From 1d939231a49dde46e9e1d18084f23fb189e8e055 Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Mon, 21 Nov 2016 12:21:01 -0500 Subject: [PATCH 001/439] USER-DPD: initial Kokkos port, first steps from Aug 24th ARL Kokkos hackathon atom_vec_dpd_kokkos pair_dpd_fdt_energy_kokkos without the Oct 7th VV support from e27ed6c --- src/KOKKOS/atom_kokkos.h | 6 + src/USER-DPD/atom_vec_dpd_kokkos.cpp | 1872 +++++++++++++++++++ src/USER-DPD/atom_vec_dpd_kokkos.h | 135 ++ src/USER-DPD/pair_dpd_fdt_energy_kokkos.cpp | 373 ++++ src/USER-DPD/pair_dpd_fdt_energy_kokkos.h | 119 ++ 5 files changed, 2505 insertions(+) create mode 100644 src/USER-DPD/atom_vec_dpd_kokkos.cpp create mode 100644 src/USER-DPD/atom_vec_dpd_kokkos.h create mode 100644 src/USER-DPD/pair_dpd_fdt_energy_kokkos.cpp create mode 100644 src/USER-DPD/pair_dpd_fdt_energy_kokkos.h diff --git a/src/KOKKOS/atom_kokkos.h b/src/KOKKOS/atom_kokkos.h index 05aae712d9..f31c26e01f 100644 --- a/src/KOKKOS/atom_kokkos.h +++ b/src/KOKKOS/atom_kokkos.h @@ -51,6 +51,12 @@ class AtomKokkos : public Atom { DAT::tdual_int_2d k_improper_type; DAT::tdual_tagint_2d k_improper_atom1, k_improper_atom2, k_improper_atom3, k_improper_atom4; + +// USER-DPD package + DAT::tdual_efloat_1d k_uCond, k_uMech, k_uChem, k_uCG, k_uCGnew, + k_rho,k_dpdTheta,k_duChem; + + AtomKokkos(class LAMMPS *); ~AtomKokkos(); diff --git a/src/USER-DPD/atom_vec_dpd_kokkos.cpp b/src/USER-DPD/atom_vec_dpd_kokkos.cpp new file mode 100644 index 0000000000..c58b592e53 --- /dev/null +++ b/src/USER-DPD/atom_vec_dpd_kokkos.cpp @@ -0,0 +1,1872 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale AtomicKokkos/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include +#include "atom_vec_dpd_kokkos.h" +#include "atom_kokkos.h" +#include "comm_kokkos.h" +#include "domain.h" +#include "modify.h" +#include "fix.h" +#include "atom_masks.h" +#include "memory.h" +#include "error.h" + +using namespace LAMMPS_NS; + +#define DELTA 10000 + +/* ---------------------------------------------------------------------- */ + +AtomVecDPDKokkos::AtomVecDPDKokkos(LAMMPS *lmp) : AtomVecKokkos(lmp) +{ + molecular = 0; + mass_type = 1; + + comm_x_only = comm_f_only = 0; + size_forward = 7; + size_reverse = 3; + size_border = 12; + size_velocity = 3; + size_data_atom = 6; + size_data_vel = 4; + xcol_data = 4; + + atom->rho_flag = 1; + atom->dpd_flag = 1; + + k_count = DAT::tdual_int_1d("atom::k_count",1); + atomKK = (AtomKokkos *) atom; + commKK = (CommKokkos *) comm; +} + +/* ---------------------------------------------------------------------- + grow atom arrays + n = 0 grows arrays by DELTA + n > 0 allocates arrays to size n +------------------------------------------------------------------------- */ + +void AtomVecDPDKokkos::grow(int n) +{ + if (n == 0) nmax += DELTA; + else nmax = n; + atomKK->nmax = nmax; + if (nmax < 0 || nmax > MAXSMALLINT) + error->one(FLERR,"Per-processor system is too big"); + + sync(Device,ALL_MASK); + modified(Device,ALL_MASK); + + memory->grow_kokkos(atomKK->k_tag,atomKK->tag,nmax,"atom:tag"); + memory->grow_kokkos(atomKK->k_type,atomKK->type,nmax,"atom:type"); + memory->grow_kokkos(atomKK->k_mask,atomKK->mask,nmax,"atom:mask"); + memory->grow_kokkos(atomKK->k_image,atomKK->image,nmax,"atom:image"); + + memory->grow_kokkos(atomKK->k_x,atomKK->x,nmax,3,"atom:x"); + memory->grow_kokkos(atomKK->k_v,atomKK->v,nmax,3,"atom:v"); + memory->grow_kokkos(atomKK->k_f,atomKK->f,nmax,3,"atom:f"); + + + memory->grow_kokkos(atomKK->k_rho,atomKK->rho,nmax,"atom:rho"); + memory->grow_kokkos(atomKK->k_dpdTheta,atomKK->dpdTheta,nmax,"atom:dpdTheta"); + memory->grow_kokkos(atomKK->k_uCond,atomKK->uCond,nmax,"atom:uCond"); + memory->grow_kokkos(atomKK->k_uMech,atomKK->uMech,nmax,"atom:uMech"); + memory->grow_kokkos(atomKK->k_uChem,atomKK->uChem,nmax,"atom:uChem"); + memory->grow_kokkos(atomKK->k_uCG,atomKK->uCG,nmax,"atom:uCG"); + memory->grow_kokkos(atomKK->k_uCGnew,atomKK->uCGnew,nmax,"atom:uCGnew"); + memory->grow_kokkos(atomKK->k_duChem,atomKK->duChem,nmax,"atom:duChem"); + + grow_reset(); + sync(Host,ALL_MASK); + + if (atom->nextra_grow) + for (int iextra = 0; iextra < atom->nextra_grow; iextra++) + modify->fix[atom->extra_grow[iextra]]->grow_arrays(nmax); +} + +/* ---------------------------------------------------------------------- + reset local array ptrs +------------------------------------------------------------------------- */ + +void AtomVecDPDKokkos::grow_reset() +{ + tag = atomKK->tag; + d_tag = atomKK->k_tag.d_view; + h_tag = atomKK->k_tag.h_view; + + type = atomKK->type; + d_type = atomKK->k_type.d_view; + h_type = atomKK->k_type.h_view; + mask = atomKK->mask; + d_mask = atomKK->k_mask.d_view; + h_mask = atomKK->k_mask.h_view; + image = atomKK->image; + d_image = atomKK->k_image.d_view; + h_image = atomKK->k_image.h_view; + + x = atomKK->x; + d_x = atomKK->k_x.d_view; + h_x = atomKK->k_x.h_view; + v = atomKK->v; + d_v = atomKK->k_v.d_view; + h_v = atomKK->k_v.h_view; + f = atomKK->f; + d_f = atomKK->k_f.d_view; + h_f = atomKK->k_f.h_view; + + rho = atomKK->rho; + d_rho = atomKK->k_rho.d_view; + h_rho = atomKK->k_rho.h_view; + dpdTheta = atomKK->dpdTheta; + d_dpdTheta = atomKK->k_dpdTheta.d_view; + h_dpdTheta = atomKK->k_dpdTheta.h_view; + uCond = atomKK->uCond; + d_uCond = atomKK->k_uCond.d_view;; + h_uCond = atomKK->k_uCond.h_view; + uMech = atomKK->uMech; + d_uMech = atomKK->k_uMech.d_view;; + h_uMech = atomKK->k_uMech.h_view; + uChem = atomKK->uChem; + d_uChem = atomKK->k_uChem.d_view;; + h_uChem = atomKK->k_uChem.h_view; + uCG = atomKK->uCG; + d_uCG = atomKK->k_uCG.d_view;; + h_uCG = atomKK->k_uCG.h_view; + uCGnew = atomKK->uCGnew; + d_uCGnew = atomKK->k_uCGnew.d_view;; + h_uCGnew = atomKK->k_uCGnew.h_view; + duChem = atomKK->duChem; + d_duChem = atomKK->k_duChem.d_view;; + h_duChem = atomKK->k_duChem.h_view; +} + +/* ---------------------------------------------------------------------- + copy atom I info to atom J +------------------------------------------------------------------------- */ + +void AtomVecDPDKokkos::copy(int i, int j, int delflag) +{ + h_tag[j] = h_tag[i]; + h_type[j] = h_type[i]; + mask[j] = mask[i]; + h_image[j] = h_image[i]; + h_x(j,0) = h_x(i,0); + h_x(j,1) = h_x(i,1); + h_x(j,2) = h_x(i,2); + h_v(j,0) = h_v(i,0); + h_v(j,1) = h_v(i,1); + h_v(j,2) = h_v(i,2); + h_dpdTheta[j] = h_dpdTheta[i]; + h_uCond[j] = h_uCond[i]; + h_uMech[j] = h_uMech[i]; + h_uChem[j] = h_uChem[i]; + h_uCG[j] = h_uCG[i]; + h_uCGnew[j] = h_uCGnew[i]; + + if (atom->nextra_grow) + for (int iextra = 0; iextra < atom->nextra_grow; iextra++) + modify->fix[atom->extra_grow[iextra]]->copy_arrays(i,j,delflag); +} + +/* ---------------------------------------------------------------------- */ + +template +struct AtomVecDPDKokkos_PackComm { + typedef DeviceType device_type; + + typename ArrayTypes::t_x_array_randomread _x; + typename ArrayTypes::t_efloat_1d _dpdTheta,_uCond,_uMech,_uChem; + typename ArrayTypes::t_xfloat_2d_um _buf; + typename ArrayTypes::t_int_2d_const _list; + const int _iswap; + X_FLOAT _xprd,_yprd,_zprd,_xy,_xz,_yz; + X_FLOAT _pbc[6]; + + AtomVecDPDKokkos_PackComm( + const typename DAT::tdual_x_array &x, + const typename DAT::tdual_efloat_1d &dpdTheta, + const typename DAT::tdual_efloat_1d &uCond, + const typename DAT::tdual_efloat_1d &uMech, + const typename DAT::tdual_efloat_1d &uChem, + const typename DAT::tdual_xfloat_2d &buf, + const typename DAT::tdual_int_2d &list, + const int & iswap, + const X_FLOAT &xprd, const X_FLOAT &yprd, const X_FLOAT &zprd, + const X_FLOAT &xy, const X_FLOAT &xz, const X_FLOAT &yz, const int* const pbc): + _x(x.view()), + _dpdTheta(dpdTheta.view()), + _uCond(uCond.view()), + _uMech(uMech.view()), + _uChem(uChem.view()), + _list(list.view()),_iswap(iswap), + _xprd(xprd),_yprd(yprd),_zprd(zprd), + _xy(xy),_xz(xz),_yz(yz) { + const size_t maxsend = (buf.view().dimension_0()*buf.view().dimension_1())/3; + const size_t elements = 3; + buffer_view(_buf,buf,maxsend,elements); + _pbc[0] = pbc[0]; _pbc[1] = pbc[1]; _pbc[2] = pbc[2]; + _pbc[3] = pbc[3]; _pbc[4] = pbc[4]; _pbc[5] = pbc[5]; + }; + + KOKKOS_INLINE_FUNCTION + void operator() (const int& i) const { + const int j = _list(_iswap,i); + if (PBC_FLAG == 0) { + _buf(i,0) = _x(j,0); + _buf(i,1) = _x(j,1); + _buf(i,2) = _x(j,2); + } else { + if (TRICLINIC == 0) { + _buf(i,0) = _x(j,0) + _pbc[0]*_xprd; + _buf(i,1) = _x(j,1) + _pbc[1]*_yprd; + _buf(i,2) = _x(j,2) + _pbc[2]*_zprd; + } else { + _buf(i,0) = _x(j,0) + _pbc[0]*_xprd + _pbc[5]*_xy + _pbc[4]*_xz; + _buf(i,1) = _x(j,1) + _pbc[1]*_yprd + _pbc[3]*_yz; + _buf(i,2) = _x(j,2) + _pbc[2]*_zprd; + } + } + _buf(i,3) = _dpdTheta(j); + _buf(i,4) = _uCond(j); + _buf(i,5) = _uMech(j); + _buf(i,6) = _uChem(j); + } +}; + +/* ---------------------------------------------------------------------- */ + +int AtomVecDPDKokkos::pack_comm_kokkos(const int &n, + const DAT::tdual_int_2d &list, + const int & iswap, + const DAT::tdual_xfloat_2d &buf, + const int &pbc_flag, + const int* const pbc) +{ + // Check whether to always run forward communication on the host + // Choose correct forward PackComm kernel + + if(commKK->forward_comm_on_host) { + sync(Host,X_MASK); + if(pbc_flag) { + if(domain->triclinic) { + struct AtomVecDPDKokkos_PackComm f(atomKK->k_x, + atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem, + buf,list,iswap, + domain->xprd,domain->yprd,domain->zprd, + domain->xy,domain->xz,domain->yz,pbc); + Kokkos::parallel_for(n,f); + } else { + struct AtomVecDPDKokkos_PackComm f(atomKK->k_x, + atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem, + buf,list,iswap, + domain->xprd,domain->yprd,domain->zprd, + domain->xy,domain->xz,domain->yz,pbc); + Kokkos::parallel_for(n,f); + } + } else { + if(domain->triclinic) { + struct AtomVecDPDKokkos_PackComm f(atomKK->k_x, + atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem, + buf,list,iswap, + domain->xprd,domain->yprd,domain->zprd, + domain->xy,domain->xz,domain->yz,pbc); + Kokkos::parallel_for(n,f); + } else { + struct AtomVecDPDKokkos_PackComm f(atomKK->k_x, + atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem, + buf,list,iswap, + domain->xprd,domain->yprd,domain->zprd, + domain->xy,domain->xz,domain->yz,pbc); + Kokkos::parallel_for(n,f); + } + } + LMPHostType::fence(); + } else { + sync(Device,X_MASK); + if(pbc_flag) { + if(domain->triclinic) { + struct AtomVecDPDKokkos_PackComm f(atomKK->k_x, + atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem, + buf,list,iswap, + domain->xprd,domain->yprd,domain->zprd, + domain->xy,domain->xz,domain->yz,pbc); + Kokkos::parallel_for(n,f); + } else { + struct AtomVecDPDKokkos_PackComm f(atomKK->k_x, + atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem, + buf,list,iswap, + domain->xprd,domain->yprd,domain->zprd, + domain->xy,domain->xz,domain->yz,pbc); + Kokkos::parallel_for(n,f); + } + } else { + if(domain->triclinic) { + struct AtomVecDPDKokkos_PackComm f(atomKK->k_x, + atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem, + buf,list,iswap, + domain->xprd,domain->yprd,domain->zprd, + domain->xy,domain->xz,domain->yz,pbc); + Kokkos::parallel_for(n,f); + } else { + struct AtomVecDPDKokkos_PackComm f(atomKK->k_x, + atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem, + buf,list,iswap, + domain->xprd,domain->yprd,domain->zprd, + domain->xy,domain->xz,domain->yz,pbc); + Kokkos::parallel_for(n,f); + } + } + LMPDeviceType::fence(); + } + + return n*size_forward; +} + +/* ---------------------------------------------------------------------- */ + +template +struct AtomVecDPDKokkos_PackCommSelf { + typedef DeviceType device_type; + + typename ArrayTypes::t_x_array_randomread _x; + typename ArrayTypes::t_x_array _xw; + typename ArrayTypes::t_efloat_1d _dpdTheta,_uCond,_uMech,_uChem; + int _nfirst; + typename ArrayTypes::t_int_2d_const _list; + const int _iswap; + X_FLOAT _xprd,_yprd,_zprd,_xy,_xz,_yz; + X_FLOAT _pbc[6]; + + AtomVecDPDKokkos_PackCommSelf( + const typename DAT::tdual_x_array &x, + const typename DAT::tdual_efloat_1d &dpdTheta, + const typename DAT::tdual_efloat_1d &uCond, + const typename DAT::tdual_efloat_1d &uMech, + const typename DAT::tdual_efloat_1d &uChem, + const int &nfirst, + const typename DAT::tdual_int_2d &list, + const int & iswap, + const X_FLOAT &xprd, const X_FLOAT &yprd, const X_FLOAT &zprd, + const X_FLOAT &xy, const X_FLOAT &xz, const X_FLOAT &yz, const int* const pbc): + _x(x.view()),_xw(x.view()), + _dpdTheta(dpdTheta.view()), + _uCond(uCond.view()), + _uMech(uMech.view()), + _uChem(uChem.view()), + _nfirst(nfirst),_list(list.view()),_iswap(iswap), + _xprd(xprd),_yprd(yprd),_zprd(zprd), + _xy(xy),_xz(xz),_yz(yz) { + _pbc[0] = pbc[0]; _pbc[1] = pbc[1]; _pbc[2] = pbc[2]; + _pbc[3] = pbc[3]; _pbc[4] = pbc[4]; _pbc[5] = pbc[5]; + }; + + KOKKOS_INLINE_FUNCTION + void operator() (const int& i) const { + const int j = _list(_iswap,i); + if (PBC_FLAG == 0) { + _xw(i+_nfirst,0) = _x(j,0); + _xw(i+_nfirst,1) = _x(j,1); + _xw(i+_nfirst,2) = _x(j,2); + } else { + if (TRICLINIC == 0) { + _xw(i+_nfirst,0) = _x(j,0) + _pbc[0]*_xprd; + _xw(i+_nfirst,1) = _x(j,1) + _pbc[1]*_yprd; + _xw(i+_nfirst,2) = _x(j,2) + _pbc[2]*_zprd; + } else { + _xw(i+_nfirst,0) = _x(j,0) + _pbc[0]*_xprd + _pbc[5]*_xy + _pbc[4]*_xz; + _xw(i+_nfirst,1) = _x(j,1) + _pbc[1]*_yprd + _pbc[3]*_yz; + _xw(i+_nfirst,2) = _x(j,2) + _pbc[2]*_zprd; + } + } + _dpdTheta(i+_nfirst) = _dpdTheta(j); + _uCond(i+_nfirst) = _uCond(j); + _uMech(i+_nfirst) = _uMech(j); + _uChem(i+_nfirst) = _uChem(j); + } +}; + +/* ---------------------------------------------------------------------- */ + +int AtomVecDPDKokkos::pack_comm_self(const int &n, const DAT::tdual_int_2d &list, const int & iswap, + const int nfirst, const int &pbc_flag, const int* const pbc) { + if(commKK->forward_comm_on_host) { + sync(Host,X_MASK); + modified(Host,X_MASK); + if(pbc_flag) { + if(domain->triclinic) { + struct AtomVecDPDKokkos_PackCommSelf f(atomKK->k_x, + atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem, + nfirst,list,iswap, + domain->xprd,domain->yprd,domain->zprd, + domain->xy,domain->xz,domain->yz,pbc); + Kokkos::parallel_for(n,f); + } else { + struct AtomVecDPDKokkos_PackCommSelf f(atomKK->k_x, + atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem, + nfirst,list,iswap, + domain->xprd,domain->yprd,domain->zprd, + domain->xy,domain->xz,domain->yz,pbc); + Kokkos::parallel_for(n,f); + } + } else { + if(domain->triclinic) { + struct AtomVecDPDKokkos_PackCommSelf f(atomKK->k_x, + atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem, + nfirst,list,iswap, + domain->xprd,domain->yprd,domain->zprd, + domain->xy,domain->xz,domain->yz,pbc); + Kokkos::parallel_for(n,f); + } else { + struct AtomVecDPDKokkos_PackCommSelf f(atomKK->k_x, + atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem, + nfirst,list,iswap, + domain->xprd,domain->yprd,domain->zprd, + domain->xy,domain->xz,domain->yz,pbc); + Kokkos::parallel_for(n,f); + } + } + LMPHostType::fence(); + } else { + sync(Device,X_MASK); + modified(Device,X_MASK); + if(pbc_flag) { + if(domain->triclinic) { + struct AtomVecDPDKokkos_PackCommSelf f(atomKK->k_x, + atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem, + nfirst,list,iswap, + domain->xprd,domain->yprd,domain->zprd, + domain->xy,domain->xz,domain->yz,pbc); + Kokkos::parallel_for(n,f); + } else { + struct AtomVecDPDKokkos_PackCommSelf f(atomKK->k_x, + atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem, + nfirst,list,iswap, + domain->xprd,domain->yprd,domain->zprd, + domain->xy,domain->xz,domain->yz,pbc); + Kokkos::parallel_for(n,f); + } + } else { + if(domain->triclinic) { + struct AtomVecDPDKokkos_PackCommSelf f(atomKK->k_x, + atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem, + nfirst,list,iswap, + domain->xprd,domain->yprd,domain->zprd, + domain->xy,domain->xz,domain->yz,pbc); + Kokkos::parallel_for(n,f); + } else { + struct AtomVecDPDKokkos_PackCommSelf f(atomKK->k_x, + atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem, + nfirst,list,iswap, + domain->xprd,domain->yprd,domain->zprd, + domain->xy,domain->xz,domain->yz,pbc); + Kokkos::parallel_for(n,f); + } + } + LMPDeviceType::fence(); + } + return n*3; +} + +/* ---------------------------------------------------------------------- */ + +template +struct AtomVecDPDKokkos_UnpackComm { + typedef DeviceType device_type; + + typename ArrayTypes::t_x_array _x; + typename ArrayTypes::t_efloat_1d _dpdTheta,_uCond,_uMech,_uChem; + typename ArrayTypes::t_xfloat_2d_const _buf; + int _first; + + AtomVecDPDKokkos_UnpackComm( + const typename DAT::tdual_x_array &x, + const typename DAT::tdual_efloat_1d &dpdTheta, + const typename DAT::tdual_efloat_1d &uCond, + const typename DAT::tdual_efloat_1d &uMech, + const typename DAT::tdual_efloat_1d &uChem, + const typename DAT::tdual_xfloat_2d &buf, + const int& first):_x(x.view()), + _dpdTheta(dpdTheta.view()), + _uCond(uCond.view()), + _uMech(uMech.view()), + _uChem(uChem.view()), + _buf(buf.view()), + _first(first) {}; + + KOKKOS_INLINE_FUNCTION + void operator() (const int& i) const { + _x(i+_first,0) = _buf(i,0); + _x(i+_first,1) = _buf(i,1); + _x(i+_first,2) = _buf(i,2); + _dpdTheta(i+_first) = _buf(i,3); + _uCond(i+_first) = _buf(i,4); + _uMech(i+_first) = _buf(i,5); + _uChem(i+_first) = _buf(i,6); + } +}; + +/* ---------------------------------------------------------------------- */ + +void AtomVecDPDKokkos::unpack_comm_kokkos(const int &n, const int &first, + const DAT::tdual_xfloat_2d &buf ) { + if(commKK->forward_comm_on_host) { + sync(Host,X_MASK); + modified(Host,X_MASK); + struct AtomVecDPDKokkos_UnpackComm f(atomKK->k_x, + atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem, + buf,first); + Kokkos::parallel_for(n,f); + LMPDeviceType::fence(); + } else { + sync(Device,X_MASK); + modified(Device,X_MASK); + struct AtomVecDPDKokkos_UnpackComm f(atomKK->k_x, + atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem, + buf,first); + Kokkos::parallel_for(n,f); + LMPDeviceType::fence(); + } +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecDPDKokkos::pack_comm(int n, int *list, double *buf, + int pbc_flag, int *pbc) +{ + int i,j,m; + double dx,dy,dz; + + m = 0; + if (pbc_flag == 0) { + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = h_x(j,0); + buf[m++] = h_x(j,1); + buf[m++] = h_x(j,2); + buf[m++] = dpdTheta[j]; + buf[m++] = uCond[j]; + buf[m++] = uMech[j]; + buf[m++] = uChem[j]; + } + } else { + if (domain->triclinic == 0) { + dx = pbc[0]*domain->xprd; + dy = pbc[1]*domain->yprd; + dz = pbc[2]*domain->zprd; + } else { + dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz; + dy = pbc[1]*domain->yprd + pbc[3]*domain->yz; + dz = pbc[2]*domain->zprd; + } + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = h_x(j,0) + dx; + buf[m++] = h_x(j,1) + dy; + buf[m++] = h_x(j,2) + dz; + buf[m++] = h_dpdTheta[j]; + buf[m++] = h_uCond[j]; + buf[m++] = h_uMech[j]; + buf[m++] = h_uChem[j]; + } + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecDPDKokkos::pack_comm_vel(int n, int *list, double *buf, + int pbc_flag, int *pbc) +{ + int i,j,m; + double dx,dy,dz,dvx,dvy,dvz; + + m = 0; + if (pbc_flag == 0) { + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = h_x(j,0); + buf[m++] = h_x(j,1); + buf[m++] = h_x(j,2); + buf[m++] = h_v(j,0); + buf[m++] = h_v(j,1); + buf[m++] = h_v(j,2); + buf[m++] = h_dpdTheta[j]; + buf[m++] = h_uCond[j]; + buf[m++] = h_uMech[j]; + buf[m++] = h_uChem[j]; + } + } else { + if (domain->triclinic == 0) { + dx = pbc[0]*domain->xprd; + dy = pbc[1]*domain->yprd; + dz = pbc[2]*domain->zprd; + } else { + dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz; + dy = pbc[1]*domain->yprd + pbc[3]*domain->yz; + dz = pbc[2]*domain->zprd; + } + if (!deform_vremap) { + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = h_x(j,0) + dx; + buf[m++] = h_x(j,1) + dy; + buf[m++] = h_x(j,2) + dz; + buf[m++] = h_v(j,0); + buf[m++] = h_v(j,1); + buf[m++] = h_v(j,2); + buf[m++] = h_dpdTheta[j]; + buf[m++] = h_uCond[j]; + buf[m++] = h_uMech[j]; + buf[m++] = h_uChem[j]; + } + } else { + dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4]; + dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3]; + dvz = pbc[2]*h_rate[2]; + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = h_x(j,0) + dx; + buf[m++] = h_x(j,1) + dy; + buf[m++] = h_x(j,2) + dz; + if (mask[i] & deform_groupbit) { + buf[m++] = h_v(j,0) + dvx; + buf[m++] = h_v(j,1) + dvy; + buf[m++] = h_v(j,2) + dvz; + } else { + buf[m++] = h_v(j,0); + buf[m++] = h_v(j,1); + buf[m++] = h_v(j,2); + } + buf[m++] = h_dpdTheta(j); + buf[m++] = h_uCond(j); + buf[m++] = h_uMech(j); + buf[m++] = h_uChem(j); + } + } + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecDPDKokkos::unpack_comm(int n, int first, double *buf) +{ + int i,m,last; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + h_x(i,0) = buf[m++]; + h_x(i,1) = buf[m++]; + h_x(i,2) = buf[m++]; + h_dpdTheta[i] = buf[m++]; + h_uCond[i] = buf[m++]; + h_uMech[i] = buf[m++]; + h_uChem[i] = buf[m++]; + } +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecDPDKokkos::unpack_comm_vel(int n, int first, double *buf) +{ + int i,m,last; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + h_x(i,0) = buf[m++]; + h_x(i,1) = buf[m++]; + h_x(i,2) = buf[m++]; + h_v(i,0) = buf[m++]; + h_v(i,1) = buf[m++]; + h_v(i,2) = buf[m++]; + h_dpdTheta[i] = buf[m++]; + h_uCond[i] = buf[m++]; + h_uMech[i] = buf[m++]; + h_uChem[i] = buf[m++]; + } +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecDPDKokkos::pack_reverse(int n, int first, double *buf) +{ + if(n > 0) + sync(Host,F_MASK); + + int m = 0; + const int last = first + n; + for (int i = first; i < last; i++) { + buf[m++] = h_f(i,0); + buf[m++] = h_f(i,1); + buf[m++] = h_f(i,2); + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecDPDKokkos::unpack_reverse(int n, int *list, double *buf) +{ + if(n > 0) { + sync(Host,F_MASK); + modified(Host,F_MASK); + } + + int m = 0; + for (int i = 0; i < n; i++) { + const int j = list[i]; + h_f(j,0) += buf[m++]; + h_f(j,1) += buf[m++]; + h_f(j,2) += buf[m++]; + } +} + +/* ---------------------------------------------------------------------- */ + +template +struct AtomVecDPDKokkos_PackBorder { + typedef DeviceType device_type; + + typename ArrayTypes::t_xfloat_2d _buf; + const typename ArrayTypes::t_int_2d_const _list; + const int _iswap; + const typename ArrayTypes::t_x_array_randomread _x; + const typename ArrayTypes::t_tagint_1d _tag; + const typename ArrayTypes::t_int_1d _type; + const typename ArrayTypes::t_int_1d _mask; + typename ArrayTypes::t_efloat_1d _dpdTheta,_uCond,_uMech,_uChem,_uCG,_uCGnew; + X_FLOAT _dx,_dy,_dz; + + AtomVecDPDKokkos_PackBorder( + const typename ArrayTypes::t_xfloat_2d &buf, + const typename ArrayTypes::t_int_2d_const &list, + const int & iswap, + const typename ArrayTypes::t_x_array &x, + const typename ArrayTypes::t_tagint_1d &tag, + const typename ArrayTypes::t_int_1d &type, + const typename ArrayTypes::t_int_1d &mask, + const typename ArrayTypes::t_efloat_1d &dpdTheta, + const typename ArrayTypes::t_efloat_1d &uCond, + const typename ArrayTypes::t_efloat_1d &uMech, + const typename ArrayTypes::t_efloat_1d &uChem, + const typename ArrayTypes::t_efloat_1d &uCG, + const typename ArrayTypes::t_efloat_1d &uCGnew, + const X_FLOAT &dx, const X_FLOAT &dy, const X_FLOAT &dz): + _buf(buf),_list(list),_iswap(iswap), + _x(x),_tag(tag),_type(type),_mask(mask), + _dpdTheta(dpdTheta), + _uCond(uCond), + _uMech(uMech), + _uChem(uChem), + _uCG(uCGnew), + _uCGnew(uCGnew), + _dx(dx),_dy(dy),_dz(dz) {} + + KOKKOS_INLINE_FUNCTION + void operator() (const int& i) const { + const int j = _list(_iswap,i); + if (PBC_FLAG == 0) { + _buf(i,0) = _x(j,0); + _buf(i,1) = _x(j,1); + _buf(i,2) = _x(j,2); + } else { + _buf(i,0) = _x(j,0) + _dx; + _buf(i,1) = _x(j,1) + _dy; + _buf(i,2) = _x(j,2) + _dz; + } + _buf(i,3) = _tag(j); + _buf(i,4) = _type(j); + _buf(i,5) = _mask(j); + _buf(i,6) = _dpdTheta(j); + _buf(i,7) = _uCond(j); + _buf(i,8) = _uMech(j); + _buf(i,9) = _uChem(j); + _buf(i,10) = _uCG(j); + _buf(i,11) = _uCGnew(j); + } +}; + +/* ---------------------------------------------------------------------- */ + +int AtomVecDPDKokkos::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) +{ + X_FLOAT dx,dy,dz; + + if (pbc_flag != 0) { + if (domain->triclinic == 0) { + dx = pbc[0]*domain->xprd; + dy = pbc[1]*domain->yprd; + dz = pbc[2]*domain->zprd; + } else { + dx = pbc[0]; + dy = pbc[1]; + dz = pbc[2]; + } + if(space==Host) { + AtomVecDPDKokkos_PackBorder f( + buf.view(), k_sendlist.view(), + iswap,h_x,h_tag,h_type,h_mask, + h_dpdTheta,h_uCond,h_uMech,h_uChem,h_uCG,h_uCGnew, + dx,dy,dz); + Kokkos::parallel_for(n,f); + LMPHostType::fence(); + } else { + AtomVecDPDKokkos_PackBorder f( + buf.view(), k_sendlist.view(), + iswap,d_x,d_tag,d_type,d_mask, + d_dpdTheta,d_uCond,d_uMech,d_uChem,d_uCG,d_uCGnew, + dx,dy,dz); + Kokkos::parallel_for(n,f); + LMPDeviceType::fence(); + } + + } else { + dx = dy = dz = 0; + if(space==Host) { + AtomVecDPDKokkos_PackBorder f( + buf.view(), k_sendlist.view(), + iswap,h_x,h_tag,h_type,h_mask, + h_dpdTheta,h_uCond,h_uMech,h_uChem,h_uCG,h_uCGnew, + dx,dy,dz); + Kokkos::parallel_for(n,f); + LMPHostType::fence(); + } else { + AtomVecDPDKokkos_PackBorder f( + buf.view(), k_sendlist.view(), + iswap,d_x,d_tag,d_type,d_mask, + d_dpdTheta,d_uCond,d_uMech,d_uChem,d_uCG,d_uCGnew, + dx,dy,dz); + Kokkos::parallel_for(n,f); + LMPDeviceType::fence(); + } + } + return n*6; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecDPDKokkos::pack_border(int n, int *list, double *buf, + int pbc_flag, int *pbc) +{ + int i,j,m; + double dx,dy,dz; + + m = 0; + if (pbc_flag == 0) { + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = h_x(j,0); + buf[m++] = h_x(j,1); + buf[m++] = h_x(j,2); + buf[m++] = ubuf(h_tag(j)).d; + buf[m++] = ubuf(h_type(j)).d; + buf[m++] = ubuf(h_mask(j)).d; + buf[m++] = h_dpdTheta(j); + buf[m++] = h_uCond(j); + buf[m++] = h_uMech(j); + buf[m++] = h_uChem(j); + buf[m++] = h_uCG(j); + buf[m++] = h_uCGnew(j); + } + } else { + if (domain->triclinic == 0) { + dx = pbc[0]*domain->xprd; + dy = pbc[1]*domain->yprd; + dz = pbc[2]*domain->zprd; + } else { + dx = pbc[0]; + dy = pbc[1]; + dz = pbc[2]; + } + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = h_x(j,0) + dx; + buf[m++] = h_x(j,1) + dy; + buf[m++] = h_x(j,2) + dz; + buf[m++] = ubuf(h_tag(j)).d; + buf[m++] = ubuf(h_type(j)).d; + buf[m++] = ubuf(h_mask(j)).d; + buf[m++] = h_dpdTheta(j); + buf[m++] = h_uCond(j); + buf[m++] = h_uMech(j); + buf[m++] = h_uChem(j); + buf[m++] = h_uCG(j); + buf[m++] = h_uCGnew(j); + } + } + + if (atom->nextra_border) + for (int iextra = 0; iextra < atom->nextra_border; iextra++) + m += modify->fix[atom->extra_border[iextra]]->pack_border(n,list,&buf[m]); + + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecDPDKokkos::pack_border_vel(int n, int *list, double *buf, + int pbc_flag, int *pbc) +{ + int i,j,m; + double dx,dy,dz,dvx,dvy,dvz; + + m = 0; + if (pbc_flag == 0) { + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = h_x(j,0); + buf[m++] = h_x(j,1); + buf[m++] = h_x(j,2); + buf[m++] = ubuf(h_tag(j)).d; + buf[m++] = ubuf(h_type(j)).d; + buf[m++] = ubuf(h_mask(j)).d; + buf[m++] = h_v(j,0); + buf[m++] = h_v(j,1); + buf[m++] = h_v(j,2); + buf[m++] = h_dpdTheta(j); + buf[m++] = h_uCond(j); + buf[m++] = h_uMech(j); + buf[m++] = h_uChem(j); + buf[m++] = h_uCG(j); + buf[m++] = h_uCGnew(j); + } + } else { + if (domain->triclinic == 0) { + dx = pbc[0]*domain->xprd; + dy = pbc[1]*domain->yprd; + dz = pbc[2]*domain->zprd; + } else { + dx = pbc[0]; + dy = pbc[1]; + dz = pbc[2]; + } + if (!deform_vremap) { + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = h_x(j,0) + dx; + buf[m++] = h_x(j,1) + dy; + buf[m++] = h_x(j,2) + dz; + buf[m++] = ubuf(h_tag(j)).d; + buf[m++] = ubuf(h_type(j)).d; + buf[m++] = ubuf(h_mask(j)).d; + buf[m++] = h_v(j,0); + buf[m++] = h_v(j,1); + buf[m++] = h_v(j,2); + buf[m++] = h_dpdTheta(j); + buf[m++] = h_uCond(j); + buf[m++] = h_uMech(j); + buf[m++] = h_uChem(j); + buf[m++] = h_uCG(j); + buf[m++] = h_uCGnew(j); + } + } else { + dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4]; + dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3]; + dvz = pbc[2]*h_rate[2]; + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = h_x(j,0) + dx; + buf[m++] = h_x(j,1) + dy; + buf[m++] = h_x(j,2) + dz; + buf[m++] = ubuf(h_tag(j)).d; + buf[m++] = ubuf(h_type(j)).d; + buf[m++] = ubuf(h_mask(j)).d; + if (mask[i] & deform_groupbit) { + buf[m++] = h_v(j,0) + dvx; + buf[m++] = h_v(j,1) + dvy; + buf[m++] = h_v(j,2) + dvz; + } else { + buf[m++] = h_v(j,0); + buf[m++] = h_v(j,1); + buf[m++] = h_v(j,2); + } + buf[m++] = h_dpdTheta(j); + buf[m++] = h_uCond(j); + buf[m++] = h_uMech(j); + buf[m++] = h_uChem(j); + buf[m++] = h_uCG(j); + buf[m++] = h_uCGnew(j); + } + } + } + + if (atom->nextra_border) + for (int iextra = 0; iextra < atom->nextra_border; iextra++) + m += modify->fix[atom->extra_border[iextra]]->pack_border(n,list,&buf[m]); + + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecDPDKokkos::pack_comm_hybrid(int n, int *list, double *buf) +{ + int i,j,m; + + m = 0; + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = h_dpdTheta[j]; + buf[m++] = h_uCond[j]; + buf[m++] = h_uMech[j]; + buf[m++] = h_uChem[j]; + buf[m++] = h_uCG[j]; + buf[m++] = h_uCGnew[j]; + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecDPDKokkos::pack_border_hybrid(int n, int *list, double *buf) +{ + int i,j,m; + + m = 0; + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = h_dpdTheta[j]; + buf[m++] = h_uCond[j]; + buf[m++] = h_uMech[j]; + buf[m++] = h_uChem[j]; + buf[m++] = h_uCG[j]; + buf[m++] = h_uCGnew[j]; + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +template +struct AtomVecDPDKokkos_UnpackBorder { + typedef DeviceType device_type; + + const typename ArrayTypes::t_xfloat_2d_const _buf; + typename ArrayTypes::t_x_array _x; + typename ArrayTypes::t_tagint_1d _tag; + typename ArrayTypes::t_int_1d _type; + typename ArrayTypes::t_int_1d _mask; + typename ArrayTypes::t_efloat_1d _dpdTheta,_uCond,_uMech,_uChem,_uCG,_uCGnew; + int _first; + + + AtomVecDPDKokkos_UnpackBorder( + const typename ArrayTypes::t_xfloat_2d_const &buf, + typename ArrayTypes::t_x_array &x, + typename ArrayTypes::t_tagint_1d &tag, + typename ArrayTypes::t_int_1d &type, + typename ArrayTypes::t_int_1d &mask, + const typename ArrayTypes::t_efloat_1d &dpdTheta, + const typename ArrayTypes::t_efloat_1d &uCond, + const typename ArrayTypes::t_efloat_1d &uMech, + const typename ArrayTypes::t_efloat_1d &uChem, + const typename ArrayTypes::t_efloat_1d &uCG, + const typename ArrayTypes::t_efloat_1d &uCGnew, + const int& first): + _buf(buf),_x(x),_tag(tag),_type(type),_mask(mask), + _dpdTheta(dpdTheta), + _uCond(uCond), + _uMech(uMech), + _uChem(uChem), + _uCG(uCGnew), + _uCGnew(uCGnew), + _first(first) {}; + + KOKKOS_INLINE_FUNCTION + void operator() (const int& i) const { + _x(i+_first,0) = _buf(i,0); + _x(i+_first,1) = _buf(i,1); + _x(i+_first,2) = _buf(i,2); + _tag(i+_first) = static_cast (_buf(i,3)); + _type(i+_first) = static_cast (_buf(i,4)); + _mask(i+_first) = static_cast (_buf(i,5)); + _dpdTheta(i+_first) = _buf(i,6); + _uCond(i+_first) = _buf(i,7); + _uMech(i+_first) = _buf(i,8); + _uChem(i+_first) = _buf(i,9); + _uCG(i+_first) = _buf(i,10); + _uCGnew(i+_first) = _buf(i,11); +// printf("%i %i %lf %lf %lf %i BORDER\n",_tag(i+_first),i+_first,_x(i+_first,0),_x(i+_first,1),_x(i+_first,2),_type(i+_first)); + } +}; + +/* ---------------------------------------------------------------------- */ + +void AtomVecDPDKokkos::unpack_border_kokkos(const int &n, const int &first, + const DAT::tdual_xfloat_2d &buf,ExecutionSpace space) { + modified(space,X_MASK|TAG_MASK|TYPE_MASK|MASK_MASK); + while (first+n >= nmax) grow(0); + modified(space,X_MASK|TAG_MASK|TYPE_MASK|MASK_MASK); + if(space==Host) { + struct AtomVecDPDKokkos_UnpackBorder f(buf.view(), + h_x,h_tag,h_type,h_mask, + h_dpdTheta,h_uCond,h_uMech,h_uChem,h_uCG,h_uCGnew, + first); + Kokkos::parallel_for(n,f); + LMPHostType::fence(); + } else { + struct AtomVecDPDKokkos_UnpackBorder f(buf.view(), + d_x,d_tag,d_type,d_mask, + d_dpdTheta,d_uCond,d_uMech,d_uChem,d_uCG,d_uCGnew, + first); + Kokkos::parallel_for(n,f); + LMPDeviceType::fence(); + } +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecDPDKokkos::unpack_border(int n, int first, double *buf) +{ + int i,m,last; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + if (i == nmax) grow(0); + modified(Host,X_MASK|TAG_MASK|TYPE_MASK|MASK_MASK); + h_x(i,0) = buf[m++]; + h_x(i,1) = buf[m++]; + h_x(i,2) = buf[m++]; + h_tag(i) = (tagint) ubuf(buf[m++]).i; + h_type(i) = (int) ubuf(buf[m++]).i; + h_mask(i) = (int) ubuf(buf[m++]).i; + h_dpdTheta(i) = buf[m++]; + h_uCond(i) = buf[m++]; + h_uMech(i) = buf[m++]; + h_uChem(i) = buf[m++]; + h_uCG(i) = buf[m++]; + h_uCGnew(i) = buf[m++]; + } + + if (atom->nextra_border) + for (int iextra = 0; iextra < atom->nextra_border; iextra++) + m += modify->fix[atom->extra_border[iextra]]-> + unpack_border(n,first,&buf[m]); +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecDPDKokkos::unpack_border_vel(int n, int first, double *buf) +{ + int i,m,last; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + if (i == nmax) grow(0); + modified(Host,X_MASK|V_MASK|TAG_MASK|TYPE_MASK|MASK_MASK); + h_x(i,0) = buf[m++]; + h_x(i,1) = buf[m++]; + h_x(i,2) = buf[m++]; + h_tag(i) = (tagint) ubuf(buf[m++]).i; + h_type(i) = (int) ubuf(buf[m++]).i; + h_mask(i) = (int) ubuf(buf[m++]).i; + h_v(i,0) = buf[m++]; + h_v(i,1) = buf[m++]; + h_v(i,2) = buf[m++]; + h_dpdTheta(i) = buf[m++]; + h_uCond(i) = buf[m++]; + h_uMech(i) = buf[m++]; + h_uChem(i) = buf[m++]; + h_uCG(i) = buf[m++]; + h_uCGnew(i) = buf[m++]; + } + + if (atom->nextra_border) + for (int iextra = 0; iextra < atom->nextra_border; iextra++) + m += modify->fix[atom->extra_border[iextra]]-> + unpack_border(n,first,&buf[m]); +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecDPDKokkos::unpack_comm_hybrid(int n, int first, double *buf) +{ + int i,m,last; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + h_dpdTheta(i) = buf[m++]; + h_uCond(i) = buf[m++]; + h_uMech(i) = buf[m++]; + h_uChem(i) = buf[m++]; + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecDPDKokkos::unpack_border_hybrid(int n, int first, double *buf) +{ + int i,m,last; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + h_dpdTheta(i) = buf[m++]; + h_uCond(i) = buf[m++]; + h_uMech(i) = buf[m++]; + h_uChem(i) = buf[m++]; + h_uCG(i) = buf[m++]; + h_uCGnew(i) = buf[m++]; + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +template +struct AtomVecDPDKokkos_PackExchangeFunctor { + typedef DeviceType device_type; + typedef ArrayTypes AT; + typename AT::t_x_array_randomread _x; + typename AT::t_v_array_randomread _v; + typename AT::t_tagint_1d_randomread _tag; + typename AT::t_int_1d_randomread _type; + typename AT::t_int_1d_randomread _mask; + typename AT::t_imageint_1d_randomread _image; + typename AT::t_efloat_1d_randomread _dpdTheta,_uCond,_uMech,_uChem,_uCG,_uCGnew; + typename AT::t_x_array _xw; + typename AT::t_v_array _vw; + typename AT::t_tagint_1d _tagw; + typename AT::t_int_1d _typew; + typename AT::t_int_1d _maskw; + typename AT::t_imageint_1d _imagew; + typename AT::t_efloat_1d _dpdThetaw,_uCondw,_uMechw,_uChemw,_uCGw,_uCGneww; + + typename AT::t_xfloat_2d_um _buf; + typename AT::t_int_1d_const _sendlist; + typename AT::t_int_1d_const _copylist; + int _nlocal,_dim; + X_FLOAT _lo,_hi; + + AtomVecDPDKokkos_PackExchangeFunctor( + const AtomKokkos* atom, + const typename AT::tdual_xfloat_2d buf, + typename AT::tdual_int_1d sendlist, + typename AT::tdual_int_1d copylist,int nlocal, int dim, + X_FLOAT lo, X_FLOAT hi): + _x(atom->k_x.view()), + _v(atom->k_v.view()), + _tag(atom->k_tag.view()), + _type(atom->k_type.view()), + _mask(atom->k_mask.view()), + _image(atom->k_image.view()), + _dpdTheta(atom->k_dpdTheta.view()), + _uCond(atom->k_uCond.view()), + _uMech(atom->k_uMech.view()), + _uChem(atom->k_uChem.view()), + _uCG(atom->k_uCG.view()), + _uCGnew(atom->k_uCGnew.view()), + _xw(atom->k_x.view()), + _vw(atom->k_v.view()), + _tagw(atom->k_tag.view()), + _typew(atom->k_type.view()), + _maskw(atom->k_mask.view()), + _imagew(atom->k_image.view()), + _dpdThetaw(atom->k_dpdTheta.view()), + _uCondw(atom->k_uCond.view()), + _uMechw(atom->k_uMech.view()), + _uChemw(atom->k_uChem.view()), + _uCGw(atom->k_uCG.view()), + _uCGneww(atom->k_uCGnew.view()), + _sendlist(sendlist.template view()), + _copylist(copylist.template view()), + _nlocal(nlocal),_dim(dim), + _lo(lo),_hi(hi){ + const size_t elements = 17; + const int maxsendlist = (buf.template view().dimension_0()*buf.template view().dimension_1())/elements; + + buffer_view(_buf,buf,maxsendlist,elements); + } + + KOKKOS_INLINE_FUNCTION + void operator() (const int &mysend) const { + const int i = _sendlist(mysend); + _buf(mysend,0) = 17; + _buf(mysend,1) = _x(i,0); + _buf(mysend,2) = _x(i,1); + _buf(mysend,3) = _x(i,2); + _buf(mysend,4) = _v(i,0); + _buf(mysend,5) = _v(i,1); + _buf(mysend,6) = _v(i,2); + _buf(mysend,7) = _tag[i]; + _buf(mysend,8) = _type[i]; + _buf(mysend,9) = _mask[i]; + _buf(mysend,10) = _image[i]; + _buf(mysend,11) = _dpdTheta[i]; + _buf(mysend,12) = _uCond[i]; + _buf(mysend,13) = _uMech[i]; + _buf(mysend,14) = _uChem[i]; + _buf(mysend,15) = _uCG[i]; + _buf(mysend,16) = _uCGnew[i]; + const int j = _copylist(mysend); + + if(j>-1) { + _xw(i,0) = _x(j,0); + _xw(i,1) = _x(j,1); + _xw(i,2) = _x(j,2); + _vw(i,0) = _v(j,0); + _vw(i,1) = _v(j,1); + _vw(i,2) = _v(j,2); + _tagw[i] = _tag(j); + _typew[i] = _type(j); + _maskw[i] = _mask(j); + _imagew[i] = _image(j); + _dpdThetaw[i] = _dpdTheta(j); + _uCondw[i] = _uCond(j); + _uMechw[i] = _uMech(j); + _uChemw[i] = _uChem(j); + _uCGw[i] = _uCG(j); + _uCGneww[i] = _uCGnew(j); + } + } +}; + +/* ---------------------------------------------------------------------- */ + +int AtomVecDPDKokkos::pack_exchange_kokkos(const int &nsend,DAT::tdual_xfloat_2d &k_buf, DAT::tdual_int_1d k_sendlist,DAT::tdual_int_1d k_copylist,ExecutionSpace space,int dim,X_FLOAT lo,X_FLOAT hi ) +{ + if(nsend > (int) (k_buf.view().dimension_0()*k_buf.view().dimension_1())/17) { + int newsize = nsend*17/k_buf.view().dimension_1()+1; + k_buf.resize(newsize,k_buf.view().dimension_1()); + } + if(space == Host) { + AtomVecDPDKokkos_PackExchangeFunctor f(atomKK,k_buf,k_sendlist,k_copylist,atom->nlocal,dim,lo,hi); + Kokkos::parallel_for(nsend,f); + LMPHostType::fence(); + return nsend*17; + } else { + AtomVecDPDKokkos_PackExchangeFunctor f(atomKK,k_buf,k_sendlist,k_copylist,atom->nlocal,dim,lo,hi); + Kokkos::parallel_for(nsend,f); + LMPDeviceType::fence(); + return nsend*17; + } +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecDPDKokkos::pack_exchange(int i, double *buf) +{ + int m = 1; + buf[m++] = h_x(i,0); + buf[m++] = h_x(i,1); + buf[m++] = h_x(i,2); + buf[m++] = h_v(i,0); + buf[m++] = h_v(i,1); + buf[m++] = h_v(i,2); + buf[m++] = ubuf(h_tag(i)).d; + buf[m++] = ubuf(h_type(i)).d; + buf[m++] = ubuf(h_mask(i)).d; + buf[m++] = ubuf(h_image(i)).d; + buf[m++] = h_dpdTheta[i]; + buf[m++] = h_uCond[i]; + buf[m++] = h_uMech[i]; + buf[m++] = h_uChem[i]; + buf[m++] = h_uCG[i]; + buf[m++] = h_uCGnew[i]; + + if (atom->nextra_grow) + for (int iextra = 0; iextra < atom->nextra_grow; iextra++) + m += modify->fix[atom->extra_grow[iextra]]->pack_exchange(i,&buf[m]); + + buf[0] = m; + return m; +} + +/* ---------------------------------------------------------------------- */ + +template +struct AtomVecDPDKokkos_UnpackExchangeFunctor { + typedef DeviceType device_type; + typedef ArrayTypes AT; + typename AT::t_x_array _x; + typename AT::t_v_array _v; + typename AT::t_tagint_1d _tag; + typename AT::t_int_1d _type; + typename AT::t_int_1d _mask; + typename AT::t_imageint_1d _image; + typename AT::t_efloat_1d _dpdTheta; + typename AT::t_efloat_1d _uCond; + typename AT::t_efloat_1d _uMech; + typename AT::t_efloat_1d _uChem; + typename AT::t_efloat_1d _uCG; + typename AT::t_efloat_1d _uCGnew; + + typename AT::t_xfloat_2d_um _buf; + typename AT::t_int_1d _nlocal; + int _dim; + X_FLOAT _lo,_hi; + + AtomVecDPDKokkos_UnpackExchangeFunctor( + const AtomKokkos* atom, + const typename AT::tdual_xfloat_2d buf, + typename AT::tdual_int_1d nlocal, + int dim, X_FLOAT lo, X_FLOAT hi): + _x(atom->k_x.view()), + _v(atom->k_v.view()), + _tag(atom->k_tag.view()), + _type(atom->k_type.view()), + _mask(atom->k_mask.view()), + _image(atom->k_image.view()), + _nlocal(nlocal.template view()),_dim(dim), + _lo(lo),_hi(hi){ + const size_t elements = 17; + const int maxsendlist = (buf.template view().dimension_0()*buf.template view().dimension_1())/elements; + + buffer_view(_buf,buf,maxsendlist,elements); + } + + KOKKOS_INLINE_FUNCTION + void operator() (const int &myrecv) const { + X_FLOAT x = _buf(myrecv,_dim+1); + if (x >= _lo && x < _hi) { + int i = Kokkos::atomic_fetch_add(&_nlocal(0),1); + _x(i,0) = _buf(myrecv,1); + _x(i,1) = _buf(myrecv,2); + _x(i,2) = _buf(myrecv,3); + _v(i,0) = _buf(myrecv,4); + _v(i,1) = _buf(myrecv,5); + _v(i,2) = _buf(myrecv,6); + _tag[i] = _buf(myrecv,7); + _type[i] = _buf(myrecv,8); + _mask[i] = _buf(myrecv,9); + _image[i] = _buf(myrecv,10); + _dpdTheta[i] = _buf(myrecv,11); + _uCond[i] = _buf(myrecv,12); + _uMech[i] = _buf(myrecv,13); + _uChem[i] = _buf(myrecv,14); + _uCG[i] = _buf(myrecv,15); + _uCGnew[i] = _buf(myrecv,16); + } + } +}; + +/* ---------------------------------------------------------------------- */ + +int AtomVecDPDKokkos::unpack_exchange_kokkos(DAT::tdual_xfloat_2d &k_buf,int nrecv,int nlocal,int dim,X_FLOAT lo,X_FLOAT hi,ExecutionSpace space) { + if(space == Host) { + k_count.h_view(0) = nlocal; + AtomVecDPDKokkos_UnpackExchangeFunctor f(atomKK,k_buf,k_count,dim,lo,hi); + Kokkos::parallel_for(nrecv/17,f); + LMPHostType::fence(); + return k_count.h_view(0); + } else { + k_count.h_view(0) = nlocal; + k_count.modify(); + k_count.sync(); + AtomVecDPDKokkos_UnpackExchangeFunctor f(atomKK,k_buf,k_count,dim,lo,hi); + Kokkos::parallel_for(nrecv/17,f); + LMPDeviceType::fence(); + k_count.modify(); + k_count.sync(); + + return k_count.h_view(0); + } +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecDPDKokkos::unpack_exchange(double *buf) +{ + int nlocal = atom->nlocal; + if (nlocal == nmax) grow(0); + modified(Host,X_MASK | V_MASK | TAG_MASK | TYPE_MASK | + MASK_MASK | IMAGE_MASK); + + int m = 1; + h_x(nlocal,0) = buf[m++]; + h_x(nlocal,1) = buf[m++]; + h_x(nlocal,2) = buf[m++]; + h_v(nlocal,0) = buf[m++]; + h_v(nlocal,1) = buf[m++]; + h_v(nlocal,2) = buf[m++]; + h_tag(nlocal) = (tagint) ubuf(buf[m++]).i; + h_type(nlocal) = (int) ubuf(buf[m++]).i; + h_mask(nlocal) = (int) ubuf(buf[m++]).i; + h_image(nlocal) = (imageint) ubuf(buf[m++]).i; + h_dpdTheta[nlocal] = buf[m++]; + h_uCond[nlocal] = buf[m++]; + h_uMech[nlocal] = buf[m++]; + h_uChem[nlocal] = buf[m++]; + h_uCG[nlocal] = buf[m++]; + h_uCGnew[nlocal] = buf[m++]; + + if (atom->nextra_grow) + for (int iextra = 0; iextra < atom->nextra_grow; iextra++) + m += modify->fix[atom->extra_grow[iextra]]-> + unpack_exchange(nlocal,&buf[m]); + + atom->nlocal++; + return m; +} + +/* ---------------------------------------------------------------------- + size of restart data for all atoms owned by this proc + include extra data stored by fixes +------------------------------------------------------------------------- */ + +int AtomVecDPDKokkos::size_restart() +{ + int i; + + int nlocal = atom->nlocal; + int n = 15 * nlocal; // 11 + dpdTheta + uCond + uMech + uChem + + if (atom->nextra_restart) + for (int iextra = 0; iextra < atom->nextra_restart; iextra++) + for (i = 0; i < nlocal; i++) + n += modify->fix[atom->extra_restart[iextra]]->size_restart(i); + + return n; +} + +/* ---------------------------------------------------------------------- + pack atom I's data for restart file including extra quantities + xyz must be 1st 3 values, so that read_restart can test on them + molecular types may be negative, but write as positive +------------------------------------------------------------------------- */ + +int AtomVecDPDKokkos::pack_restart(int i, double *buf) +{ + sync(Host,X_MASK | V_MASK | TAG_MASK | TYPE_MASK | + MASK_MASK | IMAGE_MASK ); + + int m = 1; + buf[m++] = h_x(i,0); + buf[m++] = h_x(i,1); + buf[m++] = h_x(i,2); + buf[m++] = ubuf(h_tag(i)).d; + buf[m++] = ubuf(h_type(i)).d; + buf[m++] = ubuf(h_mask(i)).d; + buf[m++] = ubuf(h_image(i)).d; + buf[m++] = h_v(i,0); + buf[m++] = h_v(i,1); + buf[m++] = h_v(i,2); + buf[m++] = h_dpdTheta[i]; + buf[m++] = h_uCond[i]; + buf[m++] = h_uMech[i]; + buf[m++] = h_uChem[i]; + + if (atom->nextra_restart) + for (int iextra = 0; iextra < atom->nextra_restart; iextra++) + m += modify->fix[atom->extra_restart[iextra]]->pack_restart(i,&buf[m]); + + buf[0] = m; + return m; +} + +/* ---------------------------------------------------------------------- + unpack data for one atom from restart file including extra quantities +------------------------------------------------------------------------- */ + +int AtomVecDPDKokkos::unpack_restart(double *buf) +{ + int nlocal = atom->nlocal; + if (nlocal == nmax) { + grow(0); + if (atom->nextra_store) + memory->grow(atom->extra,nmax,atom->nextra_store,"atom:extra"); + } + modified(Host,X_MASK | V_MASK | TAG_MASK | TYPE_MASK | + MASK_MASK | IMAGE_MASK ); + + int m = 1; + h_x(nlocal,0) = buf[m++]; + h_x(nlocal,1) = buf[m++]; + h_x(nlocal,2) = buf[m++]; + h_tag(nlocal) = (tagint) ubuf(buf[m++]).i; + h_type(nlocal) = (int) ubuf(buf[m++]).i; + h_mask(nlocal) = (int) ubuf(buf[m++]).i; + h_image(nlocal) = (imageint) ubuf(buf[m++]).i; + h_v(nlocal,0) = buf[m++]; + h_v(nlocal,1) = buf[m++]; + h_v(nlocal,2) = buf[m++]; + h_dpdTheta[nlocal] = buf[m++]; + h_uCond[nlocal] = buf[m++]; + h_uMech[nlocal] = buf[m++]; + h_uChem[nlocal] = buf[m++]; + + double **extra = atom->extra; + if (atom->nextra_store) { + int size = static_cast (ubuf(buf[m++]).i) - m; + for (int i = 0; i < size; i++) extra[nlocal][i] = buf[m++]; + } + + atom->nlocal++; + return m; +} + +/* ---------------------------------------------------------------------- + create one atom of itype at coord + set other values to defaults +------------------------------------------------------------------------- */ + +void AtomVecDPDKokkos::create_atom(int itype, double *coord) +{ + int nlocal = atom->nlocal; + if (nlocal == nmax) { + //if(nlocal>2) printf("typeA: %i %i\n",type[0],type[1]); + atomKK->modified(Host,ALL_MASK); + grow(0); + //if(nlocal>2) printf("typeB: %i %i\n",type[0],type[1]); + } + atomKK->modified(Host,ALL_MASK); + + tag[nlocal] = 0; + type[nlocal] = itype; + h_x(nlocal,0) = coord[0]; + h_x(nlocal,1) = coord[1]; + h_x(nlocal,2) = coord[2]; + h_mask[nlocal] = 1; + h_image[nlocal] = ((tagint) IMGMAX << IMG2BITS) | + ((tagint) IMGMAX << IMGBITS) | IMGMAX; + h_v(nlocal,0) = 0.0; + h_v(nlocal,1) = 0.0; + h_v(nlocal,2) = 0.0; + h_rho[nlocal] = 0.0; + h_dpdTheta[nlocal] = 0.0; + h_uCond[nlocal] = 0.0; + h_uMech[nlocal] = 0.0; + h_uChem[nlocal] = 0.0; + h_uCG[nlocal] = 0.0; + h_uCGnew[nlocal] = 0.0; + h_duChem[nlocal] = 0.0; + + atom->nlocal++; +} + +/* ---------------------------------------------------------------------- + unpack one line from Atoms section of data file + initialize other atom quantities +------------------------------------------------------------------------- */ + +void AtomVecDPDKokkos::data_atom(double *coord, tagint imagetmp, + char **values) +{ + int nlocal = atom->nlocal; + if (nlocal == nmax) grow(0); + + h_tag[nlocal] = ATOTAGINT(values[0]); + h_type[nlocal] = atoi(values[1]); + if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes) + error->one(FLERR,"Invalid atom type in Atoms section of data file"); + + h_dpdTheta[nlocal] = atof(values[2]); + if (h_dpdTheta[nlocal] <= 0) + error->one(FLERR,"Internal temperature in Atoms section of date file must be > zero"); + + h_x(nlocal,0) = coord[0]; + h_x(nlocal,1) = coord[1]; + h_x(nlocal,2) = coord[2]; + + h_image[nlocal] = imagetmp; + + h_mask[nlocal] = 1; + h_v(nlocal,0) = 0.0; + h_v(nlocal,1) = 0.0; + h_v(nlocal,2) = 0.0; + + h_rho[nlocal] = 0.0; + h_uCond[nlocal] = 0.0; + h_uMech[nlocal] = 0.0; + h_uChem[nlocal] = 0.0; + h_uCG[nlocal] = 0.0; + h_uCGnew[nlocal] = 0.0; + + atomKK->modified(Host,ALL_MASK); + + atom->nlocal++; +} + +/* ---------------------------------------------------------------------- + unpack hybrid quantities from one line in Atoms section of data file + initialize other atom quantities for this sub-style +------------------------------------------------------------------------- */ + +int AtomVecDPDKokkos::data_atom_hybrid(int nlocal, char **values) +{ + h_dpdTheta(nlocal) = atof(values[0]); + + return 1; +} + +/* ---------------------------------------------------------------------- + pack atom info for data file including 3 image flags +------------------------------------------------------------------------- */ + +void AtomVecDPDKokkos::pack_data(double **buf) +{ + int nlocal = atom->nlocal; + for (int i = 0; i < nlocal; i++) { + buf[i][0] = ubuf(h_tag(i)).d; + buf[i][1] = ubuf(h_type(i)).d; + buf[i][2] = h_dpdTheta(i); + buf[i][3] = h_x(i,0); + buf[i][4] = h_x(i,1); + buf[i][5] = h_x(i,2); + buf[i][6] = (h_image[i] & IMGMASK) - IMGMAX; + buf[i][7] = (h_image[i] >> IMGBITS & IMGMASK) - IMGMAX; + buf[i][8] = (h_image[i] >> IMG2BITS) - IMGMAX; + } +} + +/* ---------------------------------------------------------------------- + pack hybrid atom info for data file +------------------------------------------------------------------------- */ + +int AtomVecDPDKokkos::pack_data_hybrid(int i, double *buf) +{ + buf[0] = h_dpdTheta(i); + return 1; +} + +/* ---------------------------------------------------------------------- + write atom info to data file including 3 image flags +------------------------------------------------------------------------- */ + +void AtomVecDPDKokkos::write_data(FILE *fp, int n, double **buf) +{ + for (int i = 0; i < n; i++) + fprintf(fp,TAGINT_FORMAT " %d %-1.16e %-1.16e %-1.16e %-1.16e %d %d %d\n", + (tagint) ubuf(buf[i][0]).i,(int) ubuf(buf[i][1]).i, + buf[i][2],buf[i][3],buf[i][4],buf[i][5], + (int) ubuf(buf[i][6]).i,(int) ubuf(buf[i][7]).i, + (int) ubuf(buf[i][8]).i); +} + +/* ---------------------------------------------------------------------- + write hybrid atom info to data file +------------------------------------------------------------------------- */ + +int AtomVecDPDKokkos::write_data_hybrid(FILE *fp, double *buf) +{ + fprintf(fp," %-1.16e",buf[0]); + return 1; +} + +/* ---------------------------------------------------------------------- + return # of bytes of allocated memory +------------------------------------------------------------------------- */ + +bigint AtomVecDPDKokkos::memory_usage() +{ + bigint bytes = 0; + + if (atom->memcheck("tag")) bytes += memory->usage(tag,nmax); + if (atom->memcheck("type")) bytes += memory->usage(type,nmax); + if (atom->memcheck("mask")) bytes += memory->usage(mask,nmax); + if (atom->memcheck("image")) bytes += memory->usage(image,nmax); + if (atom->memcheck("x")) bytes += memory->usage(x,nmax,3); + if (atom->memcheck("v")) bytes += memory->usage(v,nmax,3); + if (atom->memcheck("f")) bytes += memory->usage(f,nmax*commKK->nthreads,3); + if (atom->memcheck("rho")) bytes += memory->usage(rho,nmax); + if (atom->memcheck("dpdTheta")) bytes += memory->usage(dpdTheta,nmax); + if (atom->memcheck("uCond")) bytes += memory->usage(uCond,nmax); + if (atom->memcheck("uMech")) bytes += memory->usage(uMech,nmax); + if (atom->memcheck("uChem")) bytes += memory->usage(uChem,nmax); + if (atom->memcheck("uCG")) bytes += memory->usage(uCG,nmax); + if (atom->memcheck("uCGnew")) bytes += memory->usage(uCGnew,nmax); + if (atom->memcheck("duChem")) bytes += memory->usage(duChem,nmax); + + return bytes; +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecDPDKokkos::sync(ExecutionSpace space, unsigned int mask) +{ + if (space == Device) { + if (mask & X_MASK) atomKK->k_x.sync(); + if (mask & V_MASK) atomKK->k_v.sync(); + if (mask & F_MASK) atomKK->k_f.sync(); + if (mask & TAG_MASK) atomKK->k_tag.sync(); + if (mask & TYPE_MASK) atomKK->k_type.sync(); + if (mask & MASK_MASK) atomKK->k_mask.sync(); + if (mask & IMAGE_MASK) atomKK->k_image.sync(); + } else { + if (mask & X_MASK) atomKK->k_x.sync(); + if (mask & V_MASK) atomKK->k_v.sync(); + if (mask & F_MASK) atomKK->k_f.sync(); + if (mask & TAG_MASK) atomKK->k_tag.sync(); + if (mask & TYPE_MASK) atomKK->k_type.sync(); + if (mask & MASK_MASK) atomKK->k_mask.sync(); + if (mask & IMAGE_MASK) atomKK->k_image.sync(); + } +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecDPDKokkos::sync_overlapping_device(ExecutionSpace space, unsigned int mask) +{ + if (space == Device) { + if ((mask & X_MASK) && atomKK->k_x.need_sync()) + perform_async_copy(atomKK->k_x,space); + if ((mask & V_MASK) && atomKK->k_v.need_sync()) + perform_async_copy(atomKK->k_v,space); + if ((mask & F_MASK) && atomKK->k_f.need_sync()) + perform_async_copy(atomKK->k_f,space); + if ((mask & TAG_MASK) && atomKK->k_tag.need_sync()) + perform_async_copy(atomKK->k_tag,space); + if ((mask & TYPE_MASK) && atomKK->k_type.need_sync()) + perform_async_copy(atomKK->k_type,space); + if ((mask & MASK_MASK) && atomKK->k_mask.need_sync()) + perform_async_copy(atomKK->k_mask,space); + if ((mask & IMAGE_MASK) && atomKK->k_image.need_sync()) + perform_async_copy(atomKK->k_image,space); + } else { + if ((mask & X_MASK) && atomKK->k_x.need_sync()) + perform_async_copy(atomKK->k_x,space); + if ((mask & V_MASK) && atomKK->k_v.need_sync()) + perform_async_copy(atomKK->k_v,space); + if ((mask & F_MASK) && atomKK->k_f.need_sync()) + perform_async_copy(atomKK->k_f,space); + if ((mask & TAG_MASK) && atomKK->k_tag.need_sync()) + perform_async_copy(atomKK->k_tag,space); + if ((mask & TYPE_MASK) && atomKK->k_type.need_sync()) + perform_async_copy(atomKK->k_type,space); + if ((mask & MASK_MASK) && atomKK->k_mask.need_sync()) + perform_async_copy(atomKK->k_mask,space); + if ((mask & IMAGE_MASK) && atomKK->k_image.need_sync()) + perform_async_copy(atomKK->k_image,space); + } +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecDPDKokkos::modified(ExecutionSpace space, unsigned int mask) +{ + if (space == Device) { + if (mask & X_MASK) atomKK->k_x.modify(); + if (mask & V_MASK) atomKK->k_v.modify(); + if (mask & F_MASK) atomKK->k_f.modify(); + if (mask & TAG_MASK) atomKK->k_tag.modify(); + if (mask & TYPE_MASK) atomKK->k_type.modify(); + if (mask & MASK_MASK) atomKK->k_mask.modify(); + if (mask & IMAGE_MASK) atomKK->k_image.modify(); + } else { + if (mask & X_MASK) atomKK->k_x.modify(); + if (mask & V_MASK) atomKK->k_v.modify(); + if (mask & F_MASK) atomKK->k_f.modify(); + if (mask & TAG_MASK) atomKK->k_tag.modify(); + if (mask & TYPE_MASK) atomKK->k_type.modify(); + if (mask & MASK_MASK) atomKK->k_mask.modify(); + if (mask & IMAGE_MASK) atomKK->k_image.modify(); + } +} + diff --git a/src/USER-DPD/atom_vec_dpd_kokkos.h b/src/USER-DPD/atom_vec_dpd_kokkos.h new file mode 100644 index 0000000000..d108e58ae7 --- /dev/null +++ b/src/USER-DPD/atom_vec_dpd_kokkos.h @@ -0,0 +1,135 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale AtomicKokkos/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef ATOM_CLASS + +AtomStyle(dpd/kk,AtomVecDPDKokkos) + +#else + +#ifndef LMP_ATOM_VEC_DPD_KOKKOS_H +#define LMP_ATOM_VEC_DPD_KOKKOS_H + +#include "atom_vec_kokkos.h" +#include "kokkos_type.h" + +namespace LAMMPS_NS { + +class AtomVecDPDKokkos : public AtomVecKokkos { + public: + AtomVecDPDKokkos(class LAMMPS *); + virtual ~AtomVecDPDKokkos() {} + void grow(int); + void copy(int, int, int); + int pack_comm(int, int *, double *, int, int *); + int pack_comm_vel(int, int *, double *, int, int *); + int pack_comm_hybrid(int, int *, double *); + void unpack_comm(int, int, double *); + void unpack_comm_vel(int, int, double *); + int unpack_comm_hybrid(int, int, double *); + int pack_reverse(int, int, double *); + void unpack_reverse(int, int *, double *); + int pack_border(int, int *, double *, int, int *); + int pack_border_vel(int, int *, double *, int, int *); + int pack_border_hybrid(int, int *, double *); + void unpack_border(int, int, double *); + void unpack_border_vel(int, int, double *); + int unpack_border_hybrid(int, int, double *); + int pack_exchange(int, double *); + int unpack_exchange(double *); + int size_restart(); + int pack_restart(int, double *); + int unpack_restart(double *); + void create_atom(int, double *); + void data_atom(double *, tagint, char **); + int data_atom_hybrid(int, char **); + void pack_data(double **); + int pack_data_hybrid(int, double *); + void write_data(FILE *, int, double **); + int write_data_hybrid(FILE *, double *); + bigint memory_usage(); + + void grow_reset(); + int pack_comm_kokkos(const int &n, const DAT::tdual_int_2d &k_sendlist, + const int & iswap, + const DAT::tdual_xfloat_2d &buf, + const int &pbc_flag, const int pbc[]); + void unpack_comm_kokkos(const int &n, const int &nfirst, + const DAT::tdual_xfloat_2d &buf); + int pack_comm_self(const int &n, const DAT::tdual_int_2d &list, + const int & iswap, const int nfirst, + const int &pbc_flag, const int pbc[]); + 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); + void unpack_border_kokkos(const int &n, const int &nfirst, + const DAT::tdual_xfloat_2d &buf, + ExecutionSpace space); + int pack_exchange_kokkos(const int &nsend,DAT::tdual_xfloat_2d &buf, + DAT::tdual_int_1d k_sendlist, + DAT::tdual_int_1d k_copylist, + ExecutionSpace space, int dim, + X_FLOAT lo, X_FLOAT hi); + int unpack_exchange_kokkos(DAT::tdual_xfloat_2d &k_buf, int nrecv, + int nlocal, int dim, X_FLOAT lo, X_FLOAT hi, + ExecutionSpace space); + + void sync(ExecutionSpace space, unsigned int mask); + void modified(ExecutionSpace space, unsigned int mask); + void sync_overlapping_device(ExecutionSpace space, unsigned int mask); + double *uCond,*uMech,*uChem,*uCG,*uCGnew,*rho,*dpdTheta; + double *duChem; + + protected: + DAT::t_efloat_1d d_uCond, d_uMech, d_uChem, d_uCG, d_uCGnew,d_rho,d_dpdTheta,d_duChem; + HAT::t_efloat_1d h_uCond, h_uMech, h_uChem, h_uCG, h_uCGnew,h_rho,h_dpdTheta,h_duChem; + + tagint *tag; + imageint *image; + int *type,*mask; + double **x,**v,**f; + + DAT::t_tagint_1d d_tag; + HAT::t_tagint_1d h_tag; + DAT::t_imageint_1d d_image; + HAT::t_imageint_1d h_image; + DAT::t_int_1d d_type, d_mask; + HAT::t_int_1d h_type, h_mask; + + DAT::t_x_array d_x; + DAT::t_v_array d_v; + DAT::t_f_array d_f; + HAT::t_x_array h_x; + HAT::t_v_array h_v; + HAT::t_f_array h_f; + + DAT::tdual_int_1d k_count; +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +E: Per-processor system is too big + +The number of owned atoms plus ghost atoms on a single +processor must fit in 32-bit integer. + +E: Invalid atom type in Atoms section of data file + +Atom types must range from 1 to specified # of types. + +*/ diff --git a/src/USER-DPD/pair_dpd_fdt_energy_kokkos.cpp b/src/USER-DPD/pair_dpd_fdt_energy_kokkos.cpp new file mode 100644 index 0000000000..f7e1fecc09 --- /dev/null +++ b/src/USER-DPD/pair_dpd_fdt_energy_kokkos.cpp @@ -0,0 +1,373 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: James Larentzos (U.S. Army Research Laboratory) +------------------------------------------------------------------------- */ + +#include +#include +#include +#include +#include "pair_dpd_fdt_energy_kokkos.h" +#include "kokkos.h" +#include "atom_kokkos.h" +#include "atom_vec.h" +#include "comm.h" +#include "update.h" +#include "fix.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "neigh_request.h" +#include "random_mars.h" +#include "math_const.h" +#include "memory.h" +#include "modify.h" +#include "error.h" +#include "atom_masks.h" + +using namespace LAMMPS_NS; +using namespace MathConst; + +#define KOKKOS_CUDA_MAX_THREADS 256 +#define KOKKOS_CUDA_MIN_BLOCKS 8 + +#define EPSILON 1.0e-10 + +/* ---------------------------------------------------------------------- */ + +template +PairDPDfdtEnergyKokkos::PairDPDfdtEnergyKokkos(LAMMPS *lmp) : PairDPDfdtEnergy(lmp) +{ + atomKK = (AtomKokkos *) atom; + execution_space = ExecutionSpaceFromDevice::space; + cutsq = NULL; +} + +/* ---------------------------------------------------------------------- */ + +template +PairDPDfdtEnergyKokkos::~PairDPDfdtEnergyKokkos() +{ + if (allocated) { + memory->destroy_kokkos(k_eatom,eatom); + memory->destroy_kokkos(k_vatom,vatom); + k_cutsq = DAT::tdual_ffloat_2d(); + memory->sfree(cutsq); + eatom = NULL; + vatom = NULL; + cutsq = NULL; + } +} + +/* ---------------------------------------------------------------------- */ + +template +void PairDPDfdtEnergyKokkos::cleanup_copy() { + // WHY needed: this prevents parent copy from deallocating any arrays + allocated = 0; + cutsq = NULL; + eatom = NULL; + vatom = NULL; +} + +/* ---------------------------------------------------------------------- */ + +template +void PairDPDfdtEnergyKokkos::compute(int eflag_in, int vflag_in) +{ + eflag = eflag_in; + vflag = vflag_in; + + if (eflag || vflag) ev_setup(eflag,vflag); + else evflag = vflag_fdotr = 0; + + // reallocate per-atom arrays if necessary + + if (eflag_atom) { + memory->destroy_kokkos(k_eatom,eatom); + memory->create_kokkos(k_eatom,eatom,maxeatom,"pair:eatom"); + d_eatom = k_eatom.view(); + } + if (vflag_atom) { + memory->destroy_kokkos(k_vatom,vatom); + memory->create_kokkos(k_vatom,vatom,maxvatom,6,"pair:vatom"); + d_vatom = k_vatom.view(); + } + + atomKK->sync(execution_space,datamask_read); + k_cutsq.template sync(); + if (eflag || vflag) atomKK->modified(execution_space,datamask_modify); + else atomKK->modified(execution_space,F_MASK); + + x = atomKK->k_x.view(); + c_x = atomKK->k_x.view(); + f = atomKK->k_f.view(); + type = atomKK->k_type.view(); + tag = atomKK->k_tag.view(); + nlocal = atom->nlocal; + nall = atom->nlocal + atom->nghost; + newton_pair = force->newton_pair; + special_lj[0] = force->special_lj[0]; + special_lj[1] = force->special_lj[1]; + special_lj[2] = force->special_lj[2]; + special_lj[3] = force->special_lj[3]; + + // loop over neighbors of my atoms + + EV_FLOAT ev = pair_compute,void >(this,(NeighListKokkos*)list); + + if (eflag_global) eng_vdwl += ev.evdwl; + if (vflag_global) { + virial[0] += ev.v[0]; + virial[1] += ev.v[1]; + virial[2] += ev.v[2]; + virial[3] += ev.v[3]; + virial[4] += ev.v[4]; + virial[5] += ev.v[5]; + } + + if (vflag_fdotr) pair_virial_fdotr_compute(this); + + if (eflag_atom) { + k_eatom.template modify(); + k_eatom.template sync(); + } + + if (vflag_atom) { + k_vatom.template modify(); + k_vatom.template sync(); + } +} + +template +template +KOKKOS_INLINE_FUNCTION +F_FLOAT PairDPDfdtEnergyKokkos:: +compute_fpair(const F_FLOAT& rsq, const int& i, const int&j, const int& itype, const int& jtype) const { + (void) i; + (void) j; + const F_FLOAT r = sqrt(rsq); + if (r < EPSILON) return 0; // r can be 0.0 in DPD systems + const F_FLOAT rinv = 1.0/r; + const F_FLOAT wr = 1.0 - r/cut[itype][jtype]; + const F_FLOAT wd = wr*wr; + + // conservative force = a0 * wr + return a0[itype][jtype]*wr*rinv; +} + +template +template +KOKKOS_INLINE_FUNCTION +F_FLOAT PairDPDfdtEnergyKokkos:: +compute_evdwl(const F_FLOAT& rsq, const int& i, const int&j, const int& itype, const int& jtype) const { + (void) i; + (void) j; + const F_FLOAT r = sqrt(rsq); + if (r < EPSILON) return 0; // r can be 0.0 in DPD systems + const F_FLOAT rinv = 1.0/r; + const F_FLOAT wr = 1.0 - r/cut[itype][jtype]; + const F_FLOAT wd = wr*wr; + // unshifted eng of conservative term: + // evdwl = -a0[itype][jtype]*r * (1.0-0.5*r/cut[itype][jtype]); + // eng shifted to 0.0 at cutoff + return 0.5*a0[itype][jtype]*cut[itype][jtype] * wd; +} + + +/* + int i,j,ii,jj,inum,jnum,itype,jtype; + double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair; + double rsq,r,rinv,wd,wr,factor_dpd; + int *ilist,*jlist,*numneigh,**firstneigh; + + evdwl = 0.0; + if (eflag || vflag) ev_setup(eflag,vflag); + else evflag = vflag_fdotr = 0; + + double **x = atom->x; + double **f = atom->f; + int *type = atom->type; + int nlocal = atom->nlocal; + double *special_lj = force->special_lj; + int newton_pair = force->newton_pair; + + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // loop over neighbors of my atoms + + for (ii = 0; ii < inum; ii++) { + i = ilist[ii]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + itype = type[i]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + factor_dpd = special_lj[sbmask(j)]; + j &= NEIGHMASK; + + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx*delx + dely*dely + delz*delz; + jtype = type[j]; + + if (rsq < cutsq[itype][jtype]) { + r = sqrt(rsq); + if (r < EPSILON) continue; // r can be 0.0 in DPD systems + rinv = 1.0/r; + wr = 1.0 - r/cut[itype][jtype]; + wd = wr*wr; + + // conservative force = a0 * wr + fpair = a0[itype][jtype]*wr; + fpair *= factor_dpd*rinv; + + f[i][0] += delx*fpair; + f[i][1] += dely*fpair; + f[i][2] += delz*fpair; + if (newton_pair || j < nlocal) { + f[j][0] -= delx*fpair; + f[j][1] -= dely*fpair; + f[j][2] -= delz*fpair; + } + + if (eflag) { + // unshifted eng of conservative term: + // evdwl = -a0[itype][jtype]*r * (1.0-0.5*r/cut[itype][jtype]); + // eng shifted to 0.0 at cutoff + evdwl = 0.5*a0[itype][jtype]*cut[itype][jtype] * wd; + evdwl *= factor_dpd; + } + + if (evflag) ev_tally(i,j,nlocal,newton_pair, + evdwl,0.0,fpair,delx,dely,delz); + } + } + } + + if (vflag_fdotr) virial_fdotr_compute(); +} +*/ + +/* ---------------------------------------------------------------------- + allocate all arrays +------------------------------------------------------------------------- */ + +template +void PairDPDfdtEnergyKokkos::allocate() +{ + PairDPDfdtEnergy::allocate(); + + int n = atom->ntypes; + memory->destroy(cutsq); + memory->create_kokkos(k_cutsq,cutsq,n+1,n+1,"pair:cutsq"); + d_cutsq = k_cutsq.template view(); +} + +/* ---------------------------------------------------------------------- + global settings +------------------------------------------------------------------------- */ + +template +void PairDPDfdtEnergyKokkos::settings(int narg, char **arg) +{ + if (narg != 2) error->all(FLERR,"Illegal pair_style command"); + + PairDPDfdtEnergy::settings(2,arg); +} + +/* ---------------------------------------------------------------------- + init specific to this pair style +------------------------------------------------------------------------- */ + +template +void PairDPDfdtEnergyKokkos::init_style() +{ + PairDPDfdtEnergy::init_style(); + + neighflag = lmp->kokkos->neighflag; + int irequest = neighbor->nrequest - 1; + + neighbor->requests[irequest]-> + kokkos_host = Kokkos::Impl::is_same::value && + !Kokkos::Impl::is_same::value; + neighbor->requests[irequest]-> + kokkos_device = Kokkos::Impl::is_same::value; + + if (neighflag == HALF || neighflag == HALFTHREAD) { + neighbor->requests[irequest]->full = 0; + neighbor->requests[irequest]->half = 1; + neighbor->requests[irequest]->full_cluster = 0; + } else { + error->all(FLERR,"Cannot use chosen neighbor list style with dpd/fdt/energy/kk"); + } + +/* + if (comm->ghost_velocity == 0) + error->all(FLERR,"Pair dpd/fdt/energy requires ghost atoms store velocity"); + + // if newton off, forces between atoms ij will be double computed + // using different random numbers + + if (force->newton_pair == 0 && comm->me == 0) error->warning(FLERR, + "Pair dpd/fdt/energy requires newton pair on"); + + int irequest = neighbor->request(this,instance_me); + neighbor->requests[irequest]->ssa = 0; + for (int i = 0; i < modify->nfix; i++) + if (strcmp(modify->fix[i]->style,"shardlow") == 0) + neighbor->requests[irequest]->ssa = 1; + + bool eos_flag = false; + for (int i = 0; i < modify->nfix; i++) + if (strncmp(modify->fix[i]->style,"eos",3) == 0) eos_flag = true; + if(!eos_flag) error->all(FLERR,"pair_style dpd/fdt/energy requires an EOS to be specified"); +*/ +} + +/* ---------------------------------------------------------------------- + init for one type pair i,j and corresponding j,i +------------------------------------------------------------------------- */ + +template +double PairDPDfdtEnergyKokkos::init_one(int i, int j) +{ + double cutone = PairDPDfdtEnergy::init_one(i,j); + + if(i(); + + return cutone; +} + + +namespace LAMMPS_NS { +template class PairDPDfdtEnergyKokkos; +#ifdef KOKKOS_HAVE_CUDA +template class PairDPDfdtEnergyKokkos; +#endif +} + diff --git a/src/USER-DPD/pair_dpd_fdt_energy_kokkos.h b/src/USER-DPD/pair_dpd_fdt_energy_kokkos.h new file mode 100644 index 0000000000..a8a5f25801 --- /dev/null +++ b/src/USER-DPD/pair_dpd_fdt_energy_kokkos.h @@ -0,0 +1,119 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(dpd/fdt/energy/kk,PairDPDfdtEnergyKokkos) +PairStyle(dpd/fdt/energy/kk/device,PairDPDfdtEnergyKokkos) +PairStyle(dpd/fdt/energy/kk/host,PairDPDfdtEnergyKokkos) + +#else + +#ifndef LMP_PAIR_DPD_FDT_ENERGY_KOKKOS_H +#define LMP_PAIR_DPD_FDT_ENERGY_KOKKOS_H + +#include "pair_kokkos.h" +#include "pair_dpd_fdt_energy.h" +#include "neigh_list_kokkos.h" + +namespace LAMMPS_NS { + +template +class PairDPDfdtEnergyKokkos : public PairDPDfdtEnergy { + public: + enum {EnabledNeighFlags=HALFTHREAD|HALF}; + enum {COUL_FLAG=0}; + typedef DeviceType device_type; + PairDPDfdtEnergyKokkos(class LAMMPS *); + virtual ~PairDPDfdtEnergyKokkos(); + virtual void compute(int, int); + virtual void settings(int, char **); + void init_style(); + double init_one(int, int); + + protected: + void cleanup_copy(); + + template + KOKKOS_INLINE_FUNCTION + F_FLOAT compute_fpair(const F_FLOAT& rsq, const int& i, const int&j, const int& itype, const int& jtype) const; + + template + KOKKOS_INLINE_FUNCTION + F_FLOAT compute_evdwl(const F_FLOAT& rsq, const int& i, const int&j, const int& itype, const int& jtype) const; + + F_FLOAT m_cutsq[MAX_TYPES_STACKPARAMS+1][MAX_TYPES_STACKPARAMS+1]; + typename ArrayTypes::t_x_array_randomread x; + typename ArrayTypes::t_x_array c_x; + typename ArrayTypes::t_f_array f; + typename ArrayTypes::t_int_1d_randomread type; + + DAT::tdual_efloat_1d k_eatom; + DAT::tdual_virial_array k_vatom; + typename ArrayTypes::t_efloat_1d d_eatom; + typename ArrayTypes::t_virial_array d_vatom; + typename ArrayTypes::t_tagint_1d tag; + + int newton_pair; + double special_lj[4]; + + typename ArrayTypes::tdual_ffloat_2d k_cutsq; + typename ArrayTypes::t_ffloat_2d d_cutsq; + + + int neighflag; + int nlocal,nall,eflag,vflag; + + void allocate(); + + friend class PairComputeFunctor; + friend class PairComputeFunctor; + friend class PairComputeFunctor; + friend class PairComputeFunctor; + friend EV_FLOAT pair_compute_neighlist(PairDPDfdtEnergyKokkos*,NeighListKokkos*); + friend EV_FLOAT pair_compute_neighlist(PairDPDfdtEnergyKokkos*,NeighListKokkos*); + friend EV_FLOAT pair_compute(PairDPDfdtEnergyKokkos*,NeighListKokkos*); + friend void pair_virial_fdotr_compute(PairDPDfdtEnergyKokkos*); +}; + +} + +#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: Pair dpd/fdt/energy requires ghost atoms store velocity + +Use the communicate vel yes command to enable this. + +E: Pair dpd/fdt/energy requires newton pair on + +Self-explanatory. + +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 8f78157202299a5bf9d860c90f30c8340d2d0cfc Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Mon, 21 Nov 2016 12:32:48 -0500 Subject: [PATCH 002/439] USER-DPD: aplly unpack_comm_hybrid bugfix d31121b to atom_vec_dpd_kokkos.cpp --- src/USER-DPD/atom_vec_dpd_kokkos.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/USER-DPD/atom_vec_dpd_kokkos.cpp b/src/USER-DPD/atom_vec_dpd_kokkos.cpp index c58b592e53..c79559172f 100644 --- a/src/USER-DPD/atom_vec_dpd_kokkos.cpp +++ b/src/USER-DPD/atom_vec_dpd_kokkos.cpp @@ -1205,6 +1205,8 @@ int AtomVecDPDKokkos::unpack_comm_hybrid(int n, int first, double *buf) h_uCond(i) = buf[m++]; h_uMech(i) = buf[m++]; h_uChem(i) = buf[m++]; + h_uCG(i) = buf[m++]; + h_uCGnew(i) = buf[m++]; } return m; } From 75907916045ff25745389db4b11773c820bc13de Mon Sep 17 00:00:00 2001 From: stamoor Date: Mon, 21 Nov 2016 13:54:14 -0700 Subject: [PATCH 003/439] Integrating atom_vec_dpd into the Kokkos package --- src/KOKKOS/atom_vec_dpd_kokkos.cpp | 1874 ++++++++++++++++++++++++++++ src/KOKKOS/atom_vec_dpd_kokkos.h | 135 ++ 2 files changed, 2009 insertions(+) create mode 100644 src/KOKKOS/atom_vec_dpd_kokkos.cpp create mode 100644 src/KOKKOS/atom_vec_dpd_kokkos.h diff --git a/src/KOKKOS/atom_vec_dpd_kokkos.cpp b/src/KOKKOS/atom_vec_dpd_kokkos.cpp new file mode 100644 index 0000000000..c79559172f --- /dev/null +++ b/src/KOKKOS/atom_vec_dpd_kokkos.cpp @@ -0,0 +1,1874 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale AtomicKokkos/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include +#include "atom_vec_dpd_kokkos.h" +#include "atom_kokkos.h" +#include "comm_kokkos.h" +#include "domain.h" +#include "modify.h" +#include "fix.h" +#include "atom_masks.h" +#include "memory.h" +#include "error.h" + +using namespace LAMMPS_NS; + +#define DELTA 10000 + +/* ---------------------------------------------------------------------- */ + +AtomVecDPDKokkos::AtomVecDPDKokkos(LAMMPS *lmp) : AtomVecKokkos(lmp) +{ + molecular = 0; + mass_type = 1; + + comm_x_only = comm_f_only = 0; + size_forward = 7; + size_reverse = 3; + size_border = 12; + size_velocity = 3; + size_data_atom = 6; + size_data_vel = 4; + xcol_data = 4; + + atom->rho_flag = 1; + atom->dpd_flag = 1; + + k_count = DAT::tdual_int_1d("atom::k_count",1); + atomKK = (AtomKokkos *) atom; + commKK = (CommKokkos *) comm; +} + +/* ---------------------------------------------------------------------- + grow atom arrays + n = 0 grows arrays by DELTA + n > 0 allocates arrays to size n +------------------------------------------------------------------------- */ + +void AtomVecDPDKokkos::grow(int n) +{ + if (n == 0) nmax += DELTA; + else nmax = n; + atomKK->nmax = nmax; + if (nmax < 0 || nmax > MAXSMALLINT) + error->one(FLERR,"Per-processor system is too big"); + + sync(Device,ALL_MASK); + modified(Device,ALL_MASK); + + memory->grow_kokkos(atomKK->k_tag,atomKK->tag,nmax,"atom:tag"); + memory->grow_kokkos(atomKK->k_type,atomKK->type,nmax,"atom:type"); + memory->grow_kokkos(atomKK->k_mask,atomKK->mask,nmax,"atom:mask"); + memory->grow_kokkos(atomKK->k_image,atomKK->image,nmax,"atom:image"); + + memory->grow_kokkos(atomKK->k_x,atomKK->x,nmax,3,"atom:x"); + memory->grow_kokkos(atomKK->k_v,atomKK->v,nmax,3,"atom:v"); + memory->grow_kokkos(atomKK->k_f,atomKK->f,nmax,3,"atom:f"); + + + memory->grow_kokkos(atomKK->k_rho,atomKK->rho,nmax,"atom:rho"); + memory->grow_kokkos(atomKK->k_dpdTheta,atomKK->dpdTheta,nmax,"atom:dpdTheta"); + memory->grow_kokkos(atomKK->k_uCond,atomKK->uCond,nmax,"atom:uCond"); + memory->grow_kokkos(atomKK->k_uMech,atomKK->uMech,nmax,"atom:uMech"); + memory->grow_kokkos(atomKK->k_uChem,atomKK->uChem,nmax,"atom:uChem"); + memory->grow_kokkos(atomKK->k_uCG,atomKK->uCG,nmax,"atom:uCG"); + memory->grow_kokkos(atomKK->k_uCGnew,atomKK->uCGnew,nmax,"atom:uCGnew"); + memory->grow_kokkos(atomKK->k_duChem,atomKK->duChem,nmax,"atom:duChem"); + + grow_reset(); + sync(Host,ALL_MASK); + + if (atom->nextra_grow) + for (int iextra = 0; iextra < atom->nextra_grow; iextra++) + modify->fix[atom->extra_grow[iextra]]->grow_arrays(nmax); +} + +/* ---------------------------------------------------------------------- + reset local array ptrs +------------------------------------------------------------------------- */ + +void AtomVecDPDKokkos::grow_reset() +{ + tag = atomKK->tag; + d_tag = atomKK->k_tag.d_view; + h_tag = atomKK->k_tag.h_view; + + type = atomKK->type; + d_type = atomKK->k_type.d_view; + h_type = atomKK->k_type.h_view; + mask = atomKK->mask; + d_mask = atomKK->k_mask.d_view; + h_mask = atomKK->k_mask.h_view; + image = atomKK->image; + d_image = atomKK->k_image.d_view; + h_image = atomKK->k_image.h_view; + + x = atomKK->x; + d_x = atomKK->k_x.d_view; + h_x = atomKK->k_x.h_view; + v = atomKK->v; + d_v = atomKK->k_v.d_view; + h_v = atomKK->k_v.h_view; + f = atomKK->f; + d_f = atomKK->k_f.d_view; + h_f = atomKK->k_f.h_view; + + rho = atomKK->rho; + d_rho = atomKK->k_rho.d_view; + h_rho = atomKK->k_rho.h_view; + dpdTheta = atomKK->dpdTheta; + d_dpdTheta = atomKK->k_dpdTheta.d_view; + h_dpdTheta = atomKK->k_dpdTheta.h_view; + uCond = atomKK->uCond; + d_uCond = atomKK->k_uCond.d_view;; + h_uCond = atomKK->k_uCond.h_view; + uMech = atomKK->uMech; + d_uMech = atomKK->k_uMech.d_view;; + h_uMech = atomKK->k_uMech.h_view; + uChem = atomKK->uChem; + d_uChem = atomKK->k_uChem.d_view;; + h_uChem = atomKK->k_uChem.h_view; + uCG = atomKK->uCG; + d_uCG = atomKK->k_uCG.d_view;; + h_uCG = atomKK->k_uCG.h_view; + uCGnew = atomKK->uCGnew; + d_uCGnew = atomKK->k_uCGnew.d_view;; + h_uCGnew = atomKK->k_uCGnew.h_view; + duChem = atomKK->duChem; + d_duChem = atomKK->k_duChem.d_view;; + h_duChem = atomKK->k_duChem.h_view; +} + +/* ---------------------------------------------------------------------- + copy atom I info to atom J +------------------------------------------------------------------------- */ + +void AtomVecDPDKokkos::copy(int i, int j, int delflag) +{ + h_tag[j] = h_tag[i]; + h_type[j] = h_type[i]; + mask[j] = mask[i]; + h_image[j] = h_image[i]; + h_x(j,0) = h_x(i,0); + h_x(j,1) = h_x(i,1); + h_x(j,2) = h_x(i,2); + h_v(j,0) = h_v(i,0); + h_v(j,1) = h_v(i,1); + h_v(j,2) = h_v(i,2); + h_dpdTheta[j] = h_dpdTheta[i]; + h_uCond[j] = h_uCond[i]; + h_uMech[j] = h_uMech[i]; + h_uChem[j] = h_uChem[i]; + h_uCG[j] = h_uCG[i]; + h_uCGnew[j] = h_uCGnew[i]; + + if (atom->nextra_grow) + for (int iextra = 0; iextra < atom->nextra_grow; iextra++) + modify->fix[atom->extra_grow[iextra]]->copy_arrays(i,j,delflag); +} + +/* ---------------------------------------------------------------------- */ + +template +struct AtomVecDPDKokkos_PackComm { + typedef DeviceType device_type; + + typename ArrayTypes::t_x_array_randomread _x; + typename ArrayTypes::t_efloat_1d _dpdTheta,_uCond,_uMech,_uChem; + typename ArrayTypes::t_xfloat_2d_um _buf; + typename ArrayTypes::t_int_2d_const _list; + const int _iswap; + X_FLOAT _xprd,_yprd,_zprd,_xy,_xz,_yz; + X_FLOAT _pbc[6]; + + AtomVecDPDKokkos_PackComm( + const typename DAT::tdual_x_array &x, + const typename DAT::tdual_efloat_1d &dpdTheta, + const typename DAT::tdual_efloat_1d &uCond, + const typename DAT::tdual_efloat_1d &uMech, + const typename DAT::tdual_efloat_1d &uChem, + const typename DAT::tdual_xfloat_2d &buf, + const typename DAT::tdual_int_2d &list, + const int & iswap, + const X_FLOAT &xprd, const X_FLOAT &yprd, const X_FLOAT &zprd, + const X_FLOAT &xy, const X_FLOAT &xz, const X_FLOAT &yz, const int* const pbc): + _x(x.view()), + _dpdTheta(dpdTheta.view()), + _uCond(uCond.view()), + _uMech(uMech.view()), + _uChem(uChem.view()), + _list(list.view()),_iswap(iswap), + _xprd(xprd),_yprd(yprd),_zprd(zprd), + _xy(xy),_xz(xz),_yz(yz) { + const size_t maxsend = (buf.view().dimension_0()*buf.view().dimension_1())/3; + const size_t elements = 3; + buffer_view(_buf,buf,maxsend,elements); + _pbc[0] = pbc[0]; _pbc[1] = pbc[1]; _pbc[2] = pbc[2]; + _pbc[3] = pbc[3]; _pbc[4] = pbc[4]; _pbc[5] = pbc[5]; + }; + + KOKKOS_INLINE_FUNCTION + void operator() (const int& i) const { + const int j = _list(_iswap,i); + if (PBC_FLAG == 0) { + _buf(i,0) = _x(j,0); + _buf(i,1) = _x(j,1); + _buf(i,2) = _x(j,2); + } else { + if (TRICLINIC == 0) { + _buf(i,0) = _x(j,0) + _pbc[0]*_xprd; + _buf(i,1) = _x(j,1) + _pbc[1]*_yprd; + _buf(i,2) = _x(j,2) + _pbc[2]*_zprd; + } else { + _buf(i,0) = _x(j,0) + _pbc[0]*_xprd + _pbc[5]*_xy + _pbc[4]*_xz; + _buf(i,1) = _x(j,1) + _pbc[1]*_yprd + _pbc[3]*_yz; + _buf(i,2) = _x(j,2) + _pbc[2]*_zprd; + } + } + _buf(i,3) = _dpdTheta(j); + _buf(i,4) = _uCond(j); + _buf(i,5) = _uMech(j); + _buf(i,6) = _uChem(j); + } +}; + +/* ---------------------------------------------------------------------- */ + +int AtomVecDPDKokkos::pack_comm_kokkos(const int &n, + const DAT::tdual_int_2d &list, + const int & iswap, + const DAT::tdual_xfloat_2d &buf, + const int &pbc_flag, + const int* const pbc) +{ + // Check whether to always run forward communication on the host + // Choose correct forward PackComm kernel + + if(commKK->forward_comm_on_host) { + sync(Host,X_MASK); + if(pbc_flag) { + if(domain->triclinic) { + struct AtomVecDPDKokkos_PackComm f(atomKK->k_x, + atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem, + buf,list,iswap, + domain->xprd,domain->yprd,domain->zprd, + domain->xy,domain->xz,domain->yz,pbc); + Kokkos::parallel_for(n,f); + } else { + struct AtomVecDPDKokkos_PackComm f(atomKK->k_x, + atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem, + buf,list,iswap, + domain->xprd,domain->yprd,domain->zprd, + domain->xy,domain->xz,domain->yz,pbc); + Kokkos::parallel_for(n,f); + } + } else { + if(domain->triclinic) { + struct AtomVecDPDKokkos_PackComm f(atomKK->k_x, + atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem, + buf,list,iswap, + domain->xprd,domain->yprd,domain->zprd, + domain->xy,domain->xz,domain->yz,pbc); + Kokkos::parallel_for(n,f); + } else { + struct AtomVecDPDKokkos_PackComm f(atomKK->k_x, + atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem, + buf,list,iswap, + domain->xprd,domain->yprd,domain->zprd, + domain->xy,domain->xz,domain->yz,pbc); + Kokkos::parallel_for(n,f); + } + } + LMPHostType::fence(); + } else { + sync(Device,X_MASK); + if(pbc_flag) { + if(domain->triclinic) { + struct AtomVecDPDKokkos_PackComm f(atomKK->k_x, + atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem, + buf,list,iswap, + domain->xprd,domain->yprd,domain->zprd, + domain->xy,domain->xz,domain->yz,pbc); + Kokkos::parallel_for(n,f); + } else { + struct AtomVecDPDKokkos_PackComm f(atomKK->k_x, + atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem, + buf,list,iswap, + domain->xprd,domain->yprd,domain->zprd, + domain->xy,domain->xz,domain->yz,pbc); + Kokkos::parallel_for(n,f); + } + } else { + if(domain->triclinic) { + struct AtomVecDPDKokkos_PackComm f(atomKK->k_x, + atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem, + buf,list,iswap, + domain->xprd,domain->yprd,domain->zprd, + domain->xy,domain->xz,domain->yz,pbc); + Kokkos::parallel_for(n,f); + } else { + struct AtomVecDPDKokkos_PackComm f(atomKK->k_x, + atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem, + buf,list,iswap, + domain->xprd,domain->yprd,domain->zprd, + domain->xy,domain->xz,domain->yz,pbc); + Kokkos::parallel_for(n,f); + } + } + LMPDeviceType::fence(); + } + + return n*size_forward; +} + +/* ---------------------------------------------------------------------- */ + +template +struct AtomVecDPDKokkos_PackCommSelf { + typedef DeviceType device_type; + + typename ArrayTypes::t_x_array_randomread _x; + typename ArrayTypes::t_x_array _xw; + typename ArrayTypes::t_efloat_1d _dpdTheta,_uCond,_uMech,_uChem; + int _nfirst; + typename ArrayTypes::t_int_2d_const _list; + const int _iswap; + X_FLOAT _xprd,_yprd,_zprd,_xy,_xz,_yz; + X_FLOAT _pbc[6]; + + AtomVecDPDKokkos_PackCommSelf( + const typename DAT::tdual_x_array &x, + const typename DAT::tdual_efloat_1d &dpdTheta, + const typename DAT::tdual_efloat_1d &uCond, + const typename DAT::tdual_efloat_1d &uMech, + const typename DAT::tdual_efloat_1d &uChem, + const int &nfirst, + const typename DAT::tdual_int_2d &list, + const int & iswap, + const X_FLOAT &xprd, const X_FLOAT &yprd, const X_FLOAT &zprd, + const X_FLOAT &xy, const X_FLOAT &xz, const X_FLOAT &yz, const int* const pbc): + _x(x.view()),_xw(x.view()), + _dpdTheta(dpdTheta.view()), + _uCond(uCond.view()), + _uMech(uMech.view()), + _uChem(uChem.view()), + _nfirst(nfirst),_list(list.view()),_iswap(iswap), + _xprd(xprd),_yprd(yprd),_zprd(zprd), + _xy(xy),_xz(xz),_yz(yz) { + _pbc[0] = pbc[0]; _pbc[1] = pbc[1]; _pbc[2] = pbc[2]; + _pbc[3] = pbc[3]; _pbc[4] = pbc[4]; _pbc[5] = pbc[5]; + }; + + KOKKOS_INLINE_FUNCTION + void operator() (const int& i) const { + const int j = _list(_iswap,i); + if (PBC_FLAG == 0) { + _xw(i+_nfirst,0) = _x(j,0); + _xw(i+_nfirst,1) = _x(j,1); + _xw(i+_nfirst,2) = _x(j,2); + } else { + if (TRICLINIC == 0) { + _xw(i+_nfirst,0) = _x(j,0) + _pbc[0]*_xprd; + _xw(i+_nfirst,1) = _x(j,1) + _pbc[1]*_yprd; + _xw(i+_nfirst,2) = _x(j,2) + _pbc[2]*_zprd; + } else { + _xw(i+_nfirst,0) = _x(j,0) + _pbc[0]*_xprd + _pbc[5]*_xy + _pbc[4]*_xz; + _xw(i+_nfirst,1) = _x(j,1) + _pbc[1]*_yprd + _pbc[3]*_yz; + _xw(i+_nfirst,2) = _x(j,2) + _pbc[2]*_zprd; + } + } + _dpdTheta(i+_nfirst) = _dpdTheta(j); + _uCond(i+_nfirst) = _uCond(j); + _uMech(i+_nfirst) = _uMech(j); + _uChem(i+_nfirst) = _uChem(j); + } +}; + +/* ---------------------------------------------------------------------- */ + +int AtomVecDPDKokkos::pack_comm_self(const int &n, const DAT::tdual_int_2d &list, const int & iswap, + const int nfirst, const int &pbc_flag, const int* const pbc) { + if(commKK->forward_comm_on_host) { + sync(Host,X_MASK); + modified(Host,X_MASK); + if(pbc_flag) { + if(domain->triclinic) { + struct AtomVecDPDKokkos_PackCommSelf f(atomKK->k_x, + atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem, + nfirst,list,iswap, + domain->xprd,domain->yprd,domain->zprd, + domain->xy,domain->xz,domain->yz,pbc); + Kokkos::parallel_for(n,f); + } else { + struct AtomVecDPDKokkos_PackCommSelf f(atomKK->k_x, + atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem, + nfirst,list,iswap, + domain->xprd,domain->yprd,domain->zprd, + domain->xy,domain->xz,domain->yz,pbc); + Kokkos::parallel_for(n,f); + } + } else { + if(domain->triclinic) { + struct AtomVecDPDKokkos_PackCommSelf f(atomKK->k_x, + atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem, + nfirst,list,iswap, + domain->xprd,domain->yprd,domain->zprd, + domain->xy,domain->xz,domain->yz,pbc); + Kokkos::parallel_for(n,f); + } else { + struct AtomVecDPDKokkos_PackCommSelf f(atomKK->k_x, + atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem, + nfirst,list,iswap, + domain->xprd,domain->yprd,domain->zprd, + domain->xy,domain->xz,domain->yz,pbc); + Kokkos::parallel_for(n,f); + } + } + LMPHostType::fence(); + } else { + sync(Device,X_MASK); + modified(Device,X_MASK); + if(pbc_flag) { + if(domain->triclinic) { + struct AtomVecDPDKokkos_PackCommSelf f(atomKK->k_x, + atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem, + nfirst,list,iswap, + domain->xprd,domain->yprd,domain->zprd, + domain->xy,domain->xz,domain->yz,pbc); + Kokkos::parallel_for(n,f); + } else { + struct AtomVecDPDKokkos_PackCommSelf f(atomKK->k_x, + atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem, + nfirst,list,iswap, + domain->xprd,domain->yprd,domain->zprd, + domain->xy,domain->xz,domain->yz,pbc); + Kokkos::parallel_for(n,f); + } + } else { + if(domain->triclinic) { + struct AtomVecDPDKokkos_PackCommSelf f(atomKK->k_x, + atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem, + nfirst,list,iswap, + domain->xprd,domain->yprd,domain->zprd, + domain->xy,domain->xz,domain->yz,pbc); + Kokkos::parallel_for(n,f); + } else { + struct AtomVecDPDKokkos_PackCommSelf f(atomKK->k_x, + atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem, + nfirst,list,iswap, + domain->xprd,domain->yprd,domain->zprd, + domain->xy,domain->xz,domain->yz,pbc); + Kokkos::parallel_for(n,f); + } + } + LMPDeviceType::fence(); + } + return n*3; +} + +/* ---------------------------------------------------------------------- */ + +template +struct AtomVecDPDKokkos_UnpackComm { + typedef DeviceType device_type; + + typename ArrayTypes::t_x_array _x; + typename ArrayTypes::t_efloat_1d _dpdTheta,_uCond,_uMech,_uChem; + typename ArrayTypes::t_xfloat_2d_const _buf; + int _first; + + AtomVecDPDKokkos_UnpackComm( + const typename DAT::tdual_x_array &x, + const typename DAT::tdual_efloat_1d &dpdTheta, + const typename DAT::tdual_efloat_1d &uCond, + const typename DAT::tdual_efloat_1d &uMech, + const typename DAT::tdual_efloat_1d &uChem, + const typename DAT::tdual_xfloat_2d &buf, + const int& first):_x(x.view()), + _dpdTheta(dpdTheta.view()), + _uCond(uCond.view()), + _uMech(uMech.view()), + _uChem(uChem.view()), + _buf(buf.view()), + _first(first) {}; + + KOKKOS_INLINE_FUNCTION + void operator() (const int& i) const { + _x(i+_first,0) = _buf(i,0); + _x(i+_first,1) = _buf(i,1); + _x(i+_first,2) = _buf(i,2); + _dpdTheta(i+_first) = _buf(i,3); + _uCond(i+_first) = _buf(i,4); + _uMech(i+_first) = _buf(i,5); + _uChem(i+_first) = _buf(i,6); + } +}; + +/* ---------------------------------------------------------------------- */ + +void AtomVecDPDKokkos::unpack_comm_kokkos(const int &n, const int &first, + const DAT::tdual_xfloat_2d &buf ) { + if(commKK->forward_comm_on_host) { + sync(Host,X_MASK); + modified(Host,X_MASK); + struct AtomVecDPDKokkos_UnpackComm f(atomKK->k_x, + atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem, + buf,first); + Kokkos::parallel_for(n,f); + LMPDeviceType::fence(); + } else { + sync(Device,X_MASK); + modified(Device,X_MASK); + struct AtomVecDPDKokkos_UnpackComm f(atomKK->k_x, + atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem, + buf,first); + Kokkos::parallel_for(n,f); + LMPDeviceType::fence(); + } +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecDPDKokkos::pack_comm(int n, int *list, double *buf, + int pbc_flag, int *pbc) +{ + int i,j,m; + double dx,dy,dz; + + m = 0; + if (pbc_flag == 0) { + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = h_x(j,0); + buf[m++] = h_x(j,1); + buf[m++] = h_x(j,2); + buf[m++] = dpdTheta[j]; + buf[m++] = uCond[j]; + buf[m++] = uMech[j]; + buf[m++] = uChem[j]; + } + } else { + if (domain->triclinic == 0) { + dx = pbc[0]*domain->xprd; + dy = pbc[1]*domain->yprd; + dz = pbc[2]*domain->zprd; + } else { + dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz; + dy = pbc[1]*domain->yprd + pbc[3]*domain->yz; + dz = pbc[2]*domain->zprd; + } + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = h_x(j,0) + dx; + buf[m++] = h_x(j,1) + dy; + buf[m++] = h_x(j,2) + dz; + buf[m++] = h_dpdTheta[j]; + buf[m++] = h_uCond[j]; + buf[m++] = h_uMech[j]; + buf[m++] = h_uChem[j]; + } + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecDPDKokkos::pack_comm_vel(int n, int *list, double *buf, + int pbc_flag, int *pbc) +{ + int i,j,m; + double dx,dy,dz,dvx,dvy,dvz; + + m = 0; + if (pbc_flag == 0) { + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = h_x(j,0); + buf[m++] = h_x(j,1); + buf[m++] = h_x(j,2); + buf[m++] = h_v(j,0); + buf[m++] = h_v(j,1); + buf[m++] = h_v(j,2); + buf[m++] = h_dpdTheta[j]; + buf[m++] = h_uCond[j]; + buf[m++] = h_uMech[j]; + buf[m++] = h_uChem[j]; + } + } else { + if (domain->triclinic == 0) { + dx = pbc[0]*domain->xprd; + dy = pbc[1]*domain->yprd; + dz = pbc[2]*domain->zprd; + } else { + dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz; + dy = pbc[1]*domain->yprd + pbc[3]*domain->yz; + dz = pbc[2]*domain->zprd; + } + if (!deform_vremap) { + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = h_x(j,0) + dx; + buf[m++] = h_x(j,1) + dy; + buf[m++] = h_x(j,2) + dz; + buf[m++] = h_v(j,0); + buf[m++] = h_v(j,1); + buf[m++] = h_v(j,2); + buf[m++] = h_dpdTheta[j]; + buf[m++] = h_uCond[j]; + buf[m++] = h_uMech[j]; + buf[m++] = h_uChem[j]; + } + } else { + dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4]; + dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3]; + dvz = pbc[2]*h_rate[2]; + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = h_x(j,0) + dx; + buf[m++] = h_x(j,1) + dy; + buf[m++] = h_x(j,2) + dz; + if (mask[i] & deform_groupbit) { + buf[m++] = h_v(j,0) + dvx; + buf[m++] = h_v(j,1) + dvy; + buf[m++] = h_v(j,2) + dvz; + } else { + buf[m++] = h_v(j,0); + buf[m++] = h_v(j,1); + buf[m++] = h_v(j,2); + } + buf[m++] = h_dpdTheta(j); + buf[m++] = h_uCond(j); + buf[m++] = h_uMech(j); + buf[m++] = h_uChem(j); + } + } + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecDPDKokkos::unpack_comm(int n, int first, double *buf) +{ + int i,m,last; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + h_x(i,0) = buf[m++]; + h_x(i,1) = buf[m++]; + h_x(i,2) = buf[m++]; + h_dpdTheta[i] = buf[m++]; + h_uCond[i] = buf[m++]; + h_uMech[i] = buf[m++]; + h_uChem[i] = buf[m++]; + } +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecDPDKokkos::unpack_comm_vel(int n, int first, double *buf) +{ + int i,m,last; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + h_x(i,0) = buf[m++]; + h_x(i,1) = buf[m++]; + h_x(i,2) = buf[m++]; + h_v(i,0) = buf[m++]; + h_v(i,1) = buf[m++]; + h_v(i,2) = buf[m++]; + h_dpdTheta[i] = buf[m++]; + h_uCond[i] = buf[m++]; + h_uMech[i] = buf[m++]; + h_uChem[i] = buf[m++]; + } +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecDPDKokkos::pack_reverse(int n, int first, double *buf) +{ + if(n > 0) + sync(Host,F_MASK); + + int m = 0; + const int last = first + n; + for (int i = first; i < last; i++) { + buf[m++] = h_f(i,0); + buf[m++] = h_f(i,1); + buf[m++] = h_f(i,2); + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecDPDKokkos::unpack_reverse(int n, int *list, double *buf) +{ + if(n > 0) { + sync(Host,F_MASK); + modified(Host,F_MASK); + } + + int m = 0; + for (int i = 0; i < n; i++) { + const int j = list[i]; + h_f(j,0) += buf[m++]; + h_f(j,1) += buf[m++]; + h_f(j,2) += buf[m++]; + } +} + +/* ---------------------------------------------------------------------- */ + +template +struct AtomVecDPDKokkos_PackBorder { + typedef DeviceType device_type; + + typename ArrayTypes::t_xfloat_2d _buf; + const typename ArrayTypes::t_int_2d_const _list; + const int _iswap; + const typename ArrayTypes::t_x_array_randomread _x; + const typename ArrayTypes::t_tagint_1d _tag; + const typename ArrayTypes::t_int_1d _type; + const typename ArrayTypes::t_int_1d _mask; + typename ArrayTypes::t_efloat_1d _dpdTheta,_uCond,_uMech,_uChem,_uCG,_uCGnew; + X_FLOAT _dx,_dy,_dz; + + AtomVecDPDKokkos_PackBorder( + const typename ArrayTypes::t_xfloat_2d &buf, + const typename ArrayTypes::t_int_2d_const &list, + const int & iswap, + const typename ArrayTypes::t_x_array &x, + const typename ArrayTypes::t_tagint_1d &tag, + const typename ArrayTypes::t_int_1d &type, + const typename ArrayTypes::t_int_1d &mask, + const typename ArrayTypes::t_efloat_1d &dpdTheta, + const typename ArrayTypes::t_efloat_1d &uCond, + const typename ArrayTypes::t_efloat_1d &uMech, + const typename ArrayTypes::t_efloat_1d &uChem, + const typename ArrayTypes::t_efloat_1d &uCG, + const typename ArrayTypes::t_efloat_1d &uCGnew, + const X_FLOAT &dx, const X_FLOAT &dy, const X_FLOAT &dz): + _buf(buf),_list(list),_iswap(iswap), + _x(x),_tag(tag),_type(type),_mask(mask), + _dpdTheta(dpdTheta), + _uCond(uCond), + _uMech(uMech), + _uChem(uChem), + _uCG(uCGnew), + _uCGnew(uCGnew), + _dx(dx),_dy(dy),_dz(dz) {} + + KOKKOS_INLINE_FUNCTION + void operator() (const int& i) const { + const int j = _list(_iswap,i); + if (PBC_FLAG == 0) { + _buf(i,0) = _x(j,0); + _buf(i,1) = _x(j,1); + _buf(i,2) = _x(j,2); + } else { + _buf(i,0) = _x(j,0) + _dx; + _buf(i,1) = _x(j,1) + _dy; + _buf(i,2) = _x(j,2) + _dz; + } + _buf(i,3) = _tag(j); + _buf(i,4) = _type(j); + _buf(i,5) = _mask(j); + _buf(i,6) = _dpdTheta(j); + _buf(i,7) = _uCond(j); + _buf(i,8) = _uMech(j); + _buf(i,9) = _uChem(j); + _buf(i,10) = _uCG(j); + _buf(i,11) = _uCGnew(j); + } +}; + +/* ---------------------------------------------------------------------- */ + +int AtomVecDPDKokkos::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) +{ + X_FLOAT dx,dy,dz; + + if (pbc_flag != 0) { + if (domain->triclinic == 0) { + dx = pbc[0]*domain->xprd; + dy = pbc[1]*domain->yprd; + dz = pbc[2]*domain->zprd; + } else { + dx = pbc[0]; + dy = pbc[1]; + dz = pbc[2]; + } + if(space==Host) { + AtomVecDPDKokkos_PackBorder f( + buf.view(), k_sendlist.view(), + iswap,h_x,h_tag,h_type,h_mask, + h_dpdTheta,h_uCond,h_uMech,h_uChem,h_uCG,h_uCGnew, + dx,dy,dz); + Kokkos::parallel_for(n,f); + LMPHostType::fence(); + } else { + AtomVecDPDKokkos_PackBorder f( + buf.view(), k_sendlist.view(), + iswap,d_x,d_tag,d_type,d_mask, + d_dpdTheta,d_uCond,d_uMech,d_uChem,d_uCG,d_uCGnew, + dx,dy,dz); + Kokkos::parallel_for(n,f); + LMPDeviceType::fence(); + } + + } else { + dx = dy = dz = 0; + if(space==Host) { + AtomVecDPDKokkos_PackBorder f( + buf.view(), k_sendlist.view(), + iswap,h_x,h_tag,h_type,h_mask, + h_dpdTheta,h_uCond,h_uMech,h_uChem,h_uCG,h_uCGnew, + dx,dy,dz); + Kokkos::parallel_for(n,f); + LMPHostType::fence(); + } else { + AtomVecDPDKokkos_PackBorder f( + buf.view(), k_sendlist.view(), + iswap,d_x,d_tag,d_type,d_mask, + d_dpdTheta,d_uCond,d_uMech,d_uChem,d_uCG,d_uCGnew, + dx,dy,dz); + Kokkos::parallel_for(n,f); + LMPDeviceType::fence(); + } + } + return n*6; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecDPDKokkos::pack_border(int n, int *list, double *buf, + int pbc_flag, int *pbc) +{ + int i,j,m; + double dx,dy,dz; + + m = 0; + if (pbc_flag == 0) { + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = h_x(j,0); + buf[m++] = h_x(j,1); + buf[m++] = h_x(j,2); + buf[m++] = ubuf(h_tag(j)).d; + buf[m++] = ubuf(h_type(j)).d; + buf[m++] = ubuf(h_mask(j)).d; + buf[m++] = h_dpdTheta(j); + buf[m++] = h_uCond(j); + buf[m++] = h_uMech(j); + buf[m++] = h_uChem(j); + buf[m++] = h_uCG(j); + buf[m++] = h_uCGnew(j); + } + } else { + if (domain->triclinic == 0) { + dx = pbc[0]*domain->xprd; + dy = pbc[1]*domain->yprd; + dz = pbc[2]*domain->zprd; + } else { + dx = pbc[0]; + dy = pbc[1]; + dz = pbc[2]; + } + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = h_x(j,0) + dx; + buf[m++] = h_x(j,1) + dy; + buf[m++] = h_x(j,2) + dz; + buf[m++] = ubuf(h_tag(j)).d; + buf[m++] = ubuf(h_type(j)).d; + buf[m++] = ubuf(h_mask(j)).d; + buf[m++] = h_dpdTheta(j); + buf[m++] = h_uCond(j); + buf[m++] = h_uMech(j); + buf[m++] = h_uChem(j); + buf[m++] = h_uCG(j); + buf[m++] = h_uCGnew(j); + } + } + + if (atom->nextra_border) + for (int iextra = 0; iextra < atom->nextra_border; iextra++) + m += modify->fix[atom->extra_border[iextra]]->pack_border(n,list,&buf[m]); + + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecDPDKokkos::pack_border_vel(int n, int *list, double *buf, + int pbc_flag, int *pbc) +{ + int i,j,m; + double dx,dy,dz,dvx,dvy,dvz; + + m = 0; + if (pbc_flag == 0) { + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = h_x(j,0); + buf[m++] = h_x(j,1); + buf[m++] = h_x(j,2); + buf[m++] = ubuf(h_tag(j)).d; + buf[m++] = ubuf(h_type(j)).d; + buf[m++] = ubuf(h_mask(j)).d; + buf[m++] = h_v(j,0); + buf[m++] = h_v(j,1); + buf[m++] = h_v(j,2); + buf[m++] = h_dpdTheta(j); + buf[m++] = h_uCond(j); + buf[m++] = h_uMech(j); + buf[m++] = h_uChem(j); + buf[m++] = h_uCG(j); + buf[m++] = h_uCGnew(j); + } + } else { + if (domain->triclinic == 0) { + dx = pbc[0]*domain->xprd; + dy = pbc[1]*domain->yprd; + dz = pbc[2]*domain->zprd; + } else { + dx = pbc[0]; + dy = pbc[1]; + dz = pbc[2]; + } + if (!deform_vremap) { + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = h_x(j,0) + dx; + buf[m++] = h_x(j,1) + dy; + buf[m++] = h_x(j,2) + dz; + buf[m++] = ubuf(h_tag(j)).d; + buf[m++] = ubuf(h_type(j)).d; + buf[m++] = ubuf(h_mask(j)).d; + buf[m++] = h_v(j,0); + buf[m++] = h_v(j,1); + buf[m++] = h_v(j,2); + buf[m++] = h_dpdTheta(j); + buf[m++] = h_uCond(j); + buf[m++] = h_uMech(j); + buf[m++] = h_uChem(j); + buf[m++] = h_uCG(j); + buf[m++] = h_uCGnew(j); + } + } else { + dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4]; + dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3]; + dvz = pbc[2]*h_rate[2]; + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = h_x(j,0) + dx; + buf[m++] = h_x(j,1) + dy; + buf[m++] = h_x(j,2) + dz; + buf[m++] = ubuf(h_tag(j)).d; + buf[m++] = ubuf(h_type(j)).d; + buf[m++] = ubuf(h_mask(j)).d; + if (mask[i] & deform_groupbit) { + buf[m++] = h_v(j,0) + dvx; + buf[m++] = h_v(j,1) + dvy; + buf[m++] = h_v(j,2) + dvz; + } else { + buf[m++] = h_v(j,0); + buf[m++] = h_v(j,1); + buf[m++] = h_v(j,2); + } + buf[m++] = h_dpdTheta(j); + buf[m++] = h_uCond(j); + buf[m++] = h_uMech(j); + buf[m++] = h_uChem(j); + buf[m++] = h_uCG(j); + buf[m++] = h_uCGnew(j); + } + } + } + + if (atom->nextra_border) + for (int iextra = 0; iextra < atom->nextra_border; iextra++) + m += modify->fix[atom->extra_border[iextra]]->pack_border(n,list,&buf[m]); + + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecDPDKokkos::pack_comm_hybrid(int n, int *list, double *buf) +{ + int i,j,m; + + m = 0; + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = h_dpdTheta[j]; + buf[m++] = h_uCond[j]; + buf[m++] = h_uMech[j]; + buf[m++] = h_uChem[j]; + buf[m++] = h_uCG[j]; + buf[m++] = h_uCGnew[j]; + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecDPDKokkos::pack_border_hybrid(int n, int *list, double *buf) +{ + int i,j,m; + + m = 0; + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = h_dpdTheta[j]; + buf[m++] = h_uCond[j]; + buf[m++] = h_uMech[j]; + buf[m++] = h_uChem[j]; + buf[m++] = h_uCG[j]; + buf[m++] = h_uCGnew[j]; + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +template +struct AtomVecDPDKokkos_UnpackBorder { + typedef DeviceType device_type; + + const typename ArrayTypes::t_xfloat_2d_const _buf; + typename ArrayTypes::t_x_array _x; + typename ArrayTypes::t_tagint_1d _tag; + typename ArrayTypes::t_int_1d _type; + typename ArrayTypes::t_int_1d _mask; + typename ArrayTypes::t_efloat_1d _dpdTheta,_uCond,_uMech,_uChem,_uCG,_uCGnew; + int _first; + + + AtomVecDPDKokkos_UnpackBorder( + const typename ArrayTypes::t_xfloat_2d_const &buf, + typename ArrayTypes::t_x_array &x, + typename ArrayTypes::t_tagint_1d &tag, + typename ArrayTypes::t_int_1d &type, + typename ArrayTypes::t_int_1d &mask, + const typename ArrayTypes::t_efloat_1d &dpdTheta, + const typename ArrayTypes::t_efloat_1d &uCond, + const typename ArrayTypes::t_efloat_1d &uMech, + const typename ArrayTypes::t_efloat_1d &uChem, + const typename ArrayTypes::t_efloat_1d &uCG, + const typename ArrayTypes::t_efloat_1d &uCGnew, + const int& first): + _buf(buf),_x(x),_tag(tag),_type(type),_mask(mask), + _dpdTheta(dpdTheta), + _uCond(uCond), + _uMech(uMech), + _uChem(uChem), + _uCG(uCGnew), + _uCGnew(uCGnew), + _first(first) {}; + + KOKKOS_INLINE_FUNCTION + void operator() (const int& i) const { + _x(i+_first,0) = _buf(i,0); + _x(i+_first,1) = _buf(i,1); + _x(i+_first,2) = _buf(i,2); + _tag(i+_first) = static_cast (_buf(i,3)); + _type(i+_first) = static_cast (_buf(i,4)); + _mask(i+_first) = static_cast (_buf(i,5)); + _dpdTheta(i+_first) = _buf(i,6); + _uCond(i+_first) = _buf(i,7); + _uMech(i+_first) = _buf(i,8); + _uChem(i+_first) = _buf(i,9); + _uCG(i+_first) = _buf(i,10); + _uCGnew(i+_first) = _buf(i,11); +// printf("%i %i %lf %lf %lf %i BORDER\n",_tag(i+_first),i+_first,_x(i+_first,0),_x(i+_first,1),_x(i+_first,2),_type(i+_first)); + } +}; + +/* ---------------------------------------------------------------------- */ + +void AtomVecDPDKokkos::unpack_border_kokkos(const int &n, const int &first, + const DAT::tdual_xfloat_2d &buf,ExecutionSpace space) { + modified(space,X_MASK|TAG_MASK|TYPE_MASK|MASK_MASK); + while (first+n >= nmax) grow(0); + modified(space,X_MASK|TAG_MASK|TYPE_MASK|MASK_MASK); + if(space==Host) { + struct AtomVecDPDKokkos_UnpackBorder f(buf.view(), + h_x,h_tag,h_type,h_mask, + h_dpdTheta,h_uCond,h_uMech,h_uChem,h_uCG,h_uCGnew, + first); + Kokkos::parallel_for(n,f); + LMPHostType::fence(); + } else { + struct AtomVecDPDKokkos_UnpackBorder f(buf.view(), + d_x,d_tag,d_type,d_mask, + d_dpdTheta,d_uCond,d_uMech,d_uChem,d_uCG,d_uCGnew, + first); + Kokkos::parallel_for(n,f); + LMPDeviceType::fence(); + } +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecDPDKokkos::unpack_border(int n, int first, double *buf) +{ + int i,m,last; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + if (i == nmax) grow(0); + modified(Host,X_MASK|TAG_MASK|TYPE_MASK|MASK_MASK); + h_x(i,0) = buf[m++]; + h_x(i,1) = buf[m++]; + h_x(i,2) = buf[m++]; + h_tag(i) = (tagint) ubuf(buf[m++]).i; + h_type(i) = (int) ubuf(buf[m++]).i; + h_mask(i) = (int) ubuf(buf[m++]).i; + h_dpdTheta(i) = buf[m++]; + h_uCond(i) = buf[m++]; + h_uMech(i) = buf[m++]; + h_uChem(i) = buf[m++]; + h_uCG(i) = buf[m++]; + h_uCGnew(i) = buf[m++]; + } + + if (atom->nextra_border) + for (int iextra = 0; iextra < atom->nextra_border; iextra++) + m += modify->fix[atom->extra_border[iextra]]-> + unpack_border(n,first,&buf[m]); +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecDPDKokkos::unpack_border_vel(int n, int first, double *buf) +{ + int i,m,last; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + if (i == nmax) grow(0); + modified(Host,X_MASK|V_MASK|TAG_MASK|TYPE_MASK|MASK_MASK); + h_x(i,0) = buf[m++]; + h_x(i,1) = buf[m++]; + h_x(i,2) = buf[m++]; + h_tag(i) = (tagint) ubuf(buf[m++]).i; + h_type(i) = (int) ubuf(buf[m++]).i; + h_mask(i) = (int) ubuf(buf[m++]).i; + h_v(i,0) = buf[m++]; + h_v(i,1) = buf[m++]; + h_v(i,2) = buf[m++]; + h_dpdTheta(i) = buf[m++]; + h_uCond(i) = buf[m++]; + h_uMech(i) = buf[m++]; + h_uChem(i) = buf[m++]; + h_uCG(i) = buf[m++]; + h_uCGnew(i) = buf[m++]; + } + + if (atom->nextra_border) + for (int iextra = 0; iextra < atom->nextra_border; iextra++) + m += modify->fix[atom->extra_border[iextra]]-> + unpack_border(n,first,&buf[m]); +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecDPDKokkos::unpack_comm_hybrid(int n, int first, double *buf) +{ + int i,m,last; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + h_dpdTheta(i) = buf[m++]; + h_uCond(i) = buf[m++]; + h_uMech(i) = buf[m++]; + h_uChem(i) = buf[m++]; + h_uCG(i) = buf[m++]; + h_uCGnew(i) = buf[m++]; + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecDPDKokkos::unpack_border_hybrid(int n, int first, double *buf) +{ + int i,m,last; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + h_dpdTheta(i) = buf[m++]; + h_uCond(i) = buf[m++]; + h_uMech(i) = buf[m++]; + h_uChem(i) = buf[m++]; + h_uCG(i) = buf[m++]; + h_uCGnew(i) = buf[m++]; + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +template +struct AtomVecDPDKokkos_PackExchangeFunctor { + typedef DeviceType device_type; + typedef ArrayTypes AT; + typename AT::t_x_array_randomread _x; + typename AT::t_v_array_randomread _v; + typename AT::t_tagint_1d_randomread _tag; + typename AT::t_int_1d_randomread _type; + typename AT::t_int_1d_randomread _mask; + typename AT::t_imageint_1d_randomread _image; + typename AT::t_efloat_1d_randomread _dpdTheta,_uCond,_uMech,_uChem,_uCG,_uCGnew; + typename AT::t_x_array _xw; + typename AT::t_v_array _vw; + typename AT::t_tagint_1d _tagw; + typename AT::t_int_1d _typew; + typename AT::t_int_1d _maskw; + typename AT::t_imageint_1d _imagew; + typename AT::t_efloat_1d _dpdThetaw,_uCondw,_uMechw,_uChemw,_uCGw,_uCGneww; + + typename AT::t_xfloat_2d_um _buf; + typename AT::t_int_1d_const _sendlist; + typename AT::t_int_1d_const _copylist; + int _nlocal,_dim; + X_FLOAT _lo,_hi; + + AtomVecDPDKokkos_PackExchangeFunctor( + const AtomKokkos* atom, + const typename AT::tdual_xfloat_2d buf, + typename AT::tdual_int_1d sendlist, + typename AT::tdual_int_1d copylist,int nlocal, int dim, + X_FLOAT lo, X_FLOAT hi): + _x(atom->k_x.view()), + _v(atom->k_v.view()), + _tag(atom->k_tag.view()), + _type(atom->k_type.view()), + _mask(atom->k_mask.view()), + _image(atom->k_image.view()), + _dpdTheta(atom->k_dpdTheta.view()), + _uCond(atom->k_uCond.view()), + _uMech(atom->k_uMech.view()), + _uChem(atom->k_uChem.view()), + _uCG(atom->k_uCG.view()), + _uCGnew(atom->k_uCGnew.view()), + _xw(atom->k_x.view()), + _vw(atom->k_v.view()), + _tagw(atom->k_tag.view()), + _typew(atom->k_type.view()), + _maskw(atom->k_mask.view()), + _imagew(atom->k_image.view()), + _dpdThetaw(atom->k_dpdTheta.view()), + _uCondw(atom->k_uCond.view()), + _uMechw(atom->k_uMech.view()), + _uChemw(atom->k_uChem.view()), + _uCGw(atom->k_uCG.view()), + _uCGneww(atom->k_uCGnew.view()), + _sendlist(sendlist.template view()), + _copylist(copylist.template view()), + _nlocal(nlocal),_dim(dim), + _lo(lo),_hi(hi){ + const size_t elements = 17; + const int maxsendlist = (buf.template view().dimension_0()*buf.template view().dimension_1())/elements; + + buffer_view(_buf,buf,maxsendlist,elements); + } + + KOKKOS_INLINE_FUNCTION + void operator() (const int &mysend) const { + const int i = _sendlist(mysend); + _buf(mysend,0) = 17; + _buf(mysend,1) = _x(i,0); + _buf(mysend,2) = _x(i,1); + _buf(mysend,3) = _x(i,2); + _buf(mysend,4) = _v(i,0); + _buf(mysend,5) = _v(i,1); + _buf(mysend,6) = _v(i,2); + _buf(mysend,7) = _tag[i]; + _buf(mysend,8) = _type[i]; + _buf(mysend,9) = _mask[i]; + _buf(mysend,10) = _image[i]; + _buf(mysend,11) = _dpdTheta[i]; + _buf(mysend,12) = _uCond[i]; + _buf(mysend,13) = _uMech[i]; + _buf(mysend,14) = _uChem[i]; + _buf(mysend,15) = _uCG[i]; + _buf(mysend,16) = _uCGnew[i]; + const int j = _copylist(mysend); + + if(j>-1) { + _xw(i,0) = _x(j,0); + _xw(i,1) = _x(j,1); + _xw(i,2) = _x(j,2); + _vw(i,0) = _v(j,0); + _vw(i,1) = _v(j,1); + _vw(i,2) = _v(j,2); + _tagw[i] = _tag(j); + _typew[i] = _type(j); + _maskw[i] = _mask(j); + _imagew[i] = _image(j); + _dpdThetaw[i] = _dpdTheta(j); + _uCondw[i] = _uCond(j); + _uMechw[i] = _uMech(j); + _uChemw[i] = _uChem(j); + _uCGw[i] = _uCG(j); + _uCGneww[i] = _uCGnew(j); + } + } +}; + +/* ---------------------------------------------------------------------- */ + +int AtomVecDPDKokkos::pack_exchange_kokkos(const int &nsend,DAT::tdual_xfloat_2d &k_buf, DAT::tdual_int_1d k_sendlist,DAT::tdual_int_1d k_copylist,ExecutionSpace space,int dim,X_FLOAT lo,X_FLOAT hi ) +{ + if(nsend > (int) (k_buf.view().dimension_0()*k_buf.view().dimension_1())/17) { + int newsize = nsend*17/k_buf.view().dimension_1()+1; + k_buf.resize(newsize,k_buf.view().dimension_1()); + } + if(space == Host) { + AtomVecDPDKokkos_PackExchangeFunctor f(atomKK,k_buf,k_sendlist,k_copylist,atom->nlocal,dim,lo,hi); + Kokkos::parallel_for(nsend,f); + LMPHostType::fence(); + return nsend*17; + } else { + AtomVecDPDKokkos_PackExchangeFunctor f(atomKK,k_buf,k_sendlist,k_copylist,atom->nlocal,dim,lo,hi); + Kokkos::parallel_for(nsend,f); + LMPDeviceType::fence(); + return nsend*17; + } +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecDPDKokkos::pack_exchange(int i, double *buf) +{ + int m = 1; + buf[m++] = h_x(i,0); + buf[m++] = h_x(i,1); + buf[m++] = h_x(i,2); + buf[m++] = h_v(i,0); + buf[m++] = h_v(i,1); + buf[m++] = h_v(i,2); + buf[m++] = ubuf(h_tag(i)).d; + buf[m++] = ubuf(h_type(i)).d; + buf[m++] = ubuf(h_mask(i)).d; + buf[m++] = ubuf(h_image(i)).d; + buf[m++] = h_dpdTheta[i]; + buf[m++] = h_uCond[i]; + buf[m++] = h_uMech[i]; + buf[m++] = h_uChem[i]; + buf[m++] = h_uCG[i]; + buf[m++] = h_uCGnew[i]; + + if (atom->nextra_grow) + for (int iextra = 0; iextra < atom->nextra_grow; iextra++) + m += modify->fix[atom->extra_grow[iextra]]->pack_exchange(i,&buf[m]); + + buf[0] = m; + return m; +} + +/* ---------------------------------------------------------------------- */ + +template +struct AtomVecDPDKokkos_UnpackExchangeFunctor { + typedef DeviceType device_type; + typedef ArrayTypes AT; + typename AT::t_x_array _x; + typename AT::t_v_array _v; + typename AT::t_tagint_1d _tag; + typename AT::t_int_1d _type; + typename AT::t_int_1d _mask; + typename AT::t_imageint_1d _image; + typename AT::t_efloat_1d _dpdTheta; + typename AT::t_efloat_1d _uCond; + typename AT::t_efloat_1d _uMech; + typename AT::t_efloat_1d _uChem; + typename AT::t_efloat_1d _uCG; + typename AT::t_efloat_1d _uCGnew; + + typename AT::t_xfloat_2d_um _buf; + typename AT::t_int_1d _nlocal; + int _dim; + X_FLOAT _lo,_hi; + + AtomVecDPDKokkos_UnpackExchangeFunctor( + const AtomKokkos* atom, + const typename AT::tdual_xfloat_2d buf, + typename AT::tdual_int_1d nlocal, + int dim, X_FLOAT lo, X_FLOAT hi): + _x(atom->k_x.view()), + _v(atom->k_v.view()), + _tag(atom->k_tag.view()), + _type(atom->k_type.view()), + _mask(atom->k_mask.view()), + _image(atom->k_image.view()), + _nlocal(nlocal.template view()),_dim(dim), + _lo(lo),_hi(hi){ + const size_t elements = 17; + const int maxsendlist = (buf.template view().dimension_0()*buf.template view().dimension_1())/elements; + + buffer_view(_buf,buf,maxsendlist,elements); + } + + KOKKOS_INLINE_FUNCTION + void operator() (const int &myrecv) const { + X_FLOAT x = _buf(myrecv,_dim+1); + if (x >= _lo && x < _hi) { + int i = Kokkos::atomic_fetch_add(&_nlocal(0),1); + _x(i,0) = _buf(myrecv,1); + _x(i,1) = _buf(myrecv,2); + _x(i,2) = _buf(myrecv,3); + _v(i,0) = _buf(myrecv,4); + _v(i,1) = _buf(myrecv,5); + _v(i,2) = _buf(myrecv,6); + _tag[i] = _buf(myrecv,7); + _type[i] = _buf(myrecv,8); + _mask[i] = _buf(myrecv,9); + _image[i] = _buf(myrecv,10); + _dpdTheta[i] = _buf(myrecv,11); + _uCond[i] = _buf(myrecv,12); + _uMech[i] = _buf(myrecv,13); + _uChem[i] = _buf(myrecv,14); + _uCG[i] = _buf(myrecv,15); + _uCGnew[i] = _buf(myrecv,16); + } + } +}; + +/* ---------------------------------------------------------------------- */ + +int AtomVecDPDKokkos::unpack_exchange_kokkos(DAT::tdual_xfloat_2d &k_buf,int nrecv,int nlocal,int dim,X_FLOAT lo,X_FLOAT hi,ExecutionSpace space) { + if(space == Host) { + k_count.h_view(0) = nlocal; + AtomVecDPDKokkos_UnpackExchangeFunctor f(atomKK,k_buf,k_count,dim,lo,hi); + Kokkos::parallel_for(nrecv/17,f); + LMPHostType::fence(); + return k_count.h_view(0); + } else { + k_count.h_view(0) = nlocal; + k_count.modify(); + k_count.sync(); + AtomVecDPDKokkos_UnpackExchangeFunctor f(atomKK,k_buf,k_count,dim,lo,hi); + Kokkos::parallel_for(nrecv/17,f); + LMPDeviceType::fence(); + k_count.modify(); + k_count.sync(); + + return k_count.h_view(0); + } +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecDPDKokkos::unpack_exchange(double *buf) +{ + int nlocal = atom->nlocal; + if (nlocal == nmax) grow(0); + modified(Host,X_MASK | V_MASK | TAG_MASK | TYPE_MASK | + MASK_MASK | IMAGE_MASK); + + int m = 1; + h_x(nlocal,0) = buf[m++]; + h_x(nlocal,1) = buf[m++]; + h_x(nlocal,2) = buf[m++]; + h_v(nlocal,0) = buf[m++]; + h_v(nlocal,1) = buf[m++]; + h_v(nlocal,2) = buf[m++]; + h_tag(nlocal) = (tagint) ubuf(buf[m++]).i; + h_type(nlocal) = (int) ubuf(buf[m++]).i; + h_mask(nlocal) = (int) ubuf(buf[m++]).i; + h_image(nlocal) = (imageint) ubuf(buf[m++]).i; + h_dpdTheta[nlocal] = buf[m++]; + h_uCond[nlocal] = buf[m++]; + h_uMech[nlocal] = buf[m++]; + h_uChem[nlocal] = buf[m++]; + h_uCG[nlocal] = buf[m++]; + h_uCGnew[nlocal] = buf[m++]; + + if (atom->nextra_grow) + for (int iextra = 0; iextra < atom->nextra_grow; iextra++) + m += modify->fix[atom->extra_grow[iextra]]-> + unpack_exchange(nlocal,&buf[m]); + + atom->nlocal++; + return m; +} + +/* ---------------------------------------------------------------------- + size of restart data for all atoms owned by this proc + include extra data stored by fixes +------------------------------------------------------------------------- */ + +int AtomVecDPDKokkos::size_restart() +{ + int i; + + int nlocal = atom->nlocal; + int n = 15 * nlocal; // 11 + dpdTheta + uCond + uMech + uChem + + if (atom->nextra_restart) + for (int iextra = 0; iextra < atom->nextra_restart; iextra++) + for (i = 0; i < nlocal; i++) + n += modify->fix[atom->extra_restart[iextra]]->size_restart(i); + + return n; +} + +/* ---------------------------------------------------------------------- + pack atom I's data for restart file including extra quantities + xyz must be 1st 3 values, so that read_restart can test on them + molecular types may be negative, but write as positive +------------------------------------------------------------------------- */ + +int AtomVecDPDKokkos::pack_restart(int i, double *buf) +{ + sync(Host,X_MASK | V_MASK | TAG_MASK | TYPE_MASK | + MASK_MASK | IMAGE_MASK ); + + int m = 1; + buf[m++] = h_x(i,0); + buf[m++] = h_x(i,1); + buf[m++] = h_x(i,2); + buf[m++] = ubuf(h_tag(i)).d; + buf[m++] = ubuf(h_type(i)).d; + buf[m++] = ubuf(h_mask(i)).d; + buf[m++] = ubuf(h_image(i)).d; + buf[m++] = h_v(i,0); + buf[m++] = h_v(i,1); + buf[m++] = h_v(i,2); + buf[m++] = h_dpdTheta[i]; + buf[m++] = h_uCond[i]; + buf[m++] = h_uMech[i]; + buf[m++] = h_uChem[i]; + + if (atom->nextra_restart) + for (int iextra = 0; iextra < atom->nextra_restart; iextra++) + m += modify->fix[atom->extra_restart[iextra]]->pack_restart(i,&buf[m]); + + buf[0] = m; + return m; +} + +/* ---------------------------------------------------------------------- + unpack data for one atom from restart file including extra quantities +------------------------------------------------------------------------- */ + +int AtomVecDPDKokkos::unpack_restart(double *buf) +{ + int nlocal = atom->nlocal; + if (nlocal == nmax) { + grow(0); + if (atom->nextra_store) + memory->grow(atom->extra,nmax,atom->nextra_store,"atom:extra"); + } + modified(Host,X_MASK | V_MASK | TAG_MASK | TYPE_MASK | + MASK_MASK | IMAGE_MASK ); + + int m = 1; + h_x(nlocal,0) = buf[m++]; + h_x(nlocal,1) = buf[m++]; + h_x(nlocal,2) = buf[m++]; + h_tag(nlocal) = (tagint) ubuf(buf[m++]).i; + h_type(nlocal) = (int) ubuf(buf[m++]).i; + h_mask(nlocal) = (int) ubuf(buf[m++]).i; + h_image(nlocal) = (imageint) ubuf(buf[m++]).i; + h_v(nlocal,0) = buf[m++]; + h_v(nlocal,1) = buf[m++]; + h_v(nlocal,2) = buf[m++]; + h_dpdTheta[nlocal] = buf[m++]; + h_uCond[nlocal] = buf[m++]; + h_uMech[nlocal] = buf[m++]; + h_uChem[nlocal] = buf[m++]; + + double **extra = atom->extra; + if (atom->nextra_store) { + int size = static_cast (ubuf(buf[m++]).i) - m; + for (int i = 0; i < size; i++) extra[nlocal][i] = buf[m++]; + } + + atom->nlocal++; + return m; +} + +/* ---------------------------------------------------------------------- + create one atom of itype at coord + set other values to defaults +------------------------------------------------------------------------- */ + +void AtomVecDPDKokkos::create_atom(int itype, double *coord) +{ + int nlocal = atom->nlocal; + if (nlocal == nmax) { + //if(nlocal>2) printf("typeA: %i %i\n",type[0],type[1]); + atomKK->modified(Host,ALL_MASK); + grow(0); + //if(nlocal>2) printf("typeB: %i %i\n",type[0],type[1]); + } + atomKK->modified(Host,ALL_MASK); + + tag[nlocal] = 0; + type[nlocal] = itype; + h_x(nlocal,0) = coord[0]; + h_x(nlocal,1) = coord[1]; + h_x(nlocal,2) = coord[2]; + h_mask[nlocal] = 1; + h_image[nlocal] = ((tagint) IMGMAX << IMG2BITS) | + ((tagint) IMGMAX << IMGBITS) | IMGMAX; + h_v(nlocal,0) = 0.0; + h_v(nlocal,1) = 0.0; + h_v(nlocal,2) = 0.0; + h_rho[nlocal] = 0.0; + h_dpdTheta[nlocal] = 0.0; + h_uCond[nlocal] = 0.0; + h_uMech[nlocal] = 0.0; + h_uChem[nlocal] = 0.0; + h_uCG[nlocal] = 0.0; + h_uCGnew[nlocal] = 0.0; + h_duChem[nlocal] = 0.0; + + atom->nlocal++; +} + +/* ---------------------------------------------------------------------- + unpack one line from Atoms section of data file + initialize other atom quantities +------------------------------------------------------------------------- */ + +void AtomVecDPDKokkos::data_atom(double *coord, tagint imagetmp, + char **values) +{ + int nlocal = atom->nlocal; + if (nlocal == nmax) grow(0); + + h_tag[nlocal] = ATOTAGINT(values[0]); + h_type[nlocal] = atoi(values[1]); + if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes) + error->one(FLERR,"Invalid atom type in Atoms section of data file"); + + h_dpdTheta[nlocal] = atof(values[2]); + if (h_dpdTheta[nlocal] <= 0) + error->one(FLERR,"Internal temperature in Atoms section of date file must be > zero"); + + h_x(nlocal,0) = coord[0]; + h_x(nlocal,1) = coord[1]; + h_x(nlocal,2) = coord[2]; + + h_image[nlocal] = imagetmp; + + h_mask[nlocal] = 1; + h_v(nlocal,0) = 0.0; + h_v(nlocal,1) = 0.0; + h_v(nlocal,2) = 0.0; + + h_rho[nlocal] = 0.0; + h_uCond[nlocal] = 0.0; + h_uMech[nlocal] = 0.0; + h_uChem[nlocal] = 0.0; + h_uCG[nlocal] = 0.0; + h_uCGnew[nlocal] = 0.0; + + atomKK->modified(Host,ALL_MASK); + + atom->nlocal++; +} + +/* ---------------------------------------------------------------------- + unpack hybrid quantities from one line in Atoms section of data file + initialize other atom quantities for this sub-style +------------------------------------------------------------------------- */ + +int AtomVecDPDKokkos::data_atom_hybrid(int nlocal, char **values) +{ + h_dpdTheta(nlocal) = atof(values[0]); + + return 1; +} + +/* ---------------------------------------------------------------------- + pack atom info for data file including 3 image flags +------------------------------------------------------------------------- */ + +void AtomVecDPDKokkos::pack_data(double **buf) +{ + int nlocal = atom->nlocal; + for (int i = 0; i < nlocal; i++) { + buf[i][0] = ubuf(h_tag(i)).d; + buf[i][1] = ubuf(h_type(i)).d; + buf[i][2] = h_dpdTheta(i); + buf[i][3] = h_x(i,0); + buf[i][4] = h_x(i,1); + buf[i][5] = h_x(i,2); + buf[i][6] = (h_image[i] & IMGMASK) - IMGMAX; + buf[i][7] = (h_image[i] >> IMGBITS & IMGMASK) - IMGMAX; + buf[i][8] = (h_image[i] >> IMG2BITS) - IMGMAX; + } +} + +/* ---------------------------------------------------------------------- + pack hybrid atom info for data file +------------------------------------------------------------------------- */ + +int AtomVecDPDKokkos::pack_data_hybrid(int i, double *buf) +{ + buf[0] = h_dpdTheta(i); + return 1; +} + +/* ---------------------------------------------------------------------- + write atom info to data file including 3 image flags +------------------------------------------------------------------------- */ + +void AtomVecDPDKokkos::write_data(FILE *fp, int n, double **buf) +{ + for (int i = 0; i < n; i++) + fprintf(fp,TAGINT_FORMAT " %d %-1.16e %-1.16e %-1.16e %-1.16e %d %d %d\n", + (tagint) ubuf(buf[i][0]).i,(int) ubuf(buf[i][1]).i, + buf[i][2],buf[i][3],buf[i][4],buf[i][5], + (int) ubuf(buf[i][6]).i,(int) ubuf(buf[i][7]).i, + (int) ubuf(buf[i][8]).i); +} + +/* ---------------------------------------------------------------------- + write hybrid atom info to data file +------------------------------------------------------------------------- */ + +int AtomVecDPDKokkos::write_data_hybrid(FILE *fp, double *buf) +{ + fprintf(fp," %-1.16e",buf[0]); + return 1; +} + +/* ---------------------------------------------------------------------- + return # of bytes of allocated memory +------------------------------------------------------------------------- */ + +bigint AtomVecDPDKokkos::memory_usage() +{ + bigint bytes = 0; + + if (atom->memcheck("tag")) bytes += memory->usage(tag,nmax); + if (atom->memcheck("type")) bytes += memory->usage(type,nmax); + if (atom->memcheck("mask")) bytes += memory->usage(mask,nmax); + if (atom->memcheck("image")) bytes += memory->usage(image,nmax); + if (atom->memcheck("x")) bytes += memory->usage(x,nmax,3); + if (atom->memcheck("v")) bytes += memory->usage(v,nmax,3); + if (atom->memcheck("f")) bytes += memory->usage(f,nmax*commKK->nthreads,3); + if (atom->memcheck("rho")) bytes += memory->usage(rho,nmax); + if (atom->memcheck("dpdTheta")) bytes += memory->usage(dpdTheta,nmax); + if (atom->memcheck("uCond")) bytes += memory->usage(uCond,nmax); + if (atom->memcheck("uMech")) bytes += memory->usage(uMech,nmax); + if (atom->memcheck("uChem")) bytes += memory->usage(uChem,nmax); + if (atom->memcheck("uCG")) bytes += memory->usage(uCG,nmax); + if (atom->memcheck("uCGnew")) bytes += memory->usage(uCGnew,nmax); + if (atom->memcheck("duChem")) bytes += memory->usage(duChem,nmax); + + return bytes; +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecDPDKokkos::sync(ExecutionSpace space, unsigned int mask) +{ + if (space == Device) { + if (mask & X_MASK) atomKK->k_x.sync(); + if (mask & V_MASK) atomKK->k_v.sync(); + if (mask & F_MASK) atomKK->k_f.sync(); + if (mask & TAG_MASK) atomKK->k_tag.sync(); + if (mask & TYPE_MASK) atomKK->k_type.sync(); + if (mask & MASK_MASK) atomKK->k_mask.sync(); + if (mask & IMAGE_MASK) atomKK->k_image.sync(); + } else { + if (mask & X_MASK) atomKK->k_x.sync(); + if (mask & V_MASK) atomKK->k_v.sync(); + if (mask & F_MASK) atomKK->k_f.sync(); + if (mask & TAG_MASK) atomKK->k_tag.sync(); + if (mask & TYPE_MASK) atomKK->k_type.sync(); + if (mask & MASK_MASK) atomKK->k_mask.sync(); + if (mask & IMAGE_MASK) atomKK->k_image.sync(); + } +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecDPDKokkos::sync_overlapping_device(ExecutionSpace space, unsigned int mask) +{ + if (space == Device) { + if ((mask & X_MASK) && atomKK->k_x.need_sync()) + perform_async_copy(atomKK->k_x,space); + if ((mask & V_MASK) && atomKK->k_v.need_sync()) + perform_async_copy(atomKK->k_v,space); + if ((mask & F_MASK) && atomKK->k_f.need_sync()) + perform_async_copy(atomKK->k_f,space); + if ((mask & TAG_MASK) && atomKK->k_tag.need_sync()) + perform_async_copy(atomKK->k_tag,space); + if ((mask & TYPE_MASK) && atomKK->k_type.need_sync()) + perform_async_copy(atomKK->k_type,space); + if ((mask & MASK_MASK) && atomKK->k_mask.need_sync()) + perform_async_copy(atomKK->k_mask,space); + if ((mask & IMAGE_MASK) && atomKK->k_image.need_sync()) + perform_async_copy(atomKK->k_image,space); + } else { + if ((mask & X_MASK) && atomKK->k_x.need_sync()) + perform_async_copy(atomKK->k_x,space); + if ((mask & V_MASK) && atomKK->k_v.need_sync()) + perform_async_copy(atomKK->k_v,space); + if ((mask & F_MASK) && atomKK->k_f.need_sync()) + perform_async_copy(atomKK->k_f,space); + if ((mask & TAG_MASK) && atomKK->k_tag.need_sync()) + perform_async_copy(atomKK->k_tag,space); + if ((mask & TYPE_MASK) && atomKK->k_type.need_sync()) + perform_async_copy(atomKK->k_type,space); + if ((mask & MASK_MASK) && atomKK->k_mask.need_sync()) + perform_async_copy(atomKK->k_mask,space); + if ((mask & IMAGE_MASK) && atomKK->k_image.need_sync()) + perform_async_copy(atomKK->k_image,space); + } +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecDPDKokkos::modified(ExecutionSpace space, unsigned int mask) +{ + if (space == Device) { + if (mask & X_MASK) atomKK->k_x.modify(); + if (mask & V_MASK) atomKK->k_v.modify(); + if (mask & F_MASK) atomKK->k_f.modify(); + if (mask & TAG_MASK) atomKK->k_tag.modify(); + if (mask & TYPE_MASK) atomKK->k_type.modify(); + if (mask & MASK_MASK) atomKK->k_mask.modify(); + if (mask & IMAGE_MASK) atomKK->k_image.modify(); + } else { + if (mask & X_MASK) atomKK->k_x.modify(); + if (mask & V_MASK) atomKK->k_v.modify(); + if (mask & F_MASK) atomKK->k_f.modify(); + if (mask & TAG_MASK) atomKK->k_tag.modify(); + if (mask & TYPE_MASK) atomKK->k_type.modify(); + if (mask & MASK_MASK) atomKK->k_mask.modify(); + if (mask & IMAGE_MASK) atomKK->k_image.modify(); + } +} + diff --git a/src/KOKKOS/atom_vec_dpd_kokkos.h b/src/KOKKOS/atom_vec_dpd_kokkos.h new file mode 100644 index 0000000000..d108e58ae7 --- /dev/null +++ b/src/KOKKOS/atom_vec_dpd_kokkos.h @@ -0,0 +1,135 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale AtomicKokkos/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef ATOM_CLASS + +AtomStyle(dpd/kk,AtomVecDPDKokkos) + +#else + +#ifndef LMP_ATOM_VEC_DPD_KOKKOS_H +#define LMP_ATOM_VEC_DPD_KOKKOS_H + +#include "atom_vec_kokkos.h" +#include "kokkos_type.h" + +namespace LAMMPS_NS { + +class AtomVecDPDKokkos : public AtomVecKokkos { + public: + AtomVecDPDKokkos(class LAMMPS *); + virtual ~AtomVecDPDKokkos() {} + void grow(int); + void copy(int, int, int); + int pack_comm(int, int *, double *, int, int *); + int pack_comm_vel(int, int *, double *, int, int *); + int pack_comm_hybrid(int, int *, double *); + void unpack_comm(int, int, double *); + void unpack_comm_vel(int, int, double *); + int unpack_comm_hybrid(int, int, double *); + int pack_reverse(int, int, double *); + void unpack_reverse(int, int *, double *); + int pack_border(int, int *, double *, int, int *); + int pack_border_vel(int, int *, double *, int, int *); + int pack_border_hybrid(int, int *, double *); + void unpack_border(int, int, double *); + void unpack_border_vel(int, int, double *); + int unpack_border_hybrid(int, int, double *); + int pack_exchange(int, double *); + int unpack_exchange(double *); + int size_restart(); + int pack_restart(int, double *); + int unpack_restart(double *); + void create_atom(int, double *); + void data_atom(double *, tagint, char **); + int data_atom_hybrid(int, char **); + void pack_data(double **); + int pack_data_hybrid(int, double *); + void write_data(FILE *, int, double **); + int write_data_hybrid(FILE *, double *); + bigint memory_usage(); + + void grow_reset(); + int pack_comm_kokkos(const int &n, const DAT::tdual_int_2d &k_sendlist, + const int & iswap, + const DAT::tdual_xfloat_2d &buf, + const int &pbc_flag, const int pbc[]); + void unpack_comm_kokkos(const int &n, const int &nfirst, + const DAT::tdual_xfloat_2d &buf); + int pack_comm_self(const int &n, const DAT::tdual_int_2d &list, + const int & iswap, const int nfirst, + const int &pbc_flag, const int pbc[]); + 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); + void unpack_border_kokkos(const int &n, const int &nfirst, + const DAT::tdual_xfloat_2d &buf, + ExecutionSpace space); + int pack_exchange_kokkos(const int &nsend,DAT::tdual_xfloat_2d &buf, + DAT::tdual_int_1d k_sendlist, + DAT::tdual_int_1d k_copylist, + ExecutionSpace space, int dim, + X_FLOAT lo, X_FLOAT hi); + int unpack_exchange_kokkos(DAT::tdual_xfloat_2d &k_buf, int nrecv, + int nlocal, int dim, X_FLOAT lo, X_FLOAT hi, + ExecutionSpace space); + + void sync(ExecutionSpace space, unsigned int mask); + void modified(ExecutionSpace space, unsigned int mask); + void sync_overlapping_device(ExecutionSpace space, unsigned int mask); + double *uCond,*uMech,*uChem,*uCG,*uCGnew,*rho,*dpdTheta; + double *duChem; + + protected: + DAT::t_efloat_1d d_uCond, d_uMech, d_uChem, d_uCG, d_uCGnew,d_rho,d_dpdTheta,d_duChem; + HAT::t_efloat_1d h_uCond, h_uMech, h_uChem, h_uCG, h_uCGnew,h_rho,h_dpdTheta,h_duChem; + + tagint *tag; + imageint *image; + int *type,*mask; + double **x,**v,**f; + + DAT::t_tagint_1d d_tag; + HAT::t_tagint_1d h_tag; + DAT::t_imageint_1d d_image; + HAT::t_imageint_1d h_image; + DAT::t_int_1d d_type, d_mask; + HAT::t_int_1d h_type, h_mask; + + DAT::t_x_array d_x; + DAT::t_v_array d_v; + DAT::t_f_array d_f; + HAT::t_x_array h_x; + HAT::t_v_array h_v; + HAT::t_f_array h_f; + + DAT::tdual_int_1d k_count; +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +E: Per-processor system is too big + +The number of owned atoms plus ghost atoms on a single +processor must fit in 32-bit integer. + +E: Invalid atom type in Atoms section of data file + +Atom types must range from 1 to specified # of types. + +*/ From 91e38720d5d69052cc92cd2344126b81d97c4aca Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Mon, 28 Nov 2016 14:25:02 -0700 Subject: [PATCH 004/439] Adding pair_exp6_rx_kokkos files --- src/KOKKOS/Install.sh | 2 + src/KOKKOS/atom_kokkos.cpp | 57 ++ src/KOKKOS/atom_kokkos.h | 4 + src/KOKKOS/pair_exp6_rx_kokkos.cpp | 1060 ++++++++++++++++++++++++++++ src/KOKKOS/pair_exp6_rx_kokkos.h | 204 ++++++ src/USER-DPD/pair_exp6_rx.cpp | 2 + src/atom.h | 4 +- 7 files changed, 1331 insertions(+), 2 deletions(-) create mode 100644 src/KOKKOS/pair_exp6_rx_kokkos.cpp create mode 100644 src/KOKKOS/pair_exp6_rx_kokkos.h diff --git a/src/KOKKOS/Install.sh b/src/KOKKOS/Install.sh index 93adf58ef5..14a8a951ee 100644 --- a/src/KOKKOS/Install.sh +++ b/src/KOKKOS/Install.sh @@ -134,6 +134,8 @@ action pair_eam_alloy_kokkos.cpp pair_eam_alloy.cpp action pair_eam_alloy_kokkos.h pair_eam_alloy.h action pair_eam_fs_kokkos.cpp pair_eam_fs.cpp action pair_eam_fs_kokkos.h pair_eam_fs.h +action pair_exp6_rx_kokkos.cpp pair_exp6_rx.cpp +action pair_exp6_rx_kokkos.h pair_exp6_rx.h action pair_kokkos.h action pair_lj_charmm_coul_charmm_implicit_kokkos.cpp pair_lj_charmm_coul_charmm_implicit.cpp action pair_lj_charmm_coul_charmm_implicit_kokkos.h pair_lj_charmm_coul_charmm_implicit.h diff --git a/src/KOKKOS/atom_kokkos.cpp b/src/KOKKOS/atom_kokkos.cpp index 577eff2364..4a7250e6ab 100644 --- a/src/KOKKOS/atom_kokkos.cpp +++ b/src/KOKKOS/atom_kokkos.cpp @@ -227,6 +227,63 @@ void AtomKokkos::grow(unsigned int mask){ } } +/* ---------------------------------------------------------------------- + add a custom variable with name of type flag = 0/1 for int/double + assumes name does not already exist + return index in ivector or dvector of its location +------------------------------------------------------------------------- */ + +int AtomKokkos::add_custom(const char *name, int flag) +{ + int index; + + if (flag == 0) { + index = nivector; + nivector++; + iname = (char **) memory->srealloc(iname,nivector*sizeof(char *), + "atom:iname"); + int n = strlen(name) + 1; + iname[index] = new char[n]; + strcpy(iname[index],name); + ivector = (int **) memory->srealloc(ivector,nivector*sizeof(int *), + "atom:ivector"); + memory->create(ivector[index],nmax,"atom:ivector"); + } else { + index = ndvector; + ndvector++; + dname = (char **) memory->srealloc(dname,ndvector*sizeof(char *), + "atom:dname"); + int n = strlen(name) + 1; + dname[index] = new char[n]; + strcpy(dname[index],name); + memory->grow_kokkos(k_dvector,dvector,ndvector,nmax, + "atom:dvector"); + } + + return index; +} + +/* ---------------------------------------------------------------------- + remove a custom variable of type flag = 0/1 for int/double at index + free memory for vector and name and set ptrs to NULL + ivector/dvector and iname/dname lists never shrink +------------------------------------------------------------------------- */ + +void AtomKokkos::remove_custom(int flag, int index) +{ + if (flag == 0) { + memory->destroy(ivector[index]); + ivector[index] = NULL; + delete [] iname[index]; + iname[index] = NULL; + } else { + //memory->destroy_kokkos(dvector); + dvector[index] = NULL; + delete [] dname[index]; + dname[index] = NULL; + } +} + /* ---------------------------------------------------------------------- */ void AtomKokkos::deallocate_topology() diff --git a/src/KOKKOS/atom_kokkos.h b/src/KOKKOS/atom_kokkos.h index f31c26e01f..cf454bcd0c 100644 --- a/src/KOKKOS/atom_kokkos.h +++ b/src/KOKKOS/atom_kokkos.h @@ -51,6 +51,8 @@ class AtomKokkos : public Atom { DAT::tdual_int_2d k_improper_type; DAT::tdual_tagint_2d k_improper_atom1, k_improper_atom2, k_improper_atom3, k_improper_atom4; + DAT::tdual_float_2d k_dvector; + // USER-DPD package DAT::tdual_efloat_1d k_uCond, k_uMech, k_uChem, k_uCG, k_uCGnew, @@ -66,6 +68,8 @@ class AtomKokkos : public Atom { void sync_overlapping_device(const ExecutionSpace space, unsigned int mask); virtual void sort(); virtual void grow(unsigned int mask); + int add_custom(const char *, int); + void remove_custom(int, int); virtual void deallocate_topology(); void sync_modify(ExecutionSpace, unsigned int, unsigned int); private: diff --git a/src/KOKKOS/pair_exp6_rx_kokkos.cpp b/src/KOKKOS/pair_exp6_rx_kokkos.cpp new file mode 100644 index 0000000000..aa37c8375d --- /dev/null +++ b/src/KOKKOS/pair_exp6_rx_kokkos.cpp @@ -0,0 +1,1060 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include +#include +#include +#include +#include "pair_exp6_rx_kokkos.h" +#include "atom.h" +#include "comm.h" +#include "force.h" +#include "neigh_list.h" +#include "math_const.h" +#include "math_special.h" +#include "memory.h" +#include "error.h" +#include "modify.h" +#include "fix.h" +#include + +using namespace LAMMPS_NS; +using namespace MathConst; +using namespace MathSpecial; + +#define MAXLINE 1024 +#define DELTA 4 + +#define oneFluidApproxParameter (-1) +#define isOneFluidApprox(_site) ( (_site) == oneFluidApproxParameter ) + +#define exp6PotentialType (1) +#define isExp6PotentialType(_type) ( (_type) == exp6PotentialType ) + +/* ---------------------------------------------------------------------- */ + +template +PairExp6rxKokkos::PairExp6rxKokkos(LAMMPS *lmp) : PairExp6rx(lmp) +{ + +} + +/* ---------------------------------------------------------------------- */ + +template +PairExp6rxKokkos::~PairExp6rxKokkos() +{ + +} + +/* ---------------------------------------------------------------------- */ + +template +void PairExp6rxKokkos::compute(int eflag_in, int vflag_in) +{ + eflag = eflag_in; + vflag = vflag_in; + + if (neighflag == FULL) no_virial_fdotr_compute = 1; + if (eflag || vflag) ev_setup(eflag,vflag); + else evflag = vflag_fdotr = 0; + + // reallocate per-atom arrays if necessary + + if (eflag_atom) { + memory->destroy_kokkos(k_eatom,eatom); + memory->create_kokkos(k_eatom,eatom,maxeatom,"pair:eatom"); + d_eatom = k_eatom.d_view; + } + if (vflag_atom) { + memory->destroy_kokkos(k_vatom,vatom); + memory->create_kokkos(k_vatom,vatom,maxvatom,6,"pair:vatom"); + d_vatom = k_vatom.d_view; + } + + x = atomKK->k_x.view(); + f = atomKK->k_f.view(); + type = atomKK->k_type.view(); + uCG = atomKK->k_uCG.view(); + uCGnew = atomKK->k_uCGnew.view(); + dvector = atomKK->k_dvector.view(); + nlocal = atom->nlocal; + special_lj[0] = force->special_lj[0]; + special_lj[1] = force->special_lj[1]; + special_lj[2] = force->special_lj[2]; + special_lj[3] = force->special_lj[3]; + special_coul[0] = force->special_coul[0]; + special_coul[1] = force->special_coul[1]; + special_coul[2] = force->special_coul[2]; + special_coul[3] = force->special_coul[3]; + newton_pair = force->newton_pair; + + copymode = 1; + + // Initialize the Exp6 parameter data for both the local + // and ghost atoms. Make the parameter data persistent + // and exchange like any other atom property later. + + { + const int np_total = nlocal + atom->nghost; + + PairExp6ParamData.epsilon1 = typename AT::t_float_1d("PairExp6ParamData.epsilon1" ,np_total); + PairExp6ParamData.alpha1 = typename AT::t_float_1d("PairExp6ParamData.alpha1" ,np_total); + PairExp6ParamData.rm1 = typename AT::t_float_1d("PairExp6ParamData.rm1" ,np_total); + PairExp6ParamData.fraction1 = typename AT::t_float_1d("PairExp6ParamData.fraction1" ,np_total); + PairExp6ParamData.epsilon2 = typename AT::t_float_1d("PairExp6ParamData.epsilon2" ,np_total); + PairExp6ParamData.alpha2 = typename AT::t_float_1d("PairExp6ParamData.alpha2" ,np_total); + PairExp6ParamData.rm2 = typename AT::t_float_1d("PairExp6ParamData.rm2" ,np_total); + PairExp6ParamData.fraction2 = typename AT::t_float_1d("PairExp6ParamData.fraction2" ,np_total); + PairExp6ParamData.epsilonOld1 = typename AT::t_float_1d("PairExp6ParamData.epsilonOld1" ,np_total); + PairExp6ParamData.alphaOld1 = typename AT::t_float_1d("PairExp6ParamData.alphaOld1" ,np_total); + PairExp6ParamData.rmOld1 = typename AT::t_float_1d("PairExp6ParamData.rmOld1" ,np_total); + PairExp6ParamData.fractionOld1 = typename AT::t_float_1d("PairExp6ParamData.fractionOld1",np_total); + PairExp6ParamData.epsilonOld2 = typename AT::t_float_1d("PairExp6ParamData.epsilonOld2" ,np_total); + PairExp6ParamData.alphaOld2 = typename AT::t_float_1d("PairExp6ParamData.alphaOld2" ,np_total); + PairExp6ParamData.rmOld2 = typename AT::t_float_1d("PairExp6ParamData.rmOld2" ,np_total); + PairExp6ParamData.fractionOld2 = typename AT::t_float_1d("PairExp6ParamData.fractionOld2",np_total); + + Kokkos::parallel_for(Kokkos::RangePolicy(0,np_total),*this); + } + + int inum = list->inum; + NeighListKokkos* k_list = static_cast*>(list); + d_numneigh = k_list->d_numneigh; + d_neighbors = k_list->d_neighbors; + d_ilist = k_list->d_ilist; + + // loop over neighbors of my atoms + + EV_FLOAT ev; + + if (evflag) { + Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + } else { + Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } + + if (eflag_global) eng_vdwl += ev.evdwl; + if (vflag_global) { + virial[0] += ev.v[0]; + virial[1] += ev.v[1]; + virial[2] += ev.v[2]; + virial[3] += ev.v[3]; + virial[4] += ev.v[4]; + virial[5] += ev.v[5]; + } + + if (vflag_fdotr) pair_virial_fdotr_compute(this); + + if (eflag_atom) { + k_eatom.template modify(); + k_eatom.template sync(); + } + + if (vflag_atom) { + k_vatom.template modify(); + k_vatom.template sync(); + } + + copymode = 0; +} + +template +KOKKOS_INLINE_FUNCTION +void PairExp6rxKokkos::operator()(TagPairExp6rxgetParamsEXP6, const int &i) const { + getParamsEXP6 (i, PairExp6ParamData.epsilon1[i], + PairExp6ParamData.alpha1[i], + PairExp6ParamData.rm1[i], + PairExp6ParamData.fraction1[i], + PairExp6ParamData.epsilon2[i], + PairExp6ParamData.alpha2[i], + PairExp6ParamData.rm2[i], + PairExp6ParamData.fraction2[i], + PairExp6ParamData.epsilonOld1[i], + PairExp6ParamData.alphaOld1[i], + PairExp6ParamData.rmOld1[i], + PairExp6ParamData.fractionOld1[i], + PairExp6ParamData.epsilonOld2[i], + PairExp6ParamData.alphaOld2[i], + PairExp6ParamData.rmOld2[i], + PairExp6ParamData.fractionOld2[i]); +} + +template +template +KOKKOS_INLINE_FUNCTION +void PairExp6rxKokkos::operator()(TagPairExp6rxCompute, const int &ii, EV_FLOAT& ev) const { + int i,j,jj,jnum,itype,jtype; + double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,evdwlOld,fpair; + double rsq,r2inv,r6inv,forceExp6,factor_lj; + double rCut,rCutInv,rCut2inv,rCut6inv,rCutExp,urc,durc; + double rm2ij,rm6ij; + double r,rexp; + + double alphaOld12_ij, rmOld12_ij, epsilonOld12_ij; + double alphaOld21_ij, rmOld21_ij, epsilonOld21_ij; + double alpha12_ij, rm12_ij, epsilon12_ij; + double alpha21_ij, rm21_ij, epsilon21_ij; + double rminv, buck1, buck2; + double epsilonOld1_i,alphaOld1_i,rmOld1_i; + double epsilonOld1_j,alphaOld1_j,rmOld1_j; + double epsilonOld2_i,alphaOld2_i,rmOld2_i; + double epsilonOld2_j,alphaOld2_j,rmOld2_j; + double epsilon1_i,alpha1_i,rm1_i; + double epsilon1_j,alpha1_j,rm1_j; + double epsilon2_i,alpha2_i,rm2_i; + double epsilon2_j,alpha2_j,rm2_j; + double evdwlOldEXP6_12, evdwlOldEXP6_21, fpairOldEXP6_12, fpairOldEXP6_21; + double evdwlEXP6_12, evdwlEXP6_21; + double fractionOld1_i, fractionOld1_j; + double fractionOld2_i, fractionOld2_j; + double fraction1_i, fraction1_j; + double fraction2_i, fraction2_j; + + const int nRep = 12; + const double shift = 1.05; + double rin1, aRep, uin1, win1, uin1rep, rin1exp, rin6, rin6inv; + + evdwlOld = 0.0; + evdwl = 0.0; + + i = d_ilist[ii]; + xtmp = x(i,0); + ytmp = x(i,1); + ztmp = x(i,2); + itype = type[i]; + jnum = d_numneigh[i]; + + { + epsilon1_i = PairExp6ParamData.epsilon1[i]; + alpha1_i = PairExp6ParamData.alpha1[i]; + rm1_i = PairExp6ParamData.rm1[i]; + fraction1_i = PairExp6ParamData.fraction1[i]; + epsilon2_i = PairExp6ParamData.epsilon2[i]; + alpha2_i = PairExp6ParamData.alpha2[i]; + rm2_i = PairExp6ParamData.rm2[i]; + fraction2_i = PairExp6ParamData.fraction2[i]; + epsilonOld1_i = PairExp6ParamData.epsilonOld1[i]; + alphaOld1_i = PairExp6ParamData.alphaOld1[i]; + rmOld1_i = PairExp6ParamData.rmOld1[i]; + fractionOld1_i = PairExp6ParamData.fractionOld1[i]; + epsilonOld2_i = PairExp6ParamData.epsilonOld2[i]; + alphaOld2_i = PairExp6ParamData.alphaOld2[i]; + rmOld2_i = PairExp6ParamData.rmOld2[i]; + fractionOld2_i = PairExp6ParamData.fractionOld2[i]; + } + + for (jj = 0; jj < jnum; jj++) { + int j = d_neighbors(i,jj); + factor_lj = special_lj[sbmask(j)]; + j &= NEIGHMASK; + + delx = xtmp - x(j,0); + dely = ytmp - x(j,1); + delz = ztmp - x(j,2); + + rsq = delx*delx + dely*dely + delz*delz; + jtype = type[j]; + + if (rsq < cutsq[itype][jtype]) { + r2inv = 1.0/rsq; + r6inv = r2inv*r2inv*r2inv; + + r = sqrt(rsq); + rCut2inv = 1.0/cutsq[itype][jtype]; + rCut6inv = rCut2inv*rCut2inv*rCut2inv; + rCut = sqrt(cutsq[itype][jtype]); + rCutInv = 1.0/rCut; + + // + // A. Compute the exp-6 potential + // + + // A1. Get alpha, epsilon and rm for particle j + + { + epsilon1_j = PairExp6ParamData.epsilon1[j]; + alpha1_j = PairExp6ParamData.alpha1[j]; + rm1_j = PairExp6ParamData.rm1[j]; + fraction1_j = PairExp6ParamData.fraction1[j]; + epsilon2_j = PairExp6ParamData.epsilon2[j]; + alpha2_j = PairExp6ParamData.alpha2[j]; + rm2_j = PairExp6ParamData.rm2[j]; + fraction2_j = PairExp6ParamData.fraction2[j]; + epsilonOld1_j = PairExp6ParamData.epsilonOld1[j]; + alphaOld1_j = PairExp6ParamData.alphaOld1[j]; + rmOld1_j = PairExp6ParamData.rmOld1[j]; + fractionOld1_j = PairExp6ParamData.fractionOld1[j]; + epsilonOld2_j = PairExp6ParamData.epsilonOld2[j]; + alphaOld2_j = PairExp6ParamData.alphaOld2[j]; + rmOld2_j = PairExp6ParamData.rmOld2[j]; + fractionOld2_j = PairExp6ParamData.fractionOld2[j]; + } + + // A2. Apply Lorentz-Berthelot mixing rules for the i-j pair + alphaOld12_ij = sqrt(alphaOld1_i*alphaOld2_j); + rmOld12_ij = 0.5*(rmOld1_i + rmOld2_j); + epsilonOld12_ij = sqrt(epsilonOld1_i*epsilonOld2_j); + alphaOld21_ij = sqrt(alphaOld2_i*alphaOld1_j); + rmOld21_ij = 0.5*(rmOld2_i + rmOld1_j); + epsilonOld21_ij = sqrt(epsilonOld2_i*epsilonOld1_j); + + alpha12_ij = sqrt(alpha1_i*alpha2_j); + rm12_ij = 0.5*(rm1_i + rm2_j); + epsilon12_ij = sqrt(epsilon1_i*epsilon2_j); + alpha21_ij = sqrt(alpha2_i*alpha1_j); + rm21_ij = 0.5*(rm2_i + rm1_j); + epsilon21_ij = sqrt(epsilon2_i*epsilon1_j); + + if(rmOld12_ij!=0.0 && rmOld21_ij!=0.0){ + if(alphaOld21_ij == 6.0 || alphaOld12_ij == 6.0) + error->all(FLERR,"alpha_ij is 6.0 in pair exp6"); + + // A3. Compute some convenient quantities for evaluating the force + rminv = 1.0/rmOld12_ij; + buck1 = epsilonOld12_ij / (alphaOld12_ij - 6.0); + rexp = expValue(alphaOld12_ij*(1.0-r*rminv)); + rm2ij = rmOld12_ij*rmOld12_ij; + rm6ij = rm2ij*rm2ij*rm2ij; + + // Compute the shifted potential + rCutExp = expValue(alphaOld12_ij*(1.0-rCut*rminv)); + buck2 = 6.0*alphaOld12_ij; + urc = buck1*(6.0*rCutExp - alphaOld12_ij*rm6ij*rCut6inv); + durc = -buck1*buck2*(rCutExp* rminv - rCutInv*rm6ij*rCut6inv); + rin1 = shift*rmOld12_ij*func_rin(alphaOld12_ij); + if(r < rin1){ + rin6 = rin1*rin1*rin1*rin1*rin1*rin1; + rin6inv = 1.0/rin6; + + rin1exp = expValue(alphaOld12_ij*(1.0-rin1*rminv)); + + uin1 = buck1*(6.0*rin1exp - alphaOld12_ij*rm6ij*rin6inv) - urc - durc*(rin1-rCut); + + win1 = -buck1*buck2*(rin1*rin1exp*rminv - rm6ij*rin6inv) - rin1*durc; + + aRep = -1.0*win1*powint(rin1,nRep)/nRep; + + uin1rep = aRep/powint(rin1,nRep); + + forceExp6 = -double(nRep)*aRep/powint(r,nRep); + fpairOldEXP6_12 = factor_lj*forceExp6*r2inv; + + evdwlOldEXP6_12 = uin1 - uin1rep + aRep/powint(r,nRep); + } else { + forceExp6 = buck1*buck2*(r*rexp*rminv - rm6ij*r6inv) + r*durc; + fpairOldEXP6_12 = factor_lj*forceExp6*r2inv; + + evdwlOldEXP6_12 = buck1*(6.0*rexp - alphaOld12_ij*rm6ij*r6inv) - urc - durc*(r-rCut); + } + + // A3. Compute some convenient quantities for evaluating the force + rminv = 1.0/rmOld21_ij; + buck1 = epsilonOld21_ij / (alphaOld21_ij - 6.0); + buck2 = 6.0*alphaOld21_ij; + rexp = expValue(alphaOld21_ij*(1.0-r*rminv)); + rm2ij = rmOld21_ij*rmOld21_ij; + rm6ij = rm2ij*rm2ij*rm2ij; + + // Compute the shifted potential + rCutExp = expValue(alphaOld21_ij*(1.0-rCut*rminv)); + buck2 = 6.0*alphaOld21_ij; + urc = buck1*(6.0*rCutExp - alphaOld21_ij*rm6ij*rCut6inv); + durc = -buck1*buck2*(rCutExp* rminv - rCutInv*rm6ij*rCut6inv); + rin1 = shift*rmOld21_ij*func_rin(alphaOld21_ij); + + if(r < rin1){ + rin6 = rin1*rin1*rin1*rin1*rin1*rin1; + rin6inv = 1.0/rin6; + + rin1exp = expValue(alphaOld21_ij*(1.0-rin1*rminv)); + + uin1 = buck1*(6.0*rin1exp - alphaOld21_ij*rm6ij*rin6inv) - urc - durc*(rin1-rCut); + + win1 = -buck1*buck2*(rin1*rin1exp*rminv - rm6ij*rin6inv) - rin1*durc; + + aRep = -1.0*win1*powint(rin1,nRep)/nRep; + + uin1rep = aRep/powint(rin1,nRep); + + forceExp6 = -double(nRep)*aRep/powint(r,nRep); + fpairOldEXP6_21 = factor_lj*forceExp6*r2inv; + + evdwlOldEXP6_21 = uin1 - uin1rep + aRep/powint(r,nRep); + } else { + forceExp6 = buck1*buck2*(r*rexp*rminv - rm6ij*r6inv) + r*durc; + fpairOldEXP6_21 = factor_lj*forceExp6*r2inv; + + evdwlOldEXP6_21 = buck1*(6.0*rexp - alphaOld21_ij*rm6ij*r6inv) - urc - durc*(r-rCut); + } + + if (isite1 == isite2) + evdwlOld = sqrt(fractionOld1_i*fractionOld2_j)*evdwlOldEXP6_12; + else + evdwlOld = sqrt(fractionOld1_i*fractionOld2_j)*evdwlOldEXP6_12 + sqrt(fractionOld2_i*fractionOld1_j)*evdwlOldEXP6_21; + + evdwlOld *= factor_lj; + + uCG[i] += 0.5*evdwlOld; + if (newton_pair || j < nlocal) + uCG[j] += 0.5*evdwlOld; + } + + if(rm12_ij!=0.0 && rm21_ij!=0.0){ + if(alpha21_ij == 6.0 || alpha12_ij == 6.0) + error->all(FLERR,"alpha_ij is 6.0 in pair exp6"); + + // A3. Compute some convenient quantities for evaluating the force + rminv = 1.0/rm12_ij; + buck1 = epsilon12_ij / (alpha12_ij - 6.0); + buck2 = 6.0*alpha12_ij; + rexp = expValue(alpha12_ij*(1.0-r*rminv)); + rm2ij = rm12_ij*rm12_ij; + rm6ij = rm2ij*rm2ij*rm2ij; + + // Compute the shifted potential + rCutExp = expValue(alpha12_ij*(1.0-rCut*rminv)); + urc = buck1*(6.0*rCutExp - alpha12_ij*rm6ij*rCut6inv); + durc = -buck1*buck2*(rCutExp*rminv - rCutInv*rm6ij*rCut6inv); + rin1 = shift*rm12_ij*func_rin(alpha12_ij); + + if(r < rin1){ + rin6 = rin1*rin1*rin1*rin1*rin1*rin1; + rin6inv = 1.0/rin6; + + rin1exp = expValue(alpha12_ij*(1.0-rin1*rminv)); + + uin1 = buck1*(6.0*rin1exp - alpha12_ij*rm6ij*rin6inv) - urc - durc*(rin1-rCut); + + win1 = -buck1*buck2*(rin1*rin1exp*rminv - rm6ij*rin6inv) - rin1*durc; + + aRep = -1.0*win1*powint(rin1,nRep)/nRep; + + uin1rep = aRep/powint(rin1,nRep); + + evdwlEXP6_12 = uin1 - uin1rep + aRep/powint(r,nRep); + } else { + evdwlEXP6_12 = buck1*(6.0*rexp - alpha12_ij*rm6ij*r6inv) - urc - durc*(r-rCut); + } + + rminv = 1.0/rm21_ij; + buck1 = epsilon21_ij / (alpha21_ij - 6.0); + buck2 = 6.0*alpha21_ij; + rexp = expValue(alpha21_ij*(1.0-r*rminv)); + rm2ij = rm21_ij*rm21_ij; + rm6ij = rm2ij*rm2ij*rm2ij; + + // Compute the shifted potential + rCutExp = expValue(alpha21_ij*(1.0-rCut*rminv)); + urc = buck1*(6.0*rCutExp - alpha21_ij*rm6ij*rCut6inv); + durc = -buck1*buck2*(rCutExp*rminv - rCutInv*rm6ij*rCut6inv); + rin1 = shift*rm21_ij*func_rin(alpha21_ij); + + if(r < rin1){ + rin6 = rin1*rin1*rin1*rin1*rin1*rin1; + rin6inv = 1.0/rin6; + + rin1exp = expValue(alpha21_ij*(1.0-rin1*rminv)); + + uin1 = buck1*(6.0*rin1exp - alpha21_ij*rm6ij*rin6inv) - urc - durc*(rin1-rCut); + + win1 = -buck1*buck2*(rin1*rin1exp*rminv - rm6ij*rin6inv) - rin1*durc; + + aRep = -1.0*win1*powint(rin1,nRep)/nRep; + + uin1rep = aRep/powint(rin1,nRep); + + evdwlEXP6_21 = uin1 - uin1rep + aRep/powint(r,nRep); + } else { + evdwlEXP6_21 = buck1*(6.0*rexp - alpha21_ij*rm6ij*r6inv) - urc - durc*(r-rCut); + } + + // + // Apply Mixing Rule to get the overall force for the CG pair + // + if (isite1 == isite2) fpair = sqrt(fractionOld1_i*fractionOld2_j)*fpairOldEXP6_12; + else fpair = sqrt(fractionOld1_i*fractionOld2_j)*fpairOldEXP6_12 + sqrt(fractionOld2_i*fractionOld1_j)*fpairOldEXP6_21; + + f(i,0) += delx*fpair; + f(i,1) += dely*fpair; + f(i,2) += delz*fpair; + if (newton_pair || j < nlocal) { + f(j,0) -= delx*fpair; + f(j,1) -= dely*fpair; + f(j,2) -= delz*fpair; + } + + if (isite1 == isite2) evdwl = sqrt(fraction1_i*fraction2_j)*evdwlEXP6_12; + else evdwl = sqrt(fraction1_i*fraction2_j)*evdwlEXP6_12 + sqrt(fraction2_i*fraction1_j)*evdwlEXP6_21; + evdwl *= factor_lj; + + uCGnew[i] += 0.5*evdwl; + if (newton_pair || j < nlocal) + uCGnew[j] += 0.5*evdwl; + evdwl = evdwlOld; + //if (vflag_either || eflag_atom) + if (EVFLAG) this->template ev_tally(ev,i,j,evdwl,fpair,delx,dely,delz); + } + } + } +} + +template +template +KOKKOS_INLINE_FUNCTION +void PairExp6rxKokkos::operator()(TagPairExp6rxCompute, const int &ii) const { + EV_FLOAT ev; + this->template operator()(TagPairExp6rxCompute(), ii, ev); +} + +/* ---------------------------------------------------------------------- + allocate all arrays +------------------------------------------------------------------------- */ + +template +void PairExp6rxKokkos::allocate() +{ + allocated = 1; + int n = atom->ntypes; + + memory->create(setflag,n+1,n+1,"pair:setflag"); + for (int i = 1; i <= n; i++) + for (int j = i; j <= n; j++) + setflag[i][j] = 0; + + memory->create_kokkos(k_cutsq,cutsq,n+1,n+1,"pair:cutsq"); + d_cutsq = k_cutsq.template view(); + + memory->create(cut,n+1,n+1,"pair:cut_lj"); +} + +/* ---------------------------------------------------------------------- */ + +template +void PairExp6rxKokkos::read_file(char *file) +{ + int params_per_line = 5; + char **words = new char*[params_per_line+1]; + + memory->sfree(params); + params = NULL; + nparams = maxparam = 0; + + // open file on proc 0 + + FILE *fp; + fp = NULL; + if (comm->me == 0) { + fp = force->open_potential(file); + if (fp == NULL) { + char str[128]; + sprintf(str,"Cannot open exp6/rx potential file %s",file); + error->one(FLERR,str); + } + } + + // read each set of params from potential file + // one set of params can span multiple lines + + int n,nwords,ispecies; + char line[MAXLINE],*ptr; + int eof = 0; + + while (1) { + if (comm->me == 0) { + ptr = fgets(line,MAXLINE,fp); + if (ptr == NULL) { + eof = 1; + fclose(fp); + } else n = strlen(line) + 1; + } + MPI_Bcast(&eof,1,MPI_INT,0,world); + if (eof) break; + MPI_Bcast(&n,1,MPI_INT,0,world); + MPI_Bcast(line,n,MPI_CHAR,0,world); + + // strip comment, skip line if blank + + if ((ptr = strchr(line,'#'))) *ptr = '\0'; + nwords = atom->count_words(line); + if (nwords == 0) continue; + + // concatenate additional lines until have params_per_line words + + while (nwords < params_per_line) { + n = strlen(line); + if (comm->me == 0) { + ptr = fgets(&line[n],MAXLINE-n,fp); + if (ptr == NULL) { + eof = 1; + fclose(fp); + } else n = strlen(line) + 1; + } + MPI_Bcast(&eof,1,MPI_INT,0,world); + if (eof) break; + MPI_Bcast(&n,1,MPI_INT,0,world); + MPI_Bcast(line,n,MPI_CHAR,0,world); + if ((ptr = strchr(line,'#'))) *ptr = '\0'; + nwords = atom->count_words(line); + } + + if (nwords != params_per_line) + error->all(FLERR,"Incorrect format in exp6/rx potential file"); + + // words = ptrs to all words in line + + nwords = 0; + words[nwords++] = strtok(line," \t\n\r\f"); + while ((words[nwords++] = strtok(NULL," \t\n\r\f"))) continue; + + for (ispecies = 0; ispecies < nspecies; ispecies++) + if (strcmp(words[0],&atom->dname[ispecies][0]) == 0) break; + if (ispecies == nspecies) continue; + + // load up parameter settings and error check their values + + if (nparams == maxparam) { + maxparam += DELTA; + memory->grow_kokkos(k_params,params,maxparam, + "pair:params"); + } + + params[nparams].ispecies = ispecies; + + n = strlen(&atom->dname[ispecies][0]) + 1; + params[nparams].name = new char[n]; + strcpy(params[nparams].name,&atom->dname[ispecies][0]); + + n = strlen(words[1]) + 1; + params[nparams].potential = new char[n]; + strcpy(params[nparams].potential,words[1]); + if (strcmp(params[nparams].potential,"exp6") == 0){ + params[nparams].alpha = atof(words[2]); + params[nparams].epsilon = atof(words[3]); + params[nparams].rm = atof(words[4]); + if (params[nparams].epsilon <= 0.0 || params[nparams].rm <= 0.0 || + params[nparams].alpha < 0.0) + error->all(FLERR,"Illegal exp6/rx parameters. Rm and Epsilon must be greater than zero. Alpha cannot be negative."); + } else { + error->all(FLERR,"Illegal exp6/rx parameters. Interaction potential does not exist."); + } + nparams++; + } + + delete [] words; + + k_params.template modify(); + k_params.template sync(); + d_params = k_params.template view(); +} + +/* ---------------------------------------------------------------------- */ + +template +void PairExp6rxKokkos::setup() +{ + int i,j,n; + + // set mol2param for all combinations + // must be a single exact match to lines read from file + + memory->destroy_kokkos(k_mol2param,mol2param); + memory->create_kokkos(k_mol2param,mol2param,nspecies,"pair:mol2param"); + + for (i = 0; i < nspecies; i++) { + n = -1; + for (j = 0; j < nparams; j++) { + if (i == params[j].ispecies) { + if (n >= 0) error->all(FLERR,"Potential file has duplicate entry"); + n = j; + } + } + mol2param[i] = n; + } + + k_mol2param.template modify(); + k_mol2param.template sync(); + d_mol2param = k_mol2param.template view(); + + neighflag = lmp->kokkos->neighflag; +} + +/* ---------------------------------------------------------------------- */ + +template +KOKKOS_INLINE_FUNCTION +void PairExp6rxKokkos::getParamsEXP6(int id,double &epsilon1,double &alpha1,double &rm1, double &fraction1,double &epsilon2,double &alpha2,double &rm2,double &fraction2,double &epsilon1_old,double &alpha1_old,double &rm1_old, double &fraction1_old,double &epsilon2_old,double &alpha2_old,double &rm2_old,double &fraction2_old) const +{ + int iparam, jparam; + double rmi, rmj, rmij, rm3ij; + double epsiloni, epsilonj, epsilonij; + double alphai, alphaj, alphaij; + double epsilon_old, rm3_old, alpha_old; + double epsilon, rm3, alpha; + double fractionOFA, fractionOFA_old; + double nTotalOFA, nTotalOFA_old; + double nTotal, nTotal_old; + double xMolei, xMolej, xMolei_old, xMolej_old; + + rm3 = 0.0; + epsilon = 0.0; + alpha = 0.0; + epsilon_old = 0.0; + rm3_old = 0.0; + alpha_old = 0.0; + fractionOFA = 0.0; + fractionOFA_old = 0.0; + nTotalOFA = 0.0; + nTotalOFA_old = 0.0; + nTotal = 0.0; + nTotal_old = 0.0; + + // Compute the total number of molecules in the old and new CG particle as well as the total number of molecules in the fluid portion of the old and new CG particle + for (int ispecies = 0; ispecies < nspecies; ispecies++){ + nTotal += dvector(ispecies,id); + nTotal_old += dvector(ispecies+nspecies,id); + + iparam = mol2param[ispecies]; + + if (iparam < 0 || d_params[iparam].potentialType != exp6PotentialType ) continue; + if (isOneFluidApprox(isite1) || isOneFluidApprox(isite2)) { + if (isite1 == d_params[iparam].ispecies || isite2 == d_params[iparam].ispecies) continue; + nTotalOFA_old += dvector(ispecies+nspecies,id); + nTotalOFA += dvector(ispecies,id); + } + } + if(nTotal < 1e-8 || nTotal_old < 1e-8) + error->all(FLERR,"The number of molecules in CG particle is less than 1e-8."); + + // Compute the mole fraction of molecules within the fluid portion of the particle (One Fluid Approximation) + fractionOFA_old = nTotalOFA_old / nTotal_old; + fractionOFA = nTotalOFA / nTotal; + + for (int ispecies = 0; ispecies < nspecies; ispecies++) { + iparam = mol2param[ispecies]; + if (iparam < 0 || d_params[iparam].potentialType != exp6PotentialType ) continue; + + // If Site1 matches a pure species, then grab the parameters + if (isite1 == d_params[iparam].ispecies){ + rm1_old = d_params[iparam].rm; + rm1 = d_params[iparam].rm; + epsilon1_old = d_params[iparam].epsilon; + epsilon1 = d_params[iparam].epsilon; + alpha1_old = d_params[iparam].alpha; + alpha1 = d_params[iparam].alpha; + + // Compute the mole fraction of Site1 + fraction1_old = dvector(ispecies+nspecies,id)/nTotal_old; + fraction1 = dvector(ispecies,id)/nTotal; + } + + // If Site2 matches a pure species, then grab the parameters + if (isite2 == d_params[iparam].ispecies){ + rm2_old = d_params[iparam].rm; + rm2 = d_params[iparam].rm; + epsilon2_old = d_params[iparam].epsilon; + epsilon2 = d_params[iparam].epsilon; + alpha2_old = d_params[iparam].alpha; + alpha2 = d_params[iparam].alpha; + + // Compute the mole fraction of Site2 + fraction2_old = dvector(ispecies+nspecies,id)/nTotal_old; + fraction2 = dvector(ispecies,id)/nTotal; + } + + // If Site1 or Site2 matches is a fluid, then compute the paramters + if (isOneFluidApprox(isite1) || isOneFluidApprox(isite2)) { + if (isite1 == d_params[iparam].ispecies || isite2 == d_params[iparam].ispecies) continue; + rmi = d_params[iparam].rm; + epsiloni = d_params[iparam].epsilon; + alphai = d_params[iparam].alpha; + xMolei = dvector(ispecies,id)/nTotalOFA; + xMolei_old = dvector(ispecies+nspecies,id)/nTotalOFA_old; + + for (int jspecies = 0; jspecies < nspecies; jspecies++) { + jparam = mol2param[jspecies]; + if (jparam < 0 || d_params[jparam].potentialType != exp6PotentialType ) continue; + if (isite1 == d_params[jparam].ispecies || isite2 == d_params[jparam].ispecies) continue; + rmj = d_params[jparam].rm; + epsilonj = d_params[jparam].epsilon; + alphaj = d_params[jparam].alpha; + xMolej = dvector(jspecies,id)/nTotalOFA; + xMolej_old = dvector(jspecies+nspecies,id)/nTotalOFA_old; + + rmij = (rmi+rmj)/2.0; + rm3ij = rmij*rmij*rmij; + epsilonij = sqrt(epsiloni*epsilonj); + alphaij = sqrt(alphai*alphaj); + + if(fractionOFA_old > 0.0){ + rm3_old += xMolei_old*xMolej_old*rm3ij; + epsilon_old += xMolei_old*xMolej_old*rm3ij*epsilonij; + alpha_old += xMolei_old*xMolej_old*rm3ij*epsilonij*alphaij; + } + if(fractionOFA > 0.0){ + rm3 += xMolei*xMolej*rm3ij; + epsilon += xMolei*xMolej*rm3ij*epsilonij; + alpha += xMolei*xMolej*rm3ij*epsilonij*alphaij; + } + } + } + } + + if (isOneFluidApprox(isite1)){ + rm1 = cbrt(rm3); + if(rm1 < 1e-16) { + rm1 = 0.0; + epsilon1 = 0.0; + alpha1 = 0.0; + } else { + epsilon1 = epsilon / rm3; + alpha1 = alpha / epsilon1 / rm3; + } + + fraction1 = fractionOFA; + + rm1_old = cbrt(rm3_old); + if(rm1_old < 1e-16) { + rm1_old = 0.0; + epsilon1_old = 0.0; + alpha1_old = 0.0; + } else { + epsilon1_old = epsilon_old / rm3_old; + alpha1_old = alpha_old / epsilon1_old / rm3_old; + } + fraction1_old = fractionOFA_old; + + // Fuchslin-Like Exp-6 Scaling + double powfuch = 0.0; + if(fuchslinEpsilon < 0.0){ + powfuch = pow(nTotalOFA,-fuchslinEpsilon); + if(powfuch<1e-15) epsilon1 = 0.0; + else epsilon1 *= 1.0/powfuch; + + powfuch = pow(nTotalOFA_old,-fuchslinEpsilon); + if(powfuch<1e-15) epsilon1_old = 0.0; + else epsilon1_old *= 1.0/powfuch; + + } else { + epsilon1 *= pow(nTotalOFA,fuchslinEpsilon); + epsilon1_old *= pow(nTotalOFA_old,fuchslinEpsilon); + } + + if(fuchslinR < 0.0){ + powfuch = pow(nTotalOFA,-fuchslinR); + if(powfuch<1e-15) rm1 = 0.0; + else rm1 *= 1.0/powfuch; + + powfuch = pow(nTotalOFA_old,-fuchslinR); + if(powfuch<1e-15) rm1_old = 0.0; + else rm1_old *= 1.0/powfuch; + + } else { + rm1 *= pow(nTotalOFA,fuchslinR); + rm1_old *= pow(nTotalOFA_old,fuchslinR); + } + } + + if (isOneFluidApprox(isite2)){ + rm2 = cbrt(rm3); + if(rm2 < 1e-16) { + rm2 = 0.0; + epsilon2 = 0.0; + alpha2 = 0.0; + } else { + epsilon2 = epsilon / rm3; + alpha2 = alpha / epsilon2 / rm3; + } + fraction2 = fractionOFA; + + rm2_old = cbrt(rm3_old); + if(rm2_old < 1e-16) { + rm2_old = 0.0; + epsilon2_old = 0.0; + alpha2_old = 0.0; + } else { + epsilon2_old = epsilon_old / rm3_old; + alpha2_old = alpha_old / epsilon2_old / rm3_old; + } + fraction2_old = fractionOFA_old; + + // Fuchslin-Like Exp-6 Scaling + double powfuch = 0.0; + if(fuchslinEpsilon < 0.0){ + powfuch = pow(nTotalOFA,-fuchslinEpsilon); + if(powfuch<1e-15) epsilon2 = 0.0; + else epsilon2 *= 1.0/powfuch; + + powfuch = pow(nTotalOFA_old,-fuchslinEpsilon); + if(powfuch<1e-15) epsilon2_old = 0.0; + else epsilon2_old *= 1.0/powfuch; + + } else { + epsilon2 *= pow(nTotalOFA,fuchslinEpsilon); + epsilon2_old *= pow(nTotalOFA_old,fuchslinEpsilon); + } + + if(fuchslinR < 0.0){ + powfuch = pow(nTotalOFA,-fuchslinR); + if(powfuch<1e-15) rm2 = 0.0; + else rm2 *= 1.0/powfuch; + + powfuch = pow(nTotalOFA_old,-fuchslinR); + if(powfuch<1e-15) rm2_old = 0.0; + else rm2_old *= 1.0/powfuch; + + } else { + rm2 *= pow(nTotalOFA,fuchslinR); + rm2_old *= pow(nTotalOFA_old,fuchslinR); + } + } +} + +/* ---------------------------------------------------------------------- */ + +template +KOKKOS_INLINE_FUNCTION +double PairExp6rxKokkos::func_rin(const double &alpha) const +{ + double function; + + const double a = 3.7682065; + const double b = -1.4308614; + + function = a+b*sqrt(alpha); + function = expValue(function); + + return function; +} + +/* ---------------------------------------------------------------------- */ + +template +KOKKOS_INLINE_FUNCTION +double PairExp6rxKokkos::expValue(double value) const +{ + double returnValue; + if(value < DBL_MIN_EXP) returnValue = 0.0; + else returnValue = exp(value); + + return returnValue; +} + +/* ---------------------------------------------------------------------- */ + +template +template +KOKKOS_INLINE_FUNCTION +void PairExp6rxKokkos::ev_tally(EV_FLOAT &ev, const int &i, const int &j, + const F_FLOAT &epair, const F_FLOAT &fpair, const F_FLOAT &delx, + const F_FLOAT &dely, const F_FLOAT &delz) const +{ + const int EFLAG = eflag; + const int VFLAG = vflag_either; + + // The eatom and vatom arrays are atomic for Half/Thread neighbor style + Kokkos::View::value> > v_eatom = k_eatom.view(); + Kokkos::View::value> > v_vatom = k_vatom.view(); + + if (EFLAG) { + if (eflag_atom) { + const E_FLOAT epairhalf = 0.5 * epair; + if (NEIGHFLAG!=FULL) { + if (NEWTON_PAIR || i < nlocal) v_eatom[i] += epairhalf; + if (NEWTON_PAIR || j < nlocal) v_eatom[j] += epairhalf; + } else { + v_eatom[i] += epairhalf; + } + } + } + + if (VFLAG) { + const E_FLOAT v0 = delx*delx*fpair; + const E_FLOAT v1 = dely*dely*fpair; + const E_FLOAT v2 = delz*delz*fpair; + const E_FLOAT v3 = delx*dely*fpair; + const E_FLOAT v4 = delx*delz*fpair; + const E_FLOAT v5 = dely*delz*fpair; + + if (vflag_global) { + if (NEIGHFLAG!=FULL) { + if (NEWTON_PAIR || i < nlocal) { + ev.v[0] += 0.5*v0; + ev.v[1] += 0.5*v1; + ev.v[2] += 0.5*v2; + ev.v[3] += 0.5*v3; + ev.v[4] += 0.5*v4; + ev.v[5] += 0.5*v5; + } + if (NEWTON_PAIR || j < nlocal) { + ev.v[0] += 0.5*v0; + ev.v[1] += 0.5*v1; + ev.v[2] += 0.5*v2; + ev.v[3] += 0.5*v3; + ev.v[4] += 0.5*v4; + ev.v[5] += 0.5*v5; + } + } else { + ev.v[0] += 0.5*v0; + ev.v[1] += 0.5*v1; + ev.v[2] += 0.5*v2; + ev.v[3] += 0.5*v3; + ev.v[4] += 0.5*v4; + ev.v[5] += 0.5*v5; + } + } + + if (vflag_atom) { + if (NEIGHFLAG!=FULL) { + if (NEWTON_PAIR || i < nlocal) { + v_vatom(i,0) += 0.5*v0; + v_vatom(i,1) += 0.5*v1; + v_vatom(i,2) += 0.5*v2; + v_vatom(i,3) += 0.5*v3; + v_vatom(i,4) += 0.5*v4; + v_vatom(i,5) += 0.5*v5; + } + if (NEWTON_PAIR || j < nlocal) { + v_vatom(j,0) += 0.5*v0; + v_vatom(j,1) += 0.5*v1; + v_vatom(j,2) += 0.5*v2; + v_vatom(j,3) += 0.5*v3; + v_vatom(j,4) += 0.5*v4; + v_vatom(j,5) += 0.5*v5; + } + } else { + v_vatom(i,0) += 0.5*v0; + v_vatom(i,1) += 0.5*v1; + v_vatom(i,2) += 0.5*v2; + v_vatom(i,3) += 0.5*v3; + v_vatom(i,4) += 0.5*v4; + v_vatom(i,5) += 0.5*v5; + } + } + } +} + +/* ---------------------------------------------------------------------- */ + +template +KOKKOS_INLINE_FUNCTION +int PairExp6rxKokkos::sbmask(const int& j) const { + return j >> SBBITS & 3; +} + +namespace LAMMPS_NS { +template class PairExp6rxKokkos; +#ifdef KOKKOS_HAVE_CUDA +template class PairExp6rxKokkos; +#endif +} \ No newline at end of file diff --git a/src/KOKKOS/pair_exp6_rx_kokkos.h b/src/KOKKOS/pair_exp6_rx_kokkos.h new file mode 100644 index 0000000000..4ff055123c --- /dev/null +++ b/src/KOKKOS/pair_exp6_rx_kokkos.h @@ -0,0 +1,204 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(exp6/rx/kk,PairExp6rxKokkos) +PairStyle(exp6/rx/kk/device,PairExp6rxKokkos) +PairStyle(exp6/rx/kk/host,PairExp6rxKokkos) + +#else + +#ifndef LMP_PAIR_EXP6_RX_KOKKOS_H +#define LMP_PAIR_EXP6_RX_KOKKOS_H + +#include "pair_exp6_rx.h" +#include "kokkos_type.h" +#include "pair_kokkos.h" + +namespace LAMMPS_NS { + +// Create a structure to hold the parameter data for all +// local and neighbor particles. Pack inside this struct +// to avoid any name clashes. + +template +struct PairExp6ParamDataTypeKokkos +{ + typedef ArrayTypes AT; + + int n; + typename AT::t_float_1d epsilon1, alpha1, rm1, fraction1, + epsilon2, alpha2, rm2, fraction2, + epsilonOld1, alphaOld1, rmOld1, fractionOld1, + epsilonOld2, alphaOld2, rmOld2, fractionOld2; + + // Default constructor -- nullify everything. + PairExp6ParamDataTypeKokkos(void) + : n(0) + {} +}; + +struct TagPairExp6rxgetParamsEXP6{}; + +template +struct TagPairExp6rxCompute{}; + +template +class PairExp6rxKokkos : public PairExp6rx { + public: + typedef DeviceType device_type; + typedef ArrayTypes AT; + typedef EV_FLOAT value_type; + + PairExp6rxKokkos(class LAMMPS *); + virtual ~PairExp6rxKokkos(); + virtual void compute(int, int); + + template + KOKKOS_INLINE_FUNCTION + void operator()(TagPairExp6rxCompute, const int&, EV_FLOAT&) const; + + template + KOKKOS_INLINE_FUNCTION + void operator()(TagPairExp6rxCompute, const int&) const; + + KOKKOS_INLINE_FUNCTION + void operator()(TagPairExp6rxgetParamsEXP6, const int&) const; + + template + KOKKOS_INLINE_FUNCTION + void ev_tally(EV_FLOAT &ev, const int &i, const int &j, + const F_FLOAT &epair, const F_FLOAT &fpair, const F_FLOAT &delx, + const F_FLOAT &dely, const F_FLOAT &delz) const; + + KOKKOS_INLINE_FUNCTION + int sbmask(const int& j) const; + + protected: + int eflag,vflag; + int nlocal,newton_pair,neighflag; + double special_coul[4]; + double special_lj[4]; + + typename AT::t_x_array_randomread x; + typename AT::t_f_array f; + typename AT::t_int_1d_randomread type; + typename AT::t_efloat_1d uCG, uCGnew; + typename AT::t_float_2d dvector; + + DAT::tdual_efloat_1d k_eatom; + DAT::tdual_virial_array k_vatom; + DAT::t_efloat_1d d_eatom; + DAT::t_virial_array d_vatom; + + typename AT::t_neighbors_2d d_neighbors; + typename AT::t_int_1d_randomread d_ilist; + typename AT::t_int_1d_randomread d_numneigh; + + PairExp6ParamDataTypeKokkos PairExp6ParamData; + + void allocate(); + DAT::tdual_int_1d k_mol2param; // mapping from molecule to parameters + typename AT::t_int_1d_randomread d_mol2param; + + typedef Kokkos::DualView tdual_param_1d; + typedef typename tdual_param_1d::t_dev_const_randomread t_param_1d_randomread; + + tdual_param_1d k_params; // parameter set for an I-J-K interaction + t_param_1d_randomread d_params; // parameter set for an I-J-K interaction + + typename ArrayTypes::tdual_ffloat_2d k_cutsq; + typename ArrayTypes::t_ffloat_2d d_cutsq; + + void read_file(char *); + void setup(); + + KOKKOS_INLINE_FUNCTION + void getParamsEXP6(int, double &, double &, double &, double &, double &, double &, double &, double &, double &, double &, double &, double &, double &, double &, double &, double &) const; + + KOKKOS_INLINE_FUNCTION + double func_rin(const double &) const; + + KOKKOS_INLINE_FUNCTION + double expValue(const double) const; + + friend void pair_virial_fdotr_compute(PairExp6rxKokkos*); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +E: alpha_ij is 6.0 in pair exp6 + +Self-explanatory + +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: PairExp6rxKokkos requires a fix rx command + +The fix rx command must come before the pair style command in the input file + +E: There are no rx species specified + +There must be at least one species specified through the fix rx command + +E: Site1 name not recognized in pair coefficients + +The site1 keyword does not match the species keywords specified throug the fix rx command + +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. + +E: Cannot open exp6/rx potential file %s + +Self-explanatory + +E: Incorrect format in exp6/rx potential file + +Self-explanatory + +E: Illegal exp6/rx parameters. Rm and Epsilon must be greater than zero. Alpha cannot be negative. + +Self-explanatory + +E: Illegal exp6/rx parameters. Interaction potential does not exist. + +Self-explanatory + +E: Potential file has duplicate entry. + +Self-explanatory + +E: The number of molecules in CG particle is less than 1e-8. + +Self-explanatory. Check the species concentrations have been properly set +and check the reaction kinetic solver parameters in fix rx to more for +sufficient accuracy. + + +*/ diff --git a/src/USER-DPD/pair_exp6_rx.cpp b/src/USER-DPD/pair_exp6_rx.cpp index 9af28026ae..2643c9ec04 100644 --- a/src/USER-DPD/pair_exp6_rx.cpp +++ b/src/USER-DPD/pair_exp6_rx.cpp @@ -77,6 +77,8 @@ PairExp6rx::PairExp6rx(LAMMPS *lmp) : Pair(lmp) PairExp6rx::~PairExp6rx() { + if (copymode) return; + for (int i=0; i < nparams; ++i) { delete[] params[i].name; delete[] params[i].potential; diff --git a/src/atom.h b/src/atom.h index 9abbb49569..de7cda06ac 100644 --- a/src/atom.h +++ b/src/atom.h @@ -255,8 +255,8 @@ class Atom : protected Pointers { void update_callback(int); int find_custom(const char *, int &); - int add_custom(const char *, int); - void remove_custom(int, int); + virtual int add_custom(const char *, int); + virtual void remove_custom(int, int); virtual void sync_modify(ExecutionSpace, unsigned int, unsigned int) {} From 6d94439cfe6f9f4cfd00a04b7e45d89693ffac46 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Mon, 28 Nov 2016 14:42:47 -0700 Subject: [PATCH 005/439] Integrating pair_dpd_fdt_energy_kokkos files --- src/KOKKOS/Install.sh | 2 ++ src/{USER-DPD => KOKKOS}/pair_dpd_fdt_energy_kokkos.cpp | 0 src/{USER-DPD => KOKKOS}/pair_dpd_fdt_energy_kokkos.h | 0 src/KOKKOS/pair_exp6_rx_kokkos.cpp | 4 ++++ 4 files changed, 6 insertions(+) rename src/{USER-DPD => KOKKOS}/pair_dpd_fdt_energy_kokkos.cpp (100%) rename src/{USER-DPD => KOKKOS}/pair_dpd_fdt_energy_kokkos.h (100%) diff --git a/src/KOKKOS/Install.sh b/src/KOKKOS/Install.sh index 14a8a951ee..7e46b52c2b 100644 --- a/src/KOKKOS/Install.sh +++ b/src/KOKKOS/Install.sh @@ -128,6 +128,8 @@ action pair_coul_long_kokkos.cpp pair_coul_long.cpp action pair_coul_long_kokkos.h pair_coul_long.h action pair_coul_wolf_kokkos.cpp action pair_coul_wolf_kokkos.h +action pair_dpd_fdt_energy_kokkos.cpp pair_dpd_fdt_energy.cpp +action pair_dpd_fdt_energy_kokkos.h pair_dpd_fdt_energy.h action pair_eam_kokkos.cpp pair_eam.cpp action pair_eam_kokkos.h pair_eam.h action pair_eam_alloy_kokkos.cpp pair_eam_alloy.cpp diff --git a/src/USER-DPD/pair_dpd_fdt_energy_kokkos.cpp b/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp similarity index 100% rename from src/USER-DPD/pair_dpd_fdt_energy_kokkos.cpp rename to src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp diff --git a/src/USER-DPD/pair_dpd_fdt_energy_kokkos.h b/src/KOKKOS/pair_dpd_fdt_energy_kokkos.h similarity index 100% rename from src/USER-DPD/pair_dpd_fdt_energy_kokkos.h rename to src/KOKKOS/pair_dpd_fdt_energy_kokkos.h diff --git a/src/KOKKOS/pair_exp6_rx_kokkos.cpp b/src/KOKKOS/pair_exp6_rx_kokkos.cpp index aa37c8375d..754fa4667d 100644 --- a/src/KOKKOS/pair_exp6_rx_kokkos.cpp +++ b/src/KOKKOS/pair_exp6_rx_kokkos.cpp @@ -11,6 +11,10 @@ See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------- + Contributing author: Stan Moore (Sandia) +------------------------------------------------------------------------- */ + #include #include #include From 6e6776f39635b1b69dab532bced2b0d95f150d62 Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Wed, 30 Nov 2016 16:25:07 -0500 Subject: [PATCH 006/439] Finish moving/integrating atom_vec_dpd_kokkos into the Kokkos package --- src/KOKKOS/Install.sh | 2 + src/USER-DPD/atom_vec_dpd_kokkos.cpp | 1874 -------------------------- src/USER-DPD/atom_vec_dpd_kokkos.h | 135 -- 3 files changed, 2 insertions(+), 2009 deletions(-) delete mode 100644 src/USER-DPD/atom_vec_dpd_kokkos.cpp delete mode 100644 src/USER-DPD/atom_vec_dpd_kokkos.h diff --git a/src/KOKKOS/Install.sh b/src/KOKKOS/Install.sh index 7e46b52c2b..1381a1978c 100644 --- a/src/KOKKOS/Install.sh +++ b/src/KOKKOS/Install.sh @@ -47,6 +47,8 @@ action atom_vec_bond_kokkos.cpp atom_vec_bond.cpp action atom_vec_bond_kokkos.h atom_vec_bond.h action atom_vec_charge_kokkos.cpp action atom_vec_charge_kokkos.h +action atom_vec_dpd_kokkos.cpp atom_vec_dpd.cpp +action atom_vec_dpd_kokkos.h atom_vec_dpd.h action atom_vec_full_kokkos.cpp atom_vec_full.cpp action atom_vec_full_kokkos.h atom_vec_full.h action atom_vec_kokkos.cpp diff --git a/src/USER-DPD/atom_vec_dpd_kokkos.cpp b/src/USER-DPD/atom_vec_dpd_kokkos.cpp deleted file mode 100644 index c79559172f..0000000000 --- a/src/USER-DPD/atom_vec_dpd_kokkos.cpp +++ /dev/null @@ -1,1874 +0,0 @@ -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale AtomicKokkos/Molecular Massively Parallel Simulator - http://lammps.sandia.gov, Sandia National Laboratories - Steve Plimpton, sjplimp@sandia.gov - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include -#include "atom_vec_dpd_kokkos.h" -#include "atom_kokkos.h" -#include "comm_kokkos.h" -#include "domain.h" -#include "modify.h" -#include "fix.h" -#include "atom_masks.h" -#include "memory.h" -#include "error.h" - -using namespace LAMMPS_NS; - -#define DELTA 10000 - -/* ---------------------------------------------------------------------- */ - -AtomVecDPDKokkos::AtomVecDPDKokkos(LAMMPS *lmp) : AtomVecKokkos(lmp) -{ - molecular = 0; - mass_type = 1; - - comm_x_only = comm_f_only = 0; - size_forward = 7; - size_reverse = 3; - size_border = 12; - size_velocity = 3; - size_data_atom = 6; - size_data_vel = 4; - xcol_data = 4; - - atom->rho_flag = 1; - atom->dpd_flag = 1; - - k_count = DAT::tdual_int_1d("atom::k_count",1); - atomKK = (AtomKokkos *) atom; - commKK = (CommKokkos *) comm; -} - -/* ---------------------------------------------------------------------- - grow atom arrays - n = 0 grows arrays by DELTA - n > 0 allocates arrays to size n -------------------------------------------------------------------------- */ - -void AtomVecDPDKokkos::grow(int n) -{ - if (n == 0) nmax += DELTA; - else nmax = n; - atomKK->nmax = nmax; - if (nmax < 0 || nmax > MAXSMALLINT) - error->one(FLERR,"Per-processor system is too big"); - - sync(Device,ALL_MASK); - modified(Device,ALL_MASK); - - memory->grow_kokkos(atomKK->k_tag,atomKK->tag,nmax,"atom:tag"); - memory->grow_kokkos(atomKK->k_type,atomKK->type,nmax,"atom:type"); - memory->grow_kokkos(atomKK->k_mask,atomKK->mask,nmax,"atom:mask"); - memory->grow_kokkos(atomKK->k_image,atomKK->image,nmax,"atom:image"); - - memory->grow_kokkos(atomKK->k_x,atomKK->x,nmax,3,"atom:x"); - memory->grow_kokkos(atomKK->k_v,atomKK->v,nmax,3,"atom:v"); - memory->grow_kokkos(atomKK->k_f,atomKK->f,nmax,3,"atom:f"); - - - memory->grow_kokkos(atomKK->k_rho,atomKK->rho,nmax,"atom:rho"); - memory->grow_kokkos(atomKK->k_dpdTheta,atomKK->dpdTheta,nmax,"atom:dpdTheta"); - memory->grow_kokkos(atomKK->k_uCond,atomKK->uCond,nmax,"atom:uCond"); - memory->grow_kokkos(atomKK->k_uMech,atomKK->uMech,nmax,"atom:uMech"); - memory->grow_kokkos(atomKK->k_uChem,atomKK->uChem,nmax,"atom:uChem"); - memory->grow_kokkos(atomKK->k_uCG,atomKK->uCG,nmax,"atom:uCG"); - memory->grow_kokkos(atomKK->k_uCGnew,atomKK->uCGnew,nmax,"atom:uCGnew"); - memory->grow_kokkos(atomKK->k_duChem,atomKK->duChem,nmax,"atom:duChem"); - - grow_reset(); - sync(Host,ALL_MASK); - - if (atom->nextra_grow) - for (int iextra = 0; iextra < atom->nextra_grow; iextra++) - modify->fix[atom->extra_grow[iextra]]->grow_arrays(nmax); -} - -/* ---------------------------------------------------------------------- - reset local array ptrs -------------------------------------------------------------------------- */ - -void AtomVecDPDKokkos::grow_reset() -{ - tag = atomKK->tag; - d_tag = atomKK->k_tag.d_view; - h_tag = atomKK->k_tag.h_view; - - type = atomKK->type; - d_type = atomKK->k_type.d_view; - h_type = atomKK->k_type.h_view; - mask = atomKK->mask; - d_mask = atomKK->k_mask.d_view; - h_mask = atomKK->k_mask.h_view; - image = atomKK->image; - d_image = atomKK->k_image.d_view; - h_image = atomKK->k_image.h_view; - - x = atomKK->x; - d_x = atomKK->k_x.d_view; - h_x = atomKK->k_x.h_view; - v = atomKK->v; - d_v = atomKK->k_v.d_view; - h_v = atomKK->k_v.h_view; - f = atomKK->f; - d_f = atomKK->k_f.d_view; - h_f = atomKK->k_f.h_view; - - rho = atomKK->rho; - d_rho = atomKK->k_rho.d_view; - h_rho = atomKK->k_rho.h_view; - dpdTheta = atomKK->dpdTheta; - d_dpdTheta = atomKK->k_dpdTheta.d_view; - h_dpdTheta = atomKK->k_dpdTheta.h_view; - uCond = atomKK->uCond; - d_uCond = atomKK->k_uCond.d_view;; - h_uCond = atomKK->k_uCond.h_view; - uMech = atomKK->uMech; - d_uMech = atomKK->k_uMech.d_view;; - h_uMech = atomKK->k_uMech.h_view; - uChem = atomKK->uChem; - d_uChem = atomKK->k_uChem.d_view;; - h_uChem = atomKK->k_uChem.h_view; - uCG = atomKK->uCG; - d_uCG = atomKK->k_uCG.d_view;; - h_uCG = atomKK->k_uCG.h_view; - uCGnew = atomKK->uCGnew; - d_uCGnew = atomKK->k_uCGnew.d_view;; - h_uCGnew = atomKK->k_uCGnew.h_view; - duChem = atomKK->duChem; - d_duChem = atomKK->k_duChem.d_view;; - h_duChem = atomKK->k_duChem.h_view; -} - -/* ---------------------------------------------------------------------- - copy atom I info to atom J -------------------------------------------------------------------------- */ - -void AtomVecDPDKokkos::copy(int i, int j, int delflag) -{ - h_tag[j] = h_tag[i]; - h_type[j] = h_type[i]; - mask[j] = mask[i]; - h_image[j] = h_image[i]; - h_x(j,0) = h_x(i,0); - h_x(j,1) = h_x(i,1); - h_x(j,2) = h_x(i,2); - h_v(j,0) = h_v(i,0); - h_v(j,1) = h_v(i,1); - h_v(j,2) = h_v(i,2); - h_dpdTheta[j] = h_dpdTheta[i]; - h_uCond[j] = h_uCond[i]; - h_uMech[j] = h_uMech[i]; - h_uChem[j] = h_uChem[i]; - h_uCG[j] = h_uCG[i]; - h_uCGnew[j] = h_uCGnew[i]; - - if (atom->nextra_grow) - for (int iextra = 0; iextra < atom->nextra_grow; iextra++) - modify->fix[atom->extra_grow[iextra]]->copy_arrays(i,j,delflag); -} - -/* ---------------------------------------------------------------------- */ - -template -struct AtomVecDPDKokkos_PackComm { - typedef DeviceType device_type; - - typename ArrayTypes::t_x_array_randomread _x; - typename ArrayTypes::t_efloat_1d _dpdTheta,_uCond,_uMech,_uChem; - typename ArrayTypes::t_xfloat_2d_um _buf; - typename ArrayTypes::t_int_2d_const _list; - const int _iswap; - X_FLOAT _xprd,_yprd,_zprd,_xy,_xz,_yz; - X_FLOAT _pbc[6]; - - AtomVecDPDKokkos_PackComm( - const typename DAT::tdual_x_array &x, - const typename DAT::tdual_efloat_1d &dpdTheta, - const typename DAT::tdual_efloat_1d &uCond, - const typename DAT::tdual_efloat_1d &uMech, - const typename DAT::tdual_efloat_1d &uChem, - const typename DAT::tdual_xfloat_2d &buf, - const typename DAT::tdual_int_2d &list, - const int & iswap, - const X_FLOAT &xprd, const X_FLOAT &yprd, const X_FLOAT &zprd, - const X_FLOAT &xy, const X_FLOAT &xz, const X_FLOAT &yz, const int* const pbc): - _x(x.view()), - _dpdTheta(dpdTheta.view()), - _uCond(uCond.view()), - _uMech(uMech.view()), - _uChem(uChem.view()), - _list(list.view()),_iswap(iswap), - _xprd(xprd),_yprd(yprd),_zprd(zprd), - _xy(xy),_xz(xz),_yz(yz) { - const size_t maxsend = (buf.view().dimension_0()*buf.view().dimension_1())/3; - const size_t elements = 3; - buffer_view(_buf,buf,maxsend,elements); - _pbc[0] = pbc[0]; _pbc[1] = pbc[1]; _pbc[2] = pbc[2]; - _pbc[3] = pbc[3]; _pbc[4] = pbc[4]; _pbc[5] = pbc[5]; - }; - - KOKKOS_INLINE_FUNCTION - void operator() (const int& i) const { - const int j = _list(_iswap,i); - if (PBC_FLAG == 0) { - _buf(i,0) = _x(j,0); - _buf(i,1) = _x(j,1); - _buf(i,2) = _x(j,2); - } else { - if (TRICLINIC == 0) { - _buf(i,0) = _x(j,0) + _pbc[0]*_xprd; - _buf(i,1) = _x(j,1) + _pbc[1]*_yprd; - _buf(i,2) = _x(j,2) + _pbc[2]*_zprd; - } else { - _buf(i,0) = _x(j,0) + _pbc[0]*_xprd + _pbc[5]*_xy + _pbc[4]*_xz; - _buf(i,1) = _x(j,1) + _pbc[1]*_yprd + _pbc[3]*_yz; - _buf(i,2) = _x(j,2) + _pbc[2]*_zprd; - } - } - _buf(i,3) = _dpdTheta(j); - _buf(i,4) = _uCond(j); - _buf(i,5) = _uMech(j); - _buf(i,6) = _uChem(j); - } -}; - -/* ---------------------------------------------------------------------- */ - -int AtomVecDPDKokkos::pack_comm_kokkos(const int &n, - const DAT::tdual_int_2d &list, - const int & iswap, - const DAT::tdual_xfloat_2d &buf, - const int &pbc_flag, - const int* const pbc) -{ - // Check whether to always run forward communication on the host - // Choose correct forward PackComm kernel - - if(commKK->forward_comm_on_host) { - sync(Host,X_MASK); - if(pbc_flag) { - if(domain->triclinic) { - struct AtomVecDPDKokkos_PackComm f(atomKK->k_x, - atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem, - buf,list,iswap, - domain->xprd,domain->yprd,domain->zprd, - domain->xy,domain->xz,domain->yz,pbc); - Kokkos::parallel_for(n,f); - } else { - struct AtomVecDPDKokkos_PackComm f(atomKK->k_x, - atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem, - buf,list,iswap, - domain->xprd,domain->yprd,domain->zprd, - domain->xy,domain->xz,domain->yz,pbc); - Kokkos::parallel_for(n,f); - } - } else { - if(domain->triclinic) { - struct AtomVecDPDKokkos_PackComm f(atomKK->k_x, - atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem, - buf,list,iswap, - domain->xprd,domain->yprd,domain->zprd, - domain->xy,domain->xz,domain->yz,pbc); - Kokkos::parallel_for(n,f); - } else { - struct AtomVecDPDKokkos_PackComm f(atomKK->k_x, - atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem, - buf,list,iswap, - domain->xprd,domain->yprd,domain->zprd, - domain->xy,domain->xz,domain->yz,pbc); - Kokkos::parallel_for(n,f); - } - } - LMPHostType::fence(); - } else { - sync(Device,X_MASK); - if(pbc_flag) { - if(domain->triclinic) { - struct AtomVecDPDKokkos_PackComm f(atomKK->k_x, - atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem, - buf,list,iswap, - domain->xprd,domain->yprd,domain->zprd, - domain->xy,domain->xz,domain->yz,pbc); - Kokkos::parallel_for(n,f); - } else { - struct AtomVecDPDKokkos_PackComm f(atomKK->k_x, - atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem, - buf,list,iswap, - domain->xprd,domain->yprd,domain->zprd, - domain->xy,domain->xz,domain->yz,pbc); - Kokkos::parallel_for(n,f); - } - } else { - if(domain->triclinic) { - struct AtomVecDPDKokkos_PackComm f(atomKK->k_x, - atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem, - buf,list,iswap, - domain->xprd,domain->yprd,domain->zprd, - domain->xy,domain->xz,domain->yz,pbc); - Kokkos::parallel_for(n,f); - } else { - struct AtomVecDPDKokkos_PackComm f(atomKK->k_x, - atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem, - buf,list,iswap, - domain->xprd,domain->yprd,domain->zprd, - domain->xy,domain->xz,domain->yz,pbc); - Kokkos::parallel_for(n,f); - } - } - LMPDeviceType::fence(); - } - - return n*size_forward; -} - -/* ---------------------------------------------------------------------- */ - -template -struct AtomVecDPDKokkos_PackCommSelf { - typedef DeviceType device_type; - - typename ArrayTypes::t_x_array_randomread _x; - typename ArrayTypes::t_x_array _xw; - typename ArrayTypes::t_efloat_1d _dpdTheta,_uCond,_uMech,_uChem; - int _nfirst; - typename ArrayTypes::t_int_2d_const _list; - const int _iswap; - X_FLOAT _xprd,_yprd,_zprd,_xy,_xz,_yz; - X_FLOAT _pbc[6]; - - AtomVecDPDKokkos_PackCommSelf( - const typename DAT::tdual_x_array &x, - const typename DAT::tdual_efloat_1d &dpdTheta, - const typename DAT::tdual_efloat_1d &uCond, - const typename DAT::tdual_efloat_1d &uMech, - const typename DAT::tdual_efloat_1d &uChem, - const int &nfirst, - const typename DAT::tdual_int_2d &list, - const int & iswap, - const X_FLOAT &xprd, const X_FLOAT &yprd, const X_FLOAT &zprd, - const X_FLOAT &xy, const X_FLOAT &xz, const X_FLOAT &yz, const int* const pbc): - _x(x.view()),_xw(x.view()), - _dpdTheta(dpdTheta.view()), - _uCond(uCond.view()), - _uMech(uMech.view()), - _uChem(uChem.view()), - _nfirst(nfirst),_list(list.view()),_iswap(iswap), - _xprd(xprd),_yprd(yprd),_zprd(zprd), - _xy(xy),_xz(xz),_yz(yz) { - _pbc[0] = pbc[0]; _pbc[1] = pbc[1]; _pbc[2] = pbc[2]; - _pbc[3] = pbc[3]; _pbc[4] = pbc[4]; _pbc[5] = pbc[5]; - }; - - KOKKOS_INLINE_FUNCTION - void operator() (const int& i) const { - const int j = _list(_iswap,i); - if (PBC_FLAG == 0) { - _xw(i+_nfirst,0) = _x(j,0); - _xw(i+_nfirst,1) = _x(j,1); - _xw(i+_nfirst,2) = _x(j,2); - } else { - if (TRICLINIC == 0) { - _xw(i+_nfirst,0) = _x(j,0) + _pbc[0]*_xprd; - _xw(i+_nfirst,1) = _x(j,1) + _pbc[1]*_yprd; - _xw(i+_nfirst,2) = _x(j,2) + _pbc[2]*_zprd; - } else { - _xw(i+_nfirst,0) = _x(j,0) + _pbc[0]*_xprd + _pbc[5]*_xy + _pbc[4]*_xz; - _xw(i+_nfirst,1) = _x(j,1) + _pbc[1]*_yprd + _pbc[3]*_yz; - _xw(i+_nfirst,2) = _x(j,2) + _pbc[2]*_zprd; - } - } - _dpdTheta(i+_nfirst) = _dpdTheta(j); - _uCond(i+_nfirst) = _uCond(j); - _uMech(i+_nfirst) = _uMech(j); - _uChem(i+_nfirst) = _uChem(j); - } -}; - -/* ---------------------------------------------------------------------- */ - -int AtomVecDPDKokkos::pack_comm_self(const int &n, const DAT::tdual_int_2d &list, const int & iswap, - const int nfirst, const int &pbc_flag, const int* const pbc) { - if(commKK->forward_comm_on_host) { - sync(Host,X_MASK); - modified(Host,X_MASK); - if(pbc_flag) { - if(domain->triclinic) { - struct AtomVecDPDKokkos_PackCommSelf f(atomKK->k_x, - atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem, - nfirst,list,iswap, - domain->xprd,domain->yprd,domain->zprd, - domain->xy,domain->xz,domain->yz,pbc); - Kokkos::parallel_for(n,f); - } else { - struct AtomVecDPDKokkos_PackCommSelf f(atomKK->k_x, - atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem, - nfirst,list,iswap, - domain->xprd,domain->yprd,domain->zprd, - domain->xy,domain->xz,domain->yz,pbc); - Kokkos::parallel_for(n,f); - } - } else { - if(domain->triclinic) { - struct AtomVecDPDKokkos_PackCommSelf f(atomKK->k_x, - atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem, - nfirst,list,iswap, - domain->xprd,domain->yprd,domain->zprd, - domain->xy,domain->xz,domain->yz,pbc); - Kokkos::parallel_for(n,f); - } else { - struct AtomVecDPDKokkos_PackCommSelf f(atomKK->k_x, - atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem, - nfirst,list,iswap, - domain->xprd,domain->yprd,domain->zprd, - domain->xy,domain->xz,domain->yz,pbc); - Kokkos::parallel_for(n,f); - } - } - LMPHostType::fence(); - } else { - sync(Device,X_MASK); - modified(Device,X_MASK); - if(pbc_flag) { - if(domain->triclinic) { - struct AtomVecDPDKokkos_PackCommSelf f(atomKK->k_x, - atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem, - nfirst,list,iswap, - domain->xprd,domain->yprd,domain->zprd, - domain->xy,domain->xz,domain->yz,pbc); - Kokkos::parallel_for(n,f); - } else { - struct AtomVecDPDKokkos_PackCommSelf f(atomKK->k_x, - atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem, - nfirst,list,iswap, - domain->xprd,domain->yprd,domain->zprd, - domain->xy,domain->xz,domain->yz,pbc); - Kokkos::parallel_for(n,f); - } - } else { - if(domain->triclinic) { - struct AtomVecDPDKokkos_PackCommSelf f(atomKK->k_x, - atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem, - nfirst,list,iswap, - domain->xprd,domain->yprd,domain->zprd, - domain->xy,domain->xz,domain->yz,pbc); - Kokkos::parallel_for(n,f); - } else { - struct AtomVecDPDKokkos_PackCommSelf f(atomKK->k_x, - atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem, - nfirst,list,iswap, - domain->xprd,domain->yprd,domain->zprd, - domain->xy,domain->xz,domain->yz,pbc); - Kokkos::parallel_for(n,f); - } - } - LMPDeviceType::fence(); - } - return n*3; -} - -/* ---------------------------------------------------------------------- */ - -template -struct AtomVecDPDKokkos_UnpackComm { - typedef DeviceType device_type; - - typename ArrayTypes::t_x_array _x; - typename ArrayTypes::t_efloat_1d _dpdTheta,_uCond,_uMech,_uChem; - typename ArrayTypes::t_xfloat_2d_const _buf; - int _first; - - AtomVecDPDKokkos_UnpackComm( - const typename DAT::tdual_x_array &x, - const typename DAT::tdual_efloat_1d &dpdTheta, - const typename DAT::tdual_efloat_1d &uCond, - const typename DAT::tdual_efloat_1d &uMech, - const typename DAT::tdual_efloat_1d &uChem, - const typename DAT::tdual_xfloat_2d &buf, - const int& first):_x(x.view()), - _dpdTheta(dpdTheta.view()), - _uCond(uCond.view()), - _uMech(uMech.view()), - _uChem(uChem.view()), - _buf(buf.view()), - _first(first) {}; - - KOKKOS_INLINE_FUNCTION - void operator() (const int& i) const { - _x(i+_first,0) = _buf(i,0); - _x(i+_first,1) = _buf(i,1); - _x(i+_first,2) = _buf(i,2); - _dpdTheta(i+_first) = _buf(i,3); - _uCond(i+_first) = _buf(i,4); - _uMech(i+_first) = _buf(i,5); - _uChem(i+_first) = _buf(i,6); - } -}; - -/* ---------------------------------------------------------------------- */ - -void AtomVecDPDKokkos::unpack_comm_kokkos(const int &n, const int &first, - const DAT::tdual_xfloat_2d &buf ) { - if(commKK->forward_comm_on_host) { - sync(Host,X_MASK); - modified(Host,X_MASK); - struct AtomVecDPDKokkos_UnpackComm f(atomKK->k_x, - atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem, - buf,first); - Kokkos::parallel_for(n,f); - LMPDeviceType::fence(); - } else { - sync(Device,X_MASK); - modified(Device,X_MASK); - struct AtomVecDPDKokkos_UnpackComm f(atomKK->k_x, - atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem, - buf,first); - Kokkos::parallel_for(n,f); - LMPDeviceType::fence(); - } -} - -/* ---------------------------------------------------------------------- */ - -int AtomVecDPDKokkos::pack_comm(int n, int *list, double *buf, - int pbc_flag, int *pbc) -{ - int i,j,m; - double dx,dy,dz; - - m = 0; - if (pbc_flag == 0) { - for (i = 0; i < n; i++) { - j = list[i]; - buf[m++] = h_x(j,0); - buf[m++] = h_x(j,1); - buf[m++] = h_x(j,2); - buf[m++] = dpdTheta[j]; - buf[m++] = uCond[j]; - buf[m++] = uMech[j]; - buf[m++] = uChem[j]; - } - } else { - if (domain->triclinic == 0) { - dx = pbc[0]*domain->xprd; - dy = pbc[1]*domain->yprd; - dz = pbc[2]*domain->zprd; - } else { - dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz; - dy = pbc[1]*domain->yprd + pbc[3]*domain->yz; - dz = pbc[2]*domain->zprd; - } - for (i = 0; i < n; i++) { - j = list[i]; - buf[m++] = h_x(j,0) + dx; - buf[m++] = h_x(j,1) + dy; - buf[m++] = h_x(j,2) + dz; - buf[m++] = h_dpdTheta[j]; - buf[m++] = h_uCond[j]; - buf[m++] = h_uMech[j]; - buf[m++] = h_uChem[j]; - } - } - return m; -} - -/* ---------------------------------------------------------------------- */ - -int AtomVecDPDKokkos::pack_comm_vel(int n, int *list, double *buf, - int pbc_flag, int *pbc) -{ - int i,j,m; - double dx,dy,dz,dvx,dvy,dvz; - - m = 0; - if (pbc_flag == 0) { - for (i = 0; i < n; i++) { - j = list[i]; - buf[m++] = h_x(j,0); - buf[m++] = h_x(j,1); - buf[m++] = h_x(j,2); - buf[m++] = h_v(j,0); - buf[m++] = h_v(j,1); - buf[m++] = h_v(j,2); - buf[m++] = h_dpdTheta[j]; - buf[m++] = h_uCond[j]; - buf[m++] = h_uMech[j]; - buf[m++] = h_uChem[j]; - } - } else { - if (domain->triclinic == 0) { - dx = pbc[0]*domain->xprd; - dy = pbc[1]*domain->yprd; - dz = pbc[2]*domain->zprd; - } else { - dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz; - dy = pbc[1]*domain->yprd + pbc[3]*domain->yz; - dz = pbc[2]*domain->zprd; - } - if (!deform_vremap) { - for (i = 0; i < n; i++) { - j = list[i]; - buf[m++] = h_x(j,0) + dx; - buf[m++] = h_x(j,1) + dy; - buf[m++] = h_x(j,2) + dz; - buf[m++] = h_v(j,0); - buf[m++] = h_v(j,1); - buf[m++] = h_v(j,2); - buf[m++] = h_dpdTheta[j]; - buf[m++] = h_uCond[j]; - buf[m++] = h_uMech[j]; - buf[m++] = h_uChem[j]; - } - } else { - dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4]; - dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3]; - dvz = pbc[2]*h_rate[2]; - for (i = 0; i < n; i++) { - j = list[i]; - buf[m++] = h_x(j,0) + dx; - buf[m++] = h_x(j,1) + dy; - buf[m++] = h_x(j,2) + dz; - if (mask[i] & deform_groupbit) { - buf[m++] = h_v(j,0) + dvx; - buf[m++] = h_v(j,1) + dvy; - buf[m++] = h_v(j,2) + dvz; - } else { - buf[m++] = h_v(j,0); - buf[m++] = h_v(j,1); - buf[m++] = h_v(j,2); - } - buf[m++] = h_dpdTheta(j); - buf[m++] = h_uCond(j); - buf[m++] = h_uMech(j); - buf[m++] = h_uChem(j); - } - } - } - return m; -} - -/* ---------------------------------------------------------------------- */ - -void AtomVecDPDKokkos::unpack_comm(int n, int first, double *buf) -{ - int i,m,last; - - m = 0; - last = first + n; - for (i = first; i < last; i++) { - h_x(i,0) = buf[m++]; - h_x(i,1) = buf[m++]; - h_x(i,2) = buf[m++]; - h_dpdTheta[i] = buf[m++]; - h_uCond[i] = buf[m++]; - h_uMech[i] = buf[m++]; - h_uChem[i] = buf[m++]; - } -} - -/* ---------------------------------------------------------------------- */ - -void AtomVecDPDKokkos::unpack_comm_vel(int n, int first, double *buf) -{ - int i,m,last; - - m = 0; - last = first + n; - for (i = first; i < last; i++) { - h_x(i,0) = buf[m++]; - h_x(i,1) = buf[m++]; - h_x(i,2) = buf[m++]; - h_v(i,0) = buf[m++]; - h_v(i,1) = buf[m++]; - h_v(i,2) = buf[m++]; - h_dpdTheta[i] = buf[m++]; - h_uCond[i] = buf[m++]; - h_uMech[i] = buf[m++]; - h_uChem[i] = buf[m++]; - } -} - -/* ---------------------------------------------------------------------- */ - -int AtomVecDPDKokkos::pack_reverse(int n, int first, double *buf) -{ - if(n > 0) - sync(Host,F_MASK); - - int m = 0; - const int last = first + n; - for (int i = first; i < last; i++) { - buf[m++] = h_f(i,0); - buf[m++] = h_f(i,1); - buf[m++] = h_f(i,2); - } - return m; -} - -/* ---------------------------------------------------------------------- */ - -void AtomVecDPDKokkos::unpack_reverse(int n, int *list, double *buf) -{ - if(n > 0) { - sync(Host,F_MASK); - modified(Host,F_MASK); - } - - int m = 0; - for (int i = 0; i < n; i++) { - const int j = list[i]; - h_f(j,0) += buf[m++]; - h_f(j,1) += buf[m++]; - h_f(j,2) += buf[m++]; - } -} - -/* ---------------------------------------------------------------------- */ - -template -struct AtomVecDPDKokkos_PackBorder { - typedef DeviceType device_type; - - typename ArrayTypes::t_xfloat_2d _buf; - const typename ArrayTypes::t_int_2d_const _list; - const int _iswap; - const typename ArrayTypes::t_x_array_randomread _x; - const typename ArrayTypes::t_tagint_1d _tag; - const typename ArrayTypes::t_int_1d _type; - const typename ArrayTypes::t_int_1d _mask; - typename ArrayTypes::t_efloat_1d _dpdTheta,_uCond,_uMech,_uChem,_uCG,_uCGnew; - X_FLOAT _dx,_dy,_dz; - - AtomVecDPDKokkos_PackBorder( - const typename ArrayTypes::t_xfloat_2d &buf, - const typename ArrayTypes::t_int_2d_const &list, - const int & iswap, - const typename ArrayTypes::t_x_array &x, - const typename ArrayTypes::t_tagint_1d &tag, - const typename ArrayTypes::t_int_1d &type, - const typename ArrayTypes::t_int_1d &mask, - const typename ArrayTypes::t_efloat_1d &dpdTheta, - const typename ArrayTypes::t_efloat_1d &uCond, - const typename ArrayTypes::t_efloat_1d &uMech, - const typename ArrayTypes::t_efloat_1d &uChem, - const typename ArrayTypes::t_efloat_1d &uCG, - const typename ArrayTypes::t_efloat_1d &uCGnew, - const X_FLOAT &dx, const X_FLOAT &dy, const X_FLOAT &dz): - _buf(buf),_list(list),_iswap(iswap), - _x(x),_tag(tag),_type(type),_mask(mask), - _dpdTheta(dpdTheta), - _uCond(uCond), - _uMech(uMech), - _uChem(uChem), - _uCG(uCGnew), - _uCGnew(uCGnew), - _dx(dx),_dy(dy),_dz(dz) {} - - KOKKOS_INLINE_FUNCTION - void operator() (const int& i) const { - const int j = _list(_iswap,i); - if (PBC_FLAG == 0) { - _buf(i,0) = _x(j,0); - _buf(i,1) = _x(j,1); - _buf(i,2) = _x(j,2); - } else { - _buf(i,0) = _x(j,0) + _dx; - _buf(i,1) = _x(j,1) + _dy; - _buf(i,2) = _x(j,2) + _dz; - } - _buf(i,3) = _tag(j); - _buf(i,4) = _type(j); - _buf(i,5) = _mask(j); - _buf(i,6) = _dpdTheta(j); - _buf(i,7) = _uCond(j); - _buf(i,8) = _uMech(j); - _buf(i,9) = _uChem(j); - _buf(i,10) = _uCG(j); - _buf(i,11) = _uCGnew(j); - } -}; - -/* ---------------------------------------------------------------------- */ - -int AtomVecDPDKokkos::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) -{ - X_FLOAT dx,dy,dz; - - if (pbc_flag != 0) { - if (domain->triclinic == 0) { - dx = pbc[0]*domain->xprd; - dy = pbc[1]*domain->yprd; - dz = pbc[2]*domain->zprd; - } else { - dx = pbc[0]; - dy = pbc[1]; - dz = pbc[2]; - } - if(space==Host) { - AtomVecDPDKokkos_PackBorder f( - buf.view(), k_sendlist.view(), - iswap,h_x,h_tag,h_type,h_mask, - h_dpdTheta,h_uCond,h_uMech,h_uChem,h_uCG,h_uCGnew, - dx,dy,dz); - Kokkos::parallel_for(n,f); - LMPHostType::fence(); - } else { - AtomVecDPDKokkos_PackBorder f( - buf.view(), k_sendlist.view(), - iswap,d_x,d_tag,d_type,d_mask, - d_dpdTheta,d_uCond,d_uMech,d_uChem,d_uCG,d_uCGnew, - dx,dy,dz); - Kokkos::parallel_for(n,f); - LMPDeviceType::fence(); - } - - } else { - dx = dy = dz = 0; - if(space==Host) { - AtomVecDPDKokkos_PackBorder f( - buf.view(), k_sendlist.view(), - iswap,h_x,h_tag,h_type,h_mask, - h_dpdTheta,h_uCond,h_uMech,h_uChem,h_uCG,h_uCGnew, - dx,dy,dz); - Kokkos::parallel_for(n,f); - LMPHostType::fence(); - } else { - AtomVecDPDKokkos_PackBorder f( - buf.view(), k_sendlist.view(), - iswap,d_x,d_tag,d_type,d_mask, - d_dpdTheta,d_uCond,d_uMech,d_uChem,d_uCG,d_uCGnew, - dx,dy,dz); - Kokkos::parallel_for(n,f); - LMPDeviceType::fence(); - } - } - return n*6; -} - -/* ---------------------------------------------------------------------- */ - -int AtomVecDPDKokkos::pack_border(int n, int *list, double *buf, - int pbc_flag, int *pbc) -{ - int i,j,m; - double dx,dy,dz; - - m = 0; - if (pbc_flag == 0) { - for (i = 0; i < n; i++) { - j = list[i]; - buf[m++] = h_x(j,0); - buf[m++] = h_x(j,1); - buf[m++] = h_x(j,2); - buf[m++] = ubuf(h_tag(j)).d; - buf[m++] = ubuf(h_type(j)).d; - buf[m++] = ubuf(h_mask(j)).d; - buf[m++] = h_dpdTheta(j); - buf[m++] = h_uCond(j); - buf[m++] = h_uMech(j); - buf[m++] = h_uChem(j); - buf[m++] = h_uCG(j); - buf[m++] = h_uCGnew(j); - } - } else { - if (domain->triclinic == 0) { - dx = pbc[0]*domain->xprd; - dy = pbc[1]*domain->yprd; - dz = pbc[2]*domain->zprd; - } else { - dx = pbc[0]; - dy = pbc[1]; - dz = pbc[2]; - } - for (i = 0; i < n; i++) { - j = list[i]; - buf[m++] = h_x(j,0) + dx; - buf[m++] = h_x(j,1) + dy; - buf[m++] = h_x(j,2) + dz; - buf[m++] = ubuf(h_tag(j)).d; - buf[m++] = ubuf(h_type(j)).d; - buf[m++] = ubuf(h_mask(j)).d; - buf[m++] = h_dpdTheta(j); - buf[m++] = h_uCond(j); - buf[m++] = h_uMech(j); - buf[m++] = h_uChem(j); - buf[m++] = h_uCG(j); - buf[m++] = h_uCGnew(j); - } - } - - if (atom->nextra_border) - for (int iextra = 0; iextra < atom->nextra_border; iextra++) - m += modify->fix[atom->extra_border[iextra]]->pack_border(n,list,&buf[m]); - - return m; -} - -/* ---------------------------------------------------------------------- */ - -int AtomVecDPDKokkos::pack_border_vel(int n, int *list, double *buf, - int pbc_flag, int *pbc) -{ - int i,j,m; - double dx,dy,dz,dvx,dvy,dvz; - - m = 0; - if (pbc_flag == 0) { - for (i = 0; i < n; i++) { - j = list[i]; - buf[m++] = h_x(j,0); - buf[m++] = h_x(j,1); - buf[m++] = h_x(j,2); - buf[m++] = ubuf(h_tag(j)).d; - buf[m++] = ubuf(h_type(j)).d; - buf[m++] = ubuf(h_mask(j)).d; - buf[m++] = h_v(j,0); - buf[m++] = h_v(j,1); - buf[m++] = h_v(j,2); - buf[m++] = h_dpdTheta(j); - buf[m++] = h_uCond(j); - buf[m++] = h_uMech(j); - buf[m++] = h_uChem(j); - buf[m++] = h_uCG(j); - buf[m++] = h_uCGnew(j); - } - } else { - if (domain->triclinic == 0) { - dx = pbc[0]*domain->xprd; - dy = pbc[1]*domain->yprd; - dz = pbc[2]*domain->zprd; - } else { - dx = pbc[0]; - dy = pbc[1]; - dz = pbc[2]; - } - if (!deform_vremap) { - for (i = 0; i < n; i++) { - j = list[i]; - buf[m++] = h_x(j,0) + dx; - buf[m++] = h_x(j,1) + dy; - buf[m++] = h_x(j,2) + dz; - buf[m++] = ubuf(h_tag(j)).d; - buf[m++] = ubuf(h_type(j)).d; - buf[m++] = ubuf(h_mask(j)).d; - buf[m++] = h_v(j,0); - buf[m++] = h_v(j,1); - buf[m++] = h_v(j,2); - buf[m++] = h_dpdTheta(j); - buf[m++] = h_uCond(j); - buf[m++] = h_uMech(j); - buf[m++] = h_uChem(j); - buf[m++] = h_uCG(j); - buf[m++] = h_uCGnew(j); - } - } else { - dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4]; - dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3]; - dvz = pbc[2]*h_rate[2]; - for (i = 0; i < n; i++) { - j = list[i]; - buf[m++] = h_x(j,0) + dx; - buf[m++] = h_x(j,1) + dy; - buf[m++] = h_x(j,2) + dz; - buf[m++] = ubuf(h_tag(j)).d; - buf[m++] = ubuf(h_type(j)).d; - buf[m++] = ubuf(h_mask(j)).d; - if (mask[i] & deform_groupbit) { - buf[m++] = h_v(j,0) + dvx; - buf[m++] = h_v(j,1) + dvy; - buf[m++] = h_v(j,2) + dvz; - } else { - buf[m++] = h_v(j,0); - buf[m++] = h_v(j,1); - buf[m++] = h_v(j,2); - } - buf[m++] = h_dpdTheta(j); - buf[m++] = h_uCond(j); - buf[m++] = h_uMech(j); - buf[m++] = h_uChem(j); - buf[m++] = h_uCG(j); - buf[m++] = h_uCGnew(j); - } - } - } - - if (atom->nextra_border) - for (int iextra = 0; iextra < atom->nextra_border; iextra++) - m += modify->fix[atom->extra_border[iextra]]->pack_border(n,list,&buf[m]); - - return m; -} - -/* ---------------------------------------------------------------------- */ - -int AtomVecDPDKokkos::pack_comm_hybrid(int n, int *list, double *buf) -{ - int i,j,m; - - m = 0; - for (i = 0; i < n; i++) { - j = list[i]; - buf[m++] = h_dpdTheta[j]; - buf[m++] = h_uCond[j]; - buf[m++] = h_uMech[j]; - buf[m++] = h_uChem[j]; - buf[m++] = h_uCG[j]; - buf[m++] = h_uCGnew[j]; - } - return m; -} - -/* ---------------------------------------------------------------------- */ - -int AtomVecDPDKokkos::pack_border_hybrid(int n, int *list, double *buf) -{ - int i,j,m; - - m = 0; - for (i = 0; i < n; i++) { - j = list[i]; - buf[m++] = h_dpdTheta[j]; - buf[m++] = h_uCond[j]; - buf[m++] = h_uMech[j]; - buf[m++] = h_uChem[j]; - buf[m++] = h_uCG[j]; - buf[m++] = h_uCGnew[j]; - } - return m; -} - -/* ---------------------------------------------------------------------- */ - -template -struct AtomVecDPDKokkos_UnpackBorder { - typedef DeviceType device_type; - - const typename ArrayTypes::t_xfloat_2d_const _buf; - typename ArrayTypes::t_x_array _x; - typename ArrayTypes::t_tagint_1d _tag; - typename ArrayTypes::t_int_1d _type; - typename ArrayTypes::t_int_1d _mask; - typename ArrayTypes::t_efloat_1d _dpdTheta,_uCond,_uMech,_uChem,_uCG,_uCGnew; - int _first; - - - AtomVecDPDKokkos_UnpackBorder( - const typename ArrayTypes::t_xfloat_2d_const &buf, - typename ArrayTypes::t_x_array &x, - typename ArrayTypes::t_tagint_1d &tag, - typename ArrayTypes::t_int_1d &type, - typename ArrayTypes::t_int_1d &mask, - const typename ArrayTypes::t_efloat_1d &dpdTheta, - const typename ArrayTypes::t_efloat_1d &uCond, - const typename ArrayTypes::t_efloat_1d &uMech, - const typename ArrayTypes::t_efloat_1d &uChem, - const typename ArrayTypes::t_efloat_1d &uCG, - const typename ArrayTypes::t_efloat_1d &uCGnew, - const int& first): - _buf(buf),_x(x),_tag(tag),_type(type),_mask(mask), - _dpdTheta(dpdTheta), - _uCond(uCond), - _uMech(uMech), - _uChem(uChem), - _uCG(uCGnew), - _uCGnew(uCGnew), - _first(first) {}; - - KOKKOS_INLINE_FUNCTION - void operator() (const int& i) const { - _x(i+_first,0) = _buf(i,0); - _x(i+_first,1) = _buf(i,1); - _x(i+_first,2) = _buf(i,2); - _tag(i+_first) = static_cast (_buf(i,3)); - _type(i+_first) = static_cast (_buf(i,4)); - _mask(i+_first) = static_cast (_buf(i,5)); - _dpdTheta(i+_first) = _buf(i,6); - _uCond(i+_first) = _buf(i,7); - _uMech(i+_first) = _buf(i,8); - _uChem(i+_first) = _buf(i,9); - _uCG(i+_first) = _buf(i,10); - _uCGnew(i+_first) = _buf(i,11); -// printf("%i %i %lf %lf %lf %i BORDER\n",_tag(i+_first),i+_first,_x(i+_first,0),_x(i+_first,1),_x(i+_first,2),_type(i+_first)); - } -}; - -/* ---------------------------------------------------------------------- */ - -void AtomVecDPDKokkos::unpack_border_kokkos(const int &n, const int &first, - const DAT::tdual_xfloat_2d &buf,ExecutionSpace space) { - modified(space,X_MASK|TAG_MASK|TYPE_MASK|MASK_MASK); - while (first+n >= nmax) grow(0); - modified(space,X_MASK|TAG_MASK|TYPE_MASK|MASK_MASK); - if(space==Host) { - struct AtomVecDPDKokkos_UnpackBorder f(buf.view(), - h_x,h_tag,h_type,h_mask, - h_dpdTheta,h_uCond,h_uMech,h_uChem,h_uCG,h_uCGnew, - first); - Kokkos::parallel_for(n,f); - LMPHostType::fence(); - } else { - struct AtomVecDPDKokkos_UnpackBorder f(buf.view(), - d_x,d_tag,d_type,d_mask, - d_dpdTheta,d_uCond,d_uMech,d_uChem,d_uCG,d_uCGnew, - first); - Kokkos::parallel_for(n,f); - LMPDeviceType::fence(); - } -} - -/* ---------------------------------------------------------------------- */ - -void AtomVecDPDKokkos::unpack_border(int n, int first, double *buf) -{ - int i,m,last; - - m = 0; - last = first + n; - for (i = first; i < last; i++) { - if (i == nmax) grow(0); - modified(Host,X_MASK|TAG_MASK|TYPE_MASK|MASK_MASK); - h_x(i,0) = buf[m++]; - h_x(i,1) = buf[m++]; - h_x(i,2) = buf[m++]; - h_tag(i) = (tagint) ubuf(buf[m++]).i; - h_type(i) = (int) ubuf(buf[m++]).i; - h_mask(i) = (int) ubuf(buf[m++]).i; - h_dpdTheta(i) = buf[m++]; - h_uCond(i) = buf[m++]; - h_uMech(i) = buf[m++]; - h_uChem(i) = buf[m++]; - h_uCG(i) = buf[m++]; - h_uCGnew(i) = buf[m++]; - } - - if (atom->nextra_border) - for (int iextra = 0; iextra < atom->nextra_border; iextra++) - m += modify->fix[atom->extra_border[iextra]]-> - unpack_border(n,first,&buf[m]); -} - -/* ---------------------------------------------------------------------- */ - -void AtomVecDPDKokkos::unpack_border_vel(int n, int first, double *buf) -{ - int i,m,last; - - m = 0; - last = first + n; - for (i = first; i < last; i++) { - if (i == nmax) grow(0); - modified(Host,X_MASK|V_MASK|TAG_MASK|TYPE_MASK|MASK_MASK); - h_x(i,0) = buf[m++]; - h_x(i,1) = buf[m++]; - h_x(i,2) = buf[m++]; - h_tag(i) = (tagint) ubuf(buf[m++]).i; - h_type(i) = (int) ubuf(buf[m++]).i; - h_mask(i) = (int) ubuf(buf[m++]).i; - h_v(i,0) = buf[m++]; - h_v(i,1) = buf[m++]; - h_v(i,2) = buf[m++]; - h_dpdTheta(i) = buf[m++]; - h_uCond(i) = buf[m++]; - h_uMech(i) = buf[m++]; - h_uChem(i) = buf[m++]; - h_uCG(i) = buf[m++]; - h_uCGnew(i) = buf[m++]; - } - - if (atom->nextra_border) - for (int iextra = 0; iextra < atom->nextra_border; iextra++) - m += modify->fix[atom->extra_border[iextra]]-> - unpack_border(n,first,&buf[m]); -} - -/* ---------------------------------------------------------------------- */ - -int AtomVecDPDKokkos::unpack_comm_hybrid(int n, int first, double *buf) -{ - int i,m,last; - - m = 0; - last = first + n; - for (i = first; i < last; i++) { - h_dpdTheta(i) = buf[m++]; - h_uCond(i) = buf[m++]; - h_uMech(i) = buf[m++]; - h_uChem(i) = buf[m++]; - h_uCG(i) = buf[m++]; - h_uCGnew(i) = buf[m++]; - } - return m; -} - -/* ---------------------------------------------------------------------- */ - -int AtomVecDPDKokkos::unpack_border_hybrid(int n, int first, double *buf) -{ - int i,m,last; - - m = 0; - last = first + n; - for (i = first; i < last; i++) { - h_dpdTheta(i) = buf[m++]; - h_uCond(i) = buf[m++]; - h_uMech(i) = buf[m++]; - h_uChem(i) = buf[m++]; - h_uCG(i) = buf[m++]; - h_uCGnew(i) = buf[m++]; - } - return m; -} - -/* ---------------------------------------------------------------------- */ - -template -struct AtomVecDPDKokkos_PackExchangeFunctor { - typedef DeviceType device_type; - typedef ArrayTypes AT; - typename AT::t_x_array_randomread _x; - typename AT::t_v_array_randomread _v; - typename AT::t_tagint_1d_randomread _tag; - typename AT::t_int_1d_randomread _type; - typename AT::t_int_1d_randomread _mask; - typename AT::t_imageint_1d_randomread _image; - typename AT::t_efloat_1d_randomread _dpdTheta,_uCond,_uMech,_uChem,_uCG,_uCGnew; - typename AT::t_x_array _xw; - typename AT::t_v_array _vw; - typename AT::t_tagint_1d _tagw; - typename AT::t_int_1d _typew; - typename AT::t_int_1d _maskw; - typename AT::t_imageint_1d _imagew; - typename AT::t_efloat_1d _dpdThetaw,_uCondw,_uMechw,_uChemw,_uCGw,_uCGneww; - - typename AT::t_xfloat_2d_um _buf; - typename AT::t_int_1d_const _sendlist; - typename AT::t_int_1d_const _copylist; - int _nlocal,_dim; - X_FLOAT _lo,_hi; - - AtomVecDPDKokkos_PackExchangeFunctor( - const AtomKokkos* atom, - const typename AT::tdual_xfloat_2d buf, - typename AT::tdual_int_1d sendlist, - typename AT::tdual_int_1d copylist,int nlocal, int dim, - X_FLOAT lo, X_FLOAT hi): - _x(atom->k_x.view()), - _v(atom->k_v.view()), - _tag(atom->k_tag.view()), - _type(atom->k_type.view()), - _mask(atom->k_mask.view()), - _image(atom->k_image.view()), - _dpdTheta(atom->k_dpdTheta.view()), - _uCond(atom->k_uCond.view()), - _uMech(atom->k_uMech.view()), - _uChem(atom->k_uChem.view()), - _uCG(atom->k_uCG.view()), - _uCGnew(atom->k_uCGnew.view()), - _xw(atom->k_x.view()), - _vw(atom->k_v.view()), - _tagw(atom->k_tag.view()), - _typew(atom->k_type.view()), - _maskw(atom->k_mask.view()), - _imagew(atom->k_image.view()), - _dpdThetaw(atom->k_dpdTheta.view()), - _uCondw(atom->k_uCond.view()), - _uMechw(atom->k_uMech.view()), - _uChemw(atom->k_uChem.view()), - _uCGw(atom->k_uCG.view()), - _uCGneww(atom->k_uCGnew.view()), - _sendlist(sendlist.template view()), - _copylist(copylist.template view()), - _nlocal(nlocal),_dim(dim), - _lo(lo),_hi(hi){ - const size_t elements = 17; - const int maxsendlist = (buf.template view().dimension_0()*buf.template view().dimension_1())/elements; - - buffer_view(_buf,buf,maxsendlist,elements); - } - - KOKKOS_INLINE_FUNCTION - void operator() (const int &mysend) const { - const int i = _sendlist(mysend); - _buf(mysend,0) = 17; - _buf(mysend,1) = _x(i,0); - _buf(mysend,2) = _x(i,1); - _buf(mysend,3) = _x(i,2); - _buf(mysend,4) = _v(i,0); - _buf(mysend,5) = _v(i,1); - _buf(mysend,6) = _v(i,2); - _buf(mysend,7) = _tag[i]; - _buf(mysend,8) = _type[i]; - _buf(mysend,9) = _mask[i]; - _buf(mysend,10) = _image[i]; - _buf(mysend,11) = _dpdTheta[i]; - _buf(mysend,12) = _uCond[i]; - _buf(mysend,13) = _uMech[i]; - _buf(mysend,14) = _uChem[i]; - _buf(mysend,15) = _uCG[i]; - _buf(mysend,16) = _uCGnew[i]; - const int j = _copylist(mysend); - - if(j>-1) { - _xw(i,0) = _x(j,0); - _xw(i,1) = _x(j,1); - _xw(i,2) = _x(j,2); - _vw(i,0) = _v(j,0); - _vw(i,1) = _v(j,1); - _vw(i,2) = _v(j,2); - _tagw[i] = _tag(j); - _typew[i] = _type(j); - _maskw[i] = _mask(j); - _imagew[i] = _image(j); - _dpdThetaw[i] = _dpdTheta(j); - _uCondw[i] = _uCond(j); - _uMechw[i] = _uMech(j); - _uChemw[i] = _uChem(j); - _uCGw[i] = _uCG(j); - _uCGneww[i] = _uCGnew(j); - } - } -}; - -/* ---------------------------------------------------------------------- */ - -int AtomVecDPDKokkos::pack_exchange_kokkos(const int &nsend,DAT::tdual_xfloat_2d &k_buf, DAT::tdual_int_1d k_sendlist,DAT::tdual_int_1d k_copylist,ExecutionSpace space,int dim,X_FLOAT lo,X_FLOAT hi ) -{ - if(nsend > (int) (k_buf.view().dimension_0()*k_buf.view().dimension_1())/17) { - int newsize = nsend*17/k_buf.view().dimension_1()+1; - k_buf.resize(newsize,k_buf.view().dimension_1()); - } - if(space == Host) { - AtomVecDPDKokkos_PackExchangeFunctor f(atomKK,k_buf,k_sendlist,k_copylist,atom->nlocal,dim,lo,hi); - Kokkos::parallel_for(nsend,f); - LMPHostType::fence(); - return nsend*17; - } else { - AtomVecDPDKokkos_PackExchangeFunctor f(atomKK,k_buf,k_sendlist,k_copylist,atom->nlocal,dim,lo,hi); - Kokkos::parallel_for(nsend,f); - LMPDeviceType::fence(); - return nsend*17; - } -} - -/* ---------------------------------------------------------------------- */ - -int AtomVecDPDKokkos::pack_exchange(int i, double *buf) -{ - int m = 1; - buf[m++] = h_x(i,0); - buf[m++] = h_x(i,1); - buf[m++] = h_x(i,2); - buf[m++] = h_v(i,0); - buf[m++] = h_v(i,1); - buf[m++] = h_v(i,2); - buf[m++] = ubuf(h_tag(i)).d; - buf[m++] = ubuf(h_type(i)).d; - buf[m++] = ubuf(h_mask(i)).d; - buf[m++] = ubuf(h_image(i)).d; - buf[m++] = h_dpdTheta[i]; - buf[m++] = h_uCond[i]; - buf[m++] = h_uMech[i]; - buf[m++] = h_uChem[i]; - buf[m++] = h_uCG[i]; - buf[m++] = h_uCGnew[i]; - - if (atom->nextra_grow) - for (int iextra = 0; iextra < atom->nextra_grow; iextra++) - m += modify->fix[atom->extra_grow[iextra]]->pack_exchange(i,&buf[m]); - - buf[0] = m; - return m; -} - -/* ---------------------------------------------------------------------- */ - -template -struct AtomVecDPDKokkos_UnpackExchangeFunctor { - typedef DeviceType device_type; - typedef ArrayTypes AT; - typename AT::t_x_array _x; - typename AT::t_v_array _v; - typename AT::t_tagint_1d _tag; - typename AT::t_int_1d _type; - typename AT::t_int_1d _mask; - typename AT::t_imageint_1d _image; - typename AT::t_efloat_1d _dpdTheta; - typename AT::t_efloat_1d _uCond; - typename AT::t_efloat_1d _uMech; - typename AT::t_efloat_1d _uChem; - typename AT::t_efloat_1d _uCG; - typename AT::t_efloat_1d _uCGnew; - - typename AT::t_xfloat_2d_um _buf; - typename AT::t_int_1d _nlocal; - int _dim; - X_FLOAT _lo,_hi; - - AtomVecDPDKokkos_UnpackExchangeFunctor( - const AtomKokkos* atom, - const typename AT::tdual_xfloat_2d buf, - typename AT::tdual_int_1d nlocal, - int dim, X_FLOAT lo, X_FLOAT hi): - _x(atom->k_x.view()), - _v(atom->k_v.view()), - _tag(atom->k_tag.view()), - _type(atom->k_type.view()), - _mask(atom->k_mask.view()), - _image(atom->k_image.view()), - _nlocal(nlocal.template view()),_dim(dim), - _lo(lo),_hi(hi){ - const size_t elements = 17; - const int maxsendlist = (buf.template view().dimension_0()*buf.template view().dimension_1())/elements; - - buffer_view(_buf,buf,maxsendlist,elements); - } - - KOKKOS_INLINE_FUNCTION - void operator() (const int &myrecv) const { - X_FLOAT x = _buf(myrecv,_dim+1); - if (x >= _lo && x < _hi) { - int i = Kokkos::atomic_fetch_add(&_nlocal(0),1); - _x(i,0) = _buf(myrecv,1); - _x(i,1) = _buf(myrecv,2); - _x(i,2) = _buf(myrecv,3); - _v(i,0) = _buf(myrecv,4); - _v(i,1) = _buf(myrecv,5); - _v(i,2) = _buf(myrecv,6); - _tag[i] = _buf(myrecv,7); - _type[i] = _buf(myrecv,8); - _mask[i] = _buf(myrecv,9); - _image[i] = _buf(myrecv,10); - _dpdTheta[i] = _buf(myrecv,11); - _uCond[i] = _buf(myrecv,12); - _uMech[i] = _buf(myrecv,13); - _uChem[i] = _buf(myrecv,14); - _uCG[i] = _buf(myrecv,15); - _uCGnew[i] = _buf(myrecv,16); - } - } -}; - -/* ---------------------------------------------------------------------- */ - -int AtomVecDPDKokkos::unpack_exchange_kokkos(DAT::tdual_xfloat_2d &k_buf,int nrecv,int nlocal,int dim,X_FLOAT lo,X_FLOAT hi,ExecutionSpace space) { - if(space == Host) { - k_count.h_view(0) = nlocal; - AtomVecDPDKokkos_UnpackExchangeFunctor f(atomKK,k_buf,k_count,dim,lo,hi); - Kokkos::parallel_for(nrecv/17,f); - LMPHostType::fence(); - return k_count.h_view(0); - } else { - k_count.h_view(0) = nlocal; - k_count.modify(); - k_count.sync(); - AtomVecDPDKokkos_UnpackExchangeFunctor f(atomKK,k_buf,k_count,dim,lo,hi); - Kokkos::parallel_for(nrecv/17,f); - LMPDeviceType::fence(); - k_count.modify(); - k_count.sync(); - - return k_count.h_view(0); - } -} - -/* ---------------------------------------------------------------------- */ - -int AtomVecDPDKokkos::unpack_exchange(double *buf) -{ - int nlocal = atom->nlocal; - if (nlocal == nmax) grow(0); - modified(Host,X_MASK | V_MASK | TAG_MASK | TYPE_MASK | - MASK_MASK | IMAGE_MASK); - - int m = 1; - h_x(nlocal,0) = buf[m++]; - h_x(nlocal,1) = buf[m++]; - h_x(nlocal,2) = buf[m++]; - h_v(nlocal,0) = buf[m++]; - h_v(nlocal,1) = buf[m++]; - h_v(nlocal,2) = buf[m++]; - h_tag(nlocal) = (tagint) ubuf(buf[m++]).i; - h_type(nlocal) = (int) ubuf(buf[m++]).i; - h_mask(nlocal) = (int) ubuf(buf[m++]).i; - h_image(nlocal) = (imageint) ubuf(buf[m++]).i; - h_dpdTheta[nlocal] = buf[m++]; - h_uCond[nlocal] = buf[m++]; - h_uMech[nlocal] = buf[m++]; - h_uChem[nlocal] = buf[m++]; - h_uCG[nlocal] = buf[m++]; - h_uCGnew[nlocal] = buf[m++]; - - if (atom->nextra_grow) - for (int iextra = 0; iextra < atom->nextra_grow; iextra++) - m += modify->fix[atom->extra_grow[iextra]]-> - unpack_exchange(nlocal,&buf[m]); - - atom->nlocal++; - return m; -} - -/* ---------------------------------------------------------------------- - size of restart data for all atoms owned by this proc - include extra data stored by fixes -------------------------------------------------------------------------- */ - -int AtomVecDPDKokkos::size_restart() -{ - int i; - - int nlocal = atom->nlocal; - int n = 15 * nlocal; // 11 + dpdTheta + uCond + uMech + uChem - - if (atom->nextra_restart) - for (int iextra = 0; iextra < atom->nextra_restart; iextra++) - for (i = 0; i < nlocal; i++) - n += modify->fix[atom->extra_restart[iextra]]->size_restart(i); - - return n; -} - -/* ---------------------------------------------------------------------- - pack atom I's data for restart file including extra quantities - xyz must be 1st 3 values, so that read_restart can test on them - molecular types may be negative, but write as positive -------------------------------------------------------------------------- */ - -int AtomVecDPDKokkos::pack_restart(int i, double *buf) -{ - sync(Host,X_MASK | V_MASK | TAG_MASK | TYPE_MASK | - MASK_MASK | IMAGE_MASK ); - - int m = 1; - buf[m++] = h_x(i,0); - buf[m++] = h_x(i,1); - buf[m++] = h_x(i,2); - buf[m++] = ubuf(h_tag(i)).d; - buf[m++] = ubuf(h_type(i)).d; - buf[m++] = ubuf(h_mask(i)).d; - buf[m++] = ubuf(h_image(i)).d; - buf[m++] = h_v(i,0); - buf[m++] = h_v(i,1); - buf[m++] = h_v(i,2); - buf[m++] = h_dpdTheta[i]; - buf[m++] = h_uCond[i]; - buf[m++] = h_uMech[i]; - buf[m++] = h_uChem[i]; - - if (atom->nextra_restart) - for (int iextra = 0; iextra < atom->nextra_restart; iextra++) - m += modify->fix[atom->extra_restart[iextra]]->pack_restart(i,&buf[m]); - - buf[0] = m; - return m; -} - -/* ---------------------------------------------------------------------- - unpack data for one atom from restart file including extra quantities -------------------------------------------------------------------------- */ - -int AtomVecDPDKokkos::unpack_restart(double *buf) -{ - int nlocal = atom->nlocal; - if (nlocal == nmax) { - grow(0); - if (atom->nextra_store) - memory->grow(atom->extra,nmax,atom->nextra_store,"atom:extra"); - } - modified(Host,X_MASK | V_MASK | TAG_MASK | TYPE_MASK | - MASK_MASK | IMAGE_MASK ); - - int m = 1; - h_x(nlocal,0) = buf[m++]; - h_x(nlocal,1) = buf[m++]; - h_x(nlocal,2) = buf[m++]; - h_tag(nlocal) = (tagint) ubuf(buf[m++]).i; - h_type(nlocal) = (int) ubuf(buf[m++]).i; - h_mask(nlocal) = (int) ubuf(buf[m++]).i; - h_image(nlocal) = (imageint) ubuf(buf[m++]).i; - h_v(nlocal,0) = buf[m++]; - h_v(nlocal,1) = buf[m++]; - h_v(nlocal,2) = buf[m++]; - h_dpdTheta[nlocal] = buf[m++]; - h_uCond[nlocal] = buf[m++]; - h_uMech[nlocal] = buf[m++]; - h_uChem[nlocal] = buf[m++]; - - double **extra = atom->extra; - if (atom->nextra_store) { - int size = static_cast (ubuf(buf[m++]).i) - m; - for (int i = 0; i < size; i++) extra[nlocal][i] = buf[m++]; - } - - atom->nlocal++; - return m; -} - -/* ---------------------------------------------------------------------- - create one atom of itype at coord - set other values to defaults -------------------------------------------------------------------------- */ - -void AtomVecDPDKokkos::create_atom(int itype, double *coord) -{ - int nlocal = atom->nlocal; - if (nlocal == nmax) { - //if(nlocal>2) printf("typeA: %i %i\n",type[0],type[1]); - atomKK->modified(Host,ALL_MASK); - grow(0); - //if(nlocal>2) printf("typeB: %i %i\n",type[0],type[1]); - } - atomKK->modified(Host,ALL_MASK); - - tag[nlocal] = 0; - type[nlocal] = itype; - h_x(nlocal,0) = coord[0]; - h_x(nlocal,1) = coord[1]; - h_x(nlocal,2) = coord[2]; - h_mask[nlocal] = 1; - h_image[nlocal] = ((tagint) IMGMAX << IMG2BITS) | - ((tagint) IMGMAX << IMGBITS) | IMGMAX; - h_v(nlocal,0) = 0.0; - h_v(nlocal,1) = 0.0; - h_v(nlocal,2) = 0.0; - h_rho[nlocal] = 0.0; - h_dpdTheta[nlocal] = 0.0; - h_uCond[nlocal] = 0.0; - h_uMech[nlocal] = 0.0; - h_uChem[nlocal] = 0.0; - h_uCG[nlocal] = 0.0; - h_uCGnew[nlocal] = 0.0; - h_duChem[nlocal] = 0.0; - - atom->nlocal++; -} - -/* ---------------------------------------------------------------------- - unpack one line from Atoms section of data file - initialize other atom quantities -------------------------------------------------------------------------- */ - -void AtomVecDPDKokkos::data_atom(double *coord, tagint imagetmp, - char **values) -{ - int nlocal = atom->nlocal; - if (nlocal == nmax) grow(0); - - h_tag[nlocal] = ATOTAGINT(values[0]); - h_type[nlocal] = atoi(values[1]); - if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes) - error->one(FLERR,"Invalid atom type in Atoms section of data file"); - - h_dpdTheta[nlocal] = atof(values[2]); - if (h_dpdTheta[nlocal] <= 0) - error->one(FLERR,"Internal temperature in Atoms section of date file must be > zero"); - - h_x(nlocal,0) = coord[0]; - h_x(nlocal,1) = coord[1]; - h_x(nlocal,2) = coord[2]; - - h_image[nlocal] = imagetmp; - - h_mask[nlocal] = 1; - h_v(nlocal,0) = 0.0; - h_v(nlocal,1) = 0.0; - h_v(nlocal,2) = 0.0; - - h_rho[nlocal] = 0.0; - h_uCond[nlocal] = 0.0; - h_uMech[nlocal] = 0.0; - h_uChem[nlocal] = 0.0; - h_uCG[nlocal] = 0.0; - h_uCGnew[nlocal] = 0.0; - - atomKK->modified(Host,ALL_MASK); - - atom->nlocal++; -} - -/* ---------------------------------------------------------------------- - unpack hybrid quantities from one line in Atoms section of data file - initialize other atom quantities for this sub-style -------------------------------------------------------------------------- */ - -int AtomVecDPDKokkos::data_atom_hybrid(int nlocal, char **values) -{ - h_dpdTheta(nlocal) = atof(values[0]); - - return 1; -} - -/* ---------------------------------------------------------------------- - pack atom info for data file including 3 image flags -------------------------------------------------------------------------- */ - -void AtomVecDPDKokkos::pack_data(double **buf) -{ - int nlocal = atom->nlocal; - for (int i = 0; i < nlocal; i++) { - buf[i][0] = ubuf(h_tag(i)).d; - buf[i][1] = ubuf(h_type(i)).d; - buf[i][2] = h_dpdTheta(i); - buf[i][3] = h_x(i,0); - buf[i][4] = h_x(i,1); - buf[i][5] = h_x(i,2); - buf[i][6] = (h_image[i] & IMGMASK) - IMGMAX; - buf[i][7] = (h_image[i] >> IMGBITS & IMGMASK) - IMGMAX; - buf[i][8] = (h_image[i] >> IMG2BITS) - IMGMAX; - } -} - -/* ---------------------------------------------------------------------- - pack hybrid atom info for data file -------------------------------------------------------------------------- */ - -int AtomVecDPDKokkos::pack_data_hybrid(int i, double *buf) -{ - buf[0] = h_dpdTheta(i); - return 1; -} - -/* ---------------------------------------------------------------------- - write atom info to data file including 3 image flags -------------------------------------------------------------------------- */ - -void AtomVecDPDKokkos::write_data(FILE *fp, int n, double **buf) -{ - for (int i = 0; i < n; i++) - fprintf(fp,TAGINT_FORMAT " %d %-1.16e %-1.16e %-1.16e %-1.16e %d %d %d\n", - (tagint) ubuf(buf[i][0]).i,(int) ubuf(buf[i][1]).i, - buf[i][2],buf[i][3],buf[i][4],buf[i][5], - (int) ubuf(buf[i][6]).i,(int) ubuf(buf[i][7]).i, - (int) ubuf(buf[i][8]).i); -} - -/* ---------------------------------------------------------------------- - write hybrid atom info to data file -------------------------------------------------------------------------- */ - -int AtomVecDPDKokkos::write_data_hybrid(FILE *fp, double *buf) -{ - fprintf(fp," %-1.16e",buf[0]); - return 1; -} - -/* ---------------------------------------------------------------------- - return # of bytes of allocated memory -------------------------------------------------------------------------- */ - -bigint AtomVecDPDKokkos::memory_usage() -{ - bigint bytes = 0; - - if (atom->memcheck("tag")) bytes += memory->usage(tag,nmax); - if (atom->memcheck("type")) bytes += memory->usage(type,nmax); - if (atom->memcheck("mask")) bytes += memory->usage(mask,nmax); - if (atom->memcheck("image")) bytes += memory->usage(image,nmax); - if (atom->memcheck("x")) bytes += memory->usage(x,nmax,3); - if (atom->memcheck("v")) bytes += memory->usage(v,nmax,3); - if (atom->memcheck("f")) bytes += memory->usage(f,nmax*commKK->nthreads,3); - if (atom->memcheck("rho")) bytes += memory->usage(rho,nmax); - if (atom->memcheck("dpdTheta")) bytes += memory->usage(dpdTheta,nmax); - if (atom->memcheck("uCond")) bytes += memory->usage(uCond,nmax); - if (atom->memcheck("uMech")) bytes += memory->usage(uMech,nmax); - if (atom->memcheck("uChem")) bytes += memory->usage(uChem,nmax); - if (atom->memcheck("uCG")) bytes += memory->usage(uCG,nmax); - if (atom->memcheck("uCGnew")) bytes += memory->usage(uCGnew,nmax); - if (atom->memcheck("duChem")) bytes += memory->usage(duChem,nmax); - - return bytes; -} - -/* ---------------------------------------------------------------------- */ - -void AtomVecDPDKokkos::sync(ExecutionSpace space, unsigned int mask) -{ - if (space == Device) { - if (mask & X_MASK) atomKK->k_x.sync(); - if (mask & V_MASK) atomKK->k_v.sync(); - if (mask & F_MASK) atomKK->k_f.sync(); - if (mask & TAG_MASK) atomKK->k_tag.sync(); - if (mask & TYPE_MASK) atomKK->k_type.sync(); - if (mask & MASK_MASK) atomKK->k_mask.sync(); - if (mask & IMAGE_MASK) atomKK->k_image.sync(); - } else { - if (mask & X_MASK) atomKK->k_x.sync(); - if (mask & V_MASK) atomKK->k_v.sync(); - if (mask & F_MASK) atomKK->k_f.sync(); - if (mask & TAG_MASK) atomKK->k_tag.sync(); - if (mask & TYPE_MASK) atomKK->k_type.sync(); - if (mask & MASK_MASK) atomKK->k_mask.sync(); - if (mask & IMAGE_MASK) atomKK->k_image.sync(); - } -} - -/* ---------------------------------------------------------------------- */ - -void AtomVecDPDKokkos::sync_overlapping_device(ExecutionSpace space, unsigned int mask) -{ - if (space == Device) { - if ((mask & X_MASK) && atomKK->k_x.need_sync()) - perform_async_copy(atomKK->k_x,space); - if ((mask & V_MASK) && atomKK->k_v.need_sync()) - perform_async_copy(atomKK->k_v,space); - if ((mask & F_MASK) && atomKK->k_f.need_sync()) - perform_async_copy(atomKK->k_f,space); - if ((mask & TAG_MASK) && atomKK->k_tag.need_sync()) - perform_async_copy(atomKK->k_tag,space); - if ((mask & TYPE_MASK) && atomKK->k_type.need_sync()) - perform_async_copy(atomKK->k_type,space); - if ((mask & MASK_MASK) && atomKK->k_mask.need_sync()) - perform_async_copy(atomKK->k_mask,space); - if ((mask & IMAGE_MASK) && atomKK->k_image.need_sync()) - perform_async_copy(atomKK->k_image,space); - } else { - if ((mask & X_MASK) && atomKK->k_x.need_sync()) - perform_async_copy(atomKK->k_x,space); - if ((mask & V_MASK) && atomKK->k_v.need_sync()) - perform_async_copy(atomKK->k_v,space); - if ((mask & F_MASK) && atomKK->k_f.need_sync()) - perform_async_copy(atomKK->k_f,space); - if ((mask & TAG_MASK) && atomKK->k_tag.need_sync()) - perform_async_copy(atomKK->k_tag,space); - if ((mask & TYPE_MASK) && atomKK->k_type.need_sync()) - perform_async_copy(atomKK->k_type,space); - if ((mask & MASK_MASK) && atomKK->k_mask.need_sync()) - perform_async_copy(atomKK->k_mask,space); - if ((mask & IMAGE_MASK) && atomKK->k_image.need_sync()) - perform_async_copy(atomKK->k_image,space); - } -} - -/* ---------------------------------------------------------------------- */ - -void AtomVecDPDKokkos::modified(ExecutionSpace space, unsigned int mask) -{ - if (space == Device) { - if (mask & X_MASK) atomKK->k_x.modify(); - if (mask & V_MASK) atomKK->k_v.modify(); - if (mask & F_MASK) atomKK->k_f.modify(); - if (mask & TAG_MASK) atomKK->k_tag.modify(); - if (mask & TYPE_MASK) atomKK->k_type.modify(); - if (mask & MASK_MASK) atomKK->k_mask.modify(); - if (mask & IMAGE_MASK) atomKK->k_image.modify(); - } else { - if (mask & X_MASK) atomKK->k_x.modify(); - if (mask & V_MASK) atomKK->k_v.modify(); - if (mask & F_MASK) atomKK->k_f.modify(); - if (mask & TAG_MASK) atomKK->k_tag.modify(); - if (mask & TYPE_MASK) atomKK->k_type.modify(); - if (mask & MASK_MASK) atomKK->k_mask.modify(); - if (mask & IMAGE_MASK) atomKK->k_image.modify(); - } -} - diff --git a/src/USER-DPD/atom_vec_dpd_kokkos.h b/src/USER-DPD/atom_vec_dpd_kokkos.h deleted file mode 100644 index d108e58ae7..0000000000 --- a/src/USER-DPD/atom_vec_dpd_kokkos.h +++ /dev/null @@ -1,135 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale AtomicKokkos/Molecular Massively Parallel Simulator - http://lammps.sandia.gov, Sandia National Laboratories - Steve Plimpton, sjplimp@sandia.gov - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef ATOM_CLASS - -AtomStyle(dpd/kk,AtomVecDPDKokkos) - -#else - -#ifndef LMP_ATOM_VEC_DPD_KOKKOS_H -#define LMP_ATOM_VEC_DPD_KOKKOS_H - -#include "atom_vec_kokkos.h" -#include "kokkos_type.h" - -namespace LAMMPS_NS { - -class AtomVecDPDKokkos : public AtomVecKokkos { - public: - AtomVecDPDKokkos(class LAMMPS *); - virtual ~AtomVecDPDKokkos() {} - void grow(int); - void copy(int, int, int); - int pack_comm(int, int *, double *, int, int *); - int pack_comm_vel(int, int *, double *, int, int *); - int pack_comm_hybrid(int, int *, double *); - void unpack_comm(int, int, double *); - void unpack_comm_vel(int, int, double *); - int unpack_comm_hybrid(int, int, double *); - int pack_reverse(int, int, double *); - void unpack_reverse(int, int *, double *); - int pack_border(int, int *, double *, int, int *); - int pack_border_vel(int, int *, double *, int, int *); - int pack_border_hybrid(int, int *, double *); - void unpack_border(int, int, double *); - void unpack_border_vel(int, int, double *); - int unpack_border_hybrid(int, int, double *); - int pack_exchange(int, double *); - int unpack_exchange(double *); - int size_restart(); - int pack_restart(int, double *); - int unpack_restart(double *); - void create_atom(int, double *); - void data_atom(double *, tagint, char **); - int data_atom_hybrid(int, char **); - void pack_data(double **); - int pack_data_hybrid(int, double *); - void write_data(FILE *, int, double **); - int write_data_hybrid(FILE *, double *); - bigint memory_usage(); - - void grow_reset(); - int pack_comm_kokkos(const int &n, const DAT::tdual_int_2d &k_sendlist, - const int & iswap, - const DAT::tdual_xfloat_2d &buf, - const int &pbc_flag, const int pbc[]); - void unpack_comm_kokkos(const int &n, const int &nfirst, - const DAT::tdual_xfloat_2d &buf); - int pack_comm_self(const int &n, const DAT::tdual_int_2d &list, - const int & iswap, const int nfirst, - const int &pbc_flag, const int pbc[]); - 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); - void unpack_border_kokkos(const int &n, const int &nfirst, - const DAT::tdual_xfloat_2d &buf, - ExecutionSpace space); - int pack_exchange_kokkos(const int &nsend,DAT::tdual_xfloat_2d &buf, - DAT::tdual_int_1d k_sendlist, - DAT::tdual_int_1d k_copylist, - ExecutionSpace space, int dim, - X_FLOAT lo, X_FLOAT hi); - int unpack_exchange_kokkos(DAT::tdual_xfloat_2d &k_buf, int nrecv, - int nlocal, int dim, X_FLOAT lo, X_FLOAT hi, - ExecutionSpace space); - - void sync(ExecutionSpace space, unsigned int mask); - void modified(ExecutionSpace space, unsigned int mask); - void sync_overlapping_device(ExecutionSpace space, unsigned int mask); - double *uCond,*uMech,*uChem,*uCG,*uCGnew,*rho,*dpdTheta; - double *duChem; - - protected: - DAT::t_efloat_1d d_uCond, d_uMech, d_uChem, d_uCG, d_uCGnew,d_rho,d_dpdTheta,d_duChem; - HAT::t_efloat_1d h_uCond, h_uMech, h_uChem, h_uCG, h_uCGnew,h_rho,h_dpdTheta,h_duChem; - - tagint *tag; - imageint *image; - int *type,*mask; - double **x,**v,**f; - - DAT::t_tagint_1d d_tag; - HAT::t_tagint_1d h_tag; - DAT::t_imageint_1d d_image; - HAT::t_imageint_1d h_image; - DAT::t_int_1d d_type, d_mask; - HAT::t_int_1d h_type, h_mask; - - DAT::t_x_array d_x; - DAT::t_v_array d_v; - DAT::t_f_array d_f; - HAT::t_x_array h_x; - HAT::t_v_array h_v; - HAT::t_f_array h_f; - - DAT::tdual_int_1d k_count; -}; - -} - -#endif -#endif - -/* ERROR/WARNING messages: - -E: Per-processor system is too big - -The number of owned atoms plus ghost atoms on a single -processor must fit in 32-bit integer. - -E: Invalid atom type in Atoms section of data file - -Atom types must range from 1 to specified # of types. - -*/ From 1dbf6d443f45a96887c02999bec3832d3c534b61 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 13 Dec 2016 16:43:40 -0700 Subject: [PATCH 007/439] Adding Kokkos files --- src/Depend.sh | 4 + src/KOKKOS/Install.sh | 6 + src/KOKKOS/fix_eos_table_rx_kokkos.cpp | 354 ++++++++++ src/KOKKOS/fix_eos_table_rx_kokkos.h | 152 +++++ src/KOKKOS/pair_exp6_rx_kokkos.cpp | 46 +- src/KOKKOS/pair_exp6_rx_kokkos.h | 9 +- src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp | 791 +++++++++++++++++++++++ src/KOKKOS/pair_multi_lucy_rx_kokkos.h | 215 ++++++ src/KOKKOS/pair_table_kokkos.cpp | 758 +--------------------- src/KOKKOS/pair_table_kokkos.h | 44 +- src/KOKKOS/pair_table_rx_kokkos.cpp | 634 ++++++++++++++++++ src/KOKKOS/pair_table_rx_kokkos.h | 269 ++++++++ src/USER-DPD/pair_multi_lucy.h | 2 +- src/USER-DPD/pair_multi_lucy_rx.cpp | 6 +- src/USER-DPD/pair_multi_lucy_rx.h | 2 +- src/pair_table.h | 6 +- 16 files changed, 2493 insertions(+), 805 deletions(-) create mode 100644 src/KOKKOS/fix_eos_table_rx_kokkos.cpp create mode 100644 src/KOKKOS/fix_eos_table_rx_kokkos.h create mode 100644 src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp create mode 100644 src/KOKKOS/pair_multi_lucy_rx_kokkos.h create mode 100644 src/KOKKOS/pair_table_rx_kokkos.cpp create mode 100644 src/KOKKOS/pair_table_rx_kokkos.h diff --git a/src/Depend.sh b/src/Depend.sh index 44964d5182..51f83b2ea5 100644 --- a/src/Depend.sh +++ b/src/Depend.sh @@ -113,6 +113,10 @@ if (test $1 = "USER-CG-CMM") then depend USER-OMP fi +if (test $1 = "USER-DPD") then + depend KOKKOS +fi + if (test $1 = "USER-FEP") then depend USER-OMP fi diff --git a/src/KOKKOS/Install.sh b/src/KOKKOS/Install.sh index 1381a1978c..567e825642 100644 --- a/src/KOKKOS/Install.sh +++ b/src/KOKKOS/Install.sh @@ -73,6 +73,8 @@ action domain_kokkos.cpp action domain_kokkos.h action fix_deform_kokkos.cpp action fix_deform_kokkos.h +action fix_eos_table_rx_kokkos.cpp fix_eos_table_rx.cpp +action fix_eos_table_rx_kokkos.h fix_eos_table_rx.h action fix_langevin_kokkos.cpp action fix_langevin_kokkos.h action fix_nh_kokkos.cpp @@ -171,6 +173,8 @@ action pair_lj_gromacs_kokkos.cpp action pair_lj_gromacs_kokkos.h action pair_lj_sdk_kokkos.cpp pair_lj_sdk.cpp action pair_lj_sdk_kokkos.h pair_lj_sdk.h +action pair_multi_lucy_rx_kokkos.cpp pair_multi_lucy_rx.cpp +action pair_multi_lucy_rx_kokkos.h pair_multi_lucy_rx.h action pair_reax_c_kokkos.cpp pair_reax_c.cpp action pair_reax_c_kokkos.h pair_reax_c.h action pair_sw_kokkos.cpp pair_sw.cpp @@ -179,6 +183,8 @@ action pair_vashishta_kokkos.cpp pair_vashishta.cpp action pair_vashishta_kokkos.h pair_vashishta.h action pair_table_kokkos.cpp action pair_table_kokkos.h +action pair_table_rx_kokkos.cpp pair_table_rx.cpp +action pair_table_rx_kokkos.h pair_table_rx.h action pair_tersoff_kokkos.cpp pair_tersoff.cpp action pair_tersoff_kokkos.h pair_tersoff.h action pair_tersoff_mod_kokkos.cpp pair_tersoff_mod.cpp diff --git a/src/KOKKOS/fix_eos_table_rx_kokkos.cpp b/src/KOKKOS/fix_eos_table_rx_kokkos.cpp new file mode 100644 index 0000000000..a1e0b1a07d --- /dev/null +++ b/src/KOKKOS/fix_eos_table_rx_kokkos.cpp @@ -0,0 +1,354 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Stan Moore (Sandia) +------------------------------------------------------------------------- */ + +#include +#include +#include "fix_eos_table_rx_kokkos.h" +#include "atom_kokkos.h" +#include "error.h" +#include "force.h" +#include "memory.h" +#include "comm.h" +#include +#include "modify.h" +#include "atom_masks.h" + +#define MAXLINE 1024 + +using namespace LAMMPS_NS; +using namespace FixConst; + +/* ---------------------------------------------------------------------- */ + +template +FixEOStableRXKokkos::FixEOStableRXKokkos(LAMMPS *lmp, int narg, char **arg) : + FixEOStableRX(lmp, narg, arg) +{ + atomKK = (AtomKokkos *) atom; + execution_space = ExecutionSpaceFromDevice::space; + datamask_read = X_MASK | F_MASK | TYPE_MASK | ENERGY_MASK | VIRIAL_MASK; + datamask_modify = F_MASK | ENERGY_MASK | VIRIAL_MASK; +} + +/* ---------------------------------------------------------------------- */ + +template +FixEOStableRXKokkos::~FixEOStableRXKokkos() +{ + +} + +/* ---------------------------------------------------------------------- */ + +template +void FixEOStableRXKokkos::setup(int vflag) +{ + int nlocal = atom->nlocal; + mask = atomKK->k_mask.view(); + uCond = atomKK->k_uCond.view(); + uMech = atomKK->k_uMech.view(); + uChem = atomKK->k_uChem.view(); + dpdTheta= atomKK->k_dpdTheta.view(); + uCG = atomKK->k_uCG.view(); + uCGnew = atomKK->k_uCGnew.view(); + double duChem; + + for (int i = 0; i < nlocal; i++) // parallel_for + if (mask[i] & groupbit){ + duChem = uCG[i] - uCGnew[i]; + uChem[i] += duChem; + uCG[i] = 0.0; + uCGnew[i] = 0.0; + } + + // Communicate the updated momenta and velocities to all nodes + comm->forward_comm_fix(this); + + for (int i = 0; i < nlocal; i++) // parallel_for + if (mask[i] & groupbit) + temperature_lookup(i,uCond[i]+uMech[i]+uChem[i],dpdTheta[i]); +} + +/* ---------------------------------------------------------------------- */ + +template +void FixEOStableRXKokkos::init() +{ + int nlocal = atom->nlocal; + mask = atomKK->k_mask.view(); + uCond = atomKK->k_uCond.view(); + uMech = atomKK->k_uMech.view(); + uChem = atomKK->k_uChem.view(); + dpdTheta= atomKK->k_dpdTheta.view(); + double tmp; + + if(this->restart_reset){ + for (int i = 0; i < nlocal; i++) + if (mask[i] & groupbit) + temperature_lookup(i,uCond[i]+uMech[i]+uChem[i],dpdTheta[i]); + } else { + for (int i = 0; i < nlocal; i++) + if (mask[i] & groupbit) { + if(dpdTheta[i] <= 0.0) + error->one(FLERR,"Internal temperature <= zero"); + energy_lookup(i,dpdTheta[i],tmp); + uCond[i] = tmp / 2.0; + uMech[i] = tmp / 2.0; + uChem[i] = 0.0; + } + } +} + + +/* ---------------------------------------------------------------------- */ + +template +void FixEOStableRXKokkos::post_integrate() +{ + int nlocal = atom->nlocal; + mask = atomKK->k_mask.view(); + uCond = atomKK->k_uCond.view(); + uMech = atomKK->k_uMech.view(); + uChem = atomKK->k_uChem.view(); + dpdTheta= atomKK->k_dpdTheta.view(); + + for (int i = 0; i < nlocal; i++) + if (mask[i] & groupbit){ + temperature_lookup(i,uCond[i]+uMech[i]+uChem[i],dpdTheta[i]); + if(dpdTheta[i] <= 0.0) + error->one(FLERR,"Internal temperature <= zero"); + } +} + +/* ---------------------------------------------------------------------- */ + +template +void FixEOStableRXKokkos::end_of_step() +{ + int nlocal = atom->nlocal; + mask = atomKK->k_mask.view(); + uCond = atomKK->k_uCond.view(); + uMech = atomKK->k_uMech.view(); + uChem = atomKK->k_uChem.view(); + dpdTheta= atomKK->k_dpdTheta.view(); + uCG = atomKK->k_uCG.view(); + uCGnew = atomKK->k_uCGnew.view(); + double duChem; + + // Communicate the ghost uCGnew + comm->reverse_comm_fix(this); + + for (int i = 0; i < nlocal; i++) + if (mask[i] & groupbit){ + duChem = uCG[i] - uCGnew[i]; + uChem[i] += duChem; + uCG[i] = 0.0; + uCGnew[i] = 0.0; + } + + // Communicate the updated momenta and velocities to all nodes + comm->forward_comm_fix(this); + + for (int i = 0; i < nlocal; i++) + if (mask[i] & groupbit){ + temperature_lookup(i,uCond[i]+uMech[i]+uChem[i],dpdTheta[i]); + if(dpdTheta[i] <= 0.0) + error->one(FLERR,"Internal temperature <= zero"); + } +} + +/* ---------------------------------------------------------------------- + calculate potential ui at temperature thetai +------------------------------------------------------------------------- */ + +template +KOKKOS_INLINE_FUNCTION +void FixEOStableRXKokkos::energy_lookup(int id, double thetai, double &ui) const +{ + int itable; + double fraction, uTmp, nTotal; + + ui = 0.0; + nTotal = 0.0; + for(int ispecies=0;ispecieslo); + thetai = MIN(thetai,tb->hi); + + if (tabstyle == LINEAR) { + itable = static_cast ((thetai - tb->lo) * tb->invdelta); + fraction = (thetai - tb->r[itable]) * tb->invdelta; + uTmp = tb->e[itable] + fraction*tb->de[itable]; + + uTmp += dHf[ispecies]; + // mol fraction form: + ui += atom->dvector[ispecies][id]*uTmp; + nTotal += atom->dvector[ispecies][id]; + } + } + ui = ui - double(nTotal+1.5)*force->boltz*thetai; +} + +/* ---------------------------------------------------------------------- + calculate temperature thetai at energy ui +------------------------------------------------------------------------- */ + +template +KOKKOS_INLINE_FUNCTION +void FixEOStableRXKokkos::temperature_lookup(int id, double ui, double &thetai) const +{ + Table *tb = &tables[0]; + + int it; + double t1,t2,u1,u2,f1,f2; + double maxit = 100; + double temp; + double delta = 0.001; + + // Store the current thetai in t1 + t1 = MAX(thetai,tb->lo); + t1 = MIN(t1,tb->hi); + if(t1==tb->hi) delta = -delta; + + // Compute u1 at thetai + energy_lookup(id,t1,u1); + + // Compute f1 + f1 = u1 - ui; + + // Compute guess of t2 + t2 = (1.0 + delta)*t1; + + // Compute u2 at t2 + energy_lookup(id,t2,u2); + + // Compute f1 + f2 = u2 - ui; + + // Apply the Secant Method + for(it=0; itone(FLERR,"NaN detected in secant solver."); + temp = t1; + temp = MAX(temp,tb->lo); + temp = MIN(temp,tb->hi); + char str[256]; + sprintf(str,"Secant solver did not converge because table bounds were exceeded: it=%d id=%d ui=%lf thetai=%lf t1=%lf t2=%lf f1=%lf f2=%lf dpdTheta=%lf\n",it,id,ui,thetai,t1,t2,f1,f2,temp); + error->warning(FLERR,str); + break; + } + temp = t2 - f2*(t2-t1)/(f2-f1); + if(fabs(temp-t2) < 1e-6) break; + f1 = f2; + t1 = t2; + t2 = temp; + energy_lookup(id,t2,u2); + f2 = u2 - ui; + } + if(it==maxit){ + char str[256]; + sprintf(str,"Maxit exceeded in secant solver: id=%d ui=%lf thetai=%lf t1=%lf t2=%lf f1=%lf f2=%lf\n",id,ui,thetai,t1,t2,f1,f2); + if(isnan(f1) || isnan(f2) || isnan(ui) || isnan(thetai) || isnan(t1) || isnan(t2)) + error->one(FLERR,"NaN detected in secant solver."); + error->one(FLERR,str); + } + thetai = temp; +} + +/* ---------------------------------------------------------------------- */ + +template +int FixEOStableRXKokkos::pack_forward_comm(int n, int *list, double *buf, int pbc_flag, int *pbc) +{ + int ii,jj,m; + uChem = atomKK->k_uChem.view(); + uCG = atomKK->k_uCG.view(); + uCGnew = atomKK->k_uCGnew.view(); + + m = 0; + for (ii = 0; ii < n; ii++) { + jj = list[ii]; + buf[m++] = uChem[jj]; + buf[m++] = uCG[jj]; + buf[m++] = uCGnew[jj]; + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +template +void FixEOStableRXKokkos::unpack_forward_comm(int n, int first, double *buf) +{ + int ii,m,last; + uChem = atomKK->k_uChem.view(); + uCG = atomKK->k_uCG.view(); + uCGnew = atomKK->k_uCGnew.view(); + + m = 0; + last = first + n ; + for (ii = first; ii < last; ii++){ + uChem[ii] = buf[m++]; + uCG[ii] = buf[m++]; + uCGnew[ii] = buf[m++]; + } +} + +/* ---------------------------------------------------------------------- */ + +template +int FixEOStableRXKokkos::pack_reverse_comm(int n, int first, double *buf) +{ + int i,m,last; + uCG = atomKK->k_uCG.view(); + uCGnew = atomKK->k_uCGnew.view(); + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + buf[m++] = uCG[i]; + buf[m++] = uCGnew[i]; + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +template +void FixEOStableRXKokkos::unpack_reverse_comm(int n, int *list, double *buf) +{ + int i,j,m; + uCG = atomKK->k_uCG.view(); + uCGnew = atomKK->k_uCGnew.view(); + + m = 0; + for (i = 0; i < n; i++) { + j = list[i]; + + uCG[j] += buf[m++]; + uCGnew[j] += buf[m++]; + } +} + +/* ---------------------------------------------------------------------- */ + +namespace LAMMPS_NS { +template class FixEOStableRXKokkos; +#ifdef KOKKOS_HAVE_CUDA +template class FixEOStableRXKokkos; +#endif +} diff --git a/src/KOKKOS/fix_eos_table_rx_kokkos.h b/src/KOKKOS/fix_eos_table_rx_kokkos.h new file mode 100644 index 0000000000..9eccd67c54 --- /dev/null +++ b/src/KOKKOS/fix_eos_table_rx_kokkos.h @@ -0,0 +1,152 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef FIX_CLASS + +FixStyle(eos/table/rx/kk,FixEOStableRXKokkos) +FixStyle(eos/table/rx/kk/device,FixEOStableRXKokkos) +FixStyle(eos/table/rx/kk/host,FixEOStableRXKokkos) + +#else + +#ifndef LMP_FIX_EOS_TABLE_RX_KOKKOS_H +#define LMP_FIX_EOS_TABLE_RX_KOKKOS_H + +#include "fix_eos_table_rx.h" +#include "kokkos_type.h" + +namespace LAMMPS_NS { + +template +class FixEOStableRXKokkos : public FixEOStableRX { + public: + typedef DeviceType device_type; + typedef ArrayTypes AT; + typedef EV_FLOAT value_type; + + FixEOStableRXKokkos(class LAMMPS *, int, char **); + virtual ~FixEOStableRXKokkos(); + void setup(int); + void init(); + void post_integrate(); + void end_of_step(); + + KOKKOS_INLINE_FUNCTION + void energy_lookup(int, double, double &) const; + + KOKKOS_INLINE_FUNCTION + void temperature_lookup(int, double, double &) const; + + protected: + //struct Table { + // int ninput; + // double lo,hi; + // double *rfile,*efile; + // double *e2file; + // double delta,invdelta,deltasq6; + // double *r,*e,*de,*e2; + //}; + //Table *tables, *tables2; + + void allocate(); + + //double *dHf; + + typename AT::t_int_1d mask; + typename AT::t_efloat_1d uCond,uMech,uChem,uCG,uCGnew,rho,dpdTheta,duChem; + + int pack_reverse_comm(int, int, double *); + void unpack_reverse_comm(int, int *, double *); + int pack_forward_comm(int , int *, double *, int, int *); + void unpack_forward_comm(int , int , double *); + + //int *eosSpecies; + }; +} + +#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: FixEOStableRXKokkos requires a fix rx command. + +The fix rx command must come before the pair style command in the input file + +E: There are no rx species specified + +There must be at least one species specified through the fix rx command + +E: Invalid eos/table/rx length + +The eos/table/rx table must have more than one entry. + +E: eos/table/rx values are not increasing + +The equation-of-state must an increasing function + +E: Internal temperature <= zero. + +Self-explanatory. + +E: Cannot open eos table/rx potential file %s + +Self-explanatory. + +E: Incorrect format in eos table/rx file + +Self-explanatory. + +E: Cannot open file %s + +Self-explanatory. + +E: Did not find keyword in table file + +Self-explanatory. + +E: Illegal fix eos/table/rx command + +Incorrect number of arguments specified for the fix eos/table/rx command. + +E: Invalid keyword in fix eos/table/rx parameters + +Self-explanatory. + +E: The number of columns in fix eos/table/rx does not match the number of species. + +Self-explanatory. Check format for fix eos/table/rx file. + +E: fix eos/table/rx parameters did not set N + +The number of table entries was not set in the eos/table/rx file + +W: Secant solver did not converge because table bounds were exceeded + +The secant solver failed to converge, resulting in the lower or upper table bound temperature to be returned + +E: NaN detected in secant solver. + +Self-explanatory. + +E: Maxit exceeded in secant solver + +The maximum number of interations was exceeded in the secant solver + +*/ diff --git a/src/KOKKOS/pair_exp6_rx_kokkos.cpp b/src/KOKKOS/pair_exp6_rx_kokkos.cpp index 754fa4667d..a7d5569537 100644 --- a/src/KOKKOS/pair_exp6_rx_kokkos.cpp +++ b/src/KOKKOS/pair_exp6_rx_kokkos.cpp @@ -31,6 +31,8 @@ #include "modify.h" #include "fix.h" #include +#include "atom_masks.h" +#include "neigh_request.h" using namespace LAMMPS_NS; using namespace MathConst; @@ -50,7 +52,10 @@ using namespace MathSpecial; template PairExp6rxKokkos::PairExp6rxKokkos(LAMMPS *lmp) : PairExp6rx(lmp) { - + atomKK = (AtomKokkos *) atom; + execution_space = ExecutionSpaceFromDevice::space; + datamask_read = X_MASK | F_MASK | TYPE_MASK | ENERGY_MASK | VIRIAL_MASK; + datamask_modify = F_MASK | ENERGY_MASK | VIRIAL_MASK; } /* ---------------------------------------------------------------------- */ @@ -63,6 +68,39 @@ PairExp6rxKokkos::~PairExp6rxKokkos() /* ---------------------------------------------------------------------- */ +template +void PairExp6rxKokkos::init_style() +{ + PairExp6rxKokkos::init_style(); + + // irequest = neigh request made by parent class + + neighflag = lmp->kokkos->neighflag; + int irequest = neighbor->nrequest - 1; + + neighbor->requests[irequest]-> + kokkos_host = Kokkos::Impl::is_same::value && + !Kokkos::Impl::is_same::value; + neighbor->requests[irequest]-> + kokkos_device = Kokkos::Impl::is_same::value; + + if (neighflag == FULL) { + neighbor->requests[irequest]->full = 1; + neighbor->requests[irequest]->half = 0; + neighbor->requests[irequest]->full_cluster = 0; + neighbor->requests[irequest]->ghost = 1; + } else if (neighflag == HALF || neighflag == HALFTHREAD) { + neighbor->requests[irequest]->full = 0; + neighbor->requests[irequest]->half = 1; + neighbor->requests[irequest]->full_cluster = 0; + neighbor->requests[irequest]->ghost = 1; + } else { + error->all(FLERR,"Cannot use chosen neighbor list style with reax/c/kk"); + } +} + +/* ---------------------------------------------------------------------- */ + template void PairExp6rxKokkos::compute(int eflag_in, int vflag_in) { @@ -270,14 +308,14 @@ void PairExp6rxKokkos::operator()(TagPairExp6rxCompute KOKKOS_INLINE_FUNCTION @@ -73,9 +77,6 @@ class PairExp6rxKokkos : public PairExp6rx { KOKKOS_INLINE_FUNCTION void operator()(TagPairExp6rxCompute, const int&) const; - KOKKOS_INLINE_FUNCTION - void operator()(TagPairExp6rxgetParamsEXP6, const int&) const; - template KOKKOS_INLINE_FUNCTION void ev_tally(EV_FLOAT &ev, const int &i, const int &j, diff --git a/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp b/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp new file mode 100644 index 0000000000..de70ae86f5 --- /dev/null +++ b/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp @@ -0,0 +1,791 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------------------------- + Contributing authors: + Stan Moore (Sandia) + + Please cite the related publications: + J.D. Moore, B.C. Barnes, S. Izvekov, M. Lisal, M.S. Sellers, D.E. Taylor & J.K. Brennan + "A coarse-grain force field for RDX: Density dependent and energy conserving" + The Journal of Chemical Physics, 2016, 144, 104501. +------------------------------------------------------------------------------------------- */ + +#include +#include +#include "math_const.h" +#include +#include +#include "pair_multi_lucy_rx_kokkos.h" +#include "atom_kokkos.h" +#include "force.h" +#include "comm.h" +#include "neigh_list.h" +#include "memory.h" +#include "error.h" +#include "citeme.h" +#include "modify.h" +#include "fix.h" +#include "atom_masks.h" +#include "neigh_request.h" + +using namespace LAMMPS_NS; + +enum{NONE,RLINEAR,RSQ}; + +#define MAXLINE 1024 + +#define oneFluidParameter (-1) +#define isOneFluid(_site) ( (_site) == oneFluidParameter ) + +static const char cite_pair_multi_lucy_rx[] = + "pair_style multi/lucy/rx command:\n\n" + "@Article{Moore16,\n" + " author = {J.D. Moore, B.C. Barnes, S. Izvekov, M. Lisal, M.S. Sellers, D.E. Taylor and J. K. Brennan},\n" + " title = {A coarse-grain force field for RDX: Density dependent and energy conserving},\n" + " journal = {J. Chem. Phys.},\n" + " year = 2016,\n" + " volume = 144\n" + " pages = {104501}\n" + "}\n\n"; + +/* ---------------------------------------------------------------------- */ + +template +PairMultiLucyRXKokkos::PairMultiLucyRXKokkos(LAMMPS *lmp) : PairMultiLucyRX(lmp) +{ + respa_enable = 0; + + atomKK = (AtomKokkos *) atom; + execution_space = ExecutionSpaceFromDevice::space; + datamask_read = X_MASK | F_MASK | TYPE_MASK | ENERGY_MASK | VIRIAL_MASK; + datamask_modify = F_MASK | ENERGY_MASK | VIRIAL_MASK; +} + +/* ---------------------------------------------------------------------- */ + +template +PairMultiLucyRXKokkos::~PairMultiLucyRXKokkos() +{ + +} + +/* ---------------------------------------------------------------------- */ + +template +void PairMultiLucyRXKokkos::init_style() +{ + PairMultiLucyRX::init_style(); + + // irequest = neigh request made by parent class + + neighflag = lmp->kokkos->neighflag; + int irequest = neighbor->nrequest - 1; + + neighbor->requests[irequest]-> + kokkos_host = Kokkos::Impl::is_same::value && + !Kokkos::Impl::is_same::value; + neighbor->requests[irequest]-> + kokkos_device = Kokkos::Impl::is_same::value; + + if (neighflag == FULL) { + neighbor->requests[irequest]->full = 1; + neighbor->requests[irequest]->half = 0; + neighbor->requests[irequest]->full_cluster = 0; + neighbor->requests[irequest]->ghost = 1; + } else if (neighflag == HALF || neighflag == HALFTHREAD) { + neighbor->requests[irequest]->full = 0; + neighbor->requests[irequest]->half = 1; + neighbor->requests[irequest]->full_cluster = 0; + neighbor->requests[irequest]->ghost = 1; + } else { + error->all(FLERR,"Cannot use chosen neighbor list style with reax/c/kk"); + } +} + +/* ---------------------------------------------------------------------- */ + +template +void PairMultiLucyRXKokkos::compute(int eflag_in, int vflag_in) +{ + eflag = eflag_in; + vflag = vflag_in; + + double evdwl,evdwlOld; + + evdwlOld = 0.0; + evdwl = 0.0; + if (neighflag == FULL) no_virial_fdotr_compute = 1; + if (eflag || vflag) ev_setup(eflag,vflag); + else evflag = vflag_fdotr = 0; + + // reallocate per-atom arrays if necessary + + if (eflag_atom) { + memory->destroy_kokkos(k_eatom,eatom); + memory->create_kokkos(k_eatom,eatom,maxeatom,"pair:eatom"); + d_eatom = k_eatom.d_view; + } + if (vflag_atom) { + memory->destroy_kokkos(k_vatom,vatom); + memory->create_kokkos(k_vatom,vatom,maxvatom,6,"pair:vatom"); + d_vatom = k_vatom.d_view; + } + + x = atomKK->k_x.view(); + f = atomKK->k_f.view(); + type = atomKK->k_type.view(); + uCG = atomKK->k_uCG.view(); + uCGnew = atomKK->k_uCGnew.view(); + dvector = atomKK->k_dvector.view(); + rho = atomKK->k_rho.view(); + + nlocal = atom->nlocal; + int nghost = atom->nghost; + int newton_pair = force->newton_pair; + + { + const int ntotal = nlocal + nghost; + d_fractionOld1 = typename AT::t_float_1d("PairMultiLucyRX::fractionOld1",ntotal); + d_fractionOld2 = typename AT::t_float_1d("PairMultiLucyRX::fractionOld2",ntotal); + d_fraction1 = typename AT::t_float_1d("PairMultiLucyRX::fraction1",ntotal); + d_fraction2 = typename AT::t_float_1d("PairMultiLucyRX::fraction2",ntotal); + + Kokkos::parallel_for(Kokkos::RangePolicy(0,ntotal),*this); + } + + const int inum = list->inum; + NeighListKokkos* k_list = static_cast*>(list); + d_numneigh = k_list->d_numneigh; + d_neighbors = k_list->d_neighbors; + d_ilist = k_list->d_ilist; + + computeLocalDensity(); + + // loop over neighbors of my atoms + + EV_FLOAT ev; + + if (evflag) { + Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + } else { + Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } + + if (eflag_global) eng_vdwl += ev.evdwl; + if (vflag_global) { + virial[0] += ev.v[0]; + virial[1] += ev.v[1]; + virial[2] += ev.v[2]; + virial[3] += ev.v[3]; + virial[4] += ev.v[4]; + virial[5] += ev.v[5]; + } + + if (vflag_fdotr) pair_virial_fdotr_compute(this); + + if (eflag_atom) { + k_eatom.template modify(); + k_eatom.template sync(); + } + + if (vflag_atom) { + k_vatom.template modify(); + k_vatom.template sync(); + } + + copymode = 0; +} + +template +KOKKOS_INLINE_FUNCTION +void PairMultiLucyRXKokkos::operator()(TagPairMultiLucyRXgetParams, const int &i) const { + getParams(i, d_fractionOld1[i], d_fractionOld2[i], d_fraction1[i], d_fraction2[i]); +} + +template +template +KOKKOS_INLINE_FUNCTION +void PairMultiLucyRXKokkos::operator()(TagPairMultiLucyRXCompute, const int &ii, EV_FLOAT& ev) const { + int i,j,jj,inum,jnum,itype,jtype,itable; + double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,evdwlOld,fpair; + double rsq; + + double fractionOld1_i,fractionOld1_j; + double fractionOld2_i,fractionOld2_j; + double fraction1_i; + + double pi = MathConst::MY_PI; + double A_i, A_j; + double fraction_i,fraction_j; + int jtable; + + Table *tb; + + int tlm1 = tablength - 1; + + i = d_ilist[ii]; + xtmp = x(i,0); + ytmp = x(i,1); + ztmp = x(i,2); + itype = type[i]; + jnum = d_numneigh[i]; + + double fx_i = 0.0; + double fy_i = 0.0; + double fz_i = 0.0; + + fractionOld1_i = d_fractionOld1[i]; + fractionOld2_i = d_fractionOld2[i]; + fraction1_i = d_fraction1[i]; + + for (jj = 0; jj < jnum; jj++) { + int j = d_neighbors(i,jj); + j &= NEIGHMASK; + + delx = xtmp - x(j,0); + dely = ytmp - x(j,1); + delz = ztmp - x(j,2); + rsq = delx*delx + dely*dely + delz*delz; + jtype = type[j]; + + if (rsq < d_cutsq(itype,jtype)) { // optimize + fpair = 0.0; + + fractionOld1_j = d_fractionOld1[j]; + fractionOld2_j = d_fractionOld2[j]; + + tb = &tables[tabindex[itype][jtype]]; + if (rho[i]*rho[i] < tb->innersq || rho[j]*rho[j] < tb->innersq){ + //printf("Table inner cutoff = %lf\n",sqrt(tb->innersq)); + //printf("rho[%d]=%lf\n",i,rho[i]); + //printf("rho[%d]=%lf\n",j,rho[j]); + error->one(FLERR,"Density < table inner cutoff"); + } + if (tabstyle == LOOKUP) { + itable = static_cast (((rho[i]*rho[i]) - tb->innersq) * tb->invdelta); + jtable = static_cast (((rho[j]*rho[j]) - tb->innersq) * tb->invdelta); + if (itable >= tlm1 || jtable >= tlm1){ + //printf("Table outer index = %d\n",tlm1); + //printf("itableIndex=%d rho[%d]=%lf\n",itable,i,rho[i]); + //printf("jtableIndex=%d rho[%d]=%lf\n",jtable,j,rho[j]); + error->one(FLERR,"Density > table outer cutoff"); + } + A_i = tb->f[itable]; + A_j = tb->f[jtable]; + + const double rfactor = 1.0-sqrt(rsq/d_cutsq(itype,jtype)); + fpair = 0.5*(A_i + A_j)*(4.0-3.0*rfactor)*rfactor*rfactor*rfactor; + fpair /= sqrt(rsq); + + } else if (tabstyle == LINEAR) { + itable = static_cast ((rho[i]*rho[i] - tb->innersq) * tb->invdelta); + jtable = static_cast (((rho[j]*rho[j]) - tb->innersq) * tb->invdelta); + if (itable >= tlm1 || jtable >= tlm1){ + //printf("Table outer index = %d\n",tlm1); + //printf("itableIndex=%d rho[%d]=%lf\n",itable,i,rho[i]); + //printf("jtableIndex=%d rho[%d]=%lf\n",jtable,j,rho[j]); + error->one(FLERR,"Density > table outer cutoff"); + } + if(itable<0) itable=0; + if(itable>=tlm1) itable=tlm1; + if(jtable<0) jtable=0; + if(jtable>=tlm1)jtable=tlm1; + + fraction_i = (((rho[i]*rho[i]) - tb->rsq[itable]) * tb->invdelta); + fraction_j = (((rho[j]*rho[j]) - tb->rsq[jtable]) * tb->invdelta); + if(itable==0) fraction_i=0.0; + if(itable==tlm1) fraction_i=0.0; + if(jtable==0) fraction_j=0.0; + if(jtable==tlm1) fraction_j=0.0; + + A_i = tb->f[itable] + fraction_i*tb->df[itable]; + A_j = tb->f[jtable] + fraction_j*tb->df[jtable]; + + const double rfactor = 1.0-sqrt(rsq/d_cutsq(itype,jtype)); + fpair = 0.5*(A_i + A_j)*(4.0-3.0*rfactor)*rfactor*rfactor*rfactor; + fpair /= sqrt(rsq); + + } else error->one(FLERR,"Only LOOKUP and LINEAR table styles have been implemented for pair multi/lucy/rx"); + + if (isite1 == isite2) fpair = sqrt(fractionOld1_i*fractionOld2_j)*fpair; + else fpair = (sqrt(fractionOld1_i*fractionOld2_j) + sqrt(fractionOld2_i*fractionOld1_j))*fpair; + + fx_i += delx*fpair; + fy_i += dely*fpair; + fz_i += delz*fpair; + if (NEWTON_PAIR || j < nlocal) { + f(j,0) -= delx*fpair; + f(j,1) -= dely*fpair; + f(j,2) -= delz*fpair; + } + //if (evflag) ev_tally(i,j,nlocal,newton_pair,0.0,0.0,fpair,delx,dely,delz); + if (EVFLAG) this->template ev_tally(ev,i,j,0.0,fpair,delx,dely,delz); + } + } + + f(i,0) += fx_i; + f(i,1) += fy_i; + f(i,2) += fz_i; + + tb = &tables[tabindex[itype][itype]]; + itable = static_cast (((rho[i]*rho[i]) - tb->innersq) * tb->invdelta); + if (tabstyle == LOOKUP) evdwl = tb->e[itable]; + else if (tabstyle == LINEAR){ + if (itable >= tlm1){ + //printf("itableIndex=%d rho[%d]=%lf\n",itable,i,rho[i]); + error->one(FLERR,"Density > table outer cutoff"); + } + if(itable==0) fraction_i=0.0; + else fraction_i = (((rho[i]*rho[i]) - tb->rsq[itable]) * tb->invdelta); + evdwl = tb->e[itable] + fraction_i*tb->de[itable]; + } else error->one(FLERR,"Only LOOKUP and LINEAR table styles have been implemented for pair multi/lucy/rx"); + + evdwl *=(pi*d_cutsq(itype,itype)*d_cutsq(itype,itype))/84.0; + evdwlOld = fractionOld1_i*evdwl; + evdwl = fraction1_i*evdwl; + + uCG[i] += evdwlOld; + uCGnew[i] += evdwl; + + evdwl = evdwlOld; + + //if (evflag) ev_tally(0,0,nlocal,newton_pair,evdwl,0.0,0.0,0.0,0.0,0.0); + if (EVFLAG) ev.evdwl += evdwl; +} + +template +template +KOKKOS_INLINE_FUNCTION +void PairMultiLucyRXKokkos::operator()(TagPairMultiLucyRXCompute, const int &ii) const { + EV_FLOAT ev; + this->template operator()(TagPairMultiLucyRXCompute(), ii, ev); +} + +/* ---------------------------------------------------------------------- + set coeffs for one or more type pairs +------------------------------------------------------------------------- */ + +template +void PairMultiLucyRXKokkos::coeff(int narg, char **arg) +{ + if (narg != 6 && narg != 7) error->all(FLERR,"Illegal pair_coeff command"); + + bool rx_flag = false; + for (int i = 0; i < modify->nfix; i++) + if (strncmp(modify->fix[i]->style,"rx",2) == 0) rx_flag = true; + if (!rx_flag) error->all(FLERR,"PairMultiLucyRXKokkos requires a fix rx command."); + + if (!allocated) allocate(); + + int ilo,ihi,jlo,jhi; + force->bounds(FLERR,arg[0],atom->ntypes,ilo,ihi); + force->bounds(FLERR,arg[1],atom->ntypes,jlo,jhi); + + int me; + MPI_Comm_rank(world,&me); + tables = (Table *) + memory->srealloc(tables,(ntables+1)*sizeof(Table),"pair:tables"); + Table *tb = &tables[ntables]; + null_table(tb); + if (me == 0) read_table(tb,arg[2],arg[3]); + bcast_table(tb); + + nspecies = atom->nspecies_dpd; + int n; + n = strlen(arg[3]) + 1; + site1 = new char[n]; + strcpy(site1,arg[4]); + + n = strlen(arg[4]) + 1; + site2 = new char[n]; + strcpy(site2,arg[5]); + + // set table cutoff + + if (narg == 7) tb->cut = force->numeric(FLERR,arg[6]); + else if (tb->rflag) tb->cut = tb->rhi; + else tb->cut = tb->rfile[tb->ninput-1]; + + // error check on table parameters + // insure cutoff is within table + + if (tb->ninput <= 1) error->one(FLERR,"Invalid pair table length"); + if (tb->rflag == 0) { + rho_0 = tb->rfile[0]; + } else { + rho_0 = tb->rlo; + } + + tb->match = 0; + if (tabstyle == LINEAR && tb->ninput == tablength && + tb->rflag == RSQ) tb->match = 1; + + // spline read-in values and compute r,e,f vectors within table + + if (tb->match == 0) spline_table(tb); + compute_table(tb); + + // store ptr to table in tabindex + + int count = 0; + for (int i = ilo; i <= ihi; i++) { + for (int j = MAX(jlo,i); j <= jhi; j++) { + tabindex[i][j] = ntables; + setflag[i][j] = 1; + count++; + } + } + + if (count == 0) error->all(FLERR,"Illegal pair_coeff command"); + ntables++; + + // Match site* to isite values. + + if (strcmp(site1, "1fluid") == 0) + isite1 = oneFluidParameter; + else { + isite1 = nspecies; + for (int ispecies = 0; ispecies < nspecies; ++ispecies) + if (strcmp(site1, atom->dname[ispecies]) == 0){ + isite1 = ispecies; + break; + } + + if (isite1 == nspecies) + error->all(FLERR,"Pair_multi_lucy_rx site1 is invalid."); + } + + if (strcmp(site2, "1fluid") == 0) + isite2 = oneFluidParameter; + else { + isite2 = nspecies; + for (int ispecies = 0; ispecies < nspecies; ++ispecies) + if (strcmp(site2, atom->dname[ispecies]) == 0){ + isite2 = ispecies; + break; + } + + if (isite2 == nspecies) + error->all(FLERR,"Pair_multi_lucy_rx site2 is invalid."); + } + +} + +/* ---------------------------------------------------------------------- */ + +template +void PairMultiLucyRXKokkos::computeLocalDensity() +{ + x = atomKK->k_x.view(); + type = atomKK->k_type.view(); + rho = atomKK->k_rho.view(); + nlocal = atom->nlocal; + + //sync + + const int inum = list->inum; + NeighListKokkos* k_list = static_cast*>(list); + d_numneigh = k_list->d_numneigh; + d_neighbors = k_list->d_neighbors; + d_ilist = k_list->d_ilist; + + const double pi = MathConst::MY_PI; + + const bool newton_pair = force->newton_pair; + one_type = (atom->ntypes == 1); + + // Special cut-off values for when there's only one type. + cutsq_type11 = cutsq[1][1]; + rcut_type11 = sqrt(cutsq_type11); + factor_type11 = 84.0/(5.0*pi*rcut_type11*rcut_type11*rcut_type11); + + // zero out density + int m = nlocal; + if (newton_pair) m += atom->nghost; + Kokkos::parallel_for(Kokkos::RangePolicy(0,m),*this); + +// rho = density at each atom +// loop over neighbors of my atoms + if (newton_pair) + Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + else + Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + + if (newton_pair) comm->reverse_comm_pair(this); + + comm->forward_comm_pair(this); +} + +template +KOKKOS_INLINE_FUNCTION +void PairMultiLucyRXKokkos::operator()(TagPairMultiLucyRXZero, const int &i) const { + rho[i] = 0.0; +} + +template +template +KOKKOS_INLINE_FUNCTION +void PairMultiLucyRXKokkos::operator()(TagPairMultiLucyRXComputeLocalDensity, const int &ii) const { + const int i = d_ilist[ii]; + + const double xtmp = x(i,0); + const double ytmp = x(i,1); + const double ztmp = x(i,2); + + double rho_i = rho[i]; + + const int itype = type[i]; + const int jnum = d_numneigh[i]; + + const double pi = MathConst::MY_PI; + + for (int jj = 0; jj < jnum; jj++){ + const int j = (d_neighbors(i,jj) & NEIGHMASK); + const int jtype = type[j]; + + const double delx = xtmp - x(j,0); + const double dely = ytmp - x(j,1); + const double delz = ztmp - x(j,2); + const double rsq = delx*delx + dely*dely + delz*delz; + + if (one_type) { + if (rsq < cutsq_type11) { + const double rcut = rcut_type11; + const double r_over_rcut = sqrt(rsq) / rcut; + const double tmpFactor = 1.0 - r_over_rcut; + const double tmpFactor4 = tmpFactor*tmpFactor*tmpFactor*tmpFactor; + const double factor = factor_type11*(1.0 + 1.5*r_over_rcut)*tmpFactor4; + rho_i += factor; + if (NEWTON_PAIR || j < nlocal) + rho[j] += factor; + } else if (rsq < d_cutsq(itype,jtype)) { + const double rcut = sqrt(d_cutsq(itype,jtype)); + const double tmpFactor = 1.0-sqrt(rsq)/rcut; + const double tmpFactor4 = tmpFactor*tmpFactor*tmpFactor*tmpFactor; + const double factor = (84.0/(5.0*pi*rcut*rcut*rcut))*(1.0+3.0*sqrt(rsq)/(2.0*rcut))*tmpFactor4; + rho_i += factor; + if (NEWTON_PAIR || j < nlocal) + rho[j] += factor; + } + } + } + + rho[i] = rho_i; +} + +/* ---------------------------------------------------------------------- */ + +template +KOKKOS_INLINE_FUNCTION +void PairMultiLucyRXKokkos::getParams(int id, double &fractionOld1, double &fractionOld2, double &fraction1, double &fraction2) const +{ + double fractionOld, fraction; + double nTotal, nTotalOld; + + nTotal = 0.0; + nTotalOld = 0.0; + for (int ispecies = 0; ispecies < nspecies; ispecies++){ + nTotal += dvector(ispecies,id); + nTotalOld += dvector(ispecies+nspecies,id); + } + + if (isOneFluid(isite1) == false){ + fractionOld1 = dvector(isite1+nspecies,id)/nTotalOld; + fraction1 = dvector(isite1,id)/nTotal; + } + if (isOneFluid(isite2) == false){ + fractionOld2 = dvector(isite2+nspecies,id)/nTotalOld; + fraction2 = dvector(isite2,id)/nTotal; + } + + if (isOneFluid(isite1) || isOneFluid(isite2)){ + fractionOld = 0.0; + fraction = 0.0; + + for (int ispecies = 0; ispecies < nspecies; ispecies++){ + if (isite1 == ispecies || isite2 == ispecies) continue; + fractionOld += dvector(ispecies+nspecies,id) / nTotalOld; + fraction += dvector(ispecies,id) / nTotal; + } + if (isOneFluid(isite1)){ + fractionOld1 = fractionOld; + fraction1 = fraction; + } + if (isOneFluid(isite2)){ + fractionOld2 = fractionOld; + fraction2 = fraction; + } + } +} + +/* ---------------------------------------------------------------------- */ + +template +int PairMultiLucyRXKokkos::pack_forward_comm(int n, int *list, double *buf, int pbc_flag, int *pbc) +{ + int i,j,m; + rho = atomKK->k_rho.view(); + + m = 0; + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = rho[j]; + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +template +void PairMultiLucyRXKokkos::unpack_forward_comm(int n, int first, double *buf) +{ + int i,m,last; + rho = atomKK->k_rho.view(); + + m = 0; + last = first + n; + for (i = first; i < last; i++) rho[i] = buf[m++]; +} + +/* ---------------------------------------------------------------------- */ + +template +int PairMultiLucyRXKokkos::pack_reverse_comm(int n, int first, double *buf) +{ + int i,m,last; + rho = atomKK->k_rho.view(); + + m = 0; + last = first + n; + for (i = first; i < last; i++) buf[m++] = rho[i]; + return m; +} + +/* ---------------------------------------------------------------------- */ + +template +void PairMultiLucyRXKokkos::unpack_reverse_comm(int n, int *list, double *buf) +{ + int i,j,m; + rho = atomKK->k_rho.view(); + + m = 0; + for (i = 0; i < n; i++) { + j = list[i]; + rho[j] += buf[m++]; + } +} + +/* ---------------------------------------------------------------------- */ + +template +template +KOKKOS_INLINE_FUNCTION +void PairMultiLucyRXKokkos::ev_tally(EV_FLOAT &ev, const int &i, const int &j, + const F_FLOAT &epair, const F_FLOAT &fpair, const F_FLOAT &delx, + const F_FLOAT &dely, const F_FLOAT &delz) const +{ + const int EFLAG = eflag; + const int VFLAG = vflag_either; + + // The eatom and vatom arrays are atomic for Half/Thread neighbor style + Kokkos::View::value> > v_eatom = k_eatom.view(); + Kokkos::View::value> > v_vatom = k_vatom.view(); + + if (EFLAG) { + if (eflag_atom) { + const E_FLOAT epairhalf = 0.5 * epair; + if (NEIGHFLAG!=FULL) { + if (NEWTON_PAIR || i < nlocal) v_eatom[i] += epairhalf; + if (NEWTON_PAIR || j < nlocal) v_eatom[j] += epairhalf; + } else { + v_eatom[i] += epairhalf; + } + } + } + + if (VFLAG) { + const E_FLOAT v0 = delx*delx*fpair; + const E_FLOAT v1 = dely*dely*fpair; + const E_FLOAT v2 = delz*delz*fpair; + const E_FLOAT v3 = delx*dely*fpair; + const E_FLOAT v4 = delx*delz*fpair; + const E_FLOAT v5 = dely*delz*fpair; + + if (vflag_global) { + if (NEIGHFLAG!=FULL) { + if (NEWTON_PAIR || i < nlocal) { + ev.v[0] += 0.5*v0; + ev.v[1] += 0.5*v1; + ev.v[2] += 0.5*v2; + ev.v[3] += 0.5*v3; + ev.v[4] += 0.5*v4; + ev.v[5] += 0.5*v5; + } + if (NEWTON_PAIR || j < nlocal) { + ev.v[0] += 0.5*v0; + ev.v[1] += 0.5*v1; + ev.v[2] += 0.5*v2; + ev.v[3] += 0.5*v3; + ev.v[4] += 0.5*v4; + ev.v[5] += 0.5*v5; + } + } else { + ev.v[0] += 0.5*v0; + ev.v[1] += 0.5*v1; + ev.v[2] += 0.5*v2; + ev.v[3] += 0.5*v3; + ev.v[4] += 0.5*v4; + ev.v[5] += 0.5*v5; + } + } + + if (vflag_atom) { + if (NEIGHFLAG!=FULL) { + if (NEWTON_PAIR || i < nlocal) { + v_vatom(i,0) += 0.5*v0; + v_vatom(i,1) += 0.5*v1; + v_vatom(i,2) += 0.5*v2; + v_vatom(i,3) += 0.5*v3; + v_vatom(i,4) += 0.5*v4; + v_vatom(i,5) += 0.5*v5; + } + if (NEWTON_PAIR || j < nlocal) { + v_vatom(j,0) += 0.5*v0; + v_vatom(j,1) += 0.5*v1; + v_vatom(j,2) += 0.5*v2; + v_vatom(j,3) += 0.5*v3; + v_vatom(j,4) += 0.5*v4; + v_vatom(j,5) += 0.5*v5; + } + } else { + v_vatom(i,0) += 0.5*v0; + v_vatom(i,1) += 0.5*v1; + v_vatom(i,2) += 0.5*v2; + v_vatom(i,3) += 0.5*v3; + v_vatom(i,4) += 0.5*v4; + v_vatom(i,5) += 0.5*v5; + } + } + } +} + +/* ---------------------------------------------------------------------- */ + +namespace LAMMPS_NS { +template class PairMultiLucyRXKokkos; +#ifdef KOKKOS_HAVE_CUDA +template class PairMultiLucyRXKokkos; +#endif +} diff --git a/src/KOKKOS/pair_multi_lucy_rx_kokkos.h b/src/KOKKOS/pair_multi_lucy_rx_kokkos.h new file mode 100644 index 0000000000..74a10ddee1 --- /dev/null +++ b/src/KOKKOS/pair_multi_lucy_rx_kokkos.h @@ -0,0 +1,215 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(multi/lucy/rx/kk,PairMultiLucyRXKokkos) +PairStyle(multi/lucy/rx/kk/device,PairMultiLucyRXKokkos) +PairStyle(multi/lucy/rx/kk/host,PairMultiLucyRXKokkos) + +#else + +#ifndef LMP_PAIR_MULTI_LUCY_RX_KOKKOS_H +#define LMP_PAIR_MULTI_LUCY_RX_KOKKOS_H + + +#include "pair_multi_lucy_rx.h" +#include "pair_kokkos.h" +#include "kokkos_type.h" + +namespace LAMMPS_NS { + +struct TagPairMultiLucyRXgetParams{}; + +template +struct TagPairMultiLucyRXCompute{}; + +struct TagPairMultiLucyRXZero{}; + +template +struct TagPairMultiLucyRXComputeLocalDensity{}; + +template +class PairMultiLucyRXKokkos : public PairMultiLucyRX { + public: + typedef DeviceType device_type; + typedef ArrayTypes AT; + typedef EV_FLOAT value_type; + + PairMultiLucyRXKokkos(class LAMMPS *); + virtual ~PairMultiLucyRXKokkos(); + + void compute(int, int); + void init_style(); + void coeff(int, char **); + int pack_forward_comm(int, int *, double *, int, int *); + void unpack_forward_comm(int, int, double *); + int pack_reverse_comm(int, int, double *); + void unpack_reverse_comm(int, int *, double *); + void computeLocalDensity(); + + KOKKOS_INLINE_FUNCTION + void operator()(TagPairMultiLucyRXgetParams, const int&) const; + + template + KOKKOS_INLINE_FUNCTION + void operator()(TagPairMultiLucyRXCompute, const int&, EV_FLOAT&) const; + + template + KOKKOS_INLINE_FUNCTION + void operator()(TagPairMultiLucyRXCompute, const int&) const; + + KOKKOS_INLINE_FUNCTION + void operator()(TagPairMultiLucyRXZero, const int&) const; + + template + KOKKOS_INLINE_FUNCTION + void operator()(TagPairMultiLucyRXComputeLocalDensity, const int&) const; + + template + KOKKOS_INLINE_FUNCTION + void ev_tally(EV_FLOAT &ev, const int &i, const int &j, + const F_FLOAT &epair, const F_FLOAT &fpair, const F_FLOAT &delx, + const F_FLOAT &dely, const F_FLOAT &delz) const; + + private: + int nlocal; + int neighflag; + int eflag,vflag; + + bool one_type; + double cutsq_type11; + double rcut_type11; + double factor_type11; + + //struct Table { + // int ninput,rflag,fpflag,match; + // double rlo,rhi,fplo,fphi,cut; + // double *rfile,*efile,*ffile; + // double *e2file,*f2file; + // double innersq,delta,invdelta,deltasq6; + // double *rsq,*drsq,*e,*de,*f,*df,*e2,*f2; + //}; + //Table *tables; + + int **tabindex; + + //void read_table(Table *, char *, char *); + //void param_extract(Table *, char *); + + char *site1, *site2; + + KOKKOS_INLINE_FUNCTION + void getParams(int, double &, double &, double &, double &) const; + + typename AT::t_float_1d d_fractionOld1,d_fractionOld2,d_fraction1,d_fraction2; + + typename AT::t_x_array_randomread x; + typename AT::t_f_array f; + typename AT::t_int_1d_randomread type; + typename AT::t_efloat_1d rho; + typename AT::t_efloat_1d uCG, uCGnew; + typename AT::t_float_2d dvector; + + DAT::tdual_efloat_1d k_eatom; + DAT::tdual_virial_array k_vatom; + DAT::t_efloat_1d d_eatom; + DAT::t_virial_array d_vatom; + + typename AT::t_neighbors_2d d_neighbors; + typename AT::t_int_1d_randomread d_ilist; + typename AT::t_int_1d_randomread d_numneigh; + + typename AT::tdual_ffloat_2d k_cutsq; + typename AT::t_ffloat_2d d_cutsq; + + friend void pair_virial_fdotr_compute(PairMultiLucyRXKokkos*); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +E: Pair multi/lucy/rx command requires atom_style with density (e.g. dpd, meso) + +Self-explanatory + +E: Density < table inner cutoff + +The local density inner is smaller than the inner cutoff + +E: Density > table inner cutoff + +The local density inner is greater than the inner cutoff + +E: Only LOOKUP and LINEAR table styles have been implemented for pair multi/lucy/rx + +Self-explanatory + +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: Unknown table style in pair_style command + +Self-explanatory + +E: Illegal number of pair table entries + +There must be at least 2 table entries. + +E: Illegal pair_coeff command + +All pair coefficients must be set in the data file or by the +pair_coeff command before running a simulation. + +E: PairMultiLucyRXKokkos requires a fix rx command + +The fix rx command must come before the pair style command in the input file + +E: There are no rx species specified + +There must be at least one species specified through the fix rx command + +E: Invalid pair table length + +Length of read-in pair table is invalid + +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. + +E: Cannot open file %s + +The specified file cannot be opened. Check that the path and name are +correct. + +E: Did not find keyword in table file + +Keyword used in pair_coeff command was not found in table file. + +E: Invalid keyword in pair table parameters + +Keyword used in list of table parameters is not recognized. + +E: Pair table parameters did not set N + +List of pair table parameters must include N setting. + +*/ diff --git a/src/KOKKOS/pair_table_kokkos.cpp b/src/KOKKOS/pair_table_kokkos.cpp index 278c5b0a2f..271490bbdd 100644 --- a/src/KOKKOS/pair_table_kokkos.cpp +++ b/src/KOKKOS/pair_table_kokkos.cpp @@ -12,7 +12,7 @@ ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- - Contributing author: Paul Crozier (SNL) + Contributing author: Christian Trott (SNL) ------------------------------------------------------------------------- */ #include @@ -41,7 +41,7 @@ enum{FULL,HALFTHREAD,HALF}; /* ---------------------------------------------------------------------- */ template -PairTableKokkos::PairTableKokkos(LAMMPS *lmp) : Pair(lmp) +PairTableKokkos::PairTableKokkos(LAMMPS *lmp) : PairTable(lmp) { update_table = 0; atomKK = (AtomKokkos *) atom; @@ -98,6 +98,7 @@ void PairTableKokkos::compute_style(int eflag_in, int vflag_in) if (neighflag == FULL || neighflag == FULLCLUSTER) no_virial_fdotr_compute = 1; + if (eflag || vflag) ev_setup(eflag,vflag); else evflag = vflag_fdotr = 0; @@ -221,6 +222,7 @@ compute_fpair(const F_FLOAT& rsq, const int& i, const int&j, const int& itype, c //if (rsq < d_table_const.innersq(tidx)) // error->one(FLERR,"Pair distance < table inner cutoff"); + if (Specialisation::TabStyle == LOOKUP) { const int itable = static_cast ((rsq - d_table_const.innersq(tidx)) * d_table_const.invdelta(tidx)); //if (itable >= tlm1) @@ -338,8 +340,6 @@ void PairTableKokkos::create_kokkos_tables() memory->create_kokkos(d_table->drsq,h_table->drsq,ntables,ntable,"Table::drsq"); } - - for(int i=0; i < ntables; i++) { Table* tb = &tables[i]; @@ -477,85 +477,6 @@ void PairTableKokkos::settings(int narg, char **arg) tables = NULL; } -/* ---------------------------------------------------------------------- - set coeffs for one or more type pairs -------------------------------------------------------------------------- */ - -template -void PairTableKokkos::coeff(int narg, char **arg) -{ - if (narg != 4 && narg != 5) error->all(FLERR,"Illegal pair_coeff command"); - if (!allocated) allocate(); - - int ilo,ihi,jlo,jhi; - force->bounds(FLERR,arg[0],atom->ntypes,ilo,ihi); - force->bounds(FLERR,arg[1],atom->ntypes,jlo,jhi); - - int me; - MPI_Comm_rank(world,&me); - tables = (Table *) - memory->srealloc(tables,(ntables+1)*sizeof(Table),"pair:tables"); - Table *tb = &tables[ntables]; - null_table(tb); - if (me == 0) read_table(tb,arg[2],arg[3]); - bcast_table(tb); - - // set table cutoff - - if (narg == 5) tb->cut = force->numeric(FLERR,arg[4]); - else if (tb->rflag) tb->cut = tb->rhi; - else tb->cut = tb->rfile[tb->ninput-1]; - - // error check on table parameters - // insure cutoff is within table - // for BITMAP tables, file values can be in non-ascending order - - if (tb->ninput <= 1) error->one(FLERR,"Invalid pair table length"); - double rlo,rhi; - if (tb->rflag == 0) { - rlo = tb->rfile[0]; - rhi = tb->rfile[tb->ninput-1]; - } else { - rlo = tb->rlo; - rhi = tb->rhi; - } - if (tb->cut <= rlo || tb->cut > rhi) - error->all(FLERR,"Invalid pair table cutoff"); - if (rlo <= 0.0) error->all(FLERR,"Invalid pair table cutoff"); - - // match = 1 if don't need to spline read-in tables - // this is only the case if r values needed by final tables - // exactly match r values read from file - // for tabstyle SPLINE, always need to build spline tables - - tb->match = 0; - if (tabstyle == LINEAR && tb->ninput == tablength && - tb->rflag == RSQ && tb->rhi == tb->cut) tb->match = 1; - if (tabstyle == BITMAP && tb->ninput == 1 << tablength && - tb->rflag == BMP && tb->rhi == tb->cut) tb->match = 1; - if (tb->rflag == BMP && tb->match == 0) - error->all(FLERR,"Bitmapped table in file does not match requested table"); - - // spline read-in values and compute r,e,f vectors within table - - if (tb->match == 0) spline_table(tb); - compute_table(tb); - - // store ptr to table in tabindex - - int count = 0; - for (int i = ilo; i <= ihi; i++) { - for (int j = MAX(jlo,i); j <= jhi; j++) { - tabindex[i][j] = ntables; - setflag[i][j] = 1; - count++; - } - } - - if (count == 0) error->all(FLERR,"Illegal pair_coeff command"); - ntables++; -} - /* ---------------------------------------------------------------------- init for one type pair i,j and corresponding j,i ------------------------------------------------------------------------- */ @@ -574,677 +495,6 @@ double PairTableKokkos::init_one(int i, int j) return tables[tabindex[i][j]].cut; } -/* ---------------------------------------------------------------------- - read a table section from a tabulated potential file - only called by proc 0 - this function sets these values in Table: - ninput,rfile,efile,ffile,rflag,rlo,rhi,fpflag,fplo,fphi,ntablebits -------------------------------------------------------------------------- */ - -template -void PairTableKokkos::read_table(Table *tb, char *file, char *keyword) -{ - char line[MAXLINE]; - - // open file - - FILE *fp = force->open_potential(file); - if (fp == NULL) { - char str[128]; - sprintf(str,"Cannot open file %s",file); - error->one(FLERR,str); - } - - // loop until section found with matching keyword - - while (1) { - if (fgets(line,MAXLINE,fp) == NULL) - error->one(FLERR,"Did not find keyword in table file"); - if (strspn(line," \t\n\r") == strlen(line)) continue; // blank line - if (line[0] == '#') continue; // comment - char *word = strtok(line," \t\n\r"); - if (strcmp(word,keyword) == 0) break; // matching keyword - fgets(line,MAXLINE,fp); // no match, skip section - param_extract(tb,line); - fgets(line,MAXLINE,fp); - for (int i = 0; i < tb->ninput; i++) fgets(line,MAXLINE,fp); - } - - // read args on 2nd line of section - // allocate table arrays for file values - - fgets(line,MAXLINE,fp); - param_extract(tb,line); - memory->create(tb->rfile,tb->ninput,"pair:rfile"); - memory->create(tb->efile,tb->ninput,"pair:efile"); - memory->create(tb->ffile,tb->ninput,"pair:ffile"); - - // setup bitmap parameters for table to read in - - tb->ntablebits = 0; - int masklo,maskhi,nmask,nshiftbits; - if (tb->rflag == BMP) { - while (1 << tb->ntablebits < tb->ninput) tb->ntablebits++; - if (1 << tb->ntablebits != tb->ninput) - error->one(FLERR,"Bitmapped table is incorrect length in table file"); - init_bitmap(tb->rlo,tb->rhi,tb->ntablebits,masklo,maskhi,nmask,nshiftbits); - } - - // read r,e,f table values from file - // if rflag set, compute r - // if rflag not set, use r from file - - int itmp; - double rtmp; - union_int_float_t rsq_lookup; - - fgets(line,MAXLINE,fp); - for (int i = 0; i < tb->ninput; i++) { - fgets(line,MAXLINE,fp); - sscanf(line,"%d %lg %lg %lg",&itmp,&rtmp,&tb->efile[i],&tb->ffile[i]); - - if (tb->rflag == RLINEAR) - rtmp = tb->rlo + (tb->rhi - tb->rlo)*i/(tb->ninput-1); - else if (tb->rflag == RSQ) { - rtmp = tb->rlo*tb->rlo + - (tb->rhi*tb->rhi - tb->rlo*tb->rlo)*i/(tb->ninput-1); - rtmp = sqrt(rtmp); - } else if (tb->rflag == BMP) { - rsq_lookup.i = i << nshiftbits; - rsq_lookup.i |= masklo; - if (rsq_lookup.f < tb->rlo*tb->rlo) { - rsq_lookup.i = i << nshiftbits; - rsq_lookup.i |= maskhi; - } - rtmp = sqrtf(rsq_lookup.f); - } - - tb->rfile[i] = rtmp; - } - - // close file - - fclose(fp); -} - -/* ---------------------------------------------------------------------- - broadcast read-in table info from proc 0 to other procs - this function communicates these values in Table: - ninput,rfile,efile,ffile,rflag,rlo,rhi,fpflag,fplo,fphi -------------------------------------------------------------------------- */ - -template -void PairTableKokkos::bcast_table(Table *tb) -{ - MPI_Bcast(&tb->ninput,1,MPI_INT,0,world); - - int me; - MPI_Comm_rank(world,&me); - if (me > 0) { - memory->create(tb->rfile,tb->ninput,"pair:rfile"); - memory->create(tb->efile,tb->ninput,"pair:efile"); - memory->create(tb->ffile,tb->ninput,"pair:ffile"); - } - - MPI_Bcast(tb->rfile,tb->ninput,MPI_DOUBLE,0,world); - MPI_Bcast(tb->efile,tb->ninput,MPI_DOUBLE,0,world); - MPI_Bcast(tb->ffile,tb->ninput,MPI_DOUBLE,0,world); - - MPI_Bcast(&tb->rflag,1,MPI_INT,0,world); - if (tb->rflag) { - MPI_Bcast(&tb->rlo,1,MPI_DOUBLE,0,world); - MPI_Bcast(&tb->rhi,1,MPI_DOUBLE,0,world); - } - MPI_Bcast(&tb->fpflag,1,MPI_INT,0,world); - if (tb->fpflag) { - MPI_Bcast(&tb->fplo,1,MPI_DOUBLE,0,world); - MPI_Bcast(&tb->fphi,1,MPI_DOUBLE,0,world); - } -} - -/* ---------------------------------------------------------------------- - build spline representation of e,f over entire range of read-in table - this function sets these values in Table: e2file,f2file -------------------------------------------------------------------------- */ - -template -void PairTableKokkos::spline_table(Table *tb) -{ - memory->create(tb->e2file,tb->ninput,"pair:e2file"); - memory->create(tb->f2file,tb->ninput,"pair:f2file"); - - double ep0 = - tb->ffile[0]; - double epn = - tb->ffile[tb->ninput-1]; - spline(tb->rfile,tb->efile,tb->ninput,ep0,epn,tb->e2file); - - if (tb->fpflag == 0) { - tb->fplo = (tb->ffile[1] - tb->ffile[0]) / (tb->rfile[1] - tb->rfile[0]); - tb->fphi = (tb->ffile[tb->ninput-1] - tb->ffile[tb->ninput-2]) / - (tb->rfile[tb->ninput-1] - tb->rfile[tb->ninput-2]); - } - - double fp0 = tb->fplo; - double fpn = tb->fphi; - spline(tb->rfile,tb->ffile,tb->ninput,fp0,fpn,tb->f2file); -} - -/* ---------------------------------------------------------------------- - extract attributes from parameter line in table section - format of line: N value R/RSQ/BITMAP lo hi FP fplo fphi - N is required, other params are optional -------------------------------------------------------------------------- */ - -template -void PairTableKokkos::param_extract(Table *tb, char *line) -{ - tb->ninput = 0; - tb->rflag = NONE; - tb->fpflag = 0; - - char *word = strtok(line," \t\n\r\f"); - while (word) { - if (strcmp(word,"N") == 0) { - word = strtok(NULL," \t\n\r\f"); - tb->ninput = atoi(word); - } else if (strcmp(word,"R") == 0 || strcmp(word,"RSQ") == 0 || - strcmp(word,"BITMAP") == 0) { - if (strcmp(word,"R") == 0) tb->rflag = RLINEAR; - else if (strcmp(word,"RSQ") == 0) tb->rflag = RSQ; - else if (strcmp(word,"BITMAP") == 0) tb->rflag = BMP; - word = strtok(NULL," \t\n\r\f"); - tb->rlo = atof(word); - word = strtok(NULL," \t\n\r\f"); - tb->rhi = atof(word); - } else if (strcmp(word,"FP") == 0) { - tb->fpflag = 1; - word = strtok(NULL," \t\n\r\f"); - tb->fplo = atof(word); - word = strtok(NULL," \t\n\r\f"); - tb->fphi = atof(word); - } else { - error->one(FLERR,"Invalid keyword in pair table parameters"); - } - word = strtok(NULL," \t\n\r\f"); - } - - if (tb->ninput == 0) error->one(FLERR,"Pair table parameters did not set N"); -} - -/* ---------------------------------------------------------------------- - compute r,e,f vectors from splined values -------------------------------------------------------------------------- */ - -template -void PairTableKokkos::compute_table(Table *tb) -{ - update_table = 1; - int tlm1 = tablength-1; - - // inner = inner table bound - // cut = outer table bound - // delta = table spacing in rsq for N-1 bins - - double inner; - if (tb->rflag) inner = tb->rlo; - else inner = tb->rfile[0]; - tb->innersq = inner*inner; - tb->delta = (tb->cut*tb->cut - tb->innersq) / tlm1; - tb->invdelta = 1.0/tb->delta; - - // direct lookup tables - // N-1 evenly spaced bins in rsq from inner to cut - // e,f = value at midpt of bin - // e,f are N-1 in length since store 1 value at bin midpt - // f is converted to f/r when stored in f[i] - // e,f are never a match to read-in values, always computed via spline interp - - if (tabstyle == LOOKUP) { - memory->create(tb->e,tlm1,"pair:e"); - memory->create(tb->f,tlm1,"pair:f"); - - double r,rsq; - for (int i = 0; i < tlm1; i++) { - rsq = tb->innersq + (i+0.5)*tb->delta; - r = sqrt(rsq); - tb->e[i] = splint(tb->rfile,tb->efile,tb->e2file,tb->ninput,r); - tb->f[i] = splint(tb->rfile,tb->ffile,tb->f2file,tb->ninput,r)/r; - } - } - - // linear tables - // N-1 evenly spaced bins in rsq from inner to cut - // rsq,e,f = value at lower edge of bin - // de,df values = delta from lower edge to upper edge of bin - // rsq,e,f are N in length so de,df arrays can compute difference - // f is converted to f/r when stored in f[i] - // e,f can match read-in values, else compute via spline interp - - if (tabstyle == LINEAR) { - memory->create(tb->rsq,tablength,"pair:rsq"); - memory->create(tb->e,tablength,"pair:e"); - memory->create(tb->f,tablength,"pair:f"); - memory->create(tb->de,tlm1,"pair:de"); - memory->create(tb->df,tlm1,"pair:df"); - - double r,rsq; - for (int i = 0; i < tablength; i++) { - rsq = tb->innersq + i*tb->delta; - r = sqrt(rsq); - tb->rsq[i] = rsq; - if (tb->match) { - tb->e[i] = tb->efile[i]; - tb->f[i] = tb->ffile[i]/r; - } else { - tb->e[i] = splint(tb->rfile,tb->efile,tb->e2file,tb->ninput,r); - tb->f[i] = splint(tb->rfile,tb->ffile,tb->f2file,tb->ninput,r)/r; - } - } - - for (int i = 0; i < tlm1; i++) { - tb->de[i] = tb->e[i+1] - tb->e[i]; - tb->df[i] = tb->f[i+1] - tb->f[i]; - } - } - - // cubic spline tables - // N-1 evenly spaced bins in rsq from inner to cut - // rsq,e,f = value at lower edge of bin - // e2,f2 = spline coefficient for each bin - // rsq,e,f,e2,f2 are N in length so have N-1 spline bins - // f is converted to f/r after e is splined - // e,f can match read-in values, else compute via spline interp - - if (tabstyle == SPLINE) { - memory->create(tb->rsq,tablength,"pair:rsq"); - memory->create(tb->e,tablength,"pair:e"); - memory->create(tb->f,tablength,"pair:f"); - memory->create(tb->e2,tablength,"pair:e2"); - memory->create(tb->f2,tablength,"pair:f2"); - - tb->deltasq6 = tb->delta*tb->delta / 6.0; - - double r,rsq; - for (int i = 0; i < tablength; i++) { - rsq = tb->innersq + i*tb->delta; - r = sqrt(rsq); - tb->rsq[i] = rsq; - if (tb->match) { - tb->e[i] = tb->efile[i]; - tb->f[i] = tb->ffile[i]/r; - } else { - tb->e[i] = splint(tb->rfile,tb->efile,tb->e2file,tb->ninput,r); - tb->f[i] = splint(tb->rfile,tb->ffile,tb->f2file,tb->ninput,r); - } - } - - // ep0,epn = dh/dg at inner and at cut - // h(r) = e(r) and g(r) = r^2 - // dh/dg = (de/dr) / 2r = -f/2r - - double ep0 = - tb->f[0] / (2.0 * sqrt(tb->innersq)); - double epn = - tb->f[tlm1] / (2.0 * tb->cut); - spline(tb->rsq,tb->e,tablength,ep0,epn,tb->e2); - - // fp0,fpn = dh/dg at inner and at cut - // h(r) = f(r)/r and g(r) = r^2 - // dh/dg = (1/r df/dr - f/r^2) / 2r - // dh/dg in secant approx = (f(r2)/r2 - f(r1)/r1) / (g(r2) - g(r1)) - - double fp0,fpn; - double secant_factor = 0.1; - if (tb->fpflag) fp0 = (tb->fplo/sqrt(tb->innersq) - tb->f[0]/tb->innersq) / - (2.0 * sqrt(tb->innersq)); - else { - double rsq1 = tb->innersq; - double rsq2 = rsq1 + secant_factor*tb->delta; - fp0 = (splint(tb->rfile,tb->ffile,tb->f2file,tb->ninput,sqrt(rsq2)) / - sqrt(rsq2) - tb->f[0] / sqrt(rsq1)) / (secant_factor*tb->delta); - } - - if (tb->fpflag && tb->cut == tb->rfile[tb->ninput-1]) fpn = - (tb->fphi/tb->cut - tb->f[tlm1]/(tb->cut*tb->cut)) / (2.0 * tb->cut); - else { - double rsq2 = tb->cut * tb->cut; - double rsq1 = rsq2 - secant_factor*tb->delta; - fpn = (tb->f[tlm1] / sqrt(rsq2) - - splint(tb->rfile,tb->ffile,tb->f2file,tb->ninput,sqrt(rsq1)) / - sqrt(rsq1)) / (secant_factor*tb->delta); - } - - for (int i = 0; i < tablength; i++) tb->f[i] /= sqrt(tb->rsq[i]); - spline(tb->rsq,tb->f,tablength,fp0,fpn,tb->f2); - } - - // bitmapped linear tables - // 2^N bins from inner to cut, spaced in bitmapped manner - // f is converted to f/r when stored in f[i] - // e,f can match read-in values, else compute via spline interp - - if (tabstyle == BITMAP) { - double r; - union_int_float_t rsq_lookup; - int masklo,maskhi; - - // linear lookup tables of length ntable = 2^n - // stored value = value at lower edge of bin - - init_bitmap(inner,tb->cut,tablength,masklo,maskhi,tb->nmask,tb->nshiftbits); - int ntable = 1 << tablength; - int ntablem1 = ntable - 1; - - memory->create(tb->rsq,ntable,"pair:rsq"); - memory->create(tb->e,ntable,"pair:e"); - memory->create(tb->f,ntable,"pair:f"); - memory->create(tb->de,ntable,"pair:de"); - memory->create(tb->df,ntable,"pair:df"); - memory->create(tb->drsq,ntable,"pair:drsq"); - - union_int_float_t minrsq_lookup; - minrsq_lookup.i = 0 << tb->nshiftbits; - minrsq_lookup.i |= maskhi; - - for (int i = 0; i < ntable; i++) { - rsq_lookup.i = i << tb->nshiftbits; - rsq_lookup.i |= masklo; - if (rsq_lookup.f < tb->innersq) { - rsq_lookup.i = i << tb->nshiftbits; - rsq_lookup.i |= maskhi; - } - r = sqrtf(rsq_lookup.f); - tb->rsq[i] = rsq_lookup.f; - if (tb->match) { - tb->e[i] = tb->efile[i]; - tb->f[i] = tb->ffile[i]/r; - } else { - tb->e[i] = splint(tb->rfile,tb->efile,tb->e2file,tb->ninput,r); - tb->f[i] = splint(tb->rfile,tb->ffile,tb->f2file,tb->ninput,r)/r; - } - minrsq_lookup.f = MIN(minrsq_lookup.f,rsq_lookup.f); - } - - tb->innersq = minrsq_lookup.f; - - for (int i = 0; i < ntablem1; i++) { - tb->de[i] = tb->e[i+1] - tb->e[i]; - tb->df[i] = tb->f[i+1] - tb->f[i]; - tb->drsq[i] = 1.0/(tb->rsq[i+1] - tb->rsq[i]); - } - - // get the delta values for the last table entries - // tables are connected periodically between 0 and ntablem1 - - tb->de[ntablem1] = tb->e[0] - tb->e[ntablem1]; - tb->df[ntablem1] = tb->f[0] - tb->f[ntablem1]; - tb->drsq[ntablem1] = 1.0/(tb->rsq[0] - tb->rsq[ntablem1]); - - // get the correct delta values at itablemax - // smallest r is in bin itablemin - // largest r is in bin itablemax, which is itablemin-1, - // or ntablem1 if itablemin=0 - - // deltas at itablemax only needed if corresponding rsq < cut*cut - // if so, compute deltas between rsq and cut*cut - // if tb->match, data at cut*cut is unavailable, so we'll take - // deltas at itablemax-1 as a good approximation - - double e_tmp,f_tmp; - int itablemin = minrsq_lookup.i & tb->nmask; - itablemin >>= tb->nshiftbits; - int itablemax = itablemin - 1; - if (itablemin == 0) itablemax = ntablem1; - int itablemaxm1 = itablemax - 1; - if (itablemax == 0) itablemaxm1 = ntablem1; - rsq_lookup.i = itablemax << tb->nshiftbits; - rsq_lookup.i |= maskhi; - if (rsq_lookup.f < tb->cut*tb->cut) { - if (tb->match) { - tb->de[itablemax] = tb->de[itablemaxm1]; - tb->df[itablemax] = tb->df[itablemaxm1]; - tb->drsq[itablemax] = tb->drsq[itablemaxm1]; - } else { - rsq_lookup.f = tb->cut*tb->cut; - r = sqrtf(rsq_lookup.f); - e_tmp = splint(tb->rfile,tb->efile,tb->e2file,tb->ninput,r); - f_tmp = splint(tb->rfile,tb->ffile,tb->f2file,tb->ninput,r)/r; - tb->de[itablemax] = e_tmp - tb->e[itablemax]; - tb->df[itablemax] = f_tmp - tb->f[itablemax]; - tb->drsq[itablemax] = 1.0/(rsq_lookup.f - tb->rsq[itablemax]); - } - } - } -} - -/* ---------------------------------------------------------------------- - set all ptrs in a table to NULL, so can be freed safely -------------------------------------------------------------------------- */ - -template -void PairTableKokkos::null_table(Table *tb) -{ - tb->rfile = tb->efile = tb->ffile = NULL; - tb->e2file = tb->f2file = NULL; - tb->rsq = tb->drsq = tb->e = tb->de = NULL; - tb->f = tb->df = tb->e2 = tb->f2 = NULL; -} - -/* ---------------------------------------------------------------------- - free all arrays in a table -------------------------------------------------------------------------- */ - -template -void PairTableKokkos::free_table(Table *tb) -{ - memory->destroy(tb->rfile); - memory->destroy(tb->efile); - memory->destroy(tb->ffile); - memory->destroy(tb->e2file); - memory->destroy(tb->f2file); - - memory->destroy(tb->rsq); - memory->destroy(tb->drsq); - memory->destroy(tb->e); - memory->destroy(tb->de); - memory->destroy(tb->f); - memory->destroy(tb->df); - memory->destroy(tb->e2); - memory->destroy(tb->f2); -} - -/* ---------------------------------------------------------------------- - spline and splint routines modified from Numerical Recipes -------------------------------------------------------------------------- */ - -template -void PairTableKokkos::spline(double *x, double *y, int n, - double yp1, double ypn, double *y2) -{ - int i,k; - double p,qn,sig,un; - double *u = new double[n]; - - if (yp1 > 0.99e30) y2[0] = u[0] = 0.0; - else { - y2[0] = -0.5; - u[0] = (3.0/(x[1]-x[0])) * ((y[1]-y[0]) / (x[1]-x[0]) - yp1); - } - for (i = 1; i < n-1; i++) { - sig = (x[i]-x[i-1]) / (x[i+1]-x[i-1]); - p = sig*y2[i-1] + 2.0; - y2[i] = (sig-1.0) / p; - u[i] = (y[i+1]-y[i]) / (x[i+1]-x[i]) - (y[i]-y[i-1]) / (x[i]-x[i-1]); - u[i] = (6.0*u[i] / (x[i+1]-x[i-1]) - sig*u[i-1]) / p; - } - if (ypn > 0.99e30) qn = un = 0.0; - else { - qn = 0.5; - un = (3.0/(x[n-1]-x[n-2])) * (ypn - (y[n-1]-y[n-2]) / (x[n-1]-x[n-2])); - } - y2[n-1] = (un-qn*u[n-2]) / (qn*y2[n-2] + 1.0); - for (k = n-2; k >= 0; k--) y2[k] = y2[k]*y2[k+1] + u[k]; - - delete [] u; -} - -/* ---------------------------------------------------------------------- */ - -template -double PairTableKokkos::splint(double *xa, double *ya, double *y2a, int n, double x) -{ - int klo,khi,k; - double h,b,a,y; - - klo = 0; - khi = n-1; - while (khi-klo > 1) { - k = (khi+klo) >> 1; - if (xa[k] > x) khi = k; - else klo = k; - } - h = xa[khi]-xa[klo]; - a = (xa[khi]-x) / h; - b = (x-xa[klo]) / h; - y = a*ya[klo] + b*ya[khi] + - ((a*a*a-a)*y2a[klo] + (b*b*b-b)*y2a[khi]) * (h*h)/6.0; - return y; -} - -/* ---------------------------------------------------------------------- - proc 0 writes to restart file -------------------------------------------------------------------------- */ - -template -void PairTableKokkos::write_restart(FILE *fp) -{ - write_restart_settings(fp); -} - -/* ---------------------------------------------------------------------- - proc 0 reads from restart file, bcasts -------------------------------------------------------------------------- */ - -template -void PairTableKokkos::read_restart(FILE *fp) -{ - read_restart_settings(fp); - allocate(); -} - -/* ---------------------------------------------------------------------- - proc 0 writes to restart file -------------------------------------------------------------------------- */ - -template -void PairTableKokkos::write_restart_settings(FILE *fp) -{ - fwrite(&tabstyle,sizeof(int),1,fp); - fwrite(&tablength,sizeof(int),1,fp); - fwrite(&ewaldflag,sizeof(int),1,fp); - fwrite(&pppmflag,sizeof(int),1,fp); - fwrite(&msmflag,sizeof(int),1,fp); - fwrite(&dispersionflag,sizeof(int),1,fp); - fwrite(&tip4pflag,sizeof(int),1,fp); -} - -/* ---------------------------------------------------------------------- - proc 0 reads from restart file, bcasts -------------------------------------------------------------------------- */ - -template -void PairTableKokkos::read_restart_settings(FILE *fp) -{ - if (comm->me == 0) { - fread(&tabstyle,sizeof(int),1,fp); - fread(&tablength,sizeof(int),1,fp); - fread(&ewaldflag,sizeof(int),1,fp); - fread(&pppmflag,sizeof(int),1,fp); - fread(&msmflag,sizeof(int),1,fp); - fread(&dispersionflag,sizeof(int),1,fp); - fread(&tip4pflag,sizeof(int),1,fp); - } - MPI_Bcast(&tabstyle,1,MPI_INT,0,world); - MPI_Bcast(&tablength,1,MPI_INT,0,world); - MPI_Bcast(&ewaldflag,1,MPI_INT,0,world); - MPI_Bcast(&pppmflag,1,MPI_INT,0,world); - MPI_Bcast(&msmflag,1,MPI_INT,0,world); - MPI_Bcast(&dispersionflag,1,MPI_INT,0,world); - MPI_Bcast(&tip4pflag,1,MPI_INT,0,world); -} - -/* ---------------------------------------------------------------------- */ - -template -double PairTableKokkos::single(int i, int j, int itype, int jtype, double rsq, - double factor_coul, double factor_lj, - double &fforce) -{ - int itable; - double fraction,value,a,b,phi; - int tlm1 = tablength - 1; - - Table *tb = &tables[tabindex[itype][jtype]]; - if (rsq < tb->innersq) error->one(FLERR,"Pair distance < table inner cutoff"); - - if (tabstyle == LOOKUP) { - itable = static_cast ((rsq-tb->innersq) * tb->invdelta); - if (itable >= tlm1) error->one(FLERR,"Pair distance > table outer cutoff"); - fforce = factor_lj * tb->f[itable]; - } else if (tabstyle == LINEAR) { - itable = static_cast ((rsq-tb->innersq) * tb->invdelta); - if (itable >= tlm1) error->one(FLERR,"Pair distance > table outer cutoff"); - fraction = (rsq - tb->rsq[itable]) * tb->invdelta; - value = tb->f[itable] + fraction*tb->df[itable]; - fforce = factor_lj * value; - } else if (tabstyle == SPLINE) { - itable = static_cast ((rsq-tb->innersq) * tb->invdelta); - if (itable >= tlm1) error->one(FLERR,"Pair distance > table outer cutoff"); - b = (rsq - tb->rsq[itable]) * tb->invdelta; - a = 1.0 - b; - value = a * tb->f[itable] + b * tb->f[itable+1] + - ((a*a*a-a)*tb->f2[itable] + (b*b*b-b)*tb->f2[itable+1]) * - tb->deltasq6; - fforce = factor_lj * value; - } else { - union_int_float_t rsq_lookup; - rsq_lookup.f = rsq; - itable = rsq_lookup.i & tb->nmask; - itable >>= tb->nshiftbits; - fraction = (rsq_lookup.f - tb->rsq[itable]) * tb->drsq[itable]; - value = tb->f[itable] + fraction*tb->df[itable]; - fforce = factor_lj * value; - } - - if (tabstyle == LOOKUP) - phi = tb->e[itable]; - else if (tabstyle == LINEAR || tabstyle == BITMAP) - phi = tb->e[itable] + fraction*tb->de[itable]; - else - phi = a * tb->e[itable] + b * tb->e[itable+1] + - ((a*a*a-a)*tb->e2[itable] + (b*b*b-b)*tb->e2[itable+1]) * tb->deltasq6; - return factor_lj*phi; -} - -/* ---------------------------------------------------------------------- - return the Coulomb cutoff for tabled potentials - called by KSpace solvers which require that all pairwise cutoffs be the same - loop over all tables not just those indexed by tabindex[i][j] since - no way to know which tables are active since pair::init() not yet called -------------------------------------------------------------------------- */ - -template -void *PairTableKokkos::extract(const char *str, int &dim) -{ - if (strcmp(str,"cut_coul") != 0) return NULL; - if (ntables == 0) error->all(FLERR,"All pair coeffs are not set"); - - double cut_coul = tables[0].cut; - for (int m = 1; m < ntables; m++) - if (tables[m].cut != cut_coul) - error->all(FLERR, - "Pair table cutoffs must all be equal to use with KSpace"); - dim = 0; - return &tables[0].cut; -} - template void PairTableKokkos::init_style() { diff --git a/src/KOKKOS/pair_table_kokkos.h b/src/KOKKOS/pair_table_kokkos.h index 09e64804b4..7c021df61e 100644 --- a/src/KOKKOS/pair_table_kokkos.h +++ b/src/KOKKOS/pair_table_kokkos.h @@ -22,7 +22,7 @@ PairStyle(table/kk/host,PairTableKokkos) #ifndef LMP_PAIR_TABLE_KOKKOS_H #define LMP_PAIR_TABLE_KOKKOS_H -#include "pair.h" +#include "pair_table.h" #include "pair_kokkos.h" #include "neigh_list_kokkos.h" #include "atom_kokkos.h" @@ -38,7 +38,7 @@ template class PairTableComputeFunctor; template -class PairTableKokkos : public Pair { +class PairTableKokkos : public PairTable { public: enum {EnabledNeighFlags=FULL|HALFTHREAD|HALF|N2|FULLCLUSTER}; @@ -59,18 +59,9 @@ class PairTableKokkos : public Pair { const NeighListKokkos &list) const; */ void settings(int, char **); - void coeff(int, char **); double init_one(int, int); - void write_restart(FILE *); - void read_restart(FILE *); - void write_restart_settings(FILE *); - void read_restart_settings(FILE *); - double single(int, int, int, int, double, double, double, double &); - void *extract(const char *, int &); - void init_style(); - protected: enum{LOOKUP,LINEAR,SPLINE,BITMAP}; @@ -107,17 +98,6 @@ class PairTableKokkos : public Pair { typename ArrayTypes::t_ffloat_2d rsq,drsq,e,de,f,df,e2,f2; }; - struct Table { - int ninput,rflag,fpflag,match,ntablebits; - int nshiftbits,nmask; - double rlo,rhi,fplo,fphi,cut; - double *rfile,*efile,*ffile; - double *e2file,*f2file; - double innersq,delta,invdelta,deltasq6; - double *rsq,*drsq,*e,*de,*f,*df,*e2,*f2; - }; - int ntables; - Table *tables; TableDeviceConst d_table_const; TableDevice* d_table; TableHost* h_table; @@ -128,15 +108,6 @@ class PairTableKokkos : public Pair { typename ArrayTypes::t_ffloat_2d d_cutsq; void allocate(); - void read_table(Table *, char *, char *); - void param_extract(Table *, char *); - void bcast_table(Table *); - void spline_table(Table *); - void compute_table(Table *); - void null_table(Table *); - void free_table(Table *); - void spline(double *, double *, int, double, double, double *); - double splint(double *, double *, double *, int, double); typename ArrayTypes::t_x_array_randomread x; typename ArrayTypes::t_x_array_const c_x; @@ -213,11 +184,6 @@ class PairTableKokkos : public Pair { friend void pair_virial_fdotr_compute(PairTableKokkos*); }; - - - - - } #endif @@ -297,4 +263,10 @@ E: Cannot use chosen neighbor list style with lj/cut/kk That style is not supported by Kokkos. + + + */ + + + diff --git a/src/KOKKOS/pair_table_rx_kokkos.cpp b/src/KOKKOS/pair_table_rx_kokkos.cpp new file mode 100644 index 0000000000..4c809d98bd --- /dev/null +++ b/src/KOKKOS/pair_table_rx_kokkos.cpp @@ -0,0 +1,634 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Stan Moore (SNL) +------------------------------------------------------------------------- */ + +#include +#include +#include +#include +#include "pair_table_rx_kokkos.h" +#include "kokkos.h" +#include "atom.h" +#include "force.h" +#include "comm.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "neigh_request.h" +#include "memory.h" +#include "error.h" +#include "atom_masks.h" + +using namespace LAMMPS_NS; + +enum{NONE,RLINEAR,RSQ,BMP}; +enum{FULL,HALFTHREAD,HALF}; + +#define MAXLINE 1024 + +/* ---------------------------------------------------------------------- */ + +template +PairTableRXKokkos::PairTableRXKokkos(LAMMPS *lmp) : PairTableRX(lmp) +{ + update_table = 0; + atomKK = (AtomKokkos *) atom; + ntables = 0; + tables = NULL; + execution_space = ExecutionSpaceFromDevice::space; + datamask_read = X_MASK | F_MASK | TYPE_MASK | ENERGY_MASK | VIRIAL_MASK; + datamask_modify = F_MASK | ENERGY_MASK | VIRIAL_MASK; + h_table = new TableHost(); + d_table = new TableDevice(); +} + +/* ---------------------------------------------------------------------- */ + +template +PairTableRXKokkos::~PairTableRXKokkos() +{ +/* for (int m = 0; m < ntables; m++) free_table(&tables[m]); + memory->sfree(tables); + + if (allocated) { + memory->destroy(setflag); + memory->destroy(cutsq); + memory->destroy(tabindex); + }*/ + delete h_table; + delete d_table; + +} + +/* ---------------------------------------------------------------------- */ + +template +void PairTableRXKokkos::compute(int eflag_in, int vflag_in) +{ + if(update_table) + create_kokkos_tables(); + if(tabstyle == LOOKUP) + compute_style(eflag_in,vflag_in); + if(tabstyle == LINEAR) + compute_style(eflag_in,vflag_in); + if(tabstyle == SPLINE) + compute_style(eflag_in,vflag_in); + if(tabstyle == BITMAP) + compute_style(eflag_in,vflag_in); +} + +template +template +void PairTableRXKokkos::compute_style(int eflag_in, int vflag_in) +{ + eflag = eflag_in; + vflag = vflag_in; + + if (neighflag == FULL || neighflag == FULLCLUSTER) no_virial_fdotr_compute = 1; + + + if (eflag || vflag) ev_setup(eflag,vflag); + else evflag = vflag_fdotr = 0; + + atomKK->sync(execution_space,datamask_read); + //k_cutsq.template sync(); + //k_params.template sync(); + if (eflag || vflag) atomKK->modified(execution_space,datamask_modify); + else atomKK->modified(execution_space,F_MASK); + + x = c_x = atomKK->k_x.view(); + f = atomKK->k_f.view(); + type = atomKK->k_type.view(); + nlocal = atom->nlocal; + nall = atom->nlocal + atom->nghost; + special_lj[0] = force->special_lj[0]; + special_lj[1] = force->special_lj[1]; + special_lj[2] = force->special_lj[2]; + special_lj[3] = force->special_lj[3]; + newton_pair = force->newton_pair; + d_cutsq = d_table->cutsq; + // loop over neighbors of my atoms + + EV_FLOAT ev; + if(atom->ntypes > MAX_TYPES_STACKPARAMS) { + if (neighflag == FULL) { + PairComputeFunctor,FULL,false,S_TableRXCompute > + ff(this,(NeighListKokkos*) list); + if (eflag || vflag) Kokkos::parallel_reduce(list->inum,ff,ev); + else Kokkos::parallel_for(list->inum,ff); + } else if (neighflag == HALFTHREAD) { + PairComputeFunctor,HALFTHREAD,false,S_TableRXCompute > + ff(this,(NeighListKokkos*) list); + if (eflag || vflag) Kokkos::parallel_reduce(list->inum,ff,ev); + else Kokkos::parallel_for(list->inum,ff); + } else if (neighflag == HALF) { + PairComputeFunctor,HALF,false,S_TableRXCompute > + f(this,(NeighListKokkos*) list); + if (eflag || vflag) Kokkos::parallel_reduce(list->inum,f,ev); + else Kokkos::parallel_for(list->inum,f); + } else if (neighflag == N2) { + PairComputeFunctor,N2,false,S_TableRXCompute > + f(this,(NeighListKokkos*) list); + if (eflag || vflag) Kokkos::parallel_reduce(nlocal,f,ev); + else Kokkos::parallel_for(nlocal,f); + } else if (neighflag == FULLCLUSTER) { + typedef PairComputeFunctor,FULLCLUSTER,false,S_TableRXCompute > + f_type; + f_type f(this,(NeighListKokkos*) list); + #ifdef KOKKOS_HAVE_CUDA + const int teamsize = Kokkos::Impl::is_same::value ? 32 : 1; + #else + const int teamsize = 1; + #endif + const int nteams = (list->inum*+teamsize-1)/teamsize; + Kokkos::TeamPolicy config(nteams,teamsize,NeighClusterSize); + if (eflag || vflag) Kokkos::parallel_reduce(config,f,ev); + else Kokkos::parallel_for(config,f); + } + } else { + if (neighflag == FULL) { + PairComputeFunctor,FULL,true,S_TableRXCompute > + f(this,(NeighListKokkos*) list); + if (eflag || vflag) Kokkos::parallel_reduce(list->inum,f,ev); + else Kokkos::parallel_for(list->inum,f); + } else if (neighflag == HALFTHREAD) { + PairComputeFunctor,HALFTHREAD,true,S_TableRXCompute > + f(this,(NeighListKokkos*) list); + if (eflag || vflag) Kokkos::parallel_reduce(list->inum,f,ev); + else Kokkos::parallel_for(list->inum,f); + } else if (neighflag == HALF) { + PairComputeFunctor,HALF,true,S_TableRXCompute > + f(this,(NeighListKokkos*) list); + if (eflag || vflag) Kokkos::parallel_reduce(list->inum,f,ev); + else Kokkos::parallel_for(list->inum,f); + } else if (neighflag == N2) { + PairComputeFunctor,N2,true,S_TableRXCompute > + f(this,(NeighListKokkos*) list); + if (eflag || vflag) Kokkos::parallel_reduce(nlocal,f,ev); + else Kokkos::parallel_for(nlocal,f); + } else if (neighflag == FULLCLUSTER) { + typedef PairComputeFunctor,FULLCLUSTER,true,S_TableRXCompute > + f_type; + f_type f(this,(NeighListKokkos*) list); + #ifdef KOKKOS_HAVE_CUDA + const int teamsize = Kokkos::Impl::is_same::value ? 32 : 1; + #else + const int teamsize = 1; + #endif + const int nteams = (list->inum*+teamsize-1)/teamsize; + Kokkos::TeamPolicy config(nteams,teamsize,NeighClusterSize); + if (eflag || vflag) Kokkos::parallel_reduce(config,f,ev); + else Kokkos::parallel_for(config,f); + } + } + + if (eflag) eng_vdwl += ev.evdwl; + if (vflag_global) { + virial[0] += ev.v[0]; + virial[1] += ev.v[1]; + virial[2] += ev.v[2]; + virial[3] += ev.v[3]; + virial[4] += ev.v[4]; + virial[5] += ev.v[5]; + } + + if (vflag_fdotr) pair_virial_fdotr_compute(this); +} + +template +template +KOKKOS_INLINE_FUNCTION +F_FLOAT PairTableRXKokkos:: +compute_fpair(const F_FLOAT& rsq, const int& i, const int&j, const int& itype, const int& jtype) const { + (void) i; + (void) j; + union_int_float_t rsq_lookup; + double fpair; + const int tidx = d_table_const.tabindex(itype,jtype); + //const Table* const tb = &tables[tabindex[itype][jtype]]; + + //if (rsq < d_table_const.innersq(tidx)) + // error->one(FLERR,"Pair distance < table inner cutoff"); + + + if (Specialisation::TabStyle == LOOKUP) { + const int itable = static_cast ((rsq - d_table_const.innersq(tidx)) * d_table_const.invdelta(tidx)); + //if (itable >= tlm1) + // error->one(FLERR,"Pair distance > table outer cutoff"); + fpair = d_table_const.f(tidx,itable); + } else if (Specialisation::TabStyle == LINEAR) { + const int itable = static_cast ((rsq - d_table_const.innersq(tidx)) * d_table_const.invdelta(tidx)); + //if (itable >= tlm1) + // error->one(FLERR,"Pair distance > table outer cutoff"); + const double fraction = (rsq - d_table_const.rsq(tidx,itable)) * d_table_const.invdelta(tidx); + fpair = d_table_const.f(tidx,itable) + fraction*d_table_const.df(tidx,itable); + } else if (Specialisation::TabStyle == SPLINE) { + const int itable = static_cast ((rsq - d_table_const.innersq(tidx)) * d_table_const.invdelta(tidx)); + //if (itable >= tlm1) + // error->one(FLERR,"Pair distance > table outer cutoff"); + const double b = (rsq - d_table_const.rsq(tidx,itable)) * d_table_const.invdelta(tidx); + const double a = 1.0 - b; + fpair = a * d_table_const.f(tidx,itable) + b * d_table_const.f(tidx,itable+1) + + ((a*a*a-a)*d_table_const.f2(tidx,itable) + (b*b*b-b)*d_table_const.f2(tidx,itable+1)) * + d_table_const.deltasq6(tidx); + } else { + rsq_lookup.f = rsq; + int itable = rsq_lookup.i & d_table_const.nmask(tidx); + itable >>= d_table_const.nshiftbits(tidx); + const double fraction = (rsq_lookup.f - d_table_const.rsq(tidx,itable)) * d_table_const.drsq(tidx,itable); + fpair = d_table_const.f(tidx,itable) + fraction*d_table_const.df(tidx,itable); + } + return fpair; +} + +template +template +KOKKOS_INLINE_FUNCTION +F_FLOAT PairTableRXKokkos:: +compute_evdwl(const F_FLOAT& rsq, const int& i, const int&j, const int& itype, const int& jtype) const { + (void) i; + (void) j; + double evdwl; + union_int_float_t rsq_lookup; + const int tidx = d_table_const.tabindex(itype,jtype); + //const Table* const tb = &tables[tabindex[itype][jtype]]; + + //if (rsq < d_table_const.innersq(tidx)) + // error->one(FLERR,"Pair distance < table inner cutoff"); + + if (Specialisation::TabStyle == LOOKUP) { + const int itable = static_cast ((rsq - d_table_const.innersq(tidx)) * d_table_const.invdelta(tidx)); + //if (itable >= tlm1) + // error->one(FLERR,"Pair distance > table outer cutoff"); + evdwl = d_table_const.e(tidx,itable); + } else if (Specialisation::TabStyle == LINEAR) { + const int itable = static_cast ((rsq - d_table_const.innersq(tidx)) * d_table_const.invdelta(tidx)); + //if (itable >= tlm1) + // error->one(FLERR,"Pair distance > table outer cutoff"); + const double fraction = (rsq - d_table_const.rsq(tidx,itable)) * d_table_const.invdelta(tidx); + evdwl = d_table_const.e(tidx,itable) + fraction*d_table_const.de(tidx,itable); + } else if (Specialisation::TabStyle == SPLINE) { + const int itable = static_cast ((rsq - d_table_const.innersq(tidx)) * d_table_const.invdelta(tidx)); + //if (itable >= tlm1) + // error->one(FLERR,"Pair distance > table outer cutoff"); + const double b = (rsq - d_table_const.rsq(tidx,itable)) * d_table_const.invdelta(tidx); + const double a = 1.0 - b; + evdwl = a * d_table_const.e(tidx,itable) + b * d_table_const.e(tidx,itable+1) + + ((a*a*a-a)*d_table_const.e2(tidx,itable) + (b*b*b-b)*d_table_const.e2(tidx,itable+1)) * + d_table_const.deltasq6(tidx); + } else { + rsq_lookup.f = rsq; + int itable = rsq_lookup.i & d_table_const.nmask(tidx); + itable >>= d_table_const.nshiftbits(tidx); + const double fraction = (rsq_lookup.f - d_table_const.rsq(tidx,itable)) * d_table_const.drsq(tidx,itable); + evdwl = d_table_const.e(tidx,itable) + fraction*d_table_const.de(tidx,itable); + } + return evdwl; +} + +template +void PairTableRXKokkos::create_kokkos_tables() +{ + const int tlm1 = tablength-1; + + memory->create_kokkos(d_table->nshiftbits,h_table->nshiftbits,ntables,"Table::nshiftbits"); + memory->create_kokkos(d_table->nmask,h_table->nmask,ntables,"Table::nmask"); + memory->create_kokkos(d_table->innersq,h_table->innersq,ntables,"Table::innersq"); + memory->create_kokkos(d_table->invdelta,h_table->invdelta,ntables,"Table::invdelta"); + memory->create_kokkos(d_table->deltasq6,h_table->deltasq6,ntables,"Table::deltasq6"); + + if(tabstyle == LOOKUP) { + memory->create_kokkos(d_table->e,h_table->e,ntables,tlm1,"Table::e"); + memory->create_kokkos(d_table->f,h_table->f,ntables,tlm1,"Table::f"); + } + + if(tabstyle == LINEAR) { + memory->create_kokkos(d_table->rsq,h_table->rsq,ntables,tablength,"Table::rsq"); + memory->create_kokkos(d_table->e,h_table->e,ntables,tablength,"Table::e"); + memory->create_kokkos(d_table->f,h_table->f,ntables,tablength,"Table::f"); + memory->create_kokkos(d_table->de,h_table->de,ntables,tlm1,"Table::de"); + memory->create_kokkos(d_table->df,h_table->df,ntables,tlm1,"Table::df"); + } + + if(tabstyle == SPLINE) { + memory->create_kokkos(d_table->rsq,h_table->rsq,ntables,tablength,"Table::rsq"); + memory->create_kokkos(d_table->e,h_table->e,ntables,tablength,"Table::e"); + memory->create_kokkos(d_table->f,h_table->f,ntables,tablength,"Table::f"); + memory->create_kokkos(d_table->e2,h_table->e2,ntables,tablength,"Table::e2"); + memory->create_kokkos(d_table->f2,h_table->f2,ntables,tablength,"Table::f2"); + } + + if(tabstyle == BITMAP) { + int ntable = 1 << tablength; + memory->create_kokkos(d_table->rsq,h_table->rsq,ntables,ntable,"Table::rsq"); + memory->create_kokkos(d_table->e,h_table->e,ntables,ntable,"Table::e"); + memory->create_kokkos(d_table->f,h_table->f,ntables,ntable,"Table::f"); + memory->create_kokkos(d_table->de,h_table->de,ntables,ntable,"Table::de"); + memory->create_kokkos(d_table->df,h_table->df,ntables,ntable,"Table::df"); + memory->create_kokkos(d_table->drsq,h_table->drsq,ntables,ntable,"Table::drsq"); + } + + for(int i=0; i < ntables; i++) { + Table* tb = &tables[i]; + + h_table->nshiftbits[i] = tb->nshiftbits; + h_table->nmask[i] = tb->nmask; + h_table->innersq[i] = tb->innersq; + h_table->invdelta[i] = tb->invdelta; + h_table->deltasq6[i] = tb->deltasq6; + + for(int j = 0; jrsq.dimension_1(); j++) + h_table->rsq(i,j) = tb->rsq[j]; + for(int j = 0; jdrsq.dimension_1(); j++) + h_table->drsq(i,j) = tb->drsq[j]; + for(int j = 0; je.dimension_1(); j++) + h_table->e(i,j) = tb->e[j]; + for(int j = 0; jde.dimension_1(); j++) + h_table->de(i,j) = tb->de[j]; + for(int j = 0; jf.dimension_1(); j++) + h_table->f(i,j) = tb->f[j]; + for(int j = 0; jdf.dimension_1(); j++) + h_table->df(i,j) = tb->df[j]; + for(int j = 0; je2.dimension_1(); j++) + h_table->e2(i,j) = tb->e2[j]; + for(int j = 0; jf2.dimension_1(); j++) + h_table->f2(i,j) = tb->f2[j]; + } + + + Kokkos::deep_copy(d_table->nshiftbits,h_table->nshiftbits); + Kokkos::deep_copy(d_table->nmask,h_table->nmask); + Kokkos::deep_copy(d_table->innersq,h_table->innersq); + Kokkos::deep_copy(d_table->invdelta,h_table->invdelta); + Kokkos::deep_copy(d_table->deltasq6,h_table->deltasq6); + Kokkos::deep_copy(d_table->rsq,h_table->rsq); + Kokkos::deep_copy(d_table->drsq,h_table->drsq); + Kokkos::deep_copy(d_table->e,h_table->e); + Kokkos::deep_copy(d_table->de,h_table->de); + Kokkos::deep_copy(d_table->f,h_table->f); + Kokkos::deep_copy(d_table->df,h_table->df); + Kokkos::deep_copy(d_table->e2,h_table->e2); + Kokkos::deep_copy(d_table->f2,h_table->f2); + Kokkos::deep_copy(d_table->tabindex,h_table->tabindex); + + d_table_const.nshiftbits = d_table->nshiftbits; + d_table_const.nmask = d_table->nmask; + d_table_const.innersq = d_table->innersq; + d_table_const.invdelta = d_table->invdelta; + d_table_const.deltasq6 = d_table->deltasq6; + d_table_const.rsq = d_table->rsq; + d_table_const.drsq = d_table->drsq; + d_table_const.e = d_table->e; + d_table_const.de = d_table->de; + d_table_const.f = d_table->f; + d_table_const.df = d_table->df; + d_table_const.e2 = d_table->e2; + d_table_const.f2 = d_table->f2; + + + Kokkos::deep_copy(d_table->cutsq,h_table->cutsq); + update_table = 0; +} + +/* ---------------------------------------------------------------------- + allocate all arrays +------------------------------------------------------------------------- */ + +template +void PairTableRXKokkos::allocate() +{ + allocated = 1; + const int nt = atom->ntypes + 1; + + memory->create(setflag,nt,nt,"pair:setflag"); + memory->create_kokkos(d_table->cutsq,h_table->cutsq,cutsq,nt,nt,"pair:cutsq"); + memory->create_kokkos(d_table->tabindex,h_table->tabindex,tabindex,nt,nt,"pair:tabindex"); + + d_table_const.cutsq = d_table->cutsq; + d_table_const.tabindex = d_table->tabindex; + memset(&setflag[0][0],0,nt*nt*sizeof(int)); + memset(&cutsq[0][0],0,nt*nt*sizeof(double)); + memset(&tabindex[0][0],0,nt*nt*sizeof(int)); +} + +/* ---------------------------------------------------------------------- + global settings +------------------------------------------------------------------------- */ + +template +void PairTableRXKokkos::settings(int narg, char **arg) +{ + if (narg < 2) error->all(FLERR,"Illegal pair_style command"); + + // new settings + + if (strcmp(arg[0],"lookup") == 0) tabstyle = LOOKUP; + else if (strcmp(arg[0],"linear") == 0) tabstyle = LINEAR; + else if (strcmp(arg[0],"spline") == 0) tabstyle = SPLINE; + else if (strcmp(arg[0],"bitmap") == 0) tabstyle = BITMAP; + else error->all(FLERR,"Unknown table style in pair_style command"); + + tablength = force->inumeric(FLERR,arg[1]); + if (tablength < 2) error->all(FLERR,"Illegal number of pair table entries"); + + // optional keywords + // assert the tabulation is compatible with a specific long-range solver + + int iarg = 2; + while (iarg < narg) { + if (strcmp(arg[iarg],"ewald") == 0) ewaldflag = 1; + else if (strcmp(arg[iarg],"pppm") == 0) pppmflag = 1; + else if (strcmp(arg[iarg],"msm") == 0) msmflag = 1; + else if (strcmp(arg[iarg],"dispersion") == 0) dispersionflag = 1; + else if (strcmp(arg[iarg],"tip4p") == 0) tip4pflag = 1; + else error->all(FLERR,"Illegal pair_style command"); + iarg++; + } + + // delete old tables, since cannot just change settings + + for (int m = 0; m < ntables; m++) free_table(&tables[m]); + memory->sfree(tables); + + if (allocated) { + memory->destroy(setflag); + + d_table_const.tabindex = d_table->tabindex = typename ArrayTypes::t_int_2d(); + h_table->tabindex = typename ArrayTypes::t_int_2d(); + + d_table_const.cutsq = d_table->cutsq = typename ArrayTypes::t_ffloat_2d(); + h_table->cutsq = typename ArrayTypes::t_ffloat_2d(); + } + allocated = 0; + + ntables = 0; + tables = NULL; +} + +/* ---------------------------------------------------------------------- + init for one type pair i,j and corresponding j,i +------------------------------------------------------------------------- */ + +template +double PairTableRXKokkos::init_one(int i, int j) +{ + if (setflag[i][j] == 0) error->all(FLERR,"All pair coeffs are not set"); + + tabindex[j][i] = tabindex[i][j]; + + if(i +void PairTableRXKokkos::init_style() +{ + neighbor->request(this,instance_me); + neighflag = lmp->kokkos->neighflag; + int irequest = neighbor->nrequest - 1; + + neighbor->requests[irequest]-> + kokkos_host = Kokkos::Impl::is_same::value && + !Kokkos::Impl::is_same::value; + neighbor->requests[irequest]-> + kokkos_device = Kokkos::Impl::is_same::value; + + if (neighflag == FULL) { + neighbor->requests[irequest]->full = 1; + neighbor->requests[irequest]->half = 0; + neighbor->requests[irequest]->full_cluster = 0; + } else if (neighflag == HALF || neighflag == HALFTHREAD) { + neighbor->requests[irequest]->full = 0; + neighbor->requests[irequest]->half = 1; + neighbor->requests[irequest]->full_cluster = 0; + } else if (neighflag == N2) { + neighbor->requests[irequest]->full = 0; + neighbor->requests[irequest]->half = 0; + neighbor->requests[irequest]->full_cluster = 0; + } else if (neighflag == FULLCLUSTER) { + neighbor->requests[irequest]->full_cluster = 1; + neighbor->requests[irequest]->full = 1; + neighbor->requests[irequest]->half = 0; + } else { + error->all(FLERR,"Cannot use chosen neighbor list style with lj/cut/kk"); + } +} + +/* +template template +KOKKOS_INLINE_FUNCTION +void PairTableRXKokkos:: +ev_tally(EV_FLOAT &ev, const int &i, const int &j, const F_FLOAT &fpair, + const F_FLOAT &delx, const F_FLOAT &dely, const F_FLOAT &delz) const +{ + const int EFLAG = eflag; + const int NEWTON_PAIR = newton_pair; + const int VFLAG = vflag_either; + + if (EFLAG) { + if (eflag_atom) { + E_FLOAT epairhalf = 0.5 * (ev.evdwl + ev.ecoul); + if (NEWTON_PAIR || i < nlocal) eatom[i] += epairhalf; + if (NEWTON_PAIR || j < nlocal) eatom[j] += epairhalf; + } + } + + if (VFLAG) { + const E_FLOAT v0 = delx*delx*fpair; + const E_FLOAT v1 = dely*dely*fpair; + const E_FLOAT v2 = delz*delz*fpair; + const E_FLOAT v3 = delx*dely*fpair; + const E_FLOAT v4 = delx*delz*fpair; + const E_FLOAT v5 = dely*delz*fpair; + + if (vflag_global) { + if (NEIGHFLAG) { + if (NEWTON_PAIR) { + ev.v[0] += v0; + ev.v[1] += v1; + ev.v[2] += v2; + ev.v[3] += v3; + ev.v[4] += v4; + ev.v[5] += v5; + } else { + if (i < nlocal) { + ev.v[0] += 0.5*v0; + ev.v[1] += 0.5*v1; + ev.v[2] += 0.5*v2; + ev.v[3] += 0.5*v3; + ev.v[4] += 0.5*v4; + ev.v[5] += 0.5*v5; + } + if (j < nlocal) { + ev.v[0] += 0.5*v0; + ev.v[1] += 0.5*v1; + ev.v[2] += 0.5*v2; + ev.v[3] += 0.5*v3; + ev.v[4] += 0.5*v4; + ev.v[5] += 0.5*v5; + } + } + } else { + ev.v[0] += 0.5*v0; + ev.v[1] += 0.5*v1; + ev.v[2] += 0.5*v2; + ev.v[3] += 0.5*v3; + ev.v[4] += 0.5*v4; + ev.v[5] += 0.5*v5; + } + } + + if (vflag_atom) { + if (NEWTON_PAIR || i < nlocal) { + d_vatom(i,0) += 0.5*v0; + d_vatom(i,1) += 0.5*v1; + d_vatom(i,2) += 0.5*v2; + d_vatom(i,3) += 0.5*v3; + d_vatom(i,4) += 0.5*v4; + d_vatom(i,5) += 0.5*v5; + } + if (NEWTON_PAIR || (NEIGHFLAG && j < nlocal)) { + d_vatom(j,0) += 0.5*v0; + d_vatom(j,1) += 0.5*v1; + d_vatom(j,2) += 0.5*v2; + d_vatom(j,3) += 0.5*v3; + d_vatom(j,4) += 0.5*v4; + d_vatom(j,5) += 0.5*v5; + } + } + } +} +*/ +template +void PairTableRXKokkos::cleanup_copy() { + // WHY needed: this prevents parent copy from deallocating any arrays + allocated = 0; + cutsq = NULL; + eatom = NULL; + vatom = NULL; + h_table=NULL; d_table=NULL; +} + +namespace LAMMPS_NS { +template class PairTableRXKokkos; +#ifdef KOKKOS_HAVE_CUDA +template class PairTableRXKokkos; +#endif + +} + diff --git a/src/KOKKOS/pair_table_rx_kokkos.h b/src/KOKKOS/pair_table_rx_kokkos.h new file mode 100644 index 0000000000..6f0616cc28 --- /dev/null +++ b/src/KOKKOS/pair_table_rx_kokkos.h @@ -0,0 +1,269 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(table/rx/kk,PairTableRXKokkos) +PairStyle(table/rx/kk/device,PairTableRXKokkos) +PairStyle(table/rx/kk/host,PairTableRXKokkos) + +#else + +#ifndef LMP_PAIR_TABLE_RX_KOKKOS_H +#define LMP_PAIR_TABLE_RX_KOKKOS_H + +#include "pair_table_rx.h" +#include "pair_kokkos.h" +#include "neigh_list_kokkos.h" +#include "atom_kokkos.h" + +namespace LAMMPS_NS { + +template +struct S_TableRXCompute { + enum {TabStyle = TABSTYLE}; +}; + +template +class PairTableRXComputeFunctor; + +template +class PairTableRXKokkos : public PairTableRX { + public: + + enum {EnabledNeighFlags=FULL|HALFTHREAD|HALF|N2|FULLCLUSTER}; + enum {COUL_FLAG=0}; + typedef DeviceType device_type; + + PairTableRXKokkos(class LAMMPS *); + virtual ~PairTableRXKokkos(); + + virtual void compute(int, int); + + template + void compute_style(int, int); + + /*template + KOKKOS_FUNCTION + EV_FLOAT compute_item(const int& i, + const NeighListKokkos &list) const; +*/ + void settings(int, char **); + double init_one(int, int); + void init_style(); + + protected: + enum{LOOKUP,LINEAR,SPLINE,BITMAP}; + + int tabstyle,tablength; + /*struct TableDeviceConst { + typename ArrayTypes::t_ffloat_2d_randomread cutsq; + typename ArrayTypes::t_int_2d_randomread tabindex; + typename ArrayTypes::t_int_1d_randomread nshiftbits,nmask; + typename ArrayTypes::t_ffloat_1d_randomread innersq,invdelta,deltasq6; + typename ArrayTypes::t_ffloat_2d_randomread rsq,drsq,e,de,f,df,e2,f2; + };*/ + //Its faster not to use texture fetch if the number of tables is less than 32! + struct TableDeviceConst { + typename ArrayTypes::t_ffloat_2d cutsq; + typename ArrayTypes::t_int_2d tabindex; + typename ArrayTypes::t_int_1d nshiftbits,nmask; + typename ArrayTypes::t_ffloat_1d innersq,invdelta,deltasq6; + typename ArrayTypes::t_ffloat_2d_randomread rsq,drsq,e,de,f,df,e2,f2; + }; + + struct TableDevice { + typename ArrayTypes::t_ffloat_2d cutsq; + typename ArrayTypes::t_int_2d tabindex; + typename ArrayTypes::t_int_1d nshiftbits,nmask; + typename ArrayTypes::t_ffloat_1d innersq,invdelta,deltasq6; + typename ArrayTypes::t_ffloat_2d rsq,drsq,e,de,f,df,e2,f2; + }; + + struct TableHost { + typename ArrayTypes::t_ffloat_2d cutsq; + typename ArrayTypes::t_int_2d tabindex; + typename ArrayTypes::t_int_1d nshiftbits,nmask; + typename ArrayTypes::t_ffloat_1d innersq,invdelta,deltasq6; + typename ArrayTypes::t_ffloat_2d rsq,drsq,e,de,f,df,e2,f2; + }; + + TableDeviceConst d_table_const; + TableDevice* d_table; + TableHost* h_table; + + int **tabindex; + F_FLOAT m_cutsq[MAX_TYPES_STACKPARAMS+1][MAX_TYPES_STACKPARAMS+1]; + + typename ArrayTypes::t_ffloat_2d d_cutsq; + + void allocate(); + + typename ArrayTypes::t_x_array_randomread x; + typename ArrayTypes::t_x_array_const c_x; + typename ArrayTypes::t_f_array f; + typename ArrayTypes::t_int_1d_randomread type; + typename ArrayTypes::t_efloat_1d d_eatom; + typename ArrayTypes::t_virial_array d_vatom; + + protected: + int nlocal,nall,eflag,vflag,neighflag,newton_pair; + + int update_table; + void create_kokkos_tables(); + void cleanup_copy(); + + template + KOKKOS_INLINE_FUNCTION + F_FLOAT compute_fpair(const F_FLOAT& rsq, const int& i, const int&j, const int& itype, const int& jtype) const; + + template + KOKKOS_INLINE_FUNCTION + F_FLOAT compute_evdwl(const F_FLOAT& rsq, const int& i, const int&j, const int& itype, const int& jtype) const; + + template + KOKKOS_INLINE_FUNCTION + F_FLOAT compute_ecoul(const F_FLOAT& rsq, const int& i, const int&j, const int& itype, const int& jtype) const { + return 0; + } + + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + + friend void pair_virial_fdotr_compute(PairTableRXKokkos*); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +E: Pair distance < table inner cutoff + +Two atoms are closer together than the pairwise table allows. + +E: Pair distance > table outer cutoff + +Two atoms are further apart than the pairwise table allows. + +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: Unknown table style in pair_style command + +Style of table is invalid for use with pair_style table command. + +E: Illegal number of pair table entries + +There must be at least 2 table entries. + +E: Invalid pair table length + +Length of read-in pair table is invalid + +E: Invalid pair table cutoff + +Cutoffs in pair_coeff command are not valid with read-in pair table. + +E: Bitmapped table in file does not match requested table + +Setting for bitmapped table in pair_coeff command must match table +in file exactly. + +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. + +E: Cannot open file %s + +The specified file cannot be opened. Check that the path and name are +correct. If the file is a compressed file, also check that the gzip +executable can be found and run. + +E: Did not find keyword in table file + +Keyword used in pair_coeff command was not found in table file. + +E: Bitmapped table is incorrect length in table file + +Number of table entries is not a correct power of 2. + +E: Invalid keyword in pair table parameters + +Keyword used in list of table parameters is not recognized. + +E: Pair table parameters did not set N + +List of pair table parameters must include N setting. + +E: Pair table cutoffs must all be equal to use with KSpace + +When using pair style table with a long-range KSpace solver, the +cutoffs for all atom type pairs must all be the same, since the +long-range solver starts at that cutoff. + +E: Cannot use chosen neighbor list style with lj/cut/kk + +That style is not supported by Kokkos. + + + + +*/ \ No newline at end of file diff --git a/src/USER-DPD/pair_multi_lucy.h b/src/USER-DPD/pair_multi_lucy.h index f3c67e4fa4..0a2d2f9885 100644 --- a/src/USER-DPD/pair_multi_lucy.h +++ b/src/USER-DPD/pair_multi_lucy.h @@ -18,7 +18,7 @@ PairStyle(multi/lucy,PairMultiLucy) #else #ifndef LMP_PAIR_MULTI_LUCY_H -#define LMP_PAIR_MUTLI_LUCY_H +#define LMP_PAIR_MULTI_LUCY_H #include "pair.h" diff --git a/src/USER-DPD/pair_multi_lucy_rx.cpp b/src/USER-DPD/pair_multi_lucy_rx.cpp index cd107f1519..431293e823 100644 --- a/src/USER-DPD/pair_multi_lucy_rx.cpp +++ b/src/USER-DPD/pair_multi_lucy_rx.cpp @@ -59,8 +59,7 @@ static const char cite_pair_multi_lucy_rx[] = /* ---------------------------------------------------------------------- */ -PairMultiLucyRX::PairMultiLucyRX(LAMMPS *lmp) : Pair(lmp), - ntables(0), tables(NULL), tabindex(NULL), site1(NULL), site2(NULL) +PairMultiLucyRX::PairMultiLucyRX(LAMMPS *lmp) : Pair(lmp) { if (lmp->citeme) lmp->citeme->add(cite_pair_multi_lucy_rx); @@ -69,6 +68,9 @@ PairMultiLucyRX::PairMultiLucyRX(LAMMPS *lmp) : Pair(lmp), ntables = 0; tables = NULL; + tabindex = NULL; + site1 = site2 = NULL; + comm_forward = 1; comm_reverse = 1; diff --git a/src/USER-DPD/pair_multi_lucy_rx.h b/src/USER-DPD/pair_multi_lucy_rx.h index 596a6c684d..2913716c5a 100644 --- a/src/USER-DPD/pair_multi_lucy_rx.h +++ b/src/USER-DPD/pair_multi_lucy_rx.h @@ -18,7 +18,7 @@ PairStyle(multi/lucy/rx,PairMultiLucyRX) #else #ifndef LMP_PAIR_MULTI_LUCY_RX_H -#define LMP_PAIR_MUTLI_LUCY_RX_H +#define LMP_PAIR_MULTI_LUCY_RX_H #include "pair.h" diff --git a/src/pair_table.h b/src/pair_table.h index 6cfd9df832..358491f7cf 100644 --- a/src/pair_table.h +++ b/src/pair_table.h @@ -30,9 +30,9 @@ class PairTable : public Pair { virtual ~PairTable(); virtual void compute(int, int); - void settings(int, char **); + virtual void settings(int, char **); void coeff(int, char **); - double init_one(int, int); + virtual double init_one(int, int); void write_restart(FILE *); void read_restart(FILE *); void write_restart_settings(FILE *); @@ -58,7 +58,7 @@ class PairTable : public Pair { int **tabindex; - void allocate(); + virtual void allocate(); void read_table(Table *, char *, char *); void param_extract(Table *, char *); void bcast_table(Table *); From f93c62d3e20301ea53e41a5a6f50b8aa9957d942 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 13 Dec 2016 16:54:00 -0700 Subject: [PATCH 008/439] Reverting accidental change --- src/USER-DPD/pair_multi_lucy_rx.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/USER-DPD/pair_multi_lucy_rx.cpp b/src/USER-DPD/pair_multi_lucy_rx.cpp index 431293e823..cd107f1519 100644 --- a/src/USER-DPD/pair_multi_lucy_rx.cpp +++ b/src/USER-DPD/pair_multi_lucy_rx.cpp @@ -59,7 +59,8 @@ static const char cite_pair_multi_lucy_rx[] = /* ---------------------------------------------------------------------- */ -PairMultiLucyRX::PairMultiLucyRX(LAMMPS *lmp) : Pair(lmp) +PairMultiLucyRX::PairMultiLucyRX(LAMMPS *lmp) : Pair(lmp), + ntables(0), tables(NULL), tabindex(NULL), site1(NULL), site2(NULL) { if (lmp->citeme) lmp->citeme->add(cite_pair_multi_lucy_rx); @@ -68,9 +69,6 @@ PairMultiLucyRX::PairMultiLucyRX(LAMMPS *lmp) : Pair(lmp) ntables = 0; tables = NULL; - tabindex = NULL; - site1 = site2 = NULL; - comm_forward = 1; comm_reverse = 1; From 3e2cd6d265db7bbbe97cc2dc00977cead964e67c Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Wed, 14 Dec 2016 11:46:04 -0700 Subject: [PATCH 009/439] Merging from master to 13Dec16 version --- src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp | 1 - src/KOKKOS/pair_exp6_rx_kokkos.cpp | 2 -- src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp | 2 -- src/KOKKOS/pair_table_rx_kokkos.cpp | 35 +---------------------- src/KOKKOS/pair_table_rx_kokkos.h | 10 +------ src/KOKKOS/pair_vashishta_kokkos.cpp | 1 - src/neigh_request.cpp | 1 - src/neigh_request.h | 1 - 8 files changed, 2 insertions(+), 51 deletions(-) diff --git a/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp b/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp index f7e1fecc09..45da5bf165 100644 --- a/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp +++ b/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp @@ -317,7 +317,6 @@ void PairDPDfdtEnergyKokkos::init_style() if (neighflag == HALF || neighflag == HALFTHREAD) { neighbor->requests[irequest]->full = 0; neighbor->requests[irequest]->half = 1; - neighbor->requests[irequest]->full_cluster = 0; } else { error->all(FLERR,"Cannot use chosen neighbor list style with dpd/fdt/energy/kk"); } diff --git a/src/KOKKOS/pair_exp6_rx_kokkos.cpp b/src/KOKKOS/pair_exp6_rx_kokkos.cpp index a7d5569537..569d131af7 100644 --- a/src/KOKKOS/pair_exp6_rx_kokkos.cpp +++ b/src/KOKKOS/pair_exp6_rx_kokkos.cpp @@ -87,12 +87,10 @@ void PairExp6rxKokkos::init_style() if (neighflag == FULL) { neighbor->requests[irequest]->full = 1; neighbor->requests[irequest]->half = 0; - neighbor->requests[irequest]->full_cluster = 0; neighbor->requests[irequest]->ghost = 1; } else if (neighflag == HALF || neighflag == HALFTHREAD) { neighbor->requests[irequest]->full = 0; neighbor->requests[irequest]->half = 1; - neighbor->requests[irequest]->full_cluster = 0; neighbor->requests[irequest]->ghost = 1; } else { error->all(FLERR,"Cannot use chosen neighbor list style with reax/c/kk"); diff --git a/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp b/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp index de70ae86f5..d1a13b12fd 100644 --- a/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp +++ b/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp @@ -101,12 +101,10 @@ void PairMultiLucyRXKokkos::init_style() if (neighflag == FULL) { neighbor->requests[irequest]->full = 1; neighbor->requests[irequest]->half = 0; - neighbor->requests[irequest]->full_cluster = 0; neighbor->requests[irequest]->ghost = 1; } else if (neighflag == HALF || neighflag == HALFTHREAD) { neighbor->requests[irequest]->full = 0; neighbor->requests[irequest]->half = 1; - neighbor->requests[irequest]->full_cluster = 0; neighbor->requests[irequest]->ghost = 1; } else { error->all(FLERR,"Cannot use chosen neighbor list style with reax/c/kk"); diff --git a/src/KOKKOS/pair_table_rx_kokkos.cpp b/src/KOKKOS/pair_table_rx_kokkos.cpp index 4c809d98bd..bf32d1c14f 100644 --- a/src/KOKKOS/pair_table_rx_kokkos.cpp +++ b/src/KOKKOS/pair_table_rx_kokkos.cpp @@ -96,7 +96,7 @@ void PairTableRXKokkos::compute_style(int eflag_in, int vflag_in) eflag = eflag_in; vflag = vflag_in; - if (neighflag == FULL || neighflag == FULLCLUSTER) no_virial_fdotr_compute = 1; + if (neighflag == FULL) no_virial_fdotr_compute = 1; if (eflag || vflag) ev_setup(eflag,vflag); @@ -143,19 +143,6 @@ void PairTableRXKokkos::compute_style(int eflag_in, int vflag_in) f(this,(NeighListKokkos*) list); if (eflag || vflag) Kokkos::parallel_reduce(nlocal,f,ev); else Kokkos::parallel_for(nlocal,f); - } else if (neighflag == FULLCLUSTER) { - typedef PairComputeFunctor,FULLCLUSTER,false,S_TableRXCompute > - f_type; - f_type f(this,(NeighListKokkos*) list); - #ifdef KOKKOS_HAVE_CUDA - const int teamsize = Kokkos::Impl::is_same::value ? 32 : 1; - #else - const int teamsize = 1; - #endif - const int nteams = (list->inum*+teamsize-1)/teamsize; - Kokkos::TeamPolicy config(nteams,teamsize,NeighClusterSize); - if (eflag || vflag) Kokkos::parallel_reduce(config,f,ev); - else Kokkos::parallel_for(config,f); } } else { if (neighflag == FULL) { @@ -178,19 +165,6 @@ void PairTableRXKokkos::compute_style(int eflag_in, int vflag_in) f(this,(NeighListKokkos*) list); if (eflag || vflag) Kokkos::parallel_reduce(nlocal,f,ev); else Kokkos::parallel_for(nlocal,f); - } else if (neighflag == FULLCLUSTER) { - typedef PairComputeFunctor,FULLCLUSTER,true,S_TableRXCompute > - f_type; - f_type f(this,(NeighListKokkos*) list); - #ifdef KOKKOS_HAVE_CUDA - const int teamsize = Kokkos::Impl::is_same::value ? 32 : 1; - #else - const int teamsize = 1; - #endif - const int nteams = (list->inum*+teamsize-1)/teamsize; - Kokkos::TeamPolicy config(nteams,teamsize,NeighClusterSize); - if (eflag || vflag) Kokkos::parallel_reduce(config,f,ev); - else Kokkos::parallel_for(config,f); } } @@ -511,19 +485,12 @@ void PairTableRXKokkos::init_style() if (neighflag == FULL) { neighbor->requests[irequest]->full = 1; neighbor->requests[irequest]->half = 0; - neighbor->requests[irequest]->full_cluster = 0; } else if (neighflag == HALF || neighflag == HALFTHREAD) { neighbor->requests[irequest]->full = 0; neighbor->requests[irequest]->half = 1; - neighbor->requests[irequest]->full_cluster = 0; } else if (neighflag == N2) { neighbor->requests[irequest]->full = 0; neighbor->requests[irequest]->half = 0; - neighbor->requests[irequest]->full_cluster = 0; - } else if (neighflag == FULLCLUSTER) { - neighbor->requests[irequest]->full_cluster = 1; - neighbor->requests[irequest]->full = 1; - neighbor->requests[irequest]->half = 0; } else { error->all(FLERR,"Cannot use chosen neighbor list style with lj/cut/kk"); } diff --git a/src/KOKKOS/pair_table_rx_kokkos.h b/src/KOKKOS/pair_table_rx_kokkos.h index 6f0616cc28..b379901201 100644 --- a/src/KOKKOS/pair_table_rx_kokkos.h +++ b/src/KOKKOS/pair_table_rx_kokkos.h @@ -41,7 +41,7 @@ template class PairTableRXKokkos : public PairTableRX { public: - enum {EnabledNeighFlags=FULL|HALFTHREAD|HALF|N2|FULLCLUSTER}; + enum {EnabledNeighFlags=FULL|HALFTHREAD|HALF|N2}; enum {COUL_FLAG=0}; typedef DeviceType device_type; @@ -141,45 +141,37 @@ class PairTableRXKokkos : public PairTableRX { friend class PairComputeFunctor >; friend class PairComputeFunctor >; friend class PairComputeFunctor >; - friend class PairComputeFunctor >; friend class PairComputeFunctor >; friend class PairComputeFunctor >; friend class PairComputeFunctor >; friend class PairComputeFunctor >; - friend class PairComputeFunctor >; friend class PairComputeFunctor >; friend class PairComputeFunctor >; friend class PairComputeFunctor >; friend class PairComputeFunctor >; - friend class PairComputeFunctor >; friend class PairComputeFunctor >; friend class PairComputeFunctor >; friend class PairComputeFunctor >; friend class PairComputeFunctor >; - friend class PairComputeFunctor >; friend class PairComputeFunctor >; friend class PairComputeFunctor >; friend class PairComputeFunctor >; friend class PairComputeFunctor >; - friend class PairComputeFunctor >; friend class PairComputeFunctor >; friend class PairComputeFunctor >; friend class PairComputeFunctor >; friend class PairComputeFunctor >; - friend class PairComputeFunctor >; friend class PairComputeFunctor >; friend class PairComputeFunctor >; friend class PairComputeFunctor >; friend class PairComputeFunctor >; - friend class PairComputeFunctor >; friend class PairComputeFunctor >; friend class PairComputeFunctor >; friend class PairComputeFunctor >; friend class PairComputeFunctor >; - friend class PairComputeFunctor >; friend void pair_virial_fdotr_compute(PairTableRXKokkos*); }; diff --git a/src/KOKKOS/pair_vashishta_kokkos.cpp b/src/KOKKOS/pair_vashishta_kokkos.cpp index 73e4e04f98..bf3b5bae85 100644 --- a/src/KOKKOS/pair_vashishta_kokkos.cpp +++ b/src/KOKKOS/pair_vashishta_kokkos.cpp @@ -603,7 +603,6 @@ void PairVashishtaKokkos::init_style() if (neighflag == FULL || neighflag == HALF || neighflag == HALFTHREAD) { neighbor->requests[irequest]->full = 1; neighbor->requests[irequest]->half = 0; - neighbor->requests[irequest]->full_cluster = 0; if (neighflag == FULL) neighbor->requests[irequest]->ghost = 1; else diff --git a/src/neigh_request.cpp b/src/neigh_request.cpp index 4a3eb14933..a8ba8496cd 100644 --- a/src/neigh_request.cpp +++ b/src/neigh_request.cpp @@ -39,7 +39,6 @@ NeighRequest::NeighRequest(LAMMPS *lmp) : Pointers(lmp) gran = granhistory = 0; respainner = respamiddle = respaouter = 0; half_from_full = 0; - full_cluster = 0; // only set when command = 1; diff --git a/src/neigh_request.h b/src/neigh_request.h index 0b561710e7..62cb11f830 100644 --- a/src/neigh_request.h +++ b/src/neigh_request.h @@ -47,7 +47,6 @@ class NeighRequest : protected Pointers { int respainner; // 1 if a rRESPA inner list int respamiddle; // 1 if a rRESPA middle list int respaouter; // 1 if a rRESPA outer list - int full_cluster; // only used by Kokkos pair styles // command_style only set if command = 1 // allows print_pair_info() to access command name From a9d26b3f4aadbf8e7a7aa91190d513b6a02217d2 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Wed, 14 Dec 2016 12:58:02 -0700 Subject: [PATCH 010/439] Updates to Kokkos files --- src/KOKKOS/fix_eos_table_rx_kokkos.cpp | 143 ++++++++++++++--------- src/KOKKOS/fix_eos_table_rx_kokkos.h | 21 ++++ src/KOKKOS/pair_exp6_rx_kokkos.cpp | 16 ++- src/KOKKOS/pair_exp6_rx_kokkos.h | 2 + src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp | 33 +++--- src/KOKKOS/pair_multi_lucy_rx_kokkos.h | 2 + 6 files changed, 145 insertions(+), 72 deletions(-) diff --git a/src/KOKKOS/fix_eos_table_rx_kokkos.cpp b/src/KOKKOS/fix_eos_table_rx_kokkos.cpp index a1e0b1a07d..faf490fcc0 100644 --- a/src/KOKKOS/fix_eos_table_rx_kokkos.cpp +++ b/src/KOKKOS/fix_eos_table_rx_kokkos.cpp @@ -42,6 +42,9 @@ FixEOStableRXKokkos::FixEOStableRXKokkos(LAMMPS *lmp, int narg, char execution_space = ExecutionSpaceFromDevice::space; datamask_read = X_MASK | F_MASK | TYPE_MASK | ENERGY_MASK | VIRIAL_MASK; datamask_modify = F_MASK | ENERGY_MASK | VIRIAL_MASK; + + k_error_flag = DAT::tdual_int_scalar("fix:error_flag"); + k_warning_flag = DAT::tdual_int_scalar("fix:warning_flag"); } /* ---------------------------------------------------------------------- */ @@ -65,22 +68,33 @@ void FixEOStableRXKokkos::setup(int vflag) dpdTheta= atomKK->k_dpdTheta.view(); uCG = atomKK->k_uCG.view(); uCGnew = atomKK->k_uCGnew.view(); - double duChem; - for (int i = 0; i < nlocal; i++) // parallel_for - if (mask[i] & groupbit){ - duChem = uCG[i] - uCGnew[i]; - uChem[i] += duChem; - uCG[i] = 0.0; - uCGnew[i] = 0.0; - } + Kokkos::parallel_for(Kokkos::RangePolicy(0,nlocal),*this); // Communicate the updated momenta and velocities to all nodes comm->forward_comm_fix(this); - for (int i = 0; i < nlocal; i++) // parallel_for - if (mask[i] & groupbit) - temperature_lookup(i,uCond[i]+uMech[i]+uChem[i],dpdTheta[i]); + Kokkos::parallel_for(Kokkos::RangePolicy(0,nlocal),*this); + + error_check(); +} + +template +KOKKOS_INLINE_FUNCTION +void FixEOStableRXKokkos::operator()(TagFixEOStableRXSetup, const int &i) const { + if (mask[i] & groupbit) { + const double duChem = uCG[i] - uCGnew[i]; + uChem[i] += duChem; + uCG[i] = 0.0; + uCGnew[i] = 0.0; + } +} + +template +KOKKOS_INLINE_FUNCTION +void FixEOStableRXKokkos::operator()(TagFixEOStableRXTemperatureLookup, const int &i) const { + if (mask[i] & groupbit) + temperature_lookup(i,uCond[i]+uMech[i]+uChem[i],dpdTheta[i]); } /* ---------------------------------------------------------------------- */ @@ -94,25 +108,28 @@ void FixEOStableRXKokkos::init() uMech = atomKK->k_uMech.view(); uChem = atomKK->k_uChem.view(); dpdTheta= atomKK->k_dpdTheta.view(); - double tmp; - if(this->restart_reset){ - for (int i = 0; i < nlocal; i++) - if (mask[i] & groupbit) - temperature_lookup(i,uCond[i]+uMech[i]+uChem[i],dpdTheta[i]); - } else { - for (int i = 0; i < nlocal; i++) - if (mask[i] & groupbit) { - if(dpdTheta[i] <= 0.0) - error->one(FLERR,"Internal temperature <= zero"); - energy_lookup(i,dpdTheta[i],tmp); - uCond[i] = tmp / 2.0; - uMech[i] = tmp / 2.0; - uChem[i] = 0.0; - } - } + if (this->restart_reset) + Kokkos::parallel_for(Kokkos::RangePolicy(0,nlocal),*this); + else + Kokkos::parallel_for(Kokkos::RangePolicy(0,nlocal),*this); + + error_check(); } +template +KOKKOS_INLINE_FUNCTION +void FixEOStableRXKokkos::operator()(TagFixEOStableRXInit, const int &i) const { + double tmp; + if (mask[i] & groupbit) { + if(dpdTheta[i] <= 0.0) + k_error_flag.d_view() = 1; + energy_lookup(i,dpdTheta[i],tmp); + uCond[i] = tmp / 2.0; + uMech[i] = tmp / 2.0; + uChem[i] = 0.0; + } +} /* ---------------------------------------------------------------------- */ @@ -126,12 +143,19 @@ void FixEOStableRXKokkos::post_integrate() uChem = atomKK->k_uChem.view(); dpdTheta= atomKK->k_dpdTheta.view(); - for (int i = 0; i < nlocal; i++) - if (mask[i] & groupbit){ - temperature_lookup(i,uCond[i]+uMech[i]+uChem[i],dpdTheta[i]); - if(dpdTheta[i] <= 0.0) - error->one(FLERR,"Internal temperature <= zero"); - } + Kokkos::parallel_for(Kokkos::RangePolicy(0,nlocal),*this); + + error_check(); +} + +template +KOKKOS_INLINE_FUNCTION +void FixEOStableRXKokkos::operator()(TagFixEOStableRXTemperatureLookup2, const int &i) const { + if (mask[i] & groupbit){ + temperature_lookup(i,uCond[i]+uMech[i]+uChem[i],dpdTheta[i]); + if (dpdTheta[i] <= 0.0) + k_error_flag.d_view() = 1; + } } /* ---------------------------------------------------------------------- */ @@ -152,23 +176,14 @@ void FixEOStableRXKokkos::end_of_step() // Communicate the ghost uCGnew comm->reverse_comm_fix(this); - for (int i = 0; i < nlocal; i++) - if (mask[i] & groupbit){ - duChem = uCG[i] - uCGnew[i]; - uChem[i] += duChem; - uCG[i] = 0.0; - uCGnew[i] = 0.0; - } + Kokkos::parallel_for(Kokkos::RangePolicy(0,nlocal),*this); // Communicate the updated momenta and velocities to all nodes comm->forward_comm_fix(this); - for (int i = 0; i < nlocal; i++) - if (mask[i] & groupbit){ - temperature_lookup(i,uCond[i]+uMech[i]+uChem[i],dpdTheta[i]); - if(dpdTheta[i] <= 0.0) - error->one(FLERR,"Internal temperature <= zero"); - } + Kokkos::parallel_for(Kokkos::RangePolicy(0,nlocal),*this); + + error_check(); } /* ---------------------------------------------------------------------- @@ -242,13 +257,11 @@ void FixEOStableRXKokkos::temperature_lookup(int id, double ui, doub // Apply the Secant Method for(it=0; itone(FLERR,"NaN detected in secant solver."); + if(isnan(f1) || isnan(f2)) k_error_flag.d_view() = 2; temp = t1; temp = MAX(temp,tb->lo); temp = MIN(temp,tb->hi); - char str[256]; - sprintf(str,"Secant solver did not converge because table bounds were exceeded: it=%d id=%d ui=%lf thetai=%lf t1=%lf t2=%lf f1=%lf f2=%lf dpdTheta=%lf\n",it,id,ui,thetai,t1,t2,f1,f2,temp); - error->warning(FLERR,str); + k_warning_flag.d_view() = 1; break; } temp = t2 - f2*(t2-t1)/(f2-f1); @@ -260,11 +273,9 @@ void FixEOStableRXKokkos::temperature_lookup(int id, double ui, doub f2 = u2 - ui; } if(it==maxit){ - char str[256]; - sprintf(str,"Maxit exceeded in secant solver: id=%d ui=%lf thetai=%lf t1=%lf t2=%lf f1=%lf f2=%lf\n",id,ui,thetai,t1,t2,f1,f2); if(isnan(f1) || isnan(f2) || isnan(ui) || isnan(thetai) || isnan(t1) || isnan(t2)) - error->one(FLERR,"NaN detected in secant solver."); - error->one(FLERR,str); + k_error_flag.d_view() = 2; + k_error_flag.d_view() = 3; } thetai = temp; } @@ -346,6 +357,30 @@ void FixEOStableRXKokkos::unpack_reverse_comm(int n, int *list, doub /* ---------------------------------------------------------------------- */ +template +void FixEOStableRXKokkos::error_check() +{ + k_error_flag.template modify(); + k_error_flag.template sync(); + if (k_error_flag.h_view() == 1) + error->one(FLERR,"Internal temperature <= zero"); + else if (k_error_flag.h_view() == 2) + error->one(FLERR,"NaN detected in secant solver."); + else if (k_error_flag.h_view() == 3) + error->one(FLERR,"Maxit exceeded in secant solver."); + + k_warning_flag.template modify(); + k_warning_flag.template sync(); + if (k_warning_flag.h_view()) { + error->warning(FLERR,"Secant solver did not converge because table bounds were exceeded."); + k_warning_flag.h_view() = 0; + k_warning_flag.template modify(); + k_warning_flag.template sync(); + } +} + +/* ---------------------------------------------------------------------- */ + namespace LAMMPS_NS { template class FixEOStableRXKokkos; #ifdef KOKKOS_HAVE_CUDA diff --git a/src/KOKKOS/fix_eos_table_rx_kokkos.h b/src/KOKKOS/fix_eos_table_rx_kokkos.h index 9eccd67c54..9b0ca366a0 100644 --- a/src/KOKKOS/fix_eos_table_rx_kokkos.h +++ b/src/KOKKOS/fix_eos_table_rx_kokkos.h @@ -27,6 +27,11 @@ FixStyle(eos/table/rx/kk/host,FixEOStableRXKokkos) namespace LAMMPS_NS { +struct TagFixEOStableRXInit{}; +struct TagFixEOStableRXSetup{}; +struct TagFixEOStableRXTemperatureLookup{}; +struct TagFixEOStableRXTemperatureLookup2{}; + template class FixEOStableRXKokkos : public FixEOStableRX { public: @@ -41,6 +46,18 @@ class FixEOStableRXKokkos : public FixEOStableRX { void post_integrate(); void end_of_step(); + KOKKOS_INLINE_FUNCTION + void operator()(TagFixEOStableRXInit, const int&) const; + + KOKKOS_INLINE_FUNCTION + void operator()(TagFixEOStableRXSetup, const int&) const; + + KOKKOS_INLINE_FUNCTION + void operator()(TagFixEOStableRXTemperatureLookup, const int&) const; + + KOKKOS_INLINE_FUNCTION + void operator()(TagFixEOStableRXTemperatureLookup2, const int&) const; + KOKKOS_INLINE_FUNCTION void energy_lookup(int, double, double &) const; @@ -59,12 +76,16 @@ class FixEOStableRXKokkos : public FixEOStableRX { //Table *tables, *tables2; void allocate(); + void error_check(); //double *dHf; typename AT::t_int_1d mask; typename AT::t_efloat_1d uCond,uMech,uChem,uCG,uCGnew,rho,dpdTheta,duChem; + DAT::tdual_int_scalar k_error_flag; + DAT::tdual_int_scalar k_warning_flag; + int pack_reverse_comm(int, int, double *); void unpack_reverse_comm(int, int *, double *); int pack_forward_comm(int , int *, double *, int, int *); diff --git a/src/KOKKOS/pair_exp6_rx_kokkos.cpp b/src/KOKKOS/pair_exp6_rx_kokkos.cpp index 569d131af7..c46f3d037d 100644 --- a/src/KOKKOS/pair_exp6_rx_kokkos.cpp +++ b/src/KOKKOS/pair_exp6_rx_kokkos.cpp @@ -56,6 +56,8 @@ PairExp6rxKokkos::PairExp6rxKokkos(LAMMPS *lmp) : PairExp6rx(lmp) execution_space = ExecutionSpaceFromDevice::space; datamask_read = X_MASK | F_MASK | TYPE_MASK | ENERGY_MASK | VIRIAL_MASK; datamask_modify = F_MASK | ENERGY_MASK | VIRIAL_MASK; + + k_error_flag = DAT::tdual_int_scalar("pair:error_flag"); } /* ---------------------------------------------------------------------- */ @@ -168,6 +170,11 @@ void PairExp6rxKokkos::compute(int eflag_in, int vflag_in) Kokkos::parallel_for(Kokkos::RangePolicy(0,np_total),*this); } + k_error_flag.template modify(); + k_error_flag.template sync(); + if (k_error_flag.h_view()) + error->all(FLERR,"The number of molecules in CG particle is less than 1e-8."); + int inum = list->inum; NeighListKokkos* k_list = static_cast*>(list); d_numneigh = k_list->d_numneigh; @@ -184,6 +191,11 @@ void PairExp6rxKokkos::compute(int eflag_in, int vflag_in) Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); } + k_error_flag.template modify(); + k_error_flag.template sync(); + if (k_error_flag.h_view()) + error->all(FLERR,"alpha_ij is 6.0 in pair exp6"); + if (eflag_global) eng_vdwl += ev.evdwl; if (vflag_global) { virial[0] += ev.v[0]; @@ -358,7 +370,7 @@ void PairExp6rxKokkos::operator()(TagPairExp6rxComputeall(FLERR,"alpha_ij is 6.0 in pair exp6"); + k_error_flag.d_view() = 1; // A3. Compute some convenient quantities for evaluating the force rminv = 1.0/rmOld12_ij; @@ -774,7 +786,7 @@ void PairExp6rxKokkos::getParamsEXP6(int id,double &epsilon1,double } } if(nTotal < 1e-8 || nTotal_old < 1e-8) - error->all(FLERR,"The number of molecules in CG particle is less than 1e-8."); + k_error_flag.d_view() = 1; // Compute the mole fraction of molecules within the fluid portion of the particle (One Fluid Approximation) fractionOFA_old = nTotalOFA_old / nTotal_old; diff --git a/src/KOKKOS/pair_exp6_rx_kokkos.h b/src/KOKKOS/pair_exp6_rx_kokkos.h index b0fbd3d9e5..366cf99d75 100644 --- a/src/KOKKOS/pair_exp6_rx_kokkos.h +++ b/src/KOKKOS/pair_exp6_rx_kokkos.h @@ -103,6 +103,8 @@ class PairExp6rxKokkos : public PairExp6rx { DAT::t_efloat_1d d_eatom; DAT::t_virial_array d_vatom; + DAT::tdual_int_scalar k_error_flag; + typename AT::t_neighbors_2d d_neighbors; typename AT::t_int_1d_randomread d_ilist; typename AT::t_int_1d_randomread d_numneigh; diff --git a/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp b/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp index d1a13b12fd..bea7cb6b0b 100644 --- a/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp +++ b/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp @@ -70,6 +70,8 @@ PairMultiLucyRXKokkos::PairMultiLucyRXKokkos(LAMMPS *lmp) : PairMult execution_space = ExecutionSpaceFromDevice::space; datamask_read = X_MASK | F_MASK | TYPE_MASK | ENERGY_MASK | VIRIAL_MASK; datamask_modify = F_MASK | ENERGY_MASK | VIRIAL_MASK; + + k_error_flag = DAT::tdual_int_scalar("pair:error_flag"); } /* ---------------------------------------------------------------------- */ @@ -180,6 +182,15 @@ void PairMultiLucyRXKokkos::compute(int eflag_in, int vflag_in) Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); } + k_error_flag.template modify(); + k_error_flag.template sync(); + if (k_error_flag.h_view() == 1) + error->one(FLERR,"Density < table inner cutoff"); + else if (k_error_flag.h_view() == 2) + error->one(FLERR,"Density > table outer cutoff"); + else if (k_error_flag.h_view() == 3) + error->one(FLERR,"Only LOOKUP and LINEAR table styles have been implemented for pair multi/lucy/rx"); + if (eflag_global) eng_vdwl += ev.evdwl; if (vflag_global) { virial[0] += ev.v[0]; @@ -265,19 +276,13 @@ void PairMultiLucyRXKokkos::operator()(TagPairMultiLucyRXComputeinnersq || rho[j]*rho[j] < tb->innersq){ - //printf("Table inner cutoff = %lf\n",sqrt(tb->innersq)); - //printf("rho[%d]=%lf\n",i,rho[i]); - //printf("rho[%d]=%lf\n",j,rho[j]); - error->one(FLERR,"Density < table inner cutoff"); + k_error_flag.d_view() = 1; } if (tabstyle == LOOKUP) { itable = static_cast (((rho[i]*rho[i]) - tb->innersq) * tb->invdelta); jtable = static_cast (((rho[j]*rho[j]) - tb->innersq) * tb->invdelta); if (itable >= tlm1 || jtable >= tlm1){ - //printf("Table outer index = %d\n",tlm1); - //printf("itableIndex=%d rho[%d]=%lf\n",itable,i,rho[i]); - //printf("jtableIndex=%d rho[%d]=%lf\n",jtable,j,rho[j]); - error->one(FLERR,"Density > table outer cutoff"); + k_error_flag.d_view() = 2; } A_i = tb->f[itable]; A_j = tb->f[jtable]; @@ -290,10 +295,7 @@ void PairMultiLucyRXKokkos::operator()(TagPairMultiLucyRXCompute ((rho[i]*rho[i] - tb->innersq) * tb->invdelta); jtable = static_cast (((rho[j]*rho[j]) - tb->innersq) * tb->invdelta); if (itable >= tlm1 || jtable >= tlm1){ - //printf("Table outer index = %d\n",tlm1); - //printf("itableIndex=%d rho[%d]=%lf\n",itable,i,rho[i]); - //printf("jtableIndex=%d rho[%d]=%lf\n",jtable,j,rho[j]); - error->one(FLERR,"Density > table outer cutoff"); + k_error_flag.d_view() = 2; } if(itable<0) itable=0; if(itable>=tlm1) itable=tlm1; @@ -314,7 +316,7 @@ void PairMultiLucyRXKokkos::operator()(TagPairMultiLucyRXComputeone(FLERR,"Only LOOKUP and LINEAR table styles have been implemented for pair multi/lucy/rx"); + } else k_error_flag.d_view() = 3; if (isite1 == isite2) fpair = sqrt(fractionOld1_i*fractionOld2_j)*fpair; else fpair = (sqrt(fractionOld1_i*fractionOld2_j) + sqrt(fractionOld2_i*fractionOld1_j))*fpair; @@ -341,13 +343,12 @@ void PairMultiLucyRXKokkos::operator()(TagPairMultiLucyRXComputee[itable]; else if (tabstyle == LINEAR){ if (itable >= tlm1){ - //printf("itableIndex=%d rho[%d]=%lf\n",itable,i,rho[i]); - error->one(FLERR,"Density > table outer cutoff"); + k_error_flag.d_view() = 2; } if(itable==0) fraction_i=0.0; else fraction_i = (((rho[i]*rho[i]) - tb->rsq[itable]) * tb->invdelta); evdwl = tb->e[itable] + fraction_i*tb->de[itable]; - } else error->one(FLERR,"Only LOOKUP and LINEAR table styles have been implemented for pair multi/lucy/rx"); + } else k_error_flag.d_view() = 3; evdwl *=(pi*d_cutsq(itype,itype)*d_cutsq(itype,itype))/84.0; evdwlOld = fractionOld1_i*evdwl; diff --git a/src/KOKKOS/pair_multi_lucy_rx_kokkos.h b/src/KOKKOS/pair_multi_lucy_rx_kokkos.h index 74a10ddee1..ff22516eb1 100644 --- a/src/KOKKOS/pair_multi_lucy_rx_kokkos.h +++ b/src/KOKKOS/pair_multi_lucy_rx_kokkos.h @@ -130,6 +130,8 @@ class PairMultiLucyRXKokkos : public PairMultiLucyRX { typename AT::t_int_1d_randomread d_ilist; typename AT::t_int_1d_randomread d_numneigh; + DAT::tdual_int_scalar k_error_flag; + typename AT::tdual_ffloat_2d k_cutsq; typename AT::t_ffloat_2d d_cutsq; From c0d6cbbdd3f135578b584525c92e447c663e2e1b Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Thu, 15 Dec 2016 11:18:50 -0700 Subject: [PATCH 011/439] Updates to Kokkos files --- src/KOKKOS/atom_vec_dpd_kokkos.cpp | 72 ++++ src/KOKKOS/fix_eos_table_rx_kokkos.cpp | 2 +- src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp | 3 + src/KOKKOS/pair_exp6_rx_kokkos.cpp | 68 ++- src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp | 490 ++++++++++++++-------- src/KOKKOS/pair_multi_lucy_rx_kokkos.h | 79 +++- src/USER-DPD/fix_eos_table_rx.cpp | 2 + src/USER-DPD/pair_multi_lucy_rx.cpp | 2 + src/USER-DPD/pair_table_rx.cpp | 2 + src/atom_masks.h | 12 + 10 files changed, 533 insertions(+), 199 deletions(-) diff --git a/src/KOKKOS/atom_vec_dpd_kokkos.cpp b/src/KOKKOS/atom_vec_dpd_kokkos.cpp index c79559172f..58fc9c46c3 100644 --- a/src/KOKKOS/atom_vec_dpd_kokkos.cpp +++ b/src/KOKKOS/atom_vec_dpd_kokkos.cpp @@ -1801,6 +1801,15 @@ void AtomVecDPDKokkos::sync(ExecutionSpace space, unsigned int mask) if (mask & TYPE_MASK) atomKK->k_type.sync(); if (mask & MASK_MASK) atomKK->k_mask.sync(); if (mask & IMAGE_MASK) atomKK->k_image.sync(); + if (mask & DPDRHO_MASK) atomKK->k_rho.sync(); + if (mask & DPDTHETA_MASK) atomKK->k_dpdTheta.sync(); + if (mask & UCOND_MASK) atomKK->k_uCond.sync(); + if (mask & UMECH_MASK) atomKK->k_uMech.sync(); + if (mask & UCHEM_MASK) atomKK->k_uChem.sync(); + if (mask & UCG_MASK) atomKK->k_uCG.sync(); + if (mask & UCGNEW_MASK) atomKK->k_uCGnew.sync(); + if (mask & DUCHEM_MASK) atomKK->k_duChem.sync(); + if (mask & DVECTOR_MASK) atomKK->k_dvector.sync(); } else { if (mask & X_MASK) atomKK->k_x.sync(); if (mask & V_MASK) atomKK->k_v.sync(); @@ -1809,6 +1818,15 @@ void AtomVecDPDKokkos::sync(ExecutionSpace space, unsigned int mask) if (mask & TYPE_MASK) atomKK->k_type.sync(); if (mask & MASK_MASK) atomKK->k_mask.sync(); if (mask & IMAGE_MASK) atomKK->k_image.sync(); + if (mask & DPDRHO_MASK) atomKK->k_rho.sync(); + if (mask & DPDTHETA_MASK) atomKK->k_dpdTheta.sync(); + if (mask & UCOND_MASK) atomKK->k_uCond.sync(); + if (mask & UMECH_MASK) atomKK->k_uMech.sync(); + if (mask & UCHEM_MASK) atomKK->k_uChem.sync(); + if (mask & UCG_MASK) atomKK->k_uCG.sync(); + if (mask & UCGNEW_MASK) atomKK->k_uCGnew.sync(); + if (mask & DUCHEM_MASK) atomKK->k_duChem.sync(); + if (mask & DVECTOR_MASK) atomKK->k_dvector.sync(); } } @@ -1831,6 +1849,24 @@ void AtomVecDPDKokkos::sync_overlapping_device(ExecutionSpace space, unsigned in perform_async_copy(atomKK->k_mask,space); if ((mask & IMAGE_MASK) && atomKK->k_image.need_sync()) perform_async_copy(atomKK->k_image,space); + if ((mask & DPDRHO_MASK) && atomKK->k_rho.need_sync()) + perform_async_copy(atomKK->k_rho,space); + if ((mask & DPDTHETA_MASK) && atomKK->k_dpdTheta.need_sync()) + perform_async_copy(atomKK->k_dpdTheta,space); + if ((mask & UCOND_MASK) && atomKK->k_uCond.need_sync()) + perform_async_copy(atomKK->k_uCond,space); + if ((mask & UMECH_MASK) && atomKK->k_uMech.need_sync()) + perform_async_copy(atomKK->k_uMech,space); + if ((mask & UCHEM_MASK) && atomKK->k_uChem.need_sync()) + perform_async_copy(atomKK->k_uChem,space); + if ((mask & UCG_MASK) && atomKK->k_uCG.need_sync()) + perform_async_copy(atomKK->k_uCG,space); + if ((mask & UCGNEW_MASK) && atomKK->k_uCGnew.need_sync()) + perform_async_copy(atomKK->k_uCGnew,space); + if ((mask & DUCHEM_MASK) && atomKK->k_duChem.need_sync()) + perform_async_copy(atomKK->k_duChem,space); + if ((mask & DVECTOR_MASK) && atomKK->k_dvector.need_sync()) + perform_async_copy(atomKK->k_dvector,space); } else { if ((mask & X_MASK) && atomKK->k_x.need_sync()) perform_async_copy(atomKK->k_x,space); @@ -1846,6 +1882,24 @@ void AtomVecDPDKokkos::sync_overlapping_device(ExecutionSpace space, unsigned in perform_async_copy(atomKK->k_mask,space); if ((mask & IMAGE_MASK) && atomKK->k_image.need_sync()) perform_async_copy(atomKK->k_image,space); + if ((mask & DPDRHO_MASK) && atomKK->k_rho.need_sync()) + perform_async_copy(atomKK->k_rho,space); + if ((mask & DPDTHETA_MASK) && atomKK->k_dpdTheta.need_sync()) + perform_async_copy(atomKK->k_dpdTheta,space); + if ((mask & UCOND_MASK) && atomKK->k_uCond.need_sync()) + perform_async_copy(atomKK->k_uCond,space); + if ((mask & UMECH_MASK) && atomKK->k_uMech.need_sync()) + perform_async_copy(atomKK->k_uMech,space); + if ((mask & UCHEM_MASK) && atomKK->k_uChem.need_sync()) + perform_async_copy(atomKK->k_uChem,space); + if ((mask & UCG_MASK) && atomKK->k_uCG.need_sync()) + perform_async_copy(atomKK->k_uCG,space); + if ((mask & UCGNEW_MASK) && atomKK->k_uCGnew.need_sync()) + perform_async_copy(atomKK->k_uCGnew,space); + if ((mask & DUCHEM_MASK) && atomKK->k_duChem.need_sync()) + perform_async_copy(atomKK->k_duChem,space); + if ((mask & DVECTOR_MASK) && atomKK->k_dvector.need_sync()) + perform_async_copy(atomKK->k_dvector,space); } } @@ -1861,6 +1915,15 @@ void AtomVecDPDKokkos::modified(ExecutionSpace space, unsigned int mask) if (mask & TYPE_MASK) atomKK->k_type.modify(); if (mask & MASK_MASK) atomKK->k_mask.modify(); if (mask & IMAGE_MASK) atomKK->k_image.modify(); + if (mask & DPDRHO_MASK) atomKK->k_rho.modify(); + if (mask & DPDTHETA_MASK) atomKK->k_dpdTheta.modify(); + if (mask & UCOND_MASK) atomKK->k_uCond.modify(); + if (mask & UMECH_MASK) atomKK->k_uMech.modify(); + if (mask & UCHEM_MASK) atomKK->k_uChem.modify(); + if (mask & UCG_MASK) atomKK->k_uCG.modify(); + if (mask & UCGNEW_MASK) atomKK->k_uCGnew.modify(); + if (mask & DUCHEM_MASK) atomKK->k_duChem.modify(); + if (mask & DVECTOR_MASK) atomKK->k_dvector.modify(); } else { if (mask & X_MASK) atomKK->k_x.modify(); if (mask & V_MASK) atomKK->k_v.modify(); @@ -1869,6 +1932,15 @@ void AtomVecDPDKokkos::modified(ExecutionSpace space, unsigned int mask) if (mask & TYPE_MASK) atomKK->k_type.modify(); if (mask & MASK_MASK) atomKK->k_mask.modify(); if (mask & IMAGE_MASK) atomKK->k_image.modify(); + if (mask & DPDRHO_MASK) atomKK->k_rho.modify(); + if (mask & DPDTHETA_MASK) atomKK->k_dpdTheta.modify(); + if (mask & UCOND_MASK) atomKK->k_uCond.modify(); + if (mask & UMECH_MASK) atomKK->k_uMech.modify(); + if (mask & UCHEM_MASK) atomKK->k_uChem.modify(); + if (mask & UCG_MASK) atomKK->k_uCG.modify(); + if (mask & UCGNEW_MASK) atomKK->k_uCGnew.modify(); + if (mask & DUCHEM_MASK) atomKK->k_duChem.modify(); + if (mask & DVECTOR_MASK) atomKK->k_dvector.modify(); } } diff --git a/src/KOKKOS/fix_eos_table_rx_kokkos.cpp b/src/KOKKOS/fix_eos_table_rx_kokkos.cpp index faf490fcc0..75e9b292f9 100644 --- a/src/KOKKOS/fix_eos_table_rx_kokkos.cpp +++ b/src/KOKKOS/fix_eos_table_rx_kokkos.cpp @@ -52,7 +52,7 @@ FixEOStableRXKokkos::FixEOStableRXKokkos(LAMMPS *lmp, int narg, char template FixEOStableRXKokkos::~FixEOStableRXKokkos() { - + if (copymode) return; } /* ---------------------------------------------------------------------- */ diff --git a/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp b/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp index 45da5bf165..0bfbb9491e 100644 --- a/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp +++ b/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp @@ -52,6 +52,8 @@ PairDPDfdtEnergyKokkos::PairDPDfdtEnergyKokkos(LAMMPS *lmp) : PairDP { atomKK = (AtomKokkos *) atom; execution_space = ExecutionSpaceFromDevice::space; + datamask_read = X_MASK | F_MASK | TYPE_MASK | TAG_MASK | ENERGY_MASK | VIRIAL_MASK; + datamask_modify = F_MASK | ENERGY_MASK | VIRIAL_MASK; cutsq = NULL; } @@ -357,6 +359,7 @@ double PairDPDfdtEnergyKokkos::init_one(int i, int j) m_cutsq[j][i] = m_cutsq[i][j] = cutone*cutone; } k_cutsq.h_view(i,j) = cutone*cutone; + k_cutsq.h_view(j,i) = k_cutsq.h_view(i,j); k_cutsq.template modify(); return cutone; diff --git a/src/KOKKOS/pair_exp6_rx_kokkos.cpp b/src/KOKKOS/pair_exp6_rx_kokkos.cpp index c46f3d037d..7e74f39ef0 100644 --- a/src/KOKKOS/pair_exp6_rx_kokkos.cpp +++ b/src/KOKKOS/pair_exp6_rx_kokkos.cpp @@ -54,8 +54,8 @@ PairExp6rxKokkos::PairExp6rxKokkos(LAMMPS *lmp) : PairExp6rx(lmp) { atomKK = (AtomKokkos *) atom; execution_space = ExecutionSpaceFromDevice::space; - datamask_read = X_MASK | F_MASK | TYPE_MASK | ENERGY_MASK | VIRIAL_MASK; - datamask_modify = F_MASK | ENERGY_MASK | VIRIAL_MASK; + datamask_read = EMPTY_MASK; + datamask_modify = EMPTY_MASK; k_error_flag = DAT::tdual_int_scalar("pair:error_flag"); } @@ -104,6 +104,8 @@ void PairExp6rxKokkos::init_style() template void PairExp6rxKokkos::compute(int eflag_in, int vflag_in) { + copymode = 1; + eflag = eflag_in; vflag = vflag_in; @@ -141,7 +143,9 @@ void PairExp6rxKokkos::compute(int eflag_in, int vflag_in) special_coul[3] = force->special_coul[3]; newton_pair = force->newton_pair; - copymode = 1; + atomKK->sync(execution_space,X_MASK | F_MASK | TYPE_MASK | ENERGY_MASK | VIRIAL_MASK | UCG_MASK | UCGNEW_MASK | DVECTOR_MASK); + if (evflag) atomKK->modified(execution_space,F_MASK | ENERGY_MASK | VIRIAL_MASK | UCG_MASK | UCGNEW_MASK); + else atomKK->modified(execution_space,F_MASK | UCG_MASK | UCGNEW_MASK); // Initialize the Exp6 parameter data for both the local // and ghost atoms. Make the parameter data persistent @@ -185,10 +189,22 @@ void PairExp6rxKokkos::compute(int eflag_in, int vflag_in) EV_FLOAT ev; - if (evflag) { - Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); - } else { - Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + if (neighflag == HALF) { + if (newton_pair) { + if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } else { + if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } + } else if (neighflag == HALFTHREAD) { + if (newton_pair) { + if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } else { + if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } } k_error_flag.template modify(); @@ -246,6 +262,12 @@ template template KOKKOS_INLINE_FUNCTION void PairExp6rxKokkos::operator()(TagPairExp6rxCompute, const int &ii, EV_FLOAT& ev) const { + + // These arrays are atomic for Half/Thread neighbor style + Kokkos::View::value> > a_f = f; + Kokkos::View::value> > a_uCG = uCG; + Kokkos::View::value> > a_uCGnew = uCGnew; + int i,j,jj,jnum,itype,jtype; double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,evdwlOld,fpair; double rsq,r2inv,r6inv,forceExp6,factor_lj; @@ -287,6 +309,12 @@ void PairExp6rxKokkos::operator()(TagPairExp6rxCompute::operator()(TagPairExp6rxCompute::operator()(TagPairExp6rxComputetemplate ev_tally(ev,i,j,evdwl,fpair,delx,dely,delz); } } } + + a_f(i,0) += fx_i; + a_f(i,1) += fy_i; + a_f(i,2) += fz_i; + a_uCG[i] += uCG_i; + a_uCGnew[i] += uCGnew_i; } template diff --git a/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp b/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp index bea7cb6b0b..03bbaf9907 100644 --- a/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp +++ b/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp @@ -68,8 +68,14 @@ PairMultiLucyRXKokkos::PairMultiLucyRXKokkos(LAMMPS *lmp) : PairMult atomKK = (AtomKokkos *) atom; execution_space = ExecutionSpaceFromDevice::space; - datamask_read = X_MASK | F_MASK | TYPE_MASK | ENERGY_MASK | VIRIAL_MASK; - datamask_modify = F_MASK | ENERGY_MASK | VIRIAL_MASK; + datamask_read = EMPTY_MASK; + datamask_modify = EMPTY_MASK; + + update_table = 0; + ntables = 0; + tables = NULL; + h_table = new TableHost(); + d_table = new TableDevice(); k_error_flag = DAT::tdual_int_scalar("pair:error_flag"); } @@ -79,7 +85,10 @@ PairMultiLucyRXKokkos::PairMultiLucyRXKokkos(LAMMPS *lmp) : PairMult template PairMultiLucyRXKokkos::~PairMultiLucyRXKokkos() { + if (copymode) return; + delete h_table; + delete d_table; } /* ---------------------------------------------------------------------- */ @@ -109,7 +118,7 @@ void PairMultiLucyRXKokkos::init_style() neighbor->requests[irequest]->half = 1; neighbor->requests[irequest]->ghost = 1; } else { - error->all(FLERR,"Cannot use chosen neighbor list style with reax/c/kk"); + error->all(FLERR,"Cannot use chosen neighbor list style with multi/lucy/rx/kk"); } } @@ -118,6 +127,23 @@ void PairMultiLucyRXKokkos::init_style() template void PairMultiLucyRXKokkos::compute(int eflag_in, int vflag_in) { + if (update_table) + create_kokkos_tables(); + + if (tabstyle == LOOKUP) + compute_style(eflag_in,vflag_in); + else if(tabstyle == LINEAR) + compute_style(eflag_in,vflag_in); +} + +/* ---------------------------------------------------------------------- */ + +template +template +void PairMultiLucyRXKokkos::compute_style(int eflag_in, int vflag_in) +{ + copymode = 1; + eflag = eflag_in; vflag = vflag_in; @@ -145,10 +171,14 @@ void PairMultiLucyRXKokkos::compute(int eflag_in, int vflag_in) x = atomKK->k_x.view(); f = atomKK->k_f.view(); type = atomKK->k_type.view(); + rho = atomKK->k_rho.view(); uCG = atomKK->k_uCG.view(); uCGnew = atomKK->k_uCGnew.view(); dvector = atomKK->k_dvector.view(); - rho = atomKK->k_rho.view(); + + atomKK->sync(execution_space,X_MASK | F_MASK | TYPE_MASK | ENERGY_MASK | VIRIAL_MASK | DPDRHO_MASK | UCG_MASK | UCGNEW_MASK | DVECTOR_MASK); + if (evflag) atomKK->modified(execution_space,F_MASK | ENERGY_MASK | VIRIAL_MASK | UCG_MASK | UCGNEW_MASK); + else atomKK->modified(execution_space,F_MASK | UCG_MASK | UCGNEW_MASK); nlocal = atom->nlocal; int nghost = atom->nghost; @@ -176,10 +206,22 @@ void PairMultiLucyRXKokkos::compute(int eflag_in, int vflag_in) EV_FLOAT ev; - if (evflag) { - Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); - } else { - Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + if (neighflag == HALF) { + if (newton_pair) { + if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } else { + if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } + } else if (neighflag == HALFTHREAD) { + if (newton_pair) { + if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } else { + if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } } k_error_flag.template modify(); @@ -223,9 +265,13 @@ void PairMultiLucyRXKokkos::operator()(TagPairMultiLucyRXgetParams, } template -template +template KOKKOS_INLINE_FUNCTION -void PairMultiLucyRXKokkos::operator()(TagPairMultiLucyRXCompute, const int &ii, EV_FLOAT& ev) const { +void PairMultiLucyRXKokkos::operator()(TagPairMultiLucyRXCompute, const int &ii, EV_FLOAT& ev) const { + + // The f array is atomic for Half/Thread neighbor style + Kokkos::View::value> > a_f = f; + int i,j,jj,inum,jnum,itype,jtype,itable; double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,evdwlOld,fpair; double rsq; @@ -239,8 +285,6 @@ void PairMultiLucyRXKokkos::operator()(TagPairMultiLucyRXCompute::operator()(TagPairMultiLucyRXComputeinnersq || rho[j]*rho[j] < tb->innersq){ + //tb = &tables[tabindex[itype][jtype]]; + const int tidx = d_table_const.tabindex(itype,jtype); + //if (rho[i]*rho[i] < tb->innersq || rho[j]*rho[j] < tb->innersq){ + if (rho[i]*rho[i] < d_table_const.innersq(tidx) || rho[j]*rho[j] < d_table_const.innersq(tidx)){ k_error_flag.d_view() = 1; } - if (tabstyle == LOOKUP) { - itable = static_cast (((rho[i]*rho[i]) - tb->innersq) * tb->invdelta); - jtable = static_cast (((rho[j]*rho[j]) - tb->innersq) * tb->invdelta); + if (TABSTYLE == LOOKUP) { + //itable = static_cast (((rho[i]*rho[i]) - tb->innersq) * tb->invdelta); + itable = static_cast (((rho[i]*rho[i]) - d_table_const.innersq(tidx)) * d_table_const.invdelta(tidx)); + //jtable = static_cast (((rho[j]*rho[j]) - tb->innersq) * tb->invdelta); + jtable = static_cast (((rho[j]*rho[j]) - d_table_const.innersq(tidx)) * d_table_const.invdelta(tidx)); if (itable >= tlm1 || jtable >= tlm1){ k_error_flag.d_view() = 2; } - A_i = tb->f[itable]; - A_j = tb->f[jtable]; + //A_i = tb->f[itable]; + A_i = d_table_const.f(tidx,itable); + //A_j = tb->f[jtable]; + A_j = d_table_const.f(tidx,jtable); const double rfactor = 1.0-sqrt(rsq/d_cutsq(itype,jtype)); fpair = 0.5*(A_i + A_j)*(4.0-3.0*rfactor)*rfactor*rfactor*rfactor; fpair /= sqrt(rsq); - } else if (tabstyle == LINEAR) { - itable = static_cast ((rho[i]*rho[i] - tb->innersq) * tb->invdelta); - jtable = static_cast (((rho[j]*rho[j]) - tb->innersq) * tb->invdelta); + } else if (TABSTYLE == LINEAR) { + //itable = static_cast ((rho[i]*rho[i] - tb->innersq) * tb->invdelta); + itable = static_cast ((rho[i]*rho[i] - d_table_const.innersq(tidx)) * d_table_const.invdelta(tidx)); + //jtable = static_cast (((rho[j]*rho[j]) - tb->innersq) * tb->invdelta); + jtable = static_cast ((rho[j]*rho[j] - d_table_const.innersq(tidx)) * d_table_const.invdelta(tidx)); if (itable >= tlm1 || jtable >= tlm1){ k_error_flag.d_view() = 2; } @@ -302,15 +354,19 @@ void PairMultiLucyRXKokkos::operator()(TagPairMultiLucyRXCompute=tlm1)jtable=tlm1; - fraction_i = (((rho[i]*rho[i]) - tb->rsq[itable]) * tb->invdelta); - fraction_j = (((rho[j]*rho[j]) - tb->rsq[jtable]) * tb->invdelta); + //fraction_i = (((rho[i]*rho[i]) - tb->rsq[itable]) * tb->invdelta); + fraction_i = (((rho[i]*rho[i]) - d_table_const.rsq(tidx,itable)) * d_table_const.invdelta(tidx)); + //fraction_j = (((rho[j]*rho[j]) - tb->rsq[jtable]) * tb->invdelta); + fraction_j = (((rho[j]*rho[j]) - d_table_const.rsq(tidx,jtable)) * d_table_const.invdelta(tidx)); if(itable==0) fraction_i=0.0; if(itable==tlm1) fraction_i=0.0; if(jtable==0) fraction_j=0.0; if(jtable==tlm1) fraction_j=0.0; - A_i = tb->f[itable] + fraction_i*tb->df[itable]; - A_j = tb->f[jtable] + fraction_j*tb->df[jtable]; + //A_i = tb->f[itable] + fraction_i*tb->df[itable]; + A_i = d_table_const.f(tidx,itable) + fraction_i*d_table_const.df(tidx,itable); + //A_j = tb->f[jtable] + fraction_j*tb->df[jtable]; + A_j = d_table_const.f(tidx,jtable) + fraction_j*d_table_const.df(tidx,jtable); const double rfactor = 1.0-sqrt(rsq/d_cutsq(itype,jtype)); fpair = 0.5*(A_i + A_j)*(4.0-3.0*rfactor)*rfactor*rfactor*rfactor; @@ -325,29 +381,34 @@ void PairMultiLucyRXKokkos::operator()(TagPairMultiLucyRXComputetemplate ev_tally(ev,i,j,0.0,fpair,delx,dely,delz); } } - f(i,0) += fx_i; - f(i,1) += fy_i; - f(i,2) += fz_i; + a_f(i,0) += fx_i; + a_f(i,1) += fy_i; + a_f(i,2) += fz_i; - tb = &tables[tabindex[itype][itype]]; - itable = static_cast (((rho[i]*rho[i]) - tb->innersq) * tb->invdelta); - if (tabstyle == LOOKUP) evdwl = tb->e[itable]; - else if (tabstyle == LINEAR){ + //tb = &tables[tabindex[itype][itype]]; + const int tidx = d_table_const.tabindex(itype,itype); + //itable = static_cast (((rho[i]*rho[i]) - tb->innersq) * tb->invdelta); + itable = static_cast (((rho[i]*rho[i]) - d_table_const.innersq(tidx)) * d_table_const.invdelta(tidx)); + //if (TABSTYLE == LOOKUP) evdwl = tb->e[itable]; + if (TABSTYLE == LOOKUP) evdwl = d_table_const.e(tidx,itable); + else if (TABSTYLE == LINEAR){ if (itable >= tlm1){ k_error_flag.d_view() = 2; } if(itable==0) fraction_i=0.0; - else fraction_i = (((rho[i]*rho[i]) - tb->rsq[itable]) * tb->invdelta); - evdwl = tb->e[itable] + fraction_i*tb->de[itable]; + //else fraction_i = (((rho[i]*rho[i]) - tb->rsq[itable]) * tb->invdelta); + else fraction_i = (((rho[i]*rho[i]) - d_table_const.rsq(tidx,itable)) * d_table_const.invdelta(tidx)); + //evdwl = tb->e[itable] + fraction_i*tb->de[itable]; + evdwl = d_table_const.e(tidx,itable); + fraction_i*d_table_const.de(tidx,itable); } else k_error_flag.d_view() = 3; evdwl *=(pi*d_cutsq(itype,itype)*d_cutsq(itype,itype))/84.0; @@ -364,121 +425,11 @@ void PairMultiLucyRXKokkos::operator()(TagPairMultiLucyRXCompute -template +template KOKKOS_INLINE_FUNCTION -void PairMultiLucyRXKokkos::operator()(TagPairMultiLucyRXCompute, const int &ii) const { +void PairMultiLucyRXKokkos::operator()(TagPairMultiLucyRXCompute, const int &ii) const { EV_FLOAT ev; - this->template operator()(TagPairMultiLucyRXCompute(), ii, ev); -} - -/* ---------------------------------------------------------------------- - set coeffs for one or more type pairs -------------------------------------------------------------------------- */ - -template -void PairMultiLucyRXKokkos::coeff(int narg, char **arg) -{ - if (narg != 6 && narg != 7) error->all(FLERR,"Illegal pair_coeff command"); - - bool rx_flag = false; - for (int i = 0; i < modify->nfix; i++) - if (strncmp(modify->fix[i]->style,"rx",2) == 0) rx_flag = true; - if (!rx_flag) error->all(FLERR,"PairMultiLucyRXKokkos requires a fix rx command."); - - if (!allocated) allocate(); - - int ilo,ihi,jlo,jhi; - force->bounds(FLERR,arg[0],atom->ntypes,ilo,ihi); - force->bounds(FLERR,arg[1],atom->ntypes,jlo,jhi); - - int me; - MPI_Comm_rank(world,&me); - tables = (Table *) - memory->srealloc(tables,(ntables+1)*sizeof(Table),"pair:tables"); - Table *tb = &tables[ntables]; - null_table(tb); - if (me == 0) read_table(tb,arg[2],arg[3]); - bcast_table(tb); - - nspecies = atom->nspecies_dpd; - int n; - n = strlen(arg[3]) + 1; - site1 = new char[n]; - strcpy(site1,arg[4]); - - n = strlen(arg[4]) + 1; - site2 = new char[n]; - strcpy(site2,arg[5]); - - // set table cutoff - - if (narg == 7) tb->cut = force->numeric(FLERR,arg[6]); - else if (tb->rflag) tb->cut = tb->rhi; - else tb->cut = tb->rfile[tb->ninput-1]; - - // error check on table parameters - // insure cutoff is within table - - if (tb->ninput <= 1) error->one(FLERR,"Invalid pair table length"); - if (tb->rflag == 0) { - rho_0 = tb->rfile[0]; - } else { - rho_0 = tb->rlo; - } - - tb->match = 0; - if (tabstyle == LINEAR && tb->ninput == tablength && - tb->rflag == RSQ) tb->match = 1; - - // spline read-in values and compute r,e,f vectors within table - - if (tb->match == 0) spline_table(tb); - compute_table(tb); - - // store ptr to table in tabindex - - int count = 0; - for (int i = ilo; i <= ihi; i++) { - for (int j = MAX(jlo,i); j <= jhi; j++) { - tabindex[i][j] = ntables; - setflag[i][j] = 1; - count++; - } - } - - if (count == 0) error->all(FLERR,"Illegal pair_coeff command"); - ntables++; - - // Match site* to isite values. - - if (strcmp(site1, "1fluid") == 0) - isite1 = oneFluidParameter; - else { - isite1 = nspecies; - for (int ispecies = 0; ispecies < nspecies; ++ispecies) - if (strcmp(site1, atom->dname[ispecies]) == 0){ - isite1 = ispecies; - break; - } - - if (isite1 == nspecies) - error->all(FLERR,"Pair_multi_lucy_rx site1 is invalid."); - } - - if (strcmp(site2, "1fluid") == 0) - isite2 = oneFluidParameter; - else { - isite2 = nspecies; - for (int ispecies = 0; ispecies < nspecies; ++ispecies) - if (strcmp(site2, atom->dname[ispecies]) == 0){ - isite2 = ispecies; - break; - } - - if (isite2 == nspecies) - error->all(FLERR,"Pair_multi_lucy_rx site2 is invalid."); - } - + this->template operator()(TagPairMultiLucyRXCompute(), ii, ev); } /* ---------------------------------------------------------------------- */ @@ -486,12 +437,16 @@ void PairMultiLucyRXKokkos::coeff(int narg, char **arg) template void PairMultiLucyRXKokkos::computeLocalDensity() { + copymode = 1; + x = atomKK->k_x.view(); type = atomKK->k_type.view(); rho = atomKK->k_rho.view(); + h_rho = atomKK->k_rho.h_view; nlocal = atom->nlocal; - //sync + atomKK->sync(execution_space,X_MASK | TYPE_MASK | DPDRHO_MASK); + atomKK->modified(execution_space,DPDRHO_MASK); const int inum = list->inum; NeighListKokkos* k_list = static_cast*>(list); @@ -514,16 +469,34 @@ void PairMultiLucyRXKokkos::computeLocalDensity() if (newton_pair) m += atom->nghost; Kokkos::parallel_for(Kokkos::RangePolicy(0,m),*this); -// rho = density at each atom -// loop over neighbors of my atoms - if (newton_pair) - Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); - else - Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + // rho = density at each atom + // loop over neighbors of my atoms - if (newton_pair) comm->reverse_comm_pair(this); + if (neighflag == HALF) { + if (newton_pair) + Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + else + Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } else if (neighflag == HALFTHREAD) { + if (newton_pair) + Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + else + Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } + + // communicate and sum densities (on the host) + + if (newton_pair) { + atomKK->modified(execution_space,DPDRHO_MASK); + atomKK->sync(Host,DPDRHO_MASK); + comm->reverse_comm_pair(this); + atomKK->modified(Host,DPDRHO_MASK); + atomKK->sync(execution_space,DPDRHO_MASK); + } comm->forward_comm_pair(this); + + copymode = 0; } template @@ -536,6 +509,10 @@ template template KOKKOS_INLINE_FUNCTION void PairMultiLucyRXKokkos::operator()(TagPairMultiLucyRXComputeLocalDensity, const int &ii) const { + + // The rho array is atomic for Half/Thread neighbor style + Kokkos::View::value> > a_rho = rho; + const int i = d_ilist[ii]; const double xtmp = x(i,0); @@ -567,7 +544,7 @@ void PairMultiLucyRXKokkos::operator()(TagPairMultiLucyRXComputeLoca const double factor = factor_type11*(1.0 + 1.5*r_over_rcut)*tmpFactor4; rho_i += factor; if (NEWTON_PAIR || j < nlocal) - rho[j] += factor; + a_rho[j] += factor; } else if (rsq < d_cutsq(itype,jtype)) { const double rcut = sqrt(d_cutsq(itype,jtype)); const double tmpFactor = 1.0-sqrt(rsq)/rcut; @@ -575,12 +552,12 @@ void PairMultiLucyRXKokkos::operator()(TagPairMultiLucyRXComputeLoca const double factor = (84.0/(5.0*pi*rcut*rcut*rcut))*(1.0+3.0*sqrt(rsq)/(2.0*rcut))*tmpFactor4; rho_i += factor; if (NEWTON_PAIR || j < nlocal) - rho[j] += factor; + a_rho[j] += factor; } } } - rho[i] = rho_i; + a_rho[i] = rho_i; } /* ---------------------------------------------------------------------- */ @@ -630,16 +607,53 @@ void PairMultiLucyRXKokkos::getParams(int id, double &fractionOld1, /* ---------------------------------------------------------------------- */ +template +int PairMultiLucyRXKokkos::pack_forward_comm_kokkos(int n, DAT::tdual_int_2d k_sendlist, int iswap_in, DAT::tdual_xfloat_1d &buf, + int pbc_flag, int *pbc) +{ + d_sendlist = k_sendlist.view(); + iswap = iswap_in; + v_buf = buf.view(); + Kokkos::parallel_for(Kokkos::RangePolicy(0,n),*this); + DeviceType::fence(); + return n; +} + +template +KOKKOS_INLINE_FUNCTION +void PairMultiLucyRXKokkos::operator()(TagPairMultiLucyRXPackForwardComm, const int &i) const { + int j = d_sendlist(iswap, i); + v_buf[i] = rho[j]; +} + +/* ---------------------------------------------------------------------- */ + +template +void PairMultiLucyRXKokkos::unpack_forward_comm_kokkos(int n, int first_in, DAT::tdual_xfloat_1d &buf) +{ + first = first_in; + v_buf = buf.view(); + Kokkos::parallel_for(Kokkos::RangePolicy(0,n),*this); + DeviceType::fence(); +} + +template +KOKKOS_INLINE_FUNCTION +void PairMultiLucyRXKokkos::operator()(TagPairMultiLucyRXUnpackForwardComm, const int &i) const { + rho[i + first] = v_buf[i]; +} + +/* ---------------------------------------------------------------------- */ + template int PairMultiLucyRXKokkos::pack_forward_comm(int n, int *list, double *buf, int pbc_flag, int *pbc) { int i,j,m; - rho = atomKK->k_rho.view(); m = 0; for (i = 0; i < n; i++) { j = list[i]; - buf[m++] = rho[j]; + buf[m++] = h_rho[j]; } return m; } @@ -650,11 +664,10 @@ template void PairMultiLucyRXKokkos::unpack_forward_comm(int n, int first, double *buf) { int i,m,last; - rho = atomKK->k_rho.view(); m = 0; last = first + n; - for (i = first; i < last; i++) rho[i] = buf[m++]; + for (i = first; i < last; i++) h_rho[i] = buf[m++]; } /* ---------------------------------------------------------------------- */ @@ -663,11 +676,10 @@ template int PairMultiLucyRXKokkos::pack_reverse_comm(int n, int first, double *buf) { int i,m,last; - rho = atomKK->k_rho.view(); m = 0; last = first + n; - for (i = first; i < last; i++) buf[m++] = rho[i]; + for (i = first; i < last; i++) buf[m++] = h_rho[i]; return m; } @@ -677,12 +689,11 @@ template void PairMultiLucyRXKokkos::unpack_reverse_comm(int n, int *list, double *buf) { int i,j,m; - rho = atomKK->k_rho.view(); m = 0; for (i = 0; i < n; i++) { j = list[i]; - rho[j] += buf[m++]; + h_rho[j] += buf[m++]; } } @@ -782,6 +793,145 @@ void PairMultiLucyRXKokkos::ev_tally(EV_FLOAT &ev, const int &i, con /* ---------------------------------------------------------------------- */ +template +void PairMultiLucyRXKokkos::create_kokkos_tables() +{ + const int tlm1 = tablength-1; + + memory->create_kokkos(d_table->innersq,h_table->innersq,ntables,"Table::innersq"); + memory->create_kokkos(d_table->invdelta,h_table->invdelta,ntables,"Table::invdelta"); + memory->create_kokkos(d_table->deltasq6,h_table->deltasq6,ntables,"Table::deltasq6"); + + if(tabstyle == LOOKUP) { + memory->create_kokkos(d_table->e,h_table->e,ntables,tlm1,"Table::e"); + memory->create_kokkos(d_table->f,h_table->f,ntables,tlm1,"Table::f"); + } + + if(tabstyle == LINEAR) { + memory->create_kokkos(d_table->rsq,h_table->rsq,ntables,tablength,"Table::rsq"); + memory->create_kokkos(d_table->e,h_table->e,ntables,tablength,"Table::e"); + memory->create_kokkos(d_table->f,h_table->f,ntables,tablength,"Table::f"); + memory->create_kokkos(d_table->de,h_table->de,ntables,tlm1,"Table::de"); + memory->create_kokkos(d_table->df,h_table->df,ntables,tlm1,"Table::df"); + } + + for(int i=0; i < ntables; i++) { + Table* tb = &tables[i]; + + h_table->innersq[i] = tb->innersq; + h_table->invdelta[i] = tb->invdelta; + h_table->deltasq6[i] = tb->deltasq6; + + for(int j = 0; jrsq.dimension_1(); j++) + h_table->rsq(i,j) = tb->rsq[j]; + for(int j = 0; jdrsq.dimension_1(); j++) + h_table->drsq(i,j) = tb->drsq[j]; + for(int j = 0; je.dimension_1(); j++) + h_table->e(i,j) = tb->e[j]; + for(int j = 0; jde.dimension_1(); j++) + h_table->de(i,j) = tb->de[j]; + for(int j = 0; jf.dimension_1(); j++) + h_table->f(i,j) = tb->f[j]; + for(int j = 0; jdf.dimension_1(); j++) + h_table->df(i,j) = tb->df[j]; + for(int j = 0; je2.dimension_1(); j++) + h_table->e2(i,j) = tb->e2[j]; + for(int j = 0; jf2.dimension_1(); j++) + h_table->f2(i,j) = tb->f2[j]; + } + + + Kokkos::deep_copy(d_table->innersq,h_table->innersq); + Kokkos::deep_copy(d_table->invdelta,h_table->invdelta); + Kokkos::deep_copy(d_table->deltasq6,h_table->deltasq6); + Kokkos::deep_copy(d_table->rsq,h_table->rsq); + Kokkos::deep_copy(d_table->drsq,h_table->drsq); + Kokkos::deep_copy(d_table->e,h_table->e); + Kokkos::deep_copy(d_table->de,h_table->de); + Kokkos::deep_copy(d_table->f,h_table->f); + Kokkos::deep_copy(d_table->df,h_table->df); + Kokkos::deep_copy(d_table->e2,h_table->e2); + Kokkos::deep_copy(d_table->f2,h_table->f2); + Kokkos::deep_copy(d_table->tabindex,h_table->tabindex); + + d_table_const.innersq = d_table->innersq; + d_table_const.invdelta = d_table->invdelta; + d_table_const.deltasq6 = d_table->deltasq6; + d_table_const.rsq = d_table->rsq; + d_table_const.drsq = d_table->drsq; + d_table_const.e = d_table->e; + d_table_const.de = d_table->de; + d_table_const.f = d_table->f; + d_table_const.df = d_table->df; + d_table_const.e2 = d_table->e2; + d_table_const.f2 = d_table->f2; + + + Kokkos::deep_copy(d_table->cutsq,h_table->cutsq); + update_table = 0; +} + +/* ---------------------------------------------------------------------- + allocate all arrays +------------------------------------------------------------------------- */ + +template +void PairMultiLucyRXKokkos::allocate() +{ + allocated = 1; + const int nt = atom->ntypes + 1; + + memory->create(setflag,nt,nt,"pair:setflag"); + memory->create_kokkos(d_table->cutsq,h_table->cutsq,cutsq,nt,nt,"pair:cutsq"); + memory->create_kokkos(d_table->tabindex,h_table->tabindex,tabindex,nt,nt,"pair:tabindex"); + + d_table_const.cutsq = d_table->cutsq; + d_table_const.tabindex = d_table->tabindex; + memset(&setflag[0][0],0,nt*nt*sizeof(int)); + memset(&cutsq[0][0],0,nt*nt*sizeof(double)); + memset(&tabindex[0][0],0,nt*nt*sizeof(int)); +} + +/* ---------------------------------------------------------------------- + global settings +------------------------------------------------------------------------- */ + +template +void PairMultiLucyRXKokkos::settings(int narg, char **arg) +{ + if (narg < 2) error->all(FLERR,"Illegal pair_style command"); + + // new settings + + if (strcmp(arg[0],"lookup") == 0) tabstyle = LOOKUP; + else if (strcmp(arg[0],"linear") == 0) tabstyle = LINEAR; + else error->all(FLERR,"Unknown table style in pair_style command"); + + tablength = force->inumeric(FLERR,arg[1]); + if (tablength < 2) error->all(FLERR,"Illegal number of pair table entries"); + + // delete old tables, since cannot just change settings + + for (int m = 0; m < ntables; m++) free_table(&tables[m]); + memory->sfree(tables); + + if (allocated) { + memory->destroy(setflag); + + d_table_const.tabindex = d_table->tabindex = typename ArrayTypes::t_int_2d(); + h_table->tabindex = typename ArrayTypes::t_int_2d(); + + d_table_const.cutsq = d_table->cutsq = typename ArrayTypes::t_ffloat_2d(); + h_table->cutsq = typename ArrayTypes::t_ffloat_2d(); + } + allocated = 0; + + ntables = 0; + tables = NULL; +} + +/* ---------------------------------------------------------------------- */ + namespace LAMMPS_NS { template class PairMultiLucyRXKokkos; #ifdef KOKKOS_HAVE_CUDA diff --git a/src/KOKKOS/pair_multi_lucy_rx_kokkos.h b/src/KOKKOS/pair_multi_lucy_rx_kokkos.h index ff22516eb1..a259588f78 100644 --- a/src/KOKKOS/pair_multi_lucy_rx_kokkos.h +++ b/src/KOKKOS/pair_multi_lucy_rx_kokkos.h @@ -29,9 +29,12 @@ PairStyle(multi/lucy/rx/kk/host,PairMultiLucyRXKokkos) namespace LAMMPS_NS { +struct TagPairMultiLucyRXPackForwardComm{}; +struct TagPairMultiLucyRXUnpackForwardComm{}; + struct TagPairMultiLucyRXgetParams{}; -template +template struct TagPairMultiLucyRXCompute{}; struct TagPairMultiLucyRXZero{}; @@ -50,24 +53,37 @@ class PairMultiLucyRXKokkos : public PairMultiLucyRX { virtual ~PairMultiLucyRXKokkos(); void compute(int, int); + void settings(int, char **); + + template + void compute_style(int, int); + void init_style(); - void coeff(int, char **); + int pack_forward_comm_kokkos(int, DAT::tdual_int_2d, int, DAT::tdual_xfloat_1d&, + int, int *); + void unpack_forward_comm_kokkos(int, int, DAT::tdual_xfloat_1d&); int pack_forward_comm(int, int *, double *, int, int *); void unpack_forward_comm(int, int, double *); int pack_reverse_comm(int, int, double *); void unpack_reverse_comm(int, int *, double *); void computeLocalDensity(); + KOKKOS_INLINE_FUNCTION + void operator()(TagPairMultiLucyRXPackForwardComm, const int&) const; + + KOKKOS_INLINE_FUNCTION + void operator()(TagPairMultiLucyRXUnpackForwardComm, const int&) const; + KOKKOS_INLINE_FUNCTION void operator()(TagPairMultiLucyRXgetParams, const int&) const; - template + template KOKKOS_INLINE_FUNCTION - void operator()(TagPairMultiLucyRXCompute, const int&, EV_FLOAT&) const; + void operator()(TagPairMultiLucyRXCompute, const int&, EV_FLOAT&) const; - template + template KOKKOS_INLINE_FUNCTION - void operator()(TagPairMultiLucyRXCompute, const int&) const; + void operator()(TagPairMultiLucyRXCompute, const int&) const; KOKKOS_INLINE_FUNCTION void operator()(TagPairMultiLucyRXZero, const int&) const; @@ -92,6 +108,8 @@ class PairMultiLucyRXKokkos : public PairMultiLucyRX { double rcut_type11; double factor_type11; + enum{LOOKUP,LINEAR,SPLINE,BITMAP}; + //struct Table { // int ninput,rflag,fpflag,match; // double rlo,rhi,fplo,fphi,cut; @@ -100,14 +118,47 @@ class PairMultiLucyRXKokkos : public PairMultiLucyRX { // double innersq,delta,invdelta,deltasq6; // double *rsq,*drsq,*e,*de,*f,*df,*e2,*f2; //}; - //Table *tables; + + int tabstyle,tablength; + /*struct TableDeviceConst { + typename ArrayTypes::t_ffloat_2d_randomread cutsq; + typename ArrayTypes::t_int_2d_randomread tabindex; + typename ArrayTypes::t_ffloat_1d_randomread innersq,invdelta,deltasq6; + typename ArrayTypes::t_ffloat_2d_randomread rsq,drsq,e,de,f,df,e2,f2; + };*/ + //Its faster not to use texture fetch if the number of tables is less than 32! + struct TableDeviceConst { + typename ArrayTypes::t_ffloat_2d cutsq; + typename ArrayTypes::t_int_2d tabindex; + typename ArrayTypes::t_ffloat_1d innersq,invdelta,deltasq6; + typename ArrayTypes::t_ffloat_2d_randomread rsq,drsq,e,de,f,df,e2,f2; + }; + + struct TableDevice { + typename ArrayTypes::t_ffloat_2d cutsq; + typename ArrayTypes::t_int_2d tabindex; + typename ArrayTypes::t_ffloat_1d innersq,invdelta,deltasq6; + typename ArrayTypes::t_ffloat_2d rsq,drsq,e,de,f,df,e2,f2; + }; + + struct TableHost { + typename ArrayTypes::t_ffloat_2d cutsq; + typename ArrayTypes::t_int_2d tabindex; + typename ArrayTypes::t_ffloat_1d innersq,invdelta,deltasq6; + typename ArrayTypes::t_ffloat_2d rsq,drsq,e,de,f,df,e2,f2; + }; + + TableDeviceConst d_table_const; + TableDevice* d_table; + TableHost* h_table; int **tabindex; + F_FLOAT m_cutsq[MAX_TYPES_STACKPARAMS+1][MAX_TYPES_STACKPARAMS+1]; - //void read_table(Table *, char *, char *); - //void param_extract(Table *, char *); - - char *site1, *site2; + void allocate(); + int update_table; + void create_kokkos_tables(); + void cleanup_copy(); KOKKOS_INLINE_FUNCTION void getParams(int, double &, double &, double &, double &) const; @@ -118,6 +169,7 @@ class PairMultiLucyRXKokkos : public PairMultiLucyRX { typename AT::t_f_array f; typename AT::t_int_1d_randomread type; typename AT::t_efloat_1d rho; + typename HAT::t_efloat_1d h_rho; typename AT::t_efloat_1d uCG, uCGnew; typename AT::t_float_2d dvector; @@ -135,6 +187,11 @@ class PairMultiLucyRXKokkos : public PairMultiLucyRX { typename AT::tdual_ffloat_2d k_cutsq; typename AT::t_ffloat_2d d_cutsq; + int iswap; + int first; + typename AT::t_int_2d d_sendlist; + typename AT::t_xfloat_1d_um v_buf; + friend void pair_virial_fdotr_compute(PairMultiLucyRXKokkos*); }; diff --git a/src/USER-DPD/fix_eos_table_rx.cpp b/src/USER-DPD/fix_eos_table_rx.cpp index e10ce96089..8871bdd176 100644 --- a/src/USER-DPD/fix_eos_table_rx.cpp +++ b/src/USER-DPD/fix_eos_table_rx.cpp @@ -127,6 +127,8 @@ FixEOStableRX::FixEOStableRX(LAMMPS *lmp, int narg, char **arg) : FixEOStableRX::~FixEOStableRX() { + if (copymode) return; + for (int m = 0; m < ntables; m++) { free_table(&tables[m]); free_table(&tables2[m]); diff --git a/src/USER-DPD/pair_multi_lucy_rx.cpp b/src/USER-DPD/pair_multi_lucy_rx.cpp index cd107f1519..6b5c7cf40a 100644 --- a/src/USER-DPD/pair_multi_lucy_rx.cpp +++ b/src/USER-DPD/pair_multi_lucy_rx.cpp @@ -78,6 +78,8 @@ PairMultiLucyRX::PairMultiLucyRX(LAMMPS *lmp) : Pair(lmp), PairMultiLucyRX::~PairMultiLucyRX() { + if (copymode) return; + for (int m = 0; m < ntables; m++) free_table(&tables[m]); memory->sfree(tables); diff --git a/src/USER-DPD/pair_table_rx.cpp b/src/USER-DPD/pair_table_rx.cpp index 902d0e5bb4..463e1838c6 100644 --- a/src/USER-DPD/pair_table_rx.cpp +++ b/src/USER-DPD/pair_table_rx.cpp @@ -50,6 +50,8 @@ PairTableRX::PairTableRX(LAMMPS *lmp) : Pair(lmp) PairTableRX::~PairTableRX() { + if (copymode) return; + for (int m = 0; m < ntables; m++) free_table(&tables[m]); memory->sfree(tables); diff --git a/src/atom_masks.h b/src/atom_masks.h index 119f09f273..8e29448488 100644 --- a/src/atom_masks.h +++ b/src/atom_masks.h @@ -42,6 +42,18 @@ #define ENERGY_MASK 0x00010000 #define VIRIAL_MASK 0x00020000 +// DPD + +#define DPDRHO_MASK 0x00040000 +#define DPDTHETA_MASK 0x00080000 +#define UCOND_MASK 0x00100000 +#define UMECH_MASK 0x00200000 +#define UCHEM_MASK 0x00400000 +#define UCG_MASK 0x00800000 +#define UCGNEW_MASK 0x01000000 +#define DUCHEM_MASK 0x02000000 +#define DVECTOR_MASK 0x04000000 + // granular #define RADIUS_MASK 0x00100000 From d5f8f36442bfc14ba49c4090f465f87afc65a24e Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Thu, 15 Dec 2016 15:48:09 -0700 Subject: [PATCH 012/439] Change to fix_property_atom to allow virtual override of grow_arrays() function --- src/fix_property_atom.cpp | 3 ++- src/fix_property_atom.h | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/fix_property_atom.cpp b/src/fix_property_atom.cpp index b83aadc95d..002260d8f0 100644 --- a/src/fix_property_atom.cpp +++ b/src/fix_property_atom.cpp @@ -134,7 +134,6 @@ FixPropertyAtom::FixPropertyAtom(LAMMPS *lmp, int narg, char **arg) : // register with Atom class nmax_old = 0; - grow_arrays(atom->nmax); atom->add_callback(0); atom->add_callback(1); if (border) atom->add_callback(2); @@ -190,6 +189,8 @@ int FixPropertyAtom::setmask() void FixPropertyAtom::init() { + grow_arrays(atom->nmax); + // error if atom style has changed since fix was defined // don't allow this b/c user could change to style that defines molecule,q diff --git a/src/fix_property_atom.h b/src/fix_property_atom.h index 77a41f393a..d923d76cac 100644 --- a/src/fix_property_atom.h +++ b/src/fix_property_atom.h @@ -27,7 +27,7 @@ namespace LAMMPS_NS { class FixPropertyAtom : public Fix { public: FixPropertyAtom(class LAMMPS *, int, char **); - ~FixPropertyAtom(); + virtual ~FixPropertyAtom(); int setmask(); void init(); @@ -38,7 +38,7 @@ class FixPropertyAtom : public Fix { void write_data_section_keyword(int, FILE *); void write_data_section(int, FILE *, int, double **, int); - void grow_arrays(int); + virtual void grow_arrays(int); void copy_arrays(int, int, int); int pack_border(int, int *, double *); int unpack_border(int, int, double *); @@ -50,7 +50,7 @@ class FixPropertyAtom : public Fix { int maxsize_restart(); double memory_usage(); - private: + protected: int nvalue,border; int molecule_flag,q_flag,rmass_flag; int *style,*index; From a3c1d385e84a68721433eaaf318513962c489657 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Thu, 15 Dec 2016 15:50:30 -0700 Subject: [PATCH 013/439] Adding Kokkos version of fix_property_atom --- src/KOKKOS/Install.sh | 2 + src/KOKKOS/fix_property_atom_kokkos.cpp | 72 ++++++++++++++++++++ src/KOKKOS/fix_property_atom_kokkos.h | 90 +++++++++++++++++++++++++ 3 files changed, 164 insertions(+) create mode 100644 src/KOKKOS/fix_property_atom_kokkos.cpp create mode 100644 src/KOKKOS/fix_property_atom_kokkos.h diff --git a/src/KOKKOS/Install.sh b/src/KOKKOS/Install.sh index 707ea1e986..a1830163bd 100644 --- a/src/KOKKOS/Install.sh +++ b/src/KOKKOS/Install.sh @@ -87,6 +87,8 @@ action fix_nve_kokkos.cpp action fix_nve_kokkos.h action fix_nvt_kokkos.cpp action fix_nvt_kokkos.h +action fix_property_atom_kokkos.cpp +action fix_property_atom_kokkos.h action fix_qeq_reax_kokkos.cpp fix_qeq_reax.cpp action fix_qeq_reax_kokkos.h fix_qeq_reax.h action fix_reaxc_bonds_kokkos.cpp fix_reaxc_bonds.cpp diff --git a/src/KOKKOS/fix_property_atom_kokkos.cpp b/src/KOKKOS/fix_property_atom_kokkos.cpp new file mode 100644 index 0000000000..327563efbd --- /dev/null +++ b/src/KOKKOS/fix_property_atom_kokkos.cpp @@ -0,0 +1,72 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include +#include +#include "fix_property_atom_kokkos.h" +#include "atom_kokkos.h" +#include "comm.h" +#include "memory.h" +#include "error.h" +#include "update.h" + +using namespace LAMMPS_NS; +using namespace FixConst; + +enum{MOLECULE,CHARGE,RMASS,INTEGER,DOUBLE}; + +/* ---------------------------------------------------------------------- */ + +FixPropertyAtomKokkos::FixPropertyAtomKokkos(LAMMPS *lmp, int narg, char **arg) : + FixPropertyAtom(lmp, narg, arg) +{ + atomKK = (AtomKokkos *) atom; +} + +/* ---------------------------------------------------------------------- + allocate atom-based arrays + initialize new values to 0, + since AtomVec class won't do it as atoms are added, + e.g. in create_atom() or data_atom() +------------------------------------------------------------------------- */ + +void FixPropertyAtomKokkos::grow_arrays(int nmax) +{ + for (int m = 0; m < nvalue; m++) { + if (style[m] == MOLECULE) { + memory->grow(atom->molecule,nmax,"atom:molecule"); + size_t nbytes = (nmax-nmax_old) * sizeof(tagint); + memset(&atom->molecule[nmax_old],0,nbytes); + } else if (style[m] == CHARGE) { + memory->grow(atom->q,nmax,"atom:q"); + size_t nbytes = (nmax-nmax_old) * sizeof(double); + memset(&atom->q[nmax_old],0,nbytes); + } else if (style[m] == RMASS) { + memory->grow(atom->rmass,nmax,"atom:rmass"); + size_t nbytes = (nmax-nmax_old) * sizeof(double); + memset(&atom->rmass[nmax_old],0,nbytes); + } else if (style[m] == INTEGER) { + memory->grow(atom->ivector[index[m]],nmax,"atom:ivector"); + size_t nbytes = (nmax-nmax_old) * sizeof(int); + memset(&atom->ivector[index[m]][nmax_old],0,nbytes); + } else if (style[m] == DOUBLE) { + memory->grow_kokkos(atomKK->k_dvector,atomKK->dvector,nvalue,nmax, + "atom:dvector"); + //memory->grow(atom->dvector[index[m]],nmax,"atom:dvector"); + //size_t nbytes = (nmax-nmax_old) * sizeof(double); + //memset(&atom->dvector[index[m]][nmax_old],0,nbytes); + } + } + + nmax_old = nmax; +} diff --git a/src/KOKKOS/fix_property_atom_kokkos.h b/src/KOKKOS/fix_property_atom_kokkos.h new file mode 100644 index 0000000000..ed1e4d7cfb --- /dev/null +++ b/src/KOKKOS/fix_property_atom_kokkos.h @@ -0,0 +1,90 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef FIX_CLASS + +FixStyle(property/atom/kk,FixPropertyAtomKokkos) + +#else + +#ifndef LMP_FIX_PROPERTY_ATOM_KOKKOS_H +#define LMP_FIX_PROPERTY_ATOM_KOKKOS_H + +#include "fix_property_atom.h" + +namespace LAMMPS_NS { + +class FixPropertyAtomKokkos : public FixPropertyAtom { + public: + FixPropertyAtomKokkos(class LAMMPS *, int, char **); + virtual ~FixPropertyAtomKokkos() {} + + void grow_arrays(int); +}; + +} + +#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: Fix property/atom mol when atom_style already has molecule attribute + +Self-explanatory. + +E: Fix property/atom cannot specify mol twice + +Self-explanatory. + +E: Fix property/atom q when atom_style already has charge attribute + +Self-explanatory. + +E: Fix property/atom cannot specify q twice + +Self-explanatory. + +E: Fix property/atom vector name already exists + +The name for an integer or floating-point vector must be unique. + +W: Fix property/atom mol or charge w/out ghost communication + +A model typically needs these properties defined for ghost atoms. + +E: Atom style was redefined after using fix property/atom + +This is not allowed. + +E: Incorrect %s format in data file + +A section of the data file being read by fix property/atom does +not have the correct number of values per line. + +E: Too few lines in %s section of data file + +Self-explanatory. + +E: Invalid atom ID in %s section of data file + +An atom in a section of the data file being read by fix property/atom +has an invalid atom ID that is <= 0 or > the maximum existing atom ID. + +*/ From f47a40b2e4ead7248c601129c9e8a5d82deac91b Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 16 Dec 2016 10:02:01 -0700 Subject: [PATCH 014/439] Fixing Kokkos memory deallocation issue --- src/KOKKOS/atom_kokkos.cpp | 13 +++++++++++++ src/atom.cpp | 8 +++++--- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/KOKKOS/atom_kokkos.cpp b/src/KOKKOS/atom_kokkos.cpp index 4a7250e6ab..97b76ba67c 100644 --- a/src/KOKKOS/atom_kokkos.cpp +++ b/src/KOKKOS/atom_kokkos.cpp @@ -73,6 +73,19 @@ AtomKokkos::~AtomKokkos() memory->destroy_kokkos(k_improper_atom2, improper_atom2); memory->destroy_kokkos(k_improper_atom3, improper_atom3); memory->destroy_kokkos(k_improper_atom4, improper_atom4); + + // USER-DPD package + memory->destroy_kokkos(k_uCond,uCond); + memory->destroy_kokkos(k_uMech,uMech); + memory->destroy_kokkos(k_uChem,uChem); + memory->destroy_kokkos(k_uCG,uCG); + memory->destroy_kokkos(k_uCGnew,uCGnew); + memory->destroy_kokkos(k_rho,rho); + memory->destroy_kokkos(k_dpdTheta,dpdTheta); + memory->destroy_kokkos(k_duChem,duChem); + + memory->destroy_kokkos(k_dvector,dvector); + dvector = NULL; } /* ---------------------------------------------------------------------- */ diff --git a/src/atom.cpp b/src/atom.cpp index 053a18430b..c7f8345898 100644 --- a/src/atom.cpp +++ b/src/atom.cpp @@ -331,9 +331,11 @@ Atom::~Atom() delete [] iname[i]; memory->destroy(ivector[i]); } - for (int i = 0; i < ndvector; i++) { - delete [] dname[i]; - memory->destroy(dvector[i]); + if (dvector != NULL) { + for (int i = 0; i < ndvector; i++) { + delete [] dname[i]; + memory->destroy(dvector[i]); + } } memory->sfree(iname); From d93e3d1cee93983df5e1c0707b4957d2bc138e9a Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 16 Dec 2016 10:06:12 -0700 Subject: [PATCH 015/439] Fixing runtime issues with pair_exp6_rx_kokkos --- src/KOKKOS/fix_property_atom_kokkos.cpp | 2 +- src/KOKKOS/pair_exp6_rx_kokkos.cpp | 17 ++++++++++++++--- src/USER-DPD/pair_exp6_rx.cpp | 10 ++++++---- src/USER-DPD/pair_exp6_rx.h | 4 ++-- 4 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/KOKKOS/fix_property_atom_kokkos.cpp b/src/KOKKOS/fix_property_atom_kokkos.cpp index 327563efbd..cb52988c31 100644 --- a/src/KOKKOS/fix_property_atom_kokkos.cpp +++ b/src/KOKKOS/fix_property_atom_kokkos.cpp @@ -60,7 +60,7 @@ void FixPropertyAtomKokkos::grow_arrays(int nmax) size_t nbytes = (nmax-nmax_old) * sizeof(int); memset(&atom->ivector[index[m]][nmax_old],0,nbytes); } else if (style[m] == DOUBLE) { - memory->grow_kokkos(atomKK->k_dvector,atomKK->dvector,nvalue,nmax, + memory->grow_kokkos(atomKK->k_dvector,atomKK->dvector,atomKK->k_dvector.dimension_0(),nmax, "atom:dvector"); //memory->grow(atom->dvector[index[m]],nmax,"atom:dvector"); //size_t nbytes = (nmax-nmax_old) * sizeof(double); diff --git a/src/KOKKOS/pair_exp6_rx_kokkos.cpp b/src/KOKKOS/pair_exp6_rx_kokkos.cpp index 7e74f39ef0..e7934cfa0b 100644 --- a/src/KOKKOS/pair_exp6_rx_kokkos.cpp +++ b/src/KOKKOS/pair_exp6_rx_kokkos.cpp @@ -65,7 +65,20 @@ PairExp6rxKokkos::PairExp6rxKokkos(LAMMPS *lmp) : PairExp6rx(lmp) template PairExp6rxKokkos::~PairExp6rxKokkos() { + if (copymode) return; + memory->destroy_kokkos(k_eatom,eatom); + memory->destroy_kokkos(k_vatom,vatom); + + memory->destroy_kokkos(k_cutsq,cutsq); + + for (int i=0; i < nparams; ++i) { + delete[] params[i].name; + delete[] params[i].potential; + } + memory->destroy_kokkos(k_params,params); + + memory->destroy_kokkos(k_mol2param,mol2param); } /* ---------------------------------------------------------------------- */ @@ -73,7 +86,7 @@ PairExp6rxKokkos::~PairExp6rxKokkos() template void PairExp6rxKokkos::init_style() { - PairExp6rxKokkos::init_style(); + PairExp6rx::init_style(); // irequest = neigh request made by parent class @@ -89,11 +102,9 @@ void PairExp6rxKokkos::init_style() if (neighflag == FULL) { neighbor->requests[irequest]->full = 1; neighbor->requests[irequest]->half = 0; - neighbor->requests[irequest]->ghost = 1; } else if (neighflag == HALF || neighflag == HALFTHREAD) { neighbor->requests[irequest]->full = 0; neighbor->requests[irequest]->half = 1; - neighbor->requests[irequest]->ghost = 1; } else { error->all(FLERR,"Cannot use chosen neighbor list style with reax/c/kk"); } diff --git a/src/USER-DPD/pair_exp6_rx.cpp b/src/USER-DPD/pair_exp6_rx.cpp index 2643c9ec04..dd8ac4bbe7 100644 --- a/src/USER-DPD/pair_exp6_rx.cpp +++ b/src/USER-DPD/pair_exp6_rx.cpp @@ -79,11 +79,13 @@ PairExp6rx::~PairExp6rx() { if (copymode) return; - for (int i=0; i < nparams; ++i) { - delete[] params[i].name; - delete[] params[i].potential; + if (params != NULL) { + for (int i=0; i < nparams; ++i) { + delete[] params[i].name; + delete[] params[i].potential; + } + memory->destroy(params); } - memory->destroy(params); memory->destroy(mol2param); if (allocated) { diff --git a/src/USER-DPD/pair_exp6_rx.h b/src/USER-DPD/pair_exp6_rx.h index dd9fa22a48..f9654e4086 100644 --- a/src/USER-DPD/pair_exp6_rx.h +++ b/src/USER-DPD/pair_exp6_rx.h @@ -44,7 +44,7 @@ class PairExp6rx : public Pair { double **epsilon,**rm,**alpha; double **rminv,**buck1,**buck2,**offset; - void allocate(); + virtual void allocate(); int *mol2param; // mapping from molecule to parameters int nparams; // # of stored parameter sets int maxparam; // max # of parameter sets @@ -58,7 +58,7 @@ class PairExp6rx : public Pair { Param *params; // parameter set for an I-J-K interaction int nspecies; - void read_file(char *); + virtual void read_file(char *); void setup(); int isite1, isite2; From cfa61b98aec5951824affe4057f81e022868d470 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 16 Dec 2016 12:37:41 -0700 Subject: [PATCH 016/439] Fixing runtime issues in fix_eos_table_rx_kokkos --- src/KOKKOS/fix_eos_table_rx_kokkos.cpp | 152 ++++++++++++++++++++----- src/KOKKOS/fix_eos_table_rx_kokkos.h | 33 ++++++ 2 files changed, 157 insertions(+), 28 deletions(-) diff --git a/src/KOKKOS/fix_eos_table_rx_kokkos.cpp b/src/KOKKOS/fix_eos_table_rx_kokkos.cpp index 75e9b292f9..6cb5c0611a 100644 --- a/src/KOKKOS/fix_eos_table_rx_kokkos.cpp +++ b/src/KOKKOS/fix_eos_table_rx_kokkos.cpp @@ -40,8 +40,12 @@ FixEOStableRXKokkos::FixEOStableRXKokkos(LAMMPS *lmp, int narg, char { atomKK = (AtomKokkos *) atom; execution_space = ExecutionSpaceFromDevice::space; - datamask_read = X_MASK | F_MASK | TYPE_MASK | ENERGY_MASK | VIRIAL_MASK; - datamask_modify = F_MASK | ENERGY_MASK | VIRIAL_MASK; + datamask_read = EMPTY_MASK; + datamask_modify = EMPTY_MASK; + + update_table = 1; + h_table = new TableHost(); + d_table = new TableDevice(); k_error_flag = DAT::tdual_int_scalar("fix:error_flag"); k_warning_flag = DAT::tdual_int_scalar("fix:warning_flag"); @@ -53,6 +57,9 @@ template FixEOStableRXKokkos::~FixEOStableRXKokkos() { if (copymode) return; + + delete h_table; + delete d_table; } /* ---------------------------------------------------------------------- */ @@ -60,6 +67,11 @@ FixEOStableRXKokkos::~FixEOStableRXKokkos() template void FixEOStableRXKokkos::setup(int vflag) { + if (update_table) + create_kokkos_tables(); + + copymode = 1; + int nlocal = atom->nlocal; mask = atomKK->k_mask.view(); uCond = atomKK->k_uCond.view(); @@ -68,6 +80,10 @@ void FixEOStableRXKokkos::setup(int vflag) dpdTheta= atomKK->k_dpdTheta.view(); uCG = atomKK->k_uCG.view(); uCGnew = atomKK->k_uCGnew.view(); + dvector = atomKK->k_dvector.view(); + + atomKK->sync(execution_space,MASK_MASK | UCOND_MASK | UMECH_MASK | UCHEM_MASK | DPDTHETA_MASK | UCG_MASK | UCGNEW_MASK | DVECTOR_MASK); + atomKK->modified(execution_space,UCHEM_MASK | DPDTHETA_MASK | UCG_MASK | UCGNEW_MASK); Kokkos::parallel_for(Kokkos::RangePolicy(0,nlocal),*this); @@ -77,6 +93,8 @@ void FixEOStableRXKokkos::setup(int vflag) Kokkos::parallel_for(Kokkos::RangePolicy(0,nlocal),*this); error_check(); + + copymode = 0; } template @@ -102,12 +120,21 @@ void FixEOStableRXKokkos::operator()(TagFixEOStableRXTemperatureLook template void FixEOStableRXKokkos::init() { + if (update_table) + create_kokkos_tables(); + + copymode = 1; + int nlocal = atom->nlocal; mask = atomKK->k_mask.view(); uCond = atomKK->k_uCond.view(); uMech = atomKK->k_uMech.view(); uChem = atomKK->k_uChem.view(); dpdTheta= atomKK->k_dpdTheta.view(); + dvector = atomKK->k_dvector.view(); + + atomKK->sync(execution_space,MASK_MASK | UCOND_MASK | UMECH_MASK | UCHEM_MASK | DPDTHETA_MASK | UCG_MASK | UCGNEW_MASK | DVECTOR_MASK); + atomKK->modified(execution_space,UCOND_MASK | UMECH_MASK | UCHEM_MASK | DPDTHETA_MASK); if (this->restart_reset) Kokkos::parallel_for(Kokkos::RangePolicy(0,nlocal),*this); @@ -115,6 +142,8 @@ void FixEOStableRXKokkos::init() Kokkos::parallel_for(Kokkos::RangePolicy(0,nlocal),*this); error_check(); + + copymode = 0; } template @@ -136,16 +165,27 @@ void FixEOStableRXKokkos::operator()(TagFixEOStableRXInit, const int template void FixEOStableRXKokkos::post_integrate() { + if (update_table) + create_kokkos_tables(); + + copymode = 1; + int nlocal = atom->nlocal; mask = atomKK->k_mask.view(); uCond = atomKK->k_uCond.view(); uMech = atomKK->k_uMech.view(); uChem = atomKK->k_uChem.view(); dpdTheta= atomKK->k_dpdTheta.view(); + dvector = atomKK->k_dvector.view(); + + atomKK->sync(execution_space,MASK_MASK | UCOND_MASK | UMECH_MASK | UCHEM_MASK | DPDTHETA_MASK | DVECTOR_MASK); + atomKK->modified(execution_space,DPDTHETA_MASK); Kokkos::parallel_for(Kokkos::RangePolicy(0,nlocal),*this); error_check(); + + copymode = 0; } template @@ -163,6 +203,11 @@ void FixEOStableRXKokkos::operator()(TagFixEOStableRXTemperatureLook template void FixEOStableRXKokkos::end_of_step() { + if (update_table) + create_kokkos_tables(); + + copymode = 1; + int nlocal = atom->nlocal; mask = atomKK->k_mask.view(); uCond = atomKK->k_uCond.view(); @@ -171,7 +216,10 @@ void FixEOStableRXKokkos::end_of_step() dpdTheta= atomKK->k_dpdTheta.view(); uCG = atomKK->k_uCG.view(); uCGnew = atomKK->k_uCGnew.view(); - double duChem; + dvector = atomKK->k_dvector.view(); + + atomKK->sync(execution_space,MASK_MASK | UCOND_MASK | UMECH_MASK | UCHEM_MASK | DPDTHETA_MASK | UCG_MASK | UCGNEW_MASK | DVECTOR_MASK); + atomKK->modified(execution_space,UCHEM_MASK | DPDTHETA_MASK | UCG_MASK | UCGNEW_MASK); // Communicate the ghost uCGnew comm->reverse_comm_fix(this); @@ -184,6 +232,8 @@ void FixEOStableRXKokkos::end_of_step() Kokkos::parallel_for(Kokkos::RangePolicy(0,nlocal),*this); error_check(); + + copymode = 0; } /* ---------------------------------------------------------------------- @@ -200,22 +250,27 @@ void FixEOStableRXKokkos::energy_lookup(int id, double thetai, doubl ui = 0.0; nTotal = 0.0; for(int ispecies=0;ispecieslo); - thetai = MIN(thetai,tb->hi); + //Table *tb = &tables[ispecies]; + //thetai = MAX(thetai,tb->lo); + thetai = MAX(thetai,d_table_const.lo(ispecies)); + //thetai = MIN(thetai,tb->hi); + thetai = MIN(thetai,d_table_const.hi(ispecies)); if (tabstyle == LINEAR) { - itable = static_cast ((thetai - tb->lo) * tb->invdelta); - fraction = (thetai - tb->r[itable]) * tb->invdelta; - uTmp = tb->e[itable] + fraction*tb->de[itable]; + //itable = static_cast ((thetai - tb->lo) * tb->invdelta); + itable = static_cast ((thetai - d_table_const.lo(ispecies)) * d_table_const.invdelta(ispecies)); + //fraction = (thetai - tb->r[itable]) * tb->invdelta; + fraction = (thetai - d_table_const.r(ispecies,itable)) * d_table_const.invdelta(ispecies); + //uTmp = tb->e[itable] + fraction*tb->de[itable]; + uTmp = d_table_const.e(ispecies,itable) + fraction*d_table_const.de(ispecies,itable); uTmp += dHf[ispecies]; // mol fraction form: - ui += atom->dvector[ispecies][id]*uTmp; - nTotal += atom->dvector[ispecies][id]; + ui += dvector(ispecies,id)*uTmp; + nTotal += dvector(ispecies,id); } } - ui = ui - double(nTotal+1.5)*force->boltz*thetai; + ui = ui - double(nTotal+1.5)*force->boltz*thetai; // need class variable } /* ---------------------------------------------------------------------- @@ -226,18 +281,20 @@ template KOKKOS_INLINE_FUNCTION void FixEOStableRXKokkos::temperature_lookup(int id, double ui, double &thetai) const { - Table *tb = &tables[0]; + //Table *tb = &tables[0]; int it; double t1,t2,u1,u2,f1,f2; double maxit = 100; double temp; double delta = 0.001; + int lo = d_table_const.lo(0); + int hi = d_table_const.hi(0); // Store the current thetai in t1 - t1 = MAX(thetai,tb->lo); - t1 = MIN(t1,tb->hi); - if(t1==tb->hi) delta = -delta; + t1 = MAX(thetai,lo); + t1 = MIN(t1,hi); + if(t1==hi) delta = -delta; // Compute u1 at thetai energy_lookup(id,t1,u1); @@ -259,8 +316,8 @@ void FixEOStableRXKokkos::temperature_lookup(int id, double ui, doub if(fabs(f2-f1)<1e-15){ if(isnan(f1) || isnan(f2)) k_error_flag.d_view() = 2; temp = t1; - temp = MAX(temp,tb->lo); - temp = MIN(temp,tb->hi); + temp = MAX(temp,lo); + temp = MIN(temp,hi); k_warning_flag.d_view() = 1; break; } @@ -286,9 +343,6 @@ template int FixEOStableRXKokkos::pack_forward_comm(int n, int *list, double *buf, int pbc_flag, int *pbc) { int ii,jj,m; - uChem = atomKK->k_uChem.view(); - uCG = atomKK->k_uCG.view(); - uCGnew = atomKK->k_uCGnew.view(); m = 0; for (ii = 0; ii < n; ii++) { @@ -306,9 +360,6 @@ template void FixEOStableRXKokkos::unpack_forward_comm(int n, int first, double *buf) { int ii,m,last; - uChem = atomKK->k_uChem.view(); - uCG = atomKK->k_uCG.view(); - uCGnew = atomKK->k_uCGnew.view(); m = 0; last = first + n ; @@ -325,8 +376,6 @@ template int FixEOStableRXKokkos::pack_reverse_comm(int n, int first, double *buf) { int i,m,last; - uCG = atomKK->k_uCG.view(); - uCGnew = atomKK->k_uCGnew.view(); m = 0; last = first + n; @@ -343,8 +392,6 @@ template void FixEOStableRXKokkos::unpack_reverse_comm(int n, int *list, double *buf) { int i,j,m; - uCG = atomKK->k_uCG.view(); - uCGnew = atomKK->k_uCGnew.view(); m = 0; for (i = 0; i < n; i++) { @@ -381,6 +428,55 @@ void FixEOStableRXKokkos::error_check() /* ---------------------------------------------------------------------- */ +template +void FixEOStableRXKokkos::create_kokkos_tables() +{ + const int tlm1 = tablength-1; + + memory->create_kokkos(d_table->lo,h_table->lo,ntables,"Table::lo"); + memory->create_kokkos(d_table->hi,h_table->hi,ntables,"Table::hi"); + memory->create_kokkos(d_table->invdelta,h_table->invdelta,ntables,"Table::invdelta"); + + if(tabstyle == LINEAR) { + memory->create_kokkos(d_table->r,h_table->r,ntables,tablength,"Table::r"); + memory->create_kokkos(d_table->e,h_table->e,ntables,tablength,"Table::e"); + memory->create_kokkos(d_table->de,h_table->de,ntables,tlm1,"Table::de"); + } + + for(int i=0; i < ntables; i++) { + Table* tb = &tables[i]; + + h_table->lo[i] = tb->lo; + h_table->hi[i] = tb->hi; + h_table->invdelta[i] = tb->invdelta; + + for(int j = 0; jr.dimension_1(); j++) + h_table->r(i,j) = tb->r[j]; + for(int j = 0; je.dimension_1(); j++) + h_table->e(i,j) = tb->e[j]; + for(int j = 0; jde.dimension_1(); j++) + h_table->de(i,j) = tb->de[j]; + } + + Kokkos::deep_copy(d_table->lo,h_table->lo); + Kokkos::deep_copy(d_table->hi,h_table->hi); + Kokkos::deep_copy(d_table->invdelta,h_table->invdelta); + Kokkos::deep_copy(d_table->r,h_table->r); + Kokkos::deep_copy(d_table->e,h_table->e); + Kokkos::deep_copy(d_table->de,h_table->de); + + d_table_const.lo = d_table->lo; + d_table_const.hi = d_table->hi; + d_table_const.invdelta = d_table->invdelta; + d_table_const.r = d_table->r; + d_table_const.e = d_table->e; + d_table_const.de = d_table->de; + + update_table = 0; +} + +/* ---------------------------------------------------------------------- */ + namespace LAMMPS_NS { template class FixEOStableRXKokkos; #ifdef KOKKOS_HAVE_CUDA diff --git a/src/KOKKOS/fix_eos_table_rx_kokkos.h b/src/KOKKOS/fix_eos_table_rx_kokkos.h index 9b0ca366a0..7de8f4dbc4 100644 --- a/src/KOKKOS/fix_eos_table_rx_kokkos.h +++ b/src/KOKKOS/fix_eos_table_rx_kokkos.h @@ -75,13 +75,46 @@ class FixEOStableRXKokkos : public FixEOStableRX { //}; //Table *tables, *tables2; + /*struct TableDeviceConst { + typename ArrayTypes::t_int_1d_randomread lo,hi; + typename ArrayTypes::t_ffloat_1d_randomread invdelta; + typename ArrayTypes::t_ffloat_2d_randomread r,e,de; + };*/ + //Its faster not to use texture fetch if the number of tables is less than 32! + struct TableDeviceConst { + typename ArrayTypes::t_int_1d lo,hi; + typename ArrayTypes::t_ffloat_1d invdelta; + typename ArrayTypes::t_ffloat_2d_randomread r,e,de; + }; + + struct TableDevice { + typename ArrayTypes::t_int_1d lo,hi; + typename ArrayTypes::t_ffloat_1d invdelta; + typename ArrayTypes::t_ffloat_2d r,e,de; + }; + + struct TableHost { + typename ArrayTypes::t_int_1d lo,hi; + typename ArrayTypes::t_ffloat_1d invdelta; + typename ArrayTypes::t_ffloat_2d r,e,de; + }; + + TableDeviceConst d_table_const; + TableDevice* d_table; + TableHost* h_table; + + int **tabindex; + void allocate(); void error_check(); + int update_table; + void create_kokkos_tables(); //double *dHf; typename AT::t_int_1d mask; typename AT::t_efloat_1d uCond,uMech,uChem,uCG,uCGnew,rho,dpdTheta,duChem; + typename AT::t_float_2d dvector; DAT::tdual_int_scalar k_error_flag; DAT::tdual_int_scalar k_warning_flag; From 5cae3eca8c43fc9712a28776e1d196b638d8216c Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 16 Dec 2016 17:09:19 -0700 Subject: [PATCH 017/439] Whitespace cleanup to pair_dpd_fdt_energy, should be cherry-picked to Master --- src/USER-DPD/pair_dpd_fdt_energy.cpp | 80 ++++++++++++++-------------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/src/USER-DPD/pair_dpd_fdt_energy.cpp b/src/USER-DPD/pair_dpd_fdt_energy.cpp index 2041405467..0f6141d015 100644 --- a/src/USER-DPD/pair_dpd_fdt_energy.cpp +++ b/src/USER-DPD/pair_dpd_fdt_energy.cpp @@ -206,7 +206,7 @@ void PairDPDfdtEnergy::compute(int eflag, int vflag) if (r < EPSILON) continue; // r can be 0.0 in DPD systems rinv = 1.0/r; wr = 1.0 - r/cut[itype][jtype]; - wd = wr*wr; + wd = wr*wr; delvx = vxtmp - v[j][0]; delvy = vytmp - v[j][1]; @@ -214,11 +214,11 @@ void PairDPDfdtEnergy::compute(int eflag, int vflag) dot = delx*delvx + dely*delvy + delz*delvz; randnum = random->gaussian(); - // Compute the current temperature - theta_ij = 0.5*(1.0/dpdTheta[i] + 1.0/dpdTheta[j]); - theta_ij = 1.0/theta_ij; - - gamma_ij = sigma[itype][jtype]*sigma[itype][jtype] + // Compute the current temperature + theta_ij = 0.5*(1.0/dpdTheta[i] + 1.0/dpdTheta[j]); + theta_ij = 1.0/theta_ij; + + gamma_ij = sigma[itype][jtype]*sigma[itype][jtype] / (2.0*force->boltz*theta_ij); // conservative force = a0 * wr @@ -239,44 +239,44 @@ void PairDPDfdtEnergy::compute(int eflag, int vflag) f[j][2] -= delz*fpair; } - if (rmass) { - mass_i = rmass[i]; - mass_j = rmass[j]; - } else { - mass_i = mass[itype]; - mass_j = mass[jtype]; - } - massinv_i = 1.0 / mass_i; - massinv_j = 1.0 / mass_j; + if (rmass) { + mass_i = rmass[i]; + mass_j = rmass[j]; + } else { + mass_i = mass[itype]; + mass_j = mass[jtype]; + } + massinv_i = 1.0 / mass_i; + massinv_j = 1.0 / mass_j; - // Compute the mechanical and conductive energy, uMech and uCond - mu_ij = massinv_i + massinv_j; - mu_ij *= force->ftm2v; + // Compute the mechanical and conductive energy, uMech and uCond + mu_ij = massinv_i + massinv_j; + mu_ij *= force->ftm2v; - uTmp = gamma_ij*wd*rinv*rinv*dot*dot - - 0.5*sigma[itype][jtype]*sigma[itype][jtype]*mu_ij*wd; - uTmp -= sigma[itype][jtype]*wr*rinv*dot*randnum*dtinvsqrt; - uTmp *= 0.5; + uTmp = gamma_ij*wd*rinv*rinv*dot*dot + - 0.5*sigma[itype][jtype]*sigma[itype][jtype]*mu_ij*wd; + uTmp -= sigma[itype][jtype]*wr*rinv*dot*randnum*dtinvsqrt; + uTmp *= 0.5; - duMech[i] += uTmp; - if (newton_pair || j < nlocal) { - duMech[j] += uTmp; - } - - // Compute uCond - randnum = random->gaussian(); - kappa_ij = kappa[itype][jtype]; - alpha_ij = sqrt(2.0*force->boltz*kappa_ij); - randPair = alpha_ij*wr*randnum*dtinvsqrt; + duMech[i] += uTmp; + if (newton_pair || j < nlocal) { + duMech[j] += uTmp; + } + + // Compute uCond + randnum = random->gaussian(); + kappa_ij = kappa[itype][jtype]; + alpha_ij = sqrt(2.0*force->boltz*kappa_ij); + randPair = alpha_ij*wr*randnum*dtinvsqrt; + + uTmp = kappa_ij*(1.0/dpdTheta[i] - 1.0/dpdTheta[j])*wd; + uTmp += randPair; + + duCond[i] += uTmp; + if (newton_pair || j < nlocal) { + duCond[j] -= uTmp; + } - uTmp = kappa_ij*(1.0/dpdTheta[i] - 1.0/dpdTheta[j])*wd; - uTmp += randPair; - - duCond[i] += uTmp; - if (newton_pair || j < nlocal) { - duCond[j] -= uTmp; - } - if (eflag) { // unshifted eng of conservative term: // evdwl = -a0[itype][jtype]*r * (1.0-0.5*r/cut[itype][jtype]); From ac57f4721cea7db41b6b964d6fb4a772fa5c5202 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 16 Dec 2016 17:14:27 -0700 Subject: [PATCH 018/439] Small whitespace tweak to pair_dpd_fdt_energy --- src/USER-DPD/pair_dpd_fdt_energy.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/USER-DPD/pair_dpd_fdt_energy.cpp b/src/USER-DPD/pair_dpd_fdt_energy.cpp index 0f6141d015..558994d35e 100644 --- a/src/USER-DPD/pair_dpd_fdt_energy.cpp +++ b/src/USER-DPD/pair_dpd_fdt_energy.cpp @@ -254,7 +254,7 @@ void PairDPDfdtEnergy::compute(int eflag, int vflag) mu_ij *= force->ftm2v; uTmp = gamma_ij*wd*rinv*rinv*dot*dot - - 0.5*sigma[itype][jtype]*sigma[itype][jtype]*mu_ij*wd; + - 0.5*sigma[itype][jtype]*sigma[itype][jtype]*mu_ij*wd; uTmp -= sigma[itype][jtype]*wr*rinv*dot*randnum*dtinvsqrt; uTmp *= 0.5; From 21bb603b93181e4551ebc69fc0e225bf055cd21d Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Mon, 19 Dec 2016 13:30:00 -0700 Subject: [PATCH 019/439] Porting recent changes from USER-DPD package to KOKKOS package --- src/KOKKOS/fix_eos_table_rx_kokkos.cpp | 7 ++-- src/KOKKOS/fix_eos_table_rx_kokkos.h | 4 +++ src/KOKKOS/pair_exp6_rx_kokkos.cpp | 50 ++++++++++++++++++++------ 3 files changed, 47 insertions(+), 14 deletions(-) diff --git a/src/KOKKOS/fix_eos_table_rx_kokkos.cpp b/src/KOKKOS/fix_eos_table_rx_kokkos.cpp index 6cb5c0611a..3b22f61e66 100644 --- a/src/KOKKOS/fix_eos_table_rx_kokkos.cpp +++ b/src/KOKKOS/fix_eos_table_rx_kokkos.cpp @@ -85,7 +85,8 @@ void FixEOStableRXKokkos::setup(int vflag) atomKK->sync(execution_space,MASK_MASK | UCOND_MASK | UMECH_MASK | UCHEM_MASK | DPDTHETA_MASK | UCG_MASK | UCGNEW_MASK | DVECTOR_MASK); atomKK->modified(execution_space,UCHEM_MASK | DPDTHETA_MASK | UCG_MASK | UCGNEW_MASK); - Kokkos::parallel_for(Kokkos::RangePolicy(0,nlocal),*this); + if (!this->restart_reset) + Kokkos::parallel_for(Kokkos::RangePolicy(0,nlocal),*this); // Communicate the updated momenta and velocities to all nodes comm->forward_comm_fix(this); @@ -154,8 +155,8 @@ void FixEOStableRXKokkos::operator()(TagFixEOStableRXInit, const int if(dpdTheta[i] <= 0.0) k_error_flag.d_view() = 1; energy_lookup(i,dpdTheta[i],tmp); - uCond[i] = tmp / 2.0; - uMech[i] = tmp / 2.0; + uCond[i] = 0.0; + uMech[i] = tmp; uChem[i] = 0.0; } } diff --git a/src/KOKKOS/fix_eos_table_rx_kokkos.h b/src/KOKKOS/fix_eos_table_rx_kokkos.h index 7de8f4dbc4..3b9a00afe2 100644 --- a/src/KOKKOS/fix_eos_table_rx_kokkos.h +++ b/src/KOKKOS/fix_eos_table_rx_kokkos.h @@ -155,6 +155,10 @@ E: eos/table/rx values are not increasing The equation-of-state must an increasing function +E: FixEOStableRX requires atom_style with internal temperature and energies (e.g. dpd) + +Self-explanatory. + E: Internal temperature <= zero. Self-explanatory. diff --git a/src/KOKKOS/pair_exp6_rx_kokkos.cpp b/src/KOKKOS/pair_exp6_rx_kokkos.cpp index e7934cfa0b..e6b8a80f44 100644 --- a/src/KOKKOS/pair_exp6_rx_kokkos.cpp +++ b/src/KOKKOS/pair_exp6_rx_kokkos.cpp @@ -187,8 +187,10 @@ void PairExp6rxKokkos::compute(int eflag_in, int vflag_in) k_error_flag.template modify(); k_error_flag.template sync(); - if (k_error_flag.h_view()) + if (k_error_flag.h_view() == 1) error->all(FLERR,"The number of molecules in CG particle is less than 1e-8."); + else if (k_error_flag.h_view() == 2) + error->all(FLERR,"Computed fraction less than -1.0e-10"); int inum = list->inum; NeighListKokkos* k_list = static_cast*>(list); @@ -432,13 +434,13 @@ void PairExp6rxKokkos::operator()(TagPairExp6rxCompute::operator()(TagPairExp6rxCompute::operator()(TagPairExp6rxCompute::operator()(TagPairExp6rxCompute::getParamsEXP6(int id,double &epsilon1,double rm2_old *= pow(nTotalOFA_old,fuchslinR); } } + + // Check that no fractions are less than zero + if(fraction1 < 0.0){ + if(fraction1 < -1.0e-10){ + k_error_flag.d_view() = 2; + } + fraction1 = 0.0; + } + if(fraction2 < 0.0){ + if(fraction2 < -1.0e-10){ + k_error_flag.d_view() = 2; + } + fraction2 = 0.0; + } + if(fraction1_old < 0.0){ + if(fraction1_old < -1.0e-10){ + k_error_flag.d_view() = 2; + } + fraction1_old = 0.0; + } + if(fraction2_old < 0.0){ + if(fraction2_old < -1.0e-10){ + k_error_flag.d_view() = 2; + } + fraction2_old = 0.0; + } } /* ---------------------------------------------------------------------- */ From 3f1f51c1c7551165d023f8269663e45a0ccb08c3 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Mon, 19 Dec 2016 13:31:09 -0700 Subject: [PATCH 020/439] Changes necessary for runtime testing of Kokkos styles --- src/USER-DPD/fix_rx.cpp | 4 ++-- src/pair_hybrid.cpp | 3 --- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/USER-DPD/fix_rx.cpp b/src/USER-DPD/fix_rx.cpp index 47194cd7bc..1c2313c694 100644 --- a/src/USER-DPD/fix_rx.cpp +++ b/src/USER-DPD/fix_rx.cpp @@ -363,11 +363,11 @@ void FixRX::post_constructor() newarg2[nspecies+3] = (char *) "ghost"; newarg2[nspecies+4] = (char *) "yes"; - modify->add_fix(nspecies+5,newarg); + modify->add_fix(nspecies+5,newarg,1); fix_species = (FixPropertyAtom *) modify->fix[modify->nfix-1]; restartFlag = modify->fix[modify->nfix-1]->restart_reset; - modify->add_fix(nspecies+5,newarg2); + modify->add_fix(nspecies+5,newarg2,1); fix_species_old = (FixPropertyAtom *) modify->fix[modify->nfix-1]; if(nspecies==0) error->all(FLERR,"There are no rx species specified."); diff --git a/src/pair_hybrid.cpp b/src/pair_hybrid.cpp index 620ceadfd9..d756b9be98 100644 --- a/src/pair_hybrid.cpp +++ b/src/pair_hybrid.cpp @@ -39,9 +39,6 @@ PairHybrid::PairHybrid(LAMMPS *lmp) : Pair(lmp), outerflag = 0; respaflag = 0; - - if (lmp->kokkos) - error->all(FLERR,"Cannot yet use pair hybrid with Kokkos"); } /* ---------------------------------------------------------------------- */ From 000df6e1cf3ebf6cfccc69268aafd60ed1fba1b0 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Mon, 19 Dec 2016 15:20:10 -0700 Subject: [PATCH 021/439] Fixing what seems to be a Kokkos bug, I will submit to Kokkos lib developers too --- lib/kokkos/algorithms/src/Kokkos_Random.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/kokkos/algorithms/src/Kokkos_Random.hpp b/lib/kokkos/algorithms/src/Kokkos_Random.hpp index d7c06dc14b..d54abeceb0 100644 --- a/lib/kokkos/algorithms/src/Kokkos_Random.hpp +++ b/lib/kokkos/algorithms/src/Kokkos_Random.hpp @@ -670,8 +670,8 @@ namespace Kokkos { double S = 2.0; double U; while(S>=1.0) { - U = drand(); - const double V = drand(); + U = 2.0*drand() - 1.0; + const double V = 2.0*drand() - 1.0; S = U*U+V*V; } return U*sqrt(-2.0*log(S)/S); From 99910fc43241df916648ad24253f8c757a1b711c Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Mon, 19 Dec 2016 15:27:16 -0700 Subject: [PATCH 022/439] Adding CPU runtime tested version of pair_dpd_fdt_energy_kokkos --- src/KOKKOS/Install.sh | 2 + src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp | 694 ++++++++++++++++------ src/KOKKOS/pair_dpd_fdt_energy_kokkos.h | 104 +++- src/KOKKOS/rand_pool_wrap.cpp | 72 +++ src/KOKKOS/rand_pool_wrap.h | 84 +++ src/USER-DPD/pair_dpd_fdt_energy.cpp | 2 + src/USER-DPD/pair_dpd_fdt_energy.h | 6 +- 7 files changed, 737 insertions(+), 227 deletions(-) create mode 100644 src/KOKKOS/rand_pool_wrap.cpp create mode 100644 src/KOKKOS/rand_pool_wrap.h diff --git a/src/KOKKOS/Install.sh b/src/KOKKOS/Install.sh index a1830163bd..94be32cc32 100644 --- a/src/KOKKOS/Install.sh +++ b/src/KOKKOS/Install.sh @@ -200,6 +200,8 @@ action pair_tersoff_zbl_kokkos.cpp pair_tersoff_zbl.cpp action pair_tersoff_zbl_kokkos.h pair_tersoff_zbl.h action pppm_kokkos.cpp pppm.cpp action pppm_kokkos.h pppm.h +action rand_pool_wrap_kokkos.cpp +action rand_pool_wrap_kokkos.h action region_block_kokkos.cpp action region_block_kokkos.h action verlet_kokkos.cpp diff --git a/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp b/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp index 0bfbb9491e..3b49f43246 100644 --- a/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp +++ b/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp @@ -12,15 +12,13 @@ ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- - Contributing author: James Larentzos (U.S. Army Research Laboratory) + Contributing author: Stan Moore (Sandia) ------------------------------------------------------------------------- */ #include #include #include #include -#include "pair_dpd_fdt_energy_kokkos.h" -#include "kokkos.h" #include "atom_kokkos.h" #include "atom_vec.h" #include "comm.h" @@ -31,30 +29,26 @@ #include "neigh_list.h" #include "neigh_request.h" #include "random_mars.h" -#include "math_const.h" #include "memory.h" #include "modify.h" +#include "pair_dpd_fdt_energy_kokkos.h" #include "error.h" #include "atom_masks.h" using namespace LAMMPS_NS; -using namespace MathConst; - -#define KOKKOS_CUDA_MAX_THREADS 256 -#define KOKKOS_CUDA_MIN_BLOCKS 8 #define EPSILON 1.0e-10 /* ---------------------------------------------------------------------- */ template -PairDPDfdtEnergyKokkos::PairDPDfdtEnergyKokkos(LAMMPS *lmp) : PairDPDfdtEnergy(lmp) +PairDPDfdtEnergyKokkos::PairDPDfdtEnergyKokkos(LAMMPS *lmp) : + PairDPDfdtEnergy(lmp),rand_pool(seed + comm->me /** , lmp/**/) { atomKK = (AtomKokkos *) atom; execution_space = ExecutionSpaceFromDevice::space; - datamask_read = X_MASK | F_MASK | TYPE_MASK | TAG_MASK | ENERGY_MASK | VIRIAL_MASK; - datamask_modify = F_MASK | ENERGY_MASK | VIRIAL_MASK; - cutsq = NULL; + datamask_read = EMPTY_MASK; + datamask_modify = EMPTY_MASK; } /* ---------------------------------------------------------------------- */ @@ -62,26 +56,49 @@ PairDPDfdtEnergyKokkos::PairDPDfdtEnergyKokkos(LAMMPS *lmp) : PairDP template PairDPDfdtEnergyKokkos::~PairDPDfdtEnergyKokkos() { + if (copymode) return; + if (allocated) { - memory->destroy_kokkos(k_eatom,eatom); - memory->destroy_kokkos(k_vatom,vatom); - k_cutsq = DAT::tdual_ffloat_2d(); - memory->sfree(cutsq); - eatom = NULL; - vatom = NULL; - cutsq = NULL; + memory->destroy_kokkos(k_duCond,duCond); + memory->destroy_kokkos(k_duMech,duMech); } + + memory->destroy_kokkos(k_cutsq,cutsq); + + /** rand_pool.destroy();/**/ } -/* ---------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------- + init specific to this pair style +------------------------------------------------------------------------- */ template -void PairDPDfdtEnergyKokkos::cleanup_copy() { - // WHY needed: this prevents parent copy from deallocating any arrays - allocated = 0; - cutsq = NULL; - eatom = NULL; - vatom = NULL; +void PairDPDfdtEnergyKokkos::init_style() +{ + PairDPDfdtEnergy::init_style(); + + // irequest = neigh request made by parent class + + neighflag = lmp->kokkos->neighflag; + int irequest = neighbor->nrequest - 1; + + neighbor->requests[irequest]-> + kokkos_host = Kokkos::Impl::is_same::value && + !Kokkos::Impl::is_same::value; + neighbor->requests[irequest]-> + kokkos_device = Kokkos::Impl::is_same::value; + + if (neighflag == FULL) { + neighbor->requests[irequest]->full = 1; + neighbor->requests[irequest]->half = 0; + } else if (neighflag == HALF || neighflag == HALFTHREAD) { + neighbor->requests[irequest]->full = 0; + neighbor->requests[irequest]->half = 1; + } else { + error->all(FLERR,"Cannot use chosen neighbor list style with reax/c/kk"); + } + + /** rand_pool.init(random,seed);/**/ } /* ---------------------------------------------------------------------- */ @@ -89,9 +106,12 @@ void PairDPDfdtEnergyKokkos::cleanup_copy() { template void PairDPDfdtEnergyKokkos::compute(int eflag_in, int vflag_in) { + copymode = 1; + eflag = eflag_in; vflag = vflag_in; + if (neighflag == FULL) no_virial_fdotr_compute = 1; if (eflag || vflag) ev_setup(eflag,vflag); else evflag = vflag_fdotr = 0; @@ -100,35 +120,115 @@ void PairDPDfdtEnergyKokkos::compute(int eflag_in, int vflag_in) if (eflag_atom) { memory->destroy_kokkos(k_eatom,eatom); memory->create_kokkos(k_eatom,eatom,maxeatom,"pair:eatom"); - d_eatom = k_eatom.view(); + d_eatom = k_eatom.d_view; } if (vflag_atom) { memory->destroy_kokkos(k_vatom,vatom); memory->create_kokkos(k_vatom,vatom,maxvatom,6,"pair:vatom"); - d_vatom = k_vatom.view(); + d_vatom = k_vatom.d_view; } - atomKK->sync(execution_space,datamask_read); - k_cutsq.template sync(); - if (eflag || vflag) atomKK->modified(execution_space,datamask_modify); - else atomKK->modified(execution_space,F_MASK); - x = atomKK->k_x.view(); - c_x = atomKK->k_x.view(); + v = atomKK->k_v.view(); f = atomKK->k_f.view(); type = atomKK->k_type.view(); - tag = atomKK->k_tag.view(); + mass = atomKK->k_mass.view(); + rmass = atomKK->rmass; + dpdTheta = atomKK->k_dpdTheta.view(); + + k_cutsq.template sync(); + k_params.template sync(); + atomKK->sync(execution_space,X_MASK | F_MASK | TYPE_MASK | ENERGY_MASK | VIRIAL_MASK | DPDTHETA_MASK | RMASS_MASK); + if (evflag) atomKK->modified(execution_space,F_MASK | ENERGY_MASK | VIRIAL_MASK); + else atomKK->modified(execution_space,F_MASK | UCG_MASK | UCGNEW_MASK); + atomKK->k_mass.sync(); + nlocal = atom->nlocal; - nall = atom->nlocal + atom->nghost; - newton_pair = force->newton_pair; - special_lj[0] = force->special_lj[0]; - special_lj[1] = force->special_lj[1]; - special_lj[2] = force->special_lj[2]; - special_lj[3] = force->special_lj[3]; + int nghost = atom->nghost; + int newton_pair = force->newton_pair; + dtinvsqrt = 1.0/sqrt(update->dt); + + int inum = list->inum; + NeighListKokkos* k_list = static_cast*>(list); + d_numneigh = k_list->d_numneigh; + d_neighbors = k_list->d_neighbors; + d_ilist = k_list->d_ilist; + + boltz = force->boltz; + + int STACKPARAMS = 0; // optimize // loop over neighbors of my atoms - EV_FLOAT ev = pair_compute,void >(this,(NeighListKokkos*)list); + EV_FLOAT ev; + + if (splitFDT_flag) { + if (neighflag == HALF) { + if (newton_pair) { + if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } else { + if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } + } else if (neighflag == HALFTHREAD) { + if (newton_pair) { + if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } else { + if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } + } + } else { + + // Allocate memory for duCond and duMech + if (allocated) { + memory->destroy_kokkos(k_duCond,duCond); + memory->destroy_kokkos(k_duMech,duMech); + } + memory->create_kokkos(k_duCond,duCond,nlocal+nghost,"pair:duCond"); + memory->create_kokkos(k_duMech,duMech,nlocal+nghost,"pair:duMech"); + d_duCond = k_duCond.view(); + d_duMech = k_duMech.view(); + h_duCond = k_duCond.h_view; + h_duMech = k_duMech.h_view; + Kokkos::parallel_for(Kokkos::RangePolicy(0,nlocal+nghost),*this); + + atomKK->sync(execution_space,V_MASK); + + // loop over neighbors of my atoms + + if (neighflag == HALF) { + if (newton_pair) { + if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } else { + if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } + } else if (neighflag == HALFTHREAD) { + if (newton_pair) { + if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } else { + if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } + } + + // Communicate the ghost delta energies to the locally owned atoms + + k_duCond.template modify(); + k_duCond.template sync(); + k_duMech.template modify(); + k_duMech.template sync(); + comm->reverse_comm_pair(this); + //k_duCond.template modify(); + //k_duCond.template sync(); + //k_duMech.template modify(); + //k_duMech.template sync(); + } if (eflag_global) eng_vdwl += ev.evdwl; if (vflag_global) { @@ -151,125 +251,262 @@ void PairDPDfdtEnergyKokkos::compute(int eflag_in, int vflag_in) k_vatom.template modify(); k_vatom.template sync(); } + + copymode = 0; } template -template KOKKOS_INLINE_FUNCTION -F_FLOAT PairDPDfdtEnergyKokkos:: -compute_fpair(const F_FLOAT& rsq, const int& i, const int&j, const int& itype, const int& jtype) const { - (void) i; - (void) j; - const F_FLOAT r = sqrt(rsq); - if (r < EPSILON) return 0; // r can be 0.0 in DPD systems - const F_FLOAT rinv = 1.0/r; - const F_FLOAT wr = 1.0 - r/cut[itype][jtype]; - const F_FLOAT wd = wr*wr; - - // conservative force = a0 * wr - return a0[itype][jtype]*wr*rinv; +void PairDPDfdtEnergyKokkos::operator()(TagPairDPDfdtEnergyZero, const int &ii) const { + d_duCond[ii] = 0.0; + d_duMech[ii] = 0.0; } template -template +template KOKKOS_INLINE_FUNCTION -F_FLOAT PairDPDfdtEnergyKokkos:: -compute_evdwl(const F_FLOAT& rsq, const int& i, const int&j, const int& itype, const int& jtype) const { - (void) i; - (void) j; - const F_FLOAT r = sqrt(rsq); - if (r < EPSILON) return 0; // r can be 0.0 in DPD systems - const F_FLOAT rinv = 1.0/r; - const F_FLOAT wr = 1.0 - r/cut[itype][jtype]; - const F_FLOAT wd = wr*wr; - // unshifted eng of conservative term: - // evdwl = -a0[itype][jtype]*r * (1.0-0.5*r/cut[itype][jtype]); - // eng shifted to 0.0 at cutoff - return 0.5*a0[itype][jtype]*cut[itype][jtype] * wd; -} +void PairDPDfdtEnergyKokkos::operator()(TagPairDPDfdtEnergyComputeSplit, const int &ii, EV_FLOAT& ev) const { + // The f array is atomic for Half/Thread neighbor style + Kokkos::View::value> > a_f = f; -/* - int i,j,ii,jj,inum,jnum,itype,jtype; + int i,j,jj,inum,jnum,itype,jtype; double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair; - double rsq,r,rinv,wd,wr,factor_dpd; - int *ilist,*jlist,*numneigh,**firstneigh; + double vxtmp,vytmp,vztmp,delvx,delvy,delvz; + double rsq,r,rinv,wd,wr,factor_dpd,uTmp; + double dot,randnum; - evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + double kappa_ij, alpha_ij, theta_ij, gamma_ij; + double mass_i, mass_j; + double massinv_i, massinv_j; + double randPair, mu_ij; - double **x = atom->x; - double **f = atom->f; - int *type = atom->type; - int nlocal = atom->nlocal; - double *special_lj = force->special_lj; - int newton_pair = force->newton_pair; + i = d_ilist[ii]; + xtmp = x(i,0); + ytmp = x(i,1); + ztmp = x(i,2); + itype = type[i]; + jnum = d_numneigh[i]; - inum = list->inum; - ilist = list->ilist; - numneigh = list->numneigh; - firstneigh = list->firstneigh; + double fx_i = 0.0; + double fy_i = 0.0; + double fz_i = 0.0; - // loop over neighbors of my atoms + for (jj = 0; jj < jnum; jj++) { + j = d_neighbors(i,jj); + factor_dpd = special_lj[sbmask(j)]; + j &= NEIGHMASK; - for (ii = 0; ii < inum; ii++) { - i = ilist[ii]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - itype = type[i]; - jlist = firstneigh[i]; - jnum = numneigh[i]; + delx = xtmp - x(j,0); + dely = ytmp - x(j,1); + delz = ztmp - x(j,2); + rsq = delx*delx + dely*dely + delz*delz; + jtype = type[j]; - for (jj = 0; jj < jnum; jj++) { - j = jlist[jj]; - factor_dpd = special_lj[sbmask(j)]; - j &= NEIGHMASK; + double cutsq_ij = STACKPARAMS?m_cutsq[itype][jtype]:d_cutsq(itype,jtype); + if (rsq < cutsq_ij) { + r = sqrt(rsq); + if (r < EPSILON) continue; // r can be 0.0 in DPD systems + rinv = 1.0/r; + double cut_ij = STACKPARAMS?m_params[itype][jtype].cut:params(itype,jtype).cut; + wr = 1.0 - r/cut_ij; + wd = wr*wr; - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - jtype = type[j]; + // conservative force = a0 * wr + double a0_ij = STACKPARAMS?m_params[itype][jtype].a0:params(itype,jtype).a0; + fpair = a0_ij*wr; + fpair *= factor_dpd*rinv; - if (rsq < cutsq[itype][jtype]) { - r = sqrt(rsq); - if (r < EPSILON) continue; // r can be 0.0 in DPD systems - rinv = 1.0/r; - wr = 1.0 - r/cut[itype][jtype]; - wd = wr*wr; - - // conservative force = a0 * wr - fpair = a0[itype][jtype]*wr; - fpair *= factor_dpd*rinv; - - f[i][0] += delx*fpair; - f[i][1] += dely*fpair; - f[i][2] += delz*fpair; - if (newton_pair || j < nlocal) { - f[j][0] -= delx*fpair; - f[j][1] -= dely*fpair; - f[j][2] -= delz*fpair; - } - - if (eflag) { - // unshifted eng of conservative term: - // evdwl = -a0[itype][jtype]*r * (1.0-0.5*r/cut[itype][jtype]); - // eng shifted to 0.0 at cutoff - evdwl = 0.5*a0[itype][jtype]*cut[itype][jtype] * wd; - evdwl *= factor_dpd; - } - - if (evflag) ev_tally(i,j,nlocal,newton_pair, - evdwl,0.0,fpair,delx,dely,delz); + fx_i += delx*fpair; + fy_i += dely*fpair; + fz_i += delz*fpair; + if (NEWTON_PAIR || j < nlocal) { + a_f(j,0) -= delx*fpair; + a_f(j,1) -= dely*fpair; + a_f(j,2) -= delz*fpair; } + + if (eflag) { + // unshifted eng of conservative term: + // evdwl = -a0[itype][jtype]*r * (1.0-0.5*r/d_cut(itype,jtype)); + // eng shifted to 0.0 at cutoff + evdwl = 0.5*a0_ij*cut_ij * wd; + evdwl *= factor_dpd; + ev.evdwl += evdwl; + } + + if (EVFLAG) this->template ev_tally(ev,i,j,evdwl,fpair,delx,dely,delz); } } - if (vflag_fdotr) virial_fdotr_compute(); + a_f(i,0) += fx_i; + a_f(i,1) += fy_i; + a_f(i,2) += fz_i; +} + +template +template +KOKKOS_INLINE_FUNCTION +void PairDPDfdtEnergyKokkos::operator()(TagPairDPDfdtEnergyComputeSplit, const int &ii) const { + EV_FLOAT ev; + this->template operator()(TagPairDPDfdtEnergyComputeSplit(), ii, ev); +} + +template +template +KOKKOS_INLINE_FUNCTION +void PairDPDfdtEnergyKokkos::operator()(TagPairDPDfdtEnergyComputeNoSplit, const int &ii, EV_FLOAT& ev) const { + + // These array are atomic for Half/Thread neighbor style + Kokkos::View::value> > a_f = f; + Kokkos::View::value> > a_duCond = d_duCond; + Kokkos::View::value> > a_duMech = d_duMech; + + int i,j,jj,inum,jnum,itype,jtype; + double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair; + double vxtmp,vytmp,vztmp,delvx,delvy,delvz; + double rsq,r,rinv,wd,wr,factor_dpd,uTmp; + double dot,randnum; + + double kappa_ij, alpha_ij, theta_ij, gamma_ij; + double mass_i, mass_j; + double massinv_i, massinv_j; + double randPair, mu_ij; + + rand_type rand_gen = rand_pool.get_state(); + + i = d_ilist[ii]; + xtmp = x(i,0); + ytmp = x(i,1); + ztmp = x(i,2); + vxtmp = v(i,0); + vytmp = v(i,1); + vztmp = v(i,2); + itype = type[i]; + jnum = d_numneigh[i]; + + double fx_i = 0.0; + double fy_i = 0.0; + double fz_i = 0.0; + + for (jj = 0; jj < jnum; jj++) { + j = d_neighbors(i,jj); + factor_dpd = special_lj[sbmask(j)]; + j &= NEIGHMASK; + + delx = xtmp - x(j,0); + dely = ytmp - x(j,1); + delz = ztmp - x(j,2); + rsq = delx*delx + dely*dely + delz*delz; + jtype = type[j]; + + double cutsq_ij = STACKPARAMS?m_cutsq[itype][jtype]:d_cutsq(itype,jtype); + if (rsq < cutsq_ij) { + r = sqrt(rsq); + if (r < EPSILON) continue; // r can be 0.0 in DPD systems + rinv = 1.0/r; + double cut_ij = STACKPARAMS?m_params[itype][jtype].cut:params(itype,jtype).cut; + wr = 1.0 - r/cut_ij; + wd = wr*wr; + + delvx = vxtmp - v(j,0); + delvy = vytmp - v(j,1); + delvz = vztmp - v(j,2); + dot = delx*delvx + dely*delvy + delz*delvz; + randnum = rand_gen.normal(); + + // Compute the current temperature + theta_ij = 0.5*(1.0/dpdTheta[i] + 1.0/dpdTheta[j]); + theta_ij = 1.0/theta_ij; + + double sigma_ij = STACKPARAMS?m_params[itype][jtype].sigma:params(itype,jtype).sigma; + gamma_ij = sigma_ij*sigma_ij + / (2.0*boltz*theta_ij); + + // conservative force = a0 * wr + // drag force = -gamma * wr^2 * (delx dot delv) / r + // random force = sigma * wr * rnd * dtinvsqrt; + + double a0_ij = STACKPARAMS?m_params[itype][jtype].a0:params(itype,jtype).a0; + fpair = a0_ij*wr; + fpair -= gamma_ij*wd*dot*rinv; + fpair += sigma_ij*wr*randnum*dtinvsqrt; + fpair *= factor_dpd*rinv; + + fx_i += delx*fpair; + fy_i += dely*fpair; + fz_i += delz*fpair; + if (NEWTON_PAIR || j < nlocal) { + f(j,0) -= delx*fpair; + f(j,1) -= dely*fpair; + f(j,2) -= delz*fpair; + } + + if (rmass) { + mass_i = rmass[i]; + mass_j = rmass[j]; + } else { + mass_i = mass[itype]; + mass_j = mass[jtype]; + } + massinv_i = 1.0 / mass_i; + massinv_j = 1.0 / mass_j; + + // Compute the mechanical and conductive energy, uMech and uCond + mu_ij = massinv_i + massinv_j; + mu_ij *= force->ftm2v; + + uTmp = gamma_ij*wd*rinv*rinv*dot*dot + - 0.5*sigma_ij*sigma_ij*mu_ij*wd; + uTmp -= sigma_ij*wr*rinv*dot*randnum*dtinvsqrt; + uTmp *= 0.5; + + a_duMech[i] += uTmp; + if (NEWTON_PAIR || j < nlocal) { + a_duMech[j] += uTmp; + } + + // Compute uCond + randnum = rand_gen.normal(); + kappa_ij = STACKPARAMS?m_params[itype][jtype].kappa:params(itype,jtype).kappa; + alpha_ij = sqrt(2.0*boltz*kappa_ij); + randPair = alpha_ij*wr*randnum*dtinvsqrt; + + uTmp = kappa_ij*(1.0/dpdTheta[i] - 1.0/dpdTheta[j])*wd; + uTmp += randPair; + + a_duCond[i] += uTmp; + if (NEWTON_PAIR || j < nlocal) { + a_duCond[j] -= uTmp; + } + + if (eflag) { + // unshifted eng of conservative term: + // evdwl = -a0[itype][jtype]*r * (1.0-0.5*r/d_cut(itype,jtype)); + // eng shifted to 0.0 at cutoff + evdwl = 0.5*a0_ij*cut_ij * wd; + evdwl *= factor_dpd; + ev.evdwl += evdwl; + } + + if (EVFLAG) this->template ev_tally(ev,i,j,evdwl,fpair,delx,dely,delz); + } + } + + a_f(i,0) += fx_i; + a_f(i,1) += fy_i; + a_f(i,2) += fz_i; + + rand_pool.free_state(rand_gen); +} + +template +template +KOKKOS_INLINE_FUNCTION +void PairDPDfdtEnergyKokkos::operator()(TagPairDPDfdtEnergyComputeNoSplit, const int &ii) const { + EV_FLOAT ev; + this->template operator()(TagPairDPDfdtEnergyComputeNoSplit(), ii, ev); } -*/ /* ---------------------------------------------------------------------- allocate all arrays @@ -281,69 +518,26 @@ void PairDPDfdtEnergyKokkos::allocate() PairDPDfdtEnergy::allocate(); int n = atom->ntypes; + int nlocal = atom->nlocal; + int nghost = atom->nghost; + memory->destroy(cutsq); memory->create_kokkos(k_cutsq,cutsq,n+1,n+1,"pair:cutsq"); d_cutsq = k_cutsq.template view(); -} -/* ---------------------------------------------------------------------- - global settings -------------------------------------------------------------------------- */ + k_params = Kokkos::DualView("PairDPDfdtEnergy::params",n+1,n+1); + params = k_params.d_view; -template -void PairDPDfdtEnergyKokkos::settings(int narg, char **arg) -{ - if (narg != 2) error->all(FLERR,"Illegal pair_style command"); - - PairDPDfdtEnergy::settings(2,arg); -} - -/* ---------------------------------------------------------------------- - init specific to this pair style -------------------------------------------------------------------------- */ - -template -void PairDPDfdtEnergyKokkos::init_style() -{ - PairDPDfdtEnergy::init_style(); - - neighflag = lmp->kokkos->neighflag; - int irequest = neighbor->nrequest - 1; - - neighbor->requests[irequest]-> - kokkos_host = Kokkos::Impl::is_same::value && - !Kokkos::Impl::is_same::value; - neighbor->requests[irequest]-> - kokkos_device = Kokkos::Impl::is_same::value; - - if (neighflag == HALF || neighflag == HALFTHREAD) { - neighbor->requests[irequest]->full = 0; - neighbor->requests[irequest]->half = 1; - } else { - error->all(FLERR,"Cannot use chosen neighbor list style with dpd/fdt/energy/kk"); + if (!splitFDT_flag) { + memory->destroy(duCond); + memory->destroy(duMech); + memory->create_kokkos(k_duCond,duCond,nlocal+nghost+1,"pair:duCond"); + memory->create_kokkos(k_duMech,duMech,nlocal+nghost+1,"pair:duMech"); + d_duCond = k_duCond.view(); + d_duMech = k_duMech.view(); + h_duCond = k_duCond.h_view; + h_duMech = k_duMech.h_view; } - -/* - if (comm->ghost_velocity == 0) - error->all(FLERR,"Pair dpd/fdt/energy requires ghost atoms store velocity"); - - // if newton off, forces between atoms ij will be double computed - // using different random numbers - - if (force->newton_pair == 0 && comm->me == 0) error->warning(FLERR, - "Pair dpd/fdt/energy requires newton pair on"); - - int irequest = neighbor->request(this,instance_me); - neighbor->requests[irequest]->ssa = 0; - for (int i = 0; i < modify->nfix; i++) - if (strcmp(modify->fix[i]->style,"shardlow") == 0) - neighbor->requests[irequest]->ssa = 1; - - bool eos_flag = false; - for (int i = 0; i < modify->nfix; i++) - if (strncmp(modify->fix[i]->style,"eos",3) == 0) eos_flag = true; - if(!eos_flag) error->all(FLERR,"pair_style dpd/fdt/energy requires an EOS to be specified"); -*/ } /* ---------------------------------------------------------------------- @@ -355,21 +549,129 @@ double PairDPDfdtEnergyKokkos::init_one(int i, int j) { double cutone = PairDPDfdtEnergy::init_one(i,j); + k_params.h_view(i,j).cut = cut[i][j]; + k_params.h_view(i,j).a0 = a0[i][j]; + k_params.h_view(i,j).sigma = sigma[i][j]; + k_params.h_view(i,j).kappa = kappa[i][j]; + k_params.h_view(j,i) = k_params.h_view(i,j); if(i(); + k_params.template modify(); return cutone; } +/* ---------------------------------------------------------------------- */ + +template +template +KOKKOS_INLINE_FUNCTION +void PairDPDfdtEnergyKokkos::ev_tally(EV_FLOAT &ev, const int &i, const int &j, + const F_FLOAT &epair, const F_FLOAT &fpair, const F_FLOAT &delx, + const F_FLOAT &dely, const F_FLOAT &delz) const +{ + const int EFLAG = eflag; + const int VFLAG = vflag_either; + + // The eatom and vatom arrays are atomic for Half/Thread neighbor style + Kokkos::View::value> > v_eatom = k_eatom.view(); + Kokkos::View::value> > v_vatom = k_vatom.view(); + + if (EFLAG) { + if (eflag_atom) { + const E_FLOAT epairhalf = 0.5 * epair; + if (NEIGHFLAG!=FULL) { + if (NEWTON_PAIR || i < nlocal) v_eatom[i] += epairhalf; + if (NEWTON_PAIR || j < nlocal) v_eatom[j] += epairhalf; + } else { + v_eatom[i] += epairhalf; + } + } + } + + if (VFLAG) { + const E_FLOAT v0 = delx*delx*fpair; + const E_FLOAT v1 = dely*dely*fpair; + const E_FLOAT v2 = delz*delz*fpair; + const E_FLOAT v3 = delx*dely*fpair; + const E_FLOAT v4 = delx*delz*fpair; + const E_FLOAT v5 = dely*delz*fpair; + + if (vflag_global) { + if (NEIGHFLAG!=FULL) { + if (NEWTON_PAIR || i < nlocal) { + ev.v[0] += 0.5*v0; + ev.v[1] += 0.5*v1; + ev.v[2] += 0.5*v2; + ev.v[3] += 0.5*v3; + ev.v[4] += 0.5*v4; + ev.v[5] += 0.5*v5; + } + if (NEWTON_PAIR || j < nlocal) { + ev.v[0] += 0.5*v0; + ev.v[1] += 0.5*v1; + ev.v[2] += 0.5*v2; + ev.v[3] += 0.5*v3; + ev.v[4] += 0.5*v4; + ev.v[5] += 0.5*v5; + } + } else { + ev.v[0] += 0.5*v0; + ev.v[1] += 0.5*v1; + ev.v[2] += 0.5*v2; + ev.v[3] += 0.5*v3; + ev.v[4] += 0.5*v4; + ev.v[5] += 0.5*v5; + } + } + + if (vflag_atom) { + if (NEIGHFLAG!=FULL) { + if (NEWTON_PAIR || i < nlocal) { + v_vatom(i,0) += 0.5*v0; + v_vatom(i,1) += 0.5*v1; + v_vatom(i,2) += 0.5*v2; + v_vatom(i,3) += 0.5*v3; + v_vatom(i,4) += 0.5*v4; + v_vatom(i,5) += 0.5*v5; + } + if (NEWTON_PAIR || j < nlocal) { + v_vatom(j,0) += 0.5*v0; + v_vatom(j,1) += 0.5*v1; + v_vatom(j,2) += 0.5*v2; + v_vatom(j,3) += 0.5*v3; + v_vatom(j,4) += 0.5*v4; + v_vatom(j,5) += 0.5*v5; + } + } else { + v_vatom(i,0) += 0.5*v0; + v_vatom(i,1) += 0.5*v1; + v_vatom(i,2) += 0.5*v2; + v_vatom(i,3) += 0.5*v3; + v_vatom(i,4) += 0.5*v4; + v_vatom(i,5) += 0.5*v5; + } + } + } +} + +/* ---------------------------------------------------------------------- */ + +template +KOKKOS_INLINE_FUNCTION +int PairDPDfdtEnergyKokkos::sbmask(const int& j) const { + return j >> SBBITS & 3; +} namespace LAMMPS_NS { template class PairDPDfdtEnergyKokkos; #ifdef KOKKOS_HAVE_CUDA template class PairDPDfdtEnergyKokkos; #endif -} - +} \ No newline at end of file diff --git a/src/KOKKOS/pair_dpd_fdt_energy_kokkos.h b/src/KOKKOS/pair_dpd_fdt_energy_kokkos.h index a8a5f25801..b8d22eff34 100644 --- a/src/KOKKOS/pair_dpd_fdt_energy_kokkos.h +++ b/src/KOKKOS/pair_dpd_fdt_energy_kokkos.h @@ -22,67 +22,115 @@ PairStyle(dpd/fdt/energy/kk/host,PairDPDfdtEnergyKokkos) #ifndef LMP_PAIR_DPD_FDT_ENERGY_KOKKOS_H #define LMP_PAIR_DPD_FDT_ENERGY_KOKKOS_H -#include "pair_kokkos.h" #include "pair_dpd_fdt_energy.h" -#include "neigh_list_kokkos.h" +#include "pair_kokkos.h" +#include "kokkos_type.h" +#include "Kokkos_Random.hpp" +#include "rand_pool_wrap.h" namespace LAMMPS_NS { +struct TagPairDPDfdtEnergyZero{}; + +template +struct TagPairDPDfdtEnergyComputeSplit{}; + +template +struct TagPairDPDfdtEnergyComputeNoSplit{}; + template class PairDPDfdtEnergyKokkos : public PairDPDfdtEnergy { public: - enum {EnabledNeighFlags=HALFTHREAD|HALF}; - enum {COUL_FLAG=0}; typedef DeviceType device_type; + typedef ArrayTypes AT; + typedef EV_FLOAT value_type; + PairDPDfdtEnergyKokkos(class LAMMPS *); virtual ~PairDPDfdtEnergyKokkos(); virtual void compute(int, int); - virtual void settings(int, char **); void init_style(); double init_one(int, int); + void operator()(TagPairDPDfdtEnergyZero, const int&) const; + + template + KOKKOS_INLINE_FUNCTION + void operator()(TagPairDPDfdtEnergyComputeSplit, const int&, EV_FLOAT&) const; + + template + KOKKOS_INLINE_FUNCTION + void operator()(TagPairDPDfdtEnergyComputeSplit, const int&) const; + + template + KOKKOS_INLINE_FUNCTION + void operator()(TagPairDPDfdtEnergyComputeNoSplit, const int&, EV_FLOAT&) const; + + template + KOKKOS_INLINE_FUNCTION + void operator()(TagPairDPDfdtEnergyComputeNoSplit, const int&) const; + + template + KOKKOS_INLINE_FUNCTION + void ev_tally(EV_FLOAT &ev, const int &i, const int &j, + const F_FLOAT &epair, const F_FLOAT &fpair, const F_FLOAT &delx, + const F_FLOAT &dely, const F_FLOAT &delz) const; + + KOKKOS_INLINE_FUNCTION + int sbmask(const int& j) const; + + struct params_dpd { + params_dpd(){cut=0;a0=0;sigma=0;kappa=0;}; + params_dpd(int i){cut=0;a0=0;sigma=0;kappa=0;}; + F_FLOAT cut,a0,sigma,kappa; + }; + protected: - void cleanup_copy(); + int eflag,vflag; + int nlocal,neighflag; + int STACKPARAMS; + double dtinvsqrt; + double boltz; - template - KOKKOS_INLINE_FUNCTION - F_FLOAT compute_fpair(const F_FLOAT& rsq, const int& i, const int&j, const int& itype, const int& jtype) const; + virtual void allocate(); - template - KOKKOS_INLINE_FUNCTION - F_FLOAT compute_evdwl(const F_FLOAT& rsq, const int& i, const int&j, const int& itype, const int& jtype) const; + Kokkos::DualView k_params; + typename Kokkos::DualView::t_dev_const_um params; + // hardwired to space for 15 atom types + params_dpd m_params[MAX_TYPES_STACKPARAMS+1][MAX_TYPES_STACKPARAMS+1]; F_FLOAT m_cutsq[MAX_TYPES_STACKPARAMS+1][MAX_TYPES_STACKPARAMS+1]; + F_FLOAT m_cut[MAX_TYPES_STACKPARAMS+1][MAX_TYPES_STACKPARAMS+1]; typename ArrayTypes::t_x_array_randomread x; typename ArrayTypes::t_x_array c_x; + typename ArrayTypes::t_v_array_randomread v; typename ArrayTypes::t_f_array f; typename ArrayTypes::t_int_1d_randomread type; + typename ArrayTypes::t_float_1d_randomread mass; + double *rmass; + typename AT::t_efloat_1d dpdTheta; + DAT::tdual_efloat_1d k_duCond,k_duMech; + typename AT::t_efloat_1d d_duCond,d_duMech; + HAT::t_efloat_1d h_duCond,h_duMech; DAT::tdual_efloat_1d k_eatom; DAT::tdual_virial_array k_vatom; - typename ArrayTypes::t_efloat_1d d_eatom; - typename ArrayTypes::t_virial_array d_vatom; - typename ArrayTypes::t_tagint_1d tag; + DAT::t_efloat_1d d_eatom; + DAT::t_virial_array d_vatom; - int newton_pair; - double special_lj[4]; + typename AT::t_neighbors_2d d_neighbors; + typename AT::t_int_1d_randomread d_ilist; + typename AT::t_int_1d_randomread d_numneigh; typename ArrayTypes::tdual_ffloat_2d k_cutsq; typename ArrayTypes::t_ffloat_2d d_cutsq; + /**/Kokkos::Random_XorShift64_Pool rand_pool; + typedef typename Kokkos::Random_XorShift64_Pool::generator_type rand_type;/**/ - int neighflag; - int nlocal,nall,eflag,vflag; + /**RandPoolWrap rand_pool; + typedef RandWrap rand_type;/**/ - void allocate(); - - friend class PairComputeFunctor; - friend class PairComputeFunctor; - friend class PairComputeFunctor; - friend class PairComputeFunctor; - friend EV_FLOAT pair_compute_neighlist(PairDPDfdtEnergyKokkos*,NeighListKokkos*); - friend EV_FLOAT pair_compute_neighlist(PairDPDfdtEnergyKokkos*,NeighListKokkos*); - friend EV_FLOAT pair_compute(PairDPDfdtEnergyKokkos*,NeighListKokkos*); friend void pair_virial_fdotr_compute(PairDPDfdtEnergyKokkos*); }; diff --git a/src/KOKKOS/rand_pool_wrap.cpp b/src/KOKKOS/rand_pool_wrap.cpp new file mode 100644 index 0000000000..b6fd0dbc55 --- /dev/null +++ b/src/KOKKOS/rand_pool_wrap.cpp @@ -0,0 +1,72 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "comm.h" +#include "rand_pool_wrap.h" +#include "lammps.h" +#include "kokkos.h" +#include "random_mars.h" +#include "update.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +RandPoolWrap::RandPoolWrap(int, LAMMPS *lmp) : Pointers(lmp) +{ + random_thr = NULL; + nthreads = lmp->kokkos->num_threads; +} + +/* ---------------------------------------------------------------------- */ + +RandPoolWrap::~RandPoolWrap() +{ + +} + +void RandPoolWrap::destroy() +{ + if (random_thr) { + for (int i=1; i < nthreads; ++i) + delete random_thr[i]; + + delete[] random_thr; + random_thr = NULL; + } +} + +void RandPoolWrap::init(RanMars* random, int seed) +{ + // deallocate pool of RNGs + if (random_thr) { + for (int i=1; i < this->nthreads; ++i) + delete random_thr[i]; + + delete[] random_thr; + } + + // allocate pool of RNGs + // generate a random number generator instance for + // all threads != 0. make sure we use unique seeds. + nthreads = lmp->kokkos->num_threads; + random_thr = new RanMars*[nthreads]; + for (int tid = 1; tid < nthreads; ++tid) { + random_thr[tid] = new RanMars(lmp, seed + comm->me + + comm->nprocs*tid); + } + + // to ensure full compatibility with the serial style + // we use the serial random number generator instance for thread 0 + random_thr[0] = random; +} \ No newline at end of file diff --git a/src/KOKKOS/rand_pool_wrap.h b/src/KOKKOS/rand_pool_wrap.h new file mode 100644 index 0000000000..349896ee9a --- /dev/null +++ b/src/KOKKOS/rand_pool_wrap.h @@ -0,0 +1,84 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifndef RAND_POOL_WRAP_H +#define RAND_POOL_WRAP_H + +#include "pointers.h" +#include "kokkos_type.h" +#include "random_mars.h" +#include "error.h" + +namespace LAMMPS_NS { + +struct RandWrap { + class RanMars* rng; + + RandWrap() { + rng = NULL; + } + + KOKKOS_INLINE_FUNCTION + double drand() { + return rng->uniform(); + } + + KOKKOS_INLINE_FUNCTION + double normal() { + return rng->gaussian(); + } +}; + +class RandPoolWrap : protected Pointers { + public: + RandPoolWrap(int, class LAMMPS *); + ~RandPoolWrap(); + void destroy(); + void init(RanMars*, int); + + KOKKOS_INLINE_FUNCTION + RandWrap get_state() const + { +#ifdef KOKKOS_HAVE_CUDA + error->all(FLERR,"Cannot use Marsaglia RNG with GPUs"); +#endif + + RandWrap rand_wrap; + int tid = 0; +#ifndef KOKKOS_HAVE_CUDA + tid = LMPDeviceType::hardware_thread_id(); +#endif + rand_wrap.rng = random_thr[tid]; + return rand_wrap; + } + + KOKKOS_INLINE_FUNCTION + void free_state(RandWrap) const + { + + } + + void clean_copy() { random_thr = NULL; } + + private: + class RanMars **random_thr; + int nthreads; +}; + +} + +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/USER-DPD/pair_dpd_fdt_energy.cpp b/src/USER-DPD/pair_dpd_fdt_energy.cpp index 558994d35e..19994acfa1 100644 --- a/src/USER-DPD/pair_dpd_fdt_energy.cpp +++ b/src/USER-DPD/pair_dpd_fdt_energy.cpp @@ -54,6 +54,8 @@ PairDPDfdtEnergy::PairDPDfdtEnergy(LAMMPS *lmp) : Pair(lmp) PairDPDfdtEnergy::~PairDPDfdtEnergy() { + if (copymode) return; + if (allocated) { memory->destroy(setflag); memory->destroy(cutsq); diff --git a/src/USER-DPD/pair_dpd_fdt_energy.h b/src/USER-DPD/pair_dpd_fdt_energy.h index 335beea7e3..ff29667682 100644 --- a/src/USER-DPD/pair_dpd_fdt_energy.h +++ b/src/USER-DPD/pair_dpd_fdt_energy.h @@ -31,8 +31,8 @@ class PairDPDfdtEnergy : public Pair { virtual void compute(int, int); virtual void settings(int, char **); virtual void coeff(int, char **); - void init_style(); - double init_one(int, int); + virtual void init_style(); + virtual double init_one(int, int); void write_restart(FILE *); void read_restart(FILE *); virtual void write_restart_settings(FILE *); @@ -53,7 +53,7 @@ class PairDPDfdtEnergy : public Pair { int seed; bool splitFDT_flag; - void allocate(); + virtual void allocate(); }; From 6f51c3b75c49e4777304e6f926ad53f4792e2ce1 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Mon, 19 Dec 2016 16:25:31 -0700 Subject: [PATCH 023/439] Fixing issues in pair_multi_lucy_rx_kokkos --- src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp | 4 ---- src/KOKKOS/pair_multi_lucy_rx_kokkos.h | 1 - 2 files changed, 5 deletions(-) diff --git a/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp b/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp index 03bbaf9907..76337b5219 100644 --- a/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp +++ b/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp @@ -72,8 +72,6 @@ PairMultiLucyRXKokkos::PairMultiLucyRXKokkos(LAMMPS *lmp) : PairMult datamask_modify = EMPTY_MASK; update_table = 0; - ntables = 0; - tables = NULL; h_table = new TableHost(); d_table = new TableDevice(); @@ -112,11 +110,9 @@ void PairMultiLucyRXKokkos::init_style() if (neighflag == FULL) { neighbor->requests[irequest]->full = 1; neighbor->requests[irequest]->half = 0; - neighbor->requests[irequest]->ghost = 1; } else if (neighflag == HALF || neighflag == HALFTHREAD) { neighbor->requests[irequest]->full = 0; neighbor->requests[irequest]->half = 1; - neighbor->requests[irequest]->ghost = 1; } else { error->all(FLERR,"Cannot use chosen neighbor list style with multi/lucy/rx/kk"); } diff --git a/src/KOKKOS/pair_multi_lucy_rx_kokkos.h b/src/KOKKOS/pair_multi_lucy_rx_kokkos.h index a259588f78..b205f00796 100644 --- a/src/KOKKOS/pair_multi_lucy_rx_kokkos.h +++ b/src/KOKKOS/pair_multi_lucy_rx_kokkos.h @@ -119,7 +119,6 @@ class PairMultiLucyRXKokkos : public PairMultiLucyRX { // double *rsq,*drsq,*e,*de,*f,*df,*e2,*f2; //}; - int tabstyle,tablength; /*struct TableDeviceConst { typename ArrayTypes::t_ffloat_2d_randomread cutsq; typename ArrayTypes::t_int_2d_randomread tabindex; From f62a6fe5a55d17cb95d0a3088d2c5d7f7f10b0ee Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Mon, 19 Dec 2016 16:50:22 -0700 Subject: [PATCH 024/439] Renaming rand_pool_wrap to rand_pool_wrap_kokkos --- src/KOKKOS/pair_dpd_fdt_energy_kokkos.h | 2 +- src/KOKKOS/{rand_pool_wrap.cpp => rand_pool_wrap_kokkos.cpp} | 4 ++-- src/KOKKOS/{rand_pool_wrap.h => rand_pool_wrap_kokkos.h} | 0 3 files changed, 3 insertions(+), 3 deletions(-) rename src/KOKKOS/{rand_pool_wrap.cpp => rand_pool_wrap_kokkos.cpp} (98%) rename src/KOKKOS/{rand_pool_wrap.h => rand_pool_wrap_kokkos.h} (100%) diff --git a/src/KOKKOS/pair_dpd_fdt_energy_kokkos.h b/src/KOKKOS/pair_dpd_fdt_energy_kokkos.h index b8d22eff34..67fa315721 100644 --- a/src/KOKKOS/pair_dpd_fdt_energy_kokkos.h +++ b/src/KOKKOS/pair_dpd_fdt_energy_kokkos.h @@ -26,7 +26,7 @@ PairStyle(dpd/fdt/energy/kk/host,PairDPDfdtEnergyKokkos) #include "pair_kokkos.h" #include "kokkos_type.h" #include "Kokkos_Random.hpp" -#include "rand_pool_wrap.h" +#include "rand_pool_wrap_kokkos.h" namespace LAMMPS_NS { diff --git a/src/KOKKOS/rand_pool_wrap.cpp b/src/KOKKOS/rand_pool_wrap_kokkos.cpp similarity index 98% rename from src/KOKKOS/rand_pool_wrap.cpp rename to src/KOKKOS/rand_pool_wrap_kokkos.cpp index b6fd0dbc55..c11764640b 100644 --- a/src/KOKKOS/rand_pool_wrap.cpp +++ b/src/KOKKOS/rand_pool_wrap_kokkos.cpp @@ -12,7 +12,7 @@ ------------------------------------------------------------------------- */ #include "comm.h" -#include "rand_pool_wrap.h" +#include "rand_pool_wrap_kokkos.h" #include "lammps.h" #include "kokkos.h" #include "random_mars.h" @@ -69,4 +69,4 @@ void RandPoolWrap::init(RanMars* random, int seed) // to ensure full compatibility with the serial style // we use the serial random number generator instance for thread 0 random_thr[0] = random; -} \ No newline at end of file +} diff --git a/src/KOKKOS/rand_pool_wrap.h b/src/KOKKOS/rand_pool_wrap_kokkos.h similarity index 100% rename from src/KOKKOS/rand_pool_wrap.h rename to src/KOKKOS/rand_pool_wrap_kokkos.h From 889ee78f8ba0587020cffe61d5a6cb6515f2e4c6 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Mon, 19 Dec 2016 17:15:02 -0700 Subject: [PATCH 025/439] Change necessary for pair_exp6_rx_kokkos to compile on GPU --- src/USER-DPD/pair_exp6_rx.h | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/USER-DPD/pair_exp6_rx.h b/src/USER-DPD/pair_exp6_rx.h index f9654e4086..2dfc1c1a2e 100644 --- a/src/USER-DPD/pair_exp6_rx.h +++ b/src/USER-DPD/pair_exp6_rx.h @@ -37,6 +37,14 @@ class PairExp6rx : public Pair { void write_restart_settings(FILE *); void read_restart_settings(FILE *); + struct Param { + double epsilon,rm,alpha; + int ispecies; + char *name, *potential; // names of unique molecules and interaction type + char *tablename; // name of interaction table + int potentialType; // enumerated interaction potential type. + }; + protected: enum{LINEAR}; double cut_global; @@ -48,13 +56,6 @@ class PairExp6rx : public Pair { int *mol2param; // mapping from molecule to parameters int nparams; // # of stored parameter sets int maxparam; // max # of parameter sets - struct Param { - double epsilon,rm,alpha; - int ispecies; - char *name, *potential; // names of unique molecules and interaction type - char *tablename; // name of interaction table - int potentialType; // enumerated interaction potential type. - }; Param *params; // parameter set for an I-J-K interaction int nspecies; From 35803c75c970c4f978a8623a1364fbce8e337126 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 20 Dec 2016 17:03:46 -0700 Subject: [PATCH 026/439] Fixing issues found during GPU runtime testing --- src/KOKKOS/fix_eos_table_rx_kokkos.cpp | 79 ++++++++++++++++++-------- src/KOKKOS/fix_eos_table_rx_kokkos.h | 6 +- src/KOKKOS/pair_exp6_rx_kokkos.cpp | 9 +-- 3 files changed, 65 insertions(+), 29 deletions(-) diff --git a/src/KOKKOS/fix_eos_table_rx_kokkos.cpp b/src/KOKKOS/fix_eos_table_rx_kokkos.cpp index 3b22f61e66..cf77e25ff4 100644 --- a/src/KOKKOS/fix_eos_table_rx_kokkos.cpp +++ b/src/KOKKOS/fix_eos_table_rx_kokkos.cpp @@ -49,6 +49,13 @@ FixEOStableRXKokkos::FixEOStableRXKokkos(LAMMPS *lmp, int narg, char k_error_flag = DAT::tdual_int_scalar("fix:error_flag"); k_warning_flag = DAT::tdual_int_scalar("fix:warning_flag"); + + k_dHf = DAT::tdual_float_1d("fix:dHf",nspecies); + for (int n = 0; n < nspecies; n++) + k_dHf.h_view(n) = dHf[n]; + k_dHf.modify(); + k_dHf.sync(); + d_dHf = k_dHf.view(); } /* ---------------------------------------------------------------------- */ @@ -73,6 +80,7 @@ void FixEOStableRXKokkos::setup(int vflag) copymode = 1; int nlocal = atom->nlocal; + double boltz = force->boltz; mask = atomKK->k_mask.view(); uCond = atomKK->k_uCond.view(); uMech = atomKK->k_uMech.view(); @@ -82,16 +90,20 @@ void FixEOStableRXKokkos::setup(int vflag) uCGnew = atomKK->k_uCGnew.view(); dvector = atomKK->k_dvector.view(); - atomKK->sync(execution_space,MASK_MASK | UCOND_MASK | UMECH_MASK | UCHEM_MASK | DPDTHETA_MASK | UCG_MASK | UCGNEW_MASK | DVECTOR_MASK); - atomKK->modified(execution_space,UCHEM_MASK | DPDTHETA_MASK | UCG_MASK | UCGNEW_MASK); - - if (!this->restart_reset) + if (!this->restart_reset) { + atomKK->sync(execution_space,MASK_MASK | UCHEM_MASK | UCG_MASK | UCGNEW_MASK); Kokkos::parallel_for(Kokkos::RangePolicy(0,nlocal),*this); + atomKK->modified(execution_space,UCHEM_MASK | UCG_MASK | UCGNEW_MASK); + } // Communicate the updated momenta and velocities to all nodes + atomKK->sync(Host,UCHEM_MASK | UCG_MASK | UCGNEW_MASK); comm->forward_comm_fix(this); + atomKK->modified(Host,UCHEM_MASK | UCG_MASK | UCGNEW_MASK); + atomKK->sync(execution_space,MASK_MASK | UCOND_MASK | UMECH_MASK | UCHEM_MASK | DPDTHETA_MASK | DVECTOR_MASK); Kokkos::parallel_for(Kokkos::RangePolicy(0,nlocal),*this); + atomKK->modified(execution_space,DPDTHETA_MASK); error_check(); @@ -127,6 +139,7 @@ void FixEOStableRXKokkos::init() copymode = 1; int nlocal = atom->nlocal; + double boltz = force->boltz; mask = atomKK->k_mask.view(); uCond = atomKK->k_uCond.view(); uMech = atomKK->k_uMech.view(); @@ -134,13 +147,15 @@ void FixEOStableRXKokkos::init() dpdTheta= atomKK->k_dpdTheta.view(); dvector = atomKK->k_dvector.view(); - atomKK->sync(execution_space,MASK_MASK | UCOND_MASK | UMECH_MASK | UCHEM_MASK | DPDTHETA_MASK | UCG_MASK | UCGNEW_MASK | DVECTOR_MASK); - atomKK->modified(execution_space,UCOND_MASK | UMECH_MASK | UCHEM_MASK | DPDTHETA_MASK); - - if (this->restart_reset) + if (this->restart_reset) { + atomKK->sync(execution_space,MASK_MASK | UCOND_MASK | UMECH_MASK | UCHEM_MASK | DPDTHETA_MASK | DVECTOR_MASK); Kokkos::parallel_for(Kokkos::RangePolicy(0,nlocal),*this); - else + atomKK->modified(execution_space,DPDTHETA_MASK); + } else { + atomKK->sync(execution_space,MASK_MASK | UCOND_MASK | UMECH_MASK | UCHEM_MASK | DPDTHETA_MASK | DVECTOR_MASK); Kokkos::parallel_for(Kokkos::RangePolicy(0,nlocal),*this); + atomKK->modified(execution_space,UCOND_MASK | UMECH_MASK | UCHEM_MASK | DPDTHETA_MASK); + } error_check(); @@ -172,6 +187,7 @@ void FixEOStableRXKokkos::post_integrate() copymode = 1; int nlocal = atom->nlocal; + double boltz = force->boltz; mask = atomKK->k_mask.view(); uCond = atomKK->k_uCond.view(); uMech = atomKK->k_uMech.view(); @@ -210,6 +226,7 @@ void FixEOStableRXKokkos::end_of_step() copymode = 1; int nlocal = atom->nlocal; + double boltz = force->boltz; mask = atomKK->k_mask.view(); uCond = atomKK->k_uCond.view(); uMech = atomKK->k_uMech.view(); @@ -219,18 +236,24 @@ void FixEOStableRXKokkos::end_of_step() uCGnew = atomKK->k_uCGnew.view(); dvector = atomKK->k_dvector.view(); - atomKK->sync(execution_space,MASK_MASK | UCOND_MASK | UMECH_MASK | UCHEM_MASK | DPDTHETA_MASK | UCG_MASK | UCGNEW_MASK | DVECTOR_MASK); - atomKK->modified(execution_space,UCHEM_MASK | DPDTHETA_MASK | UCG_MASK | UCGNEW_MASK); // Communicate the ghost uCGnew + atomKK->sync(Host,UCG_MASK | UCGNEW_MASK); comm->reverse_comm_fix(this); + atomKK->modified(Host,UCG_MASK | UCGNEW_MASK); + atomKK->sync(execution_space,MASK_MASK | UCHEM_MASK | UCG_MASK | UCGNEW_MASK); Kokkos::parallel_for(Kokkos::RangePolicy(0,nlocal),*this); + atomKK->modified(execution_space,UCHEM_MASK | UCG_MASK | UCGNEW_MASK); // Communicate the updated momenta and velocities to all nodes + atomKK->sync(Host,UCHEM_MASK | UCG_MASK | UCGNEW_MASK); comm->forward_comm_fix(this); + atomKK->modified(Host,UCHEM_MASK | UCG_MASK | UCGNEW_MASK); + atomKK->sync(execution_space,MASK_MASK | UCOND_MASK | UMECH_MASK | UCHEM_MASK | DPDTHETA_MASK | DVECTOR_MASK); Kokkos::parallel_for(Kokkos::RangePolicy(0,nlocal),*this); + atomKK->modified(execution_space,DPDTHETA_MASK); error_check(); @@ -265,13 +288,13 @@ void FixEOStableRXKokkos::energy_lookup(int id, double thetai, doubl //uTmp = tb->e[itable] + fraction*tb->de[itable]; uTmp = d_table_const.e(ispecies,itable) + fraction*d_table_const.de(ispecies,itable); - uTmp += dHf[ispecies]; + uTmp += d_dHf[ispecies]; // mol fraction form: ui += dvector(ispecies,id)*uTmp; nTotal += dvector(ispecies,id); } } - ui = ui - double(nTotal+1.5)*force->boltz*thetai; // need class variable + ui = ui - double(nTotal+1.5)*boltz*thetai; } /* ---------------------------------------------------------------------- @@ -344,13 +367,16 @@ template int FixEOStableRXKokkos::pack_forward_comm(int n, int *list, double *buf, int pbc_flag, int *pbc) { int ii,jj,m; + HAT::t_efloat_1d h_uChem = atomKK->k_uChem.h_view; + HAT::t_efloat_1d h_uCG = atomKK->k_uCG.h_view; + HAT::t_efloat_1d h_uCGnew = atomKK->k_uCGnew.h_view; m = 0; for (ii = 0; ii < n; ii++) { jj = list[ii]; - buf[m++] = uChem[jj]; - buf[m++] = uCG[jj]; - buf[m++] = uCGnew[jj]; + buf[m++] = h_uChem[jj]; + buf[m++] = h_uCG[jj]; + buf[m++] = h_uCGnew[jj]; } return m; } @@ -361,13 +387,16 @@ template void FixEOStableRXKokkos::unpack_forward_comm(int n, int first, double *buf) { int ii,m,last; + HAT::t_efloat_1d h_uChem = atomKK->k_uChem.h_view; + HAT::t_efloat_1d h_uCG = atomKK->k_uCG.h_view; + HAT::t_efloat_1d h_uCGnew = atomKK->k_uCGnew.h_view; m = 0; last = first + n ; for (ii = first; ii < last; ii++){ - uChem[ii] = buf[m++]; - uCG[ii] = buf[m++]; - uCGnew[ii] = buf[m++]; + h_uChem[ii] = buf[m++]; + h_uCG[ii] = buf[m++]; + h_uCGnew[ii] = buf[m++]; } } @@ -377,12 +406,14 @@ template int FixEOStableRXKokkos::pack_reverse_comm(int n, int first, double *buf) { int i,m,last; + HAT::t_efloat_1d h_uCG = atomKK->k_uCG.h_view; + HAT::t_efloat_1d h_uCGnew = atomKK->k_uCGnew.h_view; m = 0; last = first + n; for (i = first; i < last; i++) { - buf[m++] = uCG[i]; - buf[m++] = uCGnew[i]; + buf[m++] = h_uCG[i]; + buf[m++] = h_uCGnew[i]; } return m; } @@ -393,13 +424,15 @@ template void FixEOStableRXKokkos::unpack_reverse_comm(int n, int *list, double *buf) { int i,j,m; + HAT::t_efloat_1d h_uCG = atomKK->k_uCG.h_view; + HAT::t_efloat_1d h_uCGnew = atomKK->k_uCGnew.h_view; m = 0; for (i = 0; i < n; i++) { j = list[i]; - uCG[j] += buf[m++]; - uCGnew[j] += buf[m++]; + h_uCG[j] += buf[m++]; + h_uCGnew[j] += buf[m++]; } } diff --git a/src/KOKKOS/fix_eos_table_rx_kokkos.h b/src/KOKKOS/fix_eos_table_rx_kokkos.h index 3b9a00afe2..d4a5094ae0 100644 --- a/src/KOKKOS/fix_eos_table_rx_kokkos.h +++ b/src/KOKKOS/fix_eos_table_rx_kokkos.h @@ -105,12 +105,15 @@ class FixEOStableRXKokkos : public FixEOStableRX { int **tabindex; + double boltz; + void allocate(); void error_check(); int update_table; void create_kokkos_tables(); - //double *dHf; + DAT::tdual_float_1d k_dHf; + typename AT::t_float_1d d_dHf; typename AT::t_int_1d mask; typename AT::t_efloat_1d uCond,uMech,uChem,uCG,uCGnew,rho,dpdTheta,duChem; @@ -124,7 +127,6 @@ class FixEOStableRXKokkos : public FixEOStableRX { int pack_forward_comm(int , int *, double *, int, int *); void unpack_forward_comm(int , int , double *); - //int *eosSpecies; }; } diff --git a/src/KOKKOS/pair_exp6_rx_kokkos.cpp b/src/KOKKOS/pair_exp6_rx_kokkos.cpp index e6b8a80f44..a2c70ca115 100644 --- a/src/KOKKOS/pair_exp6_rx_kokkos.cpp +++ b/src/KOKKOS/pair_exp6_rx_kokkos.cpp @@ -645,7 +645,7 @@ void PairExp6rxKokkos::read_file(char *file) int params_per_line = 5; char **words = new char*[params_per_line+1]; - memory->sfree(params); + memory->destroy_kokkos(k_params,params); params = NULL; nparams = maxparam = 0; @@ -723,6 +723,7 @@ void PairExp6rxKokkos::read_file(char *file) // load up parameter settings and error check their values if (nparams == maxparam) { + k_params.template modify(); maxparam += DELTA; memory->grow_kokkos(k_params,params,maxparam, "pair:params"); @@ -823,7 +824,7 @@ void PairExp6rxKokkos::getParamsEXP6(int id,double &epsilon1,double nTotal += dvector(ispecies,id); nTotal_old += dvector(ispecies+nspecies,id); - iparam = mol2param[ispecies]; + iparam = d_mol2param[ispecies]; if (iparam < 0 || d_params[iparam].potentialType != exp6PotentialType ) continue; if (isOneFluidApprox(isite1) || isOneFluidApprox(isite2)) { @@ -840,7 +841,7 @@ void PairExp6rxKokkos::getParamsEXP6(int id,double &epsilon1,double fractionOFA = nTotalOFA / nTotal; for (int ispecies = 0; ispecies < nspecies; ispecies++) { - iparam = mol2param[ispecies]; + iparam = d_mol2param[ispecies]; if (iparam < 0 || d_params[iparam].potentialType != exp6PotentialType ) continue; // If Site1 matches a pure species, then grab the parameters @@ -881,7 +882,7 @@ void PairExp6rxKokkos::getParamsEXP6(int id,double &epsilon1,double xMolei_old = dvector(ispecies+nspecies,id)/nTotalOFA_old; for (int jspecies = 0; jspecies < nspecies; jspecies++) { - jparam = mol2param[jspecies]; + jparam = d_mol2param[jspecies]; if (jparam < 0 || d_params[jparam].potentialType != exp6PotentialType ) continue; if (isite1 == d_params[jparam].ispecies || isite2 == d_params[jparam].ispecies) continue; rmj = d_params[jparam].rm; From 73326922d67c756653f4607222b63ac1b5378139 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Wed, 21 Dec 2016 08:56:48 -0700 Subject: [PATCH 027/439] Fixing Kokkos issue in fix_eos_table_rx_kokkos --- src/KOKKOS/fix_eos_table_rx_kokkos.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/KOKKOS/fix_eos_table_rx_kokkos.cpp b/src/KOKKOS/fix_eos_table_rx_kokkos.cpp index cf77e25ff4..c47923680c 100644 --- a/src/KOKKOS/fix_eos_table_rx_kokkos.cpp +++ b/src/KOKKOS/fix_eos_table_rx_kokkos.cpp @@ -80,7 +80,7 @@ void FixEOStableRXKokkos::setup(int vflag) copymode = 1; int nlocal = atom->nlocal; - double boltz = force->boltz; + boltz = force->boltz; mask = atomKK->k_mask.view(); uCond = atomKK->k_uCond.view(); uMech = atomKK->k_uMech.view(); @@ -139,7 +139,7 @@ void FixEOStableRXKokkos::init() copymode = 1; int nlocal = atom->nlocal; - double boltz = force->boltz; + boltz = force->boltz; mask = atomKK->k_mask.view(); uCond = atomKK->k_uCond.view(); uMech = atomKK->k_uMech.view(); @@ -187,7 +187,7 @@ void FixEOStableRXKokkos::post_integrate() copymode = 1; int nlocal = atom->nlocal; - double boltz = force->boltz; + boltz = force->boltz; mask = atomKK->k_mask.view(); uCond = atomKK->k_uCond.view(); uMech = atomKK->k_uMech.view(); @@ -226,7 +226,7 @@ void FixEOStableRXKokkos::end_of_step() copymode = 1; int nlocal = atom->nlocal; - double boltz = force->boltz; + boltz = force->boltz; mask = atomKK->k_mask.view(); uCond = atomKK->k_uCond.view(); uMech = atomKK->k_uMech.view(); From 807d9529da32778eb6dbc2216f6a72b1e1325d3c Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Wed, 21 Dec 2016 10:41:29 -0700 Subject: [PATCH 028/439] Fixing issues found during GPU runtime testing --- lib/kokkos/algorithms/src/Kokkos_Random.hpp | 8 +++--- src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp | 29 ++++++++++++--------- src/KOKKOS/pair_dpd_fdt_energy_kokkos.h | 3 ++- src/KOKKOS/pair_exp6_rx_kokkos.cpp | 5 +--- src/KOKKOS/pair_exp6_rx_kokkos.h | 1 - 5 files changed, 23 insertions(+), 23 deletions(-) diff --git a/lib/kokkos/algorithms/src/Kokkos_Random.hpp b/lib/kokkos/algorithms/src/Kokkos_Random.hpp index d54abeceb0..afe6b54e90 100644 --- a/lib/kokkos/algorithms/src/Kokkos_Random.hpp +++ b/lib/kokkos/algorithms/src/Kokkos_Random.hpp @@ -910,8 +910,8 @@ namespace Kokkos { double S = 2.0; double U; while(S>=1.0) { - U = drand(); - const double V = drand(); + U = 2.0*drand() - 1.0; + const double V = 2.0*drand() - 1.0; S = U*U+V*V; } return U*sqrt(-2.0*log(S)/S); @@ -1163,8 +1163,8 @@ namespace Kokkos { double S = 2.0; double U; while(S>=1.0) { - U = drand(); - const double V = drand(); + U = 2.0*drand() - 1.0; + const double V = 2.0*drand() - 1.0; S = U*U+V*V; } return U*sqrt(-2.0*log(S)/S); diff --git a/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp b/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp index 3b49f43246..310f4689cb 100644 --- a/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp +++ b/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp @@ -138,10 +138,14 @@ void PairDPDfdtEnergyKokkos::compute(int eflag_in, int vflag_in) k_cutsq.template sync(); k_params.template sync(); - atomKK->sync(execution_space,X_MASK | F_MASK | TYPE_MASK | ENERGY_MASK | VIRIAL_MASK | DPDTHETA_MASK | RMASS_MASK); + atomKK->sync(execution_space,X_MASK | F_MASK | TYPE_MASK | ENERGY_MASK | VIRIAL_MASK); if (evflag) atomKK->modified(execution_space,F_MASK | ENERGY_MASK | VIRIAL_MASK); - else atomKK->modified(execution_space,F_MASK | UCG_MASK | UCGNEW_MASK); - atomKK->k_mass.sync(); + else atomKK->modified(execution_space,F_MASK); + + special_lj[0] = force->special_lj[0]; + special_lj[1] = force->special_lj[1]; + special_lj[2] = force->special_lj[2]; + special_lj[3] = force->special_lj[3]; nlocal = atom->nlocal; int nghost = atom->nghost; @@ -155,6 +159,7 @@ void PairDPDfdtEnergyKokkos::compute(int eflag_in, int vflag_in) d_ilist = k_list->d_ilist; boltz = force->boltz; + ftm2v = force->ftm2v; int STACKPARAMS = 0; // optimize @@ -195,7 +200,8 @@ void PairDPDfdtEnergyKokkos::compute(int eflag_in, int vflag_in) h_duMech = k_duMech.h_view; Kokkos::parallel_for(Kokkos::RangePolicy(0,nlocal+nghost),*this); - atomKK->sync(execution_space,V_MASK); + atomKK->sync(execution_space,V_MASK | DPDTHETA_MASK | RMASS_MASK); + atomKK->k_mass.sync(); // loop over neighbors of my atoms @@ -219,15 +225,12 @@ void PairDPDfdtEnergyKokkos::compute(int eflag_in, int vflag_in) // Communicate the ghost delta energies to the locally owned atoms + // this memory transfer can be removed when fix_dpd_fdt_energy_kokkos is added k_duCond.template modify(); k_duCond.template sync(); k_duMech.template modify(); k_duMech.template sync(); comm->reverse_comm_pair(this); - //k_duCond.template modify(); - //k_duCond.template sync(); - //k_duMech.template modify(); - //k_duMech.template sync(); } if (eflag_global) eng_vdwl += ev.evdwl; @@ -335,7 +338,7 @@ void PairDPDfdtEnergyKokkos::operator()(TagPairDPDfdtEnergyComputeSp ev.evdwl += evdwl; } - if (EVFLAG) this->template ev_tally(ev,i,j,evdwl,fpair,delx,dely,delz); + if (EVFLAG) this->template ev_tally(ev,i,j,evdwl,fpair,delx,dely,delz); } } @@ -437,9 +440,9 @@ void PairDPDfdtEnergyKokkos::operator()(TagPairDPDfdtEnergyComputeNo fy_i += dely*fpair; fz_i += delz*fpair; if (NEWTON_PAIR || j < nlocal) { - f(j,0) -= delx*fpair; - f(j,1) -= dely*fpair; - f(j,2) -= delz*fpair; + a_f(j,0) -= delx*fpair; + a_f(j,1) -= dely*fpair; + a_f(j,2) -= delz*fpair; } if (rmass) { @@ -454,7 +457,7 @@ void PairDPDfdtEnergyKokkos::operator()(TagPairDPDfdtEnergyComputeNo // Compute the mechanical and conductive energy, uMech and uCond mu_ij = massinv_i + massinv_j; - mu_ij *= force->ftm2v; + mu_ij *= ftm2v; uTmp = gamma_ij*wd*rinv*rinv*dot*dot - 0.5*sigma_ij*sigma_ij*mu_ij*wd; diff --git a/src/KOKKOS/pair_dpd_fdt_energy_kokkos.h b/src/KOKKOS/pair_dpd_fdt_energy_kokkos.h index 67fa315721..8e7d01de2a 100644 --- a/src/KOKKOS/pair_dpd_fdt_energy_kokkos.h +++ b/src/KOKKOS/pair_dpd_fdt_energy_kokkos.h @@ -89,7 +89,8 @@ class PairDPDfdtEnergyKokkos : public PairDPDfdtEnergy { int nlocal,neighflag; int STACKPARAMS; double dtinvsqrt; - double boltz; + double boltz,ftm2v; + double special_lj[4]; virtual void allocate(); diff --git a/src/KOKKOS/pair_exp6_rx_kokkos.cpp b/src/KOKKOS/pair_exp6_rx_kokkos.cpp index a2c70ca115..8ab7d62324 100644 --- a/src/KOKKOS/pair_exp6_rx_kokkos.cpp +++ b/src/KOKKOS/pair_exp6_rx_kokkos.cpp @@ -148,10 +148,6 @@ void PairExp6rxKokkos::compute(int eflag_in, int vflag_in) special_lj[1] = force->special_lj[1]; special_lj[2] = force->special_lj[2]; special_lj[3] = force->special_lj[3]; - special_coul[0] = force->special_coul[0]; - special_coul[1] = force->special_coul[1]; - special_coul[2] = force->special_coul[2]; - special_coul[3] = force->special_coul[3]; newton_pair = force->newton_pair; atomKK->sync(execution_space,X_MASK | F_MASK | TYPE_MASK | ENERGY_MASK | VIRIAL_MASK | UCG_MASK | UCGNEW_MASK | DVECTOR_MASK); @@ -595,6 +591,7 @@ void PairExp6rxKokkos::operator()(TagPairExp6rxComputetemplate ev_tally(ev,i,j,evdwl,fpair,delx,dely,delz); } diff --git a/src/KOKKOS/pair_exp6_rx_kokkos.h b/src/KOKKOS/pair_exp6_rx_kokkos.h index 366cf99d75..7dfe20fc22 100644 --- a/src/KOKKOS/pair_exp6_rx_kokkos.h +++ b/src/KOKKOS/pair_exp6_rx_kokkos.h @@ -89,7 +89,6 @@ class PairExp6rxKokkos : public PairExp6rx { protected: int eflag,vflag; int nlocal,newton_pair,neighflag; - double special_coul[4]; double special_lj[4]; typename AT::t_x_array_randomread x; From 163b61a32eff89364b99ca0e9dbde28364a65ded Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Wed, 21 Dec 2016 15:37:00 -0700 Subject: [PATCH 029/439] Removing pair_table_rx_kokkos from Kokkos Install.sh since it isn't ready for runtime testing --- src/KOKKOS/Install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/KOKKOS/Install.sh b/src/KOKKOS/Install.sh index 94be32cc32..17e9f93c9d 100644 --- a/src/KOKKOS/Install.sh +++ b/src/KOKKOS/Install.sh @@ -190,8 +190,8 @@ action pair_vashishta_kokkos.cpp pair_vashishta.cpp action pair_vashishta_kokkos.h pair_vashishta.h action pair_table_kokkos.cpp action pair_table_kokkos.h -action pair_table_rx_kokkos.cpp pair_table_rx.cpp -action pair_table_rx_kokkos.h pair_table_rx.h +#action pair_table_rx_kokkos.cpp pair_table_rx.cpp +#action pair_table_rx_kokkos.h pair_table_rx.h action pair_tersoff_kokkos.cpp pair_tersoff.cpp action pair_tersoff_kokkos.h pair_tersoff.h action pair_tersoff_mod_kokkos.cpp pair_tersoff_mod.cpp From f6fe61196da6acb067c321433dcfa31dba8fc39e Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Thu, 22 Dec 2016 11:34:17 -0700 Subject: [PATCH 030/439] CPU runtime tested version of pair_multi_lucy_rx_kokkos --- src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp | 9 ++- src/KOKKOS/pair_exp6_rx_kokkos.cpp | 11 ++-- src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp | 70 ++++++++++------------- src/KOKKOS/pair_multi_lucy_rx_kokkos.h | 30 ++++------ src/USER-DPD/pair_multi_lucy_rx.h | 12 ++-- 5 files changed, 61 insertions(+), 71 deletions(-) diff --git a/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp b/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp index 310f4689cb..133d366fbc 100644 --- a/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp +++ b/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp @@ -58,6 +58,9 @@ PairDPDfdtEnergyKokkos::~PairDPDfdtEnergyKokkos() { if (copymode) return; + memory->destroy_kokkos(k_eatom,eatom); + memory->destroy_kokkos(k_vatom,vatom); + if (allocated) { memory->destroy_kokkos(k_duCond,duCond); memory->destroy_kokkos(k_duMech,duMech); @@ -335,7 +338,8 @@ void PairDPDfdtEnergyKokkos::operator()(TagPairDPDfdtEnergyComputeSp // eng shifted to 0.0 at cutoff evdwl = 0.5*a0_ij*cut_ij * wd; evdwl *= factor_dpd; - ev.evdwl += evdwl; + if (EVFLAG) + ev.evdwl += ((NEWTON_PAIR||(jtemplate ev_tally(ev,i,j,evdwl,fpair,delx,dely,delz); @@ -489,7 +493,8 @@ void PairDPDfdtEnergyKokkos::operator()(TagPairDPDfdtEnergyComputeNo // eng shifted to 0.0 at cutoff evdwl = 0.5*a0_ij*cut_ij * wd; evdwl *= factor_dpd; - ev.evdwl += evdwl; + if (EVFLAG) + ev.evdwl += ((NEWTON_PAIR||(jtemplate ev_tally(ev,i,j,evdwl,fpair,delx,dely,delz); diff --git a/src/KOKKOS/pair_exp6_rx_kokkos.cpp b/src/KOKKOS/pair_exp6_rx_kokkos.cpp index 8ab7d62324..559948067d 100644 --- a/src/KOKKOS/pair_exp6_rx_kokkos.cpp +++ b/src/KOKKOS/pair_exp6_rx_kokkos.cpp @@ -153,6 +153,7 @@ void PairExp6rxKokkos::compute(int eflag_in, int vflag_in) atomKK->sync(execution_space,X_MASK | F_MASK | TYPE_MASK | ENERGY_MASK | VIRIAL_MASK | UCG_MASK | UCGNEW_MASK | DVECTOR_MASK); if (evflag) atomKK->modified(execution_space,F_MASK | ENERGY_MASK | VIRIAL_MASK | UCG_MASK | UCGNEW_MASK); else atomKK->modified(execution_space,F_MASK | UCG_MASK | UCGNEW_MASK); + k_cutsq.template sync(); // Initialize the Exp6 parameter data for both the local // and ghost atoms. Make the parameter data persistent @@ -495,7 +496,7 @@ void PairExp6rxKokkos::operator()(TagPairExp6rxCompute::operator()(TagPairExp6rxCompute::operator()(TagPairExp6rxComputetemplate ev_tally(ev,i,j,evdwl,fpair,delx,dely,delz); } @@ -630,6 +632,7 @@ void PairExp6rxKokkos::allocate() memory->create_kokkos(k_cutsq,cutsq,n+1,n+1,"pair:cutsq"); d_cutsq = k_cutsq.template view(); + k_cutsq.template modify(); memory->create(cut,n+1,n+1,"pair:cut_lj"); } diff --git a/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp b/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp index 76337b5219..1dc8ccbae9 100644 --- a/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp +++ b/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp @@ -71,7 +71,7 @@ PairMultiLucyRXKokkos::PairMultiLucyRXKokkos(LAMMPS *lmp) : PairMult datamask_read = EMPTY_MASK; datamask_modify = EMPTY_MASK; - update_table = 0; + update_table = 1; h_table = new TableHost(); d_table = new TableDevice(); @@ -85,8 +85,14 @@ PairMultiLucyRXKokkos::~PairMultiLucyRXKokkos() { if (copymode) return; + memory->destroy_kokkos(k_eatom,eatom); + memory->destroy_kokkos(k_vatom,vatom); + + memory->destroy_kokkos(k_cutsq,cutsq); + delete h_table; delete d_table; + tabindex = NULL; } /* ---------------------------------------------------------------------- */ @@ -123,6 +129,8 @@ void PairMultiLucyRXKokkos::init_style() template void PairMultiLucyRXKokkos::compute(int eflag_in, int vflag_in) { + copymode = 1; + if (update_table) create_kokkos_tables(); @@ -130,6 +138,8 @@ void PairMultiLucyRXKokkos::compute(int eflag_in, int vflag_in) compute_style(eflag_in,vflag_in); else if(tabstyle == LINEAR) compute_style(eflag_in,vflag_in); + + copymode = 0; } /* ---------------------------------------------------------------------- */ @@ -138,15 +148,9 @@ template template void PairMultiLucyRXKokkos::compute_style(int eflag_in, int vflag_in) { - copymode = 1; - eflag = eflag_in; vflag = vflag_in; - double evdwl,evdwlOld; - - evdwlOld = 0.0; - evdwl = 0.0; if (neighflag == FULL) no_virial_fdotr_compute = 1; if (eflag || vflag) ev_setup(eflag,vflag); else evflag = vflag_fdotr = 0; @@ -175,6 +179,7 @@ void PairMultiLucyRXKokkos::compute_style(int eflag_in, int vflag_in atomKK->sync(execution_space,X_MASK | F_MASK | TYPE_MASK | ENERGY_MASK | VIRIAL_MASK | DPDRHO_MASK | UCG_MASK | UCGNEW_MASK | DVECTOR_MASK); if (evflag) atomKK->modified(execution_space,F_MASK | ENERGY_MASK | VIRIAL_MASK | UCG_MASK | UCGNEW_MASK); else atomKK->modified(execution_space,F_MASK | UCG_MASK | UCGNEW_MASK); + k_cutsq.template sync(); nlocal = atom->nlocal; int nghost = atom->nghost; @@ -250,8 +255,6 @@ void PairMultiLucyRXKokkos::compute_style(int eflag_in, int vflag_in k_vatom.template modify(); k_vatom.template sync(); } - - copymode = 0; } template @@ -316,10 +319,12 @@ void PairMultiLucyRXKokkos::operator()(TagPairMultiLucyRXComputeinnersq || rho[j]*rho[j] < tb->innersq){ if (rho[i]*rho[i] < d_table_const.innersq(tidx) || rho[j]*rho[j] < d_table_const.innersq(tidx)){ k_error_flag.d_view() = 1; } + if (TABSTYLE == LOOKUP) { //itable = static_cast (((rho[i]*rho[i]) - tb->innersq) * tb->invdelta); itable = static_cast (((rho[i]*rho[i]) - d_table_const.innersq(tidx)) * d_table_const.invdelta(tidx)); @@ -338,6 +343,7 @@ void PairMultiLucyRXKokkos::operator()(TagPairMultiLucyRXCompute ((rho[i]*rho[i] - tb->innersq) * tb->invdelta); itable = static_cast ((rho[i]*rho[i] - d_table_const.innersq(tidx)) * d_table_const.invdelta(tidx)); //jtable = static_cast (((rho[j]*rho[j]) - tb->innersq) * tb->invdelta); @@ -395,8 +401,9 @@ void PairMultiLucyRXKokkos::operator()(TagPairMultiLucyRXCompute (((rho[i]*rho[i]) - tb->innersq) * tb->invdelta); itable = static_cast (((rho[i]*rho[i]) - d_table_const.innersq(tidx)) * d_table_const.invdelta(tidx)); //if (TABSTYLE == LOOKUP) evdwl = tb->e[itable]; - if (TABSTYLE == LOOKUP) evdwl = d_table_const.e(tidx,itable); - else if (TABSTYLE == LINEAR){ + if (TABSTYLE == LOOKUP) { + evdwl = d_table_const.e(tidx,itable); + } else if (TABSTYLE == LINEAR) { if (itable >= tlm1){ k_error_flag.d_view() = 2; } @@ -404,7 +411,7 @@ void PairMultiLucyRXKokkos::operator()(TagPairMultiLucyRXComputersq[itable]) * tb->invdelta); else fraction_i = (((rho[i]*rho[i]) - d_table_const.rsq(tidx,itable)) * d_table_const.invdelta(tidx)); //evdwl = tb->e[itable] + fraction_i*tb->de[itable]; - evdwl = d_table_const.e(tidx,itable); + fraction_i*d_table_const.de(tidx,itable); + evdwl = d_table_const.e(tidx,itable) + fraction_i*d_table_const.de(tidx,itable); } else k_error_flag.d_view() = 3; evdwl *=(pi*d_cutsq(itype,itype)*d_cutsq(itype,itype))/84.0; @@ -417,7 +424,8 @@ void PairMultiLucyRXKokkos::operator()(TagPairMultiLucyRXCompute @@ -433,8 +441,6 @@ void PairMultiLucyRXKokkos::operator()(TagPairMultiLucyRXCompute void PairMultiLucyRXKokkos::computeLocalDensity() { - copymode = 1; - x = atomKK->k_x.view(); type = atomKK->k_type.view(); rho = atomKK->k_rho.view(); @@ -491,8 +497,6 @@ void PairMultiLucyRXKokkos::computeLocalDensity() } comm->forward_comm_pair(this); - - copymode = 0; } template @@ -506,6 +510,7 @@ template KOKKOS_INLINE_FUNCTION void PairMultiLucyRXKokkos::operator()(TagPairMultiLucyRXComputeLocalDensity, const int &ii) const { + // The rho array is atomic for Half/Thread neighbor style Kokkos::View::value> > a_rho = rho; @@ -565,6 +570,7 @@ void PairMultiLucyRXKokkos::getParams(int id, double &fractionOld1, double fractionOld, fraction; double nTotal, nTotalOld; + nTotal = 0.0; nTotalOld = 0.0; for (int ispecies = 0; ispecies < nspecies; ispecies++){ @@ -796,7 +802,6 @@ void PairMultiLucyRXKokkos::create_kokkos_tables() memory->create_kokkos(d_table->innersq,h_table->innersq,ntables,"Table::innersq"); memory->create_kokkos(d_table->invdelta,h_table->invdelta,ntables,"Table::invdelta"); - memory->create_kokkos(d_table->deltasq6,h_table->deltasq6,ntables,"Table::deltasq6"); if(tabstyle == LOOKUP) { memory->create_kokkos(d_table->e,h_table->e,ntables,tlm1,"Table::e"); @@ -816,12 +821,9 @@ void PairMultiLucyRXKokkos::create_kokkos_tables() h_table->innersq[i] = tb->innersq; h_table->invdelta[i] = tb->invdelta; - h_table->deltasq6[i] = tb->deltasq6; for(int j = 0; jrsq.dimension_1(); j++) h_table->rsq(i,j) = tb->rsq[j]; - for(int j = 0; jdrsq.dimension_1(); j++) - h_table->drsq(i,j) = tb->drsq[j]; for(int j = 0; je.dimension_1(); j++) h_table->e(i,j) = tb->e[j]; for(int j = 0; jde.dimension_1(); j++) @@ -830,40 +832,26 @@ void PairMultiLucyRXKokkos::create_kokkos_tables() h_table->f(i,j) = tb->f[j]; for(int j = 0; jdf.dimension_1(); j++) h_table->df(i,j) = tb->df[j]; - for(int j = 0; je2.dimension_1(); j++) - h_table->e2(i,j) = tb->e2[j]; - for(int j = 0; jf2.dimension_1(); j++) - h_table->f2(i,j) = tb->f2[j]; } Kokkos::deep_copy(d_table->innersq,h_table->innersq); Kokkos::deep_copy(d_table->invdelta,h_table->invdelta); - Kokkos::deep_copy(d_table->deltasq6,h_table->deltasq6); Kokkos::deep_copy(d_table->rsq,h_table->rsq); - Kokkos::deep_copy(d_table->drsq,h_table->drsq); Kokkos::deep_copy(d_table->e,h_table->e); Kokkos::deep_copy(d_table->de,h_table->de); Kokkos::deep_copy(d_table->f,h_table->f); Kokkos::deep_copy(d_table->df,h_table->df); - Kokkos::deep_copy(d_table->e2,h_table->e2); - Kokkos::deep_copy(d_table->f2,h_table->f2); Kokkos::deep_copy(d_table->tabindex,h_table->tabindex); d_table_const.innersq = d_table->innersq; d_table_const.invdelta = d_table->invdelta; - d_table_const.deltasq6 = d_table->deltasq6; d_table_const.rsq = d_table->rsq; - d_table_const.drsq = d_table->drsq; d_table_const.e = d_table->e; d_table_const.de = d_table->de; d_table_const.f = d_table->f; d_table_const.df = d_table->df; - d_table_const.e2 = d_table->e2; - d_table_const.f2 = d_table->f2; - - Kokkos::deep_copy(d_table->cutsq,h_table->cutsq); update_table = 0; } @@ -878,11 +866,14 @@ void PairMultiLucyRXKokkos::allocate() const int nt = atom->ntypes + 1; memory->create(setflag,nt,nt,"pair:setflag"); - memory->create_kokkos(d_table->cutsq,h_table->cutsq,cutsq,nt,nt,"pair:cutsq"); - memory->create_kokkos(d_table->tabindex,h_table->tabindex,tabindex,nt,nt,"pair:tabindex"); - d_table_const.cutsq = d_table->cutsq; + memory->create_kokkos(k_cutsq,cutsq,nt,nt,"pair:cutsq"); + d_cutsq = k_cutsq.template view(); + k_cutsq.template modify(); + + memory->create_kokkos(d_table->tabindex,h_table->tabindex,tabindex,nt,nt,"pair:tabindex"); d_table_const.tabindex = d_table->tabindex; + memset(&setflag[0][0],0,nt*nt*sizeof(int)); memset(&cutsq[0][0],0,nt*nt*sizeof(double)); memset(&tabindex[0][0],0,nt*nt*sizeof(int)); @@ -916,9 +907,6 @@ void PairMultiLucyRXKokkos::settings(int narg, char **arg) d_table_const.tabindex = d_table->tabindex = typename ArrayTypes::t_int_2d(); h_table->tabindex = typename ArrayTypes::t_int_2d(); - - d_table_const.cutsq = d_table->cutsq = typename ArrayTypes::t_ffloat_2d(); - h_table->cutsq = typename ArrayTypes::t_ffloat_2d(); } allocated = 0; diff --git a/src/KOKKOS/pair_multi_lucy_rx_kokkos.h b/src/KOKKOS/pair_multi_lucy_rx_kokkos.h index b205f00796..a6622ac4ec 100644 --- a/src/KOKKOS/pair_multi_lucy_rx_kokkos.h +++ b/src/KOKKOS/pair_multi_lucy_rx_kokkos.h @@ -120,44 +120,38 @@ class PairMultiLucyRXKokkos : public PairMultiLucyRX { //}; /*struct TableDeviceConst { - typename ArrayTypes::t_ffloat_2d_randomread cutsq; - typename ArrayTypes::t_int_2d_randomread tabindex; - typename ArrayTypes::t_ffloat_1d_randomread innersq,invdelta,deltasq6; - typename ArrayTypes::t_ffloat_2d_randomread rsq,drsq,e,de,f,df,e2,f2; + typename AT::t_int_2d_randomread tabindex; + typename AT::t_ffloat_1d_randomread innersq,invdelta; + typename AT::t_ffloat_2d_randomread rsq,e,de,f,df; };*/ //Its faster not to use texture fetch if the number of tables is less than 32! struct TableDeviceConst { - typename ArrayTypes::t_ffloat_2d cutsq; - typename ArrayTypes::t_int_2d tabindex; - typename ArrayTypes::t_ffloat_1d innersq,invdelta,deltasq6; - typename ArrayTypes::t_ffloat_2d_randomread rsq,drsq,e,de,f,df,e2,f2; + typename AT::t_int_2d tabindex; + typename AT::t_ffloat_1d innersq,invdelta; + typename AT::t_ffloat_2d_randomread rsq,e,de,f,df; }; struct TableDevice { - typename ArrayTypes::t_ffloat_2d cutsq; - typename ArrayTypes::t_int_2d tabindex; - typename ArrayTypes::t_ffloat_1d innersq,invdelta,deltasq6; - typename ArrayTypes::t_ffloat_2d rsq,drsq,e,de,f,df,e2,f2; + typename AT::t_int_2d tabindex; + typename AT::t_ffloat_1d innersq,invdelta; + typename AT::t_ffloat_2d rsq,e,de,f,df; }; struct TableHost { - typename ArrayTypes::t_ffloat_2d cutsq; - typename ArrayTypes::t_int_2d tabindex; - typename ArrayTypes::t_ffloat_1d innersq,invdelta,deltasq6; - typename ArrayTypes::t_ffloat_2d rsq,drsq,e,de,f,df,e2,f2; + HAT::t_int_2d tabindex; + HAT::t_ffloat_1d innersq,invdelta; + HAT::t_ffloat_2d rsq,e,de,f,df; }; TableDeviceConst d_table_const; TableDevice* d_table; TableHost* h_table; - int **tabindex; F_FLOAT m_cutsq[MAX_TYPES_STACKPARAMS+1][MAX_TYPES_STACKPARAMS+1]; void allocate(); int update_table; void create_kokkos_tables(); - void cleanup_copy(); KOKKOS_INLINE_FUNCTION void getParams(int, double &, double &, double &, double &) const; diff --git a/src/USER-DPD/pair_multi_lucy_rx.h b/src/USER-DPD/pair_multi_lucy_rx.h index 2913716c5a..0562739c50 100644 --- a/src/USER-DPD/pair_multi_lucy_rx.h +++ b/src/USER-DPD/pair_multi_lucy_rx.h @@ -30,17 +30,17 @@ class PairMultiLucyRX : public Pair { virtual ~PairMultiLucyRX(); virtual void compute(int, int); - void settings(int, char **); + virtual void settings(int, char **); void coeff(int, char **); double init_one(int, int); void write_restart(FILE *); void read_restart(FILE *); void write_restart_settings(FILE *); void read_restart_settings(FILE *); - int pack_forward_comm(int, int *, double *, int, int *); - void unpack_forward_comm(int, int, double *); - int pack_reverse_comm(int, int, double *); - void unpack_reverse_comm(int, int *, double *); + virtual int pack_forward_comm(int, int *, double *, int, int *); + virtual void unpack_forward_comm(int, int, double *); + virtual int pack_reverse_comm(int, int, double *); + virtual void unpack_reverse_comm(int, int *, double *); void computeLocalDensity(); double rho_0; @@ -64,7 +64,7 @@ class PairMultiLucyRX : public Pair { int **tabindex; - void allocate(); + virtual void allocate(); void read_table(Table *, char *, char *); void param_extract(Table *, char *); void bcast_table(Table *); From a4ab877c4672b919ed5807864f5db726ef522926 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Thu, 22 Dec 2016 13:16:57 -0700 Subject: [PATCH 031/439] Change to allow pair_dpd_fdt_energy_kokkos --- src/USER-DPD/fix_dpd_energy.cpp | 2 ++ src/USER-DPD/fix_rx.cpp | 3 +++ src/USER-DPD/fix_shardlow.cpp | 2 ++ 3 files changed, 7 insertions(+) diff --git a/src/USER-DPD/fix_dpd_energy.cpp b/src/USER-DPD/fix_dpd_energy.cpp index 05907a5fcf..475e12f02f 100644 --- a/src/USER-DPD/fix_dpd_energy.cpp +++ b/src/USER-DPD/fix_dpd_energy.cpp @@ -34,6 +34,8 @@ FixDPDenergy::FixDPDenergy(LAMMPS *lmp, int narg, char **arg) : pairDPDE = NULL; pairDPDE = (PairDPDfdtEnergy *) force->pair_match("dpd/fdt/energy",1); + if (pairDPDE == NULL) + pairDPDE = (PairDPDfdtEnergy *) force->pair_match("dpd/fdt/energy/kk",1); if (pairDPDE == NULL) error->all(FLERR,"Must use pair_style dpd/fdt/energy with fix dpd/energy"); diff --git a/src/USER-DPD/fix_rx.cpp b/src/USER-DPD/fix_rx.cpp index df67cf4035..0bd560b241 100644 --- a/src/USER-DPD/fix_rx.cpp +++ b/src/USER-DPD/fix_rx.cpp @@ -627,6 +627,9 @@ int FixRX::setmask() void FixRX::init() { pairDPDE = (PairDPDfdtEnergy *) force->pair_match("dpd/fdt/energy",1); + if (pairDPDE == NULL) + pairDPDE = (PairDPDfdtEnergy *) force->pair_match("dpd/fdt/energy/kk",1); + if (pairDPDE == NULL) error->all(FLERR,"Must use pair_style dpd/fdt/energy with fix rx"); diff --git a/src/USER-DPD/fix_shardlow.cpp b/src/USER-DPD/fix_shardlow.cpp index 28c5382237..541f4ba3c3 100644 --- a/src/USER-DPD/fix_shardlow.cpp +++ b/src/USER-DPD/fix_shardlow.cpp @@ -94,6 +94,8 @@ FixShardlow::FixShardlow(LAMMPS *lmp, int narg, char **arg) : pairDPDE = NULL; pairDPD = (PairDPDfdt *) force->pair_match("dpd/fdt",1); pairDPDE = (PairDPDfdtEnergy *) force->pair_match("dpd/fdt/energy",1); + if (pairDPDE == NULL) + pairDPDE = (PairDPDfdtEnergy *) force->pair_match("dpd/fdt/energy/kk",1); if(pairDPDE){ comm_forward = 3; From a36e563aa56e8e3a31f19f8b010301c3b170b941 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Thu, 22 Dec 2016 14:37:42 -0700 Subject: [PATCH 032/439] Temporarily reverting change to pair_table_kokkos to allow runtime testing --- src/KOKKOS/pair_table_kokkos.cpp | 758 ++++++++++++++++++++++++++++++- src/KOKKOS/pair_table_kokkos.h | 44 +- 2 files changed, 790 insertions(+), 12 deletions(-) diff --git a/src/KOKKOS/pair_table_kokkos.cpp b/src/KOKKOS/pair_table_kokkos.cpp index b8b647964c..5230d1a91f 100644 --- a/src/KOKKOS/pair_table_kokkos.cpp +++ b/src/KOKKOS/pair_table_kokkos.cpp @@ -12,7 +12,7 @@ ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- - Contributing author: Christian Trott (SNL) + Contributing author: Paul Crozier (SNL) ------------------------------------------------------------------------- */ #include @@ -41,7 +41,7 @@ enum{FULL,HALFTHREAD,HALF}; /* ---------------------------------------------------------------------- */ template -PairTableKokkos::PairTableKokkos(LAMMPS *lmp) : PairTable(lmp) +PairTableKokkos::PairTableKokkos(LAMMPS *lmp) : Pair(lmp) { update_table = 0; atomKK = (AtomKokkos *) atom; @@ -98,7 +98,6 @@ void PairTableKokkos::compute_style(int eflag_in, int vflag_in) if (neighflag == FULL) no_virial_fdotr_compute = 1; - if (eflag || vflag) ev_setup(eflag,vflag); else evflag = vflag_fdotr = 0; @@ -196,7 +195,6 @@ compute_fpair(const F_FLOAT& rsq, const int& i, const int&j, const int& itype, c //if (rsq < d_table_const.innersq(tidx)) // error->one(FLERR,"Pair distance < table inner cutoff"); - if (Specialisation::TabStyle == LOOKUP) { const int itable = static_cast ((rsq - d_table_const.innersq(tidx)) * d_table_const.invdelta(tidx)); //if (itable >= tlm1) @@ -314,6 +312,8 @@ void PairTableKokkos::create_kokkos_tables() memory->create_kokkos(d_table->drsq,h_table->drsq,ntables,ntable,"Table::drsq"); } + + for(int i=0; i < ntables; i++) { Table* tb = &tables[i]; @@ -451,6 +451,85 @@ void PairTableKokkos::settings(int narg, char **arg) tables = NULL; } +/* ---------------------------------------------------------------------- + set coeffs for one or more type pairs +------------------------------------------------------------------------- */ + +template +void PairTableKokkos::coeff(int narg, char **arg) +{ + if (narg != 4 && narg != 5) error->all(FLERR,"Illegal pair_coeff command"); + if (!allocated) allocate(); + + int ilo,ihi,jlo,jhi; + force->bounds(FLERR,arg[0],atom->ntypes,ilo,ihi); + force->bounds(FLERR,arg[1],atom->ntypes,jlo,jhi); + + int me; + MPI_Comm_rank(world,&me); + tables = (Table *) + memory->srealloc(tables,(ntables+1)*sizeof(Table),"pair:tables"); + Table *tb = &tables[ntables]; + null_table(tb); + if (me == 0) read_table(tb,arg[2],arg[3]); + bcast_table(tb); + + // set table cutoff + + if (narg == 5) tb->cut = force->numeric(FLERR,arg[4]); + else if (tb->rflag) tb->cut = tb->rhi; + else tb->cut = tb->rfile[tb->ninput-1]; + + // error check on table parameters + // insure cutoff is within table + // for BITMAP tables, file values can be in non-ascending order + + if (tb->ninput <= 1) error->one(FLERR,"Invalid pair table length"); + double rlo,rhi; + if (tb->rflag == 0) { + rlo = tb->rfile[0]; + rhi = tb->rfile[tb->ninput-1]; + } else { + rlo = tb->rlo; + rhi = tb->rhi; + } + if (tb->cut <= rlo || tb->cut > rhi) + error->all(FLERR,"Invalid pair table cutoff"); + if (rlo <= 0.0) error->all(FLERR,"Invalid pair table cutoff"); + + // match = 1 if don't need to spline read-in tables + // this is only the case if r values needed by final tables + // exactly match r values read from file + // for tabstyle SPLINE, always need to build spline tables + + tb->match = 0; + if (tabstyle == LINEAR && tb->ninput == tablength && + tb->rflag == RSQ && tb->rhi == tb->cut) tb->match = 1; + if (tabstyle == BITMAP && tb->ninput == 1 << tablength && + tb->rflag == BMP && tb->rhi == tb->cut) tb->match = 1; + if (tb->rflag == BMP && tb->match == 0) + error->all(FLERR,"Bitmapped table in file does not match requested table"); + + // spline read-in values and compute r,e,f vectors within table + + if (tb->match == 0) spline_table(tb); + compute_table(tb); + + // store ptr to table in tabindex + + int count = 0; + for (int i = ilo; i <= ihi; i++) { + for (int j = MAX(jlo,i); j <= jhi; j++) { + tabindex[i][j] = ntables; + setflag[i][j] = 1; + count++; + } + } + + if (count == 0) error->all(FLERR,"Illegal pair_coeff command"); + ntables++; +} + /* ---------------------------------------------------------------------- init for one type pair i,j and corresponding j,i ------------------------------------------------------------------------- */ @@ -469,6 +548,677 @@ double PairTableKokkos::init_one(int i, int j) return tables[tabindex[i][j]].cut; } +/* ---------------------------------------------------------------------- + read a table section from a tabulated potential file + only called by proc 0 + this function sets these values in Table: + ninput,rfile,efile,ffile,rflag,rlo,rhi,fpflag,fplo,fphi,ntablebits +------------------------------------------------------------------------- */ + +template +void PairTableKokkos::read_table(Table *tb, char *file, char *keyword) +{ + char line[MAXLINE]; + + // open file + + FILE *fp = force->open_potential(file); + if (fp == NULL) { + char str[128]; + sprintf(str,"Cannot open file %s",file); + error->one(FLERR,str); + } + + // loop until section found with matching keyword + + while (1) { + if (fgets(line,MAXLINE,fp) == NULL) + error->one(FLERR,"Did not find keyword in table file"); + if (strspn(line," \t\n\r") == strlen(line)) continue; // blank line + if (line[0] == '#') continue; // comment + char *word = strtok(line," \t\n\r"); + if (strcmp(word,keyword) == 0) break; // matching keyword + fgets(line,MAXLINE,fp); // no match, skip section + param_extract(tb,line); + fgets(line,MAXLINE,fp); + for (int i = 0; i < tb->ninput; i++) fgets(line,MAXLINE,fp); + } + + // read args on 2nd line of section + // allocate table arrays for file values + + fgets(line,MAXLINE,fp); + param_extract(tb,line); + memory->create(tb->rfile,tb->ninput,"pair:rfile"); + memory->create(tb->efile,tb->ninput,"pair:efile"); + memory->create(tb->ffile,tb->ninput,"pair:ffile"); + + // setup bitmap parameters for table to read in + + tb->ntablebits = 0; + int masklo,maskhi,nmask,nshiftbits; + if (tb->rflag == BMP) { + while (1 << tb->ntablebits < tb->ninput) tb->ntablebits++; + if (1 << tb->ntablebits != tb->ninput) + error->one(FLERR,"Bitmapped table is incorrect length in table file"); + init_bitmap(tb->rlo,tb->rhi,tb->ntablebits,masklo,maskhi,nmask,nshiftbits); + } + + // read r,e,f table values from file + // if rflag set, compute r + // if rflag not set, use r from file + + int itmp; + double rtmp; + union_int_float_t rsq_lookup; + + fgets(line,MAXLINE,fp); + for (int i = 0; i < tb->ninput; i++) { + fgets(line,MAXLINE,fp); + sscanf(line,"%d %lg %lg %lg",&itmp,&rtmp,&tb->efile[i],&tb->ffile[i]); + + if (tb->rflag == RLINEAR) + rtmp = tb->rlo + (tb->rhi - tb->rlo)*i/(tb->ninput-1); + else if (tb->rflag == RSQ) { + rtmp = tb->rlo*tb->rlo + + (tb->rhi*tb->rhi - tb->rlo*tb->rlo)*i/(tb->ninput-1); + rtmp = sqrt(rtmp); + } else if (tb->rflag == BMP) { + rsq_lookup.i = i << nshiftbits; + rsq_lookup.i |= masklo; + if (rsq_lookup.f < tb->rlo*tb->rlo) { + rsq_lookup.i = i << nshiftbits; + rsq_lookup.i |= maskhi; + } + rtmp = sqrtf(rsq_lookup.f); + } + + tb->rfile[i] = rtmp; + } + + // close file + + fclose(fp); +} + +/* ---------------------------------------------------------------------- + broadcast read-in table info from proc 0 to other procs + this function communicates these values in Table: + ninput,rfile,efile,ffile,rflag,rlo,rhi,fpflag,fplo,fphi +------------------------------------------------------------------------- */ + +template +void PairTableKokkos::bcast_table(Table *tb) +{ + MPI_Bcast(&tb->ninput,1,MPI_INT,0,world); + + int me; + MPI_Comm_rank(world,&me); + if (me > 0) { + memory->create(tb->rfile,tb->ninput,"pair:rfile"); + memory->create(tb->efile,tb->ninput,"pair:efile"); + memory->create(tb->ffile,tb->ninput,"pair:ffile"); + } + + MPI_Bcast(tb->rfile,tb->ninput,MPI_DOUBLE,0,world); + MPI_Bcast(tb->efile,tb->ninput,MPI_DOUBLE,0,world); + MPI_Bcast(tb->ffile,tb->ninput,MPI_DOUBLE,0,world); + + MPI_Bcast(&tb->rflag,1,MPI_INT,0,world); + if (tb->rflag) { + MPI_Bcast(&tb->rlo,1,MPI_DOUBLE,0,world); + MPI_Bcast(&tb->rhi,1,MPI_DOUBLE,0,world); + } + MPI_Bcast(&tb->fpflag,1,MPI_INT,0,world); + if (tb->fpflag) { + MPI_Bcast(&tb->fplo,1,MPI_DOUBLE,0,world); + MPI_Bcast(&tb->fphi,1,MPI_DOUBLE,0,world); + } +} + +/* ---------------------------------------------------------------------- + build spline representation of e,f over entire range of read-in table + this function sets these values in Table: e2file,f2file +------------------------------------------------------------------------- */ + +template +void PairTableKokkos::spline_table(Table *tb) +{ + memory->create(tb->e2file,tb->ninput,"pair:e2file"); + memory->create(tb->f2file,tb->ninput,"pair:f2file"); + + double ep0 = - tb->ffile[0]; + double epn = - tb->ffile[tb->ninput-1]; + spline(tb->rfile,tb->efile,tb->ninput,ep0,epn,tb->e2file); + + if (tb->fpflag == 0) { + tb->fplo = (tb->ffile[1] - tb->ffile[0]) / (tb->rfile[1] - tb->rfile[0]); + tb->fphi = (tb->ffile[tb->ninput-1] - tb->ffile[tb->ninput-2]) / + (tb->rfile[tb->ninput-1] - tb->rfile[tb->ninput-2]); + } + + double fp0 = tb->fplo; + double fpn = tb->fphi; + spline(tb->rfile,tb->ffile,tb->ninput,fp0,fpn,tb->f2file); +} + +/* ---------------------------------------------------------------------- + extract attributes from parameter line in table section + format of line: N value R/RSQ/BITMAP lo hi FP fplo fphi + N is required, other params are optional +------------------------------------------------------------------------- */ + +template +void PairTableKokkos::param_extract(Table *tb, char *line) +{ + tb->ninput = 0; + tb->rflag = NONE; + tb->fpflag = 0; + + char *word = strtok(line," \t\n\r\f"); + while (word) { + if (strcmp(word,"N") == 0) { + word = strtok(NULL," \t\n\r\f"); + tb->ninput = atoi(word); + } else if (strcmp(word,"R") == 0 || strcmp(word,"RSQ") == 0 || + strcmp(word,"BITMAP") == 0) { + if (strcmp(word,"R") == 0) tb->rflag = RLINEAR; + else if (strcmp(word,"RSQ") == 0) tb->rflag = RSQ; + else if (strcmp(word,"BITMAP") == 0) tb->rflag = BMP; + word = strtok(NULL," \t\n\r\f"); + tb->rlo = atof(word); + word = strtok(NULL," \t\n\r\f"); + tb->rhi = atof(word); + } else if (strcmp(word,"FP") == 0) { + tb->fpflag = 1; + word = strtok(NULL," \t\n\r\f"); + tb->fplo = atof(word); + word = strtok(NULL," \t\n\r\f"); + tb->fphi = atof(word); + } else { + error->one(FLERR,"Invalid keyword in pair table parameters"); + } + word = strtok(NULL," \t\n\r\f"); + } + + if (tb->ninput == 0) error->one(FLERR,"Pair table parameters did not set N"); +} + +/* ---------------------------------------------------------------------- + compute r,e,f vectors from splined values +------------------------------------------------------------------------- */ + +template +void PairTableKokkos::compute_table(Table *tb) +{ + update_table = 1; + int tlm1 = tablength-1; + + // inner = inner table bound + // cut = outer table bound + // delta = table spacing in rsq for N-1 bins + + double inner; + if (tb->rflag) inner = tb->rlo; + else inner = tb->rfile[0]; + tb->innersq = inner*inner; + tb->delta = (tb->cut*tb->cut - tb->innersq) / tlm1; + tb->invdelta = 1.0/tb->delta; + + // direct lookup tables + // N-1 evenly spaced bins in rsq from inner to cut + // e,f = value at midpt of bin + // e,f are N-1 in length since store 1 value at bin midpt + // f is converted to f/r when stored in f[i] + // e,f are never a match to read-in values, always computed via spline interp + + if (tabstyle == LOOKUP) { + memory->create(tb->e,tlm1,"pair:e"); + memory->create(tb->f,tlm1,"pair:f"); + + double r,rsq; + for (int i = 0; i < tlm1; i++) { + rsq = tb->innersq + (i+0.5)*tb->delta; + r = sqrt(rsq); + tb->e[i] = splint(tb->rfile,tb->efile,tb->e2file,tb->ninput,r); + tb->f[i] = splint(tb->rfile,tb->ffile,tb->f2file,tb->ninput,r)/r; + } + } + + // linear tables + // N-1 evenly spaced bins in rsq from inner to cut + // rsq,e,f = value at lower edge of bin + // de,df values = delta from lower edge to upper edge of bin + // rsq,e,f are N in length so de,df arrays can compute difference + // f is converted to f/r when stored in f[i] + // e,f can match read-in values, else compute via spline interp + + if (tabstyle == LINEAR) { + memory->create(tb->rsq,tablength,"pair:rsq"); + memory->create(tb->e,tablength,"pair:e"); + memory->create(tb->f,tablength,"pair:f"); + memory->create(tb->de,tlm1,"pair:de"); + memory->create(tb->df,tlm1,"pair:df"); + + double r,rsq; + for (int i = 0; i < tablength; i++) { + rsq = tb->innersq + i*tb->delta; + r = sqrt(rsq); + tb->rsq[i] = rsq; + if (tb->match) { + tb->e[i] = tb->efile[i]; + tb->f[i] = tb->ffile[i]/r; + } else { + tb->e[i] = splint(tb->rfile,tb->efile,tb->e2file,tb->ninput,r); + tb->f[i] = splint(tb->rfile,tb->ffile,tb->f2file,tb->ninput,r)/r; + } + } + + for (int i = 0; i < tlm1; i++) { + tb->de[i] = tb->e[i+1] - tb->e[i]; + tb->df[i] = tb->f[i+1] - tb->f[i]; + } + } + + // cubic spline tables + // N-1 evenly spaced bins in rsq from inner to cut + // rsq,e,f = value at lower edge of bin + // e2,f2 = spline coefficient for each bin + // rsq,e,f,e2,f2 are N in length so have N-1 spline bins + // f is converted to f/r after e is splined + // e,f can match read-in values, else compute via spline interp + + if (tabstyle == SPLINE) { + memory->create(tb->rsq,tablength,"pair:rsq"); + memory->create(tb->e,tablength,"pair:e"); + memory->create(tb->f,tablength,"pair:f"); + memory->create(tb->e2,tablength,"pair:e2"); + memory->create(tb->f2,tablength,"pair:f2"); + + tb->deltasq6 = tb->delta*tb->delta / 6.0; + + double r,rsq; + for (int i = 0; i < tablength; i++) { + rsq = tb->innersq + i*tb->delta; + r = sqrt(rsq); + tb->rsq[i] = rsq; + if (tb->match) { + tb->e[i] = tb->efile[i]; + tb->f[i] = tb->ffile[i]/r; + } else { + tb->e[i] = splint(tb->rfile,tb->efile,tb->e2file,tb->ninput,r); + tb->f[i] = splint(tb->rfile,tb->ffile,tb->f2file,tb->ninput,r); + } + } + + // ep0,epn = dh/dg at inner and at cut + // h(r) = e(r) and g(r) = r^2 + // dh/dg = (de/dr) / 2r = -f/2r + + double ep0 = - tb->f[0] / (2.0 * sqrt(tb->innersq)); + double epn = - tb->f[tlm1] / (2.0 * tb->cut); + spline(tb->rsq,tb->e,tablength,ep0,epn,tb->e2); + + // fp0,fpn = dh/dg at inner and at cut + // h(r) = f(r)/r and g(r) = r^2 + // dh/dg = (1/r df/dr - f/r^2) / 2r + // dh/dg in secant approx = (f(r2)/r2 - f(r1)/r1) / (g(r2) - g(r1)) + + double fp0,fpn; + double secant_factor = 0.1; + if (tb->fpflag) fp0 = (tb->fplo/sqrt(tb->innersq) - tb->f[0]/tb->innersq) / + (2.0 * sqrt(tb->innersq)); + else { + double rsq1 = tb->innersq; + double rsq2 = rsq1 + secant_factor*tb->delta; + fp0 = (splint(tb->rfile,tb->ffile,tb->f2file,tb->ninput,sqrt(rsq2)) / + sqrt(rsq2) - tb->f[0] / sqrt(rsq1)) / (secant_factor*tb->delta); + } + + if (tb->fpflag && tb->cut == tb->rfile[tb->ninput-1]) fpn = + (tb->fphi/tb->cut - tb->f[tlm1]/(tb->cut*tb->cut)) / (2.0 * tb->cut); + else { + double rsq2 = tb->cut * tb->cut; + double rsq1 = rsq2 - secant_factor*tb->delta; + fpn = (tb->f[tlm1] / sqrt(rsq2) - + splint(tb->rfile,tb->ffile,tb->f2file,tb->ninput,sqrt(rsq1)) / + sqrt(rsq1)) / (secant_factor*tb->delta); + } + + for (int i = 0; i < tablength; i++) tb->f[i] /= sqrt(tb->rsq[i]); + spline(tb->rsq,tb->f,tablength,fp0,fpn,tb->f2); + } + + // bitmapped linear tables + // 2^N bins from inner to cut, spaced in bitmapped manner + // f is converted to f/r when stored in f[i] + // e,f can match read-in values, else compute via spline interp + + if (tabstyle == BITMAP) { + double r; + union_int_float_t rsq_lookup; + int masklo,maskhi; + + // linear lookup tables of length ntable = 2^n + // stored value = value at lower edge of bin + + init_bitmap(inner,tb->cut,tablength,masklo,maskhi,tb->nmask,tb->nshiftbits); + int ntable = 1 << tablength; + int ntablem1 = ntable - 1; + + memory->create(tb->rsq,ntable,"pair:rsq"); + memory->create(tb->e,ntable,"pair:e"); + memory->create(tb->f,ntable,"pair:f"); + memory->create(tb->de,ntable,"pair:de"); + memory->create(tb->df,ntable,"pair:df"); + memory->create(tb->drsq,ntable,"pair:drsq"); + + union_int_float_t minrsq_lookup; + minrsq_lookup.i = 0 << tb->nshiftbits; + minrsq_lookup.i |= maskhi; + + for (int i = 0; i < ntable; i++) { + rsq_lookup.i = i << tb->nshiftbits; + rsq_lookup.i |= masklo; + if (rsq_lookup.f < tb->innersq) { + rsq_lookup.i = i << tb->nshiftbits; + rsq_lookup.i |= maskhi; + } + r = sqrtf(rsq_lookup.f); + tb->rsq[i] = rsq_lookup.f; + if (tb->match) { + tb->e[i] = tb->efile[i]; + tb->f[i] = tb->ffile[i]/r; + } else { + tb->e[i] = splint(tb->rfile,tb->efile,tb->e2file,tb->ninput,r); + tb->f[i] = splint(tb->rfile,tb->ffile,tb->f2file,tb->ninput,r)/r; + } + minrsq_lookup.f = MIN(minrsq_lookup.f,rsq_lookup.f); + } + + tb->innersq = minrsq_lookup.f; + + for (int i = 0; i < ntablem1; i++) { + tb->de[i] = tb->e[i+1] - tb->e[i]; + tb->df[i] = tb->f[i+1] - tb->f[i]; + tb->drsq[i] = 1.0/(tb->rsq[i+1] - tb->rsq[i]); + } + + // get the delta values for the last table entries + // tables are connected periodically between 0 and ntablem1 + + tb->de[ntablem1] = tb->e[0] - tb->e[ntablem1]; + tb->df[ntablem1] = tb->f[0] - tb->f[ntablem1]; + tb->drsq[ntablem1] = 1.0/(tb->rsq[0] - tb->rsq[ntablem1]); + + // get the correct delta values at itablemax + // smallest r is in bin itablemin + // largest r is in bin itablemax, which is itablemin-1, + // or ntablem1 if itablemin=0 + + // deltas at itablemax only needed if corresponding rsq < cut*cut + // if so, compute deltas between rsq and cut*cut + // if tb->match, data at cut*cut is unavailable, so we'll take + // deltas at itablemax-1 as a good approximation + + double e_tmp,f_tmp; + int itablemin = minrsq_lookup.i & tb->nmask; + itablemin >>= tb->nshiftbits; + int itablemax = itablemin - 1; + if (itablemin == 0) itablemax = ntablem1; + int itablemaxm1 = itablemax - 1; + if (itablemax == 0) itablemaxm1 = ntablem1; + rsq_lookup.i = itablemax << tb->nshiftbits; + rsq_lookup.i |= maskhi; + if (rsq_lookup.f < tb->cut*tb->cut) { + if (tb->match) { + tb->de[itablemax] = tb->de[itablemaxm1]; + tb->df[itablemax] = tb->df[itablemaxm1]; + tb->drsq[itablemax] = tb->drsq[itablemaxm1]; + } else { + rsq_lookup.f = tb->cut*tb->cut; + r = sqrtf(rsq_lookup.f); + e_tmp = splint(tb->rfile,tb->efile,tb->e2file,tb->ninput,r); + f_tmp = splint(tb->rfile,tb->ffile,tb->f2file,tb->ninput,r)/r; + tb->de[itablemax] = e_tmp - tb->e[itablemax]; + tb->df[itablemax] = f_tmp - tb->f[itablemax]; + tb->drsq[itablemax] = 1.0/(rsq_lookup.f - tb->rsq[itablemax]); + } + } + } +} + +/* ---------------------------------------------------------------------- + set all ptrs in a table to NULL, so can be freed safely +------------------------------------------------------------------------- */ + +template +void PairTableKokkos::null_table(Table *tb) +{ + tb->rfile = tb->efile = tb->ffile = NULL; + tb->e2file = tb->f2file = NULL; + tb->rsq = tb->drsq = tb->e = tb->de = NULL; + tb->f = tb->df = tb->e2 = tb->f2 = NULL; +} + +/* ---------------------------------------------------------------------- + free all arrays in a table +------------------------------------------------------------------------- */ + +template +void PairTableKokkos::free_table(Table *tb) +{ + memory->destroy(tb->rfile); + memory->destroy(tb->efile); + memory->destroy(tb->ffile); + memory->destroy(tb->e2file); + memory->destroy(tb->f2file); + + memory->destroy(tb->rsq); + memory->destroy(tb->drsq); + memory->destroy(tb->e); + memory->destroy(tb->de); + memory->destroy(tb->f); + memory->destroy(tb->df); + memory->destroy(tb->e2); + memory->destroy(tb->f2); +} + +/* ---------------------------------------------------------------------- + spline and splint routines modified from Numerical Recipes +------------------------------------------------------------------------- */ + +template +void PairTableKokkos::spline(double *x, double *y, int n, + double yp1, double ypn, double *y2) +{ + int i,k; + double p,qn,sig,un; + double *u = new double[n]; + + if (yp1 > 0.99e30) y2[0] = u[0] = 0.0; + else { + y2[0] = -0.5; + u[0] = (3.0/(x[1]-x[0])) * ((y[1]-y[0]) / (x[1]-x[0]) - yp1); + } + for (i = 1; i < n-1; i++) { + sig = (x[i]-x[i-1]) / (x[i+1]-x[i-1]); + p = sig*y2[i-1] + 2.0; + y2[i] = (sig-1.0) / p; + u[i] = (y[i+1]-y[i]) / (x[i+1]-x[i]) - (y[i]-y[i-1]) / (x[i]-x[i-1]); + u[i] = (6.0*u[i] / (x[i+1]-x[i-1]) - sig*u[i-1]) / p; + } + if (ypn > 0.99e30) qn = un = 0.0; + else { + qn = 0.5; + un = (3.0/(x[n-1]-x[n-2])) * (ypn - (y[n-1]-y[n-2]) / (x[n-1]-x[n-2])); + } + y2[n-1] = (un-qn*u[n-2]) / (qn*y2[n-2] + 1.0); + for (k = n-2; k >= 0; k--) y2[k] = y2[k]*y2[k+1] + u[k]; + + delete [] u; +} + +/* ---------------------------------------------------------------------- */ + +template +double PairTableKokkos::splint(double *xa, double *ya, double *y2a, int n, double x) +{ + int klo,khi,k; + double h,b,a,y; + + klo = 0; + khi = n-1; + while (khi-klo > 1) { + k = (khi+klo) >> 1; + if (xa[k] > x) khi = k; + else klo = k; + } + h = xa[khi]-xa[klo]; + a = (xa[khi]-x) / h; + b = (x-xa[klo]) / h; + y = a*ya[klo] + b*ya[khi] + + ((a*a*a-a)*y2a[klo] + (b*b*b-b)*y2a[khi]) * (h*h)/6.0; + return y; +} + +/* ---------------------------------------------------------------------- + proc 0 writes to restart file +------------------------------------------------------------------------- */ + +template +void PairTableKokkos::write_restart(FILE *fp) +{ + write_restart_settings(fp); +} + +/* ---------------------------------------------------------------------- + proc 0 reads from restart file, bcasts +------------------------------------------------------------------------- */ + +template +void PairTableKokkos::read_restart(FILE *fp) +{ + read_restart_settings(fp); + allocate(); +} + +/* ---------------------------------------------------------------------- + proc 0 writes to restart file +------------------------------------------------------------------------- */ + +template +void PairTableKokkos::write_restart_settings(FILE *fp) +{ + fwrite(&tabstyle,sizeof(int),1,fp); + fwrite(&tablength,sizeof(int),1,fp); + fwrite(&ewaldflag,sizeof(int),1,fp); + fwrite(&pppmflag,sizeof(int),1,fp); + fwrite(&msmflag,sizeof(int),1,fp); + fwrite(&dispersionflag,sizeof(int),1,fp); + fwrite(&tip4pflag,sizeof(int),1,fp); +} + +/* ---------------------------------------------------------------------- + proc 0 reads from restart file, bcasts +------------------------------------------------------------------------- */ + +template +void PairTableKokkos::read_restart_settings(FILE *fp) +{ + if (comm->me == 0) { + fread(&tabstyle,sizeof(int),1,fp); + fread(&tablength,sizeof(int),1,fp); + fread(&ewaldflag,sizeof(int),1,fp); + fread(&pppmflag,sizeof(int),1,fp); + fread(&msmflag,sizeof(int),1,fp); + fread(&dispersionflag,sizeof(int),1,fp); + fread(&tip4pflag,sizeof(int),1,fp); + } + MPI_Bcast(&tabstyle,1,MPI_INT,0,world); + MPI_Bcast(&tablength,1,MPI_INT,0,world); + MPI_Bcast(&ewaldflag,1,MPI_INT,0,world); + MPI_Bcast(&pppmflag,1,MPI_INT,0,world); + MPI_Bcast(&msmflag,1,MPI_INT,0,world); + MPI_Bcast(&dispersionflag,1,MPI_INT,0,world); + MPI_Bcast(&tip4pflag,1,MPI_INT,0,world); +} + +/* ---------------------------------------------------------------------- */ + +template +double PairTableKokkos::single(int i, int j, int itype, int jtype, double rsq, + double factor_coul, double factor_lj, + double &fforce) +{ + int itable; + double fraction,value,a,b,phi; + int tlm1 = tablength - 1; + + Table *tb = &tables[tabindex[itype][jtype]]; + if (rsq < tb->innersq) error->one(FLERR,"Pair distance < table inner cutoff"); + + if (tabstyle == LOOKUP) { + itable = static_cast ((rsq-tb->innersq) * tb->invdelta); + if (itable >= tlm1) error->one(FLERR,"Pair distance > table outer cutoff"); + fforce = factor_lj * tb->f[itable]; + } else if (tabstyle == LINEAR) { + itable = static_cast ((rsq-tb->innersq) * tb->invdelta); + if (itable >= tlm1) error->one(FLERR,"Pair distance > table outer cutoff"); + fraction = (rsq - tb->rsq[itable]) * tb->invdelta; + value = tb->f[itable] + fraction*tb->df[itable]; + fforce = factor_lj * value; + } else if (tabstyle == SPLINE) { + itable = static_cast ((rsq-tb->innersq) * tb->invdelta); + if (itable >= tlm1) error->one(FLERR,"Pair distance > table outer cutoff"); + b = (rsq - tb->rsq[itable]) * tb->invdelta; + a = 1.0 - b; + value = a * tb->f[itable] + b * tb->f[itable+1] + + ((a*a*a-a)*tb->f2[itable] + (b*b*b-b)*tb->f2[itable+1]) * + tb->deltasq6; + fforce = factor_lj * value; + } else { + union_int_float_t rsq_lookup; + rsq_lookup.f = rsq; + itable = rsq_lookup.i & tb->nmask; + itable >>= tb->nshiftbits; + fraction = (rsq_lookup.f - tb->rsq[itable]) * tb->drsq[itable]; + value = tb->f[itable] + fraction*tb->df[itable]; + fforce = factor_lj * value; + } + + if (tabstyle == LOOKUP) + phi = tb->e[itable]; + else if (tabstyle == LINEAR || tabstyle == BITMAP) + phi = tb->e[itable] + fraction*tb->de[itable]; + else + phi = a * tb->e[itable] + b * tb->e[itable+1] + + ((a*a*a-a)*tb->e2[itable] + (b*b*b-b)*tb->e2[itable+1]) * tb->deltasq6; + return factor_lj*phi; +} + +/* ---------------------------------------------------------------------- + return the Coulomb cutoff for tabled potentials + called by KSpace solvers which require that all pairwise cutoffs be the same + loop over all tables not just those indexed by tabindex[i][j] since + no way to know which tables are active since pair::init() not yet called +------------------------------------------------------------------------- */ + +template +void *PairTableKokkos::extract(const char *str, int &dim) +{ + if (strcmp(str,"cut_coul") != 0) return NULL; + if (ntables == 0) error->all(FLERR,"All pair coeffs are not set"); + + double cut_coul = tables[0].cut; + for (int m = 1; m < ntables; m++) + if (tables[m].cut != cut_coul) + error->all(FLERR, + "Pair table cutoffs must all be equal to use with KSpace"); + dim = 0; + return &tables[0].cut; +} + template void PairTableKokkos::init_style() { diff --git a/src/KOKKOS/pair_table_kokkos.h b/src/KOKKOS/pair_table_kokkos.h index 5b3f3852c3..4d3a9ec106 100644 --- a/src/KOKKOS/pair_table_kokkos.h +++ b/src/KOKKOS/pair_table_kokkos.h @@ -22,7 +22,7 @@ PairStyle(table/kk/host,PairTableKokkos) #ifndef LMP_PAIR_TABLE_KOKKOS_H #define LMP_PAIR_TABLE_KOKKOS_H -#include "pair_table.h" +#include "pair.h" #include "pair_kokkos.h" #include "neigh_list_kokkos.h" #include "atom_kokkos.h" @@ -38,7 +38,7 @@ template class PairTableComputeFunctor; template -class PairTableKokkos : public PairTable { +class PairTableKokkos : public Pair { public: enum {EnabledNeighFlags=FULL|HALFTHREAD|HALF|N2}; @@ -59,9 +59,18 @@ class PairTableKokkos : public PairTable { const NeighListKokkos &list) const; */ void settings(int, char **); + void coeff(int, char **); double init_one(int, int); + void write_restart(FILE *); + void read_restart(FILE *); + void write_restart_settings(FILE *); + void read_restart_settings(FILE *); + double single(int, int, int, int, double, double, double, double &); + void *extract(const char *, int &); + void init_style(); + protected: enum{LOOKUP,LINEAR,SPLINE,BITMAP}; @@ -98,6 +107,17 @@ class PairTableKokkos : public PairTable { typename ArrayTypes::t_ffloat_2d rsq,drsq,e,de,f,df,e2,f2; }; + struct Table { + int ninput,rflag,fpflag,match,ntablebits; + int nshiftbits,nmask; + double rlo,rhi,fplo,fphi,cut; + double *rfile,*efile,*ffile; + double *e2file,*f2file; + double innersq,delta,invdelta,deltasq6; + double *rsq,*drsq,*e,*de,*f,*df,*e2,*f2; + }; + int ntables; + Table *tables; TableDeviceConst d_table_const; TableDevice* d_table; TableHost* h_table; @@ -108,6 +128,15 @@ class PairTableKokkos : public PairTable { typename ArrayTypes::t_ffloat_2d d_cutsq; void allocate(); + void read_table(Table *, char *, char *); + void param_extract(Table *, char *); + void bcast_table(Table *); + void spline_table(Table *); + void compute_table(Table *); + void null_table(Table *); + void free_table(Table *); + void spline(double *, double *, int, double, double, double *); + double splint(double *, double *, double *, int, double); typename ArrayTypes::t_x_array_randomread x; typename ArrayTypes::t_x_array_const c_x; @@ -176,6 +205,11 @@ class PairTableKokkos : public PairTable { friend void pair_virial_fdotr_compute(PairTableKokkos*); }; + + + + + } #endif @@ -255,10 +289,4 @@ E: Cannot use chosen neighbor list style with lj/cut/kk That style is not supported by Kokkos. - - - */ - - - From cc1b55e0310a5a0953d500c1b92b274ac8acf009 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 23 Dec 2016 12:36:05 -0700 Subject: [PATCH 033/439] Merging USER-DPD updates --- doc/src/fix_eos_table_rx.txt | 42 +- doc/src/pair_exp6_rx.txt | 60 ++- doc/src/pair_multi_lucy_rx.txt | 13 +- doc/src/pair_table_rx.txt | 15 +- .../USER/dpd/dpde-vv/log.dpde-vv.reference | 232 ++++----- .../USER/dpd/dpdrx-shardlow/in.dpdrx-shardlow | 2 +- .../log.dpdrx-shardlow.reference | 58 ++- src/KOKKOS/pair_exp6_rx_kokkos.cpp | 40 +- src/USER-DPD/fix_eos_table_rx.cpp | 139 ++++-- src/USER-DPD/fix_eos_table_rx.h | 3 +- src/USER-DPD/fix_rx.cpp | 15 +- src/USER-DPD/pair_exp6_rx.cpp | 445 ++++++++++++------ src/USER-DPD/pair_exp6_rx.h | 13 +- src/USER-DPD/pair_multi_lucy_rx.cpp | 126 +++-- src/USER-DPD/pair_multi_lucy_rx.h | 3 +- src/USER-DPD/pair_table_rx.cpp | 174 ++++--- src/USER-DPD/pair_table_rx.h | 5 +- 17 files changed, 896 insertions(+), 489 deletions(-) diff --git a/doc/src/fix_eos_table_rx.txt b/doc/src/fix_eos_table_rx.txt index f92b405f49..749642f57c 100644 --- a/doc/src/fix_eos_table_rx.txt +++ b/doc/src/fix_eos_table_rx.txt @@ -10,7 +10,7 @@ fix eos/table/rx command :h3 [Syntax:] -fix ID group-ID eos/table/rx style file1 N keyword file2 :pre +fix ID group-ID eos/table/rx style file1 N keyword ... :pre ID, group-ID are documented in "fix"_fix.html command eos/table/rx = style name of this fix command @@ -18,11 +18,16 @@ style = {linear} = method of interpolation file1 = filename containing the tabulated equation of state N = use N values in {linear} tables keyword = name of table keyword correponding to table file -file2 = filename containing the heats of formation of each species :ul +file2 = filename containing the heats of formation of each species (optional) +deltaHf = heat of formation for a single species in energy units (optional) +energyCorr = energy correction in energy units (optional) +tempCorrCoeff = temperature correction coefficient (optional) :ul [Examples:] -fix 1 all eos/table/rx linear eos.table 10000 KEYWORD thermo.table :pre +fix 1 all eos/table/rx linear eos.table 10000 KEYWORD thermo.table +fix 1 all eos/table/rx linear eos.table 10000 KEYWORD 1.5 +fix 1 all eos/table/rx linear eos.table 10000 KEYWORD 1.5 0.025 0.0 :pre [Description:] @@ -39,7 +44,15 @@ where {m} is the number of species, {c_i,j} is the concentration of species {j} in particle {i}, {u_j} is the internal energy of species j, {DeltaH_f,j} is the heat of formation of species {j}, N is the number of molecules represented by the coarse-grained particle, kb is the -Boltzmann constant, and T is the temperature of the system. +Boltzmann constant, and T is the temperature of the system. Additionally, +it is possible to modify the concentration-dependent particle internal +energy relation by adding an energy correction, temperature-dependent +correction, and/or a molecule-dependent correction. An energy correction can +be specified as a constant (in energy units). A temperature correction can be +specified by multiplying a temperature correction coefficient by the +internal temperature. A molecular correction can be specified by +by multiplying a molecule correction coefficient by the average number of +product gas particles in the coarse-grain particle. Fix {eos/table/rx} creates interpolation tables of length {N} from {m} internal energy values of each species {u_j} listed in a file as a @@ -58,6 +71,14 @@ file is described below. The second filename specifies a file containing heat of formation {DeltaH_f,j} for each species. +In cases where the coarse-grain particle represents a single molecular +species (i.e., no reactions occur and fix {rx} is not present in the input file), +fix {eos/table/rx} can be applied in a similar manner to fix {eos/table} +within a non-reactive DPD simulation. In this case, the heat of formation +filename is replaced with the heat of formation value for the single species. +Additionally, the energy correction and temperature correction coefficients may +also be specified as fix arguments. + :line The format of a tabulated file is as follows (without the @@ -116,6 +137,19 @@ Note that the species can be listed in any order. The tag that is used as the species name must correspond with the tags used to define the reactions with the "fix rx"_fix_rx.html command. +Alternatively, corrections to the EOS can be included by specifying +three additional columns that correspond to the energy correction, +the temperature correction coefficient and molecule correction +coefficient. In this case, the format of the file is as follows: + +# HEAT OF FORMATION TABLE (one or more comment or blank lines) :pre + (blank) +h2 0.00 1.23 0.025 0.0 (species name, heat of formation, energy correction, temperature correction coefficient, molecule correction coefficient) +no2 0.34 0.00 0.000 -1.76 +n2 0.00 0.00 0.000 -1.76 +... +no 0.93 0.00 0.000 -1.76 :pre + :line [Restrictions:] diff --git a/doc/src/pair_exp6_rx.txt b/doc/src/pair_exp6_rx.txt index 7b22dccc4f..dafba2c44c 100644 --- a/doc/src/pair_exp6_rx.txt +++ b/doc/src/pair_exp6_rx.txt @@ -10,16 +10,21 @@ pair_style exp6/rx command :h3 [Syntax:] -pair_style exp6/rx cutoff :pre +pair_style exp6/rx cutoff ... :pre -cutoff = global cutoff for DPD interactions (distance units) :ul +cutoff = global cutoff for DPD interactions (distance units) +weighting = fractional or molecular (optional) :ul [Examples:] pair_style exp6/rx 10.0 -pair_coeff * * exp6.params h2o h2o 1.0 1.0 10.0 -pair_coeff * * exp6.params h2o 1fluid 1.0 1.0 10.0 -pair_coeff * * exp6.params 1fluid 1fluid 1.0 1.0 10.0 :pre +pair_style exp6/rx 10.0 fractional +pair_style exp6/rx 10.0 molecular +pair_coeff * * exp6.params h2o h2o exponent 1.0 1.0 10.0 +pair_coeff * * exp6.params h2o 1fluid exponent 1.0 1.0 10.0 +pair_coeff * * exp6.params 1fluid 1fluid exponent 1.0 1.0 10.0 +pair_coeff * * exp6.params 1fluid 1fluid none 10.0 +pair_coeff * * exp6.params 1fluid 1fluid polynomial filename 10.0 :pre [Description:] @@ -50,14 +55,36 @@ defined in the reaction kinetics files specified with the "fix rx"_fix_rx.html command or they must correspond to the tag "1fluid", signifying interaction with a product species mixture determined through a one-fluid approximation. The interaction potential is -weighted by the geometric average of the concentrations of the two -species. The coarse-grained potential is stored before and after the +weighted by the geometric average of either the mole fraction concentrations +or the number of molecules associated with the interacting coarse-grained +particles (see the {fractional} or {molecular} weighting pair style options). +The coarse-grained potential is stored before and after the reaction kinetics solver is applied, where the difference is defined to be the internal chemical energy (uChem). -The fourth and fifth arguments specify the {Rm} and {epsilon} scaling exponents. +The fourth argument specifies the type of scaling that will be used +to scale the EXP-6 paramters as reactions occur. Currently, there +are three scaling options: {exponent}, {polynomial} and {none}. -The final argument specifies the interaction cutoff. +Exponent scaling requires two additional arguments for scaling +the {Rm} and {epsilon} parameters, respectively. The scaling factor +is computed by phi^exponent, where phi is the number of molecules +represented by the coarse-grain particle and exponent is specified +as a pair coefficient argument for {Rm} and {epsilon}, respectively. +The {Rm} and {epsilon} parameters are multiplied by the scaling +factor to give the scaled interaction paramters for the CG particle. + +Polynomial scaling requires a filename to be specified as a pair +coeff argument. The file contains the coefficients to a fifth order +polynomial for the {alpha}, {epsilon} and {Rm} parameters that depend +upon phi (the number of molecules represented by the CG particle). +The format of a polynomial file is provided below. + +The {none} option to the scaling does not have any additional pair coeff +arguments. This is equivalent to specifying the {exponent} option with +{Rm} and {epsilon} exponents of 0.0 and 0.0, respectively. + +The final argument specifies the interaction cutoff (optional). :line @@ -70,6 +97,19 @@ no2 exp6 13.60 0.01 3.70 ... co2 exp6 13.00 0.03 3.20 :pre +The format of the polynomial scaling file as follows (without the +parenthesized comments): + +# POLYNOMIAL FILE (one or more comment or blank lines) :pre +# General Functional Form: +# A*phi^5 + B*phi^4 + C*phi^3 + D*phi^2 + E*phi + F +# +# Parameter A B C D E F + (blank) +alpha 0.0000 0.00000 0.00008 0.04955 -0.73804 13.63201 +epsilon 0.0000 0.00478 -0.06283 0.24486 -0.33737 2.60097 +rm 0.0001 -0.00118 -0.00253 0.05812 -0.00509 1.50106 :pre + A section begins with a non-blank line whose 1st character is not a "#"; blank lines or lines starting with "#" can be used as comments between sections. @@ -117,4 +157,4 @@ LAMMPS"_Section_start.html#start_3 section for more info. "pair_coeff"_pair_coeff.html -[Default:] none +[Default:] fractional weighting diff --git a/doc/src/pair_multi_lucy_rx.txt b/doc/src/pair_multi_lucy_rx.txt index 14b5b32181..75547a71ce 100644 --- a/doc/src/pair_multi_lucy_rx.txt +++ b/doc/src/pair_multi_lucy_rx.txt @@ -13,11 +13,14 @@ pair_style multi/lucy/rx command :h3 pair_style multi/lucy/rx style N keyword ... :pre style = {lookup} or {linear} = method of interpolation -N = use N values in {lookup}, {linear} tables :ul +N = use N values in {lookup}, {linear} tables +weighting = fractional or molecular (optional) :ul [Examples:] pair_style multi/lucy/rx linear 1000 +pair_style multi/lucy/rx linear 1000 fractional +pair_style multi/lucy/rx linear 1000 molecular pair_coeff * * multibody.table ENTRY1 h2o h2o 7.0 pair_coeff * * multibody.table ENTRY1 h2o 1fluid 7.0 :pre @@ -94,8 +97,10 @@ tags must either correspond to the species defined in the reaction kinetics files specified with the "fix rx"_fix_rx.html command or they must correspond to the tag "1fluid", signifying interaction with a product species mixture determined through a one-fluid approximation. -The interaction potential is weighted by the geometric average of the -concentrations of the two species. The coarse-grained potential is +The interaction potential is weighted by the geometric average of +either the mole fraction concentrations or the number of molecules +associated with the interacting coarse-grained particles (see the +{fractional} or {molecular} weighting pair style options). The coarse-grained potential is stored before and after the reaction kinetics solver is applied, where the difference is defined to be the internal chemical energy (uChem). @@ -205,7 +210,7 @@ LAMMPS"_Section_start.html#start_3 section for more info. "pair_coeff"_pair_coeff.html -[Default:] none +[Default:] fractional weighting :line diff --git a/doc/src/pair_table_rx.txt b/doc/src/pair_table_rx.txt index e6006f62e2..d089a4f9da 100644 --- a/doc/src/pair_table_rx.txt +++ b/doc/src/pair_table_rx.txt @@ -10,16 +10,17 @@ pair_style table/rx command :h3 [Syntax:] -pair_style table style N :pre +pair_style table style N ... :pre style = {lookup} or {linear} or {spline} or {bitmap} = method of interpolation N = use N values in {lookup}, {linear}, {spline} tables -N = use 2^N values in {bitmap} tables +weighting = fractional or molecular (optional) :ul [Examples:] pair_style table/rx linear 1000 -pair_style table/rx bitmap 12 +pair_style table/rx linear 1000 fractional +pair_style table/rx linear 1000 molecular pair_coeff * * rxn.table ENTRY1 h2o h2o 10.0 pair_coeff * * rxn.table ENTRY1 1fluid 1fluid 10.0 pair_coeff * 3 rxn.table ENTRY1 h2o no2 10.0 :pre @@ -84,8 +85,10 @@ tags must either correspond to the species defined in the reaction kinetics files specified with the "fix rx"_fix_rx.html command or they must correspond to the tag "1fluid", signifying interaction with a product species mixture determined through a one-fluid approximation. -The interaction potential is weighted by the geometric average of the -concentrations of the two species. The coarse-grained potential is +The interaction potential is weighted by the geometric average of +either the mole fraction concentrations or the number of molecules +associated with the interacting coarse-grained particles (see the +{fractional} or {molecular} weighting pair style options). The coarse-grained potential is stored before and after the reaction kinetics solver is applied, where the difference is defined to be the internal chemical energy (uChem). @@ -230,7 +233,7 @@ LAMMPS"_Section_start.html#start_3 section for more info. "pair_coeff"_pair_coeff.html -[Default:] none +[Default:] fractional weighting :line diff --git a/examples/USER/dpd/dpde-vv/log.dpde-vv.reference b/examples/USER/dpd/dpde-vv/log.dpde-vv.reference index 7bc7bda365..800a39f7a5 100644 --- a/examples/USER/dpd/dpde-vv/log.dpde-vv.reference +++ b/examples/USER/dpd/dpde-vv/log.dpde-vv.reference @@ -35,129 +35,133 @@ thermo_modify format float %24.16f run 1000 Neighbor list info ... - 1 neighbor list requests update every 1 steps, delay 0 steps, check no max neighbors/atom: 2000, page size: 100000 master list distance cutoff = 10.6 ghost atom cutoff = 10.6 - binsize = 5.3 -> bins = 25 25 25 -Memory usage per processor = 3.36353 Mbytes + binsize = 5.3, bins = 25 25 25 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair dpd/fdt/energy, perpetual + pair build: half/bin/newton + stencil: half/bin/3d/newton + bin: standard +Memory usage per processor = 4.28221 Mbytes Step Temp Press PotEng KinEng c_dpdU[1] c_dpdU[2] v_totEnergy c_dpdU[4] - 0 301.4391322267262012 1636.1776395935085020 1188.6488072196075336 394.4722035796053206 7852.5601874986105031 7852.5601874986105031 17288.2413857964347699 299.9999999999841407 - 10 301.4791572483523510 1486.4422375141198245 1188.7147620806101713 394.5245815119678241 7852.5601874999802021 7852.3731942333779443 17288.1727253259377903 299.9960221120699089 - 20 301.4275643919337426 1677.9356110821624952 1188.7839634625399867 394.4570655673388728 7852.5601874999938445 7852.3711851933012440 17288.1724017231754260 299.9955485734552099 - 30 301.2240988054542186 1452.7304951528931269 1188.8550809767796181 394.1908044563202225 7852.5601875000002110 7852.5679666239848302 17288.1740395570850524 299.9988968405210130 - 40 301.1023506886409677 1527.9758363521380033 1188.9264527568634549 394.0314812537677653 7852.5601874999947540 7852.6574764573806533 17288.1755979680056043 300.0001694462812338 - 50 301.0409654880461972 1597.1737251233498682 1188.9944523606982330 393.9511507566391515 7852.5601875000029395 7852.6700547249911324 17288.1758453423317405 299.9999653064982681 - 60 301.2904978886139133 1610.8630327676828529 1189.0651026961211301 394.2776962691256131 7852.5601874999829306 7852.2734988976435488 17288.1764853628737910 299.9919857290491905 - 70 300.8575037843163500 1489.3259312130880971 1189.1295686642290548 393.7110673208616731 7852.5601874999856591 7852.7707182199101226 17288.1715417049854295 300.0010992278233175 - 80 300.5955830326474825 1449.3896097889587509 1189.1880764967559116 393.3683100440913449 7852.5601875000411383 7853.0484238882281716 17288.1649979291178170 300.0059513551503301 - 90 301.0092332775843147 1553.9266324350364812 1189.2470037925052111 393.9096250433288446 7852.5601875000420478 7852.4452067113825251 17288.1620230472581170 299.9940347326859182 - 100 301.0478004479094238 1539.2270336322194453 1189.3010269201699884 393.9600951881690207 7852.5601875000074870 7852.3416236045995902 17288.1629332129450631 299.9916385566916119 - 110 300.9609384905550087 1500.0429484565006533 1189.3524514939088021 393.8464250502817663 7852.5601874999983920 7852.4114980357189779 17288.1705620799075405 299.9925626482005327 - 120 300.9625536631411933 1630.5065919443034090 1189.4006029528841282 393.8485387131115658 7852.5601875000575092 7852.3600810123671181 17288.1694101784196391 299.9911580775880680 - 130 301.0373750247310340 1539.2267307640183844 1189.4426173625224692 393.9464521696795032 7852.5601874999993015 7852.2178388309775983 17288.1670958631802932 299.9879581026651749 - 140 300.7465104415114752 1550.8353679735087098 1189.4887352231000932 393.5658181350791551 7852.5601874999920256 7852.5559582333216895 17288.1706990914935886 299.9939749909034958 - 150 300.6667173911141617 1634.8987162883277051 1189.5368575067818711 393.4613985788388959 7852.5601874999920256 7852.6079668015609059 17288.1664103871735279 299.9946423938895350 - 160 300.4684731724562425 1462.9400882126803936 1189.5825022927965620 393.2019703048678707 7852.5601874999847496 7852.8265187980177870 17288.1711788956672535 299.9983600613423960 - 170 300.1439323338466920 1510.2352578813552100 1189.6305700279478970 392.7772665220106774 7852.5601874999802021 7853.2009671047335360 17288.1689911546709482 300.0051118582463232 - 180 300.1074244553407198 1529.6307083879951279 1189.6764977580119194 392.7294912276224181 7852.5601874999729262 7853.2047509722533505 17288.1709274578606710 300.0047089238623812 - 190 300.4193298066089142 1546.3205495807171701 1189.7172820166240399 393.1376598363699486 7852.5601874999847496 7852.7461854379371289 17288.1613147909156396 299.9954451643528728 - 200 300.3353919251508728 1532.5496449337254035 1189.7600175880224924 393.0278162310690391 7852.5601874999683787 7852.8107089913455638 17288.1587303104060993 299.9962707550171785 - 210 300.3276568499739483 1504.8178651700843602 1189.7998299597820733 393.0176938818990493 7852.5601875000156724 7852.7810130200659842 17288.1587243617614149 299.9953436245502871 - 220 300.5768315696971626 1592.5896084568344122 1189.8391466344742184 393.3437713226064716 7852.5601875000329528 7852.4205574703573802 17288.1636629274726147 299.9880321846658831 - 230 300.6587445618569063 1672.3049358942289473 1189.8766340798690635 393.4509650976162334 7852.5601874999847496 7852.2733199687863817 17288.1611066462573945 299.9848228571166828 - 240 300.7517707836825025 1527.1722267937811921 1189.9126240081129708 393.5727019751183207 7852.5601875000065775 7852.1160682173085661 17288.1615817005440476 299.9814952182625802 - 250 300.8473715548367409 1589.1847713095248764 1189.9441342461948352 393.6978079843565865 7852.5601875000047585 7851.9625847797888127 17288.1647145103452203 299.9782210858571148 - 260 300.8450266408960942 1623.1896863377055524 1189.9636161513917614 393.6947393603111891 7852.5601874999820211 7851.9471828473988353 17288.1657258590821584 299.9775302202895659 - 270 300.6663619570709898 1564.5160171187899323 1189.9764081239700317 393.4609334472908131 7852.5601875000193104 7852.1708276117251444 17288.1683566830033669 299.9812899253168439 - 280 300.7668534205726019 1618.5400526904263643 1189.9872008155405183 393.5924395618274048 7852.5601875000184009 7852.0271568534708422 17288.1669847308585304 299.9781169783826158 - 290 300.8462727198648849 1562.6765776748122789 1189.9918265985252219 393.6963700162682471 7852.5601875000211294 7851.9189772084127981 17288.1673613232269417 299.9756806168044250 - 300 300.8095414073812890 1525.1785808192844343 1189.9873922767767453 393.6483023295390922 7852.5601875000020300 7851.9657301693578120 17288.1616122756749974 299.9761279889730758 - 310 300.9496330741350221 1566.5597234051326723 1189.9752299662607129 393.8316304464934774 7852.5601875000056680 7851.7898117189633922 17288.1568596317229094 299.9723726900590464 - 320 301.2370566356515837 1513.6869483705047514 1189.9626455872523820 394.2077614578674343 7852.5601874999929350 7851.4248466706330873 17288.1554412157456682 299.9650543775110236 - 330 301.3279721508968692 1549.0667862452519330 1189.9513389477854162 394.3267362020337146 7852.5601874999929350 7851.3129955581916875 17288.1512582080031279 299.9625537201162615 - 340 301.1145736537583844 1414.7930515101759283 1189.9408691169965095 394.0474765890400590 7852.5601874999993015 7851.6028846074832472 17288.1514178135184920 299.9677356565828745 - 350 301.1651600907370039 1529.8016115175887535 1189.9314470205476937 394.1136755032911196 7852.5601874999929350 7851.5441417268757505 17288.1494517507089768 299.9662576716461331 - 360 301.0550563185083206 1536.7721716375504002 1189.9200519814730796 393.9695904359920178 7852.5601875000074870 7851.7101209691463737 17288.1599508866202086 299.9690811750865009 - 370 301.1008976932964742 1522.3385843459479929 1189.9109162496640693 394.0295798208944120 7852.5601875000211294 7851.6603423306560217 17288.1610259012340975 299.9677565060027860 - 380 301.1656898730700505 1505.0548721701993600 1189.9005648244351505 394.1143687921909304 7852.5601875000056680 7851.5816827598300733 17288.1568038764598896 299.9659906785156522 - 390 300.8379322662876802 1740.9151205755624687 1189.8851457594087151 393.6854554509390596 7852.5601875000238579 7852.0268864110385039 17288.1576751214088290 299.9741278188615752 - 400 300.8663790447546376 1564.9461156870302148 1189.8690133470408909 393.7226817503372445 7852.5601875000411383 7852.0043792319993372 17288.1562618294192362 299.9732593416579789 - 410 300.6263441860635908 1564.2840871092373618 1189.8566574093877080 393.4085650033033517 7852.5601874999892971 7852.3284491703725507 17288.1538590830532485 299.9792095875052951 - 420 300.5302259436974168 1438.1569922368764765 1189.8406936554465574 393.2827818158641549 7852.5601875000302243 7852.4696075433648730 17288.1532705147074012 299.9815165752025337 - 430 300.5877786105220935 1503.3641639033023694 1189.8251514530138593 393.3580969454444016 7852.5601874999802021 7852.4023373559457468 17288.1457732543858583 299.9798346272511935 - 440 300.7289160804472772 1689.2527029957295781 1189.8035410609209066 393.5427936314976591 7852.5601875000029395 7852.2436462415198548 17288.1501684339418716 299.9764596782897570 - 450 300.9487198282456575 1497.3668092174791582 1189.7808137689632986 393.8304353457919547 7852.5601874999938445 7851.9788323927432430 17288.1502690074921702 299.9710227473042323 - 460 300.9359942496024587 1625.1573864018491804 1189.7615359247627111 393.8137822755282400 7852.5601875000147629 7852.0165192783370003 17288.1520249786408385 299.9713565393226986 - 470 301.0000133856357252 1486.1561922844011860 1189.7439269526955741 393.8975596188205941 7852.5601874999656502 7851.9561324572268859 17288.1578065287103527 299.9697143418395626 - 480 300.8568627175957886 1535.6080526199095857 1189.7237810071801505 393.7102284019063063 7852.5601874999601932 7852.1697010727630186 17288.1638979818089865 299.9732503057674080 - 490 301.0608040775520067 1497.3221544489886128 1189.7062242497636362 393.9771121242308709 7852.5601874999974825 7851.9258988739011329 17288.1694227478947141 299.9682362511933320 - 500 301.0232592587148019 1517.5854528541199215 1189.6911287485861521 393.9279798589197981 7852.5601875000247674 7851.9823225510326665 17288.1616186585633841 299.9690333355835037 - 510 300.7038579923685120 1420.2615974401142012 1189.6747661513456933 393.5100018730125839 7852.5601874999674692 7852.4114869568047652 17288.1564424811294884 299.9768186576545759 - 520 300.5917863355052759 1537.4862082427132464 1189.6604754398756540 393.3633415734188361 7852.5601875000029395 7852.5789017095057716 17288.1629062228021212 299.9795694302102333 - 530 300.4751352158502868 1481.1071694751799441 1189.6453243069925065 393.2106884527691477 7852.5601874999811116 7852.7451655714066874 17288.1613658311471227 299.9823181268525900 - 540 300.5380123640739498 1547.3461372766389559 1189.6261485232855648 393.2929713568877332 7852.5601875000375003 7852.6850583598352387 17288.1643657400454686 299.9808112190538623 - 550 300.4253885005187499 1544.3485889749692888 1189.6033595464525661 393.1455884232119047 7852.5601874999756546 7852.8598718466746504 17288.1690073163154011 299.9835860164698147 - 560 300.3263552442093101 1556.5150300058251105 1189.5759163336824713 393.0159905619273673 7852.5601875000111249 7853.0148613782675966 17288.1669557738860021 299.9861837797674866 - 570 300.1977324643196425 1511.2320626303917379 1189.5441090918316149 392.8476709710407704 7852.5601875000102154 7853.2098259401755058 17288.1617935030590161 299.9896761688499964 - 580 300.3543631005173893 1588.9566243200433746 1189.5094471319721379 393.0526424747489500 7852.5601875000156724 7853.0374555421631158 17288.1597326488990802 299.9859298211933378 - 590 300.5019108864805730 1504.4406939723214691 1189.4809412920112663 393.2457278908070748 7852.5601874999874781 7852.8704277855340479 17288.1572844683396397 299.9823573257917815 - 600 300.4791158523048011 1540.4690749004150803 1189.4551948503105905 393.2158976318902432 7852.5601875000220389 7852.9312239063838206 17288.1625038886049879 299.9832002920041987 - 610 300.5939139841889869 1368.0565839211087678 1189.4252547652590692 393.3661258776944578 7852.5601874999574648 7852.8130977336286378 17288.1646658765384927 299.9807742697515778 - 620 300.7674247480806002 1483.2566452708945235 1189.3941250938435132 393.5931872179773450 7852.5601875000193104 7852.6187967208716145 17288.1662965327122947 299.9766963671718258 - 630 300.7920034341021278 1543.0699124130637756 1189.3598279316649950 393.6253516166882491 7852.5601875000302243 7852.6219971866230480 17288.1673642350069713 299.9762538437230432 - 640 300.8032734267029014 1423.2549819291616586 1189.3293074476885067 393.6400998638143278 7852.5601874999847496 7852.6384826097782934 17288.1680774212654796 299.9762118202994543 - 650 300.7516995878241346 1542.6559695158523482 1189.3021161045705867 393.5726088061030055 7852.5601874999720167 7852.7361949473242930 17288.1711073579681397 299.9775656396505497 - 660 300.8699697098109596 1675.5121937767839881 1189.2687179804190691 393.7273806013013768 7852.5601874999802021 7852.6179739687149777 17288.1742600504148868 299.9750492262036801 - 670 301.0255004186900578 1520.7397686587873977 1189.2284265783687260 393.9309127074437242 7852.5601874999847496 7852.4592279727157802 17288.1787547585117863 299.9715123049731460 - 680 301.1071983488760679 1651.9751417063259851 1189.1858967311386550 394.0378250459656329 7852.5601875000002110 7852.3982826328638112 17288.1821919099675142 299.9699481289110850 - 690 301.0027086454253435 1496.1607274163641250 1189.1436949551202815 393.9010867158519886 7852.5601875000293148 7852.5788938360938118 17288.1838630070960789 299.9731939774295597 - 700 300.9009090279179759 1551.8182127127668082 1189.0993919251338866 393.7678687121208441 7852.5601875000102154 7852.7513665452252098 17288.1788146824910655 299.9761043445071209 - 710 301.2325536720837817 1678.1546953970853338 1189.0528341066981284 394.2018687459686817 7852.5601874999956635 7852.3633298995819132 17288.1782202522445004 299.9683013583347133 - 720 301.2122298224125529 1524.1415452491430642 1189.0046957644285612 394.1752723525083866 7852.5601875000093059 7852.4351629896145823 17288.1753186065616319 299.9693315350040734 - 730 301.0763282392692304 1547.1987029633166912 1188.9602551214045434 393.9974275034455218 7852.5601874999883876 7852.6518053705112834 17288.1696754953518393 299.9732715774841267 - 740 301.3262401480515109 1544.7045314021493141 1188.9131307177485724 394.3244696516559884 7852.5601874999965730 7852.3694201272974169 17288.1672079966992897 299.9674666811455950 - 750 301.5740779122830304 1591.1785078054851965 1188.8637580645938669 394.6487975126887022 7852.5601875000029395 7852.0919529470393172 17288.1646960243233480 299.9616008527094095 - 760 301.4385361878654521 1547.3218422039201414 1188.8113669183098864 394.4714235854450521 7852.5601874999838401 7852.3161911124070684 17288.1591691161447670 299.9656339783694534 - 770 301.6110125684814420 1494.5039561806622714 1188.7581685915934031 394.6971313010439530 7852.5601875000083965 7852.1351720579104949 17288.1506594505553949 299.9619855799395509 - 780 301.8360352039435384 1588.1458619705292676 1188.7039178696472845 394.9916026067776329 7852.5601874999956635 7851.9015195838428554 17288.1572275602629816 299.9572350302977952 - 790 302.1008324754310479 1545.4409171812178556 1188.6491103416560691 395.3381241828382144 7852.5601875000138534 7851.6150048936624444 17288.1624269181702402 299.9513959104631340 - 800 301.9660372380565718 1563.9565804790736365 1188.5964649891604950 395.1617271307158035 7852.5601874999874781 7851.8461249560614306 17288.1645045759250934 299.9555810527747326 - 810 302.0507207347627627 1511.4560763489957935 1188.5468477146612258 395.2725464702810996 7852.5601875000120344 7851.7904104899025697 17288.1699921748586348 299.9541551776504775 - 820 302.4700213214911741 1458.5135514273570152 1188.4981381693974072 395.8212556746473751 7852.5601875000202199 7851.2935886962204677 17288.1731700402851857 299.9441803241180651 - 830 302.2853997979337350 1496.2544527963129894 1188.4496917372191547 395.5796544641875698 7852.5601875000447762 7851.5862641793482908 17288.1757978808018379 299.9494768794835977 - 840 302.0840465730901201 1518.8301331998704882 1188.3994383226176978 395.3161576523596636 7852.5601875000038490 7851.8962146812327774 17288.1719981562127941 299.9550476592922337 - 850 301.8910942560261788 1469.8827850510901953 1188.3489956121345585 395.0636545180261692 7852.5601874999829306 7852.2025804631493884 17288.1754180932912277 299.9606927700139067 - 860 301.7284384160519153 1657.6802015862324424 1188.3052233777652873 394.8507982536594341 7852.5601875000093059 7852.4644669022691232 17288.1806760337058222 299.9652835238809985 - 870 301.6331619894115192 1501.5829953208524330 1188.2628815714097072 394.7261166912876433 7852.5601875000202199 7852.6378180648598573 17288.1870038275774277 299.9682811831179379 - 880 301.3703918424367316 1499.1595903074553462 1188.2195190931643083 394.3822478705861272 7852.5601874999956635 7853.0266423250832304 17288.1885967888301820 299.9755099056966401 - 890 301.4157954313303662 1598.8758859042511631 1188.1845892608291706 394.4416643558612918 7852.5601875000065775 7853.0036606192506952 17288.1901017359487014 299.9745322513492738 - 900 301.4752150615485675 1621.2148728756822038 1188.1517520946135846 394.5194226492019993 7852.5601874999711072 7852.9579580608560718 17288.1893203046420240 299.9733125337182287 - 910 301.4308816315938770 1538.4823217911632582 1188.1159856659232901 394.4614066057066566 7852.5601875000002110 7853.0558695713261841 17288.1934493429580471 299.9748317405193916 - 920 301.4323110133492492 1594.7193046491217956 1188.0835779842032025 394.4632771371357762 7852.5601875000202199 7853.0942701464364291 17288.2013127677964803 299.9751127806911200 - 930 301.4801256941950101 1387.6885377097617038 1188.0464206196895702 394.5258488489681099 7852.5601875000229484 7853.0656502842994087 17288.1981072529815719 299.9740698440909910 - 940 301.8075611840245074 1534.2487040663793323 1188.0124217312886685 394.9543406584059539 7852.5601874999701977 7852.6729444202819650 17288.1998943099461030 299.9660570413493588 - 950 301.6915970126173647 1567.7725992489238251 1187.9790455470049437 394.8025864986412898 7852.5601875000274958 7852.8619557087595240 17288.2037752544347313 299.9694678653150959 - 960 301.6392594677008105 1504.8502165144939227 1187.9439133338105421 394.7340960325207675 7852.5601874999711072 7852.9728807988849439 17288.2110776651898050 299.9711546356286362 - 970 301.6049535791644303 1514.0198965433548892 1187.9094123369413865 394.6892023276233772 7852.5601874999765641 7853.0497909819878259 17288.2085931465298927 299.9722547114341751 - 980 301.2982841679705643 1634.1208149125807267 1187.8768454876480973 394.2878856256063500 7852.5601874999856591 7853.4862008383515786 17288.2111194515891839 299.9802110109069986 - 990 301.2573007350166563 1489.7316698898257528 1187.8432331161868660 394.2342534877078606 7852.5601875000047585 7853.5840096862748396 17288.2216837901723920 299.9819468620868292 - 1000 301.3195135766228532 1562.6587211933920116 1187.8034267774903583 394.3156670604516307 7852.5601874999356369 7853.5372636956635688 17288.2165450335414789 299.9807651637231629 -Loop time of 21.3308 on 1 procs for 1000 steps with 10125 atoms + 0 301.4391322267262012 1636.1776395935080473 1188.6488072196075336 394.4722035796053206 0.0000000000000000 15705.1203749972210062 17288.2413857964347699 299.9999999999841407 + 10 301.4791572483523510 1486.4422375141214161 1188.7147620806101713 394.5245815119678241 0.0000000000000000 15704.9333817333845218 17288.1727253259632562 299.9960221120699089 + 20 301.4275643919337995 1677.9356110821622678 1188.7839634625399867 394.4570655673389865 -0.0000000000000000 15704.9313726932996360 17288.1724017231790640 299.9955485734552667 + 30 301.2240988054542186 1452.7304951528922174 1188.8550809767796181 394.1908044563202225 -0.0000000000000000 15705.1281541239713988 17288.1740395570705005 299.9988968405209562 + 40 301.1023506886409109 1527.9758363521384581 1188.9264527568634549 394.0314812537677085 -0.0000000000000000 15705.2176639573335706 17288.1755979679655866 300.0001694462812907 + 50 301.0409654880461972 1597.1737251233505503 1188.9944523606984603 393.9511507566391515 -0.0000000000000000 15705.2302422249904339 17288.1758453423281026 299.9999653064982112 + 60 301.2904978886138565 1610.8630327676828529 1189.0651026961211301 394.2776962691255562 -0.0000000000000000 15704.8336863976528548 17288.1764853628992569 299.9919857290491905 + 70 300.8575037843164068 1489.3259312130892340 1189.1295686642290548 393.7110673208617300 0.0000000000000000 15705.3309057198275696 17288.1715417049199459 300.0010992278232607 + 80 300.5955830326474825 1449.3896097889576140 1189.1880764967559116 393.3683100440913449 -0.0000000000000000 15705.6086113882302016 17288.1649979290777992 300.0059513551502164 + 90 301.0092332775843147 1553.9266324350371633 1189.2470037925056658 393.9096250433288446 -0.0000000000000000 15705.0053942113881931 17288.1620230472217372 299.9940347326859182 + 100 301.0478004479094238 1539.2270336322201274 1189.3010269201699884 393.9600951881690207 -0.0000000000000000 15704.9018111045588739 17288.1629332128977694 299.9916385566916119 + 110 300.9609384905550655 1500.0429484565015628 1189.3524514939088021 393.8464250502818231 -0.0000000000000000 15704.9716855356964516 17288.1705620798857126 299.9925626482006464 + 120 300.9625536631413070 1630.5065919443020448 1189.4006029528841282 393.8485387131116795 0.0000000000000000 15704.9202685123345873 17288.1694101783286897 299.9911580775880680 + 130 301.0373750247309772 1539.2267307640188392 1189.4426173625224692 393.9464521696794463 -0.0000000000000000 15704.7780263310032751 17288.1670958632057591 299.9879581026650044 + 140 300.7465104415114183 1550.8353679735089372 1189.4887352231000932 393.5658181350790983 0.0000000000000000 15705.1161457332873397 17288.1706990914681228 299.9939749909034958 + 150 300.6667173911142186 1634.8987162883267956 1189.5368575067818711 393.4613985788390096 0.0000000000000000 15705.1681543015274656 17288.1664103871480620 299.9946423938894213 + 160 300.4684731724561857 1462.9400882126797114 1189.5825022927965620 393.2019703048678139 0.0000000000000000 15705.3867062980680203 17288.1711788957327371 299.9983600613422254 + 170 300.1439323338466920 1510.2352578813547552 1189.6305700279476696 392.7772665220106774 -0.0000000000000000 15705.7611546046609874 17288.1689911546200165 300.0051118582463232 + 180 300.1074244553407766 1529.6307083879964921 1189.6764977580119194 392.7294912276225318 -0.0000000000000000 15705.7649384723172261 17288.1709274579516205 300.0047089238623812 + 190 300.4193298066088573 1546.3205495807169427 1189.7172820166242673 393.1376598363698349 0.0000000000000000 15705.3063729379555298 17288.1613147909483814 299.9954451643527022 + 200 300.3353919251508728 1532.5496449337249487 1189.7600175880224924 393.0278162310690391 -0.0000000000000000 15705.3708964914076205 17288.1587303105006868 299.9962707550172922 + 210 300.3276568499739483 1504.8178651700850423 1189.7998299597820733 393.0176938818990493 0.0000000000000000 15705.3412005200552812 17288.1587243617359491 299.9953436245502871 + 220 300.5768315696972195 1592.5896084568353217 1189.8391466344739911 393.3437713226065284 -0.0000000000000000 15704.9807449702821032 17288.1636629273634753 299.9880321846658262 + 230 300.6587445618569063 1672.3049358942282652 1189.8766340798690635 393.4509650976162334 0.0000000000000000 15704.8335074687693123 17288.1611066462537565 299.9848228571169102 + 240 300.7517707836825025 1527.1722267937814195 1189.9126240081131982 393.5727019751183207 -0.0000000000000000 15704.6762557172896777 17288.1615817005222198 299.9814952182625802 + 250 300.8473715548367409 1589.1847713095232848 1189.9441342461948352 393.6978079843565865 0.0000000000000000 15704.5227722798481409 17288.1647145103997900 299.9782210858571148 + 260 300.8450266408959806 1623.1896863377055524 1189.9636161513917614 393.6947393603110186 0.0000000000000000 15704.5073703474117792 17288.1657258591149002 299.9775302202894522 + 270 300.6663619570710466 1564.5160171187892502 1189.9764081239700317 393.4609334472908699 0.0000000000000000 15704.7310151116998895 17288.1683566829597112 299.9812899253167302 + 280 300.7668534205727155 1618.5400526904256822 1189.9872008155405183 393.5924395618275184 0.0000000000000000 15704.5873443533891987 17288.1669847307566670 299.9781169783825590 + 290 300.8462727198648281 1562.6765776748138705 1189.9918265985252219 393.6963700162681334 0.0000000000000000 15704.4791647084566648 17288.1673613232487696 299.9756806168042544 + 300 300.8095414073812890 1525.1785808192844343 1189.9873922767767453 393.6483023295390922 0.0000000000000000 15704.5259176693853078 17288.1616122757004632 299.9761279889731327 + 310 300.9496330741349652 1566.5597234051326723 1189.9752299662607129 393.8316304464933637 0.0000000000000000 15704.3499992189717887 17288.1568596317265474 299.9723726900589327 + 320 301.2370566356514132 1513.6869483705036146 1189.9626455872523820 394.2077614578672069 0.0000000000000000 15703.9850341706151085 17288.1554412157347542 299.9650543775107394 + 330 301.3279721508969260 1549.0667862452526151 1189.9513389477854162 394.3267362020338282 0.0000000000000000 15703.8731830581982649 17288.1512582080176799 299.9625537201162615 + 340 301.1145736537582707 1414.7930515101757010 1189.9408691169962822 394.0474765890398885 0.0000000000000000 15704.1630721074998291 17288.1514178135366819 299.9677356565827040 + 350 301.1651600907369470 1529.8016115175894356 1189.9314470205474663 394.1136755032910628 0.0000000000000000 15704.1043292268568621 17288.1494517506944248 299.9662576716459625 + 360 301.0550563185083206 1536.7721716375513097 1189.9200519814730796 393.9695904359920178 0.0000000000000000 15704.2703084691693221 17288.1599508866347605 299.9690811750866146 + 370 301.1008976932965311 1522.3385843459491298 1189.9109162496640693 394.0295798208944689 0.0000000000000000 15704.2205298306434997 17288.1610259012013557 299.9677565060027860 + 380 301.1656898730701073 1505.0548721701995873 1189.9005648244356053 394.1143687921909873 -0.0000000000000000 15704.1418702597857191 17288.1568038764125959 299.9659906785157091 + 390 300.8379322662877371 1740.9151205755633782 1189.8851457594089425 393.6854554509391164 -0.0000000000000000 15704.5870739109432179 17288.1576751212924137 299.9741278188614046 + 400 300.8663790447545239 1564.9461156870302148 1189.8690133470406636 393.7226817503371308 0.0000000000000000 15704.5645667319495260 17288.1562618293282867 299.9732593416576947 + 410 300.6263441860637045 1564.2840871092375892 1189.8566574093874806 393.4085650033035222 -0.0000000000000000 15704.8886366703736712 17288.1538590830641624 299.9792095875053519 + 420 300.5302259436973031 1438.1569922368769312 1189.8406936554461026 393.2827818158640412 0.0000000000000000 15705.0297950433650840 17288.1532705146746594 299.9815165752024768 + 430 300.5877786105221503 1503.3641639033021420 1189.8251514530136319 393.3580969454445153 -0.0000000000000000 15704.9625248558968451 17288.1457732543567545 299.9798346272512504 + 440 300.7289160804472772 1689.2527029957295781 1189.8035410609209066 393.5427936314976591 -0.0000000000000000 15704.8038337415237038 17288.1501684339418716 299.9764596782894728 + 450 300.9487198282456006 1497.3668092174784761 1189.7808137689632986 393.8304353457918978 -0.0000000000000000 15704.5390198927143501 17288.1502690074703423 299.9710227473042323 + 460 300.9359942496024019 1625.1573864018473614 1189.7615359247631659 393.8137822755281263 0.0000000000000000 15704.5767067783035600 17288.1520249785935448 299.9713565393225849 + 470 301.0000133856357252 1486.1561922844020955 1189.7439269526958014 393.8975596188205941 0.0000000000000000 15704.5163199572089070 17288.1578065287249046 299.9697143418395058 + 480 300.8568627175958454 1535.6080526199100404 1189.7237810071803779 393.7102284019064200 -0.0000000000000000 15704.7298885727686866 17288.1638979818562802 299.9732503057675785 + 490 301.0608040775520067 1497.3221544489890675 1189.7062242497640909 393.9771121242308709 -0.0000000000000000 15704.4860863739140768 17288.1694227479092660 299.9682362511933889 + 500 301.0232592587148019 1517.5854528541185573 1189.6911287485863795 393.9279798589197981 -0.0000000000000000 15704.5425100510510674 17288.1616186585561081 299.9690333355832195 + 510 300.7038579923685120 1420.2615974401142012 1189.6747661513456933 393.5100018730125839 -0.0000000000000000 15704.9716744568013382 17288.1564424811585923 299.9768186576548032 + 520 300.5917863355052759 1537.4862082427125642 1189.6604754398761088 393.3633415734188361 -0.0000000000000000 15705.1390892093895673 17288.1629062226857059 299.9795694302102902 + 530 300.4751352158504574 1481.1071694751785799 1189.6453243069920518 393.2106884527693751 -0.0000000000000000 15705.3053530714041699 17288.1613658311653126 299.9823181268525900 + 540 300.5380123640739498 1547.3461372766387285 1189.6261485232855648 393.2929713568877332 0.0000000000000000 15705.2452458598490921 17288.1643657400236407 299.9808112190538623 + 550 300.4253885005187499 1544.3485889749688340 1189.6033595464525661 393.1455884232119047 0.0000000000000000 15705.4200593467012368 17288.1690073163663328 299.9835860164698147 + 560 300.3263552442091395 1556.5150300058239736 1189.5759163336820166 393.0159905619271399 0.0000000000000000 15705.5750488783432957 17288.1669557739514858 299.9861837797674298 + 570 300.1977324643196994 1511.2320626303924200 1189.5441090918316149 392.8476709710408272 0.0000000000000000 15705.7700134401693504 17288.1617935030408262 299.9896761688500533 + 580 300.3543631005173893 1588.9566243200420104 1189.5094471319723652 393.0526424747489500 -0.0000000000000000 15705.5976430422142585 17288.1597326489354600 299.9859298211932810 + 590 300.5019108864805730 1504.4406939723210144 1189.4809412920112663 393.2457278908070748 -0.0000000000000000 15705.4306152855297114 17288.1572844683469157 299.9823573257918952 + 600 300.4791158523048011 1540.4690749004137160 1189.4551948503108179 393.2158976318902432 0.0000000000000000 15705.4914114063831221 17288.1625038885831600 299.9832002920041418 + 610 300.5939139841890437 1368.0565839211083130 1189.4252547652597514 393.3661258776945715 0.0000000000000000 15705.3732852337052464 17288.1646658766585460 299.9807742697515209 + 620 300.7674247480806002 1483.2566452708929319 1189.3941250938437406 393.5931872179773450 0.0000000000000000 15705.1789842209145718 17288.1662965327341226 299.9766963671719395 + 630 300.7920034341022415 1543.0699124130630935 1189.3598279316649950 393.6253516166883628 -0.0000000000000000 15705.1821846865786938 17288.1673642349305737 299.9762538437231001 + 640 300.8032734267029014 1423.2549819291609765 1189.3293074476887341 393.6400998638143278 -0.0000000000000000 15705.1986701098048798 17288.1680774213091354 299.9762118202993975 + 650 300.7516995878240209 1542.6559695158514387 1189.3021161045703593 393.5726088061028349 0.0000000000000000 15705.2963824473390559 17288.1711073580117954 299.9775656396504360 + 660 300.8699697098108459 1675.5121937767842155 1189.2687179804192965 393.7273806013012063 0.0000000000000000 15705.1781614686860848 17288.1742600504076108 299.9750492262035095 + 670 301.0255004186899441 1520.7397686587889893 1189.2284265783694082 393.9309127074436105 0.0000000000000000 15705.0194154727287241 17288.1787547585408902 299.9715123049731460 + 680 301.1071983488761248 1651.9751417063253029 1189.1858967311388824 394.0378250459656897 0.0000000000000000 15704.9584701329349627 17288.1821919100402738 299.9699481289110281 + 690 301.0027086454255141 1496.1607274163641250 1189.1436949551202815 393.9010867158522160 0.0000000000000000 15705.1390813360922039 17288.1838630070633371 299.9731939774292755 + 700 300.9009090279178622 1551.8182127127668082 1189.0993919251338866 393.7678687121206735 -0.0000000000000000 15705.3115540452217829 17288.1788146824765136 299.9761043445070641 + 710 301.2325536720837817 1678.1546953970841969 1189.0528341066981284 394.2018687459686817 0.0000000000000000 15704.9235173995584773 17288.1782202522263105 299.9683013583346565 + 720 301.2122298224125529 1524.1415452491437463 1189.0046957644283339 394.1752723525083866 0.0000000000000000 15704.9953504895402148 17288.1753186064779584 299.9693315350040734 + 730 301.0763282392692304 1547.1987029633176007 1188.9602551214045434 393.9974275034455218 0.0000000000000000 15705.2119928705469647 17288.1696754953954951 299.9732715774840699 + 740 301.3262401480515109 1544.7045314021493141 1188.9131307177485724 394.3244696516559884 0.0000000000000000 15704.9296076272603386 17288.1672079966665478 299.9674666811455950 + 750 301.5740779122830872 1591.1785078054849691 1188.8637580645940943 394.6487975126887591 0.0000000000000000 15704.6521404470349808 17288.1646960243160720 299.9616008527092959 + 760 301.4385361878655658 1547.3218422039212783 1188.8113669183098864 394.4714235854451658 0.0000000000000000 15704.8763786124927719 17288.1591691162466304 299.9656339783693966 + 770 301.6110125684815557 1494.5039561806624988 1188.7581685915934031 394.6971313010441236 0.0000000000000000 15704.6953595579507237 17288.1506594505881367 299.9619855799396646 + 780 301.8360352039435384 1588.1458619705304045 1188.7039178696477393 394.9916026067776329 0.0000000000000000 15704.4617070838321524 17288.1572275602593436 299.9572350302976247 + 790 302.1008324754310479 1545.4409171812180830 1188.6491103416560691 395.3381241828382144 0.0000000000000000 15704.1751923936917592 17288.1624269181847922 299.9513959104630771 + 800 301.9660372380565718 1563.9565804790738639 1188.5964649891604950 395.1617271307158035 0.0000000000000000 15704.4063124560707365 17288.1645045759469212 299.9555810527747326 + 810 302.0507207347627059 1511.4560763489960209 1188.5468477146607711 395.2725464702810427 0.0000000000000000 15704.3505979898400255 17288.1699921747822373 299.9541551776507617 + 820 302.4700213214913447 1458.5135514273563331 1188.4981381693974072 395.8212556746476025 0.0000000000000000 15703.8537761962070363 17288.1731700402524439 299.9441803241177809 + 830 302.2853997979336214 1496.2544527963145811 1188.4496917372191547 395.5796544641873993 0.0000000000000000 15704.1464516793694202 17288.1757978807763720 299.9494768794834840 + 840 302.0840465730901201 1518.8301331998702608 1188.3994383226179252 395.3161576523596636 0.0000000000000000 15704.4564021812439023 17288.1719981562200701 299.9550476592922337 + 850 301.8910942560260082 1469.8827850510904227 1188.3489956121347859 395.0636545180259986 0.0000000000000000 15704.7627679631386854 17288.1754180932985037 299.9606927700136794 + 860 301.7284384160518016 1657.6802015862315329 1188.3052233777652873 394.8507982536592635 0.0000000000000000 15705.0246544022065791 17288.1806760336330626 299.9652835238807711 + 870 301.6331619894114624 1501.5829953208508414 1188.2628815714099346 394.7261166912875865 0.0000000000000000 15705.1980055648327834 17288.1870038275301340 299.9682811831179947 + 880 301.3703918424367316 1499.1595903074555736 1188.2195190931643083 394.3822478705861272 0.0000000000000000 15705.5868298250898079 17288.1885967888410960 299.9755099056964127 + 890 301.4157954313303662 1598.8758859042509357 1188.1845892608291706 394.4416643558612918 0.0000000000000000 15705.5638481192290783 17288.1901017359195976 299.9745322513492738 + 900 301.4752150615486812 1621.2148728756842502 1188.1517520946144941 394.5194226492021699 0.0000000000000000 15705.5181455608308170 17288.1893203046492999 299.9733125337182287 + 910 301.4308816315937634 1538.4823217911621214 1188.1159856659228353 394.4614066057064861 0.0000000000000000 15705.6160570713091147 17288.1934493429398572 299.9748317405192779 + 920 301.4323110133492492 1594.7193046491240693 1188.0835779842032025 394.4632771371357762 0.0000000000000000 15705.6544576464475540 17288.2013127677855664 299.9751127806913473 + 930 301.4801256941949532 1387.6885377097596574 1188.0464206196900250 394.5258488489680531 0.0000000000000000 15705.6258377843460039 17288.1981072530033998 299.9740698440912183 + 940 301.8075611840245074 1534.2487040663797870 1188.0124217312888959 394.9543406584059539 0.0000000000000000 15705.2331319202457962 17288.1998943099388271 299.9660570413491882 + 950 301.6915970126175353 1567.7725992489226883 1187.9790455470049437 394.8025864986415172 0.0000000000000000 15705.4221432087451831 17288.2037752543910756 299.9694678653152096 + 960 301.6392594677008105 1504.8502165144939227 1187.9439133338107695 394.7340960325207675 0.0000000000000000 15705.5330682989206252 17288.2110776652516506 299.9711546356285226 + 970 301.6049535791644871 1514.0198965433535250 1187.9094123369409317 394.6892023276234909 0.0000000000000000 15705.6099784820144123 17288.2085931465771864 299.9722547114341751 + 980 301.2982841679706780 1634.1208149125800446 1187.8768454876478700 394.2878856256065205 0.0000000000000000 15706.0463883383199573 17288.2111194515746320 299.9802110109068849 + 990 301.2573007350166563 1489.7316698898262075 1187.8432331161866387 394.2342534877078606 0.0000000000000000 15706.1441971863041545 17288.2216837901978579 299.9819468620868292 + 1000 301.3195135766228532 1562.6587211933931485 1187.8034267774903583 394.3156670604516307 0.0000000000000000 15706.0974511956701463 17288.2165450336106005 299.9807651637235040 +Loop time of 17.0881 on 1 procs for 1000 steps with 10125 atoms -Performance: 4.050 ns/day, 5.925 hours/ns, 46.880 timesteps/s -99.8% CPU use with 1 MPI tasks x no OpenMP threads +Performance: 5.056 ns/day, 4.747 hours/ns, 58.520 timesteps/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 | 10.099 | 10.099 | 10.099 | 0.0 | 47.34 -Neigh | 10.145 | 10.145 | 10.145 | 0.0 | 47.56 -Comm | 0.49807 | 0.49807 | 0.49807 | 0.0 | 2.33 -Output | 0.011203 | 0.011203 | 0.011203 | 0.0 | 0.05 -Modify | 0.28296 | 0.28296 | 0.28296 | 0.0 | 1.33 -Other | | 0.295 | | | 1.38 +Pair | 8.0541 | 8.0541 | 8.0541 | 0.0 | 47.13 +Neigh | 8.1306 | 8.1306 | 8.1306 | 0.0 | 47.58 +Comm | 0.39415 | 0.39415 | 0.39415 | 0.0 | 2.31 +Output | 0.01103 | 0.01103 | 0.01103 | 0.0 | 0.06 +Modify | 0.24061 | 0.24061 | 0.24061 | 0.0 | 1.41 +Other | | 0.2576 | | | 1.51 Nlocal: 10125 ave 10125 max 10125 min Histogram: 1 0 0 0 0 0 0 0 0 0 @@ -170,4 +174,4 @@ Total # of neighbors = 114682 Ave neighs/atom = 11.3266 Neighbor list builds = 1000 Dangerous builds not checked -Total wall time: 0:00:21 +Total wall time: 0:00:17 diff --git a/examples/USER/dpd/dpdrx-shardlow/in.dpdrx-shardlow b/examples/USER/dpd/dpdrx-shardlow/in.dpdrx-shardlow index e65b5a14db..815c974741 100755 --- a/examples/USER/dpd/dpdrx-shardlow/in.dpdrx-shardlow +++ b/examples/USER/dpd/dpdrx-shardlow/in.dpdrx-shardlow @@ -37,7 +37,7 @@ timestep 0.001 pair_style hybrid/overlay dpd/fdt/energy 16.00 234324 exp6/rx 16.00 pair_coeff * * dpd/fdt/energy 0.0 0.05 10.0 16.00 -pair_coeff * * exp6/rx params.exp6 1fluid 1fluid 1.0 1.0 16.00 +pair_coeff * * exp6/rx params.exp6 1fluid 1fluid exponent 1.0 1.0 16.00 fix 1 all shardlow fix 2 all nve diff --git a/examples/USER/dpd/dpdrx-shardlow/log.dpdrx-shardlow.reference b/examples/USER/dpd/dpdrx-shardlow/log.dpdrx-shardlow.reference index 067708154a..b80e033eb9 100644 --- a/examples/USER/dpd/dpdrx-shardlow/log.dpdrx-shardlow.reference +++ b/examples/USER/dpd/dpdrx-shardlow/log.dpdrx-shardlow.reference @@ -48,7 +48,7 @@ timestep 0.001 pair_style hybrid/overlay dpd/fdt/energy 16.00 234324 exp6/rx 16.00 pair_coeff * * dpd/fdt/energy 0.0 0.05 10.0 16.00 -pair_coeff * * exp6/rx params.exp6 1fluid 1fluid 1.0 1.0 16.00 +pair_coeff * * exp6/rx params.exp6 1fluid 1fluid exponent 1.0 1.0 16.00 fix 1 all shardlow fix 2 all nve @@ -69,39 +69,51 @@ dump_modify 2 sort id run 10 Neighbor list info ... - 2 neighbor list requests update every 1 steps, delay 10 steps, check yes max neighbors/atom: 2000, page size: 100000 master list distance cutoff = 18 ghost atom cutoff = 18 - binsize = 9 -> bins = 8 8 5 -Memory usage per processor = 6.52436 Mbytes + binsize = 9, bins = 8 8 5 + 3 neighbor lists, perpetual/occasional/extra = 3 0 0 + (1) pair dpd/fdt/energy, perpetual + pair build: half/bin/newton + stencil: half/bin/3d/newton + bin: standard + (2) pair exp6/rx, perpetual, copy from (1) + pair build: copy + stencil: none + bin: none + (3) fix shardlow, perpetual, ssa + pair build: half/bin/newton/ssa + stencil: half/bin/3d/newton/ssa + bin: ssa +Memory usage per processor = 8.39564 Mbytes Step Temp Press Volume PotEng KinEng c_dpdU[1] c_dpdU[2] c_dpdU[3] v_totEnergy c_dpdU[4] - 0 2065.00000000 1368.17463335 179834.51777865 0.00000000 230.35385810 3841.42393279 3841.42393279 0.00000000 7682.84786557 2065.00000000 - 1 2064.93210437 1368.12964881 179834.51777865 0.00000000 230.34628424 3841.42393279 3841.43150665 0.00000000 7682.85543943 2065.20275230 - 2 2067.82089565 1370.04362990 179834.51777865 -0.00000000 230.66853326 3841.42393279 3841.10925763 0.00000000 7682.53319042 2065.32453473 - 3 2070.45225169 1371.78704616 179834.51777865 -0.00000000 230.96206499 3841.42393279 3840.81572590 0.00000000 7682.23965869 2065.45336917 - 4 2075.00241157 1374.80177416 179834.51777865 -0.00000000 231.46964217 3841.42393279 3840.30814872 0.00000000 7681.73208151 2065.52973333 - 5 2073.96509212 1374.11449370 179834.51777865 -0.00000000 231.35392762 3841.42393279 3840.42386327 0.00000000 7681.84779605 2065.76011517 - 6 2074.26516936 1374.31331117 179834.51777865 -0.00000000 231.38740169 3841.42393279 3840.39038920 0.00000000 7681.81432198 2065.95399323 - 7 2071.41069700 1372.42206822 179834.51777865 -0.00000000 231.06898100 3841.42393279 3840.70880989 0.00000000 7682.13274267 2066.23407076 - 8 2071.35844957 1372.38745146 179834.51777865 -0.00000000 231.06315272 3841.42393279 3840.71463817 0.00000000 7682.13857095 2066.43766287 - 9 2071.35676496 1372.38633532 179834.51777865 -0.00000000 231.06296480 3841.42393279 3840.71482609 0.00000000 7682.13875887 2066.64001166 - 10 2066.53172340 1369.18948328 179834.51777865 -0.00000000 230.52472415 3841.42393279 3841.25306673 0.00000000 7682.67699952 2066.97516855 -Loop time of 0.289778 on 1 procs for 10 steps with 864 atoms + 0 2065.00000000 1368.17463335 179834.51777865 0.00000000 230.35385810 0.00000000 7682.84786557 0.00000000 7682.84786557 2065.00000000 + 1 2064.93210437 1368.12964881 179834.51777865 0.00000000 230.34628424 0.00000000 7682.85543943 0.00000000 7682.85543943 2065.20275230 + 2 2067.82089565 1370.04362990 179834.51777865 -0.00000000 230.66853326 0.00000000 7682.53319042 0.00000000 7682.53319042 2065.32453473 + 3 2070.45225169 1371.78704616 179834.51777865 -0.00000000 230.96206499 0.00000000 7682.23965869 0.00000000 7682.23965869 2065.45336917 + 4 2075.00241157 1374.80177416 179834.51777865 -0.00000000 231.46964217 0.00000000 7681.73208151 0.00000000 7681.73208151 2065.52973333 + 5 2073.96509212 1374.11449370 179834.51777865 -0.00000000 231.35392762 -0.00000000 7681.84779605 0.00000000 7681.84779605 2065.76011517 + 6 2074.26516936 1374.31331117 179834.51777865 -0.00000000 231.38740169 -0.00000000 7681.81432198 0.00000000 7681.81432198 2065.95399323 + 7 2071.41069700 1372.42206822 179834.51777865 -0.00000000 231.06898100 -0.00000000 7682.13274267 0.00000000 7682.13274267 2066.23407076 + 8 2071.35844957 1372.38745146 179834.51777865 -0.00000000 231.06315272 0.00000000 7682.13857095 0.00000000 7682.13857095 2066.43766287 + 9 2071.35676496 1372.38633532 179834.51777865 -0.00000000 231.06296480 0.00000000 7682.13875887 0.00000000 7682.13875887 2066.64001166 + 10 2066.53172340 1369.18948328 179834.51777865 -0.00000000 230.52472415 0.00000000 7682.67699952 0.00000000 7682.67699952 2066.97516855 +Loop time of 0.611304 on 1 procs for 10 steps with 864 atoms -Performance: 2.982 ns/day, 8.049 hours/ns, 34.509 timesteps/s -99.4% CPU use with 1 MPI tasks x no OpenMP threads +Performance: 1.413 ns/day, 16.981 hours/ns, 16.358 timesteps/s +98.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.16405 | 0.16405 | 0.16405 | 0.0 | 56.61 +Pair | 0.34177 | 0.34177 | 0.34177 | 0.0 | 55.91 Neigh | 0 | 0 | 0 | 0.0 | 0.00 -Comm | 0.00066328 | 0.00066328 | 0.00066328 | 0.0 | 0.23 -Output | 0.037718 | 0.037718 | 0.037718 | 0.0 | 13.02 -Modify | 0.087281 | 0.087281 | 0.087281 | 0.0 | 30.12 -Other | | 7.057e-05 | | | 0.02 +Comm | 0.0013342 | 0.0013342 | 0.0013342 | 0.0 | 0.22 +Output | 0.083583 | 0.083583 | 0.083583 | 0.0 | 13.67 +Modify | 0.18451 | 0.18451 | 0.18451 | 0.0 | 30.18 +Other | | 0.0001087 | | | 0.02 Nlocal: 864 ave 864 max 864 min Histogram: 1 0 0 0 0 0 0 0 0 0 diff --git a/src/KOKKOS/pair_exp6_rx_kokkos.cpp b/src/KOKKOS/pair_exp6_rx_kokkos.cpp index 559948067d..ce3b547435 100644 --- a/src/KOKKOS/pair_exp6_rx_kokkos.cpp +++ b/src/KOKKOS/pair_exp6_rx_kokkos.cpp @@ -936,32 +936,32 @@ void PairExp6rxKokkos::getParamsEXP6(int id,double &epsilon1,double // Fuchslin-Like Exp-6 Scaling double powfuch = 0.0; - if(fuchslinEpsilon < 0.0){ - powfuch = pow(nTotalOFA,-fuchslinEpsilon); + if(exponentEpsilon < 0.0){ + powfuch = pow(nTotalOFA,-exponentEpsilon); if(powfuch<1e-15) epsilon1 = 0.0; else epsilon1 *= 1.0/powfuch; - powfuch = pow(nTotalOFA_old,-fuchslinEpsilon); + powfuch = pow(nTotalOFA_old,-exponentEpsilon); if(powfuch<1e-15) epsilon1_old = 0.0; else epsilon1_old *= 1.0/powfuch; } else { - epsilon1 *= pow(nTotalOFA,fuchslinEpsilon); - epsilon1_old *= pow(nTotalOFA_old,fuchslinEpsilon); + epsilon1 *= pow(nTotalOFA,exponentEpsilon); + epsilon1_old *= pow(nTotalOFA_old,exponentEpsilon); } - if(fuchslinR < 0.0){ - powfuch = pow(nTotalOFA,-fuchslinR); + if(exponentR < 0.0){ + powfuch = pow(nTotalOFA,-exponentR); if(powfuch<1e-15) rm1 = 0.0; else rm1 *= 1.0/powfuch; - powfuch = pow(nTotalOFA_old,-fuchslinR); + powfuch = pow(nTotalOFA_old,-exponentR); if(powfuch<1e-15) rm1_old = 0.0; else rm1_old *= 1.0/powfuch; } else { - rm1 *= pow(nTotalOFA,fuchslinR); - rm1_old *= pow(nTotalOFA_old,fuchslinR); + rm1 *= pow(nTotalOFA,exponentR); + rm1_old *= pow(nTotalOFA_old,exponentR); } } @@ -990,32 +990,32 @@ void PairExp6rxKokkos::getParamsEXP6(int id,double &epsilon1,double // Fuchslin-Like Exp-6 Scaling double powfuch = 0.0; - if(fuchslinEpsilon < 0.0){ - powfuch = pow(nTotalOFA,-fuchslinEpsilon); + if(exponentEpsilon < 0.0){ + powfuch = pow(nTotalOFA,-exponentEpsilon); if(powfuch<1e-15) epsilon2 = 0.0; else epsilon2 *= 1.0/powfuch; - powfuch = pow(nTotalOFA_old,-fuchslinEpsilon); + powfuch = pow(nTotalOFA_old,-exponentEpsilon); if(powfuch<1e-15) epsilon2_old = 0.0; else epsilon2_old *= 1.0/powfuch; } else { - epsilon2 *= pow(nTotalOFA,fuchslinEpsilon); - epsilon2_old *= pow(nTotalOFA_old,fuchslinEpsilon); + epsilon2 *= pow(nTotalOFA,exponentEpsilon); + epsilon2_old *= pow(nTotalOFA_old,exponentEpsilon); } - if(fuchslinR < 0.0){ - powfuch = pow(nTotalOFA,-fuchslinR); + if(exponentR < 0.0){ + powfuch = pow(nTotalOFA,-exponentR); if(powfuch<1e-15) rm2 = 0.0; else rm2 *= 1.0/powfuch; - powfuch = pow(nTotalOFA_old,-fuchslinR); + powfuch = pow(nTotalOFA_old,-exponentR); if(powfuch<1e-15) rm2_old = 0.0; else rm2_old *= 1.0/powfuch; } else { - rm2 *= pow(nTotalOFA,fuchslinR); - rm2_old *= pow(nTotalOFA_old,fuchslinR); + rm2 *= pow(nTotalOFA,exponentR); + rm2_old *= pow(nTotalOFA_old,exponentR); } } diff --git a/src/USER-DPD/fix_eos_table_rx.cpp b/src/USER-DPD/fix_eos_table_rx.cpp index 91ccc8475e..52b1930c1c 100644 --- a/src/USER-DPD/fix_eos_table_rx.cpp +++ b/src/USER-DPD/fix_eos_table_rx.cpp @@ -28,6 +28,12 @@ #define MAXLINE 1024 +#ifdef DBL_EPSILON + #define MY_EPSILON (10.0*DBL_EPSILON) +#else + #define MY_EPSILON (10.0*2.220446049250313e-16) +#endif + using namespace LAMMPS_NS; using namespace FixConst; @@ -37,17 +43,18 @@ FixEOStableRX::FixEOStableRX(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg), ntables(0), tables(NULL), tables2(NULL), dHf(NULL), eosSpecies(NULL) { - if (narg != 8) error->all(FLERR,"Illegal fix eos/table/rx command"); + if (narg != 8 && narg != 10) error->all(FLERR,"Illegal fix eos/table/rx command"); restart_peratom = 1; nevery = 1; - bool rx_flag = false; + rx_flag = false; + nspecies = 1; for (int i = 0; i < modify->nfix; i++) - if (strncmp(modify->fix[i]->style,"rx",2) == 0) rx_flag = true; - if (!rx_flag) error->all(FLERR,"FixEOStableRX requires a fix rx command."); - - nspecies = atom->nspecies_dpd; - if(nspecies==0) error->all(FLERR,"There are no rx species specified."); + if (strncmp(modify->fix[i]->style,"rx",2) == 0){ + rx_flag = true; + nspecies = atom->nspecies_dpd; + if(nspecies==0) error->all(FLERR,"There are no rx species specified."); + } if (strcmp(arg[3],"linear") == 0) tabstyle = LINEAR; else error->all(FLERR,"Unknown table style in fix eos/table/rx"); @@ -113,8 +120,25 @@ FixEOStableRX::FixEOStableRX(LAMMPS *lmp, int narg, char **arg) : ntables++; } - // Read the Formation Enthalpies - read_file(arg[7]); + // Read the Formation Enthalpies and Correction Coefficients + dHf = new double[nspecies]; + energyCorr = new double[nspecies]; + tempCorrCoeff = new double[nspecies]; + moleculeCorrCoeff= new double[nspecies]; + for (int ii=0; iime == 0) { ptr = fgets(&line[n],MAXLINE-n,fp); @@ -332,7 +358,7 @@ void FixEOStableRX::read_file(char *file) nwords = atom->count_words(line); } - if (nwords != params_per_line) + if (nwords != min_params_per_line && nwords != max_params_per_line) error->all(FLERR,"Incorrect format in eos table/rx potential file"); // words = ptrs to all words in line @@ -344,8 +370,14 @@ void FixEOStableRX::read_file(char *file) for (ispecies = 0; ispecies < nspecies; ispecies++) if (strcmp(words[0],&atom->dname[ispecies][0]) == 0) break; - if (ispecies < nspecies) + if (ispecies < nspecies){ dHf[ispecies] = atof(words[1]); + if(nwords > min_params_per_line+1){ + energyCorr[ispecies] = atof(words[2]); + tempCorrCoeff[ispecies] = atof(words[3]); + moleculeCorrCoeff[ispecies] = atof(words[4]); + } + } } delete [] words; @@ -547,27 +579,33 @@ void FixEOStableRX::param_extract(Table *tb, char *line) error->one(FLERR,"Invalid keyword in fix eos/table/rx parameters"); word = strtok(NULL," \t\n\r\f"); - while (word) { - for (ispecies = 0; ispecies < nspecies; ispecies++) - if (strcmp(word,&atom->dname[ispecies][0]) == 0){ - eosSpecies[ncolumn] = ispecies; - ncolumn++; - break; + if(rx_flag){ + while (word) { + for (ispecies = 0; ispecies < nspecies; ispecies++) + if (strcmp(word,&atom->dname[ispecies][0]) == 0){ + eosSpecies[ncolumn] = ispecies; + ncolumn++; + break; + } + if (ispecies == nspecies){ + printf("name=%s not found in species list\n",word); + error->one(FLERR,"Invalid keyword in fix eos/table/rx parameters"); } - if (ispecies == nspecies){ - printf("name=%s not found in species list\n",word); - error->one(FLERR,"Invalid keyword in fix eos/table/rx parameters"); + word = strtok(NULL," \t\n\r\f"); } - word = strtok(NULL," \t\n\r\f"); + + for (int icolumn = 0; icolumn < ncolumn; icolumn++) + if(eosSpecies[icolumn]==-1) + error->one(FLERR,"EOS data is missing from fix eos/table/rx tabe"); + if(ncolumn != nspecies){ + printf("ncolumns=%d nspecies=%d\n",ncolumn,nspecies); + error->one(FLERR,"The number of columns in fix eos/table/rx does not match the number of species"); + } + } else { + eosSpecies[0] = 0; + ncolumn++; } - for (int icolumn = 0; icolumn < ncolumn; icolumn++) - if(eosSpecies[icolumn]==-1) - error->one(FLERR,"EOS data is missing from fix eos/table/rx tabe"); - if(ncolumn != nspecies){ - printf("ncolumns=%d nspecies=%d\n",ncolumn,nspecies); - error->one(FLERR,"The number of columns in fix eos/table/rx does not match the number of species"); - } if (tb->ninput == 0) error->one(FLERR,"fix eos/table/rx parameters did not set N"); } @@ -655,11 +693,27 @@ double FixEOStableRX::splint(double *xa, double *ya, double *y2a, int n, double void FixEOStableRX::energy_lookup(int id, double thetai, double &ui) { - int itable; - double fraction, uTmp, nTotal; + int itable, nPG; + double fraction, uTmp, nMolecules, nTotal, nTotalPG; + double tolerance = 1.0e-10; ui = 0.0; nTotal = 0.0; + nTotalPG = 0.0; + nPG = 0; + + if(rx_flag){ + for(int ispecies=0;ispeciesdvector[ispecies][id]; + if(fabs(moleculeCorrCoeff[ispecies]) > tolerance){ + nPG++; + nTotalPG += atom->dvector[ispecies][id]; + } + } + } else { + nTotal = 1.0; + } + for(int ispecies=0;ispecieslo); @@ -671,9 +725,13 @@ void FixEOStableRX::energy_lookup(int id, double thetai, double &ui) uTmp = tb->e[itable] + fraction*tb->de[itable]; uTmp += dHf[ispecies]; - // mol fraction form: - ui += atom->dvector[ispecies][id]*uTmp; - nTotal += atom->dvector[ispecies][id]; + uTmp += tempCorrCoeff[ispecies]*thetai; // temperature correction + uTmp += energyCorr[ispecies]; // energy correction + if(nPG > 0) ui += moleculeCorrCoeff[ispecies]*nTotalPG/double(nPG); // molecule correction + + if(rx_flag) nMolecules = atom->dvector[ispecies][id]; + else nMolecules = 1.0; + ui += nMolecules*uTmp; } } ui = ui - double(nTotal+1.5)*force->boltz*thetai; @@ -692,6 +750,7 @@ void FixEOStableRX::temperature_lookup(int id, double ui, double &thetai) double maxit = 100; double temp; double delta = 0.001; + double tolerance = 1.0e-10; // Store the current thetai in t1 t1 = MAX(thetai,tb->lo); @@ -715,7 +774,7 @@ void FixEOStableRX::temperature_lookup(int id, double ui, double &thetai) // Apply the Secant Method for(it=0; itone(FLERR,"NaN detected in secant solver."); temp = t1; temp = MAX(temp,tb->lo); @@ -726,7 +785,7 @@ void FixEOStableRX::temperature_lookup(int id, double ui, double &thetai) break; } temp = t2 - f2*(t2-t1)/(f2-f1); - if(fabs(temp-t2) < 1e-6) break; + if(fabs(temp-t2) < tolerance) break; f1 = f2; t1 = t2; t2 = temp; diff --git a/src/USER-DPD/fix_eos_table_rx.h b/src/USER-DPD/fix_eos_table_rx.h index 078cf1e2e1..8c26d133a5 100644 --- a/src/USER-DPD/fix_eos_table_rx.h +++ b/src/USER-DPD/fix_eos_table_rx.h @@ -67,7 +67,7 @@ class FixEOStableRX : public Fix { void read_file(char *); - double *dHf; + double *dHf,*energyCorr,*tempCorrCoeff,*moleculeCorrCoeff; int pack_reverse_comm(int, int, double *); void unpack_reverse_comm(int, int *, double *); @@ -76,6 +76,7 @@ class FixEOStableRX : public Fix { int *eosSpecies; int ncolumn; + bool rx_flag; }; } diff --git a/src/USER-DPD/fix_rx.cpp b/src/USER-DPD/fix_rx.cpp index 0bd560b241..b7330ba1ef 100644 --- a/src/USER-DPD/fix_rx.cpp +++ b/src/USER-DPD/fix_rx.cpp @@ -45,6 +45,12 @@ enum{LUCY}; #define MAXLINE 1024 #define DELTA 4 +#ifdef DBL_EPSILON + #define MY_EPSILON (10.0*DBL_EPSILON) +#else + #define MY_EPSILON (10.0*2.220446049250313e-16) +#endif + #define SparseKinetics_enableIntegralReactions (true) #define SparseKinetics_invalidIndex (-1) @@ -693,7 +699,6 @@ void FixRX::pre_force(int vflag) int *mask = atom->mask; double *dpdTheta = atom->dpdTheta; int newton_pair = force->newton_pair; - int ii; double theta; if(localTempFlag){ @@ -996,9 +1001,9 @@ void FixRX::rk4(int id, double *rwork) // Store the solution back in atom->dvector. for (int ispecies = 0; ispecies < nspecies; ispecies++){ - if(y[ispecies] < -1.0e-10) - error->one(FLERR,"Computed concentration in RK4 solver is < -1.0e-10"); - else if(y[ispecies] < 1e-15) + if(y[ispecies] < -MY_EPSILON) + error->one(FLERR,"Computed concentration in RK4 solver is < -10*DBL_EPSILON"); + else if(y[ispecies] < MY_EPSILON) y[ispecies] = 0.0; atom->dvector[ispecies][id] = y[ispecies]; } @@ -1515,7 +1520,7 @@ void FixRX::rkf45(int id, double *rwork) for (int ispecies = 0; ispecies < nspecies; ispecies++){ if(y[ispecies] < -1.0e-10) error->one(FLERR,"Computed concentration in RKF45 solver is < -1.0e-10"); - else if(y[ispecies] < 1e-20) + else if(y[ispecies] < MY_EPSILON) y[ispecies] = 0.0; atom->dvector[ispecies][id] = y[ispecies]; } diff --git a/src/USER-DPD/pair_exp6_rx.cpp b/src/USER-DPD/pair_exp6_rx.cpp index 202e0bf654..87a283179c 100644 --- a/src/USER-DPD/pair_exp6_rx.cpp +++ b/src/USER-DPD/pair_exp6_rx.cpp @@ -35,6 +35,12 @@ using namespace MathSpecial; #define MAXLINE 1024 #define DELTA 4 +#ifdef DBL_EPSILON + #define MY_EPSILON (10.0*DBL_EPSILON) +#else + #define MY_EPSILON (10.0*2.220446049250313e-16) +#endif + #define oneFluidApproxParameter (-1) #define isOneFluidApprox(_site) ( (_site) == oneFluidApproxParameter ) @@ -47,17 +53,17 @@ using namespace MathSpecial; struct PairExp6ParamDataType { int n; - double *epsilon1, *alpha1, *rm1, *fraction1, - *epsilon2, *alpha2, *rm2, *fraction2, - *epsilonOld1, *alphaOld1, *rmOld1, *fractionOld1, - *epsilonOld2, *alphaOld2, *rmOld2, *fractionOld2; + double *epsilon1, *alpha1, *rm1, *mixWtSite1, + *epsilon2, *alpha2, *rm2, *mixWtSite2, + *epsilonOld1, *alphaOld1, *rmOld1, *mixWtSite1old, + *epsilonOld2, *alphaOld2, *rmOld2, *mixWtSite2old; // Default constructor -- nullify everything. PairExp6ParamDataType(void) - : n(0), epsilon1(NULL), alpha1(NULL), rm1(NULL), fraction1(NULL), - epsilon2(NULL), alpha2(NULL), rm2(NULL), fraction2(NULL), - epsilonOld1(NULL), alphaOld1(NULL), rmOld1(NULL), fractionOld1(NULL), - epsilonOld2(NULL), alphaOld2(NULL), rmOld2(NULL), fractionOld2(NULL) + : n(0), epsilon1(NULL), alpha1(NULL), rm1(NULL), mixWtSite1(NULL), + epsilon2(NULL), alpha2(NULL), rm2(NULL), mixWtSite2(NULL), + epsilonOld1(NULL), alphaOld1(NULL), rmOld1(NULL), mixWtSite1old(NULL), + epsilonOld2(NULL), alphaOld2(NULL), rmOld2(NULL), mixWtSite2old(NULL) {} }; @@ -71,6 +77,7 @@ PairExp6rx::PairExp6rx(LAMMPS *lmp) : Pair(lmp) nparams = maxparam = 0; params = NULL; mol2param = NULL; + fractionalWeighting = true; } /* ---------------------------------------------------------------------- */ @@ -93,6 +100,11 @@ PairExp6rx::~PairExp6rx() memory->destroy(cutsq); memory->destroy(cut); } + if(scalingFlag == POLYNOMIAL){ + memory->destroy(coeffAlpha); + memory->destroy(coeffEps); + memory->destroy(coeffRm); + } } /* ---------------------------------------------------------------------- */ @@ -134,10 +146,10 @@ void PairExp6rx::compute(int eflag, int vflag) double epsilon2_j,alpha2_j,rm2_j; double evdwlOldEXP6_12, evdwlOldEXP6_21, fpairOldEXP6_12, fpairOldEXP6_21; double evdwlEXP6_12, evdwlEXP6_21; - double fractionOld1_i, fractionOld1_j; - double fractionOld2_i, fractionOld2_j; - double fraction1_i, fraction1_j; - double fraction2_i, fraction2_j; + double mixWtSite1old_i, mixWtSite1old_j; + double mixWtSite2old_i, mixWtSite2old_j; + double mixWtSite1_i, mixWtSite1_j; + double mixWtSite2_i, mixWtSite2_j; double *uCG = atom->uCG; double *uCGnew = atom->uCGnew; @@ -157,38 +169,38 @@ void PairExp6rx::compute(int eflag, int vflag) memory->create( PairExp6ParamData.epsilon1 , np_total, "PairExp6ParamData.epsilon1"); memory->create( PairExp6ParamData.alpha1 , np_total, "PairExp6ParamData.alpha1"); memory->create( PairExp6ParamData.rm1 , np_total, "PairExp6ParamData.rm1"); - memory->create( PairExp6ParamData.fraction1 , np_total, "PairExp6ParamData.fraction1"); + memory->create( PairExp6ParamData.mixWtSite1 , np_total, "PairExp6ParamData.mixWtSite1"); memory->create( PairExp6ParamData.epsilon2 , np_total, "PairExp6ParamData.epsilon2"); memory->create( PairExp6ParamData.alpha2 , np_total, "PairExp6ParamData.alpha2"); memory->create( PairExp6ParamData.rm2 , np_total, "PairExp6ParamData.rm2"); - memory->create( PairExp6ParamData.fraction2 , np_total, "PairExp6ParamData.fraction2"); + memory->create( PairExp6ParamData.mixWtSite2 , np_total, "PairExp6ParamData.mixWtSite2"); memory->create( PairExp6ParamData.epsilonOld1 , np_total, "PairExp6ParamData.epsilonOld1"); memory->create( PairExp6ParamData.alphaOld1 , np_total, "PairExp6ParamData.alphaOld1"); memory->create( PairExp6ParamData.rmOld1 , np_total, "PairExp6ParamData.rmOld1"); - memory->create( PairExp6ParamData.fractionOld1 , np_total, "PairExp6ParamData.fractionOld1"); + memory->create( PairExp6ParamData.mixWtSite1old , np_total, "PairExp6ParamData.mixWtSite1old"); memory->create( PairExp6ParamData.epsilonOld2 , np_total, "PairExp6ParamData.epsilonOld2"); memory->create( PairExp6ParamData.alphaOld2 , np_total, "PairExp6ParamData.alphaOld2"); memory->create( PairExp6ParamData.rmOld2 , np_total, "PairExp6ParamData.rmOld2"); - memory->create( PairExp6ParamData.fractionOld2 , np_total, "PairExp6ParamData.fractionOld2"); + memory->create( PairExp6ParamData.mixWtSite2old , np_total, "PairExp6ParamData.mixWtSite2old"); for (i = 0; i < np_total; ++i) { - getParamsEXP6 (i, PairExp6ParamData.epsilon1[i], + getMixingWeights (i, PairExp6ParamData.epsilon1[i], PairExp6ParamData.alpha1[i], PairExp6ParamData.rm1[i], - PairExp6ParamData.fraction1[i], + PairExp6ParamData.mixWtSite1[i], PairExp6ParamData.epsilon2[i], PairExp6ParamData.alpha2[i], PairExp6ParamData.rm2[i], - PairExp6ParamData.fraction2[i], + PairExp6ParamData.mixWtSite2[i], PairExp6ParamData.epsilonOld1[i], PairExp6ParamData.alphaOld1[i], PairExp6ParamData.rmOld1[i], - PairExp6ParamData.fractionOld1[i], + PairExp6ParamData.mixWtSite1old[i], PairExp6ParamData.epsilonOld2[i], PairExp6ParamData.alphaOld2[i], PairExp6ParamData.rmOld2[i], - PairExp6ParamData.fractionOld2[i]); + PairExp6ParamData.mixWtSite2old[i]); } } @@ -212,19 +224,19 @@ void PairExp6rx::compute(int eflag, int vflag) epsilon1_i = PairExp6ParamData.epsilon1[i]; alpha1_i = PairExp6ParamData.alpha1[i]; rm1_i = PairExp6ParamData.rm1[i]; - fraction1_i = PairExp6ParamData.fraction1[i]; + mixWtSite1_i = PairExp6ParamData.mixWtSite1[i]; epsilon2_i = PairExp6ParamData.epsilon2[i]; alpha2_i = PairExp6ParamData.alpha2[i]; rm2_i = PairExp6ParamData.rm2[i]; - fraction2_i = PairExp6ParamData.fraction2[i]; + mixWtSite2_i = PairExp6ParamData.mixWtSite2[i]; epsilonOld1_i = PairExp6ParamData.epsilonOld1[i]; alphaOld1_i = PairExp6ParamData.alphaOld1[i]; rmOld1_i = PairExp6ParamData.rmOld1[i]; - fractionOld1_i = PairExp6ParamData.fractionOld1[i]; + mixWtSite1old_i = PairExp6ParamData.mixWtSite1old[i]; epsilonOld2_i = PairExp6ParamData.epsilonOld2[i]; alphaOld2_i = PairExp6ParamData.alphaOld2[i]; rmOld2_i = PairExp6ParamData.rmOld2[i]; - fractionOld2_i = PairExp6ParamData.fractionOld2[i]; + mixWtSite2old_i = PairExp6ParamData.mixWtSite2old[i]; } for (jj = 0; jj < jnum; jj++) { @@ -259,19 +271,19 @@ void PairExp6rx::compute(int eflag, int vflag) epsilon1_j = PairExp6ParamData.epsilon1[j]; alpha1_j = PairExp6ParamData.alpha1[j]; rm1_j = PairExp6ParamData.rm1[j]; - fraction1_j = PairExp6ParamData.fraction1[j]; + mixWtSite1_j = PairExp6ParamData.mixWtSite1[j]; epsilon2_j = PairExp6ParamData.epsilon2[j]; alpha2_j = PairExp6ParamData.alpha2[j]; rm2_j = PairExp6ParamData.rm2[j]; - fraction2_j = PairExp6ParamData.fraction2[j]; + mixWtSite2_j = PairExp6ParamData.mixWtSite2[j]; epsilonOld1_j = PairExp6ParamData.epsilonOld1[j]; alphaOld1_j = PairExp6ParamData.alphaOld1[j]; rmOld1_j = PairExp6ParamData.rmOld1[j]; - fractionOld1_j = PairExp6ParamData.fractionOld1[j]; + mixWtSite1old_j = PairExp6ParamData.mixWtSite1old[j]; epsilonOld2_j = PairExp6ParamData.epsilonOld2[j]; alphaOld2_j = PairExp6ParamData.alphaOld2[j]; rmOld2_j = PairExp6ParamData.rmOld2[j]; - fractionOld2_j = PairExp6ParamData.fractionOld2[j]; + mixWtSite2old_j = PairExp6ParamData.mixWtSite2old[j]; } // A2. Apply Lorentz-Berthelot mixing rules for the i-j pair @@ -372,9 +384,9 @@ void PairExp6rx::compute(int eflag, int vflag) } if (isite1 == isite2) - evdwlOld = sqrt(fractionOld1_i*fractionOld2_j)*evdwlOldEXP6_12; + evdwlOld = sqrt(mixWtSite1old_i*mixWtSite2old_j)*evdwlOldEXP6_12; else - evdwlOld = sqrt(fractionOld1_i*fractionOld2_j)*evdwlOldEXP6_12 + sqrt(fractionOld2_i*fractionOld1_j)*evdwlOldEXP6_21; + evdwlOld = sqrt(mixWtSite1old_i*mixWtSite2old_j)*evdwlOldEXP6_12 + sqrt(mixWtSite2old_i*mixWtSite1old_j)*evdwlOldEXP6_21; evdwlOld *= factor_lj; @@ -455,8 +467,8 @@ void PairExp6rx::compute(int eflag, int vflag) // // Apply Mixing Rule to get the overall force for the CG pair // - if (isite1 == isite2) fpair = sqrt(fractionOld1_i*fractionOld2_j)*fpairOldEXP6_12; - else fpair = sqrt(fractionOld1_i*fractionOld2_j)*fpairOldEXP6_12 + sqrt(fractionOld2_i*fractionOld1_j)*fpairOldEXP6_21; + if (isite1 == isite2) fpair = sqrt(mixWtSite1old_i*mixWtSite2old_j)*fpairOldEXP6_12; + else fpair = sqrt(mixWtSite1old_i*mixWtSite2old_j)*fpairOldEXP6_12 + sqrt(mixWtSite2old_i*mixWtSite1old_j)*fpairOldEXP6_21; f[i][0] += delx*fpair; f[i][1] += dely*fpair; @@ -467,8 +479,8 @@ void PairExp6rx::compute(int eflag, int vflag) f[j][2] -= delz*fpair; } - if (isite1 == isite2) evdwl = sqrt(fraction1_i*fraction2_j)*evdwlEXP6_12; - else evdwl = sqrt(fraction1_i*fraction2_j)*evdwlEXP6_12 + sqrt(fraction2_i*fraction1_j)*evdwlEXP6_21; + if (isite1 == isite2) evdwl = sqrt(mixWtSite1_i*mixWtSite2_j)*evdwlEXP6_12; + else evdwl = sqrt(mixWtSite1_i*mixWtSite2_j)*evdwlEXP6_12 + sqrt(mixWtSite2_i*mixWtSite1_j)*evdwlEXP6_21; evdwl *= factor_lj; uCGnew[i] += 0.5*evdwl; @@ -488,19 +500,19 @@ void PairExp6rx::compute(int eflag, int vflag) if (PairExp6ParamData.epsilon1 ) memory->destroy(PairExp6ParamData.epsilon1); if (PairExp6ParamData.alpha1 ) memory->destroy(PairExp6ParamData.alpha1); if (PairExp6ParamData.rm1 ) memory->destroy(PairExp6ParamData.rm1); - if (PairExp6ParamData.fraction1 ) memory->destroy(PairExp6ParamData.fraction1); + if (PairExp6ParamData.mixWtSite1 ) memory->destroy(PairExp6ParamData.mixWtSite1); if (PairExp6ParamData.epsilon2 ) memory->destroy(PairExp6ParamData.epsilon2); if (PairExp6ParamData.alpha2 ) memory->destroy(PairExp6ParamData.alpha2); if (PairExp6ParamData.rm2 ) memory->destroy(PairExp6ParamData.rm2); - if (PairExp6ParamData.fraction2 ) memory->destroy(PairExp6ParamData.fraction2); + if (PairExp6ParamData.mixWtSite2 ) memory->destroy(PairExp6ParamData.mixWtSite2); if (PairExp6ParamData.epsilonOld1 ) memory->destroy(PairExp6ParamData.epsilonOld1); if (PairExp6ParamData.alphaOld1 ) memory->destroy(PairExp6ParamData.alphaOld1); if (PairExp6ParamData.rmOld1 ) memory->destroy(PairExp6ParamData.rmOld1); - if (PairExp6ParamData.fractionOld1) memory->destroy(PairExp6ParamData.fractionOld1); + if (PairExp6ParamData.mixWtSite1old) memory->destroy(PairExp6ParamData.mixWtSite1old); if (PairExp6ParamData.epsilonOld2 ) memory->destroy(PairExp6ParamData.epsilonOld2); if (PairExp6ParamData.alphaOld2 ) memory->destroy(PairExp6ParamData.alphaOld2); if (PairExp6ParamData.rmOld2 ) memory->destroy(PairExp6ParamData.rmOld2); - if (PairExp6ParamData.fractionOld2) memory->destroy(PairExp6ParamData.fractionOld2); + if (PairExp6ParamData.mixWtSite2old) memory->destroy(PairExp6ParamData.mixWtSite2old); } } @@ -530,10 +542,20 @@ void PairExp6rx::allocate() void PairExp6rx::settings(int narg, char **arg) { - if (narg != 1) error->all(FLERR,"Illegal pair_style command"); + if (narg < 1) error->all(FLERR,"Illegal pair_style command"); cut_global = force->numeric(FLERR,arg[0]); + // optional keywords + + int iarg = 1; + while (iarg < narg) { + if (strcmp(arg[iarg],"fractional") == 0) fractionalWeighting = true; + else if (strcmp(arg[iarg],"molecular") == 0) fractionalWeighting = false; + else error->all(FLERR,"Illegal pair_style command"); + iarg++; + } + if (allocated) { int i,j; for (i = 1; i <= atom->ntypes; i++) @@ -551,7 +573,7 @@ void PairExp6rx::settings(int narg, char **arg) void PairExp6rx::coeff(int narg, char **arg) { - if (narg < 7 || narg > 8) error->all(FLERR,"Incorrect args for pair coefficients"); + if (narg < 6 || narg > 9) error->all(FLERR,"Incorrect args for pair coefficients"); bool rx_flag = false; for (int i = 0; i < modify->nfix; i++) @@ -628,21 +650,36 @@ void PairExp6rx::coeff(int narg, char **arg) params[iparam].potentialType = exp6PotentialType; else error->all(FLERR,"params[].potential type unknown"); - - //printf("params[%d].name= %s ispecies= %d potential= %s potentialType= %d\n", iparam, params[iparam].name, params[iparam].ispecies, params[iparam].potential, params[iparam].potentialType); } } delete[] site1; delete[] site2; site1 = site2 = NULL; - fuchslinR = force->numeric(FLERR,arg[5]); - fuchslinEpsilon = force->numeric(FLERR,arg[6]); - setup(); double cut_one = cut_global; - if (narg == 8) cut_one = force->numeric(FLERR,arg[7]); + if (strcmp(arg[5],"exponent") == 0){ + scalingFlag = EXPONENT; + exponentR = force->numeric(FLERR,arg[6]); + exponentEpsilon = force->numeric(FLERR,arg[7]); + if (narg > 9) error->all(FLERR,"Incorrect args for pair coefficients"); + if (narg == 9) cut_one = force->numeric(FLERR,arg[8]); + } else if (strcmp(arg[5],"polynomial") == 0){ + scalingFlag = POLYNOMIAL; + memory->create(coeffAlpha,6,"pair:coeffAlpha"); + memory->create(coeffEps,6,"pair:coeffEps"); + memory->create(coeffRm,6,"pair:coeffRm"); + read_file2(arg[6]); + if (narg > 8) error->all(FLERR,"Incorrect args for pair coefficients"); + if (narg == 8) cut_one = force->numeric(FLERR,arg[7]); + } else if (strcmp(arg[5],"none") == 0){ + scalingFlag = NONE; + if (narg > 7) error->all(FLERR,"Incorrect args for pair coefficients"); + if (narg == 7) cut_one = force->numeric(FLERR,arg[6]); + } else { + error->all(FLERR,"Incorrect args for pair coefficients"); + } int count = 0; for (int i = ilo; i <= ihi; i++) { @@ -784,6 +821,95 @@ void PairExp6rx::read_file(char *file) /* ---------------------------------------------------------------------- */ +void PairExp6rx::read_file2(char *file) +{ + int params_per_line = 7; + char **words = new char*[params_per_line+1]; + + // open file on proc 0 + + FILE *fp; + fp = NULL; + if (comm->me == 0) { + fp = fopen(file,"r"); + if (fp == NULL) { + char str[128]; + sprintf(str,"Cannot open polynomial file %s",file); + error->one(FLERR,str); + } + } + + // one set of params can span multiple lines + int n,nwords; + char line[MAXLINE],*ptr; + int eof = 0; + + while (1) { + if (comm->me == 0) { + ptr = fgets(line,MAXLINE,fp); + if (ptr == NULL) { + eof = 1; + fclose(fp); + } else n = strlen(line) + 1; + } + MPI_Bcast(&eof,1,MPI_INT,0,world); + if (eof) break; + MPI_Bcast(&n,1,MPI_INT,0,world); + MPI_Bcast(line,n,MPI_CHAR,0,world); + + // strip comment, skip line if blank + + if ((ptr = strchr(line,'#'))) *ptr = '\0'; + nwords = atom->count_words(line); + if (nwords == 0) continue; + + // concatenate additional lines until have params_per_line words + + while (nwords < params_per_line) { + n = strlen(line); + if (comm->me == 0) { + ptr = fgets(&line[n],MAXLINE-n,fp); + if (ptr == NULL) { + eof = 1; + fclose(fp); + } else n = strlen(line) + 1; + } + MPI_Bcast(&eof,1,MPI_INT,0,world); + if (eof) break; + MPI_Bcast(&n,1,MPI_INT,0,world); + MPI_Bcast(line,n,MPI_CHAR,0,world); + if ((ptr = strchr(line,'#'))) *ptr = '\0'; + nwords = atom->count_words(line); + } + + if (nwords != params_per_line) + error->all(FLERR,"Incorrect format in polynomial file"); + + // words = ptrs to all words in line + + nwords = 0; + words[nwords++] = strtok(line," \t\n\r\f"); + while ((words[nwords++] = strtok(NULL," \t\n\r\f"))) continue; + + if (strcmp(words[0],"alpha") == 0){ + for (int ii=1; iidvector[ispecies][id]; - nTotal_old += atom->dvector[ispecies+nspecies][id]; + nTotalOld += atom->dvector[ispecies+nspecies][id]; iparam = mol2param[ispecies]; if (iparam < 0 || params[iparam].potentialType != exp6PotentialType ) continue; if (isOneFluidApprox(isite1) || isOneFluidApprox(isite2)) { if (isite1 == params[iparam].ispecies || isite2 == params[iparam].ispecies) continue; - nTotalOFA_old += atom->dvector[ispecies+nspecies][id]; - nTotalOFA += atom->dvector[ispecies][id]; + nMoleculesOFAold += atom->dvector[ispecies+nspecies][id]; + nMoleculesOFA += atom->dvector[ispecies][id]; } } - if(nTotal < 1e-8 || nTotal_old < 1e-8) - error->all(FLERR,"The number of molecules in CG particle is less than 1e-8."); + if(nTotal < MY_EPSILON || nTotalOld < MY_EPSILON) + error->all(FLERR,"The number of molecules in CG particle is less than 10*DBL_EPSILON."); // Compute the mole fraction of molecules within the fluid portion of the particle (One Fluid Approximation) - fractionOFA_old = nTotalOFA_old / nTotal_old; - fractionOFA = nTotalOFA / nTotal; + fractionOFAold = nMoleculesOFAold / nTotalOld; + fractionOFA = nMoleculesOFA / nTotal; for (int ispecies = 0; ispecies < nspecies; ispecies++) { iparam = mol2param[ispecies]; @@ -942,8 +1073,10 @@ void PairExp6rx::getParamsEXP6(int id,double &epsilon1,double &alpha1,double &rm alpha1 = params[iparam].alpha; // Compute the mole fraction of Site1 - fraction1_old = atom->dvector[ispecies+nspecies][id]/nTotal_old; - fraction1 = atom->dvector[ispecies][id]/nTotal; + nMoleculesOld1 = atom->dvector[ispecies+nspecies][id]; + nMolecules1 = atom->dvector[ispecies][id]; + fractionOld1 = nMoleculesOld1/nTotalOld; + fraction1 = nMolecules1/nTotal; } // If Site2 matches a pure species, then grab the parameters @@ -956,7 +1089,9 @@ void PairExp6rx::getParamsEXP6(int id,double &epsilon1,double &alpha1,double &rm alpha2 = params[iparam].alpha; // Compute the mole fraction of Site2 - fraction2_old = atom->dvector[ispecies+nspecies][id]/nTotal_old; + nMoleculesOld2 = atom->dvector[ispecies+nspecies][id]; + nMolecules2 = atom->dvector[ispecies][id]; + fractionOld2 = atom->dvector[ispecies+nspecies][id]/nTotalOld; fraction2 = atom->dvector[ispecies][id]/nTotal; } @@ -966,8 +1101,10 @@ void PairExp6rx::getParamsEXP6(int id,double &epsilon1,double &alpha1,double &rm rmi = params[iparam].rm; epsiloni = params[iparam].epsilon; alphai = params[iparam].alpha; - xMolei = atom->dvector[ispecies][id]/nTotalOFA; - xMolei_old = atom->dvector[ispecies+nspecies][id]/nTotalOFA_old; + if(nMoleculesOFAdvector[ispecies][id]/nMoleculesOFA; + if(nMoleculesOFAolddvector[ispecies+nspecies][id]/nMoleculesOFAold; for (int jspecies = 0; jspecies < nspecies; jspecies++) { jparam = mol2param[jspecies]; @@ -976,15 +1113,17 @@ void PairExp6rx::getParamsEXP6(int id,double &epsilon1,double &alpha1,double &rm rmj = params[jparam].rm; epsilonj = params[jparam].epsilon; alphaj = params[jparam].alpha; - xMolej = atom->dvector[jspecies][id]/nTotalOFA; - xMolej_old = atom->dvector[jspecies+nspecies][id]/nTotalOFA_old; + if(nMoleculesOFAdvector[jspecies][id]/nMoleculesOFA; + if(nMoleculesOFAolddvector[jspecies+nspecies][id]/nMoleculesOFAold; rmij = (rmi+rmj)/2.0; rm3ij = rmij*rmij*rmij; epsilonij = sqrt(epsiloni*epsilonj); alphaij = sqrt(alphai*alphaj); - if(fractionOFA_old > 0.0){ + if(fractionOFAold > 0.0){ rm3_old += xMolei_old*xMolej_old*rm3ij; epsilon_old += xMolei_old*xMolej_old*rm3ij*epsilonij; alpha_old += xMolei_old*xMolej_old*rm3ij*epsilonij*alphaij; @@ -1000,7 +1139,7 @@ void PairExp6rx::getParamsEXP6(int id,double &epsilon1,double &alpha1,double &rm if (isOneFluidApprox(isite1)){ rm1 = cbrt(rm3); - if(rm1 < 1e-16) { + if(rm1 < MY_EPSILON) { rm1 = 0.0; epsilon1 = 0.0; alpha1 = 0.0; @@ -1008,11 +1147,11 @@ void PairExp6rx::getParamsEXP6(int id,double &epsilon1,double &alpha1,double &rm epsilon1 = epsilon / rm3; alpha1 = alpha / epsilon1 / rm3; } - + nMolecules1 = 1.0-(nTotal-nMoleculesOFA); fraction1 = fractionOFA; rm1_old = cbrt(rm3_old); - if(rm1_old < 1e-16) { + if(rm1_old < MY_EPSILON) { rm1_old = 0.0; epsilon1_old = 0.0; alpha1_old = 0.0; @@ -1020,42 +1159,21 @@ void PairExp6rx::getParamsEXP6(int id,double &epsilon1,double &alpha1,double &rm epsilon1_old = epsilon_old / rm3_old; alpha1_old = alpha_old / epsilon1_old / rm3_old; } - fraction1_old = fractionOFA_old; + nMoleculesOld1 = 1.0-(nTotalOld-nMoleculesOFAold); + fractionOld1 = fractionOFAold; - // Fuchslin-Like Exp-6 Scaling - double powfuch = 0.0; - if(fuchslinEpsilon < 0.0){ - powfuch = pow(nTotalOFA,-fuchslinEpsilon); - if(powfuch<1e-15) epsilon1 = 0.0; - else epsilon1 *= 1.0/powfuch; - - powfuch = pow(nTotalOFA_old,-fuchslinEpsilon); - if(powfuch<1e-15) epsilon1_old = 0.0; - else epsilon1_old *= 1.0/powfuch; - - } else { - epsilon1 *= pow(nTotalOFA,fuchslinEpsilon); - epsilon1_old *= pow(nTotalOFA_old,fuchslinEpsilon); - } - - if(fuchslinR < 0.0){ - powfuch = pow(nTotalOFA,-fuchslinR); - if(powfuch<1e-15) rm1 = 0.0; - else rm1 *= 1.0/powfuch; - - powfuch = pow(nTotalOFA_old,-fuchslinR); - if(powfuch<1e-15) rm1_old = 0.0; - else rm1_old *= 1.0/powfuch; - - } else { - rm1 *= pow(nTotalOFA,fuchslinR); - rm1_old *= pow(nTotalOFA_old,fuchslinR); + if(scalingFlag == EXPONENT){ + exponentScaling(nMoleculesOFA,epsilon1,rm1); + exponentScaling(nMoleculesOFAold,epsilon1_old,rm1_old); + } else if(scalingFlag == POLYNOMIAL){ + polynomialScaling(nMoleculesOFA,alpha1,epsilon1,rm1); + polynomialScaling(nMoleculesOFAold,alpha1_old,epsilon1_old,rm1_old); } } if (isOneFluidApprox(isite2)){ rm2 = cbrt(rm3); - if(rm2 < 1e-16) { + if(rm2 < MY_EPSILON) { rm2 = 0.0; epsilon2 = 0.0; alpha2 = 0.0; @@ -1063,10 +1181,11 @@ void PairExp6rx::getParamsEXP6(int id,double &epsilon1,double &alpha1,double &rm epsilon2 = epsilon / rm3; alpha2 = alpha / epsilon2 / rm3; } + nMolecules2 = 1.0-(nTotal-nMoleculesOFA); fraction2 = fractionOFA; rm2_old = cbrt(rm3_old); - if(rm2_old < 1e-16) { + if(rm2_old < MY_EPSILON) { rm2_old = 0.0; epsilon2_old = 0.0; alpha2_old = 0.0; @@ -1074,64 +1193,96 @@ void PairExp6rx::getParamsEXP6(int id,double &epsilon1,double &alpha1,double &rm epsilon2_old = epsilon_old / rm3_old; alpha2_old = alpha_old / epsilon2_old / rm3_old; } - fraction2_old = fractionOFA_old; + nMoleculesOld2 = 1.0-(nTotalOld-nMoleculesOFAold); + fractionOld2 = fractionOFAold; - // Fuchslin-Like Exp-6 Scaling - double powfuch = 0.0; - if(fuchslinEpsilon < 0.0){ - powfuch = pow(nTotalOFA,-fuchslinEpsilon); - if(powfuch<1e-15) epsilon2 = 0.0; - else epsilon2 *= 1.0/powfuch; - - powfuch = pow(nTotalOFA_old,-fuchslinEpsilon); - if(powfuch<1e-15) epsilon2_old = 0.0; - else epsilon2_old *= 1.0/powfuch; - - } else { - epsilon2 *= pow(nTotalOFA,fuchslinEpsilon); - epsilon2_old *= pow(nTotalOFA_old,fuchslinEpsilon); - } - - if(fuchslinR < 0.0){ - powfuch = pow(nTotalOFA,-fuchslinR); - if(powfuch<1e-15) rm2 = 0.0; - else rm2 *= 1.0/powfuch; - - powfuch = pow(nTotalOFA_old,-fuchslinR); - if(powfuch<1e-15) rm2_old = 0.0; - else rm2_old *= 1.0/powfuch; - - } else { - rm2 *= pow(nTotalOFA,fuchslinR); - rm2_old *= pow(nTotalOFA_old,fuchslinR); + if(scalingFlag == EXPONENT){ + exponentScaling(nMoleculesOFA,epsilon2,rm2); + exponentScaling(nMoleculesOFAold,epsilon2_old,rm2_old); + } else if(scalingFlag == POLYNOMIAL){ + polynomialScaling(nMoleculesOFA,alpha2,epsilon2,rm2); + polynomialScaling(nMoleculesOFAold,alpha2_old,epsilon2_old,rm2_old); } } // Check that no fractions are less than zero - if(fraction1 < 0.0){ - if(fraction1 < -1.0e-10){ - error->all(FLERR,"Computed fraction less than -1.0e-10"); + if(fraction1 < 0.0 || nMolecules1 < 0.0){ + if(fraction1 < -MY_EPSILON || nMolecules1 < -MY_EPSILON){ + error->all(FLERR,"Computed fraction less than -10*DBL_EPSILON"); } + nMolecules1 = 0.0; fraction1 = 0.0; } - if(fraction2 < 0.0){ - if(fraction2 < -1.0e-10){ - error->all(FLERR,"Computed fraction less than -1.0e-10"); + if(fraction2 < 0.0 || nMolecules2 < 0.0){ + if(fraction2 < -MY_EPSILON || nMolecules2 < -MY_EPSILON){ + error->all(FLERR,"Computed fraction less than -10*DBL_EPSILON"); } + nMolecules2 = 0.0; fraction2 = 0.0; } - if(fraction1_old < 0.0){ - if(fraction1_old < -1.0e-10){ - error->all(FLERR,"Computed fraction less than -1.0e-10"); + if(fractionOld1 < 0.0 || nMoleculesOld1 < 0.0){ + if(fractionOld1 < -MY_EPSILON || nMoleculesOld1 < -MY_EPSILON){ + error->all(FLERR,"Computed fraction less than -10*DBL_EPSILON"); } - fraction1_old = 0.0; + nMoleculesOld1 = 0.0; + fractionOld1 = 0.0; } - if(fraction2_old < 0.0){ - if(fraction2_old < -1.0e-10){ - error->all(FLERR,"Computed fraction less than -1.0e-10"); + if(fractionOld2 < 0.0 || nMoleculesOld2 < 0.0){ + if(fractionOld2 < -MY_EPSILON || nMoleculesOld2 < -MY_EPSILON){ + error->all(FLERR,"Computed fraction less than -10*DBL_EPSILON"); } - fraction2_old = 0.0; + nMoleculesOld2 = 0.0; + fractionOld2 = 0.0; } + + if(fractionalWeighting){ + mixWtSite1old = fractionOld1; + mixWtSite1 = fraction1; + mixWtSite2old = fractionOld2; + mixWtSite2 = fraction2; + } else { + mixWtSite1old = nMoleculesOld1; + mixWtSite1 = nMolecules1; + mixWtSite2old = nMoleculesOld2; + mixWtSite2 = nMolecules2; + } +} + +/* ---------------------------------------------------------------------- */ + +void PairExp6rx::exponentScaling(double phi, double &epsilon, double &rm) const +{ + double powfuch; + + if(exponentEpsilon < 0.0){ + powfuch = pow(phi,-exponentEpsilon); + if(powfuchnghost; int newton_pair = force->newton_pair; - double fractionOld1_i,fractionOld1_j; - double fractionOld2_i,fractionOld2_j; - double fraction1_i; + double mixWtSite1old_i,mixWtSite1old_j; + double mixWtSite2old_i,mixWtSite2old_j; + double mixWtSite1_i; double *uCG = atom->uCG; double *uCGnew = atom->uCGnew; @@ -126,20 +133,20 @@ void PairMultiLucyRX::compute(int eflag, int vflag) int jtable; double *rho = atom->rho; - double *fractionOld1 = NULL; - double *fractionOld2 = NULL; - double *fraction1 = NULL; - double *fraction2 = NULL; + double *mixWtSite1old = NULL; + double *mixWtSite2old = NULL; + double *mixWtSite1 = NULL; + double *mixWtSite2 = NULL; { const int ntotal = nlocal + nghost; - memory->create(fractionOld1, ntotal, "PairMultiLucyRX::fractionOld1"); - memory->create(fractionOld2, ntotal, "PairMultiLucyRX::fractionOld2"); - memory->create(fraction1, ntotal, "PairMultiLucyRX::fraction1"); - memory->create(fraction2, ntotal, "PairMultiLucyRX::fraction2"); + memory->create(mixWtSite1old, ntotal, "PairMultiLucyRX::mixWtSite1old"); + memory->create(mixWtSite2old, ntotal, "PairMultiLucyRX::mixWtSite2old"); + memory->create(mixWtSite1, ntotal, "PairMultiLucyRX::mixWtSite1"); + memory->create(mixWtSite2, ntotal, "PairMultiLucyRX::mixWtSite2"); for (int i = 0; i < ntotal; ++i) - getParams(i, fractionOld1[i], fractionOld2[i], fraction1[i], fraction2[i]); + getMixingWeights(i, mixWtSite1old[i], mixWtSite2old[i], mixWtSite1[i], mixWtSite2[i]); } inum = list->inum; @@ -164,9 +171,9 @@ void PairMultiLucyRX::compute(int eflag, int vflag) double fy_i = 0.0; double fz_i = 0.0; - fractionOld1_i = fractionOld1[i]; - fractionOld2_i = fractionOld2[i]; - fraction1_i = fraction1[i]; + mixWtSite1old_i = mixWtSite1old[i]; + mixWtSite2old_i = mixWtSite2old[i]; + mixWtSite1_i = mixWtSite1[i]; for (jj = 0; jj < jnum; jj++) { j = jlist[jj]; @@ -181,8 +188,8 @@ void PairMultiLucyRX::compute(int eflag, int vflag) if (rsq < cutsq[itype][jtype]) { fpair = 0.0; - fractionOld1_j = fractionOld1[j]; - fractionOld2_j = fractionOld2[j]; + mixWtSite1old_j = mixWtSite1old[j]; + mixWtSite2old_j = mixWtSite2old[j]; tb = &tables[tabindex[itype][jtype]]; if (rho[i]*rho[i] < tb->innersq || rho[j]*rho[j] < tb->innersq){ @@ -237,8 +244,8 @@ void PairMultiLucyRX::compute(int eflag, int vflag) } else error->one(FLERR,"Only LOOKUP and LINEAR table styles have been implemented for pair multi/lucy/rx"); - if (isite1 == isite2) fpair = sqrt(fractionOld1_i*fractionOld2_j)*fpair; - else fpair = (sqrt(fractionOld1_i*fractionOld2_j) + sqrt(fractionOld2_i*fractionOld1_j))*fpair; + if (isite1 == isite2) fpair = sqrt(mixWtSite1old_i*mixWtSite2old_j)*fpair; + else fpair = (sqrt(mixWtSite1old_i*mixWtSite2old_j) + sqrt(mixWtSite2old_i*mixWtSite1old_j))*fpair; fx_i += delx*fpair; fy_i += dely*fpair; @@ -270,8 +277,8 @@ void PairMultiLucyRX::compute(int eflag, int vflag) } else error->one(FLERR,"Only LOOKUP and LINEAR table styles have been implemented for pair multi/lucy/rx"); evdwl *=(pi*cutsq[itype][itype]*cutsq[itype][itype])/84.0; - evdwlOld = fractionOld1_i*evdwl; - evdwl = fraction1_i*evdwl; + evdwlOld = mixWtSite1old_i*evdwl; + evdwl = mixWtSite1_i*evdwl; uCG[i] += evdwlOld; uCGnew[i] += evdwl; @@ -283,10 +290,10 @@ void PairMultiLucyRX::compute(int eflag, int vflag) if (vflag_fdotr) virial_fdotr_compute(); - memory->destroy(fractionOld1); - memory->destroy(fractionOld2); - memory->destroy(fraction1); - memory->destroy(fraction2); + memory->destroy(mixWtSite1old); + memory->destroy(mixWtSite2old); + memory->destroy(mixWtSite1); + memory->destroy(mixWtSite2); } /* ---------------------------------------------------------------------- @@ -313,7 +320,7 @@ void PairMultiLucyRX::allocate() void PairMultiLucyRX::settings(int narg, char **arg) { - if (narg != 2) error->all(FLERR,"Illegal pair_style command"); + if (narg < 2) error->all(FLERR,"Illegal pair_style command"); // new settings @@ -324,6 +331,16 @@ void PairMultiLucyRX::settings(int narg, char **arg) tablength = force->inumeric(FLERR,arg[1]); if (tablength < 2) error->all(FLERR,"Illegal number of pair table entries"); + // optional keywords + + int iarg = 2; + while (iarg < narg) { + if (strcmp(arg[iarg],"fractional") == 0) fractionalWeighting = true; + else if (strcmp(arg[iarg],"molecular") == 0) fractionalWeighting = false; + else error->all(FLERR,"Illegal pair_style command"); + iarg++; + } + // delete old tables, since cannot just change settings for (int m = 0; m < ntables; m++) free_table(&tables[m]); @@ -930,9 +947,14 @@ void PairMultiLucyRX::computeLocalDensity() /* ---------------------------------------------------------------------- */ -void PairMultiLucyRX::getParams(int id, double &fractionOld1, double &fractionOld2, double &fraction1, double &fraction2) +void PairMultiLucyRX::getMixingWeights(int id, double &mixWtSite1old, double &mixWtSite2old, double &mixWtSite1, double &mixWtSite2) { - double fractionOld, fraction; + double fractionOFAold, fractionOFA; + double fractionOld1, fraction1; + double fractionOld2, fraction2; + double nMoleculesOFAold, nMoleculesOFA; + double nMoleculesOld1, nMolecules1; + double nMoleculesOld2, nMolecules2; double nTotal, nTotalOld; nTotal = 0.0; @@ -943,32 +965,56 @@ void PairMultiLucyRX::getParams(int id, double &fractionOld1, double &fractionOl } if (isOneFluid(isite1) == false){ - fractionOld1 = atom->dvector[isite1+nspecies][id]/nTotalOld; - fraction1 = atom->dvector[isite1][id]/nTotal; + nMoleculesOld1 = atom->dvector[isite1+nspecies][id]; + nMolecules1 = atom->dvector[isite1][id]; + fractionOld1 = nMoleculesOld1/nTotalOld; + fraction1 = nMolecules1/nTotal; } if (isOneFluid(isite2) == false){ - fractionOld2 = atom->dvector[isite2+nspecies][id]/nTotalOld; - fraction2 = atom->dvector[isite2][id]/nTotal; + nMoleculesOld2 = atom->dvector[isite2+nspecies][id]; + nMolecules2 = atom->dvector[isite2][id]; + fractionOld2 = nMoleculesOld2/nTotalOld; + fraction2 = nMolecules2/nTotal; } if (isOneFluid(isite1) || isOneFluid(isite2)){ - fractionOld = 0.0; - fraction = 0.0; + nMoleculesOFAold = 0.0; + nMoleculesOFA = 0.0; + fractionOFAold = 0.0; + fractionOFA = 0.0; for (int ispecies = 0; ispecies < nspecies; ispecies++){ if (isite1 == ispecies || isite2 == ispecies) continue; - fractionOld += atom->dvector[ispecies+nspecies][id] / nTotalOld; - fraction += atom->dvector[ispecies][id] / nTotal; + nMoleculesOFAold += atom->dvector[ispecies+nspecies][id]; + nMoleculesOFA += atom->dvector[ispecies][id]; + fractionOFAold += atom->dvector[ispecies+nspecies][id] / nTotalOld; + fractionOFA += atom->dvector[ispecies][id] / nTotal; } if (isOneFluid(isite1)){ - fractionOld1 = fractionOld; - fraction1 = fraction; + nMoleculesOld1 = 1.0-(nTotalOld-nMoleculesOFAold); + nMolecules1 = 1.0-(nTotal-nMoleculesOFA); + fractionOld1 = fractionOFAold; + fraction1 = fractionOFA; } if (isOneFluid(isite2)){ - fractionOld2 = fractionOld; - fraction2 = fraction; + nMoleculesOld2 = 1.0-(nTotalOld-nMoleculesOFAold); + nMolecules2 = 1.0-(nTotal-nMoleculesOFA); + fractionOld2 = fractionOFAold; + fraction2 = fractionOFA; } } + + if(fractionalWeighting){ + mixWtSite1old = fractionOld1; + mixWtSite1 = fraction1; + mixWtSite2old = fractionOld2; + mixWtSite2 = fraction2; + } else { + mixWtSite1old = nMoleculesOld1; + mixWtSite1 = nMolecules1; + mixWtSite2old = nMoleculesOld2; + mixWtSite2 = nMolecules2; + } } /* ---------------------------------------------------------------------- */ diff --git a/src/USER-DPD/pair_multi_lucy_rx.h b/src/USER-DPD/pair_multi_lucy_rx.h index 0562739c50..5975bd6ccd 100644 --- a/src/USER-DPD/pair_multi_lucy_rx.h +++ b/src/USER-DPD/pair_multi_lucy_rx.h @@ -78,7 +78,8 @@ class PairMultiLucyRX : public Pair { int nspecies; char *site1, *site2; int isite1, isite2; - void getParams(int, double &, double &, double &, double &); + void getMixingWeights(int, double &, double &, double &, double &); + bool fractionalWeighting; }; diff --git a/src/USER-DPD/pair_table_rx.cpp b/src/USER-DPD/pair_table_rx.cpp index 463e1838c6..e3cacc6155 100644 --- a/src/USER-DPD/pair_table_rx.cpp +++ b/src/USER-DPD/pair_table_rx.cpp @@ -35,6 +35,12 @@ enum{NONE,RLINEAR,RSQ,BMP}; #define MAXLINE 1024 +#ifdef DBL_EPSILON + #define MY_EPSILON (10.0*DBL_EPSILON) +#else + #define MY_EPSILON (10.0*2.220446049250313e-16) +#endif + #define OneFluidValue (-1) #define isOneFluid(_site_) ( (_site_) == OneFluidValue ) @@ -44,6 +50,7 @@ PairTableRX::PairTableRX(LAMMPS *lmp) : Pair(lmp) { ntables = 0; tables = NULL; + fractionalWeighting = true; } /* ---------------------------------------------------------------------- */ @@ -84,21 +91,6 @@ void PairTableRX::compute(int eflag, int vflag) if (eflag || vflag) ev_setup(eflag,vflag); else evflag = vflag_fdotr = 0; - double *fractionOld1, *fractionOld2; - double *fraction1, *fraction2; - - { - const int ntotal = atom->nlocal + atom->nghost; - - memory->create(fractionOld1, ntotal, "PairTableRx::compute::fractionOld1"); - memory->create(fractionOld2, ntotal, "PairTableRx::compute::fractionOld2"); - memory->create(fraction1, ntotal, "PairTableRx::compute::fraction1"); - memory->create(fraction2, ntotal, "PairTableRx::compute::fraction2"); - - for (int i = 0; i < ntotal; ++i) - getParams(i, fractionOld1[i], fractionOld2[i], fraction1[i], fraction2[i]); - } - double **x = atom->x; double **f = atom->f; int *type = atom->type; @@ -106,13 +98,29 @@ void PairTableRX::compute(int eflag, int vflag) double *special_lj = force->special_lj; int newton_pair = force->newton_pair; - double fractionOld1_i, fractionOld1_j; - double fractionOld2_i, fractionOld2_j; - double fraction1_i, fraction1_j; - double fraction2_i, fraction2_j; + double mixWtSite1old_i, mixWtSite1old_j; + double mixWtSite2old_i, mixWtSite2old_j; + double mixWtSite1_i, mixWtSite1_j; + double mixWtSite2_i, mixWtSite2_j; double *uCG = atom->uCG; double *uCGnew = atom->uCGnew; + double *mixWtSite1old = NULL; + double *mixWtSite2old = NULL; + double *mixWtSite1 = NULL; + double *mixWtSite2 = NULL; + + { + const int ntotal = atom->nlocal + atom->nghost; + memory->create(mixWtSite1old, ntotal, "PairTableRx::compute::mixWtSite1old"); + memory->create(mixWtSite2old, ntotal, "PairTableRx::compute::mixWtSite2old"); + memory->create(mixWtSite1, ntotal, "PairTableRx::compute::mixWtSite1"); + memory->create(mixWtSite2, ntotal, "PairTableRx::compute::mixWtSite2"); + + for (int i = 0; i < ntotal; ++i) + getMixingWeights(i, mixWtSite1old[i], mixWtSite2old[i], mixWtSite1[i], mixWtSite2[i]); + } + inum = list->inum; ilist = list->ilist; numneigh = list->numneigh; @@ -132,10 +140,10 @@ void PairTableRX::compute(int eflag, int vflag) double uCGnew_i = 0.0; double fx_i = 0.0, fy_i = 0.0, fz_i = 0.0; - fractionOld1_i = fractionOld1[i]; - fractionOld2_i = fractionOld2[i]; - fraction1_i = fraction1[i]; - fraction2_i = fraction2[i]; + mixWtSite1old_i = mixWtSite1old[i]; + mixWtSite2old_i = mixWtSite2old[i]; + mixWtSite1_i = mixWtSite1[i]; + mixWtSite2_i = mixWtSite2[i]; for (jj = 0; jj < jnum; jj++) { j = jlist[jj]; @@ -149,10 +157,10 @@ void PairTableRX::compute(int eflag, int vflag) jtype = type[j]; if (rsq < cutsq[itype][jtype]) { - fractionOld1_j = fractionOld1[j]; - fractionOld2_j = fractionOld2[j]; - fraction1_j = fraction1[j]; - fraction2_j = fraction2[j]; + mixWtSite1old_j = mixWtSite1old[j]; + mixWtSite2old_j = mixWtSite2old[j]; + mixWtSite1_j = mixWtSite1[j]; + mixWtSite2_j = mixWtSite2[j]; tb = &tables[tabindex[itype][jtype]]; if (rsq < tb->innersq) @@ -188,8 +196,8 @@ void PairTableRX::compute(int eflag, int vflag) value = tb->f[itable] + fraction*tb->df[itable]; fpair = factor_lj * value; } - if (isite1 == isite2) fpair = sqrt(fractionOld1_i*fractionOld2_j)*fpair; - else fpair = (sqrt(fractionOld1_i*fractionOld2_j) + sqrt(fractionOld2_i*fractionOld1_j))*fpair; + if (isite1 == isite2) fpair = sqrt(mixWtSite1old_i*mixWtSite2old_j)*fpair; + else fpair = (sqrt(mixWtSite1old_i*mixWtSite2old_j) + sqrt(mixWtSite2old_i*mixWtSite1old_j))*fpair; fx_i += delx*fpair; fy_i += dely*fpair; @@ -210,11 +218,11 @@ void PairTableRX::compute(int eflag, int vflag) ((a*a*a-a)*tb->e2[itable] + (b*b*b-b)*tb->e2[itable+1]) * tb->deltasq6; if (isite1 == isite2){ - evdwlOld = sqrt(fractionOld1_i*fractionOld2_j)*evdwl; - evdwl = sqrt(fraction1_i*fraction2_j)*evdwl; + evdwlOld = sqrt(mixWtSite1old_i*mixWtSite2old_j)*evdwl; + evdwl = sqrt(mixWtSite1_i*mixWtSite2_j)*evdwl; } else { - evdwlOld = (sqrt(fractionOld1_i*fractionOld2_j) + sqrt(fractionOld2_i*fractionOld1_j))*evdwl; - evdwl = (sqrt(fraction1_i*fraction2_j) + sqrt(fraction2_i*fraction1_j))*evdwl; + evdwlOld = (sqrt(mixWtSite1old_i*mixWtSite2old_j) + sqrt(mixWtSite2old_i*mixWtSite1old_j))*evdwl; + evdwl = (sqrt(mixWtSite1_i*mixWtSite2_j) + sqrt(mixWtSite2_i*mixWtSite1_j))*evdwl; } evdwlOld *= factor_lj; evdwl *= factor_lj; @@ -240,10 +248,10 @@ void PairTableRX::compute(int eflag, int vflag) } if (vflag_fdotr) virial_fdotr_compute(); - memory->destroy(fractionOld1); - memory->destroy(fractionOld2); - memory->destroy(fraction1); - memory->destroy(fraction2); + memory->destroy(mixWtSite1old); + memory->destroy(mixWtSite2old); + memory->destroy(mixWtSite1); + memory->destroy(mixWtSite2); } /* ---------------------------------------------------------------------- @@ -293,6 +301,8 @@ void PairTableRX::settings(int narg, char **arg) else if (strcmp(arg[iarg],"msm") == 0) msmflag = 1; else if (strcmp(arg[iarg],"dispersion") == 0) dispersionflag = 1; else if (strcmp(arg[iarg],"tip4p") == 0) tip4pflag = 1; + else if (strcmp(arg[iarg],"fractional") == 0) fractionalWeighting = true; + else if (strcmp(arg[iarg],"molecular") == 0) fractionalWeighting = false; else error->all(FLERR,"Illegal pair_style command"); iarg++; } @@ -1061,17 +1071,17 @@ double PairTableRX::single(int i, int j, int itype, int jtype, double rsq, int tlm1 = tablength - 1; Table *tb = &tables[tabindex[itype][jtype]]; - double fraction1_i, fraction1_j; - double fraction2_i, fraction2_j; - double fractionOld1_i, fractionOld1_j; - double fractionOld2_i, fractionOld2_j; + double mixWtSite1_i, mixWtSite1_j; + double mixWtSite2_i, mixWtSite2_j; + double mixWtSite1old_i, mixWtSite1old_j; + double mixWtSite2old_i, mixWtSite2old_j; fraction = 0.0; a = 0.0; b = 0.0; - getParams(i,fractionOld1_i,fractionOld2_i,fraction1_i,fraction2_i); - getParams(j,fractionOld1_j,fractionOld2_j,fraction1_j,fraction2_j); + getMixingWeights(i,mixWtSite1old_i,mixWtSite2old_i,mixWtSite1_i,mixWtSite2_i); + getMixingWeights(j,mixWtSite1old_j,mixWtSite2old_j,mixWtSite1_j,mixWtSite2_j); if (rsq < tb->innersq) error->one(FLERR,"Pair distance < table inner cutoff"); @@ -1104,8 +1114,8 @@ double PairTableRX::single(int i, int j, int itype, int jtype, double rsq, fforce = factor_lj * value; } - if (isite1 == isite2) fforce = sqrt(fraction1_i*fraction2_j)*fforce; - else fforce = (sqrt(fraction1_i*fraction2_j) + sqrt(fraction2_i*fraction1_j))*fforce; + if (isite1 == isite2) fforce = sqrt(mixWtSite1_i*mixWtSite2_j)*fforce; + else fforce = (sqrt(mixWtSite1_i*mixWtSite2_j) + sqrt(mixWtSite2_i*mixWtSite1_j))*fforce; if (tabstyle == LOOKUP) phi = tb->e[itable]; @@ -1115,8 +1125,8 @@ double PairTableRX::single(int i, int j, int itype, int jtype, double rsq, phi = a * tb->e[itable] + b * tb->e[itable+1] + ((a*a*a-a)*tb->e2[itable] + (b*b*b-b)*tb->e2[itable+1]) * tb->deltasq6; - if (isite1 == isite2) phi = sqrt(fraction1_i*fraction2_j)*phi; - else phi = (sqrt(fraction1_i*fraction2_j) + sqrt(fraction2_i*fraction1_j))*phi; + if (isite1 == isite2) phi = sqrt(mixWtSite1_i*mixWtSite2_j)*phi; + else phi = (sqrt(mixWtSite1_i*mixWtSite2_j) + sqrt(mixWtSite2_i*mixWtSite1_j))*phi; return factor_lj*phi; } @@ -1143,46 +1153,74 @@ void *PairTableRX::extract(const char *str, int &dim) /* ---------------------------------------------------------------------- */ -void PairTableRX::getParams(int id, double &fractionOld1, double &fractionOld2, double &fraction1, double &fraction2) +void PairTableRX::getMixingWeights(int id, double &mixWtSite1old, double &mixWtSite2old, double &mixWtSite1, double &mixWtSite2) { - double nTotal = 0.0; - double nTotalOld = 0.0; + double fractionOFAold, fractionOFA; + double fractionOld1, fraction1; + double fractionOld2, fraction2; + double nMoleculesOFAold, nMoleculesOFA; + double nMoleculesOld1, nMolecules1; + double nMoleculesOld2, nMolecules2; + double nTotal, nTotalOld; + + nTotal = 0.0; + nTotalOld = 0.0; for (int ispecies = 0; ispecies < nspecies; ++ispecies){ nTotal += atom->dvector[ispecies][id]; nTotalOld += atom->dvector[ispecies+nspecies][id]; } - if(nTotal < 1e-8 || nTotalOld < 1e-8) - error->all(FLERR,"The number of molecules in CG particle is less than 1e-8."); + if(nTotal < MY_EPSILON || nTotalOld < MY_EPSILON) + error->all(FLERR,"The number of molecules in CG particle is less than 10*DBL_EPSILON."); if (isOneFluid(isite1) == false){ - fractionOld1 = atom->dvector[isite1+nspecies][id]/nTotalOld; - fraction1 = atom->dvector[isite1][id]/nTotal; + nMoleculesOld1 = atom->dvector[isite1+nspecies][id]; + nMolecules1 = atom->dvector[isite1][id]; + fractionOld1 = nMoleculesOld1/nTotalOld; + fraction1 = nMolecules1/nTotal; } if (isOneFluid(isite2) == false){ - fractionOld2 = atom->dvector[isite2+nspecies][id]/nTotalOld; - fraction2 = atom->dvector[isite2][id]/nTotal; + nMoleculesOld2 = atom->dvector[isite2+nspecies][id]; + nMolecules2 = atom->dvector[isite2][id]; + fractionOld2 = nMoleculesOld2/nTotalOld; + fraction2 = nMolecules2/nTotal; } if (isOneFluid(isite1) || isOneFluid(isite2)){ - double fractionOld = 0.0; - double fraction = 0.0; + nMoleculesOFAold = 0.0; + nMoleculesOFA = 0.0; + fractionOFAold = 0.0; + fractionOFA = 0.0; for (int ispecies = 0; ispecies < nspecies; ispecies++){ if (isite1 == ispecies || isite2 == ispecies) continue; - - fractionOld += atom->dvector[ispecies+nspecies][id]/nTotalOld; - fraction += atom->dvector[ispecies][id]/nTotal; + nMoleculesOFAold += atom->dvector[ispecies+nspecies][id]; + nMoleculesOFA += atom->dvector[ispecies][id]; + fractionOFAold += atom->dvector[ispecies+nspecies][id]/nTotalOld; + fractionOFA += atom->dvector[ispecies][id]/nTotal; } - if(isOneFluid(isite1)){ - fractionOld1 = fractionOld; - fraction1 = fraction; + nMoleculesOld1 = 1.0-(nTotalOld-nMoleculesOFAold); + nMolecules1 = 1.0-(nTotal-nMoleculesOFA); + fractionOld1 = fractionOFAold; + fraction1 = fractionOFA; } - if(isOneFluid(isite2)){ - fractionOld2 = fractionOld; - fraction2 = fraction; + nMoleculesOld2 = 1.0-(nTotalOld-nMoleculesOFAold); + nMolecules2 = 1.0-(nTotal-nMoleculesOFA); + fractionOld2 = fractionOFAold; + fraction2 = fractionOFA; } } -} + if(fractionalWeighting){ + mixWtSite1old = fractionOld1; + mixWtSite1 = fraction1; + mixWtSite2old = fractionOld2; + mixWtSite2 = fraction2; + } else { + mixWtSite1old = nMoleculesOld1; + mixWtSite1 = nMolecules1; + mixWtSite2old = nMoleculesOld2; + mixWtSite2 = nMolecules2; + } +} diff --git a/src/USER-DPD/pair_table_rx.h b/src/USER-DPD/pair_table_rx.h index f04ebced20..c6afe6a8d5 100644 --- a/src/USER-DPD/pair_table_rx.h +++ b/src/USER-DPD/pair_table_rx.h @@ -72,7 +72,8 @@ class PairTableRX : public Pair { int nspecies; char *site1, *site2; int isite1, isite2; - void getParams(int, double &, double &, double &, double &); + void getMixingWeights(int, double &, double &, double &, double &); + bool fractionalWeighting; }; @@ -163,7 +164,7 @@ When using pair style table with a long-range KSpace solver, the cutoffs for all atom type pairs must all be the same, since the long-range solver starts at that cutoff. -E: The number of molecules in CG particle is less than 1e-8 +E: The number of molecules in CG particle is less than 10*DBL_EPSILON Self-explanatory. Check the species concentrations have been properly set and check the reaction kinetic solver parameters in fix rx to more for From 2af10cb8da9b8bbac64cead53eb7cae57088ed7c Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 3 Jan 2017 10:09:44 -0700 Subject: [PATCH 034/439] Updating fix_eos_table_rx_kokkos to USER-DPD changes --- src/KOKKOS/fix_eos_table_rx_kokkos.cpp | 64 ++++++++++++++++++++++---- src/KOKKOS/fix_eos_table_rx_kokkos.h | 4 +- 2 files changed, 58 insertions(+), 10 deletions(-) diff --git a/src/KOKKOS/fix_eos_table_rx_kokkos.cpp b/src/KOKKOS/fix_eos_table_rx_kokkos.cpp index c47923680c..aff2cdfa2d 100644 --- a/src/KOKKOS/fix_eos_table_rx_kokkos.cpp +++ b/src/KOKKOS/fix_eos_table_rx_kokkos.cpp @@ -29,6 +29,13 @@ #define MAXLINE 1024 +#ifdef DBL_EPSILON + #define MY_EPSILON (10.0*DBL_EPSILON) +#else + #define MY_EPSILON (10.0*2.220446049250313e-16) +#endif + + using namespace LAMMPS_NS; using namespace FixConst; @@ -51,11 +58,31 @@ FixEOStableRXKokkos::FixEOStableRXKokkos(LAMMPS *lmp, int narg, char k_warning_flag = DAT::tdual_int_scalar("fix:warning_flag"); k_dHf = DAT::tdual_float_1d("fix:dHf",nspecies); - for (int n = 0; n < nspecies; n++) + k_energyCorr = DAT::tdual_float_1d("fix:energyCorr",nspecies); + k_tempCorrCoeff = DAT::tdual_float_1d("fix:tempCorrCoeff",nspecies); + k_moleculeCorrCoeff = DAT::tdual_float_1d("fix:moleculeCorrCoeff",nspecies); + for (int n = 0; n < nspecies; n++) { k_dHf.h_view(n) = dHf[n]; + k_energyCorr.h_view(n) = energyCorr[n]; + k_tempCorrCoeff.h_view(n) = tempCorrCoeff[n]; + k_moleculeCorrCoeff.h_view(n) = moleculeCorrCoeff[n]; + } + k_dHf.modify(); k_dHf.sync(); d_dHf = k_dHf.view(); + + k_energyCorr.modify(); + k_energyCorr.sync(); + d_energyCorr = k_energyCorr.view(); + + k_tempCorrCoeff.modify(); + k_tempCorrCoeff.sync(); + d_tempCorrCoeff = k_tempCorrCoeff.view(); + + k_moleculeCorrCoeff.modify(); + k_moleculeCorrCoeff.sync(); + d_moleculeCorrCoeff = k_moleculeCorrCoeff.view(); } /* ---------------------------------------------------------------------- */ @@ -268,11 +295,27 @@ template KOKKOS_INLINE_FUNCTION void FixEOStableRXKokkos::energy_lookup(int id, double thetai, double &ui) const { - int itable; - double fraction, uTmp, nTotal; + int itable, nPG; + double fraction, uTmp, nMolecules, nTotal, nTotalPG; + double tolerance = 1.0e-10; ui = 0.0; nTotal = 0.0; + nTotalPG = 0.0; + nPG = 0; + + if (rx_flag) { + for (int ispecies = 0; ispecies < nspecies; ispecies++ ) { + nTotal += dvector(ispecies,id); + if (fabs(d_moleculeCorrCoeff[ispecies]) > tolerance) { + nPG++; + nTotalPG += dvector(ispecies,id); + } + } + } else { + nTotal = 1.0; + } + for(int ispecies=0;ispecieslo); @@ -289,9 +332,13 @@ void FixEOStableRXKokkos::energy_lookup(int id, double thetai, doubl uTmp = d_table_const.e(ispecies,itable) + fraction*d_table_const.de(ispecies,itable); uTmp += d_dHf[ispecies]; - // mol fraction form: - ui += dvector(ispecies,id)*uTmp; - nTotal += dvector(ispecies,id); + uTmp += d_tempCorrCoeff[ispecies]*thetai; // temperature correction + uTmp += d_energyCorr[ispecies]; // energy correction + if (nPG > 0) ui += d_moleculeCorrCoeff[ispecies]*nTotalPG/double(nPG); // molecule correction + + if (rx_flag) nMolecules = dvector(ispecies,id); + else nMolecules = 1.0; + ui += nMolecules*uTmp; } } ui = ui - double(nTotal+1.5)*boltz*thetai; @@ -312,6 +359,7 @@ void FixEOStableRXKokkos::temperature_lookup(int id, double ui, doub double maxit = 100; double temp; double delta = 0.001; + double tolerance = 1.0e-10; int lo = d_table_const.lo(0); int hi = d_table_const.hi(0); @@ -337,7 +385,7 @@ void FixEOStableRXKokkos::temperature_lookup(int id, double ui, doub // Apply the Secant Method for(it=0; it::temperature_lookup(int id, double ui, doub break; } temp = t2 - f2*(t2-t1)/(f2-f1); - if(fabs(temp-t2) < 1e-6) break; + if(fabs(temp-t2) < tolerance) break; f1 = f2; t1 = t2; t2 = temp; diff --git a/src/KOKKOS/fix_eos_table_rx_kokkos.h b/src/KOKKOS/fix_eos_table_rx_kokkos.h index d4a5094ae0..91d73f1036 100644 --- a/src/KOKKOS/fix_eos_table_rx_kokkos.h +++ b/src/KOKKOS/fix_eos_table_rx_kokkos.h @@ -112,8 +112,8 @@ class FixEOStableRXKokkos : public FixEOStableRX { int update_table; void create_kokkos_tables(); - DAT::tdual_float_1d k_dHf; - typename AT::t_float_1d d_dHf; + DAT::tdual_float_1d k_dHf,k_energyCorr,k_tempCorrCoeff,k_moleculeCorrCoeff; + typename AT::t_float_1d d_dHf,d_energyCorr,d_tempCorrCoeff,d_moleculeCorrCoeff; typename AT::t_int_1d mask; typename AT::t_efloat_1d uCond,uMech,uChem,uCG,uCGnew,rho,dpdTheta,duChem; From f220b07625b7089b981fcaeff999bae3712b6a3a Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 3 Jan 2017 10:36:55 -0700 Subject: [PATCH 035/439] Updating pair_exp6_rx_kokkos to USER-DPD changes --- src/KOKKOS/pair_exp6_rx_kokkos.cpp | 306 +++++++++++++++++------------ src/KOKKOS/pair_exp6_rx_kokkos.h | 30 ++- src/USER-DPD/pair_exp6_rx.h | 2 +- 3 files changed, 201 insertions(+), 137 deletions(-) diff --git a/src/KOKKOS/pair_exp6_rx_kokkos.cpp b/src/KOKKOS/pair_exp6_rx_kokkos.cpp index ce3b547435..3ce6b78e57 100644 --- a/src/KOKKOS/pair_exp6_rx_kokkos.cpp +++ b/src/KOKKOS/pair_exp6_rx_kokkos.cpp @@ -41,6 +41,12 @@ using namespace MathSpecial; #define MAXLINE 1024 #define DELTA 4 +#ifdef DBL_EPSILON + #define MY_EPSILON (10.0*DBL_EPSILON) +#else + #define MY_EPSILON (10.0*2.220446049250313e-16) +#endif + #define oneFluidApproxParameter (-1) #define isOneFluidApprox(_site) ( (_site) == oneFluidApproxParameter ) @@ -165,29 +171,29 @@ void PairExp6rxKokkos::compute(int eflag_in, int vflag_in) PairExp6ParamData.epsilon1 = typename AT::t_float_1d("PairExp6ParamData.epsilon1" ,np_total); PairExp6ParamData.alpha1 = typename AT::t_float_1d("PairExp6ParamData.alpha1" ,np_total); PairExp6ParamData.rm1 = typename AT::t_float_1d("PairExp6ParamData.rm1" ,np_total); - PairExp6ParamData.fraction1 = typename AT::t_float_1d("PairExp6ParamData.fraction1" ,np_total); + PairExp6ParamData.mixWtSite1 = typename AT::t_float_1d("PairExp6ParamData.mixWtSite1" ,np_total); PairExp6ParamData.epsilon2 = typename AT::t_float_1d("PairExp6ParamData.epsilon2" ,np_total); PairExp6ParamData.alpha2 = typename AT::t_float_1d("PairExp6ParamData.alpha2" ,np_total); PairExp6ParamData.rm2 = typename AT::t_float_1d("PairExp6ParamData.rm2" ,np_total); - PairExp6ParamData.fraction2 = typename AT::t_float_1d("PairExp6ParamData.fraction2" ,np_total); + PairExp6ParamData.mixWtSite2 = typename AT::t_float_1d("PairExp6ParamData.mixWtSite2" ,np_total); PairExp6ParamData.epsilonOld1 = typename AT::t_float_1d("PairExp6ParamData.epsilonOld1" ,np_total); PairExp6ParamData.alphaOld1 = typename AT::t_float_1d("PairExp6ParamData.alphaOld1" ,np_total); PairExp6ParamData.rmOld1 = typename AT::t_float_1d("PairExp6ParamData.rmOld1" ,np_total); - PairExp6ParamData.fractionOld1 = typename AT::t_float_1d("PairExp6ParamData.fractionOld1",np_total); + PairExp6ParamData.mixWtSite1old = typename AT::t_float_1d("PairExp6ParamData.mixWtSite1old",np_total); PairExp6ParamData.epsilonOld2 = typename AT::t_float_1d("PairExp6ParamData.epsilonOld2" ,np_total); PairExp6ParamData.alphaOld2 = typename AT::t_float_1d("PairExp6ParamData.alphaOld2" ,np_total); PairExp6ParamData.rmOld2 = typename AT::t_float_1d("PairExp6ParamData.rmOld2" ,np_total); - PairExp6ParamData.fractionOld2 = typename AT::t_float_1d("PairExp6ParamData.fractionOld2",np_total); + PairExp6ParamData.mixWtSite2old = typename AT::t_float_1d("PairExp6ParamData.mixWtSite2old",np_total); - Kokkos::parallel_for(Kokkos::RangePolicy(0,np_total),*this); + Kokkos::parallel_for(Kokkos::RangePolicy(0,np_total),*this); } k_error_flag.template modify(); k_error_flag.template sync(); if (k_error_flag.h_view() == 1) - error->all(FLERR,"The number of molecules in CG particle is less than 1e-8."); + error->all(FLERR,"The number of molecules in CG particle is less than 10*DBL_EPSILON."); else if (k_error_flag.h_view() == 2) - error->all(FLERR,"Computed fraction less than -1.0e-10"); + error->all(FLERR,"Computed fraction less than -10*DBL_EPSILON"); int inum = list->inum; NeighListKokkos* k_list = static_cast*>(list); @@ -249,23 +255,23 @@ void PairExp6rxKokkos::compute(int eflag_in, int vflag_in) template KOKKOS_INLINE_FUNCTION -void PairExp6rxKokkos::operator()(TagPairExp6rxgetParamsEXP6, const int &i) const { - getParamsEXP6 (i, PairExp6ParamData.epsilon1[i], +void PairExp6rxKokkos::operator()(TagPairExp6rxgetMixingWeights, const int &i) const { + getMixingWeights (i, PairExp6ParamData.epsilon1[i], PairExp6ParamData.alpha1[i], PairExp6ParamData.rm1[i], - PairExp6ParamData.fraction1[i], + PairExp6ParamData.mixWtSite1[i], PairExp6ParamData.epsilon2[i], PairExp6ParamData.alpha2[i], PairExp6ParamData.rm2[i], - PairExp6ParamData.fraction2[i], + PairExp6ParamData.mixWtSite2[i], PairExp6ParamData.epsilonOld1[i], PairExp6ParamData.alphaOld1[i], PairExp6ParamData.rmOld1[i], - PairExp6ParamData.fractionOld1[i], + PairExp6ParamData.mixWtSite1old[i], PairExp6ParamData.epsilonOld2[i], PairExp6ParamData.alphaOld2[i], PairExp6ParamData.rmOld2[i], - PairExp6ParamData.fractionOld2[i]); + PairExp6ParamData.mixWtSite2old[i]); } template @@ -300,10 +306,10 @@ void PairExp6rxKokkos::operator()(TagPairExp6rxCompute::operator()(TagPairExp6rxCompute::operator()(TagPairExp6rxCompute::operator()(TagPairExp6rxCompute::operator()(TagPairExp6rxCompute::operator()(TagPairExp6rxCompute::allocate() memory->create(cut,n+1,n+1,"pair:cut_lj"); } + +/* ---------------------------------------------------------------------- + set coeffs for one or more type pairs +------------------------------------------------------------------------- */ + +template +void PairExp6rxKokkos::coeff(int narg, char **arg) +{ + PairExp6rx::coeff(narg,arg); + + if (scalingFlag == POLYNOMIAL) + for (int i = 0; i < 6; i++) { + s_coeffAlpha[i] = coeffAlpha[i]; + s_coeffEps[i] = coeffEps[i]; + s_coeffRm[i] = coeffRm[i]; + } +} + /* ---------------------------------------------------------------------- */ template @@ -793,7 +817,7 @@ void PairExp6rxKokkos::setup() template KOKKOS_INLINE_FUNCTION -void PairExp6rxKokkos::getParamsEXP6(int id,double &epsilon1,double &alpha1,double &rm1, double &fraction1,double &epsilon2,double &alpha2,double &rm2,double &fraction2,double &epsilon1_old,double &alpha1_old,double &rm1_old, double &fraction1_old,double &epsilon2_old,double &alpha2_old,double &rm2_old,double &fraction2_old) const +void PairExp6rxKokkos::getMixingWeights(int id,double &epsilon1,double &alpha1,double &rm1, double &mixWtSite1,double &epsilon2,double &alpha2,double &rm2,double &mixWtSite2,double &epsilon1_old,double &alpha1_old,double &rm1_old, double &mixWtSite1old,double &epsilon2_old,double &alpha2_old,double &rm2_old,double &mixWtSite2old) const { int iparam, jparam; double rmi, rmj, rmij, rm3ij; @@ -801,11 +825,16 @@ void PairExp6rxKokkos::getParamsEXP6(int id,double &epsilon1,double double alphai, alphaj, alphaij; double epsilon_old, rm3_old, alpha_old; double epsilon, rm3, alpha; - double fractionOFA, fractionOFA_old; - double nTotalOFA, nTotalOFA_old; - double nTotal, nTotal_old; double xMolei, xMolej, xMolei_old, xMolej_old; + double fractionOFAold, fractionOFA; + double fractionOld1, fraction1; + double fractionOld2, fraction2; + double nMoleculesOFAold, nMoleculesOFA; + double nMoleculesOld1, nMolecules1; + double nMoleculesOld2, nMolecules2; + double nTotal, nTotalold; + rm3 = 0.0; epsilon = 0.0; alpha = 0.0; @@ -813,32 +842,32 @@ void PairExp6rxKokkos::getParamsEXP6(int id,double &epsilon1,double rm3_old = 0.0; alpha_old = 0.0; fractionOFA = 0.0; - fractionOFA_old = 0.0; - nTotalOFA = 0.0; - nTotalOFA_old = 0.0; + fractionOFAold = 0.0; + nMoleculesOFA = 0.0; + nMoleculesOFAold = 0.0; nTotal = 0.0; - nTotal_old = 0.0; + nTotalold = 0.0; // Compute the total number of molecules in the old and new CG particle as well as the total number of molecules in the fluid portion of the old and new CG particle for (int ispecies = 0; ispecies < nspecies; ispecies++){ nTotal += dvector(ispecies,id); - nTotal_old += dvector(ispecies+nspecies,id); + nTotalold += dvector(ispecies+nspecies,id); iparam = d_mol2param[ispecies]; if (iparam < 0 || d_params[iparam].potentialType != exp6PotentialType ) continue; if (isOneFluidApprox(isite1) || isOneFluidApprox(isite2)) { if (isite1 == d_params[iparam].ispecies || isite2 == d_params[iparam].ispecies) continue; - nTotalOFA_old += dvector(ispecies+nspecies,id); - nTotalOFA += dvector(ispecies,id); + nMoleculesOFAold += dvector(ispecies+nspecies,id); + nMoleculesOFA += dvector(ispecies,id); } } - if(nTotal < 1e-8 || nTotal_old < 1e-8) + if(nTotal < MY_EPSILON || nTotalold < MY_EPSILON) k_error_flag.d_view() = 1; // Compute the mole fraction of molecules within the fluid portion of the particle (One Fluid Approximation) - fractionOFA_old = nTotalOFA_old / nTotal_old; - fractionOFA = nTotalOFA / nTotal; + fractionOFAold = nMoleculesOFAold / nTotalold; + fractionOFA = nMoleculesOFA / nTotal; for (int ispecies = 0; ispecies < nspecies; ispecies++) { iparam = d_mol2param[ispecies]; @@ -854,8 +883,10 @@ void PairExp6rxKokkos::getParamsEXP6(int id,double &epsilon1,double alpha1 = d_params[iparam].alpha; // Compute the mole fraction of Site1 - fraction1_old = dvector(ispecies+nspecies,id)/nTotal_old; - fraction1 = dvector(ispecies,id)/nTotal; + nMoleculesOld1 = dvector(ispecies+nspecies,id); + nMolecules1 = dvector(ispecies,id); + fractionOld1 = nMoleculesOld1/nTotalold; + fraction1 = nMolecules1/nTotal; } // If Site2 matches a pure species, then grab the parameters @@ -868,8 +899,9 @@ void PairExp6rxKokkos::getParamsEXP6(int id,double &epsilon1,double alpha2 = d_params[iparam].alpha; // Compute the mole fraction of Site2 - fraction2_old = dvector(ispecies+nspecies,id)/nTotal_old; - fraction2 = dvector(ispecies,id)/nTotal; + nMoleculesOld2 = dvector(ispecies+nspecies,id); + nMolecules2 = dvector(ispecies,id); + fractionOld2 = dvector(ispecies+nspecies,id)/nTotalold; } // If Site1 or Site2 matches is a fluid, then compute the paramters @@ -878,8 +910,10 @@ void PairExp6rxKokkos::getParamsEXP6(int id,double &epsilon1,double rmi = d_params[iparam].rm; epsiloni = d_params[iparam].epsilon; alphai = d_params[iparam].alpha; - xMolei = dvector(ispecies,id)/nTotalOFA; - xMolei_old = dvector(ispecies+nspecies,id)/nTotalOFA_old; + if(nMoleculesOFA::getParamsEXP6(int id,double &epsilon1,double rmj = d_params[jparam].rm; epsilonj = d_params[jparam].epsilon; alphaj = d_params[jparam].alpha; - xMolej = dvector(jspecies,id)/nTotalOFA; - xMolej_old = dvector(jspecies+nspecies,id)/nTotalOFA_old; + if(nMoleculesOFA 0.0){ + if(fractionOFAold > 0.0){ rm3_old += xMolei_old*xMolej_old*rm3ij; epsilon_old += xMolei_old*xMolej_old*rm3ij*epsilonij; alpha_old += xMolei_old*xMolej_old*rm3ij*epsilonij*alphaij; @@ -912,7 +948,7 @@ void PairExp6rxKokkos::getParamsEXP6(int id,double &epsilon1,double if (isOneFluidApprox(isite1)){ rm1 = cbrt(rm3); - if(rm1 < 1e-16) { + if(rm1 < MY_EPSILON) { rm1 = 0.0; epsilon1 = 0.0; alpha1 = 0.0; @@ -920,11 +956,11 @@ void PairExp6rxKokkos::getParamsEXP6(int id,double &epsilon1,double epsilon1 = epsilon / rm3; alpha1 = alpha / epsilon1 / rm3; } - + nMolecules1 = 1.0-(nTotal-nMoleculesOFA); fraction1 = fractionOFA; rm1_old = cbrt(rm3_old); - if(rm1_old < 1e-16) { + if(rm1_old < MY_EPSILON) { rm1_old = 0.0; epsilon1_old = 0.0; alpha1_old = 0.0; @@ -932,42 +968,21 @@ void PairExp6rxKokkos::getParamsEXP6(int id,double &epsilon1,double epsilon1_old = epsilon_old / rm3_old; alpha1_old = alpha_old / epsilon1_old / rm3_old; } - fraction1_old = fractionOFA_old; + nMoleculesOld1 = 1.0-(nTotalold-nMoleculesOFAold); + fractionOld1 = fractionOFAold; - // Fuchslin-Like Exp-6 Scaling - double powfuch = 0.0; - if(exponentEpsilon < 0.0){ - powfuch = pow(nTotalOFA,-exponentEpsilon); - if(powfuch<1e-15) epsilon1 = 0.0; - else epsilon1 *= 1.0/powfuch; - - powfuch = pow(nTotalOFA_old,-exponentEpsilon); - if(powfuch<1e-15) epsilon1_old = 0.0; - else epsilon1_old *= 1.0/powfuch; - - } else { - epsilon1 *= pow(nTotalOFA,exponentEpsilon); - epsilon1_old *= pow(nTotalOFA_old,exponentEpsilon); - } - - if(exponentR < 0.0){ - powfuch = pow(nTotalOFA,-exponentR); - if(powfuch<1e-15) rm1 = 0.0; - else rm1 *= 1.0/powfuch; - - powfuch = pow(nTotalOFA_old,-exponentR); - if(powfuch<1e-15) rm1_old = 0.0; - else rm1_old *= 1.0/powfuch; - - } else { - rm1 *= pow(nTotalOFA,exponentR); - rm1_old *= pow(nTotalOFA_old,exponentR); + if(scalingFlag == EXPONENT){ + exponentScaling(nMoleculesOFA,epsilon1,rm1); + exponentScaling(nMoleculesOFAold,epsilon1_old,rm1_old); + } else if(scalingFlag == POLYNOMIAL){ + polynomialScaling(nMoleculesOFA,alpha1,epsilon1,rm1); + polynomialScaling(nMoleculesOFAold,alpha1_old,epsilon1_old,rm1_old); } } if (isOneFluidApprox(isite2)){ rm2 = cbrt(rm3); - if(rm2 < 1e-16) { + if(rm2 < MY_EPSILON) { rm2 = 0.0; epsilon2 = 0.0; alpha2 = 0.0; @@ -975,10 +990,11 @@ void PairExp6rxKokkos::getParamsEXP6(int id,double &epsilon1,double epsilon2 = epsilon / rm3; alpha2 = alpha / epsilon2 / rm3; } + nMolecules2 = 1.0-(nTotal-nMoleculesOFA); fraction2 = fractionOFA; rm2_old = cbrt(rm3_old); - if(rm2_old < 1e-16) { + if(rm2_old < MY_EPSILON) { rm2_old = 0.0; epsilon2_old = 0.0; alpha2_old = 0.0; @@ -986,64 +1002,100 @@ void PairExp6rxKokkos::getParamsEXP6(int id,double &epsilon1,double epsilon2_old = epsilon_old / rm3_old; alpha2_old = alpha_old / epsilon2_old / rm3_old; } - fraction2_old = fractionOFA_old; + nMoleculesOld2 = 1.0-(nTotalold-nMoleculesOFAold); + fractionOld2 = fractionOFAold; - // Fuchslin-Like Exp-6 Scaling - double powfuch = 0.0; - if(exponentEpsilon < 0.0){ - powfuch = pow(nTotalOFA,-exponentEpsilon); - if(powfuch<1e-15) epsilon2 = 0.0; - else epsilon2 *= 1.0/powfuch; - - powfuch = pow(nTotalOFA_old,-exponentEpsilon); - if(powfuch<1e-15) epsilon2_old = 0.0; - else epsilon2_old *= 1.0/powfuch; - - } else { - epsilon2 *= pow(nTotalOFA,exponentEpsilon); - epsilon2_old *= pow(nTotalOFA_old,exponentEpsilon); - } - - if(exponentR < 0.0){ - powfuch = pow(nTotalOFA,-exponentR); - if(powfuch<1e-15) rm2 = 0.0; - else rm2 *= 1.0/powfuch; - - powfuch = pow(nTotalOFA_old,-exponentR); - if(powfuch<1e-15) rm2_old = 0.0; - else rm2_old *= 1.0/powfuch; - - } else { - rm2 *= pow(nTotalOFA,exponentR); - rm2_old *= pow(nTotalOFA_old,exponentR); + if(scalingFlag == EXPONENT){ + exponentScaling(nMoleculesOFA,epsilon2,rm2); + exponentScaling(nMoleculesOFAold,epsilon2_old,rm2_old); + } else if(scalingFlag == POLYNOMIAL){ + polynomialScaling(nMoleculesOFA,alpha2,epsilon2,rm2); + polynomialScaling(nMoleculesOFAold,alpha2_old,epsilon2_old,rm2_old); } } // Check that no fractions are less than zero - if(fraction1 < 0.0){ - if(fraction1 < -1.0e-10){ + if(fraction1 < 0.0 || nMolecules1 < 0.0){ + if(fraction1 < -MY_EPSILON || nMolecules1 < -MY_EPSILON){ k_error_flag.d_view() = 2; } + nMolecules1 = 0.0; fraction1 = 0.0; } - if(fraction2 < 0.0){ - if(fraction2 < -1.0e-10){ + if(fraction2 < 0.0 || nMolecules2 < 0.0){ + if(fraction2 < -MY_EPSILON || nMolecules2 < -MY_EPSILON){ k_error_flag.d_view() = 2; } + nMolecules2 = 0.0; fraction2 = 0.0; } - if(fraction1_old < 0.0){ - if(fraction1_old < -1.0e-10){ + if(fractionOld1 < 0.0 || nMoleculesOld1 < 0.0){ + if(fractionOld1 < -MY_EPSILON || nMoleculesOld1 < -MY_EPSILON){ k_error_flag.d_view() = 2; } - fraction1_old = 0.0; + nMoleculesOld1 = 0.0; + fractionOld1 = 0.0; } - if(fraction2_old < 0.0){ - if(fraction2_old < -1.0e-10){ + if(fractionOld2 < 0.0 || nMoleculesOld2 < 0.0){ + if(fractionOld2 < -MY_EPSILON || nMoleculesOld2 < -MY_EPSILON){ k_error_flag.d_view() = 2; } - fraction2_old = 0.0; + nMoleculesOld2 = 0.0; + fractionOld2 = 0.0; } + + if(fractionalWeighting){ + mixWtSite1old = fractionOld1; + mixWtSite1 = fraction1; + mixWtSite2old = fractionOld2; + mixWtSite2 = fraction2; + } else { + mixWtSite1old = nMoleculesOld1; + mixWtSite1 = nMolecules1; + mixWtSite2old = nMoleculesOld2; + mixWtSite2 = nMolecules2; + } +} + +/* ---------------------------------------------------------------------- */ + +template +KOKKOS_INLINE_FUNCTION +void PairExp6rxKokkos::exponentScaling(double phi, double &epsilon, double &rm) const +{ + double powfuch; + + if(exponentEpsilon < 0.0){ + powfuch = pow(phi,-exponentEpsilon); + if(powfuch +KOKKOS_INLINE_FUNCTION +void PairExp6rxKokkos::polynomialScaling(double phi, double &alpha, double &epsilon, double &rm) const +{ + double phi2 = phi*phi; + double phi3 = phi2*phi; + double phi4 = phi2*phi2; + double phi5 = phi2*phi3; + + alpha = (s_coeffAlpha[0]*phi5 + s_coeffAlpha[1]*phi4 + s_coeffAlpha[2]*phi3 + s_coeffAlpha[3]*phi2 + s_coeffAlpha[4]*phi + s_coeffAlpha[5]); + epsilon *= (s_coeffEps[0]*phi5 + s_coeffEps[1]*phi4 + s_coeffEps[2]*phi3 + s_coeffEps[3]*phi2 + s_coeffEps[4]*phi + s_coeffEps[5]); + rm *= (s_coeffEps[0]*phi5 + s_coeffEps[1]*phi4 + s_coeffEps[2]*phi3 + s_coeffEps[3]*phi2 + s_coeffEps[4]*phi + s_coeffEps[5]); } /* ---------------------------------------------------------------------- */ diff --git a/src/KOKKOS/pair_exp6_rx_kokkos.h b/src/KOKKOS/pair_exp6_rx_kokkos.h index 7dfe20fc22..488c9d0039 100644 --- a/src/KOKKOS/pair_exp6_rx_kokkos.h +++ b/src/KOKKOS/pair_exp6_rx_kokkos.h @@ -38,18 +38,21 @@ struct PairExp6ParamDataTypeKokkos typedef ArrayTypes AT; int n; - typename AT::t_float_1d epsilon1, alpha1, rm1, fraction1, - epsilon2, alpha2, rm2, fraction2, - epsilonOld1, alphaOld1, rmOld1, fractionOld1, - epsilonOld2, alphaOld2, rmOld2, fractionOld2; + typename AT::t_float_1d epsilon1, alpha1, rm1, mixWtSite1, + epsilon2, alpha2, rm2, mixWtSite2, + epsilonOld1, alphaOld1, rmOld1, mixWtSite1old, + epsilonOld2, alphaOld2, rmOld2, mixWtSite2old; // Default constructor -- nullify everything. PairExp6ParamDataTypeKokkos(void) - : n(0) + : n(0), epsilon1(NULL), alpha1(NULL), rm1(NULL), mixWtSite1(NULL), + epsilon2(NULL), alpha2(NULL), rm2(NULL), mixWtSite2(NULL), + epsilonOld1(NULL), alphaOld1(NULL), rmOld1(NULL), mixWtSite1old(NULL), + epsilonOld2(NULL), alphaOld2(NULL), rmOld2(NULL), mixWtSite2old(NULL) {} }; -struct TagPairExp6rxgetParamsEXP6{}; +struct TagPairExp6rxgetMixingWeights{}; template struct TagPairExp6rxCompute{}; @@ -64,10 +67,11 @@ class PairExp6rxKokkos : public PairExp6rx { PairExp6rxKokkos(class LAMMPS *); virtual ~PairExp6rxKokkos(); void compute(int, int); + void coeff(int, char **); void init_style(); KOKKOS_INLINE_FUNCTION - void operator()(TagPairExp6rxgetParamsEXP6, const int&) const; + void operator()(TagPairExp6rxgetMixingWeights, const int&) const; template KOKKOS_INLINE_FUNCTION @@ -127,7 +131,15 @@ class PairExp6rxKokkos : public PairExp6rx { void setup(); KOKKOS_INLINE_FUNCTION - void getParamsEXP6(int, double &, double &, double &, double &, double &, double &, double &, double &, double &, double &, double &, double &, double &, double &, double &, double &) const; + void getMixingWeights(int, double &, double &, double &, double &, double &, double &, double &, double &, double &, double &, double &, double &, double &, double &, double &, double &) const; + + KOKKOS_INLINE_FUNCTION + void exponentScaling(double, double &, double &) const; + + KOKKOS_INLINE_FUNCTION + void polynomialScaling(double, double &, double &, double &) const; + + double s_coeffAlpha[6],s_coeffEps[6],s_coeffRm[6]; KOKKOS_INLINE_FUNCTION double func_rin(const double &) const; @@ -196,7 +208,7 @@ E: Potential file has duplicate entry. Self-explanatory -E: The number of molecules in CG particle is less than 1e-8. +E: The number of molecules in CG particle is less than 10*DBL_EPSILON. Self-explanatory. Check the species concentrations have been properly set and check the reaction kinetic solver parameters in fix rx to more for diff --git a/src/USER-DPD/pair_exp6_rx.h b/src/USER-DPD/pair_exp6_rx.h index a7531da318..31d4ffb20b 100644 --- a/src/USER-DPD/pair_exp6_rx.h +++ b/src/USER-DPD/pair_exp6_rx.h @@ -30,7 +30,7 @@ class PairExp6rx : public Pair { virtual ~PairExp6rx(); virtual void compute(int, int); void settings(int, char **); - void coeff(int, char **); + virtual void coeff(int, char **); double init_one(int, int); void write_restart(FILE *); void read_restart(FILE *); From ccaa0506cb93e9f884ebc22b32575feda7e99199 Mon Sep 17 00:00:00 2001 From: Dan Ibanez Date: Thu, 22 Dec 2016 07:55:15 -0700 Subject: [PATCH 036/439] LAMMPS_LAMBDA from ibaned/lammps@7559bc9 --- src/KOKKOS/kokkos_type.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/KOKKOS/kokkos_type.h b/src/KOKKOS/kokkos_type.h index c1176122a7..cc096058ec 100644 --- a/src/KOKKOS/kokkos_type.h +++ b/src/KOKKOS/kokkos_type.h @@ -920,4 +920,10 @@ void memset_kokkos (ViewType &view) { #define ISFINITE(x) std::isfinite(x) #endif +#ifdef KOKKOS_HAVE_CUDA +#define LAMMPS_LAMBDA [=] __device__ +#else +#define LAMMPS_LAMBDA [=] +#endif + #endif From 66cdd3a708b911663cc45e7d6117f09d39784123 Mon Sep 17 00:00:00 2001 From: Dan Ibanez Date: Thu, 22 Dec 2016 08:01:46 -0700 Subject: [PATCH 037/439] draft fix_dpd_energy_kokkos.h --- src/KOKKOS/fix_dpd_energy_kokkos.h | 44 ++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 src/KOKKOS/fix_dpd_energy_kokkos.h diff --git a/src/KOKKOS/fix_dpd_energy_kokkos.h b/src/KOKKOS/fix_dpd_energy_kokkos.h new file mode 100644 index 0000000000..399cf91334 --- /dev/null +++ b/src/KOKKOS/fix_dpd_energy_kokkos.h @@ -0,0 +1,44 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef FIX_CLASS + +FixStyle(dpd/energy/kk,FixDPDenergyKokkos) +FixStyle(dpd/energy/kk/device,FixDPDenergyKokkos) +FixStyle(dpd/energy/kk/host,FixDPDenergyKokkos) + +#else + +#ifndef LMP_FIX_DPDE_H +#define LMP_FIX_DPDE_H + +#include "fix_dpd_energy.h" + +namespace LAMMPS_NS { + +class FixDPDenergyKokkos : public FixDPDEnergy { + public: + FixDPDenergyKokkos(class LAMMPS *, int, char **); + virtual ~FixDPDenergyKokkos() {} + virtual void initial_integrate(int); + virtual void final_integrate(); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ From 53e07996c6929f422568b5473a77cbcaea799c1e Mon Sep 17 00:00:00 2001 From: Dan Ibanez Date: Thu, 22 Dec 2016 08:07:48 -0700 Subject: [PATCH 038/439] save draft of fix_dpd_energy_kokkos.cpp --- src/KOKKOS/fix_dpd_energy_kokkos.cpp | 77 ++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 src/KOKKOS/fix_dpd_energy_kokkos.cpp diff --git a/src/KOKKOS/fix_dpd_energy_kokkos.cpp b/src/KOKKOS/fix_dpd_energy_kokkos.cpp new file mode 100644 index 0000000000..ea93c28b01 --- /dev/null +++ b/src/KOKKOS/fix_dpd_energy_kokkos.cpp @@ -0,0 +1,77 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include +#include +#include "fix_dpd_energy_kokkos.h" +#include "atom_kokkos.h" +#include "force.h" +#include "update.h" +#include "respa.h" +#include "modify.h" +#include "error.h" +#include "pair_dpd_fdt_energy.h" + +using namespace LAMMPS_NS; +using namespace FixConst; + +/* ---------------------------------------------------------------------- */ + +FixDPDenergyKokkos::FixDPDenergyKokkos(LAMMPS *lmp, int narg, char **arg) : + FixDPDenergy(lmp, narg, arg) +{ + kokkosable = 1; + atomKK = (AtomKokkos *) atom; + execution_space = ExecutionSpaceFromDevice::space; + datamask_read = EMPTY_MASK; + datamask_modify = EMPTY_MASK; +} + +/* ---------------------------------------------------------------------- + allow for both per-type and per-atom mass +------------------------------------------------------------------------- */ + +void FixDPDenergyKokkos::initial_integrate(int vflag) +{ + int nlocal = atom->nlocal; + if (igroup == atom->firstgroup) nlocal = atom->nfirst; + + t_efloat_1d uCond = atomKK + double *uCond = atom->uCond; + double *uMech = atom->uMech; + double *duCond = pairDPDE->duCond; + double *duMech = pairDPDE->duMech; + + for (int i = 0; i < nlocal; i++){ + uCond[i] += 0.5*update->dt*duCond[i]; + uMech[i] += 0.5*update->dt*duMech[i]; + } +} + +/* ---------------------------------------------------------------------- */ + +void FixDPDenergyKokkos::final_integrate() +{ + int nlocal = atom->nlocal; + if (igroup == atom->firstgroup) nlocal = atom->nfirst; + + double *uCond = atom->uCond; + double *uMech = atom->uMech; + double *duCond = pairDPDE->duCond; + double *duMech = pairDPDE->duMech; + + for (int i = 0; i < nlocal; i++){ + uCond[i] += 0.5*update->dt*duCond[i]; + uMech[i] += 0.5*update->dt*duMech[i]; + } +} From 04e2f170a33c2162f841b8a21403d95048b86371 Mon Sep 17 00:00:00 2001 From: Dan Ibanez Date: Thu, 22 Dec 2016 09:28:25 -0700 Subject: [PATCH 039/439] first draft fix_dpd_energy_kokkos had to make k_duCond and k_duMech in pair_dpd_fdt_energy_kokkos public so they could be accessed and sync'ed --- src/KOKKOS/fix_dpd_energy_kokkos.cpp | 76 ++++++++++++++----------- src/KOKKOS/fix_dpd_energy_kokkos.h | 10 ++++ src/KOKKOS/pair_dpd_fdt_energy_kokkos.h | 3 +- 3 files changed, 56 insertions(+), 33 deletions(-) diff --git a/src/KOKKOS/fix_dpd_energy_kokkos.cpp b/src/KOKKOS/fix_dpd_energy_kokkos.cpp index ea93c28b01..38671d66ab 100644 --- a/src/KOKKOS/fix_dpd_energy_kokkos.cpp +++ b/src/KOKKOS/fix_dpd_energy_kokkos.cpp @@ -20,14 +20,14 @@ #include "respa.h" #include "modify.h" #include "error.h" -#include "pair_dpd_fdt_energy.h" using namespace LAMMPS_NS; using namespace FixConst; /* ---------------------------------------------------------------------- */ -FixDPDenergyKokkos::FixDPDenergyKokkos(LAMMPS *lmp, int narg, char **arg) : +template +FixDPDenergyKokkos::FixDPDenergyKokkos(LAMMPS *lmp, int narg, char **arg) : FixDPDenergy(lmp, narg, arg) { kokkosable = 1; @@ -35,43 +35,55 @@ FixDPDenergyKokkos::FixDPDenergyKokkos(LAMMPS *lmp, int narg, char **arg) : execution_space = ExecutionSpaceFromDevice::space; datamask_read = EMPTY_MASK; datamask_modify = EMPTY_MASK; -} - -/* ---------------------------------------------------------------------- - allow for both per-type and per-atom mass -------------------------------------------------------------------------- */ - -void FixDPDenergyKokkos::initial_integrate(int vflag) -{ - int nlocal = atom->nlocal; - if (igroup == atom->firstgroup) nlocal = atom->nfirst; - - t_efloat_1d uCond = atomKK - double *uCond = atom->uCond; - double *uMech = atom->uMech; - double *duCond = pairDPDE->duCond; - double *duMech = pairDPDE->duMech; - - for (int i = 0; i < nlocal; i++){ - uCond[i] += 0.5*update->dt*duCond[i]; - uMech[i] += 0.5*update->dt*duMech[i]; - } + pairDPDEKK = dynamic_cast(pairDPDE); + if (!pairDPDEKK) + error->all(FLERR,"Must use pair_style dpd/fdt/energy/kk with fix dpd/energy/kk"); } /* ---------------------------------------------------------------------- */ -void FixDPDenergyKokkos::final_integrate() +template +void FixDPDenergyKokkos::take_half_step() { int nlocal = atom->nlocal; if (igroup == atom->firstgroup) nlocal = atom->nfirst; - double *uCond = atom->uCond; - double *uMech = atom->uMech; - double *duCond = pairDPDE->duCond; - double *duMech = pairDPDE->duMech; + atomKK->sync(execution_space, UCOND_MASK); + t_efloat_1d uCond = atomKK->k_uCond.view(); + atomKK->sync(execution_space, UMECH_MASK); + t_efloat_1d uMech = atomKK->k_uMech.view(); - for (int i = 0; i < nlocal; i++){ - uCond[i] += 0.5*update->dt*duCond[i]; - uMech[i] += 0.5*update->dt*duMech[i]; - } + pairDPDEKK->k_duCond.sync(); + t_efloat_1d_const duCond = pairDPDEKK->k_duCond.view(); + pairDPDEKK->k_duMech.sync(); + t_efloat_1d_const duMech = pairDPDEKK->k_duMech.view(); + + auto dt = update->dt; + + Kokkos::parallel_for(nlocal, LAMMPS_LAMBDA(int i) { + uCond(i) += 0.5*dt*duCond(i); + uMech(i) += 0.5*dt*duMech(i); + }); + + atomKK->modified(execution_space, UCOND_MASK); + atomKK->modified(execution_space, UMECH_MASK); + //should not be needed once everything is Kokkos + atomKK->sync(ExecutionSpaceFromDevice, UCOND_MASK); + atomKK->sync(ExecutionSpaceFromDevice, UMECH_MASK); +} + +/* ---------------------------------------------------------------------- */ + +template +void FixDPDenergyKokkos::initial_integrate(int) +{ + take_half_step(); +} + +/* ---------------------------------------------------------------------- */ + +template +void FixDPDenergyKokkos::final_integrate() +{ + take_half_step(); } diff --git a/src/KOKKOS/fix_dpd_energy_kokkos.h b/src/KOKKOS/fix_dpd_energy_kokkos.h index 399cf91334..e5ae2b0127 100644 --- a/src/KOKKOS/fix_dpd_energy_kokkos.h +++ b/src/KOKKOS/fix_dpd_energy_kokkos.h @@ -23,15 +23,21 @@ FixStyle(dpd/energy/kk/host,FixDPDenergyKokkos) #define LMP_FIX_DPDE_H #include "fix_dpd_energy.h" +#include "pair_dpd_dft_energy_kokkos.h" namespace LAMMPS_NS { +template class FixDPDenergyKokkos : public FixDPDEnergy { public: FixDPDenergyKokkos(class LAMMPS *, int, char **); virtual ~FixDPDenergyKokkos() {} virtual void initial_integrate(int); virtual void final_integrate(); + + protected: + void take_half_step(); + PairDPDfdtEnergyKokkos* pairDPDEKK; }; } @@ -41,4 +47,8 @@ class FixDPDenergyKokkos : public FixDPDEnergy { /* ERROR/WARNING messages: +E: Must use pair_style dpd/fdt/energy/kk with fix dpd/energy/kk + +Self-explanatory. + */ diff --git a/src/KOKKOS/pair_dpd_fdt_energy_kokkos.h b/src/KOKKOS/pair_dpd_fdt_energy_kokkos.h index 8e7d01de2a..41360091bc 100644 --- a/src/KOKKOS/pair_dpd_fdt_energy_kokkos.h +++ b/src/KOKKOS/pair_dpd_fdt_energy_kokkos.h @@ -84,6 +84,8 @@ class PairDPDfdtEnergyKokkos : public PairDPDfdtEnergy { F_FLOAT cut,a0,sigma,kappa; }; + DAT::tdual_efloat_1d k_duCond,k_duMech; + protected: int eflag,vflag; int nlocal,neighflag; @@ -110,7 +112,6 @@ class PairDPDfdtEnergyKokkos : public PairDPDfdtEnergy { typename ArrayTypes::t_float_1d_randomread mass; double *rmass; typename AT::t_efloat_1d dpdTheta; - DAT::tdual_efloat_1d k_duCond,k_duMech; typename AT::t_efloat_1d d_duCond,d_duMech; HAT::t_efloat_1d h_duCond,h_duMech; From 89795b3653ea6270b90911cf30b3777312af5828 Mon Sep 17 00:00:00 2001 From: Dan Ibanez Date: Thu, 22 Dec 2016 10:18:30 -0700 Subject: [PATCH 040/439] got fix_dpd_energy_kokkos to compile --- src/KOKKOS/Install.sh | 2 ++ src/KOKKOS/fix_dpd_energy_kokkos.cpp | 30 ++++++++++++++++++---------- src/KOKKOS/fix_dpd_energy_kokkos.h | 8 ++++---- 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/src/KOKKOS/Install.sh b/src/KOKKOS/Install.sh index 17e9f93c9d..96ec348b30 100644 --- a/src/KOKKOS/Install.sh +++ b/src/KOKKOS/Install.sh @@ -99,6 +99,8 @@ action fix_setforce_kokkos.cpp action fix_setforce_kokkos.h action fix_wall_reflect_kokkos.cpp action fix_wall_reflect_kokkos.h +action fix_dpd_energy_kokkos.cpp fix_dpd_energy.cpp +action fix_dpd_energy_kokkos.h fix_dpd_energy.h action gridcomm_kokkos.cpp gridcomm.cpp action gridcomm_kokkos.h gridcomm.h action improper_harmonic_kokkos.cpp improper_harmonic.cpp diff --git a/src/KOKKOS/fix_dpd_energy_kokkos.cpp b/src/KOKKOS/fix_dpd_energy_kokkos.cpp index 38671d66ab..6ab0b215b4 100644 --- a/src/KOKKOS/fix_dpd_energy_kokkos.cpp +++ b/src/KOKKOS/fix_dpd_energy_kokkos.cpp @@ -14,6 +14,7 @@ #include #include #include "fix_dpd_energy_kokkos.h" +#include "atom_masks.h" #include "atom_kokkos.h" #include "force.h" #include "update.h" @@ -48,15 +49,17 @@ void FixDPDenergyKokkos::take_half_step() int nlocal = atom->nlocal; if (igroup == atom->firstgroup) nlocal = atom->nfirst; - atomKK->sync(execution_space, UCOND_MASK); - t_efloat_1d uCond = atomKK->k_uCond.view(); - atomKK->sync(execution_space, UMECH_MASK); - t_efloat_1d uMech = atomKK->k_uMech.view(); + using AT = ArrayTypes; - pairDPDEKK->k_duCond.sync(); - t_efloat_1d_const duCond = pairDPDEKK->k_duCond.view(); - pairDPDEKK->k_duMech.sync(); - t_efloat_1d_const duMech = pairDPDEKK->k_duMech.view(); + atomKK->sync(execution_space, UCOND_MASK); + typename AT::t_efloat_1d uCond = atomKK->k_uCond.view(); + atomKK->sync(execution_space, UMECH_MASK); + typename AT::t_efloat_1d uMech = atomKK->k_uMech.view(); + + pairDPDEKK->k_duCond.template sync(); + typename AT::t_efloat_1d_const duCond = pairDPDEKK->k_duCond.template view(); + pairDPDEKK->k_duMech.template sync(); + typename AT::t_efloat_1d_const duMech = pairDPDEKK->k_duMech.template view(); auto dt = update->dt; @@ -68,8 +71,8 @@ void FixDPDenergyKokkos::take_half_step() atomKK->modified(execution_space, UCOND_MASK); atomKK->modified(execution_space, UMECH_MASK); //should not be needed once everything is Kokkos - atomKK->sync(ExecutionSpaceFromDevice, UCOND_MASK); - atomKK->sync(ExecutionSpaceFromDevice, UMECH_MASK); + atomKK->sync(ExecutionSpaceFromDevice::space, UCOND_MASK); + atomKK->sync(ExecutionSpaceFromDevice::space, UMECH_MASK); } /* ---------------------------------------------------------------------- */ @@ -87,3 +90,10 @@ void FixDPDenergyKokkos::final_integrate() { take_half_step(); } + +namespace LAMMPS_NS { +template class FixDPDenergyKokkos; +#ifdef KOKKOS_HAVE_CUDA +template class FixDPDenergyKokkos; +#endif +} diff --git a/src/KOKKOS/fix_dpd_energy_kokkos.h b/src/KOKKOS/fix_dpd_energy_kokkos.h index e5ae2b0127..0c43ecf422 100644 --- a/src/KOKKOS/fix_dpd_energy_kokkos.h +++ b/src/KOKKOS/fix_dpd_energy_kokkos.h @@ -19,16 +19,16 @@ FixStyle(dpd/energy/kk/host,FixDPDenergyKokkos) #else -#ifndef LMP_FIX_DPDE_H -#define LMP_FIX_DPDE_H +#ifndef LMP_FIX_DPDE_KOKKOS_H +#define LMP_FIX_DPDE_KOKKOS_H #include "fix_dpd_energy.h" -#include "pair_dpd_dft_energy_kokkos.h" +#include "pair_dpd_fdt_energy_kokkos.h" namespace LAMMPS_NS { template -class FixDPDenergyKokkos : public FixDPDEnergy { +class FixDPDenergyKokkos : public FixDPDenergy { public: FixDPDenergyKokkos(class LAMMPS *, int, char **); virtual ~FixDPDenergyKokkos() {} From e632f8597ac7a5229d51e8f12bfbd776f9369aee Mon Sep 17 00:00:00 2001 From: Dan Ibanez Date: Tue, 3 Jan 2017 09:04:10 -0700 Subject: [PATCH 041/439] fix warning about enum comparisons --- src/KOKKOS/pair_table_kokkos.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/KOKKOS/pair_table_kokkos.h b/src/KOKKOS/pair_table_kokkos.h index 4d3a9ec106..e768c97164 100644 --- a/src/KOKKOS/pair_table_kokkos.h +++ b/src/KOKKOS/pair_table_kokkos.h @@ -31,7 +31,7 @@ namespace LAMMPS_NS { template struct S_TableCompute { - enum {TabStyle = TABSTYLE}; + static constexpr int TabStyle = TABSTYLE; }; template From dae132c77099b2b5a895b3c08ee7df7bd11a74d4 Mon Sep 17 00:00:00 2001 From: Dan Ibanez Date: Tue, 3 Jan 2017 10:53:10 -0700 Subject: [PATCH 042/439] place newline at end of file --- src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp b/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp index 133d366fbc..4f04da2f3b 100644 --- a/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp +++ b/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp @@ -682,4 +682,4 @@ template class PairDPDfdtEnergyKokkos; #ifdef KOKKOS_HAVE_CUDA template class PairDPDfdtEnergyKokkos; #endif -} \ No newline at end of file +} From e3ebd8e7f1793caa1b7f686f6d7ae9a671be25ac Mon Sep 17 00:00:00 2001 From: Dan Ibanez Date: Tue, 3 Jan 2017 09:15:30 -0700 Subject: [PATCH 043/439] remove syncs that shouldn't be needed --- src/KOKKOS/fix_dpd_energy_kokkos.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/KOKKOS/fix_dpd_energy_kokkos.cpp b/src/KOKKOS/fix_dpd_energy_kokkos.cpp index 6ab0b215b4..e6878afed4 100644 --- a/src/KOKKOS/fix_dpd_energy_kokkos.cpp +++ b/src/KOKKOS/fix_dpd_energy_kokkos.cpp @@ -70,9 +70,6 @@ void FixDPDenergyKokkos::take_half_step() atomKK->modified(execution_space, UCOND_MASK); atomKK->modified(execution_space, UMECH_MASK); - //should not be needed once everything is Kokkos - atomKK->sync(ExecutionSpaceFromDevice::space, UCOND_MASK); - atomKK->sync(ExecutionSpaceFromDevice::space, UMECH_MASK); } /* ---------------------------------------------------------------------- */ From 6d7607a6ade5299b021190373add4a1d50765aaa Mon Sep 17 00:00:00 2001 From: Dan Ibanez Date: Tue, 3 Jan 2017 11:13:46 -0700 Subject: [PATCH 044/439] member function containing lambdas must be public --- src/KOKKOS/fix_dpd_energy_kokkos.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/KOKKOS/fix_dpd_energy_kokkos.h b/src/KOKKOS/fix_dpd_energy_kokkos.h index 0c43ecf422..ebf3a796fe 100644 --- a/src/KOKKOS/fix_dpd_energy_kokkos.h +++ b/src/KOKKOS/fix_dpd_energy_kokkos.h @@ -35,8 +35,8 @@ class FixDPDenergyKokkos : public FixDPDenergy { virtual void initial_integrate(int); virtual void final_integrate(); - protected: void take_half_step(); + protected: PairDPDfdtEnergyKokkos* pairDPDEKK; }; From ae0e882cde4c74c5cae0af09fa5fd46c783fad24 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 3 Jan 2017 11:51:28 -0700 Subject: [PATCH 045/439] Updating pair_multi_lucy_rx_kokkos to USER-DPD changes --- src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp | 111 ++++++++++++++++------- src/KOKKOS/pair_multi_lucy_rx_kokkos.h | 8 +- 2 files changed, 82 insertions(+), 37 deletions(-) diff --git a/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp b/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp index 1dc8ccbae9..7cff630cb0 100644 --- a/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp +++ b/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp @@ -45,6 +45,12 @@ enum{NONE,RLINEAR,RSQ}; #define MAXLINE 1024 +#ifdef DBL_EPSILON + #define MY_EPSILON (10.0*DBL_EPSILON) +#else + #define MY_EPSILON (10.0*2.220446049250313e-16) +#endif + #define oneFluidParameter (-1) #define isOneFluid(_site) ( (_site) == oneFluidParameter ) @@ -187,12 +193,12 @@ void PairMultiLucyRXKokkos::compute_style(int eflag_in, int vflag_in { const int ntotal = nlocal + nghost; - d_fractionOld1 = typename AT::t_float_1d("PairMultiLucyRX::fractionOld1",ntotal); - d_fractionOld2 = typename AT::t_float_1d("PairMultiLucyRX::fractionOld2",ntotal); - d_fraction1 = typename AT::t_float_1d("PairMultiLucyRX::fraction1",ntotal); - d_fraction2 = typename AT::t_float_1d("PairMultiLucyRX::fraction2",ntotal); + d_mixWtSite1old = typename AT::t_float_1d("PairMultiLucyRX::mixWtSite1old",ntotal); + d_mixWtSite2old = typename AT::t_float_1d("PairMultiLucyRX::mixWtSite2old",ntotal); + d_mixWtSite1 = typename AT::t_float_1d("PairMultiLucyRX::mixWtSite1",ntotal); + d_mixWtSite2 = typename AT::t_float_1d("PairMultiLucyRX::mixWtSite2",ntotal); - Kokkos::parallel_for(Kokkos::RangePolicy(0,ntotal),*this); + Kokkos::parallel_for(Kokkos::RangePolicy(0,ntotal),*this); } const int inum = list->inum; @@ -259,8 +265,8 @@ void PairMultiLucyRXKokkos::compute_style(int eflag_in, int vflag_in template KOKKOS_INLINE_FUNCTION -void PairMultiLucyRXKokkos::operator()(TagPairMultiLucyRXgetParams, const int &i) const { - getParams(i, d_fractionOld1[i], d_fractionOld2[i], d_fraction1[i], d_fraction2[i]); +void PairMultiLucyRXKokkos::operator()(TagPairMultiLucyRXgetMixingWeights, const int &i) const { + getMixingWeights(i, d_mixWtSite1old[i], d_mixWtSite2old[i], d_mixWtSite1[i], d_mixWtSite2[i]); } template @@ -275,9 +281,9 @@ void PairMultiLucyRXKokkos::operator()(TagPairMultiLucyRXCompute::operator()(TagPairMultiLucyRXCompute::operator()(TagPairMultiLucyRXCompute::operator()(TagPairMultiLucyRXCompute::operator()(TagPairMultiLucyRXCompute::operator()(TagPairMultiLucyRXComputeLoca template KOKKOS_INLINE_FUNCTION -void PairMultiLucyRXKokkos::getParams(int id, double &fractionOld1, double &fractionOld2, double &fraction1, double &fraction2) const +void PairMultiLucyRXKokkos::getMixingWeights(int id, double &mixWtSite1old, double &mixWtSite2old, double &mixWtSite1, double &mixWtSite2) const { - double fractionOld, fraction; + double fractionOFAold, fractionOFA; + double fractionOld1, fraction1; + double fractionOld2, fraction2; + double nMoleculesOFAold, nMoleculesOFA; + double nMoleculesOld1, nMolecules1; + double nMoleculesOld2, nMolecules2; double nTotal, nTotalOld; @@ -579,32 +590,56 @@ void PairMultiLucyRXKokkos::getParams(int id, double &fractionOld1, } if (isOneFluid(isite1) == false){ - fractionOld1 = dvector(isite1+nspecies,id)/nTotalOld; - fraction1 = dvector(isite1,id)/nTotal; + nMoleculesOld1 = dvector(isite1+nspecies,id); + nMolecules1 = dvector(isite1,id); + fractionOld1 = nMoleculesOld1/nTotalOld; + fraction1 = nMolecules1/nTotal; } if (isOneFluid(isite2) == false){ - fractionOld2 = dvector(isite2+nspecies,id)/nTotalOld; - fraction2 = dvector(isite2,id)/nTotal; + nMoleculesOld2 = dvector(isite2+nspecies,id); + nMolecules2 = dvector(isite2,id); + fractionOld2 = nMoleculesOld2/nTotalOld; + fraction2 = nMolecules2/nTotal; } if (isOneFluid(isite1) || isOneFluid(isite2)){ - fractionOld = 0.0; - fraction = 0.0; + nMoleculesOFAold = 0.0; + nMoleculesOFA = 0.0; + fractionOFAold = 0.0; + fractionOFA = 0.0; for (int ispecies = 0; ispecies < nspecies; ispecies++){ if (isite1 == ispecies || isite2 == ispecies) continue; - fractionOld += dvector(ispecies+nspecies,id) / nTotalOld; - fraction += dvector(ispecies,id) / nTotal; + nMoleculesOFAold += dvector(ispecies+nspecies,id); + nMoleculesOFA += dvector(ispecies,id); + fractionOFAold += dvector(ispecies+nspecies,id) / nTotalOld; + fractionOFA += dvector(ispecies,id) / nTotal; } if (isOneFluid(isite1)){ - fractionOld1 = fractionOld; - fraction1 = fraction; + nMoleculesOld1 = 1.0-(nTotalOld-nMoleculesOFAold); + nMolecules1 = 1.0-(nTotal-nMoleculesOFA); + fractionOld1 = fractionOFAold; + fraction1 = fractionOFA; } if (isOneFluid(isite2)){ - fractionOld2 = fractionOld; - fraction2 = fraction; + nMoleculesOld2 = 1.0-(nTotalOld-nMoleculesOFAold); + nMolecules2 = 1.0-(nTotal-nMoleculesOFA); + fractionOld2 = fractionOFAold; + fraction2 = fractionOFA; } } + + if(fractionalWeighting){ + mixWtSite1old = fractionOld1; + mixWtSite1 = fraction1; + mixWtSite2old = fractionOld2; + mixWtSite2 = fraction2; + } else { + mixWtSite1old = nMoleculesOld1; + mixWtSite1 = nMolecules1; + mixWtSite2old = nMoleculesOld2; + mixWtSite2 = nMolecules2; + } } /* ---------------------------------------------------------------------- */ @@ -897,6 +932,16 @@ void PairMultiLucyRXKokkos::settings(int narg, char **arg) tablength = force->inumeric(FLERR,arg[1]); if (tablength < 2) error->all(FLERR,"Illegal number of pair table entries"); + // optional keywords + + int iarg = 2; + while (iarg < narg) { + if (strcmp(arg[iarg],"fractional") == 0) fractionalWeighting = true; + else if (strcmp(arg[iarg],"molecular") == 0) fractionalWeighting = false; + else error->all(FLERR,"Illegal pair_style command"); + iarg++; + } + // delete old tables, since cannot just change settings for (int m = 0; m < ntables; m++) free_table(&tables[m]); diff --git a/src/KOKKOS/pair_multi_lucy_rx_kokkos.h b/src/KOKKOS/pair_multi_lucy_rx_kokkos.h index a6622ac4ec..1e84e3efd8 100644 --- a/src/KOKKOS/pair_multi_lucy_rx_kokkos.h +++ b/src/KOKKOS/pair_multi_lucy_rx_kokkos.h @@ -32,7 +32,7 @@ namespace LAMMPS_NS { struct TagPairMultiLucyRXPackForwardComm{}; struct TagPairMultiLucyRXUnpackForwardComm{}; -struct TagPairMultiLucyRXgetParams{}; +struct TagPairMultiLucyRXgetMixingWeights{}; template struct TagPairMultiLucyRXCompute{}; @@ -75,7 +75,7 @@ class PairMultiLucyRXKokkos : public PairMultiLucyRX { void operator()(TagPairMultiLucyRXUnpackForwardComm, const int&) const; KOKKOS_INLINE_FUNCTION - void operator()(TagPairMultiLucyRXgetParams, const int&) const; + void operator()(TagPairMultiLucyRXgetMixingWeights, const int&) const; template KOKKOS_INLINE_FUNCTION @@ -154,9 +154,9 @@ class PairMultiLucyRXKokkos : public PairMultiLucyRX { void create_kokkos_tables(); KOKKOS_INLINE_FUNCTION - void getParams(int, double &, double &, double &, double &) const; + void getMixingWeights(int, double &, double &, double &, double &) const; - typename AT::t_float_1d d_fractionOld1,d_fractionOld2,d_fraction1,d_fraction2; + typename AT::t_float_1d d_mixWtSite1old,d_mixWtSite2old,d_mixWtSite1,d_mixWtSite2; typename AT::t_x_array_randomread x; typename AT::t_f_array f; From a4271ae8c5c2367cfc33f08b4994849a0cccd40b Mon Sep 17 00:00:00 2001 From: Christopher Stone Date: Wed, 4 Jan 2017 15:13:46 -0500 Subject: [PATCH 046/439] Added a Makefile for AFRL Thunder. --- src/MAKE/MACHINES/Makefile.afrl_thunder | 116 ++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 src/MAKE/MACHINES/Makefile.afrl_thunder diff --git a/src/MAKE/MACHINES/Makefile.afrl_thunder b/src/MAKE/MACHINES/Makefile.afrl_thunder new file mode 100644 index 0000000000..ceeec48870 --- /dev/null +++ b/src/MAKE/MACHINES/Makefile.afrl_thunder @@ -0,0 +1,116 @@ +# mpi = MPI with its default compiler + +SHELL = /bin/sh + +# --------------------------------------------------------------------- +# compiler/linker settings +# specify flags and libraries needed for your compiler + +CC = mpicxx +CCFLAGS = -g -O3 -Wall -Wextra -frounding-math -fsignaling-nans -march=native +SHFLAGS = -shared -MD -mcmodel=medium -fpic -fPIC +DEPFLAGS = -M + +LINK = mpicxx +LINKFLAGS = -g -O +LIB = +SIZE = size + +ARCHIVE = ar +ARFLAGS = -rc +SHLIBFLAGS = -shared + +# --------------------------------------------------------------------- +# LAMMPS-specific settings, all OPTIONAL +# specify settings for LAMMPS features you will use +# if you change any -D setting, do full re-compile after "make clean" + +# LAMMPS ifdef settings +# see possible settings in Section 2.2 (step 4) of manual + +LMP_INC = -DLAMMPS_GZIP +#LMP_INC += -DLAMMPS_JPEG +LMP_INC += -DLAMMPS_MEMALIGN=64 + +# MPI library +# see discussion in Section 2.2 (step 5) of manual +# MPI wrapper compiler/linker can provide this info +# can point to dummy MPI library in src/STUBS as in Makefile.serial +# use -D MPICH and OMPI settings in INC to avoid C++ lib conflicts +# INC = path for mpi.h, MPI compiler settings +# PATH = path for MPI library +# LIB = name of MPI library + +MPI_INC = -DMPICH_SKIP_MPICXX -DOMPI_SKIP_MPICXX=1 +MPI_PATH = +MPI_LIB = + +# FFT library +# see discussion in Section 2.2 (step 6) of manual +# can be left blank to use provided KISS FFT library +# INC = -DFFT setting, e.g. -DFFT_FFTW, FFT compiler settings +# PATH = path for FFT library +# LIB = name of FFT library + +FFT_INC = +FFT_PATH = +FFT_LIB = + +# JPEG and/or PNG library +# see discussion in Section 2.2 (step 7) of manual +# only needed if -DLAMMPS_JPEG or -DLAMMPS_PNG listed with LMP_INC +# INC = path(s) for jpeglib.h and/or png.h +# PATH = path(s) for JPEG library and/or PNG library +# LIB = name(s) of JPEG library and/or PNG library + +JPG_INC = +JPG_PATH = +JPG_LIB = + +# --------------------------------------------------------------------- +# build rules and dependencies +# do not edit this section + +include Makefile.package.settings +include Makefile.package + +EXTRA_INC = $(LMP_INC) $(PKG_INC) $(MPI_INC) $(FFT_INC) $(JPG_INC) $(PKG_SYSINC) +EXTRA_PATH = $(PKG_PATH) $(MPI_PATH) $(FFT_PATH) $(JPG_PATH) $(PKG_SYSPATH) +EXTRA_LIB = $(PKG_LIB) $(MPI_LIB) $(FFT_LIB) $(JPG_LIB) $(PKG_SYSLIB) +EXTRA_CPP_DEPENDS = $(PKG_CPP_DEPENDS) +EXTRA_LINK_DEPENDS = $(PKG_LINK_DEPENDS) + +# Path to src files + +vpath %.cpp .. +vpath %.h .. + +# Link target + +$(EXE): $(OBJ) $(EXTRA_LINK_DEPENDS) + $(LINK) $(LINKFLAGS) $(EXTRA_PATH) $(OBJ) $(EXTRA_LIB) $(LIB) -o $(EXE) + $(SIZE) $(EXE) + +# Library targets + +lib: $(OBJ) $(EXTRA_LINK_DEPENDS) + $(ARCHIVE) $(ARFLAGS) $(EXE) $(OBJ) + +shlib: $(OBJ) $(EXTRA_LINK_DEPENDS) + $(CC) $(CCFLAGS) $(SHFLAGS) $(SHLIBFLAGS) $(EXTRA_PATH) -o $(EXE) \ + $(OBJ) $(EXTRA_LIB) $(LIB) + +# Compilation rules + +%.o:%.cpp + $(CC) $(CCFLAGS) $(SHFLAGS) $(EXTRA_INC) -c $< + +# Individual dependencies + +depend : fastdep.exe $(SRC) + @./fastdep.exe $(EXTRA_INC) -- $^ > .depend || exit 1 + +fastdep.exe: ../DEPEND/fastdep.c + cc -O -o $@ $< + +sinclude .depend From 8503ac22a859abb2617b5fe9bab2e5db6ec0803f Mon Sep 17 00:00:00 2001 From: Christopher Stone Date: Thu, 5 Jan 2017 13:58:11 -0500 Subject: [PATCH 047/439] Fixed error->all instead of error->one bug in USER-DPD/fix_shardlow.cpp. During dynamic load balancing, the subdomains will not be uniform so the bbox size test in USER-DPD/fix_shardlow.cpp may only be called by one rank. Using error->one allows any rank to stop the simulation in this scenario. Added rcut and bbox information to help in diagnostics. --- src/USER-DPD/fix_shardlow.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/USER-DPD/fix_shardlow.cpp b/src/USER-DPD/fix_shardlow.cpp index 541f4ba3c3..108b82a5b6 100644 --- a/src/USER-DPD/fix_shardlow.cpp +++ b/src/USER-DPD/fix_shardlow.cpp @@ -445,7 +445,12 @@ void FixShardlow::initial_integrate(int vflag) error->all(FLERR,"Fix shardlow does not yet support triclinic geometries"); if(rcut >= bbx || rcut >= bby || rcut>= bbz ) - error->all(FLERR,"Shardlow algorithm requires sub-domain length > 2*(rcut+skin). Either reduce the number of processors requested, or change the cutoff/skin\n"); + { + char fmt[] = {"Shardlow algorithm requires sub-domain length > 2*(rcut+skin). Either reduce the number of processors requested, or change the cutoff/skin: rcut= %e bbx= %e bby= %e bbz= %e\n"}; + char *msg = (char *) malloc(sizeof(fmt) + 4*15); + sprintf(msg, fmt, rcut, bbx, bby, bbz); + error->one(FLERR, msg); + } // Allocate memory for v_t0 to hold the initial velocities for the ghosts v_t0 = (double (*)[3]) memory->smalloc(sizeof(double)*3*nghost, "FixShardlow:v_t0"); From 332372dec2caab9d6f8fdcf3c87d3d6b37466999 Mon Sep 17 00:00:00 2001 From: Christopher Stone Date: Thu, 5 Jan 2017 14:03:16 -0500 Subject: [PATCH 048/439] Renamed Makefile.afrl_thunder to Makefile.icex to be more general. --- src/MAKE/MACHINES/{Makefile.afrl_thunder => Makefile.icex} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/MAKE/MACHINES/{Makefile.afrl_thunder => Makefile.icex} (100%) diff --git a/src/MAKE/MACHINES/Makefile.afrl_thunder b/src/MAKE/MACHINES/Makefile.icex similarity index 100% rename from src/MAKE/MACHINES/Makefile.afrl_thunder rename to src/MAKE/MACHINES/Makefile.icex From 19f2d2d1ecb13dae5ef26f16c8ba75b935c5fcf5 Mon Sep 17 00:00:00 2001 From: Dan Ibanez Date: Thu, 5 Jan 2017 15:22:59 -0700 Subject: [PATCH 049/439] fix many warnings in pair_dpd_fdt_energy_kokkos one Kokkos kernel was not annotated consistently, STACKPARAMS was essentially uninitialized and confused with a local variable, plus lots of variables were unused in some of the Kokkos kernels. --- src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp | 14 +++----------- src/KOKKOS/pair_dpd_fdt_energy_kokkos.h | 1 + 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp b/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp index 4f04da2f3b..5de2b38ed0 100644 --- a/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp +++ b/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp @@ -49,6 +49,7 @@ PairDPDfdtEnergyKokkos::PairDPDfdtEnergyKokkos(LAMMPS *lmp) : execution_space = ExecutionSpaceFromDevice::space; datamask_read = EMPTY_MASK; datamask_modify = EMPTY_MASK; + STACKPARAMS = 0; } /* ---------------------------------------------------------------------- */ @@ -164,8 +165,6 @@ void PairDPDfdtEnergyKokkos::compute(int eflag_in, int vflag_in) boltz = force->boltz; ftm2v = force->ftm2v; - int STACKPARAMS = 0; // optimize - // loop over neighbors of my atoms EV_FLOAT ev; @@ -278,14 +277,7 @@ void PairDPDfdtEnergyKokkos::operator()(TagPairDPDfdtEnergyComputeSp int i,j,jj,inum,jnum,itype,jtype; double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair; - double vxtmp,vytmp,vztmp,delvx,delvy,delvz; - double rsq,r,rinv,wd,wr,factor_dpd,uTmp; - double dot,randnum; - - double kappa_ij, alpha_ij, theta_ij, gamma_ij; - double mass_i, mass_j; - double massinv_i, massinv_j; - double randPair, mu_ij; + double rsq,r,rinv,wd,wr,factor_dpd; i = d_ilist[ii]; xtmp = x(i,0); @@ -369,7 +361,7 @@ void PairDPDfdtEnergyKokkos::operator()(TagPairDPDfdtEnergyComputeNo Kokkos::View::value> > a_duCond = d_duCond; Kokkos::View::value> > a_duMech = d_duMech; - int i,j,jj,inum,jnum,itype,jtype; + int i,j,jj,jnum,itype,jtype; double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair; double vxtmp,vytmp,vztmp,delvx,delvy,delvz; double rsq,r,rinv,wd,wr,factor_dpd,uTmp; diff --git a/src/KOKKOS/pair_dpd_fdt_energy_kokkos.h b/src/KOKKOS/pair_dpd_fdt_energy_kokkos.h index 41360091bc..2c2b78ac57 100644 --- a/src/KOKKOS/pair_dpd_fdt_energy_kokkos.h +++ b/src/KOKKOS/pair_dpd_fdt_energy_kokkos.h @@ -51,6 +51,7 @@ class PairDPDfdtEnergyKokkos : public PairDPDfdtEnergy { void init_style(); double init_one(int, int); + KOKKOS_INLINE_FUNCTION void operator()(TagPairDPDfdtEnergyZero, const int&) const; template From 318ab9a18506143905a0692f33dd9ac6e22ac4d0 Mon Sep 17 00:00:00 2001 From: Dan Ibanez Date: Tue, 3 Jan 2017 16:33:15 -0700 Subject: [PATCH 050/439] trying PairTableRX : public PairTable saves a lot of duplicate code --- src/USER-DPD/pair_table_rx.cpp | 662 +-------------------------------- src/USER-DPD/pair_table_rx.h | 40 +- src/pair_table.cpp | 4 +- src/pair_table.h | 7 +- 4 files changed, 13 insertions(+), 700 deletions(-) diff --git a/src/USER-DPD/pair_table_rx.cpp b/src/USER-DPD/pair_table_rx.cpp index e3cacc6155..c8d59c052d 100644 --- a/src/USER-DPD/pair_table_rx.cpp +++ b/src/USER-DPD/pair_table_rx.cpp @@ -31,10 +31,6 @@ using namespace LAMMPS_NS; -enum{NONE,RLINEAR,RSQ,BMP}; - -#define MAXLINE 1024 - #ifdef DBL_EPSILON #define MY_EPSILON (10.0*DBL_EPSILON) #else @@ -46,31 +42,13 @@ enum{NONE,RLINEAR,RSQ,BMP}; /* ---------------------------------------------------------------------- */ -PairTableRX::PairTableRX(LAMMPS *lmp) : Pair(lmp) +PairTableRX::PairTableRX(LAMMPS *lmp) : PairTable(lmp) { - ntables = 0; - tables = NULL; fractionalWeighting = true; } /* ---------------------------------------------------------------------- */ -PairTableRX::~PairTableRX() -{ - if (copymode) return; - - for (int m = 0; m < ntables; m++) free_table(&tables[m]); - memory->sfree(tables); - - if (allocated) { - memory->destroy(setflag); - memory->destroy(cutsq); - memory->destroy(tabindex); - } -} - -/* ---------------------------------------------------------------------- */ - void PairTableRX::compute(int eflag, int vflag) { int i,j,ii,jj,inum,jnum,itype,jtype,itable; @@ -254,24 +232,6 @@ void PairTableRX::compute(int eflag, int vflag) memory->destroy(mixWtSite2); } -/* ---------------------------------------------------------------------- - allocate all arrays -------------------------------------------------------------------------- */ - -void PairTableRX::allocate() -{ - allocated = 1; - const int nt = atom->ntypes + 1; - - memory->create(setflag,nt,nt,"pair:setflag"); - memory->create(cutsq,nt,nt,"pair:cutsq"); - memory->create(tabindex,nt,nt,"pair:tabindex"); - - memset(&setflag[0][0],0,nt*nt*sizeof(int)); - memset(&cutsq[0][0],0,nt*nt*sizeof(double)); - memset(&tabindex[0][0],0,nt*nt*sizeof(int)); -} - /* ---------------------------------------------------------------------- global settings ------------------------------------------------------------------------- */ @@ -301,8 +261,8 @@ void PairTableRX::settings(int narg, char **arg) else if (strcmp(arg[iarg],"msm") == 0) msmflag = 1; else if (strcmp(arg[iarg],"dispersion") == 0) dispersionflag = 1; else if (strcmp(arg[iarg],"tip4p") == 0) tip4pflag = 1; - else if (strcmp(arg[iarg],"fractional") == 0) fractionalWeighting = true; - else if (strcmp(arg[iarg],"molecular") == 0) fractionalWeighting = false; + else if (strcmp(arg[iarg],"fractional") == 0) fractionalWeighting = true; + else if (strcmp(arg[iarg],"molecular") == 0) fractionalWeighting = false; else error->all(FLERR,"Illegal pair_style command"); iarg++; } @@ -464,602 +424,6 @@ void PairTableRX::coeff(int narg, char **arg) } -/* ---------------------------------------------------------------------- - init for one type pair i,j and corresponding j,i -------------------------------------------------------------------------- */ - -double PairTableRX::init_one(int i, int j) -{ - if (setflag[i][j] == 0) error->all(FLERR,"All pair coeffs are not set"); - - tabindex[j][i] = tabindex[i][j]; - - return tables[tabindex[i][j]].cut; -} - -/* ---------------------------------------------------------------------- - read a table section from a tabulated potential file - only called by proc 0 - this function sets these values in Table: - ninput,rfile,efile,ffile,rflag,rlo,rhi,fpflag,fplo,fphi,ntablebits -------------------------------------------------------------------------- */ - -void PairTableRX::read_table(Table *tb, char *file, char *keyword) -{ - char line[MAXLINE]; - - // open file - - FILE *fp = force->open_potential(file); - if (fp == NULL) { - char str[128]; - sprintf(str,"Cannot open file %s",file); - error->one(FLERR,str); - } - - // loop until section found with matching keyword - - while (1) { - if (fgets(line,MAXLINE,fp) == NULL) - error->one(FLERR,"Did not find keyword in table file"); - if (strspn(line," \t\n\r") == strlen(line)) continue; // blank line - if (line[0] == '#') continue; // comment - char *word = strtok(line," \t\n\r"); - if (strcmp(word,keyword) == 0) break; // matching keyword - fgets(line,MAXLINE,fp); // no match, skip section - param_extract(tb,line); - fgets(line,MAXLINE,fp); - for (int i = 0; i < tb->ninput; i++) fgets(line,MAXLINE,fp); - } - - // read args on 2nd line of section - // allocate table arrays for file values - - fgets(line,MAXLINE,fp); - param_extract(tb,line); - memory->create(tb->rfile,tb->ninput,"pair:rfile"); - memory->create(tb->efile,tb->ninput,"pair:efile"); - memory->create(tb->ffile,tb->ninput,"pair:ffile"); - - // setup bitmap parameters for table to read in - - tb->ntablebits = 0; - int masklo,maskhi,nmask,nshiftbits; - if (tb->rflag == BMP) { - while (1 << tb->ntablebits < tb->ninput) tb->ntablebits++; - if (1 << tb->ntablebits != tb->ninput) - error->one(FLERR,"Bitmapped table is incorrect length in table file"); - init_bitmap(tb->rlo,tb->rhi,tb->ntablebits,masklo,maskhi,nmask,nshiftbits); - } - - // read r,e,f table values from file - // if rflag set, compute r - // if rflag not set, use r from file - - int itmp; - double rtmp; - union_int_float_t rsq_lookup; - - fgets(line,MAXLINE,fp); - for (int i = 0; i < tb->ninput; i++) { - fgets(line,MAXLINE,fp); - sscanf(line,"%d %lg %lg %lg",&itmp,&rtmp,&tb->efile[i],&tb->ffile[i]); - - if (tb->rflag == RLINEAR) - rtmp = tb->rlo + (tb->rhi - tb->rlo)*i/(tb->ninput-1); - else if (tb->rflag == RSQ) { - rtmp = tb->rlo*tb->rlo + - (tb->rhi*tb->rhi - tb->rlo*tb->rlo)*i/(tb->ninput-1); - rtmp = sqrt(rtmp); - } else if (tb->rflag == BMP) { - rsq_lookup.i = i << nshiftbits; - rsq_lookup.i |= masklo; - if (rsq_lookup.f < tb->rlo*tb->rlo) { - rsq_lookup.i = i << nshiftbits; - rsq_lookup.i |= maskhi; - } - rtmp = sqrtf(rsq_lookup.f); - } - - tb->rfile[i] = rtmp; - } - - // close file - - fclose(fp); -} - -/* ---------------------------------------------------------------------- - broadcast read-in table info from proc 0 to other procs - this function communicates these values in Table: - ninput,rfile,efile,ffile,rflag,rlo,rhi,fpflag,fplo,fphi -------------------------------------------------------------------------- */ - -void PairTableRX::bcast_table(Table *tb) -{ - MPI_Bcast(&tb->ninput,1,MPI_INT,0,world); - - int me; - MPI_Comm_rank(world,&me); - if (me > 0) { - memory->create(tb->rfile,tb->ninput,"pair:rfile"); - memory->create(tb->efile,tb->ninput,"pair:efile"); - memory->create(tb->ffile,tb->ninput,"pair:ffile"); - } - - MPI_Bcast(tb->rfile,tb->ninput,MPI_DOUBLE,0,world); - MPI_Bcast(tb->efile,tb->ninput,MPI_DOUBLE,0,world); - MPI_Bcast(tb->ffile,tb->ninput,MPI_DOUBLE,0,world); - - MPI_Bcast(&tb->rflag,1,MPI_INT,0,world); - if (tb->rflag) { - MPI_Bcast(&tb->rlo,1,MPI_DOUBLE,0,world); - MPI_Bcast(&tb->rhi,1,MPI_DOUBLE,0,world); - } - MPI_Bcast(&tb->fpflag,1,MPI_INT,0,world); - if (tb->fpflag) { - MPI_Bcast(&tb->fplo,1,MPI_DOUBLE,0,world); - MPI_Bcast(&tb->fphi,1,MPI_DOUBLE,0,world); - } -} - -/* ---------------------------------------------------------------------- - build spline representation of e,f over entire range of read-in table - this function sets these values in Table: e2file,f2file -------------------------------------------------------------------------- */ - -void PairTableRX::spline_table(Table *tb) -{ - memory->create(tb->e2file,tb->ninput,"pair:e2file"); - memory->create(tb->f2file,tb->ninput,"pair:f2file"); - - double ep0 = - tb->ffile[0]; - double epn = - tb->ffile[tb->ninput-1]; - spline(tb->rfile,tb->efile,tb->ninput,ep0,epn,tb->e2file); - - if (tb->fpflag == 0) { - tb->fplo = (tb->ffile[1] - tb->ffile[0]) / (tb->rfile[1] - tb->rfile[0]); - tb->fphi = (tb->ffile[tb->ninput-1] - tb->ffile[tb->ninput-2]) / - (tb->rfile[tb->ninput-1] - tb->rfile[tb->ninput-2]); - } - - double fp0 = tb->fplo; - double fpn = tb->fphi; - spline(tb->rfile,tb->ffile,tb->ninput,fp0,fpn,tb->f2file); -} - -/* ---------------------------------------------------------------------- - extract attributes from parameter line in table section - format of line: N value R/RSQ/BITMAP lo hi FP fplo fphi - N is required, other params are optional -------------------------------------------------------------------------- */ - -void PairTableRX::param_extract(Table *tb, char *line) -{ - tb->ninput = 0; - tb->rflag = NONE; - tb->fpflag = 0; - - char *word = strtok(line," \t\n\r\f"); - while (word) { - if (strcmp(word,"N") == 0) { - word = strtok(NULL," \t\n\r\f"); - tb->ninput = atoi(word); - } else if (strcmp(word,"R") == 0 || strcmp(word,"RSQ") == 0 || - strcmp(word,"BITMAP") == 0) { - if (strcmp(word,"R") == 0) tb->rflag = RLINEAR; - else if (strcmp(word,"RSQ") == 0) tb->rflag = RSQ; - else if (strcmp(word,"BITMAP") == 0) tb->rflag = BMP; - word = strtok(NULL," \t\n\r\f"); - tb->rlo = atof(word); - word = strtok(NULL," \t\n\r\f"); - tb->rhi = atof(word); - } else if (strcmp(word,"FP") == 0) { - tb->fpflag = 1; - word = strtok(NULL," \t\n\r\f"); - tb->fplo = atof(word); - word = strtok(NULL," \t\n\r\f"); - tb->fphi = atof(word); - } else { - printf("WORD: %s\n",word); - error->one(FLERR,"Invalid keyword in pair table parameters"); - } - word = strtok(NULL," \t\n\r\f"); - } - - if (tb->ninput == 0) error->one(FLERR,"Pair table parameters did not set N"); -} - -/* ---------------------------------------------------------------------- - compute r,e,f vectors from splined values -------------------------------------------------------------------------- */ - -void PairTableRX::compute_table(Table *tb) -{ - int tlm1 = tablength-1; - - // inner = inner table bound - // cut = outer table bound - // delta = table spacing in rsq for N-1 bins - - double inner; - if (tb->rflag) inner = tb->rlo; - else inner = tb->rfile[0]; - tb->innersq = double(inner)*double(inner); - tb->delta = double(tb->cut*tb->cut - double(tb->innersq)) / double(tlm1); - tb->invdelta = 1.0/double(tb->delta); - - // direct lookup tables - // N-1 evenly spaced bins in rsq from inner to cut - // e,f = value at midpt of bin - // e,f are N-1 in length since store 1 value at bin midpt - // f is converted to f/r when stored in f[i] - // e,f are never a match to read-in values, always computed via spline interp - - if (tabstyle == LOOKUP) { - memory->create(tb->e,tlm1,"pair:e"); - memory->create(tb->f,tlm1,"pair:f"); - - double r,rsq; - for (int i = 0; i < tlm1; i++) { - rsq = tb->innersq + (i+0.5)*tb->delta; - r = sqrt(rsq); - tb->e[i] = splint(tb->rfile,tb->efile,tb->e2file,tb->ninput,r); - tb->f[i] = splint(tb->rfile,tb->ffile,tb->f2file,tb->ninput,r)/r; - } - } - - // linear tables - // N-1 evenly spaced bins in rsq from inner to cut - // rsq,e,f = value at lower edge of bin - // de,df values = delta from lower edge to upper edge of bin - // rsq,e,f are N in length so de,df arrays can compute difference - // f is converted to f/r when stored in f[i] - // e,f can match read-in values, else compute via spline interp - - if (tabstyle == LINEAR) { - memory->create(tb->rsq,tablength,"pair:rsq"); - memory->create(tb->e,tablength,"pair:e"); - memory->create(tb->f,tablength,"pair:f"); - memory->create(tb->de,tlm1,"pair:de"); - memory->create(tb->df,tlm1,"pair:df"); - - double r,rsq; - for (int i = 0; i < tablength; i++) { - rsq = tb->innersq + i*tb->delta; - r = sqrt(rsq); - tb->rsq[i] = rsq; - if (tb->match) { - tb->e[i] = tb->efile[i]; - tb->f[i] = tb->ffile[i]/r; - } else { - tb->e[i] = splint(tb->rfile,tb->efile,tb->e2file,tb->ninput,r); - tb->f[i] = splint(tb->rfile,tb->ffile,tb->f2file,tb->ninput,r)/r; - } - } - - for (int i = 0; i < tlm1; i++) { - tb->de[i] = tb->e[i+1] - tb->e[i]; - tb->df[i] = tb->f[i+1] - tb->f[i]; - } - } - - // cubic spline tables - // N-1 evenly spaced bins in rsq from inner to cut - // rsq,e,f = value at lower edge of bin - // e2,f2 = spline coefficient for each bin - // rsq,e,f,e2,f2 are N in length so have N-1 spline bins - // f is converted to f/r after e is splined - // e,f can match read-in values, else compute via spline interp - - if (tabstyle == SPLINE) { - memory->create(tb->rsq,tablength,"pair:rsq"); - memory->create(tb->e,tablength,"pair:e"); - memory->create(tb->f,tablength,"pair:f"); - memory->create(tb->e2,tablength,"pair:e2"); - memory->create(tb->f2,tablength,"pair:f2"); - - tb->deltasq6 = tb->delta*tb->delta / 6.0; - - double r,rsq; - for (int i = 0; i < tablength; i++) { - rsq = tb->innersq + i*tb->delta; - r = sqrt(rsq); - tb->rsq[i] = rsq; - if (tb->match) { - tb->e[i] = tb->efile[i]; - tb->f[i] = tb->ffile[i]/r; - } else { - tb->e[i] = splint(tb->rfile,tb->efile,tb->e2file,tb->ninput,r); - tb->f[i] = splint(tb->rfile,tb->ffile,tb->f2file,tb->ninput,r); - } - } - - // ep0,epn = dh/dg at inner and at cut - // h(r) = e(r) and g(r) = r^2 - // dh/dg = (de/dr) / 2r = -f/2r - - double ep0 = - tb->f[0] / (2.0 * sqrt(tb->innersq)); - double epn = - tb->f[tlm1] / (2.0 * tb->cut); - spline(tb->rsq,tb->e,tablength,ep0,epn,tb->e2); - - // fp0,fpn = dh/dg at inner and at cut - // h(r) = f(r)/r and g(r) = r^2 - // dh/dg = (1/r df/dr - f/r^2) / 2r - // dh/dg in secant approx = (f(r2)/r2 - f(r1)/r1) / (g(r2) - g(r1)) - - double fp0,fpn; - double secant_factor = 0.1; - if (tb->fpflag) fp0 = (tb->fplo/sqrt(tb->innersq) - tb->f[0]/tb->innersq) / - (2.0 * sqrt(tb->innersq)); - else { - double rsq1 = tb->innersq; - double rsq2 = rsq1 + secant_factor*tb->delta; - fp0 = (splint(tb->rfile,tb->ffile,tb->f2file,tb->ninput,sqrt(rsq2)) / - sqrt(rsq2) - tb->f[0] / sqrt(rsq1)) / (secant_factor*tb->delta); - } - - if (tb->fpflag && tb->cut == tb->rfile[tb->ninput-1]) fpn = - (tb->fphi/tb->cut - tb->f[tlm1]/(tb->cut*tb->cut)) / (2.0 * tb->cut); - else { - double rsq2 = tb->cut * tb->cut; - double rsq1 = rsq2 - secant_factor*tb->delta; - fpn = (tb->f[tlm1] / sqrt(rsq2) - - splint(tb->rfile,tb->ffile,tb->f2file,tb->ninput,sqrt(rsq1)) / - sqrt(rsq1)) / (secant_factor*tb->delta); - } - - for (int i = 0; i < tablength; i++) tb->f[i] /= sqrt(tb->rsq[i]); - spline(tb->rsq,tb->f,tablength,fp0,fpn,tb->f2); - } - - // bitmapped linear tables - // 2^N bins from inner to cut, spaced in bitmapped manner - // f is converted to f/r when stored in f[i] - // e,f can match read-in values, else compute via spline interp - - if (tabstyle == BITMAP) { - double r; - union_int_float_t rsq_lookup; - int masklo,maskhi; - - // linear lookup tables of length ntable = 2^n - // stored value = value at lower edge of bin - - init_bitmap(inner,tb->cut,tablength,masklo,maskhi,tb->nmask,tb->nshiftbits); - int ntable = 1 << tablength; - int ntablem1 = ntable - 1; - - memory->create(tb->rsq,ntable,"pair:rsq"); - memory->create(tb->e,ntable,"pair:e"); - memory->create(tb->f,ntable,"pair:f"); - memory->create(tb->de,ntable,"pair:de"); - memory->create(tb->df,ntable,"pair:df"); - memory->create(tb->drsq,ntable,"pair:drsq"); - - union_int_float_t minrsq_lookup; - minrsq_lookup.i = 0 << tb->nshiftbits; - minrsq_lookup.i |= maskhi; - - for (int i = 0; i < ntable; i++) { - rsq_lookup.i = i << tb->nshiftbits; - rsq_lookup.i |= masklo; - if (rsq_lookup.f < tb->innersq) { - rsq_lookup.i = i << tb->nshiftbits; - rsq_lookup.i |= maskhi; - } - r = sqrtf(rsq_lookup.f); - tb->rsq[i] = rsq_lookup.f; - if (tb->match) { - tb->e[i] = tb->efile[i]; - tb->f[i] = tb->ffile[i]/r; - } else { - tb->e[i] = splint(tb->rfile,tb->efile,tb->e2file,tb->ninput,r); - tb->f[i] = splint(tb->rfile,tb->ffile,tb->f2file,tb->ninput,r)/r; - } - minrsq_lookup.f = MIN(minrsq_lookup.f,rsq_lookup.f); - } - - tb->innersq = minrsq_lookup.f; - - for (int i = 0; i < ntablem1; i++) { - tb->de[i] = tb->e[i+1] - tb->e[i]; - tb->df[i] = tb->f[i+1] - tb->f[i]; - tb->drsq[i] = 1.0/(tb->rsq[i+1] - tb->rsq[i]); - } - - // get the delta values for the last table entries - // tables are connected periodically between 0 and ntablem1 - - tb->de[ntablem1] = tb->e[0] - tb->e[ntablem1]; - tb->df[ntablem1] = tb->f[0] - tb->f[ntablem1]; - tb->drsq[ntablem1] = 1.0/(tb->rsq[0] - tb->rsq[ntablem1]); - - // get the correct delta values at itablemax - // smallest r is in bin itablemin - // largest r is in bin itablemax, which is itablemin-1, - // or ntablem1 if itablemin=0 - - // deltas at itablemax only needed if corresponding rsq < cut*cut - // if so, compute deltas between rsq and cut*cut - // if tb->match, data at cut*cut is unavailable, so we'll take - // deltas at itablemax-1 as a good approximation - - double e_tmp,f_tmp; - int itablemin = minrsq_lookup.i & tb->nmask; - itablemin >>= tb->nshiftbits; - int itablemax = itablemin - 1; - if (itablemin == 0) itablemax = ntablem1; - int itablemaxm1 = itablemax - 1; - if (itablemax == 0) itablemaxm1 = ntablem1; - rsq_lookup.i = itablemax << tb->nshiftbits; - rsq_lookup.i |= maskhi; - if (rsq_lookup.f < tb->cut*tb->cut) { - if (tb->match) { - tb->de[itablemax] = tb->de[itablemaxm1]; - tb->df[itablemax] = tb->df[itablemaxm1]; - tb->drsq[itablemax] = tb->drsq[itablemaxm1]; - } else { - rsq_lookup.f = tb->cut*tb->cut; - r = sqrtf(rsq_lookup.f); - e_tmp = splint(tb->rfile,tb->efile,tb->e2file,tb->ninput,r); - f_tmp = splint(tb->rfile,tb->ffile,tb->f2file,tb->ninput,r)/r; - tb->de[itablemax] = e_tmp - tb->e[itablemax]; - tb->df[itablemax] = f_tmp - tb->f[itablemax]; - tb->drsq[itablemax] = 1.0/(rsq_lookup.f - tb->rsq[itablemax]); - } - } - } -} - -/* ---------------------------------------------------------------------- - set all ptrs in a table to NULL, so can be freed safely -------------------------------------------------------------------------- */ - -void PairTableRX::null_table(Table *tb) -{ - tb->rfile = tb->efile = tb->ffile = NULL; - tb->e2file = tb->f2file = NULL; - tb->rsq = tb->drsq = tb->e = tb->de = NULL; - tb->f = tb->df = tb->e2 = tb->f2 = NULL; -} - -/* ---------------------------------------------------------------------- - free all arrays in a table -------------------------------------------------------------------------- */ - -void PairTableRX::free_table(Table *tb) -{ - memory->destroy(tb->rfile); - memory->destroy(tb->efile); - memory->destroy(tb->ffile); - memory->destroy(tb->e2file); - memory->destroy(tb->f2file); - - memory->destroy(tb->rsq); - memory->destroy(tb->drsq); - memory->destroy(tb->e); - memory->destroy(tb->de); - memory->destroy(tb->f); - memory->destroy(tb->df); - memory->destroy(tb->e2); - memory->destroy(tb->f2); -} - -/* ---------------------------------------------------------------------- - spline and splint routines modified from Numerical Recipes -------------------------------------------------------------------------- */ - -void PairTableRX::spline(double *x, double *y, int n, - double yp1, double ypn, double *y2) -{ - int i,k; - double p,qn,sig,un; - double *u = new double[n]; - - if (yp1 > 0.99e30) y2[0] = u[0] = 0.0; - else { - y2[0] = -0.5; - u[0] = (3.0/(x[1]-x[0])) * ((y[1]-y[0]) / (x[1]-x[0]) - yp1); - } - for (i = 1; i < n-1; i++) { - sig = (x[i]-x[i-1]) / (x[i+1]-x[i-1]); - p = sig*y2[i-1] + 2.0; - y2[i] = (sig-1.0) / p; - u[i] = (y[i+1]-y[i]) / (x[i+1]-x[i]) - (y[i]-y[i-1]) / (x[i]-x[i-1]); - u[i] = (6.0*u[i] / (x[i+1]-x[i-1]) - sig*u[i-1]) / p; - } - if (ypn > 0.99e30) qn = un = 0.0; - else { - qn = 0.5; - un = (3.0/(x[n-1]-x[n-2])) * (ypn - (y[n-1]-y[n-2]) / (x[n-1]-x[n-2])); - } - y2[n-1] = (un-qn*u[n-2]) / (qn*y2[n-2] + 1.0); - for (k = n-2; k >= 0; k--) y2[k] = y2[k]*y2[k+1] + u[k]; - - delete [] u; -} - -/* ---------------------------------------------------------------------- */ - -double PairTableRX::splint(double *xa, double *ya, double *y2a, int n, double x) -{ - int klo,khi,k; - double h,b,a,y; - - klo = 0; - khi = n-1; - while (khi-klo > 1) { - k = (khi+klo) >> 1; - if (xa[k] > x) khi = k; - else klo = k; - } - h = xa[khi]-xa[klo]; - a = (xa[khi]-x) / h; - b = (x-xa[klo]) / h; - y = a*ya[klo] + b*ya[khi] + - ((a*a*a-a)*y2a[klo] + (b*b*b-b)*y2a[khi]) * (h*h)/6.0; - return y; -} - -/* ---------------------------------------------------------------------- - proc 0 writes to restart file -------------------------------------------------------------------------- */ - -void PairTableRX::write_restart(FILE *fp) -{ - write_restart_settings(fp); -} - -/* ---------------------------------------------------------------------- - proc 0 reads from restart file, bcasts -------------------------------------------------------------------------- */ - -void PairTableRX::read_restart(FILE *fp) -{ - read_restart_settings(fp); - allocate(); -} - -/* ---------------------------------------------------------------------- - proc 0 writes to restart file -------------------------------------------------------------------------- */ - -void PairTableRX::write_restart_settings(FILE *fp) -{ - fwrite(&tabstyle,sizeof(int),1,fp); - fwrite(&tablength,sizeof(int),1,fp); - fwrite(&ewaldflag,sizeof(int),1,fp); - fwrite(&pppmflag,sizeof(int),1,fp); - fwrite(&msmflag,sizeof(int),1,fp); - fwrite(&dispersionflag,sizeof(int),1,fp); - fwrite(&tip4pflag,sizeof(int),1,fp); -} - -/* ---------------------------------------------------------------------- - proc 0 reads from restart file, bcasts -------------------------------------------------------------------------- */ - -void PairTableRX::read_restart_settings(FILE *fp) -{ - if (comm->me == 0) { - fread(&tabstyle,sizeof(int),1,fp); - fread(&tablength,sizeof(int),1,fp); - fread(&ewaldflag,sizeof(int),1,fp); - fread(&pppmflag,sizeof(int),1,fp); - fread(&msmflag,sizeof(int),1,fp); - fread(&dispersionflag,sizeof(int),1,fp); - fread(&tip4pflag,sizeof(int),1,fp); - } - MPI_Bcast(&tabstyle,1,MPI_INT,0,world); - MPI_Bcast(&tablength,1,MPI_INT,0,world); - MPI_Bcast(&ewaldflag,1,MPI_INT,0,world); - MPI_Bcast(&pppmflag,1,MPI_INT,0,world); - MPI_Bcast(&msmflag,1,MPI_INT,0,world); - MPI_Bcast(&dispersionflag,1,MPI_INT,0,world); - MPI_Bcast(&tip4pflag,1,MPI_INT,0,world); -} - /* ---------------------------------------------------------------------- */ double PairTableRX::single(int i, int j, int itype, int jtype, double rsq, @@ -1131,26 +495,6 @@ double PairTableRX::single(int i, int j, int itype, int jtype, double rsq, return factor_lj*phi; } -/* ---------------------------------------------------------------------- - return the Coulomb cutoff for tabled potentials - called by KSpace solvers which require that all pairwise cutoffs be the same - loop over all tables not just those indexed by tabindex[i][j] since - no way to know which tables are active since pair::init() not yet called -------------------------------------------------------------------------- */ - -void *PairTableRX::extract(const char *str, int &dim) -{ - if (strcmp(str,"cut_coul") != 0) return NULL; - if (ntables == 0) error->all(FLERR,"All pair coeffs are not set"); - - double cut_coul = tables[0].cut; - for (int m = 1; m < ntables; m++) - if (tables[m].cut != cut_coul) - error->all(FLERR,"Pair table cutoffs must all be equal to use with KSpace"); - dim = 0; - return &tables[0].cut; -} - /* ---------------------------------------------------------------------- */ void PairTableRX::getMixingWeights(int id, double &mixWtSite1old, double &mixWtSite2old, double &mixWtSite1, double &mixWtSite2) diff --git a/src/USER-DPD/pair_table_rx.h b/src/USER-DPD/pair_table_rx.h index c6afe6a8d5..4f80872029 100644 --- a/src/USER-DPD/pair_table_rx.h +++ b/src/USER-DPD/pair_table_rx.h @@ -1,4 +1,4 @@ -/* ---------------------------------------------------------------------- +/* -*- c++ -*- ---------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator http://lammps.sandia.gov, Sandia National Laboratories Steve Plimpton, sjplimp@sandia.gov @@ -20,11 +20,11 @@ PairStyle(table/rx,PairTableRX) #ifndef LMP_PAIR_TABLE_RX_H #define LMP_PAIR_TABLE_RX_H -#include "pair.h" +#include "pair_table.h" namespace LAMMPS_NS { -class PairTableRX : public Pair { +class PairTableRX : public PairTable { public: PairTableRX(class LAMMPS *); virtual ~PairTableRX(); @@ -32,43 +32,11 @@ class PairTableRX : public Pair { virtual void compute(int, int); void settings(int, char **); void coeff(int, char **); - double init_one(int, int); - void write_restart(FILE *); - void read_restart(FILE *); - void write_restart_settings(FILE *); - void read_restart_settings(FILE *); - double single(int, int, int, int, double, double, double, double &); - void *extract(const char *, int &); + virtual double single(int, int, int, int, double, double, double, double &); protected: enum{LOOKUP,LINEAR,SPLINE,BITMAP}; - int tabstyle,tablength; - struct Table { - int ninput,rflag,fpflag,match,ntablebits; - int nshiftbits,nmask; - double rlo,rhi,fplo,fphi,cut; - double *rfile,*efile,*ffile; - double *e2file,*f2file; - double innersq,delta,invdelta,deltasq6; - double *rsq,*drsq,*e,*de,*f,*df,*e2,*f2; - }; - int ntables; - Table *tables; - - int **tabindex; - - void allocate(); - void read_table(Table *, char *, char *); - void param_extract(Table *, char *); - void bcast_table(Table *); - void spline_table(Table *); - void compute_table(Table *); - void null_table(Table *); - void free_table(Table *); - void spline(double *, double *, int, double, double, double *); - double splint(double *, double *, double *, int, double); - int nspecies; char *site1, *site2; int isite1, isite2; diff --git a/src/pair_table.cpp b/src/pair_table.cpp index c4bc3e7dd2..1c6bfe128e 100644 --- a/src/pair_table.cpp +++ b/src/pair_table.cpp @@ -29,8 +29,6 @@ using namespace LAMMPS_NS; -enum{NONE,RLINEAR,RSQ,BMP}; - #define MAXLINE 1024 #define EPSILONR 1.0e-6 @@ -46,6 +44,8 @@ PairTable::PairTable(LAMMPS *lmp) : Pair(lmp) PairTable::~PairTable() { + if (copymode) return; + for (int m = 0; m < ntables; m++) free_table(&tables[m]); memory->sfree(tables); diff --git a/src/pair_table.h b/src/pair_table.h index 358491f7cf..370efcec2f 100644 --- a/src/pair_table.h +++ b/src/pair_table.h @@ -37,11 +37,12 @@ class PairTable : public Pair { void read_restart(FILE *); void write_restart_settings(FILE *); void read_restart_settings(FILE *); - double single(int, int, int, int, double, double, double, double &); + virtual double single(int, int, int, int, double, double, double, double &); void *extract(const char *, int &); protected: enum{LOOKUP,LINEAR,SPLINE,BITMAP}; + enum{NONE,RLINEAR,RSQ,BMP}; int tabstyle,tablength; struct Table { @@ -66,8 +67,8 @@ class PairTable : public Pair { void compute_table(Table *); void null_table(Table *); void free_table(Table *); - void spline(double *, double *, int, double, double, double *); - double splint(double *, double *, double *, int, double); + static void spline(double *, double *, int, double, double, double *); + static double splint(double *, double *, double *, int, double); }; } From 3941fe9ab7488bf91fca7b6c529ad2c2cd7ba35b Mon Sep 17 00:00:00 2001 From: Dan Ibanez Date: Tue, 3 Jan 2017 16:42:24 -0700 Subject: [PATCH 051/439] fix compilation --- src/USER-DPD/pair_table_rx.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/USER-DPD/pair_table_rx.h b/src/USER-DPD/pair_table_rx.h index 4f80872029..00314ac424 100644 --- a/src/USER-DPD/pair_table_rx.h +++ b/src/USER-DPD/pair_table_rx.h @@ -27,7 +27,7 @@ namespace LAMMPS_NS { class PairTableRX : public PairTable { public: PairTableRX(class LAMMPS *); - virtual ~PairTableRX(); + virtual ~PairTableRX() {} virtual void compute(int, int); void settings(int, char **); From a1ac2ae9b7570d27148064d90ea8051c7e30c75e Mon Sep 17 00:00:00 2001 From: Dan Ibanez Date: Wed, 4 Jan 2017 10:51:31 -0700 Subject: [PATCH 052/439] move enum to pair.h to avoid having it be replicated in several different locations --- src/pair.cpp | 2 -- src/pair.h | 2 ++ src/pair_table.h | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/pair.cpp b/src/pair.cpp index 5d73a592e8..f8ae641d2f 100644 --- a/src/pair.cpp +++ b/src/pair.cpp @@ -43,8 +43,6 @@ using namespace LAMMPS_NS; using namespace MathConst; -enum{NONE,RLINEAR,RSQ,BMP}; - // allocate space for static class instance variable and initialize it int Pair::instance_total = 0; diff --git a/src/pair.h b/src/pair.h index 3378115e49..fbb6d8408b 100644 --- a/src/pair.h +++ b/src/pair.h @@ -32,6 +32,8 @@ class Pair : protected Pointers { friend class Info; public: + enum{NONE,RLINEAR,RSQ,BMP}; + static int instance_total; // # of Pair classes ever instantiated double eng_vdwl,eng_coul; // accumulated energies diff --git a/src/pair_table.h b/src/pair_table.h index 370efcec2f..8d5dbdb28a 100644 --- a/src/pair_table.h +++ b/src/pair_table.h @@ -42,7 +42,6 @@ class PairTable : public Pair { protected: enum{LOOKUP,LINEAR,SPLINE,BITMAP}; - enum{NONE,RLINEAR,RSQ,BMP}; int tabstyle,tablength; struct Table { From 70927d08e734d418ed61f9492160ca23b65c6e6f Mon Sep 17 00:00:00 2001 From: Dan Ibanez Date: Thu, 5 Jan 2017 13:25:30 -0700 Subject: [PATCH 053/439] remove duplicate enum --- src/USER-DPD/pair_table_rx.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/USER-DPD/pair_table_rx.h b/src/USER-DPD/pair_table_rx.h index 00314ac424..9dee5df266 100644 --- a/src/USER-DPD/pair_table_rx.h +++ b/src/USER-DPD/pair_table_rx.h @@ -35,7 +35,6 @@ class PairTableRX : public PairTable { virtual double single(int, int, int, int, double, double, double, double &); protected: - enum{LOOKUP,LINEAR,SPLINE,BITMAP}; int nspecies; char *site1, *site2; From ad1402562d70ffa4a03e150ed9246e8ae710c684 Mon Sep 17 00:00:00 2001 From: Dan Ibanez Date: Thu, 5 Jan 2017 20:54:24 -0700 Subject: [PATCH 054/439] Revert "move enum to pair.h" This reverts commit a1ac2ae9b7570d27148064d90ea8051c7e30c75e. --- src/pair.cpp | 2 ++ src/pair.h | 2 -- src/pair_table.h | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/pair.cpp b/src/pair.cpp index f8ae641d2f..5d73a592e8 100644 --- a/src/pair.cpp +++ b/src/pair.cpp @@ -43,6 +43,8 @@ using namespace LAMMPS_NS; using namespace MathConst; +enum{NONE,RLINEAR,RSQ,BMP}; + // allocate space for static class instance variable and initialize it int Pair::instance_total = 0; diff --git a/src/pair.h b/src/pair.h index fbb6d8408b..3378115e49 100644 --- a/src/pair.h +++ b/src/pair.h @@ -32,8 +32,6 @@ class Pair : protected Pointers { friend class Info; public: - enum{NONE,RLINEAR,RSQ,BMP}; - static int instance_total; // # of Pair classes ever instantiated double eng_vdwl,eng_coul; // accumulated energies diff --git a/src/pair_table.h b/src/pair_table.h index 8d5dbdb28a..370efcec2f 100644 --- a/src/pair_table.h +++ b/src/pair_table.h @@ -42,6 +42,7 @@ class PairTable : public Pair { protected: enum{LOOKUP,LINEAR,SPLINE,BITMAP}; + enum{NONE,RLINEAR,RSQ,BMP}; int tabstyle,tablength; struct Table { From d8ddef37ed5407a3723b854ffc8ae077fb4c9fc5 Mon Sep 17 00:00:00 2001 From: Dan Ibanez Date: Thu, 5 Jan 2017 20:56:37 -0700 Subject: [PATCH 055/439] put enum back in .cpp file see lammps/lammps#325 --- src/USER-DPD/pair_table_rx.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/USER-DPD/pair_table_rx.cpp b/src/USER-DPD/pair_table_rx.cpp index c8d59c052d..e8f0e81057 100644 --- a/src/USER-DPD/pair_table_rx.cpp +++ b/src/USER-DPD/pair_table_rx.cpp @@ -31,6 +31,8 @@ using namespace LAMMPS_NS; +enum{NONE,RLINEAR,RSQ,BMP}; + #ifdef DBL_EPSILON #define MY_EPSILON (10.0*DBL_EPSILON) #else From 7201f003e57716ac7a14378127dc22fbc63954f1 Mon Sep 17 00:00:00 2001 From: Dan Ibanez Date: Thu, 5 Jan 2017 21:00:39 -0700 Subject: [PATCH 056/439] move another enum back see lammps/lammps#325 --- src/pair_table.cpp | 2 ++ src/pair_table.h | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pair_table.cpp b/src/pair_table.cpp index 1c6bfe128e..b36843ff44 100644 --- a/src/pair_table.cpp +++ b/src/pair_table.cpp @@ -29,6 +29,8 @@ using namespace LAMMPS_NS; +enum{NONE,RLINEAR,RSQ,BMP}; + #define MAXLINE 1024 #define EPSILONR 1.0e-6 diff --git a/src/pair_table.h b/src/pair_table.h index 370efcec2f..8d5dbdb28a 100644 --- a/src/pair_table.h +++ b/src/pair_table.h @@ -42,7 +42,6 @@ class PairTable : public Pair { protected: enum{LOOKUP,LINEAR,SPLINE,BITMAP}; - enum{NONE,RLINEAR,RSQ,BMP}; int tabstyle,tablength; struct Table { From d26f1403cdb70e88abd9f9d8dced12a3ef16bd51 Mon Sep 17 00:00:00 2001 From: Dan Ibanez Date: Tue, 10 Jan 2017 15:22:52 -0700 Subject: [PATCH 057/439] fix race condition on rho the main bug here is the use of a local rho_i accumulator which later gets assigned back to rho[i]. in parallel, atomic additions can happen to rho[i] while the local accumulator is held; those atomic additions are lost when the accumulator is atomically assigned. we instead initialize the accumulator to zero and atomically add it back to rho[i]. --- src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp b/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp index 7cff630cb0..24502f875c 100644 --- a/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp +++ b/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp @@ -526,7 +526,7 @@ void PairMultiLucyRXKokkos::operator()(TagPairMultiLucyRXComputeLoca const double ytmp = x(i,1); const double ztmp = x(i,2); - double rho_i = rho[i]; + double rho_i_contrib = 0.0; const int itype = type[i]; const int jnum = d_numneigh[i]; @@ -549,7 +549,7 @@ void PairMultiLucyRXKokkos::operator()(TagPairMultiLucyRXComputeLoca const double tmpFactor = 1.0 - r_over_rcut; const double tmpFactor4 = tmpFactor*tmpFactor*tmpFactor*tmpFactor; const double factor = factor_type11*(1.0 + 1.5*r_over_rcut)*tmpFactor4; - rho_i += factor; + rho_i_contrib += factor; if (NEWTON_PAIR || j < nlocal) a_rho[j] += factor; } else if (rsq < d_cutsq(itype,jtype)) { @@ -557,14 +557,14 @@ void PairMultiLucyRXKokkos::operator()(TagPairMultiLucyRXComputeLoca const double tmpFactor = 1.0-sqrt(rsq)/rcut; const double tmpFactor4 = tmpFactor*tmpFactor*tmpFactor*tmpFactor; const double factor = (84.0/(5.0*pi*rcut*rcut*rcut))*(1.0+3.0*sqrt(rsq)/(2.0*rcut))*tmpFactor4; - rho_i += factor; + rho_i_contrib += factor; if (NEWTON_PAIR || j < nlocal) a_rho[j] += factor; } } } - a_rho[i] = rho_i; + a_rho[i] += rho_i_contrib; } /* ---------------------------------------------------------------------- */ From 6abefe7ef956621d52941fb2f1778665fd6a5e3d Mon Sep 17 00:00:00 2001 From: Dan Ibanez Date: Fri, 6 Jan 2017 15:41:41 -0700 Subject: [PATCH 058/439] restarting PairTableRXKokkos as an exact copy of PairTableKokkos, now that it derives from PairTable --- src/KOKKOS/Install.sh | 4 +- src/KOKKOS/pair_table_rx_kokkos.cpp | 241 ++++++++++------------------ src/KOKKOS/pair_table_rx_kokkos.h | 185 +++++---------------- 3 files changed, 128 insertions(+), 302 deletions(-) diff --git a/src/KOKKOS/Install.sh b/src/KOKKOS/Install.sh index d796de5e2f..cfda7dbf94 100644 --- a/src/KOKKOS/Install.sh +++ b/src/KOKKOS/Install.sh @@ -195,8 +195,8 @@ action pair_vashishta_kokkos.cpp pair_vashishta.cpp action pair_vashishta_kokkos.h pair_vashishta.h action pair_table_kokkos.cpp action pair_table_kokkos.h -#action pair_table_rx_kokkos.cpp pair_table_rx.cpp -#action pair_table_rx_kokkos.h pair_table_rx.h +action pair_table_rx_kokkos.cpp pair_table_rx.cpp +action pair_table_rx_kokkos.h pair_table_rx.h action pair_tersoff_kokkos.cpp pair_tersoff.cpp action pair_tersoff_kokkos.h pair_tersoff.h action pair_tersoff_mod_kokkos.cpp pair_tersoff_mod.cpp diff --git a/src/KOKKOS/pair_table_rx_kokkos.cpp b/src/KOKKOS/pair_table_rx_kokkos.cpp index bf32d1c14f..2ccdefd05d 100644 --- a/src/KOKKOS/pair_table_rx_kokkos.cpp +++ b/src/KOKKOS/pair_table_rx_kokkos.cpp @@ -12,7 +12,7 @@ ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- - Contributing author: Stan Moore (SNL) + Contributing author: Dan Ibanez (SNL) ------------------------------------------------------------------------- */ #include @@ -33,20 +33,13 @@ using namespace LAMMPS_NS; -enum{NONE,RLINEAR,RSQ,BMP}; -enum{FULL,HALFTHREAD,HALF}; - -#define MAXLINE 1024 - /* ---------------------------------------------------------------------- */ template -PairTableRXKokkos::PairTableRXKokkos(LAMMPS *lmp) : PairTableRX(lmp) +PairTableRXKokkos::PairTableRXKokkos(LAMMPS *lmp) : PairTable(lmp) { update_table = 0; atomKK = (AtomKokkos *) atom; - ntables = 0; - tables = NULL; execution_space = ExecutionSpaceFromDevice::space; datamask_read = X_MASK | F_MASK | TYPE_MASK | ENERGY_MASK | VIRIAL_MASK; datamask_modify = F_MASK | ENERGY_MASK | VIRIAL_MASK; @@ -59,17 +52,12 @@ PairTableRXKokkos::PairTableRXKokkos(LAMMPS *lmp) : PairTableRX(lmp) template PairTableRXKokkos::~PairTableRXKokkos() { -/* for (int m = 0; m < ntables; m++) free_table(&tables[m]); - memory->sfree(tables); - - if (allocated) { - memory->destroy(setflag); - memory->destroy(cutsq); - memory->destroy(tabindex); - }*/ + if (copymode) return; delete h_table; + h_table = nullptr; delete d_table; - + d_table = nullptr; + copymode = true; //prevents base class destructor from running } /* ---------------------------------------------------------------------- */ @@ -98,7 +86,6 @@ void PairTableRXKokkos::compute_style(int eflag_in, int vflag_in) if (neighflag == FULL) no_virial_fdotr_compute = 1; - if (eflag || vflag) ev_setup(eflag,vflag); else evflag = vflag_fdotr = 0; @@ -124,44 +111,44 @@ void PairTableRXKokkos::compute_style(int eflag_in, int vflag_in) EV_FLOAT ev; if(atom->ntypes > MAX_TYPES_STACKPARAMS) { if (neighflag == FULL) { - PairComputeFunctor,FULL,false,S_TableRXCompute > + PairComputeFunctor,FULL,false,S_TableCompute > ff(this,(NeighListKokkos*) list); if (eflag || vflag) Kokkos::parallel_reduce(list->inum,ff,ev); else Kokkos::parallel_for(list->inum,ff); } else if (neighflag == HALFTHREAD) { - PairComputeFunctor,HALFTHREAD,false,S_TableRXCompute > + PairComputeFunctor,HALFTHREAD,false,S_TableCompute > ff(this,(NeighListKokkos*) list); if (eflag || vflag) Kokkos::parallel_reduce(list->inum,ff,ev); else Kokkos::parallel_for(list->inum,ff); } else if (neighflag == HALF) { - PairComputeFunctor,HALF,false,S_TableRXCompute > + PairComputeFunctor,HALF,false,S_TableCompute > f(this,(NeighListKokkos*) list); if (eflag || vflag) Kokkos::parallel_reduce(list->inum,f,ev); else Kokkos::parallel_for(list->inum,f); } else if (neighflag == N2) { - PairComputeFunctor,N2,false,S_TableRXCompute > + PairComputeFunctor,N2,false,S_TableCompute > f(this,(NeighListKokkos*) list); if (eflag || vflag) Kokkos::parallel_reduce(nlocal,f,ev); else Kokkos::parallel_for(nlocal,f); } } else { if (neighflag == FULL) { - PairComputeFunctor,FULL,true,S_TableRXCompute > + PairComputeFunctor,FULL,true,S_TableCompute > f(this,(NeighListKokkos*) list); if (eflag || vflag) Kokkos::parallel_reduce(list->inum,f,ev); else Kokkos::parallel_for(list->inum,f); } else if (neighflag == HALFTHREAD) { - PairComputeFunctor,HALFTHREAD,true,S_TableRXCompute > + PairComputeFunctor,HALFTHREAD,true,S_TableCompute > f(this,(NeighListKokkos*) list); if (eflag || vflag) Kokkos::parallel_reduce(list->inum,f,ev); else Kokkos::parallel_for(list->inum,f); } else if (neighflag == HALF) { - PairComputeFunctor,HALF,true,S_TableRXCompute > + PairComputeFunctor,HALF,true,S_TableCompute > f(this,(NeighListKokkos*) list); if (eflag || vflag) Kokkos::parallel_reduce(list->inum,f,ev); else Kokkos::parallel_for(list->inum,f); } else if (neighflag == N2) { - PairComputeFunctor,N2,true,S_TableRXCompute > + PairComputeFunctor,N2,true,S_TableCompute > f(this,(NeighListKokkos*) list); if (eflag || vflag) Kokkos::parallel_reduce(nlocal,f,ev); else Kokkos::parallel_for(nlocal,f); @@ -191,27 +178,15 @@ compute_fpair(const F_FLOAT& rsq, const int& i, const int&j, const int& itype, c union_int_float_t rsq_lookup; double fpair; const int tidx = d_table_const.tabindex(itype,jtype); - //const Table* const tb = &tables[tabindex[itype][jtype]]; - - //if (rsq < d_table_const.innersq(tidx)) - // error->one(FLERR,"Pair distance < table inner cutoff"); - - if (Specialisation::TabStyle == LOOKUP) { const int itable = static_cast ((rsq - d_table_const.innersq(tidx)) * d_table_const.invdelta(tidx)); - //if (itable >= tlm1) - // error->one(FLERR,"Pair distance > table outer cutoff"); fpair = d_table_const.f(tidx,itable); } else if (Specialisation::TabStyle == LINEAR) { const int itable = static_cast ((rsq - d_table_const.innersq(tidx)) * d_table_const.invdelta(tidx)); - //if (itable >= tlm1) - // error->one(FLERR,"Pair distance > table outer cutoff"); const double fraction = (rsq - d_table_const.rsq(tidx,itable)) * d_table_const.invdelta(tidx); fpair = d_table_const.f(tidx,itable) + fraction*d_table_const.df(tidx,itable); } else if (Specialisation::TabStyle == SPLINE) { const int itable = static_cast ((rsq - d_table_const.innersq(tidx)) * d_table_const.invdelta(tidx)); - //if (itable >= tlm1) - // error->one(FLERR,"Pair distance > table outer cutoff"); const double b = (rsq - d_table_const.rsq(tidx,itable)) * d_table_const.invdelta(tidx); const double a = 1.0 - b; fpair = a * d_table_const.f(tidx,itable) + b * d_table_const.f(tidx,itable+1) + @@ -237,26 +212,15 @@ compute_evdwl(const F_FLOAT& rsq, const int& i, const int&j, const int& itype, c double evdwl; union_int_float_t rsq_lookup; const int tidx = d_table_const.tabindex(itype,jtype); - //const Table* const tb = &tables[tabindex[itype][jtype]]; - - //if (rsq < d_table_const.innersq(tidx)) - // error->one(FLERR,"Pair distance < table inner cutoff"); - if (Specialisation::TabStyle == LOOKUP) { const int itable = static_cast ((rsq - d_table_const.innersq(tidx)) * d_table_const.invdelta(tidx)); - //if (itable >= tlm1) - // error->one(FLERR,"Pair distance > table outer cutoff"); evdwl = d_table_const.e(tidx,itable); } else if (Specialisation::TabStyle == LINEAR) { const int itable = static_cast ((rsq - d_table_const.innersq(tidx)) * d_table_const.invdelta(tidx)); - //if (itable >= tlm1) - // error->one(FLERR,"Pair distance > table outer cutoff"); const double fraction = (rsq - d_table_const.rsq(tidx,itable)) * d_table_const.invdelta(tidx); evdwl = d_table_const.e(tidx,itable) + fraction*d_table_const.de(tidx,itable); } else if (Specialisation::TabStyle == SPLINE) { const int itable = static_cast ((rsq - d_table_const.innersq(tidx)) * d_table_const.invdelta(tidx)); - //if (itable >= tlm1) - // error->one(FLERR,"Pair distance > table outer cutoff"); const double b = (rsq - d_table_const.rsq(tidx,itable)) * d_table_const.invdelta(tidx); const double a = 1.0 - b; evdwl = a * d_table_const.e(tidx,itable) + b * d_table_const.e(tidx,itable+1) + @@ -314,6 +278,8 @@ void PairTableRXKokkos::create_kokkos_tables() memory->create_kokkos(d_table->drsq,h_table->drsq,ntables,ntable,"Table::drsq"); } + + for(int i=0; i < ntables; i++) { Table* tb = &tables[i]; @@ -343,36 +309,69 @@ void PairTableRXKokkos::create_kokkos_tables() Kokkos::deep_copy(d_table->nshiftbits,h_table->nshiftbits); - Kokkos::deep_copy(d_table->nmask,h_table->nmask); - Kokkos::deep_copy(d_table->innersq,h_table->innersq); - Kokkos::deep_copy(d_table->invdelta,h_table->invdelta); - Kokkos::deep_copy(d_table->deltasq6,h_table->deltasq6); - Kokkos::deep_copy(d_table->rsq,h_table->rsq); - Kokkos::deep_copy(d_table->drsq,h_table->drsq); - Kokkos::deep_copy(d_table->e,h_table->e); - Kokkos::deep_copy(d_table->de,h_table->de); - Kokkos::deep_copy(d_table->f,h_table->f); - Kokkos::deep_copy(d_table->df,h_table->df); - Kokkos::deep_copy(d_table->e2,h_table->e2); - Kokkos::deep_copy(d_table->f2,h_table->f2); - Kokkos::deep_copy(d_table->tabindex,h_table->tabindex); - d_table_const.nshiftbits = d_table->nshiftbits; + Kokkos::deep_copy(d_table->nmask,h_table->nmask); d_table_const.nmask = d_table->nmask; + Kokkos::deep_copy(d_table->innersq,h_table->innersq); d_table_const.innersq = d_table->innersq; + Kokkos::deep_copy(d_table->invdelta,h_table->invdelta); d_table_const.invdelta = d_table->invdelta; + Kokkos::deep_copy(d_table->deltasq6,h_table->deltasq6); d_table_const.deltasq6 = d_table->deltasq6; - d_table_const.rsq = d_table->rsq; - d_table_const.drsq = d_table->drsq; - d_table_const.e = d_table->e; - d_table_const.de = d_table->de; - d_table_const.f = d_table->f; - d_table_const.df = d_table->df; - d_table_const.e2 = d_table->e2; - d_table_const.f2 = d_table->f2; + if(tabstyle == LOOKUP) { + Kokkos::deep_copy(d_table->e,h_table->e); + d_table_const.e = d_table->e; + Kokkos::deep_copy(d_table->f,h_table->f); + d_table_const.f = d_table->f; + } + + if(tabstyle == LINEAR) { + Kokkos::deep_copy(d_table->rsq,h_table->rsq); + d_table_const.rsq = d_table->rsq; + Kokkos::deep_copy(d_table->e,h_table->e); + d_table_const.e = d_table->e; + Kokkos::deep_copy(d_table->f,h_table->f); + d_table_const.f = d_table->f; + Kokkos::deep_copy(d_table->de,h_table->de); + d_table_const.de = d_table->de; + Kokkos::deep_copy(d_table->df,h_table->df); + d_table_const.df = d_table->df; + } + + if(tabstyle == SPLINE) { + Kokkos::deep_copy(d_table->rsq,h_table->rsq); + d_table_const.rsq = d_table->rsq; + Kokkos::deep_copy(d_table->e,h_table->e); + d_table_const.e = d_table->e; + Kokkos::deep_copy(d_table->f,h_table->f); + d_table_const.f = d_table->f; + Kokkos::deep_copy(d_table->e2,h_table->e2); + d_table_const.e2 = d_table->e2; + Kokkos::deep_copy(d_table->f2,h_table->f2); + d_table_const.f2 = d_table->f2; + } + + if(tabstyle == BITMAP) { + Kokkos::deep_copy(d_table->rsq,h_table->rsq); + d_table_const.rsq = d_table->rsq; + Kokkos::deep_copy(d_table->e,h_table->e); + d_table_const.e = d_table->e; + Kokkos::deep_copy(d_table->f,h_table->f); + d_table_const.f = d_table->f; + Kokkos::deep_copy(d_table->de,h_table->de); + d_table_const.de = d_table->de; + Kokkos::deep_copy(d_table->df,h_table->df); + d_table_const.df = d_table->df; + Kokkos::deep_copy(d_table->drsq,h_table->drsq); + d_table_const.drsq = d_table->drsq; + } Kokkos::deep_copy(d_table->cutsq,h_table->cutsq); + d_table_const.cutsq = d_table->cutsq; + Kokkos::deep_copy(d_table->tabindex,h_table->tabindex); + d_table_const.tabindex = d_table->tabindex; + update_table = 0; } @@ -389,9 +388,9 @@ void PairTableRXKokkos::allocate() memory->create(setflag,nt,nt,"pair:setflag"); memory->create_kokkos(d_table->cutsq,h_table->cutsq,cutsq,nt,nt,"pair:cutsq"); memory->create_kokkos(d_table->tabindex,h_table->tabindex,tabindex,nt,nt,"pair:tabindex"); - d_table_const.cutsq = d_table->cutsq; d_table_const.tabindex = d_table->tabindex; + memset(&setflag[0][0],0,nt*nt*sizeof(int)); memset(&cutsq[0][0],0,nt*nt*sizeof(double)); memset(&tabindex[0][0],0,nt*nt*sizeof(int)); @@ -469,6 +468,17 @@ double PairTableRXKokkos::init_one(int i, int j) return tables[tabindex[i][j]].cut; } +/* ---------------------------------------------------------------------- + compute r,e,f vectors from splined values +------------------------------------------------------------------------- */ + +template +void PairTableRXKokkos::compute_table(Table *tb) +{ + update_table = 1; + PairTable::compute_table(tb); +} + template void PairTableRXKokkos::init_style() { @@ -496,91 +506,6 @@ void PairTableRXKokkos::init_style() } } -/* -template template -KOKKOS_INLINE_FUNCTION -void PairTableRXKokkos:: -ev_tally(EV_FLOAT &ev, const int &i, const int &j, const F_FLOAT &fpair, - const F_FLOAT &delx, const F_FLOAT &dely, const F_FLOAT &delz) const -{ - const int EFLAG = eflag; - const int NEWTON_PAIR = newton_pair; - const int VFLAG = vflag_either; - - if (EFLAG) { - if (eflag_atom) { - E_FLOAT epairhalf = 0.5 * (ev.evdwl + ev.ecoul); - if (NEWTON_PAIR || i < nlocal) eatom[i] += epairhalf; - if (NEWTON_PAIR || j < nlocal) eatom[j] += epairhalf; - } - } - - if (VFLAG) { - const E_FLOAT v0 = delx*delx*fpair; - const E_FLOAT v1 = dely*dely*fpair; - const E_FLOAT v2 = delz*delz*fpair; - const E_FLOAT v3 = delx*dely*fpair; - const E_FLOAT v4 = delx*delz*fpair; - const E_FLOAT v5 = dely*delz*fpair; - - if (vflag_global) { - if (NEIGHFLAG) { - if (NEWTON_PAIR) { - ev.v[0] += v0; - ev.v[1] += v1; - ev.v[2] += v2; - ev.v[3] += v3; - ev.v[4] += v4; - ev.v[5] += v5; - } else { - if (i < nlocal) { - ev.v[0] += 0.5*v0; - ev.v[1] += 0.5*v1; - ev.v[2] += 0.5*v2; - ev.v[3] += 0.5*v3; - ev.v[4] += 0.5*v4; - ev.v[5] += 0.5*v5; - } - if (j < nlocal) { - ev.v[0] += 0.5*v0; - ev.v[1] += 0.5*v1; - ev.v[2] += 0.5*v2; - ev.v[3] += 0.5*v3; - ev.v[4] += 0.5*v4; - ev.v[5] += 0.5*v5; - } - } - } else { - ev.v[0] += 0.5*v0; - ev.v[1] += 0.5*v1; - ev.v[2] += 0.5*v2; - ev.v[3] += 0.5*v3; - ev.v[4] += 0.5*v4; - ev.v[5] += 0.5*v5; - } - } - - if (vflag_atom) { - if (NEWTON_PAIR || i < nlocal) { - d_vatom(i,0) += 0.5*v0; - d_vatom(i,1) += 0.5*v1; - d_vatom(i,2) += 0.5*v2; - d_vatom(i,3) += 0.5*v3; - d_vatom(i,4) += 0.5*v4; - d_vatom(i,5) += 0.5*v5; - } - if (NEWTON_PAIR || (NEIGHFLAG && j < nlocal)) { - d_vatom(j,0) += 0.5*v0; - d_vatom(j,1) += 0.5*v1; - d_vatom(j,2) += 0.5*v2; - d_vatom(j,3) += 0.5*v3; - d_vatom(j,4) += 0.5*v4; - d_vatom(j,5) += 0.5*v5; - } - } - } -} -*/ template void PairTableRXKokkos::cleanup_copy() { // WHY needed: this prevents parent copy from deallocating any arrays diff --git a/src/KOKKOS/pair_table_rx_kokkos.h b/src/KOKKOS/pair_table_rx_kokkos.h index b379901201..c4e07d41d6 100644 --- a/src/KOKKOS/pair_table_rx_kokkos.h +++ b/src/KOKKOS/pair_table_rx_kokkos.h @@ -13,32 +13,21 @@ #ifdef PAIR_CLASS -PairStyle(table/rx/kk,PairTableRXKokkos) -PairStyle(table/rx/kk/device,PairTableRXKokkos) -PairStyle(table/rx/kk/host,PairTableRXKokkos) +PairStyle(table/rx/kk,PairTableKokkos) +PairStyle(table/rx/kk/device,PairTableKokkos) +PairStyle(table/rx/kk/host,PairTableKokkos) #else #ifndef LMP_PAIR_TABLE_RX_KOKKOS_H #define LMP_PAIR_TABLE_RX_KOKKOS_H -#include "pair_table_rx.h" -#include "pair_kokkos.h" -#include "neigh_list_kokkos.h" -#include "atom_kokkos.h" +#include "pair_table_kokkos.h" namespace LAMMPS_NS { -template -struct S_TableRXCompute { - enum {TabStyle = TABSTYLE}; -}; - -template -class PairTableRXComputeFunctor; - template -class PairTableRXKokkos : public PairTableRX { +class PairTableRXKokkos : public PairTable { public: enum {EnabledNeighFlags=FULL|HALFTHREAD|HALF|N2}; @@ -53,27 +42,14 @@ class PairTableRXKokkos : public PairTableRX { template void compute_style(int, int); - /*template - KOKKOS_FUNCTION - EV_FLOAT compute_item(const int& i, - const NeighListKokkos &list) const; -*/ void settings(int, char **); double init_one(int, int); + void init_style(); - protected: - enum{LOOKUP,LINEAR,SPLINE,BITMAP}; - int tabstyle,tablength; - /*struct TableDeviceConst { - typename ArrayTypes::t_ffloat_2d_randomread cutsq; - typename ArrayTypes::t_int_2d_randomread tabindex; - typename ArrayTypes::t_int_1d_randomread nshiftbits,nmask; - typename ArrayTypes::t_ffloat_1d_randomread innersq,invdelta,deltasq6; - typename ArrayTypes::t_ffloat_2d_randomread rsq,drsq,e,de,f,df,e2,f2; - };*/ - //Its faster not to use texture fetch if the number of tables is less than 32! + protected: + struct TableDeviceConst { typename ArrayTypes::t_ffloat_2d cutsq; typename ArrayTypes::t_int_2d tabindex; @@ -102,12 +78,12 @@ class PairTableRXKokkos : public PairTableRX { TableDevice* d_table; TableHost* h_table; - int **tabindex; F_FLOAT m_cutsq[MAX_TYPES_STACKPARAMS+1][MAX_TYPES_STACKPARAMS+1]; typename ArrayTypes::t_ffloat_2d d_cutsq; - void allocate(); + virtual void allocate(); + void compute_table(Table *); typename ArrayTypes::t_x_array_randomread x; typename ArrayTypes::t_x_array_const c_x; @@ -137,41 +113,41 @@ class PairTableRXKokkos : public PairTableRX { return 0; } - friend class PairComputeFunctor >; - friend class PairComputeFunctor >; - friend class PairComputeFunctor >; - friend class PairComputeFunctor >; - friend class PairComputeFunctor >; - friend class PairComputeFunctor >; - friend class PairComputeFunctor >; - friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; - friend class PairComputeFunctor >; - friend class PairComputeFunctor >; - friend class PairComputeFunctor >; - friend class PairComputeFunctor >; - friend class PairComputeFunctor >; - friend class PairComputeFunctor >; - friend class PairComputeFunctor >; - friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; - friend class PairComputeFunctor >; - friend class PairComputeFunctor >; - friend class PairComputeFunctor >; - friend class PairComputeFunctor >; - friend class PairComputeFunctor >; - friend class PairComputeFunctor >; - friend class PairComputeFunctor >; - friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; - friend class PairComputeFunctor >; - friend class PairComputeFunctor >; - friend class PairComputeFunctor >; - friend class PairComputeFunctor >; - friend class PairComputeFunctor >; - friend class PairComputeFunctor >; - friend class PairComputeFunctor >; - friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; + friend class PairComputeFunctor >; friend void pair_virial_fdotr_compute(PairTableRXKokkos*); }; @@ -183,79 +159,4 @@ class PairTableRXKokkos : public PairTableRX { /* ERROR/WARNING messages: -E: Pair distance < table inner cutoff - -Two atoms are closer together than the pairwise table allows. - -E: Pair distance > table outer cutoff - -Two atoms are further apart than the pairwise table allows. - -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: Unknown table style in pair_style command - -Style of table is invalid for use with pair_style table command. - -E: Illegal number of pair table entries - -There must be at least 2 table entries. - -E: Invalid pair table length - -Length of read-in pair table is invalid - -E: Invalid pair table cutoff - -Cutoffs in pair_coeff command are not valid with read-in pair table. - -E: Bitmapped table in file does not match requested table - -Setting for bitmapped table in pair_coeff command must match table -in file exactly. - -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. - -E: Cannot open file %s - -The specified file cannot be opened. Check that the path and name are -correct. If the file is a compressed file, also check that the gzip -executable can be found and run. - -E: Did not find keyword in table file - -Keyword used in pair_coeff command was not found in table file. - -E: Bitmapped table is incorrect length in table file - -Number of table entries is not a correct power of 2. - -E: Invalid keyword in pair table parameters - -Keyword used in list of table parameters is not recognized. - -E: Pair table parameters did not set N - -List of pair table parameters must include N setting. - -E: Pair table cutoffs must all be equal to use with KSpace - -When using pair style table with a long-range KSpace solver, the -cutoffs for all atom type pairs must all be the same, since the -long-range solver starts at that cutoff. - -E: Cannot use chosen neighbor list style with lj/cut/kk - -That style is not supported by Kokkos. - - - - -*/ \ No newline at end of file + */ From f995bb43355f412709cf3420d4b215f39d8bbf61 Mon Sep 17 00:00:00 2001 From: Dan Ibanez Date: Fri, 6 Jan 2017 16:00:35 -0700 Subject: [PATCH 059/439] starting to add getMixingWeights some compile errors to work out --- src/KOKKOS/pair_table_rx_kokkos.cpp | 82 +++++++++++++++++++++++++++++ src/KOKKOS/pair_table_rx_kokkos.h | 5 ++ 2 files changed, 87 insertions(+) diff --git a/src/KOKKOS/pair_table_rx_kokkos.cpp b/src/KOKKOS/pair_table_rx_kokkos.cpp index 2ccdefd05d..54882ec3ce 100644 --- a/src/KOKKOS/pair_table_rx_kokkos.cpp +++ b/src/KOKKOS/pair_table_rx_kokkos.cpp @@ -33,6 +33,15 @@ using namespace LAMMPS_NS; +#ifdef DBL_EPSILON + #define MY_EPSILON (10.0*DBL_EPSILON) +#else + #define MY_EPSILON (10.0*2.220446049250313e-16) +#endif + +#define OneFluidValue (-1) +#define isOneFluid(_site_) ( (_site_) == OneFluidValue ) + /* ---------------------------------------------------------------------- */ template @@ -516,6 +525,79 @@ void PairTableRXKokkos::cleanup_copy() { h_table=NULL; d_table=NULL; } +template +KOKKOS_INLINE_FUNCTION +void PairTableRXKokkos::getMixingWeights(typename DAT::t_float_2d_randomread dvector, int, double &, double &, double &, double &) { + double fractionOFAold, fractionOFA; + double fractionOld1, fraction1; + double fractionOld2, fraction2; + double nMoleculesOFAold, nMoleculesOFA; + double nMoleculesOld1, nMolecules1; + double nMoleculesOld2, nMolecules2; + double nTotal, nTotalOld; + + nTotal = 0.0; + nTotalOld = 0.0; + for (int ispecies = 0; ispecies < nspecies; ++ispecies){ + nTotal += dvector(ispecies,id); + nTotalOld += dvector(ispecies+nspecies,id); + } + if(nTotal < MY_EPSILON || nTotalOld < MY_EPSILON) + error->all(FLERR,"The number of molecules in CG particle is less than 10*DBL_EPSILON."); + + if (isOneFluid(isite1) == false){ + nMoleculesOld1 = dvector(isite1+nspecies,id); + nMolecules1 = dvector(isite1,id); + fractionOld1 = nMoleculesOld1/nTotalOld; + fraction1 = nMolecules1/nTotal; + } + if (isOneFluid(isite2) == false){ + nMoleculesOld2 = dvector(isite2+nspecies,id); + nMolecules2 = dvector(isite2,id); + fractionOld2 = nMoleculesOld2/nTotalOld; + fraction2 = nMolecules2/nTotal; + } + + if (isOneFluid(isite1) || isOneFluid(isite2)){ + nMoleculesOFAold = 0.0; + nMoleculesOFA = 0.0; + fractionOFAold = 0.0; + fractionOFA = 0.0; + + for (int ispecies = 0; ispecies < nspecies; ispecies++){ + if (isite1 == ispecies || isite2 == ispecies) continue; + nMoleculesOFAold += dvector(ispecies+nspecies,id); + nMoleculesOFA += dvector(ispecies,id); + fractionOFAold += dvector(ispecies+nspecies,id)/nTotalOld; + fractionOFA += dvector(ispecies,id)/nTotal; + } + if(isOneFluid(isite1)){ + nMoleculesOld1 = 1.0-(nTotalOld-nMoleculesOFAold); + nMolecules1 = 1.0-(nTotal-nMoleculesOFA); + fractionOld1 = fractionOFAold; + fraction1 = fractionOFA; + } + if(isOneFluid(isite2)){ + nMoleculesOld2 = 1.0-(nTotalOld-nMoleculesOFAold); + nMolecules2 = 1.0-(nTotal-nMoleculesOFA); + fractionOld2 = fractionOFAold; + fraction2 = fractionOFA; + } + } + + if(fractionalWeighting){ + mixWtSite1old = fractionOld1; + mixWtSite1 = fraction1; + mixWtSite2old = fractionOld2; + mixWtSite2 = fraction2; + } else { + mixWtSite1old = nMoleculesOld1; + mixWtSite1 = nMolecules1; + mixWtSite2old = nMoleculesOld2; + mixWtSite2 = nMolecules2; + } +} + namespace LAMMPS_NS { template class PairTableRXKokkos; #ifdef KOKKOS_HAVE_CUDA diff --git a/src/KOKKOS/pair_table_rx_kokkos.h b/src/KOKKOS/pair_table_rx_kokkos.h index c4e07d41d6..1878faf16c 100644 --- a/src/KOKKOS/pair_table_rx_kokkos.h +++ b/src/KOKKOS/pair_table_rx_kokkos.h @@ -30,6 +30,8 @@ template class PairTableRXKokkos : public PairTable { public: + using DAT = ArrayTypes; + enum {EnabledNeighFlags=FULL|HALFTHREAD|HALF|N2}; enum {COUL_FLAG=0}; typedef DeviceType device_type; @@ -150,6 +152,9 @@ class PairTableRXKokkos : public PairTable { friend class PairComputeFunctor >; friend void pair_virial_fdotr_compute(PairTableRXKokkos*); + + KOKKOS_INLINE_FUNCTION + void getMixingWeights(typename DAT::t_float_2d_randomread dvector, int, double &, double &, double &, double &); }; } From 21cde6261aa476d59e32788b036195c7ebb98498 Mon Sep 17 00:00:00 2001 From: Dan Ibanez Date: Mon, 9 Jan 2017 12:29:15 -0700 Subject: [PATCH 060/439] add member variables from PairTableRX --- src/KOKKOS/pair_table_rx_kokkos.cpp | 5 ++++- src/KOKKOS/pair_table_rx_kokkos.h | 9 ++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/KOKKOS/pair_table_rx_kokkos.cpp b/src/KOKKOS/pair_table_rx_kokkos.cpp index 54882ec3ce..83fcb2ce1d 100644 --- a/src/KOKKOS/pair_table_rx_kokkos.cpp +++ b/src/KOKKOS/pair_table_rx_kokkos.cpp @@ -527,7 +527,10 @@ void PairTableRXKokkos::cleanup_copy() { template KOKKOS_INLINE_FUNCTION -void PairTableRXKokkos::getMixingWeights(typename DAT::t_float_2d_randomread dvector, int, double &, double &, double &, double &) { +void PairTableRXKokkos::getMixingWeights( + typename DAT::t_float_2d_randomread dvector, int id, + double &mixWtSite1old, double &mixWtSite2old, + double &mixWtSite1, double &mixWtSite2) { double fractionOFAold, fractionOFA; double fractionOld1, fraction1; double fractionOld2, fraction2; diff --git a/src/KOKKOS/pair_table_rx_kokkos.h b/src/KOKKOS/pair_table_rx_kokkos.h index 1878faf16c..0d8a8f151e 100644 --- a/src/KOKKOS/pair_table_rx_kokkos.h +++ b/src/KOKKOS/pair_table_rx_kokkos.h @@ -153,8 +153,15 @@ class PairTableRXKokkos : public PairTable { friend void pair_virial_fdotr_compute(PairTableRXKokkos*); + /* PairTableRX members */ + + int nspecies; + char *site1, *site2; + int isite1, isite2; + bool fractionalWeighting; + KOKKOS_INLINE_FUNCTION - void getMixingWeights(typename DAT::t_float_2d_randomread dvector, int, double &, double &, double &, double &); + void getMixingWeights(typename DAT::t_float_2d_randomread, int, double &, double &, double &, double &); }; } From afbc6fc628b68baae2286c1c953a29dd78f1779e Mon Sep 17 00:00:00 2001 From: Dan Ibanez Date: Mon, 9 Jan 2017 13:17:23 -0700 Subject: [PATCH 061/439] added coeff, settings, single, fix compile --- src/KOKKOS/pair_table_rx_kokkos.cpp | 228 +++++++++++++++++++++++++++- src/KOKKOS/pair_table_rx_kokkos.h | 6 +- 2 files changed, 232 insertions(+), 2 deletions(-) diff --git a/src/KOKKOS/pair_table_rx_kokkos.cpp b/src/KOKKOS/pair_table_rx_kokkos.cpp index 83fcb2ce1d..5a71739b6d 100644 --- a/src/KOKKOS/pair_table_rx_kokkos.cpp +++ b/src/KOKKOS/pair_table_rx_kokkos.cpp @@ -30,9 +30,12 @@ #include "memory.h" #include "error.h" #include "atom_masks.h" +#include "fix.h" using namespace LAMMPS_NS; +enum{NONE,RLINEAR,RSQ,BMP}; + #ifdef DBL_EPSILON #define MY_EPSILON (10.0*DBL_EPSILON) #else @@ -54,6 +57,7 @@ PairTableRXKokkos::PairTableRXKokkos(LAMMPS *lmp) : PairTable(lmp) datamask_modify = F_MASK | ENERGY_MASK | VIRIAL_MASK; h_table = new TableHost(); d_table = new TableDevice(); + fractionalWeighting = true; } /* ---------------------------------------------------------------------- */ @@ -435,6 +439,8 @@ void PairTableRXKokkos::settings(int narg, char **arg) else if (strcmp(arg[iarg],"msm") == 0) msmflag = 1; else if (strcmp(arg[iarg],"dispersion") == 0) dispersionflag = 1; else if (strcmp(arg[iarg],"tip4p") == 0) tip4pflag = 1; + else if (strcmp(arg[iarg],"fractional") == 0) fractionalWeighting = true; + else if (strcmp(arg[iarg],"molecular") == 0) fractionalWeighting = false; else error->all(FLERR,"Illegal pair_style command"); iarg++; } @@ -459,6 +465,148 @@ void PairTableRXKokkos::settings(int narg, char **arg) tables = NULL; } +/* ---------------------------------------------------------------------- + set coeffs for one or more type pairs +------------------------------------------------------------------------- */ + +template +void PairTableRXKokkos::coeff(int narg, char **arg) +{ + if (narg != 6 && narg != 7) error->all(FLERR,"Illegal pair_coeff command"); + if (!allocated) allocate(); + + bool rx_flag = false; + for (int i = 0; i < modify->nfix; i++) + if (strncmp(modify->fix[i]->style,"rx",2) == 0) rx_flag = true; + if (!rx_flag) error->all(FLERR,"PairTableRX requires a fix rx command."); + + int ilo,ihi,jlo,jhi; + force->bounds(FLERR,arg[0],atom->ntypes,ilo,ihi); + force->bounds(FLERR,arg[1],atom->ntypes,jlo,jhi); + + int me; + MPI_Comm_rank(world,&me); + tables = (Table *) + memory->srealloc(tables,(ntables+1)*sizeof(Table),"pair:tables"); + Table *tb = &tables[ntables]; + null_table(tb); + if (me == 0) read_table(tb,arg[2],arg[3]); + bcast_table(tb); + + nspecies = atom->nspecies_dpd; + if(nspecies==0) error->all(FLERR,"There are no rx species specified."); + int n; + n = strlen(arg[3]) + 1; + site1 = new char[n]; + strcpy(site1,arg[4]); + + int ispecies; + for (ispecies = 0; ispecies < nspecies; ispecies++){ + if (strcmp(site1,&atom->dname[ispecies][0]) == 0) break; + } + if (ispecies == nspecies && strcmp(site1,"1fluid") != 0) + error->all(FLERR,"Site1 name not recognized in pair coefficients"); + + n = strlen(arg[4]) + 1; + site2 = new char[n]; + strcpy(site2,arg[5]); + + for (ispecies = 0; ispecies < nspecies; ispecies++){ + if (strcmp(site2,&atom->dname[ispecies][0]) == 0) break; + } + if (ispecies == nspecies && strcmp(site2,"1fluid") != 0) + error->all(FLERR,"Site2 name not recognized in pair coefficients"); + + // set table cutoff + + if (narg == 7) tb->cut = force->numeric(FLERR,arg[6]); + else if (tb->rflag) tb->cut = tb->rhi; + else tb->cut = tb->rfile[tb->ninput-1]; + + // error check on table parameters + // insure cutoff is within table + // for BITMAP tables, file values can be in non-ascending order + + if (tb->ninput <= 1) error->one(FLERR,"Invalid pair table length"); + double rlo,rhi; + if (tb->rflag == 0) { + rlo = tb->rfile[0]; + rhi = tb->rfile[tb->ninput-1]; + } else { + rlo = tb->rlo; + rhi = tb->rhi; + } + if (tb->cut <= rlo || tb->cut > rhi) + error->all(FLERR,"Invalid pair table cutoff"); + if (rlo <= 0.0) error->all(FLERR,"Invalid pair table cutoff"); + + // match = 1 if don't need to spline read-in tables + // this is only the case if r values needed by final tables + // exactly match r values read from file + // for tabstyle SPLINE, always need to build spline tables + + tb->match = 0; + if (tabstyle == LINEAR && tb->ninput == tablength && + tb->rflag == RSQ && tb->rhi == tb->cut) tb->match = 1; + if (tabstyle == BITMAP && tb->ninput == 1 << tablength && + tb->rflag == BMP && tb->rhi == tb->cut) tb->match = 1; + if (tb->rflag == BMP && tb->match == 0) + error->all(FLERR,"Bitmapped table in file does not match requested table"); + + // spline read-in values and compute r,e,f vectors within table + + if (tb->match == 0) spline_table(tb); + compute_table(tb); + + // store ptr to table in tabindex + + int count = 0; + for (int i = ilo; i <= ihi; i++) { + for (int j = MAX(jlo,i); j <= jhi; j++) { + tabindex[i][j] = ntables; + setflag[i][j] = 1; + count++; + } + } + + if (count == 0) error->all(FLERR,"Illegal pair_coeff command"); + ntables++; + + { + if ( strcmp(site1,"1fluid") == 0 ) + isite1 = OneFluidValue; + else { + isite1 = nspecies; + + for (int k = 0; k < nspecies; k++){ + if (strcmp(site1, atom->dname[k]) == 0){ + isite1 = k; + break; + } + } + + if (isite1 == nspecies) error->all(FLERR,"isite1 == nspecies"); + } + + if ( strcmp(site2,"1fluid") == 0 ) + isite2 = OneFluidValue; + else { + isite2 = nspecies; + + for (int k = 0; k < nspecies; k++){ + if (strcmp(site2, atom->dname[k]) == 0){ + isite2 = ispecies; + break; + } + } + + if (isite2 == nspecies) + error->all(FLERR,"isite2 == nspecies"); + } + } + +} + /* ---------------------------------------------------------------------- init for one type pair i,j and corresponding j,i ------------------------------------------------------------------------- */ @@ -477,6 +625,82 @@ double PairTableRXKokkos::init_one(int i, int j) return tables[tabindex[i][j]].cut; } +/* ---------------------------------------------------------------------- */ + +template +double PairTableRXKokkos::single(int i, int j, int itype, int jtype, double rsq, + double factor_coul, double factor_lj, + double &fforce) +{ + int itable; + double fraction,value,a,b,phi; + int tlm1 = tablength - 1; + + Table *tb = &tables[tabindex[itype][jtype]]; + double mixWtSite1_i, mixWtSite1_j; + double mixWtSite2_i, mixWtSite2_j; + double mixWtSite1old_i, mixWtSite1old_j; + double mixWtSite2old_i, mixWtSite2old_j; + + fraction = 0.0; + a = 0.0; + b = 0.0; + + typename ArrayTypes::t_float_2d_randomread h_dvector = + atomKK->k_dvector.view(); + getMixingWeights(h_dvector,i,mixWtSite1old_i,mixWtSite2old_i, + mixWtSite1_i,mixWtSite2_i); + getMixingWeights(h_dvector,j,mixWtSite1old_j,mixWtSite2old_j, + mixWtSite1_j,mixWtSite2_j); + + if (rsq < tb->innersq) error->one(FLERR,"Pair distance < table inner cutoff"); + + if (tabstyle == LOOKUP) { + itable = static_cast ((rsq-tb->innersq) * tb->invdelta); + if (itable >= tlm1) error->one(FLERR,"Pair distance > table outer cutoff"); + fforce = factor_lj * tb->f[itable]; + } else if (tabstyle == LINEAR) { + itable = static_cast ((rsq-tb->innersq) * tb->invdelta); + if (itable >= tlm1) error->one(FLERR,"Pair distance > table outer cutoff"); + fraction = (rsq - tb->rsq[itable]) * tb->invdelta; + value = tb->f[itable] + fraction*tb->df[itable]; + fforce = factor_lj * value; + } else if (tabstyle == SPLINE) { + itable = static_cast ((rsq-tb->innersq) * tb->invdelta); + if (itable >= tlm1) error->one(FLERR,"Pair distance > table outer cutoff"); + b = (rsq - tb->rsq[itable]) * tb->invdelta; + a = 1.0 - b; + value = a * tb->f[itable] + b * tb->f[itable+1] + + ((a*a*a-a)*tb->f2[itable] + (b*b*b-b)*tb->f2[itable+1]) * + tb->deltasq6; + fforce = factor_lj * value; + } else { + union_int_float_t rsq_lookup; + rsq_lookup.f = rsq; + itable = rsq_lookup.i & tb->nmask; + itable >>= tb->nshiftbits; + fraction = (rsq_lookup.f - tb->rsq[itable]) * tb->drsq[itable]; + value = tb->f[itable] + fraction*tb->df[itable]; + fforce = factor_lj * value; + } + + if (isite1 == isite2) fforce = sqrt(mixWtSite1_i*mixWtSite2_j)*fforce; + else fforce = (sqrt(mixWtSite1_i*mixWtSite2_j) + sqrt(mixWtSite2_i*mixWtSite1_j))*fforce; + + if (tabstyle == LOOKUP) + phi = tb->e[itable]; + else if (tabstyle == LINEAR || tabstyle == BITMAP) + phi = tb->e[itable] + fraction*tb->de[itable]; + else + phi = a * tb->e[itable] + b * tb->e[itable+1] + + ((a*a*a-a)*tb->e2[itable] + (b*b*b-b)*tb->e2[itable+1]) * tb->deltasq6; + + if (isite1 == isite2) phi = sqrt(mixWtSite1_i*mixWtSite2_j)*phi; + else phi = (sqrt(mixWtSite1_i*mixWtSite2_j) + sqrt(mixWtSite2_i*mixWtSite1_j))*phi; + + return factor_lj*phi; +} + /* ---------------------------------------------------------------------- compute r,e,f vectors from splined values ------------------------------------------------------------------------- */ @@ -526,9 +750,11 @@ void PairTableRXKokkos::cleanup_copy() { } template +template KOKKOS_INLINE_FUNCTION void PairTableRXKokkos::getMixingWeights( - typename DAT::t_float_2d_randomread dvector, int id, + typename ArrayTypes::t_float_2d_randomread dvector, + int id, double &mixWtSite1old, double &mixWtSite2old, double &mixWtSite1, double &mixWtSite2) { double fractionOFAold, fractionOFA; diff --git a/src/KOKKOS/pair_table_rx_kokkos.h b/src/KOKKOS/pair_table_rx_kokkos.h index 0d8a8f151e..de6de61429 100644 --- a/src/KOKKOS/pair_table_rx_kokkos.h +++ b/src/KOKKOS/pair_table_rx_kokkos.h @@ -45,7 +45,9 @@ class PairTableRXKokkos : public PairTable { void compute_style(int, int); void settings(int, char **); + void coeff(int, char **); double init_one(int, int); + virtual double single(int, int, int, int, double, double, double, double &); void init_style(); @@ -160,8 +162,10 @@ class PairTableRXKokkos : public PairTable { int isite1, isite2; bool fractionalWeighting; + template KOKKOS_INLINE_FUNCTION - void getMixingWeights(typename DAT::t_float_2d_randomread, int, double &, double &, double &, double &); + void getMixingWeights(typename ArrayTypes::t_float_2d_randomread, + int, double &, double &, double &, double &); }; } From 4d5abe64d5cef0e1299bc7d43ac4482f25333d4f Mon Sep 17 00:00:00 2001 From: Dan Ibanez Date: Mon, 9 Jan 2017 14:04:03 -0700 Subject: [PATCH 062/439] draft compute_fpair for PairTableRXKokkos --- src/KOKKOS/pair_table_rx_kokkos.cpp | 21 ++++++++++++++++++--- src/KOKKOS/pair_table_rx_kokkos.h | 5 +++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/KOKKOS/pair_table_rx_kokkos.cpp b/src/KOKKOS/pair_table_rx_kokkos.cpp index 5a71739b6d..bb6c034dc0 100644 --- a/src/KOKKOS/pair_table_rx_kokkos.cpp +++ b/src/KOKKOS/pair_table_rx_kokkos.cpp @@ -53,7 +53,7 @@ PairTableRXKokkos::PairTableRXKokkos(LAMMPS *lmp) : PairTable(lmp) update_table = 0; atomKK = (AtomKokkos *) atom; execution_space = ExecutionSpaceFromDevice::space; - datamask_read = X_MASK | F_MASK | TYPE_MASK | ENERGY_MASK | VIRIAL_MASK; + datamask_read = X_MASK | F_MASK | TYPE_MASK | ENERGY_MASK | VIRIAL_MASK | DVECTOR_MASK; datamask_modify = F_MASK | ENERGY_MASK | VIRIAL_MASK; h_table = new TableHost(); d_table = new TableDevice(); @@ -121,6 +121,19 @@ void PairTableRXKokkos::compute_style(int eflag_in, int vflag_in) d_cutsq = d_table->cutsq; // loop over neighbors of my atoms + const int ntotal = atom->nlocal + atom->nghost; + mixWtSite1old_ = Kokkos::View("PairTableRxKokkos::mixWtSite1old", ntotal); + mixWtSite2old_ = Kokkos::View("PairTableRxKokkos::mixWtSite2old", ntotal); + mixWtSite1_ = Kokkos::View("PairTableRxKokkos::mixWtSite1", ntotal); + mixWtSite2_ = Kokkos::View("PairTableRxKokkos::mixWtSite2", ntotal); + + typename DAT::t_float_2d_randomread d_dvector = atomKK->k_dvector.view(); + + Kokkos::parallel_for(ntotal, LAMMPS_LAMBDA(int i) { + getMixingWeights(d_dvector, i, mixWtSite1old_(i), mixWtSite2old_(i), + mixWtSite1_(i), mixWtSite2_(i)); + }); + EV_FLOAT ev; if(atom->ntypes > MAX_TYPES_STACKPARAMS) { if (neighflag == FULL) { @@ -186,8 +199,6 @@ template KOKKOS_INLINE_FUNCTION F_FLOAT PairTableRXKokkos:: compute_fpair(const F_FLOAT& rsq, const int& i, const int&j, const int& itype, const int& jtype) const { - (void) i; - (void) j; union_int_float_t rsq_lookup; double fpair; const int tidx = d_table_const.tabindex(itype,jtype); @@ -212,6 +223,9 @@ compute_fpair(const F_FLOAT& rsq, const int& i, const int&j, const int& itype, c const double fraction = (rsq_lookup.f - d_table_const.rsq(tidx,itable)) * d_table_const.drsq(tidx,itable); fpair = d_table_const.f(tidx,itable) + fraction*d_table_const.df(tidx,itable); } + if (isite1 == isite2) fpair *= sqrt(mixWtSite1old_(i) * mixWtSite2old_(j)); + else fpair *= (sqrt(mixWtSite1old_(i) * mixWtSite2old_(j)) + + sqrt(mixWtSite2old_(i) * mixWtSite1old_(j))); return fpair; } @@ -646,6 +660,7 @@ double PairTableRXKokkos::single(int i, int j, int itype, int jtype, a = 0.0; b = 0.0; + atomKK->k_dvector.template sync(); typename ArrayTypes::t_float_2d_randomread h_dvector = atomKK->k_dvector.view(); getMixingWeights(h_dvector,i,mixWtSite1old_i,mixWtSite2old_i, diff --git a/src/KOKKOS/pair_table_rx_kokkos.h b/src/KOKKOS/pair_table_rx_kokkos.h index de6de61429..a0d937549f 100644 --- a/src/KOKKOS/pair_table_rx_kokkos.h +++ b/src/KOKKOS/pair_table_rx_kokkos.h @@ -166,6 +166,11 @@ class PairTableRXKokkos : public PairTable { KOKKOS_INLINE_FUNCTION void getMixingWeights(typename ArrayTypes::t_float_2d_randomread, int, double &, double &, double &, double &); + + Kokkos::View mixWtSite1old_; + Kokkos::View mixWtSite2old_; + Kokkos::View mixWtSite1_; + Kokkos::View mixWtSite2_; }; } From c877c07491e32160f42dbde04a7e34e5f6637b57 Mon Sep 17 00:00:00 2001 From: Dan Ibanez Date: Mon, 9 Jan 2017 16:21:32 -0700 Subject: [PATCH 063/439] progress towards custom compute functor which is needed to handle uCG contributions. --- src/KOKKOS/pair_table_rx_kokkos.cpp | 220 ++++++++++++++++++++++++++-- src/KOKKOS/pair_table_rx_kokkos.h | 76 +++++----- 2 files changed, 237 insertions(+), 59 deletions(-) diff --git a/src/KOKKOS/pair_table_rx_kokkos.cpp b/src/KOKKOS/pair_table_rx_kokkos.cpp index bb6c034dc0..cc0a416ad9 100644 --- a/src/KOKKOS/pair_table_rx_kokkos.cpp +++ b/src/KOKKOS/pair_table_rx_kokkos.cpp @@ -90,6 +90,195 @@ void PairTableRXKokkos::compute(int eflag_in, int vflag_in) compute_style(eflag_in,vflag_in); } +template +template +PairTableRXKokkos::Full::Functor( + PairTableRXKokkos* c_ptr, NeighListKokkos* list_ptr): + c(*c_ptr),f(c.f),list(*list_ptr) +{} + +template +template +PairTableRXKokkos::Full::~Functor() { + c.cleanup_copy(); + list.clean_copy(); +} + +template +template +template +KOKKOS_INLINE_FUNCTION +EV_FLOAT +PairTableRXKokkos::Functor:: +compute_item(const int& ii) { + EV_FLOAT ev; + const int i = list.d_ilist[ii]; + const X_FLOAT xtmp = c.x(i,0); + const X_FLOAT ytmp = c.x(i,1); + const X_FLOAT ztmp = c.x(i,2); + const int itype = c.type(i); + + const AtomNeighborsConst jlist = list.get_neighbors_const(i); + const int jnum = list.d_numneigh[i]; + + double uCG_i = 0.0; + double uCGnew_i = 0.0; + double fx_i = 0.0, fy_i = 0.0, fz_i = 0.0; + + double mixWtSite1old_i = mixWtSite1old(i); + double mixWtSite2old_i = mixWtSite2old(i); + double mixWtSite1_i = mixWtSite1(i); + double mixWtSite2_i = mixWtSite2(i); + + for (int jj = 0; jj < jnum; jj++) { + int j = jlist(jj); + const F_FLOAT factor_lj = c.special_lj[sbmask(j)]; + j &= NEIGHMASK; + + const X_FLOAT delx = xtmp - c.x(j,0); + const X_FLOAT dely = ytmp - c.x(j,1); + const X_FLOAT delz = ztmp - c.x(j,2); + const F_FLOAT rsq = delx*delx + dely*dely + delz*delz; + const int jtype = c.type(j); + + if(rsq < (STACKPARAMS?c.m_cutsq[itype][jtype]:c.d_cutsq(itype,jtype))) { + double mixWtSite1old_j = mixWtSite1old[j]; + double mixWtSite2old_j = mixWtSite2old[j]; + double mixWtSite1_j = mixWtSite1[j]; + double mixWtSite2_j = mixWtSite2[j]; + + const F_FLOAT fpair = factor_lj*c.template compute_fpair(rsq,i,j,itype,jtype); + + fx_i += delx*fpair; + fy_i += dely*fpair; + fz_i += delz*fpair; + + bool do_half = (NEIGHFLAG==HALF || NEIGHFLAG==HALFTHREAD) && + (NEWTON_PAIR || j < c.nlocal); + if (do_half) { + f(j,0) -= delx*fpair; + f(j,1) -= dely*fpair; + f(j,2) -= delz*fpair; + } + + auto evdwl = c.template compute_evdwl(rsq,i,j,itype,jtype); + + double evdwlOld; + if (isite1 == isite2) { + evdwlOld = sqrt(mixWtSite1old_i*mixWtSite2old_j)*evdwl; + evdwl = sqrt(mixWtSite1_i*mixWtSite2_j)*evdwl; + } else { + evdwlOld = (sqrt(mixWtSite1old_i*mixWtSite2old_j) + + sqrt(mixWtSite2old_i*mixWtSite1old_j))*evdwl; + evdwl = (sqrt(mixWtSite1_i*mixWtSite2_j) + + sqrt(mixWtSite2_i*mixWtSite1_j))*evdwl; + } + evdwlOld *= factor_lj; + evdwl *= factor_lj; + + uCG_i += 0.5*evdwlOld; + if (do_half) uCG(j) += 0.5*evdwlOld; + + uCGnew_i += 0.5*evdwl; + if (do_half) uCGnew(j) += 0.5*evdwl; + evdwl = evdwlOld; + + ev.evdwl += (do_half ? 1.0 : 0.5)*evdwl; + + if (EVFLAG) ev_tally(ev,i,j,evdwl,fpair,delx,dely,delz); + } + } + + uCG(i) += uCG_i; + uCGnew(i) += uCGnew_i; + + f(i,0) += fx_i; + f(i,1) += fy_i; + f(i,2) += fz_i; + + return ev; +} + +template +template +KOKKOS_INLINE_FUNCTION +void +PairTableRXKokkos::Functor:: +ev_tally(EV_FLOAT &ev, const int &i, const int &j, + const F_FLOAT &epair, const F_FLOAT &fpair, const F_FLOAT &delx, + const F_FLOAT &dely, const F_FLOAT &delz) const +{ + const int EFLAG = c.eflag; + const int NEWTON_PAIR = c.newton_pair; + const int VFLAG = c.vflag_either; + + if (VFLAG) { + const E_FLOAT v0 = delx*delx*fpair; + const E_FLOAT v1 = dely*dely*fpair; + const E_FLOAT v2 = delz*delz*fpair; + const E_FLOAT v3 = delx*dely*fpair; + const E_FLOAT v4 = delx*delz*fpair; + const E_FLOAT v5 = dely*delz*fpair; + + if (c.vflag_global) { + if (NEIGHFLAG!=FULL) { + if (NEWTON_PAIR) { + ev.v[0] += v0; + ev.v[1] += v1; + ev.v[2] += v2; + ev.v[3] += v3; + ev.v[4] += v4; + ev.v[5] += v5; + } else { + if (i < c.nlocal) { + ev.v[0] += 0.5*v0; + ev.v[1] += 0.5*v1; + ev.v[2] += 0.5*v2; + ev.v[3] += 0.5*v3; + ev.v[4] += 0.5*v4; + ev.v[5] += 0.5*v5; + } + if (j < c.nlocal) { + ev.v[0] += 0.5*v0; + ev.v[1] += 0.5*v1; + ev.v[2] += 0.5*v2; + ev.v[3] += 0.5*v3; + ev.v[4] += 0.5*v4; + ev.v[5] += 0.5*v5; + } + } + } else { + ev.v[0] += 0.5*v0; + ev.v[1] += 0.5*v1; + ev.v[2] += 0.5*v2; + ev.v[3] += 0.5*v3; + ev.v[4] += 0.5*v4; + ev.v[5] += 0.5*v5; + } + } + } +} + +template +template +KOKKOS_INLINE_FUNCTION +void +PairTableRXKokkos::Functor:: +operator()(const int i) const { + if (c.newton_pair) compute_item<0,1>(i); + else compute_item<0,0>(i); +} + +template +template +KOKKOS_INLINE_FUNCTION +void +PairTableRXKokkos::Functor:: +operator()(const int i, value_type &energy_virial) const { + if (c.newton_pair) energy_virial += compute_item<1,1>(i); + else energy_virial += compute_item<1,0>(i); +} + template template void PairTableRXKokkos::compute_style(int eflag_in, int vflag_in) @@ -102,9 +291,10 @@ void PairTableRXKokkos::compute_style(int eflag_in, int vflag_in) if (eflag || vflag) ev_setup(eflag,vflag); else evflag = vflag_fdotr = 0; + if (eflag_atom) error->all(FLERR, "pair table/rx/kk does not handle eflag_atom\n"); + if (vflag_atom) error->all(FLERR, "pair table/rx/kk does not handle vflag_atom\n"); + atomKK->sync(execution_space,datamask_read); - //k_cutsq.template sync(); - //k_params.template sync(); if (eflag || vflag) atomKK->modified(execution_space,datamask_modify); else atomKK->modified(execution_space,F_MASK); @@ -122,10 +312,10 @@ void PairTableRXKokkos::compute_style(int eflag_in, int vflag_in) // loop over neighbors of my atoms const int ntotal = atom->nlocal + atom->nghost; - mixWtSite1old_ = Kokkos::View("PairTableRxKokkos::mixWtSite1old", ntotal); - mixWtSite2old_ = Kokkos::View("PairTableRxKokkos::mixWtSite2old", ntotal); - mixWtSite1_ = Kokkos::View("PairTableRxKokkos::mixWtSite1", ntotal); - mixWtSite2_ = Kokkos::View("PairTableRxKokkos::mixWtSite2", ntotal); + mixWtSite1old_ = Kokkos::View("PairTableRXKokkos::mixWtSite1old", ntotal); + mixWtSite2old_ = Kokkos::View("PairTableRXKokkos::mixWtSite2old", ntotal); + mixWtSite1_ = Kokkos::View("PairTableRXKokkos::mixWtSite1", ntotal); + mixWtSite2_ = Kokkos::View("PairTableRXKokkos::mixWtSite2", ntotal); typename DAT::t_float_2d_randomread d_dvector = atomKK->k_dvector.view(); @@ -195,21 +385,21 @@ void PairTableRXKokkos::compute_style(int eflag_in, int vflag_in) } template -template +template KOKKOS_INLINE_FUNCTION F_FLOAT PairTableRXKokkos:: compute_fpair(const F_FLOAT& rsq, const int& i, const int&j, const int& itype, const int& jtype) const { union_int_float_t rsq_lookup; double fpair; const int tidx = d_table_const.tabindex(itype,jtype); - if (Specialisation::TabStyle == LOOKUP) { + if (TABSTYLE == LOOKUP) { const int itable = static_cast ((rsq - d_table_const.innersq(tidx)) * d_table_const.invdelta(tidx)); fpair = d_table_const.f(tidx,itable); - } else if (Specialisation::TabStyle == LINEAR) { + } else if (TABSTYLE == LINEAR) { const int itable = static_cast ((rsq - d_table_const.innersq(tidx)) * d_table_const.invdelta(tidx)); const double fraction = (rsq - d_table_const.rsq(tidx,itable)) * d_table_const.invdelta(tidx); fpair = d_table_const.f(tidx,itable) + fraction*d_table_const.df(tidx,itable); - } else if (Specialisation::TabStyle == SPLINE) { + } else if (TABSTYLE == SPLINE) { const int itable = static_cast ((rsq - d_table_const.innersq(tidx)) * d_table_const.invdelta(tidx)); const double b = (rsq - d_table_const.rsq(tidx,itable)) * d_table_const.invdelta(tidx); const double a = 1.0 - b; @@ -230,23 +420,21 @@ compute_fpair(const F_FLOAT& rsq, const int& i, const int&j, const int& itype, c } template -template +template KOKKOS_INLINE_FUNCTION F_FLOAT PairTableRXKokkos:: compute_evdwl(const F_FLOAT& rsq, const int& i, const int&j, const int& itype, const int& jtype) const { - (void) i; - (void) j; double evdwl; union_int_float_t rsq_lookup; const int tidx = d_table_const.tabindex(itype,jtype); - if (Specialisation::TabStyle == LOOKUP) { + if (TABSTYLE == LOOKUP) { const int itable = static_cast ((rsq - d_table_const.innersq(tidx)) * d_table_const.invdelta(tidx)); evdwl = d_table_const.e(tidx,itable); - } else if (Specialisation::TabStyle == LINEAR) { + } else if (TABSTYLE == LINEAR) { const int itable = static_cast ((rsq - d_table_const.innersq(tidx)) * d_table_const.invdelta(tidx)); const double fraction = (rsq - d_table_const.rsq(tidx,itable)) * d_table_const.invdelta(tidx); evdwl = d_table_const.e(tidx,itable) + fraction*d_table_const.de(tidx,itable); - } else if (Specialisation::TabStyle == SPLINE) { + } else if (TABSTYLE == SPLINE) { const int itable = static_cast ((rsq - d_table_const.innersq(tidx)) * d_table_const.invdelta(tidx)); const double b = (rsq - d_table_const.rsq(tidx,itable)) * d_table_const.invdelta(tidx); const double a = 1.0 - b; diff --git a/src/KOKKOS/pair_table_rx_kokkos.h b/src/KOKKOS/pair_table_rx_kokkos.h index a0d937549f..f717dc3f8a 100644 --- a/src/KOKKOS/pair_table_rx_kokkos.h +++ b/src/KOKKOS/pair_table_rx_kokkos.h @@ -33,7 +33,6 @@ class PairTableRXKokkos : public PairTable { using DAT = ArrayTypes; enum {EnabledNeighFlags=FULL|HALFTHREAD|HALF|N2}; - enum {COUL_FLAG=0}; typedef DeviceType device_type; PairTableRXKokkos(class LAMMPS *); @@ -111,48 +110,6 @@ class PairTableRXKokkos : public PairTable { KOKKOS_INLINE_FUNCTION F_FLOAT compute_evdwl(const F_FLOAT& rsq, const int& i, const int&j, const int& itype, const int& jtype) const; - template - KOKKOS_INLINE_FUNCTION - F_FLOAT compute_ecoul(const F_FLOAT& rsq, const int& i, const int&j, const int& itype, const int& jtype) const { - return 0; - } - - friend class PairComputeFunctor >; - friend class PairComputeFunctor >; - friend class PairComputeFunctor >; - friend class PairComputeFunctor >; - friend class PairComputeFunctor >; - friend class PairComputeFunctor >; - friend class PairComputeFunctor >; - friend class PairComputeFunctor >; - - friend class PairComputeFunctor >; - friend class PairComputeFunctor >; - friend class PairComputeFunctor >; - friend class PairComputeFunctor >; - friend class PairComputeFunctor >; - friend class PairComputeFunctor >; - friend class PairComputeFunctor >; - friend class PairComputeFunctor >; - - friend class PairComputeFunctor >; - friend class PairComputeFunctor >; - friend class PairComputeFunctor >; - friend class PairComputeFunctor >; - friend class PairComputeFunctor >; - friend class PairComputeFunctor >; - friend class PairComputeFunctor >; - friend class PairComputeFunctor >; - - friend class PairComputeFunctor >; - friend class PairComputeFunctor >; - friend class PairComputeFunctor >; - friend class PairComputeFunctor >; - friend class PairComputeFunctor >; - friend class PairComputeFunctor >; - friend class PairComputeFunctor >; - friend class PairComputeFunctor >; - friend void pair_virial_fdotr_compute(PairTableRXKokkos*); /* PairTableRX members */ @@ -171,6 +128,39 @@ class PairTableRXKokkos : public PairTable { Kokkos::View mixWtSite2old_; Kokkos::View mixWtSite1_; Kokkos::View mixWtSite2_; + + /* a duplicate of PairComputeFunctor to deal with uCG */ + template + struct Functor { + using device_type = DeviceType; + typedef EV_FLOAT value_type; + PairTableRXKokkos c; + // arrays are atomic for Half(Thread) neighbor style + Kokkos::View::value> > f; + Kokkos::View::value> > uCG; + Kokkos::View::value> > uCGnew; + NeighListKokkos list; + Functor(PairTableRXKokkos* c_ptr, NeighListKokkos* list_ptr); + ~Functor(); + KOKKOS_INLINE_FUNCTION int sbmask(const int& j) const { + return j >> SBBITS & 3; + } + template + KOKKOS_INLINE_FUNCTION + EV_FLOAT compute_item(const int&, + const NeighListKokkos&, const NoCoulTag&) const; + KOKKOS_INLINE_FUNCTION + ev_tally(EV_FLOAT &ev, const int &i, const int &j, + const F_FLOAT &epair, const F_FLOAT &fpair, const F_FLOAT &delx, + const F_FLOAT &dely, const F_FLOAT &delz) const + KOKKOS_INLINE_FUNCTION + void operator()(const int) const; + KOKKOS_INLINE_FUNCTION + void operator()(const int, value_type&) const; + }; }; } From e4673d7fa80b40dca606c4cf85f92e2f6d2b098b Mon Sep 17 00:00:00 2001 From: Dan Ibanez Date: Mon, 9 Jan 2017 16:36:25 -0700 Subject: [PATCH 064/439] fix compilation --- src/KOKKOS/pair_table_rx_kokkos.cpp | 52 +++++++++++++---------------- src/KOKKOS/pair_table_rx_kokkos.h | 10 +++--- 2 files changed, 28 insertions(+), 34 deletions(-) diff --git a/src/KOKKOS/pair_table_rx_kokkos.cpp b/src/KOKKOS/pair_table_rx_kokkos.cpp index cc0a416ad9..26e335fcff 100644 --- a/src/KOKKOS/pair_table_rx_kokkos.cpp +++ b/src/KOKKOS/pair_table_rx_kokkos.cpp @@ -92,14 +92,14 @@ void PairTableRXKokkos::compute(int eflag_in, int vflag_in) template template -PairTableRXKokkos::Full::Functor( +PairTableRXKokkos::Functor::Functor( PairTableRXKokkos* c_ptr, NeighListKokkos* list_ptr): c(*c_ptr),f(c.f),list(*list_ptr) {} template template -PairTableRXKokkos::Full::~Functor() { +PairTableRXKokkos::Functor::~Functor() { c.cleanup_copy(); list.clean_copy(); } @@ -110,7 +110,7 @@ template KOKKOS_INLINE_FUNCTION EV_FLOAT PairTableRXKokkos::Functor:: -compute_item(const int& ii) { +compute_item(const int& ii) const { EV_FLOAT ev; const int i = list.d_ilist[ii]; const X_FLOAT xtmp = c.x(i,0); @@ -125,10 +125,10 @@ compute_item(const int& ii) { double uCGnew_i = 0.0; double fx_i = 0.0, fy_i = 0.0, fz_i = 0.0; - double mixWtSite1old_i = mixWtSite1old(i); - double mixWtSite2old_i = mixWtSite2old(i); - double mixWtSite1_i = mixWtSite1(i); - double mixWtSite2_i = mixWtSite2(i); + double mixWtSite1old_i = c.mixWtSite1old_(i); + double mixWtSite2old_i = c.mixWtSite2old_(i); + double mixWtSite1_i = c.mixWtSite1_(i); + double mixWtSite2_i = c.mixWtSite2_(i); for (int jj = 0; jj < jnum; jj++) { int j = jlist(jj); @@ -142,12 +142,12 @@ compute_item(const int& ii) { const int jtype = c.type(j); if(rsq < (STACKPARAMS?c.m_cutsq[itype][jtype]:c.d_cutsq(itype,jtype))) { - double mixWtSite1old_j = mixWtSite1old[j]; - double mixWtSite2old_j = mixWtSite2old[j]; - double mixWtSite1_j = mixWtSite1[j]; - double mixWtSite2_j = mixWtSite2[j]; + double mixWtSite1old_j = c.mixWtSite1old_(j); + double mixWtSite2old_j = c.mixWtSite2old_(j); + double mixWtSite1_j = c.mixWtSite1_(j); + double mixWtSite2_j = c.mixWtSite2_(j); - const F_FLOAT fpair = factor_lj*c.template compute_fpair(rsq,i,j,itype,jtype); + const F_FLOAT fpair = factor_lj*c.template compute_fpair(rsq,i,j,itype,jtype); fx_i += delx*fpair; fy_i += dely*fpair; @@ -164,7 +164,7 @@ compute_item(const int& ii) { auto evdwl = c.template compute_evdwl(rsq,i,j,itype,jtype); double evdwlOld; - if (isite1 == isite2) { + if (c.isite1 == c.isite2) { evdwlOld = sqrt(mixWtSite1old_i*mixWtSite2old_j)*evdwl; evdwl = sqrt(mixWtSite1_i*mixWtSite2_j)*evdwl; } else { @@ -324,48 +324,42 @@ void PairTableRXKokkos::compute_style(int eflag_in, int vflag_in) mixWtSite1_(i), mixWtSite2_(i)); }); + if (neighflag == N2) error->all(FLERR,"pair table/rx/kk can't handle N2 yet\n"); + EV_FLOAT ev; if(atom->ntypes > MAX_TYPES_STACKPARAMS) { if (neighflag == FULL) { - PairComputeFunctor,FULL,false,S_TableCompute > - ff(this,(NeighListKokkos*) list); + Functor ff(this,(NeighListKokkos*) list); if (eflag || vflag) Kokkos::parallel_reduce(list->inum,ff,ev); else Kokkos::parallel_for(list->inum,ff); } else if (neighflag == HALFTHREAD) { - PairComputeFunctor,HALFTHREAD,false,S_TableCompute > - ff(this,(NeighListKokkos*) list); + Functor ff(this,(NeighListKokkos*) list); if (eflag || vflag) Kokkos::parallel_reduce(list->inum,ff,ev); else Kokkos::parallel_for(list->inum,ff); } else if (neighflag == HALF) { - PairComputeFunctor,HALF,false,S_TableCompute > - f(this,(NeighListKokkos*) list); + Functor f(this,(NeighListKokkos*) list); if (eflag || vflag) Kokkos::parallel_reduce(list->inum,f,ev); else Kokkos::parallel_for(list->inum,f); } else if (neighflag == N2) { - PairComputeFunctor,N2,false,S_TableCompute > - f(this,(NeighListKokkos*) list); + Functor f(this,(NeighListKokkos*) list); if (eflag || vflag) Kokkos::parallel_reduce(nlocal,f,ev); else Kokkos::parallel_for(nlocal,f); } } else { if (neighflag == FULL) { - PairComputeFunctor,FULL,true,S_TableCompute > - f(this,(NeighListKokkos*) list); + Functor f(this,(NeighListKokkos*) list); if (eflag || vflag) Kokkos::parallel_reduce(list->inum,f,ev); else Kokkos::parallel_for(list->inum,f); } else if (neighflag == HALFTHREAD) { - PairComputeFunctor,HALFTHREAD,true,S_TableCompute > - f(this,(NeighListKokkos*) list); + Functor f(this,(NeighListKokkos*) list); if (eflag || vflag) Kokkos::parallel_reduce(list->inum,f,ev); else Kokkos::parallel_for(list->inum,f); } else if (neighflag == HALF) { - PairComputeFunctor,HALF,true,S_TableCompute > - f(this,(NeighListKokkos*) list); + Functor f(this,(NeighListKokkos*) list); if (eflag || vflag) Kokkos::parallel_reduce(list->inum,f,ev); else Kokkos::parallel_for(list->inum,f); } else if (neighflag == N2) { - PairComputeFunctor,N2,true,S_TableCompute > - f(this,(NeighListKokkos*) list); + Functor f(this,(NeighListKokkos*) list); if (eflag || vflag) Kokkos::parallel_reduce(nlocal,f,ev); else Kokkos::parallel_for(nlocal,f); } diff --git a/src/KOKKOS/pair_table_rx_kokkos.h b/src/KOKKOS/pair_table_rx_kokkos.h index f717dc3f8a..c468461263 100644 --- a/src/KOKKOS/pair_table_rx_kokkos.h +++ b/src/KOKKOS/pair_table_rx_kokkos.h @@ -102,11 +102,11 @@ class PairTableRXKokkos : public PairTable { void create_kokkos_tables(); void cleanup_copy(); - template + template KOKKOS_INLINE_FUNCTION F_FLOAT compute_fpair(const F_FLOAT& rsq, const int& i, const int&j, const int& itype, const int& jtype) const; - template + template KOKKOS_INLINE_FUNCTION F_FLOAT compute_evdwl(const F_FLOAT& rsq, const int& i, const int&j, const int& itype, const int& jtype) const; @@ -150,12 +150,12 @@ class PairTableRXKokkos : public PairTable { } template KOKKOS_INLINE_FUNCTION - EV_FLOAT compute_item(const int&, - const NeighListKokkos&, const NoCoulTag&) const; + EV_FLOAT compute_item(const int&) const; KOKKOS_INLINE_FUNCTION + void ev_tally(EV_FLOAT &ev, const int &i, const int &j, const F_FLOAT &epair, const F_FLOAT &fpair, const F_FLOAT &delx, - const F_FLOAT &dely, const F_FLOAT &delz) const + const F_FLOAT &dely, const F_FLOAT &delz) const; KOKKOS_INLINE_FUNCTION void operator()(const int) const; KOKKOS_INLINE_FUNCTION From 5d5751be190b198c8e8c48526d40217e0c443255 Mon Sep 17 00:00:00 2001 From: Dan Ibanez Date: Tue, 10 Jan 2017 12:38:48 -0700 Subject: [PATCH 065/439] fix class name in PAIR_CLASS setup --- src/KOKKOS/pair_table_rx_kokkos.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/KOKKOS/pair_table_rx_kokkos.h b/src/KOKKOS/pair_table_rx_kokkos.h index c468461263..de9ae20e35 100644 --- a/src/KOKKOS/pair_table_rx_kokkos.h +++ b/src/KOKKOS/pair_table_rx_kokkos.h @@ -13,9 +13,9 @@ #ifdef PAIR_CLASS -PairStyle(table/rx/kk,PairTableKokkos) -PairStyle(table/rx/kk/device,PairTableKokkos) -PairStyle(table/rx/kk/host,PairTableKokkos) +PairStyle(table/rx/kk,PairTableRXKokkos) +PairStyle(table/rx/kk/device,PairTableRXKokkos) +PairStyle(table/rx/kk/host,PairTableRXKokkos) #else From 55aa91be6b88670dc16658883e30bfe0710e695e Mon Sep 17 00:00:00 2001 From: Dan Ibanez Date: Tue, 10 Jan 2017 13:07:22 -0700 Subject: [PATCH 066/439] copy uCG and uCGnew correctly --- src/KOKKOS/pair_table_rx_kokkos.cpp | 9 ++++++--- src/KOKKOS/pair_table_rx_kokkos.h | 2 ++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/KOKKOS/pair_table_rx_kokkos.cpp b/src/KOKKOS/pair_table_rx_kokkos.cpp index 26e335fcff..0cb2f11efc 100644 --- a/src/KOKKOS/pair_table_rx_kokkos.cpp +++ b/src/KOKKOS/pair_table_rx_kokkos.cpp @@ -53,8 +53,9 @@ PairTableRXKokkos::PairTableRXKokkos(LAMMPS *lmp) : PairTable(lmp) update_table = 0; atomKK = (AtomKokkos *) atom; execution_space = ExecutionSpaceFromDevice::space; - datamask_read = X_MASK | F_MASK | TYPE_MASK | ENERGY_MASK | VIRIAL_MASK | DVECTOR_MASK; - datamask_modify = F_MASK | ENERGY_MASK | VIRIAL_MASK; + datamask_read = X_MASK | F_MASK | TYPE_MASK | ENERGY_MASK | VIRIAL_MASK | + DVECTOR_MASK | UCG_MASK | UCGNEW_MASK; + datamask_modify = F_MASK | ENERGY_MASK | VIRIAL_MASK | UCG_MASK | UCGNEW_MASK; h_table = new TableHost(); d_table = new TableDevice(); fractionalWeighting = true; @@ -94,7 +95,7 @@ template template PairTableRXKokkos::Functor::Functor( PairTableRXKokkos* c_ptr, NeighListKokkos* list_ptr): - c(*c_ptr),f(c.f),list(*list_ptr) + c(*c_ptr),f(c.f),uCG(c.uCG),uCGnew(c.uCGnew),list(*list_ptr) {} template @@ -301,6 +302,8 @@ void PairTableRXKokkos::compute_style(int eflag_in, int vflag_in) x = c_x = atomKK->k_x.view(); f = atomKK->k_f.view(); type = atomKK->k_type.view(); + uCG = atomKK->k_uCG.view(); + uCGnew = atomKK->k_uCGnew.view(); nlocal = atom->nlocal; nall = atom->nlocal + atom->nghost; special_lj[0] = force->special_lj[0]; diff --git a/src/KOKKOS/pair_table_rx_kokkos.h b/src/KOKKOS/pair_table_rx_kokkos.h index de9ae20e35..ad8071800f 100644 --- a/src/KOKKOS/pair_table_rx_kokkos.h +++ b/src/KOKKOS/pair_table_rx_kokkos.h @@ -92,6 +92,8 @@ class PairTableRXKokkos : public PairTable { typename ArrayTypes::t_x_array_const c_x; typename ArrayTypes::t_f_array f; typename ArrayTypes::t_int_1d_randomread type; + typename ArrayTypes::t_efloat_1d uCG; + typename ArrayTypes::t_efloat_1d uCGnew; typename ArrayTypes::t_efloat_1d d_eatom; typename ArrayTypes::t_virial_array d_vatom; From d65676e981bdb5d8a9cc2c4dad9c8dfb09ea1d74 Mon Sep 17 00:00:00 2001 From: Dan Ibanez Date: Tue, 10 Jan 2017 16:08:55 -0700 Subject: [PATCH 067/439] make everything public to appease NVCC --- src/KOKKOS/pair_table_rx_kokkos.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/KOKKOS/pair_table_rx_kokkos.h b/src/KOKKOS/pair_table_rx_kokkos.h index ad8071800f..ed0f0c2eb2 100644 --- a/src/KOKKOS/pair_table_rx_kokkos.h +++ b/src/KOKKOS/pair_table_rx_kokkos.h @@ -50,9 +50,6 @@ class PairTableRXKokkos : public PairTable { void init_style(); - - protected: - struct TableDeviceConst { typename ArrayTypes::t_ffloat_2d cutsq; typename ArrayTypes::t_int_2d tabindex; @@ -97,7 +94,6 @@ class PairTableRXKokkos : public PairTable { typename ArrayTypes::t_efloat_1d d_eatom; typename ArrayTypes::t_virial_array d_vatom; - protected: int nlocal,nall,eflag,vflag,neighflag,newton_pair; int update_table; @@ -163,6 +159,7 @@ class PairTableRXKokkos : public PairTable { KOKKOS_INLINE_FUNCTION void operator()(const int, value_type&) const; }; + }; } From 6a9a0e8c334f60ccc8a6e4a8ff19308cac09a156 Mon Sep 17 00:00:00 2001 From: Dan Ibanez Date: Wed, 11 Jan 2017 09:25:13 -0700 Subject: [PATCH 068/439] tracking down some invalid reads... --- src/KOKKOS/Install.sh | 4 +- src/KOKKOS/pair_table_rx_kokkos.cpp | 252 ++++++++++++++-------------- src/KOKKOS/pair_table_rx_kokkos.h | 4 +- 3 files changed, 129 insertions(+), 131 deletions(-) diff --git a/src/KOKKOS/Install.sh b/src/KOKKOS/Install.sh index cfda7dbf94..e76f62d65d 100644 --- a/src/KOKKOS/Install.sh +++ b/src/KOKKOS/Install.sh @@ -28,8 +28,8 @@ action () { # force rebuild of files with LMP_KOKKOS switch -touch ../accelerator_kokkos.h -touch ../memory.h +#touch ../accelerator_kokkos.h +#touch ../memory.h # list of files with optional dependcies diff --git a/src/KOKKOS/pair_table_rx_kokkos.cpp b/src/KOKKOS/pair_table_rx_kokkos.cpp index 0cb2f11efc..6c7c7b0efe 100644 --- a/src/KOKKOS/pair_table_rx_kokkos.cpp +++ b/src/KOKKOS/pair_table_rx_kokkos.cpp @@ -94,15 +94,15 @@ void PairTableRXKokkos::compute(int eflag_in, int vflag_in) template template PairTableRXKokkos::Functor::Functor( - PairTableRXKokkos* c_ptr, NeighListKokkos* list_ptr): - c(*c_ptr),f(c.f),uCG(c.uCG),uCGnew(c.uCGnew),list(*list_ptr) + PairTableRXKokkos* c_ptr, NeighListKokkos* list_ptr)//: +//c(*c_ptr),f(c.f),uCG(c.uCG),uCGnew(c.uCGnew),list(*list_ptr) {} template template PairTableRXKokkos::Functor::~Functor() { - c.cleanup_copy(); - list.clean_copy(); +//c.cleanup_copy(); +//list.clean_copy(); } template @@ -113,89 +113,89 @@ EV_FLOAT PairTableRXKokkos::Functor:: compute_item(const int& ii) const { EV_FLOAT ev; - const int i = list.d_ilist[ii]; - const X_FLOAT xtmp = c.x(i,0); - const X_FLOAT ytmp = c.x(i,1); - const X_FLOAT ztmp = c.x(i,2); - const int itype = c.type(i); +//const int i = list.d_ilist[ii]; +//const X_FLOAT xtmp = c.x(i,0); +//const X_FLOAT ytmp = c.x(i,1); +//const X_FLOAT ztmp = c.x(i,2); +//const int itype = c.type(i); - const AtomNeighborsConst jlist = list.get_neighbors_const(i); - const int jnum = list.d_numneigh[i]; +//const AtomNeighborsConst jlist = list.get_neighbors_const(i); +//const int jnum = list.d_numneigh[i]; - double uCG_i = 0.0; - double uCGnew_i = 0.0; - double fx_i = 0.0, fy_i = 0.0, fz_i = 0.0; +//double uCG_i = 0.0; +//double uCGnew_i = 0.0; +//double fx_i = 0.0, fy_i = 0.0, fz_i = 0.0; - double mixWtSite1old_i = c.mixWtSite1old_(i); - double mixWtSite2old_i = c.mixWtSite2old_(i); - double mixWtSite1_i = c.mixWtSite1_(i); - double mixWtSite2_i = c.mixWtSite2_(i); +//double mixWtSite1old_i = c.mixWtSite1old_(i); +//double mixWtSite2old_i = c.mixWtSite2old_(i); +//double mixWtSite1_i = c.mixWtSite1_(i); +//double mixWtSite2_i = c.mixWtSite2_(i); - for (int jj = 0; jj < jnum; jj++) { - int j = jlist(jj); - const F_FLOAT factor_lj = c.special_lj[sbmask(j)]; - j &= NEIGHMASK; +//for (int jj = 0; jj < jnum; jj++) { +// int j = jlist(jj); +// const F_FLOAT factor_lj = c.special_lj[sbmask(j)]; +// j &= NEIGHMASK; - const X_FLOAT delx = xtmp - c.x(j,0); - const X_FLOAT dely = ytmp - c.x(j,1); - const X_FLOAT delz = ztmp - c.x(j,2); - const F_FLOAT rsq = delx*delx + dely*dely + delz*delz; - const int jtype = c.type(j); +// const X_FLOAT delx = xtmp - c.x(j,0); +// const X_FLOAT dely = ytmp - c.x(j,1); +// const X_FLOAT delz = ztmp - c.x(j,2); +// const F_FLOAT rsq = delx*delx + dely*dely + delz*delz; +// const int jtype = c.type(j); - if(rsq < (STACKPARAMS?c.m_cutsq[itype][jtype]:c.d_cutsq(itype,jtype))) { - double mixWtSite1old_j = c.mixWtSite1old_(j); - double mixWtSite2old_j = c.mixWtSite2old_(j); - double mixWtSite1_j = c.mixWtSite1_(j); - double mixWtSite2_j = c.mixWtSite2_(j); +// if(rsq < (STACKPARAMS?c.m_cutsq[itype][jtype]:c.d_cutsq(itype,jtype))) { +// double mixWtSite1old_j = c.mixWtSite1old_(j); +// double mixWtSite2old_j = c.mixWtSite2old_(j); +// double mixWtSite1_j = c.mixWtSite1_(j); +// double mixWtSite2_j = c.mixWtSite2_(j); - const F_FLOAT fpair = factor_lj*c.template compute_fpair(rsq,i,j,itype,jtype); +// const F_FLOAT fpair = factor_lj*c.template compute_fpair(rsq,i,j,itype,jtype); - fx_i += delx*fpair; - fy_i += dely*fpair; - fz_i += delz*fpair; +// fx_i += delx*fpair; +// fy_i += dely*fpair; +// fz_i += delz*fpair; - bool do_half = (NEIGHFLAG==HALF || NEIGHFLAG==HALFTHREAD) && - (NEWTON_PAIR || j < c.nlocal); - if (do_half) { - f(j,0) -= delx*fpair; - f(j,1) -= dely*fpair; - f(j,2) -= delz*fpair; - } +// bool do_half = (NEIGHFLAG==HALF || NEIGHFLAG==HALFTHREAD) && +// (NEWTON_PAIR || j < c.nlocal); +// if (do_half) { +// f(j,0) -= delx*fpair; +// f(j,1) -= dely*fpair; +// f(j,2) -= delz*fpair; +// } - auto evdwl = c.template compute_evdwl(rsq,i,j,itype,jtype); +// auto evdwl = c.template compute_evdwl(rsq,i,j,itype,jtype); - double evdwlOld; - if (c.isite1 == c.isite2) { - evdwlOld = sqrt(mixWtSite1old_i*mixWtSite2old_j)*evdwl; - evdwl = sqrt(mixWtSite1_i*mixWtSite2_j)*evdwl; - } else { - evdwlOld = (sqrt(mixWtSite1old_i*mixWtSite2old_j) + - sqrt(mixWtSite2old_i*mixWtSite1old_j))*evdwl; - evdwl = (sqrt(mixWtSite1_i*mixWtSite2_j) + - sqrt(mixWtSite2_i*mixWtSite1_j))*evdwl; - } - evdwlOld *= factor_lj; - evdwl *= factor_lj; +// double evdwlOld; +// if (c.isite1 == c.isite2) { +// evdwlOld = sqrt(mixWtSite1old_i*mixWtSite2old_j)*evdwl; +// evdwl = sqrt(mixWtSite1_i*mixWtSite2_j)*evdwl; +// } else { +// evdwlOld = (sqrt(mixWtSite1old_i*mixWtSite2old_j) + +// sqrt(mixWtSite2old_i*mixWtSite1old_j))*evdwl; +// evdwl = (sqrt(mixWtSite1_i*mixWtSite2_j) + +// sqrt(mixWtSite2_i*mixWtSite1_j))*evdwl; +// } +// evdwlOld *= factor_lj; +// evdwl *= factor_lj; - uCG_i += 0.5*evdwlOld; - if (do_half) uCG(j) += 0.5*evdwlOld; +// uCG_i += 0.5*evdwlOld; +// if (do_half) uCG(j) += 0.5*evdwlOld; - uCGnew_i += 0.5*evdwl; - if (do_half) uCGnew(j) += 0.5*evdwl; - evdwl = evdwlOld; +// uCGnew_i += 0.5*evdwl; +// if (do_half) uCGnew(j) += 0.5*evdwl; +// evdwl = evdwlOld; - ev.evdwl += (do_half ? 1.0 : 0.5)*evdwl; +// ev.evdwl += (do_half ? 1.0 : 0.5)*evdwl; - if (EVFLAG) ev_tally(ev,i,j,evdwl,fpair,delx,dely,delz); - } - } +// if (EVFLAG) ev_tally(ev,i,j,evdwl,fpair,delx,dely,delz); +// } +//} - uCG(i) += uCG_i; - uCGnew(i) += uCGnew_i; +//uCG(i) += uCG_i; +//uCGnew(i) += uCGnew_i; - f(i,0) += fx_i; - f(i,1) += fy_i; - f(i,2) += fz_i; +//f(i,0) += fx_i; +//f(i,1) += fy_i; +//f(i,2) += fz_i; return ev; } @@ -209,55 +209,55 @@ ev_tally(EV_FLOAT &ev, const int &i, const int &j, const F_FLOAT &epair, const F_FLOAT &fpair, const F_FLOAT &delx, const F_FLOAT &dely, const F_FLOAT &delz) const { - const int EFLAG = c.eflag; - const int NEWTON_PAIR = c.newton_pair; - const int VFLAG = c.vflag_either; +//const int EFLAG = c.eflag; +//const int NEWTON_PAIR = c.newton_pair; +//const int VFLAG = c.vflag_either; - if (VFLAG) { - const E_FLOAT v0 = delx*delx*fpair; - const E_FLOAT v1 = dely*dely*fpair; - const E_FLOAT v2 = delz*delz*fpair; - const E_FLOAT v3 = delx*dely*fpair; - const E_FLOAT v4 = delx*delz*fpair; - const E_FLOAT v5 = dely*delz*fpair; +//if (VFLAG) { +// const E_FLOAT v0 = delx*delx*fpair; +// const E_FLOAT v1 = dely*dely*fpair; +// const E_FLOAT v2 = delz*delz*fpair; +// const E_FLOAT v3 = delx*dely*fpair; +// const E_FLOAT v4 = delx*delz*fpair; +// const E_FLOAT v5 = dely*delz*fpair; - if (c.vflag_global) { - if (NEIGHFLAG!=FULL) { - if (NEWTON_PAIR) { - ev.v[0] += v0; - ev.v[1] += v1; - ev.v[2] += v2; - ev.v[3] += v3; - ev.v[4] += v4; - ev.v[5] += v5; - } else { - if (i < c.nlocal) { - ev.v[0] += 0.5*v0; - ev.v[1] += 0.5*v1; - ev.v[2] += 0.5*v2; - ev.v[3] += 0.5*v3; - ev.v[4] += 0.5*v4; - ev.v[5] += 0.5*v5; - } - if (j < c.nlocal) { - ev.v[0] += 0.5*v0; - ev.v[1] += 0.5*v1; - ev.v[2] += 0.5*v2; - ev.v[3] += 0.5*v3; - ev.v[4] += 0.5*v4; - ev.v[5] += 0.5*v5; - } - } - } else { - ev.v[0] += 0.5*v0; - ev.v[1] += 0.5*v1; - ev.v[2] += 0.5*v2; - ev.v[3] += 0.5*v3; - ev.v[4] += 0.5*v4; - ev.v[5] += 0.5*v5; - } - } - } +// if (c.vflag_global) { +// if (NEIGHFLAG!=FULL) { +// if (NEWTON_PAIR) { +// ev.v[0] += v0; +// ev.v[1] += v1; +// ev.v[2] += v2; +// ev.v[3] += v3; +// ev.v[4] += v4; +// ev.v[5] += v5; +// } else { +// if (i < c.nlocal) { +// ev.v[0] += 0.5*v0; +// ev.v[1] += 0.5*v1; +// ev.v[2] += 0.5*v2; +// ev.v[3] += 0.5*v3; +// ev.v[4] += 0.5*v4; +// ev.v[5] += 0.5*v5; +// } +// if (j < c.nlocal) { +// ev.v[0] += 0.5*v0; +// ev.v[1] += 0.5*v1; +// ev.v[2] += 0.5*v2; +// ev.v[3] += 0.5*v3; +// ev.v[4] += 0.5*v4; +// ev.v[5] += 0.5*v5; +// } +// } +// } else { +// ev.v[0] += 0.5*v0; +// ev.v[1] += 0.5*v1; +// ev.v[2] += 0.5*v2; +// ev.v[3] += 0.5*v3; +// ev.v[4] += 0.5*v4; +// ev.v[5] += 0.5*v5; +// } +// } +//} } template @@ -266,8 +266,8 @@ KOKKOS_INLINE_FUNCTION void PairTableRXKokkos::Functor:: operator()(const int i) const { - if (c.newton_pair) compute_item<0,1>(i); - else compute_item<0,0>(i); +//if (c.newton_pair) compute_item<0,1>(i); +//else compute_item<0,0>(i); } template @@ -276,8 +276,8 @@ KOKKOS_INLINE_FUNCTION void PairTableRXKokkos::Functor:: operator()(const int i, value_type &energy_virial) const { - if (c.newton_pair) energy_virial += compute_item<1,1>(i); - else energy_virial += compute_item<1,0>(i); +//if (c.newton_pair) energy_virial += compute_item<1,1>(i); +//else energy_virial += compute_item<1,0>(i); } template @@ -322,10 +322,10 @@ void PairTableRXKokkos::compute_style(int eflag_in, int vflag_in) typename DAT::t_float_2d_randomread d_dvector = atomKK->k_dvector.view(); - Kokkos::parallel_for(ntotal, LAMMPS_LAMBDA(int i) { - getMixingWeights(d_dvector, i, mixWtSite1old_(i), mixWtSite2old_(i), - mixWtSite1_(i), mixWtSite2_(i)); - }); +//Kokkos::parallel_for(ntotal, LAMMPS_LAMBDA(int i) { +// getMixingWeights(d_dvector, i, mixWtSite1old_(i), mixWtSite2old_(i), +// mixWtSite1_(i), mixWtSite2_(i)); +//}); if (neighflag == N2) error->all(FLERR,"pair table/rx/kk can't handle N2 yet\n"); @@ -971,8 +971,6 @@ void PairTableRXKokkos::getMixingWeights( nTotal += dvector(ispecies,id); nTotalOld += dvector(ispecies+nspecies,id); } - if(nTotal < MY_EPSILON || nTotalOld < MY_EPSILON) - error->all(FLERR,"The number of molecules in CG particle is less than 10*DBL_EPSILON."); if (isOneFluid(isite1) == false){ nMoleculesOld1 = dvector(isite1+nspecies,id); diff --git a/src/KOKKOS/pair_table_rx_kokkos.h b/src/KOKKOS/pair_table_rx_kokkos.h index ed0f0c2eb2..b71f57076d 100644 --- a/src/KOKKOS/pair_table_rx_kokkos.h +++ b/src/KOKKOS/pair_table_rx_kokkos.h @@ -132,7 +132,7 @@ class PairTableRXKokkos : public PairTable { struct Functor { using device_type = DeviceType; typedef EV_FLOAT value_type; - PairTableRXKokkos c; + //PairTableRXKokkos c; // arrays are atomic for Half(Thread) neighbor style Kokkos::View::value> > f; @@ -140,7 +140,7 @@ class PairTableRXKokkos : public PairTable { device_type,Kokkos::MemoryTraits::value> > uCG; Kokkos::View::value> > uCGnew; - NeighListKokkos list; + //NeighListKokkos list; Functor(PairTableRXKokkos* c_ptr, NeighListKokkos* list_ptr); ~Functor(); KOKKOS_INLINE_FUNCTION int sbmask(const int& j) const { From b5ff41f5efedd0aea4674263c7f4d620308e3100 Mon Sep 17 00:00:00 2001 From: Dan Ibanez Date: Wed, 11 Jan 2017 11:10:33 -0700 Subject: [PATCH 069/439] made MixingWeights code non-member CUDA was simply giving too many errors dealing with captures of member variables. --- src/KOKKOS/pair_table_rx_kokkos.cpp | 199 ++++++++++++++++------------ 1 file changed, 114 insertions(+), 85 deletions(-) diff --git a/src/KOKKOS/pair_table_rx_kokkos.cpp b/src/KOKKOS/pair_table_rx_kokkos.cpp index 6c7c7b0efe..63db613538 100644 --- a/src/KOKKOS/pair_table_rx_kokkos.cpp +++ b/src/KOKKOS/pair_table_rx_kokkos.cpp @@ -31,6 +31,7 @@ #include "error.h" #include "atom_masks.h" #include "fix.h" +#include using namespace LAMMPS_NS; @@ -45,6 +46,92 @@ enum{NONE,RLINEAR,RSQ,BMP}; #define OneFluidValue (-1) #define isOneFluid(_site_) ( (_site_) == OneFluidValue ) +template +KOKKOS_INLINE_FUNCTION +void getMixingWeights( + typename ArrayTypes::t_float_2d_randomread dvector, + int nspecies, + int isite1, int isite2, + bool fractionalWeighting, + int id, + double &mixWtSite1old, double &mixWtSite2old, + double &mixWtSite1, double &mixWtSite2) { + double fractionOFAold, fractionOFA; + double fractionOld1, fraction1; + double fractionOld2, fraction2; + double nMoleculesOFAold, nMoleculesOFA; + double nMoleculesOld1, nMolecules1; + double nMoleculesOld2, nMolecules2; + double nTotal, nTotalOld; + + nTotal = 0.0; + nTotalOld = 0.0; + assert(id >= 0); + assert(id < dvector.dimension_1()); + for (int ispecies = 0; ispecies < nspecies; ++ispecies){ + assert(ispecies < dvector.dimension_0()); + nTotal += dvector(ispecies,id); + assert(ispecies+nspecies < dvector.dimension_0()); + nTotalOld += dvector(ispecies+nspecies,id); + } + + assert(isite1 >= 0); + assert(isite1 < nspecies); + assert(isite2 >= 0); + assert(isite2 < nspecies); + if (isOneFluid(isite1) == false){ + nMoleculesOld1 = dvector(isite1+nspecies,id); + nMolecules1 = dvector(isite1,id); + fractionOld1 = nMoleculesOld1/nTotalOld; + fraction1 = nMolecules1/nTotal; + } + if (isOneFluid(isite2) == false){ + nMoleculesOld2 = dvector(isite2+nspecies,id); + nMolecules2 = dvector(isite2,id); + fractionOld2 = nMoleculesOld2/nTotalOld; + fraction2 = nMolecules2/nTotal; + } + + if (isOneFluid(isite1) || isOneFluid(isite2)){ + nMoleculesOFAold = 0.0; + nMoleculesOFA = 0.0; + fractionOFAold = 0.0; + fractionOFA = 0.0; + + for (int ispecies = 0; ispecies < nspecies; ispecies++){ + if (isite1 == ispecies || isite2 == ispecies) continue; + nMoleculesOFAold += dvector(ispecies+nspecies,id); + nMoleculesOFA += dvector(ispecies,id); + fractionOFAold += dvector(ispecies+nspecies,id)/nTotalOld; + fractionOFA += dvector(ispecies,id)/nTotal; + } + if(isOneFluid(isite1)){ + nMoleculesOld1 = 1.0-(nTotalOld-nMoleculesOFAold); + nMolecules1 = 1.0-(nTotal-nMoleculesOFA); + fractionOld1 = fractionOFAold; + fraction1 = fractionOFA; + } + if(isOneFluid(isite2)){ + nMoleculesOld2 = 1.0-(nTotalOld-nMoleculesOFAold); + nMolecules2 = 1.0-(nTotal-nMoleculesOFA); + fractionOld2 = fractionOFAold; + fraction2 = fractionOFA; + } + } + + if(fractionalWeighting){ + mixWtSite1old = fractionOld1; + mixWtSite1 = fraction1; + mixWtSite2old = fractionOld2; + mixWtSite2 = fraction2; + } else { + mixWtSite1old = nMoleculesOld1; + mixWtSite1 = nMolecules1; + mixWtSite2old = nMoleculesOld2; + mixWtSite2 = nMolecules2; + } +} + /* ---------------------------------------------------------------------- */ template @@ -280,6 +367,24 @@ operator()(const int i, value_type &energy_virial) const { //else energy_virial += compute_item<1,0>(i); } +template +static void getAllMixingWeights( + int ntotal, + typename ArrayTypes::t_float_2d_randomread dvector, + int nspecies, + int isite1, int isite2, + bool fractionalWeighting, + Kokkos::View mixWtSite1old, + Kokkos::View mixWtSite2old, + Kokkos::View mixWtSite1, + Kokkos::View mixWtSite2) { + Kokkos::parallel_for(ntotal, + LAMMPS_LAMBDA(int i) { + getMixingWeights(dvector,nspecies,isite1,isite2,fractionalWeighting, + i, mixWtSite1old(i), mixWtSite2old(i), mixWtSite1(i), mixWtSite2(i)); + }); +} + template template void PairTableRXKokkos::compute_style(int eflag_in, int vflag_in) @@ -320,12 +425,9 @@ void PairTableRXKokkos::compute_style(int eflag_in, int vflag_in) mixWtSite1_ = Kokkos::View("PairTableRXKokkos::mixWtSite1", ntotal); mixWtSite2_ = Kokkos::View("PairTableRXKokkos::mixWtSite2", ntotal); - typename DAT::t_float_2d_randomread d_dvector = atomKK->k_dvector.view(); - -//Kokkos::parallel_for(ntotal, LAMMPS_LAMBDA(int i) { -// getMixingWeights(d_dvector, i, mixWtSite1old_(i), mixWtSite2old_(i), -// mixWtSite1_(i), mixWtSite2_(i)); -//}); + getAllMixingWeights(ntotal, atomKK->k_dvector.template view(), + nspecies, isite1, isite2, fractionalWeighting, + mixWtSite1old_, mixWtSite2old_, mixWtSite1_, mixWtSite2_); if (neighflag == N2) error->all(FLERR,"pair table/rx/kk can't handle N2 yet\n"); @@ -848,9 +950,13 @@ double PairTableRXKokkos::single(int i, int j, int itype, int jtype, atomKK->k_dvector.template sync(); typename ArrayTypes::t_float_2d_randomread h_dvector = atomKK->k_dvector.view(); - getMixingWeights(h_dvector,i,mixWtSite1old_i,mixWtSite2old_i, + getMixingWeights(h_dvector, + nspecies, isite1, isite2, fractionalWeighting, + i,mixWtSite1old_i,mixWtSite2old_i, mixWtSite1_i,mixWtSite2_i); - getMixingWeights(h_dvector,j,mixWtSite1old_j,mixWtSite2old_j, + getMixingWeights(h_dvector, + nspecies, isite1, isite2, fractionalWeighting, + j,mixWtSite1old_j,mixWtSite2old_j, mixWtSite1_j,mixWtSite2_j); if (rsq < tb->innersq) error->one(FLERR,"Pair distance < table inner cutoff"); @@ -948,83 +1054,6 @@ void PairTableRXKokkos::cleanup_copy() { vatom = NULL; h_table=NULL; d_table=NULL; } - -template -template -KOKKOS_INLINE_FUNCTION -void PairTableRXKokkos::getMixingWeights( - typename ArrayTypes::t_float_2d_randomread dvector, - int id, - double &mixWtSite1old, double &mixWtSite2old, - double &mixWtSite1, double &mixWtSite2) { - double fractionOFAold, fractionOFA; - double fractionOld1, fraction1; - double fractionOld2, fraction2; - double nMoleculesOFAold, nMoleculesOFA; - double nMoleculesOld1, nMolecules1; - double nMoleculesOld2, nMolecules2; - double nTotal, nTotalOld; - - nTotal = 0.0; - nTotalOld = 0.0; - for (int ispecies = 0; ispecies < nspecies; ++ispecies){ - nTotal += dvector(ispecies,id); - nTotalOld += dvector(ispecies+nspecies,id); - } - - if (isOneFluid(isite1) == false){ - nMoleculesOld1 = dvector(isite1+nspecies,id); - nMolecules1 = dvector(isite1,id); - fractionOld1 = nMoleculesOld1/nTotalOld; - fraction1 = nMolecules1/nTotal; - } - if (isOneFluid(isite2) == false){ - nMoleculesOld2 = dvector(isite2+nspecies,id); - nMolecules2 = dvector(isite2,id); - fractionOld2 = nMoleculesOld2/nTotalOld; - fraction2 = nMolecules2/nTotal; - } - - if (isOneFluid(isite1) || isOneFluid(isite2)){ - nMoleculesOFAold = 0.0; - nMoleculesOFA = 0.0; - fractionOFAold = 0.0; - fractionOFA = 0.0; - - for (int ispecies = 0; ispecies < nspecies; ispecies++){ - if (isite1 == ispecies || isite2 == ispecies) continue; - nMoleculesOFAold += dvector(ispecies+nspecies,id); - nMoleculesOFA += dvector(ispecies,id); - fractionOFAold += dvector(ispecies+nspecies,id)/nTotalOld; - fractionOFA += dvector(ispecies,id)/nTotal; - } - if(isOneFluid(isite1)){ - nMoleculesOld1 = 1.0-(nTotalOld-nMoleculesOFAold); - nMolecules1 = 1.0-(nTotal-nMoleculesOFA); - fractionOld1 = fractionOFAold; - fraction1 = fractionOFA; - } - if(isOneFluid(isite2)){ - nMoleculesOld2 = 1.0-(nTotalOld-nMoleculesOFAold); - nMolecules2 = 1.0-(nTotal-nMoleculesOFA); - fractionOld2 = fractionOFAold; - fraction2 = fractionOFA; - } - } - - if(fractionalWeighting){ - mixWtSite1old = fractionOld1; - mixWtSite1 = fraction1; - mixWtSite2old = fractionOld2; - mixWtSite2 = fraction2; - } else { - mixWtSite1old = nMoleculesOld1; - mixWtSite1 = nMolecules1; - mixWtSite2old = nMoleculesOld2; - mixWtSite2 = nMolecules2; - } -} - namespace LAMMPS_NS { template class PairTableRXKokkos; #ifdef KOKKOS_HAVE_CUDA From cb9fdf7801bed0d31e08286fee04655f13ea0435 Mon Sep 17 00:00:00 2001 From: Dan Ibanez Date: Wed, 11 Jan 2017 11:44:54 -0700 Subject: [PATCH 070/439] starting to separate compute_item from the class --- src/KOKKOS/neigh_list_kokkos.h | 10 +- src/KOKKOS/pair_table_rx_kokkos.cpp | 211 ++++++++++++++++++---------- src/KOKKOS/pair_table_rx_kokkos.h | 7 - 3 files changed, 148 insertions(+), 80 deletions(-) diff --git a/src/KOKKOS/neigh_list_kokkos.h b/src/KOKKOS/neigh_list_kokkos.h index 45e768927c..32e6e704ae 100644 --- a/src/KOKKOS/neigh_list_kokkos.h +++ b/src/KOKKOS/neigh_list_kokkos.h @@ -48,7 +48,7 @@ class AtomNeighborsConst const int num_neighs; KOKKOS_INLINE_FUNCTION - AtomNeighborsConst(int* const & firstneigh, const int & _num_neighs, + AtomNeighborsConst(const int* const & firstneigh, const int & _num_neighs, const int & stride): _firstneigh(firstneigh), num_neighs(_num_neighs), _stride(stride) {}; KOKKOS_INLINE_FUNCTION @@ -87,6 +87,14 @@ public: &d_neighbors(i,1)-&d_neighbors(i,0)); } + KOKKOS_INLINE_FUNCTION + static AtomNeighborsConst static_neighbors_const(int i, + typename ArrayTypes::t_neighbors_2d_const d_neighbors, + typename ArrayTypes::t_int_1d d_numneigh) { + return AtomNeighborsConst(&d_neighbors(i,0),d_numneigh(i), + &d_neighbors(i,1)-&d_neighbors(i,0)); + } + KOKKOS_INLINE_FUNCTION AtomNeighborsConst get_neighbors_const(const int &i) const { return AtomNeighborsConst(&d_neighbors(i,0),d_numneigh(i), diff --git a/src/KOKKOS/pair_table_rx_kokkos.cpp b/src/KOKKOS/pair_table_rx_kokkos.cpp index 63db613538..c96da87d2f 100644 --- a/src/KOKKOS/pair_table_rx_kokkos.cpp +++ b/src/KOKKOS/pair_table_rx_kokkos.cpp @@ -31,6 +31,7 @@ #include "error.h" #include "atom_masks.h" #include "fix.h" +#include "kokkos_few.h" #include using namespace LAMMPS_NS; @@ -192,101 +193,167 @@ PairTableRXKokkos::Functor::~Functor //list.clean_copy(); } -template -template -template +KOKKOS_INLINE_FUNCTION static int sbmask(const int& j) const +{ + return j >> SBBITS & 3; +} + +template KOKKOS_INLINE_FUNCTION -EV_FLOAT -PairTableRXKokkos::Functor:: -compute_item(const int& ii) const { +static EV_FLOAT compute_item(int ii, + typename ArrayTypes::t_in_1d_const d_ilist, + typename ArrayTypes::t_neighbors_2d_const d_neighbors, + typename ArrayTypes::t_in_1d_const d_numneigh, + typename ArrayTypes::t_x_array_randomread x, + typename ArrayTypes::t_int_1d_randomread type, + Kokkos::View mixWtSite1old, + Kokkos::View mixWtSite2old, + Kokkos::View mixWtSite1, + Kokkos::View mixWtSite2, + Few special_lj, + Few, MAX_TYPES_STACKPARAMS+1> m_cutsq, + typename ArrayTypes::t_ffloat_2d d_cutsq, + Kokkos::View::t_f_array::array_layout, + DeviceType, + Kokkos::MemoryTraits::value> > f; + Kokkos::View::value> > uCG; + Kokkos::View::value> > uCGnew; + ) { EV_FLOAT ev; -//const int i = list.d_ilist[ii]; -//const X_FLOAT xtmp = c.x(i,0); -//const X_FLOAT ytmp = c.x(i,1); -//const X_FLOAT ztmp = c.x(i,2); -//const int itype = c.type(i); + auto i = d_ilist(ii); + auto xtmp = x(i,0); + auto ytmp = x(i,1); + auto ztmp = x(i,2); + auto itype = type(i); -//const AtomNeighborsConst jlist = list.get_neighbors_const(i); -//const int jnum = list.d_numneigh[i]; + auto jlist = NeighListKokkos::static_neighbors_const(i, + d_neighbors, d_numneigh); + auto jnum = d_numneigh(i); -//double uCG_i = 0.0; -//double uCGnew_i = 0.0; -//double fx_i = 0.0, fy_i = 0.0, fz_i = 0.0; + double uCG_i = 0.0; + double uCGnew_i = 0.0; + double fx_i = 0.0, fy_i = 0.0, fz_i = 0.0; -//double mixWtSite1old_i = c.mixWtSite1old_(i); -//double mixWtSite2old_i = c.mixWtSite2old_(i); -//double mixWtSite1_i = c.mixWtSite1_(i); -//double mixWtSite2_i = c.mixWtSite2_(i); + auto mixWtSite1old_i = mixWtSite1old(i); + auto mixWtSite2old_i = mixWtSite2old(i); + auto mixWtSite1_i = mixWtSite1(i); + auto mixWtSite2_i = mixWtSite2(i); -//for (int jj = 0; jj < jnum; jj++) { -// int j = jlist(jj); -// const F_FLOAT factor_lj = c.special_lj[sbmask(j)]; -// j &= NEIGHMASK; + for (int jj = 0; jj < jnum; jj++) { + auto j = jlist(jj); + const F_FLOAT factor_lj = special_lj[sbmask(j)]; + j &= NEIGHMASK; -// const X_FLOAT delx = xtmp - c.x(j,0); -// const X_FLOAT dely = ytmp - c.x(j,1); -// const X_FLOAT delz = ztmp - c.x(j,2); -// const F_FLOAT rsq = delx*delx + dely*dely + delz*delz; -// const int jtype = c.type(j); + auto delx = xtmp - x(j,0); + auto dely = ytmp - x(j,1); + auto delz = ztmp - x(j,2); + auto rsq = delx*delx + dely*dely + delz*delz; + auto jtype = type(j); -// if(rsq < (STACKPARAMS?c.m_cutsq[itype][jtype]:c.d_cutsq(itype,jtype))) { -// double mixWtSite1old_j = c.mixWtSite1old_(j); -// double mixWtSite2old_j = c.mixWtSite2old_(j); -// double mixWtSite1_j = c.mixWtSite1_(j); -// double mixWtSite2_j = c.mixWtSite2_(j); + if(rsq < (STACKPARAMS ? m_cutsq[itype][jtype] : d_cutsq(itype,jtype))) { + auto mixWtSite1old_j = mixWtSite1old_(j); + auto mixWtSite2old_j = mixWtSite2old_(j); + auto mixWtSite1_j = mixWtSite1_(j); + auto mixWtSite2_j = mixWtSite2_(j); -// const F_FLOAT fpair = factor_lj*c.template compute_fpair(rsq,i,j,itype,jtype); + auto fpair = factor_lj * compute_fpair( + rsq,i,j,itype,jtype); -// fx_i += delx*fpair; -// fy_i += dely*fpair; -// fz_i += delz*fpair; + fx_i += delx*fpair; + fy_i += dely*fpair; + fz_i += delz*fpair; -// bool do_half = (NEIGHFLAG==HALF || NEIGHFLAG==HALFTHREAD) && -// (NEWTON_PAIR || j < c.nlocal); -// if (do_half) { -// f(j,0) -= delx*fpair; -// f(j,1) -= dely*fpair; -// f(j,2) -= delz*fpair; -// } + auto do_half = (NEIGHFLAG==HALF || NEIGHFLAG==HALFTHREAD) && + (NEWTON_PAIR || j < c.nlocal); + if (do_half) { + f(j,0) -= delx*fpair; + f(j,1) -= dely*fpair; + f(j,2) -= delz*fpair; + } -// auto evdwl = c.template compute_evdwl(rsq,i,j,itype,jtype); + auto evdwl = compute_evdwl( + rsq,i,j,itype,jtype); -// double evdwlOld; -// if (c.isite1 == c.isite2) { -// evdwlOld = sqrt(mixWtSite1old_i*mixWtSite2old_j)*evdwl; -// evdwl = sqrt(mixWtSite1_i*mixWtSite2_j)*evdwl; -// } else { -// evdwlOld = (sqrt(mixWtSite1old_i*mixWtSite2old_j) + -// sqrt(mixWtSite2old_i*mixWtSite1old_j))*evdwl; -// evdwl = (sqrt(mixWtSite1_i*mixWtSite2_j) + -// sqrt(mixWtSite2_i*mixWtSite1_j))*evdwl; -// } -// evdwlOld *= factor_lj; -// evdwl *= factor_lj; + double evdwlOld; + if (c.isite1 == c.isite2) { + evdwlOld = sqrt(mixWtSite1old_i*mixWtSite2old_j)*evdwl; + evdwl = sqrt(mixWtSite1_i*mixWtSite2_j)*evdwl; + } else { + evdwlOld = (sqrt(mixWtSite1old_i*mixWtSite2old_j) + + sqrt(mixWtSite2old_i*mixWtSite1old_j))*evdwl; + evdwl = (sqrt(mixWtSite1_i*mixWtSite2_j) + + sqrt(mixWtSite2_i*mixWtSite1_j))*evdwl; + } + evdwlOld *= factor_lj; + evdwl *= factor_lj; -// uCG_i += 0.5*evdwlOld; -// if (do_half) uCG(j) += 0.5*evdwlOld; + uCG_i += 0.5*evdwlOld; + if (do_half) uCG(j) += 0.5*evdwlOld; -// uCGnew_i += 0.5*evdwl; -// if (do_half) uCGnew(j) += 0.5*evdwl; -// evdwl = evdwlOld; + uCGnew_i += 0.5*evdwl; + if (do_half) uCGnew(j) += 0.5*evdwl; + evdwl = evdwlOld; -// ev.evdwl += (do_half ? 1.0 : 0.5)*evdwl; + ev.evdwl += (do_half ? 1.0 : 0.5)*evdwl; -// if (EVFLAG) ev_tally(ev,i,j,evdwl,fpair,delx,dely,delz); -// } -//} + if (EVFLAG) { + ev_tally(ev,i,j,evdwl,fpair,delx,dely,delz); + } + } + } -//uCG(i) += uCG_i; -//uCGnew(i) += uCGnew_i; + uCG(i) += uCG_i; + uCGnew(i) += uCGnew_i; -//f(i,0) += fx_i; -//f(i,1) += fy_i; -//f(i,2) += fz_i; + f(i,0) += fx_i; + f(i,1) += fy_i; + f(i,2) += fz_i; return ev; } +template +static void compute_all_items( + int eflag, int vflag, + int newton_pair, + EV_FLOAT& ev, + Kokkos::View mixWtSite1old, + Kokkos::View mixWtSite2old, + Kokkos::View mixWtSite1, + Kokkos::View mixWtSite2, + int inum, + if (eflag || vflag) { + Kokkos::parallel_reduce(inum, + LAMMPS_LAMBDA(int i, EV_FLOAT& energy_virial) { + if (newton_pair) { + energy_virial += + compute_item( + ); + } else { + energy_virial += + compute_item( + ); + energy_virial += compute_item<1,0>(i); + } + }, ev); + } else { + Kokkos::parallel_for(inum, + LAMMPS_LAMBDA(int i) { + if (newton_pair) { + compute_item( + ); + } else { + compute_item( + ); + } + }, ev); + } +} + template template KOKKOS_INLINE_FUNCTION diff --git a/src/KOKKOS/pair_table_rx_kokkos.h b/src/KOKKOS/pair_table_rx_kokkos.h index b71f57076d..33f96d4c32 100644 --- a/src/KOKKOS/pair_table_rx_kokkos.h +++ b/src/KOKKOS/pair_table_rx_kokkos.h @@ -85,10 +85,8 @@ class PairTableRXKokkos : public PairTable { virtual void allocate(); void compute_table(Table *); - typename ArrayTypes::t_x_array_randomread x; typename ArrayTypes::t_x_array_const c_x; typename ArrayTypes::t_f_array f; - typename ArrayTypes::t_int_1d_randomread type; typename ArrayTypes::t_efloat_1d uCG; typename ArrayTypes::t_efloat_1d uCGnew; typename ArrayTypes::t_efloat_1d d_eatom; @@ -117,11 +115,6 @@ class PairTableRXKokkos : public PairTable { int isite1, isite2; bool fractionalWeighting; - template - KOKKOS_INLINE_FUNCTION - void getMixingWeights(typename ArrayTypes::t_float_2d_randomread, - int, double &, double &, double &, double &); - Kokkos::View mixWtSite1old_; Kokkos::View mixWtSite2old_; Kokkos::View mixWtSite1_; From c2bb20e60f8396158f6f712386a54a75b7d5ac43 Mon Sep 17 00:00:00 2001 From: Dan Ibanez Date: Wed, 11 Jan 2017 11:54:01 -0700 Subject: [PATCH 071/439] made compute_fpair a free function as well --- src/KOKKOS/pair_table_rx_kokkos.cpp | 81 +++++++++++++++-------------- src/KOKKOS/pair_table_rx_kokkos.h | 4 -- 2 files changed, 43 insertions(+), 42 deletions(-) diff --git a/src/KOKKOS/pair_table_rx_kokkos.cpp b/src/KOKKOS/pair_table_rx_kokkos.cpp index c96da87d2f..26c5de87e4 100644 --- a/src/KOKKOS/pair_table_rx_kokkos.cpp +++ b/src/KOKKOS/pair_table_rx_kokkos.cpp @@ -198,6 +198,40 @@ KOKKOS_INLINE_FUNCTION static int sbmask(const int& j) const return j >> SBBITS & 3; } +template +KOKKOS_INLINE_FUNCTION +static F_FLOAT +compute_fpair(F_FLOAT rsq, + int itype, int jtype, + PairTableRXKokkos::TableDeviceConst d_table_const, + ) { + union_int_float_t rsq_lookup; + double fpair; + const int tidx = d_table_const.tabindex(itype,jtype); + if (TABSTYLE == LOOKUP) { + const int itable = static_cast ((rsq - d_table_const.innersq(tidx)) * d_table_const.invdelta(tidx)); + fpair = d_table_const.f(tidx,itable); + } else if (TABSTYLE == LINEAR) { + const int itable = static_cast ((rsq - d_table_const.innersq(tidx)) * d_table_const.invdelta(tidx)); + const double fraction = (rsq - d_table_const.rsq(tidx,itable)) * d_table_const.invdelta(tidx); + fpair = d_table_const.f(tidx,itable) + fraction*d_table_const.df(tidx,itable); + } else if (TABSTYLE == SPLINE) { + const int itable = static_cast ((rsq - d_table_const.innersq(tidx)) * d_table_const.invdelta(tidx)); + const double b = (rsq - d_table_const.rsq(tidx,itable)) * d_table_const.invdelta(tidx); + const double a = 1.0 - b; + fpair = a * d_table_const.f(tidx,itable) + b * d_table_const.f(tidx,itable+1) + + ((a*a*a-a)*d_table_const.f2(tidx,itable) + (b*b*b-b)*d_table_const.f2(tidx,itable+1)) * + d_table_const.deltasq6(tidx); + } else { + rsq_lookup.f = rsq; + int itable = rsq_lookup.i & d_table_const.nmask(tidx); + itable >>= d_table_const.nshiftbits(tidx); + const double fraction = (rsq_lookup.f - d_table_const.rsq(tidx,itable)) * d_table_const.drsq(tidx,itable); + fpair = d_table_const.f(tidx,itable) + fraction*d_table_const.df(tidx,itable); + } + return fpair; +} + template KOKKOS_INLINE_FUNCTION @@ -222,6 +256,8 @@ static EV_FLOAT compute_item(int ii, device_type,Kokkos::MemoryTraits::value> > uCG; Kokkos::View::value> > uCGnew; + int isite1, int isite2, + PairTableRXKokkos::TableDeviceConst d_table_const, ) { EV_FLOAT ev; auto i = d_ilist(ii); @@ -260,8 +296,12 @@ static EV_FLOAT compute_item(int ii, auto mixWtSite1_j = mixWtSite1_(j); auto mixWtSite2_j = mixWtSite2_(j); - auto fpair = factor_lj * compute_fpair( - rsq,i,j,itype,jtype); + auto fpair = factor_lj * compute_fpair( + rsq,itype,jtype,d_table_const); + + if (isite1 == isite2) fpair *= sqrt(mixWtSite1old_i * mixWtSite2old_j); + else fpair *= (sqrt(mixWtSite1old_i * mixWtSite2old_j) + + sqrt(mixWtSite2old_i * mixWtSite1old_j)); fx_i += delx*fpair; fy_i += dely*fpair; @@ -279,7 +319,7 @@ static EV_FLOAT compute_item(int ii, rsq,i,j,itype,jtype); double evdwlOld; - if (c.isite1 == c.isite2) { + if (isite1 == isite2) { evdwlOld = sqrt(mixWtSite1old_i*mixWtSite2old_j)*evdwl; evdwl = sqrt(mixWtSite1_i*mixWtSite2_j)*evdwl; } else { @@ -550,41 +590,6 @@ void PairTableRXKokkos::compute_style(int eflag_in, int vflag_in) if (vflag_fdotr) pair_virial_fdotr_compute(this); } -template -template -KOKKOS_INLINE_FUNCTION -F_FLOAT PairTableRXKokkos:: -compute_fpair(const F_FLOAT& rsq, const int& i, const int&j, const int& itype, const int& jtype) const { - union_int_float_t rsq_lookup; - double fpair; - const int tidx = d_table_const.tabindex(itype,jtype); - if (TABSTYLE == LOOKUP) { - const int itable = static_cast ((rsq - d_table_const.innersq(tidx)) * d_table_const.invdelta(tidx)); - fpair = d_table_const.f(tidx,itable); - } else if (TABSTYLE == LINEAR) { - const int itable = static_cast ((rsq - d_table_const.innersq(tidx)) * d_table_const.invdelta(tidx)); - const double fraction = (rsq - d_table_const.rsq(tidx,itable)) * d_table_const.invdelta(tidx); - fpair = d_table_const.f(tidx,itable) + fraction*d_table_const.df(tidx,itable); - } else if (TABSTYLE == SPLINE) { - const int itable = static_cast ((rsq - d_table_const.innersq(tidx)) * d_table_const.invdelta(tidx)); - const double b = (rsq - d_table_const.rsq(tidx,itable)) * d_table_const.invdelta(tidx); - const double a = 1.0 - b; - fpair = a * d_table_const.f(tidx,itable) + b * d_table_const.f(tidx,itable+1) + - ((a*a*a-a)*d_table_const.f2(tidx,itable) + (b*b*b-b)*d_table_const.f2(tidx,itable+1)) * - d_table_const.deltasq6(tidx); - } else { - rsq_lookup.f = rsq; - int itable = rsq_lookup.i & d_table_const.nmask(tidx); - itable >>= d_table_const.nshiftbits(tidx); - const double fraction = (rsq_lookup.f - d_table_const.rsq(tidx,itable)) * d_table_const.drsq(tidx,itable); - fpair = d_table_const.f(tidx,itable) + fraction*d_table_const.df(tidx,itable); - } - if (isite1 == isite2) fpair *= sqrt(mixWtSite1old_(i) * mixWtSite2old_(j)); - else fpair *= (sqrt(mixWtSite1old_(i) * mixWtSite2old_(j)) + - sqrt(mixWtSite2old_(i) * mixWtSite1old_(j))); - return fpair; -} - template template KOKKOS_INLINE_FUNCTION diff --git a/src/KOKKOS/pair_table_rx_kokkos.h b/src/KOKKOS/pair_table_rx_kokkos.h index 33f96d4c32..b2814adcec 100644 --- a/src/KOKKOS/pair_table_rx_kokkos.h +++ b/src/KOKKOS/pair_table_rx_kokkos.h @@ -98,10 +98,6 @@ class PairTableRXKokkos : public PairTable { void create_kokkos_tables(); void cleanup_copy(); - template - KOKKOS_INLINE_FUNCTION - F_FLOAT compute_fpair(const F_FLOAT& rsq, const int& i, const int&j, const int& itype, const int& jtype) const; - template KOKKOS_INLINE_FUNCTION F_FLOAT compute_evdwl(const F_FLOAT& rsq, const int& i, const int&j, const int& itype, const int& jtype) const; From 41804ff52464f6c60ae3a0b32ead2f0a5386d733 Mon Sep 17 00:00:00 2001 From: Dan Ibanez Date: Wed, 11 Jan 2017 12:42:05 -0700 Subject: [PATCH 072/439] progress converting compute_style --- src/KOKKOS/pair_table_rx_kokkos.cpp | 234 +++++++++++++++------------- src/KOKKOS/pair_table_rx_kokkos.h | 11 +- 2 files changed, 126 insertions(+), 119 deletions(-) diff --git a/src/KOKKOS/pair_table_rx_kokkos.cpp b/src/KOKKOS/pair_table_rx_kokkos.cpp index 26c5de87e4..a9703dd927 100644 --- a/src/KOKKOS/pair_table_rx_kokkos.cpp +++ b/src/KOKKOS/pair_table_rx_kokkos.cpp @@ -232,10 +232,48 @@ compute_fpair(F_FLOAT rsq, return fpair; } +template +KOKKOS_INLINE_FUNCTION +static F_FLOAT +compute_evdwl( + F_FLOAT rsq, + int itype, int jtype, + PairTableRXKokkos::TableDeviceConst d_table_const, + ) const { + double evdwl; + union_int_float_t rsq_lookup; + const int tidx = d_table_const.tabindex(itype,jtype); + if (TABSTYLE == LOOKUP) { + const int itable = static_cast ((rsq - d_table_const.innersq(tidx)) * d_table_const.invdelta(tidx)); + evdwl = d_table_const.e(tidx,itable); + } else if (TABSTYLE == LINEAR) { + const int itable = static_cast ((rsq - d_table_const.innersq(tidx)) * d_table_const.invdelta(tidx)); + const double fraction = (rsq - d_table_const.rsq(tidx,itable)) * d_table_const.invdelta(tidx); + evdwl = d_table_const.e(tidx,itable) + fraction*d_table_const.de(tidx,itable); + } else if (TABSTYLE == SPLINE) { + const int itable = static_cast ((rsq - d_table_const.innersq(tidx)) * d_table_const.invdelta(tidx)); + const double b = (rsq - d_table_const.rsq(tidx,itable)) * d_table_const.invdelta(tidx); + const double a = 1.0 - b; + evdwl = a * d_table_const.e(tidx,itable) + b * d_table_const.e(tidx,itable+1) + + ((a*a*a-a)*d_table_const.e2(tidx,itable) + (b*b*b-b)*d_table_const.e2(tidx,itable+1)) * + d_table_const.deltasq6(tidx); + } else { + rsq_lookup.f = rsq; + int itable = rsq_lookup.i & d_table_const.nmask(tidx); + itable >>= d_table_const.nshiftbits(tidx); + const double fraction = (rsq_lookup.f - d_table_const.rsq(tidx,itable)) * d_table_const.drsq(tidx,itable); + evdwl = d_table_const.e(tidx,itable) + fraction*d_table_const.de(tidx,itable); + } + return evdwl; +} + template KOKKOS_INLINE_FUNCTION -static EV_FLOAT compute_item(int ii, +static EV_FLOAT +compute_item( + int ii, + int nlocal, typename ArrayTypes::t_in_1d_const d_ilist, typename ArrayTypes::t_neighbors_2d_const d_neighbors, typename ArrayTypes::t_in_1d_const d_numneigh, @@ -308,7 +346,7 @@ static EV_FLOAT compute_item(int ii, fz_i += delz*fpair; auto do_half = (NEIGHFLAG==HALF || NEIGHFLAG==HALFTHREAD) && - (NEWTON_PAIR || j < c.nlocal); + (NEWTON_PAIR || j < nlocal); if (do_half) { f(j,0) -= delx*fpair; f(j,1) -= dely*fpair; @@ -316,7 +354,7 @@ static EV_FLOAT compute_item(int ii, } auto evdwl = compute_evdwl( - rsq,i,j,itype,jtype); + rsq,itype,jtype,d_table_const); double evdwlOld; if (isite1 == isite2) { @@ -361,22 +399,47 @@ static void compute_all_items( int eflag, int vflag, int newton_pair, EV_FLOAT& ev, + int nlocal, + int inum, + typename ArrayTypes::t_in_1d_const d_ilist, + typename ArrayTypes::t_neighbors_2d_const d_neighbors, + typename ArrayTypes::t_in_1d_const d_numneigh, + typename ArrayTypes::t_x_array_randomread x, + typename ArrayTypes::t_int_1d_randomread type, Kokkos::View mixWtSite1old, Kokkos::View mixWtSite2old, Kokkos::View mixWtSite1, Kokkos::View mixWtSite2, - int inum, + Few special_lj, + Few, MAX_TYPES_STACKPARAMS+1> m_cutsq, + typename ArrayTypes::t_ffloat_2d d_cutsq, + Kokkos::View::t_f_array::array_layout, + DeviceType, + Kokkos::MemoryTraits::value> > f; + Kokkos::View::value> > uCG; + Kokkos::View::value> > uCGnew; + int isite1, int isite2, + PairTableRXKokkos::TableDeviceConst d_table_const) { if (eflag || vflag) { Kokkos::parallel_reduce(inum, LAMMPS_LAMBDA(int i, EV_FLOAT& energy_virial) { if (newton_pair) { energy_virial += compute_item( - ); + i, nlocal, d_ilist, d_neighbors, d_numneigh, x, type, + mixWtSite1old, mixWtSite2old, mixWtSite1, mixWtSite2, + special_lj, m_cutsq, d_cutsq, f, uCG, uCGnew, isite1, isite2, + d_table_const); } else { energy_virial += compute_item( - ); + i, nlocal, d_ilist, d_neighbors, d_numneigh, x, type, + mixWtSite1old, mixWtSite2old, mixWtSite1, mixWtSite2, + special_lj, m_cutsq, d_cutsq, f, uCG, uCGnew, isite1, isite2, + d_table_const); energy_virial += compute_item<1,0>(i); } }, ev); @@ -385,10 +448,16 @@ static void compute_all_items( LAMMPS_LAMBDA(int i) { if (newton_pair) { compute_item( - ); + i, nlocal, d_ilist, d_neighbors, d_numneigh, x, type, + mixWtSite1old, mixWtSite2old, mixWtSite1, mixWtSite2, + special_lj, m_cutsq, d_cutsq, f, uCG, uCGnew, isite1, isite2, + d_table_const); } else { compute_item( - ); + i, nlocal, d_ilist, d_neighbors, d_numneigh, x, type, + mixWtSite1old, mixWtSite2old, mixWtSite1, mixWtSite2, + special_lj, m_cutsq, d_cutsq, f, uCG, uCGnew, isite1, isite2, + d_table_const); } }, ev); } @@ -454,26 +523,6 @@ ev_tally(EV_FLOAT &ev, const int &i, const int &j, //} } -template -template -KOKKOS_INLINE_FUNCTION -void -PairTableRXKokkos::Functor:: -operator()(const int i) const { -//if (c.newton_pair) compute_item<0,1>(i); -//else compute_item<0,0>(i); -} - -template -template -KOKKOS_INLINE_FUNCTION -void -PairTableRXKokkos::Functor:: -operator()(const int i, value_type &energy_virial) const { -//if (c.newton_pair) energy_virial += compute_item<1,1>(i); -//else energy_virial += compute_item<1,0>(i); -} - template static void getAllMixingWeights( int ntotal, @@ -496,8 +545,8 @@ template template void PairTableRXKokkos::compute_style(int eflag_in, int vflag_in) { - eflag = eflag_in; - vflag = vflag_in; + auto eflag = eflag_in; + auto vflag = vflag_in; if (neighflag == FULL) no_virial_fdotr_compute = 1; @@ -511,69 +560,68 @@ void PairTableRXKokkos::compute_style(int eflag_in, int vflag_in) if (eflag || vflag) atomKK->modified(execution_space,datamask_modify); else atomKK->modified(execution_space,F_MASK); - x = c_x = atomKK->k_x.view(); - f = atomKK->k_f.view(); - type = atomKK->k_type.view(); - uCG = atomKK->k_uCG.view(); - uCGnew = atomKK->k_uCGnew.view(); - nlocal = atom->nlocal; - nall = atom->nlocal + atom->nghost; - special_lj[0] = force->special_lj[0]; - special_lj[1] = force->special_lj[1]; - special_lj[2] = force->special_lj[2]; - special_lj[3] = force->special_lj[3]; - newton_pair = force->newton_pair; + auto x = atomKK->k_x.view(); + auto f = atomKK->k_f.view(); + auto type = atomKK->k_type.view(); + auto uCG = atomKK->k_uCG.view(); + auto uCGnew = atomKK->k_uCGnew.view(); + auto nlocal = atom->nlocal; + Few special_lj_local; + special_lj_local[0] = force->special_lj[0]; + special_lj_local[1] = force->special_lj[1]; + special_lj_local[2] = force->special_lj[2]; + special_lj_local[3] = force->special_lj[3]; + auto newton_pair = force->newton_pair; d_cutsq = d_table->cutsq; // loop over neighbors of my atoms const int ntotal = atom->nlocal + atom->nghost; - mixWtSite1old_ = Kokkos::View("PairTableRXKokkos::mixWtSite1old", ntotal); - mixWtSite2old_ = Kokkos::View("PairTableRXKokkos::mixWtSite2old", ntotal); - mixWtSite1_ = Kokkos::View("PairTableRXKokkos::mixWtSite1", ntotal); - mixWtSite2_ = Kokkos::View("PairTableRXKokkos::mixWtSite2", ntotal); + auto mixWtSite1old = Kokkos::View("PairTableRXKokkos::mixWtSite1old", ntotal); + auto mixWtSite2old = Kokkos::View("PairTableRXKokkos::mixWtSite2old", ntotal); + auto mixWtSite1 = Kokkos::View("PairTableRXKokkos::mixWtSite1", ntotal); + auto mixWtSite2 = Kokkos::View("PairTableRXKokkos::mixWtSite2", ntotal); getAllMixingWeights(ntotal, atomKK->k_dvector.template view(), nspecies, isite1, isite2, fractionalWeighting, - mixWtSite1old_, mixWtSite2old_, mixWtSite1_, mixWtSite2_); + mixWtSite1old, mixWtSite2old, mixWtSite1, mixWtSite2); if (neighflag == N2) error->all(FLERR,"pair table/rx/kk can't handle N2 yet\n"); + NeighListKokkos* l = + dynamic_cast*>(list); + EV_FLOAT ev; if(atom->ntypes > MAX_TYPES_STACKPARAMS) { - if (neighflag == FULL) { - Functor ff(this,(NeighListKokkos*) list); - if (eflag || vflag) Kokkos::parallel_reduce(list->inum,ff,ev); - else Kokkos::parallel_for(list->inum,ff); - } else if (neighflag == HALFTHREAD) { - Functor ff(this,(NeighListKokkos*) list); - if (eflag || vflag) Kokkos::parallel_reduce(list->inum,ff,ev); - else Kokkos::parallel_for(list->inum,ff); + if (neighflag == HALFTHREAD) { + compute_all_items( + eflag, vflag, newton_pair, ev, nlocal, + l->inum, l->d_ilist, l->d_neighbors, l->d_numneigh, + x, type, mixWtSite1old, mixWtSite2old, mixWtSite1, mixWtSite2, + special_lj, m_cutsq, d_cutsq, f, uCG, uCGnew, isite1, isite2, + d_table_const); } else if (neighflag == HALF) { - Functor f(this,(NeighListKokkos*) list); - if (eflag || vflag) Kokkos::parallel_reduce(list->inum,f,ev); - else Kokkos::parallel_for(list->inum,f); - } else if (neighflag == N2) { - Functor f(this,(NeighListKokkos*) list); - if (eflag || vflag) Kokkos::parallel_reduce(nlocal,f,ev); - else Kokkos::parallel_for(nlocal,f); + compute_all_items( + eflag, vflag, newton_pair, ev, nlocal, + l->inum, l->d_ilist, l->d_neighbors, l->d_numneigh, + x, type, mixWtSite1old, mixWtSite2old, mixWtSite1, mixWtSite2, + special_lj, m_cutsq, d_cutsq, f, uCG, uCGnew, isite1, isite2, + d_table_const); } } else { - if (neighflag == FULL) { - Functor f(this,(NeighListKokkos*) list); - if (eflag || vflag) Kokkos::parallel_reduce(list->inum,f,ev); - else Kokkos::parallel_for(list->inum,f); - } else if (neighflag == HALFTHREAD) { - Functor f(this,(NeighListKokkos*) list); - if (eflag || vflag) Kokkos::parallel_reduce(list->inum,f,ev); - else Kokkos::parallel_for(list->inum,f); + if (neighflag == HALFTHREAD) { + compute_all_items( + eflag, vflag, newton_pair, ev, nlocal, + l->inum, l->d_ilist, l->d_neighbors, l->d_numneigh, + x, type, mixWtSite1old, mixWtSite2old, mixWtSite1, mixWtSite2, + special_lj, m_cutsq, d_cutsq, f, uCG, uCGnew, isite1, isite2, + d_table_const); } else if (neighflag == HALF) { - Functor f(this,(NeighListKokkos*) list); - if (eflag || vflag) Kokkos::parallel_reduce(list->inum,f,ev); - else Kokkos::parallel_for(list->inum,f); - } else if (neighflag == N2) { - Functor f(this,(NeighListKokkos*) list); - if (eflag || vflag) Kokkos::parallel_reduce(nlocal,f,ev); - else Kokkos::parallel_for(nlocal,f); + compute_all_items( + eflag, vflag, newton_pair, ev, nlocal, + l->inum, l->d_ilist, l->d_neighbors, l->d_numneigh, + x, type, mixWtSite1old, mixWtSite2old, mixWtSite1, mixWtSite2, + special_lj, m_cutsq, d_cutsq, f, uCG, uCGnew, isite1, isite2, + d_table_const); } } @@ -590,38 +638,6 @@ void PairTableRXKokkos::compute_style(int eflag_in, int vflag_in) if (vflag_fdotr) pair_virial_fdotr_compute(this); } -template -template -KOKKOS_INLINE_FUNCTION -F_FLOAT PairTableRXKokkos:: -compute_evdwl(const F_FLOAT& rsq, const int& i, const int&j, const int& itype, const int& jtype) const { - double evdwl; - union_int_float_t rsq_lookup; - const int tidx = d_table_const.tabindex(itype,jtype); - if (TABSTYLE == LOOKUP) { - const int itable = static_cast ((rsq - d_table_const.innersq(tidx)) * d_table_const.invdelta(tidx)); - evdwl = d_table_const.e(tidx,itable); - } else if (TABSTYLE == LINEAR) { - const int itable = static_cast ((rsq - d_table_const.innersq(tidx)) * d_table_const.invdelta(tidx)); - const double fraction = (rsq - d_table_const.rsq(tidx,itable)) * d_table_const.invdelta(tidx); - evdwl = d_table_const.e(tidx,itable) + fraction*d_table_const.de(tidx,itable); - } else if (TABSTYLE == SPLINE) { - const int itable = static_cast ((rsq - d_table_const.innersq(tidx)) * d_table_const.invdelta(tidx)); - const double b = (rsq - d_table_const.rsq(tidx,itable)) * d_table_const.invdelta(tidx); - const double a = 1.0 - b; - evdwl = a * d_table_const.e(tidx,itable) + b * d_table_const.e(tidx,itable+1) + - ((a*a*a-a)*d_table_const.e2(tidx,itable) + (b*b*b-b)*d_table_const.e2(tidx,itable+1)) * - d_table_const.deltasq6(tidx); - } else { - rsq_lookup.f = rsq; - int itable = rsq_lookup.i & d_table_const.nmask(tidx); - itable >>= d_table_const.nshiftbits(tidx); - const double fraction = (rsq_lookup.f - d_table_const.rsq(tidx,itable)) * d_table_const.drsq(tidx,itable); - evdwl = d_table_const.e(tidx,itable) + fraction*d_table_const.de(tidx,itable); - } - return evdwl; -} - template void PairTableRXKokkos::create_kokkos_tables() { diff --git a/src/KOKKOS/pair_table_rx_kokkos.h b/src/KOKKOS/pair_table_rx_kokkos.h index b2814adcec..36441f78b5 100644 --- a/src/KOKKOS/pair_table_rx_kokkos.h +++ b/src/KOKKOS/pair_table_rx_kokkos.h @@ -92,16 +92,12 @@ class PairTableRXKokkos : public PairTable { typename ArrayTypes::t_efloat_1d d_eatom; typename ArrayTypes::t_virial_array d_vatom; - int nlocal,nall,eflag,vflag,neighflag,newton_pair; + int neighflag; int update_table; void create_kokkos_tables(); void cleanup_copy(); - template - KOKKOS_INLINE_FUNCTION - F_FLOAT compute_evdwl(const F_FLOAT& rsq, const int& i, const int&j, const int& itype, const int& jtype) const; - friend void pair_virial_fdotr_compute(PairTableRXKokkos*); /* PairTableRX members */ @@ -111,11 +107,6 @@ class PairTableRXKokkos : public PairTable { int isite1, isite2; bool fractionalWeighting; - Kokkos::View mixWtSite1old_; - Kokkos::View mixWtSite2old_; - Kokkos::View mixWtSite1_; - Kokkos::View mixWtSite2_; - /* a duplicate of PairComputeFunctor to deal with uCG */ template struct Functor { From fdb6b91e29166f0882169946718b1c2d69c114ac Mon Sep 17 00:00:00 2001 From: Dan Ibanez Date: Wed, 11 Jan 2017 12:50:32 -0700 Subject: [PATCH 073/439] near trying to compile --- src/KOKKOS/pair_table_rx_kokkos.cpp | 144 ++++++++++++++-------------- 1 file changed, 71 insertions(+), 73 deletions(-) diff --git a/src/KOKKOS/pair_table_rx_kokkos.cpp b/src/KOKKOS/pair_table_rx_kokkos.cpp index a9703dd927..bed69fa0a0 100644 --- a/src/KOKKOS/pair_table_rx_kokkos.cpp +++ b/src/KOKKOS/pair_table_rx_kokkos.cpp @@ -267,6 +267,62 @@ compute_evdwl( return evdwl; } +template +KOKKOS_INLINE_FUNCTION +void +ev_tally( + int vflag_global, + int nlocal, + EV_FLOAT& ev, + F_FLOAT epair, F_FLOAT fpair, + F_FLOAT delx, F_FLOAT dely, F_FLOAT delz) +{ + if (vflag_global) { + auto v0 = delx*delx*fpair; + auto v1 = dely*dely*fpair; + auto v2 = delz*delz*fpair; + auto v3 = delx*dely*fpair; + auto v4 = delx*delz*fpair; + auto v5 = dely*delz*fpair; + + if (NEIGHFLAG!=FULL) { + if (NEWTON_PAIR) { + ev.v[0] += v0; + ev.v[1] += v1; + ev.v[2] += v2; + ev.v[3] += v3; + ev.v[4] += v4; + ev.v[5] += v5; + } else { + if (i < c.nlocal) { + ev.v[0] += 0.5*v0; + ev.v[1] += 0.5*v1; + ev.v[2] += 0.5*v2; + ev.v[3] += 0.5*v3; + ev.v[4] += 0.5*v4; + ev.v[5] += 0.5*v5; + } + if (j < c.nlocal) { + ev.v[0] += 0.5*v0; + ev.v[1] += 0.5*v1; + ev.v[2] += 0.5*v2; + ev.v[3] += 0.5*v3; + ev.v[4] += 0.5*v4; + ev.v[5] += 0.5*v5; + } + } + } else { + ev.v[0] += 0.5*v0; + ev.v[1] += 0.5*v1; + ev.v[2] += 0.5*v2; + ev.v[3] += 0.5*v3; + ev.v[4] += 0.5*v4; + ev.v[5] += 0.5*v5; + } + } +} +} + template KOKKOS_INLINE_FUNCTION @@ -296,6 +352,7 @@ compute_item( device_type,Kokkos::MemoryTraits::value> > uCGnew; int isite1, int isite2, PairTableRXKokkos::TableDeviceConst d_table_const, + int vflag_global ) { EV_FLOAT ev; auto i = d_ilist(ii); @@ -379,7 +436,8 @@ compute_item( ev.evdwl += (do_half ? 1.0 : 0.5)*evdwl; if (EVFLAG) { - ev_tally(ev,i,j,evdwl,fpair,delx,dely,delz); + ev_tally( + vflag_global,nlocal,ev,evdwl,fpair,delx,dely,delz); } } } @@ -422,7 +480,8 @@ static void compute_all_items( Kokkos::View::value> > uCGnew; int isite1, int isite2, - PairTableRXKokkos::TableDeviceConst d_table_const) { + PairTableRXKokkos::TableDeviceConst d_table_const, + int vflag_global) { if (eflag || vflag) { Kokkos::parallel_reduce(inum, LAMMPS_LAMBDA(int i, EV_FLOAT& energy_virial) { @@ -432,97 +491,36 @@ static void compute_all_items( i, nlocal, d_ilist, d_neighbors, d_numneigh, x, type, mixWtSite1old, mixWtSite2old, mixWtSite1, mixWtSite2, special_lj, m_cutsq, d_cutsq, f, uCG, uCGnew, isite1, isite2, - d_table_const); + d_table_const, vflag_global); } else { energy_virial += compute_item( i, nlocal, d_ilist, d_neighbors, d_numneigh, x, type, mixWtSite1old, mixWtSite2old, mixWtSite1, mixWtSite2, special_lj, m_cutsq, d_cutsq, f, uCG, uCGnew, isite1, isite2, - d_table_const); - energy_virial += compute_item<1,0>(i); + d_table_const, vflag_global); } }, ev); } else { Kokkos::parallel_for(inum, LAMMPS_LAMBDA(int i) { if (newton_pair) { - compute_item( + compute_item( i, nlocal, d_ilist, d_neighbors, d_numneigh, x, type, mixWtSite1old, mixWtSite2old, mixWtSite1, mixWtSite2, special_lj, m_cutsq, d_cutsq, f, uCG, uCGnew, isite1, isite2, - d_table_const); + d_table_const, vflag_global); } else { - compute_item( + compute_item( i, nlocal, d_ilist, d_neighbors, d_numneigh, x, type, mixWtSite1old, mixWtSite2old, mixWtSite1, mixWtSite2, special_lj, m_cutsq, d_cutsq, f, uCG, uCGnew, isite1, isite2, - d_table_const); + d_table_const, vflag_global); } }, ev); } } -template -template -KOKKOS_INLINE_FUNCTION -void -PairTableRXKokkos::Functor:: -ev_tally(EV_FLOAT &ev, const int &i, const int &j, - const F_FLOAT &epair, const F_FLOAT &fpair, const F_FLOAT &delx, - const F_FLOAT &dely, const F_FLOAT &delz) const -{ -//const int EFLAG = c.eflag; -//const int NEWTON_PAIR = c.newton_pair; -//const int VFLAG = c.vflag_either; - -//if (VFLAG) { -// const E_FLOAT v0 = delx*delx*fpair; -// const E_FLOAT v1 = dely*dely*fpair; -// const E_FLOAT v2 = delz*delz*fpair; -// const E_FLOAT v3 = delx*dely*fpair; -// const E_FLOAT v4 = delx*delz*fpair; -// const E_FLOAT v5 = dely*delz*fpair; - -// if (c.vflag_global) { -// if (NEIGHFLAG!=FULL) { -// if (NEWTON_PAIR) { -// ev.v[0] += v0; -// ev.v[1] += v1; -// ev.v[2] += v2; -// ev.v[3] += v3; -// ev.v[4] += v4; -// ev.v[5] += v5; -// } else { -// if (i < c.nlocal) { -// ev.v[0] += 0.5*v0; -// ev.v[1] += 0.5*v1; -// ev.v[2] += 0.5*v2; -// ev.v[3] += 0.5*v3; -// ev.v[4] += 0.5*v4; -// ev.v[5] += 0.5*v5; -// } -// if (j < c.nlocal) { -// ev.v[0] += 0.5*v0; -// ev.v[1] += 0.5*v1; -// ev.v[2] += 0.5*v2; -// ev.v[3] += 0.5*v3; -// ev.v[4] += 0.5*v4; -// ev.v[5] += 0.5*v5; -// } -// } -// } else { -// ev.v[0] += 0.5*v0; -// ev.v[1] += 0.5*v1; -// ev.v[2] += 0.5*v2; -// ev.v[3] += 0.5*v3; -// ev.v[4] += 0.5*v4; -// ev.v[5] += 0.5*v5; -// } -// } -//} -} - template static void getAllMixingWeights( int ntotal, @@ -598,14 +596,14 @@ void PairTableRXKokkos::compute_style(int eflag_in, int vflag_in) l->inum, l->d_ilist, l->d_neighbors, l->d_numneigh, x, type, mixWtSite1old, mixWtSite2old, mixWtSite1, mixWtSite2, special_lj, m_cutsq, d_cutsq, f, uCG, uCGnew, isite1, isite2, - d_table_const); + d_table_const, vflag_global); } else if (neighflag == HALF) { compute_all_items( eflag, vflag, newton_pair, ev, nlocal, l->inum, l->d_ilist, l->d_neighbors, l->d_numneigh, x, type, mixWtSite1old, mixWtSite2old, mixWtSite1, mixWtSite2, special_lj, m_cutsq, d_cutsq, f, uCG, uCGnew, isite1, isite2, - d_table_const); + d_table_const, vflag_global); } } else { if (neighflag == HALFTHREAD) { @@ -614,14 +612,14 @@ void PairTableRXKokkos::compute_style(int eflag_in, int vflag_in) l->inum, l->d_ilist, l->d_neighbors, l->d_numneigh, x, type, mixWtSite1old, mixWtSite2old, mixWtSite1, mixWtSite2, special_lj, m_cutsq, d_cutsq, f, uCG, uCGnew, isite1, isite2, - d_table_const); + d_table_const, vflag_global); } else if (neighflag == HALF) { compute_all_items( eflag, vflag, newton_pair, ev, nlocal, l->inum, l->d_ilist, l->d_neighbors, l->d_numneigh, x, type, mixWtSite1old, mixWtSite2old, mixWtSite1, mixWtSite2, special_lj, m_cutsq, d_cutsq, f, uCG, uCGnew, isite1, isite2, - d_table_const); + d_table_const, vflag_global); } } From 5dcbbba4ce53654bc40dc363872878358bfc73b5 Mon Sep 17 00:00:00 2001 From: Dan Ibanez Date: Wed, 11 Jan 2017 13:15:01 -0700 Subject: [PATCH 074/439] lots of work towards compiling --- src/KOKKOS/pair_table_rx_kokkos.cpp | 88 ++++++++++++++--------------- src/KOKKOS/pair_table_rx_kokkos.h | 7 +-- src/pair.h | 2 + src/pair_table.h | 2 +- 4 files changed, 50 insertions(+), 49 deletions(-) diff --git a/src/KOKKOS/pair_table_rx_kokkos.cpp b/src/KOKKOS/pair_table_rx_kokkos.cpp index bed69fa0a0..c6206b828b 100644 --- a/src/KOKKOS/pair_table_rx_kokkos.cpp +++ b/src/KOKKOS/pair_table_rx_kokkos.cpp @@ -182,7 +182,7 @@ void PairTableRXKokkos::compute(int eflag_in, int vflag_in) template template PairTableRXKokkos::Functor::Functor( - PairTableRXKokkos* c_ptr, NeighListKokkos* list_ptr)//: + PairTableRXKokkos* c_ptr, NeighListKokkos* list_ptr)//: //c(*c_ptr),f(c.f),uCG(c.uCG),uCGnew(c.uCGnew),list(*list_ptr) {} @@ -193,7 +193,7 @@ PairTableRXKokkos::Functor::~Functor //list.clean_copy(); } -KOKKOS_INLINE_FUNCTION static int sbmask(const int& j) const +KOKKOS_INLINE_FUNCTION static int sbmask(const int& j) { return j >> SBBITS & 3; } @@ -203,19 +203,19 @@ KOKKOS_INLINE_FUNCTION static F_FLOAT compute_fpair(F_FLOAT rsq, int itype, int jtype, - PairTableRXKokkos::TableDeviceConst d_table_const, + typename PairTableRXKokkos::TableDeviceConst d_table_const ) { - union_int_float_t rsq_lookup; + Pair::union_int_float_t rsq_lookup; double fpair; const int tidx = d_table_const.tabindex(itype,jtype); - if (TABSTYLE == LOOKUP) { + if (TABSTYLE == PairTable::LOOKUP) { const int itable = static_cast ((rsq - d_table_const.innersq(tidx)) * d_table_const.invdelta(tidx)); fpair = d_table_const.f(tidx,itable); - } else if (TABSTYLE == LINEAR) { + } else if (TABSTYLE == PairTable::LINEAR) { const int itable = static_cast ((rsq - d_table_const.innersq(tidx)) * d_table_const.invdelta(tidx)); const double fraction = (rsq - d_table_const.rsq(tidx,itable)) * d_table_const.invdelta(tidx); fpair = d_table_const.f(tidx,itable) + fraction*d_table_const.df(tidx,itable); - } else if (TABSTYLE == SPLINE) { + } else if (TABSTYLE == PairTable::SPLINE) { const int itable = static_cast ((rsq - d_table_const.innersq(tidx)) * d_table_const.invdelta(tidx)); const double b = (rsq - d_table_const.rsq(tidx,itable)) * d_table_const.invdelta(tidx); const double a = 1.0 - b; @@ -238,19 +238,19 @@ static F_FLOAT compute_evdwl( F_FLOAT rsq, int itype, int jtype, - PairTableRXKokkos::TableDeviceConst d_table_const, - ) const { + typename PairTableRXKokkos::TableDeviceConst d_table_const + ) { double evdwl; - union_int_float_t rsq_lookup; + Pair::union_int_float_t rsq_lookup; const int tidx = d_table_const.tabindex(itype,jtype); - if (TABSTYLE == LOOKUP) { + if (TABSTYLE == PairTable::LOOKUP) { const int itable = static_cast ((rsq - d_table_const.innersq(tidx)) * d_table_const.invdelta(tidx)); evdwl = d_table_const.e(tidx,itable); - } else if (TABSTYLE == LINEAR) { + } else if (TABSTYLE == PairTable::LINEAR) { const int itable = static_cast ((rsq - d_table_const.innersq(tidx)) * d_table_const.invdelta(tidx)); const double fraction = (rsq - d_table_const.rsq(tidx,itable)) * d_table_const.invdelta(tidx); evdwl = d_table_const.e(tidx,itable) + fraction*d_table_const.de(tidx,itable); - } else if (TABSTYLE == SPLINE) { + } else if (TABSTYLE == PairTable::SPLINE) { const int itable = static_cast ((rsq - d_table_const.innersq(tidx)) * d_table_const.invdelta(tidx)); const double b = (rsq - d_table_const.rsq(tidx,itable)) * d_table_const.invdelta(tidx); const double a = 1.0 - b; @@ -273,6 +273,7 @@ void ev_tally( int vflag_global, int nlocal, + int i, int j, EV_FLOAT& ev, F_FLOAT epair, F_FLOAT fpair, F_FLOAT delx, F_FLOAT dely, F_FLOAT delz) @@ -294,7 +295,7 @@ ev_tally( ev.v[4] += v4; ev.v[5] += v5; } else { - if (i < c.nlocal) { + if (i < nlocal) { ev.v[0] += 0.5*v0; ev.v[1] += 0.5*v1; ev.v[2] += 0.5*v2; @@ -302,7 +303,7 @@ ev_tally( ev.v[4] += 0.5*v4; ev.v[5] += 0.5*v5; } - if (j < c.nlocal) { + if (j < nlocal) { ev.v[0] += 0.5*v0; ev.v[1] += 0.5*v1; ev.v[2] += 0.5*v2; @@ -321,7 +322,6 @@ ev_tally( } } } -} template @@ -330,9 +330,9 @@ static EV_FLOAT compute_item( int ii, int nlocal, - typename ArrayTypes::t_in_1d_const d_ilist, - typename ArrayTypes::t_neighbors_2d_const d_neighbors, - typename ArrayTypes::t_in_1d_const d_numneigh, + typename ArrayTypes::t_int_1d_const d_ilist, + typename ArrayTypes::t_neighbors_2d_const d_neighbors, + typename ArrayTypes::t_int_1d_const d_numneigh, typename ArrayTypes::t_x_array_randomread x, typename ArrayTypes::t_int_1d_randomread type, Kokkos::View mixWtSite1old, @@ -345,13 +345,13 @@ compute_item( Kokkos::View::t_f_array::array_layout, DeviceType, - Kokkos::MemoryTraits::value> > f; + Kokkos::MemoryTraits::value> > f, Kokkos::View::value> > uCG; + DeviceType,Kokkos::MemoryTraits::value> > uCG, Kokkos::View::value> > uCGnew; + DeviceType,Kokkos::MemoryTraits::value> > uCGnew, int isite1, int isite2, - PairTableRXKokkos::TableDeviceConst d_table_const, + typename PairTableRXKokkos::TableDeviceConst d_table_const, int vflag_global ) { EV_FLOAT ev; @@ -386,10 +386,10 @@ compute_item( auto jtype = type(j); if(rsq < (STACKPARAMS ? m_cutsq[itype][jtype] : d_cutsq(itype,jtype))) { - auto mixWtSite1old_j = mixWtSite1old_(j); - auto mixWtSite2old_j = mixWtSite2old_(j); - auto mixWtSite1_j = mixWtSite1_(j); - auto mixWtSite2_j = mixWtSite2_(j); + auto mixWtSite1old_j = mixWtSite1old(j); + auto mixWtSite2old_j = mixWtSite2old(j); + auto mixWtSite1_j = mixWtSite1(j); + auto mixWtSite2_j = mixWtSite2(j); auto fpair = factor_lj * compute_fpair( rsq,itype,jtype,d_table_const); @@ -437,7 +437,7 @@ compute_item( if (EVFLAG) { ev_tally( - vflag_global,nlocal,ev,evdwl,fpair,delx,dely,delz); + vflag_global,nlocal,i,j,ev,evdwl,fpair,delx,dely,delz); } } } @@ -459,9 +459,9 @@ static void compute_all_items( EV_FLOAT& ev, int nlocal, int inum, - typename ArrayTypes::t_in_1d_const d_ilist, - typename ArrayTypes::t_neighbors_2d_const d_neighbors, - typename ArrayTypes::t_in_1d_const d_numneigh, + typename ArrayTypes::t_int_1d_const d_ilist, + typename ArrayTypes::t_neighbors_2d_const d_neighbors, + typename ArrayTypes::t_int_1d_const d_numneigh, typename ArrayTypes::t_x_array_randomread x, typename ArrayTypes::t_int_1d_randomread type, Kokkos::View mixWtSite1old, @@ -474,13 +474,13 @@ static void compute_all_items( Kokkos::View::t_f_array::array_layout, DeviceType, - Kokkos::MemoryTraits::value> > f; + Kokkos::MemoryTraits::value> > f, Kokkos::View::value> > uCG; + DeviceType,Kokkos::MemoryTraits::value> > uCG, Kokkos::View::value> > uCGnew; + DeviceType,Kokkos::MemoryTraits::value> > uCGnew, int isite1, int isite2, - PairTableRXKokkos::TableDeviceConst d_table_const, + typename PairTableRXKokkos::TableDeviceConst d_table_const, int vflag_global) { if (eflag || vflag) { Kokkos::parallel_reduce(inum, @@ -517,7 +517,7 @@ static void compute_all_items( special_lj, m_cutsq, d_cutsq, f, uCG, uCGnew, isite1, isite2, d_table_const, vflag_global); } - }, ev); + }); } } @@ -558,8 +558,8 @@ void PairTableRXKokkos::compute_style(int eflag_in, int vflag_in) if (eflag || vflag) atomKK->modified(execution_space,datamask_modify); else atomKK->modified(execution_space,F_MASK); - auto x = atomKK->k_x.view(); - auto f = atomKK->k_f.view(); + x = atomKK->k_x.view(); + f = atomKK->k_f.view(); auto type = atomKK->k_type.view(); auto uCG = atomKK->k_uCG.view(); auto uCGnew = atomKK->k_uCGnew.view(); @@ -595,14 +595,14 @@ void PairTableRXKokkos::compute_style(int eflag_in, int vflag_in) eflag, vflag, newton_pair, ev, nlocal, l->inum, l->d_ilist, l->d_neighbors, l->d_numneigh, x, type, mixWtSite1old, mixWtSite2old, mixWtSite1, mixWtSite2, - special_lj, m_cutsq, d_cutsq, f, uCG, uCGnew, isite1, isite2, + special_lj_local, m_cutsq, d_cutsq, f, uCG, uCGnew, isite1, isite2, d_table_const, vflag_global); } else if (neighflag == HALF) { compute_all_items( eflag, vflag, newton_pair, ev, nlocal, l->inum, l->d_ilist, l->d_neighbors, l->d_numneigh, x, type, mixWtSite1old, mixWtSite2old, mixWtSite1, mixWtSite2, - special_lj, m_cutsq, d_cutsq, f, uCG, uCGnew, isite1, isite2, + special_lj_local, m_cutsq, d_cutsq, f, uCG, uCGnew, isite1, isite2, d_table_const, vflag_global); } } else { @@ -611,14 +611,14 @@ void PairTableRXKokkos::compute_style(int eflag_in, int vflag_in) eflag, vflag, newton_pair, ev, nlocal, l->inum, l->d_ilist, l->d_neighbors, l->d_numneigh, x, type, mixWtSite1old, mixWtSite2old, mixWtSite1, mixWtSite2, - special_lj, m_cutsq, d_cutsq, f, uCG, uCGnew, isite1, isite2, + special_lj_local, m_cutsq, d_cutsq, f, uCG, uCGnew, isite1, isite2, d_table_const, vflag_global); } else if (neighflag == HALF) { - compute_all_items( + compute_all_items( eflag, vflag, newton_pair, ev, nlocal, l->inum, l->d_ilist, l->d_neighbors, l->d_numneigh, x, type, mixWtSite1old, mixWtSite2old, mixWtSite1, mixWtSite2, - special_lj, m_cutsq, d_cutsq, f, uCG, uCGnew, isite1, isite2, + special_lj_local, m_cutsq, d_cutsq, f, uCG, uCGnew, isite1, isite2, d_table_const, vflag_global); } } @@ -1067,7 +1067,7 @@ double PairTableRXKokkos::single(int i, int j, int itype, int jtype, tb->deltasq6; fforce = factor_lj * value; } else { - union_int_float_t rsq_lookup; + Pair::union_int_float_t rsq_lookup; rsq_lookup.f = rsq; itable = rsq_lookup.i & tb->nmask; itable >>= tb->nshiftbits; diff --git a/src/KOKKOS/pair_table_rx_kokkos.h b/src/KOKKOS/pair_table_rx_kokkos.h index 36441f78b5..fdd863e4bc 100644 --- a/src/KOKKOS/pair_table_rx_kokkos.h +++ b/src/KOKKOS/pair_table_rx_kokkos.h @@ -23,6 +23,7 @@ PairStyle(table/rx/kk/host,PairTableRXKokkos) #define LMP_PAIR_TABLE_RX_KOKKOS_H #include "pair_table_kokkos.h" +#include "kokkos_few.h" namespace LAMMPS_NS { @@ -78,17 +79,15 @@ class PairTableRXKokkos : public PairTable { TableDevice* d_table; TableHost* h_table; - F_FLOAT m_cutsq[MAX_TYPES_STACKPARAMS+1][MAX_TYPES_STACKPARAMS+1]; + Few, MAX_TYPES_STACKPARAMS+1> m_cutsq; typename ArrayTypes::t_ffloat_2d d_cutsq; virtual void allocate(); void compute_table(Table *); - typename ArrayTypes::t_x_array_const c_x; + typename ArrayTypes::t_x_array_randomread x; typename ArrayTypes::t_f_array f; - typename ArrayTypes::t_efloat_1d uCG; - typename ArrayTypes::t_efloat_1d uCGnew; typename ArrayTypes::t_efloat_1d d_eatom; typename ArrayTypes::t_virial_array d_vatom; diff --git a/src/pair.h b/src/pair.h index 3378115e49..ecb54bcf4d 100644 --- a/src/pair.h +++ b/src/pair.h @@ -211,10 +211,12 @@ class Pair : protected Pointers { double tabinner; // inner cutoff for Coulomb table double tabinner_disp; // inner cutoff for dispersion table + public: // custom data type for accessing Coulomb tables typedef union {int i; float f;} union_int_float_t; + protected: int vflag_fdotr; int maxeatom,maxvatom; diff --git a/src/pair_table.h b/src/pair_table.h index caffebdf31..b723fd2d98 100644 --- a/src/pair_table.h +++ b/src/pair_table.h @@ -40,9 +40,9 @@ class PairTable : public Pair { virtual double single(int, int, int, int, double, double, double, double &); void *extract(const char *, int &); - protected: enum{LOOKUP,LINEAR,SPLINE,BITMAP}; + protected: int tabstyle,tablength; struct Table { int ninput,rflag,fpflag,match,ntablebits; From 52761aee0dc0ab1a6319c9d8ab7baa1f6940351b Mon Sep 17 00:00:00 2001 From: Dan Ibanez Date: Wed, 11 Jan 2017 13:18:13 -0700 Subject: [PATCH 075/439] it compiles. --- src/KOKKOS/neigh_list_kokkos.h | 2 +- src/KOKKOS/pair_table_rx_kokkos.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/KOKKOS/neigh_list_kokkos.h b/src/KOKKOS/neigh_list_kokkos.h index 32e6e704ae..b43e1106f2 100644 --- a/src/KOKKOS/neigh_list_kokkos.h +++ b/src/KOKKOS/neigh_list_kokkos.h @@ -90,7 +90,7 @@ public: KOKKOS_INLINE_FUNCTION static AtomNeighborsConst static_neighbors_const(int i, typename ArrayTypes::t_neighbors_2d_const d_neighbors, - typename ArrayTypes::t_int_1d d_numneigh) { + typename ArrayTypes::t_int_1d_const d_numneigh) { return AtomNeighborsConst(&d_neighbors(i,0),d_numneigh(i), &d_neighbors(i,1)-&d_neighbors(i,0)); } diff --git a/src/KOKKOS/pair_table_rx_kokkos.cpp b/src/KOKKOS/pair_table_rx_kokkos.cpp index c6206b828b..2a9e1bb13b 100644 --- a/src/KOKKOS/pair_table_rx_kokkos.cpp +++ b/src/KOKKOS/pair_table_rx_kokkos.cpp @@ -410,7 +410,7 @@ compute_item( f(j,2) -= delz*fpair; } - auto evdwl = compute_evdwl( + auto evdwl = compute_evdwl( rsq,itype,jtype,d_table_const); double evdwlOld; From 3580e5409de58417370feae7eb7727ef9480fbde Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Thu, 12 Jan 2017 09:00:07 -0700 Subject: [PATCH 076/439] Fixing Kokkos CUDA compile error --- lib/kokkos/Makefile.kokkos | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/kokkos/Makefile.kokkos b/lib/kokkos/Makefile.kokkos index 73a332ee11..94d0452428 100644 --- a/lib/kokkos/Makefile.kokkos +++ b/lib/kokkos/Makefile.kokkos @@ -20,7 +20,7 @@ KOKKOS_OPTIONS ?= "" #Default settings specific options #Options: force_uvm,use_ldg,rdc,enable_lambda -KOKKOS_CUDA_OPTIONS ?= "" +KOKKOS_CUDA_OPTIONS ?= "enable_lambda" # Check for general settings From 0c3b9426862c4da7730834a194a6e936c7593a7a Mon Sep 17 00:00:00 2001 From: Dan Ibanez Date: Thu, 12 Jan 2017 13:50:30 -0700 Subject: [PATCH 077/439] cleanup changes to Install.sh --- src/KOKKOS/Install.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/KOKKOS/Install.sh b/src/KOKKOS/Install.sh index e76f62d65d..cf753ecee8 100644 --- a/src/KOKKOS/Install.sh +++ b/src/KOKKOS/Install.sh @@ -28,8 +28,8 @@ action () { # force rebuild of files with LMP_KOKKOS switch -#touch ../accelerator_kokkos.h -#touch ../memory.h +touch ../accelerator_kokkos.h +touch ../memory.h # list of files with optional dependcies @@ -196,7 +196,7 @@ action pair_vashishta_kokkos.h pair_vashishta.h action pair_table_kokkos.cpp action pair_table_kokkos.h action pair_table_rx_kokkos.cpp pair_table_rx.cpp -action pair_table_rx_kokkos.h pair_table_rx.h +action pair_table_rx_kokkos.h pair_table_rx.h action pair_tersoff_kokkos.cpp pair_tersoff.cpp action pair_tersoff_kokkos.h pair_tersoff.h action pair_tersoff_mod_kokkos.cpp pair_tersoff_mod.cpp From 4dab6737ba59e402bf9a7609e66e24a75c313699 Mon Sep 17 00:00:00 2001 From: Dan Ibanez Date: Thu, 12 Jan 2017 14:15:42 -0700 Subject: [PATCH 078/439] remove leftover code --- src/KOKKOS/pair_table_rx_kokkos.cpp | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/KOKKOS/pair_table_rx_kokkos.cpp b/src/KOKKOS/pair_table_rx_kokkos.cpp index 2a9e1bb13b..66089009a2 100644 --- a/src/KOKKOS/pair_table_rx_kokkos.cpp +++ b/src/KOKKOS/pair_table_rx_kokkos.cpp @@ -179,20 +179,6 @@ void PairTableRXKokkos::compute(int eflag_in, int vflag_in) compute_style(eflag_in,vflag_in); } -template -template -PairTableRXKokkos::Functor::Functor( - PairTableRXKokkos* c_ptr, NeighListKokkos* list_ptr)//: -//c(*c_ptr),f(c.f),uCG(c.uCG),uCGnew(c.uCGnew),list(*list_ptr) -{} - -template -template -PairTableRXKokkos::Functor::~Functor() { -//c.cleanup_copy(); -//list.clean_copy(); -} - KOKKOS_INLINE_FUNCTION static int sbmask(const int& j) { return j >> SBBITS & 3; From cce10f6dff0dc0c28729e5787e9bc998751692b5 Mon Sep 17 00:00:00 2001 From: Dan Ibanez Date: Thu, 12 Jan 2017 14:19:10 -0700 Subject: [PATCH 079/439] remove more leftover code --- src/KOKKOS/pair_table_rx_kokkos.h | 33 ------------------------------- 1 file changed, 33 deletions(-) diff --git a/src/KOKKOS/pair_table_rx_kokkos.h b/src/KOKKOS/pair_table_rx_kokkos.h index fdd863e4bc..4e94802d72 100644 --- a/src/KOKKOS/pair_table_rx_kokkos.h +++ b/src/KOKKOS/pair_table_rx_kokkos.h @@ -106,39 +106,6 @@ class PairTableRXKokkos : public PairTable { int isite1, isite2; bool fractionalWeighting; - /* a duplicate of PairComputeFunctor to deal with uCG */ - template - struct Functor { - using device_type = DeviceType; - typedef EV_FLOAT value_type; - //PairTableRXKokkos c; - // arrays are atomic for Half(Thread) neighbor style - Kokkos::View::value> > f; - Kokkos::View::value> > uCG; - Kokkos::View::value> > uCGnew; - //NeighListKokkos list; - Functor(PairTableRXKokkos* c_ptr, NeighListKokkos* list_ptr); - ~Functor(); - KOKKOS_INLINE_FUNCTION int sbmask(const int& j) const { - return j >> SBBITS & 3; - } - template - KOKKOS_INLINE_FUNCTION - EV_FLOAT compute_item(const int&) const; - KOKKOS_INLINE_FUNCTION - void - ev_tally(EV_FLOAT &ev, const int &i, const int &j, - const F_FLOAT &epair, const F_FLOAT &fpair, const F_FLOAT &delx, - const F_FLOAT &dely, const F_FLOAT &delz) const; - KOKKOS_INLINE_FUNCTION - void operator()(const int) const; - KOKKOS_INLINE_FUNCTION - void operator()(const int, value_type&) const; - }; - }; } From 0635151e2db0e53b3680f5bc8613c078e99cf901 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Thu, 12 Jan 2017 16:22:24 -0700 Subject: [PATCH 080/439] Fixing neighbor bug --- src/neighbor.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/neighbor.cpp b/src/neighbor.cpp index 59abc29f19..af59391209 100644 --- a/src/neighbor.cpp +++ b/src/neighbor.cpp @@ -909,9 +909,10 @@ void Neighbor::init_pair() done = 1; for (i = 0; i < npair_perpetual; i++) { ptr = NULL; - if (lists[plist[i]]->listcopy) ptr = lists[plist[i]]->listcopy; - if (lists[plist[i]]->listskip) ptr = lists[plist[i]]->listskip; if (lists[plist[i]]->listfull) ptr = lists[plist[i]]->listfull; + if (lists[plist[i]]->listcopy) ptr = lists[plist[i]]->listcopy; + // listskip check must be after listfull check + if (lists[plist[i]]->listskip) ptr = lists[plist[i]]->listskip; if (ptr == NULL) continue; for (m = 0; m < nrequest; m++) if (ptr == lists[m]) break; From 5b7ab135dd849b2dbc74118036e872a1e20d2c43 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Thu, 12 Jan 2017 16:22:38 -0700 Subject: [PATCH 081/439] Fixing Kokkos neighbor bug --- src/neigh_request.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/neigh_request.cpp b/src/neigh_request.cpp index a8ba8496cd..7f5d9a6195 100644 --- a/src/neigh_request.cpp +++ b/src/neigh_request.cpp @@ -138,6 +138,8 @@ int NeighRequest::identical(NeighRequest *other) if (ghost != other->ghost) same = 0; if (omp != other->omp) same = 0; if (intel != other->intel) same = 0; + if (kokkos_host != other->kokkos_host) same = 0; + if (kokkos_device != other->kokkos_device) same = 0; if (ssa != other->ssa) same = 0; if (copy != other->copy_original) same = 0; From c15d6580da4174c247b9dc6af108b02b6b3aa47c Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 13 Jan 2017 10:01:22 -0700 Subject: [PATCH 082/439] Fixing issue in pair_multi_lucy_rx_kokkos found by ibaned --- src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp b/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp index 24502f875c..fac1478e32 100644 --- a/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp +++ b/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp @@ -277,7 +277,7 @@ void PairMultiLucyRXKokkos::operator()(TagPairMultiLucyRXCompute::value> > a_f = f; - int i,j,jj,inum,jnum,itype,jtype,itable; + int i,jj,inum,jnum,itype,jtype,itable; double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,evdwlOld,fpair; double rsq; @@ -431,7 +431,7 @@ void PairMultiLucyRXKokkos::operator()(TagPairMultiLucyRXCompute From 2a35fa7a4e253facc698e834d47a0ccb2cd2cace Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 13 Jan 2017 10:37:31 -0700 Subject: [PATCH 083/439] Adding initial versions of pair_hybrid_kokkos and pair_hybrid_overlay_kokkos --- src/KOKKOS/Install.sh | 4 + src/KOKKOS/pair_hybrid_kokkos.cpp | 147 ++++++++++++++++++++++ src/KOKKOS/pair_hybrid_kokkos.h | 109 ++++++++++++++++ src/KOKKOS/pair_hybrid_overlay_kokkos.cpp | 28 +++++ src/KOKKOS/pair_hybrid_overlay_kokkos.h | 48 +++++++ src/pair_hybrid.h | 6 +- src/pair_hybrid_overlay.h | 2 +- 7 files changed, 338 insertions(+), 6 deletions(-) create mode 100644 src/KOKKOS/pair_hybrid_kokkos.cpp create mode 100644 src/KOKKOS/pair_hybrid_kokkos.h create mode 100644 src/KOKKOS/pair_hybrid_overlay_kokkos.cpp create mode 100644 src/KOKKOS/pair_hybrid_overlay_kokkos.h diff --git a/src/KOKKOS/Install.sh b/src/KOKKOS/Install.sh index cf753ecee8..198946d9f0 100644 --- a/src/KOKKOS/Install.sh +++ b/src/KOKKOS/Install.sh @@ -154,6 +154,10 @@ action pair_eam_fs_kokkos.cpp pair_eam_fs.cpp action pair_eam_fs_kokkos.h pair_eam_fs.h action pair_exp6_rx_kokkos.cpp pair_exp6_rx.cpp action pair_exp6_rx_kokkos.h pair_exp6_rx.h +action pair_hybrid_kokkos.cpp +action pair_hybrid_kokkos.h +action pair_hybrid_overlay_kokkos.cpp +action pair_hybrid_overlay_kokkos.h action pair_kokkos.h action pair_lj_charmm_coul_charmm_implicit_kokkos.cpp pair_lj_charmm_coul_charmm_implicit.cpp action pair_lj_charmm_coul_charmm_implicit_kokkos.h pair_lj_charmm_coul_charmm_implicit.h diff --git a/src/KOKKOS/pair_hybrid_kokkos.cpp b/src/KOKKOS/pair_hybrid_kokkos.cpp new file mode 100644 index 0000000000..973d60348f --- /dev/null +++ b/src/KOKKOS/pair_hybrid_kokkos.cpp @@ -0,0 +1,147 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include +#include +#include +#include +#include "pair_hybrid_kokkos.h" +#include "atom_kokkos.h" +#include "force.h" +#include "pair.h" +#include "neighbor.h" +#include "neigh_request.h" +#include "update.h" +#include "comm.h" +#include "memory.h" +#include "error.h" +#include "respa.h" +#include "atom_masks.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +PairHybridKokkos::PairHybridKokkos(LAMMPS *lmp) : PairHybrid(lmp) +{ + atomKK = (AtomKokkos *) atom; + datamask_read = EMPTY_MASK; + datamask_modify = EMPTY_MASK; +} + +/* ---------------------------------------------------------------------- */ + +PairHybridKokkos::~PairHybridKokkos() +{ + +} + +/* ---------------------------------------------------------------------- + call each sub-style's compute() or compute_outer() function + accumulate sub-style global/peratom energy/virial in hybrid + for global vflag = 1: + each sub-style computes own virial[6] + sum sub-style virial[6] to hybrid's virial[6] + for global vflag = 2: + call sub-style with adjusted vflag to prevent it calling + virial_fdotr_compute() + hybrid calls virial_fdotr_compute() on final accumulated f +------------------------------------------------------------------------- */ + +void PairHybridKokkos::compute(int eflag, int vflag) +{ + int i,j,m,n; + + // if no_virial_fdotr_compute is set and global component of + // incoming vflag = 2, then + // reset vflag as if global component were 1 + // necessary since one or more sub-styles cannot compute virial as F dot r + + int neighflag = lmp->kokkos->neighflag; + if (neighflag == FULL) no_virial_fdotr_compute = 1; + + if (no_virial_fdotr_compute && vflag % 4 == 2) vflag = 1 + vflag/4 * 4; + + if (eflag || vflag) ev_setup(eflag,vflag); + else evflag = vflag_fdotr = eflag_global = vflag_global = + eflag_atom = vflag_atom = 0; + + // check if global component of incoming vflag = 2 + // if so, reset vflag passed to substyle as if it were 0 + // necessary so substyle will not invoke virial_fdotr_compute() + + int vflag_substyle; + if (vflag % 4 == 2) vflag_substyle = vflag/4 * 4; + else vflag_substyle = vflag; + + double *saved_special = save_special(); + + // check if we are running with r-RESPA using the hybrid keyword + + Respa *respa = NULL; + respaflag = 0; + if (strstr(update->integrate_style,"respa")) { + respa = (Respa *) update->integrate; + if (respa->nhybrid_styles > 0) respaflag = 1; + } + + for (m = 0; m < nstyles; m++) { + + set_special(m); + + if (!respaflag || (respaflag && respa->hybrid_compute[m])) { + + // invoke compute() unless compute flag is turned off or + // outerflag is set and sub-style has a compute_outer() method + + if (styles[m]->compute_flag == 0) continue; + atomKK->sync(styles[m]->execution_space,styles[m]->datamask_read); + if (outerflag && styles[m]->respa_enable) + styles[m]->compute_outer(eflag,vflag_substyle); + else styles[m]->compute(eflag,vflag_substyle); + atomKK->modified(styles[m]->execution_space,styles[m]->datamask_modify); + } + + restore_special(saved_special); + + // jump to next sub-style if r-RESPA does not want global accumulated data + + if (respaflag && !respa->tally_global) continue; + + if (eflag_global) { + eng_vdwl += styles[m]->eng_vdwl; + eng_coul += styles[m]->eng_coul; + } + if (vflag_global) { + for (n = 0; n < 6; n++) virial[n] += styles[m]->virial[n]; + } + if (eflag_atom) { + n = atom->nlocal; + if (force->newton_pair) n += atom->nghost; + double *eatom_substyle = styles[m]->eatom; + for (i = 0; i < n; i++) eatom[i] += eatom_substyle[i]; + } + if (vflag_atom) { + n = atom->nlocal; + if (force->newton_pair) n += atom->nghost; + double **vatom_substyle = styles[m]->vatom; + for (i = 0; i < n; i++) + for (j = 0; j < 6; j++) + vatom[i][j] += vatom_substyle[i][j]; + } + } + + delete [] saved_special; + + if (vflag_fdotr) virial_fdotr_compute(); +} diff --git a/src/KOKKOS/pair_hybrid_kokkos.h b/src/KOKKOS/pair_hybrid_kokkos.h new file mode 100644 index 0000000000..cfcef7fb31 --- /dev/null +++ b/src/KOKKOS/pair_hybrid_kokkos.h @@ -0,0 +1,109 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(hybrid/kk,PairHybridKokkos) + +#else + +#ifndef LMP_PAIR_HYBRID_KOKKOS_H +#define LMP_PAIR_HYBRID_KOKKOS_H + +#include +#include "pair_hybrid.h" + +namespace LAMMPS_NS { + +class PairHybridKokkos : public PairHybrid { + friend class FixGPU; + friend class FixIntel; + friend class FixOMP; + friend class Force; + friend class Respa; + friend class Info; + public: + PairHybridKokkos(class LAMMPS *); + virtual ~PairHybridKokkos(); + void compute(int, int); +}; + +} + +#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: Pair style hybrid cannot have hybrid as an argument + +Self-explanatory. + +E: Pair style hybrid cannot have none as an argument + +Self-explanatory. + +E: Incorrect args for pair coefficients + +Self-explanatory. Check the input script or data file. + +E: Pair coeff for hybrid has invalid style + +Style in pair coeff must have been listed in pair_style command. + +E: Pair hybrid sub-style is not used + +No pair_coeff command used a sub-style specified in the pair_style +command. + +E: Pair_modify special setting for pair hybrid incompatible with global special_bonds setting + +Cannot override a setting of 0.0 or 1.0 or change a setting between +0.0 and 1.0. + +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. + +E: Invoked pair single on pair style none + +A command (e.g. a dump) attempted to invoke the single() function on a +pair style none, which is illegal. You are probably attempting to +compute per-atom quantities with an undefined pair style. + +E: Pair hybrid sub-style does not support single call + +You are attempting to invoke a single() call on a pair style +that doesn't support it. + +E: Pair hybrid single calls do not support per sub-style special bond values + +Self-explanatory. + +E: Unknown pair_modify hybrid sub-style + +The choice of sub-style is unknown. + +E: Coulomb cutoffs of pair hybrid sub-styles do not match + +If using a Kspace solver, all Coulomb cutoffs of long pair styles must +be the same. + +*/ diff --git a/src/KOKKOS/pair_hybrid_overlay_kokkos.cpp b/src/KOKKOS/pair_hybrid_overlay_kokkos.cpp new file mode 100644 index 0000000000..55fed33f96 --- /dev/null +++ b/src/KOKKOS/pair_hybrid_overlay_kokkos.cpp @@ -0,0 +1,28 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include +#include +#include +#include "pair_hybrid_overlay_kokkos.h" +#include "atom.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_request.h" +#include "error.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +PairHybridOverlayKokkos::PairHybridOverlayKokkos(LAMMPS *lmp) : PairHybridOverlay(lmp) {} diff --git a/src/KOKKOS/pair_hybrid_overlay_kokkos.h b/src/KOKKOS/pair_hybrid_overlay_kokkos.h new file mode 100644 index 0000000000..c9a50e3bb1 --- /dev/null +++ b/src/KOKKOS/pair_hybrid_overlay_kokkos.h @@ -0,0 +1,48 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(hybrid/overlay/kk,PairHybridOverlayKokkos) + +#else + +#ifndef LMP_PAIR_HYBRID_OVERLAY_KOKKOS_H +#define LMP_PAIR_HYBRID_OVERLAY_KOKKOS_H + +#include "pair_hybrid_overlay.h" + +namespace LAMMPS_NS { + +class PairHybridOverlayKokkos : public PairHybridOverlay { + public: + PairHybridOverlayKokkos(class LAMMPS *); + virtual ~PairHybridOverlayKokkos() {} +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +E: Incorrect args for pair coefficients + +Self-explanatory. Check the input script or data file. + +E: Pair coeff for hybrid has invalid style + +Style in pair coeff must have been listed in pair_style command. + +*/ diff --git a/src/pair_hybrid.h b/src/pair_hybrid.h index 4d224dafc3..a7a236d269 100644 --- a/src/pair_hybrid.h +++ b/src/pair_hybrid.h @@ -35,7 +35,7 @@ class PairHybrid : public Pair { public: PairHybrid(class LAMMPS *); virtual ~PairHybrid(); - void compute(int, int); + virtual void compute(int, int); void settings(int, char **); virtual void coeff(int, char **); void init_style(); @@ -88,10 +88,6 @@ class PairHybrid : public Pair { /* ERROR/WARNING messages: -E: Cannot yet use pair hybrid with Kokkos - -This feature is not yet supported. - E: Illegal ... command Self-explanatory. Check the input script syntax and compare to the diff --git a/src/pair_hybrid_overlay.h b/src/pair_hybrid_overlay.h index 60cff45508..169583a48b 100644 --- a/src/pair_hybrid_overlay.h +++ b/src/pair_hybrid_overlay.h @@ -27,7 +27,7 @@ namespace LAMMPS_NS { class PairHybridOverlay : public PairHybrid { public: PairHybridOverlay(class LAMMPS *); - ~PairHybridOverlay() {} + virtual ~PairHybridOverlay() {} void coeff(int, char **); private: From a42a666142cdab572ee6bac9ef81559f9c02ceb8 Mon Sep 17 00:00:00 2001 From: Dan Ibanez Date: Fri, 13 Jan 2017 13:23:26 -0700 Subject: [PATCH 084/439] support for eatom and vatom in pair_table_rx_kokkos --- src/KOKKOS/pair_table_rx_kokkos.cpp | 214 +++++++++++++++++++++------- src/KOKKOS/pair_table_rx_kokkos.h | 6 +- 2 files changed, 166 insertions(+), 54 deletions(-) diff --git a/src/KOKKOS/pair_table_rx_kokkos.cpp b/src/KOKKOS/pair_table_rx_kokkos.cpp index 66089009a2..7402a00900 100644 --- a/src/KOKKOS/pair_table_rx_kokkos.cpp +++ b/src/KOKKOS/pair_table_rx_kokkos.cpp @@ -155,6 +155,10 @@ template PairTableRXKokkos::~PairTableRXKokkos() { if (copymode) return; + + memory->destroy_kokkos(k_eatom,eatom); + memory->destroy_kokkos(k_vatom,vatom); + delete h_table; h_table = nullptr; delete d_table; @@ -257,14 +261,38 @@ template KOKKOS_INLINE_FUNCTION void ev_tally( + int eflag, + int eflag_atom, + int vflag, int vflag_global, + int vflag_atom, int nlocal, int i, int j, EV_FLOAT& ev, F_FLOAT epair, F_FLOAT fpair, - F_FLOAT delx, F_FLOAT dely, F_FLOAT delz) + F_FLOAT delx, F_FLOAT dely, F_FLOAT delz, + Kokkos::View::value> > v_vatom, + Kokkos::View::value> > v_eatom) { - if (vflag_global) { + if (eflag) { + if (eflag_atom) { + auto epairhalf = 0.5 * epair; + if (NEIGHFLAG!=FULL) { + if (NEWTON_PAIR || i < nlocal) v_eatom[i] += epairhalf; + if (NEWTON_PAIR || j < nlocal) v_eatom[j] += epairhalf; + } else { + v_eatom[i] += epairhalf; + } + } + } + + if (vflag) { auto v0 = delx*delx*fpair; auto v1 = dely*dely*fpair; auto v2 = delz*delz*fpair; @@ -272,39 +300,69 @@ ev_tally( auto v4 = delx*delz*fpair; auto v5 = dely*delz*fpair; - if (NEIGHFLAG!=FULL) { - if (NEWTON_PAIR) { - ev.v[0] += v0; - ev.v[1] += v1; - ev.v[2] += v2; - ev.v[3] += v3; - ev.v[4] += v4; - ev.v[5] += v5; + if (vflag_global) { + if (NEIGHFLAG!=FULL) { + if (NEWTON_PAIR) { + ev.v[0] += v0; + ev.v[1] += v1; + ev.v[2] += v2; + ev.v[3] += v3; + ev.v[4] += v4; + ev.v[5] += v5; + } else { + if (i < nlocal) { + ev.v[0] += 0.5*v0; + ev.v[1] += 0.5*v1; + ev.v[2] += 0.5*v2; + ev.v[3] += 0.5*v3; + ev.v[4] += 0.5*v4; + ev.v[5] += 0.5*v5; + } + if (j < nlocal) { + ev.v[0] += 0.5*v0; + ev.v[1] += 0.5*v1; + ev.v[2] += 0.5*v2; + ev.v[3] += 0.5*v3; + ev.v[4] += 0.5*v4; + ev.v[5] += 0.5*v5; + } + } } else { - if (i < nlocal) { - ev.v[0] += 0.5*v0; - ev.v[1] += 0.5*v1; - ev.v[2] += 0.5*v2; - ev.v[3] += 0.5*v3; - ev.v[4] += 0.5*v4; - ev.v[5] += 0.5*v5; - } - if (j < nlocal) { - ev.v[0] += 0.5*v0; - ev.v[1] += 0.5*v1; - ev.v[2] += 0.5*v2; - ev.v[3] += 0.5*v3; - ev.v[4] += 0.5*v4; - ev.v[5] += 0.5*v5; - } + ev.v[0] += 0.5*v0; + ev.v[1] += 0.5*v1; + ev.v[2] += 0.5*v2; + ev.v[3] += 0.5*v3; + ev.v[4] += 0.5*v4; + ev.v[5] += 0.5*v5; + } + } + + if (vflag_atom) { + if (NEIGHFLAG!=FULL) { + if (NEWTON_PAIR || i < nlocal) { + v_vatom(i,0) += 0.5*v0; + v_vatom(i,1) += 0.5*v1; + v_vatom(i,2) += 0.5*v2; + v_vatom(i,3) += 0.5*v3; + v_vatom(i,4) += 0.5*v4; + v_vatom(i,5) += 0.5*v5; + } + if (NEWTON_PAIR || j < nlocal) { + v_vatom(j,0) += 0.5*v0; + v_vatom(j,1) += 0.5*v1; + v_vatom(j,2) += 0.5*v2; + v_vatom(j,3) += 0.5*v3; + v_vatom(j,4) += 0.5*v4; + v_vatom(j,5) += 0.5*v5; + } + } else { + v_vatom(i,0) += 0.5*v0; + v_vatom(i,1) += 0.5*v1; + v_vatom(i,2) += 0.5*v2; + v_vatom(i,3) += 0.5*v3; + v_vatom(i,4) += 0.5*v4; + v_vatom(i,5) += 0.5*v5; } - } else { - ev.v[0] += 0.5*v0; - ev.v[1] += 0.5*v1; - ev.v[2] += 0.5*v2; - ev.v[3] += 0.5*v3; - ev.v[4] += 0.5*v4; - ev.v[5] += 0.5*v5; } } } @@ -338,8 +396,19 @@ compute_item( DeviceType,Kokkos::MemoryTraits::value> > uCGnew, int isite1, int isite2, typename PairTableRXKokkos::TableDeviceConst d_table_const, - int vflag_global - ) { + int eflag, + int eflag_atom, + int vflag, + int vflag_global, + int vflag_atom, + Kokkos::View::value> > v_vatom, + Kokkos::View::value> > v_eatom) { EV_FLOAT ev; auto i = d_ilist(ii); auto xtmp = x(i,0); @@ -423,7 +492,10 @@ compute_item( if (EVFLAG) { ev_tally( - vflag_global,nlocal,i,j,ev,evdwl,fpair,delx,dely,delz); + eflag,eflag_atom, + vflag,vflag_global,vflag_atom, + nlocal,i,j,ev,evdwl,fpair,delx,dely,delz, + v_vatom, v_eatom); } } } @@ -440,7 +512,6 @@ compute_item( template static void compute_all_items( - int eflag, int vflag, int newton_pair, EV_FLOAT& ev, int nlocal, @@ -467,7 +538,19 @@ static void compute_all_items( DeviceType,Kokkos::MemoryTraits::value> > uCGnew, int isite1, int isite2, typename PairTableRXKokkos::TableDeviceConst d_table_const, - int vflag_global) { + int eflag, + int eflag_atom, + int vflag, + int vflag_global, + int vflag_atom, + Kokkos::View::value> > v_vatom, + Kokkos::View::value> > v_eatom) { if (eflag || vflag) { Kokkos::parallel_reduce(inum, LAMMPS_LAMBDA(int i, EV_FLOAT& energy_virial) { @@ -477,14 +560,16 @@ static void compute_all_items( i, nlocal, d_ilist, d_neighbors, d_numneigh, x, type, mixWtSite1old, mixWtSite2old, mixWtSite1, mixWtSite2, special_lj, m_cutsq, d_cutsq, f, uCG, uCGnew, isite1, isite2, - d_table_const, vflag_global); + d_table_const, eflag, eflag_atom, + vflag, vflag_global, vflag_atom, v_vatom, v_eatom); } else { energy_virial += compute_item( i, nlocal, d_ilist, d_neighbors, d_numneigh, x, type, mixWtSite1old, mixWtSite2old, mixWtSite1, mixWtSite2, special_lj, m_cutsq, d_cutsq, f, uCG, uCGnew, isite1, isite2, - d_table_const, vflag_global); + d_table_const, eflag, eflag_atom, + vflag, vflag_global, vflag_atom, v_vatom, v_eatom); } }, ev); } else { @@ -495,13 +580,15 @@ static void compute_all_items( i, nlocal, d_ilist, d_neighbors, d_numneigh, x, type, mixWtSite1old, mixWtSite2old, mixWtSite1, mixWtSite2, special_lj, m_cutsq, d_cutsq, f, uCG, uCGnew, isite1, isite2, - d_table_const, vflag_global); + d_table_const, eflag, eflag_atom, + vflag, vflag_global, vflag_atom, v_vatom, v_eatom); } else { compute_item( i, nlocal, d_ilist, d_neighbors, d_numneigh, x, type, mixWtSite1old, mixWtSite2old, mixWtSite1, mixWtSite2, special_lj, m_cutsq, d_cutsq, f, uCG, uCGnew, isite1, isite2, - d_table_const, vflag_global); + d_table_const, eflag, eflag_atom, + vflag, vflag_global, vflag_atom, v_vatom, v_eatom); } }); } @@ -537,8 +624,16 @@ void PairTableRXKokkos::compute_style(int eflag_in, int vflag_in) if (eflag || vflag) ev_setup(eflag,vflag); else evflag = vflag_fdotr = 0; - if (eflag_atom) error->all(FLERR, "pair table/rx/kk does not handle eflag_atom\n"); - if (vflag_atom) error->all(FLERR, "pair table/rx/kk does not handle vflag_atom\n"); + if (eflag_atom) { + memory->destroy_kokkos(k_eatom,eatom); + memory->create_kokkos(k_eatom,eatom,maxeatom,"pair:eatom"); + d_eatom = k_eatom.d_view; + } + if (vflag_atom) { + memory->destroy_kokkos(k_vatom,vatom); + memory->create_kokkos(k_vatom,vatom,maxvatom,6,"pair:vatom"); + d_vatom = k_vatom.d_view; + } atomKK->sync(execution_space,datamask_read); if (eflag || vflag) atomKK->modified(execution_space,datamask_modify); @@ -578,34 +673,38 @@ void PairTableRXKokkos::compute_style(int eflag_in, int vflag_in) if(atom->ntypes > MAX_TYPES_STACKPARAMS) { if (neighflag == HALFTHREAD) { compute_all_items( - eflag, vflag, newton_pair, ev, nlocal, + newton_pair, ev, nlocal, l->inum, l->d_ilist, l->d_neighbors, l->d_numneigh, x, type, mixWtSite1old, mixWtSite2old, mixWtSite1, mixWtSite2, special_lj_local, m_cutsq, d_cutsq, f, uCG, uCGnew, isite1, isite2, - d_table_const, vflag_global); + d_table_const, eflag, eflag_atom, + vflag, vflag_global, vflag_atom, d_vatom, d_eatom); } else if (neighflag == HALF) { compute_all_items( - eflag, vflag, newton_pair, ev, nlocal, + newton_pair, ev, nlocal, l->inum, l->d_ilist, l->d_neighbors, l->d_numneigh, x, type, mixWtSite1old, mixWtSite2old, mixWtSite1, mixWtSite2, special_lj_local, m_cutsq, d_cutsq, f, uCG, uCGnew, isite1, isite2, - d_table_const, vflag_global); + d_table_const, eflag, eflag_atom, + vflag, vflag_global, vflag_atom, d_vatom, d_eatom); } } else { if (neighflag == HALFTHREAD) { compute_all_items( - eflag, vflag, newton_pair, ev, nlocal, + newton_pair, ev, nlocal, l->inum, l->d_ilist, l->d_neighbors, l->d_numneigh, x, type, mixWtSite1old, mixWtSite2old, mixWtSite1, mixWtSite2, special_lj_local, m_cutsq, d_cutsq, f, uCG, uCGnew, isite1, isite2, - d_table_const, vflag_global); + d_table_const, eflag, eflag_atom, + vflag, vflag_global, vflag_atom, d_vatom, d_eatom); } else if (neighflag == HALF) { compute_all_items( - eflag, vflag, newton_pair, ev, nlocal, + newton_pair, ev, nlocal, l->inum, l->d_ilist, l->d_neighbors, l->d_numneigh, x, type, mixWtSite1old, mixWtSite2old, mixWtSite1, mixWtSite2, special_lj_local, m_cutsq, d_cutsq, f, uCG, uCGnew, isite1, isite2, - d_table_const, vflag_global); + d_table_const, eflag, eflag_atom, + vflag, vflag_global, vflag_atom, d_vatom, d_eatom); } } @@ -620,6 +719,16 @@ void PairTableRXKokkos::compute_style(int eflag_in, int vflag_in) } if (vflag_fdotr) pair_virial_fdotr_compute(this); + + if (eflag_atom) { + k_eatom.template modify(); + k_eatom.template sync(); + } + + if (vflag_atom) { + k_vatom.template modify(); + k_vatom.template sync(); + } } template @@ -1126,6 +1235,7 @@ void PairTableRXKokkos::cleanup_copy() { vatom = NULL; h_table=NULL; d_table=NULL; } + namespace LAMMPS_NS { template class PairTableRXKokkos; #ifdef KOKKOS_HAVE_CUDA diff --git a/src/KOKKOS/pair_table_rx_kokkos.h b/src/KOKKOS/pair_table_rx_kokkos.h index 4e94802d72..c7ecd370a4 100644 --- a/src/KOKKOS/pair_table_rx_kokkos.h +++ b/src/KOKKOS/pair_table_rx_kokkos.h @@ -88,8 +88,6 @@ class PairTableRXKokkos : public PairTable { typename ArrayTypes::t_x_array_randomread x; typename ArrayTypes::t_f_array f; - typename ArrayTypes::t_efloat_1d d_eatom; - typename ArrayTypes::t_virial_array d_vatom; int neighflag; @@ -106,6 +104,10 @@ class PairTableRXKokkos : public PairTable { int isite1, isite2; bool fractionalWeighting; + typename ArrayTypes::tdual_efloat_1d k_eatom; + typename ArrayTypes::tdual_virial_array k_vatom; + typename ArrayTypes::t_efloat_1d d_eatom; + typename ArrayTypes::t_virial_array d_vatom; }; } From 2b2998052c567719d6076435b640186105dda2ce Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 13 Jan 2017 13:50:21 -0700 Subject: [PATCH 085/439] Fixing inheritance issue in pair_hybrid_overlay_kokkos --- src/KOKKOS/pair_hybrid_overlay_kokkos.cpp | 116 +++++++++++++++++++++- src/KOKKOS/pair_hybrid_overlay_kokkos.h | 8 +- 2 files changed, 121 insertions(+), 3 deletions(-) diff --git a/src/KOKKOS/pair_hybrid_overlay_kokkos.cpp b/src/KOKKOS/pair_hybrid_overlay_kokkos.cpp index 55fed33f96..79d9c63221 100644 --- a/src/KOKKOS/pair_hybrid_overlay_kokkos.cpp +++ b/src/KOKKOS/pair_hybrid_overlay_kokkos.cpp @@ -25,4 +25,118 @@ using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ -PairHybridOverlayKokkos::PairHybridOverlayKokkos(LAMMPS *lmp) : PairHybridOverlay(lmp) {} +PairHybridOverlayKokkos::PairHybridOverlayKokkos(LAMMPS *lmp) : PairHybridKokkos(lmp) {} + +/* ---------------------------------------------------------------------- + set coeffs for one or more type pairs +------------------------------------------------------------------------- */ + +void PairHybridOverlayKokkos::coeff(int narg, char **arg) +{ + if (narg < 3) error->all(FLERR,"Incorrect args for pair coefficients"); + if (!allocated) allocate(); + + int ilo,ihi,jlo,jhi; + force->bounds(FLERR,arg[0],atom->ntypes,ilo,ihi); + force->bounds(FLERR,arg[1],atom->ntypes,jlo,jhi); + + // 3rd arg = pair sub-style name + // 4th arg = pair sub-style index if name used multiple times + // allow for "none" as valid sub-style name + + int multflag; + int m; + + for (m = 0; m < nstyles; m++) { + multflag = 0; + if (strcmp(arg[2],keywords[m]) == 0) { + if (multiple[m]) { + multflag = 1; + if (narg < 4) error->all(FLERR,"Incorrect args for pair coefficients"); + if (!isdigit(arg[3][0])) + error->all(FLERR,"Incorrect args for pair coefficients"); + int index = force->inumeric(FLERR,arg[3]); + if (index == multiple[m]) break; + else continue; + } else break; + } + } + + 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"); + } + + // move 1st/2nd args to 2nd/3rd args + // if multflag: move 1st/2nd args to 3rd/4th args + // just copy ptrs, since arg[] points into original input line + + arg[2+multflag] = arg[1]; + arg[1+multflag] = arg[0]; + + // invoke sub-style coeff() starting with 1st remaining arg + + if (!none) styles[m]->coeff(narg-1-multflag,&arg[1+multflag]); + + // set setflag and which type pairs map to which sub-style + // if sub-style is none: set hybrid subflag, wipe out map + // else: set hybrid setflag & map only if substyle setflag is set + // if sub-style is new for type pair, add as multiple mapping + // if sub-style exists for type pair, don't add, just update coeffs + + int count = 0; + for (int i = ilo; i <= ihi; i++) { + for (int j = MAX(jlo,i); j <= jhi; j++) { + if (none) { + setflag[i][j] = 1; + nmap[i][j] = 0; + count++; + } else if (styles[m]->setflag[i][j]) { + int k; + for (k = 0; k < nmap[i][j]; k++) + if (map[i][j][k] == m) break; + if (k == nmap[i][j]) map[i][j][nmap[i][j]++] = m; + setflag[i][j] = 1; + count++; + } + } + } + + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); +} + +/* ---------------------------------------------------------------------- + combine sub-style neigh list requests and create new ones if needed +------------------------------------------------------------------------- */ + +void PairHybridOverlayKokkos::modify_requests() +{ + int i,j; + NeighRequest *irq,*jrq; + + // loop over pair requests only + // if a previous list is same kind with same skip attributes + // then make this one a copy list of that one + // works whether both lists are no-skip or yes-skip + // will not point a list at a copy list, but at copy list's parent + + for (i = 0; i < neighbor->nrequest; i++) { + if (!neighbor->requests[i]->pair) continue; + + irq = neighbor->requests[i]; + for (j = 0; j < i; j++) { + if (!neighbor->requests[j]->pair) continue; + jrq = neighbor->requests[j]; + if (irq->same_kind(jrq) && irq->same_skip(jrq)) { + irq->copy = 1; + irq->otherlist = j; + break; + } + } + } + + // perform same operations on skip lists as pair style = hybrid + + PairHybrid::modify_requests(); +} diff --git a/src/KOKKOS/pair_hybrid_overlay_kokkos.h b/src/KOKKOS/pair_hybrid_overlay_kokkos.h index c9a50e3bb1..2e4899a1f3 100644 --- a/src/KOKKOS/pair_hybrid_overlay_kokkos.h +++ b/src/KOKKOS/pair_hybrid_overlay_kokkos.h @@ -20,14 +20,18 @@ PairStyle(hybrid/overlay/kk,PairHybridOverlayKokkos) #ifndef LMP_PAIR_HYBRID_OVERLAY_KOKKOS_H #define LMP_PAIR_HYBRID_OVERLAY_KOKKOS_H -#include "pair_hybrid_overlay.h" +#include "pair_hybrid_kokkos.h" namespace LAMMPS_NS { -class PairHybridOverlayKokkos : public PairHybridOverlay { +class PairHybridOverlayKokkos : public PairHybridKokkos { public: PairHybridOverlayKokkos(class LAMMPS *); virtual ~PairHybridOverlayKokkos() {} + void coeff(int, char **); + + private: + void modify_requests(); }; } From 688df1c2542cef4461b99e99632cce54dd0eb51d Mon Sep 17 00:00:00 2001 From: Dan Ibanez Date: Fri, 13 Jan 2017 14:40:36 -0700 Subject: [PATCH 086/439] fix CUDA type issues in pair_table_rx_kokkos stop using the global DAT, use the pair's DeviceType for all the relevant types. --- src/KOKKOS/pair_table_rx_kokkos.cpp | 34 +++++++++++++++++------------ src/KOKKOS/pair_table_rx_kokkos.h | 3 --- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/src/KOKKOS/pair_table_rx_kokkos.cpp b/src/KOKKOS/pair_table_rx_kokkos.cpp index 7402a00900..58108c9308 100644 --- a/src/KOKKOS/pair_table_rx_kokkos.cpp +++ b/src/KOKKOS/pair_table_rx_kokkos.cpp @@ -272,11 +272,11 @@ ev_tally( F_FLOAT epair, F_FLOAT fpair, F_FLOAT delx, F_FLOAT dely, F_FLOAT delz, Kokkos::View::t_virial_array::array_layout, DeviceType, Kokkos::MemoryTraits::value> > v_vatom, Kokkos::View::t_efloat_1d::array_layout, DeviceType, Kokkos::MemoryTraits::value> > v_eatom) { @@ -390,10 +390,14 @@ compute_item( typename ArrayTypes::t_f_array::array_layout, DeviceType, Kokkos::MemoryTraits::value> > f, - Kokkos::View::value> > uCG, - Kokkos::View::value> > uCGnew, + Kokkos::View::t_efloat_1d::array_layout, + DeviceType, + Kokkos::MemoryTraits::value> > uCG, + Kokkos::View::t_efloat_1d::array_layout, + DeviceType, + Kokkos::MemoryTraits::value> > uCGnew, int isite1, int isite2, typename PairTableRXKokkos::TableDeviceConst d_table_const, int eflag, @@ -402,11 +406,11 @@ compute_item( int vflag_global, int vflag_atom, Kokkos::View::t_virial_array::array_layout, DeviceType, Kokkos::MemoryTraits::value> > v_vatom, Kokkos::View::t_efloat_1d::array_layout, DeviceType, Kokkos::MemoryTraits::value> > v_eatom) { EV_FLOAT ev; @@ -532,9 +536,11 @@ static void compute_all_items( typename ArrayTypes::t_f_array::array_layout, DeviceType, Kokkos::MemoryTraits::value> > f, - Kokkos::View::t_efloat_1d::array_layout, DeviceType,Kokkos::MemoryTraits::value> > uCG, - Kokkos::View::t_efloat_1d::array_layout, DeviceType,Kokkos::MemoryTraits::value> > uCGnew, int isite1, int isite2, typename PairTableRXKokkos::TableDeviceConst d_table_const, @@ -544,11 +550,11 @@ static void compute_all_items( int vflag_global, int vflag_atom, Kokkos::View::t_virial_array::array_layout, DeviceType, Kokkos::MemoryTraits::value> > v_vatom, Kokkos::View::t_efloat_1d::array_layout, DeviceType, Kokkos::MemoryTraits::value> > v_eatom) { if (eflag || vflag) { @@ -627,12 +633,12 @@ void PairTableRXKokkos::compute_style(int eflag_in, int vflag_in) if (eflag_atom) { memory->destroy_kokkos(k_eatom,eatom); memory->create_kokkos(k_eatom,eatom,maxeatom,"pair:eatom"); - d_eatom = k_eatom.d_view; + d_eatom = k_eatom.template view(); } if (vflag_atom) { memory->destroy_kokkos(k_vatom,vatom); memory->create_kokkos(k_vatom,vatom,maxvatom,6,"pair:vatom"); - d_vatom = k_vatom.d_view; + d_vatom = k_vatom.template view(); } atomKK->sync(execution_space,datamask_read); diff --git a/src/KOKKOS/pair_table_rx_kokkos.h b/src/KOKKOS/pair_table_rx_kokkos.h index c7ecd370a4..54c114a433 100644 --- a/src/KOKKOS/pair_table_rx_kokkos.h +++ b/src/KOKKOS/pair_table_rx_kokkos.h @@ -30,9 +30,6 @@ namespace LAMMPS_NS { template class PairTableRXKokkos : public PairTable { public: - - using DAT = ArrayTypes; - enum {EnabledNeighFlags=FULL|HALFTHREAD|HALF|N2}; typedef DeviceType device_type; From 91d68e26eff86b7e1fe50bb3786b13b7f6a07b30 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 17 Jan 2017 12:26:00 -0700 Subject: [PATCH 087/439] Prevent overlapping host/device computation in pair_hybrid_kokkos --- src/KOKKOS/pair_hybrid_kokkos.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/KOKKOS/pair_hybrid_kokkos.cpp b/src/KOKKOS/pair_hybrid_kokkos.cpp index 973d60348f..9c0948b7d4 100644 --- a/src/KOKKOS/pair_hybrid_kokkos.cpp +++ b/src/KOKKOS/pair_hybrid_kokkos.cpp @@ -35,6 +35,11 @@ using namespace LAMMPS_NS; PairHybridKokkos::PairHybridKokkos(LAMMPS *lmp) : PairHybrid(lmp) { atomKK = (AtomKokkos *) atom; + + // prevent overlapping host/device computation, which isn't + // yet supported by pair_hybrid_kokkos + execution_space = Device; + datamask_read = EMPTY_MASK; datamask_modify = EMPTY_MASK; } From 8b4130c0cbbbf6bfb69e01d51f5ba47c94ecd3ed Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 17 Jan 2017 13:28:55 -0700 Subject: [PATCH 088/439] Fixing issue with pressure in pair_hybrid_kokkos --- src/KOKKOS/pair_hybrid_kokkos.cpp | 9 ++++++++- src/KOKKOS/pair_hybrid_kokkos.h | 9 +++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/KOKKOS/pair_hybrid_kokkos.cpp b/src/KOKKOS/pair_hybrid_kokkos.cpp index 9c0948b7d4..337b56c6ce 100644 --- a/src/KOKKOS/pair_hybrid_kokkos.cpp +++ b/src/KOKKOS/pair_hybrid_kokkos.cpp @@ -148,5 +148,12 @@ void PairHybridKokkos::compute(int eflag, int vflag) delete [] saved_special; - if (vflag_fdotr) virial_fdotr_compute(); + // perform virial_fdotr on device + + atomKK->sync(Device,X_MASK|F_MASK); + x = atomKK->k_x.view(); + f = atomKK->k_f.view(); + + if (vflag_fdotr) + pair_virial_fdotr_compute(this); } diff --git a/src/KOKKOS/pair_hybrid_kokkos.h b/src/KOKKOS/pair_hybrid_kokkos.h index cfcef7fb31..62d325925b 100644 --- a/src/KOKKOS/pair_hybrid_kokkos.h +++ b/src/KOKKOS/pair_hybrid_kokkos.h @@ -22,6 +22,8 @@ PairStyle(hybrid/kk,PairHybridKokkos) #include #include "pair_hybrid.h" +#include "pair_kokkos.h" +#include "kokkos_type.h" namespace LAMMPS_NS { @@ -33,9 +35,16 @@ class PairHybridKokkos : public PairHybrid { friend class Respa; friend class Info; public: + typedef LMPDeviceType device_type; + PairHybridKokkos(class LAMMPS *); virtual ~PairHybridKokkos(); void compute(int, int); + + private: + DAT::t_x_array_randomread x; + DAT::t_f_array f; + friend void pair_virial_fdotr_compute(PairHybridKokkos*); }; } From 5569c4c130c08656ddf4313127effcd039185bf6 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 17 Jan 2017 16:19:25 -0700 Subject: [PATCH 089/439] Fixing GPU memory issue with fix_property_atom_kokkos --- src/KOKKOS/atom_vec_dpd_kokkos.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/KOKKOS/atom_vec_dpd_kokkos.cpp b/src/KOKKOS/atom_vec_dpd_kokkos.cpp index 58fc9c46c3..82d45dfcd4 100644 --- a/src/KOKKOS/atom_vec_dpd_kokkos.cpp +++ b/src/KOKKOS/atom_vec_dpd_kokkos.cpp @@ -86,12 +86,12 @@ void AtomVecDPDKokkos::grow(int n) memory->grow_kokkos(atomKK->k_uCGnew,atomKK->uCGnew,nmax,"atom:uCGnew"); memory->grow_kokkos(atomKK->k_duChem,atomKK->duChem,nmax,"atom:duChem"); - grow_reset(); - sync(Host,ALL_MASK); - if (atom->nextra_grow) for (int iextra = 0; iextra < atom->nextra_grow; iextra++) modify->fix[atom->extra_grow[iextra]]->grow_arrays(nmax); + + grow_reset(); + sync(Host,ALL_MASK); } /* ---------------------------------------------------------------------- From 96636c7514a8fa9f978e3bbb42972a986e458285 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 17 Jan 2017 16:43:55 -0700 Subject: [PATCH 090/439] Fixing warnings in pair_exp6_rx_kokkos --- src/KOKKOS/pair_exp6_rx_kokkos.cpp | 4 ++-- src/KOKKOS/pair_exp6_rx_kokkos.h | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/KOKKOS/pair_exp6_rx_kokkos.cpp b/src/KOKKOS/pair_exp6_rx_kokkos.cpp index 3ce6b78e57..9be44666aa 100644 --- a/src/KOKKOS/pair_exp6_rx_kokkos.cpp +++ b/src/KOKKOS/pair_exp6_rx_kokkos.cpp @@ -284,7 +284,7 @@ void PairExp6rxKokkos::operator()(TagPairExp6rxCompute::value> > a_uCG = uCG; Kokkos::View::value> > a_uCGnew = uCGnew; - int i,j,jj,jnum,itype,jtype; + int i,jj,jnum,itype,jtype; double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,evdwlOld,fpair; double rsq,r2inv,r6inv,forceExp6,factor_lj; double rCut,rCutInv,rCut2inv,rCut6inv,rCutExp,urc,durc; @@ -508,7 +508,7 @@ void PairExp6rxKokkos::operator()(TagPairExp6rxComputeall(FLERR,"alpha_ij is 6.0 in pair exp6"); + k_error_flag.d_view() = 1; // A3. Compute some convenient quantities for evaluating the force rminv = 1.0/rm12_ij; diff --git a/src/KOKKOS/pair_exp6_rx_kokkos.h b/src/KOKKOS/pair_exp6_rx_kokkos.h index 488c9d0039..1f2172471b 100644 --- a/src/KOKKOS/pair_exp6_rx_kokkos.h +++ b/src/KOKKOS/pair_exp6_rx_kokkos.h @@ -150,6 +150,24 @@ class PairExp6rxKokkos : public PairExp6rx { friend void pair_virial_fdotr_compute(PairExp6rxKokkos*); }; + +// optimized version of pow(x,n) with n being integer +// up to 10x faster than pow(x,y) + +KOKKOS_INLINE_FUNCTION +static double powint(const double &x, const int n) { + double yy,ww; + + if (x == 0.0) return 0.0; + int nn = (n > 0) ? n : -n; + ww = x; + + for (yy = 1.0; nn != 0; nn >>= 1, ww *=ww) + if (nn & 1) yy *= ww; + + return (n > 0) ? yy : 1.0/yy; +}; + } #endif From b38733e5a2b73e6f1a3d6ec37958bc68251f2bca Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Wed, 18 Jan 2017 10:15:06 -0700 Subject: [PATCH 091/439] Fixing GPU memory issue in pair_exp6_rx_kokkos --- src/KOKKOS/pair_exp6_rx_kokkos.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/KOKKOS/pair_exp6_rx_kokkos.cpp b/src/KOKKOS/pair_exp6_rx_kokkos.cpp index 9be44666aa..bde3a32b4b 100644 --- a/src/KOKKOS/pair_exp6_rx_kokkos.cpp +++ b/src/KOKKOS/pair_exp6_rx_kokkos.cpp @@ -659,6 +659,10 @@ void PairExp6rxKokkos::coeff(int narg, char **arg) s_coeffEps[i] = coeffEps[i]; s_coeffRm[i] = coeffRm[i]; } + + k_params.template modify(); + k_params.template sync(); + d_params = k_params.template view(); } /* ---------------------------------------------------------------------- */ @@ -776,10 +780,6 @@ void PairExp6rxKokkos::read_file(char *file) } delete [] words; - - k_params.template modify(); - k_params.template sync(); - d_params = k_params.template view(); } /* ---------------------------------------------------------------------- */ From 2d32fa8ccb046159155212e36b09b663608525d5 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Wed, 18 Jan 2017 12:53:40 -0700 Subject: [PATCH 092/439] Fixing GPU memory issues in atom_vec_dpd_kokkos --- src/KOKKOS/atom_vec_dpd_kokkos.cpp | 45 +++++++++++++++++++----------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/src/KOKKOS/atom_vec_dpd_kokkos.cpp b/src/KOKKOS/atom_vec_dpd_kokkos.cpp index 82d45dfcd4..699ea61c9d 100644 --- a/src/KOKKOS/atom_vec_dpd_kokkos.cpp +++ b/src/KOKKOS/atom_vec_dpd_kokkos.cpp @@ -256,7 +256,7 @@ int AtomVecDPDKokkos::pack_comm_kokkos(const int &n, // Choose correct forward PackComm kernel if(commKK->forward_comm_on_host) { - sync(Host,X_MASK); + sync(Host,X_MASK|DPDTHETA_MASK|UCOND_MASK|UMECH_MASK|UCHEM_MASK); if(pbc_flag) { if(domain->triclinic) { struct AtomVecDPDKokkos_PackComm f(atomKK->k_x, @@ -292,7 +292,7 @@ int AtomVecDPDKokkos::pack_comm_kokkos(const int &n, } LMPHostType::fence(); } else { - sync(Device,X_MASK); + sync(Device,X_MASK|DPDTHETA_MASK|UCOND_MASK|UMECH_MASK|UCHEM_MASK); if(pbc_flag) { if(domain->triclinic) { struct AtomVecDPDKokkos_PackComm f(atomKK->k_x, @@ -400,8 +400,8 @@ struct AtomVecDPDKokkos_PackCommSelf { int AtomVecDPDKokkos::pack_comm_self(const int &n, const DAT::tdual_int_2d &list, const int & iswap, const int nfirst, const int &pbc_flag, const int* const pbc) { if(commKK->forward_comm_on_host) { - sync(Host,X_MASK); - modified(Host,X_MASK); + sync(Host,X_MASK|DPDTHETA_MASK|UCOND_MASK|UMECH_MASK|UCHEM_MASK); + modified(Host,X_MASK|DPDTHETA_MASK|UCOND_MASK|UMECH_MASK|UCHEM_MASK); if(pbc_flag) { if(domain->triclinic) { struct AtomVecDPDKokkos_PackCommSelf f(atomKK->k_x, @@ -437,8 +437,8 @@ int AtomVecDPDKokkos::pack_comm_self(const int &n, const DAT::tdual_int_2d &list } LMPHostType::fence(); } else { - sync(Device,X_MASK); - modified(Device,X_MASK); + sync(Device,X_MASK|DPDTHETA_MASK|UCOND_MASK|UMECH_MASK|UCHEM_MASK); + modified(Device,X_MASK|DPDTHETA_MASK|UCOND_MASK|UMECH_MASK|UCHEM_MASK); if(pbc_flag) { if(domain->triclinic) { struct AtomVecDPDKokkos_PackCommSelf f(atomKK->k_x, @@ -520,16 +520,16 @@ struct AtomVecDPDKokkos_UnpackComm { void AtomVecDPDKokkos::unpack_comm_kokkos(const int &n, const int &first, const DAT::tdual_xfloat_2d &buf ) { if(commKK->forward_comm_on_host) { - sync(Host,X_MASK); - modified(Host,X_MASK); + sync(Host,X_MASK|DPDTHETA_MASK|UCOND_MASK|UMECH_MASK|UCHEM_MASK); + modified(Host,X_MASK|DPDTHETA_MASK|UCOND_MASK|UMECH_MASK|UCHEM_MASK); struct AtomVecDPDKokkos_UnpackComm f(atomKK->k_x, atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem, buf,first); Kokkos::parallel_for(n,f); LMPDeviceType::fence(); } else { - sync(Device,X_MASK); - modified(Device,X_MASK); + sync(Device,X_MASK|DPDTHETA_MASK|UCOND_MASK|UMECH_MASK|UCHEM_MASK); + modified(Device,X_MASK|DPDTHETA_MASK|UCOND_MASK|UMECH_MASK|UCHEM_MASK); struct AtomVecDPDKokkos_UnpackComm f(atomKK->k_x, atomKK->k_dpdTheta,atomKK->k_uCond,atomKK->k_uMech,atomKK->k_uChem, buf,first); @@ -1107,9 +1107,13 @@ struct AtomVecDPDKokkos_UnpackBorder { void AtomVecDPDKokkos::unpack_border_kokkos(const int &n, const int &first, const DAT::tdual_xfloat_2d &buf,ExecutionSpace space) { - modified(space,X_MASK|TAG_MASK|TYPE_MASK|MASK_MASK); + modified(space,X_MASK|TAG_MASK|TYPE_MASK|MASK_MASK| + DPDTHETA_MASK|UCOND_MASK|UMECH_MASK|UCHEM_MASK| + UCG_MASK|UCGNEW_MASK); while (first+n >= nmax) grow(0); - modified(space,X_MASK|TAG_MASK|TYPE_MASK|MASK_MASK); + modified(space,X_MASK|TAG_MASK|TYPE_MASK|MASK_MASK| + DPDTHETA_MASK|UCOND_MASK|UMECH_MASK|UCHEM_MASK| + UCG_MASK|UCGNEW_MASK); if(space==Host) { struct AtomVecDPDKokkos_UnpackBorder f(buf.view(), h_x,h_tag,h_type,h_mask, @@ -1137,7 +1141,9 @@ void AtomVecDPDKokkos::unpack_border(int n, int first, double *buf) last = first + n; for (i = first; i < last; i++) { if (i == nmax) grow(0); - modified(Host,X_MASK|TAG_MASK|TYPE_MASK|MASK_MASK); + modified(Host,X_MASK|TAG_MASK|TYPE_MASK|MASK_MASK| + DPDTHETA_MASK|UCOND_MASK|UMECH_MASK|UCHEM_MASK| + UCG_MASK|UCGNEW_MASK); h_x(i,0) = buf[m++]; h_x(i,1) = buf[m++]; h_x(i,2) = buf[m++]; @@ -1168,7 +1174,9 @@ void AtomVecDPDKokkos::unpack_border_vel(int n, int first, double *buf) last = first + n; for (i = first; i < last; i++) { if (i == nmax) grow(0); - modified(Host,X_MASK|V_MASK|TAG_MASK|TYPE_MASK|MASK_MASK); + modified(Host,X_MASK|V_MASK|TAG_MASK|TYPE_MASK|MASK_MASK| + DPDTHETA_MASK|UCOND_MASK|UMECH_MASK|UCHEM_MASK| + UCG_MASK|UCGNEW_MASK); h_x(i,0) = buf[m++]; h_x(i,1) = buf[m++]; h_x(i,2) = buf[m++]; @@ -1489,7 +1497,8 @@ int AtomVecDPDKokkos::unpack_exchange(double *buf) int nlocal = atom->nlocal; if (nlocal == nmax) grow(0); modified(Host,X_MASK | V_MASK | TAG_MASK | TYPE_MASK | - MASK_MASK | IMAGE_MASK); + MASK_MASK | IMAGE_MASK| DPDTHETA_MASK | UCOND_MASK | + UMECH_MASK | UCHEM_MASK | UCG_MASK | UCGNEW_MASK); int m = 1; h_x(nlocal,0) = buf[m++]; @@ -1547,7 +1556,8 @@ int AtomVecDPDKokkos::size_restart() int AtomVecDPDKokkos::pack_restart(int i, double *buf) { sync(Host,X_MASK | V_MASK | TAG_MASK | TYPE_MASK | - MASK_MASK | IMAGE_MASK ); + MASK_MASK | IMAGE_MASK | DPDTHETA_MASK | + UCOND_MASK | UMECH_MASK | UCHEM_MASK | DVECTOR_MASK); int m = 1; buf[m++] = h_x(i,0); @@ -1586,7 +1596,8 @@ int AtomVecDPDKokkos::unpack_restart(double *buf) memory->grow(atom->extra,nmax,atom->nextra_store,"atom:extra"); } modified(Host,X_MASK | V_MASK | TAG_MASK | TYPE_MASK | - MASK_MASK | IMAGE_MASK ); + MASK_MASK | IMAGE_MASK | DPDTHETA_MASK | + UCOND_MASK | UMECH_MASK | UCHEM_MASK | DVECTOR_MASK); int m = 1; h_x(nlocal,0) = buf[m++]; From e05b1322895337ed3653b74adebfc54208db3649 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Wed, 18 Jan 2017 14:18:35 -0700 Subject: [PATCH 093/439] Fixing error check in fix_eos_table_rx_kokkos --- src/KOKKOS/fix_eos_table_rx_kokkos.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/KOKKOS/fix_eos_table_rx_kokkos.cpp b/src/KOKKOS/fix_eos_table_rx_kokkos.cpp index aff2cdfa2d..40b44d6744 100644 --- a/src/KOKKOS/fix_eos_table_rx_kokkos.cpp +++ b/src/KOKKOS/fix_eos_table_rx_kokkos.cpp @@ -404,7 +404,8 @@ void FixEOStableRXKokkos::temperature_lookup(int id, double ui, doub if(it==maxit){ if(isnan(f1) || isnan(f2) || isnan(ui) || isnan(thetai) || isnan(t1) || isnan(t2)) k_error_flag.d_view() = 2; - k_error_flag.d_view() = 3; + else + k_error_flag.d_view() = 3; } thetai = temp; } From 116ae9d0c42aa949f9478a95ba20654804442381 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Wed, 18 Jan 2017 14:51:35 -0700 Subject: [PATCH 094/439] Fixing copy bug in pair_exp6_rx_kokkos --- src/KOKKOS/pair_exp6_rx_kokkos.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/KOKKOS/pair_exp6_rx_kokkos.cpp b/src/KOKKOS/pair_exp6_rx_kokkos.cpp index bde3a32b4b..acba9e473b 100644 --- a/src/KOKKOS/pair_exp6_rx_kokkos.cpp +++ b/src/KOKKOS/pair_exp6_rx_kokkos.cpp @@ -1095,7 +1095,7 @@ void PairExp6rxKokkos::polynomialScaling(double phi, double &alpha, alpha = (s_coeffAlpha[0]*phi5 + s_coeffAlpha[1]*phi4 + s_coeffAlpha[2]*phi3 + s_coeffAlpha[3]*phi2 + s_coeffAlpha[4]*phi + s_coeffAlpha[5]); epsilon *= (s_coeffEps[0]*phi5 + s_coeffEps[1]*phi4 + s_coeffEps[2]*phi3 + s_coeffEps[3]*phi2 + s_coeffEps[4]*phi + s_coeffEps[5]); - rm *= (s_coeffEps[0]*phi5 + s_coeffEps[1]*phi4 + s_coeffEps[2]*phi3 + s_coeffEps[3]*phi2 + s_coeffEps[4]*phi + s_coeffEps[5]); + rm *= (s_coeffRm[0]*phi5 + s_coeffRm[1]*phi4 + s_coeffRm[2]*phi3 + s_coeffRm[3]*phi2 + s_coeffRm[4]*phi + s_coeffRm[5]); } /* ---------------------------------------------------------------------- */ From cf83ce454369b365efff7210382b7f2a3a246cf1 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Thu, 19 Jan 2017 08:44:30 -0700 Subject: [PATCH 095/439] Adding zero compute to pair_dpd_fdt_energy_kokkos --- src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp | 32 ++++++++++++----------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp b/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp index 5de2b38ed0..ec807a0e08 100644 --- a/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp +++ b/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp @@ -170,21 +170,23 @@ void PairDPDfdtEnergyKokkos::compute(int eflag_in, int vflag_in) EV_FLOAT ev; if (splitFDT_flag) { - if (neighflag == HALF) { - if (newton_pair) { - if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); - else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); - } else { - if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); - else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); - } - } else if (neighflag == HALFTHREAD) { - if (newton_pair) { - if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); - else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); - } else { - if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); - else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + if (!a0_is_zero) { + if (neighflag == HALF) { + if (newton_pair) { + if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } else { + if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } + } else if (neighflag == HALFTHREAD) { + if (newton_pair) { + if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } else { + if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } } } } else { From 917ca19b340dec624890201ebb7280c2a64fef0a Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Thu, 19 Jan 2017 09:54:15 -0700 Subject: [PATCH 096/439] Fixing GPU memory issue in modify_kokkos, need to cherry pick back to Master --- src/KOKKOS/modify_kokkos.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/KOKKOS/modify_kokkos.cpp b/src/KOKKOS/modify_kokkos.cpp index ec3831dff8..b4a89c8e39 100644 --- a/src/KOKKOS/modify_kokkos.cpp +++ b/src/KOKKOS/modify_kokkos.cpp @@ -360,9 +360,7 @@ void ModifyKokkos::post_run() for (int i = 0; i < nfix; i++) { atomKK->sync(fix[i]->execution_space, fix[i]->datamask_read); - if (!fix[i]->kokkosable) lmp->kokkos->auto_sync = 1; fix[i]->post_run(); - lmp->kokkos->auto_sync = 0; atomKK->modified(fix[i]->execution_space, fix[i]->datamask_modify); } From de6442d8450cbebc62267dcc6872c58e68947766 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Thu, 19 Jan 2017 11:55:22 -0700 Subject: [PATCH 097/439] Fixing GPU memory issues in Kokkos --- src/KOKKOS/domain_kokkos.cpp | 4 ++-- src/KOKKOS/verlet_kokkos.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/KOKKOS/domain_kokkos.cpp b/src/KOKKOS/domain_kokkos.cpp index cf65316ec9..5c1f1a60b9 100644 --- a/src/KOKKOS/domain_kokkos.cpp +++ b/src/KOKKOS/domain_kokkos.cpp @@ -354,7 +354,6 @@ void DomainKokkos::pbc() } atomKK->sync(Device,X_MASK|V_MASK|MASK_MASK|IMAGE_MASK); - atomKK->modified(Device,X_MASK|V_MASK|IMAGE_MASK); if (xperiodic || yperiodic || zperiodic) { if (deform_vremap) { @@ -385,8 +384,9 @@ void DomainKokkos::pbc() Kokkos::parallel_for(nlocal,f); } } - LMPDeviceType::fence(); + + atomKK->modified(Device,X_MASK|V_MASK|IMAGE_MASK); } /* ---------------------------------------------------------------------- diff --git a/src/KOKKOS/verlet_kokkos.cpp b/src/KOKKOS/verlet_kokkos.cpp index 20c4035276..53b4042376 100644 --- a/src/KOKKOS/verlet_kokkos.cpp +++ b/src/KOKKOS/verlet_kokkos.cpp @@ -170,7 +170,7 @@ void VerletKokkos::setup() modify->setup(vflag); output->setup(); - lmp->kokkos->auto_sync = 0; + lmp->kokkos->auto_sync = 1; update->setupflag = 1; } From 521f3df3d5939fe2d61b3fb9f2e756200822ba6e Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Thu, 19 Jan 2017 16:54:50 -0700 Subject: [PATCH 098/439] Initialize variables in pair_exp6_rx_kokkos --- src/KOKKOS/pair_exp6_rx_kokkos.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/KOKKOS/pair_exp6_rx_kokkos.cpp b/src/KOKKOS/pair_exp6_rx_kokkos.cpp index acba9e473b..dd3228efc4 100644 --- a/src/KOKKOS/pair_exp6_rx_kokkos.cpp +++ b/src/KOKKOS/pair_exp6_rx_kokkos.cpp @@ -311,6 +311,9 @@ void PairExp6rxKokkos::operator()(TagPairExp6rxCompute Date: Tue, 24 Jan 2017 11:24:47 -0700 Subject: [PATCH 099/439] Fixing GPU memory issue in fix_eos_table_rx_kokkos --- src/KOKKOS/fix_eos_table_rx_kokkos.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/KOKKOS/fix_eos_table_rx_kokkos.cpp b/src/KOKKOS/fix_eos_table_rx_kokkos.cpp index 40b44d6744..38222e6dd7 100644 --- a/src/KOKKOS/fix_eos_table_rx_kokkos.cpp +++ b/src/KOKKOS/fix_eos_table_rx_kokkos.cpp @@ -45,6 +45,8 @@ template FixEOStableRXKokkos::FixEOStableRXKokkos(LAMMPS *lmp, int narg, char **arg) : FixEOStableRX(lmp, narg, arg) { + int kokkosable = 1; + atomKK = (AtomKokkos *) atom; execution_space = ExecutionSpaceFromDevice::space; datamask_read = EMPTY_MASK; @@ -181,7 +183,7 @@ void FixEOStableRXKokkos::init() } else { atomKK->sync(execution_space,MASK_MASK | UCOND_MASK | UMECH_MASK | UCHEM_MASK | DPDTHETA_MASK | DVECTOR_MASK); Kokkos::parallel_for(Kokkos::RangePolicy(0,nlocal),*this); - atomKK->modified(execution_space,UCOND_MASK | UMECH_MASK | UCHEM_MASK | DPDTHETA_MASK); + atomKK->modified(execution_space,UCOND_MASK | UMECH_MASK | UCHEM_MASK); } error_check(); @@ -223,9 +225,8 @@ void FixEOStableRXKokkos::post_integrate() dvector = atomKK->k_dvector.view(); atomKK->sync(execution_space,MASK_MASK | UCOND_MASK | UMECH_MASK | UCHEM_MASK | DPDTHETA_MASK | DVECTOR_MASK); - atomKK->modified(execution_space,DPDTHETA_MASK); - Kokkos::parallel_for(Kokkos::RangePolicy(0,nlocal),*this); + atomKK->modified(execution_space,DPDTHETA_MASK); error_check(); From 8e808f6c6b861cd46329b3c4d58e97631661896d Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 24 Jan 2017 11:45:27 -0700 Subject: [PATCH 100/439] Zeroing variables in pair_exp6_rx_kokkos to match pull request --- src/KOKKOS/pair_exp6_rx_kokkos.cpp | 66 ++++++++++++++++-------------- 1 file changed, 35 insertions(+), 31 deletions(-) diff --git a/src/KOKKOS/pair_exp6_rx_kokkos.cpp b/src/KOKKOS/pair_exp6_rx_kokkos.cpp index dd3228efc4..23c217ef6e 100644 --- a/src/KOKKOS/pair_exp6_rx_kokkos.cpp +++ b/src/KOKKOS/pair_exp6_rx_kokkos.cpp @@ -311,9 +311,6 @@ void PairExp6rxKokkos::operator()(TagPairExp6rxCompute::operator()(TagPairExp6rxCompute::operator()(TagPairExp6rxComputetemplate ev_tally(ev,i,j,evdwl,fpair,delx,dely,delz); } + + // + // Apply Mixing Rule to get the overall force for the CG pair + // + if (isite1 == isite2) fpair = sqrt(mixWtSite1old_i*mixWtSite2old_j)*fpairOldEXP6_12; + else fpair = sqrt(mixWtSite1old_i*mixWtSite2old_j)*fpairOldEXP6_12 + sqrt(mixWtSite2old_i*mixWtSite1old_j)*fpairOldEXP6_21; + + fx_i += delx*fpair; + fy_i += dely*fpair; + fz_i += delz*fpair; + if (NEWTON_PAIR || j < nlocal) { + a_f(j,0) -= delx*fpair; + a_f(j,1) -= dely*fpair; + a_f(j,2) -= delz*fpair; + } + + if (isite1 == isite2) evdwl = sqrt(mixWtSite1_i*mixWtSite2_j)*evdwlEXP6_12; + else evdwl = sqrt(mixWtSite1_i*mixWtSite2_j)*evdwlEXP6_12 + sqrt(mixWtSite2_i*mixWtSite1_j)*evdwlEXP6_21; + evdwl *= factor_lj; + + uCGnew_i += 0.5*evdwl; + if (NEWTON_PAIR || j < nlocal) + a_uCGnew[j] += 0.5*evdwl; + evdwl = evdwlOld; + if (EVFLAG) + ev.evdwl += ((NEWTON_PAIR||(jtemplate ev_tally(ev,i,j,evdwl,fpair,delx,dely,delz); } } From c617bc180afd1295fd49ffa71fdf779e8bf67603 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Thu, 26 Jan 2017 08:52:17 -0700 Subject: [PATCH 101/439] Adding sync/modify to pair_multi_lucy_rx_kokkos --- src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp b/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp index fac1478e32..8399fccc64 100644 --- a/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp +++ b/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp @@ -183,8 +183,6 @@ void PairMultiLucyRXKokkos::compute_style(int eflag_in, int vflag_in dvector = atomKK->k_dvector.view(); atomKK->sync(execution_space,X_MASK | F_MASK | TYPE_MASK | ENERGY_MASK | VIRIAL_MASK | DPDRHO_MASK | UCG_MASK | UCGNEW_MASK | DVECTOR_MASK); - if (evflag) atomKK->modified(execution_space,F_MASK | ENERGY_MASK | VIRIAL_MASK | UCG_MASK | UCGNEW_MASK); - else atomKK->modified(execution_space,F_MASK | UCG_MASK | UCGNEW_MASK); k_cutsq.template sync(); nlocal = atom->nlocal; @@ -231,6 +229,9 @@ void PairMultiLucyRXKokkos::compute_style(int eflag_in, int vflag_in } } + if (evflag) atomKK->modified(execution_space,F_MASK | ENERGY_MASK | VIRIAL_MASK | UCG_MASK | UCGNEW_MASK); + else atomKK->modified(execution_space,F_MASK | UCG_MASK | UCGNEW_MASK); + k_error_flag.template modify(); k_error_flag.template sync(); if (k_error_flag.h_view() == 1) @@ -454,7 +455,6 @@ void PairMultiLucyRXKokkos::computeLocalDensity() nlocal = atom->nlocal; atomKK->sync(execution_space,X_MASK | TYPE_MASK | DPDRHO_MASK); - atomKK->modified(execution_space,DPDRHO_MASK); const int inum = list->inum; NeighListKokkos* k_list = static_cast*>(list); @@ -492,14 +492,14 @@ void PairMultiLucyRXKokkos::computeLocalDensity() Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); } + atomKK->modified(execution_space,DPDRHO_MASK); + // communicate and sum densities (on the host) if (newton_pair) { - atomKK->modified(execution_space,DPDRHO_MASK); atomKK->sync(Host,DPDRHO_MASK); comm->reverse_comm_pair(this); atomKK->modified(Host,DPDRHO_MASK); - atomKK->sync(execution_space,DPDRHO_MASK); } comm->forward_comm_pair(this); @@ -687,6 +687,8 @@ int PairMultiLucyRXKokkos::pack_forward_comm(int n, int *list, doubl { int i,j,m; + atomKK->sync(Host,DPDRHO_MASK); + m = 0; for (i = 0; i < n; i++) { j = list[i]; @@ -705,6 +707,8 @@ void PairMultiLucyRXKokkos::unpack_forward_comm(int n, int first, do m = 0; last = first + n; for (i = first; i < last; i++) h_rho[i] = buf[m++]; + + atomKK->modified(Host,DPDRHO_MASK); } /* ---------------------------------------------------------------------- */ From 8050eb3aa85c95fd55433208f185ff7f9bc74e02 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Thu, 26 Jan 2017 09:17:59 -0700 Subject: [PATCH 102/439] Another tweak to sync/modify in pair_multi_lucy_rx_kokkos --- src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp b/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp index 8399fccc64..2e6d48227f 100644 --- a/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp +++ b/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp @@ -496,11 +496,8 @@ void PairMultiLucyRXKokkos::computeLocalDensity() // communicate and sum densities (on the host) - if (newton_pair) { - atomKK->sync(Host,DPDRHO_MASK); + if (newton_pair) comm->reverse_comm_pair(this); - atomKK->modified(Host,DPDRHO_MASK); - } comm->forward_comm_pair(this); } @@ -648,6 +645,8 @@ template int PairMultiLucyRXKokkos::pack_forward_comm_kokkos(int n, DAT::tdual_int_2d k_sendlist, int iswap_in, DAT::tdual_xfloat_1d &buf, int pbc_flag, int *pbc) { + atomKK->sync(execution_space,DPDRHO_MASK); + d_sendlist = k_sendlist.view(); iswap = iswap_in; v_buf = buf.view(); @@ -672,6 +671,8 @@ void PairMultiLucyRXKokkos::unpack_forward_comm_kokkos(int n, int fi v_buf = buf.view(); Kokkos::parallel_for(Kokkos::RangePolicy(0,n),*this); DeviceType::fence(); + + atomKK->modified(execution_space,DPDRHO_MASK); } template @@ -718,6 +719,8 @@ int PairMultiLucyRXKokkos::pack_reverse_comm(int n, int first, doubl { int i,m,last; + atomKK->sync(Host,DPDRHO_MASK); + m = 0; last = first + n; for (i = first; i < last; i++) buf[m++] = h_rho[i]; @@ -736,6 +739,8 @@ void PairMultiLucyRXKokkos::unpack_reverse_comm(int n, int *list, do j = list[i]; h_rho[j] += buf[m++]; } + + atomKK->modified(Host,DPDRHO_MASK); } /* ---------------------------------------------------------------------- */ From 6cc969db9282e5712ce659b951615b14366a7e78 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Thu, 26 Jan 2017 09:24:13 -0700 Subject: [PATCH 103/439] Fixing warnings in Kokkos --- src/KOKKOS/fix_eos_table_rx_kokkos.cpp | 2 +- src/KOKKOS/rand_pool_wrap_kokkos.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/KOKKOS/fix_eos_table_rx_kokkos.cpp b/src/KOKKOS/fix_eos_table_rx_kokkos.cpp index 38222e6dd7..8487fd4c4f 100644 --- a/src/KOKKOS/fix_eos_table_rx_kokkos.cpp +++ b/src/KOKKOS/fix_eos_table_rx_kokkos.cpp @@ -45,7 +45,7 @@ template FixEOStableRXKokkos::FixEOStableRXKokkos(LAMMPS *lmp, int narg, char **arg) : FixEOStableRX(lmp, narg, arg) { - int kokkosable = 1; + kokkosable = 1; atomKK = (AtomKokkos *) atom; execution_space = ExecutionSpaceFromDevice::space; diff --git a/src/KOKKOS/rand_pool_wrap_kokkos.h b/src/KOKKOS/rand_pool_wrap_kokkos.h index 349896ee9a..ce134e5215 100644 --- a/src/KOKKOS/rand_pool_wrap_kokkos.h +++ b/src/KOKKOS/rand_pool_wrap_kokkos.h @@ -24,6 +24,7 @@ namespace LAMMPS_NS { struct RandWrap { class RanMars* rng; + KOKKOS_INLINE_FUNCTION RandWrap() { rng = NULL; } From be13ecfa17cf837b0b1b4a69f8b0e733b9c5dae3 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Thu, 26 Jan 2017 10:03:43 -0700 Subject: [PATCH 104/439] Fixing Kokkos warnings --- src/KOKKOS/pair_dpd_fdt_energy_kokkos.h | 2 ++ src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp | 13 +------------ 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/src/KOKKOS/pair_dpd_fdt_energy_kokkos.h b/src/KOKKOS/pair_dpd_fdt_energy_kokkos.h index 2c2b78ac57..7d1749eb94 100644 --- a/src/KOKKOS/pair_dpd_fdt_energy_kokkos.h +++ b/src/KOKKOS/pair_dpd_fdt_energy_kokkos.h @@ -80,7 +80,9 @@ class PairDPDfdtEnergyKokkos : public PairDPDfdtEnergy { int sbmask(const int& j) const; struct params_dpd { + KOKKOS_INLINE_FUNCTION params_dpd(){cut=0;a0=0;sigma=0;kappa=0;}; + KOKKOS_INLINE_FUNCTION params_dpd(int i){cut=0;a0=0;sigma=0;kappa=0;}; F_FLOAT cut,a0,sigma,kappa; }; diff --git a/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp b/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp index 2e6d48227f..30b49a8e8d 100644 --- a/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp +++ b/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp @@ -54,17 +54,6 @@ enum{NONE,RLINEAR,RSQ}; #define oneFluidParameter (-1) #define isOneFluid(_site) ( (_site) == oneFluidParameter ) -static const char cite_pair_multi_lucy_rx[] = - "pair_style multi/lucy/rx command:\n\n" - "@Article{Moore16,\n" - " author = {J.D. Moore, B.C. Barnes, S. Izvekov, M. Lisal, M.S. Sellers, D.E. Taylor and J. K. Brennan},\n" - " title = {A coarse-grain force field for RDX: Density dependent and energy conserving},\n" - " journal = {J. Chem. Phys.},\n" - " year = 2016,\n" - " volume = 144\n" - " pages = {104501}\n" - "}\n\n"; - /* ---------------------------------------------------------------------- */ template @@ -278,7 +267,7 @@ void PairMultiLucyRXKokkos::operator()(TagPairMultiLucyRXCompute::value> > a_f = f; - int i,jj,inum,jnum,itype,jtype,itable; + int i,jj,jnum,itype,jtype,itable; double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,evdwlOld,fpair; double rsq; From 85c8db5f86c7becfdb6c2d6831368abebabae0d4 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Thu, 26 Jan 2017 10:09:45 -0700 Subject: [PATCH 105/439] Fixing warning in pair_dpd_fdt_energy_kokkos --- src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp b/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp index ec807a0e08..84a489bcc3 100644 --- a/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp +++ b/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp @@ -277,7 +277,7 @@ void PairDPDfdtEnergyKokkos::operator()(TagPairDPDfdtEnergyComputeSp // The f array is atomic for Half/Thread neighbor style Kokkos::View::value> > a_f = f; - int i,j,jj,inum,jnum,itype,jtype; + int i,j,jj,jnum,itype,jtype; double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair; double rsq,r,rinv,wd,wr,factor_dpd; From ebe27c65e18645f6aded43a039c8c3af2337afac Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Thu, 26 Jan 2017 10:33:03 -0700 Subject: [PATCH 106/439] Removing duplicate code in pair_exp6_rx_kokkos --- src/KOKKOS/pair_exp6_rx_kokkos.cpp | 4 ++-- src/KOKKOS/pair_exp6_rx_kokkos.h | 18 ------------------ 2 files changed, 2 insertions(+), 20 deletions(-) diff --git a/src/KOKKOS/pair_exp6_rx_kokkos.cpp b/src/KOKKOS/pair_exp6_rx_kokkos.cpp index 23c217ef6e..962dcfd031 100644 --- a/src/KOKKOS/pair_exp6_rx_kokkos.cpp +++ b/src/KOKKOS/pair_exp6_rx_kokkos.cpp @@ -25,7 +25,7 @@ #include "force.h" #include "neigh_list.h" #include "math_const.h" -#include "math_special.h" +#include "math_special_kokkos.h" #include "memory.h" #include "error.h" #include "modify.h" @@ -36,7 +36,7 @@ using namespace LAMMPS_NS; using namespace MathConst; -using namespace MathSpecial; +using namespace MathSpecialKokkos; #define MAXLINE 1024 #define DELTA 4 diff --git a/src/KOKKOS/pair_exp6_rx_kokkos.h b/src/KOKKOS/pair_exp6_rx_kokkos.h index 1f2172471b..488c9d0039 100644 --- a/src/KOKKOS/pair_exp6_rx_kokkos.h +++ b/src/KOKKOS/pair_exp6_rx_kokkos.h @@ -150,24 +150,6 @@ class PairExp6rxKokkos : public PairExp6rx { friend void pair_virial_fdotr_compute(PairExp6rxKokkos*); }; - -// optimized version of pow(x,n) with n being integer -// up to 10x faster than pow(x,y) - -KOKKOS_INLINE_FUNCTION -static double powint(const double &x, const int n) { - double yy,ww; - - if (x == 0.0) return 0.0; - int nn = (n > 0) ? n : -n; - ww = x; - - for (yy = 1.0; nn != 0; nn >>= 1, ww *=ww) - if (nn & 1) yy *= ww; - - return (n > 0) ? yy : 1.0/yy; -}; - } #endif From a1f4551ac20e6660d7903f779ad67b4e56d7069d Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 27 Jan 2017 10:18:41 -0700 Subject: [PATCH 107/439] Adding missing sync/modified in atom_vec_dpd_kokkos --- src/KOKKOS/atom_vec_dpd_kokkos.cpp | 101 ++++++++++++++++++++++++----- 1 file changed, 83 insertions(+), 18 deletions(-) diff --git a/src/KOKKOS/atom_vec_dpd_kokkos.cpp b/src/KOKKOS/atom_vec_dpd_kokkos.cpp index 699ea61c9d..820f11c215 100644 --- a/src/KOKKOS/atom_vec_dpd_kokkos.cpp +++ b/src/KOKKOS/atom_vec_dpd_kokkos.cpp @@ -156,6 +156,10 @@ void AtomVecDPDKokkos::grow_reset() void AtomVecDPDKokkos::copy(int i, int j, int delflag) { + sync(Host,X_MASK | V_MASK | TAG_MASK | TYPE_MASK | + MASK_MASK | IMAGE_MASK | DPDTHETA_MASK | + UCOND_MASK | UMECH_MASK | UCHEM_MASK | DVECTOR_MASK); + h_tag[j] = h_tag[i]; h_type[j] = h_type[i]; mask[j] = mask[i]; @@ -176,6 +180,10 @@ void AtomVecDPDKokkos::copy(int i, int j, int delflag) if (atom->nextra_grow) for (int iextra = 0; iextra < atom->nextra_grow; iextra++) modify->fix[atom->extra_grow[iextra]]->copy_arrays(i,j,delflag); + + modified(Host,X_MASK | V_MASK | TAG_MASK | TYPE_MASK | + MASK_MASK | IMAGE_MASK | DPDTHETA_MASK | + UCOND_MASK | UMECH_MASK | UCHEM_MASK | DVECTOR_MASK); } /* ---------------------------------------------------------------------- */ @@ -546,6 +554,8 @@ int AtomVecDPDKokkos::pack_comm(int n, int *list, double *buf, int i,j,m; double dx,dy,dz; + sync(Host,X_MASK|DPDTHETA_MASK|UCOND_MASK|UMECH_MASK|UCHEM_MASK); + m = 0; if (pbc_flag == 0) { for (i = 0; i < n; i++) { @@ -590,6 +600,8 @@ int AtomVecDPDKokkos::pack_comm_vel(int n, int *list, double *buf, int i,j,m; double dx,dy,dz,dvx,dvy,dvz; + sync(Host,X_MASK|V_MASK|DPDTHETA_MASK|UCOND_MASK|UMECH_MASK|UCHEM_MASK); + m = 0; if (pbc_flag == 0) { for (i = 0; i < n; i++) { @@ -674,6 +686,8 @@ void AtomVecDPDKokkos::unpack_comm(int n, int first, double *buf) h_uMech[i] = buf[m++]; h_uChem[i] = buf[m++]; } + + modified(Host,X_MASK|DPDTHETA_MASK|UCOND_MASK|UMECH_MASK|UCHEM_MASK); } /* ---------------------------------------------------------------------- */ @@ -696,6 +710,8 @@ void AtomVecDPDKokkos::unpack_comm_vel(int n, int first, double *buf) h_uMech[i] = buf[m++]; h_uChem[i] = buf[m++]; } + + modified(Host,X_MASK|V_MASK|DPDTHETA_MASK|UCOND_MASK|UMECH_MASK|UCHEM_MASK); } /* ---------------------------------------------------------------------- */ @@ -805,6 +821,8 @@ int AtomVecDPDKokkos::pack_border_kokkos(int n, DAT::tdual_int_2d k_sendlist, DA { X_FLOAT dx,dy,dz; + sync(space,ALL_MASK); + if (pbc_flag != 0) { if (domain->triclinic == 0) { dx = pbc[0]*domain->xprd; @@ -864,6 +882,8 @@ int AtomVecDPDKokkos::pack_border(int n, int *list, double *buf, int i,j,m; double dx,dy,dz; + sync(Host,ALL_MASK); + m = 0; if (pbc_flag == 0) { for (i = 0; i < n; i++) { @@ -923,6 +943,8 @@ int AtomVecDPDKokkos::pack_border_vel(int n, int *list, double *buf, int i,j,m; double dx,dy,dz,dvx,dvy,dvz; + sync(Host,ALL_MASK); + m = 0; if (pbc_flag == 0) { for (i = 0; i < n; i++) { @@ -1016,6 +1038,9 @@ int AtomVecDPDKokkos::pack_comm_hybrid(int n, int *list, double *buf) { int i,j,m; + sync(Host,DPDTHETA_MASK | UCOND_MASK | + UMECH_MASK | UCHEM_MASK | UCG_MASK | UCGNEW_MASK); + m = 0; for (i = 0; i < n; i++) { j = list[i]; @@ -1035,6 +1060,9 @@ int AtomVecDPDKokkos::pack_border_hybrid(int n, int *list, double *buf) { int i,j,m; + sync(Host,DPDTHETA_MASK | UCOND_MASK | + UMECH_MASK | UCHEM_MASK | UCG_MASK | UCGNEW_MASK); + m = 0; for (i = 0; i < n; i++) { j = list[i]; @@ -1113,7 +1141,7 @@ void AtomVecDPDKokkos::unpack_border_kokkos(const int &n, const int &first, while (first+n >= nmax) grow(0); modified(space,X_MASK|TAG_MASK|TYPE_MASK|MASK_MASK| DPDTHETA_MASK|UCOND_MASK|UMECH_MASK|UCHEM_MASK| - UCG_MASK|UCGNEW_MASK); + UCG_MASK|UCGNEW_MASK|DVECTOR_MASK); if(space==Host) { struct AtomVecDPDKokkos_UnpackBorder f(buf.view(), h_x,h_tag,h_type,h_mask, @@ -1141,9 +1169,7 @@ void AtomVecDPDKokkos::unpack_border(int n, int first, double *buf) last = first + n; for (i = first; i < last; i++) { if (i == nmax) grow(0); - modified(Host,X_MASK|TAG_MASK|TYPE_MASK|MASK_MASK| - DPDTHETA_MASK|UCOND_MASK|UMECH_MASK|UCHEM_MASK| - UCG_MASK|UCGNEW_MASK); + h_x(i,0) = buf[m++]; h_x(i,1) = buf[m++]; h_x(i,2) = buf[m++]; @@ -1162,6 +1188,10 @@ void AtomVecDPDKokkos::unpack_border(int n, int first, double *buf) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]-> unpack_border(n,first,&buf[m]); + + modified(Host,X_MASK|TAG_MASK|TYPE_MASK|MASK_MASK| + DPDTHETA_MASK|UCOND_MASK|UMECH_MASK|UCHEM_MASK| + UCG_MASK|UCGNEW_MASK|DVECTOR_MASK); } /* ---------------------------------------------------------------------- */ @@ -1174,9 +1204,7 @@ void AtomVecDPDKokkos::unpack_border_vel(int n, int first, double *buf) last = first + n; for (i = first; i < last; i++) { if (i == nmax) grow(0); - modified(Host,X_MASK|V_MASK|TAG_MASK|TYPE_MASK|MASK_MASK| - DPDTHETA_MASK|UCOND_MASK|UMECH_MASK|UCHEM_MASK| - UCG_MASK|UCGNEW_MASK); + h_x(i,0) = buf[m++]; h_x(i,1) = buf[m++]; h_x(i,2) = buf[m++]; @@ -1198,6 +1226,10 @@ void AtomVecDPDKokkos::unpack_border_vel(int n, int first, double *buf) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]-> unpack_border(n,first,&buf[m]); + + modified(Host,X_MASK|V_MASK|TAG_MASK|TYPE_MASK|MASK_MASK| + DPDTHETA_MASK|UCOND_MASK|UMECH_MASK|UCHEM_MASK| + UCG_MASK|UCGNEW_MASK|DVECTOR_MASK); } /* ---------------------------------------------------------------------- */ @@ -1216,6 +1248,10 @@ int AtomVecDPDKokkos::unpack_comm_hybrid(int n, int first, double *buf) h_uCG(i) = buf[m++]; h_uCGnew(i) = buf[m++]; } + + modified(Host,DPDTHETA_MASK | UCOND_MASK | + UMECH_MASK | UCHEM_MASK | UCG_MASK | UCGNEW_MASK); + return m; } @@ -1235,6 +1271,10 @@ int AtomVecDPDKokkos::unpack_border_hybrid(int n, int first, double *buf) h_uCG(i) = buf[m++]; h_uCGnew(i) = buf[m++]; } + + modified(Host,DPDTHETA_MASK | UCOND_MASK | + UMECH_MASK | UCHEM_MASK | UCG_MASK | UCGNEW_MASK); + return m; } @@ -1356,23 +1396,31 @@ int AtomVecDPDKokkos::pack_exchange_kokkos(const int &nsend,DAT::tdual_xfloat_2d int newsize = nsend*17/k_buf.view().dimension_1()+1; k_buf.resize(newsize,k_buf.view().dimension_1()); } + sync(space,X_MASK | V_MASK | TAG_MASK | TYPE_MASK | + MASK_MASK | IMAGE_MASK| DPDTHETA_MASK | UCOND_MASK | + UMECH_MASK | UCHEM_MASK | UCG_MASK | UCGNEW_MASK | + DVECTOR_MASK); if(space == Host) { AtomVecDPDKokkos_PackExchangeFunctor f(atomKK,k_buf,k_sendlist,k_copylist,atom->nlocal,dim,lo,hi); Kokkos::parallel_for(nsend,f); LMPHostType::fence(); - return nsend*17; } else { AtomVecDPDKokkos_PackExchangeFunctor f(atomKK,k_buf,k_sendlist,k_copylist,atom->nlocal,dim,lo,hi); Kokkos::parallel_for(nsend,f); LMPDeviceType::fence(); - return nsend*17; } + return nsend*17; } /* ---------------------------------------------------------------------- */ int AtomVecDPDKokkos::pack_exchange(int i, double *buf) { + sync(Host,X_MASK | V_MASK | TAG_MASK | TYPE_MASK | + MASK_MASK | IMAGE_MASK| DPDTHETA_MASK | UCOND_MASK | + UMECH_MASK | UCHEM_MASK | UCG_MASK | UCGNEW_MASK | + DVECTOR_MASK); + int m = 1; buf[m++] = h_x(i,0); buf[m++] = h_x(i,1); @@ -1475,7 +1523,6 @@ int AtomVecDPDKokkos::unpack_exchange_kokkos(DAT::tdual_xfloat_2d &k_buf,int nre AtomVecDPDKokkos_UnpackExchangeFunctor f(atomKK,k_buf,k_count,dim,lo,hi); Kokkos::parallel_for(nrecv/17,f); LMPHostType::fence(); - return k_count.h_view(0); } else { k_count.h_view(0) = nlocal; k_count.modify(); @@ -1485,9 +1532,14 @@ int AtomVecDPDKokkos::unpack_exchange_kokkos(DAT::tdual_xfloat_2d &k_buf,int nre LMPDeviceType::fence(); k_count.modify(); k_count.sync(); - - return k_count.h_view(0); } + + modified(space,X_MASK | V_MASK | TAG_MASK | TYPE_MASK | + MASK_MASK | IMAGE_MASK| DPDTHETA_MASK | UCOND_MASK | + UMECH_MASK | UCHEM_MASK | UCG_MASK | UCGNEW_MASK | + DVECTOR_MASK); + + return k_count.h_view(0); } /* ---------------------------------------------------------------------- */ @@ -1496,9 +1548,6 @@ int AtomVecDPDKokkos::unpack_exchange(double *buf) { int nlocal = atom->nlocal; if (nlocal == nmax) grow(0); - modified(Host,X_MASK | V_MASK | TAG_MASK | TYPE_MASK | - MASK_MASK | IMAGE_MASK| DPDTHETA_MASK | UCOND_MASK | - UMECH_MASK | UCHEM_MASK | UCG_MASK | UCGNEW_MASK); int m = 1; h_x(nlocal,0) = buf[m++]; @@ -1523,6 +1572,11 @@ int AtomVecDPDKokkos::unpack_exchange(double *buf) m += modify->fix[atom->extra_grow[iextra]]-> unpack_exchange(nlocal,&buf[m]); + modified(Host,X_MASK | V_MASK | TAG_MASK | TYPE_MASK | + MASK_MASK | IMAGE_MASK| DPDTHETA_MASK | UCOND_MASK | + UMECH_MASK | UCHEM_MASK | UCG_MASK | UCGNEW_MASK | + DVECTOR_MASK); + atom->nlocal++; return m; } @@ -1595,9 +1649,6 @@ int AtomVecDPDKokkos::unpack_restart(double *buf) if (atom->nextra_store) memory->grow(atom->extra,nmax,atom->nextra_store,"atom:extra"); } - modified(Host,X_MASK | V_MASK | TAG_MASK | TYPE_MASK | - MASK_MASK | IMAGE_MASK | DPDTHETA_MASK | - UCOND_MASK | UMECH_MASK | UCHEM_MASK | DVECTOR_MASK); int m = 1; h_x(nlocal,0) = buf[m++]; @@ -1621,6 +1672,10 @@ int AtomVecDPDKokkos::unpack_restart(double *buf) for (int i = 0; i < size; i++) extra[nlocal][i] = buf[m++]; } + modified(Host,X_MASK | V_MASK | TAG_MASK | TYPE_MASK | + MASK_MASK | IMAGE_MASK | DPDTHETA_MASK | + UCOND_MASK | UMECH_MASK | UCHEM_MASK | DVECTOR_MASK); + atom->nlocal++; return m; } @@ -1661,6 +1716,10 @@ void AtomVecDPDKokkos::create_atom(int itype, double *coord) h_uCGnew[nlocal] = 0.0; h_duChem[nlocal] = 0.0; + //atomKK->modified(Host,TAG_MASK|TYPE_MASK|DPDTHETA_MASK|X_MASK|IMAGE_MASK| + // MASK_MASK|V_MASK|DPDRHO_MASK|UCOND_MASK|UMECH_MASK| + // UCHEM_MASK|UCG_MASK|UCGNEW_MASK); + atom->nlocal++; } @@ -1716,6 +1775,8 @@ int AtomVecDPDKokkos::data_atom_hybrid(int nlocal, char **values) { h_dpdTheta(nlocal) = atof(values[0]); + atomKK->modified(Host,DPDTHETA_MASK); + return 1; } @@ -1725,6 +1786,8 @@ int AtomVecDPDKokkos::data_atom_hybrid(int nlocal, char **values) void AtomVecDPDKokkos::pack_data(double **buf) { + atomKK->sync(Host,TAG_MASK|TYPE_MASK|DPDTHETA_MASK|X_MASK|IMAGE_MASK); + int nlocal = atom->nlocal; for (int i = 0; i < nlocal; i++) { buf[i][0] = ubuf(h_tag(i)).d; @@ -1745,6 +1808,8 @@ void AtomVecDPDKokkos::pack_data(double **buf) int AtomVecDPDKokkos::pack_data_hybrid(int i, double *buf) { + atomKK->sync(Host,DPDTHETA_MASK); + buf[0] = h_dpdTheta(i); return 1; } From 43d61f313f566b53fd00112b594395a3c40b2145 Mon Sep 17 00:00:00 2001 From: Christopher Stone Date: Sun, 22 Jan 2017 15:03:45 -0500 Subject: [PATCH 108/439] Initial bare-bones port of FixRX to Kokkos. Initial port of USER-DPD/fix_rx.cpp to KOKKOS/fix_rx_kokkos.cpp. Using parallel_reduce(...) but still using host-only data. TODO: 1. Switch to KOKKOS datatypes for sparse-kinetics data; dense is finished. 2. Switch to using KOKKOS data for dvector. 3. Remove dependencies in rhs(...) on atom. Store those consts in UserData{} or as member constants. 4. Port ComputeLocalTemp(...) to Kokkos (needs pairing algorithm). --- src/KOKKOS/fix_rx_kokkos.cpp | 887 +++++++++++++++++++++++++++++++++++ src/KOKKOS/fix_rx_kokkos.h | 124 +++++ 2 files changed, 1011 insertions(+) create mode 100644 src/KOKKOS/fix_rx_kokkos.cpp create mode 100644 src/KOKKOS/fix_rx_kokkos.h diff --git a/src/KOKKOS/fix_rx_kokkos.cpp b/src/KOKKOS/fix_rx_kokkos.cpp new file mode 100644 index 0000000000..f8a10dff93 --- /dev/null +++ b/src/KOKKOS/fix_rx_kokkos.cpp @@ -0,0 +1,887 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include +#include +#include "fix_rx_kokkos.h" +#include "atom_masks.h" +#include "atom_kokkos.h" +#include "force.h" +#include "memory.h" +#include "update.h" +#include "respa.h" +#include "modify.h" +#include "error.h" +#include "math_special.h" + +#include // DBL_EPSILON + +using namespace LAMMPS_NS; +using namespace FixConst; +using namespace MathSpecial; + +#ifdef DBL_EPSILON + #define MY_EPSILON (10.0*DBL_EPSILON) +#else + #define MY_EPSILON (10.0*2.220446049250313e-16) +#endif + +#define SparseKinetics_enableIntegralReactions (true) +#define SparseKinetics_invalidIndex (-1) + +namespace /* anonymous */ +{ + +typedef double TimerType; +TimerType getTimeStamp(void) { return MPI_Wtime(); } +double getElapsedTime( const TimerType &t0, const TimerType &t1) { return t1-t0; } + +} // end namespace + +/* ---------------------------------------------------------------------- */ + +template +FixRxKokkos::FixRxKokkos(LAMMPS *lmp, int narg, char **arg) : + FixRX(lmp, narg, arg), + pairDPDEKK(NULL), + update_kinetics_data(true) +{ + kokkosable = 1; + atomKK = (AtomKokkos *) atom; + execution_space = ExecutionSpaceFromDevice::space; + datamask_read = EMPTY_MASK; + datamask_modify = EMPTY_MASK; + + printf("Inside FixRxKokkos::FixRxKokkos\n"); +} + +template +FixRxKokkos::~FixRxKokkos() +{ + printf("Inside FixRxKokkos::~FixRxKokkos\n"); +} + +/* ---------------------------------------------------------------------- */ + +template +void FixRxKokkos::init() +{ + printf("Inside FixRxKokkos::init\n"); + + // Call the parent's version. + FixRX::init(); + + pairDPDEKK = dynamic_cast(pairDPDE); + if (pairDPDEKK == NULL) + error->all(FLERR,"Must use pair_style dpd/fdt/energy/kk with fix rx/kk"); + + if (update_kinetics_data) + create_kinetics_data(); +} + +/* ---------------------------------------------------------------------- */ + +template +void FixRxKokkos::rk4(const double t_stop, double *y, double *rwork, void* v_params) const +{ + double *k1 = rwork; + double *k2 = k1 + nspecies; + double *k3 = k2 + nspecies; + double *k4 = k3 + nspecies; + double *yp = k4 + nspecies; + + const int numSteps = minSteps; + + const double h = t_stop / double(numSteps); + + // Run the requested steps with h. + for (int step = 0; step < numSteps; step++) + { + // k1 + rhs(0.0,y,k1,v_params); + + // k2 + for (int ispecies = 0; ispecies < nspecies; ispecies++) + yp[ispecies] = y[ispecies] + 0.5*h*k1[ispecies]; + + rhs(0.0,yp,k2,v_params); + + // k3 + for (int ispecies = 0; ispecies < nspecies; ispecies++) + yp[ispecies] = y[ispecies] + 0.5*h*k2[ispecies]; + + rhs(0.0,yp,k3,v_params); + + // k4 + for (int ispecies = 0; ispecies < nspecies; ispecies++) + yp[ispecies] = y[ispecies] + h*k3[ispecies]; + + rhs(0.0,yp,k4,v_params); + + for (int ispecies = 0; ispecies < nspecies; ispecies++) + y[ispecies] += h*(k1[ispecies]/6.0 + k2[ispecies]/3.0 + k3[ispecies]/3.0 + k4[ispecies]/6.0); + + } // end for (int step... + +} + +/* ---------------------------------------------------------------------- */ + +// f1 = dt*f(t,x) +// f2 = dt*f(t+ c20*dt,x + c21*f1) +// f3 = dt*f(t+ c30*dt,x + c31*f1 + c32*f2) +// f4 = dt*f(t+ c40*dt,x + c41*f1 + c42*f2 + c43*f3) +// f5 = dt*f(t+dt,x + c51*f1 + c52*f2 + c53*f3 + c54*f4) +// f6 = dt*f(t+ c60*dt,x + c61*f1 + c62*f2 + c63*f3 + c64*f4 + c65*f5) +// +// fifth-order runge-kutta integration +// x5 = x + b1*f1 + b3*f3 + b4*f4 + b5*f5 + b6*f6 +// fourth-order runge-kutta integration +// x = x + a1*f1 + a3*f3 + a4*f4 + a5*f5 + +template +void FixRxKokkos::rkf45_step (const int neq, const double h, double y[], double y_out[], double rwk[], void* v_param) const +{ + const double c21=0.25; + const double c31=0.09375; + const double c32=0.28125; + const double c41=0.87938097405553; + const double c42=-3.2771961766045; + const double c43=3.3208921256258; + const double c51=2.0324074074074; + const double c52=-8.0; + const double c53=7.1734892787524; + const double c54=-0.20589668615984; + const double c61=-0.2962962962963; + const double c62=2.0; + const double c63=-1.3816764132554; + const double c64=0.45297270955166; + const double c65=-0.275; + const double a1=0.11574074074074; + const double a3=0.54892787524366; + const double a4=0.5353313840156; + const double a5=-0.2; + const double b1=0.11851851851852; + const double b3=0.51898635477583; + const double b4=0.50613149034201; + const double b5=-0.18; + const double b6=0.036363636363636; + + // local dependent variables (5 total) + double* f1 = &rwk[ 0]; + double* f2 = &rwk[ neq]; + double* f3 = &rwk[2*neq]; + double* f4 = &rwk[3*neq]; + double* f5 = &rwk[4*neq]; + double* f6 = &rwk[5*neq]; + + // scratch for the intermediate solution. + //double* ytmp = &rwk[6*neq]; + double* ytmp = y_out; + + // 1) + rhs (0.0, y, f1, v_param); + + for (int k = 0; k < neq; k++){ + f1[k] *= h; + ytmp[k] = y[k] + c21 * f1[k]; + } + + // 2) + rhs(0.0, ytmp, f2, v_param); + + for (int k = 0; k < neq; k++){ + f2[k] *= h; + ytmp[k] = y[k] + c31 * f1[k] + c32 * f2[k]; + } + + // 3) + rhs(0.0, ytmp, f3, v_param); + + for (int k = 0; k < neq; k++) { + f3[k] *= h; + ytmp[k] = y[k] + c41 * f1[k] + c42 * f2[k] + c43 * f3[k]; + } + + // 4) + rhs(0.0, ytmp, f4, v_param); + + for (int k = 0; k < neq; k++) { + f4[k] *= h; + ytmp[k] = y[k] + c51 * f1[k] + c52 * f2[k] + c53 * f3[k] + c54 * f4[k]; + } + + // 5) + rhs(0.0, ytmp, f5, v_param); + + for (int k = 0; k < neq; k++) { + f5[k] *= h; + ytmp[k] = y[k] + c61*f1[k] + c62*f2[k] + c63*f3[k] + c64*f4[k] + c65*f5[k]; + } + + // 6) + rhs(0.0, ytmp, f6, v_param); + + for (int k = 0; k < neq; k++) + { + //const double f6 = h * ydot[k]; + f6[k] *= h; + + // 5th-order solution. + const double r5 = b1*f1[k] + b3*f3[k] + b4*f4[k] + b5*f5[k] + b6*f6[k]; + + // 4th-order solution. + const double r4 = a1*f1[k] + a3*f3[k] + a4*f4[k] + a5*f5[k]; + + // Truncation error: difference between 4th and 5th-order solutions. + rwk[k] = fabs(r5 - r4); + + // Update solution. + //y_out[k] = y[k] + r5; // Local extrapolation + y_out[k] = y[k] + r4; + } + + return; +} + +template +int FixRxKokkos::rkf45_h0 + (const int neq, const double t, const double t_stop, + const double hmin, const double hmax, + double& h0, double y[], double rwk[], void* v_params) const +{ + // Set lower and upper bounds on h0, and take geometric mean as first trial value. + // Exit with this value if the bounds cross each other. + + // Adjust upper bound based on ydot ... + double hg = sqrt(hmin*hmax); + + //if (hmax < hmin) + //{ + // h0 = hg; + // return; + //} + + // Start iteration to find solution to ... {WRMS norm of (h0^2 y'' / 2)} = 1 + + double *ydot = rwk; + double *y1 = ydot + neq; + double *ydot1 = y1 + neq; + + const int max_iters = 10; + bool hnew_is_ok = false; + double hnew = hg; + int iter = 0; + + // compute ydot at t=t0 + rhs (t, y, ydot, v_params); + + while(1) + { + // Estimate y'' with finite-difference ... + + for (int k = 0; k < neq; k++) + y1[k] = y[k] + hg * ydot[k]; + + // compute y' at t1 + rhs (t + hg, y1, ydot1, v_params); + + // Compute WRMS norm of y'' + double yddnrm = 0.0; + for (int k = 0; k < neq; k++){ + double ydd = (ydot1[k] - ydot[k]) / hg; + double wterr = ydd / (relTol * fabs( y[k] ) + absTol); + yddnrm += wterr * wterr; + } + + yddnrm = sqrt( yddnrm / double(neq) ); + + //std::cout << "iter " << _iter << " hg " << hg << " y'' " << yddnrm << std::endl; + //std::cout << "ydot " << ydot[neq-1] << std::endl; + + // should we accept this? + if (hnew_is_ok || iter == max_iters){ + hnew = hg; + if (iter == max_iters) + fprintf(stderr, "ERROR_HIN_MAX_ITERS\n"); + break; + } + + // Get the new value of h ... + hnew = (yddnrm*hmax*hmax > 2.0) ? sqrt(2.0 / yddnrm) : sqrt(hg * hmax); + + // test the stopping conditions. + double hrat = hnew / hg; + + // Accept this value ... the bias factor should bring it within range. + if ( (hrat > 0.5) && (hrat < 2.0) ) + hnew_is_ok = true; + + // If y'' is still bad after a few iterations, just accept h and give up. + if ( (iter > 1) && hrat > 2.0 ) { + hnew = hg; + hnew_is_ok = true; + } + + //printf("iter=%d, yddnrw=%e, hnew=%e, hmin=%e, hmax=%e\n", iter, yddnrm, hnew, hmin, hmax); + + hg = hnew; + iter ++; + } + + // bound and bias estimate + h0 = hnew * 0.5; + h0 = fmax(h0, hmin); + h0 = fmin(h0, hmax); + //printf("h0=%e, hmin=%e, hmax=%e\n", h0, hmin, hmax); + + return (iter + 1); +} + +template +void FixRxKokkos::rkf45(const int neq, const double t_stop, double *y, double *rwork, void *v_param, CounterType& counter) const +{ + // Rounding coefficient. + const double uround = DBL_EPSILON; + + // Adaption limit (shrink or grow) + const double adaption_limit = 4.0; + + // Safety factor on the adaption. very specific but not necessary .. 0.9 is common. + const double hsafe = 0.840896415; + + // Time rounding factor. + const double tround = t_stop * uround; + + // Counters for diagnostics. + int nst = 0; // # of steps (accepted) + int nit = 0; // # of iterations total + int nfe = 0; // # of RHS evaluations + + // Min/Max step-size limits. + const double h_min = 100.0 * tround; + const double h_max = (minSteps > 0) ? t_stop / double(minSteps) : t_stop; + + // Set the initial step-size. 0 forces an internal estimate ... stable Euler step size. + double h = (minSteps > 0) ? t_stop / double(minSteps) : 0.0; + + double t = 0.0; + + if (h < h_min){ + //fprintf(stderr,"hin not implemented yet\n"); + //exit(-1); + nfe = rkf45_h0 (neq, t, t_stop, h_min, h_max, h, y, rwork, v_param); + } + + //printf("t= %e t_stop= %e h= %e\n", t, t_stop, h); + + // Integrate until we reach the end time. + while (fabs(t - t_stop) > tround){ + double *yout = rwork; + double *eout = yout + neq; + + // Take a trial step. + rkf45_step (neq, h, y, yout, eout, v_param); + + // Estimate the solution error. + // ... weighted 2-norm of the error. + double err2 = 0.0; + for (int k = 0; k < neq; k++){ + const double wterr = eout[k] / (relTol * fabs( y[k] ) + absTol); + err2 += wterr * wterr; + } + + double err = fmax( uround, sqrt( err2 / double(nspecies) )); + + // Accept the solution? + if (err <= 1.0 || h <= h_min){ + t += h; + nst++; + + for (int k = 0; k < neq; k++) + y[k] = yout[k]; + } + + // Adjust h for the next step. + double hfac = hsafe * sqrt( sqrt( 1.0 / err ) ); + + // Limit the adaption. + hfac = fmax( hfac, 1.0 / adaption_limit ); + hfac = fmin( hfac, adaption_limit ); + + // Apply the adaption factor... + h *= hfac; + + // Limit h. + h = fmin( h, h_max ); + h = fmax( h, h_min ); + + // Stretch h if we're within 5% ... and we didn't just fail. + if (err <= 1.0 && (t + 1.05*h) > t_stop) + h = t_stop - t; + + // And don't overshoot the end. + if (t + h > t_stop) + h = t_stop - t; + + nit++; + nfe += 6; + + if (maxIters && nit > maxIters){ + //fprintf(stderr,"atom[%d] took too many iterations in rkf45 %d %e %e\n", id, nit, t, t_stop); + counter.nFails ++; + break; + // We should set an error here so that the solution is not used! + } + + } // end while + + counter.nSteps += nst; + counter.nIters += nit; + counter.nFuncs += nfe; + + //printf("id= %d nst= %d nit= %d\n", id, nst, nit); +} + +/* ---------------------------------------------------------------------- */ + +template +int FixRxKokkos::rhs(double t, const double *y, double *dydt, void *params) const +{ + // Use the sparse format instead. + if (useSparseKinetics) + return this->rhs_sparse( t, y, dydt, params); + else + return this->rhs_dense ( t, y, dydt, params); +} + +/* ---------------------------------------------------------------------- */ + +template +int FixRxKokkos::rhs_dense(double t, const double *y, double *dydt, void *params) const +{ + UserRHSData *userData = (UserRHSData *) params; + + double *rxnRateLaw = userData->rxnRateLaw; + double *kFor = userData->kFor; + + const double VDPD = domain->xprd * domain->yprd * domain->zprd / atom->natoms; + const int nspecies = atom->nspecies_dpd; + + for(int ispecies=0; ispecies +int FixRxKokkos::rhs_sparse(double t, const double *y, double *dydt, void *v_params) const +{ + UserRHSData *userData = (UserRHSData *) v_params; + + const double VDPD = domain->xprd * domain->yprd * domain->zprd / atom->natoms; + + #define kFor (userData->kFor) + #define kRev (NULL) + #define rxnRateLaw (userData->rxnRateLaw) + #define conc (dydt) + #define maxReactants (this->sparseKinetics_maxReactants) + #define maxSpecies (this->sparseKinetics_maxSpecies) + #define nuk (this->sparseKinetics_nuk) + #define nu (this->sparseKinetics_nu) + #define inu (this->sparseKinetics_inu) + #define isIntegral(idx) (SparseKinetics_enableIntegralReactions \ + && this->sparseKinetics_isIntegralReaction[idx]) + + for (int k = 0; k < nspecies; ++k) + conc[k] = y[k] / VDPD; + + // Construct the reaction rate laws + for (int i = 0; i < nreactions; ++i) + { + double rxnRateLawForward; + if (isIntegral(i)){ + rxnRateLawForward = kFor[i] * powint( conc[ nuk[i][0] ], inu[i][0]); + for (int kk = 1; kk < maxReactants; ++kk){ + const int k = nuk[i][kk]; + if (k == SparseKinetics_invalidIndex) break; + //if (k != SparseKinetics_invalidIndex) + rxnRateLawForward *= powint( conc[k], inu[i][kk] ); + } + } else { + rxnRateLawForward = kFor[i] * pow( conc[ nuk[i][0] ], nu[i][0]); + for (int kk = 1; kk < maxReactants; ++kk){ + const int k = nuk[i][kk]; + if (k == SparseKinetics_invalidIndex) break; + //if (k != SparseKinetics_invalidIndex) + rxnRateLawForward *= pow( conc[k], nu[i][kk] ); + } + } + + rxnRateLaw[i] = rxnRateLawForward; + } + + // Construct the reaction rates for each species from the + // Stoichiometric matrix and ROP vector. + for (int k = 0; k < nspecies; ++k) + dydt[k] = 0.0; + + for (int i = 0; i < nreactions; ++i){ + // Reactants ... + dydt[ nuk[i][0] ] -= nu[i][0] * rxnRateLaw[i]; + for (int kk = 1; kk < maxReactants; ++kk){ + const int k = nuk[i][kk]; + if (k == SparseKinetics_invalidIndex) break; + //if (k != SparseKinetics_invalidIndex) + dydt[k] -= nu[i][kk] * rxnRateLaw[i]; + } + + // Products ... + dydt[ nuk[i][maxReactants] ] += nu[i][maxReactants] * rxnRateLaw[i]; + for (int kk = maxReactants+1; kk < maxSpecies; ++kk){ + const int k = nuk[i][kk]; + if (k == SparseKinetics_invalidIndex) break; + //if (k != SparseKinetics_invalidIndex) + dydt[k] += nu[i][kk] * rxnRateLaw[i]; + } + } + + // Add in the volume factor to convert to the proper units. + for (int k = 0; k < nspecies; ++k) + dydt[k] *= VDPD; + + #undef kFor + #undef kRev + #undef rxnRateLaw + #undef conc + #undef maxReactants + #undef maxSpecies + #undef nuk + #undef nu + #undef inu + #undef isIntegral + //#undef invalidIndex + + return 0; +} + +/* ---------------------------------------------------------------------- */ + +/*template + template + KOKKOS_INLINE_FUNCTION +void FixRxKokkos::operator()(SolverType, const int &i) const +{ + if (atom->mask[i] & groupbit) + { + double *rwork = new double[8*nspecies]; + + UserRHSData userData; + userData.kFor = new double[nreactions]; + userData.rxnRateLaw = new double[nreactions]; + + int ode_counter[4] = { 0 }; + + const double theta = (localTempFlag) ? dpdThetaLocal[i] : atom->dpdTheta[i]; + + //Compute the reaction rate constants + for (int irxn = 0; irxn < nreactions; irxn++) + { + if (SolverType::setToZero) + userData.kFor[irxn] = 0.0; + else + userData.kFor[irxn] = Arr[irxn]*pow(theta,nArr[irxn])*exp(-Ea[irxn]/force->boltz/theta); + } + + if (odeIntegrationFlag == ODE_LAMMPS_RK4) + rk4(i, rwork, &userData); + else if (odeIntegrationFlag == ODE_LAMMPS_RKF45) + rkf45(i, rwork, &userData, ode_counter); + + delete [] rwork; + delete [] userData.kFor; + delete [] userData.rxnRateLaw; + } +} */ + +/* ---------------------------------------------------------------------- */ + +template +void FixRxKokkos::solve_reactions(void) +{ +/* int nlocal = atom->nlocal; + if (igroup == atom->firstgroup) nlocal = atom->nfirst; + + using AT = ArrayTypes; + + atomKK->sync(execution_space, UCOND_MASK); + typename AT::t_efloat_1d uCond = atomKK->k_uCond.view(); + atomKK->sync(execution_space, UMECH_MASK); + typename AT::t_efloat_1d uMech = atomKK->k_uMech.view(); + + pairDPDEKK->k_duCond.template sync(); + typename AT::t_efloat_1d_const duCond = pairDPDEKK->k_duCond.template view(); + pairDPDEKK->k_duMech.template sync(); + typename AT::t_efloat_1d_const duMech = pairDPDEKK->k_duMech.template view(); + + auto dt = update->dt; + + Kokkos::parallel_for(nlocal, LAMMPS_LAMBDA(int i) { + uCond(i) += 0.5*dt*duCond(i); + uMech(i) += 0.5*dt*duMech(i); + }); + + atomKK->modified(execution_space, UCOND_MASK); + atomKK->modified(execution_space, UMECH_MASK); */ +} + +/* ---------------------------------------------------------------------- */ + +template +void FixRxKokkos::create_kinetics_data(void) +{ + printf("Inside FixRxKokkos::create_kinetics_data\n"); + + memory->create_kokkos( d_kinetics_data.Arr, h_kinetics_data.Arr, nreactions, "KineticsType::Arr"); + memory->create_kokkos( d_kinetics_data.nArr, h_kinetics_data.nArr, nreactions, "KineticsType::nArr"); + memory->create_kokkos( d_kinetics_data.Ea, h_kinetics_data.Ea, nreactions, "KineticsType::Ea"); + + memory->create_kokkos( d_kinetics_data.stoich, h_kinetics_data.stoich, nreactions, nspecies, "KineticsType::stoich"); + memory->create_kokkos( d_kinetics_data.stoichReactants, h_kinetics_data.stoichReactants, nreactions, nspecies, "KineticsType::stoichReactants"); + memory->create_kokkos( d_kinetics_data.stoichProducts, h_kinetics_data.stoichProducts, nreactions, nspecies, "KineticsType::stoichProducts"); + + for (int i = 0; i < nreactions; ++i) + { + h_kinetics_data.Arr[i] = Arr[i]; + h_kinetics_data.nArr[i] = nArr[i]; + h_kinetics_data.Ea[i] = Ea[i]; + + for (int k = 0; k < nspecies; ++k) + { + h_kinetics_data.stoich(i,k) = stoich[i][k]; + h_kinetics_data.stoichReactants(i,k) = stoichReactants[i][k]; + h_kinetics_data.stoichProducts(i,k) = stoichProducts[i][k]; + } + } + + Kokkos::deep_copy( d_kinetics_data.Arr, h_kinetics_data.Arr ); + Kokkos::deep_copy( d_kinetics_data.nArr, h_kinetics_data.nArr ); + Kokkos::deep_copy( d_kinetics_data.Ea, h_kinetics_data.Ea ); + Kokkos::deep_copy( d_kinetics_data.stoich, h_kinetics_data.stoich ); + Kokkos::deep_copy( d_kinetics_data.stoichReactants, h_kinetics_data.stoichReactants ); + Kokkos::deep_copy( d_kinetics_data.stoichProducts, h_kinetics_data.stoichProducts ); + + update_kinetics_data = false; +} + +/* ---------------------------------------------------------------------- */ + +template +void FixRxKokkos::pre_force(int vflag) +{ + printf("Inside FixRxKokkos::pre_force localTempFlag= %d\n", localTempFlag); + + if (update_kinetics_data) + create_kinetics_data(); + + TimerType timer_start = getTimeStamp(); + + int nlocal = atom->nlocal; + int nghost = atom->nghost; + int newton_pair = force->newton_pair; + + const bool setToZero = false; // don't set the forward rates to zero. + + if(localTempFlag){ + int count = nlocal + (newton_pair ? nghost : 0); + dpdThetaLocal = new double[count]; + memset(dpdThetaLocal, 0, sizeof(double)*count); + computeLocalTemperature(); + } + + TimerType timer_localTemperature = getTimeStamp(); + + // Total counters from the ODE solvers. + CounterType Counters; + + // Set data needed in the operators. + int *mask = atom->mask; + double *dpdTheta = atom->dpdTheta; + + const double boltz = force->boltz; + const double t_stop = update->dt; // DPD time-step and integration length. + + /*if (odeIntegrationFlag == ODE_LAMMPS_RKF45 && diagnosticFrequency == 1) + { + memory->create( diagnosticCounterPerODE[StepSum], nlocal, "FixRX::diagnosticCounterPerODE"); + memory->create( diagnosticCounterPerODE[FuncSum], nlocal, "FixRX::diagnosticCounterPerODE"); + }*/ + + Kokkos::parallel_reduce( nlocal, LAMMPS_LAMBDA(int i, CounterType &counter) + { + if (mask[i] & groupbit) + { + double *y = new double[8*nspecies]; + double *rwork = y + nspecies; + + UserRHSData userData; + userData.kFor = new double[nreactions]; + userData.rxnRateLaw = new double[nreactions]; + + CounterType counter_i; + + const double theta = (localTempFlag) ? dpdThetaLocal[i] : dpdTheta[i]; + + //Compute the reaction rate constants + for (int irxn = 0; irxn < nreactions; irxn++) + { + if (setToZero) + userData.kFor[irxn] = 0.0; + else + { + userData.kFor[irxn] = d_kinetics_data.Arr(irxn) * + pow(theta, d_kinetics_data.nArr(irxn)) * + exp(-d_kinetics_data.Ea(irxn) / boltz / theta); + //userData.kFor[irxn] = Arr[irxn]*pow(theta,nArr[irxn])*exp(-Ea[irxn]/boltz/theta); + } + } + + // Update ConcOld and initialize the ODE solution vector y[]. + for (int ispecies = 0; ispecies < nspecies; ispecies++){ + const double tmp = atom->dvector[ispecies][i]; + atom->dvector[ispecies+nspecies][i] = tmp; + y[ispecies] = tmp; + } + + // Solver the ODE system. + if (odeIntegrationFlag == ODE_LAMMPS_RK4) + { + rk4(t_stop, y, rwork, &userData); + + /* This should be a duplicate of the copy-out in the + rkf45 block but for the MY_EPSILON v. -1e-10 (literal) + difference. Can these be merged? */ + + // Store the solution back in atom->dvector. + for (int ispecies = 0; ispecies < nspecies; ispecies++){ + if(y[ispecies] < -MY_EPSILON) + error->one(FLERR,"Computed concentration in RK4 solver is < -10*DBL_EPSILON"); + else if(y[ispecies] < MY_EPSILON) + y[ispecies] = 0.0; + atom->dvector[ispecies][i] = y[ispecies]; + } + } + else if (odeIntegrationFlag == ODE_LAMMPS_RKF45) + { + rkf45(nspecies, t_stop, y, rwork, &userData, counter_i); + + // Store the solution back in atom->dvector. + for (int ispecies = 0; ispecies < nspecies; ispecies++){ + if(y[ispecies] < -1.0e-10) + error->one(FLERR,"Computed concentration in RKF45 solver is < -1.0e-10"); + else if(y[ispecies] < MY_EPSILON) + y[ispecies] = 0.0; + atom->dvector[ispecies][i] = y[ispecies]; + } + + //if (diagnosticFrequency == 1 && diagnosticCounterPerODE[StepSum] != NULL) + if (diagnosticCounterPerODE[StepSum] != NULL) + { + diagnosticCounterPerODE[StepSum][i] = counter_i.nSteps; + diagnosticCounterPerODE[FuncSum][i] = counter_i.nFuncs; + } + } + + delete [] y; + delete [] userData.kFor; + delete [] userData.rxnRateLaw; + + counter += counter_i; + } // if + } // parallel_for lambda-body + + , Counters // reduction value + ); + + TimerType timer_ODE = getTimeStamp(); + + // Communicate the updated momenta and velocities to all nodes + comm->forward_comm_fix(this); + if(localTempFlag) delete [] dpdThetaLocal; + + TimerType timer_stop = getTimeStamp(); + + double time_ODE = getElapsedTime(timer_localTemperature, timer_ODE); + + printf("me= %d kokkos total= %g temp= %g ode= %g comm= %g nlocal= %d nfc= %d %d\n", comm->me, + getElapsedTime(timer_start, timer_stop), + getElapsedTime(timer_start, timer_localTemperature), + getElapsedTime(timer_localTemperature, timer_ODE), + getElapsedTime(timer_ODE, timer_stop), nlocal, Counters.nFuncs, Counters.nSteps); + + // Warn the user if a failure was detected in the ODE solver. + if (Counters.nFails > 0){ + char sbuf[128]; + sprintf(sbuf,"in FixRX::pre_force, ODE solver failed for %d atoms.", Counters.nFails); + error->warning(FLERR, sbuf); + } + +/* + // Compute and report ODE diagnostics, if requested. + if (odeIntegrationFlag == ODE_LAMMPS_RKF45 && diagnosticFrequency != 0){ + // Update the counters. + diagnosticCounter[StepSum] += nSteps; + diagnosticCounter[FuncSum] += nFuncs; + diagnosticCounter[TimeSum] += time_ODE; + diagnosticCounter[AtomSum] += nlocal; + diagnosticCounter[numDiagnosticCounters-1] ++; + + if ( (diagnosticFrequency > 0 && + ((update->ntimestep - update->firststep) % diagnosticFrequency) == 0) || + (diagnosticFrequency < 0 && update->ntimestep == update->laststep) ) + this->odeDiagnostics(); + + for (int i = 0; i < numDiagnosticCounters; ++i) + if (diagnosticCounterPerODE[i]) + memory->destroy( diagnosticCounterPerODE[i] ); + } */ +} + +namespace LAMMPS_NS { +template class FixRxKokkos; +#ifdef KOKKOS_HAVE_CUDA +template class FixRxKokkos; +#endif +} diff --git a/src/KOKKOS/fix_rx_kokkos.h b/src/KOKKOS/fix_rx_kokkos.h new file mode 100644 index 0000000000..4a41644257 --- /dev/null +++ b/src/KOKKOS/fix_rx_kokkos.h @@ -0,0 +1,124 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef FIX_CLASS + +FixStyle(rx/kk,FixRxKokkos) +FixStyle(rx/kk/device,FixRxKokkos) +FixStyle(rx/kk/host,FixRxKokkos) + +#else + +#ifndef LMP_FIX_RX_KOKKOS_H +#define LMP_FIX_RX_KOKKOS_H + +#include "fix_rx.h" +#include "pair_dpd_fdt_energy_kokkos.h" +#include "kokkos_type.h" + +namespace LAMMPS_NS { + +template +struct TagFixRxKokkosSolver +{ + enum { setToZero = (_setToZero == true) ? 1 : 0 }; +}; + +template +class FixRxKokkos : public FixRX { + public: + FixRxKokkos(class LAMMPS *, int, char **); + virtual ~FixRxKokkos(); + virtual void init(); + virtual void pre_force(int); + + //template + // KOKKOS_INLINE_FUNCTION + //void operator()(SolverTag, const int&) const; + + struct CounterType + { + int nSteps, nIters, nFuncs, nFails; + + CounterType() : nSteps(0), nIters(0), nFuncs(0), nFails(0) {}; + + KOKKOS_INLINE_FUNCTION + CounterType& operator+=(const CounterType &rhs) + { + nSteps += rhs.nSteps; + nIters += rhs.nIters; + nFuncs += rhs.nFuncs; + nFails += rhs.nFails; + return *this; + } + + KOKKOS_INLINE_FUNCTION + volatile CounterType& operator+=(const volatile CounterType &rhs) volatile + { + nSteps += rhs.nSteps; + nIters += rhs.nIters; + nFuncs += rhs.nFuncs; + nFails += rhs.nFails; + return *this; + } + }; + + protected: + PairDPDfdtEnergyKokkos* pairDPDEKK; + + void solve_reactions(void); + + int rhs(double, const double *, double *, void *) const; + int rhs_dense (double, const double *, double *, void *) const; + int rhs_sparse(double, const double *, double *, void *) const; + + //!< Classic Runge-Kutta 4th-order stepper. + void rk4(const double t_stop, double *y, double *rwork, void *v_params) const; + + //!< Runge-Kutta-Fehlberg ODE Solver. + void rkf45(const int neq, const double t_stop, double *y, double *rwork, void *v_params, CounterType& counter) const; + + //!< Runge-Kutta-Fehlberg ODE stepper function. + void rkf45_step (const int neq, const double h, double y[], double y_out[], + double rwk[], void *) const; + + //!< Initial step size estimation for the Runge-Kutta-Fehlberg ODE solver. + int rkf45_h0 (const int neq, const double t, const double t_stop, + const double hmin, const double hmax, + double& h0, double y[], double rwk[], void *v_params) const; + + template + struct KineticsType + { + typename ArrayTypes::t_float_1d Arr, nArr, Ea; + typename ArrayTypes::t_float_2d stoich, stoichReactants, stoichProducts; + }; + + //!< Kokkos versions of the kinetics data. + KineticsType h_kinetics_data; + KineticsType d_kinetics_data; + + bool update_kinetics_data; + + void create_kinetics_data(void); + +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ From 41d3903f5a7226ef4b30d3fd6b818123354300d9 Mon Sep 17 00:00:00 2001 From: Christopher Stone Date: Sun, 22 Jan 2017 22:49:21 -0500 Subject: [PATCH 109/439] Added kokkos-managed parameters for FixRxKokkos. - Added kokkos-managed parameter data for the kinetics equations. - Removed dependencies in rhs() on atom and domain objects. TODO: 1. Switch to using KOKKOS data for dvector. 2. Port ComputeLocalTemp(...) to Kokkos (needs pairing algorithm). --- src/KOKKOS/fix_rx_kokkos.cpp | 135 +++++++++++++++++++++++------------ src/KOKKOS/fix_rx_kokkos.h | 13 +++- 2 files changed, 101 insertions(+), 47 deletions(-) diff --git a/src/KOKKOS/fix_rx_kokkos.cpp b/src/KOKKOS/fix_rx_kokkos.cpp index f8a10dff93..b989d6b2d4 100644 --- a/src/KOKKOS/fix_rx_kokkos.cpp +++ b/src/KOKKOS/fix_rx_kokkos.cpp @@ -475,8 +475,8 @@ int FixRxKokkos::rhs_dense(double t, const double *y, double *dydt, double *rxnRateLaw = userData->rxnRateLaw; double *kFor = userData->kFor; - const double VDPD = domain->xprd * domain->yprd * domain->zprd / atom->natoms; - const int nspecies = atom->nspecies_dpd; + //const double VDPD = domain->xprd * domain->yprd * domain->zprd / atom->natoms; + //const int nspecies = atom->nspecies_dpd; for(int ispecies=0; ispecies::rhs_dense(double t, const double *y, double *dydt, for(int ispecies=0; ispecies::rhs_dense(double t, const double *y, double *dydt, for(int ispecies=0; ispecies::rhs_sparse(double t, const double *y, double *dydt, { UserRHSData *userData = (UserRHSData *) v_params; - const double VDPD = domain->xprd * domain->yprd * domain->zprd / atom->natoms; + //const double VDPD = domain->xprd * domain->yprd * domain->zprd / atom->natoms; #define kFor (userData->kFor) #define kRev (NULL) @@ -519,11 +519,11 @@ int FixRxKokkos::rhs_sparse(double t, const double *y, double *dydt, #define conc (dydt) #define maxReactants (this->sparseKinetics_maxReactants) #define maxSpecies (this->sparseKinetics_maxSpecies) - #define nuk (this->sparseKinetics_nuk) - #define nu (this->sparseKinetics_nu) - #define inu (this->sparseKinetics_inu) - #define isIntegral(idx) (SparseKinetics_enableIntegralReactions \ - && this->sparseKinetics_isIntegralReaction[idx]) + #define nuk (this->d_kineticsData.nuk) + #define nu (this->d_kineticsData.nu) + #define inu (this->d_kineticsData.inu) + #define isIntegral(idx) ( SparseKinetics_enableIntegralReactions \ + && this->d_kineticsData.isIntegral(idx) ) for (int k = 0; k < nspecies; ++k) conc[k] = y[k] / VDPD; @@ -533,20 +533,20 @@ int FixRxKokkos::rhs_sparse(double t, const double *y, double *dydt, { double rxnRateLawForward; if (isIntegral(i)){ - rxnRateLawForward = kFor[i] * powint( conc[ nuk[i][0] ], inu[i][0]); + rxnRateLawForward = kFor[i] * powint( conc[ nuk(i,0) ], inu(i,0) ); for (int kk = 1; kk < maxReactants; ++kk){ - const int k = nuk[i][kk]; + const int k = nuk(i,kk); if (k == SparseKinetics_invalidIndex) break; //if (k != SparseKinetics_invalidIndex) - rxnRateLawForward *= powint( conc[k], inu[i][kk] ); + rxnRateLawForward *= powint( conc[k], inu(i,kk) ); } } else { - rxnRateLawForward = kFor[i] * pow( conc[ nuk[i][0] ], nu[i][0]); + rxnRateLawForward = kFor[i] * pow( conc[ nuk(i,0) ], nu(i,0) ); for (int kk = 1; kk < maxReactants; ++kk){ - const int k = nuk[i][kk]; + const int k = nuk(i,kk); if (k == SparseKinetics_invalidIndex) break; //if (k != SparseKinetics_invalidIndex) - rxnRateLawForward *= pow( conc[k], nu[i][kk] ); + rxnRateLawForward *= pow( conc[k], nu(i,kk) ); } } @@ -560,21 +560,21 @@ int FixRxKokkos::rhs_sparse(double t, const double *y, double *dydt, for (int i = 0; i < nreactions; ++i){ // Reactants ... - dydt[ nuk[i][0] ] -= nu[i][0] * rxnRateLaw[i]; + dydt[ nuk(i,0) ] -= nu(i,0) * rxnRateLaw[i]; for (int kk = 1; kk < maxReactants; ++kk){ - const int k = nuk[i][kk]; + const int k = nuk(i,kk); if (k == SparseKinetics_invalidIndex) break; //if (k != SparseKinetics_invalidIndex) - dydt[k] -= nu[i][kk] * rxnRateLaw[i]; + dydt[k] -= nu(i,kk) * rxnRateLaw[i]; } // Products ... - dydt[ nuk[i][maxReactants] ] += nu[i][maxReactants] * rxnRateLaw[i]; + dydt[ nuk(i,maxReactants) ] += nu(i,maxReactants) * rxnRateLaw[i]; for (int kk = maxReactants+1; kk < maxSpecies; ++kk){ - const int k = nuk[i][kk]; + const int k = nuk(i,kk); if (k == SparseKinetics_invalidIndex) break; //if (k != SparseKinetics_invalidIndex) - dydt[k] += nu[i][kk] * rxnRateLaw[i]; + dydt[k] += nu(i,kk) * rxnRateLaw[i]; } } @@ -674,34 +674,76 @@ void FixRxKokkos::create_kinetics_data(void) { printf("Inside FixRxKokkos::create_kinetics_data\n"); - memory->create_kokkos( d_kinetics_data.Arr, h_kinetics_data.Arr, nreactions, "KineticsType::Arr"); - memory->create_kokkos( d_kinetics_data.nArr, h_kinetics_data.nArr, nreactions, "KineticsType::nArr"); - memory->create_kokkos( d_kinetics_data.Ea, h_kinetics_data.Ea, nreactions, "KineticsType::Ea"); - - memory->create_kokkos( d_kinetics_data.stoich, h_kinetics_data.stoich, nreactions, nspecies, "KineticsType::stoich"); - memory->create_kokkos( d_kinetics_data.stoichReactants, h_kinetics_data.stoichReactants, nreactions, nspecies, "KineticsType::stoichReactants"); - memory->create_kokkos( d_kinetics_data.stoichProducts, h_kinetics_data.stoichProducts, nreactions, nspecies, "KineticsType::stoichProducts"); + memory->create_kokkos( d_kineticsData.Arr, h_kineticsData.Arr, nreactions, "KineticsType::Arr"); + memory->create_kokkos( d_kineticsData.nArr, h_kineticsData.nArr, nreactions, "KineticsType::nArr"); + memory->create_kokkos( d_kineticsData.Ea, h_kineticsData.Ea, nreactions, "KineticsType::Ea"); for (int i = 0; i < nreactions; ++i) { - h_kinetics_data.Arr[i] = Arr[i]; - h_kinetics_data.nArr[i] = nArr[i]; - h_kinetics_data.Ea[i] = Ea[i]; + h_kineticsData.Arr[i] = Arr[i]; + h_kineticsData.nArr[i] = nArr[i]; + h_kineticsData.Ea[i] = Ea[i]; + } - for (int k = 0; k < nspecies; ++k) + Kokkos::deep_copy( d_kineticsData.Arr, h_kineticsData.Arr ); + Kokkos::deep_copy( d_kineticsData.nArr, h_kineticsData.nArr ); + Kokkos::deep_copy( d_kineticsData.Ea, h_kineticsData.Ea ); + + if (useSparseKinetics) + { + + memory->create_kokkos( d_kineticsData.nu , h_kineticsData.nu , nreactions, sparseKinetics_maxSpecies, "KineticsType::nu"); + memory->create_kokkos( d_kineticsData.nuk, h_kineticsData.nuk, nreactions, sparseKinetics_maxSpecies, "KineticsType::nuk"); + + for (int i = 0; i < nreactions; ++i) + for (int k = 0; k < sparseKinetics_maxSpecies; ++k) + { + h_kineticsData.nu (i,k) = sparseKinetics_nu [i][k]; + h_kineticsData.nuk(i,k) = sparseKinetics_nuk[i][k]; + } + + Kokkos::deep_copy( d_kineticsData.nu, h_kineticsData.nu ); + Kokkos::deep_copy( d_kineticsData.nuk, h_kineticsData.nuk ); + + if (SparseKinetics_enableIntegralReactions) { - h_kinetics_data.stoich(i,k) = stoich[i][k]; - h_kinetics_data.stoichReactants(i,k) = stoichReactants[i][k]; - h_kinetics_data.stoichProducts(i,k) = stoichProducts[i][k]; + memory->create_kokkos( d_kineticsData.inu, h_kineticsData.inu, nreactions, sparseKinetics_maxSpecies, "KineticsType::inu"); + memory->create_kokkos( d_kineticsData.isIntegral, h_kineticsData.isIntegral, nreactions, "KineticsType::isIntegral"); + + for (int i = 0; i < nreactions; ++i) + { + h_kineticsData.isIntegral(i) = sparseKinetics_isIntegralReaction[i]; + + for (int k = 0; k < sparseKinetics_maxSpecies; ++k) + h_kineticsData.inu(i,k) = sparseKinetics_inu[i][k]; + } + + Kokkos::deep_copy( d_kineticsData.inu, h_kineticsData.inu ); + Kokkos::deep_copy( d_kineticsData.isIntegral, h_kineticsData.isIntegral ); } } - Kokkos::deep_copy( d_kinetics_data.Arr, h_kinetics_data.Arr ); - Kokkos::deep_copy( d_kinetics_data.nArr, h_kinetics_data.nArr ); - Kokkos::deep_copy( d_kinetics_data.Ea, h_kinetics_data.Ea ); - Kokkos::deep_copy( d_kinetics_data.stoich, h_kinetics_data.stoich ); - Kokkos::deep_copy( d_kinetics_data.stoichReactants, h_kinetics_data.stoichReactants ); - Kokkos::deep_copy( d_kinetics_data.stoichProducts, h_kinetics_data.stoichProducts ); + //else + //{ + + // Dense option + memory->create_kokkos( d_kineticsData.stoich, h_kineticsData.stoich, nreactions, nspecies, "KineticsType::stoich"); + memory->create_kokkos( d_kineticsData.stoichReactants, h_kineticsData.stoichReactants, nreactions, nspecies, "KineticsType::stoichReactants"); + memory->create_kokkos( d_kineticsData.stoichProducts, h_kineticsData.stoichProducts, nreactions, nspecies, "KineticsType::stoichProducts"); + + for (int i = 0; i < nreactions; ++i) + for (int k = 0; k < nspecies; ++k) + { + h_kineticsData.stoich(i,k) = stoich[i][k]; + h_kineticsData.stoichReactants(i,k) = stoichReactants[i][k]; + h_kineticsData.stoichProducts(i,k) = stoichProducts[i][k]; + } + + Kokkos::deep_copy( d_kineticsData.stoich, h_kineticsData.stoich ); + Kokkos::deep_copy( d_kineticsData.stoichReactants, h_kineticsData.stoichReactants ); + Kokkos::deep_copy( d_kineticsData.stoichProducts, h_kineticsData.stoichProducts ); + + //} update_kinetics_data = false; } @@ -743,6 +785,9 @@ void FixRxKokkos::pre_force(int vflag) const double boltz = force->boltz; const double t_stop = update->dt; // DPD time-step and integration length. + // Average DPD volume. Used in the RHS function. + this->VDPD = domain->xprd * domain->yprd * domain->zprd / atom->natoms; + /*if (odeIntegrationFlag == ODE_LAMMPS_RKF45 && diagnosticFrequency == 1) { memory->create( diagnosticCounterPerODE[StepSum], nlocal, "FixRX::diagnosticCounterPerODE"); @@ -771,9 +816,9 @@ void FixRxKokkos::pre_force(int vflag) userData.kFor[irxn] = 0.0; else { - userData.kFor[irxn] = d_kinetics_data.Arr(irxn) * - pow(theta, d_kinetics_data.nArr(irxn)) * - exp(-d_kinetics_data.Ea(irxn) / boltz / theta); + userData.kFor[irxn] = d_kineticsData.Arr(irxn) * + pow(theta, d_kineticsData.nArr(irxn)) * + exp(-d_kineticsData.Ea(irxn) / boltz / theta); //userData.kFor[irxn] = Arr[irxn]*pow(theta,nArr[irxn])*exp(-Ea[irxn]/boltz/theta); } } diff --git a/src/KOKKOS/fix_rx_kokkos.h b/src/KOKKOS/fix_rx_kokkos.h index 4a41644257..95872c67e9 100644 --- a/src/KOKKOS/fix_rx_kokkos.h +++ b/src/KOKKOS/fix_rx_kokkos.h @@ -75,6 +75,7 @@ class FixRxKokkos : public FixRX { protected: PairDPDfdtEnergyKokkos* pairDPDEKK; + double VDPD; void solve_reactions(void); @@ -100,13 +101,21 @@ class FixRxKokkos : public FixRX { template struct KineticsType { + // Arrhenius rate coefficients. typename ArrayTypes::t_float_1d Arr, nArr, Ea; + + // Dense versions. typename ArrayTypes::t_float_2d stoich, stoichReactants, stoichProducts; + + // Sparse versions. + typename ArrayTypes::t_int_2d nuk, inu; + typename ArrayTypes::t_float_2d nu; + typename ArrayTypes::t_int_1d isIntegral; }; //!< Kokkos versions of the kinetics data. - KineticsType h_kinetics_data; - KineticsType d_kinetics_data; + KineticsType h_kineticsData; + KineticsType d_kineticsData; bool update_kinetics_data; From 70fa9189a8c8d74ac1dc09084c15260aaa204612 Mon Sep 17 00:00:00 2001 From: Christopher Stone Date: Tue, 24 Jan 2017 21:49:16 -0500 Subject: [PATCH 110/439] Updated KOKKOS installer and updated USER-DPD FixRx to match KOKKOS version. - Updated the KOKKOS installer to include the fix_rx_kokkos.[cpp,h]. - Updated the USER-DPD version of fix_rx.[cpp,h] to sync with the Kokkos version. Solves child->parent class dependencies. --- src/KOKKOS/Install.sh | 2 + src/USER-DPD/fix_rx.cpp | 244 +++++++++++++++++++++++++++++----------- src/USER-DPD/fix_rx.h | 23 ++-- 3 files changed, 193 insertions(+), 76 deletions(-) diff --git a/src/KOKKOS/Install.sh b/src/KOKKOS/Install.sh index f53f8624c4..db4fcf8ddc 100644 --- a/src/KOKKOS/Install.sh +++ b/src/KOKKOS/Install.sh @@ -103,6 +103,8 @@ action fix_wall_reflect_kokkos.cpp action fix_wall_reflect_kokkos.h action fix_dpd_energy_kokkos.cpp fix_dpd_energy.cpp action fix_dpd_energy_kokkos.h fix_dpd_energy.h +action fix_rx_kokkos.cpp fix_rx.cpp +action fix_rx_kokkos.h fix_rx.h action gridcomm_kokkos.cpp gridcomm.cpp action gridcomm_kokkos.h gridcomm.h action improper_harmonic_kokkos.cpp improper_harmonic.cpp diff --git a/src/USER-DPD/fix_rx.cpp b/src/USER-DPD/fix_rx.cpp index a55ae78110..28321dbecf 100644 --- a/src/USER-DPD/fix_rx.cpp +++ b/src/USER-DPD/fix_rx.cpp @@ -673,7 +673,17 @@ void FixRX::setup_pre_force(int vflag) if(restartFlag){ restartFlag = 0; - } else { + } + else + { + int ode_counter[4] = {0}; + + UserRHSData userData; + userData.kFor = new double[nreactions]; + userData.rxnRateLaw = new double[nreactions]; + + double *rwork = new double[8*nspecies]; + if(localTempFlag){ int count = nlocal + (newton_pair ? nghost : 0); dpdThetaLocal = new double[count]; @@ -686,22 +696,27 @@ void FixRX::setup_pre_force(int vflag) tmp = atom->dvector[ispecies][id]; atom->dvector[ispecies+nspecies][id] = tmp; } + for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit){ // Set the reaction rate constants to zero: no reactions occur at step 0 for(int irxn=0;irxnforward_comm_fix(this); if(localTempFlag) delete [] dpdThetaLocal; + + delete [] userData.kFor; + delete [] userData.rxnRateLaw; + delete [] rwork; } } @@ -709,12 +724,13 @@ void FixRX::setup_pre_force(int vflag) void FixRX::pre_force(int vflag) { + TimerType timer_start = getTimeStamp(); + int nlocal = atom->nlocal; int nghost = atom->nghost; int *mask = atom->mask; double *dpdTheta = atom->dpdTheta; int newton_pair = force->newton_pair; - double theta; if(localTempFlag){ int count = nlocal + (newton_pair ? nghost : 0); @@ -726,7 +742,10 @@ void FixRX::pre_force(int vflag) TimerType timer_localTemperature = getTimeStamp(); // Zero the counters for the ODE solvers. - this->nSteps = this->nIters = this->nFuncs = this->nFails = 0; + int nSteps = 0; + int nIters = 0; + int nFuncs = 0; + int nFails = 0; if (odeIntegrationFlag == ODE_LAMMPS_RKF45 && diagnosticFrequency == 1) { @@ -734,35 +753,66 @@ void FixRX::pre_force(int vflag) memory->create( diagnosticCounterPerODE[FuncSum], nlocal, "FixRX::diagnosticCounterPerODE"); } - double *rwork = new double[8*nspecies + nreactions]; + #pragma omp parallel \ + reduction(+: nSteps, nIters, nFuncs, nFails ) + { + double *rwork = new double[8*nspecies]; - for (int i = 0; i < nlocal; i++) - if (mask[i] & groupbit){ - if (localTempFlag) - theta = dpdThetaLocal[i]; - else - theta = dpdTheta[i]; + UserRHSData userData; + userData.kFor = new double[nreactions]; + userData.rxnRateLaw = new double[nreactions]; - //Compute the reaction rate constants - for (int irxn = 0; irxn < nreactions; irxn++) - kR[irxn] = Arr[irxn]*pow(theta,nArr[irxn])*exp(-Ea[irxn]/force->boltz/theta); + int ode_counter[4] = { 0 }; - if (odeIntegrationFlag == ODE_LAMMPS_RK4) - rk4(i,rwork); - else if (odeIntegrationFlag == ODE_LAMMPS_RKF45) - rkf45(i,rwork); + #pragma omp for schedule(runtime) + for (int i = 0; i < nlocal; i++) + { + if (mask[i] & groupbit) + { + double theta; + if (localTempFlag) + theta = dpdThetaLocal[i]; + else + theta = dpdTheta[i]; + + //Compute the reaction rate constants + for (int irxn = 0; irxn < nreactions; irxn++) + userData.kFor[irxn] = Arr[irxn]*pow(theta,nArr[irxn])*exp(-Ea[irxn]/force->boltz/theta); + + if (odeIntegrationFlag == ODE_LAMMPS_RK4) + rk4(i, rwork, &userData); + else if (odeIntegrationFlag == ODE_LAMMPS_RKF45) + rkf45(i, rwork, &userData, ode_counter); + } } - TimerType timer_ODE = getTimeStamp(); + nSteps += ode_counter[0]; + nIters += ode_counter[1]; + nFuncs += ode_counter[2]; + nFails += ode_counter[3]; - delete [] rwork; + delete [] rwork; + delete [] userData.kFor; + delete [] userData.rxnRateLaw; + + } // end parallel region + + TimerType timer_ODE = getTimeStamp(); // Communicate the updated momenta and velocities to all nodes comm->forward_comm_fix(this); if(localTempFlag) delete [] dpdThetaLocal; + TimerType timer_stop = getTimeStamp(); + double time_ODE = getElapsedTime(timer_localTemperature, timer_ODE); + printf("me= %d total= %g temp= %g ode= %g comm= %g nlocal= %d nfc= %d %d\n", comm->me, + getElapsedTime(timer_start, timer_stop), + getElapsedTime(timer_start, timer_localTemperature), + getElapsedTime(timer_localTemperature, timer_ODE), + getElapsedTime(timer_ODE, timer_stop), nlocal, nFuncs, nSteps); + // Warn the user if a failure was detected in the ODE solver. if (nFails > 0){ char sbuf[128]; @@ -958,21 +1008,15 @@ void FixRX::setupParams() /* ---------------------------------------------------------------------- */ -void FixRX::rk4(int id, double *rwork) +void FixRX::rk4(int id, double *rwork, void* v_params) { - double *k1 = NULL; - if (rwork == NULL) - k1 = new double[6*nspecies + nreactions]; - else - k1 = rwork; + double *k1 = rwork; double *k2 = k1 + nspecies; double *k3 = k2 + nspecies; double *k4 = k3 + nspecies; double *y = k4 + nspecies; double *yp = y + nspecies; - double *dummyArray = yp + nspecies; // Passed to the rhs function. - const int numSteps = minSteps; const double h = update->dt / double(numSteps); @@ -989,25 +1033,25 @@ void FixRX::rk4(int id, double *rwork) for (int step = 0; step < numSteps; step++) { // k1 - rhs(0.0,y,k1,dummyArray); + rhs(0.0,y,k1,v_params); // k2 for (int ispecies = 0; ispecies < nspecies; ispecies++) yp[ispecies] = y[ispecies] + 0.5*h*k1[ispecies]; - rhs(0.0,yp,k2,dummyArray); + rhs(0.0,yp,k2,v_params); // k3 for (int ispecies = 0; ispecies < nspecies; ispecies++) yp[ispecies] = y[ispecies] + 0.5*h*k2[ispecies]; - rhs(0.0,yp,k3,dummyArray); + rhs(0.0,yp,k3,v_params); // k4 for (int ispecies = 0; ispecies < nspecies; ispecies++) yp[ispecies] = y[ispecies] + h*k3[ispecies]; - rhs(0.0,yp,k4,dummyArray); + rhs(0.0,yp,k4,v_params); for (int ispecies = 0; ispecies < nspecies; ispecies++) y[ispecies] += h*(k1[ispecies]/6.0 + k2[ispecies]/3.0 + k3[ispecies]/3.0 + k4[ispecies]/6.0); @@ -1022,9 +1066,6 @@ void FixRX::rk4(int id, double *rwork) y[ispecies] = 0.0; atom->dvector[ispecies][id] = y[ispecies]; } - - if (rwork == NULL) - delete [] k1; } /* ---------------------------------------------------------------------- */ @@ -1274,6 +1315,78 @@ void FixRX::odeDiagnostics(void) double max_per_proc[numCounters]; double min_per_proc[numCounters]; + if(1) + { + static bool firstStep = true; + + static TimerType oldTimeStamp (-1); + + TimerType now = getTimeStamp(); + + // Query the fix database and look for rx_weight for the balance fix. + int type_flag = -1; + int rx_weight_index = atom->find_custom( "rx_weight", /*0:int, 1:float*/ type_flag ); + + // Compute the average # of neighbors. + double averageNumNeighbors = 0; + { + const int inum = pairDPDE->list->inum; + const int* ilist = pairDPDE->list->ilist; + const int* numneigh = pairDPDE->list->numneigh; + + for (int ii = 0; ii < inum; ++ii) + { + const int i = ilist[ii]; + averageNumNeighbors += numneigh[i]; + } + + averageNumNeighbors /= inum; + } + + printf("me= %d nst= %g nfc= %g time= %g nlocal= %g lmpnst= %g weight_idx= %d 1st= %d aveNeigh= %g\n", comm->me, this->diagnosticCounter[0], this->diagnosticCounter[1], this->diagnosticCounter[2], this->diagnosticCounter[3], this->diagnosticCounter[4], rx_weight_index, firstStep, averageNumNeighbors); + + if (rx_weight_index != -1 && !firstStep && 0) + { + double *rx_weight = atom->dvector[rx_weight_index]; + + const int nlocal = atom->nlocal; + const int *mask = atom->mask; + + if (odeIntegrationFlag == ODE_LAMMPS_RKF45 && diagnosticFrequency == 1) + { + const double total_time = getElapsedTime( oldTimeStamp, now ); + const double fixrx_time = this->diagnosticCounter[TimeSum]; + const double time_ratio = fixrx_time / total_time; + + double tsum = 0.0; + double tmin = 100000, tmax = 0; + for (int i = 0; i < nlocal; ++i) + if (mask[i] & groupbit) + { + double nfunc_ratio = double( diagnosticCounterPerODE[FuncSum][i] ) / diagnosticCounter[FuncSum]; + rx_weight[i] = nfunc_ratio * fixrx_time + (total_time - fixrx_time) / nlocal; + tmin = fmin( tmin, rx_weight[i] ); + tmax = fmax( tmax, rx_weight[i] ); + tsum += rx_weight[i]; + //rx_weight[i] = (double) diagnosticCounterPerODE[FuncSum][i]; + } + + printf("me= %d total= %g fixrx= %g ratio= %g tsum= %g %g %g %g\n", comm->me, total_time, fixrx_time, time_ratio, tsum, (total_time - fixrx_time) / nlocal, tmin, tmax); + } + else + { + error->warning(FLERR, "Dynamic load balancing enabled but per-atom weights not available."); + + for (int i = 0; i < nlocal; ++i) + if (mask[i] & groupbit) + rx_weight[i] = 1.0; + } + } + + firstStep = false; + oldTimeStamp = now; + } + // Compute counters per dpd time-step. for (int i = 0; i < numCounters; ++i){ my_vals[i] = this->diagnosticCounter[i] / nTimes; @@ -1347,7 +1460,7 @@ void FixRX::odeDiagnostics(void) if (screen) fprintf(screen,"%s\n", smesg); \ if (logfile) fprintf(logfile,"%s\n", smesg); } - sprintf(smesg, "FixRX::ODE Diagnostics: # of steps |# of rhs evals| run-time (sec)"); + sprintf(smesg, "FixRX::ODE Diagnostics: # of iters |# of rhs evals| run-time (sec) | # atoms"); print_mesg(smesg); sprintf(smesg, " AVG per ODE : %-12.5g | %-12.5g | %-12.5g", avg_per_atom[0], avg_per_atom[1], avg_per_atom[2]); @@ -1369,7 +1482,7 @@ void FixRX::odeDiagnostics(void) print_mesg(smesg); } - sprintf(smesg, " AVG per Proc : %-12.5g | %-12.5g | %-12.5g", avg_per_proc[0], avg_per_proc[1], avg_per_proc[2]); + sprintf(smesg, " AVG per Proc : %-12.5g | %-12.5g | %-12.5g | %-12.5g", avg_per_proc[StepSum], avg_per_proc[FuncSum], avg_per_proc[TimeSum], avg_per_proc[AtomSum]); print_mesg(smesg); if (comm->nprocs > 1){ @@ -1377,13 +1490,13 @@ void FixRX::odeDiagnostics(void) for (int i = 0; i < numCounters; ++i) rms_per_proc[i] = sqrt( sum_sq[i] / comm->nprocs ); - sprintf(smesg, " RMS per Proc : %-12.5g | %-12.5g | %-12.5g", rms_per_proc[0], rms_per_proc[1], rms_per_proc[2]); + sprintf(smesg, " RMS per Proc : %-12.5g | %-12.5g | %-12.5g | %-12.5g", rms_per_proc[0], rms_per_proc[1], rms_per_proc[2], rms_per_proc[AtomSum]); print_mesg(smesg); - sprintf(smesg, " MAX per Proc : %-12.5g | %-12.5g | %-12.5g", max_per_proc[0], max_per_proc[1], max_per_proc[2]); + sprintf(smesg, " MAX per Proc : %-12.5g | %-12.5g | %-12.5g | %-12.5g", max_per_proc[0], max_per_proc[1], max_per_proc[2], max_per_proc[AtomSum]); print_mesg(smesg); - sprintf(smesg, " MIN per Proc : %-12.5g | %-12.5g | %-12.5g", min_per_proc[0], min_per_proc[1], min_per_proc[2]); + sprintf(smesg, " MIN per Proc : %-12.5g | %-12.5g | %-12.5g | %-12.5g", min_per_proc[0], min_per_proc[1], min_per_proc[2], min_per_proc[AtomSum]); print_mesg(smesg); } @@ -1403,7 +1516,7 @@ void FixRX::odeDiagnostics(void) return; } -void FixRX::rkf45(int id, double *rwork) +void FixRX::rkf45(int id, double *rwork, void *v_param, int ode_counter[]) { // Rounding coefficient. const double uround = DBL_EPSILON; @@ -1412,12 +1525,7 @@ void FixRX::rkf45(int id, double *rwork) const double adaption_limit = 4.0; //double *y = new double[8*nspecies + nreactions]; - double *y = NULL; - if (rwork == NULL) - y = new double[8*nspecies + nreactions]; - else - y = rwork; - double *rhstmp = y + 8*nspecies; + double *y = rwork; const int neq = nspecies; @@ -1454,7 +1562,7 @@ void FixRX::rkf45(int id, double *rwork) if (h < h_min){ //fprintf(stderr,"hin not implemented yet\n"); //exit(-1); - nfe = rkf45_h0 (neq, t, t_stop, h_min, h_max, h, y, y + neq, rhstmp); + nfe = rkf45_h0 (neq, t, t_stop, h_min, h_max, h, y, y + neq, v_param); } //printf("t= %e t_stop= %e h= %e\n", t, t_stop, h); @@ -1465,7 +1573,7 @@ void FixRX::rkf45(int id, double *rwork) double *eout = yout + neq; // Take a trial step. - rkf45_step (neq, h, y, yout, eout, rhstmp); + rkf45_step (neq, h, y, yout, eout, v_param); // Estimate the solution error. // ... weighted 2-norm of the error. @@ -1513,16 +1621,17 @@ void FixRX::rkf45(int id, double *rwork) if (maxIters && nit > maxIters){ //fprintf(stderr,"atom[%d] took too many iterations in rkf45 %d %e %e\n", id, nit, t, t_stop); - nFails ++; + //nFails ++; + ode_counter[3] ++; break; // We should set an error here so that the solution is not used! } } // end while - nSteps += nst; - nIters += nit; - nFuncs += nfe; + ode_counter[0] += nst; + ode_counter[1] += nit; + ode_counter[2] += nfe; //if (diagnosticFrequency == 1 && diagnosticCounterPerODE[StepSum] != NULL) if (diagnosticCounterPerODE[StepSum] != NULL){ @@ -1539,9 +1648,6 @@ void FixRX::rkf45(int id, double *rwork) y[ispecies] = 0.0; atom->dvector[ispecies][id] = y[ispecies]; } - - if (rwork == NULL) - delete [] y; } /* ---------------------------------------------------------------------- */ @@ -1559,21 +1665,23 @@ int FixRX::rhs(double t, const double *y, double *dydt, void *params) int FixRX::rhs_dense(double t, const double *y, double *dydt, void *params) { - double rxnRateLawForward; - double *rxnRateLaw = (double *) params; - double VDPD = domain->xprd * domain->yprd * domain->zprd / atom->natoms; - double concentration; - int nspecies = atom->nspecies_dpd; + UserRHSData *userData = (UserRHSData *) params; + + double *rxnRateLaw = userData->rxnRateLaw; + double *kFor = userData->kFor; + + const double VDPD = domain->xprd * domain->yprd * domain->zprd / atom->natoms; + const int nspecies = atom->nspecies_dpd; for(int ispecies=0; ispeciesxprd * domain->yprd * domain->zprd / atom->natoms; - #define kFor (this->kR) + #define kFor (userData->kFor) #define kRev (NULL) - #define rxnRateLaw (_rxnRateLaw) + #define rxnRateLaw (userData->rxnRateLaw) #define conc (dydt) #define maxReactants (this->sparseKinetics_maxReactants) #define maxSpecies (this->sparseKinetics_maxSpecies) diff --git a/src/USER-DPD/fix_rx.h b/src/USER-DPD/fix_rx.h index c35c9afabf..5e226aec73 100644 --- a/src/USER-DPD/fix_rx.h +++ b/src/USER-DPD/fix_rx.h @@ -66,19 +66,19 @@ class FixRX : public Fix { double *kR; //!< Classic Runge-Kutta 4th-order stepper. - void rk4(int,double*); + void rk4(int, double*, void*); //!< Runge-Kutta-Fehlberg ODE Solver. - void rkf45(int,double*); + void rkf45(int, double*, void*, int ode_counter[]); //!< Runge-Kutta-Fehlberg ODE stepper function. void rkf45_step (const int neq, const double h, double y[], double y_out[], - double rwk[], void* v_param); + double rwk[], void *); //!< Initial step size estimation for the Runge-Kutta-Fehlberg ODE solver. int rkf45_h0 (const int neq, const double t, const double t_stop, const double hmin, const double hmax, - double& h0, double y[], double rwk[], void* v_params); + double& h0, double y[], double rwk[], void *v_params); class PairDPDfdtEnergy *pairDPDE; double *dpdThetaLocal; @@ -90,6 +90,13 @@ class FixRX : public Fix { int rhs(double, const double *, double *, void *); int rhs_dense (double, const double *, double *, void *); + // User-defined data container needed in rhs. + struct UserRHSData + { + double *kFor; + double *rxnRateLaw; + }; + // Sparse stoichiometric matrix storage format and methods. bool useSparseKinetics; //SparseKinetics sparseKinetics; @@ -116,10 +123,10 @@ class FixRX : public Fix { double relTol, absTol; //!< Relative and absolute tolerances for the ODE solver(s). // ODE Diagnostics - int nSteps; //!< # of accepted steps taken over all atoms. - int nIters; //!< # of attemped steps for all atoms. - int nFuncs; //!< # of RHS evaluations for all atoms. - int nFails; //!< # of ODE systems that failed (for some reason). + //int nSteps; //!< # of accepted steps taken over all atoms. + //int nIters; //!< # of attemped steps for all atoms. + //int nFuncs; //!< # of RHS evaluations for all atoms. + //int nFails; //!< # of ODE systems that failed (for some reason). int diagnosticFrequency; //!< Frequency (LMP steps) that run-time diagnostics will be printed to the log. enum { numDiagnosticCounters = 5 }; From 2ea900df007e59905720503adbc4955c5c45b574 Mon Sep 17 00:00:00 2001 From: Christopher Stone Date: Sat, 28 Jan 2017 10:41:16 -0500 Subject: [PATCH 111/439] Updated FixRxKokkos to use kokkos-managed data objects. - Switched to use kokkos dvector, mask, and dpdTheta views from atomKK. --- src/KOKKOS/fix_rx_kokkos.cpp | 54 ++++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 18 deletions(-) diff --git a/src/KOKKOS/fix_rx_kokkos.cpp b/src/KOKKOS/fix_rx_kokkos.cpp index b989d6b2d4..19da344db8 100644 --- a/src/KOKKOS/fix_rx_kokkos.cpp +++ b/src/KOKKOS/fix_rx_kokkos.cpp @@ -760,9 +760,9 @@ void FixRxKokkos::pre_force(int vflag) TimerType timer_start = getTimeStamp(); - int nlocal = atom->nlocal; - int nghost = atom->nghost; - int newton_pair = force->newton_pair; + const int nlocal = atom->nlocal; + const int nghost = atom->nghost; + const int newton_pair = force->newton_pair; const bool setToZero = false; // don't set the forward rates to zero. @@ -776,12 +776,23 @@ void FixRxKokkos::pre_force(int vflag) TimerType timer_localTemperature = getTimeStamp(); // Total counters from the ODE solvers. - CounterType Counters; + CounterType TotalCounters; // Set data needed in the operators. - int *mask = atom->mask; - double *dpdTheta = atom->dpdTheta; + // ... + //int *mask = atom->mask; + //double *dpdTheta = atom->dpdTheta; + + // Local references to the atomKK objects. + typename ArrayTypes::t_efloat_1d d_dpdTheta = atomKK->k_dpdTheta.view(); + typename ArrayTypes::t_float_2d d_dvector = atomKK->k_dvector.view(); + typename ArrayTypes::t_int_1d d_mask = atomKK->k_mask.view(); + + // Get up-to-date data. + atomKK->sync( execution_space, MASK_MASK | DVECTOR_MASK | DPDTHETA_MASK ); + + // Set some constants outside of the parallel_for const double boltz = force->boltz; const double t_stop = update->dt; // DPD time-step and integration length. @@ -796,7 +807,7 @@ void FixRxKokkos::pre_force(int vflag) Kokkos::parallel_reduce( nlocal, LAMMPS_LAMBDA(int i, CounterType &counter) { - if (mask[i] & groupbit) + if (d_mask(i) & groupbit) { double *y = new double[8*nspecies]; double *rwork = y + nspecies; @@ -807,7 +818,7 @@ void FixRxKokkos::pre_force(int vflag) CounterType counter_i; - const double theta = (localTempFlag) ? dpdThetaLocal[i] : dpdTheta[i]; + const double theta = (localTempFlag) ? dpdThetaLocal[i] : d_dpdTheta(i); //Compute the reaction rate constants for (int irxn = 0; irxn < nreactions; irxn++) @@ -819,14 +830,13 @@ void FixRxKokkos::pre_force(int vflag) userData.kFor[irxn] = d_kineticsData.Arr(irxn) * pow(theta, d_kineticsData.nArr(irxn)) * exp(-d_kineticsData.Ea(irxn) / boltz / theta); - //userData.kFor[irxn] = Arr[irxn]*pow(theta,nArr[irxn])*exp(-Ea[irxn]/boltz/theta); } } // Update ConcOld and initialize the ODE solution vector y[]. for (int ispecies = 0; ispecies < nspecies; ispecies++){ - const double tmp = atom->dvector[ispecies][i]; - atom->dvector[ispecies+nspecies][i] = tmp; + const double tmp = d_dvector(ispecies, i); + d_dvector(ispecies+nspecies, i) = tmp; y[ispecies] = tmp; } @@ -845,7 +855,7 @@ void FixRxKokkos::pre_force(int vflag) error->one(FLERR,"Computed concentration in RK4 solver is < -10*DBL_EPSILON"); else if(y[ispecies] < MY_EPSILON) y[ispecies] = 0.0; - atom->dvector[ispecies][i] = y[ispecies]; + d_dvector(ispecies,i) = y[ispecies]; } } else if (odeIntegrationFlag == ODE_LAMMPS_RKF45) @@ -858,7 +868,7 @@ void FixRxKokkos::pre_force(int vflag) error->one(FLERR,"Computed concentration in RKF45 solver is < -1.0e-10"); else if(y[ispecies] < MY_EPSILON) y[ispecies] = 0.0; - atom->dvector[ispecies][i] = y[ispecies]; + d_dvector(ispecies,i) = y[ispecies]; } //if (diagnosticFrequency == 1 && diagnosticCounterPerODE[StepSum] != NULL) @@ -877,13 +887,21 @@ void FixRxKokkos::pre_force(int vflag) } // if } // parallel_for lambda-body - , Counters // reduction value + , TotalCounters // reduction value ); TimerType timer_ODE = getTimeStamp(); - // Communicate the updated momenta and velocities to all nodes + // Signal that dvector has been modified on this execution space. + atomKK->modified( execution_space, DVECTOR_MASK ); + + // Communicate the updated species data to all nodes + atomKK->sync ( Host, DVECTOR_MASK ); + comm->forward_comm_fix(this); + + atomKK->modified ( Host, DVECTOR_MASK ); + if(localTempFlag) delete [] dpdThetaLocal; TimerType timer_stop = getTimeStamp(); @@ -894,12 +912,12 @@ void FixRxKokkos::pre_force(int vflag) getElapsedTime(timer_start, timer_stop), getElapsedTime(timer_start, timer_localTemperature), getElapsedTime(timer_localTemperature, timer_ODE), - getElapsedTime(timer_ODE, timer_stop), nlocal, Counters.nFuncs, Counters.nSteps); + getElapsedTime(timer_ODE, timer_stop), nlocal, TotalCounters.nFuncs, TotalCounters.nSteps); // Warn the user if a failure was detected in the ODE solver. - if (Counters.nFails > 0){ + if (TotalCounters.nFails > 0){ char sbuf[128]; - sprintf(sbuf,"in FixRX::pre_force, ODE solver failed for %d atoms.", Counters.nFails); + sprintf(sbuf,"in FixRX::pre_force, ODE solver failed for %d atoms.", TotalCounters.nFails); error->warning(FLERR, sbuf); } From 843f3a9192564bc863d739636453598f046a8555 Mon Sep 17 00:00:00 2001 From: Christopher Stone Date: Sat, 28 Jan 2017 12:02:49 -0500 Subject: [PATCH 112/439] Updates to FixRxKokkos ... - Added templated computeLocalTemp<>() to FixRxKokkos but still using the original host data pointers. - Updated the copy-back to dvector operation to be the same with RK4 and RKF45 per discussion with J. Larentzos. TODO: - Add kokkos data for computeLocalTemp and parallel_for loop. --- src/KOKKOS/fix_rx_kokkos.cpp | 163 ++++++++++++++++++++++++++++------- src/KOKKOS/fix_rx_kokkos.h | 3 + 2 files changed, 136 insertions(+), 30 deletions(-) diff --git a/src/KOKKOS/fix_rx_kokkos.cpp b/src/KOKKOS/fix_rx_kokkos.cpp index 19da344db8..45af816810 100644 --- a/src/KOKKOS/fix_rx_kokkos.cpp +++ b/src/KOKKOS/fix_rx_kokkos.cpp @@ -39,6 +39,10 @@ using namespace MathSpecial; #define SparseKinetics_enableIntegralReactions (true) #define SparseKinetics_invalidIndex (-1) +// From fix_rx.cpp ... this should be lifted into fix_rx.h or fix_rx_kokkos.h? +enum{NONE,HARMONIC}; +enum{LUCY}; + namespace /* anonymous */ { @@ -770,7 +774,19 @@ void FixRxKokkos::pre_force(int vflag) int count = nlocal + (newton_pair ? nghost : 0); dpdThetaLocal = new double[count]; memset(dpdThetaLocal, 0, sizeof(double)*count); - computeLocalTemperature(); + //FixRx::computeLocalTemperature(); + + // Are there is no other options than wtFlag = (0)LUCY and localTempFlag = NONE : HARMONIC? + if (localTempFlag == HARMONIC) + if (newton_pair) + computeLocalTemperature (); + else + computeLocalTemperature (); + else + if (newton_pair) + computeLocalTemperature (); + else + computeLocalTemperature (); } TimerType timer_localTemperature = getTimeStamp(); @@ -834,7 +850,8 @@ void FixRxKokkos::pre_force(int vflag) } // Update ConcOld and initialize the ODE solution vector y[]. - for (int ispecies = 0; ispecies < nspecies; ispecies++){ + for (int ispecies = 0; ispecies < nspecies; ispecies++) + { const double tmp = d_dvector(ispecies, i); d_dvector(ispecies+nspecies, i) = tmp; y[ispecies] = tmp; @@ -844,50 +861,41 @@ void FixRxKokkos::pre_force(int vflag) if (odeIntegrationFlag == ODE_LAMMPS_RK4) { rk4(t_stop, y, rwork, &userData); - - /* This should be a duplicate of the copy-out in the - rkf45 block but for the MY_EPSILON v. -1e-10 (literal) - difference. Can these be merged? */ - - // Store the solution back in atom->dvector. - for (int ispecies = 0; ispecies < nspecies; ispecies++){ - if(y[ispecies] < -MY_EPSILON) - error->one(FLERR,"Computed concentration in RK4 solver is < -10*DBL_EPSILON"); - else if(y[ispecies] < MY_EPSILON) - y[ispecies] = 0.0; - d_dvector(ispecies,i) = y[ispecies]; - } } else if (odeIntegrationFlag == ODE_LAMMPS_RKF45) { rkf45(nspecies, t_stop, y, rwork, &userData, counter_i); - // Store the solution back in atom->dvector. - for (int ispecies = 0; ispecies < nspecies; ispecies++){ - if(y[ispecies] < -1.0e-10) - error->one(FLERR,"Computed concentration in RKF45 solver is < -1.0e-10"); - else if(y[ispecies] < MY_EPSILON) - y[ispecies] = 0.0; - d_dvector(ispecies,i) = y[ispecies]; - } - //if (diagnosticFrequency == 1 && diagnosticCounterPerODE[StepSum] != NULL) - if (diagnosticCounterPerODE[StepSum] != NULL) - { - diagnosticCounterPerODE[StepSum][i] = counter_i.nSteps; - diagnosticCounterPerODE[FuncSum][i] = counter_i.nFuncs; - } + //if (diagnosticCounterPerODE[StepSum] != NULL) + //{ + // diagnosticCounterPerODE[StepSum][i] = counter_i.nSteps; + // diagnosticCounterPerODE[FuncSum][i] = counter_i.nFuncs; + //} + } + + // Store the solution back in dvector. + for (int ispecies = 0; ispecies < nspecies; ispecies++) + { + if (y[ispecies] < -MY_EPSILON) + error->one(FLERR,"Computed concentration in RK solver is < -10*DBL_EPSILON"); + else if (y[ispecies] < MY_EPSILON) + y[ispecies] = 0.0; + + d_dvector(ispecies,i) = y[ispecies]; } delete [] y; delete [] userData.kFor; delete [] userData.rxnRateLaw; + // Update the iteration statistics counter. Is this unique for each iteration? counter += counter_i; + } // if } // parallel_for lambda-body - , TotalCounters // reduction value + , TotalCounters // reduction value for all iterations. ); TimerType timer_ODE = getTimeStamp(); @@ -942,6 +950,101 @@ void FixRxKokkos::pre_force(int vflag) } */ } +/* ---------------------------------------------------------------------- */ + +template + template +void FixRxKokkos::computeLocalTemperature() +{ + int i,j,ii,jj,inum,jnum,itype,jtype; + double xtmp,ytmp,ztmp,delx,dely,delz; + double rsq; + int *ilist,*jlist,*numneigh,**firstneigh; + + double **x = atom->x; + int *type = atom->type; + int nlocal = atom->nlocal; + int nghost = atom->nghost; + //int newton_pair = force->newton_pair; + + // local temperature variables + double wij=0.0; + double *dpdTheta = atom->dpdTheta; + + // Initialize the local temperature weight array + int sumWeightsCt = nlocal + (IS_NEWTON_PAIR ? nghost : 0); + sumWeights = new double[sumWeightsCt]; + memset(sumWeights, 0, sizeof(double)*sumWeightsCt); + + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // loop over neighbors of my atoms + for (ii = 0; ii < inum; ii++) { + i = ilist[ii]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + itype = type[i]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + j &= NEIGHMASK; + jtype = type[j]; + + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx*delx + dely*dely + delz*delz; + + if (rsq < pairDPDE->cutsq[itype][jtype]) { + double rcut = sqrt(pairDPDE->cutsq[itype][jtype]); + double rij = sqrt(rsq); + double ratio = rij/rcut; + + // Lucy's Weight Function + if (WT_FLAG == LUCY) + { + wij = (1.0+3.0*ratio) * (1.0-ratio)*(1.0-ratio)*(1.0-ratio); + dpdThetaLocal[i] += wij/dpdTheta[j]; + if (IS_NEWTON_PAIR || j < nlocal) + dpdThetaLocal[j] += wij/dpdTheta[i]; + } + + sumWeights[i] += wij; + if (IS_NEWTON_PAIR || j < nlocal) + sumWeights[j] += wij; + } + } + } + if (IS_NEWTON_PAIR) comm->reverse_comm_fix(this); + + // self-interaction for local temperature + for (i = 0; i < nlocal; i++){ + + // Lucy Weight Function + if (WT_FLAG == LUCY) + { + wij = 1.0; + dpdThetaLocal[i] += wij / dpdTheta[i]; + } + sumWeights[i] += wij; + + // Normalized local temperature + dpdThetaLocal[i] = dpdThetaLocal[i] / sumWeights[i]; + + if (LOCAL_TEMP_FLAG == HARMONIC) + dpdThetaLocal[i] = 1.0 / dpdThetaLocal[i]; + + } + + delete [] sumWeights; +} + namespace LAMMPS_NS { template class FixRxKokkos; #ifdef KOKKOS_HAVE_CUDA diff --git a/src/KOKKOS/fix_rx_kokkos.h b/src/KOKKOS/fix_rx_kokkos.h index 95872c67e9..ec9a8fa976 100644 --- a/src/KOKKOS/fix_rx_kokkos.h +++ b/src/KOKKOS/fix_rx_kokkos.h @@ -121,6 +121,9 @@ class FixRxKokkos : public FixRX { void create_kinetics_data(void); + template + void computeLocalTemperature(); + }; } From acba25c3831249f54353f1a0a76b63f42881da6f Mon Sep 17 00:00:00 2001 From: Christopher Stone Date: Sat, 28 Jan 2017 15:58:21 -0500 Subject: [PATCH 113/439] Added kokkos datatypes to FixRxKokkos::computeLocalTemperature(...) Added kokkos dual-view datatypes used in computeLocalTemperature and pre_force (e.g., dpdThetaLocal) but still using the original host pointers for the pack/unpack operations. TODO: - The Kokkos neighbor list is not working. Need to request a Kokkos neighbor list in ::init(). Then, replace objects like list->ilist[] with k_list->d_ilist(). - Add another template parameter for HALFTHREAD and create (automatic) atomic view of dpdThetaLocal and sumWeights. - Add modify/sync comments and replace the host-only pointers in the pack/unpack methods. --- src/KOKKOS/fix_rx_kokkos.cpp | 220 +++++++++++++++++++++++++---------- src/KOKKOS/fix_rx_kokkos.h | 6 +- 2 files changed, 166 insertions(+), 60 deletions(-) diff --git a/src/KOKKOS/fix_rx_kokkos.cpp b/src/KOKKOS/fix_rx_kokkos.cpp index 45af816810..491b32e01d 100644 --- a/src/KOKKOS/fix_rx_kokkos.cpp +++ b/src/KOKKOS/fix_rx_kokkos.cpp @@ -95,6 +95,15 @@ void FixRxKokkos::init() /* ---------------------------------------------------------------------- */ +//template +//void FixRXKokkos::init_list(int, class NeighList* ptr) +//{ +// printf("Inside FixRxKokkos::init_list\n"); +// this->list = ptr; +//} + +/* ---------------------------------------------------------------------- */ + template void FixRxKokkos::rk4(const double t_stop, double *y, double *rwork, void* v_params) const { @@ -770,12 +779,17 @@ void FixRxKokkos::pre_force(int vflag) const bool setToZero = false; // don't set the forward rates to zero. - if(localTempFlag){ - int count = nlocal + (newton_pair ? nghost : 0); - dpdThetaLocal = new double[count]; - memset(dpdThetaLocal, 0, sizeof(double)*count); + if (localTempFlag) + { + const int count = nlocal + (newton_pair ? nghost : 0); + + //dpdThetaLocal = new double[count]; + //memset(dpdThetaLocal, 0, sizeof(double)*count); //FixRx::computeLocalTemperature(); + memory->create_kokkos (k_dpdThetaLocal, dpdThetaLocal, count, "FixRxKokkos::dpdThetaLocal"); + d_dpdThetaLocal = k_dpdThetaLocal.d_view; + // Are there is no other options than wtFlag = (0)LUCY and localTempFlag = NONE : HARMONIC? if (localTempFlag == HARMONIC) if (newton_pair) @@ -802,8 +816,8 @@ void FixRxKokkos::pre_force(int vflag) // Local references to the atomKK objects. typename ArrayTypes::t_efloat_1d d_dpdTheta = atomKK->k_dpdTheta.view(); - typename ArrayTypes::t_float_2d d_dvector = atomKK->k_dvector.view(); - typename ArrayTypes::t_int_1d d_mask = atomKK->k_mask.view(); + typename ArrayTypes::t_float_2d d_dvector = atomKK->k_dvector.view(); + typename ArrayTypes::t_int_1d d_mask = atomKK->k_mask.view(); // Get up-to-date data. atomKK->sync( execution_space, MASK_MASK | DVECTOR_MASK | DPDTHETA_MASK ); @@ -834,7 +848,8 @@ void FixRxKokkos::pre_force(int vflag) CounterType counter_i; - const double theta = (localTempFlag) ? dpdThetaLocal[i] : d_dpdTheta(i); + //const double theta = (localTempFlag) ? dpdThetaLocal[i] : d_dpdTheta(i); + const double theta = (localTempFlag) ? d_dpdThetaLocal(i) : d_dpdTheta(i); //Compute the reaction rate constants for (int irxn = 0; irxn < nreactions; irxn++) @@ -910,7 +925,11 @@ void FixRxKokkos::pre_force(int vflag) atomKK->modified ( Host, DVECTOR_MASK ); - if(localTempFlag) delete [] dpdThetaLocal; + if (localTempFlag) + { + //delete [] dpdThetaLocal; + memory->destroy_kokkos(k_dpdThetaLocal, dpdThetaLocal); + } TimerType timer_stop = getTimeStamp(); @@ -953,96 +972,179 @@ void FixRxKokkos::pre_force(int vflag) /* ---------------------------------------------------------------------- */ template - template + template void FixRxKokkos::computeLocalTemperature() { - int i,j,ii,jj,inum,jnum,itype,jtype; - double xtmp,ytmp,ztmp,delx,dely,delz; - double rsq; - int *ilist,*jlist,*numneigh,**firstneigh; + printf("Inside FixRxKokkos::computeLocalTemperature: %d %d %d %d\n", WT_FLAG, LOCAL_TEMP_FLAG, NEWTON_PAIR, (int)lmp->kokkos->neighflag); - double **x = atom->x; - int *type = atom->type; - int nlocal = atom->nlocal; - int nghost = atom->nghost; - //int newton_pair = force->newton_pair; + //int inum,jnum,itype,jtype; + //double xtmp,ytmp,ztmp,delx,dely,delz; + //double rsq; + //int *ilist,*jlist,*numneigh,**firstneigh; + + //double **x = atom->x; + //int *type = atom->type; + //double *dpdTheta = atom->dpdTheta; + + typename ArrayTypes::t_x_array_randomread d_x = atomKK->k_x.view(); + typename ArrayTypes::t_int_1d_randomread d_type = atomKK->k_type.view(); + typename ArrayTypes::t_efloat_1d d_dpdTheta = atomKK->k_dpdTheta.view(); + + atomKK->sync(execution_space, X_MASK | TYPE_MASK | DPDTHETA_MASK ); + + const int nlocal = atom->nlocal; + const int nghost = atom->nghost; + //const int newton_pair = force->newton_pair; // local temperature variables - double wij=0.0; - double *dpdTheta = atom->dpdTheta; + //double wij=0.0; + + // Pull from pairDPDE. The pairDPDEKK objects are producted so recreate here for now. + //pairDPDEKK->k_cutsq.template sync(); + //typename ArrayTypes::t_ffloat_2d d_cutsq = pairDPDEKK->k_cutsq.template view::tdual_ffloat_2d k_cutsq; + typename ArrayTypes::t_ffloat_2d d_cutsq; + double **h_cutsq; + + { + const int ntypes = atom->ntypes; + + memory->create_kokkos (k_cutsq, h_cutsq, ntypes+1, ntypes+1, "pair:cutsq"); + d_cutsq = k_cutsq.template view(); + + for (int i = 1; i <= ntypes; ++i) + for (int j = i; j <= ntypes; ++j) + { + k_cutsq.h_view(i,j) = pairDPDE->cutsq[i][j]; + k_cutsq.h_view(j,i) = k_cutsq.h_view(i,j); + } + + k_cutsq.template modify(); + k_cutsq.template sync(); + } // Initialize the local temperature weight array - int sumWeightsCt = nlocal + (IS_NEWTON_PAIR ? nghost : 0); - sumWeights = new double[sumWeightsCt]; - memset(sumWeights, 0, sizeof(double)*sumWeightsCt); + int sumWeightsCt = nlocal + (NEWTON_PAIR ? nghost : 0); + //sumWeights = new double[sumWeightsCt]; + //memset(sumWeights, 0, sizeof(double)*sumWeightsCt); - inum = list->inum; - ilist = list->ilist; - numneigh = list->numneigh; - firstneigh = list->firstneigh; + memory->create_kokkos (k_sumWeights, sumWeights, sumWeightsCt, "FixRxKokkos::sumWeights"); + d_sumWeights = k_sumWeights.d_view; + + // Initialize the accumulator to zero ... + Kokkos::parallel_for(nlocal, + LAMMPS_LAMBDA(int i) + { + d_sumWeights(i) = 0.0; + } + ); + + const int inum = list->inum; + + // Local list views. (This isn't working!) + //NeighListKokkos* k_list = static_cast*>(list); + //if (not(list->kokkos)) + //{ + // error->one(FLERR,"list is not a Kokkos list\n"); + //} + + //typename ArrayTypes::t_neighbors_2d d_neighbors = k_list->d_neighbors; + //typename ArrayTypes::t_int_1d d_ilist = k_list->d_ilist; + //typename ArrayTypes::t_int_1d d_numneigh = k_list->d_numneigh; + + int* ilist = list->ilist; + int* numneigh = list->numneigh; + int** firstneigh = list->firstneigh; // loop over neighbors of my atoms - for (ii = 0; ii < inum; ii++) { - i = ilist[ii]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - itype = type[i]; - jlist = firstneigh[i]; - jnum = numneigh[i]; + for (int ii = 0; ii < inum; ii++) + { + const int i = ilist[ii]; + //const int i = d_ilist(ii); + + //const double xtmp = x[i][0]; + //const double ytmp = x[i][1]; + //const double ztmp = x[i][2]; + //const int itype = type[i]; + const double xtmp = d_x(i,0); + const double ytmp = d_x(i,1); + const double ztmp = d_x(i,2); + const int itype = d_type(i); - for (jj = 0; jj < jnum; jj++) { - j = jlist[jj]; - j &= NEIGHMASK; - jtype = type[j]; + int *jlist = firstneigh[i]; + const int jnum = numneigh[i]; + //const int jnum = d_numneigh(i); - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; + for (int jj = 0; jj < jnum; jj++) + { + const int j = (jlist[jj] & NEIGHMASK); + //const int j = (d_neighbors(i,jj) & NEIGHMASK); + //const int jtype = type[j]; + const int jtype = d_type(j); - if (rsq < pairDPDE->cutsq[itype][jtype]) { - double rcut = sqrt(pairDPDE->cutsq[itype][jtype]); + //const double delx = xtmp - x[j][0]; + //const double dely = ytmp - x[j][1]; + //const double delz = ztmp - x[j][2]; + const double delx = xtmp - d_x(j,0); + const double dely = ytmp - d_x(j,1); + const double delz = ztmp - d_x(j,2); + const double rsq = delx*delx + dely*dely + delz*delz; + + const double cutsq_ij = d_cutsq(itype,jtype); + + if (rsq < cutsq_ij) + { + const double rcut = sqrt( cutsq_ij ); double rij = sqrt(rsq); double ratio = rij/rcut; + double wij = 0.0; + // Lucy's Weight Function if (WT_FLAG == LUCY) { wij = (1.0+3.0*ratio) * (1.0-ratio)*(1.0-ratio)*(1.0-ratio); - dpdThetaLocal[i] += wij/dpdTheta[j]; - if (IS_NEWTON_PAIR || j < nlocal) - dpdThetaLocal[j] += wij/dpdTheta[i]; + d_dpdThetaLocal(i) += wij / d_dpdTheta(j); + if (NEWTON_PAIR || j < nlocal) + d_dpdThetaLocal(j) += wij / d_dpdTheta(i); } - sumWeights[i] += wij; - if (IS_NEWTON_PAIR || j < nlocal) - sumWeights[j] += wij; + d_sumWeights(i) += wij; + if (NEWTON_PAIR || j < nlocal) + d_sumWeights(j) += wij; } } } - if (IS_NEWTON_PAIR) comm->reverse_comm_fix(this); + + if (NEWTON_PAIR) comm->reverse_comm_fix(this); // self-interaction for local temperature - for (i = 0; i < nlocal; i++){ + for (int i = 0; i < nlocal; i++) + { + double wij = 0.0; // Lucy Weight Function if (WT_FLAG == LUCY) { wij = 1.0; - dpdThetaLocal[i] += wij / dpdTheta[i]; + d_dpdThetaLocal(i) += wij / d_dpdTheta(i); } - sumWeights[i] += wij; + d_sumWeights(i) += wij; // Normalized local temperature - dpdThetaLocal[i] = dpdThetaLocal[i] / sumWeights[i]; + d_dpdThetaLocal(i) = d_dpdThetaLocal(i) / d_sumWeights(i); if (LOCAL_TEMP_FLAG == HARMONIC) - dpdThetaLocal[i] = 1.0 / dpdThetaLocal[i]; - + d_dpdThetaLocal(i) = 1.0 / d_dpdThetaLocal(i); } - delete [] sumWeights; + // Clean up the local kokkos data. + memory->destroy_kokkos(k_cutsq, h_cutsq); + memory->destroy_kokkos(k_sumWeights, sumWeights); + + //delete [] sumWeights; } namespace LAMMPS_NS { diff --git a/src/KOKKOS/fix_rx_kokkos.h b/src/KOKKOS/fix_rx_kokkos.h index ec9a8fa976..9d60f2b99e 100644 --- a/src/KOKKOS/fix_rx_kokkos.h +++ b/src/KOKKOS/fix_rx_kokkos.h @@ -121,7 +121,11 @@ class FixRxKokkos : public FixRX { void create_kinetics_data(void); - template + // Need a dual-view and device-view for dpdThetaLocal and sumWeights since they're used in several callbacks. + DAT::tdual_efloat_1d k_dpdThetaLocal, k_sumWeights; + typename ArrayTypes::t_efloat_1d d_dpdThetaLocal, d_sumWeights; + + template void computeLocalTemperature(); }; From 0d57a1d831e6a73e55491adb982c44175be4c76f Mon Sep 17 00:00:00 2001 From: Christopher Stone Date: Fri, 3 Feb 2017 16:09:06 -0500 Subject: [PATCH 114/439] Added setup_pre_force, pack/unpack methods to FixRxKokkos. - Added a kokkos version of setup_pre_force that only sets dvector and then communicates that. - Converted all for loops to parallel_for's in computeLocalTemperator() and setup_pre_force. - Added pack/unpack forward/reverse methods with Kokkos host views. TODO: - The Kokkos neighbor list is not working. Need to request a Kokkos neighbor list in ::init(). Then, replace objects like list->ilist[] with k_list->d_ilist(). --- src/KOKKOS/fix_rx_kokkos.cpp | 343 ++++++++++++++++++++++++++--------- src/KOKKOS/fix_rx_kokkos.h | 12 +- 2 files changed, 272 insertions(+), 83 deletions(-) diff --git a/src/KOKKOS/fix_rx_kokkos.cpp b/src/KOKKOS/fix_rx_kokkos.cpp index 491b32e01d..167f2713ea 100644 --- a/src/KOKKOS/fix_rx_kokkos.cpp +++ b/src/KOKKOS/fix_rx_kokkos.cpp @@ -77,6 +77,18 @@ FixRxKokkos::~FixRxKokkos() /* ---------------------------------------------------------------------- */ +template +void FixRxKokkos::post_constructor() +{ + // Run the parents and then reset one value. + FixRX::post_constructor(); + + // Need a copy of this + this->my_restartFlag = modify->fix[modify->nfix-1]->restart_reset; +} + +/* ---------------------------------------------------------------------- */ + template void FixRxKokkos::init() { @@ -763,6 +775,51 @@ void FixRxKokkos::create_kinetics_data(void) /* ---------------------------------------------------------------------- */ +template +void FixRxKokkos::setup_pre_force(int vflag) +{ + printf("Inside FixRxKokkos::setup_pre_force restartFlag= %d\n", my_restartFlag); + + if (my_restartFlag) + my_restartFlag = 0; + else + { + const int nlocal = atom->nlocal; + //const int nghost = atom->nghost; + //const int *mask = atom->mask; + //const int newton_pair = force->newton_pair; + + typename ArrayTypes::t_float_2d d_dvector = atomKK->k_dvector.view(); + + // Get up-to-date data. + atomKK->sync( execution_space, DVECTOR_MASK ); + + // The only net effect from fix_rx.cpp is to set dvector[nspecies:2*nspecies] + // since the reactions are set to zero for step 0. + Kokkos::parallel_for ( nlocal, + LAMMPS_LAMBDA(const int i) + { + for (int ispecies = 0; ispecies < nspecies; ispecies++) + d_dvector(ispecies+nspecies,i) = d_dvector(ispecies,i); + } + ); + + // Signal that dvector has been modified on this execution space. + atomKK->modified( execution_space, DVECTOR_MASK ); + + // Communicate the updated species data to all nodes + atomKK->sync ( Host, DVECTOR_MASK ); + + // Communicate the dvector to all nodes + comm->forward_comm_fix(this); + + // Flag that dvector was updated on the host in the comm. + atomKK->modified ( Host, DVECTOR_MASK ); + } +} + +/* ---------------------------------------------------------------------- */ + template void FixRxKokkos::pre_force(int vflag) { @@ -789,18 +846,31 @@ void FixRxKokkos::pre_force(int vflag) memory->create_kokkos (k_dpdThetaLocal, dpdThetaLocal, count, "FixRxKokkos::dpdThetaLocal"); d_dpdThetaLocal = k_dpdThetaLocal.d_view; + h_dpdThetaLocal = k_dpdThetaLocal.h_view; + + const int neighflag = lmp->kokkos->neighflag; + +#define _template_switch(_wtflag, _localTempFlag) { \ + if (neighflag == HALF) \ + if (newton_pair) \ + computeLocalTemperature<_wtflag, _localTempFlag, true , HALF> (); \ + else \ + computeLocalTemperature<_wtflag, _localTempFlag, false, HALF> (); \ + else if (neighflag == HALFTHREAD) \ + if (newton_pair) \ + computeLocalTemperature<_wtflag, _localTempFlag, true , HALFTHREAD> (); \ + else \ + computeLocalTemperature<_wtflag, _localTempFlag, false, HALFTHREAD> (); \ + } // Are there is no other options than wtFlag = (0)LUCY and localTempFlag = NONE : HARMONIC? - if (localTempFlag == HARMONIC) - if (newton_pair) - computeLocalTemperature (); - else - computeLocalTemperature (); - else - if (newton_pair) - computeLocalTemperature (); - else - computeLocalTemperature (); + if (localTempFlag == HARMONIC) { + _template_switch(LUCY, HARMONIC) + } + else { + _template_switch(LUCY, NONE) + } +#undef _template_switch } TimerType timer_localTemperature = getTimeStamp(); @@ -972,10 +1042,9 @@ void FixRxKokkos::pre_force(int vflag) /* ---------------------------------------------------------------------- */ template - template + template void FixRxKokkos::computeLocalTemperature() { - printf("Inside FixRxKokkos::computeLocalTemperature: %d %d %d %d\n", WT_FLAG, LOCAL_TEMP_FLAG, NEWTON_PAIR, (int)lmp->kokkos->neighflag); //int inum,jnum,itype,jtype; //double xtmp,ytmp,ztmp,delx,dely,delz; @@ -996,10 +1065,12 @@ void FixRxKokkos::computeLocalTemperature() const int nghost = atom->nghost; //const int newton_pair = force->newton_pair; + printf("Inside FixRxKokkos::computeLocalTemperature: %d %d %d %d %d\n", WT_FLAG, LOCAL_TEMP_FLAG, NEWTON_PAIR, (int)lmp->kokkos->neighflag, NEIGHFLAG, nlocal, nghost); + // local temperature variables //double wij=0.0; - // Pull from pairDPDE. The pairDPDEKK objects are producted so recreate here for now. + // Pull from pairDPDE. The pairDPDEKK objects are protected so recreate here for now. //pairDPDEKK->k_cutsq.template sync(); //typename ArrayTypes::t_ffloat_2d d_cutsq = pairDPDEKK->k_cutsq.template view::computeLocalTemperature() memory->create_kokkos (k_sumWeights, sumWeights, sumWeightsCt, "FixRxKokkos::sumWeights"); d_sumWeights = k_sumWeights.d_view; + h_sumWeights = k_sumWeights.h_view; // Initialize the accumulator to zero ... - Kokkos::parallel_for(nlocal, - LAMMPS_LAMBDA(int i) - { - d_sumWeights(i) = 0.0; - } - ); + Kokkos::parallel_for (sumWeightsCt, + LAMMPS_LAMBDA(const int i) + { + d_sumWeights(i) = 0.0; + } + ); const int inum = list->inum; @@ -1059,86 +1131,106 @@ void FixRxKokkos::computeLocalTemperature() int** firstneigh = list->firstneigh; // loop over neighbors of my atoms - for (int ii = 0; ii < inum; ii++) - { - const int i = ilist[ii]; - //const int i = d_ilist(ii); + Kokkos::parallel_for ( inum, + LAMMPS_LAMBDA(const int ii) + { + // Create an atomic view of sumWeights and dpdThetaLocal. Only needed + // for Half/thread scenarios. + typedef Kokkos::View< E_FLOAT*, typename DAT::t_efloat_1d::array_layout, DeviceType, Kokkos::MemoryTraits< AtomicF< NEIGHFLAG >::value> > AtomicViewType; + + AtomicViewType a_dpdThetaLocal = d_dpdThetaLocal; + AtomicViewType a_sumWeights = d_sumWeights; + + // Local scalar accumulators. + double i_dpdThetaLocal = 0.0; + double i_sumWeights = 0.0; + + const int i = ilist[ii]; + //const int i = d_ilist(ii); - //const double xtmp = x[i][0]; - //const double ytmp = x[i][1]; - //const double ztmp = x[i][2]; - //const int itype = type[i]; - const double xtmp = d_x(i,0); - const double ytmp = d_x(i,1); - const double ztmp = d_x(i,2); - const int itype = d_type(i); + const double xtmp = d_x(i,0); + const double ytmp = d_x(i,1); + const double ztmp = d_x(i,2); + const int itype = d_type(i); - int *jlist = firstneigh[i]; - const int jnum = numneigh[i]; - //const int jnum = d_numneigh(i); + int *jlist = firstneigh[i]; + const int jnum = numneigh[i]; + //const int jnum = d_numneigh(i); - for (int jj = 0; jj < jnum; jj++) - { - const int j = (jlist[jj] & NEIGHMASK); - //const int j = (d_neighbors(i,jj) & NEIGHMASK); - //const int jtype = type[j]; - const int jtype = d_type(j); + for (int jj = 0; jj < jnum; jj++) + { + const int j = (jlist[jj] & NEIGHMASK); + //const int j = (d_neighbors(i,jj) & NEIGHMASK); + const int jtype = d_type(j); - //const double delx = xtmp - x[j][0]; - //const double dely = ytmp - x[j][1]; - //const double delz = ztmp - x[j][2]; - const double delx = xtmp - d_x(j,0); - const double dely = ytmp - d_x(j,1); - const double delz = ztmp - d_x(j,2); - const double rsq = delx*delx + dely*dely + delz*delz; + const double delx = xtmp - d_x(j,0); + const double dely = ytmp - d_x(j,1); + const double delz = ztmp - d_x(j,2); + const double rsq = delx*delx + dely*dely + delz*delz; - const double cutsq_ij = d_cutsq(itype,jtype); + const double cutsq_ij = d_cutsq(itype,jtype); - if (rsq < cutsq_ij) - { - const double rcut = sqrt( cutsq_ij ); - double rij = sqrt(rsq); - double ratio = rij/rcut; + if (rsq < cutsq_ij) + { + const double rcut = sqrt( cutsq_ij ); + double rij = sqrt(rsq); + double ratio = rij/rcut; - double wij = 0.0; + double wij = 0.0; - // Lucy's Weight Function - if (WT_FLAG == LUCY) - { - wij = (1.0+3.0*ratio) * (1.0-ratio)*(1.0-ratio)*(1.0-ratio); - d_dpdThetaLocal(i) += wij / d_dpdTheta(j); - if (NEWTON_PAIR || j < nlocal) - d_dpdThetaLocal(j) += wij / d_dpdTheta(i); + // Lucy's Weight Function + if (WT_FLAG == LUCY) + { + wij = (1.0+3.0*ratio) * (1.0-ratio)*(1.0-ratio)*(1.0-ratio); + i_dpdThetaLocal += wij / d_dpdTheta(j); + if (NEWTON_PAIR || j < nlocal) + a_dpdThetaLocal(j) += wij / d_dpdTheta(i); + } + + i_sumWeights += wij; + if (NEWTON_PAIR || j < nlocal) + a_sumWeights(j) += wij; + } + } + + // Update, don't assign, the array value (because another iteration may have hit it). + a_dpdThetaLocal(i) += i_dpdThetaLocal; + a_sumWeights(i) += i_sumWeights; } + ); - d_sumWeights(i) += wij; - if (NEWTON_PAIR || j < nlocal) - d_sumWeights(j) += wij; - } - } - } + // Signal that dpdThetaLocal and sumWeights have been modified. + k_dpdThetaLocal.template modify(); + k_sumWeights. template modify(); + // Communicate the sum dpdTheta and the weights on the host. if (NEWTON_PAIR) comm->reverse_comm_fix(this); + // Update the device view in case they got changed. + k_dpdThetaLocal.template sync(); + k_sumWeights. template sync(); + // self-interaction for local temperature - for (int i = 0; i < nlocal; i++) - { - double wij = 0.0; + Kokkos::parallel_for ( nlocal, + LAMMPS_LAMBDA(const int i) + { + double wij = 0.0; - // Lucy Weight Function - if (WT_FLAG == LUCY) - { - wij = 1.0; - d_dpdThetaLocal(i) += wij / d_dpdTheta(i); - } - d_sumWeights(i) += wij; + // Lucy Weight Function + if (WT_FLAG == LUCY) + { + wij = 1.0; + d_dpdThetaLocal(i) += wij / d_dpdTheta(i); + } + d_sumWeights(i) += wij; - // Normalized local temperature - d_dpdThetaLocal(i) = d_dpdThetaLocal(i) / d_sumWeights(i); + // Normalized local temperature + d_dpdThetaLocal(i) = d_dpdThetaLocal(i) / d_sumWeights(i); - if (LOCAL_TEMP_FLAG == HARMONIC) - d_dpdThetaLocal(i) = 1.0 / d_dpdThetaLocal(i); - } + if (LOCAL_TEMP_FLAG == HARMONIC) + d_dpdThetaLocal(i) = 1.0 / d_dpdThetaLocal(i); + } + ); // Clean up the local kokkos data. memory->destroy_kokkos(k_cutsq, h_cutsq); @@ -1147,6 +1239,93 @@ void FixRxKokkos::computeLocalTemperature() //delete [] sumWeights; } +/* ---------------------------------------------------------------------- */ + +template +int FixRxKokkos::pack_forward_comm(int n, int *list, double *buf, int pbc_flag, int *pbc) +{ + //printf("inside FixRxKokkos::pack_forward_comm %d\n", comm->me); + + HAT::t_float_2d h_dvector = atomKK->k_dvector.h_view; + + int m = 0; + for (int ii = 0; ii < n; ii++) { + const int jj = list[ii]; + for(int ispecies = 0; ispecies < nspecies; ispecies++){ + buf[m++] = h_dvector(ispecies,jj); + buf[m++] = h_dvector(ispecies+nspecies,jj); + } + } + + //printf("done with FixRxKokkos::pack_forward_comm %d\n", comm->me); + + return m; +} + +/* ---------------------------------------------------------------------- */ + +template +void FixRxKokkos::unpack_forward_comm(int n, int first, double *buf) +{ + //printf("inside FixRxKokkos::unpack_forward_comm %d\n", comm->me); + + HAT::t_float_2d h_dvector = atomKK->k_dvector.h_view; + + const int last = first + n ; + int m = 0; + for (int ii = first; ii < last; ii++){ + for (int ispecies = 0; ispecies < nspecies; ispecies++){ + h_dvector(ispecies,ii) = buf[m++]; + h_dvector(ispecies+nspecies,ii) = buf[m++]; + } + } + + //printf("done with FixRxKokkos::unpack_forward_comm %d\n", comm->me); +} + +/* ---------------------------------------------------------------------- */ + +template +int FixRxKokkos::pack_reverse_comm(int n, int first, double *buf) +{ + //printf("inside FixRxKokkos::pack_reverse_comm %d %d %d\n", comm->me, first, n); + // Sync the host view. + k_dpdThetaLocal.template sync(); + k_sumWeights. template sync(); + + const int last = first + n; + int m = 0; + for (int i = first; i < last; ++i) + { + buf[m++] = h_dpdThetaLocal(i); + buf[m++] = h_sumWeights(i); + } + //printf("done with FixRxKokkos::pack_reverse_comm %d\n", comm->me); + + return m; +} + +/* ---------------------------------------------------------------------- */ + +template +void FixRxKokkos::unpack_reverse_comm(int n, int *list, double *buf) +{ + // printf("inside FixRxKokkos::unpack_reverse_comm %d\n", comm->me); + int m = 0; + for (int i = 0; i < n; i++) { + const int j = list[i]; + + h_dpdThetaLocal(j) += buf[m++]; + h_sumWeights(j) += buf[m++]; + } + + // Signal that the host view has been modified. + k_dpdThetaLocal.template modify(); + k_sumWeights. template modify(); + + // printf("done with FixRxKokkos::unpack_reverse_comm %d\n", comm->me); +} + namespace LAMMPS_NS { template class FixRxKokkos; #ifdef KOKKOS_HAVE_CUDA diff --git a/src/KOKKOS/fix_rx_kokkos.h b/src/KOKKOS/fix_rx_kokkos.h index 9d60f2b99e..d397d91499 100644 --- a/src/KOKKOS/fix_rx_kokkos.h +++ b/src/KOKKOS/fix_rx_kokkos.h @@ -40,6 +40,8 @@ class FixRxKokkos : public FixRX { FixRxKokkos(class LAMMPS *, int, char **); virtual ~FixRxKokkos(); virtual void init(); + void post_constructor(); + virtual void setup_pre_force(int); virtual void pre_force(int); //template @@ -124,10 +126,18 @@ class FixRxKokkos : public FixRX { // Need a dual-view and device-view for dpdThetaLocal and sumWeights since they're used in several callbacks. DAT::tdual_efloat_1d k_dpdThetaLocal, k_sumWeights; typename ArrayTypes::t_efloat_1d d_dpdThetaLocal, d_sumWeights; + typename HAT::t_efloat_1d h_dpdThetaLocal, h_sumWeights; - template + template void computeLocalTemperature(); + int pack_reverse_comm(int, int, double *); + void unpack_reverse_comm(int, int *, double *); + int pack_forward_comm(int , int *, double *, int, int *); + void unpack_forward_comm(int , int , double *); + + private: // replicate a few from FixRX + int my_restartFlag; }; } From f2d005fb8db00fa90a151c2237985a77c7473b2a Mon Sep 17 00:00:00 2001 From: Christopher Stone Date: Tue, 7 Feb 2017 16:24:59 -0500 Subject: [PATCH 115/439] Fixed errors in FixRxKokkos kokkos neighbor lists initialization and usage and calls to computeLocalTemperature. - Created request for kokkos neighbor list for fix and switched to that neighbor list datatype in computeLocalTemperature. - Reconfigured pre_force and setup_pre_force to call a common solve_reactions() method to avoid duplicate code. TODO: - Clean-up - Provide per-problem scratch data within kokkos framework (instead of C++ new/delete data). --- src/KOKKOS/fix_rx_kokkos.cpp | 195 ++++++++++++++++++++++++++--------- src/KOKKOS/fix_rx_kokkos.h | 11 +- 2 files changed, 148 insertions(+), 58 deletions(-) diff --git a/src/KOKKOS/fix_rx_kokkos.cpp b/src/KOKKOS/fix_rx_kokkos.cpp index 167f2713ea..1497fea6c1 100644 --- a/src/KOKKOS/fix_rx_kokkos.cpp +++ b/src/KOKKOS/fix_rx_kokkos.cpp @@ -21,6 +21,9 @@ #include "update.h" #include "respa.h" #include "modify.h" +#include "neighbor.h" +#include "neigh_list_kokkos.h" +#include "neigh_request.h" #include "error.h" #include "math_special.h" @@ -95,24 +98,61 @@ void FixRxKokkos::init() printf("Inside FixRxKokkos::init\n"); // Call the parent's version. - FixRX::init(); + //FixRX::init(); + + pairDPDE = (PairDPDfdtEnergy *) force->pair_match("dpd/fdt/energy",1); + if (pairDPDE == NULL) + pairDPDE = (PairDPDfdtEnergy *) force->pair_match("dpd/fdt/energy/kk",1); + + if (pairDPDE == NULL) + error->all(FLERR,"Must use pair_style dpd/fdt/energy with fix rx"); pairDPDEKK = dynamic_cast(pairDPDE); if (pairDPDEKK == NULL) error->all(FLERR,"Must use pair_style dpd/fdt/energy/kk with fix rx/kk"); + bool eos_flag = false; + for (int i = 0; i < modify->nfix; i++) + if (strcmp(modify->fix[i]->style,"eos/table/rx") == 0) eos_flag = true; + if(!eos_flag) error->all(FLERR,"fix rx requires fix eos/table/rx to be specified"); + if (update_kinetics_data) create_kinetics_data(); + + // From FixRX::init() + // need a half neighbor list + // built whenever re-neighboring occurs + + int irequest = neighbor->request(this,instance_me); + neighbor->requests[irequest]->pair = 0; + neighbor->requests[irequest]->fix = 1; + + // Update the neighbor data for Kokkos. + int neighflag = lmp->kokkos->neighflag; + + neighbor->requests[irequest]-> + kokkos_host = Kokkos::Impl::is_same::value && + !Kokkos::Impl::is_same::value; + neighbor->requests[irequest]-> + kokkos_device = Kokkos::Impl::is_same::value; + + if (neighflag == FULL) { + neighbor->requests[irequest]->full = 1; + neighbor->requests[irequest]->half = 0; + } else { //if (neighflag == HALF || neighflag == HALFTHREAD) + neighbor->requests[irequest]->full = 0; + neighbor->requests[irequest]->half = 1; + } } /* ---------------------------------------------------------------------- */ -//template -//void FixRXKokkos::init_list(int, class NeighList* ptr) -//{ -// printf("Inside FixRxKokkos::init_list\n"); -// this->list = ptr; -//} +template +void FixRxKokkos::init_list(int, class NeighList* ptr) +{ + printf("Inside FixRxKokkos::init_list\n"); + this->list = ptr; +} /* ---------------------------------------------------------------------- */ @@ -663,37 +703,6 @@ void FixRxKokkos::operator()(SolverType, const int &i) const /* ---------------------------------------------------------------------- */ -template -void FixRxKokkos::solve_reactions(void) -{ -/* int nlocal = atom->nlocal; - if (igroup == atom->firstgroup) nlocal = atom->nfirst; - - using AT = ArrayTypes; - - atomKK->sync(execution_space, UCOND_MASK); - typename AT::t_efloat_1d uCond = atomKK->k_uCond.view(); - atomKK->sync(execution_space, UMECH_MASK); - typename AT::t_efloat_1d uMech = atomKK->k_uMech.view(); - - pairDPDEKK->k_duCond.template sync(); - typename AT::t_efloat_1d_const duCond = pairDPDEKK->k_duCond.template view(); - pairDPDEKK->k_duMech.template sync(); - typename AT::t_efloat_1d_const duMech = pairDPDEKK->k_duMech.template view(); - - auto dt = update->dt; - - Kokkos::parallel_for(nlocal, LAMMPS_LAMBDA(int i) { - uCond(i) += 0.5*dt*duCond(i); - uMech(i) += 0.5*dt*duMech(i); - }); - - atomKK->modified(execution_space, UCOND_MASK); - atomKK->modified(execution_space, UMECH_MASK); */ -} - -/* ---------------------------------------------------------------------- */ - template void FixRxKokkos::create_kinetics_data(void) { @@ -784,6 +793,9 @@ void FixRxKokkos::setup_pre_force(int vflag) my_restartFlag = 0; else { +#if 1 + this->solve_reactions( vflag, false ); +#else const int nlocal = atom->nlocal; //const int nghost = atom->nghost; //const int *mask = atom->mask; @@ -815,6 +827,7 @@ void FixRxKokkos::setup_pre_force(int vflag) // Flag that dvector was updated on the host in the comm. atomKK->modified ( Host, DVECTOR_MASK ); +#endif } } @@ -825,6 +838,15 @@ void FixRxKokkos::pre_force(int vflag) { printf("Inside FixRxKokkos::pre_force localTempFlag= %d\n", localTempFlag); + this->solve_reactions( vflag, true ); +} +/* ---------------------------------------------------------------------- */ + +template +void FixRxKokkos::solve_reactions(const int vflag, const bool isPreForce) +{ + printf("Inside FixRxKokkos::solve_reactions localTempFlag= %d isPreForce= %s\n", localTempFlag, isPreForce ? "True" : "false"); + if (update_kinetics_data) create_kinetics_data(); @@ -834,7 +856,8 @@ void FixRxKokkos::pre_force(int vflag) const int nghost = atom->nghost; const int newton_pair = force->newton_pair; - const bool setToZero = false; // don't set the forward rates to zero. + //const bool setToZero = false; // don't set the forward rates to zero. + const bool setToZero = isPreForce == false; // Set the forward rates to zero if acting as setup_pre_force. if (localTempFlag) { @@ -1115,16 +1138,71 @@ void FixRxKokkos::computeLocalTemperature() const int inum = list->inum; - // Local list views. (This isn't working!) - //NeighListKokkos* k_list = static_cast*>(list); - //if (not(list->kokkos)) - //{ - // error->one(FLERR,"list is not a Kokkos list\n"); - //} + bool useKokkosLists = false; - //typename ArrayTypes::t_neighbors_2d d_neighbors = k_list->d_neighbors; - //typename ArrayTypes::t_int_1d d_ilist = k_list->d_ilist; - //typename ArrayTypes::t_int_1d d_numneigh = k_list->d_numneigh; + // Local list views. (This isn't working!) + NeighListKokkos* k_list = static_cast*>(list); + if (not(list->kokkos)) + { + //error->one(FLERR,"list is not a Kokkos list\n"); + printf("list is NOT a Kokkos list\n"); + + int* ilist = list->ilist; + int* numneigh = list->numneigh; + int** firstneigh = list->firstneigh; + printf("inum= %d ilist= %x\n", inum, ilist); + for (int ii = 0; ii < std::min(inum,10); ++ii) + { + const int i = ilist[ii]; + int *jlist = firstneigh[i]; + const int jnum = numneigh[i]; + const int j = (jlist[0] & NEIGHMASK); + printf(" ilist[%d]= %d j= %d jnum= %d\n", ii, i, j, jnum); + } + } + else + { + printf("It's a kokkos list\n"); + + useKokkosLists = true; + + typename ArrayTypes::t_neighbors_2d d_neighbors = k_list->d_neighbors; + typename ArrayTypes::t_int_1d d_ilist = k_list->d_ilist; + typename ArrayTypes::t_int_1d d_numneigh = k_list->d_numneigh; + + static FILE *fp1 = NULL; + + //if (fp1 == NULL) + // fp1 = fopen("kokkos_list.txt","w"); + + if (fp1 != NULL) + { + const int inum = list->inum; + fprintf(fp1, "inum= %d\n", inum); + for (int ii = 0; ii < inum; ++ii) + { + const int i = d_ilist[ii]; + const int jnum = d_numneigh[i]; + fprintf(fp1, " %d %d %d\n", ii, i, jnum); + for (int jj = 0; jj < jnum; ++jj) + { + const int j = (d_neighbors(i,jj) & NEIGHMASK); + fprintf(fp1, " %d %d\n", jj, j); + } + } + } + } + + typename ArrayTypes::t_neighbors_2d d_neighbors; + typename ArrayTypes::t_int_1d d_ilist; + typename ArrayTypes::t_int_1d d_numneigh; + + if (useKokkosLists) + { + d_neighbors = k_list->d_neighbors; + d_ilist = k_list->d_ilist; + d_numneigh = k_list->d_numneigh; + } int* ilist = list->ilist; int* numneigh = list->numneigh; @@ -1145,8 +1223,9 @@ void FixRxKokkos::computeLocalTemperature() double i_dpdThetaLocal = 0.0; double i_sumWeights = 0.0; - const int i = ilist[ii]; + //const int i = ilist[ii]; //const int i = d_ilist(ii); + const int i = (useKokkosLists) ? d_ilist(ii) : ilist[ii]; const double xtmp = d_x(i,0); const double ytmp = d_x(i,1); @@ -1154,13 +1233,15 @@ void FixRxKokkos::computeLocalTemperature() const int itype = d_type(i); int *jlist = firstneigh[i]; - const int jnum = numneigh[i]; + //const int jnum = numneigh[i]; //const int jnum = d_numneigh(i); + const int jnum = (useKokkosLists) ? d_numneigh(i) : numneigh[i]; for (int jj = 0; jj < jnum; jj++) { - const int j = (jlist[jj] & NEIGHMASK); + //const int j = (jlist[jj] & NEIGHMASK); //const int j = (d_neighbors(i,jj) & NEIGHMASK); + const int j = (useKokkosLists) ? (d_neighbors(i,jj) & NEIGHMASK) : (jlist[jj] & NEIGHMASK); const int jtype = d_type(j); const double delx = xtmp - d_x(j,0); @@ -1232,6 +1313,18 @@ void FixRxKokkos::computeLocalTemperature() } ); + if (false) + { + static FILE *fp = NULL; + + if (fp == NULL) + fp = fopen("kokkos_temp.txt","w"); + + fprintf(fp, "nlocal= %d %d\n", nlocal, nghost); + for (int i = 0; i < nlocal; ++i) + fprintf(fp, "%d %15.9e %15.9e\n", i, d_dpdThetaLocal[i], d_sumWeights[i]); + } + // Clean up the local kokkos data. memory->destroy_kokkos(k_cutsq, h_cutsq); memory->destroy_kokkos(k_sumWeights, sumWeights); diff --git a/src/KOKKOS/fix_rx_kokkos.h b/src/KOKKOS/fix_rx_kokkos.h index d397d91499..36b05cb210 100644 --- a/src/KOKKOS/fix_rx_kokkos.h +++ b/src/KOKKOS/fix_rx_kokkos.h @@ -25,21 +25,18 @@ FixStyle(rx/kk/host,FixRxKokkos) #include "fix_rx.h" #include "pair_dpd_fdt_energy_kokkos.h" #include "kokkos_type.h" +#include "neigh_list.h" +#include "neigh_list_kokkos.h" namespace LAMMPS_NS { -template -struct TagFixRxKokkosSolver -{ - enum { setToZero = (_setToZero == true) ? 1 : 0 }; -}; - template class FixRxKokkos : public FixRX { public: FixRxKokkos(class LAMMPS *, int, char **); virtual ~FixRxKokkos(); virtual void init(); + void init_list(int, class NeighList *); void post_constructor(); virtual void setup_pre_force(int); virtual void pre_force(int); @@ -79,7 +76,7 @@ class FixRxKokkos : public FixRX { PairDPDfdtEnergyKokkos* pairDPDEKK; double VDPD; - void solve_reactions(void); + void solve_reactions(const int vflag, const bool isPreForce = true); int rhs(double, const double *, double *, void *) const; int rhs_dense (double, const double *, double *, void *) const; From 4e8351d9c8cb26328b667882290742029d5bbdfe Mon Sep 17 00:00:00 2001 From: Christopher Stone Date: Tue, 7 Feb 2017 17:53:36 -0500 Subject: [PATCH 116/439] Code clean-up for FixRxKokkos. - Removed dead code and old errors. TODO: - Per-thread scratch data in kokkos. - ODE Diagnostics in kokkos. --- src/KOKKOS/fix_rx_kokkos.cpp | 166 +++-------------------------------- 1 file changed, 12 insertions(+), 154 deletions(-) diff --git a/src/KOKKOS/fix_rx_kokkos.cpp b/src/KOKKOS/fix_rx_kokkos.cpp index 1497fea6c1..b5055191c4 100644 --- a/src/KOKKOS/fix_rx_kokkos.cpp +++ b/src/KOKKOS/fix_rx_kokkos.cpp @@ -792,43 +792,7 @@ void FixRxKokkos::setup_pre_force(int vflag) if (my_restartFlag) my_restartFlag = 0; else - { -#if 1 this->solve_reactions( vflag, false ); -#else - const int nlocal = atom->nlocal; - //const int nghost = atom->nghost; - //const int *mask = atom->mask; - //const int newton_pair = force->newton_pair; - - typename ArrayTypes::t_float_2d d_dvector = atomKK->k_dvector.view(); - - // Get up-to-date data. - atomKK->sync( execution_space, DVECTOR_MASK ); - - // The only net effect from fix_rx.cpp is to set dvector[nspecies:2*nspecies] - // since the reactions are set to zero for step 0. - Kokkos::parallel_for ( nlocal, - LAMMPS_LAMBDA(const int i) - { - for (int ispecies = 0; ispecies < nspecies; ispecies++) - d_dvector(ispecies+nspecies,i) = d_dvector(ispecies,i); - } - ); - - // Signal that dvector has been modified on this execution space. - atomKK->modified( execution_space, DVECTOR_MASK ); - - // Communicate the updated species data to all nodes - atomKK->sync ( Host, DVECTOR_MASK ); - - // Communicate the dvector to all nodes - comm->forward_comm_fix(this); - - // Flag that dvector was updated on the host in the comm. - atomKK->modified ( Host, DVECTOR_MASK ); -#endif - } } /* ---------------------------------------------------------------------- */ @@ -856,17 +820,13 @@ void FixRxKokkos::solve_reactions(const int vflag, const bool isPreF const int nghost = atom->nghost; const int newton_pair = force->newton_pair; - //const bool setToZero = false; // don't set the forward rates to zero. - const bool setToZero = isPreForce == false; // Set the forward rates to zero if acting as setup_pre_force. + // Set the forward rates to zero if acting as setup_pre_force. + const bool setRatesToZero = (isPreForce == false); if (localTempFlag) { const int count = nlocal + (newton_pair ? nghost : 0); - //dpdThetaLocal = new double[count]; - //memset(dpdThetaLocal, 0, sizeof(double)*count); - //FixRx::computeLocalTemperature(); - memory->create_kokkos (k_dpdThetaLocal, dpdThetaLocal, count, "FixRxKokkos::dpdThetaLocal"); d_dpdThetaLocal = k_dpdThetaLocal.d_view; h_dpdThetaLocal = k_dpdThetaLocal.h_view; @@ -904,9 +864,6 @@ void FixRxKokkos::solve_reactions(const int vflag, const bool isPreF // Set data needed in the operators. // ... - //int *mask = atom->mask; - //double *dpdTheta = atom->dpdTheta; - // Local references to the atomKK objects. typename ArrayTypes::t_efloat_1d d_dpdTheta = atomKK->k_dpdTheta.view(); typename ArrayTypes::t_float_2d d_dvector = atomKK->k_dvector.view(); @@ -941,13 +898,12 @@ void FixRxKokkos::solve_reactions(const int vflag, const bool isPreF CounterType counter_i; - //const double theta = (localTempFlag) ? dpdThetaLocal[i] : d_dpdTheta(i); const double theta = (localTempFlag) ? d_dpdThetaLocal(i) : d_dpdTheta(i); //Compute the reaction rate constants for (int irxn = 0; irxn < nreactions; irxn++) { - if (setToZero) + if (setRatesToZero) userData.kFor[irxn] = 0.0; else { @@ -1068,16 +1024,6 @@ template template void FixRxKokkos::computeLocalTemperature() { - - //int inum,jnum,itype,jtype; - //double xtmp,ytmp,ztmp,delx,dely,delz; - //double rsq; - //int *ilist,*jlist,*numneigh,**firstneigh; - - //double **x = atom->x; - //int *type = atom->type; - //double *dpdTheta = atom->dpdTheta; - typename ArrayTypes::t_x_array_randomread d_x = atomKK->k_x.view(); typename ArrayTypes::t_int_1d_randomread d_type = atomKK->k_type.view(); typename ArrayTypes::t_efloat_1d d_dpdTheta = atomKK->k_dpdTheta.view(); @@ -1086,12 +1032,8 @@ void FixRxKokkos::computeLocalTemperature() const int nlocal = atom->nlocal; const int nghost = atom->nghost; - //const int newton_pair = force->newton_pair; - printf("Inside FixRxKokkos::computeLocalTemperature: %d %d %d %d %d\n", WT_FLAG, LOCAL_TEMP_FLAG, NEWTON_PAIR, (int)lmp->kokkos->neighflag, NEIGHFLAG, nlocal, nghost); - - // local temperature variables - //double wij=0.0; + printf("Inside FixRxKokkos::computeLocalTemperature: %d %d %d %d %d %d %d\n", WT_FLAG, LOCAL_TEMP_FLAG, NEWTON_PAIR, (int)lmp->kokkos->neighflag, NEIGHFLAG, nlocal, nghost); // Pull from pairDPDE. The pairDPDEKK objects are protected so recreate here for now. //pairDPDEKK->k_cutsq.template sync(); @@ -1121,8 +1063,6 @@ void FixRxKokkos::computeLocalTemperature() // Initialize the local temperature weight array int sumWeightsCt = nlocal + (NEWTON_PAIR ? nghost : 0); - //sumWeights = new double[sumWeightsCt]; - //memset(sumWeights, 0, sizeof(double)*sumWeightsCt); memory->create_kokkos (k_sumWeights, sumWeights, sumWeightsCt, "FixRxKokkos::sumWeights"); d_sumWeights = k_sumWeights.d_view; @@ -1136,77 +1076,16 @@ void FixRxKokkos::computeLocalTemperature() } ); - const int inum = list->inum; - - bool useKokkosLists = false; - // Local list views. (This isn't working!) NeighListKokkos* k_list = static_cast*>(list); if (not(list->kokkos)) - { - //error->one(FLERR,"list is not a Kokkos list\n"); - printf("list is NOT a Kokkos list\n"); + error->one(FLERR,"list is not a Kokkos list\n"); - int* ilist = list->ilist; - int* numneigh = list->numneigh; - int** firstneigh = list->firstneigh; - printf("inum= %d ilist= %x\n", inum, ilist); - for (int ii = 0; ii < std::min(inum,10); ++ii) - { - const int i = ilist[ii]; - int *jlist = firstneigh[i]; - const int jnum = numneigh[i]; - const int j = (jlist[0] & NEIGHMASK); - printf(" ilist[%d]= %d j= %d jnum= %d\n", ii, i, j, jnum); - } - } - else - { - printf("It's a kokkos list\n"); + typename ArrayTypes::t_neighbors_2d d_neighbors = k_list->d_neighbors; + typename ArrayTypes::t_int_1d d_ilist = k_list->d_ilist; + typename ArrayTypes::t_int_1d d_numneigh = k_list->d_numneigh; - useKokkosLists = true; - - typename ArrayTypes::t_neighbors_2d d_neighbors = k_list->d_neighbors; - typename ArrayTypes::t_int_1d d_ilist = k_list->d_ilist; - typename ArrayTypes::t_int_1d d_numneigh = k_list->d_numneigh; - - static FILE *fp1 = NULL; - - //if (fp1 == NULL) - // fp1 = fopen("kokkos_list.txt","w"); - - if (fp1 != NULL) - { - const int inum = list->inum; - fprintf(fp1, "inum= %d\n", inum); - for (int ii = 0; ii < inum; ++ii) - { - const int i = d_ilist[ii]; - const int jnum = d_numneigh[i]; - fprintf(fp1, " %d %d %d\n", ii, i, jnum); - for (int jj = 0; jj < jnum; ++jj) - { - const int j = (d_neighbors(i,jj) & NEIGHMASK); - fprintf(fp1, " %d %d\n", jj, j); - } - } - } - } - - typename ArrayTypes::t_neighbors_2d d_neighbors; - typename ArrayTypes::t_int_1d d_ilist; - typename ArrayTypes::t_int_1d d_numneigh; - - if (useKokkosLists) - { - d_neighbors = k_list->d_neighbors; - d_ilist = k_list->d_ilist; - d_numneigh = k_list->d_numneigh; - } - - int* ilist = list->ilist; - int* numneigh = list->numneigh; - int** firstneigh = list->firstneigh; + const int inum = list->inum; // loop over neighbors of my atoms Kokkos::parallel_for ( inum, @@ -1223,25 +1102,18 @@ void FixRxKokkos::computeLocalTemperature() double i_dpdThetaLocal = 0.0; double i_sumWeights = 0.0; - //const int i = ilist[ii]; - //const int i = d_ilist(ii); - const int i = (useKokkosLists) ? d_ilist(ii) : ilist[ii]; + const int i = d_ilist(ii); const double xtmp = d_x(i,0); const double ytmp = d_x(i,1); const double ztmp = d_x(i,2); const int itype = d_type(i); - int *jlist = firstneigh[i]; - //const int jnum = numneigh[i]; - //const int jnum = d_numneigh(i); - const int jnum = (useKokkosLists) ? d_numneigh(i) : numneigh[i]; + const int jnum = d_numneigh(i); for (int jj = 0; jj < jnum; jj++) { - //const int j = (jlist[jj] & NEIGHMASK); - //const int j = (d_neighbors(i,jj) & NEIGHMASK); - const int j = (useKokkosLists) ? (d_neighbors(i,jj) & NEIGHMASK) : (jlist[jj] & NEIGHMASK); + const int j = (d_neighbors(i,jj) & NEIGHMASK); const int jtype = d_type(j); const double delx = xtmp - d_x(j,0); @@ -1313,23 +1185,9 @@ void FixRxKokkos::computeLocalTemperature() } ); - if (false) - { - static FILE *fp = NULL; - - if (fp == NULL) - fp = fopen("kokkos_temp.txt","w"); - - fprintf(fp, "nlocal= %d %d\n", nlocal, nghost); - for (int i = 0; i < nlocal; ++i) - fprintf(fp, "%d %15.9e %15.9e\n", i, d_dpdThetaLocal[i], d_sumWeights[i]); - } - // Clean up the local kokkos data. memory->destroy_kokkos(k_cutsq, h_cutsq); memory->destroy_kokkos(k_sumWeights, sumWeights); - - //delete [] sumWeights; } /* ---------------------------------------------------------------------- */ From 93d99ec8d0576aebebbc7658a891013326de6f6c Mon Sep 17 00:00:00 2001 From: Christopher Stone Date: Thu, 9 Feb 2017 22:38:58 -0500 Subject: [PATCH 117/439] Added ODE diagnostics to FixRxKokkos using Kokkos managed data. - Added the diagnostics performance analysis routine to FixRxKokkos using Kokkos views. TODO: - Switch to using Kokkos data for the per-iteration scratch data. How to allocate only enouch for each work-unit and not all iterations? Can the shared-memory scratch memory work for this, even for large sizes? --- src/KOKKOS/fix_rx_kokkos.cpp | 231 +++++++++++++++++++++++++++++++---- src/KOKKOS/fix_rx_kokkos.h | 13 ++ 2 files changed, 223 insertions(+), 21 deletions(-) diff --git a/src/KOKKOS/fix_rx_kokkos.cpp b/src/KOKKOS/fix_rx_kokkos.cpp index b5055191c4..2a3fc7547a 100644 --- a/src/KOKKOS/fix_rx_kokkos.cpp +++ b/src/KOKKOS/fix_rx_kokkos.cpp @@ -879,11 +879,22 @@ void FixRxKokkos::solve_reactions(const int vflag, const bool isPreF // Average DPD volume. Used in the RHS function. this->VDPD = domain->xprd * domain->yprd * domain->zprd / atom->natoms; - /*if (odeIntegrationFlag == ODE_LAMMPS_RKF45 && diagnosticFrequency == 1) + if (odeIntegrationFlag == ODE_LAMMPS_RKF45 && diagnosticFrequency == 1) { - memory->create( diagnosticCounterPerODE[StepSum], nlocal, "FixRX::diagnosticCounterPerODE"); - memory->create( diagnosticCounterPerODE[FuncSum], nlocal, "FixRX::diagnosticCounterPerODE"); - }*/ + memory->create_kokkos (k_diagnosticCounterPerODEnSteps, diagnosticCounterPerODEnSteps, nlocal, "FixRxKokkos::diagnosticCounterPerODEnSteps"); + memory->create_kokkos (k_diagnosticCounterPerODEnFuncs, diagnosticCounterPerODEnFuncs, nlocal, "FixRxKokkos::diagnosticCounterPerODEnFuncs"); + + d_diagnosticCounterPerODEnSteps = k_diagnosticCounterPerODEnSteps.d_view; + d_diagnosticCounterPerODEnFuncs = k_diagnosticCounterPerODEnFuncs.d_view; + + Kokkos::parallel_for ( nlocal, + LAMMPS_LAMBDA(const int i) + { + d_diagnosticCounterPerODEnSteps(i) = 0; + d_diagnosticCounterPerODEnFuncs(i) = 0; + } + ); + } Kokkos::parallel_reduce( nlocal, LAMMPS_LAMBDA(int i, CounterType &counter) { @@ -930,12 +941,11 @@ void FixRxKokkos::solve_reactions(const int vflag, const bool isPreF { rkf45(nspecies, t_stop, y, rwork, &userData, counter_i); - //if (diagnosticFrequency == 1 && diagnosticCounterPerODE[StepSum] != NULL) - //if (diagnosticCounterPerODE[StepSum] != NULL) - //{ - // diagnosticCounterPerODE[StepSum][i] = counter_i.nSteps; - // diagnosticCounterPerODE[FuncSum][i] = counter_i.nFuncs; - //} + if (diagnosticFrequency == 1) + { + d_diagnosticCounterPerODEnSteps(i) = counter_i.nSteps; + d_diagnosticCounterPerODEnFuncs(i) = counter_i.nFuncs; + } } // Store the solution back in dvector. @@ -975,10 +985,7 @@ void FixRxKokkos::solve_reactions(const int vflag, const bool isPreF atomKK->modified ( Host, DVECTOR_MASK ); if (localTempFlag) - { - //delete [] dpdThetaLocal; memory->destroy_kokkos(k_dpdThetaLocal, dpdThetaLocal); - } TimerType timer_stop = getTimeStamp(); @@ -997,12 +1004,12 @@ void FixRxKokkos::solve_reactions(const int vflag, const bool isPreF error->warning(FLERR, sbuf); } -/* // Compute and report ODE diagnostics, if requested. - if (odeIntegrationFlag == ODE_LAMMPS_RKF45 && diagnosticFrequency != 0){ + if (odeIntegrationFlag == ODE_LAMMPS_RKF45 && diagnosticFrequency != 0) + { // Update the counters. - diagnosticCounter[StepSum] += nSteps; - diagnosticCounter[FuncSum] += nFuncs; + diagnosticCounter[StepSum] += TotalCounters.nSteps; + diagnosticCounter[FuncSum] += TotalCounters.nFuncs; diagnosticCounter[TimeSum] += time_ODE; diagnosticCounter[AtomSum] += nlocal; diagnosticCounter[numDiagnosticCounters-1] ++; @@ -1011,11 +1018,193 @@ void FixRxKokkos::solve_reactions(const int vflag, const bool isPreF ((update->ntimestep - update->firststep) % diagnosticFrequency) == 0) || (diagnosticFrequency < 0 && update->ntimestep == update->laststep) ) this->odeDiagnostics(); + } +} - for (int i = 0; i < numDiagnosticCounters; ++i) - if (diagnosticCounterPerODE[i]) - memory->destroy( diagnosticCounterPerODE[i] ); - } */ +/* ---------------------------------------------------------------------- */ + +template +void FixRxKokkos::odeDiagnostics(void) +{ + TimerType timer_start = getTimeStamp(); + + // Compute: + // 1) Average # of ODE integrator steps and RHS evaluations per atom globally. + // 2) RMS # of ... + // 3) Average # of ODE steps and RHS evaluations per MPI task. + // 4) RMS # of ODE steps and RHS evaluations per MPI task. + // 5) MAX # of ODE steps and RHS evaluations per MPI task. + // + // ... 1,2 are for ODE control diagnostics. + // ... 3-5 are for load balancing diagnostics. + // + // To do this, we'll need to + // a) Allreduce (sum) the sum of nSteps / nFuncs. Dividing by atom->natoms + // gives the avg # of steps/funcs per atom globally. + // b) Reduce (sum) to root the sum of squares of the differences. + // i) Sum_i (steps_i - avg_steps_global)^2 + // ii) Sum_i (funcs_i - avg_funcs_global)^2 + // iii) (avg_steps_local - avg_steps_global)^2 + // iv) (avg_funcs_local - avg_funcs_global)^2 + + const int numCounters = numDiagnosticCounters-1; + + // # of time-steps for averaging. + const int nTimes = this->diagnosticCounter[numDiagnosticCounters-1]; + + // # of ODE's per time-step (on average). + //const int nODEs = this->diagnosticCounter[AtomSum] / nTimes; + + // Sum up the sums from each task. + double sums[numCounters]; + double my_vals[numCounters]; + double max_per_proc[numCounters]; + double min_per_proc[numCounters]; + + // Compute counters per dpd time-step. + for (int i = 0; i < numCounters; ++i){ + my_vals[i] = this->diagnosticCounter[i] / nTimes; + //printf("my sum[%d] = %f %d\n", i, my_vals[i], comm->me); + } + + MPI_Allreduce (my_vals, sums, numCounters, MPI_DOUBLE, MPI_SUM, world); + + MPI_Reduce (my_vals, max_per_proc, numCounters, MPI_DOUBLE, MPI_MAX, 0, world); + MPI_Reduce (my_vals, min_per_proc, numCounters, MPI_DOUBLE, MPI_MIN, 0, world); + + const double nODEs = sums[numCounters-1]; + + double avg_per_atom[numCounters], avg_per_proc[numCounters]; + + // Averages per-ODE and per-proc per time-step. + for (int i = 0; i < numCounters; ++i){ + avg_per_atom[i] = sums[i] / nODEs; + avg_per_proc[i] = sums[i] / comm->nprocs; + } + + // Sum up the differences from each task. + double sum_sq[2*numCounters]; + double my_sum_sq[2*numCounters]; + for (int i = 0; i < numCounters; ++i){ + double diff_i = my_vals[i] - avg_per_proc[i]; + my_sum_sq[i] = diff_i * diff_i; + } + + double max_per_ODE[numCounters], min_per_ODE[numCounters]; + + // Process the per-ODE RMS of the # of steps/funcs + if (diagnosticFrequency == 1) + { + h_diagnosticCounterPerODEnSteps = k_diagnosticCounterPerODEnSteps.h_view; + h_diagnosticCounterPerODEnFuncs = k_diagnosticCounterPerODEnFuncs.h_view; + + Kokkos::deep_copy( h_diagnosticCounterPerODEnSteps, d_diagnosticCounterPerODEnSteps ); + Kokkos::deep_copy( h_diagnosticCounterPerODEnFuncs, d_diagnosticCounterPerODEnFuncs ); + + double my_max[numCounters], my_min[numCounters]; + + const int nlocal = atom->nlocal; + HAT::t_int_1d h_mask = atomKK->k_mask.h_view; + + for (int i = 0; i < numCounters; ++i) + { + my_sum_sq[i+numCounters] = 0; + my_max[i] = 0; + my_min[i] = DBL_MAX; + } + + for (int j = 0; j < nlocal; ++j) + if (h_mask(j) & groupbit) + { + int nSteps = h_diagnosticCounterPerODEnSteps(j); + double diff_nSteps = double( nSteps ) - avg_per_atom[StepSum]; + my_sum_sq[StepSum+numCounters] += diff_nSteps*diff_nSteps; + my_max[StepSum] = std::max( my_max[StepSum], (double)nSteps ); + my_min[StepSum] = std::min( my_min[StepSum], (double)nSteps ); + + int nFuncs = h_diagnosticCounterPerODEnFuncs(j); + double diff_nFuncs = double( nFuncs ) - avg_per_atom[FuncSum]; + my_sum_sq[FuncSum+numCounters] += diff_nFuncs*diff_nFuncs; + + my_max[FuncSum] = std::max( my_max[FuncSum], (double)nFuncs ); + my_min[FuncSum] = std::min( my_min[FuncSum], (double)nFuncs ); + } + + memory->destroy_kokkos( k_diagnosticCounterPerODEnSteps, diagnosticCounterPerODEnSteps ); + memory->destroy_kokkos( k_diagnosticCounterPerODEnFuncs, diagnosticCounterPerODEnFuncs ); + + MPI_Reduce (my_sum_sq, sum_sq, 2*numCounters, MPI_DOUBLE, MPI_SUM, 0, world); + + MPI_Reduce (my_max, max_per_ODE, numCounters, MPI_DOUBLE, MPI_MAX, 0, world); + MPI_Reduce (my_min, min_per_ODE, numCounters, MPI_DOUBLE, MPI_MIN, 0, world); + } + else + MPI_Reduce (my_sum_sq, sum_sq, numCounters, MPI_DOUBLE, MPI_SUM, 0, world); + + TimerType timer_stop = getTimeStamp(); + double time_local = getElapsedTime( timer_start, timer_stop ); + + if (comm->me == 0){ + char smesg[128]; + +#define print_mesg(smesg) {\ + if (screen) fprintf(screen,"%s\n", smesg); \ + if (logfile) fprintf(logfile,"%s\n", smesg); } + + sprintf(smesg, "FixRX::ODE Diagnostics: # of iters |# of rhs evals| run-time (sec) | # atoms"); + print_mesg(smesg); + + sprintf(smesg, " AVG per ODE : %-12.5g | %-12.5g | %-12.5g", avg_per_atom[0], avg_per_atom[1], avg_per_atom[2]); + print_mesg(smesg); + + // only valid for single time-step! + if (diagnosticFrequency == 1){ + double rms_per_ODE[numCounters]; + for (int i = 0; i < numCounters; ++i) + rms_per_ODE[i] = sqrt( sum_sq[i+numCounters] / nODEs ); + + sprintf(smesg, " RMS per ODE : %-12.5g | %-12.5g ", rms_per_ODE[0], rms_per_ODE[1]); + print_mesg(smesg); + + sprintf(smesg, " MAX per ODE : %-12.5g | %-12.5g ", max_per_ODE[0], max_per_ODE[1]); + print_mesg(smesg); + + sprintf(smesg, " MIN per ODE : %-12.5g | %-12.5g ", min_per_ODE[0], min_per_ODE[1]); + print_mesg(smesg); + } + + sprintf(smesg, " AVG per Proc : %-12.5g | %-12.5g | %-12.5g | %-12.5g", avg_per_proc[StepSum], avg_per_proc[FuncSum], avg_per_proc[TimeSum], avg_per_proc[AtomSum]); + print_mesg(smesg); + + if (comm->nprocs > 1){ + double rms_per_proc[numCounters]; + for (int i = 0; i < numCounters; ++i) + rms_per_proc[i] = sqrt( sum_sq[i] / comm->nprocs ); + + sprintf(smesg, " RMS per Proc : %-12.5g | %-12.5g | %-12.5g | %-12.5g", rms_per_proc[0], rms_per_proc[1], rms_per_proc[2], rms_per_proc[AtomSum]); + print_mesg(smesg); + + sprintf(smesg, " MAX per Proc : %-12.5g | %-12.5g | %-12.5g | %-12.5g", max_per_proc[0], max_per_proc[1], max_per_proc[2], max_per_proc[AtomSum]); + print_mesg(smesg); + + sprintf(smesg, " MIN per Proc : %-12.5g | %-12.5g | %-12.5g | %-12.5g", min_per_proc[0], min_per_proc[1], min_per_proc[2], min_per_proc[AtomSum]); + print_mesg(smesg); + } + + sprintf(smesg, " AVG'd over %d time-steps", nTimes); + print_mesg(smesg); + sprintf(smesg, " AVG'ing took %g sec", time_local); + print_mesg(smesg); + +#undef print_mesg + + } + + // Reset the counters. + for (int i = 0; i < numDiagnosticCounters; ++i) + diagnosticCounter[i] = 0; + + return; } /* ---------------------------------------------------------------------- */ diff --git a/src/KOKKOS/fix_rx_kokkos.h b/src/KOKKOS/fix_rx_kokkos.h index 36b05cb210..4a11ac9fb9 100644 --- a/src/KOKKOS/fix_rx_kokkos.h +++ b/src/KOKKOS/fix_rx_kokkos.h @@ -97,6 +97,19 @@ class FixRxKokkos : public FixRX { const double hmin, const double hmax, double& h0, double y[], double rwk[], void *v_params) const; + //!< ODE Solver diagnostics. + void odeDiagnostics(void); + + //!< Special counters per-ode. + int *diagnosticCounterPerODEnSteps; + int *diagnosticCounterPerODEnFuncs; + DAT::tdual_int_1d k_diagnosticCounterPerODEnSteps; + DAT::tdual_int_1d k_diagnosticCounterPerODEnFuncs; + typename ArrayTypes::t_int_1d d_diagnosticCounterPerODEnSteps; + typename ArrayTypes::t_int_1d d_diagnosticCounterPerODEnFuncs; + typename HAT::t_int_1d h_diagnosticCounterPerODEnSteps; + typename HAT::t_int_1d h_diagnosticCounterPerODEnFuncs; + template struct KineticsType { From 4ac7a5d1f2e6132595c8999090e7b4159aa6971a Mon Sep 17 00:00:00 2001 From: Christopher Stone Date: Sun, 12 Feb 2017 21:21:11 -0500 Subject: [PATCH 118/439] Added Kokkos-like array datatype into RK4 and RHS in FixRXKokkos. - Created an Array class that provides stride access for operator[] w/o needing Kokkos views. This was designed to avoid the performance issues encountered with Views and sub-views throughout the RHS and ODE solver functions. --- src/KOKKOS/fix_rx_kokkos.cpp | 520 ++++++++++++++++++++++++++++++++++- src/KOKKOS/fix_rx_kokkos.h | 52 +++- 2 files changed, 570 insertions(+), 2 deletions(-) diff --git a/src/KOKKOS/fix_rx_kokkos.cpp b/src/KOKKOS/fix_rx_kokkos.cpp index 2a3fc7547a..a6da0306bb 100644 --- a/src/KOKKOS/fix_rx_kokkos.cpp +++ b/src/KOKKOS/fix_rx_kokkos.cpp @@ -202,6 +202,373 @@ void FixRxKokkos::rk4(const double t_stop, double *y, double *rwork, /* ---------------------------------------------------------------------- */ +template + template +void FixRxKokkos::k_rk4(const double t_stop, double *y, double *rwork, UserDataType& userData) const +{ + double *k1 = rwork; + double *k2 = k1 + nspecies; + double *k3 = k2 + nspecies; + double *k4 = k3 + nspecies; + double *yp = k4 + nspecies; + + const int numSteps = minSteps; + + const double h = t_stop / double(numSteps); + + // Run the requested steps with h. + for (int step = 0; step < numSteps; step++) + { + // k1 + k_rhs(0.0,y,k1, userData); + + // k2 + for (int ispecies = 0; ispecies < nspecies; ispecies++) + yp[ispecies] = y[ispecies] + 0.5*h*k1[ispecies]; + + k_rhs(0.0,yp,k2, userData); + + // k3 + for (int ispecies = 0; ispecies < nspecies; ispecies++) + yp[ispecies] = y[ispecies] + 0.5*h*k2[ispecies]; + + k_rhs(0.0,yp,k3, userData); + + // k4 + for (int ispecies = 0; ispecies < nspecies; ispecies++) + yp[ispecies] = y[ispecies] + h*k3[ispecies]; + + k_rhs(0.0,yp,k4, userData); + + for (int ispecies = 0; ispecies < nspecies; ispecies++) + y[ispecies] += h*(k1[ispecies]/6.0 + k2[ispecies]/3.0 + k3[ispecies]/3.0 + k4[ispecies]/6.0); + + } // end for (int step... + +} + +/* ---------------------------------------------------------------------- */ + +// f1 = dt*f(t,x) +// f2 = dt*f(t+ c20*dt,x + c21*f1) +// f3 = dt*f(t+ c30*dt,x + c31*f1 + c32*f2) +// f4 = dt*f(t+ c40*dt,x + c41*f1 + c42*f2 + c43*f3) +// f5 = dt*f(t+dt,x + c51*f1 + c52*f2 + c53*f3 + c54*f4) +// f6 = dt*f(t+ c60*dt,x + c61*f1 + c62*f2 + c63*f3 + c64*f4 + c65*f5) +// +// fifth-order runge-kutta integration +// x5 = x + b1*f1 + b3*f3 + b4*f4 + b5*f5 + b6*f6 +// fourth-order runge-kutta integration +// x = x + a1*f1 + a3*f3 + a4*f4 + a5*f5 + +template + template +void FixRxKokkos::k_rkf45_step (const int neq, const double h, double y[], double y_out[], double rwk[], UserDataType& userData) const +{ + const double c21=0.25; + const double c31=0.09375; + const double c32=0.28125; + const double c41=0.87938097405553; + const double c42=-3.2771961766045; + const double c43=3.3208921256258; + const double c51=2.0324074074074; + const double c52=-8.0; + const double c53=7.1734892787524; + const double c54=-0.20589668615984; + const double c61=-0.2962962962963; + const double c62=2.0; + const double c63=-1.3816764132554; + const double c64=0.45297270955166; + const double c65=-0.275; + const double a1=0.11574074074074; + const double a3=0.54892787524366; + const double a4=0.5353313840156; + const double a5=-0.2; + const double b1=0.11851851851852; + const double b3=0.51898635477583; + const double b4=0.50613149034201; + const double b5=-0.18; + const double b6=0.036363636363636; + + // local dependent variables (5 total) + double* f1 = &rwk[ 0]; + double* f2 = &rwk[ neq]; + double* f3 = &rwk[2*neq]; + double* f4 = &rwk[3*neq]; + double* f5 = &rwk[4*neq]; + double* f6 = &rwk[5*neq]; + + // scratch for the intermediate solution. + //double* ytmp = &rwk[6*neq]; + double* ytmp = y_out; + + // 1) + k_rhs (0.0, y, f1, userData); + + for (int k = 0; k < neq; k++){ + f1[k] *= h; + ytmp[k] = y[k] + c21 * f1[k]; + } + + // 2) + k_rhs(0.0, ytmp, f2, userData); + + for (int k = 0; k < neq; k++){ + f2[k] *= h; + ytmp[k] = y[k] + c31 * f1[k] + c32 * f2[k]; + } + + // 3) + k_rhs(0.0, ytmp, f3, userData); + + for (int k = 0; k < neq; k++) { + f3[k] *= h; + ytmp[k] = y[k] + c41 * f1[k] + c42 * f2[k] + c43 * f3[k]; + } + + // 4) + k_rhs(0.0, ytmp, f4, userData); + + for (int k = 0; k < neq; k++) { + f4[k] *= h; + ytmp[k] = y[k] + c51 * f1[k] + c52 * f2[k] + c53 * f3[k] + c54 * f4[k]; + } + + // 5) + k_rhs(0.0, ytmp, f5, userData); + + for (int k = 0; k < neq; k++) { + f5[k] *= h; + ytmp[k] = y[k] + c61*f1[k] + c62*f2[k] + c63*f3[k] + c64*f4[k] + c65*f5[k]; + } + + // 6) + k_rhs(0.0, ytmp, f6, userData); + + for (int k = 0; k < neq; k++) + { + //const double f6 = h * ydot[k]; + f6[k] *= h; + + // 5th-order solution. + const double r5 = b1*f1[k] + b3*f3[k] + b4*f4[k] + b5*f5[k] + b6*f6[k]; + + // 4th-order solution. + const double r4 = a1*f1[k] + a3*f3[k] + a4*f4[k] + a5*f5[k]; + + // Truncation error: difference between 4th and 5th-order solutions. + rwk[k] = fabs(r5 - r4); + + // Update solution. + //y_out[k] = y[k] + r5; // Local extrapolation + y_out[k] = y[k] + r4; + } + + return; +} + +template + template +int FixRxKokkos::k_rkf45_h0 + (const int neq, const double t, const double t_stop, + const double hmin, const double hmax, + double& h0, double y[], double rwk[], UserDataType& userData) const +{ + // Set lower and upper bounds on h0, and take geometric mean as first trial value. + // Exit with this value if the bounds cross each other. + + // Adjust upper bound based on ydot ... + double hg = sqrt(hmin*hmax); + + //if (hmax < hmin) + //{ + // h0 = hg; + // return; + //} + + // Start iteration to find solution to ... {WRMS norm of (h0^2 y'' / 2)} = 1 + + double *ydot = rwk; + double *y1 = ydot + neq; + double *ydot1 = y1 + neq; + + const int max_iters = 10; + bool hnew_is_ok = false; + double hnew = hg; + int iter = 0; + + // compute ydot at t=t0 + k_rhs (t, y, ydot, userData); + + while(1) + { + // Estimate y'' with finite-difference ... + + for (int k = 0; k < neq; k++) + y1[k] = y[k] + hg * ydot[k]; + + // compute y' at t1 + k_rhs (t + hg, y1, ydot1, userData); + + // Compute WRMS norm of y'' + double yddnrm = 0.0; + for (int k = 0; k < neq; k++){ + double ydd = (ydot1[k] - ydot[k]) / hg; + double wterr = ydd / (relTol * fabs( y[k] ) + absTol); + yddnrm += wterr * wterr; + } + + yddnrm = sqrt( yddnrm / double(neq) ); + + //std::cout << "iter " << _iter << " hg " << hg << " y'' " << yddnrm << std::endl; + //std::cout << "ydot " << ydot[neq-1] << std::endl; + + // should we accept this? + if (hnew_is_ok || iter == max_iters){ + hnew = hg; + if (iter == max_iters) + fprintf(stderr, "ERROR_HIN_MAX_ITERS\n"); + break; + } + + // Get the new value of h ... + hnew = (yddnrm*hmax*hmax > 2.0) ? sqrt(2.0 / yddnrm) : sqrt(hg * hmax); + + // test the stopping conditions. + double hrat = hnew / hg; + + // Accept this value ... the bias factor should bring it within range. + if ( (hrat > 0.5) && (hrat < 2.0) ) + hnew_is_ok = true; + + // If y'' is still bad after a few iterations, just accept h and give up. + if ( (iter > 1) && hrat > 2.0 ) { + hnew = hg; + hnew_is_ok = true; + } + + //printf("iter=%d, yddnrw=%e, hnew=%e, hmin=%e, hmax=%e\n", iter, yddnrm, hnew, hmin, hmax); + + hg = hnew; + iter ++; + } + + // bound and bias estimate + h0 = hnew * 0.5; + h0 = fmax(h0, hmin); + h0 = fmin(h0, hmax); + //printf("h0=%e, hmin=%e, hmax=%e\n", h0, hmin, hmax); + + return (iter + 1); +} + +template + template +void FixRxKokkos::k_rkf45(const int neq, const double t_stop, double *y, double *rwork, UserDataType& userData, CounterType& counter) const +{ + // Rounding coefficient. + const double uround = DBL_EPSILON; + + // Adaption limit (shrink or grow) + const double adaption_limit = 4.0; + + // Safety factor on the adaption. very specific but not necessary .. 0.9 is common. + const double hsafe = 0.840896415; + + // Time rounding factor. + const double tround = t_stop * uround; + + // Counters for diagnostics. + int nst = 0; // # of steps (accepted) + int nit = 0; // # of iterations total + int nfe = 0; // # of RHS evaluations + + // Min/Max step-size limits. + const double h_min = 100.0 * tround; + const double h_max = (minSteps > 0) ? t_stop / double(minSteps) : t_stop; + + // Set the initial step-size. 0 forces an internal estimate ... stable Euler step size. + double h = (minSteps > 0) ? t_stop / double(minSteps) : 0.0; + + double t = 0.0; + + if (h < h_min){ + //fprintf(stderr,"hin not implemented yet\n"); + //exit(-1); + nfe = k_rkf45_h0 (neq, t, t_stop, h_min, h_max, h, y, rwork, userData); + } + + //printf("t= %e t_stop= %e h= %e\n", t, t_stop, h); + + // Integrate until we reach the end time. + while (fabs(t - t_stop) > tround){ + double *yout = rwork; + double *eout = yout + neq; + + // Take a trial step. + k_rkf45_step (neq, h, y, yout, eout, userData); + + // Estimate the solution error. + // ... weighted 2-norm of the error. + double err2 = 0.0; + for (int k = 0; k < neq; k++){ + const double wterr = eout[k] / (relTol * fabs( y[k] ) + absTol); + err2 += wterr * wterr; + } + + double err = fmax( uround, sqrt( err2 / double(nspecies) )); + + // Accept the solution? + if (err <= 1.0 || h <= h_min){ + t += h; + nst++; + + for (int k = 0; k < neq; k++) + y[k] = yout[k]; + } + + // Adjust h for the next step. + double hfac = hsafe * sqrt( sqrt( 1.0 / err ) ); + + // Limit the adaption. + hfac = fmax( hfac, 1.0 / adaption_limit ); + hfac = fmin( hfac, adaption_limit ); + + // Apply the adaption factor... + h *= hfac; + + // Limit h. + h = fmin( h, h_max ); + h = fmax( h, h_min ); + + // Stretch h if we're within 5% ... and we didn't just fail. + if (err <= 1.0 && (t + 1.05*h) > t_stop) + h = t_stop - t; + + // And don't overshoot the end. + if (t + h > t_stop) + h = t_stop - t; + + nit++; + nfe += 6; + + if (maxIters && nit > maxIters){ + //fprintf(stderr,"atom[%d] took too many iterations in rkf45 %d %e %e\n", id, nit, t, t_stop); + counter.nFails ++; + break; + // We should set an error here so that the solution is not used! + } + + } // end while + + counter.nSteps += nst; + counter.nIters += nit; + counter.nFuncs += nfe; + + //printf("id= %d nst= %d nit= %d\n", id, nst, nit); +} +/* ---------------------------------------------------------------------- */ + // f1 = dt*f(t,x) // f2 = dt*f(t+ c20*dt,x + c21*f1) // f3 = dt*f(t+ c30*dt,x + c31*f1 + c32*f2) @@ -664,6 +1031,152 @@ int FixRxKokkos::rhs_sparse(double t, const double *y, double *dydt, /* ---------------------------------------------------------------------- */ +template + template +int FixRxKokkos::k_rhs(double t, const VectorType& y, VectorType& dydt, UserDataType& userData) const +{ + //StridedArrayType _y( const_cast( y ) ), _dydt( dydt ); + + // Use the sparse format instead. + if (useSparseKinetics) + return this->k_rhs_sparse( t, y, dydt, userData); + else + return this->k_rhs_dense ( t, y, dydt, userData); +} + +/* ---------------------------------------------------------------------- */ + +template + template +int FixRxKokkos::k_rhs_dense(double t, const VectorType& y, VectorType& dydt, UserDataType& userData) const +{ + #define rxnRateLaw (userData.rxnRateLaw) + #define kFor (userData.kFor ) + + //const double VDPD = domain->xprd * domain->yprd * domain->zprd / atom->natoms; + //const int nspecies = atom->nspecies_dpd; + + for(int ispecies=0; ispecies + template +int FixRxKokkos::k_rhs_sparse(double t, const VectorType& y, VectorType& dydt, UserDataType& userData) const +{ + #define kFor (userData.kFor) + #define kRev (NULL) + #define rxnRateLaw (userData.rxnRateLaw) + #define conc (dydt) + #define maxReactants (this->sparseKinetics_maxReactants) + #define maxSpecies (this->sparseKinetics_maxSpecies) + #define nuk (this->d_kineticsData.nuk) + #define nu (this->d_kineticsData.nu) + #define inu (this->d_kineticsData.inu) + #define isIntegral(idx) ( SparseKinetics_enableIntegralReactions \ + && this->d_kineticsData.isIntegral(idx) ) + + for (int k = 0; k < nspecies; ++k) + conc[k] = y[k] / VDPD; + + // Construct the reaction rate laws + for (int i = 0; i < nreactions; ++i) + { + double rxnRateLawForward; + if (isIntegral(i)){ + rxnRateLawForward = kFor[i] * powint( conc[ nuk(i,0) ], inu(i,0) ); + for (int kk = 1; kk < maxReactants; ++kk){ + const int k = nuk(i,kk); + if (k == SparseKinetics_invalidIndex) break; + //if (k != SparseKinetics_invalidIndex) + rxnRateLawForward *= powint( conc[k], inu(i,kk) ); + } + } else { + rxnRateLawForward = kFor[i] * pow( conc[ nuk(i,0) ], nu(i,0) ); + for (int kk = 1; kk < maxReactants; ++kk){ + const int k = nuk(i,kk); + if (k == SparseKinetics_invalidIndex) break; + //if (k != SparseKinetics_invalidIndex) + rxnRateLawForward *= pow( conc[k], nu(i,kk) ); + } + } + + rxnRateLaw[i] = rxnRateLawForward; + } + + // Construct the reaction rates for each species from the + // Stoichiometric matrix and ROP vector. + for (int k = 0; k < nspecies; ++k) + dydt[k] = 0.0; + + for (int i = 0; i < nreactions; ++i){ + // Reactants ... + dydt[ nuk(i,0) ] -= nu(i,0) * rxnRateLaw[i]; + for (int kk = 1; kk < maxReactants; ++kk){ + const int k = nuk(i,kk); + if (k == SparseKinetics_invalidIndex) break; + //if (k != SparseKinetics_invalidIndex) + dydt[k] -= nu(i,kk) * rxnRateLaw[i]; + } + + // Products ... + dydt[ nuk(i,maxReactants) ] += nu(i,maxReactants) * rxnRateLaw[i]; + for (int kk = maxReactants+1; kk < maxSpecies; ++kk){ + const int k = nuk(i,kk); + if (k == SparseKinetics_invalidIndex) break; + //if (k != SparseKinetics_invalidIndex) + dydt[k] += nu(i,kk) * rxnRateLaw[i]; + } + } + + // Add in the volume factor to convert to the proper units. + for (int k = 0; k < nspecies; ++k) + dydt[k] *= VDPD; + + #undef kFor + #undef kRev + #undef rxnRateLaw + #undef conc + #undef maxReactants + #undef maxSpecies + #undef nuk + #undef nu + #undef inu + #undef isIntegral + //#undef invalidIndex + + return 0; +} + +/* ---------------------------------------------------------------------- */ + /*template template KOKKOS_INLINE_FUNCTION @@ -907,6 +1420,10 @@ void FixRxKokkos::solve_reactions(const int vflag, const bool isPreF userData.kFor = new double[nreactions]; userData.rxnRateLaw = new double[nreactions]; + UserRHSDataKokkos<1> userDataKokkos; + userDataKokkos.kFor.m_data = userData.kFor; + userDataKokkos.rxnRateLaw.m_data = userData.rxnRateLaw; + CounterType counter_i; const double theta = (localTempFlag) ? d_dpdThetaLocal(i) : d_dpdTheta(i); @@ -935,7 +1452,8 @@ void FixRxKokkos::solve_reactions(const int vflag, const bool isPreF // Solver the ODE system. if (odeIntegrationFlag == ODE_LAMMPS_RK4) { - rk4(t_stop, y, rwork, &userData); + //rk4(t_stop, y, rwork, &userData); + k_rk4(t_stop, y, rwork, userDataKokkos); } else if (odeIntegrationFlag == ODE_LAMMPS_RKF45) { diff --git a/src/KOKKOS/fix_rx_kokkos.h b/src/KOKKOS/fix_rx_kokkos.h index 4a11ac9fb9..e36d606525 100644 --- a/src/KOKKOS/fix_rx_kokkos.h +++ b/src/KOKKOS/fix_rx_kokkos.h @@ -76,12 +76,43 @@ class FixRxKokkos : public FixRX { PairDPDfdtEnergyKokkos* pairDPDEKK; double VDPD; + template + struct StridedArrayType + { + typedef T value_type; + enum { Stride = stride }; + + value_type *m_data; + + StridedArrayType() : m_data(NULL) {} + StridedArrayType(value_type *ptr) : m_data(ptr) {} + + inline value_type& operator()(const int idx) { return m_data[Stride*idx]; } + inline const value_type& operator()(const int idx) const { return m_data[Stride*idx]; } + inline value_type& operator[](const int idx) { return m_data[Stride*idx]; } + inline const value_type& operator[](const int idx) const { return m_data[Stride*idx]; } + }; + + template + struct UserRHSDataKokkos + { + StridedArrayType kFor; + StridedArrayType rxnRateLaw; + }; + void solve_reactions(const int vflag, const bool isPreForce = true); - int rhs(double, const double *, double *, void *) const; + int rhs (double, const double *, double *, void *) const; int rhs_dense (double, const double *, double *, void *) const; int rhs_sparse(double, const double *, double *, void *) const; + template + int k_rhs (double, const VectorType&, VectorType&, UserDataType& ) const; + template + int k_rhs_dense (double, const VectorType&, VectorType&, UserDataType& ) const; + template + int k_rhs_sparse(double, const VectorType&, VectorType&, UserDataType& ) const; + //!< Classic Runge-Kutta 4th-order stepper. void rk4(const double t_stop, double *y, double *rwork, void *v_params) const; @@ -97,6 +128,25 @@ class FixRxKokkos : public FixRX { const double hmin, const double hmax, double& h0, double y[], double rwk[], void *v_params) const; + //!< Classic Runge-Kutta 4th-order stepper. + template + void k_rk4(const double t_stop, double *y, double *rwork, UserDataType& userData) const; + + //!< Runge-Kutta-Fehlberg ODE Solver. + template + void k_rkf45(const int neq, const double t_stop, double *y, double *rwork, UserDataType& userData, CounterType& counter) const; + + //!< Runge-Kutta-Fehlberg ODE stepper function. + template + void k_rkf45_step (const int neq, const double h, double y[], double y_out[], + double rwk[], UserDataType& userData) const; + + //!< Initial step size estimation for the Runge-Kutta-Fehlberg ODE solver. + template + int k_rkf45_h0 (const int neq, const double t, const double t_stop, + const double hmin, const double hmax, + double& h0, double y[], double rwk[], UserDataType& userData) const; + //!< ODE Solver diagnostics. void odeDiagnostics(void); From 2f32c1a9af6f8a8bb39c69f051552263dc313572 Mon Sep 17 00:00:00 2001 From: Christopher Stone Date: Sun, 12 Feb 2017 22:48:02 -0500 Subject: [PATCH 119/439] Switched to using Kokkos device data for ODE scratch data. - Finished porting all scratch arrays to using the StridedArrayType template. - Created a single, large Kokkos device array and using that for all scratch data passed into the StridedArrayType objects. --- src/KOKKOS/fix_rx_kokkos.cpp | 101 ++++++++++++++++++++--------------- src/KOKKOS/fix_rx_kokkos.h | 18 +++---- 2 files changed, 67 insertions(+), 52 deletions(-) diff --git a/src/KOKKOS/fix_rx_kokkos.cpp b/src/KOKKOS/fix_rx_kokkos.cpp index a6da0306bb..09a122a108 100644 --- a/src/KOKKOS/fix_rx_kokkos.cpp +++ b/src/KOKKOS/fix_rx_kokkos.cpp @@ -203,14 +203,14 @@ void FixRxKokkos::rk4(const double t_stop, double *y, double *rwork, /* ---------------------------------------------------------------------- */ template - template -void FixRxKokkos::k_rk4(const double t_stop, double *y, double *rwork, UserDataType& userData) const + template +void FixRxKokkos::k_rk4(const double t_stop, VectorType& y, VectorType& rwork, UserDataType& userData) const { - double *k1 = rwork; - double *k2 = k1 + nspecies; - double *k3 = k2 + nspecies; - double *k4 = k3 + nspecies; - double *yp = k4 + nspecies; + VectorType k1( rwork ); + VectorType k2( &k1[nspecies] ); + VectorType k3( &k2[nspecies] ); + VectorType k4( &k3[nspecies] ); + VectorType yp( &k4[nspecies] ); const int numSteps = minSteps; @@ -262,8 +262,8 @@ void FixRxKokkos::k_rk4(const double t_stop, double *y, double *rwor // x = x + a1*f1 + a3*f3 + a4*f4 + a5*f5 template - template -void FixRxKokkos::k_rkf45_step (const int neq, const double h, double y[], double y_out[], double rwk[], UserDataType& userData) const + template +void FixRxKokkos::k_rkf45_step (const int neq, const double h, VectorType& y, VectorType& y_out, VectorType& rwk, UserDataType& userData) const { const double c21=0.25; const double c31=0.09375; @@ -291,16 +291,15 @@ void FixRxKokkos::k_rkf45_step (const int neq, const double h, doubl const double b6=0.036363636363636; // local dependent variables (5 total) - double* f1 = &rwk[ 0]; - double* f2 = &rwk[ neq]; - double* f3 = &rwk[2*neq]; - double* f4 = &rwk[3*neq]; - double* f5 = &rwk[4*neq]; - double* f6 = &rwk[5*neq]; + VectorType& f1 = rwk; + VectorType f2( &rwk[ neq] ); + VectorType f3( &rwk[2*neq] ); + VectorType f4( &rwk[3*neq] ); + VectorType f5( &rwk[4*neq] ); + VectorType f6( &rwk[5*neq] ); // scratch for the intermediate solution. - //double* ytmp = &rwk[6*neq]; - double* ytmp = y_out; + VectorType& ytmp = y_out; // 1) k_rhs (0.0, y, f1, userData); @@ -368,11 +367,11 @@ void FixRxKokkos::k_rkf45_step (const int neq, const double h, doubl } template - template + template int FixRxKokkos::k_rkf45_h0 (const int neq, const double t, const double t_stop, const double hmin, const double hmax, - double& h0, double y[], double rwk[], UserDataType& userData) const + double& h0, VectorType& y, VectorType& rwk, UserDataType& userData) const { // Set lower and upper bounds on h0, and take geometric mean as first trial value. // Exit with this value if the bounds cross each other. @@ -388,9 +387,9 @@ int FixRxKokkos::k_rkf45_h0 // Start iteration to find solution to ... {WRMS norm of (h0^2 y'' / 2)} = 1 - double *ydot = rwk; - double *y1 = ydot + neq; - double *ydot1 = y1 + neq; + VectorType& ydot = rwk; + VectorType y1 ( &ydot[ neq] ); + VectorType ydot1 ( &ydot[2*neq] ); const int max_iters = 10; bool hnew_is_ok = false; @@ -463,8 +462,8 @@ int FixRxKokkos::k_rkf45_h0 } template - template -void FixRxKokkos::k_rkf45(const int neq, const double t_stop, double *y, double *rwork, UserDataType& userData, CounterType& counter) const + template +void FixRxKokkos::k_rkf45(const int neq, const double t_stop, VectorType& y, VectorType& rwork, UserDataType& userData, CounterType& counter) const { // Rounding coefficient. const double uround = DBL_EPSILON; @@ -501,9 +500,10 @@ void FixRxKokkos::k_rkf45(const int neq, const double t_stop, double //printf("t= %e t_stop= %e h= %e\n", t, t_stop, h); // Integrate until we reach the end time. - while (fabs(t - t_stop) > tround){ - double *yout = rwork; - double *eout = yout + neq; + while (fabs(t - t_stop) > tround) + { + VectorType& yout = rwork; + VectorType eout ( &yout[neq] ); // Take a trial step. k_rkf45_step (neq, h, y, yout, eout, userData); @@ -1035,8 +1035,6 @@ template template int FixRxKokkos::k_rhs(double t, const VectorType& y, VectorType& dydt, UserDataType& userData) const { - //StridedArrayType _y( const_cast( y ) ), _dydt( dydt ); - // Use the sparse format instead. if (useSparseKinetics) return this->k_rhs_sparse( t, y, dydt, userData); @@ -1409,20 +1407,36 @@ void FixRxKokkos::solve_reactions(const int vflag, const bool isPreF ); } + // Create scratch array space. + const size_t scratchSpaceSize = (8*nspecies + 2*nreactions); + //double *scratchSpace = new double[ scratchSpaceSize * nlocal ]; + + typename ArrayTypes::t_double_1d d_scratchSpace("d_scratchSpace", scratchSpaceSize * nlocal); + Kokkos::parallel_reduce( nlocal, LAMMPS_LAMBDA(int i, CounterType &counter) { if (d_mask(i) & groupbit) { - double *y = new double[8*nspecies]; - double *rwork = y + nspecies; + //double *y = new double[8*nspecies]; + //double *rwork = y + nspecies; - UserRHSData userData; - userData.kFor = new double[nreactions]; - userData.rxnRateLaw = new double[nreactions]; + //StridedArrayType _y( y ); + //StridedArrayType _rwork( rwork ); - UserRHSDataKokkos<1> userDataKokkos; - userDataKokkos.kFor.m_data = userData.kFor; - userDataKokkos.rxnRateLaw.m_data = userData.rxnRateLaw; + StridedArrayType y( d_scratchSpace.ptr_on_device() + scratchSpaceSize * i ); + StridedArrayType rwork( &y[nspecies] ); + + //UserRHSData userData; + //userData.kFor = new double[nreactions]; + //userData.rxnRateLaw = new double[nreactions]; + + //UserRHSDataKokkos<1> userDataKokkos; + //userDataKokkos.kFor.m_data = userData.kFor; + //userDataKokkos.rxnRateLaw.m_data = userData.rxnRateLaw; + + UserRHSDataKokkos<1> userData; + userData.kFor.m_data = &( rwork[7*nspecies] ); + userData.rxnRateLaw.m_data = &( userData.kFor[ nreactions ] ); CounterType counter_i; @@ -1452,12 +1466,11 @@ void FixRxKokkos::solve_reactions(const int vflag, const bool isPreF // Solver the ODE system. if (odeIntegrationFlag == ODE_LAMMPS_RK4) { - //rk4(t_stop, y, rwork, &userData); - k_rk4(t_stop, y, rwork, userDataKokkos); + k_rk4(t_stop, y, rwork, userData); } else if (odeIntegrationFlag == ODE_LAMMPS_RKF45) { - rkf45(nspecies, t_stop, y, rwork, &userData, counter_i); + k_rkf45(nspecies, t_stop, y, rwork, userData, counter_i); if (diagnosticFrequency == 1) { @@ -1477,9 +1490,9 @@ void FixRxKokkos::solve_reactions(const int vflag, const bool isPreF d_dvector(ispecies,i) = y[ispecies]; } - delete [] y; - delete [] userData.kFor; - delete [] userData.rxnRateLaw; + //delete [] y; + //delete [] userData.kFor; + //delete [] userData.rxnRateLaw; // Update the iteration statistics counter. Is this unique for each iteration? counter += counter_i; @@ -1490,6 +1503,8 @@ void FixRxKokkos::solve_reactions(const int vflag, const bool isPreF , TotalCounters // reduction value for all iterations. ); + //delete [] scratchSpace; + TimerType timer_ODE = getTimeStamp(); // Signal that dvector has been modified on this execution space. diff --git a/src/KOKKOS/fix_rx_kokkos.h b/src/KOKKOS/fix_rx_kokkos.h index e36d606525..9ac944c6a5 100644 --- a/src/KOKKOS/fix_rx_kokkos.h +++ b/src/KOKKOS/fix_rx_kokkos.h @@ -129,23 +129,23 @@ class FixRxKokkos : public FixRX { double& h0, double y[], double rwk[], void *v_params) const; //!< Classic Runge-Kutta 4th-order stepper. - template - void k_rk4(const double t_stop, double *y, double *rwork, UserDataType& userData) const; + template + void k_rk4(const double t_stop, VectorType& y, VectorType& rwork, UserDataType& userData) const; //!< Runge-Kutta-Fehlberg ODE Solver. - template - void k_rkf45(const int neq, const double t_stop, double *y, double *rwork, UserDataType& userData, CounterType& counter) const; + template + void k_rkf45(const int neq, const double t_stop, VectorType& y, VectorType& rwork, UserDataType& userData, CounterType& counter) const; //!< Runge-Kutta-Fehlberg ODE stepper function. - template - void k_rkf45_step (const int neq, const double h, double y[], double y_out[], - double rwk[], UserDataType& userData) const; + template + void k_rkf45_step (const int neq, const double h, VectorType& y, VectorType& y_out, + VectorType& rwk, UserDataType& userData) const; //!< Initial step size estimation for the Runge-Kutta-Fehlberg ODE solver. - template + template int k_rkf45_h0 (const int neq, const double t, const double t_stop, const double hmin, const double hmax, - double& h0, double y[], double rwk[], UserDataType& userData) const; + double& h0, VectorType& y, VectorType& rwk, UserDataType& userData) const; //!< ODE Solver diagnostics. void odeDiagnostics(void); From 4e9c8f496235016a5277a43e22f7bca5b85b4f10 Mon Sep 17 00:00:00 2001 From: Christopher Stone Date: Mon, 13 Feb 2017 10:48:30 -0500 Subject: [PATCH 120/439] Update FixRXKokkos for Cuda build. Added inline and other KOKKOS macros. - Updated the function prototypes to include the necessary KOKKOS macros for __host__ and __device__ functions and inlined functions. - Changed several View definitions to match the disjoint memory spaces that only come up with Cuda builds. --- src/KOKKOS/fix_rx_kokkos.cpp | 31 +++++++++++++++++++++++++------ src/KOKKOS/fix_rx_kokkos.h | 35 +++++++++++++++++++++++++---------- 2 files changed, 50 insertions(+), 16 deletions(-) diff --git a/src/KOKKOS/fix_rx_kokkos.cpp b/src/KOKKOS/fix_rx_kokkos.cpp index 09a122a108..71897157f3 100644 --- a/src/KOKKOS/fix_rx_kokkos.cpp +++ b/src/KOKKOS/fix_rx_kokkos.cpp @@ -25,13 +25,13 @@ #include "neigh_list_kokkos.h" #include "neigh_request.h" #include "error.h" -#include "math_special.h" +#include "math_special_kokkos.h" #include // DBL_EPSILON using namespace LAMMPS_NS; using namespace FixConst; -using namespace MathSpecial; +using namespace MathSpecialKokkos; #ifdef DBL_EPSILON #define MY_EPSILON (10.0*DBL_EPSILON) @@ -425,8 +425,8 @@ int FixRxKokkos::k_rkf45_h0 // should we accept this? if (hnew_is_ok || iter == max_iters){ hnew = hg; - if (iter == max_iters) - fprintf(stderr, "ERROR_HIN_MAX_ITERS\n"); + //if (iter == max_iters) + // fprintf(stderr, "ERROR_HIN_MAX_ITERS\n"); break; } @@ -1407,6 +1407,14 @@ void FixRxKokkos::solve_reactions(const int vflag, const bool isPreF ); } + // Error flag for any failures. + DAT::tdual_int_scalar k_error_flag("pair:error_flag"); + + // Initialize and sync the device flag. + k_error_flag.h_view() = 0; + k_error_flag.template modify(); + k_error_flag.template sync(); + // Create scratch array space. const size_t scratchSpaceSize = (8*nspecies + 2*nreactions); //double *scratchSpace = new double[ scratchSpaceSize * nlocal ]; @@ -1483,7 +1491,11 @@ void FixRxKokkos::solve_reactions(const int vflag, const bool isPreF for (int ispecies = 0; ispecies < nspecies; ispecies++) { if (y[ispecies] < -MY_EPSILON) - error->one(FLERR,"Computed concentration in RK solver is < -10*DBL_EPSILON"); + { + //error->one(FLERR,"Computed concentration in RK solver is < -10*DBL_EPSILON"); + k_error_flag.d_view() = 2; + // This should be an atomic update. + } else if (y[ispecies] < MY_EPSILON) y[ispecies] = 0.0; @@ -1507,6 +1519,12 @@ void FixRxKokkos::solve_reactions(const int vflag, const bool isPreF TimerType timer_ODE = getTimeStamp(); + // Check the error flag for any failures. + k_error_flag.template modify(); + k_error_flag.template sync(); + if (k_error_flag.h_view() == 2) + error->one(FLERR,"Computed concentration in RK solver is < -10*DBL_EPSILON"); + // Signal that dvector has been modified on this execution space. atomKK->modified( execution_space, DVECTOR_MASK ); @@ -1815,7 +1833,8 @@ void FixRxKokkos::computeLocalTemperature() { // Create an atomic view of sumWeights and dpdThetaLocal. Only needed // for Half/thread scenarios. - typedef Kokkos::View< E_FLOAT*, typename DAT::t_efloat_1d::array_layout, DeviceType, Kokkos::MemoryTraits< AtomicF< NEIGHFLAG >::value> > AtomicViewType; + //typedef Kokkos::View< E_FLOAT*, typename DAT::t_efloat_1d::array_layout, DeviceType, Kokkos::MemoryTraits< AtomicF< NEIGHFLAG >::value> > AtomicViewType; + typedef Kokkos::View< E_FLOAT*, typename DAT::t_efloat_1d::array_layout, typename DAT::t_efloat_1d::device_type, Kokkos::MemoryTraits< AtomicF< NEIGHFLAG >::value> > AtomicViewType; AtomicViewType a_dpdThetaLocal = d_dpdThetaLocal; AtomicViewType a_sumWeights = d_sumWeights; diff --git a/src/KOKKOS/fix_rx_kokkos.h b/src/KOKKOS/fix_rx_kokkos.h index 9ac944c6a5..c18ce6f151 100644 --- a/src/KOKKOS/fix_rx_kokkos.h +++ b/src/KOKKOS/fix_rx_kokkos.h @@ -49,6 +49,7 @@ class FixRxKokkos : public FixRX { { int nSteps, nIters, nFuncs, nFails; + KOKKOS_INLINE_FUNCTION CounterType() : nSteps(0), nIters(0), nFuncs(0), nFails(0) {}; KOKKOS_INLINE_FUNCTION @@ -72,7 +73,7 @@ class FixRxKokkos : public FixRX { } }; - protected: + //protected: PairDPDfdtEnergyKokkos* pairDPDEKK; double VDPD; @@ -84,13 +85,15 @@ class FixRxKokkos : public FixRX { value_type *m_data; + KOKKOS_INLINE_FUNCTION StridedArrayType() : m_data(NULL) {} + KOKKOS_INLINE_FUNCTION StridedArrayType(value_type *ptr) : m_data(ptr) {} - inline value_type& operator()(const int idx) { return m_data[Stride*idx]; } - inline const value_type& operator()(const int idx) const { return m_data[Stride*idx]; } - inline value_type& operator[](const int idx) { return m_data[Stride*idx]; } - inline const value_type& operator[](const int idx) const { return m_data[Stride*idx]; } + KOKKOS_INLINE_FUNCTION value_type& operator()(const int idx) { return m_data[Stride*idx]; } + KOKKOS_INLINE_FUNCTION const value_type& operator()(const int idx) const { return m_data[Stride*idx]; } + KOKKOS_INLINE_FUNCTION value_type& operator[](const int idx) { return m_data[Stride*idx]; } + KOKKOS_INLINE_FUNCTION const value_type& operator[](const int idx) const { return m_data[Stride*idx]; } }; template @@ -100,17 +103,22 @@ class FixRxKokkos : public FixRX { StridedArrayType rxnRateLaw; }; - void solve_reactions(const int vflag, const bool isPreForce = true); + void solve_reactions(const int vflag, const bool isPreForce); int rhs (double, const double *, double *, void *) const; int rhs_dense (double, const double *, double *, void *) const; int rhs_sparse(double, const double *, double *, void *) const; template + KOKKOS_INLINE_FUNCTION int k_rhs (double, const VectorType&, VectorType&, UserDataType& ) const; + template + KOKKOS_INLINE_FUNCTION int k_rhs_dense (double, const VectorType&, VectorType&, UserDataType& ) const; + template + KOKKOS_INLINE_FUNCTION int k_rhs_sparse(double, const VectorType&, VectorType&, UserDataType& ) const; //!< Classic Runge-Kutta 4th-order stepper. @@ -130,19 +138,23 @@ class FixRxKokkos : public FixRX { //!< Classic Runge-Kutta 4th-order stepper. template + KOKKOS_INLINE_FUNCTION void k_rk4(const double t_stop, VectorType& y, VectorType& rwork, UserDataType& userData) const; //!< Runge-Kutta-Fehlberg ODE Solver. template + KOKKOS_INLINE_FUNCTION void k_rkf45(const int neq, const double t_stop, VectorType& y, VectorType& rwork, UserDataType& userData, CounterType& counter) const; //!< Runge-Kutta-Fehlberg ODE stepper function. template + KOKKOS_INLINE_FUNCTION void k_rkf45_step (const int neq, const double h, VectorType& y, VectorType& y_out, VectorType& rwk, UserDataType& userData) const; //!< Initial step size estimation for the Runge-Kutta-Fehlberg ODE solver. template + KOKKOS_INLINE_FUNCTION int k_rkf45_h0 (const int neq, const double t, const double t_stop, const double hmin, const double hmax, double& h0, VectorType& y, VectorType& rwk, UserDataType& userData) const; @@ -155,8 +167,10 @@ class FixRxKokkos : public FixRX { int *diagnosticCounterPerODEnFuncs; DAT::tdual_int_1d k_diagnosticCounterPerODEnSteps; DAT::tdual_int_1d k_diagnosticCounterPerODEnFuncs; - typename ArrayTypes::t_int_1d d_diagnosticCounterPerODEnSteps; - typename ArrayTypes::t_int_1d d_diagnosticCounterPerODEnFuncs; + //typename ArrayTypes::t_int_1d d_diagnosticCounterPerODEnSteps; + //typename ArrayTypes::t_int_1d d_diagnosticCounterPerODEnFuncs; + typename DAT::t_int_1d d_diagnosticCounterPerODEnSteps; + typename DAT::t_int_1d d_diagnosticCounterPerODEnFuncs; typename HAT::t_int_1d h_diagnosticCounterPerODEnSteps; typename HAT::t_int_1d h_diagnosticCounterPerODEnFuncs; @@ -185,7 +199,8 @@ class FixRxKokkos : public FixRX { // Need a dual-view and device-view for dpdThetaLocal and sumWeights since they're used in several callbacks. DAT::tdual_efloat_1d k_dpdThetaLocal, k_sumWeights; - typename ArrayTypes::t_efloat_1d d_dpdThetaLocal, d_sumWeights; + //typename ArrayTypes::t_efloat_1d d_dpdThetaLocal, d_sumWeights; + typename DAT::t_efloat_1d d_dpdThetaLocal, d_sumWeights; typename HAT::t_efloat_1d h_dpdThetaLocal, h_sumWeights; template @@ -196,7 +211,7 @@ class FixRxKokkos : public FixRX { int pack_forward_comm(int , int *, double *, int, int *); void unpack_forward_comm(int , int , double *); - private: // replicate a few from FixRX + //private: // replicate a few from FixRX int my_restartFlag; }; From 799d55e0971331c6b54527b38ec991b2f1a08212 Mon Sep 17 00:00:00 2001 From: Christopher Stone Date: Mon, 13 Feb 2017 14:24:51 -0500 Subject: [PATCH 121/439] Switched to operator()'s and Tag's for the Kokkos launch objects. - Switched from using lambda functions to operator()'s with type tags in FixRxKokkos. The lambda's were giving big problems in Cuda with the memory objects. This required that all referenced views be members of the FixRXKokkos class. - Add copymode controls to solve_reactions() to avoid the destructor freeing pointers carried forward from the copy constructor. Added the same to FixRX since its called, too. --- src/KOKKOS/fix_rx_kokkos.cpp | 316 ++++++++++++++++++++++++++++++----- src/KOKKOS/fix_rx_kokkos.h | 109 +++++++++--- src/USER-DPD/fix_rx.cpp | 3 + 3 files changed, 361 insertions(+), 67 deletions(-) diff --git a/src/KOKKOS/fix_rx_kokkos.cpp b/src/KOKKOS/fix_rx_kokkos.cpp index 71897157f3..77e948be35 100644 --- a/src/KOKKOS/fix_rx_kokkos.cpp +++ b/src/KOKKOS/fix_rx_kokkos.cpp @@ -69,13 +69,16 @@ FixRxKokkos::FixRxKokkos(LAMMPS *lmp, int narg, char **arg) : datamask_read = EMPTY_MASK; datamask_modify = EMPTY_MASK; + k_error_flag = DAT::tdual_int_scalar("FixRxKokkos::k_error_flag"); + printf("Inside FixRxKokkos::FixRxKokkos\n"); } template FixRxKokkos::~FixRxKokkos() { - printf("Inside FixRxKokkos::~FixRxKokkos\n"); + printf("Inside FixRxKokkos::~FixRxKokkos copymode= %d\n", copymode); + if (copymode) return; } /* ---------------------------------------------------------------------- */ @@ -1315,6 +1318,95 @@ void FixRxKokkos::pre_force(int vflag) this->solve_reactions( vflag, true ); } + +/* ---------------------------------------------------------------------- */ + +template + KOKKOS_INLINE_FUNCTION +void FixRxKokkos::operator()(Tag_FixRxKokkos_zeroCounterViews, const int& i) const +{ + d_diagnosticCounterPerODEnSteps(i) = 0; + d_diagnosticCounterPerODEnFuncs(i) = 0; +} + +/* ---------------------------------------------------------------------- */ + +template + template + KOKKOS_INLINE_FUNCTION +void FixRxKokkos::operator()(Tag_FixRxKokkos_solveSystems, const int& i, CounterType& counter) const +{ + if (d_mask(i) & groupbit) + { + StridedArrayType y( d_scratchSpace.ptr_on_device() + scratchSpaceSize * i ); + StridedArrayType rwork( &y[nspecies] ); + + UserRHSDataKokkos<1> userData; + userData.kFor.m_data = &( rwork[7*nspecies] ); + userData.rxnRateLaw.m_data = &( userData.kFor[ nreactions ] ); + + CounterType counter_i; + + const double theta = (localTempFlag) ? d_dpdThetaLocal(i) : d_dpdTheta(i); + + //Compute the reaction rate constants + for (int irxn = 0; irxn < nreactions; irxn++) + { + if (ZERO_RATES) + userData.kFor[irxn] = 0.0; + else + { + userData.kFor[irxn] = d_kineticsData.Arr(irxn) * + pow(theta, d_kineticsData.nArr(irxn)) * + exp(-d_kineticsData.Ea(irxn) / boltz / theta); + } + } + + // Update ConcOld and initialize the ODE solution vector y[]. + for (int ispecies = 0; ispecies < nspecies; ispecies++) + { + const double tmp = d_dvector(ispecies, i); + d_dvector(ispecies+nspecies, i) = tmp; + y[ispecies] = tmp; + } + + // Solver the ODE system. + if (odeIntegrationFlag == ODE_LAMMPS_RK4) + { + k_rk4(t_stop, y, rwork, userData); + } + else if (odeIntegrationFlag == ODE_LAMMPS_RKF45) + { + k_rkf45(nspecies, t_stop, y, rwork, userData, counter_i); + + if (diagnosticFrequency == 1) + { + d_diagnosticCounterPerODEnSteps(i) = counter_i.nSteps; + d_diagnosticCounterPerODEnFuncs(i) = counter_i.nFuncs; + } + } + + // Store the solution back in dvector. + for (int ispecies = 0; ispecies < nspecies; ispecies++) + { + if (y[ispecies] < -MY_EPSILON) + { + //error->one(FLERR,"Computed concentration in RK solver is < -10*DBL_EPSILON"); + k_error_flag.d_view() = 2; + // This should be an atomic update. + } + else if (y[ispecies] < MY_EPSILON) + y[ispecies] = 0.0; + + d_dvector(ispecies,i) = y[ispecies]; + } + + // Update the iteration statistics counter. Is this unique for each iteration? + counter += counter_i; + + } // if +} + /* ---------------------------------------------------------------------- */ template @@ -1322,12 +1414,15 @@ void FixRxKokkos::solve_reactions(const int vflag, const bool isPreF { printf("Inside FixRxKokkos::solve_reactions localTempFlag= %d isPreForce= %s\n", localTempFlag, isPreForce ? "True" : "false"); + copymode = 1; + if (update_kinetics_data) create_kinetics_data(); TimerType timer_start = getTimeStamp(); - const int nlocal = atom->nlocal; + //const int nlocal = atom->nlocal; + this->nlocal = atom->nlocal; const int nghost = atom->nghost; const int newton_pair = force->newton_pair; @@ -1339,8 +1434,8 @@ void FixRxKokkos::solve_reactions(const int vflag, const bool isPreF const int count = nlocal + (newton_pair ? nghost : 0); memory->create_kokkos (k_dpdThetaLocal, dpdThetaLocal, count, "FixRxKokkos::dpdThetaLocal"); - d_dpdThetaLocal = k_dpdThetaLocal.d_view; - h_dpdThetaLocal = k_dpdThetaLocal.h_view; + this->d_dpdThetaLocal = k_dpdThetaLocal.d_view; + this->h_dpdThetaLocal = k_dpdThetaLocal.h_view; const int neighflag = lmp->kokkos->neighflag; @@ -1376,16 +1471,21 @@ void FixRxKokkos::solve_reactions(const int vflag, const bool isPreF // ... // Local references to the atomKK objects. - typename ArrayTypes::t_efloat_1d d_dpdTheta = atomKK->k_dpdTheta.view(); - typename ArrayTypes::t_float_2d d_dvector = atomKK->k_dvector.view(); - typename ArrayTypes::t_int_1d d_mask = atomKK->k_mask.view(); + //typename ArrayTypes::t_efloat_1d d_dpdTheta = atomKK->k_dpdTheta.view(); + //typename ArrayTypes::t_float_2d d_dvector = atomKK->k_dvector.view(); + //typename ArrayTypes::t_int_1d d_mask = atomKK->k_mask.view(); + this->d_dpdTheta = atomKK->k_dpdTheta.view(); + this->d_dvector = atomKK->k_dvector.view(); + this->d_mask = atomKK->k_mask.view(); // Get up-to-date data. atomKK->sync( execution_space, MASK_MASK | DVECTOR_MASK | DPDTHETA_MASK ); // Set some constants outside of the parallel_for - const double boltz = force->boltz; - const double t_stop = update->dt; // DPD time-step and integration length. + //const double boltz = force->boltz; + //const double t_stop = update->dt; // DPD time-step and integration length. + this->boltz = force->boltz; + this->t_stop = update->dt; // DPD time-step and integration length. // Average DPD volume. Used in the RHS function. this->VDPD = domain->xprd * domain->yprd * domain->zprd / atom->natoms; @@ -1398,17 +1498,18 @@ void FixRxKokkos::solve_reactions(const int vflag, const bool isPreF d_diagnosticCounterPerODEnSteps = k_diagnosticCounterPerODEnSteps.d_view; d_diagnosticCounterPerODEnFuncs = k_diagnosticCounterPerODEnFuncs.d_view; - Kokkos::parallel_for ( nlocal, - LAMMPS_LAMBDA(const int i) - { - d_diagnosticCounterPerODEnSteps(i) = 0; - d_diagnosticCounterPerODEnFuncs(i) = 0; - } - ); + Kokkos::parallel_for ( Kokkos::RangePolicy(0,nlocal), *this); + //Kokkos::parallel_for ( nlocal, + // LAMMPS_LAMBDA(const int i) + // { + // d_diagnosticCounterPerODEnSteps(i) = 0; + // d_diagnosticCounterPerODEnFuncs(i) = 0; + // } + // ); } // Error flag for any failures. - DAT::tdual_int_scalar k_error_flag("pair:error_flag"); + //DAT::tdual_int_scalar k_error_flag("pair:error_flag"); // Initialize and sync the device flag. k_error_flag.h_view() = 0; @@ -1416,11 +1517,14 @@ void FixRxKokkos::solve_reactions(const int vflag, const bool isPreF k_error_flag.template sync(); // Create scratch array space. - const size_t scratchSpaceSize = (8*nspecies + 2*nreactions); + //const size_t scratchSpaceSize = (8*nspecies + 2*nreactions); + this->scratchSpaceSize = (8*nspecies + 2*nreactions); //double *scratchSpace = new double[ scratchSpaceSize * nlocal ]; - typename ArrayTypes::t_double_1d d_scratchSpace("d_scratchSpace", scratchSpaceSize * nlocal); + //typename ArrayTypes::t_double_1d d_scratchSpace("d_scratchSpace", scratchSpaceSize * nlocal); + memory->create_kokkos (d_scratchSpace, nlocal*scratchSpaceSize, "FixRxKokkos::d_scratchSpace"); +#if 0 Kokkos::parallel_reduce( nlocal, LAMMPS_LAMBDA(int i, CounterType &counter) { if (d_mask(i) & groupbit) @@ -1514,8 +1618,15 @@ void FixRxKokkos::solve_reactions(const int vflag, const bool isPreF , TotalCounters // reduction value for all iterations. ); +#else + if (setRatesToZero) + Kokkos::parallel_reduce( Kokkos::RangePolicy >(0,nlocal), *this, TotalCounters); + else + Kokkos::parallel_reduce( Kokkos::RangePolicy >(0,nlocal), *this, TotalCounters); +#endif //delete [] scratchSpace; + memory->destroy_kokkos (d_scratchSpace); TimerType timer_ODE = getTimeStamp(); @@ -1570,6 +1681,8 @@ void FixRxKokkos::solve_reactions(const int vflag, const bool isPreF (diagnosticFrequency < 0 && update->ntimestep == update->laststep) ) this->odeDiagnostics(); } + + copymode = 0; } /* ---------------------------------------------------------------------- */ @@ -1654,7 +1767,8 @@ void FixRxKokkos::odeDiagnostics(void) double my_max[numCounters], my_min[numCounters]; - const int nlocal = atom->nlocal; + //const int nlocal = atom->nlocal; + nlocal = atom->nlocal; HAT::t_int_1d h_mask = atomKK->k_mask.h_view; for (int i = 0; i < numCounters; ++i) @@ -1760,17 +1874,122 @@ void FixRxKokkos::odeDiagnostics(void) /* ---------------------------------------------------------------------- */ +template + KOKKOS_INLINE_FUNCTION +void FixRxKokkos::operator()(Tag_FixRxKokkos_zeroTemperatureViews, const int& i) const +{ + d_sumWeights(i) = 0.0; + d_dpdThetaLocal(i) = 0.0; +} + +/* ---------------------------------------------------------------------- */ + +template + template + KOKKOS_INLINE_FUNCTION +void FixRxKokkos::operator()(Tag_FixRxKokkos_firstPairOperator, const int& ii) const +{ + // Create an atomic view of sumWeights and dpdThetaLocal. Only needed + // for Half/thread scenarios. + typedef Kokkos::View< E_FLOAT*, typename DAT::t_efloat_1d::array_layout, typename DAT::t_efloat_1d::device_type, Kokkos::MemoryTraits< AtomicF< NEIGHFLAG >::value> > AtomicViewType; + + AtomicViewType a_dpdThetaLocal = d_dpdThetaLocal; + AtomicViewType a_sumWeights = d_sumWeights; + + // Local scalar accumulators. + double i_dpdThetaLocal = 0.0; + double i_sumWeights = 0.0; + + const int i = d_ilist(ii); + + const double xtmp = d_x(i,0); + const double ytmp = d_x(i,1); + const double ztmp = d_x(i,2); + const int itype = d_type(i); + + const int jnum = d_numneigh(i); + + for (int jj = 0; jj < jnum; jj++) + { + const int j = (d_neighbors(i,jj) & NEIGHMASK); + const int jtype = d_type(j); + + const double delx = xtmp - d_x(j,0); + const double dely = ytmp - d_x(j,1); + const double delz = ztmp - d_x(j,2); + const double rsq = delx*delx + dely*dely + delz*delz; + + const double cutsq_ij = d_cutsq(itype,jtype); + + if (rsq < cutsq_ij) + { + const double rcut = sqrt( cutsq_ij ); + double rij = sqrt(rsq); + double ratio = rij/rcut; + + double wij = 0.0; + + // Lucy's Weight Function + if (WT_FLAG == LUCY) + { + wij = (1.0+3.0*ratio) * (1.0-ratio)*(1.0-ratio)*(1.0-ratio); + i_dpdThetaLocal += wij / d_dpdTheta(j); + if (NEWTON_PAIR || j < nlocal) + a_dpdThetaLocal(j) += wij / d_dpdTheta(i); + } + + i_sumWeights += wij; + if (NEWTON_PAIR || j < nlocal) + a_sumWeights(j) += wij; + } + } + + // Update, don't assign, the array value (because another iteration may have hit it). + a_dpdThetaLocal(i) += i_dpdThetaLocal; + a_sumWeights(i) += i_sumWeights; +} + +/* ---------------------------------------------------------------------- */ + +template + template + KOKKOS_INLINE_FUNCTION +void FixRxKokkos::operator()(Tag_FixRxKokkos_2ndPairOperator, const int& i) const +{ + double wij = 0.0; + + // Lucy Weight Function + if (WT_FLAG == LUCY) + { + wij = 1.0; + d_dpdThetaLocal(i) += wij / d_dpdTheta(i); + } + d_sumWeights(i) += wij; + + // Normalized local temperature + d_dpdThetaLocal(i) = d_dpdThetaLocal(i) / d_sumWeights(i); + + if (LOCAL_TEMP_FLAG == HARMONIC) + d_dpdThetaLocal(i) = 1.0 / d_dpdThetaLocal(i); +} + +/* ---------------------------------------------------------------------- */ + template template void FixRxKokkos::computeLocalTemperature() { - typename ArrayTypes::t_x_array_randomread d_x = atomKK->k_x.view(); - typename ArrayTypes::t_int_1d_randomread d_type = atomKK->k_type.view(); - typename ArrayTypes::t_efloat_1d d_dpdTheta = atomKK->k_dpdTheta.view(); + //typename ArrayTypes::t_x_array_randomread d_x = atomKK->k_x.view(); + //typename ArrayTypes::t_int_1d_randomread d_type = atomKK->k_type.view(); + //typename ArrayTypes::t_efloat_1d d_dpdTheta = atomKK->k_dpdTheta.view(); + d_x = atomKK->k_x.view(); + d_type = atomKK->k_type.view(); + d_dpdTheta = atomKK->k_dpdTheta.view(); atomKK->sync(execution_space, X_MASK | TYPE_MASK | DPDTHETA_MASK ); - const int nlocal = atom->nlocal; + //const int nlocal = atom->nlocal; + nlocal = atom->nlocal; const int nghost = atom->nghost; printf("Inside FixRxKokkos::computeLocalTemperature: %d %d %d %d %d %d %d\n", WT_FLAG, LOCAL_TEMP_FLAG, NEWTON_PAIR, (int)lmp->kokkos->neighflag, NEIGHFLAG, nlocal, nghost); @@ -1780,14 +1999,15 @@ void FixRxKokkos::computeLocalTemperature() //typename ArrayTypes::t_ffloat_2d d_cutsq = pairDPDEKK->k_cutsq.template view::tdual_ffloat_2d k_cutsq; - typename ArrayTypes::t_ffloat_2d d_cutsq; - double **h_cutsq; + //typename ArrayTypes::tdual_ffloat_2d k_cutsq; + //typename ArrayTypes::t_ffloat_2d d_cutsq; + //double **h_cutsq; { const int ntypes = atom->ntypes; - memory->create_kokkos (k_cutsq, h_cutsq, ntypes+1, ntypes+1, "pair:cutsq"); + //memory->create_kokkos (k_cutsq, h_cutsq, ntypes+1, ntypes+1, "pair:cutsq"); + memory->create_kokkos (k_cutsq, ntypes+1, ntypes+1, "FixRxKokkos::k_cutsq"); d_cutsq = k_cutsq.template view(); for (int i = 1; i <= ntypes; ++i) @@ -1804,30 +2024,37 @@ void FixRxKokkos::computeLocalTemperature() // Initialize the local temperature weight array int sumWeightsCt = nlocal + (NEWTON_PAIR ? nghost : 0); - memory->create_kokkos (k_sumWeights, sumWeights, sumWeightsCt, "FixRxKokkos::sumWeights"); + //memory->create_kokkos (k_sumWeights, sumWeights, sumWeightsCt, "FixRxKokkos::sumWeights"); + memory->create_kokkos (k_sumWeights, sumWeightsCt, "FixRxKokkos::sumWeights"); d_sumWeights = k_sumWeights.d_view; h_sumWeights = k_sumWeights.h_view; // Initialize the accumulator to zero ... - Kokkos::parallel_for (sumWeightsCt, - LAMMPS_LAMBDA(const int i) - { - d_sumWeights(i) = 0.0; - } - ); + //Kokkos::parallel_for (sumWeightsCt, + // LAMMPS_LAMBDA(const int i) + // { + // d_sumWeights(i) = 0.0; + // } + // ); + + Kokkos::parallel_for (Kokkos::RangePolicy(0, sumWeightsCt), *this); // Local list views. (This isn't working!) NeighListKokkos* k_list = static_cast*>(list); if (not(list->kokkos)) error->one(FLERR,"list is not a Kokkos list\n"); - typename ArrayTypes::t_neighbors_2d d_neighbors = k_list->d_neighbors; - typename ArrayTypes::t_int_1d d_ilist = k_list->d_ilist; - typename ArrayTypes::t_int_1d d_numneigh = k_list->d_numneigh; + //typename ArrayTypes::t_neighbors_2d d_neighbors = k_list->d_neighbors; + //typename ArrayTypes::t_int_1d d_ilist = k_list->d_ilist; + //typename ArrayTypes::t_int_1d d_numneigh = k_list->d_numneigh; + d_neighbors = k_list->d_neighbors; + d_ilist = k_list->d_ilist; + d_numneigh = k_list->d_numneigh; const int inum = list->inum; // loop over neighbors of my atoms +#if 0 Kokkos::parallel_for ( inum, LAMMPS_LAMBDA(const int ii) { @@ -1892,6 +2119,9 @@ void FixRxKokkos::computeLocalTemperature() a_sumWeights(i) += i_sumWeights; } ); +#else + Kokkos::parallel_for (Kokkos::RangePolicy >(0, inum), *this); +#endif // Signal that dpdThetaLocal and sumWeights have been modified. k_dpdThetaLocal.template modify(); @@ -1905,6 +2135,7 @@ void FixRxKokkos::computeLocalTemperature() k_sumWeights. template sync(); // self-interaction for local temperature +#if 0 Kokkos::parallel_for ( nlocal, LAMMPS_LAMBDA(const int i) { @@ -1925,10 +2156,15 @@ void FixRxKokkos::computeLocalTemperature() d_dpdThetaLocal(i) = 1.0 / d_dpdThetaLocal(i); } ); +#else + Kokkos::parallel_for (Kokkos::RangePolicy >(0, nlocal), *this); +#endif // Clean up the local kokkos data. - memory->destroy_kokkos(k_cutsq, h_cutsq); - memory->destroy_kokkos(k_sumWeights, sumWeights); + //memory->destroy_kokkos(k_cutsq, h_cutsq); + memory->destroy_kokkos(k_cutsq); + //memory->destroy_kokkos(k_sumWeights, sumWeights); + memory->destroy_kokkos(k_sumWeights); } /* ---------------------------------------------------------------------- */ diff --git a/src/KOKKOS/fix_rx_kokkos.h b/src/KOKKOS/fix_rx_kokkos.h index c18ce6f151..169a87a2f9 100644 --- a/src/KOKKOS/fix_rx_kokkos.h +++ b/src/KOKKOS/fix_rx_kokkos.h @@ -30,6 +30,47 @@ FixStyle(rx/kk/host,FixRxKokkos) namespace LAMMPS_NS { +struct Tag_FixRxKokkos_zeroTemperatureViews {}; +struct Tag_FixRxKokkos_zeroCounterViews {}; + +template +struct Tag_FixRxKokkos_firstPairOperator {}; + +template +struct Tag_FixRxKokkos_2ndPairOperator {}; + +template +struct Tag_FixRxKokkos_solveSystems {}; + +struct s_CounterType +{ + int nSteps, nIters, nFuncs, nFails; + + KOKKOS_INLINE_FUNCTION + s_CounterType() : nSteps(0), nIters(0), nFuncs(0), nFails(0) {}; + + KOKKOS_INLINE_FUNCTION + s_CounterType& operator+=(const s_CounterType &rhs) + { + nSteps += rhs.nSteps; + nIters += rhs.nIters; + nFuncs += rhs.nFuncs; + nFails += rhs.nFails; + return *this; + } + + KOKKOS_INLINE_FUNCTION + volatile s_CounterType& operator+=(const volatile s_CounterType &rhs) volatile + { + nSteps += rhs.nSteps; + nIters += rhs.nIters; + nFuncs += rhs.nFuncs; + nFails += rhs.nFails; + return *this; + } +}; +typedef struct s_CounterType CounterType; + template class FixRxKokkos : public FixRX { public: @@ -41,42 +82,34 @@ class FixRxKokkos : public FixRX { virtual void setup_pre_force(int); virtual void pre_force(int); - //template - // KOKKOS_INLINE_FUNCTION - //void operator()(SolverTag, const int&) const; + // Define a value_type here for the reduction operator on CounterType. + typedef CounterType value_type; - struct CounterType - { - int nSteps, nIters, nFuncs, nFails; + KOKKOS_INLINE_FUNCTION + void operator()(Tag_FixRxKokkos_zeroCounterViews, const int&) const; - KOKKOS_INLINE_FUNCTION - CounterType() : nSteps(0), nIters(0), nFuncs(0), nFails(0) {}; + KOKKOS_INLINE_FUNCTION + void operator()(Tag_FixRxKokkos_zeroTemperatureViews, const int&) const; - KOKKOS_INLINE_FUNCTION - CounterType& operator+=(const CounterType &rhs) - { - nSteps += rhs.nSteps; - nIters += rhs.nIters; - nFuncs += rhs.nFuncs; - nFails += rhs.nFails; - return *this; - } + template + KOKKOS_INLINE_FUNCTION + void operator()(Tag_FixRxKokkos_firstPairOperator, const int&) const; - KOKKOS_INLINE_FUNCTION - volatile CounterType& operator+=(const volatile CounterType &rhs) volatile - { - nSteps += rhs.nSteps; - nIters += rhs.nIters; - nFuncs += rhs.nFuncs; - nFails += rhs.nFails; - return *this; - } - }; + template + KOKKOS_INLINE_FUNCTION + void operator()(Tag_FixRxKokkos_2ndPairOperator, const int&) const; + + template + KOKKOS_INLINE_FUNCTION + void operator()(Tag_FixRxKokkos_solveSystems, const int&, CounterType&) const; //protected: PairDPDfdtEnergyKokkos* pairDPDEKK; double VDPD; + double boltz; + double t_stop; + template struct StridedArrayType { @@ -203,6 +236,27 @@ class FixRxKokkos : public FixRX { typename DAT::t_efloat_1d d_dpdThetaLocal, d_sumWeights; typename HAT::t_efloat_1d h_dpdThetaLocal, h_sumWeights; + typename ArrayTypes::t_x_array_randomread d_x ; + typename ArrayTypes::t_int_1d_randomread d_type ; + typename ArrayTypes::t_efloat_1d d_dpdTheta; + + typename ArrayTypes::tdual_ffloat_2d k_cutsq; + typename ArrayTypes::t_ffloat_2d d_cutsq; + //double **h_cutsq; + + typename ArrayTypes::t_neighbors_2d d_neighbors; + typename ArrayTypes::t_int_1d d_ilist ; + typename ArrayTypes::t_int_1d d_numneigh ; + + typename ArrayTypes::t_float_2d d_dvector; + typename ArrayTypes::t_int_1d d_mask ; + + typename ArrayTypes::t_double_1d d_scratchSpace; + size_t scratchSpaceSize; + + // Error flag for any failures. + DAT::tdual_int_scalar k_error_flag; + template void computeLocalTemperature(); @@ -213,6 +267,7 @@ class FixRxKokkos : public FixRX { //private: // replicate a few from FixRX int my_restartFlag; + int nlocal; }; } diff --git a/src/USER-DPD/fix_rx.cpp b/src/USER-DPD/fix_rx.cpp index 28321dbecf..8a8195da19 100644 --- a/src/USER-DPD/fix_rx.cpp +++ b/src/USER-DPD/fix_rx.cpp @@ -220,6 +220,9 @@ FixRX::FixRX(LAMMPS *lmp, int narg, char **arg) : FixRX::~FixRX() { + printf("Inside FixRX::~FixRX copymode= %d\n", copymode); + if (copymode) return; + // De-Allocate memory to prevent memory leak for (int ii = 0; ii < nreactions; ii++){ delete [] stoich[ii]; From acc5bde0fe53a2e9052ee7a27ceafb42acbea114 Mon Sep 17 00:00:00 2001 From: Christopher Stone Date: Mon, 13 Feb 2017 16:36:30 -0500 Subject: [PATCH 122/439] Removed printf's from FixRXKokkos and FixRX. - Commented out the printf's in FixRXKokkos and FixRX used for active debugging. --- src/KOKKOS/fix_rx_kokkos.cpp | 28 ++++++++++++++-------------- src/USER-DPD/fix_rx.cpp | 18 +++++++++--------- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/KOKKOS/fix_rx_kokkos.cpp b/src/KOKKOS/fix_rx_kokkos.cpp index 77e948be35..08a20ac9a7 100644 --- a/src/KOKKOS/fix_rx_kokkos.cpp +++ b/src/KOKKOS/fix_rx_kokkos.cpp @@ -71,13 +71,13 @@ FixRxKokkos::FixRxKokkos(LAMMPS *lmp, int narg, char **arg) : k_error_flag = DAT::tdual_int_scalar("FixRxKokkos::k_error_flag"); - printf("Inside FixRxKokkos::FixRxKokkos\n"); + //printf("Inside FixRxKokkos::FixRxKokkos\n"); } template FixRxKokkos::~FixRxKokkos() { - printf("Inside FixRxKokkos::~FixRxKokkos copymode= %d\n", copymode); + //printf("Inside FixRxKokkos::~FixRxKokkos copymode= %d\n", copymode); if (copymode) return; } @@ -98,7 +98,7 @@ void FixRxKokkos::post_constructor() template void FixRxKokkos::init() { - printf("Inside FixRxKokkos::init\n"); + //printf("Inside FixRxKokkos::init\n"); // Call the parent's version. //FixRX::init(); @@ -153,7 +153,7 @@ void FixRxKokkos::init() template void FixRxKokkos::init_list(int, class NeighList* ptr) { - printf("Inside FixRxKokkos::init_list\n"); + //printf("Inside FixRxKokkos::init_list\n"); this->list = ptr; } @@ -1220,7 +1220,7 @@ void FixRxKokkos::operator()(SolverType, const int &i) const template void FixRxKokkos::create_kinetics_data(void) { - printf("Inside FixRxKokkos::create_kinetics_data\n"); + //printf("Inside FixRxKokkos::create_kinetics_data\n"); memory->create_kokkos( d_kineticsData.Arr, h_kineticsData.Arr, nreactions, "KineticsType::Arr"); memory->create_kokkos( d_kineticsData.nArr, h_kineticsData.nArr, nreactions, "KineticsType::nArr"); @@ -1301,7 +1301,7 @@ void FixRxKokkos::create_kinetics_data(void) template void FixRxKokkos::setup_pre_force(int vflag) { - printf("Inside FixRxKokkos::setup_pre_force restartFlag= %d\n", my_restartFlag); + //printf("Inside FixRxKokkos::setup_pre_force restartFlag= %d\n", my_restartFlag); if (my_restartFlag) my_restartFlag = 0; @@ -1314,7 +1314,7 @@ void FixRxKokkos::setup_pre_force(int vflag) template void FixRxKokkos::pre_force(int vflag) { - printf("Inside FixRxKokkos::pre_force localTempFlag= %d\n", localTempFlag); + //printf("Inside FixRxKokkos::pre_force localTempFlag= %d\n", localTempFlag); this->solve_reactions( vflag, true ); } @@ -1412,7 +1412,7 @@ void FixRxKokkos::operator()(Tag_FixRxKokkos_solveSystems void FixRxKokkos::solve_reactions(const int vflag, const bool isPreForce) { - printf("Inside FixRxKokkos::solve_reactions localTempFlag= %d isPreForce= %s\n", localTempFlag, isPreForce ? "True" : "false"); + //printf("Inside FixRxKokkos::solve_reactions localTempFlag= %d isPreForce= %s\n", localTempFlag, isPreForce ? "True" : "false"); copymode = 1; @@ -1653,11 +1653,11 @@ void FixRxKokkos::solve_reactions(const int vflag, const bool isPreF double time_ODE = getElapsedTime(timer_localTemperature, timer_ODE); - printf("me= %d kokkos total= %g temp= %g ode= %g comm= %g nlocal= %d nfc= %d %d\n", comm->me, - getElapsedTime(timer_start, timer_stop), - getElapsedTime(timer_start, timer_localTemperature), - getElapsedTime(timer_localTemperature, timer_ODE), - getElapsedTime(timer_ODE, timer_stop), nlocal, TotalCounters.nFuncs, TotalCounters.nSteps); + //printf("me= %d kokkos total= %g temp= %g ode= %g comm= %g nlocal= %d nfc= %d %d\n", comm->me, + // getElapsedTime(timer_start, timer_stop), + // getElapsedTime(timer_start, timer_localTemperature), + // getElapsedTime(timer_localTemperature, timer_ODE), + // getElapsedTime(timer_ODE, timer_stop), nlocal, TotalCounters.nFuncs, TotalCounters.nSteps); // Warn the user if a failure was detected in the ODE solver. if (TotalCounters.nFails > 0){ @@ -1992,7 +1992,7 @@ void FixRxKokkos::computeLocalTemperature() nlocal = atom->nlocal; const int nghost = atom->nghost; - printf("Inside FixRxKokkos::computeLocalTemperature: %d %d %d %d %d %d %d\n", WT_FLAG, LOCAL_TEMP_FLAG, NEWTON_PAIR, (int)lmp->kokkos->neighflag, NEIGHFLAG, nlocal, nghost); + //printf("Inside FixRxKokkos::computeLocalTemperature: %d %d %d %d %d %d %d\n", WT_FLAG, LOCAL_TEMP_FLAG, NEWTON_PAIR, (int)lmp->kokkos->neighflag, NEIGHFLAG, nlocal, nghost); // Pull from pairDPDE. The pairDPDEKK objects are protected so recreate here for now. //pairDPDEKK->k_cutsq.template sync(); diff --git a/src/USER-DPD/fix_rx.cpp b/src/USER-DPD/fix_rx.cpp index 8a8195da19..a8939e27f2 100644 --- a/src/USER-DPD/fix_rx.cpp +++ b/src/USER-DPD/fix_rx.cpp @@ -220,7 +220,7 @@ FixRX::FixRX(LAMMPS *lmp, int narg, char **arg) : FixRX::~FixRX() { - printf("Inside FixRX::~FixRX copymode= %d\n", copymode); + //printf("Inside FixRX::~FixRX copymode= %d\n", copymode); if (copymode) return; // De-Allocate memory to prevent memory leak @@ -756,8 +756,8 @@ void FixRX::pre_force(int vflag) memory->create( diagnosticCounterPerODE[FuncSum], nlocal, "FixRX::diagnosticCounterPerODE"); } - #pragma omp parallel \ - reduction(+: nSteps, nIters, nFuncs, nFails ) + //#pragma omp parallel \ + // reduction(+: nSteps, nIters, nFuncs, nFails ) { double *rwork = new double[8*nspecies]; @@ -767,7 +767,7 @@ void FixRX::pre_force(int vflag) int ode_counter[4] = { 0 }; - #pragma omp for schedule(runtime) + //#pragma omp for schedule(runtime) for (int i = 0; i < nlocal; i++) { if (mask[i] & groupbit) @@ -810,11 +810,11 @@ void FixRX::pre_force(int vflag) double time_ODE = getElapsedTime(timer_localTemperature, timer_ODE); - printf("me= %d total= %g temp= %g ode= %g comm= %g nlocal= %d nfc= %d %d\n", comm->me, - getElapsedTime(timer_start, timer_stop), - getElapsedTime(timer_start, timer_localTemperature), - getElapsedTime(timer_localTemperature, timer_ODE), - getElapsedTime(timer_ODE, timer_stop), nlocal, nFuncs, nSteps); + //printf("me= %d total= %g temp= %g ode= %g comm= %g nlocal= %d nfc= %d %d\n", comm->me, + // getElapsedTime(timer_start, timer_stop), + // getElapsedTime(timer_start, timer_localTemperature), + // getElapsedTime(timer_localTemperature, timer_ODE), + // getElapsedTime(timer_ODE, timer_stop), nlocal, nFuncs, nSteps); // Warn the user if a failure was detected in the ODE solver. if (nFails > 0){ From 0a751c59012ec2ef97d5d5313512983ef77f2c0f Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Wed, 22 Feb 2017 11:52:20 -0500 Subject: [PATCH 123/439] KOKKOS: fix a compile-time error caused by merge of patch 21Feb17 Remove the unused PairHybridOverlayKokkos::modify_requests() method The patch removed the parent PairHybridOverlay::modify_requests() --- src/KOKKOS/pair_hybrid_overlay_kokkos.cpp | 35 ----------------------- src/KOKKOS/pair_hybrid_overlay_kokkos.h | 3 -- 2 files changed, 38 deletions(-) diff --git a/src/KOKKOS/pair_hybrid_overlay_kokkos.cpp b/src/KOKKOS/pair_hybrid_overlay_kokkos.cpp index 79d9c63221..aa5d895155 100644 --- a/src/KOKKOS/pair_hybrid_overlay_kokkos.cpp +++ b/src/KOKKOS/pair_hybrid_overlay_kokkos.cpp @@ -105,38 +105,3 @@ void PairHybridOverlayKokkos::coeff(int narg, char **arg) if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } - -/* ---------------------------------------------------------------------- - combine sub-style neigh list requests and create new ones if needed -------------------------------------------------------------------------- */ - -void PairHybridOverlayKokkos::modify_requests() -{ - int i,j; - NeighRequest *irq,*jrq; - - // loop over pair requests only - // if a previous list is same kind with same skip attributes - // then make this one a copy list of that one - // works whether both lists are no-skip or yes-skip - // will not point a list at a copy list, but at copy list's parent - - for (i = 0; i < neighbor->nrequest; i++) { - if (!neighbor->requests[i]->pair) continue; - - irq = neighbor->requests[i]; - for (j = 0; j < i; j++) { - if (!neighbor->requests[j]->pair) continue; - jrq = neighbor->requests[j]; - if (irq->same_kind(jrq) && irq->same_skip(jrq)) { - irq->copy = 1; - irq->otherlist = j; - break; - } - } - } - - // perform same operations on skip lists as pair style = hybrid - - PairHybrid::modify_requests(); -} diff --git a/src/KOKKOS/pair_hybrid_overlay_kokkos.h b/src/KOKKOS/pair_hybrid_overlay_kokkos.h index 2e4899a1f3..6bec57c453 100644 --- a/src/KOKKOS/pair_hybrid_overlay_kokkos.h +++ b/src/KOKKOS/pair_hybrid_overlay_kokkos.h @@ -29,9 +29,6 @@ class PairHybridOverlayKokkos : public PairHybridKokkos { PairHybridOverlayKokkos(class LAMMPS *); virtual ~PairHybridOverlayKokkos() {} void coeff(int, char **); - - private: - void modify_requests(); }; } From 2db66e49b444c829a27e7a874d0fba49faf0387b Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Fri, 30 Dec 2016 12:16:54 -0500 Subject: [PATCH 124/439] USER-DPD: make pair_dpd_fdt* check more generically for use of fix_shardlow Allows easier experimentation of alternative shardlow implementations. --- src/USER-DPD/pair_dpd_fdt.cpp | 2 +- src/USER-DPD/pair_dpd_fdt_energy.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/USER-DPD/pair_dpd_fdt.cpp b/src/USER-DPD/pair_dpd_fdt.cpp index e7e9febd82..90aa4f1eaf 100644 --- a/src/USER-DPD/pair_dpd_fdt.cpp +++ b/src/USER-DPD/pair_dpd_fdt.cpp @@ -325,7 +325,7 @@ void PairDPDfdt::init_style() splitFDT_flag = false; int irequest = neighbor->request(this,instance_me); for (int i = 0; i < modify->nfix; i++) - if (strcmp(modify->fix[i]->style,"shardlow") == 0){ + if (strncmp(modify->fix[i]->style,"shardlow", 8) == 0){ splitFDT_flag = true; } } diff --git a/src/USER-DPD/pair_dpd_fdt_energy.cpp b/src/USER-DPD/pair_dpd_fdt_energy.cpp index 9d08393b9d..ad6310a283 100644 --- a/src/USER-DPD/pair_dpd_fdt_energy.cpp +++ b/src/USER-DPD/pair_dpd_fdt_energy.cpp @@ -414,7 +414,7 @@ void PairDPDfdtEnergy::init_style() splitFDT_flag = false; int irequest = neighbor->request(this,instance_me); for (int i = 0; i < modify->nfix; i++) - if (strcmp(modify->fix[i]->style,"shardlow") == 0){ + if (strncmp(modify->fix[i]->style,"shardlow", 8) == 0){ splitFDT_flag = true; } From 0512e7886067fbed5d9178654ffe74b16020e258 Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Fri, 30 Dec 2016 14:42:21 -0500 Subject: [PATCH 125/439] USER-DPD: new neighbor list code for SSA that gives neighbors to ghosts. This simplifies the processing of the neighbor list in fix_shardlow. NOTE: pair evaluation order changes, causing numerical differences! --- src/USER-DPD/fix_shardlow.cpp | 18 ++- src/USER-DPD/nbin_ssa.cpp | 27 ++-- src/USER-DPD/nbin_ssa.h | 2 +- src/USER-DPD/npair_half_bin_newton_ssa.cpp | 153 ++++++++---------- src/USER-DPD/npair_half_bin_newton_ssa.h | 2 +- src/USER-DPD/npair_halffull_newton_ssa.cpp | 4 + .../nstencil_half_bin_2d_newton_ssa.cpp | 12 +- .../nstencil_half_bin_2d_newton_ssa.h | 2 +- .../nstencil_half_bin_3d_newton_ssa.cpp | 18 ++- .../nstencil_half_bin_3d_newton_ssa.h | 2 +- src/USER-DPD/nstencil_ssa.h | 2 +- 11 files changed, 129 insertions(+), 113 deletions(-) diff --git a/src/USER-DPD/fix_shardlow.cpp b/src/USER-DPD/fix_shardlow.cpp index bf8959fa9f..56597697f7 100644 --- a/src/USER-DPD/fix_shardlow.cpp +++ b/src/USER-DPD/fix_shardlow.cpp @@ -148,6 +148,7 @@ void FixShardlow::init() int irequest = neighbor->request(this,instance_me); neighbor->requests[irequest]->pair = 0; neighbor->requests[irequest]->fix = 1; + neighbor->requests[irequest]->ghost= 1; neighbor->requests[irequest]->ssa = 1; } @@ -498,7 +499,7 @@ void FixShardlow::ssa_update_dpde( void FixShardlow::initial_integrate(int vflag) { - int i,ii,inum; + int i,ii,inum,anum; int *ilist; int nlocal = atom->nlocal; @@ -531,10 +532,12 @@ void FixShardlow::initial_integrate(int vflag) v_t0 = (double (*)[3]) memory->smalloc(sizeof(double)*3*nghost, "FixShardlow:v_t0"); inum = list->inum; + anum = inum + list->gnum; ilist = list->ilist; dtsqrt = sqrt(update->dt); + ii = 0; //Loop over all 14 directions (8 stages) for (airnum = 1; airnum <=8; airnum++){ @@ -549,15 +552,16 @@ void FixShardlow::initial_integrate(int vflag) } } - // Loop over neighbors of my atoms - for (ii = 0; ii < inum; ii++) { + // process neighbors in this AIR + while (ii < anum) { i = ilist[ii]; - int start = (airnum < 2) ? 0 : list->ndxAIR_ssa[i][airnum - 2]; - int len = list->ndxAIR_ssa[i][airnum - 1] - start; + if (atom->ssaAIR[i] > airnum) break; /* done with curent AIR */ + int len = list->numneigh[i]; if (len > 0) { - if (useDPDE) ssa_update_dpde(i, &(list->firstneigh[i][start]), len); - else ssa_update_dpd(i, &(list->firstneigh[i][start]), len); + if (useDPDE) ssa_update_dpde(i, &(list->firstneigh[i][0]), len); + else ssa_update_dpd(i, &(list->firstneigh[i][0]), len); } + ii++; } // Communicate the ghost deltas to the atom owners diff --git a/src/USER-DPD/nbin_ssa.cpp b/src/USER-DPD/nbin_ssa.cpp index 73da5e0df3..c2d780bac6 100644 --- a/src/USER-DPD/nbin_ssa.cpp +++ b/src/USER-DPD/nbin_ssa.cpp @@ -33,14 +33,13 @@ NBinSSA::NBinSSA(LAMMPS *lmp) : NBinStandard(lmp) bins_ssa = NULL; maxhead_ssa = 0; binhead_ssa = NULL; - gbinhead_ssa = NULL; + for (int i = 0; i < 9; i++) gairhead_ssa[i] = -1; } NBinSSA::~NBinSSA() { memory->destroy(bins_ssa); memory->destroy(binhead_ssa); - memory->destroy(gbinhead_ssa); } /* ---------------------------------------------------------------------- @@ -62,8 +61,11 @@ void NBinSSA::bin_atoms() last_bin = update->ntimestep; + for (i = 0; i < 9; i++) { + gairhead_ssa[i] = -1; + } + for (i = 0; i < mbins; i++) { - gbinhead_ssa[i] = -1; binhead_ssa[i] = -1; } @@ -73,19 +75,19 @@ void NBinSSA::bin_atoms() int bitmask = group->bitmask[includegroup]; int nowned = atom->nlocal; // NOTE: nlocal was set to atom->nfirst above for (i = nall-1; i >= nowned; i--) { - if (ssaAIR[i] < 2) continue; // skip ghost atoms not in AIR + ibin = ssaAIR[i]; + if (ibin < 2) continue; // skip ghost atoms not in AIR if (mask[i] & bitmask) { - ibin = coord2bin(x[i]); - bins_ssa[i] = gbinhead_ssa[ibin]; - gbinhead_ssa[ibin] = i; + bins_ssa[i] = gairhead_ssa[ibin]; + gairhead_ssa[ibin] = i; } } } else { for (i = nall-1; i >= nlocal; i--) { - if (ssaAIR[i] < 2) continue; // skip ghost atoms not in AIR - ibin = coord2bin(x[i]); - bins_ssa[i] = gbinhead_ssa[ibin]; - gbinhead_ssa[ibin] = i; + ibin = ssaAIR[i]; + if (ibin < 2) continue; // skip ghost atoms not in AIR + bins_ssa[i] = gairhead_ssa[ibin]; + gairhead_ssa[ibin] = i; } } for (i = nlocal-1; i >= 0; i--) { @@ -103,10 +105,8 @@ void NBinSSA::bin_atoms_setup(int nall) if (mbins > maxhead_ssa) { maxhead_ssa = mbins; - memory->destroy(gbinhead_ssa); memory->destroy(binhead_ssa); memory->create(binhead_ssa,maxhead_ssa,"binhead_ssa"); - memory->create(gbinhead_ssa,maxhead_ssa,"gbinhead_ssa"); } if (nall > maxbin_ssa) { @@ -125,7 +125,6 @@ bigint NBinSSA::memory_usage() if (maxbin_ssa) bytes += memory->usage(bins_ssa,maxbin_ssa); if (maxhead_ssa) { bytes += memory->usage(binhead_ssa,maxhead_ssa); - bytes += memory->usage(gbinhead_ssa,maxhead_ssa); } return bytes; } diff --git a/src/USER-DPD/nbin_ssa.h b/src/USER-DPD/nbin_ssa.h index f0699b3a7a..5a2562d305 100644 --- a/src/USER-DPD/nbin_ssa.h +++ b/src/USER-DPD/nbin_ssa.h @@ -32,7 +32,7 @@ class NBinSSA : public NBinStandard { int *bins_ssa; // index of next atom in each bin int maxbin_ssa; // size of bins_ssa array int *binhead_ssa; // index of 1st local atom in each bin - int *gbinhead_ssa; // index of 1st ghost atom in each bin + int gairhead_ssa[9]; // index of 1st ghost atom in each AIR int maxhead_ssa; // size of binhead_ssa and gbinhead_ssa arrays NBinSSA(class LAMMPS *); diff --git a/src/USER-DPD/npair_half_bin_newton_ssa.cpp b/src/USER-DPD/npair_half_bin_newton_ssa.cpp index fd67b66e9b..4c9dc95308 100644 --- a/src/USER-DPD/npair_half_bin_newton_ssa.cpp +++ b/src/USER-DPD/npair_half_bin_newton_ssa.cpp @@ -32,12 +32,6 @@ using namespace LAMMPS_NS; -// allocate space for static class variable -// prototype for non-class function - -static int *ssaAIRptr; -static int cmp_ssaAIR(const void *, const void *); - /* ---------------------------------------------------------------------- */ NPairHalfBinNewtonSSA::NPairHalfBinNewtonSSA(LAMMPS *lmp) : NPair(lmp) {} @@ -64,9 +58,7 @@ void NPairHalfBinNewtonSSA::build(NeighList *list) tagint **special = atom->special; int **nspecial = atom->nspecial; int nlocal = atom->nlocal; - int nall = nlocal + atom->nghost; if (includegroup) nlocal = atom->nfirst; - int *ssaAIR = atom->ssaAIR; int *molindex = atom->molindex; int *molatom = atom->molatom; @@ -89,16 +81,18 @@ void NPairHalfBinNewtonSSA::build(NeighList *list) if (!nb_ssa) error->one(FLERR, "NBin wasn't a NBinSSA object"); int *bins_ssa = nb_ssa->bins_ssa; int *binhead_ssa = nb_ssa->binhead_ssa; - int *gbinhead_ssa = nb_ssa->gbinhead_ssa; + int *gairhead_ssa = &(nb_ssa->gairhead_ssa[0]); int inum = 0; + int gnum = 0; + int xbin,ybin,zbin,xbin2,ybin2,zbin2; + int **stencilxyz = ns_ssa->stencilxyz; ipage->reset(); // loop over owned atoms, storing half of the neighbors for (i = 0; i < nlocal; i++) { - int AIRct[8] = { 0 }; n = 0; neighptr = ipage->vget(); @@ -175,51 +169,6 @@ void NPairHalfBinNewtonSSA::build(NeighList *list) } } } - AIRct[0] = n; - - // loop over AIR ghost atoms in all bins in "full" stencil - // Note: the non-AIR ghost atoms have already been filtered out - // That is a significant time savings because of the "full" stencil - // Note2: only non-pure locals can have ghosts as neighbors - - if (ssaAIR[i] == 1) for (k = 0; k < nstencil_full; k++) { - for (j = gbinhead_ssa[ibin+stencil[k]]; j >= 0; - j = bins_ssa[j]) { - - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) { - neighptr[n++] = j; - ++(AIRct[ssaAIR[j] - 1]); - } else if (domain->minimum_image_check(delx,dely,delz)) { - neighptr[n++] = j; - ++(AIRct[ssaAIR[j] - 1]); - } else if (which > 0) { - neighptr[n++] = j ^ (which << SBBITS); - ++(AIRct[ssaAIR[j] - 1]); - } - } else { - neighptr[n++] = j; - ++(AIRct[ssaAIR[j] - 1]); - } - } - } - } ilist[inum++] = i; firstneigh[i] = neighptr; @@ -227,34 +176,74 @@ void NPairHalfBinNewtonSSA::build(NeighList *list) ipage->vgot(n); if (ipage->status()) error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - - // sort the ghosts in the neighbor list by their ssaAIR number - - ssaAIRptr = atom->ssaAIR; - qsort(&(neighptr[AIRct[0]]), n - AIRct[0], sizeof(int), cmp_ssaAIR); - - // do a prefix sum on the counts to turn them into indexes - - list->ndxAIR_ssa[i][0] = AIRct[0]; - for (int ndx = 1; ndx < 8; ++ndx) { - list->ndxAIR_ssa[i][ndx] = AIRct[ndx] + list->ndxAIR_ssa[i][ndx - 1]; - } } list->inum = inum; + + // loop over AIR ghost atoms, storing their local neighbors + // since these are ghosts, must check if stencil bin is out of bounds + for (int airnum = 2; airnum <= 8; airnum++) { + for (i = gairhead_ssa[airnum]; i >= 0; i = bins_ssa[i]) { + n = 0; + neighptr = ipage->vget(); + + itype = type[i]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + if (moltemplate) { + imol = molindex[i]; + iatom = molatom[i]; + tagprev = tag[i] - iatom - 1; + } + + ibin = coord2bin(x[i],xbin,ybin,zbin); + + // loop over AIR ghost atoms in all bins in "full" stencil + // Note: the non-AIR ghost atoms have already been filtered out + for (k = 0; k < nstencil_full; k++) { + xbin2 = xbin + stencilxyz[k][0]; + ybin2 = ybin + stencilxyz[k][1]; + zbin2 = zbin + stencilxyz[k][2]; + // since we only care about ghost to local neighbors, these "bounds" could be inset + if (xbin2 < 0 || xbin2 >= mbinx || + ybin2 < 0 || ybin2 >= mbiny || + zbin2 < 0 || zbin2 >= mbinz) continue; + for (j = binhead_ssa[ibin+stencil[k]]; j >= 0; j = bins_ssa[j]) { + + jtype = type[j]; + if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; + + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx*delx + dely*dely + delz*delz; + + if (rsq <= cutneighsq[itype][jtype]) { + if (molecular) { + if (!moltemplate) + which = find_special(special[i],nspecial[i],tag[j]); + else if (imol >= 0) + which = find_special(onemols[imol]->special[iatom], + onemols[imol]->nspecial[iatom], + tag[j]-tagprev); + else which = 0; + if (which == 0) neighptr[n++] = j; + else if (domain->minimum_image_check(delx,dely,delz)) + neighptr[n++] = j; + else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); + } else neighptr[n++] = j; + } + } + } + + if (n > 0) ilist[inum + (gnum++)] = i; + firstneigh[i] = neighptr; + numneigh[i] = n; + ipage->vgot(n); + if (ipage->status()) + error->one(FLERR,"Neighbor (ghost) list overflow, boost neigh_modify one"); + } + } + list->gnum = gnum; } - -/* ---------------------------------------------------------------------- - comparison function invoked by qsort() - accesses static class member ssaAIRptr, set before call to qsort() -------------------------------------------------------------------------- */ - -static int cmp_ssaAIR(const void *iptr, const void *jptr) -{ - int i = NEIGHMASK & *((int *) iptr); - int j = NEIGHMASK & *((int *) jptr); - if (ssaAIRptr[i] < ssaAIRptr[j]) return -1; - if (ssaAIRptr[i] > ssaAIRptr[j]) return 1; - return 0; -} - diff --git a/src/USER-DPD/npair_half_bin_newton_ssa.h b/src/USER-DPD/npair_half_bin_newton_ssa.h index 13347b33b0..c9ccbc4bd9 100644 --- a/src/USER-DPD/npair_half_bin_newton_ssa.h +++ b/src/USER-DPD/npair_half_bin_newton_ssa.h @@ -15,7 +15,7 @@ NPairStyle(half/bin/newton/ssa, NPairHalfBinNewtonSSA, - NP_HALF | NP_BIN | NP_NEWTON | NP_ORTHO | NP_SSA) + NP_HALF | NP_BIN | NP_NEWTON | NP_ORTHO | NP_SSA | NP_GHOST) #else diff --git a/src/USER-DPD/npair_halffull_newton_ssa.cpp b/src/USER-DPD/npair_halffull_newton_ssa.cpp index 2c9de3e50f..d0be1685b6 100644 --- a/src/USER-DPD/npair_halffull_newton_ssa.cpp +++ b/src/USER-DPD/npair_halffull_newton_ssa.cpp @@ -64,6 +64,10 @@ void NPairHalffullNewtonSSA::build(NeighList *list) int inum_full = list->listfull->inum; int inum = 0; + + error->one(FLERR,"NPairHalffullNewtonSSA not yet implemented for ghosts with neighbors."); + return; + ipage->reset(); // loop over parent full list diff --git a/src/USER-DPD/nstencil_half_bin_2d_newton_ssa.cpp b/src/USER-DPD/nstencil_half_bin_2d_newton_ssa.cpp index df379a109a..254339bffc 100644 --- a/src/USER-DPD/nstencil_half_bin_2d_newton_ssa.cpp +++ b/src/USER-DPD/nstencil_half_bin_2d_newton_ssa.cpp @@ -46,8 +46,12 @@ void NStencilHalfBin2dNewtonSSA::create() for (j = 0; j <= sy; j++) for (i = -sx; i <= sx; i++) if (j > 0 || (j == 0 && i > 0)) - if (bin_distance(i,j,0) < cutneighmaxsq) + if (bin_distance(i,j,0) < cutneighmaxsq) { + stencilxyz[pos][0] = i; + stencilxyz[pos][1] = j; + stencilxyz[pos][2] = 0; stencil[pos++] = j*mbinx + i; + } nstencil_half = pos; // record where normal half stencil ends @@ -56,8 +60,12 @@ void NStencilHalfBin2dNewtonSSA::create() for (j = -sy; j <= 0; j++) for (i = -sx; i <= sx; i++) { if (j == 0 && i > 0) continue; - if (bin_distance(i,j,0) < cutneighmaxsq) + if (bin_distance(i,j,0) < cutneighmaxsq) { + stencilxyz[pos][0] = i; + stencilxyz[pos][1] = j; + stencilxyz[pos][2] = 0; stencil[pos++] = j*mbinx + i; + } } nstencil = pos; // record where full stencil ends diff --git a/src/USER-DPD/nstencil_half_bin_2d_newton_ssa.h b/src/USER-DPD/nstencil_half_bin_2d_newton_ssa.h index 30901bb3e2..1d5cc3f6b2 100644 --- a/src/USER-DPD/nstencil_half_bin_2d_newton_ssa.h +++ b/src/USER-DPD/nstencil_half_bin_2d_newton_ssa.h @@ -15,7 +15,7 @@ NStencilStyle(half/bin/2d/newton/ssa, NStencilHalfBin2dNewtonSSA, - NS_HALF | NS_BIN | NS_2D | NS_NEWTON | NS_SSA | NS_ORTHO) + NS_HALF | NS_BIN | NS_2D | NS_NEWTON | NS_SSA | NS_ORTHO | NS_GHOST) #else diff --git a/src/USER-DPD/nstencil_half_bin_3d_newton_ssa.cpp b/src/USER-DPD/nstencil_half_bin_3d_newton_ssa.cpp index 76c9931ab2..1e2c18c66a 100644 --- a/src/USER-DPD/nstencil_half_bin_3d_newton_ssa.cpp +++ b/src/USER-DPD/nstencil_half_bin_3d_newton_ssa.cpp @@ -47,8 +47,12 @@ void NStencilHalfBin3dNewtonSSA::create() for (j = -sy; j <= sy; j++) for (i = -sx; i <= sx; i++) if (k > 0 || j > 0 || (j == 0 && i > 0)) - if (bin_distance(i,j,k) < cutneighmaxsq) + if (bin_distance(i,j,k) < cutneighmaxsq) { + stencilxyz[pos][0] = i; + stencilxyz[pos][1] = j; + stencilxyz[pos][2] = k; stencil[pos++] = k*mbiny*mbinx + j*mbinx + i; + } nstencil_half = pos; // record where normal half stencil ends @@ -57,8 +61,12 @@ void NStencilHalfBin3dNewtonSSA::create() for (k = -sz; k < 0; k++) for (j = -sy; j <= sy; j++) for (i = -sx; i <= sx; i++) - if (bin_distance(i,j,k) < cutneighmaxsq) + if (bin_distance(i,j,k) < cutneighmaxsq) { + stencilxyz[pos][0] = i; + stencilxyz[pos][1] = j; + stencilxyz[pos][2] = k; stencil[pos++] = k*mbiny*mbinx + j*mbinx + i; + } // For k==0, make sure to skip already included bins @@ -66,8 +74,12 @@ void NStencilHalfBin3dNewtonSSA::create() for (j = -sy; j <= 0; j++) for (i = -sx; i <= sx; i++) { if (j == 0 && i > 0) continue; - if (bin_distance(i,j,k) < cutneighmaxsq) + if (bin_distance(i,j,k) < cutneighmaxsq) { + stencilxyz[pos][0] = i; + stencilxyz[pos][1] = j; + stencilxyz[pos][2] = k; stencil[pos++] = k*mbiny*mbinx + j*mbinx + i; + } } nstencil = pos; // record where full stencil ends diff --git a/src/USER-DPD/nstencil_half_bin_3d_newton_ssa.h b/src/USER-DPD/nstencil_half_bin_3d_newton_ssa.h index 7765b256d3..450a696e46 100644 --- a/src/USER-DPD/nstencil_half_bin_3d_newton_ssa.h +++ b/src/USER-DPD/nstencil_half_bin_3d_newton_ssa.h @@ -15,7 +15,7 @@ NStencilStyle(half/bin/3d/newton/ssa, NStencilHalfBin3dNewtonSSA, - NS_HALF | NS_BIN | NS_3D | NS_NEWTON | NS_SSA | NS_ORTHO) + NS_HALF | NS_BIN | NS_3D | NS_NEWTON | NS_SSA | NS_ORTHO | NS_GHOST) #else diff --git a/src/USER-DPD/nstencil_ssa.h b/src/USER-DPD/nstencil_ssa.h index 9fcd19ee26..e6dfce60f4 100644 --- a/src/USER-DPD/nstencil_ssa.h +++ b/src/USER-DPD/nstencil_ssa.h @@ -20,7 +20,7 @@ namespace LAMMPS_NS { class NStencilSSA : public NStencil { public: - NStencilSSA(class LAMMPS *lmp) : NStencil(lmp) { } + NStencilSSA(class LAMMPS *lmp) : NStencil(lmp) { xyzflag = 1; } ~NStencilSSA() {} virtual void create() = 0; From 638448676404468bda5253124d27ccf3c13a043e Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Thu, 26 Jan 2017 13:12:28 -0500 Subject: [PATCH 126/439] USER-DPD: Copy inline coord2bin() functions from nbin_kokkos into nbin_ssa --- src/USER-DPD/nbin_ssa.cpp | 5 ++- src/USER-DPD/nbin_ssa.h | 72 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 1 deletion(-) diff --git a/src/USER-DPD/nbin_ssa.cpp b/src/USER-DPD/nbin_ssa.cpp index c2d780bac6..82cf6e7cac 100644 --- a/src/USER-DPD/nbin_ssa.cpp +++ b/src/USER-DPD/nbin_ssa.cpp @@ -61,6 +61,9 @@ void NBinSSA::bin_atoms() last_bin = update->ntimestep; + bboxlo_[0] = bboxlo[0]; bboxlo_[1] = bboxlo[1]; bboxlo_[2] = bboxlo[2]; + bboxhi_[0] = bboxhi[0]; bboxhi_[1] = bboxhi[1]; bboxhi_[2] = bboxhi[2]; + for (i = 0; i < 9; i++) { gairhead_ssa[i] = -1; } @@ -91,7 +94,7 @@ void NBinSSA::bin_atoms() } } for (i = nlocal-1; i >= 0; i--) { - ibin = coord2bin(x[i]); + ibin = coord2bin(x[i][0], x[i][1], x[i][2]); bins_ssa[i] = binhead_ssa[ibin]; binhead_ssa[ibin] = i; } diff --git a/src/USER-DPD/nbin_ssa.h b/src/USER-DPD/nbin_ssa.h index 5a2562d305..c39d7c7bce 100644 --- a/src/USER-DPD/nbin_ssa.h +++ b/src/USER-DPD/nbin_ssa.h @@ -42,6 +42,78 @@ class NBinSSA : public NBinStandard { void bin_atoms(); bigint memory_usage(); + + inline + int coord2bin(const double & x,const double & y,const double & z) const + { + int ix,iy,iz; + + if (x >= bboxhi_[0]) + ix = static_cast ((x-bboxhi_[0])*bininvx) + nbinx; + else if (x >= bboxlo_[0]) { + ix = static_cast ((x-bboxlo_[0])*bininvx); + ix = MIN(ix,nbinx-1); + } else + ix = static_cast ((x-bboxlo_[0])*bininvx) - 1; + + if (y >= bboxhi_[1]) + iy = static_cast ((y-bboxhi_[1])*bininvy) + nbiny; + else if (y >= bboxlo_[1]) { + iy = static_cast ((y-bboxlo_[1])*bininvy); + iy = MIN(iy,nbiny-1); + } else + iy = static_cast ((y-bboxlo_[1])*bininvy) - 1; + + if (z >= bboxhi_[2]) + iz = static_cast ((z-bboxhi_[2])*bininvz) + nbinz; + else if (z >= bboxlo_[2]) { + iz = static_cast ((z-bboxlo_[2])*bininvz); + iz = MIN(iz,nbinz-1); + } else + iz = static_cast ((z-bboxlo_[2])*bininvz) - 1; + + return (iz-mbinzlo)*mbiny*mbinx + (iy-mbinylo)*mbinx + (ix-mbinxlo); + } + + inline + int coord2bin(const double & x,const double & y,const double & z, int* i) const + { + int ix,iy,iz; + + if (x >= bboxhi_[0]) + ix = static_cast ((x-bboxhi_[0])*bininvx) + nbinx; + else if (x >= bboxlo_[0]) { + ix = static_cast ((x-bboxlo_[0])*bininvx); + ix = MIN(ix,nbinx-1); + } else + ix = static_cast ((x-bboxlo_[0])*bininvx) - 1; + + if (y >= bboxhi_[1]) + iy = static_cast ((y-bboxhi_[1])*bininvy) + nbiny; + else if (y >= bboxlo_[1]) { + iy = static_cast ((y-bboxlo_[1])*bininvy); + iy = MIN(iy,nbiny-1); + } else + iy = static_cast ((y-bboxlo_[1])*bininvy) - 1; + + if (z >= bboxhi_[2]) + iz = static_cast ((z-bboxhi_[2])*bininvz) + nbinz; + else if (z >= bboxlo_[2]) { + iz = static_cast ((z-bboxlo_[2])*bininvz); + iz = MIN(iz,nbinz-1); + } else + iz = static_cast ((z-bboxlo_[2])*bininvz) - 1; + + i[0] = ix - mbinxlo; + i[1] = iy - mbinylo; + i[2] = iz - mbinzlo; + + return (iz-mbinzlo)*mbiny*mbinx + (iy-mbinylo)*mbinx + (ix-mbinxlo); + } + + private: + double bboxlo_[3],bboxhi_[3]; + }; } From ff2786c86c4c3c1e103fefeccd0bdaeee826a4d4 Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Thu, 26 Jan 2017 14:28:54 -0500 Subject: [PATCH 127/439] USER-DPD: Make another version of coord2bin() for nbin_ssa --- src/USER-DPD/nbin_ssa.h | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/USER-DPD/nbin_ssa.h b/src/USER-DPD/nbin_ssa.h index c39d7c7bce..75766ebcd2 100644 --- a/src/USER-DPD/nbin_ssa.h +++ b/src/USER-DPD/nbin_ssa.h @@ -111,6 +111,42 @@ class NBinSSA : public NBinStandard { return (iz-mbinzlo)*mbiny*mbinx + (iy-mbinylo)*mbinx + (ix-mbinxlo); } + inline + int coord2bin(const double & x,const double & y,const double & z, int &ixo, int &iyo, int &izo) const + { + int ix,iy,iz; + + if (x >= bboxhi_[0]) + ix = static_cast ((x-bboxhi_[0])*bininvx) + nbinx; + else if (x >= bboxlo_[0]) { + ix = static_cast ((x-bboxlo_[0])*bininvx); + ix = MIN(ix,nbinx-1); + } else + ix = static_cast ((x-bboxlo_[0])*bininvx) - 1; + + if (y >= bboxhi_[1]) + iy = static_cast ((y-bboxhi_[1])*bininvy) + nbiny; + else if (y >= bboxlo_[1]) { + iy = static_cast ((y-bboxlo_[1])*bininvy); + iy = MIN(iy,nbiny-1); + } else + iy = static_cast ((y-bboxlo_[1])*bininvy) - 1; + + if (z >= bboxhi_[2]) + iz = static_cast ((z-bboxhi_[2])*bininvz) + nbinz; + else if (z >= bboxlo_[2]) { + iz = static_cast ((z-bboxlo_[2])*bininvz); + iz = MIN(iz,nbinz-1); + } else + iz = static_cast ((z-bboxlo_[2])*bininvz) - 1; + + ixo = ix - mbinxlo; + iyo = iy - mbinylo; + izo = iz - mbinzlo; + + return (iz-mbinzlo)*mbiny*mbinx + (iy-mbinylo)*mbinx + (ix-mbinxlo); + } + private: double bboxlo_[3],bboxhi_[3]; From e42678ed517d8bc95f16da08329a2ae63bffe7bb Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Thu, 26 Jan 2017 16:20:12 -0500 Subject: [PATCH 128/439] USER-DPD: track & use the extent of the local atoms in the bins --- src/USER-DPD/nbin_ssa.cpp | 73 ++++++++++++++-------- src/USER-DPD/nbin_ssa.h | 16 +++-- src/USER-DPD/npair_half_bin_newton_ssa.cpp | 49 ++++++++++----- src/neigh_list.h | 1 + 4 files changed, 93 insertions(+), 46 deletions(-) diff --git a/src/USER-DPD/nbin_ssa.cpp b/src/USER-DPD/nbin_ssa.cpp index 82cf6e7cac..321baf771a 100644 --- a/src/USER-DPD/nbin_ssa.cpp +++ b/src/USER-DPD/nbin_ssa.cpp @@ -30,22 +30,24 @@ using namespace LAMMPS_NS; NBinSSA::NBinSSA(LAMMPS *lmp) : NBinStandard(lmp) { maxbin_ssa = 0; - bins_ssa = NULL; - maxhead_ssa = 0; - binhead_ssa = NULL; - for (int i = 0; i < 9; i++) gairhead_ssa[i] = -1; + binlist_ssa = NULL; + binct_ssa = NULL; + for (int i = 0; i < 9; i++) { + gairhead_ssa[i] = -1; + gairct_ssa[i] = 0; + } } NBinSSA::~NBinSSA() { - memory->destroy(bins_ssa); - memory->destroy(binhead_ssa); + memory->destroy(binlist_ssa); + memory->destroy(binct_ssa); } /* ---------------------------------------------------------------------- bin owned and ghost atoms for the Shardlow Splitting Algorithm (SSA) - local atoms are in distinct bins (binhead_ssa) from the ghosts - ghost atoms are in distinct bins (gbinhead_ssa) from the locals + local atoms are in distinct bins (binhead[]) from the ghosts + ghost atoms are "binned" in gairhead_ssa[] instead ghosts which are not in an Active Interaction Region (AIR) are skipped ------------------------------------------------------------------------- */ @@ -58,6 +60,7 @@ void NBinSSA::bin_atoms() double **x = atom->x; int *mask = atom->mask; int *ssaAIR = atom->ssaAIR; + int xbin,ybin,zbin; last_bin = update->ntimestep; @@ -66,10 +69,13 @@ void NBinSSA::bin_atoms() for (i = 0; i < 9; i++) { gairhead_ssa[i] = -1; + gairct_ssa[i] = 0; } for (i = 0; i < mbins; i++) { - binhead_ssa[i] = -1; + binhead[i] = -1; + binlist_ssa[i] = -1; + binct_ssa[i] = 0; } // bin in reverse order so linked list will be in forward order @@ -81,23 +87,34 @@ void NBinSSA::bin_atoms() ibin = ssaAIR[i]; if (ibin < 2) continue; // skip ghost atoms not in AIR if (mask[i] & bitmask) { - bins_ssa[i] = gairhead_ssa[ibin]; + bins[i] = gairhead_ssa[ibin]; gairhead_ssa[ibin] = i; + ++(gairct_ssa[ibin]); } } } else { for (i = nall-1; i >= nlocal; i--) { ibin = ssaAIR[i]; if (ibin < 2) continue; // skip ghost atoms not in AIR - bins_ssa[i] = gairhead_ssa[ibin]; + bins[i] = gairhead_ssa[ibin]; gairhead_ssa[ibin] = i; + ++(gairct_ssa[ibin]); } } for (i = nlocal-1; i >= 0; i--) { - ibin = coord2bin(x[i][0], x[i][1], x[i][2]); - bins_ssa[i] = binhead_ssa[ibin]; - binhead_ssa[ibin] = i; + ibin = coord2bin(x[i][0], x[i][1], x[i][2], xbin, ybin, zbin); + // Find the bounding box of the local atoms in the bins + if (xbin < lbinxlo) lbinxlo = xbin; + if (xbin >= lbinxhi) lbinxhi = xbin + 1; + if (ybin < lbinylo) lbinylo = ybin; + if (ybin >= lbinyhi) lbinyhi = ybin + 1; + if (zbin < lbinzlo) lbinzlo = zbin; + if (zbin >= lbinzhi) lbinzhi = zbin + 1; + bins[i] = binhead[ibin]; + binhead[ibin] = i; + ++(binct_ssa[ibin]); } + } /* ---------------------------------------------------------------------- */ @@ -106,17 +123,21 @@ void NBinSSA::bin_atoms_setup(int nall) { NBinStandard::bin_atoms_setup(nall); // Setup the parent class's data too - if (mbins > maxhead_ssa) { - maxhead_ssa = mbins; - memory->destroy(binhead_ssa); - memory->create(binhead_ssa,maxhead_ssa,"binhead_ssa"); + if (mbins > maxbin_ssa) { + maxbin_ssa = mbins; + memory->destroy(binlist_ssa); + memory->destroy(binct_ssa); + memory->create(binlist_ssa,maxbin_ssa,"binlist_ssa"); + memory->create(binct_ssa,maxbin_ssa,"binct_ssa"); } - if (nall > maxbin_ssa) { - maxbin_ssa = nall; - memory->destroy(bins_ssa); - memory->create(bins_ssa,maxbin_ssa,"bins_ssa"); - } + // Clear the local bin extent bounding box. + lbinxlo = mbinx - 1; // Safe to = stencil->sx + 1 + lbinylo = mbiny - 1; // Safe to = stencil->sy + 1 + lbinzlo = mbinz - 1; // Safe to = stencil->sz + 1 + lbinxhi = 0; // Safe to = mbinx - stencil->sx - 1 + lbinyhi = 0; // Safe to = mbiny - stencil->sy - 1 + lbinzhi = 0; // Safe to = mbinz - stencil->sz - 1 } /* ---------------------------------------------------------------------- */ @@ -125,9 +146,9 @@ bigint NBinSSA::memory_usage() { bigint bytes = NBinStandard::memory_usage(); // Count the parent's usage too - if (maxbin_ssa) bytes += memory->usage(bins_ssa,maxbin_ssa); - if (maxhead_ssa) { - bytes += memory->usage(binhead_ssa,maxhead_ssa); + if (maxbin_ssa) { + bytes += memory->usage(binlist_ssa,maxbin_ssa); + bytes += memory->usage(binct_ssa,maxbin_ssa); } return bytes; } diff --git a/src/USER-DPD/nbin_ssa.h b/src/USER-DPD/nbin_ssa.h index 75766ebcd2..48694370b9 100644 --- a/src/USER-DPD/nbin_ssa.h +++ b/src/USER-DPD/nbin_ssa.h @@ -29,11 +29,19 @@ namespace LAMMPS_NS { class NBinSSA : public NBinStandard { public: - int *bins_ssa; // index of next atom in each bin - int maxbin_ssa; // size of bins_ssa array - int *binhead_ssa; // index of 1st local atom in each bin + int *binlist_ssa; // index in neighlist of 1st local atom in each bin + int *binct_ssa; // count of local atoms in each bin int gairhead_ssa[9]; // index of 1st ghost atom in each AIR - int maxhead_ssa; // size of binhead_ssa and gbinhead_ssa arrays + int gairct_ssa[9]; // count of ghost atoms in each AIR + int maxbin_ssa; // size of binlist_ssa and binct_ssa arrays + + // Bounds of the local atoms in the binhead array + int lbinxlo; // lowest local bin x-dim coordinate + int lbinylo; // lowest local bin y-dim coordinate + int lbinzlo; // lowest local bin z-dim coordinate + int lbinxhi; // highest local bin x-dim coordinate + int lbinyhi; // highest local bin y-dim coordinate + int lbinzhi; // highest local bin z-dim coordinate NBinSSA(class LAMMPS *); ~NBinSSA(); diff --git a/src/USER-DPD/npair_half_bin_newton_ssa.cpp b/src/USER-DPD/npair_half_bin_newton_ssa.cpp index 4c9dc95308..f0860cba4b 100644 --- a/src/USER-DPD/npair_half_bin_newton_ssa.cpp +++ b/src/USER-DPD/npair_half_bin_newton_ssa.cpp @@ -79,20 +79,32 @@ void NPairHalfBinNewtonSSA::build(NeighList *list) NBinSSA *nb_ssa = dynamic_cast(nb); if (!nb_ssa) error->one(FLERR, "NBin wasn't a NBinSSA object"); - int *bins_ssa = nb_ssa->bins_ssa; - int *binhead_ssa = nb_ssa->binhead_ssa; + int *bins = nb_ssa->bins; + int *binhead = nb_ssa->binhead; + int *binlist_ssa = nb_ssa->binlist_ssa; + int *binct_ssa = nb_ssa->binct_ssa; int *gairhead_ssa = &(nb_ssa->gairhead_ssa[0]); int inum = 0; int gnum = 0; int xbin,ybin,zbin,xbin2,ybin2,zbin2; int **stencilxyz = ns_ssa->stencilxyz; + int lbinxlo = nb_ssa->lbinxlo; + int lbinxhi = nb_ssa->lbinxhi; + int lbinylo = nb_ssa->lbinylo; + int lbinyhi = nb_ssa->lbinyhi; + int lbinzlo = nb_ssa->lbinzlo; + int lbinzhi = nb_ssa->lbinzhi; ipage->reset(); - // loop over owned atoms, storing half of the neighbors - - for (i = 0; i < nlocal; i++) { + // loop over bins with local atoms, storing half of the neighbors + for (zbin = lbinzlo; zbin < lbinzhi; zbin++) { + for (ybin = lbinylo; ybin < lbinyhi; ybin++) { + for (xbin = lbinxlo; xbin < lbinxhi; xbin++) { + ibin = zbin*mbiny*mbinx + ybin*mbinx + xbin; + binlist_ssa[ibin] = inum; // record where ibin starts in ilist + for (i = binhead[ibin]; i >= 0; i = bins[i]) { n = 0; neighptr = ipage->vget(); @@ -109,7 +121,7 @@ void NPairHalfBinNewtonSSA::build(NeighList *list) // loop over rest of local atoms in i's bin // just store them, since j is beyond i in linked list - for (j = bins_ssa[i]; j >= 0; j = bins_ssa[j]) { + for (j = bins[i]; j >= 0; j = bins[j]) { jtype = type[j]; if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; @@ -136,13 +148,11 @@ void NPairHalfBinNewtonSSA::build(NeighList *list) } } - ibin = coord2bin(x[i]); - // loop over all local atoms in other bins in "half" stencil for (k = 0; k < nstencil_half; k++) { - for (j = binhead_ssa[ibin+stencil[k]]; j >= 0; - j = bins_ssa[j]) { + for (j = binhead[ibin+stencil[k]]; j >= 0; + j = bins[j]) { jtype = type[j]; if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; @@ -177,13 +187,20 @@ void NPairHalfBinNewtonSSA::build(NeighList *list) if (ipage->status()) error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); } + // verify count of atoms in ibin + if (binct_ssa[ibin] != (inum - binlist_ssa[ibin])) + error->one(FLERR,"binct_ssa didn't agree with lenght in ilist"); + } + } + } list->inum = inum; // loop over AIR ghost atoms, storing their local neighbors // since these are ghosts, must check if stencil bin is out of bounds for (int airnum = 2; airnum <= 8; airnum++) { - for (i = gairhead_ssa[airnum]; i >= 0; i = bins_ssa[i]) { + list->AIRct_ssa[airnum - 1] = nb_ssa->gairct_ssa[airnum]; + for (i = gairhead_ssa[airnum]; i >= 0; i = bins[i]) { n = 0; neighptr = ipage->vget(); @@ -205,11 +222,11 @@ void NPairHalfBinNewtonSSA::build(NeighList *list) xbin2 = xbin + stencilxyz[k][0]; ybin2 = ybin + stencilxyz[k][1]; zbin2 = zbin + stencilxyz[k][2]; - // since we only care about ghost to local neighbors, these "bounds" could be inset - if (xbin2 < 0 || xbin2 >= mbinx || - ybin2 < 0 || ybin2 >= mbiny || - zbin2 < 0 || zbin2 >= mbinz) continue; - for (j = binhead_ssa[ibin+stencil[k]]; j >= 0; j = bins_ssa[j]) { + // Skip it if this bin is outside the extent of local bins + if (xbin2 < lbinxlo || xbin2 >= lbinxhi || + ybin2 < lbinylo || ybin2 >= lbinyhi || + zbin2 < lbinzlo || zbin2 >= lbinzhi) continue; + for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) { jtype = type[j]; if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; diff --git a/src/neigh_list.h b/src/neigh_list.h index 9a77a0311d..7649245e99 100644 --- a/src/neigh_list.h +++ b/src/neigh_list.h @@ -80,6 +80,7 @@ class NeighList : protected Pointers { // USER-DPD package and Shardlow Splitting Algorithm (SSA) support + int AIRct_ssa[8]; // count of how many atoms in each AIR uint16_t (*ndxAIR_ssa)[8]; // for each atom, last neighbor index of each AIR // methods From e9d46f4e7acb79d57c982f59cbcd335e96beb10e Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Fri, 27 Jan 2017 12:31:13 -0500 Subject: [PATCH 129/439] USER-DPD: Correct an error message typo. --- src/USER-DPD/npair_half_bin_newton_ssa.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/USER-DPD/npair_half_bin_newton_ssa.cpp b/src/USER-DPD/npair_half_bin_newton_ssa.cpp index f0860cba4b..b9306ee3b1 100644 --- a/src/USER-DPD/npair_half_bin_newton_ssa.cpp +++ b/src/USER-DPD/npair_half_bin_newton_ssa.cpp @@ -189,7 +189,7 @@ void NPairHalfBinNewtonSSA::build(NeighList *list) } // verify count of atoms in ibin if (binct_ssa[ibin] != (inum - binlist_ssa[ibin])) - error->one(FLERR,"binct_ssa didn't agree with lenght in ilist"); + error->one(FLERR,"binct_ssa didn't agree with length in ilist"); } } } From fb279a87f5eac44e02319e4464a05fa62aa87794 Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Fri, 27 Jan 2017 13:24:46 -0500 Subject: [PATCH 130/439] USER-DPD: properly compute AIRct_ssa values, and use them in fix_shardlow. Eliminates last use of per-atom ssaAIR values within initial_integrate() --- src/USER-DPD/fix_shardlow.cpp | 36 ++++++++++++++-------- src/USER-DPD/npair_half_bin_newton_ssa.cpp | 8 +++-- 2 files changed, 29 insertions(+), 15 deletions(-) diff --git a/src/USER-DPD/fix_shardlow.cpp b/src/USER-DPD/fix_shardlow.cpp index 56597697f7..9253d17317 100644 --- a/src/USER-DPD/fix_shardlow.cpp +++ b/src/USER-DPD/fix_shardlow.cpp @@ -538,24 +538,34 @@ void FixShardlow::initial_integrate(int vflag) dtsqrt = sqrt(update->dt); ii = 0; - //Loop over all 14 directions (8 stages) - for (airnum = 1; airnum <=8; airnum++){ + // process neighbors in the local AIR + while (ii < inum) { + i = ilist[ii]; + int len = list->numneigh[i]; + if (len > 0) { + if (useDPDE) ssa_update_dpde(i, &(list->firstneigh[i][0]), len); + else ssa_update_dpd(i, &(list->firstneigh[i][0]), len); + } + ii++; + } - if (airnum > 1) { - // Communicate the updated velocities to all nodes - comm->forward_comm_fix(this); + ii = inum; + //Loop over all 13 outward directions (7 stages) + for (airnum = 1; airnum <=7; airnum++){ + int ct = list->AIRct_ssa[airnum]; - if(useDPDE){ - // Zero out the ghosts' uCond & uMech to be used as delta accumulators - memset(&(atom->uCond[nlocal]), 0, sizeof(double)*nghost); - memset(&(atom->uMech[nlocal]), 0, sizeof(double)*nghost); - } + // Communicate the updated velocities to all nodes + comm->forward_comm_fix(this); + + if(useDPDE){ + // Zero out the ghosts' uCond & uMech to be used as delta accumulators + memset(&(atom->uCond[nlocal]), 0, sizeof(double)*nghost); + memset(&(atom->uMech[nlocal]), 0, sizeof(double)*nghost); } // process neighbors in this AIR - while (ii < anum) { + while (ct-- > 0) { i = ilist[ii]; - if (atom->ssaAIR[i] > airnum) break; /* done with curent AIR */ int len = list->numneigh[i]; if (len > 0) { if (useDPDE) ssa_update_dpde(i, &(list->firstneigh[i][0]), len); @@ -565,7 +575,7 @@ void FixShardlow::initial_integrate(int vflag) } // Communicate the ghost deltas to the atom owners - if (airnum > 1) comm->reverse_comm_fix(this); + comm->reverse_comm_fix(this); } //End Loop over all directions For airnum = Top, Top-Right, Right, Bottom-Right, Back diff --git a/src/USER-DPD/npair_half_bin_newton_ssa.cpp b/src/USER-DPD/npair_half_bin_newton_ssa.cpp index b9306ee3b1..cc107a55c4 100644 --- a/src/USER-DPD/npair_half_bin_newton_ssa.cpp +++ b/src/USER-DPD/npair_half_bin_newton_ssa.cpp @@ -199,7 +199,7 @@ void NPairHalfBinNewtonSSA::build(NeighList *list) // loop over AIR ghost atoms, storing their local neighbors // since these are ghosts, must check if stencil bin is out of bounds for (int airnum = 2; airnum <= 8; airnum++) { - list->AIRct_ssa[airnum - 1] = nb_ssa->gairct_ssa[airnum]; + int locAIRct = 0; for (i = gairhead_ssa[airnum]; i >= 0; i = bins[i]) { n = 0; neighptr = ipage->vget(); @@ -254,13 +254,17 @@ void NPairHalfBinNewtonSSA::build(NeighList *list) } } - if (n > 0) ilist[inum + (gnum++)] = i; + if (n > 0) { + ilist[inum + (gnum++)] = i; + ++locAIRct; + } firstneigh[i] = neighptr; numneigh[i] = n; ipage->vgot(n); if (ipage->status()) error->one(FLERR,"Neighbor (ghost) list overflow, boost neigh_modify one"); } + list->AIRct_ssa[airnum - 1] = locAIRct; } list->gnum = gnum; } From 3dddeef365cfcab63e909d8388cc0f674419f6cd Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Fri, 27 Jan 2017 14:02:56 -0500 Subject: [PATCH 131/439] USER-DPD: remove unneeded gairct_ssa[] & anum vars, and some > 0 guards --- src/USER-DPD/fix_shardlow.cpp | 15 +++++---------- src/USER-DPD/nbin_ssa.cpp | 4 ---- src/USER-DPD/nbin_ssa.h | 1 - src/USER-DPD/npair_half_bin_newton_ssa.cpp | 9 ++++----- 4 files changed, 9 insertions(+), 20 deletions(-) diff --git a/src/USER-DPD/fix_shardlow.cpp b/src/USER-DPD/fix_shardlow.cpp index 9253d17317..4fa323a9d8 100644 --- a/src/USER-DPD/fix_shardlow.cpp +++ b/src/USER-DPD/fix_shardlow.cpp @@ -499,7 +499,7 @@ void FixShardlow::ssa_update_dpde( void FixShardlow::initial_integrate(int vflag) { - int i,ii,inum,anum; + int i,ii,inum; int *ilist; int nlocal = atom->nlocal; @@ -532,7 +532,6 @@ void FixShardlow::initial_integrate(int vflag) v_t0 = (double (*)[3]) memory->smalloc(sizeof(double)*3*nghost, "FixShardlow:v_t0"); inum = list->inum; - anum = inum + list->gnum; ilist = list->ilist; dtsqrt = sqrt(update->dt); @@ -542,10 +541,8 @@ void FixShardlow::initial_integrate(int vflag) while (ii < inum) { i = ilist[ii]; int len = list->numneigh[i]; - if (len > 0) { - if (useDPDE) ssa_update_dpde(i, &(list->firstneigh[i][0]), len); - else ssa_update_dpd(i, &(list->firstneigh[i][0]), len); - } + if (useDPDE) ssa_update_dpde(i, &(list->firstneigh[i][0]), len); + else ssa_update_dpd(i, &(list->firstneigh[i][0]), len); ii++; } @@ -567,10 +564,8 @@ void FixShardlow::initial_integrate(int vflag) while (ct-- > 0) { i = ilist[ii]; int len = list->numneigh[i]; - if (len > 0) { - if (useDPDE) ssa_update_dpde(i, &(list->firstneigh[i][0]), len); - else ssa_update_dpd(i, &(list->firstneigh[i][0]), len); - } + if (useDPDE) ssa_update_dpde(i, &(list->firstneigh[i][0]), len); + else ssa_update_dpd(i, &(list->firstneigh[i][0]), len); ii++; } diff --git a/src/USER-DPD/nbin_ssa.cpp b/src/USER-DPD/nbin_ssa.cpp index 321baf771a..7ea2117300 100644 --- a/src/USER-DPD/nbin_ssa.cpp +++ b/src/USER-DPD/nbin_ssa.cpp @@ -34,7 +34,6 @@ NBinSSA::NBinSSA(LAMMPS *lmp) : NBinStandard(lmp) binct_ssa = NULL; for (int i = 0; i < 9; i++) { gairhead_ssa[i] = -1; - gairct_ssa[i] = 0; } } @@ -69,7 +68,6 @@ void NBinSSA::bin_atoms() for (i = 0; i < 9; i++) { gairhead_ssa[i] = -1; - gairct_ssa[i] = 0; } for (i = 0; i < mbins; i++) { @@ -89,7 +87,6 @@ void NBinSSA::bin_atoms() if (mask[i] & bitmask) { bins[i] = gairhead_ssa[ibin]; gairhead_ssa[ibin] = i; - ++(gairct_ssa[ibin]); } } } else { @@ -98,7 +95,6 @@ void NBinSSA::bin_atoms() if (ibin < 2) continue; // skip ghost atoms not in AIR bins[i] = gairhead_ssa[ibin]; gairhead_ssa[ibin] = i; - ++(gairct_ssa[ibin]); } } for (i = nlocal-1; i >= 0; i--) { diff --git a/src/USER-DPD/nbin_ssa.h b/src/USER-DPD/nbin_ssa.h index 48694370b9..4ec376200c 100644 --- a/src/USER-DPD/nbin_ssa.h +++ b/src/USER-DPD/nbin_ssa.h @@ -32,7 +32,6 @@ class NBinSSA : public NBinStandard { int *binlist_ssa; // index in neighlist of 1st local atom in each bin int *binct_ssa; // count of local atoms in each bin int gairhead_ssa[9]; // index of 1st ghost atom in each AIR - int gairct_ssa[9]; // count of ghost atoms in each AIR int maxbin_ssa; // size of binlist_ssa and binct_ssa arrays // Bounds of the local atoms in the binhead array diff --git a/src/USER-DPD/npair_half_bin_newton_ssa.cpp b/src/USER-DPD/npair_half_bin_newton_ssa.cpp index cc107a55c4..ccc41d1fc4 100644 --- a/src/USER-DPD/npair_half_bin_newton_ssa.cpp +++ b/src/USER-DPD/npair_half_bin_newton_ssa.cpp @@ -180,21 +180,20 @@ void NPairHalfBinNewtonSSA::build(NeighList *list) } } - ilist[inum++] = i; + if (n > 0) { + ilist[inum++] = i; + } firstneigh[i] = neighptr; numneigh[i] = n; ipage->vgot(n); if (ipage->status()) error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); } - // verify count of atoms in ibin - if (binct_ssa[ibin] != (inum - binlist_ssa[ibin])) - error->one(FLERR,"binct_ssa didn't agree with length in ilist"); } } } - list->inum = inum; + list->AIRct_ssa[0] = list->inum = inum; // loop over AIR ghost atoms, storing their local neighbors // since these are ghosts, must check if stencil bin is out of bounds From f73c9a43aba9b5ff0837360ea7c3d4925906e5f6 Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Fri, 27 Jan 2017 16:45:15 -0500 Subject: [PATCH 132/439] USER-DPD: remove broken code for building SSA half neighbor list from full --- src/USER-DPD/npair_halffull_newton_ssa.cpp | 136 --------------------- src/USER-DPD/npair_halffull_newton_ssa.h | 44 ------- 2 files changed, 180 deletions(-) delete mode 100644 src/USER-DPD/npair_halffull_newton_ssa.cpp delete mode 100644 src/USER-DPD/npair_halffull_newton_ssa.h diff --git a/src/USER-DPD/npair_halffull_newton_ssa.cpp b/src/USER-DPD/npair_halffull_newton_ssa.cpp deleted file mode 100644 index d0be1685b6..0000000000 --- a/src/USER-DPD/npair_halffull_newton_ssa.cpp +++ /dev/null @@ -1,136 +0,0 @@ -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - http://lammps.sandia.gov, Sandia National Laboratories - Steve Plimpton, sjplimp@sandia.gov - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -/* ---------------------------------------------------------------------- - Contributing authors: - James Larentzos and Timothy I. Mattox (Engility Corporation) -------------------------------------------------------------------------- */ - -#include "npair_halffull_newton_ssa.h" -#include "neighbor.h" -#include "neigh_list.h" -#include "atom.h" -#include "atom_vec.h" -#include "molecule.h" -#include "domain.h" -#include "my_page.h" -#include "error.h" - -using namespace LAMMPS_NS; - -// allocate space for static class variable -// prototype for non-class function - -static int *ssaAIRptr; -static int cmp_ssaAIR(const void *, const void *); - -/* ---------------------------------------------------------------------- */ - -NPairHalffullNewtonSSA::NPairHalffullNewtonSSA(LAMMPS *lmp) : NPair(lmp) {} - -/* ---------------------------------------------------------------------- - build half list from full list for use by Shardlow Spliting Algorithm - pair stored once if i,j are both owned and i < j - if j is ghost, only store if j coords are "above and to the right" of i - works if full list is a skip list -------------------------------------------------------------------------- */ - -void NPairHalffullNewtonSSA::build(NeighList *list) -{ - int i,j,ii,jj,n,jnum,joriginal; - int *neighptr,*jlist; - - int nlocal = atom->nlocal; - int *ssaAIR = atom->ssaAIR; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - int *ilist_full = list->listfull->ilist; - int *numneigh_full = list->listfull->numneigh; - int **firstneigh_full = list->listfull->firstneigh; - int inum_full = list->listfull->inum; - - int inum = 0; - - error->one(FLERR,"NPairHalffullNewtonSSA not yet implemented for ghosts with neighbors."); - return; - - ipage->reset(); - - // loop over parent full list - - for (ii = 0; ii < inum_full; ii++) { - int AIRct[8] = { 0 }; - n = 0; - neighptr = ipage->vget(); - - i = ilist_full[ii]; - - // loop over full neighbor list - - jlist = firstneigh_full[i]; - jnum = numneigh_full[i]; - - for (jj = 0; jj < jnum; jj++) { - joriginal = jlist[jj]; - j = joriginal & NEIGHMASK; - if (j < nlocal) { - if (i > j) continue; - ++(AIRct[0]); - } else { - if (ssaAIR[j] < 2) continue; // skip ghost atoms not in AIR - ++(AIRct[ssaAIR[j] - 1]); - } - neighptr[n++] = joriginal; - } - - ilist[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - - // sort the locals+ghosts in the neighbor list by their ssaAIR number - - ssaAIRptr = atom->ssaAIR; - qsort(&(neighptr[0]), n, sizeof(int), cmp_ssaAIR); - - // do a prefix sum on the counts to turn them into indexes - - list->ndxAIR_ssa[i][0] = AIRct[0]; - for (int ndx = 1; ndx < 8; ++ndx) { - list->ndxAIR_ssa[i][ndx] = AIRct[ndx] + list->ndxAIR_ssa[i][ndx - 1]; - } - } - - list->inum = inum; -} - -/* ---------------------------------------------------------------------- - comparison function invoked by qsort() - accesses static class member ssaAIRptr, set before call to qsort() -------------------------------------------------------------------------- */ - -static int cmp_ssaAIR(const void *iptr, const void *jptr) -{ - int i = NEIGHMASK & *((int *) iptr); - int j = NEIGHMASK & *((int *) jptr); - if (ssaAIRptr[i] < ssaAIRptr[j]) return -1; - if (ssaAIRptr[i] > ssaAIRptr[j]) return 1; - return 0; -} - diff --git a/src/USER-DPD/npair_halffull_newton_ssa.h b/src/USER-DPD/npair_halffull_newton_ssa.h deleted file mode 100644 index 03903815b1..0000000000 --- a/src/USER-DPD/npair_halffull_newton_ssa.h +++ /dev/null @@ -1,44 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - http://lammps.sandia.gov, Sandia National Laboratories - Steve Plimpton, sjplimp@sandia.gov - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS - -NPairStyle(halffull/newton/ssa, - NPairHalffullNewtonSSA, - NP_HALF_FULL | NP_NSQ | NP_BIN | NP_MULTI | NP_NEWTON | - NP_ORTHO | NP_TRI | NP_SSA) - -#else - -#ifndef LMP_NPAIR_HALFFULL_NEWTON_SSA_H -#define LMP_NPAIR_HALFFULL_NEWTON_SSA_H - -#include "npair.h" - -namespace LAMMPS_NS { - -class NPairHalffullNewtonSSA : public NPair { - public: - NPairHalffullNewtonSSA(class LAMMPS *); - ~NPairHalffullNewtonSSA() {} - void build(class NeighList *); -}; - -} - -#endif -#endif - -/* ERROR/WARNING messages: - -*/ From 641bb4bb16c8f852af189ba1e71cd7b035e0c8e2 Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Fri, 27 Jan 2017 16:47:19 -0500 Subject: [PATCH 133/439] USER-DPD: remove use of ssaAIR[], move coord2ssaAIR() to nbin_ssa.cpp Saves an int per atom and ghost, also simplifies and reduces code size. --- src/USER-DPD/fix_shardlow.cpp | 116 ---------------------------------- src/USER-DPD/fix_shardlow.h | 13 ---- src/USER-DPD/nbin_ssa.cpp | 40 +++++++++++- src/USER-DPD/nbin_ssa.h | 1 + 4 files changed, 38 insertions(+), 132 deletions(-) diff --git a/src/USER-DPD/fix_shardlow.cpp b/src/USER-DPD/fix_shardlow.cpp index 4fa323a9d8..05bf1602f9 100644 --- a/src/USER-DPD/fix_shardlow.cpp +++ b/src/USER-DPD/fix_shardlow.cpp @@ -109,26 +109,12 @@ FixShardlow::FixShardlow(LAMMPS *lmp, int narg, char **arg) : if(pairDPD == NULL && pairDPDE == NULL) error->all(FLERR,"Must use pair_style dpd/fdt or dpd/fdt/energy with fix shardlow"); - // Setup the ssaAIR array - atom->ssaAIR = NULL; - grow_arrays(atom->nmax); - memset(atom->ssaAIR, 0, sizeof(int)*atom->nlocal); - - // Setup callbacks for maintaining atom->ssaAIR[] - atom->add_callback(0); // grow (aka exchange) - atom->add_callback(1); // restart - atom->add_callback(2); // border } /* ---------------------------------------------------------------------- */ FixShardlow::~FixShardlow() { - atom->delete_callback(id, 0); - atom->delete_callback(id, 1); - atom->delete_callback(id, 2); - - memory->destroy(atom->ssaAIR); } /* ---------------------------------------------------------------------- */ @@ -137,7 +123,6 @@ int FixShardlow::setmask() { int mask = 0; mask |= INITIAL_INTEGRATE; - mask |= PRE_EXCHANGE | MIN_PRE_EXCHANGE; return mask; } @@ -161,27 +146,6 @@ void FixShardlow::init_list(int id, NeighList *ptr) /* ---------------------------------------------------------------------- */ -void FixShardlow::pre_exchange() -{ - memset(atom->ssaAIR, 0, sizeof(int)*atom->nlocal); -} - -/* ---------------------------------------------------------------------- */ - -void FixShardlow::setup_pre_exchange() -{ - memset(atom->ssaAIR, 0, sizeof(int)*atom->nlocal); -} - -/* ---------------------------------------------------------------------- */ - -void FixShardlow::min_pre_exchange() -{ - memset(atom->ssaAIR, 0, sizeof(int)*atom->nlocal); -} - -/* ---------------------------------------------------------------------- */ - void FixShardlow::setup(int vflag) { bool fixShardlow = false; @@ -659,91 +623,11 @@ void FixShardlow::unpack_reverse_comm(int n, int *list, double *buf) } } -/* ---------------------------------------------------------------------- - convert atom coords into the ssa active interaction region number -------------------------------------------------------------------------- */ - -int FixShardlow::coord2ssaAIR(double *x) -{ - int ix, iy, iz; - - ix = iy = iz = 0; - if (x[2] < domain->sublo[2]) iz = -1; - if (x[2] >= domain->subhi[2]) iz = 1; - if (x[1] < domain->sublo[1]) iy = -1; - if (x[1] >= domain->subhi[1]) iy = 1; - if (x[0] < domain->sublo[0]) ix = -1; - if (x[0] >= domain->subhi[0]) ix = 1; - - if(iz < 0){ - return -1; - } else if(iz == 0){ - if( iy<0 ) return -1; // bottom left/middle/right - if( (iy==0) && (ix<0) ) return -1; // left atoms - if( (iy==0) && (ix==0) ) return 0; // Locally owned atoms - if( (iy==0) && (ix>0) ) return 3; // Right atoms - if( (iy>0) && (ix==0) ) return 2; // Top-middle atoms - if( (iy>0) && (ix!=0) ) return 4; // Top-right and top-left atoms - } else { // iz > 0 - if((ix==0) && (iy==0)) return 5; // Back atoms - if((ix==0) && (iy!=0)) return 6; // Top-back and bottom-back atoms - if((ix!=0) && (iy==0)) return 7; // Left-back and right-back atoms - if((ix!=0) && (iy!=0)) return 8; // Back corner atoms - } - - return -2; -} - /* ---------------------------------------------------------------------- */ -void FixShardlow::grow_arrays(int nmax) -{ - memory->grow(atom->ssaAIR,nmax,"fix_shardlow:ssaAIR"); -} - -void FixShardlow::copy_arrays(int i, int j, int delflag) -{ - atom->ssaAIR[j] = atom->ssaAIR[i]; -} - -void FixShardlow::set_arrays(int i) -{ - atom->ssaAIR[i] = 0; /* coord2ssaAIR(x[i]) */ -} - -int FixShardlow::pack_border(int n, int *list, double *buf) -{ - for (int i = 0; i < n; i++) { - int j = list[i]; - if (atom->ssaAIR[j] == 0) atom->ssaAIR[j] = 1; // not purely local anymore - } - return 0; -} - -int FixShardlow::unpack_border(int n, int first, double *buf) -{ - int i,last = first + n; - for (i = first; i < last; i++) { - atom->ssaAIR[i] = coord2ssaAIR(atom->x[i]); - } - return 0; -} - -int FixShardlow::unpack_exchange(int i, double *buf) -{ - atom->ssaAIR[i] = 0; /* coord2ssaAIR(x[i]) */ - return 0; -} - -void FixShardlow::unpack_restart(int i, int nth) -{ - atom->ssaAIR[i] = 0; /* coord2ssaAIR(x[i]) */ -} - double FixShardlow::memory_usage() { double bytes = 0.0; - bytes += memory->usage(atom->ssaAIR,atom->nmax); bytes += sizeof(double)*3*atom->nghost; // v_t0[] return bytes; } diff --git a/src/USER-DPD/fix_shardlow.h b/src/USER-DPD/fix_shardlow.h index 2ffb96ae7c..6fd438b8f0 100644 --- a/src/USER-DPD/fix_shardlow.h +++ b/src/USER-DPD/fix_shardlow.h @@ -35,18 +35,6 @@ class FixShardlow : public Fix { virtual void init_list(int, class NeighList *); virtual void setup(int); virtual void initial_integrate(int); - void setup_pre_exchange(); - void pre_exchange(); - void min_pre_exchange(); - - void grow_arrays(int); - void copy_arrays(int, int, int); - void set_arrays(int); - - int pack_border(int, int *, double *); - int unpack_border(int, int, double *); - int unpack_exchange(int, double *); - void unpack_restart(int, int); double memory_usage(); @@ -63,7 +51,6 @@ class FixShardlow : public Fix { private: double dtsqrt; // = sqrt(update->dt); - int coord2ssaAIR(double *); // map atom coord to an AIR number void ssa_update_dpd(int, int *, int); // Constant Temperature void ssa_update_dpde(int, int *, int); // Constant Energy diff --git a/src/USER-DPD/nbin_ssa.cpp b/src/USER-DPD/nbin_ssa.cpp index 7ea2117300..25a2fb3b35 100644 --- a/src/USER-DPD/nbin_ssa.cpp +++ b/src/USER-DPD/nbin_ssa.cpp @@ -20,6 +20,7 @@ #include "atom.h" #include "update.h" #include "group.h" +#include "domain.h" #include "memory.h" #include "error.h" @@ -58,7 +59,6 @@ void NBinSSA::bin_atoms() if (includegroup) nlocal = atom->nfirst; double **x = atom->x; int *mask = atom->mask; - int *ssaAIR = atom->ssaAIR; int xbin,ybin,zbin; last_bin = update->ntimestep; @@ -82,7 +82,7 @@ void NBinSSA::bin_atoms() int bitmask = group->bitmask[includegroup]; int nowned = atom->nlocal; // NOTE: nlocal was set to atom->nfirst above for (i = nall-1; i >= nowned; i--) { - ibin = ssaAIR[i]; + ibin = coord2ssaAIR(x[i]); if (ibin < 2) continue; // skip ghost atoms not in AIR if (mask[i] & bitmask) { bins[i] = gairhead_ssa[ibin]; @@ -91,7 +91,7 @@ void NBinSSA::bin_atoms() } } else { for (i = nall-1; i >= nlocal; i--) { - ibin = ssaAIR[i]; + ibin = coord2ssaAIR(x[i]); if (ibin < 2) continue; // skip ghost atoms not in AIR bins[i] = gairhead_ssa[ibin]; gairhead_ssa[ibin] = i; @@ -148,3 +148,37 @@ bigint NBinSSA::memory_usage() } return bytes; } + +/* ---------------------------------------------------------------------- + convert atom coords into the ssa active interaction region number +------------------------------------------------------------------------- */ +int NBinSSA::coord2ssaAIR(const double *x) +{ + int ix, iy, iz; + + ix = iy = iz = 0; + if (x[2] < domain->sublo[2]) iz = -1; + if (x[2] >= domain->subhi[2]) iz = 1; + if (x[1] < domain->sublo[1]) iy = -1; + if (x[1] >= domain->subhi[1]) iy = 1; + if (x[0] < domain->sublo[0]) ix = -1; + if (x[0] >= domain->subhi[0]) ix = 1; + + if(iz < 0){ + return -1; + } else if(iz == 0){ + if( iy<0 ) return -1; // bottom left/middle/right + if( (iy==0) && (ix<0) ) return -1; // left atoms + if( (iy==0) && (ix==0) ) return 0; // Locally owned atoms + if( (iy==0) && (ix>0) ) return 3; // Right atoms + if( (iy>0) && (ix==0) ) return 2; // Top-middle atoms + if( (iy>0) && (ix!=0) ) return 4; // Top-right and top-left atoms + } else { // iz > 0 + if((ix==0) && (iy==0)) return 5; // Back atoms + if((ix==0) && (iy!=0)) return 6; // Top-back and bottom-back atoms + if((ix!=0) && (iy==0)) return 7; // Left-back and right-back atoms + if((ix!=0) && (iy!=0)) return 8; // Back corner atoms + } + + return -2; +} diff --git a/src/USER-DPD/nbin_ssa.h b/src/USER-DPD/nbin_ssa.h index 4ec376200c..5db5a0fa41 100644 --- a/src/USER-DPD/nbin_ssa.h +++ b/src/USER-DPD/nbin_ssa.h @@ -155,6 +155,7 @@ class NBinSSA : public NBinStandard { } private: + int coord2ssaAIR(const double *); // map atom coord to an AIR number double bboxlo_[3],bboxhi_[3]; }; From ce2da5068b6e77c5a508e554ab824dc54328bd21 Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Mon, 30 Jan 2017 13:01:28 -0500 Subject: [PATCH 134/439] USER-DPD: renumber AIRs back to 1-7 for ghosts, and just 0 for locals. This removes the the distinction between pure and impure locals. Pure and impure locals messed up the directionality of half neighbor lists, which turns out is crucial to the approach for SSA with kokkos. --- src/USER-DPD/nbin_ssa.cpp | 22 +++++++++++----------- src/USER-DPD/nbin_ssa.h | 2 +- src/USER-DPD/npair_half_bin_newton_ssa.cpp | 4 ++-- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/USER-DPD/nbin_ssa.cpp b/src/USER-DPD/nbin_ssa.cpp index 25a2fb3b35..7e603af714 100644 --- a/src/USER-DPD/nbin_ssa.cpp +++ b/src/USER-DPD/nbin_ssa.cpp @@ -33,7 +33,7 @@ NBinSSA::NBinSSA(LAMMPS *lmp) : NBinStandard(lmp) maxbin_ssa = 0; binlist_ssa = NULL; binct_ssa = NULL; - for (int i = 0; i < 9; i++) { + for (int i = 0; i < 8; i++) { gairhead_ssa[i] = -1; } } @@ -66,7 +66,7 @@ void NBinSSA::bin_atoms() bboxlo_[0] = bboxlo[0]; bboxlo_[1] = bboxlo[1]; bboxlo_[2] = bboxlo[2]; bboxhi_[0] = bboxhi[0]; bboxhi_[1] = bboxhi[1]; bboxhi_[2] = bboxhi[2]; - for (i = 0; i < 9; i++) { + for (i = 0; i < 8; i++) { gairhead_ssa[i] = -1; } @@ -83,7 +83,7 @@ void NBinSSA::bin_atoms() int nowned = atom->nlocal; // NOTE: nlocal was set to atom->nfirst above for (i = nall-1; i >= nowned; i--) { ibin = coord2ssaAIR(x[i]); - if (ibin < 2) continue; // skip ghost atoms not in AIR + if (ibin < 1) continue; // skip ghost atoms not in AIR if (mask[i] & bitmask) { bins[i] = gairhead_ssa[ibin]; gairhead_ssa[ibin] = i; @@ -92,7 +92,7 @@ void NBinSSA::bin_atoms() } else { for (i = nall-1; i >= nlocal; i--) { ibin = coord2ssaAIR(x[i]); - if (ibin < 2) continue; // skip ghost atoms not in AIR + if (ibin < 1) continue; // skip ghost atoms not in AIR bins[i] = gairhead_ssa[ibin]; gairhead_ssa[ibin] = i; } @@ -170,14 +170,14 @@ int NBinSSA::coord2ssaAIR(const double *x) if( iy<0 ) return -1; // bottom left/middle/right if( (iy==0) && (ix<0) ) return -1; // left atoms if( (iy==0) && (ix==0) ) return 0; // Locally owned atoms - if( (iy==0) && (ix>0) ) return 3; // Right atoms - if( (iy>0) && (ix==0) ) return 2; // Top-middle atoms - if( (iy>0) && (ix!=0) ) return 4; // Top-right and top-left atoms + if( (iy==0) && (ix>0) ) return 2; // Right atoms + if( (iy>0) && (ix==0) ) return 1; // Top-middle atoms + if( (iy>0) && (ix!=0) ) return 3; // Top-right and top-left atoms } else { // iz > 0 - if((ix==0) && (iy==0)) return 5; // Back atoms - if((ix==0) && (iy!=0)) return 6; // Top-back and bottom-back atoms - if((ix!=0) && (iy==0)) return 7; // Left-back and right-back atoms - if((ix!=0) && (iy!=0)) return 8; // Back corner atoms + if((ix==0) && (iy==0)) return 4; // Back atoms + if((ix==0) && (iy!=0)) return 5; // Top-back and bottom-back atoms + if((ix!=0) && (iy==0)) return 6; // Left-back and right-back atoms + if((ix!=0) && (iy!=0)) return 7; // Back corner atoms } return -2; diff --git a/src/USER-DPD/nbin_ssa.h b/src/USER-DPD/nbin_ssa.h index 5db5a0fa41..f26f8c77f0 100644 --- a/src/USER-DPD/nbin_ssa.h +++ b/src/USER-DPD/nbin_ssa.h @@ -31,7 +31,7 @@ class NBinSSA : public NBinStandard { int *binlist_ssa; // index in neighlist of 1st local atom in each bin int *binct_ssa; // count of local atoms in each bin - int gairhead_ssa[9]; // index of 1st ghost atom in each AIR + int gairhead_ssa[8]; // index of 1st ghost atom in each AIR int maxbin_ssa; // size of binlist_ssa and binct_ssa arrays // Bounds of the local atoms in the binhead array diff --git a/src/USER-DPD/npair_half_bin_newton_ssa.cpp b/src/USER-DPD/npair_half_bin_newton_ssa.cpp index ccc41d1fc4..f3b7094bd8 100644 --- a/src/USER-DPD/npair_half_bin_newton_ssa.cpp +++ b/src/USER-DPD/npair_half_bin_newton_ssa.cpp @@ -197,7 +197,7 @@ void NPairHalfBinNewtonSSA::build(NeighList *list) // loop over AIR ghost atoms, storing their local neighbors // since these are ghosts, must check if stencil bin is out of bounds - for (int airnum = 2; airnum <= 8; airnum++) { + for (int airnum = 1; airnum <= 7; airnum++) { int locAIRct = 0; for (i = gairhead_ssa[airnum]; i >= 0; i = bins[i]) { n = 0; @@ -263,7 +263,7 @@ void NPairHalfBinNewtonSSA::build(NeighList *list) if (ipage->status()) error->one(FLERR,"Neighbor (ghost) list overflow, boost neigh_modify one"); } - list->AIRct_ssa[airnum - 1] = locAIRct; + list->AIRct_ssa[airnum] = locAIRct; } list->gnum = gnum; } From ee83b755eae4f3167fd2ab8b50bbf86cab3407ee Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Mon, 30 Jan 2017 14:32:18 -0500 Subject: [PATCH 135/439] USER-DPD: Split the SSA stencil and neighbor list into subphases. NOTE: pair evaluation order changes, causing numerical differences! This enables processing neighbors in subphase groups that enforce a geometrical seperation of pairs, allowing greater parallelism once fix_shardlow (SSA) is converted to Kokkos. --- src/USER-DPD/npair_half_bin_newton_ssa.cpp | 52 +++++---- .../nstencil_half_bin_2d_newton_ssa.cpp | 60 ++++++++-- .../nstencil_half_bin_3d_newton_ssa.cpp | 110 ++++++++++++++---- src/USER-DPD/nstencil_ssa.h | 2 +- 4 files changed, 165 insertions(+), 59 deletions(-) diff --git a/src/USER-DPD/npair_half_bin_newton_ssa.cpp b/src/USER-DPD/npair_half_bin_newton_ssa.cpp index f3b7094bd8..77b20966b0 100644 --- a/src/USER-DPD/npair_half_bin_newton_ssa.cpp +++ b/src/USER-DPD/npair_half_bin_newton_ssa.cpp @@ -74,7 +74,7 @@ void NPairHalfBinNewtonSSA::build(NeighList *list) NStencilSSA *ns_ssa = dynamic_cast(ns); if (!ns_ssa) error->one(FLERR, "NStencil wasn't a NStencilSSA object"); - int nstencil_half = ns_ssa->nstencil_half; + int *nstencil_ssa = &(ns_ssa->nstencil_ssa[0]); int nstencil_full = ns_ssa->nstencil; NBinSSA *nb_ssa = dynamic_cast(nb); @@ -150,34 +150,38 @@ void NPairHalfBinNewtonSSA::build(NeighList *list) // loop over all local atoms in other bins in "half" stencil - for (k = 0; k < nstencil_half; k++) { - for (j = binhead[ibin+stencil[k]]; j >= 0; - j = bins[j]) { + k = 0; + for (int subphase = 0; subphase < 4; subphase++) { + for (; k < nstencil_ssa[subphase]; k++) { + for (j = binhead[ibin+stencil[k]]; j >= 0; + j = bins[j]) { - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; + jtype = type[j]; + if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx*delx + dely*dely + delz*delz; - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; + if (rsq <= cutneighsq[itype][jtype]) { + if (molecular) { + if (!moltemplate) + which = find_special(special[i],nspecial[i],tag[j]); + else if (imol >= 0) + which = find_special(onemols[imol]->special[iatom], + onemols[imol]->nspecial[iatom], + tag[j]-tagprev); + else which = 0; + if (which == 0) neighptr[n++] = j; + else if (domain->minimum_image_check(delx,dely,delz)) + neighptr[n++] = j; + else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); + } else neighptr[n++] = j; + } } } + list->ndxAIR_ssa[i][subphase] = n; // record end of this subphase } if (n > 0) { diff --git a/src/USER-DPD/nstencil_half_bin_2d_newton_ssa.cpp b/src/USER-DPD/nstencil_half_bin_2d_newton_ssa.cpp index 254339bffc..af337a38c6 100644 --- a/src/USER-DPD/nstencil_half_bin_2d_newton_ssa.cpp +++ b/src/USER-DPD/nstencil_half_bin_2d_newton_ssa.cpp @@ -42,31 +42,69 @@ NStencilHalfBin2dNewtonSSA::NStencilHalfBin2dNewtonSSA(LAMMPS *lmp) : void NStencilHalfBin2dNewtonSSA::create() { int i,j,pos = 0; - + // Subphase 0: upper right front bins (red) for (j = 0; j <= sy; j++) - for (i = -sx; i <= sx; i++) - if (j > 0 || (j == 0 && i > 0)) + for (i = 0; i <= sx; i++) + if (j > 0 || i > 0) // skip the centroid if (bin_distance(i,j,0) < cutneighmaxsq) { stencilxyz[pos][0] = i; stencilxyz[pos][1] = j; stencilxyz[pos][2] = 0; stencil[pos++] = j*mbinx + i; } + nstencil_ssa[0] = pos; - nstencil_half = pos; // record where normal half stencil ends - - // include additional bins for AIR ghosts only - - for (j = -sy; j <= 0; j++) - for (i = -sx; i <= sx; i++) { - if (j == 0 && i > 0) continue; + // Subphase 1: upper left front bins (light blue) + for (j = 1; j <= sy; j++) + for (i = -sx; i < 0; i++) if (bin_distance(i,j,0) < cutneighmaxsq) { stencilxyz[pos][0] = i; stencilxyz[pos][1] = j; stencilxyz[pos][2] = 0; stencil[pos++] = j*mbinx + i; } - } + nstencil_ssa[1] = pos; + + // Subphase 2: lower left front bins (blue) + nstencil_ssa[2] = pos; + + // Subphase 3: lower right front bins (yellow) + nstencil_ssa[3] = pos; + + // Now include additional bins for AIR ghosts, and impure-to-pure locals + // Subphase 4: upper right back bins (pink) + nstencil_ssa[4] = pos; + + // Subphase 5: upper left back bins (light green) + nstencil_ssa[5] = pos; + + // Subphase 6: lower left back bins (purple) + for (j = -sy; j <= 0; j++) + for (i = -sx; i < 0; i++) + if (bin_distance(i,j,0) < cutneighmaxsq) { + stencilxyz[pos][0] = i; + stencilxyz[pos][1] = j; + stencilxyz[pos][2] = 0; + stencil[pos++] = j*mbinx + i; + } + nstencil_ssa[6] = pos; + + // Subphase 7: lower right back bins (white) + for (j = -sy; j < 0; j++) + for (i = 0; i <= sx; i++) + if (bin_distance(i,j,0) < cutneighmaxsq) { + stencilxyz[pos][0] = i; + stencilxyz[pos][1] = j; + stencilxyz[pos][2] = 0; + stencil[pos++] = j*mbinx + i; + } + nstencil_ssa[7] = pos; + + // Also, include the centroid for the AIR ghosts. + stencilxyz[pos][0] = 0; + stencilxyz[pos][1] = 0; + stencilxyz[pos][2] = 0; + stencil[pos++] = 0; nstencil = pos; // record where full stencil ends } diff --git a/src/USER-DPD/nstencil_half_bin_3d_newton_ssa.cpp b/src/USER-DPD/nstencil_half_bin_3d_newton_ssa.cpp index 1e2c18c66a..a2911a6d7b 100644 --- a/src/USER-DPD/nstencil_half_bin_3d_newton_ssa.cpp +++ b/src/USER-DPD/nstencil_half_bin_3d_newton_ssa.cpp @@ -42,45 +42,109 @@ NStencilHalfBin3dNewtonSSA::NStencilHalfBin3dNewtonSSA(LAMMPS *lmp) : void NStencilHalfBin3dNewtonSSA::create() { int i,j,k,pos = 0; - + // Subphase 0: upper right front bins (red) for (k = 0; k <= sz; k++) - for (j = -sy; j <= sy; j++) - for (i = -sx; i <= sx; i++) - if (k > 0 || j > 0 || (j == 0 && i > 0)) + for (j = 0; j <= sy; j++) + for (i = 0; i <= sx; i++) + if (k > 0 || j > 0 || i > 0) // skip the centroid if (bin_distance(i,j,k) < cutneighmaxsq) { stencilxyz[pos][0] = i; stencilxyz[pos][1] = j; stencilxyz[pos][2] = k; stencil[pos++] = k*mbiny*mbinx + j*mbinx + i; } + nstencil_ssa[0] = pos; - nstencil_half = pos; // record where normal half stencil ends - - // include additional bins for AIR ghosts only - - for (k = -sz; k < 0; k++) - for (j = -sy; j <= sy; j++) - for (i = -sx; i <= sx; i++) + // Subphase 1: upper left front bins (light blue) + for (k = 0; k <= sz; k++) + for (j = 1; j <= sy; j++) + for (i = -sx; i < 0; i++) if (bin_distance(i,j,k) < cutneighmaxsq) { stencilxyz[pos][0] = i; stencilxyz[pos][1] = j; stencilxyz[pos][2] = k; stencil[pos++] = k*mbiny*mbinx + j*mbinx + i; } + nstencil_ssa[1] = pos; - // For k==0, make sure to skip already included bins + // Subphase 2: lower left front bins (blue) + for (k = 1; k <= sz; k++) + for (j = -sy; j <= 0; j++) + for (i = -sx; i < 0; i++) + if (bin_distance(i,j,k) < cutneighmaxsq) { + stencilxyz[pos][0] = i; + stencilxyz[pos][1] = j; + stencilxyz[pos][2] = k; + stencil[pos++] = k*mbiny*mbinx + j*mbinx + i; + } + nstencil_ssa[2] = pos; - k = 0; - for (j = -sy; j <= 0; j++) - for (i = -sx; i <= sx; i++) { - if (j == 0 && i > 0) continue; - if (bin_distance(i,j,k) < cutneighmaxsq) { - stencilxyz[pos][0] = i; - stencilxyz[pos][1] = j; - stencilxyz[pos][2] = k; - stencil[pos++] = k*mbiny*mbinx + j*mbinx + i; - } - } + // Subphase 3: lower right front bins (yellow) + for (k = 1; k <= sz; k++) + for (j = -sy; j < 0; j++) + for (i = 0; i <= sx; i++) + if (bin_distance(i,j,k) < cutneighmaxsq) { + stencilxyz[pos][0] = i; + stencilxyz[pos][1] = j; + stencilxyz[pos][2] = k; + stencil[pos++] = k*mbiny*mbinx + j*mbinx + i; + } + nstencil_ssa[3] = pos; + + // Now include additional bins for AIR ghosts, and impure-to-pure locals + // Subphase 4: upper right back bins (pink) + for (k = -sz; k < 0; k++) + for (j = 0; j <= sy; j++) + for (i = 0; i <= sx; i++) + if (bin_distance(i,j,k) < cutneighmaxsq) { + stencilxyz[pos][0] = i; + stencilxyz[pos][1] = j; + stencilxyz[pos][2] = k; + stencil[pos++] = k*mbiny*mbinx + j*mbinx + i; + } + nstencil_ssa[4] = pos; + + // Subphase 5: upper left back bins (light green) + for (k = -sz; k < 0; k++) + for (j = 1; j <= sy; j++) + for (i = -sx; i < 0; i++) + if (bin_distance(i,j,k) < cutneighmaxsq) { + stencilxyz[pos][0] = i; + stencilxyz[pos][1] = j; + stencilxyz[pos][2] = k; + stencil[pos++] = k*mbiny*mbinx + j*mbinx + i; + } + nstencil_ssa[5] = pos; + + // Subphase 6: lower left back bins (purple) + for (k = -sz; k <= 0; k++) + for (j = -sy; j <= 0; j++) + for (i = -sx; i < 0; i++) + if (bin_distance(i,j,k) < cutneighmaxsq) { + stencilxyz[pos][0] = i; + stencilxyz[pos][1] = j; + stencilxyz[pos][2] = k; + stencil[pos++] = k*mbiny*mbinx + j*mbinx + i; + } + nstencil_ssa[6] = pos; + + // Subphase 7: lower right back bins (white) + for (k = -sz; k <= 0; k++) + for (j = -sy; j < 0; j++) + for (i = 0; i <= sx; i++) + if (bin_distance(i,j,k) < cutneighmaxsq) { + stencilxyz[pos][0] = i; + stencilxyz[pos][1] = j; + stencilxyz[pos][2] = k; + stencil[pos++] = k*mbiny*mbinx + j*mbinx + i; + } + nstencil_ssa[7] = pos; + + // Also, include the centroid for the AIR ghosts. + stencilxyz[pos][0] = 0; + stencilxyz[pos][1] = 0; + stencilxyz[pos][2] = 0; + stencil[pos++] = 0; nstencil = pos; // record where full stencil ends } diff --git a/src/USER-DPD/nstencil_ssa.h b/src/USER-DPD/nstencil_ssa.h index e6dfce60f4..a5e3723271 100644 --- a/src/USER-DPD/nstencil_ssa.h +++ b/src/USER-DPD/nstencil_ssa.h @@ -24,7 +24,7 @@ class NStencilSSA : public NStencil { ~NStencilSSA() {} virtual void create() = 0; - int nstencil_half; // where the half stencil ends + int nstencil_ssa[8]; // last stencil index for each subphase }; } From be166cb5bf3743b0598009570d44cfe96b327979 Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Mon, 30 Jan 2017 15:03:43 -0500 Subject: [PATCH 136/439] USER-DPD: Use subphases when processing AIR zero (locals) in SSA. NOTE: pair ordering was NOT changed, but tiny differences could occur. --- src/USER-DPD/fix_shardlow.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/USER-DPD/fix_shardlow.cpp b/src/USER-DPD/fix_shardlow.cpp index 05bf1602f9..4220760a9b 100644 --- a/src/USER-DPD/fix_shardlow.cpp +++ b/src/USER-DPD/fix_shardlow.cpp @@ -504,9 +504,14 @@ void FixShardlow::initial_integrate(int vflag) // process neighbors in the local AIR while (ii < inum) { i = ilist[ii]; - int len = list->numneigh[i]; - if (useDPDE) ssa_update_dpde(i, &(list->firstneigh[i][0]), len); - else ssa_update_dpd(i, &(list->firstneigh[i][0]), len); + for (int subphase = 0; subphase < 4; subphase++) { + int start = (subphase > 0) ? list->ndxAIR_ssa[i][subphase - 1] : 0; + int len = list->ndxAIR_ssa[i][subphase] - start; + if (len > 0) { + if (useDPDE) ssa_update_dpde(i, &(list->firstneigh[i][start]), len); + else ssa_update_dpd(i, &(list->firstneigh[i][start]), len); + } + } ii++; } From 52aaad907f356e6ab1e553512d343fcf641a547a Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Tue, 7 Feb 2017 12:18:27 -0500 Subject: [PATCH 137/439] USER-DPD: SSA with Kokkos: Reorder stencil subphases to make things easier. --- .../nstencil_half_bin_2d_newton_ssa.cpp | 16 ++++++------- .../nstencil_half_bin_3d_newton_ssa.cpp | 24 +++++++++---------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/USER-DPD/nstencil_half_bin_2d_newton_ssa.cpp b/src/USER-DPD/nstencil_half_bin_2d_newton_ssa.cpp index af337a38c6..084d5b0602 100644 --- a/src/USER-DPD/nstencil_half_bin_2d_newton_ssa.cpp +++ b/src/USER-DPD/nstencil_half_bin_2d_newton_ssa.cpp @@ -65,10 +65,10 @@ void NStencilHalfBin2dNewtonSSA::create() } nstencil_ssa[1] = pos; - // Subphase 2: lower left front bins (blue) + // Subphase 2: lower right front bins (yellow) nstencil_ssa[2] = pos; - // Subphase 3: lower right front bins (yellow) + // Subphase 3: lower left front bins (blue) nstencil_ssa[3] = pos; // Now include additional bins for AIR ghosts, and impure-to-pure locals @@ -78,9 +78,9 @@ void NStencilHalfBin2dNewtonSSA::create() // Subphase 5: upper left back bins (light green) nstencil_ssa[5] = pos; - // Subphase 6: lower left back bins (purple) - for (j = -sy; j <= 0; j++) - for (i = -sx; i < 0; i++) + // Subphase 6: lower right back bins (white) + for (j = -sy; j < 0; j++) + for (i = 0; i <= sx; i++) if (bin_distance(i,j,0) < cutneighmaxsq) { stencilxyz[pos][0] = i; stencilxyz[pos][1] = j; @@ -89,9 +89,9 @@ void NStencilHalfBin2dNewtonSSA::create() } nstencil_ssa[6] = pos; - // Subphase 7: lower right back bins (white) - for (j = -sy; j < 0; j++) - for (i = 0; i <= sx; i++) + // Subphase 7: lower left back bins (purple) + for (j = -sy; j <= 0; j++) + for (i = -sx; i < 0; i++) if (bin_distance(i,j,0) < cutneighmaxsq) { stencilxyz[pos][0] = i; stencilxyz[pos][1] = j; diff --git a/src/USER-DPD/nstencil_half_bin_3d_newton_ssa.cpp b/src/USER-DPD/nstencil_half_bin_3d_newton_ssa.cpp index a2911a6d7b..1741a1e847 100644 --- a/src/USER-DPD/nstencil_half_bin_3d_newton_ssa.cpp +++ b/src/USER-DPD/nstencil_half_bin_3d_newton_ssa.cpp @@ -67,10 +67,10 @@ void NStencilHalfBin3dNewtonSSA::create() } nstencil_ssa[1] = pos; - // Subphase 2: lower left front bins (blue) + // Subphase 2: lower right front bins (yellow) for (k = 1; k <= sz; k++) - for (j = -sy; j <= 0; j++) - for (i = -sx; i < 0; i++) + for (j = -sy; j < 0; j++) + for (i = 0; i <= sx; i++) if (bin_distance(i,j,k) < cutneighmaxsq) { stencilxyz[pos][0] = i; stencilxyz[pos][1] = j; @@ -79,10 +79,10 @@ void NStencilHalfBin3dNewtonSSA::create() } nstencil_ssa[2] = pos; - // Subphase 3: lower right front bins (yellow) + // Subphase 3: lower left front bins (blue) for (k = 1; k <= sz; k++) - for (j = -sy; j < 0; j++) - for (i = 0; i <= sx; i++) + for (j = -sy; j <= 0; j++) + for (i = -sx; i < 0; i++) if (bin_distance(i,j,k) < cutneighmaxsq) { stencilxyz[pos][0] = i; stencilxyz[pos][1] = j; @@ -116,10 +116,10 @@ void NStencilHalfBin3dNewtonSSA::create() } nstencil_ssa[5] = pos; - // Subphase 6: lower left back bins (purple) + // Subphase 6: lower right back bins (white) for (k = -sz; k <= 0; k++) - for (j = -sy; j <= 0; j++) - for (i = -sx; i < 0; i++) + for (j = -sy; j < 0; j++) + for (i = 0; i <= sx; i++) if (bin_distance(i,j,k) < cutneighmaxsq) { stencilxyz[pos][0] = i; stencilxyz[pos][1] = j; @@ -128,10 +128,10 @@ void NStencilHalfBin3dNewtonSSA::create() } nstencil_ssa[6] = pos; - // Subphase 7: lower right back bins (white) + // Subphase 7: lower left back bins (purple) for (k = -sz; k <= 0; k++) - for (j = -sy; j < 0; j++) - for (i = 0; i <= sx; i++) + for (j = -sy; j <= 0; j++) + for (i = -sx; i < 0; i++) if (bin_distance(i,j,k) < cutneighmaxsq) { stencilxyz[pos][0] = i; stencilxyz[pos][1] = j; From 151b3f552bfdfcc915a4ed429b210342a3e1837f Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Tue, 7 Feb 2017 12:53:45 -0500 Subject: [PATCH 138/439] USER-DPD: Save pointer to the NPair used to create the NeighList Gives a user of NeighList access to data stored in a custom NPair --- src/neigh_list.cpp | 1 + src/neigh_list.h | 1 + src/neighbor.cpp | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/neigh_list.cpp b/src/neigh_list.cpp index edc8634373..e8fd4130fc 100644 --- a/src/neigh_list.cpp +++ b/src/neigh_list.cpp @@ -79,6 +79,7 @@ NeighList::NeighList(LAMMPS *lmp) : Pointers(lmp) // USER-DPD package ndxAIR_ssa = NULL; + np = NULL; } /* ---------------------------------------------------------------------- */ diff --git a/src/neigh_list.h b/src/neigh_list.h index 7649245e99..ea88e9b28b 100644 --- a/src/neigh_list.h +++ b/src/neigh_list.h @@ -82,6 +82,7 @@ class NeighList : protected Pointers { int AIRct_ssa[8]; // count of how many atoms in each AIR uint16_t (*ndxAIR_ssa)[8]; // for each atom, last neighbor index of each AIR + class NPair *np; // ptr to NPair instance I depend on // methods diff --git a/src/neighbor.cpp b/src/neighbor.cpp index e0b84cc410..148dcbd7e9 100644 --- a/src/neighbor.cpp +++ b/src/neighbor.cpp @@ -785,7 +785,7 @@ int Neighbor::init_pair() } PairCreator pair_creator = pairclass[flag-1]; - neigh_pair[i] = pair_creator(lmp); + lists[i]->np = neigh_pair[i] = pair_creator(lmp); neigh_pair[i]->post_constructor(requests[i]); neigh_pair[i]->istyle = flag; From ab32d136b97e0f83e4a8e21e60251394623f1787 Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Tue, 7 Feb 2017 13:03:07 -0500 Subject: [PATCH 139/439] USER-DPD: SSA with Kokkos: make stencil's sx, sy, sz variables public --- src/nstencil.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nstencil.h b/src/nstencil.h index 7985d23202..a4c6a4af66 100644 --- a/src/nstencil.h +++ b/src/nstencil.h @@ -30,6 +30,7 @@ class NStencil : protected Pointers { int *nstencil_multi; // # bins in each type-based multi stencil int **stencil_multi; // list of bin offsets in each stencil double **distsq_multi; // sq distances to bins in each stencil + int sx,sy,sz; // extent of stencil in each dim double cutoff_custom; // cutoff set by requestor @@ -64,7 +65,6 @@ class NStencil : protected Pointers { int xyzflag; // 1 if stencilxyz is allocated int maxstencil; // max size of stencil int maxstencil_multi; // max sizes of stencils - int sx,sy,sz; // extent of stencil in each dim int dimension; From 4b3197202ba2fc56f946376719bce24f1452897f Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Tue, 7 Feb 2017 13:38:49 -0500 Subject: [PATCH 140/439] USER-DPD: Rework SSA to use a new neighbor list structure, ready for Kokkos NOTE: pair evaluation order changes, causing numerical differences! Atom pair processing order is fully planned out in npair_half_bin_newton_ssa Makes the SSA neighbor list structure very different. Do not use by others! Each local is in ilist, numneigh, and firstneigh four times instead of once. Changes LAMMPS core code that had been previously changed for USER-DPD/SSA: Removes ssaAIR[] from class Atom as it is now unused. Removes ndxAIR_ssa[] from class NeighList as it is now unused. Increases length of ilist[], numneigh[], and firstneigh[] if SSA flag set. --- src/USER-DPD/fix_shardlow.cpp | 39 ++-- src/USER-DPD/nbin_ssa.cpp | 20 -- src/USER-DPD/nbin_ssa.h | 3 - src/USER-DPD/npair_half_bin_newton_ssa.cpp | 204 ++++++++++++++------- src/USER-DPD/npair_half_bin_newton_ssa.h | 11 +- src/atom.cpp | 2 - src/atom.h | 1 - src/neigh_list.cpp | 22 +-- src/neigh_list.h | 1 - 9 files changed, 174 insertions(+), 129 deletions(-) diff --git a/src/USER-DPD/fix_shardlow.cpp b/src/USER-DPD/fix_shardlow.cpp index 4220760a9b..4a7fff66cf 100644 --- a/src/USER-DPD/fix_shardlow.cpp +++ b/src/USER-DPD/fix_shardlow.cpp @@ -55,6 +55,7 @@ #include "pair_dpd_fdt.h" #include "pair_dpd_fdt_energy.h" #include "pair.h" +#include "npair_half_bin_newton_ssa.h" #include "citeme.h" using namespace LAMMPS_NS; @@ -500,19 +501,30 @@ void FixShardlow::initial_integrate(int vflag) dtsqrt = sqrt(update->dt); - ii = 0; + NPairHalfBinNewtonSSA *np_ssa = dynamic_cast(list->np); + if (!np_ssa) error->one(FLERR, "NPair wasn't a NPairHalfBinNewtonSSA object"); + int ssa_phaseCt = np_ssa->ssa_phaseCt; + int *ssa_phaseLen = np_ssa->ssa_phaseLen; + int **ssa_itemLoc = np_ssa->ssa_itemLoc; + int **ssa_itemLen = np_ssa->ssa_itemLen; + // process neighbors in the local AIR - while (ii < inum) { - i = ilist[ii]; - for (int subphase = 0; subphase < 4; subphase++) { - int start = (subphase > 0) ? list->ndxAIR_ssa[i][subphase - 1] : 0; - int len = list->ndxAIR_ssa[i][subphase] - start; - if (len > 0) { - if (useDPDE) ssa_update_dpde(i, &(list->firstneigh[i][start]), len); - else ssa_update_dpd(i, &(list->firstneigh[i][start]), len); + for (int workPhase = 0; workPhase < ssa_phaseCt; ++workPhase) { + int workItemCt = ssa_phaseLen[workPhase]; + + for (int workItem = 0; workItem < workItemCt; ++workItem) { + int ct = ssa_itemLen[workPhase][workItem]; + ii = ssa_itemLoc[workPhase][workItem]; + + while (ct-- > 0) { + int len = list->numneigh[ii]; + if (len > 0) { + if (useDPDE) ssa_update_dpde(ilist[ii], list->firstneigh[ii], len); + else ssa_update_dpd(ilist[ii], list->firstneigh[ii], len); + } + ii++; } } - ii++; } ii = inum; @@ -531,10 +543,9 @@ void FixShardlow::initial_integrate(int vflag) // process neighbors in this AIR while (ct-- > 0) { - i = ilist[ii]; - int len = list->numneigh[i]; - if (useDPDE) ssa_update_dpde(i, &(list->firstneigh[i][0]), len); - else ssa_update_dpd(i, &(list->firstneigh[i][0]), len); + int len = list->numneigh[ii]; + if (useDPDE) ssa_update_dpde(ilist[ii], list->firstneigh[ii], len); + else ssa_update_dpd(ilist[ii], list->firstneigh[ii], len); ii++; } diff --git a/src/USER-DPD/nbin_ssa.cpp b/src/USER-DPD/nbin_ssa.cpp index 7e603af714..4c57a8e70f 100644 --- a/src/USER-DPD/nbin_ssa.cpp +++ b/src/USER-DPD/nbin_ssa.cpp @@ -30,9 +30,6 @@ using namespace LAMMPS_NS; NBinSSA::NBinSSA(LAMMPS *lmp) : NBinStandard(lmp) { - maxbin_ssa = 0; - binlist_ssa = NULL; - binct_ssa = NULL; for (int i = 0; i < 8; i++) { gairhead_ssa[i] = -1; } @@ -40,8 +37,6 @@ NBinSSA::NBinSSA(LAMMPS *lmp) : NBinStandard(lmp) NBinSSA::~NBinSSA() { - memory->destroy(binlist_ssa); - memory->destroy(binct_ssa); } /* ---------------------------------------------------------------------- @@ -72,8 +67,6 @@ void NBinSSA::bin_atoms() for (i = 0; i < mbins; i++) { binhead[i] = -1; - binlist_ssa[i] = -1; - binct_ssa[i] = 0; } // bin in reverse order so linked list will be in forward order @@ -108,7 +101,6 @@ void NBinSSA::bin_atoms() if (zbin >= lbinzhi) lbinzhi = zbin + 1; bins[i] = binhead[ibin]; binhead[ibin] = i; - ++(binct_ssa[ibin]); } } @@ -119,14 +111,6 @@ void NBinSSA::bin_atoms_setup(int nall) { NBinStandard::bin_atoms_setup(nall); // Setup the parent class's data too - if (mbins > maxbin_ssa) { - maxbin_ssa = mbins; - memory->destroy(binlist_ssa); - memory->destroy(binct_ssa); - memory->create(binlist_ssa,maxbin_ssa,"binlist_ssa"); - memory->create(binct_ssa,maxbin_ssa,"binct_ssa"); - } - // Clear the local bin extent bounding box. lbinxlo = mbinx - 1; // Safe to = stencil->sx + 1 lbinylo = mbiny - 1; // Safe to = stencil->sy + 1 @@ -142,10 +126,6 @@ bigint NBinSSA::memory_usage() { bigint bytes = NBinStandard::memory_usage(); // Count the parent's usage too - if (maxbin_ssa) { - bytes += memory->usage(binlist_ssa,maxbin_ssa); - bytes += memory->usage(binct_ssa,maxbin_ssa); - } return bytes; } diff --git a/src/USER-DPD/nbin_ssa.h b/src/USER-DPD/nbin_ssa.h index f26f8c77f0..2a0175081e 100644 --- a/src/USER-DPD/nbin_ssa.h +++ b/src/USER-DPD/nbin_ssa.h @@ -29,10 +29,7 @@ namespace LAMMPS_NS { class NBinSSA : public NBinStandard { public: - int *binlist_ssa; // index in neighlist of 1st local atom in each bin - int *binct_ssa; // count of local atoms in each bin int gairhead_ssa[8]; // index of 1st ghost atom in each AIR - int maxbin_ssa; // size of binlist_ssa and binct_ssa arrays // Bounds of the local atoms in the binhead array int lbinxlo; // lowest local bin x-dim coordinate diff --git a/src/USER-DPD/npair_half_bin_newton_ssa.cpp b/src/USER-DPD/npair_half_bin_newton_ssa.cpp index 77b20966b0..2c787d6398 100644 --- a/src/USER-DPD/npair_half_bin_newton_ssa.cpp +++ b/src/USER-DPD/npair_half_bin_newton_ssa.cpp @@ -34,7 +34,27 @@ using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ -NPairHalfBinNewtonSSA::NPairHalfBinNewtonSSA(LAMMPS *lmp) : NPair(lmp) {} +NPairHalfBinNewtonSSA::NPairHalfBinNewtonSSA(LAMMPS *lmp) : NPair(lmp) +{ + ssa_maxPhaseCt = 0; + ssa_maxPhaseLen = 0; + ssa_phaseCt = 0; + ssa_phaseLen = NULL; + ssa_itemLoc = NULL; + ssa_itemLen = NULL; +} + +/* ---------------------------------------------------------------------- */ + +NPairHalfBinNewtonSSA::~NPairHalfBinNewtonSSA() +{ + ssa_maxPhaseCt = 0; + ssa_maxPhaseLen = 0; + ssa_phaseCt = 0; + memory->destroy(ssa_phaseLen); + memory->destroy(ssa_itemLoc); + memory->destroy(ssa_itemLen); +} /* ---------------------------------------------------------------------- binned neighbor list construction with full Newton's 3rd law @@ -81,8 +101,6 @@ void NPairHalfBinNewtonSSA::build(NeighList *list) if (!nb_ssa) error->one(FLERR, "NBin wasn't a NBinSSA object"); int *bins = nb_ssa->bins; int *binhead = nb_ssa->binhead; - int *binlist_ssa = nb_ssa->binlist_ssa; - int *binct_ssa = nb_ssa->binct_ssa; int *gairhead_ssa = &(nb_ssa->gairhead_ssa[0]); int inum = 0; @@ -96,74 +114,81 @@ void NPairHalfBinNewtonSSA::build(NeighList *list) int lbinzlo = nb_ssa->lbinzlo; int lbinzhi = nb_ssa->lbinzhi; + int sx1 = ns_ssa->sx + 1; + int sy1 = ns_ssa->sy + 1; + int sz1 = ns_ssa->sz + 1; + + ssa_phaseCt = sz1*sy1*sx1; + + xbin = (lbinxhi - lbinxlo + sx1 - 1) / sx1 + 1; + ybin = (lbinyhi - lbinylo + sy1 - 1) / sy1 + 1; + zbin = (lbinzhi - lbinzlo + sz1 - 1) / sz1 + 1; + + int phaseLenEstimate = xbin*ybin*zbin; + + if (ssa_phaseCt > ssa_maxPhaseCt) { + ssa_maxPhaseCt = ssa_phaseCt; + ssa_maxPhaseLen = 0; + memory->destroy(ssa_phaseLen); + memory->destroy(ssa_itemLoc); + memory->destroy(ssa_itemLen); + memory->create(ssa_phaseLen,ssa_maxPhaseCt,"NPairHalfBinNewtonSSA:ssa_phaseLen"); + } + + if (phaseLenEstimate > ssa_maxPhaseLen) { + ssa_maxPhaseLen = phaseLenEstimate; + memory->destroy(ssa_itemLoc); + memory->destroy(ssa_itemLen); + memory->create(ssa_itemLoc,ssa_maxPhaseCt,ssa_maxPhaseLen,"NPairHalfBinNewtonSSA:ssa_itemLoc"); + memory->create(ssa_itemLen,ssa_maxPhaseCt,ssa_maxPhaseLen,"NPairHalfBinNewtonSSA:ssa_itemLen"); + } + ipage->reset(); + int workPhase = 0; // loop over bins with local atoms, storing half of the neighbors - for (zbin = lbinzlo; zbin < lbinzhi; zbin++) { - for (ybin = lbinylo; ybin < lbinyhi; ybin++) { - for (xbin = lbinxlo; xbin < lbinxhi; xbin++) { - ibin = zbin*mbiny*mbinx + ybin*mbinx + xbin; - binlist_ssa[ibin] = inum; // record where ibin starts in ilist - for (i = binhead[ibin]; i >= 0; i = bins[i]) { - n = 0; - neighptr = ipage->vget(); + for (int zoff = ns_ssa->sz; zoff >= 0; --zoff) { + for (int yoff = ns_ssa->sy; yoff >= 0; --yoff) { + for (int xoff = ns_ssa->sx; xoff >= 0; --xoff) { + int workItem = 0; + for (zbin = lbinzlo + zoff; zbin < lbinzhi; zbin += sz1) { + for (ybin = lbinylo + yoff - ns_ssa->sy; ybin < lbinyhi; ybin += sy1) { + for (xbin = lbinxlo + xoff - ns_ssa->sx; xbin < lbinxhi; xbin += sz1) { + if (workItem >= phaseLenEstimate) error->one(FLERR,"phaseLenEstimate was too small"); + ssa_itemLoc[workPhase][workItem] = inum; // record where workItem starts in ilist - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over rest of local atoms in i's bin - // just store them, since j is beyond i in linked list - - for (j = bins[i]; j >= 0; j = bins[j]) { - - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; - } - } - - // loop over all local atoms in other bins in "half" stencil - - k = 0; for (int subphase = 0; subphase < 4; subphase++) { - for (; k < nstencil_ssa[subphase]; k++) { - for (j = binhead[ibin+stencil[k]]; j >= 0; - j = bins[j]) { + int s_ybin = ybin + ((subphase & 0x2) ? ns_ssa->sy : 0); + int s_xbin = xbin + ((subphase & 0x1) ? ns_ssa->sx : 0); + int ibin, ct; + if ((s_ybin < lbinylo) || (s_ybin >= lbinyhi)) continue; + if ((s_xbin < lbinxlo) || (s_xbin >= lbinxhi)) continue; + ibin = zbin*nb_ssa->mbiny*nb_ssa->mbinx + + s_ybin*nb_ssa->mbinx + + s_xbin; + + for (i = binhead[ibin]; i >= 0; i = bins[i]) { + n = 0; + neighptr = ipage->vget(); + itype = type[i]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + if (moltemplate) { + imol = molindex[i]; + iatom = molatom[i]; + tagprev = tag[i] - iatom - 1; + } + // loop over rest of local atoms in i's bin if this is subphase 0 + // just store them, since j is beyond i in linked list + if (subphase == 0) for (j = bins[i]; j >= 0; j = bins[j]) { jtype = type[j]; if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - delx = xtmp - x[j][0]; dely = ytmp - x[j][1]; delz = ztmp - x[j][2]; rsq = delx*delx + dely*dely + delz*delz; - if (rsq <= cutneighsq[itype][jtype]) { if (molecular) { if (!moltemplate) @@ -180,22 +205,59 @@ void NPairHalfBinNewtonSSA::build(NeighList *list) } else neighptr[n++] = j; } } - } - list->ndxAIR_ssa[i][subphase] = n; // record end of this subphase - } - if (n > 0) { - ilist[inum++] = i; + // loop over all local atoms in other bins in "subphase" of stencil + k = (subphase > 0) ? nstencil_ssa[subphase - 1] : 0; + for (; k < nstencil_ssa[subphase]; k++) { + for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) { + jtype = type[j]; + if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx*delx + dely*dely + delz*delz; + if (rsq <= cutneighsq[itype][jtype]) { + if (molecular) { + if (!moltemplate) + which = find_special(special[i],nspecial[i],tag[j]); + else if (imol >= 0) + which = find_special(onemols[imol]->special[iatom], + onemols[imol]->nspecial[iatom], + tag[j]-tagprev); + else which = 0; + if (which == 0) neighptr[n++] = j; + else if (domain->minimum_image_check(delx,dely,delz)) + neighptr[n++] = j; + else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); + } else neighptr[n++] = j; + } + } + } + + if (n > 0) { + firstneigh[inum] = neighptr; + numneigh[inum] = n; + ilist[inum++] = i; + } + ipage->vgot(n); + if (ipage->status()) + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + } } - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + // record where workItem ends in ilist + ssa_itemLen[workPhase][workItem] = inum - ssa_itemLoc[workPhase][workItem]; + if (ssa_itemLen[workPhase][workItem] > 0) workItem++; } } } + + // record where workPhase ends + ssa_phaseLen[workPhase++] = workItem; } + } + } + + if (ssa_phaseCt != workPhase) error->one(FLERR,"ssa_phaseCt was wrong"); list->AIRct_ssa[0] = list->inum = inum; @@ -258,11 +320,11 @@ void NPairHalfBinNewtonSSA::build(NeighList *list) } if (n > 0) { + firstneigh[inum + gnum] = neighptr; + numneigh[inum + gnum] = n; ilist[inum + (gnum++)] = i; ++locAIRct; } - firstneigh[i] = neighptr; - numneigh[i] = n; ipage->vgot(n); if (ipage->status()) error->one(FLERR,"Neighbor (ghost) list overflow, boost neigh_modify one"); diff --git a/src/USER-DPD/npair_half_bin_newton_ssa.h b/src/USER-DPD/npair_half_bin_newton_ssa.h index c9ccbc4bd9..ea292316ca 100644 --- a/src/USER-DPD/npair_half_bin_newton_ssa.h +++ b/src/USER-DPD/npair_half_bin_newton_ssa.h @@ -28,9 +28,18 @@ namespace LAMMPS_NS { class NPairHalfBinNewtonSSA : public NPair { public: + // SSA Work plan data structures + int ssa_phaseCt; + int *ssa_phaseLen; + int **ssa_itemLoc; + int **ssa_itemLen; + NPairHalfBinNewtonSSA(class LAMMPS *); - ~NPairHalfBinNewtonSSA() {} + ~NPairHalfBinNewtonSSA(); void build(class NeighList *); + private: + int ssa_maxPhaseCt; + int ssa_maxPhaseLen; }; } diff --git a/src/atom.cpp b/src/atom.cpp index 0920dc3a02..de98b65470 100644 --- a/src/atom.cpp +++ b/src/atom.cpp @@ -99,7 +99,6 @@ Atom::Atom(LAMMPS *lmp) : Pointers(lmp) uCond = uMech = uChem = uCG = uCGnew = NULL; duChem = NULL; dpdTheta = NULL; - ssaAIR = NULL; // USER-SMD @@ -296,7 +295,6 @@ Atom::~Atom() memory->destroy(uCG); memory->destroy(uCGnew); memory->destroy(duChem); - memory->destroy(ssaAIR); memory->destroy(nspecial); memory->destroy(special); diff --git a/src/atom.h b/src/atom.h index de7cda06ac..745377cee1 100644 --- a/src/atom.h +++ b/src/atom.h @@ -93,7 +93,6 @@ class Atom : protected Pointers { double *duChem; double *dpdTheta; int nspecies_dpd; - int *ssaAIR; // Shardlow Splitting Algorithm Active Interaction Region number // molecular info diff --git a/src/neigh_list.cpp b/src/neigh_list.cpp index e8fd4130fc..6376637832 100644 --- a/src/neigh_list.cpp +++ b/src/neigh_list.cpp @@ -78,7 +78,7 @@ NeighList::NeighList(LAMMPS *lmp) : Pointers(lmp) // USER-DPD package - ndxAIR_ssa = NULL; + for (int i = 0; i < 8; i++) AIRct_ssa[i] = 0; np = NULL; } @@ -98,10 +98,6 @@ NeighList::~NeighList() delete [] iskip; memory->destroy(ijskip); - - if (ssa) { - memory->sfree(ndxAIR_ssa); - } } /* ---------------------------------------------------------------------- @@ -202,14 +198,16 @@ void NeighList::grow(int nlocal, int nall) if (listmiddle) listmiddle->grow(nlocal,nall); // skip if data structs are already big enough - - if (ghost) { + if (ssa) { + if ((nlocal * 3) + nall <= maxatom) return; + } else if (ghost) { if (nall <= maxatom) return; } else { if (nlocal <= maxatom) return; } - maxatom = atom->nmax; + if (ssa) maxatom = (nlocal * 3) + nall; + else maxatom = atom->nmax; memory->destroy(ilist); memory->destroy(numneigh); @@ -223,12 +221,6 @@ void NeighList::grow(int nlocal, int nall) firstdouble = (double **) memory->smalloc(maxatom*sizeof(double *), "neighlist:firstdouble"); } - - if (ssa) { - if (ndxAIR_ssa) memory->sfree(ndxAIR_ssa); - ndxAIR_ssa = (uint16_t (*)[8]) memory->smalloc(sizeof(uint16_t)*8*maxatom, - "neighlist:ndxAIR_ssa"); - } } /* ---------------------------------------------------------------------- @@ -305,7 +297,5 @@ bigint NeighList::memory_usage() } } - if (ndxAIR_ssa) bytes += sizeof(uint16_t) * 8 * maxatom; - return bytes; } diff --git a/src/neigh_list.h b/src/neigh_list.h index ea88e9b28b..bef512512c 100644 --- a/src/neigh_list.h +++ b/src/neigh_list.h @@ -81,7 +81,6 @@ class NeighList : protected Pointers { // USER-DPD package and Shardlow Splitting Algorithm (SSA) support int AIRct_ssa[8]; // count of how many atoms in each AIR - uint16_t (*ndxAIR_ssa)[8]; // for each atom, last neighbor index of each AIR class NPair *np; // ptr to NPair instance I depend on // methods From e0bafa499d55d0f273b23adf87cbaf824d5f9f11 Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Wed, 15 Feb 2017 15:03:40 -0500 Subject: [PATCH 141/439] indentation fixes in npair_kokkos.cpp, plus a comment question --- src/KOKKOS/npair_kokkos.cpp | 38 ++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/KOKKOS/npair_kokkos.cpp b/src/KOKKOS/npair_kokkos.cpp index f49e44c352..4f17835717 100644 --- a/src/KOKKOS/npair_kokkos.cpp +++ b/src/KOKKOS/npair_kokkos.cpp @@ -170,7 +170,7 @@ void NPairKokkos::build(NeighList *list_) data.special_flag[2] = special_flag[2]; data.special_flag[3] = special_flag[3]; - if(list->d_neighbors.dimension_0()d_neighbors.dimension_0()d_neighbors = typename ArrayTypes::t_neighbors_2d("neighbors", nall*1.1, list->maxneighs); list->d_numneigh = typename ArrayTypes::t_int_1d("numneigh", nall*1.1); data.neigh_list.d_neighbors = list->d_neighbors; @@ -179,10 +179,10 @@ void NPairKokkos::build(NeighList *list_) data.h_resize()=1; while(data.h_resize()) { data.h_new_maxneighs() = list->maxneighs; - data.h_resize() = 0; + data.h_resize() = 0; - Kokkos::deep_copy(data.resize, data.h_resize); - Kokkos::deep_copy(data.new_maxneighs, data.h_new_maxneighs); + Kokkos::deep_copy(data.resize, data.h_resize); + Kokkos::deep_copy(data.new_maxneighs, data.h_new_maxneighs); #ifdef KOKKOS_HAVE_CUDA #define BINS_PER_BLOCK 2 const int factor = atoms_per_bin<64?2:1; @@ -191,27 +191,27 @@ void NPairKokkos::build(NeighList *list_) const int factor = 1; #endif -if (GHOST) { - NPairKokkosBuildFunctorGhost f(data,atoms_per_bin * 5 * sizeof(X_FLOAT) * factor); - Kokkos::parallel_for(nall, f); -} else { - if (newton_pair) { - NPairKokkosBuildFunctor f(data,atoms_per_bin * 5 * sizeof(X_FLOAT) * factor); + if (GHOST) { + NPairKokkosBuildFunctorGhost f(data,atoms_per_bin * 5 * sizeof(X_FLOAT) * factor); + Kokkos::parallel_for(nall, f); + } else { + if (newton_pair) { + NPairKokkosBuildFunctor f(data,atoms_per_bin * 5 * sizeof(X_FLOAT) * factor); #ifdef KOKKOS_HAVE_CUDA - Kokkos::parallel_for(config, f); + Kokkos::parallel_for(config, f); #else - Kokkos::parallel_for(nall, f); + Kokkos::parallel_for(nall, f); #endif - } else { - NPairKokkosBuildFunctor f(data,atoms_per_bin * 5 * sizeof(X_FLOAT) * factor); + } else { + NPairKokkosBuildFunctor f(data,atoms_per_bin * 5 * sizeof(X_FLOAT) * factor); #ifdef KOKKOS_HAVE_CUDA - Kokkos::parallel_for(config, f); + Kokkos::parallel_for(config, f); #else - Kokkos::parallel_for(nall, f); + Kokkos::parallel_for(nall, f); #endif - } -} - DeviceType::fence(); + } + } + DeviceType::fence(); deep_copy(data.h_resize, data.resize); if(data.h_resize()) { From 5289ec0b39f2c6600da1c246bcb59c2a668e5b56 Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Fri, 17 Feb 2017 18:39:04 -0500 Subject: [PATCH 142/439] cleanup: remove unused binatomsItem() declaration in npair_kokkos.h --- src/KOKKOS/npair_kokkos.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/KOKKOS/npair_kokkos.h b/src/KOKKOS/npair_kokkos.h index 54726cb971..87fa0b8aee 100644 --- a/src/KOKKOS/npair_kokkos.h +++ b/src/KOKKOS/npair_kokkos.h @@ -277,9 +277,6 @@ class NeighborKokkosExecute void build_ItemCuda(typename Kokkos::TeamPolicy::member_type dev) const; #endif - KOKKOS_INLINE_FUNCTION - void binatomsItem(const int &i) const; - KOKKOS_INLINE_FUNCTION int coord2bin(const X_FLOAT & x,const X_FLOAT & y,const X_FLOAT & z) const { From c2ee3285fc79729d03e458ca2d5118699bd40c7a Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Fri, 17 Feb 2017 21:54:41 -0500 Subject: [PATCH 143/439] USER-DPD: change nstencil_ssa[] to eliminate a corner case Saves a conditional inside an NPairHalfBinNewtonSSA::build() inner loop --- src/USER-DPD/npair_half_bin_newton_ssa.cpp | 3 +-- .../nstencil_half_bin_2d_newton_ssa.cpp | 17 +++++++++-------- .../nstencil_half_bin_3d_newton_ssa.cpp | 17 +++++++++-------- src/USER-DPD/nstencil_ssa.h | 3 ++- 4 files changed, 21 insertions(+), 19 deletions(-) diff --git a/src/USER-DPD/npair_half_bin_newton_ssa.cpp b/src/USER-DPD/npair_half_bin_newton_ssa.cpp index 2c787d6398..8d260dd2be 100644 --- a/src/USER-DPD/npair_half_bin_newton_ssa.cpp +++ b/src/USER-DPD/npair_half_bin_newton_ssa.cpp @@ -207,8 +207,7 @@ void NPairHalfBinNewtonSSA::build(NeighList *list) } // loop over all local atoms in other bins in "subphase" of stencil - k = (subphase > 0) ? nstencil_ssa[subphase - 1] : 0; - for (; k < nstencil_ssa[subphase]; k++) { + for (k = nstencil_ssa[subphase]; k < nstencil_ssa[subphase+1]; k++) { for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) { jtype = type[j]; if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; diff --git a/src/USER-DPD/nstencil_half_bin_2d_newton_ssa.cpp b/src/USER-DPD/nstencil_half_bin_2d_newton_ssa.cpp index 084d5b0602..5df65918d3 100644 --- a/src/USER-DPD/nstencil_half_bin_2d_newton_ssa.cpp +++ b/src/USER-DPD/nstencil_half_bin_2d_newton_ssa.cpp @@ -42,6 +42,7 @@ NStencilHalfBin2dNewtonSSA::NStencilHalfBin2dNewtonSSA(LAMMPS *lmp) : void NStencilHalfBin2dNewtonSSA::create() { int i,j,pos = 0; + nstencil_ssa[0] = 0; // redundant info, but saves a conditional // Subphase 0: upper right front bins (red) for (j = 0; j <= sy; j++) for (i = 0; i <= sx; i++) @@ -52,8 +53,8 @@ void NStencilHalfBin2dNewtonSSA::create() stencilxyz[pos][2] = 0; stencil[pos++] = j*mbinx + i; } - nstencil_ssa[0] = pos; + nstencil_ssa[1] = pos; // Subphase 1: upper left front bins (light blue) for (j = 1; j <= sy; j++) for (i = -sx; i < 0; i++) @@ -63,21 +64,21 @@ void NStencilHalfBin2dNewtonSSA::create() stencilxyz[pos][2] = 0; stencil[pos++] = j*mbinx + i; } - nstencil_ssa[1] = pos; - // Subphase 2: lower right front bins (yellow) nstencil_ssa[2] = pos; + // Subphase 2: lower right front bins (yellow) - // Subphase 3: lower left front bins (blue) nstencil_ssa[3] = pos; + // Subphase 3: lower left front bins (blue) + nstencil_ssa[4] = pos; // record end of half stencil // Now include additional bins for AIR ghosts, and impure-to-pure locals // Subphase 4: upper right back bins (pink) - nstencil_ssa[4] = pos; + // nstencil_ssa[5] = pos; // Subphase 5: upper left back bins (light green) - nstencil_ssa[5] = pos; + // nstencil_ssa[6] = pos; // Subphase 6: lower right back bins (white) for (j = -sy; j < 0; j++) for (i = 0; i <= sx; i++) @@ -87,8 +88,8 @@ void NStencilHalfBin2dNewtonSSA::create() stencilxyz[pos][2] = 0; stencil[pos++] = j*mbinx + i; } - nstencil_ssa[6] = pos; + // nstencil_ssa[7] = pos; // Subphase 7: lower left back bins (purple) for (j = -sy; j <= 0; j++) for (i = -sx; i < 0; i++) @@ -98,7 +99,7 @@ void NStencilHalfBin2dNewtonSSA::create() stencilxyz[pos][2] = 0; stencil[pos++] = j*mbinx + i; } - nstencil_ssa[7] = pos; + // nstencil_ssa[8] = pos; // Also, include the centroid for the AIR ghosts. stencilxyz[pos][0] = 0; diff --git a/src/USER-DPD/nstencil_half_bin_3d_newton_ssa.cpp b/src/USER-DPD/nstencil_half_bin_3d_newton_ssa.cpp index 1741a1e847..3b1c85bdc1 100644 --- a/src/USER-DPD/nstencil_half_bin_3d_newton_ssa.cpp +++ b/src/USER-DPD/nstencil_half_bin_3d_newton_ssa.cpp @@ -42,6 +42,7 @@ NStencilHalfBin3dNewtonSSA::NStencilHalfBin3dNewtonSSA(LAMMPS *lmp) : void NStencilHalfBin3dNewtonSSA::create() { int i,j,k,pos = 0; + nstencil_ssa[0] = 0; // redundant info, but saves a conditional // Subphase 0: upper right front bins (red) for (k = 0; k <= sz; k++) for (j = 0; j <= sy; j++) @@ -53,8 +54,8 @@ void NStencilHalfBin3dNewtonSSA::create() stencilxyz[pos][2] = k; stencil[pos++] = k*mbiny*mbinx + j*mbinx + i; } - nstencil_ssa[0] = pos; + nstencil_ssa[1] = pos; // Subphase 1: upper left front bins (light blue) for (k = 0; k <= sz; k++) for (j = 1; j <= sy; j++) @@ -65,8 +66,8 @@ void NStencilHalfBin3dNewtonSSA::create() stencilxyz[pos][2] = k; stencil[pos++] = k*mbiny*mbinx + j*mbinx + i; } - nstencil_ssa[1] = pos; + nstencil_ssa[2] = pos; // Subphase 2: lower right front bins (yellow) for (k = 1; k <= sz; k++) for (j = -sy; j < 0; j++) @@ -77,8 +78,8 @@ void NStencilHalfBin3dNewtonSSA::create() stencilxyz[pos][2] = k; stencil[pos++] = k*mbiny*mbinx + j*mbinx + i; } - nstencil_ssa[2] = pos; + nstencil_ssa[3] = pos; // Subphase 3: lower left front bins (blue) for (k = 1; k <= sz; k++) for (j = -sy; j <= 0; j++) @@ -89,8 +90,8 @@ void NStencilHalfBin3dNewtonSSA::create() stencilxyz[pos][2] = k; stencil[pos++] = k*mbiny*mbinx + j*mbinx + i; } - nstencil_ssa[3] = pos; + nstencil_ssa[4] = pos; // record end of half stencil // Now include additional bins for AIR ghosts, and impure-to-pure locals // Subphase 4: upper right back bins (pink) for (k = -sz; k < 0; k++) @@ -102,8 +103,8 @@ void NStencilHalfBin3dNewtonSSA::create() stencilxyz[pos][2] = k; stencil[pos++] = k*mbiny*mbinx + j*mbinx + i; } - nstencil_ssa[4] = pos; + // nstencil_ssa[5] = pos; // Subphase 5: upper left back bins (light green) for (k = -sz; k < 0; k++) for (j = 1; j <= sy; j++) @@ -114,8 +115,8 @@ void NStencilHalfBin3dNewtonSSA::create() stencilxyz[pos][2] = k; stencil[pos++] = k*mbiny*mbinx + j*mbinx + i; } - nstencil_ssa[5] = pos; + // nstencil_ssa[6] = pos; // Subphase 6: lower right back bins (white) for (k = -sz; k <= 0; k++) for (j = -sy; j < 0; j++) @@ -126,8 +127,8 @@ void NStencilHalfBin3dNewtonSSA::create() stencilxyz[pos][2] = k; stencil[pos++] = k*mbiny*mbinx + j*mbinx + i; } - nstencil_ssa[6] = pos; + // nstencil_ssa[7] = pos; // Subphase 7: lower left back bins (purple) for (k = -sz; k <= 0; k++) for (j = -sy; j <= 0; j++) @@ -138,7 +139,7 @@ void NStencilHalfBin3dNewtonSSA::create() stencilxyz[pos][2] = k; stencil[pos++] = k*mbiny*mbinx + j*mbinx + i; } - nstencil_ssa[7] = pos; + //nstencil_ssa[8] = pos; // Also, include the centroid for the AIR ghosts. stencilxyz[pos][0] = 0; diff --git a/src/USER-DPD/nstencil_ssa.h b/src/USER-DPD/nstencil_ssa.h index a5e3723271..f6f91fefde 100644 --- a/src/USER-DPD/nstencil_ssa.h +++ b/src/USER-DPD/nstencil_ssa.h @@ -24,7 +24,8 @@ class NStencilSSA : public NStencil { ~NStencilSSA() {} virtual void create() = 0; - int nstencil_ssa[8]; // last stencil index for each subphase + // first stencil index for each subphase, with last index at end + int nstencil_ssa[5]; }; } From d1a0a3e1c369254f173845ca6c4200f956eed0f5 Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Fri, 17 Feb 2017 22:00:56 -0500 Subject: [PATCH 144/439] USER-DPD: first attempt at nbin_ssa_kokkos... It compiles! --- src/KOKKOS/nbin_ssa_kokkos.cpp | 233 +++++++++++++++++++++++++++++++++ src/KOKKOS/nbin_ssa_kokkos.h | 193 +++++++++++++++++++++++++++ 2 files changed, 426 insertions(+) create mode 100644 src/KOKKOS/nbin_ssa_kokkos.cpp create mode 100644 src/KOKKOS/nbin_ssa_kokkos.h diff --git a/src/KOKKOS/nbin_ssa_kokkos.cpp b/src/KOKKOS/nbin_ssa_kokkos.cpp new file mode 100644 index 0000000000..6ed8e9f3e4 --- /dev/null +++ b/src/KOKKOS/nbin_ssa_kokkos.cpp @@ -0,0 +1,233 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing authors: + James Larentzos (ARL) and Timothy I. Mattox (Engility Corporation) +------------------------------------------------------------------------- */ + +#include "nbin_ssa_kokkos.h" +#include "neighbor.h" +#include "atom_kokkos.h" +#include "group.h" +#include "domain.h" +#include "comm.h" +#include "update.h" +#include "error.h" +#include "atom_masks.h" + +// #include "memory.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +template +NBinSSAKokkos::NBinSSAKokkos(LAMMPS *lmp) : NBinStandard(lmp) +{ + atoms_per_bin = ghosts_per_gbin = 16; + + d_resize = typename AT::t_int_scalar("NBinSSAKokkos::d_resize"); +#ifndef KOKKOS_USE_CUDA_UVM + h_resize = Kokkos::create_mirror_view(d_resize); +#else + h_resize = d_resize; +#endif + h_resize() = 1; + + k_gbincount = DAT::tdual_int_1d("NBinSSAKokkos::gbincount",8); + gbincount = k_gbincount.view(); +} + +/* ---------------------------------------------------------------------- */ + +template +void NBinSSAKokkos::bin_atoms_setup(int nall) +{ + if (mbins > (int) k_bins.d_view.dimension_0()) { + k_bins = DAT::tdual_int_2d("NBinSSAKokkos::bins",mbins,atoms_per_bin); + bins = k_bins.view(); + + k_bincount = DAT::tdual_int_1d("NBinSSAKokkos::bincount",mbins); + bincount = k_bincount.view(); + } + + ghosts_per_gbin = atom->nghost / 7; // estimate needed size + + if (ghosts_per_gbin > (int) k_gbins.d_view.dimension_1()) { + k_gbins = DAT::tdual_int_2d("NBinSSAKokkos::gbins",8,ghosts_per_gbin); + gbins = k_gbins.view(); + } + + // Clear the local bin extent bounding box. + h_lbinxlo() = mbinx - 1; // Safe to = stencil->sx + 1 + h_lbinylo() = mbiny - 1; // Safe to = stencil->sy + 1 + h_lbinzlo() = mbinz - 1; // Safe to = stencil->sz + 1 + h_lbinxhi() = 0; // Safe to = mbinx - stencil->sx - 1 + h_lbinyhi() = 0; // Safe to = mbiny - stencil->sy - 1 + h_lbinzhi() = 0; // Safe to = mbinz - stencil->sz - 1 + deep_copy(d_lbinxlo, h_lbinxlo); + deep_copy(d_lbinylo, h_lbinylo); + deep_copy(d_lbinzlo, h_lbinzlo); + deep_copy(d_lbinxhi, h_lbinxhi); + deep_copy(d_lbinyhi, h_lbinyhi); + deep_copy(d_lbinzhi, h_lbinzhi); +} + +/* ---------------------------------------------------------------------- + bin owned and ghost atoms for the Shardlow Splitting Algorithm (SSA) + local atoms are in distinct bins (binhead[]) from the ghosts + ghost atoms are "binned" in gairhead_ssa[] instead + ghosts which are not in an Active Interaction Region (AIR) are skipped +------------------------------------------------------------------------- */ + +template +void NBinSSAKokkos::bin_atoms() +{ + last_bin = update->ntimestep; + + int i; + + // bin the ghost atoms + h_resize() = 1; + while(h_resize() > 0) { + h_resize() = 0; + deep_copy(d_resize, h_resize); + + for (int i = 0; i < 8; i++) { + k_gbincount.h_view(i) = 0; + } + k_gbincount.modify(); + k_gbincount.sync(); + DeviceType::fence(); // FIXME? + + atomKK->sync(ExecutionSpaceFromDevice::space,X_MASK); + x = atomKK->k_x.view(); + + // I don't think these two lines need to be repeated here... - TIM 20170216 + sublo_[0] = domain->sublo[0]; + sublo_[1] = domain->sublo[1]; + sublo_[2] = domain->sublo[2]; + subhi_[0] = domain->subhi[0]; + subhi_[1] = domain->subhi[1]; + subhi_[2] = domain->subhi[2]; + + NPairSSAKokkosBinGhostsFunctor f(*this); + + Kokkos::parallel_for(atom->nghost, f); + DeviceType::fence(); + + deep_copy(h_resize, d_resize); + if(h_resize()) { + k_gbincount.modify(); + k_gbincount.sync(); + for (i = 1; i < 8; i++) { + if (k_gbincount.h_view(i) > ghosts_per_gbin) { + ghosts_per_gbin = k_gbincount.h_view(i); + } + } + k_gbins = DAT::tdual_int_2d("gbins", 8, ghosts_per_gbin); + gbins = k_gbins.view(); + } + } + c_gbins = gbins; // gbins won't change until the next bin_atoms + + // bin the local atoms + h_resize() = 1; + while(h_resize() > 0) { + h_resize() = 0; + deep_copy(d_resize, h_resize); + + MemsetZeroFunctor f_zero; + f_zero.ptr = (void*) k_bincount.view().ptr_on_device(); + Kokkos::parallel_for(mbins, f_zero); + DeviceType::fence(); + + atomKK->sync(ExecutionSpaceFromDevice::space,X_MASK); + x = atomKK->k_x.view(); + + // I don't think these two lines need to be repeated here... - TIM 20170216 + bboxlo_[0] = bboxlo[0]; bboxlo_[1] = bboxlo[1]; bboxlo_[2] = bboxlo[2]; + bboxhi_[0] = bboxhi[0]; bboxhi_[1] = bboxhi[1]; bboxhi_[2] = bboxhi[2]; + + NPairSSAKokkosBinAtomsFunctor f(*this); + + Kokkos::parallel_for(atom->nlocal, f); + DeviceType::fence(); + + deep_copy(h_resize, d_resize); + if(h_resize()) { + + atoms_per_bin += 16; + k_bins = DAT::tdual_int_2d("bins", mbins, atoms_per_bin); + bins = k_bins.view(); + } + } + deep_copy(h_lbinxlo, d_lbinxlo); + deep_copy(h_lbinylo, d_lbinylo); + deep_copy(h_lbinzlo, d_lbinzlo); + deep_copy(h_lbinxhi, d_lbinxhi); + deep_copy(h_lbinyhi, d_lbinyhi); + deep_copy(h_lbinzhi, d_lbinzhi); + c_bins = bins; // bins won't change until the next bin_atoms +} + +/* ---------------------------------------------------------------------- */ + +template +KOKKOS_INLINE_FUNCTION +void NBinSSAKokkos::binGhostsItem(const int &i_) const +{ + const int i = i_ + atom->nlocal; + const int iAIR = coord2ssaAIR(x(i, 0), x(i, 1), x(i, 2)); + if (iAIR > 0) { // include only ghost atoms in an AIR + const int ac = Kokkos::atomic_fetch_add(&gbincount[iAIR], (int)1); + if(ac < (int) gbins.dimension_1()) { + gbins(iAIR, ac) = i; + } else { + d_resize() = 1; + } + } +} + +/* ---------------------------------------------------------------------- */ + +template +KOKKOS_INLINE_FUNCTION +void NBinSSAKokkos::binAtomsItem(const int &i) const +{ + int loc[3]; + const int ibin = coord2bin(x(i, 0), x(i, 1), x(i, 2), &(loc[0])); + + // Find the bounding box of the local atoms in the bins + if (loc[0] < d_lbinxlo()) Kokkos::atomic_fetch_min(&d_lbinxlo(),loc[0]); + if (loc[0] >= d_lbinxhi()) Kokkos::atomic_fetch_max(&d_lbinxhi(),loc[0] + 1); + if (loc[1] < d_lbinylo()) Kokkos::atomic_fetch_min(&d_lbinylo(),loc[1]); + if (loc[1] >= d_lbinyhi()) Kokkos::atomic_fetch_max(&d_lbinyhi(),loc[1] + 1); + if (loc[2] < d_lbinzlo()) Kokkos::atomic_fetch_min(&d_lbinzlo(),loc[2]); + if (loc[2] >= d_lbinzhi()) Kokkos::atomic_fetch_max(&d_lbinzhi(),loc[2] + 1); + + const int ac = Kokkos::atomic_fetch_add(&(bincount[ibin]), (int)1); + if(ac < (int) bins.dimension_1()) { + bins(ibin, ac) = i; + } else { + d_resize() = 1; + } +} + +namespace LAMMPS_NS { +template class NBinSSAKokkos; +#ifdef KOKKOS_HAVE_CUDA +template class NBinSSAKokkos; +#endif +} diff --git a/src/KOKKOS/nbin_ssa_kokkos.h b/src/KOKKOS/nbin_ssa_kokkos.h new file mode 100644 index 0000000000..a16cb2d0b7 --- /dev/null +++ b/src/KOKKOS/nbin_ssa_kokkos.h @@ -0,0 +1,193 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NBIN_CLASS + +NBinStyle(ssa/kk/host, + NBinSSAKokkos, + NB_SSA | NB_KOKKOS_HOST) + +NBinStyle(ssa/kk/device, + NBinSSAKokkos, + NB_SSA | NB_KOKKOS_DEVICE) + +#else + +#ifndef LMP_NBIN_SSA_KOKKOS_H +#define LMP_NBIN_SSA_KOKKOS_H + +#include "nbin_standard.h" +#include "kokkos_type.h" + +namespace LAMMPS_NS { + +template +class NBinSSAKokkos : public NBinStandard { + public: + typedef ArrayTypes AT; + + NBinSSAKokkos(class LAMMPS *); + ~NBinSSAKokkos() {} + void bin_atoms_setup(int); + void bin_atoms(); + + int atoms_per_bin; + DAT::tdual_int_1d k_bincount; + DAT::tdual_int_2d k_bins; + typename AT::t_int_1d bincount; + typename AT::t_int_2d bins; + typename AT::t_int_2d_const c_bins; + + int ghosts_per_gbin; + DAT::tdual_int_1d k_gbincount; + DAT::tdual_int_2d k_gbins; + typename AT::t_int_1d gbincount; + typename AT::t_int_2d gbins; + typename AT::t_int_2d_const c_gbins; + + typename AT::t_int_scalar d_resize; + typename ArrayTypes::t_int_scalar h_resize; + typename AT::t_x_array_randomread x; + + // Bounds of the local atoms in the bins array + typename AT::t_int_scalar d_lbinxlo; // lowest local bin x-dim coordinate + typename AT::t_int_scalar d_lbinylo; // lowest local bin y-dim coordinate + typename AT::t_int_scalar d_lbinzlo; // lowest local bin z-dim coordinate + typename AT::t_int_scalar d_lbinxhi; // highest local bin x-dim coordinate + typename AT::t_int_scalar d_lbinyhi; // highest local bin y-dim coordinate + typename AT::t_int_scalar d_lbinzhi; // highest local bin z-dim coordinate + typename ArrayTypes::t_int_scalar h_lbinxlo; + typename ArrayTypes::t_int_scalar h_lbinylo; + typename ArrayTypes::t_int_scalar h_lbinzlo; + typename ArrayTypes::t_int_scalar h_lbinxhi; + typename ArrayTypes::t_int_scalar h_lbinyhi; + typename ArrayTypes::t_int_scalar h_lbinzhi; + + + KOKKOS_INLINE_FUNCTION + void binAtomsItem(const int &i) const; + + KOKKOS_INLINE_FUNCTION + void binGhostsItem(const int &i) const; + +/* ---------------------------------------------------------------------- + convert atom coords into the ssa active interaction region number +------------------------------------------------------------------------- */ + KOKKOS_INLINE_FUNCTION + int coord2ssaAIR(const X_FLOAT & x,const X_FLOAT & y,const X_FLOAT & z) const + { + int ix, iy, iz; + ix = iy = iz = 0; + if (z < sublo_[2]) iz = -1; + if (z >= subhi_[2]) iz = 1; + if (y < sublo_[1]) iy = -1; + if (y >= subhi_[1]) iy = 1; + if (x < sublo_[0]) ix = -1; + if (x >= subhi_[0]) ix = 1; + if(iz < 0){ + return -1; + } else if(iz == 0){ + if( iy<0 ) return -1; // bottom left/middle/right + if( (iy==0) && (ix<0) ) return -1; // left atoms + if( (iy==0) && (ix==0) ) return 0; // Locally owned atoms + if( (iy==0) && (ix>0) ) return 2; // Right atoms + if( (iy>0) && (ix==0) ) return 1; // Top-middle atoms + if( (iy>0) && (ix!=0) ) return 3; // Top-right and top-left atoms + } else { // iz > 0 + if((ix==0) && (iy==0)) return 4; // Back atoms + if((ix==0) && (iy!=0)) return 5; // Top-back and bottom-back atoms + if((ix!=0) && (iy==0)) return 6; // Left-back and right-back atoms + if((ix!=0) && (iy!=0)) return 7; // Back corner atoms + } + return -2; + } + + KOKKOS_INLINE_FUNCTION + int coord2bin(const X_FLOAT & x,const X_FLOAT & y,const X_FLOAT & z, int* i) const + { + int ix,iy,iz; + + if (x >= bboxhi_[0]) + ix = static_cast ((x-bboxhi_[0])*bininvx) + nbinx; + else if (x >= bboxlo_[0]) { + ix = static_cast ((x-bboxlo_[0])*bininvx); + ix = MIN(ix,nbinx-1); + } else + ix = static_cast ((x-bboxlo_[0])*bininvx) - 1; + + if (y >= bboxhi_[1]) + iy = static_cast ((y-bboxhi_[1])*bininvy) + nbiny; + else if (y >= bboxlo_[1]) { + iy = static_cast ((y-bboxlo_[1])*bininvy); + iy = MIN(iy,nbiny-1); + } else + iy = static_cast ((y-bboxlo_[1])*bininvy) - 1; + + if (z >= bboxhi_[2]) + iz = static_cast ((z-bboxhi_[2])*bininvz) + nbinz; + else if (z >= bboxlo_[2]) { + iz = static_cast ((z-bboxlo_[2])*bininvz); + iz = MIN(iz,nbinz-1); + } else + iz = static_cast ((z-bboxlo_[2])*bininvz) - 1; + + i[0] = ix - mbinxlo; + i[1] = iy - mbinylo; + i[2] = iz - mbinzlo; + + return (iz-mbinzlo)*mbiny*mbinx + (iy-mbinylo)*mbinx + (ix-mbinxlo); + } + + private: + double bboxlo_[3],bboxhi_[3]; + double sublo_[3], subhi_[3]; +}; + +template +struct NPairSSAKokkosBinGhostsFunctor { + typedef DeviceType device_type; + + const NBinSSAKokkos c; + + NPairSSAKokkosBinGhostsFunctor(const NBinSSAKokkos &_c): + c(_c) {}; + ~NPairSSAKokkosBinGhostsFunctor() {} + KOKKOS_INLINE_FUNCTION + void operator() (const int & i) const { + c.binGhostsItem(i); + } +}; + +template +struct NPairSSAKokkosBinAtomsFunctor { + typedef DeviceType device_type; + + const NBinSSAKokkos c; + + NPairSSAKokkosBinAtomsFunctor(const NBinSSAKokkos &_c): + c(_c) {}; + ~NPairSSAKokkosBinAtomsFunctor() {} + KOKKOS_INLINE_FUNCTION + void operator() (const int & i) const { + c.binAtomsItem(i); + } +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ From 7feb6c2853b6f2b8f67f84bda07cd9d0ab287e8b Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Fri, 17 Feb 2017 22:41:32 -0500 Subject: [PATCH 145/439] USER-DPD: fix a bug in AtomVecDPDKokkos::unpack_restart() --- src/KOKKOS/atom_vec_dpd_kokkos.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/KOKKOS/atom_vec_dpd_kokkos.cpp b/src/KOKKOS/atom_vec_dpd_kokkos.cpp index 820f11c215..f46f284f14 100644 --- a/src/KOKKOS/atom_vec_dpd_kokkos.cpp +++ b/src/KOKKOS/atom_vec_dpd_kokkos.cpp @@ -1668,7 +1668,7 @@ int AtomVecDPDKokkos::unpack_restart(double *buf) double **extra = atom->extra; if (atom->nextra_store) { - int size = static_cast (ubuf(buf[m++]).i) - m; + int size = static_cast (buf[0]) - m; for (int i = 0; i < size; i++) extra[nlocal][i] = buf[m++]; } From 37810bdc530209dc776f79bdbadf41c232919d04 Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Fri, 17 Feb 2017 23:06:53 -0500 Subject: [PATCH 146/439] USER-DPD: move centroid bin of stencil_ssa to the first slot. Eliminates a special case version of a loop just for Subphase 0. NOTE: pair evaluation order changes, causing numerical differences! This changed the order that close neighbors of ghosts are processed. --- src/USER-DPD/npair_half_bin_newton_ssa.cpp | 32 +++---------------- .../nstencil_half_bin_2d_newton_ssa.cpp | 14 ++++---- .../nstencil_half_bin_3d_newton_ssa.cpp | 14 ++++---- 3 files changed, 21 insertions(+), 39 deletions(-) diff --git a/src/USER-DPD/npair_half_bin_newton_ssa.cpp b/src/USER-DPD/npair_half_bin_newton_ssa.cpp index 8d260dd2be..14095bf349 100644 --- a/src/USER-DPD/npair_half_bin_newton_ssa.cpp +++ b/src/USER-DPD/npair_half_bin_newton_ssa.cpp @@ -180,35 +180,13 @@ void NPairHalfBinNewtonSSA::build(NeighList *list) iatom = molatom[i]; tagprev = tag[i] - iatom - 1; } - // loop over rest of local atoms in i's bin if this is subphase 0 - // just store them, since j is beyond i in linked list - if (subphase == 0) for (j = bins[i]; j >= 0; j = bins[j]) { - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; - if (which == 0) neighptr[n++] = j; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; - } - } - // loop over all local atoms in other bins in "subphase" of stencil + // loop over all local atoms in the current stencil "subphase" for (k = nstencil_ssa[subphase]; k < nstencil_ssa[subphase+1]; k++) { - for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) { + const int jbin = ibin+stencil[k]; + if (jbin != ibin) j = binhead[jbin]; + else j = bins[i]; // same bin as i, so start just past i in the bin + for (; j >= 0; j = bins[j]) { jtype = type[j]; if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; delx = xtmp - x[j][0]; diff --git a/src/USER-DPD/nstencil_half_bin_2d_newton_ssa.cpp b/src/USER-DPD/nstencil_half_bin_2d_newton_ssa.cpp index 5df65918d3..451381c104 100644 --- a/src/USER-DPD/nstencil_half_bin_2d_newton_ssa.cpp +++ b/src/USER-DPD/nstencil_half_bin_2d_newton_ssa.cpp @@ -43,6 +43,14 @@ void NStencilHalfBin2dNewtonSSA::create() { int i,j,pos = 0; nstencil_ssa[0] = 0; // redundant info, but saves a conditional + + // Include the centroid at the start. + // It will be handled as part of Subphase 0. + stencilxyz[pos][0] = 0; + stencilxyz[pos][1] = 0; + stencilxyz[pos][2] = 0; + stencil[pos++] = 0; + // Subphase 0: upper right front bins (red) for (j = 0; j <= sy; j++) for (i = 0; i <= sx; i++) @@ -101,11 +109,5 @@ void NStencilHalfBin2dNewtonSSA::create() } // nstencil_ssa[8] = pos; - // Also, include the centroid for the AIR ghosts. - stencilxyz[pos][0] = 0; - stencilxyz[pos][1] = 0; - stencilxyz[pos][2] = 0; - stencil[pos++] = 0; - nstencil = pos; // record where full stencil ends } diff --git a/src/USER-DPD/nstencil_half_bin_3d_newton_ssa.cpp b/src/USER-DPD/nstencil_half_bin_3d_newton_ssa.cpp index 3b1c85bdc1..cdd3b8856f 100644 --- a/src/USER-DPD/nstencil_half_bin_3d_newton_ssa.cpp +++ b/src/USER-DPD/nstencil_half_bin_3d_newton_ssa.cpp @@ -43,6 +43,14 @@ void NStencilHalfBin3dNewtonSSA::create() { int i,j,k,pos = 0; nstencil_ssa[0] = 0; // redundant info, but saves a conditional + + // Include the centroid at the start. + // It will be handled as part of Subphase 0. + stencilxyz[pos][0] = 0; + stencilxyz[pos][1] = 0; + stencilxyz[pos][2] = 0; + stencil[pos++] = 0; + // Subphase 0: upper right front bins (red) for (k = 0; k <= sz; k++) for (j = 0; j <= sy; j++) @@ -141,11 +149,5 @@ void NStencilHalfBin3dNewtonSSA::create() } //nstencil_ssa[8] = pos; - // Also, include the centroid for the AIR ghosts. - stencilxyz[pos][0] = 0; - stencilxyz[pos][1] = 0; - stencilxyz[pos][2] = 0; - stencil[pos++] = 0; - nstencil = pos; // record where full stencil ends } From 19ffe5931529b9c49cf9bc656c2e9fa01248aa3c Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Sat, 18 Feb 2017 00:32:14 -0500 Subject: [PATCH 147/439] USER-DPD: fix typo in NPairHalfBinNewtonSSA::build(): sz1 instead of sx1 Luckily, no real change, since sz1 and sx1 are normally identical. --- src/USER-DPD/npair_half_bin_newton_ssa.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/USER-DPD/npair_half_bin_newton_ssa.cpp b/src/USER-DPD/npair_half_bin_newton_ssa.cpp index 14095bf349..ab439d3731 100644 --- a/src/USER-DPD/npair_half_bin_newton_ssa.cpp +++ b/src/USER-DPD/npair_half_bin_newton_ssa.cpp @@ -153,7 +153,7 @@ void NPairHalfBinNewtonSSA::build(NeighList *list) int workItem = 0; for (zbin = lbinzlo + zoff; zbin < lbinzhi; zbin += sz1) { for (ybin = lbinylo + yoff - ns_ssa->sy; ybin < lbinyhi; ybin += sy1) { - for (xbin = lbinxlo + xoff - ns_ssa->sx; xbin < lbinxhi; xbin += sz1) { + for (xbin = lbinxlo + xoff - ns_ssa->sx; xbin < lbinxhi; xbin += sx1) { if (workItem >= phaseLenEstimate) error->one(FLERR,"phaseLenEstimate was too small"); ssa_itemLoc[workPhase][workItem] = inum; // record where workItem starts in ilist From 5c6e7b12c647a21d45e8d6460e53a5ff64f277d6 Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Sat, 18 Feb 2017 01:09:02 -0500 Subject: [PATCH 148/439] BUGFIX: fix a copy-o in build_Item_Ghost(): xbin2, etc. should be an int xbin2, ybin2, and zbin2 are temporary integer bin coordinates, not floats! --- src/KOKKOS/npair_kokkos.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/KOKKOS/npair_kokkos.cpp b/src/KOKKOS/npair_kokkos.cpp index 4f17835717..c750918695 100644 --- a/src/KOKKOS/npair_kokkos.cpp +++ b/src/KOKKOS/npair_kokkos.cpp @@ -724,9 +724,9 @@ void NeighborKokkosExecute:: const int ybin = binxyz[1]; const int zbin = binxyz[2]; for (int k = 0; k < nstencil; k++) { - const X_FLOAT xbin2 = xbin + stencilxyz(k,0); - const X_FLOAT ybin2 = ybin + stencilxyz(k,1); - const X_FLOAT zbin2 = zbin + stencilxyz(k,2); + const int xbin2 = xbin + stencilxyz(k,0); + const int ybin2 = ybin + stencilxyz(k,1); + const int zbin2 = zbin + stencilxyz(k,2); if (xbin2 < 0 || xbin2 >= mbinx || ybin2 < 0 || ybin2 >= mbiny || zbin2 < 0 || zbin2 >= mbinz) continue; From 01d0a5c4a210617fb47b9aa85a79eeccd715fa5f Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Sat, 18 Feb 2017 01:38:55 -0500 Subject: [PATCH 149/439] BUGFIX: use Kokkos::atomic_fetch_max() to avoid a race on new_maxneighs --- src/KOKKOS/npair_kokkos.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/KOKKOS/npair_kokkos.cpp b/src/KOKKOS/npair_kokkos.cpp index c750918695..5bfa147def 100644 --- a/src/KOKKOS/npair_kokkos.cpp +++ b/src/KOKKOS/npair_kokkos.cpp @@ -422,10 +422,10 @@ void NeighborKokkosExecute:: neigh_list.d_numneigh(i) = n; - if(n >= neigh_list.maxneighs) { + if(n > neigh_list.maxneighs) { resize() = 1; - if(n >= new_maxneighs()) new_maxneighs() = n; + if(n > new_maxneighs()) Kokkos::atomic_fetch_max(&new_maxneighs(),n); } neigh_list.d_ilist(i) = i; @@ -632,10 +632,10 @@ void NeighborKokkosExecute::build_ItemCuda(typename Kokkos::TeamPoli neigh_list.d_ilist(i) = i; } - if(n >= neigh_list.maxneighs) { + if(n > neigh_list.maxneighs) { resize() = 1; - if(n >= new_maxneighs()) new_maxneighs() = n; + if(n > new_maxneighs()) Kokkos::atomic_fetch_max(&new_maxneighs(),n); } } } @@ -755,10 +755,10 @@ void NeighborKokkosExecute:: neigh_list.d_numneigh(i) = n; - if(n >= neigh_list.maxneighs) { + if(n > neigh_list.maxneighs) { resize() = 1; - if(n >= new_maxneighs()) new_maxneighs() = n; + if(n > new_maxneighs()) Kokkos::atomic_fetch_max(&new_maxneighs(),n); } neigh_list.d_ilist(i) = i; } From 8065d967612a04ce0f6e3f8286d7c66fe1e48f0d Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Sat, 18 Feb 2017 03:14:32 -0500 Subject: [PATCH 150/439] USER-DPD: first attempt at npair_ssa_kokkos... It compiles! --- src/KOKKOS/npair_ssa_kokkos.cpp | 539 ++++++++++++++++++++++++++++++++ src/KOKKOS/npair_ssa_kokkos.h | 334 ++++++++++++++++++++ 2 files changed, 873 insertions(+) create mode 100644 src/KOKKOS/npair_ssa_kokkos.cpp create mode 100644 src/KOKKOS/npair_ssa_kokkos.h diff --git a/src/KOKKOS/npair_ssa_kokkos.cpp b/src/KOKKOS/npair_ssa_kokkos.cpp new file mode 100644 index 0000000000..752fc0c938 --- /dev/null +++ b/src/KOKKOS/npair_ssa_kokkos.cpp @@ -0,0 +1,539 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing authors: + James Larentzos and Timothy I. Mattox (Engility Corporation) +------------------------------------------------------------------------- */ + +#include "npair_ssa_kokkos.h" +#include "neigh_list.h" +#include "atom_kokkos.h" +#include "atom_masks.h" +#include "domain_kokkos.h" +#include "neighbor_kokkos.h" +#include "nbin_ssa_kokkos.h" +#include "nstencil_ssa.h" +#include "error.h" + +namespace LAMMPS_NS { + +/* ---------------------------------------------------------------------- */ + +template +NPairSSAKokkos::NPairSSAKokkos(LAMMPS *lmp) : NPair(lmp), ssa_phaseCt(27) +{ +} + +/* ---------------------------------------------------------------------- + copy needed info from Neighbor class to this build class + ------------------------------------------------------------------------- */ + +template +void NPairSSAKokkos::copy_neighbor_info() +{ + NPair::copy_neighbor_info(); + + NeighborKokkos* neighborKK = (NeighborKokkos*) neighbor; + + // general params + + k_cutneighsq = neighborKK->k_cutneighsq; + + // exclusion info + + k_ex1_type = neighborKK->k_ex1_type; + k_ex2_type = neighborKK->k_ex2_type; + k_ex_type = neighborKK->k_ex_type; + k_ex1_group = neighborKK->k_ex1_group; + k_ex2_group = neighborKK->k_ex2_group; + k_ex1_bit = neighborKK->k_ex1_bit; + k_ex2_bit = neighborKK->k_ex2_bit; + k_ex_mol_group = neighborKK->k_ex_mol_group; + k_ex_mol_bit = neighborKK->k_ex_mol_bit; +} + +/* ---------------------------------------------------------------------- + copy per-atom and per-bin vectors from NBinSSAKokkos class to this build class + ------------------------------------------------------------------------- */ + +template +void NPairSSAKokkos::copy_bin_info() +{ + NPair::copy_bin_info(); + + NBinSSAKokkos* nbKK = dynamic_cast*>(nb); + if (!nbKK) error->one(FLERR, "NBin wasn't a NBinSSAKokkos object"); + + atoms_per_bin = nbKK->atoms_per_bin; + k_bincount = nbKK->k_bincount; + k_bins = nbKK->k_bins; + + ghosts_per_gbin = nbKK->ghosts_per_gbin; + k_gbincount = nbKK->k_gbincount; + k_gbins = nbKK->k_gbins; + + lbinxlo = nbKK->d_lbinxlo(); + lbinxhi = nbKK->d_lbinxhi(); + lbinylo = nbKK->d_lbinylo(); + lbinyhi = nbKK->d_lbinyhi(); + lbinzlo = nbKK->d_lbinzlo(); + lbinzhi = nbKK->d_lbinzhi(); +} + +/* ---------------------------------------------------------------------- + copy needed info from NStencil class to this build class + ------------------------------------------------------------------------- */ + +template +void NPairSSAKokkos::copy_stencil_info() +{ + NPair::copy_stencil_info(); + + nstencil = ns->nstencil; + + int maxstencil = ns->get_maxstencil(); + + k_stencil = DAT::tdual_int_1d("NPairSSAKokkos:stencil",maxstencil); + for (int k = 0; k < maxstencil; k++) { + k_stencil.h_view(k) = ns->stencil[k]; + } + k_stencil.modify(); + k_stencil.sync(); + k_stencilxyz = DAT::tdual_int_1d_3("NPairSSAKokkos:stencilxyz",maxstencil); + for (int k = 0; k < maxstencil; k++) { + k_stencilxyz.h_view(k,0) = ns->stencilxyz[k][0]; + k_stencilxyz.h_view(k,1) = ns->stencilxyz[k][1]; + k_stencilxyz.h_view(k,2) = ns->stencilxyz[k][2]; + } + k_stencilxyz.modify(); + k_stencilxyz.sync(); + + NStencilSSA *ns_ssa = dynamic_cast(ns); + if (!ns_ssa) error->one(FLERR, "NStencil wasn't a NStencilSSA object"); + + k_nstencil_ssa = DAT::tdual_int_1d("NPairSSAKokkos:nstencil_ssa",8); + for (int k = 0; k < 8; ++k) { + k_nstencil_ssa.h_view(k) = ns_ssa->nstencil_ssa[k]; + } + k_nstencil_ssa.modify(); + k_nstencil_ssa.sync(); + sx1 = ns_ssa->sx + 1; + sy1 = ns_ssa->sy + 1; + sz1 = ns_ssa->sz + 1; +} + +/* ---------------------------------------------------------------------- */ + +template +KOKKOS_INLINE_FUNCTION +int NPairSSAKokkosExecute::find_special(const int &i, const int &j) const +{ + const int n1 = nspecial(i,0); + const int n2 = nspecial(i,1); + const int n3 = nspecial(i,2); + + for (int k = 0; k < n3; k++) { + if (special(i,k) == tag(j)) { + if (k < n1) { + if (special_flag[1] == 0) return -1; + else if (special_flag[1] == 1) return 0; + else return 1; + } else if (k < n2) { + if (special_flag[2] == 0) return -1; + else if (special_flag[2] == 1) return 0; + else return 2; + } else { + if (special_flag[3] == 0) return -1; + else if (special_flag[3] == 1) return 0; + else return 3; + } + } + } + return 0; +}; + +/* ---------------------------------------------------------------------- */ + +template +KOKKOS_INLINE_FUNCTION +int NPairSSAKokkosExecute::exclusion(const int &i,const int &j, + const int &itype,const int &jtype) const +{ + int m; + + if (nex_type && ex_type(itype,jtype)) return 1; + + if (nex_group) { + for (m = 0; m < nex_group; m++) { + if (mask(i) & ex1_bit(m) && mask(j) & ex2_bit(m)) return 1; + if (mask(i) & ex2_bit(m) && mask(j) & ex1_bit(m)) return 1; + } + } + + if (nex_mol) { + for (m = 0; m < nex_mol; m++) + if (mask(i) & ex_mol_bit(m) && mask(j) & ex_mol_bit(m) && + molecule(i) == molecule(j)) return 1; + } + + return 0; +} + +/* ---------------------------------------------------------------------- */ + + +/* ---------------------------------------------------------------------- + binned neighbor list construction with full Newton's 3rd law + for use by Shardlow Spliting Algorithm + each owned atom i checks its own bin and other bins in Newton stencil + every pair stored exactly once by some processor +------------------------------------------------------------------------- */ + +template +void NPairSSAKokkos::build(NeighList *list_) +{ + NeighListKokkos* list = (NeighListKokkos*) list_; + const int nlocal = includegroup?atom->nfirst:atom->nlocal; + const int nl_size = (nlocal + atom->nghost) * 4; + list->grow(nl_size); // Make special larger SSA neighbor list + + ssa_phaseCt = sz1*sy1*sx1; + + int xbin = (lbinxhi - lbinxlo + sx1 - 1) / sx1 + 1; + int ybin = (lbinyhi - lbinylo + sy1 - 1) / sy1 + 1; + int zbin = (lbinzhi - lbinzlo + sz1 - 1) / sz1 + 1; + int phaseLenEstimate = xbin*ybin*zbin; + + if (ssa_phaseCt > (int) k_ssa_phaseLen.dimension_0()) { + k_ssa_phaseLen = DAT::tdual_int_1d("NPairSSAKokkos:ssa_phaseLen",ssa_phaseCt); + ssa_phaseLen = k_ssa_phaseLen.view(); + } + if ((ssa_phaseCt > (int) k_ssa_itemLoc.dimension_0()) || + (phaseLenEstimate > (int) k_ssa_itemLoc.dimension_1())) { + k_ssa_itemLoc = DAT::tdual_int_2d("NPairSSAKokkos::ssa_itemLoc",ssa_phaseCt,phaseLenEstimate); + ssa_itemLoc = k_ssa_itemLoc.view(); + k_ssa_itemLen = DAT::tdual_int_2d("NPairSSAKokkos::ssa_itemLen",ssa_phaseCt,phaseLenEstimate); + ssa_itemLen = k_ssa_itemLen.view(); + } + + NPairSSAKokkosExecute + data(*list, + k_cutneighsq.view(), + k_bincount.view(), + k_bins.view(), + k_gbincount.view(), + k_gbins.view(), + lbinxlo, lbinxhi, lbinylo, lbinyhi, lbinzlo, lbinzhi, + nstencil, sx1, sy1, sz1, + k_stencil.view(), + k_stencilxyz.view(), + k_nstencil_ssa.view(), + ssa_phaseCt, + k_ssa_phaseLen.view(), + k_ssa_itemLoc.view(), + k_ssa_itemLen.view(), + nlocal, + atomKK->k_x.view(), + atomKK->k_type.view(), + atomKK->k_mask.view(), + atomKK->k_molecule.view(), + atomKK->k_tag.view(), + atomKK->k_special.view(), + atomKK->k_nspecial.view(), + atomKK->molecular, + nbinx,nbiny,nbinz,mbinx,mbiny,mbinz,mbinxlo,mbinylo,mbinzlo, + bininvx,bininvy,bininvz, + exclude, nex_type, + k_ex1_type.view(), + k_ex2_type.view(), + k_ex_type.view(), + nex_group, + k_ex1_group.view(), + k_ex2_group.view(), + k_ex1_bit.view(), + k_ex2_bit.view(), + nex_mol, + k_ex_mol_group.view(), + k_ex_mol_bit.view(), + bboxhi,bboxlo, + domain->xperiodic,domain->yperiodic,domain->zperiodic, + domain->xprd_half,domain->yprd_half,domain->zprd_half); + + k_cutneighsq.sync(); + k_ex1_type.sync(); + k_ex2_type.sync(); + k_ex_type.sync(); + k_ex1_group.sync(); + k_ex2_group.sync(); + k_ex1_bit.sync(); + k_ex2_bit.sync(); + k_ex_mol_group.sync(); + k_ex_mol_bit.sync(); + k_bincount.sync(); + k_bins.sync(); + k_gbincount.sync(); + k_gbins.sync(); + atomKK->sync(Device,X_MASK|TYPE_MASK|MASK_MASK|MOLECULE_MASK|TAG_MASK|SPECIAL_MASK); + + data.special_flag[0] = special_flag[0]; + data.special_flag[1] = special_flag[1]; + data.special_flag[2] = special_flag[2]; + data.special_flag[3] = special_flag[3]; + + data.h_resize()=1; + while(data.h_resize()) { + data.h_new_maxneighs() = list->maxneighs; + data.h_resize() = 0; + + Kokkos::deep_copy(data.resize, data.h_resize); + Kokkos::deep_copy(data.new_maxneighs, data.h_new_maxneighs); + +#ifdef NOTYET + NPairSSAKokkosBuildFunctor f(data,atoms_per_bin*5*sizeof(X_FLOAT)); + Kokkos::parallel_for(nall, f); +#endif + data.build_locals(); + data.build_ghosts(); + + DeviceType::fence(); + deep_copy(data.h_resize, data.resize); + + if(data.h_resize()) { + deep_copy(data.h_new_maxneighs, data.new_maxneighs); + list->maxneighs = data.h_new_maxneighs() * 1.2; + list->d_neighbors = typename ArrayTypes::t_neighbors_2d("neighbors", list->d_neighbors.dimension_0(), list->maxneighs); + data.neigh_list.d_neighbors = list->d_neighbors; + data.neigh_list.maxneighs = list->maxneighs; + } + } + + k_ssa_phaseLen.modify(); + k_ssa_itemLoc.modify(); + k_ssa_itemLen.modify(); + + list->k_ilist.template modify(); +} + + +template +void NPairSSAKokkosExecute::build_locals() +{ + int n = 0; + int which = 0; + int inum = 0; + + int workPhase = 0; + // loop over bins with local atoms, storing half of the neighbors + for (int zoff = sz1 - 1; zoff >= 0; --zoff) { + for (int yoff = sy1 - 1; yoff >= 0; --yoff) { + for (int xoff = sx1 - 1; xoff >= 0; --xoff) { + int workItem = 0; + for (int zbin = lbinzlo + zoff; zbin < lbinzhi; zbin += sz1) { + for (int ybin = lbinylo + yoff - sy1 + 1; ybin < lbinyhi; ybin += sy1) { + for (int xbin = lbinxlo + xoff - sx1 + 1; xbin < lbinxhi; xbin += sx1) { +// if (workItem >= phaseLenEstimate) error->one(FLERR,"phaseLenEstimate was too small"); + d_ssa_itemLoc(workPhase, workItem) = inum; // record where workItem starts in ilist + + for (int subphase = 0; subphase < 4; subphase++) { + int s_ybin = ybin + ((subphase & 0x2) ? sy1 - 1 : 0); + int s_xbin = xbin + ((subphase & 0x1) ? sx1 - 1 : 0); + if ((s_ybin < lbinylo) || (s_ybin >= lbinyhi)) continue; + if ((s_xbin < lbinxlo) || (s_xbin >= lbinxhi)) continue; + + int ibin = zbin*mbiny*mbinx + s_ybin*mbinx + s_xbin; + for (int il = 0; il < c_bincount(ibin); ++il) { + const int i = c_bins(ibin, il); + n = 0; + + const AtomNeighbors neighbors_i = neigh_list.get_neighbors(inum); + 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 typename ArrayTypes::t_int_1d_const_um stencil + = d_stencil; + + // loop over all local atoms in the current stencil "subphase" + for (int k = d_nstencil_ssa(subphase); k < d_nstencil_ssa(subphase+1); k++) { + const int jbin = ibin+stencil(k); + int jl; + if (jbin != ibin) jl = 0; + else jl = il + 1; // same bin as i, so start just past i in the bin + for (; jl < c_bincount(jbin); ++jl) { + const int j = c_bins(jbin, jl); + const int jtype = type(j); + if(exclude && exclusion(i,j,itype,jtype)) continue; + + 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 X_FLOAT rsq = delx*delx + dely*dely + delz*delz; + if(rsq <= cutneighsq(itype,jtype)) { + if (molecular) { + if (!moltemplate) + which = find_special(i,j); + /* else if (imol >= 0) */ + /* which = find_special(onemols[imol]->special[iatom], */ + /* onemols[imol]->nspecial[iatom], */ + /* tag[j]-tagprev); */ + /* else which = 0; */ + if (which == 0){ + if(n 0) { + if(n 0) { + neigh_list.d_numneigh(inum) = n; + neigh_list.d_ilist(inum++) = i; + if(n > neigh_list.maxneighs) { + resize() = 1; + if(n > new_maxneighs()) Kokkos::atomic_fetch_max(&new_maxneighs(),n); + } + } + } + } + // record where workItem ends in ilist + d_ssa_itemLen(workPhase,workItem) = inum - d_ssa_itemLoc(workPhase,workItem); + if (d_ssa_itemLen(workPhase,workItem) > 0) workItem++; + } + } + } + + // record where workPhase ends + d_ssa_phaseLen(workPhase++) = workItem; + } + } + } + +//FIXME if (ssa_phaseCt != workPhase) error->one(FLERR,"ssa_phaseCt was wrong"); + + neigh_list.inum = inum; //FIXME +} + + +template +void NPairSSAKokkosExecute::build_ghosts() +{ + int n = 0; + int which = 0; + int inum = neigh_list.inum; + int gnum = 0; + neigh_list.AIRct_ssa[0] = inum; //FIXME + + // loop over AIR ghost atoms, storing their local neighbors + // since these are ghosts, must check if stencil bin is out of bounds + for (int airnum = 1; airnum <= 7; airnum++) { + int locAIRct = 0; + for (int il = 0; il < c_gbincount(airnum); ++il) { + const int i = c_gbins(airnum, il); + n = 0; + + const AtomNeighbors neighbors_i = neigh_list.get_neighbors(inum + gnum); + 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 typename ArrayTypes::t_int_1d_const_um stencil + = d_stencil; + + int loc[3]; + const int ibin = coord2bin(x(i, 0), x(i, 1), x(i, 2), &(loc[0])); + + // loop over AIR ghost atoms in all bins in "full" stencil + // Note: the non-AIR ghost atoms have already been filtered out + for (int k = 0; k < nstencil; k++) { + int xbin2 = loc[0] + d_stencilxyz(k,0); + int ybin2 = loc[1] + d_stencilxyz(k,1); + int zbin2 = loc[2] + d_stencilxyz(k,2); + // Skip it if this bin is outside the extent of local bins + if (xbin2 < lbinxlo || xbin2 >= lbinxhi || + ybin2 < lbinylo || ybin2 >= lbinyhi || + zbin2 < lbinzlo || zbin2 >= lbinzhi) continue; + const int jbin = ibin+stencil(k); + for (int jl = 0; jl < c_bincount(jbin); ++jl) { + const int j = c_bins(jbin, jl); + const int jtype = type(j); + if(exclude && exclusion(i,j,itype,jtype)) continue; + + 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 X_FLOAT rsq = delx*delx + dely*dely + delz*delz; + if(rsq <= cutneighsq(itype,jtype)) { + if (molecular) { + if (!moltemplate) + which = find_special(i,j); + /* else if (imol >= 0) */ + /* which = find_special(onemols[imol]->special[iatom], */ + /* onemols[imol]->nspecial[iatom], */ + /* tag[j]-tagprev); */ + /* else which = 0; */ + if (which == 0){ + if(n 0) { + if(n 0) { + neigh_list.d_numneigh(inum + gnum) = n; + neigh_list.d_ilist(inum + (gnum++)) = i; + if(n > neigh_list.maxneighs) { + resize() = 1; + if(n > new_maxneighs()) Kokkos::atomic_fetch_max(&new_maxneighs(),n); + } + ++locAIRct; + } + } + neigh_list.AIRct_ssa[airnum] = locAIRct; //FIXME + } + neigh_list.gnum = gnum; //FIXME +} + +} + +namespace LAMMPS_NS { +template class NPairSSAKokkos; +#ifdef KOKKOS_HAVE_CUDA +template class NPairSSAKokkos; +#endif +} diff --git a/src/KOKKOS/npair_ssa_kokkos.h b/src/KOKKOS/npair_ssa_kokkos.h new file mode 100644 index 0000000000..a656fe32ba --- /dev/null +++ b/src/KOKKOS/npair_ssa_kokkos.h @@ -0,0 +1,334 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +typedef NPairSSAKokkos NPairSSAKokkosHost; +NPairStyle(half/bin/newton/ssa/kk/host, + NPairSSAKokkosHost, + NP_HALF | NP_BIN | NP_NEWTON | NP_ORTHO | NP_SSA | NP_GHOST | NP_KOKKOS_HOST) + +typedef NPairSSAKokkos NPairSSAKokkosDevice; +NPairStyle(half/bin/newton/ssa/kk/device, + NPairSSAKokkosDevice, + NP_HALF | NP_BIN | NP_NEWTON | NP_ORTHO | NP_SSA | NP_GHOST | NP_KOKKOS_DEVICE) + +#else + +#ifndef LMP_NPAIR_SSA_KOKKOS_H +#define LMP_NPAIR_SSA_KOKKOS_H + +#include "npair.h" +#include "neigh_list_kokkos.h" + +namespace LAMMPS_NS { + +template +class NPairSSAKokkos : public NPair { + public: + typedef ArrayTypes AT; + + // SSA Work plan data structures + int ssa_phaseCt; + DAT::tdual_int_1d k_ssa_phaseLen; + DAT::tdual_int_2d k_ssa_itemLoc; + DAT::tdual_int_2d k_ssa_itemLen; + typename AT::t_int_1d ssa_phaseLen; + typename AT::t_int_2d ssa_itemLoc; + typename AT::t_int_2d ssa_itemLen; + + NPairSSAKokkos(class LAMMPS *); + ~NPairSSAKokkos() {} + void copy_neighbor_info(); + void copy_bin_info(); + void copy_stencil_info(); + void build(class NeighList *); + private: + // data from Neighbor class + + DAT::tdual_xfloat_2d k_cutneighsq; + + // exclusion data from Neighbor class + + DAT::tdual_int_1d k_ex1_type,k_ex2_type; + DAT::tdual_int_2d k_ex_type; + DAT::tdual_int_1d k_ex1_group,k_ex2_group; + DAT::tdual_int_1d k_ex1_bit,k_ex2_bit; + DAT::tdual_int_1d k_ex_mol_group; + DAT::tdual_int_1d k_ex_mol_bit; + + // data from NBinSSA class + + int atoms_per_bin; + DAT::tdual_int_1d k_bincount; + DAT::tdual_int_2d k_bins; + int ghosts_per_gbin; + DAT::tdual_int_1d k_gbincount; + DAT::tdual_int_2d k_gbins; + int lbinxlo, lbinxhi, lbinylo, lbinyhi, lbinzlo, lbinzhi; + + // data from NStencilSSA class + + int nstencil; + DAT::tdual_int_1d k_stencil; // # of J neighs for each I + DAT::tdual_int_1d_3 k_stencilxyz; + DAT::tdual_int_1d k_nstencil_ssa; + int sx1, sy1, sz1; +}; + +template +class NPairSSAKokkosExecute +{ + typedef ArrayTypes AT; + + public: + NeighListKokkos neigh_list; + + // data from Neighbor class + + const typename AT::t_xfloat_2d_randomread cutneighsq; + + // exclusion data from Neighbor class + + const int exclude; + + const int nex_type; + const typename AT::t_int_1d_const ex1_type,ex2_type; + const typename AT::t_int_2d_const ex_type; + + const int nex_group; + const typename AT::t_int_1d_const ex1_group,ex2_group; + const typename AT::t_int_1d_const ex1_bit,ex2_bit; + + const int nex_mol; + const typename AT::t_int_1d_const ex_mol_group; + const typename AT::t_int_1d_const ex_mol_bit; + + // data from NBinSSA class + + const typename AT::t_int_1d bincount; + const typename AT::t_int_1d_const c_bincount; + typename AT::t_int_2d bins; + typename AT::t_int_2d_const c_bins; + const typename AT::t_int_1d gbincount; + const typename AT::t_int_1d_const c_gbincount; + typename AT::t_int_2d gbins; + typename AT::t_int_2d_const c_gbins; + const int lbinxlo, lbinxhi, lbinylo, lbinyhi, lbinzlo, lbinzhi; + + + // data from NStencil class + + const int nstencil; + const int sx1, sy1, sz1; + typename AT::t_int_1d d_stencil; // # of J neighs for each I + typename AT::t_int_1d_3 d_stencilxyz; + typename AT::t_int_1d d_nstencil_ssa; + + // data from Atom class + + const typename AT::t_x_array_randomread x; + const typename AT::t_int_1d_const type,mask; + const typename AT::t_tagint_1d_const molecule; + const typename AT::t_tagint_1d_const tag; + const typename AT::t_tagint_2d_const special; + const typename AT::t_int_2d_const nspecial; + const int molecular; + int moltemplate; + + int special_flag[4]; + + const int nbinx,nbiny,nbinz; + const int mbinx,mbiny,mbinz; + const int mbinxlo,mbinylo,mbinzlo; + const X_FLOAT bininvx,bininvy,bininvz; + X_FLOAT bboxhi[3],bboxlo[3]; + + const int nlocal; + + typename AT::t_int_scalar resize; + typename AT::t_int_scalar new_maxneighs; + typename ArrayTypes::t_int_scalar h_resize; + typename ArrayTypes::t_int_scalar h_new_maxneighs; + + const int xperiodic, yperiodic, zperiodic; + const int xprd_half, yprd_half, zprd_half; + + // SSA Work plan data structures + int ssa_phaseCt; + typename AT::t_int_1d d_ssa_phaseLen; + typename AT::t_int_2d d_ssa_itemLoc; + typename AT::t_int_2d d_ssa_itemLen; + + NPairSSAKokkosExecute( + const NeighListKokkos &_neigh_list, + const typename AT::t_xfloat_2d_randomread &_cutneighsq, + const typename AT::t_int_1d &_bincount, + const typename AT::t_int_2d &_bins, + const typename AT::t_int_1d &_gbincount, + const typename AT::t_int_2d &_gbins, + const int _lbinxlo, const int _lbinxhi, + const int _lbinylo, const int _lbinyhi, + const int _lbinzlo, const int _lbinzhi, + const int _nstencil, const int _sx1, const int _sy1, const int _sz1, + const typename AT::t_int_1d &_d_stencil, + const typename AT::t_int_1d_3 &_d_stencilxyz, + const typename AT::t_int_1d &_d_nstencil_ssa, + const int _ssa_phaseCt, + const typename AT::t_int_1d &_d_ssa_phaseLen, + const typename AT::t_int_2d &_d_ssa_itemLoc, + const typename AT::t_int_2d &_d_ssa_itemLen, + const int _nlocal, + const typename AT::t_x_array_randomread &_x, + const typename AT::t_int_1d_const &_type, + const typename AT::t_int_1d_const &_mask, + const typename AT::t_tagint_1d_const &_molecule, + const typename AT::t_tagint_1d_const &_tag, + const typename AT::t_tagint_2d_const &_special, + const typename AT::t_int_2d_const &_nspecial, + const int &_molecular, + const int & _nbinx,const int & _nbiny,const int & _nbinz, + const int & _mbinx,const int & _mbiny,const int & _mbinz, + const int & _mbinxlo,const int & _mbinylo,const int & _mbinzlo, + const X_FLOAT &_bininvx,const X_FLOAT &_bininvy,const X_FLOAT &_bininvz, + const int & _exclude,const int & _nex_type, + const typename AT::t_int_1d_const & _ex1_type, + const typename AT::t_int_1d_const & _ex2_type, + const typename AT::t_int_2d_const & _ex_type, + const int & _nex_group, + const typename AT::t_int_1d_const & _ex1_group, + const typename AT::t_int_1d_const & _ex2_group, + const typename AT::t_int_1d_const & _ex1_bit, + const typename AT::t_int_1d_const & _ex2_bit, + const int & _nex_mol, + const typename AT::t_int_1d_const & _ex_mol_group, + const typename AT::t_int_1d_const & _ex_mol_bit, + const X_FLOAT *_bboxhi, const X_FLOAT* _bboxlo, + const int & _xperiodic, const int & _yperiodic, const int & _zperiodic, + const int & _xprd_half, const int & _yprd_half, const int & _zprd_half): + neigh_list(_neigh_list), cutneighsq(_cutneighsq), + bincount(_bincount),c_bincount(_bincount),bins(_bins),c_bins(_bins), + gbincount(_gbincount),c_gbincount(_gbincount),gbins(_gbins),c_gbins(_gbins), + lbinxlo(_lbinxlo),lbinxhi(_lbinxhi), + lbinylo(_lbinylo),lbinyhi(_lbinyhi), + lbinzlo(_lbinzlo),lbinzhi(_lbinzhi), + nstencil(_nstencil),sx1(_sx1),sy1(_sy1),sz1(_sz1), + d_stencil(_d_stencil),d_stencilxyz(_d_stencilxyz),d_nstencil_ssa(_d_nstencil_ssa), + ssa_phaseCt(_ssa_phaseCt), + d_ssa_phaseLen(_d_ssa_phaseLen), + d_ssa_itemLoc(_d_ssa_itemLoc), + d_ssa_itemLen(_d_ssa_itemLen), + nlocal(_nlocal), + x(_x),type(_type),mask(_mask),molecule(_molecule), + tag(_tag),special(_special),nspecial(_nspecial),molecular(_molecular), + nbinx(_nbinx),nbiny(_nbiny),nbinz(_nbinz), + mbinx(_mbinx),mbiny(_mbiny),mbinz(_mbinz), + mbinxlo(_mbinxlo),mbinylo(_mbinylo),mbinzlo(_mbinzlo), + bininvx(_bininvx),bininvy(_bininvy),bininvz(_bininvz), + exclude(_exclude),nex_type(_nex_type), + ex1_type(_ex1_type),ex2_type(_ex2_type),ex_type(_ex_type), + nex_group(_nex_group), + ex1_group(_ex1_group),ex2_group(_ex2_group), + ex1_bit(_ex1_bit),ex2_bit(_ex2_bit),nex_mol(_nex_mol), + ex_mol_group(_ex_mol_group),ex_mol_bit(_ex_mol_bit), + xperiodic(_xperiodic),yperiodic(_yperiodic),zperiodic(_zperiodic), + xprd_half(_xprd_half),yprd_half(_yprd_half),zprd_half(_zprd_half) { + + if (molecular == 2) moltemplate = 1; + else moltemplate = 0; + + bboxlo[0] = _bboxlo[0]; bboxlo[1] = _bboxlo[1]; bboxlo[2] = _bboxlo[2]; + bboxhi[0] = _bboxhi[0]; bboxhi[1] = _bboxhi[1]; bboxhi[2] = _bboxhi[2]; + + resize = typename AT::t_int_scalar("NeighborKokkosFunctor::resize"); +#ifndef KOKKOS_USE_CUDA_UVM + h_resize = Kokkos::create_mirror_view(resize); +#else + h_resize = resize; +#endif + h_resize() = 1; + new_maxneighs = typename AT:: + t_int_scalar("NeighborKokkosFunctor::new_maxneighs"); +#ifndef KOKKOS_USE_CUDA_UVM + h_new_maxneighs = Kokkos::create_mirror_view(new_maxneighs); +#else + h_new_maxneighs = new_maxneighs; +#endif + h_new_maxneighs() = neigh_list.maxneighs; + }; + + ~NPairSSAKokkosExecute() {neigh_list.clean_copy();}; + + void build_locals(); + void build_ghosts(); + + KOKKOS_INLINE_FUNCTION + int coord2bin(const X_FLOAT & x,const X_FLOAT & y,const X_FLOAT & z, int* i) const + { + int ix,iy,iz; + + if (x >= bboxhi[0]) + ix = static_cast ((x-bboxhi[0])*bininvx) + nbinx; + else if (x >= bboxlo[0]) { + ix = static_cast ((x-bboxlo[0])*bininvx); + ix = MIN(ix,nbinx-1); + } else + ix = static_cast ((x-bboxlo[0])*bininvx) - 1; + + if (y >= bboxhi[1]) + iy = static_cast ((y-bboxhi[1])*bininvy) + nbiny; + else if (y >= bboxlo[1]) { + iy = static_cast ((y-bboxlo[1])*bininvy); + iy = MIN(iy,nbiny-1); + } else + iy = static_cast ((y-bboxlo[1])*bininvy) - 1; + + if (z >= bboxhi[2]) + iz = static_cast ((z-bboxhi[2])*bininvz) + nbinz; + else if (z >= bboxlo[2]) { + iz = static_cast ((z-bboxlo[2])*bininvz); + iz = MIN(iz,nbinz-1); + } else + iz = static_cast ((z-bboxlo[2])*bininvz) - 1; + + i[0] = ix - mbinxlo; + i[1] = iy - mbinylo; + i[2] = iz - mbinzlo; + + return (iz-mbinzlo)*mbiny*mbinx + (iy-mbinylo)*mbinx + (ix-mbinxlo); + } + + KOKKOS_INLINE_FUNCTION + int exclusion(const int &i,const int &j, const int &itype,const int &jtype) const; + + KOKKOS_INLINE_FUNCTION + int find_special(const int &i, const int &j) const; + + KOKKOS_INLINE_FUNCTION + int minimum_image_check(double dx, double dy, double dz) const { + if (xperiodic && fabs(dx) > xprd_half) return 1; + if (yperiodic && fabs(dy) > yprd_half) return 1; + if (zperiodic && fabs(dz) > zprd_half) return 1; + return 0; + } + +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ From b27cc8f474e1a1284d242d209e5fa3ba0e77c5f7 Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Mon, 20 Feb 2017 14:09:11 -0500 Subject: [PATCH 151/439] USER-DPD: use LAMBDA instead of functor for ghost binning in nbin_ssa_kokkos --- src/KOKKOS/nbin_ssa_kokkos.cpp | 32 +++++++++++--------------------- src/KOKKOS/nbin_ssa_kokkos.h | 18 ------------------ 2 files changed, 11 insertions(+), 39 deletions(-) diff --git a/src/KOKKOS/nbin_ssa_kokkos.cpp b/src/KOKKOS/nbin_ssa_kokkos.cpp index 6ed8e9f3e4..32a77119de 100644 --- a/src/KOKKOS/nbin_ssa_kokkos.cpp +++ b/src/KOKKOS/nbin_ssa_kokkos.cpp @@ -122,9 +122,17 @@ void NBinSSAKokkos::bin_atoms() subhi_[1] = domain->subhi[1]; subhi_[2] = domain->subhi[2]; - NPairSSAKokkosBinGhostsFunctor f(*this); - - Kokkos::parallel_for(atom->nghost, f); + Kokkos::parallel_for(Kokkos::RangePolicy(atom->nlocal,atom->nlocal+atom->nghost), KOKKOS_LAMBDA (const int i) { + const int iAIR = coord2ssaAIR(x(i, 0), x(i, 1), x(i, 2)); + if (iAIR > 0) { // include only ghost atoms in an AIR + const int ac = Kokkos::atomic_fetch_add(&gbincount[iAIR], (int)1); + if(ac < (int) gbins.dimension_1()) { + gbins(iAIR, ac) = i; + } else { + d_resize() = 1; + } + } + }); DeviceType::fence(); deep_copy(h_resize, d_resize); @@ -184,24 +192,6 @@ void NBinSSAKokkos::bin_atoms() /* ---------------------------------------------------------------------- */ -template -KOKKOS_INLINE_FUNCTION -void NBinSSAKokkos::binGhostsItem(const int &i_) const -{ - const int i = i_ + atom->nlocal; - const int iAIR = coord2ssaAIR(x(i, 0), x(i, 1), x(i, 2)); - if (iAIR > 0) { // include only ghost atoms in an AIR - const int ac = Kokkos::atomic_fetch_add(&gbincount[iAIR], (int)1); - if(ac < (int) gbins.dimension_1()) { - gbins(iAIR, ac) = i; - } else { - d_resize() = 1; - } - } -} - -/* ---------------------------------------------------------------------- */ - template KOKKOS_INLINE_FUNCTION void NBinSSAKokkos::binAtomsItem(const int &i) const diff --git a/src/KOKKOS/nbin_ssa_kokkos.h b/src/KOKKOS/nbin_ssa_kokkos.h index a16cb2d0b7..488c1034f5 100644 --- a/src/KOKKOS/nbin_ssa_kokkos.h +++ b/src/KOKKOS/nbin_ssa_kokkos.h @@ -77,9 +77,6 @@ class NBinSSAKokkos : public NBinStandard { KOKKOS_INLINE_FUNCTION void binAtomsItem(const int &i) const; - KOKKOS_INLINE_FUNCTION - void binGhostsItem(const int &i) const; - /* ---------------------------------------------------------------------- convert atom coords into the ssa active interaction region number ------------------------------------------------------------------------- */ @@ -153,21 +150,6 @@ class NBinSSAKokkos : public NBinStandard { double sublo_[3], subhi_[3]; }; -template -struct NPairSSAKokkosBinGhostsFunctor { - typedef DeviceType device_type; - - const NBinSSAKokkos c; - - NPairSSAKokkosBinGhostsFunctor(const NBinSSAKokkos &_c): - c(_c) {}; - ~NPairSSAKokkosBinGhostsFunctor() {} - KOKKOS_INLINE_FUNCTION - void operator() (const int & i) const { - c.binGhostsItem(i); - } -}; - template struct NPairSSAKokkosBinAtomsFunctor { typedef DeviceType device_type; From 1db62a57b5ddbd579f1040d977ee659b2c377f89 Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Fri, 24 Feb 2017 13:17:49 -0500 Subject: [PATCH 152/439] USER-DPD: pair_dpd_fdt_energy_kokkos: enable STACKPARAMS specialization --- src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp | 117 ++++++++++++++-------- src/KOKKOS/pair_dpd_fdt_energy_kokkos.h | 24 ++--- 2 files changed, 89 insertions(+), 52 deletions(-) diff --git a/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp b/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp index 84a489bcc3..aaf638fac3 100644 --- a/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp +++ b/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp @@ -49,7 +49,6 @@ PairDPDfdtEnergyKokkos::PairDPDfdtEnergyKokkos(LAMMPS *lmp) : execution_space = ExecutionSpaceFromDevice::space; datamask_read = EMPTY_MASK; datamask_modify = EMPTY_MASK; - STACKPARAMS = 0; } /* ---------------------------------------------------------------------- */ @@ -171,21 +170,41 @@ void PairDPDfdtEnergyKokkos::compute(int eflag_in, int vflag_in) if (splitFDT_flag) { if (!a0_is_zero) { - if (neighflag == HALF) { - if (newton_pair) { - if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); - else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); - } else { - if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); - else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + if(atom->ntypes > MAX_TYPES_STACKPARAMS) { + if (neighflag == HALF) { + if (newton_pair) { + if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } else { + if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } + } else if (neighflag == HALFTHREAD) { + if (newton_pair) { + if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } else { + if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } } - } else if (neighflag == HALFTHREAD) { - if (newton_pair) { - if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); - else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); - } else { - if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); - else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } else { + if (neighflag == HALF) { + if (newton_pair) { + if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } else { + if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } + } else if (neighflag == HALFTHREAD) { + if (newton_pair) { + if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } else { + if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } } } } @@ -209,21 +228,41 @@ void PairDPDfdtEnergyKokkos::compute(int eflag_in, int vflag_in) // loop over neighbors of my atoms - if (neighflag == HALF) { - if (newton_pair) { - if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); - else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); - } else { - if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); - else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + if(atom->ntypes > MAX_TYPES_STACKPARAMS) { + if (neighflag == HALF) { + if (newton_pair) { + if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } else { + if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } + } else if (neighflag == HALFTHREAD) { + if (newton_pair) { + if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } else { + if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } } - } else if (neighflag == HALFTHREAD) { - if (newton_pair) { - if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); - else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); - } else { - if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); - else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } else { + if (neighflag == HALF) { + if (newton_pair) { + if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } else { + if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } + } else if (neighflag == HALFTHREAD) { + if (newton_pair) { + if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } else { + if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } } } @@ -270,9 +309,9 @@ void PairDPDfdtEnergyKokkos::operator()(TagPairDPDfdtEnergyZero, con } template -template +template KOKKOS_INLINE_FUNCTION -void PairDPDfdtEnergyKokkos::operator()(TagPairDPDfdtEnergyComputeSplit, const int &ii, EV_FLOAT& ev) const { +void PairDPDfdtEnergyKokkos::operator()(TagPairDPDfdtEnergyComputeSplit, const int &ii, EV_FLOAT& ev) const { // The f array is atomic for Half/Thread neighbor style Kokkos::View::value> > a_f = f; @@ -346,17 +385,17 @@ void PairDPDfdtEnergyKokkos::operator()(TagPairDPDfdtEnergyComputeSp } template -template +template KOKKOS_INLINE_FUNCTION -void PairDPDfdtEnergyKokkos::operator()(TagPairDPDfdtEnergyComputeSplit, const int &ii) const { +void PairDPDfdtEnergyKokkos::operator()(TagPairDPDfdtEnergyComputeSplit, const int &ii) const { EV_FLOAT ev; - this->template operator()(TagPairDPDfdtEnergyComputeSplit(), ii, ev); + this->template operator()(TagPairDPDfdtEnergyComputeSplit(), ii, ev); } template -template +template KOKKOS_INLINE_FUNCTION -void PairDPDfdtEnergyKokkos::operator()(TagPairDPDfdtEnergyComputeNoSplit, const int &ii, EV_FLOAT& ev) const { +void PairDPDfdtEnergyKokkos::operator()(TagPairDPDfdtEnergyComputeNoSplit, const int &ii, EV_FLOAT& ev) const { // These array are atomic for Half/Thread neighbor style Kokkos::View::value> > a_f = f; @@ -503,11 +542,11 @@ void PairDPDfdtEnergyKokkos::operator()(TagPairDPDfdtEnergyComputeNo } template -template +template KOKKOS_INLINE_FUNCTION -void PairDPDfdtEnergyKokkos::operator()(TagPairDPDfdtEnergyComputeNoSplit, const int &ii) const { +void PairDPDfdtEnergyKokkos::operator()(TagPairDPDfdtEnergyComputeNoSplit, const int &ii) const { EV_FLOAT ev; - this->template operator()(TagPairDPDfdtEnergyComputeNoSplit(), ii, ev); + this->template operator()(TagPairDPDfdtEnergyComputeNoSplit(), ii, ev); } /* ---------------------------------------------------------------------- diff --git a/src/KOKKOS/pair_dpd_fdt_energy_kokkos.h b/src/KOKKOS/pair_dpd_fdt_energy_kokkos.h index 7d1749eb94..9689712273 100644 --- a/src/KOKKOS/pair_dpd_fdt_energy_kokkos.h +++ b/src/KOKKOS/pair_dpd_fdt_energy_kokkos.h @@ -32,10 +32,10 @@ namespace LAMMPS_NS { struct TagPairDPDfdtEnergyZero{}; -template +template struct TagPairDPDfdtEnergyComputeSplit{}; -template +template struct TagPairDPDfdtEnergyComputeNoSplit{}; template @@ -54,21 +54,21 @@ class PairDPDfdtEnergyKokkos : public PairDPDfdtEnergy { KOKKOS_INLINE_FUNCTION void operator()(TagPairDPDfdtEnergyZero, const int&) const; - template + template KOKKOS_INLINE_FUNCTION - void operator()(TagPairDPDfdtEnergyComputeSplit, const int&, EV_FLOAT&) const; + void operator()(TagPairDPDfdtEnergyComputeSplit, const int&, EV_FLOAT&) const; - template + template KOKKOS_INLINE_FUNCTION - void operator()(TagPairDPDfdtEnergyComputeSplit, const int&) const; + void operator()(TagPairDPDfdtEnergyComputeSplit, const int&) const; - template + template KOKKOS_INLINE_FUNCTION - void operator()(TagPairDPDfdtEnergyComputeNoSplit, const int&, EV_FLOAT&) const; + void operator()(TagPairDPDfdtEnergyComputeNoSplit, const int&, EV_FLOAT&) const; - template + template KOKKOS_INLINE_FUNCTION - void operator()(TagPairDPDfdtEnergyComputeNoSplit, const int&) const; + void operator()(TagPairDPDfdtEnergyComputeNoSplit, const int&) const; template KOKKOS_INLINE_FUNCTION @@ -92,7 +92,6 @@ class PairDPDfdtEnergyKokkos : public PairDPDfdtEnergy { protected: int eflag,vflag; int nlocal,neighflag; - int STACKPARAMS; double dtinvsqrt; double boltz,ftm2v; double special_lj[4]; @@ -102,11 +101,10 @@ class PairDPDfdtEnergyKokkos : public PairDPDfdtEnergy { Kokkos::DualView k_params; typename Kokkos::DualView::t_dev_const_um params; - // hardwired to space for 15 atom types + // hardwired to space for MAX_TYPES_STACKPARAMS (12) atom types params_dpd m_params[MAX_TYPES_STACKPARAMS+1][MAX_TYPES_STACKPARAMS+1]; F_FLOAT m_cutsq[MAX_TYPES_STACKPARAMS+1][MAX_TYPES_STACKPARAMS+1]; - F_FLOAT m_cut[MAX_TYPES_STACKPARAMS+1][MAX_TYPES_STACKPARAMS+1]; typename ArrayTypes::t_x_array_randomread x; typename ArrayTypes::t_x_array c_x; typename ArrayTypes::t_v_array_randomread v; From aecafecaa2f89f6db8c90ec5af0db429e736b82e Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Fri, 24 Feb 2017 13:21:26 -0500 Subject: [PATCH 153/439] USER-DPD: fix missing host prefixes in AtomVecDPDKokkos::pack_comm --- src/KOKKOS/atom_vec_dpd_kokkos.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/KOKKOS/atom_vec_dpd_kokkos.cpp b/src/KOKKOS/atom_vec_dpd_kokkos.cpp index f46f284f14..18f63599e4 100644 --- a/src/KOKKOS/atom_vec_dpd_kokkos.cpp +++ b/src/KOKKOS/atom_vec_dpd_kokkos.cpp @@ -563,10 +563,10 @@ int AtomVecDPDKokkos::pack_comm(int n, int *list, double *buf, buf[m++] = h_x(j,0); buf[m++] = h_x(j,1); buf[m++] = h_x(j,2); - buf[m++] = dpdTheta[j]; - buf[m++] = uCond[j]; - buf[m++] = uMech[j]; - buf[m++] = uChem[j]; + buf[m++] = h_dpdTheta[j]; + buf[m++] = h_uCond[j]; + buf[m++] = h_uMech[j]; + buf[m++] = h_uChem[j]; } } else { if (domain->triclinic == 0) { From 2f04e87d0794c66e9fbe0073690e64f7353cfcec Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Fri, 24 Feb 2017 13:24:18 -0500 Subject: [PATCH 154/439] USER-DPD: make PairDPDfdtEnergyKokkos's rand_pool public so it can be reused --- src/KOKKOS/pair_dpd_fdt_energy_kokkos.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/KOKKOS/pair_dpd_fdt_energy_kokkos.h b/src/KOKKOS/pair_dpd_fdt_energy_kokkos.h index 9689712273..deb264c37e 100644 --- a/src/KOKKOS/pair_dpd_fdt_energy_kokkos.h +++ b/src/KOKKOS/pair_dpd_fdt_energy_kokkos.h @@ -89,6 +89,15 @@ class PairDPDfdtEnergyKokkos : public PairDPDfdtEnergy { DAT::tdual_efloat_1d k_duCond,k_duMech; + Kokkos::Random_XorShift64_Pool rand_pool; + typedef typename Kokkos::Random_XorShift64_Pool::generator_type rand_type; + + // RandPoolWrap rand_pool; + // typedef RandWrap rand_type; + + typename ArrayTypes::tdual_ffloat_2d k_cutsq; + typename ArrayTypes::t_ffloat_2d d_cutsq; + protected: int eflag,vflag; int nlocal,neighflag; @@ -125,15 +134,6 @@ class PairDPDfdtEnergyKokkos : public PairDPDfdtEnergy { typename AT::t_int_1d_randomread d_ilist; typename AT::t_int_1d_randomread d_numneigh; - typename ArrayTypes::tdual_ffloat_2d k_cutsq; - typename ArrayTypes::t_ffloat_2d d_cutsq; - - /**/Kokkos::Random_XorShift64_Pool rand_pool; - typedef typename Kokkos::Random_XorShift64_Pool::generator_type rand_type;/**/ - - /**RandPoolWrap rand_pool; - typedef RandWrap rand_type;/**/ - friend void pair_virial_fdotr_compute(PairDPDfdtEnergyKokkos*); }; From a341a6bca927e84a9fc947e402459466ceded503 Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Fri, 24 Feb 2017 13:27:27 -0500 Subject: [PATCH 155/439] USER-DPD: make locals & ghosts use similar SSA work plan data structure Kokkos SSA won't use AIRct_ssa[], but still used for non-Kokkos for now. --- src/KOKKOS/npair_ssa_kokkos.cpp | 31 +++++++++++++++++++++++++------ src/KOKKOS/npair_ssa_kokkos.h | 20 ++++++++++++++++++++ 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/src/KOKKOS/npair_ssa_kokkos.cpp b/src/KOKKOS/npair_ssa_kokkos.cpp index 752fc0c938..c70fd0087e 100644 --- a/src/KOKKOS/npair_ssa_kokkos.cpp +++ b/src/KOKKOS/npair_ssa_kokkos.cpp @@ -31,7 +31,7 @@ namespace LAMMPS_NS { /* ---------------------------------------------------------------------- */ template -NPairSSAKokkos::NPairSSAKokkos(LAMMPS *lmp) : NPair(lmp), ssa_phaseCt(27) +NPairSSAKokkos::NPairSSAKokkos(LAMMPS *lmp) : NPair(lmp), ssa_phaseCt(27), ssa_gphaseCt(7) { } @@ -214,6 +214,7 @@ void NPairSSAKokkos::build(NeighList *list_) int ybin = (lbinyhi - lbinylo + sy1 - 1) / sy1 + 1; int zbin = (lbinzhi - lbinzlo + sz1 - 1) / sz1 + 1; int phaseLenEstimate = xbin*ybin*zbin; + int gphaseLenEstimate = 1; //FIXME make this 4 eventually if (ssa_phaseCt > (int) k_ssa_phaseLen.dimension_0()) { k_ssa_phaseLen = DAT::tdual_int_1d("NPairSSAKokkos:ssa_phaseLen",ssa_phaseCt); @@ -227,6 +228,18 @@ void NPairSSAKokkos::build(NeighList *list_) ssa_itemLen = k_ssa_itemLen.view(); } + if (ssa_gphaseCt > (int) k_ssa_gphaseLen.dimension_0()) { + k_ssa_gphaseLen = DAT::tdual_int_1d("NPairSSAKokkos:ssa_gphaseLen",ssa_gphaseCt); + ssa_gphaseLen = k_ssa_gphaseLen.view(); + } + if ((ssa_gphaseCt > (int) k_ssa_gitemLoc.dimension_0()) || + (gphaseLenEstimate > (int) k_ssa_gitemLoc.dimension_1())) { + k_ssa_gitemLoc = DAT::tdual_int_2d("NPairSSAKokkos::ssa_gitemLoc",ssa_gphaseCt,gphaseLenEstimate); + ssa_gitemLoc = k_ssa_gitemLoc.view(); + k_ssa_gitemLen = DAT::tdual_int_2d("NPairSSAKokkos::ssa_gitemLen",ssa_gphaseCt,gphaseLenEstimate); + ssa_gitemLen = k_ssa_gitemLen.view(); + } + NPairSSAKokkosExecute data(*list, k_cutneighsq.view(), @@ -243,6 +256,10 @@ void NPairSSAKokkos::build(NeighList *list_) k_ssa_phaseLen.view(), k_ssa_itemLoc.view(), k_ssa_itemLen.view(), + ssa_gphaseCt, + k_ssa_gphaseLen.view(), + k_ssa_gitemLoc.view(), + k_ssa_gitemLen.view(), nlocal, atomKK->k_x.view(), atomKK->k_type.view(), @@ -444,12 +461,13 @@ void NPairSSAKokkosExecute::build_ghosts() int which = 0; int inum = neigh_list.inum; int gnum = 0; - neigh_list.AIRct_ssa[0] = inum; //FIXME // loop over AIR ghost atoms, storing their local neighbors // since these are ghosts, must check if stencil bin is out of bounds - for (int airnum = 1; airnum <= 7; airnum++) { - int locAIRct = 0; + for (int workPhase = 0; workPhase < ssa_gphaseCt; workPhase++) { + int airnum = workPhase + 1; + int workItem = 0; //FIXME for now, there is only 1 workItem for each ghost AIR + d_ssa_gitemLoc(workPhase, workItem) = inum + gnum; // record where workItem starts in ilist for (int il = 0; il < c_gbincount(airnum); ++il) { const int i = c_gbins(airnum, il); n = 0; @@ -521,10 +539,11 @@ void NPairSSAKokkosExecute::build_ghosts() resize() = 1; if(n > new_maxneighs()) Kokkos::atomic_fetch_max(&new_maxneighs(),n); } - ++locAIRct; } } - neigh_list.AIRct_ssa[airnum] = locAIRct; //FIXME + // record where workItem ends in ilist + d_ssa_gitemLen(workPhase,workItem) = inum + gnum - d_ssa_gitemLoc(workPhase,workItem); + if (d_ssa_gitemLen(workPhase,workItem) > 0) workItem++; } neigh_list.gnum = gnum; //FIXME } diff --git a/src/KOKKOS/npair_ssa_kokkos.h b/src/KOKKOS/npair_ssa_kokkos.h index a656fe32ba..e38d648984 100644 --- a/src/KOKKOS/npair_ssa_kokkos.h +++ b/src/KOKKOS/npair_ssa_kokkos.h @@ -47,6 +47,14 @@ class NPairSSAKokkos : public NPair { typename AT::t_int_2d ssa_itemLoc; typename AT::t_int_2d ssa_itemLen; + const int ssa_gphaseCt; + DAT::tdual_int_1d k_ssa_gphaseLen; + DAT::tdual_int_2d k_ssa_gitemLoc; + DAT::tdual_int_2d k_ssa_gitemLen; + typename AT::t_int_1d ssa_gphaseLen; + typename AT::t_int_2d ssa_gitemLoc; + typename AT::t_int_2d ssa_gitemLen; + NPairSSAKokkos(class LAMMPS *); ~NPairSSAKokkos() {} void copy_neighbor_info(); @@ -169,6 +177,10 @@ class NPairSSAKokkosExecute typename AT::t_int_1d d_ssa_phaseLen; typename AT::t_int_2d d_ssa_itemLoc; typename AT::t_int_2d d_ssa_itemLen; + int ssa_gphaseCt; + typename AT::t_int_1d d_ssa_gphaseLen; + typename AT::t_int_2d d_ssa_gitemLoc; + typename AT::t_int_2d d_ssa_gitemLen; NPairSSAKokkosExecute( const NeighListKokkos &_neigh_list, @@ -188,6 +200,10 @@ class NPairSSAKokkosExecute const typename AT::t_int_1d &_d_ssa_phaseLen, const typename AT::t_int_2d &_d_ssa_itemLoc, const typename AT::t_int_2d &_d_ssa_itemLen, + const int _ssa_gphaseCt, + const typename AT::t_int_1d &_d_ssa_gphaseLen, + const typename AT::t_int_2d &_d_ssa_gitemLoc, + const typename AT::t_int_2d &_d_ssa_gitemLen, const int _nlocal, const typename AT::t_x_array_randomread &_x, const typename AT::t_int_1d_const &_type, @@ -228,6 +244,10 @@ class NPairSSAKokkosExecute d_ssa_phaseLen(_d_ssa_phaseLen), d_ssa_itemLoc(_d_ssa_itemLoc), d_ssa_itemLen(_d_ssa_itemLen), + ssa_gphaseCt(_ssa_gphaseCt), + d_ssa_gphaseLen(_d_ssa_gphaseLen), + d_ssa_gitemLoc(_d_ssa_gitemLoc), + d_ssa_gitemLen(_d_ssa_gitemLen), nlocal(_nlocal), x(_x),type(_type),mask(_mask),molecule(_molecule), tag(_tag),special(_special),nspecial(_nspecial),molecular(_molecular), From f7a48719adba859eede3808e69556f1e33e4dbf0 Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Fri, 24 Feb 2017 13:35:48 -0500 Subject: [PATCH 156/439] USER-DPD: first attempt at fix_shardlow_kokkos... It compiles! --- src/KOKKOS/fix_shardlow_kokkos.cpp | 718 +++++++++++++++++++++++++++++ src/KOKKOS/fix_shardlow_kokkos.h | 154 +++++++ 2 files changed, 872 insertions(+) create mode 100644 src/KOKKOS/fix_shardlow_kokkos.cpp create mode 100644 src/KOKKOS/fix_shardlow_kokkos.h diff --git a/src/KOKKOS/fix_shardlow_kokkos.cpp b/src/KOKKOS/fix_shardlow_kokkos.cpp new file mode 100644 index 0000000000..7b2810bb4c --- /dev/null +++ b/src/KOKKOS/fix_shardlow_kokkos.cpp @@ -0,0 +1,718 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing authors: + James Larentzos (U.S. Army Research Laboratory) + and Timothy I. Mattox (Engility Corporation) + + Martin Lisal (Institute of Chemical Process Fundamentals + of the Czech Academy of Sciences and J. E. Purkinje University) + + John Brennan, Joshua Moore and William Mattson (Army Research Lab) + + Please cite the related publications: + J. P. Larentzos, J. K. Brennan, J. D. Moore, M. Lisal, W. D. Mattson, + "Parallel implementation of isothermal and isoenergetic Dissipative + Particle Dynamics using Shardlow-like splitting algorithms", + Computer Physics Communications, 2014, 185, pp 1987--1998. + + M. Lisal, J. K. Brennan, J. Bonet Avalos, "Dissipative particle dynamics + at isothermal, isobaric, isoenergetic, and isoenthalpic conditions using + Shardlow-like splitting algorithms", Journal of Chemical Physics, 2011, + 135, 204105. +------------------------------------------------------------------------- */ + +#include +#include +#include +#include "fix_shardlow_kokkos.h" +#include "atom.h" +#include "atom_masks.h" +#include "atom_kokkos.h" +#include "force.h" +#include "update.h" +#include "respa.h" +#include "error.h" +#include +#include "atom_vec.h" +#include "comm.h" +#include "neighbor.h" +#include "neigh_list_kokkos.h" +#include "neigh_request.h" +#include "random_mars.h" +#include "memory.h" +#include "domain.h" +#include "modify.h" +// #include "pair_dpd_fdt.h" +#include "pair_dpd_fdt_energy_kokkos.h" +#include "pair.h" +#include "npair_ssa_kokkos.h" +#include "citeme.h" + +using namespace LAMMPS_NS; +using namespace FixConst; + +#define EPSILON 1.0e-10 +#define EPSILON_SQUARED ((EPSILON) * (EPSILON)) + + +/* ---------------------------------------------------------------------- */ + +template +FixShardlowKokkos::FixShardlowKokkos(LAMMPS *lmp, int narg, char **arg) : + FixShardlow(lmp, narg, arg), k_pairDPDE(NULL), ghostmax(0), nlocal(0) , nghost(0) +{ + kokkosable = 1; +// atomKK = (AtomKokkos *) atom; +// execution_space = ExecutionSpaceFromDevice::space; + +// datamask_read = X_MASK | V_MASK | F_MASK | MASK_MASK | Q_MASK | TYPE_MASK; +// datamask_modify = Q_MASK | X_MASK; + + if (narg != 3) error->all(FLERR,"Illegal fix shardlow command"); + +// k_pairDPD = NULL; + k_pairDPDE = NULL; +// k_pairDPD = (PairDPDfdtKokkos *) force->pair_match("dpd/fdt",1); + k_pairDPDE = (PairDPDfdtEnergyKokkos *) force->pair_match("dpd/fdt/energy/kk",1); + +// if(k_pairDPDE){ + comm_forward = 3; + comm_reverse = 5; + p_rand_pool = &(k_pairDPDE->rand_pool); +// } else { +// comm_forward = 3; +// comm_reverse = 3; +// p_rand_pool = &(k_pairDPD->rand_pool); +// } + + + if(/* k_pairDPD == NULL &&*/ k_pairDPDE == NULL) + error->all(FLERR,"Must use pair_style "/*"dpd/fdt/kk or "*/"dpd/fdt/energy/kk with fix shardlow/kk"); + +} + +/* ---------------------------------------------------------------------- */ + +template +FixShardlowKokkos::~FixShardlowKokkos() +{ + ghostmax = 0; +} + +/* ---------------------------------------------------------------------- */ + +template +int FixShardlowKokkos::setmask() +{ + int mask = 0; + mask |= INITIAL_INTEGRATE | PRE_NEIGHBOR; + return mask; +} + +/* ---------------------------------------------------------------------- */ + +template +void FixShardlowKokkos::init() +{ + FixShardlow::init(); + + int irequest = neighbor->nrequest - 1; + + neighbor->requests[irequest]-> + kokkos_host = Kokkos::Impl::is_same::value && + !Kokkos::Impl::is_same::value; + neighbor->requests[irequest]-> + kokkos_device = Kokkos::Impl::is_same::value; + +// neighbor->requests[irequest]->pair = 0; +// neighbor->requests[irequest]->fix = 1; +// neighbor->requests[irequest]->ghost= 1; +// neighbor->requests[irequest]->ssa = 1; + + int ntypes = atom->ntypes; + k_params = Kokkos::DualView + ("FixShardlowKokkos::params",ntypes+1,ntypes+1); + params = k_params.template view(); +//FIXME either create cutsq and fill it in, or just point to pairDPD's... +// memory->destroy(cutsq); //FIXME +// memory->create_kokkos(k_cutsq,cutsq,ntypes+1,ntypes+1,"FixShardlowKokkos:cutsq"); + d_cutsq = k_pairDPDE->k_cutsq.template view(); //FIXME + + const double boltz2 = 2.0*force->boltz; + for (int i = 1; i <= ntypes; i++) { + for (int j = i; j <= ntypes; j++) { + F_FLOAT cutone = k_pairDPDE->cut[i][j]; +// k_cutsq.h_view(i,j) = k_cutsq.h_view(j,i) = cutone*cutone; //FIXME + if (cutone > EPSILON) k_params.h_view(i,j).cutinv = 1.0/cutone; + else k_params.h_view(i,j).cutinv = FLT_MAX; + k_params.h_view(i,j).halfsigma = 0.5*k_pairDPDE->sigma[i][j]; + k_params.h_view(i,j).kappa = k_pairDPDE->kappa[i][j]; + k_params.h_view(i,j).alpha = sqrt(boltz2*k_pairDPDE->kappa[i][j]); + + k_params.h_view(j,i) = k_params.h_view(i,j); + + if(ik_cutsq.h_view(i,j); + } + } + } + + // k_cutsq.template modify(); + k_params.template modify(); +} + +/* ---------------------------------------------------------------------- */ + +template +void FixShardlowKokkos::init_list(int id, NeighList *ptr) +{ + k_list = static_cast*>(ptr); +} + +/* ---------------------------------------------------------------------- */ + +template +void FixShardlowKokkos::pre_neighbor() +{ + // NOTE: this logic is specific to orthogonal boxes, not triclinic + + // Enforce the constraint that ghosts must be contained in the nearest sub-domains + double bbx = domain->subhi[0] - domain->sublo[0]; + double bby = domain->subhi[1] - domain->sublo[1]; + double bbz = domain->subhi[2] - domain->sublo[2]; + + double rcut = 2.0*neighbor->cutneighmax; + + if (domain->triclinic) + error->all(FLERR,"Fix shardlow does not yet support triclinic geometries"); + + if(rcut >= bbx || rcut >= bby || rcut>= bbz ) + { + char fmt[] = {"Shardlow algorithm requires sub-domain length > 2*(rcut+skin). Either reduce the number of processors requested, or change the cutoff/skin: rcut= %e bbx= %e bby= %e bbz= %e\n"}; + char *msg = (char *) malloc(sizeof(fmt) + 4*15); + sprintf(msg, fmt, rcut, bbx, bby, bbz); + error->one(FLERR, msg); + } + + nlocal = atomKK->nlocal; + nghost = atomKK->nghost; + + // Allocate memory for h_v_t0 to hold the initial velocities for the ghosts + if (nghost > ghostmax) { + ghostmax = nghost; + k_v_t0 = DAT::tdual_v_array("FixShardlowKokkos:v_t0", ghostmax); + // d_v_t0 = k_v_t0.template view(); + h_v_t0 = k_v_t0.h_view; + } + + // Setup views of relevant data + x = atomKK->k_x.template view(); + v = atomKK->k_v.template view(); + h_v = atomKK->k_v.h_view; + uCond = atomKK->k_uCond.template view(); + h_uCond = atomKK->k_uCond.h_view; + uMech = atomKK->k_uMech.template view(); + h_uMech = atomKK->k_uMech.h_view; + type = atomKK->k_type.view(); + if (atomKK->rmass) { + massPerI = true; + masses = atomKK->k_rmass.view(); + } else { + massPerI = false; + masses = atomKK->k_mass.view(); + } +// if(k_pairDPDE){ + dpdTheta = atomKK->k_dpdTheta.view(); + +//} else { +//} +} + +template +void FixShardlowKokkos::setup_pre_neighbor() +{ + pre_neighbor(); +} + +/* ---------------------------------------------------------------------- */ + +#ifdef NOTNOW +/* ---------------------------------------------------------------------- + Perform the stochastic integration and Shardlow update for constant temperature + Allow for both per-type and per-atom mass + + NOTE: only implemented for orthogonal boxes, not triclinic +------------------------------------------------------------------------- */ +template +template +void FixShardlowKokkos::ssa_update_dpd( + int start_ii, int count +) +{ + rand_type rand_gen = p_rand_pool->get_state(); + + const double theta_ij_inv = 1.0/k_pairDPD->temperature; // independent of i,j + const double boltz_inv = 1.0/force->boltz; + const double ftm2v = force->ftm2v; + const double dt = update->dt; + int ct = count; + int ii = start_ii; + + while (ct-- > 0) { + const int i = d_ilist(ii); + const int jlen = d_numneigh(ii); + + const double xtmp = x(i, 0); + const double ytmp = x(i, 1); + const double ztmp = x(i, 2); + + // load velocity for i from memory + double vxi = v(i, 0); + double vyi = v(i, 1); + double vzi = v(i, 2); + + const int itype = type(i); + + const double mass_i = masses(massPerI ? i : itype); + const double massinv_i = 1.0 / mass_i; + + // Loop over Directional Neighbors only + for (int jj = 0; jj < jlen; jj++) { + const int j = d_neighbors(ii,jj) & NEIGHMASK; + int jtype = type[j]; + + 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 F_FLOAT rsq = delx*delx + dely*dely + delz*delz; + + // NOTE: r can be 0.0 in DPD systems, so do EPSILON_SQUARED test + if ((rsq < STACKPARAMS?m_cutsq[itype][jtype]:d_cutsq(itype,jtype)) + && (rsq >= EPSILON_SQUARED)) { + double r = sqrt(rsq); + double rinv = 1.0/r; + double delx_rinv = delx*rinv; + double dely_rinv = dely*rinv; + double delz_rinv = delz*rinv; + + double wr = 1.0 - r*(STACKPARAMS?m_params[itype][jtype].cutinv:params(itype,jtype).cutinv); + double wdt = wr*wr*dt; + + double halfsigma_ij = STACKPARAMS?m_params[itype][jtype].halfsigma:params(itype,jtype).halfsigma; + double halfgamma_ij = halfsigma_ij*halfsigma_ij*boltz_inv*theta_ij_inv; + + double sigmaRand = halfsigma_ij*wr*dtsqrt*ftm2v * pRNG->gaussian(); + + const double mass_j = masses(massPerI ? j : jtype); + double massinv_j = 1.0 / mass_j; + + double gammaFactor = halfgamma_ij*wdt*ftm2v; + double inv_1p_mu_gammaFactor = 1.0/(1.0 + (massinv_i + massinv_j)*gammaFactor); + + double vxj = v(j, 0); + double vyj = v(j, 1); + double vzj = v(j, 2); + + // Compute the initial velocity difference between atom i and atom j + double delvx = vxi - vxj; + double delvy = vyi - vyj; + double delvz = vzi - vzj; + double dot_rinv = (delx_rinv*delvx + dely_rinv*delvy + delz_rinv*delvz); + + // Compute momentum change between t and t+dt + double factorA = sigmaRand - gammaFactor*dot_rinv; + + // Update the velocity on i + vxi += delx_rinv*factorA*massinv_i; + vyi += dely_rinv*factorA*massinv_i; + vzi += delz_rinv*factorA*massinv_i; + + // Update the velocity on j + vxj -= delx_rinv*factorA*massinv_j; + vyj -= dely_rinv*factorA*massinv_j; + vzj -= delz_rinv*factorA*massinv_j; + + //ii. Compute the new velocity diff + delvx = vxi - vxj; + delvy = vyi - vyj; + delvz = vzi - vzj; + dot_rinv = delx_rinv*delvx + dely_rinv*delvy + delz_rinv*delvz; + + // Compute the new momentum change between t and t+dt + double factorB = (sigmaRand - gammaFactor*dot_rinv)*inv_1p_mu_gammaFactor; + + // Update the velocity on i + vxi += delx_rinv*factorB*massinv_i; + vyi += dely_rinv*factorB*massinv_i; + vzi += delz_rinv*factorB*massinv_i; + + // Update the velocity on j + vxj -= delx_rinv*factorB*massinv_j; + vyj -= dely_rinv*factorB*massinv_j; + vzj -= delz_rinv*factorB*massinv_j; + + // Store updated velocity for j + v(j, 0) = vxj; + v(j, 1) = vyj; + v(j, 2) = vzj; + } + } + // store updated velocity for i + v(i, 0) = vxi; + v(i, 1) = vyi; + v(i, 2) = vzi; + } + + p_rand_pool->free_state(rand_gen); +} +#endif + +/* ---------------------------------------------------------------------- + Perform the stochastic integration and Shardlow update for constant energy + Allow for both per-type and per-atom mass + + NOTE: only implemented for orthogonal boxes, not triclinic +------------------------------------------------------------------------- */ +template +template +void FixShardlowKokkos::ssa_update_dpde( + int start_ii, int count +) +{ + rand_type rand_gen = p_rand_pool->get_state(); + + const double boltz_inv = 1.0/force->boltz; + const double ftm2v = force->ftm2v; + const double dt = update->dt; + int ct = count; + int ii = start_ii; + + while (ct-- > 0) { + const int i = d_ilist(ii); + const int jlen = d_numneigh(ii); + + const double xtmp = x(i, 0); + const double ytmp = x(i, 1); + const double ztmp = x(i, 2); + + // load velocity for i from memory + double vxi = v(i, 0); + double vyi = v(i, 1); + double vzi = v(i, 2); + + double uMech_i = uMech(i); + double uCond_i = uCond(i); + const int itype = type(i); + + const double theta_i_inv = 1.0/dpdTheta(i); + const double mass_i = masses(massPerI ? i : itype); + const double massinv_i = 1.0 / mass_i; + const double mass_i_div_neg4_ftm2v = mass_i*(-0.25)/ftm2v; + + // Loop over Directional Neighbors only + for (int jj = 0; jj < jlen; jj++) { + const int j = d_neighbors(ii,jj) & NEIGHMASK; + const int jtype = type(j); + + 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 F_FLOAT rsq = delx*delx + dely*dely + delz*delz; + + // NOTE: r can be 0.0 in DPD systems, so do EPSILON_SQUARED test + if ((rsq < STACKPARAMS?m_cutsq[itype][jtype]:d_cutsq(itype,jtype)) + && (rsq >= EPSILON_SQUARED)) { + double r = sqrt(rsq); + double rinv = 1.0/r; + double delx_rinv = delx*rinv; + double dely_rinv = dely*rinv; + double delz_rinv = delz*rinv; + + double wr = 1.0 - r*(STACKPARAMS?m_params[itype][jtype].cutinv:params(itype,jtype).cutinv); + double wdt = wr*wr*dt; + + // Compute the current temperature + double theta_j_inv = 1.0/dpdTheta(j); + double theta_ij_inv = 0.5*(theta_i_inv + theta_j_inv); + + double halfsigma_ij = STACKPARAMS?m_params[itype][jtype].halfsigma:params(itype,jtype).halfsigma; + double halfgamma_ij = halfsigma_ij*halfsigma_ij*boltz_inv*theta_ij_inv; + + double sigmaRand = halfsigma_ij*wr*dtsqrt*ftm2v * rand_gen.normal(); + + const double mass_j = masses(massPerI ? j : jtype); + double mass_ij_div_neg4_ftm2v = mass_j*mass_i_div_neg4_ftm2v; + double massinv_j = 1.0 / mass_j; + + // Compute uCond + double kappa_ij = STACKPARAMS?m_params[itype][jtype].kappa:params(itype,jtype).kappa; + double alpha_ij = STACKPARAMS?m_params[itype][jtype].alpha:params(itype,jtype).alpha; + double del_uCond = alpha_ij*wr*dtsqrt * rand_gen.normal(); + + del_uCond += kappa_ij*(theta_i_inv - theta_j_inv)*wdt; + uCond[j] -= del_uCond; + uCond_i += del_uCond; + + double gammaFactor = halfgamma_ij*wdt*ftm2v; + double inv_1p_mu_gammaFactor = 1.0/(1.0 + (massinv_i + massinv_j)*gammaFactor); + + double vxj = v(j, 0); + double vyj = v(j, 1); + double vzj = v(j, 2); + double dot4 = vxj*vxj + vyj*vyj + vzj*vzj; + double dot3 = vxi*vxi + vyi*vyi + vzi*vzi; + + // Compute the initial velocity difference between atom i and atom j + double delvx = vxi - vxj; + double delvy = vyi - vyj; + double delvz = vzi - vzj; + double dot_rinv = (delx_rinv*delvx + dely_rinv*delvy + delz_rinv*delvz); + + // Compute momentum change between t and t+dt + double factorA = sigmaRand - gammaFactor*dot_rinv; + + // Update the velocity on i + vxi += delx_rinv*factorA*massinv_i; + vyi += dely_rinv*factorA*massinv_i; + vzi += delz_rinv*factorA*massinv_i; + + // Update the velocity on j + vxj -= delx_rinv*factorA*massinv_j; + vyj -= dely_rinv*factorA*massinv_j; + vzj -= delz_rinv*factorA*massinv_j; + + //ii. Compute the new velocity diff + delvx = vxi - vxj; + delvy = vyi - vyj; + delvz = vzi - vzj; + dot_rinv = delx_rinv*delvx + dely_rinv*delvy + delz_rinv*delvz; + + // Compute the new momentum change between t and t+dt + double factorB = (sigmaRand - gammaFactor*dot_rinv)*inv_1p_mu_gammaFactor; + + // Update the velocity on i + vxi += delx_rinv*factorB*massinv_i; + vyi += dely_rinv*factorB*massinv_i; + vzi += delz_rinv*factorB*massinv_i; + double partial_uMech = (vxi*vxi + vyi*vyi + vzi*vzi - dot3)*massinv_j; + + // Update the velocity on j + vxj -= delx_rinv*factorB*massinv_j; + vyj -= dely_rinv*factorB*massinv_j; + vzj -= delz_rinv*factorB*massinv_j; + partial_uMech += (vxj*vxj + vyj*vyj + vzj*vzj - dot4)*massinv_i; + + // Store updated velocity for j + v(j, 0) = vxj; + v(j, 1) = vyj; + v(j, 2) = vzj; + + // Compute uMech + double del_uMech = partial_uMech*mass_ij_div_neg4_ftm2v; + uMech_i += del_uMech; + uMech(j) += del_uMech; + } + } + // store updated velocity for i + v(i, 0) = vxi; + v(i, 1) = vyi; + v(i, 2) = vzi; + // store updated uMech and uCond for i + uMech(i) = uMech_i; + uCond(i) = uCond_i; + ii++; + } + + p_rand_pool->free_state(rand_gen); +} + + +template +void FixShardlowKokkos::initial_integrate(int vflag) +{ + d_numneigh = k_list->d_numneigh; + d_neighbors = k_list->d_neighbors; + d_ilist = k_list->d_ilist; + + k_list->clean_copy(); + //cleanup_copy(); + copymode = 1; + + dtsqrt = sqrt(update->dt); + + NPairSSAKokkos *np_ssa = dynamic_cast*>(list->np); + if (!np_ssa) error->one(FLERR, "NPair wasn't a NPairSSAKokkos object"); + ssa_phaseCt = np_ssa->ssa_phaseCt; + ssa_phaseLen = np_ssa->ssa_phaseLen; + ssa_itemLoc = np_ssa->ssa_itemLoc; + ssa_itemLen = np_ssa->ssa_itemLen; + ssa_gphaseCt = np_ssa->ssa_gphaseCt; + ssa_gphaseLen = np_ssa->ssa_gphaseLen; + ssa_gitemLoc = np_ssa->ssa_gitemLoc; + ssa_gitemLen = np_ssa->ssa_gitemLen; + + // process neighbors in the local AIR + for (int workPhase = 0; workPhase < ssa_phaseCt; ++workPhase) { + int workItemCt = ssa_phaseLen[workPhase]; + + if(atom->ntypes > MAX_TYPES_STACKPARAMS) { + Kokkos::parallel_for(workItemCt, KOKKOS_LAMBDA (const int workItem ) { + int ct = ssa_itemLen(workPhase, workItem); + int ii = ssa_itemLoc(workPhase, workItem); + ssa_update_dpde(ii, ct); + }); + } else { + Kokkos::parallel_for(workItemCt, KOKKOS_LAMBDA (const int workItem ) { + int ct = ssa_itemLen(workPhase, workItem); + int ii = ssa_itemLoc(workPhase, workItem); + ssa_update_dpde(ii, ct); + }); + } + } + + //Loop over all 13 outward directions (7 stages) + for (int workPhase = 0; workPhase < ssa_gphaseCt; ++workPhase) { + // int airnum = workPhase + 1; + int workItemCt = ssa_gphaseLen[workPhase]; + + // Communicate the updated velocities to all nodes + comm->forward_comm_fix(this); + + if(k_pairDPDE){ + // Zero out the ghosts' uCond & uMech to be used as delta accumulators +// memset(&(atom->uCond[nlocal]), 0, sizeof(double)*nghost); +// memset(&(atom->uMech[nlocal]), 0, sizeof(double)*nghost); + + Kokkos::parallel_for(Kokkos::RangePolicy(nlocal,nlocal+nghost), KOKKOS_LAMBDA (const int i) { + uCond(i) = 0.0; + uMech(i) = 0.0; + }); + DeviceType::fence(); + } + + // process neighbors in this AIR + if(atom->ntypes > MAX_TYPES_STACKPARAMS) { + Kokkos::parallel_for(workItemCt, KOKKOS_LAMBDA (const int workItem ) { + int ct = ssa_gitemLen(workPhase, workItem); + int ii = ssa_gitemLoc(workPhase, workItem); + ssa_update_dpde(ii, ct); + }); + } else { + Kokkos::parallel_for(workItemCt, KOKKOS_LAMBDA (const int workItem ) { + int ct = ssa_gitemLen(workPhase, workItem); + int ii = ssa_gitemLoc(workPhase, workItem); + ssa_update_dpde(ii, ct); + }); + } + + // Communicate the ghost deltas to the atom owners + comm->reverse_comm_fix(this); + + } //End Loop over all directions For airnum = Top, Top-Right, Right, Bottom-Right, Back + +} + +/* ---------------------------------------------------------------------- */ + +template +int FixShardlowKokkos::pack_forward_comm(int n, int *list, double *buf, int pbc_flag, int *pbc) +{ + int ii,jj,m; + + m = 0; + for (ii = 0; ii < n; ii++) { + jj = list[ii]; + buf[m++] = h_v(jj, 0); + buf[m++] = h_v(jj, 1); + buf[m++] = h_v(jj, 2); + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +template +void FixShardlowKokkos::unpack_forward_comm(int n, int first, double *buf) +{ + int ii,m,last; + + m = 0; + last = first + n ; + for (ii = first; ii < last; ii++) { + h_v_t0(ii - nlocal, 0) = h_v(ii, 0) = buf[m++]; + h_v_t0(ii - nlocal, 1) = h_v(ii, 1) = buf[m++]; + h_v_t0(ii - nlocal, 2) = h_v(ii, 2) = buf[m++]; + } +} + +/* ---------------------------------------------------------------------- */ + +template +int FixShardlowKokkos::pack_reverse_comm(int n, int first, double *buf) +{ + int i,m,last; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + buf[m++] = h_v(i, 0) - h_v_t0(i - nlocal, 0); + buf[m++] = h_v(i, 1) - h_v_t0(i - nlocal, 1); + buf[m++] = h_v(i, 2) - h_v_t0(i - nlocal, 2); + if(k_pairDPDE){ + buf[m++] = h_uCond(i); // for ghosts, this is an accumulated delta + buf[m++] = h_uMech(i); // for ghosts, this is an accumulated delta + } + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +template +void FixShardlowKokkos::unpack_reverse_comm(int n, int *list, double *buf) +{ + int i,j,m; + + m = 0; + for (i = 0; i < n; i++) { + j = list[i]; + + h_v(j, 0) += buf[m++]; + h_v(j, 1) += buf[m++]; + h_v(j, 2) += buf[m++]; + if(k_pairDPDE){ + h_uCond(j) += buf[m++]; // add in the accumulated delta + h_uMech(j) += buf[m++]; // add in the accumulated delta + } + } +} + +/* ---------------------------------------------------------------------- */ + +template +double FixShardlowKokkos::memory_usage() +{ + double bytes = 0.0; + bytes += sizeof(double)*3*ghostmax; // v_t0[] + return bytes; +} + +namespace LAMMPS_NS { +template class FixShardlowKokkos; +#ifdef KOKKOS_HAVE_CUDA +template class FixShardlowKokkos; +#endif +} diff --git a/src/KOKKOS/fix_shardlow_kokkos.h b/src/KOKKOS/fix_shardlow_kokkos.h new file mode 100644 index 0000000000..08d9034fdf --- /dev/null +++ b/src/KOKKOS/fix_shardlow_kokkos.h @@ -0,0 +1,154 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef FIX_CLASS + +FixStyle(shardlow/kk,FixShardlowKokkos) +FixStyle(shardlow/kk/device,FixShardlowKokkos) +FixStyle(shardlow/kk/host,FixShardlowKokkos) + +#else + +#ifndef LMP_FIX_SHARDLOW_KOKKOS_H +#define LMP_FIX_SHARDLOW_KOKKOS_H + +#include "float.h" +#include "fix_shardlow.h" +#include "kokkos_type.h" +#include "neigh_list_kokkos.h" +#include "pair_dpd_fdt_energy_kokkos.h" + +namespace LAMMPS_NS { + +template +class FixShardlowKokkos : public FixShardlow { + public: + typedef ArrayTypes AT; + NeighListKokkos *k_list; // The SSA specific neighbor list + + FixShardlowKokkos(class LAMMPS *, int, char **); + ~FixShardlowKokkos(); + int setmask(); + virtual void init(); + virtual void init_list(int, class NeighList *); + virtual void initial_integrate(int); + void setup_pre_neighbor(); + void pre_neighbor(); + + double memory_usage(); + + int pack_reverse_comm(int, int, double *); + void unpack_reverse_comm(int, int *, double *); + int pack_forward_comm(int , int *, double *, int, int *); + void unpack_forward_comm(int , int , double *); + + struct params_ssa { + KOKKOS_INLINE_FUNCTION + params_ssa(){cutinv=FLT_MAX;halfsigma=0;kappa=0;alpha=0;}; + KOKKOS_INLINE_FUNCTION + params_ssa(int i){cutinv=FLT_MAX;halfsigma=0;kappa=0;alpha=0;}; + F_FLOAT cutinv,halfsigma,kappa,alpha; + }; + + protected: +// class PairDPDfdt *pairDPD; + PairDPDfdtEnergyKokkos *k_pairDPDE; + Kokkos::Random_XorShift64_Pool *p_rand_pool; + typedef typename Kokkos::Random_XorShift64_Pool::generator_type rand_type; + + Kokkos::DualView k_params; + typename Kokkos::DualView::t_dev_const_um params; + // hardwired to space for MAX_TYPES_STACKPARAMS (12) atom types + params_ssa m_params[MAX_TYPES_STACKPARAMS+1][MAX_TYPES_STACKPARAMS+1]; + + F_FLOAT m_cutsq[MAX_TYPES_STACKPARAMS+1][MAX_TYPES_STACKPARAMS+1]; + typename ArrayTypes::t_ffloat_2d d_cutsq; + + typename DAT::tdual_v_array k_v_t0; + // typename AT::t_v_array d_v_t0; v_t0 only used in comm routines (on host) + typename HAT::t_v_array h_v_t0; + + typename AT::t_x_array x; + typename AT::t_v_array v; + typename HAT::t_v_array h_v; + typename AT::t_efloat_1d uCond, uMech; + typename HAT::t_efloat_1d h_uCond, h_uMech; + typename AT::t_int_1d type; + bool massPerI; + typename AT::t_float_1d_randomread masses; + typename AT::t_efloat_1d dpdTheta; + + double dtsqrt; // = sqrt(update->dt); + int ghostmax; + int nlocal, nghost; + + typename AT::t_neighbors_2d d_neighbors; + typename AT::t_int_1d_randomread d_ilist, d_numneigh; + + int ssa_phaseCt; + typename AT::t_int_1d ssa_phaseLen; + typename AT::t_int_2d ssa_itemLoc, ssa_itemLen; + + int ssa_gphaseCt; + typename AT::t_int_1d ssa_gphaseLen; + typename AT::t_int_2d ssa_gitemLoc, ssa_gitemLen; + + +// template +// void ssa_update_dpd(int, int); // Constant Temperature + template + void ssa_update_dpde(int, int); // Constant Energy + +}; + +} + +#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: Must use dpd/fdt pair_style with fix shardlow + +Self-explanatory. + +E: Must use pair_style dpd/fdt or dpd/fdt/energy with fix shardlow + +E: A deterministic integrator must be specified after fix shardlow in input +file (e.g. fix nve or fix nph). + +Self-explanatory. + +E: Cannot use constant temperature integration routines with DPD + +Self-explanatory. Must use deterministic integrators such as nve or nph + +E: Fix shardlow does not yet support triclinic geometries + +Self-explanatory. + +E: Shardlow algorithm requires sub-domain length > 2*(rcut+skin). Either +reduce the number of processors requested, or change the cutoff/skin + +The Shardlow splitting algorithm requires the size of the sub-domain lengths +to be are larger than twice the cutoff+skin. Generally, the domain decomposition +is dependant on the number of processors requested. + +*/ From 71379487abc7062a698e960c68a97766829bffdf Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Fri, 24 Feb 2017 17:35:58 -0500 Subject: [PATCH 157/439] USER-DPD: variety of fixes for new SSA Kokkos code. Still not functional. --- src/KOKKOS/fix_shardlow_kokkos.cpp | 1 + src/KOKKOS/nbin_ssa_kokkos.cpp | 18 ++++++++++++++++++ src/KOKKOS/npair_ssa_kokkos.cpp | 10 ++++++++-- 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/KOKKOS/fix_shardlow_kokkos.cpp b/src/KOKKOS/fix_shardlow_kokkos.cpp index 7b2810bb4c..a01cc36c3e 100644 --- a/src/KOKKOS/fix_shardlow_kokkos.cpp +++ b/src/KOKKOS/fix_shardlow_kokkos.cpp @@ -179,6 +179,7 @@ void FixShardlowKokkos::init() template void FixShardlowKokkos::init_list(int id, NeighList *ptr) { + FixShardlow::init_list(id, ptr); k_list = static_cast*>(ptr); } diff --git a/src/KOKKOS/nbin_ssa_kokkos.cpp b/src/KOKKOS/nbin_ssa_kokkos.cpp index 32a77119de..ebd07752b0 100644 --- a/src/KOKKOS/nbin_ssa_kokkos.cpp +++ b/src/KOKKOS/nbin_ssa_kokkos.cpp @@ -38,10 +38,28 @@ NBinSSAKokkos::NBinSSAKokkos(LAMMPS *lmp) : NBinStandard(lmp) atoms_per_bin = ghosts_per_gbin = 16; d_resize = typename AT::t_int_scalar("NBinSSAKokkos::d_resize"); + d_lbinxlo = typename AT::t_int_scalar("NBinSSAKokkos::d_lbinxlo"); + d_lbinylo = typename AT::t_int_scalar("NBinSSAKokkos::d_lbinylo"); + d_lbinzlo = typename AT::t_int_scalar("NBinSSAKokkos::d_lbinzlo"); + d_lbinxhi = typename AT::t_int_scalar("NBinSSAKokkos::d_lbinxhi"); + d_lbinyhi = typename AT::t_int_scalar("NBinSSAKokkos::d_lbinyhi"); + d_lbinzhi = typename AT::t_int_scalar("NBinSSAKokkos::d_lbinzhi"); #ifndef KOKKOS_USE_CUDA_UVM h_resize = Kokkos::create_mirror_view(d_resize); + h_lbinxlo = Kokkos::create_mirror_view(d_lbinxlo); + h_lbinylo = Kokkos::create_mirror_view(d_lbinylo); + h_lbinzlo = Kokkos::create_mirror_view(d_lbinzlo); + h_lbinxhi = Kokkos::create_mirror_view(d_lbinxhi); + h_lbinyhi = Kokkos::create_mirror_view(d_lbinyhi); + h_lbinzhi = Kokkos::create_mirror_view(d_lbinzhi); #else h_resize = d_resize; + h_lbinxlo = d_lbinxlo; + h_lbinylo = d_lbinylo; + h_lbinzlo = d_lbinzlo; + h_lbinxhi = d_lbinxhi; + h_lbinyhi = d_lbinyhi; + h_lbinzhi = d_lbinzhi; #endif h_resize() = 1; diff --git a/src/KOKKOS/npair_ssa_kokkos.cpp b/src/KOKKOS/npair_ssa_kokkos.cpp index c70fd0087e..f94d51197a 100644 --- a/src/KOKKOS/npair_ssa_kokkos.cpp +++ b/src/KOKKOS/npair_ssa_kokkos.cpp @@ -338,6 +338,12 @@ void NPairSSAKokkos::build(NeighList *list_) k_ssa_phaseLen.modify(); k_ssa_itemLoc.modify(); k_ssa_itemLen.modify(); + k_ssa_gphaseLen.modify(); + k_ssa_gitemLoc.modify(); + k_ssa_gitemLen.modify(); + + list->inum = data.neigh_list.inum; //FIXME once the above is in a parallel_for + list->gnum = data.neigh_list.gnum; // it will need a deep_copy or something list->k_ilist.template modify(); } @@ -450,7 +456,7 @@ void NPairSSAKokkosExecute::build_locals() //FIXME if (ssa_phaseCt != workPhase) error->one(FLERR,"ssa_phaseCt was wrong"); - neigh_list.inum = inum; //FIXME + neigh_list.inum = inum; } @@ -545,7 +551,7 @@ void NPairSSAKokkosExecute::build_ghosts() d_ssa_gitemLen(workPhase,workItem) = inum + gnum - d_ssa_gitemLoc(workPhase,workItem); if (d_ssa_gitemLen(workPhase,workItem) > 0) workItem++; } - neigh_list.gnum = gnum; //FIXME + neigh_list.gnum = gnum; } } From c56e0692b9141d1f4442b61f95a7e47d998a44dc Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Fri, 24 Feb 2017 17:38:46 -0500 Subject: [PATCH 158/439] USER-DPD Kokkos: enable install of SSA Kokkos code --- src/KOKKOS/Install.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/KOKKOS/Install.sh b/src/KOKKOS/Install.sh index ea70ae4ca1..dda1ba011b 100644 --- a/src/KOKKOS/Install.sh +++ b/src/KOKKOS/Install.sh @@ -103,6 +103,8 @@ action fix_reaxc_species_kokkos.cpp fix_reaxc_species.cpp action fix_reaxc_species_kokkos.h fix_reaxc_species.h action fix_setforce_kokkos.cpp action fix_setforce_kokkos.h +action fix_shardlow_kokkos.cpp fix_shardlow.cpp +action fix_shardlow_kokkos.h fix_shardlow.h action fix_momentum_kokkos.cpp action fix_momentum_kokkos.h action fix_wall_reflect_kokkos.cpp @@ -134,8 +136,12 @@ action npair_copy_kokkos.cpp action npair_copy_kokkos.h action npair_kokkos.cpp action npair_kokkos.h +action npair_ssa_kokkos.cpp npair_half_bin_newton_ssa.cpp +action npair_ssa_kokkos.h npair_half_bin_newton_ssa.h action nbin_kokkos.cpp action nbin_kokkos.h +action nbin_ssa_kokkos.cpp nbin_ssa.cpp +action nbin_ssa_kokkos.h nbin_ssa.h action math_special_kokkos.cpp action math_special_kokkos.h action pair_buck_coul_cut_kokkos.cpp From 6ea290a69963a9e6619c51e81f004906194870fe Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Fri, 24 Feb 2017 17:41:57 -0500 Subject: [PATCH 159/439] DEBUG: make FixShardlowKokkos have it's own rand_pool, plus debug code. ssa_update_dpde() hangs on first use of rand_gen.normal() Switching to not using a pointer to PairDPDfdtEnergyKokkos's rand_pool had no noticble effect. --- src/KOKKOS/fix_shardlow_kokkos.cpp | 37 ++++++++++++++++++++---------- src/KOKKOS/fix_shardlow_kokkos.h | 5 ++-- 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/src/KOKKOS/fix_shardlow_kokkos.cpp b/src/KOKKOS/fix_shardlow_kokkos.cpp index a01cc36c3e..fe05db6d33 100644 --- a/src/KOKKOS/fix_shardlow_kokkos.cpp +++ b/src/KOKKOS/fix_shardlow_kokkos.cpp @@ -71,7 +71,7 @@ using namespace FixConst; template FixShardlowKokkos::FixShardlowKokkos(LAMMPS *lmp, int narg, char **arg) : - FixShardlow(lmp, narg, arg), k_pairDPDE(NULL), ghostmax(0), nlocal(0) , nghost(0) + FixShardlow(lmp, narg, arg), k_pairDPDE(NULL), ghostmax(0), nlocal(0) , nghost(0), rand_pool(comm->me) { kokkosable = 1; // atomKK = (AtomKokkos *) atom; @@ -85,12 +85,12 @@ FixShardlowKokkos::FixShardlowKokkos(LAMMPS *lmp, int narg, char **a // k_pairDPD = NULL; k_pairDPDE = NULL; // k_pairDPD = (PairDPDfdtKokkos *) force->pair_match("dpd/fdt",1); - k_pairDPDE = (PairDPDfdtEnergyKokkos *) force->pair_match("dpd/fdt/energy/kk",1); + k_pairDPDE = dynamic_cast *>(force->pair_match("dpd/fdt/energy",0)); // if(k_pairDPDE){ comm_forward = 3; comm_reverse = 5; - p_rand_pool = &(k_pairDPDE->rand_pool); +// p_rand_pool = &(k_pairDPDE->rand_pool); // } else { // comm_forward = 3; // comm_reverse = 3; @@ -263,7 +263,8 @@ void FixShardlowKokkos::ssa_update_dpd( int start_ii, int count ) { - rand_type rand_gen = p_rand_pool->get_state(); + rand_type rand_gen = rand_pool.get_state(); +// rand_type rand_gen = p_rand_pool->get_state(); const double theta_ij_inv = 1.0/k_pairDPD->temperature; // independent of i,j const double boltz_inv = 1.0/force->boltz; @@ -377,7 +378,8 @@ void FixShardlowKokkos::ssa_update_dpd( v(i, 2) = vzi; } - p_rand_pool->free_state(rand_gen); +// p_rand_pool->free_state(rand_gen); + rand_pool.free_state(rand_gen); } #endif @@ -390,10 +392,13 @@ void FixShardlowKokkos::ssa_update_dpd( template template void FixShardlowKokkos::ssa_update_dpde( - int start_ii, int count + int start_ii, int count, int id ) { - rand_type rand_gen = p_rand_pool->get_state(); + rand_type rand_gen = rand_pool.get_state(); +// rand_type rand_gen = p_rand_pool->get_state(); + +//fprintf(stderr, "ssa_update_dpde(%d,%d,%d)\n", start_ii, count, id); const double boltz_inv = 1.0/force->boltz; const double ftm2v = force->ftm2v; @@ -401,6 +406,11 @@ void FixShardlowKokkos::ssa_update_dpde( int ct = count; int ii = start_ii; +// double randnum1 = rand_gen.normal(); +//fprintf(stderr, "randnum1 = %g\n", randnum1); +// double randnum2 = rand_gen.normal(); +//fprintf(stderr, "randnum2 = %g\n", randnum2); + while (ct-- > 0) { const int i = d_ilist(ii); const int jlen = d_numneigh(ii); @@ -453,6 +463,7 @@ void FixShardlowKokkos::ssa_update_dpde( double halfgamma_ij = halfsigma_ij*halfsigma_ij*boltz_inv*theta_ij_inv; double sigmaRand = halfsigma_ij*wr*dtsqrt*ftm2v * rand_gen.normal(); +// double sigmaRand = halfsigma_ij*wr*dtsqrt*ftm2v * randnum1;//rand_gen.normal(); const double mass_j = masses(massPerI ? j : jtype); double mass_ij_div_neg4_ftm2v = mass_j*mass_i_div_neg4_ftm2v; @@ -462,6 +473,7 @@ void FixShardlowKokkos::ssa_update_dpde( double kappa_ij = STACKPARAMS?m_params[itype][jtype].kappa:params(itype,jtype).kappa; double alpha_ij = STACKPARAMS?m_params[itype][jtype].alpha:params(itype,jtype).alpha; double del_uCond = alpha_ij*wr*dtsqrt * rand_gen.normal(); +// double del_uCond = alpha_ij*wr*dtsqrt * randnum2;//rand_gen.normal(); del_uCond += kappa_ij*(theta_i_inv - theta_j_inv)*wdt; uCond[j] -= del_uCond; @@ -537,7 +549,8 @@ void FixShardlowKokkos::ssa_update_dpde( ii++; } - p_rand_pool->free_state(rand_gen); + rand_pool.free_state(rand_gen); +// p_rand_pool->free_state(rand_gen); } @@ -573,13 +586,13 @@ void FixShardlowKokkos::initial_integrate(int vflag) Kokkos::parallel_for(workItemCt, KOKKOS_LAMBDA (const int workItem ) { int ct = ssa_itemLen(workPhase, workItem); int ii = ssa_itemLoc(workPhase, workItem); - ssa_update_dpde(ii, ct); + ssa_update_dpde(ii, ct, workItem); }); } else { Kokkos::parallel_for(workItemCt, KOKKOS_LAMBDA (const int workItem ) { int ct = ssa_itemLen(workPhase, workItem); int ii = ssa_itemLoc(workPhase, workItem); - ssa_update_dpde(ii, ct); + ssa_update_dpde(ii, ct, workItem); }); } } @@ -609,13 +622,13 @@ void FixShardlowKokkos::initial_integrate(int vflag) Kokkos::parallel_for(workItemCt, KOKKOS_LAMBDA (const int workItem ) { int ct = ssa_gitemLen(workPhase, workItem); int ii = ssa_gitemLoc(workPhase, workItem); - ssa_update_dpde(ii, ct); + ssa_update_dpde(ii, ct, workItem); }); } else { Kokkos::parallel_for(workItemCt, KOKKOS_LAMBDA (const int workItem ) { int ct = ssa_gitemLen(workPhase, workItem); int ii = ssa_gitemLoc(workPhase, workItem); - ssa_update_dpde(ii, ct); + ssa_update_dpde(ii, ct, workItem); }); } diff --git a/src/KOKKOS/fix_shardlow_kokkos.h b/src/KOKKOS/fix_shardlow_kokkos.h index 08d9034fdf..b4267226e6 100644 --- a/src/KOKKOS/fix_shardlow_kokkos.h +++ b/src/KOKKOS/fix_shardlow_kokkos.h @@ -63,7 +63,8 @@ class FixShardlowKokkos : public FixShardlow { protected: // class PairDPDfdt *pairDPD; PairDPDfdtEnergyKokkos *k_pairDPDE; - Kokkos::Random_XorShift64_Pool *p_rand_pool; + Kokkos::Random_XorShift64_Pool rand_pool; +// Kokkos::Random_XorShift64_Pool *p_rand_pool; typedef typename Kokkos::Random_XorShift64_Pool::generator_type rand_type; Kokkos::DualView k_params; @@ -108,7 +109,7 @@ class FixShardlowKokkos : public FixShardlow { // template // void ssa_update_dpd(int, int); // Constant Temperature template - void ssa_update_dpde(int, int); // Constant Energy + void ssa_update_dpde(int, int, int); // Constant Energy }; From c2e3a76225f421bee13b7256b8be8f1730049214 Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Fri, 24 Feb 2017 19:07:55 -0500 Subject: [PATCH 160/439] USER-DPD Kokkos: rand seed can't be zero, so add some salt. --- src/KOKKOS/fix_shardlow_kokkos.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/KOKKOS/fix_shardlow_kokkos.cpp b/src/KOKKOS/fix_shardlow_kokkos.cpp index fe05db6d33..65bb7033bb 100644 --- a/src/KOKKOS/fix_shardlow_kokkos.cpp +++ b/src/KOKKOS/fix_shardlow_kokkos.cpp @@ -71,7 +71,7 @@ using namespace FixConst; template FixShardlowKokkos::FixShardlowKokkos(LAMMPS *lmp, int narg, char **arg) : - FixShardlow(lmp, narg, arg), k_pairDPDE(NULL), ghostmax(0), nlocal(0) , nghost(0), rand_pool(comm->me) + FixShardlow(lmp, narg, arg), k_pairDPDE(NULL), ghostmax(0), nlocal(0) , nghost(0), rand_pool(1234567 + comm->me) { kokkosable = 1; // atomKK = (AtomKokkos *) atom; From b053c367ea1edd00138e68f673a8928dd9d42151 Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Fri, 24 Feb 2017 19:09:07 -0500 Subject: [PATCH 161/439] USER-DPD Kokkos: remove extranious debugging code --- src/KOKKOS/fix_shardlow_kokkos.cpp | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/KOKKOS/fix_shardlow_kokkos.cpp b/src/KOKKOS/fix_shardlow_kokkos.cpp index 65bb7033bb..1ec1455b23 100644 --- a/src/KOKKOS/fix_shardlow_kokkos.cpp +++ b/src/KOKKOS/fix_shardlow_kokkos.cpp @@ -90,11 +90,9 @@ FixShardlowKokkos::FixShardlowKokkos(LAMMPS *lmp, int narg, char **a // if(k_pairDPDE){ comm_forward = 3; comm_reverse = 5; -// p_rand_pool = &(k_pairDPDE->rand_pool); // } else { // comm_forward = 3; // comm_reverse = 3; -// p_rand_pool = &(k_pairDPD->rand_pool); // } @@ -264,7 +262,6 @@ void FixShardlowKokkos::ssa_update_dpd( ) { rand_type rand_gen = rand_pool.get_state(); -// rand_type rand_gen = p_rand_pool->get_state(); const double theta_ij_inv = 1.0/k_pairDPD->temperature; // independent of i,j const double boltz_inv = 1.0/force->boltz; @@ -378,7 +375,6 @@ void FixShardlowKokkos::ssa_update_dpd( v(i, 2) = vzi; } -// p_rand_pool->free_state(rand_gen); rand_pool.free_state(rand_gen); } #endif @@ -396,9 +392,6 @@ void FixShardlowKokkos::ssa_update_dpde( ) { rand_type rand_gen = rand_pool.get_state(); -// rand_type rand_gen = p_rand_pool->get_state(); - -//fprintf(stderr, "ssa_update_dpde(%d,%d,%d)\n", start_ii, count, id); const double boltz_inv = 1.0/force->boltz; const double ftm2v = force->ftm2v; @@ -406,11 +399,6 @@ void FixShardlowKokkos::ssa_update_dpde( int ct = count; int ii = start_ii; -// double randnum1 = rand_gen.normal(); -//fprintf(stderr, "randnum1 = %g\n", randnum1); -// double randnum2 = rand_gen.normal(); -//fprintf(stderr, "randnum2 = %g\n", randnum2); - while (ct-- > 0) { const int i = d_ilist(ii); const int jlen = d_numneigh(ii); @@ -463,7 +451,6 @@ void FixShardlowKokkos::ssa_update_dpde( double halfgamma_ij = halfsigma_ij*halfsigma_ij*boltz_inv*theta_ij_inv; double sigmaRand = halfsigma_ij*wr*dtsqrt*ftm2v * rand_gen.normal(); -// double sigmaRand = halfsigma_ij*wr*dtsqrt*ftm2v * randnum1;//rand_gen.normal(); const double mass_j = masses(massPerI ? j : jtype); double mass_ij_div_neg4_ftm2v = mass_j*mass_i_div_neg4_ftm2v; @@ -473,7 +460,6 @@ void FixShardlowKokkos::ssa_update_dpde( double kappa_ij = STACKPARAMS?m_params[itype][jtype].kappa:params(itype,jtype).kappa; double alpha_ij = STACKPARAMS?m_params[itype][jtype].alpha:params(itype,jtype).alpha; double del_uCond = alpha_ij*wr*dtsqrt * rand_gen.normal(); -// double del_uCond = alpha_ij*wr*dtsqrt * randnum2;//rand_gen.normal(); del_uCond += kappa_ij*(theta_i_inv - theta_j_inv)*wdt; uCond[j] -= del_uCond; @@ -550,7 +536,6 @@ void FixShardlowKokkos::ssa_update_dpde( } rand_pool.free_state(rand_gen); -// p_rand_pool->free_state(rand_gen); } From 21619b29768553bfcf9d31347c00904973e155d4 Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Fri, 24 Feb 2017 22:16:33 -0500 Subject: [PATCH 162/439] USER-DPD Kokkos: correct the setup of the ghost SSA workplan --- src/KOKKOS/npair_ssa_kokkos.cpp | 130 ++++++++++++++++---------------- 1 file changed, 67 insertions(+), 63 deletions(-) diff --git a/src/KOKKOS/npair_ssa_kokkos.cpp b/src/KOKKOS/npair_ssa_kokkos.cpp index f94d51197a..7eea57d492 100644 --- a/src/KOKKOS/npair_ssa_kokkos.cpp +++ b/src/KOKKOS/npair_ssa_kokkos.cpp @@ -472,84 +472,88 @@ void NPairSSAKokkosExecute::build_ghosts() // since these are ghosts, must check if stencil bin is out of bounds for (int workPhase = 0; workPhase < ssa_gphaseCt; workPhase++) { int airnum = workPhase + 1; - int workItem = 0; //FIXME for now, there is only 1 workItem for each ghost AIR - d_ssa_gitemLoc(workPhase, workItem) = inum + gnum; // record where workItem starts in ilist - for (int il = 0; il < c_gbincount(airnum); ++il) { - const int i = c_gbins(airnum, il); - n = 0; + //FIXME for now, there is only 1 workItem for each ghost AIR + int workItem; + for (workItem = 0; workItem < 1; ++workItem) { + d_ssa_gitemLoc(workPhase, workItem) = inum + gnum; // record where workItem starts in ilist + for (int il = 0; il < c_gbincount(airnum); ++il) { + const int i = c_gbins(airnum, il); + n = 0; - const AtomNeighbors neighbors_i = neigh_list.get_neighbors(inum + gnum); - 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 AtomNeighbors neighbors_i = neigh_list.get_neighbors(inum + gnum); + 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 typename ArrayTypes::t_int_1d_const_um stencil - = d_stencil; + const typename ArrayTypes::t_int_1d_const_um stencil + = d_stencil; - int loc[3]; - const int ibin = coord2bin(x(i, 0), x(i, 1), x(i, 2), &(loc[0])); + int loc[3]; + const int ibin = coord2bin(x(i, 0), x(i, 1), x(i, 2), &(loc[0])); - // loop over AIR ghost atoms in all bins in "full" stencil - // Note: the non-AIR ghost atoms have already been filtered out - for (int k = 0; k < nstencil; k++) { - int xbin2 = loc[0] + d_stencilxyz(k,0); - int ybin2 = loc[1] + d_stencilxyz(k,1); - int zbin2 = loc[2] + d_stencilxyz(k,2); - // Skip it if this bin is outside the extent of local bins - if (xbin2 < lbinxlo || xbin2 >= lbinxhi || - ybin2 < lbinylo || ybin2 >= lbinyhi || - zbin2 < lbinzlo || zbin2 >= lbinzhi) continue; - const int jbin = ibin+stencil(k); - for (int jl = 0; jl < c_bincount(jbin); ++jl) { - const int j = c_bins(jbin, jl); - const int jtype = type(j); - if(exclude && exclusion(i,j,itype,jtype)) continue; + // loop over AIR ghost atoms in all bins in "full" stencil + // Note: the non-AIR ghost atoms have already been filtered out + for (int k = 0; k < nstencil; k++) { + int xbin2 = loc[0] + d_stencilxyz(k,0); + int ybin2 = loc[1] + d_stencilxyz(k,1); + int zbin2 = loc[2] + d_stencilxyz(k,2); + // Skip it if this bin is outside the extent of local bins + if (xbin2 < lbinxlo || xbin2 >= lbinxhi || + ybin2 < lbinylo || ybin2 >= lbinyhi || + zbin2 < lbinzlo || zbin2 >= lbinzhi) continue; + const int jbin = ibin+stencil(k); + for (int jl = 0; jl < c_bincount(jbin); ++jl) { + const int j = c_bins(jbin, jl); + const int jtype = type(j); + if(exclude && exclusion(i,j,itype,jtype)) continue; - 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 X_FLOAT rsq = delx*delx + dely*dely + delz*delz; - if(rsq <= cutneighsq(itype,jtype)) { - if (molecular) { - if (!moltemplate) - which = find_special(i,j); - /* else if (imol >= 0) */ - /* which = find_special(onemols[imol]->special[iatom], */ - /* onemols[imol]->nspecial[iatom], */ - /* tag[j]-tagprev); */ - /* else which = 0; */ - if (which == 0){ - if(n= 0) */ + /* which = find_special(onemols[imol]->special[iatom], */ + /* onemols[imol]->nspecial[iatom], */ + /* tag[j]-tagprev); */ + /* else which = 0; */ + if (which == 0){ + if(n 0) { + if(n 0) { - if(n 0) { - neigh_list.d_numneigh(inum + gnum) = n; - neigh_list.d_ilist(inum + (gnum++)) = i; - if(n > neigh_list.maxneighs) { - resize() = 1; - if(n > new_maxneighs()) Kokkos::atomic_fetch_max(&new_maxneighs(),n); + if (n > 0) { + neigh_list.d_numneigh(inum + gnum) = n; + neigh_list.d_ilist(inum + (gnum++)) = i; + if(n > neigh_list.maxneighs) { + resize() = 1; + if(n > new_maxneighs()) Kokkos::atomic_fetch_max(&new_maxneighs(),n); + } } } + // record where workItem ends in ilist + d_ssa_gitemLen(workPhase,workItem) = inum + gnum - d_ssa_gitemLoc(workPhase,workItem); + // if (d_ssa_gitemLen(workPhase,workItem) > 0) workItem++; } - // record where workItem ends in ilist - d_ssa_gitemLen(workPhase,workItem) = inum + gnum - d_ssa_gitemLoc(workPhase,workItem); - if (d_ssa_gitemLen(workPhase,workItem) > 0) workItem++; + d_ssa_gphaseLen(workPhase) = workItem; } neigh_list.gnum = gnum; } From fd1523c7561e98d61b02c55f74939f5dda97cfe5 Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Fri, 24 Feb 2017 22:19:53 -0500 Subject: [PATCH 163/439] USER-DPD Kokkos: add missing () in STACKPARAMS check in ssa_update_* --- src/KOKKOS/fix_shardlow_kokkos.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/KOKKOS/fix_shardlow_kokkos.cpp b/src/KOKKOS/fix_shardlow_kokkos.cpp index 1ec1455b23..79e40dee98 100644 --- a/src/KOKKOS/fix_shardlow_kokkos.cpp +++ b/src/KOKKOS/fix_shardlow_kokkos.cpp @@ -299,7 +299,7 @@ void FixShardlowKokkos::ssa_update_dpd( const F_FLOAT rsq = delx*delx + dely*dely + delz*delz; // NOTE: r can be 0.0 in DPD systems, so do EPSILON_SQUARED test - if ((rsq < STACKPARAMS?m_cutsq[itype][jtype]:d_cutsq(itype,jtype)) + if ((rsq < (STACKPARAMS?m_cutsq[itype][jtype]:d_cutsq(itype,jtype))) && (rsq >= EPSILON_SQUARED)) { double r = sqrt(rsq); double rinv = 1.0/r; @@ -432,7 +432,7 @@ void FixShardlowKokkos::ssa_update_dpde( const F_FLOAT rsq = delx*delx + dely*dely + delz*delz; // NOTE: r can be 0.0 in DPD systems, so do EPSILON_SQUARED test - if ((rsq < STACKPARAMS?m_cutsq[itype][jtype]:d_cutsq(itype,jtype)) + if ((rsq < (STACKPARAMS?m_cutsq[itype][jtype]:d_cutsq(itype,jtype))) && (rsq >= EPSILON_SQUARED)) { double r = sqrt(rsq); double rinv = 1.0/r; From e4500859a3e2388a2b3275ae1491f28589781e00 Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Fri, 24 Feb 2017 22:24:29 -0500 Subject: [PATCH 164/439] USER-DPD: add "#ifdef DEBUG_PAIR_CT" debugging code to fix_shardlow* --- src/KOKKOS/fix_shardlow_kokkos.cpp | 61 ++++++++++++++++++++++++++++++ src/KOKKOS/fix_shardlow_kokkos.h | 7 ++++ src/USER-DPD/fix_shardlow.cpp | 53 ++++++++++++++++++++++++++ src/USER-DPD/fix_shardlow.h | 5 +++ 4 files changed, 126 insertions(+) diff --git a/src/KOKKOS/fix_shardlow_kokkos.cpp b/src/KOKKOS/fix_shardlow_kokkos.cpp index 79e40dee98..1459819430 100644 --- a/src/KOKKOS/fix_shardlow_kokkos.cpp +++ b/src/KOKKOS/fix_shardlow_kokkos.cpp @@ -99,6 +99,17 @@ FixShardlowKokkos::FixShardlowKokkos(LAMMPS *lmp, int narg, char **a if(/* k_pairDPD == NULL &&*/ k_pairDPDE == NULL) error->all(FLERR,"Must use pair_style "/*"dpd/fdt/kk or "*/"dpd/fdt/energy/kk with fix shardlow/kk"); +#ifdef DEBUG_PAIR_CT + d_counters = typename AT::t_int_2d("FixShardlowKokkos::d_counters", 2, 3); + d_hist = typename AT::t_int_1d("FixShardlowKokkos::d_hist", 32); +#ifndef KOKKOS_USE_CUDA_UVM + h_counters = Kokkos::create_mirror_view(d_counters); + h_hist = Kokkos::create_mirror_view(d_hist); +#else + h_counters = d_counters; + h_hist = d_hist; +#endif +#endif } /* ---------------------------------------------------------------------- */ @@ -297,10 +308,24 @@ void FixShardlowKokkos::ssa_update_dpd( const X_FLOAT dely = ytmp - x(j, 1); const X_FLOAT delz = ztmp - x(j, 2); const F_FLOAT rsq = delx*delx + dely*dely + delz*delz; +#ifdef DEBUG_PAIR_CT + if ((i < nlocal) && (j < nlocal)) Kokkos::atomic_increment(&(d_counters(0, 0))); + else Kokkos::atomic_increment(&(d_counters(0, 1))); + Kokkos::atomic_increment(&(d_counters(0, 2))); + int rsqi = rsq / 8; + if (rsqi < 0) rsqi = 0; + else if (rsqi > 31) rsqi = 31; + Kokkos::atomic_increment(&(d_hist(rsqi))); +#endif // NOTE: r can be 0.0 in DPD systems, so do EPSILON_SQUARED test if ((rsq < (STACKPARAMS?m_cutsq[itype][jtype]:d_cutsq(itype,jtype))) && (rsq >= EPSILON_SQUARED)) { +#ifdef DEBUG_PAIR_CT + if ((i < nlocal) && (j < nlocal)) Kokkos::atomic_increment(&(d_counters(1, 0))); + else Kokkos::atomic_increment(&(d_counters(1, 1))); + Kokkos::atomic_increment(&(d_counters(1, 2))); +#endif double r = sqrt(rsq); double rinv = 1.0/r; double delx_rinv = delx*rinv; @@ -430,10 +455,25 @@ void FixShardlowKokkos::ssa_update_dpde( const X_FLOAT dely = ytmp - x(j, 1); const X_FLOAT delz = ztmp - x(j, 2); const F_FLOAT rsq = delx*delx + dely*dely + delz*delz; +#ifdef DEBUG_PAIR_CT + if ((i < nlocal) && (j < nlocal)) Kokkos::atomic_increment(&(d_counters(0, 0))); + else Kokkos::atomic_increment(&(d_counters(0, 1))); + Kokkos::atomic_increment(&(d_counters(0, 2))); + int rsqi = rsq / 8; + if (rsqi < 0) rsqi = 0; + else if (rsqi > 31) rsqi = 31; + Kokkos::atomic_increment(&(d_hist(rsqi))); +#endif // NOTE: r can be 0.0 in DPD systems, so do EPSILON_SQUARED test if ((rsq < (STACKPARAMS?m_cutsq[itype][jtype]:d_cutsq(itype,jtype))) && (rsq >= EPSILON_SQUARED)) { +#ifdef DEBUG_PAIR_CT + if ((i < nlocal) && (j < nlocal)) Kokkos::atomic_increment(&(d_counters(1, 0))); + else Kokkos::atomic_increment(&(d_counters(1, 1))); + Kokkos::atomic_increment(&(d_counters(1, 2))); +#endif + double r = sqrt(rsq); double rinv = 1.0/r; double delx_rinv = delx*rinv; @@ -563,6 +603,15 @@ void FixShardlowKokkos::initial_integrate(int vflag) ssa_gitemLoc = np_ssa->ssa_gitemLoc; ssa_gitemLen = np_ssa->ssa_gitemLen; +#ifdef DEBUG_PAIR_CT + for (int i = 0; i < 2; ++i) + for (int j = 0; j < 3; ++j) + h_counters(i,j) = 0; + for (int i = 0; i < 32; ++i) h_hist[i] = 0; + deep_copy(d_counters, h_counters); + deep_copy(d_hist, h_hist); +#endif + // process neighbors in the local AIR for (int workPhase = 0; workPhase < ssa_phaseCt; ++workPhase) { int workItemCt = ssa_phaseLen[workPhase]; @@ -622,6 +671,18 @@ void FixShardlowKokkos::initial_integrate(int vflag) } //End Loop over all directions For airnum = Top, Top-Right, Right, Bottom-Right, Back +#ifdef DEBUG_PAIR_CT +deep_copy(h_counters, d_counters); +deep_copy(h_hist, d_hist); +for (int i = 0; i < 32; ++i) fprintf(stdout, "%8d", h_hist[i]); +fprintf(stdout, "\n%6d %6d,%6d %6d: " + ,h_counters(0, 2) + ,h_counters(1, 2) + ,h_counters(0, 1) + ,h_counters(1, 1) +); +#endif + } /* ---------------------------------------------------------------------- */ diff --git a/src/KOKKOS/fix_shardlow_kokkos.h b/src/KOKKOS/fix_shardlow_kokkos.h index b4267226e6..ddd4f5b1ba 100644 --- a/src/KOKKOS/fix_shardlow_kokkos.h +++ b/src/KOKKOS/fix_shardlow_kokkos.h @@ -60,6 +60,13 @@ class FixShardlowKokkos : public FixShardlow { F_FLOAT cutinv,halfsigma,kappa,alpha; }; +#ifdef DEBUG_PAIR_CT + typename AT::t_int_2d d_counters; + typename HAT::t_int_2d h_counters; + typename AT::t_int_1d d_hist; + typename HAT::t_int_1d h_hist; +#endif + protected: // class PairDPDfdt *pairDPD; PairDPDfdtEnergyKokkos *k_pairDPDE; diff --git a/src/USER-DPD/fix_shardlow.cpp b/src/USER-DPD/fix_shardlow.cpp index 4a7fff66cf..5132d937ea 100644 --- a/src/USER-DPD/fix_shardlow.cpp +++ b/src/USER-DPD/fix_shardlow.cpp @@ -211,6 +211,10 @@ void FixShardlow::ssa_update_dpd( const double mass_i = (rmass) ? rmass[i] : mass[itype]; const double massinv_i = 1.0 / mass_i; +#ifdef DEBUG_PAIR_CT + const int nlocal = atom->nlocal; +#endif + // Loop over Directional Neighbors only for (int jj = 0; jj < jlen; jj++) { int j = jlist[jj] & NEIGHMASK; @@ -220,9 +224,23 @@ void FixShardlow::ssa_update_dpd( double dely = ytmp - x[j][1]; double delz = ztmp - x[j][2]; double rsq = delx*delx + dely*dely + delz*delz; +#ifdef DEBUG_PAIR_CT + if ((i < nlocal) && (j < nlocal)) ++(counters[0][0]); + else ++(counters[0][1]); + ++(counters[0][2]); + int rsqi = rsq / 8; + if (rsqi < 0) rsqi = 0; + else if (rsqi > 31) rsqi = 31; + ++(hist[rsqi]); +#endif // NOTE: r can be 0.0 in DPD systems, so do EPSILON_SQUARED test if ((rsq < cut2_i[jtype]) && (rsq >= EPSILON_SQUARED)) { +#ifdef DEBUG_PAIR_CT + if ((i < nlocal) && (j < nlocal)) ++(counters[1][0]); + else ++(counters[1][1]); + ++(counters[1][2]); +#endif double r = sqrt(rsq); double rinv = 1.0/r; double delx_rinv = delx*rinv; @@ -350,6 +368,10 @@ void FixShardlow::ssa_update_dpde( const double massinv_i = 1.0 / mass_i; const double mass_i_div_neg4_ftm2v = mass_i*(-0.25)/ftm2v; +#ifdef DEBUG_PAIR_CT + const int nlocal = atom->nlocal; +#endif + // Loop over Directional Neighbors only for (int jj = 0; jj < jlen; jj++) { int j = jlist[jj] & NEIGHMASK; @@ -359,9 +381,23 @@ void FixShardlow::ssa_update_dpde( double dely = ytmp - x[j][1]; double delz = ztmp - x[j][2]; double rsq = delx*delx + dely*dely + delz*delz; +#ifdef DEBUG_PAIR_CT + if ((i < nlocal) && (j < nlocal)) ++(counters[0][0]); + else ++(counters[0][1]); + ++(counters[0][2]); + int rsqi = rsq / 8; + if (rsqi < 0) rsqi = 0; + else if (rsqi > 31) rsqi = 31; + ++(hist[rsqi]); +#endif // NOTE: r can be 0.0 in DPD systems, so do EPSILON_SQUARED test if ((rsq < cut2_i[jtype]) && (rsq >= EPSILON_SQUARED)) { +#ifdef DEBUG_PAIR_CT + if ((i < nlocal) && (j < nlocal)) ++(counters[1][0]); + else ++(counters[1][1]); + ++(counters[1][2]); +#endif double r = sqrt(rsq); double rinv = 1.0/r; double delx_rinv = delx*rinv; @@ -493,6 +529,13 @@ void FixShardlow::initial_integrate(int vflag) error->one(FLERR, msg); } +#ifdef DEBUG_PAIR_CT + for (int i = 0; i < 2; ++i) + for (int j = 0; j < 3; ++j) + counters[i][j] = 0; + for (int i = 0; i < 32; ++i) hist[i] = 0; +#endif + // Allocate memory for v_t0 to hold the initial velocities for the ghosts v_t0 = (double (*)[3]) memory->smalloc(sizeof(double)*3*nghost, "FixShardlow:v_t0"); @@ -554,6 +597,16 @@ void FixShardlow::initial_integrate(int vflag) } //End Loop over all directions For airnum = Top, Top-Right, Right, Bottom-Right, Back +#ifdef DEBUG_PAIR_CT +for (int i = 0; i < 32; ++i) fprintf(stdout, "%8d", hist[i]); +fprintf(stdout, "\n%6d %6d,%6d %6d: " + ,counters[0][2] + ,counters[1][2] + ,counters[0][1] + ,counters[1][1] +); +#endif + memory->sfree(v_t0); v_t0 = NULL; } diff --git a/src/USER-DPD/fix_shardlow.h b/src/USER-DPD/fix_shardlow.h index 6fd438b8f0..e87ae3c9cf 100644 --- a/src/USER-DPD/fix_shardlow.h +++ b/src/USER-DPD/fix_shardlow.h @@ -38,6 +38,11 @@ class FixShardlow : public Fix { double memory_usage(); +#ifdef DEBUG_PAIR_CT + int counters[2][3]; + int hist[32]; +#endif + protected: int pack_reverse_comm(int, int, double *); void unpack_reverse_comm(int, int *, double *); From 35ee24cfad501b694ceba49b7104100101d0a5cb Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Sun, 26 Feb 2017 14:50:58 -0500 Subject: [PATCH 165/439] use RandWrap in pair_dpd_fdt_energy_kokkos and fix_shardlow_kokkos --- src/KOKKOS/fix_shardlow_kokkos.cpp | 25 ++++++++++++++++++----- src/KOKKOS/fix_shardlow_kokkos.h | 8 ++++++-- src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp | 6 +++--- src/KOKKOS/pair_dpd_fdt_energy_kokkos.h | 8 ++++---- 4 files changed, 33 insertions(+), 14 deletions(-) diff --git a/src/KOKKOS/fix_shardlow_kokkos.cpp b/src/KOKKOS/fix_shardlow_kokkos.cpp index 1459819430..e82991bcba 100644 --- a/src/KOKKOS/fix_shardlow_kokkos.cpp +++ b/src/KOKKOS/fix_shardlow_kokkos.cpp @@ -71,7 +71,7 @@ using namespace FixConst; template FixShardlowKokkos::FixShardlowKokkos(LAMMPS *lmp, int narg, char **arg) : - FixShardlow(lmp, narg, arg), k_pairDPDE(NULL), ghostmax(0), nlocal(0) , nghost(0), rand_pool(1234567 + comm->me) + FixShardlow(lmp, narg, arg), k_pairDPDE(NULL), ghostmax(0), nlocal(0) , nghost(0) { kokkosable = 1; // atomKK = (AtomKokkos *) atom; @@ -90,6 +90,7 @@ FixShardlowKokkos::FixShardlowKokkos(LAMMPS *lmp, int narg, char **a // if(k_pairDPDE){ comm_forward = 3; comm_reverse = 5; + p_rand_pool = &(k_pairDPDE->rand_pool); // } else { // comm_forward = 3; // comm_reverse = 3; @@ -272,7 +273,7 @@ void FixShardlowKokkos::ssa_update_dpd( int start_ii, int count ) { - rand_type rand_gen = rand_pool.get_state(); + rand_type rand_gen = p_rand_pool->get_state(); const double theta_ij_inv = 1.0/k_pairDPD->temperature; // independent of i,j const double boltz_inv = 1.0/force->boltz; @@ -400,7 +401,7 @@ void FixShardlowKokkos::ssa_update_dpd( v(i, 2) = vzi; } - rand_pool.free_state(rand_gen); + p_rand_pool->free_state(rand_gen); } #endif @@ -416,7 +417,11 @@ void FixShardlowKokkos::ssa_update_dpde( int start_ii, int count, int id ) { - rand_type rand_gen = rand_pool.get_state(); +#ifdef USE_RAND_MARS + class RanMars *pRNG = k_pairDPDE->random; +#else + rand_type rand_gen = p_rand_pool->get_state(); +#endif const double boltz_inv = 1.0/force->boltz; const double ftm2v = force->ftm2v; @@ -490,7 +495,11 @@ void FixShardlowKokkos::ssa_update_dpde( double halfsigma_ij = STACKPARAMS?m_params[itype][jtype].halfsigma:params(itype,jtype).halfsigma; double halfgamma_ij = halfsigma_ij*halfsigma_ij*boltz_inv*theta_ij_inv; +#ifdef USE_RAND_MARS + double sigmaRand = halfsigma_ij*wr*dtsqrt*ftm2v * pRNG->gaussian(); +#else double sigmaRand = halfsigma_ij*wr*dtsqrt*ftm2v * rand_gen.normal(); +#endif const double mass_j = masses(massPerI ? j : jtype); double mass_ij_div_neg4_ftm2v = mass_j*mass_i_div_neg4_ftm2v; @@ -499,7 +508,11 @@ void FixShardlowKokkos::ssa_update_dpde( // Compute uCond double kappa_ij = STACKPARAMS?m_params[itype][jtype].kappa:params(itype,jtype).kappa; double alpha_ij = STACKPARAMS?m_params[itype][jtype].alpha:params(itype,jtype).alpha; +#ifdef USE_RAND_MARS + double del_uCond = alpha_ij*wr*dtsqrt * pRNG->gaussian(); +#else double del_uCond = alpha_ij*wr*dtsqrt * rand_gen.normal(); +#endif del_uCond += kappa_ij*(theta_i_inv - theta_j_inv)*wdt; uCond[j] -= del_uCond; @@ -575,7 +588,9 @@ void FixShardlowKokkos::ssa_update_dpde( ii++; } - rand_pool.free_state(rand_gen); +#ifndef USE_RAND_MARS + p_rand_pool->free_state(rand_gen); +#endif } diff --git a/src/KOKKOS/fix_shardlow_kokkos.h b/src/KOKKOS/fix_shardlow_kokkos.h index ddd4f5b1ba..f71ca1ce11 100644 --- a/src/KOKKOS/fix_shardlow_kokkos.h +++ b/src/KOKKOS/fix_shardlow_kokkos.h @@ -70,9 +70,13 @@ class FixShardlowKokkos : public FixShardlow { protected: // class PairDPDfdt *pairDPD; PairDPDfdtEnergyKokkos *k_pairDPDE; - Kokkos::Random_XorShift64_Pool rand_pool; // Kokkos::Random_XorShift64_Pool *p_rand_pool; - typedef typename Kokkos::Random_XorShift64_Pool::generator_type rand_type; + +// Kokkos::Random_XorShift64_Pool rand_pool; +// typedef typename Kokkos::Random_XorShift64_Pool::generator_type rand_type; + + RandPoolWrap *p_rand_pool; + typedef RandWrap rand_type; Kokkos::DualView k_params; typename Kokkos::DualView PairDPDfdtEnergyKokkos::PairDPDfdtEnergyKokkos(LAMMPS *lmp) : - PairDPDfdtEnergy(lmp),rand_pool(seed + comm->me /** , lmp/**/) + PairDPDfdtEnergy(lmp),rand_pool(12345 /* not actually used, seed + comm->me */, lmp) { atomKK = (AtomKokkos *) atom; execution_space = ExecutionSpaceFromDevice::space; @@ -68,7 +68,7 @@ PairDPDfdtEnergyKokkos::~PairDPDfdtEnergyKokkos() memory->destroy_kokkos(k_cutsq,cutsq); - /** rand_pool.destroy();/**/ + rand_pool.destroy(); } /* ---------------------------------------------------------------------- @@ -101,7 +101,7 @@ void PairDPDfdtEnergyKokkos::init_style() error->all(FLERR,"Cannot use chosen neighbor list style with reax/c/kk"); } - /** rand_pool.init(random,seed);/**/ + rand_pool.init(random,seed); } /* ---------------------------------------------------------------------- */ diff --git a/src/KOKKOS/pair_dpd_fdt_energy_kokkos.h b/src/KOKKOS/pair_dpd_fdt_energy_kokkos.h index deb264c37e..e065d71d3e 100644 --- a/src/KOKKOS/pair_dpd_fdt_energy_kokkos.h +++ b/src/KOKKOS/pair_dpd_fdt_energy_kokkos.h @@ -89,11 +89,11 @@ class PairDPDfdtEnergyKokkos : public PairDPDfdtEnergy { DAT::tdual_efloat_1d k_duCond,k_duMech; - Kokkos::Random_XorShift64_Pool rand_pool; - typedef typename Kokkos::Random_XorShift64_Pool::generator_type rand_type; + // Kokkos::Random_XorShift64_Pool rand_pool; + // typedef typename Kokkos::Random_XorShift64_Pool::generator_type rand_type; - // RandPoolWrap rand_pool; - // typedef RandWrap rand_type; + RandPoolWrap rand_pool; + typedef RandWrap rand_type; typename ArrayTypes::tdual_ffloat_2d k_cutsq; typename ArrayTypes::t_ffloat_2d d_cutsq; From e4b544f934bd816a31759b654f3c26c9ecf36ebd Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Sun, 26 Feb 2017 17:53:45 -0500 Subject: [PATCH 166/439] Make pair_dpd_fdt_energy's random seed public so fix_shardlow can use it. --- src/USER-DPD/pair_dpd_fdt_energy.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/USER-DPD/pair_dpd_fdt_energy.h b/src/USER-DPD/pair_dpd_fdt_energy.h index f8303d4854..dce39f83f0 100644 --- a/src/USER-DPD/pair_dpd_fdt_energy.h +++ b/src/USER-DPD/pair_dpd_fdt_energy.h @@ -46,11 +46,11 @@ class PairDPDfdtEnergy : public Pair { double **sigma,**kappa; double *duCond,*duMech; + int seed; class RanMars *random; protected: double cut_global; - int seed; bool splitFDT_flag; bool a0_is_zero; From 3eba3e5a1b756e4a125e0f88201a2c54399e42ce Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Sun, 26 Feb 2017 17:57:13 -0500 Subject: [PATCH 167/439] USER-DPD Kokkos: for deterministic results, serialize bin_atoms() for now. --- src/KOKKOS/nbin_ssa_kokkos.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/KOKKOS/nbin_ssa_kokkos.cpp b/src/KOKKOS/nbin_ssa_kokkos.cpp index ebd07752b0..98ec638be9 100644 --- a/src/KOKKOS/nbin_ssa_kokkos.cpp +++ b/src/KOKKOS/nbin_ssa_kokkos.cpp @@ -140,7 +140,7 @@ void NBinSSAKokkos::bin_atoms() subhi_[1] = domain->subhi[1]; subhi_[2] = domain->subhi[2]; - Kokkos::parallel_for(Kokkos::RangePolicy(atom->nlocal,atom->nlocal+atom->nghost), KOKKOS_LAMBDA (const int i) { + Kokkos::parallel_for(Kokkos::RangePolicy(atom->nlocal,atom->nlocal+atom->nghost), KOKKOS_LAMBDA (const int i) { const int iAIR = coord2ssaAIR(x(i, 0), x(i, 1), x(i, 2)); if (iAIR > 0) { // include only ghost atoms in an AIR const int ac = Kokkos::atomic_fetch_add(&gbincount[iAIR], (int)1); @@ -188,7 +188,7 @@ void NBinSSAKokkos::bin_atoms() NPairSSAKokkosBinAtomsFunctor f(*this); - Kokkos::parallel_for(atom->nlocal, f); + Kokkos::parallel_for(Kokkos::RangePolicy(0, atom->nlocal), f); DeviceType::fence(); deep_copy(h_resize, d_resize); From a5507b291d3d78d93136053d530f8be51d57728c Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Sun, 26 Feb 2017 18:00:20 -0500 Subject: [PATCH 168/439] USER-DPD Kokkos: give each workItem index a unique instance of RanMars Makes fix_shardlow_kokkos deterministic across runs and thread count. --- src/KOKKOS/fix_shardlow_kokkos.cpp | 27 ++++++++++++++++++++++++++- src/KOKKOS/fix_shardlow_kokkos.h | 6 ++++-- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/src/KOKKOS/fix_shardlow_kokkos.cpp b/src/KOKKOS/fix_shardlow_kokkos.cpp index e82991bcba..a5e02f3dd8 100644 --- a/src/KOKKOS/fix_shardlow_kokkos.cpp +++ b/src/KOKKOS/fix_shardlow_kokkos.cpp @@ -90,7 +90,12 @@ FixShardlowKokkos::FixShardlowKokkos(LAMMPS *lmp, int narg, char **a // if(k_pairDPDE){ comm_forward = 3; comm_reverse = 5; +#ifdef USE_RAND_MARS + maxRNG = 0; + pp_random = NULL; +#else p_rand_pool = &(k_pairDPDE->rand_pool); +#endif // } else { // comm_forward = 3; // comm_reverse = 3; @@ -119,6 +124,11 @@ template FixShardlowKokkos::~FixShardlowKokkos() { ghostmax = 0; + if (pp_random) { + for (int i = 1; i < maxRNG; ++i) delete pp_random[i]; + delete[] pp_random; + pp_random = NULL; + } } /* ---------------------------------------------------------------------- */ @@ -418,7 +428,7 @@ void FixShardlowKokkos::ssa_update_dpde( ) { #ifdef USE_RAND_MARS - class RanMars *pRNG = k_pairDPDE->random; + class RanMars *pRNG = pp_random[id]; #else rand_type rand_gen = p_rand_pool->get_state(); #endif @@ -618,6 +628,21 @@ void FixShardlowKokkos::initial_integrate(int vflag) ssa_gitemLoc = np_ssa->ssa_gitemLoc; ssa_gitemLen = np_ssa->ssa_gitemLen; + int maxWorkItemCt = (int) ssa_itemLoc.dimension_1(); + if (maxWorkItemCt > maxRNG) { + if (pp_random) { + for (int i = 1; i < maxRNG; ++i) delete pp_random[i]; + delete[] pp_random; + pp_random = NULL; + } + maxRNG = maxWorkItemCt; + pp_random = new RanMars*[maxRNG]; + for (int i = 1; i < maxRNG; ++i) { + pp_random[i] = new RanMars(lmp, k_pairDPDE->seed + comm->me + comm->nprocs*i); + } + pp_random[0] = k_pairDPDE->random; + } + #ifdef DEBUG_PAIR_CT for (int i = 0; i < 2; ++i) for (int j = 0; j < 3; ++j) diff --git a/src/KOKKOS/fix_shardlow_kokkos.h b/src/KOKKOS/fix_shardlow_kokkos.h index f71ca1ce11..95e8add64a 100644 --- a/src/KOKKOS/fix_shardlow_kokkos.h +++ b/src/KOKKOS/fix_shardlow_kokkos.h @@ -75,8 +75,10 @@ class FixShardlowKokkos : public FixShardlow { // Kokkos::Random_XorShift64_Pool rand_pool; // typedef typename Kokkos::Random_XorShift64_Pool::generator_type rand_type; - RandPoolWrap *p_rand_pool; - typedef RandWrap rand_type; +// RandPoolWrap *p_rand_pool; +// typedef RandWrap rand_type; + int maxRNG; + class RanMars **pp_random; Kokkos::DualView k_params; typename Kokkos::DualView Date: Tue, 28 Feb 2017 12:49:11 -0500 Subject: [PATCH 169/439] USER-DPD Kokkos: Add "#ifdef DPD_USE_RAN_MARS" toggle Also, initialize the rand_pool with a seed in init_style() --- src/KOKKOS/fix_shardlow_kokkos.cpp | 14 ++++++++----- src/KOKKOS/fix_shardlow_kokkos.h | 11 +++++------ src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp | 13 +++++++++++- src/KOKKOS/pair_dpd_fdt_energy_kokkos.h | 24 +++++++++++++++++++---- 4 files changed, 46 insertions(+), 16 deletions(-) diff --git a/src/KOKKOS/fix_shardlow_kokkos.cpp b/src/KOKKOS/fix_shardlow_kokkos.cpp index a5e02f3dd8..9bac6250da 100644 --- a/src/KOKKOS/fix_shardlow_kokkos.cpp +++ b/src/KOKKOS/fix_shardlow_kokkos.cpp @@ -90,7 +90,7 @@ FixShardlowKokkos::FixShardlowKokkos(LAMMPS *lmp, int narg, char **a // if(k_pairDPDE){ comm_forward = 3; comm_reverse = 5; -#ifdef USE_RAND_MARS +#ifdef DPD_USE_RAN_MARS maxRNG = 0; pp_random = NULL; #else @@ -124,11 +124,13 @@ template FixShardlowKokkos::~FixShardlowKokkos() { ghostmax = 0; +#ifdef DPD_USE_RAN_MARS if (pp_random) { for (int i = 1; i < maxRNG; ++i) delete pp_random[i]; delete[] pp_random; pp_random = NULL; } +#endif } /* ---------------------------------------------------------------------- */ @@ -427,7 +429,7 @@ void FixShardlowKokkos::ssa_update_dpde( int start_ii, int count, int id ) { -#ifdef USE_RAND_MARS +#ifdef DPD_USE_RAN_MARS class RanMars *pRNG = pp_random[id]; #else rand_type rand_gen = p_rand_pool->get_state(); @@ -505,7 +507,7 @@ void FixShardlowKokkos::ssa_update_dpde( double halfsigma_ij = STACKPARAMS?m_params[itype][jtype].halfsigma:params(itype,jtype).halfsigma; double halfgamma_ij = halfsigma_ij*halfsigma_ij*boltz_inv*theta_ij_inv; -#ifdef USE_RAND_MARS +#ifdef DPD_USE_RAN_MARS double sigmaRand = halfsigma_ij*wr*dtsqrt*ftm2v * pRNG->gaussian(); #else double sigmaRand = halfsigma_ij*wr*dtsqrt*ftm2v * rand_gen.normal(); @@ -518,7 +520,7 @@ void FixShardlowKokkos::ssa_update_dpde( // Compute uCond double kappa_ij = STACKPARAMS?m_params[itype][jtype].kappa:params(itype,jtype).kappa; double alpha_ij = STACKPARAMS?m_params[itype][jtype].alpha:params(itype,jtype).alpha; -#ifdef USE_RAND_MARS +#ifdef DPD_USE_RAN_MARS double del_uCond = alpha_ij*wr*dtsqrt * pRNG->gaussian(); #else double del_uCond = alpha_ij*wr*dtsqrt * rand_gen.normal(); @@ -598,7 +600,7 @@ void FixShardlowKokkos::ssa_update_dpde( ii++; } -#ifndef USE_RAND_MARS +#ifndef DPD_USE_RAN_MARS p_rand_pool->free_state(rand_gen); #endif } @@ -628,6 +630,7 @@ void FixShardlowKokkos::initial_integrate(int vflag) ssa_gitemLoc = np_ssa->ssa_gitemLoc; ssa_gitemLen = np_ssa->ssa_gitemLen; +#ifdef DPD_USE_RAN_MARS int maxWorkItemCt = (int) ssa_itemLoc.dimension_1(); if (maxWorkItemCt > maxRNG) { if (pp_random) { @@ -642,6 +645,7 @@ void FixShardlowKokkos::initial_integrate(int vflag) } pp_random[0] = k_pairDPDE->random; } +#endif #ifdef DEBUG_PAIR_CT for (int i = 0; i < 2; ++i) diff --git a/src/KOKKOS/fix_shardlow_kokkos.h b/src/KOKKOS/fix_shardlow_kokkos.h index 95e8add64a..011c16dc60 100644 --- a/src/KOKKOS/fix_shardlow_kokkos.h +++ b/src/KOKKOS/fix_shardlow_kokkos.h @@ -70,15 +70,14 @@ class FixShardlowKokkos : public FixShardlow { protected: // class PairDPDfdt *pairDPD; PairDPDfdtEnergyKokkos *k_pairDPDE; -// Kokkos::Random_XorShift64_Pool *p_rand_pool; -// Kokkos::Random_XorShift64_Pool rand_pool; -// typedef typename Kokkos::Random_XorShift64_Pool::generator_type rand_type; - -// RandPoolWrap *p_rand_pool; -// typedef RandWrap rand_type; +#ifdef DPD_USE_RAN_MARS int maxRNG; class RanMars **pp_random; +#else + Kokkos::Random_XorShift64_Pool *p_rand_pool; + typedef typename Kokkos::Random_XorShift64_Pool::generator_type rand_type; +#endif Kokkos::DualView k_params; typename Kokkos::DualView PairDPDfdtEnergyKokkos::PairDPDfdtEnergyKokkos(LAMMPS *lmp) : - PairDPDfdtEnergy(lmp),rand_pool(12345 /* not actually used, seed + comm->me */, lmp) + PairDPDfdtEnergy(lmp), +#ifdef DPD_USE_RAN_MARS + rand_pool(0 /* unused */, lmp) +#else + rand_pool() +#endif { atomKK = (AtomKokkos *) atom; execution_space = ExecutionSpaceFromDevice::space; @@ -68,7 +73,9 @@ PairDPDfdtEnergyKokkos::~PairDPDfdtEnergyKokkos() memory->destroy_kokkos(k_cutsq,cutsq); +#ifdef DPD_USE_RAN_MARS rand_pool.destroy(); +#endif } /* ---------------------------------------------------------------------- @@ -101,7 +108,11 @@ void PairDPDfdtEnergyKokkos::init_style() error->all(FLERR,"Cannot use chosen neighbor list style with reax/c/kk"); } +#ifdef DPD_USE_RAN_MARS rand_pool.init(random,seed); +#else + rand_pool.init(seed + comm->me,DeviceType::max_hardware_threads()); +#endif } /* ---------------------------------------------------------------------- */ diff --git a/src/KOKKOS/pair_dpd_fdt_energy_kokkos.h b/src/KOKKOS/pair_dpd_fdt_energy_kokkos.h index e065d71d3e..a32539242a 100644 --- a/src/KOKKOS/pair_dpd_fdt_energy_kokkos.h +++ b/src/KOKKOS/pair_dpd_fdt_energy_kokkos.h @@ -22,11 +22,25 @@ PairStyle(dpd/fdt/energy/kk/host,PairDPDfdtEnergyKokkos) #ifndef LMP_PAIR_DPD_FDT_ENERGY_KOKKOS_H #define LMP_PAIR_DPD_FDT_ENERGY_KOKKOS_H + +#ifndef ALLOW_NON_DETERMINISTIC_DPD +#ifdef KOKKOS_HAVE_CUDA +//FIXME print some warning +#endif +#ifndef DPD_USE_RAN_MARS +#define DPD_USE_RAN_MARS +#endif +#endif + + #include "pair_dpd_fdt_energy.h" #include "pair_kokkos.h" #include "kokkos_type.h" -#include "Kokkos_Random.hpp" +#ifdef DPD_USE_RAN_MARS #include "rand_pool_wrap_kokkos.h" +#else +#include "Kokkos_Random.hpp" +#endif namespace LAMMPS_NS { @@ -89,11 +103,13 @@ class PairDPDfdtEnergyKokkos : public PairDPDfdtEnergy { DAT::tdual_efloat_1d k_duCond,k_duMech; - // Kokkos::Random_XorShift64_Pool rand_pool; - // typedef typename Kokkos::Random_XorShift64_Pool::generator_type rand_type; - +#ifdef DPD_USE_RAN_MARS RandPoolWrap rand_pool; typedef RandWrap rand_type; +#else + Kokkos::Random_XorShift64_Pool rand_pool; + typedef typename Kokkos::Random_XorShift64_Pool::generator_type rand_type; +#endif typename ArrayTypes::tdual_ffloat_2d k_cutsq; typename ArrayTypes::t_ffloat_2d d_cutsq; From b26a434a502d953b3b7fd2772a4bbc5a5091f468 Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Tue, 28 Feb 2017 12:53:56 -0500 Subject: [PATCH 170/439] USER-DPD Kokkos: Add "#ifdef ALLOW_NON_DETERMINISTIC_SSA" toggle SSA atom binning algorithm was adjusted to do as much work in parallel while preserving deterministic behavior. The final step is done serially to preserve deterministic behavior. An alternative would be to sort the contents of the bins so that they are always in the same order. --- src/KOKKOS/nbin_ssa_kokkos.cpp | 189 +++++++++++++++++++-------------- src/KOKKOS/nbin_ssa_kokkos.h | 65 ++++++++++++ 2 files changed, 172 insertions(+), 82 deletions(-) diff --git a/src/KOKKOS/nbin_ssa_kokkos.cpp b/src/KOKKOS/nbin_ssa_kokkos.cpp index 98ec638be9..53f3f2fc80 100644 --- a/src/KOKKOS/nbin_ssa_kokkos.cpp +++ b/src/KOKKOS/nbin_ssa_kokkos.cpp @@ -115,89 +115,31 @@ void NBinSSAKokkos::bin_atoms() last_bin = update->ntimestep; int i; + int nlocal = atom->nlocal; + int nghost = atom->nghost; + int nall = nlocal + nghost; - // bin the ghost atoms - h_resize() = 1; - while(h_resize() > 0) { - h_resize() = 0; - deep_copy(d_resize, h_resize); + atomKK->sync(ExecutionSpaceFromDevice::space,X_MASK); + x = atomKK->k_x.view(); - for (int i = 0; i < 8; i++) { - k_gbincount.h_view(i) = 0; - } - k_gbincount.modify(); - k_gbincount.sync(); - DeviceType::fence(); // FIXME? + sublo_[0] = domain->sublo[0]; + sublo_[1] = domain->sublo[1]; + sublo_[2] = domain->sublo[2]; + subhi_[0] = domain->subhi[0]; + subhi_[1] = domain->subhi[1]; + subhi_[2] = domain->subhi[2]; - atomKK->sync(ExecutionSpaceFromDevice::space,X_MASK); - x = atomKK->k_x.view(); + bboxlo_[0] = bboxlo[0]; bboxlo_[1] = bboxlo[1]; bboxlo_[2] = bboxlo[2]; + bboxhi_[0] = bboxhi[0]; bboxhi_[1] = bboxhi[1]; bboxhi_[2] = bboxhi[2]; - // I don't think these two lines need to be repeated here... - TIM 20170216 - sublo_[0] = domain->sublo[0]; - sublo_[1] = domain->sublo[1]; - sublo_[2] = domain->sublo[2]; - subhi_[0] = domain->subhi[0]; - subhi_[1] = domain->subhi[1]; - subhi_[2] = domain->subhi[2]; + k_binID = DAT::tdual_int_1d("NBinSSAKokkos::binID",nall); + binID = k_binID.view(); - Kokkos::parallel_for(Kokkos::RangePolicy(atom->nlocal,atom->nlocal+atom->nghost), KOKKOS_LAMBDA (const int i) { - const int iAIR = coord2ssaAIR(x(i, 0), x(i, 1), x(i, 2)); - if (iAIR > 0) { // include only ghost atoms in an AIR - const int ac = Kokkos::atomic_fetch_add(&gbincount[iAIR], (int)1); - if(ac < (int) gbins.dimension_1()) { - gbins(iAIR, ac) = i; - } else { - d_resize() = 1; - } - } - }); - DeviceType::fence(); - - deep_copy(h_resize, d_resize); - if(h_resize()) { - k_gbincount.modify(); - k_gbincount.sync(); - for (i = 1; i < 8; i++) { - if (k_gbincount.h_view(i) > ghosts_per_gbin) { - ghosts_per_gbin = k_gbincount.h_view(i); - } - } - k_gbins = DAT::tdual_int_2d("gbins", 8, ghosts_per_gbin); - gbins = k_gbins.view(); - } - } - c_gbins = gbins; // gbins won't change until the next bin_atoms - - // bin the local atoms - h_resize() = 1; - while(h_resize() > 0) { - h_resize() = 0; - deep_copy(d_resize, h_resize); - - MemsetZeroFunctor f_zero; - f_zero.ptr = (void*) k_bincount.view().ptr_on_device(); - Kokkos::parallel_for(mbins, f_zero); - DeviceType::fence(); - - atomKK->sync(ExecutionSpaceFromDevice::space,X_MASK); - x = atomKK->k_x.view(); - - // I don't think these two lines need to be repeated here... - TIM 20170216 - bboxlo_[0] = bboxlo[0]; bboxlo_[1] = bboxlo[1]; bboxlo_[2] = bboxlo[2]; - bboxhi_[0] = bboxhi[0]; bboxhi_[1] = bboxhi[1]; bboxhi_[2] = bboxhi[2]; - - NPairSSAKokkosBinAtomsFunctor f(*this); - - Kokkos::parallel_for(Kokkos::RangePolicy(0, atom->nlocal), f); - DeviceType::fence(); - - deep_copy(h_resize, d_resize); - if(h_resize()) { - - atoms_per_bin += 16; - k_bins = DAT::tdual_int_2d("bins", mbins, atoms_per_bin); - bins = k_bins.view(); - } + // find each local atom's binID + { + atoms_per_bin = 0; + NPairSSAKokkosBinIDAtomsFunctor f(*this); + Kokkos::parallel_reduce(nlocal, f, atoms_per_bin); } deep_copy(h_lbinxlo, d_lbinxlo); deep_copy(h_lbinylo, d_lbinylo); @@ -205,7 +147,72 @@ void NBinSSAKokkos::bin_atoms() deep_copy(h_lbinxhi, d_lbinxhi); deep_copy(h_lbinyhi, d_lbinyhi); deep_copy(h_lbinzhi, d_lbinzhi); + + // find each ghost's binID (AIR number) + { + for (int i = 0; i < 8; i++) k_gbincount.h_view(i) = 0; + k_gbincount.modify(); + k_gbincount.sync(); + DeviceType::fence(); // FIXME? + ghosts_per_gbin = 0; + NPairSSAKokkosBinIDGhostsFunctor f(*this); + Kokkos::parallel_reduce(Kokkos::RangePolicy(nlocal,nall), f, ghosts_per_gbin); + } + + // actually bin the ghost atoms + { + if(ghosts_per_gbin > (int) gbins.dimension_1()) { + k_gbins = DAT::tdual_int_2d("gbins", 8, ghosts_per_gbin); + gbins = k_gbins.view(); + } + for (int i = 0; i < 8; i++) k_gbincount.h_view(i) = 0; + k_gbincount.modify(); + k_gbincount.sync(); + DeviceType::fence(); // FIXME? + + Kokkos::parallel_for( +#ifdef ALLOW_NON_DETERMINISTIC_SSA + Kokkos::RangePolicy(nlocal,nall) +#else + Kokkos::RangePolicy(nlocal,nall) +#endif + , KOKKOS_LAMBDA (const int i) { + const int iAIR = binID(i); + if (iAIR > 0) { // include only ghost atoms in an AIR + const int ac = Kokkos::atomic_fetch_add(&gbincount[iAIR], (int)1); + gbins(iAIR, ac) = i; + } + }); + DeviceType::fence(); + } + c_gbins = gbins; // gbins won't change until the next bin_atoms + + // actually bin the local atoms + { + if ((mbins > (int) bins.dimension_0()) || + (atoms_per_bin > (int) bins.dimension_1())) { + k_bins = DAT::tdual_int_2d("bins", mbins, atoms_per_bin); + bins = k_bins.view(); + } + MemsetZeroFunctor f_zero; + f_zero.ptr = (void*) k_bincount.view().ptr_on_device(); + Kokkos::parallel_for(mbins, f_zero); + DeviceType::fence(); + + NPairSSAKokkosBinAtomsFunctor f(*this); +#ifdef ALLOW_NON_DETERMINISTIC_SSA + Kokkos::parallel_for(nlocal, f); +#else + Kokkos::parallel_for(Kokkos::RangePolicy(0, nlocal), f); +#endif + DeviceType::fence(); + + } c_bins = bins; // bins won't change until the next bin_atoms + +//now dispose of the k_binID array + k_binID = DAT::tdual_int_1d("NBinSSAKokkos::binID",0); + binID = k_binID.view(); } /* ---------------------------------------------------------------------- */ @@ -213,9 +220,19 @@ void NBinSSAKokkos::bin_atoms() template KOKKOS_INLINE_FUNCTION void NBinSSAKokkos::binAtomsItem(const int &i) const +{ + const int ibin = binID(i); + const int ac = Kokkos::atomic_fetch_add(&(bincount[ibin]), (int)1); + bins(ibin, ac) = i; +} + +template +KOKKOS_INLINE_FUNCTION +void NBinSSAKokkos::binIDAtomsItem(const int &i, int &update) const { int loc[3]; const int ibin = coord2bin(x(i, 0), x(i, 1), x(i, 2), &(loc[0])); + binID(i) = ibin; // Find the bounding box of the local atoms in the bins if (loc[0] < d_lbinxlo()) Kokkos::atomic_fetch_min(&d_lbinxlo(),loc[0]); @@ -226,10 +243,18 @@ void NBinSSAKokkos::binAtomsItem(const int &i) const if (loc[2] >= d_lbinzhi()) Kokkos::atomic_fetch_max(&d_lbinzhi(),loc[2] + 1); const int ac = Kokkos::atomic_fetch_add(&(bincount[ibin]), (int)1); - if(ac < (int) bins.dimension_1()) { - bins(ibin, ac) = i; - } else { - d_resize() = 1; + if (update <= ac) update = ac + 1; +} + +template +KOKKOS_INLINE_FUNCTION +void NBinSSAKokkos::binIDGhostsItem(const int &i, int &update) const +{ + const int iAIR = coord2ssaAIR(x(i, 0), x(i, 1), x(i, 2)); + binID(i) = iAIR; + if (iAIR > 0) { // include only ghost atoms in an AIR + const int ac = Kokkos::atomic_fetch_add(&gbincount[iAIR], (int)1); + if (update <= ac) update = ac + 1; } } diff --git a/src/KOKKOS/nbin_ssa_kokkos.h b/src/KOKKOS/nbin_ssa_kokkos.h index 488c1034f5..69f05c9304 100644 --- a/src/KOKKOS/nbin_ssa_kokkos.h +++ b/src/KOKKOS/nbin_ssa_kokkos.h @@ -41,6 +41,11 @@ class NBinSSAKokkos : public NBinStandard { void bin_atoms_setup(int); void bin_atoms(); + // temporary array to hold the binID for each atom + DAT::tdual_int_1d k_binID; + typename AT::t_int_1d binID; + typename AT::t_int_1d_const c_binID; + int atoms_per_bin; DAT::tdual_int_1d k_bincount; DAT::tdual_int_2d k_bins; @@ -77,6 +82,12 @@ class NBinSSAKokkos : public NBinStandard { KOKKOS_INLINE_FUNCTION void binAtomsItem(const int &i) const; + KOKKOS_INLINE_FUNCTION + void binIDAtomsItem(const int &i, int &update) const; + + KOKKOS_INLINE_FUNCTION + void binIDGhostsItem(const int &i, int &update) const; + /* ---------------------------------------------------------------------- convert atom coords into the ssa active interaction region number ------------------------------------------------------------------------- */ @@ -165,6 +176,60 @@ struct NPairSSAKokkosBinAtomsFunctor { } }; +template +struct NPairSSAKokkosBinIDAtomsFunctor { + typedef DeviceType device_type; + typedef int value_type; + + const NBinSSAKokkos c; + + NPairSSAKokkosBinIDAtomsFunctor(const NBinSSAKokkos &_c): + c(_c) {}; + ~NPairSSAKokkosBinIDAtomsFunctor() {} + KOKKOS_INLINE_FUNCTION + void operator() (const int & i, value_type& update) const { + c.binIDAtomsItem(i, update); + } + + KOKKOS_INLINE_FUNCTION + void join (volatile value_type& dst, + const volatile value_type& src) const { + if (dst < src) dst = src; + } + + KOKKOS_INLINE_FUNCTION + void init (value_type& dst) const { + dst = INT_MIN; + } +}; + +template +struct NPairSSAKokkosBinIDGhostsFunctor { + typedef DeviceType device_type; + typedef int value_type; + + const NBinSSAKokkos c; + + NPairSSAKokkosBinIDGhostsFunctor(const NBinSSAKokkos &_c): + c(_c) {}; + ~NPairSSAKokkosBinIDGhostsFunctor() {} + KOKKOS_INLINE_FUNCTION + void operator() (const int & i, value_type& update) const { + c.binIDGhostsItem(i, update); + } + + KOKKOS_INLINE_FUNCTION + void join (volatile value_type& dst, + const volatile value_type& src) const { + if (dst < src) dst = src; + } + + KOKKOS_INLINE_FUNCTION + void init (value_type& dst) const { + dst = INT_MIN; + } +}; + } #endif From 0982331c71fbb9d9420e26c47dfad1a0392fd028 Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Wed, 1 Mar 2017 09:49:24 -0500 Subject: [PATCH 171/439] USER-DPD Kokkos: replicate 7a593c2f bugfix to pair_table_rx_kokkos.cpp --- src/KOKKOS/pair_table_rx_kokkos.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/KOKKOS/pair_table_rx_kokkos.cpp b/src/KOKKOS/pair_table_rx_kokkos.cpp index 58108c9308..2a1ee2c0b1 100644 --- a/src/KOKKOS/pair_table_rx_kokkos.cpp +++ b/src/KOKKOS/pair_table_rx_kokkos.cpp @@ -984,7 +984,7 @@ void PairTableRXKokkos::coeff(int narg, char **arg) nspecies = atom->nspecies_dpd; if(nspecies==0) error->all(FLERR,"There are no rx species specified."); int n; - n = strlen(arg[3]) + 1; + n = strlen(arg[4]) + 1; site1 = new char[n]; strcpy(site1,arg[4]); @@ -995,7 +995,7 @@ void PairTableRXKokkos::coeff(int narg, char **arg) if (ispecies == nspecies && strcmp(site1,"1fluid") != 0) error->all(FLERR,"Site1 name not recognized in pair coefficients"); - n = strlen(arg[4]) + 1; + n = strlen(arg[5]) + 1; site2 = new char[n]; strcpy(site2,arg[5]); From 6e26358ec3eade9bb35f4dc1ad48b5374cec417d Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Wed, 1 Mar 2017 11:46:26 -0500 Subject: [PATCH 172/439] lib kokkos bugfix: on a CUDA host, the random state wasn't preserved. Random_XorShift*_Pool::free_state() has two purposes: 1) update the state value kept in the pool 2) unlock the state For a CUDA host thread, ONLY skip step 2, not both. --- lib/kokkos/algorithms/src/Kokkos_Random.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/kokkos/algorithms/src/Kokkos_Random.hpp b/lib/kokkos/algorithms/src/Kokkos_Random.hpp index d376173bf1..2fb6b553c2 100644 --- a/lib/kokkos/algorithms/src/Kokkos_Random.hpp +++ b/lib/kokkos/algorithms/src/Kokkos_Random.hpp @@ -1204,8 +1204,8 @@ Random_XorShift64 Random_XorShift64_Pool::get_state( template<> KOKKOS_INLINE_FUNCTION void Random_XorShift64_Pool::free_state(const Random_XorShift64 &state) const { -#ifdef __CUDA_ARCH__ state_(state.state_idx_) = state.state_; +#ifdef __CUDA_ARCH__ locks_(state.state_idx_) = 0; return; #endif @@ -1240,9 +1240,9 @@ Random_XorShift1024 Random_XorShift1024_Pool::get_st template<> KOKKOS_INLINE_FUNCTION void Random_XorShift1024_Pool::free_state(const Random_XorShift1024 &state) const { -#ifdef __CUDA_ARCH__ for(int i=0; i<16; i++) state_(state.state_idx_,i) = state.state_[i]; +#ifdef __CUDA_ARCH__ locks_(state.state_idx_) = 0; return; #endif From 641bf72f2030f78d1ecfbbedc60704f4215d9662 Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Wed, 1 Mar 2017 11:52:33 -0500 Subject: [PATCH 173/439] lib kokkos: Enable deterministic use of Random_XorShift*_Pool. Add support for lock-free and deterministic use of Random_XorShift*_Pool by giving state_idx selection and lock responsibility up to the application. Done by an overload of get_state() to take sate_idx as an argument that the appplication guarantees is concurrently unique and within the range of num_states that the application passed to init(). In other words, this allows the RNG state to be associated with some application specific index, rather than a runtime arbitrary thread ID, and thus the application can control which work is performed using which RNG in a deterministic manner, regardless of which thread performs the work. --- lib/kokkos/algorithms/src/Kokkos_Random.hpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/lib/kokkos/algorithms/src/Kokkos_Random.hpp b/lib/kokkos/algorithms/src/Kokkos_Random.hpp index 2fb6b553c2..a0d666183c 100644 --- a/lib/kokkos/algorithms/src/Kokkos_Random.hpp +++ b/lib/kokkos/algorithms/src/Kokkos_Random.hpp @@ -752,6 +752,12 @@ namespace Kokkos { return Random_XorShift64(state_(i),i); } + // NOTE: state_idx MUST be unique and less than num_states + KOKKOS_INLINE_FUNCTION + Random_XorShift64 get_state(const int state_idx) const { + return Random_XorShift64(state_(state_idx),state_idx); + } + KOKKOS_INLINE_FUNCTION void free_state(const Random_XorShift64& state) const { state_(state.state_idx_) = state.state_; @@ -1006,6 +1012,12 @@ namespace Kokkos { return Random_XorShift1024(state_,p_(i),i); }; + // NOTE: state_idx MUST be unique and less than num_states + KOKKOS_INLINE_FUNCTION + Random_XorShift1024 get_state(const int state_idx) const { + return Random_XorShift1024(state_,p_(state_idx),state_idx); + } + KOKKOS_INLINE_FUNCTION void free_state(const Random_XorShift1024& state) const { for(int i = 0; i<16; i++) From 268e855a151360861f7b6059414356af1323e997 Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Wed, 1 Mar 2017 14:14:29 -0500 Subject: [PATCH 174/439] USER-DPD Kokkos: bugfix for the rare case were the SSA ghost processing has more parallelism than for the locals. --- src/KOKKOS/fix_shardlow_kokkos.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/KOKKOS/fix_shardlow_kokkos.cpp b/src/KOKKOS/fix_shardlow_kokkos.cpp index 9bac6250da..8b6432e2dc 100644 --- a/src/KOKKOS/fix_shardlow_kokkos.cpp +++ b/src/KOKKOS/fix_shardlow_kokkos.cpp @@ -50,7 +50,6 @@ #include "neighbor.h" #include "neigh_list_kokkos.h" #include "neigh_request.h" -#include "random_mars.h" #include "memory.h" #include "domain.h" #include "modify.h" @@ -632,6 +631,9 @@ void FixShardlowKokkos::initial_integrate(int vflag) #ifdef DPD_USE_RAN_MARS int maxWorkItemCt = (int) ssa_itemLoc.dimension_1(); + if (maxWorkItemCt < (int) ssa_gitemLoc.dimension_1()) { + maxWorkItemCt = (int) ssa_gitemLoc.dimension_1(); + } if (maxWorkItemCt > maxRNG) { if (pp_random) { for (int i = 1; i < maxRNG; ++i) delete pp_random[i]; From ed089c34cfda77885d235ade1a285d30109ce157 Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Wed, 1 Mar 2017 14:18:14 -0500 Subject: [PATCH 175/439] USER-DPD Kokkos: Now use the deterministic Random_XorShift64() for SSA --- src/KOKKOS/fix_shardlow_kokkos.cpp | 49 ++++++++++++++--------- src/KOKKOS/fix_shardlow_kokkos.h | 7 +++- src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp | 1 - src/KOKKOS/pair_dpd_fdt_energy_kokkos.h | 17 ++++---- 4 files changed, 44 insertions(+), 30 deletions(-) diff --git a/src/KOKKOS/fix_shardlow_kokkos.cpp b/src/KOKKOS/fix_shardlow_kokkos.cpp index 8b6432e2dc..996f37257d 100644 --- a/src/KOKKOS/fix_shardlow_kokkos.cpp +++ b/src/KOKKOS/fix_shardlow_kokkos.cpp @@ -89,11 +89,9 @@ FixShardlowKokkos::FixShardlowKokkos(LAMMPS *lmp, int narg, char **a // if(k_pairDPDE){ comm_forward = 3; comm_reverse = 5; -#ifdef DPD_USE_RAN_MARS maxRNG = 0; +#ifdef DPD_USE_RAN_MARS pp_random = NULL; -#else - p_rand_pool = &(k_pairDPDE->rand_pool); #endif // } else { // comm_forward = 3; @@ -281,10 +279,14 @@ void FixShardlowKokkos::setup_pre_neighbor() template template void FixShardlowKokkos::ssa_update_dpd( - int start_ii, int count + int start_ii, int count, int id ) { - rand_type rand_gen = p_rand_pool->get_state(); +#ifdef DPD_USE_RAN_MARS + class RanMars *pRNG = pp_random[id]; +#else + rand_type rand_gen = rand_pool.get_state(id); +#endif const double theta_ij_inv = 1.0/k_pairDPD->temperature; // independent of i,j const double boltz_inv = 1.0/force->boltz; @@ -350,7 +352,12 @@ void FixShardlowKokkos::ssa_update_dpd( double halfsigma_ij = STACKPARAMS?m_params[itype][jtype].halfsigma:params(itype,jtype).halfsigma; double halfgamma_ij = halfsigma_ij*halfsigma_ij*boltz_inv*theta_ij_inv; - double sigmaRand = halfsigma_ij*wr*dtsqrt*ftm2v * pRNG->gaussian(); + double sigmaRand = halfsigma_ij*wr*dtsqrt*ftm2v * +#ifdef DPD_USE_RAN_MARS + pRNG->gaussian(); +#else + rand_gen.normal(); +#endif const double mass_j = masses(massPerI ? j : jtype); double massinv_j = 1.0 / mass_j; @@ -412,7 +419,9 @@ void FixShardlowKokkos::ssa_update_dpd( v(i, 2) = vzi; } - p_rand_pool->free_state(rand_gen); +#ifndef DPD_USE_RAN_MARS + rand_pool.free_state(rand_gen); +#endif } #endif @@ -431,7 +440,7 @@ void FixShardlowKokkos::ssa_update_dpde( #ifdef DPD_USE_RAN_MARS class RanMars *pRNG = pp_random[id]; #else - rand_type rand_gen = p_rand_pool->get_state(); + rand_type rand_gen = rand_pool.get_state(id); #endif const double boltz_inv = 1.0/force->boltz; @@ -506,10 +515,11 @@ void FixShardlowKokkos::ssa_update_dpde( double halfsigma_ij = STACKPARAMS?m_params[itype][jtype].halfsigma:params(itype,jtype).halfsigma; double halfgamma_ij = halfsigma_ij*halfsigma_ij*boltz_inv*theta_ij_inv; + double sigmaRand = halfsigma_ij*wr*dtsqrt*ftm2v * #ifdef DPD_USE_RAN_MARS - double sigmaRand = halfsigma_ij*wr*dtsqrt*ftm2v * pRNG->gaussian(); + pRNG->gaussian(); #else - double sigmaRand = halfsigma_ij*wr*dtsqrt*ftm2v * rand_gen.normal(); + rand_gen.normal(); #endif const double mass_j = masses(massPerI ? j : jtype); @@ -519,10 +529,11 @@ void FixShardlowKokkos::ssa_update_dpde( // Compute uCond double kappa_ij = STACKPARAMS?m_params[itype][jtype].kappa:params(itype,jtype).kappa; double alpha_ij = STACKPARAMS?m_params[itype][jtype].alpha:params(itype,jtype).alpha; + double del_uCond = alpha_ij*wr*dtsqrt * #ifdef DPD_USE_RAN_MARS - double del_uCond = alpha_ij*wr*dtsqrt * pRNG->gaussian(); + pRNG->gaussian(); #else - double del_uCond = alpha_ij*wr*dtsqrt * rand_gen.normal(); + rand_gen.normal(); #endif del_uCond += kappa_ij*(theta_i_inv - theta_j_inv)*wdt; @@ -600,7 +611,7 @@ void FixShardlowKokkos::ssa_update_dpde( } #ifndef DPD_USE_RAN_MARS - p_rand_pool->free_state(rand_gen); + rand_pool.free_state(rand_gen); #endif } @@ -629,25 +640,27 @@ void FixShardlowKokkos::initial_integrate(int vflag) ssa_gitemLoc = np_ssa->ssa_gitemLoc; ssa_gitemLen = np_ssa->ssa_gitemLen; -#ifdef DPD_USE_RAN_MARS int maxWorkItemCt = (int) ssa_itemLoc.dimension_1(); if (maxWorkItemCt < (int) ssa_gitemLoc.dimension_1()) { maxWorkItemCt = (int) ssa_gitemLoc.dimension_1(); } if (maxWorkItemCt > maxRNG) { +#ifdef DPD_USE_RAN_MARS if (pp_random) { for (int i = 1; i < maxRNG; ++i) delete pp_random[i]; delete[] pp_random; pp_random = NULL; } - maxRNG = maxWorkItemCt; - pp_random = new RanMars*[maxRNG]; - for (int i = 1; i < maxRNG; ++i) { + pp_random = new RanMars*[maxWorkItemCt]; + for (int i = 1; i < maxWorkItemCt; ++i) { pp_random[i] = new RanMars(lmp, k_pairDPDE->seed + comm->me + comm->nprocs*i); } pp_random[0] = k_pairDPDE->random; - } +#else + rand_pool.init(k_pairDPDE->seed + comm->me, maxWorkItemCt); #endif + maxRNG = maxWorkItemCt; + } #ifdef DEBUG_PAIR_CT for (int i = 0; i < 2; ++i) diff --git a/src/KOKKOS/fix_shardlow_kokkos.h b/src/KOKKOS/fix_shardlow_kokkos.h index 011c16dc60..c4711f5b8b 100644 --- a/src/KOKKOS/fix_shardlow_kokkos.h +++ b/src/KOKKOS/fix_shardlow_kokkos.h @@ -71,11 +71,14 @@ class FixShardlowKokkos : public FixShardlow { // class PairDPDfdt *pairDPD; PairDPDfdtEnergyKokkos *k_pairDPDE; -#ifdef DPD_USE_RAN_MARS int maxRNG; +#ifdef DPD_USE_RAN_MARS class RanMars **pp_random; +#elif defined(DPD_USE_Random_XorShift1024) + Kokkos::Random_XorShift1024_Pool rand_pool; + typedef typename Kokkos::Random_XorShift1024_Pool::generator_type rand_type; #else - Kokkos::Random_XorShift64_Pool *p_rand_pool; + Kokkos::Random_XorShift64_Pool rand_pool; typedef typename Kokkos::Random_XorShift64_Pool::generator_type rand_type; #endif diff --git a/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp b/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp index e534f97391..ba61185a57 100644 --- a/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp +++ b/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp @@ -28,7 +28,6 @@ #include "neighbor.h" #include "neigh_list.h" #include "neigh_request.h" -#include "random_mars.h" #include "memory.h" #include "modify.h" #include "pair_dpd_fdt_energy_kokkos.h" diff --git a/src/KOKKOS/pair_dpd_fdt_energy_kokkos.h b/src/KOKKOS/pair_dpd_fdt_energy_kokkos.h index a32539242a..74fe5a63b8 100644 --- a/src/KOKKOS/pair_dpd_fdt_energy_kokkos.h +++ b/src/KOKKOS/pair_dpd_fdt_energy_kokkos.h @@ -22,16 +22,12 @@ PairStyle(dpd/fdt/energy/kk/host,PairDPDfdtEnergyKokkos) #ifndef LMP_PAIR_DPD_FDT_ENERGY_KOKKOS_H #define LMP_PAIR_DPD_FDT_ENERGY_KOKKOS_H +//#define DPD_USE_RAN_MARS +#define DPD_USE_Random_XorShift64 -#ifndef ALLOW_NON_DETERMINISTIC_DPD -#ifdef KOKKOS_HAVE_CUDA -//FIXME print some warning +#if !defined(DPD_USE_RAN_MARS) && !defined(DPD_USE_Random_XorShift64) && !defined(Random_XorShift1024) +#define DPD_USE_Random_XorShift64 #endif -#ifndef DPD_USE_RAN_MARS -#define DPD_USE_RAN_MARS -#endif -#endif - #include "pair_dpd_fdt_energy.h" #include "pair_kokkos.h" @@ -106,9 +102,12 @@ class PairDPDfdtEnergyKokkos : public PairDPDfdtEnergy { #ifdef DPD_USE_RAN_MARS RandPoolWrap rand_pool; typedef RandWrap rand_type; -#else +#elif defined(DPD_USE_Random_XorShift64) Kokkos::Random_XorShift64_Pool rand_pool; typedef typename Kokkos::Random_XorShift64_Pool::generator_type rand_type; +#elif defined(DPD_USE_Random_XorShift1024) + Kokkos::Random_XorShift1024_Pool rand_pool; + typedef typename Kokkos::Random_XorShift1024_Pool::generator_type rand_type; #endif typename ArrayTypes::tdual_ffloat_2d k_cutsq; From 8210b25fb848c15484a2dd4dd46af2c933e28bd1 Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Wed, 1 Mar 2017 15:34:24 -0500 Subject: [PATCH 176/439] USER-DPD Kokkos: replicate 9a560b90 bugfix to atom_vec_dpd_kokkos.cpp --- src/KOKKOS/atom_vec_dpd_kokkos.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/KOKKOS/atom_vec_dpd_kokkos.cpp b/src/KOKKOS/atom_vec_dpd_kokkos.cpp index 820f11c215..146ae8f7dd 100644 --- a/src/KOKKOS/atom_vec_dpd_kokkos.cpp +++ b/src/KOKKOS/atom_vec_dpd_kokkos.cpp @@ -1048,8 +1048,6 @@ int AtomVecDPDKokkos::pack_comm_hybrid(int n, int *list, double *buf) buf[m++] = h_uCond[j]; buf[m++] = h_uMech[j]; buf[m++] = h_uChem[j]; - buf[m++] = h_uCG[j]; - buf[m++] = h_uCGnew[j]; } return m; } @@ -1245,8 +1243,6 @@ int AtomVecDPDKokkos::unpack_comm_hybrid(int n, int first, double *buf) h_uCond(i) = buf[m++]; h_uMech(i) = buf[m++]; h_uChem(i) = buf[m++]; - h_uCG(i) = buf[m++]; - h_uCGnew(i) = buf[m++]; } modified(Host,DPDTHETA_MASK | UCOND_MASK | From d95fbf3a5e4afb3aaef5d9d931893a06dd609d94 Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Thu, 2 Mar 2017 15:01:41 -0500 Subject: [PATCH 177/439] USER-DPD Kokkos: use Random_XorShift64() by default, but allow overrides --- src/KOKKOS/pair_dpd_fdt_energy_kokkos.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/KOKKOS/pair_dpd_fdt_energy_kokkos.h b/src/KOKKOS/pair_dpd_fdt_energy_kokkos.h index 74fe5a63b8..fcf4b33a7a 100644 --- a/src/KOKKOS/pair_dpd_fdt_energy_kokkos.h +++ b/src/KOKKOS/pair_dpd_fdt_energy_kokkos.h @@ -22,9 +22,6 @@ PairStyle(dpd/fdt/energy/kk/host,PairDPDfdtEnergyKokkos) #ifndef LMP_PAIR_DPD_FDT_ENERGY_KOKKOS_H #define LMP_PAIR_DPD_FDT_ENERGY_KOKKOS_H -//#define DPD_USE_RAN_MARS -#define DPD_USE_Random_XorShift64 - #if !defined(DPD_USE_RAN_MARS) && !defined(DPD_USE_Random_XorShift64) && !defined(Random_XorShift1024) #define DPD_USE_Random_XorShift64 #endif From 27d2e9bf56f04fbb598443b84fb1c8f18f53a9aa Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Thu, 2 Mar 2017 15:03:33 -0500 Subject: [PATCH 178/439] USER-DPD: add npair_halffull_newton_ssa to Purge.list With the new SSA neighbor list, half from full can't work, and will break compiles if the old files are in the src directory --- src/Purge.list | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Purge.list b/src/Purge.list index 554c5df824..772961bbdf 100644 --- a/src/Purge.list +++ b/src/Purge.list @@ -16,6 +16,9 @@ style_region.h style_neigh_bin.h style_neigh_pair.h style_neigh_stencil.h +# deleted on 01 Mar 2017 +npair_halffull_newton_ssa.cpp +npair_halffull_newton_ssa.h # deleted on ## XXX 2016 accelerator_intel.h neigh_bond.cpp From 3820c5881d5c8af44baa45c12771a7971fb668ca Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Thu, 2 Mar 2017 14:02:49 -0700 Subject: [PATCH 179/439] Adding fix_wall_lj93_kokkos --- src/KOKKOS/Install.sh | 2 + src/KOKKOS/fix_wall_lj93_kokkos.cpp | 104 ++++++++++++++++++++++++++++ src/KOKKOS/fix_wall_lj93_kokkos.h | 83 ++++++++++++++++++++++ src/fix_wall.cpp | 2 + src/fix_wall_lj93.h | 4 +- 5 files changed, 193 insertions(+), 2 deletions(-) create mode 100644 src/KOKKOS/fix_wall_lj93_kokkos.cpp create mode 100644 src/KOKKOS/fix_wall_lj93_kokkos.h diff --git a/src/KOKKOS/Install.sh b/src/KOKKOS/Install.sh index ea70ae4ca1..10245631ab 100644 --- a/src/KOKKOS/Install.sh +++ b/src/KOKKOS/Install.sh @@ -105,6 +105,8 @@ action fix_setforce_kokkos.cpp action fix_setforce_kokkos.h action fix_momentum_kokkos.cpp action fix_momentum_kokkos.h +action fix_wall_lj93_kokkos.cpp +action fix_wall_lj93_kokkos.h action fix_wall_reflect_kokkos.cpp action fix_wall_reflect_kokkos.h action fix_dpd_energy_kokkos.cpp fix_dpd_energy.cpp diff --git a/src/KOKKOS/fix_wall_lj93_kokkos.cpp b/src/KOKKOS/fix_wall_lj93_kokkos.cpp new file mode 100644 index 0000000000..38c7347e97 --- /dev/null +++ b/src/KOKKOS/fix_wall_lj93_kokkos.cpp @@ -0,0 +1,104 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include +#include "fix_wall_lj93_kokkos.h" +#include "atom_kokkos.h" +#include "error.h" +#include "atom_masks.h" + +using namespace LAMMPS_NS; +using namespace FixConst; + +/* ---------------------------------------------------------------------- */ + +template +FixWallLJ93Kokkos::FixWallLJ93Kokkos(LAMMPS *lmp, int narg, char **arg) : + FixWallLJ93(lmp, narg, arg) +{ + kokkosable = 1; + atomKK = (AtomKokkos *) atom; + execution_space = ExecutionSpaceFromDevice::space; + datamask_read = EMPTY_MASK; + datamask_modify = EMPTY_MASK; +} + +/* ---------------------------------------------------------------------- + interaction of all particles in group with a wall + m = index of wall coeffs + which = xlo,xhi,ylo,yhi,zlo,zhi + error if any particle is on or behind wall +------------------------------------------------------------------------- */ + +template +void FixWallLJ93Kokkos::wall_particle(int m_in, int which, double coord_in) +{ + m = m_in; + coord = coord_in; + + atomKK->sync(execution_space, X_MASK|F_MASK|MASK_MASK); + x = atomKK->k_x.view(); + f = atomKK->k_f.view(); + mask = atomKK->k_mask.view(); + DAT::tdual_int_scalar k_oneflag = DAT::tdual_int_scalar("fix:oneflag"); + d_oneflag = k_oneflag.view(); + + int nlocal = atom->nlocal; + + dim = which / 2; + side = which % 2; + if (side == 0) side = -1; + + copymode = 1; + FixWallLJ93KokkosFunctor wp_functor(this); + Kokkos::parallel_reduce(nlocal,wp_functor,ewall); + DeviceType::fence(); + copymode = 0; + + atomKK->modified(execution_space, F_MASK); + + k_oneflag.template modify(); + k_oneflag.template sync(); + if (k_oneflag.h_view()) error->one(FLERR,"Particle on or inside fix wall surface"); +} + +template +KOKKOS_INLINE_FUNCTION +void FixWallLJ93Kokkos::wall_particle_item(int i, value_type ewall) const { + if (mask(i) & groupbit) { + double delta; + if (side < 0) delta = x(i,dim) - coord; + else delta = coord - x(i,dim); + if (delta >= cutoff[m]) return; + if (delta <= 0.0) { + d_oneflag() = 1; + return; + } + double rinv = 1.0/delta; + double r2inv = rinv*rinv; + double r4inv = r2inv*r2inv; + double r10inv = r4inv*r4inv*r2inv; + double fwall = side * (coeff1[m]*r10inv - coeff2[m]*r4inv); + f(i,dim) -= fwall; + ewall[0] += coeff3[m]*r4inv*r4inv*rinv - + coeff4[m]*r2inv*rinv - offset[m]; + ewall[m+1] += fwall; + } +} + +namespace LAMMPS_NS { +template class FixWallLJ93Kokkos; +#ifdef KOKKOS_HAVE_CUDA +template class FixWallLJ93Kokkos; +#endif +} diff --git a/src/KOKKOS/fix_wall_lj93_kokkos.h b/src/KOKKOS/fix_wall_lj93_kokkos.h new file mode 100644 index 0000000000..3cb0a2d44c --- /dev/null +++ b/src/KOKKOS/fix_wall_lj93_kokkos.h @@ -0,0 +1,83 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef FIX_CLASS + +FixStyle(wall/lj93/kk,FixWallLJ93Kokkos) +FixStyle(wall/lj93/kk/device,FixWallLJ93Kokkos) +FixStyle(wall/lj93/kk/host,FixWallLJ93Kokkos) + +#else + +#ifndef LMP_FIX_WALL_LJ93_KOKKOS_H +#define LMP_FIX_WALL_LJ93_KOKKOS_H + +#include "fix_wall_lj93.h" +#include "kokkos_type.h" + +namespace LAMMPS_NS { + +template +class FixWallLJ93Kokkos : public FixWallLJ93 { + public: + typedef DeviceType device_type; + typedef ArrayTypes AT; + typedef double value_type[]; + + FixWallLJ93Kokkos(class LAMMPS *, int, char **); + void wall_particle(int, int, double); + + int m; + + KOKKOS_INLINE_FUNCTION + void wall_particle_item(int, value_type) const; + + private: + int dim,side; + double coord; + + typename AT::t_x_array x; + typename AT::t_f_array f; + typename AT::t_int_1d mask; + typename AT::t_int_scalar d_oneflag; +}; + +template +struct FixWallLJ93KokkosFunctor { + typedef DeviceType device_type ; + typedef double value_type[]; + const int value_count; + + FixWallLJ93Kokkos c; + FixWallLJ93KokkosFunctor(FixWallLJ93Kokkos* c_ptr): + c(*c_ptr), + value_count(c.m) {} + KOKKOS_INLINE_FUNCTION + void operator()(const int i, value_type ewall) const { + c.wall_particle_item(i,ewall); + } +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +E: Particle on or inside fix wall surface + +Particles must be "exterior" to the wall in order for energy/force to +be calculated. + +*/ diff --git a/src/fix_wall.cpp b/src/fix_wall.cpp index 503b87f4a7..8b569cafc6 100644 --- a/src/fix_wall.cpp +++ b/src/fix_wall.cpp @@ -201,6 +201,8 @@ FixWall::FixWall(LAMMPS *lmp, int narg, char **arg) : FixWall::~FixWall() { + if (copymode) return; + for (int m = 0; m < nwall; m++) { delete [] xstr[m]; delete [] estr[m]; diff --git a/src/fix_wall_lj93.h b/src/fix_wall_lj93.h index 40337a5176..3763a02910 100644 --- a/src/fix_wall_lj93.h +++ b/src/fix_wall_lj93.h @@ -28,9 +28,9 @@ class FixWallLJ93 : public FixWall { public: FixWallLJ93(class LAMMPS *, int, char **); void precompute(int); - void wall_particle(int, int, double); + virtual void wall_particle(int, int, double); - private: + protected: double coeff1[6],coeff2[6],coeff3[6],coeff4[6],offset[6]; }; From 7e78921c96a5f822dd5c8942bc1fb204a3c747f3 Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Fri, 3 Mar 2017 10:12:44 -0500 Subject: [PATCH 180/439] USER-DPD Kokkos: propagate 763a00e8 bugfix to pair_multi_lucy_rx_kokkos.cpp --- src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp b/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp index 30b49a8e8d..d087546619 100644 --- a/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp +++ b/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp @@ -538,15 +538,15 @@ void PairMultiLucyRXKokkos::operator()(TagPairMultiLucyRXComputeLoca rho_i_contrib += factor; if (NEWTON_PAIR || j < nlocal) a_rho[j] += factor; - } else if (rsq < d_cutsq(itype,jtype)) { - const double rcut = sqrt(d_cutsq(itype,jtype)); - const double tmpFactor = 1.0-sqrt(rsq)/rcut; - const double tmpFactor4 = tmpFactor*tmpFactor*tmpFactor*tmpFactor; - const double factor = (84.0/(5.0*pi*rcut*rcut*rcut))*(1.0+3.0*sqrt(rsq)/(2.0*rcut))*tmpFactor4; - rho_i_contrib += factor; - if (NEWTON_PAIR || j < nlocal) - a_rho[j] += factor; } + } else if (rsq < d_cutsq(itype,jtype)) { + const double rcut = sqrt(d_cutsq(itype,jtype)); + const double tmpFactor = 1.0-sqrt(rsq)/rcut; + const double tmpFactor4 = tmpFactor*tmpFactor*tmpFactor*tmpFactor; + const double factor = (84.0/(5.0*pi*rcut*rcut*rcut))*(1.0+3.0*sqrt(rsq)/(2.0*rcut))*tmpFactor4; + rho_i_contrib += factor; + if (NEWTON_PAIR || j < nlocal) + a_rho[j] += factor; } } From a7e855096215b5204b39bc7e54b080095909d6c4 Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Fri, 3 Mar 2017 10:38:45 -0500 Subject: [PATCH 181/439] USER-DPD Kokkos: turn one_type optimization into a template specialization --- src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp | 28 +++++++++++++++++------- src/KOKKOS/pair_multi_lucy_rx_kokkos.h | 7 +++--- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp b/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp index d087546619..11dbfabf3a 100644 --- a/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp +++ b/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp @@ -454,7 +454,7 @@ void PairMultiLucyRXKokkos::computeLocalDensity() const double pi = MathConst::MY_PI; const bool newton_pair = force->newton_pair; - one_type = (atom->ntypes == 1); + const bool one_type = (atom->ntypes == 1); // Special cut-off values for when there's only one type. cutsq_type11 = cutsq[1][1]; @@ -471,14 +471,26 @@ void PairMultiLucyRXKokkos::computeLocalDensity() if (neighflag == HALF) { if (newton_pair) - Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + if (one_type) + Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + else + Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); else - Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + if (one_type) + Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + else + Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); } else if (neighflag == HALFTHREAD) { if (newton_pair) - Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + if (one_type) + Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + else + Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); else - Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + if (one_type) + Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + else + Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); } atomKK->modified(execution_space,DPDRHO_MASK); @@ -498,9 +510,9 @@ void PairMultiLucyRXKokkos::operator()(TagPairMultiLucyRXZero, const } template -template +template KOKKOS_INLINE_FUNCTION -void PairMultiLucyRXKokkos::operator()(TagPairMultiLucyRXComputeLocalDensity, const int &ii) const { +void PairMultiLucyRXKokkos::operator()(TagPairMultiLucyRXComputeLocalDensity, const int &ii) const { // The rho array is atomic for Half/Thread neighbor style @@ -528,7 +540,7 @@ void PairMultiLucyRXKokkos::operator()(TagPairMultiLucyRXComputeLoca const double delz = ztmp - x(j,2); const double rsq = delx*delx + dely*dely + delz*delz; - if (one_type) { + if (ONE_TYPE) { if (rsq < cutsq_type11) { const double rcut = rcut_type11; const double r_over_rcut = sqrt(rsq) / rcut; diff --git a/src/KOKKOS/pair_multi_lucy_rx_kokkos.h b/src/KOKKOS/pair_multi_lucy_rx_kokkos.h index 1e84e3efd8..8556319531 100644 --- a/src/KOKKOS/pair_multi_lucy_rx_kokkos.h +++ b/src/KOKKOS/pair_multi_lucy_rx_kokkos.h @@ -39,7 +39,7 @@ struct TagPairMultiLucyRXCompute{}; struct TagPairMultiLucyRXZero{}; -template +template struct TagPairMultiLucyRXComputeLocalDensity{}; template @@ -88,9 +88,9 @@ class PairMultiLucyRXKokkos : public PairMultiLucyRX { KOKKOS_INLINE_FUNCTION void operator()(TagPairMultiLucyRXZero, const int&) const; - template + template KOKKOS_INLINE_FUNCTION - void operator()(TagPairMultiLucyRXComputeLocalDensity, const int&) const; + void operator()(TagPairMultiLucyRXComputeLocalDensity, const int&) const; template KOKKOS_INLINE_FUNCTION @@ -103,7 +103,6 @@ class PairMultiLucyRXKokkos : public PairMultiLucyRX { int neighflag; int eflag,vflag; - bool one_type; double cutsq_type11; double rcut_type11; double factor_type11; From c468727db0927c45c25a43d0285265ed01a5a765 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 3 Mar 2017 10:49:15 -0700 Subject: [PATCH 182/439] Fixing issue in fix_wall_lj93_kokkos --- src/KOKKOS/fix_wall_lj93_kokkos.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/KOKKOS/fix_wall_lj93_kokkos.h b/src/KOKKOS/fix_wall_lj93_kokkos.h index 3cb0a2d44c..64f3c59a62 100644 --- a/src/KOKKOS/fix_wall_lj93_kokkos.h +++ b/src/KOKKOS/fix_wall_lj93_kokkos.h @@ -61,7 +61,7 @@ struct FixWallLJ93KokkosFunctor { FixWallLJ93Kokkos c; FixWallLJ93KokkosFunctor(FixWallLJ93Kokkos* c_ptr): c(*c_ptr), - value_count(c.m) {} + value_count(c_ptr->m+1) {} KOKKOS_INLINE_FUNCTION void operator()(const int i, value_type ewall) const { c.wall_particle_item(i,ewall); From 0651ea7f69c33ed026199928476297f9a485e00b Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Fri, 3 Mar 2017 12:50:13 -0500 Subject: [PATCH 183/439] USER-DPD Kokkos: work around CUDA not having max_hardware_threads() --- src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp | 36 +++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp b/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp index ba61185a57..99a364eb86 100644 --- a/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp +++ b/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp @@ -114,6 +114,42 @@ void PairDPDfdtEnergyKokkos::init_style() #endif } +#if defined(KOKKOS_ENABLE_CUDA) && defined(__CUDACC__) +// CUDA specialization of init_style to properly call rand_pool.init() +template<> +void PairDPDfdtEnergyKokkos::init_style() +{ + PairDPDfdtEnergy::init_style(); + + // irequest = neigh request made by parent class + + neighflag = lmp->kokkos->neighflag; + int irequest = neighbor->nrequest - 1; + + neighbor->requests[irequest]-> + kokkos_host = Kokkos::Impl::is_same::value && + !Kokkos::Impl::is_same::value; + neighbor->requests[irequest]-> + kokkos_device = Kokkos::Impl::is_same::value; + + if (neighflag == FULL) { + neighbor->requests[irequest]->full = 1; + neighbor->requests[irequest]->half = 0; + } else if (neighflag == HALF || neighflag == HALFTHREAD) { + neighbor->requests[irequest]->full = 0; + neighbor->requests[irequest]->half = 1; + } else { + error->all(FLERR,"Cannot use chosen neighbor list style with reax/c/kk"); + } + +#ifdef DPD_USE_RAN_MARS + rand_pool.init(random,seed); +#else + rand_pool.init(seed + comm->me,4*32768 /*fake max_hardware_threads()*/); +#endif +} +#endif + /* ---------------------------------------------------------------------- */ template From 635c448b61bd0279c567ee4426fff6c6ee1ef88d Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Fri, 3 Mar 2017 14:57:35 -0500 Subject: [PATCH 184/439] USER-DPD: sort bins for deterministic SSA instead of using Kokkos::Serial --- src/KOKKOS/nbin_ssa_kokkos.cpp | 85 +++++++++++++++++++++++++++++----- src/KOKKOS/nbin_ssa_kokkos.h | 6 +++ 2 files changed, 79 insertions(+), 12 deletions(-) diff --git a/src/KOKKOS/nbin_ssa_kokkos.cpp b/src/KOKKOS/nbin_ssa_kokkos.cpp index 53f3f2fc80..afe016c3f7 100644 --- a/src/KOKKOS/nbin_ssa_kokkos.cpp +++ b/src/KOKKOS/nbin_ssa_kokkos.cpp @@ -114,7 +114,6 @@ void NBinSSAKokkos::bin_atoms() { last_bin = update->ntimestep; - int i; int nlocal = atom->nlocal; int nghost = atom->nghost; int nall = nlocal + nghost; @@ -170,19 +169,17 @@ void NBinSSAKokkos::bin_atoms() k_gbincount.sync(); DeviceType::fence(); // FIXME? - Kokkos::parallel_for( -#ifdef ALLOW_NON_DETERMINISTIC_SSA - Kokkos::RangePolicy(nlocal,nall) -#else - Kokkos::RangePolicy(nlocal,nall) -#endif - , KOKKOS_LAMBDA (const int i) { + Kokkos::parallel_for(Kokkos::RangePolicy(nlocal,nall), + KOKKOS_LAMBDA (const int i) { const int iAIR = binID(i); if (iAIR > 0) { // include only ghost atoms in an AIR const int ac = Kokkos::atomic_fetch_add(&gbincount[iAIR], (int)1); gbins(iAIR, ac) = i; } }); +#ifndef ALLOW_NON_DETERMINISTIC_DPD + Kokkos::parallel_for(Kokkos::RangePolicy(1,8), KOKKOS_LAMBDA (const int i) { sortGhostBin(i); }); +#endif DeviceType::fence(); } c_gbins = gbins; // gbins won't change until the next bin_atoms @@ -200,13 +197,11 @@ void NBinSSAKokkos::bin_atoms() DeviceType::fence(); NPairSSAKokkosBinAtomsFunctor f(*this); -#ifdef ALLOW_NON_DETERMINISTIC_SSA Kokkos::parallel_for(nlocal, f); -#else - Kokkos::parallel_for(Kokkos::RangePolicy(0, nlocal), f); +#ifndef ALLOW_NON_DETERMINISTIC_DPD + Kokkos::parallel_for(mbins, KOKKOS_LAMBDA (const int i) { sortAtomBin(i); }); #endif DeviceType::fence(); - } c_bins = bins; // bins won't change until the next bin_atoms @@ -258,6 +253,72 @@ void NBinSSAKokkos::binIDGhostsItem(const int &i, int &update) const } } +// An implementation of heapsort without recursion +template +KOKKOS_INLINE_FUNCTION +void NBinSSAKokkos::sortAtomBin(const int &ibin) const +{ + int n = bincount(ibin); + int i = n/2; + int t; + + do { /* Loops until bin is sorted */ + if (i > 0) { /* First stage - Sorting the heap */ + i--; /* Save its index to i */ + t = bins(ibin, i); /* Save parent value to t */ + } else { /* Second stage - Extracting elements in-place */ + if ((--n) <= 0) return; /* When the heap is empty, we are done */ + t = bins(ibin, n); /* Save last value (it will be overwritten) */ + bins(ibin, n) = bins(ibin, 0); /* Save largest value at the end of the bin */ + } + int parent = i; /* We will start pushing down t from parent */ + int child = i*2 + 1; /* parent's left child */ + /* Sift operation - pushing the value of t down the heap */ + while (child < n) { + /* Choose the largest child */ + if ((child + 1 < n) && (bins(ibin, child + 1) > bins(ibin, child))) ++child; + if (bins(ibin, child) <= t) break; /* t's place is found */ + bins(ibin, parent) = bins(ibin, child); /* Move the largest child up */ + parent = child; /* Move parent pointer to this child */ + child = parent*2+1; /* Find the next child */ + } + bins(ibin, parent) = t; /* We save t in the heap */ + } while(1); +} + +// An implementation of heapsort without recursion +template +KOKKOS_INLINE_FUNCTION +void NBinSSAKokkos::sortGhostBin(const int &ibin) const +{ + int n = gbincount(ibin); + int i = n/2; + int t; + + do { /* Loops until bin is sorted */ + if (i > 0) { /* First stage - Sorting the heap */ + i--; /* Save its index to i */ + t = gbins(ibin, i); /* Save parent value to t */ + } else { /* Second stage - Extracting elements in-place */ + if (--n <= 0) return; /* When the heap is empty, we are done */ + t = gbins(ibin, n); /* Save last value (it will be overwritten) */ + gbins(ibin, n) = gbins(ibin, 0); /* Save largest value at the end of the bin */ + } + int parent = i; /* We will start pushing down t from parent */ + int child = i*2 + 1; /* parent's left child */ + /* Sift operation - pushing the value of t down the heap */ + while (child < n) { + /* Choose the largest child */ + if ((child + 1 < n) && (gbins(ibin, child + 1) > gbins(ibin, child))) ++child; + if (gbins(ibin, child) <= t) break; /* t's place is found */ + gbins(ibin, parent) = gbins(ibin, child); /* Move the largest child up */ + parent = child; /* Move parent pointer to this child */ + child = parent*2+1; /* Find the next child */ + } + gbins(ibin, parent) = t; /* We save t in the heap */ + } while(1); +} + namespace LAMMPS_NS { template class NBinSSAKokkos; #ifdef KOKKOS_HAVE_CUDA diff --git a/src/KOKKOS/nbin_ssa_kokkos.h b/src/KOKKOS/nbin_ssa_kokkos.h index 69f05c9304..add400c573 100644 --- a/src/KOKKOS/nbin_ssa_kokkos.h +++ b/src/KOKKOS/nbin_ssa_kokkos.h @@ -88,6 +88,12 @@ class NBinSSAKokkos : public NBinStandard { KOKKOS_INLINE_FUNCTION void binIDGhostsItem(const int &i, int &update) const; + KOKKOS_INLINE_FUNCTION + void sortAtomBin(const int &ibin) const; + + KOKKOS_INLINE_FUNCTION + void sortGhostBin(const int &ibin) const; + /* ---------------------------------------------------------------------- convert atom coords into the ssa active interaction region number ------------------------------------------------------------------------- */ From b35895ca128b375595d3da401a88f842b8ad63bf Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Fri, 3 Mar 2017 15:21:09 -0500 Subject: [PATCH 185/439] USER-DPD Kokkos: Remove the SSA's ALLOW_NON_DETERMINISTIC_DPD option. There was no measurable performance benefit to turning it on. --- src/KOKKOS/nbin_ssa_kokkos.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/KOKKOS/nbin_ssa_kokkos.cpp b/src/KOKKOS/nbin_ssa_kokkos.cpp index afe016c3f7..0f4a3b8d4f 100644 --- a/src/KOKKOS/nbin_ssa_kokkos.cpp +++ b/src/KOKKOS/nbin_ssa_kokkos.cpp @@ -177,9 +177,7 @@ void NBinSSAKokkos::bin_atoms() gbins(iAIR, ac) = i; } }); -#ifndef ALLOW_NON_DETERMINISTIC_DPD Kokkos::parallel_for(Kokkos::RangePolicy(1,8), KOKKOS_LAMBDA (const int i) { sortGhostBin(i); }); -#endif DeviceType::fence(); } c_gbins = gbins; // gbins won't change until the next bin_atoms @@ -198,9 +196,7 @@ void NBinSSAKokkos::bin_atoms() NPairSSAKokkosBinAtomsFunctor f(*this); Kokkos::parallel_for(nlocal, f); -#ifndef ALLOW_NON_DETERMINISTIC_DPD Kokkos::parallel_for(mbins, KOKKOS_LAMBDA (const int i) { sortAtomBin(i); }); -#endif DeviceType::fence(); } c_bins = bins; // bins won't change until the next bin_atoms From c2c22fc2ede651fe5b9da1f7c45a4c05ab543951 Mon Sep 17 00:00:00 2001 From: Dan Ibanez Date: Mon, 6 Mar 2017 10:57:19 -0700 Subject: [PATCH 186/439] add missing KOKKOS_INLINE_FUNCTION to fix_shardlow --- src/KOKKOS/Install.sh | 4 ++-- src/KOKKOS/fix_shardlow_kokkos.cpp | 1 + src/KOKKOS/fix_shardlow_kokkos.h | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/KOKKOS/Install.sh b/src/KOKKOS/Install.sh index 68bd8d2ea8..5707a4e53c 100644 --- a/src/KOKKOS/Install.sh +++ b/src/KOKKOS/Install.sh @@ -28,8 +28,8 @@ action () { # force rebuild of files with LMP_KOKKOS switch -touch ../accelerator_kokkos.h -touch ../memory.h +#touch ../accelerator_kokkos.h +#touch ../memory.h # list of files with optional dependcies diff --git a/src/KOKKOS/fix_shardlow_kokkos.cpp b/src/KOKKOS/fix_shardlow_kokkos.cpp index 996f37257d..0dfbce5033 100644 --- a/src/KOKKOS/fix_shardlow_kokkos.cpp +++ b/src/KOKKOS/fix_shardlow_kokkos.cpp @@ -433,6 +433,7 @@ void FixShardlowKokkos::ssa_update_dpd( ------------------------------------------------------------------------- */ template template +KOKKOS_INLINE_FUNCTION void FixShardlowKokkos::ssa_update_dpde( int start_ii, int count, int id ) diff --git a/src/KOKKOS/fix_shardlow_kokkos.h b/src/KOKKOS/fix_shardlow_kokkos.h index c4711f5b8b..4dc47709e1 100644 --- a/src/KOKKOS/fix_shardlow_kokkos.h +++ b/src/KOKKOS/fix_shardlow_kokkos.h @@ -124,6 +124,7 @@ class FixShardlowKokkos : public FixShardlow { // template // void ssa_update_dpd(int, int); // Constant Temperature template + KOKKOS_INLINE_FUNCTION void ssa_update_dpde(int, int, int); // Constant Energy }; From 3e8cfb8247fdf7bb19ac21edfd971b3188f4881c Mon Sep 17 00:00:00 2001 From: Dan Ibanez Date: Mon, 6 Mar 2017 11:04:47 -0700 Subject: [PATCH 187/439] The wonders of git commit -a --- src/KOKKOS/Install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/KOKKOS/Install.sh b/src/KOKKOS/Install.sh index 5707a4e53c..68bd8d2ea8 100644 --- a/src/KOKKOS/Install.sh +++ b/src/KOKKOS/Install.sh @@ -28,8 +28,8 @@ action () { # force rebuild of files with LMP_KOKKOS switch -#touch ../accelerator_kokkos.h -#touch ../memory.h +touch ../accelerator_kokkos.h +touch ../memory.h # list of files with optional dependcies From 4a6f27935d26567203c595fdf8214c89f4e94643 Mon Sep 17 00:00:00 2001 From: Dan Ibanez Date: Mon, 6 Mar 2017 14:58:40 -0700 Subject: [PATCH 188/439] fix lambda syntax for CUDA KOKKOS_LAMBDA doesn't quite work on CUDA, you have to use LAMMPS_LAMBDA. Also, if you do use LAMMPS_LAMBDA, you need to run on the default device type, i.e. no using lambdas to run on OpenMP when LAMMPS has been compiled for CUDA. --- src/KOKKOS/fix_shardlow_kokkos.cpp | 10 +++++----- src/KOKKOS/nbin_ssa_kokkos.cpp | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/KOKKOS/fix_shardlow_kokkos.cpp b/src/KOKKOS/fix_shardlow_kokkos.cpp index 0dfbce5033..bf026552fa 100644 --- a/src/KOKKOS/fix_shardlow_kokkos.cpp +++ b/src/KOKKOS/fix_shardlow_kokkos.cpp @@ -677,13 +677,13 @@ void FixShardlowKokkos::initial_integrate(int vflag) int workItemCt = ssa_phaseLen[workPhase]; if(atom->ntypes > MAX_TYPES_STACKPARAMS) { - Kokkos::parallel_for(workItemCt, KOKKOS_LAMBDA (const int workItem ) { + Kokkos::parallel_for(workItemCt, LAMMPS_LAMBDA (const int workItem ) { int ct = ssa_itemLen(workPhase, workItem); int ii = ssa_itemLoc(workPhase, workItem); ssa_update_dpde(ii, ct, workItem); }); } else { - Kokkos::parallel_for(workItemCt, KOKKOS_LAMBDA (const int workItem ) { + Kokkos::parallel_for(workItemCt, LAMMPS_LAMBDA (const int workItem ) { int ct = ssa_itemLen(workPhase, workItem); int ii = ssa_itemLoc(workPhase, workItem); ssa_update_dpde(ii, ct, workItem); @@ -704,7 +704,7 @@ void FixShardlowKokkos::initial_integrate(int vflag) // memset(&(atom->uCond[nlocal]), 0, sizeof(double)*nghost); // memset(&(atom->uMech[nlocal]), 0, sizeof(double)*nghost); - Kokkos::parallel_for(Kokkos::RangePolicy(nlocal,nlocal+nghost), KOKKOS_LAMBDA (const int i) { + Kokkos::parallel_for(Kokkos::RangePolicy(nlocal,nlocal+nghost), LAMMPS_LAMBDA (const int i) { uCond(i) = 0.0; uMech(i) = 0.0; }); @@ -713,13 +713,13 @@ void FixShardlowKokkos::initial_integrate(int vflag) // process neighbors in this AIR if(atom->ntypes > MAX_TYPES_STACKPARAMS) { - Kokkos::parallel_for(workItemCt, KOKKOS_LAMBDA (const int workItem ) { + Kokkos::parallel_for(workItemCt, LAMMPS_LAMBDA (const int workItem ) { int ct = ssa_gitemLen(workPhase, workItem); int ii = ssa_gitemLoc(workPhase, workItem); ssa_update_dpde(ii, ct, workItem); }); } else { - Kokkos::parallel_for(workItemCt, KOKKOS_LAMBDA (const int workItem ) { + Kokkos::parallel_for(workItemCt, LAMMPS_LAMBDA (const int workItem ) { int ct = ssa_gitemLen(workPhase, workItem); int ii = ssa_gitemLoc(workPhase, workItem); ssa_update_dpde(ii, ct, workItem); diff --git a/src/KOKKOS/nbin_ssa_kokkos.cpp b/src/KOKKOS/nbin_ssa_kokkos.cpp index 0f4a3b8d4f..b0e2d5be88 100644 --- a/src/KOKKOS/nbin_ssa_kokkos.cpp +++ b/src/KOKKOS/nbin_ssa_kokkos.cpp @@ -155,7 +155,7 @@ void NBinSSAKokkos::bin_atoms() DeviceType::fence(); // FIXME? ghosts_per_gbin = 0; NPairSSAKokkosBinIDGhostsFunctor f(*this); - Kokkos::parallel_reduce(Kokkos::RangePolicy(nlocal,nall), f, ghosts_per_gbin); + Kokkos::parallel_reduce(Kokkos::RangePolicy(nlocal,nall), f, ghosts_per_gbin); } // actually bin the ghost atoms @@ -169,15 +169,15 @@ void NBinSSAKokkos::bin_atoms() k_gbincount.sync(); DeviceType::fence(); // FIXME? - Kokkos::parallel_for(Kokkos::RangePolicy(nlocal,nall), - KOKKOS_LAMBDA (const int i) { + Kokkos::parallel_for(Kokkos::RangePolicy(nlocal,nall), + LAMMPS_LAMBDA (const int i) { const int iAIR = binID(i); if (iAIR > 0) { // include only ghost atoms in an AIR const int ac = Kokkos::atomic_fetch_add(&gbincount[iAIR], (int)1); gbins(iAIR, ac) = i; } }); - Kokkos::parallel_for(Kokkos::RangePolicy(1,8), KOKKOS_LAMBDA (const int i) { sortGhostBin(i); }); + Kokkos::parallel_for(Kokkos::RangePolicy(1,8), LAMMPS_LAMBDA (const int i) { sortGhostBin(i); }); DeviceType::fence(); } c_gbins = gbins; // gbins won't change until the next bin_atoms @@ -196,7 +196,7 @@ void NBinSSAKokkos::bin_atoms() NPairSSAKokkosBinAtomsFunctor f(*this); Kokkos::parallel_for(nlocal, f); - Kokkos::parallel_for(mbins, KOKKOS_LAMBDA (const int i) { sortAtomBin(i); }); + Kokkos::parallel_for(mbins, LAMMPS_LAMBDA (const int i) { sortAtomBin(i); }); DeviceType::fence(); } c_bins = bins; // bins won't change until the next bin_atoms From a7d1b571be0ae8969911cba9cf4b4d5a9b879948 Mon Sep 17 00:00:00 2001 From: Dan Ibanez Date: Mon, 6 Mar 2017 15:07:07 -0700 Subject: [PATCH 189/439] don't capture "this" in lambdas CUDA lambdas can't capture the calling object very well. make local shallow copies of variables needed. --- src/KOKKOS/nbin_ssa_kokkos.cpp | 21 +++++++++++++++------ src/KOKKOS/nbin_ssa_kokkos.h | 7 +++++-- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/KOKKOS/nbin_ssa_kokkos.cpp b/src/KOKKOS/nbin_ssa_kokkos.cpp index b0e2d5be88..8c991cc0c2 100644 --- a/src/KOKKOS/nbin_ssa_kokkos.cpp +++ b/src/KOKKOS/nbin_ssa_kokkos.cpp @@ -169,16 +169,22 @@ void NBinSSAKokkos::bin_atoms() k_gbincount.sync(); DeviceType::fence(); // FIXME? + auto binID_ = binID; + auto gbincount_ = gbincount; + auto gbins_ = gbins; + Kokkos::parallel_for(Kokkos::RangePolicy(nlocal,nall), LAMMPS_LAMBDA (const int i) { - const int iAIR = binID(i); + const int iAIR = binID_(i); if (iAIR > 0) { // include only ghost atoms in an AIR - const int ac = Kokkos::atomic_fetch_add(&gbincount[iAIR], (int)1); - gbins(iAIR, ac) = i; + const int ac = Kokkos::atomic_fetch_add(&gbincount_[iAIR], (int)1); + gbins_(iAIR, ac) = i; } }); - Kokkos::parallel_for(Kokkos::RangePolicy(1,8), LAMMPS_LAMBDA (const int i) { sortGhostBin(i); }); - DeviceType::fence(); + Kokkos::parallel_for(Kokkos::RangePolicy(1,8), + LAMMPS_LAMBDA (const int i) { + sortGhostBin(gbincount_, gbins_, i); + }); } c_gbins = gbins; // gbins won't change until the next bin_atoms @@ -285,7 +291,10 @@ void NBinSSAKokkos::sortAtomBin(const int &ibin) const // An implementation of heapsort without recursion template KOKKOS_INLINE_FUNCTION -void NBinSSAKokkos::sortGhostBin(const int &ibin) const +void NBinSSAKokkos::sortGhostBin( + typename AT::t_int_1d gbincount, + typename AT::t_int_2d gbins, + const int &ibin) { int n = gbincount(ibin); int i = n/2; diff --git a/src/KOKKOS/nbin_ssa_kokkos.h b/src/KOKKOS/nbin_ssa_kokkos.h index add400c573..ca1f81953f 100644 --- a/src/KOKKOS/nbin_ssa_kokkos.h +++ b/src/KOKKOS/nbin_ssa_kokkos.h @@ -91,8 +91,11 @@ class NBinSSAKokkos : public NBinStandard { KOKKOS_INLINE_FUNCTION void sortAtomBin(const int &ibin) const; - KOKKOS_INLINE_FUNCTION - void sortGhostBin(const int &ibin) const; + static KOKKOS_INLINE_FUNCTION + void sortGhostBin( + typename AT::t_int_1d gbincount, + typename AT::t_int_2d gbins, + const int &ibin); /* ---------------------------------------------------------------------- convert atom coords into the ssa active interaction region number From 3e3a24da48d41227f5bfc12f3337a0a39ce7e948 Mon Sep 17 00:00:00 2001 From: Dan Ibanez Date: Mon, 6 Mar 2017 15:28:25 -0700 Subject: [PATCH 190/439] consolidate sorting functions two sort functions with different names but identical functionality. making them the same function until we descide to use a different algorithm for atoms and ghosts --- src/KOKKOS/nbin_ssa_kokkos.cpp | 48 ++++++++-------------------------- src/KOKKOS/nbin_ssa_kokkos.h | 5 +--- 2 files changed, 12 insertions(+), 41 deletions(-) diff --git a/src/KOKKOS/nbin_ssa_kokkos.cpp b/src/KOKKOS/nbin_ssa_kokkos.cpp index 8c991cc0c2..1fcbbed601 100644 --- a/src/KOKKOS/nbin_ssa_kokkos.cpp +++ b/src/KOKKOS/nbin_ssa_kokkos.cpp @@ -183,7 +183,7 @@ void NBinSSAKokkos::bin_atoms() }); Kokkos::parallel_for(Kokkos::RangePolicy(1,8), LAMMPS_LAMBDA (const int i) { - sortGhostBin(gbincount_, gbins_, i); + sortBin(gbincount_, gbins_, i); }); } c_gbins = gbins; // gbins won't change until the next bin_atoms @@ -200,9 +200,16 @@ void NBinSSAKokkos::bin_atoms() Kokkos::parallel_for(mbins, f_zero); DeviceType::fence(); + auto bincount_ = bincount; + auto bins_ = bins; + NPairSSAKokkosBinAtomsFunctor f(*this); Kokkos::parallel_for(nlocal, f); - Kokkos::parallel_for(mbins, LAMMPS_LAMBDA (const int i) { sortAtomBin(i); }); + + Kokkos::parallel_for(mbins, + LAMMPS_LAMBDA (const int i) { + sortBin(bincount_, bins_, i); + }); DeviceType::fence(); } c_bins = bins; // bins won't change until the next bin_atoms @@ -258,40 +265,7 @@ void NBinSSAKokkos::binIDGhostsItem(const int &i, int &update) const // An implementation of heapsort without recursion template KOKKOS_INLINE_FUNCTION -void NBinSSAKokkos::sortAtomBin(const int &ibin) const -{ - int n = bincount(ibin); - int i = n/2; - int t; - - do { /* Loops until bin is sorted */ - if (i > 0) { /* First stage - Sorting the heap */ - i--; /* Save its index to i */ - t = bins(ibin, i); /* Save parent value to t */ - } else { /* Second stage - Extracting elements in-place */ - if ((--n) <= 0) return; /* When the heap is empty, we are done */ - t = bins(ibin, n); /* Save last value (it will be overwritten) */ - bins(ibin, n) = bins(ibin, 0); /* Save largest value at the end of the bin */ - } - int parent = i; /* We will start pushing down t from parent */ - int child = i*2 + 1; /* parent's left child */ - /* Sift operation - pushing the value of t down the heap */ - while (child < n) { - /* Choose the largest child */ - if ((child + 1 < n) && (bins(ibin, child + 1) > bins(ibin, child))) ++child; - if (bins(ibin, child) <= t) break; /* t's place is found */ - bins(ibin, parent) = bins(ibin, child); /* Move the largest child up */ - parent = child; /* Move parent pointer to this child */ - child = parent*2+1; /* Find the next child */ - } - bins(ibin, parent) = t; /* We save t in the heap */ - } while(1); -} - -// An implementation of heapsort without recursion -template -KOKKOS_INLINE_FUNCTION -void NBinSSAKokkos::sortGhostBin( +void NBinSSAKokkos::sortBin( typename AT::t_int_1d gbincount, typename AT::t_int_2d gbins, const int &ibin) @@ -305,7 +279,7 @@ void NBinSSAKokkos::sortGhostBin( i--; /* Save its index to i */ t = gbins(ibin, i); /* Save parent value to t */ } else { /* Second stage - Extracting elements in-place */ - if (--n <= 0) return; /* When the heap is empty, we are done */ + if ((--n) <= 0) return; /* When the heap is empty, we are done */ t = gbins(ibin, n); /* Save last value (it will be overwritten) */ gbins(ibin, n) = gbins(ibin, 0); /* Save largest value at the end of the bin */ } diff --git a/src/KOKKOS/nbin_ssa_kokkos.h b/src/KOKKOS/nbin_ssa_kokkos.h index ca1f81953f..cc98859913 100644 --- a/src/KOKKOS/nbin_ssa_kokkos.h +++ b/src/KOKKOS/nbin_ssa_kokkos.h @@ -88,11 +88,8 @@ class NBinSSAKokkos : public NBinStandard { KOKKOS_INLINE_FUNCTION void binIDGhostsItem(const int &i, int &update) const; - KOKKOS_INLINE_FUNCTION - void sortAtomBin(const int &ibin) const; - static KOKKOS_INLINE_FUNCTION - void sortGhostBin( + void sortBin( typename AT::t_int_1d gbincount, typename AT::t_int_2d gbins, const int &ibin); From 527a573026d14fc068f0e44e8b676d98cd1816d6 Mon Sep 17 00:00:00 2001 From: Dan Ibanez Date: Mon, 6 Mar 2017 15:42:26 -0700 Subject: [PATCH 191/439] don't use device views to measure dimensions --- src/KOKKOS/nbin_ssa_kokkos.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/KOKKOS/nbin_ssa_kokkos.cpp b/src/KOKKOS/nbin_ssa_kokkos.cpp index 1fcbbed601..6c9e3a3446 100644 --- a/src/KOKKOS/nbin_ssa_kokkos.cpp +++ b/src/KOKKOS/nbin_ssa_kokkos.cpp @@ -72,7 +72,7 @@ NBinSSAKokkos::NBinSSAKokkos(LAMMPS *lmp) : NBinStandard(lmp) template void NBinSSAKokkos::bin_atoms_setup(int nall) { - if (mbins > (int) k_bins.d_view.dimension_0()) { + if (mbins > (int) k_bins.h_view.dimension_0()) { k_bins = DAT::tdual_int_2d("NBinSSAKokkos::bins",mbins,atoms_per_bin); bins = k_bins.view(); @@ -82,7 +82,7 @@ void NBinSSAKokkos::bin_atoms_setup(int nall) ghosts_per_gbin = atom->nghost / 7; // estimate needed size - if (ghosts_per_gbin > (int) k_gbins.d_view.dimension_1()) { + if (ghosts_per_gbin > (int) k_gbins.h_view.dimension_1()) { k_gbins = DAT::tdual_int_2d("NBinSSAKokkos::gbins",8,ghosts_per_gbin); gbins = k_gbins.view(); } From b8c72c7bdb547c75c3fc4077353b8f15e4b7b240 Mon Sep 17 00:00:00 2001 From: Dan Ibanez Date: Mon, 6 Mar 2017 15:51:09 -0700 Subject: [PATCH 192/439] don't query device variables from the host --- src/KOKKOS/npair_ssa_kokkos.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/KOKKOS/npair_ssa_kokkos.cpp b/src/KOKKOS/npair_ssa_kokkos.cpp index 7eea57d492..a9b59bfc96 100644 --- a/src/KOKKOS/npair_ssa_kokkos.cpp +++ b/src/KOKKOS/npair_ssa_kokkos.cpp @@ -83,12 +83,12 @@ void NPairSSAKokkos::copy_bin_info() k_gbincount = nbKK->k_gbincount; k_gbins = nbKK->k_gbins; - lbinxlo = nbKK->d_lbinxlo(); - lbinxhi = nbKK->d_lbinxhi(); - lbinylo = nbKK->d_lbinylo(); - lbinyhi = nbKK->d_lbinyhi(); - lbinzlo = nbKK->d_lbinzlo(); - lbinzhi = nbKK->d_lbinzhi(); + lbinxlo = nbKK->h_lbinxlo(); + lbinxhi = nbKK->h_lbinxhi(); + lbinylo = nbKK->h_lbinylo(); + lbinyhi = nbKK->h_lbinyhi(); + lbinzlo = nbKK->h_lbinzlo(); + lbinzhi = nbKK->h_lbinzhi(); } /* ---------------------------------------------------------------------- From d01f09dce237dabe50e22d78881380676db3451a Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Tue, 7 Mar 2017 15:23:17 -0500 Subject: [PATCH 193/439] Turn off use of OpenMP in MPIIO/dump_custom_mpiio.cpp if Kokkos is in use. The convert_string_omp() method breaks when Kokkos is also using OpenMP. --- src/MPIIO/dump_custom_mpiio.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/MPIIO/dump_custom_mpiio.cpp b/src/MPIIO/dump_custom_mpiio.cpp index 6e48bfa146..0b282b77ef 100644 --- a/src/MPIIO/dump_custom_mpiio.cpp +++ b/src/MPIIO/dump_custom_mpiio.cpp @@ -542,8 +542,8 @@ void DumpCustomMPIIO::write_string(int n, double *mybuf) #if defined(_OPENMP) int nthreads = omp_get_max_threads(); - if (nthreads > 1) - nsme = convert_string_omp(n,mybuf); + if ((nthreads > 1) && !(lmp->kokkos)) + nsme = convert_string_omp(n,mybuf); // not (yet) compatible with Kokkos else nsme = convert_string(n,mybuf); #else From fc23f9cfe897f383db0fa48ce28ea7a2dceb34e8 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Wed, 8 Mar 2017 13:07:52 -0700 Subject: [PATCH 194/439] Disable allocation of per-atom arrays in ev_setup for USER-DPD Kokkos styles --- src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp | 2 +- src/KOKKOS/pair_exp6_rx_kokkos.cpp | 2 +- src/KOKKOS/pair_hybrid_kokkos.cpp | 2 +- src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp | 2 +- src/KOKKOS/pair_table_rx_kokkos.cpp | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp b/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp index 99a364eb86..bd0f08efa6 100644 --- a/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp +++ b/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp @@ -161,7 +161,7 @@ void PairDPDfdtEnergyKokkos::compute(int eflag_in, int vflag_in) vflag = vflag_in; if (neighflag == FULL) no_virial_fdotr_compute = 1; - if (eflag || vflag) ev_setup(eflag,vflag); + if (eflag || vflag) ev_setup(eflag,vflag,0); else evflag = vflag_fdotr = 0; // reallocate per-atom arrays if necessary diff --git a/src/KOKKOS/pair_exp6_rx_kokkos.cpp b/src/KOKKOS/pair_exp6_rx_kokkos.cpp index 962dcfd031..4b0748721c 100644 --- a/src/KOKKOS/pair_exp6_rx_kokkos.cpp +++ b/src/KOKKOS/pair_exp6_rx_kokkos.cpp @@ -127,7 +127,7 @@ void PairExp6rxKokkos::compute(int eflag_in, int vflag_in) vflag = vflag_in; if (neighflag == FULL) no_virial_fdotr_compute = 1; - if (eflag || vflag) ev_setup(eflag,vflag); + if (eflag || vflag) ev_setup(eflag,vflag,0); else evflag = vflag_fdotr = 0; // reallocate per-atom arrays if necessary diff --git a/src/KOKKOS/pair_hybrid_kokkos.cpp b/src/KOKKOS/pair_hybrid_kokkos.cpp index 337b56c6ce..629eee156a 100644 --- a/src/KOKKOS/pair_hybrid_kokkos.cpp +++ b/src/KOKKOS/pair_hybrid_kokkos.cpp @@ -77,7 +77,7 @@ void PairHybridKokkos::compute(int eflag, int vflag) if (no_virial_fdotr_compute && vflag % 4 == 2) vflag = 1 + vflag/4 * 4; - if (eflag || vflag) ev_setup(eflag,vflag); + if (eflag || vflag) ev_setup(eflag,vflag,0); else evflag = vflag_fdotr = eflag_global = vflag_global = eflag_atom = vflag_atom = 0; diff --git a/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp b/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp index 11dbfabf3a..4379cc4001 100644 --- a/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp +++ b/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp @@ -147,7 +147,7 @@ void PairMultiLucyRXKokkos::compute_style(int eflag_in, int vflag_in vflag = vflag_in; if (neighflag == FULL) no_virial_fdotr_compute = 1; - if (eflag || vflag) ev_setup(eflag,vflag); + if (eflag || vflag) ev_setup(eflag,vflag,0); else evflag = vflag_fdotr = 0; // reallocate per-atom arrays if necessary diff --git a/src/KOKKOS/pair_table_rx_kokkos.cpp b/src/KOKKOS/pair_table_rx_kokkos.cpp index 2a1ee2c0b1..cbb1096712 100644 --- a/src/KOKKOS/pair_table_rx_kokkos.cpp +++ b/src/KOKKOS/pair_table_rx_kokkos.cpp @@ -627,7 +627,7 @@ void PairTableRXKokkos::compute_style(int eflag_in, int vflag_in) if (neighflag == FULL) no_virial_fdotr_compute = 1; - if (eflag || vflag) ev_setup(eflag,vflag); + if (eflag || vflag) ev_setup(eflag,vflag,0); else evflag = vflag_fdotr = 0; if (eflag_atom) { From 35e1cf1d6e006b4c4508c9eb34caa8563a0418e3 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Wed, 8 Mar 2017 20:02:02 -0700 Subject: [PATCH 195/439] Fixing issue with ev_setup in pair_hybrid_kokkos --- src/KOKKOS/pair_hybrid_kokkos.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/KOKKOS/pair_hybrid_kokkos.cpp b/src/KOKKOS/pair_hybrid_kokkos.cpp index 629eee156a..337b56c6ce 100644 --- a/src/KOKKOS/pair_hybrid_kokkos.cpp +++ b/src/KOKKOS/pair_hybrid_kokkos.cpp @@ -77,7 +77,7 @@ void PairHybridKokkos::compute(int eflag, int vflag) if (no_virial_fdotr_compute && vflag % 4 == 2) vflag = 1 + vflag/4 * 4; - if (eflag || vflag) ev_setup(eflag,vflag,0); + if (eflag || vflag) ev_setup(eflag,vflag); else evflag = vflag_fdotr = eflag_global = vflag_global = eflag_atom = vflag_atom = 0; From 6f71275db30fcea912d9fb37fb13ab0608cc9d1b Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Thu, 9 Mar 2017 15:35:07 -0700 Subject: [PATCH 196/439] Add Kokkos version of atom_vec_hybrid_kokkos, without CUDA support --- src/KOKKOS/Install.sh | 2 + src/KOKKOS/atom_kokkos.cpp | 1 + src/KOKKOS/atom_kokkos.h | 1 + src/KOKKOS/atom_vec_hybrid_kokkos.cpp | 1191 +++++++++++++++++++++++++ src/KOKKOS/atom_vec_hybrid_kokkos.h | 161 ++++ 5 files changed, 1356 insertions(+) create mode 100644 src/KOKKOS/atom_vec_hybrid_kokkos.cpp create mode 100644 src/KOKKOS/atom_vec_hybrid_kokkos.h diff --git a/src/KOKKOS/Install.sh b/src/KOKKOS/Install.sh index 68bd8d2ea8..9c11e9321b 100644 --- a/src/KOKKOS/Install.sh +++ b/src/KOKKOS/Install.sh @@ -53,6 +53,8 @@ action atom_vec_dpd_kokkos.cpp atom_vec_dpd.cpp action atom_vec_dpd_kokkos.h atom_vec_dpd.h action atom_vec_full_kokkos.cpp atom_vec_full.cpp action atom_vec_full_kokkos.h atom_vec_full.h +action atom_vec_hybrid_kokkos.cpp +action atom_vec_hybrid_kokkos.h action atom_vec_kokkos.cpp action atom_vec_kokkos.h action atom_vec_molecular_kokkos.cpp atom_vec_molecular.cpp diff --git a/src/KOKKOS/atom_kokkos.cpp b/src/KOKKOS/atom_kokkos.cpp index 97b76ba67c..31b33dbdc9 100644 --- a/src/KOKKOS/atom_kokkos.cpp +++ b/src/KOKKOS/atom_kokkos.cpp @@ -49,6 +49,7 @@ AtomKokkos::~AtomKokkos() memory->destroy_kokkos(k_radius, radius); memory->destroy_kokkos(k_rmass, rmass); memory->destroy_kokkos(k_omega, omega); + memory->destroy_kokkos(k_angmom, angmom); memory->destroy_kokkos(k_torque, torque); memory->destroy_kokkos(k_nspecial, nspecial); diff --git a/src/KOKKOS/atom_kokkos.h b/src/KOKKOS/atom_kokkos.h index cf454bcd0c..2245023189 100644 --- a/src/KOKKOS/atom_kokkos.h +++ b/src/KOKKOS/atom_kokkos.h @@ -34,6 +34,7 @@ class AtomKokkos : public Atom { DAT::tdual_float_1d k_radius; DAT::tdual_float_1d k_rmass; DAT::tdual_v_array k_omega; + DAT::tdual_v_array k_angmom; DAT::tdual_f_array k_torque; DAT::tdual_tagint_1d k_molecule; DAT::tdual_int_2d k_nspecial; diff --git a/src/KOKKOS/atom_vec_hybrid_kokkos.cpp b/src/KOKKOS/atom_vec_hybrid_kokkos.cpp new file mode 100644 index 0000000000..0c9d261be5 --- /dev/null +++ b/src/KOKKOS/atom_vec_hybrid_kokkos.cpp @@ -0,0 +1,1191 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include +#include +#include "atom_vec_kokkos.h" +#include "atom_vec_hybrid_kokkos.h" +#include "atom_kokkos.h" +#include "domain.h" +#include "modify.h" +#include "fix.h" +#include "memory.h" +#include "error.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +AtomVecHybridKokkos::AtomVecHybridKokkos(LAMMPS *lmp) : AtomVecKokkos(lmp) {} + +/* ---------------------------------------------------------------------- */ + +AtomVecHybridKokkos::~AtomVecHybridKokkos() +{ + for (int k = 0; k < nstyles; k++) delete styles[k]; + delete [] styles; + for (int k = 0; k < nstyles; k++) delete [] keywords[k]; + delete [] keywords; +} + +/* ---------------------------------------------------------------------- + process sub-style args +------------------------------------------------------------------------- */ + +void AtomVecHybridKokkos::process_args(int narg, char **arg) +{ + // build list of all known atom styles + + build_styles(); + + // allocate list of sub-styles as big as possibly needed if no extra args + + styles = new AtomVec*[narg]; + keywords = new char*[narg]; + + // allocate each sub-style + // call process_args() with set of args that are not atom style names + // use known_style() to determine which args these are + + int i,jarg,dummy; + + int iarg = 0; + nstyles = 0; + while (iarg < narg) { + if (strcmp(arg[iarg],"hybrid") == 0) + error->all(FLERR,"Atom style hybrid cannot have hybrid as an argument"); + for (i = 0; i < nstyles; i++) + if (strcmp(arg[iarg],keywords[i]) == 0) + error->all(FLERR,"Atom style hybrid cannot use same atom style twice"); + styles[nstyles] = atom->new_avec(arg[iarg],1,dummy); + keywords[nstyles] = new char[strlen(arg[iarg])+1]; + strcpy(keywords[nstyles],arg[iarg]); + jarg = iarg + 1; + while (jarg < narg && !known_style(arg[jarg])) jarg++; + styles[nstyles]->process_args(jarg-iarg-1,&arg[iarg+1]); + iarg = jarg; + nstyles++; + } + + // free allstyles created by build_styles() + + for (int i = 0; i < nallstyles; i++) delete [] allstyles[i]; + delete [] allstyles; + + // hybrid settings are MAX or MIN of sub-style settings + // hybrid sizes are minimal values plus extra values for each sub-style + + molecular = 0; + comm_x_only = comm_f_only = 1; + + size_forward = 3; + size_reverse = 3; + size_border = 6; + size_data_atom = 5; + size_data_vel = 4; + xcol_data = 3; + + for (int k = 0; k < nstyles; k++) { + if ((styles[k]->molecular == 1 && molecular == 2) || + (styles[k]->molecular == 2 && molecular == 1)) + error->all(FLERR,"Cannot mix molecular and molecule template " + "atom styles"); + molecular = MAX(molecular,styles[k]->molecular); + + bonds_allow = MAX(bonds_allow,styles[k]->bonds_allow); + angles_allow = MAX(angles_allow,styles[k]->angles_allow); + dihedrals_allow = MAX(dihedrals_allow,styles[k]->dihedrals_allow); + impropers_allow = MAX(impropers_allow,styles[k]->impropers_allow); + mass_type = MAX(mass_type,styles[k]->mass_type); + dipole_type = MAX(dipole_type,styles[k]->dipole_type); + forceclearflag = MAX(forceclearflag,styles[k]->forceclearflag); + + if (styles[k]->molecular == 2) onemols = styles[k]->onemols; + + comm_x_only = MIN(comm_x_only,styles[k]->comm_x_only); + comm_f_only = MIN(comm_f_only,styles[k]->comm_f_only); + size_forward += styles[k]->size_forward - 3; + size_reverse += styles[k]->size_reverse - 3; + size_border += styles[k]->size_border - 6; + size_data_atom += styles[k]->size_data_atom - 5; + size_data_vel += styles[k]->size_data_vel - 4; + } + + size_velocity = 3; + if (atom->omega_flag) size_velocity += 3; + if (atom->angmom_flag) size_velocity += 3; +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecHybridKokkos::init() +{ + AtomVec::init(); + for (int k = 0; k < nstyles; k++) styles[k]->init(); + +#ifdef KOKKOS_HAVE_CUDA + error->all(FLERR,"AtomVecHybridKokkos doesn't yet support CUDA"); +#endif +} + +/* ---------------------------------------------------------------------- + grow atom arrays + n = 0 grows arrays by a chunk + n > 0 allocates arrays to size n +------------------------------------------------------------------------- */ + +void AtomVecHybridKokkos::grow(int n) +{ + if (n == 0) grow_nmax(); + else nmax = n; + atom->nmax = nmax; + if (nmax < 0 || nmax > MAXSMALLINT) + error->one(FLERR,"Per-processor system is too big"); + + // sub-styles perform all reallocation + // turn off nextra_grow so hybrid can do that once below + + int tmp = atom->nextra_grow; + atom->nextra_grow = 0; + for (int k = 0; k < nstyles; k++) styles[k]->grow(nmax); + atom->nextra_grow = tmp; + + // insure hybrid local ptrs and sub-style ptrs are up to date + // for sub-styles, do this in case + // multiple sub-style reallocs of same array occurred + + grow_reset(); + + if (atom->nextra_grow) + for (int iextra = 0; iextra < atom->nextra_grow; iextra++) + modify->fix[atom->extra_grow[iextra]]->grow_arrays(nmax); +} + +/* ---------------------------------------------------------------------- + reset local array ptrs +------------------------------------------------------------------------- */ + +void AtomVecHybridKokkos::grow_reset() +{ + tag = atomKK->tag; + d_tag = atomKK->k_tag.d_view; + h_tag = atomKK->k_tag.h_view; + + type = atomKK->type; + d_type = atomKK->k_type.d_view; + h_type = atomKK->k_type.h_view; + + mask = atomKK->mask; + d_mask = atomKK->k_mask.d_view; + h_mask = atomKK->k_mask.h_view; + + image = atomKK->image; + d_image = atomKK->k_image.d_view; + h_image = atomKK->k_image.h_view; + + x = atomKK->x; + d_x = atomKK->k_x.d_view; + h_x = atomKK->k_x.h_view; + + v = atomKK->v; + d_v = atomKK->k_v.d_view; + h_v = atomKK->k_v.h_view; + + f = atomKK->f; + d_f = atomKK->k_f.d_view; + h_f = atomKK->k_f.h_view; + + v = atomKK->v; + d_v = atomKK->k_v.d_view; + h_v = atomKK->k_v.h_view; + + omega = atomKK->omega; + d_omega = atomKK->k_omega.d_view; + h_omega = atomKK->k_omega.h_view; + + angmom = atomKK->angmom; + d_angmom = atomKK->k_angmom.d_view; + h_angmom = atomKK->k_angmom.h_view; + + for (int k = 0; k < nstyles; k++) styles[k]->grow_reset(); +} + +/* ---------------------------------------------------------------------- + copy atom I info to atom J for all sub-styles +------------------------------------------------------------------------- */ + +void AtomVecHybridKokkos::copy(int i, int j, int delflag) +{ + int tmp = atom->nextra_grow; + atom->nextra_grow = 0; + for (int k = 0; k < nstyles; k++) styles[k]->copy(i,j,delflag); + atom->nextra_grow = tmp; + + if (atom->nextra_grow) + for (int iextra = 0; iextra < atom->nextra_grow; iextra++) + modify->fix[atom->extra_grow[iextra]]->copy_arrays(i,j,delflag); +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecHybridKokkos::clear_bonus() +{ + for (int k = 0; k < nstyles; k++) styles[k]->clear_bonus(); +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecHybridKokkos::force_clear(int n, size_t nbytes) +{ + for (int k = 0; k < nstyles; k++) + if (styles[k]->forceclearflag) styles[k]->force_clear(n,nbytes); +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecHybridKokkos::pack_comm_kokkos(const int &n, const DAT::tdual_int_2d &k_sendlist, + const int & iswap, + const DAT::tdual_xfloat_2d &buf, + const int &pbc_flag, const int pbc[]) +{ + error->all(FLERR,"AtomVecHybridKokkos doesn't yet support threaded comm"); +} +void AtomVecHybridKokkos::unpack_comm_kokkos(const int &n, const int &nfirst, + const DAT::tdual_xfloat_2d &buf) +{ + error->all(FLERR,"AtomVecHybridKokkos doesn't yet support threaded comm"); +} +int AtomVecHybridKokkos::pack_comm_self(const int &n, const DAT::tdual_int_2d &list, + const int & iswap, const int nfirst, + const int &pbc_flag, const int pbc[]) +{ + error->all(FLERR,"AtomVecHybridKokkos doesn't yet support threaded comm"); +} +int AtomVecHybridKokkos::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) +{ + error->all(FLERR,"AtomVecHybridKokkos doesn't yet support threaded comm"); +} +void AtomVecHybridKokkos::unpack_border_kokkos(const int &n, const int &nfirst, + const DAT::tdual_xfloat_2d &buf, + ExecutionSpace space) +{ + error->all(FLERR,"AtomVecHybridKokkos doesn't yet support threaded comm"); +} +int AtomVecHybridKokkos::pack_exchange_kokkos(const int &nsend,DAT::tdual_xfloat_2d &buf, + DAT::tdual_int_1d k_sendlist, + DAT::tdual_int_1d k_copylist, + ExecutionSpace space, int dim, + X_FLOAT lo, X_FLOAT hi) +{ + error->all(FLERR,"AtomVecHybridKokkos doesn't yet support threaded comm"); +} +int AtomVecHybridKokkos::unpack_exchange_kokkos(DAT::tdual_xfloat_2d &k_buf, int nrecv, + int nlocal, int dim, X_FLOAT lo, X_FLOAT hi, + ExecutionSpace space) +{ + error->all(FLERR,"AtomVecHybridKokkos doesn't yet support threaded comm"); +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecHybridKokkos::pack_comm(int n, int *list, double *buf, + int pbc_flag, int *pbc) +{ + int i,j,k,m; + double dx,dy,dz; + + m = 0; + if (pbc_flag == 0) { + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = h_x(j,0); + buf[m++] = h_x(j,1); + buf[m++] = h_x(j,2); + } + } else { + if (domain->triclinic == 0) { + dx = pbc[0]*domain->xprd; + dy = pbc[1]*domain->yprd; + dz = pbc[2]*domain->zprd; + } else { + dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz; + dy = pbc[1]*domain->yprd + pbc[3]*domain->yz; + dz = pbc[2]*domain->zprd; + } + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = h_x(j,0) + dx; + buf[m++] = h_x(j,1) + dy; + buf[m++] = h_x(j,2) + dz; + } + } + + // pack sub-style contributions as contiguous chunks + + for (k = 0; k < nstyles; k++) + m += styles[k]->pack_comm_hybrid(n,list,&buf[m]); + + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecHybridKokkos::pack_comm_vel(int n, int *list, double *buf, + int pbc_flag, int *pbc) +{ + int i,j,k,m; + double dx,dy,dz,dvx,dvy,dvz; + int omega_flag = atom->omega_flag; + int angmom_flag = atom->angmom_flag; + + m = 0; + if (pbc_flag == 0) { + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = h_x(j,0); + buf[m++] = h_x(j,1); + buf[m++] = h_x(j,2); + buf[m++] = h_v(j,0); + buf[m++] = h_v(j,1); + buf[m++] = h_v(j,2); + if (omega_flag) { + buf[m++] = h_omega(j,0); + buf[m++] = h_omega(j,1); + buf[m++] = h_omega(j,2); + } + if (angmom_flag) { + buf[m++] = h_angmom(j,0); + buf[m++] = h_angmom(j,1); + buf[m++] = h_angmom(j,2); + } + } + } else { + if (domain->triclinic == 0) { + dx = pbc[0]*domain->xprd; + dy = pbc[1]*domain->yprd; + dz = pbc[2]*domain->zprd; + } else { + dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz; + dy = pbc[1]*domain->yprd + pbc[3]*domain->yz; + dz = pbc[2]*domain->zprd; + } + if (!deform_vremap) { + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = h_x(j,0) + dx; + buf[m++] = h_x(j,1) + dy; + buf[m++] = h_x(j,2) + dz; + buf[m++] = h_v(j,0); + buf[m++] = h_v(j,1); + buf[m++] = h_v(j,2); + if (omega_flag) { + buf[m++] = h_omega(j,0); + buf[m++] = h_omega(j,1); + buf[m++] = h_omega(j,2); + } + if (angmom_flag) { + buf[m++] = h_angmom(j,0); + buf[m++] = h_angmom(j,1); + buf[m++] = h_angmom(j,2); + } + } + } else { + dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4]; + dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3]; + dvz = pbc[2]*h_rate[2]; + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = h_x(j,0) + dx; + buf[m++] = h_x(j,1) + dy; + buf[m++] = h_x(j,2) + dz; + if (h_mask[i] & deform_groupbit) { + buf[m++] = h_v(j,0) + dvx; + buf[m++] = h_v(j,1) + dvy; + buf[m++] = h_v(j,2) + dvz; + } else { + buf[m++] = h_v(j,0); + buf[m++] = h_v(j,1); + buf[m++] = h_v(j,2); + } + if (omega_flag) { + buf[m++] = h_omega(j,0); + buf[m++] = h_omega(j,1); + buf[m++] = h_omega(j,2); + } + if (angmom_flag) { + buf[m++] = h_angmom(j,0); + buf[m++] = h_angmom(j,1); + buf[m++] = h_angmom(j,2); + } + } + } + } + + // pack sub-style contributions as contiguous chunks + + for (k = 0; k < nstyles; k++) + m += styles[k]->pack_comm_hybrid(n,list,&buf[m]); + + return m; +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecHybridKokkos::unpack_comm(int n, int first, double *buf) +{ + int i,k,m,last; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + h_x(i,0) = buf[m++]; + h_x(i,1) = buf[m++]; + h_x(i,2) = buf[m++]; + } + + // unpack sub-style contributions as contiguous chunks + + for (k = 0; k < nstyles; k++) + m += styles[k]->unpack_comm_hybrid(n,first,&buf[m]); +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecHybridKokkos::unpack_comm_vel(int n, int first, double *buf) +{ + int i,k,m,last; + int omega_flag = atom->omega_flag; + int angmom_flag = atom->angmom_flag; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + h_x(i,0) = buf[m++]; + h_x(i,1) = buf[m++]; + h_x(i,2) = buf[m++]; + h_v(i,0) = buf[m++]; + h_v(i,1) = buf[m++]; + h_v(i,2) = buf[m++]; + if (omega_flag) { + h_omega(i,0) = buf[m++]; + h_omega(i,1) = buf[m++]; + h_omega(i,2) = buf[m++]; + } + if (angmom_flag) { + h_angmom(i,0) = buf[m++]; + h_angmom(i,1) = buf[m++]; + h_angmom(i,2) = buf[m++]; + } + } + + // unpack sub-style contributions as contiguous chunks + + for (k = 0; k < nstyles; k++) + m += styles[k]->unpack_comm_hybrid(n,first,&buf[m]); +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecHybridKokkos::pack_reverse(int n, int first, double *buf) +{ + int i,k,m,last; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + buf[m++] = h_f(i,0); + buf[m++] = h_f(i,1); + buf[m++] = h_f(i,2); + } + + // pack sub-style contributions as contiguous chunks + + for (k = 0; k < nstyles; k++) + m += styles[k]->pack_reverse_hybrid(n,first,&buf[m]); + + return m; +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecHybridKokkos::unpack_reverse(int n, int *list, double *buf) +{ + int i,j,k,m; + + m = 0; + for (i = 0; i < n; i++) { + j = list[i]; + h_f(j,0) += buf[m++]; + h_f(j,1) += buf[m++]; + h_f(j,2) += buf[m++]; + } + + // unpack sub-style contributions as contiguous chunks + + for (k = 0; k < nstyles; k++) + m += styles[k]->unpack_reverse_hybrid(n,list,&buf[m]); +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecHybridKokkos::pack_border(int n, int *list, double *buf, + int pbc_flag, int *pbc) +{ + int i,j,k,m; + double dx,dy,dz; + + m = 0; + if (pbc_flag == 0) { + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = h_x(j,0); + buf[m++] = h_x(j,1); + buf[m++] = h_x(j,2); + buf[m++] = ubuf(h_tag[j]).d; + buf[m++] = ubuf(h_type[j]).d; + buf[m++] = ubuf(h_mask[j]).d; + } + } else { + if (domain->triclinic == 0) { + dx = pbc[0]*domain->xprd; + dy = pbc[1]*domain->yprd; + dz = pbc[2]*domain->zprd; + } else { + dx = pbc[0]; + dy = pbc[1]; + dz = pbc[2]; + } + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = h_x(j,0) + dx; + buf[m++] = h_x(j,1) + dy; + buf[m++] = h_x(j,2) + dz; + buf[m++] = ubuf(h_tag[j]).d; + buf[m++] = ubuf(h_type[j]).d; + buf[m++] = ubuf(h_mask[j]).d; + } + } + + // pack sub-style contributions as contiguous chunks + + for (k = 0; k < nstyles; k++) + m += styles[k]->pack_border_hybrid(n,list,&buf[m]); + + if (atom->nextra_border) + for (int iextra = 0; iextra < atom->nextra_border; iextra++) + m += modify->fix[atom->extra_border[iextra]]->pack_border(n,list,&buf[m]); + + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecHybridKokkos::pack_border_vel(int n, int *list, double *buf, + int pbc_flag, int *pbc) +{ + int i,j,k,m; + double dx,dy,dz,dvx,dvy,dvz; + int omega_flag = atom->omega_flag; + int angmom_flag = atom->angmom_flag; + + m = 0; + if (pbc_flag == 0) { + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = h_x(j,0); + buf[m++] = h_x(j,1); + buf[m++] = h_x(j,2); + buf[m++] = ubuf(h_tag[j]).d; + buf[m++] = ubuf(h_type[j]).d; + buf[m++] = ubuf(h_mask[j]).d; + buf[m++] = h_v(j,0); + buf[m++] = h_v(j,1); + buf[m++] = h_v(j,2); + if (omega_flag) { + buf[m++] = h_omega(j,0); + buf[m++] = h_omega(j,1); + buf[m++] = h_omega(j,2); + } + if (angmom_flag) { + buf[m++] = h_angmom(j,0); + buf[m++] = h_angmom(j,1); + buf[m++] = h_angmom(j,2); + } + } + } else { + if (domain->triclinic == 0) { + dx = pbc[0]*domain->xprd; + dy = pbc[1]*domain->yprd; + dz = pbc[2]*domain->zprd; + } else { + dx = pbc[0]; + dy = pbc[1]; + dz = pbc[2]; + } + if (!deform_vremap) { + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = h_x(j,0) + dx; + buf[m++] = h_x(j,1) + dy; + buf[m++] = h_x(j,2) + dz; + buf[m++] = ubuf(h_tag[j]).d; + buf[m++] = ubuf(h_type[j]).d; + buf[m++] = ubuf(h_mask[j]).d; + buf[m++] = h_v(j,0); + buf[m++] = h_v(j,1); + buf[m++] = h_v(j,2); + if (omega_flag) { + buf[m++] = h_omega(j,0); + buf[m++] = h_omega(j,1); + buf[m++] = h_omega(j,2); + } + if (angmom_flag) { + buf[m++] = h_angmom(j,0); + buf[m++] = h_angmom(j,1); + buf[m++] = h_angmom(j,2); + } + } + } else { + dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4]; + dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3]; + dvz = pbc[2]*h_rate[2]; + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = h_x(j,0) + dx; + buf[m++] = h_x(j,1) + dy; + buf[m++] = h_x(j,2) + dz; + buf[m++] = ubuf(h_tag[j]).d; + buf[m++] = ubuf(h_type[j]).d; + buf[m++] = ubuf(h_mask[j]).d; + if (h_mask[i] & deform_groupbit) { + buf[m++] = h_v(j,0) + dvx; + buf[m++] = h_v(j,1) + dvy; + buf[m++] = h_v(j,2) + dvz; + } else { + buf[m++] = h_v(j,0); + buf[m++] = h_v(j,1); + buf[m++] = h_v(j,2); + } + if (omega_flag) { + buf[m++] = h_omega(j,0); + buf[m++] = h_omega(j,1); + buf[m++] = h_omega(j,2); + } + if (angmom_flag) { + buf[m++] = h_angmom(j,0); + buf[m++] = h_angmom(j,1); + buf[m++] = h_angmom(j,2); + } + } + } + } + + // pack sub-style contributions as contiguous chunks + + for (k = 0; k < nstyles; k++) + m += styles[k]->pack_border_hybrid(n,list,&buf[m]); + + if (atom->nextra_border) + for (int iextra = 0; iextra < atom->nextra_border; iextra++) + m += modify->fix[atom->extra_border[iextra]]->pack_border(n,list,&buf[m]); + + return m; +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecHybridKokkos::unpack_border(int n, int first, double *buf) +{ + int i,k,m,last; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + if (i == nmax) grow(0); + h_x(i,0) = buf[m++]; + h_x(i,1) = buf[m++]; + h_x(i,2) = buf[m++]; + h_tag[i] = (tagint) ubuf(buf[m++]).i; + h_type[i] = (int) ubuf(buf[m++]).i; + h_mask[i] = (int) ubuf(buf[m++]).i; + } + + // unpack sub-style contributions as contiguous chunks + + for (k = 0; k < nstyles; k++) + m += styles[k]->unpack_border_hybrid(n,first,&buf[m]); + + if (atom->nextra_border) + for (int iextra = 0; iextra < atom->nextra_border; iextra++) + m += modify->fix[atom->extra_border[iextra]]-> + unpack_border(n,first,&buf[m]); +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecHybridKokkos::unpack_border_vel(int n, int first, double *buf) +{ + int i,k,m,last; + int omega_flag = atom->omega_flag; + int angmom_flag = atom->angmom_flag; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + if (i == nmax) grow(0); + h_x(i,0) = buf[m++]; + h_x(i,1) = buf[m++]; + h_x(i,2) = buf[m++]; + h_tag[i] = (tagint) ubuf(buf[m++]).i; + h_type[i] = (int) ubuf(buf[m++]).i; + h_mask[i] = (int) ubuf(buf[m++]).i; + h_v(i,0) = buf[m++]; + h_v(i,1) = buf[m++]; + h_v(i,2) = buf[m++]; + if (omega_flag) { + h_omega(i,0) = buf[m++]; + h_omega(i,1) = buf[m++]; + h_omega(i,2) = buf[m++]; + } + if (angmom_flag) { + h_angmom(i,0) = buf[m++]; + h_angmom(i,1) = buf[m++]; + h_angmom(i,2) = buf[m++]; + } + } + + // unpack sub-style contributions as contiguous chunks + + for (k = 0; k < nstyles; k++) + m += styles[k]->unpack_border_hybrid(n,first,&buf[m]); + + if (atom->nextra_border) + for (int iextra = 0; iextra < atom->nextra_border; iextra++) + m += modify->fix[atom->extra_border[iextra]]-> + unpack_border(n,first,&buf[m]); +} + +/* ---------------------------------------------------------------------- + pack data for atom I for sending to another proc + pack each sub-style one after the other +------------------------------------------------------------------------- */ + +int AtomVecHybridKokkos::pack_exchange(int i, double *buf) +{ + int k,m; + + int tmp = atom->nextra_grow; + atom->nextra_grow = 0; + + m = 0; + for (k = 0; k < nstyles; k++) + m += styles[k]->pack_exchange(i,&buf[m]); + + atom->nextra_grow = tmp; + + if (atom->nextra_grow) + for (int iextra = 0; iextra < atom->nextra_grow; iextra++) + m += modify->fix[atom->extra_grow[iextra]]->pack_exchange(i,&buf[m]); + + buf[0] = m; + return m; +} + +/* ---------------------------------------------------------------------- + unpack data for single atom received from another proc + unpack each sub-style one after the other + grow() occurs here so arrays for all sub-styles are grown +------------------------------------------------------------------------- */ + +int AtomVecHybridKokkos::unpack_exchange(double *buf) +{ + int k,m; + + int nlocal = atom->nlocal; + if (nlocal == nmax) grow(0); + + int tmp = atom->nextra_grow; + atom->nextra_grow = 0; + + m = 0; + for (k = 0; k < nstyles; k++) { + m += styles[k]->unpack_exchange(&buf[m]); + atom->nlocal--; + } + + atom->nextra_grow = tmp; + + if (atom->nextra_grow) + for (int iextra = 0; iextra < atom->nextra_grow; iextra++) + m += modify->fix[atom->extra_grow[iextra]]-> + unpack_exchange(nlocal,&buf[m]); + + atom->nlocal++; + return m; +} + +/* ---------------------------------------------------------------------- + size of restart data for all atoms owned by this proc + include extra data stored by fixes +------------------------------------------------------------------------- */ + +int AtomVecHybridKokkos::size_restart() +{ + int tmp = atom->nextra_restart; + atom->nextra_restart = 0; + + int n = 0; + for (int k = 0; k < nstyles; k++) + n += styles[k]->size_restart(); + + atom->nextra_restart = tmp; + + int nlocal = atom->nlocal; + if (atom->nextra_restart) + for (int iextra = 0; iextra < atom->nextra_restart; iextra++) + for (int i = 0; i < nlocal; i++) + n += modify->fix[atom->extra_restart[iextra]]->size_restart(i); + + return n; +} + +/* ---------------------------------------------------------------------- + pack atom I's data for restart file including extra quantities + xyz must be 1st 3 values, so that read_restart can test on them + pack each sub-style one after the other +------------------------------------------------------------------------- */ + +int AtomVecHybridKokkos::pack_restart(int i, double *buf) +{ + int tmp = atom->nextra_restart; + atom->nextra_restart = 0; + + int m = 0; + for (int k = 0; k < nstyles; k++) + m += styles[k]->pack_restart(i,&buf[m]); + + atom->nextra_restart = tmp; + + if (atom->nextra_restart) + for (int iextra = 0; iextra < atom->nextra_restart; iextra++) + m += modify->fix[atom->extra_restart[iextra]]->pack_restart(i,&buf[m]); + + buf[0] = m; + return m; +} + +/* ---------------------------------------------------------------------- + unpack data for one atom from restart file including extra quantities + unpack each sub-style one after the other + grow() occurs here so arrays for all sub-styles are grown +------------------------------------------------------------------------- */ + +int AtomVecHybridKokkos::unpack_restart(double *buf) +{ + int nlocal = atom->nlocal; + if (nlocal == nmax) { + grow(0); + if (atom->nextra_store) + memory->grow(atom->extra,nmax,atom->nextra_store,"atom:extra"); + } + + int tmp = atom->nextra_store; + atom->nextra_store = 0; + + int m = 0; + for (int k = 0; k < nstyles; k++) { + m += styles[k]->unpack_restart(&buf[m]); + atom->nlocal--; + } + atom->nextra_store = tmp; + + double **extra = atom->extra; + if (atom->nextra_store) { + int size = static_cast (buf[0]) - m; + for (int i = 0; i < size; i++) extra[nlocal][i] = buf[m++]; + } + + atom->nlocal++; + return m; +} + +/* ---------------------------------------------------------------------- + create one atom of itype at coord + create each sub-style one after the other + grow() occurs here so arrays for all sub-styles are grown +------------------------------------------------------------------------- */ + +void AtomVecHybridKokkos::create_atom(int itype, double *coord) +{ + int nlocal = atom->nlocal; + if (nlocal == nmax) grow(0); + + for (int k = 0; k < nstyles; k++) { + styles[k]->create_atom(itype,coord); + atom->nlocal--; + } + atom->nlocal++; +} + +/* ---------------------------------------------------------------------- + unpack one line from Atoms section of data file + grow() occurs here so arrays for all sub-styles are grown +------------------------------------------------------------------------- */ + +void AtomVecHybridKokkos::data_atom(double *coord, imageint imagetmp, char **values) +{ + int nlocal = atom->nlocal; + if (nlocal == nmax) grow(0); + + h_tag[nlocal] = ATOTAGINT(values[0]); + h_type[nlocal] = atoi(values[1]); + if (h_type[nlocal] <= 0 || h_type[nlocal] > atom->ntypes) + error->one(FLERR,"Invalid atom h_type in Atoms section of data file"); + + h_x(nlocal,0) = coord[0]; + h_x(nlocal,1) = coord[1]; + h_x(nlocal,2) = coord[2]; + + h_image[nlocal] = imagetmp; + h_mask[nlocal] = 1; + + h_v(nlocal,0) = 0.0; + h_v(nlocal,1) = 0.0; + h_v(nlocal,2) = 0.0; + if (atom->omega_flag) { + h_omega(nlocal,0) = 0.0; + h_omega(nlocal,1) = 0.0; + h_omega(nlocal,2) = 0.0; + } + if (atom->angmom_flag) { + h_angmom(nlocal,0) = 0.0; + h_angmom(nlocal,1) = 0.0; + h_angmom(nlocal,2) = 0.0; + } + + // each sub-style parses sub-style specific values + + int m = 5; + for (int k = 0; k < nstyles; k++) + m += styles[k]->data_atom_hybrid(nlocal,&values[m]); + + atom->nlocal++; +} + +/* ---------------------------------------------------------------------- + unpack one line from Velocities section of data file +------------------------------------------------------------------------- */ + +void AtomVecHybridKokkos::data_vel(int m, char **values) +{ + h_v(m,0) = atof(values[0]); + h_v(m,1) = atof(values[1]); + h_v(m,2) = atof(values[2]); + + // each sub-style parses sub-style specific values + + int n = 3; + for (int k = 0; k < nstyles; k++) + n += styles[k]->data_vel_hybrid(m,&values[n]); +} + +/* ---------------------------------------------------------------------- + pack atom info for data file including 3 image flags +------------------------------------------------------------------------- */ + +void AtomVecHybridKokkos::pack_data(double **buf) +{ + int k,m; + + int nlocal = atom->nlocal; + for (int i = 0; i < nlocal; i++) { + buf[i][0] = ubuf(h_tag[i]).d; + buf[i][1] = ubuf(h_type[i]).d; + buf[i][2] = h_x(i,0); + buf[i][3] = h_x(i,1); + buf[i][4] = h_x(i,2); + + m = 5; + for (k = 0; k < nstyles; k++) + m += styles[k]->pack_data_hybrid(i,&buf[i][m]); + + buf[i][m] = ubuf((h_image[i] & IMGMASK) - IMGMAX).d; + buf[i][m+1] = ubuf((h_image[i] >> IMGBITS & IMGMASK) - IMGMAX).d; + buf[i][m+2] = ubuf((h_image[i] >> IMG2BITS) - IMGMAX).d; + } +} + +/* ---------------------------------------------------------------------- + write atom info to data file including 3 h_image flags +------------------------------------------------------------------------- */ + +void AtomVecHybridKokkos::write_data(FILE *fp, int n, double **buf) +{ + int k,m; + + for (int i = 0; i < n; i++) { + fprintf(fp,TAGINT_FORMAT " %d %-1.16e %-1.16e %-1.16e", + (tagint) ubuf(buf[i][0]).i,(int) ubuf(buf[i][1]).i, + buf[i][2],buf[i][3],buf[i][4]); + + m = 5; + for (k = 0; k < nstyles; k++) + m += styles[k]->write_data_hybrid(fp,&buf[i][m]); + + fprintf(fp," %d %d %d\n", + (int) ubuf(buf[i][m]).i,(int) ubuf(buf[i][m+1]).i, + (int) ubuf(buf[i][m+2]).i); + } +} + +/* ---------------------------------------------------------------------- + pack velocity info for data file +------------------------------------------------------------------------- */ + +void AtomVecHybridKokkos::pack_vel(double **buf) +{ + int k,m; + + int nlocal = atom->nlocal; + for (int i = 0; i < nlocal; i++) { + buf[i][0] = ubuf(h_tag[i]).d; + buf[i][1] = h_v(i,0); + buf[i][2] = h_v(i,1); + buf[i][3] = h_v(i,2); + + m = 4; + for (k = 0; k < nstyles; k++) + m += styles[k]->pack_vel_hybrid(i,&buf[i][m]); + } +} + +/* ---------------------------------------------------------------------- + write velocity info to data file +------------------------------------------------------------------------- */ + +void AtomVecHybridKokkos::write_vel(FILE *fp, int n, double **buf) +{ + int k,m; + + for (int i = 0; i < n; i++) { + fprintf(fp,TAGINT_FORMAT " %g %g %g", + (tagint) ubuf(buf[i][0]).i,buf[i][1],buf[i][2],buf[i][3]); + + m = 4; + for (k = 0; k < nstyles; k++) + m += styles[k]->write_vel_hybrid(fp,&buf[i][m]); + + fprintf(fp,"\n"); + } +} + +/* ---------------------------------------------------------------------- + assign an index to named atom property and return index + returned value encodes which sub-style and index returned by sub-style + return -1 if name is unknown to any sub-styles +------------------------------------------------------------------------- */ + +int AtomVecHybridKokkos::property_atom(char *name) +{ + for (int k = 0; k < nstyles; k++) { + int index = styles[k]->property_atom(name); + if (index >= 0) return index*nstyles + k; + } + return -1; +} + +/* ---------------------------------------------------------------------- + pack per-atom data into buf for ComputePropertyAtom + index maps to data specific to this atom style +------------------------------------------------------------------------- */ + +void AtomVecHybridKokkos::pack_property_atom(int multiindex, double *buf, + int nvalues, int groupbit) +{ + int k = multiindex % nstyles; + int index = multiindex/nstyles; + styles[k]->pack_property_atom(index,buf,nvalues,groupbit); +} + +/* ---------------------------------------------------------------------- + allstyles = list of all atom styles in this LAMMPS executable +------------------------------------------------------------------------- */ + +void AtomVecHybridKokkos::build_styles() +{ + nallstyles = 0; +#define ATOM_CLASS +#define AtomStyle(key,Class) nallstyles++; +#include "style_atom.h" +#undef AtomStyle +#undef ATOM_CLASS + + allstyles = new char*[nallstyles]; + + int n; + nallstyles = 0; +#define ATOM_CLASS +#define AtomStyle(key,Class) \ + n = strlen(#key) + 1; \ + allstyles[nallstyles] = new char[n]; \ + strcpy(allstyles[nallstyles],#key); \ + nallstyles++; +#include "style_atom.h" +#undef AtomStyle +#undef ATOM_CLASS +} + +/* ---------------------------------------------------------------------- + allstyles = list of all known atom styles +------------------------------------------------------------------------- */ + +int AtomVecHybridKokkos::known_style(char *str) +{ + for (int i = 0; i < nallstyles; i++) + if (strcmp(str,allstyles[i]) == 0) return 1; + return 0; +} + +/* ---------------------------------------------------------------------- + return # of bytes of allocated memory +------------------------------------------------------------------------- */ + +bigint AtomVecHybridKokkos::memory_usage() +{ + bigint bytes = 0; + for (int k = 0; k < nstyles; k++) bytes += styles[k]->memory_usage(); + return bytes; +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecHybridKokkos::sync(ExecutionSpace space, unsigned int h_mask) +{ + for (int k = 0; k < nstyles; k++) ((AtomVecKokkos*) styles[k])->sync(space,h_mask); +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecHybridKokkos::sync_overlapping_device(ExecutionSpace space, unsigned int h_mask) +{ + for (int k = 0; k < nstyles; k++) ((AtomVecKokkos*) styles[k])->sync_overlapping_device(space,h_mask); +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecHybridKokkos::modified(ExecutionSpace space, unsigned int h_mask) +{ + for (int k = 0; k < nstyles; k++) ((AtomVecKokkos*) styles[k])->modified(space,h_mask); +} diff --git a/src/KOKKOS/atom_vec_hybrid_kokkos.h b/src/KOKKOS/atom_vec_hybrid_kokkos.h new file mode 100644 index 0000000000..802314bfa6 --- /dev/null +++ b/src/KOKKOS/atom_vec_hybrid_kokkos.h @@ -0,0 +1,161 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef ATOM_CLASS + +AtomStyle(hybrid/kk,AtomVecHybridKokkos) + +#else + +#ifndef LMP_ATOM_VEC_HYBRID_KOKKOS_H +#define LMP_ATOM_VEC_HYBRID_KOKKOS_H + +#include +#include "atom_vec.h" +#include "kokkos_type.h" + +namespace LAMMPS_NS { + +class AtomVecHybridKokkos : public AtomVecKokkos { + public: + int nstyles; + class AtomVec **styles; + char **keywords; + + AtomVecHybridKokkos(class LAMMPS *); + ~AtomVecHybridKokkos(); + void process_args(int, char **); + void init(); + void grow(int); + void grow_reset(); + void copy(int, int, int); + void clear_bonus(); + void force_clear(int, size_t); + int pack_comm(int, int *, double *, int, int *); + int pack_comm_vel(int, int *, double *, int, int *); + void unpack_comm(int, int, double *); + void unpack_comm_vel(int, int, double *); + int pack_reverse(int, int, double *); + void unpack_reverse(int, int *, double *); + int pack_border(int, int *, double *, int, int *); + int pack_border_vel(int, int *, double *, int, int *); + void unpack_border(int, int, double *); + void unpack_border_vel(int, int, double *); + int pack_exchange(int, double *); + int unpack_exchange(double *); + int size_restart(); + int pack_restart(int, double *); + int unpack_restart(double *); + void create_atom(int, double *); + void data_atom(double *, imageint, char **); + int data_atom_hybrid(int, char **) {return 0;} + void data_vel(int, char **); + void pack_data(double **); + void write_data(FILE *, int, double **); + void pack_vel(double **); + void write_vel(FILE *, int, double **); + int property_atom(char *); + void pack_property_atom(int, double *, int, int); + bigint memory_usage(); + + int pack_comm_kokkos(const int &n, const DAT::tdual_int_2d &k_sendlist, + const int & iswap, + const DAT::tdual_xfloat_2d &buf, + const int &pbc_flag, const int pbc[]); + void unpack_comm_kokkos(const int &n, const int &nfirst, + const DAT::tdual_xfloat_2d &buf); + int pack_comm_self(const int &n, const DAT::tdual_int_2d &list, + const int & iswap, const int nfirst, + const int &pbc_flag, const int pbc[]); + 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); + void unpack_border_kokkos(const int &n, const int &nfirst, + const DAT::tdual_xfloat_2d &buf, + ExecutionSpace space); + int pack_exchange_kokkos(const int &nsend,DAT::tdual_xfloat_2d &buf, + DAT::tdual_int_1d k_sendlist, + DAT::tdual_int_1d k_copylist, + ExecutionSpace space, int dim, + X_FLOAT lo, X_FLOAT hi); + int unpack_exchange_kokkos(DAT::tdual_xfloat_2d &k_buf, int nrecv, + int nlocal, int dim, X_FLOAT lo, X_FLOAT hi, + ExecutionSpace space); + + void sync(ExecutionSpace space, unsigned int mask); + void modified(ExecutionSpace space, unsigned int mask); + void sync_overlapping_device(ExecutionSpace space, unsigned int mask); + + private: + tagint *tag; + int *type,*mask; + imageint *image; + double **x,**v,**f; + double **omega,**angmom; + + DAT::t_tagint_1d d_tag; + DAT::t_int_1d d_type, d_mask; + HAT::t_tagint_1d h_tag; + HAT::t_int_1d h_type, h_mask; + + DAT::t_imageint_1d d_image; + HAT::t_imageint_1d h_image; + + DAT::t_x_array d_x; + DAT::t_v_array d_v; + DAT::t_f_array d_f; + HAT::t_x_array h_x; + HAT::t_v_array h_v; + HAT::t_f_array h_f; + + DAT::t_v_array d_omega, d_angmom; + HAT::t_v_array h_omega, h_angmom; + + DAT::tdual_int_1d k_count; + + int nallstyles; + char **allstyles; + + void build_styles(); + int known_style(char *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +E: Atom style hybrid cannot have hybrid as an argument + +Self-explanatory. + +E: Atom style hybrid cannot use same atom style twice + +Self-explanatory. + +E: Cannot mix molecular and molecule template atom styles + +Self-explanatory. + +E: Per-processor system is too big + +The number of owned atoms plus ghost atoms on a single +processor must fit in 32-bit integer. + +E: Invalid atom type in Atoms section of data file + +Atom types must range from 1 to specified # of types. + +*/ From d6f6c6faf1ecd6b25b1297b2f546632f3864fa45 Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Sun, 12 Mar 2017 16:05:28 -0400 Subject: [PATCH 197/439] USER-DPD: Make newton-off warning in pair_dpd_fdt* be more selective. If using fix_shardlow, the pair_dpd_fdt* styles are okay with newton off, because the stocastic forces are thus only done in fix_shardlow. --- src/USER-DPD/pair_dpd_fdt.cpp | 11 +++++------ src/USER-DPD/pair_dpd_fdt_energy.cpp | 11 +++++------ 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/USER-DPD/pair_dpd_fdt.cpp b/src/USER-DPD/pair_dpd_fdt.cpp index 90aa4f1eaf..987755db8a 100644 --- a/src/USER-DPD/pair_dpd_fdt.cpp +++ b/src/USER-DPD/pair_dpd_fdt.cpp @@ -316,18 +316,17 @@ void PairDPDfdt::init_style() if (comm->ghost_velocity == 0) error->all(FLERR,"Pair dpd/fdt requires ghost atoms store velocity"); - // if newton off, forces between atoms ij will be double computed - // using different random numbers - - if (force->newton_pair == 0 && comm->me == 0) error->warning(FLERR, - "Pair dpd/fdt requires newton pair on"); - splitFDT_flag = false; int irequest = neighbor->request(this,instance_me); for (int i = 0; i < modify->nfix; i++) if (strncmp(modify->fix[i]->style,"shardlow", 8) == 0){ splitFDT_flag = true; } + + // if newton off, forces between atoms ij will be double computed + // using different random numbers if splitFDT_flag is false + if (!splitFDT_flag && (force->newton_pair == 0) && (comm->me == 0)) error->warning(FLERR, + "Pair dpd/fdt requires newton pair on if not also using fix shardlow"); } /* ---------------------------------------------------------------------- diff --git a/src/USER-DPD/pair_dpd_fdt_energy.cpp b/src/USER-DPD/pair_dpd_fdt_energy.cpp index ad6310a283..bf86f95b5f 100644 --- a/src/USER-DPD/pair_dpd_fdt_energy.cpp +++ b/src/USER-DPD/pair_dpd_fdt_energy.cpp @@ -405,12 +405,6 @@ void PairDPDfdtEnergy::init_style() if (comm->ghost_velocity == 0) error->all(FLERR,"Pair dpd/fdt/energy requires ghost atoms store velocity"); - // if newton off, forces between atoms ij will be double computed - // using different random numbers - - if (force->newton_pair == 0 && comm->me == 0) error->warning(FLERR, - "Pair dpd/fdt/energy requires newton pair on"); - splitFDT_flag = false; int irequest = neighbor->request(this,instance_me); for (int i = 0; i < modify->nfix; i++) @@ -418,6 +412,11 @@ void PairDPDfdtEnergy::init_style() splitFDT_flag = true; } + // if newton off, forces between atoms ij will be double computed + // using different random numbers if splitFDT_flag is false + if (!splitFDT_flag && (force->newton_pair == 0) && (comm->me == 0)) error->warning(FLERR, + "Pair dpd/fdt/energy requires newton pair on if not also using fix shardlow"); + bool eos_flag = false; for (int i = 0; i < modify->nfix; i++) if (strncmp(modify->fix[i]->style,"eos",3) == 0) eos_flag = true; From e908b8dbea0284460ea070cd98862dc4abd5d4c1 Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Sun, 12 Mar 2017 16:20:09 -0400 Subject: [PATCH 198/439] USER-DPD Kokkos: correct some error messages --- src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp | 4 ++-- src/KOKKOS/pair_exp6_rx_kokkos.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp b/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp index bd0f08efa6..1c63b9af95 100644 --- a/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp +++ b/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp @@ -104,7 +104,7 @@ void PairDPDfdtEnergyKokkos::init_style() neighbor->requests[irequest]->full = 0; neighbor->requests[irequest]->half = 1; } else { - error->all(FLERR,"Cannot use chosen neighbor list style with reax/c/kk"); + error->all(FLERR,"Cannot use chosen neighbor list style with dpd/fdt/energy/kk"); } #ifdef DPD_USE_RAN_MARS @@ -139,7 +139,7 @@ void PairDPDfdtEnergyKokkos::init_style() neighbor->requests[irequest]->full = 0; neighbor->requests[irequest]->half = 1; } else { - error->all(FLERR,"Cannot use chosen neighbor list style with reax/c/kk"); + error->all(FLERR,"Cannot use chosen neighbor list style with dpd/fdt/energy/kk"); } #ifdef DPD_USE_RAN_MARS diff --git a/src/KOKKOS/pair_exp6_rx_kokkos.cpp b/src/KOKKOS/pair_exp6_rx_kokkos.cpp index 4b0748721c..e22a4bff22 100644 --- a/src/KOKKOS/pair_exp6_rx_kokkos.cpp +++ b/src/KOKKOS/pair_exp6_rx_kokkos.cpp @@ -112,7 +112,7 @@ void PairExp6rxKokkos::init_style() neighbor->requests[irequest]->full = 0; neighbor->requests[irequest]->half = 1; } else { - error->all(FLERR,"Cannot use chosen neighbor list style with reax/c/kk"); + error->all(FLERR,"Cannot use chosen neighbor list style with exp6/rx/kk"); } } @@ -1242,4 +1242,4 @@ template class PairExp6rxKokkos; #ifdef KOKKOS_HAVE_CUDA template class PairExp6rxKokkos; #endif -} \ No newline at end of file +} From b1b377cb594738d35b31ba33ea2d125e78483ee3 Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Sun, 12 Mar 2017 17:48:51 -0400 Subject: [PATCH 199/439] USER-DPD: fix_shardlow's neighbor request needs "newton on" override. Even if other stuff is doing newton off, SSA must have it turned on. --- src/USER-DPD/fix_shardlow.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/USER-DPD/fix_shardlow.cpp b/src/USER-DPD/fix_shardlow.cpp index 5132d937ea..2b7ef9314b 100644 --- a/src/USER-DPD/fix_shardlow.cpp +++ b/src/USER-DPD/fix_shardlow.cpp @@ -132,10 +132,11 @@ int FixShardlow::setmask() void FixShardlow::init() { int irequest = neighbor->request(this,instance_me); - neighbor->requests[irequest]->pair = 0; - neighbor->requests[irequest]->fix = 1; - neighbor->requests[irequest]->ghost= 1; - neighbor->requests[irequest]->ssa = 1; + neighbor->requests[irequest]->pair = 0; + neighbor->requests[irequest]->fix = 1; + neighbor->requests[irequest]->ghost = 1; + neighbor->requests[irequest]->ssa = 1; + neighbor->requests[irequest]->newton = 1; // SSA requires newton on } /* ---------------------------------------------------------------------- */ From d5eceebf3283cd460a4230672c582b952bef36f0 Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Mon, 13 Mar 2017 01:56:00 -0400 Subject: [PATCH 200/439] USER-DPD Kokkos: add support for full neighbor lists. Note: "newton on" still required if using non-kokkos pair styles or fixes. Non-kokkos pairs/fixes don't expect their half lists with newton off, which happens if newton is turned off globally by kokkos via commandline. Note2: Regardless, fix_shardlow* will still use half lists and newton on. --- src/KOKKOS/fix_rx_kokkos.cpp | 9 +++-- src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp | 44 +++++++++++++++++++---- src/KOKKOS/pair_exp6_rx_kokkos.cpp | 16 ++++++--- src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp | 27 +++++++++++--- src/KOKKOS/pair_table_rx_kokkos.cpp | 16 +++++++++ 5 files changed, 96 insertions(+), 16 deletions(-) diff --git a/src/KOKKOS/fix_rx_kokkos.cpp b/src/KOKKOS/fix_rx_kokkos.cpp index 08a20ac9a7..ac81e5c2a7 100644 --- a/src/KOKKOS/fix_rx_kokkos.cpp +++ b/src/KOKKOS/fix_rx_kokkos.cpp @@ -1450,6 +1450,11 @@ void FixRxKokkos::solve_reactions(const int vflag, const bool isPreF computeLocalTemperature<_wtflag, _localTempFlag, true , HALFTHREAD> (); \ else \ computeLocalTemperature<_wtflag, _localTempFlag, false, HALFTHREAD> (); \ + else if (neighflag == FULL) \ + if (newton_pair) \ + computeLocalTemperature<_wtflag, _localTempFlag, true , FULL> (); \ + else \ + computeLocalTemperature<_wtflag, _localTempFlag, false, FULL> (); \ } // Are there is no other options than wtFlag = (0)LUCY and localTempFlag = NONE : HARMONIC? @@ -1934,12 +1939,12 @@ void FixRxKokkos::operator()(Tag_FixRxKokkos_firstPairOperator::compute(int eflag_in, int vflag_in) if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); } + } else if (neighflag == FULL) { + if (newton_pair) { + if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } else { + if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } } } else { if (neighflag == HALF) { @@ -251,6 +259,14 @@ void PairDPDfdtEnergyKokkos::compute(int eflag_in, int vflag_in) if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); } + } else if (neighflag == FULL) { + if (newton_pair) { + if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } else { + if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } } } } @@ -291,6 +307,14 @@ void PairDPDfdtEnergyKokkos::compute(int eflag_in, int vflag_in) if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); } + } else if (neighflag == FULL) { + if (newton_pair) { + if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } else { + if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } } } else { if (neighflag == HALF) { @@ -309,6 +333,14 @@ void PairDPDfdtEnergyKokkos::compute(int eflag_in, int vflag_in) if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); } + } else if (neighflag == FULL) { + if (newton_pair) { + if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } else { + if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } } } @@ -405,7 +437,7 @@ void PairDPDfdtEnergyKokkos::operator()(TagPairDPDfdtEnergyComputeSp fx_i += delx*fpair; fy_i += dely*fpair; fz_i += delz*fpair; - if (NEWTON_PAIR || j < nlocal) { + 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; @@ -418,7 +450,7 @@ void PairDPDfdtEnergyKokkos::operator()(TagPairDPDfdtEnergyComputeSp evdwl = 0.5*a0_ij*cut_ij * wd; evdwl *= factor_dpd; if (EVFLAG) - ev.evdwl += ((NEWTON_PAIR||(jtemplate ev_tally(ev,i,j,evdwl,fpair,delx,dely,delz); @@ -522,7 +554,7 @@ void PairDPDfdtEnergyKokkos::operator()(TagPairDPDfdtEnergyComputeNo fx_i += delx*fpair; fy_i += dely*fpair; fz_i += delz*fpair; - if (NEWTON_PAIR || j < nlocal) { + 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; @@ -548,7 +580,7 @@ void PairDPDfdtEnergyKokkos::operator()(TagPairDPDfdtEnergyComputeNo uTmp *= 0.5; a_duMech[i] += uTmp; - if (NEWTON_PAIR || j < nlocal) { + if ((NEIGHFLAG==HALF || NEIGHFLAG==HALFTHREAD) && (NEWTON_PAIR || j < nlocal)) { a_duMech[j] += uTmp; } @@ -562,7 +594,7 @@ void PairDPDfdtEnergyKokkos::operator()(TagPairDPDfdtEnergyComputeNo uTmp += randPair; a_duCond[i] += uTmp; - if (NEWTON_PAIR || j < nlocal) { + if ((NEIGHFLAG==HALF || NEIGHFLAG==HALFTHREAD) && (NEWTON_PAIR || j < nlocal)) { a_duCond[j] -= uTmp; } @@ -573,7 +605,7 @@ void PairDPDfdtEnergyKokkos::operator()(TagPairDPDfdtEnergyComputeNo evdwl = 0.5*a0_ij*cut_ij * wd; evdwl *= factor_dpd; if (EVFLAG) - ev.evdwl += ((NEWTON_PAIR||(jtemplate ev_tally(ev,i,j,evdwl,fpair,delx,dely,delz); diff --git a/src/KOKKOS/pair_exp6_rx_kokkos.cpp b/src/KOKKOS/pair_exp6_rx_kokkos.cpp index e22a4bff22..abc158d72c 100644 --- a/src/KOKKOS/pair_exp6_rx_kokkos.cpp +++ b/src/KOKKOS/pair_exp6_rx_kokkos.cpp @@ -221,6 +221,14 @@ void PairExp6rxKokkos::compute(int eflag_in, int vflag_in) if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); } + } else if (neighflag == FULL) { + if (newton_pair) { + if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } else { + if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } } k_error_flag.template modify(); @@ -509,7 +517,7 @@ void PairExp6rxKokkos::operator()(TagPairExp6rxCompute::operator()(TagPairExp6rxCompute::operator()(TagPairExp6rxComputetemplate ev_tally(ev,i,j,evdwl,fpair,delx,dely,delz); } diff --git a/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp b/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp index 4379cc4001..ef30fdc6f6 100644 --- a/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp +++ b/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp @@ -216,6 +216,14 @@ void PairMultiLucyRXKokkos::compute_style(int eflag_in, int vflag_in if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); } + } else if (neighflag == FULL) { + if (newton_pair) { + if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } else { + if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } } if (evflag) atomKK->modified(execution_space,F_MASK | ENERGY_MASK | VIRIAL_MASK | UCG_MASK | UCGNEW_MASK); @@ -378,7 +386,7 @@ void PairMultiLucyRXKokkos::operator()(TagPairMultiLucyRXCompute::operator()(TagPairMultiLucyRXCompute @@ -491,6 +499,17 @@ void PairMultiLucyRXKokkos::computeLocalDensity() Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } else if (neighflag == FULL) { + if (newton_pair) + if (one_type) + Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + else + Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + else + if (one_type) + Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + else + Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); } atomKK->modified(execution_space,DPDRHO_MASK); @@ -548,7 +567,7 @@ void PairMultiLucyRXKokkos::operator()(TagPairMultiLucyRXComputeLoca const double tmpFactor4 = tmpFactor*tmpFactor*tmpFactor*tmpFactor; const double factor = factor_type11*(1.0 + 1.5*r_over_rcut)*tmpFactor4; rho_i_contrib += factor; - if (NEWTON_PAIR || j < nlocal) + if ((NEIGHFLAG==HALF || NEIGHFLAG==HALFTHREAD) && (NEWTON_PAIR || j < nlocal)) a_rho[j] += factor; } } else if (rsq < d_cutsq(itype,jtype)) { @@ -557,7 +576,7 @@ void PairMultiLucyRXKokkos::operator()(TagPairMultiLucyRXComputeLoca const double tmpFactor4 = tmpFactor*tmpFactor*tmpFactor*tmpFactor; const double factor = (84.0/(5.0*pi*rcut*rcut*rcut))*(1.0+3.0*sqrt(rsq)/(2.0*rcut))*tmpFactor4; rho_i_contrib += factor; - if (NEWTON_PAIR || j < nlocal) + if ((NEIGHFLAG==HALF || NEIGHFLAG==HALFTHREAD) && (NEWTON_PAIR || j < nlocal)) a_rho[j] += factor; } } diff --git a/src/KOKKOS/pair_table_rx_kokkos.cpp b/src/KOKKOS/pair_table_rx_kokkos.cpp index cbb1096712..e3d416f293 100644 --- a/src/KOKKOS/pair_table_rx_kokkos.cpp +++ b/src/KOKKOS/pair_table_rx_kokkos.cpp @@ -693,6 +693,14 @@ void PairTableRXKokkos::compute_style(int eflag_in, int vflag_in) special_lj_local, m_cutsq, d_cutsq, f, uCG, uCGnew, isite1, isite2, d_table_const, eflag, eflag_atom, vflag, vflag_global, vflag_atom, d_vatom, d_eatom); + } else if (neighflag == FULL) { + compute_all_items( + newton_pair, ev, nlocal, + l->inum, l->d_ilist, l->d_neighbors, l->d_numneigh, + x, type, mixWtSite1old, mixWtSite2old, mixWtSite1, mixWtSite2, + special_lj_local, m_cutsq, d_cutsq, f, uCG, uCGnew, isite1, isite2, + d_table_const, eflag, eflag_atom, + vflag, vflag_global, vflag_atom, d_vatom, d_eatom); } } else { if (neighflag == HALFTHREAD) { @@ -711,6 +719,14 @@ void PairTableRXKokkos::compute_style(int eflag_in, int vflag_in) special_lj_local, m_cutsq, d_cutsq, f, uCG, uCGnew, isite1, isite2, d_table_const, eflag, eflag_atom, vflag, vflag_global, vflag_atom, d_vatom, d_eatom); + } else if (neighflag == FULL) { + compute_all_items( + newton_pair, ev, nlocal, + l->inum, l->d_ilist, l->d_neighbors, l->d_numneigh, + x, type, mixWtSite1old, mixWtSite2old, mixWtSite1, mixWtSite2, + special_lj_local, m_cutsq, d_cutsq, f, uCG, uCGnew, isite1, isite2, + d_table_const, eflag, eflag_atom, + vflag, vflag_global, vflag_atom, d_vatom, d_eatom); } } From 4b4bc7dc3bd11d52e6ad49e99749f80405d7dbbb Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Mon, 13 Mar 2017 03:03:27 -0400 Subject: [PATCH 201/439] USER-DPD: specialize PairTableRXKokkos's compute_all_items() on NEWTON_PAIR No noticable performance change, but it does eliminate a deep conditional. --- src/KOKKOS/pair_table_rx_kokkos.cpp | 110 +++++++++++++++++----------- 1 file changed, 69 insertions(+), 41 deletions(-) diff --git a/src/KOKKOS/pair_table_rx_kokkos.cpp b/src/KOKKOS/pair_table_rx_kokkos.cpp index e3d416f293..e93ea53fa4 100644 --- a/src/KOKKOS/pair_table_rx_kokkos.cpp +++ b/src/KOKKOS/pair_table_rx_kokkos.cpp @@ -514,9 +514,8 @@ compute_item( return ev; } -template +template static void compute_all_items( - int newton_pair, EV_FLOAT& ev, int nlocal, int inum, @@ -560,42 +559,23 @@ static void compute_all_items( if (eflag || vflag) { Kokkos::parallel_reduce(inum, LAMMPS_LAMBDA(int i, EV_FLOAT& energy_virial) { - if (newton_pair) { energy_virial += - compute_item( + compute_item( i, nlocal, d_ilist, d_neighbors, d_numneigh, x, type, mixWtSite1old, mixWtSite2old, mixWtSite1, mixWtSite2, special_lj, m_cutsq, d_cutsq, f, uCG, uCGnew, isite1, isite2, d_table_const, eflag, eflag_atom, vflag, vflag_global, vflag_atom, v_vatom, v_eatom); - } else { - energy_virial += - compute_item( - i, nlocal, d_ilist, d_neighbors, d_numneigh, x, type, - mixWtSite1old, mixWtSite2old, mixWtSite1, mixWtSite2, - special_lj, m_cutsq, d_cutsq, f, uCG, uCGnew, isite1, isite2, - d_table_const, eflag, eflag_atom, - vflag, vflag_global, vflag_atom, v_vatom, v_eatom); - } }, ev); } else { Kokkos::parallel_for(inum, LAMMPS_LAMBDA(int i) { - if (newton_pair) { - compute_item( + compute_item( i, nlocal, d_ilist, d_neighbors, d_numneigh, x, type, mixWtSite1old, mixWtSite2old, mixWtSite1, mixWtSite2, special_lj, m_cutsq, d_cutsq, f, uCG, uCGnew, isite1, isite2, d_table_const, eflag, eflag_atom, vflag, vflag_global, vflag_atom, v_vatom, v_eatom); - } else { - compute_item( - i, nlocal, d_ilist, d_neighbors, d_numneigh, x, type, - mixWtSite1old, mixWtSite2old, mixWtSite1, mixWtSite2, - special_lj, m_cutsq, d_cutsq, f, uCG, uCGnew, isite1, isite2, - d_table_const, eflag, eflag_atom, - vflag, vflag_global, vflag_atom, v_vatom, v_eatom); - } }); } } @@ -678,55 +658,103 @@ void PairTableRXKokkos::compute_style(int eflag_in, int vflag_in) EV_FLOAT ev; if(atom->ntypes > MAX_TYPES_STACKPARAMS) { if (neighflag == HALFTHREAD) { - compute_all_items( - newton_pair, ev, nlocal, - l->inum, l->d_ilist, l->d_neighbors, l->d_numneigh, + if (newton_pair) { + compute_all_items( + ev, nlocal, l->inum, l->d_ilist, l->d_neighbors, l->d_numneigh, x, type, mixWtSite1old, mixWtSite2old, mixWtSite1, mixWtSite2, special_lj_local, m_cutsq, d_cutsq, f, uCG, uCGnew, isite1, isite2, d_table_const, eflag, eflag_atom, vflag, vflag_global, vflag_atom, d_vatom, d_eatom); + } else { + compute_all_items( + ev, nlocal, l->inum, l->d_ilist, l->d_neighbors, l->d_numneigh, + x, type, mixWtSite1old, mixWtSite2old, mixWtSite1, mixWtSite2, + special_lj_local, m_cutsq, d_cutsq, f, uCG, uCGnew, isite1, isite2, + d_table_const, eflag, eflag_atom, + vflag, vflag_global, vflag_atom, d_vatom, d_eatom); + } } else if (neighflag == HALF) { - compute_all_items( - newton_pair, ev, nlocal, - l->inum, l->d_ilist, l->d_neighbors, l->d_numneigh, + if (newton_pair) { + compute_all_items( + ev, nlocal, l->inum, l->d_ilist, l->d_neighbors, l->d_numneigh, x, type, mixWtSite1old, mixWtSite2old, mixWtSite1, mixWtSite2, special_lj_local, m_cutsq, d_cutsq, f, uCG, uCGnew, isite1, isite2, d_table_const, eflag, eflag_atom, vflag, vflag_global, vflag_atom, d_vatom, d_eatom); + } else { + compute_all_items( + ev, nlocal, l->inum, l->d_ilist, l->d_neighbors, l->d_numneigh, + x, type, mixWtSite1old, mixWtSite2old, mixWtSite1, mixWtSite2, + special_lj_local, m_cutsq, d_cutsq, f, uCG, uCGnew, isite1, isite2, + d_table_const, eflag, eflag_atom, + vflag, vflag_global, vflag_atom, d_vatom, d_eatom); + } } else if (neighflag == FULL) { - compute_all_items( - newton_pair, ev, nlocal, - l->inum, l->d_ilist, l->d_neighbors, l->d_numneigh, + if (newton_pair) { + compute_all_items( + ev, nlocal, l->inum, l->d_ilist, l->d_neighbors, l->d_numneigh, x, type, mixWtSite1old, mixWtSite2old, mixWtSite1, mixWtSite2, special_lj_local, m_cutsq, d_cutsq, f, uCG, uCGnew, isite1, isite2, d_table_const, eflag, eflag_atom, vflag, vflag_global, vflag_atom, d_vatom, d_eatom); + } else { + compute_all_items( + ev, nlocal, l->inum, l->d_ilist, l->d_neighbors, l->d_numneigh, + x, type, mixWtSite1old, mixWtSite2old, mixWtSite1, mixWtSite2, + special_lj_local, m_cutsq, d_cutsq, f, uCG, uCGnew, isite1, isite2, + d_table_const, eflag, eflag_atom, + vflag, vflag_global, vflag_atom, d_vatom, d_eatom); + } } } else { if (neighflag == HALFTHREAD) { - compute_all_items( - newton_pair, ev, nlocal, - l->inum, l->d_ilist, l->d_neighbors, l->d_numneigh, + if (newton_pair) { + compute_all_items( + ev, nlocal, l->inum, l->d_ilist, l->d_neighbors, l->d_numneigh, x, type, mixWtSite1old, mixWtSite2old, mixWtSite1, mixWtSite2, special_lj_local, m_cutsq, d_cutsq, f, uCG, uCGnew, isite1, isite2, d_table_const, eflag, eflag_atom, vflag, vflag_global, vflag_atom, d_vatom, d_eatom); + } else { + compute_all_items( + ev, nlocal, l->inum, l->d_ilist, l->d_neighbors, l->d_numneigh, + x, type, mixWtSite1old, mixWtSite2old, mixWtSite1, mixWtSite2, + special_lj_local, m_cutsq, d_cutsq, f, uCG, uCGnew, isite1, isite2, + d_table_const, eflag, eflag_atom, + vflag, vflag_global, vflag_atom, d_vatom, d_eatom); + } } else if (neighflag == HALF) { - compute_all_items( - newton_pair, ev, nlocal, - l->inum, l->d_ilist, l->d_neighbors, l->d_numneigh, + if (newton_pair) { + compute_all_items( + ev, nlocal, l->inum, l->d_ilist, l->d_neighbors, l->d_numneigh, x, type, mixWtSite1old, mixWtSite2old, mixWtSite1, mixWtSite2, special_lj_local, m_cutsq, d_cutsq, f, uCG, uCGnew, isite1, isite2, d_table_const, eflag, eflag_atom, vflag, vflag_global, vflag_atom, d_vatom, d_eatom); + } else { + compute_all_items( + ev, nlocal, l->inum, l->d_ilist, l->d_neighbors, l->d_numneigh, + x, type, mixWtSite1old, mixWtSite2old, mixWtSite1, mixWtSite2, + special_lj_local, m_cutsq, d_cutsq, f, uCG, uCGnew, isite1, isite2, + d_table_const, eflag, eflag_atom, + vflag, vflag_global, vflag_atom, d_vatom, d_eatom); + } } else if (neighflag == FULL) { - compute_all_items( - newton_pair, ev, nlocal, - l->inum, l->d_ilist, l->d_neighbors, l->d_numneigh, + if (newton_pair) { + compute_all_items( + ev, nlocal, l->inum, l->d_ilist, l->d_neighbors, l->d_numneigh, x, type, mixWtSite1old, mixWtSite2old, mixWtSite1, mixWtSite2, special_lj_local, m_cutsq, d_cutsq, f, uCG, uCGnew, isite1, isite2, d_table_const, eflag, eflag_atom, vflag, vflag_global, vflag_atom, d_vatom, d_eatom); + } else { + compute_all_items( + ev, nlocal, l->inum, l->d_ilist, l->d_neighbors, l->d_numneigh, + x, type, mixWtSite1old, mixWtSite2old, mixWtSite1, mixWtSite2, + special_lj_local, m_cutsq, d_cutsq, f, uCG, uCGnew, isite1, isite2, + d_table_const, eflag, eflag_atom, + vflag, vflag_global, vflag_atom, d_vatom, d_eatom); + } } } From d2cbfef13bac634b99459f3f4f78465ed03e712d Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Mon, 13 Mar 2017 09:01:35 -0600 Subject: [PATCH 202/439] Add CUDA support to atom_vec_hybrid_kokkos --- src/KOKKOS/atom_vec_hybrid_kokkos.cpp | 37 +++++++++++++++++++++++---- src/KOKKOS/atom_vec_hybrid_kokkos.h | 2 +- 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/src/KOKKOS/atom_vec_hybrid_kokkos.cpp b/src/KOKKOS/atom_vec_hybrid_kokkos.cpp index 0c9d261be5..e5e361e70a 100644 --- a/src/KOKKOS/atom_vec_hybrid_kokkos.cpp +++ b/src/KOKKOS/atom_vec_hybrid_kokkos.cpp @@ -13,7 +13,6 @@ #include #include -#include "atom_vec_kokkos.h" #include "atom_vec_hybrid_kokkos.h" #include "atom_kokkos.h" #include "domain.h" @@ -21,6 +20,7 @@ #include "fix.h" #include "memory.h" #include "error.h" +#include "atom_masks.h" using namespace LAMMPS_NS; @@ -132,10 +132,6 @@ void AtomVecHybridKokkos::init() { AtomVec::init(); for (int k = 0; k < nstyles; k++) styles[k]->init(); - -#ifdef KOKKOS_HAVE_CUDA - error->all(FLERR,"AtomVecHybridKokkos doesn't yet support CUDA"); -#endif } /* ---------------------------------------------------------------------- @@ -303,6 +299,8 @@ int AtomVecHybridKokkos::unpack_exchange_kokkos(DAT::tdual_xfloat_2d &k_buf, int int AtomVecHybridKokkos::pack_comm(int n, int *list, double *buf, int pbc_flag, int *pbc) { + sync(Host,X_MASK); + int i,j,k,m; double dx,dy,dz; @@ -345,6 +343,8 @@ int AtomVecHybridKokkos::pack_comm(int n, int *list, double *buf, int AtomVecHybridKokkos::pack_comm_vel(int n, int *list, double *buf, int pbc_flag, int *pbc) { + sync(Host,X_MASK|V_MASK|OMEGA_MASK/*|ANGMOM_MASK*/); + int i,j,k,m; double dx,dy,dz,dvx,dvy,dvz; int omega_flag = atom->omega_flag; @@ -455,6 +455,8 @@ void AtomVecHybridKokkos::unpack_comm(int n, int first, double *buf) h_x(i,2) = buf[m++]; } + modified(Host,X_MASK); + // unpack sub-style contributions as contiguous chunks for (k = 0; k < nstyles; k++) @@ -490,6 +492,8 @@ void AtomVecHybridKokkos::unpack_comm_vel(int n, int first, double *buf) } } + modified(Host,X_MASK|V_MASK|OMEGA_MASK/*|ANGMOM_MASK*/); + // unpack sub-style contributions as contiguous chunks for (k = 0; k < nstyles; k++) @@ -500,6 +504,8 @@ void AtomVecHybridKokkos::unpack_comm_vel(int n, int first, double *buf) int AtomVecHybridKokkos::pack_reverse(int n, int first, double *buf) { + sync(Host,F_MASK); + int i,k,m,last; m = 0; @@ -532,6 +538,8 @@ void AtomVecHybridKokkos::unpack_reverse(int n, int *list, double *buf) h_f(j,2) += buf[m++]; } + modified(Host,F_MASK); + // unpack sub-style contributions as contiguous chunks for (k = 0; k < nstyles; k++) @@ -543,6 +551,8 @@ void AtomVecHybridKokkos::unpack_reverse(int n, int *list, double *buf) int AtomVecHybridKokkos::pack_border(int n, int *list, double *buf, int pbc_flag, int *pbc) { + sync(Host,X_MASK|TAG_MASK|TYPE_MASK|MASK_MASK); + int i,j,k,m; double dx,dy,dz; @@ -595,6 +605,7 @@ int AtomVecHybridKokkos::pack_border(int n, int *list, double *buf, int AtomVecHybridKokkos::pack_border_vel(int n, int *list, double *buf, int pbc_flag, int *pbc) { + sync(Host,X_MASK|TAG_MASK|TYPE_MASK|MASK_MASK|V_MASK|OMEGA_MASK/*|ANGMOM_MASK*/); int i,j,k,m; double dx,dy,dz,dvx,dvy,dvz; int omega_flag = atom->omega_flag; @@ -722,6 +733,8 @@ void AtomVecHybridKokkos::unpack_border(int n, int first, double *buf) h_mask[i] = (int) ubuf(buf[m++]).i; } + modified(Host,X_MASK|TAG_MASK|TYPE_MASK|MASK_MASK); + // unpack sub-style contributions as contiguous chunks for (k = 0; k < nstyles; k++) @@ -766,6 +779,8 @@ void AtomVecHybridKokkos::unpack_border_vel(int n, int first, double *buf) } } + modified(Host,X_MASK|TAG_MASK|TYPE_MASK|MASK_MASK|V_MASK|OMEGA_MASK/*|ANGMOM_MASK*/); + // unpack sub-style contributions as contiguous chunks for (k = 0; k < nstyles; k++) @@ -946,6 +961,8 @@ void AtomVecHybridKokkos::create_atom(int itype, double *coord) void AtomVecHybridKokkos::data_atom(double *coord, imageint imagetmp, char **values) { + sync(Host,X_MASK|TAG_MASK|TYPE_MASK|IMAGE_MASK|MASK_MASK|V_MASK|OMEGA_MASK/*|ANGMOM_MASK*/); + int nlocal = atom->nlocal; if (nlocal == nmax) grow(0); @@ -975,6 +992,8 @@ void AtomVecHybridKokkos::data_atom(double *coord, imageint imagetmp, char **val h_angmom(nlocal,2) = 0.0; } + modified(Host,X_MASK|TAG_MASK|TYPE_MASK|IMAGE_MASK|MASK_MASK|V_MASK|OMEGA_MASK/*|ANGMOM_MASK*/); + // each sub-style parses sub-style specific values int m = 5; @@ -990,10 +1009,14 @@ void AtomVecHybridKokkos::data_atom(double *coord, imageint imagetmp, char **val void AtomVecHybridKokkos::data_vel(int m, char **values) { + sync(Host,V_MASK); + h_v(m,0) = atof(values[0]); h_v(m,1) = atof(values[1]); h_v(m,2) = atof(values[2]); + modified(Host,V_MASK); + // each sub-style parses sub-style specific values int n = 3; @@ -1007,6 +1030,8 @@ void AtomVecHybridKokkos::data_vel(int m, char **values) void AtomVecHybridKokkos::pack_data(double **buf) { + sync(Host,TAG_MASK|TYPE_MASK|X_MASK); + int k,m; int nlocal = atom->nlocal; @@ -1056,6 +1081,8 @@ void AtomVecHybridKokkos::write_data(FILE *fp, int n, double **buf) void AtomVecHybridKokkos::pack_vel(double **buf) { + sync(Host,V_MASK); + int k,m; int nlocal = atom->nlocal; diff --git a/src/KOKKOS/atom_vec_hybrid_kokkos.h b/src/KOKKOS/atom_vec_hybrid_kokkos.h index 802314bfa6..fcf48f6c74 100644 --- a/src/KOKKOS/atom_vec_hybrid_kokkos.h +++ b/src/KOKKOS/atom_vec_hybrid_kokkos.h @@ -21,7 +21,7 @@ AtomStyle(hybrid/kk,AtomVecHybridKokkos) #define LMP_ATOM_VEC_HYBRID_KOKKOS_H #include -#include "atom_vec.h" +#include "atom_vec_kokkos.h" #include "kokkos_type.h" namespace LAMMPS_NS { From 5925460a275fe4cf588e86eab45242351f5e86cf Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Tue, 14 Mar 2017 14:27:23 -0500 Subject: [PATCH 203/439] Improve the performance of read_data of gzip'ed files using taskset. Normally, the gzip process would be pinned to the same core as the MPI rank 0 process, which makes the pipe stay in one core's cache, but forces the two process to fight for that core, slowing things down. --- src/read_data.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/read_data.cpp b/src/read_data.cpp index d6a33d6e9d..3e180b7aeb 100644 --- a/src/read_data.cpp +++ b/src/read_data.cpp @@ -50,7 +50,7 @@ using namespace LAMMPS_NS; #define MAXLINE 256 #define LB_FACTOR 1.1 -#define CHUNK 1024 +#define CHUNK 4096 #define DELTA 4 // must be 2 or larger #define MAXBODY 32 // max # of lines in one body @@ -1856,8 +1856,12 @@ void ReadData::open(char *file) if (!compressed) fp = fopen(file,"r"); else { #ifdef LAMMPS_GZIP - char gunzip[128]; - sprintf(gunzip,"gzip -c -d %s",file); + char gunzip[2048]; + // Use taskset to force the gzip process to NOT run on the 0th "CPU", which should + // keep it from thrashing with the MPI rank zero process (the one reading the pipe). + // This is Linux specific, and the 1023 upper range might also be system specific. + // Use of something like hwloc would be more portable... but more complicated. + sprintf(gunzip,"taskset -c 1-1023 gzip -c -d %s",file); #ifdef _WIN32 fp = _popen(gunzip,"rb"); From f4a08ba4fcaed73f5bc9660266a75ddc868c9c3d Mon Sep 17 00:00:00 2001 From: Dan Ibanez Date: Wed, 15 Mar 2017 09:25:16 -0600 Subject: [PATCH 204/439] pass Views by reference for pair_table_rx_kokkos this greatly speeds up pair_table_rx_kokkos, and should put it on par with pair_table_rx in the Serial case --- src/KOKKOS/neigh_list_kokkos.h | 4 +-- src/KOKKOS/pair_table_rx_kokkos.cpp | 44 ++++++++++++++--------------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/KOKKOS/neigh_list_kokkos.h b/src/KOKKOS/neigh_list_kokkos.h index b43e1106f2..cece97197d 100644 --- a/src/KOKKOS/neigh_list_kokkos.h +++ b/src/KOKKOS/neigh_list_kokkos.h @@ -89,8 +89,8 @@ public: KOKKOS_INLINE_FUNCTION static AtomNeighborsConst static_neighbors_const(int i, - typename ArrayTypes::t_neighbors_2d_const d_neighbors, - typename ArrayTypes::t_int_1d_const d_numneigh) { + typename ArrayTypes::t_neighbors_2d_const const& d_neighbors, + typename ArrayTypes::t_int_1d_const const& d_numneigh) { return AtomNeighborsConst(&d_neighbors(i,0),d_numneigh(i), &d_neighbors(i,1)-&d_neighbors(i,0)); } diff --git a/src/KOKKOS/pair_table_rx_kokkos.cpp b/src/KOKKOS/pair_table_rx_kokkos.cpp index e93ea53fa4..044f303bf5 100644 --- a/src/KOKKOS/pair_table_rx_kokkos.cpp +++ b/src/KOKKOS/pair_table_rx_kokkos.cpp @@ -193,7 +193,7 @@ KOKKOS_INLINE_FUNCTION static F_FLOAT compute_fpair(F_FLOAT rsq, int itype, int jtype, - typename PairTableRXKokkos::TableDeviceConst d_table_const + typename PairTableRXKokkos::TableDeviceConst const& d_table_const ) { Pair::union_int_float_t rsq_lookup; double fpair; @@ -228,7 +228,7 @@ static F_FLOAT compute_evdwl( F_FLOAT rsq, int itype, int jtype, - typename PairTableRXKokkos::TableDeviceConst d_table_const + typename PairTableRXKokkos::TableDeviceConst const& d_table_const ) { double evdwl; Pair::union_int_float_t rsq_lookup; @@ -274,11 +274,11 @@ ev_tally( Kokkos::View::t_virial_array::array_layout, DeviceType, - Kokkos::MemoryTraits::value> > v_vatom, + Kokkos::MemoryTraits::value> > const& v_vatom, Kokkos::View::t_efloat_1d::array_layout, DeviceType, - Kokkos::MemoryTraits::value> > v_eatom) + Kokkos::MemoryTraits::value> > const& v_eatom) { if (eflag) { if (eflag_atom) { @@ -374,32 +374,32 @@ static EV_FLOAT compute_item( int ii, int nlocal, - typename ArrayTypes::t_int_1d_const d_ilist, - typename ArrayTypes::t_neighbors_2d_const d_neighbors, - typename ArrayTypes::t_int_1d_const d_numneigh, - typename ArrayTypes::t_x_array_randomread x, - typename ArrayTypes::t_int_1d_randomread type, - Kokkos::View mixWtSite1old, - Kokkos::View mixWtSite2old, - Kokkos::View mixWtSite1, - Kokkos::View mixWtSite2, - Few special_lj, - Few, MAX_TYPES_STACKPARAMS+1> m_cutsq, - typename ArrayTypes::t_ffloat_2d d_cutsq, + typename ArrayTypes::t_int_1d_const const& d_ilist, + typename ArrayTypes::t_neighbors_2d_const const& d_neighbors, + typename ArrayTypes::t_int_1d_const const& d_numneigh, + typename ArrayTypes::t_x_array_randomread const& x, + typename ArrayTypes::t_int_1d_randomread const& type, + Kokkos::View const& mixWtSite1old, + Kokkos::View const& mixWtSite2old, + Kokkos::View const& mixWtSite1, + Kokkos::View const& mixWtSite2, + Few const& special_lj, + Few, MAX_TYPES_STACKPARAMS+1> const& m_cutsq, + typename ArrayTypes::t_ffloat_2d const& d_cutsq, Kokkos::View::t_f_array::array_layout, DeviceType, - Kokkos::MemoryTraits::value> > f, + Kokkos::MemoryTraits::value> > const& f, Kokkos::View::t_efloat_1d::array_layout, DeviceType, - Kokkos::MemoryTraits::value> > uCG, + Kokkos::MemoryTraits::value> > const& uCG, Kokkos::View::t_efloat_1d::array_layout, DeviceType, - Kokkos::MemoryTraits::value> > uCGnew, + Kokkos::MemoryTraits::value> > const& uCGnew, int isite1, int isite2, - typename PairTableRXKokkos::TableDeviceConst d_table_const, + typename PairTableRXKokkos::TableDeviceConst const& d_table_const, int eflag, int eflag_atom, int vflag, @@ -408,11 +408,11 @@ compute_item( Kokkos::View::t_virial_array::array_layout, DeviceType, - Kokkos::MemoryTraits::value> > v_vatom, + Kokkos::MemoryTraits::value> > const& v_vatom, Kokkos::View::t_efloat_1d::array_layout, DeviceType, - Kokkos::MemoryTraits::value> > v_eatom) { + Kokkos::MemoryTraits::value> > const& v_eatom) { EV_FLOAT ev; auto i = d_ilist(ii); auto xtmp = x(i,0); From 7ebed717de983c351208b8e2080b37fbf761d522 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Wed, 15 Mar 2017 16:05:51 -0600 Subject: [PATCH 205/439] Adding gb_test --- src/KOKKOS/kokkos.cpp | 10 +- src/KOKKOS/kokkos.h | 1 + src/KOKKOS/pair_exp6_rx_kokkos.cpp | 425 +++++++++++++++++++++++++++++ src/KOKKOS/pair_exp6_rx_kokkos.h | 27 ++ 4 files changed, 462 insertions(+), 1 deletion(-) diff --git a/src/KOKKOS/kokkos.cpp b/src/KOKKOS/kokkos.cpp index b8be74ac1e..a000ad5550 100644 --- a/src/KOKKOS/kokkos.cpp +++ b/src/KOKKOS/kokkos.cpp @@ -34,6 +34,7 @@ KokkosLMP::KokkosLMP(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp) lmp->kokkos = this; auto_sync = 1; + gb_test = 0; int me = 0; MPI_Comm_rank(world,&me); @@ -156,6 +157,7 @@ void KokkosLMP::accelerator(int narg, char **arg) neighflag = FULL; neighflag_qeq = FULL; neighflag_qeq_set = 0; + gb_test = 0; int newtonflag = 0; double binsize = 0.0; exchange_comm_classic = forward_comm_classic = 0; @@ -197,6 +199,12 @@ void KokkosLMP::accelerator(int narg, char **arg) else if (strcmp(arg[iarg+1],"on") == 0) newtonflag = 1; else error->all(FLERR,"Illegal package kokkos command"); iarg += 2; + } else if (strcmp(arg[iarg],"gb/test") == 0) { + if (iarg+2 > narg) error->all(FLERR,"Illegal package kokkos command"); + if (strcmp(arg[iarg+1],"off") == 0) gb_test = 0; + else if (strcmp(arg[iarg+1],"on") == 0) gb_test = 1; + else error->all(FLERR,"Illegal package kokkos command"); + iarg += 2; } else if (strcmp(arg[iarg],"comm") == 0) { if (iarg+2 > narg) error->all(FLERR,"Illegal package kokkos command"); if (strcmp(arg[iarg+1],"no") == 0) { @@ -293,4 +301,4 @@ void KokkosLMP::my_signal_handler(int sig) if (sig == SIGSEGV) { kill(getpid(),SIGABRT); } -} \ No newline at end of file +} diff --git a/src/KOKKOS/kokkos.h b/src/KOKKOS/kokkos.h index 8e28b38cbf..3784d806bf 100644 --- a/src/KOKKOS/kokkos.h +++ b/src/KOKKOS/kokkos.h @@ -32,6 +32,7 @@ class KokkosLMP : protected Pointers { int num_threads,ngpu; int numa; int auto_sync; + int gb_test; KokkosLMP(class LAMMPS *, int, char **); ~KokkosLMP(); diff --git a/src/KOKKOS/pair_exp6_rx_kokkos.cpp b/src/KOKKOS/pair_exp6_rx_kokkos.cpp index abc158d72c..8cf235964c 100644 --- a/src/KOKKOS/pair_exp6_rx_kokkos.cpp +++ b/src/KOKKOS/pair_exp6_rx_kokkos.cpp @@ -205,6 +205,8 @@ void PairExp6rxKokkos::compute(int eflag_in, int vflag_in) EV_FLOAT ev; + if (!lmp->kokkos->gb_test) { + if (neighflag == HALF) { if (newton_pair) { if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); @@ -231,6 +233,48 @@ void PairExp6rxKokkos::compute(int eflag_in, int vflag_in) } } + } else { // No atomics + + num_threads = lmp->kokkos->num_threads; + int nmax = f.dimension_1(); + if (nmax > t_f.dimension_1()) { + t_f = t_f_array_thread("pair_exp6_rx:t_f",num_threads,nmax); + t_uCG = t_efloat_1d_thread("pair_exp6_rx:t_uCG",num_threads,nmax); + t_uCGnew = t_efloat_1d_thread("pair_exp6_rx:t_UCGnew",num_threads,nmax); + } + + Kokkos::parallel_for(Kokkos::RangePolicy(0,nmax),*this); + + if (neighflag == HALF) { + if (newton_pair) { + if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } else { + if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } + } else if (neighflag == HALFTHREAD) { + if (newton_pair) { + if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } else { + if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } + } else if (neighflag == FULL) { + if (newton_pair) { + if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } else { + if (evflag) Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + else Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + } + } + + Kokkos::parallel_for(Kokkos::RangePolicy(0,nmax),*this); + + } + k_error_flag.template modify(); k_error_flag.template sync(); if (k_error_flag.h_view()) @@ -636,6 +680,387 @@ void PairExp6rxKokkos::operator()(TagPairExp6rxComputetemplate operator()(TagPairExp6rxCompute(), ii, ev); } +// Experimental thread-safety using duplicated data instead of atomics + +template +template +KOKKOS_INLINE_FUNCTION +void PairExp6rxKokkos::operator()(TagPairExp6rxComputeNoAtomics, const int &ii, EV_FLOAT& ev) const { + + int tid = 0; +#ifndef KOKKOS_HAVE_CUDA + tid = DeviceType::hardware_thread_id(); +#endif + + int i,jj,jnum,itype,jtype; + double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,evdwlOld,fpair; + double rsq,r2inv,r6inv,forceExp6,factor_lj; + double rCut,rCutInv,rCut2inv,rCut6inv,rCutExp,urc,durc; + double rm2ij,rm6ij; + double r,rexp; + + double alphaOld12_ij, rmOld12_ij, epsilonOld12_ij; + double alphaOld21_ij, rmOld21_ij, epsilonOld21_ij; + double alpha12_ij, rm12_ij, epsilon12_ij; + double alpha21_ij, rm21_ij, epsilon21_ij; + double rminv, buck1, buck2; + double epsilonOld1_i,alphaOld1_i,rmOld1_i; + double epsilonOld1_j,alphaOld1_j,rmOld1_j; + double epsilonOld2_i,alphaOld2_i,rmOld2_i; + double epsilonOld2_j,alphaOld2_j,rmOld2_j; + double epsilon1_i,alpha1_i,rm1_i; + double epsilon1_j,alpha1_j,rm1_j; + double epsilon2_i,alpha2_i,rm2_i; + double epsilon2_j,alpha2_j,rm2_j; + double evdwlOldEXP6_12, evdwlOldEXP6_21, fpairOldEXP6_12, fpairOldEXP6_21; + double evdwlEXP6_12, evdwlEXP6_21; + double mixWtSite1old_i, mixWtSite1old_j; + double mixWtSite2old_i, mixWtSite2old_j; + double mixWtSite1_i, mixWtSite1_j; + double mixWtSite2_i, mixWtSite2_j; + + const int nRep = 12; + const double shift = 1.05; + double rin1, aRep, uin1, win1, uin1rep, rin1exp, rin6, rin6inv; + + evdwlOld = 0.0; + evdwl = 0.0; + + i = d_ilist[ii]; + xtmp = x(i,0); + ytmp = x(i,1); + ztmp = x(i,2); + itype = type[i]; + jnum = d_numneigh[i]; + + double fx_i = 0.0; + double fy_i = 0.0; + double fz_i = 0.0; + double uCG_i = 0.0; + double uCGnew_i = 0.0; + + { + epsilon1_i = PairExp6ParamData.epsilon1[i]; + alpha1_i = PairExp6ParamData.alpha1[i]; + rm1_i = PairExp6ParamData.rm1[i]; + mixWtSite1_i = PairExp6ParamData.mixWtSite1[i]; + epsilon2_i = PairExp6ParamData.epsilon2[i]; + alpha2_i = PairExp6ParamData.alpha2[i]; + rm2_i = PairExp6ParamData.rm2[i]; + mixWtSite2_i = PairExp6ParamData.mixWtSite2[i]; + epsilonOld1_i = PairExp6ParamData.epsilonOld1[i]; + alphaOld1_i = PairExp6ParamData.alphaOld1[i]; + rmOld1_i = PairExp6ParamData.rmOld1[i]; + mixWtSite1old_i = PairExp6ParamData.mixWtSite1old[i]; + epsilonOld2_i = PairExp6ParamData.epsilonOld2[i]; + alphaOld2_i = PairExp6ParamData.alphaOld2[i]; + rmOld2_i = PairExp6ParamData.rmOld2[i]; + mixWtSite2old_i = PairExp6ParamData.mixWtSite2old[i]; + } + + for (jj = 0; jj < jnum; jj++) { + int j = d_neighbors(i,jj); + factor_lj = special_lj[sbmask(j)]; + j &= NEIGHMASK; + + delx = xtmp - x(j,0); + dely = ytmp - x(j,1); + delz = ztmp - x(j,2); + + rsq = delx*delx + dely*dely + delz*delz; + jtype = type[j]; + + if (rsq < d_cutsq(itype,jtype)) { // optimize + r2inv = 1.0/rsq; + r6inv = r2inv*r2inv*r2inv; + + r = sqrt(rsq); + rCut2inv = 1.0/d_cutsq(itype,jtype); + rCut6inv = rCut2inv*rCut2inv*rCut2inv; + rCut = sqrt(d_cutsq(itype,jtype)); + rCutInv = 1.0/rCut; + + // + // A. Compute the exp-6 potential + // + + // A1. Get alpha, epsilon and rm for particle j + + { + epsilon1_j = PairExp6ParamData.epsilon1[j]; + alpha1_j = PairExp6ParamData.alpha1[j]; + rm1_j = PairExp6ParamData.rm1[j]; + mixWtSite1_j = PairExp6ParamData.mixWtSite1[j]; + epsilon2_j = PairExp6ParamData.epsilon2[j]; + alpha2_j = PairExp6ParamData.alpha2[j]; + rm2_j = PairExp6ParamData.rm2[j]; + mixWtSite2_j = PairExp6ParamData.mixWtSite2[j]; + epsilonOld1_j = PairExp6ParamData.epsilonOld1[j]; + alphaOld1_j = PairExp6ParamData.alphaOld1[j]; + rmOld1_j = PairExp6ParamData.rmOld1[j]; + mixWtSite1old_j = PairExp6ParamData.mixWtSite1old[j]; + epsilonOld2_j = PairExp6ParamData.epsilonOld2[j]; + alphaOld2_j = PairExp6ParamData.alphaOld2[j]; + rmOld2_j = PairExp6ParamData.rmOld2[j]; + mixWtSite2old_j = PairExp6ParamData.mixWtSite2old[j]; + } + + // A2. Apply Lorentz-Berthelot mixing rules for the i-j pair + alphaOld12_ij = sqrt(alphaOld1_i*alphaOld2_j); + rmOld12_ij = 0.5*(rmOld1_i + rmOld2_j); + epsilonOld12_ij = sqrt(epsilonOld1_i*epsilonOld2_j); + alphaOld21_ij = sqrt(alphaOld2_i*alphaOld1_j); + rmOld21_ij = 0.5*(rmOld2_i + rmOld1_j); + epsilonOld21_ij = sqrt(epsilonOld2_i*epsilonOld1_j); + + alpha12_ij = sqrt(alpha1_i*alpha2_j); + rm12_ij = 0.5*(rm1_i + rm2_j); + epsilon12_ij = sqrt(epsilon1_i*epsilon2_j); + alpha21_ij = sqrt(alpha2_i*alpha1_j); + rm21_ij = 0.5*(rm2_i + rm1_j); + epsilon21_ij = sqrt(epsilon2_i*epsilon1_j); + + evdwlOldEXP6_12 = 0.0; + evdwlOldEXP6_21 = 0.0; + evdwlEXP6_12 = 0.0; + evdwlEXP6_21 = 0.0; + fpairOldEXP6_12 = 0.0; + fpairOldEXP6_21 = 0.0; + + if(rmOld12_ij!=0.0 && rmOld21_ij!=0.0){ + if(alphaOld21_ij == 6.0 || alphaOld12_ij == 6.0) + k_error_flag.d_view() = 1; + + // A3. Compute some convenient quantities for evaluating the force + rminv = 1.0/rmOld12_ij; + buck1 = epsilonOld12_ij / (alphaOld12_ij - 6.0); + rexp = expValue(alphaOld12_ij*(1.0-r*rminv)); + rm2ij = rmOld12_ij*rmOld12_ij; + rm6ij = rm2ij*rm2ij*rm2ij; + + // Compute the shifted potential + rCutExp = expValue(alphaOld12_ij*(1.0-rCut*rminv)); + buck2 = 6.0*alphaOld12_ij; + urc = buck1*(6.0*rCutExp - alphaOld12_ij*rm6ij*rCut6inv); + durc = -buck1*buck2*(rCutExp* rminv - rCutInv*rm6ij*rCut6inv); + rin1 = shift*rmOld12_ij*func_rin(alphaOld12_ij); + if(r < rin1){ + rin6 = rin1*rin1*rin1*rin1*rin1*rin1; + rin6inv = 1.0/rin6; + + rin1exp = expValue(alphaOld12_ij*(1.0-rin1*rminv)); + + uin1 = buck1*(6.0*rin1exp - alphaOld12_ij*rm6ij*rin6inv) - urc - durc*(rin1-rCut); + + win1 = buck1*buck2*(rin1*rin1exp*rminv - rm6ij*rin6inv) + rin1*durc; + + aRep = win1*powint(rin1,nRep)/nRep; + + uin1rep = aRep/powint(rin1,nRep); + + forceExp6 = double(nRep)*aRep/powint(r,nRep); + fpairOldEXP6_12 = factor_lj*forceExp6*r2inv; + + evdwlOldEXP6_12 = uin1 - uin1rep + aRep/powint(r,nRep); + } else { + forceExp6 = buck1*buck2*(r*rexp*rminv - rm6ij*r6inv) + r*durc; + fpairOldEXP6_12 = factor_lj*forceExp6*r2inv; + + evdwlOldEXP6_12 = buck1*(6.0*rexp - alphaOld12_ij*rm6ij*r6inv) - urc - durc*(r-rCut); + } + + // A3. Compute some convenient quantities for evaluating the force + rminv = 1.0/rmOld21_ij; + buck1 = epsilonOld21_ij / (alphaOld21_ij - 6.0); + buck2 = 6.0*alphaOld21_ij; + rexp = expValue(alphaOld21_ij*(1.0-r*rminv)); + rm2ij = rmOld21_ij*rmOld21_ij; + rm6ij = rm2ij*rm2ij*rm2ij; + + // Compute the shifted potential + rCutExp = expValue(alphaOld21_ij*(1.0-rCut*rminv)); + buck2 = 6.0*alphaOld21_ij; + urc = buck1*(6.0*rCutExp - alphaOld21_ij*rm6ij*rCut6inv); + durc = -buck1*buck2*(rCutExp* rminv - rCutInv*rm6ij*rCut6inv); + rin1 = shift*rmOld21_ij*func_rin(alphaOld21_ij); + + if(r < rin1){ + rin6 = rin1*rin1*rin1*rin1*rin1*rin1; + rin6inv = 1.0/rin6; + + rin1exp = expValue(alphaOld21_ij*(1.0-rin1*rminv)); + + uin1 = buck1*(6.0*rin1exp - alphaOld21_ij*rm6ij*rin6inv) - urc - durc*(rin1-rCut); + + win1 = buck1*buck2*(rin1*rin1exp*rminv - rm6ij*rin6inv) + rin1*durc; + + aRep = win1*powint(rin1,nRep)/nRep; + + uin1rep = aRep/powint(rin1,nRep); + + forceExp6 = double(nRep)*aRep/powint(r,nRep); + fpairOldEXP6_21 = factor_lj*forceExp6*r2inv; + + evdwlOldEXP6_21 = uin1 - uin1rep + aRep/powint(r,nRep); + } else { + forceExp6 = buck1*buck2*(r*rexp*rminv - rm6ij*r6inv) + r*durc; + fpairOldEXP6_21 = factor_lj*forceExp6*r2inv; + + evdwlOldEXP6_21 = buck1*(6.0*rexp - alphaOld21_ij*rm6ij*r6inv) - urc - durc*(r-rCut); + } + + if (isite1 == isite2) + evdwlOld = sqrt(mixWtSite1old_i*mixWtSite2old_j)*evdwlOldEXP6_12; + else + evdwlOld = sqrt(mixWtSite1old_i*mixWtSite2old_j)*evdwlOldEXP6_12 + sqrt(mixWtSite2old_i*mixWtSite1old_j)*evdwlOldEXP6_21; + + evdwlOld *= factor_lj; + + uCG_i += 0.5*evdwlOld; + if ((NEIGHFLAG==HALF || NEIGHFLAG==HALFTHREAD) && (NEWTON_PAIR || j < nlocal)) + t_uCG(tid,j) += 0.5*evdwlOld; + } + + if(rm12_ij!=0.0 && rm21_ij!=0.0){ + if(alpha21_ij == 6.0 || alpha12_ij == 6.0) + k_error_flag.d_view() = 1; + + // A3. Compute some convenient quantities for evaluating the force + rminv = 1.0/rm12_ij; + buck1 = epsilon12_ij / (alpha12_ij - 6.0); + buck2 = 6.0*alpha12_ij; + rexp = expValue(alpha12_ij*(1.0-r*rminv)); + rm2ij = rm12_ij*rm12_ij; + rm6ij = rm2ij*rm2ij*rm2ij; + + // Compute the shifted potential + rCutExp = expValue(alpha12_ij*(1.0-rCut*rminv)); + urc = buck1*(6.0*rCutExp - alpha12_ij*rm6ij*rCut6inv); + durc = -buck1*buck2*(rCutExp*rminv - rCutInv*rm6ij*rCut6inv); + rin1 = shift*rm12_ij*func_rin(alpha12_ij); + + if(r < rin1){ + rin6 = rin1*rin1*rin1*rin1*rin1*rin1; + rin6inv = 1.0/rin6; + + rin1exp = expValue(alpha12_ij*(1.0-rin1*rminv)); + + uin1 = buck1*(6.0*rin1exp - alpha12_ij*rm6ij*rin6inv) - urc - durc*(rin1-rCut); + + win1 = buck1*buck2*(rin1*rin1exp*rminv - rm6ij*rin6inv) + rin1*durc; + + aRep = win1*powint(rin1,nRep)/nRep; + + uin1rep = aRep/powint(rin1,nRep); + + evdwlEXP6_12 = uin1 - uin1rep + aRep/powint(r,nRep); + } else { + evdwlEXP6_12 = buck1*(6.0*rexp - alpha12_ij*rm6ij*r6inv) - urc - durc*(r-rCut); + } + + rminv = 1.0/rm21_ij; + buck1 = epsilon21_ij / (alpha21_ij - 6.0); + buck2 = 6.0*alpha21_ij; + rexp = expValue(alpha21_ij*(1.0-r*rminv)); + rm2ij = rm21_ij*rm21_ij; + rm6ij = rm2ij*rm2ij*rm2ij; + + // Compute the shifted potential + rCutExp = expValue(alpha21_ij*(1.0-rCut*rminv)); + urc = buck1*(6.0*rCutExp - alpha21_ij*rm6ij*rCut6inv); + durc = -buck1*buck2*(rCutExp*rminv - rCutInv*rm6ij*rCut6inv); + rin1 = shift*rm21_ij*func_rin(alpha21_ij); + + if(r < rin1){ + rin6 = rin1*rin1*rin1*rin1*rin1*rin1; + rin6inv = 1.0/rin6; + + rin1exp = expValue(alpha21_ij*(1.0-rin1*rminv)); + + uin1 = buck1*(6.0*rin1exp - alpha21_ij*rm6ij*rin6inv) - urc - durc*(rin1-rCut); + + win1 = buck1*buck2*(rin1*rin1exp*rminv - rm6ij*rin6inv) + rin1*durc; + + aRep = win1*powint(rin1,nRep)/nRep; + + uin1rep = aRep/powint(rin1,nRep); + + evdwlEXP6_21 = uin1 - uin1rep + aRep/powint(r,nRep); + } else { + evdwlEXP6_21 = buck1*(6.0*rexp - alpha21_ij*rm6ij*r6inv) - urc - durc*(r-rCut); + } + } + + // + // Apply Mixing Rule to get the overall force for the CG pair + // + if (isite1 == isite2) fpair = sqrt(mixWtSite1old_i*mixWtSite2old_j)*fpairOldEXP6_12; + else fpair = sqrt(mixWtSite1old_i*mixWtSite2old_j)*fpairOldEXP6_12 + sqrt(mixWtSite2old_i*mixWtSite1old_j)*fpairOldEXP6_21; + + fx_i += delx*fpair; + fy_i += dely*fpair; + fz_i += delz*fpair; + if ((NEIGHFLAG==HALF || NEIGHFLAG==HALFTHREAD) && (NEWTON_PAIR || j < nlocal)) { + t_f(tid,j,0) -= delx*fpair; + t_f(tid,j,1) -= dely*fpair; + t_f(tid,j,2) -= delz*fpair; + } + + if (isite1 == isite2) evdwl = sqrt(mixWtSite1_i*mixWtSite2_j)*evdwlEXP6_12; + else evdwl = sqrt(mixWtSite1_i*mixWtSite2_j)*evdwlEXP6_12 + sqrt(mixWtSite2_i*mixWtSite1_j)*evdwlEXP6_21; + evdwl *= factor_lj; + + uCGnew_i += 0.5*evdwl; + if ((NEIGHFLAG==HALF || NEIGHFLAG==HALFTHREAD) && (NEWTON_PAIR || j < nlocal)) + t_uCGnew(tid,j) += 0.5*evdwl; + evdwl = evdwlOld; + if (EVFLAG) + ev.evdwl += (((NEIGHFLAG==HALF || NEIGHFLAG==HALFTHREAD) && (NEWTON_PAIR||(jtemplate ev_tally(ev,i,j,evdwl,fpair,delx,dely,delz); + } + } + + t_f(tid,i,0) += fx_i; + t_f(tid,i,1) += fy_i; + t_f(tid,i,2) += fz_i; + t_uCG(tid,i) += uCG_i; + t_uCGnew(tid,i) += uCGnew_i; +} + +template +template +KOKKOS_INLINE_FUNCTION +void PairExp6rxKokkos::operator()(TagPairExp6rxComputeNoAtomics, const int &ii) const { + EV_FLOAT ev; + this->template operator()(TagPairExp6rxComputeNoAtomics(), ii, ev); +} + +template +KOKKOS_INLINE_FUNCTION +void PairExp6rxKokkos::operator()(TagPairExp6rxCollapseDupViews, const int &i) const { + for (int n = 0; n < num_threads; n++) { + f(i,0) += t_f(n,i,0); + f(i,1) += t_f(n,i,1); + f(i,2) += t_f(n,i,2); + uCG(i) += t_uCG(n,i); + uCGnew(i) += t_uCGnew(n,i); + } +} + +template +KOKKOS_INLINE_FUNCTION +void PairExp6rxKokkos::operator()(TagPairExp6rxZeroDupViews, const int &i) const { + for (int n = 0; n < num_threads; n++) { + t_f(n,i,0) = 0.0; + t_f(n,i,1) = 0.0; + t_f(n,i,2) = 0.0; + t_uCG(n,i) = 0.0; + t_uCGnew(n,i) = 0.0; + } +} + + /* ---------------------------------------------------------------------- allocate all arrays ------------------------------------------------------------------------- */ diff --git a/src/KOKKOS/pair_exp6_rx_kokkos.h b/src/KOKKOS/pair_exp6_rx_kokkos.h index 488c9d0039..8754a73c96 100644 --- a/src/KOKKOS/pair_exp6_rx_kokkos.h +++ b/src/KOKKOS/pair_exp6_rx_kokkos.h @@ -57,6 +57,12 @@ struct TagPairExp6rxgetMixingWeights{}; template struct TagPairExp6rxCompute{}; +template +struct TagPairExp6rxComputeNoAtomics{}; + +struct TagPairExp6rxCollapseDupViews{}; +struct TagPairExp6rxZeroDupViews{}; + template class PairExp6rxKokkos : public PairExp6rx { public: @@ -81,6 +87,20 @@ class PairExp6rxKokkos : public PairExp6rx { KOKKOS_INLINE_FUNCTION void operator()(TagPairExp6rxCompute, const int&) const; + template + KOKKOS_INLINE_FUNCTION + void operator()(TagPairExp6rxComputeNoAtomics, const int&, EV_FLOAT&) const; + + template + KOKKOS_INLINE_FUNCTION + void operator()(TagPairExp6rxComputeNoAtomics, const int&) const; + + KOKKOS_INLINE_FUNCTION + void operator()(TagPairExp6rxCollapseDupViews, const int&) const; + + KOKKOS_INLINE_FUNCTION + void operator()(TagPairExp6rxZeroDupViews, const int&) const; + template KOKKOS_INLINE_FUNCTION void ev_tally(EV_FLOAT &ev, const int &i, const int &j, @@ -94,6 +114,7 @@ class PairExp6rxKokkos : public PairExp6rx { int eflag,vflag; int nlocal,newton_pair,neighflag; double special_lj[4]; + int num_threads; typename AT::t_x_array_randomread x; typename AT::t_f_array f; @@ -101,6 +122,12 @@ class PairExp6rxKokkos : public PairExp6rx { typename AT::t_efloat_1d uCG, uCGnew; typename AT::t_float_2d dvector; + typedef Kokkos::View t_f_array_thread; + typedef Kokkos::View t_efloat_1d_thread; + + t_f_array_thread t_f; + t_efloat_1d_thread t_uCG, t_uCGnew; + DAT::tdual_efloat_1d k_eatom; DAT::tdual_virial_array k_vatom; DAT::t_efloat_1d d_eatom; From acdb932c4ec56b2ce56a71280dab5c17b39f2c03 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Thu, 16 Mar 2017 09:28:27 -0600 Subject: [PATCH 206/439] Fixing index issue in pair_exp6_rx_kokkos --- src/KOKKOS/pair_exp6_rx_kokkos.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/KOKKOS/pair_exp6_rx_kokkos.cpp b/src/KOKKOS/pair_exp6_rx_kokkos.cpp index 8cf235964c..577d5261a3 100644 --- a/src/KOKKOS/pair_exp6_rx_kokkos.cpp +++ b/src/KOKKOS/pair_exp6_rx_kokkos.cpp @@ -236,7 +236,7 @@ void PairExp6rxKokkos::compute(int eflag_in, int vflag_in) } else { // No atomics num_threads = lmp->kokkos->num_threads; - int nmax = f.dimension_1(); + int nmax = f.dimension_0(); if (nmax > t_f.dimension_1()) { t_f = t_f_array_thread("pair_exp6_rx:t_f",num_threads,nmax); t_uCG = t_efloat_1d_thread("pair_exp6_rx:t_uCG",num_threads,nmax); From f5b7361ef6b6dbeedb2ad2181a44db64943001bb Mon Sep 17 00:00:00 2001 From: "Christopher P. Stone" Date: Thu, 16 Mar 2017 21:31:30 -0400 Subject: [PATCH 207/439] Non-kokkos candidate of PairExp6rxKokkos::getMixingWeights to improve vectorization on the KNL. - Moved the particle loop inside a replica of getMixingWeights, getMixingWeightsVect, and refactored to improve vectorization. - Added OMP SIMD and OMP threading directly inside that function but will replace with kokkos parallel_for and parallel_reduce methods later. --- src/KOKKOS/pair_exp6_rx_kokkos.cpp | 473 ++++++++++++++++++++++++++++- src/KOKKOS/pair_exp6_rx_kokkos.h | 3 + 2 files changed, 475 insertions(+), 1 deletion(-) diff --git a/src/KOKKOS/pair_exp6_rx_kokkos.cpp b/src/KOKKOS/pair_exp6_rx_kokkos.cpp index abc158d72c..df663c9df9 100644 --- a/src/KOKKOS/pair_exp6_rx_kokkos.cpp +++ b/src/KOKKOS/pair_exp6_rx_kokkos.cpp @@ -53,6 +53,22 @@ using namespace MathSpecialKokkos; #define exp6PotentialType (1) #define isExp6PotentialType(_type) ( (_type) == exp6PotentialType ) +namespace /* anonymous */ +{ + +//typedef double TimerType; +//TimerType getTimeStamp(void) { return MPI_Wtime(); } +//double getElapsedTime( const TimerType &t0, const TimerType &t1) { return t1-t0; } + +typedef struct timespec TimerType; +TimerType getTimeStamp(void) { TimerType tick; clock_gettime( CLOCK_MONOTONIC, &tick); return tick; } +double getElapsedTime( const TimerType &t0, const TimerType &t1) +{ + return (t1.tv_sec - t0.tv_sec) + 1e-9*(t1.tv_nsec - t0.tv_nsec); +} + +} // end namespace + /* ---------------------------------------------------------------------- */ template @@ -121,6 +137,8 @@ void PairExp6rxKokkos::init_style() template void PairExp6rxKokkos::compute(int eflag_in, int vflag_in) { + TimerType t_start = getTimeStamp(); + copymode = 1; eflag = eflag_in; @@ -165,6 +183,7 @@ void PairExp6rxKokkos::compute(int eflag_in, int vflag_in) // and ghost atoms. Make the parameter data persistent // and exchange like any other atom property later. + TimerType t_mix_start = getTimeStamp(); { const int np_total = nlocal + atom->nghost; @@ -185,8 +204,77 @@ void PairExp6rxKokkos::compute(int eflag_in, int vflag_in) PairExp6ParamData.rmOld2 = typename AT::t_float_1d("PairExp6ParamData.rmOld2" ,np_total); PairExp6ParamData.mixWtSite2old = typename AT::t_float_1d("PairExp6ParamData.mixWtSite2old",np_total); - Kokkos::parallel_for(Kokkos::RangePolicy(0,np_total),*this); + //Kokkos::parallel_for(Kokkos::RangePolicy(0,np_total),*this); + + //typename AT::t_float_1d epsilon1 ("epsilon1" ,np_total); + //typename AT::t_float_1d alpha1 ("alpha1" ,np_total); + //typename AT::t_float_1d rm1 ("rm1" ,np_total); + //typename AT::t_float_1d mixWtSite1 ("mixWtSite1" ,np_total); + //typename AT::t_float_1d epsilon2 ("epsilon2" ,np_total); + //typename AT::t_float_1d alpha2 ("alpha2" ,np_total); + //typename AT::t_float_1d rm2 ("rm2" ,np_total); + //typename AT::t_float_1d mixWtSite2 ("mixWtSite2" ,np_total); + //typename AT::t_float_1d epsilonOld1 ("epsilonOld1" ,np_total); + //typename AT::t_float_1d alphaOld1 ("alphaOld1" ,np_total); + //typename AT::t_float_1d rmOld1 ("rmOld1" ,np_total); + //typename AT::t_float_1d mixWtSite1old("mixWtSite1old",np_total); + //typename AT::t_float_1d epsilonOld2 ("epsilonOld2" ,np_total); + //typename AT::t_float_1d alphaOld2 ("alphaOld2" ,np_total); + //typename AT::t_float_1d rmOld2 ("rmOld2" ,np_total); + //typename AT::t_float_1d mixWtSite2old("mixWtSite2old",np_total); + + int errorFlag = 0; + getMixingWeightsVect (np_total, errorFlag, PairExp6ParamData.epsilon1, + PairExp6ParamData.alpha1, + PairExp6ParamData.rm1, + PairExp6ParamData.mixWtSite1, + PairExp6ParamData.epsilon2, + PairExp6ParamData.alpha2, + PairExp6ParamData.rm2, + PairExp6ParamData.mixWtSite2, + PairExp6ParamData.epsilonOld1, + PairExp6ParamData.alphaOld1, + PairExp6ParamData.rmOld1, + PairExp6ParamData.mixWtSite1old, + PairExp6ParamData.epsilonOld2, + PairExp6ParamData.alphaOld2, + PairExp6ParamData.rmOld2, + PairExp6ParamData.mixWtSite2old); + if (errorFlag == 1) + error->all(FLERR,"The number of molecules in CG particle is less than 10*DBL_EPSILON."); + else if (errorFlag == 2) + error->all(FLERR,"Computed fraction less than -10*DBL_EPSILON"); + + //#define _test_var(var) { \ + // double ref2 = 0, err2 = 0; \ + // for (int id = 0; id < np_total; ++id) \ + // { \ + // double ref = PairExp6ParamData. var [id]; \ + // double diff = ref - var[id]; \ + // ref2 += ref*ref; \ + // err2 += diff*diff; \ + // } \ + // if (ref2 < 1e-20) ref2 = 1.0; \ + // if (sqrt(err2)/sqrt(ref2) > 1e-12) \ + // printf("%s: %e %e %e\n", # var, sqrt(ref2), sqrt(err2), sqrt(err2)/sqrt(ref2)); \ + //} + //_test_var( epsilon1); + //_test_var( alpha1); + //_test_var( rm1); + //_test_var( epsilon2); + //_test_var( alpha2); + //_test_var( rm2); + //_test_var( mixWtSite2); + //_test_var( epsilonOld1); + //_test_var( alphaOld1); + //_test_var( rmOld1); + //_test_var( mixWtSite1old); + //_test_var( epsilonOld2); + //_test_var( alphaOld2); + //_test_var( rmOld2); + //_test_var( mixWtSite2old); } + TimerType t_mix_stop = getTimeStamp(); k_error_flag.template modify(); k_error_flag.template sync(); @@ -259,6 +347,9 @@ void PairExp6rxKokkos::compute(int eflag_in, int vflag_in) } copymode = 0; + + TimerType t_stop = getTimeStamp(); + printf("PairExp6rxKokkos::compute %f %f\n", getElapsedTime(t_start, t_stop), getElapsedTime(t_mix_start, t_mix_stop)); } template @@ -917,6 +1008,7 @@ void PairExp6rxKokkos::getMixingWeights(int id,double &epsilon1,doub nMoleculesOld2 = dvector(ispecies+nspecies,id); nMolecules2 = dvector(ispecies,id); fractionOld2 = dvector(ispecies+nspecies,id)/nTotalold; + fraction2 = nMolecules2/nTotal; } // If Site1 or Site2 matches is a fluid, then compute the paramters @@ -1072,6 +1164,385 @@ void PairExp6rxKokkos::getMixingWeights(int id,double &epsilon1,doub } } +#ifdef _OPENMP +void partition_range( const int begin, const int end, int &thread_begin, int &thread_end, const int chunkSize = 1) +{ + int threadId = omp_get_thread_num(); + int nThreads = omp_get_num_threads(); + + const int len = end - begin; + const int nBlocks = (len + (chunkSize - 1)) / chunkSize; + const int nBlocksPerThread = nBlocks / nThreads; + const int nRemaining = nBlocks - nBlocksPerThread * nThreads; + int block_lo, block_hi; + if (threadId < nRemaining) + { + block_lo = threadId * nBlocksPerThread + threadId; + block_hi = block_lo + nBlocksPerThread + 1; + } + else + { + block_lo = threadId * nBlocksPerThread + nRemaining; + block_hi = block_lo + nBlocksPerThread; + } + + thread_begin = std::min(begin + block_lo * chunkSize, end); + thread_end = std::min(begin + block_hi * chunkSize, end); + //printf("tid: %d %d %d %d %d\n", threadId, block_lo, block_hi, thread_begin, thread_end); +} +#endif + +/* ---------------------------------------------------------------------- */ + +template + template +void PairExp6rxKokkos::getMixingWeightsVect(const int np_total, int errorFlag, + ArrayT &epsilon1, ArrayT &alpha1, ArrayT &rm1, ArrayT &mixWtSite1, ArrayT &epsilon2, ArrayT &alpha2, ArrayT &rm2, ArrayT &mixWtSite2, ArrayT &epsilon1_old, ArrayT &alpha1_old, ArrayT &rm1_old, ArrayT &mixWtSite1old, ArrayT &epsilon2_old, ArrayT &alpha2_old, ArrayT &rm2_old, ArrayT &mixWtSite2old) const +{ + ArrayT epsilon("PairExp6ParamData.epsilon", np_total); + ArrayT rm3("PairExp6ParamData.rm3", np_total); + ArrayT alpha("PairExp6ParamData.alpha", np_total); + ArrayT xMolei("PairExp6ParamData.xMolei", np_total); + + ArrayT epsilon_old("PairExp6ParamData.epsilon_old", np_total); + ArrayT rm3_old("PairExp6ParamData.rm3_old", np_total); + ArrayT alpha_old("PairExp6ParamData.alpha_old", np_total); + ArrayT xMolei_old("PairExp6ParamData.xMolei_old", np_total); + + ArrayT fractionOFA("PairExp6ParamData.fractionOFA", np_total); + ArrayT fraction1("PairExp6ParamData.fraction1", np_total); + ArrayT fraction2("PairExp6ParamData.fraction2", np_total); + ArrayT nMoleculesOFA("PairExp6ParamData.nMoleculesOFA", np_total); + ArrayT nMolecules1("PairExp6ParamData.nMolecules1", np_total); + ArrayT nMolecules2("PairExp6ParamData.nMolecules2", np_total); + ArrayT nTotal("PairExp6ParamData.nTotal", np_total); + + ArrayT fractionOFAold("PairExp6ParamData.fractionOFAold", np_total); + ArrayT fractionOld1("PairExp6ParamData.fractionOld1", np_total); + ArrayT fractionOld2("PairExp6ParamData.fractionOld2", np_total); + ArrayT nMoleculesOFAold("PairExp6ParamData.nMoleculesOFAold", np_total); + ArrayT nMoleculesOld1("PairExp6ParamData.nMoleculesOld1", np_total); + ArrayT nMoleculesOld2("PairExp6ParamData.nMoleculesOld2", np_total); + ArrayT nTotalold("PairExp6ParamData.nTotalold", np_total); + + int errorFlag1 = 0, errorFlag2 = 0; + +#ifdef _OPENMP + #pragma omp parallel reduction(+: errorFlag1, errorFlag2) +#endif + { + int idx_begin = 0, idx_end = np_total; +#ifdef _OPENMP + partition_range( 0, np_total, idx_begin, idx_end, 16 ); +#endif + + // Zero out all of the terms first. + #pragma ivdep + for (int id = idx_begin; id < idx_end; ++id) + { + rm3[id] = 0.0; + epsilon[id] = 0.0; + alpha[id] = 0.0; + epsilon_old[id] = 0.0; + rm3_old[id] = 0.0; + alpha_old[id] = 0.0; + fractionOFA[id] = 0.0; + fractionOFAold[id] = 0.0; + nMoleculesOFA[id] = 0.0; + nMoleculesOFAold[id] = 0.0; + nTotal[id] = 0.0; + nTotalold[id] = 0.0; + } + + // Compute the total number of molecules in the old and new CG particle as well as the total number of molecules in the fluid portion of the old and new CG particle + for (int ispecies = 0; ispecies < nspecies; ispecies++) + { + #pragma ivdep + for (int id = idx_begin; id < idx_end; ++id) + { + nTotal[id] += dvector(ispecies,id); + nTotalold[id] += dvector(ispecies+nspecies,id); + } + + const int iparam = d_mol2param[ispecies]; + + if (iparam < 0 || d_params[iparam].potentialType != exp6PotentialType ) continue; + if (isOneFluidApprox(isite1) || isOneFluidApprox(isite2)) { + if (isite1 == d_params[iparam].ispecies || isite2 == d_params[iparam].ispecies) continue; + + #pragma ivdep + for (int id = idx_begin; id < idx_end; ++id) + { + nMoleculesOFAold[id] += dvector(ispecies+nspecies,id); + nMoleculesOFA[id] += dvector(ispecies,id); + } + } + } + + // Make a reduction. + #pragma omp simd reduction(+:errorFlag1) + for (int id = idx_begin; id < idx_end; ++id) + { + if ( nTotal[id] < MY_EPSILON || nTotalold[id] < MY_EPSILON ) + errorFlag1 = 1; + + // Compute the mole fraction of molecules within the fluid portion of the particle (One Fluid Approximation) + fractionOFAold[id] = nMoleculesOFAold[id] / nTotalold[id]; + fractionOFA[id] = nMoleculesOFA[id] / nTotal[id]; + } + + for (int ispecies = 0; ispecies < nspecies; ispecies++) { + const int iparam = d_mol2param[ispecies]; + if (iparam < 0 || d_params[iparam].potentialType != exp6PotentialType ) continue; + + // If Site1 matches a pure species, then grab the parameters + if (isite1 == d_params[iparam].ispecies) + { + #pragma ivdep + for (int id = idx_begin; id < idx_end; ++id) + { + rm1_old[id] = d_params[iparam].rm; + rm1[id] = d_params[iparam].rm; + epsilon1_old[id] = d_params[iparam].epsilon; + epsilon1[id] = d_params[iparam].epsilon; + alpha1_old[id] = d_params[iparam].alpha; + alpha1[id] = d_params[iparam].alpha; + + // Compute the mole fraction of Site1 + nMoleculesOld1[id] = dvector(ispecies+nspecies,id); + nMolecules1[id] = dvector(ispecies,id); + fractionOld1[id] = nMoleculesOld1[id]/nTotalold[id]; + fraction1[id] = nMolecules1[id]/nTotal[id]; + } + } + + // If Site2 matches a pure species, then grab the parameters + if (isite2 == d_params[iparam].ispecies) + { + #pragma ivdep + for (int id = idx_begin; id < idx_end; ++id) + { + rm2_old[id] = d_params[iparam].rm; + rm2[id] = d_params[iparam].rm; + epsilon2_old[id] = d_params[iparam].epsilon; + epsilon2[id] = d_params[iparam].epsilon; + alpha2_old[id] = d_params[iparam].alpha; + alpha2[id] = d_params[iparam].alpha; + + // Compute the mole fraction of Site2 + nMoleculesOld2[id] = dvector(ispecies+nspecies,id); + nMolecules2[id] = dvector(ispecies,id); + fractionOld2[id] = nMoleculesOld2[id]/nTotalold[id]; + fraction2[id] = nMolecules2[id]/nTotal[id]; + } + } + + // If Site1 or Site2 matches is a fluid, then compute the paramters + if (isOneFluidApprox(isite1) || isOneFluidApprox(isite2)) { + if (isite1 == d_params[iparam].ispecies || isite2 == d_params[iparam].ispecies) continue; + + const double rmi = d_params[iparam].rm; + const double epsiloni = d_params[iparam].epsilon; + const double alphai = d_params[iparam].alpha; + + #pragma ivdep + for (int id = idx_begin; id < idx_end; ++id) + { + if(nMoleculesOFA[id] 0.0){ + rm3_old[id] += xMolei_old[id]*xMolej_old*rm3ij; + epsilon_old[id] += xMolei_old[id]*xMolej_old*rm3ij*epsilonij; + alpha_old[id] += xMolei_old[id]*xMolej_old*rm3ij*epsilonij*alphaij; + } + if(fractionOFA[id] > 0.0){ + rm3[id] += xMolei[id]*xMolej*rm3ij; + epsilon[id] += xMolei[id]*xMolej*rm3ij*epsilonij; + alpha[id] += xMolei[id]*xMolej*rm3ij*epsilonij*alphaij; + } + } + } + } + } + + if (isOneFluidApprox(isite1)) + { + #pragma ivdep + for (int id = idx_begin; id < idx_end; ++id) + { + rm1[id] = cbrt(rm3[id]); + if(rm1[id] < MY_EPSILON) { + rm1[id] = 0.0; + epsilon1[id] = 0.0; + alpha1[id] = 0.0; + } else { + epsilon1[id] = epsilon[id] / rm3[id]; + alpha1[id] = alpha[id] / epsilon1[id] / rm3[id]; + } + nMolecules1[id] = 1.0-(nTotal[id]-nMoleculesOFA[id]); + fraction1[id] = fractionOFA[id]; + + rm1_old[id] = cbrt(rm3_old[id]); + if(rm1_old[id] < MY_EPSILON) { + rm1_old[id] = 0.0; + epsilon1_old[id] = 0.0; + alpha1_old[id] = 0.0; + } else { + epsilon1_old[id] = epsilon_old[id] / rm3_old[id]; + alpha1_old[id] = alpha_old[id] / epsilon1_old[id] / rm3_old[id]; + } + nMoleculesOld1[id] = 1.0-(nTotalold[id]-nMoleculesOFAold[id]); + fractionOld1[id] = fractionOFAold[id]; + } + + if(scalingFlag == EXPONENT) { + #pragma ivdep + for (int id = idx_begin; id < idx_end; ++id) + { + exponentScaling(nMoleculesOFA[id],epsilon1[id],rm1[id]); + exponentScaling(nMoleculesOFAold[id],epsilon1_old[id],rm1_old[id]); + } + } + else if(scalingFlag == POLYNOMIAL){ + #pragma ivdep + for (int id = idx_begin; id < idx_end; ++id) + { + polynomialScaling(nMoleculesOFA[id],alpha1[id],epsilon1[id],rm1[id]); + polynomialScaling(nMoleculesOFAold[id],alpha1_old[id],epsilon1_old[id],rm1_old[id]); + } + } + } + + if (isOneFluidApprox(isite2)) + { + #pragma ivdep + for (int id = idx_begin; id < idx_end; ++id) + { + rm2[id] = cbrt(rm3[id]); + if(rm2[id] < MY_EPSILON) { + rm2[id] = 0.0; + epsilon2[id] = 0.0; + alpha2[id] = 0.0; + } else { + epsilon2[id] = epsilon[id] / rm3[id]; + alpha2[id] = alpha[id] / epsilon2[id] / rm3[id]; + } + nMolecules2[id] = 1.0-(nTotal[id]-nMoleculesOFA[id]); + fraction2[id] = fractionOFA[id]; + + rm2_old[id] = cbrt(rm3_old[id]); + if(rm2_old[id] < MY_EPSILON) { + rm2_old[id] = 0.0; + epsilon2_old[id] = 0.0; + alpha2_old[id] = 0.0; + } else { + epsilon2_old[id] = epsilon_old[id] / rm3_old[id]; + alpha2_old[id] = alpha_old[id] / epsilon2_old[id] / rm3_old[id]; + } + nMoleculesOld2[id] = 1.0-(nTotalold[id]-nMoleculesOFAold[id]); + fractionOld2[id] = fractionOFAold[id]; + } + + if(scalingFlag == EXPONENT){ + #pragma ivdep + for (int id = idx_begin; id < idx_end; ++id) + { + exponentScaling(nMoleculesOFA[id],epsilon2[id],rm2[id]); + exponentScaling(nMoleculesOFAold[id],epsilon2_old[id],rm2_old[id]); + } + } + else if(scalingFlag == POLYNOMIAL){ + #pragma ivdep + for (int id = idx_begin; id < idx_end; ++id) + { + polynomialScaling(nMoleculesOFA[id],alpha2[id],epsilon2[id],rm2[id]); + polynomialScaling(nMoleculesOFAold[id],alpha2_old[id],epsilon2_old[id],rm2_old[id]); + } + } + } + + // Check that no fractions are less than zero + #pragma omp simd reduction(+:errorFlag2) + for (int id = idx_begin; id < idx_end; ++id) + { + if(fraction1[id] < 0.0 || nMolecules1[id] < 0.0){ + if(fraction1[id] < -MY_EPSILON || nMolecules1[id] < -MY_EPSILON){ + errorFlag2 = 2; + } + nMolecules1[id] = 0.0; + fraction1[id] = 0.0; + } + if(fraction2[id] < 0.0 || nMolecules2[id] < 0.0){ + if(fraction2[id] < -MY_EPSILON || nMolecules2[id] < -MY_EPSILON){ + errorFlag2 = 2; + } + nMolecules2[id] = 0.0; + fraction2[id] = 0.0; + } + if(fractionOld1[id] < 0.0 || nMoleculesOld1[id] < 0.0){ + if(fractionOld1[id] < -MY_EPSILON || nMoleculesOld1[id] < -MY_EPSILON){ + errorFlag2 = 2; + } + nMoleculesOld1[id] = 0.0; + fractionOld1[id] = 0.0; + } + if(fractionOld2[id] < 0.0 || nMoleculesOld2[id] < 0.0){ + if(fractionOld2[id] < -MY_EPSILON || nMoleculesOld2[id] < -MY_EPSILON){ + errorFlag2 = 2; + } + nMoleculesOld2[id] = 0.0; + fractionOld2[id] = 0.0; + } + + if(fractionalWeighting){ + mixWtSite1old[id] = fractionOld1[id]; + mixWtSite1[id] = fraction1[id]; + mixWtSite2old[id] = fractionOld2[id]; + mixWtSite2[id] = fraction2[id]; + } else { + mixWtSite1old[id] = nMoleculesOld1[id]; + mixWtSite1[id] = nMolecules1[id]; + mixWtSite2old[id] = nMoleculesOld2[id]; + mixWtSite2[id] = nMolecules2[id]; + } + } + + } // end parallel region + + if (errorFlag1 > 0) + errorFlag = 1; + + if (errorFlag2 > 0) + errorFlag = 2; +} + /* ---------------------------------------------------------------------- */ template diff --git a/src/KOKKOS/pair_exp6_rx_kokkos.h b/src/KOKKOS/pair_exp6_rx_kokkos.h index 488c9d0039..55b29f559b 100644 --- a/src/KOKKOS/pair_exp6_rx_kokkos.h +++ b/src/KOKKOS/pair_exp6_rx_kokkos.h @@ -133,6 +133,9 @@ class PairExp6rxKokkos : public PairExp6rx { KOKKOS_INLINE_FUNCTION void getMixingWeights(int, double &, double &, double &, double &, double &, double &, double &, double &, double &, double &, double &, double &, double &, double &, double &, double &) const; + template + void getMixingWeightsVect(const int, int, ArrayT &, ArrayT &, ArrayT &, ArrayT &, ArrayT &, ArrayT &, ArrayT &, ArrayT &, ArrayT &, ArrayT &, ArrayT &, ArrayT &, ArrayT &, ArrayT &, ArrayT &, ArrayT &) const; + KOKKOS_INLINE_FUNCTION void exponentScaling(double, double &, double &) const; From ec192a95cb1465184f29f9f6bae06da9815411dc Mon Sep 17 00:00:00 2001 From: "Christopher P. Stone" Date: Thu, 16 Mar 2017 22:28:19 -0400 Subject: [PATCH 208/439] Cleaned up the non-kokkos part of KOKKOS/pair_exp6_rx_kokkos.cpp --- src/KOKKOS/pair_exp6_rx_kokkos.cpp | 78 +++++++----------------------- 1 file changed, 17 insertions(+), 61 deletions(-) diff --git a/src/KOKKOS/pair_exp6_rx_kokkos.cpp b/src/KOKKOS/pair_exp6_rx_kokkos.cpp index df663c9df9..d1481e6a44 100644 --- a/src/KOKKOS/pair_exp6_rx_kokkos.cpp +++ b/src/KOKKOS/pair_exp6_rx_kokkos.cpp @@ -187,42 +187,26 @@ void PairExp6rxKokkos::compute(int eflag_in, int vflag_in) { const int np_total = nlocal + atom->nghost; - PairExp6ParamData.epsilon1 = typename AT::t_float_1d("PairExp6ParamData.epsilon1" ,np_total); - PairExp6ParamData.alpha1 = typename AT::t_float_1d("PairExp6ParamData.alpha1" ,np_total); - PairExp6ParamData.rm1 = typename AT::t_float_1d("PairExp6ParamData.rm1" ,np_total); + PairExp6ParamData.epsilon1 = typename AT::t_float_1d("PairExp6ParamData.epsilon1" ,np_total); + PairExp6ParamData.alpha1 = typename AT::t_float_1d("PairExp6ParamData.alpha1" ,np_total); + PairExp6ParamData.rm1 = typename AT::t_float_1d("PairExp6ParamData.rm1" ,np_total); PairExp6ParamData.mixWtSite1 = typename AT::t_float_1d("PairExp6ParamData.mixWtSite1" ,np_total); - PairExp6ParamData.epsilon2 = typename AT::t_float_1d("PairExp6ParamData.epsilon2" ,np_total); - PairExp6ParamData.alpha2 = typename AT::t_float_1d("PairExp6ParamData.alpha2" ,np_total); - PairExp6ParamData.rm2 = typename AT::t_float_1d("PairExp6ParamData.rm2" ,np_total); + PairExp6ParamData.epsilon2 = typename AT::t_float_1d("PairExp6ParamData.epsilon2" ,np_total); + PairExp6ParamData.alpha2 = typename AT::t_float_1d("PairExp6ParamData.alpha2" ,np_total); + PairExp6ParamData.rm2 = typename AT::t_float_1d("PairExp6ParamData.rm2" ,np_total); PairExp6ParamData.mixWtSite2 = typename AT::t_float_1d("PairExp6ParamData.mixWtSite2" ,np_total); - PairExp6ParamData.epsilonOld1 = typename AT::t_float_1d("PairExp6ParamData.epsilonOld1" ,np_total); - PairExp6ParamData.alphaOld1 = typename AT::t_float_1d("PairExp6ParamData.alphaOld1" ,np_total); - PairExp6ParamData.rmOld1 = typename AT::t_float_1d("PairExp6ParamData.rmOld1" ,np_total); + PairExp6ParamData.epsilonOld1 = typename AT::t_float_1d("PairExp6ParamData.epsilonOld1" ,np_total); + PairExp6ParamData.alphaOld1 = typename AT::t_float_1d("PairExp6ParamData.alphaOld1" ,np_total); + PairExp6ParamData.rmOld1 = typename AT::t_float_1d("PairExp6ParamData.rmOld1" ,np_total); PairExp6ParamData.mixWtSite1old = typename AT::t_float_1d("PairExp6ParamData.mixWtSite1old",np_total); - PairExp6ParamData.epsilonOld2 = typename AT::t_float_1d("PairExp6ParamData.epsilonOld2" ,np_total); - PairExp6ParamData.alphaOld2 = typename AT::t_float_1d("PairExp6ParamData.alphaOld2" ,np_total); - PairExp6ParamData.rmOld2 = typename AT::t_float_1d("PairExp6ParamData.rmOld2" ,np_total); + PairExp6ParamData.epsilonOld2 = typename AT::t_float_1d("PairExp6ParamData.epsilonOld2" ,np_total); + PairExp6ParamData.alphaOld2 = typename AT::t_float_1d("PairExp6ParamData.alphaOld2" ,np_total); + PairExp6ParamData.rmOld2 = typename AT::t_float_1d("PairExp6ParamData.rmOld2" ,np_total); PairExp6ParamData.mixWtSite2old = typename AT::t_float_1d("PairExp6ParamData.mixWtSite2old",np_total); - //Kokkos::parallel_for(Kokkos::RangePolicy(0,np_total),*this); - - //typename AT::t_float_1d epsilon1 ("epsilon1" ,np_total); - //typename AT::t_float_1d alpha1 ("alpha1" ,np_total); - //typename AT::t_float_1d rm1 ("rm1" ,np_total); - //typename AT::t_float_1d mixWtSite1 ("mixWtSite1" ,np_total); - //typename AT::t_float_1d epsilon2 ("epsilon2" ,np_total); - //typename AT::t_float_1d alpha2 ("alpha2" ,np_total); - //typename AT::t_float_1d rm2 ("rm2" ,np_total); - //typename AT::t_float_1d mixWtSite2 ("mixWtSite2" ,np_total); - //typename AT::t_float_1d epsilonOld1 ("epsilonOld1" ,np_total); - //typename AT::t_float_1d alphaOld1 ("alphaOld1" ,np_total); - //typename AT::t_float_1d rmOld1 ("rmOld1" ,np_total); - //typename AT::t_float_1d mixWtSite1old("mixWtSite1old",np_total); - //typename AT::t_float_1d epsilonOld2 ("epsilonOld2" ,np_total); - //typename AT::t_float_1d alphaOld2 ("alphaOld2" ,np_total); - //typename AT::t_float_1d rmOld2 ("rmOld2" ,np_total); - //typename AT::t_float_1d mixWtSite2old("mixWtSite2old",np_total); - +#ifdef KOKKOS_HAVE_CUDA + Kokkos::parallel_for(Kokkos::RangePolicy(0,np_total),*this); +#else int errorFlag = 0; getMixingWeightsVect (np_total, errorFlag, PairExp6ParamData.epsilon1, PairExp6ParamData.alpha1, @@ -244,35 +228,7 @@ void PairExp6rxKokkos::compute(int eflag_in, int vflag_in) error->all(FLERR,"The number of molecules in CG particle is less than 10*DBL_EPSILON."); else if (errorFlag == 2) error->all(FLERR,"Computed fraction less than -10*DBL_EPSILON"); - - //#define _test_var(var) { \ - // double ref2 = 0, err2 = 0; \ - // for (int id = 0; id < np_total; ++id) \ - // { \ - // double ref = PairExp6ParamData. var [id]; \ - // double diff = ref - var[id]; \ - // ref2 += ref*ref; \ - // err2 += diff*diff; \ - // } \ - // if (ref2 < 1e-20) ref2 = 1.0; \ - // if (sqrt(err2)/sqrt(ref2) > 1e-12) \ - // printf("%s: %e %e %e\n", # var, sqrt(ref2), sqrt(err2), sqrt(err2)/sqrt(ref2)); \ - //} - //_test_var( epsilon1); - //_test_var( alpha1); - //_test_var( rm1); - //_test_var( epsilon2); - //_test_var( alpha2); - //_test_var( rm2); - //_test_var( mixWtSite2); - //_test_var( epsilonOld1); - //_test_var( alphaOld1); - //_test_var( rmOld1); - //_test_var( mixWtSite1old); - //_test_var( epsilonOld2); - //_test_var( alphaOld2); - //_test_var( rmOld2); - //_test_var( mixWtSite2old); +#endif } TimerType t_mix_stop = getTimeStamp(); @@ -349,7 +305,7 @@ void PairExp6rxKokkos::compute(int eflag_in, int vflag_in) copymode = 0; TimerType t_stop = getTimeStamp(); - printf("PairExp6rxKokkos::compute %f %f\n", getElapsedTime(t_start, t_stop), getElapsedTime(t_mix_start, t_mix_stop)); + //printf("PairExp6rxKokkos::compute %f %f\n", getElapsedTime(t_start, t_stop), getElapsedTime(t_mix_start, t_mix_stop)); } template From 64fdb1f528bcaacc8c6a7ad1ea1b4824533af838 Mon Sep 17 00:00:00 2001 From: "Christopher P. Stone" Date: Fri, 17 Mar 2017 15:52:40 -0400 Subject: [PATCH 209/439] Kokkos/pair_exp6_rx_kokkos optimized for SIMD on the inner j-loop. --- src/KOKKOS/pair_exp6_rx_kokkos.cpp | 518 ++++++++++++++++++++++++++++- src/KOKKOS/pair_exp6_rx_kokkos.h | 4 + 2 files changed, 521 insertions(+), 1 deletion(-) diff --git a/src/KOKKOS/pair_exp6_rx_kokkos.cpp b/src/KOKKOS/pair_exp6_rx_kokkos.cpp index 64a91c9e65..85d919091f 100644 --- a/src/KOKKOS/pair_exp6_rx_kokkos.cpp +++ b/src/KOKKOS/pair_exp6_rx_kokkos.cpp @@ -349,7 +349,7 @@ void PairExp6rxKokkos::compute(int eflag_in, int vflag_in) copymode = 0; TimerType t_stop = getTimeStamp(); - //printf("PairExp6rxKokkos::compute %f %f\n", getElapsedTime(t_start, t_stop), getElapsedTime(t_mix_start, t_mix_stop)); + printf("PairExp6rxKokkos::compute %f %f\n", getElapsedTime(t_start, t_stop), getElapsedTime(t_mix_start, t_mix_stop)); } template @@ -378,6 +378,14 @@ template KOKKOS_INLINE_FUNCTION void PairExp6rxKokkos::operator()(TagPairExp6rxCompute, const int &ii, EV_FLOAT& ev) const { + { + if (isite1 == isite2) + this->vectorized_operator(ii, ev); + else + this->vectorized_operator(ii, ev); + return; + } + // These arrays are atomic for Half/Thread neighbor style Kokkos::View::value> > a_f = f; Kokkos::View::value> > a_uCG = uCG; @@ -734,6 +742,14 @@ template KOKKOS_INLINE_FUNCTION void PairExp6rxKokkos::operator()(TagPairExp6rxComputeNoAtomics, const int &ii, EV_FLOAT& ev) const { + { + if (isite1 == isite2) + this->vectorized_operator(ii, ev); + else + this->vectorized_operator(ii, ev); + return; + } + int tid = 0; #ifndef KOKKOS_HAVE_CUDA tid = DeviceType::hardware_thread_id(); @@ -1075,6 +1091,506 @@ void PairExp6rxKokkos::operator()(TagPairExp6rxComputeNoAtomics + KOKKOS_INLINE_FUNCTION +double __powint(const double& x, const int) +{ + static_assert(n == 12, "__powint<> only supports specific integer powers."); + + if (n == 12) + { + // Do x^12 here ... x^12 = (x^3)^4 + double x3 = x*x*x; + return x3*x3*x3*x3; + } +} + +template + template +KOKKOS_INLINE_FUNCTION +void PairExp6rxKokkos::vectorized_operator(const int &ii, EV_FLOAT& ev) const +{ + // These arrays are atomic for Half/Thread neighbor style + Kokkos::View::value> > a_f = f; + Kokkos::View::value> > a_uCG = uCG; + Kokkos::View::value> > a_uCGnew = uCGnew; + + int tid = 0; +#ifndef KOKKOS_HAVE_CUDA + tid = DeviceType::hardware_thread_id(); +#endif + + const int nRep = 12; + const double shift = 1.05; + + const int i = d_ilist[ii]; + const double xtmp = x(i,0); + const double ytmp = x(i,1); + const double ztmp = x(i,2); + const int itype = type[i]; + const int jnum = d_numneigh[i]; + + double fx_i = 0.0; + double fy_i = 0.0; + double fz_i = 0.0; + double uCG_i = 0.0; + double uCGnew_i = 0.0; + + // Constant values for this atom. + const double epsilon1_i = PairExp6ParamData.epsilon1[i]; + const double alpha1_i = PairExp6ParamData.alpha1[i]; + const double rm1_i = PairExp6ParamData.rm1[i]; + const double mixWtSite1_i = PairExp6ParamData.mixWtSite1[i]; + const double epsilon2_i = PairExp6ParamData.epsilon2[i]; + const double alpha2_i = PairExp6ParamData.alpha2[i]; + const double rm2_i = PairExp6ParamData.rm2[i]; + const double mixWtSite2_i = PairExp6ParamData.mixWtSite2[i]; + const double epsilonOld1_i = PairExp6ParamData.epsilonOld1[i]; + const double alphaOld1_i = PairExp6ParamData.alphaOld1[i]; + const double rmOld1_i = PairExp6ParamData.rmOld1[i]; + const double mixWtSite1old_i = PairExp6ParamData.mixWtSite1old[i]; + const double epsilonOld2_i = PairExp6ParamData.epsilonOld2[i]; + const double alphaOld2_i = PairExp6ParamData.alphaOld2[i]; + const double rmOld2_i = PairExp6ParamData.rmOld2[i]; + const double mixWtSite2old_i = PairExp6ParamData.mixWtSite2old[i]; + + // Do error testing locally. + bool hasError = false; + + // Process this many neighbors concurrently -- if possible. + const int batchSize = 8; + + int neigh_j[batchSize]; + double evdwlOld_j[batchSize]; + double uCGnew_j[batchSize]; + double fpair_j[batchSize]; + double delx_j[batchSize]; + double dely_j[batchSize]; + double delz_j[batchSize]; + double cutsq_j[batchSize]; + //double j_epsilon1[batchSize] ; + //double j_alpha1[batchSize] ; + //double j_rm1[batchSize] ; + //double j_mixWtSite1[batchSize] ; + //double j_epsilon2[batchSize] ; + //double j_alpha2[batchSize] ; + //double j_rm2[batchSize] ; + //double j_mixWtSite2[batchSize] ; + //double j_epsilonOld1[batchSize] ; + //double j_alphaOld1[batchSize] ; + //double j_rmOld1[batchSize] ; + //double j_mixWtSite1old[batchSize] ; + //double j_epsilonOld2[batchSize] ; + //double j_alphaOld2[batchSize] ; + //double j_rmOld2[batchSize] ; + //double j_mixWtSite2old[batchSize] ; + + for (int jptr = 0; jptr < jnum; ) + { + // The core computation here is very expensive so let's only bother with + // those that pass rsq < cutsq. + + for (int j = 0; j < batchSize; ++j) + { + evdwlOld_j[j] = 0.0; + uCGnew_j[j] = 0.0; + fpair_j[j] = 0.0; + //delx_j[j] = 0.0; + //dely_j[j] = 0.0; + //delz_j[j] = 0.0; + //cutsq_j[j] = 0.0; + } + + int niters = 0; + + for (; (jptr < jnum) && (niters < batchSize); ++jptr) + { + const int j = d_neighbors(i,jptr) & NEIGHMASK; + + const double delx = xtmp - x(j,0); + const double dely = ytmp - x(j,1); + const double delz = ztmp - x(j,2); + + const double rsq = delx*delx + dely*dely + delz*delz; + const int jtype = type[j]; + + if (rsq < d_cutsq(itype,jtype)) + { + delx_j [niters] = delx; + dely_j [niters] = dely; + delz_j [niters] = delz; + cutsq_j[niters] = d_cutsq(itype,jtype); + + neigh_j[niters] = d_neighbors(i,jptr); + + //j_epsilon1[niters] = PairExp6ParamData.epsilon1[j]; + //j_alpha1[niters] = PairExp6ParamData.alpha1[j]; + //j_rm1[niters] = PairExp6ParamData.rm1[j]; + //j_mixWtSite1[niters] = PairExp6ParamData.mixWtSite1[j]; + //j_epsilon2[niters] = PairExp6ParamData.epsilon2[j]; + //j_alpha2[niters] = PairExp6ParamData.alpha2[j]; + //j_rm2[niters] = PairExp6ParamData.rm2[j]; + //j_mixWtSite2[niters] = PairExp6ParamData.mixWtSite2[j]; + //j_epsilonOld1[niters] = PairExp6ParamData.epsilonOld1[j]; + //j_alphaOld1[niters] = PairExp6ParamData.alphaOld1[j]; + //j_rmOld1[niters] = PairExp6ParamData.rmOld1[j]; + //j_mixWtSite1old[niters] = PairExp6ParamData.mixWtSite1old[j]; + //j_epsilonOld2[niters] = PairExp6ParamData.epsilonOld2[j]; + //j_alphaOld2[niters] = PairExp6ParamData.alphaOld2[j]; + //j_rmOld2[niters] = PairExp6ParamData.rmOld2[j]; + //j_mixWtSite2old[niters] = PairExp6ParamData.mixWtSite2old[j]; + + ++niters; + } + } + + // reduction here. + #pragma simd reduction(+: fx_i, fy_i, fz_i, uCG_i, uCGnew_i) reduction(|: hasError) + for (int jlane = 0; jlane < niters; jlane++) + { + int j = neigh_j[jlane]; + const double factor_lj = special_lj[sbmask(j)]; + j &= NEIGHMASK; + + const double delx = delx_j[jlane]; + const double dely = dely_j[jlane]; + const double delz = delz_j[jlane]; + + const double rsq = delx*delx + dely*dely + delz*delz; + // const int jtype = type[j]; + + // if (rsq < d_cutsq(itype,jtype)) // optimize + { + const double r2inv = 1.0/rsq; + const double r6inv = r2inv*r2inv*r2inv; + + const double r = sqrt(rsq); + const double rCut2inv = 1.0/ cutsq_j[jlane]; + const double rCut6inv = rCut2inv*rCut2inv*rCut2inv; + const double rCut = sqrt( cutsq_j[jlane] ); + const double rCutInv = 1.0/rCut; + + // + // A. Compute the exp-6 potential + // + + // A1. Get alpha, epsilon and rm for particle j + + const double epsilon1_j = PairExp6ParamData.epsilon1[j]; + const double alpha1_j = PairExp6ParamData.alpha1[j]; + const double rm1_j = PairExp6ParamData.rm1[j]; + const double mixWtSite1_j = PairExp6ParamData.mixWtSite1[j]; + const double epsilon2_j = PairExp6ParamData.epsilon2[j]; + const double alpha2_j = PairExp6ParamData.alpha2[j]; + const double rm2_j = PairExp6ParamData.rm2[j]; + const double mixWtSite2_j = PairExp6ParamData.mixWtSite2[j]; + const double epsilonOld1_j = PairExp6ParamData.epsilonOld1[j]; + const double alphaOld1_j = PairExp6ParamData.alphaOld1[j]; + const double rmOld1_j = PairExp6ParamData.rmOld1[j]; + const double mixWtSite1old_j = PairExp6ParamData.mixWtSite1old[j]; + const double epsilonOld2_j = PairExp6ParamData.epsilonOld2[j]; + const double alphaOld2_j = PairExp6ParamData.alphaOld2[j]; + const double rmOld2_j = PairExp6ParamData.rmOld2[j]; + const double mixWtSite2old_j = PairExp6ParamData.mixWtSite2old[j]; + //const double epsilon1_j = j_epsilon1[jlane]; + //const double alpha1_j = j_alpha1[jlane]; + //const double rm1_j = j_rm1[jlane]; + //const double mixWtSite1_j = j_mixWtSite1[jlane]; + //const double epsilon2_j = j_epsilon2[jlane]; + //const double alpha2_j = j_alpha2[jlane]; + //const double rm2_j = j_rm2[jlane]; + //const double mixWtSite2_j = j_mixWtSite2[jlane]; + //const double epsilonOld1_j = j_epsilonOld1[jlane]; + //const double alphaOld1_j = j_alphaOld1[jlane]; + //const double rmOld1_j = j_rmOld1[jlane]; + //const double mixWtSite1old_j = j_mixWtSite1old[jlane]; + //const double epsilonOld2_j = j_epsilonOld2[jlane]; + //const double alphaOld2_j = j_alphaOld2[jlane]; + //const double rmOld2_j = j_rmOld2[jlane]; + //const double mixWtSite2old_j = j_mixWtSite2old[jlane]; + + // A2. Apply Lorentz-Berthelot mixing rules for the i-j pair + const double alphaOld12_ij = sqrt(alphaOld1_i*alphaOld2_j); + const double rmOld12_ij = 0.5*(rmOld1_i + rmOld2_j); + const double epsilonOld12_ij = sqrt(epsilonOld1_i*epsilonOld2_j); + const double alphaOld21_ij = sqrt(alphaOld2_i*alphaOld1_j); + const double rmOld21_ij = 0.5*(rmOld2_i + rmOld1_j); + const double epsilonOld21_ij = sqrt(epsilonOld2_i*epsilonOld1_j); + + const double alpha12_ij = sqrt(alpha1_i*alpha2_j); + const double rm12_ij = 0.5*(rm1_i + rm2_j); + const double epsilon12_ij = sqrt(epsilon1_i*epsilon2_j); + const double alpha21_ij = sqrt(alpha2_i*alpha1_j); + const double rm21_ij = 0.5*(rm2_i + rm1_j); + const double epsilon21_ij = sqrt(epsilon2_i*epsilon1_j); + + double evdwlOldEXP6_12 = 0.0; + double evdwlOldEXP6_21 = 0.0; + double evdwlEXP6_12 = 0.0; + double evdwlEXP6_21 = 0.0; + double fpairOldEXP6_12 = 0.0; + double fpairOldEXP6_21 = 0.0; + + if(rmOld12_ij!=0.0 && rmOld21_ij!=0.0) + { + hasError |= (alphaOld21_ij == 6.0 || alphaOld12_ij == 6.0); + + // A3. Compute some convenient quantities for evaluating the force + double rminv = 1.0/rmOld12_ij; + double buck1 = epsilonOld12_ij / (alphaOld12_ij - 6.0); + double rexp = expValue(alphaOld12_ij*(1.0-r*rminv)); + double rm2ij = rmOld12_ij*rmOld12_ij; + double rm6ij = rm2ij*rm2ij*rm2ij; + + // Compute the shifted potential + double rCutExp = expValue(alphaOld12_ij*(1.0-rCut*rminv)); + double buck2 = 6.0*alphaOld12_ij; + double urc = buck1*(6.0*rCutExp - alphaOld12_ij*rm6ij*rCut6inv); + double durc = -buck1*buck2*(rCutExp* rminv - rCutInv*rm6ij*rCut6inv); + double rin1 = shift*rmOld12_ij*func_rin(alphaOld12_ij); + + if(r < rin1){ + const double rin6 = rin1*rin1*rin1*rin1*rin1*rin1; + const double rin6inv = 1.0/rin6; + + const double rin1exp = expValue(alphaOld12_ij*(1.0-rin1*rminv)); + + const double uin1 = buck1*(6.0*rin1exp - alphaOld12_ij*rm6ij*rin6inv) - urc - durc*(rin1-rCut); + + const double win1 = buck1*buck2*(rin1*rin1exp*rminv - rm6ij*rin6inv) + rin1*durc; + + const double aRep = win1*__powint<12>(rin1,nRep)/nRep; + + const double uin1rep = aRep/__powint<12>(rin1,nRep); + + const double forceExp6 = double(nRep)*aRep/__powint<12>(r,nRep); + fpairOldEXP6_12 = factor_lj*forceExp6*r2inv; + + evdwlOldEXP6_12 = uin1 - uin1rep + aRep/__powint<12>(r,nRep); + } else { + const double forceExp6 = buck1*buck2*(r*rexp*rminv - rm6ij*r6inv) + r*durc; + fpairOldEXP6_12 = factor_lj*forceExp6*r2inv; + + evdwlOldEXP6_12 = buck1*(6.0*rexp - alphaOld12_ij*rm6ij*r6inv) - urc - durc*(r-rCut); + } + + // A3. Compute some convenient quantities for evaluating the force + rminv = 1.0/rmOld21_ij; + buck1 = epsilonOld21_ij / (alphaOld21_ij - 6.0); + buck2 = 6.0*alphaOld21_ij; + rexp = expValue(alphaOld21_ij*(1.0-r*rminv)); + rm2ij = rmOld21_ij*rmOld21_ij; + rm6ij = rm2ij*rm2ij*rm2ij; + + // Compute the shifted potential + rCutExp = expValue(alphaOld21_ij*(1.0-rCut*rminv)); + buck2 = 6.0*alphaOld21_ij; + urc = buck1*(6.0*rCutExp - alphaOld21_ij*rm6ij*rCut6inv); + durc = -buck1*buck2*(rCutExp* rminv - rCutInv*rm6ij*rCut6inv); + rin1 = shift*rmOld21_ij*func_rin(alphaOld21_ij); + + if(r < rin1){ + const double rin6 = rin1*rin1*rin1*rin1*rin1*rin1; + const double rin6inv = 1.0/rin6; + + const double rin1exp = expValue(alphaOld21_ij*(1.0-rin1*rminv)); + + const double uin1 = buck1*(6.0*rin1exp - alphaOld21_ij*rm6ij*rin6inv) - urc - durc*(rin1-rCut); + + const double win1 = buck1*buck2*(rin1*rin1exp*rminv - rm6ij*rin6inv) + rin1*durc; + + const double aRep = win1*__powint<12>(rin1,nRep)/nRep; + + const double uin1rep = aRep/__powint<12>(rin1,nRep); + + const double forceExp6 = double(nRep)*aRep/__powint<12>(r,nRep); + fpairOldEXP6_21 = factor_lj*forceExp6*r2inv; + + evdwlOldEXP6_21 = uin1 - uin1rep + aRep/__powint<12>(r,nRep); + } else { + const double forceExp6 = buck1*buck2*(r*rexp*rminv - rm6ij*r6inv) + r*durc; + fpairOldEXP6_21 = factor_lj*forceExp6*r2inv; + + evdwlOldEXP6_21 = buck1*(6.0*rexp - alphaOld21_ij*rm6ij*r6inv) - urc - durc*(r-rCut); + } + + double evdwlOld; + if (Site1EqSite2) + evdwlOld = sqrt(mixWtSite1old_i*mixWtSite2old_j)*evdwlOldEXP6_12; + else + evdwlOld = sqrt(mixWtSite1old_i*mixWtSite2old_j)*evdwlOldEXP6_12 + sqrt(mixWtSite2old_i*mixWtSite1old_j)*evdwlOldEXP6_21; + + evdwlOld *= factor_lj; + + uCG_i += 0.5*evdwlOld; + + evdwlOld_j[jlane] = evdwlOld; + } + + if(rm12_ij!=0.0 && rm21_ij!=0.0) + { + hasError |= (alpha21_ij == 6.0 || alpha12_ij == 6.0); + + // A3. Compute some convenient quantities for evaluating the force + double rminv = 1.0/rm12_ij; + double buck1 = epsilon12_ij / (alpha12_ij - 6.0); + double buck2 = 6.0*alpha12_ij; + double rexp = expValue(alpha12_ij*(1.0-r*rminv)); + double rm2ij = rm12_ij*rm12_ij; + double rm6ij = rm2ij*rm2ij*rm2ij; + + // Compute the shifted potential + double rCutExp = expValue(alpha12_ij*(1.0-rCut*rminv)); + double urc = buck1*(6.0*rCutExp - alpha12_ij*rm6ij*rCut6inv); + double durc = -buck1*buck2*(rCutExp*rminv - rCutInv*rm6ij*rCut6inv); + double rin1 = shift*rm12_ij*func_rin(alpha12_ij); + + if(r < rin1){ + const double rin6 = rin1*rin1*rin1*rin1*rin1*rin1; + const double rin6inv = 1.0/rin6; + + const double rin1exp = expValue(alpha12_ij*(1.0-rin1*rminv)); + + const double uin1 = buck1*(6.0*rin1exp - alpha12_ij*rm6ij*rin6inv) - urc - durc*(rin1-rCut); + + const double win1 = buck1*buck2*(rin1*rin1exp*rminv - rm6ij*rin6inv) + rin1*durc; + + const double aRep = win1*__powint<12>(rin1,nRep)/nRep; + + const double uin1rep = aRep/__powint<12>(rin1,nRep); + + evdwlEXP6_12 = uin1 - uin1rep + aRep/__powint<12>(r,nRep); + } else { + evdwlEXP6_12 = buck1*(6.0*rexp - alpha12_ij*rm6ij*r6inv) - urc - durc*(r-rCut); + } + + rminv = 1.0/rm21_ij; + buck1 = epsilon21_ij / (alpha21_ij - 6.0); + buck2 = 6.0*alpha21_ij; + rexp = expValue(alpha21_ij*(1.0-r*rminv)); + rm2ij = rm21_ij*rm21_ij; + rm6ij = rm2ij*rm2ij*rm2ij; + + // Compute the shifted potential + rCutExp = expValue(alpha21_ij*(1.0-rCut*rminv)); + urc = buck1*(6.0*rCutExp - alpha21_ij*rm6ij*rCut6inv); + durc = -buck1*buck2*(rCutExp*rminv - rCutInv*rm6ij*rCut6inv); + rin1 = shift*rm21_ij*func_rin(alpha21_ij); + + if(r < rin1){ + const double rin6 = rin1*rin1*rin1*rin1*rin1*rin1; + const double rin6inv = 1.0/rin6; + + const double rin1exp = expValue(alpha21_ij*(1.0-rin1*rminv)); + + const double uin1 = buck1*(6.0*rin1exp - alpha21_ij*rm6ij*rin6inv) - urc - durc*(rin1-rCut); + + const double win1 = buck1*buck2*(rin1*rin1exp*rminv - rm6ij*rin6inv) + rin1*durc; + + const double aRep = win1*__powint<12>(rin1,nRep)/nRep; + + const double uin1rep = aRep/__powint<12>(rin1,nRep); + + evdwlEXP6_21 = uin1 - uin1rep + aRep/__powint<12>(r,nRep); + } else { + evdwlEXP6_21 = buck1*(6.0*rexp - alpha21_ij*rm6ij*r6inv) - urc - durc*(r-rCut); + } + } + + // + // Apply Mixing Rule to get the overall force for the CG pair + // + double fpair; + if (Site1EqSite2) + fpair = sqrt(mixWtSite1old_i*mixWtSite2old_j)*fpairOldEXP6_12; + else + fpair = sqrt(mixWtSite1old_i*mixWtSite2old_j)*fpairOldEXP6_12 + sqrt(mixWtSite2old_i*mixWtSite1old_j)*fpairOldEXP6_21; + + double evdwl; + if (Site1EqSite2) + evdwl = sqrt(mixWtSite1_i*mixWtSite2_j)*evdwlEXP6_12; + else + evdwl = sqrt(mixWtSite1_i*mixWtSite2_j)*evdwlEXP6_12 + sqrt(mixWtSite2_i*mixWtSite1_j)*evdwlEXP6_21; + + evdwl *= factor_lj; + + fpair_j[jlane] = fpair; + + fx_i += delx*fpair; + fy_i += dely*fpair; + fz_i += delz*fpair; + + uCGnew_i += 0.5*evdwl; + if ((NEIGHFLAG==HALF || NEIGHFLAG==HALFTHREAD)) + uCGnew_j[jlane] = 0.5*evdwl; + + } // if rsq < cutsq + + } // end jlane loop. + + for (int jlane = 0; jlane < niters; jlane++) + { + const int j = neigh_j[jlane] & NEIGHMASK; + + if ((NEIGHFLAG==HALF || NEIGHFLAG==HALFTHREAD) && (NEWTON_PAIR || j < nlocal)) + if (UseAtomics) + a_uCG(j) += 0.5*evdwlOld_j[jlane]; + else + t_uCG(tid,j) += 0.5*evdwlOld_j[jlane]; + + if ((NEIGHFLAG==HALF || NEIGHFLAG==HALFTHREAD) && (NEWTON_PAIR || j < nlocal)) + if (UseAtomics) + a_uCGnew(j) += uCGnew_j[jlane]; + else + t_uCGnew(tid,j) += uCGnew_j[jlane]; + + if ((NEIGHFLAG==HALF || NEIGHFLAG==HALFTHREAD) && (NEWTON_PAIR || j < nlocal)) { + if (UseAtomics) + { + a_f(j,0) -= delx_j[jlane]*fpair_j[jlane]; + a_f(j,1) -= dely_j[jlane]*fpair_j[jlane]; + a_f(j,2) -= delz_j[jlane]*fpair_j[jlane]; + } + else + { + t_f(tid,j,0) -= delx_j[jlane]*fpair_j[jlane]; + t_f(tid,j,1) -= dely_j[jlane]*fpair_j[jlane]; + t_f(tid,j,2) -= delz_j[jlane]*fpair_j[jlane]; + } + } + + double evdwl = evdwlOld_j[jlane]; + if (EVFLAG) + ev.evdwl += (((NEIGHFLAG==HALF || NEIGHFLAG==HALFTHREAD) && (NEWTON_PAIR||(jtemplate ev_tally(ev,i,j,evdwl,fpair_j[jlane],delx_j[jlane],dely_j[jlane],delz_j[jlane]); + } + } + + if (hasError) + k_error_flag.d_view() = 1; + + if (UseAtomics) + { + a_f(i,0) += fx_i; + a_f(i,1) += fy_i; + a_f(i,2) += fz_i; + a_uCG(i) += uCG_i; + a_uCGnew(i) += uCGnew_i; + } + else + { + t_f(tid,i,0) += fx_i; + t_f(tid,i,1) += fy_i; + t_f(tid,i,2) += fz_i; + t_uCG(tid,i) += uCG_i; + t_uCGnew(tid,i) += uCGnew_i; + } +} + template template KOKKOS_INLINE_FUNCTION diff --git a/src/KOKKOS/pair_exp6_rx_kokkos.h b/src/KOKKOS/pair_exp6_rx_kokkos.h index ebbc26ea20..6899e5ff62 100644 --- a/src/KOKKOS/pair_exp6_rx_kokkos.h +++ b/src/KOKKOS/pair_exp6_rx_kokkos.h @@ -91,6 +91,10 @@ class PairExp6rxKokkos : public PairExp6rx { KOKKOS_INLINE_FUNCTION void operator()(TagPairExp6rxComputeNoAtomics, const int&, EV_FLOAT&) const; + template + KOKKOS_INLINE_FUNCTION + void vectorized_operator(const int&, EV_FLOAT&) const; + template KOKKOS_INLINE_FUNCTION void operator()(TagPairExp6rxComputeNoAtomics, const int&) const; From 75670244bb5d30c407e8fc3635f06cf9b08ba817 Mon Sep 17 00:00:00 2001 From: "Christopher P. Stone" Date: Fri, 17 Mar 2017 17:02:47 -0400 Subject: [PATCH 210/439] Added ONE-TYPE template capability to vectorized_operator and cleaned up timers. --- src/KOKKOS/pair_exp6_rx_kokkos.cpp | 98 +++++++++++------------------- src/KOKKOS/pair_exp6_rx_kokkos.h | 2 +- 2 files changed, 37 insertions(+), 63 deletions(-) diff --git a/src/KOKKOS/pair_exp6_rx_kokkos.cpp b/src/KOKKOS/pair_exp6_rx_kokkos.cpp index 85d919091f..5c74cba8c7 100644 --- a/src/KOKKOS/pair_exp6_rx_kokkos.cpp +++ b/src/KOKKOS/pair_exp6_rx_kokkos.cpp @@ -348,8 +348,8 @@ void PairExp6rxKokkos::compute(int eflag_in, int vflag_in) copymode = 0; - TimerType t_stop = getTimeStamp(); - printf("PairExp6rxKokkos::compute %f %f\n", getElapsedTime(t_start, t_stop), getElapsedTime(t_mix_start, t_mix_stop)); + //TimerType t_stop = getTimeStamp(); + //printf("PairExp6rxKokkos::compute %f %f\n", getElapsedTime(t_start, t_stop), getElapsedTime(t_mix_start, t_mix_stop)); } template @@ -379,10 +379,17 @@ KOKKOS_INLINE_FUNCTION void PairExp6rxKokkos::operator()(TagPairExp6rxCompute, const int &ii, EV_FLOAT& ev) const { { + const bool one_type = (atom->ntypes == 1); if (isite1 == isite2) - this->vectorized_operator(ii, ev); + if (one_type) + this->vectorized_operator(ii, ev); + else + this->vectorized_operator(ii, ev); else - this->vectorized_operator(ii, ev); + if (one_type) + this->vectorized_operator(ii, ev); + else + this->vectorized_operator(ii, ev); return; } @@ -743,10 +750,17 @@ KOKKOS_INLINE_FUNCTION void PairExp6rxKokkos::operator()(TagPairExp6rxComputeNoAtomics, const int &ii, EV_FLOAT& ev) const { { + const bool one_type = (atom->ntypes == 1); if (isite1 == isite2) - this->vectorized_operator(ii, ev); + if (one_type) + this->vectorized_operator(ii, ev); + else + this->vectorized_operator(ii, ev); else - this->vectorized_operator(ii, ev); + if (one_type) + this->vectorized_operator(ii, ev); + else + this->vectorized_operator(ii, ev); return; } @@ -1109,7 +1123,7 @@ double __powint(const double& x, const int) } template - template + template KOKKOS_INLINE_FUNCTION void PairExp6rxKokkos::vectorized_operator(const int &ii, EV_FLOAT& ev) const { @@ -1157,6 +1171,12 @@ void PairExp6rxKokkos::vectorized_operator(const int &ii, EV_FLOAT& const double rmOld2_i = PairExp6ParamData.rmOld2[i]; const double mixWtSite2old_i = PairExp6ParamData.mixWtSite2old[i]; + const double cutsq_type11 = d_cutsq(1,1); + const double rCut2inv_type11 = 1.0/ cutsq_type11; + const double rCut6inv_type11 = rCut2inv_type11*rCut2inv_type11*rCut2inv_type11; + const double rCut_type11 = sqrt( cutsq_type11 ); + const double rCutInv_type11 = 1.0/rCut_type11; + // Do error testing locally. bool hasError = false; @@ -1171,22 +1191,6 @@ void PairExp6rxKokkos::vectorized_operator(const int &ii, EV_FLOAT& double dely_j[batchSize]; double delz_j[batchSize]; double cutsq_j[batchSize]; - //double j_epsilon1[batchSize] ; - //double j_alpha1[batchSize] ; - //double j_rm1[batchSize] ; - //double j_mixWtSite1[batchSize] ; - //double j_epsilon2[batchSize] ; - //double j_alpha2[batchSize] ; - //double j_rm2[batchSize] ; - //double j_mixWtSite2[batchSize] ; - //double j_epsilonOld1[batchSize] ; - //double j_alphaOld1[batchSize] ; - //double j_rmOld1[batchSize] ; - //double j_mixWtSite1old[batchSize] ; - //double j_epsilonOld2[batchSize] ; - //double j_alphaOld2[batchSize] ; - //double j_rmOld2[batchSize] ; - //double j_mixWtSite2old[batchSize] ; for (int jptr = 0; jptr < jnum; ) { @@ -1217,32 +1221,18 @@ void PairExp6rxKokkos::vectorized_operator(const int &ii, EV_FLOAT& const double rsq = delx*delx + dely*dely + delz*delz; const int jtype = type[j]; - if (rsq < d_cutsq(itype,jtype)) + const double cutsq_ij = (OneType) ? cutsq_type11 : d_cutsq(itype,jtype); + + if (rsq < cutsq_ij) { delx_j [niters] = delx; dely_j [niters] = dely; delz_j [niters] = delz; - cutsq_j[niters] = d_cutsq(itype,jtype); + if (OneType == false) + cutsq_j[niters] = cutsq_ij; neigh_j[niters] = d_neighbors(i,jptr); - //j_epsilon1[niters] = PairExp6ParamData.epsilon1[j]; - //j_alpha1[niters] = PairExp6ParamData.alpha1[j]; - //j_rm1[niters] = PairExp6ParamData.rm1[j]; - //j_mixWtSite1[niters] = PairExp6ParamData.mixWtSite1[j]; - //j_epsilon2[niters] = PairExp6ParamData.epsilon2[j]; - //j_alpha2[niters] = PairExp6ParamData.alpha2[j]; - //j_rm2[niters] = PairExp6ParamData.rm2[j]; - //j_mixWtSite2[niters] = PairExp6ParamData.mixWtSite2[j]; - //j_epsilonOld1[niters] = PairExp6ParamData.epsilonOld1[j]; - //j_alphaOld1[niters] = PairExp6ParamData.alphaOld1[j]; - //j_rmOld1[niters] = PairExp6ParamData.rmOld1[j]; - //j_mixWtSite1old[niters] = PairExp6ParamData.mixWtSite1old[j]; - //j_epsilonOld2[niters] = PairExp6ParamData.epsilonOld2[j]; - //j_alphaOld2[niters] = PairExp6ParamData.alphaOld2[j]; - //j_rmOld2[niters] = PairExp6ParamData.rmOld2[j]; - //j_mixWtSite2old[niters] = PairExp6ParamData.mixWtSite2old[j]; - ++niters; } } @@ -1268,10 +1258,10 @@ void PairExp6rxKokkos::vectorized_operator(const int &ii, EV_FLOAT& const double r6inv = r2inv*r2inv*r2inv; const double r = sqrt(rsq); - const double rCut2inv = 1.0/ cutsq_j[jlane]; - const double rCut6inv = rCut2inv*rCut2inv*rCut2inv; - const double rCut = sqrt( cutsq_j[jlane] ); - const double rCutInv = 1.0/rCut; + const double rCut2inv = (OneType) ? rCut2inv_type11 : (1.0/ cutsq_j[jlane]); + const double rCut6inv = (OneType) ? rCut6inv_type11 : (rCut2inv*rCut2inv*rCut2inv); + const double rCut = (OneType) ? rCut_type11 : (sqrt( cutsq_j[jlane] )); + const double rCutInv = (OneType) ? rCutInv_type11 : (1.0/rCut); // // A. Compute the exp-6 potential @@ -1295,22 +1285,6 @@ void PairExp6rxKokkos::vectorized_operator(const int &ii, EV_FLOAT& const double alphaOld2_j = PairExp6ParamData.alphaOld2[j]; const double rmOld2_j = PairExp6ParamData.rmOld2[j]; const double mixWtSite2old_j = PairExp6ParamData.mixWtSite2old[j]; - //const double epsilon1_j = j_epsilon1[jlane]; - //const double alpha1_j = j_alpha1[jlane]; - //const double rm1_j = j_rm1[jlane]; - //const double mixWtSite1_j = j_mixWtSite1[jlane]; - //const double epsilon2_j = j_epsilon2[jlane]; - //const double alpha2_j = j_alpha2[jlane]; - //const double rm2_j = j_rm2[jlane]; - //const double mixWtSite2_j = j_mixWtSite2[jlane]; - //const double epsilonOld1_j = j_epsilonOld1[jlane]; - //const double alphaOld1_j = j_alphaOld1[jlane]; - //const double rmOld1_j = j_rmOld1[jlane]; - //const double mixWtSite1old_j = j_mixWtSite1old[jlane]; - //const double epsilonOld2_j = j_epsilonOld2[jlane]; - //const double alphaOld2_j = j_alphaOld2[jlane]; - //const double rmOld2_j = j_rmOld2[jlane]; - //const double mixWtSite2old_j = j_mixWtSite2old[jlane]; // A2. Apply Lorentz-Berthelot mixing rules for the i-j pair const double alphaOld12_ij = sqrt(alphaOld1_i*alphaOld2_j); diff --git a/src/KOKKOS/pair_exp6_rx_kokkos.h b/src/KOKKOS/pair_exp6_rx_kokkos.h index 6899e5ff62..9f38732c32 100644 --- a/src/KOKKOS/pair_exp6_rx_kokkos.h +++ b/src/KOKKOS/pair_exp6_rx_kokkos.h @@ -91,7 +91,7 @@ class PairExp6rxKokkos : public PairExp6rx { KOKKOS_INLINE_FUNCTION void operator()(TagPairExp6rxComputeNoAtomics, const int&, EV_FLOAT&) const; - template + template KOKKOS_INLINE_FUNCTION void vectorized_operator(const int&, EV_FLOAT&) const; From 0cd3f0cd63f2305d2408bea36a18302ee11d9326 Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Fri, 17 Mar 2017 19:11:39 -0400 Subject: [PATCH 211/439] USER-DPD: bugfix for npair_half_bin_newton_ssa when bonds are involved. Only locals have valid special[] arrays, so when finding neighbors of ghosts, we have to swap the arguments to find_special(). --- src/USER-DPD/npair_half_bin_newton_ssa.cpp | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/USER-DPD/npair_half_bin_newton_ssa.cpp b/src/USER-DPD/npair_half_bin_newton_ssa.cpp index ab439d3731..a6479d4c4f 100644 --- a/src/USER-DPD/npair_half_bin_newton_ssa.cpp +++ b/src/USER-DPD/npair_half_bin_newton_ssa.cpp @@ -250,11 +250,6 @@ void NPairHalfBinNewtonSSA::build(NeighList *list) xtmp = x[i][0]; ytmp = x[i][1]; ztmp = x[i][2]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } ibin = coord2bin(x[i],xbin,ybin,zbin); @@ -281,12 +276,16 @@ void NPairHalfBinNewtonSSA::build(NeighList *list) if (rsq <= cutneighsq[itype][jtype]) { if (molecular) { if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >= 0) - which = find_special(onemols[imol]->special[iatom], - onemols[imol]->nspecial[iatom], - tag[j]-tagprev); - else which = 0; + which = find_special(special[j],nspecial[j],tag[i]); + else { + int jmol = molindex[j]; + if (jmol >= 0) { + int jatom = molatom[j]; + which = find_special(onemols[jmol]->special[jatom], + onemols[jmol]->nspecial[jatom], + tag[i] - (tag[j] - jatom - 1)); + } else which = 0; + } if (which == 0) neighptr[n++] = j; else if (domain->minimum_image_check(delx,dely,delz)) neighptr[n++] = j; From fff43a4604a29de23f23f066027b5f8e41cd33f4 Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Fri, 17 Mar 2017 19:33:04 -0400 Subject: [PATCH 212/439] USER-DPD Kokkos: bugfix for npair_ssa_kokkos.cpp corresponding to 0cd3f0cd --- src/KOKKOS/npair_ssa_kokkos.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/KOKKOS/npair_ssa_kokkos.cpp b/src/KOKKOS/npair_ssa_kokkos.cpp index a9b59bfc96..7b5a569051 100644 --- a/src/KOKKOS/npair_ssa_kokkos.cpp +++ b/src/KOKKOS/npair_ssa_kokkos.cpp @@ -515,11 +515,11 @@ void NPairSSAKokkosExecute::build_ghosts() if(rsq <= cutneighsq(itype,jtype)) { if (molecular) { if (!moltemplate) - which = find_special(i,j); - /* else if (imol >= 0) */ - /* which = find_special(onemols[imol]->special[iatom], */ - /* onemols[imol]->nspecial[iatom], */ - /* tag[j]-tagprev); */ + which = find_special(j,i); + /* else if (jmol >= 0) */ + /* which = find_special(onemols[jmol]->special[jatom], */ + /* onemols[jmol]->nspecial[jatom], */ + /* tag[i]-jtagprev); */ /* else which = 0; */ if (which == 0){ if(n Date: Sun, 19 Mar 2017 21:12:52 -0400 Subject: [PATCH 213/439] USER-DPD Kokkos: bugfix, add a misisng line of code in pair_exp6_rx_kokkos.cpp --- src/KOKKOS/pair_exp6_rx_kokkos.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/KOKKOS/pair_exp6_rx_kokkos.cpp b/src/KOKKOS/pair_exp6_rx_kokkos.cpp index abc158d72c..23fb4f59e5 100644 --- a/src/KOKKOS/pair_exp6_rx_kokkos.cpp +++ b/src/KOKKOS/pair_exp6_rx_kokkos.cpp @@ -917,6 +917,7 @@ void PairExp6rxKokkos::getMixingWeights(int id,double &epsilon1,doub nMoleculesOld2 = dvector(ispecies+nspecies,id); nMolecules2 = dvector(ispecies,id); fractionOld2 = dvector(ispecies+nspecies,id)/nTotalold; + fraction2 = nMolecules2/nTotal; } // If Site1 or Site2 matches is a fluid, then compute the paramters From 3c91f9734dbb97f293718b0c3f5e5d5d98accc38 Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Tue, 21 Mar 2017 17:12:09 -0400 Subject: [PATCH 214/439] make RK solver check in fix_rx_kokkos.cpp be as lenient as in fix_rx.cpp NOTE: the (y < -MY_EPSILON) test was too strict, but don't know by how much This needs to be revisited before merging back to LAMMPS master. --- src/KOKKOS/fix_rx_kokkos.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/KOKKOS/fix_rx_kokkos.cpp b/src/KOKKOS/fix_rx_kokkos.cpp index ac81e5c2a7..d994b2c5d1 100644 --- a/src/KOKKOS/fix_rx_kokkos.cpp +++ b/src/KOKKOS/fix_rx_kokkos.cpp @@ -1389,9 +1389,9 @@ void FixRxKokkos::operator()(Tag_FixRxKokkos_solveSystemsone(FLERR,"Computed concentration in RK solver is < -10*DBL_EPSILON"); + //error->one(FLERR,"Computed concentration in RK solver is < -1.0e-10"); k_error_flag.d_view() = 2; // This should be an atomic update. } @@ -1599,9 +1599,9 @@ void FixRxKokkos::solve_reactions(const int vflag, const bool isPreF // Store the solution back in dvector. for (int ispecies = 0; ispecies < nspecies; ispecies++) { - if (y[ispecies] < -MY_EPSILON) + if (y[ispecies] < -1.0e-10) { - //error->one(FLERR,"Computed concentration in RK solver is < -10*DBL_EPSILON"); + //error->one(FLERR,"Computed concentration in RK solver is < -1.0e-10"); k_error_flag.d_view() = 2; // This should be an atomic update. } @@ -1639,7 +1639,7 @@ void FixRxKokkos::solve_reactions(const int vflag, const bool isPreF k_error_flag.template modify(); k_error_flag.template sync(); if (k_error_flag.h_view() == 2) - error->one(FLERR,"Computed concentration in RK solver is < -10*DBL_EPSILON"); + error->one(FLERR,"Computed concentration in RK solver is < -1.0e-10"); // Signal that dvector has been modified on this execution space. atomKK->modified( execution_space, DVECTOR_MASK ); From b418b46a03acf427c5d9eb015d1ea202557caed8 Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Sun, 26 Mar 2017 23:07:48 -0400 Subject: [PATCH 215/439] USER-DPD: bugfix for an array that changed length in the non-kokkos version. --- src/KOKKOS/npair_ssa_kokkos.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/KOKKOS/npair_ssa_kokkos.cpp b/src/KOKKOS/npair_ssa_kokkos.cpp index 7b5a569051..699c2d3269 100644 --- a/src/KOKKOS/npair_ssa_kokkos.cpp +++ b/src/KOKKOS/npair_ssa_kokkos.cpp @@ -122,8 +122,8 @@ void NPairSSAKokkos::copy_stencil_info() NStencilSSA *ns_ssa = dynamic_cast(ns); if (!ns_ssa) error->one(FLERR, "NStencil wasn't a NStencilSSA object"); - k_nstencil_ssa = DAT::tdual_int_1d("NPairSSAKokkos:nstencil_ssa",8); - for (int k = 0; k < 8; ++k) { + k_nstencil_ssa = DAT::tdual_int_1d("NPairSSAKokkos:nstencil_ssa",5); + for (int k = 0; k < 5; ++k) { k_nstencil_ssa.h_view(k) = ns_ssa->nstencil_ssa[k]; } k_nstencil_ssa.modify(); From 5f0823172c4a2f76f6385e011e90876a08e7390c Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Mon, 27 Mar 2017 06:35:19 -0400 Subject: [PATCH 216/439] Make read_restart properly size the atom_vec_* data when reading via mpiio --- src/read_restart.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/read_restart.cpp b/src/read_restart.cpp index 6a950353ef..92d21a7062 100644 --- a/src/read_restart.cpp +++ b/src/read_restart.cpp @@ -208,6 +208,7 @@ void ReadRestart::command(int narg, char **arg) mpiio->read((headerOffset+assignedChunkOffset),assignedChunkSize,buf); mpiio->close(); + if (assignedChunkSize > atom->nmax) avec->grow(assignedChunkSize); m = 0; while (m < assignedChunkSize) m += avec->unpack_restart(&buf[m]); } From 28784a4ce2de90728365717a768c5d0f5b17772a Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Mon, 27 Mar 2017 08:38:40 -0500 Subject: [PATCH 217/439] Now with the correct math, make read_restart properly size the atom_vec_* data --- src/read_restart.cpp | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/read_restart.cpp b/src/read_restart.cpp index 92d21a7062..f29a603ef6 100644 --- a/src/read_restart.cpp +++ b/src/read_restart.cpp @@ -207,8 +207,23 @@ void ReadRestart::command(int narg, char **arg) memory->create(buf,assignedChunkSize,"read_restart:buf"); mpiio->read((headerOffset+assignedChunkOffset),assignedChunkSize,buf); mpiio->close(); - - if (assignedChunkSize > atom->nmax) avec->grow(assignedChunkSize); + if (!nextra) { // We can actually calculate number of atoms from assignedChunkSize + atom->nlocal = 1; // temporarily claim there is one atom... + int perAtomSize = avec->size_restart(); // ...so we can get its size + atom->nlocal = 0; // restore nlocal to zero atoms + int atomCt = (int) (assignedChunkSize / perAtomSize); +#ifdef DEBUG_ME_NOTNOW +fprintf(stdout, "ReadRestart::command %04d: pAS %d, aCt %d, nmax %d, chunckSize %12.0f, %12.0f\n" + ,me + ,perAtomSize + ,atomCt + ,atom->nmax + ,(double) assignedChunkSize + ,((double) perAtomSize) * atomCt +); +#endif + if (atomCt > atom->nmax) avec->grow(atomCt); + } m = 0; while (m < assignedChunkSize) m += avec->unpack_restart(&buf[m]); } From 0463923e330b070e578a38f7a2a0eda2b033c8c4 Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Mon, 27 Mar 2017 10:41:32 -0500 Subject: [PATCH 218/439] USER-DPD Kokkos: tighten up the SSA data allocation to what is needed. A future version was planned to use more space for a ghost work queue. --- src/KOKKOS/npair_ssa_kokkos.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/KOKKOS/npair_ssa_kokkos.cpp b/src/KOKKOS/npair_ssa_kokkos.cpp index 699c2d3269..59470189bc 100644 --- a/src/KOKKOS/npair_ssa_kokkos.cpp +++ b/src/KOKKOS/npair_ssa_kokkos.cpp @@ -205,7 +205,7 @@ void NPairSSAKokkos::build(NeighList *list_) { NeighListKokkos* list = (NeighListKokkos*) list_; const int nlocal = includegroup?atom->nfirst:atom->nlocal; - const int nl_size = (nlocal + atom->nghost) * 4; + const int nl_size = (nlocal * 4) + atom->nghost; list->grow(nl_size); // Make special larger SSA neighbor list ssa_phaseCt = sz1*sy1*sx1; From 661bd37e15bcb83266dbd28b294889fe0ece9554 Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Mon, 27 Mar 2017 14:53:48 -0500 Subject: [PATCH 219/439] Make read_restart evenly divide the work of reading when using mpiio. Currently only affects restart files written without any per-atom fix data. --- src/read_restart.cpp | 90 +++++++++++++++++++++++++++++++++----------- 1 file changed, 69 insertions(+), 21 deletions(-) diff --git a/src/read_restart.cpp b/src/read_restart.cpp index f29a603ef6..331a5d6cda 100644 --- a/src/read_restart.cpp +++ b/src/read_restart.cpp @@ -212,7 +212,8 @@ void ReadRestart::command(int narg, char **arg) int perAtomSize = avec->size_restart(); // ...so we can get its size atom->nlocal = 0; // restore nlocal to zero atoms int atomCt = (int) (assignedChunkSize / perAtomSize); -#ifdef DEBUG_ME_NOTNOW +//#define DEBUG_PRE_GROW +#ifdef DEBUG_PRE_GROW fprintf(stdout, "ReadRestart::command %04d: pAS %d, aCt %d, nmax %d, chunckSize %12.0f, %12.0f\n" ,me ,perAtomSize @@ -1026,6 +1027,7 @@ void ReadRestart::file_layout() // if the number of ranks that did the writing is different if (me == 0) { + int ndx; int *all_written_send_sizes; memory->create(all_written_send_sizes,nprocs_file, "write_restart:all_written_send_sizes"); @@ -1035,30 +1037,76 @@ void ReadRestart::file_layout() fread(all_written_send_sizes,sizeof(int),nprocs_file,fp); - int init_chunk_number = nprocs_file/nprocs; - int num_extra_chunks = nprocs_file - (nprocs*init_chunk_number); + if ((nprocs != nprocs_file) && !(atom->nextra_store)) { + // nprocs differ, but atom sizes are fixed length, yeah! + atom->nlocal = 1; // temporarily claim there is one atom... + int perAtomSize = atom->avec->size_restart(); // ...so we can get its size + atom->nlocal = 0; // restore nlocal to zero atoms - for (int i = 0; i < nprocs; i++) { - if (i < num_extra_chunks) - nproc_chunk_number[i] = init_chunk_number+1; - else - nproc_chunk_number[i] = init_chunk_number; - } + bigint total_size = 0; + for (int i = 0; i < nprocs_file; ++i) { + total_size += all_written_send_sizes[i]; + } + bigint total_ct = total_size / perAtomSize; - int all_written_send_sizes_index = 0; - bigint current_offset = 0; - for (int i=0;inatoms + ,(double) base_ct + ,(double) leftover_ct + ,nprocs + ,nprocs_file + ,(total_size == (total_ct * perAtomSize)) ? ' ' : 'E' + ,(total_ct == (base_ct * nprocs + leftover_ct)) ? ' ' : 'F' +); +#endif + } else { // Bummer, we have to read in based on how it was written + int init_chunk_number = nprocs_file/nprocs; + int num_extra_chunks = nprocs_file - (nprocs*init_chunk_number); + + for (int i = 0; i < nprocs; i++) { + if (i < num_extra_chunks) + nproc_chunk_number[i] = init_chunk_number+1; + else + nproc_chunk_number[i] = init_chunk_number; } + int all_written_send_sizes_index = 0; + bigint current_offset = 0; + for (int i=0;idestroy(all_written_send_sizes); memory->destroy(nproc_chunk_number); From 20ae05055dbb04054f0c1c6a0b4cda3260d7fbad Mon Sep 17 00:00:00 2001 From: Dan Ibanez Date: Tue, 28 Mar 2017 11:38:26 -0600 Subject: [PATCH 220/439] fix memory leak via NeighListKokkos::clean_copy() There were several clean_copy() calls in pair styles *outside device code*. They seem to have been left over from an abandoned effort to copy the Kokkos neighbor list as a member of the pair style, instead of copying out the individual views needed. These leftover clean_copy() calls were setting pointers to NULL that had not been freed, leading to large memory leaks. I've removed the clean_copy() function entirely, and replaced it with the copymode flag system used in many other Kokkos objects. The copymode flag is only set to one in functors that hold copies of the neighbor list. --- src/KOKKOS/fix_qeq_reax_kokkos.cpp | 2 -- src/KOKKOS/fix_shardlow_kokkos.cpp | 2 -- src/KOKKOS/neigh_list_kokkos.cpp | 19 ++++++------------- src/KOKKOS/neigh_list_kokkos.h | 7 +------ src/KOKKOS/npair_kokkos.h | 2 +- src/KOKKOS/npair_ssa_kokkos.h | 2 +- src/KOKKOS/pair_coul_dsf_kokkos.cpp | 3 --- src/KOKKOS/pair_coul_wolf_kokkos.cpp | 3 --- src/KOKKOS/pair_eam_alloy_kokkos.cpp | 3 --- src/KOKKOS/pair_eam_fs_kokkos.cpp | 3 --- src/KOKKOS/pair_eam_kokkos.cpp | 5 +---- src/KOKKOS/pair_kokkos.h | 4 ++-- src/KOKKOS/pair_reax_c_kokkos.cpp | 3 --- src/KOKKOS/pair_sw_kokkos.cpp | 1 - src/KOKKOS/pair_tersoff_kokkos.cpp | 1 - src/KOKKOS/pair_tersoff_mod_kokkos.cpp | 1 - src/KOKKOS/pair_tersoff_zbl_kokkos.cpp | 1 - src/neigh_list.cpp | 2 ++ src/neigh_list.h | 3 ++- 19 files changed, 16 insertions(+), 51 deletions(-) diff --git a/src/KOKKOS/fix_qeq_reax_kokkos.cpp b/src/KOKKOS/fix_qeq_reax_kokkos.cpp index 3b8d5a85ea..fbc6e0a298 100644 --- a/src/KOKKOS/fix_qeq_reax_kokkos.cpp +++ b/src/KOKKOS/fix_qeq_reax_kokkos.cpp @@ -217,8 +217,6 @@ void FixQEqReaxKokkos::pre_force(int vflag) d_ilist = k_list->d_ilist; inum = list->inum; - k_list->clean_copy(); - //cleanup_copy(); copymode = 1; int teamsize = TEAMSIZE; diff --git a/src/KOKKOS/fix_shardlow_kokkos.cpp b/src/KOKKOS/fix_shardlow_kokkos.cpp index bf026552fa..676df07b61 100644 --- a/src/KOKKOS/fix_shardlow_kokkos.cpp +++ b/src/KOKKOS/fix_shardlow_kokkos.cpp @@ -624,8 +624,6 @@ void FixShardlowKokkos::initial_integrate(int vflag) d_neighbors = k_list->d_neighbors; d_ilist = k_list->d_ilist; - k_list->clean_copy(); - //cleanup_copy(); copymode = 1; dtsqrt = sqrt(update->dt); diff --git a/src/KOKKOS/neigh_list_kokkos.cpp b/src/KOKKOS/neigh_list_kokkos.cpp index b1b4e4467a..caf2dfee56 100644 --- a/src/KOKKOS/neigh_list_kokkos.cpp +++ b/src/KOKKOS/neigh_list_kokkos.cpp @@ -22,21 +22,14 @@ enum{NSQ,BIN,MULTI}; /* ---------------------------------------------------------------------- */ template -void NeighListKokkos::clean_copy() +NeighListKokkos::NeighListKokkos(class LAMMPS *lmp):NeighList(lmp) { - ilist = NULL; - numneigh = NULL; - firstneigh = NULL; - firstdouble = NULL; - dnum = 0; - iskip = NULL; - ijskip = NULL; - - ipage = NULL; - dpage = NULL; - + _stride = 1; + maxneighs = 16; + kokkos = 1; maxatoms = 0; -} + execution_space = ExecutionSpaceFromDevice::space; +}; /* ---------------------------------------------------------------------- */ diff --git a/src/KOKKOS/neigh_list_kokkos.h b/src/KOKKOS/neigh_list_kokkos.h index cece97197d..1c433f321c 100644 --- a/src/KOKKOS/neigh_list_kokkos.h +++ b/src/KOKKOS/neigh_list_kokkos.h @@ -68,18 +68,13 @@ class NeighListKokkos: public NeighList { public: int maxneighs; - void clean_copy(); void grow(int nmax); typename ArrayTypes::t_neighbors_2d d_neighbors; typename DAT::tdual_int_1d k_ilist; // local indices of I atoms typename ArrayTypes::t_int_1d d_ilist; typename ArrayTypes::t_int_1d d_numneigh; // # of J neighs for each I - NeighListKokkos(class LAMMPS *lmp): - NeighList(lmp) {_stride = 1; maxneighs = 16; kokkos = 1; maxatoms = 0; - execution_space = ExecutionSpaceFromDevice::space; - }; - ~NeighListKokkos() {numneigh = NULL; ilist = NULL;}; + NeighListKokkos(class LAMMPS *lmp); KOKKOS_INLINE_FUNCTION AtomNeighbors get_neighbors(const int &i) const { diff --git a/src/KOKKOS/npair_kokkos.h b/src/KOKKOS/npair_kokkos.h index b31ef2ebbf..ab094e68eb 100644 --- a/src/KOKKOS/npair_kokkos.h +++ b/src/KOKKOS/npair_kokkos.h @@ -265,7 +265,7 @@ class NeighborKokkosExecute h_new_maxneighs() = neigh_list.maxneighs; }; - ~NeighborKokkosExecute() {neigh_list.clean_copy();}; + ~NeighborKokkosExecute() {neigh_list.copymode = 1;}; template KOKKOS_FUNCTION diff --git a/src/KOKKOS/npair_ssa_kokkos.h b/src/KOKKOS/npair_ssa_kokkos.h index e38d648984..96efd7404b 100644 --- a/src/KOKKOS/npair_ssa_kokkos.h +++ b/src/KOKKOS/npair_ssa_kokkos.h @@ -287,7 +287,7 @@ class NPairSSAKokkosExecute h_new_maxneighs() = neigh_list.maxneighs; }; - ~NPairSSAKokkosExecute() {neigh_list.clean_copy();}; + ~NPairSSAKokkosExecute() {neigh_list.copymode = 1;}; void build_locals(); void build_ghosts(); diff --git a/src/KOKKOS/pair_coul_dsf_kokkos.cpp b/src/KOKKOS/pair_coul_dsf_kokkos.cpp index f2063bdc08..e6f5407f2d 100644 --- a/src/KOKKOS/pair_coul_dsf_kokkos.cpp +++ b/src/KOKKOS/pair_coul_dsf_kokkos.cpp @@ -120,9 +120,6 @@ void PairCoulDSFKokkos::compute(int eflag_in, int vflag_in) int inum = list->inum; - // Call cleanup_copy which sets allocations NULL which are destructed by the PairStyle - - k_list->clean_copy(); copymode = 1; // loop over neighbors of my atoms diff --git a/src/KOKKOS/pair_coul_wolf_kokkos.cpp b/src/KOKKOS/pair_coul_wolf_kokkos.cpp index 8049ba0031..75177e2d81 100644 --- a/src/KOKKOS/pair_coul_wolf_kokkos.cpp +++ b/src/KOKKOS/pair_coul_wolf_kokkos.cpp @@ -121,9 +121,6 @@ void PairCoulWolfKokkos::compute(int eflag_in, int vflag_in) int inum = list->inum; - // Call cleanup_copy which sets allocations NULL which are destructed by the PairStyle - - k_list->clean_copy(); copymode = 1; // loop over neighbors of my atoms diff --git a/src/KOKKOS/pair_eam_alloy_kokkos.cpp b/src/KOKKOS/pair_eam_alloy_kokkos.cpp index 45c320bc51..acf9b27963 100644 --- a/src/KOKKOS/pair_eam_alloy_kokkos.cpp +++ b/src/KOKKOS/pair_eam_alloy_kokkos.cpp @@ -122,9 +122,6 @@ void PairEAMAlloyKokkos::compute(int eflag_in, int vflag_in) d_ilist = k_list->d_ilist; int inum = list->inum; - // Call cleanup_copy which sets allocations NULL which are destructed by the PairStyle - - k_list->clean_copy(); copymode = 1; // zero out density diff --git a/src/KOKKOS/pair_eam_fs_kokkos.cpp b/src/KOKKOS/pair_eam_fs_kokkos.cpp index b9fa82740a..a31263dfcd 100644 --- a/src/KOKKOS/pair_eam_fs_kokkos.cpp +++ b/src/KOKKOS/pair_eam_fs_kokkos.cpp @@ -122,9 +122,6 @@ void PairEAMFSKokkos::compute(int eflag_in, int vflag_in) d_ilist = k_list->d_ilist; int inum = list->inum; - // Call cleanup_copy which sets allocations NULL which are destructed by the PairStyle - - k_list->clean_copy(); copymode = 1; // zero out density diff --git a/src/KOKKOS/pair_eam_kokkos.cpp b/src/KOKKOS/pair_eam_kokkos.cpp index e4128de722..006c9582c5 100644 --- a/src/KOKKOS/pair_eam_kokkos.cpp +++ b/src/KOKKOS/pair_eam_kokkos.cpp @@ -117,9 +117,6 @@ void PairEAMKokkos::compute(int eflag_in, int vflag_in) d_ilist = k_list->d_ilist; int inum = list->inum; - // Call cleanup_copy which sets allocations NULL which are destructed by the PairStyle - - k_list->clean_copy(); copymode = 1; // zero out density @@ -870,4 +867,4 @@ template class PairEAMKokkos; #ifdef KOKKOS_HAVE_CUDA template class PairEAMKokkos; #endif -} \ No newline at end of file +} diff --git a/src/KOKKOS/pair_kokkos.h b/src/KOKKOS/pair_kokkos.h index 1e01b3df15..b0614a934b 100644 --- a/src/KOKKOS/pair_kokkos.h +++ b/src/KOKKOS/pair_kokkos.h @@ -87,7 +87,7 @@ struct PairComputeFunctor { vatom(c.d_vatom),list(*list_ptr) {}; // Call cleanup_copy which sets allocations NULL which are destructed by the PairStyle - ~PairComputeFunctor() {c.cleanup_copy();list.clean_copy();}; + ~PairComputeFunctor() {c.cleanup_copy();list.copymode = 1;}; KOKKOS_INLINE_FUNCTION int sbmask(const int& j) const { return j >> SBBITS & 3; @@ -344,7 +344,7 @@ struct PairComputeFunctor { PairComputeFunctor(PairStyle* c_ptr, NeighListKokkos* list_ptr): c(*c_ptr),list(*list_ptr) {}; - ~PairComputeFunctor() {c.cleanup_copy();list.clean_copy();}; + ~PairComputeFunctor() {c.cleanup_copy();list.copymode = 1;}; KOKKOS_INLINE_FUNCTION int sbmask(const int& j) const { return j >> SBBITS & 3; diff --git a/src/KOKKOS/pair_reax_c_kokkos.cpp b/src/KOKKOS/pair_reax_c_kokkos.cpp index acf9c754cd..87915dce3e 100644 --- a/src/KOKKOS/pair_reax_c_kokkos.cpp +++ b/src/KOKKOS/pair_reax_c_kokkos.cpp @@ -709,8 +709,6 @@ void PairReaxCKokkos::compute(int eflag_in, int vflag_in) d_neighbors = k_list->d_neighbors; d_ilist = k_list->d_ilist; - k_list->clean_copy(); - if (eflag_global) { for (int i = 0; i < 14; i++) pvector[i] = 0.0; @@ -4012,7 +4010,6 @@ void PairReaxCKokkos::FindBond(int &numbonds) const int inum = list->inum; NeighListKokkos* k_list = static_cast*>(list); d_ilist = k_list->d_ilist; - k_list->clean_copy(); numbonds = 0; PairReaxCKokkosFindBondFunctor find_bond_functor(this); diff --git a/src/KOKKOS/pair_sw_kokkos.cpp b/src/KOKKOS/pair_sw_kokkos.cpp index a8950a0c79..e5c947cc8e 100644 --- a/src/KOKKOS/pair_sw_kokkos.cpp +++ b/src/KOKKOS/pair_sw_kokkos.cpp @@ -115,7 +115,6 @@ void PairSWKokkos::compute(int eflag_in, int vflag_in) d_numneigh = k_list->d_numneigh; d_neighbors = k_list->d_neighbors; - k_list->clean_copy(); copymode = 1; EV_FLOAT ev; diff --git a/src/KOKKOS/pair_tersoff_kokkos.cpp b/src/KOKKOS/pair_tersoff_kokkos.cpp index 75280c8f7c..833c815ad9 100644 --- a/src/KOKKOS/pair_tersoff_kokkos.cpp +++ b/src/KOKKOS/pair_tersoff_kokkos.cpp @@ -200,7 +200,6 @@ void PairTersoffKokkos::compute(int eflag_in, int vflag_in) d_neighbors = k_list->d_neighbors; d_ilist = k_list->d_ilist; - k_list->clean_copy(); copymode = 1; EV_FLOAT ev; diff --git a/src/KOKKOS/pair_tersoff_mod_kokkos.cpp b/src/KOKKOS/pair_tersoff_mod_kokkos.cpp index d16a7fc4d7..d77ba2f141 100644 --- a/src/KOKKOS/pair_tersoff_mod_kokkos.cpp +++ b/src/KOKKOS/pair_tersoff_mod_kokkos.cpp @@ -200,7 +200,6 @@ void PairTersoffMODKokkos::compute(int eflag_in, int vflag_in) d_neighbors = k_list->d_neighbors; d_ilist = k_list->d_ilist; - k_list->clean_copy(); copymode = 1; EV_FLOAT ev; diff --git a/src/KOKKOS/pair_tersoff_zbl_kokkos.cpp b/src/KOKKOS/pair_tersoff_zbl_kokkos.cpp index e9bae49fb7..040d8c5230 100644 --- a/src/KOKKOS/pair_tersoff_zbl_kokkos.cpp +++ b/src/KOKKOS/pair_tersoff_zbl_kokkos.cpp @@ -214,7 +214,6 @@ void PairTersoffZBLKokkos::compute(int eflag_in, int vflag_in) d_neighbors = k_list->d_neighbors; d_ilist = k_list->d_ilist; - k_list->clean_copy(); copymode = 1; EV_FLOAT ev; diff --git a/src/neigh_list.cpp b/src/neigh_list.cpp index 6376637832..dde544a69f 100644 --- a/src/neigh_list.cpp +++ b/src/neigh_list.cpp @@ -48,6 +48,7 @@ NeighList::NeighList(LAMMPS *lmp) : Pointers(lmp) ghost = 0; ssa = 0; copy = 0; + copymode = 0; dnum = 0; // ptrs @@ -86,6 +87,7 @@ NeighList::NeighList(LAMMPS *lmp) : Pointers(lmp) NeighList::~NeighList() { + if (copymode) return; if (!copy) { memory->destroy(ilist); memory->destroy(numneigh); diff --git a/src/neigh_list.h b/src/neigh_list.h index bef512512c..4010a68857 100644 --- a/src/neigh_list.h +++ b/src/neigh_list.h @@ -34,7 +34,8 @@ class NeighList : protected Pointers { int occasional; // 0 if build every reneighbor, 1 if not int ghost; // 1 if list stores neighbors of ghosts int ssa; // 1 if list stores Shardlow data - int copy; // 1 if this list copied from another list + int copy; // 1 if this list is (host) copied from another list + int copymode; // 1 if this is a Kokkos on-device copy int dnum; // # of doubles per neighbor, 0 if none // data structs to store neighbor pairs I,J and associated values From b3d6d9f8cf3e66437c7471a214fb668a7601c9fd Mon Sep 17 00:00:00 2001 From: Dan Ibanez Date: Tue, 28 Mar 2017 11:38:26 -0600 Subject: [PATCH 221/439] fix memory leak via NeighListKokkos::clean_copy() There were several clean_copy() calls in pair styles *outside device code*. They seem to have been left over from an abandoned effort to copy the Kokkos neighbor list as a member of the pair style, instead of copying out the individual views needed. These leftover clean_copy() calls were setting pointers to NULL that had not been freed, leading to large memory leaks. I've removed the clean_copy() function entirely, and replaced it with the copymode flag system used in many other Kokkos objects. The copymode flag is only set to one in functors that hold copies of the neighbor list. --- src/KOKKOS/fix_qeq_reax_kokkos.cpp | 2 -- src/KOKKOS/fix_shardlow_kokkos.cpp | 2 -- src/KOKKOS/neigh_list_kokkos.cpp | 19 ++++++------------- src/KOKKOS/neigh_list_kokkos.h | 7 +------ src/KOKKOS/npair_kokkos.h | 2 +- src/KOKKOS/npair_ssa_kokkos.h | 2 +- src/KOKKOS/pair_coul_dsf_kokkos.cpp | 3 --- src/KOKKOS/pair_coul_wolf_kokkos.cpp | 3 --- src/KOKKOS/pair_eam_alloy_kokkos.cpp | 3 --- src/KOKKOS/pair_eam_fs_kokkos.cpp | 3 --- src/KOKKOS/pair_eam_kokkos.cpp | 5 +---- src/KOKKOS/pair_kokkos.h | 4 ++-- src/KOKKOS/pair_reax_c_kokkos.cpp | 3 --- src/KOKKOS/pair_sw_kokkos.cpp | 1 - src/KOKKOS/pair_tersoff_kokkos.cpp | 1 - src/KOKKOS/pair_tersoff_mod_kokkos.cpp | 1 - src/KOKKOS/pair_tersoff_zbl_kokkos.cpp | 1 - src/neigh_list.cpp | 2 ++ src/neigh_list.h | 3 ++- 19 files changed, 16 insertions(+), 51 deletions(-) diff --git a/src/KOKKOS/fix_qeq_reax_kokkos.cpp b/src/KOKKOS/fix_qeq_reax_kokkos.cpp index 3b8d5a85ea..fbc6e0a298 100644 --- a/src/KOKKOS/fix_qeq_reax_kokkos.cpp +++ b/src/KOKKOS/fix_qeq_reax_kokkos.cpp @@ -217,8 +217,6 @@ void FixQEqReaxKokkos::pre_force(int vflag) d_ilist = k_list->d_ilist; inum = list->inum; - k_list->clean_copy(); - //cleanup_copy(); copymode = 1; int teamsize = TEAMSIZE; diff --git a/src/KOKKOS/fix_shardlow_kokkos.cpp b/src/KOKKOS/fix_shardlow_kokkos.cpp index bf026552fa..676df07b61 100644 --- a/src/KOKKOS/fix_shardlow_kokkos.cpp +++ b/src/KOKKOS/fix_shardlow_kokkos.cpp @@ -624,8 +624,6 @@ void FixShardlowKokkos::initial_integrate(int vflag) d_neighbors = k_list->d_neighbors; d_ilist = k_list->d_ilist; - k_list->clean_copy(); - //cleanup_copy(); copymode = 1; dtsqrt = sqrt(update->dt); diff --git a/src/KOKKOS/neigh_list_kokkos.cpp b/src/KOKKOS/neigh_list_kokkos.cpp index b1b4e4467a..caf2dfee56 100644 --- a/src/KOKKOS/neigh_list_kokkos.cpp +++ b/src/KOKKOS/neigh_list_kokkos.cpp @@ -22,21 +22,14 @@ enum{NSQ,BIN,MULTI}; /* ---------------------------------------------------------------------- */ template -void NeighListKokkos::clean_copy() +NeighListKokkos::NeighListKokkos(class LAMMPS *lmp):NeighList(lmp) { - ilist = NULL; - numneigh = NULL; - firstneigh = NULL; - firstdouble = NULL; - dnum = 0; - iskip = NULL; - ijskip = NULL; - - ipage = NULL; - dpage = NULL; - + _stride = 1; + maxneighs = 16; + kokkos = 1; maxatoms = 0; -} + execution_space = ExecutionSpaceFromDevice::space; +}; /* ---------------------------------------------------------------------- */ diff --git a/src/KOKKOS/neigh_list_kokkos.h b/src/KOKKOS/neigh_list_kokkos.h index cece97197d..1c433f321c 100644 --- a/src/KOKKOS/neigh_list_kokkos.h +++ b/src/KOKKOS/neigh_list_kokkos.h @@ -68,18 +68,13 @@ class NeighListKokkos: public NeighList { public: int maxneighs; - void clean_copy(); void grow(int nmax); typename ArrayTypes::t_neighbors_2d d_neighbors; typename DAT::tdual_int_1d k_ilist; // local indices of I atoms typename ArrayTypes::t_int_1d d_ilist; typename ArrayTypes::t_int_1d d_numneigh; // # of J neighs for each I - NeighListKokkos(class LAMMPS *lmp): - NeighList(lmp) {_stride = 1; maxneighs = 16; kokkos = 1; maxatoms = 0; - execution_space = ExecutionSpaceFromDevice::space; - }; - ~NeighListKokkos() {numneigh = NULL; ilist = NULL;}; + NeighListKokkos(class LAMMPS *lmp); KOKKOS_INLINE_FUNCTION AtomNeighbors get_neighbors(const int &i) const { diff --git a/src/KOKKOS/npair_kokkos.h b/src/KOKKOS/npair_kokkos.h index b31ef2ebbf..ab094e68eb 100644 --- a/src/KOKKOS/npair_kokkos.h +++ b/src/KOKKOS/npair_kokkos.h @@ -265,7 +265,7 @@ class NeighborKokkosExecute h_new_maxneighs() = neigh_list.maxneighs; }; - ~NeighborKokkosExecute() {neigh_list.clean_copy();}; + ~NeighborKokkosExecute() {neigh_list.copymode = 1;}; template KOKKOS_FUNCTION diff --git a/src/KOKKOS/npair_ssa_kokkos.h b/src/KOKKOS/npair_ssa_kokkos.h index e38d648984..96efd7404b 100644 --- a/src/KOKKOS/npair_ssa_kokkos.h +++ b/src/KOKKOS/npair_ssa_kokkos.h @@ -287,7 +287,7 @@ class NPairSSAKokkosExecute h_new_maxneighs() = neigh_list.maxneighs; }; - ~NPairSSAKokkosExecute() {neigh_list.clean_copy();}; + ~NPairSSAKokkosExecute() {neigh_list.copymode = 1;}; void build_locals(); void build_ghosts(); diff --git a/src/KOKKOS/pair_coul_dsf_kokkos.cpp b/src/KOKKOS/pair_coul_dsf_kokkos.cpp index f2063bdc08..e6f5407f2d 100644 --- a/src/KOKKOS/pair_coul_dsf_kokkos.cpp +++ b/src/KOKKOS/pair_coul_dsf_kokkos.cpp @@ -120,9 +120,6 @@ void PairCoulDSFKokkos::compute(int eflag_in, int vflag_in) int inum = list->inum; - // Call cleanup_copy which sets allocations NULL which are destructed by the PairStyle - - k_list->clean_copy(); copymode = 1; // loop over neighbors of my atoms diff --git a/src/KOKKOS/pair_coul_wolf_kokkos.cpp b/src/KOKKOS/pair_coul_wolf_kokkos.cpp index 8049ba0031..75177e2d81 100644 --- a/src/KOKKOS/pair_coul_wolf_kokkos.cpp +++ b/src/KOKKOS/pair_coul_wolf_kokkos.cpp @@ -121,9 +121,6 @@ void PairCoulWolfKokkos::compute(int eflag_in, int vflag_in) int inum = list->inum; - // Call cleanup_copy which sets allocations NULL which are destructed by the PairStyle - - k_list->clean_copy(); copymode = 1; // loop over neighbors of my atoms diff --git a/src/KOKKOS/pair_eam_alloy_kokkos.cpp b/src/KOKKOS/pair_eam_alloy_kokkos.cpp index 45c320bc51..acf9b27963 100644 --- a/src/KOKKOS/pair_eam_alloy_kokkos.cpp +++ b/src/KOKKOS/pair_eam_alloy_kokkos.cpp @@ -122,9 +122,6 @@ void PairEAMAlloyKokkos::compute(int eflag_in, int vflag_in) d_ilist = k_list->d_ilist; int inum = list->inum; - // Call cleanup_copy which sets allocations NULL which are destructed by the PairStyle - - k_list->clean_copy(); copymode = 1; // zero out density diff --git a/src/KOKKOS/pair_eam_fs_kokkos.cpp b/src/KOKKOS/pair_eam_fs_kokkos.cpp index b9fa82740a..a31263dfcd 100644 --- a/src/KOKKOS/pair_eam_fs_kokkos.cpp +++ b/src/KOKKOS/pair_eam_fs_kokkos.cpp @@ -122,9 +122,6 @@ void PairEAMFSKokkos::compute(int eflag_in, int vflag_in) d_ilist = k_list->d_ilist; int inum = list->inum; - // Call cleanup_copy which sets allocations NULL which are destructed by the PairStyle - - k_list->clean_copy(); copymode = 1; // zero out density diff --git a/src/KOKKOS/pair_eam_kokkos.cpp b/src/KOKKOS/pair_eam_kokkos.cpp index e4128de722..006c9582c5 100644 --- a/src/KOKKOS/pair_eam_kokkos.cpp +++ b/src/KOKKOS/pair_eam_kokkos.cpp @@ -117,9 +117,6 @@ void PairEAMKokkos::compute(int eflag_in, int vflag_in) d_ilist = k_list->d_ilist; int inum = list->inum; - // Call cleanup_copy which sets allocations NULL which are destructed by the PairStyle - - k_list->clean_copy(); copymode = 1; // zero out density @@ -870,4 +867,4 @@ template class PairEAMKokkos; #ifdef KOKKOS_HAVE_CUDA template class PairEAMKokkos; #endif -} \ No newline at end of file +} diff --git a/src/KOKKOS/pair_kokkos.h b/src/KOKKOS/pair_kokkos.h index 1e01b3df15..b0614a934b 100644 --- a/src/KOKKOS/pair_kokkos.h +++ b/src/KOKKOS/pair_kokkos.h @@ -87,7 +87,7 @@ struct PairComputeFunctor { vatom(c.d_vatom),list(*list_ptr) {}; // Call cleanup_copy which sets allocations NULL which are destructed by the PairStyle - ~PairComputeFunctor() {c.cleanup_copy();list.clean_copy();}; + ~PairComputeFunctor() {c.cleanup_copy();list.copymode = 1;}; KOKKOS_INLINE_FUNCTION int sbmask(const int& j) const { return j >> SBBITS & 3; @@ -344,7 +344,7 @@ struct PairComputeFunctor { PairComputeFunctor(PairStyle* c_ptr, NeighListKokkos* list_ptr): c(*c_ptr),list(*list_ptr) {}; - ~PairComputeFunctor() {c.cleanup_copy();list.clean_copy();}; + ~PairComputeFunctor() {c.cleanup_copy();list.copymode = 1;}; KOKKOS_INLINE_FUNCTION int sbmask(const int& j) const { return j >> SBBITS & 3; diff --git a/src/KOKKOS/pair_reax_c_kokkos.cpp b/src/KOKKOS/pair_reax_c_kokkos.cpp index acf9c754cd..87915dce3e 100644 --- a/src/KOKKOS/pair_reax_c_kokkos.cpp +++ b/src/KOKKOS/pair_reax_c_kokkos.cpp @@ -709,8 +709,6 @@ void PairReaxCKokkos::compute(int eflag_in, int vflag_in) d_neighbors = k_list->d_neighbors; d_ilist = k_list->d_ilist; - k_list->clean_copy(); - if (eflag_global) { for (int i = 0; i < 14; i++) pvector[i] = 0.0; @@ -4012,7 +4010,6 @@ void PairReaxCKokkos::FindBond(int &numbonds) const int inum = list->inum; NeighListKokkos* k_list = static_cast*>(list); d_ilist = k_list->d_ilist; - k_list->clean_copy(); numbonds = 0; PairReaxCKokkosFindBondFunctor find_bond_functor(this); diff --git a/src/KOKKOS/pair_sw_kokkos.cpp b/src/KOKKOS/pair_sw_kokkos.cpp index a8950a0c79..e5c947cc8e 100644 --- a/src/KOKKOS/pair_sw_kokkos.cpp +++ b/src/KOKKOS/pair_sw_kokkos.cpp @@ -115,7 +115,6 @@ void PairSWKokkos::compute(int eflag_in, int vflag_in) d_numneigh = k_list->d_numneigh; d_neighbors = k_list->d_neighbors; - k_list->clean_copy(); copymode = 1; EV_FLOAT ev; diff --git a/src/KOKKOS/pair_tersoff_kokkos.cpp b/src/KOKKOS/pair_tersoff_kokkos.cpp index 75280c8f7c..833c815ad9 100644 --- a/src/KOKKOS/pair_tersoff_kokkos.cpp +++ b/src/KOKKOS/pair_tersoff_kokkos.cpp @@ -200,7 +200,6 @@ void PairTersoffKokkos::compute(int eflag_in, int vflag_in) d_neighbors = k_list->d_neighbors; d_ilist = k_list->d_ilist; - k_list->clean_copy(); copymode = 1; EV_FLOAT ev; diff --git a/src/KOKKOS/pair_tersoff_mod_kokkos.cpp b/src/KOKKOS/pair_tersoff_mod_kokkos.cpp index d16a7fc4d7..d77ba2f141 100644 --- a/src/KOKKOS/pair_tersoff_mod_kokkos.cpp +++ b/src/KOKKOS/pair_tersoff_mod_kokkos.cpp @@ -200,7 +200,6 @@ void PairTersoffMODKokkos::compute(int eflag_in, int vflag_in) d_neighbors = k_list->d_neighbors; d_ilist = k_list->d_ilist; - k_list->clean_copy(); copymode = 1; EV_FLOAT ev; diff --git a/src/KOKKOS/pair_tersoff_zbl_kokkos.cpp b/src/KOKKOS/pair_tersoff_zbl_kokkos.cpp index e9bae49fb7..040d8c5230 100644 --- a/src/KOKKOS/pair_tersoff_zbl_kokkos.cpp +++ b/src/KOKKOS/pair_tersoff_zbl_kokkos.cpp @@ -214,7 +214,6 @@ void PairTersoffZBLKokkos::compute(int eflag_in, int vflag_in) d_neighbors = k_list->d_neighbors; d_ilist = k_list->d_ilist; - k_list->clean_copy(); copymode = 1; EV_FLOAT ev; diff --git a/src/neigh_list.cpp b/src/neigh_list.cpp index 6376637832..dde544a69f 100644 --- a/src/neigh_list.cpp +++ b/src/neigh_list.cpp @@ -48,6 +48,7 @@ NeighList::NeighList(LAMMPS *lmp) : Pointers(lmp) ghost = 0; ssa = 0; copy = 0; + copymode = 0; dnum = 0; // ptrs @@ -86,6 +87,7 @@ NeighList::NeighList(LAMMPS *lmp) : Pointers(lmp) NeighList::~NeighList() { + if (copymode) return; if (!copy) { memory->destroy(ilist); memory->destroy(numneigh); diff --git a/src/neigh_list.h b/src/neigh_list.h index bef512512c..4010a68857 100644 --- a/src/neigh_list.h +++ b/src/neigh_list.h @@ -34,7 +34,8 @@ class NeighList : protected Pointers { int occasional; // 0 if build every reneighbor, 1 if not int ghost; // 1 if list stores neighbors of ghosts int ssa; // 1 if list stores Shardlow data - int copy; // 1 if this list copied from another list + int copy; // 1 if this list is (host) copied from another list + int copymode; // 1 if this is a Kokkos on-device copy int dnum; // # of doubles per neighbor, 0 if none // data structs to store neighbor pairs I,J and associated values From bf4f0817d4f85bc22a6f1b3a01b40b8f23b46a6b Mon Sep 17 00:00:00 2001 From: Dan Ibanez Date: Fri, 31 Mar 2017 15:57:00 -0600 Subject: [PATCH 222/439] fix memory leaks in pair_tabl_rx_kokkos --- src/KOKKOS/pair_table_rx_kokkos.cpp | 19 ++++++++++++++----- src/USER-DPD/pair_table_rx.cpp | 10 ++++++++++ src/USER-DPD/pair_table_rx.h | 2 +- 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/KOKKOS/pair_table_rx_kokkos.cpp b/src/KOKKOS/pair_table_rx_kokkos.cpp index 044f303bf5..eacaf83cf5 100644 --- a/src/KOKKOS/pair_table_rx_kokkos.cpp +++ b/src/KOKKOS/pair_table_rx_kokkos.cpp @@ -147,6 +147,9 @@ PairTableRXKokkos::PairTableRXKokkos(LAMMPS *lmp) : PairTable(lmp) h_table = new TableHost(); d_table = new TableDevice(); fractionalWeighting = true; + + site1 = nullptr; + site2 = nullptr; } /* ---------------------------------------------------------------------- */ @@ -156,14 +159,21 @@ PairTableRXKokkos::~PairTableRXKokkos() { if (copymode) return; + delete [] site1; + delete [] site2; + memory->destroy_kokkos(k_eatom,eatom); memory->destroy_kokkos(k_vatom,vatom); + if (allocated) { + memory->destroy_kokkos(d_table->cutsq, cutsq); + memory->destroy_kokkos(d_table->tabindex, tabindex); + } + delete h_table; h_table = nullptr; delete d_table; d_table = nullptr; - copymode = true; //prevents base class destructor from running } /* ---------------------------------------------------------------------- */ @@ -981,6 +991,8 @@ void PairTableRXKokkos::settings(int narg, char **arg) for (int m = 0; m < ntables; m++) free_table(&tables[m]); memory->sfree(tables); + ntables = 0; + tables = NULL; if (allocated) { memory->destroy(setflag); @@ -990,11 +1002,8 @@ void PairTableRXKokkos::settings(int narg, char **arg) d_table_const.cutsq = d_table->cutsq = typename ArrayTypes::t_ffloat_2d(); h_table->cutsq = typename ArrayTypes::t_ffloat_2d(); + allocated = 0; } - allocated = 0; - - ntables = 0; - tables = NULL; } /* ---------------------------------------------------------------------- diff --git a/src/USER-DPD/pair_table_rx.cpp b/src/USER-DPD/pair_table_rx.cpp index cf85fe2e60..89d09e7322 100644 --- a/src/USER-DPD/pair_table_rx.cpp +++ b/src/USER-DPD/pair_table_rx.cpp @@ -47,6 +47,16 @@ enum{NONE,RLINEAR,RSQ,BMP}; PairTableRX::PairTableRX(LAMMPS *lmp) : PairTable(lmp) { fractionalWeighting = true; + site1 = NULL; + site2 = NULL; +} + +/* ---------------------------------------------------------------------- */ + +PairTableRX::~PairTableRX() +{ + delete [] site1; + delete [] site2; } /* ---------------------------------------------------------------------- */ diff --git a/src/USER-DPD/pair_table_rx.h b/src/USER-DPD/pair_table_rx.h index 9dee5df266..da7889e99a 100644 --- a/src/USER-DPD/pair_table_rx.h +++ b/src/USER-DPD/pair_table_rx.h @@ -27,7 +27,7 @@ namespace LAMMPS_NS { class PairTableRX : public PairTable { public: PairTableRX(class LAMMPS *); - virtual ~PairTableRX() {} + virtual ~PairTableRX(); virtual void compute(int, int); void settings(int, char **); From 5edbd63920681f585b054d4aebf2fb7eb462f5ce Mon Sep 17 00:00:00 2001 From: Dan Ibanez Date: Fri, 31 Mar 2017 16:03:05 -0600 Subject: [PATCH 223/439] fix memory leak in fix_shardlow_kokkos --- src/KOKKOS/fix_shardlow_kokkos.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/KOKKOS/fix_shardlow_kokkos.cpp b/src/KOKKOS/fix_shardlow_kokkos.cpp index 676df07b61..52287d586c 100644 --- a/src/KOKKOS/fix_shardlow_kokkos.cpp +++ b/src/KOKKOS/fix_shardlow_kokkos.cpp @@ -741,6 +741,7 @@ fprintf(stdout, "\n%6d %6d,%6d %6d: " ); #endif + copymode = 0; } /* ---------------------------------------------------------------------- */ From fe82926c1f41d2a99ad75ca3d07312ad0945e52a Mon Sep 17 00:00:00 2001 From: Dan Ibanez Date: Fri, 31 Mar 2017 15:57:00 -0600 Subject: [PATCH 224/439] fix memory leaks in pair_tabl_rx_kokkos --- src/KOKKOS/pair_table_rx_kokkos.cpp | 19 ++++++++++++++----- src/USER-DPD/pair_table_rx.cpp | 10 ++++++++++ src/USER-DPD/pair_table_rx.h | 2 +- 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/KOKKOS/pair_table_rx_kokkos.cpp b/src/KOKKOS/pair_table_rx_kokkos.cpp index 044f303bf5..eacaf83cf5 100644 --- a/src/KOKKOS/pair_table_rx_kokkos.cpp +++ b/src/KOKKOS/pair_table_rx_kokkos.cpp @@ -147,6 +147,9 @@ PairTableRXKokkos::PairTableRXKokkos(LAMMPS *lmp) : PairTable(lmp) h_table = new TableHost(); d_table = new TableDevice(); fractionalWeighting = true; + + site1 = nullptr; + site2 = nullptr; } /* ---------------------------------------------------------------------- */ @@ -156,14 +159,21 @@ PairTableRXKokkos::~PairTableRXKokkos() { if (copymode) return; + delete [] site1; + delete [] site2; + memory->destroy_kokkos(k_eatom,eatom); memory->destroy_kokkos(k_vatom,vatom); + if (allocated) { + memory->destroy_kokkos(d_table->cutsq, cutsq); + memory->destroy_kokkos(d_table->tabindex, tabindex); + } + delete h_table; h_table = nullptr; delete d_table; d_table = nullptr; - copymode = true; //prevents base class destructor from running } /* ---------------------------------------------------------------------- */ @@ -981,6 +991,8 @@ void PairTableRXKokkos::settings(int narg, char **arg) for (int m = 0; m < ntables; m++) free_table(&tables[m]); memory->sfree(tables); + ntables = 0; + tables = NULL; if (allocated) { memory->destroy(setflag); @@ -990,11 +1002,8 @@ void PairTableRXKokkos::settings(int narg, char **arg) d_table_const.cutsq = d_table->cutsq = typename ArrayTypes::t_ffloat_2d(); h_table->cutsq = typename ArrayTypes::t_ffloat_2d(); + allocated = 0; } - allocated = 0; - - ntables = 0; - tables = NULL; } /* ---------------------------------------------------------------------- diff --git a/src/USER-DPD/pair_table_rx.cpp b/src/USER-DPD/pair_table_rx.cpp index cf85fe2e60..89d09e7322 100644 --- a/src/USER-DPD/pair_table_rx.cpp +++ b/src/USER-DPD/pair_table_rx.cpp @@ -47,6 +47,16 @@ enum{NONE,RLINEAR,RSQ,BMP}; PairTableRX::PairTableRX(LAMMPS *lmp) : PairTable(lmp) { fractionalWeighting = true; + site1 = NULL; + site2 = NULL; +} + +/* ---------------------------------------------------------------------- */ + +PairTableRX::~PairTableRX() +{ + delete [] site1; + delete [] site2; } /* ---------------------------------------------------------------------- */ diff --git a/src/USER-DPD/pair_table_rx.h b/src/USER-DPD/pair_table_rx.h index 9dee5df266..da7889e99a 100644 --- a/src/USER-DPD/pair_table_rx.h +++ b/src/USER-DPD/pair_table_rx.h @@ -27,7 +27,7 @@ namespace LAMMPS_NS { class PairTableRX : public PairTable { public: PairTableRX(class LAMMPS *); - virtual ~PairTableRX() {} + virtual ~PairTableRX(); virtual void compute(int, int); void settings(int, char **); From 6ba59cb4583c86af3f0104bb10e1ecd324bf9cce Mon Sep 17 00:00:00 2001 From: Dan Ibanez Date: Fri, 31 Mar 2017 16:03:05 -0600 Subject: [PATCH 225/439] fix memory leak in fix_shardlow_kokkos --- src/KOKKOS/fix_shardlow_kokkos.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/KOKKOS/fix_shardlow_kokkos.cpp b/src/KOKKOS/fix_shardlow_kokkos.cpp index 676df07b61..52287d586c 100644 --- a/src/KOKKOS/fix_shardlow_kokkos.cpp +++ b/src/KOKKOS/fix_shardlow_kokkos.cpp @@ -741,6 +741,7 @@ fprintf(stdout, "\n%6d %6d,%6d %6d: " ); #endif + copymode = 0; } /* ---------------------------------------------------------------------- */ From ac64183ecfdd1a7cdd82770c96e1fbe05934967e Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Sat, 1 Apr 2017 12:11:55 -0400 Subject: [PATCH 226/439] USER-DPD Kokkos: WIP on preflighting SSA neighbor list build, with debugging --- src/KOKKOS/npair_ssa_kokkos.cpp | 73 +++++++++++++++++++++++++++++++-- 1 file changed, 69 insertions(+), 4 deletions(-) diff --git a/src/KOKKOS/npair_ssa_kokkos.cpp b/src/KOKKOS/npair_ssa_kokkos.cpp index 59470189bc..87cc02e734 100644 --- a/src/KOKKOS/npair_ssa_kokkos.cpp +++ b/src/KOKKOS/npair_ssa_kokkos.cpp @@ -240,6 +240,58 @@ void NPairSSAKokkos::build(NeighList *list_) ssa_gitemLen = k_ssa_gitemLen.view(); } +{ // Preflight the neighbor list build + const typename ArrayTypes::t_int_1d_const c_bincount = k_bincount.view(); + int inum = 0; + + int workPhase = 0; + // loop over bins with local atoms, storing half of the neighbors + for (int zoff = sz1 - 1; zoff >= 0; --zoff) { + for (int yoff = sy1 - 1; yoff >= 0; --yoff) { + for (int xoff = sx1 - 1; xoff >= 0; --xoff) { + int workItem = 0; + for (int zbin = lbinzlo + zoff; zbin < lbinzhi; zbin += sz1) { + for (int ybin = lbinylo + yoff - sy1 + 1; ybin < lbinyhi; ybin += sy1) { + for (int xbin = lbinxlo + xoff - sx1 + 1; xbin < lbinxhi; xbin += sx1) { +// if (workItem >= phaseLenEstimate) error->one(FLERR,"phaseLenEstimate was too small"); + ssa_itemLoc(workPhase, workItem) = inum; // record where workItem starts in ilist + + for (int subphase = 0; subphase < 4; subphase++) { + int s_ybin = ybin + ((subphase & 0x2) ? sy1 - 1 : 0); + int s_xbin = xbin + ((subphase & 0x1) ? sx1 - 1 : 0); + if ((s_ybin < lbinylo) || (s_ybin >= lbinyhi)) continue; + if ((s_xbin < lbinxlo) || (s_xbin >= lbinxhi)) continue; + + int ibin = zbin*mbiny*mbinx + s_ybin*mbinx + s_xbin; + inum += c_bincount(ibin); + } + // record where workItem ends in ilist + ssa_itemLen(workPhase,workItem) = inum - ssa_itemLoc(workPhase,workItem); + if (ssa_itemLen(workPhase,workItem) > 0) workItem++; + } + } + } + +fprintf(stdout, "phase %3d could use %6d inums, expected %6d inums. maxworkItems = %3d, inums/workItems = %g\n" + ,workPhase + ,inum - ssa_itemLoc(workPhase, 0) + ,(nlocal*4 + ssa_phaseCt - 1) / ssa_phaseCt + ,workItem + ,(inum - ssa_itemLoc(workPhase, 0)) / (double) workItem +); + // record where workPhase ends + ssa_phaseLen(workPhase++) = workItem; + } + } + } +fprintf(stdout, "total %3d could use %6d inums, expected %6d inums. inums/phase = %g\n" + ,workPhase + ,inum + ,nlocal*4 + ,inum / (double) workPhase +); +} + NPairSSAKokkosExecute data(*list, k_cutneighsq.view(), @@ -355,18 +407,18 @@ void NPairSSAKokkosExecute::build_locals() int n = 0; int which = 0; int inum = 0; - int workPhase = 0; + // loop over bins with local atoms, storing half of the neighbors for (int zoff = sz1 - 1; zoff >= 0; --zoff) { for (int yoff = sy1 - 1; yoff >= 0; --yoff) { for (int xoff = sx1 - 1; xoff >= 0; --xoff) { int workItem = 0; + inum = d_ssa_itemLoc(workPhase, workItem); // get where workPhase starts in ilist for (int zbin = lbinzlo + zoff; zbin < lbinzhi; zbin += sz1) { for (int ybin = lbinylo + yoff - sy1 + 1; ybin < lbinyhi; ybin += sy1) { for (int xbin = lbinxlo + xoff - sx1 + 1; xbin < lbinxhi; xbin += sx1) { -// if (workItem >= phaseLenEstimate) error->one(FLERR,"phaseLenEstimate was too small"); - d_ssa_itemLoc(workPhase, workItem) = inum; // record where workItem starts in ilist + d_ssa_itemLoc(workPhase, workItem) = inum; // record where workItem actually starts in ilist for (int subphase = 0; subphase < 4; subphase++) { int s_ybin = ybin + ((subphase & 0x2) ? sy1 - 1 : 0); @@ -441,18 +493,31 @@ void NPairSSAKokkosExecute::build_locals() } } } - // record where workItem ends in ilist + // record where workItem actually ends in ilist d_ssa_itemLen(workPhase,workItem) = inum - d_ssa_itemLoc(workPhase,workItem); if (d_ssa_itemLen(workPhase,workItem) > 0) workItem++; } } } +fprintf(stdout, "phase %3d used %6d inums, expected %6d inums. workItems = %3d, inums/workItems = %g\n" + ,workPhase + ,inum - d_ssa_itemLoc(workPhase, 0) + ,(nlocal*4 + ssa_phaseCt - 1) / ssa_phaseCt + ,workItem + ,(inum - d_ssa_itemLoc(workPhase, 0)) / (double) workItem +); // record where workPhase ends d_ssa_phaseLen(workPhase++) = workItem; } } } +fprintf(stdout, "Total %3d could use %6d inums, expected %6d inums. inums/phase = %g\n" + ,workPhase + ,inum + ,nlocal*4 + ,inum / (double) workPhase +); //FIXME if (ssa_phaseCt != workPhase) error->one(FLERR,"ssa_phaseCt was wrong"); From ac4c35ce8d1caf0d7deaa1f0c816c0f5f5d9c523 Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Sat, 1 Apr 2017 13:45:29 -0400 Subject: [PATCH 227/439] USER-DPD Kokkos: more WIP on preflighting SSA neighbor list build, with debugging --- src/KOKKOS/npair_ssa_kokkos.cpp | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/src/KOKKOS/npair_ssa_kokkos.cpp b/src/KOKKOS/npair_ssa_kokkos.cpp index 87cc02e734..5c20f1c270 100644 --- a/src/KOKKOS/npair_ssa_kokkos.cpp +++ b/src/KOKKOS/npair_ssa_kokkos.cpp @@ -205,8 +205,7 @@ void NPairSSAKokkos::build(NeighList *list_) { NeighListKokkos* list = (NeighListKokkos*) list_; const int nlocal = includegroup?atom->nfirst:atom->nlocal; - const int nl_size = (nlocal * 4) + atom->nghost; - list->grow(nl_size); // Make special larger SSA neighbor list + int nl_size = atom->nghost; ssa_phaseCt = sz1*sy1*sx1; @@ -240,8 +239,11 @@ void NPairSSAKokkos::build(NeighList *list_) ssa_gitemLen = k_ssa_gitemLen.view(); } -{ // Preflight the neighbor list build +{ // Preflight the neighbor list workplan const typename ArrayTypes::t_int_1d_const c_bincount = k_bincount.view(); + const typename ArrayTypes::t_int_2d_const c_bins = k_bins.view(); + const typename ArrayTypes::t_int_1d_const_um c_stencil = k_stencil.view(); + const typename ArrayTypes::t_int_1d_const c_nstencil_ssa = k_nstencil_ssa.view(); int inum = 0; int workPhase = 0; @@ -263,7 +265,17 @@ void NPairSSAKokkos::build(NeighList *list_) if ((s_xbin < lbinxlo) || (s_xbin >= lbinxhi)) continue; int ibin = zbin*mbiny*mbinx + s_ybin*mbinx + s_xbin; - inum += c_bincount(ibin); + for (int il = 0; il < c_bincount(ibin); ++il) { + int n = 0; + + // count all local atoms in the current stencil "subphase" as potential neighbors + for (int k = c_nstencil_ssa(subphase); k < c_nstencil_ssa(subphase+1); k++) { + const int jbin = ibin+c_stencil(k); + int jl = (jbin != ibin) ? 0 : (il + 1); // same bin as il, so start just past il in the bin + n += c_bincount(jbin) - jl; + } + if (n > 0) inum++; + } } // record where workItem ends in ilist ssa_itemLen(workPhase,workItem) = inum - ssa_itemLoc(workPhase,workItem); @@ -290,8 +302,11 @@ fprintf(stdout, "total %3d could use %6d inums, expected %6d inums. inums/phase ,nlocal*4 ,inum / (double) workPhase ); + nl_size += inum; } + list->grow(nl_size); // Make special larger SSA neighbor list + NPairSSAKokkosExecute data(*list, k_cutneighsq.view(), @@ -404,7 +419,6 @@ fprintf(stdout, "total %3d could use %6d inums, expected %6d inums. inums/phase template void NPairSSAKokkosExecute::build_locals() { - int n = 0; int which = 0; int inum = 0; int workPhase = 0; @@ -429,7 +443,7 @@ void NPairSSAKokkosExecute::build_locals() int ibin = zbin*mbiny*mbinx + s_ybin*mbinx + s_xbin; for (int il = 0; il < c_bincount(ibin); ++il) { const int i = c_bins(ibin, il); - n = 0; + int n = 0; const AtomNeighbors neighbors_i = neigh_list.get_neighbors(inum); const X_FLOAT xtmp = x(i, 0); From e0021a3ff51702ed4b5c79720dfe69dd247988fa Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Sat, 1 Apr 2017 14:41:52 -0400 Subject: [PATCH 228/439] USER-DPD Kokkos: preflight SSA neigh list workplan to reduce allocated storage --- src/KOKKOS/npair_ssa_kokkos.cpp | 36 +++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/src/KOKKOS/npair_ssa_kokkos.cpp b/src/KOKKOS/npair_ssa_kokkos.cpp index 5c20f1c270..1c7095c9b4 100644 --- a/src/KOKKOS/npair_ssa_kokkos.cpp +++ b/src/KOKKOS/npair_ssa_kokkos.cpp @@ -205,7 +205,7 @@ void NPairSSAKokkos::build(NeighList *list_) { NeighListKokkos* list = (NeighListKokkos*) list_; const int nlocal = includegroup?atom->nfirst:atom->nlocal; - int nl_size = atom->nghost; + int nl_size; ssa_phaseCt = sz1*sy1*sx1; @@ -265,17 +265,17 @@ void NPairSSAKokkos::build(NeighList *list_) if ((s_xbin < lbinxlo) || (s_xbin >= lbinxhi)) continue; int ibin = zbin*mbiny*mbinx + s_ybin*mbinx + s_xbin; - for (int il = 0; il < c_bincount(ibin); ++il) { - int n = 0; - - // count all local atoms in the current stencil "subphase" as potential neighbors - for (int k = c_nstencil_ssa(subphase); k < c_nstencil_ssa(subphase+1); k++) { - const int jbin = ibin+c_stencil(k); - int jl = (jbin != ibin) ? 0 : (il + 1); // same bin as il, so start just past il in the bin - n += c_bincount(jbin) - jl; - } - if (n > 0) inum++; + int base_n = 0; + bool include_same = false; + // count all local atoms in the current stencil "subphase" as potential neighbors + for (int k = c_nstencil_ssa(subphase); k < c_nstencil_ssa(subphase+1); k++) { + const int jbin = ibin+c_stencil(k); + if (jbin != ibin) base_n += c_bincount(jbin); + else include_same = true; } + // Calculate how many ibin particles would have had some neighbors + if (base_n > 0) inum += c_bincount(ibin); + else if (include_same) inum += c_bincount(ibin) - 1; } // record where workItem ends in ilist ssa_itemLen(workPhase,workItem) = inum - ssa_itemLoc(workPhase,workItem); @@ -302,9 +302,12 @@ fprintf(stdout, "total %3d could use %6d inums, expected %6d inums. inums/phase ,nlocal*4 ,inum / (double) workPhase ); - nl_size += inum; + nl_size = inum; // record how much space is needed for the local work plan } - + // count how many ghosts are likely to have neighbors, and increase the work plan storage + for (int workPhase = 0; workPhase < ssa_gphaseCt; workPhase++) { + nl_size += k_gbincount.h_view(workPhase + 1); + } list->grow(nl_size); // Make special larger SSA neighbor list NPairSSAKokkosExecute @@ -412,6 +415,13 @@ fprintf(stdout, "total %3d could use %6d inums, expected %6d inums. inums/phase list->inum = data.neigh_list.inum; //FIXME once the above is in a parallel_for list->gnum = data.neigh_list.gnum; // it will need a deep_copy or something +fprintf(stdout, "%6d inum %6d gnum, total used %6d, allocated %6d\n" + ,list->inum + ,list->gnum + ,list->inum + list->gnum + ,nl_size +); + list->k_ilist.template modify(); } From c4c3d490c7e0e4c416a119f852ef2973229c2815 Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Sat, 1 Apr 2017 23:52:14 -0400 Subject: [PATCH 229/439] USER-DPD Kokkos: preflight storage needed for SSA threaded neigh list build --- src/KOKKOS/npair_ssa_kokkos.cpp | 122 +++++++++++++++++++++++--------- src/KOKKOS/npair_ssa_kokkos.h | 2 +- 2 files changed, 90 insertions(+), 34 deletions(-) diff --git a/src/KOKKOS/npair_ssa_kokkos.cpp b/src/KOKKOS/npair_ssa_kokkos.cpp index 1c7095c9b4..042c48fbac 100644 --- a/src/KOKKOS/npair_ssa_kokkos.cpp +++ b/src/KOKKOS/npair_ssa_kokkos.cpp @@ -25,6 +25,7 @@ #include "nbin_ssa_kokkos.h" #include "nstencil_ssa.h" #include "error.h" +#include "comm.h" namespace LAMMPS_NS { @@ -255,8 +256,8 @@ void NPairSSAKokkos::build(NeighList *list_) for (int zbin = lbinzlo + zoff; zbin < lbinzhi; zbin += sz1) { for (int ybin = lbinylo + yoff - sy1 + 1; ybin < lbinyhi; ybin += sy1) { for (int xbin = lbinxlo + xoff - sx1 + 1; xbin < lbinxhi; xbin += sx1) { + int inum_start = inum; // if (workItem >= phaseLenEstimate) error->one(FLERR,"phaseLenEstimate was too small"); - ssa_itemLoc(workPhase, workItem) = inum; // record where workItem starts in ilist for (int subphase = 0; subphase < 4; subphase++) { int s_ybin = ybin + ((subphase & 0x2) ? sy1 - 1 : 0); @@ -264,27 +265,40 @@ void NPairSSAKokkos::build(NeighList *list_) if ((s_ybin < lbinylo) || (s_ybin >= lbinyhi)) continue; if ((s_xbin < lbinxlo) || (s_xbin >= lbinxhi)) continue; - int ibin = zbin*mbiny*mbinx + s_ybin*mbinx + s_xbin; - int base_n = 0; - bool include_same = false; - // count all local atoms in the current stencil "subphase" as potential neighbors - for (int k = c_nstencil_ssa(subphase); k < c_nstencil_ssa(subphase+1); k++) { - const int jbin = ibin+c_stencil(k); - if (jbin != ibin) base_n += c_bincount(jbin); - else include_same = true; + const int ibin = zbin*mbiny*mbinx + s_ybin*mbinx + s_xbin; + const int ibinCt = c_bincount(ibin); + if (ibinCt > 0) { + int base_n = 0; + bool include_same = false; + // count all local atoms in the current stencil "subphase" as potential neighbors + for (int k = c_nstencil_ssa(subphase); k < c_nstencil_ssa(subphase+1); k++) { + const int jbin = ibin+c_stencil(k); + if (jbin != ibin) base_n += c_bincount(jbin); + else include_same = true; + } + // Calculate how many ibin particles would have had some neighbors + if (base_n > 0) inum += ibinCt; + else if (include_same) inum += ibinCt - 1; } - // Calculate how many ibin particles would have had some neighbors - if (base_n > 0) inum += c_bincount(ibin); - else if (include_same) inum += c_bincount(ibin) - 1; } - // record where workItem ends in ilist - ssa_itemLen(workPhase,workItem) = inum - ssa_itemLoc(workPhase,workItem); - if (ssa_itemLen(workPhase,workItem) > 0) workItem++; + /* if (inum > inum_start) */ { + ssa_itemLoc(workPhase,workItem) = inum_start; // record where workItem starts in ilist + ssa_itemLen(workPhase,workItem) = inum - inum_start; // record workItem length +if (ssa_itemLen(workPhase,workItem) < 0) fprintf(stdout, "undr%03d phase (%3d,%3d) inum %d - inum_start %d UNDERFLOW\n" + ,comm->me + ,workPhase + ,workItem + ,inum + ,inum_start +); + workItem++; + } } } } -fprintf(stdout, "phase %3d could use %6d inums, expected %6d inums. maxworkItems = %3d, inums/workItems = %g\n" +fprintf(stdout, "phas%03d phase %3d could use %6d inums, expected %6d inums. maxworkItems = %3d, inums/workItems = %g\n" + ,comm->me ,workPhase ,inum - ssa_itemLoc(workPhase, 0) ,(nlocal*4 + ssa_phaseCt - 1) / ssa_phaseCt @@ -296,7 +310,8 @@ fprintf(stdout, "phase %3d could use %6d inums, expected %6d inums. maxworkItems } } } -fprintf(stdout, "total %3d could use %6d inums, expected %6d inums. inums/phase = %g\n" +fprintf(stdout, "tota%03d total %3d could use %6d inums, expected %6d inums. inums/phase = %g\n" + ,comm->me ,workPhase ,inum ,nlocal*4 @@ -378,6 +393,7 @@ fprintf(stdout, "total %3d could use %6d inums, expected %6d inums. inums/phase data.special_flag[2] = special_flag[2]; data.special_flag[3] = special_flag[3]; + bool firstTry = true; data.h_resize()=1; while(data.h_resize()) { data.h_new_maxneighs() = list->maxneighs; @@ -390,8 +406,9 @@ fprintf(stdout, "total %3d could use %6d inums, expected %6d inums. inums/phase NPairSSAKokkosBuildFunctor f(data,atoms_per_bin*5*sizeof(X_FLOAT)); Kokkos::parallel_for(nall, f); #endif - data.build_locals(); + data.build_locals(firstTry, comm->me); data.build_ghosts(); + firstTry = false; DeviceType::fence(); deep_copy(data.h_resize, data.resize); @@ -415,7 +432,8 @@ fprintf(stdout, "total %3d could use %6d inums, expected %6d inums. inums/phase list->inum = data.neigh_list.inum; //FIXME once the above is in a parallel_for list->gnum = data.neigh_list.gnum; // it will need a deep_copy or something -fprintf(stdout, "%6d inum %6d gnum, total used %6d, allocated %6d\n" +fprintf(stdout, "Fina%03d: %6d inum %6d gnum, total used %6d, allocated %6d\n" + ,comm->me ,list->inum ,list->gnum ,list->inum + list->gnum @@ -427,8 +445,9 @@ fprintf(stdout, "%6d inum %6d gnum, total used %6d, allocated %6d\n" template -void NPairSSAKokkosExecute::build_locals() +void NPairSSAKokkosExecute::build_locals(const bool firstTry, int me) { + const typename ArrayTypes::t_int_1d_const_um stencil = d_stencil; int which = 0; int inum = 0; int workPhase = 0; @@ -438,11 +457,29 @@ void NPairSSAKokkosExecute::build_locals() for (int yoff = sy1 - 1; yoff >= 0; --yoff) { for (int xoff = sx1 - 1; xoff >= 0; --xoff) { int workItem = 0; - inum = d_ssa_itemLoc(workPhase, workItem); // get where workPhase starts in ilist + int skippedItems = 0; +// inum = d_ssa_itemLoc(workPhase, workItem); // get where workPhase starts in ilist for (int zbin = lbinzlo + zoff; zbin < lbinzhi; zbin += sz1) { for (int ybin = lbinylo + yoff - sy1 + 1; ybin < lbinyhi; ybin += sy1) { for (int xbin = lbinxlo + xoff - sx1 + 1; xbin < lbinxhi; xbin += sx1) { - d_ssa_itemLoc(workPhase, workItem) = inum; // record where workItem actually starts in ilist + if (d_ssa_itemLen(workPhase, workItem + skippedItems) == 0) { + if (firstTry) ++skippedItems; + else ++workItem; // phase is done,should break out of three loops here if we could... + continue; + } + int inum_start = d_ssa_itemLoc(workPhase, workItem + skippedItems); + if (inum > inum_start) { // This shouldn't happen! +fprintf(stdout, "Rank%03d workphase (%2d,%3d,%3d): inum = %4d, but ssa_itemLoc = %4d OVERFLOW\n" + ,me + ,workPhase + ,workItem + ,workItem + skippedItems + ,inum + ,d_ssa_itemLoc(workPhase, workItem + skippedItems) +); + inum_start = inum; + } else inum = inum_start; + // d_ssa_itemLoc(workPhase, workItem) = inum; // record where workItem actually starts in ilist for (int subphase = 0; subphase < 4; subphase++) { int s_ybin = ybin + ((subphase & 0x2) ? sy1 - 1 : 0); @@ -461,9 +498,6 @@ void NPairSSAKokkosExecute::build_locals() const X_FLOAT ztmp = x(i, 2); const int itype = type(i); - const typename ArrayTypes::t_int_1d_const_um stencil - = d_stencil; - // loop over all local atoms in the current stencil "subphase" for (int k = d_nstencil_ssa(subphase); k < d_nstencil_ssa(subphase+1); k++) { const int jbin = ibin+stencil(k); @@ -517,26 +551,48 @@ void NPairSSAKokkosExecute::build_locals() } } } - // record where workItem actually ends in ilist - d_ssa_itemLen(workPhase,workItem) = inum - d_ssa_itemLoc(workPhase,workItem); - if (d_ssa_itemLen(workPhase,workItem) > 0) workItem++; + int len = inum - inum_start; + if (len != d_ssa_itemLen(workPhase, workItem + skippedItems)) { +fprintf(stdout, "Leng%03d workphase (%2d,%3d,%3d): len = %4d, but ssa_itemLen = %4d%s\n" + ,me + ,workPhase + ,workItem + ,workItem + skippedItems + ,len + ,d_ssa_itemLen(workPhase, workItem + skippedItems) + ,(len > d_ssa_itemLen(workPhase, workItem + skippedItems)) ? " OVERFLOW" : "" +); + } + if (inum > inum_start) { + d_ssa_itemLoc(workPhase,workItem) = inum_start; // record where workItem starts in ilist + d_ssa_itemLen(workPhase,workItem) = inum - inum_start; // record actual workItem length + workItem++; + } else if (firstTry) ++skippedItems; } } } -fprintf(stdout, "phase %3d used %6d inums, expected %6d inums. workItems = %3d, inums/workItems = %g\n" +fprintf(stdout, "Phas%03d phase %3d used %6d inums, workItems = %3d, skipped = %3d, inums/workItems = %g\n" + ,me ,workPhase ,inum - d_ssa_itemLoc(workPhase, 0) - ,(nlocal*4 + ssa_phaseCt - 1) / ssa_phaseCt ,workItem + ,skippedItems ,(inum - d_ssa_itemLoc(workPhase, 0)) / (double) workItem ); - // record where workPhase ends - d_ssa_phaseLen(workPhase++) = workItem; + // record where workPhase actually ends + if (firstTry) { + d_ssa_phaseLen(workPhase) = workItem; + while (workItem < (int) d_ssa_itemLen.dimension_1()) { + d_ssa_itemLen(workPhase,workItem++) = 0; + } + } + ++workPhase; } } } -fprintf(stdout, "Total %3d could use %6d inums, expected %6d inums. inums/phase = %g\n" +fprintf(stdout, "Totl%03d %3d could use %6d inums, expected %6d inums. inums/phase = %g\n" + ,me ,workPhase ,inum ,nlocal*4 diff --git a/src/KOKKOS/npair_ssa_kokkos.h b/src/KOKKOS/npair_ssa_kokkos.h index 96efd7404b..2c2ae15fb8 100644 --- a/src/KOKKOS/npair_ssa_kokkos.h +++ b/src/KOKKOS/npair_ssa_kokkos.h @@ -289,7 +289,7 @@ class NPairSSAKokkosExecute ~NPairSSAKokkosExecute() {neigh_list.copymode = 1;}; - void build_locals(); + void build_locals(const bool firstTry, int me); void build_ghosts(); KOKKOS_INLINE_FUNCTION From 2b2f3bd57c1d42a87334812cdab06f7e75405b7e Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Sun, 2 Apr 2017 00:07:24 -0400 Subject: [PATCH 230/439] USER-DPD Kokkos: #ifdef DEBUG_SSA_BUILD_LOCALS the new debug output --- src/KOKKOS/npair_ssa_kokkos.cpp | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/src/KOKKOS/npair_ssa_kokkos.cpp b/src/KOKKOS/npair_ssa_kokkos.cpp index 042c48fbac..4c3218a08a 100644 --- a/src/KOKKOS/npair_ssa_kokkos.cpp +++ b/src/KOKKOS/npair_ssa_kokkos.cpp @@ -281,9 +281,9 @@ void NPairSSAKokkos::build(NeighList *list_) else if (include_same) inum += ibinCt - 1; } } - /* if (inum > inum_start) */ { - ssa_itemLoc(workPhase,workItem) = inum_start; // record where workItem starts in ilist - ssa_itemLen(workPhase,workItem) = inum - inum_start; // record workItem length + ssa_itemLoc(workPhase,workItem) = inum_start; // record where workItem starts in ilist + ssa_itemLen(workPhase,workItem) = inum - inum_start; // record workItem length +#ifdef DEBUG_SSA_BUILD_LOCALS if (ssa_itemLen(workPhase,workItem) < 0) fprintf(stdout, "undr%03d phase (%3d,%3d) inum %d - inum_start %d UNDERFLOW\n" ,comm->me ,workPhase @@ -291,12 +291,13 @@ if (ssa_itemLen(workPhase,workItem) < 0) fprintf(stdout, "undr%03d phase (%3d,%3 ,inum ,inum_start ); - workItem++; - } +#endif + workItem++; } } } +#ifdef DEBUG_SSA_BUILD_LOCALS fprintf(stdout, "phas%03d phase %3d could use %6d inums, expected %6d inums. maxworkItems = %3d, inums/workItems = %g\n" ,comm->me ,workPhase @@ -305,11 +306,13 @@ fprintf(stdout, "phas%03d phase %3d could use %6d inums, expected %6d inums. max ,workItem ,(inum - ssa_itemLoc(workPhase, 0)) / (double) workItem ); +#endif // record where workPhase ends ssa_phaseLen(workPhase++) = workItem; } } } +#ifdef DEBUG_SSA_BUILD_LOCALS fprintf(stdout, "tota%03d total %3d could use %6d inums, expected %6d inums. inums/phase = %g\n" ,comm->me ,workPhase @@ -317,9 +320,10 @@ fprintf(stdout, "tota%03d total %3d could use %6d inums, expected %6d inums. inu ,nlocal*4 ,inum / (double) workPhase ); +#endif nl_size = inum; // record how much space is needed for the local work plan } - // count how many ghosts are likely to have neighbors, and increase the work plan storage + // count how many ghosts might have neighbors, and increase the work plan storage for (int workPhase = 0; workPhase < ssa_gphaseCt; workPhase++) { nl_size += k_gbincount.h_view(workPhase + 1); } @@ -432,13 +436,15 @@ fprintf(stdout, "tota%03d total %3d could use %6d inums, expected %6d inums. inu list->inum = data.neigh_list.inum; //FIXME once the above is in a parallel_for list->gnum = data.neigh_list.gnum; // it will need a deep_copy or something -fprintf(stdout, "Fina%03d: %6d inum %6d gnum, total used %6d, allocated %6d\n" +#ifdef DEBUG_SSA_BUILD_LOCALS +fprintf(stdout, "Fina%03d %6d inum %6d gnum, total used %6d, allocated %6d\n" ,comm->me ,list->inum ,list->gnum ,list->inum + list->gnum ,nl_size ); +#endif list->k_ilist.template modify(); } @@ -468,6 +474,7 @@ void NPairSSAKokkosExecute::build_locals(const bool firstTry, int me continue; } int inum_start = d_ssa_itemLoc(workPhase, workItem + skippedItems); +#ifdef DEBUG_SSA_BUILD_LOCALS if (inum > inum_start) { // This shouldn't happen! fprintf(stdout, "Rank%03d workphase (%2d,%3d,%3d): inum = %4d, but ssa_itemLoc = %4d OVERFLOW\n" ,me @@ -478,7 +485,9 @@ fprintf(stdout, "Rank%03d workphase (%2d,%3d,%3d): inum = %4d, but ssa_itemLoc = ,d_ssa_itemLoc(workPhase, workItem + skippedItems) ); inum_start = inum; - } else inum = inum_start; + } else +#endif + inum = inum_start; // d_ssa_itemLoc(workPhase, workItem) = inum; // record where workItem actually starts in ilist for (int subphase = 0; subphase < 4; subphase++) { @@ -552,6 +561,7 @@ fprintf(stdout, "Rank%03d workphase (%2d,%3d,%3d): inum = %4d, but ssa_itemLoc = } } int len = inum - inum_start; +#ifdef DEBUG_SSA_BUILD_LOCALS if (len != d_ssa_itemLen(workPhase, workItem + skippedItems)) { fprintf(stdout, "Leng%03d workphase (%2d,%3d,%3d): len = %4d, but ssa_itemLen = %4d%s\n" ,me @@ -563,6 +573,7 @@ fprintf(stdout, "Leng%03d workphase (%2d,%3d,%3d): len = %4d, but ssa_itemLen = ,(len > d_ssa_itemLen(workPhase, workItem + skippedItems)) ? " OVERFLOW" : "" ); } +#endif if (inum > inum_start) { d_ssa_itemLoc(workPhase,workItem) = inum_start; // record where workItem starts in ilist d_ssa_itemLen(workPhase,workItem) = inum - inum_start; // record actual workItem length @@ -572,6 +583,7 @@ fprintf(stdout, "Leng%03d workphase (%2d,%3d,%3d): len = %4d, but ssa_itemLen = } } +#ifdef DEBUG_SSA_BUILD_LOCALS fprintf(stdout, "Phas%03d phase %3d used %6d inums, workItems = %3d, skipped = %3d, inums/workItems = %g\n" ,me ,workPhase @@ -580,6 +592,7 @@ fprintf(stdout, "Phas%03d phase %3d used %6d inums, workItems = %3d, skipped = % ,skippedItems ,(inum - d_ssa_itemLoc(workPhase, 0)) / (double) workItem ); +#endif // record where workPhase actually ends if (firstTry) { d_ssa_phaseLen(workPhase) = workItem; @@ -591,6 +604,7 @@ fprintf(stdout, "Phas%03d phase %3d used %6d inums, workItems = %3d, skipped = % } } } +#ifdef DEBUG_SSA_BUILD_LOCALS fprintf(stdout, "Totl%03d %3d could use %6d inums, expected %6d inums. inums/phase = %g\n" ,me ,workPhase @@ -598,6 +612,7 @@ fprintf(stdout, "Totl%03d %3d could use %6d inums, expected %6d inums. inums/pha ,nlocal*4 ,inum / (double) workPhase ); +#endif //FIXME if (ssa_phaseCt != workPhase) error->one(FLERR,"ssa_phaseCt was wrong"); From aedd7c57f3f78596f8b737972aed5f241ef4f7f4 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Mon, 3 Apr 2017 16:42:18 -0600 Subject: [PATCH 231/439] Reset atom map values from restart file --- src/read_restart.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/read_restart.cpp b/src/read_restart.cpp index 331a5d6cda..fcbd8d186d 100644 --- a/src/read_restart.cpp +++ b/src/read_restart.cpp @@ -905,8 +905,10 @@ void ReadRestart::header(int incompatible) atom->tag_enable = read_int(); } else if (flag == ATOM_MAP_STYLE) { atom->map_style = read_int(); + atom->map_style = 0; } else if (flag == ATOM_MAP_USER) { atom->map_user = read_int(); + atom->map_user = 0; } else if (flag == ATOM_SORTFREQ) { atom->sortfreq = read_int(); } else if (flag == ATOM_SORTBIN) { From 4d4b6f66b7139be46a9f292d7bad2403b22117f3 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Wed, 5 Apr 2017 11:42:25 -0600 Subject: [PATCH 232/439] Changing default gb/test to on --- src/KOKKOS/kokkos.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/KOKKOS/kokkos.cpp b/src/KOKKOS/kokkos.cpp index a000ad5550..10e7bda4e0 100644 --- a/src/KOKKOS/kokkos.cpp +++ b/src/KOKKOS/kokkos.cpp @@ -34,7 +34,7 @@ KokkosLMP::KokkosLMP(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp) lmp->kokkos = this; auto_sync = 1; - gb_test = 0; + gb_test = 1; int me = 0; MPI_Comm_rank(world,&me); @@ -157,7 +157,7 @@ void KokkosLMP::accelerator(int narg, char **arg) neighflag = FULL; neighflag_qeq = FULL; neighflag_qeq_set = 0; - gb_test = 0; + gb_test = 1; int newtonflag = 0; double binsize = 0.0; exchange_comm_classic = forward_comm_classic = 0; From 9e272cb393fdce5697267a2b629cd5a3a3fdc0b2 Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Thu, 6 Apr 2017 02:31:45 -0400 Subject: [PATCH 233/439] USER-DPD Kokkos: use a parallel_for() to build the locals workplan for SSA --- src/KOKKOS/npair_ssa_kokkos.cpp | 131 ++++++++++++++------------------ src/KOKKOS/npair_ssa_kokkos.h | 27 ++++++- 2 files changed, 84 insertions(+), 74 deletions(-) diff --git a/src/KOKKOS/npair_ssa_kokkos.cpp b/src/KOKKOS/npair_ssa_kokkos.cpp index 4c3218a08a..2b33256599 100644 --- a/src/KOKKOS/npair_ssa_kokkos.cpp +++ b/src/KOKKOS/npair_ssa_kokkos.cpp @@ -34,6 +34,14 @@ namespace LAMMPS_NS { template NPairSSAKokkos::NPairSSAKokkos(LAMMPS *lmp) : NPair(lmp), ssa_phaseCt(27), ssa_gphaseCt(7) { + const int gphaseLenEstimate = 1; //FIXME make this 4 eventually + k_ssa_gphaseLen = DAT::tdual_int_1d("NPairSSAKokkos:ssa_gphaseLen",ssa_gphaseCt); + ssa_gphaseLen = k_ssa_gphaseLen.view(); + + k_ssa_gitemLoc = DAT::tdual_int_2d("NPairSSAKokkos::ssa_gitemLoc",ssa_gphaseCt,gphaseLenEstimate); + ssa_gitemLoc = k_ssa_gitemLoc.view(); + k_ssa_gitemLen = DAT::tdual_int_2d("NPairSSAKokkos::ssa_gitemLen",ssa_gphaseCt,gphaseLenEstimate); + ssa_gitemLen = k_ssa_gitemLen.view(); } /* ---------------------------------------------------------------------- @@ -132,6 +140,27 @@ void NPairSSAKokkos::copy_stencil_info() sx1 = ns_ssa->sx + 1; sy1 = ns_ssa->sy + 1; sz1 = ns_ssa->sz + 1; + + // Setup the phases of the workplan for locals + ssa_phaseCt = sz1*sy1*sx1; + if (ssa_phaseCt > (int) k_ssa_phaseLen.dimension_0()) { + k_ssa_phaseLen = DAT::tdual_int_1d("NPairSSAKokkos:ssa_phaseLen",ssa_phaseCt); + ssa_phaseLen = k_ssa_phaseLen.view(); + k_ssa_phaseOff = DAT::tdual_int_1d_3("NPairSSAKokkos:ssa_phaseOff",ssa_phaseCt); + ssa_phaseOff = k_ssa_phaseOff.view(); + } + int workPhase = 0; + for (int zoff = sz1 - 1; zoff >= 0; --zoff) { + for (int yoff = sy1 - 1; yoff >= 0; --yoff) { + for (int xoff = sx1 - 1; xoff >= 0; --xoff) { + ssa_phaseOff(workPhase, 0) = xoff; + ssa_phaseOff(workPhase, 1) = yoff; + ssa_phaseOff(workPhase, 2) = zoff; + workPhase++; + } + } + } + } /* ---------------------------------------------------------------------- */ @@ -208,18 +237,11 @@ void NPairSSAKokkos::build(NeighList *list_) const int nlocal = includegroup?atom->nfirst:atom->nlocal; int nl_size; - ssa_phaseCt = sz1*sy1*sx1; + int xbinCt = (lbinxhi - lbinxlo + sx1 - 1) / sx1 + 1; + int ybinCt = (lbinyhi - lbinylo + sy1 - 1) / sy1 + 1; + int zbinCt = (lbinzhi - lbinzlo + sz1 - 1) / sz1 + 1; + int phaseLenEstimate = xbinCt*ybinCt*zbinCt; - int xbin = (lbinxhi - lbinxlo + sx1 - 1) / sx1 + 1; - int ybin = (lbinyhi - lbinylo + sy1 - 1) / sy1 + 1; - int zbin = (lbinzhi - lbinzlo + sz1 - 1) / sz1 + 1; - int phaseLenEstimate = xbin*ybin*zbin; - int gphaseLenEstimate = 1; //FIXME make this 4 eventually - - if (ssa_phaseCt > (int) k_ssa_phaseLen.dimension_0()) { - k_ssa_phaseLen = DAT::tdual_int_1d("NPairSSAKokkos:ssa_phaseLen",ssa_phaseCt); - ssa_phaseLen = k_ssa_phaseLen.view(); - } if ((ssa_phaseCt > (int) k_ssa_itemLoc.dimension_0()) || (phaseLenEstimate > (int) k_ssa_itemLoc.dimension_1())) { k_ssa_itemLoc = DAT::tdual_int_2d("NPairSSAKokkos::ssa_itemLoc",ssa_phaseCt,phaseLenEstimate); @@ -228,18 +250,6 @@ void NPairSSAKokkos::build(NeighList *list_) ssa_itemLen = k_ssa_itemLen.view(); } - if (ssa_gphaseCt > (int) k_ssa_gphaseLen.dimension_0()) { - k_ssa_gphaseLen = DAT::tdual_int_1d("NPairSSAKokkos:ssa_gphaseLen",ssa_gphaseCt); - ssa_gphaseLen = k_ssa_gphaseLen.view(); - } - if ((ssa_gphaseCt > (int) k_ssa_gitemLoc.dimension_0()) || - (gphaseLenEstimate > (int) k_ssa_gitemLoc.dimension_1())) { - k_ssa_gitemLoc = DAT::tdual_int_2d("NPairSSAKokkos::ssa_gitemLoc",ssa_gphaseCt,gphaseLenEstimate); - ssa_gitemLoc = k_ssa_gitemLoc.view(); - k_ssa_gitemLen = DAT::tdual_int_2d("NPairSSAKokkos::ssa_gitemLen",ssa_gphaseCt,gphaseLenEstimate); - ssa_gitemLen = k_ssa_gitemLen.view(); - } - { // Preflight the neighbor list workplan const typename ArrayTypes::t_int_1d_const c_bincount = k_bincount.view(); const typename ArrayTypes::t_int_2d_const c_bins = k_bins.view(); @@ -247,11 +257,11 @@ void NPairSSAKokkos::build(NeighList *list_) const typename ArrayTypes::t_int_1d_const c_nstencil_ssa = k_nstencil_ssa.view(); int inum = 0; - int workPhase = 0; - // loop over bins with local atoms, storing half of the neighbors - for (int zoff = sz1 - 1; zoff >= 0; --zoff) { - for (int yoff = sy1 - 1; yoff >= 0; --yoff) { - for (int xoff = sx1 - 1; xoff >= 0; --xoff) { + // loop over bins with local atoms, counting half of the neighbors + for (int workPhase = 0; workPhase < ssa_phaseCt; ++workPhase) { + int zoff = ssa_phaseOff(workPhase, 2); + int yoff = ssa_phaseOff(workPhase, 1); + int xoff = ssa_phaseOff(workPhase, 0); int workItem = 0; for (int zbin = lbinzlo + zoff; zbin < lbinzhi; zbin += sz1) { for (int ybin = lbinylo + yoff - sy1 + 1; ybin < lbinyhi; ybin += sy1) { @@ -308,9 +318,7 @@ fprintf(stdout, "phas%03d phase %3d could use %6d inums, expected %6d inums. max ); #endif // record where workPhase ends - ssa_phaseLen(workPhase++) = workItem; - } - } + ssa_phaseLen(workPhase) = workItem; } #ifdef DEBUG_SSA_BUILD_LOCALS fprintf(stdout, "tota%03d total %3d could use %6d inums, expected %6d inums. inums/phase = %g\n" @@ -343,6 +351,7 @@ fprintf(stdout, "tota%03d total %3d could use %6d inums, expected %6d inums. inu k_nstencil_ssa.view(), ssa_phaseCt, k_ssa_phaseLen.view(), + k_ssa_phaseOff.view(), k_ssa_itemLoc.view(), k_ssa_itemLen.view(), ssa_gphaseCt, @@ -410,7 +419,17 @@ fprintf(stdout, "tota%03d total %3d could use %6d inums, expected %6d inums. inu NPairSSAKokkosBuildFunctor f(data,atoms_per_bin*5*sizeof(X_FLOAT)); Kokkos::parallel_for(nall, f); #endif - data.build_locals(firstTry, comm->me); + // loop over bins with local atoms, storing half of the neighbors +#ifdef USE_LAMBDA_BUILD + Kokkos::parallel_for(ssa_phaseCt, LAMMPS_LAMBDA (const int workPhase) { + data.build_locals_onePhase(firstTry, comm->me, workPhase); + }); +#else + NPairSSAKokkosBuildFunctor f(data, firstTry, comm->me); + Kokkos::parallel_for(ssa_phaseCt, f); +#endif + data.neigh_list.inum = ssa_itemLoc(ssa_phaseCt-1,ssa_phaseLen(ssa_phaseCt-1)-1) + + ssa_itemLen(ssa_phaseCt-1,ssa_phaseLen(ssa_phaseCt-1)-1); data.build_ghosts(); firstTry = false; @@ -451,20 +470,16 @@ fprintf(stdout, "Fina%03d %6d inum %6d gnum, total used %6d, allocated %6d\n" template -void NPairSSAKokkosExecute::build_locals(const bool firstTry, int me) +void NPairSSAKokkosExecute::build_locals_onePhase(const bool firstTry, int me, int workPhase) const { const typename ArrayTypes::t_int_1d_const_um stencil = d_stencil; int which = 0; - int inum = 0; - int workPhase = 0; - // loop over bins with local atoms, storing half of the neighbors - for (int zoff = sz1 - 1; zoff >= 0; --zoff) { - for (int yoff = sy1 - 1; yoff >= 0; --yoff) { - for (int xoff = sx1 - 1; xoff >= 0; --xoff) { - int workItem = 0; - int skippedItems = 0; -// inum = d_ssa_itemLoc(workPhase, workItem); // get where workPhase starts in ilist + int zoff = d_ssa_phaseOff(workPhase, 2); + int yoff = d_ssa_phaseOff(workPhase, 1); + int xoff = d_ssa_phaseOff(workPhase, 0); + int workItem = 0; + int skippedItems = 0; for (int zbin = lbinzlo + zoff; zbin < lbinzhi; zbin += sz1) { for (int ybin = lbinylo + yoff - sy1 + 1; ybin < lbinyhi; ybin += sy1) { for (int xbin = lbinxlo + xoff - sx1 + 1; xbin < lbinxhi; xbin += sx1) { @@ -474,21 +489,7 @@ void NPairSSAKokkosExecute::build_locals(const bool firstTry, int me continue; } int inum_start = d_ssa_itemLoc(workPhase, workItem + skippedItems); -#ifdef DEBUG_SSA_BUILD_LOCALS - if (inum > inum_start) { // This shouldn't happen! -fprintf(stdout, "Rank%03d workphase (%2d,%3d,%3d): inum = %4d, but ssa_itemLoc = %4d OVERFLOW\n" - ,me - ,workPhase - ,workItem - ,workItem + skippedItems - ,inum - ,d_ssa_itemLoc(workPhase, workItem + skippedItems) -); - inum_start = inum; - } else -#endif - inum = inum_start; - // d_ssa_itemLoc(workPhase, workItem) = inum; // record where workItem actually starts in ilist + int inum = inum_start; for (int subphase = 0; subphase < 4; subphase++) { int s_ybin = ybin + ((subphase & 0x2) ? sy1 - 1 : 0); @@ -600,23 +601,7 @@ fprintf(stdout, "Phas%03d phase %3d used %6d inums, workItems = %3d, skipped = % d_ssa_itemLen(workPhase,workItem++) = 0; } } - ++workPhase; - } - } - } -#ifdef DEBUG_SSA_BUILD_LOCALS -fprintf(stdout, "Totl%03d %3d could use %6d inums, expected %6d inums. inums/phase = %g\n" - ,me - ,workPhase - ,inum - ,nlocal*4 - ,inum / (double) workPhase -); -#endif -//FIXME if (ssa_phaseCt != workPhase) error->one(FLERR,"ssa_phaseCt was wrong"); - - neigh_list.inum = inum; } diff --git a/src/KOKKOS/npair_ssa_kokkos.h b/src/KOKKOS/npair_ssa_kokkos.h index 2c2ae15fb8..62c4135cc7 100644 --- a/src/KOKKOS/npair_ssa_kokkos.h +++ b/src/KOKKOS/npair_ssa_kokkos.h @@ -41,9 +41,11 @@ class NPairSSAKokkos : public NPair { // SSA Work plan data structures int ssa_phaseCt; DAT::tdual_int_1d k_ssa_phaseLen; + DAT::tdual_int_1d_3 k_ssa_phaseOff; DAT::tdual_int_2d k_ssa_itemLoc; DAT::tdual_int_2d k_ssa_itemLen; typename AT::t_int_1d ssa_phaseLen; + typename AT::t_int_1d_3 ssa_phaseOff; typename AT::t_int_2d ssa_itemLoc; typename AT::t_int_2d ssa_itemLen; @@ -175,6 +177,7 @@ class NPairSSAKokkosExecute // SSA Work plan data structures int ssa_phaseCt; typename AT::t_int_1d d_ssa_phaseLen; + typename AT::t_int_1d_3_const d_ssa_phaseOff; typename AT::t_int_2d d_ssa_itemLoc; typename AT::t_int_2d d_ssa_itemLen; int ssa_gphaseCt; @@ -198,6 +201,7 @@ class NPairSSAKokkosExecute const typename AT::t_int_1d &_d_nstencil_ssa, const int _ssa_phaseCt, const typename AT::t_int_1d &_d_ssa_phaseLen, + const typename AT::t_int_1d_3 &_d_ssa_phaseOff, const typename AT::t_int_2d &_d_ssa_itemLoc, const typename AT::t_int_2d &_d_ssa_itemLen, const int _ssa_gphaseCt, @@ -242,6 +246,7 @@ class NPairSSAKokkosExecute d_stencil(_d_stencil),d_stencilxyz(_d_stencilxyz),d_nstencil_ssa(_d_nstencil_ssa), ssa_phaseCt(_ssa_phaseCt), d_ssa_phaseLen(_d_ssa_phaseLen), + d_ssa_phaseOff(_d_ssa_phaseOff), d_ssa_itemLoc(_d_ssa_itemLoc), d_ssa_itemLen(_d_ssa_itemLen), ssa_gphaseCt(_ssa_gphaseCt), @@ -289,7 +294,9 @@ class NPairSSAKokkosExecute ~NPairSSAKokkosExecute() {neigh_list.copymode = 1;}; - void build_locals(const bool firstTry, int me); + KOKKOS_FUNCTION + void build_locals_onePhase(const bool firstTry, int me, int workPhase) const; + void build_ghosts(); KOKKOS_INLINE_FUNCTION @@ -344,6 +351,24 @@ class NPairSSAKokkosExecute }; +template +struct NPairSSAKokkosBuildFunctor { + typedef DeviceType device_type; + + const NPairSSAKokkosExecute c; + const bool firstTry; + const int me; + + NPairSSAKokkosBuildFunctor(const NPairSSAKokkosExecute &_c, + const bool _firstTry, const int _me):c(_c), + firstTry(_firstTry), me(_me) {}; + + KOKKOS_INLINE_FUNCTION + void operator() (const int & i) const { + c.build_locals_onePhase(firstTry, me, i); + } +}; + } #endif From 178af2ec9e7225daff3ce853af749f6fdb6e58a9 Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Thu, 6 Apr 2017 03:53:57 -0400 Subject: [PATCH 234/439] USER-DPD Kokkos: use a parallel_for() to build the ghosts workplan for SSA --- src/KOKKOS/npair_ssa_kokkos.cpp | 47 +++++++++++++-------------------- src/KOKKOS/npair_ssa_kokkos.h | 25 +++--------------- 2 files changed, 23 insertions(+), 49 deletions(-) diff --git a/src/KOKKOS/npair_ssa_kokkos.cpp b/src/KOKKOS/npair_ssa_kokkos.cpp index 2b33256599..ba4bc9171c 100644 --- a/src/KOKKOS/npair_ssa_kokkos.cpp +++ b/src/KOKKOS/npair_ssa_kokkos.cpp @@ -333,7 +333,10 @@ fprintf(stdout, "tota%03d total %3d could use %6d inums, expected %6d inums. inu } // count how many ghosts might have neighbors, and increase the work plan storage for (int workPhase = 0; workPhase < ssa_gphaseCt; workPhase++) { - nl_size += k_gbincount.h_view(workPhase + 1); + int len = k_gbincount.h_view(workPhase + 1); + ssa_gitemLoc(workPhase,0) = nl_size; // record where workItem starts in ilist + ssa_gitemLen(workPhase,0) = len; + nl_size += len; } list->grow(nl_size); // Make special larger SSA neighbor list @@ -415,22 +418,19 @@ fprintf(stdout, "tota%03d total %3d could use %6d inums, expected %6d inums. inu Kokkos::deep_copy(data.resize, data.h_resize); Kokkos::deep_copy(data.new_maxneighs, data.h_new_maxneighs); -#ifdef NOTYET - NPairSSAKokkosBuildFunctor f(data,atoms_per_bin*5*sizeof(X_FLOAT)); - Kokkos::parallel_for(nall, f); -#endif // loop over bins with local atoms, storing half of the neighbors -#ifdef USE_LAMBDA_BUILD Kokkos::parallel_for(ssa_phaseCt, LAMMPS_LAMBDA (const int workPhase) { data.build_locals_onePhase(firstTry, comm->me, workPhase); }); -#else - NPairSSAKokkosBuildFunctor f(data, firstTry, comm->me); - Kokkos::parallel_for(ssa_phaseCt, f); -#endif data.neigh_list.inum = ssa_itemLoc(ssa_phaseCt-1,ssa_phaseLen(ssa_phaseCt-1)-1) + ssa_itemLen(ssa_phaseCt-1,ssa_phaseLen(ssa_phaseCt-1)-1); - data.build_ghosts(); + + // loop over AIR ghost atoms, storing their local neighbors + Kokkos::parallel_for(ssa_gphaseCt, LAMMPS_LAMBDA (const int workPhase) { + data.build_ghosts_onePhase(workPhase); + }); + data.neigh_list.gnum = ssa_gitemLoc(ssa_gphaseCt-1,ssa_gphaseLen(ssa_gphaseCt-1)-1) + + ssa_gitemLen(ssa_gphaseCt-1,ssa_gphaseLen(ssa_gphaseCt-1)-1) - data.neigh_list.inum; firstTry = false; DeviceType::fence(); @@ -606,34 +606,27 @@ fprintf(stdout, "Phas%03d phase %3d used %6d inums, workItems = %3d, skipped = % template -void NPairSSAKokkosExecute::build_ghosts() +void NPairSSAKokkosExecute::build_ghosts_onePhase(int workPhase) const { - int n = 0; + const typename ArrayTypes::t_int_1d_const_um stencil = d_stencil; int which = 0; - int inum = neigh_list.inum; - int gnum = 0; - // loop over AIR ghost atoms, storing their local neighbors // since these are ghosts, must check if stencil bin is out of bounds - for (int workPhase = 0; workPhase < ssa_gphaseCt; workPhase++) { int airnum = workPhase + 1; //FIXME for now, there is only 1 workItem for each ghost AIR int workItem; for (workItem = 0; workItem < 1; ++workItem) { - d_ssa_gitemLoc(workPhase, workItem) = inum + gnum; // record where workItem starts in ilist + int gNdx = d_ssa_gitemLoc(workPhase, workItem); // record where workItem starts in ilist for (int il = 0; il < c_gbincount(airnum); ++il) { const int i = c_gbins(airnum, il); - n = 0; + int n = 0; - const AtomNeighbors neighbors_i = neigh_list.get_neighbors(inum + gnum); + const AtomNeighbors neighbors_i = neigh_list.get_neighbors(gNdx); 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 typename ArrayTypes::t_int_1d_const_um stencil - = d_stencil; - int loc[3]; const int ibin = coord2bin(x(i, 0), x(i, 1), x(i, 2), &(loc[0])); @@ -686,8 +679,8 @@ void NPairSSAKokkosExecute::build_ghosts() } if (n > 0) { - neigh_list.d_numneigh(inum + gnum) = n; - neigh_list.d_ilist(inum + (gnum++)) = i; + neigh_list.d_numneigh(gNdx) = n; + neigh_list.d_ilist(gNdx++) = i; if(n > neigh_list.maxneighs) { resize() = 1; if(n > new_maxneighs()) Kokkos::atomic_fetch_max(&new_maxneighs(),n); @@ -695,12 +688,10 @@ void NPairSSAKokkosExecute::build_ghosts() } } // record where workItem ends in ilist - d_ssa_gitemLen(workPhase,workItem) = inum + gnum - d_ssa_gitemLoc(workPhase,workItem); + d_ssa_gitemLen(workPhase,workItem) = gNdx - d_ssa_gitemLoc(workPhase,workItem); // if (d_ssa_gitemLen(workPhase,workItem) > 0) workItem++; } d_ssa_gphaseLen(workPhase) = workItem; - } - neigh_list.gnum = gnum; } } diff --git a/src/KOKKOS/npair_ssa_kokkos.h b/src/KOKKOS/npair_ssa_kokkos.h index 62c4135cc7..98046feba8 100644 --- a/src/KOKKOS/npair_ssa_kokkos.h +++ b/src/KOKKOS/npair_ssa_kokkos.h @@ -275,7 +275,7 @@ class NPairSSAKokkosExecute bboxlo[0] = _bboxlo[0]; bboxlo[1] = _bboxlo[1]; bboxlo[2] = _bboxlo[2]; bboxhi[0] = _bboxhi[0]; bboxhi[1] = _bboxhi[1]; bboxhi[2] = _bboxhi[2]; - resize = typename AT::t_int_scalar("NeighborKokkosFunctor::resize"); + resize = typename AT::t_int_scalar("NPairSSAKokkosExecute::resize"); #ifndef KOKKOS_USE_CUDA_UVM h_resize = Kokkos::create_mirror_view(resize); #else @@ -283,7 +283,7 @@ class NPairSSAKokkosExecute #endif h_resize() = 1; new_maxneighs = typename AT:: - t_int_scalar("NeighborKokkosFunctor::new_maxneighs"); + t_int_scalar("NPairSSAKokkosExecute::new_maxneighs"); #ifndef KOKKOS_USE_CUDA_UVM h_new_maxneighs = Kokkos::create_mirror_view(new_maxneighs); #else @@ -297,7 +297,8 @@ class NPairSSAKokkosExecute KOKKOS_FUNCTION void build_locals_onePhase(const bool firstTry, int me, int workPhase) const; - void build_ghosts(); + KOKKOS_FUNCTION + void build_ghosts_onePhase(int workPhase) const; KOKKOS_INLINE_FUNCTION int coord2bin(const X_FLOAT & x,const X_FLOAT & y,const X_FLOAT & z, int* i) const @@ -351,24 +352,6 @@ class NPairSSAKokkosExecute }; -template -struct NPairSSAKokkosBuildFunctor { - typedef DeviceType device_type; - - const NPairSSAKokkosExecute c; - const bool firstTry; - const int me; - - NPairSSAKokkosBuildFunctor(const NPairSSAKokkosExecute &_c, - const bool _firstTry, const int _me):c(_c), - firstTry(_firstTry), me(_me) {}; - - KOKKOS_INLINE_FUNCTION - void operator() (const int & i) const { - c.build_locals_onePhase(firstTry, me, i); - } -}; - } #endif From 035d0a80d7bc8375886c3c6989a85c1bda12de67 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Mon, 10 Apr 2017 16:38:58 -0600 Subject: [PATCH 235/439] Reducing memory churn in pair_exp6_rx_kokkos --- src/KOKKOS/pair_exp6_rx_kokkos.cpp | 56 +++++++++++++++++++++--------- src/KOKKOS/pair_exp6_rx_kokkos.h | 4 +++ 2 files changed, 44 insertions(+), 16 deletions(-) diff --git a/src/KOKKOS/pair_exp6_rx_kokkos.cpp b/src/KOKKOS/pair_exp6_rx_kokkos.cpp index 5c74cba8c7..312f1c6076 100644 --- a/src/KOKKOS/pair_exp6_rx_kokkos.cpp +++ b/src/KOKKOS/pair_exp6_rx_kokkos.cpp @@ -187,22 +187,25 @@ void PairExp6rxKokkos::compute(int eflag_in, int vflag_in) { const int np_total = nlocal + atom->nghost; - PairExp6ParamData.epsilon1 = typename AT::t_float_1d("PairExp6ParamData.epsilon1" ,np_total); - PairExp6ParamData.alpha1 = typename AT::t_float_1d("PairExp6ParamData.alpha1" ,np_total); - PairExp6ParamData.rm1 = typename AT::t_float_1d("PairExp6ParamData.rm1" ,np_total); - PairExp6ParamData.mixWtSite1 = typename AT::t_float_1d("PairExp6ParamData.mixWtSite1" ,np_total); - PairExp6ParamData.epsilon2 = typename AT::t_float_1d("PairExp6ParamData.epsilon2" ,np_total); - PairExp6ParamData.alpha2 = typename AT::t_float_1d("PairExp6ParamData.alpha2" ,np_total); - PairExp6ParamData.rm2 = typename AT::t_float_1d("PairExp6ParamData.rm2" ,np_total); - PairExp6ParamData.mixWtSite2 = typename AT::t_float_1d("PairExp6ParamData.mixWtSite2" ,np_total); - PairExp6ParamData.epsilonOld1 = typename AT::t_float_1d("PairExp6ParamData.epsilonOld1" ,np_total); - PairExp6ParamData.alphaOld1 = typename AT::t_float_1d("PairExp6ParamData.alphaOld1" ,np_total); - PairExp6ParamData.rmOld1 = typename AT::t_float_1d("PairExp6ParamData.rmOld1" ,np_total); - PairExp6ParamData.mixWtSite1old = typename AT::t_float_1d("PairExp6ParamData.mixWtSite1old",np_total); - PairExp6ParamData.epsilonOld2 = typename AT::t_float_1d("PairExp6ParamData.epsilonOld2" ,np_total); - PairExp6ParamData.alphaOld2 = typename AT::t_float_1d("PairExp6ParamData.alphaOld2" ,np_total); - PairExp6ParamData.rmOld2 = typename AT::t_float_1d("PairExp6ParamData.rmOld2" ,np_total); - PairExp6ParamData.mixWtSite2old = typename AT::t_float_1d("PairExp6ParamData.mixWtSite2old",np_total); + if (np_total > PairExp6ParamData.epsilon1.dimension_0()) { + PairExp6ParamData.epsilon1 = typename AT::t_float_1d("PairExp6ParamData.epsilon1" ,np_total); + PairExp6ParamData.alpha1 = typename AT::t_float_1d("PairExp6ParamData.alpha1" ,np_total); + PairExp6ParamData.rm1 = typename AT::t_float_1d("PairExp6ParamData.rm1" ,np_total); + PairExp6ParamData.mixWtSite1 = typename AT::t_float_1d("PairExp6ParamData.mixWtSite1" ,np_total); + PairExp6ParamData.epsilon2 = typename AT::t_float_1d("PairExp6ParamData.epsilon2" ,np_total); + PairExp6ParamData.alpha2 = typename AT::t_float_1d("PairExp6ParamData.alpha2" ,np_total); + PairExp6ParamData.rm2 = typename AT::t_float_1d("PairExp6ParamData.rm2" ,np_total); + PairExp6ParamData.mixWtSite2 = typename AT::t_float_1d("PairExp6ParamData.mixWtSite2" ,np_total); + PairExp6ParamData.epsilonOld1 = typename AT::t_float_1d("PairExp6ParamData.epsilonOld1" ,np_total); + PairExp6ParamData.alphaOld1 = typename AT::t_float_1d("PairExp6ParamData.alphaOld1" ,np_total); + PairExp6ParamData.rmOld1 = typename AT::t_float_1d("PairExp6ParamData.rmOld1" ,np_total); + PairExp6ParamData.mixWtSite1old = typename AT::t_float_1d("PairExp6ParamData.mixWtSite1old",np_total); + PairExp6ParamData.epsilonOld2 = typename AT::t_float_1d("PairExp6ParamData.epsilonOld2" ,np_total); + PairExp6ParamData.alphaOld2 = typename AT::t_float_1d("PairExp6ParamData.alphaOld2" ,np_total); + PairExp6ParamData.rmOld2 = typename AT::t_float_1d("PairExp6ParamData.rmOld2" ,np_total); + PairExp6ParamData.mixWtSite2old = typename AT::t_float_1d("PairExp6ParamData.mixWtSite2old",np_total); + } else + Kokkos::parallel_for(Kokkos::RangePolicy(0,np_total),*this); #ifdef KOKKOS_HAVE_CUDA Kokkos::parallel_for(Kokkos::RangePolicy(0,np_total),*this); @@ -352,6 +355,27 @@ void PairExp6rxKokkos::compute(int eflag_in, int vflag_in) //printf("PairExp6rxKokkos::compute %f %f\n", getElapsedTime(t_start, t_stop), getElapsedTime(t_mix_start, t_mix_stop)); } +template +KOKKOS_INLINE_FUNCTION +void PairExp6rxKokkos::operator()(TagPairExp6rxZeroMixingWeights, const int &i) const { + PairExp6ParamData.epsilon1[i] = 0.0; + PairExp6ParamData.alpha1[i] = 0.0; + PairExp6ParamData.rm1[i] = 0.0; + PairExp6ParamData.mixWtSite1[i] = 0.0; + PairExp6ParamData.epsilon2[i] = 0.0; + PairExp6ParamData.alpha2[i] = 0.0; + PairExp6ParamData.rm2[i] = 0.0; + PairExp6ParamData.mixWtSite2[i] = 0.0; + PairExp6ParamData.epsilonOld1[i] = 0.0; + PairExp6ParamData.alphaOld1[i] = 0.0; + PairExp6ParamData.rmOld1[i] = 0.0; + PairExp6ParamData.mixWtSite1old[i] = 0.0; + PairExp6ParamData.epsilonOld2[i] = 0.0; + PairExp6ParamData.alphaOld2[i] = 0.0; + PairExp6ParamData.rmOld2[i] = 0.0; + PairExp6ParamData.mixWtSite2old[i] = 0.0; +} + template KOKKOS_INLINE_FUNCTION void PairExp6rxKokkos::operator()(TagPairExp6rxgetMixingWeights, const int &i) const { diff --git a/src/KOKKOS/pair_exp6_rx_kokkos.h b/src/KOKKOS/pair_exp6_rx_kokkos.h index 9f38732c32..5e9fb4e3e3 100644 --- a/src/KOKKOS/pair_exp6_rx_kokkos.h +++ b/src/KOKKOS/pair_exp6_rx_kokkos.h @@ -52,6 +52,7 @@ struct PairExp6ParamDataTypeKokkos {} }; +struct TagPairExp6rxZeroMixingWeights{}; struct TagPairExp6rxgetMixingWeights{}; template @@ -76,6 +77,9 @@ class PairExp6rxKokkos : public PairExp6rx { void coeff(int, char **); void init_style(); + KOKKOS_INLINE_FUNCTION + void operator()(TagPairExp6rxZeroMixingWeights, const int&) const; + KOKKOS_INLINE_FUNCTION void operator()(TagPairExp6rxgetMixingWeights, const int&) const; From 6c0b6918821ac738327b0aee398873546a929340 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 11 Apr 2017 09:12:46 -0600 Subject: [PATCH 236/439] Removing more memory churn in pair_exp6_rx_kokkos --- src/KOKKOS/pair_exp6_rx_kokkos.cpp | 67 ++++++++++++++++++++---------- src/KOKKOS/pair_exp6_rx_kokkos.h | 24 +++++++++++ 2 files changed, 69 insertions(+), 22 deletions(-) diff --git a/src/KOKKOS/pair_exp6_rx_kokkos.cpp b/src/KOKKOS/pair_exp6_rx_kokkos.cpp index 312f1c6076..51cf1a72e7 100644 --- a/src/KOKKOS/pair_exp6_rx_kokkos.cpp +++ b/src/KOKKOS/pair_exp6_rx_kokkos.cpp @@ -204,6 +204,29 @@ void PairExp6rxKokkos::compute(int eflag_in, int vflag_in) PairExp6ParamData.alphaOld2 = typename AT::t_float_1d("PairExp6ParamData.alphaOld2" ,np_total); PairExp6ParamData.rmOld2 = typename AT::t_float_1d("PairExp6ParamData.rmOld2" ,np_total); PairExp6ParamData.mixWtSite2old = typename AT::t_float_1d("PairExp6ParamData.mixWtSite2old",np_total); + + PairExp6ParamDataVect.epsilon = typename AT::t_float_1d("PairExp6ParamDataVect.epsilon" ,np_total);; + PairExp6ParamDataVect.rm3 = typename AT::t_float_1d("PairExp6ParamDataVect.rm3" ,np_total);; + PairExp6ParamDataVect.alpha = typename AT::t_float_1d("PairExp6ParamDataVect.alpha" ,np_total);; + PairExp6ParamDataVect.xMolei = typename AT::t_float_1d("PairExp6ParamDataVect.xMolei" ,np_total);; + PairExp6ParamDataVect.epsilon_old = typename AT::t_float_1d("PairExp6ParamDataVect.epsilon_old" ,np_total);; + PairExp6ParamDataVect.rm3_old = typename AT::t_float_1d("PairExp6ParamDataVect.rm3_old" ,np_total);; + PairExp6ParamDataVect.alpha_old = typename AT::t_float_1d("PairExp6ParamDataVect.alpha_old" ,np_total);; + PairExp6ParamDataVect.xMolei_old = typename AT::t_float_1d("PairExp6ParamDataVect.xMolei_old" ,np_total);; + PairExp6ParamDataVect.fractionOFA = typename AT::t_float_1d("PairExp6ParamDataVect.fractionOFA" ,np_total);; + PairExp6ParamDataVect.fraction1 = typename AT::t_float_1d("PairExp6ParamDataVect.fraction1" ,np_total);; + PairExp6ParamDataVect.fraction2 = typename AT::t_float_1d("PairExp6ParamDataVect.fraction2" ,np_total);; + PairExp6ParamDataVect.nMoleculesOFA = typename AT::t_float_1d("PairExp6ParamDataVect.nMoleculesOFA" ,np_total);; + PairExp6ParamDataVect.nMolecules1 = typename AT::t_float_1d("PairExp6ParamDataVect.nMolecules1" ,np_total);; + PairExp6ParamDataVect.nMolecules2 = typename AT::t_float_1d("PairExp6ParamDataVect.nMolecules2" ,np_total);; + PairExp6ParamDataVect.nTotal = typename AT::t_float_1d("PairExp6ParamDataVect.nTotal" ,np_total);; + PairExp6ParamDataVect.fractionOFAold = typename AT::t_float_1d("PairExp6ParamDataVect.fractionOFAold" ,np_total);; + PairExp6ParamDataVect.fractionOld1 = typename AT::t_float_1d("PairExp6ParamDataVect.fractionOld1" ,np_total);; + PairExp6ParamDataVect.fractionOld2 = typename AT::t_float_1d("PairExp6ParamDataVect.fractionOld2" ,np_total);; + PairExp6ParamDataVect.nMoleculesOFAold = typename AT::t_float_1d("PairExp6ParamDataVect.nMoleculesOFAold",np_total);; + PairExp6ParamDataVect.nMoleculesOld1 = typename AT::t_float_1d("PairExp6ParamDataVect.nMoleculesOld1" ,np_total);; + PairExp6ParamDataVect.nMoleculesOld2 = typename AT::t_float_1d("PairExp6ParamDataVect.nMoleculesOld2" ,np_total);; + PairExp6ParamDataVect.nTotalold = typename AT::t_float_1d("PairExp6ParamDataVect.nTotalold" ,np_total);; } else Kokkos::parallel_for(Kokkos::RangePolicy(0,np_total),*this); @@ -2094,31 +2117,31 @@ template void PairExp6rxKokkos::getMixingWeightsVect(const int np_total, int errorFlag, ArrayT &epsilon1, ArrayT &alpha1, ArrayT &rm1, ArrayT &mixWtSite1, ArrayT &epsilon2, ArrayT &alpha2, ArrayT &rm2, ArrayT &mixWtSite2, ArrayT &epsilon1_old, ArrayT &alpha1_old, ArrayT &rm1_old, ArrayT &mixWtSite1old, ArrayT &epsilon2_old, ArrayT &alpha2_old, ArrayT &rm2_old, ArrayT &mixWtSite2old) const { - ArrayT epsilon("PairExp6ParamData.epsilon", np_total); - ArrayT rm3("PairExp6ParamData.rm3", np_total); - ArrayT alpha("PairExp6ParamData.alpha", np_total); - ArrayT xMolei("PairExp6ParamData.xMolei", np_total); + ArrayT epsilon = PairExp6ParamDataVect.epsilon ; + ArrayT rm3 = PairExp6ParamDataVect.rm3 ; + ArrayT alpha = PairExp6ParamDataVect.alpha ; + ArrayT xMolei = PairExp6ParamDataVect.xMolei ; - ArrayT epsilon_old("PairExp6ParamData.epsilon_old", np_total); - ArrayT rm3_old("PairExp6ParamData.rm3_old", np_total); - ArrayT alpha_old("PairExp6ParamData.alpha_old", np_total); - ArrayT xMolei_old("PairExp6ParamData.xMolei_old", np_total); + ArrayT epsilon_old = PairExp6ParamDataVect.epsilon_old ; + ArrayT rm3_old = PairExp6ParamDataVect.rm3_old ; + ArrayT alpha_old = PairExp6ParamDataVect.alpha_old ; + ArrayT xMolei_old = PairExp6ParamDataVect.xMolei_old ; - ArrayT fractionOFA("PairExp6ParamData.fractionOFA", np_total); - ArrayT fraction1("PairExp6ParamData.fraction1", np_total); - ArrayT fraction2("PairExp6ParamData.fraction2", np_total); - ArrayT nMoleculesOFA("PairExp6ParamData.nMoleculesOFA", np_total); - ArrayT nMolecules1("PairExp6ParamData.nMolecules1", np_total); - ArrayT nMolecules2("PairExp6ParamData.nMolecules2", np_total); - ArrayT nTotal("PairExp6ParamData.nTotal", np_total); + ArrayT fractionOFA = PairExp6ParamDataVect.fractionOFA ; + ArrayT fraction1 = PairExp6ParamDataVect.fraction1 ; + ArrayT fraction2 = PairExp6ParamDataVect.fraction2 ; + ArrayT nMoleculesOFA = PairExp6ParamDataVect.nMoleculesOFA ; + ArrayT nMolecules1 = PairExp6ParamDataVect.nMolecules1 ; + ArrayT nMolecules2 = PairExp6ParamDataVect.nMolecules2 ; + ArrayT nTotal = PairExp6ParamDataVect.nTotal ; - ArrayT fractionOFAold("PairExp6ParamData.fractionOFAold", np_total); - ArrayT fractionOld1("PairExp6ParamData.fractionOld1", np_total); - ArrayT fractionOld2("PairExp6ParamData.fractionOld2", np_total); - ArrayT nMoleculesOFAold("PairExp6ParamData.nMoleculesOFAold", np_total); - ArrayT nMoleculesOld1("PairExp6ParamData.nMoleculesOld1", np_total); - ArrayT nMoleculesOld2("PairExp6ParamData.nMoleculesOld2", np_total); - ArrayT nTotalold("PairExp6ParamData.nTotalold", np_total); + ArrayT fractionOFAold = PairExp6ParamDataVect.fractionOFAold ; + ArrayT fractionOld1 = PairExp6ParamDataVect.fractionOld1 ; + ArrayT fractionOld2 = PairExp6ParamDataVect.fractionOld2 ; + ArrayT nMoleculesOFAold = PairExp6ParamDataVect.nMoleculesOFAold; + ArrayT nMoleculesOld1 = PairExp6ParamDataVect.nMoleculesOld1 ; + ArrayT nMoleculesOld2 = PairExp6ParamDataVect.nMoleculesOld2 ; + ArrayT nTotalold = PairExp6ParamDataVect.nTotalold ; int errorFlag1 = 0, errorFlag2 = 0; diff --git a/src/KOKKOS/pair_exp6_rx_kokkos.h b/src/KOKKOS/pair_exp6_rx_kokkos.h index 5e9fb4e3e3..09283662a2 100644 --- a/src/KOKKOS/pair_exp6_rx_kokkos.h +++ b/src/KOKKOS/pair_exp6_rx_kokkos.h @@ -52,6 +52,29 @@ struct PairExp6ParamDataTypeKokkos {} }; +template +struct PairExp6ParamDataTypeKokkosVect +{ + typedef ArrayTypes AT; + + typename AT::t_float_1d epsilon, rm3, alpha, xMolei, epsilon_old, rm3_old, + alpha_old, xMolei_old, fractionOFA, fraction1, + fraction2, nMoleculesOFA, nMolecules1, nMolecules2, + nTotal, fractionOFAold, fractionOld1, fractionOld2, + nMoleculesOFAold, nMoleculesOld1, nMoleculesOld2, + nTotalold; + + // Default constructor -- nullify everything. + PairExp6ParamDataTypeKokkosVect(void) + : epsilon(NULL), rm3(NULL), alpha(NULL), xMolei(NULL), epsilon_old(NULL), rm3_old(NULL), + alpha_old(NULL), xMolei_old(NULL), fractionOFA(NULL), fraction1(NULL), + fraction2(NULL), nMoleculesOFA(NULL), nMolecules1(NULL), nMolecules2(NULL), + nTotal(NULL), fractionOFAold(NULL), fractionOld1(NULL), fractionOld2(NULL), + nMoleculesOFAold(NULL), nMoleculesOld1(NULL), nMoleculesOld2(NULL), + nTotalold(NULL) + {} +}; + struct TagPairExp6rxZeroMixingWeights{}; struct TagPairExp6rxgetMixingWeights{}; @@ -148,6 +171,7 @@ class PairExp6rxKokkos : public PairExp6rx { typename AT::t_int_1d_randomread d_numneigh; PairExp6ParamDataTypeKokkos PairExp6ParamData; + PairExp6ParamDataTypeKokkosVect PairExp6ParamDataVect; void allocate(); DAT::tdual_int_1d k_mol2param; // mapping from molecule to parameters From ca4619e22791294cb7e63a0043869504350772ed Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 11 Apr 2017 09:14:21 -0600 Subject: [PATCH 237/439] Fix format issue in pair_exp6_rx_kokkos --- src/KOKKOS/pair_exp6_rx_kokkos.cpp | 44 +++++++++++++++--------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/KOKKOS/pair_exp6_rx_kokkos.cpp b/src/KOKKOS/pair_exp6_rx_kokkos.cpp index 51cf1a72e7..5b84f09fd6 100644 --- a/src/KOKKOS/pair_exp6_rx_kokkos.cpp +++ b/src/KOKKOS/pair_exp6_rx_kokkos.cpp @@ -205,28 +205,28 @@ void PairExp6rxKokkos::compute(int eflag_in, int vflag_in) PairExp6ParamData.rmOld2 = typename AT::t_float_1d("PairExp6ParamData.rmOld2" ,np_total); PairExp6ParamData.mixWtSite2old = typename AT::t_float_1d("PairExp6ParamData.mixWtSite2old",np_total); - PairExp6ParamDataVect.epsilon = typename AT::t_float_1d("PairExp6ParamDataVect.epsilon" ,np_total);; - PairExp6ParamDataVect.rm3 = typename AT::t_float_1d("PairExp6ParamDataVect.rm3" ,np_total);; - PairExp6ParamDataVect.alpha = typename AT::t_float_1d("PairExp6ParamDataVect.alpha" ,np_total);; - PairExp6ParamDataVect.xMolei = typename AT::t_float_1d("PairExp6ParamDataVect.xMolei" ,np_total);; - PairExp6ParamDataVect.epsilon_old = typename AT::t_float_1d("PairExp6ParamDataVect.epsilon_old" ,np_total);; - PairExp6ParamDataVect.rm3_old = typename AT::t_float_1d("PairExp6ParamDataVect.rm3_old" ,np_total);; - PairExp6ParamDataVect.alpha_old = typename AT::t_float_1d("PairExp6ParamDataVect.alpha_old" ,np_total);; - PairExp6ParamDataVect.xMolei_old = typename AT::t_float_1d("PairExp6ParamDataVect.xMolei_old" ,np_total);; - PairExp6ParamDataVect.fractionOFA = typename AT::t_float_1d("PairExp6ParamDataVect.fractionOFA" ,np_total);; - PairExp6ParamDataVect.fraction1 = typename AT::t_float_1d("PairExp6ParamDataVect.fraction1" ,np_total);; - PairExp6ParamDataVect.fraction2 = typename AT::t_float_1d("PairExp6ParamDataVect.fraction2" ,np_total);; - PairExp6ParamDataVect.nMoleculesOFA = typename AT::t_float_1d("PairExp6ParamDataVect.nMoleculesOFA" ,np_total);; - PairExp6ParamDataVect.nMolecules1 = typename AT::t_float_1d("PairExp6ParamDataVect.nMolecules1" ,np_total);; - PairExp6ParamDataVect.nMolecules2 = typename AT::t_float_1d("PairExp6ParamDataVect.nMolecules2" ,np_total);; - PairExp6ParamDataVect.nTotal = typename AT::t_float_1d("PairExp6ParamDataVect.nTotal" ,np_total);; - PairExp6ParamDataVect.fractionOFAold = typename AT::t_float_1d("PairExp6ParamDataVect.fractionOFAold" ,np_total);; - PairExp6ParamDataVect.fractionOld1 = typename AT::t_float_1d("PairExp6ParamDataVect.fractionOld1" ,np_total);; - PairExp6ParamDataVect.fractionOld2 = typename AT::t_float_1d("PairExp6ParamDataVect.fractionOld2" ,np_total);; - PairExp6ParamDataVect.nMoleculesOFAold = typename AT::t_float_1d("PairExp6ParamDataVect.nMoleculesOFAold",np_total);; - PairExp6ParamDataVect.nMoleculesOld1 = typename AT::t_float_1d("PairExp6ParamDataVect.nMoleculesOld1" ,np_total);; - PairExp6ParamDataVect.nMoleculesOld2 = typename AT::t_float_1d("PairExp6ParamDataVect.nMoleculesOld2" ,np_total);; - PairExp6ParamDataVect.nTotalold = typename AT::t_float_1d("PairExp6ParamDataVect.nTotalold" ,np_total);; + PairExp6ParamDataVect.epsilon = typename AT::t_float_1d("PairExp6ParamDataVect.epsilon" ,np_total); + PairExp6ParamDataVect.rm3 = typename AT::t_float_1d("PairExp6ParamDataVect.rm3" ,np_total); + PairExp6ParamDataVect.alpha = typename AT::t_float_1d("PairExp6ParamDataVect.alpha" ,np_total); + PairExp6ParamDataVect.xMolei = typename AT::t_float_1d("PairExp6ParamDataVect.xMolei" ,np_total); + PairExp6ParamDataVect.epsilon_old = typename AT::t_float_1d("PairExp6ParamDataVect.epsilon_old" ,np_total); + PairExp6ParamDataVect.rm3_old = typename AT::t_float_1d("PairExp6ParamDataVect.rm3_old" ,np_total); + PairExp6ParamDataVect.alpha_old = typename AT::t_float_1d("PairExp6ParamDataVect.alpha_old" ,np_total); + PairExp6ParamDataVect.xMolei_old = typename AT::t_float_1d("PairExp6ParamDataVect.xMolei_old" ,np_total); + PairExp6ParamDataVect.fractionOFA = typename AT::t_float_1d("PairExp6ParamDataVect.fractionOFA" ,np_total); + PairExp6ParamDataVect.fraction1 = typename AT::t_float_1d("PairExp6ParamDataVect.fraction1" ,np_total); + PairExp6ParamDataVect.fraction2 = typename AT::t_float_1d("PairExp6ParamDataVect.fraction2" ,np_total); + PairExp6ParamDataVect.nMoleculesOFA = typename AT::t_float_1d("PairExp6ParamDataVect.nMoleculesOFA" ,np_total); + PairExp6ParamDataVect.nMolecules1 = typename AT::t_float_1d("PairExp6ParamDataVect.nMolecules1" ,np_total); + PairExp6ParamDataVect.nMolecules2 = typename AT::t_float_1d("PairExp6ParamDataVect.nMolecules2" ,np_total); + PairExp6ParamDataVect.nTotal = typename AT::t_float_1d("PairExp6ParamDataVect.nTotal" ,np_total); + PairExp6ParamDataVect.fractionOFAold = typename AT::t_float_1d("PairExp6ParamDataVect.fractionOFAold" ,np_total); + PairExp6ParamDataVect.fractionOld1 = typename AT::t_float_1d("PairExp6ParamDataVect.fractionOld1" ,np_total); + PairExp6ParamDataVect.fractionOld2 = typename AT::t_float_1d("PairExp6ParamDataVect.fractionOld2" ,np_total); + PairExp6ParamDataVect.nMoleculesOFAold = typename AT::t_float_1d("PairExp6ParamDataVect.nMoleculesOFAold",np_total); + PairExp6ParamDataVect.nMoleculesOld1 = typename AT::t_float_1d("PairExp6ParamDataVect.nMoleculesOld1" ,np_total); + PairExp6ParamDataVect.nMoleculesOld2 = typename AT::t_float_1d("PairExp6ParamDataVect.nMoleculesOld2" ,np_total); + PairExp6ParamDataVect.nTotalold = typename AT::t_float_1d("PairExp6ParamDataVect.nTotalold" ,np_total); } else Kokkos::parallel_for(Kokkos::RangePolicy(0,np_total),*this); From 36cbe439780dc8b44ecbb25036327853033aab68 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 6 Jun 2017 10:51:26 -0600 Subject: [PATCH 238/439] Fixing some CUDA runtime issues in npair_ssa_kokkos --- src/KOKKOS/npair_ssa_kokkos.cpp | 100 +++++++++++++++++++++++--------- 1 file changed, 74 insertions(+), 26 deletions(-) diff --git a/src/KOKKOS/npair_ssa_kokkos.cpp b/src/KOKKOS/npair_ssa_kokkos.cpp index ba4bc9171c..0c3a5985ff 100644 --- a/src/KOKKOS/npair_ssa_kokkos.cpp +++ b/src/KOKKOS/npair_ssa_kokkos.cpp @@ -149,17 +149,21 @@ void NPairSSAKokkos::copy_stencil_info() k_ssa_phaseOff = DAT::tdual_int_1d_3("NPairSSAKokkos:ssa_phaseOff",ssa_phaseCt); ssa_phaseOff = k_ssa_phaseOff.view(); } + auto h_ssa_phaseOff = k_ssa_phaseOff.h_view; + k_ssa_phaseOff.sync(); int workPhase = 0; for (int zoff = sz1 - 1; zoff >= 0; --zoff) { for (int yoff = sy1 - 1; yoff >= 0; --yoff) { for (int xoff = sx1 - 1; xoff >= 0; --xoff) { - ssa_phaseOff(workPhase, 0) = xoff; - ssa_phaseOff(workPhase, 1) = yoff; - ssa_phaseOff(workPhase, 2) = zoff; + h_ssa_phaseOff(workPhase, 0) = xoff; + h_ssa_phaseOff(workPhase, 1) = yoff; + h_ssa_phaseOff(workPhase, 2) = zoff; workPhase++; } } } + k_ssa_phaseOff.modify(); + k_ssa_phaseOff.sync(); } @@ -250,8 +254,25 @@ void NPairSSAKokkos::build(NeighList *list_) ssa_itemLen = k_ssa_itemLen.view(); } + k_ssa_itemLoc.sync(); + k_ssa_itemLen.sync(); + k_ssa_gitemLoc.sync(); + k_ssa_gitemLen.sync(); + k_ssa_phaseOff.sync(); + k_ssa_phaseLen.sync(); + k_ssa_gphaseLen.sync(); + auto h_ssa_itemLoc = k_ssa_itemLoc.h_view; + auto h_ssa_itemLen = k_ssa_itemLen.h_view; + auto h_ssa_gitemLoc = k_ssa_gitemLoc.h_view; + auto h_ssa_gitemLen = k_ssa_gitemLen.h_view; + auto h_ssa_phaseOff = k_ssa_phaseOff.h_view; + auto h_ssa_phaseLen = k_ssa_phaseLen.h_view; + auto h_ssa_gphaseLen = k_ssa_gphaseLen.h_view; + { // Preflight the neighbor list workplan const typename ArrayTypes::t_int_1d_const c_bincount = k_bincount.view(); + k_bincount.sync(); + auto h_bincount = k_bincount.h_view; const typename ArrayTypes::t_int_2d_const c_bins = k_bins.view(); const typename ArrayTypes::t_int_1d_const_um c_stencil = k_stencil.view(); const typename ArrayTypes::t_int_1d_const c_nstencil_ssa = k_nstencil_ssa.view(); @@ -259,9 +280,9 @@ void NPairSSAKokkos::build(NeighList *list_) // loop over bins with local atoms, counting half of the neighbors for (int workPhase = 0; workPhase < ssa_phaseCt; ++workPhase) { - int zoff = ssa_phaseOff(workPhase, 2); - int yoff = ssa_phaseOff(workPhase, 1); - int xoff = ssa_phaseOff(workPhase, 0); + int zoff = h_ssa_phaseOff(workPhase, 2); + int yoff = h_ssa_phaseOff(workPhase, 1); + int xoff = h_ssa_phaseOff(workPhase, 0); int workItem = 0; for (int zbin = lbinzlo + zoff; zbin < lbinzhi; zbin += sz1) { for (int ybin = lbinylo + yoff - sy1 + 1; ybin < lbinyhi; ybin += sy1) { @@ -276,14 +297,14 @@ void NPairSSAKokkos::build(NeighList *list_) if ((s_xbin < lbinxlo) || (s_xbin >= lbinxhi)) continue; const int ibin = zbin*mbiny*mbinx + s_ybin*mbinx + s_xbin; - const int ibinCt = c_bincount(ibin); + const int ibinCt = h_bincount(ibin); if (ibinCt > 0) { int base_n = 0; bool include_same = false; // count all local atoms in the current stencil "subphase" as potential neighbors for (int k = c_nstencil_ssa(subphase); k < c_nstencil_ssa(subphase+1); k++) { const int jbin = ibin+c_stencil(k); - if (jbin != ibin) base_n += c_bincount(jbin); + if (jbin != ibin) base_n += h_bincount(jbin); else include_same = true; } // Calculate how many ibin particles would have had some neighbors @@ -291,10 +312,10 @@ void NPairSSAKokkos::build(NeighList *list_) else if (include_same) inum += ibinCt - 1; } } - ssa_itemLoc(workPhase,workItem) = inum_start; // record where workItem starts in ilist - ssa_itemLen(workPhase,workItem) = inum - inum_start; // record workItem length + h_ssa_itemLoc(workPhase,workItem) = inum_start; // record where workItem starts in ilist + h_ssa_itemLen(workPhase,workItem) = inum - inum_start; // record workItem length #ifdef DEBUG_SSA_BUILD_LOCALS -if (ssa_itemLen(workPhase,workItem) < 0) fprintf(stdout, "undr%03d phase (%3d,%3d) inum %d - inum_start %d UNDERFLOW\n" +if (h_ssa_itemLen(workPhase,workItem) < 0) fprintf(stdout, "undr%03d phase (%3d,%3d) inum %d - inum_start %d UNDERFLOW\n" ,comm->me ,workPhase ,workItem @@ -311,14 +332,14 @@ if (ssa_itemLen(workPhase,workItem) < 0) fprintf(stdout, "undr%03d phase (%3d,%3 fprintf(stdout, "phas%03d phase %3d could use %6d inums, expected %6d inums. maxworkItems = %3d, inums/workItems = %g\n" ,comm->me ,workPhase - ,inum - ssa_itemLoc(workPhase, 0) + ,inum - h_ssa_itemLoc(workPhase, 0) ,(nlocal*4 + ssa_phaseCt - 1) / ssa_phaseCt ,workItem - ,(inum - ssa_itemLoc(workPhase, 0)) / (double) workItem + ,(inum - h_ssa_itemLoc(workPhase, 0)) / (double) workItem ); #endif // record where workPhase ends - ssa_phaseLen(workPhase) = workItem; + h_ssa_phaseLen(workPhase) = workItem; } #ifdef DEBUG_SSA_BUILD_LOCALS fprintf(stdout, "tota%03d total %3d could use %6d inums, expected %6d inums. inums/phase = %g\n" @@ -331,15 +352,30 @@ fprintf(stdout, "tota%03d total %3d could use %6d inums, expected %6d inums. inu #endif nl_size = inum; // record how much space is needed for the local work plan } + // count how many ghosts might have neighbors, and increase the work plan storage for (int workPhase = 0; workPhase < ssa_gphaseCt; workPhase++) { int len = k_gbincount.h_view(workPhase + 1); - ssa_gitemLoc(workPhase,0) = nl_size; // record where workItem starts in ilist - ssa_gitemLen(workPhase,0) = len; + h_ssa_gitemLoc(workPhase,0) = nl_size; // record where workItem starts in ilist + h_ssa_gitemLen(workPhase,0) = len; nl_size += len; } list->grow(nl_size); // Make special larger SSA neighbor list + k_ssa_itemLoc.modify(); + k_ssa_itemLen.modify(); + k_ssa_gitemLoc.modify(); + k_ssa_gitemLen.modify(); + k_ssa_phaseOff.modify(); + k_ssa_phaseLen.modify(); + k_ssa_itemLoc.sync(); + k_ssa_itemLen.sync(); + k_ssa_gitemLen.sync(); + k_ssa_gitemLoc.sync(); + k_ssa_phaseOff.sync(); + k_ssa_phaseLen.sync(); + k_ssa_gphaseLen.sync(); + NPairSSAKokkosExecute data(*list, k_cutneighsq.view(), @@ -422,15 +458,27 @@ fprintf(stdout, "tota%03d total %3d could use %6d inums, expected %6d inums. inu Kokkos::parallel_for(ssa_phaseCt, LAMMPS_LAMBDA (const int workPhase) { data.build_locals_onePhase(firstTry, comm->me, workPhase); }); - data.neigh_list.inum = ssa_itemLoc(ssa_phaseCt-1,ssa_phaseLen(ssa_phaseCt-1)-1) + - ssa_itemLen(ssa_phaseCt-1,ssa_phaseLen(ssa_phaseCt-1)-1); + k_ssa_itemLoc.modify(); + k_ssa_itemLen.modify(); + k_ssa_phaseLen.modify(); + k_ssa_itemLoc.sync(); + k_ssa_itemLen.sync(); + k_ssa_phaseLen.sync(); + data.neigh_list.inum = h_ssa_itemLoc(ssa_phaseCt-1,h_ssa_phaseLen(ssa_phaseCt-1)-1) + + h_ssa_itemLen(ssa_phaseCt-1,h_ssa_phaseLen(ssa_phaseCt-1)-1); // loop over AIR ghost atoms, storing their local neighbors Kokkos::parallel_for(ssa_gphaseCt, LAMMPS_LAMBDA (const int workPhase) { data.build_ghosts_onePhase(workPhase); }); - data.neigh_list.gnum = ssa_gitemLoc(ssa_gphaseCt-1,ssa_gphaseLen(ssa_gphaseCt-1)-1) + - ssa_gitemLen(ssa_gphaseCt-1,ssa_gphaseLen(ssa_gphaseCt-1)-1) - data.neigh_list.inum; + k_ssa_gitemLoc.modify(); + k_ssa_gitemLen.modify(); + k_ssa_gphaseLen.modify(); + k_ssa_gitemLoc.sync(); + k_ssa_gitemLen.sync(); + k_ssa_gphaseLen.sync(); + data.neigh_list.gnum = h_ssa_gitemLoc(ssa_gphaseCt-1,h_ssa_gphaseLen(ssa_gphaseCt-1)-1) + + h_ssa_gitemLen(ssa_gphaseCt-1,h_ssa_gphaseLen(ssa_gphaseCt-1)-1) - data.neigh_list.inum; firstTry = false; DeviceType::fence(); @@ -445,12 +493,12 @@ fprintf(stdout, "tota%03d total %3d could use %6d inums, expected %6d inums. inu } } - k_ssa_phaseLen.modify(); - k_ssa_itemLoc.modify(); - k_ssa_itemLen.modify(); - k_ssa_gphaseLen.modify(); - k_ssa_gitemLoc.modify(); - k_ssa_gitemLen.modify(); + //k_ssa_phaseLen.modify(); + //k_ssa_itemLoc.modify(); + //k_ssa_itemLen.modify(); + //k_ssa_gphaseLen.modify(); + //k_ssa_gitemLoc.modify(); + //k_ssa_gitemLen.modify(); list->inum = data.neigh_list.inum; //FIXME once the above is in a parallel_for list->gnum = data.neigh_list.gnum; // it will need a deep_copy or something From efe60bf991c69d0cdd0e1f960f060c53abb62457 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 6 Jun 2017 13:10:04 -0600 Subject: [PATCH 239/439] Fixing more CUDA runtime issues --- src/KOKKOS/nbin_ssa_kokkos.cpp | 2 ++ src/KOKKOS/npair_ssa_kokkos.cpp | 8 ++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/KOKKOS/nbin_ssa_kokkos.cpp b/src/KOKKOS/nbin_ssa_kokkos.cpp index 6c9e3a3446..f11d7e18ef 100644 --- a/src/KOKKOS/nbin_ssa_kokkos.cpp +++ b/src/KOKKOS/nbin_ssa_kokkos.cpp @@ -212,6 +212,8 @@ void NBinSSAKokkos::bin_atoms() }); DeviceType::fence(); } + k_bins.modify(); + k_bincount.modify(); c_bins = bins; // bins won't change until the next bin_atoms //now dispose of the k_binID array diff --git a/src/KOKKOS/npair_ssa_kokkos.cpp b/src/KOKKOS/npair_ssa_kokkos.cpp index 0c3a5985ff..368fb1a6ed 100644 --- a/src/KOKKOS/npair_ssa_kokkos.cpp +++ b/src/KOKKOS/npair_ssa_kokkos.cpp @@ -275,7 +275,11 @@ void NPairSSAKokkos::build(NeighList *list_) auto h_bincount = k_bincount.h_view; const typename ArrayTypes::t_int_2d_const c_bins = k_bins.view(); const typename ArrayTypes::t_int_1d_const_um c_stencil = k_stencil.view(); + k_stencil.sync(); + auto h_stencil = k_stencil.h_view; const typename ArrayTypes::t_int_1d_const c_nstencil_ssa = k_nstencil_ssa.view(); + k_nstencil_ssa.sync(); + auto h_nstencil_ssa = k_nstencil_ssa.h_view; int inum = 0; // loop over bins with local atoms, counting half of the neighbors @@ -302,8 +306,8 @@ void NPairSSAKokkos::build(NeighList *list_) int base_n = 0; bool include_same = false; // count all local atoms in the current stencil "subphase" as potential neighbors - for (int k = c_nstencil_ssa(subphase); k < c_nstencil_ssa(subphase+1); k++) { - const int jbin = ibin+c_stencil(k); + for (int k = h_nstencil_ssa(subphase); k < h_nstencil_ssa(subphase+1); k++) { + const int jbin = ibin+h_stencil(k); if (jbin != ibin) base_n += h_bincount(jbin); else include_same = true; } From 520ab26bd966b5fda778b5e30f4cbdeb95d8e842 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Wed, 7 Jun 2017 15:07:53 -0600 Subject: [PATCH 240/439] Fixing more CUDA runtime issues --- src/KOKKOS/nbin_ssa_kokkos.cpp | 3 +++ src/KOKKOS/npair_ssa_kokkos.cpp | 9 ++------- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/KOKKOS/nbin_ssa_kokkos.cpp b/src/KOKKOS/nbin_ssa_kokkos.cpp index f11d7e18ef..883ba25b24 100644 --- a/src/KOKKOS/nbin_ssa_kokkos.cpp +++ b/src/KOKKOS/nbin_ssa_kokkos.cpp @@ -216,6 +216,9 @@ void NBinSSAKokkos::bin_atoms() k_bincount.modify(); c_bins = bins; // bins won't change until the next bin_atoms + k_gbins.modify(); + k_gbincount.modify(); + //now dispose of the k_binID array k_binID = DAT::tdual_int_1d("NBinSSAKokkos::binID",0); binID = k_binID.view(); diff --git a/src/KOKKOS/npair_ssa_kokkos.cpp b/src/KOKKOS/npair_ssa_kokkos.cpp index 368fb1a6ed..aec482993d 100644 --- a/src/KOKKOS/npair_ssa_kokkos.cpp +++ b/src/KOKKOS/npair_ssa_kokkos.cpp @@ -260,24 +260,18 @@ void NPairSSAKokkos::build(NeighList *list_) k_ssa_gitemLen.sync(); k_ssa_phaseOff.sync(); k_ssa_phaseLen.sync(); - k_ssa_gphaseLen.sync(); auto h_ssa_itemLoc = k_ssa_itemLoc.h_view; auto h_ssa_itemLen = k_ssa_itemLen.h_view; auto h_ssa_gitemLoc = k_ssa_gitemLoc.h_view; auto h_ssa_gitemLen = k_ssa_gitemLen.h_view; auto h_ssa_phaseOff = k_ssa_phaseOff.h_view; auto h_ssa_phaseLen = k_ssa_phaseLen.h_view; - auto h_ssa_gphaseLen = k_ssa_gphaseLen.h_view; { // Preflight the neighbor list workplan - const typename ArrayTypes::t_int_1d_const c_bincount = k_bincount.view(); k_bincount.sync(); auto h_bincount = k_bincount.h_view; - const typename ArrayTypes::t_int_2d_const c_bins = k_bins.view(); - const typename ArrayTypes::t_int_1d_const_um c_stencil = k_stencil.view(); k_stencil.sync(); auto h_stencil = k_stencil.h_view; - const typename ArrayTypes::t_int_1d_const c_nstencil_ssa = k_nstencil_ssa.view(); k_nstencil_ssa.sync(); auto h_nstencil_ssa = k_nstencil_ssa.h_view; int inum = 0; @@ -358,6 +352,7 @@ fprintf(stdout, "tota%03d total %3d could use %6d inums, expected %6d inums. inu } // count how many ghosts might have neighbors, and increase the work plan storage + k_gbincount.sync(); for (int workPhase = 0; workPhase < ssa_gphaseCt; workPhase++) { int len = k_gbincount.h_view(workPhase + 1); h_ssa_gitemLoc(workPhase,0) = nl_size; // record where workItem starts in ilist @@ -370,7 +365,6 @@ fprintf(stdout, "tota%03d total %3d could use %6d inums, expected %6d inums. inu k_ssa_itemLen.modify(); k_ssa_gitemLoc.modify(); k_ssa_gitemLen.modify(); - k_ssa_phaseOff.modify(); k_ssa_phaseLen.modify(); k_ssa_itemLoc.sync(); k_ssa_itemLen.sync(); @@ -481,6 +475,7 @@ fprintf(stdout, "tota%03d total %3d could use %6d inums, expected %6d inums. inu k_ssa_gitemLoc.sync(); k_ssa_gitemLen.sync(); k_ssa_gphaseLen.sync(); + auto h_ssa_gphaseLen = k_ssa_gphaseLen.h_view; data.neigh_list.gnum = h_ssa_gitemLoc(ssa_gphaseCt-1,h_ssa_gphaseLen(ssa_gphaseCt-1)-1) + h_ssa_gitemLen(ssa_gphaseCt-1,h_ssa_gphaseLen(ssa_gphaseCt-1)-1) - data.neigh_list.inum; firstTry = false; From 611bb6f130355d88c1b89e710cf963b629b2a443 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Thu, 8 Jun 2017 09:31:51 -0600 Subject: [PATCH 241/439] Reduce memory churn in pair_table_rx_kokkos --- src/KOKKOS/pair_table_rx_kokkos.cpp | 26 ++++++++++++++------------ src/KOKKOS/pair_table_rx_kokkos.h | 5 +++++ 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/src/KOKKOS/pair_table_rx_kokkos.cpp b/src/KOKKOS/pair_table_rx_kokkos.cpp index eacaf83cf5..2f5a670537 100644 --- a/src/KOKKOS/pair_table_rx_kokkos.cpp +++ b/src/KOKKOS/pair_table_rx_kokkos.cpp @@ -534,10 +534,10 @@ static void compute_all_items( typename ArrayTypes::t_int_1d_const d_numneigh, typename ArrayTypes::t_x_array_randomread x, typename ArrayTypes::t_int_1d_randomread type, - Kokkos::View mixWtSite1old, - Kokkos::View mixWtSite2old, - Kokkos::View mixWtSite1, - Kokkos::View mixWtSite2, + Kokkos::View const& mixWtSite1old, + Kokkos::View const& mixWtSite2old, + Kokkos::View const& mixWtSite1, + Kokkos::View const& mixWtSite2, Few special_lj, Few, MAX_TYPES_STACKPARAMS+1> m_cutsq, typename ArrayTypes::t_ffloat_2d d_cutsq, @@ -597,10 +597,10 @@ static void getAllMixingWeights( int nspecies, int isite1, int isite2, bool fractionalWeighting, - Kokkos::View mixWtSite1old, - Kokkos::View mixWtSite2old, - Kokkos::View mixWtSite1, - Kokkos::View mixWtSite2) { + Kokkos::View const& mixWtSite1old, + Kokkos::View const& mixWtSite2old, + Kokkos::View const& mixWtSite1, + Kokkos::View const& mixWtSite2) { Kokkos::parallel_for(ntotal, LAMMPS_LAMBDA(int i) { getMixingWeights(dvector,nspecies,isite1,isite2,fractionalWeighting, @@ -651,10 +651,12 @@ void PairTableRXKokkos::compute_style(int eflag_in, int vflag_in) // loop over neighbors of my atoms const int ntotal = atom->nlocal + atom->nghost; - auto mixWtSite1old = Kokkos::View("PairTableRXKokkos::mixWtSite1old", ntotal); - auto mixWtSite2old = Kokkos::View("PairTableRXKokkos::mixWtSite2old", ntotal); - auto mixWtSite1 = Kokkos::View("PairTableRXKokkos::mixWtSite1", ntotal); - auto mixWtSite2 = Kokkos::View("PairTableRXKokkos::mixWtSite2", ntotal); + if (ntotal > mixWtSite1.dimension_0()) { + mixWtSite1old = Kokkos::View("PairTableRXKokkos::mixWtSite1old", ntotal); + mixWtSite2old = Kokkos::View("PairTableRXKokkos::mixWtSite2old", ntotal); + mixWtSite1 = Kokkos::View("PairTableRXKokkos::mixWtSite1", ntotal); + mixWtSite2 = Kokkos::View("PairTableRXKokkos::mixWtSite2", ntotal); + } getAllMixingWeights(ntotal, atomKK->k_dvector.template view(), nspecies, isite1, isite2, fractionalWeighting, diff --git a/src/KOKKOS/pair_table_rx_kokkos.h b/src/KOKKOS/pair_table_rx_kokkos.h index 54c114a433..4230263dc9 100644 --- a/src/KOKKOS/pair_table_rx_kokkos.h +++ b/src/KOKKOS/pair_table_rx_kokkos.h @@ -96,6 +96,11 @@ class PairTableRXKokkos : public PairTable { /* PairTableRX members */ + Kokkos::View mixWtSite1old; + Kokkos::View mixWtSite2old; + Kokkos::View mixWtSite1; + Kokkos::View mixWtSite2; + int nspecies; char *site1, *site2; int isite1, isite2; From 6f24c58c1a31d6f7fe8cac237e22b21c8a159660 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Thu, 8 Jun 2017 09:52:00 -0600 Subject: [PATCH 242/439] Reduce memory churn in fix_rx_kokkos --- src/KOKKOS/fix_rx_kokkos.cpp | 52 ++++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/src/KOKKOS/fix_rx_kokkos.cpp b/src/KOKKOS/fix_rx_kokkos.cpp index d994b2c5d1..92db54d234 100644 --- a/src/KOKKOS/fix_rx_kokkos.cpp +++ b/src/KOKKOS/fix_rx_kokkos.cpp @@ -79,6 +79,17 @@ FixRxKokkos::~FixRxKokkos() { //printf("Inside FixRxKokkos::~FixRxKokkos copymode= %d\n", copymode); if (copymode) return; + + if (localTempFlag) + memory->destroy_kokkos(k_dpdThetaLocal, dpdThetaLocal); + + memory->destroy_kokkos(k_sumWeights, sumWeights); + //memory->destroy_kokkos(k_sumWeights); + + //delete [] scratchSpace; + memory->destroy_kokkos(d_scratchSpace); + + memory->destroy_kokkos(k_cutsq); } /* ---------------------------------------------------------------------- */ @@ -1433,9 +1444,12 @@ void FixRxKokkos::solve_reactions(const int vflag, const bool isPreF { const int count = nlocal + (newton_pair ? nghost : 0); - memory->create_kokkos (k_dpdThetaLocal, dpdThetaLocal, count, "FixRxKokkos::dpdThetaLocal"); - this->d_dpdThetaLocal = k_dpdThetaLocal.d_view; - this->h_dpdThetaLocal = k_dpdThetaLocal.h_view; + if (count > k_dpdThetaLocal.d_view.dimension_0()) { + memory->destroy_kokkos (k_dpdThetaLocal, dpdThetaLocal); + memory->create_kokkos (k_dpdThetaLocal, dpdThetaLocal, count, "FixRxKokkos::dpdThetaLocal"); + this->d_dpdThetaLocal = k_dpdThetaLocal.d_view; + this->h_dpdThetaLocal = k_dpdThetaLocal.h_view; + } const int neighflag = lmp->kokkos->neighflag; @@ -1527,7 +1541,10 @@ void FixRxKokkos::solve_reactions(const int vflag, const bool isPreF //double *scratchSpace = new double[ scratchSpaceSize * nlocal ]; //typename ArrayTypes::t_double_1d d_scratchSpace("d_scratchSpace", scratchSpaceSize * nlocal); - memory->create_kokkos (d_scratchSpace, nlocal*scratchSpaceSize, "FixRxKokkos::d_scratchSpace"); + if (nlocal*scratchSpaceSize > d_scratchSpace.dimension_0()) { + memory->destroy_kokkos (d_scratchSpace); + memory->create_kokkos (d_scratchSpace, nlocal*scratchSpaceSize, "FixRxKokkos::d_scratchSpace"); + } #if 0 Kokkos::parallel_reduce( nlocal, LAMMPS_LAMBDA(int i, CounterType &counter) @@ -1630,9 +1647,6 @@ void FixRxKokkos::solve_reactions(const int vflag, const bool isPreF Kokkos::parallel_reduce( Kokkos::RangePolicy >(0,nlocal), *this, TotalCounters); #endif - //delete [] scratchSpace; - memory->destroy_kokkos (d_scratchSpace); - TimerType timer_ODE = getTimeStamp(); // Check the error flag for any failures. @@ -1651,9 +1665,6 @@ void FixRxKokkos::solve_reactions(const int vflag, const bool isPreF atomKK->modified ( Host, DVECTOR_MASK ); - if (localTempFlag) - memory->destroy_kokkos(k_dpdThetaLocal, dpdThetaLocal); - TimerType timer_stop = getTimeStamp(); double time_ODE = getElapsedTime(timer_localTemperature, timer_ODE); @@ -2012,8 +2023,11 @@ void FixRxKokkos::computeLocalTemperature() const int ntypes = atom->ntypes; //memory->create_kokkos (k_cutsq, h_cutsq, ntypes+1, ntypes+1, "pair:cutsq"); - memory->create_kokkos (k_cutsq, ntypes+1, ntypes+1, "FixRxKokkos::k_cutsq"); - d_cutsq = k_cutsq.template view(); + if (ntypes+1 > k_cutsq.dimension_0()) { + memory->destroy_kokkos (k_cutsq); + memory->create_kokkos (k_cutsq, ntypes+1, ntypes+1, "FixRxKokkos::k_cutsq"); + d_cutsq = k_cutsq.template view(); + } for (int i = 1; i <= ntypes; ++i) for (int j = i; j <= ntypes; ++j) @@ -2030,9 +2044,12 @@ void FixRxKokkos::computeLocalTemperature() int sumWeightsCt = nlocal + (NEWTON_PAIR ? nghost : 0); //memory->create_kokkos (k_sumWeights, sumWeights, sumWeightsCt, "FixRxKokkos::sumWeights"); - memory->create_kokkos (k_sumWeights, sumWeightsCt, "FixRxKokkos::sumWeights"); - d_sumWeights = k_sumWeights.d_view; - h_sumWeights = k_sumWeights.h_view; + if (sumWeightsCt > k_sumWeights.d_view.dimension_0()) { + memory->destroy_kokkos(k_sumWeights, sumWeights); + memory->create_kokkos (k_sumWeights, sumWeightsCt, "FixRxKokkos::sumWeights"); + d_sumWeights = k_sumWeights.d_view; + h_sumWeights = k_sumWeights.h_view; + } // Initialize the accumulator to zero ... //Kokkos::parallel_for (sumWeightsCt, @@ -2165,11 +2182,6 @@ void FixRxKokkos::computeLocalTemperature() Kokkos::parallel_for (Kokkos::RangePolicy >(0, nlocal), *this); #endif - // Clean up the local kokkos data. - //memory->destroy_kokkos(k_cutsq, h_cutsq); - memory->destroy_kokkos(k_cutsq); - //memory->destroy_kokkos(k_sumWeights, sumWeights); - memory->destroy_kokkos(k_sumWeights); } /* ---------------------------------------------------------------------- */ From 43cfa10ea48df7323ce4c15996aacddcb66b2228 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Thu, 8 Jun 2017 09:58:10 -0600 Subject: [PATCH 243/439] Reduce memory churn in pair_multi_lucy_rx_kokkos --- src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp b/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp index ef30fdc6f6..f7e1bad056 100644 --- a/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp +++ b/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp @@ -180,10 +180,12 @@ void PairMultiLucyRXKokkos::compute_style(int eflag_in, int vflag_in { const int ntotal = nlocal + nghost; - d_mixWtSite1old = typename AT::t_float_1d("PairMultiLucyRX::mixWtSite1old",ntotal); - d_mixWtSite2old = typename AT::t_float_1d("PairMultiLucyRX::mixWtSite2old",ntotal); - d_mixWtSite1 = typename AT::t_float_1d("PairMultiLucyRX::mixWtSite1",ntotal); - d_mixWtSite2 = typename AT::t_float_1d("PairMultiLucyRX::mixWtSite2",ntotal); + if (ntotal > d_mixWtSite1.dimension_0()) { + d_mixWtSite1old = typename AT::t_float_1d("PairMultiLucyRX::mixWtSite1old",ntotal); + d_mixWtSite2old = typename AT::t_float_1d("PairMultiLucyRX::mixWtSite2old",ntotal); + d_mixWtSite1 = typename AT::t_float_1d("PairMultiLucyRX::mixWtSite1",ntotal); + d_mixWtSite2 = typename AT::t_float_1d("PairMultiLucyRX::mixWtSite2",ntotal); + } Kokkos::parallel_for(Kokkos::RangePolicy(0,ntotal),*this); } From b4b7310884382a18f9439983a4c241c24998d88c Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Thu, 8 Jun 2017 13:33:23 -0600 Subject: [PATCH 244/439] Fixing CUDA runtime issues in pair_exp6_rx_kokkos --- src/KOKKOS/pair_exp6_rx_kokkos.cpp | 16 ++++++++-------- src/KOKKOS/pair_exp6_rx_kokkos.h | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/KOKKOS/pair_exp6_rx_kokkos.cpp b/src/KOKKOS/pair_exp6_rx_kokkos.cpp index 5b84f09fd6..1eb1c6c770 100644 --- a/src/KOKKOS/pair_exp6_rx_kokkos.cpp +++ b/src/KOKKOS/pair_exp6_rx_kokkos.cpp @@ -426,7 +426,7 @@ KOKKOS_INLINE_FUNCTION void PairExp6rxKokkos::operator()(TagPairExp6rxCompute, const int &ii, EV_FLOAT& ev) const { { - const bool one_type = (atom->ntypes == 1); + const bool one_type = (ntypes == 1); if (isite1 == isite2) if (one_type) this->vectorized_operator(ii, ev); @@ -797,7 +797,7 @@ KOKKOS_INLINE_FUNCTION void PairExp6rxKokkos::operator()(TagPairExp6rxComputeNoAtomics, const int &ii, EV_FLOAT& ev) const { { - const bool one_type = (atom->ntypes == 1); + const bool one_type = (ntypes == 1); if (isite1 == isite2) if (one_type) this->vectorized_operator(ii, ev); @@ -1653,18 +1653,18 @@ template void PairExp6rxKokkos::allocate() { allocated = 1; - int n = atom->ntypes; + ntypes = atom->ntypes; - memory->create(setflag,n+1,n+1,"pair:setflag"); - for (int i = 1; i <= n; i++) - for (int j = i; j <= n; j++) + memory->create(setflag,ntypes+1,ntypes+1,"pair:setflag"); + for (int i = 1; i <= ntypes; i++) + for (int j = i; j <= ntypes; j++) setflag[i][j] = 0; - memory->create_kokkos(k_cutsq,cutsq,n+1,n+1,"pair:cutsq"); + memory->create_kokkos(k_cutsq,cutsq,ntypes+1,ntypes+1,"pair:cutsq"); d_cutsq = k_cutsq.template view(); k_cutsq.template modify(); - memory->create(cut,n+1,n+1,"pair:cut_lj"); + memory->create(cut,ntypes+1,ntypes+1,"pair:cut_lj"); } diff --git a/src/KOKKOS/pair_exp6_rx_kokkos.h b/src/KOKKOS/pair_exp6_rx_kokkos.h index 09283662a2..4c35c76851 100644 --- a/src/KOKKOS/pair_exp6_rx_kokkos.h +++ b/src/KOKKOS/pair_exp6_rx_kokkos.h @@ -145,7 +145,7 @@ class PairExp6rxKokkos : public PairExp6rx { int eflag,vflag; int nlocal,newton_pair,neighflag; double special_lj[4]; - int num_threads; + int num_threads,ntypes; typename AT::t_x_array_randomread x; typename AT::t_f_array f; From 86497949f20a2a6ae0609172e9aabf4e7221390d Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Thu, 8 Jun 2017 13:40:20 -0600 Subject: [PATCH 245/439] Fixing CUDA runtime issues in fix_shardlow_kokkos --- src/KOKKOS/fix_shardlow_kokkos.cpp | 21 ++++++++++++++++----- src/KOKKOS/fix_shardlow_kokkos.h | 2 ++ 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/KOKKOS/fix_shardlow_kokkos.cpp b/src/KOKKOS/fix_shardlow_kokkos.cpp index 52287d586c..b3d4e86244 100644 --- a/src/KOKKOS/fix_shardlow_kokkos.cpp +++ b/src/KOKKOS/fix_shardlow_kokkos.cpp @@ -444,9 +444,6 @@ void FixShardlowKokkos::ssa_update_dpde( rand_type rand_gen = rand_pool.get_state(id); #endif - const double boltz_inv = 1.0/force->boltz; - const double ftm2v = force->ftm2v; - const double dt = update->dt; int ct = count; int ii = start_ii; @@ -639,6 +636,16 @@ void FixShardlowKokkos::initial_integrate(int vflag) ssa_gitemLoc = np_ssa->ssa_gitemLoc; ssa_gitemLen = np_ssa->ssa_gitemLen; + np_ssa->k_ssa_itemLoc.template sync(); + np_ssa->k_ssa_itemLen.template sync(); + np_ssa->k_ssa_gitemLoc.template sync(); + np_ssa->k_ssa_gitemLen.template sync(); + + np_ssa->k_ssa_phaseLen.template sync(); + np_ssa->k_ssa_gphaseLen.template sync(); + auto h_ssa_phaseLen = np_ssa->k_ssa_phaseLen.h_view; + auto h_ssa_gphaseLen = np_ssa->k_ssa_gphaseLen.h_view; + int maxWorkItemCt = (int) ssa_itemLoc.dimension_1(); if (maxWorkItemCt < (int) ssa_gitemLoc.dimension_1()) { maxWorkItemCt = (int) ssa_gitemLoc.dimension_1(); @@ -670,9 +677,13 @@ void FixShardlowKokkos::initial_integrate(int vflag) deep_copy(d_hist, h_hist); #endif + boltz_inv = 1.0/force->boltz; + ftm2v = force->ftm2v; + dt = update->dt; + // process neighbors in the local AIR for (int workPhase = 0; workPhase < ssa_phaseCt; ++workPhase) { - int workItemCt = ssa_phaseLen[workPhase]; + int workItemCt = h_ssa_phaseLen[workPhase]; if(atom->ntypes > MAX_TYPES_STACKPARAMS) { Kokkos::parallel_for(workItemCt, LAMMPS_LAMBDA (const int workItem ) { @@ -692,7 +703,7 @@ void FixShardlowKokkos::initial_integrate(int vflag) //Loop over all 13 outward directions (7 stages) for (int workPhase = 0; workPhase < ssa_gphaseCt; ++workPhase) { // int airnum = workPhase + 1; - int workItemCt = ssa_gphaseLen[workPhase]; + int workItemCt = h_ssa_gphaseLen[workPhase]; // Communicate the updated velocities to all nodes comm->forward_comm_fix(this); diff --git a/src/KOKKOS/fix_shardlow_kokkos.h b/src/KOKKOS/fix_shardlow_kokkos.h index 4dc47709e1..df8849d80b 100644 --- a/src/KOKKOS/fix_shardlow_kokkos.h +++ b/src/KOKKOS/fix_shardlow_kokkos.h @@ -68,6 +68,8 @@ class FixShardlowKokkos : public FixShardlow { #endif protected: + double boltz_inv,ftm2v,dt; + // class PairDPDfdt *pairDPD; PairDPDfdtEnergyKokkos *k_pairDPDE; From c51cadcc6c38ff2c939fb0bed46dd73c09873c2d Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 9 Jun 2017 09:31:37 -0600 Subject: [PATCH 246/439] Fixing CUDA runtime issues in fix_shardlow_kokkos --- src/KOKKOS/fix_shardlow_kokkos.cpp | 66 ++++++++++++++++-------------- src/KOKKOS/fix_shardlow_kokkos.h | 17 +++++++- 2 files changed, 51 insertions(+), 32 deletions(-) diff --git a/src/KOKKOS/fix_shardlow_kokkos.cpp b/src/KOKKOS/fix_shardlow_kokkos.cpp index b3d4e86244..d2fb937a57 100644 --- a/src/KOKKOS/fix_shardlow_kokkos.cpp +++ b/src/KOKKOS/fix_shardlow_kokkos.cpp @@ -436,7 +436,7 @@ template KOKKOS_INLINE_FUNCTION void FixShardlowKokkos::ssa_update_dpde( int start_ii, int count, int id -) +) const { #ifdef DPD_USE_RAN_MARS class RanMars *pRNG = pp_random[id]; @@ -682,26 +682,18 @@ void FixShardlowKokkos::initial_integrate(int vflag) dt = update->dt; // process neighbors in the local AIR - for (int workPhase = 0; workPhase < ssa_phaseCt; ++workPhase) { + for (workPhase = 0; workPhase < ssa_phaseCt; ++workPhase) { int workItemCt = h_ssa_phaseLen[workPhase]; - if(atom->ntypes > MAX_TYPES_STACKPARAMS) { - Kokkos::parallel_for(workItemCt, LAMMPS_LAMBDA (const int workItem ) { - int ct = ssa_itemLen(workPhase, workItem); - int ii = ssa_itemLoc(workPhase, workItem); - ssa_update_dpde(ii, ct, workItem); - }); - } else { - Kokkos::parallel_for(workItemCt, LAMMPS_LAMBDA (const int workItem ) { - int ct = ssa_itemLen(workPhase, workItem); - int ii = ssa_itemLoc(workPhase, workItem); - ssa_update_dpde(ii, ct, workItem); - }); - } + + if(atom->ntypes > MAX_TYPES_STACKPARAMS) + Kokkos::parallel_for(Kokkos::RangePolicy >(0,workItemCt),*this); + else + Kokkos::parallel_for(Kokkos::RangePolicy >(0,workItemCt),*this); } //Loop over all 13 outward directions (7 stages) - for (int workPhase = 0; workPhase < ssa_gphaseCt; ++workPhase) { + for (workPhase = 0; workPhase < ssa_gphaseCt; ++workPhase) { // int airnum = workPhase + 1; int workItemCt = h_ssa_gphaseLen[workPhase]; @@ -713,27 +705,21 @@ void FixShardlowKokkos::initial_integrate(int vflag) // memset(&(atom->uCond[nlocal]), 0, sizeof(double)*nghost); // memset(&(atom->uMech[nlocal]), 0, sizeof(double)*nghost); + // must capture local variables, not class variables + auto l_uCond = uCond; + auto l_uMech = uMech; Kokkos::parallel_for(Kokkos::RangePolicy(nlocal,nlocal+nghost), LAMMPS_LAMBDA (const int i) { - uCond(i) = 0.0; - uMech(i) = 0.0; + l_uCond(i) = 0.0; + l_uMech(i) = 0.0; }); DeviceType::fence(); } // process neighbors in this AIR - if(atom->ntypes > MAX_TYPES_STACKPARAMS) { - Kokkos::parallel_for(workItemCt, LAMMPS_LAMBDA (const int workItem ) { - int ct = ssa_gitemLen(workPhase, workItem); - int ii = ssa_gitemLoc(workPhase, workItem); - ssa_update_dpde(ii, ct, workItem); - }); - } else { - Kokkos::parallel_for(workItemCt, LAMMPS_LAMBDA (const int workItem ) { - int ct = ssa_gitemLen(workPhase, workItem); - int ii = ssa_gitemLoc(workPhase, workItem); - ssa_update_dpde(ii, ct, workItem); - }); - } + if(atom->ntypes > MAX_TYPES_STACKPARAMS) + Kokkos::parallel_for(Kokkos::RangePolicy >(0,workItemCt),*this); + else + Kokkos::parallel_for(Kokkos::RangePolicy >(0,workItemCt),*this); // Communicate the ghost deltas to the atom owners comm->reverse_comm_fix(this); @@ -755,6 +741,24 @@ fprintf(stdout, "\n%6d %6d,%6d %6d: " copymode = 0; } +template +template +KOKKOS_INLINE_FUNCTION +void FixShardlowKokkos::operator()(TagFixShardlowSSAUpdateDPDE, const int &workItem) const { + const int ct = ssa_itemLen(workPhase, workItem); + const int ii = ssa_itemLoc(workPhase, workItem); + ssa_update_dpde(ii, ct, workItem); +} + +template +template +KOKKOS_INLINE_FUNCTION +void FixShardlowKokkos::operator()(TagFixShardlowSSAUpdateDPDEGhost, const int &workItem) const { + const int ct = ssa_gitemLen(workPhase, workItem); + const int ii = ssa_gitemLoc(workPhase, workItem); + ssa_update_dpde(ii, ct, workItem); +} + /* ---------------------------------------------------------------------- */ template diff --git a/src/KOKKOS/fix_shardlow_kokkos.h b/src/KOKKOS/fix_shardlow_kokkos.h index df8849d80b..91a2fdbc97 100644 --- a/src/KOKKOS/fix_shardlow_kokkos.h +++ b/src/KOKKOS/fix_shardlow_kokkos.h @@ -30,6 +30,12 @@ FixStyle(shardlow/kk/host,FixShardlowKokkos) namespace LAMMPS_NS { +template +struct TagFixShardlowSSAUpdateDPDE{}; + +template +struct TagFixShardlowSSAUpdateDPDEGhost{}; + template class FixShardlowKokkos : public FixShardlow { public: @@ -60,6 +66,14 @@ class FixShardlowKokkos : public FixShardlow { F_FLOAT cutinv,halfsigma,kappa,alpha; }; + template + KOKKOS_INLINE_FUNCTION + void operator()(TagFixShardlowSSAUpdateDPDE, const int&) const; + + template + KOKKOS_INLINE_FUNCTION + void operator()(TagFixShardlowSSAUpdateDPDEGhost, const int&) const; + #ifdef DEBUG_PAIR_CT typename AT::t_int_2d d_counters; typename HAT::t_int_2d h_counters; @@ -68,6 +82,7 @@ class FixShardlowKokkos : public FixShardlow { #endif protected: + int workPhase; double boltz_inv,ftm2v,dt; // class PairDPDfdt *pairDPD; @@ -127,7 +142,7 @@ class FixShardlowKokkos : public FixShardlow { // void ssa_update_dpd(int, int); // Constant Temperature template KOKKOS_INLINE_FUNCTION - void ssa_update_dpde(int, int, int); // Constant Energy + void ssa_update_dpde(int, int, int) const; // Constant Energy }; From 3c8e75ad590ae35be1002ce88281d88d8bbfc6f9 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 9 Jun 2017 10:57:35 -0600 Subject: [PATCH 247/439] Add missing sync/modify to fix_shardlow_kokkos --- src/KOKKOS/fix_shardlow_kokkos.cpp | 27 ++++++++++++++++++--------- src/KOKKOS/fix_shardlow_kokkos.h | 2 +- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/KOKKOS/fix_shardlow_kokkos.cpp b/src/KOKKOS/fix_shardlow_kokkos.cpp index d2fb937a57..0c7c51c821 100644 --- a/src/KOKKOS/fix_shardlow_kokkos.cpp +++ b/src/KOKKOS/fix_shardlow_kokkos.cpp @@ -73,11 +73,11 @@ FixShardlowKokkos::FixShardlowKokkos(LAMMPS *lmp, int narg, char **a FixShardlow(lmp, narg, arg), k_pairDPDE(NULL), ghostmax(0), nlocal(0) , nghost(0) { kokkosable = 1; -// atomKK = (AtomKokkos *) atom; -// execution_space = ExecutionSpaceFromDevice::space; + atomKK = (AtomKokkos *) atom; + execution_space = ExecutionSpaceFromDevice::space; -// datamask_read = X_MASK | V_MASK | F_MASK | MASK_MASK | Q_MASK | TYPE_MASK; -// datamask_modify = Q_MASK | X_MASK; + datamask_read = EMPTY_MASK; + datamask_modify = EMPTY_MASK; if (narg != 3) error->all(FLERR,"Illegal fix shardlow command"); @@ -167,6 +167,7 @@ void FixShardlowKokkos::init() //FIXME either create cutsq and fill it in, or just point to pairDPD's... // memory->destroy(cutsq); //FIXME // memory->create_kokkos(k_cutsq,cutsq,ntypes+1,ntypes+1,"FixShardlowKokkos:cutsq"); + k_pairDPDE->k_cutsq.template sync(); d_cutsq = k_pairDPDE->k_cutsq.template view(); //FIXME const double boltz2 = 2.0*force->boltz; @@ -288,10 +289,6 @@ void FixShardlowKokkos::ssa_update_dpd( rand_type rand_gen = rand_pool.get_state(id); #endif - const double theta_ij_inv = 1.0/k_pairDPD->temperature; // independent of i,j - const double boltz_inv = 1.0/force->boltz; - const double ftm2v = force->ftm2v; - const double dt = update->dt; int ct = count; int ii = start_ii; @@ -677,20 +674,24 @@ void FixShardlowKokkos::initial_integrate(int vflag) deep_copy(d_hist, h_hist); #endif + //theta_ij_inv = 1.0/k_pairDPD->temperature; // independent of i,j boltz_inv = 1.0/force->boltz; ftm2v = force->ftm2v; dt = update->dt; + k_params.template sync(); + // process neighbors in the local AIR + atomKK->sync(execution_space,X_MASK | V_MASK | TYPE_MASK | RMASS_MASK | UCOND_MASK | UMECH_MASK | DPDTHETA_MASK); for (workPhase = 0; workPhase < ssa_phaseCt; ++workPhase) { int workItemCt = h_ssa_phaseLen[workPhase]; - if(atom->ntypes > MAX_TYPES_STACKPARAMS) Kokkos::parallel_for(Kokkos::RangePolicy >(0,workItemCt),*this); else Kokkos::parallel_for(Kokkos::RangePolicy >(0,workItemCt),*this); } + atomKK->modified(execution_space,V_MASK | UCOND_MASK | UMECH_MASK); //Loop over all 13 outward directions (7 stages) for (workPhase = 0; workPhase < ssa_gphaseCt; ++workPhase) { @@ -698,7 +699,9 @@ void FixShardlowKokkos::initial_integrate(int vflag) int workItemCt = h_ssa_gphaseLen[workPhase]; // Communicate the updated velocities to all nodes + atomKK->sync(Host,V_MASK); comm->forward_comm_fix(this); + atomKK->modified(Host,V_MASK); if(k_pairDPDE){ // Zero out the ghosts' uCond & uMech to be used as delta accumulators @@ -706,6 +709,7 @@ void FixShardlowKokkos::initial_integrate(int vflag) // memset(&(atom->uMech[nlocal]), 0, sizeof(double)*nghost); // must capture local variables, not class variables + atomKK->sync(execution_space,UCOND_MASK | UMECH_MASK); auto l_uCond = uCond; auto l_uMech = uMech; Kokkos::parallel_for(Kokkos::RangePolicy(nlocal,nlocal+nghost), LAMMPS_LAMBDA (const int i) { @@ -713,16 +717,21 @@ void FixShardlowKokkos::initial_integrate(int vflag) l_uMech(i) = 0.0; }); DeviceType::fence(); + atomKK->modified(execution_space,UCOND_MASK | UMECH_MASK); } // process neighbors in this AIR + atomKK->sync(execution_space,X_MASK | V_MASK | TYPE_MASK | RMASS_MASK | UCOND_MASK | UMECH_MASK | DPDTHETA_MASK); if(atom->ntypes > MAX_TYPES_STACKPARAMS) Kokkos::parallel_for(Kokkos::RangePolicy >(0,workItemCt),*this); else Kokkos::parallel_for(Kokkos::RangePolicy >(0,workItemCt),*this); + atomKK->modified(execution_space,V_MASK | UCOND_MASK | UMECH_MASK); // Communicate the ghost deltas to the atom owners + atomKK->sync(Host,V_MASK | UCOND_MASK | UMECH_MASK); comm->reverse_comm_fix(this); + atomKK->modified(Host,V_MASK | UCOND_MASK | UMECH_MASK); } //End Loop over all directions For airnum = Top, Top-Right, Right, Bottom-Right, Back diff --git a/src/KOKKOS/fix_shardlow_kokkos.h b/src/KOKKOS/fix_shardlow_kokkos.h index 91a2fdbc97..3dbbaaa61c 100644 --- a/src/KOKKOS/fix_shardlow_kokkos.h +++ b/src/KOKKOS/fix_shardlow_kokkos.h @@ -83,7 +83,7 @@ class FixShardlowKokkos : public FixShardlow { protected: int workPhase; - double boltz_inv,ftm2v,dt; + double theta_ij_inv,boltz_inv,ftm2v,dt; // class PairDPDfdt *pairDPD; PairDPDfdtEnergyKokkos *k_pairDPDE; From b96b6b9cd775b43007777ba2182949c331ca9fb2 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Mon, 19 Jun 2017 14:04:16 -0600 Subject: [PATCH 248/439] Fixing error checks --- src/KOKKOS/fix_rx_kokkos.cpp | 2 +- src/USER-DPD/fix_shardlow.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/KOKKOS/fix_rx_kokkos.cpp b/src/KOKKOS/fix_rx_kokkos.cpp index ac81e5c2a7..6fbdfad289 100644 --- a/src/KOKKOS/fix_rx_kokkos.cpp +++ b/src/KOKKOS/fix_rx_kokkos.cpp @@ -116,7 +116,7 @@ void FixRxKokkos::init() bool eos_flag = false; for (int i = 0; i < modify->nfix; i++) - if (strcmp(modify->fix[i]->style,"eos/table/rx") == 0) eos_flag = true; + if (strncmp(modify->fix[i]->style,"eos/table/rx",3) == 0) eos_flag = true; if(!eos_flag) error->all(FLERR,"fix rx requires fix eos/table/rx to be specified"); if (update_kinetics_data) diff --git a/src/USER-DPD/fix_shardlow.cpp b/src/USER-DPD/fix_shardlow.cpp index a1059e2fb0..f3057a6563 100644 --- a/src/USER-DPD/fix_shardlow.cpp +++ b/src/USER-DPD/fix_shardlow.cpp @@ -157,7 +157,7 @@ void FixShardlow::setup(int vflag) error->all(FLERR,"Cannot use constant temperature integration routines with DPD."); for (int i = 0; i < modify->nfix; i++){ - if (strcmp(modify->fix[i]->style,"shardlow") == 0) fixShardlow = true; + if (strncmp(modify->fix[i]->style,"shardlow",3) == 0) fixShardlow = true; if (strncmp(modify->fix[i]->style,"nve",3) == 0 || (strncmp(modify->fix[i]->style,"nph",3) == 0)){ if(fixShardlow) break; else error->all(FLERR,"The deterministic integrator must follow fix shardlow in the input file."); From 67a0183b333225a89902aba88c4bdc69160709d6 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Mon, 19 Jun 2017 15:23:33 -0600 Subject: [PATCH 249/439] Removing atom2bin change since ssa neighlists aren't be used for occasional lists --- src/USER-DPD/nbin_ssa.cpp | 3 --- src/USER-DPD/npair_half_bin_newton_ssa.cpp | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/USER-DPD/nbin_ssa.cpp b/src/USER-DPD/nbin_ssa.cpp index 5dacf52ee1..4c57a8e70f 100644 --- a/src/USER-DPD/nbin_ssa.cpp +++ b/src/USER-DPD/nbin_ssa.cpp @@ -76,7 +76,6 @@ void NBinSSA::bin_atoms() int nowned = atom->nlocal; // NOTE: nlocal was set to atom->nfirst above for (i = nall-1; i >= nowned; i--) { ibin = coord2ssaAIR(x[i]); - atom2bin[i] = ibin; if (ibin < 1) continue; // skip ghost atoms not in AIR if (mask[i] & bitmask) { bins[i] = gairhead_ssa[ibin]; @@ -86,7 +85,6 @@ void NBinSSA::bin_atoms() } else { for (i = nall-1; i >= nlocal; i--) { ibin = coord2ssaAIR(x[i]); - atom2bin[i] = ibin; if (ibin < 1) continue; // skip ghost atoms not in AIR bins[i] = gairhead_ssa[ibin]; gairhead_ssa[ibin] = i; @@ -94,7 +92,6 @@ void NBinSSA::bin_atoms() } for (i = nlocal-1; i >= 0; i--) { ibin = coord2bin(x[i][0], x[i][1], x[i][2], xbin, ybin, zbin); - atom2bin[i] = ibin; // Find the bounding box of the local atoms in the bins if (xbin < lbinxlo) lbinxlo = xbin; if (xbin >= lbinxhi) lbinxhi = xbin + 1; diff --git a/src/USER-DPD/npair_half_bin_newton_ssa.cpp b/src/USER-DPD/npair_half_bin_newton_ssa.cpp index 221aa5b454..a6479d4c4f 100644 --- a/src/USER-DPD/npair_half_bin_newton_ssa.cpp +++ b/src/USER-DPD/npair_half_bin_newton_ssa.cpp @@ -251,7 +251,7 @@ void NPairHalfBinNewtonSSA::build(NeighList *list) ytmp = x[i][1]; ztmp = x[i][2]; - ibin = atom2bin[i]; + ibin = coord2bin(x[i],xbin,ybin,zbin); // loop over AIR ghost atoms in all bins in "full" stencil // Note: the non-AIR ghost atoms have already been filtered out From 68206079da39fbef08c37e5c1cef1ae8bd9ad2c6 Mon Sep 17 00:00:00 2001 From: Trung Nguyen Date: Fri, 7 Jul 2017 16:47:24 -0500 Subject: [PATCH 250/439] Supported short neighbor lists for 3-body kernels in sw/gpu and vashishta/gpu --- lib/gpu/lal_aux_fun1.h | 24 +++---- lib/gpu/lal_base_three.cpp | 65 ++++++++++++++---- lib/gpu/lal_base_three.h | 27 ++++---- lib/gpu/lal_sw.cpp | 26 ++++++-- lib/gpu/lal_sw.cu | 117 +++++++++++++++++++++++++++++--- lib/gpu/lal_vashishta.cpp | 34 +++++++--- lib/gpu/lal_vashishta.cu | 133 +++++++++++++++++++++++++++++-------- lib/gpu/lal_vashishta.h | 1 + 8 files changed, 332 insertions(+), 95 deletions(-) diff --git a/lib/gpu/lal_aux_fun1.h b/lib/gpu/lal_aux_fun1.h index b40bb7f943..47a216ff6f 100644 --- a/lib/gpu/lal_aux_fun1.h +++ b/lib/gpu/lal_aux_fun1.h @@ -22,21 +22,21 @@ offset=tid & (t_per_atom-1); \ ii=fast_mul((int)BLOCK_ID_X,(int)(BLOCK_SIZE_X)/t_per_atom)+tid/t_per_atom; -#define nbor_info(nbor_mem, packed_mem, nbor_stride, t_per_atom, ii, offset, \ - i, numj, stride, nbor_end, nbor_begin) \ - i=nbor_mem[ii]; \ - nbor_begin=ii+nbor_stride; \ - numj=nbor_mem[nbor_begin]; \ - if (nbor_mem==packed_mem) { \ - nbor_begin+=nbor_stride+fast_mul(ii,t_per_atom-1); \ - stride=fast_mul(t_per_atom,nbor_stride); \ - nbor_end=nbor_begin+fast_mul(numj/t_per_atom,stride)+(numj & (t_per_atom-1)); \ +#define nbor_info(dev_nbor, dev_packed, nbor_pitch, t_per_atom, ii, offset, \ + i, numj, n_stride, nbor_end, nbor_begin) \ + i=dev_nbor[ii]; \ + nbor_begin=ii+nbor_pitch; \ + numj=dev_nbor[nbor_begin]; \ + if (dev_nbor==dev_packed) { \ + nbor_begin+=nbor_pitch+fast_mul(ii,t_per_atom-1); \ + n_stride=fast_mul(t_per_atom,nbor_pitch); \ + nbor_end=nbor_begin+fast_mul(numj/t_per_atom,n_stride)+(numj & (t_per_atom-1)); \ nbor_begin+=offset; \ } else { \ - nbor_begin+=nbor_stride; \ - nbor_begin=nbor_mem[nbor_begin]; \ + nbor_begin+=nbor_pitch; \ + nbor_begin=dev_nbor[nbor_begin]; \ nbor_end=nbor_begin+numj; \ - stride=t_per_atom; \ + n_stride=t_per_atom; \ nbor_begin+=offset; \ } diff --git a/lib/gpu/lal_base_three.cpp b/lib/gpu/lal_base_three.cpp index f772e36295..fd9fc7f272 100644 --- a/lib/gpu/lal_base_three.cpp +++ b/lib/gpu/lal_base_three.cpp @@ -20,7 +20,7 @@ using namespace LAMMPS_AL; extern Device global_device; template -BaseThreeT::BaseThree() : _compiled(false), _max_bytes(0) { +BaseThreeT::BaseThree() : _compiled(false), _max_bytes(0), _short_nbor(false) { device=&global_device; ans=new Answer(); nbor=new Neighbor(); @@ -53,8 +53,8 @@ int BaseThreeT::init_three(const int nlocal, const int nall, const int max_nbors, const int maxspecial, const double cell_size, const double gpu_split, FILE *_screen, const void *pair_program, - const char *k_two, const char *k_three_center, - const char *k_three_end) { + const char *two, const char *three_center, + const char *three_end, const char *short_nbor) { screen=_screen; int gpu_nbor=0; @@ -70,10 +70,10 @@ int BaseThreeT::init_three(const int nlocal, const int nall, _gpu_host=1; _threads_per_atom=device->threads_per_atom(); - if (_threads_per_atom>1 && gpu_nbor==0) { + if (_threads_per_atom>1 && gpu_nbor==0) { // neigh no and tpa > 1 nbor->packing(true); _nbor_data=&(nbor->dev_packed); - } else + } else // neigh yes or tpa == 1 _nbor_data=&(nbor->dev_nbor); if (_threads_per_atom*_threads_per_atom>device->warp_size()) return -10; @@ -97,7 +97,7 @@ int BaseThreeT::init_three(const int nlocal, const int nall, _block_pair=device->pair_block_size(); _block_size=device->block_ellipse(); - compile_kernels(*ucl_device,pair_program,k_two,k_three_center,k_three_end); + compile_kernels(*ucl_device,pair_program,two,three_center,three_end,short_nbor); // Initialize host-device load balancer hd_balancer.init(device,gpu_nbor,gpu_split); @@ -113,6 +113,15 @@ int BaseThreeT::init_three(const int nlocal, const int nall, _max_an_bytes+=ans2->gpu_bytes(); #endif + // if short neighbor list is supported + if (short_nbor) { + _short_nbor = true; + int ef_nall=nall; + if (ef_nall==0) + ef_nall=2000; + dev_short_nbor.alloc(ef_nall*(2+max_nbors),*(this->ucl_device),UCL_READ_WRITE); + } + return 0; } @@ -136,6 +145,7 @@ void BaseThreeT::clear_atomic() { k_three_end.clear(); k_three_end_vatom.clear(); k_pair.clear(); + k_short_nbor.clear(); delete pair_program; _compiled=false; } @@ -143,6 +153,7 @@ void BaseThreeT::clear_atomic() { time_pair.clear(); hd_balancer.clear(); + dev_short_nbor.clear(); nbor->clear(); ans->clear(); #ifdef THREE_CONCURRENT @@ -247,12 +258,26 @@ void BaseThreeT::compute(const int f_ago, const int inum_full, const int nall, reset_nbors(nall, inum, nlist, ilist, numj, firstneigh, success); if (!success) return; + _max_nbors = nbor->max_nbor_loop(nlist,numj,ilist); } atom->cast_x_data(host_x,host_type); hd_balancer.start_timer(); atom->add_x_data(host_x,host_type); + // if short neighbor list is supported + if (_short_nbor) { + + // re-allocate dev_short_nbor if necessary + if (nall*(2+_max_nbors) > dev_short_nbor.cols()) { + int _nmax=static_cast(static_cast(nall)*1.10); + dev_short_nbor.resize((2+_max_nbors)*_nmax); + } + } + + // _ainum to be used in loop() for short neighbor list build + _ainum = nlist; + int evatom=0; if (eatom || vatom) evatom=1; @@ -300,7 +325,7 @@ int ** BaseThreeT::compute(const int ago, const int inum_full, // Build neighbor list on GPU if necessary if (ago==0) { - build_nbor_list(inum, inum_full-inum, nall, host_x, host_type, + _max_nbors = build_nbor_list(inum, inum_full-inum, nall, host_x, host_type, sublo, subhi, tag, nspecial, special, success); if (!success) return NULL; @@ -313,6 +338,19 @@ int ** BaseThreeT::compute(const int ago, const int inum_full, *ilist=nbor->host_ilist.begin(); *jnum=nbor->host_acc.begin(); + // if short neighbor list is supported + if (_short_nbor) { + + // re-allocate dev_short_nbor if necessary + if (nall*(2+_max_nbors) > dev_short_nbor.cols()) { + int _nmax=static_cast(static_cast(nall)*1.10); + dev_short_nbor.resize((2+_max_nbors)*_nmax); + } + } + + // _ainum to be used in loop() for short neighbor list build + _ainum = nall; + int evatom=0; if (eatom || vatom) evatom=1; @@ -339,19 +377,20 @@ double BaseThreeT::host_memory_usage_atomic() const { template void BaseThreeT::compile_kernels(UCL_Device &dev, const void *pair_str, - const char *ktwo, const char *kthree_center, - const char *kthree_end) { + const char *two, const char *three_center, + const char *three_end, const char* short_nbor) { if (_compiled) return; - std::string vatom_name=std::string(kthree_end)+"_vatom"; + std::string vatom_name=std::string(three_end)+"_vatom"; pair_program=new UCL_Program(dev); pair_program->load_string(pair_str,device->compile_string().c_str()); - k_three_center.set_function(*pair_program,kthree_center); - k_three_end.set_function(*pair_program,kthree_end); + k_three_center.set_function(*pair_program,three_center); + k_three_end.set_function(*pair_program,three_end); k_three_end_vatom.set_function(*pair_program,vatom_name.c_str()); - k_pair.set_function(*pair_program,ktwo); + k_pair.set_function(*pair_program,two); + if (short_nbor) k_short_nbor.set_function(*pair_program,short_nbor); pos_tex.get_texture(*pair_program,"pos_tex"); #ifdef THREE_CONCURRENT diff --git a/lib/gpu/lal_base_three.h b/lib/gpu/lal_base_three.h index 4f27ecdf92..d03a7521cd 100644 --- a/lib/gpu/lal_base_three.h +++ b/lib/gpu/lal_base_three.h @@ -56,7 +56,8 @@ class BaseThree { const int maxspecial, const double cell_size, const double gpu_split, FILE *screen, const void *pair_program, const char *k_two, - const char *k_three_center, const char *k_three_end); + const char *k_three_center, const char *k_three_end, + const char *k_short_nbor=NULL); /// Estimate the overhead for GPU context changes and CPU driver void estimate_gpu_overhead(); @@ -74,8 +75,8 @@ class BaseThree { /// Check if there is enough storage for neighbors and realloc if not /** \param nlocal number of particles whose nbors must be stored on device - * \param host_inum number of particles whose nbors need to copied to host - * \param current maximum number of neighbors + * \param max_nbors maximum number of neighbors + * \param success set to false if insufficient memory * \note olist_size=total number of local particles **/ inline void resize_local(const int inum, const int max_nbors, bool &success) { nbor->resize(inum,max_nbors,success); @@ -84,7 +85,7 @@ class BaseThree { /// Check if there is enough storage for neighbors and realloc if not /** \param nlocal number of particles whose nbors must be stored on device * \param host_inum number of particles whose nbors need to copied to host - * \param current maximum number of neighbors + * \param max_nbors current maximum number of neighbors * \note host_inum is 0 if the host is performing neighboring * \note nlocal+host_inum=total number local particles * \note olist_size=0 **/ @@ -143,14 +144,6 @@ class BaseThree { const bool vflag, const bool eatom, const bool vatom, int &host_start, const double cpu_time, bool &success); - /// Pair loop with device neighboring - int * compute(const int ago, const int inum_full, const int nall, - double **host_x, int *host_type, double *sublo, - double *subhi, tagint *tag, int **nspecial, - tagint **special, const bool eflag, const bool vflag, - const bool eatom, const bool vatom, int &host_start, - const double cpu_time, bool &success); - /// Pair loop with device neighboring int ** compute(const int ago, const int inum_full, const int nall, double **host_x, int *host_type, double *sublo, @@ -193,6 +186,9 @@ class BaseThree { /// Neighbor data Neighbor *nbor; + UCL_D_Vec dev_short_nbor; + UCL_Kernel k_short_nbor; + // ------------------------- DEVICE KERNELS ------------------------- UCL_Program *pair_program; UCL_Kernel k_pair, k_three_center, k_three_end, k_three_end_vatom; @@ -203,16 +199,17 @@ class BaseThree { UCL_Texture pos_tex; protected: - bool _compiled; + bool _compiled,_short_nbor; int _block_pair, _block_size, _threads_per_atom, _end_command_queue; int _gpu_nbor; double _max_bytes, _max_an_bytes; + int _max_nbors, _ainum; double _gpu_overhead, _driver_overhead; UCL_D_Vec *_nbor_data; void compile_kernels(UCL_Device &dev, const void *pair_string, - const char *k_two, const char *k_three_center, - const char *k_three_end); + const char *two, const char *three_center, + const char *three_end, const char* short_nbor); virtual void loop(const bool _eflag, const bool _vflag, const int evatom) = 0; diff --git a/lib/gpu/lal_sw.cpp b/lib/gpu/lal_sw.cpp index 3492d7030e..24984e4878 100644 --- a/lib/gpu/lal_sw.cpp +++ b/lib/gpu/lal_sw.cpp @@ -55,7 +55,7 @@ int SWT::init(const int ntypes, const int nlocal, const int nall, const int max_ int success; success=this->init_three(nlocal,nall,max_nbors,0,cell_size,gpu_split, _screen,sw,"k_sw","k_sw_three_center", - "k_sw_three_end"); + "k_sw_three_end","k_sw_short_nbor"); if (success!=0) return success; @@ -193,19 +193,30 @@ void SWT::loop(const bool _eflag, const bool _vflag, const int evatom) { else vflag=0; - int GX=static_cast(ceil(static_cast(this->ans->inum())/ + // build the short neighbor list + int ainum=this->_ainum; + int nbor_pitch=this->nbor->nbor_pitch(); + int GX=static_cast(ceil(static_cast(ainum)/ (BX/this->_threads_per_atom))); + this->k_short_nbor.set_size(GX,BX); + this->k_short_nbor.run(&this->atom->x, &sw3, &map, &elem2param, &_nelements, + &this->nbor->dev_nbor, &this->_nbor_data->begin(), + &this->dev_short_nbor, &ainum, + &nbor_pitch, &this->_threads_per_atom); // this->_nbor_data == nbor->dev_packed for gpu_nbor == 0 and tpa > 1 // this->_nbor_data == nbor->dev_nbor for gpu_nbor == 1 or tpa == 1 - int ainum=this->ans->inum(); - int nbor_pitch=this->nbor->nbor_pitch(); + ainum=this->ans->inum(); + nbor_pitch=this->nbor->nbor_pitch(); + GX=static_cast(ceil(static_cast(this->ans->inum())/ + (BX/this->_threads_per_atom))); this->time_pair.start(); - + this->k_pair.set_size(GX,BX); this->k_pair.run(&this->atom->x, &sw1, &sw2, &sw3, &map, &elem2param, &_nelements, &this->nbor->dev_nbor, &this->_nbor_data->begin(), + &this->dev_short_nbor, &this->ans->force, &this->ans->engv, &eflag, &vflag, &ainum, &nbor_pitch, &this->_threads_per_atom); @@ -217,6 +228,7 @@ void SWT::loop(const bool _eflag, const bool _vflag, const int evatom) { this->k_three_center.run(&this->atom->x, &sw1, &sw2, &sw3, &map, &elem2param, &_nelements, &this->nbor->dev_nbor, &this->_nbor_data->begin(), + &this->dev_short_nbor, &this->ans->force, &this->ans->engv, &eflag, &vflag, &ainum, &nbor_pitch, &this->_threads_per_atom, &evatom); @@ -231,7 +243,7 @@ void SWT::loop(const bool _eflag, const bool _vflag, const int evatom) { this->k_three_end_vatom.run(&this->atom->x, &sw1, &sw2, &sw3, &map, &elem2param, &_nelements, &this->nbor->dev_nbor, &this->_nbor_data->begin(), - &this->nbor->dev_acc, + &this->nbor->dev_acc, &this->dev_short_nbor, &end_ans->force, &end_ans->engv, &eflag, &vflag, &ainum, &nbor_pitch, &this->_threads_per_atom, &this->_gpu_nbor); @@ -240,7 +252,7 @@ void SWT::loop(const bool _eflag, const bool _vflag, const int evatom) { this->k_three_end.run(&this->atom->x, &sw1, &sw2, &sw3, &map, &elem2param, &_nelements, &this->nbor->dev_nbor, &this->_nbor_data->begin(), - &this->nbor->dev_acc, + &this->nbor->dev_acc, &this->dev_short_nbor, &end_ans->force, &end_ans->engv, &eflag, &vflag, &ainum, &nbor_pitch, &this->_threads_per_atom, &this->_gpu_nbor); diff --git a/lib/gpu/lal_sw.cu b/lib/gpu/lal_sw.cu index 46330c59e4..7dea52898e 100644 --- a/lib/gpu/lal_sw.cu +++ b/lib/gpu/lal_sw.cu @@ -130,6 +130,64 @@ texture sw3_tex; #endif +__kernel void k_sw_short_nbor(const __global numtyp4 *restrict x_, + const __global numtyp4 *restrict sw3, + const __global int *restrict map, + const __global int *restrict elem2param, + const int nelements, + const __global int * dev_nbor, + const __global int * dev_packed, + __global int * dev_short_nbor, + const int inum, const int nbor_pitch, const int t_per_atom) { + __local int n_stride; + int tid, ii, offset; + atom_info(t_per_atom,ii,tid,offset); + + if (iiinit_three(nlocal,nall,max_nbors,0,cell_size,gpu_split, _screen,vashishta,"k_vashishta","k_vashishta_three_center", - "k_vashishta_three_end"); + "k_vashishta_three_end","k_vashishta_short_nbor"); if (success!=0) return success; @@ -128,15 +128,18 @@ int VashishtaT::init(const int ntypes, const int nlocal, const int nall, const i param4.alloc(nparams,*(this->ucl_device),UCL_READ_ONLY); + double r0sqmax = 0; for (int i=0; i(r0sq); dview[i].y=static_cast(gamma[i]); dview[i].z=static_cast(cutsq[i]); dview[i].w=static_cast(r0[i]); } + _cutshortsq = static_cast(r0sqmax); + ucl_copy(param4,dview,false); param4_tex.get_texture(*(this->pair_program),"param4_tex"); param4_tex.bind_float(param4,4); @@ -223,15 +226,27 @@ void VashishtaT::loop(const bool _eflag, const bool _vflag, const int evatom) { else vflag=0; - int GX=static_cast(ceil(static_cast(this->ans->inum())/ + // build the short neighbor list + int ainum=this->_ainum; + int nbor_pitch=this->nbor->nbor_pitch(); + int GX=static_cast(ceil(static_cast(ainum)/ (BX/this->_threads_per_atom))); + this->k_short_nbor.set_size(GX,BX); + this->k_short_nbor.run(&this->atom->x, &_cutshortsq, + &this->nbor->dev_nbor, &this->_nbor_data->begin(), + &this->dev_short_nbor, &ainum, + &nbor_pitch, &this->_threads_per_atom); + // this->_nbor_data == nbor->dev_packed for gpu_nbor == 0 and tpa > 1 // this->_nbor_data == nbor->dev_nbor for gpu_nbor == 1 or tpa == 1 - int ainum=this->ans->inum(); - int nbor_pitch=this->nbor->nbor_pitch(); + ainum=this->ans->inum(); + nbor_pitch=this->nbor->nbor_pitch(); + GX=static_cast(ceil(static_cast(this->ans->inum())/ + (BX/this->_threads_per_atom))); this->time_pair.start(); + // note that k_pair does not run with the short neighbor list this->k_pair.set_size(GX,BX); this->k_pair.run(&this->atom->x, ¶m1, ¶m2, ¶m3, ¶m4, ¶m5, &map, &elem2param, &_nelements, @@ -248,6 +263,7 @@ void VashishtaT::loop(const bool _eflag, const bool _vflag, const int evatom) { this->k_three_center.run(&this->atom->x, ¶m1, ¶m2, ¶m3, ¶m4, ¶m5, &map, &elem2param, &_nelements, &this->nbor->dev_nbor, &this->_nbor_data->begin(), + &this->dev_short_nbor, &this->ans->force, &this->ans->engv, &eflag, &vflag, &ainum, &nbor_pitch, &this->_threads_per_atom, &evatom); Answer *end_ans; @@ -257,21 +273,19 @@ void VashishtaT::loop(const bool _eflag, const bool _vflag, const int evatom) { end_ans=this->ans; #endif if (evatom!=0) { - this->k_three_end_vatom.set_size(GX,BX); this->k_three_end_vatom.run(&this->atom->x, ¶m1, ¶m2, ¶m3, ¶m4, ¶m5, &map, &elem2param, &_nelements, &this->nbor->dev_nbor, &this->_nbor_data->begin(), - &this->nbor->dev_acc, + &this->nbor->dev_acc, &this->dev_short_nbor, &end_ans->force, &end_ans->engv, &eflag, &vflag, &ainum, &nbor_pitch, &this->_threads_per_atom, &this->_gpu_nbor); } else { - this->k_three_end.set_size(GX,BX); this->k_three_end.run(&this->atom->x, ¶m1, ¶m2, ¶m3, ¶m4, ¶m5, &map, &elem2param, &_nelements, &this->nbor->dev_nbor, &this->_nbor_data->begin(), - &this->nbor->dev_acc, + &this->nbor->dev_acc, &this->dev_short_nbor, &end_ans->force, &end_ans->engv, &eflag, &vflag, &ainum, &nbor_pitch, &this->_threads_per_atom, &this->_gpu_nbor); } diff --git a/lib/gpu/lal_vashishta.cu b/lib/gpu/lal_vashishta.cu index caa3c03613..7449b18f6b 100644 --- a/lib/gpu/lal_vashishta.cu +++ b/lib/gpu/lal_vashishta.cu @@ -136,6 +136,56 @@ texture param5_tex; #endif +__kernel void k_vashishta_short_nbor(const __global numtyp4 *restrict x_, + const numtyp cutshortsq, + const __global int * dev_nbor, + const __global int * dev_packed, + __global int * dev_short_nbor, + const int inum, const int nbor_pitch, + const int t_per_atom) { + __local int n_stride; + int tid, ii, offset; + atom_info(t_per_atom,ii,tid,offset); + + if (ii { UCL_D_Vec elem2param; UCL_D_Vec map; int _nparams,_nelements; + numtyp _cutshortsq; UCL_Texture param1_tex, param2_tex, param3_tex, param4_tex, param5_tex; From 1c6533e53df2e4d69cb40228baf69677b5941405 Mon Sep 17 00:00:00 2001 From: Trung Nguyen Date: Sat, 8 Jul 2017 14:15:26 -0500 Subject: [PATCH 251/439] Working on short neighbor list for tersoff/gpu --- lib/gpu/lal_tersoff.cpp | 81 +++++++++++--------- lib/gpu/lal_tersoff.cu | 165 ++++++++++++++++++++++++++++++++-------- lib/gpu/lal_tersoff.h | 3 +- 3 files changed, 178 insertions(+), 71 deletions(-) diff --git a/lib/gpu/lal_tersoff.cpp b/lib/gpu/lal_tersoff.cpp index 6b0b563d9f..f1e0320b8c 100644 --- a/lib/gpu/lal_tersoff.cpp +++ b/lib/gpu/lal_tersoff.cpp @@ -55,7 +55,8 @@ int TersoffT::init(const int ntypes, const int nlocal, const int nall, const int int success; success=this->init_three(nlocal,nall,max_nbors,0,cell_size,gpu_split, _screen,tersoff,"k_tersoff_repulsive", - "k_tersoff_three_center", "k_tersoff_three_end"); + "k_tersoff_three_center", "k_tersoff_three_end", + "k_tersoff_short_nbor"); if (success!=0) return success; @@ -157,8 +158,12 @@ int TersoffT::init(const int ntypes, const int nlocal, const int nall, const int UCL_H_Vec cutsq_view(nparams,*(this->ucl_device), UCL_WRITE_ONLY); - for (int i=0; i(host_cutsq[i]); + if (cutsqmax < host_cutsq[i]) cutsqmax = host_cutsq[i]; + } + _cutshortsq = static_cast(cutsqmax); cutsq.alloc(nparams,*(this->ucl_device),UCL_READ_ONLY); ucl_copy(cutsq,cutsq_view,false); @@ -250,7 +255,7 @@ void TersoffT::compute(const int f_ago, const int inum_full, const int nall, this->reset_nbors(nall, inum, nlist, ilist, numj, firstneigh, success); if (!success) return; - _max_nbors = this->nbor->max_nbor_loop(nlist,numj,ilist); + this->_max_nbors = this->nbor->max_nbor_loop(nlist,numj,ilist); } this->atom->cast_x_data(host_x,host_type); @@ -258,29 +263,19 @@ void TersoffT::compute(const int f_ago, const int inum_full, const int nall, this->atom->add_x_data(host_x,host_type); // re-allocate zetaij if necessary - if (nall*_max_nbors > _zetaij.cols()) { + if (nall*this->_max_nbors > _zetaij.cols()) { int _nmax=static_cast(static_cast(nall)*1.10); - _zetaij.resize(_max_nbors*_nmax); + _zetaij.resize(this->_max_nbors*_nmax); } + this->_ainum=nlist; + int _eflag; if (eflag) _eflag=1; else _eflag=0; - int ainum=nlist; - int nbor_pitch=this->nbor->nbor_pitch(); - int BX=this->block_pair(); - int GX=static_cast(ceil(static_cast(ainum)/ - (BX/(JTHREADS*KTHREADS)))); - - this->k_zeta.set_size(GX,BX); - this->k_zeta.run(&this->atom->x, &ts1, &ts2, &ts3, &ts4, &ts5, &cutsq, - &map, &elem2param, &_nelements, &_nparams, &_zetaij, - &this->nbor->dev_nbor, &this->_nbor_data->begin(), - &_eflag, &ainum, &nbor_pitch, &this->_threads_per_atom); - int evatom=0; if (eatom || vatom) evatom=1; @@ -329,7 +324,7 @@ int ** TersoffT::compute(const int ago, const int inum_full, // Build neighbor list on GPU if necessary if (ago==0) { - _max_nbors = this->build_nbor_list(inum, inum_full-inum, nall, host_x, host_type, + this->_max_nbors = this->build_nbor_list(inum, inum_full-inum, nall, host_x, host_type, sublo, subhi, tag, nspecial, special, success); if (!success) return NULL; @@ -343,29 +338,19 @@ int ** TersoffT::compute(const int ago, const int inum_full, *jnum=this->nbor->host_acc.begin(); // re-allocate zetaij if necessary - if (nall*_max_nbors > _zetaij.cols()) { + if (nall*this->_max_nbors > _zetaij.cols()) { int _nmax=static_cast(static_cast(nall)*1.10); - _zetaij.resize(_max_nbors*_nmax); + _zetaij.resize(this->_max_nbors*_nmax); } + this->_ainum=nall; + int _eflag; if (eflag) _eflag=1; else _eflag=0; - int ainum=nall; - int nbor_pitch=this->nbor->nbor_pitch(); - int BX=this->block_pair(); - int GX=static_cast(ceil(static_cast(ainum)/ - (BX/(JTHREADS*KTHREADS)))); - - this->k_zeta.set_size(GX,BX); - this->k_zeta.run(&this->atom->x, &ts1, &ts2, &ts3, &ts4, &ts5, &cutsq, - &map, &elem2param, &_nelements, &_nparams, &_zetaij, - &this->nbor->dev_nbor, &this->_nbor_data->begin(), - &_eflag, &ainum, &nbor_pitch, &this->_threads_per_atom); - int evatom=0; if (eatom || vatom) evatom=1; @@ -402,9 +387,32 @@ void TersoffT::loop(const bool _eflag, const bool _vflag, const int evatom) { else vflag=0; - int ainum=this->ans->inum(); + // build the short neighbor list + int ainum=this->_ainum; int nbor_pitch=this->nbor->nbor_pitch(); - int GX=static_cast(ceil(static_cast(this->ans->inum())/ + int GX=static_cast(ceil(static_cast(ainum)/ + (BX/this->_threads_per_atom))); + + this->k_short_nbor.set_size(GX,BX); + this->k_short_nbor.run(&this->atom->x, &_cutshortsq, + &this->nbor->dev_nbor, &this->_nbor_data->begin(), + &this->dev_short_nbor, &ainum, + &nbor_pitch, &this->_threads_per_atom); + + nbor_pitch=this->nbor->nbor_pitch(); + GX=static_cast(ceil(static_cast(this->_ainum)/ + (BX/(JTHREADS*KTHREADS)))); + + this->k_zeta.set_size(GX,BX); + this->k_zeta.run(&this->atom->x, &ts1, &ts2, &ts3, &ts4, &ts5, &cutsq, + &map, &elem2param, &_nelements, &_nparams, &_zetaij, + &this->nbor->dev_nbor, &this->_nbor_data->begin(), + &this->dev_short_nbor, + &_eflag, &this->_ainum, &nbor_pitch, &this->_threads_per_atom); + + ainum=this->ans->inum(); + nbor_pitch=this->nbor->nbor_pitch(); + GX=static_cast(ceil(static_cast(this->ans->inum())/ (BX/this->_threads_per_atom))); this->time_pair.start(); @@ -423,6 +431,7 @@ void TersoffT::loop(const bool _eflag, const bool _vflag, const int evatom) { this->k_three_center.run(&this->atom->x, &ts1, &ts2, &ts4, &cutsq, &map, &elem2param, &_nelements, &_nparams, &_zetaij, &this->nbor->dev_nbor, &this->_nbor_data->begin(), + &this->dev_short_nbor, &this->ans->force, &this->ans->engv, &eflag, &vflag, &ainum, &nbor_pitch, &this->_threads_per_atom, &evatom); @@ -437,7 +446,7 @@ void TersoffT::loop(const bool _eflag, const bool _vflag, const int evatom) { this->k_three_end_vatom.run(&this->atom->x, &ts1, &ts2, &ts4, &cutsq, &map, &elem2param, &_nelements, &_nparams, &_zetaij, &this->nbor->dev_nbor, &this->_nbor_data->begin(), - &this->nbor->dev_acc, + &this->nbor->dev_acc, &this->dev_short_nbor, &end_ans->force, &end_ans->engv, &eflag, &vflag, &ainum, &nbor_pitch, &this->_threads_per_atom, &this->_gpu_nbor); @@ -446,7 +455,7 @@ void TersoffT::loop(const bool _eflag, const bool _vflag, const int evatom) { this->k_three_end.run(&this->atom->x, &ts1, &ts2, &ts4, &cutsq, &map, &elem2param, &_nelements, &_nparams, &_zetaij, &this->nbor->dev_nbor, &this->_nbor_data->begin(), - &this->nbor->dev_acc, + &this->nbor->dev_acc, &this->dev_short_nbor, &end_ans->force, &end_ans->engv, &eflag, &vflag, &ainum, &nbor_pitch, &this->_threads_per_atom, &this->_gpu_nbor); } diff --git a/lib/gpu/lal_tersoff.cu b/lib/gpu/lal_tersoff.cu index b7d48d9e34..d132545984 100644 --- a/lib/gpu/lal_tersoff.cu +++ b/lib/gpu/lal_tersoff.cu @@ -164,6 +164,57 @@ texture ts5_tex; #endif +__kernel void k_tersoff_short_nbor(const __global numtyp4 *restrict x_, + const numtyp cutshortsq, + const __global int * dev_nbor, + const __global int * dev_packed, + __global int * dev_short_nbor, + const int inum, const int nbor_pitch, + const int t_per_atom) { + __local int n_stride; + int tid, ii, offset; + atom_info(t_per_atom,ii,tid,offset); + + if (ii { UCL_Kernel k_zeta; UCL_Texture ts1_tex, ts2_tex, ts3_tex, ts4_tex, ts5_tex; - - int _max_nbors; + numtyp _cutshortsq; private: bool _allocated; From 77c60189b8cd11d6f1f5329c6e22ff4d105b7c8a Mon Sep 17 00:00:00 2001 From: Trung Nguyen Date: Sat, 8 Jul 2017 14:43:53 -0500 Subject: [PATCH 252/439] Minor cleanups for tersoff/gpu --- lib/gpu/lal_tersoff.cpp | 3 ++- lib/gpu/lal_tersoff.cu | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/gpu/lal_tersoff.cpp b/lib/gpu/lal_tersoff.cpp index f1e0320b8c..d830499257 100644 --- a/lib/gpu/lal_tersoff.cpp +++ b/lib/gpu/lal_tersoff.cpp @@ -163,10 +163,11 @@ int TersoffT::init(const int ntypes, const int nlocal, const int nall, const int cutsq_view[i]=static_cast(host_cutsq[i]); if (cutsqmax < host_cutsq[i]) cutsqmax = host_cutsq[i]; } - _cutshortsq = static_cast(cutsqmax); cutsq.alloc(nparams,*(this->ucl_device),UCL_READ_ONLY); ucl_copy(cutsq,cutsq_view,false); + _cutshortsq = static_cast(cutsqmax); + UCL_H_Vec dview_elem2param(nelements*nelements*nelements, *(this->ucl_device), UCL_WRITE_ONLY); diff --git a/lib/gpu/lal_tersoff.cu b/lib/gpu/lal_tersoff.cu index d132545984..9faa59c34d 100644 --- a/lib/gpu/lal_tersoff.cu +++ b/lib/gpu/lal_tersoff.cu @@ -106,7 +106,7 @@ texture ts5_tex; ans[ii]=old; \ } -#define store_zeta(z, tid, t_per_atom, offset) \ +#define acc_zeta(z, tid, t_per_atom, offset) \ if (t_per_atom>1) { \ __local acctyp red_acc[BLOCK_PAIR]; \ red_acc[tid]=z; \ @@ -155,7 +155,7 @@ texture ts5_tex; ans[ii]=old; \ } -#define store_zeta(z, tid, t_per_atom, offset) \ +#define acc_zeta(z, tid, t_per_atom, offset) \ if (t_per_atom>1) { \ for (unsigned int s=t_per_atom/2; s>0; s>>=1) { \ z += shfl_xor(z, s, t_per_atom); \ @@ -348,7 +348,7 @@ __kernel void k_tersoff_zeta(const __global numtyp4 *restrict x_, int idx = nbor_j - n_stride; // zeta_idx(dev_nbor,dev_packed, nbor_pitch, n_stride, t_per_atom, // i, nbor_j, offset_j, idx); - store_zeta(z, tid, t_per_atom, offset_k); + acc_zeta(z, tid, t_per_atom, offset_k); numtyp4 ts1_ijparam = ts1[ijparam]; //fetch4(ts1_ijparam,ijparam,ts1_tex); numtyp ijparam_lam2 = ts1_ijparam.y; From 34fe2273f64bbee8f96ab91642106471ad77c25b Mon Sep 17 00:00:00 2001 From: Trung Nguyen Date: Sat, 8 Jul 2017 14:59:48 -0500 Subject: [PATCH 253/439] Added short neighbor list implementation for tersoff/zbl/gpu and tersoff/mod/gpu --- lib/gpu/lal_tersoff_mod.cpp | 58 +++++++++--- lib/gpu/lal_tersoff_mod.cu | 173 ++++++++++++++++++++++++++++-------- lib/gpu/lal_tersoff_mod.h | 3 +- lib/gpu/lal_tersoff_zbl.cpp | 58 +++++++++--- lib/gpu/lal_tersoff_zbl.cu | 171 +++++++++++++++++++++++++++-------- lib/gpu/lal_tersoff_zbl.h | 2 +- 6 files changed, 365 insertions(+), 100 deletions(-) diff --git a/lib/gpu/lal_tersoff_mod.cpp b/lib/gpu/lal_tersoff_mod.cpp index 553dad3583..ba1804c37e 100644 --- a/lib/gpu/lal_tersoff_mod.cpp +++ b/lib/gpu/lal_tersoff_mod.cpp @@ -55,7 +55,8 @@ int TersoffMT::init(const int ntypes, const int nlocal, const int nall, const in int success; success=this->init_three(nlocal,nall,max_nbors,0,cell_size,gpu_split, _screen,tersoff_mod,"k_tersoff_mod_repulsive", - "k_tersoff_mod_three_center", "k_tersoff_mod_three_end"); + "k_tersoff_mod_three_center", "k_tersoff_mod_three_end", + "k_tersoff_mod_short_nbor"); if (success!=0) return success; @@ -157,11 +158,16 @@ int TersoffMT::init(const int ntypes, const int nlocal, const int nall, const in UCL_H_Vec cutsq_view(nparams,*(this->ucl_device), UCL_WRITE_ONLY); - for (int i=0; i(host_cutsq[i]); + if (cutsqmax < host_cutsq[i]) cutsqmax = host_cutsq[i]; + } cutsq.alloc(nparams,*(this->ucl_device),UCL_READ_ONLY); ucl_copy(cutsq,cutsq_view,false); + _cutshortsq = static_cast(cutsqmax); + UCL_H_Vec dview_elem2param(nelements*nelements*nelements, *(this->ucl_device), UCL_WRITE_ONLY); @@ -250,7 +256,7 @@ void TersoffMT::compute(const int f_ago, const int inum_full, const int nall, this->reset_nbors(nall, inum, nlist, ilist, numj, firstneigh, success); if (!success) return; - _max_nbors = this->nbor->max_nbor_loop(nlist,numj,ilist); + this->_max_nbors = this->nbor->max_nbor_loop(nlist,numj,ilist); } this->atom->cast_x_data(host_x,host_type); @@ -258,11 +264,13 @@ void TersoffMT::compute(const int f_ago, const int inum_full, const int nall, this->atom->add_x_data(host_x,host_type); // re-allocate zetaij if necessary - if (nall*_max_nbors > _zetaij.cols()) { + if (nall*this->_max_nbors > _zetaij.cols()) { int _nmax=static_cast(static_cast(nall)*1.10); - _zetaij.resize(_max_nbors*_nmax); + _zetaij.resize(this->_max_nbors*_nmax); } + this->_ainum=nlist; + int _eflag; if (eflag) _eflag=1; @@ -329,7 +337,7 @@ int ** TersoffMT::compute(const int ago, const int inum_full, // Build neighbor list on GPU if necessary if (ago==0) { - _max_nbors = this->build_nbor_list(inum, inum_full-inum, nall, host_x, host_type, + this->_max_nbors = this->build_nbor_list(inum, inum_full-inum, nall, host_x, host_type, sublo, subhi, tag, nspecial, special, success); if (!success) return NULL; @@ -343,11 +351,13 @@ int ** TersoffMT::compute(const int ago, const int inum_full, *jnum=this->nbor->host_acc.begin(); // re-allocate zetaij if necessary - if (nall*_max_nbors > _zetaij.cols()) { + if (nall*this->_max_nbors > _zetaij.cols()) { int _nmax=static_cast(static_cast(nall)*1.10); - _zetaij.resize(_max_nbors*_nmax); + _zetaij.resize(this->_max_nbors*_nmax); } + this->_ainum=nall; + int _eflag; if (eflag) _eflag=1; @@ -402,9 +412,32 @@ void TersoffMT::loop(const bool _eflag, const bool _vflag, const int evatom) { else vflag=0; - int ainum=this->ans->inum(); + // build the short neighbor list + int ainum=this->_ainum; int nbor_pitch=this->nbor->nbor_pitch(); - int GX=static_cast(ceil(static_cast(this->ans->inum())/ + int GX=static_cast(ceil(static_cast(ainum)/ + (BX/this->_threads_per_atom))); + + this->k_short_nbor.set_size(GX,BX); + this->k_short_nbor.run(&this->atom->x, &_cutshortsq, + &this->nbor->dev_nbor, &this->_nbor_data->begin(), + &this->dev_short_nbor, &ainum, + &nbor_pitch, &this->_threads_per_atom); + + nbor_pitch=this->nbor->nbor_pitch(); + GX=static_cast(ceil(static_cast(this->_ainum)/ + (BX/(JTHREADS*KTHREADS)))); + + this->k_zeta.set_size(GX,BX); + this->k_zeta.run(&this->atom->x, &ts1, &ts2, &ts3, &ts4, &ts5, &cutsq, + &map, &elem2param, &_nelements, &_nparams, &_zetaij, + &this->nbor->dev_nbor, &this->_nbor_data->begin(), + &this->dev_short_nbor, + &_eflag, &this->_ainum, &nbor_pitch, &this->_threads_per_atom); + + ainum=this->ans->inum(); + nbor_pitch=this->nbor->nbor_pitch(); + GX=static_cast(ceil(static_cast(this->ans->inum())/ (BX/this->_threads_per_atom))); this->time_pair.start(); @@ -423,6 +456,7 @@ void TersoffMT::loop(const bool _eflag, const bool _vflag, const int evatom) { this->k_three_center.run(&this->atom->x, &ts1, &ts2, &ts4, &ts5, &cutsq, &map, &elem2param, &_nelements, &_nparams, &_zetaij, &this->nbor->dev_nbor, &this->_nbor_data->begin(), + &this->dev_short_nbor, &this->ans->force, &this->ans->engv, &eflag, &vflag, &ainum, &nbor_pitch, &this->_threads_per_atom, &evatom); @@ -437,7 +471,7 @@ void TersoffMT::loop(const bool _eflag, const bool _vflag, const int evatom) { this->k_three_end_vatom.run(&this->atom->x, &ts1, &ts2, &ts4, &ts5, &cutsq, &map, &elem2param, &_nelements, &_nparams, &_zetaij, &this->nbor->dev_nbor, &this->_nbor_data->begin(), - &this->nbor->dev_acc, + &this->nbor->dev_acc, &this->dev_short_nbor, &end_ans->force, &end_ans->engv, &eflag, &vflag, &ainum, &nbor_pitch, &this->_threads_per_atom, &this->_gpu_nbor); @@ -446,7 +480,7 @@ void TersoffMT::loop(const bool _eflag, const bool _vflag, const int evatom) { this->k_three_end.run(&this->atom->x, &ts1, &ts2, &ts4, &ts5, &cutsq, &map, &elem2param, &_nelements, &_nparams, &_zetaij, &this->nbor->dev_nbor, &this->_nbor_data->begin(), - &this->nbor->dev_acc, + &this->nbor->dev_acc, &this->dev_short_nbor, &end_ans->force, &end_ans->engv, &eflag, &vflag, &ainum, &nbor_pitch, &this->_threads_per_atom, &this->_gpu_nbor); } diff --git a/lib/gpu/lal_tersoff_mod.cu b/lib/gpu/lal_tersoff_mod.cu index 3a81b36941..75bacc2179 100644 --- a/lib/gpu/lal_tersoff_mod.cu +++ b/lib/gpu/lal_tersoff_mod.cu @@ -106,7 +106,7 @@ texture ts5_tex; ans[ii]=old; \ } -#define store_zeta(z, tid, t_per_atom, offset) \ +#define acc_zeta(z, tid, t_per_atom, offset) \ if (t_per_atom>1) { \ __local acctyp red_acc[BLOCK_PAIR]; \ red_acc[tid]=z; \ @@ -155,7 +155,7 @@ texture ts5_tex; ans[ii]=old; \ } -#define store_zeta(z, tid, t_per_atom, offset) \ +#define acc_zeta(z, tid, t_per_atom, offset) \ if (t_per_atom>1) { \ for (unsigned int s=t_per_atom/2; s>0; s>>=1) { \ z += shfl_xor(z, s, t_per_atom); \ @@ -164,6 +164,57 @@ texture ts5_tex; #endif +__kernel void k_tersoff_mod_short_nbor(const __global numtyp4 *restrict x_, + const numtyp cutshortsq, + const __global int * dev_nbor, + const __global int * dev_packed, + __global int * dev_short_nbor, + const int inum, const int nbor_pitch, + const int t_per_atom) { + __local int n_stride; + int tid, ii, offset; + atom_info(t_per_atom,ii,tid,offset); + + if (ii cutsq[ijparam]) continue; // compute zeta_ij - z = (numtyp)0; + z = (acctyp)0; int nbor_k = nborj_start-offset_j+offset_k; - for ( ; nbor_k < nbor_end; nbor_k+=n_stride) { - int k=dev_packed[nbor_k]; + int numk = dev_short_nbor[nbor_k-n_stride]; + int k_end = nbor_k+fast_mul(numk,n_stride); + + for ( ; nbor_k < k_end; nbor_k+=n_stride) { + int k=dev_short_nbor[nbor_k]; k &= NEIGHMASK; if (k == j) continue; @@ -287,10 +347,11 @@ __kernel void k_tersoff_mod_zeta(const __global numtyp4 *restrict x_, //int jj = (nbor_j-offset_j-2*nbor_pitch)/n_stride; //int idx = jj*n_stride + i*t_per_atom + offset_j; - int idx; - zeta_idx(dev_nbor,dev_packed, nbor_pitch, n_stride, t_per_atom, - i, nbor_j, offset_j, idx); - store_zeta(z, tid, t_per_atom, offset_k); + //idx to zetaij is shifted by n_stride relative to nbor_j in dev_short_nbor + int idx = nbor_j - n_stride; +// zeta_idx(dev_nbor,dev_packed, nbor_pitch, n_stride, t_per_atom, +// i, nbor_j, offset_j, idx); + acc_zeta(z, tid, t_per_atom, offset_k); numtyp4 ts1_ijparam = ts1[ijparam]; //fetch4(ts1_ijparam,ijparam,ts1_tex); numtyp ijparam_lam2 = ts1_ijparam.y; @@ -430,6 +491,7 @@ __kernel void k_tersoff_mod_three_center(const __global numtyp4 *restrict x_, const __global acctyp4 *restrict zetaij, const __global int * dev_nbor, const __global int * dev_packed, + const __global int * dev_short_nbor, __global acctyp4 *restrict ans, __global acctyp *restrict engv, const int eflag, const int vflag, @@ -470,15 +532,20 @@ __kernel void k_tersoff_mod_three_center(const __global numtyp4 *restrict x_, nbor_info(dev_nbor,dev_packed,nbor_pitch,t_per_atom,ii,offset_j,i,numj, n_stride,nbor_end,nbor_j); int offset_k=tid & (t_per_atom-1); - int nborj_start = nbor_j; numtyp4 ix; fetch4(ix,i,pos_tex); //x_[i]; int itype=ix.w; itype=map[itype]; + // recalculate numj and nbor_end for use of the short nbor list + numj = dev_short_nbor[nbor_j]; + nbor_j += n_stride; + int nborj_start = nbor_j; + nbor_end = nbor_j+fast_mul(numj,n_stride); + for ( ; nbor_j { UCL_Kernel k_zeta; UCL_Texture ts1_tex, ts2_tex, ts3_tex, ts4_tex, ts5_tex; - - int _max_nbors; + numtyp _cutshortsq; private: bool _allocated; diff --git a/lib/gpu/lal_tersoff_zbl.cpp b/lib/gpu/lal_tersoff_zbl.cpp index 9cce8a802d..6efa8b9487 100644 --- a/lib/gpu/lal_tersoff_zbl.cpp +++ b/lib/gpu/lal_tersoff_zbl.cpp @@ -62,7 +62,8 @@ int TersoffZT::init(const int ntypes, const int nlocal, const int nall, int success; success=this->init_three(nlocal,nall,max_nbors,0,cell_size,gpu_split, _screen,tersoff_zbl,"k_tersoff_zbl_repulsive", - "k_tersoff_zbl_three_center", "k_tersoff_zbl_three_end"); + "k_tersoff_zbl_three_center", "k_tersoff_zbl_three_end", + "k_tersoff_zbl_short_nbor"); if (success!=0) return success; @@ -177,11 +178,16 @@ int TersoffZT::init(const int ntypes, const int nlocal, const int nall, UCL_H_Vec cutsq_view(nparams,*(this->ucl_device), UCL_WRITE_ONLY); - for (int i=0; i(host_cutsq[i]); + if (cutsqmax < host_cutsq[i]) cutsqmax = host_cutsq[i]; + } cutsq.alloc(nparams,*(this->ucl_device),UCL_READ_ONLY); ucl_copy(cutsq,cutsq_view,false); + _cutshortsq = static_cast(cutsqmax); + UCL_H_Vec dview_elem2param(nelements*nelements*nelements, *(this->ucl_device), UCL_WRITE_ONLY); @@ -275,7 +281,7 @@ void TersoffZT::compute(const int f_ago, const int inum_full, const int nall, this->reset_nbors(nall, inum, nlist, ilist, numj, firstneigh, success); if (!success) return; - _max_nbors = this->nbor->max_nbor_loop(nlist,numj,ilist); + this->_max_nbors = this->nbor->max_nbor_loop(nlist,numj,ilist); } this->atom->cast_x_data(host_x,host_type); @@ -283,11 +289,13 @@ void TersoffZT::compute(const int f_ago, const int inum_full, const int nall, this->atom->add_x_data(host_x,host_type); // re-allocate zetaij if necessary - if (nall*_max_nbors > _zetaij.cols()) { + if (nall*this->_max_nbors > _zetaij.cols()) { int _nmax=static_cast(static_cast(nall)*1.10); - _zetaij.resize(_max_nbors*_nmax); + _zetaij.resize(this->_max_nbors*_nmax); } + this->_ainum=nlist; + int _eflag; if (eflag) _eflag=1; @@ -354,7 +362,7 @@ int ** TersoffZT::compute(const int ago, const int inum_full, // Build neighbor list on GPU if necessary if (ago==0) { - _max_nbors = this->build_nbor_list(inum, inum_full-inum, nall, host_x, host_type, + this->_max_nbors = this->build_nbor_list(inum, inum_full-inum, nall, host_x, host_type, sublo, subhi, tag, nspecial, special, success); if (!success) return NULL; @@ -368,11 +376,13 @@ int ** TersoffZT::compute(const int ago, const int inum_full, *jnum=this->nbor->host_acc.begin(); // re-allocate zetaij if necessary - if (nall*_max_nbors > _zetaij.cols()) { + if (nall*this->_max_nbors > _zetaij.cols()) { int _nmax=static_cast(static_cast(nall)*1.10); - _zetaij.resize(_max_nbors*_nmax); + _zetaij.resize(this->_max_nbors*_nmax); } + this->_ainum=nall; + int _eflag; if (eflag) _eflag=1; @@ -427,9 +437,32 @@ void TersoffZT::loop(const bool _eflag, const bool _vflag, const int evatom) { else vflag=0; - int ainum=this->ans->inum(); + // build the short neighbor list + int ainum=this->_ainum; int nbor_pitch=this->nbor->nbor_pitch(); - int GX=static_cast(ceil(static_cast(this->ans->inum())/ + int GX=static_cast(ceil(static_cast(ainum)/ + (BX/this->_threads_per_atom))); + + this->k_short_nbor.set_size(GX,BX); + this->k_short_nbor.run(&this->atom->x, &_cutshortsq, + &this->nbor->dev_nbor, &this->_nbor_data->begin(), + &this->dev_short_nbor, &ainum, + &nbor_pitch, &this->_threads_per_atom); + + nbor_pitch=this->nbor->nbor_pitch(); + GX=static_cast(ceil(static_cast(this->_ainum)/ + (BX/(JTHREADS*KTHREADS)))); + + this->k_zeta.set_size(GX,BX); + this->k_zeta.run(&this->atom->x, &ts1, &ts2, &ts3, &ts4, &ts5, &cutsq, + &map, &elem2param, &_nelements, &_nparams, &_zetaij, + &this->nbor->dev_nbor, &this->_nbor_data->begin(), + &this->dev_short_nbor, + &_eflag, &this->_ainum, &nbor_pitch, &this->_threads_per_atom); + + ainum=this->ans->inum(); + nbor_pitch=this->nbor->nbor_pitch(); + GX=static_cast(ceil(static_cast(this->ans->inum())/ (BX/this->_threads_per_atom))); this->time_pair.start(); @@ -449,6 +482,7 @@ void TersoffZT::loop(const bool _eflag, const bool _vflag, const int evatom) { this->k_three_center.run(&this->atom->x, &ts1, &ts2, &ts4, &cutsq, &map, &elem2param, &_nelements, &_nparams, &_zetaij, &this->nbor->dev_nbor, &this->_nbor_data->begin(), + &this->dev_short_nbor, &this->ans->force, &this->ans->engv, &eflag, &vflag, &ainum, &nbor_pitch, &this->_threads_per_atom, &evatom); @@ -463,7 +497,7 @@ void TersoffZT::loop(const bool _eflag, const bool _vflag, const int evatom) { this->k_three_end_vatom.run(&this->atom->x, &ts1, &ts2, &ts4, &cutsq, &map, &elem2param, &_nelements, &_nparams, &_zetaij, &this->nbor->dev_nbor, &this->_nbor_data->begin(), - &this->nbor->dev_acc, + &this->nbor->dev_acc, &this->dev_short_nbor, &end_ans->force, &end_ans->engv, &eflag, &vflag, &ainum, &nbor_pitch, &this->_threads_per_atom, &this->_gpu_nbor); @@ -472,7 +506,7 @@ void TersoffZT::loop(const bool _eflag, const bool _vflag, const int evatom) { this->k_three_end.run(&this->atom->x, &ts1, &ts2, &ts4, &cutsq, &map, &elem2param, &_nelements, &_nparams, &_zetaij, &this->nbor->dev_nbor, &this->_nbor_data->begin(), - &this->nbor->dev_acc, + &this->nbor->dev_acc, &this->dev_short_nbor, &end_ans->force, &end_ans->engv, &eflag, &vflag, &ainum, &nbor_pitch, &this->_threads_per_atom, &this->_gpu_nbor); } diff --git a/lib/gpu/lal_tersoff_zbl.cu b/lib/gpu/lal_tersoff_zbl.cu index 9509b9802c..439d4028df 100644 --- a/lib/gpu/lal_tersoff_zbl.cu +++ b/lib/gpu/lal_tersoff_zbl.cu @@ -109,7 +109,7 @@ texture ts6_tex; ans[ii]=old; \ } -#define store_zeta(z, tid, t_per_atom, offset) \ +#define acc_zeta(z, tid, t_per_atom, offset) \ if (t_per_atom>1) { \ __local acctyp red_acc[BLOCK_PAIR]; \ red_acc[tid]=z; \ @@ -158,7 +158,7 @@ texture ts6_tex; ans[ii]=old; \ } -#define store_zeta(z, tid, t_per_atom, offset) \ +#define acc_zeta(z, tid, t_per_atom, offset) \ if (t_per_atom>1) { \ for (unsigned int s=t_per_atom/2; s>0; s>>=1) { \ z += shfl_xor(z, s, t_per_atom); \ @@ -167,6 +167,57 @@ texture ts6_tex; #endif +__kernel void k_tersoff_zbl_short_nbor(const __global numtyp4 *restrict x_, + const numtyp cutshortsq, + const __global int * dev_nbor, + const __global int * dev_packed, + __global int * dev_short_nbor, + const int inum, const int nbor_pitch, + const int t_per_atom) { + __local int n_stride; + int tid, ii, offset; + atom_info(t_per_atom,ii,tid,offset); + + if (ii { UCL_Kernel k_zeta; UCL_Texture ts1_tex, ts2_tex, ts3_tex, ts4_tex, ts5_tex, ts6_tex; - int _max_nbors; numtyp _global_e,_global_a_0,_global_epsilon_0; + numtyp _cutshortsq; private: bool _allocated; From ea2b01e83b910d29ef487ff51c88b22d8059d434 Mon Sep 17 00:00:00 2001 From: Trung Nguyen Date: Sat, 8 Jul 2017 20:17:31 -0500 Subject: [PATCH 254/439] Refactored 3-body gpu styles to remove code duplication --- lib/gpu/lal_base_three.cpp | 4 + lib/gpu/lal_base_three.h | 6 +- lib/gpu/lal_tersoff.cpp | 152 ++----------------------------- lib/gpu/lal_tersoff.h | 15 --- lib/gpu/lal_tersoff_mod.cpp | 176 ++---------------------------------- lib/gpu/lal_tersoff_mod.h | 15 --- lib/gpu/lal_tersoff_zbl.cpp | 176 ++---------------------------------- lib/gpu/lal_tersoff_zbl.h | 15 --- 8 files changed, 28 insertions(+), 531 deletions(-) diff --git a/lib/gpu/lal_base_three.cpp b/lib/gpu/lal_base_three.cpp index fd9fc7f272..4e8a95937c 100644 --- a/lib/gpu/lal_base_three.cpp +++ b/lib/gpu/lal_base_three.cpp @@ -180,6 +180,8 @@ int * BaseThreeT::reset_nbors(const int nall, const int inum, const int nlist, if (!success) return NULL; + _nall = nall; + // originally the requirement that nall == nlist was enforced // to allow direct indexing neighbors of neighbors after re-arrangement // nbor->get_host3(nall,nlist,ilist,numj,firstneigh,block_size()); @@ -214,6 +216,8 @@ inline int BaseThreeT::build_nbor_list(const int inum, const int host_inum, return 0; atom->cast_copy_x(host_x,host_type); + _nall = nall; + int mn; nbor->build_nbor_list(host_x, nall, host_inum, nall, *atom, sublo, subhi, tag, nspecial, special, success, mn); diff --git a/lib/gpu/lal_base_three.h b/lib/gpu/lal_base_three.h index d03a7521cd..fde1936b25 100644 --- a/lib/gpu/lal_base_three.h +++ b/lib/gpu/lal_base_three.h @@ -74,7 +74,7 @@ class BaseThree { } /// Check if there is enough storage for neighbors and realloc if not - /** \param nlocal number of particles whose nbors must be stored on device + /** \param inum number of particles whose nbors must be stored on device * \param max_nbors maximum number of neighbors * \param success set to false if insufficient memory * \note olist_size=total number of local particles **/ @@ -83,7 +83,7 @@ class BaseThree { } /// Check if there is enough storage for neighbors and realloc if not - /** \param nlocal number of particles whose nbors must be stored on device + /** \param inum number of particles whose nbors must be stored on device * \param host_inum number of particles whose nbors need to copied to host * \param max_nbors current maximum number of neighbors * \note host_inum is 0 if the host is performing neighboring @@ -203,7 +203,7 @@ class BaseThree { int _block_pair, _block_size, _threads_per_atom, _end_command_queue; int _gpu_nbor; double _max_bytes, _max_an_bytes; - int _max_nbors, _ainum; + int _max_nbors, _ainum, _nall; double _gpu_overhead, _driver_overhead; UCL_D_Vec *_nbor_data; diff --git a/lib/gpu/lal_tersoff.cpp b/lib/gpu/lal_tersoff.cpp index d830499257..cb4a3fdbd6 100644 --- a/lib/gpu/lal_tersoff.cpp +++ b/lib/gpu/lal_tersoff.cpp @@ -225,151 +225,6 @@ double TersoffT::host_memory_usage() const { #define KTHREADS this->_threads_per_atom #define JTHREADS this->_threads_per_atom -// --------------------------------------------------------------------------- -// Copy nbor list from host if necessary and then calculate forces, virials,.. -// --------------------------------------------------------------------------- -template -void TersoffT::compute(const int f_ago, const int inum_full, const int nall, - const int nlist, double **host_x, int *host_type, - int *ilist, int *numj, int **firstneigh, - const bool eflag, const bool vflag, const bool eatom, - const bool vatom, int &host_start, - const double cpu_time, bool &success) { - this->acc_timers(); - if (inum_full==0) { - host_start=0; - // Make sure textures are correct if realloc by a different hybrid style - this->resize_atom(0,nall,success); - this->zero_timers(); - return; - } - - int ago=this->hd_balancer.ago_first(f_ago); - int inum=this->hd_balancer.balance(ago,inum_full,cpu_time); - this->ans->inum(inum); - #ifdef THREE_CONCURRENT - this->ans2->inum(inum); - #endif - host_start=inum; - - if (ago==0) { - this->reset_nbors(nall, inum, nlist, ilist, numj, firstneigh, success); - if (!success) - return; - this->_max_nbors = this->nbor->max_nbor_loop(nlist,numj,ilist); - } - - this->atom->cast_x_data(host_x,host_type); - this->hd_balancer.start_timer(); - this->atom->add_x_data(host_x,host_type); - - // re-allocate zetaij if necessary - if (nall*this->_max_nbors > _zetaij.cols()) { - int _nmax=static_cast(static_cast(nall)*1.10); - _zetaij.resize(this->_max_nbors*_nmax); - } - - this->_ainum=nlist; - - int _eflag; - if (eflag) - _eflag=1; - else - _eflag=0; - - int evatom=0; - if (eatom || vatom) - evatom=1; - #ifdef THREE_CONCURRENT - this->ucl_device->sync(); - #endif - loop(eflag,vflag,evatom); - this->ans->copy_answers(eflag,vflag,eatom,vatom,ilist); - this->device->add_ans_object(this->ans); - #ifdef THREE_CONCURRENT - this->ans2->copy_answers(eflag,vflag,eatom,vatom,ilist); - this->device->add_ans_object(this->ans2); - #endif - this->hd_balancer.stop_timer(); -} - -// --------------------------------------------------------------------------- -// Reneighbor on GPU if necessary and then compute forces, virials, energies -// --------------------------------------------------------------------------- -template -int ** TersoffT::compute(const int ago, const int inum_full, - const int nall, double **host_x, int *host_type, - double *sublo, double *subhi, tagint *tag, - int **nspecial, tagint **special, const bool eflag, - const bool vflag, const bool eatom, - const bool vatom, int &host_start, - int **ilist, int **jnum, - const double cpu_time, bool &success) { - this->acc_timers(); - - if (inum_full==0) { - host_start=0; - // Make sure textures are correct if realloc by a different hybrid style - this->resize_atom(0,nall,success); - this->zero_timers(); - return NULL; - } - - this->hd_balancer.balance(cpu_time); - int inum=this->hd_balancer.get_gpu_count(ago,inum_full); - this->ans->inum(inum); - #ifdef THREE_CONCURRENT - this->ans2->inum(inum); - #endif - host_start=inum; - - // Build neighbor list on GPU if necessary - if (ago==0) { - this->_max_nbors = this->build_nbor_list(inum, inum_full-inum, nall, host_x, host_type, - sublo, subhi, tag, nspecial, special, success); - if (!success) - return NULL; - this->hd_balancer.start_timer(); - } else { - this->atom->cast_x_data(host_x,host_type); - this->hd_balancer.start_timer(); - this->atom->add_x_data(host_x,host_type); - } - *ilist=this->nbor->host_ilist.begin(); - *jnum=this->nbor->host_acc.begin(); - - // re-allocate zetaij if necessary - if (nall*this->_max_nbors > _zetaij.cols()) { - int _nmax=static_cast(static_cast(nall)*1.10); - _zetaij.resize(this->_max_nbors*_nmax); - } - - this->_ainum=nall; - - int _eflag; - if (eflag) - _eflag=1; - else - _eflag=0; - - int evatom=0; - if (eatom || vatom) - evatom=1; - #ifdef THREE_CONCURRENT - this->ucl_device->sync(); - #endif - loop(eflag,vflag,evatom); - this->ans->copy_answers(eflag,vflag,eatom,vatom); - this->device->add_ans_object(this->ans); - #ifdef THREE_CONCURRENT - this->ans2->copy_answers(eflag,vflag,eatom,vatom); - this->device->add_ans_object(this->ans2); - #endif - this->hd_balancer.stop_timer(); - - return this->nbor->host_jlist.begin()-host_start; -} - // --------------------------------------------------------------------------- // Calculate energies, forces, and torques // --------------------------------------------------------------------------- @@ -400,6 +255,13 @@ void TersoffT::loop(const bool _eflag, const bool _vflag, const int evatom) { &this->dev_short_nbor, &ainum, &nbor_pitch, &this->_threads_per_atom); + // re-allocate zetaij if necessary + int nall = this->_nall; + if (nall*this->_max_nbors > _zetaij.cols()) { + int _nmax=static_cast(static_cast(nall)*1.10); + _zetaij.resize(this->_max_nbors*_nmax); + } + nbor_pitch=this->nbor->nbor_pitch(); GX=static_cast(ceil(static_cast(this->_ainum)/ (BX/(JTHREADS*KTHREADS)))); diff --git a/lib/gpu/lal_tersoff.h b/lib/gpu/lal_tersoff.h index 5e2bedfeef..fd01af031a 100644 --- a/lib/gpu/lal_tersoff.h +++ b/lib/gpu/lal_tersoff.h @@ -47,21 +47,6 @@ class Tersoff : public BaseThree { const double* h, const double* gamma, const double* beta, const double* powern, const double* cutsq); - /// Pair loop with host neighboring - void compute(const int f_ago, const int inum_full, const int nall, - const int nlist, double **host_x, int *host_type, - int *ilist, int *numj, int **firstneigh, const bool eflag, - const bool vflag, const bool eatom, const bool vatom, - int &host_start, const double cpu_time, bool &success); - - /// Pair loop with device neighboring - int ** compute(const int ago, const int inum_full, - const int nall, double **host_x, int *host_type, double *sublo, - double *subhi, tagint *tag, int **nspecial, - tagint **special, const bool eflag, const bool vflag, - const bool eatom, const bool vatom, int &host_start, - int **ilist, int **numj, const double cpu_time, bool &success); - /// Clear all host and device data /** \note This is called at the beginning of the init() routine **/ void clear(); diff --git a/lib/gpu/lal_tersoff_mod.cpp b/lib/gpu/lal_tersoff_mod.cpp index ba1804c37e..02000d77d3 100644 --- a/lib/gpu/lal_tersoff_mod.cpp +++ b/lib/gpu/lal_tersoff_mod.cpp @@ -225,175 +225,6 @@ double TersoffMT::host_memory_usage() const { #define KTHREADS this->_threads_per_atom #define JTHREADS this->_threads_per_atom -// --------------------------------------------------------------------------- -// Copy nbor list from host if necessary and then calculate forces, virials,.. -// --------------------------------------------------------------------------- -template -void TersoffMT::compute(const int f_ago, const int inum_full, const int nall, - const int nlist, double **host_x, int *host_type, - int *ilist, int *numj, int **firstneigh, - const bool eflag, const bool vflag, const bool eatom, - const bool vatom, int &host_start, - const double cpu_time, bool &success) { - this->acc_timers(); - if (inum_full==0) { - host_start=0; - // Make sure textures are correct if realloc by a different hybrid style - this->resize_atom(0,nall,success); - this->zero_timers(); - return; - } - - int ago=this->hd_balancer.ago_first(f_ago); - int inum=this->hd_balancer.balance(ago,inum_full,cpu_time); - this->ans->inum(inum); - #ifdef THREE_CONCURRENT - this->ans2->inum(inum); - #endif - host_start=inum; - - if (ago==0) { - this->reset_nbors(nall, inum, nlist, ilist, numj, firstneigh, success); - if (!success) - return; - this->_max_nbors = this->nbor->max_nbor_loop(nlist,numj,ilist); - } - - this->atom->cast_x_data(host_x,host_type); - this->hd_balancer.start_timer(); - this->atom->add_x_data(host_x,host_type); - - // re-allocate zetaij if necessary - if (nall*this->_max_nbors > _zetaij.cols()) { - int _nmax=static_cast(static_cast(nall)*1.10); - _zetaij.resize(this->_max_nbors*_nmax); - } - - this->_ainum=nlist; - - int _eflag; - if (eflag) - _eflag=1; - else - _eflag=0; - - int ainum=nlist; - int nbor_pitch=this->nbor->nbor_pitch(); - int BX=this->block_pair(); - int GX=static_cast(ceil(static_cast(ainum)/ - (BX/(JTHREADS*KTHREADS)))); - - this->k_zeta.set_size(GX,BX); - this->k_zeta.run(&this->atom->x, &ts1, &ts2, &ts3, &ts4, &ts5, &cutsq, - &map, &elem2param, &_nelements, &_nparams, &_zetaij, - &this->nbor->dev_nbor, &this->_nbor_data->begin(), - &_eflag, &ainum, &nbor_pitch, &this->_threads_per_atom); - - int evatom=0; - if (eatom || vatom) - evatom=1; - #ifdef THREE_CONCURRENT - this->ucl_device->sync(); - #endif - loop(eflag,vflag,evatom); - this->ans->copy_answers(eflag,vflag,eatom,vatom,ilist); - this->device->add_ans_object(this->ans); - #ifdef THREE_CONCURRENT - this->ans2->copy_answers(eflag,vflag,eatom,vatom,ilist); - this->device->add_ans_object(this->ans2); - #endif - this->hd_balancer.stop_timer(); -} - -// --------------------------------------------------------------------------- -// Reneighbor on GPU if necessary and then compute forces, virials, energies -// --------------------------------------------------------------------------- -template -int ** TersoffMT::compute(const int ago, const int inum_full, - const int nall, double **host_x, int *host_type, - double *sublo, double *subhi, tagint *tag, - int **nspecial, tagint **special, const bool eflag, - const bool vflag, const bool eatom, - const bool vatom, int &host_start, - int **ilist, int **jnum, - const double cpu_time, bool &success) { - this->acc_timers(); - - if (inum_full==0) { - host_start=0; - // Make sure textures are correct if realloc by a different hybrid style - this->resize_atom(0,nall,success); - this->zero_timers(); - return NULL; - } - - this->hd_balancer.balance(cpu_time); - int inum=this->hd_balancer.get_gpu_count(ago,inum_full); - this->ans->inum(inum); - #ifdef THREE_CONCURRENT - this->ans2->inum(inum); - #endif - host_start=inum; - - // Build neighbor list on GPU if necessary - if (ago==0) { - this->_max_nbors = this->build_nbor_list(inum, inum_full-inum, nall, host_x, host_type, - sublo, subhi, tag, nspecial, special, success); - if (!success) - return NULL; - this->hd_balancer.start_timer(); - } else { - this->atom->cast_x_data(host_x,host_type); - this->hd_balancer.start_timer(); - this->atom->add_x_data(host_x,host_type); - } - *ilist=this->nbor->host_ilist.begin(); - *jnum=this->nbor->host_acc.begin(); - - // re-allocate zetaij if necessary - if (nall*this->_max_nbors > _zetaij.cols()) { - int _nmax=static_cast(static_cast(nall)*1.10); - _zetaij.resize(this->_max_nbors*_nmax); - } - - this->_ainum=nall; - - int _eflag; - if (eflag) - _eflag=1; - else - _eflag=0; - - int ainum=nall; - int nbor_pitch=this->nbor->nbor_pitch(); - int BX=this->block_pair(); - int GX=static_cast(ceil(static_cast(ainum)/ - (BX/(JTHREADS*KTHREADS)))); - - this->k_zeta.set_size(GX,BX); - this->k_zeta.run(&this->atom->x, &ts1, &ts2, &ts3, &ts4, &ts5, &cutsq, - &map, &elem2param, &_nelements, &_nparams, &_zetaij, - &this->nbor->dev_nbor, &this->_nbor_data->begin(), - &_eflag, &ainum, &nbor_pitch, &this->_threads_per_atom); - - int evatom=0; - if (eatom || vatom) - evatom=1; - #ifdef THREE_CONCURRENT - this->ucl_device->sync(); - #endif - loop(eflag,vflag,evatom); - this->ans->copy_answers(eflag,vflag,eatom,vatom); - this->device->add_ans_object(this->ans); - #ifdef THREE_CONCURRENT - this->ans2->copy_answers(eflag,vflag,eatom,vatom); - this->device->add_ans_object(this->ans2); - #endif - this->hd_balancer.stop_timer(); - - return this->nbor->host_jlist.begin()-host_start; -} - // --------------------------------------------------------------------------- // Calculate energies, forces, and torques // --------------------------------------------------------------------------- @@ -424,6 +255,13 @@ void TersoffMT::loop(const bool _eflag, const bool _vflag, const int evatom) { &this->dev_short_nbor, &ainum, &nbor_pitch, &this->_threads_per_atom); + // re-allocate zetaij if necessary + int nall = this->_nall; + if (nall*this->_max_nbors > _zetaij.cols()) { + int _nmax=static_cast(static_cast(nall)*1.10); + _zetaij.resize(this->_max_nbors*_nmax); + } + nbor_pitch=this->nbor->nbor_pitch(); GX=static_cast(ceil(static_cast(this->_ainum)/ (BX/(JTHREADS*KTHREADS)))); diff --git a/lib/gpu/lal_tersoff_mod.h b/lib/gpu/lal_tersoff_mod.h index 286a23fa6f..ab1560d951 100644 --- a/lib/gpu/lal_tersoff_mod.h +++ b/lib/gpu/lal_tersoff_mod.h @@ -47,21 +47,6 @@ class TersoffMod : public BaseThree { const double* h, const double* beta, const double* powern, const double* powern_del, const double* ca1, const double* cutsq); - /// Pair loop with host neighboring - void compute(const int f_ago, const int inum_full, const int nall, - const int nlist, double **host_x, int *host_type, - int *ilist, int *numj, int **firstneigh, const bool eflag, - const bool vflag, const bool eatom, const bool vatom, - int &host_start, const double cpu_time, bool &success); - - /// Pair loop with device neighboring - int ** compute(const int ago, const int inum_full, - const int nall, double **host_x, int *host_type, double *sublo, - double *subhi, tagint *tag, int **nspecial, - tagint **special, const bool eflag, const bool vflag, - const bool eatom, const bool vatom, int &host_start, - int **ilist, int **numj, const double cpu_time, bool &success); - /// Clear all host and device data /** \note This is called at the beginning of the init() routine **/ void clear(); diff --git a/lib/gpu/lal_tersoff_zbl.cpp b/lib/gpu/lal_tersoff_zbl.cpp index 6efa8b9487..33edabd799 100644 --- a/lib/gpu/lal_tersoff_zbl.cpp +++ b/lib/gpu/lal_tersoff_zbl.cpp @@ -250,175 +250,6 @@ double TersoffZT::host_memory_usage() const { #define KTHREADS this->_threads_per_atom #define JTHREADS this->_threads_per_atom -// --------------------------------------------------------------------------- -// Copy nbor list from host if necessary and then calculate forces, virials,.. -// --------------------------------------------------------------------------- -template -void TersoffZT::compute(const int f_ago, const int inum_full, const int nall, - const int nlist, double **host_x, int *host_type, - int *ilist, int *numj, int **firstneigh, - const bool eflag, const bool vflag, const bool eatom, - const bool vatom, int &host_start, - const double cpu_time, bool &success) { - this->acc_timers(); - if (inum_full==0) { - host_start=0; - // Make sure textures are correct if realloc by a different hybrid style - this->resize_atom(0,nall,success); - this->zero_timers(); - return; - } - - int ago=this->hd_balancer.ago_first(f_ago); - int inum=this->hd_balancer.balance(ago,inum_full,cpu_time); - this->ans->inum(inum); - #ifdef THREE_CONCURRENT - this->ans2->inum(inum); - #endif - host_start=inum; - - if (ago==0) { - this->reset_nbors(nall, inum, nlist, ilist, numj, firstneigh, success); - if (!success) - return; - this->_max_nbors = this->nbor->max_nbor_loop(nlist,numj,ilist); - } - - this->atom->cast_x_data(host_x,host_type); - this->hd_balancer.start_timer(); - this->atom->add_x_data(host_x,host_type); - - // re-allocate zetaij if necessary - if (nall*this->_max_nbors > _zetaij.cols()) { - int _nmax=static_cast(static_cast(nall)*1.10); - _zetaij.resize(this->_max_nbors*_nmax); - } - - this->_ainum=nlist; - - int _eflag; - if (eflag) - _eflag=1; - else - _eflag=0; - - int ainum=nlist; - int nbor_pitch=this->nbor->nbor_pitch(); - int BX=this->block_pair(); - int GX=static_cast(ceil(static_cast(ainum)/ - (BX/(JTHREADS*KTHREADS)))); - - this->k_zeta.set_size(GX,BX); - this->k_zeta.run(&this->atom->x, &ts1, &ts2, &ts3, &ts4, &ts5, &ts6, &cutsq, - &map, &elem2param, &_nelements, &_nparams, &_zetaij, - &this->nbor->dev_nbor, &this->_nbor_data->begin(), - &_eflag, &ainum, &nbor_pitch, &this->_threads_per_atom); - - int evatom=0; - if (eatom || vatom) - evatom=1; - #ifdef THREE_CONCURRENT - this->ucl_device->sync(); - #endif - loop(eflag,vflag,evatom); - this->ans->copy_answers(eflag,vflag,eatom,vatom,ilist); - this->device->add_ans_object(this->ans); - #ifdef THREE_CONCURRENT - this->ans2->copy_answers(eflag,vflag,eatom,vatom,ilist); - this->device->add_ans_object(this->ans2); - #endif - this->hd_balancer.stop_timer(); -} - -// --------------------------------------------------------------------------- -// Reneighbor on GPU if necessary and then compute forces, virials, energies -// --------------------------------------------------------------------------- -template -int ** TersoffZT::compute(const int ago, const int inum_full, - const int nall, double **host_x, int *host_type, - double *sublo, double *subhi, tagint *tag, - int **nspecial, tagint **special, const bool eflag, - const bool vflag, const bool eatom, - const bool vatom, int &host_start, - int **ilist, int **jnum, - const double cpu_time, bool &success) { - this->acc_timers(); - - if (inum_full==0) { - host_start=0; - // Make sure textures are correct if realloc by a different hybrid style - this->resize_atom(0,nall,success); - this->zero_timers(); - return NULL; - } - - this->hd_balancer.balance(cpu_time); - int inum=this->hd_balancer.get_gpu_count(ago,inum_full); - this->ans->inum(inum); - #ifdef THREE_CONCURRENT - this->ans2->inum(inum); - #endif - host_start=inum; - - // Build neighbor list on GPU if necessary - if (ago==0) { - this->_max_nbors = this->build_nbor_list(inum, inum_full-inum, nall, host_x, host_type, - sublo, subhi, tag, nspecial, special, success); - if (!success) - return NULL; - this->hd_balancer.start_timer(); - } else { - this->atom->cast_x_data(host_x,host_type); - this->hd_balancer.start_timer(); - this->atom->add_x_data(host_x,host_type); - } - *ilist=this->nbor->host_ilist.begin(); - *jnum=this->nbor->host_acc.begin(); - - // re-allocate zetaij if necessary - if (nall*this->_max_nbors > _zetaij.cols()) { - int _nmax=static_cast(static_cast(nall)*1.10); - _zetaij.resize(this->_max_nbors*_nmax); - } - - this->_ainum=nall; - - int _eflag; - if (eflag) - _eflag=1; - else - _eflag=0; - - int ainum=nall; - int nbor_pitch=this->nbor->nbor_pitch(); - int BX=this->block_pair(); - int GX=static_cast(ceil(static_cast(ainum)/ - (BX/(JTHREADS*KTHREADS)))); - - this->k_zeta.set_size(GX,BX); - this->k_zeta.run(&this->atom->x, &ts1, &ts2, &ts3, &ts4, &ts5, &ts6, &cutsq, - &map, &elem2param, &_nelements, &_nparams, &_zetaij, - &this->nbor->dev_nbor, &this->_nbor_data->begin(), - &_eflag, &ainum, &nbor_pitch, &this->_threads_per_atom); - - int evatom=0; - if (eatom || vatom) - evatom=1; - #ifdef THREE_CONCURRENT - this->ucl_device->sync(); - #endif - loop(eflag,vflag,evatom); - this->ans->copy_answers(eflag,vflag,eatom,vatom); - this->device->add_ans_object(this->ans); - #ifdef THREE_CONCURRENT - this->ans2->copy_answers(eflag,vflag,eatom,vatom); - this->device->add_ans_object(this->ans2); - #endif - this->hd_balancer.stop_timer(); - - return this->nbor->host_jlist.begin()-host_start; -} - // --------------------------------------------------------------------------- // Calculate energies, forces, and torques // --------------------------------------------------------------------------- @@ -449,6 +280,13 @@ void TersoffZT::loop(const bool _eflag, const bool _vflag, const int evatom) { &this->dev_short_nbor, &ainum, &nbor_pitch, &this->_threads_per_atom); + // re-allocate zetaij if necessary + int nall = this->_nall; + if (nall*this->_max_nbors > _zetaij.cols()) { + int _nmax=static_cast(static_cast(nall)*1.10); + _zetaij.resize(this->_max_nbors*_nmax); + } + nbor_pitch=this->nbor->nbor_pitch(); GX=static_cast(ceil(static_cast(this->_ainum)/ (BX/(JTHREADS*KTHREADS)))); diff --git a/lib/gpu/lal_tersoff_zbl.h b/lib/gpu/lal_tersoff_zbl.h index a5f1ace754..0e6cac9587 100644 --- a/lib/gpu/lal_tersoff_zbl.h +++ b/lib/gpu/lal_tersoff_zbl.h @@ -49,21 +49,6 @@ class TersoffZBL : public BaseThree { const double* ZBLcut, const double* ZBLexpscale, const double global_e, const double global_a_0, const double global_epsilon_0, const double* cutsq); - /// Pair loop with host neighboring - void compute(const int f_ago, const int inum_full, const int nall, - const int nlist, double **host_x, int *host_type, - int *ilist, int *numj, int **firstneigh, const bool eflag, - const bool vflag, const bool eatom, const bool vatom, - int &host_start, const double cpu_time, bool &success); - - /// Pair loop with device neighboring - int ** compute(const int ago, const int inum_full, - const int nall, double **host_x, int *host_type, double *sublo, - double *subhi, tagint *tag, int **nspecial, - tagint **special, const bool eflag, const bool vflag, - const bool eatom, const bool vatom, int &host_start, - int **ilist, int **numj, const double cpu_time, bool &success); - /// Clear all host and device data /** \note This is called at the beginning of the init() routine **/ void clear(); From 8c9db3ea0010be90236beb490e8deb64c9c2a785 Mon Sep 17 00:00:00 2001 From: Trung Nguyen Date: Mon, 10 Jul 2017 23:50:21 -0500 Subject: [PATCH 255/439] Built 2-body short neighbor list and used for 2-body kernels in tersoff gpu styles --- lib/gpu/lal_tersoff.cpp | 4 +- lib/gpu/lal_tersoff.cu | 75 ++++++++++++++++++-------------- lib/gpu/lal_tersoff_mod.cpp | 4 +- lib/gpu/lal_tersoff_mod.cu | 73 ++++++++++++++++++------------- lib/gpu/lal_tersoff_zbl.cpp | 4 +- lib/gpu/lal_tersoff_zbl.cu | 85 +++++++++++++++++++++---------------- 6 files changed, 145 insertions(+), 100 deletions(-) diff --git a/lib/gpu/lal_tersoff.cpp b/lib/gpu/lal_tersoff.cpp index cb4a3fdbd6..a63d286d9c 100644 --- a/lib/gpu/lal_tersoff.cpp +++ b/lib/gpu/lal_tersoff.cpp @@ -250,7 +250,8 @@ void TersoffT::loop(const bool _eflag, const bool _vflag, const int evatom) { (BX/this->_threads_per_atom))); this->k_short_nbor.set_size(GX,BX); - this->k_short_nbor.run(&this->atom->x, &_cutshortsq, + this->k_short_nbor.run(&this->atom->x, &cutsq, &map, + &elem2param, &_nelements, &_nparams, &this->nbor->dev_nbor, &this->_nbor_data->begin(), &this->dev_short_nbor, &ainum, &nbor_pitch, &this->_threads_per_atom); @@ -283,6 +284,7 @@ void TersoffT::loop(const bool _eflag, const bool _vflag, const int evatom) { this->k_pair.run(&this->atom->x, &ts1, &ts2, &cutsq, &map, &elem2param, &_nelements, &_nparams, &this->nbor->dev_nbor, &this->_nbor_data->begin(), + &this->dev_short_nbor, &this->ans->force, &this->ans->engv, &eflag, &vflag, &ainum, &nbor_pitch, &this->_threads_per_atom); diff --git a/lib/gpu/lal_tersoff.cu b/lib/gpu/lal_tersoff.cu index 9faa59c34d..0026fb97cb 100644 --- a/lib/gpu/lal_tersoff.cu +++ b/lib/gpu/lal_tersoff.cu @@ -165,7 +165,10 @@ texture ts5_tex; #endif __kernel void k_tersoff_short_nbor(const __global numtyp4 *restrict x_, - const numtyp cutshortsq, + const __global numtyp *restrict cutsq, + const __global int *restrict map, + const __global int *restrict elem2param, + const int nelements, const int nparams, const __global int * dev_nbor, const __global int * dev_packed, __global int * dev_short_nbor, @@ -182,6 +185,8 @@ __kernel void k_tersoff_short_nbor(const __global numtyp4 *restrict x_, n_stride,nbor_end,nbor); numtyp4 ix; fetch4(ix,i,pos_tex); //x_[i]; + int itype=ix.w; + itype=map[itype]; int ncount = 0; int m = nbor; @@ -195,6 +200,9 @@ __kernel void k_tersoff_short_nbor(const __global numtyp4 *restrict x_, j &= NEIGHMASK; numtyp4 jx; fetch4(jx,j,pos_tex); //x_[j]; + int jtype=jx.w; + jtype=map[jtype]; + int ijparam=elem2param[itype*nelements*nelements+jtype*nelements+jtype]; // Compute r12 numtyp delx = ix.x-jx.x; @@ -202,7 +210,7 @@ __kernel void k_tersoff_short_nbor(const __global numtyp4 *restrict x_, numtyp delz = ix.z-jx.z; numtyp rsq = delx*delx+dely*dely+delz*delz; - if (rsq cutsq[ijparam]) continue; +// if (rsq1 > cutsq[ijparam]) continue; // compute zeta_ij z = (acctyp)0; @@ -391,6 +399,7 @@ __kernel void k_tersoff_repulsive(const __global numtyp4 *restrict x_, const int nelements, const int nparams, const __global int * dev_nbor, const __global int * dev_packed, + const __global int * dev_short_nbor, __global acctyp4 *restrict ans, __global acctyp *restrict engv, const int eflag, const int vflag, @@ -426,9 +435,14 @@ __kernel void k_tersoff_repulsive(const __global numtyp4 *restrict x_, int itype=ix.w; itype=map[itype]; + // recalculate numj and nbor_end for use of the short nbor list + numj = dev_short_nbor[nbor]; + nbor += n_stride; + nbor_end = nbor+fast_mul(numj,n_stride); + for ( ; nbor0) - energy+=feng[1]; - if (vflag>0) { - virial[0] += delx*delx*force; - virial[1] += dely*dely*force; - virial[2] += delz*delz*force; - virial[3] += delx*dely*force; - virial[4] += delx*delz*force; - virial[5] += dely*delz*force; - } + if (eflag>0) + energy+=feng[1]; + if (vflag>0) { + virial[0] += delx*delx*force; + virial[1] += dely*dely*force; + virial[2] += delz*delz*force; + virial[3] += delx*dely*force; + virial[4] += delx*delz*force; + virial[5] += dely*delz*force; } } // for nbor @@ -556,7 +569,7 @@ __kernel void k_tersoff_three_center(const __global numtyp4 *restrict x_, delr1[2] = jx.z-ix.z; numtyp rsq1 = delr1[0]*delr1[0] + delr1[1]*delr1[1] + delr1[2]*delr1[2]; - if (rsq1 > cutsq[ijparam]) continue; +// if (rsq1 > cutsq[ijparam]) continue; numtyp r1 = ucl_sqrt(rsq1); numtyp r1inv = ucl_rsqrt(rsq1); @@ -669,7 +682,7 @@ __kernel void k_tersoff_three_end(const __global numtyp4 *restrict x_, const __global int * dev_nbor, const __global int * dev_packed, const __global int * dev_acc, - const __global int * dev_short_nbor, + const __global int * dev_short_nbor, __global acctyp4 *restrict ans, __global acctyp *restrict engv, const int eflag, const int vflag, @@ -738,7 +751,7 @@ __kernel void k_tersoff_three_end(const __global numtyp4 *restrict x_, delr1[2] = jx.z-ix.z; numtyp rsq1 = delr1[0]*delr1[0] + delr1[1]*delr1[1] + delr1[2]*delr1[2]; - if (rsq1 > cutsq[ijparam]) continue; +// if (rsq1 > cutsq[ijparam]) continue; numtyp mdelr1[3]; mdelr1[0] = -delr1[0]; @@ -978,7 +991,7 @@ __kernel void k_tersoff_three_end_vatom(const __global numtyp4 *restrict x_, delr1[2] = jx.z-ix.z; numtyp rsq1 = delr1[0]*delr1[0] + delr1[1]*delr1[1] + delr1[2]*delr1[2]; - if (rsq1 > cutsq[ijparam]) continue; +// if (rsq1 > cutsq[ijparam]) continue; numtyp mdelr1[3]; mdelr1[0] = -delr1[0]; diff --git a/lib/gpu/lal_tersoff_mod.cpp b/lib/gpu/lal_tersoff_mod.cpp index 02000d77d3..c37c07f1a1 100644 --- a/lib/gpu/lal_tersoff_mod.cpp +++ b/lib/gpu/lal_tersoff_mod.cpp @@ -250,7 +250,8 @@ void TersoffMT::loop(const bool _eflag, const bool _vflag, const int evatom) { (BX/this->_threads_per_atom))); this->k_short_nbor.set_size(GX,BX); - this->k_short_nbor.run(&this->atom->x, &_cutshortsq, + this->k_short_nbor.run(&this->atom->x, &cutsq, &map, + &elem2param, &_nelements, &_nparams, &this->nbor->dev_nbor, &this->_nbor_data->begin(), &this->dev_short_nbor, &ainum, &nbor_pitch, &this->_threads_per_atom); @@ -283,6 +284,7 @@ void TersoffMT::loop(const bool _eflag, const bool _vflag, const int evatom) { this->k_pair.run(&this->atom->x, &ts1, &ts2, &cutsq, &map, &elem2param, &_nelements, &_nparams, &this->nbor->dev_nbor, &this->_nbor_data->begin(), + &this->dev_short_nbor, &this->ans->force, &this->ans->engv, &eflag, &vflag, &ainum, &nbor_pitch, &this->_threads_per_atom); diff --git a/lib/gpu/lal_tersoff_mod.cu b/lib/gpu/lal_tersoff_mod.cu index 75bacc2179..555485a1b2 100644 --- a/lib/gpu/lal_tersoff_mod.cu +++ b/lib/gpu/lal_tersoff_mod.cu @@ -165,7 +165,10 @@ texture ts5_tex; #endif __kernel void k_tersoff_mod_short_nbor(const __global numtyp4 *restrict x_, - const numtyp cutshortsq, + const __global numtyp *restrict cutsq, + const __global int *restrict map, + const __global int *restrict elem2param, + const int nelements, const int nparams, const __global int * dev_nbor, const __global int * dev_packed, __global int * dev_short_nbor, @@ -182,6 +185,8 @@ __kernel void k_tersoff_mod_short_nbor(const __global numtyp4 *restrict x_, n_stride,nbor_end,nbor); numtyp4 ix; fetch4(ix,i,pos_tex); //x_[i]; + int itype=ix.w; + itype=map[itype]; int ncount = 0; int m = nbor; @@ -195,6 +200,9 @@ __kernel void k_tersoff_mod_short_nbor(const __global numtyp4 *restrict x_, j &= NEIGHMASK; numtyp4 jx; fetch4(jx,j,pos_tex); //x_[j]; + int jtype=jx.w; + jtype=map[jtype]; + int ijparam=elem2param[itype*nelements*nelements+jtype*nelements+jtype]; // Compute r12 numtyp delx = ix.x-jx.x; @@ -202,7 +210,7 @@ __kernel void k_tersoff_mod_short_nbor(const __global numtyp4 *restrict x_, numtyp delz = ix.z-jx.z; numtyp rsq = delx*delx+dely*dely+delz*delz; - if (rsq cutsq[ijparam]) continue; +// if (rsq1 > cutsq[ijparam]) continue; // compute zeta_ij z = (acctyp)0; @@ -392,6 +400,7 @@ __kernel void k_tersoff_mod_repulsive(const __global numtyp4 *restrict x_, const int nelements, const int nparams, const __global int * dev_nbor, const __global int * dev_packed, + const __global int * dev_short_nbor, __global acctyp4 *restrict ans, __global acctyp *restrict engv, const int eflag, const int vflag, @@ -427,9 +436,14 @@ __kernel void k_tersoff_mod_repulsive(const __global numtyp4 *restrict x_, int itype=ix.w; itype=map[itype]; + // recalculate numj and nbor_end for use of the short nbor list + numj = dev_short_nbor[nbor]; + nbor += n_stride; + nbor_end = nbor+fast_mul(numj,n_stride); + for ( ; nbor0) - energy+=feng[1]; - if (vflag>0) { - virial[0] += delx*delx*force; - virial[1] += dely*dely*force; - virial[2] += delz*delz*force; - virial[3] += delx*dely*force; - virial[4] += delx*delz*force; - virial[5] += dely*delz*force; - } + if (eflag>0) + energy+=feng[1]; + if (vflag>0) { + virial[0] += delx*delx*force; + virial[1] += dely*dely*force; + virial[2] += delz*delz*force; + virial[3] += delx*dely*force; + virial[4] += delx*delz*force; + virial[5] += dely*delz*force; } } // for nbor @@ -560,7 +573,7 @@ __kernel void k_tersoff_mod_three_center(const __global numtyp4 *restrict x_, delr1[2] = jx.z-ix.z; numtyp rsq1 = delr1[0]*delr1[0] + delr1[1]*delr1[1] + delr1[2]*delr1[2]; - if (rsq1 > cutsq[ijparam]) continue; +// if (rsq1 > cutsq[ijparam]) continue; numtyp r1 = ucl_sqrt(rsq1); numtyp r1inv = ucl_rsqrt(rsq1); @@ -748,7 +761,7 @@ __kernel void k_tersoff_mod_three_end(const __global numtyp4 *restrict x_, delr1[2] = jx.z-ix.z; numtyp rsq1 = delr1[0]*delr1[0] + delr1[1]*delr1[1] + delr1[2]*delr1[2]; - if (rsq1 > cutsq[ijparam]) continue; +// if (rsq1 > cutsq[ijparam]) continue; numtyp mdelr1[3]; mdelr1[0] = -delr1[0]; @@ -997,7 +1010,7 @@ __kernel void k_tersoff_mod_three_end_vatom(const __global numtyp4 *restrict x_, delr1[2] = jx.z-ix.z; numtyp rsq1 = delr1[0]*delr1[0] + delr1[1]*delr1[1] + delr1[2]*delr1[2]; - if (rsq1 > cutsq[ijparam]) continue; +// if (rsq1 > cutsq[ijparam]) continue; numtyp mdelr1[3]; mdelr1[0] = -delr1[0]; diff --git a/lib/gpu/lal_tersoff_zbl.cpp b/lib/gpu/lal_tersoff_zbl.cpp index 33edabd799..827613067c 100644 --- a/lib/gpu/lal_tersoff_zbl.cpp +++ b/lib/gpu/lal_tersoff_zbl.cpp @@ -275,7 +275,8 @@ void TersoffZT::loop(const bool _eflag, const bool _vflag, const int evatom) { (BX/this->_threads_per_atom))); this->k_short_nbor.set_size(GX,BX); - this->k_short_nbor.run(&this->atom->x, &_cutshortsq, + this->k_short_nbor.run(&this->atom->x, &cutsq, &map, + &elem2param, &_nelements, &_nparams, &this->nbor->dev_nbor, &this->_nbor_data->begin(), &this->dev_short_nbor, &ainum, &nbor_pitch, &this->_threads_per_atom); @@ -309,6 +310,7 @@ void TersoffZT::loop(const bool _eflag, const bool _vflag, const int evatom) { &_global_e, &_global_a_0, &_global_epsilon_0, &cutsq, &map, &elem2param, &_nelements, &_nparams, &this->nbor->dev_nbor, &this->_nbor_data->begin(), + &this->dev_short_nbor, &this->ans->force, &this->ans->engv, &eflag, &vflag, &ainum, &nbor_pitch, &this->_threads_per_atom); diff --git a/lib/gpu/lal_tersoff_zbl.cu b/lib/gpu/lal_tersoff_zbl.cu index 439d4028df..89ae72df8a 100644 --- a/lib/gpu/lal_tersoff_zbl.cu +++ b/lib/gpu/lal_tersoff_zbl.cu @@ -168,7 +168,10 @@ texture ts6_tex; #endif __kernel void k_tersoff_zbl_short_nbor(const __global numtyp4 *restrict x_, - const numtyp cutshortsq, + const __global numtyp *restrict cutsq, + const __global int *restrict map, + const __global int *restrict elem2param, + const int nelements, const int nparams, const __global int * dev_nbor, const __global int * dev_packed, __global int * dev_short_nbor, @@ -185,6 +188,8 @@ __kernel void k_tersoff_zbl_short_nbor(const __global numtyp4 *restrict x_, n_stride,nbor_end,nbor); numtyp4 ix; fetch4(ix,i,pos_tex); //x_[i]; + int itype=ix.w; + itype=map[itype]; int ncount = 0; int m = nbor; @@ -198,6 +203,9 @@ __kernel void k_tersoff_zbl_short_nbor(const __global numtyp4 *restrict x_, j &= NEIGHMASK; numtyp4 jx; fetch4(jx,j,pos_tex); //x_[j]; + int jtype=jx.w; + jtype=map[jtype]; + int ijparam=elem2param[itype*nelements*nelements+jtype*nelements+jtype]; // Compute r12 numtyp delx = ix.x-jx.x; @@ -205,7 +213,7 @@ __kernel void k_tersoff_zbl_short_nbor(const __global numtyp4 *restrict x_, numtyp delz = ix.z-jx.z; numtyp rsq = delx*delx+dely*dely+delz*delz; - if (rsq cutsq[ijparam]) continue; +// if (rsq1 > cutsq[ijparam]) continue; // compute zeta_ij z = (acctyp)0; @@ -403,6 +411,7 @@ __kernel void k_tersoff_zbl_repulsive(const __global numtyp4 *restrict x_, const int nelements, const int nparams, const __global int * dev_nbor, const __global int * dev_packed, + const __global int * dev_short_nbor, __global acctyp4 *restrict ans, __global acctyp *restrict engv, const int eflag, const int vflag, @@ -440,9 +449,14 @@ __kernel void k_tersoff_zbl_repulsive(const __global numtyp4 *restrict x_, int itype=ix.w; itype=map[itype]; + // recalculate numj and nbor_end for use of the short nbor list + numj = dev_short_nbor[nbor]; + nbor += n_stride; + nbor_end = nbor+fast_mul(numj,n_stride); + for ( ; nbor0) - energy+=feng[1]; - if (vflag>0) { - virial[0] += delx*delx*force; - virial[1] += dely*dely*force; - virial[2] += delz*delz*force; - virial[3] += delx*dely*force; - virial[4] += delx*delz*force; - virial[5] += dely*delz*force; - } + if (eflag>0) + energy+=feng[1]; + if (vflag>0) { + virial[0] += delx*delx*force; + virial[1] += dely*dely*force; + virial[2] += delz*delz*force; + virial[3] += delx*dely*force; + virial[4] += delx*delz*force; + virial[5] += dely*delz*force; } } // for nbor @@ -576,7 +589,7 @@ __kernel void k_tersoff_zbl_three_center(const __global numtyp4 *restrict x_, delr1[2] = jx.z-ix.z; numtyp rsq1 = delr1[0]*delr1[0] + delr1[1]*delr1[1] + delr1[2]*delr1[2]; - if (rsq1 > cutsq[ijparam]) continue; +// if (rsq1 > cutsq[ijparam]) continue; numtyp r1 = ucl_sqrt(rsq1); numtyp r1inv = ucl_rsqrt(rsq1); @@ -758,7 +771,7 @@ __kernel void k_tersoff_zbl_three_end(const __global numtyp4 *restrict x_, delr1[2] = jx.z-ix.z; numtyp rsq1 = delr1[0]*delr1[0] + delr1[1]*delr1[1] + delr1[2]*delr1[2]; - if (rsq1 > cutsq[ijparam]) continue; +// if (rsq1 > cutsq[ijparam]) continue; numtyp mdelr1[3]; mdelr1[0] = -delr1[0]; @@ -998,7 +1011,7 @@ __kernel void k_tersoff_zbl_three_end_vatom(const __global numtyp4 *restrict x_, delr1[2] = jx.z-ix.z; numtyp rsq1 = delr1[0]*delr1[0] + delr1[1]*delr1[1] + delr1[2]*delr1[2]; - if (rsq1 > cutsq[ijparam]) continue; +// if (rsq1 > cutsq[ijparam]) continue; numtyp mdelr1[3]; mdelr1[0] = -delr1[0]; From cdac5f496c531a851b1bdc5b6177f590150c9fff Mon Sep 17 00:00:00 2001 From: Trung Nguyen Date: Tue, 11 Jul 2017 00:13:56 -0500 Subject: [PATCH 256/439] Built 3-body short neighbor list for the 3-body kernels using per-pair cutoffs for vashishta gpu style --- lib/gpu/lal_vashishta.cpp | 3 ++- lib/gpu/lal_vashishta.cu | 22 +++++++++++++++++----- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/lib/gpu/lal_vashishta.cpp b/lib/gpu/lal_vashishta.cpp index 55318bb3b0..d03ac992bd 100644 --- a/lib/gpu/lal_vashishta.cpp +++ b/lib/gpu/lal_vashishta.cpp @@ -233,7 +233,8 @@ void VashishtaT::loop(const bool _eflag, const bool _vflag, const int evatom) { (BX/this->_threads_per_atom))); this->k_short_nbor.set_size(GX,BX); - this->k_short_nbor.run(&this->atom->x, &_cutshortsq, + this->k_short_nbor.run(&this->atom->x, ¶m4, &map, + &elem2param, &_nelements, &_nparams, &this->nbor->dev_nbor, &this->_nbor_data->begin(), &this->dev_short_nbor, &ainum, &nbor_pitch, &this->_threads_per_atom); diff --git a/lib/gpu/lal_vashishta.cu b/lib/gpu/lal_vashishta.cu index 7449b18f6b..d226aba6dd 100644 --- a/lib/gpu/lal_vashishta.cu +++ b/lib/gpu/lal_vashishta.cu @@ -137,7 +137,10 @@ texture param5_tex; #endif __kernel void k_vashishta_short_nbor(const __global numtyp4 *restrict x_, - const numtyp cutshortsq, + const __global numtyp4 *restrict param4, + const __global int *restrict map, + const __global int *restrict elem2param, + const int nelements, const int nparams, const __global int * dev_nbor, const __global int * dev_packed, __global int * dev_short_nbor, @@ -154,6 +157,8 @@ __kernel void k_vashishta_short_nbor(const __global numtyp4 *restrict x_, n_stride,nbor_end,nbor); numtyp4 ix; fetch4(ix,i,pos_tex); //x_[i]; + int itype=ix.w; + itype=map[itype]; int ncount = 0; int m = nbor; @@ -167,6 +172,9 @@ __kernel void k_vashishta_short_nbor(const __global numtyp4 *restrict x_, j &= NEIGHMASK; numtyp4 jx; fetch4(jx,j,pos_tex); //x_[j]; + int jtype=jx.w; + jtype=map[jtype]; + int ijparam=elem2param[itype*nelements*nelements+jtype*nelements+jtype]; // Compute r12 numtyp delx = ix.x-jx.x; @@ -174,7 +182,7 @@ __kernel void k_vashishta_short_nbor(const __global numtyp4 *restrict x_, numtyp delz = ix.z-jx.z; numtyp rsq = delx*delx+dely*dely+delz*delz; - if (rsq param_r0sq_ij) continue; + +// if (rsq1 > param_r0sq_ij) continue; + param_gamma_ij=param4_ijparam.y; param_r0_ij=param4_ijparam.w; @@ -592,7 +602,8 @@ __kernel void k_vashishta_three_end(const __global numtyp4 *restrict x_, int ijparam=elem2param[itype*nelements*nelements+jtype*nelements+jtype]; numtyp4 param4_ijparam; fetch4(param4_ijparam,ijparam,param4_tex); param_r0sq_ij = param4_ijparam.x; - if (rsq1 > param_r0sq_ij) continue; + +// if (rsq1 > param_r0sq_ij) continue; param_gamma_ij=param4_ijparam.y; param_r0_ij = param4_ijparam.w; @@ -742,7 +753,8 @@ __kernel void k_vashishta_three_end_vatom(const __global numtyp4 *restrict x_, int ijparam=elem2param[itype*nelements*nelements+jtype*nelements+jtype]; numtyp4 param4_ijparam; fetch4(param4_ijparam,ijparam,param4_tex); param_r0sq_ij=param4_ijparam.x; - if (rsq1 > param_r0sq_ij) continue; + +// if (rsq1 > param_r0sq_ij) continue; param_gamma_ij=param4_ijparam.y; param_r0_ij=param4_ijparam.w; From 6b19016deb3ef6357bb7b912e24d4d498f79fad0 Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Wed, 12 Jul 2017 15:54:44 -0600 Subject: [PATCH 257/439] cmake: initial commit --- .gitignore | 8 +++++ CMakeLists.txt | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 CMakeLists.txt diff --git a/.gitignore b/.gitignore index 74e511515e..50b970249a 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,11 @@ log.cite .Trashes ehthumbs.db Thumbs.db + +#cmake +/build* +/CMakeCache.txt +/CMakeFiles/ +/Makefile +/cmake_install.cmake +/lmp diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000000..9bcf3118ae --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,84 @@ +cmake_minimum_required(VERSION 3.1) + +project(lammps) +set(SOVERSION 0) + +if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_C_FLAGS) + #release comes with -O3 by default + set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel." FORCE) +endif(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_C_FLAGS) + +enable_language(CXX) + +###################################################################### +# compiler tests +# these need ot be done early (before further tests). +##################################################################### + +include(CheckCCompilerFlag) + +######################################################################## +# User input options # +######################################################################## +option(BUILD_SHARED_LIBS "Build shared libs" OFF) +include(GNUInstallDirs) + +option(ENABLE_MPI "Build MPI version" OFF) +if(ENABLE_MPI) + find_package(MPI) + include_directories(${MPI_C_INCLUDE_PATH}) + set(MPI_SOURCES) +else() + file(GLOB MPI_SOURCES src/STUBS/mpi.c) + include_directories(src/STUBS) + set(MPI_CXX_LIBRARIES) +endif() + +find_package(UnixCommands) + +option(CMAKE_VERBOSE_MAKEFILE "Verbose makefile" OFF) + +######################################################################## +# Basic system tests (standard libraries, headers, functions, types) # +######################################################################## +include(CheckIncludeFile) +foreach(HEADER math.h) + check_include_file(${HEADER} FOUND_${HEADER}) + if(NOT FOUND_${HEADER}) + message(FATAL_ERROR "Could not find needed header - ${HEADER}") + endif(NOT FOUND_${HEADER}) +endforeach(HEADER) + +set(MATH_LIBRARIES "m" CACHE STRING "math library") +mark_as_advanced( MATH_LIBRARIES ) +include(CheckLibraryExists) +foreach(FUNC sin cos) + check_library_exists(${MATH_LIBRARIES} ${FUNC} "" FOUND_${FUNC}_${MATH_LIBRARIES}) + if(NOT FOUND_${FUNC}_${MATH_LIBRARIES}) + message(FATAL_ERROR "Could not find needed math function - ${FUNC}") + endif(NOT FOUND_${FUNC}_${MATH_LIBRARIES}) +endforeach(FUNC) + +###################################### +# Include the following subdirectory # +###################################### + +#Do NOT go into src to not conflict with old Makefile build system +#add_subdirectory(src) + +file(GLOB LIB_SOURCES src/*.cpp) +file(GLOB LMP_SOURCES src/main.cpp) +list(REMOVE_ITEM LIB_SOURCES ${LMP_SOURCES}) + +add_custom_target(style COMMAND ${BASH} Make.sh style WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src) +add_library(lammps ${LIB_SOURCES} ${MPI_SOURCES}) +add_dependencies(lammps style) +# better but slower +#add_custom_command(TARGET lammps PRE_BUILD COMMAND ${BASH} Make.sh style WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src) +target_link_libraries(lammps ${MPI_CXX_LIBRARIES} ${MATH_LIBRARIES}) +set_target_properties(lammps PROPERTIES SOVERSION ${SOVERSION}) +install(TARGETS lammps LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) + +add_executable(lmp ${LMP_SOURCES}) +target_link_libraries(lmp lammps) +install(TARGETS lammps DESTINATION ${CMAKE_INSTALL_BINDIR}) From bfb449cec9788dfa649ab7bbb17964364768c3be Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Thu, 13 Jul 2017 22:54:48 -0600 Subject: [PATCH 258/439] cmake: furhter improvments * Add support for one package * Add support for JPEG as external package * Use pre-generated style header * TODO write a script to generate them --- CMakeLists.txt => cmake/CMakeLists.txt | 39 ++++++++--- cmake/Headers/package.h.cmakein | 1 + cmake/Headers/style_angle.h | 3 + cmake/Headers/style_atom.h | 9 +++ cmake/Headers/style_body.h | 1 + cmake/Headers/style_bond.h | 3 + cmake/Headers/style_command.h | 23 +++++++ cmake/Headers/style_compute.h | 66 +++++++++++++++++++ cmake/Headers/style_dihedral.h | 3 + cmake/Headers/style_dump.h | 9 +++ cmake/Headers/style_fix.h | 89 ++++++++++++++++++++++++++ cmake/Headers/style_improper.h | 3 + cmake/Headers/style_integrate.h | 3 + cmake/Headers/style_kspace.h | 1 + cmake/Headers/style_minimize.h | 6 ++ cmake/Headers/style_nbin.h | 2 + cmake/Headers/style_npair.h | 36 +++++++++++ cmake/Headers/style_nstencil.h | 21 ++++++ cmake/Headers/style_ntopo.h | 13 ++++ cmake/Headers/style_pair.h | 47 ++++++++++++++ cmake/Headers/style_reader.h | 3 + cmake/Headers/style_region.h | 9 +++ 22 files changed, 381 insertions(+), 9 deletions(-) rename CMakeLists.txt => cmake/CMakeLists.txt (71%) create mode 100644 cmake/Headers/package.h.cmakein create mode 100644 cmake/Headers/style_angle.h create mode 100644 cmake/Headers/style_atom.h create mode 100644 cmake/Headers/style_body.h create mode 100644 cmake/Headers/style_bond.h create mode 100644 cmake/Headers/style_command.h create mode 100644 cmake/Headers/style_compute.h create mode 100644 cmake/Headers/style_dihedral.h create mode 100644 cmake/Headers/style_dump.h create mode 100644 cmake/Headers/style_fix.h create mode 100644 cmake/Headers/style_improper.h create mode 100644 cmake/Headers/style_integrate.h create mode 100644 cmake/Headers/style_kspace.h create mode 100644 cmake/Headers/style_minimize.h create mode 100644 cmake/Headers/style_nbin.h create mode 100644 cmake/Headers/style_npair.h create mode 100644 cmake/Headers/style_nstencil.h create mode 100644 cmake/Headers/style_ntopo.h create mode 100644 cmake/Headers/style_pair.h create mode 100644 cmake/Headers/style_reader.h create mode 100644 cmake/Headers/style_region.h diff --git a/CMakeLists.txt b/cmake/CMakeLists.txt similarity index 71% rename from CMakeLists.txt rename to cmake/CMakeLists.txt index 9bcf3118ae..4dd54ddf90 100644 --- a/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -29,8 +29,8 @@ if(ENABLE_MPI) include_directories(${MPI_C_INCLUDE_PATH}) set(MPI_SOURCES) else() - file(GLOB MPI_SOURCES src/STUBS/mpi.c) - include_directories(src/STUBS) + file(GLOB MPI_SOURCES ${CMAKE_SOURCE_DIR}/../src/STUBS/mpi.c) + include_directories(${CMAKE_SOURCE_DIR}/../src/STUBS) set(MPI_CXX_LIBRARIES) endif() @@ -38,6 +38,19 @@ find_package(UnixCommands) option(CMAKE_VERBOSE_MAKEFILE "Verbose makefile" OFF) +set(PACKAGES ASPHERE) +foreach(PKG ${PACKAGES}) + option(ENABLE_${PKG} "Build ${PKG} Package" OFF) +endforeach() + +find_package(JPEG) +if(JPEG_FOUND) + add_definitions(-DLAMMPS_JPEG) + include_directories(${JPEG_INCLUDE_DIR}) +else() + set(JPEG_LIBRARIES) +endif() + ######################################################################## # Basic system tests (standard libraries, headers, functions, types) # ######################################################################## @@ -66,16 +79,24 @@ endforeach(FUNC) #Do NOT go into src to not conflict with old Makefile build system #add_subdirectory(src) -file(GLOB LIB_SOURCES src/*.cpp) -file(GLOB LMP_SOURCES src/main.cpp) +file(GLOB LIB_SOURCES ${CMAKE_SOURCE_DIR}/../src/*.cpp) +file(GLOB LMP_SOURCES ${CMAKE_SOURCE_DIR}/../src/main.cpp) list(REMOVE_ITEM LIB_SOURCES ${LMP_SOURCES}) -add_custom_target(style COMMAND ${BASH} Make.sh style WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src) +foreach(PKG ${PACKAGES}) + if(ENABLE_${PKG}) + file(GLOB ${PKG}_SOURCES ${CMAKE_SOURCE_DIR}/../src/${PKG}/*.cpp) + list(APPEND LIB_SOURCES ${${PKG}_SOURCES}) + include_directories(${CMAKE_SOURCE_DIR}/../src/${PKG}) + endif() +endforeach() +include_directories(${CMAKE_SOURCE_DIR}/../src) +include_directories(${CMAKE_SOURCE_DIR}/Headers) +configure_file(${CMAKE_SOURCE_DIR}/Headers/package.h.cmakein ${CMAKE_BINARY_DIR}/cmake/package.h) +include_directories(${CMAKE_BINARY_DIR}/cmake) + add_library(lammps ${LIB_SOURCES} ${MPI_SOURCES}) -add_dependencies(lammps style) -# better but slower -#add_custom_command(TARGET lammps PRE_BUILD COMMAND ${BASH} Make.sh style WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src) -target_link_libraries(lammps ${MPI_CXX_LIBRARIES} ${MATH_LIBRARIES}) +target_link_libraries(lammps ${MPI_CXX_LIBRARIES} ${JPEG_LIBRARIES} ${MATH_LIBRARIES}) set_target_properties(lammps PROPERTIES SOVERSION ${SOVERSION}) install(TARGETS lammps LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) diff --git a/cmake/Headers/package.h.cmakein b/cmake/Headers/package.h.cmakein new file mode 100644 index 0000000000..f582f6f7d5 --- /dev/null +++ b/cmake/Headers/package.h.cmakein @@ -0,0 +1 @@ +#cmakedefine ENABLE_ASPHERE diff --git a/cmake/Headers/style_angle.h b/cmake/Headers/style_angle.h new file mode 100644 index 0000000000..8b395b557f --- /dev/null +++ b/cmake/Headers/style_angle.h @@ -0,0 +1,3 @@ +#include "package.h" +#include "angle_hybrid.h" +#include "angle_zero.h" diff --git a/cmake/Headers/style_atom.h b/cmake/Headers/style_atom.h new file mode 100644 index 0000000000..ec4e5d7d20 --- /dev/null +++ b/cmake/Headers/style_atom.h @@ -0,0 +1,9 @@ +#include "package.h" +#include "atom_vec_atomic.h" +#include "atom_vec_body.h" +#include "atom_vec_charge.h" +#include "atom_vec_ellipsoid.h" +#include "atom_vec_hybrid.h" +#include "atom_vec_line.h" +#include "atom_vec_sphere.h" +#include "atom_vec_tri.h" diff --git a/cmake/Headers/style_body.h b/cmake/Headers/style_body.h new file mode 100644 index 0000000000..b2b5c1f82e --- /dev/null +++ b/cmake/Headers/style_body.h @@ -0,0 +1 @@ +#include "package.h" diff --git a/cmake/Headers/style_bond.h b/cmake/Headers/style_bond.h new file mode 100644 index 0000000000..d18a31ca91 --- /dev/null +++ b/cmake/Headers/style_bond.h @@ -0,0 +1,3 @@ +#include "package.h" +#include "bond_hybrid.h" +#include "bond_zero.h" diff --git a/cmake/Headers/style_command.h b/cmake/Headers/style_command.h new file mode 100644 index 0000000000..08f90396f7 --- /dev/null +++ b/cmake/Headers/style_command.h @@ -0,0 +1,23 @@ +#include "balance.h" +#include "change_box.h" +#include "create_atoms.h" +#include "create_bonds.h" +#include "create_box.h" +#include "delete_atoms.h" +#include "delete_bonds.h" +#include "displace_atoms.h" +#include "info.h" +#include "minimize.h" +#include "read_data.h" +#include "read_dump.h" +#include "read_restart.h" +#include "replicate.h" +#include "rerun.h" +#include "run.h" +#include "set.h" +#include "velocity.h" +#include "write_coeff.h" +#include "write_data.h" +#include "write_dump.h" +#include "package.h" +#include "write_restart.h" diff --git a/cmake/Headers/style_compute.h b/cmake/Headers/style_compute.h new file mode 100644 index 0000000000..bfcd053ed6 --- /dev/null +++ b/cmake/Headers/style_compute.h @@ -0,0 +1,66 @@ +#include "package.h" +#include "compute_angle.h" +#include "compute_angle_local.h" +#include "compute_angmom_chunk.h" +#include "compute_bond.h" +#include "compute_bond_local.h" +#include "compute_centro_atom.h" +#include "compute_chunk_atom.h" +#include "compute_cluster_atom.h" +#include "compute_cna_atom.h" +#include "compute_com.h" +#include "compute_com_chunk.h" +#include "compute_contact_atom.h" +#include "compute_coord_atom.h" +#include "compute_dihedral.h" +#include "compute_dihedral_local.h" +#include "compute_dipole_chunk.h" +#include "compute_displace_atom.h" +#ifdef ENABLE_ASPHERE +#include "compute_erotate_asphere.h" +#endif +#include "compute_erotate_sphere.h" +#include "compute_erotate_sphere_atom.h" +#include "compute_global_atom.h" +#include "compute_group_group.h" +#include "compute_gyration.h" +#include "compute_gyration_chunk.h" +#include "compute_heat_flux.h" +#include "compute_hexorder_atom.h" +#include "compute_improper.h" +#include "compute_improper_local.h" +#include "compute_inertia_chunk.h" +#include "compute_ke.h" +#include "compute_ke_atom.h" +#include "compute_msd.h" +#include "compute_msd_chunk.h" +#include "compute_omega_chunk.h" +#include "compute_orientorder_atom.h" +#include "compute_pair.h" +#include "compute_pair_local.h" +#include "compute_pe.h" +#include "compute_pe_atom.h" +#include "compute_pressure.h" +#include "compute_property_atom.h" +#include "compute_property_chunk.h" +#include "compute_property_local.h" +#include "compute_rdf.h" +#include "compute_reduce.h" +#include "compute_reduce_region.h" +#include "compute_slice.h" +#include "compute_stress_atom.h" +#include "compute_temp.h" +#ifdef ENABLE_ASPHERE +#include "compute_temp_asphere.h" +#endif +#include "compute_temp_chunk.h" +#include "compute_temp_com.h" +#include "compute_temp_deform.h" +#include "compute_temp_partial.h" +#include "compute_temp_profile.h" +#include "compute_temp_ramp.h" +#include "compute_temp_region.h" +#include "compute_temp_sphere.h" +#include "compute_torque_chunk.h" +#include "compute_vacf.h" +#include "compute_vcm_chunk.h" diff --git a/cmake/Headers/style_dihedral.h b/cmake/Headers/style_dihedral.h new file mode 100644 index 0000000000..26cb4a815a --- /dev/null +++ b/cmake/Headers/style_dihedral.h @@ -0,0 +1,3 @@ +#include "package.h" +#include "dihedral_hybrid.h" +#include "dihedral_zero.h" diff --git a/cmake/Headers/style_dump.h b/cmake/Headers/style_dump.h new file mode 100644 index 0000000000..bc8477a6bf --- /dev/null +++ b/cmake/Headers/style_dump.h @@ -0,0 +1,9 @@ +#include "package.h" +#include "dump_atom.h" +#include "dump_cfg.h" +#include "dump_custom.h" +#include "dump_dcd.h" +#include "dump_image.h" +#include "dump_local.h" +#include "dump_movie.h" +#include "dump_xyz.h" diff --git a/cmake/Headers/style_fix.h b/cmake/Headers/style_fix.h new file mode 100644 index 0000000000..5d142e086b --- /dev/null +++ b/cmake/Headers/style_fix.h @@ -0,0 +1,89 @@ +#include "package.h" +#include "fix_adapt.h" +#include "fix_addforce.h" +#include "fix_ave_atom.h" +#include "fix_ave_chunk.h" +#include "fix_ave_correlate.h" +#include "fix_ave_histo.h" +#include "fix_ave_histo_weight.h" +#include "fix_ave_time.h" +#include "fix_aveforce.h" +#include "fix_balance.h" +#include "fix_box_relax.h" +#include "fix_controller.h" +#include "fix_deform.h" +#include "fix_deprecated.h" +#include "fix_drag.h" +#include "fix_dt_reset.h" +#include "fix_enforce2d.h" +#include "fix_external.h" +#include "fix_gravity.h" +#include "fix_group.h" +#include "fix_halt.h" +#include "fix_heat.h" +#include "fix_indent.h" +#include "fix_langevin.h" +#include "fix_lineforce.h" +#include "fix_minimize.h" +#include "fix_momentum.h" +#include "fix_move.h" +#include "fix_nph.h" +#ifdef ENABLE_ASPHERE +#include "fix_nph_asphere.h" +#endif +#include "fix_nph_sphere.h" +#include "fix_npt.h" +#ifdef ENABLE_ASPHERE +#include "fix_npt_asphere.h" +#endif +#include "fix_npt_sphere.h" +#include "fix_nve.h" +#ifdef ENABLE_ASPHERE +#include "fix_nve_asphere.h" +#include "fix_nve_asphere_noforce.h" +#endif +#include "fix_nve_limit.h" +#ifdef ENABLE_ASPHERE +#include "fix_nve_line.h" +#endif +#include "fix_nve_noforce.h" +#include "fix_nve_sphere.h" +#ifdef ENABLE_ASPHERE +#include "fix_nve_tri.h" +#endif +#include "fix_nvt.h" +#ifdef ENABLE_ASPHERE +#include "fix_nvt_asphere.h" +#endif +#include "fix_nvt_sllod.h" +#include "fix_nvt_sphere.h" +#include "fix_planeforce.h" +#include "fix_press_berendsen.h" +#include "fix_print.h" +#include "fix_property_atom.h" +#include "fix_read_restart.h" +#include "fix_recenter.h" +#include "fix_respa.h" +#include "fix_restrain.h" +#include "fix_setforce.h" +#include "fix_shear_history.h" +#include "fix_spring.h" +#include "fix_spring_chunk.h" +#include "fix_spring_rg.h" +#include "fix_spring_self.h" +#include "fix_store.h" +#include "fix_store_force.h" +#include "fix_store_state.h" +#include "fix_temp_berendsen.h" +#include "fix_temp_csld.h" +#include "fix_temp_csvr.h" +#include "fix_temp_rescale.h" +#include "fix_tmd.h" +#include "fix_vector.h" +#include "fix_viscous.h" +#include "fix_wall_harmonic.h" +#include "fix_wall_lj1043.h" +#include "fix_wall_lj126.h" +#include "fix_wall_lj93.h" +#include "fix_wall_reflect.h" +#include "fix_wall_region.h" diff --git a/cmake/Headers/style_improper.h b/cmake/Headers/style_improper.h new file mode 100644 index 0000000000..3de3047d73 --- /dev/null +++ b/cmake/Headers/style_improper.h @@ -0,0 +1,3 @@ +#include "package.h" +#include "improper_hybrid.h" +#include "improper_zero.h" diff --git a/cmake/Headers/style_integrate.h b/cmake/Headers/style_integrate.h new file mode 100644 index 0000000000..0a2fd00cf7 --- /dev/null +++ b/cmake/Headers/style_integrate.h @@ -0,0 +1,3 @@ +#include "package.h" +#include "respa.h" +#include "verlet.h" diff --git a/cmake/Headers/style_kspace.h b/cmake/Headers/style_kspace.h new file mode 100644 index 0000000000..b2b5c1f82e --- /dev/null +++ b/cmake/Headers/style_kspace.h @@ -0,0 +1 @@ +#include "package.h" diff --git a/cmake/Headers/style_minimize.h b/cmake/Headers/style_minimize.h new file mode 100644 index 0000000000..35d9188e8d --- /dev/null +++ b/cmake/Headers/style_minimize.h @@ -0,0 +1,6 @@ +#include "package.h" +#include "min_cg.h" +#include "min_fire.h" +#include "min_hftn.h" +#include "min_quickmin.h" +#include "min_sd.h" diff --git a/cmake/Headers/style_nbin.h b/cmake/Headers/style_nbin.h new file mode 100644 index 0000000000..f0d52b05bc --- /dev/null +++ b/cmake/Headers/style_nbin.h @@ -0,0 +1,2 @@ +#include "package.h" +#include "nbin_standard.h" diff --git a/cmake/Headers/style_npair.h b/cmake/Headers/style_npair.h new file mode 100644 index 0000000000..bd403ebeeb --- /dev/null +++ b/cmake/Headers/style_npair.h @@ -0,0 +1,36 @@ +#include "package.h" +#include "npair_copy.h" +#include "npair_full_bin.h" +#include "npair_full_bin_atomonly.h" +#include "npair_full_bin_ghost.h" +#include "npair_full_multi.h" +#include "npair_full_nsq.h" +#include "npair_full_nsq_ghost.h" +#include "npair_half_bin_atomonly_newton.h" +#include "npair_half_bin_newtoff.h" +#include "npair_half_bin_newtoff_ghost.h" +#include "npair_half_bin_newton.h" +#include "npair_half_bin_newton_tri.h" +#include "npair_half_multi_newtoff.h" +#include "npair_half_multi_newton.h" +#include "npair_half_multi_newton_tri.h" +#include "npair_half_nsq_newtoff.h" +#include "npair_half_nsq_newtoff_ghost.h" +#include "npair_half_nsq_newton.h" +#include "npair_half_respa_bin_newtoff.h" +#include "npair_half_respa_bin_newton.h" +#include "npair_half_respa_bin_newton_tri.h" +#include "npair_half_respa_nsq_newtoff.h" +#include "npair_half_respa_nsq_newton.h" +#include "npair_half_size_bin_newtoff.h" +#include "npair_half_size_bin_newton.h" +#include "npair_half_size_bin_newton_tri.h" +#include "npair_half_size_nsq_newtoff.h" +#include "npair_half_size_nsq_newton.h" +#include "npair_halffull_newtoff.h" +#include "npair_halffull_newton.h" +#include "npair_skip.h" +#include "npair_skip_respa.h" +#include "npair_skip_size.h" +#include "npair_skip_size_off2on.h" +#include "npair_skip_size_off2on_oneside.h" diff --git a/cmake/Headers/style_nstencil.h b/cmake/Headers/style_nstencil.h new file mode 100644 index 0000000000..d28e4b23b1 --- /dev/null +++ b/cmake/Headers/style_nstencil.h @@ -0,0 +1,21 @@ +#include "package.h" +#include "nstencil_full_bin_2d.h" +#include "nstencil_full_bin_3d.h" +#include "nstencil_full_ghost_bin_2d.h" +#include "nstencil_full_ghost_bin_3d.h" +#include "nstencil_full_multi_2d.h" +#include "nstencil_full_multi_3d.h" +#include "nstencil_half_bin_2d_newtoff.h" +#include "nstencil_half_bin_2d_newton.h" +#include "nstencil_half_bin_2d_newton_tri.h" +#include "nstencil_half_bin_3d_newtoff.h" +#include "nstencil_half_bin_3d_newton.h" +#include "nstencil_half_bin_3d_newton_tri.h" +#include "nstencil_half_ghost_bin_2d_newtoff.h" +#include "nstencil_half_ghost_bin_3d_newtoff.h" +#include "nstencil_half_multi_2d_newtoff.h" +#include "nstencil_half_multi_2d_newton.h" +#include "nstencil_half_multi_2d_newton_tri.h" +#include "nstencil_half_multi_3d_newtoff.h" +#include "nstencil_half_multi_3d_newton.h" +#include "nstencil_half_multi_3d_newton_tri.h" diff --git a/cmake/Headers/style_ntopo.h b/cmake/Headers/style_ntopo.h new file mode 100644 index 0000000000..130b10200f --- /dev/null +++ b/cmake/Headers/style_ntopo.h @@ -0,0 +1,13 @@ +#include "package.h" +#include "ntopo_angle_all.h" +#include "ntopo_angle_partial.h" +#include "ntopo_angle_template.h" +#include "ntopo_bond_all.h" +#include "ntopo_bond_partial.h" +#include "ntopo_bond_template.h" +#include "ntopo_dihedral_all.h" +#include "ntopo_dihedral_partial.h" +#include "ntopo_dihedral_template.h" +#include "ntopo_improper_all.h" +#include "ntopo_improper_partial.h" +#include "ntopo_improper_template.h" diff --git a/cmake/Headers/style_pair.h b/cmake/Headers/style_pair.h new file mode 100644 index 0000000000..b2ecef6a2a --- /dev/null +++ b/cmake/Headers/style_pair.h @@ -0,0 +1,47 @@ +#include "package.h" +#include "pair_beck.h" +#include "pair_born.h" +#include "pair_born_coul_dsf.h" +#include "pair_born_coul_wolf.h" +#include "pair_buck.h" +#include "pair_buck_coul_cut.h" +#include "pair_coul_cut.h" +#include "pair_coul_debye.h" +#include "pair_coul_dsf.h" +#include "pair_coul_streitz.h" +#include "pair_coul_wolf.h" +#include "pair_dpd.h" +#include "pair_dpd_tstat.h" +#include "pair_gauss.h" +#ifdef ENABLE_ASPHERE +#include "pair_gayberne.h" +#endif +#include "pair_hybrid.h" +#include "pair_hybrid_overlay.h" +#ifdef ENABLE_ASPHERE +#include "pair_line_lj.h" +#endif +#include "pair_lj96_cut.h" +#include "pair_lj_cubic.h" +#include "pair_lj_cut.h" +#include "pair_lj_cut_coul_cut.h" +#include "pair_lj_cut_coul_debye.h" +#include "pair_lj_cut_coul_dsf.h" +#include "pair_lj_expand.h" +#include "pair_lj_gromacs.h" +#include "pair_lj_gromacs_coul_gromacs.h" +#include "pair_lj_smooth.h" +#include "pair_lj_smooth_linear.h" +#include "pair_mie_cut.h" +#include "pair_morse.h" +#ifdef ENABLE_ASPHERE +#include "pair_resquared.h" +#endif +#include "pair_soft.h" +#include "pair_table.h" +#ifdef ENABLE_ASPHERE +#include "pair_tri_lj.h" +#endif +#include "pair_yukawa.h" +#include "pair_zbl.h" +#include "pair_zero.h" diff --git a/cmake/Headers/style_reader.h b/cmake/Headers/style_reader.h new file mode 100644 index 0000000000..0b8145e13d --- /dev/null +++ b/cmake/Headers/style_reader.h @@ -0,0 +1,3 @@ +#include "package.h" +#include "reader_native.h" +#include "reader_xyz.h" diff --git a/cmake/Headers/style_region.h b/cmake/Headers/style_region.h new file mode 100644 index 0000000000..dc467b2a3d --- /dev/null +++ b/cmake/Headers/style_region.h @@ -0,0 +1,9 @@ +#include "package.h" +#include "region_block.h" +#include "region_cone.h" +#include "region_cylinder.h" +#include "region_intersect.h" +#include "region_plane.h" +#include "region_prism.h" +#include "region_sphere.h" +#include "region_union.h" From 7f1789a0c44c77a3eee1bf05cf0ea66a04a1fe0b Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Thu, 13 Jul 2017 23:27:55 -0600 Subject: [PATCH 259/439] cmake: add support for REAX and hence Fortran --- cmake/CMakeLists.txt | 9 ++++++++- cmake/Headers/package.h.cmakein | 1 + cmake/Headers/style_command.h | 2 +- cmake/Headers/style_fix.h | 3 +++ cmake/Headers/style_pair.h | 3 +++ 5 files changed, 16 insertions(+), 2 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 4dd54ddf90..cd3db7b7e9 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -38,7 +38,7 @@ find_package(UnixCommands) option(CMAKE_VERBOSE_MAKEFILE "Verbose makefile" OFF) -set(PACKAGES ASPHERE) +set(PACKAGES ASPHERE REAX) foreach(PKG ${PACKAGES}) option(ENABLE_${PKG} "Build ${PKG} Package" OFF) endforeach() @@ -90,6 +90,13 @@ foreach(PKG ${PACKAGES}) include_directories(${CMAKE_SOURCE_DIR}/../src/${PKG}) endif() endforeach() + +if(ENABLE_REAX) + enable_language(Fortran) + file(GLOB REAX_SOURCES ${CMAKE_SOURCE_DIR}/../lib/reax/*.F) + list(APPEND LIB_SOURCES ${REAX_SOURCES}) + include_directories(${CMAKE_SOURCE_DIR}/../lib/reax) +endif() include_directories(${CMAKE_SOURCE_DIR}/../src) include_directories(${CMAKE_SOURCE_DIR}/Headers) configure_file(${CMAKE_SOURCE_DIR}/Headers/package.h.cmakein ${CMAKE_BINARY_DIR}/cmake/package.h) diff --git a/cmake/Headers/package.h.cmakein b/cmake/Headers/package.h.cmakein index f582f6f7d5..9c7ff403a4 100644 --- a/cmake/Headers/package.h.cmakein +++ b/cmake/Headers/package.h.cmakein @@ -1 +1,2 @@ #cmakedefine ENABLE_ASPHERE +#cmakedefine ENABLE_REAX diff --git a/cmake/Headers/style_command.h b/cmake/Headers/style_command.h index 08f90396f7..d795f4ba0a 100644 --- a/cmake/Headers/style_command.h +++ b/cmake/Headers/style_command.h @@ -1,3 +1,4 @@ +#include "package.h" #include "balance.h" #include "change_box.h" #include "create_atoms.h" @@ -19,5 +20,4 @@ #include "write_coeff.h" #include "write_data.h" #include "write_dump.h" -#include "package.h" #include "write_restart.h" diff --git a/cmake/Headers/style_fix.h b/cmake/Headers/style_fix.h index 5d142e086b..146616124d 100644 --- a/cmake/Headers/style_fix.h +++ b/cmake/Headers/style_fix.h @@ -62,6 +62,9 @@ #include "fix_print.h" #include "fix_property_atom.h" #include "fix_read_restart.h" +#ifdef ENABLE_REAX +#include "fix_reax_bonds.h" +#endif #include "fix_recenter.h" #include "fix_respa.h" #include "fix_restrain.h" diff --git a/cmake/Headers/style_pair.h b/cmake/Headers/style_pair.h index b2ecef6a2a..067e2cdb23 100644 --- a/cmake/Headers/style_pair.h +++ b/cmake/Headers/style_pair.h @@ -34,6 +34,9 @@ #include "pair_lj_smooth_linear.h" #include "pair_mie_cut.h" #include "pair_morse.h" +#ifdef ENABLE_REAX +#include "pair_reax.h" +#endif #ifdef ENABLE_ASPHERE #include "pair_resquared.h" #endif From a86b0d4c1b3e9a98aa47907401b72cd49a1637b2 Mon Sep 17 00:00:00 2001 From: Richard Berger Date: Fri, 14 Jul 2017 03:53:07 -0500 Subject: [PATCH 260/439] Add PNG library detection to CMakeList.txt --- cmake/CMakeLists.txt | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index cd3db7b7e9..4692372cec 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -51,6 +51,14 @@ else() set(JPEG_LIBRARIES) endif() +find_package(PNG) +if(PNG_FOUND) + include_directories(${PNG_INCLUDE_DIR}) + add_definitions(-DLAMMPS_PNG) +else(PNG_FOUND) + set(PNG_LIBRARIES) +endif(PNG_FOUND) + ######################################################################## # Basic system tests (standard libraries, headers, functions, types) # ######################################################################## @@ -103,7 +111,7 @@ configure_file(${CMAKE_SOURCE_DIR}/Headers/package.h.cmakein ${CMAKE_BINARY_DIR} include_directories(${CMAKE_BINARY_DIR}/cmake) add_library(lammps ${LIB_SOURCES} ${MPI_SOURCES}) -target_link_libraries(lammps ${MPI_CXX_LIBRARIES} ${JPEG_LIBRARIES} ${MATH_LIBRARIES}) +target_link_libraries(lammps ${MPI_CXX_LIBRARIES} ${JPEG_LIBRARIES} ${PNG_LIBRARIES} ${MATH_LIBRARIES}) set_target_properties(lammps PROPERTIES SOVERSION ${SOVERSION}) install(TARGETS lammps LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) From fdd3d802f06e24c5f0501f6ff9e12d25f1f78198 Mon Sep 17 00:00:00 2001 From: Richard Berger Date: Fri, 14 Jul 2017 04:00:38 -0500 Subject: [PATCH 261/439] Clean up CMakeList.txt by introducing LAMMPS_SOURCE_DIR variable --- cmake/CMakeLists.txt | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 4692372cec..14ec5059f1 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 3.1) project(lammps) set(SOVERSION 0) +set(LAMMPS_SOURCE_DIR ${CMAKE_SOURCE_DIR}/../src) if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_C_FLAGS) #release comes with -O3 by default @@ -29,8 +30,8 @@ if(ENABLE_MPI) include_directories(${MPI_C_INCLUDE_PATH}) set(MPI_SOURCES) else() - file(GLOB MPI_SOURCES ${CMAKE_SOURCE_DIR}/../src/STUBS/mpi.c) - include_directories(${CMAKE_SOURCE_DIR}/../src/STUBS) + file(GLOB MPI_SOURCES ${LAMMPS_SOURCE_DIR}/STUBS/mpi.c) + include_directories(${LAMMPS_SOURCE_DIR}/STUBS) set(MPI_CXX_LIBRARIES) endif() @@ -87,15 +88,15 @@ endforeach(FUNC) #Do NOT go into src to not conflict with old Makefile build system #add_subdirectory(src) -file(GLOB LIB_SOURCES ${CMAKE_SOURCE_DIR}/../src/*.cpp) -file(GLOB LMP_SOURCES ${CMAKE_SOURCE_DIR}/../src/main.cpp) +file(GLOB LIB_SOURCES ${LAMMPS_SOURCE_DIR}/*.cpp) +file(GLOB LMP_SOURCES ${LAMMPS_SOURCE_DIR}/main.cpp) list(REMOVE_ITEM LIB_SOURCES ${LMP_SOURCES}) foreach(PKG ${PACKAGES}) if(ENABLE_${PKG}) - file(GLOB ${PKG}_SOURCES ${CMAKE_SOURCE_DIR}/../src/${PKG}/*.cpp) + file(GLOB ${PKG}_SOURCES ${LAMMPS_SOURCE_DIR}/${PKG}/*.cpp) list(APPEND LIB_SOURCES ${${PKG}_SOURCES}) - include_directories(${CMAKE_SOURCE_DIR}/../src/${PKG}) + include_directories(${LAMMPS_SOURCE_DIR}/${PKG}) endif() endforeach() @@ -105,7 +106,7 @@ if(ENABLE_REAX) list(APPEND LIB_SOURCES ${REAX_SOURCES}) include_directories(${CMAKE_SOURCE_DIR}/../lib/reax) endif() -include_directories(${CMAKE_SOURCE_DIR}/../src) +include_directories(${LAMMPS_SOURCE_DIR}) include_directories(${CMAKE_SOURCE_DIR}/Headers) configure_file(${CMAKE_SOURCE_DIR}/Headers/package.h.cmakein ${CMAKE_BINARY_DIR}/cmake/package.h) include_directories(${CMAKE_BINARY_DIR}/cmake) From a566419ca6916f047f9b855437c1729a98638822 Mon Sep 17 00:00:00 2001 From: Richard Berger Date: Fri, 14 Jul 2017 04:36:52 -0500 Subject: [PATCH 262/439] Add LAMMPS_LIB_SOURCE_DIR variable in CMakeLists.txt --- cmake/CMakeLists.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 14ec5059f1..f69d84e852 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -3,6 +3,7 @@ cmake_minimum_required(VERSION 3.1) project(lammps) set(SOVERSION 0) set(LAMMPS_SOURCE_DIR ${CMAKE_SOURCE_DIR}/../src) +set(LAMMPS_LIB_SOURCE_DIR ${CMAKE_SOURCE_DIR}/../lib) if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_C_FLAGS) #release comes with -O3 by default @@ -102,9 +103,9 @@ endforeach() if(ENABLE_REAX) enable_language(Fortran) - file(GLOB REAX_SOURCES ${CMAKE_SOURCE_DIR}/../lib/reax/*.F) + file(GLOB REAX_SOURCES ${LAMMPS_LIB_SOURCE_DIR}/reax/*.F) list(APPEND LIB_SOURCES ${REAX_SOURCES}) - include_directories(${CMAKE_SOURCE_DIR}/../lib/reax) + include_directories(${LAMMPS_LIB_SOURCE_DIR}/reax) endif() include_directories(${LAMMPS_SOURCE_DIR}) include_directories(${CMAKE_SOURCE_DIR}/Headers) From 842dc1b58c4b8f7aa68cf0c64e44d2aaffa753f9 Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Fri, 14 Jul 2017 14:21:21 -0600 Subject: [PATCH 263/439] cmake: collect link libs --- cmake/CMakeLists.txt | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index f69d84e852..074407650e 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -25,15 +25,12 @@ include(CheckCCompilerFlag) option(BUILD_SHARED_LIBS "Build shared libs" OFF) include(GNUInstallDirs) +set(LAMMPS_LINK_LIBS) option(ENABLE_MPI "Build MPI version" OFF) if(ENABLE_MPI) - find_package(MPI) + find_package(MPI REQUIRED) include_directories(${MPI_C_INCLUDE_PATH}) - set(MPI_SOURCES) -else() - file(GLOB MPI_SOURCES ${LAMMPS_SOURCE_DIR}/STUBS/mpi.c) - include_directories(${LAMMPS_SOURCE_DIR}/STUBS) - set(MPI_CXX_LIBRARIES) + list(APPEND LAMMPS_LINK_LIBS ${MPI_CXX_LIBRARIES}) endif() find_package(UnixCommands) @@ -49,16 +46,14 @@ find_package(JPEG) if(JPEG_FOUND) add_definitions(-DLAMMPS_JPEG) include_directories(${JPEG_INCLUDE_DIR}) -else() - set(JPEG_LIBRARIES) + list(APPEND LAMMPS_LINK_LIBS ${JPEG_LIBRARIES}) endif() find_package(PNG) if(PNG_FOUND) include_directories(${PNG_INCLUDE_DIR}) + list(APPEND LAMMPS_LINK_LIBS ${PNG_LIBRARIES}) add_definitions(-DLAMMPS_PNG) -else(PNG_FOUND) - set(PNG_LIBRARIES) endif(PNG_FOUND) ######################################################################## @@ -81,6 +76,7 @@ foreach(FUNC sin cos) message(FATAL_ERROR "Could not find needed math function - ${FUNC}") endif(NOT FOUND_${FUNC}_${MATH_LIBRARIES}) endforeach(FUNC) +list(APPEND LAMMPS_LINK_LIBS ${MATH_LIBRARIES}) ###################################### # Include the following subdirectory # @@ -93,6 +89,12 @@ file(GLOB LIB_SOURCES ${LAMMPS_SOURCE_DIR}/*.cpp) file(GLOB LMP_SOURCES ${LAMMPS_SOURCE_DIR}/main.cpp) list(REMOVE_ITEM LIB_SOURCES ${LMP_SOURCES}) +if(NOT ENABLE_MPI) + file(GLOB MPI_SOURCES ${LAMMPS_SOURCE_DIR}/STUBS/mpi.c) + list(APPEND LIB_SOURCES ${MPI_SOURCES}) + include_directories(${LAMMPS_SOURCE_DIR}/STUBS) +endif() + foreach(PKG ${PACKAGES}) if(ENABLE_${PKG}) file(GLOB ${PKG}_SOURCES ${LAMMPS_SOURCE_DIR}/${PKG}/*.cpp) @@ -112,8 +114,8 @@ include_directories(${CMAKE_SOURCE_DIR}/Headers) configure_file(${CMAKE_SOURCE_DIR}/Headers/package.h.cmakein ${CMAKE_BINARY_DIR}/cmake/package.h) include_directories(${CMAKE_BINARY_DIR}/cmake) -add_library(lammps ${LIB_SOURCES} ${MPI_SOURCES}) -target_link_libraries(lammps ${MPI_CXX_LIBRARIES} ${JPEG_LIBRARIES} ${PNG_LIBRARIES} ${MATH_LIBRARIES}) +add_library(lammps ${LIB_SOURCES}) +target_link_libraries(lammps ${LAMMPS_LINK_LIBS}) set_target_properties(lammps PROPERTIES SOVERSION ${SOVERSION}) install(TARGETS lammps LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) From e4e12521522b1bdbb57758f431d9ef08b6aa7792 Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Fri, 14 Jul 2017 14:44:44 -0600 Subject: [PATCH 264/439] fix LAMMPS_PNG --- cmake/CMakeLists.txt | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 074407650e..a21c81b9cd 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -50,11 +50,12 @@ if(JPEG_FOUND) endif() find_package(PNG) -if(PNG_FOUND) - include_directories(${PNG_INCLUDE_DIR}) - list(APPEND LAMMPS_LINK_LIBS ${PNG_LIBRARIES}) +find_package(ZLIB) +if(PNG_FOUND AND ZLIB_FOUND) + include_directories(${PNG_INCLUDE_DIRS} ${ZLIB_INCLUDE_DIRS}) + list(APPEND LAMMPS_LINK_LIBS ${PNG_LIBRARIES} ${ZLIB_LIBRARIES}) add_definitions(-DLAMMPS_PNG) -endif(PNG_FOUND) +endif() ######################################################################## # Basic system tests (standard libraries, headers, functions, types) # From c07adac22d577c4ad4cb6546480ca6c669018fdb Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Fri, 14 Jul 2017 14:49:53 -0600 Subject: [PATCH 265/439] add support for LAMMPS_GZIP --- cmake/CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index a21c81b9cd..9db55174fc 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -57,6 +57,11 @@ if(PNG_FOUND AND ZLIB_FOUND) add_definitions(-DLAMMPS_PNG) endif() +find_program(GZIP gzip) +if(GZIP) + add_definitions(-DLAMMPS_GZIP) +endif() + ######################################################################## # Basic system tests (standard libraries, headers, functions, types) # ######################################################################## From d5dcb3d32930c2efcd41bd394d21b283c46c78e6 Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Fri, 14 Jul 2017 15:55:36 -0600 Subject: [PATCH 266/439] add support for KSPACE --- cmake/CMakeLists.txt | 14 +++++++++++++- cmake/Headers/style_fix.h | 3 +++ cmake/Headers/style_kspace.h | 12 ++++++++++++ cmake/Headers/style_pair.h | 30 ++++++++++++++++++++++++++++++ cmake/Modules/FindFFTW3.cmake | 25 +++++++++++++++++++++++++ 5 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 cmake/Modules/FindFFTW3.cmake diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 9db55174fc..f0d121d834 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -5,6 +5,9 @@ set(SOVERSION 0) set(LAMMPS_SOURCE_DIR ${CMAKE_SOURCE_DIR}/../src) set(LAMMPS_LIB_SOURCE_DIR ${CMAKE_SOURCE_DIR}/../lib) +# Cmake modules/macros are in a subdirectory to keep this file cleaner +set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/Modules) + if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_C_FLAGS) #release comes with -O3 by default set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel." FORCE) @@ -37,11 +40,20 @@ find_package(UnixCommands) option(CMAKE_VERBOSE_MAKEFILE "Verbose makefile" OFF) -set(PACKAGES ASPHERE REAX) +set(PACKAGES ASPHERE KSPACE REAX) foreach(PKG ${PACKAGES}) option(ENABLE_${PKG} "Build ${PKG} Package" OFF) endforeach() +if(ENABLE_KSPACE) + find_package(FFTW3) + if(FFTW3_FOUND) + add_definitions(-DFFT_FFTW3) + include_directories(${FFTW3_INCLUDE_DIRS}) + list(APPEND LAMMPS_LINK_LIBS ${FFTW3_LIBRARIES}) + endif() +endif() + find_package(JPEG) if(JPEG_FOUND) add_definitions(-DLAMMPS_JPEG) diff --git a/cmake/Headers/style_fix.h b/cmake/Headers/style_fix.h index 146616124d..fb68f69135 100644 --- a/cmake/Headers/style_fix.h +++ b/cmake/Headers/style_fix.h @@ -82,6 +82,9 @@ #include "fix_temp_csvr.h" #include "fix_temp_rescale.h" #include "fix_tmd.h" +#ifdef ENABLE_KSPACE +#include "fix_tune_kspace.h" +#endif #include "fix_vector.h" #include "fix_viscous.h" #include "fix_wall_harmonic.h" diff --git a/cmake/Headers/style_kspace.h b/cmake/Headers/style_kspace.h index b2b5c1f82e..64760bb422 100644 --- a/cmake/Headers/style_kspace.h +++ b/cmake/Headers/style_kspace.h @@ -1 +1,13 @@ #include "package.h" +#ifdef ENABLE_KSPACE +#include "ewald.h" +#include "ewald_disp.h" +#include "msm.h" +#include "msm_cg.h" +#include "pppm.h" +#include "pppm_cg.h" +#include "pppm_disp.h" +#include "pppm_disp_tip4p.h" +#include "pppm_stagger.h" +#include "pppm_tip4p.h" +#endif diff --git a/cmake/Headers/style_pair.h b/cmake/Headers/style_pair.h index 067e2cdb23..e7676bfabf 100644 --- a/cmake/Headers/style_pair.h +++ b/cmake/Headers/style_pair.h @@ -2,12 +2,25 @@ #include "pair_beck.h" #include "pair_born.h" #include "pair_born_coul_dsf.h" +#ifdef ENABLE_KSPACE +#include "pair_born_coul_long.h" +#include "pair_born_coul_msm.h" +#endif #include "pair_born_coul_wolf.h" #include "pair_buck.h" #include "pair_buck_coul_cut.h" +#ifdef ENABLE_KSPACE +#include "pair_buck_coul_long.h" +#include "pair_buck_coul_msm.h" +#include "pair_buck_long_coul_long.h" +#endif #include "pair_coul_cut.h" #include "pair_coul_debye.h" #include "pair_coul_dsf.h" +#ifdef ENABLE_KSPACE +#include "pair_coul_long.h" +#include "pair_coul_msm.h" +#endif #include "pair_coul_streitz.h" #include "pair_coul_wolf.h" #include "pair_dpd.h" @@ -22,14 +35,28 @@ #include "pair_line_lj.h" #endif #include "pair_lj96_cut.h" +#ifdef ENABLE_KSPACE +#include "pair_lj_charmm_coul_long.h" +#include "pair_lj_charmm_coul_msm.h" +#include "pair_lj_charmmfsw_coul_long.h" +#endif #include "pair_lj_cubic.h" #include "pair_lj_cut.h" #include "pair_lj_cut_coul_cut.h" #include "pair_lj_cut_coul_debye.h" #include "pair_lj_cut_coul_dsf.h" +#ifdef ENABLE_KSPACE +#include "pair_lj_cut_coul_long.h" +#include "pair_lj_cut_coul_msm.h" +#include "pair_lj_cut_tip4p_long.h" +#endif #include "pair_lj_expand.h" #include "pair_lj_gromacs.h" #include "pair_lj_gromacs_coul_gromacs.h" +#ifdef ENABLE_KSPACE +#include "pair_lj_long_coul_long.h" +#include "pair_lj_long_tip4p_long.h" +#endif #include "pair_lj_smooth.h" #include "pair_lj_smooth_linear.h" #include "pair_mie_cut.h" @@ -42,6 +69,9 @@ #endif #include "pair_soft.h" #include "pair_table.h" +#ifdef ENABLE_KSPACE +#include "pair_tip4p_long.h" +#endif #ifdef ENABLE_ASPHERE #include "pair_tri_lj.h" #endif diff --git a/cmake/Modules/FindFFTW3.cmake b/cmake/Modules/FindFFTW3.cmake new file mode 100644 index 0000000000..552bcc4257 --- /dev/null +++ b/cmake/Modules/FindFFTW3.cmake @@ -0,0 +1,25 @@ +# - Find fftw3 +# Find the native FFTW3 headers and libraries. +# +# FFTW3_INCLUDE_DIRS - where to find fftw3.h, etc. +# FFTW3_LIBRARIES - List of libraries when using fftw3. +# FFTW3_FOUND - True if fftw3 found. +# + +find_package(PkgConfig) + +pkg_check_modules(PC_FFTW3 fftw3) +find_path(FFTW3_INCLUDE_DIR fftw3.h HINTS ${PC_FFTW3_INCLUDE_DIRS}) + +find_library(FFTW3_LIBRARY NAMES fftw3 HINTS ${PC_FFTW3_LIBRARY_DIRS}) + +set(FFTW3_LIBRARIES ${FFTW3_LIBRARY}) +set(FFTW3_INCLUDE_DIRS ${FFTW3_INCLUDE_DIR}) + +include(FindPackageHandleStandardArgs) +# handle the QUIETLY and REQUIRED arguments and set FFTW3_FOUND to TRUE +# if all listed variables are TRUE + +find_package_handle_standard_args(FFTW3 DEFAULT_MSG FFTW3_LIBRARY FFTW3_INCLUDE_DIR) + +mark_as_advanced(FFTW3_INCLUDE_DIR FFTW3_LIBRARY ) From 335ef11a7bf555dfcf524e35b142509fb8a572d3 Mon Sep 17 00:00:00 2001 From: Richard Berger Date: Fri, 14 Jul 2017 17:49:05 -0500 Subject: [PATCH 267/439] Added style header generation with CMake --- cmake/CMakeLists.txt | 41 +++++++++++-- cmake/Headers/package.h.cmakein | 2 - cmake/Headers/style_angle.h | 3 - cmake/Headers/style_atom.h | 9 --- cmake/Headers/style_body.h | 1 - cmake/Headers/style_bond.h | 3 - cmake/Headers/style_command.h | 23 ------- cmake/Headers/style_compute.h | 66 -------------------- cmake/Headers/style_dihedral.h | 3 - cmake/Headers/style_dump.h | 9 --- cmake/Headers/style_fix.h | 92 ---------------------------- cmake/Headers/style_improper.h | 3 - cmake/Headers/style_integrate.h | 3 - cmake/Headers/style_kspace.h | 1 - cmake/Headers/style_minimize.h | 6 -- cmake/Headers/style_nbin.h | 2 - cmake/Headers/style_npair.h | 36 ----------- cmake/Headers/style_nstencil.h | 21 ------- cmake/Headers/style_ntopo.h | 13 ---- cmake/Headers/style_pair.h | 50 --------------- cmake/Headers/style_reader.h | 3 - cmake/Headers/style_region.h | 9 --- cmake/Modules/StyleHeaderUtils.cmake | 81 ++++++++++++++++++++++++ 23 files changed, 117 insertions(+), 363 deletions(-) delete mode 100644 cmake/Headers/package.h.cmakein delete mode 100644 cmake/Headers/style_angle.h delete mode 100644 cmake/Headers/style_atom.h delete mode 100644 cmake/Headers/style_body.h delete mode 100644 cmake/Headers/style_bond.h delete mode 100644 cmake/Headers/style_command.h delete mode 100644 cmake/Headers/style_compute.h delete mode 100644 cmake/Headers/style_dihedral.h delete mode 100644 cmake/Headers/style_dump.h delete mode 100644 cmake/Headers/style_fix.h delete mode 100644 cmake/Headers/style_improper.h delete mode 100644 cmake/Headers/style_integrate.h delete mode 100644 cmake/Headers/style_kspace.h delete mode 100644 cmake/Headers/style_minimize.h delete mode 100644 cmake/Headers/style_nbin.h delete mode 100644 cmake/Headers/style_npair.h delete mode 100644 cmake/Headers/style_nstencil.h delete mode 100644 cmake/Headers/style_ntopo.h delete mode 100644 cmake/Headers/style_pair.h delete mode 100644 cmake/Headers/style_reader.h delete mode 100644 cmake/Headers/style_region.h create mode 100644 cmake/Modules/StyleHeaderUtils.cmake diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 9db55174fc..c69ca085e8 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -5,6 +5,8 @@ set(SOVERSION 0) set(LAMMPS_SOURCE_DIR ${CMAKE_SOURCE_DIR}/../src) set(LAMMPS_LIB_SOURCE_DIR ${CMAKE_SOURCE_DIR}/../lib) +set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/Modules) + if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_C_FLAGS) #release comes with -O3 by default set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel." FORCE) @@ -42,6 +44,11 @@ foreach(PKG ${PACKAGES}) option(ENABLE_${PKG} "Build ${PKG} Package" OFF) endforeach() +set(ACCEL_PACKAGES USER-OMP) +foreach(PKG ${ACCEL_PACKAGES}) + option(ENABLE_${PKG} "Build ${PKG} Package" OFF) +endforeach() + find_package(JPEG) if(JPEG_FOUND) add_definitions(-DLAMMPS_JPEG) @@ -101,24 +108,48 @@ if(NOT ENABLE_MPI) include_directories(${LAMMPS_SOURCE_DIR}/STUBS) endif() +include(StyleHeaderUtils) +RegisterStyles(${LAMMPS_SOURCE_DIR}) + +# packages which include entire content when enabled + foreach(PKG ${PACKAGES}) if(ENABLE_${PKG}) - file(GLOB ${PKG}_SOURCES ${LAMMPS_SOURCE_DIR}/${PKG}/*.cpp) + set(${PKG}_SOURCES_DIR ${LAMMPS_SOURCE_DIR}/${PKG}) + + # detects styles in package and adds them to global list + RegisterStyles(${${PKG}_SOURCES_DIR}) + + file(GLOB ${PKG}_SOURCES ${${PKG}_SOURCES_DIR}/*.cpp) list(APPEND LIB_SOURCES ${${PKG}_SOURCES}) - include_directories(${LAMMPS_SOURCE_DIR}/${PKG}) + include_directories(${${PKG}_SOURCES_DIR}) endif() endforeach() +# packages which selectively include variants based on enabled styles +# e.g. accelerator packages + +# TODO + if(ENABLE_REAX) enable_language(Fortran) file(GLOB REAX_SOURCES ${LAMMPS_LIB_SOURCE_DIR}/reax/*.F) list(APPEND LIB_SOURCES ${REAX_SOURCES}) include_directories(${LAMMPS_LIB_SOURCE_DIR}/reax) endif() + + +###################################################### +# Generate style headers based on global list of +# styles registered during package selection +###################################################### +set(LAMMPS_STYLE_HEADERS_DIR ${CMAKE_CURRENT_BINARY_DIR}/styles) + +GenerateStyleHeaders(${LAMMPS_STYLE_HEADERS_DIR}) + include_directories(${LAMMPS_SOURCE_DIR}) -include_directories(${CMAKE_SOURCE_DIR}/Headers) -configure_file(${CMAKE_SOURCE_DIR}/Headers/package.h.cmakein ${CMAKE_BINARY_DIR}/cmake/package.h) -include_directories(${CMAKE_BINARY_DIR}/cmake) +include_directories(${LAMMPS_STYLE_HEADERS_DIR}) + add_library(lammps ${LIB_SOURCES}) target_link_libraries(lammps ${LAMMPS_LINK_LIBS}) diff --git a/cmake/Headers/package.h.cmakein b/cmake/Headers/package.h.cmakein deleted file mode 100644 index 9c7ff403a4..0000000000 --- a/cmake/Headers/package.h.cmakein +++ /dev/null @@ -1,2 +0,0 @@ -#cmakedefine ENABLE_ASPHERE -#cmakedefine ENABLE_REAX diff --git a/cmake/Headers/style_angle.h b/cmake/Headers/style_angle.h deleted file mode 100644 index 8b395b557f..0000000000 --- a/cmake/Headers/style_angle.h +++ /dev/null @@ -1,3 +0,0 @@ -#include "package.h" -#include "angle_hybrid.h" -#include "angle_zero.h" diff --git a/cmake/Headers/style_atom.h b/cmake/Headers/style_atom.h deleted file mode 100644 index ec4e5d7d20..0000000000 --- a/cmake/Headers/style_atom.h +++ /dev/null @@ -1,9 +0,0 @@ -#include "package.h" -#include "atom_vec_atomic.h" -#include "atom_vec_body.h" -#include "atom_vec_charge.h" -#include "atom_vec_ellipsoid.h" -#include "atom_vec_hybrid.h" -#include "atom_vec_line.h" -#include "atom_vec_sphere.h" -#include "atom_vec_tri.h" diff --git a/cmake/Headers/style_body.h b/cmake/Headers/style_body.h deleted file mode 100644 index b2b5c1f82e..0000000000 --- a/cmake/Headers/style_body.h +++ /dev/null @@ -1 +0,0 @@ -#include "package.h" diff --git a/cmake/Headers/style_bond.h b/cmake/Headers/style_bond.h deleted file mode 100644 index d18a31ca91..0000000000 --- a/cmake/Headers/style_bond.h +++ /dev/null @@ -1,3 +0,0 @@ -#include "package.h" -#include "bond_hybrid.h" -#include "bond_zero.h" diff --git a/cmake/Headers/style_command.h b/cmake/Headers/style_command.h deleted file mode 100644 index d795f4ba0a..0000000000 --- a/cmake/Headers/style_command.h +++ /dev/null @@ -1,23 +0,0 @@ -#include "package.h" -#include "balance.h" -#include "change_box.h" -#include "create_atoms.h" -#include "create_bonds.h" -#include "create_box.h" -#include "delete_atoms.h" -#include "delete_bonds.h" -#include "displace_atoms.h" -#include "info.h" -#include "minimize.h" -#include "read_data.h" -#include "read_dump.h" -#include "read_restart.h" -#include "replicate.h" -#include "rerun.h" -#include "run.h" -#include "set.h" -#include "velocity.h" -#include "write_coeff.h" -#include "write_data.h" -#include "write_dump.h" -#include "write_restart.h" diff --git a/cmake/Headers/style_compute.h b/cmake/Headers/style_compute.h deleted file mode 100644 index bfcd053ed6..0000000000 --- a/cmake/Headers/style_compute.h +++ /dev/null @@ -1,66 +0,0 @@ -#include "package.h" -#include "compute_angle.h" -#include "compute_angle_local.h" -#include "compute_angmom_chunk.h" -#include "compute_bond.h" -#include "compute_bond_local.h" -#include "compute_centro_atom.h" -#include "compute_chunk_atom.h" -#include "compute_cluster_atom.h" -#include "compute_cna_atom.h" -#include "compute_com.h" -#include "compute_com_chunk.h" -#include "compute_contact_atom.h" -#include "compute_coord_atom.h" -#include "compute_dihedral.h" -#include "compute_dihedral_local.h" -#include "compute_dipole_chunk.h" -#include "compute_displace_atom.h" -#ifdef ENABLE_ASPHERE -#include "compute_erotate_asphere.h" -#endif -#include "compute_erotate_sphere.h" -#include "compute_erotate_sphere_atom.h" -#include "compute_global_atom.h" -#include "compute_group_group.h" -#include "compute_gyration.h" -#include "compute_gyration_chunk.h" -#include "compute_heat_flux.h" -#include "compute_hexorder_atom.h" -#include "compute_improper.h" -#include "compute_improper_local.h" -#include "compute_inertia_chunk.h" -#include "compute_ke.h" -#include "compute_ke_atom.h" -#include "compute_msd.h" -#include "compute_msd_chunk.h" -#include "compute_omega_chunk.h" -#include "compute_orientorder_atom.h" -#include "compute_pair.h" -#include "compute_pair_local.h" -#include "compute_pe.h" -#include "compute_pe_atom.h" -#include "compute_pressure.h" -#include "compute_property_atom.h" -#include "compute_property_chunk.h" -#include "compute_property_local.h" -#include "compute_rdf.h" -#include "compute_reduce.h" -#include "compute_reduce_region.h" -#include "compute_slice.h" -#include "compute_stress_atom.h" -#include "compute_temp.h" -#ifdef ENABLE_ASPHERE -#include "compute_temp_asphere.h" -#endif -#include "compute_temp_chunk.h" -#include "compute_temp_com.h" -#include "compute_temp_deform.h" -#include "compute_temp_partial.h" -#include "compute_temp_profile.h" -#include "compute_temp_ramp.h" -#include "compute_temp_region.h" -#include "compute_temp_sphere.h" -#include "compute_torque_chunk.h" -#include "compute_vacf.h" -#include "compute_vcm_chunk.h" diff --git a/cmake/Headers/style_dihedral.h b/cmake/Headers/style_dihedral.h deleted file mode 100644 index 26cb4a815a..0000000000 --- a/cmake/Headers/style_dihedral.h +++ /dev/null @@ -1,3 +0,0 @@ -#include "package.h" -#include "dihedral_hybrid.h" -#include "dihedral_zero.h" diff --git a/cmake/Headers/style_dump.h b/cmake/Headers/style_dump.h deleted file mode 100644 index bc8477a6bf..0000000000 --- a/cmake/Headers/style_dump.h +++ /dev/null @@ -1,9 +0,0 @@ -#include "package.h" -#include "dump_atom.h" -#include "dump_cfg.h" -#include "dump_custom.h" -#include "dump_dcd.h" -#include "dump_image.h" -#include "dump_local.h" -#include "dump_movie.h" -#include "dump_xyz.h" diff --git a/cmake/Headers/style_fix.h b/cmake/Headers/style_fix.h deleted file mode 100644 index 146616124d..0000000000 --- a/cmake/Headers/style_fix.h +++ /dev/null @@ -1,92 +0,0 @@ -#include "package.h" -#include "fix_adapt.h" -#include "fix_addforce.h" -#include "fix_ave_atom.h" -#include "fix_ave_chunk.h" -#include "fix_ave_correlate.h" -#include "fix_ave_histo.h" -#include "fix_ave_histo_weight.h" -#include "fix_ave_time.h" -#include "fix_aveforce.h" -#include "fix_balance.h" -#include "fix_box_relax.h" -#include "fix_controller.h" -#include "fix_deform.h" -#include "fix_deprecated.h" -#include "fix_drag.h" -#include "fix_dt_reset.h" -#include "fix_enforce2d.h" -#include "fix_external.h" -#include "fix_gravity.h" -#include "fix_group.h" -#include "fix_halt.h" -#include "fix_heat.h" -#include "fix_indent.h" -#include "fix_langevin.h" -#include "fix_lineforce.h" -#include "fix_minimize.h" -#include "fix_momentum.h" -#include "fix_move.h" -#include "fix_nph.h" -#ifdef ENABLE_ASPHERE -#include "fix_nph_asphere.h" -#endif -#include "fix_nph_sphere.h" -#include "fix_npt.h" -#ifdef ENABLE_ASPHERE -#include "fix_npt_asphere.h" -#endif -#include "fix_npt_sphere.h" -#include "fix_nve.h" -#ifdef ENABLE_ASPHERE -#include "fix_nve_asphere.h" -#include "fix_nve_asphere_noforce.h" -#endif -#include "fix_nve_limit.h" -#ifdef ENABLE_ASPHERE -#include "fix_nve_line.h" -#endif -#include "fix_nve_noforce.h" -#include "fix_nve_sphere.h" -#ifdef ENABLE_ASPHERE -#include "fix_nve_tri.h" -#endif -#include "fix_nvt.h" -#ifdef ENABLE_ASPHERE -#include "fix_nvt_asphere.h" -#endif -#include "fix_nvt_sllod.h" -#include "fix_nvt_sphere.h" -#include "fix_planeforce.h" -#include "fix_press_berendsen.h" -#include "fix_print.h" -#include "fix_property_atom.h" -#include "fix_read_restart.h" -#ifdef ENABLE_REAX -#include "fix_reax_bonds.h" -#endif -#include "fix_recenter.h" -#include "fix_respa.h" -#include "fix_restrain.h" -#include "fix_setforce.h" -#include "fix_shear_history.h" -#include "fix_spring.h" -#include "fix_spring_chunk.h" -#include "fix_spring_rg.h" -#include "fix_spring_self.h" -#include "fix_store.h" -#include "fix_store_force.h" -#include "fix_store_state.h" -#include "fix_temp_berendsen.h" -#include "fix_temp_csld.h" -#include "fix_temp_csvr.h" -#include "fix_temp_rescale.h" -#include "fix_tmd.h" -#include "fix_vector.h" -#include "fix_viscous.h" -#include "fix_wall_harmonic.h" -#include "fix_wall_lj1043.h" -#include "fix_wall_lj126.h" -#include "fix_wall_lj93.h" -#include "fix_wall_reflect.h" -#include "fix_wall_region.h" diff --git a/cmake/Headers/style_improper.h b/cmake/Headers/style_improper.h deleted file mode 100644 index 3de3047d73..0000000000 --- a/cmake/Headers/style_improper.h +++ /dev/null @@ -1,3 +0,0 @@ -#include "package.h" -#include "improper_hybrid.h" -#include "improper_zero.h" diff --git a/cmake/Headers/style_integrate.h b/cmake/Headers/style_integrate.h deleted file mode 100644 index 0a2fd00cf7..0000000000 --- a/cmake/Headers/style_integrate.h +++ /dev/null @@ -1,3 +0,0 @@ -#include "package.h" -#include "respa.h" -#include "verlet.h" diff --git a/cmake/Headers/style_kspace.h b/cmake/Headers/style_kspace.h deleted file mode 100644 index b2b5c1f82e..0000000000 --- a/cmake/Headers/style_kspace.h +++ /dev/null @@ -1 +0,0 @@ -#include "package.h" diff --git a/cmake/Headers/style_minimize.h b/cmake/Headers/style_minimize.h deleted file mode 100644 index 35d9188e8d..0000000000 --- a/cmake/Headers/style_minimize.h +++ /dev/null @@ -1,6 +0,0 @@ -#include "package.h" -#include "min_cg.h" -#include "min_fire.h" -#include "min_hftn.h" -#include "min_quickmin.h" -#include "min_sd.h" diff --git a/cmake/Headers/style_nbin.h b/cmake/Headers/style_nbin.h deleted file mode 100644 index f0d52b05bc..0000000000 --- a/cmake/Headers/style_nbin.h +++ /dev/null @@ -1,2 +0,0 @@ -#include "package.h" -#include "nbin_standard.h" diff --git a/cmake/Headers/style_npair.h b/cmake/Headers/style_npair.h deleted file mode 100644 index bd403ebeeb..0000000000 --- a/cmake/Headers/style_npair.h +++ /dev/null @@ -1,36 +0,0 @@ -#include "package.h" -#include "npair_copy.h" -#include "npair_full_bin.h" -#include "npair_full_bin_atomonly.h" -#include "npair_full_bin_ghost.h" -#include "npair_full_multi.h" -#include "npair_full_nsq.h" -#include "npair_full_nsq_ghost.h" -#include "npair_half_bin_atomonly_newton.h" -#include "npair_half_bin_newtoff.h" -#include "npair_half_bin_newtoff_ghost.h" -#include "npair_half_bin_newton.h" -#include "npair_half_bin_newton_tri.h" -#include "npair_half_multi_newtoff.h" -#include "npair_half_multi_newton.h" -#include "npair_half_multi_newton_tri.h" -#include "npair_half_nsq_newtoff.h" -#include "npair_half_nsq_newtoff_ghost.h" -#include "npair_half_nsq_newton.h" -#include "npair_half_respa_bin_newtoff.h" -#include "npair_half_respa_bin_newton.h" -#include "npair_half_respa_bin_newton_tri.h" -#include "npair_half_respa_nsq_newtoff.h" -#include "npair_half_respa_nsq_newton.h" -#include "npair_half_size_bin_newtoff.h" -#include "npair_half_size_bin_newton.h" -#include "npair_half_size_bin_newton_tri.h" -#include "npair_half_size_nsq_newtoff.h" -#include "npair_half_size_nsq_newton.h" -#include "npair_halffull_newtoff.h" -#include "npair_halffull_newton.h" -#include "npair_skip.h" -#include "npair_skip_respa.h" -#include "npair_skip_size.h" -#include "npair_skip_size_off2on.h" -#include "npair_skip_size_off2on_oneside.h" diff --git a/cmake/Headers/style_nstencil.h b/cmake/Headers/style_nstencil.h deleted file mode 100644 index d28e4b23b1..0000000000 --- a/cmake/Headers/style_nstencil.h +++ /dev/null @@ -1,21 +0,0 @@ -#include "package.h" -#include "nstencil_full_bin_2d.h" -#include "nstencil_full_bin_3d.h" -#include "nstencil_full_ghost_bin_2d.h" -#include "nstencil_full_ghost_bin_3d.h" -#include "nstencil_full_multi_2d.h" -#include "nstencil_full_multi_3d.h" -#include "nstencil_half_bin_2d_newtoff.h" -#include "nstencil_half_bin_2d_newton.h" -#include "nstencil_half_bin_2d_newton_tri.h" -#include "nstencil_half_bin_3d_newtoff.h" -#include "nstencil_half_bin_3d_newton.h" -#include "nstencil_half_bin_3d_newton_tri.h" -#include "nstencil_half_ghost_bin_2d_newtoff.h" -#include "nstencil_half_ghost_bin_3d_newtoff.h" -#include "nstencil_half_multi_2d_newtoff.h" -#include "nstencil_half_multi_2d_newton.h" -#include "nstencil_half_multi_2d_newton_tri.h" -#include "nstencil_half_multi_3d_newtoff.h" -#include "nstencil_half_multi_3d_newton.h" -#include "nstencil_half_multi_3d_newton_tri.h" diff --git a/cmake/Headers/style_ntopo.h b/cmake/Headers/style_ntopo.h deleted file mode 100644 index 130b10200f..0000000000 --- a/cmake/Headers/style_ntopo.h +++ /dev/null @@ -1,13 +0,0 @@ -#include "package.h" -#include "ntopo_angle_all.h" -#include "ntopo_angle_partial.h" -#include "ntopo_angle_template.h" -#include "ntopo_bond_all.h" -#include "ntopo_bond_partial.h" -#include "ntopo_bond_template.h" -#include "ntopo_dihedral_all.h" -#include "ntopo_dihedral_partial.h" -#include "ntopo_dihedral_template.h" -#include "ntopo_improper_all.h" -#include "ntopo_improper_partial.h" -#include "ntopo_improper_template.h" diff --git a/cmake/Headers/style_pair.h b/cmake/Headers/style_pair.h deleted file mode 100644 index 067e2cdb23..0000000000 --- a/cmake/Headers/style_pair.h +++ /dev/null @@ -1,50 +0,0 @@ -#include "package.h" -#include "pair_beck.h" -#include "pair_born.h" -#include "pair_born_coul_dsf.h" -#include "pair_born_coul_wolf.h" -#include "pair_buck.h" -#include "pair_buck_coul_cut.h" -#include "pair_coul_cut.h" -#include "pair_coul_debye.h" -#include "pair_coul_dsf.h" -#include "pair_coul_streitz.h" -#include "pair_coul_wolf.h" -#include "pair_dpd.h" -#include "pair_dpd_tstat.h" -#include "pair_gauss.h" -#ifdef ENABLE_ASPHERE -#include "pair_gayberne.h" -#endif -#include "pair_hybrid.h" -#include "pair_hybrid_overlay.h" -#ifdef ENABLE_ASPHERE -#include "pair_line_lj.h" -#endif -#include "pair_lj96_cut.h" -#include "pair_lj_cubic.h" -#include "pair_lj_cut.h" -#include "pair_lj_cut_coul_cut.h" -#include "pair_lj_cut_coul_debye.h" -#include "pair_lj_cut_coul_dsf.h" -#include "pair_lj_expand.h" -#include "pair_lj_gromacs.h" -#include "pair_lj_gromacs_coul_gromacs.h" -#include "pair_lj_smooth.h" -#include "pair_lj_smooth_linear.h" -#include "pair_mie_cut.h" -#include "pair_morse.h" -#ifdef ENABLE_REAX -#include "pair_reax.h" -#endif -#ifdef ENABLE_ASPHERE -#include "pair_resquared.h" -#endif -#include "pair_soft.h" -#include "pair_table.h" -#ifdef ENABLE_ASPHERE -#include "pair_tri_lj.h" -#endif -#include "pair_yukawa.h" -#include "pair_zbl.h" -#include "pair_zero.h" diff --git a/cmake/Headers/style_reader.h b/cmake/Headers/style_reader.h deleted file mode 100644 index 0b8145e13d..0000000000 --- a/cmake/Headers/style_reader.h +++ /dev/null @@ -1,3 +0,0 @@ -#include "package.h" -#include "reader_native.h" -#include "reader_xyz.h" diff --git a/cmake/Headers/style_region.h b/cmake/Headers/style_region.h deleted file mode 100644 index dc467b2a3d..0000000000 --- a/cmake/Headers/style_region.h +++ /dev/null @@ -1,9 +0,0 @@ -#include "package.h" -#include "region_block.h" -#include "region_cone.h" -#include "region_cylinder.h" -#include "region_intersect.h" -#include "region_plane.h" -#include "region_prism.h" -#include "region_sphere.h" -#include "region_union.h" diff --git a/cmake/Modules/StyleHeaderUtils.cmake b/cmake/Modules/StyleHeaderUtils.cmake new file mode 100644 index 0000000000..2ee9496671 --- /dev/null +++ b/cmake/Modules/StyleHeaderUtils.cmake @@ -0,0 +1,81 @@ +function(FindStyleHeaders path style_class file_pattern headers) + file(GLOB files "${path}/${file_pattern}*.h") + get_property(hlist GLOBAL PROPERTY ${headers}) + + foreach(file_name ${files}) + file(STRINGS ${file_name} is_style LIMIT_COUNT 1 REGEX ${style_class}) + if(is_style) + list(APPEND hlist ${file_name}) + endif() + endforeach() + set_property(GLOBAL PROPERTY ${headers} "${hlist}") +endfunction(FindStyleHeaders) + +function(CreateStyleHeader path filename) + math(EXPR N "${ARGC}-2") + + set(temp "") + if(N GREATER 0) + math(EXPR ARG_END "${ARGC}-1") + + foreach(IDX RANGE 2 ${ARG_END}) + list(GET ARGV ${IDX} FNAME) + get_filename_component(FNAME ${FNAME} NAME) + set(temp "${temp}#include \"${FNAME}\"\n") + endforeach() + endif() + message("Generating ${filename}...") + file(WRITE "${path}/${filename}" "${temp}" ) +endfunction(CreateStyleHeader) + +function(GenerateStyleHeader path property style) + get_property(files GLOBAL PROPERTY ${property}) + #message("${property} = ${files}") + CreateStyleHeader("${path}" "style_${style}.h" ${files}) +endfunction(GenerateStyleHeader) + +function(RegisterStyles search_path) + FindStyleHeaders(${search_path} ANGLE_CLASS angle_ ANGLE ) # angle ) # force + FindStyleHeaders(${search_path} ATOM_CLASS atom_vec_ ATOM_VEC ) # atom ) # atom atom_vec_hybrid + FindStyleHeaders(${search_path} BODY_CLASS body_ BODY ) # body ) # atom_vec_body + FindStyleHeaders(${search_path} BOND_CLASS bond_ BOND ) # bond ) # force + FindStyleHeaders(${search_path} COMMAND_CLASS "" COMMAND ) # command ) # input + FindStyleHeaders(${search_path} COMPUTE_CLASS compute_ COMPUTE ) # compute ) # modify + FindStyleHeaders(${search_path} DIHEDRAL_CLASS dihedral_ DIHEDRAL ) # dihedral ) # force + FindStyleHeaders(${search_path} DUMP_CLASS dump_ DUMP ) # dump ) # output write_dump + FindStyleHeaders(${search_path} FIX_CLASS fix_ FIX ) # fix ) # modify + FindStyleHeaders(${search_path} IMPROPER_CLASS improper_ IMPROPER ) # improper ) # force + FindStyleHeaders(${search_path} INTEGRATE_CLASS "" INTEGRATE ) # integrate ) # update + FindStyleHeaders(${search_path} KSPACE_CLASS "" KSPACE ) # kspace ) # force + FindStyleHeaders(${search_path} MINIMIZE_CLASS min_ MINIMIZE ) # minimize ) # update + FindStyleHeaders(${search_path} NBIN_CLASS nbin_ NBIN ) # nbin ) # neighbor + FindStyleHeaders(${search_path} NPAIR_CLASS npair_ NPAIR ) # npair ) # neighbor + FindStyleHeaders(${search_path} NSTENCIL_CLASS nstencil_ NSTENCIL ) # nstencil ) # neighbor + FindStyleHeaders(${search_path} NTOPO_CLASS ntopo_ NTOPO ) # ntopo ) # neighbor + FindStyleHeaders(${search_path} PAIR_CLASS pair_ PAIR ) # pair ) # force + FindStyleHeaders(${search_path} READER_CLASS reader_ READER ) # reader ) # read_dump + FindStyleHeaders(${search_path} REGION_CLASS region_ REGION ) # region ) # domain +endfunction(RegisterStyles) + +function(GenerateStyleHeaders output_path) + GenerateStyleHeader(${output_path} ANGLE angle ) # force + GenerateStyleHeader(${output_path} ATOM_VEC atom ) # atom atom_vec_hybrid + GenerateStyleHeader(${output_path} BODY body ) # atom_vec_body + GenerateStyleHeader(${output_path} BOND bond ) # force + GenerateStyleHeader(${output_path} COMMAND command ) # input + GenerateStyleHeader(${output_path} COMPUTE compute ) # modify + GenerateStyleHeader(${output_path} DIHEDRAL dihedral ) # force + GenerateStyleHeader(${output_path} DUMP dump ) # output write_dump + GenerateStyleHeader(${output_path} FIX fix ) # modify + GenerateStyleHeader(${output_path} IMPROPER improper ) # force + GenerateStyleHeader(${output_path} INTEGRATE integrate ) # update + GenerateStyleHeader(${output_path} KSPACE kspace ) # force + GenerateStyleHeader(${output_path} MINIMIZE minimize ) # update + GenerateStyleHeader(${output_path} NBIN nbin ) # neighbor + GenerateStyleHeader(${output_path} NPAIR npair ) # neighbor + GenerateStyleHeader(${output_path} NSTENCIL nstencil ) # neighbor + GenerateStyleHeader(${output_path} NTOPO ntopo ) # neighbor + GenerateStyleHeader(${output_path} PAIR pair ) # force + GenerateStyleHeader(${output_path} READER reader ) # read_dump + GenerateStyleHeader(${output_path} REGION region ) # domain +endfunction(GenerateStyleHeaders) From b85979503ffc41a83750efa5caae14e331af9091 Mon Sep 17 00:00:00 2001 From: Richard Berger Date: Fri, 14 Jul 2017 18:19:59 -0500 Subject: [PATCH 268/439] Add CMake support for more packages BODY, COLLOID, CLASS2, COMPRESS, CORESHELL, DIPOLE, GRANULAR, MC, MOLECULE, MANYBODY, RIGID --- cmake/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 74785d340f..7fc2304a4c 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -40,7 +40,7 @@ find_package(UnixCommands) option(CMAKE_VERBOSE_MAKEFILE "Verbose makefile" OFF) -set(PACKAGES ASPHERE KSPACE REAX) +set(PACKAGES ASPHERE BODY COLLOID CLASS2 COMPRESS CORESHELL DIPOLE GRANULAR KSPACE MC MOLECULE MANYBODY RIGID REAX) foreach(PKG ${PACKAGES}) option(ENABLE_${PKG} "Build ${PKG} Package" OFF) endforeach() From 0a6e9c8bf676a12ef9a6dad0c8b67eb2b10e5eff Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Fri, 14 Jul 2017 17:41:13 -0600 Subject: [PATCH 269/439] added ENABLE_ALL option --- cmake/CMakeLists.txt | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 7fc2304a4c..5cff0f0a54 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -40,9 +40,10 @@ find_package(UnixCommands) option(CMAKE_VERBOSE_MAKEFILE "Verbose makefile" OFF) +option(ENABLE_ALL "Build all packages" OFF) set(PACKAGES ASPHERE BODY COLLOID CLASS2 COMPRESS CORESHELL DIPOLE GRANULAR KSPACE MC MOLECULE MANYBODY RIGID REAX) foreach(PKG ${PACKAGES}) - option(ENABLE_${PKG} "Build ${PKG} Package" OFF) + option(ENABLE_${PKG} "Build ${PKG} Package" ${ENABLE_ALL}) endforeach() set(ACCEL_PACKAGES USER-OMP) @@ -169,3 +170,9 @@ install(TARGETS lammps LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTI add_executable(lmp ${LMP_SOURCES}) target_link_libraries(lmp lammps) install(TARGETS lammps DESTINATION ${CMAKE_INSTALL_BINDIR}) + +foreach(PKG ${PACKAGES} ${ACCEL_PACKAGES}) + if(ENABLE_${PKG}) + message(STATUS "Building package: ${PKG}") + endif() +endforeach() From 54f2b02ac813f5931a8e4118395ccc86078d583b Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Fri, 14 Jul 2017 18:33:27 -0600 Subject: [PATCH 270/439] cmake: fix install --- cmake/CMakeLists.txt | 10 ++++++++-- cmake/Modules/StyleHeaderUtils.cmake | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 5cff0f0a54..96d1595f6b 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -26,6 +26,7 @@ include(CheckCCompilerFlag) # User input options # ######################################################################## option(BUILD_SHARED_LIBS "Build shared libs" OFF) +option(INSTALL_LIB "Install lammps library and header" ON) include(GNUInstallDirs) set(LAMMPS_LINK_LIBS) @@ -165,11 +166,16 @@ include_directories(${LAMMPS_STYLE_HEADERS_DIR}) add_library(lammps ${LIB_SOURCES}) target_link_libraries(lammps ${LAMMPS_LINK_LIBS}) set_target_properties(lammps PROPERTIES SOVERSION ${SOVERSION}) -install(TARGETS lammps LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) +if(INSTALL_LIB) + install(TARGETS lammps LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) + install(FILES ${LAMMPS_SOURCE_DIR}/lammps.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) +elseif(NOT BUILD_SHARED_LIBS) + message(FATAL_ERROR "Shared library has to install, use -DBUILD_SHARED_LIBS=OFF to install lammps with a a library") +endif() add_executable(lmp ${LMP_SOURCES}) target_link_libraries(lmp lammps) -install(TARGETS lammps DESTINATION ${CMAKE_INSTALL_BINDIR}) +install(TARGETS lmp DESTINATION ${CMAKE_INSTALL_BINDIR}) foreach(PKG ${PACKAGES} ${ACCEL_PACKAGES}) if(ENABLE_${PKG}) diff --git a/cmake/Modules/StyleHeaderUtils.cmake b/cmake/Modules/StyleHeaderUtils.cmake index 2ee9496671..bbb93e6145 100644 --- a/cmake/Modules/StyleHeaderUtils.cmake +++ b/cmake/Modules/StyleHeaderUtils.cmake @@ -24,7 +24,7 @@ function(CreateStyleHeader path filename) set(temp "${temp}#include \"${FNAME}\"\n") endforeach() endif() - message("Generating ${filename}...") + message(STATUS "Generating ${filename}...") file(WRITE "${path}/${filename}" "${temp}" ) endfunction(CreateStyleHeader) From d079b2f758fe1a0235897d9f74376fda07a8ed69 Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Fri, 14 Jul 2017 18:37:06 -0600 Subject: [PATCH 271/439] CreateStyleHeader: use temp file --- cmake/Modules/StyleHeaderUtils.cmake | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cmake/Modules/StyleHeaderUtils.cmake b/cmake/Modules/StyleHeaderUtils.cmake index bbb93e6145..b0b9bd9418 100644 --- a/cmake/Modules/StyleHeaderUtils.cmake +++ b/cmake/Modules/StyleHeaderUtils.cmake @@ -25,7 +25,8 @@ function(CreateStyleHeader path filename) endforeach() endif() message(STATUS "Generating ${filename}...") - file(WRITE "${path}/${filename}" "${temp}" ) + file(WRITE "${path}/${filename}.tmp" "${temp}" ) + execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different "${path}/${filename}.tmp" "${path}/${filename}") endfunction(CreateStyleHeader) function(GenerateStyleHeader path property style) From 5e841bfe1522a4ea54baed7472d5ee74243bacfa Mon Sep 17 00:00:00 2001 From: Richard Berger Date: Fri, 14 Jul 2017 22:07:53 -0500 Subject: [PATCH 272/439] Added USER-OMP support to CMake build --- cmake/CMakeLists.txt | 28 ++++++++++++++-- cmake/Modules/StyleHeaderUtils.cmake | 50 ++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 2 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 7fc2304a4c..35c0708d36 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -45,7 +45,7 @@ foreach(PKG ${PACKAGES}) option(ENABLE_${PKG} "Build ${PKG} Package" OFF) endforeach() -set(ACCEL_PACKAGES USER-OMP) +set(ACCEL_PACKAGES USER_OMP) foreach(PKG ${ACCEL_PACKAGES}) option(ENABLE_${PKG} "Build ${PKG} Package" OFF) endforeach() @@ -139,7 +139,31 @@ endforeach() # packages which selectively include variants based on enabled styles # e.g. accelerator packages -# TODO +if(ENABLE_USER_OMP) + find_package(OpenMP REQUIRED) + if (OPENMP_FOUND) + set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") + else() + message(FATAL_ERROR "USER-OMP requires a compiler with OpenMP support") + endif() + + set(USER_OMP_SOURCES_DIR ${LAMMPS_SOURCE_DIR}/USER-OMP) + set(USER_OMP_SOURCES ${USER_OMP_SOURCES_DIR}/thr_data.cpp + ${USER_OMP_SOURCES_DIR}/thr_omp.cpp + ${USER_OMP_SOURCES_DIR}/fix_nh_omp.cpp + ${USER_OMP_SOURCES_DIR}/fix_nh_sphere_omp.cpp) + set_property(GLOBAL PROPERTY "OMP_SOURCES" "${USER_OMP_SOURCES}") + + # detects styles which have USER-OMP version + RegisterStylesExt(${USER_OMP_SOURCES_DIR} omp OMP_SOURCES) + + get_property(USER_OMP_SOURCES GLOBAL PROPERTY OMP_SOURCES) + + list(APPEND LIB_SOURCES ${USER_OMP_SOURCES}) + include_directories(${USER_OMP_SOURCES_DIR}) +endif() + if(ENABLE_REAX) enable_language(Fortran) diff --git a/cmake/Modules/StyleHeaderUtils.cmake b/cmake/Modules/StyleHeaderUtils.cmake index 2ee9496671..55a6c15223 100644 --- a/cmake/Modules/StyleHeaderUtils.cmake +++ b/cmake/Modules/StyleHeaderUtils.cmake @@ -11,6 +11,33 @@ function(FindStyleHeaders path style_class file_pattern headers) set_property(GLOBAL PROPERTY ${headers} "${hlist}") endfunction(FindStyleHeaders) +function(FindStyleHeadersExt path style_class extension headers sources) + get_property(hlist GLOBAL PROPERTY ${headers}) + get_property(slist GLOBAL PROPERTY ${sources}) + set(ext_list) + get_filename_component(abs_path "${path}" ABSOLUTE) + + foreach(file_name ${hlist}) + get_filename_component(basename ${file_name} NAME_WE) + set(ext_file_name "${abs_path}/${basename}_${extension}.h") + if(EXISTS "${ext_file_name}") + file(STRINGS ${ext_file_name} is_style LIMIT_COUNT 1 REGEX ${style_class}) + if(is_style) + list(APPEND ext_list ${ext_file_name}) + + set(source_file_name "${abs_path}/${basename}_${extension}.cpp") + if(EXISTS "${source_file_name}") + list(APPEND slist ${source_file_name}) + endif() + endif() + endif() + endforeach() + + list(APPEND hlist ${ext_list}) + set_property(GLOBAL PROPERTY ${headers} "${hlist}") + set_property(GLOBAL PROPERTY ${sources} "${slist}") +endfunction(FindStyleHeadersExt) + function(CreateStyleHeader path filename) math(EXPR N "${ARGC}-2") @@ -57,6 +84,29 @@ function(RegisterStyles search_path) FindStyleHeaders(${search_path} REGION_CLASS region_ REGION ) # region ) # domain endfunction(RegisterStyles) +function(RegisterStylesExt search_path extension sources) + FindStyleHeadersExt(${search_path} ANGLE_CLASS ${extension} ANGLE ${sources}) + FindStyleHeadersExt(${search_path} ATOM_CLASS ${extension} ATOM_VEC ${sources}) + FindStyleHeadersExt(${search_path} BODY_CLASS ${extension} BODY ${sources}) + FindStyleHeadersExt(${search_path} BOND_CLASS ${extension} BOND ${sources}) + FindStyleHeadersExt(${search_path} COMMAND_CLASS ${extension} COMMAND ${sources}) + FindStyleHeadersExt(${search_path} COMPUTE_CLASS ${extension} COMPUTE ${sources}) + FindStyleHeadersExt(${search_path} DIHEDRAL_CLASS ${extension} DIHEDRAL ${sources}) + FindStyleHeadersExt(${search_path} DUMP_CLASS ${extension} DUMP ${sources}) + FindStyleHeadersExt(${search_path} FIX_CLASS ${extension} FIX ${sources}) + FindStyleHeadersExt(${search_path} IMPROPER_CLASS ${extension} IMPROPER ${sources}) + FindStyleHeadersExt(${search_path} INTEGRATE_CLASS ${extension} INTEGRATE ${sources}) + FindStyleHeadersExt(${search_path} KSPACE_CLASS ${extension} KSPACE ${sources}) + FindStyleHeadersExt(${search_path} MINIMIZE_CLASS ${extension} MINIMIZE ${sources}) + FindStyleHeadersExt(${search_path} NBIN_CLASS ${extension} NBIN ${sources}) + FindStyleHeadersExt(${search_path} NPAIR_CLASS ${extension} NPAIR ${sources}) + FindStyleHeadersExt(${search_path} NSTENCIL_CLASS ${extension} NSTENCIL ${sources}) + FindStyleHeadersExt(${search_path} NTOPO_CLASS ${extension} NTOPO ${sources}) + FindStyleHeadersExt(${search_path} PAIR_CLASS ${extension} PAIR ${sources}) + FindStyleHeadersExt(${search_path} READER_CLASS ${extension} READER ${sources}) + FindStyleHeadersExt(${search_path} REGION_CLASS ${extension} REGION ${sources}) +endfunction(RegisterStylesExt) + function(GenerateStyleHeaders output_path) GenerateStyleHeader(${output_path} ANGLE angle ) # force GenerateStyleHeader(${output_path} ATOM_VEC atom ) # atom atom_vec_hybrid From acd315e97a7ce25fa2b1d8ef6825ecfd36ecc172 Mon Sep 17 00:00:00 2001 From: Richard Berger Date: Sat, 15 Jul 2017 15:33:36 -0500 Subject: [PATCH 273/439] Add basic KOKKOS support to CMake build --- cmake/CMakeLists.txt | 59 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index eb84d0eb6a..e23cfa67ff 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -4,6 +4,7 @@ project(lammps) set(SOVERSION 0) set(LAMMPS_SOURCE_DIR ${CMAKE_SOURCE_DIR}/../src) set(LAMMPS_LIB_SOURCE_DIR ${CMAKE_SOURCE_DIR}/../lib) +set(LAMMPS_LIB_BINARY_DIR ${CMAKE_BINARY_DIR}/lib) # Cmake modules/macros are in a subdirectory to keep this file cleaner set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/Modules) @@ -47,7 +48,7 @@ foreach(PKG ${PACKAGES}) option(ENABLE_${PKG} "Build ${PKG} Package" ${ENABLE_ALL}) endforeach() -set(ACCEL_PACKAGES USER_OMP) +set(ACCEL_PACKAGES USER_OMP KOKKOS) foreach(PKG ${ACCEL_PACKAGES}) option(ENABLE_${PKG} "Build ${PKG} Package" OFF) endforeach() @@ -61,6 +62,24 @@ if(ENABLE_KSPACE) endif() endif() +if(ENABLE_KOKKOS) + # starting with CMake 3.1 this is all you have to do to enforce C++11 + set (CMAKE_CXX_STANDARD 11) + set(LAMMPS_LIB_KOKKOS_SRC_DIR ${LAMMPS_LIB_SOURCE_DIR}/kokkos) + set(LAMMPS_LIB_KOKKOS_BIN_DIR ${LAMMPS_LIB_BINARY_DIR}/kokkos) + add_definitions(-DLMP_KOKKOS) + add_subdirectory(${LAMMPS_LIB_KOKKOS_SRC_DIR} ${LAMMPS_LIB_KOKKOS_BIN_DIR}) + message("KOKKOS_DIRS: ${Kokkos_INCLUDE_DIRS}") + + # TODO there probably is a better way + set(Kokkos_INCLUDE_DIRS ${LAMMPS_LIB_KOKKOS_SRC_DIR}/core/src + ${LAMMPS_LIB_KOKKOS_SRC_DIR}/containers/src + ${LAMMPS_LIB_KOKKOS_SRC_DIR}/algorithms/src + ${LAMMPS_LIB_KOKKOS_BIN_DIR}) + include_directories(${Kokkos_INCLUDE_DIRS}) + list(APPEND LAMMPS_LINK_LIBS ${Kokkos_LIBRARIES}) +endif() + find_package(JPEG) if(JPEG_FOUND) add_definitions(-DLAMMPS_JPEG) @@ -166,6 +185,38 @@ if(ENABLE_USER_OMP) include_directories(${USER_OMP_SOURCES_DIR}) endif() +if(ENABLE_KOKKOS) + find_package(OpenMP REQUIRED) + if (OPENMP_FOUND) + set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") + else() + message(FATAL_ERROR "USER-OMP requires a compiler with OpenMP support") + endif() + + set(KOKKOS_PKG_SOURCES_DIR ${LAMMPS_SOURCE_DIR}/KOKKOS) + set(KOKKOS_PKG_SOURCES ${KOKKOS_PKG_SOURCES_DIR}/kokkos.cpp + ${KOKKOS_PKG_SOURCES_DIR}/atom_kokkos.cpp + ${KOKKOS_PKG_SOURCES_DIR}/atom_vec_kokkos.cpp + ${KOKKOS_PKG_SOURCES_DIR}/comm_kokkos.cpp + ${KOKKOS_PKG_SOURCES_DIR}/comm_tiled_kokkos.cpp + ${KOKKOS_PKG_SOURCES_DIR}/neighbor_kokkos.cpp + ${KOKKOS_PKG_SOURCES_DIR}/neigh_list_kokkos.cpp + ${KOKKOS_PKG_SOURCES_DIR}/neigh_bond_kokkos.cpp + ${KOKKOS_PKG_SOURCES_DIR}/fix_nh_kokkos.cpp + ${KOKKOS_PKG_SOURCES_DIR}/domain_kokkos.cpp + ${KOKKOS_PKG_SOURCES_DIR}/modify_kokkos.cpp) + set_property(GLOBAL PROPERTY "KOKKOS_PKG_SOURCES" "${KOKKOS_PKG_SOURCES}") + + # detects styles which have KOKKOS version + RegisterStylesExt(${KOKKOS_PKG_SOURCES_DIR} kokkos KOKKOS_PKG_SOURCES) + + get_property(KOKKOS_PKG_SOURCES GLOBAL PROPERTY KOKKOS_PKG_SOURCES) + + list(APPEND LIB_SOURCES ${KOKKOS_PKG_SOURCES}) + include_directories(${KOKKOS_PKG_SOURCES_DIR}) +endif() + if(ENABLE_REAX) enable_language(Fortran) @@ -190,6 +241,11 @@ include_directories(${LAMMPS_STYLE_HEADERS_DIR}) add_library(lammps ${LIB_SOURCES}) target_link_libraries(lammps ${LAMMPS_LINK_LIBS}) set_target_properties(lammps PROPERTIES SOVERSION ${SOVERSION}) + +if(ENABLE_KOKKOS) + target_link_libraries(lammps kokkos) +endif() + if(INSTALL_LIB) install(TARGETS lammps LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) install(FILES ${LAMMPS_SOURCE_DIR}/lammps.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) @@ -199,6 +255,7 @@ endif() add_executable(lmp ${LMP_SOURCES}) target_link_libraries(lmp lammps) + install(TARGETS lmp DESTINATION ${CMAKE_INSTALL_BINDIR}) foreach(PKG ${PACKAGES} ${ACCEL_PACKAGES}) From 629f1129150d2b6af7ec28ba72aea0eac95aff50 Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Sat, 15 Jul 2017 16:44:03 -0600 Subject: [PATCH 274/439] add support for MEAM --- cmake/CMakeLists.txt | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index eb84d0eb6a..c0153e3d6b 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -42,7 +42,7 @@ find_package(UnixCommands) option(CMAKE_VERBOSE_MAKEFILE "Verbose makefile" OFF) option(ENABLE_ALL "Build all packages" OFF) -set(PACKAGES ASPHERE BODY COLLOID CLASS2 COMPRESS CORESHELL DIPOLE GRANULAR KSPACE MC MOLECULE MANYBODY RIGID REAX) +set(PACKAGES ASPHERE BODY CLASS2 COLLOID COMPRESS CORESHELL DIPOLE GRANULAR KSPACE MANYBODY MC MEAM MOLECULE RIGID REAX) foreach(PKG ${PACKAGES}) option(ENABLE_${PKG} "Build ${PKG} Package" ${ENABLE_ALL}) endforeach() @@ -167,13 +167,22 @@ if(ENABLE_USER_OMP) endif() -if(ENABLE_REAX) +if(ENABLE_REAX OR ENABLE_MEAM) enable_language(Fortran) +endif() + +if(ENABLE_REAX) file(GLOB REAX_SOURCES ${LAMMPS_LIB_SOURCE_DIR}/reax/*.F) list(APPEND LIB_SOURCES ${REAX_SOURCES}) include_directories(${LAMMPS_LIB_SOURCE_DIR}/reax) endif() +if(ENABLE_MEAM) + file(GLOB MEAM_SOURCES ${LAMMPS_LIB_SOURCE_DIR}/meam/*.F ${LAMMPS_LIB_SOURCE_DIR}/meam/*.c) + list(APPEND LIB_SOURCES ${MEAM_SOURCES}) + include_directories(${LAMMPS_LIB_SOURCE_DIR}/meam) +endif() + ###################################################### # Generate style headers based on global list of From 23540cfc94148a2388892f705491a865e93c7c40 Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Sat, 15 Jul 2017 16:46:20 -0600 Subject: [PATCH 275/439] enable MISC --- cmake/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index f81f8f120a..5aa8a7a358 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -43,7 +43,8 @@ find_package(UnixCommands) option(CMAKE_VERBOSE_MAKEFILE "Verbose makefile" OFF) option(ENABLE_ALL "Build all packages" OFF) -set(PACKAGES ASPHERE BODY CLASS2 COLLOID COMPRESS CORESHELL DIPOLE GRANULAR KSPACE MANYBODY MC MEAM MOLECULE RIGID REAX) +set(PACKAGES ASPHERE BODY CLASS2 COLLOID COMPRESS CORESHELL DIPOLE GRANULAR + KSPACE MANYBODY MC MEAM MISC MOLECULE RIGID REAX) foreach(PKG ${PACKAGES}) option(ENABLE_${PKG} "Build ${PKG} Package" ${ENABLE_ALL}) endforeach() From fa1f38596c08c4da5570d0d9fdd31969405a7de7 Mon Sep 17 00:00:00 2001 From: Richard Berger Date: Sat, 15 Jul 2017 18:29:33 -0500 Subject: [PATCH 276/439] Add support for PYTHON in CMake build --- cmake/CMakeLists.txt | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 5aa8a7a358..a16cad55eb 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -44,7 +44,7 @@ option(CMAKE_VERBOSE_MAKEFILE "Verbose makefile" OFF) option(ENABLE_ALL "Build all packages" OFF) set(PACKAGES ASPHERE BODY CLASS2 COLLOID COMPRESS CORESHELL DIPOLE GRANULAR - KSPACE MANYBODY MC MEAM MISC MOLECULE RIGID REAX) + KSPACE MANYBODY MC MEAM MISC MOLECULE PYTHON RIGID REAX) foreach(PKG ${PACKAGES}) option(ENABLE_${PKG} "Build ${PKG} Package" ${ENABLE_ALL}) endforeach() @@ -81,6 +81,17 @@ if(ENABLE_KOKKOS) list(APPEND LAMMPS_LINK_LIBS ${Kokkos_LIBRARIES}) endif() +if(ENABLE_PYTHON) + find_package(PythonLibs) + if(PYTHONLIBS_FOUND) + add_definitions(-DLMP_PYTHON) + include_directories(${PYTHON_INCLUDE_DIR}) + list(APPEND LAMMPS_LINK_LIBS ${PYTHON_LIBRARY}) + else() + message(FATAL_ERROR "Could not find needed Python libraries and headers") + endif() +endif() + find_package(JPEG) if(JPEG_FOUND) add_definitions(-DLAMMPS_JPEG) From 01f5136584b3faf7010f48feddb31257a7ce8803 Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Sun, 16 Jul 2017 08:22:19 -0600 Subject: [PATCH 277/439] cmake: clean up --- cmake/CMakeLists.txt | 89 +++++++++++++++++++------------------------- 1 file changed, 38 insertions(+), 51 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index a16cad55eb..7b1aa6363a 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -38,8 +38,6 @@ if(ENABLE_MPI) list(APPEND LAMMPS_LINK_LIBS ${MPI_CXX_LIBRARIES}) endif() -find_package(UnixCommands) - option(CMAKE_VERBOSE_MAKEFILE "Verbose makefile" OFF) option(ENABLE_ALL "Build all packages" OFF) @@ -64,13 +62,10 @@ if(ENABLE_KSPACE) endif() if(ENABLE_KOKKOS) - # starting with CMake 3.1 this is all you have to do to enforce C++11 - set (CMAKE_CXX_STANDARD 11) set(LAMMPS_LIB_KOKKOS_SRC_DIR ${LAMMPS_LIB_SOURCE_DIR}/kokkos) set(LAMMPS_LIB_KOKKOS_BIN_DIR ${LAMMPS_LIB_BINARY_DIR}/kokkos) add_definitions(-DLMP_KOKKOS) add_subdirectory(${LAMMPS_LIB_KOKKOS_SRC_DIR} ${LAMMPS_LIB_KOKKOS_BIN_DIR}) - message("KOKKOS_DIRS: ${Kokkos_INCLUDE_DIRS}") # TODO there probably is a better way set(Kokkos_INCLUDE_DIRS ${LAMMPS_LIB_KOKKOS_SRC_DIR}/core/src @@ -78,18 +73,14 @@ if(ENABLE_KOKKOS) ${LAMMPS_LIB_KOKKOS_SRC_DIR}/algorithms/src ${LAMMPS_LIB_KOKKOS_BIN_DIR}) include_directories(${Kokkos_INCLUDE_DIRS}) - list(APPEND LAMMPS_LINK_LIBS ${Kokkos_LIBRARIES}) + list(APPEND LAMMPS_LINK_LIBS kokkos) endif() if(ENABLE_PYTHON) - find_package(PythonLibs) - if(PYTHONLIBS_FOUND) - add_definitions(-DLMP_PYTHON) - include_directories(${PYTHON_INCLUDE_DIR}) - list(APPEND LAMMPS_LINK_LIBS ${PYTHON_LIBRARY}) - else() - message(FATAL_ERROR "Could not find needed Python libraries and headers") - endif() + find_package(PythonLibs REQUIRED) + add_definitions(-DLMP_PYTHON) + include_directories(${PYTHON_INCLUDE_DIR}) + list(APPEND LAMMPS_LINK_LIBS ${PYTHON_LIBRARY}) endif() find_package(JPEG) @@ -169,18 +160,43 @@ foreach(PKG ${PACKAGES}) endif() endforeach() +if(ENABLE_REAX OR ENABLE_MEAM) + enable_language(Fortran) +endif() + + +if(ENABLE_KOKKOS) + # starting with CMake 3.1 this is all you have to do to enforce C++11 + set(CMAKE_CXX_STANDARD 11) # C++11... + set(CMAKE_CXX_STANDARD_REQUIRED ON) #...is required... + set(CMAKE_CXX_EXTENSIONS OFF) #...without compiler extensions like gnu++11 +endif() + +if(ENABLE_USER_OMP OR ENABLE_KOKKOS) + find_package(OpenMP REQUIRED) + set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") +endif() + + +if(ENABLE_REAX) + file(GLOB REAX_SOURCES ${LAMMPS_LIB_SOURCE_DIR}/reax/*.F) + list(APPEND LIB_SOURCES ${REAX_SOURCES}) + include_directories(${LAMMPS_LIB_SOURCE_DIR}/reax) +endif() + +if(ENABLE_MEAM) + file(GLOB MEAM_SOURCES ${LAMMPS_LIB_SOURCE_DIR}/meam/*.F ${LAMMPS_LIB_SOURCE_DIR}/meam/*.c) + list(APPEND LIB_SOURCES ${MEAM_SOURCES}) + include_directories(${LAMMPS_LIB_SOURCE_DIR}/meam) +endif() + +###################################################################### # packages which selectively include variants based on enabled styles # e.g. accelerator packages +###################################################################### if(ENABLE_USER_OMP) - find_package(OpenMP REQUIRED) - if (OPENMP_FOUND) - set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") - set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") - else() - message(FATAL_ERROR "USER-OMP requires a compiler with OpenMP support") - endif() - set(USER_OMP_SOURCES_DIR ${LAMMPS_SOURCE_DIR}/USER-OMP) set(USER_OMP_SOURCES ${USER_OMP_SOURCES_DIR}/thr_data.cpp ${USER_OMP_SOURCES_DIR}/thr_omp.cpp @@ -198,14 +214,6 @@ if(ENABLE_USER_OMP) endif() if(ENABLE_KOKKOS) - find_package(OpenMP REQUIRED) - if (OPENMP_FOUND) - set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") - set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") - else() - message(FATAL_ERROR "USER-OMP requires a compiler with OpenMP support") - endif() - set(KOKKOS_PKG_SOURCES_DIR ${LAMMPS_SOURCE_DIR}/KOKKOS) set(KOKKOS_PKG_SOURCES ${KOKKOS_PKG_SOURCES_DIR}/kokkos.cpp ${KOKKOS_PKG_SOURCES_DIR}/atom_kokkos.cpp @@ -230,23 +238,6 @@ if(ENABLE_KOKKOS) endif() -if(ENABLE_REAX OR ENABLE_MEAM) - enable_language(Fortran) -endif() - -if(ENABLE_REAX) - file(GLOB REAX_SOURCES ${LAMMPS_LIB_SOURCE_DIR}/reax/*.F) - list(APPEND LIB_SOURCES ${REAX_SOURCES}) - include_directories(${LAMMPS_LIB_SOURCE_DIR}/reax) -endif() - -if(ENABLE_MEAM) - file(GLOB MEAM_SOURCES ${LAMMPS_LIB_SOURCE_DIR}/meam/*.F ${LAMMPS_LIB_SOURCE_DIR}/meam/*.c) - list(APPEND LIB_SOURCES ${MEAM_SOURCES}) - include_directories(${LAMMPS_LIB_SOURCE_DIR}/meam) -endif() - - ###################################################### # Generate style headers based on global list of # styles registered during package selection @@ -263,10 +254,6 @@ add_library(lammps ${LIB_SOURCES}) target_link_libraries(lammps ${LAMMPS_LINK_LIBS}) set_target_properties(lammps PROPERTIES SOVERSION ${SOVERSION}) -if(ENABLE_KOKKOS) - target_link_libraries(lammps kokkos) -endif() - if(INSTALL_LIB) install(TARGETS lammps LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) install(FILES ${LAMMPS_SOURCE_DIR}/lammps.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) From f50a757dc6d34f3a6379fadfa0bdec3ea3a76d3a Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Sun, 16 Jul 2017 08:32:14 -0600 Subject: [PATCH 278/439] added MPIIO support --- cmake/CMakeLists.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 7b1aa6363a..493bafc3ad 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -42,7 +42,7 @@ option(CMAKE_VERBOSE_MAKEFILE "Verbose makefile" OFF) option(ENABLE_ALL "Build all packages" OFF) set(PACKAGES ASPHERE BODY CLASS2 COLLOID COMPRESS CORESHELL DIPOLE GRANULAR - KSPACE MANYBODY MC MEAM MISC MOLECULE PYTHON RIGID REAX) + KSPACE MANYBODY MC MEAM MISC MOLECULE MPIIO PYTHON RIGID REAX) foreach(PKG ${PACKAGES}) option(ENABLE_${PKG} "Build ${PKG} Package" ${ENABLE_ALL}) endforeach() @@ -52,6 +52,10 @@ foreach(PKG ${ACCEL_PACKAGES}) option(ENABLE_${PKG} "Build ${PKG} Package" OFF) endforeach() +if(ENABLE_MPIIO AND NOT ENABLE_MPI) + message(FATAL_ERROR "MPIIO package needed to LAMMPS to be build with mpi") +endif() + if(ENABLE_KSPACE) find_package(FFTW3) if(FFTW3_FOUND) From 95d9d323075b204a0663f104f4a0b2efe20b9dcd Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Sun, 16 Jul 2017 10:37:24 -0600 Subject: [PATCH 279/439] add support for MSCG --- cmake/CMakeLists.txt | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 493bafc3ad..0032c8100e 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -42,7 +42,7 @@ option(CMAKE_VERBOSE_MAKEFILE "Verbose makefile" OFF) option(ENABLE_ALL "Build all packages" OFF) set(PACKAGES ASPHERE BODY CLASS2 COLLOID COMPRESS CORESHELL DIPOLE GRANULAR - KSPACE MANYBODY MC MEAM MISC MOLECULE MPIIO PYTHON RIGID REAX) + KSPACE MANYBODY MC MEAM MISC MOLECULE MSCG MPIIO PYTHON RIGID REAX) foreach(PKG ${PACKAGES}) option(ENABLE_${PKG} "Build ${PKG} Package" ${ENABLE_ALL}) endforeach() @@ -169,7 +169,7 @@ if(ENABLE_REAX OR ENABLE_MEAM) endif() -if(ENABLE_KOKKOS) +if(ENABLE_KOKKOS OR ENABLE_MSCG) # starting with CMake 3.1 this is all you have to do to enforce C++11 set(CMAKE_CXX_STANDARD 11) # C++11... set(CMAKE_CXX_STANDARD_REQUIRED ON) #...is required... @@ -195,6 +195,33 @@ if(ENABLE_MEAM) include_directories(${LAMMPS_LIB_SOURCE_DIR}/meam) endif() +if(ENABLE_MSCG) + find_package(GSL REQUIRED) + find_package(LAPACK REQUIRED) + set(LAMMPS_LIB_MSCG_BIN_DIR ${LAMMPS_LIB_BINARY_DIR}/mscg) + set(MSCG_TARBALL ${LAMMPS_LIB_MSCG_BIN_DIR}/MS-CG-master.zip) + set(LAMMPS_LIB_MSCG_BIN_DIR ${LAMMPS_LIB_MSCG_BIN_DIR}/MSCG-release-master/src) + if(NOT EXISTS ${LAMMPS_LIB_MSCG_BIN_DIR}) + if(NOT EXISTS ${MSCG_TARBALL}) + message(STATUS "Downloading ${MSCG_TARBALL}") + file(DOWNLOAD + https://github.com/uchicago-voth/MSCG-release/archive/master.zip + ${MSCG_TARBALL} SHOW_PROGRESS) #EXPECTED_MD5 cannot be due due to master + endif() + message(STATUS "Unpacking ${MSCG_TARBALL}") + execute_process(COMMAND ${CMAKE_COMMAND} -E tar xvf ${MSCG_TARBALL} + WORKING_DIRECTORY ${LAMMPS_LIB_BINARY_DIR}/mscg) + endif() + file(GLOB MSCG_SOURCES ${LAMMPS_LIB_MSCG_BIN_DIR}/*.cpp) + list(APPEND LIB_SOURCES ${MSCG_SOURCES}) + foreach(MSCG_SOURCE ${MSCG_SOURCES}) + set_property(SOURCE ${MSCG_SOURCE} APPEND PROPERTY COMPILE_DEFINITIONS + DIMENSION=3 _exclude_gromacs=1) + endforeach() + include_directories(${LAMMPS_LIB_MSCG_BIN_DIR} ${GSL_INCLUDE_DIRS}) + list(APPEND LAMMPS_LINK_LIBS ${GSL_LIBRARIES} ${LAPACK_LIBRARIES}) +endif() + ###################################################################### # packages which selectively include variants based on enabled styles # e.g. accelerator packages From 4812d4c659f6e3e7e178744f5721e0419e2da442 Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Sun, 16 Jul 2017 10:48:29 -0600 Subject: [PATCH 280/439] enable PERI --- cmake/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 0032c8100e..eb613a8089 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -42,7 +42,7 @@ option(CMAKE_VERBOSE_MAKEFILE "Verbose makefile" OFF) option(ENABLE_ALL "Build all packages" OFF) set(PACKAGES ASPHERE BODY CLASS2 COLLOID COMPRESS CORESHELL DIPOLE GRANULAR - KSPACE MANYBODY MC MEAM MISC MOLECULE MSCG MPIIO PYTHON RIGID REAX) + KSPACE MANYBODY MC MEAM MISC MOLECULE MSCG MPIIO PERI PYTHON RIGID REAX) foreach(PKG ${PACKAGES}) option(ENABLE_${PKG} "Build ${PKG} Package" ${ENABLE_ALL}) endforeach() From 742eee1966c1c43e3df1700a08b7dfe81d431d99 Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Sun, 16 Jul 2017 11:07:36 -0600 Subject: [PATCH 281/439] added support for POEMS --- cmake/CMakeLists.txt | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index eb613a8089..7f825f012e 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -42,7 +42,7 @@ option(CMAKE_VERBOSE_MAKEFILE "Verbose makefile" OFF) option(ENABLE_ALL "Build all packages" OFF) set(PACKAGES ASPHERE BODY CLASS2 COLLOID COMPRESS CORESHELL DIPOLE GRANULAR - KSPACE MANYBODY MC MEAM MISC MOLECULE MSCG MPIIO PERI PYTHON RIGID REAX) + KSPACE MANYBODY MC MEAM MISC MOLECULE MSCG MPIIO PERI POEMS PYTHON RIGID REAX) foreach(PKG ${PACKAGES}) option(ENABLE_${PKG} "Build ${PKG} Package" ${ENABLE_ALL}) endforeach() @@ -182,18 +182,15 @@ if(ENABLE_USER_OMP OR ENABLE_KOKKOS) set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") endif() - -if(ENABLE_REAX) - file(GLOB REAX_SOURCES ${LAMMPS_LIB_SOURCE_DIR}/reax/*.F) - list(APPEND LIB_SOURCES ${REAX_SOURCES}) - include_directories(${LAMMPS_LIB_SOURCE_DIR}/reax) -endif() - -if(ENABLE_MEAM) - file(GLOB MEAM_SOURCES ${LAMMPS_LIB_SOURCE_DIR}/meam/*.F ${LAMMPS_LIB_SOURCE_DIR}/meam/*.c) - list(APPEND LIB_SOURCES ${MEAM_SOURCES}) - include_directories(${LAMMPS_LIB_SOURCE_DIR}/meam) -endif() +foreach(SIMPLE_LIB REAX MEAM POEMS) + if(ENABLE_${SIMPLE_LIB}) + string(TOLOWER "${SIMPLE_LIB}" INC_DIR) + file(GLOB ${SIMPLE_LIB}_SOURCES ${LAMMPS_LIB_SOURCE_DIR}/${INC_DIR}/*.F + ${LAMMPS_LIB_SOURCE_DIR}/${INC_DIR}/*.c ${LAMMPS_LIB_SOURCE_DIR}/${INC_DIR}/*.cpp) + list(APPEND LIB_SOURCES ${${SIMPLE_LIB}_SOURCES}) + include_directories(${LAMMPS_LIB_SOURCE_DIR}/${INC_DIR}) + endif() +endforeach() if(ENABLE_MSCG) find_package(GSL REQUIRED) From 140182fb0bb01c46d50352c347c24c8cc2eb9be5 Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Sun, 16 Jul 2017 11:14:08 -0600 Subject: [PATCH 282/439] added support for QEQ --- cmake/CMakeLists.txt | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 7f825f012e..d6289fb37c 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -42,7 +42,8 @@ option(CMAKE_VERBOSE_MAKEFILE "Verbose makefile" OFF) option(ENABLE_ALL "Build all packages" OFF) set(PACKAGES ASPHERE BODY CLASS2 COLLOID COMPRESS CORESHELL DIPOLE GRANULAR - KSPACE MANYBODY MC MEAM MISC MOLECULE MSCG MPIIO PERI POEMS PYTHON RIGID REAX) + KSPACE MANYBODY MC MEAM MISC MOLECULE MSCG MPIIO PERI POEMS PYTHON RIGID QEQ + REAX) foreach(PKG ${PACKAGES}) option(ENABLE_${PKG} "Build ${PKG} Package" ${ENABLE_ALL}) endforeach() @@ -52,9 +53,14 @@ foreach(PKG ${ACCEL_PACKAGES}) option(ENABLE_${PKG} "Build ${PKG} Package" OFF) endforeach() -if(ENABLE_MPIIO AND NOT ENABLE_MPI) - message(FATAL_ERROR "MPIIO package needed to LAMMPS to be build with mpi") -endif() +macro(pkg_depends PKG1 PKG2) + if(ENABLE_${PKG1} AND NOT ENABLE_${PKG2}) + message(FATAL_ERROR "${PKG1} package needed to LAMMPS to be build with ${PKG2}") + endif() +endmacro() + +pkg_depends(MPIIO MPI) +pkg_depends(QEQ MANYBODY) if(ENABLE_KSPACE) find_package(FFTW3) From c549a16a85ad022796841e0de3daf05733b7a906 Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Sun, 16 Jul 2017 11:29:31 -0600 Subject: [PATCH 283/439] enable REPLICA RIGID SHOCK SNAP SRD VORONOI --- cmake/CMakeLists.txt | 11 +++++++++-- cmake/Modules/FindVORO.cmake | 22 ++++++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 cmake/Modules/FindVORO.cmake diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index d6289fb37c..54864a8a48 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -42,8 +42,8 @@ option(CMAKE_VERBOSE_MAKEFILE "Verbose makefile" OFF) option(ENABLE_ALL "Build all packages" OFF) set(PACKAGES ASPHERE BODY CLASS2 COLLOID COMPRESS CORESHELL DIPOLE GRANULAR - KSPACE MANYBODY MC MEAM MISC MOLECULE MSCG MPIIO PERI POEMS PYTHON RIGID QEQ - REAX) + KSPACE MANYBODY MC MEAM MISC MOLECULE MSCG MPIIO PERI POEMS PYTHON QEQ + REAX REPLICA RIGID SHOCK SNAP SRD VORONOI) foreach(PKG ${PACKAGES}) option(ENABLE_${PKG} "Build ${PKG} Package" ${ENABLE_ALL}) endforeach() @@ -113,6 +113,13 @@ if(GZIP) add_definitions(-DLAMMPS_GZIP) endif() +if(ENABLE_VORONOI) + find_package(VORO REQUIRED) #some distros + include_directories(${VORO_INCLUDE_DIRS}) + list(APPEND LAMMPS_LINK_LIBS ${VORO_LIBRARIES}) + #TODO download and build voro++ +endif() + ######################################################################## # Basic system tests (standard libraries, headers, functions, types) # ######################################################################## diff --git a/cmake/Modules/FindVORO.cmake b/cmake/Modules/FindVORO.cmake new file mode 100644 index 0000000000..b0cccbcd1d --- /dev/null +++ b/cmake/Modules/FindVORO.cmake @@ -0,0 +1,22 @@ +# - Find voro++ +# Find the native VORO headers and libraries. +# +# VORO_INCLUDE_DIRS - where to find voro++.hh, etc. +# VORO_LIBRARIES - List of libraries when using voro++. +# VORO_FOUND - True if voro++ found. +# + +find_path(VORO_INCLUDE_DIR voro++.hh PATH_SUFFIXES voro++) + +find_library(VORO_LIBRARY NAMES voro++) + +set(VORO_LIBRARIES ${VORO_LIBRARY}) +set(VORO_INCLUDE_DIRS ${VORO_INCLUDE_DIR}) + +include(FindPackageHandleStandardArgs) +# handle the QUIETLY and REQUIRED arguments and set VORO_FOUND to TRUE +# if all listed variables are TRUE + +find_package_handle_standard_args(VORO DEFAULT_MSG VORO_LIBRARY VORO_INCLUDE_DIR) + +mark_as_advanced(VORO_INCLUDE_DIR VORO_LIBRARY ) From c64424754d32705c6fc5dc7f867baea94e5dd204 Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Sun, 16 Jul 2017 16:18:58 -0600 Subject: [PATCH 284/439] added USER-ATC --- cmake/CMakeLists.txt | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 54864a8a48..46203f43dc 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -43,7 +43,7 @@ option(CMAKE_VERBOSE_MAKEFILE "Verbose makefile" OFF) option(ENABLE_ALL "Build all packages" OFF) set(PACKAGES ASPHERE BODY CLASS2 COLLOID COMPRESS CORESHELL DIPOLE GRANULAR KSPACE MANYBODY MC MEAM MISC MOLECULE MSCG MPIIO PERI POEMS PYTHON QEQ - REAX REPLICA RIGID SHOCK SNAP SRD VORONOI) + REAX REPLICA RIGID SHOCK SNAP SRD VORONOI USER-ATC) foreach(PKG ${PACKAGES}) option(ENABLE_${PKG} "Build ${PKG} Package" ${ENABLE_ALL}) endforeach() @@ -55,12 +55,13 @@ endforeach() macro(pkg_depends PKG1 PKG2) if(ENABLE_${PKG1} AND NOT ENABLE_${PKG2}) - message(FATAL_ERROR "${PKG1} package needed to LAMMPS to be build with ${PKG2}") + message(FATAL_ERROR "${PKG1} package needs LAMMPS to be build with ${PKG2}") endif() endmacro() pkg_depends(MPIIO MPI) pkg_depends(QEQ MANYBODY) +pkg_depends(USER-ATC MANYBODY) if(ENABLE_KSPACE) find_package(FFTW3) @@ -86,6 +87,11 @@ if(ENABLE_KOKKOS) list(APPEND LAMMPS_LINK_LIBS kokkos) endif() +if(ENABLE_MSCG OR ENABLE_USER-ATC) + find_package(LAPACK REQUIRED) + list(APPEND LAMMPS_LINK_LIBS ${LAPACK_LIBRARIES}) +endif() + if(ENABLE_PYTHON) find_package(PythonLibs REQUIRED) add_definitions(-DLMP_PYTHON) @@ -195,8 +201,9 @@ if(ENABLE_USER_OMP OR ENABLE_KOKKOS) set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") endif() -foreach(SIMPLE_LIB REAX MEAM POEMS) +foreach(SIMPLE_LIB REAX MEAM POEMS USER-ATC) if(ENABLE_${SIMPLE_LIB}) + string(REGEX REPLACE "^USER-" "" SIMPLE_LIB "${SIMPLE_LIB}") string(TOLOWER "${SIMPLE_LIB}" INC_DIR) file(GLOB ${SIMPLE_LIB}_SOURCES ${LAMMPS_LIB_SOURCE_DIR}/${INC_DIR}/*.F ${LAMMPS_LIB_SOURCE_DIR}/${INC_DIR}/*.c ${LAMMPS_LIB_SOURCE_DIR}/${INC_DIR}/*.cpp) @@ -207,7 +214,6 @@ endforeach() if(ENABLE_MSCG) find_package(GSL REQUIRED) - find_package(LAPACK REQUIRED) set(LAMMPS_LIB_MSCG_BIN_DIR ${LAMMPS_LIB_BINARY_DIR}/mscg) set(MSCG_TARBALL ${LAMMPS_LIB_MSCG_BIN_DIR}/MS-CG-master.zip) set(LAMMPS_LIB_MSCG_BIN_DIR ${LAMMPS_LIB_MSCG_BIN_DIR}/MSCG-release-master/src) @@ -229,7 +235,7 @@ if(ENABLE_MSCG) DIMENSION=3 _exclude_gromacs=1) endforeach() include_directories(${LAMMPS_LIB_MSCG_BIN_DIR} ${GSL_INCLUDE_DIRS}) - list(APPEND LAMMPS_LINK_LIBS ${GSL_LIBRARIES} ${LAPACK_LIBRARIES}) + list(APPEND LAMMPS_LINK_LIBS ${GSL_LIBRARIES}) endif() ###################################################################### From d50b62837b42c9390e3bdf6c2d160bee4c1fba3d Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Sun, 16 Jul 2017 16:45:28 -0600 Subject: [PATCH 285/439] add USER-AWPMD --- cmake/CMakeLists.txt | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 46203f43dc..b1990b1a9c 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -43,7 +43,7 @@ option(CMAKE_VERBOSE_MAKEFILE "Verbose makefile" OFF) option(ENABLE_ALL "Build all packages" OFF) set(PACKAGES ASPHERE BODY CLASS2 COLLOID COMPRESS CORESHELL DIPOLE GRANULAR KSPACE MANYBODY MC MEAM MISC MOLECULE MSCG MPIIO PERI POEMS PYTHON QEQ - REAX REPLICA RIGID SHOCK SNAP SRD VORONOI USER-ATC) + REAX REPLICA RIGID SHOCK SNAP SRD VORONOI USER-ATC USER-AWPMD) foreach(PKG ${PACKAGES}) option(ENABLE_${PKG} "Build ${PKG} Package" ${ENABLE_ALL}) endforeach() @@ -87,9 +87,10 @@ if(ENABLE_KOKKOS) list(APPEND LAMMPS_LINK_LIBS kokkos) endif() -if(ENABLE_MSCG OR ENABLE_USER-ATC) +if(ENABLE_MSCG OR ENABLE_USER-ATC OR ENABLE_USER-AWPMD) find_package(LAPACK REQUIRED) list(APPEND LAMMPS_LINK_LIBS ${LAPACK_LIBRARIES}) + #TODO use lib/lapack endif() if(ENABLE_PYTHON) @@ -201,17 +202,22 @@ if(ENABLE_USER_OMP OR ENABLE_KOKKOS) set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") endif() -foreach(SIMPLE_LIB REAX MEAM POEMS USER-ATC) +foreach(SIMPLE_LIB REAX MEAM POEMS USER-ATC USER-AWPMD) if(ENABLE_${SIMPLE_LIB}) string(REGEX REPLACE "^USER-" "" SIMPLE_LIB "${SIMPLE_LIB}") string(TOLOWER "${SIMPLE_LIB}" INC_DIR) - file(GLOB ${SIMPLE_LIB}_SOURCES ${LAMMPS_LIB_SOURCE_DIR}/${INC_DIR}/*.F + file(GLOB_RECURSE ${SIMPLE_LIB}_SOURCES ${LAMMPS_LIB_SOURCE_DIR}/${INC_DIR}/*.F ${LAMMPS_LIB_SOURCE_DIR}/${INC_DIR}/*.c ${LAMMPS_LIB_SOURCE_DIR}/${INC_DIR}/*.cpp) list(APPEND LIB_SOURCES ${${SIMPLE_LIB}_SOURCES}) include_directories(${LAMMPS_LIB_SOURCE_DIR}/${INC_DIR}) endif() endforeach() +if(ENABLE_USER-AWPMD) + include_directories(${LAMMPS_LIB_SOURCE_DIR}/awpmd/systems/interact + ${LAMMPS_LIB_SOURCE_DIR}/awpmd/ivutils/include) +endif() + if(ENABLE_MSCG) find_package(GSL REQUIRED) set(LAMMPS_LIB_MSCG_BIN_DIR ${LAMMPS_LIB_BINARY_DIR}/mscg) From bb87bd4ac74d4bc5bb1a9b9e3db2562bdacf1984 Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Sun, 16 Jul 2017 17:01:28 -0600 Subject: [PATCH 286/439] enable more user packages --- cmake/CMakeLists.txt | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index b1990b1a9c..43d8f5decf 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -43,7 +43,9 @@ option(CMAKE_VERBOSE_MAKEFILE "Verbose makefile" OFF) option(ENABLE_ALL "Build all packages" OFF) set(PACKAGES ASPHERE BODY CLASS2 COLLOID COMPRESS CORESHELL DIPOLE GRANULAR KSPACE MANYBODY MC MEAM MISC MOLECULE MSCG MPIIO PERI POEMS PYTHON QEQ - REAX REPLICA RIGID SHOCK SNAP SRD VORONOI USER-ATC USER-AWPMD) + REAX REPLICA RIGID SHOCK SNAP SRD VORONOI USER-ATC USER-AWPMD USER-CGDNA + USER-CGSDK USER-COLVARS USER-DIFFRACTION USER-DPD USER-DRUDE USER-EFF + USER-FEP USER-H5MD USER-LB) foreach(PKG ${PACKAGES}) option(ENABLE_${PKG} "Build ${PKG} Package" ${ENABLE_ALL}) endforeach() @@ -62,6 +64,8 @@ endmacro() pkg_depends(MPIIO MPI) pkg_depends(QEQ MANYBODY) pkg_depends(USER-ATC MANYBODY) +pkg_depends(USER-H5MD MPI) +pkg_depends(USER-LB MPI) if(ENABLE_KSPACE) find_package(FFTW3) @@ -202,7 +206,7 @@ if(ENABLE_USER_OMP OR ENABLE_KOKKOS) set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") endif() -foreach(SIMPLE_LIB REAX MEAM POEMS USER-ATC USER-AWPMD) +foreach(SIMPLE_LIB REAX MEAM POEMS USER-ATC USER-AWPMD USER-COLVARS USER-H5MD) if(ENABLE_${SIMPLE_LIB}) string(REGEX REPLACE "^USER-" "" SIMPLE_LIB "${SIMPLE_LIB}") string(TOLOWER "${SIMPLE_LIB}" INC_DIR) @@ -218,6 +222,12 @@ if(ENABLE_USER-AWPMD) ${LAMMPS_LIB_SOURCE_DIR}/awpmd/ivutils/include) endif() +if(ENABLE_USER-H5MD) + find_package(HDF5 REQUIRED) + list(APPEND LAMMPS_LINK_LIBS ${HDF5_LIBRARIES}) + include_directories(${HDF5_INCLUDE_DIRS} ${LAMMPS_LIB_SOURCE_DIR}/h5md/include) +endif() + if(ENABLE_MSCG) find_package(GSL REQUIRED) set(LAMMPS_LIB_MSCG_BIN_DIR ${LAMMPS_LIB_BINARY_DIR}/mscg) From fc2e8b3c5ed552306daf31cba4af56eef3e67861 Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Sun, 16 Jul 2017 17:52:43 -0600 Subject: [PATCH 287/439] more USER packages --- cmake/CMakeLists.txt | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 43d8f5decf..ed0eeaacdd 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -45,7 +45,9 @@ set(PACKAGES ASPHERE BODY CLASS2 COLLOID COMPRESS CORESHELL DIPOLE GRANULAR KSPACE MANYBODY MC MEAM MISC MOLECULE MSCG MPIIO PERI POEMS PYTHON QEQ REAX REPLICA RIGID SHOCK SNAP SRD VORONOI USER-ATC USER-AWPMD USER-CGDNA USER-CGSDK USER-COLVARS USER-DIFFRACTION USER-DPD USER-DRUDE USER-EFF - USER-FEP USER-H5MD USER-LB) + USER-FEP USER-H5MD USER-LB USER-MANIFOLD USER-MEAMC USER-MGPT USER-MISC + USER-MOLFILE USER-NETCDF USER-PHONON USER-QTB USER-REAXC USER-SMD + USER-SMTBQ USER-SPH USER-TALLY) foreach(PKG ${PACKAGES}) option(ENABLE_${PKG} "Build ${PKG} Package" ${ENABLE_ALL}) endforeach() @@ -66,6 +68,8 @@ pkg_depends(QEQ MANYBODY) pkg_depends(USER-ATC MANYBODY) pkg_depends(USER-H5MD MPI) pkg_depends(USER-LB MPI) +pkg_depends(USER-MISC MANYBODY) +pkg_depends(USER-PHONON KSPACE) if(ENABLE_KSPACE) find_package(FFTW3) @@ -131,6 +135,22 @@ if(ENABLE_VORONOI) #TODO download and build voro++ endif() +if(ENABLE_USER-MOLFILE) + list(APPEND LAMMPS_LINK_LIBS ${CMAKE_DL_LIBS}) +endif() + +if(ENABLE_USER-NETCDF) + find_package(NetCDF REQUIRED) + include_directories(NETCDF_INCLUDE_DIR) + list(APPEND LAMMPS_LINK_LIBS ${NETCDF_LIBRARY}) + add_definitions(-DLMP_HAS_NETCDF -DNC_64BIT_DATA=0x0020) +endif() + +if(ENABLE_USER-SMD) + find_package(Eigen3 REQUIRED) + include_directories(${EIGEN3_INCLUDE_DIR}) +endif() + ######################################################################## # Basic system tests (standard libraries, headers, functions, types) # ######################################################################## @@ -206,7 +226,8 @@ if(ENABLE_USER_OMP OR ENABLE_KOKKOS) set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") endif() -foreach(SIMPLE_LIB REAX MEAM POEMS USER-ATC USER-AWPMD USER-COLVARS USER-H5MD) +foreach(SIMPLE_LIB REAX MEAM POEMS USER-ATC USER-AWPMD USER-COLVARS USER-H5MD + USER-MOLFILE) if(ENABLE_${SIMPLE_LIB}) string(REGEX REPLACE "^USER-" "" SIMPLE_LIB "${SIMPLE_LIB}") string(TOLOWER "${SIMPLE_LIB}" INC_DIR) From 9991f679ae03310064281f3c7bf37cf260845451 Mon Sep 17 00:00:00 2001 From: Richard Berger Date: Sun, 16 Jul 2017 20:41:42 -0400 Subject: [PATCH 288/439] added USER-VTK --- cmake/CMakeLists.txt | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index ed0eeaacdd..947e29cbd0 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -47,7 +47,7 @@ set(PACKAGES ASPHERE BODY CLASS2 COLLOID COMPRESS CORESHELL DIPOLE GRANULAR USER-CGSDK USER-COLVARS USER-DIFFRACTION USER-DPD USER-DRUDE USER-EFF USER-FEP USER-H5MD USER-LB USER-MANIFOLD USER-MEAMC USER-MGPT USER-MISC USER-MOLFILE USER-NETCDF USER-PHONON USER-QTB USER-REAXC USER-SMD - USER-SMTBQ USER-SPH USER-TALLY) + USER-SMTBQ USER-SPH USER-TALLY USER-VTK) foreach(PKG ${PACKAGES}) option(ENABLE_${PKG} "Build ${PKG} Package" ${ENABLE_ALL}) endforeach() @@ -249,6 +249,13 @@ if(ENABLE_USER-H5MD) include_directories(${HDF5_INCLUDE_DIRS} ${LAMMPS_LIB_SOURCE_DIR}/h5md/include) endif() +if(ENABLE_USER-VTK) + find_package(VTK REQUIRED NO_MODULE) + include(${VTK_USE_FILE}) + add_definitions(-DLAMMPS_VTK) + list(APPEND LAMMPS_LINK_LIBS ${VTK_LIBRARIES}) +endif() + if(ENABLE_MSCG) find_package(GSL REQUIRED) set(LAMMPS_LIB_MSCG_BIN_DIR ${LAMMPS_LIB_BINARY_DIR}/mscg) From 2978cce8db453c4d6e9a251fb42989ff85c3afef Mon Sep 17 00:00:00 2001 From: Richard Berger Date: Sun, 16 Jul 2017 20:52:38 -0400 Subject: [PATCH 289/439] Added OPT --- cmake/CMakeLists.txt | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 947e29cbd0..68097d3655 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -52,7 +52,7 @@ foreach(PKG ${PACKAGES}) option(ENABLE_${PKG} "Build ${PKG} Package" ${ENABLE_ALL}) endforeach() -set(ACCEL_PACKAGES USER_OMP KOKKOS) +set(ACCEL_PACKAGES USER_OMP KOKKOS OPT) foreach(PKG ${ACCEL_PACKAGES}) option(ENABLE_${PKG} "Build ${PKG} Package" OFF) endforeach() @@ -328,6 +328,20 @@ if(ENABLE_KOKKOS) include_directories(${KOKKOS_PKG_SOURCES_DIR}) endif() +if(ENABLE_OPT) + set(OPT_SOURCES_DIR ${LAMMPS_SOURCE_DIR}/OPT) + set(OPT_SOURCES) + set_property(GLOBAL PROPERTY "OPT_SOURCES" "${OPT_SOURCES}") + + # detects styles which have OPT version + RegisterStylesExt(${OPT_SOURCES_DIR} opt OPT_SOURCES) + + get_property(OPT_SOURCES GLOBAL PROPERTY OPT_SOURCES) + + list(APPEND LIB_SOURCES ${OPT_SOURCES}) + include_directories(${OPT_SOURCES_DIR}) +endif() + ###################################################### # Generate style headers based on global list of From b6385d6ce21ca19048b9451cff65e7cbaaa1f441 Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Sun, 16 Jul 2017 20:17:41 -0600 Subject: [PATCH 290/439] add OpenKIM support --- cmake/CMakeLists.txt | 8 ++- cmake/Modules/FindKIM.cmake | 22 ++++++ cmake/Modules/FindNetCDF.cmake | 118 +++++++++++++++++++++++++++++++++ 3 files changed, 147 insertions(+), 1 deletion(-) create mode 100644 cmake/Modules/FindKIM.cmake create mode 100644 cmake/Modules/FindNetCDF.cmake diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 68097d3655..1b6b426ded 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -42,7 +42,7 @@ option(CMAKE_VERBOSE_MAKEFILE "Verbose makefile" OFF) option(ENABLE_ALL "Build all packages" OFF) set(PACKAGES ASPHERE BODY CLASS2 COLLOID COMPRESS CORESHELL DIPOLE GRANULAR - KSPACE MANYBODY MC MEAM MISC MOLECULE MSCG MPIIO PERI POEMS PYTHON QEQ + KIM KSPACE MANYBODY MC MEAM MISC MOLECULE MSCG MPIIO PERI POEMS PYTHON QEQ REAX REPLICA RIGID SHOCK SNAP SRD VORONOI USER-ATC USER-AWPMD USER-CGDNA USER-CGSDK USER-COLVARS USER-DIFFRACTION USER-DPD USER-DRUDE USER-EFF USER-FEP USER-H5MD USER-LB USER-MANIFOLD USER-MEAMC USER-MGPT USER-MISC @@ -256,6 +256,12 @@ if(ENABLE_USER-VTK) list(APPEND LAMMPS_LINK_LIBS ${VTK_LIBRARIES}) endif() +if(ENABLE_KIM) + find_package(KIM REQUIRED) + list(APPEND LAMMPS_LINK_LIBS ${KIM_LIBRARIES}) + include_directories(${KIM_INCLUDE_DIRS}) +endif() + if(ENABLE_MSCG) find_package(GSL REQUIRED) set(LAMMPS_LIB_MSCG_BIN_DIR ${LAMMPS_LIB_BINARY_DIR}/mscg) diff --git a/cmake/Modules/FindKIM.cmake b/cmake/Modules/FindKIM.cmake new file mode 100644 index 0000000000..a01f817cf6 --- /dev/null +++ b/cmake/Modules/FindKIM.cmake @@ -0,0 +1,22 @@ +# - Find kim +# Find the native KIM headers and libraries. +# +# KIM_INCLUDE_DIRS - where to find kim.h, etc. +# KIM_LIBRARIES - List of libraries when using kim. +# KIM_FOUND - True if kim found. +# + +find_path(KIM_INCLUDE_DIR KIM_API.h PATH_SUFFIXES kim-api-v1) + +find_library(KIM_LIBRARY NAMES kim-api-v1) + +set(KIM_LIBRARIES ${KIM_LIBRARY}) +set(KIM_INCLUDE_DIRS ${KIM_INCLUDE_DIR}) + +include(FindPackageHandleStandardArgs) +# handle the QUIETLY and REQUIRED arguments and set KIM_FOUND to TRUE +# if all listed variables are TRUE + +find_package_handle_standard_args(KIM DEFAULT_MSG KIM_LIBRARY KIM_INCLUDE_DIR) + +mark_as_advanced(KIM_INCLUDE_DIR KIM_LIBRARY ) diff --git a/cmake/Modules/FindNetCDF.cmake b/cmake/Modules/FindNetCDF.cmake new file mode 100644 index 0000000000..a28c959acf --- /dev/null +++ b/cmake/Modules/FindNetCDF.cmake @@ -0,0 +1,118 @@ +# - Find NetCDF +# Find the native NetCDF includes and library +# +# NETCDF_INCLUDE_DIR - user modifiable choice of where netcdf headers are +# NETCDF_LIBRARY - user modifiable choice of where netcdf libraries are +# +# Your package can require certain interfaces to be FOUND by setting these +# +# NETCDF_CXX - require the C++ interface and link the C++ library +# NETCDF_F77 - require the F77 interface and link the fortran library +# NETCDF_F90 - require the F90 interface and link the fortran library +# +# Or equivalently by calling FindNetCDF with a COMPONENTS argument containing one or +# more of "CXX;F77;F90". +# +# When interfaces are requested the user has access to interface specific hints: +# +# NETCDF_${LANG}_INCLUDE_DIR - where to search for interface header files +# NETCDF_${LANG}_LIBRARY - where to search for interface libraries +# +# This module returns these variables for the rest of the project to use. +# +# NETCDF_FOUND - True if NetCDF found including required interfaces (see below) +# NETCDF_LIBRARIES - All netcdf related libraries. +# NETCDF_INCLUDE_DIRS - All directories to include. +# NETCDF_HAS_INTERFACES - Whether requested interfaces were found or not. +# NETCDF_${LANG}_INCLUDE_DIRS/NETCDF_${LANG}_LIBRARIES - C/C++/F70/F90 only interface +# +# Normal usage would be: +# set (NETCDF_F90 "YES") +# find_package (NetCDF REQUIRED) +# target_link_libraries (uses_everthing ${NETCDF_LIBRARIES}) +# target_link_libraries (only_uses_f90 ${NETCDF_F90_LIBRARIES}) + +#search starting from user editable cache var +if (NETCDF_INCLUDE_DIR AND NETCDF_LIBRARY) + # Already in cache, be silent + set (NETCDF_FIND_QUIETLY TRUE) +endif () + +set(USE_DEFAULT_PATHS "NO_DEFAULT_PATH") +if(NETCDF_USE_DEFAULT_PATHS) + set(USE_DEFAULT_PATHS "") +endif() + +find_path (NETCDF_INCLUDE_DIR netcdf.h + HINTS "${NETCDF_DIR}/include") +mark_as_advanced (NETCDF_INCLUDE_DIR) +set (NETCDF_C_INCLUDE_DIRS ${NETCDF_INCLUDE_DIR}) + +find_library (NETCDF_LIBRARY NAMES netcdf + HINTS "${NETCDF_DIR}/lib") +mark_as_advanced (NETCDF_LIBRARY) + +set (NETCDF_C_LIBRARIES ${NETCDF_LIBRARY}) + +#start finding requested language components +set (NetCDF_libs "") +set (NetCDF_includes "${NETCDF_INCLUDE_DIR}") + +get_filename_component (NetCDF_lib_dirs "${NETCDF_LIBRARY}" PATH) +set (NETCDF_HAS_INTERFACES "YES") # will be set to NO if we're missing any interfaces + +macro (NetCDF_check_interface lang header libs) + if (NETCDF_${lang}) + #search starting from user modifiable cache var + find_path (NETCDF_${lang}_INCLUDE_DIR NAMES ${header} + HINTS "${NETCDF_INCLUDE_DIR}" + HINTS "${NETCDF_${lang}_ROOT}/include" + ${USE_DEFAULT_PATHS}) + + find_library (NETCDF_${lang}_LIBRARY NAMES ${libs} + HINTS "${NetCDF_lib_dirs}" + HINTS "${NETCDF_${lang}_ROOT}/lib" + ${USE_DEFAULT_PATHS}) + + mark_as_advanced (NETCDF_${lang}_INCLUDE_DIR NETCDF_${lang}_LIBRARY) + + #export to internal varS that rest of project can use directly + set (NETCDF_${lang}_LIBRARIES ${NETCDF_${lang}_LIBRARY}) + set (NETCDF_${lang}_INCLUDE_DIRS ${NETCDF_${lang}_INCLUDE_DIR}) + + if (NETCDF_${lang}_INCLUDE_DIR AND NETCDF_${lang}_LIBRARY) + list (APPEND NetCDF_libs ${NETCDF_${lang}_LIBRARY}) + list (APPEND NetCDF_includes ${NETCDF_${lang}_INCLUDE_DIR}) + else () + set (NETCDF_HAS_INTERFACES "NO") + message (STATUS "Failed to find NetCDF interface for ${lang}") + endif () + endif () +endmacro () + +list (FIND NetCDF_FIND_COMPONENTS "CXX" _nextcomp) +if (_nextcomp GREATER -1) + set (NETCDF_CXX 1) +endif () +list (FIND NetCDF_FIND_COMPONENTS "F77" _nextcomp) +if (_nextcomp GREATER -1) + set (NETCDF_F77 1) +endif () +list (FIND NetCDF_FIND_COMPONENTS "F90" _nextcomp) +if (_nextcomp GREATER -1) + set (NETCDF_F90 1) +endif () +NetCDF_check_interface (CXX netcdfcpp.h netcdf_c++) +NetCDF_check_interface (F77 netcdf.inc netcdff) +NetCDF_check_interface (F90 netcdf.mod netcdff) + +#export accumulated results to internal varS that rest of project can depend on +list (APPEND NetCDF_libs "${NETCDF_C_LIBRARIES}") +set (NETCDF_LIBRARIES ${NetCDF_libs}) +set (NETCDF_INCLUDE_DIRS ${NetCDF_includes}) + +# handle the QUIETLY and REQUIRED arguments and set NETCDF_FOUND to TRUE if +# all listed variables are TRUE +include (FindPackageHandleStandardArgs) +find_package_handle_standard_args (NetCDF + DEFAULT_MSG NETCDF_LIBRARIES NETCDF_INCLUDE_DIRS NETCDF_HAS_INTERFACES) From d6f05ea309c8362f8c603022ccf60904551a119b Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Sun, 16 Jul 2017 20:19:20 -0600 Subject: [PATCH 291/439] USER_OMP -> USER-OMP --- cmake/CMakeLists.txt | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 1b6b426ded..f732576513 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -52,7 +52,7 @@ foreach(PKG ${PACKAGES}) option(ENABLE_${PKG} "Build ${PKG} Package" ${ENABLE_ALL}) endforeach() -set(ACCEL_PACKAGES USER_OMP KOKKOS OPT) +set(ACCEL_PACKAGES USER-OMP KOKKOS OPT) foreach(PKG ${ACCEL_PACKAGES}) option(ENABLE_${PKG} "Build ${PKG} Package" OFF) endforeach() @@ -220,7 +220,7 @@ if(ENABLE_KOKKOS OR ENABLE_MSCG) set(CMAKE_CXX_EXTENSIONS OFF) #...without compiler extensions like gnu++11 endif() -if(ENABLE_USER_OMP OR ENABLE_KOKKOS) +if(ENABLE_USER-OMP OR ENABLE_KOKKOS) find_package(OpenMP REQUIRED) set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") @@ -293,21 +293,21 @@ endif() # e.g. accelerator packages ###################################################################### -if(ENABLE_USER_OMP) - set(USER_OMP_SOURCES_DIR ${LAMMPS_SOURCE_DIR}/USER-OMP) - set(USER_OMP_SOURCES ${USER_OMP_SOURCES_DIR}/thr_data.cpp - ${USER_OMP_SOURCES_DIR}/thr_omp.cpp - ${USER_OMP_SOURCES_DIR}/fix_nh_omp.cpp - ${USER_OMP_SOURCES_DIR}/fix_nh_sphere_omp.cpp) - set_property(GLOBAL PROPERTY "OMP_SOURCES" "${USER_OMP_SOURCES}") +if(ENABLE_USER-OMP) + set(USER-OMP_SOURCES_DIR ${LAMMPS_SOURCE_DIR}/USER-OMP) + set(USER-OMP_SOURCES ${USER-OMP_SOURCES_DIR}/thr_data.cpp + ${USER-OMP_SOURCES_DIR}/thr_omp.cpp + ${USER-OMP_SOURCES_DIR}/fix_nh_omp.cpp + ${USER-OMP_SOURCES_DIR}/fix_nh_sphere_omp.cpp) + set_property(GLOBAL PROPERTY "OMP_SOURCES" "${USER-OMP_SOURCES}") # detects styles which have USER-OMP version - RegisterStylesExt(${USER_OMP_SOURCES_DIR} omp OMP_SOURCES) + RegisterStylesExt(${USER-OMP_SOURCES_DIR} omp OMP_SOURCES) - get_property(USER_OMP_SOURCES GLOBAL PROPERTY OMP_SOURCES) + get_property(USER-OMP_SOURCES GLOBAL PROPERTY OMP_SOURCES) - list(APPEND LIB_SOURCES ${USER_OMP_SOURCES}) - include_directories(${USER_OMP_SOURCES_DIR}) + list(APPEND LIB_SOURCES ${USER-OMP_SOURCES}) + include_directories(${USER-OMP_SOURCES_DIR}) endif() if(ENABLE_KOKKOS) From fa0f8a9e2ad23f2d7bb780478690e20f04cc66c8 Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Sun, 16 Jul 2017 21:31:57 -0600 Subject: [PATCH 292/439] added USER-QUIP --- cmake/CMakeLists.txt | 44 ++++++++++++++++++++---------------- cmake/Modules/FindQUIP.cmake | 18 +++++++++++++++ 2 files changed, 42 insertions(+), 20 deletions(-) create mode 100644 cmake/Modules/FindQUIP.cmake diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index f732576513..b9d57a3736 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -47,7 +47,7 @@ set(PACKAGES ASPHERE BODY CLASS2 COLLOID COMPRESS CORESHELL DIPOLE GRANULAR USER-CGSDK USER-COLVARS USER-DIFFRACTION USER-DPD USER-DRUDE USER-EFF USER-FEP USER-H5MD USER-LB USER-MANIFOLD USER-MEAMC USER-MGPT USER-MISC USER-MOLFILE USER-NETCDF USER-PHONON USER-QTB USER-REAXC USER-SMD - USER-SMTBQ USER-SPH USER-TALLY USER-VTK) + USER-SMTBQ USER-SPH USER-TALLY USER-VTK USER-QUIP) foreach(PKG ${PACKAGES}) option(ENABLE_${PKG} "Build ${PKG} Package" ${ENABLE_ALL}) endforeach() @@ -71,6 +71,23 @@ pkg_depends(USER-LB MPI) pkg_depends(USER-MISC MANYBODY) pkg_depends(USER-PHONON KSPACE) +if(ENABLE_REAX OR ENABLE_MEAM OR ENABLE_USER-QUIP) + enable_language(Fortran) +endif() + +if(ENABLE_KOKKOS OR ENABLE_MSCG) + # starting with CMake 3.1 this is all you have to do to enforce C++11 + set(CMAKE_CXX_STANDARD 11) # C++11... + set(CMAKE_CXX_STANDARD_REQUIRED ON) #...is required... + set(CMAKE_CXX_EXTENSIONS OFF) #...without compiler extensions like gnu++11 +endif() + +if(ENABLE_USER-OMP OR ENABLE_KOKKOS) + find_package(OpenMP REQUIRED) + set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") +endif() + if(ENABLE_KSPACE) find_package(FFTW3) if(FFTW3_FOUND) @@ -95,7 +112,7 @@ if(ENABLE_KOKKOS) list(APPEND LAMMPS_LINK_LIBS kokkos) endif() -if(ENABLE_MSCG OR ENABLE_USER-ATC OR ENABLE_USER-AWPMD) +if(ENABLE_MSCG OR ENABLE_USER-ATC OR ENABLE_USER-AWPMD OR ENABLE_USER-QUIP) find_package(LAPACK REQUIRED) list(APPEND LAMMPS_LINK_LIBS ${LAPACK_LIBRARIES}) #TODO use lib/lapack @@ -151,6 +168,11 @@ if(ENABLE_USER-SMD) include_directories(${EIGEN3_INCLUDE_DIR}) endif() +if(ENABLE_USER-QUIP) + find_package(QUIP REQUIRED) + list(APPEND LAMMPS_LINK_LIBS ${QUIP_LIBRARIES} ${CMAKE_Fortran_IMPLICIT_LINK_LIBRARIES}) +endif() + ######################################################################## # Basic system tests (standard libraries, headers, functions, types) # ######################################################################## @@ -208,24 +230,6 @@ foreach(PKG ${PACKAGES}) endif() endforeach() -if(ENABLE_REAX OR ENABLE_MEAM) - enable_language(Fortran) -endif() - - -if(ENABLE_KOKKOS OR ENABLE_MSCG) - # starting with CMake 3.1 this is all you have to do to enforce C++11 - set(CMAKE_CXX_STANDARD 11) # C++11... - set(CMAKE_CXX_STANDARD_REQUIRED ON) #...is required... - set(CMAKE_CXX_EXTENSIONS OFF) #...without compiler extensions like gnu++11 -endif() - -if(ENABLE_USER-OMP OR ENABLE_KOKKOS) - find_package(OpenMP REQUIRED) - set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") - set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") -endif() - foreach(SIMPLE_LIB REAX MEAM POEMS USER-ATC USER-AWPMD USER-COLVARS USER-H5MD USER-MOLFILE) if(ENABLE_${SIMPLE_LIB}) diff --git a/cmake/Modules/FindQUIP.cmake b/cmake/Modules/FindQUIP.cmake new file mode 100644 index 0000000000..4ee1baf4f8 --- /dev/null +++ b/cmake/Modules/FindQUIP.cmake @@ -0,0 +1,18 @@ +# - Find quip +# Find the native QUIP libraries. +# +# QUIP_LIBRARIES - List of libraries when using fftw3. +# QUIP_FOUND - True if fftw3 found. +# + +find_library(QUIP_LIBRARY NAMES quip) + +set(QUIP_LIBRARIES ${QUIP_LIBRARY}) + +include(FindPackageHandleStandardArgs) +# handle the QUIETLY and REQUIRED arguments and set QUIP_FOUND to TRUE +# if all listed variables are TRUE + +find_package_handle_standard_args(QUIP DEFAULT_MSG QUIP_LIBRARY) + +mark_as_advanced(QUIP_LIBRARY) From 7dd5068740ac38a385252163356fe229d8ba8f22 Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Sun, 16 Jul 2017 21:43:29 -0600 Subject: [PATCH 293/439] allow internal lapack --- cmake/CMakeLists.txt | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index b9d57a3736..7693b0f744 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -6,6 +6,10 @@ set(LAMMPS_SOURCE_DIR ${CMAKE_SOURCE_DIR}/../src) set(LAMMPS_LIB_SOURCE_DIR ${CMAKE_SOURCE_DIR}/../lib) set(LAMMPS_LIB_BINARY_DIR ${CMAKE_BINARY_DIR}/lib) +file(GLOB LIB_SOURCES ${LAMMPS_SOURCE_DIR}/*.cpp) +file(GLOB LMP_SOURCES ${LAMMPS_SOURCE_DIR}/main.cpp) +list(REMOVE_ITEM LIB_SOURCES ${LMP_SOURCES}) + # Cmake modules/macros are in a subdirectory to keep this file cleaner set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/Modules) @@ -113,9 +117,14 @@ if(ENABLE_KOKKOS) endif() if(ENABLE_MSCG OR ENABLE_USER-ATC OR ENABLE_USER-AWPMD OR ENABLE_USER-QUIP) - find_package(LAPACK REQUIRED) - list(APPEND LAMMPS_LINK_LIBS ${LAPACK_LIBRARIES}) - #TODO use lib/lapack + find_package(LAPACK) + if(LAPACK_FOUND) + list(APPEND LAMMPS_LINK_LIBS ${LAPACK_LIBRARIES}) + else() + enable_language(Fortran) + file(GLOB LAPACK_SOURCES ${LAMMPS_LIB_SOURCE_DIR}/linalg/*.f) + list(APPEND LIB_SOURCES ${LAPACK_SOURCES}) + endif() endif() if(ENABLE_PYTHON) @@ -202,10 +211,6 @@ list(APPEND LAMMPS_LINK_LIBS ${MATH_LIBRARIES}) #Do NOT go into src to not conflict with old Makefile build system #add_subdirectory(src) -file(GLOB LIB_SOURCES ${LAMMPS_SOURCE_DIR}/*.cpp) -file(GLOB LMP_SOURCES ${LAMMPS_SOURCE_DIR}/main.cpp) -list(REMOVE_ITEM LIB_SOURCES ${LMP_SOURCES}) - if(NOT ENABLE_MPI) file(GLOB MPI_SOURCES ${LAMMPS_SOURCE_DIR}/STUBS/mpi.c) list(APPEND LIB_SOURCES ${MPI_SOURCES}) From 22ecd9b8d225819de8fe134cf44cdcc8ff1d1a71 Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Sun, 16 Jul 2017 22:07:21 -0600 Subject: [PATCH 294/439] started on USER-QMMM --- cmake/CMakeLists.txt | 10 ++++++++-- cmake/Modules/FindQE.cmake | 22 ++++++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 cmake/Modules/FindQE.cmake diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 7693b0f744..c40cee9252 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -51,7 +51,7 @@ set(PACKAGES ASPHERE BODY CLASS2 COLLOID COMPRESS CORESHELL DIPOLE GRANULAR USER-CGSDK USER-COLVARS USER-DIFFRACTION USER-DPD USER-DRUDE USER-EFF USER-FEP USER-H5MD USER-LB USER-MANIFOLD USER-MEAMC USER-MGPT USER-MISC USER-MOLFILE USER-NETCDF USER-PHONON USER-QTB USER-REAXC USER-SMD - USER-SMTBQ USER-SPH USER-TALLY USER-VTK USER-QUIP) + USER-SMTBQ USER-SPH USER-TALLY USER-VTK USER-QUIP USER-QMMM) foreach(PKG ${PACKAGES}) option(ENABLE_${PKG} "Build ${PKG} Package" ${ENABLE_ALL}) endforeach() @@ -182,6 +182,12 @@ if(ENABLE_USER-QUIP) list(APPEND LAMMPS_LINK_LIBS ${QUIP_LIBRARIES} ${CMAKE_Fortran_IMPLICIT_LINK_LIBRARIES}) endif() +if(ENABLE_USER-QMMM) + find_package(QE REQUIRED) + include_directories(${QE_INCLUDE_DIRS}) + list(APPEND LAMMPS_LINK_LIBS ${QE_LIBRARIES}) +endif() + ######################################################################## # Basic system tests (standard libraries, headers, functions, types) # ######################################################################## @@ -236,7 +242,7 @@ foreach(PKG ${PACKAGES}) endforeach() foreach(SIMPLE_LIB REAX MEAM POEMS USER-ATC USER-AWPMD USER-COLVARS USER-H5MD - USER-MOLFILE) + USER-MOLFILE USER-QMMM) if(ENABLE_${SIMPLE_LIB}) string(REGEX REPLACE "^USER-" "" SIMPLE_LIB "${SIMPLE_LIB}") string(TOLOWER "${SIMPLE_LIB}" INC_DIR) diff --git a/cmake/Modules/FindQE.cmake b/cmake/Modules/FindQE.cmake new file mode 100644 index 0000000000..c46adc1689 --- /dev/null +++ b/cmake/Modules/FindQE.cmake @@ -0,0 +1,22 @@ +# - Find quantum-espresso +# Find the native QE headers and libraries. +# +# QE_INCLUDE_DIRS - where to find quantum-espresso.h, etc. +# QE_LIBRARIES - List of libraries when using quantum-espresso. +# QE_FOUND - True if quantum-espresso found. +# + +find_path(QE_INCLUDE_DIR libqecouple.h PATH_SUFFIXES COUPLE/include) + +find_library(QE_LIBRARY NAMES libqefft) + +set(QE_LIBRARIES ${QE_LIBRARY}) +set(QE_INCLUDE_DIRS ${QE_INCLUDE_DIR}) + +include(FindPackageHandleStandardArgs) +# handle the QUIETLY and REQUIRED arguments and set QE_FOUND to TRUE +# if all listed variables are TRUE + +find_package_handle_standard_args(QE DEFAULT_MSG QE_LIBRARY QE_INCLUDE_DIR) + +mark_as_advanced(QE_INCLUDE_DIR QE_LIBRARY ) From 7605f72c9a3e484515da9b1bd10d36251dee6a5c Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Sun, 16 Jul 2017 22:37:51 -0600 Subject: [PATCH 295/439] finish USER-QMMM --- cmake/CMakeLists.txt | 4 ++-- cmake/Modules/FindQE.cmake | 15 +++++++++++---- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index c40cee9252..7727efa8c9 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -75,7 +75,7 @@ pkg_depends(USER-LB MPI) pkg_depends(USER-MISC MANYBODY) pkg_depends(USER-PHONON KSPACE) -if(ENABLE_REAX OR ENABLE_MEAM OR ENABLE_USER-QUIP) +if(ENABLE_REAX OR ENABLE_MEAM OR ENABLE_USER-QUIP OR ENABLE_USER-QMMM) enable_language(Fortran) endif() @@ -185,7 +185,7 @@ endif() if(ENABLE_USER-QMMM) find_package(QE REQUIRED) include_directories(${QE_INCLUDE_DIRS}) - list(APPEND LAMMPS_LINK_LIBS ${QE_LIBRARIES}) + list(APPEND LAMMPS_LINK_LIBS ${QE_LIBRARIES} ${CMAKE_Fortran_IMPLICIT_LINK_LIBRARIES}) endif() ######################################################################## diff --git a/cmake/Modules/FindQE.cmake b/cmake/Modules/FindQE.cmake index c46adc1689..4484bd4db2 100644 --- a/cmake/Modules/FindQE.cmake +++ b/cmake/Modules/FindQE.cmake @@ -8,15 +8,22 @@ find_path(QE_INCLUDE_DIR libqecouple.h PATH_SUFFIXES COUPLE/include) -find_library(QE_LIBRARY NAMES libqefft) +find_library(QECOUPLE_LIBRARY NAMES qecouple) +find_library(PW_LIBRARY NAMES pw) +find_library(QEMOD_LIBRARY NAMES qemod) +find_library(QEFFT_LIBRARY NAMES qefft) +find_library(QELA_LIBRARY NAMES qela) +find_library(CLIB_LIBRARY NAMES clib) +find_library(IOTK_LIBRARY NAMES iotk) -set(QE_LIBRARIES ${QE_LIBRARY}) + +set(QE_LIBRARIES ${QECOUPLE_LIBRARY} ${PW_LIBRARY} ${QEMOD_LIBRARY} ${QEFFT_LIBRARY} ${QELA_LIBRARY} ${CLIB_LIBRARY} ${IOTK_LIBRARY}) set(QE_INCLUDE_DIRS ${QE_INCLUDE_DIR}) include(FindPackageHandleStandardArgs) # handle the QUIETLY and REQUIRED arguments and set QE_FOUND to TRUE # if all listed variables are TRUE -find_package_handle_standard_args(QE DEFAULT_MSG QE_LIBRARY QE_INCLUDE_DIR) +find_package_handle_standard_args(QE DEFAULT_MSG QECOUPLE_LIBRARY PW_LIBRARY QEMOD_LIBRARY QEFFT_LIBRARY QELA_LIBRARY CLIB_LIBRARY IOTK_LIBRARY QE_INCLUDE_DIR) -mark_as_advanced(QE_INCLUDE_DIR QE_LIBRARY ) +mark_as_advanced(QE_INCLUDE_DIR QECOUPLE_LIBRARY PW_LIBRARY QEMOD_LIBRARY QEFFT_LIBRARY QELA_LIBRARY CLIB_LIBRARY IOTK_LIBRARY) From fc1be074b2957b72911dffdf3ec7f176174904ac Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Sun, 16 Jul 2017 22:52:59 -0600 Subject: [PATCH 296/439] added USER-INTEL --- cmake/CMakeLists.txt | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 7727efa8c9..1d755913e6 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -56,7 +56,7 @@ foreach(PKG ${PACKAGES}) option(ENABLE_${PKG} "Build ${PKG} Package" ${ENABLE_ALL}) endforeach() -set(ACCEL_PACKAGES USER-OMP KOKKOS OPT) +set(ACCEL_PACKAGES USER-OMP KOKKOS OPT USER-INTEL) foreach(PKG ${ACCEL_PACKAGES}) option(ENABLE_${PKG} "Build ${PKG} Package" OFF) endforeach() @@ -86,7 +86,7 @@ if(ENABLE_KOKKOS OR ENABLE_MSCG) set(CMAKE_CXX_EXTENSIONS OFF) #...without compiler extensions like gnu++11 endif() -if(ENABLE_USER-OMP OR ENABLE_KOKKOS) +if(ENABLE_USER-OMP OR ENABLE_KOKKOS OR ENABLE_USER-INTEL) find_package(OpenMP REQUIRED) set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") @@ -363,6 +363,29 @@ if(ENABLE_OPT) include_directories(${OPT_SOURCES_DIR}) endif() +if(ENABLE_USER-INTEL) + set(USER-INTEL_SOURCES_DIR ${LAMMPS_SOURCE_DIR}/USER-INTEL) + set(USER-INTEL_SOURCES ${USER-INTEL_SOURCES_DIR}/intel_preprocess.h + ${USER-INTEL_SOURCES_DIR}/intel_buffers.h + ${USER-INTEL_SOURCES_DIR}/intel_buffers.cpp + ${USER-INTEL_SOURCES_DIR}/math_extra_intel.h + ${USER-INTEL_SOURCES_DIR}/nbin_intel.h + ${USER-INTEL_SOURCES_DIR}/nbin_intel.cpp + ${USER-INTEL_SOURCES_DIR}/npair_intel.h + ${USER-INTEL_SOURCES_DIR}/npair_intel.cpp + ${USER-INTEL_SOURCES_DIR}/intel_simd.h + ${USER-INTEL_SOURCES_DIR}/intel_intrinsics.h) + + set_property(GLOBAL PROPERTY "USER-INTEL_SOURCES" "${USER-INTEL_SOURCES}") + + # detects styles which have USER-INTEL version + RegisterStylesExt(${USER-INTEL_SOURCES_DIR} opt USER-INTEL_SOURCES) + + get_property(USER-INTEL_SOURCES GLOBAL PROPERTY USER-INTEL_SOURCES) + + list(APPEND LIB_SOURCES ${USER-INTEL_SOURCES}) + include_directories(${USER-INTEL_SOURCES_DIR}) +endif() ###################################################### # Generate style headers based on global list of From 385c6f7f2ba7ee72783f5bd4b205f99e2826853f Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Sun, 16 Jul 2017 22:53:53 -0600 Subject: [PATCH 297/439] cmake: clean up --- cmake/CMakeLists.txt | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 1d755913e6..8713c3c2db 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -40,6 +40,10 @@ if(ENABLE_MPI) find_package(MPI REQUIRED) include_directories(${MPI_C_INCLUDE_PATH}) list(APPEND LAMMPS_LINK_LIBS ${MPI_CXX_LIBRARIES}) +else() + file(GLOB MPI_SOURCES ${LAMMPS_SOURCE_DIR}/STUBS/mpi.c) + list(APPEND LIB_SOURCES ${MPI_SOURCES}) + include_directories(${LAMMPS_SOURCE_DIR}/STUBS) endif() option(CMAKE_VERBOSE_MAKEFILE "Verbose makefile" OFF) @@ -217,12 +221,6 @@ list(APPEND LAMMPS_LINK_LIBS ${MATH_LIBRARIES}) #Do NOT go into src to not conflict with old Makefile build system #add_subdirectory(src) -if(NOT ENABLE_MPI) - file(GLOB MPI_SOURCES ${LAMMPS_SOURCE_DIR}/STUBS/mpi.c) - list(APPEND LIB_SOURCES ${MPI_SOURCES}) - include_directories(${LAMMPS_SOURCE_DIR}/STUBS) -endif() - include(StyleHeaderUtils) RegisterStyles(${LAMMPS_SOURCE_DIR}) From 80e44486146c35dcfb63ad62e01f88755da2735a Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Sun, 16 Jul 2017 23:03:11 -0600 Subject: [PATCH 298/439] added GPU --- cmake/CMakeLists.txt | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 8713c3c2db..e96516c1cd 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -60,7 +60,7 @@ foreach(PKG ${PACKAGES}) option(ENABLE_${PKG} "Build ${PKG} Package" ${ENABLE_ALL}) endforeach() -set(ACCEL_PACKAGES USER-OMP KOKKOS OPT USER-INTEL) +set(ACCEL_PACKAGES USER-OMP KOKKOS OPT USER-INTEL GPU) foreach(PKG ${ACCEL_PACKAGES}) option(ENABLE_${PKG} "Build ${PKG} Package" OFF) endforeach() @@ -385,6 +385,29 @@ if(ENABLE_USER-INTEL) include_directories(${USER-INTEL_SOURCES_DIR}) endif() +if(ENABLE_GPU) + find_package(CUDA REQUIRED) + + set(GPU_SOURCES_DIR ${LAMMPS_SOURCE_DIR}/GPU) + set(GPU_SOURCES ${GPU_SOURCES_DIR}/gpu_extra.h) + + set_property(GLOBAL PROPERTY "GPU_SOURCES" "${GPU_SOURCES}") + + # detects styles which have GPU version + RegisterStylesExt(${GPU_SOURCES_DIR} opt GPU_SOURCES) + + get_property(GPU_SOURCES GLOBAL PROPERTY GPU_SOURCES) + + + file(GLOB_RECURSE GPU_LIB_SOURCES ${LAMMPS_LIB_SOURCE_DIR}/gpu/*.cpp + ${LAMMPS_LIB_SOURCE_DIR}/gpu/*.cu + cuda_add_library(lammps_gpu ${GPU_LIB_SOURCES}) + + list(APPEND LAMMPS_LINK_LIBS lammps_gpu) + list(APPEND LIB_SOURCES ${GPU_SOURCES}) + include_directories(${GPU_SOURCES_DIR} ${LAMMPS_LIB_SOURCE_DIR}/gpu) +endif() + ###################################################### # Generate style headers based on global list of # styles registered during package selection From 1c1a1db3666989a327f360d93ed47e111aab2239 Mon Sep 17 00:00:00 2001 From: Richard Berger Date: Mon, 17 Jul 2017 11:55:05 -0400 Subject: [PATCH 299/439] Fix typo --- cmake/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index e96516c1cd..d768e10662 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -400,7 +400,7 @@ if(ENABLE_GPU) file(GLOB_RECURSE GPU_LIB_SOURCES ${LAMMPS_LIB_SOURCE_DIR}/gpu/*.cpp - ${LAMMPS_LIB_SOURCE_DIR}/gpu/*.cu + ${LAMMPS_LIB_SOURCE_DIR}/gpu/*.cu) cuda_add_library(lammps_gpu ${GPU_LIB_SOURCES}) list(APPEND LAMMPS_LINK_LIBS lammps_gpu) From 5ee2c310389d249b511ab59e27a7332a31db3e0d Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Mon, 17 Jul 2017 11:01:08 -0600 Subject: [PATCH 300/439] split PACKAGES, get ENABLE-ALL right --- cmake/CMakeLists.txt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index d768e10662..55bed88501 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -51,17 +51,17 @@ option(CMAKE_VERBOSE_MAKEFILE "Verbose makefile" OFF) option(ENABLE_ALL "Build all packages" OFF) set(PACKAGES ASPHERE BODY CLASS2 COLLOID COMPRESS CORESHELL DIPOLE GRANULAR KIM KSPACE MANYBODY MC MEAM MISC MOLECULE MSCG MPIIO PERI POEMS PYTHON QEQ - REAX REPLICA RIGID SHOCK SNAP SRD VORONOI USER-ATC USER-AWPMD USER-CGDNA + REAX REPLICA RIGID SHOCK SNAP SRD VORONOI) +set(USER-PACKAGES USER-ATC USER-AWPMD USER-CGDNA USER-CGSDK USER-COLVARS USER-DIFFRACTION USER-DPD USER-DRUDE USER-EFF USER-FEP USER-H5MD USER-LB USER-MANIFOLD USER-MEAMC USER-MGPT USER-MISC USER-MOLFILE USER-NETCDF USER-PHONON USER-QTB USER-REAXC USER-SMD USER-SMTBQ USER-SPH USER-TALLY USER-VTK USER-QUIP USER-QMMM) +set(ACCEL_PACKAGES USER-OMP KOKKOS OPT USER-INTEL GPU) foreach(PKG ${PACKAGES}) option(ENABLE_${PKG} "Build ${PKG} Package" ${ENABLE_ALL}) endforeach() - -set(ACCEL_PACKAGES USER-OMP KOKKOS OPT USER-INTEL GPU) -foreach(PKG ${ACCEL_PACKAGES}) +foreach(PKG ${ACCEL_PACKAGES} ${USER-PACKAGES}) option(ENABLE_${PKG} "Build ${PKG} Package" OFF) endforeach() @@ -226,7 +226,7 @@ RegisterStyles(${LAMMPS_SOURCE_DIR}) # packages which include entire content when enabled -foreach(PKG ${PACKAGES}) +foreach(PKG ${PACKAGES} ${USER-PACKAGES}) if(ENABLE_${PKG}) set(${PKG}_SOURCES_DIR ${LAMMPS_SOURCE_DIR}/${PKG}) From 2411192ab41dc92a3d1bebb3a5f6d80805de8124 Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Mon, 17 Jul 2017 11:52:06 -0600 Subject: [PATCH 301/439] cmake: add cross-configure warning --- cmake/CMakeLists.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 55bed88501..1846d6babb 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -18,6 +18,14 @@ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_C_FLAGS) set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel." FORCE) endif(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_C_FLAGS) +foreach(STYLE_FILE style_angle.h style_atom.h style_body.h style_bond.h style_command.h style_compute.h style_dihedral.h style_dump.h + style_fix.h style_improper.h style_integrate.h style_kspace.h style_minimize.h style_nbin.h style_npair.h style_nstencil.h + style_ntopo.h style_pair.h style_reader.h style_region.h) + if(EXISTS ${LAMMPS_SOURCE_DIR}/${STYLE_FILE}) + message(FATAL_ERROR "There is a ${STYLE_FILE} in ${LAMMPS_SOURCE_DIR}, please clean up the source directory first") + endif() +endforeach() + enable_language(CXX) ###################################################################### From 08c920029fc78d0da2da73fc6ecf104e15d1fcf2 Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Mon, 17 Jul 2017 12:22:28 -0600 Subject: [PATCH 302/439] added lammps size option --- cmake/CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 1846d6babb..177a9b8296 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -54,6 +54,10 @@ else() include_directories(${LAMMPS_SOURCE_DIR}/STUBS) endif() +set(LAMMPS_SIZE_LIMIT "LAMMPS_SMALLBIG" CACHE STRING "Lammps size limit") +set_property(CACHE LAMMPS_SIZE_LIMIT PROPERTY STRINGS LAMMPS_SMALLBIG LAMMPS_BIGBIG LAMMPS_SMALLSMALL) +add_definitions(-D${LAMMPS_SIZE_LIMIT}) + option(CMAKE_VERBOSE_MAKEFILE "Verbose makefile" OFF) option(ENABLE_ALL "Build all packages" OFF) From a3885b78ada825208c757cb2a2c7c3a98dfc7496 Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Mon, 17 Jul 2017 13:21:42 -0600 Subject: [PATCH 303/439] added support -DLAMMPS_XDR and -DPACK_* --- cmake/CMakeLists.txt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 177a9b8296..8095f3e500 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -115,6 +115,16 @@ if(ENABLE_KSPACE) include_directories(${FFTW3_INCLUDE_DIRS}) list(APPEND LAMMPS_LINK_LIBS ${FFTW3_LIBRARIES}) endif() + set(PACK_OPTIMIZATION "PACK_ARRAY" CACHE STRING "Optimization for FFT") + set_property(CACHE LAMMPS_SIZE_LIMIT PROPERTY STRINGS PACK_ARRAY PACK_POINTER PACK_MEMCPY) + add_definitions(-D${PACK_OPTIMIZATION}) +endif() + +if(ENABLE_MISC) + option(LAMMPS_XDR "include XDR compatibility files for doing particle dumps in XTC format" OFF) + if(LAMMPS_XDR) + add_definitions(-DLAMMPS_XDR) + endif() endif() if(ENABLE_KOKKOS) From 99f5f82b0266f47c12ec6d5e61b4d5eb339502ba Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Mon, 17 Jul 2017 13:26:46 -0600 Subject: [PATCH 304/439] added support for LAMMPS_MEMALIGN and LAMMPS_LONGLONG_TO_LONG --- cmake/CMakeLists.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 8095f3e500..1d912970d2 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -48,6 +48,10 @@ if(ENABLE_MPI) find_package(MPI REQUIRED) include_directories(${MPI_C_INCLUDE_PATH}) list(APPEND LAMMPS_LINK_LIBS ${MPI_CXX_LIBRARIES}) + option(LAMMPS_LONGLONG_TO_LONG "Workaround if your system or MPI version does not recognize "long long" data types" OFF) + if(LAMMPS_LONGLONG_TO_LONG) + add_definitions(-DLAMMPS_LONGLONG_TO_LONG) + endif() else() file(GLOB MPI_SOURCES ${LAMMPS_SOURCE_DIR}/STUBS/mpi.c) list(APPEND LIB_SOURCES ${MPI_SOURCES}) @@ -58,6 +62,9 @@ set(LAMMPS_SIZE_LIMIT "LAMMPS_SMALLBIG" CACHE STRING "Lammps size limit") set_property(CACHE LAMMPS_SIZE_LIMIT PROPERTY STRINGS LAMMPS_SMALLBIG LAMMPS_BIGBIG LAMMPS_SMALLSMALL) add_definitions(-D${LAMMPS_SIZE_LIMIT}) +set(LAMMPS_MEMALIGN "64" CACHE STRING "enables the use of the posix_memalign() call instead of malloc() when large chunks or memory are allocated by LAMMPS") +add_definitions(-DLAMMPS_MEMALIGN=${LAMMPS_MEMALIGN}) + option(CMAKE_VERBOSE_MAKEFILE "Verbose makefile" OFF) option(ENABLE_ALL "Build all packages" OFF) From 050a82af5813b15536a509f20a62b8b1f0cde0de Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Mon, 17 Jul 2017 13:28:34 -0600 Subject: [PATCH 305/439] fix LAMMPS_LONGLONG_TO_LONG description --- cmake/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 1d912970d2..1aeaf33c43 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -48,7 +48,7 @@ if(ENABLE_MPI) find_package(MPI REQUIRED) include_directories(${MPI_C_INCLUDE_PATH}) list(APPEND LAMMPS_LINK_LIBS ${MPI_CXX_LIBRARIES}) - option(LAMMPS_LONGLONG_TO_LONG "Workaround if your system or MPI version does not recognize "long long" data types" OFF) + option(LAMMPS_LONGLONG_TO_LONG "Workaround if your system or MPI version does not recognize 'long long' data types" OFF) if(LAMMPS_LONGLONG_TO_LONG) add_definitions(-DLAMMPS_LONGLONG_TO_LONG) endif() From 8bc318461172d95625f0bda8db17bc59b124ff44 Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Mon, 17 Jul 2017 14:01:05 -0600 Subject: [PATCH 306/439] added support for LAMMPS_FFMPEG --- cmake/CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 1aeaf33c43..051ff4d290 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -187,6 +187,11 @@ if(GZIP) add_definitions(-DLAMMPS_GZIP) endif() +find_program(FFMPEG ffmpeg) +if(FFMPEG) + add_definitions(-DLAMMPS_FFMPEG) +endif() + if(ENABLE_VORONOI) find_package(VORO REQUIRED) #some distros include_directories(${VORO_INCLUDE_DIRS}) From 3c3baf34c4e55970ae1845cbbc650b0c562efdc8 Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Mon, 17 Jul 2017 15:04:07 -0600 Subject: [PATCH 307/439] GPU: added cuda includedir --- cmake/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 051ff4d290..17759cbb65 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -421,6 +421,7 @@ endif() if(ENABLE_GPU) find_package(CUDA REQUIRED) + include_directories(${CUDA_TOOLKIT_INCLUDE}) set(GPU_SOURCES_DIR ${LAMMPS_SOURCE_DIR}/GPU) set(GPU_SOURCES ${GPU_SOURCES_DIR}/gpu_extra.h) From 3c88b2a9805b0908351759d76eb6421226e0c1d0 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 18 Jul 2017 09:53:26 -0600 Subject: [PATCH 308/439] Fixing execution space issues in KOKKOS package --- src/KOKKOS/atom_vec_angle_kokkos.h | 2 + src/KOKKOS/atom_vec_atomic_kokkos.h | 2 + src/KOKKOS/atom_vec_bond_kokkos.h | 2 + src/KOKKOS/atom_vec_charge_kokkos.h | 2 + src/KOKKOS/atom_vec_full_kokkos.h | 2 + src/KOKKOS/atom_vec_molecular_kokkos.h | 2 + src/KOKKOS/fix_deform_kokkos.h | 2 + src/KOKKOS/fix_reaxc_bonds_kokkos.cpp | 2 +- src/KOKKOS/fix_reaxc_bonds_kokkos.h | 2 + src/KOKKOS/fix_reaxc_species_kokkos.cpp | 2 +- src/KOKKOS/fix_reaxc_species_kokkos.h | 2 + src/KOKKOS/out.txt | 321 ++++++++++++++++++++++++ src/KOKKOS/pair_eam_kokkos.cpp | 4 +- src/KOKKOS/pair_kokkos.h | 6 +- src/KOKKOS/pair_reaxc_kokkos.cpp | 40 +-- src/KOKKOS/pair_reaxc_kokkos.h | 19 +- src/KOKKOS/verlet_kokkos.h | 2 + 17 files changed, 379 insertions(+), 35 deletions(-) create mode 100644 src/KOKKOS/out.txt diff --git a/src/KOKKOS/atom_vec_angle_kokkos.h b/src/KOKKOS/atom_vec_angle_kokkos.h index 0a477b0386..abdd48fce5 100644 --- a/src/KOKKOS/atom_vec_angle_kokkos.h +++ b/src/KOKKOS/atom_vec_angle_kokkos.h @@ -14,6 +14,8 @@ #ifdef ATOM_CLASS AtomStyle(angle/kk,AtomVecAngleKokkos) +AtomStyle(angle/kk/device,AtomVecAngleKokkos) +AtomStyle(angle/kk/host,AtomVecAngleKokkos) #else diff --git a/src/KOKKOS/atom_vec_atomic_kokkos.h b/src/KOKKOS/atom_vec_atomic_kokkos.h index 0c3e24f9d9..5e9a72c2e3 100644 --- a/src/KOKKOS/atom_vec_atomic_kokkos.h +++ b/src/KOKKOS/atom_vec_atomic_kokkos.h @@ -14,6 +14,8 @@ #ifdef ATOM_CLASS AtomStyle(atomic/kk,AtomVecAtomicKokkos) +AtomStyle(atomic/kk/device,AtomVecAtomicKokkos) +AtomStyle(atomic/kk/host,AtomVecAtomicKokkos) #else diff --git a/src/KOKKOS/atom_vec_bond_kokkos.h b/src/KOKKOS/atom_vec_bond_kokkos.h index e64017c99b..3dcc99fa78 100644 --- a/src/KOKKOS/atom_vec_bond_kokkos.h +++ b/src/KOKKOS/atom_vec_bond_kokkos.h @@ -14,6 +14,8 @@ #ifdef ATOM_CLASS AtomStyle(bond/kk,AtomVecBondKokkos) +AtomStyle(bond/kk/device,AtomVecBondKokkos) +AtomStyle(bond/kk/host,AtomVecBondKokkos) #else diff --git a/src/KOKKOS/atom_vec_charge_kokkos.h b/src/KOKKOS/atom_vec_charge_kokkos.h index 38e32458c6..f9b385e7ed 100644 --- a/src/KOKKOS/atom_vec_charge_kokkos.h +++ b/src/KOKKOS/atom_vec_charge_kokkos.h @@ -14,6 +14,8 @@ #ifdef ATOM_CLASS AtomStyle(charge/kk,AtomVecChargeKokkos) +AtomStyle(charge/kk/device,AtomVecChargeKokkos) +AtomStyle(charge/kk/host,AtomVecChargeKokkos) #else diff --git a/src/KOKKOS/atom_vec_full_kokkos.h b/src/KOKKOS/atom_vec_full_kokkos.h index 841707b338..760df087e1 100644 --- a/src/KOKKOS/atom_vec_full_kokkos.h +++ b/src/KOKKOS/atom_vec_full_kokkos.h @@ -14,6 +14,8 @@ #ifdef ATOM_CLASS AtomStyle(full/kk,AtomVecFullKokkos) +AtomStyle(full/kk/device,AtomVecFullKokkos) +AtomStyle(full/kk/host,AtomVecFullKokkos) #else diff --git a/src/KOKKOS/atom_vec_molecular_kokkos.h b/src/KOKKOS/atom_vec_molecular_kokkos.h index 4ec26621cc..06444510e0 100644 --- a/src/KOKKOS/atom_vec_molecular_kokkos.h +++ b/src/KOKKOS/atom_vec_molecular_kokkos.h @@ -14,6 +14,8 @@ #ifdef ATOM_CLASS AtomStyle(molecular/kk,AtomVecMolecularKokkos) +AtomStyle(molecular/kk/device,AtomVecMolecularKokkos) +AtomStyle(molecular/kk/host,AtomVecMolecularKokkos) #else diff --git a/src/KOKKOS/fix_deform_kokkos.h b/src/KOKKOS/fix_deform_kokkos.h index 8fa12a2e37..69f65fbcf4 100644 --- a/src/KOKKOS/fix_deform_kokkos.h +++ b/src/KOKKOS/fix_deform_kokkos.h @@ -14,6 +14,8 @@ #ifdef FIX_CLASS FixStyle(deform/kk,FixDeformKokkos) +FixStyle(deform/kk/device,FixDeformKokkos) +FixStyle(deform/kk/host,FixDeformKokkos) #else diff --git a/src/KOKKOS/fix_reaxc_bonds_kokkos.cpp b/src/KOKKOS/fix_reaxc_bonds_kokkos.cpp index e4fb9385a5..0d74a49ed3 100644 --- a/src/KOKKOS/fix_reaxc_bonds_kokkos.cpp +++ b/src/KOKKOS/fix_reaxc_bonds_kokkos.cpp @@ -64,7 +64,7 @@ FixReaxCBondsKokkos::~FixReaxCBondsKokkos() void FixReaxCBondsKokkos::init() { - Pair *pair_kk = force->pair_match("reax/c/kk",1); + Pair *pair_kk = force->pair_match("reax/c/kk",0); if (pair_kk == NULL) error->all(FLERR,"Cannot use fix reax/c/bonds without " "pair_style reax/c/kk"); diff --git a/src/KOKKOS/fix_reaxc_bonds_kokkos.h b/src/KOKKOS/fix_reaxc_bonds_kokkos.h index e85a7988f3..55adb6f8d9 100644 --- a/src/KOKKOS/fix_reaxc_bonds_kokkos.h +++ b/src/KOKKOS/fix_reaxc_bonds_kokkos.h @@ -14,6 +14,8 @@ #ifdef FIX_CLASS FixStyle(reax/c/bonds/kk,FixReaxCBondsKokkos) +FixStyle(reax/c/bonds/kk/device,FixReaxCBondsKokkos) +FixStyle(reax/c/bonds/kk/host,FixReaxCBondsKokkos) #else diff --git a/src/KOKKOS/fix_reaxc_species_kokkos.cpp b/src/KOKKOS/fix_reaxc_species_kokkos.cpp index 8b778ecf65..f2719f9f0e 100644 --- a/src/KOKKOS/fix_reaxc_species_kokkos.cpp +++ b/src/KOKKOS/fix_reaxc_species_kokkos.cpp @@ -66,7 +66,7 @@ FixReaxCSpeciesKokkos::~FixReaxCSpeciesKokkos() void FixReaxCSpeciesKokkos::init() { - Pair* pair_kk = force->pair_match("reax/c/kk",1); + Pair* pair_kk = force->pair_match("reax/c/kk",0); if (pair_kk == NULL) error->all(FLERR,"Cannot use fix reax/c/species/kk without " "pair_style reax/c/kk"); diff --git a/src/KOKKOS/fix_reaxc_species_kokkos.h b/src/KOKKOS/fix_reaxc_species_kokkos.h index 64de060006..7c163b23b5 100644 --- a/src/KOKKOS/fix_reaxc_species_kokkos.h +++ b/src/KOKKOS/fix_reaxc_species_kokkos.h @@ -14,6 +14,8 @@ #ifdef FIX_CLASS FixStyle(reax/c/species/kk,FixReaxCSpeciesKokkos) +FixStyle(reax/c/species/kk/device,FixReaxCSpeciesKokkos) +FixStyle(reax/c/species/kk/host,FixReaxCSpeciesKokkos) #else diff --git a/src/KOKKOS/out.txt b/src/KOKKOS/out.txt new file mode 100644 index 0000000000..00908bf69a --- /dev/null +++ b/src/KOKKOS/out.txt @@ -0,0 +1,321 @@ +atom_vec_angle_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_angle_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_angle_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_angle_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_angle_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_angle_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_angle_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_angle_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_angle_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_angle_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_angle_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_angle_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_angle_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_angle_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_angle_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_angle_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_angle_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_angle_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_angle_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_angle_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_angle_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_angle_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_angle_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_angle_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_angle_kokkos.cpp: Kokkos::parallel_for(nsend,f); +atom_vec_angle_kokkos.cpp: Kokkos::parallel_for(nsend,f); +atom_vec_angle_kokkos.cpp: Kokkos::parallel_for(nrecv/elements,f); +atom_vec_angle_kokkos.cpp: Kokkos::parallel_for(nrecv/elements,f); +atom_vec_atomic_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_atomic_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_atomic_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_atomic_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_atomic_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_atomic_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_atomic_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_atomic_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_atomic_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_atomic_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_atomic_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_atomic_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_atomic_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_atomic_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_atomic_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_atomic_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_atomic_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_atomic_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_atomic_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_atomic_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_atomic_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_atomic_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_atomic_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_atomic_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_atomic_kokkos.cpp: Kokkos::parallel_for(nsend,f); +atom_vec_atomic_kokkos.cpp: Kokkos::parallel_for(nsend,f); +atom_vec_atomic_kokkos.cpp: Kokkos::parallel_for(nrecv/11,f); +atom_vec_atomic_kokkos.cpp: Kokkos::parallel_for(nrecv/11,f); +atom_vec_bond_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_bond_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_bond_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_bond_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_bond_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_bond_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_bond_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_bond_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_bond_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_bond_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_bond_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_bond_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_bond_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_bond_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_bond_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_bond_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_bond_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_bond_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_bond_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_bond_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_bond_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_bond_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_bond_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_bond_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_bond_kokkos.cpp: Kokkos::parallel_for(nsend,f); +atom_vec_bond_kokkos.cpp: Kokkos::parallel_for(nsend,f); +atom_vec_bond_kokkos.cpp: Kokkos::parallel_for(nrecv/elements,f); +atom_vec_bond_kokkos.cpp: Kokkos::parallel_for(nrecv/elements,f); +atom_vec_charge_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_charge_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_charge_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_charge_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_charge_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_charge_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_charge_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_charge_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_charge_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_charge_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_charge_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_charge_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_charge_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_charge_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_charge_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_charge_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_charge_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_charge_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_charge_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_charge_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_charge_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_charge_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_charge_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_charge_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_charge_kokkos.cpp: Kokkos::parallel_for(nsend,f); +atom_vec_charge_kokkos.cpp: Kokkos::parallel_for(nsend,f); +atom_vec_charge_kokkos.cpp: Kokkos::parallel_for(nrecv/12,f); +atom_vec_charge_kokkos.cpp: Kokkos::parallel_for(nrecv/12,f); +atom_vec_full_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_full_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_full_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_full_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_full_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_full_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_full_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_full_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_full_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_full_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_full_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_full_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_full_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_full_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_full_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_full_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_full_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_full_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_full_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_full_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_full_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_full_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_full_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_full_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_full_kokkos.cpp: Kokkos::parallel_for(nsend,f); +atom_vec_full_kokkos.cpp: Kokkos::parallel_for(nsend,f); +atom_vec_full_kokkos.cpp: Kokkos::parallel_for(nrecv/elements,f); +atom_vec_full_kokkos.cpp: Kokkos::parallel_for(nrecv/elements,f); +atom_vec_molecular_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_molecular_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_molecular_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_molecular_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_molecular_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_molecular_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_molecular_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_molecular_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_molecular_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_molecular_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_molecular_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_molecular_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_molecular_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_molecular_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_molecular_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_molecular_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_molecular_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_molecular_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_molecular_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_molecular_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_molecular_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_molecular_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_molecular_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_molecular_kokkos.cpp: Kokkos::parallel_for(n,f); +atom_vec_molecular_kokkos.cpp: Kokkos::parallel_for(nsend,f); +atom_vec_molecular_kokkos.cpp: Kokkos::parallel_for(nsend,f); +atom_vec_molecular_kokkos.cpp: Kokkos::parallel_for(nrecv/elements,f); +atom_vec_molecular_kokkos.cpp: Kokkos::parallel_for(nrecv/elements,f); +comm_kokkos.cpp: Kokkos::parallel_for(nlocal,f); +comm_kokkos.cpp: Kokkos::parallel_for(config,f); +comm_kokkos.cpp: Kokkos::parallel_for(config,f); +domain_kokkos.cpp: Kokkos::parallel_reduce(nlocal,f,result); +domain_kokkos.cpp: Kokkos::parallel_for(nlocal,f); +domain_kokkos.cpp: Kokkos::parallel_for(nlocal,f); +domain_kokkos.cpp: Kokkos::parallel_for(nlocal,f); +domain_kokkos.cpp: Kokkos::parallel_for(nlocal,f); +fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); +fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); +fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); +fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); +fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); +fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); +fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); +fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); +fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); +fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); +fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); +fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); +fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); +fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); +fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); +fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); +fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); +fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); +fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); +fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); +fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); +fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); +fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); +fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); +fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); +fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); +fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); +fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); +fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); +fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); +fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); +fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); +fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); +fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); +fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); +fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); +fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); +fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); +fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); +fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); +fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); +fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); +fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); +fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); +fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); +fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); +fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); +fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); +fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); +fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); +fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); +fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); +fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); +fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); +fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); +fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); +fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); +fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); +fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); +fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); +fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); +fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); +fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); +fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); +fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,zero_functor); +fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,scalar_functor,energy_onestep); +fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,tally_functor,energy_onestep); +fix_momentum_kokkos.cpp: Kokkos::parallel_reduce(nlocal, LAMMPS_LAMBDA(int i, double& update) { +fix_momentum_kokkos.cpp: Kokkos::parallel_reduce(nlocal, LAMMPS_LAMBDA(int i, double& update) { +fix_momentum_kokkos.cpp: Kokkos::parallel_for(nlocal, LAMMPS_LAMBDA(int i) { +fix_momentum_kokkos.cpp: Kokkos::parallel_for(nlocal, LAMMPS_LAMBDA(int i) { +fix_momentum_kokkos.cpp: Kokkos::parallel_for(nlocal, LAMMPS_LAMBDA(int i) { +fix_nve_kokkos.cpp: Kokkos::parallel_for(nlocal,functor); +fix_nve_kokkos.cpp: Kokkos::parallel_for(nlocal,functor); +fix_nve_kokkos.cpp: Kokkos::parallel_for(nlocal,functor); +fix_nve_kokkos.cpp: Kokkos::parallel_for(nlocal,functor); +fix_qeq_reax_kokkos.cpp: Kokkos::parallel_scan(inum,computeH_functor); +fix_qeq_reax_kokkos.cpp: Kokkos::parallel_for(inum,matvec_functor); +fix_qeq_reax_kokkos.cpp: Kokkos::parallel_reduce(inum,neigh_functor,m_cap); +fix_qeq_reax_kokkos.cpp: Kokkos::parallel_for(ignum,zero_functor); +fix_qeq_reax_kokkos.cpp: Kokkos::parallel_for(inum,sparse12_functor); +fix_qeq_reax_kokkos.cpp: Kokkos::parallel_for(inum,sparse13_functor); +fix_qeq_reax_kokkos.cpp: Kokkos::parallel_for(inum,sparse13_functor); +fix_qeq_reax_kokkos.cpp: Kokkos::parallel_reduce(inum,norm1_functor,my_norm); +fix_qeq_reax_kokkos.cpp: Kokkos::parallel_reduce(inum,dot1_functor,my_dot); +fix_qeq_reax_kokkos.cpp: Kokkos::parallel_for(inum,sparse22_functor); +fix_qeq_reax_kokkos.cpp: Kokkos::parallel_for(inum,sparse23_functor); +fix_qeq_reax_kokkos.cpp: Kokkos::parallel_for(inum,sparse23_functor); +fix_qeq_reax_kokkos.cpp: Kokkos::parallel_reduce(inum,dot2_functor,my_dot); +fix_qeq_reax_kokkos.cpp: Kokkos::parallel_for(inum,precon1_functor); +fix_qeq_reax_kokkos.cpp: Kokkos::parallel_reduce(inum,precon_functor,my_dot); +fix_qeq_reax_kokkos.cpp: Kokkos::parallel_for(inum,vecsum2_functor); +fix_qeq_reax_kokkos.cpp: Kokkos::parallel_for(inum,sparse32_functor); +fix_qeq_reax_kokkos.cpp: Kokkos::parallel_for(inum,sparse33_functor); +fix_qeq_reax_kokkos.cpp: Kokkos::parallel_for(inum,sparse33_functor); +fix_qeq_reax_kokkos.cpp: Kokkos::parallel_reduce(inum,norm2_functor,my_norm); +fix_qeq_reax_kokkos.cpp: Kokkos::parallel_reduce(inum,dot1_functor,my_dot); +fix_qeq_reax_kokkos.cpp: Kokkos::parallel_for(inum,sparse22_functor); +fix_qeq_reax_kokkos.cpp: Kokkos::parallel_for(inum,sparse23_functor); +fix_qeq_reax_kokkos.cpp: Kokkos::parallel_for(inum,sparse23_functor); +fix_qeq_reax_kokkos.cpp: Kokkos::parallel_reduce(inum,dot2_functor,my_dot); +fix_qeq_reax_kokkos.cpp: Kokkos::parallel_for(inum,precon2_functor); +fix_qeq_reax_kokkos.cpp: Kokkos::parallel_reduce(inum,precon_functor,my_dot); +fix_qeq_reax_kokkos.cpp: Kokkos::parallel_for(inum,vecsum2_functor); +fix_qeq_reax_kokkos.cpp: Kokkos::parallel_reduce(inum,vecacc1_functor,sum); +fix_qeq_reax_kokkos.cpp: Kokkos::parallel_reduce(inum,vecacc2_functor,sum); +fix_qeq_reax_kokkos.cpp: Kokkos::parallel_for(inum,calculateQ_functor); +fix_qeq_reax_kokkos.cpp: Kokkos::parallel_reduce(Kokkos::TeamThreadRange(team, d_firstnbr[i], d_firstnbr[i] + d_numnbrs[i]), [&] (const int &jj, F_FLOAT &doi) { +fix_qeq_reax_kokkos.cpp: Kokkos::parallel_reduce(Kokkos::TeamThreadRange(team, d_firstnbr[i], d_firstnbr[i] + d_numnbrs[i]), [&] (const int &jj, F_FLOAT &doi) { +fix_qeq_reax_kokkos.cpp: Kokkos::parallel_reduce(Kokkos::TeamThreadRange(team, d_firstnbr[i], d_firstnbr[i] + d_numnbrs[i]), [&] (const int &jj, F_FLOAT &doi) { +kokkos_type.h: Kokkos::parallel_for(view.span()*sizeof(typename ViewType::value_type)/4, f); +kokkos_type.h: Kokkos::parallel_for(view.capacity()*sizeof(typename ViewType::value_type)/4, f); +nbin_kokkos.cpp: Kokkos::parallel_for(mbins, f_zero); +nbin_kokkos.cpp: Kokkos::parallel_for(atom->nlocal+atom->nghost, f); +npair_kokkos.cpp: Kokkos::parallel_for(nall, f); +npair_kokkos.cpp: Kokkos::parallel_for(config, f); +npair_kokkos.cpp: Kokkos::parallel_for(nall, f); +npair_kokkos.cpp: Kokkos::parallel_for(config, f); +npair_kokkos.cpp: Kokkos::parallel_for(nall, f); +pair_eam_kokkos.cpp: Kokkos::parallel_for(Kokkos::RangePolicy(0,n),*this); +pair_eam_kokkos.cpp: Kokkos::parallel_for(Kokkos::RangePolicy(0,n),*this); +pair_kokkos.h: if (fpair->eflag || fpair->vflag) Kokkos::parallel_reduce(list->inum,ff,ev); +pair_kokkos.h: else Kokkos::parallel_for(list->inum,ff); +pair_kokkos.h: if (fpair->eflag || fpair->vflag) Kokkos::parallel_reduce(list->inum,ff,ev); +pair_kokkos.h: else Kokkos::parallel_for(list->inum,ff); +pair_reaxc_kokkos.cpp: Kokkos::parallel_reduce(inum,find_bond_functor,numbonds); +pair_reaxc_kokkos.cpp: Kokkos::parallel_scan(nlocal,pack_bond_buffer_functor); +pair_table_kokkos.cpp: if (eflag || vflag) Kokkos::parallel_reduce(list->inum,ff,ev); +pair_table_kokkos.cpp: else Kokkos::parallel_for(list->inum,ff); +pair_table_kokkos.cpp: if (eflag || vflag) Kokkos::parallel_reduce(list->inum,ff,ev); +pair_table_kokkos.cpp: else Kokkos::parallel_for(list->inum,ff); +pair_table_kokkos.cpp: if (eflag || vflag) Kokkos::parallel_reduce(list->inum,f,ev); +pair_table_kokkos.cpp: else Kokkos::parallel_for(list->inum,f); +pair_table_kokkos.cpp: if (eflag || vflag) Kokkos::parallel_reduce(nlocal,f,ev); +pair_table_kokkos.cpp: else Kokkos::parallel_for(nlocal,f); +pair_table_kokkos.cpp: if (eflag || vflag) Kokkos::parallel_reduce(list->inum,f,ev); +pair_table_kokkos.cpp: else Kokkos::parallel_for(list->inum,f); +pair_table_kokkos.cpp: if (eflag || vflag) Kokkos::parallel_reduce(list->inum,f,ev); +pair_table_kokkos.cpp: else Kokkos::parallel_for(list->inum,f); +pair_table_kokkos.cpp: if (eflag || vflag) Kokkos::parallel_reduce(list->inum,f,ev); +pair_table_kokkos.cpp: else Kokkos::parallel_for(list->inum,f); +pair_table_kokkos.cpp: if (eflag || vflag) Kokkos::parallel_reduce(nlocal,f,ev); +pair_table_kokkos.cpp: else Kokkos::parallel_for(nlocal,f); +pppm_kokkos.cpp: Kokkos::parallel_for(config,*this); +verlet_kokkos.cpp: Kokkos::parallel_for(atomKK->k_f.dimension_0(), diff --git a/src/KOKKOS/pair_eam_kokkos.cpp b/src/KOKKOS/pair_eam_kokkos.cpp index e848669947..6b2588475f 100644 --- a/src/KOKKOS/pair_eam_kokkos.cpp +++ b/src/KOKKOS/pair_eam_kokkos.cpp @@ -405,7 +405,7 @@ int PairEAMKokkos::pack_forward_comm_kokkos(int n, DAT::tdual_int_2d 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; } @@ -423,7 +423,7 @@ void PairEAMKokkos::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 diff --git a/src/KOKKOS/pair_kokkos.h b/src/KOKKOS/pair_kokkos.h index b0614a934b..a5a45dd2ec 100644 --- a/src/KOKKOS/pair_kokkos.h +++ b/src/KOKKOS/pair_kokkos.h @@ -540,11 +540,11 @@ void pair_virial_fdotr_compute(PairStyle* fpair) { EV_FLOAT virial; if (fpair->neighbor->includegroup == 0) { int nall = fpair->atom->nlocal + fpair->atom->nghost; - Kokkos::parallel_reduce(nall,PairVirialFDotRCompute(fpair->x,fpair->f,0),virial); + Kokkos::parallel_reduce(Kokkos::RangePolicy(0,nall),PairVirialFDotRCompute(fpair->x,fpair->f,0),virial); } else { - Kokkos::parallel_reduce(fpair->atom->nfirst,PairVirialFDotRCompute(fpair->x,fpair->f,0),virial); + Kokkos::parallel_reduce(Kokkos::RangePolicy(0,fpair->atom->nfirst),PairVirialFDotRCompute(fpair->x,fpair->f,0),virial); EV_FLOAT virial_ghost; - Kokkos::parallel_reduce(fpair->atom->nghost,PairVirialFDotRCompute(fpair->x,fpair->f,fpair->atom->nlocal),virial_ghost); + Kokkos::parallel_reduce(Kokkos::RangePolicy(0,fpair->atom->nghost),PairVirialFDotRCompute(fpair->x,fpair->f,fpair->atom->nlocal),virial_ghost); virial+=virial_ghost; } fpair->vflag_fdotr = 0; diff --git a/src/KOKKOS/pair_reaxc_kokkos.cpp b/src/KOKKOS/pair_reaxc_kokkos.cpp index 6be09548da..43559bde07 100644 --- a/src/KOKKOS/pair_reaxc_kokkos.cpp +++ b/src/KOKKOS/pair_reaxc_kokkos.cpp @@ -99,26 +99,26 @@ void PairReaxCKokkos::allocate() k_params_sing = Kokkos::DualView ("PairReaxC::params_sing",n+1); - paramssing = k_params_sing.d_view; + paramssing = k_params_sing.template view(); k_params_twbp = Kokkos::DualView ("PairReaxC::params_twbp",n+1,n+1); - paramstwbp = k_params_twbp.d_view; + paramstwbp = k_params_twbp.template view(); k_params_thbp = Kokkos::DualView ("PairReaxC::params_thbp",n+1,n+1,n+1); - paramsthbp = k_params_thbp.d_view; + paramsthbp = k_params_thbp.template view(); k_params_fbp = Kokkos::DualView ("PairReaxC::params_fbp",n+1,n+1,n+1,n+1); - paramsfbp = k_params_fbp.d_view; + paramsfbp = k_params_fbp.template view(); k_params_hbp = Kokkos::DualView ("PairReaxC::params_hbp",n+1,n+1,n+1); - paramshbp = k_params_hbp.d_view; + paramshbp = k_params_hbp.template view(); k_tap = DAT::tdual_ffloat_1d("pair:tap",8); - d_tap = k_tap.d_view; + d_tap = k_tap.template view(); h_tap = k_tap.h_view; } @@ -367,7 +367,7 @@ void PairReaxCKokkos::init_md() Init_Lookup_Tables(); k_LR = tdual_LR_lookup_table_kk_2d("lookup:LR",ntypes+1,ntypes+1); - d_LR = k_LR.d_view; + d_LR = k_LR.template view(); for (int i = 1; i <= ntypes; ++i) { for (int j = i; j <= ntypes; ++j) { @@ -382,19 +382,19 @@ void PairReaxCKokkos::init_md() k_LR.h_view(i,j).m = LR[i][j].m; k_LR.h_view(i,j).c = LR[i][j].c; - tdual_LR_data_1d k_y = tdual_LR_data_1d("lookup:LR[i,j].y",n); - tdual_cubic_spline_coef_1d k_H = tdual_cubic_spline_coef_1d("lookup:LR[i,j].H",n); - tdual_cubic_spline_coef_1d k_vdW = tdual_cubic_spline_coef_1d("lookup:LR[i,j].vdW",n); - tdual_cubic_spline_coef_1d k_CEvd = tdual_cubic_spline_coef_1d("lookup:LR[i,j].CEvd",n); - tdual_cubic_spline_coef_1d k_ele = tdual_cubic_spline_coef_1d("lookup:LR[i,j].ele",n); - tdual_cubic_spline_coef_1d k_CEclmb = tdual_cubic_spline_coef_1d("lookup:LR[i,j].CEclmb",n); + typename LR_lookup_table_kk::tdual_LR_data_1d k_y = typename LR_lookup_table_kk::tdual_LR_data_1d("lookup:LR[i,j].y",n); + typename LR_lookup_table_kk::tdual_cubic_spline_coef_1d k_H = typename LR_lookup_table_kk::tdual_cubic_spline_coef_1d("lookup:LR[i,j].H",n); + typename LR_lookup_table_kk::tdual_cubic_spline_coef_1d k_vdW = typename LR_lookup_table_kk::tdual_cubic_spline_coef_1d("lookup:LR[i,j].vdW",n); + typename LR_lookup_table_kk::tdual_cubic_spline_coef_1d k_CEvd = typename LR_lookup_table_kk::tdual_cubic_spline_coef_1d("lookup:LR[i,j].CEvd",n); + typename LR_lookup_table_kk::tdual_cubic_spline_coef_1d k_ele = typename LR_lookup_table_kk::tdual_cubic_spline_coef_1d("lookup:LR[i,j].ele",n); + typename LR_lookup_table_kk::tdual_cubic_spline_coef_1d k_CEclmb = typename LR_lookup_table_kk::tdual_cubic_spline_coef_1d("lookup:LR[i,j].CEclmb",n); - k_LR.h_view(i,j).d_y = k_y.d_view; - k_LR.h_view(i,j).d_H = k_H.d_view; - k_LR.h_view(i,j).d_vdW = k_vdW.d_view; - k_LR.h_view(i,j).d_CEvd = k_CEvd.d_view; - k_LR.h_view(i,j).d_ele = k_ele.d_view; - k_LR.h_view(i,j).d_CEclmb = k_CEclmb.d_view; + k_LR.h_view(i,j).d_y = k_y.template view(); + k_LR.h_view(i,j).d_H = k_H.template view(); + k_LR.h_view(i,j).d_vdW = k_vdW.template view(); + k_LR.h_view(i,j).d_CEvd = k_CEvd.template view(); + k_LR.h_view(i,j).d_ele = k_ele.template view(); + k_LR.h_view(i,j).d_CEclmb = k_CEclmb.template view(); for (int k = 0; k < n; k++) { k_y.h_view(k) = LR[i][j].y[k]; @@ -1213,7 +1213,7 @@ void PairReaxCKokkos::operator()(PairReaxComputeTabulatedLJCoulomb t = d_LR(tmin,tmax); /* Cubic Spline Interpolation */ diff --git a/src/KOKKOS/pair_reaxc_kokkos.h b/src/KOKKOS/pair_reaxc_kokkos.h index 59c4d196d5..95fd7ced38 100644 --- a/src/KOKKOS/pair_reaxc_kokkos.h +++ b/src/KOKKOS/pair_reaxc_kokkos.h @@ -39,14 +39,15 @@ PairStyle(reax/c/kk/host,PairReaxCKokkos) namespace LAMMPS_NS { -typedef Kokkos::DualView tdual_LR_data_1d; -typedef typename tdual_LR_data_1d::t_dev t_LR_data_1d; - -typedef Kokkos::DualView tdual_cubic_spline_coef_1d; -typedef typename tdual_cubic_spline_coef_1d::t_dev t_cubic_spline_coef_1d; - +template struct LR_lookup_table_kk { + typedef Kokkos::DualView tdual_LR_data_1d; + typedef typename tdual_LR_data_1d::t_dev t_LR_data_1d; + + typedef Kokkos::DualView tdual_cubic_spline_coef_1d; + typedef typename tdual_cubic_spline_coef_1d::t_dev t_cubic_spline_coef_1d; + double xmin, xmax; int n; double dx, inv_dx; @@ -397,7 +398,7 @@ class PairReaxCKokkos : public PairReaxC { HAT::t_virial_array h_vatom; DAT::tdual_float_1d k_tap; - DAT::t_float_1d d_tap; + typename AT::t_float_1d d_tap; HAT::t_float_1d h_tap; typename AT::t_float_1d d_bo_rij, d_hb_rsq, d_Deltap, d_Deltap_boc, d_total_bo; @@ -438,7 +439,9 @@ class PairReaxCKokkos : public PairReaxC { int bocnt,hbcnt; - typedef Kokkos::DualView tdual_LR_lookup_table_kk_2d; + typedef LR_lookup_table_kk LR_lookup_table_kk_DT; + + typedef Kokkos::DualView tdual_LR_lookup_table_kk_2d; typedef typename tdual_LR_lookup_table_kk_2d::t_dev t_LR_lookup_table_kk_2d; tdual_LR_lookup_table_kk_2d k_LR; diff --git a/src/KOKKOS/verlet_kokkos.h b/src/KOKKOS/verlet_kokkos.h index 6455239204..7b140b6f81 100644 --- a/src/KOKKOS/verlet_kokkos.h +++ b/src/KOKKOS/verlet_kokkos.h @@ -14,6 +14,8 @@ #ifdef INTEGRATE_CLASS IntegrateStyle(verlet/kk,VerletKokkos) +IntegrateStyle(verlet/kk/device,VerletKokkos) +IntegrateStyle(verlet/kk/host,VerletKokkos) #else From 9df61b642e564473b090f89bec12b0bfc2aa300c Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 18 Jul 2017 10:44:45 -0600 Subject: [PATCH 309/439] Removing stray file --- src/KOKKOS/out.txt | 321 --------------------------------------------- 1 file changed, 321 deletions(-) delete mode 100644 src/KOKKOS/out.txt diff --git a/src/KOKKOS/out.txt b/src/KOKKOS/out.txt deleted file mode 100644 index 00908bf69a..0000000000 --- a/src/KOKKOS/out.txt +++ /dev/null @@ -1,321 +0,0 @@ -atom_vec_angle_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_angle_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_angle_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_angle_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_angle_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_angle_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_angle_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_angle_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_angle_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_angle_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_angle_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_angle_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_angle_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_angle_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_angle_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_angle_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_angle_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_angle_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_angle_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_angle_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_angle_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_angle_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_angle_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_angle_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_angle_kokkos.cpp: Kokkos::parallel_for(nsend,f); -atom_vec_angle_kokkos.cpp: Kokkos::parallel_for(nsend,f); -atom_vec_angle_kokkos.cpp: Kokkos::parallel_for(nrecv/elements,f); -atom_vec_angle_kokkos.cpp: Kokkos::parallel_for(nrecv/elements,f); -atom_vec_atomic_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_atomic_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_atomic_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_atomic_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_atomic_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_atomic_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_atomic_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_atomic_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_atomic_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_atomic_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_atomic_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_atomic_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_atomic_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_atomic_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_atomic_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_atomic_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_atomic_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_atomic_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_atomic_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_atomic_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_atomic_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_atomic_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_atomic_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_atomic_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_atomic_kokkos.cpp: Kokkos::parallel_for(nsend,f); -atom_vec_atomic_kokkos.cpp: Kokkos::parallel_for(nsend,f); -atom_vec_atomic_kokkos.cpp: Kokkos::parallel_for(nrecv/11,f); -atom_vec_atomic_kokkos.cpp: Kokkos::parallel_for(nrecv/11,f); -atom_vec_bond_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_bond_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_bond_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_bond_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_bond_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_bond_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_bond_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_bond_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_bond_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_bond_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_bond_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_bond_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_bond_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_bond_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_bond_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_bond_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_bond_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_bond_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_bond_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_bond_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_bond_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_bond_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_bond_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_bond_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_bond_kokkos.cpp: Kokkos::parallel_for(nsend,f); -atom_vec_bond_kokkos.cpp: Kokkos::parallel_for(nsend,f); -atom_vec_bond_kokkos.cpp: Kokkos::parallel_for(nrecv/elements,f); -atom_vec_bond_kokkos.cpp: Kokkos::parallel_for(nrecv/elements,f); -atom_vec_charge_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_charge_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_charge_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_charge_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_charge_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_charge_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_charge_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_charge_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_charge_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_charge_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_charge_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_charge_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_charge_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_charge_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_charge_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_charge_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_charge_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_charge_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_charge_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_charge_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_charge_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_charge_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_charge_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_charge_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_charge_kokkos.cpp: Kokkos::parallel_for(nsend,f); -atom_vec_charge_kokkos.cpp: Kokkos::parallel_for(nsend,f); -atom_vec_charge_kokkos.cpp: Kokkos::parallel_for(nrecv/12,f); -atom_vec_charge_kokkos.cpp: Kokkos::parallel_for(nrecv/12,f); -atom_vec_full_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_full_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_full_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_full_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_full_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_full_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_full_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_full_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_full_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_full_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_full_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_full_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_full_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_full_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_full_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_full_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_full_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_full_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_full_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_full_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_full_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_full_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_full_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_full_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_full_kokkos.cpp: Kokkos::parallel_for(nsend,f); -atom_vec_full_kokkos.cpp: Kokkos::parallel_for(nsend,f); -atom_vec_full_kokkos.cpp: Kokkos::parallel_for(nrecv/elements,f); -atom_vec_full_kokkos.cpp: Kokkos::parallel_for(nrecv/elements,f); -atom_vec_molecular_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_molecular_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_molecular_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_molecular_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_molecular_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_molecular_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_molecular_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_molecular_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_molecular_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_molecular_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_molecular_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_molecular_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_molecular_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_molecular_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_molecular_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_molecular_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_molecular_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_molecular_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_molecular_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_molecular_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_molecular_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_molecular_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_molecular_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_molecular_kokkos.cpp: Kokkos::parallel_for(n,f); -atom_vec_molecular_kokkos.cpp: Kokkos::parallel_for(nsend,f); -atom_vec_molecular_kokkos.cpp: Kokkos::parallel_for(nsend,f); -atom_vec_molecular_kokkos.cpp: Kokkos::parallel_for(nrecv/elements,f); -atom_vec_molecular_kokkos.cpp: Kokkos::parallel_for(nrecv/elements,f); -comm_kokkos.cpp: Kokkos::parallel_for(nlocal,f); -comm_kokkos.cpp: Kokkos::parallel_for(config,f); -comm_kokkos.cpp: Kokkos::parallel_for(config,f); -domain_kokkos.cpp: Kokkos::parallel_reduce(nlocal,f,result); -domain_kokkos.cpp: Kokkos::parallel_for(nlocal,f); -domain_kokkos.cpp: Kokkos::parallel_for(nlocal,f); -domain_kokkos.cpp: Kokkos::parallel_for(nlocal,f); -domain_kokkos.cpp: Kokkos::parallel_for(nlocal,f); -fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); -fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); -fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); -fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); -fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); -fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); -fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); -fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); -fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); -fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); -fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); -fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); -fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); -fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); -fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); -fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); -fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); -fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); -fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); -fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); -fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); -fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); -fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); -fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); -fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); -fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); -fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); -fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); -fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); -fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); -fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); -fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); -fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); -fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); -fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); -fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); -fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); -fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); -fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); -fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); -fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); -fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); -fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); -fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); -fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); -fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); -fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); -fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); -fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); -fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); -fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); -fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); -fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); -fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); -fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); -fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); -fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); -fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); -fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); -fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); -fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); -fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); -fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,post_functor,s_fsum); -fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,post_functor); -fix_langevin_kokkos.cpp: Kokkos::parallel_for(nlocal,zero_functor); -fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,scalar_functor,energy_onestep); -fix_langevin_kokkos.cpp: Kokkos::parallel_reduce(nlocal,tally_functor,energy_onestep); -fix_momentum_kokkos.cpp: Kokkos::parallel_reduce(nlocal, LAMMPS_LAMBDA(int i, double& update) { -fix_momentum_kokkos.cpp: Kokkos::parallel_reduce(nlocal, LAMMPS_LAMBDA(int i, double& update) { -fix_momentum_kokkos.cpp: Kokkos::parallel_for(nlocal, LAMMPS_LAMBDA(int i) { -fix_momentum_kokkos.cpp: Kokkos::parallel_for(nlocal, LAMMPS_LAMBDA(int i) { -fix_momentum_kokkos.cpp: Kokkos::parallel_for(nlocal, LAMMPS_LAMBDA(int i) { -fix_nve_kokkos.cpp: Kokkos::parallel_for(nlocal,functor); -fix_nve_kokkos.cpp: Kokkos::parallel_for(nlocal,functor); -fix_nve_kokkos.cpp: Kokkos::parallel_for(nlocal,functor); -fix_nve_kokkos.cpp: Kokkos::parallel_for(nlocal,functor); -fix_qeq_reax_kokkos.cpp: Kokkos::parallel_scan(inum,computeH_functor); -fix_qeq_reax_kokkos.cpp: Kokkos::parallel_for(inum,matvec_functor); -fix_qeq_reax_kokkos.cpp: Kokkos::parallel_reduce(inum,neigh_functor,m_cap); -fix_qeq_reax_kokkos.cpp: Kokkos::parallel_for(ignum,zero_functor); -fix_qeq_reax_kokkos.cpp: Kokkos::parallel_for(inum,sparse12_functor); -fix_qeq_reax_kokkos.cpp: Kokkos::parallel_for(inum,sparse13_functor); -fix_qeq_reax_kokkos.cpp: Kokkos::parallel_for(inum,sparse13_functor); -fix_qeq_reax_kokkos.cpp: Kokkos::parallel_reduce(inum,norm1_functor,my_norm); -fix_qeq_reax_kokkos.cpp: Kokkos::parallel_reduce(inum,dot1_functor,my_dot); -fix_qeq_reax_kokkos.cpp: Kokkos::parallel_for(inum,sparse22_functor); -fix_qeq_reax_kokkos.cpp: Kokkos::parallel_for(inum,sparse23_functor); -fix_qeq_reax_kokkos.cpp: Kokkos::parallel_for(inum,sparse23_functor); -fix_qeq_reax_kokkos.cpp: Kokkos::parallel_reduce(inum,dot2_functor,my_dot); -fix_qeq_reax_kokkos.cpp: Kokkos::parallel_for(inum,precon1_functor); -fix_qeq_reax_kokkos.cpp: Kokkos::parallel_reduce(inum,precon_functor,my_dot); -fix_qeq_reax_kokkos.cpp: Kokkos::parallel_for(inum,vecsum2_functor); -fix_qeq_reax_kokkos.cpp: Kokkos::parallel_for(inum,sparse32_functor); -fix_qeq_reax_kokkos.cpp: Kokkos::parallel_for(inum,sparse33_functor); -fix_qeq_reax_kokkos.cpp: Kokkos::parallel_for(inum,sparse33_functor); -fix_qeq_reax_kokkos.cpp: Kokkos::parallel_reduce(inum,norm2_functor,my_norm); -fix_qeq_reax_kokkos.cpp: Kokkos::parallel_reduce(inum,dot1_functor,my_dot); -fix_qeq_reax_kokkos.cpp: Kokkos::parallel_for(inum,sparse22_functor); -fix_qeq_reax_kokkos.cpp: Kokkos::parallel_for(inum,sparse23_functor); -fix_qeq_reax_kokkos.cpp: Kokkos::parallel_for(inum,sparse23_functor); -fix_qeq_reax_kokkos.cpp: Kokkos::parallel_reduce(inum,dot2_functor,my_dot); -fix_qeq_reax_kokkos.cpp: Kokkos::parallel_for(inum,precon2_functor); -fix_qeq_reax_kokkos.cpp: Kokkos::parallel_reduce(inum,precon_functor,my_dot); -fix_qeq_reax_kokkos.cpp: Kokkos::parallel_for(inum,vecsum2_functor); -fix_qeq_reax_kokkos.cpp: Kokkos::parallel_reduce(inum,vecacc1_functor,sum); -fix_qeq_reax_kokkos.cpp: Kokkos::parallel_reduce(inum,vecacc2_functor,sum); -fix_qeq_reax_kokkos.cpp: Kokkos::parallel_for(inum,calculateQ_functor); -fix_qeq_reax_kokkos.cpp: Kokkos::parallel_reduce(Kokkos::TeamThreadRange(team, d_firstnbr[i], d_firstnbr[i] + d_numnbrs[i]), [&] (const int &jj, F_FLOAT &doi) { -fix_qeq_reax_kokkos.cpp: Kokkos::parallel_reduce(Kokkos::TeamThreadRange(team, d_firstnbr[i], d_firstnbr[i] + d_numnbrs[i]), [&] (const int &jj, F_FLOAT &doi) { -fix_qeq_reax_kokkos.cpp: Kokkos::parallel_reduce(Kokkos::TeamThreadRange(team, d_firstnbr[i], d_firstnbr[i] + d_numnbrs[i]), [&] (const int &jj, F_FLOAT &doi) { -kokkos_type.h: Kokkos::parallel_for(view.span()*sizeof(typename ViewType::value_type)/4, f); -kokkos_type.h: Kokkos::parallel_for(view.capacity()*sizeof(typename ViewType::value_type)/4, f); -nbin_kokkos.cpp: Kokkos::parallel_for(mbins, f_zero); -nbin_kokkos.cpp: Kokkos::parallel_for(atom->nlocal+atom->nghost, f); -npair_kokkos.cpp: Kokkos::parallel_for(nall, f); -npair_kokkos.cpp: Kokkos::parallel_for(config, f); -npair_kokkos.cpp: Kokkos::parallel_for(nall, f); -npair_kokkos.cpp: Kokkos::parallel_for(config, f); -npair_kokkos.cpp: Kokkos::parallel_for(nall, f); -pair_eam_kokkos.cpp: Kokkos::parallel_for(Kokkos::RangePolicy(0,n),*this); -pair_eam_kokkos.cpp: Kokkos::parallel_for(Kokkos::RangePolicy(0,n),*this); -pair_kokkos.h: if (fpair->eflag || fpair->vflag) Kokkos::parallel_reduce(list->inum,ff,ev); -pair_kokkos.h: else Kokkos::parallel_for(list->inum,ff); -pair_kokkos.h: if (fpair->eflag || fpair->vflag) Kokkos::parallel_reduce(list->inum,ff,ev); -pair_kokkos.h: else Kokkos::parallel_for(list->inum,ff); -pair_reaxc_kokkos.cpp: Kokkos::parallel_reduce(inum,find_bond_functor,numbonds); -pair_reaxc_kokkos.cpp: Kokkos::parallel_scan(nlocal,pack_bond_buffer_functor); -pair_table_kokkos.cpp: if (eflag || vflag) Kokkos::parallel_reduce(list->inum,ff,ev); -pair_table_kokkos.cpp: else Kokkos::parallel_for(list->inum,ff); -pair_table_kokkos.cpp: if (eflag || vflag) Kokkos::parallel_reduce(list->inum,ff,ev); -pair_table_kokkos.cpp: else Kokkos::parallel_for(list->inum,ff); -pair_table_kokkos.cpp: if (eflag || vflag) Kokkos::parallel_reduce(list->inum,f,ev); -pair_table_kokkos.cpp: else Kokkos::parallel_for(list->inum,f); -pair_table_kokkos.cpp: if (eflag || vflag) Kokkos::parallel_reduce(nlocal,f,ev); -pair_table_kokkos.cpp: else Kokkos::parallel_for(nlocal,f); -pair_table_kokkos.cpp: if (eflag || vflag) Kokkos::parallel_reduce(list->inum,f,ev); -pair_table_kokkos.cpp: else Kokkos::parallel_for(list->inum,f); -pair_table_kokkos.cpp: if (eflag || vflag) Kokkos::parallel_reduce(list->inum,f,ev); -pair_table_kokkos.cpp: else Kokkos::parallel_for(list->inum,f); -pair_table_kokkos.cpp: if (eflag || vflag) Kokkos::parallel_reduce(list->inum,f,ev); -pair_table_kokkos.cpp: else Kokkos::parallel_for(list->inum,f); -pair_table_kokkos.cpp: if (eflag || vflag) Kokkos::parallel_reduce(nlocal,f,ev); -pair_table_kokkos.cpp: else Kokkos::parallel_for(nlocal,f); -pppm_kokkos.cpp: Kokkos::parallel_for(config,*this); -verlet_kokkos.cpp: Kokkos::parallel_for(atomKK->k_f.dimension_0(), From 1b34bec81a2cca135b9b483f35800ce72e5f5e97 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 18 Jul 2017 10:59:34 -0600 Subject: [PATCH 310/439] Prefer DeviceType specification over RangePolicy --- src/KOKKOS/pair_kokkos.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/KOKKOS/pair_kokkos.h b/src/KOKKOS/pair_kokkos.h index a5a45dd2ec..f0e357270c 100644 --- a/src/KOKKOS/pair_kokkos.h +++ b/src/KOKKOS/pair_kokkos.h @@ -513,6 +513,7 @@ EV_FLOAT pair_compute (PairStyle* fpair, NeighListKokkos struct PairVirialFDotRCompute { + typedef DeviceType device_type; typedef ArrayTypes AT; typedef EV_FLOAT value_type; typename AT::t_x_array_const_um x; @@ -540,11 +541,11 @@ void pair_virial_fdotr_compute(PairStyle* fpair) { EV_FLOAT virial; if (fpair->neighbor->includegroup == 0) { int nall = fpair->atom->nlocal + fpair->atom->nghost; - Kokkos::parallel_reduce(Kokkos::RangePolicy(0,nall),PairVirialFDotRCompute(fpair->x,fpair->f,0),virial); + Kokkos::parallel_reduce(nall,PairVirialFDotRCompute(fpair->x,fpair->f,0),virial); } else { - Kokkos::parallel_reduce(Kokkos::RangePolicy(0,fpair->atom->nfirst),PairVirialFDotRCompute(fpair->x,fpair->f,0),virial); + Kokkos::parallel_reduce(fpair->atom->nfirst,PairVirialFDotRCompute(fpair->x,fpair->f,0),virial); EV_FLOAT virial_ghost; - Kokkos::parallel_reduce(Kokkos::RangePolicy(0,fpair->atom->nghost),PairVirialFDotRCompute(fpair->x,fpair->f,fpair->atom->nlocal),virial_ghost); + Kokkos::parallel_reduce(fpair->atom->nghost,PairVirialFDotRCompute(fpair->x,fpair->f,fpair->atom->nlocal),virial_ghost); virial+=virial_ghost; } fpair->vflag_fdotr = 0; From a9eaeb4d95a896e5ccb60b424152913e250d43d6 Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Tue, 18 Jul 2017 13:47:03 -0600 Subject: [PATCH 311/439] working on GPU build --- cmake/CMakeLists.txt | 29 ++++++++++++++++++++++++++--- lib/gpu/lal_pppm.cu | 5 +++++ 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 17759cbb65..0212e3906d 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -421,7 +421,16 @@ endif() if(ENABLE_GPU) find_package(CUDA REQUIRED) + find_program(BIN2C bin2c) + if(NOT BIN2C) + message(FATAL_ERROR "Couldn't find bin2c") + endif() include_directories(${CUDA_TOOLKIT_INCLUDE}) + set(CUDA_BUILD_CUBIN ON) + set(GPU_PREC "SINGLE_DOUBLE" CACHE STRING "Lammps gpu precision size") + set_property(CACHE GPU_PREC PROPERTY STRINGS SINGLE_DOUBLE SINGLE_SINGLE DOUBLE_DOUBLE) + add_definitions(-D_${GPU_PREC}) + add_definitions(-DNV_KERNEL -DUSE_CUDPP -DUCL_CUDADR -DCMAKE_GPU) set(GPU_SOURCES_DIR ${LAMMPS_SOURCE_DIR}/GPU) set(GPU_SOURCES ${GPU_SOURCES_DIR}/gpu_extra.h) @@ -432,15 +441,29 @@ if(ENABLE_GPU) RegisterStylesExt(${GPU_SOURCES_DIR} opt GPU_SOURCES) get_property(GPU_SOURCES GLOBAL PROPERTY GPU_SOURCES) - file(GLOB_RECURSE GPU_LIB_SOURCES ${LAMMPS_LIB_SOURCE_DIR}/gpu/*.cpp ${LAMMPS_LIB_SOURCE_DIR}/gpu/*.cu) cuda_add_library(lammps_gpu ${GPU_LIB_SOURCES}) - + #add_custom_target(cubin_headers) + #file(GLOB_RECURSE GPU_LIB_CUBIN ${LAMMPS_LIB_SOURCE_DIR}/gpu/*.cubin) + #file(MAKE_DIRECTORY ${LAMMPS_LIB_BINARY_DIR}/gpu) + #foreach(CUBIN ${GPU_LIB_CUBIN}) + # get_filename_component(CUBIN_NAME NAME_WE ${CUBIN}) + # message("XXX ${CUBIN_NAME}_cubin.h") + # add_custom_command(OUTPUT ${LAMMPS_LIB_BINARY_DIR/gpu/${CUBIN_NAME}_cubin.h + # COMMAND ${BIN2C} -c -n ${CUBIN_NAME} ${CUBIN} > ${LAMMPS_LIB_BINARY_DIR}/gpu/${CUBIN_NAME}_cubin.h + # DEPENDS ${CUBIN} + # COMMENT "Generating ${CUBIN_NAME}_cubin.h") + # add_custom_target(${CUBIN_NAME}_cubin DEPENDS ${LAMMPS_LIB_BINARY_DIR/gpu/${CUBIN_NAME}_cubin.h) + # add_dependencies(cubin_headers ${CUBIN_NAME}_cubin) + #endforeach() + #add_dependencies(lammps_gpu cubin_headers) + list(APPEND LAMMPS_LINK_LIBS lammps_gpu) list(APPEND LIB_SOURCES ${GPU_SOURCES}) - include_directories(${GPU_SOURCES_DIR} ${LAMMPS_LIB_SOURCE_DIR}/gpu) + include_directories(${GPU_SOURCES_DIR} ${LAMMPS_LIB_SOURCE_DIR}/gpu + ${LAMMPS_LIB_SOURCE_DIR}/gpu/cudpp_mini ${LAMMPS_LIB_BINARY_DIR}/gpu) endif() ###################################################### diff --git a/lib/gpu/lal_pppm.cu b/lib/gpu/lal_pppm.cu index 24636b9a93..fede2180cf 100644 --- a/lib/gpu/lal_pppm.cu +++ b/lib/gpu/lal_pppm.cu @@ -13,6 +13,11 @@ // email : brownw@ornl.gov // ***************************************************************************/ +#ifdef CMAKE_GPU +#define grdtyp float +#define grdtyp4 float4 +#endif + #ifdef NV_KERNEL #include "lal_preprocessor.h" From c3d9786616c62c40d6d03347436855dd67a4e718 Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Tue, 18 Jul 2017 16:01:35 -0600 Subject: [PATCH 312/439] GPU compiles --- cmake/CMakeLists.txt | 43 ++++++++++++++++++++++++------------------- lib/gpu/lal_pppm.cu | 5 ----- lib/gpu/lal_pppm_d.cu | 6 ++++++ lib/gpu/lal_pppm_f.cu | 6 ++++++ 4 files changed, 36 insertions(+), 24 deletions(-) create mode 100644 lib/gpu/lal_pppm_d.cu create mode 100644 lib/gpu/lal_pppm_f.cu diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 0212e3906d..ff92c370d6 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -427,6 +427,7 @@ if(ENABLE_GPU) endif() include_directories(${CUDA_TOOLKIT_INCLUDE}) set(CUDA_BUILD_CUBIN ON) + set(CUDA_GENERATED_OUTPUT_DIR ${LAMMPS_LIB_BINARY_DIR}/gpu) set(GPU_PREC "SINGLE_DOUBLE" CACHE STRING "Lammps gpu precision size") set_property(CACHE GPU_PREC PROPERTY STRINGS SINGLE_DOUBLE SINGLE_SINGLE DOUBLE_DOUBLE) add_definitions(-D_${GPU_PREC}) @@ -442,28 +443,29 @@ if(ENABLE_GPU) get_property(GPU_SOURCES GLOBAL PROPERTY GPU_SOURCES) - file(GLOB_RECURSE GPU_LIB_SOURCES ${LAMMPS_LIB_SOURCE_DIR}/gpu/*.cpp - ${LAMMPS_LIB_SOURCE_DIR}/gpu/*.cu) - cuda_add_library(lammps_gpu ${GPU_LIB_SOURCES}) - #add_custom_target(cubin_headers) - #file(GLOB_RECURSE GPU_LIB_CUBIN ${LAMMPS_LIB_SOURCE_DIR}/gpu/*.cubin) - #file(MAKE_DIRECTORY ${LAMMPS_LIB_BINARY_DIR}/gpu) - #foreach(CUBIN ${GPU_LIB_CUBIN}) - # get_filename_component(CUBIN_NAME NAME_WE ${CUBIN}) - # message("XXX ${CUBIN_NAME}_cubin.h") - # add_custom_command(OUTPUT ${LAMMPS_LIB_BINARY_DIR/gpu/${CUBIN_NAME}_cubin.h - # COMMAND ${BIN2C} -c -n ${CUBIN_NAME} ${CUBIN} > ${LAMMPS_LIB_BINARY_DIR}/gpu/${CUBIN_NAME}_cubin.h - # DEPENDS ${CUBIN} - # COMMENT "Generating ${CUBIN_NAME}_cubin.h") - # add_custom_target(${CUBIN_NAME}_cubin DEPENDS ${LAMMPS_LIB_BINARY_DIR/gpu/${CUBIN_NAME}_cubin.h) - # add_dependencies(cubin_headers ${CUBIN_NAME}_cubin) - #endforeach() - #add_dependencies(lammps_gpu cubin_headers) - + file(GLOB_RECURSE GPU_LIB_SOURCES ${LAMMPS_LIB_SOURCE_DIR}/gpu/*.cpp) + file(GLOB_RECURSE GPU_LIB_CU ${LAMMPS_LIB_SOURCE_DIR}/gpu/*.cu) + file(GLOB_RECURSE GPU_NOT_LIB_CU ${LAMMPS_LIB_SOURCE_DIR}/gpu/lal_pppm.cu) + list(REMOVE_ITEM GPU_LIB_CU ${GPU_NOT_LIB_CU}) + cuda_add_library(lammps_gpu ${GPU_LIB_CU}) + file(MAKE_DIRECTORY ${LAMMPS_LIB_BINARY_DIR}/gpu) + add_custom_target(cubin_headers) + foreach(CU ${GPU_LIB_CU}) + get_filename_component(CU_NAME ${CU} NAME_WE) + set(CU_OBJ ${CUDA_GENERATED_OUTPUT_DIR}/lammps_gpu_generated_${CU_NAME}.cu.o.cubin.txt) + string(REGEX REPLACE "^lal_" "" CU_HEADER "${CU_NAME}") + add_custom_command(OUTPUT ${LAMMPS_LIB_BINARY_DIR}/gpu/${CU_HEADER}_cubin.h + COMMAND ${BIN2C} -c -n ${CU_HEADER} ${CU_OBJ} > ${LAMMPS_LIB_BINARY_DIR}/gpu/${CU_HEADER}_cubin.h + DEPENDS ${CU_OBJ} + COMMENT "Generating ${CU_HEADER}_cubin.h") + add_custom_target(${CU_HEADER}_cubin DEPENDS ${LAMMPS_LIB_BINARY_DIR}/gpu/${CU_HEADER}_cubin.h) + add_dependencies(cubin_headers ${CU_HEADER}_cubin) + endforeach() list(APPEND LAMMPS_LINK_LIBS lammps_gpu) - list(APPEND LIB_SOURCES ${GPU_SOURCES}) + list(APPEND LIB_SOURCES ${GPU_SOURCES} ${GPU_LIB_SOURCES}) include_directories(${GPU_SOURCES_DIR} ${LAMMPS_LIB_SOURCE_DIR}/gpu ${LAMMPS_LIB_SOURCE_DIR}/gpu/cudpp_mini ${LAMMPS_LIB_BINARY_DIR}/gpu) + set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${AMMPS_LIB_BINARY_DIR}/gpu") endif() ###################################################### @@ -479,6 +481,9 @@ include_directories(${LAMMPS_STYLE_HEADERS_DIR}) add_library(lammps ${LIB_SOURCES}) +if(ENABLE_GPU) + add_dependencies(lammps cubin_headers) +endif() target_link_libraries(lammps ${LAMMPS_LINK_LIBS}) set_target_properties(lammps PROPERTIES SOVERSION ${SOVERSION}) diff --git a/lib/gpu/lal_pppm.cu b/lib/gpu/lal_pppm.cu index fede2180cf..24636b9a93 100644 --- a/lib/gpu/lal_pppm.cu +++ b/lib/gpu/lal_pppm.cu @@ -13,11 +13,6 @@ // email : brownw@ornl.gov // ***************************************************************************/ -#ifdef CMAKE_GPU -#define grdtyp float -#define grdtyp4 float4 -#endif - #ifdef NV_KERNEL #include "lal_preprocessor.h" diff --git a/lib/gpu/lal_pppm_d.cu b/lib/gpu/lal_pppm_d.cu new file mode 100644 index 0000000000..e00ad50496 --- /dev/null +++ b/lib/gpu/lal_pppm_d.cu @@ -0,0 +1,6 @@ +#ifdef CMAKE_GPU +#define grdtyp double +#define grdtyp4 double4 +#endif + +#include "lal_pppm.cu" diff --git a/lib/gpu/lal_pppm_f.cu b/lib/gpu/lal_pppm_f.cu new file mode 100644 index 0000000000..8c8ca88167 --- /dev/null +++ b/lib/gpu/lal_pppm_f.cu @@ -0,0 +1,6 @@ +#ifdef CMAKE_GPU +#define grdtyp float +#define grdtyp4 float4 +#endif + +#include "lal_pppm.cu" From 4d65c327f54a02d0f1a90de792609baae47fa456 Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Tue, 18 Jul 2017 16:06:29 -0600 Subject: [PATCH 313/439] added minimal README --- cmake/README | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 cmake/README diff --git a/cmake/README b/cmake/README new file mode 100644 index 0000000000..cc67cceb52 --- /dev/null +++ b/cmake/README @@ -0,0 +1,19 @@ +cmake-buildsystem +----------------- + +To use the cmake build system instead of the make-driven one, do: +``` +cmake /path/to/lammps/source/cmake +``` +(please note the cmake directory as the very end) + +To enable package, e.g. GPU do +``` +cmake /path/to/lammps/source/cmake -DENABLE_GPU=ON +``` + +cmake has many many options, do get an overview use the curses-based cmake interface, ccmake: +``` +ccmake /path/to/lammps/source/cmake +``` +(Don't forget to press "g" for generate once you are done with configuring) From 864fd9cd8788af46e1e055fa4786a074c1e7d6e6 Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Tue, 18 Jul 2017 18:20:23 -0600 Subject: [PATCH 314/439] remove cubin_headers hack --- cmake/CMakeLists.txt | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index ff92c370d6..224de45a09 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -449,7 +449,6 @@ if(ENABLE_GPU) list(REMOVE_ITEM GPU_LIB_CU ${GPU_NOT_LIB_CU}) cuda_add_library(lammps_gpu ${GPU_LIB_CU}) file(MAKE_DIRECTORY ${LAMMPS_LIB_BINARY_DIR}/gpu) - add_custom_target(cubin_headers) foreach(CU ${GPU_LIB_CU}) get_filename_component(CU_NAME ${CU} NAME_WE) set(CU_OBJ ${CUDA_GENERATED_OUTPUT_DIR}/lammps_gpu_generated_${CU_NAME}.cu.o.cubin.txt) @@ -458,8 +457,7 @@ if(ENABLE_GPU) COMMAND ${BIN2C} -c -n ${CU_HEADER} ${CU_OBJ} > ${LAMMPS_LIB_BINARY_DIR}/gpu/${CU_HEADER}_cubin.h DEPENDS ${CU_OBJ} COMMENT "Generating ${CU_HEADER}_cubin.h") - add_custom_target(${CU_HEADER}_cubin DEPENDS ${LAMMPS_LIB_BINARY_DIR}/gpu/${CU_HEADER}_cubin.h) - add_dependencies(cubin_headers ${CU_HEADER}_cubin) + list(APPEND LIB_SOURCES ${LAMMPS_LIB_BINARY_DIR}/gpu/${CU_HEADER}_cubin.h) endforeach() list(APPEND LAMMPS_LINK_LIBS lammps_gpu) list(APPEND LIB_SOURCES ${GPU_SOURCES} ${GPU_LIB_SOURCES}) @@ -481,9 +479,6 @@ include_directories(${LAMMPS_STYLE_HEADERS_DIR}) add_library(lammps ${LIB_SOURCES}) -if(ENABLE_GPU) - add_dependencies(lammps cubin_headers) -endif() target_link_libraries(lammps ${LAMMPS_LINK_LIBS}) set_target_properties(lammps PROPERTIES SOVERSION ${SOVERSION}) From e6f5f77edfacadfd4c4f55c167533279a3f0c6af Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Tue, 18 Jul 2017 18:38:36 -0600 Subject: [PATCH 315/439] GPU: clean up --- cmake/CMakeLists.txt | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 224de45a09..c5c8326080 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -447,23 +447,22 @@ if(ENABLE_GPU) file(GLOB_RECURSE GPU_LIB_CU ${LAMMPS_LIB_SOURCE_DIR}/gpu/*.cu) file(GLOB_RECURSE GPU_NOT_LIB_CU ${LAMMPS_LIB_SOURCE_DIR}/gpu/lal_pppm.cu) list(REMOVE_ITEM GPU_LIB_CU ${GPU_NOT_LIB_CU}) - cuda_add_library(lammps_gpu ${GPU_LIB_CU}) + add_custom_target(gpu_objs) + cuda_wrap_srcs(gpu_objs OBJ GPU_OBJS ${GPU_LIB_CU}) file(MAKE_DIRECTORY ${LAMMPS_LIB_BINARY_DIR}/gpu) - foreach(CU ${GPU_LIB_CU}) - get_filename_component(CU_NAME ${CU} NAME_WE) - set(CU_OBJ ${CUDA_GENERATED_OUTPUT_DIR}/lammps_gpu_generated_${CU_NAME}.cu.o.cubin.txt) - string(REGEX REPLACE "^lal_" "" CU_HEADER "${CU_NAME}") - add_custom_command(OUTPUT ${LAMMPS_LIB_BINARY_DIR}/gpu/${CU_HEADER}_cubin.h - COMMAND ${BIN2C} -c -n ${CU_HEADER} ${CU_OBJ} > ${LAMMPS_LIB_BINARY_DIR}/gpu/${CU_HEADER}_cubin.h + foreach(CU_OBJ ${GPU_OBJS}) + get_filename_component(CU_NAME ${CU_OBJ} NAME_WE) + string(REGEX REPLACE "^.*_lal_" "" CU_NAME "${CU_NAME}") + add_custom_command(OUTPUT ${LAMMPS_LIB_BINARY_DIR}/gpu/${CU_NAME}_cubin.h + COMMAND ${BIN2C} -c -n ${CU_NAME} ${CU_OBJ}.cubin.txt > ${LAMMPS_LIB_BINARY_DIR}/gpu/${CU_NAME}_cubin.h DEPENDS ${CU_OBJ} - COMMENT "Generating ${CU_HEADER}_cubin.h") - list(APPEND LIB_SOURCES ${LAMMPS_LIB_BINARY_DIR}/gpu/${CU_HEADER}_cubin.h) + COMMENT "Generating ${CU_NAME}_cubin.h") + list(APPEND LIB_SOURCES ${LAMMPS_LIB_BINARY_DIR}/gpu/${CU_NAME}_cubin.h) endforeach() - list(APPEND LAMMPS_LINK_LIBS lammps_gpu) - list(APPEND LIB_SOURCES ${GPU_SOURCES} ${GPU_LIB_SOURCES}) + list(APPEND LIB_SOURCES ${GPU_SOURCES} ${GPU_LIB_SOURCES} ${GPU_OBJS}) include_directories(${GPU_SOURCES_DIR} ${LAMMPS_LIB_SOURCE_DIR}/gpu ${LAMMPS_LIB_SOURCE_DIR}/gpu/cudpp_mini ${LAMMPS_LIB_BINARY_DIR}/gpu) - set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${AMMPS_LIB_BINARY_DIR}/gpu") + set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${AMMPS_LIB_BINARY_DIR}/gpu/*_cubin.h") endif() ###################################################### From acbc60319f6eb3ad15007ed568b876f1b8575785 Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Tue, 18 Jul 2017 18:43:51 -0600 Subject: [PATCH 316/439] GPU: clean up part 2 --- cmake/CMakeLists.txt | 5 ++--- {lib => cmake}/gpu/lal_pppm_d.cu | 2 -- {lib => cmake}/gpu/lal_pppm_f.cu | 2 -- 3 files changed, 2 insertions(+), 7 deletions(-) rename {lib => cmake}/gpu/lal_pppm_d.cu (74%) rename {lib => cmake}/gpu/lal_pppm_f.cu (73%) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index c5c8326080..99208ff65b 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -427,11 +427,10 @@ if(ENABLE_GPU) endif() include_directories(${CUDA_TOOLKIT_INCLUDE}) set(CUDA_BUILD_CUBIN ON) - set(CUDA_GENERATED_OUTPUT_DIR ${LAMMPS_LIB_BINARY_DIR}/gpu) set(GPU_PREC "SINGLE_DOUBLE" CACHE STRING "Lammps gpu precision size") set_property(CACHE GPU_PREC PROPERTY STRINGS SINGLE_DOUBLE SINGLE_SINGLE DOUBLE_DOUBLE) add_definitions(-D_${GPU_PREC}) - add_definitions(-DNV_KERNEL -DUSE_CUDPP -DUCL_CUDADR -DCMAKE_GPU) + add_definitions(-DNV_KERNEL -DUSE_CUDPP -DUCL_CUDADR) set(GPU_SOURCES_DIR ${LAMMPS_SOURCE_DIR}/GPU) set(GPU_SOURCES ${GPU_SOURCES_DIR}/gpu_extra.h) @@ -444,7 +443,7 @@ if(ENABLE_GPU) get_property(GPU_SOURCES GLOBAL PROPERTY GPU_SOURCES) file(GLOB_RECURSE GPU_LIB_SOURCES ${LAMMPS_LIB_SOURCE_DIR}/gpu/*.cpp) - file(GLOB_RECURSE GPU_LIB_CU ${LAMMPS_LIB_SOURCE_DIR}/gpu/*.cu) + file(GLOB_RECURSE GPU_LIB_CU ${LAMMPS_LIB_SOURCE_DIR}/gpu/*.cu ${CMAKE_SOURCE_DIR}/gpu/*.cu) file(GLOB_RECURSE GPU_NOT_LIB_CU ${LAMMPS_LIB_SOURCE_DIR}/gpu/lal_pppm.cu) list(REMOVE_ITEM GPU_LIB_CU ${GPU_NOT_LIB_CU}) add_custom_target(gpu_objs) diff --git a/lib/gpu/lal_pppm_d.cu b/cmake/gpu/lal_pppm_d.cu similarity index 74% rename from lib/gpu/lal_pppm_d.cu rename to cmake/gpu/lal_pppm_d.cu index e00ad50496..a49a535013 100644 --- a/lib/gpu/lal_pppm_d.cu +++ b/cmake/gpu/lal_pppm_d.cu @@ -1,6 +1,4 @@ -#ifdef CMAKE_GPU #define grdtyp double #define grdtyp4 double4 -#endif #include "lal_pppm.cu" diff --git a/lib/gpu/lal_pppm_f.cu b/cmake/gpu/lal_pppm_f.cu similarity index 73% rename from lib/gpu/lal_pppm_f.cu rename to cmake/gpu/lal_pppm_f.cu index 8c8ca88167..e7f5116fa0 100644 --- a/lib/gpu/lal_pppm_f.cu +++ b/cmake/gpu/lal_pppm_f.cu @@ -1,6 +1,4 @@ -#ifdef CMAKE_GPU #define grdtyp float #define grdtyp4 float4 -#endif #include "lal_pppm.cu" From e2ad4fa74579c8432bb0a286385f329421c7bb2a Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Tue, 18 Jul 2017 19:29:40 -0600 Subject: [PATCH 317/439] GPU: cubin not needed --- cmake/CMakeLists.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 99208ff65b..5764700ebd 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -426,7 +426,6 @@ if(ENABLE_GPU) message(FATAL_ERROR "Couldn't find bin2c") endif() include_directories(${CUDA_TOOLKIT_INCLUDE}) - set(CUDA_BUILD_CUBIN ON) set(GPU_PREC "SINGLE_DOUBLE" CACHE STRING "Lammps gpu precision size") set_property(CACHE GPU_PREC PROPERTY STRINGS SINGLE_DOUBLE SINGLE_SINGLE DOUBLE_DOUBLE) add_definitions(-D_${GPU_PREC}) @@ -453,7 +452,7 @@ if(ENABLE_GPU) get_filename_component(CU_NAME ${CU_OBJ} NAME_WE) string(REGEX REPLACE "^.*_lal_" "" CU_NAME "${CU_NAME}") add_custom_command(OUTPUT ${LAMMPS_LIB_BINARY_DIR}/gpu/${CU_NAME}_cubin.h - COMMAND ${BIN2C} -c -n ${CU_NAME} ${CU_OBJ}.cubin.txt > ${LAMMPS_LIB_BINARY_DIR}/gpu/${CU_NAME}_cubin.h + COMMAND ${BIN2C} -c -n ${CU_NAME} ${CU_OBJ} > ${LAMMPS_LIB_BINARY_DIR}/gpu/${CU_NAME}_cubin.h DEPENDS ${CU_OBJ} COMMENT "Generating ${CU_NAME}_cubin.h") list(APPEND LIB_SOURCES ${LAMMPS_LIB_BINARY_DIR}/gpu/${CU_NAME}_cubin.h) From 2961ba7ebb0d27accaf9b33957597e592bb56f9e Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Wed, 19 Jul 2017 10:35:48 -0600 Subject: [PATCH 318/439] added MKL support --- cmake/CMakeLists.txt | 9 ++++++++- cmake/Modules/FindMKL.cmake | 22 ++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 cmake/Modules/FindMKL.cmake diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 5764700ebd..9d8b93e12d 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -117,14 +117,21 @@ endif() if(ENABLE_KSPACE) find_package(FFTW3) + find_package(MKL) if(FFTW3_FOUND) add_definitions(-DFFT_FFTW3) include_directories(${FFTW3_INCLUDE_DIRS}) list(APPEND LAMMPS_LINK_LIBS ${FFTW3_LIBRARIES}) + elseif(MKL_FOUND) + add_definitions(-DFFT_MKL) + include_directories(${MKL_INCLUDE_DIRS}) + list(APPEND LAMMPS_LINK_LIBS ${MKL_LIBRARIES}) endif() set(PACK_OPTIMIZATION "PACK_ARRAY" CACHE STRING "Optimization for FFT") set_property(CACHE LAMMPS_SIZE_LIMIT PROPERTY STRINGS PACK_ARRAY PACK_POINTER PACK_MEMCPY) - add_definitions(-D${PACK_OPTIMIZATION}) + if(NOT PACK_OPTIMIZATION STREQUAL "PACK_ARRAY") + add_definitions(-D${PACK_OPTIMIZATION}) + endif() endif() if(ENABLE_MISC) diff --git a/cmake/Modules/FindMKL.cmake b/cmake/Modules/FindMKL.cmake new file mode 100644 index 0000000000..4246062103 --- /dev/null +++ b/cmake/Modules/FindMKL.cmake @@ -0,0 +1,22 @@ +# - Find mkl +# Find the native MKL headers and libraries. +# +# MKL_INCLUDE_DIRS - where to find mkl.h, etc. +# MKL_LIBRARIES - List of libraries when using mkl. +# MKL_FOUND - True if mkl found. +# + +find_path(MKL_INCLUDE_DIR mkl_dfti.h HINTS $ENV{MKLROOT}/include) + +find_library(MKL_LIBRARY NAMES mkl_rt HINTS $ENV{MKLROOT}/lib $ENV{MKLROOT}/lib/intel64) + +set(MKL_LIBRARIES ${MKL_LIBRARY}) +set(MKL_INCLUDE_DIRS ${MKL_INCLUDE_DIR}) + +include(FindPackageHandleStandardArgs) +# handle the QUIETLY and REQUIRED arguments and set MKL_FOUND to TRUE +# if all listed variables are TRUE + +find_package_handle_standard_args(MKL DEFAULT_MSG MKL_LIBRARY MKL_INCLUDE_DIR) + +mark_as_advanced(MKL_INCLUDE_DIR MKL_LIBRARY ) From c95db97b83c3e7d6aa72ef2298d901903b3ce562 Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Wed, 19 Jul 2017 15:15:24 -0600 Subject: [PATCH 319/439] fix PYTHON install --- cmake/CMakeLists.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 9d8b93e12d..7b9d9f14f9 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -168,10 +168,18 @@ if(ENABLE_MSCG OR ENABLE_USER-ATC OR ENABLE_USER-AWPMD OR ENABLE_USER-QUIP) endif() if(ENABLE_PYTHON) + find_package(PythonInterp REQUIRED) find_package(PythonLibs REQUIRED) add_definitions(-DLMP_PYTHON) include_directories(${PYTHON_INCLUDE_DIR}) list(APPEND LAMMPS_LINK_LIBS ${PYTHON_LIBRARY}) + execute_process(COMMAND ${PYTHON_EXECUTABLE} + -c "import distutils.sysconfig as cg; print(cg.get_python_lib(1,0,prefix='${CMAKE_INSTALL_PREFIX}'))" + OUTPUT_VARIABLE PYTHON_INSTDIR OUTPUT_STRIP_TRAILING_WHITESPACE) + install(FILES ${CMAKE_SOURCE_DIR}/../python/lammps.py DESTINATION ${PYTHON_INSTDIR}) + if(NOT BUILD_SHARED_LIBS) + message(FATAL_ERROR "Python package need lammps to be build shared, -DBUILD_SHARED_LIBS=ON") + endif() endif() find_package(JPEG) From a99e3ef4f0e839cd7b6f21f5d1df6b55344e5849 Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Wed, 19 Jul 2017 15:15:49 -0600 Subject: [PATCH 320/439] cmake: fix typo and pkg info --- cmake/CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 7b9d9f14f9..af2740eba1 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -497,8 +497,8 @@ set_target_properties(lammps PROPERTIES SOVERSION ${SOVERSION}) if(INSTALL_LIB) install(TARGETS lammps LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) install(FILES ${LAMMPS_SOURCE_DIR}/lammps.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) -elseif(NOT BUILD_SHARED_LIBS) - message(FATAL_ERROR "Shared library has to install, use -DBUILD_SHARED_LIBS=OFF to install lammps with a a library") +elseif(BUILD_SHARED_LIBS) + message(FATAL_ERROR "Shared library has to be installed, use -DBUILD_SHARED_LIBS=ON to install lammps with a library") endif() add_executable(lmp ${LMP_SOURCES}) @@ -506,7 +506,7 @@ target_link_libraries(lmp lammps) install(TARGETS lmp DESTINATION ${CMAKE_INSTALL_BINDIR}) -foreach(PKG ${PACKAGES} ${ACCEL_PACKAGES}) +foreach(PKG ${PACKAGES} ${USER-PACKAGES} ${ACCEL_PACKAGES}) if(ENABLE_${PKG}) message(STATUS "Building package: ${PKG}") endif() From babba1870efe58f9dbdf3118d44fc51557669965 Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Wed, 19 Jul 2017 15:33:02 -0600 Subject: [PATCH 321/439] added FFTW2 support --- cmake/CMakeLists.txt | 20 +++++++++----------- cmake/Modules/FindFFTW2.cmake | 22 ++++++++++++++++++++++ 2 files changed, 31 insertions(+), 11 deletions(-) create mode 100644 cmake/Modules/FindFFTW2.cmake diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index af2740eba1..7b6b2112da 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -116,17 +116,15 @@ if(ENABLE_USER-OMP OR ENABLE_KOKKOS OR ENABLE_USER-INTEL) endif() if(ENABLE_KSPACE) - find_package(FFTW3) - find_package(MKL) - if(FFTW3_FOUND) - add_definitions(-DFFT_FFTW3) - include_directories(${FFTW3_INCLUDE_DIRS}) - list(APPEND LAMMPS_LINK_LIBS ${FFTW3_LIBRARIES}) - elseif(MKL_FOUND) - add_definitions(-DFFT_MKL) - include_directories(${MKL_INCLUDE_DIRS}) - list(APPEND LAMMPS_LINK_LIBS ${MKL_LIBRARIES}) - endif() + foreach(FFT FFTW3 MKL FFTW2) + find_package(${FFT}) + if(${FFT}_FOUND) + add_definitions(-DFFT_${FFT}) + include_directories(${${FFT}_INCLUDE_DIRS}) + list(APPEND LAMMPS_LINK_LIBS ${${FFT}_LIBRARIES}) + break() + endif() + endforeach() set(PACK_OPTIMIZATION "PACK_ARRAY" CACHE STRING "Optimization for FFT") set_property(CACHE LAMMPS_SIZE_LIMIT PROPERTY STRINGS PACK_ARRAY PACK_POINTER PACK_MEMCPY) if(NOT PACK_OPTIMIZATION STREQUAL "PACK_ARRAY") diff --git a/cmake/Modules/FindFFTW2.cmake b/cmake/Modules/FindFFTW2.cmake new file mode 100644 index 0000000000..c77e6cf8e9 --- /dev/null +++ b/cmake/Modules/FindFFTW2.cmake @@ -0,0 +1,22 @@ +# - Find fftw2 +# Find the native FFTW2 headers and libraries. +# +# FFTW2_INCLUDE_DIRS - where to find fftw2.h, etc. +# FFTW2_LIBRARIES - List of libraries when using fftw2. +# FFTW2_FOUND - True if fftw2 found. +# + +find_path(FFTW2_INCLUDE_DIR fftw.h) + +find_library(FFTW2_LIBRARY NAMES fftw) + +set(FFTW2_LIBRARIES ${FFTW2_LIBRARY}) +set(FFTW2_INCLUDE_DIRS ${FFTW2_INCLUDE_DIR}) + +include(FindPackageHandleStandardArgs) +# handle the QUIETLY and REQUIRED arguments and set FFTW2_FOUND to TRUE +# if all listed variables are TRUE + +find_package_handle_standard_args(FFTW2 DEFAULT_MSG FFTW2_LIBRARY FFTW2_INCLUDE_DIR) + +mark_as_advanced(FFTW2_INCLUDE_DIR FFTW2_LIBRARY ) From 01bcb79bdc0c6043fc1c4f537884e5c8f5913463 Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Wed, 19 Jul 2017 18:34:07 -0600 Subject: [PATCH 322/439] cmake: clean up and updated comments --- cmake/CMakeLists.txt | 201 ++++++++++++++++++++++--------------------- 1 file changed, 103 insertions(+), 98 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 7b6b2112da..262857de16 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -1,3 +1,7 @@ +######################################## +# CMake build system +# This file is part of LAMMPS +# Created by Christoph Junghans and Richard Berger cmake_minimum_required(VERSION 3.1) project(lammps) @@ -6,6 +10,7 @@ set(LAMMPS_SOURCE_DIR ${CMAKE_SOURCE_DIR}/../src) set(LAMMPS_LIB_SOURCE_DIR ${CMAKE_SOURCE_DIR}/../lib) set(LAMMPS_LIB_BINARY_DIR ${CMAKE_BINARY_DIR}/lib) +#To not conflict with old Makefile build system, we build everything here file(GLOB LIB_SOURCES ${LAMMPS_SOURCE_DIR}/*.cpp) file(GLOB LMP_SOURCES ${LAMMPS_SOURCE_DIR}/main.cpp) list(REMOVE_ITEM LIB_SOURCES ${LMP_SOURCES}) @@ -32,7 +37,6 @@ enable_language(CXX) # compiler tests # these need ot be done early (before further tests). ##################################################################### - include(CheckCCompilerFlag) ######################################################################## @@ -98,6 +102,9 @@ pkg_depends(USER-LB MPI) pkg_depends(USER-MISC MANYBODY) pkg_depends(USER-PHONON KSPACE) +###################################################### +# packages with special compiler needs or external libs +###################################################### if(ENABLE_REAX OR ENABLE_MEAM OR ENABLE_USER-QUIP OR ENABLE_USER-QMMM) enable_language(Fortran) endif() @@ -139,21 +146,6 @@ if(ENABLE_MISC) endif() endif() -if(ENABLE_KOKKOS) - set(LAMMPS_LIB_KOKKOS_SRC_DIR ${LAMMPS_LIB_SOURCE_DIR}/kokkos) - set(LAMMPS_LIB_KOKKOS_BIN_DIR ${LAMMPS_LIB_BINARY_DIR}/kokkos) - add_definitions(-DLMP_KOKKOS) - add_subdirectory(${LAMMPS_LIB_KOKKOS_SRC_DIR} ${LAMMPS_LIB_KOKKOS_BIN_DIR}) - - # TODO there probably is a better way - set(Kokkos_INCLUDE_DIRS ${LAMMPS_LIB_KOKKOS_SRC_DIR}/core/src - ${LAMMPS_LIB_KOKKOS_SRC_DIR}/containers/src - ${LAMMPS_LIB_KOKKOS_SRC_DIR}/algorithms/src - ${LAMMPS_LIB_KOKKOS_BIN_DIR}) - include_directories(${Kokkos_INCLUDE_DIRS}) - list(APPEND LAMMPS_LINK_LIBS kokkos) -endif() - if(ENABLE_MSCG OR ENABLE_USER-ATC OR ENABLE_USER-AWPMD OR ENABLE_USER-QUIP) find_package(LAPACK) if(LAPACK_FOUND) @@ -209,7 +201,6 @@ if(ENABLE_VORONOI) find_package(VORO REQUIRED) #some distros include_directories(${VORO_INCLUDE_DIRS}) list(APPEND LAMMPS_LINK_LIBS ${VORO_LIBRARIES}) - #TODO download and build voro++ endif() if(ENABLE_USER-MOLFILE) @@ -239,65 +230,6 @@ if(ENABLE_USER-QMMM) list(APPEND LAMMPS_LINK_LIBS ${QE_LIBRARIES} ${CMAKE_Fortran_IMPLICIT_LINK_LIBRARIES}) endif() -######################################################################## -# Basic system tests (standard libraries, headers, functions, types) # -######################################################################## -include(CheckIncludeFile) -foreach(HEADER math.h) - check_include_file(${HEADER} FOUND_${HEADER}) - if(NOT FOUND_${HEADER}) - message(FATAL_ERROR "Could not find needed header - ${HEADER}") - endif(NOT FOUND_${HEADER}) -endforeach(HEADER) - -set(MATH_LIBRARIES "m" CACHE STRING "math library") -mark_as_advanced( MATH_LIBRARIES ) -include(CheckLibraryExists) -foreach(FUNC sin cos) - check_library_exists(${MATH_LIBRARIES} ${FUNC} "" FOUND_${FUNC}_${MATH_LIBRARIES}) - if(NOT FOUND_${FUNC}_${MATH_LIBRARIES}) - message(FATAL_ERROR "Could not find needed math function - ${FUNC}") - endif(NOT FOUND_${FUNC}_${MATH_LIBRARIES}) -endforeach(FUNC) -list(APPEND LAMMPS_LINK_LIBS ${MATH_LIBRARIES}) - -###################################### -# Include the following subdirectory # -###################################### - -#Do NOT go into src to not conflict with old Makefile build system -#add_subdirectory(src) - -include(StyleHeaderUtils) -RegisterStyles(${LAMMPS_SOURCE_DIR}) - -# packages which include entire content when enabled - -foreach(PKG ${PACKAGES} ${USER-PACKAGES}) - if(ENABLE_${PKG}) - set(${PKG}_SOURCES_DIR ${LAMMPS_SOURCE_DIR}/${PKG}) - - # detects styles in package and adds them to global list - RegisterStyles(${${PKG}_SOURCES_DIR}) - - file(GLOB ${PKG}_SOURCES ${${PKG}_SOURCES_DIR}/*.cpp) - list(APPEND LIB_SOURCES ${${PKG}_SOURCES}) - include_directories(${${PKG}_SOURCES_DIR}) - endif() -endforeach() - -foreach(SIMPLE_LIB REAX MEAM POEMS USER-ATC USER-AWPMD USER-COLVARS USER-H5MD - USER-MOLFILE USER-QMMM) - if(ENABLE_${SIMPLE_LIB}) - string(REGEX REPLACE "^USER-" "" SIMPLE_LIB "${SIMPLE_LIB}") - string(TOLOWER "${SIMPLE_LIB}" INC_DIR) - file(GLOB_RECURSE ${SIMPLE_LIB}_SOURCES ${LAMMPS_LIB_SOURCE_DIR}/${INC_DIR}/*.F - ${LAMMPS_LIB_SOURCE_DIR}/${INC_DIR}/*.c ${LAMMPS_LIB_SOURCE_DIR}/${INC_DIR}/*.cpp) - list(APPEND LIB_SOURCES ${${SIMPLE_LIB}_SOURCES}) - include_directories(${LAMMPS_LIB_SOURCE_DIR}/${INC_DIR}) - endif() -endforeach() - if(ENABLE_USER-AWPMD) include_directories(${LAMMPS_LIB_SOURCE_DIR}/awpmd/systems/interact ${LAMMPS_LIB_SOURCE_DIR}/awpmd/ivutils/include) @@ -348,11 +280,69 @@ if(ENABLE_MSCG) list(APPEND LAMMPS_LINK_LIBS ${GSL_LIBRARIES}) endif() +######################################################################## +# Basic system tests (standard libraries, headers, functions, types) # +######################################################################## +include(CheckIncludeFile) +foreach(HEADER math.h) + check_include_file(${HEADER} FOUND_${HEADER}) + if(NOT FOUND_${HEADER}) + message(FATAL_ERROR "Could not find needed header - ${HEADER}") + endif(NOT FOUND_${HEADER}) +endforeach(HEADER) + +set(MATH_LIBRARIES "m" CACHE STRING "math library") +mark_as_advanced( MATH_LIBRARIES ) +include(CheckLibraryExists) +foreach(FUNC sin cos) + check_library_exists(${MATH_LIBRARIES} ${FUNC} "" FOUND_${FUNC}_${MATH_LIBRARIES}) + if(NOT FOUND_${FUNC}_${MATH_LIBRARIES}) + message(FATAL_ERROR "Could not find needed math function - ${FUNC}") + endif(NOT FOUND_${FUNC}_${MATH_LIBRARIES}) +endforeach(FUNC) +list(APPEND LAMMPS_LINK_LIBS ${MATH_LIBRARIES}) + +###################################### +# Generate Basic Style files +###################################### +include(StyleHeaderUtils) +RegisterStyles(${LAMMPS_SOURCE_DIR}) + +############################################## +# add sources of enabled packages +############################################ +foreach(PKG ${PACKAGES} ${USER-PACKAGES}) + if(ENABLE_${PKG}) + set(${PKG}_SOURCES_DIR ${LAMMPS_SOURCE_DIR}/${PKG}) + + # detects styles in package and adds them to global list + RegisterStyles(${${PKG}_SOURCES_DIR}) + + file(GLOB ${PKG}_SOURCES ${${PKG}_SOURCES_DIR}/*.cpp) + list(APPEND LIB_SOURCES ${${PKG}_SOURCES}) + include_directories(${${PKG}_SOURCES_DIR}) + endif() +endforeach() + +############################################## +# add lib sources of (simple) enabled packages +############################################ +foreach(SIMPLE_LIB REAX MEAM POEMS USER-ATC USER-AWPMD USER-COLVARS USER-H5MD + USER-MOLFILE USER-QMMM) + if(ENABLE_${SIMPLE_LIB}) + string(REGEX REPLACE "^USER-" "" SIMPLE_LIB "${SIMPLE_LIB}") + string(TOLOWER "${SIMPLE_LIB}" INC_DIR) + file(GLOB_RECURSE ${SIMPLE_LIB}_SOURCES ${LAMMPS_LIB_SOURCE_DIR}/${INC_DIR}/*.F + ${LAMMPS_LIB_SOURCE_DIR}/${INC_DIR}/*.c ${LAMMPS_LIB_SOURCE_DIR}/${INC_DIR}/*.cpp) + list(APPEND LIB_SOURCES ${${SIMPLE_LIB}_SOURCES}) + include_directories(${LAMMPS_LIB_SOURCE_DIR}/${INC_DIR}) + endif() +endforeach() + ###################################################################### # packages which selectively include variants based on enabled styles # e.g. accelerator packages ###################################################################### - if(ENABLE_USER-OMP) set(USER-OMP_SOURCES_DIR ${LAMMPS_SOURCE_DIR}/USER-OMP) set(USER-OMP_SOURCES ${USER-OMP_SOURCES_DIR}/thr_data.cpp @@ -371,27 +361,39 @@ if(ENABLE_USER-OMP) endif() if(ENABLE_KOKKOS) - set(KOKKOS_PKG_SOURCES_DIR ${LAMMPS_SOURCE_DIR}/KOKKOS) - set(KOKKOS_PKG_SOURCES ${KOKKOS_PKG_SOURCES_DIR}/kokkos.cpp - ${KOKKOS_PKG_SOURCES_DIR}/atom_kokkos.cpp - ${KOKKOS_PKG_SOURCES_DIR}/atom_vec_kokkos.cpp - ${KOKKOS_PKG_SOURCES_DIR}/comm_kokkos.cpp - ${KOKKOS_PKG_SOURCES_DIR}/comm_tiled_kokkos.cpp - ${KOKKOS_PKG_SOURCES_DIR}/neighbor_kokkos.cpp - ${KOKKOS_PKG_SOURCES_DIR}/neigh_list_kokkos.cpp - ${KOKKOS_PKG_SOURCES_DIR}/neigh_bond_kokkos.cpp - ${KOKKOS_PKG_SOURCES_DIR}/fix_nh_kokkos.cpp - ${KOKKOS_PKG_SOURCES_DIR}/domain_kokkos.cpp - ${KOKKOS_PKG_SOURCES_DIR}/modify_kokkos.cpp) - set_property(GLOBAL PROPERTY "KOKKOS_PKG_SOURCES" "${KOKKOS_PKG_SOURCES}") + set(LAMMPS_LIB_KOKKOS_SRC_DIR ${LAMMPS_LIB_SOURCE_DIR}/kokkos) + set(LAMMPS_LIB_KOKKOS_BIN_DIR ${LAMMPS_LIB_BINARY_DIR}/kokkos) + add_definitions(-DLMP_KOKKOS) + add_subdirectory(${LAMMPS_LIB_KOKKOS_SRC_DIR} ${LAMMPS_LIB_KOKKOS_BIN_DIR}) - # detects styles which have KOKKOS version - RegisterStylesExt(${KOKKOS_PKG_SOURCES_DIR} kokkos KOKKOS_PKG_SOURCES) + set(Kokkos_INCLUDE_DIRS ${LAMMPS_LIB_KOKKOS_SRC_DIR}/core/src + ${LAMMPS_LIB_KOKKOS_SRC_DIR}/containers/src + ${LAMMPS_LIB_KOKKOS_SRC_DIR}/algorithms/src + ${LAMMPS_LIB_KOKKOS_BIN_DIR}) + include_directories(${Kokkos_INCLUDE_DIRS}) + list(APPEND LAMMPS_LINK_LIBS kokkos) - get_property(KOKKOS_PKG_SOURCES GLOBAL PROPERTY KOKKOS_PKG_SOURCES) + set(KOKKOS_PKG_SOURCES_DIR ${LAMMPS_SOURCE_DIR}/KOKKOS) + set(KOKKOS_PKG_SOURCES ${KOKKOS_PKG_SOURCES_DIR}/kokkos.cpp + ${KOKKOS_PKG_SOURCES_DIR}/atom_kokkos.cpp + ${KOKKOS_PKG_SOURCES_DIR}/atom_vec_kokkos.cpp + ${KOKKOS_PKG_SOURCES_DIR}/comm_kokkos.cpp + ${KOKKOS_PKG_SOURCES_DIR}/comm_tiled_kokkos.cpp + ${KOKKOS_PKG_SOURCES_DIR}/neighbor_kokkos.cpp + ${KOKKOS_PKG_SOURCES_DIR}/neigh_list_kokkos.cpp + ${KOKKOS_PKG_SOURCES_DIR}/neigh_bond_kokkos.cpp + ${KOKKOS_PKG_SOURCES_DIR}/fix_nh_kokkos.cpp + ${KOKKOS_PKG_SOURCES_DIR}/domain_kokkos.cpp + ${KOKKOS_PKG_SOURCES_DIR}/modify_kokkos.cpp) + set_property(GLOBAL PROPERTY "KOKKOS_PKG_SOURCES" "${KOKKOS_PKG_SOURCES}") - list(APPEND LIB_SOURCES ${KOKKOS_PKG_SOURCES}) - include_directories(${KOKKOS_PKG_SOURCES_DIR}) + # detects styles which have KOKKOS version + RegisterStylesExt(${KOKKOS_PKG_SOURCES_DIR} kokkos KOKKOS_PKG_SOURCES) + + get_property(KOKKOS_PKG_SOURCES GLOBAL PROPERTY KOKKOS_PKG_SOURCES) + + list(APPEND LIB_SOURCES ${KOKKOS_PKG_SOURCES}) + include_directories(${KOKKOS_PKG_SOURCES_DIR}) endif() if(ENABLE_OPT) @@ -487,11 +489,12 @@ GenerateStyleHeaders(${LAMMPS_STYLE_HEADERS_DIR}) include_directories(${LAMMPS_SOURCE_DIR}) include_directories(${LAMMPS_STYLE_HEADERS_DIR}) - +########################################### +# Actually add executable and lib to build +############################################ add_library(lammps ${LIB_SOURCES}) target_link_libraries(lammps ${LAMMPS_LINK_LIBS}) set_target_properties(lammps PROPERTIES SOVERSION ${SOVERSION}) - if(INSTALL_LIB) install(TARGETS lammps LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) install(FILES ${LAMMPS_SOURCE_DIR}/lammps.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) @@ -501,9 +504,11 @@ endif() add_executable(lmp ${LMP_SOURCES}) target_link_libraries(lmp lammps) - install(TARGETS lmp DESTINATION ${CMAKE_INSTALL_BINDIR}) +################################## +# Print package summary +################################## foreach(PKG ${PACKAGES} ${USER-PACKAGES} ${ACCEL_PACKAGES}) if(ENABLE_${PKG}) message(STATUS "Building package: ${PKG}") From 488609a5fdfabbf97e206277b81aa15660671f0b Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Wed, 19 Jul 2017 18:54:15 -0600 Subject: [PATCH 323/439] make FFT a selective option --- cmake/CMakeLists.txt | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 262857de16..e8afb6fb56 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -123,15 +123,14 @@ if(ENABLE_USER-OMP OR ENABLE_KOKKOS OR ENABLE_USER-INTEL) endif() if(ENABLE_KSPACE) - foreach(FFT FFTW3 MKL FFTW2) - find_package(${FFT}) - if(${FFT}_FOUND) - add_definitions(-DFFT_${FFT}) - include_directories(${${FFT}_INCLUDE_DIRS}) - list(APPEND LAMMPS_LINK_LIBS ${${FFT}_LIBRARIES}) - break() - endif() - endforeach() + set(FFT "KISSFFT" CACHE STRING "FFT library for KSPACE package") + set_property(CACHE FFT PROPERTY STRINGS KISSFFT FFTW3 MKL FFTW2) + if(NOT FFT STREQUAL "KISSFFT") + find_package(${FFT} REQUIRED) + add_definitions(-DFFT_${FFT}) + include_directories(${${FFT}_INCLUDE_DIRS}) + list(APPEND LAMMPS_LINK_LIBS ${${FFT}_LIBRARIES}) + endif() set(PACK_OPTIMIZATION "PACK_ARRAY" CACHE STRING "Optimization for FFT") set_property(CACHE LAMMPS_SIZE_LIMIT PROPERTY STRINGS PACK_ARRAY PACK_POINTER PACK_MEMCPY) if(NOT PACK_OPTIMIZATION STREQUAL "PACK_ARRAY") From f037f89f5f4de24f760b608778bb232c8312dc66 Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Thu, 20 Jul 2017 14:12:17 -0600 Subject: [PATCH 324/439] fix GPU + BUILD_SHARED_LIBS X-Thanks: Robert Maynard --- cmake/CMakeLists.txt | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index e8afb6fb56..bbf6048460 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -439,11 +439,12 @@ if(ENABLE_GPU) if(NOT BIN2C) message(FATAL_ERROR "Couldn't find bin2c") endif() - include_directories(${CUDA_TOOLKIT_INCLUDE}) + include_directories(${CUDA_INCLUDE_DIRS}) + list(APPEND LAMMPS_LINK_LIBS ${CUDA_LIBRARIES} ${CUDA_CUDA_LIBRARY}) set(GPU_PREC "SINGLE_DOUBLE" CACHE STRING "Lammps gpu precision size") set_property(CACHE GPU_PREC PROPERTY STRINGS SINGLE_DOUBLE SINGLE_SINGLE DOUBLE_DOUBLE) add_definitions(-D_${GPU_PREC}) - add_definitions(-DNV_KERNEL -DUSE_CUDPP -DUCL_CUDADR) + add_definitions(-DNV_KERNEL -DUCL_CUDADR) set(GPU_SOURCES_DIR ${LAMMPS_SOURCE_DIR}/GPU) set(GPU_SOURCES ${GPU_SOURCES_DIR}/gpu_extra.h) @@ -455,12 +456,13 @@ if(ENABLE_GPU) get_property(GPU_SOURCES GLOBAL PROPERTY GPU_SOURCES) - file(GLOB_RECURSE GPU_LIB_SOURCES ${LAMMPS_LIB_SOURCE_DIR}/gpu/*.cpp) - file(GLOB_RECURSE GPU_LIB_CU ${LAMMPS_LIB_SOURCE_DIR}/gpu/*.cu ${CMAKE_SOURCE_DIR}/gpu/*.cu) + file(GLOB GPU_LIB_SOURCES ${LAMMPS_LIB_SOURCE_DIR}/gpu/*.cpp) + file(GLOB GPU_LIB_CU ${LAMMPS_LIB_SOURCE_DIR}/gpu/*.cu ${CMAKE_SOURCE_DIR}/gpu/*.cu) file(GLOB_RECURSE GPU_NOT_LIB_CU ${LAMMPS_LIB_SOURCE_DIR}/gpu/lal_pppm.cu) list(REMOVE_ITEM GPU_LIB_CU ${GPU_NOT_LIB_CU}) - add_custom_target(gpu_objs) - cuda_wrap_srcs(gpu_objs OBJ GPU_OBJS ${GPU_LIB_CU}) + include_directories(${GPU_SOURCES_DIR} ${LAMMPS_LIB_SOURCE_DIR}/gpu + ${LAMMPS_LIB_SOURCE_DIR}/gpu/cudpp_mini ${LAMMPS_LIB_BINARY_DIR}/gpu) + cuda_compile(GPU_OBJS ${GPU_LIB_CU} OPTIONS $<$:-Xcompiler=-fPIC>) file(MAKE_DIRECTORY ${LAMMPS_LIB_BINARY_DIR}/gpu) foreach(CU_OBJ ${GPU_OBJS}) get_filename_component(CU_NAME ${CU_OBJ} NAME_WE) @@ -470,10 +472,12 @@ if(ENABLE_GPU) DEPENDS ${CU_OBJ} COMMENT "Generating ${CU_NAME}_cubin.h") list(APPEND LIB_SOURCES ${LAMMPS_LIB_BINARY_DIR}/gpu/${CU_NAME}_cubin.h) + if(${CU_NAME} STREQUAL "pppm_d") #pppm_d doesn't get linked into the lib + set(CU_FORBIDDEN_OBJ "${CU_OBJ}") + endif() endforeach() + list(REMOVE_ITEM GPU_OBJS "${CU_FORBIDDEN_OBJ}") list(APPEND LIB_SOURCES ${GPU_SOURCES} ${GPU_LIB_SOURCES} ${GPU_OBJS}) - include_directories(${GPU_SOURCES_DIR} ${LAMMPS_LIB_SOURCE_DIR}/gpu - ${LAMMPS_LIB_SOURCE_DIR}/gpu/cudpp_mini ${LAMMPS_LIB_BINARY_DIR}/gpu) set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${AMMPS_LIB_BINARY_DIR}/gpu/*_cubin.h") endif() From 1749d643c7205ec05655818d2d5b2295bd37b171 Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Thu, 20 Jul 2017 14:30:52 -0600 Subject: [PATCH 325/439] GPU: bring back CUDPP_OPT --- cmake/CMakeLists.txt | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index bbf6048460..4304a8078f 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -445,6 +445,7 @@ if(ENABLE_GPU) set_property(CACHE GPU_PREC PROPERTY STRINGS SINGLE_DOUBLE SINGLE_SINGLE DOUBLE_DOUBLE) add_definitions(-D_${GPU_PREC}) add_definitions(-DNV_KERNEL -DUCL_CUDADR) + option(CUDPP_OPT "Enable CUDPP_OPT" ON) set(GPU_SOURCES_DIR ${LAMMPS_SOURCE_DIR}/GPU) set(GPU_SOURCES ${GPU_SOURCES_DIR}/gpu_extra.h) @@ -460,9 +461,14 @@ if(ENABLE_GPU) file(GLOB GPU_LIB_CU ${LAMMPS_LIB_SOURCE_DIR}/gpu/*.cu ${CMAKE_SOURCE_DIR}/gpu/*.cu) file(GLOB_RECURSE GPU_NOT_LIB_CU ${LAMMPS_LIB_SOURCE_DIR}/gpu/lal_pppm.cu) list(REMOVE_ITEM GPU_LIB_CU ${GPU_NOT_LIB_CU}) - include_directories(${GPU_SOURCES_DIR} ${LAMMPS_LIB_SOURCE_DIR}/gpu - ${LAMMPS_LIB_SOURCE_DIR}/gpu/cudpp_mini ${LAMMPS_LIB_BINARY_DIR}/gpu) - cuda_compile(GPU_OBJS ${GPU_LIB_CU} OPTIONS $<$:-Xcompiler=-fPIC>) + include_directories(${GPU_SOURCES_DIR} ${LAMMPS_LIB_SOURCE_DIR}/gpu ${LAMMPS_LIB_BINARY_DIR}/gpu) + if(CUDPP_OPT) + include_directories(${LAMMPS_LIB_SOURCE_DIR}/gpu/cudpp_mini) + add_definitions(-DCUDPP_OPT) + file(GLOB GPU_LIB_CUDPP_SOURCES ${LAMMPS_LIB_SOURCE_DIR}/gpu/cudpp_mini/*.cpp) + file(GLOB GPU_LIB_CUDPP_CU ${LAMMPS_LIB_SOURCE_DIR}/gpu/cudpp_mini/*.cu) + endif() + cuda_compile(GPU_OBJS ${GPU_LIB_CU} ${GPU_LIB_CUDPP_CU} OPTIONS $<$:-Xcompiler=-fPIC>) file(MAKE_DIRECTORY ${LAMMPS_LIB_BINARY_DIR}/gpu) foreach(CU_OBJ ${GPU_OBJS}) get_filename_component(CU_NAME ${CU_OBJ} NAME_WE) @@ -477,7 +483,7 @@ if(ENABLE_GPU) endif() endforeach() list(REMOVE_ITEM GPU_OBJS "${CU_FORBIDDEN_OBJ}") - list(APPEND LIB_SOURCES ${GPU_SOURCES} ${GPU_LIB_SOURCES} ${GPU_OBJS}) + list(APPEND LIB_SOURCES ${GPU_SOURCES} ${GPU_LIB_SOURCES} ${GPU_LIB_CUDPP_SOURCES} ${GPU_OBJS}) set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${AMMPS_LIB_BINARY_DIR}/gpu/*_cubin.h") endif() From 427ca88dd44dc7638de9f9131e120c85a298942e Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Thu, 20 Jul 2017 15:02:41 -0600 Subject: [PATCH 326/439] cmake: error for POEMS + BODY package --- cmake/CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 4304a8078f..8f375e91bb 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -102,6 +102,10 @@ pkg_depends(USER-LB MPI) pkg_depends(USER-MISC MANYBODY) pkg_depends(USER-PHONON KSPACE) +if(ENABLE_BODY AND ENABLE_POEMS) + message(FATAL_ERROR "BODY and POEMS cannot be enabled at the same time") +endif() + ###################################################### # packages with special compiler needs or external libs ###################################################### From c88d1e5510a1999d64604d97df406cf212f14d24 Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Thu, 20 Jul 2017 15:15:29 -0600 Subject: [PATCH 327/439] make ENABLE_ALL work out of the box --- cmake/CMakeLists.txt | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 8f375e91bb..c9e973e212 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -71,20 +71,21 @@ add_definitions(-DLAMMPS_MEMALIGN=${LAMMPS_MEMALIGN}) option(CMAKE_VERBOSE_MAKEFILE "Verbose makefile" OFF) -option(ENABLE_ALL "Build all packages" OFF) -set(PACKAGES ASPHERE BODY CLASS2 COLLOID COMPRESS CORESHELL DIPOLE GRANULAR - KIM KSPACE MANYBODY MC MEAM MISC MOLECULE MSCG MPIIO PERI POEMS PYTHON QEQ - REAX REPLICA RIGID SHOCK SNAP SRD VORONOI) -set(USER-PACKAGES USER-ATC USER-AWPMD USER-CGDNA +option(ENABLE_ALL "Build all default packages" OFF) +set(DEFAULT_PACKAGES ASPHERE BODY CLASS2 COLLOID COMPRESS CORESHELL DIPOLE GRANULAR + KSPACE MANYBODY MC MEAM MISC MOLECULE PERI QEQ + REAX REPLICA RIGID SHOCK SNAP SRD) +set(OTHER_PACKAGES KIM PYTHON MSCG MPIIO VORONOI POEMS + USER-ATC USER-AWPMD USER-CGDNA USER-CGSDK USER-COLVARS USER-DIFFRACTION USER-DPD USER-DRUDE USER-EFF USER-FEP USER-H5MD USER-LB USER-MANIFOLD USER-MEAMC USER-MGPT USER-MISC USER-MOLFILE USER-NETCDF USER-PHONON USER-QTB USER-REAXC USER-SMD USER-SMTBQ USER-SPH USER-TALLY USER-VTK USER-QUIP USER-QMMM) set(ACCEL_PACKAGES USER-OMP KOKKOS OPT USER-INTEL GPU) -foreach(PKG ${PACKAGES}) +foreach(PKG ${DEFAULT_PACKAGES}) option(ENABLE_${PKG} "Build ${PKG} Package" ${ENABLE_ALL}) endforeach() -foreach(PKG ${ACCEL_PACKAGES} ${USER-PACKAGES}) +foreach(PKG ${ACCEL_PACKAGES} ${OTHER_PACKAGES}) option(ENABLE_${PKG} "Build ${PKG} Package" OFF) endforeach() @@ -522,7 +523,7 @@ install(TARGETS lmp DESTINATION ${CMAKE_INSTALL_BINDIR}) ################################## # Print package summary ################################## -foreach(PKG ${PACKAGES} ${USER-PACKAGES} ${ACCEL_PACKAGES}) +foreach(PKG ${DEFAULT_PACKAGES} ${OTHER_PACKAGES} ${ACCEL_PACKAGES}) if(ENABLE_${PKG}) message(STATUS "Building package: ${PKG}") endif() From e8e9ea839207e9de447754c843db402b86969092 Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Thu, 20 Jul 2017 16:14:02 -0600 Subject: [PATCH 328/439] added one trivial test --- cmake/CMakeLists.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index c9e973e212..4a2a8773ec 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -71,6 +71,11 @@ add_definitions(-DLAMMPS_MEMALIGN=${LAMMPS_MEMALIGN}) option(CMAKE_VERBOSE_MAKEFILE "Verbose makefile" OFF) +option(ENABLE_TESTING "Enable testing" OFF) +if(ENABLE_TESTING) + enable_testing() +endif(ENABLE_TESTING) + option(ENABLE_ALL "Build all default packages" OFF) set(DEFAULT_PACKAGES ASPHERE BODY CLASS2 COLLOID COMPRESS CORESHELL DIPOLE GRANULAR KSPACE MANYBODY MC MEAM MISC MOLECULE PERI QEQ @@ -519,6 +524,9 @@ endif() add_executable(lmp ${LMP_SOURCES}) target_link_libraries(lmp lammps) install(TARGETS lmp DESTINATION ${CMAKE_INSTALL_BINDIR}) +if(ENABLE_TESTING) + add_test(ShowHelp lmp -help) +endif() ################################## # Print package summary From 3d1d0c58c7322aca3ab8019dfc176875868a9743 Mon Sep 17 00:00:00 2001 From: Trung Nguyen Date: Fri, 21 Jul 2017 12:08:04 -0500 Subject: [PATCH 329/439] Cleaned up 3-body gpu styles, and fixed a bug for tersoff/zbl/gpu. There is a unresolved bug for neigh no with tpa > 1 with BaseThree, enforce tpa = 1 for neigh no in BaseThree for now. --- lib/gpu/lal_base_three.cpp | 41 ++++++++++++++----------------------- lib/gpu/lal_base_three.h | 2 +- lib/gpu/lal_tersoff_mod.cu | 2 +- lib/gpu/lal_tersoff_zbl.cpp | 2 +- lib/gpu/lal_tersoff_zbl.cu | 2 +- 5 files changed, 19 insertions(+), 30 deletions(-) diff --git a/lib/gpu/lal_base_three.cpp b/lib/gpu/lal_base_three.cpp index 4e8a95937c..5f3c57337e 100644 --- a/lib/gpu/lal_base_three.cpp +++ b/lib/gpu/lal_base_three.cpp @@ -20,7 +20,7 @@ using namespace LAMMPS_AL; extern Device global_device; template -BaseThreeT::BaseThree() : _compiled(false), _max_bytes(0), _short_nbor(false) { +BaseThreeT::BaseThree() : _compiled(false), _max_bytes(0) { device=&global_device; ans=new Answer(); nbor=new Neighbor(); @@ -73,6 +73,7 @@ int BaseThreeT::init_three(const int nlocal, const int nall, if (_threads_per_atom>1 && gpu_nbor==0) { // neigh no and tpa > 1 nbor->packing(true); _nbor_data=&(nbor->dev_packed); + _threads_per_atom = 1; // enforce tpa = 1 for now } else // neigh yes or tpa == 1 _nbor_data=&(nbor->dev_nbor); if (_threads_per_atom*_threads_per_atom>device->warp_size()) @@ -113,14 +114,10 @@ int BaseThreeT::init_three(const int nlocal, const int nall, _max_an_bytes+=ans2->gpu_bytes(); #endif - // if short neighbor list is supported - if (short_nbor) { - _short_nbor = true; - int ef_nall=nall; - if (ef_nall==0) - ef_nall=2000; - dev_short_nbor.alloc(ef_nall*(2+max_nbors),*(this->ucl_device),UCL_READ_WRITE); - } + int ef_nall=nall; + if (ef_nall==0) + ef_nall=2000; + dev_short_nbor.alloc(ef_nall*(2+max_nbors),*(this->ucl_device),UCL_READ_WRITE); return 0; } @@ -269,14 +266,10 @@ void BaseThreeT::compute(const int f_ago, const int inum_full, const int nall, hd_balancer.start_timer(); atom->add_x_data(host_x,host_type); - // if short neighbor list is supported - if (_short_nbor) { - - // re-allocate dev_short_nbor if necessary - if (nall*(2+_max_nbors) > dev_short_nbor.cols()) { - int _nmax=static_cast(static_cast(nall)*1.10); - dev_short_nbor.resize((2+_max_nbors)*_nmax); - } + // re-allocate dev_short_nbor if necessary + if (nall*(2+_max_nbors) > dev_short_nbor.cols()) { + int _nmax=static_cast(static_cast(nall)*1.10); + dev_short_nbor.resize((2+_max_nbors)*_nmax); } // _ainum to be used in loop() for short neighbor list build @@ -342,14 +335,10 @@ int ** BaseThreeT::compute(const int ago, const int inum_full, *ilist=nbor->host_ilist.begin(); *jnum=nbor->host_acc.begin(); - // if short neighbor list is supported - if (_short_nbor) { - - // re-allocate dev_short_nbor if necessary - if (nall*(2+_max_nbors) > dev_short_nbor.cols()) { - int _nmax=static_cast(static_cast(nall)*1.10); - dev_short_nbor.resize((2+_max_nbors)*_nmax); - } + // re-allocate dev_short_nbor if necessary + if (nall*(2+_max_nbors) > dev_short_nbor.cols()) { + int _nmax=static_cast(static_cast(nall)*1.10); + dev_short_nbor.resize((2+_max_nbors)*_nmax); } // _ainum to be used in loop() for short neighbor list build @@ -394,7 +383,7 @@ void BaseThreeT::compile_kernels(UCL_Device &dev, const void *pair_str, k_three_end.set_function(*pair_program,three_end); k_three_end_vatom.set_function(*pair_program,vatom_name.c_str()); k_pair.set_function(*pair_program,two); - if (short_nbor) k_short_nbor.set_function(*pair_program,short_nbor); + k_short_nbor.set_function(*pair_program,short_nbor); pos_tex.get_texture(*pair_program,"pos_tex"); #ifdef THREE_CONCURRENT diff --git a/lib/gpu/lal_base_three.h b/lib/gpu/lal_base_three.h index fde1936b25..f5f36863c4 100644 --- a/lib/gpu/lal_base_three.h +++ b/lib/gpu/lal_base_three.h @@ -199,7 +199,7 @@ class BaseThree { UCL_Texture pos_tex; protected: - bool _compiled,_short_nbor; + bool _compiled; int _block_pair, _block_size, _threads_per_atom, _end_command_queue; int _gpu_nbor; double _max_bytes, _max_an_bytes; diff --git a/lib/gpu/lal_tersoff_mod.cu b/lib/gpu/lal_tersoff_mod.cu index 555485a1b2..257d3972ed 100644 --- a/lib/gpu/lal_tersoff_mod.cu +++ b/lib/gpu/lal_tersoff_mod.cu @@ -690,7 +690,7 @@ __kernel void k_tersoff_mod_three_end(const __global numtyp4 *restrict x_, const __global int * dev_nbor, const __global int * dev_packed, const __global int * dev_acc, - const __global int * dev_short_nbor, + const __global int * dev_short_nbor, __global acctyp4 *restrict ans, __global acctyp *restrict engv, const int eflag, const int vflag, diff --git a/lib/gpu/lal_tersoff_zbl.cpp b/lib/gpu/lal_tersoff_zbl.cpp index 827613067c..341f663030 100644 --- a/lib/gpu/lal_tersoff_zbl.cpp +++ b/lib/gpu/lal_tersoff_zbl.cpp @@ -293,7 +293,7 @@ void TersoffZT::loop(const bool _eflag, const bool _vflag, const int evatom) { (BX/(JTHREADS*KTHREADS)))); this->k_zeta.set_size(GX,BX); - this->k_zeta.run(&this->atom->x, &ts1, &ts2, &ts3, &ts4, &ts5, &cutsq, + this->k_zeta.run(&this->atom->x, &ts1, &ts2, &ts3, &ts4, &ts5, &ts6, &cutsq, &map, &elem2param, &_nelements, &_nparams, &_zetaij, &this->nbor->dev_nbor, &this->_nbor_data->begin(), &this->dev_short_nbor, diff --git a/lib/gpu/lal_tersoff_zbl.cu b/lib/gpu/lal_tersoff_zbl.cu index 89ae72df8a..89317b990c 100644 --- a/lib/gpu/lal_tersoff_zbl.cu +++ b/lib/gpu/lal_tersoff_zbl.cu @@ -702,7 +702,7 @@ __kernel void k_tersoff_zbl_three_end(const __global numtyp4 *restrict x_, const __global int * dev_nbor, const __global int * dev_packed, const __global int * dev_acc, - const __global int * dev_short_nbor, + const __global int * dev_short_nbor, __global acctyp4 *restrict ans, __global acctyp *restrict engv, const int eflag, const int vflag, From c010edc4fdc34ec1e4f527afbff1e6eb8d5f2293 Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Fri, 21 Jul 2017 11:38:02 -0600 Subject: [PATCH 330/439] cmake: fixed two typos --- cmake/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 4a2a8773ec..ebf452d183 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -142,7 +142,7 @@ if(ENABLE_KSPACE) list(APPEND LAMMPS_LINK_LIBS ${${FFT}_LIBRARIES}) endif() set(PACK_OPTIMIZATION "PACK_ARRAY" CACHE STRING "Optimization for FFT") - set_property(CACHE LAMMPS_SIZE_LIMIT PROPERTY STRINGS PACK_ARRAY PACK_POINTER PACK_MEMCPY) + set_property(CACHE PACK_OPTIMIZATION PROPERTY STRINGS PACK_ARRAY PACK_POINTER PACK_MEMCPY) if(NOT PACK_OPTIMIZATION STREQUAL "PACK_ARRAY") add_definitions(-D${PACK_OPTIMIZATION}) endif() @@ -320,7 +320,7 @@ RegisterStyles(${LAMMPS_SOURCE_DIR}) ############################################## # add sources of enabled packages ############################################ -foreach(PKG ${PACKAGES} ${USER-PACKAGES}) +foreach(PKG ${PACKAGES} ${OTHER-PACKAGES}) if(ENABLE_${PKG}) set(${PKG}_SOURCES_DIR ${LAMMPS_SOURCE_DIR}/${PKG}) From 74deeeca5855742fd2aa8274b4203c45be12086d Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Fri, 21 Jul 2017 11:50:13 -0600 Subject: [PATCH 331/439] cmake: fixed another typo --- cmake/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index ebf452d183..228a9e36e3 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -320,7 +320,7 @@ RegisterStyles(${LAMMPS_SOURCE_DIR}) ############################################## # add sources of enabled packages ############################################ -foreach(PKG ${PACKAGES} ${OTHER-PACKAGES}) +foreach(PKG ${PACKAGES} ${OTHER_PACKAGES}) if(ENABLE_${PKG}) set(${PKG}_SOURCES_DIR ${LAMMPS_SOURCE_DIR}/${PKG}) From 8ed881947ff91ef1e87f0fa8a7abb04f50a1dc78 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 21 Jul 2017 14:28:13 -0600 Subject: [PATCH 332/439] Fix execution space in manybody potentials --- src/KOKKOS/pair_sw_kokkos.cpp | 6 +++--- src/KOKKOS/pair_sw_kokkos.h | 12 ++++++------ src/KOKKOS/pair_tersoff_kokkos.cpp | 2 +- src/KOKKOS/pair_vashishta_kokkos.cpp | 6 +++--- src/KOKKOS/pair_vashishta_kokkos.h | 8 ++++---- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/KOKKOS/pair_sw_kokkos.cpp b/src/KOKKOS/pair_sw_kokkos.cpp index e5c947cc8e..3440f7c639 100644 --- a/src/KOKKOS/pair_sw_kokkos.cpp +++ b/src/KOKKOS/pair_sw_kokkos.cpp @@ -572,7 +572,7 @@ void PairSWKokkos::coeff(int narg, char **arg) k_map.template modify(); k_map.template sync(); - d_map = k_map.d_view; + d_map = k_map.template view(); } /* ---------------------------------------------------------------------- @@ -637,8 +637,8 @@ void PairSWKokkos::setup_params() k_params.template modify(); k_params.template sync(); - d_elem2param = k_elem2param.d_view; - d_params = k_params.d_view; + d_elem2param = k_elem2param.template view(); + d_params = k_params.template view(); } /* ---------------------------------------------------------------------- */ diff --git a/src/KOKKOS/pair_sw_kokkos.h b/src/KOKKOS/pair_sw_kokkos.h index b94e39335f..3152fb6e94 100644 --- a/src/KOKKOS/pair_sw_kokkos.h +++ b/src/KOKKOS/pair_sw_kokkos.h @@ -103,7 +103,7 @@ class PairSWKokkos : public PairSW { typedef typename tdual_int_3d::t_host t_host_int_3d; t_int_3d_randomread d_elem2param; - DAT::t_int_1d_randomread d_map; + typename AT::t_int_1d_randomread d_map; typedef Kokkos::DualView tdual_param_1d; typedef typename tdual_param_1d::t_dev t_param_1d; @@ -125,12 +125,12 @@ class PairSWKokkos : public PairSW { DAT::tdual_efloat_1d k_eatom; DAT::tdual_virial_array k_vatom; - typename ArrayTypes::t_efloat_1d d_eatom; - typename ArrayTypes::t_virial_array d_vatom; + typename AT::t_efloat_1d d_eatom; + typename AT::t_virial_array d_vatom; - DAT::t_int_1d_randomread d_type2frho; - DAT::t_int_2d_randomread d_type2rhor; - DAT::t_int_2d_randomread d_type2z2r; + typename AT::t_int_1d_randomread d_type2frho; + typename AT::t_int_2d_randomread d_type2rhor; + typename AT::t_int_2d_randomread d_type2z2r; typename AT::t_neighbors_2d d_neighbors; typename AT::t_int_1d_randomread d_ilist; diff --git a/src/KOKKOS/pair_tersoff_kokkos.cpp b/src/KOKKOS/pair_tersoff_kokkos.cpp index 833c815ad9..3a5c2227ef 100644 --- a/src/KOKKOS/pair_tersoff_kokkos.cpp +++ b/src/KOKKOS/pair_tersoff_kokkos.cpp @@ -76,7 +76,7 @@ void PairTersoffKokkos::allocate() k_params = Kokkos::DualView ("PairTersoff::paramskk",n+1,n+1,n+1); - paramskk = k_params.d_view; + paramskk = k_params.template view(); } /* ---------------------------------------------------------------------- diff --git a/src/KOKKOS/pair_vashishta_kokkos.cpp b/src/KOKKOS/pair_vashishta_kokkos.cpp index abdcfac89e..fe2394ae84 100644 --- a/src/KOKKOS/pair_vashishta_kokkos.cpp +++ b/src/KOKKOS/pair_vashishta_kokkos.cpp @@ -573,7 +573,7 @@ void PairVashishtaKokkos::coeff(int narg, char **arg) k_map.template modify(); k_map.template sync(); - d_map = k_map.d_view; + d_map = k_map.template view(); } /* ---------------------------------------------------------------------- @@ -638,8 +638,8 @@ void PairVashishtaKokkos::setup_params() k_params.template modify(); k_params.template sync(); - d_elem2param = k_elem2param.d_view; - d_params = k_params.d_view; + d_elem2param = k_elem2param.template view(); + d_params = k_params.template view(); } /* ---------------------------------------------------------------------- */ diff --git a/src/KOKKOS/pair_vashishta_kokkos.h b/src/KOKKOS/pair_vashishta_kokkos.h index 174db2cb94..c5595bbd8a 100644 --- a/src/KOKKOS/pair_vashishta_kokkos.h +++ b/src/KOKKOS/pair_vashishta_kokkos.h @@ -103,7 +103,7 @@ class PairVashishtaKokkos : public PairVashishta { typedef typename tdual_int_3d::t_host t_host_int_3d; t_int_3d_randomread d_elem2param; - DAT::t_int_1d_randomread d_map; + typename AT::t_int_1d_randomread d_map; typedef Kokkos::DualView tdual_param_1d; typedef typename tdual_param_1d::t_dev t_param_1d; @@ -128,9 +128,9 @@ class PairVashishtaKokkos : public PairVashishta { typename ArrayTypes::t_efloat_1d d_eatom; typename ArrayTypes::t_virial_array d_vatom; - DAT::t_int_1d_randomread d_type2frho; - DAT::t_int_2d_randomread d_type2rhor; - DAT::t_int_2d_randomread d_type2z2r; + typename AT::t_int_1d_randomread d_type2frho; + typename AT::t_int_2d_randomread d_type2rhor; + typename AT::t_int_2d_randomread d_type2z2r; typename AT::t_neighbors_2d d_neighbors; typename AT::t_int_1d_randomread d_ilist; From f4b6b67f6ee6f09b3fc37ac952db065538f6ef75 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 21 Jul 2017 15:04:14 -0600 Subject: [PATCH 333/439] Fixing more execution space issues in KOKKOS package --- src/KOKKOS/angle_charmm_kokkos.cpp | 8 ++++---- src/KOKKOS/bond_fene_kokkos.cpp | 8 ++++---- src/KOKKOS/bond_fene_kokkos.h | 8 ++++---- src/KOKKOS/dihedral_charmm_kokkos.cpp | 20 +++++++++---------- src/KOKKOS/dihedral_opls_kokkos.cpp | 8 ++++---- src/KOKKOS/dihedral_opls_kokkos.h | 8 ++++---- src/KOKKOS/improper_harmonic_kokkos.cpp | 4 ++-- src/KOKKOS/pair_buck_coul_cut_kokkos.cpp | 2 +- src/KOKKOS/pair_buck_coul_long_kokkos.cpp | 2 +- src/KOKKOS/pair_buck_kokkos.cpp | 2 +- src/KOKKOS/pair_coul_cut_kokkos.cpp | 2 +- src/KOKKOS/pair_coul_debye_kokkos.cpp | 2 +- src/KOKKOS/pair_coul_long_kokkos.cpp | 2 +- src/KOKKOS/pair_eam_alloy_kokkos.cpp | 16 +++++++-------- src/KOKKOS/pair_eam_alloy_kokkos.h | 10 +++++----- src/KOKKOS/pair_eam_fs_kokkos.cpp | 16 +++++++-------- src/KOKKOS/pair_eam_fs_kokkos.h | 10 +++++----- src/KOKKOS/pair_eam_kokkos.cpp | 16 +++++++-------- src/KOKKOS/pair_eam_kokkos.h | 10 +++++----- ..._lj_charmm_coul_charmm_implicit_kokkos.cpp | 2 +- .../pair_lj_charmm_coul_charmm_kokkos.cpp | 2 +- .../pair_lj_charmm_coul_long_kokkos.cpp | 2 +- src/KOKKOS/pair_lj_class2_coul_cut_kokkos.cpp | 2 +- .../pair_lj_class2_coul_long_kokkos.cpp | 2 +- src/KOKKOS/pair_lj_class2_kokkos.cpp | 2 +- src/KOKKOS/pair_lj_cut_coul_cut_kokkos.cpp | 2 +- src/KOKKOS/pair_lj_cut_coul_debye_kokkos.cpp | 2 +- src/KOKKOS/pair_lj_cut_coul_dsf_kokkos.cpp | 2 +- src/KOKKOS/pair_lj_cut_coul_long_kokkos.cpp | 2 +- src/KOKKOS/pair_lj_cut_kokkos.cpp | 2 +- src/KOKKOS/pair_lj_expand_kokkos.cpp | 2 +- .../pair_lj_gromacs_coul_gromacs_kokkos.cpp | 2 +- src/KOKKOS/pair_lj_gromacs_kokkos.cpp | 2 +- src/KOKKOS/pair_lj_sdk_kokkos.cpp | 2 +- src/KOKKOS/pair_morse_kokkos.cpp | 2 +- src/KOKKOS/pair_tersoff_mod_kokkos.cpp | 2 +- src/KOKKOS/pair_tersoff_zbl_kokkos.cpp | 2 +- 37 files changed, 95 insertions(+), 95 deletions(-) diff --git a/src/KOKKOS/angle_charmm_kokkos.cpp b/src/KOKKOS/angle_charmm_kokkos.cpp index 8dd22022d8..401a00c856 100644 --- a/src/KOKKOS/angle_charmm_kokkos.cpp +++ b/src/KOKKOS/angle_charmm_kokkos.cpp @@ -271,10 +271,10 @@ void AngleCharmmKokkos::coeff(int narg, char **arg) Kokkos::DualView k_k_ub("AngleCharmm::k_ub",n+1); Kokkos::DualView k_r_ub("AngleCharmm::r_ub",n+1); - d_k = k_k.d_view; - d_theta0 = k_theta0.d_view; - d_k_ub = k_k_ub.d_view; - d_r_ub = k_r_ub.d_view; + d_k = k_k.template view(); + d_theta0 = k_theta0.template view(); + d_k_ub = k_k_ub.template view(); + d_r_ub = k_r_ub.template view(); for (int i = 1; i <= n; i++) { k_k.h_view[i] = k[i]; diff --git a/src/KOKKOS/bond_fene_kokkos.cpp b/src/KOKKOS/bond_fene_kokkos.cpp index 025838340b..8a716a98ef 100644 --- a/src/KOKKOS/bond_fene_kokkos.cpp +++ b/src/KOKKOS/bond_fene_kokkos.cpp @@ -253,10 +253,10 @@ void BondFENEKokkos::allocate() k_epsilon = DAT::tdual_ffloat_1d("BondFene::epsilon",n+1); k_sigma = DAT::tdual_ffloat_1d("BondFene::sigma",n+1); - d_k = k_k.d_view; - d_r0 = k_r0.d_view; - d_epsilon = k_epsilon.d_view; - d_sigma = k_sigma.d_view; + d_k = k_k.template view(); + d_r0 = k_r0.template view(); + d_epsilon = k_epsilon.template view(); + d_sigma = k_sigma.template view(); } /* ---------------------------------------------------------------------- diff --git a/src/KOKKOS/bond_fene_kokkos.h b/src/KOKKOS/bond_fene_kokkos.h index c630abcafc..094685d0cf 100644 --- a/src/KOKKOS/bond_fene_kokkos.h +++ b/src/KOKKOS/bond_fene_kokkos.h @@ -85,10 +85,10 @@ class BondFENEKokkos : public BondFENE { DAT::tdual_ffloat_1d k_epsilon; DAT::tdual_ffloat_1d k_sigma; - DAT::t_ffloat_1d d_k; - DAT::t_ffloat_1d d_r0; - DAT::t_ffloat_1d d_epsilon; - DAT::t_ffloat_1d d_sigma; + typename AT::t_ffloat_1d d_k; + typename AT::t_ffloat_1d d_r0; + typename AT::t_ffloat_1d d_epsilon; + typename AT::t_ffloat_1d d_sigma; virtual void allocate(); }; diff --git a/src/KOKKOS/dihedral_charmm_kokkos.cpp b/src/KOKKOS/dihedral_charmm_kokkos.cpp index a8a8aade60..7f2117c97f 100644 --- a/src/KOKKOS/dihedral_charmm_kokkos.cpp +++ b/src/KOKKOS/dihedral_charmm_kokkos.cpp @@ -432,12 +432,12 @@ void DihedralCharmmKokkos::coeff(int narg, char **arg) Kokkos::DualView k_sin_shift("DihedralCharmm::sin_shift",nd+1); Kokkos::DualView k_weight("DihedralCharmm::weight",nd+1); - d_k = k_k.d_view; - d_multiplicity = k_multiplicity.d_view; - d_shift = k_shift.d_view; - d_cos_shift = k_cos_shift.d_view; - d_sin_shift = k_sin_shift.d_view; - d_weight = k_weight.d_view; + d_k = k_k.template view(); + d_multiplicity = k_multiplicity.template view(); + d_shift = k_shift.template view(); + d_cos_shift = k_cos_shift.template view(); + d_sin_shift = k_sin_shift.template view(); + d_weight = k_weight.template view(); int n = atom->ndihedraltypes; for (int i = 1; i <= n; i++) { @@ -479,10 +479,10 @@ void DihedralCharmmKokkos::init_style() Kokkos::DualView k_lj14_3("DihedralCharmm:lj14_3",n+1,n+1); Kokkos::DualView k_lj14_4("DihedralCharmm:lj14_4",n+1,n+1); - d_lj14_1 = k_lj14_1.d_view; - d_lj14_2 = k_lj14_2.d_view; - d_lj14_3 = k_lj14_3.d_view; - d_lj14_4 = k_lj14_4.d_view; + d_lj14_1 = k_lj14_1.template view(); + d_lj14_2 = k_lj14_2.template view(); + d_lj14_3 = k_lj14_3.template view(); + d_lj14_4 = k_lj14_4.template view(); if (weightflag) { diff --git a/src/KOKKOS/dihedral_opls_kokkos.cpp b/src/KOKKOS/dihedral_opls_kokkos.cpp index e37d4d2ef5..0ee00ca8db 100644 --- a/src/KOKKOS/dihedral_opls_kokkos.cpp +++ b/src/KOKKOS/dihedral_opls_kokkos.cpp @@ -348,10 +348,10 @@ void DihedralOPLSKokkos::allocate() k_k3 = DAT::tdual_ffloat_1d("DihedralOPLS::k3",n+1); k_k4 = DAT::tdual_ffloat_1d("DihedralOPLS::k4",n+1); - d_k1 = k_k1.d_view; - d_k2 = k_k2.d_view; - d_k3 = k_k3.d_view; - d_k4 = k_k4.d_view; + d_k1 = k_k1.template view(); + d_k2 = k_k2.template view(); + d_k3 = k_k3.template view(); + d_k4 = k_k4.template view(); } /* ---------------------------------------------------------------------- diff --git a/src/KOKKOS/dihedral_opls_kokkos.h b/src/KOKKOS/dihedral_opls_kokkos.h index 0a8860c87c..2594f5e74d 100644 --- a/src/KOKKOS/dihedral_opls_kokkos.h +++ b/src/KOKKOS/dihedral_opls_kokkos.h @@ -83,10 +83,10 @@ class DihedralOPLSKokkos : public DihedralOPLS { DAT::tdual_ffloat_1d k_k3; DAT::tdual_ffloat_1d k_k4; - DAT::t_ffloat_1d d_k1; - DAT::t_ffloat_1d d_k2; - DAT::t_ffloat_1d d_k3; - DAT::t_ffloat_1d d_k4; + typename AT::t_ffloat_1d d_k1; + typename AT::t_ffloat_1d d_k2; + typename AT::t_ffloat_1d d_k3; + typename AT::t_ffloat_1d d_k4; virtual void allocate(); }; diff --git a/src/KOKKOS/improper_harmonic_kokkos.cpp b/src/KOKKOS/improper_harmonic_kokkos.cpp index 1e58e18c51..73e105864f 100644 --- a/src/KOKKOS/improper_harmonic_kokkos.cpp +++ b/src/KOKKOS/improper_harmonic_kokkos.cpp @@ -309,8 +309,8 @@ void ImproperHarmonicKokkos::allocate() k_k = Kokkos::DualView("ImproperHarmonic::k",n+1); k_chi = Kokkos::DualView("ImproperHarmonic::chi",n+1); - d_k = k_k.d_view; - d_chi = k_chi.d_view; + d_k = k_k.template view(); + d_chi = k_chi.template view(); } /* ---------------------------------------------------------------------- diff --git a/src/KOKKOS/pair_buck_coul_cut_kokkos.cpp b/src/KOKKOS/pair_buck_coul_cut_kokkos.cpp index 34fd427226..0da8a0a3d6 100644 --- a/src/KOKKOS/pair_buck_coul_cut_kokkos.cpp +++ b/src/KOKKOS/pair_buck_coul_cut_kokkos.cpp @@ -261,7 +261,7 @@ void PairBuckCoulCutKokkos::allocate() memory->create_kokkos(k_cut_coulsq,cut_coulsq,n+1,n+1,"pair:cut_coulsq"); d_cut_coulsq = k_cut_coulsq.template view(); k_params = Kokkos::DualView("PairBuckCoulCut::params",n+1,n+1); - params = k_params.d_view; + params = k_params.template view(); } /* ---------------------------------------------------------------------- diff --git a/src/KOKKOS/pair_buck_coul_long_kokkos.cpp b/src/KOKKOS/pair_buck_coul_long_kokkos.cpp index 243bac5ab7..3a5cbd868f 100644 --- a/src/KOKKOS/pair_buck_coul_long_kokkos.cpp +++ b/src/KOKKOS/pair_buck_coul_long_kokkos.cpp @@ -319,7 +319,7 @@ void PairBuckCoulLongKokkos::allocate() d_cut_coulsq = k_cut_coulsq.template view(); k_params = Kokkos::DualView("PairBuckCoulLong::params",n+1,n+1); - params = k_params.d_view; + params = k_params.template view(); } template diff --git a/src/KOKKOS/pair_buck_kokkos.cpp b/src/KOKKOS/pair_buck_kokkos.cpp index d8534f7900..e7640471d5 100644 --- a/src/KOKKOS/pair_buck_kokkos.cpp +++ b/src/KOKKOS/pair_buck_kokkos.cpp @@ -197,7 +197,7 @@ void PairBuckKokkos::allocate() memory->create_kokkos(k_cutsq,cutsq,n+1,n+1,"pair:cutsq"); d_cutsq = k_cutsq.template view(); k_params = Kokkos::DualView("PairBuck::params",n+1,n+1); - params = k_params.d_view; + params = k_params.template view(); } /* ---------------------------------------------------------------------- diff --git a/src/KOKKOS/pair_coul_cut_kokkos.cpp b/src/KOKKOS/pair_coul_cut_kokkos.cpp index 80ab01d91a..8edf093e2e 100644 --- a/src/KOKKOS/pair_coul_cut_kokkos.cpp +++ b/src/KOKKOS/pair_coul_cut_kokkos.cpp @@ -199,7 +199,7 @@ void PairCoulCutKokkos::allocate() d_cut_coulsq = k_cut_coulsq.template view(); k_params = Kokkos::DualView("PairCoulCut::params",n+1,n+1); - params = k_params.d_view; + params = k_params.template view(); } /* ---------------------------------------------------------------------- diff --git a/src/KOKKOS/pair_coul_debye_kokkos.cpp b/src/KOKKOS/pair_coul_debye_kokkos.cpp index 0771572e46..c331ab8da8 100644 --- a/src/KOKKOS/pair_coul_debye_kokkos.cpp +++ b/src/KOKKOS/pair_coul_debye_kokkos.cpp @@ -221,7 +221,7 @@ void PairCoulDebyeKokkos::allocate() memory->create_kokkos(k_cutsq,cutsq,n+1,n+1,"pair:cutsq"); d_cutsq = k_cutsq.template view(); k_params = Kokkos::DualView("PairCoulDebye::params",n+1,n+1); - params = k_params.d_view; + params = k_params.template view(); } /* ---------------------------------------------------------------------- diff --git a/src/KOKKOS/pair_coul_long_kokkos.cpp b/src/KOKKOS/pair_coul_long_kokkos.cpp index 7dbadf4834..721e140e33 100644 --- a/src/KOKKOS/pair_coul_long_kokkos.cpp +++ b/src/KOKKOS/pair_coul_long_kokkos.cpp @@ -279,7 +279,7 @@ void PairCoulLongKokkos::allocate() d_cut_coulsq = k_cut_coulsq.template view(); k_params = Kokkos::DualView("PairCoulLong::params",n+1,n+1); - params = k_params.d_view; + params = k_params.template view(); } template diff --git a/src/KOKKOS/pair_eam_alloy_kokkos.cpp b/src/KOKKOS/pair_eam_alloy_kokkos.cpp index f8b7a69d60..b7e0175147 100644 --- a/src/KOKKOS/pair_eam_alloy_kokkos.cpp +++ b/src/KOKKOS/pair_eam_alloy_kokkos.cpp @@ -101,8 +101,8 @@ void PairEAMAlloyKokkos::compute(int eflag_in, int vflag_in) nmax = atom->nmax; k_rho = DAT::tdual_ffloat_1d("pair:rho",nmax); k_fp = DAT::tdual_ffloat_1d("pair:fp",nmax); - d_rho = k_rho.d_view; - d_fp = k_fp.d_view; + d_rho = k_rho.template view(); + d_fp = k_fp.template view(); h_rho = k_rho.h_view; h_fp = k_fp.h_view; } @@ -322,9 +322,9 @@ void PairEAMAlloyKokkos::file2array() k_type2z2r.template modify(); k_type2z2r.template sync(); - d_type2frho = k_type2frho.d_view; - d_type2rhor = k_type2rhor.d_view; - d_type2z2r = k_type2z2r.d_view; + d_type2frho = k_type2frho.template view(); + d_type2rhor = k_type2rhor.template view(); + d_type2z2r = k_type2z2r.template view(); } /* ---------------------------------------------------------------------- */ @@ -358,9 +358,9 @@ void PairEAMAlloyKokkos::array2spline() k_z2r_spline.template modify(); k_z2r_spline.template sync(); - d_frho_spline = k_frho_spline.d_view; - d_rhor_spline = k_rhor_spline.d_view; - d_z2r_spline = k_z2r_spline.d_view; + d_frho_spline = k_frho_spline.template view(); + d_rhor_spline = k_rhor_spline.template view(); + d_z2r_spline = k_z2r_spline.template view(); } /* ---------------------------------------------------------------------- */ diff --git a/src/KOKKOS/pair_eam_alloy_kokkos.h b/src/KOKKOS/pair_eam_alloy_kokkos.h index d8c745b230..fb07eec32b 100644 --- a/src/KOKKOS/pair_eam_alloy_kokkos.h +++ b/src/KOKKOS/pair_eam_alloy_kokkos.h @@ -130,15 +130,15 @@ class PairEAMAlloyKokkos : public PairEAM { DAT::tdual_ffloat_1d k_rho; DAT::tdual_ffloat_1d k_fp; - DAT::t_ffloat_1d d_rho; + typename AT::t_ffloat_1d d_rho; typename AT::t_ffloat_1d v_rho; - DAT::t_ffloat_1d d_fp; + typename AT::t_ffloat_1d d_fp; HAT::t_ffloat_1d h_rho; HAT::t_ffloat_1d h_fp; - DAT::t_int_1d_randomread d_type2frho; - DAT::t_int_2d_randomread d_type2rhor; - DAT::t_int_2d_randomread d_type2z2r; + typename AT::t_int_1d_randomread d_type2frho; + typename AT::t_int_2d_randomread d_type2rhor; + typename AT::t_int_2d_randomread d_type2z2r; typedef Kokkos::DualView tdual_ffloat_2d_n7; typedef typename tdual_ffloat_2d_n7::t_dev_const_randomread t_ffloat_2d_n7_randomread; diff --git a/src/KOKKOS/pair_eam_fs_kokkos.cpp b/src/KOKKOS/pair_eam_fs_kokkos.cpp index 57820afb26..982082937e 100644 --- a/src/KOKKOS/pair_eam_fs_kokkos.cpp +++ b/src/KOKKOS/pair_eam_fs_kokkos.cpp @@ -101,8 +101,8 @@ void PairEAMFSKokkos::compute(int eflag_in, int vflag_in) nmax = atom->nmax; k_rho = DAT::tdual_ffloat_1d("pair:rho",nmax); k_fp = DAT::tdual_ffloat_1d("pair:fp",nmax); - d_rho = k_rho.d_view; - d_fp = k_fp.d_view; + d_rho = k_rho.template view(); + d_fp = k_fp.template view(); h_rho = k_rho.h_view; h_fp = k_fp.h_view; } @@ -322,9 +322,9 @@ void PairEAMFSKokkos::file2array() k_type2z2r.template modify(); k_type2z2r.template sync(); - d_type2frho = k_type2frho.d_view; - d_type2rhor = k_type2rhor.d_view; - d_type2z2r = k_type2z2r.d_view; + d_type2frho = k_type2frho.template view(); + d_type2rhor = k_type2rhor.template view(); + d_type2z2r = k_type2z2r.template view(); } /* ---------------------------------------------------------------------- */ @@ -358,9 +358,9 @@ void PairEAMFSKokkos::array2spline() k_z2r_spline.template modify(); k_z2r_spline.template sync(); - d_frho_spline = k_frho_spline.d_view; - d_rhor_spline = k_rhor_spline.d_view; - d_z2r_spline = k_z2r_spline.d_view; + d_frho_spline = k_frho_spline.template view(); + d_rhor_spline = k_rhor_spline.template view(); + d_z2r_spline = k_z2r_spline.template view(); } /* ---------------------------------------------------------------------- */ diff --git a/src/KOKKOS/pair_eam_fs_kokkos.h b/src/KOKKOS/pair_eam_fs_kokkos.h index 40375af066..d71ec2b887 100644 --- a/src/KOKKOS/pair_eam_fs_kokkos.h +++ b/src/KOKKOS/pair_eam_fs_kokkos.h @@ -130,15 +130,15 @@ class PairEAMFSKokkos : public PairEAM { DAT::tdual_ffloat_1d k_rho; DAT::tdual_ffloat_1d k_fp; - DAT::t_ffloat_1d d_rho; + typename AT::t_ffloat_1d d_rho; typename AT::t_ffloat_1d v_rho; - DAT::t_ffloat_1d d_fp; + typename AT::t_ffloat_1d d_fp; HAT::t_ffloat_1d h_rho; HAT::t_ffloat_1d h_fp; - DAT::t_int_1d_randomread d_type2frho; - DAT::t_int_2d_randomread d_type2rhor; - DAT::t_int_2d_randomread d_type2z2r; + typename AT::t_int_1d_randomread d_type2frho; + typename AT::t_int_2d_randomread d_type2rhor; + typename AT::t_int_2d_randomread d_type2z2r; typedef Kokkos::DualView tdual_ffloat_2d_n7; typedef typename tdual_ffloat_2d_n7::t_dev_const_randomread t_ffloat_2d_n7_randomread; diff --git a/src/KOKKOS/pair_eam_kokkos.cpp b/src/KOKKOS/pair_eam_kokkos.cpp index 6b2588475f..8ac92a1766 100644 --- a/src/KOKKOS/pair_eam_kokkos.cpp +++ b/src/KOKKOS/pair_eam_kokkos.cpp @@ -96,8 +96,8 @@ void PairEAMKokkos::compute(int eflag_in, int vflag_in) nmax = atom->nmax; k_rho = DAT::tdual_ffloat_1d("pair:rho",nmax); k_fp = DAT::tdual_ffloat_1d("pair:fp",nmax); - d_rho = k_rho.d_view; - d_fp = k_fp.d_view; + d_rho = k_rho.template view(); + d_fp = k_fp.template view(); h_rho = k_rho.h_view; h_fp = k_fp.h_view; } @@ -322,9 +322,9 @@ void PairEAMKokkos::file2array() k_type2z2r.template modify(); k_type2z2r.template sync(); - d_type2frho = k_type2frho.d_view; - d_type2rhor = k_type2rhor.d_view; - d_type2z2r = k_type2z2r.d_view; + d_type2frho = k_type2frho.template view(); + d_type2rhor = k_type2rhor.template view(); + d_type2z2r = k_type2z2r.template view(); } /* ---------------------------------------------------------------------- */ @@ -358,9 +358,9 @@ void PairEAMKokkos::array2spline() k_z2r_spline.template modify(); k_z2r_spline.template sync(); - d_frho_spline = k_frho_spline.d_view; - d_rhor_spline = k_rhor_spline.d_view; - d_z2r_spline = k_z2r_spline.d_view; + d_frho_spline = k_frho_spline.template view(); + d_rhor_spline = k_rhor_spline.template view(); + d_z2r_spline = k_z2r_spline.template view(); } /* ---------------------------------------------------------------------- */ diff --git a/src/KOKKOS/pair_eam_kokkos.h b/src/KOKKOS/pair_eam_kokkos.h index 229b16471d..856cc51f77 100644 --- a/src/KOKKOS/pair_eam_kokkos.h +++ b/src/KOKKOS/pair_eam_kokkos.h @@ -127,15 +127,15 @@ class PairEAMKokkos : public PairEAM { DAT::tdual_ffloat_1d k_rho; DAT::tdual_ffloat_1d k_fp; - DAT::t_ffloat_1d d_rho; + typename AT::t_ffloat_1d d_rho; typename AT::t_ffloat_1d v_rho; - DAT::t_ffloat_1d d_fp; + typename AT::t_ffloat_1d d_fp; HAT::t_ffloat_1d h_rho; HAT::t_ffloat_1d h_fp; - DAT::t_int_1d_randomread d_type2frho; - DAT::t_int_2d_randomread d_type2rhor; - DAT::t_int_2d_randomread d_type2z2r; + typename AT::t_int_1d_randomread d_type2frho; + typename AT::t_int_2d_randomread d_type2rhor; + typename AT::t_int_2d_randomread d_type2z2r; typedef Kokkos::DualView tdual_ffloat_2d_n7; typedef typename tdual_ffloat_2d_n7::t_dev_const_randomread t_ffloat_2d_n7_randomread; diff --git a/src/KOKKOS/pair_lj_charmm_coul_charmm_implicit_kokkos.cpp b/src/KOKKOS/pair_lj_charmm_coul_charmm_implicit_kokkos.cpp index c00b1fbae4..e7cf7ba42a 100644 --- a/src/KOKKOS/pair_lj_charmm_coul_charmm_implicit_kokkos.cpp +++ b/src/KOKKOS/pair_lj_charmm_coul_charmm_implicit_kokkos.cpp @@ -326,7 +326,7 @@ void PairLJCharmmCoulCharmmImplicitKokkos::allocate() d_cut_coulsq = k_cut_coulsq.template view(); k_params = Kokkos::DualView("PairLJCharmmCoulCharmmImplicit::params",n+1,n+1); - params = k_params.d_view; + params = k_params.template view(); } template diff --git a/src/KOKKOS/pair_lj_charmm_coul_charmm_kokkos.cpp b/src/KOKKOS/pair_lj_charmm_coul_charmm_kokkos.cpp index c88c7db2e3..a456d6e276 100644 --- a/src/KOKKOS/pair_lj_charmm_coul_charmm_kokkos.cpp +++ b/src/KOKKOS/pair_lj_charmm_coul_charmm_kokkos.cpp @@ -327,7 +327,7 @@ void PairLJCharmmCoulCharmmKokkos::allocate() d_cut_coulsq = k_cut_coulsq.template view(); k_params = Kokkos::DualView("PairLJCharmmCoulCharmm::params",n+1,n+1); - params = k_params.d_view; + params = k_params.template view(); } template diff --git a/src/KOKKOS/pair_lj_charmm_coul_long_kokkos.cpp b/src/KOKKOS/pair_lj_charmm_coul_long_kokkos.cpp index 8ebc5f87f3..dffbbb638f 100644 --- a/src/KOKKOS/pair_lj_charmm_coul_long_kokkos.cpp +++ b/src/KOKKOS/pair_lj_charmm_coul_long_kokkos.cpp @@ -347,7 +347,7 @@ void PairLJCharmmCoulLongKokkos::allocate() d_cut_coulsq = k_cut_coulsq.template view(); k_params = Kokkos::DualView("PairLJCharmmCoulLong::params",n+1,n+1); - params = k_params.d_view; + params = k_params.template view(); } template diff --git a/src/KOKKOS/pair_lj_class2_coul_cut_kokkos.cpp b/src/KOKKOS/pair_lj_class2_coul_cut_kokkos.cpp index 936eae79d5..0081aca4f1 100644 --- a/src/KOKKOS/pair_lj_class2_coul_cut_kokkos.cpp +++ b/src/KOKKOS/pair_lj_class2_coul_cut_kokkos.cpp @@ -264,7 +264,7 @@ void PairLJClass2CoulCutKokkos::allocate() memory->create_kokkos(k_cut_coulsq,cut_coulsq,n+1,n+1,"pair:cut_coulsq"); d_cut_coulsq = k_cut_coulsq.template view(); k_params = Kokkos::DualView("PairLJClass2CoulCut::params",n+1,n+1); - params = k_params.d_view; + params = k_params.template view(); } /* ---------------------------------------------------------------------- diff --git a/src/KOKKOS/pair_lj_class2_coul_long_kokkos.cpp b/src/KOKKOS/pair_lj_class2_coul_long_kokkos.cpp index 268213cdbc..b5dc358feb 100644 --- a/src/KOKKOS/pair_lj_class2_coul_long_kokkos.cpp +++ b/src/KOKKOS/pair_lj_class2_coul_long_kokkos.cpp @@ -316,7 +316,7 @@ void PairLJClass2CoulLongKokkos::allocate() memory->create_kokkos(k_cut_coulsq,n+1,n+1,"pair:cut_coulsq"); d_cut_coulsq = k_cut_coulsq.template view(); k_params = Kokkos::DualView("PairLJClass2CoulLong::params",n+1,n+1); - params = k_params.d_view; + params = k_params.template view(); } template diff --git a/src/KOKKOS/pair_lj_class2_kokkos.cpp b/src/KOKKOS/pair_lj_class2_kokkos.cpp index c899327d7c..34cc15279b 100644 --- a/src/KOKKOS/pair_lj_class2_kokkos.cpp +++ b/src/KOKKOS/pair_lj_class2_kokkos.cpp @@ -203,7 +203,7 @@ void PairLJClass2Kokkos::allocate() memory->create_kokkos(k_cutsq,cutsq,n+1,n+1,"pair:cutsq"); d_cutsq = k_cutsq.template view(); k_params = Kokkos::DualView("PairLJClass2::params",n+1,n+1); - params = k_params.d_view; + params = k_params.template view(); } /* ---------------------------------------------------------------------- diff --git a/src/KOKKOS/pair_lj_cut_coul_cut_kokkos.cpp b/src/KOKKOS/pair_lj_cut_coul_cut_kokkos.cpp index f4de48f176..c3fda01ce6 100644 --- a/src/KOKKOS/pair_lj_cut_coul_cut_kokkos.cpp +++ b/src/KOKKOS/pair_lj_cut_coul_cut_kokkos.cpp @@ -256,7 +256,7 @@ void PairLJCutCoulCutKokkos::allocate() memory->create_kokkos(k_cut_coulsq,cut_coulsq,n+1,n+1,"pair:cut_coulsq"); d_cut_coulsq = k_cut_coulsq.template view(); k_params = Kokkos::DualView("PairLJCutCoulCut::params",n+1,n+1); - params = k_params.d_view; + params = k_params.template view(); } /* ---------------------------------------------------------------------- diff --git a/src/KOKKOS/pair_lj_cut_coul_debye_kokkos.cpp b/src/KOKKOS/pair_lj_cut_coul_debye_kokkos.cpp index ad51dd0a88..b7a71cb99a 100644 --- a/src/KOKKOS/pair_lj_cut_coul_debye_kokkos.cpp +++ b/src/KOKKOS/pair_lj_cut_coul_debye_kokkos.cpp @@ -270,7 +270,7 @@ void PairLJCutCoulDebyeKokkos::allocate() memory->create_kokkos(k_cut_coulsq,cut_coulsq,n+1,n+1,"pair:cut_coulsq"); d_cut_coulsq = k_cut_coulsq.template view(); k_params = Kokkos::DualView("PairLJCutCoulDebye::params",n+1,n+1); - params = k_params.d_view; + params = k_params.template view(); } /* ---------------------------------------------------------------------- diff --git a/src/KOKKOS/pair_lj_cut_coul_dsf_kokkos.cpp b/src/KOKKOS/pair_lj_cut_coul_dsf_kokkos.cpp index 89f263113e..9df5963676 100644 --- a/src/KOKKOS/pair_lj_cut_coul_dsf_kokkos.cpp +++ b/src/KOKKOS/pair_lj_cut_coul_dsf_kokkos.cpp @@ -288,7 +288,7 @@ void PairLJCutCoulDSFKokkos::allocate() memory->create_kokkos(k_cut_coulsq,n+1,n+1,"pair:cut_coulsq"); d_cut_coulsq = k_cut_coulsq.template view(); k_params = Kokkos::DualView("PairLJCutCoulDSF::params",n+1,n+1); - params = k_params.d_view; + params = k_params.template view(); } /* ---------------------------------------------------------------------- diff --git a/src/KOKKOS/pair_lj_cut_coul_long_kokkos.cpp b/src/KOKKOS/pair_lj_cut_coul_long_kokkos.cpp index 4de51ca8d2..9bd79c7341 100644 --- a/src/KOKKOS/pair_lj_cut_coul_long_kokkos.cpp +++ b/src/KOKKOS/pair_lj_cut_coul_long_kokkos.cpp @@ -313,7 +313,7 @@ void PairLJCutCoulLongKokkos::allocate() memory->create_kokkos(k_cut_coulsq,n+1,n+1,"pair:cut_coulsq"); d_cut_coulsq = k_cut_coulsq.template view(); k_params = Kokkos::DualView("PairLJCutCoulLong::params",n+1,n+1); - params = k_params.d_view; + params = k_params.template view(); } template diff --git a/src/KOKKOS/pair_lj_cut_kokkos.cpp b/src/KOKKOS/pair_lj_cut_kokkos.cpp index ea78b73711..c90d5ad11c 100644 --- a/src/KOKKOS/pair_lj_cut_kokkos.cpp +++ b/src/KOKKOS/pair_lj_cut_kokkos.cpp @@ -198,7 +198,7 @@ void PairLJCutKokkos::allocate() memory->create_kokkos(k_cutsq,cutsq,n+1,n+1,"pair:cutsq"); d_cutsq = k_cutsq.template view(); k_params = Kokkos::DualView("PairLJCut::params",n+1,n+1); - params = k_params.d_view; + params = k_params.template view(); } /* ---------------------------------------------------------------------- diff --git a/src/KOKKOS/pair_lj_expand_kokkos.cpp b/src/KOKKOS/pair_lj_expand_kokkos.cpp index 6b62150632..95ec252ad5 100644 --- a/src/KOKKOS/pair_lj_expand_kokkos.cpp +++ b/src/KOKKOS/pair_lj_expand_kokkos.cpp @@ -205,7 +205,7 @@ void PairLJExpandKokkos::allocate() memory->create_kokkos(k_cutsq,cutsq,n+1,n+1,"pair:cutsq"); d_cutsq = k_cutsq.template view(); k_params = Kokkos::DualView("PairLJExpand::params",n+1,n+1); - params = k_params.d_view; + params = k_params.template view(); } /* ---------------------------------------------------------------------- diff --git a/src/KOKKOS/pair_lj_gromacs_coul_gromacs_kokkos.cpp b/src/KOKKOS/pair_lj_gromacs_coul_gromacs_kokkos.cpp index 0c492131dd..4b21b08eb3 100644 --- a/src/KOKKOS/pair_lj_gromacs_coul_gromacs_kokkos.cpp +++ b/src/KOKKOS/pair_lj_gromacs_coul_gromacs_kokkos.cpp @@ -310,7 +310,7 @@ void PairLJGromacsCoulGromacsKokkos::allocate() d_cut_coulsq = k_cut_coulsq.template view(); k_params = Kokkos::DualView("PairLJGromacsCoulGromacs::params",n+1,n+1); - params = k_params.d_view; + params = k_params.template view(); } template diff --git a/src/KOKKOS/pair_lj_gromacs_kokkos.cpp b/src/KOKKOS/pair_lj_gromacs_kokkos.cpp index 76d7abbe28..73a17d7b22 100644 --- a/src/KOKKOS/pair_lj_gromacs_kokkos.cpp +++ b/src/KOKKOS/pair_lj_gromacs_kokkos.cpp @@ -252,7 +252,7 @@ void PairLJGromacsKokkos::allocate() d_cut_inner_sq = k_cut_inner_sq.template view(); k_params = Kokkos::DualView("PairLJGromacs::params",n+1,n+1); - params = k_params.d_view; + params = k_params.template view(); } /* ---------------------------------------------------------------------- diff --git a/src/KOKKOS/pair_lj_sdk_kokkos.cpp b/src/KOKKOS/pair_lj_sdk_kokkos.cpp index 41561c2988..2063f62b20 100644 --- a/src/KOKKOS/pair_lj_sdk_kokkos.cpp +++ b/src/KOKKOS/pair_lj_sdk_kokkos.cpp @@ -234,7 +234,7 @@ void PairLJSDKKokkos::allocate() memory->create_kokkos(k_cutsq,cutsq,n+1,n+1,"pair:cutsq"); d_cutsq = k_cutsq.template view(); k_params = Kokkos::DualView("PairLJSDK::params",n+1,n+1); - params = k_params.d_view; + params = k_params.template view(); } /* ---------------------------------------------------------------------- diff --git a/src/KOKKOS/pair_morse_kokkos.cpp b/src/KOKKOS/pair_morse_kokkos.cpp index 3201fad215..08a9b82640 100644 --- a/src/KOKKOS/pair_morse_kokkos.cpp +++ b/src/KOKKOS/pair_morse_kokkos.cpp @@ -212,7 +212,7 @@ void PairMorseKokkos::allocate() memory->create_kokkos(k_cutsq,cutsq,n+1,n+1,"pair:cutsq"); d_cutsq = k_cutsq.template view(); k_params = Kokkos::DualView("PairMorse::params",n+1,n+1); - params = k_params.d_view; + params = k_params.template view(); } /* ---------------------------------------------------------------------- diff --git a/src/KOKKOS/pair_tersoff_mod_kokkos.cpp b/src/KOKKOS/pair_tersoff_mod_kokkos.cpp index d77ba2f141..9a59979f4c 100644 --- a/src/KOKKOS/pair_tersoff_mod_kokkos.cpp +++ b/src/KOKKOS/pair_tersoff_mod_kokkos.cpp @@ -76,7 +76,7 @@ void PairTersoffMODKokkos::allocate() k_params = Kokkos::DualView ("PairTersoffMOD::paramskk",n+1,n+1,n+1); - paramskk = k_params.d_view; + paramskk = k_params.template view(); } /* ---------------------------------------------------------------------- diff --git a/src/KOKKOS/pair_tersoff_zbl_kokkos.cpp b/src/KOKKOS/pair_tersoff_zbl_kokkos.cpp index 040d8c5230..8468bb01f5 100644 --- a/src/KOKKOS/pair_tersoff_zbl_kokkos.cpp +++ b/src/KOKKOS/pair_tersoff_zbl_kokkos.cpp @@ -87,7 +87,7 @@ void PairTersoffZBLKokkos::allocate() k_params = Kokkos::DualView ("PairTersoffZBL::paramskk",n+1,n+1,n+1); - paramskk = k_params.d_view; + paramskk = k_params.template view(); } /* ---------------------------------------------------------------------- From 8d485ea128d90a7b50bf90e5f47cb759be9e2074 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 21 Jul 2017 16:04:18 -0600 Subject: [PATCH 334/439] Remove hardcoded execution spaces --- src/KOKKOS/fix_nh_kokkos.cpp | 2 +- src/KOKKOS/fix_nve_kokkos.cpp | 2 +- src/KOKKOS/fix_qeq_reax_kokkos.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/KOKKOS/fix_nh_kokkos.cpp b/src/KOKKOS/fix_nh_kokkos.cpp index fb03bf68c6..7136c776a1 100644 --- a/src/KOKKOS/fix_nh_kokkos.cpp +++ b/src/KOKKOS/fix_nh_kokkos.cpp @@ -80,7 +80,7 @@ void FixNHKokkos::init() FixNH::init(); atomKK->k_mass.modify(); - atomKK->k_mass.sync(); + atomKK->k_mass.sync(); } /* ---------------------------------------------------------------------- diff --git a/src/KOKKOS/fix_nve_kokkos.cpp b/src/KOKKOS/fix_nve_kokkos.cpp index eb41443bab..c071447eb7 100644 --- a/src/KOKKOS/fix_nve_kokkos.cpp +++ b/src/KOKKOS/fix_nve_kokkos.cpp @@ -46,7 +46,7 @@ void FixNVEKokkos::init() FixNVE::init(); atomKK->k_mass.modify(); - atomKK->k_mass.sync(); + atomKK->k_mass.sync(); } /* ---------------------------------------------------------------------- diff --git a/src/KOKKOS/fix_qeq_reax_kokkos.cpp b/src/KOKKOS/fix_qeq_reax_kokkos.cpp index cef003222a..e54b53ae89 100644 --- a/src/KOKKOS/fix_qeq_reax_kokkos.cpp +++ b/src/KOKKOS/fix_qeq_reax_kokkos.cpp @@ -79,7 +79,7 @@ template void FixQEqReaxKokkos::init() { atomKK->k_q.modify(); - atomKK->k_q.sync(); + atomKK->k_q.sync(); FixQEqReax::init(); From 126d9cd3bc71cd354556999319e48a381d08d980 Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Sat, 22 Jul 2017 13:57:15 -0600 Subject: [PATCH 335/439] add GZIP and FFMPEG status --- cmake/CMakeLists.txt | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 228a9e36e3..959aea869a 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -196,13 +196,15 @@ if(PNG_FOUND AND ZLIB_FOUND) add_definitions(-DLAMMPS_PNG) endif() -find_program(GZIP gzip) -if(GZIP) +find_program(GZIP_EXECUTABLE gzip) +find_package_handle_standard_args(GZIP REQUIRED_VARS GZIP_EXECUTABLE) +if(GZIP_FOUND) add_definitions(-DLAMMPS_GZIP) endif() -find_program(FFMPEG ffmpeg) -if(FFMPEG) +find_program(FFMPEG_EXECUTABLE ffmpeg) +find_package_handle_standard_args(FFMPEG REQUIRED_VARS FFMPEG_EXECUTABLE) +if(FFMPEG_FOUND) add_definitions(-DLAMMPS_FFMPEG) endif() From a71f5a0c20f7e23c3d5cfe2e73eff38aa4dcb5c3 Mon Sep 17 00:00:00 2001 From: Trung Nguyen Date: Sat, 22 Jul 2017 22:57:37 -0500 Subject: [PATCH 336/439] Enabled again neigh no with tpa > 1 for 3-body gpu styles for backward compatibility, could be slower than neigh no tpa 1 in many cases --- lib/gpu/lal_base_three.cpp | 1 - lib/gpu/lal_sw.cu | 92 ++++++++++++++++---------- lib/gpu/lal_tersoff.cu | 131 ++++++++++++++++++++++--------------- lib/gpu/lal_tersoff_mod.cu | 130 ++++++++++++++++++++++-------------- lib/gpu/lal_tersoff_zbl.cu | 130 ++++++++++++++++++++++-------------- lib/gpu/lal_vashishta.cu | 82 ++++++++++++++--------- 6 files changed, 349 insertions(+), 217 deletions(-) diff --git a/lib/gpu/lal_base_three.cpp b/lib/gpu/lal_base_three.cpp index 5f3c57337e..aa77a48c66 100644 --- a/lib/gpu/lal_base_three.cpp +++ b/lib/gpu/lal_base_three.cpp @@ -73,7 +73,6 @@ int BaseThreeT::init_three(const int nlocal, const int nall, if (_threads_per_atom>1 && gpu_nbor==0) { // neigh no and tpa > 1 nbor->packing(true); _nbor_data=&(nbor->dev_packed); - _threads_per_atom = 1; // enforce tpa = 1 for now } else // neigh yes or tpa == 1 _nbor_data=&(nbor->dev_nbor); if (_threads_per_atom*_threads_per_atom>device->warp_size()) diff --git a/lib/gpu/lal_sw.cu b/lib/gpu/lal_sw.cu index 7dea52898e..a5c9f49d08 100644 --- a/lib/gpu/lal_sw.cu +++ b/lib/gpu/lal_sw.cu @@ -167,7 +167,6 @@ __kernel void k_sw_short_nbor(const __global numtyp4 *restrict x_, numtyp4 jx; fetch4(jx,j,pos_tex); //x_[j]; int jtype=jx.w; jtype=map[jtype]; - int ijparam=elem2param[itype*nelements*nelements+jtype*nelements+jtype]; // Compute r12 @@ -217,8 +216,8 @@ __kernel void k_sw(const __global numtyp4 *restrict x_, __syncthreads(); if (ii0) energy += (param3_bigh*reta+vc2-vc3-param3_bigw*r6inv-r*param3_dvrc+param3_c0); @@ -435,7 +436,7 @@ __kernel void k_vashishta_three_center(const __global numtyp4 *restrict x_, if (ii Date: Sun, 23 Jul 2017 00:08:55 -0500 Subject: [PATCH 337/439] Cleaned up 3-body kernels, reverted some mistaken changes to vashishta --- lib/gpu/lal_tersoff.cu | 5 ----- lib/gpu/lal_tersoff_mod.cu | 7 ------- lib/gpu/lal_tersoff_zbl.cu | 7 ------- lib/gpu/lal_vashishta.cu | 10 +++------- 4 files changed, 3 insertions(+), 26 deletions(-) diff --git a/lib/gpu/lal_tersoff.cu b/lib/gpu/lal_tersoff.cu index 65c0fa49fc..cdeb5679d8 100644 --- a/lib/gpu/lal_tersoff.cu +++ b/lib/gpu/lal_tersoff.cu @@ -581,7 +581,6 @@ __kernel void k_tersoff_three_center(const __global numtyp4 *restrict x_, delr1[2] = jx.z-ix.z; numtyp rsq1 = delr1[0]*delr1[0] + delr1[1]*delr1[1] + delr1[2]*delr1[2]; -// if (rsq1 > cutsq[ijparam]) continue; numtyp r1 = ucl_sqrt(rsq1); numtyp r1inv = ucl_rsqrt(rsq1); @@ -770,8 +769,6 @@ __kernel void k_tersoff_three_end(const __global numtyp4 *restrict x_, delr1[2] = jx.z-ix.z; numtyp rsq1 = delr1[0]*delr1[0] + delr1[1]*delr1[1] + delr1[2]*delr1[2]; -// if (rsq1 > cutsq[ijparam]) continue; - numtyp mdelr1[3]; mdelr1[0] = -delr1[0]; mdelr1[1] = -delr1[1]; @@ -1017,8 +1014,6 @@ __kernel void k_tersoff_three_end_vatom(const __global numtyp4 *restrict x_, delr1[2] = jx.z-ix.z; numtyp rsq1 = delr1[0]*delr1[0] + delr1[1]*delr1[1] + delr1[2]*delr1[2]; -// if (rsq1 > cutsq[ijparam]) continue; - numtyp mdelr1[3]; mdelr1[0] = -delr1[0]; mdelr1[1] = -delr1[1]; diff --git a/lib/gpu/lal_tersoff_mod.cu b/lib/gpu/lal_tersoff_mod.cu index 3297bc74fb..576359b514 100644 --- a/lib/gpu/lal_tersoff_mod.cu +++ b/lib/gpu/lal_tersoff_mod.cu @@ -308,8 +308,6 @@ __kernel void k_tersoff_mod_zeta(const __global numtyp4 *restrict x_, delr1.z = jx.z-ix.z; numtyp rsq1 = delr1.x*delr1.x+delr1.y*delr1.y+delr1.z*delr1.z; -// if (rsq1 > cutsq[ijparam]) continue; - // compute zeta_ij z = (acctyp)0; @@ -585,7 +583,6 @@ __kernel void k_tersoff_mod_three_center(const __global numtyp4 *restrict x_, delr1[2] = jx.z-ix.z; numtyp rsq1 = delr1[0]*delr1[0] + delr1[1]*delr1[1] + delr1[2]*delr1[2]; -// if (rsq1 > cutsq[ijparam]) continue; numtyp r1 = ucl_sqrt(rsq1); numtyp r1inv = ucl_rsqrt(rsq1); @@ -780,8 +777,6 @@ __kernel void k_tersoff_mod_three_end(const __global numtyp4 *restrict x_, delr1[2] = jx.z-ix.z; numtyp rsq1 = delr1[0]*delr1[0] + delr1[1]*delr1[1] + delr1[2]*delr1[2]; -// if (rsq1 > cutsq[ijparam]) continue; - numtyp mdelr1[3]; mdelr1[0] = -delr1[0]; mdelr1[1] = -delr1[1]; @@ -1036,8 +1031,6 @@ __kernel void k_tersoff_mod_three_end_vatom(const __global numtyp4 *restrict x_, delr1[2] = jx.z-ix.z; numtyp rsq1 = delr1[0]*delr1[0] + delr1[1]*delr1[1] + delr1[2]*delr1[2]; -// if (rsq1 > cutsq[ijparam]) continue; - numtyp mdelr1[3]; mdelr1[0] = -delr1[0]; mdelr1[1] = -delr1[1]; diff --git a/lib/gpu/lal_tersoff_zbl.cu b/lib/gpu/lal_tersoff_zbl.cu index 8fd5489543..e8bb017f59 100644 --- a/lib/gpu/lal_tersoff_zbl.cu +++ b/lib/gpu/lal_tersoff_zbl.cu @@ -314,8 +314,6 @@ __kernel void k_tersoff_zbl_zeta(const __global numtyp4 *restrict x_, delr1.z = jx.z-ix.z; numtyp rsq1 = delr1.x*delr1.x+delr1.y*delr1.y+delr1.z*delr1.z; -// if (rsq1 > cutsq[ijparam]) continue; - // compute zeta_ij z = (acctyp)0; @@ -601,7 +599,6 @@ __kernel void k_tersoff_zbl_three_center(const __global numtyp4 *restrict x_, delr1[2] = jx.z-ix.z; numtyp rsq1 = delr1[0]*delr1[0] + delr1[1]*delr1[1] + delr1[2]*delr1[2]; -// if (rsq1 > cutsq[ijparam]) continue; numtyp r1 = ucl_sqrt(rsq1); numtyp r1inv = ucl_rsqrt(rsq1); @@ -790,8 +787,6 @@ __kernel void k_tersoff_zbl_three_end(const __global numtyp4 *restrict x_, delr1[2] = jx.z-ix.z; numtyp rsq1 = delr1[0]*delr1[0] + delr1[1]*delr1[1] + delr1[2]*delr1[2]; -// if (rsq1 > cutsq[ijparam]) continue; - numtyp mdelr1[3]; mdelr1[0] = -delr1[0]; mdelr1[1] = -delr1[1]; @@ -1037,8 +1032,6 @@ __kernel void k_tersoff_zbl_three_end_vatom(const __global numtyp4 *restrict x_, delr1[2] = jx.z-ix.z; numtyp rsq1 = delr1[0]*delr1[0] + delr1[1]*delr1[1] + delr1[2]*delr1[2]; -// if (rsq1 > cutsq[ijparam]) continue; - numtyp mdelr1[3]; mdelr1[0] = -delr1[0]; mdelr1[1] = -delr1[1]; diff --git a/lib/gpu/lal_vashishta.cu b/lib/gpu/lal_vashishta.cu index 26805588eb..fa7f413aa5 100644 --- a/lib/gpu/lal_vashishta.cu +++ b/lib/gpu/lal_vashishta.cu @@ -474,9 +474,7 @@ __kernel void k_vashishta_three_center(const __global numtyp4 *restrict x_, numtyp4 param4_ijparam; fetch4(param4_ijparam,ijparam,param4_tex); param_r0sq_ij=param4_ijparam.x; - -// if (rsq1 > param_r0sq_ij) continue; - + if (rsq1 > param_r0sq_ij) continue; // still keep this for neigh no and tpa > 1 param_gamma_ij=param4_ijparam.y; param_r0_ij=param4_ijparam.w; @@ -617,8 +615,7 @@ __kernel void k_vashishta_three_end(const __global numtyp4 *restrict x_, int ijparam=elem2param[itype*nelements*nelements+jtype*nelements+jtype]; numtyp4 param4_ijparam; fetch4(param4_ijparam,ijparam,param4_tex); param_r0sq_ij = param4_ijparam.x; - -// if (rsq1 > param_r0sq_ij) continue; + if (rsq1 > param_r0sq_ij) continue; // still keep this for neigh no and tpa > 1 param_gamma_ij=param4_ijparam.y; param_r0_ij = param4_ijparam.w; @@ -773,8 +770,7 @@ __kernel void k_vashishta_three_end_vatom(const __global numtyp4 *restrict x_, int ijparam=elem2param[itype*nelements*nelements+jtype*nelements+jtype]; numtyp4 param4_ijparam; fetch4(param4_ijparam,ijparam,param4_tex); param_r0sq_ij=param4_ijparam.x; - -// if (rsq1 > param_r0sq_ij) continue; + if (rsq1 > param_r0sq_ij) continue; // still keep this for neigh no and tpa > 1 param_gamma_ij=param4_ijparam.y; param_r0_ij=param4_ijparam.w; From f2023431f69bd0449ef0bc622697d9bdca2b9b73 Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Mon, 24 Jul 2017 12:54:26 -0600 Subject: [PATCH 338/439] cmake: fixed another typo --- cmake/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 959aea869a..059a8733a3 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -322,7 +322,7 @@ RegisterStyles(${LAMMPS_SOURCE_DIR}) ############################################## # add sources of enabled packages ############################################ -foreach(PKG ${PACKAGES} ${OTHER_PACKAGES}) +foreach(PKG ${DEFAULT_PACKAGES} ${OTHER_PACKAGES}) if(ENABLE_${PKG}) set(${PKG}_SOURCES_DIR ${LAMMPS_SOURCE_DIR}/${PKG}) From 6716de5320733f033ebbaba6fc6f2b28cf770c3a Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Mon, 24 Jul 2017 20:17:17 -0600 Subject: [PATCH 339/439] allow user to override PYTHON_INSTDIR --- cmake/CMakeLists.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 059a8733a3..15a87b7f6e 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -172,9 +172,11 @@ if(ENABLE_PYTHON) add_definitions(-DLMP_PYTHON) include_directories(${PYTHON_INCLUDE_DIR}) list(APPEND LAMMPS_LINK_LIBS ${PYTHON_LIBRARY}) - execute_process(COMMAND ${PYTHON_EXECUTABLE} + if(NOT PYTHON_INSTDIR) + execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "import distutils.sysconfig as cg; print(cg.get_python_lib(1,0,prefix='${CMAKE_INSTALL_PREFIX}'))" - OUTPUT_VARIABLE PYTHON_INSTDIR OUTPUT_STRIP_TRAILING_WHITESPACE) + OUTPUT_VARIABLE PYTHON_INSTDIR OUTPUT_STRIP_TRAILING_WHITESPACE) + endif() install(FILES ${CMAKE_SOURCE_DIR}/../python/lammps.py DESTINATION ${PYTHON_INSTDIR}) if(NOT BUILD_SHARED_LIBS) message(FATAL_ERROR "Python package need lammps to be build shared, -DBUILD_SHARED_LIBS=ON") From 633ca33f2f9163a4bbe740801e28efa9d4a5d7ce Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 25 Jul 2017 13:08:24 -0600 Subject: [PATCH 340/439] Fix issue in Kokkos neighborlist --- src/KOKKOS/npair_kokkos.cpp | 10 ++++++++-- src/KOKKOS/npair_kokkos.h | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/KOKKOS/npair_kokkos.cpp b/src/KOKKOS/npair_kokkos.cpp index b7b550369d..fd5f9373f2 100644 --- a/src/KOKKOS/npair_kokkos.cpp +++ b/src/KOKKOS/npair_kokkos.cpp @@ -201,14 +201,20 @@ if (GHOST) { if (newton_pair) { NPairKokkosBuildFunctor f(data,atoms_per_bin * 5 * sizeof(X_FLOAT) * factor); #ifdef KOKKOS_HAVE_CUDA - Kokkos::parallel_for(config, f); + if (ExecutionSpaceFromDevice::space == Device) + Kokkos::parallel_for(config, f); + else + Kokkos::parallel_for(nall, f); #else Kokkos::parallel_for(nall, f); #endif } else { NPairKokkosBuildFunctor f(data,atoms_per_bin * 5 * sizeof(X_FLOAT) * factor); #ifdef KOKKOS_HAVE_CUDA - Kokkos::parallel_for(config, f); + if (ExecutionSpaceFromDevice::space == Device) + Kokkos::parallel_for(config, f); + else + Kokkos::parallel_for(nall, f); #else Kokkos::parallel_for(nall, f); #endif diff --git a/src/KOKKOS/npair_kokkos.h b/src/KOKKOS/npair_kokkos.h index 53183114d3..a28b5ff978 100644 --- a/src/KOKKOS/npair_kokkos.h +++ b/src/KOKKOS/npair_kokkos.h @@ -409,7 +409,7 @@ struct NPairKokkosBuildFunctor { c.template build_Item(i); } - void operator() (typename Kokkos::TeamPolicy::member_type dev) const {} + void operator() (typename Kokkos::TeamPolicy::member_type dev) const {} // Should error out }; template From 557e5b964ad8ae26d61ddb4713575f3706fb6d74 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 25 Jul 2017 13:37:01 -0600 Subject: [PATCH 341/439] Fixing Kokkos execution space issue with regions --- src/KOKKOS/fix_setforce_kokkos.cpp | 6 +- src/KOKKOS/fix_setforce_kokkos.h | 4 +- src/KOKKOS/out.txt | 119 +++++++++++++++++++++++++++++ src/KOKKOS/region_block_kokkos.cpp | 6 +- src/KOKKOS/region_block_kokkos.h | 4 +- src/accelerator_kokkos.h | 2 +- src/region.cpp | 2 +- src/region.h | 2 +- 8 files changed, 134 insertions(+), 11 deletions(-) create mode 100644 src/KOKKOS/out.txt diff --git a/src/KOKKOS/fix_setforce_kokkos.cpp b/src/KOKKOS/fix_setforce_kokkos.cpp index 5e26ef3610..2ef04ad6ee 100644 --- a/src/KOKKOS/fix_setforce_kokkos.cpp +++ b/src/KOKKOS/fix_setforce_kokkos.cpp @@ -89,8 +89,10 @@ void FixSetForceKokkos::post_force(int vflag) if (iregion >= 0) { region = domain->regions[iregion]; region->prematch(); - d_match = DAT::t_int_1d("setforce:d_match",nlocal); - region->match_all_kokkos(groupbit,d_match); + DAT::tdual_int_1d k_match = DAT::tdual_int_1d("setforce:k_match",nlocal); + region->match_all_kokkos(groupbit,k_match); + k_match.template sync(); + d_match = k_match.template view(); } // reallocate sforce array if necessary diff --git a/src/KOKKOS/fix_setforce_kokkos.h b/src/KOKKOS/fix_setforce_kokkos.h index dffa22c93a..3cbf3d3720 100644 --- a/src/KOKKOS/fix_setforce_kokkos.h +++ b/src/KOKKOS/fix_setforce_kokkos.h @@ -75,8 +75,8 @@ class FixSetForceKokkos : public FixSetForce { private: DAT::tdual_ffloat_2d k_sforce; - DAT::t_ffloat_2d_randomread d_sforce; - DAT::t_int_1d d_match; + typename AT::t_ffloat_2d_randomread d_sforce; + typename AT::t_int_1d d_match; typename AT::t_x_array_randomread x; typename AT::t_f_array f; diff --git a/src/KOKKOS/out.txt b/src/KOKKOS/out.txt new file mode 100644 index 0000000000..0452e263ab --- /dev/null +++ b/src/KOKKOS/out.txt @@ -0,0 +1,119 @@ +atom_vec_angle_kokkos.cpp: k_count.modify(); +atom_vec_angle_kokkos.cpp: if (mask & X_MASK) atomKK->k_x.modify(); +atom_vec_angle_kokkos.cpp: if (mask & V_MASK) atomKK->k_v.modify(); +atom_vec_angle_kokkos.cpp: if (mask & F_MASK) atomKK->k_f.modify(); +atom_vec_angle_kokkos.cpp: if (mask & TAG_MASK) atomKK->k_tag.modify(); +atom_vec_angle_kokkos.cpp: if (mask & TYPE_MASK) atomKK->k_type.modify(); +atom_vec_angle_kokkos.cpp: if (mask & MASK_MASK) atomKK->k_mask.modify(); +atom_vec_angle_kokkos.cpp: if (mask & IMAGE_MASK) atomKK->k_image.modify(); +atom_vec_angle_kokkos.cpp: if (mask & MOLECULE_MASK) atomKK->k_molecule.modify(); +atom_vec_angle_kokkos.cpp: atomKK->k_nspecial.modify(); +atom_vec_angle_kokkos.cpp: atomKK->k_special.modify(); +atom_vec_angle_kokkos.cpp: atomKK->k_num_bond.modify(); +atom_vec_angle_kokkos.cpp: atomKK->k_bond_type.modify(); +atom_vec_angle_kokkos.cpp: atomKK->k_bond_atom.modify(); +atom_vec_angle_kokkos.cpp: atomKK->k_num_angle.modify(); +atom_vec_angle_kokkos.cpp: atomKK->k_angle_type.modify(); +atom_vec_angle_kokkos.cpp: atomKK->k_angle_atom1.modify(); +atom_vec_angle_kokkos.cpp: atomKK->k_angle_atom2.modify(); +atom_vec_angle_kokkos.cpp: atomKK->k_angle_atom3.modify(); +atom_vec_atomic_kokkos.cpp: k_count.modify(); +atom_vec_atomic_kokkos.cpp: if (mask & X_MASK) atomKK->k_x.modify(); +atom_vec_atomic_kokkos.cpp: if (mask & V_MASK) atomKK->k_v.modify(); +atom_vec_atomic_kokkos.cpp: if (mask & F_MASK) atomKK->k_f.modify(); +atom_vec_atomic_kokkos.cpp: if (mask & TAG_MASK) atomKK->k_tag.modify(); +atom_vec_atomic_kokkos.cpp: if (mask & TYPE_MASK) atomKK->k_type.modify(); +atom_vec_atomic_kokkos.cpp: if (mask & MASK_MASK) atomKK->k_mask.modify(); +atom_vec_atomic_kokkos.cpp: if (mask & IMAGE_MASK) atomKK->k_image.modify(); +atom_vec_bond_kokkos.cpp: k_count.modify(); +atom_vec_bond_kokkos.cpp: if (mask & X_MASK) atomKK->k_x.modify(); +atom_vec_bond_kokkos.cpp: if (mask & V_MASK) atomKK->k_v.modify(); +atom_vec_bond_kokkos.cpp: if (mask & F_MASK) atomKK->k_f.modify(); +atom_vec_bond_kokkos.cpp: if (mask & TAG_MASK) atomKK->k_tag.modify(); +atom_vec_bond_kokkos.cpp: if (mask & TYPE_MASK) atomKK->k_type.modify(); +atom_vec_bond_kokkos.cpp: if (mask & MASK_MASK) atomKK->k_mask.modify(); +atom_vec_bond_kokkos.cpp: if (mask & IMAGE_MASK) atomKK->k_image.modify(); +atom_vec_bond_kokkos.cpp: if (mask & MOLECULE_MASK) atomKK->k_molecule.modify(); +atom_vec_bond_kokkos.cpp: atomKK->k_nspecial.modify(); +atom_vec_bond_kokkos.cpp: atomKK->k_special.modify(); +atom_vec_bond_kokkos.cpp: atomKK->k_num_bond.modify(); +atom_vec_bond_kokkos.cpp: atomKK->k_bond_type.modify(); +atom_vec_bond_kokkos.cpp: atomKK->k_bond_atom.modify(); +atom_vec_charge_kokkos.cpp: k_count.modify(); +atom_vec_charge_kokkos.cpp: if (mask & X_MASK) atomKK->k_x.modify(); +atom_vec_charge_kokkos.cpp: if (mask & V_MASK) atomKK->k_v.modify(); +atom_vec_charge_kokkos.cpp: if (mask & F_MASK) atomKK->k_f.modify(); +atom_vec_charge_kokkos.cpp: if (mask & TAG_MASK) atomKK->k_tag.modify(); +atom_vec_charge_kokkos.cpp: if (mask & TYPE_MASK) atomKK->k_type.modify(); +atom_vec_charge_kokkos.cpp: if (mask & MASK_MASK) atomKK->k_mask.modify(); +atom_vec_charge_kokkos.cpp: if (mask & IMAGE_MASK) atomKK->k_image.modify(); +atom_vec_charge_kokkos.cpp: if (mask & Q_MASK) atomKK->k_q.modify(); +atom_vec_full_kokkos.cpp: k_count.modify(); +atom_vec_full_kokkos.cpp: if (mask & X_MASK) atomKK->k_x.modify(); +atom_vec_full_kokkos.cpp: if (mask & V_MASK) atomKK->k_v.modify(); +atom_vec_full_kokkos.cpp: if (mask & F_MASK) atomKK->k_f.modify(); +atom_vec_full_kokkos.cpp: if (mask & TAG_MASK) atomKK->k_tag.modify(); +atom_vec_full_kokkos.cpp: if (mask & TYPE_MASK) atomKK->k_type.modify(); +atom_vec_full_kokkos.cpp: if (mask & MASK_MASK) atomKK->k_mask.modify(); +atom_vec_full_kokkos.cpp: if (mask & IMAGE_MASK) atomKK->k_image.modify(); +atom_vec_full_kokkos.cpp: if (mask & Q_MASK) atomKK->k_q.modify(); +atom_vec_full_kokkos.cpp: if (mask & MOLECULE_MASK) atomKK->k_molecule.modify(); +atom_vec_full_kokkos.cpp: atomKK->k_nspecial.modify(); +atom_vec_full_kokkos.cpp: atomKK->k_special.modify(); +atom_vec_full_kokkos.cpp: atomKK->k_num_bond.modify(); +atom_vec_full_kokkos.cpp: atomKK->k_bond_type.modify(); +atom_vec_full_kokkos.cpp: atomKK->k_bond_atom.modify(); +atom_vec_full_kokkos.cpp: atomKK->k_num_angle.modify(); +atom_vec_full_kokkos.cpp: atomKK->k_angle_type.modify(); +atom_vec_full_kokkos.cpp: atomKK->k_angle_atom1.modify(); +atom_vec_full_kokkos.cpp: atomKK->k_angle_atom2.modify(); +atom_vec_full_kokkos.cpp: atomKK->k_angle_atom3.modify(); +atom_vec_full_kokkos.cpp: atomKK->k_num_dihedral.modify(); +atom_vec_full_kokkos.cpp: atomKK->k_dihedral_type.modify(); +atom_vec_full_kokkos.cpp: atomKK->k_dihedral_atom1.modify(); +atom_vec_full_kokkos.cpp: atomKK->k_dihedral_atom2.modify(); +atom_vec_full_kokkos.cpp: atomKK->k_dihedral_atom3.modify(); +atom_vec_full_kokkos.cpp: atomKK->k_dihedral_atom4.modify(); +atom_vec_full_kokkos.cpp: atomKK->k_num_improper.modify(); +atom_vec_full_kokkos.cpp: atomKK->k_improper_type.modify(); +atom_vec_full_kokkos.cpp: atomKK->k_improper_atom1.modify(); +atom_vec_full_kokkos.cpp: atomKK->k_improper_atom2.modify(); +atom_vec_full_kokkos.cpp: atomKK->k_improper_atom3.modify(); +atom_vec_full_kokkos.cpp: atomKK->k_improper_atom4.modify(); +atom_vec_molecular_kokkos.cpp: k_count.modify(); +atom_vec_molecular_kokkos.cpp: if (mask & X_MASK) atomKK->k_x.modify(); +atom_vec_molecular_kokkos.cpp: if (mask & V_MASK) atomKK->k_v.modify(); +atom_vec_molecular_kokkos.cpp: if (mask & F_MASK) atomKK->k_f.modify(); +atom_vec_molecular_kokkos.cpp: if (mask & TAG_MASK) atomKK->k_tag.modify(); +atom_vec_molecular_kokkos.cpp: if (mask & TYPE_MASK) atomKK->k_type.modify(); +atom_vec_molecular_kokkos.cpp: if (mask & MASK_MASK) atomKK->k_mask.modify(); +atom_vec_molecular_kokkos.cpp: if (mask & IMAGE_MASK) atomKK->k_image.modify(); +atom_vec_molecular_kokkos.cpp: if (mask & MOLECULE_MASK) atomKK->k_molecule.modify(); +atom_vec_molecular_kokkos.cpp: atomKK->k_nspecial.modify(); +atom_vec_molecular_kokkos.cpp: atomKK->k_special.modify(); +atom_vec_molecular_kokkos.cpp: atomKK->k_num_bond.modify(); +atom_vec_molecular_kokkos.cpp: atomKK->k_bond_type.modify(); +atom_vec_molecular_kokkos.cpp: atomKK->k_bond_atom.modify(); +atom_vec_molecular_kokkos.cpp: atomKK->k_num_angle.modify(); +atom_vec_molecular_kokkos.cpp: atomKK->k_angle_type.modify(); +atom_vec_molecular_kokkos.cpp: atomKK->k_angle_atom1.modify(); +atom_vec_molecular_kokkos.cpp: atomKK->k_angle_atom2.modify(); +atom_vec_molecular_kokkos.cpp: atomKK->k_angle_atom3.modify(); +atom_vec_molecular_kokkos.cpp: atomKK->k_num_dihedral.modify(); +atom_vec_molecular_kokkos.cpp: atomKK->k_dihedral_type.modify(); +atom_vec_molecular_kokkos.cpp: atomKK->k_dihedral_atom1.modify(); +atom_vec_molecular_kokkos.cpp: atomKK->k_dihedral_atom2.modify(); +atom_vec_molecular_kokkos.cpp: atomKK->k_dihedral_atom3.modify(); +atom_vec_molecular_kokkos.cpp: atomKK->k_dihedral_atom4.modify(); +atom_vec_molecular_kokkos.cpp: atomKK->k_num_improper.modify(); +atom_vec_molecular_kokkos.cpp: atomKK->k_improper_type.modify(); +atom_vec_molecular_kokkos.cpp: atomKK->k_improper_atom1.modify(); +atom_vec_molecular_kokkos.cpp: atomKK->k_improper_atom2.modify(); +atom_vec_molecular_kokkos.cpp: atomKK->k_improper_atom3.modify(); +atom_vec_molecular_kokkos.cpp: atomKK->k_improper_atom4.modify(); +comm_kokkos.cpp: k_buf_send.modify(); +neighbor_kokkos.cpp: k_bondlist.modify(); +neighbor_kokkos.cpp: k_anglelist.modify(); +neighbor_kokkos.cpp: k_dihedrallist.modify(); +neighbor_kokkos.cpp: k_improperlist.modify(); +verlet_kokkos.cpp: atomKK->k_f.modify(); diff --git a/src/KOKKOS/region_block_kokkos.cpp b/src/KOKKOS/region_block_kokkos.cpp index 6734d7fdd1..90fd47ab06 100644 --- a/src/KOKKOS/region_block_kokkos.cpp +++ b/src/KOKKOS/region_block_kokkos.cpp @@ -54,10 +54,10 @@ int RegBlockKokkos::k_inside(double x, double y, double z) const } template -void RegBlockKokkos::match_all_kokkos(int groupbit_in, DAT::t_int_1d d_match_in) +void RegBlockKokkos::match_all_kokkos(int groupbit_in, DAT::tdual_int_1d k_match_in) { groupbit = groupbit_in; - d_match = d_match_in; + d_match = k_match_in.template view(); atomKK->sync(Device, X_MASK | MASK_MASK); @@ -69,6 +69,8 @@ void RegBlockKokkos::match_all_kokkos(int groupbit_in, DAT::t_int_1d Kokkos::parallel_for(Kokkos::RangePolicy(0,nlocal),*this); DeviceType::fence(); copymode = 0; + + k_match_in.template modify(); } template diff --git a/src/KOKKOS/region_block_kokkos.h b/src/KOKKOS/region_block_kokkos.h index f570e3ed33..e14ac4d0c0 100644 --- a/src/KOKKOS/region_block_kokkos.h +++ b/src/KOKKOS/region_block_kokkos.h @@ -39,14 +39,14 @@ class RegBlockKokkos : public RegBlock { RegBlockKokkos(class LAMMPS *, int, char **); ~RegBlockKokkos(); - void match_all_kokkos(int, DAT::t_int_1d); + void match_all_kokkos(int, DAT::tdual_int_1d); KOKKOS_INLINE_FUNCTION void operator()(TagRegBlockMatchAll, const int&) const; private: int groupbit; - DAT::t_int_1d d_match; + typename AT::t_int_1d d_match; typename AT::t_x_array_randomread x; typename AT::t_int_1d_randomread mask; diff --git a/src/accelerator_kokkos.h b/src/accelerator_kokkos.h index d9794023b0..8ea5b9d4d2 100644 --- a/src/accelerator_kokkos.h +++ b/src/accelerator_kokkos.h @@ -99,7 +99,7 @@ class DAT { public: typedef double tdual_xfloat_1d; typedef double tdual_FFT_SCALAR_1d; - typedef int t_int_1d; + typedef int tdual_int_1d; typedef int tdual_int_2d; }; diff --git a/src/region.cpp b/src/region.cpp index e69fdc79d5..d2ef481cb7 100644 --- a/src/region.cpp +++ b/src/region.cpp @@ -146,7 +146,7 @@ int Region::match(double x, double y, double z) generate error if Kokkos function defaults to base class ------------------------------------------------------------------------- */ -void Region::match_all_kokkos(int, DAT::t_int_1d) +void Region::match_all_kokkos(int, DAT::tdual_int_1d) { error->all(FLERR,"Can only use Kokkos supported regions with Kokkos package"); } diff --git a/src/region.h b/src/region.h index 9c693bfcd5..5b4238acb4 100644 --- a/src/region.h +++ b/src/region.h @@ -99,7 +99,7 @@ class Region : protected Pointers { // Kokkos function, implemented by each Kokkos region - virtual void match_all_kokkos(int, DAT::t_int_1d); + virtual void match_all_kokkos(int, DAT::tdual_int_1d); protected: void add_contact(int, double *, double, double, double); From d3fa882280a93affd1b55223395200feba7f7b3d Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 25 Jul 2017 13:49:23 -0600 Subject: [PATCH 342/439] Fix execution space issues in Kokkos EAM pairstyles --- src/KOKKOS/pair_eam_alloy_kokkos.cpp | 4 ++-- src/KOKKOS/pair_eam_fs_kokkos.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/KOKKOS/pair_eam_alloy_kokkos.cpp b/src/KOKKOS/pair_eam_alloy_kokkos.cpp index b7e0175147..aa68d0a054 100644 --- a/src/KOKKOS/pair_eam_alloy_kokkos.cpp +++ b/src/KOKKOS/pair_eam_alloy_kokkos.cpp @@ -405,7 +405,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; } @@ -423,7 +423,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 diff --git a/src/KOKKOS/pair_eam_fs_kokkos.cpp b/src/KOKKOS/pair_eam_fs_kokkos.cpp index 982082937e..a982f94ec4 100644 --- a/src/KOKKOS/pair_eam_fs_kokkos.cpp +++ b/src/KOKKOS/pair_eam_fs_kokkos.cpp @@ -405,7 +405,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; } @@ -423,7 +423,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 From c3c9f357fdfa6753eaa056bc17a3fe0dd3aaaa6a Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 25 Jul 2017 14:37:41 -0600 Subject: [PATCH 343/439] Fix concurrent modification issue in comm_kokkos --- src/KOKKOS/comm_kokkos.cpp | 1 + src/KOKKOS/out.txt | 119 ------------------------------------- 2 files changed, 1 insertion(+), 119 deletions(-) delete mode 100644 src/KOKKOS/out.txt diff --git a/src/KOKKOS/comm_kokkos.cpp b/src/KOKKOS/comm_kokkos.cpp index f38a6c21c9..2b19908396 100644 --- a/src/KOKKOS/comm_kokkos.cpp +++ b/src/KOKKOS/comm_kokkos.cpp @@ -488,6 +488,7 @@ void CommKokkos::exchange_device() if (true) { if (k_sendflag.h_view.dimension_0()(); k_count.h_view(0) = k_exchange_sendlist.h_view.dimension_0(); while (k_count.h_view(0)>=k_exchange_sendlist.h_view.dimension_0()) { k_count.h_view(0) = 0; diff --git a/src/KOKKOS/out.txt b/src/KOKKOS/out.txt deleted file mode 100644 index 0452e263ab..0000000000 --- a/src/KOKKOS/out.txt +++ /dev/null @@ -1,119 +0,0 @@ -atom_vec_angle_kokkos.cpp: k_count.modify(); -atom_vec_angle_kokkos.cpp: if (mask & X_MASK) atomKK->k_x.modify(); -atom_vec_angle_kokkos.cpp: if (mask & V_MASK) atomKK->k_v.modify(); -atom_vec_angle_kokkos.cpp: if (mask & F_MASK) atomKK->k_f.modify(); -atom_vec_angle_kokkos.cpp: if (mask & TAG_MASK) atomKK->k_tag.modify(); -atom_vec_angle_kokkos.cpp: if (mask & TYPE_MASK) atomKK->k_type.modify(); -atom_vec_angle_kokkos.cpp: if (mask & MASK_MASK) atomKK->k_mask.modify(); -atom_vec_angle_kokkos.cpp: if (mask & IMAGE_MASK) atomKK->k_image.modify(); -atom_vec_angle_kokkos.cpp: if (mask & MOLECULE_MASK) atomKK->k_molecule.modify(); -atom_vec_angle_kokkos.cpp: atomKK->k_nspecial.modify(); -atom_vec_angle_kokkos.cpp: atomKK->k_special.modify(); -atom_vec_angle_kokkos.cpp: atomKK->k_num_bond.modify(); -atom_vec_angle_kokkos.cpp: atomKK->k_bond_type.modify(); -atom_vec_angle_kokkos.cpp: atomKK->k_bond_atom.modify(); -atom_vec_angle_kokkos.cpp: atomKK->k_num_angle.modify(); -atom_vec_angle_kokkos.cpp: atomKK->k_angle_type.modify(); -atom_vec_angle_kokkos.cpp: atomKK->k_angle_atom1.modify(); -atom_vec_angle_kokkos.cpp: atomKK->k_angle_atom2.modify(); -atom_vec_angle_kokkos.cpp: atomKK->k_angle_atom3.modify(); -atom_vec_atomic_kokkos.cpp: k_count.modify(); -atom_vec_atomic_kokkos.cpp: if (mask & X_MASK) atomKK->k_x.modify(); -atom_vec_atomic_kokkos.cpp: if (mask & V_MASK) atomKK->k_v.modify(); -atom_vec_atomic_kokkos.cpp: if (mask & F_MASK) atomKK->k_f.modify(); -atom_vec_atomic_kokkos.cpp: if (mask & TAG_MASK) atomKK->k_tag.modify(); -atom_vec_atomic_kokkos.cpp: if (mask & TYPE_MASK) atomKK->k_type.modify(); -atom_vec_atomic_kokkos.cpp: if (mask & MASK_MASK) atomKK->k_mask.modify(); -atom_vec_atomic_kokkos.cpp: if (mask & IMAGE_MASK) atomKK->k_image.modify(); -atom_vec_bond_kokkos.cpp: k_count.modify(); -atom_vec_bond_kokkos.cpp: if (mask & X_MASK) atomKK->k_x.modify(); -atom_vec_bond_kokkos.cpp: if (mask & V_MASK) atomKK->k_v.modify(); -atom_vec_bond_kokkos.cpp: if (mask & F_MASK) atomKK->k_f.modify(); -atom_vec_bond_kokkos.cpp: if (mask & TAG_MASK) atomKK->k_tag.modify(); -atom_vec_bond_kokkos.cpp: if (mask & TYPE_MASK) atomKK->k_type.modify(); -atom_vec_bond_kokkos.cpp: if (mask & MASK_MASK) atomKK->k_mask.modify(); -atom_vec_bond_kokkos.cpp: if (mask & IMAGE_MASK) atomKK->k_image.modify(); -atom_vec_bond_kokkos.cpp: if (mask & MOLECULE_MASK) atomKK->k_molecule.modify(); -atom_vec_bond_kokkos.cpp: atomKK->k_nspecial.modify(); -atom_vec_bond_kokkos.cpp: atomKK->k_special.modify(); -atom_vec_bond_kokkos.cpp: atomKK->k_num_bond.modify(); -atom_vec_bond_kokkos.cpp: atomKK->k_bond_type.modify(); -atom_vec_bond_kokkos.cpp: atomKK->k_bond_atom.modify(); -atom_vec_charge_kokkos.cpp: k_count.modify(); -atom_vec_charge_kokkos.cpp: if (mask & X_MASK) atomKK->k_x.modify(); -atom_vec_charge_kokkos.cpp: if (mask & V_MASK) atomKK->k_v.modify(); -atom_vec_charge_kokkos.cpp: if (mask & F_MASK) atomKK->k_f.modify(); -atom_vec_charge_kokkos.cpp: if (mask & TAG_MASK) atomKK->k_tag.modify(); -atom_vec_charge_kokkos.cpp: if (mask & TYPE_MASK) atomKK->k_type.modify(); -atom_vec_charge_kokkos.cpp: if (mask & MASK_MASK) atomKK->k_mask.modify(); -atom_vec_charge_kokkos.cpp: if (mask & IMAGE_MASK) atomKK->k_image.modify(); -atom_vec_charge_kokkos.cpp: if (mask & Q_MASK) atomKK->k_q.modify(); -atom_vec_full_kokkos.cpp: k_count.modify(); -atom_vec_full_kokkos.cpp: if (mask & X_MASK) atomKK->k_x.modify(); -atom_vec_full_kokkos.cpp: if (mask & V_MASK) atomKK->k_v.modify(); -atom_vec_full_kokkos.cpp: if (mask & F_MASK) atomKK->k_f.modify(); -atom_vec_full_kokkos.cpp: if (mask & TAG_MASK) atomKK->k_tag.modify(); -atom_vec_full_kokkos.cpp: if (mask & TYPE_MASK) atomKK->k_type.modify(); -atom_vec_full_kokkos.cpp: if (mask & MASK_MASK) atomKK->k_mask.modify(); -atom_vec_full_kokkos.cpp: if (mask & IMAGE_MASK) atomKK->k_image.modify(); -atom_vec_full_kokkos.cpp: if (mask & Q_MASK) atomKK->k_q.modify(); -atom_vec_full_kokkos.cpp: if (mask & MOLECULE_MASK) atomKK->k_molecule.modify(); -atom_vec_full_kokkos.cpp: atomKK->k_nspecial.modify(); -atom_vec_full_kokkos.cpp: atomKK->k_special.modify(); -atom_vec_full_kokkos.cpp: atomKK->k_num_bond.modify(); -atom_vec_full_kokkos.cpp: atomKK->k_bond_type.modify(); -atom_vec_full_kokkos.cpp: atomKK->k_bond_atom.modify(); -atom_vec_full_kokkos.cpp: atomKK->k_num_angle.modify(); -atom_vec_full_kokkos.cpp: atomKK->k_angle_type.modify(); -atom_vec_full_kokkos.cpp: atomKK->k_angle_atom1.modify(); -atom_vec_full_kokkos.cpp: atomKK->k_angle_atom2.modify(); -atom_vec_full_kokkos.cpp: atomKK->k_angle_atom3.modify(); -atom_vec_full_kokkos.cpp: atomKK->k_num_dihedral.modify(); -atom_vec_full_kokkos.cpp: atomKK->k_dihedral_type.modify(); -atom_vec_full_kokkos.cpp: atomKK->k_dihedral_atom1.modify(); -atom_vec_full_kokkos.cpp: atomKK->k_dihedral_atom2.modify(); -atom_vec_full_kokkos.cpp: atomKK->k_dihedral_atom3.modify(); -atom_vec_full_kokkos.cpp: atomKK->k_dihedral_atom4.modify(); -atom_vec_full_kokkos.cpp: atomKK->k_num_improper.modify(); -atom_vec_full_kokkos.cpp: atomKK->k_improper_type.modify(); -atom_vec_full_kokkos.cpp: atomKK->k_improper_atom1.modify(); -atom_vec_full_kokkos.cpp: atomKK->k_improper_atom2.modify(); -atom_vec_full_kokkos.cpp: atomKK->k_improper_atom3.modify(); -atom_vec_full_kokkos.cpp: atomKK->k_improper_atom4.modify(); -atom_vec_molecular_kokkos.cpp: k_count.modify(); -atom_vec_molecular_kokkos.cpp: if (mask & X_MASK) atomKK->k_x.modify(); -atom_vec_molecular_kokkos.cpp: if (mask & V_MASK) atomKK->k_v.modify(); -atom_vec_molecular_kokkos.cpp: if (mask & F_MASK) atomKK->k_f.modify(); -atom_vec_molecular_kokkos.cpp: if (mask & TAG_MASK) atomKK->k_tag.modify(); -atom_vec_molecular_kokkos.cpp: if (mask & TYPE_MASK) atomKK->k_type.modify(); -atom_vec_molecular_kokkos.cpp: if (mask & MASK_MASK) atomKK->k_mask.modify(); -atom_vec_molecular_kokkos.cpp: if (mask & IMAGE_MASK) atomKK->k_image.modify(); -atom_vec_molecular_kokkos.cpp: if (mask & MOLECULE_MASK) atomKK->k_molecule.modify(); -atom_vec_molecular_kokkos.cpp: atomKK->k_nspecial.modify(); -atom_vec_molecular_kokkos.cpp: atomKK->k_special.modify(); -atom_vec_molecular_kokkos.cpp: atomKK->k_num_bond.modify(); -atom_vec_molecular_kokkos.cpp: atomKK->k_bond_type.modify(); -atom_vec_molecular_kokkos.cpp: atomKK->k_bond_atom.modify(); -atom_vec_molecular_kokkos.cpp: atomKK->k_num_angle.modify(); -atom_vec_molecular_kokkos.cpp: atomKK->k_angle_type.modify(); -atom_vec_molecular_kokkos.cpp: atomKK->k_angle_atom1.modify(); -atom_vec_molecular_kokkos.cpp: atomKK->k_angle_atom2.modify(); -atom_vec_molecular_kokkos.cpp: atomKK->k_angle_atom3.modify(); -atom_vec_molecular_kokkos.cpp: atomKK->k_num_dihedral.modify(); -atom_vec_molecular_kokkos.cpp: atomKK->k_dihedral_type.modify(); -atom_vec_molecular_kokkos.cpp: atomKK->k_dihedral_atom1.modify(); -atom_vec_molecular_kokkos.cpp: atomKK->k_dihedral_atom2.modify(); -atom_vec_molecular_kokkos.cpp: atomKK->k_dihedral_atom3.modify(); -atom_vec_molecular_kokkos.cpp: atomKK->k_dihedral_atom4.modify(); -atom_vec_molecular_kokkos.cpp: atomKK->k_num_improper.modify(); -atom_vec_molecular_kokkos.cpp: atomKK->k_improper_type.modify(); -atom_vec_molecular_kokkos.cpp: atomKK->k_improper_atom1.modify(); -atom_vec_molecular_kokkos.cpp: atomKK->k_improper_atom2.modify(); -atom_vec_molecular_kokkos.cpp: atomKK->k_improper_atom3.modify(); -atom_vec_molecular_kokkos.cpp: atomKK->k_improper_atom4.modify(); -comm_kokkos.cpp: k_buf_send.modify(); -neighbor_kokkos.cpp: k_bondlist.modify(); -neighbor_kokkos.cpp: k_anglelist.modify(); -neighbor_kokkos.cpp: k_dihedrallist.modify(); -neighbor_kokkos.cpp: k_improperlist.modify(); -verlet_kokkos.cpp: atomKK->k_f.modify(); From 0231cc38a35e1d38a800305cd32cef12bae113b1 Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Tue, 25 Jul 2017 19:09:20 -0600 Subject: [PATCH 344/439] cmake: some more typo fixes --- cmake/CMakeLists.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 15a87b7f6e..d691386c05 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -18,10 +18,10 @@ list(REMOVE_ITEM LIB_SOURCES ${LMP_SOURCES}) # Cmake modules/macros are in a subdirectory to keep this file cleaner set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/Modules) -if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_C_FLAGS) +if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CXX_FLAGS) #release comes with -O3 by default set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel." FORCE) -endif(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_C_FLAGS) +endif(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CXX_FLAGS) foreach(STYLE_FILE style_angle.h style_atom.h style_body.h style_bond.h style_command.h style_compute.h style_dihedral.h style_dump.h style_fix.h style_improper.h style_integrate.h style_kspace.h style_minimize.h style_nbin.h style_npair.h style_nstencil.h @@ -498,7 +498,7 @@ if(ENABLE_GPU) endforeach() list(REMOVE_ITEM GPU_OBJS "${CU_FORBIDDEN_OBJ}") list(APPEND LIB_SOURCES ${GPU_SOURCES} ${GPU_LIB_SOURCES} ${GPU_LIB_CUDPP_SOURCES} ${GPU_OBJS}) - set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${AMMPS_LIB_BINARY_DIR}/gpu/*_cubin.h") + set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${LAMMPS_LIB_BINARY_DIR}/gpu/*_cubin.h") endif() ###################################################### @@ -529,7 +529,7 @@ add_executable(lmp ${LMP_SOURCES}) target_link_libraries(lmp lammps) install(TARGETS lmp DESTINATION ${CMAKE_INSTALL_BINDIR}) if(ENABLE_TESTING) - add_test(ShowHelp lmp -help) + add_test(ShowHelp ${CMAKE_CURRENT_BINARY_DIR}/lmp -help) endif() ################################## From 8f59c0e188b9dc0d03621a58a78b81a16cd05546 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Thu, 27 Jul 2017 08:51:17 -0600 Subject: [PATCH 345/439] Fix modify/sync issue in neigh_bond_kokkos --- src/KOKKOS/neigh_bond_kokkos.cpp | 16 ++++++++++++++++ src/KOKKOS/neighbor_kokkos.cpp | 20 -------------------- 2 files changed, 16 insertions(+), 20 deletions(-) diff --git a/src/KOKKOS/neigh_bond_kokkos.cpp b/src/KOKKOS/neigh_bond_kokkos.cpp index 767def70c2..ca7dc1582b 100644 --- a/src/KOKKOS/neigh_bond_kokkos.cpp +++ b/src/KOKKOS/neigh_bond_kokkos.cpp @@ -307,6 +307,8 @@ void NeighBondKokkos::bond_all() "Bond atoms missing at step " BIGINT_FORMAT,update->ntimestep); if (me == 0) error->warning(FLERR,str); } + + k_bondlist.modify(); } template @@ -401,6 +403,8 @@ void NeighBondKokkos::bond_partial() "Bond atoms missing at step " BIGINT_FORMAT,update->ntimestep); if (me == 0) error->warning(FLERR,str); } + + k_bondlist.modify(); } template @@ -521,6 +525,8 @@ void NeighBondKokkos::angle_all() "Angle atoms missing at step " BIGINT_FORMAT,update->ntimestep); if (me == 0) error->warning(FLERR,str); } + + k_anglelist.modify(); } template @@ -622,6 +628,8 @@ void NeighBondKokkos::angle_partial() "Angle atoms missing at step " BIGINT_FORMAT,update->ntimestep); if (me == 0) error->warning(FLERR,str); } + + k_anglelist.modify(); } template @@ -762,6 +770,8 @@ void NeighBondKokkos::dihedral_all() "Dihedral atoms missing at step " BIGINT_FORMAT,update->ntimestep); if (me == 0) error->warning(FLERR,str); } + + k_dihedrallist.modify(); } template @@ -868,6 +878,8 @@ void NeighBondKokkos::dihedral_partial() "Dihedral atoms missing at step " BIGINT_FORMAT,update->ntimestep); if (me == 0) error->warning(FLERR,str); } + + k_dihedrallist.modify(); } template @@ -1030,6 +1042,8 @@ void NeighBondKokkos::improper_all() "Improper atoms missing at step " BIGINT_FORMAT,update->ntimestep); if (me == 0) error->warning(FLERR,str); } + + k_improperlist.modify(); } template @@ -1136,6 +1150,8 @@ void NeighBondKokkos::improper_partial() "Improper atoms missing at step " BIGINT_FORMAT,update->ntimestep); if (me == 0) error->warning(FLERR,str); } + + k_improperlist.modify(); } template diff --git a/src/KOKKOS/neighbor_kokkos.cpp b/src/KOKKOS/neighbor_kokkos.cpp index e40e6a238c..8eda7ee55c 100644 --- a/src/KOKKOS/neighbor_kokkos.cpp +++ b/src/KOKKOS/neighbor_kokkos.cpp @@ -387,16 +387,6 @@ void NeighborKokkos::build_topology() { k_dihedrallist = neighbond_device.k_dihedrallist; k_improperlist = neighbond_device.k_improperlist; - k_bondlist.sync(); - k_anglelist.sync(); - k_dihedrallist.sync(); - k_improperlist.sync(); - - k_bondlist.modify(); - k_anglelist.modify(); - k_dihedrallist.modify(); - k_improperlist.modify(); - // Transfer topology neighbor lists to Host for non-Kokkos styles if (force->bond && force->bond->execution_space == Host) @@ -415,15 +405,5 @@ void NeighborKokkos::build_topology() { k_anglelist = neighbond_host.k_anglelist; k_dihedrallist = neighbond_host.k_dihedrallist; k_improperlist = neighbond_host.k_improperlist; - - k_bondlist.sync(); - k_anglelist.sync(); - k_dihedrallist.sync(); - k_improperlist.sync(); - - k_bondlist.modify(); - k_anglelist.modify(); - k_dihedrallist.modify(); - k_improperlist.modify(); } } From 8e834d8be149fced6868362b8585ecb316e78be5 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Thu, 27 Jul 2017 09:37:16 -0600 Subject: [PATCH 346/439] Add missing sync to neigh_bond_kokkos --- src/KOKKOS/neigh_bond_kokkos.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/KOKKOS/neigh_bond_kokkos.cpp b/src/KOKKOS/neigh_bond_kokkos.cpp index ca7dc1582b..a8c230fa59 100644 --- a/src/KOKKOS/neigh_bond_kokkos.cpp +++ b/src/KOKKOS/neigh_bond_kokkos.cpp @@ -439,6 +439,8 @@ void NeighBondKokkos::bond_check() int flag = 0; update_domain_variables(); + atomKK->sync(execution_space, X_MASK); + k_bondlist.sync(); Kokkos::parallel_reduce(Kokkos::RangePolicy(0,neighbor->nbondlist),*this,flag); DeviceType::fence(); @@ -672,6 +674,8 @@ void NeighBondKokkos::angle_check() // in case angle potential computes any of them update_domain_variables(); + atomKK->sync(execution_space, X_MASK); + k_anglelist.sync(); Kokkos::parallel_reduce(Kokkos::RangePolicy(0,neighbor->nanglelist),*this,flag); DeviceType::fence(); @@ -927,6 +931,8 @@ void NeighBondKokkos::dihedral_check(int nlist, typename AT::t_int_2 // in case dihedral/improper potential computes any of them update_domain_variables(); + atomKK->sync(execution_space, X_MASK); + k_dihedrallist.sync(); Kokkos::parallel_reduce(Kokkos::RangePolicy(0,nlist),*this,flag); DeviceType::fence(); From 7edb294b447c62d3d2dbd4f9df984fb8d14f9a7c Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 28 Jul 2017 10:44:08 -0600 Subject: [PATCH 347/439] Fix execution space issues in comm_kokkos --- src/KOKKOS/comm_kokkos.cpp | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/src/KOKKOS/comm_kokkos.cpp b/src/KOKKOS/comm_kokkos.cpp index 2b19908396..adc8da501c 100644 --- a/src/KOKKOS/comm_kokkos.cpp +++ b/src/KOKKOS/comm_kokkos.cpp @@ -472,8 +472,6 @@ void CommKokkos::exchange_device() subhi = domain->subhi_lamda; } - atomKK->sync(ExecutionSpaceFromDevice::space,ALL_MASK); - // loop over dimensions for (int dim = 0; dim < 3; dim++) { @@ -602,8 +600,6 @@ void CommKokkos::exchange_device() } - atomKK->modified(ExecutionSpaceFromDevice::space,ALL_MASK); - if (atom->firstgroupname) { /* this is not yet implemented with Kokkos */ atomKK->sync(Host,ALL_MASK); @@ -704,8 +700,8 @@ void CommKokkos::borders_device() { AtomVecKokkos *avec = (AtomVecKokkos *) atom->avec; ExecutionSpace exec_space = ExecutionSpaceFromDevice::space; - k_sendlist.modify(); - atomKK->sync(exec_space,ALL_MASK); + k_sendlist.sync(); + atomKK->sync(exec_space,X_MASK); // do swaps over all 3 dimensions @@ -754,12 +750,10 @@ void CommKokkos::borders_device() { if (sendflag) { if (!bordergroup || ineed >= 2) { if (style == SINGLE) { - typename ArrayTypes::tdual_int_1d total_send("TS",1); + DAT::tdual_int_1d total_send("TS",1); total_send.h_view(0) = 0; - if(exec_space == Device) { - total_send.template modify(); - total_send.template sync(); - } + total_send.template modify(); + total_send.template sync(); BuildBorderListFunctor f(atomKK->k_x,k_sendlist, total_send,nfirst,nlast,dim,lo,hi,iswap,maxsendlist[iswap]); @@ -773,16 +767,17 @@ void CommKokkos::borders_device() { if(total_send.h_view(0) >= maxsendlist[iswap]) { grow_list(iswap,total_send.h_view(0)); k_sendlist.modify(); + total_send.h_view(0) = 0; - if(exec_space == Device) { - total_send.template modify(); - total_send.template sync(); - } + total_send.template modify(); + total_send.template sync(); + BuildBorderListFunctor f(atomKK->k_x,k_sendlist, total_send,nfirst,nlast,dim,lo,hi,iswap,maxsendlist[iswap]); Kokkos::TeamPolicy config((nlast-nfirst+127)/128,128); Kokkos::parallel_for(config,f); DeviceType::fence(); + total_send.template modify(); total_send.template sync(); } @@ -909,9 +904,7 @@ void CommKokkos::borders_device() { // reset global->local map - if (exec_space == Host) k_sendlist.sync(); - atomKK->modified(exec_space,ALL_MASK); - DeviceType::fence(); + k_sendlist.template modify(); atomKK->sync(Host,TAG_MASK); if (map_style) atom->map_set(); } From 13f2d39f55b17515b9637eaf4a24536d1c203f62 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Mon, 31 Jul 2017 10:34:21 -0600 Subject: [PATCH 348/439] Update Kokkos library to v2.03.13 --- lib/kokkos/CHANGELOG.md | 41 + lib/kokkos/Makefile.kokkos | 75 +- lib/kokkos/Makefile.targets | 8 +- .../algorithms/unit_tests/TestOpenMP.cpp | 13 +- .../algorithms/unit_tests/TestRandom.hpp | 38 +- .../algorithms/unit_tests/UnitTestMain.cpp | 8 +- .../benchmarks/bytes_and_flops/main.cpp | 9 +- lib/kokkos/benchmarks/gather/main.cpp | 2 +- .../benchmarks/policy_performance/Makefile | 44 + .../benchmarks/policy_performance/main.cpp | 170 + .../policy_performance/policy_perf_test.hpp | 354 + .../script_basic_testing.sh | 53 + .../policy_performance/script_sample_usage.sh | 126 + lib/kokkos/bin/hpcbind | 454 + lib/kokkos/bin/kokkos-bind | 221 + lib/kokkos/bin/runtest | 165 + lib/kokkos/cmake/kokkos.cmake | 4 + lib/kokkos/config/master_history.txt | 1 + lib/kokkos/config/query_cuda_arch.cpp | 24 + lib/kokkos/config/test_all_sandia | 11 +- .../shepard_jenkins_run_script_pthread_intel | 6 +- .../shepard_jenkins_run_script_serial_intel | 6 +- .../containers/performance_tests/Makefile | 1 - .../containers/performance_tests/TestMain.cpp | 11 +- .../performance_tests/TestOpenMP.cpp | 21 +- lib/kokkos/containers/src/Kokkos_DualView.hpp | 2 +- .../containers/src/Kokkos_DynRankView.hpp | 98 +- .../containers/src/Kokkos_DynamicView.hpp | 30 +- lib/kokkos/containers/unit_tests/TestCuda.cpp | 6 + .../containers/unit_tests/TestOpenMP.cpp | 15 +- .../containers/unit_tests/TestSerial.cpp | 6 + .../containers/unit_tests/TestThreads.cpp | 6 + .../TestViewCtorPropEmbeddedDim.hpp | 213 + .../containers/unit_tests/UnitTestMain.cpp | 10 +- lib/kokkos/core/perf_test/Makefile | 1 - lib/kokkos/core/perf_test/PerfTestMain.cpp | 10 +- .../KokkosExp_Cuda_IterateTile_Refactor.hpp | 2715 +++ lib/kokkos/core/src/Cuda/Kokkos_CudaExec.hpp | 108 +- lib/kokkos/core/src/Cuda/Kokkos_CudaSpace.cpp | 96 +- lib/kokkos/core/src/Cuda/Kokkos_Cuda_Impl.cpp | 85 +- .../core/src/Cuda/Kokkos_Cuda_Locks.cpp | 119 + .../core/src/Cuda/Kokkos_Cuda_Locks.hpp | 166 + .../core/src/Cuda/Kokkos_Cuda_Parallel.hpp | 404 +- .../core/src/Cuda/Kokkos_Cuda_ReduceScan.hpp | 19 +- lib/kokkos/core/src/Cuda/Kokkos_Cuda_Task.cpp | 128 +- lib/kokkos/core/src/Cuda/Kokkos_Cuda_Task.hpp | 23 +- lib/kokkos/core/src/Cuda/Kokkos_Cuda_Team.hpp | 26 +- .../core/src/Cuda/Kokkos_Cuda_UniqueToken.hpp | 133 + lib/kokkos/core/src/Cuda/Kokkos_Cuda_View.hpp | 6 +- .../src/Cuda/Kokkos_Cuda_WorkGraphPolicy.hpp | 119 + .../core/src/KokkosExp_MDRangePolicy.hpp | 175 +- lib/kokkos/core/src/Kokkos_Atomic.hpp | 33 +- lib/kokkos/core/src/Kokkos_Concepts.hpp | 16 + lib/kokkos/core/src/Kokkos_Core.hpp | 15 +- lib/kokkos/core/src/Kokkos_Core_fwd.hpp | 3 + lib/kokkos/core/src/Kokkos_Crs.hpp | 333 + lib/kokkos/core/src/Kokkos_Cuda.hpp | 3 +- lib/kokkos/core/src/Kokkos_CudaSpace.hpp | 6 +- lib/kokkos/core/src/Kokkos_ExecPolicy.hpp | 40 + lib/kokkos/core/src/Kokkos_HBWSpace.hpp | 8 - lib/kokkos/core/src/Kokkos_HostSpace.hpp | 10 +- lib/kokkos/core/src/Kokkos_Layout.hpp | 2 + lib/kokkos/core/src/Kokkos_Macros.hpp | 11 +- lib/kokkos/core/src/Kokkos_MasterLock.hpp | 73 + lib/kokkos/core/src/Kokkos_MemoryPool.hpp | 182 +- lib/kokkos/core/src/Kokkos_MemoryTraits.hpp | 16 +- lib/kokkos/core/src/Kokkos_OpenMP.hpp | 172 +- lib/kokkos/core/src/Kokkos_Parallel.hpp | 64 +- .../core/src/Kokkos_Parallel_Reduce.hpp | 19 +- lib/kokkos/core/src/Kokkos_Serial.hpp | 228 + lib/kokkos/core/src/Kokkos_TaskScheduler.hpp | 108 +- lib/kokkos/core/src/Kokkos_UniqueToken.hpp | 88 + lib/kokkos/core/src/Kokkos_View.hpp | 233 +- .../core/src/Kokkos_WorkGraphPolicy.hpp | 265 + .../core/src/OpenMP/Kokkos_OpenMP_Exec.cpp | 431 +- .../core/src/OpenMP/Kokkos_OpenMP_Exec.hpp | 490 +- .../src/OpenMP/Kokkos_OpenMP_Parallel.hpp | 419 +- .../core/src/OpenMP/Kokkos_OpenMP_Task.cpp | 94 +- .../core/src/OpenMP/Kokkos_OpenMP_Task.hpp | 4 +- .../core/src/OpenMP/Kokkos_OpenMP_Team.hpp | 245 + .../OpenMP/Kokkos_OpenMP_WorkGraphPolicy.hpp | 107 + .../OpenMPTarget/Kokkos_OpenMPTarget_Exec.hpp | 28 +- .../core/src/Qthreads/Kokkos_QthreadsExec.hpp | 2 +- .../core/src/Threads/Kokkos_ThreadsExec.cpp | 12 +- .../core/src/Threads/Kokkos_ThreadsExec.hpp | 70 +- .../core/src/Threads/Kokkos_ThreadsTeam.hpp | 6 +- .../src/Threads/Kokkos_Threads_Parallel.hpp | 267 + .../Kokkos_Threads_WorkGraphPolicy.hpp | 115 + .../src/impl/KokkosExp_Host_IterateTile.hpp | 566 +- .../core/src/impl/Kokkos_AnalyzePolicy.hpp | 35 +- .../Kokkos_Atomic_Compare_Exchange_Strong.hpp | 34 +- .../core/src/impl/Kokkos_Atomic_Decrement.hpp | 19 + .../core/src/impl/Kokkos_Atomic_Exchange.hpp | 32 + .../core/src/impl/Kokkos_Atomic_Fetch_Add.hpp | 62 +- .../core/src/impl/Kokkos_Atomic_Fetch_And.hpp | 32 +- .../core/src/impl/Kokkos_Atomic_Fetch_Or.hpp | 32 +- .../core/src/impl/Kokkos_Atomic_Fetch_Sub.hpp | 44 +- .../core/src/impl/Kokkos_Atomic_Increment.hpp | 16 + lib/kokkos/core/src/impl/Kokkos_Core.cpp | 20 +- .../core/src/impl/Kokkos_FunctorAdapter.hpp | 13 +- lib/kokkos/core/src/impl/Kokkos_HBWSpace.cpp | 56 - lib/kokkos/core/src/impl/Kokkos_HostSpace.cpp | 59 - .../core/src/impl/Kokkos_HostThreadTeam.cpp | 30 +- .../core/src/impl/Kokkos_HostThreadTeam.hpp | 33 +- .../src/impl/Kokkos_Profiling_Interface.cpp | 102 +- .../src/impl/Kokkos_Profiling_Interface.hpp | 53 +- .../core/src/impl/Kokkos_Rendezvous.cpp | 208 + .../core/src/impl/Kokkos_Rendezvous.hpp | 87 + lib/kokkos/core/src/impl/Kokkos_Serial.cpp | 4 +- .../core/src/impl/Kokkos_Serial_Task.cpp | 4 +- .../core/src/impl/Kokkos_Serial_Task.hpp | 2 +- .../impl/Kokkos_Serial_WorkGraphPolicy.hpp | 102 + .../core/src/impl/Kokkos_SharedAlloc.cpp | 24 +- .../core/src/impl/Kokkos_SharedAlloc.hpp | 16 +- lib/kokkos/core/src/impl/Kokkos_Spinwait.cpp | 210 + ...okkos_spinwait.hpp => Kokkos_Spinwait.hpp} | 17 + lib/kokkos/core/src/impl/Kokkos_TaskQueue.hpp | 606 +- .../core/src/impl/Kokkos_TaskQueue_impl.hpp | 86 +- lib/kokkos/core/src/impl/Kokkos_ViewArray.hpp | 14 +- lib/kokkos/core/src/impl/Kokkos_ViewCtor.hpp | 21 + .../core/src/impl/Kokkos_ViewMapping.hpp | 137 +- lib/kokkos/core/src/impl/Kokkos_ViewTile.hpp | 12 +- lib/kokkos/core/src/impl/Kokkos_spinwait.cpp | 183 - lib/kokkos/core/unit_test/CMakeLists.txt | 6 + lib/kokkos/core/unit_test/Makefile | 8 +- lib/kokkos/core/unit_test/TestAggregate.hpp | 2 +- .../unit_test/TestDefaultDeviceTypeInit.hpp | 21 +- lib/kokkos/core/unit_test/TestMDRange.hpp | 882 +- lib/kokkos/core/unit_test/TestMemoryPool.hpp | 228 +- lib/kokkos/core/unit_test/TestRange.hpp | 25 + lib/kokkos/core/unit_test/TestResize.hpp | 140 + .../core/unit_test/TestTaskScheduler.hpp | 32 +- lib/kokkos/core/unit_test/TestTeamVector.hpp | 12 + lib/kokkos/core/unit_test/TestTile.hpp | 2 +- lib/kokkos/core/unit_test/TestUniqueToken.hpp | 138 + .../unit_test/TestViewCtorPropEmbeddedDim.hpp | 160 + .../core/unit_test/TestViewMapping_a.hpp | 114 +- lib/kokkos/core/unit_test/TestViewSubview.hpp | 224 +- lib/kokkos/core/unit_test/TestWorkGraph.hpp | 172 + lib/kokkos/core/unit_test/UnitTestMain.cpp | 1 + .../core/unit_test/UnitTestMainInit.cpp | 2 + .../core/unit_test/cuda/TestCuda_Other.cpp | 2 + .../unit_test/cuda/TestCuda_UniqueToken.cpp | 46 + .../unit_test/cuda/TestCuda_WorkGraph.cpp | 45 + .../default/TestDefaultDeviceTypeResize.cpp | 57 + .../core/unit_test/openmp/TestOpenMP.hpp | 19 +- .../unit_test/openmp/TestOpenMP_Other.cpp | 90 + .../openmp/TestOpenMP_UniqueToken.cpp | 46 + .../unit_test/openmp/TestOpenMP_WorkGraph.cpp | 45 + .../unit_test/serial/TestSerial_Other.cpp | 2 + .../unit_test/serial/TestSerial_WorkGraph.cpp | 45 + .../unit_test/threads/TestThreads_Other.cpp | 2 + .../threads/TestThreads_WorkGraph.cpp | 45 + lib/kokkos/example/cmake_build/CMakeLists.txt | 2 + lib/kokkos/example/feint/main.cpp | 22 +- .../example/global_2_local_ids/G2L_Main.cpp | 11 +- lib/kokkos/example/grow_array/main.cpp | 2 +- .../example/tutorial/03_simple_view/Makefile | 1 + .../example/tutorial/Advanced_Views/Makefile | 86 +- .../example/tutorial/Algorithms/Makefile | 12 +- .../Hierarchical_Parallelism/Makefile | 60 +- lib/kokkos/example/tutorial/Makefile | 132 +- .../tutorial/launch_bounds/CMakeLists.txt | 10 + .../example/tutorial/launch_bounds/Makefile | 56 + .../launch_bounds/launch_bounds_reduce.cpp | 173 + lib/kokkos/generate_makefile.bash | 191 +- lib/kokkos/tpls/gtest/gtest/LICENSE | 28 + lib/kokkos/tpls/gtest/gtest/README | 13 + lib/kokkos/tpls/gtest/gtest/gtest-all.cc | 9594 ++++++++ lib/kokkos/tpls/gtest/gtest/gtest-test-part.h | 1 + lib/kokkos/tpls/gtest/gtest/gtest.h | 20065 ++++++++++++++++ 171 files changed, 44039 insertions(+), 2807 deletions(-) create mode 100644 lib/kokkos/benchmarks/policy_performance/Makefile create mode 100644 lib/kokkos/benchmarks/policy_performance/main.cpp create mode 100644 lib/kokkos/benchmarks/policy_performance/policy_perf_test.hpp create mode 100755 lib/kokkos/benchmarks/policy_performance/script_basic_testing.sh create mode 100755 lib/kokkos/benchmarks/policy_performance/script_sample_usage.sh create mode 100755 lib/kokkos/bin/hpcbind create mode 100755 lib/kokkos/bin/kokkos-bind create mode 100755 lib/kokkos/bin/runtest create mode 100644 lib/kokkos/config/query_cuda_arch.cpp create mode 100644 lib/kokkos/containers/unit_tests/TestViewCtorPropEmbeddedDim.hpp create mode 100644 lib/kokkos/core/src/Cuda/KokkosExp_Cuda_IterateTile_Refactor.hpp create mode 100644 lib/kokkos/core/src/Cuda/Kokkos_Cuda_Locks.cpp create mode 100644 lib/kokkos/core/src/Cuda/Kokkos_Cuda_Locks.hpp create mode 100644 lib/kokkos/core/src/Cuda/Kokkos_Cuda_UniqueToken.hpp create mode 100644 lib/kokkos/core/src/Cuda/Kokkos_Cuda_WorkGraphPolicy.hpp create mode 100644 lib/kokkos/core/src/Kokkos_Crs.hpp create mode 100644 lib/kokkos/core/src/Kokkos_MasterLock.hpp create mode 100644 lib/kokkos/core/src/Kokkos_UniqueToken.hpp create mode 100644 lib/kokkos/core/src/Kokkos_WorkGraphPolicy.hpp create mode 100644 lib/kokkos/core/src/OpenMP/Kokkos_OpenMP_Team.hpp create mode 100644 lib/kokkos/core/src/OpenMP/Kokkos_OpenMP_WorkGraphPolicy.hpp create mode 100644 lib/kokkos/core/src/Threads/Kokkos_Threads_WorkGraphPolicy.hpp create mode 100644 lib/kokkos/core/src/impl/Kokkos_Rendezvous.cpp create mode 100644 lib/kokkos/core/src/impl/Kokkos_Rendezvous.hpp create mode 100644 lib/kokkos/core/src/impl/Kokkos_Serial_WorkGraphPolicy.hpp create mode 100644 lib/kokkos/core/src/impl/Kokkos_Spinwait.cpp rename lib/kokkos/core/src/impl/{Kokkos_spinwait.hpp => Kokkos_Spinwait.hpp} (82%) delete mode 100644 lib/kokkos/core/src/impl/Kokkos_spinwait.cpp create mode 100644 lib/kokkos/core/unit_test/TestResize.hpp create mode 100644 lib/kokkos/core/unit_test/TestUniqueToken.hpp create mode 100644 lib/kokkos/core/unit_test/TestViewCtorPropEmbeddedDim.hpp create mode 100644 lib/kokkos/core/unit_test/TestWorkGraph.hpp create mode 100644 lib/kokkos/core/unit_test/cuda/TestCuda_UniqueToken.cpp create mode 100644 lib/kokkos/core/unit_test/cuda/TestCuda_WorkGraph.cpp create mode 100644 lib/kokkos/core/unit_test/default/TestDefaultDeviceTypeResize.cpp create mode 100644 lib/kokkos/core/unit_test/openmp/TestOpenMP_UniqueToken.cpp create mode 100644 lib/kokkos/core/unit_test/openmp/TestOpenMP_WorkGraph.cpp create mode 100644 lib/kokkos/core/unit_test/serial/TestSerial_WorkGraph.cpp create mode 100644 lib/kokkos/core/unit_test/threads/TestThreads_WorkGraph.cpp create mode 100644 lib/kokkos/example/tutorial/launch_bounds/CMakeLists.txt create mode 100644 lib/kokkos/example/tutorial/launch_bounds/Makefile create mode 100644 lib/kokkos/example/tutorial/launch_bounds/launch_bounds_reduce.cpp create mode 100644 lib/kokkos/tpls/gtest/gtest/LICENSE create mode 100644 lib/kokkos/tpls/gtest/gtest/README create mode 100644 lib/kokkos/tpls/gtest/gtest/gtest-all.cc create mode 120000 lib/kokkos/tpls/gtest/gtest/gtest-test-part.h create mode 100644 lib/kokkos/tpls/gtest/gtest/gtest.h diff --git a/lib/kokkos/CHANGELOG.md b/lib/kokkos/CHANGELOG.md index acb54ff22f..3fe9e46111 100644 --- a/lib/kokkos/CHANGELOG.md +++ b/lib/kokkos/CHANGELOG.md @@ -1,5 +1,46 @@ # Change Log +## [2.03.13](https://github.com/kokkos/kokkos/tree/2.03.13) (2017-07-27) +[Full Changelog](https://github.com/kokkos/kokkos/compare/2.03.05...2.03.13) + +**Implemented enhancements:** + +- Disallow enabling both OpenMP and Threads in the same executable [\#406](https://github.com/kokkos/kokkos/issues/406) +- Make Kokkos::OpenMP respect OMP environment even if hwloc is available [\#630](https://github.com/kokkos/kokkos/issues/630) +- Improve Atomics Performance on KNL/Broadwell where PREFETCHW/RFO is Available [\#898](https://github.com/kokkos/kokkos/issues/898) +- Kokkos::resize should test whether dimensions have changed before resizing [\#904](https://github.com/kokkos/kokkos/issues/904) +- Develop performance-regression/acceptance tests [\#737](https://github.com/kokkos/kokkos/issues/737) +- Make the deep\_copy Profiling hook a start/end system [\#890](https://github.com/kokkos/kokkos/issues/890) +- Add deep\_copy Profiling hook [\#843](https://github.com/kokkos/kokkos/issues/843) +- Append tag name to parallel construct name for Profiling [\#842](https://github.com/kokkos/kokkos/issues/842) +- Add view label to `View bounds error` message for CUDA backend [\#870](https://github.com/kokkos/kokkos/issues/870) +- Disable printing the loaded profiling library [\#824](https://github.com/kokkos/kokkos/issues/824) +- "Declared but never referenced" warnings [\#853](https://github.com/kokkos/kokkos/issues/853) +- Warnings about lock\_address\_cuda\_space [\#852](https://github.com/kokkos/kokkos/issues/852) +- WorkGraph execution policy [\#771](https://github.com/kokkos/kokkos/issues/771) +- Simplify makefiles by guarding compilation with appropriate KOKKOS\_ENABLE\_\#\#\# macros [\#716](https://github.com/kokkos/kokkos/issues/716) +- Cmake build: wrong include install directory [\#668](https://github.com/kokkos/kokkos/issues/668) +- Derived View type and allocation [\#566](https://github.com/kokkos/kokkos/issues/566) +- Fix Compiler warnings when compiling core unit tests for Cuda [\#214](https://github.com/kokkos/kokkos/issues/214) + +**Fixed bugs:** + +- Out-of-bounds read in Kokkos\_Layout.hpp [\#975](https://github.com/kokkos/kokkos/issues/975) +- CudaClang: Fix failing test with Clang 4.0 [\#941](https://github.com/kokkos/kokkos/issues/941) +- Respawn when memory pool allocation fails \(not available memory\) [\#940](https://github.com/kokkos/kokkos/issues/940) +- Memory pool aborts on zero allocation request, returns NULL for \< minimum [\#939](https://github.com/kokkos/kokkos/issues/939) +- Error with TaskScheduler query of underlying memory pool [\#917](https://github.com/kokkos/kokkos/issues/917) +- Profiling::\*Callee static variables declared in header [\#863](https://github.com/kokkos/kokkos/issues/863) +- calling \*Space::name\(\) causes compile error [\#862](https://github.com/kokkos/kokkos/issues/862) +- bug in Profiling::deallocateData [\#860](https://github.com/kokkos/kokkos/issues/860) +- task\_depend test failing, CUDA 8.0 + Pascal + RDC [\#829](https://github.com/kokkos/kokkos/issues/829) +- \[develop branch\] Standalone cmake issues [\#826](https://github.com/kokkos/kokkos/issues/826) +- Kokkos CUDA failes to compile with OMPI\_CXX and MPICH\_CXX wrappers [\#776](https://github.com/kokkos/kokkos/issues/776) +- Task Team reduction on Pascal [\#767](https://github.com/kokkos/kokkos/issues/767) +- CUDA stack overflow with TaskDAG test [\#758](https://github.com/kokkos/kokkos/issues/758) +- TeamVector test on Cuda [\#670](https://github.com/kokkos/kokkos/issues/670) +- Clang 4.0 Cuda Build broken again [\#560](https://github.com/kokkos/kokkos/issues/560) + ## [2.03.05](https://github.com/kokkos/kokkos/tree/2.03.05) (2017-05-27) [Full Changelog](https://github.com/kokkos/kokkos/compare/2.03.00...2.03.05) diff --git a/lib/kokkos/Makefile.kokkos b/lib/kokkos/Makefile.kokkos index 24cd772e00..acb6c36134 100644 --- a/lib/kokkos/Makefile.kokkos +++ b/lib/kokkos/Makefile.kokkos @@ -33,6 +33,7 @@ KOKKOS_INTERNAL_USE_LIBRT := $(strip $(shell echo $(KOKKOS_USE_TPLS) | grep "lib KOKKOS_INTERNAL_USE_MEMKIND := $(strip $(shell echo $(KOKKOS_USE_TPLS) | grep "experimental_memkind" | wc -l)) # Check for advanced settings. +KOKKOS_INTERNAL_ENABLE_COMPILER_WARNINGS := $(strip $(shell echo $(KOKKOS_OPTIONS) | grep "compiler_warnings" | wc -l)) KOKKOS_INTERNAL_OPT_RANGE_AGGRESSIVE_VECTORIZATION := $(strip $(shell echo $(KOKKOS_OPTIONS) | grep "aggressive_vectorization" | wc -l)) KOKKOS_INTERNAL_DISABLE_PROFILING := $(strip $(shell echo $(KOKKOS_OPTIONS) | grep "disable_profiling" | wc -l)) KOKKOS_INTERNAL_DISABLE_DUALVIEW_MODIFY_CHECK := $(strip $(shell echo $(KOKKOS_OPTIONS) | grep "disable_dualview_modify_check" | wc -l)) @@ -78,6 +79,12 @@ KOKKOS_INTERNAL_COMPILER_PGI := $(strip $(shell $(CXX) --version 2 KOKKOS_INTERNAL_COMPILER_XL := $(strip $(shell $(CXX) -qversion 2>&1 | grep XL | wc -l)) KOKKOS_INTERNAL_COMPILER_CRAY := $(strip $(shell $(CXX) -craype-verbose 2>&1 | grep "CC-" | wc -l)) KOKKOS_INTERNAL_COMPILER_NVCC := $(strip $(shell $(CXX) --version 2>&1 | grep nvcc | wc -l)) +ifneq ($(OMPI_CXX),) + KOKKOS_INTERNAL_COMPILER_NVCC := $(strip $(shell $(OMPI_CXX) --version 2>&1 | grep nvcc | wc -l)) +endif +ifneq ($(MPICH_CXX),) + KOKKOS_INTERNAL_COMPILER_NVCC := $(strip $(shell $(MPICH_CXX) --version 2>&1 | grep nvcc | wc -l)) +endif KOKKOS_INTERNAL_COMPILER_CLANG := $(strip $(shell $(CXX) --version 2>&1 | grep clang | wc -l)) KOKKOS_INTERNAL_COMPILER_APPLE_CLANG := $(strip $(shell $(CXX) --version 2>&1 | grep "apple-darwin" | wc -l)) ifneq ($(OMPI_CXX),) @@ -111,6 +118,36 @@ ifeq ($(KOKKOS_INTERNAL_COMPILER_CLANG), 1) endif endif +# Set compiler warnings flags. +ifeq ($(KOKKOS_INTERNAL_ENABLE_COMPILER_WARNINGS), 1) + ifeq ($(KOKKOS_INTERNAL_COMPILER_PGI), 1) + # TODO check if PGI accepts GNU style warnings + KOKKOS_INTERNAL_COMPILER_WARNINGS = + else + ifeq ($(KOKKOS_INTERNAL_COMPILER_CLANG), 1) + KOKKOS_INTERNAL_COMPILER_WARNINGS = -Wall -Wshadow -pedantic -Wsign-compare -Wtype-limits -Wuninitialized + else + ifeq ($(KOKKOS_INTERNAL_COMPILER_APPLE_CLANG), 1) + KOKKOS_INTERNAL_COMPILER_WARNINGS = -Wall -Wshadow -pedantic -Wsign-compare -Wtype-limits -Wuninitialized + else + ifeq ($(KOKKOS_INTERNAL_COMPILER_XL), 1) + KOKKOS_INTERNAL_COMPILER_WARNINGS = -Wall -Wshadow -pedantic -Wsign-compare -Wtype-limits -Wuninitialized + else + ifeq ($(KOKKOS_INTERNAL_COMPILER_CRAY), 1) + # TODO check if cray accepts GNU style warnings + KOKKOS_INTERNAL_COMPILER_WARNINGS = + else + #gcc + KOKKOS_INTERNAL_COMPILER_WARNINGS = -Wall -Wshadow -pedantic -Wsign-compare -Wtype-limits -Wignored-qualifiers -Wempty-body -Wclobbered -Wuninitialized + endif + endif + endif + endif + endif +else + KOKKOS_INTERNAL_COMPILER_WARNINGS = +endif + # Set OpenMP flags. ifeq ($(KOKKOS_INTERNAL_COMPILER_PGI), 1) KOKKOS_INTERNAL_OPENMP_FLAG := -mp @@ -162,6 +199,7 @@ endif # Intel based. KOKKOS_INTERNAL_USE_ARCH_KNC := $(strip $(shell echo $(KOKKOS_ARCH) | grep KNC | wc -l)) +KOKKOS_INTERNAL_USE_ARCH_WSM := $(strip $(shell echo $(KOKKOS_ARCH) | grep WSM | wc -l)) KOKKOS_INTERNAL_USE_ARCH_SNB := $(strip $(shell echo $(KOKKOS_ARCH) | grep SNB | wc -l)) KOKKOS_INTERNAL_USE_ARCH_HSW := $(strip $(shell echo $(KOKKOS_ARCH) | grep HSW | wc -l)) KOKKOS_INTERNAL_USE_ARCH_BDW := $(strip $(shell echo $(KOKKOS_ARCH) | grep BDW | wc -l)) @@ -229,13 +267,14 @@ KOKKOS_INTERNAL_USE_ARCH_IBM := $(strip $(shell echo $(KOKKOS_INTERNAL_USE_ARCH_ KOKKOS_INTERNAL_USE_ARCH_AMDAVX := $(strip $(shell echo $(KOKKOS_ARCH) | grep AMDAVX | wc -l)) # Any AVX? +KOKKOS_INTERNAL_USE_ARCH_SSE42 := $(strip $(shell echo $(KOKKOS_INTERNAL_USE_ARCH_WSM) | bc )) KOKKOS_INTERNAL_USE_ARCH_AVX := $(strip $(shell echo $(KOKKOS_INTERNAL_USE_ARCH_SNB)+$(KOKKOS_INTERNAL_USE_ARCH_AMDAVX) | bc )) KOKKOS_INTERNAL_USE_ARCH_AVX2 := $(strip $(shell echo $(KOKKOS_INTERNAL_USE_ARCH_HSW)+$(KOKKOS_INTERNAL_USE_ARCH_BDW) | bc )) KOKKOS_INTERNAL_USE_ARCH_AVX512MIC := $(strip $(shell echo $(KOKKOS_INTERNAL_USE_ARCH_KNL) | bc )) KOKKOS_INTERNAL_USE_ARCH_AVX512XEON := $(strip $(shell echo $(KOKKOS_INTERNAL_USE_ARCH_SKX) | bc )) # Decide what ISA level we are able to support. -KOKKOS_INTERNAL_USE_ISA_X86_64 := $(strip $(shell echo $(KOKKOS_INTERNAL_USE_ARCH_SNB)+$(KOKKOS_INTERNAL_USE_ARCH_HSW)+$(KOKKOS_INTERNAL_USE_ARCH_BDW)+$(KOKKOS_INTERNAL_USE_ARCH_KNL)+$(KOKKOS_INTERNAL_USE_ARCH_SKX) | bc )) +KOKKOS_INTERNAL_USE_ISA_X86_64 := $(strip $(shell echo $(KOKKOS_INTERNAL_USE_ARCH_WSM)+$(KOKKOS_INTERNAL_USE_ARCH_SNB)+$(KOKKOS_INTERNAL_USE_ARCH_HSW)+$(KOKKOS_INTERNAL_USE_ARCH_BDW)+$(KOKKOS_INTERNAL_USE_ARCH_KNL)+$(KOKKOS_INTERNAL_USE_ARCH_SKX) | bc )) KOKKOS_INTERNAL_USE_ISA_KNC := $(strip $(shell echo $(KOKKOS_INTERNAL_USE_ARCH_KNC) | bc )) KOKKOS_INTERNAL_USE_ISA_POWERPCLE := $(strip $(shell echo $(KOKKOS_INTERNAL_USE_ARCH_POWER8)+$(KOKKOS_INTERNAL_USE_ARCH_POWER9) | bc )) @@ -243,7 +282,7 @@ KOKKOS_INTERNAL_USE_ISA_POWERPCLE := $(strip $(shell echo $(KOKKOS_INTERNAL_USE_ KOKKOS_INTERNAL_USE_TM := $(strip $(shell echo $(KOKKOS_INTERNAL_USE_ARCH_BDW)+$(KOKKOS_INTERNAL_USE_ARCH_SKX) | bc )) # Incompatible flags? -KOKKOS_INTERNAL_USE_ARCH_MULTIHOST := $(strip $(shell echo "$(KOKKOS_INTERNAL_USE_ARCH_AVX)+$(KOKKOS_INTERNAL_USE_ARCH_AVX2)+$(KOKKOS_INTERNAL_USE_ARCH_AVX512MIC)+$(KOKKOS_INTERNAL_USE_ARCH_AVX512XEON)+$(KOKKOS_INTERNAL_USE_ARCH_KNC)+$(KOKKOS_INTERNAL_USE_ARCH_IBM)+$(KOKKOS_INTERNAL_USE_ARCH_ARM)>1" | bc )) +KOKKOS_INTERNAL_USE_ARCH_MULTIHOST := $(strip $(shell echo "$(KOKKOS_INTERNAL_USE_ARCH_SSE42)+$(KOKKOS_INTERNAL_USE_ARCH_AVX)+$(KOKKOS_INTERNAL_USE_ARCH_AVX2)+$(KOKKOS_INTERNAL_USE_ARCH_AVX512MIC)+$(KOKKOS_INTERNAL_USE_ARCH_AVX512XEON)+$(KOKKOS_INTERNAL_USE_ARCH_KNC)+$(KOKKOS_INTERNAL_USE_ARCH_IBM)+$(KOKKOS_INTERNAL_USE_ARCH_ARM)>1" | bc )) KOKKOS_INTERNAL_USE_ARCH_MULTIGPU := $(strip $(shell echo "$(KOKKOS_INTERNAL_USE_ARCH_NVIDIA)>1" | bc)) ifeq ($(KOKKOS_INTERNAL_USE_ARCH_MULTIHOST), 1) @@ -257,12 +296,10 @@ endif KOKKOS_CPPFLAGS = -I./ -I$(KOKKOS_PATH)/core/src -I$(KOKKOS_PATH)/containers/src -I$(KOKKOS_PATH)/algorithms/src -# No warnings: KOKKOS_CXXFLAGS = -# INTEL and CLANG warnings: -#KOKKOS_CXXFLAGS = -Wall -Wshadow -pedantic -Wsign-compare -Wtype-limits -Wuninitialized -# GCC warnings: -#KOKKOS_CXXFLAGS = -Wall -Wshadow -pedantic -Wsign-compare -Wtype-limits -Wuninitialized -Wignored-qualifiers -Wempty-body -Wclobbered +ifeq ($(KOKKOS_INTERNAL_ENABLE_COMPILER_WARNINGS), 1) + KOKKOS_CXXFLAGS += $(KOKKOS_INTERNAL_COMPILER_WARNINGS) +endif KOKKOS_LIBS = -lkokkos -ldl KOKKOS_LDFLAGS = -L$(shell pwd) @@ -486,6 +523,28 @@ ifeq ($(KOKKOS_INTERNAL_USE_ARCH_ARMV8_THUNDERX), 1) endif endif +ifeq ($(KOKKOS_INTERNAL_USE_ARCH_SSE42), 1) + tmp := $(shell echo "\#define KOKKOS_ARCH_SSE42 1" >> KokkosCore_config.tmp ) + + ifeq ($(KOKKOS_INTERNAL_COMPILER_INTEL), 1) + KOKKOS_CXXFLAGS += -xSSE4.2 + KOKKOS_LDFLAGS += -xSSE4.2 + else + ifeq ($(KOKKOS_INTERNAL_COMPILER_CRAY), 1) + + else + ifeq ($(KOKKOS_INTERNAL_COMPILER_PGI), 1) + KOKKOS_CXXFLAGS += -tp=nehalem + KOKKOS_LDFLAGS += -tp=nehalem + else + # Assume that this is a really a GNU compiler. + KOKKOS_CXXFLAGS += -msse4.2 + KOKKOS_LDFLAGS += -msse4.2 + endif + endif + endif +endif + ifeq ($(KOKKOS_INTERNAL_USE_ARCH_AVX), 1) tmp := $(shell echo "\#define KOKKOS_ARCH_AVX 1" >> KokkosCore_config.tmp ) @@ -689,7 +748,7 @@ ifeq ($(KOKKOS_INTERNAL_USE_CUDA), 1) endif endif -KOKKOS_INTERNAL_LS_CONFIG := $(shell ls KokkosCore_config.h) +KOKKOS_INTERNAL_LS_CONFIG := $(shell ls KokkosCore_config.h 2>&1) ifeq ($(KOKKOS_INTERNAL_LS_CONFIG), KokkosCore_config.h) KOKKOS_INTERNAL_NEW_CONFIG := $(strip $(shell diff KokkosCore_config.h KokkosCore_config.tmp | grep define | wc -l)) else diff --git a/lib/kokkos/Makefile.targets b/lib/kokkos/Makefile.targets index 3cb52a04cd..a9341a907c 100644 --- a/lib/kokkos/Makefile.targets +++ b/lib/kokkos/Makefile.targets @@ -20,8 +20,10 @@ Kokkos_TaskQueue.o: $(KOKKOS_CPP_DEPENDS) $(KOKKOS_PATH)/core/src/impl/Kokkos_Ta $(CXX) $(KOKKOS_CPPFLAGS) $(KOKKOS_CXXFLAGS) $(CXXFLAGS) -c $(KOKKOS_PATH)/core/src/impl/Kokkos_TaskQueue.cpp Kokkos_HostThreadTeam.o: $(KOKKOS_CPP_DEPENDS) $(KOKKOS_PATH)/core/src/impl/Kokkos_HostThreadTeam.cpp $(CXX) $(KOKKOS_CPPFLAGS) $(KOKKOS_CXXFLAGS) $(CXXFLAGS) -c $(KOKKOS_PATH)/core/src/impl/Kokkos_HostThreadTeam.cpp -Kokkos_spinwait.o: $(KOKKOS_CPP_DEPENDS) $(KOKKOS_PATH)/core/src/impl/Kokkos_spinwait.cpp - $(CXX) $(KOKKOS_CPPFLAGS) $(KOKKOS_CXXFLAGS) $(CXXFLAGS) -c $(KOKKOS_PATH)/core/src/impl/Kokkos_spinwait.cpp +Kokkos_Spinwait.o: $(KOKKOS_CPP_DEPENDS) $(KOKKOS_PATH)/core/src/impl/Kokkos_Spinwait.cpp + $(CXX) $(KOKKOS_CPPFLAGS) $(KOKKOS_CXXFLAGS) $(CXXFLAGS) -c $(KOKKOS_PATH)/core/src/impl/Kokkos_Spinwait.cpp +Kokkos_Rendezvous.o: $(KOKKOS_CPP_DEPENDS) $(KOKKOS_PATH)/core/src/impl/Kokkos_Rendezvous.cpp + $(CXX) $(KOKKOS_CPPFLAGS) $(KOKKOS_CXXFLAGS) $(CXXFLAGS) -c $(KOKKOS_PATH)/core/src/impl/Kokkos_Rendezvous.cpp Kokkos_Profiling_Interface.o: $(KOKKOS_CPP_DEPENDS) $(KOKKOS_PATH)/core/src/impl/Kokkos_Profiling_Interface.cpp $(CXX) $(KOKKOS_CPPFLAGS) $(KOKKOS_CXXFLAGS) $(CXXFLAGS) -c $(KOKKOS_PATH)/core/src/impl/Kokkos_Profiling_Interface.cpp Kokkos_SharedAlloc.o: $(KOKKOS_CPP_DEPENDS) $(KOKKOS_PATH)/core/src/impl/Kokkos_SharedAlloc.cpp @@ -36,6 +38,8 @@ Kokkos_CudaSpace.o: $(KOKKOS_CPP_DEPENDS) $(KOKKOS_PATH)/core/src/Cuda/Kokkos_Cu $(CXX) $(KOKKOS_CPPFLAGS) $(KOKKOS_CXXFLAGS) $(CXXFLAGS) -c $(KOKKOS_PATH)/core/src/Cuda/Kokkos_CudaSpace.cpp Kokkos_Cuda_Task.o: $(KOKKOS_CPP_DEPENDS) $(KOKKOS_PATH)/core/src/Cuda/Kokkos_Cuda_Task.cpp $(CXX) $(KOKKOS_CPPFLAGS) $(KOKKOS_CXXFLAGS) $(CXXFLAGS) -c $(KOKKOS_PATH)/core/src/Cuda/Kokkos_Cuda_Task.cpp +Kokkos_Cuda_Locks.o: $(KOKKOS_CPP_DEPENDS) $(KOKKOS_PATH)/core/src/Cuda/Kokkos_Cuda_Locks.cpp + $(CXX) $(KOKKOS_CPPFLAGS) $(KOKKOS_CXXFLAGS) $(CXXFLAGS) -c $(KOKKOS_PATH)/core/src/Cuda/Kokkos_Cuda_Locks.cpp endif ifeq ($(KOKKOS_INTERNAL_USE_PTHREADS), 1) diff --git a/lib/kokkos/algorithms/unit_tests/TestOpenMP.cpp b/lib/kokkos/algorithms/unit_tests/TestOpenMP.cpp index 1e7ee68549..c2c118ce1a 100644 --- a/lib/kokkos/algorithms/unit_tests/TestOpenMP.cpp +++ b/lib/kokkos/algorithms/unit_tests/TestOpenMP.cpp @@ -61,14 +61,19 @@ protected: { std::cout << std::setprecision(5) << std::scientific; - unsigned threads_count = omp_get_max_threads(); + int threads_count = 0; + #pragma omp parallel + { + #pragma omp atomic + ++threads_count; + } - if ( Kokkos::hwloc::available() ) { - threads_count = Kokkos::hwloc::get_available_numa_count() * - Kokkos::hwloc::get_available_cores_per_numa(); + if (threads_count > 3) { + threads_count /= 2; } Kokkos::OpenMP::initialize( threads_count ); + Kokkos::OpenMP::print_configuration( std::cout ); } static void TearDownTestCase() diff --git a/lib/kokkos/algorithms/unit_tests/TestRandom.hpp b/lib/kokkos/algorithms/unit_tests/TestRandom.hpp index 9cf02f74b4..2771f1793d 100644 --- a/lib/kokkos/algorithms/unit_tests/TestRandom.hpp +++ b/lib/kokkos/algorithms/unit_tests/TestRandom.hpp @@ -1,12 +1,12 @@ //@HEADER // ************************************************************************ -// +// // Kokkos v. 2.0 // Copyright (2014) Sandia Corporation -// +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: @@ -35,7 +35,7 @@ // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) -// +// // ************************************************************************ //@HEADER @@ -283,12 +283,12 @@ struct test_random_scalar { RandomGenerator& pool, unsigned int num_draws) { - using std::cerr; + using std::cout; using std::endl; using Kokkos::parallel_reduce; { - cerr << " -- Testing randomness properties" << endl; + cout << " -- Testing randomness properties" << endl; RandomProperties result; typedef test_random_functor functor_type; @@ -307,7 +307,7 @@ struct test_random_scalar { ( 1.5*tolerance > variance_eps)) ? 1:0; pass_covar = ((-2.0*tolerance < covariance_eps) && ( 2.0*tolerance > covariance_eps)) ? 1:0; - cerr << "Pass: " << pass_mean + cout << "Pass: " << pass_mean << " " << pass_var << " " << mean_eps << " " << variance_eps @@ -315,7 +315,7 @@ struct test_random_scalar { << " || " << tolerance << endl; } { - cerr << " -- Testing 1-D histogram" << endl; + cout << " -- Testing 1-D histogram" << endl; RandomProperties result; typedef test_histogram1d_functor functor_type; @@ -335,7 +335,7 @@ struct test_random_scalar { pass_hist1d_covar = ((-0.06 < covariance_eps) && ( 0.06 > covariance_eps)) ? 1:0; - cerr << "Density 1D: " << mean_eps + cout << "Density 1D: " << mean_eps << " " << variance_eps << " " << (result.covariance/HIST_DIM1D/HIST_DIM1D) << " || " << tolerance @@ -348,7 +348,7 @@ struct test_random_scalar { << endl; } { - cerr << " -- Testing 3-D histogram" << endl; + cout << " -- Testing 3-D histogram" << endl; RandomProperties result; typedef test_histogram3d_functor functor_type; @@ -368,7 +368,7 @@ struct test_random_scalar { pass_hist3d_covar = ((-tolerance < covariance_eps) && ( tolerance > covariance_eps)) ? 1:0; - cerr << "Density 3D: " << mean_eps + cout << "Density 3D: " << mean_eps << " " << variance_eps << " " << result.covariance/HIST_DIM1D/HIST_DIM1D << " || " << tolerance @@ -381,18 +381,18 @@ struct test_random_scalar { template void test_random(unsigned int num_draws) { - using std::cerr; + using std::cout; using std::endl; typename test_random_functor::type_1d density_1d("D1d"); typename test_random_functor::type_3d density_3d("D3d"); uint64_t ticks = std::chrono::high_resolution_clock::now().time_since_epoch().count(); - cerr << "Test Seed:" << ticks << endl; + cout << "Test Seed:" << ticks << endl; RandomGenerator pool(ticks); - cerr << "Test Scalar=int" << endl; + cout << "Test Scalar=int" << endl; test_random_scalar test_int(density_1d,density_3d,pool,num_draws); ASSERT_EQ( test_int.pass_mean,1); ASSERT_EQ( test_int.pass_var,1); @@ -406,7 +406,7 @@ void test_random(unsigned int num_draws) deep_copy(density_1d,0); deep_copy(density_3d,0); - cerr << "Test Scalar=unsigned int" << endl; + cout << "Test Scalar=unsigned int" << endl; test_random_scalar test_uint(density_1d,density_3d,pool,num_draws); ASSERT_EQ( test_uint.pass_mean,1); ASSERT_EQ( test_uint.pass_var,1); @@ -420,7 +420,7 @@ void test_random(unsigned int num_draws) deep_copy(density_1d,0); deep_copy(density_3d,0); - cerr << "Test Scalar=int64_t" << endl; + cout << "Test Scalar=int64_t" << endl; test_random_scalar test_int64(density_1d,density_3d,pool,num_draws); ASSERT_EQ( test_int64.pass_mean,1); ASSERT_EQ( test_int64.pass_var,1); @@ -434,7 +434,7 @@ void test_random(unsigned int num_draws) deep_copy(density_1d,0); deep_copy(density_3d,0); - cerr << "Test Scalar=uint64_t" << endl; + cout << "Test Scalar=uint64_t" << endl; test_random_scalar test_uint64(density_1d,density_3d,pool,num_draws); ASSERT_EQ( test_uint64.pass_mean,1); ASSERT_EQ( test_uint64.pass_var,1); @@ -448,7 +448,7 @@ void test_random(unsigned int num_draws) deep_copy(density_1d,0); deep_copy(density_3d,0); - cerr << "Test Scalar=float" << endl; + cout << "Test Scalar=float" << endl; test_random_scalar test_float(density_1d,density_3d,pool,num_draws); ASSERT_EQ( test_float.pass_mean,1); ASSERT_EQ( test_float.pass_var,1); @@ -462,7 +462,7 @@ void test_random(unsigned int num_draws) deep_copy(density_1d,0); deep_copy(density_3d,0); - cerr << "Test Scalar=double" << endl; + cout << "Test Scalar=double" << endl; test_random_scalar test_double(density_1d,density_3d,pool,num_draws); ASSERT_EQ( test_double.pass_mean,1); ASSERT_EQ( test_double.pass_var,1); diff --git a/lib/kokkos/algorithms/unit_tests/UnitTestMain.cpp b/lib/kokkos/algorithms/unit_tests/UnitTestMain.cpp index f952ab3db5..9e75b580bc 100644 --- a/lib/kokkos/algorithms/unit_tests/UnitTestMain.cpp +++ b/lib/kokkos/algorithms/unit_tests/UnitTestMain.cpp @@ -1,13 +1,13 @@ /* //@HEADER // ************************************************************************ -// +// // Kokkos v. 2.0 // Copyright (2014) Sandia Corporation -// +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: @@ -36,7 +36,7 @@ // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) -// +// // ************************************************************************ //@HEADER */ diff --git a/lib/kokkos/benchmarks/bytes_and_flops/main.cpp b/lib/kokkos/benchmarks/bytes_and_flops/main.cpp index f545247212..8db5ce0eb5 100644 --- a/lib/kokkos/benchmarks/bytes_and_flops/main.cpp +++ b/lib/kokkos/benchmarks/bytes_and_flops/main.cpp @@ -44,12 +44,13 @@ #include #include #include +#include int main(int argc, char* argv[]) { Kokkos::initialize(); - - if(argc<10) { + + if(argc<10) { printf("Arguments: N K R D U F T S\n"); printf(" P: Precision (1==float, 2==double)\n"); printf(" N,K: dimensions of the 2D array to allocate\n"); @@ -68,7 +69,7 @@ int main(int argc, char* argv[]) { Kokkos::finalize(); return 0; } - + int P = atoi(argv[1]); int N = atoi(argv[2]); @@ -80,7 +81,7 @@ int main(int argc, char* argv[]) { int T = atoi(argv[8]); int S = atoi(argv[9]); - if(U>8) {printf("U must be 1-8\n"); return 0;} + if(U>8) {printf("U must be 1-8\n"); return 0;} if( (D!=1) && (D!=2) && (D!=4) && (D!=8) && (D!=16) && (D!=32)) {printf("D must be one of 1,2,4,8,16,32\n"); return 0;} if( (P!=1) && (P!=2) ) {printf("P must be one of 1,2\n"); return 0;} diff --git a/lib/kokkos/benchmarks/gather/main.cpp b/lib/kokkos/benchmarks/gather/main.cpp index 161c6f2091..88eb0493c1 100644 --- a/lib/kokkos/benchmarks/gather/main.cpp +++ b/lib/kokkos/benchmarks/gather/main.cpp @@ -44,11 +44,11 @@ #include #include #include +#include int main(int argc, char* argv[]) { Kokkos::initialize(argc,argv); - if(argc<8) { printf("Arguments: S N K D\n"); printf(" S: Scalar Type Size (1==float, 2==double, 4=complex)\n"); diff --git a/lib/kokkos/benchmarks/policy_performance/Makefile b/lib/kokkos/benchmarks/policy_performance/Makefile new file mode 100644 index 0000000000..13aef3209c --- /dev/null +++ b/lib/kokkos/benchmarks/policy_performance/Makefile @@ -0,0 +1,44 @@ +KOKKOS_PATH = ../.. +SRC = $(wildcard *.cpp) + +default: build + echo "Start Build" + +ifneq (,$(findstring Cuda,$(KOKKOS_DEVICES))) +CXX = ${KOKKOS_PATH}/bin/nvcc_wrapper +CXXFLAGS = -O3 -g +LINK = ${CXX} +LINKFLAGS = +EXE = policy_performance.cuda +KOKKOS_DEVICES = "Cuda,OpenMP" +KOKKOS_ARCH = "SNB,Kepler35" +KOKKOS_CUDA_OPTIONS+=enable_lambda +else +CXX = g++ +CXXFLAGS = -O3 -g -Wall -Werror +LINK = ${CXX} +LINKFLAGS = +EXE = policy_performance.host +KOKKOS_DEVICES = "OpenMP" +KOKKOS_ARCH = "SNB" +endif + +DEPFLAGS = -M + +OBJ = $(SRC:.cpp=.o) +LIB = + +include $(KOKKOS_PATH)/Makefile.kokkos + +build: $(EXE) + +$(EXE): $(OBJ) $(KOKKOS_LINK_DEPENDS) + $(LINK) $(KOKKOS_LDFLAGS) $(LINKFLAGS) $(EXTRA_PATH) $(OBJ) $(KOKKOS_LIBS) $(LIB) -o $(EXE) + +clean: kokkos-clean + rm -f *.o *.cuda *.host + +# Compilation rules + +%.o:%.cpp $(KOKKOS_CPP_DEPENDS) main.cpp policy_perf_test.hpp + $(CXX) $(KOKKOS_CPPFLAGS) $(KOKKOS_CXXFLAGS) $(CXXFLAGS) $(EXTRA_INC) -c $< diff --git a/lib/kokkos/benchmarks/policy_performance/main.cpp b/lib/kokkos/benchmarks/policy_performance/main.cpp new file mode 100644 index 0000000000..b0ed9bb512 --- /dev/null +++ b/lib/kokkos/benchmarks/policy_performance/main.cpp @@ -0,0 +1,170 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include +#include "policy_perf_test.hpp" + +int main(int argc, char* argv[] ) { + Kokkos::initialize(argc,argv); + + if(argc<10) { + printf(" Ten arguments are needed to run this program:\n"); + printf(" (1)team_range, (2)thread_range, (3)vector_range, (4)outer_repeat, (5)thread_repeat, (6)vector_repeat, (7)team_size, (8)vector_size, (9)schedule, (10)test_type\n"); + printf(" team_range: number of teams (league_size)\n"); + printf(" thread_range: range for nested TeamThreadRange parallel_*\n"); + printf(" vector_range: range for nested ThreadVectorRange parallel_*\n"); + printf(" outer_repeat: number of repeats for outer parallel_* call\n"); + printf(" thread_repeat: number of repeats for TeamThreadRange parallel_* call\n"); + printf(" vector_repeat: number of repeats for ThreadVectorRange parallel_* call\n"); + printf(" team_size: number of team members (team_size)\n"); + printf(" vector_size: desired vectorization (if possible)\n"); + printf(" schedule: 1 == Static 2 == Dynamic\n"); + printf(" test_type: 3-digit code XYZ for testing (nested) parallel_*\n"); + printf(" code key: XYZ X in {1,2,3,4,5}, Y in {0,1,2}, Z in {0,1,2}\n"); + printf(" TeamPolicy:\n"); + printf(" X: 0 = none (never used, makes no sense); 1 = parallel_for; 2 = parallel_reduce\n"); + printf(" Y: 0 = none; 1 = parallel_for; 2 = parallel_reduce\n"); + printf(" Z: 0 = none; 1 = parallel_for; 2 = parallel_reduce\n"); + printf(" RangePolicy:\n"); + printf(" X: 3 = parallel_for; 4 = parallel_reduce; 5 = parallel_scan\n"); + printf(" Y: 0 = none\n"); + printf(" Z: 0 = none\n"); + printf(" Example Input:\n"); + printf(" 100000 32 32 100 100 100 8 1 1 100\n"); + Kokkos::finalize(); + return 0; + } + + int team_range = atoi(argv[1]); + int thread_range = atoi(argv[2]); + int vector_range = atoi(argv[3]); + + int outer_repeat = atoi(argv[4]); + int thread_repeat = atoi(argv[5]); + int vector_repeat = atoi(argv[6]); + + int team_size = atoi(argv[7]); + int vector_size = atoi(argv[8]); + int schedule = atoi(argv[9]); + int test_type = atoi(argv[10]); + + int disable_verbose_output = 0; + if ( argc > 11 ) { + disable_verbose_output = atoi(argv[11]); + } + + if ( schedule != 1 && schedule != 2 ) { + printf("schedule: %d\n", schedule); + printf("Options for schedule are: 1 == Static 2 == Dynamic\n"); + Kokkos::finalize(); + return -1; + } + + if ( test_type != 100 && test_type != 110 && test_type != 111 && test_type != 112 && test_type != 120 && test_type != 121 && test_type != 122 + && test_type != 200 && test_type != 210 && test_type != 211 && test_type != 212 && test_type != 220 && test_type != 221 && test_type != 222 + && test_type != 300 && test_type != 400 && test_type != 500 + ) + { + printf("Incorrect test_type option\n"); + Kokkos::finalize(); + return -2; + } + + double result = 0.0; + + Kokkos::parallel_reduce( "parallel_reduce warmup", Kokkos::TeamPolicy<>(10,1), + KOKKOS_LAMBDA(const Kokkos::TeamPolicy<>::member_type team, double& lval) { + lval += 1; + }, result); + + typedef Kokkos::View view_type_1d; + typedef Kokkos::View view_type_2d; + typedef Kokkos::View view_type_3d; + + // Allocate view without initializing + // Call a 'warmup' test with 1 repeat - this will initialize the corresponding view appropriately for test and should obey first-touch etc + // Second call to test is the one we actually care about and time + view_type_1d v_1( Kokkos::ViewAllocateWithoutInitializing("v_1"), team_range*team_size); + view_type_2d v_2( Kokkos::ViewAllocateWithoutInitializing("v_2"), team_range*team_size, thread_range); + view_type_3d v_3( Kokkos::ViewAllocateWithoutInitializing("v_3"), team_range*team_size, thread_range, vector_range); + + double result_computed = 0.0; + double result_expect = 0.0; + double time = 0.0; + + if(schedule==1) { + if ( test_type != 500 ) { + // warmup - no repeat of loops + test_policy,int>(team_range,thread_range,vector_range,1,1,1,team_size,vector_size,test_type,v_1,v_2,v_3,result_computed,result_expect,time); + test_policy,int>(team_range,thread_range,vector_range,outer_repeat,thread_repeat,vector_repeat,team_size,vector_size,test_type,v_1,v_2,v_3,result_computed,result_expect,time); + } + else { + // parallel_scan: initialize 1d view for parallel_scan + test_policy,int>(team_range,thread_range,vector_range,1,1,1,team_size,vector_size,100,v_1,v_2,v_3,result_computed,result_expect,time); + test_policy,int>(team_range,thread_range,vector_range,outer_repeat,thread_repeat,vector_repeat,team_size,vector_size,test_type,v_1,v_2,v_3,result_computed,result_expect,time); + } + } + if(schedule==2) { + if ( test_type != 500 ) { + // warmup - no repeat of loops + test_policy,int>(team_range,thread_range,vector_range,1,1,1,team_size,vector_size,test_type,v_1,v_2,v_3,result_computed,result_expect,time); + test_policy,int>(team_range,thread_range,vector_range,outer_repeat,thread_repeat,vector_repeat,team_size,vector_size,test_type,v_1,v_2,v_3,result_computed,result_expect,time); + } + else { + // parallel_scan: initialize 1d view for parallel_scan + test_policy,int>(team_range,thread_range,vector_range,1,1,1,team_size,vector_size,100,v_1,v_2,v_3,result_computed,result_expect,time); + test_policy,int>(team_range,thread_range,vector_range,outer_repeat,thread_repeat,vector_repeat,team_size,vector_size,test_type,v_1,v_2,v_3,result_computed,result_expect,time); + } + } + + if ( disable_verbose_output == 0 ) { + printf("%7i %4i %2i %9i %4i %4i %4i %2i %1i %3i %e %e %lf\n",team_range,thread_range,vector_range,outer_repeat,thread_repeat,vector_repeat,team_size,vector_size,schedule,test_type,result_computed,result_expect,time); + } + else { + printf("%lf\n",time); + } + + Kokkos::finalize(); + + return 0; +} diff --git a/lib/kokkos/benchmarks/policy_performance/policy_perf_test.hpp b/lib/kokkos/benchmarks/policy_performance/policy_perf_test.hpp new file mode 100644 index 0000000000..8c79f3b88d --- /dev/null +++ b/lib/kokkos/benchmarks/policy_performance/policy_perf_test.hpp @@ -0,0 +1,354 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include + +template < class ViewType > +struct ParallelScanFunctor { + using value_type = double; + ViewType v; + + ParallelScanFunctor( const ViewType & v_ ) + : v(v_) + {} + + KOKKOS_INLINE_FUNCTION + void operator()( const int idx, value_type& val, const bool& final ) const + { + // inclusive scan + val += v(idx); + if ( final ) { + v(idx) = val; + } + } +}; + +template +void test_policy(int team_range, int thread_range, int vector_range, + int outer_repeat, int thread_repeat, int inner_repeat, + int team_size, int vector_size, int test_type, + ViewType1 &v1, ViewType2 &v2, ViewType3 &v3, + double &result, double &result_expect, double &time) { + + typedef Kokkos::TeamPolicy t_policy; + typedef typename t_policy::member_type t_team; + Kokkos::Timer timer; + + for(int orep = 0; orep(v1) +#if 0 + // This does not compile with pre Cuda 8.0 - see Github Issue #913 for explanation + KOKKOS_LAMBDA (const int idx, double& val, const bool& final) { + // inclusive scan + val += v1(idx); + if ( final ) { + v1(idx) = val; + } + } +#endif + ); + // result = v1( team_size*team_range - 1 ); // won't work with Cuda - need to copy result back to host to print + // result_expect = 0.5*(team_size*team_range)*(team_size*team_range-1); + } + + } // end outer for loop + + time = timer.seconds(); +} //end test_policy diff --git a/lib/kokkos/benchmarks/policy_performance/script_basic_testing.sh b/lib/kokkos/benchmarks/policy_performance/script_basic_testing.sh new file mode 100755 index 0000000000..e621fffbd4 --- /dev/null +++ b/lib/kokkos/benchmarks/policy_performance/script_basic_testing.sh @@ -0,0 +1,53 @@ +#!/bin/bash + +# Script to check policy_perf_test code works with each possible combo of options + +echo "Performance test results for parallel_reduce code computing sum of sequence [0,N) with various (nested) policies" + +EXECUTABLE=policy_performance + +TEAMRANGE=1000 +THREADRANGE=4 +VECTORRANGE=32 +TEAMSIZE=4 +VECTORSIZE=1 +OREPEAT=1 +MREPEAT=1 +IREPEAT=1 +SCHEDULE=1 + +SUFFIX=host +if [ -e $EXECUTABLE.$SUFFIX ] +then +SCHEDULE=1 +echo "Host tests Static schedule" +for CODE in {100,110,111,112,120,121,122,200,210,211,212,220,221,222,300,400,500} +do + OMP_PROC_BIND=true ./$EXECUTABLE.$SUFFIX $TEAMRANGE $THREADRANGE $VECTORRANGE $OREPEAT $MREPEAT $IREPEAT $TEAMSIZE $VECTORSIZE $SCHEDULE $CODE +done + +SCHEDULE=2 +echo "Host tests Dynamic schedule" +for CODE in {100,110,111,112,120,121,122,200,210,211,212,220,221,222,300,400,500} +do + OMP_PROC_BIND=true ./$EXECUTABLE.$SUFFIX $TEAMRANGE $THREADRANGE $VECTORRANGE $OREPEAT $MREPEAT $IREPEAT $TEAMSIZE $VECTORSIZE $SCHEDULE $CODE +done +fi + +SUFFIX=cuda +if [ -e $EXECUTABLE.$SUFFIX ] +then +SCHEDULE=1 +echo "Cuda tests Static schedule" +for CODE in {100,110,111,112,120,121,122,200,210,211,212,220,221,222,300,400,500} +do + ./$EXECUTABLE.$SUFFIX $TEAMRANGE $THREADRANGE $VECTORRANGE $OREPEAT $MREPEAT $IREPEAT $TEAMSIZE $VECTORSIZE $SCHEDULE $CODE +done + +SCHEDULE=2 +echo "Cuda tests Dynamic schedule" +for CODE in {100,110,111,112,120,121,122,200,210,211,212,220,221,222,300,400,500} +do + ./$EXECUTABLE.$SUFFIX $TEAMRANGE $THREADRANGE $VECTORRANGE $OREPEAT $MREPEAT $IREPEAT $TEAMSIZE $VECTORSIZE $SCHEDULE $CODE +done +fi diff --git a/lib/kokkos/benchmarks/policy_performance/script_sample_usage.sh b/lib/kokkos/benchmarks/policy_performance/script_sample_usage.sh new file mode 100755 index 0000000000..f4bfb87f8f --- /dev/null +++ b/lib/kokkos/benchmarks/policy_performance/script_sample_usage.sh @@ -0,0 +1,126 @@ +#!/bin/bash + +# Sample script for benchmarking policy performance + +# Suggested enviroment variables to export prior to executing script: +# KNL: +# OMP_NUM_THREADS=256 KMP_AFFINITY=compact +# Power: +# OMP_NUM_THREADS=64 OMP_PROC_BIND=true + +# Constants and Variables: +# Vary: TEAMSIZE, and THREADRANGE +# for TEAMSIZE in {1,2,4,5,8}; do +# for THREADRANGE in {32,41,1000}; do +# Fixed: TEAMRANGE, VECTORRANGE, VECTORSIZE +# System specific: Adjust REPEAT values to architecture tests are run on + +# Tests +# Static SCHEDULE = 1 +# Tier 1: parallel_for + RangePolicy 300 +# Tier 2: parallel_reduce, parallel_scan + RangePolicy 400 500 +# Tier 3: 'outer' parallel_for with TeamPolicy (nested parallelism) 1XY +# Tier 4: 'outer' parallel_reduce with TeamPolicy (nested parallelism) 2XY +# Dynamic SCHEDULE = 2 +# Tier 5: parallel_for + RangePolicy 300 +# Tier 6: parallel_reduce, parallel_scan + RangePolicy 400 500 +# Tier 7: 'outer' parallel_for with TeamPolicy (nested parallelism) 1XY +# Tier 8: 'outer' parallel_reduce with TeamPolicy (nested parallelism) 2XY + +# Results grouped by: +# 0) SCHEDULE 1) CODE (test) 2) TEAMRANGE 3) TEAMSIZE 4) THREADRANGE + +EXECUTABLE=policy_performance + +# Default defined values +TEAMRANGE=1000 +THREADRANGE=1 +VECTORRANGE=32 +TEAMSIZE=1 +VECTORSIZE=1 +OREPEAT=1 +MREPEAT=1 +IREPEAT=1 +SCHEDULE=1 + +# Host tests +SUFFIX=host +if [ -e $EXECUTABLE.$SUFFIX ]; then +echo "Host" + +for SCHEDULE in {1,2}; do + +# Tier 1 and 2, 5 and 6 +for CODE in {300,400,500}; do + for TEAMSIZE in {1,2,4,5,8}; do + OMP_PROC_BIND=true ./$EXECUTABLE.$SUFFIX $TEAMRANGE $THREADRANGE $VECTORRANGE $OREPEAT $MREPEAT $IREPEAT $TEAMSIZE $VECTORSIZE $SCHEDULE $CODE + done +done + +# Tier 3, 7 +for CODE in {100,110,111,112,120,121,122}; do + for TEAMSIZE in {1,2,4,5,8}; do + for THREADRANGE in {32,41,1000}; do + OMP_PROC_BIND=true ./$EXECUTABLE.$SUFFIX $TEAMRANGE $THREADRANGE $VECTORRANGE $OREPEAT $MREPEAT $IREPEAT $TEAMSIZE $VECTORSIZE $SCHEDULE $CODE + done + done +done + +# Tier 4, 8 +for CODE in {200,210,211,212,220,221,222}; do + for TEAMSIZE in {1,2,4,5,8}; do + for THREADRANGE in {32,41,1000}; do + OMP_PROC_BIND=true ./$EXECUTABLE.$SUFFIX $TEAMRANGE $THREADRANGE $VECTORRANGE $OREPEAT $MREPEAT $IREPEAT $TEAMSIZE $VECTORSIZE $SCHEDULE $CODE + done + done +done + +done # end SCHEDULE + +fi # end host + + +# Cuda tests +SUFFIX=cuda +# TEAMRANGE=10000, TEAMSIZE=8 too large +# TEAMRANGE=10000, TEAMSIZE=8, THREADRANGE=1000 too large +if [ -e $EXECUTABLE.$SUFFIX ]; then +echo "Cuda" + +for SCHEDULE in {1,2}; do + +# Reset defaults +TEAMRANGE=1000 +THREADRANGE=1 +VECTORRANGE=32 +TEAMSIZE=1 +VECTORSIZE=1 + +# Tier 1 and 2, 5 and 6 +for CODE in {300,400,500}; do + for TEAMSIZE in {1,2,4,5,8}; do + ./$EXECUTABLE.$SUFFIX $TEAMRANGE $THREADRANGE $VECTORRANGE $OREPEAT $MREPEAT $IREPEAT $TEAMSIZE $VECTORSIZE $SCHEDULE $CODE + done +done + +# Tier 3, 7 +for CODE in {100,110,111,112,120,121,122}; do + for TEAMSIZE in {1,2,4,5,8}; do + for THREADRANGE in {32,41,1000}; do + ./$EXECUTABLE.$SUFFIX $TEAMRANGE $THREADRANGE $VECTORRANGE $OREPEAT $MREPEAT $IREPEAT $TEAMSIZE $VECTORSIZE $SCHEDULE $CODE + done + done +done + +# Tier 4, 8 +for CODE in {200,210,211,212,220,221,222}; do + for TEAMSIZE in {1,2,4,5,8}; do + for THREADRANGE in {32,41,1000}; do + ./$EXECUTABLE.$SUFFIX $TEAMRANGE $THREADRANGE $VECTORRANGE $OREPEAT $MREPEAT $IREPEAT $TEAMSIZE $VECTORSIZE $SCHEDULE $CODE + done + done +done + +done # end SCHEDULE + +fi #end cuda diff --git a/lib/kokkos/bin/hpcbind b/lib/kokkos/bin/hpcbind new file mode 100755 index 0000000000..ca34648780 --- /dev/null +++ b/lib/kokkos/bin/hpcbind @@ -0,0 +1,454 @@ +#!/usr/bin/env bash + +################################################################################ +# Check if hwloc commands exist +################################################################################ +declare -i HPCBIND_HAS_HWLOC=1 +type hwloc-bind >/dev/null 2>&1 +HPCBIND_HAS_HWLOC=$((HPCBIND_HAS_HWLOC & ! $?)) + +type hwloc-distrib >/dev/null 2>&1 +HPCBIND_HAS_HWLOC=$((HPCBIND_HAS_HWLOC & ! $?)) + +type hwloc-ls >/dev/null 2>&1 +HPCBIND_HAS_HWLOC=$((HPCBIND_HAS_HWLOC & ! $?)) + +type hwloc-calc >/dev/null 2>&1 +HPCBIND_HAS_HWLOC=$((HPCBIND_HAS_HWLOC & ! $?)) + +type hwloc-ps >/dev/null 2>&1 +HPCBIND_HAS_HWLOC=$((HPCBIND_HAS_HWLOC & ! $?)) + +if [[ ${HPCBIND_HAS_HWLOC} -eq 0 ]]; then + echo "hwloc not found, no process binding will occur" +fi + +# Get parent cpuset +HPCBIND_HWLOC_PARENT_CPUSET="" +if [[ ${HPCBIND_HAS_HWLOC} -eq 1 ]]; then + MY_PID="$BASHPID" + HPCBIND_HWLOC_PARENT_CPUSET=$(hwloc-ps --cpuset | grep "${MY_PID}" | cut -f 2) +fi + +################################################################################ +# Check if nvidia-smi exist +################################################################################ +declare -i HPCBIND_HAS_NVIDIA=0 +type nvidia-smi >/dev/null 2>&1 +HPCBIND_HAS_NVIDIA=$((!$?)) + + +################################################################################ +# Get visible gpu +################################################################################ +declare -i NUM_GPUS=0 +HPCBIND_VISIBLE_GPUS="" +if [[ ${HPCBIND_HAS_NVIDIA} -eq 1 ]]; then + NUM_GPUS=$(nvidia-smi -L | wc -l); + GPU_LIST="$( seq 0 $((NUM_GPUS-1)) )" + HPCBIND_VISIBLE_GPUS=${CUDA_VISIBLE_DEVICES:-${GPU_LIST}} +fi + +declare -i HPCBIND_ENABLE_GPU_MAPPING=$((NUM_GPUS > 0)) + + +################################################################################ +# Get queue id +# supports sbatch, bsub, aprun +################################################################################ +HPCBIND_QUEUE_NAME="" +declare -i HPCBIND_QUEUE_INDEX=0 +declare -i HPCBIND_QUEUE_GPU_MAPPING=0 + +if [[ ! -z "${SLURM_LOCAL_ID}" ]]; then + HPCBIND_QUEUE_GPU_MAPPING=1 + HPCBIND_QUEUE_NAME="sbatch" + HPCBIND_QUEUE_INDEX=${SLURM_LOCAL_ID} +elif [[ ! -z "${LBS_JOBINDEX}" ]]; then + HPCBIND_QUEUE_GPU_MAPPING=1 + HPCBIND_QUEUE_NAME="bsub" + HPCBIND_QUEUE_INDEX=${LBS_JOBINDEX} +elif [[ ! -z "${ALPS_APP_PE}" ]]; then + HPCBIND_QUEUE_GPU_MAPPING=1 + HPCBIND_QUEUE_NAME="aprun" + HPCBIND_QUEUE_INDEX=${ALPS_APP_PE} +fi + + +################################################################################ +# Show help +################################################################################ +function show_help { + local cmd=$(basename "$0") + echo "Usage: ${cmd} -- command ..." + echo " Set the process mask, OMP environment variables and CUDA environment" + echo " variables to sane values if possible. Uses hwloc and nvidia-smi if" + echo " available. Will preserve the current process binding, so it is safe" + echo " to use with a queuing system or mpiexec." + echo "" + echo "Options:" + echo " --no-hwloc-bind Disable binding" + echo " --proc-bind= Set the initial process mask for the script" + echo " LOC can be any valid location argument for" + echo " hwloc-calc Default: all" + echo " --distribute=N Distribute the current cpuset into N partitions" + echo " --distribute-partition=I" + echo " Use the i'th partition (zero based)" + echo " --visible-gpus= Comma separated list of gpu ids" + echo " Default: CUDA_VISIBLE_DEVICES or all gpus in" + echo " sequential order" + echo " --gpu-ignore-queue Ignore queue job id when choosing visible GPU" + echo " --no-gpu-mapping Do not set CUDA_VISIBLE_DEVICES" + echo " --openmp=M.m Set env variables for the given OpenMP version" + echo " Default: 4.0" + echo " --openmp-percent=N Integer percentage of cpuset to use for OpenMP" + echo " threads Default: 100" + echo " --openmp-places= Op=threads|cores|sockets. Default: threads" + echo " --no-openmp-proc-bind Set OMP_PROC_BIND to false and unset OMP_PLACES" + echo " --force-openmp-num-threads=N" + echo " Override logic for selecting OMP_NUM_THREADS" + echo " --force-openmp-proc-bind=" + echo " Override logic for selecting OMP_PROC_BIND" + echo " --no-openmp-nested Set OMP_NESTED to false" + echo " --show-bindings Show the bindings" + echo " --lstopo Show bindings in lstopo without executing a command" + echo " -v|--verbose Show options and relevant environment variables" + echo " -h|--help Show this message" + echo "" + echo "Sample Usage:" + echo " Split the current process cpuset into 4 and use the 3rd partition" + echo " ${cmd} --distribute=4 --distribute-partition=2 -v -- command ..." + echo " Bing the process to all even cores" + echo " ${cmd} --proc-bind=core:even -v -- command ..." + echo " Bind to the first 64 cores and split the current process cpuset into 4" + echo " ${cmd} --proc-bind=core:0-63 --distribute=4 --distribute-partition=0 -- command ..." + echo " skip GPU 0 when mapping visible devices" + echo " ${cmd} --distribute=4 --distribute-partition=0 --visible-gpus=1,2 -v -- command ..." + echo " Display the current bindings" + echo " ${cmd} --proc-bind=numa:0 --show-bindings -- command" + echo " Display the current bindings using lstopo" + echo " ${cmd} --proc-bind=numa:0.core:odd --lstopo" + echo "" +} + + +################################################################################ +# Parse command line arguments +################################################################################ +# Show help if no command line arguments given +if [[ "$#" -eq 0 ]]; then + show_help + exit 0 +fi + +declare -a UNKNOWN_ARGS=() +declare -i HPCBIND_ENABLE_HWLOC_BIND=${HPCBIND_HAS_HWLOC} +declare -i HPCBIND_DISTRIBUTE=1 +declare -i HPCBIND_PARTITION=0 +HPCBIND_PROC_BIND="all" +HPCBIND_OPENMP_VERSION=4.0 +declare -i HPCBIND_OPENMP_PERCENT=100 +HPCBIND_OPENMP_PLACES=${OMP_PLACES:-threads} +declare -i HPCBIND_OPENMP_PROC_BIND=1 +declare -i HPCBIND_OPENMP_FORCE_NUM_THREADS=-1 +HPCBIND_OPENMP_FORCE_PROC_BIND="" +HPCBIND_OPENMP_NESTED=${OMP_NESTED:-true} +declare -i HPCBIND_VERBOSE=0 + +declare -i HPCBIND_SHOW_BINDINGS=0 +declare -i HPCBIND_LSTOPO=0 + +for i in $@; do + case $i in + # number of partitions to create + --no-hwloc-bind) + HPCBIND_ENABLE_HWLOC_BIND=0 + shift + ;; + --proc-bind=*) + HPCBIND_PROC_BIND="${i#*=}" + shift + ;; + --distribute=*) + HPCBIND_DISTRIBUTE="${i#*=}" + shift + ;; + # which partition to use + --distribute-partition=*) + HPCBIND_PARTITION="${i#*=}" + shift + ;; + --visible-gpus=*) + HPCBIND_VISIBLE_GPUS=$(echo "${i#*=}" | tr ',' ' ') + shift + ;; + --gpu-ignore-queue) + HPCBIND_QUEUE_GPU_MAPPING=0 + shift + ;; + --no-gpu-mapping) + HPCBIND_ENABLE_GPU_MAPPING=0 + shift + ;; + --openmp=*) + HPCBIND_OPENMP_VERSION="${i#*=}" + shift + ;; + --openmp-percent=*) + HPCBIND_OPENMP_PERCENT="${i#*=}" + shift + ;; + --openmp-places=*) + HPCBIND_OPENMP_PLACES="${i#*=}" + shift + ;; + --no-openmp-proc-bind) + HPCBIND_OPENMP_PROC_BIND=0 + shift + ;; + --force-openmp-proc-bind=*) + HPCBIND_OPENMP_FORCE_PROC_BIND="${i#*=}" + shift + ;; + --force-openmp-num-threads=*) + HPCBIND_OPENMP_FORCE_NUM_THREADS="${i#*=}" + shift + ;; + --no-openmp-nested) + HPCBIND_OPENMP_NESTED="false" + shift + ;; + --show-bindings) + HPCBIND_VERBOSE=1 + HPCBIND_SHOW_BINDINGS=1 + shift + ;; + --lstopo) + HPCBIND_VERBOSE=1 + HPCBIND_SHOW_BINDINGS=0 + HPCBIND_LSTOPO=1 + shift + ;; + -v|--verbose) + HPCBIND_VERBOSE=1 + shift + ;; + -h|--help) + show_help + exit 0 + ;; + # ignore remaining arguments + --) + shift + break + ;; + # unknown option + *) + UNKNOWN_ARGS+=("$i") + shift + ;; + esac +done + + +################################################################################ +# Check unknown arguments +################################################################################ +if [[ ${#UNKNOWN_ARGS[*]} > 0 ]]; then + echo "Uknown options: ${UNKNOWN_ARGS[*]}" + exit 1 +fi + + +################################################################################ +# Check that visible gpus are valid +################################################################################ +HPCBIND_VISIBLE_GPUS=(${HPCBIND_VISIBLE_GPUS}) +if [[ ${HPCBIND_ENABLE_GPU_MAPPING} -eq 1 ]]; then + for ((i=0; i < ${#HPCBIND_VISIBLE_GPUS[*]}; i++)); do + if [[ ${HPCBIND_VISIBLE_GPUS[$i]} -ge ${NUM_GPUS} || + ${HPCBIND_VISIBLE_GPUS[$i]} -lt 0 ]]; then + echo "Invaild GPU ID ${HPCBIND_VISIBLE_GPUS[$i]}, setting to 0" + HPCBIND_VISIBLE_GPUS[$i]=0; + fi + done + NUM_GPUS=${#HPCBIND_VISIBLE_GPUS[@]} +fi + + +################################################################################ +# Check OpenMP percent +################################################################################ +if [[ ${HPCBIND_OPENMP_PERCENT} -lt 1 ]]; then + echo "OpenMP percent < 1, setting to 1" + HPCBIND_OPENMP_PERCENT=1 +elif [[ ${HPCBIND_OPENMP_PERCENT} -gt 100 ]]; then + echo "OpenMP percent > 100, setting to 100" + HPCBIND_OPENMP_PERCENT=100 +fi + +################################################################################ +# Check distribute +################################################################################ +if [[ ${HPCBIND_DISTRIBUTE} -le 0 ]]; then + echo "Invalid input for distribute, changing distribute to 1" + HPCBIND_DISTRIBUTE=1 +fi + +if [[ ${HPCBIND_PARTITION} -ge ${HPCBIND_DISTRIBUTE} ]]; then + echo "Invalid input for distribute-partition, changing to 0" + HPCBIND_PARTITION=0 +fi + + +################################################################################ +# Find cpuset and num threads +################################################################################ +HPCBIND_HWLOC_CPUSET="" +declare -i HPCBIND_NUM_PUS=0 + +if [[ ${HPCBIND_ENABLE_HWLOC_BIND} -eq 1 ]]; then + if [[ "${HPCBIND_HWLOC_PARENT_CPUSET}" == "" ]]; then + BINDING=$(hwloc-calc ${HPCBIND_PROC_BIND}) + else + BINDING=$(hwloc-calc --restrict ${HPCBIND_HWLOC_PARENT_CPUSET} ${HPCBIND_PROC_BIND}) + fi + + CPUSETS=($(hwloc-distrib --restrict ${BINDING} --at core ${HPCBIND_DISTRIBUTE})) + HPCBIND_HWLOC_CPUSET=${CPUSETS[${HPCBIND_PARTITION}]} + HPCBIND_NUM_PUS=$(hwloc-ls --restrict ${HPCBIND_HWLOC_CPUSET} --only pu | wc -l) +else + HPCBIND_NUM_PUS=$(cat /proc/cpuinfo | grep -c processor) +fi + +declare -i HPCBIND_OPENMP_NUM_THREADS=$((HPCBIND_NUM_PUS * HPCBIND_OPENMP_PERCENT)) +HPCBIND_OPENMP_NUM_THREADS=$((HPCBIND_OPENMP_NUM_THREADS / 100)) + + +if [[ ${HPCBIND_OPENMP_NUM_THREADS} -lt 1 ]]; then + HPCBIND_OPENMP_NUM_THREADS=1 +elif [[ ${HPCBIND_OPENMP_NUM_THREADS} -gt ${HPCBIND_NUM_PUS} ]]; then + HPCBIND_OPENMP_NUM_THREADS=${HPCBIND_NUM_PUS} +fi + +if [[ ${HPCBIND_OPENMP_FORCE_NUM_THREADS} -gt 0 ]]; then + HPCBIND_OPENMP_NUM_THREADS=${HPCBIND_OPENMP_FORCE_NUM_THREADS} +fi + +################################################################################ +# Set OpenMP environment variables +################################################################################ + +# set OMP_NUM_THREADS +export OMP_NUM_THREADS=${HPCBIND_OPENMP_NUM_THREADS} + +# set OMP_PROC_BIND and OMP_PLACES +if [[ ${HPCBIND_OPENMP_PROC_BIND} -eq 1 ]]; then + if [[ "${HPCBIND_OPENMP_FORCE_PROC_BIND}" == "" ]]; then + #default proc bind logic + if [[ "${HPCBIND_OPENMP_VERSION}" == "4.0" || "${HPCBIND_OPENMP_VERSION}" > "4.0" ]]; then + export OMP_PLACES="${HPCBIND_OPENMP_PLACES}" + export OMP_PROC_BIND="spread" + else + export OMP_PROC_BIND="true" + unset OMP_PLACES + fi + else + #force proc bind + export OMP_PLACES="${HPCBIND_OPENMP_PLACES}" + export OMP_PROC_BIND="${HPCBIND_OPENMP_FORCE_PROC_BIND}" + fi +else + # no openmp proc bind + unset OMP_PLACES + unset OMP_PROC_BIND +fi + +# set OMP_NESTED +export OMP_NESTED=${HPCBIND_OPENMP_NESTED} + + +################################################################################ +# Set CUDA environment variables +################################################################################ + +if [[ ${HPCBIND_ENABLE_GPU_MAPPING} -eq 1 ]]; then + if [[ ${HPCBIND_QUEUE_GPU_MAPPING} -eq 0 ]]; then + declare -i GPU_ID=$((HPCBIND_PARTITION % NUM_GPUS)) + export CUDA_VISIBLE_DEVICES=${HPCBIND_VISIBLE_GPUS[${GPU_ID}]} + else + declare -i MY_TASK_ID=$((HPCBIND_QUEUE_INDEX * HPCBIND_DISTRIBUTE + HPCBIND_PARTITION)) + declare -i GPU_ID=$((MY_TASK_ID % NUM_GPUS)) + export CUDA_VISIBLE_DEVICES=${HPCBIND_VISIBLE_GPUS[${GPU_ID}]} + fi +fi + +################################################################################ +# Set hpcbind environment variables +################################################################################ +export HPCBIND_HAS_HWLOC=${HPCBIND_HAS_HWLOC} +export HPCBIND_HAS_NVIDIA=${HPCBIND_HAS_NVIDIA} +export HPCBIND_NUM_PUS=${HPCBIND_NUM_PUS} +export HPCBIND_HWLOC_CPUSET=${HPCBIND_HWLOC_CPUSET} +export HPCBIND_HWLOC_DISTRIBUTE=${HPCBIND_DISTRIBUTE} +export HPCBIND_HWLOC_DISTRIBUTE_PARTITION=${HPCBIND_PARTITION} +if [[ "${HPCBIND_HWLOC_PARENT_CPUSET}" == "" ]]; then + export HPCBIND_HWLOC_PARENT_CPUSET="all" +else + export HPCBIND_HWLOC_PARENT_CPUSET=${HPCBIND_HWLOC_PARENT_CPUSET} +fi +export HPCBIND_HWLOC_PROC_BIND=${HPCBIND_PROC_BIND} +export HPCBIND_NVIDIA_ENABLE_GPU_MAPPING=${HPCBIND_ENABLE_GPU_MAPPING} +export HPCBIND_NVIDIA_VISIBLE_GPUS=$(echo "${HPCBIND_VISIBLE_GPUS[*]}" | tr ' ' ',') +export HPCBIND_OPENMP_VERSION=${HPCBIND_OPENMP_VERSION} +if [[ "${HPCBIND_QUEUE_NAME}" != "" ]]; then + export HPCBIND_QUEUE_INDEX=${HPCBIND_QUEUE_INDEX} + export HPCBIND_QUEUE_NAME=${HPCBIND_QUEUE_NAME} + export HPCBIND_QUEUE_GPU_MAPPING=${HPCBIND_QUEUE_GPU_MAPPING} +fi + + +################################################################################ +# Print verbose +################################################################################ + +if [[ ${HPCBIND_VERBOSE} -eq 1 ]]; then + MY_ENV=$(env | sort) + echo "[HPCBIND]" + echo "${MY_ENV}" | grep -E "^HPCBIND_" + echo "[CUDA]" + echo "${MY_ENV}" | grep -E "^CUDA_" + echo "[OPENMP]" + echo "${MY_ENV}" | grep -E "^OMP_" +fi + +if [[ ${HPCBIND_HAS_HWLOC} -eq 1 && ${HPCBIND_SHOW_BINDINGS} -eq 1 ]]; then + echo "[BINDINGS]" + hwloc-ls --restrict ${HPCBIND_HWLOC_CPUSET} --only pu +elif [[ ${HPCBIND_SHOW_BINDINGS} -eq 1 ]]; then + echo "Unable to show bindings, hwloc not available." +fi + +################################################################################ +# Run command +################################################################################ + +if [[ ${HPCBIND_LSTOPO} -eq 0 ]]; then + if [[ ${HPCBIND_ENABLE_HWLOC_BIND} -eq 1 ]]; then + hwloc-bind ${HPCBIND_HWLOC_CPUSET} -- $@ + else + eval $@ + fi +else + if [[ ${HPCBIND_HAS_HWLOC} -eq 1 ]]; then + if [[ ${HPCBIND_ENABLE_HWLOC_BIND} -eq 1 && ! -z ${DISPLAY} ]]; then + echo "[BINDINGS]" + hwloc-ls --restrict ${HPCBIND_HWLOC_CPUSET} --only pu + hwloc-bind ${HPCBIND_HWLOC_CPUSET} -- lstopo --pid 0 + else + hwloc-ls --restrict ${HPCBIND_HWLOC_CPUSET} + fi + else + echo "Unable to show bindings, hwloc not available." + fi +fi diff --git a/lib/kokkos/bin/kokkos-bind b/lib/kokkos/bin/kokkos-bind new file mode 100755 index 0000000000..b6fe07a1bd --- /dev/null +++ b/lib/kokkos/bin/kokkos-bind @@ -0,0 +1,221 @@ +#!/usr/bin/env bash + +# check if hwloc commands exist +declare -i HAS_HWLOC=0 +type hwloc-bind >/dev/null 2>&1 +HAS_HWLOC="${HAS_HWLOC} + $?" + +type hwloc-distrib >/dev/null 2>&1 +HAS_HWLOC="${HAS_HWLOC} + $?" + +type hwloc-ls >/dev/null 2>&1 +HAS_HWLOC="${HAS_HWLOC} + $?" + +type hwloc-calc >/dev/null 2>&1 +HAS_HWLOC="${HAS_HWLOC} + $?" + +type hwloc-ps >/dev/null 2>&1 +HAS_HWLOC="${HAS_HWLOC} + $?" + + +#parse args +declare -a UNKNOWN_ARGS=() +declare -i DISTRIBUTE=1 +declare -i INDEX=0 +PROC_BIND="all" +CURRENT_CPUSET="" +OPENMP_VERSION=4.0 +OPENMP_PROC_BIND=True +OPENMP_NESTED=True +VERBOSE=False + +#get the current process cpuset +if [[ ${HAS_HWLOC} -eq 0 ]]; then + MY_PID="$BASHPID" + CURRENT_CPUSET=$(hwloc-ps --cpuset | grep "${MY_PID}" | cut -f 2) + echo "$CURRENT_CPUSET" +fi + +function show_help { + local cmd=$(basename "$0") + echo "Usage: ${cmd} -- command ..." + echo " Uses hwloc to divide the node into the given number of groups," + echo " set the appropriate OMP_NUM_THREADS and execute the command on the" + echo " selected group." + echo "" + echo " NOTE: This command assumes it has exclusive use of the node" + echo "" + echo "Options:" + echo " --proc-bind= Set the initial process mask for the script. " + echo " LOC can be any valid location argumnet for" + echo " hwloc-calc. Defaults to the entire machine" + echo " --distribute=N Distribute the current proc-bind into N groups" + echo " --index=I Use the i'th group (zero based)" + echo " --openmp=M.m Set env variables for the given OpenMP version" + echo " (default 4.0)" + echo " --no-openmp-proc-bind Set OMP_PROC_BIND to false and unset OMP_PLACES" + echo " --no-openmp-nested Set OMP_NESTED to false" + echo " -v|--verbose" + echo " -h|--help" + echo "" + echo "Sample Usage:" + echo " ${cmd} --distribute=4 --index=2 -v -- command ..." + echo "" +} + +if [[ "$#" -eq 0 ]]; then + show_help + exit 0 +fi + + +for i in $@; do + case $i in + # number of partitions to create + --proc-bind=*) + PROC_BIND="${i#*=}" + shift + ;; + --distribute=*) + DISTRIBUTE="${i#*=}" + shift + ;; + # which group to use + --index=*) + INDEX="${i#*=}" + shift + ;; + --openmp=*) + OPENMP_VERSION="${i#*=}" + shift + ;; + --no-openmp-proc-bind) + OPENMP_PROC_BIND=False + shift + ;; + --no-openmp-nested) + OPENMP_NESTED=False + shift + ;; + -v|--verbose) + VERBOSE=True + shift + ;; + -h|--help) + show_help + exit 0 + ;; + # ignore remaining arguments + --) + shift + break + ;; + # unknown option + *) + UNKNOWN_ARGS+=("$i") + shift + ;; + esac +done + +if [[ ${#UNKNOWN_ARGS[*]} > 0 ]]; then + echo "Uknown options: ${UNKNOWN_ARGS[*]}" + exit 1 +fi + +if [[ ${DISTRIBUTE} -le 0 ]]; then + echo "Invalid input for distribute, changing distribute to 1" + DISTRIBUTE=1 +fi + +if [[ ${INDEX} -ge ${DISTRIBUTE} ]]; then + echo "Invalid input for index, changing index to 0" + INDEX=0 +fi + +if [[ ${HAS_HWLOC} -ne 0 ]]; then + echo "hwloc not found, no process binding will occur" + DISTRIBUTE=1 + INDEX=0 +fi + +if [[ ${HAS_HWLOC} -eq 0 ]]; then + + if [[ "${CURRENT_CPUSET}" == "" ]]; then + BINDING=$(hwloc-calc ${PROC_BIND}) + else + BINDING=$(hwloc-calc --restrict ${CURRENT_CPUSET} ${PROC_BIND}) + fi + + CPUSETS=($(hwloc-distrib --restrict ${BINDING} --at core ${DISTRIBUTE})) + CPUSET=${CPUSETS[${INDEX}]} + NUM_THREADS=$(hwloc-ls --restrict ${CPUSET} --only pu | wc -l) + + if [[ "${VERBOSE}" == "True" ]]; then + echo "hwloc: true" + echo " proc_bind: ${PROC_BIND}" + echo " distribute: ${DISTRIBUTE}" + echo " index: ${INDEX}" + echo " parent_cpuset: ${CURRENT_CPUSET}" + echo " cpuset: ${CPUSET}" + echo "omp_num_threads: ${NUM_THREADS}" + echo "omp_proc_bind: ${OPENMP_PROC_BIND}" + echo "omp_nested: ${OPENMP_NESTED}" + echo "OpenMP: ${OPENMP_VERSION}" + fi + + # set OMP env + if [[ "${OPENMP_PROC_BIND}" == "True" ]]; then + if [[ "${OPENMP_VERSION}" == "4.0" || "${OPENMP_VERSION}" > "4.0" ]]; then + export OMP_PLACES="threads" + export OMP_PROC_BIND="spread" + else + export OMP_PROC_BIND="true" + unset OMP_PLACES + fi + else + unset OMP_PLACES + unset OMP_PROC_BIND + fi + if [[ "${OPENMP_NESTED}" == "True" ]]; then + export OMP_NESTED="true" + else + export OMP_NESTED="false" + fi + export OMP_NUM_THREADS="${NUM_THREADS}" + + hwloc-bind ${CPUSET} -- $@ +else + NUM_THREADS=$(cat /proc/cpuinfo | grep -c processor) + + if [[ "${VERBOSE}" == "True" ]]; then + echo "hwloc: false" + echo "omp_num_threads: ${NUM_THREADS}" + echo "omp_proc_bind: ${OPENMP_PROC_BIND}" + echo "omp_nested: ${OPENMP_NESTED}" + echo "OpenMP: ${OPENMP_VERSION}" + fi + + # set OMP env + if [[ "${OPENMP_PROC_BIND}" == "True" ]]; then + if [[ "${OPENMP_VERSION}" == "4.0" || "${OPENMP_VERSION}" > "4.0" ]]; then + export OMP_PLACES="threads" + export OMP_PROC_BIND="spread" + else + export OMP_PROC_BIND="true" + unset OMP_PLACES + fi + else + unset OMP_PLACES + unset OMP_PROC_BIND + fi + if [[ "${OPENMP_NESTED}" == "True" ]]; then + export OMP_NESTED="true" + else + export OMP_NESTED="false" + fi + export OMP_NUM_THREADS="${NUM_THREADS}" + + eval $@ +fi + diff --git a/lib/kokkos/bin/runtest b/lib/kokkos/bin/runtest new file mode 100755 index 0000000000..92411fe5ba --- /dev/null +++ b/lib/kokkos/bin/runtest @@ -0,0 +1,165 @@ +#!/usr/bin/env bash + +function get_path() { + cd "$(dirname "$0")" + cd .. + echo "$(pwd -P)" +} + +KOKKOS_PATH="$(get_path "$0")" + +function show_help() { + local cmd=$(basename "$0") + echo "Usage: ${cmd} " + echo " Build and run the tests" + echo "" + echo "Options:" + echo " -j=N|--make-j=N Build the tests in parallel" + echo " -c|--clean Clean build and regenerate make files" + echo " --clean-on-pass Clean build when runtest passes" + echo " --output-prefix=
  Prefix of log files  Default: runtest"
+  echo "  --build-only           Only build the tests"
+  echo "  -v|--verbose           Tee STDOUT and STDERR to screen and files"
+  echo "  -h|--help              Show this message"
+  echo ""
+  ${KOKKOS_PATH}/generate_makefile.bash --help
+  return 0
+}
+
+
+declare -a GENERATE_ARGS=()
+declare -i VERBOSE=0
+declare -i CLEAN=0
+declare -i CLEAN_ON_PASS=0
+declare -i BUILD_ONLY=0
+OUTPUT="runtest"
+
+declare -i MAKE_J=${HPCBIND_NUM_PUS:-1}
+
+for i in $@; do
+  case $i in
+    -j=*|--make-j=*)
+      MAKE_J=${i#*=}
+      shift
+      ;;
+    -c|--clean)
+      CLEAN=1
+      shift
+      ;;
+    --clean-on-pass)
+      CLEAN_ON_PASS=1
+      shift
+      ;;
+    --output-prefix=*)
+      OUTPUT=${i#*=}
+      shift
+      ;;
+    --build-only)
+      BUILD_ONLY=1
+      shift
+      ;;
+    -v|--verbose)
+      VERBOSE=1
+      shift
+      ;;
+    -h|--help)
+      show_help
+      exit 0
+      ;;
+    *)
+      GENERATE_ARGS+=("$i")
+      shift
+      ;;
+  esac
+done
+
+if [[ "$(pwd -P)" == ${KOKKOS_PATH} ]]; then
+  echo "Cannot call $0 from root repository path ${KOKKOS_PATH}"
+  exit 1
+fi
+
+# Some makefile dependencies are incorrect, so clean needs to force
+# a new call to generate_makefiles.bash
+if [[ ${CLEAN} -eq 1 ]]; then
+  START=${SECONDS}
+  echo "Cleaning"
+  /bin/rm -rf algorithms containers core example install Makefile >/dev/null 2>&1
+  END=${SECONDS}
+  echo "    $((END-START)) seconds"
+  if [[ ${VERBOSE} -eq 1 ]]; then
+    echo ""
+    echo ""
+  fi
+fi
+
+declare -i START=${SECONDS}
+echo "Generating Makefile"
+echo "    ${KOKKOS_PATH}/generate_makefile.bash --kokkos-path=${KOKKOS_PATH} ${GENERATE_ARGS[@]}"
+
+if [[ ${VERBOSE} -eq 0 ]]; then
+  "${KOKKOS_PATH}"/generate_makefile.bash --kokkos-path="${KOKKOS_PATH}" "${GENERATE_ARGS[@]}" > ${OUTPUT}.out 2> >(tee ${OUTPUT}.err >&2)
+else
+  "${KOKKOS_PATH}"/generate_makefile.bash --kokkos-path="${KOKKOS_PATH}" "${GENERATE_ARGS[@]}" > >(tee ${OUTPUT}.out) 2> >(tee ${OUTPUT}.err >&2)
+fi
+declare -i RESULT=$?
+declare -i END=${SECONDS}
+if [[ ${RESULT} -eq 0 ]]; then
+  echo "    PASS:  $((END-START)) seconds"
+  if [[ ${VERBOSE} -eq 1 ]]; then
+    echo ""
+    echo ""
+  fi
+else
+  cat ${OUTPUT}.out | grep "FAIL"
+  cat ${OUTPUT}.err | grep "FAIL"
+  echo "    FAIL:  $((END-START)) seconds"
+  exit 1
+fi
+
+START=${SECONDS}
+echo "Building"
+if [[ ${VERBOSE} -eq 0 ]]; then
+  make --keep-going -j ${MAKE_J} build-test >> ${OUTPUT}.out 2> >(tee -a ${OUTPUT}.err >&2)
+else
+  make --keep-going -j ${MAKE_J} build-test > >(tee -a ${OUTPUT}.out) 2> >(tee -a ${OUTPUT}.err >&2)
+fi
+RESULT=$?
+END=${SECONDS}
+if [[ ${RESULT} -eq 0 ]]; then
+  echo "    PASS:  $((END-START)) seconds"
+  if [[ ${VERBOSE} -eq 1 ]]; then
+    echo ""
+    echo ""
+  fi
+else
+  cat ${OUTPUT}.out | grep -E "[[:space:]]error:[[:space:]]"
+  cat ${OUTPUT}.err | grep -E "[[:space:]]error:[[:space:]]"
+  echo "    FAIL:  $((END-START)) seconds"
+  exit 1
+fi
+
+if [[ ${BUILD_ONLY} -eq 0 ]]; then
+  START=${SECONDS}
+  echo "Testing"
+  if [[ ${VERBOSE} -eq 0 ]]; then
+    make --keep-going test >> ${OUTPUT}.out 2> >(tee -a ${OUTPUT}.err >&2)
+  else
+    make --keep-going test > >(tee -a ${OUTPUT}.out) 2> >(tee -a ${OUTPUT}.err >&2)
+  fi
+  RESULT=$?
+  END=${SECONDS}
+  if [[ ${RESULT} -eq 0 ]]; then
+    echo "    PASS:  $((END-START)) seconds"
+    if [[ ${CLEAN_ON_PASS} -eq 1 ]]; then
+      make clean
+    fi
+  else
+    cat ${OUTPUT}.out | grep "FAIL"
+    cat ${OUTPUT}.err | grep "FAIL"
+    echo "    FAIL:  $((END-START)) seconds"
+    exit 1
+  fi
+fi
+
+exit ${RESULT}
+
diff --git a/lib/kokkos/cmake/kokkos.cmake b/lib/kokkos/cmake/kokkos.cmake
index 235b7eaba4..396822c7fa 100644
--- a/lib/kokkos/cmake/kokkos.cmake
+++ b/lib/kokkos/cmake/kokkos.cmake
@@ -999,8 +999,12 @@ SET (Kokkos_INCLUDE_DIRS
     ${Kokkos_SOURCE_DIR}/containers/src
     ${Kokkos_SOURCE_DIR}/algorithms/src
     ${Kokkos_BINARY_DIR}  # to find KokkosCore_config.h
+    ${KOKKOS_INCLUDE_DIRS}
 )
 
+# pass include dirs back to parent scope
+SET(Kokkos_INCLUDE_DIRS_RET ${Kokkos_INCLUDE_DIRS} PARENT_SCOPE)
+
 INCLUDE_DIRECTORIES(${Kokkos_INCLUDE_DIRS})
 
 IF(KOKKOS_SEPARATE_LIBS)
diff --git a/lib/kokkos/config/master_history.txt b/lib/kokkos/config/master_history.txt
index cc6f4c97d7..0447db4b2b 100644
--- a/lib/kokkos/config/master_history.txt
+++ b/lib/kokkos/config/master_history.txt
@@ -7,3 +7,4 @@ tag:  2.02.07    date: 12:16:2016    master: 4b4cc4ba    develop: 382c0966
 tag:  2.02.15    date: 02:10:2017    master: 8c64cd93    develop: 28dea8b6
 tag:  2.03.00    date: 04:25:2017    master: 120d9ce7    develop: 015ba641
 tag:  2.03.05    date: 05:27:2017    master: 36b92f43    develop: 79073186
+tag:  2.03.13    date: 07:27:2017    master: da314444    develop: 29ccb58a
diff --git a/lib/kokkos/config/query_cuda_arch.cpp b/lib/kokkos/config/query_cuda_arch.cpp
new file mode 100644
index 0000000000..383f04e34e
--- /dev/null
+++ b/lib/kokkos/config/query_cuda_arch.cpp
@@ -0,0 +1,24 @@
+#include 
+#include 
+int main()
+{
+	cudaDeviceProp prop;
+  const cudaError_t err_code = cudaGetDeviceProperties(&prop, 0);
+  if (cudaSuccess != err_code) {
+		fprintf(stderr,"cudaGetDeviceProperties failed: %s\n", cudaGetErrorString(err_code));
+		return -1;
+	}
+  switch (prop.major) {
+    case 3:
+      printf("Kepler"); break;
+    case 5:
+      printf("Maxwell"); break;
+    case 6:
+      printf("Pascal"); break;
+    default:
+      fprintf(stderr, "Unspported Device %d%d\n", (int)prop.major, (int)prop.minor);
+      return -1;
+  }
+  printf("%d%d\n", (int)prop.major, (int)prop.minor);
+  return 0;
+}
diff --git a/lib/kokkos/config/test_all_sandia b/lib/kokkos/config/test_all_sandia
index 8e1246bf8b..005cd20721 100755
--- a/lib/kokkos/config/test_all_sandia
+++ b/lib/kokkos/config/test_all_sandia
@@ -160,9 +160,14 @@ if [ "$MACHINE" = "sems" ]; then
     # Format: (compiler module-list build-list exe-name warning-flag)
     COMPILERS=("gcc/4.7.2 $BASE_MODULE_LIST $GCC_BUILD_LIST g++ $GCC_WARNING_FLAGS"
                "gcc/4.8.4 $BASE_MODULE_LIST $GCC_BUILD_LIST g++ $GCC_WARNING_FLAGS"
+               "gcc/4.9.3 $BASE_MODULE_LIST $GCC_BUILD_LIST g++ $GCC_WARNING_FLAGS"
+               "gcc/5.3.0 $BASE_MODULE_LIST $GCC_BUILD_LIST g++ $GCC_WARNING_FLAGS"
+               "gcc/6.1.0 $BASE_MODULE_LIST $GCC_BUILD_LIST g++ $GCC_WARNING_FLAGS"
                "intel/14.0.4 $BASE_MODULE_LIST $INTEL_BUILD_LIST icpc $INTEL_WARNING_FLAGS"
                "intel/15.0.2 $BASE_MODULE_LIST $INTEL_BUILD_LIST icpc $INTEL_WARNING_FLAGS"
                "intel/16.0.1 $BASE_MODULE_LIST $INTEL_BUILD_LIST icpc $INTEL_WARNING_FLAGS"
+               "intel/16.0.3 $BASE_MODULE_LIST $INTEL_BUILD_LIST icpc $INTEL_WARNING_FLAGS"
+               "intel/17.0.1 $BASE_MODULE_LIST $INTEL_BUILD_LIST icpc $INTEL_WARNING_FLAGS"
                "clang/3.6.1 $BASE_MODULE_LIST $CLANG_BUILD_LIST clang++ $CLANG_WARNING_FLAGS"
                "clang/3.7.1 $BASE_MODULE_LIST $CLANG_BUILD_LIST clang++ $CLANG_WARNING_FLAGS"
                "clang/3.8.1 $BASE_MODULE_LIST $CLANG_BUILD_LIST clang++ $CLANG_WARNING_FLAGS"
@@ -280,13 +285,13 @@ elif [ "$MACHINE" = "apollo" ]; then
                "gcc/5.1.0 $BASE_MODULE_LIST "Serial" g++ $GCC_WARNING_FLAGS"
                "intel/16.0.1 $BASE_MODULE_LIST "OpenMP" icpc $INTEL_WARNING_FLAGS"
                "clang/3.9.0 $BASE_MODULE_LIST "Pthread_Serial" clang++ $CLANG_WARNING_FLAGS"
-               "clang/head $CLANG_MODULE_LIST "Cuda_Pthread" clang++ $CUDA_WARNING_FLAGS"
+               "clang/4.0.0 $CLANG_MODULE_LIST "Cuda_Pthread" clang++ $CUDA_WARNING_FLAGS"
                "cuda/8.0.44 $CUDA_MODULE_LIST "Cuda_OpenMP" $KOKKOS_PATH/bin/nvcc_wrapper $CUDA_WARNING_FLAGS"
     )
   else
     # Format: (compiler module-list build-list exe-name warning-flag)
     COMPILERS=("cuda/8.0.44 $CUDA8_MODULE_LIST $BUILD_LIST_CUDA_NVCC $KOKKOS_PATH/bin/nvcc_wrapper $CUDA_WARNING_FLAGS"
-               "clang/head $CLANG_MODULE_LIST $BUILD_LIST_CUDA_CLANG clang++ $CUDA_WARNING_FLAGS"
+               "clang/4.0.0 $CLANG_MODULE_LIST $BUILD_LIST_CUDA_CLANG clang++ $CUDA_WARNING_FLAGS"
                "clang/3.9.0 $CLANG_MODULE_LIST $BUILD_LIST_CLANG clang++ $CLANG_WARNING_FLAGS"
                "gcc/4.7.2 $BASE_MODULE_LIST $GCC_BUILD_LIST g++ $GCC_WARNING_FLAGS"
                "gcc/4.8.4 $BASE_MODULE_LIST $GCC_BUILD_LIST g++ $GCC_WARNING_FLAGS"
@@ -584,7 +589,7 @@ single_build_and_test() {
   else
     run_cmd ${KOKKOS_PATH}/generate_makefile.bash --with-devices=$build $ARCH_FLAG --compiler=$(which $compiler_exe) --cxxflags=\"$cxxflags\" $extra_args &>> ${desc}.configure.log || { report_and_log_test_result 1 ${desc} configure && return 0; }
     local -i build_start_time=$(date +%s)
-    run_cmd make build-test >& ${desc}.build.log || { report_and_log_test_result 1 ${desc} build && return 0; }
+    run_cmd make -j 32 build-test >& ${desc}.build.log || { report_and_log_test_result 1 ${desc} build && return 0; }
     local -i build_end_time=$(date +%s)
     comment="build_time=$(($build_end_time-$build_start_time))"
 
diff --git a/lib/kokkos/config/trilinos-integration/shepard_jenkins_run_script_pthread_intel b/lib/kokkos/config/trilinos-integration/shepard_jenkins_run_script_pthread_intel
index 23968e8c0f..6527df2eb9 100755
--- a/lib/kokkos/config/trilinos-integration/shepard_jenkins_run_script_pthread_intel
+++ b/lib/kokkos/config/trilinos-integration/shepard_jenkins_run_script_pthread_intel
@@ -28,14 +28,14 @@ export JENKINS_DO_PTHREAD=ON
 export JENKINS_DO_SERIAL=OFF
 export JENKINS_DO_COMPLEX=OFF
 
-export ARCH_CXX_FLAG="-xCORE-AVX2 -mkl"
-export ARCH_C_FLAG="-xCORE-AVX2 -mkl"
+export JENKINS_ARCH_CXX_FLAG="-xCORE-AVX2 -mkl"
+export JENKINS_ARCH_C_FLAG="-xCORE-AVX2 -mkl"
 export BLAS_LIBRARIES="-mkl;${MKLROOT}/lib/intel64/libmkl_intel_lp64.a;${MKLROOT}/lib/intel64/libmkl_intel_thread.a;${MKLROOT}/lib/intel64/libmkl_core.a"
 export LAPACK_LIBRARIES=${BLAS_LIBRARIES}
 
 export JENKINS_DO_TESTS=ON
 export JENKINS_DO_EXAMPLES=ON
-export JENKINS_DO_SHARED=OFF
+export JENKINS_DO_SHARED=ON
 
 export QUEUE=haswell
 
diff --git a/lib/kokkos/config/trilinos-integration/shepard_jenkins_run_script_serial_intel b/lib/kokkos/config/trilinos-integration/shepard_jenkins_run_script_serial_intel
index 964de3a002..1a306bc2b2 100755
--- a/lib/kokkos/config/trilinos-integration/shepard_jenkins_run_script_serial_intel
+++ b/lib/kokkos/config/trilinos-integration/shepard_jenkins_run_script_serial_intel
@@ -28,14 +28,14 @@ export JENKINS_DO_PTHREAD=OFF
 export JENKINS_DO_SERIAL=ON
 export JENKINS_DO_COMPLEX=ON
 
-export ARCH_CXX_FLAG="-xCORE-AVX2 -mkl"
-export ARCH_C_FLAG="-xCORE-AVX2 -mkl"
+export JENKINS_ARCH_CXX_FLAG="-xCORE-AVX2 -mkl"
+export JENKINS_ARCH_C_FLAG="-xCORE-AVX2 -mkl"
 export BLAS_LIBRARIES="-mkl;${MKLROOT}/lib/intel64/libmkl_intel_lp64.a;${MKLROOT}/lib/intel64/libmkl_intel_thread.a;${MKLROOT}/lib/intel64/libmkl_core.a"
 export LAPACK_LIBRARIES=${BLAS_LIBRARIES}
 
 export JENKINS_DO_TESTS=ON
 export JENKINS_DO_EXAMPLES=ON
-export JENKINS_DO_SHARED=OFF
+export JENKINS_DO_SHARED=ON
 
 export QUEUE=haswell
 
diff --git a/lib/kokkos/containers/performance_tests/Makefile b/lib/kokkos/containers/performance_tests/Makefile
index edaaf1ee51..ec69363a17 100644
--- a/lib/kokkos/containers/performance_tests/Makefile
+++ b/lib/kokkos/containers/performance_tests/Makefile
@@ -60,7 +60,6 @@ test-threads: KokkosContainers_PerformanceTest_Threads
 test-openmp: KokkosContainers_PerformanceTest_OpenMP
 	./KokkosContainers_PerformanceTest_OpenMP
 
-
 build_all: $(TARGETS)
 
 test: $(TEST_TARGETS)
diff --git a/lib/kokkos/containers/performance_tests/TestMain.cpp b/lib/kokkos/containers/performance_tests/TestMain.cpp
index f952ab3db5..1224af7cdb 100644
--- a/lib/kokkos/containers/performance_tests/TestMain.cpp
+++ b/lib/kokkos/containers/performance_tests/TestMain.cpp
@@ -1,13 +1,13 @@
 /*
 //@HEADER
 // ************************************************************************
-// 
+//
 //                        Kokkos v. 2.0
 //              Copyright (2014) Sandia Corporation
-// 
+//
 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
 // the U.S. Government retains certain rights in this software.
-// 
+//
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -36,12 +36,15 @@
 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 //
 // Questions? Contact  H. Carter Edwards (hcedwar@sandia.gov)
-// 
+//
 // ************************************************************************
 //@HEADER
 */
 
 #include 
+#include 
+
+#include 
 
 int main(int argc, char *argv[]) {
   ::testing::InitGoogleTest(&argc,argv);
diff --git a/lib/kokkos/containers/performance_tests/TestOpenMP.cpp b/lib/kokkos/containers/performance_tests/TestOpenMP.cpp
index b674ec4a74..6631184624 100644
--- a/lib/kokkos/containers/performance_tests/TestOpenMP.cpp
+++ b/lib/kokkos/containers/performance_tests/TestOpenMP.cpp
@@ -69,30 +69,13 @@ protected:
   {
     std::cout << std::setprecision(5) << std::scientific;
 
-    unsigned num_threads = 4;
-
-    if (Kokkos::hwloc::available()) {
-      num_threads = Kokkos::hwloc::get_available_numa_count()
-                    * Kokkos::hwloc::get_available_cores_per_numa()
-                    * Kokkos::hwloc::get_available_threads_per_core()
-                    ;
-
-    }
-
-    std::cout << "OpenMP: " << num_threads << std::endl;
-
-    Kokkos::OpenMP::initialize( num_threads );
-
-    std::cout << "available threads: " << omp_get_max_threads() << std::endl;
+    Kokkos::OpenMP::initialize();
+    Kokkos::OpenMP::print_configuration( std::cout );
   }
 
   static void TearDownTestCase()
   {
     Kokkos::OpenMP::finalize();
-
-    omp_set_num_threads(1);
-
-    ASSERT_EQ( 1 , omp_get_max_threads() );
   }
 };
 
diff --git a/lib/kokkos/containers/src/Kokkos_DualView.hpp b/lib/kokkos/containers/src/Kokkos_DualView.hpp
index 937eab0d88..35cc8ec753 100644
--- a/lib/kokkos/containers/src/Kokkos_DualView.hpp
+++ b/lib/kokkos/containers/src/Kokkos_DualView.hpp
@@ -564,7 +564,7 @@ namespace Impl {
 template< class D, class A1, class A2, class A3, class ... Args >
 struct DualViewSubview {
 
-  typedef typename Kokkos::Experimental::Impl::ViewMapping
+  typedef typename Kokkos::Impl::ViewMapping
     < void
     , Kokkos::ViewTraits< D, A1, A2, A3 >
     , Args ...
diff --git a/lib/kokkos/containers/src/Kokkos_DynRankView.hpp b/lib/kokkos/containers/src/Kokkos_DynRankView.hpp
index 8e464506f9..d22d6b865d 100644
--- a/lib/kokkos/containers/src/Kokkos_DynRankView.hpp
+++ b/lib/kokkos/containers/src/Kokkos_DynRankView.hpp
@@ -46,19 +46,6 @@
 ///
 /// This header file declares and defines Kokkos::Experimental::DynRankView and its
 /// related nonmember functions.
-/*
- *   Changes from View
- *   1. The rank of the DynRankView is returned by the method rank()
- *   2. Max rank of a DynRankView is 7
- *   3. subview name is subdynrankview
- *   4. Every subdynrankview is returned with LayoutStride
- *
- *   NEW: Redesigned DynRankView
- *   5. subview function name now available
- *   6. Copy and Copy-Assign View to DynRankView
- *   7. deep_copy between Views and DynRankViews
- *   8. rank( view ); returns the rank of View or DynRankView
- */
 
 #ifndef KOKKOS_DYNRANKVIEW_HPP
 #define KOKKOS_DYNRANKVIEW_HPP
@@ -117,6 +104,14 @@ struct DynRankDimTraits {
                       , layout.dimension[7] );
   }
 
+  // Extra overload to match that for specialize types v2
+  template 
+  KOKKOS_INLINE_FUNCTION
+  static size_t computeRank( const Kokkos::Impl::ViewCtorProp& prop, const Layout& layout )
+  {
+    return computeRank(layout);
+  }
+
   // Create the layout for the rank-7 view.
   // Non-strided Layout
   template 
@@ -158,8 +153,17 @@ struct DynRankDimTraits {
                  );
   }
 
+  // Extra overload to match that for specialize types
+  template 
+  KOKKOS_INLINE_FUNCTION
+  static typename std::enable_if< (std::is_same::value || std::is_same::value || std::is_same::value) , typename Traits::array_layout >::type createLayout( const ViewCtorProp& prop, const typename Traits::array_layout& layout )
+  {
+    return createLayout( layout );
+  }
+
   // Create a view from the given dimension arguments.
   // This is only necessary because the shmem constructor doesn't take a layout.
+  //   NDE shmem View's are not compatible with the added view_alloc value_type / fad_dim deduction functionality
   template 
   static ViewType createView( const ViewArg& arg
                             , const size_t N0
@@ -186,7 +190,8 @@ struct DynRankDimTraits {
   // Non-strided Layout
   template 
   KOKKOS_INLINE_FUNCTION
-  static typename std::enable_if< (std::is_same::value || std::is_same::value) && std::is_integral::value , Layout >::type reconstructLayout( const Layout& layout , iType dynrank )
+  static typename std::enable_if< (std::is_same::value || std::is_same::value) && std::is_integral::value , Layout >::type
+  reconstructLayout( const Layout& layout , iType dynrank )
   {
     return Layout( dynrank > 0 ? layout.dimension[0] : ~size_t(0)
                  , dynrank > 1 ? layout.dimension[1] : ~size_t(0)
@@ -202,7 +207,8 @@ struct DynRankDimTraits {
   // LayoutStride
   template 
   KOKKOS_INLINE_FUNCTION
-  static typename std::enable_if< (std::is_same::value) && std::is_integral::value , Layout >::type reconstructLayout( const Layout& layout , iType dynrank )
+  static typename std::enable_if< (std::is_same::value) && std::is_integral::value , Layout >::type
+  reconstructLayout( const Layout& layout , iType dynrank )
   {
     return Layout( dynrank > 0 ? layout.dimension[0] : ~size_t(0)
                  , dynrank > 0 ? layout.stride[0] : (0)
@@ -311,6 +317,11 @@ void dyn_rank_view_verify_operator_bounds
 /** \brief  Assign compatible default mappings */
 struct ViewToDynRankViewTag {};
 
+} // namespace Impl
+} // namespace Experimental
+
+namespace Impl {
+
 template< class DstTraits , class SrcTraits >
 class ViewMapping< DstTraits , SrcTraits ,
   typename std::enable_if<(
@@ -337,7 +348,7 @@ class ViewMapping< DstTraits , SrcTraits ,
         )
       )
     )
-  ) , ViewToDynRankViewTag >::type >
+  ) , Kokkos::Experimental::Impl::ViewToDynRankViewTag >::type >
 {
 private:
 
@@ -376,7 +387,7 @@ public:
 
       typedef typename DstType::offset_type  dst_offset_type ;
       dst.m_map.m_offset = dst_offset_type(std::integral_constant() , src.layout() ); //Check this for integer input1 for padding, etc
-      dst.m_map.m_handle = Kokkos::Experimental::Impl::ViewDataHandle< DstTraits >::assign( src.m_map.m_handle , src.m_track );
+      dst.m_map.m_handle = Kokkos::Impl::ViewDataHandle< DstTraits >::assign( src.m_map.m_handle , src.m_track );
       dst.m_track.assign( src.m_track , DstTraits::is_managed );
       dst.m_rank = src.Rank ;
     }
@@ -384,22 +395,20 @@ public:
 
 } //end Impl
 
+namespace Experimental {
+
 /* \class DynRankView
  * \brief Container that creates a Kokkos view with rank determined at runtime.
- *   Essentially this is a rank 7 view that wraps the access operators
- *   to yield the functionality of a view
+ *   Essentially this is a rank 7 view
  *
  *   Changes from View
  *   1. The rank of the DynRankView is returned by the method rank()
  *   2. Max rank of a DynRankView is 7
- *   3. subview name is subdynrankview
- *   4. Every subdynrankview is returned with LayoutStride
- *
- *   NEW: Redesigned DynRankView
- *   5. subview function name now available
- *   6. Copy and Copy-Assign View to DynRankView
- *   7. deep_copy between Views and DynRankViews
- *   8. rank( view ); returns the rank of View or DynRankView
+ *   3. subview called with 'subview(...)' or 'subdynrankview(...)' (backward compatibility) 
+ *   4. Every subview is returned with LayoutStride
+ *   5. Copy and Copy-Assign View to DynRankView
+ *   6. deep_copy between Views and DynRankViews
+ *   7. rank( view ); returns the rank of View or DynRankView
  *
  */
 
@@ -427,7 +436,7 @@ public:
 
 
 private:
-  typedef Kokkos::Experimental::Impl::ViewMapping< traits , void > map_type ;
+  typedef Kokkos::Impl::ViewMapping< traits , void > map_type ;
   typedef Kokkos::Experimental::Impl::SharedAllocationTracker      track_type ;
 
   track_type  m_track ;
@@ -556,7 +565,7 @@ public:
   // Allow specializations to query their specialized map
 
   KOKKOS_INLINE_FUNCTION
-  const Kokkos::Experimental::Impl::ViewMapping< traits , void > &
+  const Kokkos::Impl::ViewMapping< traits , void > &
   implementation_map() const { return m_map ; }
 
   //----------------------------------------
@@ -803,7 +812,7 @@ public:
     , m_rank(rhs.m_rank)
     {
       typedef typename DynRankView ::traits SrcTraits ;
-      typedef Kokkos::Experimental::Impl::ViewMapping< traits , SrcTraits , void > Mapping ;
+      typedef Kokkos::Impl::ViewMapping< traits , SrcTraits , void > Mapping ;
       static_assert( Mapping::is_assignable , "Incompatible DynRankView copy construction" );
       Mapping::assign( m_map , rhs.m_map , rhs.m_track );
     }
@@ -813,7 +822,7 @@ public:
   DynRankView & operator = (const DynRankView & rhs )
     {
       typedef typename DynRankView ::traits SrcTraits ;
-      typedef Kokkos::Experimental::Impl::ViewMapping< traits , SrcTraits , void > Mapping ;
+      typedef Kokkos::Impl::ViewMapping< traits , SrcTraits , void > Mapping ;
       static_assert( Mapping::is_assignable , "Incompatible DynRankView copy construction" );
       Mapping::assign( m_map , rhs.m_map , rhs.m_track );
       m_track.assign( rhs.m_track , traits::is_managed );
@@ -831,7 +840,7 @@ public:
     , m_rank( rhs.Rank )
     {
       typedef typename View::traits  SrcTraits ;
-      typedef Kokkos::Experimental::Impl::ViewMapping< traits , SrcTraits , Kokkos::Experimental::Impl::ViewToDynRankViewTag >  Mapping ;
+      typedef Kokkos::Impl::ViewMapping< traits , SrcTraits , Kokkos::Experimental::Impl::ViewToDynRankViewTag >  Mapping ;
       static_assert( Mapping::is_assignable , "Incompatible DynRankView copy construction" );
       Mapping::assign( *this , rhs );
     }
@@ -841,7 +850,7 @@ public:
   DynRankView & operator = ( const View & rhs )
     {
       typedef typename View::traits  SrcTraits ;
-      typedef Kokkos::Experimental::Impl::ViewMapping< traits , SrcTraits , Kokkos::Experimental::Impl::ViewToDynRankViewTag >  Mapping ;
+      typedef Kokkos::Impl::ViewMapping< traits , SrcTraits , Kokkos::Experimental::Impl::ViewToDynRankViewTag >  Mapping ;
       static_assert( Mapping::is_assignable , "Incompatible View to DynRankView copy assignment" );
       Mapping::assign( *this , rhs );
       return *this ;
@@ -870,7 +879,7 @@ public:
       )
       : m_track()
       , m_map()
-      , m_rank( Impl::DynRankDimTraits::computeRank(arg_layout) )
+      , m_rank( Impl::DynRankDimTraits::template computeRank< typename traits::array_layout, P...>(arg_prop, arg_layout) )
     {
       // Append layout and spaces if not input
       typedef Impl::ViewCtorProp< P ... > alloc_prop_input ;
@@ -923,7 +932,7 @@ public:
 //------------------------------------------------------------
 
       Kokkos::Experimental::Impl::SharedAllocationRecord<> *
-        record = m_map.allocate_shared( prop , Impl::DynRankDimTraits::createLayout(arg_layout) );
+        record = m_map.allocate_shared( prop , Impl::DynRankDimTraits::template createLayout(arg_prop, arg_layout) );
 
 //------------------------------------------------------------
 #if defined( KOKKOS_ENABLE_CUDA )
@@ -947,8 +956,8 @@ public:
                                >::type const & arg_layout
       )
       : m_track() // No memory tracking
-      , m_map( arg_prop , Impl::DynRankDimTraits::createLayout(arg_layout) )
-      , m_rank( Impl::DynRankDimTraits::computeRank(arg_layout) )
+      , m_map( arg_prop , Impl::DynRankDimTraits::template createLayout(arg_prop, arg_layout) )
+      , m_rank( Impl::DynRankDimTraits::template computeRank< typename traits::array_layout, P...>(arg_prop, arg_layout) )
     {
       static_assert(
         std::is_same< pointer_type
@@ -1034,6 +1043,7 @@ public:
     {}
 
   // For backward compatibility
+  // NDE This ctor does not take ViewCtorProp argument - should not use alternative createLayout call
   explicit inline
   DynRankView( const ViewAllocateWithoutInitializing & arg_prop
       , const typename traits::array_layout & arg_layout
@@ -1179,6 +1189,11 @@ namespace Impl {
 
 struct DynRankSubviewTag {};
 
+} // namespace Impl
+} // namespace Experimental
+
+namespace Impl {
+
 template< class SrcTraits , class ... Args >
 struct ViewMapping
   < typename std::enable_if<(
@@ -1192,7 +1207,7 @@ struct ViewMapping
         std::is_same< typename SrcTraits::array_layout
                     , Kokkos::LayoutStride >::value
       )
-    ), DynRankSubviewTag >::type
+    ), Kokkos::Experimental::Impl::DynRankSubviewTag >::type
   , SrcTraits
   , Args ... >
 {
@@ -1264,7 +1279,7 @@ public:
   };
 
 
-  typedef DynRankView< value_type , array_layout , typename SrcTraits::device_type , typename SrcTraits::memory_traits >  ret_type;
+  typedef Kokkos::Experimental::DynRankView< value_type , array_layout , typename SrcTraits::device_type , typename SrcTraits::memory_traits >  ret_type;
 
   template < typename T , class ... P >
   KOKKOS_INLINE_FUNCTION
@@ -1336,9 +1351,10 @@ public:
 
 } // end Impl
 
+namespace Experimental {
 
 template< class V , class ... Args >
-using Subdynrankview = typename Kokkos::Experimental::Impl::ViewMapping< Kokkos::Experimental::Impl::DynRankSubviewTag , V , Args... >::ret_type ;
+using Subdynrankview = typename Kokkos::Impl::ViewMapping< Kokkos::Experimental::Impl::DynRankSubviewTag , V , Args... >::ret_type ;
 
 template< class D , class ... P , class ...Args >
 KOKKOS_INLINE_FUNCTION
@@ -1348,7 +1364,7 @@ subdynrankview( const Kokkos::Experimental::DynRankView< D , P... > &src , Args.
     if ( src.rank() > sizeof...(Args) ) //allow sizeof...(Args) >= src.rank(), ignore the remaining args
       { Kokkos::abort("subdynrankview: num of args must be >= rank of the source DynRankView"); }
 
-    typedef Kokkos::Experimental::Impl::ViewMapping< Kokkos::Experimental::Impl::DynRankSubviewTag , Kokkos::ViewTraits< D*******, P... > , Args... > metafcn ;
+    typedef Kokkos::Impl::ViewMapping< Kokkos::Experimental::Impl::DynRankSubviewTag , Kokkos::ViewTraits< D*******, P... > , Args... > metafcn ;
 
     return metafcn::subview( src.rank() , src , args... );
   }
diff --git a/lib/kokkos/containers/src/Kokkos_DynamicView.hpp b/lib/kokkos/containers/src/Kokkos_DynamicView.hpp
index da96db2d6b..e9059d64c4 100644
--- a/lib/kokkos/containers/src/Kokkos_DynamicView.hpp
+++ b/lib/kokkos/containers/src/Kokkos_DynamicView.hpp
@@ -1,13 +1,13 @@
 /*
 //@HEADER
 // ************************************************************************
-// 
+//
 //                        Kokkos v. 2.0
 //              Copyright (2014) Sandia Corporation
-// 
+//
 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
 // the U.S. Government retains certain rights in this software.
-// 
+//
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -36,7 +36,7 @@
 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 //
 // Questions? Contact  H. Carter Edwards (hcedwar@sandia.gov)
-// 
+//
 // ************************************************************************
 //@HEADER
 */
@@ -57,7 +57,7 @@ namespace Experimental {
  */
 template< typename DataType , typename ... P >
 class DynamicView : public Kokkos::ViewTraits< DataType , P ... >
-{ 
+{
 public:
 
   typedef Kokkos::ViewTraits< DataType , P ... >  traits ;
@@ -68,7 +68,7 @@ private:
 
   typedef Kokkos::Experimental::Impl::SharedAllocationTracker   track_type ;
 
-  static_assert( traits::rank == 1 && traits::rank_dynamic == 1 
+  static_assert( traits::rank == 1 && traits::rank_dynamic == 1
                , "DynamicView must be rank-one" );
 
   static_assert( std::is_trivial< typename traits::value_type >::value &&
@@ -216,14 +216,14 @@ public:
         // Verify that allocation of the requested chunk in in progress.
 
         // The allocated chunk counter is m_chunks[ m_chunk_max ]
-        const uintptr_t n = 
+        const uintptr_t n =
           *reinterpret_cast( m_chunks + m_chunk_max );
 
         if ( n <= ic ) {
           Kokkos::abort("Kokkos::DynamicView array bounds error");
         }
 
-        // Allocation of this chunk is in progress 
+        // Allocation of this chunk is in progress
         // so wait for allocation to complete.
         while ( 0 == *ch );
       }
@@ -267,7 +267,7 @@ public:
         const uintptr_t jc_try = jc ;
 
         // Jump iteration to the chunk counter.
-        
+
         jc = atomic_compare_exchange( pc , jc_try , jc_try + 1 );
 
         if ( jc_try == jc ) {
@@ -316,7 +316,7 @@ public:
       }
       else {
         while ( NC + 1 <= *pc ) {
-          --*pc ;        
+          --*pc ;
           m_pool.deallocate( m_chunks[*pc]
                            , sizeof(value_type) << m_chunk_shift );
           m_chunks[*pc] = 0 ;
@@ -331,7 +331,7 @@ public:
     typename traits::value_type ** m_chunks ;
     uintptr_t                    * m_pc ;
     uintptr_t                      m_nc ;
-    unsigned                       m_chunk_shift ;  
+    unsigned                       m_chunk_shift ;
 
     KOKKOS_INLINE_FUNCTION
     void operator()( int ) const
@@ -348,7 +348,7 @@ public:
         }
         else {
           while ( m_nc + 1 <= *m_pc ) {
-            --*m_pc ;        
+            --*m_pc ;
             m_pool.deallocate( m_chunks[*m_pc]
                              , sizeof(value_type) << m_chunk_shift );
             m_chunks[*m_pc] = 0 ;
@@ -482,7 +482,7 @@ public:
   };
 
 
-  /**\brief  Allocation constructor 
+  /**\brief  Allocation constructor
    *
    *  Memory is allocated in chunks from the memory pool.
    *  The chunk size conforms to the memory pool's chunk size.
@@ -557,7 +557,7 @@ void deep_copy( const View & dst
 
   if ( DstExecCanAccessSrc ) {
     // Copying data between views in accessible memory spaces and either non-contiguous or incompatible shape.
-    Kokkos::Experimental::Impl::ViewRemap< dst_type , src_type >( dst , src );
+    Kokkos::Impl::ViewRemap< dst_type , src_type >( dst , src );
   }
   else {
     Kokkos::Impl::throw_runtime_exception("deep_copy given views that would require a temporary allocation");
@@ -581,7 +581,7 @@ void deep_copy( const DynamicView & dst
 
   if ( DstExecCanAccessSrc ) {
     // Copying data between views in accessible memory spaces and either non-contiguous or incompatible shape.
-    Kokkos::Experimental::Impl::ViewRemap< dst_type , src_type >( dst , src );
+    Kokkos::Impl::ViewRemap< dst_type , src_type >( dst , src );
   }
   else {
     Kokkos::Impl::throw_runtime_exception("deep_copy given views that would require a temporary allocation");
diff --git a/lib/kokkos/containers/unit_tests/TestCuda.cpp b/lib/kokkos/containers/unit_tests/TestCuda.cpp
index 5a78a5de9e..651a4e7eb8 100644
--- a/lib/kokkos/containers/unit_tests/TestCuda.cpp
+++ b/lib/kokkos/containers/unit_tests/TestCuda.cpp
@@ -69,6 +69,8 @@
 #include 
 #include 
 
+#include 
+
 //----------------------------------------------------------------------------
 
 
@@ -94,6 +96,10 @@ TEST_F( cuda , dyn_view_api) {
   TestDynViewAPI< double , Kokkos::Cuda >();
 }
 
+TEST_F( cuda, viewctorprop_embedded_dim ) {
+  TestViewCtorProp_EmbeddedDim< Kokkos::Cuda >::test_vcpt( 2, 3 );
+}
+
 TEST_F( cuda , staticcrsgraph )
 {
   TestStaticCrsGraph::run_test_graph< Kokkos::Cuda >();
diff --git a/lib/kokkos/containers/unit_tests/TestOpenMP.cpp b/lib/kokkos/containers/unit_tests/TestOpenMP.cpp
index 2448bd077b..5365d91361 100644
--- a/lib/kokkos/containers/unit_tests/TestOpenMP.cpp
+++ b/lib/kokkos/containers/unit_tests/TestOpenMP.cpp
@@ -66,6 +66,8 @@
 #include 
 #include 
 
+#include 
+
 #include 
 
 namespace Test {
@@ -76,14 +78,7 @@ protected:
   {
     std::cout << std::setprecision(5) << std::scientific;
 
-    unsigned threads_count = 4 ;
-
-    if ( Kokkos::hwloc::available() ) {
-      threads_count = Kokkos::hwloc::get_available_numa_count() *
-                      Kokkos::hwloc::get_available_cores_per_numa();
-    }
-
-    Kokkos::OpenMP::initialize( threads_count );
+    Kokkos::OpenMP::initialize();
   }
 
   static void TearDownTestCase()
@@ -96,6 +91,10 @@ TEST_F( openmp, dyn_view_api) {
   TestDynViewAPI< double , Kokkos::OpenMP >();
 }
 
+TEST_F( openmp, viewctorprop_embedded_dim ) {
+  TestViewCtorProp_EmbeddedDim< Kokkos::OpenMP >::test_vcpt( 2, 3 );
+}
+
 TEST_F( openmp, bitset )
 {
   test_bitset();
diff --git a/lib/kokkos/containers/unit_tests/TestSerial.cpp b/lib/kokkos/containers/unit_tests/TestSerial.cpp
index 06c4d9f6ed..1b9b5a2da3 100644
--- a/lib/kokkos/containers/unit_tests/TestSerial.cpp
+++ b/lib/kokkos/containers/unit_tests/TestSerial.cpp
@@ -67,6 +67,8 @@
 #include 
 #include 
 
+#include 
+
 namespace Test {
 
 class serial : public ::testing::Test {
@@ -85,6 +87,10 @@ TEST_F( serial, dyn_view_api) {
   TestDynViewAPI< double , Kokkos::Serial >();
 }
 
+TEST_F( serial, viewctorprop_embedded_dim ) {
+  TestViewCtorProp_EmbeddedDim< Kokkos::Serial >::test_vcpt( 2, 3 );
+}
+
 TEST_F( serial , staticcrsgraph )
 {
   TestStaticCrsGraph::run_test_graph< Kokkos::Serial >();
diff --git a/lib/kokkos/containers/unit_tests/TestThreads.cpp b/lib/kokkos/containers/unit_tests/TestThreads.cpp
index 938ec88e90..aca0b57d65 100644
--- a/lib/kokkos/containers/unit_tests/TestThreads.cpp
+++ b/lib/kokkos/containers/unit_tests/TestThreads.cpp
@@ -70,6 +70,8 @@
 #include 
 #include 
 
+#include 
+
 namespace Test {
 
 class threads : public ::testing::Test {
@@ -103,6 +105,10 @@ TEST_F( threads , dyn_view_api) {
   TestDynViewAPI< double , Kokkos::Threads >();
 }
 
+TEST_F( threads, viewctorprop_embedded_dim ) {
+  TestViewCtorProp_EmbeddedDim< Kokkos::Threads >::test_vcpt( 2, 3 );
+}
+
 TEST_F( threads , staticcrsgraph )
 {
   TestStaticCrsGraph::run_test_graph< Kokkos::Threads >();
diff --git a/lib/kokkos/containers/unit_tests/TestViewCtorPropEmbeddedDim.hpp b/lib/kokkos/containers/unit_tests/TestViewCtorPropEmbeddedDim.hpp
new file mode 100644
index 0000000000..1efd1ddc51
--- /dev/null
+++ b/lib/kokkos/containers/unit_tests/TestViewCtorPropEmbeddedDim.hpp
@@ -0,0 +1,213 @@
+/*
+//@HEADER
+// ************************************************************************
+//
+//                        Kokkos v. 2.0
+//              Copyright (2014) Sandia Corporation
+//
+// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
+// the U.S. Government retains certain rights in this software.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the Corporation nor the names of the
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Questions? Contact  H. Carter Edwards (hcedwar@sandia.gov)
+//
+// ************************************************************************
+//@HEADER
+*/
+
+#include 
+
+#include 
+
+#include 
+#include 
+
+#include 
+#include 
+
+namespace Test {
+
+namespace {
+
+template 
+struct TestViewCtorProp_EmbeddedDim {
+
+  using ViewIntType     = typename Kokkos::View< int**, ExecSpace >;
+  using ViewDoubleType     = typename Kokkos::View< double*, ExecSpace >;
+
+  using DynRankViewIntType     = typename Kokkos::DynRankView< int, ExecSpace >;
+  using DynRankViewDoubleType     = typename Kokkos::DynRankView< double, ExecSpace >;
+
+  // Cuda 7.0 has issues with using a lamda in parallel_for to initialize the view - replace with this functor
+  template < class ViewType >
+  struct Functor {
+
+    ViewType v;
+
+    Functor( const ViewType & v_ ) : v(v_) {}
+
+    KOKKOS_INLINE_FUNCTION
+    void operator()( const int i ) const {
+      v(i) = i;
+    }
+
+  };
+
+
+  static void test_vcpt( const int N0, const int N1 )
+  {
+
+    // Create two views to test
+    {
+      using VIT = typename TestViewCtorProp_EmbeddedDim::ViewIntType ;
+      using VDT = typename TestViewCtorProp_EmbeddedDim::ViewDoubleType ;
+
+      VIT vi1("vi1", N0, N1);
+      VDT vd1("vd1", N0);
+
+      // TEST: Test for common type between two views, one with type double, other with type int
+      // Deduce common value_type and construct a view with that type
+      {
+        // Two views
+        auto view_alloc_arg = Kokkos::common_view_alloc_prop(vi1, vd1);
+        typedef typename decltype( view_alloc_arg )::value_type                    CommonViewValueType;
+        typedef typename Kokkos::View< CommonViewValueType*, ExecSpace >  CVT;
+        typedef typename CVT::HostMirror                                           HostCVT;
+
+        // Construct View using the common type; for case of specialization, an 'embedded_dim' would be stored by view_alloc_arg
+        CVT cv1( Kokkos::view_alloc( "cv1", view_alloc_arg ), N0*N1 );
+
+        Kokkos::parallel_for( Kokkos::RangePolicy< ExecSpace >(0, N0*N1), 
+          Functor(cv1)
+        );
+
+        HostCVT hcv1 = Kokkos::create_mirror_view( cv1 );
+        Kokkos::deep_copy( hcv1, cv1 );
+
+        ASSERT_EQ( (std::is_same< CommonViewValueType, double >::value) , true ) ;
+      #if 0
+      // debug output
+      for ( int i = 0; i < N0*N1; ++i ) {
+        printf(" Output check: hcv1(%d) = %lf\n ", i, hcv1(i) );
+      }
+
+      printf( " Common value type view: %s \n", typeid( CVT() ).name() );
+      printf( " Common value type: %s \n", typeid( CommonViewValueType() ).name() );
+      if ( std::is_same< CommonViewValueType, double >::value == true ) {
+        printf("Proper common value_type\n");
+      }
+      else {
+        printf("WRONG common value_type\n");
+      }
+      // end debug output
+      #endif
+      }
+
+      {
+        // Single view
+        auto view_alloc_arg = Kokkos::common_view_alloc_prop(vi1);
+        typedef typename decltype( view_alloc_arg )::value_type                    CommonViewValueType;
+        typedef typename Kokkos::View< CommonViewValueType*, ExecSpace >  CVT;
+        typedef typename CVT::HostMirror                                           HostCVT;
+
+        // Construct View using the common type; for case of specialization, an 'embedded_dim' would be stored by view_alloc_arg
+        CVT cv1( Kokkos::view_alloc( "cv1", view_alloc_arg ), N0*N1 );
+
+        Kokkos::parallel_for( Kokkos::RangePolicy< ExecSpace >(0, N0*N1), 
+          Functor(cv1)
+        );
+
+        HostCVT hcv1 = Kokkos::create_mirror_view( cv1 );
+        Kokkos::deep_copy( hcv1, cv1 );
+
+        ASSERT_EQ( (std::is_same< CommonViewValueType, int>::value) , true ) ;
+      }
+
+    }
+
+    // Create two dynamic rank views to test
+    {
+      using VIT = typename TestViewCtorProp_EmbeddedDim::DynRankViewIntType ;
+      using VDT = typename TestViewCtorProp_EmbeddedDim::DynRankViewDoubleType ;
+
+      VIT vi1("vi1", N0, N1);
+      VDT vd1("vd1", N0);
+
+      // TEST: Test for common type between two views, one with type double, other with type int
+      // Deduce common value_type and construct a view with that type
+      {
+        // Two views
+        auto view_alloc_arg = Kokkos::common_view_alloc_prop( vi1, vd1 );
+        typedef typename decltype( view_alloc_arg )::value_type                    CommonViewValueType;
+        typedef typename Kokkos::View< CommonViewValueType*, ExecSpace >  CVT;
+        typedef typename CVT::HostMirror                                           HostCVT;
+
+        // Construct View using the common type; for case of specialization, an 'embedded_dim' would be stored by view_alloc_arg
+        CVT cv1( Kokkos::view_alloc( "cv1", view_alloc_arg ), N0*N1 );
+
+
+        Kokkos::parallel_for( Kokkos::RangePolicy< ExecSpace >(0, N0*N1), 
+          Functor(cv1)
+        );
+
+        HostCVT hcv1 = Kokkos::create_mirror_view( cv1 );
+        Kokkos::deep_copy( hcv1, cv1 );
+
+        ASSERT_EQ( (std::is_same< CommonViewValueType, double >::value) , true ) ;
+      }
+
+      {
+        // Single views
+        auto view_alloc_arg = Kokkos::common_view_alloc_prop( vi1 );
+        typedef typename decltype( view_alloc_arg )::value_type                    CommonViewValueType;
+        typedef typename Kokkos::View< CommonViewValueType*, ExecSpace >  CVT;
+        typedef typename CVT::HostMirror                                           HostCVT;
+
+        // Construct View using the common type; for case of specialization, an 'embedded_dim' would be stored by view_alloc_arg
+        CVT cv1( Kokkos::view_alloc( "cv1", view_alloc_arg ), N0*N1 );
+
+        Kokkos::parallel_for( Kokkos::RangePolicy< ExecSpace >(0, N0*N1), 
+          Functor(cv1)
+        );
+
+        HostCVT hcv1 = Kokkos::create_mirror_view( cv1 );
+        Kokkos::deep_copy( hcv1, cv1 );
+
+        ASSERT_EQ( (std::is_same< CommonViewValueType, int>::value) , true ) ;
+      }
+    }
+
+
+  } // end test_vcpt
+
+}; // end struct
+
+} // namespace
+
+} // namespace Test
diff --git a/lib/kokkos/containers/unit_tests/UnitTestMain.cpp b/lib/kokkos/containers/unit_tests/UnitTestMain.cpp
index f952ab3db5..2b73535c83 100644
--- a/lib/kokkos/containers/unit_tests/UnitTestMain.cpp
+++ b/lib/kokkos/containers/unit_tests/UnitTestMain.cpp
@@ -1,13 +1,13 @@
 /*
 //@HEADER
 // ************************************************************************
-// 
+//
 //                        Kokkos v. 2.0
 //              Copyright (2014) Sandia Corporation
-// 
+//
 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
 // the U.S. Government retains certain rights in this software.
-// 
+//
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -36,12 +36,14 @@
 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 //
 // Questions? Contact  H. Carter Edwards (hcedwar@sandia.gov)
-// 
+//
 // ************************************************************************
 //@HEADER
 */
 
 #include 
+#include 
+#include 
 
 int main(int argc, char *argv[]) {
   ::testing::InitGoogleTest(&argc,argv);
diff --git a/lib/kokkos/core/perf_test/Makefile b/lib/kokkos/core/perf_test/Makefile
index f59e7bbe1c..bb9353f583 100644
--- a/lib/kokkos/core/perf_test/Makefile
+++ b/lib/kokkos/core/perf_test/Makefile
@@ -79,7 +79,6 @@ test-mempool: KokkosCore_PerformanceTest_Mempool
 test-taskdag: KokkosCore_PerformanceTest_TaskDAG
 	./KokkosCore_PerformanceTest_TaskDAG
 
-
 build_all: $(TARGETS)
 
 test: $(TEST_TARGETS)
diff --git a/lib/kokkos/core/perf_test/PerfTestMain.cpp b/lib/kokkos/core/perf_test/PerfTestMain.cpp
index d80cfab8b5..832f650b9a 100644
--- a/lib/kokkos/core/perf_test/PerfTestMain.cpp
+++ b/lib/kokkos/core/perf_test/PerfTestMain.cpp
@@ -1,13 +1,13 @@
 /*
 //@HEADER
 // ************************************************************************
-// 
+//
 //                        Kokkos v. 2.0
 //              Copyright (2014) Sandia Corporation
-// 
+//
 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
 // the U.S. Government retains certain rights in this software.
-// 
+//
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -36,12 +36,14 @@
 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 //
 // Questions? Contact  H. Carter Edwards (hcedwar@sandia.gov)
-// 
+//
 // ************************************************************************
 //@HEADER
 */
 
 #include 
+#include 
+
 #include 
 
 namespace Test {
diff --git a/lib/kokkos/core/src/Cuda/KokkosExp_Cuda_IterateTile_Refactor.hpp b/lib/kokkos/core/src/Cuda/KokkosExp_Cuda_IterateTile_Refactor.hpp
new file mode 100644
index 0000000000..46321378d9
--- /dev/null
+++ b/lib/kokkos/core/src/Cuda/KokkosExp_Cuda_IterateTile_Refactor.hpp
@@ -0,0 +1,2715 @@
+/*
+//@HEADER
+// ************************************************************************
+//
+//                        Kokkos v. 2.0
+//              Copyright (2014) Sandia Corporation
+//
+// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
+// the U.S. Government retains certain rights in this software.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the Corporation nor the names of the
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Questions? Contact  H. Carter Edwards (hcedwar@sandia.gov)
+//
+// ************************************************************************
+//@HEADER
+*/
+
+#ifndef KOKKOS_CUDA_EXP_ITERATE_TILE_REFACTOR_HPP
+#define KOKKOS_CUDA_EXP_ITERATE_TILE_REFACTOR_HPP
+
+#include 
+#if defined( __CUDACC__ ) && defined( KOKKOS_ENABLE_CUDA )
+
+#include 
+#include 
+#include 
+
+#include 
+
+// #include
+// Including the file above leads to following type of errors:
+// /home/ndellin/kokkos/core/src/Cuda/Kokkos_CudaExec.hpp(84): error: incomplete type is not allowed
+// use existing Kokkos functionality, e.g. max blocks, once resolved
+
+#if defined(KOKKOS_ENABLE_PROFILING)
+#include 
+#include 
+#endif
+
+namespace Kokkos { namespace Experimental { namespace Impl {
+
+namespace Refactor {
+
+// ------------------------------------------------------------------ //
+// ParallelFor iteration pattern
+template< int N , typename RP , typename Functor , typename Tag >
+struct DeviceIterateTile;
+
+//Rank 2
+// Specializations for void tag type
+template< typename RP , typename Functor >
+struct DeviceIterateTile<2,RP,Functor,void >
+{
+  using index_type = typename RP::index_type;
+
+  __device__
+  DeviceIterateTile( const RP & rp_ , const Functor & f_ )
+  : m_rp(rp_)
+  , m_func(f_)
+  {}
+
+  inline __device__
+  void exec_range() const
+  {
+    // LL
+    if (RP::inner_direction == RP::Left) {
+      for ( index_type tile_id1 = (index_type)blockIdx.y; tile_id1 < m_rp.m_tile_end[1]; tile_id1 += gridDim.y ) {
+        const index_type offset_1 = tile_id1*m_rp.m_tile[1] + (index_type)threadIdx.y;
+        if ( offset_1 < m_rp.m_upper[1] && (index_type)threadIdx.y < m_rp.m_tile[1] ) {
+
+          for ( index_type tile_id0 = (index_type)blockIdx.x; tile_id0 < m_rp.m_tile_end[0]; tile_id0 += gridDim.x ) {
+            const index_type offset_0 = tile_id0*m_rp.m_tile[0] + (index_type)threadIdx.x;
+            if ( offset_0 < m_rp.m_upper[0] && (index_type)threadIdx.x < m_rp.m_tile[0] ) {
+              m_func(offset_0 , offset_1);
+            }
+          }
+        }
+      }
+    }
+    // LR
+    else {
+      for ( index_type tile_id0 = (index_type)blockIdx.x; tile_id0 < m_rp.m_tile_end[0]; tile_id0 += gridDim.x ) {
+        const index_type offset_0 = tile_id0*m_rp.m_tile[0] + (index_type)threadIdx.x;
+        if ( offset_0 < m_rp.m_upper[0] && (index_type)threadIdx.x < m_rp.m_tile[0] ) {
+
+          for ( index_type tile_id1 = (index_type)blockIdx.y; tile_id1 < m_rp.m_tile_end[1]; tile_id1 += gridDim.y ) {
+            const index_type offset_1 = tile_id1*m_rp.m_tile[1] + (index_type)threadIdx.y;
+            if ( offset_1 < m_rp.m_upper[1] && (index_type)threadIdx.y < m_rp.m_tile[1] ) {
+              m_func(offset_0 , offset_1);
+            }
+          }
+        }
+      }
+    }
+  } //end exec_range
+
+private:
+  const RP & m_rp;
+  const Functor & m_func;
+};
+
+// Specializations for tag type
+template< typename RP , typename Functor , typename Tag >
+struct DeviceIterateTile<2,RP,Functor,Tag>
+{
+  using index_type = typename RP::index_type;
+
+  inline __device__
+  DeviceIterateTile( const RP & rp_ , const Functor & f_ )
+  : m_rp(rp_)
+  , m_func(f_)
+  {}
+
+  inline __device__
+  void exec_range() const
+  {
+    if (RP::inner_direction == RP::Left) {
+      // Loop over size maxnumblocks until full range covered
+      for ( index_type tile_id1 = (index_type)blockIdx.y; tile_id1 < m_rp.m_tile_end[1]; tile_id1 += gridDim.y ) {
+        const index_type offset_1 = tile_id1*m_rp.m_tile[1] + (index_type)threadIdx.y;
+        if ( offset_1 < m_rp.m_upper[1] && (index_type)threadIdx.y < m_rp.m_tile[1] ) {
+
+          for ( index_type tile_id0 = (index_type)blockIdx.x; tile_id0 < m_rp.m_tile_end[0]; tile_id0 += gridDim.x ) {
+            const index_type offset_0 = tile_id0*m_rp.m_tile[0] + (index_type)threadIdx.x;
+            if ( offset_0 < m_rp.m_upper[0] && (index_type)threadIdx.x < m_rp.m_tile[0] ) {
+              m_func(Tag(), offset_0 , offset_1);
+            }
+          }
+        }
+      }
+    }
+    else {
+      for ( index_type tile_id0 = (index_type)blockIdx.x; tile_id0 < m_rp.m_tile_end[0]; tile_id0 += gridDim.x ) {
+        const index_type offset_0 = tile_id0*m_rp.m_tile[0] + (index_type)threadIdx.x;
+        if ( offset_0 < m_rp.m_upper[0] && (index_type)threadIdx.x < m_rp.m_tile[0] ) {
+
+          for ( index_type tile_id1 = (index_type)blockIdx.y; tile_id1 < m_rp.m_tile_end[1]; tile_id1 += gridDim.y ) {
+            const index_type offset_1 = tile_id1*m_rp.m_tile[1] + (index_type)threadIdx.y;
+            if ( offset_1 < m_rp.m_upper[1] && (index_type)threadIdx.y < m_rp.m_tile[1] ) {
+              m_func(Tag(), offset_0 , offset_1);
+            }
+          }
+        }
+      }
+    }
+  } //end exec_range
+
+private:
+  const RP & m_rp;
+  const Functor & m_func;
+};
+
+
+//Rank 3
+// Specializations for void tag type
+template< typename RP , typename Functor >
+struct DeviceIterateTile<3,RP,Functor,void >
+{
+  using index_type = typename RP::index_type;
+
+  __device__
+  DeviceIterateTile( const RP & rp_ , const Functor & f_ )
+  : m_rp(rp_)
+  , m_func(f_)
+  {}
+
+  inline __device__
+  void exec_range() const
+  {
+    // LL
+    if (RP::inner_direction == RP::Left) {
+      for ( index_type tile_id2 = (index_type)blockIdx.z; tile_id2 < m_rp.m_tile_end[2]; tile_id2 += gridDim.z ) {
+        const index_type offset_2 = tile_id2*m_rp.m_tile[2] + (index_type)threadIdx.z;
+        if ( offset_2 < m_rp.m_upper[2] && (index_type)threadIdx.z < m_rp.m_tile[2] ) {
+
+          for ( index_type tile_id1 = (index_type)blockIdx.y; tile_id1 < m_rp.m_tile_end[1]; tile_id1 += gridDim.y ) {
+            const index_type offset_1 = tile_id1*m_rp.m_tile[1] + (index_type)threadIdx.y;
+            if ( offset_1 < m_rp.m_upper[1] && (index_type)threadIdx.y < m_rp.m_tile[1] ) {
+
+              for ( index_type tile_id0 = (index_type)blockIdx.x; tile_id0 < m_rp.m_tile_end[0]; tile_id0 += gridDim.x ) {
+                const index_type offset_0 = tile_id0*m_rp.m_tile[0] + (index_type)threadIdx.x;
+                if ( offset_0 < m_rp.m_upper[0] && (index_type)threadIdx.x < m_rp.m_tile[0] ) {
+                  m_func(offset_0 , offset_1 , offset_2);
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+    // LR
+    else {
+      for ( index_type tile_id0 = (index_type)blockIdx.x; tile_id0 < m_rp.m_tile_end[0]; tile_id0 += gridDim.x ) {
+        const index_type offset_0 = tile_id0*m_rp.m_tile[0] + (index_type)threadIdx.x;
+        if ( offset_0 < m_rp.m_upper[0] && (index_type)threadIdx.x < m_rp.m_tile[0] ) {
+
+          for ( index_type tile_id1 = (index_type)blockIdx.y; tile_id1 < m_rp.m_tile_end[1]; tile_id1 += gridDim.y ) {
+            const index_type offset_1 = tile_id1*m_rp.m_tile[1] + (index_type)threadIdx.y;
+            if ( offset_1 < m_rp.m_upper[1] && (index_type)threadIdx.y < m_rp.m_tile[1] ) {
+
+              for ( index_type tile_id2 = (index_type)blockIdx.z; tile_id2 < m_rp.m_tile_end[2]; tile_id2 += gridDim.z ) {
+                const index_type offset_2 = tile_id2*m_rp.m_tile[2] + (index_type)threadIdx.z;
+                if ( offset_2 < m_rp.m_upper[2] && (index_type)threadIdx.z < m_rp.m_tile[2] ) {
+                  m_func(offset_0 , offset_1 , offset_2);
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  } //end exec_range
+
+private:
+  const RP & m_rp;
+  const Functor & m_func;
+};
+
+// Specializations for void tag type
+template< typename RP , typename Functor , typename Tag >
+struct DeviceIterateTile<3,RP,Functor,Tag>
+{
+  using index_type = typename RP::index_type;
+
+  inline __device__
+  DeviceIterateTile( const RP & rp_ , const Functor & f_ )
+  : m_rp(rp_)
+  , m_func(f_)
+  {}
+
+  inline __device__
+  void exec_range() const
+  {
+    if (RP::inner_direction == RP::Left) {
+      for ( index_type tile_id2 = (index_type)blockIdx.z; tile_id2 < m_rp.m_tile_end[2]; tile_id2 += gridDim.z ) {
+        const index_type offset_2 = tile_id2*m_rp.m_tile[2] + (index_type)threadIdx.z;
+        if ( offset_2 < m_rp.m_upper[2] && (index_type)threadIdx.z < m_rp.m_tile[2] ) {
+
+          for ( index_type tile_id1 = (index_type)blockIdx.y; tile_id1 < m_rp.m_tile_end[1]; tile_id1 += gridDim.y ) {
+            const index_type offset_1 = tile_id1*m_rp.m_tile[1] + (index_type)threadIdx.y;
+            if ( offset_1 < m_rp.m_upper[1] && (index_type)threadIdx.y < m_rp.m_tile[1] ) {
+
+              for ( index_type tile_id0 = (index_type)blockIdx.x; tile_id0 < m_rp.m_tile_end[0]; tile_id0 += gridDim.x ) {
+                const index_type offset_0 = tile_id0*m_rp.m_tile[0] + (index_type)threadIdx.x;
+                if ( offset_0 < m_rp.m_upper[0] && (index_type)threadIdx.x < m_rp.m_tile[0] ) {
+                  m_func(Tag(), offset_0 , offset_1 , offset_2);
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+    else {
+      for ( index_type tile_id0 = (index_type)blockIdx.x; tile_id0 < m_rp.m_tile_end[0]; tile_id0 += gridDim.x ) {
+        const index_type offset_0 = tile_id0*m_rp.m_tile[0] + (index_type)threadIdx.x;
+        if ( offset_0 < m_rp.m_upper[0] && (index_type)threadIdx.x < m_rp.m_tile[0] ) {
+
+          for ( index_type tile_id1 = (index_type)blockIdx.y; tile_id1 < m_rp.m_tile_end[1]; tile_id1 += gridDim.y ) {
+            const index_type offset_1 = tile_id1*m_rp.m_tile[1] + (index_type)threadIdx.y;
+            if ( offset_1 < m_rp.m_upper[1] && (index_type)threadIdx.y < m_rp.m_tile[1] ) {
+
+              for ( index_type tile_id2 = (index_type)blockIdx.z; tile_id2 < m_rp.m_tile_end[2]; tile_id2 += gridDim.z ) {
+                const index_type offset_2 = tile_id2*m_rp.m_tile[2] + (index_type)threadIdx.z;
+                if ( offset_2 < m_rp.m_upper[2] && (index_type)threadIdx.z < m_rp.m_tile[2] ) {
+                  m_func(Tag(), offset_0 , offset_1 , offset_2);
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  } //end exec_range
+
+private:
+  const RP & m_rp;
+  const Functor & m_func;
+};
+
+
+//Rank 4
+// Specializations for void tag type
+template< typename RP , typename Functor >
+struct DeviceIterateTile<4,RP,Functor,void >
+{
+  using index_type = typename RP::index_type;
+
+  __device__
+  DeviceIterateTile( const RP & rp_ , const Functor & f_ )
+  : m_rp(rp_)
+  , m_func(f_)
+  {}
+
+  static constexpr index_type max_blocks = 65535;
+  //static constexpr index_type max_blocks = static_cast(Kokkos::Impl::CudaTraits::UpperBoundGridCount);
+
+  inline __device__
+  void exec_range() const
+  {
+    //enum { max_blocks = static_cast(Kokkos::Impl::CudaTraits::UpperBoundGridCount) };
+    //const index_type max_blocks = static_cast( Kokkos::Impl::cuda_internal_maximum_grid_count() );
+    // LL
+    if (RP::inner_direction == RP::Left) {
+      const index_type temp0  =  m_rp.m_tile_end[0];
+      const index_type temp1  =  m_rp.m_tile_end[1];
+      const index_type numbl0 = ( temp0 <= max_blocks ? temp0 : max_blocks ) ;
+      const index_type numbl1 = ( temp0*temp1 > max_blocks ? index_type( max_blocks / numbl0 ) :
+          (  temp1 <= max_blocks ? temp1 : max_blocks ) );
+
+      const index_type tile_id0 = (index_type)blockIdx.x % numbl0;
+      const index_type tile_id1 = (index_type)blockIdx.x / numbl0;
+      const index_type thr_id0 = (index_type)threadIdx.x % m_rp.m_tile[0];
+      const index_type thr_id1 = (index_type)threadIdx.x / m_rp.m_tile[0];
+
+      for ( index_type tile_id3 = (index_type)blockIdx.z; tile_id3 < m_rp.m_tile_end[3]; tile_id3 += gridDim.z ) {
+        const index_type offset_3 = tile_id3*m_rp.m_tile[3] + (index_type)threadIdx.z;
+        if ( offset_3 < m_rp.m_upper[3] && (index_type)threadIdx.z < m_rp.m_tile[3] ) {
+
+          for ( index_type tile_id2 = (index_type)blockIdx.y; tile_id2 < m_rp.m_tile_end[2]; tile_id2 += gridDim.y ) {
+            const index_type offset_2 = tile_id2*m_rp.m_tile[2] + (index_type)threadIdx.y;
+            if ( offset_2 < m_rp.m_upper[2] && (index_type)threadIdx.y < m_rp.m_tile[2] ) {
+
+              for ( index_type j = tile_id1 ; j < m_rp.m_tile_end[1]; j += numbl1 ) {
+                const index_type offset_1 = j*m_rp.m_tile[1] + thr_id1;
+                if ( offset_1 < m_rp.m_upper[1] && thr_id1 < m_rp.m_tile[1] ) {
+
+                  for ( index_type i = tile_id0 ; i < m_rp.m_tile_end[0]; i += numbl0 ) {
+                    const index_type offset_0 = i*m_rp.m_tile[0] + thr_id0;
+                    if ( offset_0 < m_rp.m_upper[0] && thr_id0 < m_rp.m_tile[0] ) {
+                      m_func(offset_0 , offset_1 , offset_2 , offset_3);
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+    // LR
+    else {
+      const index_type temp0  =  m_rp.m_tile_end[0];
+      const index_type temp1  =  m_rp.m_tile_end[1];
+      const index_type numbl1 = ( temp1 <= max_blocks ? temp1 : max_blocks ) ;
+      const index_type numbl0 = ( temp0*temp1 > max_blocks ? index_type( max_blocks / numbl1 ) :
+          ( temp0 <= max_blocks ? temp0 : max_blocks ) );
+
+      const index_type tile_id0 = (index_type)blockIdx.x / numbl1;
+      const index_type tile_id1 = (index_type)blockIdx.x % numbl1;
+      const index_type thr_id0 = (index_type)threadIdx.x / m_rp.m_tile[1];
+      const index_type thr_id1 = (index_type)threadIdx.x % m_rp.m_tile[1];
+
+      for ( index_type i = tile_id0; i < m_rp.m_tile_end[0]; i += numbl0 ) {
+        const index_type offset_0 = i*m_rp.m_tile[0] + thr_id0;
+        if ( offset_0 < m_rp.m_upper[0] && thr_id0 < m_rp.m_tile[0] ) {
+
+          for ( index_type j = tile_id1; j < m_rp.m_tile_end[1]; j += numbl1 ) {
+            const index_type offset_1 = j*m_rp.m_tile[1] + thr_id1;
+            if ( offset_1 < m_rp.m_upper[1] && thr_id1 < m_rp.m_tile[1] ) {
+
+              for ( index_type tile_id2 = (index_type)blockIdx.y; tile_id2 < m_rp.m_tile_end[2]; tile_id2 += gridDim.y ) {
+                const index_type offset_2 = tile_id2*m_rp.m_tile[2] + (index_type)threadIdx.y;
+                if ( offset_2 < m_rp.m_upper[2] && (index_type)threadIdx.y < m_rp.m_tile[2] ) {
+
+                  for ( index_type tile_id3 = (index_type)blockIdx.z; tile_id3 < m_rp.m_tile_end[3]; tile_id3 += gridDim.z ) {
+                    const index_type offset_3 = tile_id3*m_rp.m_tile[3] + (index_type)threadIdx.z;
+                    if ( offset_3 < m_rp.m_upper[3] && (index_type)threadIdx.z < m_rp.m_tile[3] ) {
+                      m_func(offset_0 , offset_1 , offset_2 , offset_3);
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  } //end exec_range
+
+private:
+  const RP & m_rp;
+  const Functor & m_func;
+};
+
+// Specializations for void tag type
+template< typename RP , typename Functor , typename Tag >
+struct DeviceIterateTile<4,RP,Functor,Tag>
+{
+  using index_type = typename RP::index_type;
+
+  inline __device__
+  DeviceIterateTile( const RP & rp_ , const Functor & f_ )
+  : m_rp(rp_)
+  , m_func(f_)
+  {}
+
+  static constexpr index_type max_blocks = 65535;
+  //static constexpr index_type max_blocks = static_cast(Kokkos::Impl::CudaTraits::UpperBoundGridCount);
+
+  inline __device__
+  void exec_range() const
+  {
+    //enum { max_blocks = static_cast(Kokkos::Impl::CudaTraits::UpperBoundGridCount) };
+    //const index_type max_blocks = static_cast( Kokkos::Impl::cuda_internal_maximum_grid_count() );
+    if (RP::inner_direction == RP::Left) {
+      const index_type temp0  =  m_rp.m_tile_end[0];
+      const index_type temp1  =  m_rp.m_tile_end[1];
+      const index_type numbl0 = ( temp0 <= max_blocks ? temp0 : max_blocks ) ;
+      const index_type numbl1 = ( temp0*temp1 > max_blocks ? index_type( max_blocks / numbl0 ) :
+          (  temp1 <= max_blocks ? temp1 : max_blocks ) );
+
+      const index_type tile_id0 = (index_type)blockIdx.x % numbl0;
+      const index_type tile_id1 = (index_type)blockIdx.x / numbl0;
+      const index_type thr_id0 = (index_type)threadIdx.x % m_rp.m_tile[0];
+      const index_type thr_id1 = (index_type)threadIdx.x / m_rp.m_tile[0];
+
+      for ( index_type tile_id3 = (index_type)blockIdx.z; tile_id3 < m_rp.m_tile_end[3]; tile_id3 += gridDim.z ) {
+        const index_type offset_3 = tile_id3*m_rp.m_tile[3] + (index_type)threadIdx.z;
+        if ( offset_3 < m_rp.m_upper[3] && (index_type)threadIdx.z < m_rp.m_tile[3] ) {
+
+          for ( index_type tile_id2 = (index_type)blockIdx.y; tile_id2 < m_rp.m_tile_end[2]; tile_id2 += gridDim.y ) {
+            const index_type offset_2 = tile_id2*m_rp.m_tile[2] + (index_type)threadIdx.y;
+            if ( offset_2 < m_rp.m_upper[2] && (index_type)threadIdx.y < m_rp.m_tile[2] ) {
+
+              for ( index_type j = tile_id1; j < m_rp.m_tile_end[1]; j += numbl1 ) {
+                const index_type offset_1 = j*m_rp.m_tile[1] + thr_id1;
+                if ( offset_1 < m_rp.m_upper[1] && thr_id1 < m_rp.m_tile[1] ) {
+
+                  for ( index_type i = tile_id0; i < m_rp.m_tile_end[0]; i += numbl0 ) {
+                    const index_type offset_0 = i*m_rp.m_tile[0] + thr_id0;
+                    if ( offset_0 < m_rp.m_upper[0] && thr_id0 < m_rp.m_tile[0] ) {
+                      m_func(Tag(), offset_0 , offset_1 , offset_2 , offset_3);
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+    else {
+      const index_type temp0  =  m_rp.m_tile_end[0];
+      const index_type temp1  =  m_rp.m_tile_end[1];
+      const index_type numbl1 = ( temp1 <= max_blocks ? temp1 : max_blocks ) ;
+      const index_type numbl0 = ( temp0*temp1 > max_blocks ? index_type( max_blocks / numbl1 ) :
+          ( temp0 <= max_blocks ? temp0 : max_blocks ) );
+
+      const index_type tile_id0 = (index_type)blockIdx.x / numbl1;
+      const index_type tile_id1 = (index_type)blockIdx.x % numbl1;
+      const index_type thr_id0 = (index_type)threadIdx.x / m_rp.m_tile[1];
+      const index_type thr_id1 = (index_type)threadIdx.x % m_rp.m_tile[1];
+
+      for ( index_type i = tile_id0; i < m_rp.m_tile_end[0]; i += numbl0 ) {
+        const index_type offset_0 = i*m_rp.m_tile[0] + thr_id0;
+        if ( offset_0 < m_rp.m_upper[0] && thr_id0 < m_rp.m_tile[0] ) {
+
+          for ( index_type j = tile_id1; j < m_rp.m_tile_end[1]; j += numbl1 ) {
+            const index_type offset_1 = tile_id1*m_rp.m_tile[1] + thr_id1;
+            if ( offset_1 < m_rp.m_upper[1] && thr_id1 < m_rp.m_tile[1] ) {
+
+              for ( index_type tile_id2 = (index_type)blockIdx.y; tile_id2 < m_rp.m_tile_end[2]; tile_id2 += gridDim.y ) {
+                const index_type offset_2 = tile_id2*m_rp.m_tile[2] + (index_type)threadIdx.y;
+                if ( offset_2 < m_rp.m_upper[2] && (index_type)threadIdx.y < m_rp.m_tile[2] ) {
+
+                  for ( index_type tile_id3 = (index_type)blockIdx.z; tile_id3 < m_rp.m_tile_end[3]; tile_id3 += gridDim.z ) {
+                    const index_type offset_3 = tile_id3*m_rp.m_tile[3] + (index_type)threadIdx.z;
+                    if ( offset_3 < m_rp.m_upper[3] && (index_type)threadIdx.z < m_rp.m_tile[3] ) {
+                      m_func(Tag() , offset_0 , offset_1 , offset_2 , offset_3);
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  } //end exec_range
+
+private:
+  const RP & m_rp;
+  const Functor & m_func;
+};
+
+
+//Rank 5
+// Specializations for void tag type
+template< typename RP , typename Functor >
+struct DeviceIterateTile<5,RP,Functor,void >
+{
+  using index_type = typename RP::index_type;
+
+  __device__
+  DeviceIterateTile( const RP & rp_ , const Functor & f_ )
+  : m_rp(rp_)
+  , m_func(f_)
+  {}
+
+  static constexpr index_type max_blocks = 65535;
+  //static constexpr index_type max_blocks = static_cast(Kokkos::Impl::CudaTraits::UpperBoundGridCount);
+
+  inline __device__
+  void exec_range() const
+  {
+    //enum { max_blocks = static_cast(Kokkos::Impl::CudaTraits::UpperBoundGridCount) };
+    //const index_type max_blocks = static_cast( Kokkos::Impl::cuda_internal_maximum_grid_count() );
+    // LL
+    if (RP::inner_direction == RP::Left) {
+
+      index_type temp0  =  m_rp.m_tile_end[0];
+      index_type temp1  =  m_rp.m_tile_end[1];
+      const index_type numbl0 = ( temp0 <= max_blocks ? temp0 : max_blocks ) ;
+      const index_type numbl1 = ( temp0*temp1 > max_blocks ? index_type( max_blocks / numbl0 ) :
+          (  temp1 <= max_blocks ? temp1 : max_blocks ) );
+
+      const index_type tile_id0 = (index_type)blockIdx.x % numbl0;
+      const index_type tile_id1 = (index_type)blockIdx.x / numbl0;
+      const index_type thr_id0 = (index_type)threadIdx.x % m_rp.m_tile[0];
+      const index_type thr_id1 = (index_type)threadIdx.x / m_rp.m_tile[0];
+
+      temp0  =  m_rp.m_tile_end[2];
+      temp1  =  m_rp.m_tile_end[3];
+      const index_type numbl2 = ( temp0 <= max_blocks ? temp0 : max_blocks ) ;
+      const index_type numbl3 = ( temp0*temp1 > max_blocks ? index_type( max_blocks / numbl2 ) :
+          (  temp1 <= max_blocks ? temp1 : max_blocks ) );
+
+      const index_type tile_id2 = (index_type)blockIdx.y % numbl2;
+      const index_type tile_id3 = (index_type)blockIdx.y / numbl2;
+      const index_type thr_id2 = (index_type)threadIdx.y % m_rp.m_tile[2];
+      const index_type thr_id3 = (index_type)threadIdx.y / m_rp.m_tile[2];
+
+      for ( index_type tile_id4 = (index_type)blockIdx.z; tile_id4 < m_rp.m_tile_end[4]; tile_id4 += gridDim.z ) {
+        const index_type offset_4 = tile_id4*m_rp.m_tile[4] + (index_type)threadIdx.z;
+        if ( offset_4 < m_rp.m_upper[4] && (index_type)threadIdx.z < m_rp.m_tile[4] ) {
+
+          for ( index_type l = tile_id3; l < m_rp.m_tile_end[3]; l += numbl3 ) {
+            const index_type offset_3 = l*m_rp.m_tile[3] + thr_id3;
+            if ( offset_3 < m_rp.m_upper[3] && thr_id3 < m_rp.m_tile[3] ) {
+
+              for ( index_type k = tile_id2; k < m_rp.m_tile_end[2]; k += numbl2 ) {
+                const index_type offset_2 = k*m_rp.m_tile[2] + thr_id2;
+                if ( offset_2 < m_rp.m_upper[2] && thr_id2 < m_rp.m_tile[2] ) {
+
+                  for ( index_type j = tile_id1 ; j < m_rp.m_tile_end[1]; j += numbl1 ) {
+                    const index_type offset_1 = j*m_rp.m_tile[1] + thr_id1;
+                    if ( offset_1 < m_rp.m_upper[1] && thr_id1 < m_rp.m_tile[1] ) {
+
+                      for ( index_type i = tile_id0 ; i < m_rp.m_tile_end[0]; i += numbl0 ) {
+                        const index_type offset_0 = i*m_rp.m_tile[0] + thr_id0;
+                        if ( offset_0 < m_rp.m_upper[0] && thr_id0 < m_rp.m_tile[0] ) {
+                          m_func(offset_0 , offset_1 , offset_2 , offset_3, offset_4);
+                        }
+                      }
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+    // LR
+    else {
+      index_type temp0  =  m_rp.m_tile_end[0];
+      index_type temp1  =  m_rp.m_tile_end[1];
+      const index_type numbl1 = ( temp1 <= max_blocks ? temp1 : max_blocks ) ;
+      const index_type numbl0 = ( temp0*temp1 > max_blocks ? index_type( max_blocks / numbl1 ) :
+          ( temp0 <= max_blocks ? temp0 : max_blocks ) );
+
+      const index_type tile_id0 = (index_type)blockIdx.x / numbl1;
+      const index_type tile_id1 = (index_type)blockIdx.x % numbl1;
+      const index_type thr_id0 = (index_type)threadIdx.x / m_rp.m_tile[1];
+      const index_type thr_id1 = (index_type)threadIdx.x % m_rp.m_tile[1];
+
+      temp0  =  m_rp.m_tile_end[2];
+      temp1  =  m_rp.m_tile_end[3];
+      const index_type numbl3 = ( temp1 <= max_blocks ? temp1 : max_blocks ) ;
+      const index_type numbl2 = ( temp0*temp1 > max_blocks ? index_type( max_blocks / numbl3 ) :
+          (  temp0 <= max_blocks ? temp0 : max_blocks ) );
+
+      const index_type tile_id2 = (index_type)blockIdx.y / numbl3;
+      const index_type tile_id3 = (index_type)blockIdx.y % numbl3;
+      const index_type thr_id2 = (index_type)threadIdx.y / m_rp.m_tile[3];
+      const index_type thr_id3 = (index_type)threadIdx.y % m_rp.m_tile[3];
+
+      for ( index_type i = tile_id0; i < m_rp.m_tile_end[0]; i += numbl0 ) {
+        const index_type offset_0 = i*m_rp.m_tile[0] + thr_id0;
+        if ( offset_0 < m_rp.m_upper[0] && thr_id0 < m_rp.m_tile[0] ) {
+
+          for ( index_type j = tile_id1; j < m_rp.m_tile_end[1]; j += numbl1 ) {
+            const index_type offset_1 = j*m_rp.m_tile[1] + thr_id1;
+            if ( offset_1 < m_rp.m_upper[1] && thr_id1 < m_rp.m_tile[1] ) {
+
+              for ( index_type k = tile_id2; k < m_rp.m_tile_end[2]; k += numbl2 ) {
+                const index_type offset_2 = k*m_rp.m_tile[2] + thr_id2;
+                if ( offset_2 < m_rp.m_upper[2] && thr_id2 < m_rp.m_tile[2] ) {
+
+                  for ( index_type l = tile_id3; l < m_rp.m_tile_end[3]; l += numbl3 ) {
+                    const index_type offset_3 = l*m_rp.m_tile[3] + thr_id3;
+                    if ( offset_3 < m_rp.m_upper[3] && thr_id3 < m_rp.m_tile[3] ) {
+
+                      for ( index_type tile_id4 = (index_type)blockIdx.z; tile_id4 < m_rp.m_tile_end[4]; tile_id4 += gridDim.z ) {
+                        const index_type offset_4 = tile_id4*m_rp.m_tile[4] + (index_type)threadIdx.z;
+                        if ( offset_4 < m_rp.m_upper[4] && (index_type)threadIdx.z < m_rp.m_tile[4] ) {
+                          m_func(offset_0 , offset_1 , offset_2 , offset_3 , offset_4);
+                        }
+                      }
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  } //end exec_range
+
+private:
+  const RP & m_rp;
+  const Functor & m_func;
+};
+
+// Specializations for tag type
+template< typename RP , typename Functor , typename Tag >
+struct DeviceIterateTile<5,RP,Functor,Tag>
+{
+  using index_type = typename RP::index_type;
+
+  __device__
+  DeviceIterateTile( const RP & rp_ , const Functor & f_ )
+  : m_rp(rp_)
+  , m_func(f_)
+  {}
+
+  static constexpr index_type max_blocks = 65535;
+  //static constexpr index_type max_blocks = static_cast(Kokkos::Impl::CudaTraits::UpperBoundGridCount);
+
+  inline __device__
+  void exec_range() const
+  {
+    //enum { max_blocks = static_cast(Kokkos::Impl::CudaTraits::UpperBoundGridCount) };
+    //const index_type max_blocks = static_cast( Kokkos::Impl::cuda_internal_maximum_grid_count() );
+    // LL
+    if (RP::inner_direction == RP::Left) {
+      index_type temp0  =  m_rp.m_tile_end[0];
+      index_type temp1  =  m_rp.m_tile_end[1];
+      const index_type numbl0 = ( temp0 <= max_blocks ? temp0 : max_blocks ) ;
+      const index_type numbl1 = ( temp0*temp1 > max_blocks ? index_type( max_blocks / numbl0 ) :
+          (  temp1 <= max_blocks ? temp1 : max_blocks ) );
+
+      const index_type tile_id0 = (index_type)blockIdx.x % numbl0;
+      const index_type tile_id1 = (index_type)blockIdx.x / numbl0;
+      const index_type thr_id0 = (index_type)threadIdx.x % m_rp.m_tile[0];
+      const index_type thr_id1 = (index_type)threadIdx.x / m_rp.m_tile[0];
+
+      temp0  =  m_rp.m_tile_end[2];
+      temp1  =  m_rp.m_tile_end[3];
+      const index_type numbl2 = ( temp0 <= max_blocks ? temp0 : max_blocks ) ;
+      const index_type numbl3 = ( temp0*temp1 > max_blocks ? index_type( max_blocks / numbl2 ) :
+          (  temp1 <= max_blocks ? temp1 : max_blocks ) );
+
+      const index_type tile_id2 = (index_type)blockIdx.y % numbl2;
+      const index_type tile_id3 = (index_type)blockIdx.y / numbl2;
+      const index_type thr_id2 = (index_type)threadIdx.y % m_rp.m_tile[2];
+      const index_type thr_id3 = (index_type)threadIdx.y / m_rp.m_tile[2];
+
+      for ( index_type tile_id4 = (index_type)blockIdx.z; tile_id4 < m_rp.m_tile_end[4]; tile_id4 += gridDim.z ) {
+        const index_type offset_4 = tile_id4*m_rp.m_tile[4] + (index_type)threadIdx.z;
+        if ( offset_4 < m_rp.m_upper[4] && (index_type)threadIdx.z < m_rp.m_tile[4] ) {
+
+          for ( index_type l = tile_id3; l < m_rp.m_tile_end[3]; l += numbl3 ) {
+            const index_type offset_3 = l*m_rp.m_tile[3] + thr_id3;
+            if ( offset_3 < m_rp.m_upper[3] && thr_id3 < m_rp.m_tile[3] ) {
+
+              for ( index_type k = tile_id2; k < m_rp.m_tile_end[2]; k += numbl2 ) {
+                const index_type offset_2 = k*m_rp.m_tile[2] + thr_id2;
+                if ( offset_2 < m_rp.m_upper[2] && thr_id2 < m_rp.m_tile[2] ) {
+
+                  for ( index_type j = tile_id1 ; j < m_rp.m_tile_end[1]; j += numbl1 ) {
+                    const index_type offset_1 = j*m_rp.m_tile[1] + thr_id1;
+                    if ( offset_1 < m_rp.m_upper[1] && thr_id1 < m_rp.m_tile[1] ) {
+
+                      for ( index_type i = tile_id0 ; i < m_rp.m_tile_end[0]; i += numbl0 ) {
+                        const index_type offset_0 = i*m_rp.m_tile[0] + thr_id0;
+                        if ( offset_0 < m_rp.m_upper[0] && thr_id0 < m_rp.m_tile[0] ) {
+                          m_func(Tag() , offset_0 , offset_1 , offset_2 , offset_3, offset_4);
+                        }
+                      }
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+    // LR
+    else {
+      index_type temp0  =  m_rp.m_tile_end[0];
+      index_type temp1  =  m_rp.m_tile_end[1];
+      const index_type numbl1 = ( temp1 <= max_blocks ? temp1 : max_blocks ) ;
+      const index_type numbl0 = ( temp0*temp1 > max_blocks ? index_type( max_blocks / numbl1 ) :
+          ( temp0 <= max_blocks ? temp0 : max_blocks ) );
+
+      const index_type tile_id0 = (index_type)blockIdx.x / numbl1;
+      const index_type tile_id1 = (index_type)blockIdx.x % numbl1;
+      const index_type thr_id0 = (index_type)threadIdx.x / m_rp.m_tile[1];
+      const index_type thr_id1 = (index_type)threadIdx.x % m_rp.m_tile[1];
+
+      temp0  =  m_rp.m_tile_end[2];
+      temp1  =  m_rp.m_tile_end[3];
+      const index_type numbl3 = ( temp1 <= max_blocks ? temp1 : max_blocks ) ;
+      const index_type numbl2 = ( temp0*temp1 > max_blocks ? index_type( max_blocks / numbl3 ) :
+          (  temp0 <= max_blocks ? temp0 : max_blocks ) );
+
+      const index_type tile_id2 = (index_type)blockIdx.y / numbl3;
+      const index_type tile_id3 = (index_type)blockIdx.y % numbl3;
+      const index_type thr_id2 = (index_type)threadIdx.y / m_rp.m_tile[3];
+      const index_type thr_id3 = (index_type)threadIdx.y % m_rp.m_tile[3];
+
+      for ( index_type i = tile_id0; i < m_rp.m_tile_end[0]; i += numbl0 ) {
+        const index_type offset_0 = i*m_rp.m_tile[0] + thr_id0;
+        if ( offset_0 < m_rp.m_upper[0] && thr_id0 < m_rp.m_tile[0] ) {
+
+          for ( index_type j = tile_id1; j < m_rp.m_tile_end[1]; j += numbl1 ) {
+            const index_type offset_1 = j*m_rp.m_tile[1] + thr_id1;
+            if ( offset_1 < m_rp.m_upper[1] && thr_id1 < m_rp.m_tile[1] ) {
+
+              for ( index_type k = tile_id2; k < m_rp.m_tile_end[2]; k += numbl2 ) {
+                const index_type offset_2 = k*m_rp.m_tile[2] + thr_id2;
+                if ( offset_2 < m_rp.m_upper[2] && thr_id2 < m_rp.m_tile[2] ) {
+
+                  for ( index_type l = tile_id3; l < m_rp.m_tile_end[3]; l += numbl3 ) {
+                    const index_type offset_3 = l*m_rp.m_tile[3] + thr_id3;
+                    if ( offset_3 < m_rp.m_upper[3] && thr_id3 < m_rp.m_tile[3] ) {
+
+                      for ( index_type tile_id4 = (index_type)blockIdx.z; tile_id4 < m_rp.m_tile_end[4]; tile_id4 += gridDim.z ) {
+                        const index_type offset_4 = tile_id4*m_rp.m_tile[4] + (index_type)threadIdx.z;
+                        if ( offset_4 < m_rp.m_upper[4] && (index_type)threadIdx.z < m_rp.m_tile[4] ) {
+                          m_func(Tag() , offset_0 , offset_1 , offset_2 , offset_3 , offset_4);
+                        }
+                      }
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  } //end exec_range
+
+private:
+  const RP & m_rp;
+  const Functor & m_func;
+};
+
+
+//Rank 6
+// Specializations for void tag type
+template< typename RP , typename Functor >
+struct DeviceIterateTile<6,RP,Functor,void >
+{
+  using index_type = typename RP::index_type;
+
+  __device__
+  DeviceIterateTile( const RP & rp_ , const Functor & f_ )
+  : m_rp(rp_)
+  , m_func(f_)
+  {}
+
+  static constexpr index_type max_blocks = 65535;
+  //static constexpr index_type max_blocks = static_cast(Kokkos::Impl::CudaTraits::UpperBoundGridCount);
+
+  inline __device__
+  void exec_range() const
+  {
+    //enum { max_blocks = static_cast(Kokkos::Impl::CudaTraits::UpperBoundGridCount) };
+    //const index_type max_blocks = static_cast( Kokkos::Impl::cuda_internal_maximum_grid_count() );
+    // LL
+    if (RP::inner_direction == RP::Left) {
+      index_type temp0  =  m_rp.m_tile_end[0];
+      index_type temp1  =  m_rp.m_tile_end[1];
+      const index_type numbl0 = ( temp0 <= max_blocks ? temp0 : max_blocks ) ;
+      const index_type numbl1 = ( temp0*temp1 > max_blocks ? index_type( max_blocks / numbl0 ) :
+          (  temp1 <= max_blocks ? temp1 : max_blocks ) );
+
+      const index_type tile_id0 = (index_type)blockIdx.x % numbl0;
+      const index_type tile_id1 = (index_type)blockIdx.x / numbl0;
+      const index_type thr_id0 = (index_type)threadIdx.x % m_rp.m_tile[0];
+      const index_type thr_id1 = (index_type)threadIdx.x / m_rp.m_tile[0];
+
+      temp0  =  m_rp.m_tile_end[2];
+      temp1  =  m_rp.m_tile_end[3];
+      const index_type numbl2 = ( temp0 <= max_blocks ? temp0 : max_blocks ) ;
+      const index_type numbl3 = ( temp0*temp1 > max_blocks ? index_type( max_blocks / numbl2 ) :
+          (  temp1 <= max_blocks ? temp1 : max_blocks ) );
+
+      const index_type tile_id2 = (index_type)blockIdx.y % numbl2;
+      const index_type tile_id3 = (index_type)blockIdx.y / numbl2;
+      const index_type thr_id2 = (index_type)threadIdx.y % m_rp.m_tile[2];
+      const index_type thr_id3 = (index_type)threadIdx.y / m_rp.m_tile[2];
+
+      temp0  =  m_rp.m_tile_end[4];
+      temp1  =  m_rp.m_tile_end[5];
+      const index_type numbl4 = ( temp0 <= max_blocks ? temp0 : max_blocks ) ;
+      const index_type numbl5 = ( temp0*temp1 > max_blocks ? index_type( max_blocks / numbl4 ) :
+          (  temp1 <= max_blocks ? temp1 : max_blocks ) );
+
+      const index_type tile_id4 = (index_type)blockIdx.z % numbl4;
+      const index_type tile_id5 = (index_type)blockIdx.z / numbl4;
+      const index_type thr_id4 = (index_type)threadIdx.z % m_rp.m_tile[4];
+      const index_type thr_id5 = (index_type)threadIdx.z / m_rp.m_tile[4];
+
+      for ( index_type n = tile_id5; n < m_rp.m_tile_end[5]; n += numbl5 ) {
+        const index_type offset_5 = n*m_rp.m_tile[5] + thr_id5;
+        if ( offset_5 < m_rp.m_upper[5] && thr_id5 < m_rp.m_tile[5] ) {
+
+          for ( index_type m = tile_id4; m < m_rp.m_tile_end[4]; m += numbl4 ) {
+            const index_type offset_4 = m*m_rp.m_tile[4] + thr_id4;
+            if ( offset_4 < m_rp.m_upper[4] && thr_id4 < m_rp.m_tile[4] ) {
+
+              for ( index_type l = tile_id3; l < m_rp.m_tile_end[3]; l += numbl3 ) {
+                const index_type offset_3 = l*m_rp.m_tile[3] + thr_id3;
+                if ( offset_3 < m_rp.m_upper[3] && thr_id3 < m_rp.m_tile[3] ) {
+
+                  for ( index_type k = tile_id2; k < m_rp.m_tile_end[2]; k += numbl2 ) {
+                    const index_type offset_2 = k*m_rp.m_tile[2] + thr_id2;
+                    if ( offset_2 < m_rp.m_upper[2] && thr_id2 < m_rp.m_tile[2] ) {
+
+                      for ( index_type j = tile_id1 ; j < m_rp.m_tile_end[1]; j += numbl1 ) {
+                        const index_type offset_1 = j*m_rp.m_tile[1] + thr_id1;
+                        if ( offset_1 < m_rp.m_upper[1] && thr_id1 < m_rp.m_tile[1] ) {
+
+                          for ( index_type i = tile_id0 ; i < m_rp.m_tile_end[0]; i += numbl0 ) {
+                            const index_type offset_0 = i*m_rp.m_tile[0] + thr_id0;
+                            if ( offset_0 < m_rp.m_upper[0] && thr_id0 < m_rp.m_tile[0] ) {
+                              m_func(offset_0 , offset_1 , offset_2 , offset_3, offset_4, offset_5);
+                            }
+                          }
+                        }
+                      }
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+    // LR
+    else {
+      index_type temp0  =  m_rp.m_tile_end[0];
+      index_type temp1  =  m_rp.m_tile_end[1];
+      const index_type numbl1 = ( temp1 <= max_blocks ? temp1 : max_blocks ) ;
+      const index_type numbl0 = ( temp0*temp1 > max_blocks ? index_type( max_blocks / numbl1 ) :
+          ( temp0 <= max_blocks ? temp0 : max_blocks ) );
+
+      const index_type tile_id0 = (index_type)blockIdx.x / numbl1;
+      const index_type tile_id1 = (index_type)blockIdx.x % numbl1;
+      const index_type thr_id0 = (index_type)threadIdx.x / m_rp.m_tile[1];
+      const index_type thr_id1 = (index_type)threadIdx.x % m_rp.m_tile[1];
+
+      temp0  =  m_rp.m_tile_end[2];
+      temp1  =  m_rp.m_tile_end[3];
+      const index_type numbl3 = ( temp1 <= max_blocks ? temp1 : max_blocks ) ;
+      const index_type numbl2 = ( temp0*temp1 > max_blocks ? index_type( max_blocks / numbl3 ) :
+          (  temp0 <= max_blocks ? temp0 : max_blocks ) );
+
+      const index_type tile_id2 = (index_type)blockIdx.y / numbl3;
+      const index_type tile_id3 = (index_type)blockIdx.y % numbl3;
+      const index_type thr_id2 = (index_type)threadIdx.y / m_rp.m_tile[3];
+      const index_type thr_id3 = (index_type)threadIdx.y % m_rp.m_tile[3];
+
+      temp0  =  m_rp.m_tile_end[4];
+      temp1  =  m_rp.m_tile_end[5];
+      const index_type numbl5 = ( temp1 <= max_blocks ? temp1 : max_blocks ) ;
+      const index_type numbl4 = ( temp0*temp1 > max_blocks ? index_type( max_blocks / numbl5 ) :
+          (  temp0 <= max_blocks ? temp0 : max_blocks ) );
+
+      const index_type tile_id4 = (index_type)blockIdx.z / numbl5;
+      const index_type tile_id5 = (index_type)blockIdx.z % numbl5;
+      const index_type thr_id4 = (index_type)threadIdx.z / m_rp.m_tile[5];
+      const index_type thr_id5 = (index_type)threadIdx.z % m_rp.m_tile[5];
+
+      for ( index_type i = tile_id0; i < m_rp.m_tile_end[0]; i += numbl0 ) {
+        const index_type offset_0 = i*m_rp.m_tile[0] + thr_id0;
+        if ( offset_0 < m_rp.m_upper[0] && thr_id0 < m_rp.m_tile[0] ) {
+
+          for ( index_type j = tile_id1; j < m_rp.m_tile_end[1]; j += numbl1 ) {
+            const index_type offset_1 = j*m_rp.m_tile[1] + thr_id1;
+            if ( offset_1 < m_rp.m_upper[1] && thr_id1 < m_rp.m_tile[1] ) {
+
+              for ( index_type k = tile_id2; k < m_rp.m_tile_end[2]; k += numbl2 ) {
+                const index_type offset_2 = k*m_rp.m_tile[2] + thr_id2;
+                if ( offset_2 < m_rp.m_upper[2] && thr_id2 < m_rp.m_tile[2] ) {
+
+                  for ( index_type l = tile_id3; l < m_rp.m_tile_end[3]; l += numbl3 ) {
+                    const index_type offset_3 = l*m_rp.m_tile[3] + thr_id3;
+                    if ( offset_3 < m_rp.m_upper[3] && thr_id3 < m_rp.m_tile[3] ) {
+
+                      for ( index_type m = tile_id4; m < m_rp.m_tile_end[4]; m += numbl4 ) {
+                        const index_type offset_4 = m*m_rp.m_tile[4] + thr_id4;
+                        if ( offset_4 < m_rp.m_upper[4] && thr_id4 < m_rp.m_tile[4] ) {
+
+                          for ( index_type n = tile_id5; n < m_rp.m_tile_end[5]; n += numbl5 ) {
+                            const index_type offset_5 = n*m_rp.m_tile[5] + thr_id5;
+                            if ( offset_5 < m_rp.m_upper[5] && thr_id5 < m_rp.m_tile[5] ) {
+                              m_func(offset_0 , offset_1 , offset_2 , offset_3 , offset_4 , offset_5);
+                            }
+                          }
+                        }
+                      }
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  } //end exec_range
+
+private:
+  const RP & m_rp;
+  const Functor & m_func;
+};
+
+// Specializations for tag type
+template< typename RP , typename Functor , typename Tag >
+struct DeviceIterateTile<6,RP,Functor,Tag>
+{
+  using index_type = typename RP::index_type;
+
+  __device__
+  DeviceIterateTile( const RP & rp_ , const Functor & f_ )
+  : m_rp(rp_)
+  , m_func(f_)
+  {}
+
+  static constexpr index_type max_blocks = 65535;
+  //static constexpr index_type max_blocks = static_cast(Kokkos::Impl::CudaTraits::UpperBoundGridCount);
+
+  inline __device__
+  void exec_range() const
+  {
+    //enum { max_blocks = static_cast(Kokkos::Impl::CudaTraits::UpperBoundGridCount) };
+    //const index_type max_blocks = static_cast( Kokkos::Impl::cuda_internal_maximum_grid_count() );
+    // LL
+    if (RP::inner_direction == RP::Left) {
+      index_type temp0  =  m_rp.m_tile_end[0];
+      index_type temp1  =  m_rp.m_tile_end[1];
+      const index_type numbl0 = ( temp0 <= max_blocks ? temp0 : max_blocks ) ;
+      const index_type numbl1 = ( temp0*temp1 > max_blocks ? index_type( max_blocks / numbl0 ) :
+          (  temp1 <= max_blocks ? temp1 : max_blocks ) );
+
+      const index_type tile_id0 = (index_type)blockIdx.x % numbl0;
+      const index_type tile_id1 = (index_type)blockIdx.x / numbl0;
+      const index_type thr_id0 = (index_type)threadIdx.x % m_rp.m_tile[0];
+      const index_type thr_id1 = (index_type)threadIdx.x / m_rp.m_tile[0];
+
+      temp0  =  m_rp.m_tile_end[2];
+      temp1  =  m_rp.m_tile_end[3];
+      const index_type numbl2 = ( temp0 <= max_blocks ? temp0 : max_blocks ) ;
+      const index_type numbl3 = ( temp0*temp1 > max_blocks ? index_type( max_blocks / numbl2 ) :
+          (  temp1 <= max_blocks ? temp1 : max_blocks ) );
+
+      const index_type tile_id2 = (index_type)blockIdx.y % numbl2;
+      const index_type tile_id3 = (index_type)blockIdx.y / numbl2;
+      const index_type thr_id2 = (index_type)threadIdx.y % m_rp.m_tile[2];
+      const index_type thr_id3 = (index_type)threadIdx.y / m_rp.m_tile[2];
+
+      temp0  =  m_rp.m_tile_end[4];
+      temp1  =  m_rp.m_tile_end[5];
+      const index_type numbl4 = ( temp0 <= max_blocks ? temp0 : max_blocks ) ;
+      const index_type numbl5 = ( temp0*temp1 > max_blocks ? index_type( max_blocks / numbl4 ) :
+          (  temp1 <= max_blocks ? temp1 : max_blocks ) );
+
+      const index_type tile_id4 = (index_type)blockIdx.z % numbl4;
+      const index_type tile_id5 = (index_type)blockIdx.z / numbl4;
+      const index_type thr_id4 = (index_type)threadIdx.z % m_rp.m_tile[4];
+      const index_type thr_id5 = (index_type)threadIdx.z / m_rp.m_tile[4];
+
+      for ( index_type n = tile_id5; n < m_rp.m_tile_end[5]; n += numbl5 ) {
+        const index_type offset_5 = n*m_rp.m_tile[5] + thr_id5;
+        if ( offset_5 < m_rp.m_upper[5] && thr_id5 < m_rp.m_tile[5] ) {
+
+          for ( index_type m = tile_id4; m < m_rp.m_tile_end[4]; m += numbl4 ) {
+            const index_type offset_4 = m*m_rp.m_tile[4] + thr_id4;
+            if ( offset_4 < m_rp.m_upper[4] && thr_id4 < m_rp.m_tile[4] ) {
+
+              for ( index_type l = tile_id3; l < m_rp.m_tile_end[3]; l += numbl3 ) {
+                const index_type offset_3 = l*m_rp.m_tile[3] + thr_id3;
+                if ( offset_3 < m_rp.m_upper[3] && thr_id3 < m_rp.m_tile[3] ) {
+
+                  for ( index_type k = tile_id2; k < m_rp.m_tile_end[2]; k += numbl2 ) {
+                    const index_type offset_2 = k*m_rp.m_tile[2] + thr_id2;
+                    if ( offset_2 < m_rp.m_upper[2] && thr_id2 < m_rp.m_tile[2] ) {
+
+                      for ( index_type j = tile_id1 ; j < m_rp.m_tile_end[1]; j += numbl1 ) {
+                        const index_type offset_1 = j*m_rp.m_tile[1] + thr_id1;
+                        if ( offset_1 < m_rp.m_upper[1] && thr_id1 < m_rp.m_tile[1] ) {
+
+                          for ( index_type i = tile_id0 ; i < m_rp.m_tile_end[0]; i += numbl0 ) {
+                            const index_type offset_0 = i*m_rp.m_tile[0] + thr_id0;
+                            if ( offset_0 < m_rp.m_upper[0] && thr_id0 < m_rp.m_tile[0] ) {
+                              m_func(Tag() , offset_0 , offset_1 , offset_2 , offset_3, offset_4, offset_5);
+                            }
+                          }
+                        }
+                      }
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+    // LR
+    else {
+      index_type temp0  =  m_rp.m_tile_end[0];
+      index_type temp1  =  m_rp.m_tile_end[1];
+      const index_type numbl1 = ( temp1 <= max_blocks ? temp1 : max_blocks ) ;
+      const index_type numbl0 = ( temp0*temp1 > max_blocks ? index_type( max_blocks / numbl1 ) :
+          ( temp0 <= max_blocks ? temp0 : max_blocks ) );
+
+      const index_type tile_id0 = (index_type)blockIdx.x / numbl1;
+      const index_type tile_id1 = (index_type)blockIdx.x % numbl1;
+      const index_type thr_id0 = (index_type)threadIdx.x / m_rp.m_tile[1];
+      const index_type thr_id1 = (index_type)threadIdx.x % m_rp.m_tile[1];
+
+      temp0  =  m_rp.m_tile_end[2];
+      temp1  =  m_rp.m_tile_end[3];
+      const index_type numbl3 = ( temp1 <= max_blocks ? temp1 : max_blocks ) ;
+      const index_type numbl2 = ( temp0*temp1 > max_blocks ? index_type( max_blocks / numbl3 ) :
+          (  temp0 <= max_blocks ? temp0 : max_blocks ) );
+
+      const index_type tile_id2 = (index_type)blockIdx.y / numbl3;
+      const index_type tile_id3 = (index_type)blockIdx.y % numbl3;
+      const index_type thr_id2 = (index_type)threadIdx.y / m_rp.m_tile[3];
+      const index_type thr_id3 = (index_type)threadIdx.y % m_rp.m_tile[3];
+
+      temp0  =  m_rp.m_tile_end[4];
+      temp1  =  m_rp.m_tile_end[5];
+      const index_type numbl5 = ( temp1 <= max_blocks ? temp1 : max_blocks ) ;
+      const index_type numbl4 = ( temp0*temp1 > max_blocks ? index_type( max_blocks / numbl5 ) :
+          (  temp0 <= max_blocks ? temp0 : max_blocks ) );
+
+      const index_type tile_id4 = (index_type)blockIdx.z / numbl5;
+      const index_type tile_id5 = (index_type)blockIdx.z % numbl5;
+      const index_type thr_id4 = (index_type)threadIdx.z / m_rp.m_tile[5];
+      const index_type thr_id5 = (index_type)threadIdx.z % m_rp.m_tile[5];
+
+      for ( index_type i = tile_id0; i < m_rp.m_tile_end[0]; i += numbl0 ) {
+        const index_type offset_0 = i*m_rp.m_tile[0] + thr_id0;
+        if ( offset_0 < m_rp.m_upper[0] && thr_id0 < m_rp.m_tile[0] ) {
+
+          for ( index_type j = tile_id1; j < m_rp.m_tile_end[1]; j += numbl1 ) {
+            const index_type offset_1 = j*m_rp.m_tile[1] + thr_id1;
+            if ( offset_1 < m_rp.m_upper[1] && thr_id1 < m_rp.m_tile[1] ) {
+
+              for ( index_type k = tile_id2; k < m_rp.m_tile_end[2]; k += numbl2 ) {
+                const index_type offset_2 = k*m_rp.m_tile[2] + thr_id2;
+                if ( offset_2 < m_rp.m_upper[2] && thr_id2 < m_rp.m_tile[2] ) {
+
+                  for ( index_type l = tile_id3; l < m_rp.m_tile_end[3]; l += numbl3 ) {
+                    const index_type offset_3 = l*m_rp.m_tile[3] + thr_id3;
+                    if ( offset_3 < m_rp.m_upper[3] && thr_id3 < m_rp.m_tile[3] ) {
+
+                      for ( index_type m = tile_id4; m < m_rp.m_tile_end[4]; m += numbl4 ) {
+                        const index_type offset_4 = m*m_rp.m_tile[4] + thr_id4;
+                        if ( offset_4 < m_rp.m_upper[4] && thr_id4 < m_rp.m_tile[4] ) {
+
+                          for ( index_type n = tile_id5; n < m_rp.m_tile_end[5]; n += numbl5 ) {
+                            const index_type offset_5 = n*m_rp.m_tile[5] + thr_id5;
+                            if ( offset_5 < m_rp.m_upper[5] && thr_id5 < m_rp.m_tile[5] ) {
+                              m_func(Tag() , offset_0 , offset_1 , offset_2 , offset_3 , offset_4 , offset_5);
+                            }
+                          }
+                        }
+                      }
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  } //end exec_range
+
+private:
+  const RP & m_rp;
+  const Functor & m_func;
+};
+
+} // Refactor
+
+// ----------------------------------------------------------------------------------
+
+namespace Reduce {
+
+template < typename T >
+using is_void = std::is_same< T, void >;
+
+template < typename T >
+struct is_array_type : std::false_type
+{
+  using value_type = T;
+};
+
+template < typename T >
+struct is_array_type< T* > : std::true_type
+{
+  using value_type = T;
+};
+
+template < typename T >
+struct is_array_type< T[] > : std::true_type
+{
+  using value_type = T;
+};
+
+// ------------------------------------------------------------------ //
+template< int N , typename RP , typename Functor , typename Tag , typename ValueType , typename Enable = void >
+struct DeviceIterateTile;
+
+// ParallelReduce iteration pattern
+// Scalar reductions
+
+// num_blocks = min( num_tiles, max_num_blocks ); //i.e. determined by number of tiles and reduction algorithm constraints
+// extract n-dim tile offsets (i.e. tile's global starting mulit-index) from the tileid = blockid using tile dimensions
+// local indices within a tile extracted from (index_type)threadIdx.x using tile dims, constrained by blocksize
+// combine tile and local id info for multi-dim global ids
+
+// Pattern:
+// Each block+thread is responsible for a tile+local_id combo (additional when striding by num_blocks)
+// 1. create offset arrays
+// 2. loop over number of tiles, striding by griddim (equal to num tiles, or max num blocks)
+// 3. temps set for tile_idx and thrd_idx, which will be modified
+// 4. if LL vs LR:
+//      determine tile starting point offsets (multidim)
+//      determine local index offsets (multidim)
+//      concatentate tile offset + local offset for global multi-dim index
+//    if offset withinin range bounds AND local offset within tile bounds, call functor
+
+// ValueType = T
+//Rank 2
+// Specializations for void tag type
+template< typename RP , typename Functor , typename ValueType >
+struct DeviceIterateTile<2,RP,Functor,void,ValueType, typename std::enable_if< !is_array_type::value >::type >
+{
+  using index_type = typename RP::index_type;
+
+  __device__
+  DeviceIterateTile( const RP & rp_ , const Functor & f_ , ValueType & v_)
+  : m_rp(rp_)
+  , m_func(f_)
+  , m_v(v_)
+  {}
+
+  inline __device__
+  void exec_range() const
+  {
+    if ( (index_type)blockIdx.x < m_rp.m_num_tiles && (index_type)threadIdx.y < m_rp.m_prod_tile_dims ) {
+      index_type m_offset[RP::rank]; // tile starting global id offset
+      index_type m_local_offset[RP::rank]; // tile starting global id offset
+
+      for ( index_type tileidx = (index_type)blockIdx.x; tileidx < m_rp.m_num_tiles; tileidx += gridDim.x ) {
+        index_type tile_idx = tileidx; // temp because tile_idx will be modified while determining tile starting point offsets
+        index_type thrd_idx = (index_type)threadIdx.y;
+        bool in_bounds = true;
+
+        // LL
+        if (RP::inner_direction == RP::Left) {
+          for (int i=0; i=0; --i) {
+            m_offset[i] = (tile_idx % m_rp.m_tile_end[i]) * m_rp.m_tile[i] + m_rp.m_lower[i] ;
+            tile_idx /= m_rp.m_tile_end[i];
+
+            m_local_offset[i] = (thrd_idx % m_rp.m_tile[i]);
+            thrd_idx /= m_rp.m_tile[i];
+
+            m_offset[i] += m_local_offset[i];
+            if ( !(m_offset[i] < m_rp.m_upper[i] && m_local_offset[i] < m_rp.m_tile[i]) ) {
+              in_bounds &= false;
+            }
+          }
+          if ( in_bounds )
+          { m_func( m_offset[0], m_offset[1], m_v ); }
+        }
+      }
+    }
+
+  } //end exec_range
+
+private:
+  const RP & m_rp;
+  const Functor & m_func;
+  ValueType & m_v;
+};
+
+
+// Specializations for tag type
+template< typename RP , typename Functor , typename Tag, typename ValueType >
+struct DeviceIterateTile<2,RP,Functor,Tag, ValueType, typename std::enable_if< !is_array_type::value && !is_void< Tag >::value >::type >
+{
+  using index_type = typename RP::index_type;
+
+  inline __device__
+  DeviceIterateTile( const RP & rp_ , const Functor & f_ , ValueType & v_)
+  : m_rp(rp_)
+  , m_func(f_)
+  , m_v(v_)
+  {}
+
+  inline __device__
+  void exec_range() const
+  {
+    if ( (index_type)blockIdx.x < m_rp.m_num_tiles && (index_type)threadIdx.y < m_rp.m_prod_tile_dims ) {
+      index_type m_offset[RP::rank]; // tile starting global id offset
+      index_type m_local_offset[RP::rank]; // tile starting global id offset
+
+      for ( index_type tileidx = (index_type)blockIdx.x; tileidx < m_rp.m_num_tiles; tileidx += gridDim.x ) {
+        index_type tile_idx = tileidx; // temp because tile_idx will be modified while determining tile starting point offsets
+        index_type thrd_idx = (index_type)threadIdx.y;
+        bool in_bounds = true;
+
+        // LL
+        if (RP::inner_direction == RP::Left) {
+          for (int i=0; i=0; --i) {
+            m_offset[i] = (tile_idx % m_rp.m_tile_end[i]) * m_rp.m_tile[i] + m_rp.m_lower[i] ;
+            tile_idx /= m_rp.m_tile_end[i];
+
+            // tile-local indices identified with (index_type)threadIdx.y
+            m_local_offset[i] = (thrd_idx % m_rp.m_tile[i]); // Move this to first computation, add to m_offset right away
+            thrd_idx /= m_rp.m_tile[i];
+
+            m_offset[i] += m_local_offset[i];
+            if ( !(m_offset[i] < m_rp.m_upper[i] && m_local_offset[i] < m_rp.m_tile[i]) ) {
+              in_bounds &= false;
+            }
+          }
+          if ( in_bounds )
+          { m_func( Tag(), m_offset[0], m_offset[1], m_v ); }
+        }
+      }
+    }
+  } //end exec_range
+
+private:
+  const RP & m_rp;
+  const Functor & m_func;
+  ValueType & m_v;
+};
+
+
+//Rank 3
+// Specializations for void tag type
+template< typename RP , typename Functor , typename ValueType >
+struct DeviceIterateTile<3,RP,Functor,void,ValueType , typename std::enable_if< !is_array_type::value >::type >
+{
+  using index_type = typename RP::index_type;
+
+  __device__
+  DeviceIterateTile( const RP & rp_ , const Functor & f_ , ValueType & v_)
+  : m_rp(rp_)
+  , m_func(f_)
+  , m_v(v_)
+  {}
+
+  inline __device__
+  void exec_range() const
+  {
+    if ( (index_type)blockIdx.x < m_rp.m_num_tiles && (index_type)threadIdx.y < m_rp.m_prod_tile_dims ) {
+      index_type m_offset[RP::rank]; // tile starting global id offset
+      index_type m_local_offset[RP::rank]; // tile starting global id offset
+
+      for ( index_type tileidx = (index_type)blockIdx.x; tileidx < m_rp.m_num_tiles; tileidx += gridDim.x ) {
+        index_type tile_idx = tileidx; // temp because tile_idx will be modified while determining tile starting point offsets
+        index_type thrd_idx = (index_type)threadIdx.y;
+        bool in_bounds = true;
+
+        // LL
+        if (RP::inner_direction == RP::Left) {
+          for (int i=0; i=0; --i) {
+            m_offset[i] = (tile_idx % m_rp.m_tile_end[i]) * m_rp.m_tile[i] + m_rp.m_lower[i] ;
+            tile_idx /= m_rp.m_tile_end[i];
+
+            // tile-local indices identified with (index_type)threadIdx.y
+            m_local_offset[i] = (thrd_idx % m_rp.m_tile[i]); // Move this to first computation, add to m_offset right away
+            thrd_idx /= m_rp.m_tile[i];
+
+            m_offset[i] += m_local_offset[i];
+            if ( !(m_offset[i] < m_rp.m_upper[i] && m_local_offset[i] < m_rp.m_tile[i]) ) {
+              in_bounds &= false;
+            }
+          }
+          if ( in_bounds )
+          { m_func( m_offset[0], m_offset[1], m_offset[2], m_v ); }
+        }
+      }
+    }
+  } //end exec_range
+
+private:
+  const RP & m_rp;
+  const Functor & m_func;
+  ValueType & m_v;
+};
+
+
+// Specializations for void tag type
+template< typename RP , typename Functor , typename Tag, typename ValueType >
+struct DeviceIterateTile<3,RP,Functor,Tag, ValueType, typename std::enable_if< !is_array_type::value && !is_void< Tag >::value >::type >
+{
+  using index_type = typename RP::index_type;
+
+  inline __device__
+  DeviceIterateTile( const RP & rp_ , const Functor & f_ , ValueType & v_)
+  : m_rp(rp_)
+  , m_func(f_)
+  , m_v(v_)
+  {}
+
+  inline __device__
+  void exec_range() const
+  {
+    if ( (index_type)blockIdx.x < m_rp.m_num_tiles && (index_type)threadIdx.y < m_rp.m_prod_tile_dims ) {
+      index_type m_offset[RP::rank]; // tile starting global id offset
+      index_type m_local_offset[RP::rank]; // tile starting global id offset
+
+      for ( index_type tileidx = (index_type)blockIdx.x; tileidx < m_rp.m_num_tiles; tileidx += gridDim.x ) {
+        index_type tile_idx = tileidx; // temp because tile_idx will be modified while determining tile starting point offsets
+        index_type thrd_idx = (index_type)threadIdx.y;
+        bool in_bounds = true;
+
+        // LL
+        if (RP::inner_direction == RP::Left) {
+          for (int i=0; i=0; --i) {
+            m_offset[i] = (tile_idx % m_rp.m_tile_end[i]) * m_rp.m_tile[i] + m_rp.m_lower[i] ;
+            tile_idx /= m_rp.m_tile_end[i];
+
+            // tile-local indices identified with (index_type)threadIdx.y
+            m_local_offset[i] = (thrd_idx % m_rp.m_tile[i]); // Move this to first computation, add to m_offset right away
+            thrd_idx /= m_rp.m_tile[i];
+
+            m_offset[i] += m_local_offset[i];
+            if ( !(m_offset[i] < m_rp.m_upper[i] && m_local_offset[i] < m_rp.m_tile[i]) ) {
+              in_bounds &= false;
+            }
+          }
+          if ( in_bounds )
+          { m_func( Tag(), m_offset[0], m_offset[1], m_offset[2], m_v ); }
+        }
+      }
+    }
+  } //end exec_range
+
+private:
+  const RP & m_rp;
+  const Functor & m_func;
+  ValueType & m_v;
+};
+
+
+//Rank 4
+// Specializations for void tag type
+template< typename RP , typename Functor , typename ValueType >
+struct DeviceIterateTile<4,RP,Functor,void,ValueType , typename std::enable_if< !is_array_type::value >::type >
+{
+  using index_type = typename RP::index_type;
+
+  __device__
+  DeviceIterateTile( const RP & rp_ , const Functor & f_ , ValueType & v_)
+  : m_rp(rp_)
+  , m_func(f_)
+  , m_v(v_)
+  {}
+
+  static constexpr index_type max_blocks = 65535;
+  //static constexpr index_type max_blocks = static_cast(Kokkos::Impl::CudaTraits::UpperBoundGridCount);
+
+  inline __device__
+  void exec_range() const
+  {
+    //enum { max_blocks = static_cast(Kokkos::Impl::CudaTraits::UpperBoundGridCount) };
+    //const index_type max_blocks = static_cast( Kokkos::Impl::cuda_internal_maximum_grid_count() );
+    if ( (index_type)blockIdx.x < m_rp.m_num_tiles && (index_type)threadIdx.y < m_rp.m_prod_tile_dims ) {
+      index_type m_offset[RP::rank]; // tile starting global id offset
+      index_type m_local_offset[RP::rank]; // tile starting global id offset
+
+      for ( index_type tileidx = (index_type)blockIdx.x; tileidx < m_rp.m_num_tiles; tileidx += gridDim.x ) {
+        index_type tile_idx = tileidx; // temp because tile_idx will be modified while determining tile starting point offsets
+        index_type thrd_idx = (index_type)threadIdx.y;
+        bool in_bounds = true;
+
+        // LL
+        if (RP::inner_direction == RP::Left) {
+          for (int i=0; i=0; --i) {
+            m_offset[i] = (tile_idx % m_rp.m_tile_end[i]) * m_rp.m_tile[i] + m_rp.m_lower[i] ;
+            tile_idx /= m_rp.m_tile_end[i];
+
+            // tile-local indices identified with (index_type)threadIdx.y
+            m_local_offset[i] = (thrd_idx % m_rp.m_tile[i]);
+            thrd_idx /= m_rp.m_tile[i];
+
+            m_offset[i] += m_local_offset[i];
+            if ( !(m_offset[i] < m_rp.m_upper[i] && m_local_offset[i] < m_rp.m_tile[i]) ) {
+              in_bounds &= false;
+            }
+          }
+          if ( in_bounds )
+          { m_func( m_offset[0], m_offset[1], m_offset[2], m_offset[3], m_v ); }
+        }
+      }
+    }
+  } //end exec_range
+
+private:
+  const RP & m_rp;
+  const Functor & m_func;
+  ValueType & m_v;
+};
+
+
+// Specializations for void tag type
+template< typename RP , typename Functor , typename Tag, typename ValueType >
+struct DeviceIterateTile<4,RP,Functor,Tag,ValueType, typename std::enable_if< !is_array_type::value && !is_void< Tag >::value >::type >
+{
+  using index_type = typename RP::index_type;
+
+  inline __device__
+  DeviceIterateTile( const RP & rp_ , const Functor & f_ , ValueType & v_)
+  : m_rp(rp_)
+  , m_func(f_)
+  , m_v(v_)
+  {}
+
+  static constexpr index_type max_blocks = 65535;
+  //static constexpr index_type max_blocks = static_cast(Kokkos::Impl::CudaTraits::UpperBoundGridCount);
+
+  inline __device__
+  void exec_range() const
+  {
+    //enum { max_blocks = static_cast(Kokkos::Impl::CudaTraits::UpperBoundGridCount) };
+    //const index_type max_blocks = static_cast( Kokkos::Impl::cuda_internal_maximum_grid_count() );
+    if ( (index_type)blockIdx.x < m_rp.m_num_tiles && (index_type)threadIdx.y < m_rp.m_prod_tile_dims ) {
+      index_type m_offset[RP::rank]; // tile starting global id offset
+      index_type m_local_offset[RP::rank]; // tile starting global id offset
+
+      for ( index_type tileidx = (index_type)blockIdx.x; tileidx < m_rp.m_num_tiles; tileidx += gridDim.x ) {
+        index_type tile_idx = tileidx; // temp because tile_idx will be modified while determining tile starting point offsets
+        index_type thrd_idx = (index_type)threadIdx.y;
+        bool in_bounds = true;
+
+        // LL
+        if (RP::inner_direction == RP::Left) {
+          for (int i=0; i=0; --i) {
+            m_offset[i] = (tile_idx % m_rp.m_tile_end[i]) * m_rp.m_tile[i] + m_rp.m_lower[i] ;
+            tile_idx /= m_rp.m_tile_end[i];
+
+            // tile-local indices identified with (index_type)threadIdx.y
+            m_local_offset[i] = (thrd_idx % m_rp.m_tile[i]);
+            thrd_idx /= m_rp.m_tile[i];
+
+            m_offset[i] += m_local_offset[i];
+            if ( !(m_offset[i] < m_rp.m_upper[i] && m_local_offset[i] < m_rp.m_tile[i]) ) {
+              in_bounds &= false;
+            }
+          }
+          if ( in_bounds )
+          { m_func( Tag(), m_offset[0], m_offset[1], m_offset[2], m_offset[3], m_v ); }
+        }
+      }
+    }
+  } //end exec_range
+
+private:
+  const RP & m_rp;
+  const Functor & m_func;
+  ValueType & m_v;
+};
+
+
+//Rank 5
+// Specializations for void tag type
+template< typename RP , typename Functor , typename ValueType >
+struct DeviceIterateTile<5,RP,Functor,void,ValueType , typename std::enable_if< !is_array_type::value >::type >
+{
+  using index_type = typename RP::index_type;
+
+  __device__
+  DeviceIterateTile( const RP & rp_ , const Functor & f_ , ValueType & v_)
+  : m_rp(rp_)
+  , m_func(f_)
+  , m_v(v_)
+  {}
+
+  static constexpr index_type max_blocks = 65535;
+  //static constexpr index_type max_blocks = static_cast(Kokkos::Impl::CudaTraits::UpperBoundGridCount);
+
+  inline __device__
+  void exec_range() const
+  {
+    //enum { max_blocks = static_cast(Kokkos::Impl::CudaTraits::UpperBoundGridCount) };
+    //const index_type max_blocks = static_cast( Kokkos::Impl::cuda_internal_maximum_grid_count() );
+    if ( (index_type)blockIdx.x < m_rp.m_num_tiles && (index_type)threadIdx.y < m_rp.m_prod_tile_dims ) {
+      index_type m_offset[RP::rank]; // tile starting global id offset
+      index_type m_local_offset[RP::rank]; // tile starting global id offset
+
+      for ( index_type tileidx = (index_type)blockIdx.x; tileidx < m_rp.m_num_tiles; tileidx += gridDim.x ) {
+        index_type tile_idx = tileidx; // temp because tile_idx will be modified while determining tile starting point offsets
+        index_type thrd_idx = (index_type)threadIdx.y;
+        bool in_bounds = true;
+
+        // LL
+        if (RP::inner_direction == RP::Left) {
+          for (int i=0; i=0; --i) {
+            m_offset[i] = (tile_idx % m_rp.m_tile_end[i]) * m_rp.m_tile[i] + m_rp.m_lower[i] ;
+            tile_idx /= m_rp.m_tile_end[i];
+
+            // tile-local indices identified with (index_type)threadIdx.y
+            m_local_offset[i] = (thrd_idx % m_rp.m_tile[i]);
+            thrd_idx /= m_rp.m_tile[i];
+
+            m_offset[i] += m_local_offset[i];
+            if ( !(m_offset[i] < m_rp.m_upper[i] && m_local_offset[i] < m_rp.m_tile[i]) ) {
+              in_bounds &= false;
+            }
+          }
+          if ( in_bounds )
+          { m_func( m_offset[0], m_offset[1], m_offset[2], m_offset[3], m_offset[4], m_v ); }
+        }
+      }
+    }
+  } //end exec_range
+
+private:
+  const RP & m_rp;
+  const Functor & m_func;
+  ValueType & m_v;
+};
+
+
+// Specializations for tag type
+template< typename RP , typename Functor , typename Tag, typename ValueType >
+struct DeviceIterateTile<5,RP,Functor,Tag,ValueType, typename std::enable_if< !is_array_type::value && !is_void< Tag >::value >::type >
+{
+  using index_type = typename RP::index_type;
+
+  __device__
+  DeviceIterateTile( const RP & rp_ , const Functor & f_ , ValueType & v_)
+  : m_rp(rp_)
+  , m_func(f_)
+  , m_v(v_)
+  {}
+
+  static constexpr index_type max_blocks = 65535;
+  //static constexpr index_type max_blocks = static_cast(Kokkos::Impl::CudaTraits::UpperBoundGridCount);
+
+  inline __device__
+  void exec_range() const
+  {
+    //enum { max_blocks = static_cast(Kokkos::Impl::CudaTraits::UpperBoundGridCount) };
+    //const index_type max_blocks = static_cast( Kokkos::Impl::cuda_internal_maximum_grid_count() );
+    if ( (index_type)blockIdx.x < m_rp.m_num_tiles && (index_type)threadIdx.y < m_rp.m_prod_tile_dims ) {
+      index_type m_offset[RP::rank]; // tile starting global id offset
+      index_type m_local_offset[RP::rank]; // tile starting global id offset
+
+      for ( index_type tileidx = (index_type)blockIdx.x; tileidx < m_rp.m_num_tiles; tileidx += gridDim.x ) {
+        index_type tile_idx = tileidx; // temp because tile_idx will be modified while determining tile starting point offsets
+        index_type thrd_idx = (index_type)threadIdx.y;
+        bool in_bounds = true;
+
+        // LL
+        if (RP::inner_direction == RP::Left) {
+          for (int i=0; i=0; --i) {
+            m_offset[i] = (tile_idx % m_rp.m_tile_end[i]) * m_rp.m_tile[i] + m_rp.m_lower[i] ;
+            tile_idx /= m_rp.m_tile_end[i];
+
+            // tile-local indices identified with (index_type)threadIdx.y
+            m_local_offset[i] = (thrd_idx % m_rp.m_tile[i]);
+            thrd_idx /= m_rp.m_tile[i];
+
+            m_offset[i] += m_local_offset[i];
+            if ( !(m_offset[i] < m_rp.m_upper[i] && m_local_offset[i] < m_rp.m_tile[i]) ) {
+              in_bounds &= false;
+            }
+          }
+          if ( in_bounds )
+          { m_func( Tag(), m_offset[0], m_offset[1], m_offset[2], m_offset[3], m_offset[4], m_v ); }
+        }
+      }
+    }
+  } //end exec_range
+
+private:
+  const RP & m_rp;
+  const Functor & m_func;
+  ValueType & m_v;
+};
+
+
+//Rank 6
+// Specializations for void tag type
+template< typename RP , typename Functor , typename ValueType >
+struct DeviceIterateTile<6,RP,Functor,void,ValueType , typename std::enable_if< !is_array_type::value >::type >
+{
+  using index_type = typename RP::index_type;
+
+  __device__
+  DeviceIterateTile( const RP & rp_ , const Functor & f_ , ValueType & v_)
+  : m_rp(rp_)
+  , m_func(f_)
+  , m_v(v_)
+  {}
+
+  static constexpr index_type max_blocks = 65535;
+  //static constexpr index_type max_blocks = static_cast(Kokkos::Impl::CudaTraits::UpperBoundGridCount);
+
+  inline __device__
+  void exec_range() const
+  {
+    //enum { max_blocks = static_cast(Kokkos::Impl::CudaTraits::UpperBoundGridCount) };
+    //const index_type max_blocks = static_cast( Kokkos::Impl::cuda_internal_maximum_grid_count() );
+    if ( (index_type)blockIdx.x < m_rp.m_num_tiles && (index_type)threadIdx.y < m_rp.m_prod_tile_dims ) {
+      index_type m_offset[RP::rank]; // tile starting global id offset
+      index_type m_local_offset[RP::rank]; // tile starting global id offset
+
+      for ( index_type tileidx = (index_type)blockIdx.x; tileidx < m_rp.m_num_tiles; tileidx += gridDim.x ) {
+        index_type tile_idx = tileidx; // temp because tile_idx will be modified while determining tile starting point offsets
+        index_type thrd_idx = (index_type)threadIdx.y;
+        bool in_bounds = true;
+
+        // LL
+        if (RP::inner_direction == RP::Left) {
+          for (int i=0; i=0; --i) {
+            m_offset[i] = (tile_idx % m_rp.m_tile_end[i]) * m_rp.m_tile[i] + m_rp.m_lower[i] ;
+            tile_idx /= m_rp.m_tile_end[i];
+
+            // tile-local indices identified with (index_type)threadIdx.y
+            m_local_offset[i] = (thrd_idx % m_rp.m_tile[i]);
+            thrd_idx /= m_rp.m_tile[i];
+
+            m_offset[i] += m_local_offset[i];
+            if ( !(m_offset[i] < m_rp.m_upper[i] && m_local_offset[i] < m_rp.m_tile[i]) ) {
+              in_bounds &= false;
+            }
+          }
+          if ( in_bounds )
+          { m_func( m_offset[0], m_offset[1], m_offset[2], m_offset[3], m_offset[4], m_offset[5], m_v ); }
+        }
+      }
+    }
+  } //end exec_range
+
+private:
+  const RP & m_rp;
+  const Functor & m_func;
+  ValueType & m_v;
+};
+
+
+// Specializations for tag type
+template< typename RP , typename Functor , typename Tag, typename ValueType >
+struct DeviceIterateTile<6,RP,Functor,Tag,ValueType, typename std::enable_if< !is_array_type::value && !is_void< Tag >::value >::type >
+{
+  using index_type = typename RP::index_type;
+
+  __device__
+  DeviceIterateTile( const RP & rp_ , const Functor & f_ , ValueType & v_)
+  : m_rp(rp_)
+  , m_func(f_)
+  , m_v(v_)
+  {}
+
+  static constexpr index_type max_blocks = 65535;
+  //static constexpr index_type max_blocks = static_cast(Kokkos::Impl::CudaTraits::UpperBoundGridCount);
+
+  inline __device__
+  void exec_range() const
+  {
+    //enum { max_blocks = static_cast(Kokkos::Impl::CudaTraits::UpperBoundGridCount) };
+    //const index_type max_blocks = static_cast( Kokkos::Impl::cuda_internal_maximum_grid_count() );
+    if ( (index_type)blockIdx.x < m_rp.m_num_tiles && (index_type)threadIdx.y < m_rp.m_prod_tile_dims ) {
+      index_type m_offset[RP::rank]; // tile starting global id offset
+      index_type m_local_offset[RP::rank]; // tile starting global id offset
+
+      for ( index_type tileidx = (index_type)blockIdx.x; tileidx < m_rp.m_num_tiles; tileidx += gridDim.x ) {
+        index_type tile_idx = tileidx; // temp because tile_idx will be modified while determining tile starting point offsets
+        index_type thrd_idx = (index_type)threadIdx.y;
+        bool in_bounds = true;
+
+        // LL
+        if (RP::inner_direction == RP::Left) {
+          for (int i=0; i=0; --i) {
+            m_offset[i] = (tile_idx % m_rp.m_tile_end[i]) * m_rp.m_tile[i] + m_rp.m_lower[i] ;
+            tile_idx /= m_rp.m_tile_end[i];
+
+            // tile-local indices identified with (index_type)threadIdx.y
+            m_local_offset[i] = (thrd_idx % m_rp.m_tile[i]);
+            thrd_idx /= m_rp.m_tile[i];
+
+            m_offset[i] += m_local_offset[i];
+            if ( !(m_offset[i] < m_rp.m_upper[i] && m_local_offset[i] < m_rp.m_tile[i]) ) {
+              in_bounds &= false;
+            }
+          }
+          if ( in_bounds )
+          { m_func( Tag(), m_offset[0], m_offset[1], m_offset[2], m_offset[3], m_offset[4], m_offset[5], m_v ); }
+        }
+      }
+    }
+  } //end exec_range
+
+private:
+  const RP & m_rp;
+  const Functor & m_func;
+  ValueType & m_v;
+};
+
+
+// ValueType = T[], T*
+//Rank 2
+// Specializations for void tag type
+template< typename RP , typename Functor , typename ValueType >
+struct DeviceIterateTile<2,RP,Functor,void,ValueType, typename std::enable_if< is_array_type::value >::type >
+{
+  using index_type = typename RP::index_type;
+  using value_type = typename is_array_type< ValueType >::value_type;
+
+  __device__
+  DeviceIterateTile( const RP & rp_ , const Functor & f_ , value_type* v_)
+  : m_rp(rp_)
+  , m_func(f_)
+  , m_v(v_)
+  {}
+
+  inline __device__
+  void exec_range() const
+  {
+    if ( (index_type)blockIdx.x < m_rp.m_num_tiles && (index_type)threadIdx.y < m_rp.m_prod_tile_dims ) {
+      index_type m_offset[RP::rank]; // tile starting global id offset
+      index_type m_local_offset[RP::rank]; // tile starting global id offset
+
+      for ( index_type tileidx = (index_type)blockIdx.x; tileidx < m_rp.m_num_tiles; tileidx += gridDim.x ) {
+        index_type tile_idx = tileidx; // temp because tile_idx will be modified while determining tile starting point offsets
+        index_type thrd_idx = (index_type)threadIdx.y;
+        bool in_bounds = true;
+
+        // LL
+        if (RP::inner_direction == RP::Left) {
+          for (int i=0; i=0; --i) {
+            m_offset[i] = (tile_idx % m_rp.m_tile_end[i]) * m_rp.m_tile[i] + m_rp.m_lower[i] ;
+            tile_idx /= m_rp.m_tile_end[i];
+
+            // tile-local indices identified with (index_type)threadIdx.y
+            m_local_offset[i] = (thrd_idx % m_rp.m_tile[i]); // Move this to first computation, add to m_offset right away
+            thrd_idx /= m_rp.m_tile[i];
+
+            m_offset[i] += m_local_offset[i];
+            if ( !(m_offset[i] < m_rp.m_upper[i] && m_local_offset[i] < m_rp.m_tile[i]) ) {
+              in_bounds &= false;
+            }
+          }
+          if ( in_bounds )
+          { m_func( m_offset[0], m_offset[1], m_v ); }
+        }
+      }
+    }
+  } //end exec_range
+
+private:
+  const RP & m_rp;
+  const Functor & m_func;
+  value_type* m_v;
+};
+
+
+// Specializations for tag type
+template< typename RP , typename Functor , typename Tag, typename ValueType >
+struct DeviceIterateTile<2,RP,Functor,Tag, ValueType, typename std::enable_if< is_array_type::value && !is_void< Tag >::value >::type >
+{
+  using index_type = typename RP::index_type;
+  using value_type = typename is_array_type< ValueType >::value_type;
+
+  inline __device__
+  DeviceIterateTile( const RP & rp_ , const Functor & f_ , value_type* v_)
+  : m_rp(rp_)
+  , m_func(f_)
+  , m_v(v_)
+  {}
+
+  inline __device__
+  void exec_range() const
+  {
+    if ( (index_type)blockIdx.x < m_rp.m_num_tiles && (index_type)threadIdx.y < m_rp.m_prod_tile_dims ) {
+      index_type m_offset[RP::rank]; // tile starting global id offset
+      index_type m_local_offset[RP::rank]; // tile starting global id offset
+
+      for ( index_type tileidx = (index_type)blockIdx.x; tileidx < m_rp.m_num_tiles; tileidx += gridDim.x ) {
+        index_type tile_idx = tileidx; // temp because tile_idx will be modified while determining tile starting point offsets
+        index_type thrd_idx = (index_type)threadIdx.y;
+        bool in_bounds = true;
+
+        // LL
+        if (RP::inner_direction == RP::Left) {
+          for (int i=0; i=0; --i) {
+            m_offset[i] = (tile_idx % m_rp.m_tile_end[i]) * m_rp.m_tile[i] + m_rp.m_lower[i] ;
+            tile_idx /= m_rp.m_tile_end[i];
+
+            // tile-local indices identified with (index_type)threadIdx.y
+            m_local_offset[i] = (thrd_idx % m_rp.m_tile[i]);
+            thrd_idx /= m_rp.m_tile[i];
+
+            m_offset[i] += m_local_offset[i];
+            if ( !(m_offset[i] < m_rp.m_upper[i] && m_local_offset[i] < m_rp.m_tile[i]) ) {
+              in_bounds &= false;
+            }
+          }
+          if ( in_bounds )
+          { m_func( Tag(), m_offset[0], m_offset[1], m_v ); }
+        }
+      } //end for loop over num_tiles - product of tiles in each direction
+    }
+  } //end exec_range
+
+private:
+  const RP & m_rp;
+  const Functor & m_func;
+  value_type* m_v;
+};
+
+
+//Rank 3
+// Specializations for void tag type
+template< typename RP , typename Functor , typename ValueType >
+struct DeviceIterateTile<3,RP,Functor,void,ValueType , typename std::enable_if< is_array_type::value >::type >
+{
+  using index_type = typename RP::index_type;
+  using value_type = typename is_array_type< ValueType >::value_type;
+
+  __device__
+  DeviceIterateTile( const RP & rp_ , const Functor & f_ , value_type* v_)
+  : m_rp(rp_)
+  , m_func(f_)
+  , m_v(v_)
+  {}
+
+  inline __device__
+  void exec_range() const
+  {
+    if ( (index_type)blockIdx.x < m_rp.m_num_tiles && (index_type)threadIdx.y < m_rp.m_prod_tile_dims ) {
+      index_type m_offset[RP::rank]; // tile starting global id offset
+      index_type m_local_offset[RP::rank]; // tile starting global id offset
+
+      for ( index_type tileidx = (index_type)blockIdx.x; tileidx < m_rp.m_num_tiles; tileidx += gridDim.x ) {
+        index_type tile_idx = tileidx; // temp because tile_idx will be modified while determining tile starting point offsets
+        index_type thrd_idx = (index_type)threadIdx.y;
+        bool in_bounds = true;
+
+        // LL
+        if (RP::inner_direction == RP::Left) {
+          for (int i=0; i=0; --i) {
+            m_offset[i] = (tile_idx % m_rp.m_tile_end[i]) * m_rp.m_tile[i] + m_rp.m_lower[i] ;
+            tile_idx /= m_rp.m_tile_end[i];
+
+            // tile-local indices identified with (index_type)threadIdx.y
+            m_local_offset[i] = (thrd_idx % m_rp.m_tile[i]); // Move this to first computation, add to m_offset right away
+            thrd_idx /= m_rp.m_tile[i];
+
+            m_offset[i] += m_local_offset[i];
+            if ( !(m_offset[i] < m_rp.m_upper[i] && m_local_offset[i] < m_rp.m_tile[i]) ) {
+              in_bounds &= false;
+            }
+          }
+          if ( in_bounds )
+          { m_func( m_offset[0], m_offset[1], m_offset[2], m_v ); }
+        }
+      }
+    }
+  } //end exec_range
+
+private:
+  const RP & m_rp;
+  const Functor & m_func;
+  value_type* m_v;
+};
+
+
+// Specializations for void tag type
+template< typename RP , typename Functor , typename Tag, typename ValueType >
+struct DeviceIterateTile<3,RP,Functor,Tag, ValueType, typename std::enable_if< is_array_type::value && !is_void< Tag >::value >::type >
+{
+  using index_type = typename RP::index_type;
+  using value_type = typename is_array_type< ValueType >::value_type;
+
+  inline __device__
+  DeviceIterateTile( const RP & rp_ , const Functor & f_ , value_type* v_)
+  : m_rp(rp_)
+  , m_func(f_)
+  , m_v(v_)
+  {}
+
+  inline __device__
+  void exec_range() const
+  {
+    if ( (index_type)blockIdx.x < m_rp.m_num_tiles && (index_type)threadIdx.y < m_rp.m_prod_tile_dims ) {
+      index_type m_offset[RP::rank]; // tile starting global id offset
+      index_type m_local_offset[RP::rank]; // tile starting global id offset
+
+      for ( index_type tileidx = (index_type)blockIdx.x; tileidx < m_rp.m_num_tiles; tileidx += gridDim.x ) {
+        index_type tile_idx = tileidx; // temp because tile_idx will be modified while determining tile starting point offsets
+        index_type thrd_idx = (index_type)threadIdx.y;
+        bool in_bounds = true;
+
+        // LL
+        if (RP::inner_direction == RP::Left) {
+          for (int i=0; i=0; --i) {
+            m_offset[i] = (tile_idx % m_rp.m_tile_end[i]) * m_rp.m_tile[i] + m_rp.m_lower[i] ;
+            tile_idx /= m_rp.m_tile_end[i];
+
+            // tile-local indices identified with (index_type)threadIdx.y
+            m_local_offset[i] = (thrd_idx % m_rp.m_tile[i]);
+            thrd_idx /= m_rp.m_tile[i];
+
+            m_offset[i] += m_local_offset[i];
+            if ( !(m_offset[i] < m_rp.m_upper[i] && m_local_offset[i] < m_rp.m_tile[i]) ) {
+              in_bounds &= false;
+            }
+          }
+          if ( in_bounds )
+          { m_func( Tag(), m_offset[0], m_offset[1], m_offset[2], m_v ); }
+        }
+      }
+    }
+  } //end exec_range
+
+private:
+  const RP & m_rp;
+  const Functor & m_func;
+  value_type* m_v;
+};
+
+
+//Rank 4
+// Specializations for void tag type
+template< typename RP , typename Functor , typename ValueType >
+struct DeviceIterateTile<4,RP,Functor,void,ValueType , typename std::enable_if< is_array_type::value >::type >
+{
+  using index_type = typename RP::index_type;
+  using value_type = typename is_array_type< ValueType >::value_type;
+
+  __device__
+  DeviceIterateTile( const RP & rp_ , const Functor & f_ , value_type* v_)
+  : m_rp(rp_)
+  , m_func(f_)
+  , m_v(v_)
+  {}
+
+  static constexpr index_type max_blocks = 65535;
+  //static constexpr index_type max_blocks = static_cast(Kokkos::Impl::CudaTraits::UpperBoundGridCount);
+
+  inline __device__
+  void exec_range() const
+  {
+    //enum { max_blocks = static_cast(Kokkos::Impl::CudaTraits::UpperBoundGridCount) };
+    //const index_type max_blocks = static_cast( Kokkos::Impl::cuda_internal_maximum_grid_count() );
+    if ( (index_type)blockIdx.x < m_rp.m_num_tiles && (index_type)threadIdx.y < m_rp.m_prod_tile_dims ) {
+      index_type m_offset[RP::rank]; // tile starting global id offset
+      index_type m_local_offset[RP::rank]; // tile starting global id offset
+
+      for ( index_type tileidx = (index_type)blockIdx.x; tileidx < m_rp.m_num_tiles; tileidx += gridDim.x ) {
+        index_type tile_idx = tileidx; // temp because tile_idx will be modified while determining tile starting point offsets
+        index_type thrd_idx = (index_type)threadIdx.y;
+        bool in_bounds = true;
+
+        // LL
+        if (RP::inner_direction == RP::Left) {
+          for (int i=0; i=0; --i) {
+            m_offset[i] = (tile_idx % m_rp.m_tile_end[i]) * m_rp.m_tile[i] + m_rp.m_lower[i] ;
+            tile_idx /= m_rp.m_tile_end[i];
+
+            // tile-local indices identified with (index_type)threadIdx.y
+            m_local_offset[i] = (thrd_idx % m_rp.m_tile[i]);
+            thrd_idx /= m_rp.m_tile[i];
+
+            m_offset[i] += m_local_offset[i];
+            if ( !(m_offset[i] < m_rp.m_upper[i] && m_local_offset[i] < m_rp.m_tile[i]) ) {
+              in_bounds &= false;
+            }
+          }
+          if ( in_bounds )
+          { m_func( m_offset[0], m_offset[1], m_offset[2], m_offset[3], m_v ); }
+        }
+      }
+    }
+  } //end exec_range
+
+private:
+  const RP & m_rp;
+  const Functor & m_func;
+  value_type* m_v;
+};
+
+
+// Specializations for void tag type
+template< typename RP , typename Functor , typename Tag, typename ValueType >
+struct DeviceIterateTile<4,RP,Functor,Tag,ValueType, typename std::enable_if< is_array_type::value && !is_void< Tag >::value >::type >
+{
+  using index_type = typename RP::index_type;
+  using value_type = typename is_array_type< ValueType >::value_type;
+
+  inline __device__
+  DeviceIterateTile( const RP & rp_ , const Functor & f_ , value_type* v_)
+  : m_rp(rp_)
+  , m_func(f_)
+  , m_v(v_)
+  {}
+
+  static constexpr index_type max_blocks = 65535;
+  //static constexpr index_type max_blocks = static_cast(Kokkos::Impl::CudaTraits::UpperBoundGridCount);
+
+  inline __device__
+  void exec_range() const
+  {
+    //enum { max_blocks = static_cast(Kokkos::Impl::CudaTraits::UpperBoundGridCount) };
+    //const index_type max_blocks = static_cast( Kokkos::Impl::cuda_internal_maximum_grid_count() );
+    if ( (index_type)blockIdx.x < m_rp.m_num_tiles && (index_type)threadIdx.y < m_rp.m_prod_tile_dims ) {
+      index_type m_offset[RP::rank]; // tile starting global id offset
+      index_type m_local_offset[RP::rank]; // tile starting global id offset
+
+      for ( index_type tileidx = (index_type)blockIdx.x; tileidx < m_rp.m_num_tiles; tileidx += gridDim.x ) {
+        index_type tile_idx = tileidx; // temp because tile_idx will be modified while determining tile starting point offsets
+        index_type thrd_idx = (index_type)threadIdx.y;
+        bool in_bounds = true;
+
+        // LL
+        if (RP::inner_direction == RP::Left) {
+          for (int i=0; i=0; --i) {
+            m_offset[i] = (tile_idx % m_rp.m_tile_end[i]) * m_rp.m_tile[i] + m_rp.m_lower[i] ;
+            tile_idx /= m_rp.m_tile_end[i];
+
+            // tile-local indices identified with (index_type)threadIdx.y
+            m_local_offset[i] = (thrd_idx % m_rp.m_tile[i]);
+            thrd_idx /= m_rp.m_tile[i];
+
+            m_offset[i] += m_local_offset[i];
+            if ( !(m_offset[i] < m_rp.m_upper[i] && m_local_offset[i] < m_rp.m_tile[i]) ) {
+              in_bounds &= false;
+            }
+          }
+          if ( in_bounds )
+          { m_func( Tag(), m_offset[0], m_offset[1], m_offset[2], m_offset[3], m_v ); }
+        }
+      }
+    }
+  } //end exec_range
+
+private:
+  const RP & m_rp;
+  const Functor & m_func;
+  value_type* m_v;
+};
+
+
+//Rank 5
+// Specializations for void tag type
+template< typename RP , typename Functor , typename ValueType >
+struct DeviceIterateTile<5,RP,Functor,void,ValueType , typename std::enable_if< is_array_type::value >::type >
+{
+  using index_type = typename RP::index_type;
+  using value_type = typename is_array_type< ValueType >::value_type;
+
+  __device__
+  DeviceIterateTile( const RP & rp_ , const Functor & f_ , value_type* v_)
+  : m_rp(rp_)
+  , m_func(f_)
+  , m_v(v_)
+  {}
+
+  static constexpr index_type max_blocks = 65535;
+  //static constexpr index_type max_blocks = static_cast(Kokkos::Impl::CudaTraits::UpperBoundGridCount);
+
+  inline __device__
+  void exec_range() const
+  {
+    //enum { max_blocks = static_cast(Kokkos::Impl::CudaTraits::UpperBoundGridCount) };
+    //const index_type max_blocks = static_cast( Kokkos::Impl::cuda_internal_maximum_grid_count() );
+    if ( (index_type)blockIdx.x < m_rp.m_num_tiles && (index_type)threadIdx.y < m_rp.m_prod_tile_dims ) {
+      index_type m_offset[RP::rank]; // tile starting global id offset
+      index_type m_local_offset[RP::rank]; // tile starting global id offset
+
+      for ( index_type tileidx = (index_type)blockIdx.x; tileidx < m_rp.m_num_tiles; tileidx += gridDim.x ) {
+        index_type tile_idx = tileidx; // temp because tile_idx will be modified while determining tile starting point offsets
+        index_type thrd_idx = (index_type)threadIdx.y;
+        bool in_bounds = true;
+
+        // LL
+        if (RP::inner_direction == RP::Left) {
+          for (int i=0; i=0; --i) {
+            m_offset[i] = (tile_idx % m_rp.m_tile_end[i]) * m_rp.m_tile[i] + m_rp.m_lower[i] ;
+            tile_idx /= m_rp.m_tile_end[i];
+
+            // tile-local indices identified with (index_type)threadIdx.y
+            m_local_offset[i] = (thrd_idx % m_rp.m_tile[i]);
+            thrd_idx /= m_rp.m_tile[i];
+
+            m_offset[i] += m_local_offset[i];
+            if ( !(m_offset[i] < m_rp.m_upper[i] && m_local_offset[i] < m_rp.m_tile[i]) ) {
+              in_bounds &= false;
+            }
+          }
+          if ( in_bounds )
+          { m_func( m_offset[0], m_offset[1], m_offset[2], m_offset[3], m_offset[4], m_v ); }
+        }
+      }
+    }
+  } //end exec_range
+
+private:
+  const RP & m_rp;
+  const Functor & m_func;
+  value_type* m_v;
+};
+
+
+// Specializations for tag type
+template< typename RP , typename Functor , typename Tag, typename ValueType >
+struct DeviceIterateTile<5,RP,Functor,Tag,ValueType, typename std::enable_if< is_array_type::value && !is_void< Tag >::value >::type >
+{
+  using index_type = typename RP::index_type;
+  using value_type = typename is_array_type< ValueType >::value_type;
+
+  __device__
+  DeviceIterateTile( const RP & rp_ , const Functor & f_ , value_type* v_)
+  : m_rp(rp_)
+  , m_func(f_)
+  , m_v(v_)
+  {}
+
+  static constexpr index_type max_blocks = 65535;
+  //static constexpr index_type max_blocks = static_cast(Kokkos::Impl::CudaTraits::UpperBoundGridCount);
+
+  inline __device__
+  void exec_range() const
+  {
+    //enum { max_blocks = static_cast(Kokkos::Impl::CudaTraits::UpperBoundGridCount) };
+    //const index_type max_blocks = static_cast( Kokkos::Impl::cuda_internal_maximum_grid_count() );
+    if ( (index_type)blockIdx.x < m_rp.m_num_tiles && (index_type)threadIdx.y < m_rp.m_prod_tile_dims ) {
+      index_type m_offset[RP::rank]; // tile starting global id offset
+      index_type m_local_offset[RP::rank]; // tile starting global id offset
+
+      for ( index_type tileidx = (index_type)blockIdx.x; tileidx < m_rp.m_num_tiles; tileidx += gridDim.x ) {
+        index_type tile_idx = tileidx; // temp because tile_idx will be modified while determining tile starting point offsets
+        index_type thrd_idx = (index_type)threadIdx.y;
+        bool in_bounds = true;
+
+        // LL
+        if (RP::inner_direction == RP::Left) {
+          for (int i=0; i=0; --i) {
+            m_offset[i] = (tile_idx % m_rp.m_tile_end[i]) * m_rp.m_tile[i] + m_rp.m_lower[i] ;
+            tile_idx /= m_rp.m_tile_end[i];
+
+            // tile-local indices identified with (index_type)threadIdx.y
+            m_local_offset[i] = (thrd_idx % m_rp.m_tile[i]);
+            thrd_idx /= m_rp.m_tile[i];
+
+            m_offset[i] += m_local_offset[i];
+            if ( !(m_offset[i] < m_rp.m_upper[i] && m_local_offset[i] < m_rp.m_tile[i]) ) {
+              in_bounds &= false;
+            }
+          }
+          if ( in_bounds )
+          { m_func( Tag(), m_offset[0], m_offset[1], m_offset[2], m_offset[3], m_offset[4], m_v ); }
+        }
+      }
+    }
+  } //end exec_range
+
+private:
+  const RP & m_rp;
+  const Functor & m_func;
+  value_type* m_v;
+};
+
+
+//Rank 6
+// Specializations for void tag type
+template< typename RP , typename Functor , typename ValueType >
+struct DeviceIterateTile<6,RP,Functor,void,ValueType , typename std::enable_if< is_array_type::value >::type >
+{
+  using index_type = typename RP::index_type;
+  using value_type = typename is_array_type< ValueType >::value_type;
+
+  __device__
+  DeviceIterateTile( const RP & rp_ , const Functor & f_ , value_type* v_)
+  : m_rp(rp_)
+  , m_func(f_)
+  , m_v(v_)
+  {}
+
+  static constexpr index_type max_blocks = 65535;
+  //static constexpr index_type max_blocks = static_cast(Kokkos::Impl::CudaTraits::UpperBoundGridCount);
+
+  inline __device__
+  void exec_range() const
+  {
+    //enum { max_blocks = static_cast(Kokkos::Impl::CudaTraits::UpperBoundGridCount) };
+    //const index_type max_blocks = static_cast( Kokkos::Impl::cuda_internal_maximum_grid_count() );
+    if ( (index_type)blockIdx.x < m_rp.m_num_tiles && (index_type)threadIdx.y < m_rp.m_prod_tile_dims ) {
+      index_type m_offset[RP::rank]; // tile starting global id offset
+      index_type m_local_offset[RP::rank]; // tile starting global id offset
+
+      for ( index_type tileidx = (index_type)blockIdx.x; tileidx < m_rp.m_num_tiles; tileidx += gridDim.x ) {
+        index_type tile_idx = tileidx; // temp because tile_idx will be modified while determining tile starting point offsets
+        index_type thrd_idx = (index_type)threadIdx.y;
+        bool in_bounds = true;
+
+        // LL
+        if (RP::inner_direction == RP::Left) {
+          for (int i=0; i=0; --i) {
+            m_offset[i] = (tile_idx % m_rp.m_tile_end[i]) * m_rp.m_tile[i] + m_rp.m_lower[i] ;
+            tile_idx /= m_rp.m_tile_end[i];
+
+            // tile-local indices identified with (index_type)threadIdx.y
+            m_local_offset[i] = (thrd_idx % m_rp.m_tile[i]);
+            thrd_idx /= m_rp.m_tile[i];
+
+            m_offset[i] += m_local_offset[i];
+            if ( !(m_offset[i] < m_rp.m_upper[i] && m_local_offset[i] < m_rp.m_tile[i]) ) {
+              in_bounds &= false;
+            }
+          }
+          if ( in_bounds )
+          { m_func( m_offset[0], m_offset[1], m_offset[2], m_offset[3], m_offset[4], m_offset[5], m_v ); }
+        }
+      }
+    }
+  } //end exec_range
+
+private:
+  const RP & m_rp;
+  const Functor & m_func;
+  value_type* m_v;
+};
+
+
+// Specializations for tag type
+template< typename RP , typename Functor , typename Tag, typename ValueType >
+struct DeviceIterateTile<6,RP,Functor,Tag,ValueType, typename std::enable_if< is_array_type::value && !is_void< Tag >::value >::type >
+{
+  using index_type = typename RP::index_type;
+  using value_type = typename is_array_type< ValueType >::value_type;
+
+  __device__
+  DeviceIterateTile( const RP & rp_ , const Functor & f_ , value_type* v_)
+  : m_rp(rp_)
+  , m_func(f_)
+  , m_v(v_)
+  {}
+
+  static constexpr index_type max_blocks = 65535;
+  //static constexpr index_type max_blocks = static_cast(Kokkos::Impl::CudaTraits::UpperBoundGridCount);
+
+  inline __device__
+  void exec_range() const
+  {
+    //enum { max_blocks = static_cast(Kokkos::Impl::CudaTraits::UpperBoundGridCount) };
+    //const index_type max_blocks = static_cast( Kokkos::Impl::cuda_internal_maximum_grid_count() );
+    if ( (index_type)blockIdx.x < m_rp.m_num_tiles && (index_type)threadIdx.y < m_rp.m_prod_tile_dims ) {
+      index_type m_offset[RP::rank]; // tile starting global id offset
+      index_type m_local_offset[RP::rank]; // tile starting global id offset
+
+      for ( index_type tileidx = (index_type)blockIdx.x; tileidx < m_rp.m_num_tiles; tileidx += gridDim.x ) {
+        index_type tile_idx = tileidx; // temp because tile_idx will be modified while determining tile starting point offsets
+        index_type thrd_idx = (index_type)threadIdx.y;
+        bool in_bounds = true;
+
+        // LL
+        if (RP::inner_direction == RP::Left) {
+          for (int i=0; i=0; --i) {
+            m_offset[i] = (tile_idx % m_rp.m_tile_end[i]) * m_rp.m_tile[i] + m_rp.m_lower[i] ;
+            tile_idx /= m_rp.m_tile_end[i];
+
+            // tile-local indices identified with (index_type)threadIdx.y
+            m_local_offset[i] = (thrd_idx % m_rp.m_tile[i]);
+            thrd_idx /= m_rp.m_tile[i];
+
+            m_offset[i] += m_local_offset[i];
+            if ( !(m_offset[i] < m_rp.m_upper[i] && m_local_offset[i] < m_rp.m_tile[i]) ) {
+              in_bounds &= false;
+            }
+          }
+          if ( in_bounds )
+          { m_func( Tag(), m_offset[0], m_offset[1], m_offset[2], m_offset[3], m_offset[4], m_offset[5], m_v ); }
+        }
+      }
+    }
+  } //end exec_range
+
+private:
+  const RP & m_rp;
+  const Functor & m_func;
+  value_type* m_v;
+};
+
+} // Reduce
+
+// ----------------------------------------------------------------------------------
+
+} } } //end namespace Kokkos::Experimental::Impl
+
+#endif
+#endif
diff --git a/lib/kokkos/core/src/Cuda/Kokkos_CudaExec.hpp b/lib/kokkos/core/src/Cuda/Kokkos_CudaExec.hpp
index 13abcfd93c..cae8ecd489 100644
--- a/lib/kokkos/core/src/Cuda/Kokkos_CudaExec.hpp
+++ b/lib/kokkos/core/src/Cuda/Kokkos_CudaExec.hpp
@@ -53,6 +53,7 @@
 #include 
 #include 
 #include 
+#include 
 
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
@@ -125,53 +126,12 @@ unsigned long kokkos_impl_cuda_constant_memory_buffer[ Kokkos::Impl::CudaTraits:
 
 #endif
 
-
-namespace Kokkos {
-namespace Impl {
-  struct CudaLockArraysStruct {
-    int* atomic;
-    int* scratch;
-    int* threadid;
-    int n;
-  };
-}
-}
-__device__ __constant__
-#ifdef KOKKOS_ENABLE_CUDA_RELOCATABLE_DEVICE_CODE
-extern
-#endif
-Kokkos::Impl::CudaLockArraysStruct kokkos_impl_cuda_lock_arrays ;
-
-#define CUDA_SPACE_ATOMIC_MASK 0x1FFFF
-#define CUDA_SPACE_ATOMIC_XOR_MASK 0x15A39
-
 namespace Kokkos {
 namespace Impl {
   void* cuda_resize_scratch_space(std::int64_t bytes, bool force_shrink = false);
 }
 }
 
-namespace Kokkos {
-namespace Impl {
-__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_cuda_lock_arrays.atomic[offset],0,1));
-}
-
-__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_cuda_lock_arrays.atomic[ offset ], 0);
-}
-
-}
-}
-
 template< typename T >
 inline
 __device__
@@ -192,7 +152,7 @@ namespace Impl {
 // For 2.0 capability: 48 KB L1 and 16 KB shared
 //----------------------------------------------------------------------------
 
-template< class DriverType >
+template< class DriverType>
 __global__
 static void cuda_parallel_launch_constant_memory()
 {
@@ -202,19 +162,39 @@ static void cuda_parallel_launch_constant_memory()
   driver();
 }
 
-template< class DriverType >
+template< class DriverType, unsigned int maxTperB, unsigned int minBperSM >
+__global__
+__launch_bounds__(maxTperB, minBperSM)
+static void cuda_parallel_launch_constant_memory()
+{
+  const DriverType & driver =
+    *((const DriverType *) kokkos_impl_cuda_constant_memory_buffer );
+
+  driver();
+}
+
+template< class DriverType>
 __global__
 static void cuda_parallel_launch_local_memory( const DriverType driver )
 {
   driver();
 }
 
-template < class DriverType ,
-           bool Large = ( CudaTraits::ConstantMemoryUseThreshold < sizeof(DriverType) ) >
+template< class DriverType, unsigned int maxTperB, unsigned int minBperSM >
+__global__
+__launch_bounds__(maxTperB, minBperSM)
+static void cuda_parallel_launch_local_memory( const DriverType driver )
+{
+  driver();
+}
+
+template < class DriverType
+         , class LaunchBounds = Kokkos::LaunchBounds<>
+         , bool Large = ( CudaTraits::ConstantMemoryUseThreshold < sizeof(DriverType) ) >
 struct CudaParallelLaunch ;
 
-template < class DriverType >
-struct CudaParallelLaunch< DriverType , true > {
+template < class DriverType, class LaunchBounds >
+struct CudaParallelLaunch< DriverType, LaunchBounds, true > {
 
   inline
   CudaParallelLaunch( const DriverType & driver
@@ -238,26 +218,19 @@ struct CudaParallelLaunch< DriverType , true > {
       }
       #ifndef KOKKOS_ARCH_KEPLER //On Kepler the L1 has no benefit since it doesn't cache reads
       else if ( shmem ) {
-        CUDA_SAFE_CALL( cudaFuncSetCacheConfig( cuda_parallel_launch_constant_memory< DriverType > , cudaFuncCachePreferShared ) );
+        CUDA_SAFE_CALL( cudaFuncSetCacheConfig( cuda_parallel_launch_constant_memory< DriverType, LaunchBounds::maxTperB, LaunchBounds::minBperSM > , cudaFuncCachePreferShared ) );
       } else {
-        CUDA_SAFE_CALL( cudaFuncSetCacheConfig( cuda_parallel_launch_constant_memory< DriverType > , cudaFuncCachePreferL1 ) );
+        CUDA_SAFE_CALL( cudaFuncSetCacheConfig( cuda_parallel_launch_constant_memory< DriverType, LaunchBounds::maxTperB, LaunchBounds::minBperSM > , cudaFuncCachePreferL1 ) );
       }
       #endif
 
       // Copy functor to constant memory on the device
       cudaMemcpyToSymbol( kokkos_impl_cuda_constant_memory_buffer , & driver , sizeof(DriverType) );
 
-      #ifndef KOKKOS_ENABLE_CUDA_RELOCATABLE_DEVICE_CODE
-      Kokkos::Impl::CudaLockArraysStruct locks;
-      locks.atomic = atomic_lock_array_cuda_space_ptr(false);
-      locks.scratch = scratch_lock_array_cuda_space_ptr(false);
-      locks.threadid = threadid_lock_array_cuda_space_ptr(false);
-      locks.n = Kokkos::Cuda::concurrency();
-      cudaMemcpyToSymbol( kokkos_impl_cuda_lock_arrays , & locks , sizeof(CudaLockArraysStruct) );
-      #endif
+      KOKKOS_ENSURE_CUDA_LOCK_ARRAYS_ON_DEVICE();
 
       // Invoke the driver function on the device
-      cuda_parallel_launch_constant_memory< DriverType ><<< grid , block , shmem , stream >>>();
+      cuda_parallel_launch_constant_memory< DriverType, LaunchBounds::maxTperB, LaunchBounds::minBperSM ><<< grid , block , shmem , stream >>>();
 
 #if defined( KOKKOS_ENABLE_DEBUG_BOUNDS_CHECK )
       CUDA_SAFE_CALL( cudaGetLastError() );
@@ -267,8 +240,8 @@ struct CudaParallelLaunch< DriverType , true > {
   }
 };
 
-template < class DriverType >
-struct CudaParallelLaunch< DriverType , false > {
+template < class DriverType, class LaunchBounds >
+struct CudaParallelLaunch< DriverType, LaunchBounds, false > {
 
   inline
   CudaParallelLaunch( const DriverType & driver
@@ -284,22 +257,15 @@ struct CudaParallelLaunch< DriverType , false > {
       }
       #ifndef KOKKOS_ARCH_KEPLER //On Kepler the L1 has no benefit since it doesn't cache reads
       else if ( shmem ) {
-        CUDA_SAFE_CALL( cudaFuncSetCacheConfig( cuda_parallel_launch_local_memory< DriverType > , cudaFuncCachePreferShared ) );
+        CUDA_SAFE_CALL( cudaFuncSetCacheConfig( cuda_parallel_launch_local_memory< DriverType, LaunchBounds::maxTperB, LaunchBounds::minBperSM > , cudaFuncCachePreferShared ) );
       } else {
-        CUDA_SAFE_CALL( cudaFuncSetCacheConfig( cuda_parallel_launch_local_memory< DriverType > , cudaFuncCachePreferL1 ) );
+        CUDA_SAFE_CALL( cudaFuncSetCacheConfig( cuda_parallel_launch_local_memory< DriverType, LaunchBounds::maxTperB, LaunchBounds::minBperSM > , cudaFuncCachePreferL1 ) );
       }
       #endif
 
-      #ifndef KOKKOS_ENABLE_CUDA_RELOCATABLE_DEVICE_CODE
-      Kokkos::Impl::CudaLockArraysStruct locks;
-      locks.atomic = atomic_lock_array_cuda_space_ptr(false);
-      locks.scratch = scratch_lock_array_cuda_space_ptr(false);
-      locks.threadid = threadid_lock_array_cuda_space_ptr(false);
-      locks.n = Kokkos::Cuda::concurrency();
-      cudaMemcpyToSymbol( kokkos_impl_cuda_lock_arrays , & locks , sizeof(CudaLockArraysStruct) );
-      #endif
+      KOKKOS_ENSURE_CUDA_LOCK_ARRAYS_ON_DEVICE();
 
-      cuda_parallel_launch_local_memory< DriverType ><<< grid , block , shmem , stream >>>( driver );
+      cuda_parallel_launch_local_memory< DriverType, LaunchBounds::maxTperB, LaunchBounds::minBperSM ><<< grid , block , shmem , stream >>>( driver );
 
 #if defined( KOKKOS_ENABLE_DEBUG_BOUNDS_CHECK )
       CUDA_SAFE_CALL( cudaGetLastError() );
diff --git a/lib/kokkos/core/src/Cuda/Kokkos_CudaSpace.cpp b/lib/kokkos/core/src/Cuda/Kokkos_CudaSpace.cpp
index 406b4f1e22..b699f0d6ba 100644
--- a/lib/kokkos/core/src/Cuda/Kokkos_CudaSpace.cpp
+++ b/lib/kokkos/core/src/Cuda/Kokkos_CudaSpace.cpp
@@ -230,18 +230,6 @@ void CudaHostPinnedSpace::deallocate( void * const arg_alloc_ptr , const size_t
   } catch(...) {}
 }
 
-constexpr const char* CudaSpace::name() {
-  return m_name;
-}
-
-constexpr const char* CudaUVMSpace::name() {
-  return m_name;
-}
-
-constexpr const char* CudaHostPinnedSpace::name() {
-  return m_name;
-}
-
 } // namespace Kokkos
 
 //----------------------------------------------------------------------------
@@ -655,11 +643,12 @@ reallocate_tracked( void * const arg_alloc_ptr
 SharedAllocationRecord< Kokkos::CudaSpace , void > *
 SharedAllocationRecord< Kokkos::CudaSpace , void >::get_record( void * alloc_ptr )
 {
-  using Header     = SharedAllocationHeader ;
   using RecordBase = SharedAllocationRecord< void , void > ;
   using RecordCuda = SharedAllocationRecord< Kokkos::CudaSpace , void > ;
 
 #if 0
+  using Header     = SharedAllocationHeader ;
+
   // Copy the header from the allocation
   Header head ;
 
@@ -812,83 +801,6 @@ print_records( std::ostream & s , const Kokkos::CudaHostPinnedSpace & space , bo
   SharedAllocationRecord< void , void >::print_host_accessible_records( s , "CudaHostPinned" , & s_root_record , detail );
 }
 
-} // namespace Impl
-} // namespace Kokkos
-
-/*--------------------------------------------------------------------------*/
-/*--------------------------------------------------------------------------*/
-
-namespace Kokkos {
-namespace {
-  __global__ void init_lock_array_kernel_atomic() {
-    unsigned i = blockIdx.x*blockDim.x + threadIdx.x;
-
-    if(i>>();
-    init_lock_array_kernel_scratch_threadid<<<(Kokkos::Cuda::concurrency()+255)/256,256>>>(Kokkos::Cuda::concurrency());
-  }
-}
-
 void* cuda_resize_scratch_space(std::int64_t bytes, bool force_shrink) {
   static void* ptr = NULL;
   static std::int64_t current_size = 0;
@@ -908,8 +820,8 @@ void* cuda_resize_scratch_space(std::int64_t bytes, bool force_shrink) {
   return ptr;
 }
 
-}
-}
+} // namespace Impl
+} // namespace Kokkos
 #else
 void KOKKOS_CORE_SRC_CUDA_CUDASPACE_PREVENT_LINK_ERROR() {}
 #endif // KOKKOS_ENABLE_CUDA
diff --git a/lib/kokkos/core/src/Cuda/Kokkos_Cuda_Impl.cpp b/lib/kokkos/core/src/Cuda/Kokkos_Cuda_Impl.cpp
index daf55cbd97..80e8f9bd8a 100644
--- a/lib/kokkos/core/src/Cuda/Kokkos_Cuda_Impl.cpp
+++ b/lib/kokkos/core/src/Cuda/Kokkos_Cuda_Impl.cpp
@@ -51,6 +51,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -69,9 +70,6 @@
 __device__ __constant__
 unsigned long kokkos_impl_cuda_constant_memory_buffer[ Kokkos::Impl::CudaTraits::ConstantMemoryUsage / sizeof(unsigned long) ] ;
 
-__device__ __constant__
-Kokkos::Impl::CudaLockArraysStruct kokkos_impl_cuda_lock_arrays ;
-
 #endif
 
 /*--------------------------------------------------------------------------*/
@@ -103,6 +101,7 @@ int cuda_kernel_arch()
   return arch ;
 }
 
+#ifdef KOKKOS_ENABLE_CUDA_UVM
 bool cuda_launch_blocking()
 {
   const char * env = getenv("CUDA_LAUNCH_BLOCKING");
@@ -111,16 +110,13 @@ bool cuda_launch_blocking()
 
   return atoi(env);
 }
+#endif
 
 }
 
 void cuda_device_synchronize()
 {
-//  static const bool launch_blocking = cuda_launch_blocking();
-
-//  if (!launch_blocking) {
-    CUDA_SAFE_CALL( cudaDeviceSynchronize() );
-//  }
+  CUDA_SAFE_CALL( cudaDeviceSynchronize() );
 }
 
 void cuda_internal_error_throw( cudaError e , const char * name, const char * file, const int line )
@@ -240,6 +236,7 @@ public:
   unsigned    m_maxWarpCount ;
   unsigned    m_maxBlock ;
   unsigned    m_maxSharedWords ;
+  uint32_t    m_maxConcurrency ;
   size_type   m_scratchSpaceCount ;
   size_type   m_scratchFlagsCount ;
   size_type   m_scratchUnifiedCount ;
@@ -248,6 +245,7 @@ public:
   size_type * m_scratchSpace ;
   size_type * m_scratchFlags ;
   size_type * m_scratchUnified ;
+  uint32_t  * m_scratchConcurrentBitset ;
   cudaStream_t * m_stream ;
 
   static int was_initialized;
@@ -274,6 +272,7 @@ public:
     , m_maxWarpCount( 0 )
     , m_maxBlock( 0 )
     , m_maxSharedWords( 0 )
+    , m_maxConcurrency( 0 )
     , m_scratchSpaceCount( 0 )
     , m_scratchFlagsCount( 0 )
     , m_scratchUnifiedCount( 0 )
@@ -282,6 +281,7 @@ public:
     , m_scratchSpace( 0 )
     , m_scratchFlags( 0 )
     , m_scratchUnified( 0 )
+    , m_scratchConcurrentBitset( 0 )
     , m_stream( 0 )
     {}
 
@@ -327,7 +327,8 @@ CudaInternal::~CudaInternal()
   if ( m_stream ||
        m_scratchSpace ||
        m_scratchFlags ||
-       m_scratchUnified ) {
+       m_scratchUnified ||
+       m_scratchConcurrentBitset ) {
     std::cerr << "Kokkos::Cuda ERROR: Failed to call Kokkos::Cuda::finalize()"
               << std::endl ;
     std::cerr.flush();
@@ -339,6 +340,7 @@ CudaInternal::~CudaInternal()
   m_maxWarpCount            = 0 ;
   m_maxBlock                = 0 ;
   m_maxSharedWords          = 0 ;
+  m_maxConcurrency          = 0 ;
   m_scratchSpaceCount       = 0 ;
   m_scratchFlagsCount       = 0 ;
   m_scratchUnifiedCount     = 0 ;
@@ -347,6 +349,7 @@ CudaInternal::~CudaInternal()
   m_scratchSpace            = 0 ;
   m_scratchFlags            = 0 ;
   m_scratchUnified          = 0 ;
+  m_scratchConcurrentBitset = 0 ;
   m_stream                  = 0 ;
 }
 
@@ -485,6 +488,33 @@ void CudaInternal::initialize( int cuda_device_id , int stream_count )
       (void) scratch_space( reduce_block_count * 16 * sizeof(size_type) );
     }
     //----------------------------------
+    // Concurrent bitset for obtaining unique tokens from within
+    // an executing kernel.
+    {
+      const unsigned max_threads_per_sm = 2048 ; // up to capability 7.0
+
+      m_maxConcurrency =
+        max_threads_per_sm * cudaProp.multiProcessorCount ;
+
+      const int32_t buffer_bound =
+         Kokkos::Impl::concurrent_bitset::buffer_bound( m_maxConcurrency );
+
+      // Allocate and initialize uint32_t[ buffer_bound ]
+
+      typedef Kokkos::Experimental::Impl::SharedAllocationRecord< Kokkos::CudaSpace , void > Record ;
+
+      Record * const r = Record::allocate( Kokkos::CudaSpace()
+                                         , "InternalScratchBitset"
+                                         , sizeof(uint32_t) * buffer_bound );
+
+      Record::increment( r );
+
+      m_scratchConcurrentBitset = reinterpret_cast( r->data() );
+
+      CUDA_SAFE_CALL( cudaMemset( m_scratchConcurrentBitset , 0 , sizeof(uint32_t) * buffer_bound ) );
+
+    }
+    //----------------------------------
 
     if ( stream_count ) {
       m_stream = (cudaStream_t*) ::malloc( stream_count * sizeof(cudaStream_t) );
@@ -543,16 +573,7 @@ void CudaInternal::initialize( int cuda_device_id , int stream_count )
   cudaThreadSetCacheConfig(cudaFuncCachePreferShared);
 
   // Init the array for used for arbitrarily sized atomics
-  Impl::init_lock_arrays_cuda_space();
-
-  #ifdef KOKKOS_ENABLE_CUDA_RELOCATABLE_DEVICE_CODE
-  Kokkos::Impl::CudaLockArraysStruct locks;
-  locks.atomic = atomic_lock_array_cuda_space_ptr(false);
-  locks.scratch = scratch_lock_array_cuda_space_ptr(false);
-  locks.threadid = threadid_lock_array_cuda_space_ptr(false);
-  locks.n = Kokkos::Cuda::concurrency();
-  cudaMemcpyToSymbol( kokkos_impl_cuda_lock_arrays , & locks , sizeof(CudaLockArraysStruct) );
-  #endif
+  Impl::initialize_host_cuda_lock_arrays();
 }
 
 //----------------------------------------------------------------------------
@@ -635,9 +656,7 @@ void CudaInternal::finalize()
   was_finalized = 1;
   if ( 0 != m_scratchSpace || 0 != m_scratchFlags ) {
 
-    atomic_lock_array_cuda_space_ptr(true);
-    scratch_lock_array_cuda_space_ptr(true);
-    threadid_lock_array_cuda_space_ptr(true);
+    Impl::finalize_host_cuda_lock_arrays();
 
     if ( m_stream ) {
       for ( size_type i = 1 ; i < m_streamCount ; ++i ) {
@@ -653,6 +672,7 @@ void CudaInternal::finalize()
     RecordCuda::decrement( RecordCuda::get_record( m_scratchFlags ) );
     RecordCuda::decrement( RecordCuda::get_record( m_scratchSpace ) );
     RecordHost::decrement( RecordHost::get_record( m_scratchUnified ) );
+    RecordCuda::decrement( RecordCuda::get_record( m_scratchConcurrentBitset ) );
 
     m_cudaDev             = -1 ;
     m_multiProcCount      = 0 ;
@@ -666,6 +686,7 @@ void CudaInternal::finalize()
     m_scratchSpace        = 0 ;
     m_scratchFlags        = 0 ;
     m_scratchUnified      = 0 ;
+    m_scratchConcurrentBitset = 0 ;
     m_stream              = 0 ;
   }
 }
@@ -713,9 +734,8 @@ namespace Kokkos {
 Cuda::size_type Cuda::detect_device_count()
 { return Impl::CudaInternalDevices::singleton().m_cudaDevCount ; }
 
-int Cuda::concurrency() {
-  return 131072;
-}
+int Cuda::concurrency()
+{ return Impl::CudaInternal::singleton().m_maxConcurrency ; }
 
 int Cuda::is_initialized()
 { return Impl::CudaInternal::singleton().is_initialized(); }
@@ -798,7 +818,22 @@ void Cuda::fence()
 const char* Cuda::name() { return "Cuda"; }
 
 } // namespace Kokkos
+
+namespace Kokkos {
+namespace Experimental {
+
+UniqueToken< Kokkos::Cuda , Kokkos::Experimental::UniqueTokenScope::Global >::
+UniqueToken( Kokkos::Cuda const & )
+  : m_buffer( Kokkos::Impl::CudaInternal::singleton().m_scratchConcurrentBitset )
+  , m_count(  Kokkos::Impl::CudaInternal::singleton().m_maxConcurrency )
+  {}
+
+} // namespace Experimental
+} // namespace Kokkos
+
 #else
+
 void KOKKOS_CORE_SRC_CUDA_IMPL_PREVENT_LINK_ERROR() {}
+
 #endif // KOKKOS_ENABLE_CUDA
 
diff --git a/lib/kokkos/core/src/Cuda/Kokkos_Cuda_Locks.cpp b/lib/kokkos/core/src/Cuda/Kokkos_Cuda_Locks.cpp
new file mode 100644
index 0000000000..237022ad23
--- /dev/null
+++ b/lib/kokkos/core/src/Cuda/Kokkos_Cuda_Locks.cpp
@@ -0,0 +1,119 @@
+/*
+//@HEADER
+// ************************************************************************
+//
+//                        Kokkos v. 2.0
+//              Copyright (2014) Sandia Corporation
+//
+// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
+// the U.S. Government retains certain rights in this software.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the Corporation nor the names of the
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Questions? Contact  H. Carter Edwards (hcedwar@sandia.gov)
+//
+// ************************************************************************
+//@HEADER
+*/
+
+#include 
+
+#ifdef KOKKOS_ENABLE_CUDA
+
+#include 
+#include 
+#include 
+
+#ifdef KOKKOS_ENABLE_CUDA_RELOCATABLE_DEVICE_CODE
+namespace Kokkos {
+namespace Impl {
+__device__ __constant__
+CudaLockArrays g_device_cuda_lock_arrays = { nullptr, nullptr, 0 };
+}
+}
+#endif
+
+namespace Kokkos {
+
+namespace {
+
+__global__ void init_lock_array_kernel_atomic() {
+  unsigned i = blockIdx.x*blockDim.x + threadIdx.x;
+  if(i>>();
+  init_lock_array_kernel_threadid<<<(Kokkos::Cuda::concurrency()+255)/256,256>>>(Kokkos::Cuda::concurrency());
+  CUDA_SAFE_CALL(cudaDeviceSynchronize());
+}
+
+void finalize_host_cuda_lock_arrays() {
+  if (g_host_cuda_lock_arrays.atomic == nullptr) return;
+  cudaFree(g_host_cuda_lock_arrays.atomic);
+  g_host_cuda_lock_arrays.atomic = nullptr;
+  cudaFree(g_host_cuda_lock_arrays.scratch);
+  g_host_cuda_lock_arrays.scratch = nullptr;
+  g_host_cuda_lock_arrays.n = 0;
+#ifdef KOKKOS_ENABLE_CUDA_RELOCATABLE_DEVICE_CODE
+  KOKKOS_COPY_CUDA_LOCK_ARRAYS_TO_DEVICE();
+#endif
+}
+
+} // namespace Impl
+
+} // namespace Kokkos
+
+#else
+
+void KOKKOS_CORE_SRC_CUDA_CUDA_LOCKS_PREVENT_LINK_ERROR() {}
+
+#endif
diff --git a/lib/kokkos/core/src/Cuda/Kokkos_Cuda_Locks.hpp b/lib/kokkos/core/src/Cuda/Kokkos_Cuda_Locks.hpp
new file mode 100644
index 0000000000..d01f06fb4f
--- /dev/null
+++ b/lib/kokkos/core/src/Cuda/Kokkos_Cuda_Locks.hpp
@@ -0,0 +1,166 @@
+/*
+//@HEADER
+// ************************************************************************
+//
+//                        Kokkos v. 2.0
+//              Copyright (2014) Sandia Corporation
+//
+// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
+// the U.S. Government retains certain rights in this software.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the Corporation nor the names of the
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Questions? Contact  H. Carter Edwards (hcedwar@sandia.gov)
+//
+// ************************************************************************
+//@HEADER
+*/
+
+#ifndef KOKKOS_CUDA_LOCKS_HPP
+#define KOKKOS_CUDA_LOCKS_HPP
+
+#include 
+
+#ifdef KOKKOS_ENABLE_CUDA
+
+#include 
+
+#include 
+
+namespace Kokkos {
+namespace Impl {
+
+struct CudaLockArrays {
+  std::int32_t* atomic;
+  std::int32_t* scratch;
+  std::int32_t n;
+};
+
+/// \brief This global variable in Host space is the central definition
+///        of these arrays.
+extern Kokkos::Impl::CudaLockArrays g_host_cuda_lock_arrays ;
+
+/// \brief After this call, the g_host_cuda_lock_arrays variable has
+///        valid, initialized arrays.
+///
+/// This call is idempotent.
+void initialize_host_cuda_lock_arrays();
+
+/// \brief After this call, the g_host_cuda_lock_arrays variable has
+///        all null pointers, and all array memory has been freed.
+///
+/// This call is idempotent.
+void finalize_host_cuda_lock_arrays();
+
+} // namespace Impl
+} // namespace Kokkos
+
+#if defined( __CUDACC__ )
+
+namespace Kokkos {
+namespace Impl {
+
+/// \brief This global variable in CUDA space is what kernels use
+///        to get access to the lock arrays.
+///
+/// When relocatable device code is enabled, there can be one single
+/// instance of this global variable for the entire executable,
+/// whose definition will be in Kokkos_Cuda_Locks.cpp (and whose declaration
+/// here must then be extern.
+/// This one instance will be initialized by initialize_host_cuda_lock_arrays
+/// and need not be modified afterwards.
+///
+/// When relocatable device code is disabled, an instance of this variable
+/// will be created in every translation unit that sees this header file
+/// (we make this clear by marking it static, meaning no other translation
+///  unit can link to it).
+/// Since the Kokkos_Cuda_Locks.cpp translation unit cannot initialize the
+/// 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.
+__device__ __constant__
+#ifdef KOKKOS_ENABLE_CUDA_RELOCATABLE_DEVICE_CODE
+extern
+#endif
+Kokkos::Impl::CudaLockArrays g_device_cuda_lock_arrays ;
+
+#define CUDA_SPACE_ATOMIC_MASK 0x1FFFF
+
+/// \brief Aquire a lock for the address
+///
+/// This function tries to aquire the lock for the hash value derived
+/// from the provided ptr. If the lock is successfully aquired the
+/// function returns true. Otherwise it returns false.
+__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));
+}
+
+/// \brief Release lock for the address
+///
+/// This function releases the lock for the hash value derived
+/// from the provided ptr. This function should only be called
+/// after previously successfully aquiring a lock with
+/// lock_address.
+__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);
+}
+
+} // 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() \
+{ \
+  CUDA_SAFE_CALL(cudaMemcpyToSymbol( \
+        Kokkos::Impl::g_device_cuda_lock_arrays , \
+        & Kokkos::Impl::g_host_cuda_lock_arrays , \
+        sizeof(Kokkos::Impl::CudaLockArrays) ) ); \
+}
+
+#ifdef KOKKOS_ENABLE_CUDA_RELOCATABLE_DEVICE_CODE
+#define KOKKOS_ENSURE_CUDA_LOCK_ARRAYS_ON_DEVICE()
+#else
+#define KOKKOS_ENSURE_CUDA_LOCK_ARRAYS_ON_DEVICE() KOKKOS_COPY_CUDA_LOCK_ARRAYS_TO_DEVICE()
+#endif
+
+#endif /* defined( __CUDACC__ ) */
+
+#endif /* defined( KOKKOS_ENABLE_CUDA ) */
+
+#endif /* #ifndef KOKKOS_CUDA_LOCKS_HPP */
diff --git a/lib/kokkos/core/src/Cuda/Kokkos_Cuda_Parallel.hpp b/lib/kokkos/core/src/Cuda/Kokkos_Cuda_Parallel.hpp
index 0c8c700e8f..e2eab19e45 100644
--- a/lib/kokkos/core/src/Cuda/Kokkos_Cuda_Parallel.hpp
+++ b/lib/kokkos/core/src/Cuda/Kokkos_Cuda_Parallel.hpp
@@ -58,6 +58,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #if defined(KOKKOS_ENABLE_PROFILING)
@@ -65,6 +66,8 @@
 #include 
 #endif
 
+#include 
+
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
 
@@ -318,6 +321,7 @@ private:
   typedef Kokkos::RangePolicy< Traits ... > Policy;
   typedef typename Policy::member_type  Member ;
   typedef typename Policy::work_tag     WorkTag ;
+  typedef typename Policy::launch_bounds LaunchBounds ;
 
   const FunctorType  m_functor ;
   const Policy       m_policy ;
@@ -363,7 +367,7 @@ public:
       const dim3 block(  1 , CudaTraits::WarpSize * cuda_internal_maximum_warp_count(), 1);
       const dim3 grid( std::min( ( nwork + block.y - 1 ) / block.y , cuda_internal_maximum_grid_count() ) , 1 , 1);
 
-      CudaParallelLaunch< ParallelFor >( *this , grid , block , 0 );
+      CudaParallelLaunch< ParallelFor, LaunchBounds >( *this , grid , block , 0 );
     }
 
   ParallelFor( const FunctorType  & arg_functor ,
@@ -373,6 +377,115 @@ public:
     { }
 };
 
+
+// MDRangePolicy impl
+template< class FunctorType , class ... Traits >
+class ParallelFor< FunctorType
+                 , Kokkos::Experimental::MDRangePolicy< Traits ... >
+                 , Kokkos::Cuda
+                 >
+{
+private:
+  typedef Kokkos::Experimental::MDRangePolicy< Traits ...  > Policy ;
+  using RP = Policy;
+  typedef typename Policy::array_index_type array_index_type;
+  typedef typename Policy::index_type index_type;
+  typedef typename Policy::launch_bounds LaunchBounds;
+
+
+  const FunctorType m_functor ;
+  const Policy      m_rp ;
+
+public:
+
+  inline
+  __device__
+  void operator()(void) const
+    {
+      Kokkos::Experimental::Impl::Refactor::DeviceIterateTile(m_rp,m_functor).exec_range();
+    }
+
+
+  inline
+  void execute() const
+  {
+    const array_index_type maxblocks = static_cast(Kokkos::Impl::CudaTraits::UpperBoundGridCount);
+    if ( RP::rank == 2 )
+    {
+      const dim3 block( m_rp.m_tile[0] , m_rp.m_tile[1] , 1);
+      const dim3 grid(
+            std::min( ( m_rp.m_upper[0] - m_rp.m_lower[0] + block.x - 1 ) / block.x , maxblocks )
+          , std::min( ( m_rp.m_upper[1] - m_rp.m_lower[1] + block.y - 1 ) / block.y , maxblocks )
+          , 1
+          );
+      CudaParallelLaunch< ParallelFor, LaunchBounds >( *this , grid , block , 0 );
+    }
+    else if ( RP::rank == 3 )
+    {
+      const dim3 block( m_rp.m_tile[0] , m_rp.m_tile[1] , m_rp.m_tile[2] );
+      const dim3 grid(
+          std::min( ( m_rp.m_upper[0] - m_rp.m_lower[0] + block.x - 1 ) / block.x , maxblocks )
+        , std::min( ( m_rp.m_upper[1] - m_rp.m_lower[1] + block.y - 1 ) / block.y , maxblocks )
+        , std::min( ( m_rp.m_upper[2] - m_rp.m_lower[2] + block.z - 1 ) / block.z , maxblocks )
+        );
+      CudaParallelLaunch< ParallelFor, LaunchBounds >( *this , grid , block , 0 );
+    }
+    else if ( RP::rank == 4 )
+    {
+      // id0,id1 encoded within threadIdx.x; id2 to threadIdx.y; id3 to threadIdx.z
+      const dim3 block( m_rp.m_tile[0]*m_rp.m_tile[1] , m_rp.m_tile[2] , m_rp.m_tile[3] );
+      const dim3 grid(
+          std::min( static_cast( m_rp.m_tile_end[0] * m_rp.m_tile_end[1] )
+                  , static_cast(maxblocks) )
+        , std::min( ( m_rp.m_upper[2] - m_rp.m_lower[2] + block.y - 1 ) / block.y , maxblocks )
+        , std::min( ( m_rp.m_upper[3] - m_rp.m_lower[3] + block.z - 1 ) / block.z , maxblocks )
+        );
+      CudaParallelLaunch< ParallelFor, LaunchBounds >( *this , grid , block , 0 );
+    }
+    else if ( RP::rank == 5 )
+    {
+      // id0,id1 encoded within threadIdx.x; id2,id3 to threadIdx.y; id4 to threadIdx.z
+      const dim3 block( m_rp.m_tile[0]*m_rp.m_tile[1] , m_rp.m_tile[2]*m_rp.m_tile[3] , m_rp.m_tile[4] );
+      const dim3 grid(
+          std::min( static_cast( m_rp.m_tile_end[0] * m_rp.m_tile_end[1] )
+                  , static_cast(maxblocks) )
+        , std::min( static_cast( m_rp.m_tile_end[2] * m_rp.m_tile_end[3] )
+                  , static_cast(maxblocks) )
+        , std::min( ( m_rp.m_upper[4] - m_rp.m_lower[4] + block.z - 1 ) / block.z , maxblocks )
+        );
+      CudaParallelLaunch< ParallelFor, LaunchBounds >( *this , grid , block , 0 );
+    }
+    else if ( RP::rank == 6 )
+    {
+      // id0,id1 encoded within threadIdx.x; id2,id3 to threadIdx.y; id4,id5 to threadIdx.z
+      const dim3 block( m_rp.m_tile[0]*m_rp.m_tile[1] , m_rp.m_tile[2]*m_rp.m_tile[3] , m_rp.m_tile[4]*m_rp.m_tile[5] );
+      const dim3 grid(
+          std::min( static_cast( m_rp.m_tile_end[0] * m_rp.m_tile_end[1] )
+                  , static_cast(maxblocks) )
+        ,  std::min( static_cast( m_rp.m_tile_end[2] * m_rp.m_tile_end[3] )
+                  , static_cast(maxblocks) )
+        , std::min( static_cast( m_rp.m_tile_end[4] * m_rp.m_tile_end[5] )
+                  , static_cast(maxblocks) )
+        );
+      CudaParallelLaunch< ParallelFor, LaunchBounds >( *this , grid , block , 0 );
+    }
+    else
+    {
+      printf("Kokkos::MDRange Error: Exceeded rank bounds with Cuda\n");
+      Kokkos::abort("Aborting");
+    }
+
+  } //end execute
+
+//  inline
+  ParallelFor( const FunctorType & arg_functor
+             , Policy arg_policy )
+    : m_functor( arg_functor )
+    , m_rp(  arg_policy )
+    {}
+};
+
+
 template< class FunctorType , class ... Properties >
 class ParallelFor< FunctorType
                  , Kokkos::TeamPolicy< Properties ... >
@@ -384,6 +497,7 @@ private:
   typedef TeamPolicyInternal< Kokkos::Cuda , Properties ... >   Policy ;
   typedef typename Policy::member_type  Member ;
   typedef typename Policy::work_tag     WorkTag ;
+  typedef typename Policy::launch_bounds  LaunchBounds ;
 
 public:
 
@@ -430,15 +544,15 @@ public:
     if ( m_scratch_size[1]>0 ) {
       __shared__ int base_thread_id;
       if (threadIdx.x==0 && threadIdx.y==0 ) {
-        threadid = ((blockIdx.x*blockDim.z + threadIdx.z) * blockDim.x * blockDim.y) % kokkos_impl_cuda_lock_arrays.n;
+        threadid = ((blockIdx.x*blockDim.z + threadIdx.z) * blockDim.x * blockDim.y) % Kokkos::Impl::g_device_cuda_lock_arrays.n;
         threadid = ((threadid + blockDim.x * blockDim.y-1)/(blockDim.x * blockDim.y)) * blockDim.x * blockDim.y;
-        if(threadid > kokkos_impl_cuda_lock_arrays.n) threadid-=blockDim.x * blockDim.y;
+        if(threadid > Kokkos::Impl::g_device_cuda_lock_arrays.n) threadid-=blockDim.x * blockDim.y;
         int done = 0;
         while (!done) {
-          done = (0 == atomicCAS(&kokkos_impl_cuda_lock_arrays.atomic[threadid],0,1));
+          done = (0 == atomicCAS(&Kokkos::Impl::g_device_cuda_lock_arrays.scratch[threadid],0,1));
           if(!done) {
             threadid += blockDim.x * blockDim.y;
-            if(threadid > kokkos_impl_cuda_lock_arrays.n) threadid = 0;
+            if(threadid > Kokkos::Impl::g_device_cuda_lock_arrays.n) threadid = 0;
           }
         }
         base_thread_id = threadid;
@@ -448,7 +562,8 @@ public:
     }
 
 
-    for ( int league_rank = blockIdx.x ; league_rank < m_league_size ; league_rank += gridDim.x ) {
+    const int int_league_size = (int)m_league_size;
+    for ( int league_rank = blockIdx.x ; league_rank < int_league_size ; league_rank += gridDim.x ) {
 
       this-> template exec_team< WorkTag >(
         typename Policy::member_type( kokkos_impl_cuda_shared_memory()
@@ -462,7 +577,7 @@ public:
     if ( m_scratch_size[1]>0 ) {
       __syncthreads();
       if (threadIdx.x==0 && threadIdx.y==0 )
-        kokkos_impl_cuda_lock_arrays.atomic[threadid]=0;
+        Kokkos::Impl::g_device_cuda_lock_arrays.scratch[threadid]=0;
     }
   }
 
@@ -473,7 +588,7 @@ public:
       const dim3 grid( int(m_league_size) , 1 , 1 );
       const dim3 block( int(m_vector_size) , int(m_team_size) , 1 );
 
-      CudaParallelLaunch< ParallelFor >( *this, grid, block, shmem_size_total ); // copy to device and execute
+      CudaParallelLaunch< ParallelFor, LaunchBounds >( *this, grid, block, shmem_size_total ); // copy to device and execute
 
     }
 
@@ -529,6 +644,7 @@ private:
   typedef typename Policy::WorkRange    WorkRange ;
   typedef typename Policy::work_tag     WorkTag ;
   typedef typename Policy::member_type  Member ;
+  typedef typename Policy::launch_bounds LaunchBounds ;
 
   typedef Kokkos::Impl::if_c< std::is_same::value, FunctorType, ReducerType> ReducerConditional;
   typedef typename ReducerConditional::type ReducerTypeFwd;
@@ -563,6 +679,7 @@ private:
   typedef int DummySHMEMReductionType;
 
 public:
+  // Make the exec_range calls call to Reduce::DeviceIterateTile
   template< class TagType >
   __device__ inline
   typename std::enable_if< std::is_same< TagType , void >::value >::type
@@ -686,7 +803,7 @@ public:
 
       const int shmem = UseShflReduction?0:cuda_single_inter_block_reduce_scan_shmem( m_functor , block.y );
 
-      CudaParallelLaunch< ParallelReduce >( *this, grid, block, shmem ); // copy to device and execute
+      CudaParallelLaunch< ParallelReduce, LaunchBounds >( *this, grid, block, shmem ); // copy to device and execute
 
       Cuda::fence();
 
@@ -737,6 +854,232 @@ public:
   { }
 };
 
+
+// MDRangePolicy impl
+template< class FunctorType , class ReducerType, class ... Traits >
+class ParallelReduce< FunctorType
+                    , Kokkos::Experimental::MDRangePolicy< Traits ... >
+                    , ReducerType
+                    , Kokkos::Cuda
+                    >
+{
+private:
+
+  typedef Kokkos::Experimental::MDRangePolicy< Traits ... > Policy ;
+  typedef typename Policy::array_index_type                 array_index_type;
+  typedef typename Policy::index_type                       index_type;
+
+  typedef typename Policy::work_tag     WorkTag ;
+  typedef typename Policy::member_type  Member ;
+  typedef typename Policy::launch_bounds LaunchBounds;
+
+  typedef Kokkos::Impl::if_c< std::is_same::value, FunctorType, ReducerType> ReducerConditional;
+  typedef typename ReducerConditional::type ReducerTypeFwd;
+
+  typedef Kokkos::Impl::FunctorValueTraits< ReducerTypeFwd, WorkTag > ValueTraits ;
+  typedef Kokkos::Impl::FunctorValueInit<   ReducerTypeFwd, WorkTag > ValueInit ;
+  typedef Kokkos::Impl::FunctorValueJoin<   ReducerTypeFwd, WorkTag > ValueJoin ;
+
+public:
+
+  typedef typename ValueTraits::pointer_type    pointer_type ;
+  typedef typename ValueTraits::value_type      value_type ;
+  typedef typename ValueTraits::reference_type  reference_type ;
+  typedef FunctorType                           functor_type ;
+  typedef Cuda::size_type                       size_type ;
+
+  // Algorithmic constraints: blockSize is a power of two AND blockDim.y == blockDim.z == 1
+
+  const FunctorType   m_functor ;
+  const Policy        m_policy ; // used for workrange and nwork
+  const ReducerType   m_reducer ;
+  const pointer_type  m_result_ptr ;
+  size_type *         m_scratch_space ;
+  size_type *         m_scratch_flags ;
+  size_type *         m_unified_space ;
+
+  typedef typename Kokkos::Experimental::Impl::Reduce::DeviceIterateTile DeviceIteratePattern;
+
+  // Shall we use the shfl based reduction or not (only use it for static sized types of more than 128bit
+  enum { UseShflReduction = ((sizeof(value_type)>2*sizeof(double)) && ValueTraits::StaticValueSize) };
+  // Some crutch to do function overloading
+private:
+  typedef double DummyShflReductionType;
+  typedef int DummySHMEMReductionType;
+
+public:
+  inline
+  __device__
+  void
+  exec_range( reference_type update ) const
+  {
+    Kokkos::Experimental::Impl::Reduce::DeviceIterateTile(m_policy, m_functor, update).exec_range();
+  }
+
+  inline
+  __device__
+  void operator() (void) const {
+    run(Kokkos::Impl::if_c::select(1,1.0) );
+  }
+
+  __device__ inline
+  void run(const DummySHMEMReductionType& ) const
+  {
+    const integral_nonzero_constant< size_type , ValueTraits::StaticValueSize / sizeof(size_type) >
+      word_count( ValueTraits::value_size( ReducerConditional::select(m_functor , m_reducer) ) / sizeof(size_type) );
+
+    {
+      reference_type value =
+        ValueInit::init( ReducerConditional::select(m_functor , m_reducer) , kokkos_impl_cuda_shared_memory() + threadIdx.y * word_count.value );
+
+      // Number of blocks is bounded so that the reduction can be limited to two passes.
+      // Each thread block is given an approximately equal amount of work to perform.
+      // Accumulate the values for this block.
+      // The accumulation ordering does not match the final pass, but is arithmatically equivalent.
+
+      this-> exec_range( value );
+    }
+
+    // Reduce with final value at blockDim.y - 1 location.
+    // Problem: non power-of-two blockDim
+    if ( cuda_single_inter_block_reduce_scan(
+           ReducerConditional::select(m_functor , m_reducer) , blockIdx.x , gridDim.x ,
+           kokkos_impl_cuda_shared_memory() , m_scratch_space , m_scratch_flags ) ) {
+
+      // This is the final block with the final result at the final threads' location
+      size_type * const shared = kokkos_impl_cuda_shared_memory() + ( blockDim.y - 1 ) * word_count.value ;
+      size_type * const global = m_unified_space ? m_unified_space : m_scratch_space ;
+
+      if ( threadIdx.y == 0 ) {
+        Kokkos::Impl::FunctorFinal< ReducerTypeFwd , WorkTag >::final( ReducerConditional::select(m_functor , m_reducer) , shared );
+      }
+
+      if ( CudaTraits::WarpSize < word_count.value ) { __syncthreads(); }
+
+      for ( unsigned i = threadIdx.y ; i < word_count.value ; i += blockDim.y ) { global[i] = shared[i]; }
+    }
+  }
+
+  __device__ inline
+   void run(const DummyShflReductionType&) const
+   {
+
+     value_type value;
+     ValueInit::init( ReducerConditional::select(m_functor , m_reducer) , &value);
+     // Number of blocks is bounded so that the reduction can be limited to two passes.
+     // Each thread block is given an approximately equal amount of work to perform.
+     // Accumulate the values for this block.
+     // The accumulation ordering does not match the final pass, but is arithmatically equivalent.
+
+     const Member work_part =
+       ( ( m_policy.m_num_tiles + ( gridDim.x - 1 ) ) / gridDim.x ); //portion of tiles handled by each block
+
+     this-> exec_range( value );
+
+     pointer_type const result = (pointer_type) (m_unified_space ? m_unified_space : m_scratch_space) ;
+
+     int max_active_thread = work_part < blockDim.y ? work_part:blockDim.y;
+     max_active_thread = (max_active_thread == 0)?blockDim.y:max_active_thread;
+
+     value_type init;
+     ValueInit::init( ReducerConditional::select(m_functor , m_reducer) , &init);
+     if(Impl::cuda_inter_block_reduction
+         (value,init,ValueJoin(ReducerConditional::select(m_functor , m_reducer)),m_scratch_space,result,m_scratch_flags,max_active_thread)) {
+       const unsigned id = threadIdx.y*blockDim.x + threadIdx.x;
+       if(id==0) {
+         Kokkos::Impl::FunctorFinal< ReducerTypeFwd , WorkTag >::final( ReducerConditional::select(m_functor , m_reducer) , (void*) &value );
+         *result = value;
+       }
+     }
+   }
+
+  // Determine block size constrained by shared memory:
+  static inline
+  unsigned local_block_size( const FunctorType & f )
+    {
+      unsigned n = CudaTraits::WarpSize * 8 ;
+      while ( n && CudaTraits::SharedMemoryCapacity < cuda_single_inter_block_reduce_scan_shmem( f , n ) ) { n >>= 1 ; }
+      return n ;
+    }
+
+  inline
+  void execute()
+    {
+      const int nwork = m_policy.m_num_tiles;
+      if ( nwork ) {
+        int block_size = m_policy.m_prod_tile_dims;
+        // CONSTRAINT: Algorithm requires block_size >= product of tile dimensions
+        // Nearest power of two
+        int exponent_pow_two = std::ceil( std::log2(block_size) );
+        block_size = std::pow(2, exponent_pow_two);
+        int suggested_blocksize = local_block_size( m_functor );
+
+        block_size = (block_size > suggested_blocksize) ? block_size : suggested_blocksize ; //Note: block_size must be less than or equal to 512
+
+
+        m_scratch_space = cuda_internal_scratch_space( ValueTraits::value_size( ReducerConditional::select(m_functor , m_reducer) ) * block_size /* block_size == max block_count */ );
+        m_scratch_flags = cuda_internal_scratch_flags( sizeof(size_type) );
+        m_unified_space = cuda_internal_scratch_unified( ValueTraits::value_size( ReducerConditional::select(m_functor , m_reducer) ) );
+
+        // REQUIRED ( 1 , N , 1 )
+        const dim3 block( 1 , block_size , 1 );
+        // Required grid.x <= block.y
+        const dim3 grid( std::min( int(block.y) , int( nwork ) ) , 1 , 1 );
+
+      const int shmem = UseShflReduction?0:cuda_single_inter_block_reduce_scan_shmem( m_functor , block.y );
+
+      CudaParallelLaunch< ParallelReduce, LaunchBounds >( *this, grid, block, shmem ); // copy to device and execute
+
+      Cuda::fence();
+
+      if ( m_result_ptr ) {
+        if ( m_unified_space ) {
+          const int count = ValueTraits::value_count( ReducerConditional::select(m_functor , m_reducer)  );
+          for ( int i = 0 ; i < count ; ++i ) { m_result_ptr[i] = pointer_type(m_unified_space)[i] ; }
+        }
+        else {
+          const int size = ValueTraits::value_size( ReducerConditional::select(m_functor , m_reducer)  );
+          DeepCopy( m_result_ptr , m_scratch_space , size );
+        }
+      }
+    }
+    else {
+      if (m_result_ptr) {
+        ValueInit::init( ReducerConditional::select(m_functor , m_reducer) , m_result_ptr );
+      }
+    }
+  }
+
+  template< class HostViewType >
+  ParallelReduce( const FunctorType  & arg_functor
+                , const Policy       & arg_policy
+                , const HostViewType & arg_result
+                , typename std::enable_if<
+                   Kokkos::is_view< HostViewType >::value
+                ,void*>::type = NULL)
+  : m_functor( arg_functor )
+  , m_policy(  arg_policy )
+  , m_reducer( InvalidType() )
+  , m_result_ptr( arg_result.ptr_on_device() )
+  , m_scratch_space( 0 )
+  , m_scratch_flags( 0 )
+  , m_unified_space( 0 )
+  {}
+
+  ParallelReduce( const FunctorType  & arg_functor
+                , const Policy       & arg_policy
+                , const ReducerType & reducer)
+  : m_functor( arg_functor )
+  , m_policy(  arg_policy )
+  , m_reducer( reducer )
+  , m_result_ptr( reducer.view().ptr_on_device() )
+  , m_scratch_space( 0 )
+  , m_scratch_flags( 0 )
+  , m_unified_space( 0 )
+  {}
+};
+
+
 //----------------------------------------------------------------------------
 
 #if 1
@@ -753,6 +1096,7 @@ private:
   typedef TeamPolicyInternal< Kokkos::Cuda, Properties ... >  Policy ;
   typedef typename Policy::member_type  Member ;
   typedef typename Policy::work_tag     WorkTag ;
+  typedef typename Policy::launch_bounds     LaunchBounds ;
 
   typedef Kokkos::Impl::if_c< std::is_same::value, FunctorType, ReducerType> ReducerConditional;
   typedef typename ReducerConditional::type ReducerTypeFwd;
@@ -819,15 +1163,15 @@ public:
     if ( m_scratch_size[1]>0 ) {
       __shared__ int base_thread_id;
       if (threadIdx.x==0 && threadIdx.y==0 ) {
-        threadid = ((blockIdx.x*blockDim.z + threadIdx.z) * blockDim.x * blockDim.y) % kokkos_impl_cuda_lock_arrays.n;
+        threadid = ((blockIdx.x*blockDim.z + threadIdx.z) * blockDim.x * blockDim.y) % Kokkos::Impl::g_device_cuda_lock_arrays.n;
         threadid = ((threadid + blockDim.x * blockDim.y-1)/(blockDim.x * blockDim.y)) * blockDim.x * blockDim.y;
-        if(threadid > kokkos_impl_cuda_lock_arrays.n) threadid-=blockDim.x * blockDim.y;
+        if(threadid > Kokkos::Impl::g_device_cuda_lock_arrays.n) threadid-=blockDim.x * blockDim.y;
         int done = 0;
         while (!done) {
-          done = (0 == atomicCAS(&kokkos_impl_cuda_lock_arrays.atomic[threadid],0,1));
+          done = (0 == atomicCAS(&Kokkos::Impl::g_device_cuda_lock_arrays.scratch[threadid],0,1));
           if(!done) {
             threadid += blockDim.x * blockDim.y;
-            if(threadid > kokkos_impl_cuda_lock_arrays.n) threadid = 0;
+            if(threadid > Kokkos::Impl::g_device_cuda_lock_arrays.n) threadid = 0;
           }
         }
         base_thread_id = threadid;
@@ -840,7 +1184,7 @@ public:
     if ( m_scratch_size[1]>0 ) {
       __syncthreads();
       if (threadIdx.x==0 && threadIdx.y==0 )
-        kokkos_impl_cuda_lock_arrays.atomic[threadid]=0;
+        Kokkos::Impl::g_device_cuda_lock_arrays.scratch[threadid]=0;
     }
   }
 
@@ -854,7 +1198,8 @@ public:
       ValueInit::init( ReducerConditional::select(m_functor , m_reducer) , kokkos_impl_cuda_shared_memory() + threadIdx.y * word_count.value );
 
     // Iterate this block through the league
-    for ( int league_rank = blockIdx.x ; league_rank < m_league_size ; league_rank += gridDim.x ) {
+    const int int_league_size = (int)m_league_size;
+    for ( int league_rank = blockIdx.x ; league_rank < int_league_size ; league_rank += gridDim.x ) {
       this-> template exec_team< WorkTag >
         ( Member( kokkos_impl_cuda_shared_memory() + m_team_begin
                                         , m_shmem_begin
@@ -894,7 +1239,8 @@ public:
     ValueInit::init( ReducerConditional::select(m_functor , m_reducer) , &value);
 
     // Iterate this block through the league
-    for ( int league_rank = blockIdx.x ; league_rank < m_league_size ; league_rank += gridDim.x ) {
+    const int int_league_size = (int)m_league_size;
+    for ( int league_rank = blockIdx.x ; league_rank < int_league_size ; league_rank += gridDim.x ) {
       this-> template exec_team< WorkTag >
         ( Member( kokkos_impl_cuda_shared_memory() + m_team_begin
                                         , m_shmem_begin
@@ -936,7 +1282,7 @@ public:
         const dim3 grid( block_count , 1 , 1 );
         const int shmem_size_total = m_team_begin + m_shmem_begin + m_shmem_size ;
 
-        CudaParallelLaunch< ParallelReduce >( *this, grid, block, shmem_size_total ); // copy to device and execute
+        CudaParallelLaunch< ParallelReduce, LaunchBounds >( *this, grid, block, shmem_size_total ); // copy to device and execute
 
         Cuda::fence();
 
@@ -975,12 +1321,6 @@ public:
   , m_shmem_begin( 0 )
   , m_shmem_size( 0 )
   , m_scratch_ptr{NULL,NULL}
-  , m_league_size( arg_policy.league_size() )
-  , m_team_size( 0 <= arg_policy.team_size() ? arg_policy.team_size() :
-      Kokkos::Impl::cuda_get_opt_block_size< ParallelReduce >( arg_functor , arg_policy.vector_length(),
-                                                               arg_policy.team_scratch_size(0),arg_policy.thread_scratch_size(0) ) /
-                                                               arg_policy.vector_length() )
-  , m_vector_size( arg_policy.vector_length() )
   , m_scratch_size{
     arg_policy.scratch_size(0,( 0 <= arg_policy.team_size() ? arg_policy.team_size() :
         Kokkos::Impl::cuda_get_opt_block_size< ParallelReduce >( arg_functor , arg_policy.vector_length(),
@@ -991,6 +1331,12 @@ public:
                                                                  arg_policy.team_scratch_size(0),arg_policy.thread_scratch_size(0) ) /
                                                                  arg_policy.vector_length() )
         )}
+  , m_league_size( arg_policy.league_size() )
+  , m_team_size( 0 <= arg_policy.team_size() ? arg_policy.team_size() :
+      Kokkos::Impl::cuda_get_opt_block_size< ParallelReduce >( arg_functor , arg_policy.vector_length(),
+                                                               arg_policy.team_scratch_size(0),arg_policy.thread_scratch_size(0) ) /
+                                                               arg_policy.vector_length() )
+  , m_vector_size( arg_policy.vector_length() )
   {
     // Return Init value if the number of worksets is zero
     if( arg_policy.league_size() == 0) {
@@ -1150,6 +1496,7 @@ private:
   typedef typename reducer_type<>::pointer_type    pointer_type ;
   typedef typename reducer_type<>::reference_type  reference_type ;
   typedef typename reducer_type<>::value_type      value_type ;
+  typedef typename Policy::launch_bounds           LaunchBounds ;
 
   typedef Kokkos::Impl::FunctorAnalysis
     < Kokkos::Impl::FunctorPatternInterface::REDUCE
@@ -1273,7 +1620,7 @@ public:
         const int  shmem = m_shmem_team_begin + m_shmem_team_size ;
 
         // copy to device and execute
-        CudaParallelLaunch( *this, grid, block, shmem );
+        CudaParallelLaunch( *this, grid, block, shmem );
 
         Cuda::fence();
 
@@ -1373,7 +1720,7 @@ public:
 
     if ( CudaTraits::WarpSize < team_threads ) {
       // Need inter-warp team reduction (collectives) shared memory
-      // Speculate an upper bound for the value size 
+      // Speculate an upper bound for the value size
 
       m_shmem_team_begin =
         align_scratch( CudaTraits::warp_count(team_threads) * sizeof(double) );
@@ -1426,7 +1773,7 @@ public:
 
     // Reduce space has claim flag followed by vaue buffer
     const int global_reduce_value_size =
-      max_concurrent_block * 
+      max_concurrent_block *
       ( aligned_flag_size + align_scratch( value_size ) );
 
     // Scratch space has claim flag followed by scratch buffer
@@ -1469,6 +1816,7 @@ private:
   typedef typename Policy::member_type  Member ;
   typedef typename Policy::work_tag     WorkTag ;
   typedef typename Policy::WorkRange    WorkRange ;
+  typedef typename Policy::launch_bounds  LaunchBounds ;
 
   typedef Kokkos::Impl::FunctorValueTraits< FunctorType, WorkTag > ValueTraits ;
   typedef Kokkos::Impl::FunctorValueInit<   FunctorType, WorkTag > ValueInit ;
@@ -1655,10 +2003,10 @@ public:
         const int shmem = ValueTraits::value_size( m_functor ) * ( block_size + 2 );
 
         m_final = false ;
-        CudaParallelLaunch< ParallelScan >( *this, grid, block, shmem ); // copy to device and execute
+        CudaParallelLaunch< ParallelScan, LaunchBounds >( *this, grid, block, shmem ); // copy to device and execute
 
         m_final = true ;
-        CudaParallelLaunch< ParallelScan >( *this, grid, block, shmem ); // copy to device and execute
+        CudaParallelLaunch< ParallelScan, LaunchBounds >( *this, grid, block, shmem ); // copy to device and execute
       }
     }
 
diff --git a/lib/kokkos/core/src/Cuda/Kokkos_Cuda_ReduceScan.hpp b/lib/kokkos/core/src/Cuda/Kokkos_Cuda_ReduceScan.hpp
index 432c7895cc..709cbbd534 100644
--- a/lib/kokkos/core/src/Cuda/Kokkos_Cuda_ReduceScan.hpp
+++ b/lib/kokkos/core/src/Cuda/Kokkos_Cuda_ReduceScan.hpp
@@ -151,7 +151,7 @@ template< class ValueType , class JoinOp>
 __device__
 inline void cuda_intra_warp_reduction( ValueType& result,
                                        const JoinOp& join,
-                                       const int max_active_thread = blockDim.y) {
+                                       const uint32_t max_active_thread = blockDim.y) {
 
   unsigned int shift = 1;
 
@@ -268,29 +268,33 @@ bool cuda_inter_block_reduction( typename FunctorValueTraits< FunctorType , ArgT
         if( id + 1 < int(gridDim.x) )
           join(value, tmp);
       }
+      int active = __ballot(1);
       if (int(blockDim.x*blockDim.y) > 2) {
         value_type tmp = Kokkos::shfl_down(value, 2,32);
         if( id + 2 < int(gridDim.x) )
           join(value, tmp);
       }
+      active += __ballot(1);
       if (int(blockDim.x*blockDim.y) > 4) {
         value_type tmp = Kokkos::shfl_down(value, 4,32);
         if( id + 4 < int(gridDim.x) )
           join(value, tmp);
       }
+      active += __ballot(1);
       if (int(blockDim.x*blockDim.y) > 8) {
         value_type tmp = Kokkos::shfl_down(value, 8,32);
         if( id + 8 < int(gridDim.x) )
           join(value, tmp);
       }
+      active += __ballot(1);
       if (int(blockDim.x*blockDim.y) > 16) {
         value_type tmp = Kokkos::shfl_down(value, 16,32);
         if( id + 16 < int(gridDim.x) )
           join(value, tmp);
       }
+      active += __ballot(1);
     }
   }
-
   //The last block has in its thread=0 the global reduction value through "value"
   return last_block;
 #else
@@ -302,7 +306,7 @@ template< class ReducerType >
 __device__ inline
 typename std::enable_if< Kokkos::is_reducer::value >::type
 cuda_intra_warp_reduction( const ReducerType& reducer,
-                           const int max_active_thread = blockDim.y) {
+                           const uint32_t max_active_thread = blockDim.y) {
 
   typedef typename ReducerType::value_type ValueType;
 
@@ -428,26 +432,31 @@ cuda_inter_block_reduction( const ReducerType& reducer,
         if( id + 1 < int(gridDim.x) )
           reducer.join(value, tmp);
       }
+      int active = __ballot(1);
       if (int(blockDim.x*blockDim.y) > 2) {
         value_type tmp = Kokkos::shfl_down(value, 2,32);
         if( id + 2 < int(gridDim.x) )
           reducer.join(value, tmp);
       }
+      active += __ballot(1);
       if (int(blockDim.x*blockDim.y) > 4) {
         value_type tmp = Kokkos::shfl_down(value, 4,32);
         if( id + 4 < int(gridDim.x) )
           reducer.join(value, tmp);
       }
+      active += __ballot(1);
       if (int(blockDim.x*blockDim.y) > 8) {
         value_type tmp = Kokkos::shfl_down(value, 8,32);
         if( id + 8 < int(gridDim.x) )
           reducer.join(value, tmp);
       }
+      active += __ballot(1);
       if (int(blockDim.x*blockDim.y) > 16) {
         value_type tmp = Kokkos::shfl_down(value, 16,32);
         if( id + 16 < int(gridDim.x) )
           reducer.join(value, tmp);
       }
+      active += __ballot(1);
     }
   }
 
@@ -594,7 +603,7 @@ bool cuda_single_inter_block_reduce_scan( const FunctorType     & functor ,
   typedef FunctorValueOps<    FunctorType , ArgTag >  ValueOps ;
 
   typedef typename ValueTraits::pointer_type    pointer_type ;
-  typedef typename ValueTraits::reference_type  reference_type ;
+  //typedef typename ValueTraits::reference_type  reference_type ;
 
   // '__ffs' = position of the least significant bit set to 1.
   // 'blockDim.y' is guaranteed to be a power of two so this
@@ -637,7 +646,7 @@ bool cuda_single_inter_block_reduce_scan( const FunctorType     & functor ,
 
     {
       void * const shared_ptr = shared_data + word_count.value * threadIdx.y ;
-      reference_type shared_value = ValueInit::init( functor , shared_ptr );
+      /* reference_type shared_value = */ ValueInit::init( functor , shared_ptr );
 
       for ( size_type i = b ; i < e ; ++i ) {
         ValueJoin::join( functor , shared_ptr , global_data + word_count.value * i );
diff --git a/lib/kokkos/core/src/Cuda/Kokkos_Cuda_Task.cpp b/lib/kokkos/core/src/Cuda/Kokkos_Cuda_Task.cpp
index 3c6f0a5dda..5f08800c40 100644
--- a/lib/kokkos/core/src/Cuda/Kokkos_Cuda_Task.cpp
+++ b/lib/kokkos/core/src/Cuda/Kokkos_Cuda_Task.cpp
@@ -58,25 +58,56 @@ template class TaskQueue< Kokkos::Cuda > ;
 
 //----------------------------------------------------------------------------
 
+#if defined( KOKKOS_DEBUG )
+
+__device__
+void verify_warp_convergence( const char * const where )
+{
+  const unsigned b = __ballot(1);
+
+  if ( b != ~0u ) {
+
+printf(" verify_warp_convergence( %s ) (%d,%d,%d) (%d,%d,%d) failed %x\n"
+      , where
+      , blockIdx.x
+      , blockIdx.y
+      , blockIdx.z
+      , threadIdx.x
+      , threadIdx.y
+      , threadIdx.z
+      , b );
+
+  }
+}
+
+#endif // #if defined( KOKKOS_DEBUG )
+
+//----------------------------------------------------------------------------
+
 __device__
 void TaskQueueSpecialization< Kokkos::Cuda >::driver
-  ( TaskQueueSpecialization< Kokkos::Cuda >::queue_type * const queue )
+  ( TaskQueueSpecialization< Kokkos::Cuda >::queue_type * const queue 
+  , int32_t shmem_per_warp )
 {
   using Member = TaskExec< Kokkos::Cuda > ;
   using Queue  = TaskQueue< Kokkos::Cuda > ;
-  using task_root_type = TaskBase< Kokkos::Cuda , void , void > ;
+  using task_root_type = TaskBase< void , void , void > ;
+
+  extern __shared__ int32_t shmem_all[];
 
   task_root_type * const end = (task_root_type *) task_root_type::EndTag ;
 
-  Member single_exec( 1 );
-  Member team_exec( blockDim.y );
+  int32_t * const warp_shmem =
+    shmem_all + ( threadIdx.z * shmem_per_warp ) / sizeof(int32_t);
+
+  task_root_type * const task_shmem = (task_root_type *) warp_shmem ;
 
   const int warp_lane = threadIdx.x + threadIdx.y * blockDim.x ;
 
-  union {
-    task_root_type * ptr ;
-    int              raw[2] ;
-  } task ;
+  Member single_exec( warp_shmem , 1 );
+  Member team_exec( warp_shmem , blockDim.y );
+
+  task_root_type * task_ptr ;
 
   // Loop until all queues are empty and no tasks in flight
 
@@ -87,41 +118,86 @@ void TaskQueueSpecialization< Kokkos::Cuda >::driver
 
     if ( 0 == warp_lane ) {
 
-      task.ptr = 0 < *((volatile int *) & queue->m_ready_count) ? end : 0 ;
+      task_ptr = 0 < *((volatile int *) & queue->m_ready_count) ? end : 0 ;
 
       // Loop by priority and then type
-      for ( int i = 0 ; i < Queue::NumQueue && end == task.ptr ; ++i ) {
-        for ( int j = 0 ; j < 2 && end == task.ptr ; ++j ) {
-          task.ptr = Queue::pop_ready_task( & queue->m_ready[i][j] );
+      for ( int i = 0 ; i < Queue::NumQueue && end == task_ptr ; ++i ) {
+        for ( int j = 0 ; j < 2 && end == task_ptr ; ++j ) {
+          task_ptr = Queue::pop_ready_task( & queue->m_ready[i][j] );
         }
       }
 
 #if 0
 printf("TaskQueue::driver(%d,%d) task(%lx)\n",threadIdx.z,blockIdx.x
-      , uintptr_t(task.ptr));
+      , uintptr_t(task_ptr));
 #endif
 
     }
 
     // shuffle broadcast
 
-    task.raw[0] = __shfl( task.raw[0] , 0 );
-    task.raw[1] = __shfl( task.raw[1] , 0 );
+    ((int*) & task_ptr )[0] = __shfl( ((int*) & task_ptr )[0] , 0 );
+    ((int*) & task_ptr )[1] = __shfl( ((int*) & task_ptr )[1] , 0 );
 
-    if ( 0 == task.ptr ) break ; // 0 == queue->m_ready_count
+#if defined( KOKKOS_DEBUG )
+    verify_warp_convergence("task_ptr");
+#endif
 
-    if ( end != task.ptr ) {
-      if ( task_root_type::TaskTeam == task.ptr->m_task_type ) {
+    if ( 0 == task_ptr ) break ; // 0 == queue->m_ready_count
+
+    if ( end != task_ptr ) {
+
+      // Whole warp copy task's closure to/from shared memory.
+      // Use all threads of warp for coalesced read/write.
+
+      int32_t const b = sizeof(task_root_type) / sizeof(int32_t);
+      int32_t const e = *((int32_t volatile *)( & task_ptr->m_alloc_size )) / sizeof(int32_t);
+
+      int32_t volatile * const task_mem = (int32_t volatile *) task_ptr ;
+
+      // copy global to shared memory:
+
+      for ( int32_t i = warp_lane ; i < e ; i += CudaTraits::WarpSize ) {
+        warp_shmem[i] = task_mem[i] ;
+      }
+
+      Kokkos::memory_fence();
+
+      // Copy done - use memory fence so that memory writes are visible.
+      // For reliable warp convergence on Pascal and Volta an explicit
+      // warp level synchronization will also be required.
+
+      if ( task_root_type::TaskTeam == task_shmem->m_task_type ) {
         // Thread Team Task
-        (*task.ptr->m_apply)( task.ptr , & team_exec );
+        (*task_shmem->m_apply)( task_shmem , & team_exec );
       }
       else if ( 0 == threadIdx.y ) {
         // Single Thread Task
-        (*task.ptr->m_apply)( task.ptr , & single_exec );
+        (*task_shmem->m_apply)( task_shmem , & single_exec );
       }
 
+      // copy shared to global memory:
+
+      for ( int32_t i = b + warp_lane ; i < e ; i += CudaTraits::WarpSize ) {
+        task_mem[i] = warp_shmem[i] ;
+      }
+
+      Kokkos::memory_fence();
+
+#if defined( KOKKOS_DEBUG )
+    verify_warp_convergence("apply");
+#endif
+
+      // If respawn requested copy respawn data back to main memory
+
       if ( 0 == warp_lane ) {
-        queue->complete( task.ptr );
+
+        if ( ((task_root_type *) task_root_type::LockTag) != task_shmem->m_next ) {
+          ( (volatile task_root_type *) task_ptr )->m_next = task_shmem->m_next ;
+          ( (volatile task_root_type *) task_ptr )->m_priority = task_shmem->m_priority ;
+        }
+
+        queue->complete( task_ptr );
       }
     }
   } while(1);
@@ -130,18 +206,20 @@ printf("TaskQueue::driver(%d,%d) task(%lx)\n",threadIdx.z,blockIdx.x
 namespace {
 
 __global__
-void cuda_task_queue_execute( TaskQueue< Kokkos::Cuda > * queue )
-{ TaskQueueSpecialization< Kokkos::Cuda >::driver( queue ); }
+void cuda_task_queue_execute( TaskQueue< Kokkos::Cuda > * queue 
+                            , int32_t shmem_size )
+{ TaskQueueSpecialization< Kokkos::Cuda >::driver( queue , shmem_size ); }
 
 }
 
 void TaskQueueSpecialization< Kokkos::Cuda >::execute
   ( TaskQueue< Kokkos::Cuda > * const queue )
 {
+  const int shared_per_warp = 2048 ;
   const int warps_per_block = 4 ;
   const dim3 grid( Kokkos::Impl::cuda_internal_multiprocessor_count() , 1 , 1 );
   const dim3 block( 1 , Kokkos::Impl::CudaTraits::WarpSize , warps_per_block );
-  const int shared = 0 ;
+  const int shared_total = shared_per_warp * warps_per_block ;
   const cudaStream_t stream = 0 ;
 
   CUDA_SAFE_CALL( cudaDeviceSynchronize() );
@@ -159,7 +237,7 @@ printf("cuda_task_queue_execute before\n");
   //
   // CUDA_SAFE_CALL( cudaDeviceSetLimit( cudaLimitStackSize , stack_size ) );
 
-  cuda_task_queue_execute<<< grid , block , shared , stream >>>( queue );
+  cuda_task_queue_execute<<< grid , block , shared_total , stream >>>( queue , shared_per_warp );
 
   CUDA_SAFE_CALL( cudaGetLastError() );
 
diff --git a/lib/kokkos/core/src/Cuda/Kokkos_Cuda_Task.hpp b/lib/kokkos/core/src/Cuda/Kokkos_Cuda_Task.hpp
index 5d08219ea5..4a52985d29 100644
--- a/lib/kokkos/core/src/Cuda/Kokkos_Cuda_Task.hpp
+++ b/lib/kokkos/core/src/Cuda/Kokkos_Cuda_Task.hpp
@@ -57,7 +57,7 @@ namespace {
 template< typename TaskType >
 __global__
 void set_cuda_task_base_apply_function_pointer
-  ( TaskBase::function_type * ptr )
+  ( TaskBase::function_type * ptr )
 { *ptr = TaskType::apply ; }
 
 }
@@ -78,7 +78,7 @@ public:
   void iff_single_thread_recursive_execute( queue_type * const ) {}
 
   __device__
-  static void driver( queue_type * const );
+  static void driver( queue_type * const , int32_t );
 
   static
   void execute( queue_type * const );
@@ -106,7 +106,14 @@ public:
 
 extern template class TaskQueue< Kokkos::Cuda > ;
 
+}} /* namespace Kokkos::Impl */
+
 //----------------------------------------------------------------------------
+//----------------------------------------------------------------------------
+
+namespace Kokkos {
+namespace Impl {
+
 /**\brief  Impl::TaskExec is the TaskScheduler::member_type
  *         passed to tasks running in a Cuda space.
  *
@@ -134,11 +141,13 @@ private:
   friend class Kokkos::Impl::TaskQueue< Kokkos::Cuda > ;
   friend class Kokkos::Impl::TaskQueueSpecialization< Kokkos::Cuda > ;
 
+  int32_t * m_team_shmem ;
   const int m_team_size ;
 
   __device__
-  TaskExec( int arg_team_size = blockDim.y )
-    : m_team_size( arg_team_size ) {}
+  TaskExec( int32_t * arg_team_shmem , int arg_team_size = blockDim.y )
+    : m_team_shmem( arg_team_shmem )
+    , m_team_size( arg_team_size ) {}
 
 public:
 
@@ -154,7 +163,13 @@ public:
 
 };
 
+}} /* namespace Kokkos::Impl */
+
 //----------------------------------------------------------------------------
+//----------------------------------------------------------------------------
+
+namespace Kokkos {
+namespace Impl {
 
 template
 struct TeamThreadRangeBoundariesStruct >
diff --git a/lib/kokkos/core/src/Cuda/Kokkos_Cuda_Team.hpp b/lib/kokkos/core/src/Cuda/Kokkos_Cuda_Team.hpp
index 084daa098b..3f3d85ecd1 100644
--- a/lib/kokkos/core/src/Cuda/Kokkos_Cuda_Team.hpp
+++ b/lib/kokkos/core/src/Cuda/Kokkos_Cuda_Team.hpp
@@ -106,7 +106,7 @@ private:
   typedef Kokkos::Cuda                           execution_space ;
   typedef execution_space::scratch_memory_space  scratch_memory_space ;
 
-  void                * m_team_reduce ;
+  mutable void        * m_team_reduce ;
   scratch_memory_space  m_team_shared ;
   int                   m_team_reduce_size ;
   int                   m_league_rank ;
@@ -166,7 +166,7 @@ public:
       if ( 1 == blockDim.z ) { // team == block
         __syncthreads();
         // Wait for shared data write until all threads arrive here
-        if ( threadIdx.x == 0 && threadIdx.y == thread_id ) {
+        if ( threadIdx.x == 0u && threadIdx.y == (uint32_t)thread_id ) {
           *((ValueType*) m_team_reduce) = val ;
         }
         __syncthreads(); // Wait for shared data read until root thread writes
@@ -210,7 +210,7 @@ public:
       const int wx =
         ( threadIdx.x + blockDim.x * threadIdx.y ) & CudaTraits::WarpIndexMask ;
 
-      for ( int i = CudaTraits::WarpSize ; blockDim.x <= ( i >>= 1 ) ; ) {
+      for ( int i = CudaTraits::WarpSize ; (int)blockDim.x <= ( i >>= 1 ) ; ) {
 
         cuda_shfl_down( reducer.reference() , tmp , i , CudaTraits::WarpSize );
 
@@ -354,7 +354,7 @@ public:
 
       for ( int i = blockDim.x ; ( i >>= 1 ) ; ) {
         cuda_shfl_down( reducer.reference() , tmp , i , blockDim.x );
-        if ( threadIdx.x < i ) { reducer.join( tmp , reducer.reference() ); }
+        if ( (int)threadIdx.x < i ) { reducer.join( tmp , reducer.reference() ); }
       }
 
       // Broadcast from root lane to all other lanes.
@@ -410,7 +410,7 @@ public:
 
         value_type tmp( reducer.reference() );
 
-        for ( int i = CudaTraits::WarpSize ; blockDim.x <= ( i >>= 1 ) ; ) {
+        for ( int i = CudaTraits::WarpSize ; (int)blockDim.x <= ( i >>= 1 ) ; ) {
 
           cuda_shfl_down( reducer.reference(), tmp, i, CudaTraits::WarpSize );
 
@@ -479,7 +479,7 @@ public:
 
           __threadfence(); // Wait until global write is visible.
 
-          last_block = gridDim.x ==
+          last_block = (int)gridDim.x ==
                        1 + Kokkos::atomic_fetch_add(global_scratch_flags,1);
 
           // If last block then reset count
@@ -509,7 +509,7 @@ public:
         reducer.copy( ((pointer_type)shmem) + offset
                     , ((pointer_type)global_scratch_space) + offset );
 
-        for ( int i = nentry + tid ; i < gridDim.x ; i += nentry ) {
+        for ( int i = nentry + tid ; i < (int)gridDim.x ; i += nentry ) {
           reducer.join( ((pointer_type)shmem) + offset
                       , ((pointer_type)global_scratch_space)
                         + i * reducer.length() );
@@ -576,6 +576,14 @@ public:
     , m_league_size( arg_league_size )
     {}
 
+public:
+  // Declare to avoid unused private member warnings which are trigger
+  // when SFINAE excludes the member function which uses these variables
+  // Making another class a friend also surpresses these warnings
+  bool impl_avoid_sfinae_warning() const noexcept
+  {
+    return m_team_reduce_size > 0 && m_team_reduce != nullptr;
+  }
 };
 
 } // namspace Impl
@@ -913,10 +921,10 @@ void parallel_scan
     //  [t] += [t-4] if t >= 4
     //  ...
 
-    for ( int j = 1 ; j < blockDim.x ; j <<= 1 ) {
+    for ( int j = 1 ; j < (int)blockDim.x ; j <<= 1 ) {
       value_type tmp = 0 ;
       Impl::cuda_shfl_up( tmp , sval , j , blockDim.x );
-      if ( j <= threadIdx.x ) { sval += tmp ; }
+      if ( j <= (int)threadIdx.x ) { sval += tmp ; }
     }
 
     // Include accumulation and remove value for exclusive scan:
diff --git a/lib/kokkos/core/src/Cuda/Kokkos_Cuda_UniqueToken.hpp b/lib/kokkos/core/src/Cuda/Kokkos_Cuda_UniqueToken.hpp
new file mode 100644
index 0000000000..e11ae4798f
--- /dev/null
+++ b/lib/kokkos/core/src/Cuda/Kokkos_Cuda_UniqueToken.hpp
@@ -0,0 +1,133 @@
+/*
+//@HEADER
+// ************************************************************************
+//
+//                        Kokkos v. 2.0
+//              Copyright (2014) Sandia Corporation
+//
+// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
+// the U.S. Government retains certain rights in this software.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the Corporation nor the names of the
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Questions? Contact  H. Carter Edwards (hcedwar@sandia.gov)
+//
+// ************************************************************************
+//@HEADER
+*/
+
+#ifndef KOKKOS_CUDA_UNIQUE_TOKEN_HPP
+#define KOKKOS_CUDA_UNIQUE_TOKEN_HPP
+
+#include 
+#ifdef KOKKOS_ENABLE_CUDA
+
+#include 
+#include 
+#include 
+#include 
+
+namespace Kokkos { namespace Experimental {
+
+// both global and instance Unique Tokens are implemented in the same way
+template<>
+class UniqueToken< Cuda, UniqueTokenScope::Global >
+{
+private:
+
+  uint32_t volatile * m_buffer ;
+  uint32_t            m_count ;
+
+public:
+
+  using execution_space = Cuda;
+
+  explicit
+  UniqueToken( execution_space const& );
+
+  KOKKOS_INLINE_FUNCTION
+  UniqueToken() : m_buffer(0), m_count(0) {}
+
+  KOKKOS_INLINE_FUNCTION
+  UniqueToken( const UniqueToken & ) = default;
+
+  KOKKOS_INLINE_FUNCTION
+  UniqueToken( UniqueToken && )      = default;
+
+  KOKKOS_INLINE_FUNCTION
+  UniqueToken & operator=( const UniqueToken & ) = default ;
+
+  KOKKOS_INLINE_FUNCTION
+  UniqueToken & operator=( UniqueToken && ) = default ;
+
+  /// \brief upper bound for acquired values, i.e. 0 <= value < size()
+  KOKKOS_INLINE_FUNCTION
+  int32_t size() const noexcept { return m_count ; }
+
+  /// \brief acquire value such that 0 <= value < size()
+  KOKKOS_INLINE_FUNCTION
+  int32_t acquire() const
+  {
+    const Kokkos::pair result =
+      Kokkos::Impl::concurrent_bitset::
+        acquire_bounded( m_buffer
+                       , m_count
+                       , Kokkos::Impl::clock_tic() % m_count
+                       );
+
+   if ( result.first < 0 ) {
+     Kokkos::abort("UniqueToken failure to release tokens, no tokens available" );
+   }
+
+    return result.first;
+  }
+
+  /// \brief release an acquired value
+  KOKKOS_INLINE_FUNCTION
+  void release( int32_t i ) const noexcept
+  {
+    Kokkos::Impl::concurrent_bitset::release( m_buffer, i );
+  }
+};
+
+template<>
+class UniqueToken< Cuda, UniqueTokenScope::Instance >
+  : public UniqueToken< Cuda, UniqueTokenScope::Global >
+{
+public:
+
+  explicit
+  UniqueToken( execution_space const& arg )
+    : UniqueToken< Cuda, UniqueTokenScope::Global >( arg ) {}
+};
+
+}} // namespace Kokkos::Experimental
+
+#endif // KOKKOS_ENABLE_CUDA
+#endif // KOKKOS_CUDA_UNIQUE_TOKEN_HPP
+
diff --git a/lib/kokkos/core/src/Cuda/Kokkos_Cuda_View.hpp b/lib/kokkos/core/src/Cuda/Kokkos_Cuda_View.hpp
index f5e2d87fb6..d641622bb6 100644
--- a/lib/kokkos/core/src/Cuda/Kokkos_Cuda_View.hpp
+++ b/lib/kokkos/core/src/Cuda/Kokkos_Cuda_View.hpp
@@ -221,7 +221,6 @@ struct CudaLDGFetch {
 //----------------------------------------------------------------------------
 
 namespace Kokkos {
-namespace Experimental {
 namespace Impl {
 
 /** \brief  Replace Default ViewDataHandle with Cuda texture fetch specialization
@@ -294,9 +293,8 @@ public:
     }
 };
 
-}
-}
-}
+} // namespace Impl
+} // namespace Kokkos
 
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
diff --git a/lib/kokkos/core/src/Cuda/Kokkos_Cuda_WorkGraphPolicy.hpp b/lib/kokkos/core/src/Cuda/Kokkos_Cuda_WorkGraphPolicy.hpp
new file mode 100644
index 0000000000..99778c64b1
--- /dev/null
+++ b/lib/kokkos/core/src/Cuda/Kokkos_Cuda_WorkGraphPolicy.hpp
@@ -0,0 +1,119 @@
+/*
+//@HEADER
+// ************************************************************************
+//
+//                        Kokkos v. 2.0
+//              Copyright (2014) Sandia Corporation
+//
+// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
+// the U.S. Government retains certain rights in this software.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the Corporation nor the names of the
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Questions? Contact  H. Carter Edwards (hcedwar@sandia.gov)
+//
+// ************************************************************************
+//@HEADER
+*/
+
+#ifndef KOKKOS_CUDA_WORKGRAPHPOLICY_HPP
+#define KOKKOS_CUDA_WORKGRAPHPOLICY_HPP
+
+namespace Kokkos {
+namespace Impl {
+
+template< class FunctorType , class ... Traits >
+class ParallelFor< FunctorType ,
+                   Kokkos::Experimental::WorkGraphPolicy< Traits ... > ,
+                   Kokkos::Cuda
+                 >
+  : public Kokkos::Impl::Experimental::
+           WorkGraphExec< FunctorType,
+                          Kokkos::Cuda,
+                          Traits ...
+                        >
+{
+public:
+
+  typedef Kokkos::Experimental::WorkGraphPolicy< Traits ... >   Policy ;
+  typedef Kokkos::Impl::Experimental::
+          WorkGraphExec Base ;
+  typedef ParallelFor        Self ;
+
+private:
+
+  template< class TagType >
+  __device__
+  typename std::enable_if< std::is_same< TagType , void >::value >::type
+  exec_one(const typename Policy::member_type& i) const {
+    Base::m_functor( i );
+  }
+
+  template< class TagType >
+  __device__
+  typename std::enable_if< ! std::is_same< TagType , void >::value >::type
+  exec_one(const typename Policy::member_type& i) const {
+    const TagType t{} ;
+    Base::m_functor( t , i );
+  }
+
+public:
+
+  __device__
+  inline
+  void operator()() const {
+    for (std::int32_t i; (-1 != (i = Base::before_work())); ) {
+      exec_one< typename Policy::work_tag >( i );
+      Base::after_work(i);
+    }
+  }
+
+  inline
+  void execute()
+  {
+    const int warps_per_block = 4 ;
+    const dim3 grid( Kokkos::Impl::cuda_internal_multiprocessor_count() , 1 , 1 );
+    const dim3 block( 1 , Kokkos::Impl::CudaTraits::WarpSize , warps_per_block );
+    const int shared = 0 ;
+    const cudaStream_t stream = 0 ;
+
+    Kokkos::Impl::CudaParallelLaunch(*this, grid, block, shared, stream);
+  }
+
+  inline
+  ParallelFor( const FunctorType & arg_functor
+             , const Policy      & arg_policy )
+    : Base( arg_functor, arg_policy )
+  {
+  }
+};
+
+} // namespace Impl
+} // namespace Kokkos
+
+#endif /* #define KOKKOS_CUDA_WORKGRAPHPOLICY_HPP */
diff --git a/lib/kokkos/core/src/KokkosExp_MDRangePolicy.hpp b/lib/kokkos/core/src/KokkosExp_MDRangePolicy.hpp
index 4f68d9c2c0..6ef7443a14 100644
--- a/lib/kokkos/core/src/KokkosExp_MDRangePolicy.hpp
+++ b/lib/kokkos/core/src/KokkosExp_MDRangePolicy.hpp
@@ -52,6 +52,7 @@
 
 #if defined( __CUDACC__ ) && defined( KOKKOS_ENABLE_CUDA )
 #include
+#include 
 #endif
 
 namespace Kokkos { namespace Experimental {
@@ -120,28 +121,17 @@ struct MDRangePolicy
                                        , typename traits::index_type
                                        > ;
 
+  typedef MDRangePolicy execution_policy; // needed for is_execution_space interrogation
+
   static_assert( !std::is_same::value
                , "Kokkos Error: MD iteration pattern not defined" );
 
   using iteration_pattern   = typename traits::iteration_pattern;
   using work_tag            = typename traits::work_tag;
+  using launch_bounds       = typename traits::launch_bounds;
+  using member_type = typename range_policy::member_type;
 
-  static constexpr int rank = iteration_pattern::rank;
-
-  static constexpr int outer_direction = static_cast (
-      (iteration_pattern::outer_direction != Iterate::Default)
-    ? iteration_pattern::outer_direction
-    : default_outer_direction< typename traits::execution_space>::value );
-
-  static constexpr int inner_direction = static_cast (
-      iteration_pattern::inner_direction != Iterate::Default
-    ? iteration_pattern::inner_direction
-    : default_inner_direction< typename traits::execution_space>::value ) ;
-
-
-  // Ugly ugly workaround intel 14 not handling scoped enum correctly
-  static constexpr int Right = static_cast( Iterate::Right );
-  static constexpr int Left  = static_cast( Iterate::Left );
+  enum { rank = static_cast(iteration_pattern::rank) };
 
   using index_type  = typename traits::index_type;
   using array_index_type = long;
@@ -155,11 +145,50 @@ struct MDRangePolicy
   // This would require the user to either pass a matching index_type parameter
   // as template parameter to the MDRangePolicy or static_cast the individual values
 
+  point_type m_lower;
+  point_type m_upper;
+  tile_type  m_tile;
+  point_type m_tile_end;
+  index_type m_num_tiles;
+  index_type m_prod_tile_dims;
+
+/*
+  // NDE enum impl definition alternative - replace static constexpr int ? 
+  enum { outer_direction = static_cast (
+      (iteration_pattern::outer_direction != Iterate::Default)
+    ? iteration_pattern::outer_direction
+    : default_outer_direction< typename traits::execution_space>::value ) };
+
+  enum { inner_direction = static_cast (
+      iteration_pattern::inner_direction != Iterate::Default
+    ? iteration_pattern::inner_direction
+    : default_inner_direction< typename traits::execution_space>::value ) };
+
+  enum { Right = static_cast( Iterate::Right ) };
+  enum { Left  = static_cast( Iterate::Left ) };
+*/
+  //static constexpr int rank = iteration_pattern::rank;
+
+  static constexpr int outer_direction = static_cast (
+      (iteration_pattern::outer_direction != Iterate::Default)
+    ? iteration_pattern::outer_direction
+    : default_outer_direction< typename traits::execution_space>::value );
+
+  static constexpr int inner_direction = static_cast (
+      iteration_pattern::inner_direction != Iterate::Default
+    ? iteration_pattern::inner_direction
+    : default_inner_direction< typename traits::execution_space>::value ) ;
+
+  // Ugly ugly workaround intel 14 not handling scoped enum correctly
+  static constexpr int Right = static_cast( Iterate::Right );
+  static constexpr int Left  = static_cast( Iterate::Left );
+
   MDRangePolicy( point_type const& lower, point_type const& upper, tile_type const& tile = tile_type{} )
     : m_lower(lower)
     , m_upper(upper)
     , m_tile(tile)
     , m_num_tiles(1)
+    , m_prod_tile_dims(1)
   {
     // Host
     if ( true
@@ -172,8 +201,8 @@ struct MDRangePolicy
       for (int i=0; i 0)) )
+          if (  ((int)inner_direction == (int)Right && (i < rank-1))
+              || ((int)inner_direction == (int)Left && (i > 0)) )
           {
             m_tile[i] = 2;
           }
@@ -183,6 +212,7 @@ struct MDRangePolicy
         }
         m_tile_end[i] = static_cast((span + m_tile[i] - 1) / m_tile[i]);
         m_num_tiles *= m_tile_end[i];
+        m_prod_tile_dims *= m_tile[i];
       }
     }
     #if defined(KOKKOS_ENABLE_CUDA)
@@ -190,14 +220,18 @@ struct MDRangePolicy
     {
       index_type span;
       for (int i=0; i 0)) )
+          if (  ((int)inner_direction == (int)Right && (i < rank-1))
+              || ((int)inner_direction == (int)Left && (i > 0)) )
           {
-            m_tile[i] = 2;
+            if ( m_prod_tile_dims < 512 ) {
+              m_tile[i] = 2;
+            } else {
+              m_tile[i] = 1;
+            }
           }
           else {
             m_tile[i] = 16;
@@ -205,12 +239,9 @@ struct MDRangePolicy
         }
         m_tile_end[i] = static_cast((span + m_tile[i] - 1) / m_tile[i]);
         m_num_tiles *= m_tile_end[i];
+        m_prod_tile_dims *= m_tile[i];
       }
-      index_type total_tile_size_check = 1;
-      for (int i=0; i= 1024 ) { // improve this check - 1024,1024,64 max per dim (Kepler), but product num_threads < 1024; more restrictions pending register limit
+      if ( m_prod_tile_dims > 512 ) { // Match Cuda restriction for ParallelReduce; 1024,1024,64 max per dim (Kepler), but product num_threads < 1024
         printf(" Tile dimensions exceed Cuda limits\n");
         Kokkos::abort(" Cuda ExecSpace Error: MDRange tile dims exceed maximum number of threads per block - choose smaller tile dims");
         //Kokkos::Impl::throw_runtime_exception( " Cuda ExecSpace Error: MDRange tile dims exceed maximum number of threads per block - choose smaller tile dims");
@@ -223,19 +254,7 @@ struct MDRangePolicy
   template < typename LT , typename UT , typename TT = array_index_type >
   MDRangePolicy( std::initializer_list const& lower, std::initializer_list const& upper, std::initializer_list const& tile = {} )
   {
-#if 0
-    // This should work, less duplicated code but not yet extensively tested
-    point_type lower_tmp, upper_tmp;
-    tile_type tile_tmp;
-    for ( auto i = 0; i < rank; ++i ) {
-      lower_tmp[i] = static_cast(lower.begin()[i]);
-      upper_tmp[i] = static_cast(upper.begin()[i]);
-      tile_tmp[i]  = static_cast(tile.begin()[i]);
-    }
 
-    MDRangePolicy( lower_tmp, upper_tmp, tile_tmp );
-
-#else
     if(static_cast(m_lower.size()) != rank || static_cast(m_upper.size()) != rank)
       Kokkos::abort("MDRangePolicy: Constructor initializer lists have wrong size");
 
@@ -249,7 +268,7 @@ struct MDRangePolicy
     }
 
     m_num_tiles = 1;
-
+    m_prod_tile_dims = 1;
 
     // Host
     if ( true
@@ -262,8 +281,8 @@ struct MDRangePolicy
       for (int i=0; i 0)) )
+          if (  ((int)inner_direction == (int)Right && (i < rank-1))
+              || ((int)inner_direction == (int)Left && (i > 0)) )
           {
             m_tile[i] = 2;
           }
@@ -273,6 +292,7 @@ struct MDRangePolicy
         }
         m_tile_end[i] = static_cast((span + m_tile[i] - 1) / m_tile[i]);
         m_num_tiles *= m_tile_end[i];
+        m_prod_tile_dims *= m_tile[i];
       }
     }
     #if defined(KOKKOS_ENABLE_CUDA)
@@ -284,10 +304,14 @@ struct MDRangePolicy
         if ( m_tile[i] <= 0 ) {
           // TODO: determine what is a good default tile size for cuda
           // may be rank dependent
-          if (  (inner_direction == Right && (i < rank-1))
-              || (inner_direction == Left && (i > 0)) )
+          if (  ((int)inner_direction == (int)Right && (i < rank-1))
+              || ((int)inner_direction == (int)Left && (i > 0)) )
           {
-            m_tile[i] = 2;
+            if ( m_prod_tile_dims < 512 ) {
+              m_tile[i] = 2;
+            } else {
+              m_tile[i] = 1;
+            }
           }
           else {
             m_tile[i] = 16;
@@ -295,32 +319,22 @@ struct MDRangePolicy
         }
         m_tile_end[i] = static_cast((span + m_tile[i] - 1) / m_tile[i]);
         m_num_tiles *= m_tile_end[i];
+        m_prod_tile_dims *= m_tile[i];
       }
-      index_type total_tile_size_check = 1;
-      for (int i=0; i= 1024 ) { // improve this check - 1024,1024,64 max per dim (Kepler), but product num_threads < 1024; more restrictions pending register limit
+      if ( m_prod_tile_dims > 512 ) { // Match Cuda restriction for ParallelReduce; 1024,1024,64 max per dim (Kepler), but product num_threads < 1024
         printf(" Tile dimensions exceed Cuda limits\n");
         Kokkos::abort(" Cuda ExecSpace Error: MDRange tile dims exceed maximum number of threads per block - choose smaller tile dims");
         //Kokkos::Impl::throw_runtime_exception( " Cuda ExecSpace Error: MDRange tile dims exceed maximum number of threads per block - choose smaller tile dims");
       }
     }
     #endif
-#endif
   }
 
-
-  point_type m_lower;
-  point_type m_upper;
-  tile_type  m_tile;
-  point_type m_tile_end;
-  index_type m_num_tiles;
 };
 // ------------------------------------------------------------------ //
 
 // ------------------------------------------------------------------ //
-//md_parallel_for
+//md_parallel_for - deprecated use parallel_for
 // ------------------------------------------------------------------ //
 template 
 void md_parallel_for( MDRange const& range
@@ -335,7 +349,6 @@ void md_parallel_for( MDRange const& range
 {
   Impl::MDFunctor g(range, f);
 
-  //using range_policy = typename MDRange::range_policy;
   using range_policy = typename MDRange::impl_range_policy;
 
   Kokkos::parallel_for( range_policy(0, range.m_num_tiles).set_chunk_size(1), g, str );
@@ -354,7 +367,6 @@ void md_parallel_for( const std::string& str
 {
   Impl::MDFunctor g(range, f);
 
-  //using range_policy = typename MDRange::range_policy;
   using range_policy = typename MDRange::impl_range_policy;
 
   Kokkos::parallel_for( range_policy(0, range.m_num_tiles).set_chunk_size(1), g, str );
@@ -395,7 +407,7 @@ void md_parallel_for( MDRange const& range
 // ------------------------------------------------------------------ //
 
 // ------------------------------------------------------------------ //
-//md_parallel_reduce
+//md_parallel_reduce - deprecated use parallel_reduce
 // ------------------------------------------------------------------ //
 template 
 void md_parallel_reduce( MDRange const& range
@@ -409,9 +421,8 @@ void md_parallel_reduce( MDRange const& range
                       ) >::type* = 0
                     )
 {
-  Impl::MDFunctor g(range, f, v);
+  Impl::MDFunctor g(range, f);
 
-  //using range_policy = typename MDRange::range_policy;
   using range_policy = typename MDRange::impl_range_policy;
   Kokkos::parallel_reduce( str, range_policy(0, range.m_num_tiles).set_chunk_size(1), g, v );
 }
@@ -428,48 +439,14 @@ void md_parallel_reduce( const std::string& str
                       ) >::type* = 0
                     )
 {
-  Impl::MDFunctor g(range, f, v);
+  Impl::MDFunctor g(range, f);
 
-  //using range_policy = typename MDRange::range_policy;
   using range_policy = typename MDRange::impl_range_policy;
 
   Kokkos::parallel_reduce( str, range_policy(0, range.m_num_tiles).set_chunk_size(1), g, v );
 }
 
-// Cuda - parallel_reduce not implemented yet
-/*
-template 
-void md_parallel_reduce( MDRange const& range
-                    , Functor const& f
-                    , ValueType & v
-                    , const std::string& str = ""
-                    , typename std::enable_if<( true
-                      #if defined( KOKKOS_ENABLE_CUDA)
-                      && std::is_same< typename MDRange::range_policy::execution_space, Kokkos::Cuda>::value
-                      #endif
-                      ) >::type* = 0
-                    )
-{
-  Impl::DeviceIterateTile closure(range, f, v);
-  closure.execute();
-}
-
-template 
-void md_parallel_reduce( const std::string& str
-                    , MDRange const& range
-                    , Functor const& f
-                    , ValueType & v
-                    , typename std::enable_if<( true
-                      #if defined( KOKKOS_ENABLE_CUDA)
-                      && std::is_same< typename MDRange::range_policy::execution_space, Kokkos::Cuda>::value
-                      #endif
-                      ) >::type* = 0
-                    )
-{
-  Impl::DeviceIterateTile closure(range, f, v);
-  closure.execute();
-}
-*/
+// Cuda - md_parallel_reduce not implemented - use parallel_reduce
 
 }} // namespace Kokkos::Experimental
 
diff --git a/lib/kokkos/core/src/Kokkos_Atomic.hpp b/lib/kokkos/core/src/Kokkos_Atomic.hpp
index 3ecae24da4..3c8673c66a 100644
--- a/lib/kokkos/core/src/Kokkos_Atomic.hpp
+++ b/lib/kokkos/core/src/Kokkos_Atomic.hpp
@@ -114,40 +114,9 @@
 #endif /* Not pre-selected atomic implementation */
 #endif
 
-//----------------------------------------------------------------------------
-
-// Forward decalaration of functions supporting arbitrary sized atomics
-// This is necessary since Kokkos_Atomic.hpp is internally included very early
-// through Kokkos_HostSpace.hpp as well as the allocation tracker.
 #ifdef KOKKOS_ENABLE_CUDA
-namespace Kokkos {
-namespace Impl {
-/// \brief Aquire a lock for the address
-///
-/// This function tries to aquire the lock for the hash value derived
-/// from the provided ptr. If the lock is successfully aquired the
-/// function returns true. Otherwise it returns false.
-#ifdef KOKKOS_ENABLE_CUDA_RELOCATABLE_DEVICE_CODE
-extern
+#include 
 #endif
-__device__ inline
-bool lock_address_cuda_space(void* ptr);
-
-/// \brief Release lock for the address
-///
-/// This function releases the lock for the hash value derived
-/// from the provided ptr. This function should only be called
-/// after previously successfully aquiring a lock with
-/// lock_address.
-#ifdef KOKKOS_ENABLE_CUDA_RELOCATABLE_DEVICE_CODE
-extern
-#endif
-__device__ inline
-void unlock_address_cuda_space(void* ptr);
-}
-}
-#endif
-
 
 namespace Kokkos {
 template 
diff --git a/lib/kokkos/core/src/Kokkos_Concepts.hpp b/lib/kokkos/core/src/Kokkos_Concepts.hpp
index 9a2b53e157..5480dbf40c 100644
--- a/lib/kokkos/core/src/Kokkos_Concepts.hpp
+++ b/lib/kokkos/core/src/Kokkos_Concepts.hpp
@@ -79,6 +79,21 @@ struct IndexType
   using type = T;
 };
 
+/**\brief Specify Launch Bounds for CUDA execution.
+ *
+ *  The "best" defaults may be architecture specific.
+ */
+template< unsigned int maxT = 1024 /* Max threads per block */
+        , unsigned int minB = 1    /* Min blocks per SM */
+        >
+struct LaunchBounds
+{
+  using launch_bounds = LaunchBounds;
+  using type = LaunchBounds;
+  static unsigned int constexpr maxTperB {maxT};
+  static unsigned int constexpr minBperSM {minB};
+};
+
 } // namespace Kokkos
 
 //----------------------------------------------------------------------------
@@ -119,6 +134,7 @@ using Kokkos::is_array_layout ;
 KOKKOS_IMPL_IS_CONCEPT( iteration_pattern )
 KOKKOS_IMPL_IS_CONCEPT( schedule_type )
 KOKKOS_IMPL_IS_CONCEPT( index_type )
+KOKKOS_IMPL_IS_CONCEPT( launch_bounds )
 
 }
 
diff --git a/lib/kokkos/core/src/Kokkos_Core.hpp b/lib/kokkos/core/src/Kokkos_Core.hpp
index 19de791c0f..ddb11d2894 100644
--- a/lib/kokkos/core/src/Kokkos_Core.hpp
+++ b/lib/kokkos/core/src/Kokkos_Core.hpp
@@ -96,11 +96,13 @@ struct InitArguments {
   int num_numa;
   int device_id;
 
-  InitArguments() {
-    num_threads = -1;
-    num_numa = -1;
-    device_id = -1;
-  }
+  InitArguments( int nt = -1
+               , int nn = -1
+               , int dv = -1)
+    : num_threads( nt )
+    , num_numa( nn )
+    , device_id( dv )
+  {}
 };
 
 void initialize(int& narg, char* arg[]);
@@ -168,6 +170,9 @@ void * kokkos_realloc( void * arg_alloc , const size_t arg_alloc_size )
 
 } // namespace Kokkos
 
+#include 
+#include 
+
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
 
diff --git a/lib/kokkos/core/src/Kokkos_Core_fwd.hpp b/lib/kokkos/core/src/Kokkos_Core_fwd.hpp
index 09081d2387..8c080f7a8f 100644
--- a/lib/kokkos/core/src/Kokkos_Core_fwd.hpp
+++ b/lib/kokkos/core/src/Kokkos_Core_fwd.hpp
@@ -51,6 +51,9 @@
 #include 
 #include 
 
+#include 
+#include 
+
 //----------------------------------------------------------------------------
 // Have assumed a 64bit build (8byte pointers) throughout the code base.
 
diff --git a/lib/kokkos/core/src/Kokkos_Crs.hpp b/lib/kokkos/core/src/Kokkos_Crs.hpp
new file mode 100644
index 0000000000..93b3fa5ca9
--- /dev/null
+++ b/lib/kokkos/core/src/Kokkos_Crs.hpp
@@ -0,0 +1,333 @@
+/*
+//@HEADER
+// ************************************************************************
+//
+//                        Kokkos v. 2.0
+//              Copyright (2014) Sandia Corporation
+//
+// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
+// the U.S. Government retains certain rights in this software.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the Corporation nor the names of the
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Questions? Contact  H. Carter Edwards (hcedwar@sandia.gov)
+//
+// ************************************************************************
+//@HEADER
+*/
+
+#ifndef KOKKOS_CRS_HPP
+#define KOKKOS_CRS_HPP
+
+namespace Kokkos {
+namespace Experimental {
+
+/// \class Crs
+/// \brief Compressed row storage array.
+///
+/// \tparam DataType The type of stored entries.  If a Crs is
+///   used as the graph of a sparse matrix, then this is usually an
+///   integer type, the type of the column indices in the sparse
+///   matrix.
+///
+/// \tparam Arg1Type The second template parameter, corresponding
+///   either to the Device type (if there are no more template
+///   parameters) or to the Layout type (if there is at least one more
+///   template parameter).
+///
+/// \tparam Arg2Type The third template parameter, which if provided
+///   corresponds to the Device type.
+///
+/// \tparam SizeType The type of row offsets.  Usually the default
+///   parameter suffices.  However, setting a nondefault value is
+///   necessary in some cases, for example, if you want to have a
+///   sparse matrices with dimensions (and therefore column indices)
+///   that fit in \c int, but want to store more than INT_MAX
+///   entries in the sparse matrix.
+///
+/// A row has a range of entries:
+/// 
    +///
  • row_map[i0] <= entry < row_map[i0+1]
  • +///
  • 0 <= i1 < row_map[i0+1] - row_map[i0]
  • +///
  • entries( entry , i2 , i3 , ... );
  • +///
  • entries( row_map[i0] + i1 , i2 , i3 , ... );
  • +///
+template< class DataType, + class Arg1Type, + class Arg2Type = void, + typename SizeType = typename ViewTraits::size_type> +class Crs { +protected: + typedef ViewTraits traits; + +public: + typedef DataType data_type; + typedef typename traits::array_layout array_layout; + typedef typename traits::execution_space execution_space; + typedef typename traits::memory_space memory_space; + typedef typename traits::device_type device_type; + typedef SizeType size_type; + + typedef Crs< DataType , Arg1Type , Arg2Type , SizeType > staticcrsgraph_type; + typedef Crs< DataType , array_layout , typename traits::host_mirror_space , SizeType > HostMirror; + typedef View row_map_type; + typedef View entries_type; + + entries_type entries; + row_map_type row_map; + + //! Construct an empty view. + Crs () : entries(), row_map() {} + + //! Copy constructor (shallow copy). + Crs (const Crs& rhs) : entries (rhs.entries), row_map (rhs.row_map) + {} + + template + Crs (const EntriesType& entries_,const RowMapType& row_map_) : entries (entries_), row_map (row_map_) + {} + + /** \brief Assign to a view of the rhs array. + * If the old view is the last view + * then allocated memory is deallocated. + */ + Crs& operator= (const Crs& rhs) { + entries = rhs.entries; + row_map = rhs.row_map; + return *this; + } + + /** \brief Destroy this view of the array. + * If the last view then allocated memory is deallocated. + */ + ~Crs() {} + + /** \brief Return number of rows in the graph + */ + KOKKOS_INLINE_FUNCTION + size_type numRows() const { + return (row_map.dimension_0 () != 0) ? + row_map.dimension_0 () - static_cast (1) : + static_cast (0); + } +}; + +/*--------------------------------------------------------------------------*/ + +template< class OutCounts, + class DataType, + class Arg1Type, + class Arg2Type, + class SizeType> +void get_crs_transpose_counts( + OutCounts& out, + Crs const& in, + std::string const& name = "transpose_counts"); + +template< class OutCounts, + class InCrs> +void get_crs_row_map_from_counts( + OutCounts& out, + InCrs const& in, + std::string const& name = "row_map"); + +template< class DataType, + class Arg1Type, + class Arg2Type, + class SizeType> +void transpose_crs( + Crs& out, + Crs const& in); + +}} // namespace Kokkos::Experimental + +/*--------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------*/ + +namespace Kokkos { +namespace Impl { +namespace Experimental { + +template +class GetCrsTransposeCounts { + public: + using execution_space = typename InCrs::execution_space; + using self_type = GetCrsTransposeCounts; + using index_type = typename InCrs::size_type; + private: + InCrs in; + OutCounts out; + public: + KOKKOS_INLINE_FUNCTION + void operator()(index_type i) const { + atomic_increment( &out[in.entries(i)] ); + } + GetCrsTransposeCounts(InCrs const& arg_in, OutCounts const& arg_out): + in(arg_in),out(arg_out) { + using policy_type = RangePolicy; + using closure_type = Kokkos::Impl::ParallelFor; + const closure_type closure(*this, policy_type(0, index_type(in.entries.size()))); + closure.execute(); + execution_space::fence(); + } +}; + +template +class CrsRowMapFromCounts { + public: + using execution_space = typename InCounts::execution_space; + using value_type = typename OutRowMap::value_type; + using index_type = typename InCounts::size_type; + private: + InCounts in; + OutRowMap out; + public: + KOKKOS_INLINE_FUNCTION + void operator()(index_type i, value_type& update, bool final_pass) const { + update += in(i); + if (final_pass) { + out(i + 1) = update; + if (i == 0) { + out(0) = 0; + } + } + } + KOKKOS_INLINE_FUNCTION + void init(value_type& update) const { update = 0; } + KOKKOS_INLINE_FUNCTION + void join(volatile value_type& update, const volatile value_type& input) const { + update += input; + } + using self_type = CrsRowMapFromCounts; + CrsRowMapFromCounts(InCounts const& arg_in, OutRowMap const& arg_out): + in(arg_in),out(arg_out) { + using policy_type = RangePolicy; + using closure_type = Kokkos::Impl::ParallelScan; + closure_type closure(*this, policy_type(0, in.size())); + closure.execute(); + execution_space::fence(); + } +}; + +template +class FillCrsTransposeEntries { + public: + using execution_space = typename InCrs::execution_space; + using memory_space = typename InCrs::memory_space; + using value_type = typename OutCrs::entries_type::value_type; + using index_type = typename InCrs::size_type; + private: + using counters_type = View; + InCrs in; + OutCrs out; + counters_type counters; + public: + KOKKOS_INLINE_FUNCTION + void operator()(index_type i) const { + auto begin = in.row_map(i); + auto end = in.row_map(i + 1); + for (auto j = begin; j < end; ++j) { + auto ti = in.entries(j); + auto tbegin = out.row_map(ti); + auto tj = atomic_fetch_add( &counters(ti), 1 ); + out.entries( tbegin + tj ) = i; + } + } + using self_type = FillCrsTransposeEntries; + FillCrsTransposeEntries(InCrs const& arg_in, OutCrs const& arg_out): + in(arg_in),out(arg_out), + counters("counters", arg_out.numRows()) { + using policy_type = RangePolicy; + using closure_type = Kokkos::Impl::ParallelFor; + const closure_type closure(*this, policy_type(0, index_type(in.numRows()))); + closure.execute(); + execution_space::fence(); + } +}; + +}}} // namespace Kokkos::Impl::Experimental + +/*--------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------*/ + +namespace Kokkos { +namespace Experimental { + +template< class OutCounts, + class DataType, + class Arg1Type, + class Arg2Type, + class SizeType> +void get_crs_transpose_counts( + OutCounts& out, + Crs const& in, + std::string const& name) { + using InCrs = Crs; + out = OutCounts(name, in.numRows()); + Kokkos::Impl::Experimental:: + GetCrsTransposeCounts functor(in, out); +} + +template< class OutRowMap, + class InCounts> +void get_crs_row_map_from_counts( + OutRowMap& out, + InCounts const& in, + std::string const& name) { + out = OutRowMap(ViewAllocateWithoutInitializing(name), in.size() + 1); + Kokkos::Impl::Experimental:: + CrsRowMapFromCounts functor(in, out); +} + +template< class DataType, + class Arg1Type, + class Arg2Type, + class SizeType> +void transpose_crs( + Crs& out, + Crs const& in) +{ + typedef Crs crs_type ; + typedef typename crs_type::memory_space memory_space ; + typedef View counts_type ; + { + counts_type counts; + Kokkos::Experimental::get_crs_transpose_counts(counts, in); + Kokkos::Experimental::get_crs_row_map_from_counts(out.row_map, counts, + "tranpose_row_map"); + } + out.entries = decltype(out.entries)("transpose_entries", in.entries.size()); + Kokkos::Impl::Experimental:: + FillCrsTransposeEntries entries_functor(in, out); +} + +}} // namespace Kokkos::Experimental + +#endif /* #define KOKKOS_CRS_HPP */ diff --git a/lib/kokkos/core/src/Kokkos_Cuda.hpp b/lib/kokkos/core/src/Kokkos_Cuda.hpp index f0f0f87458..197831dee5 100644 --- a/lib/kokkos/core/src/Kokkos_Cuda.hpp +++ b/lib/kokkos/core/src/Kokkos_Cuda.hpp @@ -217,8 +217,8 @@ public: private: - cudaStream_t m_stream ; int m_device ; + cudaStream_t m_stream ; }; } // namespace Kokkos @@ -295,6 +295,7 @@ struct VerifyExecutionCanAccessMemorySpace #include #include #include +#include #include //---------------------------------------------------------------------------- diff --git a/lib/kokkos/core/src/Kokkos_CudaSpace.hpp b/lib/kokkos/core/src/Kokkos_CudaSpace.hpp index 307ab193b1..fb5985e164 100644 --- a/lib/kokkos/core/src/Kokkos_CudaSpace.hpp +++ b/lib/kokkos/core/src/Kokkos_CudaSpace.hpp @@ -90,7 +90,7 @@ public: , const size_t arg_alloc_size ) const ; /**\brief Return Name of the MemorySpace */ - static constexpr const char* name(); + static constexpr const char* name() { return m_name; } /*--------------------------------*/ /** \brief Error reporting for HostSpace attempt to access CudaSpace */ @@ -186,7 +186,7 @@ public: , const size_t arg_alloc_size ) const ; /**\brief Return Name of the MemorySpace */ - static constexpr const char* name(); + static constexpr const char* name() { return m_name; } /*--------------------------------*/ @@ -234,7 +234,7 @@ public: , const size_t arg_alloc_size ) const ; /**\brief Return Name of the MemorySpace */ - static constexpr const char* name(); + static constexpr const char* name() { return m_name; } private: diff --git a/lib/kokkos/core/src/Kokkos_ExecPolicy.hpp b/lib/kokkos/core/src/Kokkos_ExecPolicy.hpp index 375a2d3744..a8c4d77c62 100644 --- a/lib/kokkos/core/src/Kokkos_ExecPolicy.hpp +++ b/lib/kokkos/core/src/Kokkos_ExecPolicy.hpp @@ -384,6 +384,7 @@ Impl::PerThreadValue PerThread(const int& arg); * WorkTag (none): Tag which is used as the first argument for the functor operator. * Schedule (Schedule): Scheduling Policy (Dynamic, or Static). * IndexType (IndexType: Integer Index type used to iterate over the Index space. + * LaunchBounds (LaunchBounds<1024,1>: Launch Bounds for CUDA compilation. */ template< class ... Properties> class TeamPolicy: public @@ -561,6 +562,45 @@ KOKKOS_INLINE_FUNCTION Impl::ThreadVectorRangeBoundariesStruct ThreadVectorRange( const TeamMemberType&, const iType& count ); +#if defined(KOKKOS_ENABLE_PROFILING) +namespace Impl { + +template::value > +struct ParallelConstructName; + +template +struct ParallelConstructName { + ParallelConstructName(std::string const& label):label_ref(label) { + if (label.empty()) { + default_name = std::string(typeid(FunctorType).name()) + "/" + + typeid(TagType).name(); + } + } + std::string const& get() { + return (label_ref.empty()) ? default_name : label_ref; + } + std::string const& label_ref; + std::string default_name; +}; + +template +struct ParallelConstructName { + ParallelConstructName(std::string const& label):label_ref(label) { + if (label.empty()) { + default_name = std::string(typeid(FunctorType).name()); + } + } + std::string const& get() { + return (label_ref.empty()) ? default_name : label_ref; + } + std::string const& label_ref; + std::string default_name; +}; + +} // namespace Impl +#endif /* defined KOKKOS_ENABLE_PROFILING */ + } // namespace Kokkos #endif /* #define KOKKOS_EXECPOLICY_HPP */ diff --git a/lib/kokkos/core/src/Kokkos_HBWSpace.hpp b/lib/kokkos/core/src/Kokkos_HBWSpace.hpp index e224cd4e84..9c9af0dd8b 100644 --- a/lib/kokkos/core/src/Kokkos_HBWSpace.hpp +++ b/lib/kokkos/core/src/Kokkos_HBWSpace.hpp @@ -126,14 +126,6 @@ public: //! This memory space preferred device_type typedef Kokkos::Device< execution_space, memory_space > device_type; - /*--------------------------------*/ - /* Functions unique to the HBWSpace */ - static int in_parallel(); - - static void register_in_parallel( int (*)() ); - - /*--------------------------------*/ - /**\brief Default memory space instance */ HBWSpace(); HBWSpace( const HBWSpace & rhs ) = default; diff --git a/lib/kokkos/core/src/Kokkos_HostSpace.hpp b/lib/kokkos/core/src/Kokkos_HostSpace.hpp index d00cce8f60..431635047a 100644 --- a/lib/kokkos/core/src/Kokkos_HostSpace.hpp +++ b/lib/kokkos/core/src/Kokkos_HostSpace.hpp @@ -130,14 +130,6 @@ public: //! This memory space preferred device_type typedef Kokkos::Device< execution_space, memory_space > device_type; - /*--------------------------------*/ - /* Functions unique to the HostSpace */ - static int in_parallel(); - - static void register_in_parallel( int (*)() ); - - /*--------------------------------*/ - /**\brief Default memory space instance */ HostSpace(); HostSpace( HostSpace && rhs ) = default; @@ -161,7 +153,7 @@ public: , const size_t arg_alloc_size ) const; /**\brief Return Name of the MemorySpace */ - static constexpr const char* name(); + static constexpr const char* name() { return m_name; } private: AllocationMechanism m_alloc_mech; diff --git a/lib/kokkos/core/src/Kokkos_Layout.hpp b/lib/kokkos/core/src/Kokkos_Layout.hpp index f300a6d9f6..87c705153e 100644 --- a/lib/kokkos/core/src/Kokkos_Layout.hpp +++ b/lib/kokkos/core/src/Kokkos_Layout.hpp @@ -156,6 +156,8 @@ struct LayoutStride { for ( int r = 0 ; r < ARRAY_LAYOUT_MAX_RANK ; ++r ) { tmp.dimension[r] = 0 ; tmp.stride[r] = 0 ; + } + for ( int r = 0 ; r < rank ; ++r ) { check_input &= ~int( 1 << order[r] ); } if ( 0 == check_input ) { diff --git a/lib/kokkos/core/src/Kokkos_Macros.hpp b/lib/kokkos/core/src/Kokkos_Macros.hpp index 1439dbd3f8..250ef6630a 100644 --- a/lib/kokkos/core/src/Kokkos_Macros.hpp +++ b/lib/kokkos/core/src/Kokkos_Macros.hpp @@ -297,6 +297,10 @@ #endif #endif + #if defined( KOKKOS_ARCH_AVX512MIC ) + #define KOKKOS_ENABLE_RFO_PREFETCH 1 + #endif + #if defined( __MIC__ ) // Compiling for Xeon Phi #endif @@ -344,13 +348,18 @@ //#define KOKKOS_ENABLE_PRAGMA_VECTOR 1 //#define KOKKOS_ENABLE_PRAGMA_SIMD 1 + #if defined( KOKKOS_ARCH_AVX512MIC ) + #define KOKKOS_ENABLE_RFO_PREFETCH 1 + #endif + #if !defined( KOKKOS_FORCEINLINE_FUNCTION ) #define KOKKOS_FORCEINLINE_FUNCTION inline __attribute__((always_inline)) #endif #if !defined( KOKKOS_ENABLE_ASM ) && !defined( __PGIC__ ) && \ ( defined( __amd64 ) || defined( __amd64__ ) || \ - defined( __x86_64 ) || defined( __x86_64__ ) ) + defined( __x86_64 ) || defined( __x86_64__ ) || \ + defined(__PPC64__) ) #define KOKKOS_ENABLE_ASM 1 #endif #endif diff --git a/lib/kokkos/core/src/Kokkos_MasterLock.hpp b/lib/kokkos/core/src/Kokkos_MasterLock.hpp new file mode 100644 index 0000000000..81564b8eac --- /dev/null +++ b/lib/kokkos/core/src/Kokkos_MasterLock.hpp @@ -0,0 +1,73 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#ifndef KOKKOS_MASTER_LOCK_HPP +#define KOKKOS_MASTER_LOCK_HPP + +#include + +namespace Kokkos { namespace Experimental { + +// my be used to coordinate work between master instances +// SHOULD NOT be used within a parallel algorithm +// +// This lock should be used with with a scoped lock guard +// i.e. std::unique_lock, std::lock_guard +// +// cannot be copied or moved +// has the following functions available +// +// Lock() +// ~Lock() +// +// void lock() +// void unlock() +// bool try_lock() +// +template +class MasterLock; + +}} // namespace Kokkos::Experimental + +#endif //KOKKOS_MASTER_LOCK_HPP + diff --git a/lib/kokkos/core/src/Kokkos_MemoryPool.hpp b/lib/kokkos/core/src/Kokkos_MemoryPool.hpp index dbf1ad8057..1da936067d 100644 --- a/lib/kokkos/core/src/Kokkos_MemoryPool.hpp +++ b/lib/kokkos/core/src/Kokkos_MemoryPool.hpp @@ -66,11 +66,6 @@ private: enum : uint32_t { max_bit_count_lg2 = CB::max_bit_count_lg2 }; enum : uint32_t { max_bit_count = CB::max_bit_count }; - /* Defaults for min block, max block, and superblock sizes */ - enum : uint32_t { MIN_BLOCK_SIZE_LG2 = 6 /* 64 bytes */ }; - enum : uint32_t { MAX_BLOCK_SIZE_LG2 = 12 /* 4k bytes */ }; - enum : uint32_t { SUPERBLOCK_SIZE_LG2 = 16 /* 64k bytes */ }; - enum : uint32_t { HINT_PER_BLOCK_SIZE = 2 }; /* Each superblock has a concurrent bitset state @@ -85,6 +80,14 @@ private: * is concurrently updated. */ + /* Mapping between block_size <-> block_state + * + * block_state = ( m_sb_size_lg2 - block_size_lg2 ) << state_shift + * block_size = m_sb_size_lg2 - ( block_state >> state_shift ) + * + * Thus A_block_size < B_block_size <=> A_block_state > B_block_state + */ + typedef typename DeviceType::memory_space base_memory_space ; enum { accessible = @@ -251,10 +254,10 @@ public: * significant runtime performance improvements. */ MemoryPool( const base_memory_space & memspace - , const size_t min_total_alloc_size - , const uint32_t min_block_alloc_size // = 1 << MIN_BLOCK_SIZE_LG2 - , const uint32_t max_block_alloc_size // = 1 << MAX_BLOCK_SIZE_LG2 - , const uint32_t min_superblock_size // = 1 << SUPERBLOCK_SIZE_LG2 + , const size_t min_total_alloc_size + , size_t min_block_alloc_size = 0 + , size_t max_block_alloc_size = 0 + , size_t min_superblock_size = 0 ) : m_tracker() , m_sb_state_array(0) @@ -267,8 +270,43 @@ public: , m_data_offset(0) , m_unused_padding(0) { - const uint32_t int_align_lg2 = 3 ; /* align as int[8] */ - const uint32_t int_align_mask = ( 1u << int_align_lg2 ) - 1 ; + const uint32_t int_align_lg2 = 3 ; /* align as int[8] */ + const uint32_t int_align_mask = ( 1u << int_align_lg2 ) - 1 ; + + // Constraints and defaults: + // min_block_alloc_size <= max_block_alloc_size + // max_block_alloc_size <= min_superblock_size + // min_superblock_size <= min_total_alloc_size + + const uint32_t MIN_BLOCK_SIZE = 1u << 6 /* 64 bytes */ ; + const uint32_t MAX_BLOCK_SIZE = 1u << 12 /* 4k bytes */ ; + + if ( 0 == min_block_alloc_size ) min_block_alloc_size = MIN_BLOCK_SIZE ; + + if ( 0 == max_block_alloc_size ) { + + max_block_alloc_size = MAX_BLOCK_SIZE ; + + // Upper bound of total allocation size + max_block_alloc_size = std::min( size_t(max_block_alloc_size) + , min_total_alloc_size ); + + // Lower bound of minimum block size + max_block_alloc_size = std::max( max_block_alloc_size + , min_block_alloc_size ); + } + + if ( 0 == min_superblock_size ) { + min_superblock_size = max_block_alloc_size ; + + // Upper bound of total allocation size + min_superblock_size = std::min( size_t(min_superblock_size) + , min_total_alloc_size ); + + // Lower bound of maximum block size + min_superblock_size = std::max( min_superblock_size + , max_block_alloc_size ); + } // Block and superblock size is power of two: @@ -435,6 +473,8 @@ public: void * allocate( size_t alloc_size , int32_t attempt_limit = 1 ) const noexcept { + if ( 0 == alloc_size ) return (void*) 0 ; + void * p = 0 ; const uint32_t block_size_lg2 = get_block_size_lg2( alloc_size ); @@ -444,10 +484,9 @@ public: // Allocation will fit within a superblock // that has block sizes ( 1 << block_size_lg2 ) - const uint32_t block_count_lg2 = m_sb_size_lg2 - block_size_lg2 ; - const uint32_t block_state = block_count_lg2 << state_shift ; - const uint32_t block_count = 1u << block_count_lg2 ; - const uint32_t block_count_mask = block_count - 1 ; + const uint32_t block_count_lg2 = m_sb_size_lg2 - block_size_lg2 ; + const uint32_t block_state = block_count_lg2 << state_shift ; + const uint32_t block_count = 1u << block_count_lg2 ; // Superblock hints for this block size: // hint_sb_id_ptr[0] is the dynamically changing hint @@ -465,7 +504,7 @@ public: // the guess for which block within a superblock should // be claimed. If not available then a search occurs. - const uint32_t block_id_hint = block_count_mask & + const uint32_t block_id_hint = (uint32_t)( Kokkos::Impl::clock_tic() #if defined( KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_CUDA ) // Spread out potentially concurrent access @@ -474,6 +513,9 @@ public: #endif ); + // expected state of superblock for allocation + uint32_t sb_state = block_state ; + int32_t sb_id = -1 ; volatile uint32_t * sb_state_array = 0 ; @@ -484,6 +526,8 @@ public: if ( sb_id < 0 ) { + // No superblock specified, try the hint for this block size + sb_id = hint_sb_id = int32_t( *hint_sb_id_ptr ); sb_state_array = m_sb_state_array + ( sb_id * m_sb_state_size ); @@ -493,16 +537,20 @@ public: // 0 <= sb_id // sb_state_array == m_sb_state_array + m_sb_state_size * sb_id - if ( block_state == ( state_header_mask & *sb_state_array ) ) { + if ( sb_state == ( state_header_mask & *sb_state_array ) ) { - // This superblock state is assigned to this block size. - // Try to claim a bit. + // This superblock state is as expected, for the moment. + // Attempt to claim a bit. The attempt updates the state + // so have already made sure the state header is as expected. + + const uint32_t count_lg2 = sb_state >> state_shift ; + const uint32_t mask = ( 1u << count_lg2 ) - 1 ; const Kokkos::pair result = CB::acquire_bounded_lg2( sb_state_array - , block_count_lg2 - , block_id_hint - , block_state + , count_lg2 + , block_id_hint & mask + , sb_state ); // If result.first < 0 then failed to acquire @@ -512,16 +560,18 @@ public: if ( 0 <= result.first ) { // acquired a bit + const uint32_t size_lg2 = m_sb_size_lg2 - count_lg2 ; + // Set the allocated block pointer p = ((char*)( m_sb_state_array + m_data_offset )) + ( uint32_t(sb_id) << m_sb_size_lg2 ) // superblock memory - + ( result.first << block_size_lg2 ); // block memory + + ( result.first << size_lg2 ); // block memory break ; // Success } -// printf(" acquire block_count_lg2(%d) block_state(0x%x) sb_id(%d) result(%d,%d)\n" , block_count_lg2 , block_state , sb_id , result.first , result.second ); +// printf(" acquire count_lg2(%d) sb_state(0x%x) sb_id(%d) result(%d,%d)\n" , count_lg2 , sb_state , sb_id , result.first , result.second ); } //------------------------------------------------------------------ @@ -529,12 +579,18 @@ public: // Must find a new superblock. // Start searching at designated index for this block size. - // Look for a partially full superblock of this block size. - // Look for an empty superblock just in case cannot find partfull. + // Look for superblock that, in preferential order, + // 1) part-full superblock of this block size + // 2) empty superblock to claim for this block size + // 3) part-full superblock of the next larger block size + sb_state = block_state ; // Expect to find the desired state sb_id = -1 ; + bool update_hint = false ; int32_t sb_id_empty = -1 ; + int32_t sb_id_large = -1 ; + uint32_t sb_state_large = 0 ; sb_state_array = m_sb_state_array + sb_id_begin * m_sb_state_size ; @@ -544,38 +600,54 @@ public: // Note that the state may change at any moment // as concurrent allocations and deallocations occur. - const uint32_t state = *sb_state_array ; - const uint32_t used = state & state_used_mask ; + const uint32_t full_state = *sb_state_array ; + const uint32_t used = full_state & state_used_mask ; + const uint32_t state = full_state & state_header_mask ; - if ( block_state == ( state & state_header_mask ) ) { + if ( state == block_state ) { // Superblock is assigned to this block size - if ( used < block_count ) { + if ( used < block_count ) { // There is room to allocate one block sb_id = id ; - if ( used + 1 < block_count ) { + // Is there room to allocate more than one block? - // There is room to allocate more than one block - - Kokkos::atomic_compare_exchange - ( hint_sb_id_ptr , uint32_t(hint_sb_id) , uint32_t(sb_id) ); - } + update_hint = used + 1 < block_count ; break ; } } - else if ( ( used == 0 ) && ( sb_id_empty == -1 ) ) { + else if ( 0 == used ) { - // Superblock is not assigned to this block size - // and is the first empty superblock encountered. - // Save this id to use if a partfull superblock is not found. + // Superblock is empty - sb_id_empty = id ; + if ( -1 == sb_id_empty ) { + + // Superblock is not assigned to this block size + // and is the first empty superblock encountered. + // Save this id to use if a partfull superblock is not found. + + sb_id_empty = id ; + } } + else if ( ( -1 == sb_id_empty /* have not found an empty */ ) && + ( -1 == sb_id_large /* have not found a larger */ ) && + ( state < block_state /* a larger block */ ) && + // is not full: + ( used < ( 1u << ( state >> state_shift ) ) ) ) { + // First superblock encountered that is + // larger than this block size and + // has room for an allocation. + // Save this id to use of partfull or empty superblock not found + sb_id_large = id ; + sb_state_large = state ; + } + + // Iterate around the superblock array: if ( ++id < m_sb_count ) { sb_state_array += m_sb_state_size ; @@ -586,7 +658,7 @@ public: } } -// printf(" search m_sb_count(%d) sb_id(%d) sb_id_empty(%d)\n" , m_sb_count , sb_id , sb_id_empty ); +// printf(" search m_sb_count(%d) sb_id(%d) sb_id_empty(%d) sb_id_large(%d)\n" , m_sb_count , sb_id , sb_id_empty , sb_id_large); if ( sb_id < 0 ) { @@ -609,21 +681,31 @@ public: const uint32_t state_empty = state_header_mask & *sb_state_array ; - if ( state_empty == - Kokkos::atomic_compare_exchange - (sb_state_array,state_empty,block_state) ) { + // If this thread claims the empty block then update the hint + update_hint = + state_empty == + Kokkos::atomic_compare_exchange + (sb_state_array,state_empty,block_state); + } + else if ( 0 <= sb_id_large ) { - // If this thread claimed the block then update the hint + // Found a larger superblock with space available - Kokkos::atomic_compare_exchange - ( hint_sb_id_ptr , uint32_t(hint_sb_id) , uint32_t(sb_id) ); - } + sb_id = sb_id_large ; + sb_state = sb_state_large ; + + sb_state_array = m_sb_state_array + ( sb_id * m_sb_state_size ); } else { // Did not find a potentially usable superblock --attempt_limit ; } } + + if ( update_hint ) { + Kokkos::atomic_compare_exchange + ( hint_sb_id_ptr , uint32_t(hint_sb_id) , uint32_t(sb_id) ); + } } // end allocation attempt loop //-------------------------------------------------------------------- @@ -646,6 +728,8 @@ public: KOKKOS_INLINE_FUNCTION void deallocate( void * p , size_t /* alloc_size */ ) const noexcept { + if ( 0 == p ) return ; + // Determine which superblock and block const ptrdiff_t d = ((char*)p) - ((char*)( m_sb_state_array + m_data_offset )); diff --git a/lib/kokkos/core/src/Kokkos_MemoryTraits.hpp b/lib/kokkos/core/src/Kokkos_MemoryTraits.hpp index 94b58b8aff..af9c8ea782 100644 --- a/lib/kokkos/core/src/Kokkos_MemoryTraits.hpp +++ b/lib/kokkos/core/src/Kokkos_MemoryTraits.hpp @@ -72,11 +72,11 @@ struct MemoryTraits { //! Tag this class as a kokkos memory traits: typedef MemoryTraits memory_traits ; - enum { Unmanaged = T & unsigned(Kokkos::Unmanaged) }; - enum { RandomAccess = T & unsigned(Kokkos::RandomAccess) }; - enum { Atomic = T & unsigned(Kokkos::Atomic) }; - enum { Restrict = T & unsigned(Kokkos::Restrict) }; - enum { Aligned = T & unsigned(Kokkos::Aligned) }; + enum : bool { Unmanaged = (unsigned(0) != (T & unsigned(Kokkos::Unmanaged))) }; + enum : bool { RandomAccess = (unsigned(0) != (T & unsigned(Kokkos::RandomAccess))) }; + enum : bool { Atomic = (unsigned(0) != (T & unsigned(Kokkos::Atomic))) }; + enum : bool { Restrict = (unsigned(0) != (T & unsigned(Kokkos::Restrict))) }; + enum : bool { Aligned = (unsigned(0) != (T & unsigned(Kokkos::Aligned))) }; }; @@ -109,7 +109,11 @@ enum { MEMORY_ALIGNMENT = #else ( 1 << Kokkos::Impl::integral_power_of_two( 128 ) ) #endif - , MEMORY_ALIGNMENT_THRESHOLD = 4 +#if defined( KOKKOS_MEMORY_ALIGNMENT_THRESHOLD ) + , MEMORY_ALIGNMENT_THRESHOLD = KOKKOS_MEMORY_ALIGNMENT_THRESHOLD +#else + , MEMORY_ALIGNMENT_THRESHOLD = 4 +#endif }; diff --git a/lib/kokkos/core/src/Kokkos_OpenMP.hpp b/lib/kokkos/core/src/Kokkos_OpenMP.hpp index 3e11621ce6..d5de01cf2f 100644 --- a/lib/kokkos/core/src/Kokkos_OpenMP.hpp +++ b/lib/kokkos/core/src/Kokkos_OpenMP.hpp @@ -47,10 +47,6 @@ #include #if defined( KOKKOS_ENABLE_OPENMP) -#if !defined(_OPENMP) -#error "You enabled Kokkos OpenMP support without enabling OpenMP in the compiler!" -#endif - #include #include @@ -67,95 +63,144 @@ #include #include +#include + /*--------------------------------------------------------------------------*/ namespace Kokkos { +namespace Impl { +class OpenMPExec; +} + /// \class OpenMP /// \brief Kokkos device for multicore processors in the host memory space. class OpenMP { public: - //------------------------------------ - //! \name Type declarations that all Kokkos devices must provide. - //@{ - //! Tag this class as a kokkos execution space using execution_space = OpenMP; + + using memory_space = #ifdef KOKKOS_ENABLE_HBWSPACE - using memory_space = Experimental::HBWSpace; + Experimental::HBWSpace; #else - using memory_space = HostSpace; + HostSpace; #endif + //! This execution space preferred device_type - using device_type = Kokkos::Device; - - using array_layout = LayoutRight; - using size_type = memory_space::size_type; - + using device_type = Kokkos::Device< execution_space, memory_space >; + using array_layout = LayoutRight; + using size_type = memory_space::size_type; using scratch_memory_space = ScratchMemorySpace< OpenMP >; - //@} - //------------------------------------ - //! \name Functions that all Kokkos execution spaces must implement. - //@{ + /// \brief Get a handle to the default execution space instance + inline + OpenMP() noexcept; - inline static bool in_parallel(); + // Using omp_get_max_threads(); is problematic + // On Intel (essentially an initial call to the OpenMP runtime + // without a parallel region before will set a process mask for a single core + // The runtime will than bind threads for a parallel region to other cores on the + // entering the first parallel region and make the process mask the aggregate of + // the thread masks. The intend seems to be to make serial code run fast, if you + // compile with OpenMP enabled but don't actually use parallel regions or so + // static int omp_max_threads = omp_get_max_threads(); + static int get_current_max_threads() noexcept; - /** \brief Set the device in a "sleep" state. A noop for OpenMP. */ - static bool sleep(); + /// \brief Initialize the default execution space + /// + /// if ( thread_count == -1 ) + /// then use the number of threads that openmp defaults to + /// if ( thread_count == 0 && Kokkos::hwlow_available() ) + /// then use hwloc to choose the number of threads and change + /// the default number of threads + /// if ( thread_count > 0 ) + /// then force openmp to use the given number of threads and change + /// the default number of threads + static void initialize( int thread_count = -1 ); - /** \brief Wake the device from the 'sleep' state. A noop for OpenMP. */ - static bool wake(); - - /** \brief Wait until all dispatched functors complete. A noop for OpenMP. */ - static void fence() {} - - /// \brief Print configuration information to the given output stream. - static void print_configuration( std::ostream & , const bool detail = false ); - - /// \brief Free any resources being consumed by the device. + /// \brief Free any resources being consumed by the default execution space static void finalize(); - /** \brief Initialize the device. - * - * 1) If the hardware locality library is enabled and OpenMP has not - * already bound threads then bind OpenMP threads to maximize - * core utilization and group for memory hierarchy locality. - * - * 2) Allocate a HostThread for each OpenMP thread to hold its - * topology and fan in/out data. - */ - static void initialize( unsigned thread_count = 0 , - unsigned use_numa_count = 0 , - unsigned use_cores_per_numa = 0 ); + /// \brief is the default execution space initialized for current 'master' thread + static bool is_initialized() noexcept; - static int is_initialized(); + /// \brief Print configuration information to the given output stream. + static void print_configuration( std::ostream & , const bool verbose = false ); - /** \brief Return the maximum amount of concurrency. */ - static int concurrency(); + /// \brief is the instance running a parallel algorithm + inline + static bool in_parallel( OpenMP const& = OpenMP() ) noexcept; - //@} - //------------------------------------ - /** \brief This execution space has a topological thread pool which can be queried. - * - * All threads within a pool have a common memory space for which they are cache coherent. - * depth = 0 gives the number of threads in the whole pool. - * depth = 1 gives the number of threads in a NUMA region, typically sharing L3 cache. - * depth = 2 gives the number of threads at the finest granularity, typically sharing L1 cache. - */ - inline static int thread_pool_size( int depth = 0 ); + /// \brief Wait until all dispatched functors complete on the given instance + /// + /// This is a no-op on OpenMP + inline + static void fence( OpenMP const& = OpenMP() ) noexcept; + + /// \brief Does the given instance return immediately after launching + /// a parallel algorithm + /// + /// This always returns false on OpenMP + inline + static bool is_asynchronous( OpenMP const& = OpenMP() ) noexcept; + + + /// \brief Partition the default instance into new instances without creating + /// new masters + /// + /// This is a no-op on OpenMP since the default instance cannot be partitioned + /// without promoting other threads to 'master' + static std::vector partition(...); + + /// Non-default instances should be ref-counted so that when the last + /// is destroyed the instance resources are released + /// + /// This is a no-op on OpenMP since a non default instance cannot be created + static OpenMP create_instance(...); + + /// \brief Partition the default instance and call 'f' on each new 'master' thread + /// + /// Func is a functor with the following signiture + /// void( int partition_id, int num_partitions ) + template + static void partition_master( F const& f + , int requested_num_partitions = 0 + , int requested_partition_size = 0 + ); + + inline + static int thread_pool_size() noexcept; /** \brief The rank of the executing thread in this thread pool */ - KOKKOS_INLINE_FUNCTION static int thread_pool_rank(); + KOKKOS_INLINE_FUNCTION + static int thread_pool_rank() noexcept; - //------------------------------------ +#if !defined( KOKKOS_DISABLE_DEPRECATED ) + /// \brief Initialize the default execution space + static void initialize( int thread_count, + int use_numa_count, + int use_cores_per_numa = 0); - inline static unsigned max_hardware_threads() { return thread_pool_size(0); } + inline + static int thread_pool_size( int depth ); - KOKKOS_INLINE_FUNCTION static - unsigned hardware_thread_id() { return thread_pool_rank(); } + static void sleep() {}; + static void wake() {}; - static const char* name(); + // use UniqueToken + static int concurrency(); + + // use UniqueToken + inline + static int max_hardware_threads() noexcept; + + // use UniqueToken + KOKKOS_INLINE_FUNCTION + static int hardware_thread_id() noexcept; +#endif + + static constexpr const char* name() noexcept { return "OpenMP"; } }; } // namespace Kokkos @@ -195,6 +240,7 @@ struct VerifyExecutionCanAccessMemorySpace /*--------------------------------------------------------------------------*/ #include +#include #include #include diff --git a/lib/kokkos/core/src/Kokkos_Parallel.hpp b/lib/kokkos/core/src/Kokkos_Parallel.hpp index e412e608b2..fc8d6bec81 100644 --- a/lib/kokkos/core/src/Kokkos_Parallel.hpp +++ b/lib/kokkos/core/src/Kokkos_Parallel.hpp @@ -177,22 +177,23 @@ void parallel_for( const ExecPolicy & policy ) { #if defined(KOKKOS_ENABLE_PROFILING) - uint64_t kpID = 0; - if(Kokkos::Profiling::profileLibraryLoaded()) { - Kokkos::Profiling::beginParallelFor("" == str ? typeid(FunctorType).name() : str, 0, &kpID); - } + uint64_t kpID = 0; + if(Kokkos::Profiling::profileLibraryLoaded()) { + Kokkos::Impl::ParallelConstructName name(str); + Kokkos::Profiling::beginParallelFor(name.get(), 0, &kpID); + } #endif - Kokkos::Impl::shared_allocation_tracking_claim_and_disable(); + Kokkos::Impl::shared_allocation_tracking_disable(); Impl::ParallelFor< FunctorType , ExecPolicy > closure( functor , policy ); - Kokkos::Impl::shared_allocation_tracking_release_and_enable(); + Kokkos::Impl::shared_allocation_tracking_enable(); closure.execute(); #if defined(KOKKOS_ENABLE_PROFILING) - if(Kokkos::Profiling::profileLibraryLoaded()) { - Kokkos::Profiling::endParallelFor(kpID); - } + if(Kokkos::Profiling::profileLibraryLoaded()) { + Kokkos::Profiling::endParallelFor(kpID); + } #endif } @@ -210,14 +211,15 @@ void parallel_for( const size_t work_count #if defined(KOKKOS_ENABLE_PROFILING) uint64_t kpID = 0; - if(Kokkos::Profiling::profileLibraryLoaded()) { - Kokkos::Profiling::beginParallelFor("" == str ? typeid(FunctorType).name() : str, 0, &kpID); - } + if(Kokkos::Profiling::profileLibraryLoaded()) { + Kokkos::Impl::ParallelConstructName name(str); + Kokkos::Profiling::beginParallelFor(name.get(), 0, &kpID); + } #endif - Kokkos::Impl::shared_allocation_tracking_claim_and_disable(); + Kokkos::Impl::shared_allocation_tracking_disable(); Impl::ParallelFor< FunctorType , policy > closure( functor , policy(0,work_count) ); - Kokkos::Impl::shared_allocation_tracking_release_and_enable(); + Kokkos::Impl::shared_allocation_tracking_enable(); closure.execute(); @@ -420,21 +422,22 @@ void parallel_scan( const ExecutionPolicy & policy { #if defined(KOKKOS_ENABLE_PROFILING) uint64_t kpID = 0; - if(Kokkos::Profiling::profileLibraryLoaded()) { - Kokkos::Profiling::beginParallelScan("" == str ? typeid(FunctorType).name() : str, 0, &kpID); - } + if(Kokkos::Profiling::profileLibraryLoaded()) { + Kokkos::Impl::ParallelConstructName name(str); + Kokkos::Profiling::beginParallelScan(name.get(), 0, &kpID); + } #endif - Kokkos::Impl::shared_allocation_tracking_claim_and_disable(); + Kokkos::Impl::shared_allocation_tracking_disable(); Impl::ParallelScan< FunctorType , ExecutionPolicy > closure( functor , policy ); - Kokkos::Impl::shared_allocation_tracking_release_and_enable(); + Kokkos::Impl::shared_allocation_tracking_enable(); closure.execute(); #if defined(KOKKOS_ENABLE_PROFILING) - if(Kokkos::Profiling::profileLibraryLoaded()) { - Kokkos::Profiling::endParallelScan(kpID); - } + if(Kokkos::Profiling::profileLibraryLoaded()) { + Kokkos::Profiling::endParallelScan(kpID); + } #endif } @@ -453,21 +456,22 @@ void parallel_scan( const size_t work_count #if defined(KOKKOS_ENABLE_PROFILING) uint64_t kpID = 0; - if(Kokkos::Profiling::profileLibraryLoaded()) { - Kokkos::Profiling::beginParallelScan("" == str ? typeid(FunctorType).name() : str, 0, &kpID); - } + if(Kokkos::Profiling::profileLibraryLoaded()) { + Kokkos::Impl::ParallelConstructName name(str); + Kokkos::Profiling::beginParallelScan(name.get(), 0, &kpID); + } #endif - Kokkos::Impl::shared_allocation_tracking_claim_and_disable(); + Kokkos::Impl::shared_allocation_tracking_disable(); Impl::ParallelScan< FunctorType , policy > closure( functor , policy(0,work_count) ); - Kokkos::Impl::shared_allocation_tracking_release_and_enable(); + Kokkos::Impl::shared_allocation_tracking_enable(); closure.execute(); #if defined(KOKKOS_ENABLE_PROFILING) - if(Kokkos::Profiling::profileLibraryLoaded()) { - Kokkos::Profiling::endParallelScan(kpID); - } + if(Kokkos::Profiling::profileLibraryLoaded()) { + Kokkos::Profiling::endParallelScan(kpID); + } #endif } diff --git a/lib/kokkos/core/src/Kokkos_Parallel_Reduce.hpp b/lib/kokkos/core/src/Kokkos_Parallel_Reduce.hpp index 8ea5183e35..9df6d4ba09 100644 --- a/lib/kokkos/core/src/Kokkos_Parallel_Reduce.hpp +++ b/lib/kokkos/core/src/Kokkos_Parallel_Reduce.hpp @@ -872,13 +872,14 @@ namespace Impl { const FunctorType& functor, ReturnType& return_value) { #if defined(KOKKOS_ENABLE_PROFILING) - uint64_t kpID = 0; - if(Kokkos::Profiling::profileLibraryLoaded()) { - Kokkos::Profiling::beginParallelReduce("" == label ? typeid(FunctorType).name() : label, 0, &kpID); - } + uint64_t kpID = 0; + if(Kokkos::Profiling::profileLibraryLoaded()) { + Kokkos::Impl::ParallelConstructName name(label); + Kokkos::Profiling::beginParallelReduce(name.get(), 0, &kpID); + } #endif - Kokkos::Impl::shared_allocation_tracking_claim_and_disable(); + Kokkos::Impl::shared_allocation_tracking_disable(); #ifdef KOKKOS_IMPL_NEED_FUNCTOR_WRAPPER Impl::ParallelReduce closure(functor_adaptor::functor(functor), @@ -890,13 +891,13 @@ namespace Impl { policy, return_value_adapter::return_value(return_value,functor)); #endif - Kokkos::Impl::shared_allocation_tracking_release_and_enable(); + Kokkos::Impl::shared_allocation_tracking_enable(); closure.execute(); #if defined(KOKKOS_ENABLE_PROFILING) - if(Kokkos::Profiling::profileLibraryLoaded()) { - Kokkos::Profiling::endParallelReduce(kpID); - } + if(Kokkos::Profiling::profileLibraryLoaded()) { + Kokkos::Profiling::endParallelReduce(kpID); + } #endif } diff --git a/lib/kokkos/core/src/Kokkos_Serial.hpp b/lib/kokkos/core/src/Kokkos_Serial.hpp index 73e8ae3030..539761a1f9 100644 --- a/lib/kokkos/core/src/Kokkos_Serial.hpp +++ b/lib/kokkos/core/src/Kokkos_Serial.hpp @@ -66,6 +66,7 @@ #include +#include namespace Kokkos { @@ -526,6 +527,7 @@ public: } }; + /*--------------------------------------------------------------------------*/ template< class FunctorType , class ... Traits > @@ -604,6 +606,178 @@ public: {} }; +} // namespace Impl +} // namespace Kokkos + + +/*--------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------*/ +/* Parallel patterns for Kokkos::Serial with MDRangePolicy */ + +namespace Kokkos { +namespace Impl { + +template< class FunctorType , class ... Traits > +class ParallelFor< FunctorType , + Kokkos::Experimental::MDRangePolicy< Traits ... > , + Kokkos::Serial + > +{ +private: + + typedef Kokkos::Experimental::MDRangePolicy< Traits ... > MDRangePolicy ; + typedef typename MDRangePolicy::impl_range_policy Policy ; + + typedef typename Kokkos::Experimental::Impl::HostIterateTile< MDRangePolicy, FunctorType, typename MDRangePolicy::work_tag, void > iterate_type; + + 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 ) { + iterate_type( m_mdr_policy, m_functor )( i ); + } + } + +public: + + inline + void execute() const + { this->exec(); } + + 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) ) + {} +}; + + +template< class FunctorType , class ReducerType , class ... Traits > +class ParallelReduce< FunctorType + , Kokkos::Experimental::MDRangePolicy< Traits ... > + , ReducerType + , Kokkos::Serial + > +{ +private: + + typedef Kokkos::Experimental::MDRangePolicy< Traits ... > MDRangePolicy ; + typedef typename MDRangePolicy::impl_range_policy Policy ; + + typedef typename MDRangePolicy::work_tag WorkTag ; + + typedef Kokkos::Impl::if_c< std::is_same::value, FunctorType, ReducerType> ReducerConditional; + typedef typename ReducerConditional::type ReducerTypeFwd; + + typedef typename ReducerTypeFwd::value_type ValueType; + + typedef FunctorAnalysis< FunctorPatternInterface::REDUCE , Policy , FunctorType > Analysis ; + + typedef Kokkos::Impl::FunctorValueInit< ReducerTypeFwd , WorkTag > ValueInit ; + + typedef typename Analysis::pointer_type pointer_type ; + typedef typename Analysis::reference_type reference_type ; + + + using iterate_type = typename Kokkos::Experimental::Impl::HostIterateTile< MDRangePolicy + , FunctorType + , WorkTag + , ValueType + >; + + + 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 ) { + iterate_type( m_mdr_policy, m_functor, update )( i ); + } + } + +public: + + inline + void execute() const + { + const size_t pool_reduce_size = + Analysis::value_size( ReducerConditional::select(m_functor , m_reducer) ); + const size_t team_reduce_size = 0 ; // Never shrinks + const size_t team_shared_size = 0 ; // Never shrinks + const size_t thread_local_size = 0 ; // Never shrinks + + serial_resize_thread_team_data( pool_reduce_size + , team_reduce_size + , team_shared_size + , thread_local_size ); + + HostThreadTeamData & data = *serial_get_thread_team_data(); + + pointer_type ptr = + m_result_ptr ? m_result_ptr : pointer_type(data.pool_reduce_local()); + + reference_type update = + ValueInit::init( ReducerConditional::select(m_functor , m_reducer) , ptr ); + + this-> exec( update ); + + Kokkos::Impl::FunctorFinal< ReducerTypeFwd , WorkTag >:: + final( ReducerConditional::select(m_functor , m_reducer) , ptr ); + } + + template< class HostViewType > + ParallelReduce( const FunctorType & arg_functor , + const MDRangePolicy & arg_policy , + const HostViewType & arg_result_view , + typename std::enable_if< + Kokkos::is_view< HostViewType >::value && + !Kokkos::is_reducer_type::value + ,void*>::type = NULL) + : 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< HostViewType >::value + , "Kokkos::Serial reduce result must be a View" ); + + static_assert( std::is_same< typename HostViewType::memory_space , HostSpace >::value + , "Kokkos::Serial reduce result must be a View in HostSpace" ); + } + + inline + ParallelReduce( const FunctorType & arg_functor + , 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 + , Kokkos::HostSpace >::value + , "Reduction result on Kokkos::OpenMP must be a Kokkos::View in HostSpace" );*/ + } +}; + + + } // namespace Impl } // namespace Kokkos @@ -819,6 +993,60 @@ public: /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ +namespace Kokkos { namespace Experimental { + +template<> +class UniqueToken< Serial, UniqueTokenScope::Instance> +{ +public: + using execution_space = Serial; + using size_type = int; + + /// \brief create object size for concurrency on the given instance + /// + /// This object should not be shared between instances + UniqueToken( execution_space const& = execution_space() ) noexcept {} + + /// \brief upper bound for acquired values, i.e. 0 <= value < size() + inline + int size() const noexcept { return 1; } + + /// \brief acquire value such that 0 <= value < size() + inline + int acquire() const noexcept { return 0; } + + /// \brief release a value acquired by generate + inline + void release( int ) const noexcept {} +}; + +template<> +class UniqueToken< Serial, UniqueTokenScope::Global> +{ +public: + using execution_space = Serial; + using size_type = int; + + /// \brief create object size for concurrency on the given instance + /// + /// This object should not be shared between instances + UniqueToken( execution_space const& = execution_space() ) noexcept {} + + /// \brief upper bound for acquired values, i.e. 0 <= value < size() + inline + int size() const noexcept { return 1; } + + /// \brief acquire value such that 0 <= value < size() + inline + int acquire() const noexcept { return 0; } + + /// \brief release a value acquired by generate + inline + void release( int ) const noexcept {} +}; + +}} // namespace Kokkos::Experimental + #include #endif // defined( KOKKOS_ENABLE_SERIAL ) diff --git a/lib/kokkos/core/src/Kokkos_TaskScheduler.hpp b/lib/kokkos/core/src/Kokkos_TaskScheduler.hpp index 7edda7aa75..fcfc91a4ee 100644 --- a/lib/kokkos/core/src/Kokkos_TaskScheduler.hpp +++ b/lib/kokkos/core/src/Kokkos_TaskScheduler.hpp @@ -148,7 +148,7 @@ private: typename std::conditional< Arg2_is_space , Arg2 , void >::type >::type ; - using task_base = Impl::TaskBase< Space , ValueType , void > ; + using task_base = Impl::TaskBase< void , void , void > ; using queue_type = Impl::TaskQueue< Space > ; task_base * m_task ; @@ -293,13 +293,17 @@ public: //---------------------------------------- KOKKOS_INLINE_FUNCTION - typename task_base::get_return_type + int is_ready() const noexcept + { return ( 0 == m_task ) || ( ((task_base*) task_base::LockTag) == m_task->m_wait ); } + + KOKKOS_INLINE_FUNCTION + const typename Impl::TaskResult< ValueType >::reference_type get() const { if ( 0 == m_task ) { Kokkos::abort( "Kokkos:::Future::get ERROR: is_null()"); } - return m_task->get(); + return Impl::TaskResult< ValueType >::get( m_task ); } }; @@ -396,7 +400,7 @@ private: using track_type = Kokkos::Impl::SharedAllocationTracker ; using queue_type = Kokkos::Impl::TaskQueue< ExecSpace > ; - using task_base = Impl::TaskBase< ExecSpace , void , void > ; + using task_base = Impl::TaskBase< void , void , void > ; track_type m_track ; queue_type * m_queue ; @@ -464,29 +468,19 @@ public: KOKKOS_INLINE_FUNCTION memory_pool * memory() const noexcept - { return m_queue ? m_queue->m_memory : (memory_pool*) 0 ; } + { return m_queue ? &( m_queue->m_memory ) : (memory_pool*) 0 ; } //---------------------------------------- /**\brief Allocation size for a spawned task */ template< typename FunctorType > KOKKOS_FUNCTION size_t spawn_allocation_size() const - { - using task_type = Impl::TaskBase< execution_space - , typename FunctorType::value_type - , FunctorType > ; - - return m_queue->allocate_block_size( sizeof(task_type) ); - } + { return m_queue->template spawn_allocation_size< FunctorType >(); } /**\brief Allocation size for a when_all aggregate */ KOKKOS_FUNCTION size_t when_all_allocation_size( int narg ) const - { - using task_base = Kokkos::Impl::TaskBase< ExecSpace , void , void > ; - - return m_queue->allocate_block_size( sizeof(task_base) + narg * sizeof(task_base*) ); - } + { return m_queue->when_all_allocation_size( narg ); } //---------------------------------------- @@ -507,7 +501,7 @@ public: queue_type * const queue = arg_policy.m_scheduler ? arg_policy.m_scheduler->m_queue : ( arg_policy.m_dependence.m_task - ? arg_policy.m_dependence.m_task->m_queue + ? static_cast(arg_policy.m_dependence.m_task->m_queue) : (queue_type*) 0 ); if ( 0 == queue ) { @@ -530,8 +524,12 @@ public: future_type f ; // Allocate task from memory pool + + const size_t alloc_size = + queue->template spawn_allocation_size< FunctorType >(); + f.m_task = - reinterpret_cast< task_type * >(queue->allocate(sizeof(task_type))); + reinterpret_cast< task_type * >(queue->allocate(alloc_size) ); if ( f.m_task ) { @@ -539,15 +537,17 @@ public: // Reference count starts at two: // +1 for the matching decrement when task is complete // +1 for the future - new ( f.m_task ) - task_type( arg_function - , queue - , arg_policy.m_dependence.m_task /* dependence */ - , 2 /* reference count */ - , int(sizeof(task_type)) /* allocation size */ - , int(arg_policy.m_task_type) - , int(arg_policy.m_priority) - , std::move(arg_functor) ); + new ( f.m_task ) task_type( std::move(arg_functor) ); + + f.m_task->m_apply = arg_function ; + f.m_task->m_queue = queue ; + f.m_task->m_next = arg_policy.m_dependence.m_task ; + f.m_task->m_ref_count = 2 ; + f.m_task->m_alloc_size = alloc_size ; + f.m_task->m_task_type = arg_policy.m_task_type ; + f.m_task->m_priority = arg_policy.m_priority ; + + Kokkos::memory_fence(); // The dependence (if any) is processed immediately // within the schedule function, as such the dependence's @@ -586,6 +586,30 @@ public: // Postcondition: task is in Executing-Respawn state } + template< typename FunctorType > + KOKKOS_FUNCTION static + void + respawn( FunctorType * arg_self + , TaskScheduler const & + , TaskPriority const & arg_priority + ) + { + // Precondition: task is in Executing state + + using value_type = typename FunctorType::value_type ; + using task_type = Impl::TaskBase< execution_space + , value_type + , FunctorType > ; + + task_type * const task = static_cast< task_type * >( arg_self ); + + task->m_priority = static_cast(arg_priority); + + task->add_dependence( (task_base*) 0 ); + + // Postcondition: task is in Executing-Respawn state + } + //---------------------------------------- /**\brief Return a future that is complete * when all input futures are complete. @@ -596,7 +620,7 @@ public: when_all( Future< A1 , A2 > const arg[] , int narg ) { using future_type = Future< execution_space > ; - using task_base = Kokkos::Impl::TaskBase< execution_space , void , void > ; + using task_base = Kokkos::Impl::TaskBase< void , void , void > ; future_type f ; @@ -610,9 +634,9 @@ public: // Increment reference count to track subsequent assignment. Kokkos::atomic_increment( &(t->m_ref_count) ); if ( queue == 0 ) { - queue = t->m_queue ; + queue = static_cast< queue_type * >( t->m_queue ); } - else if ( queue != t->m_queue ) { + else if ( queue != static_cast< queue_type * >( t->m_queue ) ) { Kokkos::abort("Kokkos when_all Futures must be in the same scheduler" ); } } @@ -620,28 +644,34 @@ public: if ( queue != 0 ) { - size_t const size = sizeof(task_base) + narg * sizeof(task_base*); + size_t const alloc_size = queue->when_all_allocation_size( narg ); f.m_task = - reinterpret_cast< task_base * >( queue->allocate( size ) ); + reinterpret_cast< task_base * >( queue->allocate( alloc_size ) ); if ( f.m_task ) { // Reference count starts at two: // +1 to match decrement when task completes // +1 for the future - new( f.m_task ) task_base( queue - , 2 /* reference count */ - , size /* allocation size */ - , narg /* dependence count */ - ); + + new( f.m_task ) task_base(); + + f.m_task->m_queue = queue ; + f.m_task->m_ref_count = 2 ; + f.m_task->m_alloc_size = alloc_size ; + f.m_task->m_dep_count = narg ; + f.m_task->m_task_type = task_base::Aggregate ; // Assign dependences, reference counts were already incremented - task_base ** const dep = f.m_task->aggregate_dependences(); + task_base * volatile * const dep = + f.m_task->aggregate_dependences(); for ( int i = 0 ; i < narg ; ++i ) { dep[i] = arg[i].m_task ; } + Kokkos::memory_fence(); + queue->schedule_aggregate( f.m_task ); // this when_all may be processed at any moment } diff --git a/lib/kokkos/core/src/Kokkos_UniqueToken.hpp b/lib/kokkos/core/src/Kokkos_UniqueToken.hpp new file mode 100644 index 0000000000..1ffb07a6db --- /dev/null +++ b/lib/kokkos/core/src/Kokkos_UniqueToken.hpp @@ -0,0 +1,88 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#ifndef KOKKOS_UNIQUE_TOKEN_HPP +#define KOKKOS_UNIQUE_TOKEN_HPP + +#include + +namespace Kokkos { namespace Experimental { + +enum class UniqueTokenScope : int +{ + Instance, + Global +}; + +/// \brief class to generate unique ids base on the required amount of concurrency +/// +/// This object should behave like a ref-counted object, so that when the last +/// instance is destroy resources are free if needed +template +class UniqueToken +{ +public: + using execution_space = ExecutionSpace; + using size_type = typename execution_space::size_type; + + /// \brief create object size for concurrency on the given instance + /// + /// This object should not be shared between instances + UniqueToken( execution_space const& = execution_space() ); + + /// \brief upper bound for acquired values, i.e. 0 <= value < size() + KOKKOS_INLINE_FUNCTION + size_type size() const ; + + /// \brief acquire value such that 0 <= value < size() + KOKKOS_INLINE_FUNCTION + size_type acquire() const ; + + /// \brief release a value acquired by generate + KOKKOS_INLINE_FUNCTION + void release( size_type ) const ; +}; + +}} // namespace Kokkos::Experimental + +#endif //KOKKOS_UNIQUE_TOKEN_HPP diff --git a/lib/kokkos/core/src/Kokkos_View.hpp b/lib/kokkos/core/src/Kokkos_View.hpp index 3312aa6a96..1754e4a8fb 100644 --- a/lib/kokkos/core/src/Kokkos_View.hpp +++ b/lib/kokkos/core/src/Kokkos_View.hpp @@ -1,13 +1,13 @@ /* //@HEADER // ************************************************************************ -// +// // Kokkos v. 2.0 // Copyright (2014) Sandia Corporation -// +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: @@ -36,7 +36,7 @@ // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) -// +// // ************************************************************************ //@HEADER */ @@ -54,11 +54,14 @@ #include #include +#if defined(KOKKOS_ENABLE_PROFILING) +#include +#endif + //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- namespace Kokkos { -namespace Experimental { namespace Impl { template< class DataType > @@ -73,16 +76,6 @@ struct ViewDataAnalysis ; template< class , class ... > class ViewMapping { public: enum { is_assignable = false }; }; -} /* namespace Impl */ -} /* namespace Experimental */ -} /* namespace Kokkos */ - -namespace Kokkos { -namespace Impl { - -using Kokkos::Experimental::Impl::ViewMapping ; -using Kokkos::Experimental::Impl::ViewDataAnalysis ; - } /* namespace Impl */ } /* namespace Kokkos */ @@ -1563,12 +1556,12 @@ namespace Kokkos { namespace Impl { inline -void shared_allocation_tracking_claim_and_disable() -{ Kokkos::Impl::SharedAllocationRecord::tracking_claim_and_disable(); } +void shared_allocation_tracking_disable() +{ Kokkos::Impl::SharedAllocationRecord::tracking_disable(); } inline -void shared_allocation_tracking_release_and_enable() -{ Kokkos::Impl::SharedAllocationRecord::tracking_release_and_enable(); } +void shared_allocation_tracking_enable() +{ Kokkos::Impl::SharedAllocationRecord::tracking_enable(); } } /* namespace Impl */ } /* namespace Kokkos */ @@ -1795,6 +1788,20 @@ void deep_copy if ( (void *) dst.data() != (void*) src.data() ) { +#if defined(KOKKOS_ENABLE_PROFILING) + if (Kokkos::Profiling::profileLibraryLoaded()) { + const size_t nbytes = sizeof(typename dst_type::value_type) * dst.span(); + Kokkos::Profiling::beginDeepCopy( + Kokkos::Profiling::SpaceHandle(dst_memory_space::name()), + dst.label(), + dst.data(), + Kokkos::Profiling::SpaceHandle(src_memory_space::name()), + src.label(), + src.data(), + nbytes); + } +#endif + // Concern: If overlapping views then a parallel copy will be erroneous. // ... @@ -1882,7 +1889,14 @@ void deep_copy else { Kokkos::Impl::throw_runtime_exception("deep_copy given views that would require a temporary allocation"); } - } + +#if defined(KOKKOS_ENABLE_PROFILING) + if (Kokkos::Profiling::profileLibraryLoaded()) { + Kokkos::Profiling::endDeepCopy(); + } +#endif + + } // ( (void *) dst.data() != (void*) src.data() ) } } /* namespace Kokkos */ @@ -2249,6 +2263,82 @@ resize( Kokkos::View & v , static_assert( Kokkos::ViewTraits::is_managed , "Can only resize managed views" ); + // Fix #904 by checking dimensions before actually resizing. + // + // Rank is known at compile time, so hopefully the compiler will + // remove branches that are compile-time false. The upcoming "if + // constexpr" language feature would make this certain. + if (view_type::Rank == 1 && + n0 == static_cast (v.extent(0))) { + return; + } + if (view_type::Rank == 2 && + n0 == static_cast (v.extent(0)) && + n1 == static_cast (v.extent(1))) { + return; + } + if (view_type::Rank == 3 && + n0 == static_cast (v.extent(0)) && + n1 == static_cast (v.extent(1)) && + n2 == static_cast (v.extent(2))) { + return; + } + if (view_type::Rank == 4 && + n0 == static_cast (v.extent(0)) && + n1 == static_cast (v.extent(1)) && + n2 == static_cast (v.extent(2)) && + n3 == static_cast (v.extent(3))) { + return; + } + if (view_type::Rank == 5 && + n0 == static_cast (v.extent(0)) && + n1 == static_cast (v.extent(1)) && + n2 == static_cast (v.extent(2)) && + n3 == static_cast (v.extent(3)) && + n4 == static_cast (v.extent(4))) { + return; + } + if (view_type::Rank == 6 && + n0 == static_cast (v.extent(0)) && + n1 == static_cast (v.extent(1)) && + n2 == static_cast (v.extent(2)) && + n3 == static_cast (v.extent(3)) && + n4 == static_cast (v.extent(4)) && + n5 == static_cast (v.extent(5))) { + return; + } + if (view_type::Rank == 7 && + n0 == static_cast (v.extent(0)) && + n1 == static_cast (v.extent(1)) && + n2 == static_cast (v.extent(2)) && + n3 == static_cast (v.extent(3)) && + n4 == static_cast (v.extent(4)) && + n5 == static_cast (v.extent(5)) && + n6 == static_cast (v.extent(6))) { + return; + } + if (view_type::Rank == 8 && + n0 == static_cast (v.extent(0)) && + n1 == static_cast (v.extent(1)) && + n2 == static_cast (v.extent(2)) && + n3 == static_cast (v.extent(3)) && + n4 == static_cast (v.extent(4)) && + n5 == static_cast (v.extent(5)) && + n6 == static_cast (v.extent(6)) && + n7 == static_cast (v.extent(7))) { + return; + } + // If Kokkos ever supports Views of rank > 8, the above code won't + // be incorrect, because avoiding reallocation in resize() is just + // an optimization. + + // TODO (mfh 27 Jun 2017) If the old View has enough space but just + // different dimensions (e.g., if the product of the dimensions, + // including extra space for alignment, will not change), then + // consider just reusing storage. For now, Kokkos always + // reallocates if any of the dimensions change, even if the old View + // has enough space. + view_type v_resized( v.label(), n0, n1, n2, n3, n4, n5, n6, n7 ); Kokkos::Impl::ViewRemap< view_type , view_type >( v_resized , v ); @@ -2317,6 +2407,106 @@ void realloc( Kokkos::View & v , } } /* namespace Kokkos */ +//---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- + +namespace Kokkos { namespace Impl { + +template < class Specialize, typename A, typename B > +struct CommonViewValueType; + +template < typename A, typename B > +struct CommonViewValueType< void, A, B > +{ + using value_type = typename std::common_type< A , B >::type; +}; + + +template < class Specialize, class ValueType > +struct CommonViewAllocProp; + +template < class ValueType > +struct CommonViewAllocProp< void, ValueType > +{ + using value_type = ValueType; + + template < class ... Views > + CommonViewAllocProp( const Views & ... ) {} +}; + + +template < class ... Views > +struct DeduceCommonViewAllocProp; + +// Base case must provide types for: +// 1. specialize 2. value_type 3. is_view 4. prop_type +template < class FirstView > +struct DeduceCommonViewAllocProp< FirstView > +{ + using specialize = typename FirstView::traits::specialize; + + using value_type = typename FirstView::traits::value_type; + + enum : bool { is_view = is_view< FirstView >::value }; + + using prop_type = CommonViewAllocProp< specialize, value_type >; +}; + + +template < class FirstView, class ... NextViews > +struct DeduceCommonViewAllocProp< FirstView, NextViews... > +{ + using NextTraits = DeduceCommonViewAllocProp< NextViews... >; + + using first_specialize = typename FirstView::traits::specialize; + using first_value_type = typename FirstView::traits::value_type; + + enum : bool { first_is_view = is_view< FirstView >::value }; + + using next_specialize = typename NextTraits::specialize; + using next_value_type = typename NextTraits::value_type; + + enum : bool { next_is_view = NextTraits::is_view }; + + // common types + + // determine specialize type + // if first and next specialize differ, but are not the same specialize, error out + static_assert( !(!std::is_same< first_specialize, next_specialize >::value && !std::is_same< first_specialize, void>::value && !std::is_same< void, next_specialize >::value) , "Kokkos DeduceCommonViewAllocProp ERROR: Only one non-void specialize trait allowed" ); + + // otherwise choose non-void specialize if either/both are non-void + using specialize = typename std::conditional< std::is_same< first_specialize, next_specialize >::value + , first_specialize + , typename std::conditional< ( std::is_same< first_specialize, void >::value + && !std::is_same< next_specialize, void >::value) + , next_specialize + , first_specialize + >::type + >::type; + + using value_type = typename CommonViewValueType< specialize, first_value_type, next_value_type >::value_type; + + enum : bool { is_view = (first_is_view && next_is_view) }; + + using prop_type = CommonViewAllocProp< specialize, value_type >; +}; + +} // end namespace Impl + +template < class ... Views > +using DeducedCommonPropsType = typename Impl::DeduceCommonViewAllocProp::prop_type ; + +// User function +template < class ... Views > +DeducedCommonPropsType +common_view_alloc_prop( Views const & ... views ) +{ + return DeducedCommonPropsType( views... ); +} + +} // namespace Kokkos + + //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- // For backward compatibility: @@ -2350,6 +2540,9 @@ using Kokkos::Impl::WithoutInitializing_t ; using Kokkos::Impl::AllowPadding_t ; using Kokkos::Impl::SharedAllocationRecord ; using Kokkos::Impl::SharedAllocationTracker ; +using Kokkos::Impl::ViewMapping ; +using Kokkos::Impl::ViewDataAnalysis ; + } /* namespace Impl */ } /* namespace Experimental */ diff --git a/lib/kokkos/core/src/Kokkos_WorkGraphPolicy.hpp b/lib/kokkos/core/src/Kokkos_WorkGraphPolicy.hpp new file mode 100644 index 0000000000..58b0f72f51 --- /dev/null +++ b/lib/kokkos/core/src/Kokkos_WorkGraphPolicy.hpp @@ -0,0 +1,265 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#ifndef KOKKOS_WORKGRAPHPOLICY_HPP +#define KOKKOS_WORKGRAPHPOLICY_HPP + +namespace Kokkos { +namespace Impl { +namespace Experimental { + +template< class functor_type , class execution_space, class ... policy_args > +class WorkGraphExec; + +}}} // namespace Kokkos::Impl::Experimental + +namespace Kokkos { +namespace Experimental { + +template< class ... Properties > +class WorkGraphPolicy +{ +public: + + using self_type = WorkGraphPolicy; + using traits = Kokkos::Impl::PolicyTraits; + using index_type = typename traits::index_type; + using execution_space = typename traits::execution_space; + using work_tag = typename traits::work_tag; + using memory_space = typename execution_space::memory_space; + using graph_type = Kokkos::Experimental::Crs; + using member_type = index_type; + +private: + + graph_type m_graph; + + using ints_type = Kokkos::View; + using range_type = Kokkos::pair; + using ranges_type = Kokkos::View; + const std::int32_t m_total_work; + ints_type m_counts; + ints_type m_queue; + ranges_type m_ranges; + +public: + + struct TagZeroRanges {}; + KOKKOS_INLINE_FUNCTION + void operator()(TagZeroRanges, std::int32_t i) const { + m_ranges[i] = range_type(0, 0); + } + void zero_ranges() { + using policy_type = RangePolicy; + using closure_type = Kokkos::Impl::ParallelFor; + const closure_type closure(*this, policy_type(0, 1)); + closure.execute(); + execution_space::fence(); + } + + struct TagFillQueue {}; + KOKKOS_INLINE_FUNCTION + void operator()(TagFillQueue, std::int32_t i) const { + if (*((volatile std::int32_t*)(&m_counts(i))) == 0) push_work(i); + } + void fill_queue() { + using policy_type = RangePolicy; + using closure_type = Kokkos::Impl::ParallelFor; + const closure_type closure(*this, policy_type(0, m_total_work)); + closure.execute(); + execution_space::fence(); + } + +private: + + inline + void setup() { + if (m_graph.numRows() > std::numeric_limits::max()) { + Kokkos::abort("WorkGraphPolicy work must be indexable using int32_t"); + } + get_crs_transpose_counts(m_counts, m_graph); + m_queue = ints_type(ViewAllocateWithoutInitializing("queue"), m_total_work); + deep_copy(m_queue, std::int32_t(-1)); + m_ranges = ranges_type("ranges", 1); + fill_queue(); + } + + KOKKOS_INLINE_FUNCTION + std::int32_t pop_work() const { + range_type w(-1,-1); + while (true) { + const range_type w_new( w.first + 1 , w.second ); + w = atomic_compare_exchange( &m_ranges(0) , w , w_new ); + if ( w.first < w.second ) { // there was work in the queue + if ( w_new.first == w.first + 1 && w_new.second == w.second ) { + // we got a work item + std::int32_t i; + // the push_work function may have incremented the end counter + // but not yet written the work index into the queue. + // wait until the entry is valid. + while ( -1 == ( i = *((volatile std::int32_t*)(&m_queue( w.first ))) ) ); + return i; + } // we got a work item + } else { // there was no work in the queue +#ifdef KOKKOS_DEBUG + if ( w_new.first == w.first + 1 && w_new.second == w.second ) { + Kokkos::abort("bug in pop_work"); + } +#endif + if (w.first == m_total_work) { // all work is done + return -1; + } else { // need to wait for more work to be pushed + // take a guess that one work item will be pushed + // the key thing is we can't leave (w) alone, because + // otherwise the next compare_exchange may succeed in + // popping work from an empty queue + w.second++; + } + } // there was no work in the queue + } // while (true) + } + + KOKKOS_INLINE_FUNCTION + void push_work(std::int32_t i) const { + range_type w(-1,-1); + while (true) { + const range_type w_new( w.first , w.second + 1 ); + // try to increment the end counter + w = atomic_compare_exchange( &m_ranges(0) , w , w_new ); + // stop trying if the increment was successful + if ( w.first == w_new.first && w.second + 1 == w_new.second ) break; + } + // write the work index into the claimed spot in the queue + *((volatile std::int32_t*)(&m_queue( w.second ))) = i; + // push this write out into the memory system + memory_fence(); + } + + template< class functor_type , class execution_space, class ... policy_args > + friend class Kokkos::Impl::Experimental::WorkGraphExec; + +public: + + WorkGraphPolicy(graph_type arg_graph) + : m_graph(arg_graph) + , m_total_work( arg_graph.numRows() ) + { + setup(); + } + +}; + +}} // namespace Kokkos::Experimental + +/*--------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------*/ + +namespace Kokkos { +namespace Impl { +namespace Experimental { + +template< class functor_type , class execution_space, class ... policy_args > +class WorkGraphExec +{ + public: + + using self_type = WorkGraphExec< functor_type, execution_space, policy_args ... >; + using policy_type = Kokkos::Experimental::WorkGraphPolicy< policy_args ... >; + using member_type = typename policy_type::member_type; + using memory_space = typename execution_space::memory_space; + + protected: + + const functor_type m_functor; + const policy_type m_policy; + + protected: + + KOKKOS_INLINE_FUNCTION + std::int32_t before_work() const { + return m_policy.pop_work(); + } + + KOKKOS_INLINE_FUNCTION + void after_work(std::int32_t i) const { + /* fence any writes that were done by the work item itself + (usually writing its result to global memory) */ + memory_fence(); + const std::int32_t begin = m_policy.m_graph.row_map( i ); + const std::int32_t end = m_policy.m_graph.row_map( i + 1 ); + for (std::int32_t j = begin; j < end; ++j) { + const std::int32_t next = m_policy.m_graph.entries( j ); + const std::int32_t old_count = atomic_fetch_add( &(m_policy.m_counts(next)), -1 ); + if ( old_count == 1 ) m_policy.push_work( next ); + } + } + + inline + WorkGraphExec( const functor_type & arg_functor + , const policy_type & arg_policy ) + : m_functor( arg_functor ) + , m_policy( arg_policy ) + { + } +}; + +}}} // namespace Kokkos::Impl::Experimental + +#ifdef KOKKOS_ENABLE_SERIAL +#include "impl/Kokkos_Serial_WorkGraphPolicy.hpp" +#endif + +#ifdef KOKKOS_ENABLE_OPENMP +#include "OpenMP/Kokkos_OpenMP_WorkGraphPolicy.hpp" +#endif + +#ifdef KOKKOS_ENABLE_CUDA +#include "Cuda/Kokkos_Cuda_WorkGraphPolicy.hpp" +#endif + +#ifdef KOKKOS_ENABLE_THREADS +#include "Threads/Kokkos_Threads_WorkGraphPolicy.hpp" +#endif + +#endif /* #define KOKKOS_WORKGRAPHPOLICY_HPP */ diff --git a/lib/kokkos/core/src/OpenMP/Kokkos_OpenMP_Exec.cpp b/lib/kokkos/core/src/OpenMP/Kokkos_OpenMP_Exec.cpp index 4e0ea93920..915fbe52c1 100644 --- a/lib/kokkos/core/src/OpenMP/Kokkos_OpenMP_Exec.cpp +++ b/lib/kokkos/core/src/OpenMP/Kokkos_OpenMP_Exec.cpp @@ -45,75 +45,100 @@ #if defined( KOKKOS_ENABLE_OPENMP ) #include +#include + #include #include #include + #include + #include -#include #include #include namespace Kokkos { namespace Impl { -namespace { -KOKKOS_INLINE_FUNCTION -int kokkos_omp_in_parallel(); +int g_openmp_hardware_max_threads = 1; -int kokkos_omp_in_critical_region = ( Kokkos::HostSpace::register_in_parallel( kokkos_omp_in_parallel ) , 0 ); +__thread int t_openmp_hardware_id = 0; +__thread Impl::OpenMPExec * t_openmp_instance = nullptr; -KOKKOS_INLINE_FUNCTION -int kokkos_omp_in_parallel() +void OpenMPExec::validate_partition( const int nthreads + , int & num_partitions + , int & partition_size + ) { -#ifndef __CUDA_ARCH__ - return omp_in_parallel() && ! kokkos_omp_in_critical_region ; -#else - return 0; -#endif + if (nthreads == 1) { + num_partitions = 1; + partition_size = 1; + } + else if( num_partitions < 1 && partition_size < 1) { + int idle = nthreads; + for (int np = 2; np <= nthreads ; ++np) { + for (int ps = 1; ps <= nthreads/np; ++ps) { + if (nthreads - np*ps < idle) { + idle = nthreads - np*ps; + num_partitions = np; + partition_size = ps; + } + if (idle == 0) { + break; + } + } + } + } + else if( num_partitions < 1 && partition_size > 0 ) { + if ( partition_size <= nthreads ) { + num_partitions = nthreads / partition_size; + } + else { + num_partitions = 1; + partition_size = nthreads; + } + } + else if( num_partitions > 0 && partition_size < 1 ) { + if ( num_partitions <= nthreads ) { + partition_size = nthreads / num_partitions; + } + else { + num_partitions = nthreads; + partition_size = 1; + } + } + else if ( num_partitions * partition_size > nthreads ) { + int idle = nthreads; + const int NP = num_partitions; + const int PS = partition_size; + for (int np = NP; np > 0; --np) { + for (int ps = PS; ps > 0; --ps) { + if ( (np*ps <= nthreads) + && (nthreads - np*ps < idle) ) { + idle = nthreads - np*ps; + num_partitions = np; + partition_size = ps; + } + if (idle == 0) { + break; + } + } + } + } + } -bool s_using_hwloc = false; - -} // namespace -} // namespace Impl -} // namespace Kokkos - - -namespace Kokkos { -namespace Impl { - -int OpenMPExec::m_map_rank[ OpenMPExec::MAX_THREAD_COUNT ] = { 0 }; - -int OpenMPExec::m_pool_topo[ 4 ] = { 0 }; - -HostThreadTeamData * OpenMPExec::m_pool[ OpenMPExec::MAX_THREAD_COUNT ] = { 0 }; - -void OpenMPExec::verify_is_process( const char * const label ) +void OpenMPExec::verify_is_master( const char * const label ) { - if ( omp_in_parallel() ) { + if ( !t_openmp_instance ) + { std::string msg( label ); - msg.append( " ERROR: in parallel" ); + msg.append( " ERROR: in parallel or not initialized" ); Kokkos::Impl::throw_runtime_exception( msg ); } } -void OpenMPExec::verify_initialized( const char * const label ) -{ - if ( 0 == m_pool[0] ) { - std::string msg( label ); - msg.append( " ERROR: not initialized" ); - Kokkos::Impl::throw_runtime_exception( msg ); - } - - if ( omp_get_max_threads() != Kokkos::OpenMP::thread_pool_size(0) ) { - std::string msg( label ); - msg.append( " ERROR: Initialized but threads modified inappropriately" ); - Kokkos::Impl::throw_runtime_exception( msg ); - } - -} } // namespace Impl } // namespace Kokkos @@ -133,11 +158,11 @@ void OpenMPExec::clear_thread_data() const int old_alloc_bytes = m_pool[0] ? ( member_bytes + m_pool[0]->scratch_bytes() ) : 0 ; - Kokkos::HostSpace space ; + OpenMP::memory_space space ; -#pragma omp parallel + #pragma omp parallel num_threads( m_pool_size ) { - const int rank = m_map_rank[ omp_get_thread_num() ]; + const int rank = omp_get_thread_num(); if ( 0 != m_pool[rank] ) { @@ -189,13 +214,13 @@ void OpenMPExec::resize_thread_data( size_t pool_reduce_bytes , team_shared_bytes , thread_local_bytes ); - const int pool_size = omp_get_max_threads(); + OpenMP::memory_space space ; - Kokkos::HostSpace space ; + memory_fence(); -#pragma omp parallel + #pragma omp parallel num_threads(m_pool_size) { - const int rank = m_map_rank[ omp_get_thread_num() ]; + const int rank = omp_get_thread_num(); if ( 0 != m_pool[rank] ) { @@ -214,11 +239,14 @@ void OpenMPExec::resize_thread_data( size_t pool_reduce_bytes , pool_reduce_bytes , team_reduce_bytes , team_shared_bytes - , thread_local_bytes ); + , thread_local_bytes + ); + + memory_fence(); } /* END #pragma omp parallel */ - HostThreadTeamData::organize_pool( m_pool , pool_size ); + HostThreadTeamData::organize_pool( m_pool , m_pool_size ); } } @@ -232,16 +260,8 @@ namespace Kokkos { //---------------------------------------------------------------------------- -int OpenMP::is_initialized() -{ return 0 != Impl::OpenMPExec::m_pool[0]; } - -void OpenMP::initialize( unsigned thread_count , - unsigned use_numa_count , - unsigned use_cores_per_numa ) +int OpenMP::get_current_max_threads() noexcept { - // Before any other call to OMP query the maximum number of threads - // and save the value for re-initialization unit testing. - // Using omp_get_max_threads(); is problematic in conjunction with // Hwloc on Intel (essentially an initial call to the OpenMP runtime // without a parallel region before will set a process mask for a single core @@ -250,110 +270,99 @@ void OpenMP::initialize( unsigned thread_count , // the thread masks. The intend seems to be to make serial code run fast, if you // compile with OpenMP enabled but don't actually use parallel regions or so // static int omp_max_threads = omp_get_max_threads(); - int nthreads = 0; + + int count = 0; #pragma omp parallel { #pragma omp atomic - nthreads++; + ++count; } + return count; +} - static int omp_max_threads = nthreads; - - const bool is_initialized = 0 != Impl::OpenMPExec::m_pool[0] ; - - bool thread_spawn_failed = false ; - - if ( ! is_initialized ) { - - // Use hwloc thread pinning if concerned with locality. - // If spreading threads across multiple NUMA regions. - // If hyperthreading is enabled. - Impl::s_using_hwloc = hwloc::available() && ( - ( 1 < Kokkos::hwloc::get_available_numa_count() ) || - ( 1 < Kokkos::hwloc::get_available_threads_per_core() ) ); - - std::pair threads_coord[ Impl::OpenMPExec::MAX_THREAD_COUNT ]; - - // If hwloc available then use it's maximum value. - - if ( thread_count == 0 ) { - thread_count = Impl::s_using_hwloc - ? Kokkos::hwloc::get_available_numa_count() * - Kokkos::hwloc::get_available_cores_per_numa() * - Kokkos::hwloc::get_available_threads_per_core() - : omp_max_threads ; - } - - if(Impl::s_using_hwloc) - hwloc::thread_mapping( "Kokkos::OpenMP::initialize" , - false /* do not allow asynchronous */ , - thread_count , - use_numa_count , - use_cores_per_numa , - threads_coord ); - - // Spawn threads: - - omp_set_num_threads( thread_count ); - - // Verify OMP interaction: - if ( int(thread_count) != omp_get_max_threads() ) { - thread_spawn_failed = true ; - } - - // Verify spawning and bind threads: -#pragma omp parallel - { -#pragma omp critical - { - if ( int(thread_count) != omp_get_num_threads() ) { - thread_spawn_failed = true ; - } - - // Call to 'bind_this_thread' is not thread safe so place this whole block in a critical region. - // Call to 'new' may not be thread safe as well. - - const unsigned omp_rank = omp_get_thread_num(); - const unsigned thread_r = Impl::s_using_hwloc && Kokkos::hwloc::can_bind_threads() - ? Kokkos::hwloc::bind_this_thread( thread_count , threads_coord ) - : omp_rank ; - - Impl::OpenMPExec::m_map_rank[ omp_rank ] = thread_r ; - } -/* END #pragma omp critical */ - } -/* END #pragma omp parallel */ - - if ( ! thread_spawn_failed ) { - Impl::OpenMPExec::m_pool_topo[0] = thread_count ; - Impl::OpenMPExec::m_pool_topo[1] = Impl::s_using_hwloc ? thread_count / use_numa_count : thread_count; - Impl::OpenMPExec::m_pool_topo[2] = Impl::s_using_hwloc ? thread_count / ( use_numa_count * use_cores_per_numa ) : 1; - - // New, unified host thread team data: - { - size_t pool_reduce_bytes = 32 * thread_count ; - size_t team_reduce_bytes = 32 * thread_count ; - size_t team_shared_bytes = 1024 * thread_count ; - size_t thread_local_bytes = 1024 ; - - Impl::OpenMPExec::resize_thread_data( pool_reduce_bytes - , team_reduce_bytes - , team_shared_bytes - , thread_local_bytes - ); - } - } - } - - if ( is_initialized || thread_spawn_failed ) { - std::string msg("Kokkos::OpenMP::initialize ERROR"); - - if ( is_initialized ) { msg.append(" : already initialized"); } - if ( thread_spawn_failed ) { msg.append(" : failed spawning threads"); } +void OpenMP::initialize( int thread_count ) +{ + if ( omp_in_parallel() ) { + std::string msg("Kokkos::OpenMP::initialize ERROR : in parallel"); Kokkos::Impl::throw_runtime_exception(msg); } + if ( Impl::t_openmp_instance ) + { + finalize(); + } + + { + if (nullptr == std::getenv("OMP_PROC_BIND") ) { + printf("Kokkos::OpenMP::initialize WARNING: OMP_PROC_BIND environment variable not set\n"); + printf(" In general, for best performance with OpenMP 4.0 or better set OMP_PROC_BIND=spread and OMP_PLACES=threads\n"); + printf(" For best performance with OpenMP 3.1 set OMP_PROC_BIND=true\n"); + printf(" For unit testing set OMP_PROC_BIND=false\n"); + } + + OpenMP::memory_space space ; + + // Before any other call to OMP query the maximum number of threads + // and save the value for re-initialization unit testing. + + Impl::g_openmp_hardware_max_threads = get_current_max_threads(); + + int process_num_threads = Impl::g_openmp_hardware_max_threads; + + if ( Kokkos::hwloc::available() ) { + process_num_threads = Kokkos::hwloc::get_available_numa_count() + * Kokkos::hwloc::get_available_cores_per_numa() + * Kokkos::hwloc::get_available_threads_per_core(); + } + + // if thread_count < 0, use g_openmp_hardware_max_threads; + // if thread_count == 0, set g_openmp_hardware_max_threads to process_num_threads + // if thread_count > 0, set g_openmp_hardware_max_threads to thread_count + if (thread_count < 0 ) { + thread_count = Impl::g_openmp_hardware_max_threads; + } + else if( thread_count == 0 && Impl::g_openmp_hardware_max_threads != process_num_threads ) { + Impl::g_openmp_hardware_max_threads = process_num_threads; + omp_set_num_threads(Impl::g_openmp_hardware_max_threads); + } + else { + if( thread_count > process_num_threads ) { + printf( "Kokkos::OpenMP::initialize WARNING: You are likely oversubscribing your CPU cores.\n"); + printf( " process threads available : %3d, requested thread : %3d\n", process_num_threads, thread_count ); + } + Impl::g_openmp_hardware_max_threads = thread_count; + omp_set_num_threads(Impl::g_openmp_hardware_max_threads); + } + + // setup thread local + #pragma omp parallel num_threads(Impl::g_openmp_hardware_max_threads) + { + Impl::t_openmp_instance = nullptr; + Impl::t_openmp_hardware_id = omp_get_thread_num(); + Impl::SharedAllocationRecord< void, void >::tracking_enable(); + } + + void * const ptr = space.allocate( sizeof(Impl::OpenMPExec) ); + + Impl::t_openmp_instance = new (ptr) Impl::OpenMPExec( Impl::g_openmp_hardware_max_threads ); + + // New, unified host thread team data: + { + size_t pool_reduce_bytes = 32 * thread_count ; + size_t team_reduce_bytes = 32 * thread_count ; + size_t team_shared_bytes = 1024 * thread_count ; + size_t thread_local_bytes = 1024 ; + + Impl::t_openmp_instance->resize_thread_data( pool_reduce_bytes + , team_reduce_bytes + , team_shared_bytes + , thread_local_bytes + ); + } + } + + // Check for over-subscription //if( Impl::mpi_ranks_per_node() * long(thread_count) > Impl::processors_per_node() ) { // std::cout << "Kokkos::OpenMP::initialize WARNING: You are likely oversubscribing your CPU cores." << std::endl; @@ -373,20 +382,38 @@ void OpenMP::initialize( unsigned thread_count , void OpenMP::finalize() { - Impl::OpenMPExec::verify_initialized( "OpenMP::finalize" ); - Impl::OpenMPExec::verify_is_process( "OpenMP::finalize" ); + if ( omp_in_parallel() ) + { + std::string msg("Kokkos::OpenMP::finalize ERROR "); + if( !Impl::t_openmp_instance ) msg.append(": not initialized"); + if( omp_in_parallel() ) msg.append(": in parallel"); + Kokkos::Impl::throw_runtime_exception(msg); + } - // New, unified host thread team data: - Impl::OpenMPExec::clear_thread_data(); + if ( Impl::t_openmp_instance ) { - Impl::OpenMPExec::m_pool_topo[0] = 0 ; - Impl::OpenMPExec::m_pool_topo[1] = 0 ; - Impl::OpenMPExec::m_pool_topo[2] = 0 ; + const int nthreads = Impl::t_openmp_instance->m_pool_size <= Impl::g_openmp_hardware_max_threads + ? Impl::g_openmp_hardware_max_threads + : Impl::t_openmp_instance->m_pool_size; - omp_set_num_threads(1); + using Exec = Impl::OpenMPExec; + Exec * instance = Impl::t_openmp_instance; + instance->~Exec(); - if ( Impl::s_using_hwloc && Kokkos::hwloc::can_bind_threads() ) { - hwloc::unbind_this_thread(); + OpenMP::memory_space space; + space.deallocate( instance, sizeof(Exec) ); + + #pragma omp parallel num_threads(nthreads) + { + Impl::t_openmp_hardware_id = 0; + Impl::t_openmp_instance = nullptr; + Impl::SharedAllocationRecord< void, void >::tracking_disable(); + } + + // allow main thread to track + Impl::SharedAllocationRecord< void, void >::tracking_enable(); + + Impl::g_openmp_hardware_max_threads = 1; } #if defined(KOKKOS_ENABLE_PROFILING) @@ -396,70 +423,48 @@ void OpenMP::finalize() //---------------------------------------------------------------------------- -void OpenMP::print_configuration( std::ostream & s , const bool detail ) +void OpenMP::print_configuration( std::ostream & s , const bool verbose ) { - Impl::OpenMPExec::verify_is_process( "OpenMP::print_configuration" ); - s << "Kokkos::OpenMP" ; -#if defined( KOKKOS_ENABLE_OPENMP ) - s << " KOKKOS_ENABLE_OPENMP" ; -#endif -#if defined( KOKKOS_ENABLE_HWLOC ) - - const unsigned numa_count_ = Kokkos::hwloc::get_available_numa_count(); - const unsigned cores_per_numa = Kokkos::hwloc::get_available_cores_per_numa(); - const unsigned threads_per_core = Kokkos::hwloc::get_available_threads_per_core(); - - s << " hwloc[" << numa_count_ << "x" << cores_per_numa << "x" << threads_per_core << "]" - << " hwloc_binding_" << ( Impl::s_using_hwloc ? "enabled" : "disabled" ) - ; -#endif - - const bool is_initialized = 0 != Impl::OpenMPExec::m_pool[0] ; + const bool is_initialized = Impl::t_openmp_instance != nullptr; if ( is_initialized ) { - const int numa_count = Kokkos::Impl::OpenMPExec::m_pool_topo[0] / Kokkos::Impl::OpenMPExec::m_pool_topo[1] ; - const int core_per_numa = Kokkos::Impl::OpenMPExec::m_pool_topo[1] / Kokkos::Impl::OpenMPExec::m_pool_topo[2] ; - const int thread_per_core = Kokkos::Impl::OpenMPExec::m_pool_topo[2] ; + Impl::OpenMPExec::verify_is_master( "OpenMP::print_configuration" ); + + const int numa_count = 1; + const int core_per_numa = Impl::g_openmp_hardware_max_threads; + const int thread_per_core = 1; s << " thread_pool_topology[ " << numa_count << " x " << core_per_numa << " x " << thread_per_core << " ]" << std::endl ; - - if ( detail ) { - std::vector< std::pair > coord( Kokkos::Impl::OpenMPExec::m_pool_topo[0] ); - -#pragma omp parallel - { -#pragma omp critical - { - coord[ omp_get_thread_num() ] = hwloc::get_this_thread_coordinate(); - } -/* END #pragma omp critical */ - } -/* END #pragma omp parallel */ - - for ( unsigned i = 0 ; i < coord.size() ; ++i ) { - s << " thread omp_rank[" << i << "]" - << " kokkos_rank[" << Impl::OpenMPExec::m_map_rank[ i ] << "]" - << " hwloc_coord[" << coord[i].first << "." << coord[i].second << "]" - << std::endl ; - } - } } else { s << " not initialized" << std::endl ; } } +std::vector OpenMP::partition(...) +{ return std::vector(1); } + +OpenMP OpenMP::create_instance(...) { return OpenMP(); } + + +#if !defined( KOKKOS_DISABLE_DEPRECATED ) + int OpenMP::concurrency() { - return thread_pool_size(0); + return Impl::g_openmp_hardware_max_threads; } -const char* OpenMP::name() { return "OpenMP"; } +void OpenMP::initialize( int thread_count , int, int ) +{ + initialize(thread_count); +} + +#endif } // namespace Kokkos diff --git a/lib/kokkos/core/src/OpenMP/Kokkos_OpenMP_Exec.hpp b/lib/kokkos/core/src/OpenMP/Kokkos_OpenMP_Exec.hpp index 75b7f5da4a..37d2ac8318 100644 --- a/lib/kokkos/core/src/OpenMP/Kokkos_OpenMP_Exec.hpp +++ b/lib/kokkos/core/src/OpenMP/Kokkos_OpenMP_Exec.hpp @@ -47,6 +47,10 @@ #include #if defined( KOKKOS_ENABLE_OPENMP ) +#if !defined(_OPENMP) +#error "You enabled Kokkos OpenMP support without enabling OpenMP in the compiler!" +#endif + #include #include @@ -54,6 +58,8 @@ #include +#include + #include #include #include @@ -63,8 +69,14 @@ //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- -namespace Kokkos { -namespace Impl { +namespace Kokkos { namespace Impl { + +class OpenMPExec; + +extern int g_openmp_hardware_max_threads; + +extern __thread int t_openmp_hardware_id; +extern __thread OpenMPExec * t_openmp_instance; //---------------------------------------------------------------------------- /** \brief Data for OpenMP thread execution */ @@ -74,279 +86,279 @@ public: friend class Kokkos::OpenMP ; - enum { MAX_THREAD_COUNT = 4096 }; + enum { MAX_THREAD_COUNT = 512 }; + + void clear_thread_data(); + + static void validate_partition( const int nthreads + , int & num_partitions + , int & partition_size + ); private: + OpenMPExec( int arg_pool_size ) + : m_pool_size{ arg_pool_size } + , m_level{ omp_get_level() } + , m_pool() + {} - static int m_pool_topo[ 4 ]; - static int m_map_rank[ MAX_THREAD_COUNT ]; + ~OpenMPExec() + { + clear_thread_data(); + } - static HostThreadTeamData * m_pool[ MAX_THREAD_COUNT ]; + int m_pool_size; + int m_level; - static - void clear_thread_data(); + HostThreadTeamData * m_pool[ MAX_THREAD_COUNT ]; public: - // Topology of a cache coherent thread pool: - // TOTAL = NUMA x GRAIN - // pool_size( depth = 0 ) - // pool_size(0) = total number of threads - // pool_size(1) = number of threads per NUMA - // pool_size(2) = number of threads sharing finest grain memory hierarchy + static void verify_is_master( const char * const ); - inline static - int pool_size( int depth = 0 ) { return m_pool_topo[ depth ]; } - - static void finalize(); - - static void initialize( const unsigned team_count , - const unsigned threads_per_team , - const unsigned numa_count , - const unsigned cores_per_numa ); - - static void verify_is_process( const char * const ); - static void verify_initialized( const char * const ); - - - static void resize_thread_data( size_t pool_reduce_bytes , size_t team_reduce_bytes , size_t team_shared_bytes , size_t thread_local_bytes ); - inline static - HostThreadTeamData * get_thread_data() noexcept - { return m_pool[ m_map_rank[ omp_get_thread_num() ] ]; } + inline + HostThreadTeamData * get_thread_data() const noexcept + { return m_pool[ m_level == omp_get_level() ? 0 : omp_get_thread_num() ]; } - inline static - HostThreadTeamData * get_thread_data( int i ) noexcept - { return m_pool[i]; } + inline + HostThreadTeamData * get_thread_data( int i ) const noexcept + { return m_pool[i]; } }; -} // namespace Impl -} // namespace Kokkos - -//---------------------------------------------------------------------------- -//---------------------------------------------------------------------------- - -namespace Kokkos { -namespace Impl { - -template< class ... Properties > -class TeamPolicyInternal< Kokkos::OpenMP, Properties ... >: public PolicyTraits -{ -public: - - //! Tag this class as a kokkos execution policy - typedef TeamPolicyInternal execution_policy ; - - typedef PolicyTraits traits; - - TeamPolicyInternal& operator = (const TeamPolicyInternal& p) { - m_league_size = p.m_league_size; - m_team_size = p.m_team_size; - m_team_alloc = p.m_team_alloc; - m_team_iter = p.m_team_iter; - m_team_scratch_size[0] = p.m_team_scratch_size[0]; - m_thread_scratch_size[0] = p.m_thread_scratch_size[0]; - m_team_scratch_size[1] = p.m_team_scratch_size[1]; - m_thread_scratch_size[1] = p.m_thread_scratch_size[1]; - m_chunk_size = p.m_chunk_size; - return *this; - } - - //---------------------------------------- - - template< class FunctorType > - inline static - int team_size_max( const FunctorType & ) { - int pool_size = traits::execution_space::thread_pool_size(1); - int max_host_team_size = Impl::HostThreadTeamData::max_team_members; - return pool_size - inline static - int team_size_recommended( const FunctorType & ) - { return traits::execution_space::thread_pool_size(2); } - - template< class FunctorType > - inline static - int team_size_recommended( const FunctorType &, const int& ) - { return traits::execution_space::thread_pool_size(2); } - - //---------------------------------------- - -private: - - int m_league_size ; - int m_team_size ; - int m_team_alloc ; - int m_team_iter ; - - size_t m_team_scratch_size[2]; - size_t m_thread_scratch_size[2]; - - int m_chunk_size; - - inline void init( const int league_size_request - , const int team_size_request ) - { - const int pool_size = traits::execution_space::thread_pool_size(0); - const int max_host_team_size = Impl::HostThreadTeamData::max_team_members; - const int team_max = pool_size 0) { - if(!Impl::is_integral_power_of_two( m_chunk_size )) - Kokkos::abort("TeamPolicy blocking granularity must be power of two" ); - } - - int new_chunk_size = 1; - while(new_chunk_size*100*concurrency < m_league_size) - new_chunk_size *= 2; - if(new_chunk_size < 128) { - new_chunk_size = 1; - while( (new_chunk_size*40*concurrency < m_league_size ) && (new_chunk_size<128) ) - new_chunk_size*=2; - } - m_chunk_size = new_chunk_size; - } - -public: - typedef Impl::HostThreadTeamMember< Kokkos::OpenMP > member_type ; -}; -} // namespace Impl - -} // namespace Kokkos +}} // namespace Kokkos::Impl //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- namespace Kokkos { -inline -bool OpenMP::in_parallel() -{ return omp_in_parallel(); } +inline OpenMP::OpenMP() noexcept +{} inline -int OpenMP::thread_pool_size( int depth ) +bool OpenMP::is_initialized() noexcept +{ return Impl::t_openmp_instance != nullptr; } + +inline +bool OpenMP::in_parallel( OpenMP const& ) noexcept { - return Impl::OpenMPExec::pool_size(depth); + //t_openmp_instance is only non-null on a master thread + return !Impl::t_openmp_instance + || Impl::t_openmp_instance->m_level < omp_get_level() + ; +} + +inline +int OpenMP::thread_pool_size() noexcept +{ + return OpenMP::in_parallel() + ? omp_get_num_threads() + : Impl::t_openmp_instance->m_pool_size + ; } KOKKOS_INLINE_FUNCTION -int OpenMP::thread_pool_rank() +int OpenMP::thread_pool_rank() noexcept { #if defined( KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_HOST ) - return Impl::OpenMPExec::m_map_rank[ omp_get_thread_num() ]; + return Impl::t_openmp_instance ? 0 : omp_get_thread_num(); #else return -1 ; #endif } +inline +void OpenMP::fence( OpenMP const& instance ) noexcept {} + +inline +bool OpenMP::is_asynchronous( OpenMP const& instance ) noexcept +{ return false; } + +template +void OpenMP::partition_master( F const& f + , int num_partitions + , int partition_size + ) +{ + if (omp_get_nested()) { + using Exec = Impl::OpenMPExec; + + Exec * prev_instance = Impl::t_openmp_instance; + + Exec::validate_partition( prev_instance->m_pool_size, num_partitions, partition_size ); + + OpenMP::memory_space space; + + #pragma omp parallel num_threads(num_partitions) + { + void * const ptr = space.allocate( sizeof(Exec) ); + + Impl::t_openmp_instance = new (ptr) Exec( partition_size ); + + size_t pool_reduce_bytes = 32 * partition_size ; + size_t team_reduce_bytes = 32 * partition_size ; + size_t team_shared_bytes = 1024 * partition_size ; + size_t thread_local_bytes = 1024 ; + + Impl::t_openmp_instance->resize_thread_data( pool_reduce_bytes + , team_reduce_bytes + , team_shared_bytes + , thread_local_bytes + ); + + f( omp_get_thread_num(), omp_get_num_threads() ); + + Impl::t_openmp_instance->~Exec(); + space.deallocate( Impl::t_openmp_instance, sizeof(Exec) ); + Impl::t_openmp_instance = nullptr; + } + + Impl::t_openmp_instance = prev_instance; + } + else { + // nested openmp not enabled + f(0,1); + } +} + + +namespace Experimental { + +template<> +class MasterLock +{ +public: + void lock() { omp_set_lock( &m_lock ); } + void unlock() { omp_unset_lock( &m_lock ); } + bool try_lock() { return static_cast(omp_test_lock( &m_lock )); } + + MasterLock() { omp_init_lock( &m_lock ); } + ~MasterLock() { omp_destroy_lock( &m_lock ); } + + MasterLock( MasterLock const& ) = delete; + MasterLock( MasterLock && ) = delete; + MasterLock & operator=( MasterLock const& ) = delete; + MasterLock & operator=( MasterLock && ) = delete; + +private: + omp_lock_t m_lock; + +}; + +template<> +class UniqueToken< OpenMP, UniqueTokenScope::Instance> +{ +public: + using execution_space = OpenMP; + using size_type = int; + + /// \brief create object size for concurrency on the given instance + /// + /// This object should not be shared between instances + UniqueToken( execution_space const& = execution_space() ) noexcept {} + + /// \brief upper bound for acquired values, i.e. 0 <= value < size() + KOKKOS_INLINE_FUNCTION + int size() const noexcept + { + #if defined( KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_HOST ) + return Kokkos::OpenMP::thread_pool_size(); + #else + return 0 ; + #endif + } + + /// \brief acquire value such that 0 <= value < size() + KOKKOS_INLINE_FUNCTION + int acquire() const noexcept + { + #if defined( KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_HOST ) + return Kokkos::OpenMP::thread_pool_rank(); + #else + return 0 ; + #endif + } + + /// \brief release a value acquired by generate + KOKKOS_INLINE_FUNCTION + void release( int ) const noexcept {} +}; + +template<> +class UniqueToken< OpenMP, UniqueTokenScope::Global> +{ +public: + using execution_space = OpenMP; + using size_type = int; + + /// \brief create object size for concurrency on the given instance + /// + /// This object should not be shared between instances + UniqueToken( execution_space const& = execution_space() ) noexcept {} + + /// \brief upper bound for acquired values, i.e. 0 <= value < size() + KOKKOS_INLINE_FUNCTION + int size() const noexcept + { + #if defined( KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_HOST ) + return Kokkos::Impl::g_openmp_hardware_max_threads ; + #else + return 0 ; + #endif + } + + /// \brief acquire value such that 0 <= value < size() + KOKKOS_INLINE_FUNCTION + int acquire() const noexcept + { + #if defined( KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_HOST ) + return Kokkos::Impl::t_openmp_hardware_id ; + #else + return 0 ; + #endif + } + + /// \brief release a value acquired by generate + KOKKOS_INLINE_FUNCTION + void release( int ) const noexcept {} +}; + +} // namespace Experimental + + +#if !defined( KOKKOS_DISABLE_DEPRECATED ) + +inline +int OpenMP::thread_pool_size( int depth ) +{ + return depth < 2 + ? thread_pool_size() + : 1; +} + +KOKKOS_INLINE_FUNCTION +int OpenMP::hardware_thread_id() noexcept +{ +#if defined( KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_HOST ) + return Impl::t_openmp_hardware_id; +#else + return -1 ; +#endif +} + +inline +int OpenMP::max_hardware_threads() noexcept +{ + return Impl::g_openmp_hardware_max_threads; +} + +#endif // KOKKOS_DISABLE_DEPRECATED + } // namespace Kokkos #endif diff --git a/lib/kokkos/core/src/OpenMP/Kokkos_OpenMP_Parallel.hpp b/lib/kokkos/core/src/OpenMP/Kokkos_OpenMP_Parallel.hpp index c47e0fc654..b54abb0068 100644 --- a/lib/kokkos/core/src/OpenMP/Kokkos_OpenMP_Parallel.hpp +++ b/lib/kokkos/core/src/OpenMP/Kokkos_OpenMP_Parallel.hpp @@ -52,6 +52,8 @@ #include #include +#include + //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- @@ -71,8 +73,9 @@ private: typedef typename Policy::WorkRange WorkRange ; typedef typename Policy::member_type Member ; - const FunctorType m_functor ; - const Policy m_policy ; + OpenMPExec * m_instance ; + const FunctorType m_functor ; + const Policy m_policy ; template< class TagType > inline static @@ -110,16 +113,120 @@ private: public: inline void execute() const + { + enum { is_dynamic = std::is_same< typename Policy::schedule_type::type + , Kokkos::Dynamic >::value + }; + + if ( OpenMP::in_parallel() ) { + exec_range< WorkTag >( m_functor + , m_policy.begin() + , m_policy.end() ); + } + else { + + OpenMPExec::verify_is_master("Kokkos::OpenMP parallel_for"); + + const int pool_size = OpenMP::thread_pool_size(); + #pragma omp parallel num_threads(pool_size) + { + HostThreadTeamData & data = *(m_instance->get_thread_data()); + + data.set_work_partition( m_policy.end() - m_policy.begin() + , m_policy.chunk_size() ); + + if ( is_dynamic ) { + // Make sure work partition is set before stealing + if ( data.pool_rendezvous() ) data.pool_rendezvous_release(); + } + + std::pair range(0,0); + + do { + + range = is_dynamic ? data.get_work_stealing_chunk() + : data.get_work_partition(); + + ParallelFor::template + exec_range< WorkTag >( m_functor + , range.first + m_policy.begin() + , range.second + m_policy.begin() ); + + } while ( is_dynamic && 0 <= range.first ); + } + } + } + + inline + ParallelFor( const FunctorType & arg_functor + , Policy arg_policy ) + : m_instance( t_openmp_instance ) + , m_functor( arg_functor ) + , m_policy( arg_policy ) + {} +}; + + +// MDRangePolicy impl +template< class FunctorType , class ... Traits > +class ParallelFor< FunctorType + , Kokkos::Experimental::MDRangePolicy< Traits ... > + , Kokkos::OpenMP + > +{ +private: + + typedef Kokkos::Experimental::MDRangePolicy< Traits ... > MDRangePolicy ; + typedef typename MDRangePolicy::impl_range_policy Policy ; + typedef typename MDRangePolicy::work_tag WorkTag ; + + typedef typename Policy::WorkRange WorkRange ; + typedef typename Policy::member_type Member ; + + typedef typename Kokkos::Experimental::Impl::HostIterateTile< MDRangePolicy, FunctorType, typename MDRangePolicy::work_tag, void > iterate_type; + + OpenMPExec * m_instance ; + const FunctorType m_functor ; + const MDRangePolicy m_mdr_policy ; + const Policy m_policy ; // construct as RangePolicy( 0, num_tiles ).set_chunk_size(1) in ctor + + inline static + void + exec_range( const MDRangePolicy & mdr_policy + , const FunctorType & functor + , const Member ibeg , const Member iend ) { + #ifdef KOKKOS_ENABLE_AGGRESSIVE_VECTORIZATION + #ifdef KOKKOS_ENABLE_PRAGMA_IVDEP + #pragma ivdep + #endif + #endif + for ( Member iwork = ibeg ; iwork < iend ; ++iwork ) { + iterate_type( mdr_policy, functor )( iwork ); + } + } + +public: + + inline void execute() const + { enum { is_dynamic = std::is_same< typename Policy::schedule_type::type , Kokkos::Dynamic >::value }; - OpenMPExec::verify_is_process("Kokkos::OpenMP parallel_for"); - OpenMPExec::verify_initialized("Kokkos::OpenMP parallel_for"); + if ( OpenMP::in_parallel() ) { + ParallelFor::exec_range ( m_mdr_policy + , m_functor + , m_policy.begin() + , m_policy.end() ); + } + else { -#pragma omp parallel + OpenMPExec::verify_is_master("Kokkos::OpenMP parallel_for"); + + const int pool_size = OpenMP::thread_pool_size(); + #pragma omp parallel num_threads(pool_size) { - HostThreadTeamData & data = *OpenMPExec::get_thread_data(); + HostThreadTeamData & data = *(m_instance->get_thread_data()); data.set_work_partition( m_policy.end() - m_policy.begin() , m_policy.chunk_size() ); @@ -136,8 +243,8 @@ public: range = is_dynamic ? data.get_work_stealing_chunk() : data.get_work_partition(); - ParallelFor::template - exec_range< WorkTag >( m_functor + ParallelFor::exec_range( m_mdr_policy + , m_functor , range.first + m_policy.begin() , range.second + m_policy.begin() ); @@ -145,12 +252,15 @@ public: } // END #pragma omp parallel } + } inline ParallelFor( const FunctorType & arg_functor - , Policy arg_policy ) - : m_functor( arg_functor ) - , m_policy( arg_policy ) + , MDRangePolicy arg_policy ) + : m_instance( t_openmp_instance ) + , m_functor( arg_functor ) + , m_mdr_policy( arg_policy ) + , m_policy( Policy(0, m_mdr_policy.m_num_tiles).set_chunk_size(1) ) {} }; @@ -191,10 +301,11 @@ private: typedef typename Analysis::pointer_type pointer_type ; typedef typename Analysis::reference_type reference_type ; - const FunctorType m_functor ; - const Policy m_policy ; - const ReducerType m_reducer ; - const pointer_type m_result_ptr ; + OpenMPExec * m_instance; + const FunctorType m_functor; + const Policy m_policy; + const ReducerType m_reducer; + const pointer_type m_result_ptr; template< class TagType > inline static @@ -228,21 +339,21 @@ public: enum { is_dynamic = std::is_same< typename Policy::schedule_type::type , Kokkos::Dynamic >::value }; - OpenMPExec::verify_is_process("Kokkos::OpenMP parallel_reduce"); - OpenMPExec::verify_initialized("Kokkos::OpenMP parallel_reduce"); + OpenMPExec::verify_is_master("Kokkos::OpenMP parallel_reduce"); const size_t pool_reduce_bytes = Analysis::value_size( ReducerConditional::select(m_functor, m_reducer)); - OpenMPExec::resize_thread_data( pool_reduce_bytes + m_instance->resize_thread_data( pool_reduce_bytes , 0 // team_reduce_bytes , 0 // team_shared_bytes , 0 // thread_local_bytes ); -#pragma omp parallel + const int pool_size = OpenMP::thread_pool_size(); + #pragma omp parallel num_threads(pool_size) { - HostThreadTeamData & data = *OpenMPExec::get_thread_data(); + HostThreadTeamData & data = *(m_instance->get_thread_data()); data.set_work_partition( m_policy.end() - m_policy.begin() , m_policy.chunk_size() ); @@ -271,16 +382,15 @@ public: } while ( is_dynamic && 0 <= range.first ); } -// END #pragma omp parallel // Reduction: - const pointer_type ptr = pointer_type( OpenMPExec::get_thread_data(0)->pool_reduce_local() ); + const pointer_type ptr = pointer_type( m_instance->get_thread_data(0)->pool_reduce_local() ); - for ( int i = 1 ; i < OpenMPExec::pool_size() ; ++i ) { + for ( int i = 1 ; i < pool_size ; ++i ) { ValueJoin::join( ReducerConditional::select(m_functor , m_reducer) , ptr - , OpenMPExec::get_thread_data(i)->pool_reduce_local() ); + , m_instance->get_thread_data(i)->pool_reduce_local() ); } Kokkos::Impl::FunctorFinal< ReducerTypeFwd , WorkTag >::final( ReducerConditional::select(m_functor , m_reducer) , ptr ); @@ -303,7 +413,8 @@ public: Kokkos::is_view< ViewType >::value && !Kokkos::is_reducer_type::value ,void*>::type = NULL) - : m_functor( arg_functor ) + : m_instance( t_openmp_instance ) + , m_functor( arg_functor ) , m_policy( arg_policy ) , m_reducer( InvalidType() ) , m_result_ptr( arg_view.data() ) @@ -317,7 +428,8 @@ public: ParallelReduce( const FunctorType & arg_functor , Policy arg_policy , const ReducerType& reducer ) - : m_functor( arg_functor ) + : m_instance( t_openmp_instance ) + , m_functor( arg_functor ) , m_policy( arg_policy ) , m_reducer( reducer ) , m_result_ptr( reducer.view().data() ) @@ -329,6 +441,173 @@ public: }; + +// MDRangePolicy impl +template< class FunctorType , class ReducerType, class ... Traits > +class ParallelReduce< FunctorType + , Kokkos::Experimental::MDRangePolicy< Traits ...> + , ReducerType + , Kokkos::OpenMP + > +{ +private: + + typedef Kokkos::Experimental::MDRangePolicy< Traits ... > MDRangePolicy ; + typedef typename MDRangePolicy::impl_range_policy Policy ; + + typedef typename MDRangePolicy::work_tag WorkTag ; + typedef typename Policy::WorkRange WorkRange ; + typedef typename Policy::member_type Member ; + + typedef FunctorAnalysis< FunctorPatternInterface::REDUCE , Policy , FunctorType > Analysis ; + + typedef Kokkos::Impl::if_c< std::is_same::value, FunctorType, ReducerType> ReducerConditional; + typedef typename ReducerConditional::type ReducerTypeFwd; + + typedef typename ReducerTypeFwd::value_type ValueType; + + typedef Kokkos::Impl::FunctorValueInit< ReducerTypeFwd, WorkTag > ValueInit ; + typedef Kokkos::Impl::FunctorValueJoin< ReducerTypeFwd, WorkTag > ValueJoin ; + + typedef typename Analysis::pointer_type pointer_type ; + typedef typename Analysis::reference_type reference_type ; + + using iterate_type = typename Kokkos::Experimental::Impl::HostIterateTile< MDRangePolicy + , FunctorType + , WorkTag + , ValueType + >; + + OpenMPExec * m_instance ; + const FunctorType m_functor ; + const MDRangePolicy m_mdr_policy ; + const Policy m_policy ; // construct as RangePolicy( 0, num_tiles ).set_chunk_size(1) in ctor + const ReducerType m_reducer ; + const pointer_type m_result_ptr ; + + inline static + void + exec_range( const MDRangePolicy & mdr_policy + , const FunctorType & functor + , const Member ibeg , const Member iend + , reference_type update ) + { + for ( Member iwork = ibeg ; iwork < iend ; ++iwork ) { + iterate_type( mdr_policy, functor, update )( iwork ); + } + } + +public: + + inline void execute() const + { + enum { is_dynamic = std::is_same< typename Policy::schedule_type::type + , Kokkos::Dynamic >::value }; + + OpenMPExec::verify_is_master("Kokkos::OpenMP parallel_reduce"); + + const size_t pool_reduce_bytes = + Analysis::value_size( ReducerConditional::select(m_functor, m_reducer)); + + m_instance->resize_thread_data( pool_reduce_bytes + , 0 // team_reduce_bytes + , 0 // team_shared_bytes + , 0 // thread_local_bytes + ); + + const int pool_size = OpenMP::thread_pool_size(); + #pragma omp parallel num_threads(pool_size) + { + HostThreadTeamData & data = *(m_instance->get_thread_data()); + + data.set_work_partition( m_policy.end() - m_policy.begin() + , m_policy.chunk_size() ); + + if ( is_dynamic ) { + // Make sure work partition is set before stealing + if ( data.pool_rendezvous() ) data.pool_rendezvous_release(); + } + + reference_type update = + ValueInit::init( ReducerConditional::select(m_functor , m_reducer) + , data.pool_reduce_local() ); + + std::pair range(0,0); + + do { + + range = is_dynamic ? data.get_work_stealing_chunk() + : data.get_work_partition(); + + ParallelReduce::exec_range ( m_mdr_policy, m_functor + , range.first + m_policy.begin() + , range.second + m_policy.begin() + , update ); + + } while ( is_dynamic && 0 <= range.first ); + } +// END #pragma omp parallel + + // Reduction: + + const pointer_type ptr = pointer_type( m_instance->get_thread_data(0)->pool_reduce_local() ); + + for ( int i = 1 ; i < pool_size ; ++i ) { + ValueJoin::join( ReducerConditional::select(m_functor , m_reducer) + , ptr + , m_instance->get_thread_data(i)->pool_reduce_local() ); + } + + Kokkos::Impl::FunctorFinal< ReducerTypeFwd , WorkTag >::final( ReducerConditional::select(m_functor , m_reducer) , ptr ); + + if ( m_result_ptr ) { + const int n = Analysis::value_count( ReducerConditional::select(m_functor , m_reducer) ); + + for ( int j = 0 ; j < n ; ++j ) { m_result_ptr[j] = ptr[j] ; } + } + } + + //---------------------------------------- + + template< class ViewType > + inline + ParallelReduce( const FunctorType & arg_functor + , MDRangePolicy arg_policy + , const ViewType & arg_view + , typename std::enable_if< + Kokkos::is_view< ViewType >::value && + !Kokkos::is_reducer_type::value + ,void*>::type = NULL) + : m_instance( t_openmp_instance ) + , 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_view.data() ) + { + /*static_assert( std::is_same< typename ViewType::memory_space + , Kokkos::HostSpace >::value + , "Reduction result on Kokkos::OpenMP must be a Kokkos::View in HostSpace" );*/ + } + + inline + ParallelReduce( const FunctorType & arg_functor + , MDRangePolicy arg_policy + , const ReducerType& reducer ) + : m_instance( t_openmp_instance ) + , 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 + , Kokkos::HostSpace >::value + , "Reduction result on Kokkos::OpenMP must be a Kokkos::View in HostSpace" );*/ + } + +}; + } // namespace Impl } // namespace Kokkos @@ -361,8 +640,9 @@ private: typedef typename Analysis::pointer_type pointer_type ; typedef typename Analysis::reference_type reference_type ; - const FunctorType m_functor ; - const Policy m_policy ; + OpenMPExec * m_instance; + const FunctorType m_functor; + const Policy m_policy; template< class TagType > inline static @@ -394,23 +674,23 @@ public: inline void execute() const { - OpenMPExec::verify_is_process("Kokkos::OpenMP parallel_scan"); - OpenMPExec::verify_initialized("Kokkos::OpenMP parallel_scan"); + OpenMPExec::verify_is_master("Kokkos::OpenMP parallel_scan"); const int value_count = Analysis::value_count( m_functor ); const size_t pool_reduce_bytes = 2 * Analysis::value_size( m_functor ); - OpenMPExec::resize_thread_data( pool_reduce_bytes + m_instance->resize_thread_data( pool_reduce_bytes , 0 // team_reduce_bytes , 0 // team_shared_bytes , 0 // thread_local_bytes ); -#pragma omp parallel + const int pool_size = OpenMP::thread_pool_size(); + #pragma omp parallel num_threads(pool_size) { - HostThreadTeamData & data = *OpenMPExec::get_thread_data(); + HostThreadTeamData & data = *(m_instance->get_thread_data()); - const WorkRange range( m_policy, data.pool_rank(), data.pool_size() ); + const WorkRange range( m_policy, omp_get_thread_num(), omp_get_num_threads() ); reference_type update_sum = ValueInit::init( m_functor , data.pool_reduce_local() ); @@ -422,7 +702,7 @@ public: pointer_type ptr_prev = 0 ; - const int n = data.pool_size(); + const int n = omp_get_num_threads(); for ( int i = 0 ; i < n ; ++i ) { @@ -452,7 +732,6 @@ public: ParallelScan::template exec_range< WorkTag > ( m_functor , range.begin() , range.end() , update_base , true ); } -/* END #pragma omp parallel */ } @@ -461,7 +740,8 @@ public: inline ParallelScan( const FunctorType & arg_functor , const Policy & arg_policy ) - : m_functor( arg_functor ) + : m_instance( t_openmp_instance ) + , m_functor( arg_functor ) , m_policy( arg_policy ) {} @@ -492,9 +772,10 @@ private: typedef typename Policy::schedule_type::type SchedTag ; typedef typename Policy::member_type Member ; - const FunctorType m_functor ; - const Policy m_policy ; - const int m_shmem_size ; + OpenMPExec * m_instance; + const FunctorType m_functor; + const Policy m_policy; + const int m_shmem_size; template< class TagType > inline static @@ -548,22 +829,22 @@ public: { enum { is_dynamic = std::is_same< SchedTag , Kokkos::Dynamic >::value }; - OpenMPExec::verify_is_process("Kokkos::OpenMP parallel_for"); - OpenMPExec::verify_initialized("Kokkos::OpenMP parallel_for"); + OpenMPExec::verify_is_master("Kokkos::OpenMP parallel_for"); const size_t pool_reduce_size = 0 ; // Never shrinks const size_t team_reduce_size = TEAM_REDUCE_SIZE * m_policy.team_size(); const size_t team_shared_size = m_shmem_size + m_policy.scratch_size(1); const size_t thread_local_size = 0 ; // Never shrinks - OpenMPExec::resize_thread_data( pool_reduce_size + m_instance->resize_thread_data( pool_reduce_size , team_reduce_size , team_shared_size , thread_local_size ); -#pragma omp parallel + const int pool_size = OpenMP::thread_pool_size(); + #pragma omp parallel num_threads(pool_size) { - HostThreadTeamData & data = *OpenMPExec::get_thread_data(); + HostThreadTeamData & data = *(m_instance->get_thread_data()); const int active = data.organize_team( m_policy.team_size() ); @@ -598,14 +879,14 @@ public: data.disband_team(); } -// END #pragma omp parallel } inline ParallelFor( const FunctorType & arg_functor , const Policy & arg_policy ) - : m_functor( arg_functor ) + : m_instance( t_openmp_instance ) + , m_functor( arg_functor ) , m_policy( arg_policy ) , m_shmem_size( arg_policy.scratch_size(0) + arg_policy.scratch_size(1) + @@ -646,11 +927,12 @@ private: typedef typename Analysis::pointer_type pointer_type ; typedef typename Analysis::reference_type reference_type ; - const FunctorType m_functor ; - const Policy m_policy ; - const ReducerType m_reducer ; - const pointer_type m_result_ptr ; - const int m_shmem_size ; + OpenMPExec * m_instance; + const FunctorType m_functor; + const Policy m_policy; + const ReducerType m_reducer; + const pointer_type m_result_ptr; + const int m_shmem_size; template< class TagType > inline static @@ -706,8 +988,7 @@ public: { enum { is_dynamic = std::is_same< SchedTag , Kokkos::Dynamic >::value }; - OpenMPExec::verify_is_process("Kokkos::OpenMP parallel_reduce"); - OpenMPExec::verify_initialized("Kokkos::OpenMP parallel_reduce"); + OpenMPExec::verify_is_master("Kokkos::OpenMP parallel_reduce"); const size_t pool_reduce_size = Analysis::value_size( ReducerConditional::select(m_functor, m_reducer)); @@ -716,14 +997,15 @@ public: const size_t team_shared_size = m_shmem_size + m_policy.scratch_size(1); const size_t thread_local_size = 0 ; // Never shrinks - OpenMPExec::resize_thread_data( pool_reduce_size + m_instance->resize_thread_data( pool_reduce_size , team_reduce_size , team_shared_size , thread_local_size ); -#pragma omp parallel + const int pool_size = OpenMP::thread_pool_size(); + #pragma omp parallel num_threads(pool_size) { - HostThreadTeamData & data = *OpenMPExec::get_thread_data(); + HostThreadTeamData & data = *(m_instance->get_thread_data()); const int active = data.organize_team( m_policy.team_size() ); @@ -763,17 +1045,26 @@ public: } data.disband_team(); + + // This thread has updated 'pool_reduce_local()' with its + // contributions to the reduction. The parallel region is + // about to terminate and the master thread will load and + // reduce each 'pool_reduce_local()' contribution. + // Must 'memory_fence()' to guarantee that storing the update to + // 'pool_reduce_local()' will complete before this thread + // exits the parallel region. + + memory_fence(); } -// END #pragma omp parallel // Reduction: - const pointer_type ptr = pointer_type( OpenMPExec::get_thread_data(0)->pool_reduce_local() ); + const pointer_type ptr = pointer_type( m_instance->get_thread_data(0)->pool_reduce_local() ); - for ( int i = 1 ; i < OpenMPExec::pool_size() ; ++i ) { + for ( int i = 1 ; i < pool_size ; ++i ) { ValueJoin::join( ReducerConditional::select(m_functor , m_reducer) , ptr - , OpenMPExec::get_thread_data(i)->pool_reduce_local() ); + , m_instance->get_thread_data(i)->pool_reduce_local() ); } Kokkos::Impl::FunctorFinal< ReducerTypeFwd , WorkTag >::final( ReducerConditional::select(m_functor , m_reducer) , ptr ); @@ -796,7 +1087,8 @@ public: Kokkos::is_view< ViewType >::value && !Kokkos::is_reducer_type::value ,void*>::type = NULL) - : m_functor( arg_functor ) + : m_instance( t_openmp_instance ) + , m_functor( arg_functor ) , m_policy( arg_policy ) , m_reducer( InvalidType() ) , m_result_ptr( arg_result.ptr_on_device() ) @@ -810,7 +1102,8 @@ public: ParallelReduce( const FunctorType & arg_functor , Policy arg_policy , const ReducerType& reducer ) - : m_functor( arg_functor ) + : m_instance( t_openmp_instance ) + , m_functor( arg_functor ) , m_policy( arg_policy ) , m_reducer( reducer ) , m_result_ptr( reducer.view().data() ) diff --git a/lib/kokkos/core/src/OpenMP/Kokkos_OpenMP_Task.cpp b/lib/kokkos/core/src/OpenMP/Kokkos_OpenMP_Task.cpp index d4ade211f8..77363876b0 100644 --- a/lib/kokkos/core/src/OpenMP/Kokkos_OpenMP_Task.cpp +++ b/lib/kokkos/core/src/OpenMP/Kokkos_OpenMP_Task.cpp @@ -105,7 +105,7 @@ void TaskQueueSpecialization< Kokkos::OpenMP >::execute { using execution_space = Kokkos::OpenMP ; using queue_type = TaskQueue< execution_space > ; - using task_root_type = TaskBase< execution_space , void , void > ; + using task_root_type = TaskBase< void , void , void > ; using Member = Impl::HostThreadTeamMember< execution_space > ; static task_root_type * const end = @@ -115,23 +115,19 @@ void TaskQueueSpecialization< Kokkos::OpenMP >::execute HostThreadTeamData & team_data_single = HostThreadTeamDataSingleton::singleton(); - const int team_size = Impl::OpenMPExec::pool_size(2); // Threads per core - // const int team_size = Impl::OpenMPExec::pool_size(1); // Threads per NUMA + Impl::OpenMPExec * instance = t_openmp_instance; + const int pool_size = OpenMP::thread_pool_size(); -#if 0 -fprintf(stdout,"TaskQueue execute %d\n", team_size ); -fflush(stdout); -#endif + const int team_size = 1; // Threads per core + instance->resize_thread_data( 0 /* global reduce buffer */ + , 512 * team_size /* team reduce buffer */ + , 0 /* team shared buffer */ + , 0 /* thread local buffer */ + ); - OpenMPExec::resize_thread_data( 0 /* global reduce buffer */ - , 512 * team_size /* team reduce buffer */ - , 0 /* team shared buffer */ - , 0 /* thread local buffer */ - ); - -#pragma omp parallel + #pragma omp parallel num_threads(pool_size) { - Impl::HostThreadTeamData & self = *Impl::OpenMPExec::get_thread_data(); + Impl::HostThreadTeamData & self = *(instance->get_thread_data()); // Organizing threads into a team performs a barrier across the // entire pool to insure proper initialization of the team @@ -142,18 +138,6 @@ fflush(stdout); Member single_exec( team_data_single ); Member team_exec( self ); -#if 0 -fprintf(stdout,"TaskQueue pool(%d of %d) team(%d of %d) league(%d of %d) running\n" - , self.pool_rank() - , self.pool_size() - , team_exec.team_rank() - , team_exec.team_size() - , team_exec.league_rank() - , team_exec.league_size() - ); -fflush(stdout); -#endif - // Loop until all queues are empty and no tasks in flight task_root_type * task = 0 ; @@ -197,15 +181,6 @@ fflush(stdout); // if a single thread task then execute now -#if 0 -fprintf(stdout,"TaskQueue pool(%d of %d) executing single task 0x%lx\n" - , self.pool_rank() - , self.pool_size() - , int64_t(task) - ); -fflush(stdout); -#endif - (*task->m_apply)( task , & single_exec ); leader_loop = true ; @@ -220,57 +195,14 @@ fflush(stdout); if ( 0 != task ) { // Thread Team Task -#if 0 -fprintf(stdout,"TaskQueue pool(%d of %d) team((%d of %d) league(%d of %d) executing team task 0x%lx\n" - , self.pool_rank() - , self.pool_size() - , team_exec.team_rank() - , team_exec.team_size() - , team_exec.league_rank() - , team_exec.league_size() - , int64_t(task) - ); -fflush(stdout); -#endif - (*task->m_apply)( task , & team_exec ); // The m_apply function performs a barrier } } while( 0 != task ); - -#if 0 -fprintf(stdout,"TaskQueue pool(%d of %d) team(%d of %d) league(%d of %d) ending\n" - , self.pool_rank() - , self.pool_size() - , team_exec.team_rank() - , team_exec.team_size() - , team_exec.league_rank() - , team_exec.league_size() - ); -fflush(stdout); -#endif - } - self.disband_team(); - -#if 0 -fprintf(stdout,"TaskQueue pool(%d of %d) disbanded\n" - , self.pool_rank() - , self.pool_size() - ); -fflush(stdout); -#endif - } -// END #pragma omp parallel - -#if 0 -fprintf(stdout,"TaskQueue execute %d end\n", team_size ); -fflush(stdout); -#endif - } void TaskQueueSpecialization< Kokkos::OpenMP >:: @@ -279,10 +211,10 @@ void TaskQueueSpecialization< Kokkos::OpenMP >:: { using execution_space = Kokkos::OpenMP ; using queue_type = TaskQueue< execution_space > ; - using task_root_type = TaskBase< execution_space , void , void > ; + using task_root_type = TaskBase< void , void , void > ; using Member = Impl::HostThreadTeamMember< execution_space > ; - if ( 1 == omp_get_num_threads() ) { + if ( 1 == OpenMP::thread_pool_size() ) { task_root_type * const end = (task_root_type *) task_root_type::EndTag ; diff --git a/lib/kokkos/core/src/OpenMP/Kokkos_OpenMP_Task.hpp b/lib/kokkos/core/src/OpenMP/Kokkos_OpenMP_Task.hpp index 82fbef255b..dfa1635e08 100644 --- a/lib/kokkos/core/src/OpenMP/Kokkos_OpenMP_Task.hpp +++ b/lib/kokkos/core/src/OpenMP/Kokkos_OpenMP_Task.hpp @@ -45,7 +45,7 @@ #define KOKKOS_IMPL_OPENMP_TASK_HPP #include -#if defined( KOKKOS_ENABLE_TASKDAG ) +#if defined( KOKKOS_ENABLE_OPENMP ) && defined( KOKKOS_ENABLE_TASKDAG ) //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- @@ -60,7 +60,7 @@ public: using execution_space = Kokkos::OpenMP ; using queue_type = Kokkos::Impl::TaskQueue< execution_space > ; - using task_base_type = Kokkos::Impl::TaskBase< execution_space , void , void > ; + using task_base_type = Kokkos::Impl::TaskBase< void , void , void > ; using member_type = Kokkos::Impl::HostThreadTeamMember< execution_space > ; // Must specify memory space diff --git a/lib/kokkos/core/src/OpenMP/Kokkos_OpenMP_Team.hpp b/lib/kokkos/core/src/OpenMP/Kokkos_OpenMP_Team.hpp new file mode 100644 index 0000000000..743e6b6e62 --- /dev/null +++ b/lib/kokkos/core/src/OpenMP/Kokkos_OpenMP_Team.hpp @@ -0,0 +1,245 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#ifndef KOKKOS_OPENMP_TEAM_HPP +#define KOKKOS_OPENMP_TEAM_HPP + +#include +#if defined( KOKKOS_ENABLE_OPENMP ) + +#include + +namespace Kokkos { namespace Impl { + +template< class ... Properties > +class TeamPolicyInternal< Kokkos::OpenMP, Properties ... >: public PolicyTraits +{ +public: + + //! Tag this class as a kokkos execution policy + typedef TeamPolicyInternal execution_policy ; + + typedef PolicyTraits traits; + + TeamPolicyInternal& operator = (const TeamPolicyInternal& p) { + m_league_size = p.m_league_size; + m_team_size = p.m_team_size; + m_team_alloc = p.m_team_alloc; + m_team_iter = p.m_team_iter; + m_team_scratch_size[0] = p.m_team_scratch_size[0]; + m_thread_scratch_size[0] = p.m_thread_scratch_size[0]; + m_team_scratch_size[1] = p.m_team_scratch_size[1]; + m_thread_scratch_size[1] = p.m_thread_scratch_size[1]; + m_chunk_size = p.m_chunk_size; + return *this; + } + + //---------------------------------------- + + template< class FunctorType > + inline static + int team_size_max( const FunctorType & ) { + int pool_size = traits::execution_space::thread_pool_size(1); + int max_host_team_size = Impl::HostThreadTeamData::max_team_members; + return pool_size + inline static + int team_size_recommended( const FunctorType & ) + { return traits::execution_space::thread_pool_size(2); } + + template< class FunctorType > + inline static + int team_size_recommended( const FunctorType &, const int& ) + { return traits::execution_space::thread_pool_size(2); } + + //---------------------------------------- + +private: + + int m_league_size ; + int m_team_size ; + int m_team_alloc ; + int m_team_iter ; + + size_t m_team_scratch_size[2]; + size_t m_thread_scratch_size[2]; + + int m_chunk_size; + + inline void init( const int league_size_request + , const int team_size_request ) + { + const int pool_size = traits::execution_space::thread_pool_size(0); + const int max_host_team_size = Impl::HostThreadTeamData::max_team_members; + const int team_max = pool_size 0) { + if(!Impl::is_integral_power_of_two( m_chunk_size )) + Kokkos::abort("TeamPolicy blocking granularity must be power of two" ); + } + + int new_chunk_size = 1; + while(new_chunk_size*100*concurrency < m_league_size) + new_chunk_size *= 2; + if(new_chunk_size < 128) { + new_chunk_size = 1; + while( (new_chunk_size*40*concurrency < m_league_size ) && (new_chunk_size<128) ) + new_chunk_size*=2; + } + m_chunk_size = new_chunk_size; + } + +public: + typedef Impl::HostThreadTeamMember< Kokkos::OpenMP > member_type ; +}; + +}} // namespace Kokkos::Impl + +#endif +#endif /* KOKKOS_OPENMP_TEAM_HPP */ + + diff --git a/lib/kokkos/core/src/OpenMP/Kokkos_OpenMP_WorkGraphPolicy.hpp b/lib/kokkos/core/src/OpenMP/Kokkos_OpenMP_WorkGraphPolicy.hpp new file mode 100644 index 0000000000..289ad15451 --- /dev/null +++ b/lib/kokkos/core/src/OpenMP/Kokkos_OpenMP_WorkGraphPolicy.hpp @@ -0,0 +1,107 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#ifndef KOKKOS_OPENMP_WORKGRAPHPOLICY_HPP +#define KOKKOS_OPENMP_WORKGRAPHPOLICY_HPP + +namespace Kokkos { +namespace Impl { + +template< class FunctorType , class ... Traits > +class ParallelFor< FunctorType , + Kokkos::Experimental::WorkGraphPolicy< Traits ... > , + Kokkos::OpenMP + > + : public Kokkos::Impl::Experimental:: + WorkGraphExec< FunctorType, + Kokkos::OpenMP, + Traits ... + > +{ +private: + + typedef Kokkos::Experimental::WorkGraphPolicy< Traits ... > Policy ; + typedef Kokkos::Impl::Experimental:: + WorkGraphExec Base ; + + template< class TagType > + typename std::enable_if< std::is_same< TagType , void >::value >::type + exec_one(const typename Policy::member_type& i) const { + Base::m_functor( i ); + } + + template< class TagType > + typename std::enable_if< ! std::is_same< TagType , void >::value >::type + exec_one(const typename Policy::member_type& i) const { + const TagType t{} ; + Base::m_functor( t , i ); + } + +public: + + inline + void execute() + { + const int pool_size = OpenMP::thread_pool_size(); + + #pragma omp parallel num_threads(pool_size) + { + for (std::int32_t i; (-1 != (i = Base::before_work())); ) { + exec_one< typename Policy::work_tag >( i ); + Base::after_work(i); + } + } + } + + inline + ParallelFor( const FunctorType & arg_functor + , const Policy & arg_policy ) + : Base( arg_functor, arg_policy ) + { + } +}; + +} // namespace Impl +} // namespace Kokkos + +#endif /* #define KOKKOS_OPENMP_WORKGRAPHPOLICY_HPP */ diff --git a/lib/kokkos/core/src/OpenMPTarget/Kokkos_OpenMPTarget_Exec.hpp b/lib/kokkos/core/src/OpenMPTarget/Kokkos_OpenMPTarget_Exec.hpp index bec7844ed6..258a9d2ff7 100644 --- a/lib/kokkos/core/src/OpenMPTarget/Kokkos_OpenMPTarget_Exec.hpp +++ b/lib/kokkos/core/src/OpenMPTarget/Kokkos_OpenMPTarget_Exec.hpp @@ -1,13 +1,13 @@ /* //@HEADER // ************************************************************************ -// +// // Kokkos v. 2.0 // Copyright (2014) Sandia Corporation -// +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: @@ -36,7 +36,7 @@ // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) -// +// // ************************************************************************ //@HEADER */ @@ -45,7 +45,7 @@ #define KOKKOS_OPENMPTARGETEXEC_HPP #include -#include +#include #include #include @@ -59,10 +59,10 @@ namespace Impl { class OpenMPTargetExec { -public: +public: enum { MAX_ACTIVE_THREADS = 256*8*56*4 }; enum { MAX_ACTIVE_TEAMS = MAX_ACTIVE_THREADS/32 }; - + private: static void* scratch_ptr; @@ -70,7 +70,7 @@ public: static void verify_is_process( const char * const ); static void verify_initialized( const char * const ); - static void* get_scratch_ptr(); + static void* get_scratch_ptr(); static void clear_scratch(); static void resize_scratch( int64_t reduce_bytes , int64_t team_reduce_bytes, int64_t team_shared_bytes, int64_t thread_local_bytes ); @@ -159,7 +159,7 @@ public: KOKKOS_INLINE_FUNCTION void team_barrier() const { - #pragma omp barrier + #pragma omp barrier } template @@ -191,13 +191,13 @@ public: typedef ValueType value_type; const JoinLambdaAdapter op(op_in); - + // Make sure there is enough scratch space: typedef typename if_c< sizeof(value_type) < TEAM_REDUCE_SIZE , value_type , void >::type type ; const int n_values = TEAM_REDUCE_SIZE/sizeof(value_type); - type * team_scratch = (type*) ((char*)m_glb_scratch + TEAM_REDUCE_SIZE*omp_get_team_num()); + type * team_scratch = (type*) ((char*)m_glb_scratch + TEAM_REDUCE_SIZE*omp_get_team_num()); for(int i = m_team_rank; i < n_values; i+= m_team_size) { team_scratch[i] = value_type(); } @@ -209,7 +209,7 @@ public: team_scratch[m_team_rank%n_values]+=value; #pragma omp barrier } - + for(int d = 1; d #if defined( KOKKOS_ENABLE_QTHREADS ) -#include +#include //---------------------------------------------------------------------------- diff --git a/lib/kokkos/core/src/Threads/Kokkos_ThreadsExec.cpp b/lib/kokkos/core/src/Threads/Kokkos_ThreadsExec.cpp index 4c805310cc..35b2163ae5 100644 --- a/lib/kokkos/core/src/Threads/Kokkos_ThreadsExec.cpp +++ b/lib/kokkos/core/src/Threads/Kokkos_ThreadsExec.cpp @@ -45,14 +45,14 @@ #include #if defined( KOKKOS_ENABLE_THREADS ) -#include - #include #include #include #include #include + #include + #include #include #include @@ -80,9 +80,7 @@ const void * volatile s_current_function_arg = 0 ; struct Sentinel { Sentinel() - { - HostSpace::register_in_parallel( ThreadsExec::in_parallel ); - } + {} ~Sentinel() { @@ -122,6 +120,8 @@ void execute_function_noop( ThreadsExec & , const void * ) {} void ThreadsExec::driver(void) { + SharedAllocationRecord< void, void >::tracking_enable(); + ThreadsExec this_thread ; while ( ThreadsExec::Active == this_thread.m_pool_state ) { @@ -726,6 +726,8 @@ void ThreadsExec::initialize( unsigned thread_count , // Init the array for used for arbitrarily sized atomics Impl::init_lock_array_host_space(); + Impl::SharedAllocationRecord< void, void >::tracking_enable(); + #if defined(KOKKOS_ENABLE_PROFILING) Kokkos::Profiling::initialize(); #endif diff --git a/lib/kokkos/core/src/Threads/Kokkos_ThreadsExec.hpp b/lib/kokkos/core/src/Threads/Kokkos_ThreadsExec.hpp index 74de3a2596..7557bad7d9 100644 --- a/lib/kokkos/core/src/Threads/Kokkos_ThreadsExec.hpp +++ b/lib/kokkos/core/src/Threads/Kokkos_ThreadsExec.hpp @@ -50,11 +50,12 @@ #include #include -#include +#include #include #include +#include //---------------------------------------------------------------------------- namespace Kokkos { @@ -275,6 +276,17 @@ public: if ( ! rev_rank ) { Final::final( f , reduce_memory() ); } + + // This thread has updated 'reduce_memory()' and upon returning + // from this function will set 'm_pool_state' to inactive. + // If this is a non-root thread then setting 'm_pool_state' + // to inactive triggers another thread to exit a spinwait + // and read the 'reduce_memory'. + // Must 'memory_fence()' to guarantee that storing the update to + // 'reduce_memory()' will complete before storing the the update to + // 'm_pool_state'. + + memory_fence(); } inline @@ -627,6 +639,62 @@ inline void Threads::fence() } /* namespace Kokkos */ +//---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- + +namespace Kokkos { namespace Experimental { + +template<> +class UniqueToken< Threads, UniqueTokenScope::Instance> +{ +public: + using execution_space = Threads; + using size_type = int; + + /// \brief create object size for concurrency on the given instance + /// + /// This object should not be shared between instances + UniqueToken( execution_space const& = execution_space() ) noexcept {} + + /// \brief upper bound for acquired values, i.e. 0 <= value < size() + inline + int size() const noexcept { return Threads::thread_pool_size(); } + + /// \brief acquire value such that 0 <= value < size() + inline + int acquire() const noexcept { return Threads::thread_pool_rank(); } + + /// \brief release a value acquired by generate + inline + void release( int ) const noexcept {} +}; + +template<> +class UniqueToken< Threads, UniqueTokenScope::Global> +{ +public: + using execution_space = Threads; + using size_type = int; + + /// \brief create object size for concurrency on the given instance + /// + /// This object should not be shared between instances + UniqueToken( execution_space const& = execution_space() ) noexcept {} + + /// \brief upper bound for acquired values, i.e. 0 <= value < size() + inline + int size() const noexcept { return Threads::thread_pool_size(); } + + /// \brief acquire value such that 0 <= value < size() + inline + int acquire() const noexcept { return Threads::thread_pool_rank(); } + + /// \brief release a value acquired by generate + inline + void release( int ) const noexcept {} +}; + +}} // namespace Kokkos::Experimental //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- #endif diff --git a/lib/kokkos/core/src/Threads/Kokkos_ThreadsTeam.hpp b/lib/kokkos/core/src/Threads/Kokkos_ThreadsTeam.hpp index c12019413b..6060bf191f 100644 --- a/lib/kokkos/core/src/Threads/Kokkos_ThreadsTeam.hpp +++ b/lib/kokkos/core/src/Threads/Kokkos_ThreadsTeam.hpp @@ -50,7 +50,7 @@ #include #include -#include +#include #include #include @@ -482,6 +482,8 @@ public: void next_static() { if ( m_league_rank < m_league_end ) { + // Make sure all stores are complete before entering the barrier + memory_fence(); team_barrier(); set_team_shared(); } @@ -518,6 +520,8 @@ public: return; if ( m_league_rank < m_league_chunk_end ) { + // Make sure all stores are complete before entering the barrier + memory_fence(); team_barrier(); set_team_shared(); } diff --git a/lib/kokkos/core/src/Threads/Kokkos_Threads_Parallel.hpp b/lib/kokkos/core/src/Threads/Kokkos_Threads_Parallel.hpp index 0ee0cd3280..18ac7d26ad 100644 --- a/lib/kokkos/core/src/Threads/Kokkos_Threads_Parallel.hpp +++ b/lib/kokkos/core/src/Threads/Kokkos_Threads_Parallel.hpp @@ -55,6 +55,8 @@ #include #include +#include + //---------------------------------------------------------------------------- namespace Kokkos { @@ -174,6 +176,108 @@ public: {} }; + +// MDRangePolicy impl +template< class FunctorType , class ... Traits > +class ParallelFor< FunctorType + , Kokkos::Experimental::MDRangePolicy< Traits ... > + , Kokkos::Threads + > +{ +private: + typedef Kokkos::Experimental::MDRangePolicy< Traits ... > MDRangePolicy ; + typedef typename MDRangePolicy::impl_range_policy Policy ; + + typedef typename MDRangePolicy::work_tag WorkTag ; + + typedef typename Policy::WorkRange WorkRange ; + typedef typename Policy::member_type Member ; + + typedef typename Kokkos::Experimental::Impl::HostIterateTile< MDRangePolicy, FunctorType, typename MDRangePolicy::work_tag, void > iterate_type; + + const FunctorType m_functor ; + const MDRangePolicy m_mdr_policy ; + const Policy m_policy ; // construct as RangePolicy( 0, num_tiles ).set_chunk_size(1) in ctor + + inline static + void + exec_range( const MDRangePolicy & mdr_policy + , const FunctorType & functor + , const Member ibeg , const Member iend ) + { + #if defined( KOKKOS_ENABLE_AGGRESSIVE_VECTORIZATION ) && \ + defined( KOKKOS_ENABLE_PRAGMA_IVDEP ) + #pragma ivdep + #endif + for ( Member i = ibeg ; i < iend ; ++i ) { + iterate_type( mdr_policy, functor )( i ); + } + } + + static void exec( ThreadsExec & exec , const void * arg ) + { + exec_schedule(exec,arg); + } + + template + static + typename std::enable_if< std::is_same::value >::type + exec_schedule( ThreadsExec & exec , const void * arg ) + { + const ParallelFor & self = * ((const ParallelFor *) arg ); + + WorkRange range( self.m_policy , exec.pool_rank() , exec.pool_size() ); + + ParallelFor::exec_range + ( self.m_mdr_policy, self.m_functor , range.begin() , range.end() ); + + exec.fan_in(); + } + + template + static + typename std::enable_if< std::is_same::value >::type + exec_schedule( ThreadsExec & exec , const void * arg ) + { + const ParallelFor & self = * ((const ParallelFor *) arg ); + + WorkRange range( self.m_policy , exec.pool_rank() , exec.pool_size() ); + + exec.set_work_range(range.begin(),range.end(),self.m_policy.chunk_size()); + exec.reset_steal_target(); + exec.barrier(); + + long work_index = exec.get_work_index(); + + while(work_index != -1) { + const Member begin = static_cast(work_index) * self.m_policy.chunk_size(); + const Member end = begin + self.m_policy.chunk_size() < self.m_policy.end()?begin+self.m_policy.chunk_size():self.m_policy.end(); + + ParallelFor::exec_range + ( self.m_mdr_policy, self.m_functor , begin , end ); + work_index = exec.get_work_index(); + } + + exec.fan_in(); + } + +public: + + inline + void execute() const + { + ThreadsExec::start( & ParallelFor::exec , this ); + ThreadsExec::fence(); + } + + 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) ) + {} +}; + //---------------------------------------------------------------------------- /* ParallelFor Kokkos::Threads with TeamPolicy */ @@ -440,6 +544,169 @@ public: }; + +// MDRangePolicy impl +template< class FunctorType , class ReducerType, class ... Traits > +class ParallelReduce< FunctorType + , Kokkos::Experimental::MDRangePolicy< Traits ... > + , ReducerType + , Kokkos::Threads + > +{ +private: + + typedef Kokkos::Experimental::MDRangePolicy< Traits ... > MDRangePolicy ; + typedef typename MDRangePolicy::impl_range_policy Policy ; + + typedef typename MDRangePolicy::work_tag WorkTag ; + typedef typename Policy::WorkRange WorkRange ; + typedef typename Policy::member_type Member ; + + typedef Kokkos::Impl::if_c< std::is_same::value, FunctorType, ReducerType> ReducerConditional; + typedef typename ReducerConditional::type ReducerTypeFwd; + + typedef typename ReducerTypeFwd::value_type ValueType; + + typedef Kokkos::Impl::FunctorValueTraits< ReducerTypeFwd, WorkTag > ValueTraits ; + typedef Kokkos::Impl::FunctorValueInit< ReducerTypeFwd, WorkTag > ValueInit ; + + typedef typename ValueTraits::pointer_type pointer_type ; + typedef typename ValueTraits::reference_type reference_type ; + + using iterate_type = typename Kokkos::Experimental::Impl::HostIterateTile< MDRangePolicy + , FunctorType + , WorkTag + , ValueType + >; + + const FunctorType m_functor ; + const MDRangePolicy m_mdr_policy ; + const Policy m_policy ; // construct as RangePolicy( 0, num_tiles ).set_chunk_size(1) in ctor + const ReducerType m_reducer ; + const pointer_type m_result_ptr ; + + inline static + void + exec_range( const MDRangePolicy & mdr_policy + , const FunctorType & functor + , const Member & ibeg , const Member & iend + , reference_type update ) + { + #if defined( KOKKOS_ENABLE_AGGRESSIVE_VECTORIZATION ) && \ + defined( KOKKOS_ENABLE_PRAGMA_IVDEP ) + #pragma ivdep + #endif + for ( Member i = ibeg ; i < iend ; ++i ) { + iterate_type( mdr_policy, functor, update )( i ); + } + } + + static void + exec( ThreadsExec & exec , const void * arg ) { + exec_schedule(exec, arg); + } + + template + static + typename std::enable_if< std::is_same::value >::type + exec_schedule( ThreadsExec & exec , const void * arg ) + { + const ParallelReduce & self = * ((const ParallelReduce *) arg ); + const WorkRange range( self.m_policy, exec.pool_rank(), exec.pool_size() ); + + ParallelReduce::exec_range + ( self.m_mdr_policy, self.m_functor , range.begin() , range.end() + , ValueInit::init( ReducerConditional::select(self.m_functor , self.m_reducer) , exec.reduce_memory() ) ); + + exec.template fan_in_reduce< ReducerTypeFwd , WorkTag >( ReducerConditional::select(self.m_functor , self.m_reducer) ); + } + + template + static + typename std::enable_if< std::is_same::value >::type + exec_schedule( ThreadsExec & exec , const void * arg ) + { + const ParallelReduce & self = * ((const ParallelReduce *) arg ); + const WorkRange range( self.m_policy, exec.pool_rank(), exec.pool_size() ); + + exec.set_work_range(range.begin(),range.end(),self.m_policy.chunk_size()); + exec.reset_steal_target(); + exec.barrier(); + + long work_index = exec.get_work_index(); + reference_type update = ValueInit::init( ReducerConditional::select(self.m_functor , self.m_reducer) , exec.reduce_memory() ); + while(work_index != -1) { + const Member begin = static_cast(work_index) * self.m_policy.chunk_size(); + const Member end = begin + self.m_policy.chunk_size() < self.m_policy.end()?begin+self.m_policy.chunk_size():self.m_policy.end(); + ParallelReduce::exec_range + ( self.m_mdr_policy, self.m_functor , begin , end + , update ); + work_index = exec.get_work_index(); + } + + exec.template fan_in_reduce< ReducerTypeFwd , WorkTag >( ReducerConditional::select(self.m_functor , self.m_reducer) ); + } + +public: + + inline + void execute() const + { + ThreadsExec::resize_scratch( ValueTraits::value_size( ReducerConditional::select(m_functor , m_reducer) ) , 0 ); + + ThreadsExec::start( & ParallelReduce::exec , this ); + + ThreadsExec::fence(); + + if ( m_result_ptr ) { + + const pointer_type data = + (pointer_type) ThreadsExec::root_reduce_scratch(); + + const unsigned n = ValueTraits::value_count( ReducerConditional::select(m_functor , m_reducer) ); + for ( unsigned i = 0 ; i < n ; ++i ) { m_result_ptr[i] = data[i]; } + } + } + + template< class HostViewType > + ParallelReduce( const FunctorType & arg_functor , + const MDRangePolicy & arg_policy , + const HostViewType & arg_result_view , + typename std::enable_if< + Kokkos::is_view< HostViewType >::value && + !Kokkos::is_reducer_type::value + ,void*>::type = NULL) + : 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.ptr_on_device() ) + { + static_assert( Kokkos::is_view< HostViewType >::value + , "Kokkos::Threads reduce result must be a View" ); + + static_assert( std::is_same< typename HostViewType::memory_space , HostSpace >::value + , "Kokkos::Threads reduce result must be a View in HostSpace" ); + } + + inline + ParallelReduce( const FunctorType & arg_functor + , 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 + , Kokkos::HostSpace >::value + , "Reduction result on Kokkos::OpenMP must be a Kokkos::View in HostSpace" );*/ + } + +}; + + //---------------------------------------------------------------------------- /* ParallelReduce with Kokkos::Threads and TeamPolicy */ diff --git a/lib/kokkos/core/src/Threads/Kokkos_Threads_WorkGraphPolicy.hpp b/lib/kokkos/core/src/Threads/Kokkos_Threads_WorkGraphPolicy.hpp new file mode 100644 index 0000000000..be904a1670 --- /dev/null +++ b/lib/kokkos/core/src/Threads/Kokkos_Threads_WorkGraphPolicy.hpp @@ -0,0 +1,115 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#ifndef KOKKOS_THREADS_WORKGRAPHPOLICY_HPP +#define KOKKOS_THREADS_WORKGRAPHPOLICY_HPP + +namespace Kokkos { +namespace Impl { + +template< class FunctorType , class ... Traits > +class ParallelFor< FunctorType , + Kokkos::Experimental::WorkGraphPolicy< Traits ... > , + Kokkos::Threads + > + : public Kokkos::Impl::Experimental:: + WorkGraphExec< FunctorType, + Kokkos::Threads, + Traits ... + > +{ +private: + + typedef Kokkos::Experimental::WorkGraphPolicy< Traits ... > Policy ; + typedef Kokkos::Impl::Experimental:: + WorkGraphExec Base ; + typedef ParallelFor, + Kokkos::Threads> Self ; + + template< class TagType > + typename std::enable_if< std::is_same< TagType , void >::value >::type + exec_one(const typename Policy::member_type& i) const { + Base::m_functor( i ); + } + + template< class TagType > + typename std::enable_if< ! std::is_same< TagType , void >::value >::type + exec_one(const typename Policy::member_type& i) const { + const TagType t{} ; + Base::m_functor( t , i ); + } + + inline void exec_one_thread() const { + for (std::int32_t i; (-1 != (i = Base::before_work())); ) { + exec_one< typename Policy::work_tag >( i ); + Base::after_work(i); + } + } + + static inline void thread_main( ThreadsExec&, const void* arg ) { + const Self& self = *(static_cast(arg)); + self.exec_one_thread(); + } + +public: + + inline + void execute() + { + ThreadsExec::start( & Self::thread_main, this ); + ThreadsExec::fence(); + } + + inline + ParallelFor( const FunctorType & arg_functor + , const Policy & arg_policy ) + : Base( arg_functor, arg_policy ) + { + } +}; + +} // namespace Impl +} // namespace Kokkos + +#endif /* #define KOKKOS_THREADS_WORKGRAPHPOLICY_HPP */ diff --git a/lib/kokkos/core/src/impl/KokkosExp_Host_IterateTile.hpp b/lib/kokkos/core/src/impl/KokkosExp_Host_IterateTile.hpp index 77a1e8754d..0171b209e5 100644 --- a/lib/kokkos/core/src/impl/KokkosExp_Host_IterateTile.hpp +++ b/lib/kokkos/core/src/impl/KokkosExp_Host_IterateTile.hpp @@ -141,7 +141,6 @@ namespace Kokkos { namespace Experimental { namespace Impl { #define LOOP_ARGS_8 LOOP_ARGS_7, i7 + m_offset[7] - // New Loop Macros... // parallel_for, non-tagged #define APPLY( func, ... ) \ @@ -1010,8 +1009,6 @@ namespace Kokkos { namespace Experimental { namespace Impl { // end tagged macros - - // Structs for calling loops template < int Rank, bool IsLeft, typename IType, typename Tagged, typename Enable = void > struct Tile_Loop_Type; @@ -1279,6 +1276,19 @@ struct Tile_Loop_Type<8, IsLeft, IType, Tagged, typename std::enable_if< !std::i template using is_void = std::is_same< T , void >; +template +struct is_type_array : std::false_type +{ + using value_type = T; +}; + +template +struct is_type_array< T[] > : std::true_type +{ + using value_type = T; +}; + + template < typename RP , typename Functor , typename Tag = void @@ -1761,18 +1771,17 @@ struct HostIterateTile < RP , Functor , Tag , ValueType , typename std::enable_i RP const& m_rp; Functor const& m_func; typename std::conditional< std::is_same::value,int,Tag>::type m_tag; -// value_type & m_v; - }; -// ValueType: For reductions +// For ParallelReduce +// ValueType - scalar: For reductions template < typename RP , typename Functor , typename Tag , typename ValueType > -struct HostIterateTile < RP , Functor , Tag , ValueType , typename std::enable_if< !is_void::value >::type > +struct HostIterateTile < RP , Functor , Tag , ValueType , typename std::enable_if< !is_void::value && !is_type_array::value >::type > { using index_type = typename RP::index_type; using point_type = typename RP::point_type; @@ -2251,12 +2260,497 @@ struct HostIterateTile < RP , Functor , Tag , ValueType , typename std::enable_i }; +// For ParallelReduce +// Extra specialization for array reductions +// ValueType[]: For array reductions +template < typename RP + , typename Functor + , typename Tag + , typename ValueType + > +struct HostIterateTile < RP , Functor , Tag , ValueType , typename std::enable_if< !is_void::value && is_type_array::value >::type > +{ + using index_type = typename RP::index_type; + using point_type = typename RP::point_type; + + using value_type = typename is_type_array::value_type; // strip away the 'array-ness' [], only underlying type remains + + inline + HostIterateTile( RP const& rp, Functor const& func, value_type *v ) // v should be an array; treat as pointer for compatibility since size is not known nor needed here + : m_rp(rp) //Cuda 7.0 does not like braces... + , m_func(func) + , m_v(v) // use with non-void ValueType struct + {} + + inline + bool check_iteration_bounds( point_type& partial_tile , point_type& offset ) const { + bool is_full_tile = true; + + for ( int i = 0; i < RP::rank; ++i ) { + if ((offset[i] + m_rp.m_tile[i]) <= m_rp.m_upper[i]) { + partial_tile[i] = m_rp.m_tile[i] ; + } + else { + is_full_tile = false ; + partial_tile[i] = (m_rp.m_upper[i] - 1 - offset[i]) == 0 ? 1 + : (m_rp.m_upper[i] - m_rp.m_tile[i]) > 0 ? (m_rp.m_upper[i] - offset[i]) + : (m_rp.m_upper[i] - m_rp.m_lower[i]) ; // when single tile encloses range + } + } + + return is_full_tile ; + } // end check bounds + + + template + struct RankTag + { + typedef RankTag type; + enum { value = (int)Rank }; + }; + + +#if KOKKOS_ENABLE_NEW_LOOP_MACROS + template + inline + void + operator()(IType tile_idx) const + { + point_type m_offset; + point_type m_tiledims; + + if (RP::outer_direction == RP::Left) { + for (int i=0; i=0; --i) { + m_offset[i] = (tile_idx % m_rp.m_tile_end[i]) * m_rp.m_tile[i] + m_rp.m_lower[i] ; + tile_idx /= m_rp.m_tile_end[i]; + } + } + + //Check if offset+tiledim in bounds - if not, replace tile dims with the partial tile dims + const bool full_tile = check_iteration_bounds(m_tiledims , m_offset) ; + + Tile_Loop_Type< RP::rank, (RP::inner_direction == RP::Left), index_type, Tag >::apply( m_v, m_func, full_tile, m_offset, m_rp.m_tile, m_tiledims ); + + } + +#else + template + inline + void + operator()(IType tile_idx) const + { operator_impl( tile_idx , RankTag() ); } + // added due to compiler error when using sfinae to choose operator based on rank + + + template + inline + void operator_impl( IType tile_idx , const RankTag<2> ) const + { + point_type m_offset; + point_type m_tiledims; + + if (RP::outer_direction == RP::Left) { + for (int i=0; i=0; --i) { + m_offset[i] = (tile_idx % m_rp.m_tile_end[i]) * m_rp.m_tile[i] + m_rp.m_lower[i] ; + tile_idx /= m_rp.m_tile_end[i]; + } + } + + //Check if offset+tiledim in bounds - if not, replace tile dims with the partial tile dims + const bool full_tile = check_iteration_bounds(m_tiledims , m_offset) ; + + if (RP::inner_direction == RP::Left) { + if ( full_tile ) { +// #pragma simd + LOOP_2L(index_type, m_tiledims) { + apply( LOOP_ARGS_2 ); + } + } else { +// #pragma simd + LOOP_2L(index_type, m_tiledims) { + apply( LOOP_ARGS_2 ); + } + } + } // end RP::Left + else { + if ( full_tile ) { +// #pragma simd + LOOP_2R(index_type, m_tiledims) { + apply( LOOP_ARGS_2 ); + } + } else { +// #pragma simd + LOOP_2R(index_type, m_tiledims) { + apply( LOOP_ARGS_2 ); + } + } + } // end RP::Right + + } //end op() rank == 2 + + + template + inline + void operator_impl( IType tile_idx , const RankTag<3> ) const + { + point_type m_offset; + point_type m_tiledims; + + if (RP::outer_direction == RP::Left) { + for (int i=0; i=0; --i) { + m_offset[i] = (tile_idx % m_rp.m_tile_end[i]) * m_rp.m_tile[i] + m_rp.m_lower[i] ; + tile_idx /= m_rp.m_tile_end[i]; + } + } + + //Check if offset+tiledim in bounds - if not, replace tile dims with the partial tile dims + const bool full_tile = check_iteration_bounds(m_tiledims , m_offset) ; + + if (RP::inner_direction == RP::Left) { + if ( full_tile ) { +// #pragma simd + LOOP_3L(index_type, m_tiledims) { + apply( LOOP_ARGS_3 ); + } + } else { +// #pragma simd + LOOP_3L(index_type, m_tiledims) { + apply( LOOP_ARGS_3 ); + } + } + } // end RP::Left + else { + if ( full_tile ) { +// #pragma simd + LOOP_3R(index_type, m_tiledims) { + apply( LOOP_ARGS_3 ); + } + } else { +// #pragma simd + LOOP_3R(index_type, m_tiledims) { + apply( LOOP_ARGS_3 ); + } + } + } // end RP::Right + + } //end op() rank == 3 + + + template + inline + void operator_impl( IType tile_idx , const RankTag<4> ) const + { + point_type m_offset; + point_type m_tiledims; + + if (RP::outer_direction == RP::Left) { + for (int i=0; i=0; --i) { + m_offset[i] = (tile_idx % m_rp.m_tile_end[i]) * m_rp.m_tile[i] + m_rp.m_lower[i] ; + tile_idx /= m_rp.m_tile_end[i]; + } + } + + //Check if offset+tiledim in bounds - if not, replace tile dims with the partial tile dims + const bool full_tile = check_iteration_bounds(m_tiledims , m_offset) ; + + if (RP::inner_direction == RP::Left) { + if ( full_tile ) { +// #pragma simd + LOOP_4L(index_type, m_tiledims) { + apply( LOOP_ARGS_4 ); + } + } else { +// #pragma simd + LOOP_4L(index_type, m_tiledims) { + apply( LOOP_ARGS_4 ); + } + } + } // end RP::Left + else { + if ( full_tile ) { +// #pragma simd + LOOP_4R(index_type, m_tiledims) { + apply( LOOP_ARGS_4 ); + } + } else { +// #pragma simd + LOOP_4R(index_type, m_tiledims) { + apply( LOOP_ARGS_4 ); + } + } + } // end RP::Right + + } //end op() rank == 4 + + + template + inline + void operator_impl( IType tile_idx , const RankTag<5> ) const + { + point_type m_offset; + point_type m_tiledims; + + if (RP::outer_direction == RP::Left) { + for (int i=0; i=0; --i) { + m_offset[i] = (tile_idx % m_rp.m_tile_end[i]) * m_rp.m_tile[i] + m_rp.m_lower[i] ; + tile_idx /= m_rp.m_tile_end[i]; + } + } + + //Check if offset+tiledim in bounds - if not, replace tile dims with the partial tile dims + const bool full_tile = check_iteration_bounds(m_tiledims , m_offset) ; + + if (RP::inner_direction == RP::Left) { + if ( full_tile ) { +// #pragma simd + LOOP_5L(index_type, m_tiledims) { + apply( LOOP_ARGS_5 ); + } + } else { +// #pragma simd + LOOP_5L(index_type, m_tiledims) { + apply( LOOP_ARGS_5 ); + } + } + } // end RP::Left + else { + if ( full_tile ) { +// #pragma simd + LOOP_5R(index_type, m_tiledims) { + apply( LOOP_ARGS_5 ); + } + } else { +// #pragma simd + LOOP_5R(index_type, m_tiledims) { + apply( LOOP_ARGS_5 ); + } + } + } // end RP::Right + + } //end op() rank == 5 + + + template + inline + void operator_impl( IType tile_idx , const RankTag<6> ) const + { + point_type m_offset; + point_type m_tiledims; + + if (RP::outer_direction == RP::Left) { + for (int i=0; i=0; --i) { + m_offset[i] = (tile_idx % m_rp.m_tile_end[i]) * m_rp.m_tile[i] + m_rp.m_lower[i] ; + tile_idx /= m_rp.m_tile_end[i]; + } + } + + //Check if offset+tiledim in bounds - if not, replace tile dims with the partial tile dims + const bool full_tile = check_iteration_bounds(m_tiledims , m_offset) ; + + if (RP::inner_direction == RP::Left) { + if ( full_tile ) { +// #pragma simd + LOOP_6L(index_type, m_tiledims) { + apply( LOOP_ARGS_6 ); + } + } else { +// #pragma simd + LOOP_6L(index_type, m_tiledims) { + apply( LOOP_ARGS_6 ); + } + } + } // end RP::Left + else { + if ( full_tile ) { +// #pragma simd + LOOP_6R(index_type, m_tiledims) { + apply( LOOP_ARGS_6 ); + } + } else { +// #pragma simd + LOOP_6R(index_type, m_tiledims) { + apply( LOOP_ARGS_6 ); + } + } + } // end RP::Right + + } //end op() rank == 6 + + + template + inline + void operator_impl( IType tile_idx , const RankTag<7> ) const + { + point_type m_offset; + point_type m_tiledims; + + if (RP::outer_direction == RP::Left) { + for (int i=0; i=0; --i) { + m_offset[i] = (tile_idx % m_rp.m_tile_end[i]) * m_rp.m_tile[i] + m_rp.m_lower[i] ; + tile_idx /= m_rp.m_tile_end[i]; + } + } + + //Check if offset+tiledim in bounds - if not, replace tile dims with the partial tile dims + const bool full_tile = check_iteration_bounds(m_tiledims , m_offset) ; + + if (RP::inner_direction == RP::Left) { + if ( full_tile ) { +// #pragma simd + LOOP_7L(index_type, m_tiledims) { + apply( LOOP_ARGS_7 ); + } + } else { +// #pragma simd + LOOP_7L(index_type, m_tiledims) { + apply( LOOP_ARGS_7 ); + } + } + } // end RP::Left + else { + if ( full_tile ) { +// #pragma simd + LOOP_7R(index_type, m_tiledims) { + apply( LOOP_ARGS_7 ); + } + } else { +// #pragma simd + LOOP_7R(index_type, m_tiledims) { + apply( LOOP_ARGS_7 ); + } + } + } // end RP::Right + + } //end op() rank == 7 + + + template + inline + void operator_impl( IType tile_idx , const RankTag<8> ) const + { + point_type m_offset; + point_type m_tiledims; + + if (RP::outer_direction == RP::Left) { + for (int i=0; i=0; --i) { + m_offset[i] = (tile_idx % m_rp.m_tile_end[i]) * m_rp.m_tile[i] + m_rp.m_lower[i] ; + tile_idx /= m_rp.m_tile_end[i]; + } + } + + //Check if offset+tiledim in bounds - if not, replace tile dims with the partial tile dims + const bool full_tile = check_iteration_bounds(m_tiledims , m_offset) ; + + if (RP::inner_direction == RP::Left) { + if ( full_tile ) { +// #pragma simd + LOOP_8L(index_type, m_tiledims) { + apply( LOOP_ARGS_8 ); + } + } else { +// #pragma simd + LOOP_8L(index_type, m_tiledims) { + apply( LOOP_ARGS_8 ); + } + } + } // end RP::Left + else { + if ( full_tile ) { +// #pragma simd + LOOP_8R(index_type, m_tiledims) { + apply( LOOP_ARGS_8 ); + } + } else { +// #pragma simd + LOOP_8R(index_type, m_tiledims) { + apply( LOOP_ARGS_8 ); + } + } + } // end RP::Right + + } //end op() rank == 8 +#endif + + + template + typename std::enable_if<( sizeof...(Args) == RP::rank && std::is_same::value), void>::type + apply(Args &&... args) const + { + m_func(args... , m_v); + } + + template + typename std::enable_if<( sizeof...(Args) == RP::rank && !std::is_same::value), void>::type + apply(Args &&... args) const + { + m_func( m_tag, args... , m_v); + } + + + RP const& m_rp; + Functor const& m_func; + value_type * m_v; + typename std::conditional< std::is_same::value,int,Tag>::type m_tag; + +}; + + // ------------------------------------------------------------------ // // MDFunctor - wraps the range_policy and functor to pass to IterateTile -// Serial, Threads, OpenMP +// Used for md_parallel_{for,reduce} with Serial, Threads, OpenMP // Cuda uses DeviceIterateTile directly within md_parallel_for -// ParallelReduce +// TODO Once md_parallel_{for,reduce} removed, this can be removed + +// ParallelReduce - scalar reductions template < typename MDRange, typename Functor, typename ValueType = void > struct MDFunctor { @@ -2273,7 +2767,7 @@ struct MDFunctor inline - MDFunctor( MDRange const& range, Functor const& f, ValueType & v ) + MDFunctor( MDRange const& range, Functor const& f ) : m_range( range ) , m_func( f ) {} @@ -2290,7 +2784,6 @@ struct MDFunctor inline MDFunctor& operator=( MDFunctor && ) = default; -// KOKKOS_FORCEINLINE_FUNCTION //Caused cuda warning - __host__ warning inline void operator()(index_type t, value_type & v) const { @@ -2301,6 +2794,56 @@ struct MDFunctor Functor m_func; }; + +// ParallelReduce - array reductions +template < typename MDRange, typename Functor, typename ValueType > +struct MDFunctor< MDRange, Functor, ValueType[] > +{ + using range_policy = MDRange; + using functor_type = Functor; + using value_type = ValueType[]; + using work_tag = typename range_policy::work_tag; + using index_type = typename range_policy::index_type; + using iterate_type = typename Kokkos::Experimental::Impl::HostIterateTile< MDRange + , Functor + , work_tag + , value_type + >; + + + inline + MDFunctor( MDRange const& range, Functor const& f ) + : m_range( range ) + , m_func( f ) + , value_count( f.value_count ) + {} + + inline + MDFunctor( MDFunctor const& ) = default; + + inline + MDFunctor& operator=( MDFunctor const& ) = default; + + inline + MDFunctor( MDFunctor && ) = default; + + inline + MDFunctor& operator=( MDFunctor && ) = default; + + // FIXME Init and Join, as defined in m_func, are not working through the MDFunctor + // Best path forward is to eliminate need for MDFunctor, directly use MDRangePolicy within Parallel{For,Reduce} ?? + inline + void operator()(index_type t, value_type v) const + { + iterate_type(m_range, m_func, v)(t); + } + + MDRange m_range; + Functor m_func; + size_t value_count; +}; + + // ParallelFor template < typename MDRange, typename Functor > struct MDFunctor< MDRange, Functor, void > @@ -2349,4 +2892,3 @@ struct MDFunctor< MDRange, Functor, void > } } } //end namespace Kokkos::Experimental::Impl #endif - diff --git a/lib/kokkos/core/src/impl/Kokkos_AnalyzePolicy.hpp b/lib/kokkos/core/src/impl/Kokkos_AnalyzePolicy.hpp index c5685c5b62..3fb15c8d1e 100644 --- a/lib/kokkos/core/src/impl/Kokkos_AnalyzePolicy.hpp +++ b/lib/kokkos/core/src/impl/Kokkos_AnalyzePolicy.hpp @@ -55,16 +55,19 @@ template < typename ExecutionSpace = void , typename WorkTag = void , typename IndexType = void , typename IterationPattern = void + , typename LaunchBounds = void > struct PolicyTraitsBase { - using type = PolicyTraitsBase< ExecutionSpace, Schedule, WorkTag, IndexType, IterationPattern>; + using type = PolicyTraitsBase< ExecutionSpace, Schedule, WorkTag, IndexType, + IterationPattern, LaunchBounds>; using execution_space = ExecutionSpace; using schedule_type = Schedule; using work_tag = WorkTag; using index_type = IndexType; using iteration_pattern = IterationPattern; + using launch_bounds = LaunchBounds; }; @@ -78,6 +81,7 @@ struct SetExecutionSpace , typename PolicyBase::work_tag , typename PolicyBase::index_type , typename PolicyBase::iteration_pattern + , typename PolicyBase::launch_bounds >; }; @@ -91,6 +95,7 @@ struct SetSchedule , typename PolicyBase::work_tag , typename PolicyBase::index_type , typename PolicyBase::iteration_pattern + , typename PolicyBase::launch_bounds >; }; @@ -104,6 +109,7 @@ struct SetWorkTag , WorkTag , typename PolicyBase::index_type , typename PolicyBase::iteration_pattern + , typename PolicyBase::launch_bounds >; }; @@ -117,6 +123,7 @@ struct SetIndexType , typename PolicyBase::work_tag , IndexType , typename PolicyBase::iteration_pattern + , typename PolicyBase::launch_bounds >; }; @@ -131,6 +138,22 @@ struct SetIterationPattern , typename PolicyBase::work_tag , typename PolicyBase::index_type , IterationPattern + , typename PolicyBase::launch_bounds + >; +}; + + +template +struct SetLaunchBounds +{ + static_assert( is_void::value + , "Kokkos Error: More than one launch_bounds given" ); + using type = PolicyTraitsBase< typename PolicyBase::execution_space + , typename PolicyBase::schedule_type + , typename PolicyBase::work_tag + , typename PolicyBase::index_type + , typename PolicyBase::iteration_pattern + , LaunchBounds >; }; @@ -146,8 +169,9 @@ struct AnalyzePolicy : public , typename std::conditional< is_index_type::value , SetIndexType , typename std::conditional< std::is_integral::value , SetIndexType > , typename std::conditional< is_iteration_pattern::value, SetIterationPattern + , typename std::conditional< is_launch_bounds::value , SetLaunchBounds , SetWorkTag - >::type >::type >::type >::type>::type::type + >::type >::type >::type >::type >::type>::type::type , Traits... > {}; @@ -178,11 +202,18 @@ struct AnalyzePolicy , void // TODO set default iteration pattern , typename Base::iteration_pattern >::type; + + using launch_bounds = typename std::conditional< is_void< typename Base::launch_bounds >::value + , LaunchBounds<> + , typename Base::launch_bounds + >::type; + using type = PolicyTraitsBase< execution_space , schedule_type , work_tag , index_type , iteration_pattern + , launch_bounds >; }; diff --git a/lib/kokkos/core/src/impl/Kokkos_Atomic_Compare_Exchange_Strong.hpp b/lib/kokkos/core/src/impl/Kokkos_Atomic_Compare_Exchange_Strong.hpp index 010b15064e..5b894b037b 100644 --- a/lib/kokkos/core/src/impl/Kokkos_Atomic_Compare_Exchange_Strong.hpp +++ b/lib/kokkos/core/src/impl/Kokkos_Atomic_Compare_Exchange_Strong.hpp @@ -41,6 +41,10 @@ //@HEADER */ +#if defined( KOKKOS_ENABLE_RFO_PREFETCH ) +#include +#endif + #include #if defined( KOKKOS_ATOMIC_HPP ) && ! defined( KOKKOS_ATOMIC_COMPARE_EXCHANGE_STRONG_HPP ) #define KOKKOS_ATOMIC_COMPARE_EXCHANGE_STRONG_HPP @@ -126,11 +130,21 @@ T atomic_compare_exchange( volatile T * const dest , const T & compare , inline int atomic_compare_exchange( volatile int * const dest, const int compare, const int val) -{ return __sync_val_compare_and_swap(dest,compare,val); } +{ +#if defined( KOKKOS_ENABLE_RFO_PREFETCH ) + _mm_prefetch( (const char*) dest, _MM_HINT_ET0 ); +#endif + return __sync_val_compare_and_swap(dest,compare,val); +} inline long atomic_compare_exchange( volatile long * const dest, const long compare, const long val ) -{ return __sync_val_compare_and_swap(dest,compare,val); } +{ +#if defined( KOKKOS_ENABLE_RFO_PREFETCH ) + _mm_prefetch( (const char*) dest, _MM_HINT_ET0 ); +#endif + return __sync_val_compare_and_swap(dest,compare,val); +} #if defined( KOKKOS_ENABLE_GNU_ATOMICS ) @@ -159,6 +173,10 @@ T atomic_compare_exchange( volatile T * const dest, const T & compare, KOKKOS_INLINE_FUNCTION U() {}; } tmp ; +#if defined( KOKKOS_ENABLE_RFO_PREFETCH ) + _mm_prefetch( (const char*) dest, _MM_HINT_ET0 ); +#endif + tmp.i = __sync_val_compare_and_swap( (int*) dest , *((int*)&compare) , *((int*)&val) ); return tmp.t ; } @@ -175,6 +193,10 @@ T atomic_compare_exchange( volatile T * const dest, const T & compare, KOKKOS_INLINE_FUNCTION U() {}; } tmp ; +#if defined( KOKKOS_ENABLE_RFO_PREFETCH ) + _mm_prefetch( (const char*) dest, _MM_HINT_ET0 ); +#endif + tmp.i = __sync_val_compare_and_swap( (long*) dest , *((long*)&compare) , *((long*)&val) ); return tmp.t ; } @@ -193,6 +215,10 @@ T atomic_compare_exchange( volatile T * const dest, const T & compare, KOKKOS_INLINE_FUNCTION U() {}; } tmp ; +#if defined( KOKKOS_ENABLE_RFO_PREFETCH ) + _mm_prefetch( (const char*) dest, _MM_HINT_ET0 ); +#endif + tmp.i = Impl::cas128( (Impl::cas128_t*) dest , *((Impl::cas128_t*)&compare) , *((Impl::cas128_t*)&val) ); return tmp.t ; } @@ -209,6 +235,10 @@ T atomic_compare_exchange( volatile T * const dest , const T compare , #endif , const T >::type& val ) { +#if defined( KOKKOS_ENABLE_RFO_PREFETCH ) + _mm_prefetch( (const char*) dest, _MM_HINT_ET0 ); +#endif + while( !Impl::lock_address_host_space( (void*) dest ) ); T return_val = *dest; if( return_val == compare ) { diff --git a/lib/kokkos/core/src/impl/Kokkos_Atomic_Decrement.hpp b/lib/kokkos/core/src/impl/Kokkos_Atomic_Decrement.hpp index 127de528f5..2a13a4865c 100644 --- a/lib/kokkos/core/src/impl/Kokkos_Atomic_Decrement.hpp +++ b/lib/kokkos/core/src/impl/Kokkos_Atomic_Decrement.hpp @@ -41,6 +41,10 @@ //@HEADER */ +#if defined( KOKKOS_ENABLE_RFO_PREFETCH ) +#include +#endif + #include #if defined( KOKKOS_ATOMIC_HPP) && ! defined( KOKKOS_ATOMIC_DECREMENT_HPP ) #define KOKKOS_ATOMIC_DECREMENT_HPP @@ -54,6 +58,10 @@ template<> KOKKOS_INLINE_FUNCTION void atomic_decrement(volatile char* a) { #if defined( KOKKOS_ENABLE_ASM ) && defined( KOKKOS_ENABLE_ISA_X86_64 ) && ! defined(_WIN32) && ! defined(__CUDA_ARCH__) +#if defined( KOKKOS_ENABLE_RFO_PREFETCH ) + _mm_prefetch( (const char*) a, _MM_HINT_ET0 ); +#endif + __asm__ __volatile__( "lock decb %0" : /* no output registers */ @@ -69,6 +77,10 @@ template<> KOKKOS_INLINE_FUNCTION void atomic_decrement(volatile short* a) { #if defined( KOKKOS_ENABLE_ASM ) && defined( KOKKOS_ENABLE_ISA_X86_64 ) && ! defined(_WIN32) && ! defined(__CUDA_ARCH__) +#if defined( KOKKOS_ENABLE_RFO_PREFETCH ) + _mm_prefetch( (const char*) a, _MM_HINT_ET0 ); +#endif + __asm__ __volatile__( "lock decw %0" : /* no output registers */ @@ -84,6 +96,10 @@ template<> KOKKOS_INLINE_FUNCTION void atomic_decrement(volatile int* a) { #if defined( KOKKOS_ENABLE_ASM ) && defined( KOKKOS_ENABLE_ISA_X86_64 ) && ! defined(_WIN32) && ! defined(__CUDA_ARCH__) +#if defined( KOKKOS_ENABLE_RFO_PREFETCH ) + _mm_prefetch( (const char*) a, _MM_HINT_ET0 ); +#endif + __asm__ __volatile__( "lock decl %0" : /* no output registers */ @@ -99,6 +115,9 @@ template<> KOKKOS_INLINE_FUNCTION void atomic_decrement(volatile long long int* a) { #if defined( KOKKOS_ENABLE_ASM ) && defined( KOKKOS_ENABLE_ISA_X86_64 ) && ! defined(_WIN32) && ! defined(__CUDA_ARCH__) +#if defined( KOKKOS_ENABLE_RFO_PREFETCH ) + _mm_prefetch( (const char*) a, _MM_HINT_ET0 ); +#endif __asm__ __volatile__( "lock decq %0" : /* no output registers */ diff --git a/lib/kokkos/core/src/impl/Kokkos_Atomic_Exchange.hpp b/lib/kokkos/core/src/impl/Kokkos_Atomic_Exchange.hpp index a1ff47abce..9ba3cae9fc 100644 --- a/lib/kokkos/core/src/impl/Kokkos_Atomic_Exchange.hpp +++ b/lib/kokkos/core/src/impl/Kokkos_Atomic_Exchange.hpp @@ -41,6 +41,10 @@ //@HEADER */ +#if defined( KOKKOS_ENABLE_RFO_PREFETCH ) +#include +#endif + #include #if defined( KOKKOS_ATOMIC_HPP ) && ! defined( KOKKOS_ATOMIC_EXCHANGE_HPP ) #define KOKKOS_ATOMIC_EXCHANGE_HPP @@ -81,6 +85,10 @@ T atomic_exchange( typename Kokkos::Impl::enable_if< sizeof(T) == sizeof(int) , const T & >::type val ) { // int tmp = __ullAtomicExch( (int*) dest , *((int*)&val) ); +#if defined( KOKKOS_ENABLE_RFO_PREFETCH ) + _mm_prefetch( (const char*) dest, _MM_HINT_ET0 ); +#endif + int tmp = atomicExch( ((int*)dest) , *((int*)&val) ); return *((T*)&tmp); } @@ -93,6 +101,11 @@ T atomic_exchange( sizeof(T) == sizeof(unsigned long long int) , const T & >::type val ) { typedef unsigned long long int type ; + +#if defined( KOKKOS_ENABLE_RFO_PREFETCH ) + _mm_prefetch( (const char*) dest, _MM_HINT_ET0 ); +#endif + // type tmp = __ullAtomicExch( (type*) dest , *((type*)&val) ); type tmp = atomicExch( ((type*)dest) , *((type*)&val) ); return *((T*)&tmp); @@ -108,6 +121,10 @@ T atomic_exchange( volatile T * const dest , { T return_val; // This is a way to (hopefully) avoid dead lock in a warp +#if defined( KOKKOS_ENABLE_RFO_PREFETCH ) + _mm_prefetch( (const char*) dest, _MM_HINT_ET0 ); +#endif + int done = 0; unsigned int active = __ballot(1); unsigned int done_active = 0; @@ -173,6 +190,9 @@ T atomic_exchange( volatile T * const dest , , const T & >::type val ) { typedef typename Kokkos::Impl::if_c< sizeof(T) == sizeof(int) , int , long >::type type ; +#if defined( KOKKOS_ENABLE_RFO_PREFETCH ) + _mm_prefetch( (const char*) dest, _MM_HINT_ET0 ); +#endif const type v = *((type*)&val); // Extract to be sure the value doesn't change @@ -201,6 +221,10 @@ T atomic_exchange( volatile T * const dest , typename Kokkos::Impl::enable_if< sizeof(T) == sizeof(Impl::cas128_t) , const T & >::type val ) { +#if defined( KOKKOS_ENABLE_RFO_PREFETCH ) + _mm_prefetch( (const char*) dest, _MM_HINT_ET0 ); +#endif + union U { Impl::cas128_t i ; T t ; @@ -260,6 +284,10 @@ void atomic_assign( volatile T * const dest , { typedef typename Kokkos::Impl::if_c< sizeof(T) == sizeof(int) , int , long >::type type ; +#if defined( KOKKOS_ENABLE_RFO_PREFETCH ) + _mm_prefetch( (const char*) dest, _MM_HINT_ET0 ); +#endif + const type v = *((type*)&val); // Extract to be sure the value doesn't change type assumed ; @@ -285,6 +313,10 @@ void atomic_assign( volatile T * const dest , typename Kokkos::Impl::enable_if< sizeof(T) == sizeof(Impl::cas128_t) , const T & >::type val ) { +#if defined( KOKKOS_ENABLE_RFO_PREFETCH ) + _mm_prefetch( (const char*) dest, _MM_HINT_ET0 ); +#endif + union U { Impl::cas128_t i ; T t ; diff --git a/lib/kokkos/core/src/impl/Kokkos_Atomic_Fetch_Add.hpp b/lib/kokkos/core/src/impl/Kokkos_Atomic_Fetch_Add.hpp index 860c8e0e43..084c55efed 100644 --- a/lib/kokkos/core/src/impl/Kokkos_Atomic_Fetch_Add.hpp +++ b/lib/kokkos/core/src/impl/Kokkos_Atomic_Fetch_Add.hpp @@ -41,6 +41,10 @@ //@HEADER */ +#if defined( KOKKOS_ENABLE_RFO_PREFETCH ) +#include +#endif + #include #if defined( KOKKOS_ATOMIC_HPP ) && ! defined( KOKKOS_ATOMIC_FETCH_ADD_HPP ) #define KOKKOS_ATOMIC_FETCH_ADD_HPP @@ -161,36 +165,60 @@ T atomic_fetch_add( volatile T * const dest , inline int atomic_fetch_add( volatile int * dest , const int val ) { - int original = val; +#if defined( KOKKOS_ENABLE_RFO_PREFETCH ) + _mm_prefetch( (const char*) dest, _MM_HINT_ET0 ); +#endif - __asm__ __volatile__( - "lock xadd %1, %0" - : "+m" (*dest), "+r" (original) - : "m" (*dest), "r" (original) - : "memory" + int original = val; + + __asm__ __volatile__( + "lock xadd %1, %0" + : "+m" (*dest), "+r" (original) + : "m" (*dest), "r" (original) + : "memory" ); - return original; + return original; } #else inline int atomic_fetch_add( volatile int * const dest , const int val ) -{ return __sync_fetch_and_add(dest, val); } +{ +#if defined( KOKKOS_ENABLE_RFO_PREFETCH ) + _mm_prefetch( (const char*) dest, _MM_HINT_ET0 ); +#endif + return __sync_fetch_and_add(dest, val); +} #endif inline long int atomic_fetch_add( volatile long int * const dest , const long int val ) -{ return __sync_fetch_and_add(dest,val); } +{ +#if defined( KOKKOS_ENABLE_RFO_PREFETCH ) + _mm_prefetch( (const char*) dest, _MM_HINT_ET0 ); +#endif + return __sync_fetch_and_add(dest,val); +} #if defined( KOKKOS_ENABLE_GNU_ATOMICS ) inline unsigned int atomic_fetch_add( volatile unsigned int * const dest , const unsigned int val ) -{ return __sync_fetch_and_add(dest,val); } +{ +#if defined( KOKKOS_ENABLE_RFO_PREFETCH ) + _mm_prefetch( (const char*) dest, _MM_HINT_ET0 ); +#endif + return __sync_fetch_and_add(dest,val); +} inline unsigned long int atomic_fetch_add( volatile unsigned long int * const dest , const unsigned long int val ) -{ return __sync_fetch_and_add(dest,val); } +{ +#if defined( KOKKOS_ENABLE_RFO_PREFETCH ) + _mm_prefetch( (const char*) dest, _MM_HINT_ET0 ); +#endif + return __sync_fetch_and_add(dest,val); +} #endif @@ -205,6 +233,10 @@ T atomic_fetch_add( volatile T * const dest , inline U() {}; } assume , oldval , newval ; +#if defined( KOKKOS_ENABLE_RFO_PREFETCH ) + _mm_prefetch( (const char*) dest, _MM_HINT_ET0 ); +#endif + oldval.t = *dest ; do { @@ -228,6 +260,10 @@ T atomic_fetch_add( volatile T * const dest , inline U() {}; } assume , oldval , newval ; +#if defined( KOKKOS_ENABLE_RFO_PREFETCH ) + _mm_prefetch( (const char*) dest, _MM_HINT_ET0 ); +#endif + oldval.t = *dest ; do { @@ -253,6 +289,10 @@ T atomic_fetch_add( volatile T * const dest , inline U() {}; } assume , oldval , newval ; +#if defined( KOKKOS_ENABLE_RFO_PREFETCH ) + _mm_prefetch( (const char*) dest, _MM_HINT_ET0 ); +#endif + oldval.t = *dest ; do { diff --git a/lib/kokkos/core/src/impl/Kokkos_Atomic_Fetch_And.hpp b/lib/kokkos/core/src/impl/Kokkos_Atomic_Fetch_And.hpp index 83f5b2a5aa..6ecb65336c 100644 --- a/lib/kokkos/core/src/impl/Kokkos_Atomic_Fetch_And.hpp +++ b/lib/kokkos/core/src/impl/Kokkos_Atomic_Fetch_And.hpp @@ -41,6 +41,10 @@ //@HEADER */ +#if defined( KOKKOS_ENABLE_RFO_PREFETCH ) +#include +#endif + #include #if defined( KOKKOS_ATOMIC_HPP ) && ! defined( KOKKOS_ATOMIC_FETCH_AND_HPP ) #define KOKKOS_ATOMIC_FETCH_AND_HPP @@ -76,21 +80,41 @@ unsigned long long int atomic_fetch_and( volatile unsigned long long int * const inline int atomic_fetch_and( volatile int * const dest , const int val ) -{ return __sync_fetch_and_and(dest,val); } +{ +#if defined( KOKKOS_ENABLE_RFO_PREFETCH ) + _mm_prefetch( (const char*) dest, _MM_HINT_ET0 ); +#endif + return __sync_fetch_and_and(dest,val); +} inline long int atomic_fetch_and( volatile long int * const dest , const long int val ) -{ return __sync_fetch_and_and(dest,val); } +{ +#if defined( KOKKOS_ENABLE_RFO_PREFETCH ) + _mm_prefetch( (const char*) dest, _MM_HINT_ET0 ); +#endif + return __sync_fetch_and_and(dest,val); +} #if defined( KOKKOS_ENABLE_GNU_ATOMICS ) inline unsigned int atomic_fetch_and( volatile unsigned int * const dest , const unsigned int val ) -{ return __sync_fetch_and_and(dest,val); } +{ +#if defined( KOKKOS_ENABLE_RFO_PREFETCH ) + _mm_prefetch( (const char*) dest, _MM_HINT_ET0 ); +#endif + return __sync_fetch_and_and(dest,val); +} inline unsigned long int atomic_fetch_and( volatile unsigned long int * const dest , const unsigned long int val ) -{ return __sync_fetch_and_and(dest,val); } +{ +#if defined( KOKKOS_ENABLE_RFO_PREFETCH ) + _mm_prefetch( (const char*) dest, _MM_HINT_ET0 ); +#endif + return __sync_fetch_and_and(dest,val); +} #endif diff --git a/lib/kokkos/core/src/impl/Kokkos_Atomic_Fetch_Or.hpp b/lib/kokkos/core/src/impl/Kokkos_Atomic_Fetch_Or.hpp index 8c73b4c3ef..ed3b438f89 100644 --- a/lib/kokkos/core/src/impl/Kokkos_Atomic_Fetch_Or.hpp +++ b/lib/kokkos/core/src/impl/Kokkos_Atomic_Fetch_Or.hpp @@ -41,6 +41,10 @@ //@HEADER */ +#if defined( KOKKOS_ENABLE_RFO_PREFETCH ) +#include +#endif + #include #if defined( KOKKOS_ATOMIC_HPP ) && ! defined( KOKKOS_ATOMIC_FETCH_OR_HPP ) #define KOKKOS_ATOMIC_FETCH_OR_HPP @@ -76,21 +80,41 @@ unsigned long long int atomic_fetch_or( volatile unsigned long long int * const inline int atomic_fetch_or( volatile int * const dest , const int val ) -{ return __sync_fetch_and_or(dest,val); } +{ +#if defined( KOKKOS_ENABLE_RFO_PREFETCH ) + _mm_prefetch( (const char*) dest, _MM_HINT_ET0 ); +#endif + return __sync_fetch_and_or(dest,val); +} inline long int atomic_fetch_or( volatile long int * const dest , const long int val ) -{ return __sync_fetch_and_or(dest,val); } +{ +#if defined( KOKKOS_ENABLE_RFO_PREFETCH ) + _mm_prefetch( (const char*) dest, _MM_HINT_ET0 ); +#endif + return __sync_fetch_and_or(dest,val); +} #if defined( KOKKOS_ENABLE_GNU_ATOMICS ) inline unsigned int atomic_fetch_or( volatile unsigned int * const dest , const unsigned int val ) -{ return __sync_fetch_and_or(dest,val); } +{ +#if defined( KOKKOS_ENABLE_RFO_PREFETCH ) + _mm_prefetch( (const char*) dest, _MM_HINT_ET0 ); +#endif + return __sync_fetch_and_or(dest,val); +} inline unsigned long int atomic_fetch_or( volatile unsigned long int * const dest , const unsigned long int val ) -{ return __sync_fetch_and_or(dest,val); } +{ +#if defined( KOKKOS_ENABLE_RFO_PREFETCH ) + _mm_prefetch( (const char*) dest, _MM_HINT_ET0 ); +#endif + return __sync_fetch_and_or(dest,val); +} #endif diff --git a/lib/kokkos/core/src/impl/Kokkos_Atomic_Fetch_Sub.hpp b/lib/kokkos/core/src/impl/Kokkos_Atomic_Fetch_Sub.hpp index 504731d3a2..038cc13e9a 100644 --- a/lib/kokkos/core/src/impl/Kokkos_Atomic_Fetch_Sub.hpp +++ b/lib/kokkos/core/src/impl/Kokkos_Atomic_Fetch_Sub.hpp @@ -41,6 +41,10 @@ //@HEADER */ +#if defined( KOKKOS_ENABLE_RFO_PREFETCH ) +#include +#endif + #include #if defined( KOKKOS_ATOMIC_HPP ) && ! defined( KOKKOS_ATOMIC_FETCH_SUB_HPP ) #define KOKKOS_ATOMIC_FETCH_SUB_HPP @@ -136,21 +140,41 @@ T atomic_fetch_sub( volatile T * const dest , inline int atomic_fetch_sub( volatile int * const dest , const int val ) -{ return __sync_fetch_and_sub(dest,val); } +{ +#if defined( KOKKOS_ENABLE_RFO_PREFETCH ) + _mm_prefetch( (const char*) dest, _MM_HINT_ET0 ); +#endif + return __sync_fetch_and_sub(dest,val); +} inline long int atomic_fetch_sub( volatile long int * const dest , const long int val ) -{ return __sync_fetch_and_sub(dest,val); } +{ +#if defined( KOKKOS_ENABLE_RFO_PREFETCH ) + _mm_prefetch( (const char*) dest, _MM_HINT_ET0 ); +#endif + return __sync_fetch_and_sub(dest,val); +} #if defined( KOKKOS_ENABLE_GNU_ATOMICS ) inline unsigned int atomic_fetch_sub( volatile unsigned int * const dest , const unsigned int val ) -{ return __sync_fetch_and_sub(dest,val); } +{ +#if defined( KOKKOS_ENABLE_RFO_PREFETCH ) + _mm_prefetch( (const char*) dest, _MM_HINT_ET0 ); +#endif + return __sync_fetch_and_sub(dest,val); +} inline unsigned long int atomic_fetch_sub( volatile unsigned long int * const dest , const unsigned long int val ) -{ return __sync_fetch_and_sub(dest,val); } +{ +#if defined( KOKKOS_ENABLE_RFO_PREFETCH ) + _mm_prefetch( (const char*) dest, _MM_HINT_ET0 ); +#endif + return __sync_fetch_and_sub(dest,val); +} #endif @@ -161,6 +185,10 @@ T atomic_fetch_sub( volatile T * const dest , { union { int i ; T t ; } assume , oldval , newval ; +#if defined( KOKKOS_ENABLE_RFO_PREFETCH ) + _mm_prefetch( (const char*) dest, _MM_HINT_ET0 ); +#endif + oldval.t = *dest ; do { @@ -178,6 +206,10 @@ T atomic_fetch_sub( volatile T * const dest , typename Kokkos::Impl::enable_if< sizeof(T) != sizeof(int) && sizeof(T) == sizeof(long) , const T >::type val ) { +#if defined( KOKKOS_ENABLE_RFO_PREFETCH ) + _mm_prefetch( (const char*) dest, _MM_HINT_ET0 ); +#endif + union { long i ; T t ; } assume , oldval , newval ; oldval.t = *dest ; @@ -202,6 +234,10 @@ T atomic_fetch_sub( volatile T * const dest , && ( sizeof(T) != 8 ) , const T >::type& val ) { +#if defined( KOKKOS_ENABLE_RFO_PREFETCH ) + _mm_prefetch( (const char*) dest, _MM_HINT_ET0 ); +#endif + while( !Impl::lock_address_host_space( (void*) dest ) ); T return_val = *dest; *dest = return_val - val; diff --git a/lib/kokkos/core/src/impl/Kokkos_Atomic_Increment.hpp b/lib/kokkos/core/src/impl/Kokkos_Atomic_Increment.hpp index 2985fad95e..e7626603fc 100644 --- a/lib/kokkos/core/src/impl/Kokkos_Atomic_Increment.hpp +++ b/lib/kokkos/core/src/impl/Kokkos_Atomic_Increment.hpp @@ -41,6 +41,10 @@ //@HEADER */ +#if defined( KOKKOS_ENABLE_RFO_PREFETCH ) +#include +#endif + #include #if defined( KOKKOS_ATOMIC_HPP) && ! defined( KOKKOS_ATOMIC_INCREMENT_HPP ) #define KOKKOS_ATOMIC_INCREMENT_HPP @@ -52,6 +56,9 @@ template<> KOKKOS_INLINE_FUNCTION void atomic_increment(volatile char* a) { #if defined( KOKKOS_ENABLE_ASM ) && defined( KOKKOS_ENABLE_ISA_X86_64 ) && ! defined(_WIN32) && ! defined(__CUDA_ARCH__) +#if defined( KOKKOS_ENABLE_RFO_PREFETCH ) + _mm_prefetch( (const char*) a, _MM_HINT_ET0 ); +#endif __asm__ __volatile__( "lock incb %0" : /* no output registers */ @@ -67,6 +74,9 @@ template<> KOKKOS_INLINE_FUNCTION void atomic_increment(volatile short* a) { #if defined( KOKKOS_ENABLE_ASM ) && defined( KOKKOS_ENABLE_ISA_X86_64 ) && ! defined(_WIN32) && ! defined(__CUDA_ARCH__) +#if defined( KOKKOS_ENABLE_RFO_PREFETCH ) + _mm_prefetch( (const char*) a, _MM_HINT_ET0 ); +#endif __asm__ __volatile__( "lock incw %0" : /* no output registers */ @@ -82,6 +92,9 @@ template<> KOKKOS_INLINE_FUNCTION void atomic_increment(volatile int* a) { #if defined( KOKKOS_ENABLE_ASM ) && defined( KOKKOS_ENABLE_ISA_X86_64 ) && ! defined(_WIN32) && ! defined(__CUDA_ARCH__) +#if defined( KOKKOS_ENABLE_RFO_PREFETCH ) + _mm_prefetch( (const char*) a, _MM_HINT_ET0 ); +#endif __asm__ __volatile__( "lock incl %0" : /* no output registers */ @@ -97,6 +110,9 @@ template<> KOKKOS_INLINE_FUNCTION void atomic_increment(volatile long long int* a) { #if defined( KOKKOS_ENABLE_ASM ) && defined( KOKKOS_ENABLE_ISA_X86_64 ) && ! defined(_WIN32) && ! defined(__CUDA_ARCH__) +#if defined( KOKKOS_ENABLE_RFO_PREFETCH ) + _mm_prefetch( (const char*) a, _MM_HINT_ET0 ); +#endif __asm__ __volatile__( "lock incq %0" : /* no output registers */ diff --git a/lib/kokkos/core/src/impl/Kokkos_Core.cpp b/lib/kokkos/core/src/impl/Kokkos_Core.cpp index f0ff6d78ec..f52cc469ac 100644 --- a/lib/kokkos/core/src/impl/Kokkos_Core.cpp +++ b/lib/kokkos/core/src/impl/Kokkos_Core.cpp @@ -87,17 +87,12 @@ setenv("MEMKIND_HBW_NODES", "1", 0); #if defined( KOKKOS_ENABLE_OPENMP ) if( std::is_same< Kokkos::OpenMP , Kokkos::DefaultExecutionSpace >::value || std::is_same< Kokkos::OpenMP , Kokkos::HostSpace::execution_space >::value ) { - if(num_threads>0) { - if(use_numa>0) { - Kokkos::OpenMP::initialize(num_threads,use_numa); - } - else { - Kokkos::OpenMP::initialize(num_threads); - } - } else { - Kokkos::OpenMP::initialize(); + if(use_numa>0) { + Kokkos::OpenMP::initialize(num_threads,use_numa); + } + else { + Kokkos::OpenMP::initialize(num_threads); } - //std::cout << "Kokkos::initialize() fyi: OpenMP enabled and initialized" << std::endl ; } else { //std::cout << "Kokkos::initialize() fyi: OpenMP enabled but not initialized" << std::endl ; @@ -437,10 +432,7 @@ void initialize(int& narg, char* arg[]) iarg++; } - InitArguments arguments; - arguments.num_threads = num_threads; - arguments.num_numa = numa; - arguments.device_id = device; + InitArguments arguments{num_threads, numa, device}; Impl::initialize_internal(arguments); } diff --git a/lib/kokkos/core/src/impl/Kokkos_FunctorAdapter.hpp b/lib/kokkos/core/src/impl/Kokkos_FunctorAdapter.hpp index dc75fb072f..fccd8e090f 100644 --- a/lib/kokkos/core/src/impl/Kokkos_FunctorAdapter.hpp +++ b/lib/kokkos/core/src/impl/Kokkos_FunctorAdapter.hpp @@ -170,28 +170,31 @@ struct FunctorValueTraits< FunctorType , ArgTag , true /* == exists FunctorType: static_assert( 0 == ( sizeof(value_type) % sizeof(int) ) , "Reduction functor's declared value_type requires: 0 == sizeof(value_type) % sizeof(int)" ); + /* this cast to bool is needed for correctness by NVCC */ + enum : bool { IsArray = static_cast(Impl::is_array< typename FunctorType::value_type >::value) }; + // If not an array then what is the sizeof(value_type) - enum { StaticValueSize = Impl::is_array< typename FunctorType::value_type >::value ? 0 : sizeof(value_type) }; + enum { StaticValueSize = IsArray ? 0 : sizeof(value_type) }; typedef value_type * pointer_type ; // The reference_type for an array is 'value_type *' // The reference_type for a single value is 'value_type &' - typedef typename Impl::if_c< ! StaticValueSize , value_type * - , value_type & >::type reference_type ; + typedef typename Impl::if_c< IsArray , value_type * + , value_type & >::type reference_type ; // Number of values if single value template< class F > KOKKOS_FORCEINLINE_FUNCTION static - typename Impl::enable_if< std::is_same::value && StaticValueSize , unsigned >::type + typename Impl::enable_if< std::is_same::value && ! IsArray , unsigned >::type value_count( const F & ) { return 1 ; } // Number of values if an array, protect via templating because 'f.value_count' // will only exist when the functor declares the value_type to be an array. template< class F > KOKKOS_FORCEINLINE_FUNCTION static - typename Impl::enable_if< std::is_same::value && ! StaticValueSize , unsigned >::type + typename Impl::enable_if< std::is_same::value && IsArray , unsigned >::type value_count( const F & f ) { return f.value_count ; } // Total size of the value diff --git a/lib/kokkos/core/src/impl/Kokkos_HBWSpace.cpp b/lib/kokkos/core/src/impl/Kokkos_HBWSpace.cpp index 8cb7430035..e11f8b6d34 100644 --- a/lib/kokkos/core/src/impl/Kokkos_HBWSpace.cpp +++ b/lib/kokkos/core/src/impl/Kokkos_HBWSpace.cpp @@ -70,62 +70,6 @@ #ifdef KOKKOS_ENABLE_HBWSPACE #define MEMKIND_TYPE MEMKIND_HBW //hbw_get_kind(HBW_PAGESIZE_4KB) -namespace Kokkos { -namespace Experimental { -namespace { - -static const int QUERY_SPACE_IN_PARALLEL_MAX = 16 ; - -typedef int (* QuerySpaceInParallelPtr )(); - -QuerySpaceInParallelPtr s_in_parallel_query[ QUERY_SPACE_IN_PARALLEL_MAX ] ; -int s_in_parallel_query_count = 0 ; - -} // namespace - -void HBWSpace::register_in_parallel( int (*device_in_parallel)() ) -{ - if ( 0 == device_in_parallel ) { - Kokkos::Impl::throw_runtime_exception( std::string("Kokkos::Experimental::HBWSpace::register_in_parallel ERROR : given NULL" ) ); - } - - int i = -1 ; - - if ( ! (device_in_parallel)() ) { - for ( i = 0 ; i < s_in_parallel_query_count && ! (*(s_in_parallel_query[i]))() ; ++i ); - } - - if ( i < s_in_parallel_query_count ) { - Kokkos::Impl::throw_runtime_exception( std::string("Kokkos::Experimental::HBWSpace::register_in_parallel_query ERROR : called in_parallel" ) ); - - } - - if ( QUERY_SPACE_IN_PARALLEL_MAX <= i ) { - Kokkos::Impl::throw_runtime_exception( std::string("Kokkos::Experimental::HBWSpace::register_in_parallel_query ERROR : exceeded maximum" ) ); - - } - - for ( i = 0 ; i < s_in_parallel_query_count && s_in_parallel_query[i] != device_in_parallel ; ++i ); - - if ( i == s_in_parallel_query_count ) { - s_in_parallel_query[s_in_parallel_query_count++] = device_in_parallel ; - } -} - -int HBWSpace::in_parallel() -{ - const int n = s_in_parallel_query_count ; - - int i = 0 ; - - while ( i < n && ! (*(s_in_parallel_query[i]))() ) { ++i ; } - - return i < n ; -} - -} // namespace Experiemtal -} // namespace Kokkos - /*--------------------------------------------------------------------------*/ namespace Kokkos { diff --git a/lib/kokkos/core/src/impl/Kokkos_HostSpace.cpp b/lib/kokkos/core/src/impl/Kokkos_HostSpace.cpp index 2a5c34c375..a5a73ddebb 100644 --- a/lib/kokkos/core/src/impl/Kokkos_HostSpace.cpp +++ b/lib/kokkos/core/src/impl/Kokkos_HostSpace.cpp @@ -106,62 +106,6 @@ //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- -namespace Kokkos { -namespace { - -static const int QUERY_SPACE_IN_PARALLEL_MAX = 16 ; - -typedef int (* QuerySpaceInParallelPtr )(); - -QuerySpaceInParallelPtr s_in_parallel_query[ QUERY_SPACE_IN_PARALLEL_MAX ] ; -int s_in_parallel_query_count = 0 ; - -} // namespace - -void HostSpace::register_in_parallel( int (*device_in_parallel)() ) -{ - if ( 0 == device_in_parallel ) { - Kokkos::Impl::throw_runtime_exception( std::string("Kokkos::HostSpace::register_in_parallel ERROR : given NULL" ) ); - } - - int i = -1 ; - - if ( ! (device_in_parallel)() ) { - for ( i = 0 ; i < s_in_parallel_query_count && ! (*(s_in_parallel_query[i]))() ; ++i ); - } - - if ( i < s_in_parallel_query_count ) { - Kokkos::Impl::throw_runtime_exception( std::string("Kokkos::HostSpace::register_in_parallel_query ERROR : called in_parallel" ) ); - - } - - if ( QUERY_SPACE_IN_PARALLEL_MAX <= i ) { - Kokkos::Impl::throw_runtime_exception( std::string("Kokkos::HostSpace::register_in_parallel_query ERROR : exceeded maximum" ) ); - - } - - for ( i = 0 ; i < s_in_parallel_query_count && s_in_parallel_query[i] != device_in_parallel ; ++i ); - - if ( i == s_in_parallel_query_count ) { - s_in_parallel_query[s_in_parallel_query_count++] = device_in_parallel ; - } -} - -int HostSpace::in_parallel() -{ - const int n = s_in_parallel_query_count ; - - int i = 0 ; - - while ( i < n && ! (*(s_in_parallel_query[i]))() ) { ++i ; } - - return i < n ; -} - -} // namespace Kokkos - -/*--------------------------------------------------------------------------*/ - namespace Kokkos { /* Default allocation mechanism */ @@ -340,9 +284,6 @@ void HostSpace::deallocate( void * const arg_alloc_ptr , const size_t arg_alloc_ } } -constexpr const char* HostSpace::name() { - return m_name; -} } // namespace Kokkos //---------------------------------------------------------------------------- diff --git a/lib/kokkos/core/src/impl/Kokkos_HostThreadTeam.cpp b/lib/kokkos/core/src/impl/Kokkos_HostThreadTeam.cpp index ac200209c7..d2446bde09 100644 --- a/lib/kokkos/core/src/impl/Kokkos_HostThreadTeam.cpp +++ b/lib/kokkos/core/src/impl/Kokkos_HostThreadTeam.cpp @@ -45,7 +45,7 @@ #include #include #include -#include +#include //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- @@ -58,9 +58,11 @@ void HostThreadTeamData::organize_pool { bool ok = true ; + memory_fence(); + // Verify not already a member of a pool: for ( int rank = 0 ; rank < size && ok ; ++rank ) { - ok = ( 0 != members[rank] ) && ( 0 == members[rank]->m_pool_scratch ); + ok = ( nullptr != members[rank] ) && ( 0 == members[rank]->m_pool_scratch ); } if ( ok ) { @@ -89,7 +91,6 @@ void HostThreadTeamData::organize_pool mem->m_team_alloc = 1 ; mem->m_league_rank = rank ; mem->m_league_size = size ; - mem->m_pool_rendezvous_step = 0 ; mem->m_team_rendezvous_step = 0 ; pool[ rank ] = mem ; } @@ -116,7 +117,6 @@ void HostThreadTeamData::disband_pool() m_team_alloc = 1 ; m_league_rank = 0 ; m_league_size = 1 ; - m_pool_rendezvous_step = 0 ; m_team_rendezvous_step = 0 ; } @@ -256,11 +256,6 @@ int HostThreadTeamData::rendezvous( int64_t * const buffer const int sync_offset = ( step & mask_mem_cycle ) + size_mem_cycle ; - union { - int64_t full ; - int8_t byte[8] ; - } value ; - if ( rank ) { const int group_begin = rank << shift_byte ; // == rank * size_byte @@ -275,13 +270,14 @@ int HostThreadTeamData::rendezvous( int64_t * const buffer const int end = group_begin + size_byte < size ? size_byte : size - group_begin ; - value.full = 0 ; - for ( int i = 0 ; i < end ; ++i ) value.byte[i] = int8_t( step ); + int64_t value = 0 ; - store_fence(); // This should not be needed but fixes #742 + for ( int i = 0 ; i < end ; ++i ) { + ((int8_t*) & value )[i] = int8_t( step ); + } spinwait_until_equal( buffer[ (rank << shift_mem_cycle) + sync_offset ] - , value.full ); + , value ); } { @@ -316,10 +312,12 @@ int HostThreadTeamData::rendezvous( int64_t * const buffer const int end = size_byte < size ? 8 : size ; - value.full = 0 ; - for ( int i = 1 ; i < end ; ++i ) value.byte[i] = int8_t( step ); + int64_t value = 0 ; + for ( int i = 1 ; i < end ; ++i ) { + ((int8_t *) & value)[i] = int8_t( step ); + } - spinwait_until_equal( buffer[ sync_offset ], value.full ); + spinwait_until_equal( buffer[ sync_offset ], value ); } return rank ? 0 : 1 ; diff --git a/lib/kokkos/core/src/impl/Kokkos_HostThreadTeam.hpp b/lib/kokkos/core/src/impl/Kokkos_HostThreadTeam.hpp index c050a16eae..7facc0a410 100644 --- a/lib/kokkos/core/src/impl/Kokkos_HostThreadTeam.hpp +++ b/lib/kokkos/core/src/impl/Kokkos_HostThreadTeam.hpp @@ -50,6 +50,7 @@ #include #include #include +#include //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- @@ -67,14 +68,12 @@ public: // Assume upper bounds on number of threads: // pool size <= 1024 threads - // pool rendezvous <= ( 1024 / 8 ) * 4 + 4 = 2052 // team size <= 64 threads - // team rendezvous <= ( 64 / 8 ) * 4 + 4 = 36 enum : int { max_pool_members = 1024 }; enum : int { max_team_members = 64 }; - enum : int { max_pool_rendezvous = ( max_pool_members / 8 ) * 4 + 4 }; - enum : int { max_team_rendezvous = ( max_team_members / 8 ) * 4 + 4 }; + enum : int { max_pool_rendezvous = rendezvous_buffer_size( max_pool_members ) }; + enum : int { max_team_rendezvous = rendezvous_buffer_size( max_team_members ) }; private: @@ -114,7 +113,6 @@ private: int m_league_size ; int m_work_chunk ; int m_steal_rank ; // work stealing rank - int mutable m_pool_rendezvous_step ; int mutable m_team_rendezvous_step ; HostThreadTeamData * team_member( int r ) const noexcept @@ -147,6 +145,7 @@ public: int team_rendezvous( int const root ) const noexcept { return 1 == m_team_size ? 1 : + HostThreadTeamData:: rendezvous( m_team_scratch + m_team_rendezvous , m_team_rendezvous_step , m_team_size @@ -157,6 +156,7 @@ public: int team_rendezvous() const noexcept { return 1 == m_team_size ? 1 : + HostThreadTeamData:: rendezvous( m_team_scratch + m_team_rendezvous , m_team_rendezvous_step , m_team_size @@ -167,6 +167,7 @@ public: void team_rendezvous_release() const noexcept { if ( 1 < m_team_size ) { + HostThreadTeamData:: rendezvous_release( m_team_scratch + m_team_rendezvous , m_team_rendezvous_step ); } @@ -175,19 +176,30 @@ public: inline int pool_rendezvous() const noexcept { + static constexpr int yield_wait = + #if defined( KOKKOS_COMPILER_IBM ) + // If running on IBM POWER architecture the global + // level rendzvous should immediately yield when + // waiting for other threads in the pool to arrive. + 1 + #else + 0 + #endif + ; return 1 == m_pool_size ? 1 : + Kokkos::Impl:: rendezvous( m_pool_scratch + m_pool_rendezvous - , m_pool_rendezvous_step , m_pool_size - , m_pool_rank ); + , m_pool_rank + , yield_wait ); } inline void pool_rendezvous_release() const noexcept { if ( 1 < m_pool_size ) { - rendezvous_release( m_pool_scratch + m_pool_rendezvous - , m_pool_rendezvous_step ); + Kokkos::Impl:: + rendezvous_release( m_pool_scratch + m_pool_rendezvous ); } } @@ -213,7 +225,6 @@ public: , m_league_size(1) , m_work_chunk(0) , m_steal_rank(0) - , m_pool_rendezvous_step(0) , m_team_rendezvous_step(0) {} @@ -406,7 +417,7 @@ fflush(stdout); // Steal from next team, round robin // The next team is offset by m_team_alloc if it fits in the pool. - m_steal_rank = m_team_base + m_team_alloc + m_team_size <= m_pool_size ? + m_steal_rank = m_team_base + m_team_alloc + m_team_size <= m_pool_size ? m_team_base + m_team_alloc : 0 ; } diff --git a/lib/kokkos/core/src/impl/Kokkos_Profiling_Interface.cpp b/lib/kokkos/core/src/impl/Kokkos_Profiling_Interface.cpp index 98482cfab6..608d514c79 100644 --- a/lib/kokkos/core/src/impl/Kokkos_Profiling_Interface.cpp +++ b/lib/kokkos/core/src/impl/Kokkos_Profiling_Interface.cpp @@ -50,51 +50,70 @@ namespace Kokkos { namespace Profiling { +static initFunction initProfileLibrary = nullptr; +static finalizeFunction finalizeProfileLibrary = nullptr; + +static beginFunction beginForCallee = nullptr; +static beginFunction beginScanCallee = nullptr; +static beginFunction beginReduceCallee = nullptr; +static endFunction endForCallee = nullptr; +static endFunction endScanCallee = nullptr; +static endFunction endReduceCallee = nullptr; + +static pushFunction pushRegionCallee = nullptr; +static popFunction popRegionCallee = nullptr; + +static allocateDataFunction allocateDataCallee = nullptr; +static deallocateDataFunction deallocateDataCallee = nullptr; + +static beginDeepCopyFunction beginDeepCopyCallee = nullptr; +static endDeepCopyFunction endDeepCopyCallee = nullptr; + SpaceHandle::SpaceHandle(const char* space_name) { strncpy(name,space_name,64); } bool profileLibraryLoaded() { - return (NULL != initProfileLibrary); + return (nullptr != initProfileLibrary); } void beginParallelFor(const std::string& kernelPrefix, const uint32_t devID, uint64_t* kernelID) { - if(NULL != beginForCallee) { + if(nullptr != beginForCallee) { Kokkos::fence(); (*beginForCallee)(kernelPrefix.c_str(), devID, kernelID); } } void endParallelFor(const uint64_t kernelID) { - if(NULL != endForCallee) { + if(nullptr != endForCallee) { Kokkos::fence(); (*endForCallee)(kernelID); } } void beginParallelScan(const std::string& kernelPrefix, const uint32_t devID, uint64_t* kernelID) { - if(NULL != beginScanCallee) { + if(nullptr != beginScanCallee) { Kokkos::fence(); (*beginScanCallee)(kernelPrefix.c_str(), devID, kernelID); } } void endParallelScan(const uint64_t kernelID) { - if(NULL != endScanCallee) { + if(nullptr != endScanCallee) { Kokkos::fence(); (*endScanCallee)(kernelID); } } void beginParallelReduce(const std::string& kernelPrefix, const uint32_t devID, uint64_t* kernelID) { - if(NULL != beginReduceCallee) { + if(nullptr != beginReduceCallee) { Kokkos::fence(); (*beginReduceCallee)(kernelPrefix.c_str(), devID, kernelID); } } void endParallelReduce(const uint64_t kernelID) { - if(NULL != endReduceCallee) { + if(nullptr != endReduceCallee) { Kokkos::fence(); (*endReduceCallee)(kernelID); } @@ -102,31 +121,47 @@ void endParallelReduce(const uint64_t kernelID) { void pushRegion(const std::string& kName) { - if( NULL != pushRegionCallee ) { + if( nullptr != pushRegionCallee ) { Kokkos::fence(); (*pushRegionCallee)(kName.c_str()); } } void popRegion() { - if( NULL != popRegionCallee ) { + if( nullptr != popRegionCallee ) { Kokkos::fence(); (*popRegionCallee)(); } } void allocateData(const SpaceHandle space, const std::string label, const void* ptr, const uint64_t size) { - if(NULL != allocateDataCallee) { + if(nullptr != allocateDataCallee) { (*allocateDataCallee)(space,label.c_str(),ptr,size); } } void deallocateData(const SpaceHandle space, const std::string label, const void* ptr, const uint64_t size) { - if(NULL != allocateDataCallee) { + if(nullptr != deallocateDataCallee) { (*deallocateDataCallee)(space,label.c_str(),ptr,size); } } +void beginDeepCopy(const SpaceHandle dst_space, const std::string dst_label, const void* dst_ptr, + const SpaceHandle src_space, const std::string src_label, const void* src_ptr, + const uint64_t size) { + if(nullptr != beginDeepCopyCallee) { + (*beginDeepCopyCallee)(dst_space, dst_label.c_str(), dst_ptr, + src_space, src_label.c_str(), src_ptr, + size); + } +} + +void endDeepCopy() { + if(nullptr != endDeepCopyCallee) { + (*endDeepCopyCallee)(); + } +} + void initialize() { // Make sure initialize calls happens only once @@ -140,7 +175,7 @@ void initialize() { // If we do not find a profiling library in the environment then exit // early. - if( NULL == envProfileLibrary ) { + if( nullptr == envProfileLibrary ) { return ; } @@ -149,10 +184,10 @@ void initialize() { char* profileLibraryName = strtok(envProfileCopy, ";"); - if( (NULL != profileLibraryName) && (strcmp(profileLibraryName, "") != 0) ) { + if( (nullptr != profileLibraryName) && (strcmp(profileLibraryName, "") != 0) ) { firstProfileLibrary = dlopen(profileLibraryName, RTLD_NOW | RTLD_GLOBAL); - if(NULL == firstProfileLibrary) { + if(nullptr == firstProfileLibrary) { std::cerr << "Error: Unable to load KokkosP library: " << profileLibraryName << std::endl; } else { @@ -191,14 +226,19 @@ void initialize() { auto p12 = dlsym(firstProfileLibrary, "kokkosp_deallocate_data"); deallocateDataCallee = *((deallocateDataFunction*) &p12); + auto p13 = dlsym(firstProfileLibrary, "kokkosp_begin_deep_copy"); + beginDeepCopyCallee = *((beginDeepCopyFunction*) &p13); + auto p14 = dlsym(firstProfileLibrary, "kokkosp_end_deep_copy"); + endDeepCopyCallee = *((endDeepCopyFunction*) &p14); + } } - if(NULL != initProfileLibrary) { + if(nullptr != initProfileLibrary) { (*initProfileLibrary)(0, (uint64_t) KOKKOSP_INTERFACE_VERSION, (uint32_t) 0, - NULL); + nullptr); } free(envProfileCopy); @@ -210,28 +250,30 @@ void finalize() { if(is_finalized) return; is_finalized = 1; - if(NULL != finalizeProfileLibrary) { + if(nullptr != finalizeProfileLibrary) { (*finalizeProfileLibrary)(); - // Set all profile hooks to NULL to prevent + // Set all profile hooks to nullptr to prevent // any additional calls. Once we are told to // finalize, we mean it - initProfileLibrary = NULL; - finalizeProfileLibrary = NULL; + initProfileLibrary = nullptr; + finalizeProfileLibrary = nullptr; - beginForCallee = NULL; - beginScanCallee = NULL; - beginReduceCallee = NULL; - endScanCallee = NULL; - endForCallee = NULL; - endReduceCallee = NULL; + beginForCallee = nullptr; + beginScanCallee = nullptr; + beginReduceCallee = nullptr; + endScanCallee = nullptr; + endForCallee = nullptr; + endReduceCallee = nullptr; - pushRegionCallee = NULL; - popRegionCallee = NULL; + pushRegionCallee = nullptr; + popRegionCallee = nullptr; - allocateDataCallee = NULL; - deallocateDataCallee = NULL; + allocateDataCallee = nullptr; + deallocateDataCallee = nullptr; + beginDeepCopyCallee = nullptr; + endDeepCopyCallee = nullptr; } } } diff --git a/lib/kokkos/core/src/impl/Kokkos_Profiling_Interface.hpp b/lib/kokkos/core/src/impl/Kokkos_Profiling_Interface.hpp index f76e5dfa04..2c2e524d9d 100644 --- a/lib/kokkos/core/src/impl/Kokkos_Profiling_Interface.hpp +++ b/lib/kokkos/core/src/impl/Kokkos_Profiling_Interface.hpp @@ -81,23 +81,11 @@ typedef void (*popFunction)(); typedef void (*allocateDataFunction)(const SpaceHandle, const char*, const void*, const uint64_t); typedef void (*deallocateDataFunction)(const SpaceHandle, const char*, const void*, const uint64_t); - -static initFunction initProfileLibrary = NULL; -static finalizeFunction finalizeProfileLibrary = NULL; - -static beginFunction beginForCallee = NULL; -static beginFunction beginScanCallee = NULL; -static beginFunction beginReduceCallee = NULL; -static endFunction endForCallee = NULL; -static endFunction endScanCallee = NULL; -static endFunction endReduceCallee = NULL; - -static pushFunction pushRegionCallee = NULL; -static popFunction popRegionCallee = NULL; - -static allocateDataFunction allocateDataCallee = NULL; -static deallocateDataFunction deallocateDataCallee = NULL; - +typedef void (*beginDeepCopyFunction)( + SpaceHandle, const char*, const void*, + SpaceHandle, const char*, const void*, + uint64_t); +typedef void (*endDeepCopyFunction)(); bool profileLibraryLoaded(); @@ -114,35 +102,14 @@ void popRegion(); void allocateData(const SpaceHandle space, const std::string label, const void* ptr, const uint64_t size); void deallocateData(const SpaceHandle space, const std::string label, const void* ptr, const uint64_t size); +void beginDeepCopy(const SpaceHandle dst_space, const std::string dst_label, const void* dst_ptr, + const SpaceHandle src_space, const std::string src_label, const void* src_ptr, + const uint64_t size); +void endDeepCopy(); + void initialize(); void finalize(); -//Define finalize_fake inline to get rid of warnings for unused static variables -inline void finalize_fake() { - if(NULL != finalizeProfileLibrary) { - (*finalizeProfileLibrary)(); - - // Set all profile hooks to NULL to prevent - // any additional calls. Once we are told to - // finalize, we mean it - beginForCallee = NULL; - beginScanCallee = NULL; - beginReduceCallee = NULL; - endScanCallee = NULL; - endForCallee = NULL; - endReduceCallee = NULL; - - allocateDataCallee = NULL; - deallocateDataCallee = NULL; - - initProfileLibrary = NULL; - finalizeProfileLibrary = NULL; - pushRegionCallee = NULL; - popRegionCallee = NULL; - } -} - - } } diff --git a/lib/kokkos/core/src/impl/Kokkos_Rendezvous.cpp b/lib/kokkos/core/src/impl/Kokkos_Rendezvous.cpp new file mode 100644 index 0000000000..ac697fce4b --- /dev/null +++ b/lib/kokkos/core/src/impl/Kokkos_Rendezvous.cpp @@ -0,0 +1,208 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include +#include +#include +#include + +namespace Kokkos { namespace Impl { + +//---------------------------------------------------------------------------- +/* pattern for rendezvous + * + * if ( rendezvous() ) { + * ... all other threads are still in team_rendezvous() ... + * rendezvous_release(); + * ... all other threads are released from team_rendezvous() ... + * } + */ + +int rendezvous( volatile int64_t * const buffer + , int const size + , int const rank + , int const slow + ) noexcept +{ + enum : int { shift_byte = 3 }; + enum : int { size_byte = ( 01 << shift_byte ) }; // == 8 + enum : int { mask_byte = size_byte - 1 }; + + enum : int { shift_mem_cycle = 2 }; + enum : int { size_mem_cycle = ( 01 << shift_mem_cycle ) }; // == 4 + enum : int { mask_mem_cycle = size_mem_cycle - 1 }; + + // Cycle step values: 1 <= step <= size_val_cycle + // An odd multiple of memory cycle so that when a memory location + // is reused it has a different value. + // Must be representable within a single byte: size_val_cycle < 16 + + enum : int { size_val_cycle = 3 * size_mem_cycle }; + + // Requires: + // Called by rank = [ 0 .. size ) + // buffer aligned to int64_t[4] + + // A sequence of rendezvous uses four cycled locations in memory + // and non-equal cycled synchronization values to + // 1) prevent rendezvous from overtaking one another and + // 2) give each spin wait location an int64_t[4] span + // so that it has its own cache line. + + const int64_t step = (buffer[0] % size_val_cycle ) + 1 ; + + // The leading int64_t[4] span is for thread 0 to write + // and all other threads to read spin-wait. + // sync_offset is the index into this array for this step. + + const int sync_offset = ( step & mask_mem_cycle ) + size_mem_cycle + size_mem_cycle ; + + if ( rank ) { + + const int group_begin = rank << shift_byte ; // == rank * size_byte + + if ( group_begin < size ) { + + // This thread waits for threads + // [ group_begin .. group_begin + 8 ) + // [ rank*8 .. rank*8 + 8 ) + // to write to their designated bytes. + + const int end = group_begin + size_byte < size + ? size_byte : size - group_begin ; + + int64_t value = 0; + for ( int i = 0 ; i < end ; ++i ) { + value |= step << (i * size_byte ); + } + + store_fence(); // This should not be needed but fixes #742 + + if ( slow ) { + yield_until_equal( buffer[ (rank << shift_mem_cycle) + sync_offset ] + , value ); + } + else { + spinwait_until_equal( buffer[ (rank << shift_mem_cycle) + sync_offset ] + , value ); + } + } + + { + // This thread sets its designated byte. + // ( rank % size_byte ) + + // ( ( rank / size_byte ) * size_byte * size_mem_cycle ) + + // ( sync_offset * size_byte ) + const int offset = ( rank & mask_byte ) + + ( ( rank & ~mask_byte ) << shift_mem_cycle ) + + ( sync_offset << shift_byte ); + + // All of this thread's previous memory stores must be complete before + // this thread stores the step value at this thread's designated byte + // in the shared synchronization array. + + Kokkos::memory_fence(); + + ((volatile int8_t*) buffer)[ offset ] = int8_t( step ); + + // Memory fence to push the previous store out + Kokkos::memory_fence(); + } + + // Wait for thread 0 to release all other threads + + if ( slow ) { + yield_until_equal( buffer[ (step & mask_mem_cycle) + size_mem_cycle ] , int64_t(step) ); + } + else { + spinwait_until_equal( buffer[ (step & mask_mem_cycle) + size_mem_cycle ] , int64_t(step) ); + } + } + else { + // Thread 0 waits for threads [1..7] + // to write to their designated bytes. + + const int end = size_byte < size ? 8 : size ; + + int64_t value = 0; + for ( int i = 1 ; i < end ; ++i ) { + value |= step << (i * size_byte ); + } + + if ( slow ) { + yield_until_equal( buffer[ sync_offset ], value ); + } + else { + spinwait_until_equal( buffer[ sync_offset ], value ); + } + } + + return rank ? 0 : 1 ; +} + +void rendezvous_release( volatile int64_t * const buffer ) noexcept +{ + enum : int { shift_mem_cycle = 2 }; + enum : int { size_mem_cycle = ( 01 << shift_mem_cycle ) }; // == 4 + enum : int { mask_mem_cycle = size_mem_cycle - 1 }; + enum : int { size_val_cycle = 3 * size_mem_cycle }; + + // Requires: + // Called after team_rendezvous + // Called only by true == team_rendezvous(root) + + // update step + const int64_t step = (buffer[0] % size_val_cycle ) + 1; + buffer[0] = step; + + // Memory fence to be sure all previous writes are complete: + Kokkos::memory_fence(); + + buffer[ (step & mask_mem_cycle) + size_mem_cycle ] = step; + + // Memory fence to push the store out + Kokkos::memory_fence(); +} + +}} // namespace Kokkos::Impl + diff --git a/lib/kokkos/core/src/impl/Kokkos_Rendezvous.hpp b/lib/kokkos/core/src/impl/Kokkos_Rendezvous.hpp new file mode 100644 index 0000000000..57f8633bca --- /dev/null +++ b/lib/kokkos/core/src/impl/Kokkos_Rendezvous.hpp @@ -0,0 +1,87 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#ifndef KOKKOS_IMPL_RENDEZVOUS_HPP +#define KOKKOS_IMPL_RENDEZVOUS_HPP + +#include + +namespace Kokkos { namespace Impl { + +inline +constexpr int rendezvous_buffer_size( int max_members ) noexcept +{ + return (((max_members + 7) / 8) * 4) + 4 + 4; +} + +/** \brief Thread pool rendezvous + * + * Rendezvous pattern: + * if ( rendezvous(root) ) { + * ... only root thread here while all others wait ... + * rendezvous_release(); + * } + * else { + * ... all other threads release here ... + * } + * + * Requires: buffer[ rendezvous_buffer_size( max_threads ) ]; + * + * When slow != 0 the expectation is thread arrival will be + * slow so the threads that arrive early should quickly yield + * their core to the runtime thus possibly allowing the late + * arriving threads to have more resources + * (e.g., power and clock frequency). + */ +int rendezvous( volatile int64_t * const buffer + , int const size + , int const rank + , int const slow = 0 ) noexcept ; + +void rendezvous_release( volatile int64_t * const buffer ) noexcept ; + + +}} // namespace Kokkos::Impl + +#endif // KOKKOS_IMPL_RENDEZVOUS_HPP + diff --git a/lib/kokkos/core/src/impl/Kokkos_Serial.cpp b/lib/kokkos/core/src/impl/Kokkos_Serial.cpp index 755271c07e..dfbeba461e 100644 --- a/lib/kokkos/core/src/impl/Kokkos_Serial.cpp +++ b/lib/kokkos/core/src/impl/Kokkos_Serial.cpp @@ -50,6 +50,7 @@ #include #include +#include /*--------------------------------------------------------------------------*/ @@ -123,7 +124,6 @@ void serial_resize_thread_team_data( size_t pool_reduce_bytes } } -// Get thread team data structure for omp_get_thread_num() HostThreadTeamData * serial_get_thread_team_data() { return & g_serial_thread_team_data ; @@ -151,6 +151,8 @@ void Serial::initialize( unsigned threads_count (void) use_cores_per_numa; (void) allow_asynchronous_threadpool; + Impl::SharedAllocationRecord< void, void >::tracking_enable(); + // Init the array of locks used for arbitrarily sized atomics Impl::init_lock_array_host_space(); #if defined(KOKKOS_ENABLE_PROFILING) diff --git a/lib/kokkos/core/src/impl/Kokkos_Serial_Task.cpp b/lib/kokkos/core/src/impl/Kokkos_Serial_Task.cpp index 76297161b1..0b6fbd9af0 100644 --- a/lib/kokkos/core/src/impl/Kokkos_Serial_Task.cpp +++ b/lib/kokkos/core/src/impl/Kokkos_Serial_Task.cpp @@ -62,7 +62,7 @@ void TaskQueueSpecialization< Kokkos::Serial >::execute { using execution_space = Kokkos::Serial ; using queue_type = TaskQueue< execution_space > ; - using task_root_type = TaskBase< execution_space , void , void > ; + using task_root_type = TaskBase< void , void , void > ; using Member = Impl::HostThreadTeamMember< execution_space > ; task_root_type * const end = (task_root_type *) task_root_type::EndTag ; @@ -122,7 +122,7 @@ void TaskQueueSpecialization< Kokkos::Serial > :: { using execution_space = Kokkos::Serial ; using queue_type = TaskQueue< execution_space > ; - using task_root_type = TaskBase< execution_space , void , void > ; + using task_root_type = TaskBase< void , void , void > ; using Member = Impl::HostThreadTeamMember< execution_space > ; task_root_type * const end = (task_root_type *) task_root_type::EndTag ; diff --git a/lib/kokkos/core/src/impl/Kokkos_Serial_Task.hpp b/lib/kokkos/core/src/impl/Kokkos_Serial_Task.hpp index 2eb2b5cf52..39deebbbf1 100644 --- a/lib/kokkos/core/src/impl/Kokkos_Serial_Task.hpp +++ b/lib/kokkos/core/src/impl/Kokkos_Serial_Task.hpp @@ -65,7 +65,7 @@ public: using execution_space = Kokkos::Serial ; using memory_space = Kokkos::HostSpace ; using queue_type = Kokkos::Impl::TaskQueue< execution_space > ; - using task_base_type = Kokkos::Impl::TaskBase< execution_space , void , void > ; + using task_base_type = Kokkos::Impl::TaskBase< void , void , void > ; using member_type = Kokkos::Impl::HostThreadTeamMember< execution_space > ; static diff --git a/lib/kokkos/core/src/impl/Kokkos_Serial_WorkGraphPolicy.hpp b/lib/kokkos/core/src/impl/Kokkos_Serial_WorkGraphPolicy.hpp new file mode 100644 index 0000000000..dc30ffe9e0 --- /dev/null +++ b/lib/kokkos/core/src/impl/Kokkos_Serial_WorkGraphPolicy.hpp @@ -0,0 +1,102 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#ifndef KOKKOS_SERIAL_WORKGRAPHPOLICY_HPP +#define KOKKOS_SERIAL_WORKGRAPHPOLICY_HPP + +namespace Kokkos { +namespace Impl { + +template< class FunctorType , class ... Traits > +class ParallelFor< FunctorType , + Kokkos::Experimental::WorkGraphPolicy< Traits ... > , + Kokkos::Serial + > + : public Kokkos::Impl::Experimental:: + WorkGraphExec< FunctorType, + Kokkos::Serial, + Traits ... + > +{ +private: + + typedef Kokkos::Experimental::WorkGraphPolicy< Traits ... > Policy ; + typedef Kokkos::Impl::Experimental:: + WorkGraphExec Base ; + + template< class TagType > + typename std::enable_if< std::is_same< TagType , void >::value >::type + exec_one(const typename Policy::member_type& i) const { + Base::m_functor( i ); + } + + template< class TagType > + typename std::enable_if< ! std::is_same< TagType , void >::value >::type + exec_one(const typename Policy::member_type& i) const { + const TagType t{} ; + Base::m_functor( t , i ); + } + +public: + + inline + void execute() + { + for (std::int32_t i; (-1 != (i = Base::before_work())); ) { + exec_one< typename Policy::work_tag >( i ); + Base::after_work(i); + } + } + + inline + ParallelFor( const FunctorType & arg_functor + , const Policy & arg_policy ) + : Base( arg_functor, arg_policy ) + { + } +}; + +} // namespace Impl +} // namespace Kokkos + +#endif /* #define KOKKOS_SERIAL_WORKGRAPHPOLICY_HPP */ diff --git a/lib/kokkos/core/src/impl/Kokkos_SharedAlloc.cpp b/lib/kokkos/core/src/impl/Kokkos_SharedAlloc.cpp index e28c1194a7..af79523e0c 100644 --- a/lib/kokkos/core/src/impl/Kokkos_SharedAlloc.cpp +++ b/lib/kokkos/core/src/impl/Kokkos_SharedAlloc.cpp @@ -46,23 +46,23 @@ namespace Kokkos { namespace Impl { -int SharedAllocationRecord< void , void >::s_tracking_enabled = 1 ; +namespace { -void SharedAllocationRecord< void , void >::tracking_claim_and_disable() -{ - // A host thread claim and disable tracking flag +__thread int t_tracking_enabled = 1; - while ( ! Kokkos::atomic_compare_exchange_strong( & s_tracking_enabled, 1, 0 ) ); } -void SharedAllocationRecord< void , void >::tracking_release_and_enable() -{ - // The host thread that claimed and disabled the tracking flag - // now release and enable tracking. +int SharedAllocationRecord< void , void >::tracking_enabled() +{ return t_tracking_enabled; } - if ( ! Kokkos::atomic_compare_exchange_strong( & s_tracking_enabled, 0, 1 ) ){ - Kokkos::Impl::throw_runtime_exception("Kokkos::Impl::SharedAllocationRecord<>::tracking_release_and_enable FAILED, this host process thread did not hold the lock" ); - } +void SharedAllocationRecord< void , void >::tracking_disable() +{ + t_tracking_enabled = 0; +} + +void SharedAllocationRecord< void , void >::tracking_enable() +{ + t_tracking_enabled = 1; } //---------------------------------------------------------------------------- diff --git a/lib/kokkos/core/src/impl/Kokkos_SharedAlloc.hpp b/lib/kokkos/core/src/impl/Kokkos_SharedAlloc.hpp index 4dc61bb02e..2e3cc1a163 100644 --- a/lib/kokkos/core/src/impl/Kokkos_SharedAlloc.hpp +++ b/lib/kokkos/core/src/impl/Kokkos_SharedAlloc.hpp @@ -71,6 +71,9 @@ public: KOKKOS_INLINE_FUNCTION static const SharedAllocationHeader * get_header( void * alloc_ptr ) { return reinterpret_cast( reinterpret_cast(alloc_ptr) - sizeof(SharedAllocationHeader) ); } + + KOKKOS_INLINE_FUNCTION + const char* label() const { return m_label; } }; template<> @@ -83,8 +86,6 @@ protected: typedef void (* function_type )( SharedAllocationRecord * ); - static int s_tracking_enabled ; - SharedAllocationHeader * const m_alloc_ptr ; size_t const m_alloc_size ; function_type const m_dealloc ; @@ -110,17 +111,17 @@ protected: public: inline std::string get_label() const { return std::string("Unmanaged"); } - static int tracking_enabled() { return s_tracking_enabled ; } + static int tracking_enabled(); /**\brief A host process thread claims and disables the * shared allocation tracking flag. */ - static void tracking_claim_and_disable(); + static void tracking_disable(); /**\brief A host process thread releases and enables the * shared allocation tracking flag. */ - static void tracking_release_and_enable(); + static void tracking_enable(); ~SharedAllocationRecord() = default ; @@ -317,6 +318,11 @@ public: #endif } + KOKKOS_INLINE_FUNCTION + bool has_record() const { + return (m_record_bits & (~DO_NOT_DEREF_FLAG)) != 0; + } + KOKKOS_FORCEINLINE_FUNCTION ~SharedAllocationTracker() { KOKKOS_IMPL_SHARED_ALLOCATION_TRACKER_DECREMENT } diff --git a/lib/kokkos/core/src/impl/Kokkos_Spinwait.cpp b/lib/kokkos/core/src/impl/Kokkos_Spinwait.cpp new file mode 100644 index 0000000000..3d3f83ed85 --- /dev/null +++ b/lib/kokkos/core/src/impl/Kokkos_Spinwait.cpp @@ -0,0 +1,210 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include +#if defined( KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_HOST ) + +#include +#include +#include + +#if defined( KOKKOS_ENABLE_STDTHREAD ) + #include +#elif !defined( _WIN32 ) + #include + #include +#else + #include + #include + #include +#endif + +/*--------------------------------------------------------------------------*/ + +namespace Kokkos { +namespace Impl { +namespace { + +void host_thread_yield( const uint32_t i , const int force_yield ) +{ + static constexpr uint32_t sleep_limit = 1 << 13 ; + static constexpr uint32_t yield_limit = 1 << 12 ; + + const int c = Kokkos::Impl::bit_scan_reverse(i); + + if ( sleep_limit < i ) { + + // Attempt to put the thread to sleep for 'c' milliseconds + + #if defined( KOKKOS_ENABLE_STDTHREAD ) + std::this_thread::sleep_for( std::chrono::nanoseconds( c * 1000 ) ) + #elif !defined( _WIN32 ) + timespec req ; + req.tv_sec = 0 ; + req.tv_nsec = 1000 * c ; + nanosleep( &req, nullptr ); + #else /* defined( _WIN32 ) IS Microsoft Windows */ + Sleep(c); + #endif + } + + else if ( force_yield || yield_limit < i ) { + + // Attempt to yield thread resources to runtime + + #if defined( KOKKOS_ENABLE_STDTHREAD ) + std::this_thread::yield(); + #elif !defined( _WIN32 ) + sched_yield(); + #else /* defined( _WIN32 ) IS Microsoft Windows */ + YieldProcessor(); + #endif + } + + #if defined( KOKKOS_ENABLE_ASM ) + + else if ( (1u<<4) < i ) { + + // Insert a few no-ops to quiet the thread: + + for ( int k = 0 ; k < c ; ++k ) { + #if defined( __amd64 ) || defined( __amd64__ ) || \ + defined( __x86_64 ) || defined( __x86_64__ ) + #if !defined( _WIN32 ) /* IS NOT Microsoft Windows */ + asm volatile( "nop\n" ); + #else + __asm__ __volatile__( "nop\n" ); + #endif + #elif defined(__PPC64__) + asm volatile( "nop\n" ); + #endif + } + } + + { + // Insert memory pause + #if defined( __amd64 ) || defined( __amd64__ ) || \ + defined( __x86_64 ) || defined( __x86_64__ ) + #if !defined( _WIN32 ) /* IS NOT Microsoft Windows */ + asm volatile( "pause\n":::"memory" ); + #else + __asm__ __volatile__( "pause\n":::"memory" ); + #endif + #elif defined(__PPC64__) + asm volatile( "or 27, 27, 27" ::: "memory" ); + #endif + } + + #endif /* defined( KOKKOS_ENABLE_ASM ) */ +} + +}}} // namespace Kokkos::Impl::{anonymous} + +/*--------------------------------------------------------------------------*/ + +namespace Kokkos { +namespace Impl { + +void spinwait_while_equal( volatile int32_t & flag , const int32_t value ) +{ + Kokkos::store_fence(); + uint32_t i = 0 ; while( value == flag ) host_thread_yield(++i,0); + Kokkos::load_fence(); +} + +void spinwait_until_equal( volatile int32_t & flag , const int32_t value ) +{ + Kokkos::store_fence(); + uint32_t i = 0 ; while( value != flag ) host_thread_yield(++i,0); + Kokkos::load_fence(); +} + +void spinwait_while_equal( volatile int64_t & flag , const int64_t value ) +{ + Kokkos::store_fence(); + uint32_t i = 0 ; while( value == flag ) host_thread_yield(++i,0); + Kokkos::load_fence(); +} + +void spinwait_until_equal( volatile int64_t & flag , const int64_t value ) +{ + Kokkos::store_fence(); + uint32_t i = 0 ; while( value != flag ) host_thread_yield(++i,0); + Kokkos::load_fence(); +} + +void yield_while_equal( volatile int32_t & flag , const int32_t value ) +{ + Kokkos::store_fence(); + uint32_t i = 0 ; while( value == flag ) host_thread_yield(++i,1); + Kokkos::load_fence(); +} + +void yield_until_equal( volatile int32_t & flag , const int32_t value ) +{ + Kokkos::store_fence(); + uint32_t i = 0 ; while( value != flag ) host_thread_yield(++i,1); + Kokkos::load_fence(); +} + +void yield_while_equal( volatile int64_t & flag , const int64_t value ) +{ + Kokkos::store_fence(); + uint32_t i = 0 ; while( value == flag ) host_thread_yield(++i,1); + Kokkos::load_fence(); +} + +void yield_until_equal( volatile int64_t & flag , const int64_t value ) +{ + Kokkos::store_fence(); + uint32_t i = 0 ; while( value != flag ) host_thread_yield(++i,1); + Kokkos::load_fence(); +} + +} /* namespace Impl */ +} /* namespace Kokkos */ + +#else +void KOKKOS_CORE_SRC_IMPL_SPINWAIT_PREVENT_LINK_ERROR() {} +#endif + diff --git a/lib/kokkos/core/src/impl/Kokkos_spinwait.hpp b/lib/kokkos/core/src/impl/Kokkos_Spinwait.hpp similarity index 82% rename from lib/kokkos/core/src/impl/Kokkos_spinwait.hpp rename to lib/kokkos/core/src/impl/Kokkos_Spinwait.hpp index 6e34b8a943..b49e308566 100644 --- a/lib/kokkos/core/src/impl/Kokkos_spinwait.hpp +++ b/lib/kokkos/core/src/impl/Kokkos_Spinwait.hpp @@ -59,6 +59,13 @@ void spinwait_until_equal( volatile int32_t & flag , const int32_t value ); void spinwait_while_equal( volatile int64_t & flag , const int64_t value ); void spinwait_until_equal( volatile int64_t & flag , const int64_t value ); + +void yield_while_equal( volatile int32_t & flag , const int32_t value ); +void yield_until_equal( volatile int32_t & flag , const int32_t value ); + +void yield_while_equal( volatile int64_t & flag , const int64_t value ); +void yield_until_equal( volatile int64_t & flag , const int64_t value ); + #else KOKKOS_INLINE_FUNCTION @@ -71,6 +78,16 @@ void spinwait_while_equal( volatile int64_t & , const int64_t ) {} KOKKOS_INLINE_FUNCTION void spinwait_until_equal( volatile int64_t & , const int64_t ) {} +KOKKOS_INLINE_FUNCTION +void yield_while_equal( volatile int32_t & , const int32_t ) {} +KOKKOS_INLINE_FUNCTION +void yield_until_equal( volatile int32_t & , const int32_t ) {} + +KOKKOS_INLINE_FUNCTION +void yield_while_equal( volatile int64_t & , const int64_t ) {} +KOKKOS_INLINE_FUNCTION +void yield_until_equal( volatile int64_t & , const int64_t ) {} + #endif } /* namespace Impl */ diff --git a/lib/kokkos/core/src/impl/Kokkos_TaskQueue.hpp b/lib/kokkos/core/src/impl/Kokkos_TaskQueue.hpp index bee98e6745..5f8699302d 100644 --- a/lib/kokkos/core/src/impl/Kokkos_TaskQueue.hpp +++ b/lib/kokkos/core/src/impl/Kokkos_TaskQueue.hpp @@ -59,24 +59,15 @@ namespace Kokkos { namespace Impl { -/*\brief Implementation data for task data management, access, and execution. - * - * Curiously recurring template pattern (CRTP) - * to allow static_cast from the - * task root type and a task's FunctorType. - * - * TaskBase< Space , ResultType , FunctorType > - * : TaskBase< Space , ResultType , void > - * , FunctorType - * { ... }; - * - * TaskBase< Space , ResultType , void > - * : TaskBase< Space , void , void > - * { ... }; - */ -template< typename Space , typename ResultType , typename FunctorType > +template< class Space , typename ResultType , class FunctorType > class TaskBase ; +template< typename Space > +class TaskQueue ; + +template< typename Space > +class TaskQueueSpecialization ; + } /* namespace Impl */ } /* namespace Kokkos */ @@ -86,8 +77,217 @@ class TaskBase ; namespace Kokkos { namespace Impl { -template< typename Space > -class TaskQueueSpecialization ; +/** \brief Base class for task management, access, and execution. + * + * Inheritance structure to allow static_cast from the task root type + * and a task's FunctorType. + * + * // Enable a functor to access the base class + * // and provide memory for result value. + * TaskBase< Space , ResultType , FunctorType > + * : TaskBase< void , void , void > + * , FunctorType + * { ... }; + * Followed by memory allocated for result value. + * + * + * States of a task: + * + * Constructing State, NOT IN a linked list + * m_wait == 0 + * m_next == 0 + * + * Scheduling transition : Constructing -> Waiting + * before: + * m_wait == 0 + * m_next == this task's initial dependence, 0 if none + * after: + * m_wait == EndTag + * m_next == EndTag + * + * Waiting State, IN a linked list + * m_apply != 0 + * m_queue != 0 + * m_ref_count > 0 + * m_wait == head of linked list of tasks waiting on this task + * m_next == next of linked list of tasks + * + * transition : Waiting -> Executing + * before: + * m_next == EndTag + * after:: + * m_next == LockTag + * + * Executing State, NOT IN a linked list + * m_apply != 0 + * m_queue != 0 + * m_ref_count > 0 + * m_wait == head of linked list of tasks waiting on this task + * m_next == LockTag + * + * Respawn transition : Executing -> Executing-Respawn + * before: + * m_next == LockTag + * after: + * m_next == this task's updated dependence, 0 if none + * + * Executing-Respawn State, NOT IN a linked list + * m_apply != 0 + * m_queue != 0 + * m_ref_count > 0 + * m_wait == head of linked list of tasks waiting on this task + * m_next == this task's updated dependence, 0 if none + * + * transition : Executing -> Complete + * before: + * m_wait == head of linked list + * after: + * m_wait == LockTag + * + * Complete State, NOT IN a linked list + * m_wait == LockTag: cannot add dependence (<=> complete) + * m_next == LockTag: not a member of a wait queue + * + */ +template<> +class TaskBase< void , void , void > +{ +public: + + enum : int16_t { TaskTeam = 0 , TaskSingle = 1 , Aggregate = 2 }; + enum : uintptr_t { LockTag = ~uintptr_t(0) , EndTag = ~uintptr_t(1) }; + + template< typename > friend class Kokkos::TaskScheduler ; + + typedef TaskQueue< void > queue_type ; + + typedef void (* function_type) ( TaskBase * , void * ); + + // sizeof(TaskBase) == 48 + + function_type m_apply ; ///< Apply function pointer + queue_type * m_queue ; ///< Pointer to queue + TaskBase * m_wait ; ///< Linked list of tasks waiting on this + TaskBase * m_next ; ///< Waiting linked-list next + int32_t m_ref_count ; ///< Reference count + int32_t m_alloc_size ; ///< Allocation size + int32_t m_dep_count ; ///< Aggregate's number of dependences + int16_t m_task_type ; ///< Type of task + int16_t m_priority ; ///< Priority of runnable task + + TaskBase( TaskBase && ) = delete ; + TaskBase( const TaskBase & ) = delete ; + TaskBase & operator = ( TaskBase && ) = delete ; + TaskBase & operator = ( const TaskBase & ) = delete ; + + KOKKOS_INLINE_FUNCTION ~TaskBase() = default ; + + KOKKOS_INLINE_FUNCTION constexpr + TaskBase() + : m_apply( 0 ) + , m_queue( 0 ) + , m_wait( 0 ) + , m_next( 0 ) + , m_ref_count( 0 ) + , m_alloc_size( 0 ) + , m_dep_count( 0 ) + , m_task_type( 0 ) + , m_priority( 0 ) + {} + + //---------------------------------------- + + KOKKOS_INLINE_FUNCTION + TaskBase * volatile * aggregate_dependences() volatile + { return reinterpret_cast( this + 1 ); } + + KOKKOS_INLINE_FUNCTION + bool requested_respawn() + { + // This should only be called when a task has finished executing and is + // in the transition to either the complete or executing-respawn state. + TaskBase * const lock = reinterpret_cast< TaskBase * >( LockTag ); + return lock != m_next; + } + + KOKKOS_INLINE_FUNCTION + void add_dependence( TaskBase* dep ) + { + // Precondition: lock == m_next + + TaskBase * const lock = (TaskBase *) LockTag ; + + // Assign dependence to m_next. It will be processed in the subsequent + // call to schedule. Error if the dependence is reset. + if ( lock != Kokkos::atomic_exchange( & m_next, dep ) ) { + Kokkos::abort("TaskScheduler ERROR: resetting task dependence"); + } + + if ( 0 != dep ) { + // The future may be destroyed upon returning from this call + // so increment reference count to track this assignment. + Kokkos::atomic_increment( &(dep->m_ref_count) ); + } + } + + //---------------------------------------- + + KOKKOS_INLINE_FUNCTION + int32_t reference_count() const + { return *((int32_t volatile *)( & m_ref_count )); } + +}; + +static_assert( sizeof(TaskBase) == 48 + , "Verifying expected sizeof(TaskBase)" ); + +//---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- + +template< typename ResultType > +struct TaskResult { + + enum : int32_t { size = sizeof(ResultType) }; + + using reference_type = ResultType & ; + + KOKKOS_INLINE_FUNCTION static + ResultType * ptr( TaskBase * task ) + { + return reinterpret_cast< ResultType * > + ( reinterpret_cast< char * >(task) + task->m_alloc_size - sizeof(ResultType) ); + } + + KOKKOS_INLINE_FUNCTION static + reference_type get( TaskBase * task ) + { return *ptr( task ); } +}; + +template<> +struct TaskResult< void > { + + enum : int32_t { size = 0 }; + + using reference_type = void ; + + KOKKOS_INLINE_FUNCTION static + void * ptr( TaskBase * ) { return (void*) 0 ; } + + KOKKOS_INLINE_FUNCTION static + reference_type get( TaskBase * ) {} +}; + +} /* namespace Impl */ +} /* namespace Kokkos */ + +//---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- + +namespace Kokkos { +namespace Impl { + +template<> +class TaskQueue< void > {}; /** \brief Manage task allocation, deallocation, and scheduling. * @@ -95,7 +295,7 @@ class TaskQueueSpecialization ; * All other aspects of task management have shared implementation. */ template< typename ExecSpace > -class TaskQueue { +class TaskQueue : public TaskQueue { private: friend class TaskQueueSpecialization< ExecSpace > ; @@ -106,7 +306,7 @@ private: using memory_space = typename specialization::memory_space ; using device_type = Kokkos::Device< execution_space , memory_space > ; using memory_pool = Kokkos::MemoryPool< device_type > ; - using task_root_type = Kokkos::Impl::TaskBase ; + using task_root_type = Kokkos::Impl::TaskBase ; struct Destroy { TaskQueue * m_queue ; @@ -198,12 +398,10 @@ public: } // Assign task pointer with reference counting of assigned tasks - template< typename LV , typename RV > KOKKOS_FUNCTION static - void assign( TaskBase< execution_space,LV,void> ** const lhs - , TaskBase< execution_space,RV,void> * const rhs ) + void assign( task_root_type ** const lhs + , task_root_type * const rhs ) { - using task_lhs = TaskBase< execution_space,LV,void> ; #if 0 { printf( "assign( 0x%lx { 0x%lx %d %d } , 0x%lx { 0x%lx %d %d } )\n" @@ -225,7 +423,7 @@ public: // Force write of *lhs - *static_cast< task_lhs * volatile * >(lhs) = rhs ; + *static_cast< task_root_type * volatile * >(lhs) = rhs ; Kokkos::memory_fence(); } @@ -238,6 +436,38 @@ public: KOKKOS_FUNCTION void deallocate( void * p , size_t n ); ///< Deallocate to the memory pool + + + //---------------------------------------- + /**\brief Allocation size for a spawned task */ + + template< typename FunctorType > + KOKKOS_FUNCTION + size_t spawn_allocation_size() const + { + using value_type = typename FunctorType::value_type ; + + using task_type = Impl::TaskBase< execution_space + , value_type + , FunctorType > ; + + enum : size_t { align = ( 1 << 4 ) , align_mask = align - 1 }; + enum : size_t { task_size = sizeof(task_type) }; + enum : size_t { result_size = Impl::TaskResult< value_type >::size }; + enum : size_t { alloc_size = + ( ( task_size + align_mask ) & ~align_mask ) + + ( ( result_size + align_mask ) & ~align_mask ) }; + + return m_memory.allocate_block_size( task_size ); + } + + /**\brief Allocation size for a when_all aggregate */ + + KOKKOS_FUNCTION + size_t when_all_allocation_size( int narg ) const + { + return m_memory.allocate_block_size( sizeof(task_root_type) + narg * sizeof(task_root_type*) ); + } }; } /* namespace Impl */ @@ -249,261 +479,9 @@ public: namespace Kokkos { namespace Impl { -template<> -class TaskBase< void , void , void > { -public: - enum : int16_t { TaskTeam = 0 , TaskSingle = 1 , Aggregate = 2 }; - enum : uintptr_t { LockTag = ~uintptr_t(0) , EndTag = ~uintptr_t(1) }; -}; - -/** \brief Base class for task management, access, and execution. - * - * Inheritance structure to allow static_cast from the task root type - * and a task's FunctorType. - * - * // Enable a Future to access result data - * TaskBase< Space , ResultType , void > - * : TaskBase< void , void , void > - * { ... }; - * - * // Enable a functor to access the base class - * TaskBase< Space , ResultType , FunctorType > - * : TaskBase< Space , ResultType , void > - * , FunctorType - * { ... }; - * - * - * States of a task: - * - * Constructing State, NOT IN a linked list - * m_wait == 0 - * m_next == 0 - * - * Scheduling transition : Constructing -> Waiting - * before: - * m_wait == 0 - * m_next == this task's initial dependence, 0 if none - * after: - * m_wait == EndTag - * m_next == EndTag - * - * Waiting State, IN a linked list - * m_apply != 0 - * m_queue != 0 - * m_ref_count > 0 - * m_wait == head of linked list of tasks waiting on this task - * m_next == next of linked list of tasks - * - * transition : Waiting -> Executing - * before: - * m_next == EndTag - * after:: - * m_next == LockTag - * - * Executing State, NOT IN a linked list - * m_apply != 0 - * m_queue != 0 - * m_ref_count > 0 - * m_wait == head of linked list of tasks waiting on this task - * m_next == LockTag - * - * Respawn transition : Executing -> Executing-Respawn - * before: - * m_next == LockTag - * after: - * m_next == this task's updated dependence, 0 if none - * - * Executing-Respawn State, NOT IN a linked list - * m_apply != 0 - * m_queue != 0 - * m_ref_count > 0 - * m_wait == head of linked list of tasks waiting on this task - * m_next == this task's updated dependence, 0 if none - * - * transition : Executing -> Complete - * before: - * m_wait == head of linked list - * after: - * m_wait == LockTag - * - * Complete State, NOT IN a linked list - * m_wait == LockTag: cannot add dependence - * m_next == LockTag: not a member of a wait queue - * - */ -template< typename ExecSpace > -class TaskBase< ExecSpace , void , void > -{ -public: - - enum : int16_t { TaskTeam = TaskBase::TaskTeam - , TaskSingle = TaskBase::TaskSingle - , Aggregate = TaskBase::Aggregate }; - - enum : uintptr_t { LockTag = TaskBase::LockTag - , EndTag = TaskBase::EndTag }; - - using execution_space = ExecSpace ; - using queue_type = TaskQueue< execution_space > ; - - template< typename > friend class Kokkos::TaskScheduler ; - - typedef void (* function_type) ( TaskBase * , void * ); - - // sizeof(TaskBase) == 48 - - function_type m_apply ; ///< Apply function pointer - queue_type * m_queue ; ///< Queue in which this task resides - TaskBase * m_wait ; ///< Linked list of tasks waiting on this - TaskBase * m_next ; ///< Waiting linked-list next - int32_t m_ref_count ; ///< Reference count - int32_t m_alloc_size ; ///< Allocation size - int32_t m_dep_count ; ///< Aggregate's number of dependences - int16_t m_task_type ; ///< Type of task - int16_t m_priority ; ///< Priority of runnable task - - TaskBase() = delete ; - TaskBase( TaskBase && ) = delete ; - TaskBase( const TaskBase & ) = delete ; - TaskBase & operator = ( TaskBase && ) = delete ; - TaskBase & operator = ( const TaskBase & ) = delete ; - - KOKKOS_INLINE_FUNCTION ~TaskBase() = default ; - - // Constructor for a runnable task - KOKKOS_INLINE_FUNCTION - constexpr TaskBase( function_type arg_apply - , queue_type * arg_queue - , TaskBase * arg_dependence - , int arg_ref_count - , int arg_alloc_size - , int arg_task_type - , int arg_priority - ) noexcept - : m_apply( arg_apply ) - , m_queue( arg_queue ) - , m_wait( 0 ) - , m_next( arg_dependence ) - , m_ref_count( arg_ref_count ) - , m_alloc_size( arg_alloc_size ) - , m_dep_count( 0 ) - , m_task_type( arg_task_type ) - , m_priority( arg_priority ) - {} - - // Constructor for an aggregate task - KOKKOS_INLINE_FUNCTION - constexpr TaskBase( queue_type * arg_queue - , int arg_ref_count - , int arg_alloc_size - , int arg_dep_count - ) noexcept - : m_apply( 0 ) - , m_queue( arg_queue ) - , m_wait( 0 ) - , m_next( 0 ) - , m_ref_count( arg_ref_count ) - , m_alloc_size( arg_alloc_size ) - , m_dep_count( arg_dep_count ) - , m_task_type( Aggregate ) - , m_priority( 0 ) - {} - - //---------------------------------------- - - KOKKOS_INLINE_FUNCTION - TaskBase ** aggregate_dependences() - { return reinterpret_cast( this + 1 ); } - - KOKKOS_INLINE_FUNCTION - bool requested_respawn() - { - // This should only be called when a task has finished executing and is - // in the transition to either the complete or executing-respawn state. - TaskBase * const lock = reinterpret_cast< TaskBase * >( LockTag ); - return lock != m_next; - } - - KOKKOS_INLINE_FUNCTION - void add_dependence( TaskBase* dep ) - { - // Precondition: lock == m_next - - TaskBase * const lock = (TaskBase *) LockTag ; - - // Assign dependence to m_next. It will be processed in the subsequent - // call to schedule. Error if the dependence is reset. - if ( lock != Kokkos::atomic_exchange( & m_next, dep ) ) { - Kokkos::abort("TaskScheduler ERROR: resetting task dependence"); - } - - if ( 0 != dep ) { - // The future may be destroyed upon returning from this call - // so increment reference count to track this assignment. - Kokkos::atomic_increment( &(dep->m_ref_count) ); - } - } - - using get_return_type = void ; - - KOKKOS_INLINE_FUNCTION - get_return_type get() const {} -}; - -template < typename ExecSpace , typename ResultType > -class TaskBase< ExecSpace , ResultType , void > - : public TaskBase< ExecSpace , void , void > -{ -private: - - using root_type = TaskBase ; - using function_type = typename root_type::function_type ; - using queue_type = typename root_type::queue_type ; - - static_assert( sizeof(root_type) == 48 , "" ); - - TaskBase() = delete ; - TaskBase( TaskBase && ) = delete ; - TaskBase( const TaskBase & ) = delete ; - TaskBase & operator = ( TaskBase && ) = delete ; - TaskBase & operator = ( const TaskBase & ) = delete ; - -public: - - ResultType m_result ; - - KOKKOS_INLINE_FUNCTION ~TaskBase() = default ; - - // Constructor for runnable task - KOKKOS_INLINE_FUNCTION - constexpr TaskBase( function_type arg_apply - , queue_type * arg_queue - , root_type * arg_dependence - , int arg_ref_count - , int arg_alloc_size - , int arg_task_type - , int arg_priority - ) - : root_type( arg_apply - , arg_queue - , arg_dependence - , arg_ref_count - , arg_alloc_size - , arg_task_type - , arg_priority - ) - , m_result() - {} - - using get_return_type = ResultType const & ; - - KOKKOS_INLINE_FUNCTION - get_return_type get() const { return m_result ; } -}; - -template< typename ExecSpace , typename ResultType , typename FunctorType > +template< class ExecSpace , typename ResultType , class FunctorType > class TaskBase - : public TaskBase< ExecSpace , ResultType , void > + : public TaskBase< void , void , void > , public FunctorType { private: @@ -516,50 +494,31 @@ private: public: - using root_type = TaskBase< ExecSpace , void , void > ; - using base_type = TaskBase< ExecSpace , ResultType , void > ; - using specialization = TaskQueueSpecialization< ExecSpace > ; - using function_type = typename root_type::function_type ; - using queue_type = typename root_type::queue_type ; - using member_type = typename specialization::member_type ; + using root_type = TaskBase< void , void , void > ; using functor_type = FunctorType ; using result_type = ResultType ; - template< typename Type > - KOKKOS_INLINE_FUNCTION static - void apply_functor - ( Type * const task - , typename std::enable_if - < std::is_same< typename Type::result_type , void >::value - , member_type * const - >::type member - ) - { - using fType = typename Type::functor_type ; - static_cast(task)->operator()( *member ); - } + using specialization = TaskQueueSpecialization< ExecSpace > ; + using member_type = typename specialization::member_type ; - template< typename Type > - KOKKOS_INLINE_FUNCTION static - void apply_functor - ( Type * const task - , typename std::enable_if - < ! std::is_same< typename Type::result_type , void >::value - , member_type * const - >::type member - ) - { - using fType = typename Type::functor_type ; - static_cast(task)->operator()( *member , task->m_result ); - } + KOKKOS_INLINE_FUNCTION + void apply_functor( member_type * const member , void * ) + { functor_type::operator()( *member ); } + + template< typename T > + KOKKOS_INLINE_FUNCTION + void apply_functor( member_type * const member + , T * const result ) + { functor_type::operator()( *member , *result ); } KOKKOS_FUNCTION static void apply( root_type * root , void * exec ) { TaskBase * const task = static_cast< TaskBase * >( root ); member_type * const member = reinterpret_cast< member_type * >( exec ); + result_type * const result = TaskResult< result_type >::ptr( task ); - TaskBase::template apply_functor( task , member ); + task->apply_functor( member , result ); // Task may be serial or team. // If team then must synchronize before querying if respawn was requested. @@ -576,26 +535,9 @@ public: } // Constructor for runnable task - KOKKOS_INLINE_FUNCTION - constexpr TaskBase( function_type arg_apply - , queue_type * arg_queue - , root_type * arg_dependence - , int arg_ref_count - , int arg_alloc_size - , int arg_task_type - , int arg_priority - , FunctorType && arg_functor - ) - : base_type( arg_apply - , arg_queue - , arg_dependence - , arg_ref_count - , arg_alloc_size - , arg_task_type - , arg_priority - ) - , functor_type( arg_functor ) - {} + KOKKOS_INLINE_FUNCTION constexpr + TaskBase( FunctorType && arg_functor ) + : root_type() , functor_type( std::move(arg_functor) ) {} KOKKOS_INLINE_FUNCTION ~TaskBase() {} diff --git a/lib/kokkos/core/src/impl/Kokkos_TaskQueue_impl.hpp b/lib/kokkos/core/src/impl/Kokkos_TaskQueue_impl.hpp index aee381afad..1974f7e1ca 100644 --- a/lib/kokkos/core/src/impl/Kokkos_TaskQueue_impl.hpp +++ b/lib/kokkos/core/src/impl/Kokkos_TaskQueue_impl.hpp @@ -44,6 +44,8 @@ #include #if defined( KOKKOS_ENABLE_TASKDAG ) +#define KOKKOS_IMPL_DEBUG_TASKDAG_SCHEDULING 0 + namespace Kokkos { namespace Impl { @@ -100,9 +102,11 @@ KOKKOS_FUNCTION void TaskQueue< ExecSpace >::decrement ( TaskQueue< ExecSpace >::task_root_type * task ) { - const int count = Kokkos::atomic_fetch_add(&(task->m_ref_count),-1); + task_root_type volatile & t = *task ; -#if 0 + const int count = Kokkos::atomic_fetch_add(&(t.m_ref_count),-1); + +#if KOKKOS_IMPL_DEBUG_TASKDAG_SCHEDULING if ( 1 == count ) { printf( "decrement-destroy( 0x%lx { 0x%lx %d %d } )\n" , uintptr_t( task ) @@ -114,9 +118,13 @@ void TaskQueue< ExecSpace >::decrement #endif if ( ( 1 == count ) && - ( task->m_next == (task_root_type *) task_root_type::LockTag ) ) { + ( t.m_next == (task_root_type *) task_root_type::LockTag ) ) { // Reference count is zero and task is complete, deallocate. - task->m_queue->deallocate( task , task->m_alloc_size ); + + TaskQueue< ExecSpace > * const queue = + static_cast< TaskQueue< ExecSpace > * >( t.m_queue ); + + queue->deallocate( task , t.m_alloc_size ); } else if ( count <= 1 ) { Kokkos::abort("TaskScheduler task has negative reference count or is incomplete" ); @@ -171,7 +179,7 @@ bool TaskQueue< ExecSpace >::push_task // Fail the push attempt if the queue is locked; // otherwise retry until the push succeeds. -#if 0 +#if KOKKOS_IMPL_DEBUG_TASKDAG_SCHEDULING printf( "push_task( 0x%lx { 0x%lx } 0x%lx { 0x%lx 0x%lx %d %d %d } )\n" , uintptr_t(queue) , uintptr_t(*queue) @@ -186,9 +194,9 @@ bool TaskQueue< ExecSpace >::push_task task_root_type * const zero = (task_root_type *) 0 ; task_root_type * const lock = (task_root_type *) task_root_type::LockTag ; - task_root_type * volatile * const next = & task->m_next ; + task_root_type * volatile & next = task->m_next ; - if ( zero != *next ) { + if ( zero != next ) { Kokkos::abort("TaskQueue::push_task ERROR: already a member of another queue" ); } @@ -196,9 +204,9 @@ bool TaskQueue< ExecSpace >::push_task while ( lock != y ) { - *next = y ; + next = y ; - // Do not proceed until '*next' has been stored. + // Do not proceed until 'next' has been stored. Kokkos::memory_fence(); task_root_type * const x = y ; @@ -211,9 +219,9 @@ bool TaskQueue< ExecSpace >::push_task // Failed, replace 'task->m_next' value since 'task' remains // not a member of a queue. - *next = zero ; + next = zero ; - // Do not proceed until '*next' has been stored. + // Do not proceed until 'next' has been stored. Kokkos::memory_fence(); return false ; @@ -270,11 +278,13 @@ TaskQueue< ExecSpace >::pop_ready_task // This thread has exclusive access to // the queue and the popped task's m_next. - *queue = task->m_next ; task->m_next = lock ; + task_root_type * volatile & next = task->m_next ; + + *queue = next ; next = lock ; Kokkos::memory_fence(); -#if 0 +#if KOKKOS_IMPL_DEBUG_TASKDAG_SCHEDULING printf( "pop_ready_task( 0x%lx 0x%lx { 0x%lx 0x%lx %d %d %d } )\n" , uintptr_t(queue) , uintptr_t(task) @@ -323,7 +333,7 @@ void TaskQueue< ExecSpace >::schedule_runnable // task->m_wait == head of linked list (queue) // task->m_next == member of linked list (queue) -#if 0 +#if KOKKOS_IMPL_DEBUG_TASKDAG_SCHEDULING printf( "schedule_runnable( 0x%lx { 0x%lx 0x%lx %d %d %d }\n" , uintptr_t(task) , uintptr_t(task->m_wait) @@ -337,20 +347,22 @@ void TaskQueue< ExecSpace >::schedule_runnable task_root_type * const lock = (task_root_type *) task_root_type::LockTag ; task_root_type * const end = (task_root_type *) task_root_type::EndTag ; + task_root_type volatile & t = *task ; + bool respawn = false ; //---------------------------------------- - if ( zero == task->m_wait ) { + if ( zero == t.m_wait ) { // Task in Constructing state // - Transition to Waiting state // Preconditions: // - call occurs exclusively within a single thread - task->m_wait = end ; + t.m_wait = end ; // Task in Waiting state } - else if ( lock != task->m_wait ) { + else if ( lock != t.m_wait ) { // Task in Executing state with Respawn request // - Update dependence // - Transition to Waiting state @@ -373,7 +385,9 @@ void TaskQueue< ExecSpace >::schedule_runnable // Exclusive access so don't need an atomic exchange // task_root_type * dep = Kokkos::atomic_exchange( & task->m_next , zero ); - task_root_type * dep = task->m_next ; task->m_next = zero ; + task_root_type * dep = t.m_next ; t.m_next = zero ; + + Kokkos::memory_fence(); const bool is_ready = ( 0 == dep ) || ( ! push_task( & dep->m_wait , task ) ); @@ -398,7 +412,7 @@ void TaskQueue< ExecSpace >::schedule_runnable Kokkos::atomic_increment( & m_ready_count ); task_root_type * volatile * const ready_queue = - & m_ready[ task->m_priority ][ task->m_task_type ]; + & m_ready[ t.m_priority ][ t.m_task_type ]; // A push_task fails if the ready queue is locked. // A ready queue is only locked during a push or pop; @@ -441,7 +455,7 @@ void TaskQueue< ExecSpace >::schedule_aggregate // task->m_wait == head of linked list (queue) // task->m_next == member of linked list (queue) -#if 0 +#if KOKKOS_IMPL_DEBUG_TASKDAG_SCHEDULING printf( "schedule_aggregate( 0x%lx { 0x%lx 0x%lx %d %d %d }\n" , uintptr_t(task) , uintptr_t(task->m_wait) @@ -455,18 +469,20 @@ void TaskQueue< ExecSpace >::schedule_aggregate task_root_type * const lock = (task_root_type *) task_root_type::LockTag ; task_root_type * const end = (task_root_type *) task_root_type::EndTag ; + task_root_type volatile & t = *task ; + //---------------------------------------- - if ( zero == task->m_wait ) { + if ( zero == t.m_wait ) { // Task in Constructing state // - Transition to Waiting state // Preconditions: // - call occurs exclusively within a single thread - task->m_wait = end ; + t.m_wait = end ; // Task in Waiting state } - else if ( lock == task->m_wait ) { + else if ( lock == t.m_wait ) { // Task in Complete state Kokkos::abort("TaskQueue::schedule_aggregate ERROR: task is complete"); } @@ -477,14 +493,14 @@ void TaskQueue< ExecSpace >::schedule_aggregate // (1) created or // (2) being removed from a completed task's wait list. - task_root_type ** const aggr = task->aggregate_dependences(); + task_root_type * volatile * const aggr = t.aggregate_dependences(); // Assume the 'when_all' is complete until a dependence is // found that is not complete. bool is_complete = true ; - for ( int i = task->m_dep_count ; 0 < i && is_complete ; ) { + for ( int i = t.m_dep_count ; 0 < i && is_complete ; ) { --i ; @@ -523,7 +539,7 @@ void TaskQueue< ExecSpace >::schedule_aggregate // Complete the when_all 'task' to schedule other tasks // that are waiting for the when_all 'task' to complete. - task->m_next = lock ; + t.m_next = lock ; complete( task ); @@ -573,7 +589,7 @@ void TaskQueue< ExecSpace >::complete task_root_type * const lock = (task_root_type *) task_root_type::LockTag ; task_root_type * const end = (task_root_type *) task_root_type::EndTag ; -#if 0 +#if KOKKOS_IMPL_DEBUG_TASKDAG_SCHEDULING printf( "complete( 0x%lx { 0x%lx 0x%lx %d %d %d }\n" , uintptr_t(task) , uintptr_t(task->m_wait) @@ -584,11 +600,13 @@ void TaskQueue< ExecSpace >::complete fflush( stdout ); #endif - const bool runnable = task_root_type::Aggregate != task->m_task_type ; + task_root_type volatile & t = *task ; + + const bool runnable = task_root_type::Aggregate != t.m_task_type ; //---------------------------------------- - if ( runnable && lock != task->m_next ) { + if ( runnable && lock != t.m_next ) { // Is a runnable task has finished executing and requested respawn. // Schedule the task for subsequent execution. @@ -607,7 +625,7 @@ void TaskQueue< ExecSpace >::complete // Stop other tasks from adding themselves to this task's wait queue // by locking the head of this task's wait queue. - task_root_type * x = Kokkos::atomic_exchange( & task->m_wait , lock ); + task_root_type * x = Kokkos::atomic_exchange( & t.m_wait , lock ); if ( x != (task_root_type *) lock ) { @@ -627,9 +645,13 @@ void TaskQueue< ExecSpace >::complete // Have exclusive access to 'x' until it is scheduled // Set x->m_next = zero <= no dependence, not a respawn - task_root_type * const next = x->m_next ; x->m_next = 0 ; + task_root_type volatile & vx = *x ; - if ( task_root_type::Aggregate != x->m_task_type ) { + task_root_type * const next = vx.m_next ; vx.m_next = 0 ; + + Kokkos::memory_fence(); + + if ( task_root_type::Aggregate != vx.m_task_type ) { schedule_runnable( x ); } else { diff --git a/lib/kokkos/core/src/impl/Kokkos_ViewArray.hpp b/lib/kokkos/core/src/impl/Kokkos_ViewArray.hpp index c55636b64e..ed1a71bea7 100644 --- a/lib/kokkos/core/src/impl/Kokkos_ViewArray.hpp +++ b/lib/kokkos/core/src/impl/Kokkos_ViewArray.hpp @@ -1,13 +1,13 @@ /* //@HEADER // ************************************************************************ -// +// // Kokkos v. 2.0 // Copyright (2014) Sandia Corporation -// +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: @@ -36,7 +36,7 @@ // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) -// +// // ************************************************************************ //@HEADER */ @@ -47,7 +47,6 @@ #include namespace Kokkos { -namespace Experimental { namespace Impl { template< class DataType , class ArrayLayout , class V , size_t N , class P > @@ -94,13 +93,12 @@ public: typedef typename ViewDataType< non_const_scalar_type , array_scalar_dimension >::type non_const_scalar_array_type ; }; -}}} // namespace Kokkos::Experimental::Impl +}} // namespace Kokkos::Impl //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- namespace Kokkos { -namespace Experimental { namespace Impl { /** \brief View mapping for non-specialized data type and standard layout */ @@ -597,7 +595,7 @@ public: } }; -}}} // namespace Kokkos::Experimental::Impl +}} // namespace Kokkos::Impl //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- diff --git a/lib/kokkos/core/src/impl/Kokkos_ViewCtor.hpp b/lib/kokkos/core/src/impl/Kokkos_ViewCtor.hpp index 6381aee468..f32c6bb2ee 100644 --- a/lib/kokkos/core/src/impl/Kokkos_ViewCtor.hpp +++ b/lib/kokkos/core/src/impl/Kokkos_ViewCtor.hpp @@ -96,6 +96,27 @@ struct is_view_label< const char[N] > : public std::true_type {}; template< typename ... P > struct ViewCtorProp ; +// Forward declare +template< typename Specialize , typename T > +struct CommonViewAllocProp ; + +/* Common value_type stored as ViewCtorProp + */ +template< typename Specialize , typename T > +struct ViewCtorProp< void , CommonViewAllocProp > +{ + ViewCtorProp() = default ; + ViewCtorProp( const ViewCtorProp & ) = default ; + ViewCtorProp & operator = ( const ViewCtorProp & ) = default ; + + using type = CommonViewAllocProp ; + + ViewCtorProp( const type & arg ) : value( arg ) {} + ViewCtorProp( type && arg ) : value( arg ) {} + + type value ; +}; + /* std::integral_constant are dummy arguments * that avoid duplicate base class errors */ diff --git a/lib/kokkos/core/src/impl/Kokkos_ViewMapping.hpp b/lib/kokkos/core/src/impl/Kokkos_ViewMapping.hpp index 900bd88f1c..d346f9e639 100644 --- a/lib/kokkos/core/src/impl/Kokkos_ViewMapping.hpp +++ b/lib/kokkos/core/src/impl/Kokkos_ViewMapping.hpp @@ -62,7 +62,6 @@ //---------------------------------------------------------------------------- namespace Kokkos { -namespace Experimental { namespace Impl { template< unsigned I , size_t ... Args > @@ -250,7 +249,7 @@ struct ViewDimensionAssignable< ViewDimension< DstArgs ... > }; -}}} // namespace Kokkos::Experimental::Impl +}} // namespace Kokkos::Impl //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- @@ -266,14 +265,11 @@ struct ALL_t { }} // namespace Kokkos::Impl namespace Kokkos { -namespace Experimental { namespace Impl { -using Kokkos::Impl::ALL_t ; - template< class T > struct is_integral_extent_type -{ enum { value = std::is_same::value ? 1 : 0 }; }; +{ enum { value = std::is_same::value ? 1 : 0 }; }; template< class iType > struct is_integral_extent_type< std::pair > @@ -314,10 +310,10 @@ struct SubviewLegalArgsCompileTime; template struct SubviewLegalArgsCompileTime { - enum { value =(((CurrentArg==RankDest-1) && (Kokkos::Experimental::Impl::is_integral_extent_type::value)) || + enum { value =(((CurrentArg==RankDest-1) && (Kokkos::Impl::is_integral_extent_type::value)) || ((CurrentArg>=RankDest) && (std::is_integral::value)) || ((CurrentArg::value)) || - ((CurrentArg==0) && (Kokkos::Experimental::Impl::is_integral_extent_type::value)) + ((CurrentArg==0) && (Kokkos::Impl::is_integral_extent_type::value)) ) && (SubviewLegalArgsCompileTime::value)}; }; @@ -331,7 +327,7 @@ struct SubviewLegalArgsCompileTime struct SubviewLegalArgsCompileTime { - enum { value =(((CurrentArg==RankSrc-RankDest) && (Kokkos::Experimental::Impl::is_integral_extent_type::value)) || + enum { value =(((CurrentArg==RankSrc-RankDest) && (Kokkos::Impl::is_integral_extent_type::value)) || ((CurrentArg::value)) || ((CurrentArg>=RankSrc-RankDest) && (std::is_same::value)) ) && (SubviewLegalArgsCompileTime::value)}; @@ -403,7 +399,7 @@ private: bool set( unsigned domain_rank , unsigned range_rank , const ViewDimension< DimArgs ... > & dim - , const Kokkos::Experimental::Impl::ALL_t + , const Kokkos::Impl::ALL_t , Args ... args ) { m_begin[ domain_rank ] = 0 ; @@ -519,7 +515,7 @@ private: , unsigned domain_rank , unsigned range_rank , const ViewDimension< DimArgs ... > & dim - , const Kokkos::Experimental::Impl::ALL_t + , const Kokkos::Impl::ALL_t , Args ... args ) const { const int n = std::min( buf_len , @@ -670,13 +666,12 @@ public: { return unsigned(i) < InternalRangeRank ? m_index[i] : ~0u ; } }; -}}} // namespace Kokkos::Experimental::Impl +}} // namespace Kokkos::Impl //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- namespace Kokkos { -namespace Experimental { namespace Impl { /** \brief Given a value type and dimension generate the View data type */ @@ -814,13 +809,12 @@ public: typedef non_const_type non_const_scalar_array_type ; }; -}}} // namespace Kokkos::Experimental::Impl +}} // namespace Kokkos::Impl //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- namespace Kokkos { -namespace Experimental { namespace Impl { template < class Dimension , class Layout , typename Enable = void > @@ -1228,14 +1222,14 @@ private: // If memory alignment is a multiple of the trivial scalar size then attempt to align. enum { align = 0 != TrivialScalarSize && 0 == mod ? div : 0 }; - enum { div_ok = div ? div : 1 }; // To valid modulo zero in constexpr + enum { div_ok = (div != 0) ? div : 1 }; // To valid modulo zero in constexpr KOKKOS_INLINE_FUNCTION static constexpr size_t stride( size_t const N ) - { - return ( align && ( Kokkos::Impl::MEMORY_ALIGNMENT_THRESHOLD * align < N ) && ( N % div_ok ) ) - ? N + align - ( N % div_ok ) : N ; - } + { + return ( (align != 0) && ((Kokkos::Impl::MEMORY_ALIGNMENT_THRESHOLD * align) < N) && ((N % div_ok) != 0) ) + ? N + align - ( N % div_ok ) : N ; + } }; public: @@ -1707,12 +1701,12 @@ private: // If memory alignment is a multiple of the trivial scalar size then attempt to align. enum { align = 0 != TrivialScalarSize && 0 == mod ? div : 0 }; - enum { div_ok = div ? div : 1 }; // To valid modulo zero in constexpr + enum { div_ok = (div != 0) ? div : 1 }; // To valid modulo zero in constexpr KOKKOS_INLINE_FUNCTION static constexpr size_t stride( size_t const N ) { - return ( align && ( Kokkos::Impl::MEMORY_ALIGNMENT_THRESHOLD * align < N ) && ( N % div_ok ) ) + return ( (align != 0) && ((Kokkos::Impl::MEMORY_ALIGNMENT_THRESHOLD * align) < N) && ((N % div_ok) != 0) ) ? N + align - ( N % div_ok ) : N ; } }; @@ -2225,13 +2219,12 @@ public: {} }; -}}} // namespace Kokkos::Experimental::Impl +}} // namespace Kokkos::Impl //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- namespace Kokkos { -namespace Experimental { namespace Impl { /** \brief ViewDataHandle provides the type of the 'data handle' which the view @@ -2422,13 +2415,12 @@ struct ViewDataHandle< Traits , return handle_type( arg_data_ptr + offset ); } }; -}}} // namespace Kokkos::Experimental::Impl +}} // namespace Kokkos::Impl //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- namespace Kokkos { -namespace Experimental { namespace Impl { //---------------------------------------------------------------------------- @@ -2451,8 +2443,9 @@ template< class ExecSpace , class ValueType > struct ViewValueFunctor< ExecSpace , ValueType , false /* is_scalar */ > { typedef Kokkos::RangePolicy< ExecSpace > PolicyType ; + typedef typename ExecSpace::execution_space Exec; - ExecSpace space ; + Exec space ; ValueType * ptr ; size_t n ; bool destroy ; @@ -2597,6 +2590,9 @@ private: public: + typedef void printable_label_typedef; + enum { is_managed = Traits::is_managed }; + //---------------------------------------- // Domain dimensions @@ -2944,7 +2940,7 @@ public: Kokkos::abort("View Assignment: trying to assign runtime dimension to non matching compile time dimension."); } dst.m_offset = dst_offset_type( src.m_offset ); - dst.m_handle = Kokkos::Experimental::Impl::ViewDataHandle< DstTraits >::assign( src.m_handle , src_track ); + dst.m_handle = Kokkos::Impl::ViewDataHandle< DstTraits >::assign( src.m_handle , src_track ); } }; @@ -3102,7 +3098,7 @@ public: //---------------------------------------------------------------------------- -}}} // namespace Kokkos::Experimental::Impl +}} // namespace Kokkos::Impl //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- @@ -3151,6 +3147,77 @@ void view_error_operator_bounds view_error_operator_bounds(buf+n,len-n,map,args...); } +#if ! defined( KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_HOST ) + +/* Check #3: is the View managed as determined by the MemoryTraits? */ +template< class MapType, + bool is_managed = (MapType::is_managed != 0) > +struct OperatorBoundsErrorOnDevice; + +template< class MapType > +struct OperatorBoundsErrorOnDevice< MapType, false > { +KOKKOS_INLINE_FUNCTION +static void run(MapType const&) { + Kokkos::abort("View bounds error"); +} +}; + +template< class MapType > +struct OperatorBoundsErrorOnDevice< MapType, true > { +KOKKOS_INLINE_FUNCTION +static void run(MapType const& map) { + char const* const user_alloc_start = reinterpret_cast(map.data()); + char const* const header_start = user_alloc_start - sizeof(SharedAllocationHeader); + SharedAllocationHeader const* const header = + reinterpret_cast(header_start); + char const* const label = header->label(); + enum { LEN = 128 }; + char msg[LEN]; + char const* const first_part = "View bounds error of view "; + char* p = msg; + char* const end = msg + LEN - 1; + for (char const* p2 = first_part; (*p2 != '\0') && (p < end); ++p, ++p2) { + *p = *p2; + } + for (char const* p2 = label; (*p2 != '\0') && (p < end); ++p, ++p2) { + *p = *p2; + } + *p = '\0'; + Kokkos::abort(msg); +} +}; + +/* Check #2: does the ViewMapping have the printable_label_typedef defined? + See above that only the non-specialized standard-layout ViewMapping has + this defined by default. + The existence of this typedef indicates the existence of MapType::is_managed */ +template< class T, class Enable = void > +struct has_printable_label_typedef : public std::false_type {}; + +template +struct has_printable_label_typedef< + T, typename enable_if_type::type> + : public std::true_type +{}; + +template< class MapType > +KOKKOS_INLINE_FUNCTION +void operator_bounds_error_on_device( + MapType const&, + std::false_type) { + Kokkos::abort("View bounds error"); +} + +template< class MapType > +KOKKOS_INLINE_FUNCTION +void operator_bounds_error_on_device( + MapType const& map, + std::true_type) { + OperatorBoundsErrorOnDevice< MapType >::run(map); +} + +#endif // ! defined( KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_HOST ) + template< class MemorySpace , class MapType , class ... Args > KOKKOS_INLINE_FUNCTION void view_verify_operator_bounds @@ -3166,7 +3233,17 @@ void view_verify_operator_bounds view_error_operator_bounds<0>( buffer + n , LEN - n , map , args ... ); Kokkos::Impl::throw_runtime_exception(std::string(buffer)); #else - Kokkos::abort("View bounds error"); + /* Check #1: is there a SharedAllocationRecord? + (we won't use it, but if its not there then there isn't + a corresponding SharedAllocationHeader containing a label). + This check should cover the case of Views that don't + have the Unmanaged trait but were initialized by pointer. */ + if (tracker.has_record()) { + operator_bounds_error_on_device( + map, has_printable_label_typedef()); + } else { + Kokkos::abort("View bounds error"); + } #endif } } diff --git a/lib/kokkos/core/src/impl/Kokkos_ViewTile.hpp b/lib/kokkos/core/src/impl/Kokkos_ViewTile.hpp index ecbcf72fe0..5a8600e0ae 100644 --- a/lib/kokkos/core/src/impl/Kokkos_ViewTile.hpp +++ b/lib/kokkos/core/src/impl/Kokkos_ViewTile.hpp @@ -1,13 +1,13 @@ /* //@HEADER // ************************************************************************ -// +// // Kokkos v. 2.0 // Copyright (2014) Sandia Corporation -// +// // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: @@ -36,7 +36,7 @@ // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) -// +// // ************************************************************************ //@HEADER */ @@ -48,7 +48,6 @@ //---------------------------------------------------------------------------- namespace Kokkos { -namespace Experimental { namespace Impl { // View mapping for rank two tiled array @@ -195,11 +194,9 @@ struct ViewMapping }; } /* namespace Impl */ -} /* namespace Experimental */ } /* namespace Kokkos */ namespace Kokkos { -namespace Experimental { template< typename T , unsigned N0 , unsigned N1 , class ... P > KOKKOS_INLINE_FUNCTION @@ -217,7 +214,6 @@ tile_subview( const Kokkos::View,P...> & ( src , SrcLayout() , i_tile0 , i_tile1 ); } -} /* namespace Experimental */ } /* namespace Kokkos */ //---------------------------------------------------------------------------- diff --git a/lib/kokkos/core/src/impl/Kokkos_spinwait.cpp b/lib/kokkos/core/src/impl/Kokkos_spinwait.cpp deleted file mode 100644 index 101b714fcd..0000000000 --- a/lib/kokkos/core/src/impl/Kokkos_spinwait.cpp +++ /dev/null @@ -1,183 +0,0 @@ -/* -//@HEADER -// ************************************************************************ -// -// Kokkos v. 2.0 -// Copyright (2014) Sandia Corporation -// -// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, -// the U.S. Government retains certain rights in this software. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// 1. Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// 3. Neither the name of the Corporation nor the names of the -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE -// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) -// -// ************************************************************************ -//@HEADER -*/ - -#include -#if defined( KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_HOST ) - -#include - -#include -#include - -/*--------------------------------------------------------------------------*/ - -#if !defined( _WIN32 ) - #if defined( KOKKOS_ENABLE_ASM ) - #if defined( __arm__ ) || defined( __aarch64__ ) - /* No-operation instruction to idle the thread. */ - #define KOKKOS_INTERNAL_PAUSE - #else - /* Pause instruction to prevent excess processor bus usage */ - #define KOKKOS_INTERNAL_PAUSE asm volatile("pause\n":::"memory") - #endif - #define KOKKOS_INTERNAL_NOP2 asm volatile("nop\n" "nop\n") - #define KOKKOS_INTERNAL_NOP4 KOKKOS_INTERNAL_NOP2; KOKKOS_INTERNAL_NOP2 - #define KOKKOS_INTERNAL_NOP8 KOKKOS_INTERNAL_NOP4; KOKKOS_INTERNAL_NOP4; - #define KOKKOS_INTERNAL_NOP16 KOKKOS_INTERNAL_NOP8; KOKKOS_INTERNAL_NOP8; - #define KOKKOS_INTERNAL_NOP32 KOKKOS_INTERNAL_NOP16; KOKKOS_INTERNAL_NOP16; - namespace { - inline void kokkos_internal_yield( const unsigned i ) noexcept { - switch (Kokkos::Impl::bit_scan_reverse((i >> 2)+1u)) { - case 0u: KOKKOS_INTERNAL_NOP2; break; - case 1u: KOKKOS_INTERNAL_NOP4; break; - case 2u: KOKKOS_INTERNAL_NOP8; break; - case 3u: KOKKOS_INTERNAL_NOP16; break; - default: KOKKOS_INTERNAL_NOP32; - } - KOKKOS_INTERNAL_PAUSE; - } - } - #else - #include - namespace { - inline void kokkos_internal_yield( const unsigned ) noexcept { - sched_yield(); - } - } - #endif -#else // defined( _WIN32 ) - #if defined ( KOKKOS_ENABLE_WINTHREAD ) - #include - namespace { - inline void kokkos_internal_yield( const unsigned ) noexcept { - Sleep(0); - } - } - #elif defined( _MSC_VER ) - #define NOMINMAX - #include - #include - namespace { - inline void kokkos_internal_yield( const unsigned ) noexcept { - YieldProcessor(); - } - } - #else - #define KOKKOS_INTERNAL_PAUSE __asm__ __volatile__("pause\n":::"memory") - #define KOKKOS_INTERNAL_NOP2 __asm__ __volatile__("nop\n" "nop") - #define KOKKOS_INTERNAL_NOP4 KOKKOS_INTERNAL_NOP2; KOKKOS_INTERNAL_NOP2 - #define KOKKOS_INTERNAL_NOP8 KOKKOS_INTERNAL_NOP4; KOKKOS_INTERNAL_NOP4; - #define KOKKOS_INTERNAL_NOP16 KOKKOS_INTERNAL_NOP8; KOKKOS_INTERNAL_NOP8; - #define KOKKOS_INTERNAL_NOP32 KOKKOS_INTERNAL_NOP16; KOKKOS_INTERNAL_NOP16; - namespace { - inline void kokkos_internal_yield( const unsigned i ) noexcept { - switch (Kokkos::Impl::bit_scan_reverse((i >> 2)+1u)) { - case 0: KOKKOS_INTERNAL_NOP2; break; - case 1: KOKKOS_INTERNAL_NOP4; break; - case 2: KOKKOS_INTERNAL_NOP8; break; - case 3: KOKKOS_INTERNAL_NOP16; break; - default: KOKKOS_INTERNAL_NOP32; - } - KOKKOS_INTERNAL_PAUSE; - } - } - #endif -#endif - - -/*--------------------------------------------------------------------------*/ - -namespace Kokkos { -namespace Impl { - -void spinwait_while_equal( volatile int32_t & flag , const int32_t value ) -{ - Kokkos::store_fence(); - unsigned i = 0; - while ( value == flag ) { - kokkos_internal_yield(i); - ++i; - } - Kokkos::load_fence(); -} - -void spinwait_until_equal( volatile int32_t & flag , const int32_t value ) -{ - Kokkos::store_fence(); - unsigned i = 0; - while ( value != flag ) { - kokkos_internal_yield(i); - ++i; - } - Kokkos::load_fence(); -} - -void spinwait_while_equal( volatile int64_t & flag , const int64_t value ) -{ - Kokkos::store_fence(); - unsigned i = 0; - while ( value == flag ) { - kokkos_internal_yield(i); - ++i; - } - Kokkos::load_fence(); -} - -void spinwait_until_equal( volatile int64_t & flag , const int64_t value ) -{ - Kokkos::store_fence(); - unsigned i = 0; - while ( value != flag ) { - kokkos_internal_yield(i); - ++i; - } - Kokkos::load_fence(); -} - -} /* namespace Impl */ -} /* namespace Kokkos */ - -#else -void KOKKOS_CORE_SRC_IMPL_SPINWAIT_PREVENT_LINK_ERROR() {} -#endif - diff --git a/lib/kokkos/core/unit_test/CMakeLists.txt b/lib/kokkos/core/unit_test/CMakeLists.txt index 5d6f25ac95..475b6bb48a 100644 --- a/lib/kokkos/core/unit_test/CMakeLists.txt +++ b/lib/kokkos/core/unit_test/CMakeLists.txt @@ -57,6 +57,7 @@ IF(Kokkos_ENABLE_Serial) serial/TestSerial_ViewMapping_b.cpp serial/TestSerial_ViewMapping_subview.cpp serial/TestSerial_ViewOfClass.cpp + serial/TestSerial_WorkGraph.cpp COMM serial mpi NUM_MPI_PROCS 1 FAIL_REGULAR_EXPRESSION " FAILED " @@ -102,6 +103,7 @@ IF(Kokkos_ENABLE_Pthread) threads/TestThreads_ViewMapping_b.cpp threads/TestThreads_ViewMapping_subview.cpp threads/TestThreads_ViewOfClass.cpp + threads/TestThreads_WorkGraph.cpp COMM serial mpi NUM_MPI_PROCS 1 FAIL_REGULAR_EXPRESSION " FAILED " @@ -147,6 +149,8 @@ IF(Kokkos_ENABLE_OpenMP) openmp/TestOpenMP_ViewMapping_b.cpp openmp/TestOpenMP_ViewMapping_subview.cpp openmp/TestOpenMP_ViewOfClass.cpp + openmp/TestOpenMP_WorkGraph.cpp + openmp/TestOpenMP_UniqueToken.cpp COMM serial mpi NUM_MPI_PROCS 1 FAIL_REGULAR_EXPRESSION " FAILED " @@ -237,6 +241,7 @@ IF(Kokkos_ENABLE_Cuda) cuda/TestCuda_ViewMapping_b.cpp cuda/TestCuda_ViewMapping_subview.cpp cuda/TestCuda_ViewOfClass.cpp + cuda/TestCuda_WorkGraph.cpp COMM serial mpi NUM_MPI_PROCS 1 FAIL_REGULAR_EXPRESSION " FAILED " @@ -253,6 +258,7 @@ TRIBITS_ADD_EXECUTABLE_AND_TEST( default/TestDefaultDeviceType_b.cpp default/TestDefaultDeviceType_c.cpp default/TestDefaultDeviceType_d.cpp + default/TestDefaultDeviceTypeResize.cpp COMM serial mpi NUM_MPI_PROCS 1 FAIL_REGULAR_EXPRESSION " FAILED " diff --git a/lib/kokkos/core/unit_test/Makefile b/lib/kokkos/core/unit_test/Makefile index 41f192a486..c877aa7dd2 100644 --- a/lib/kokkos/core/unit_test/Makefile +++ b/lib/kokkos/core/unit_test/Makefile @@ -62,8 +62,9 @@ endif OBJ_CUDA += TestCuda_TeamReductionScan.o OBJ_CUDA += TestCuda_Other.o OBJ_CUDA += TestCuda_MDRange.o - OBJ_CUDA += TestCuda_Task.o + OBJ_CUDA += TestCuda_Task.o TestCuda_WorkGraph.o OBJ_CUDA += TestCuda_Spaces.o + OBJ_CUDA += TestCuda_UniqueToken.o TARGETS += KokkosCore_UnitTest_Cuda @@ -121,7 +122,8 @@ endif OBJ_OPENMP += TestOpenMP_TeamReductionScan.o OBJ_OPENMP += TestOpenMP_Other.o OBJ_OPENMP += TestOpenMP_MDRange.o - OBJ_OPENMP += TestOpenMP_Task.o + OBJ_OPENMP += TestOpenMP_Task.o TestOpenMP_WorkGraph.o + OBJ_OPENMP += TestOpenMP_UniqueToken.o TARGETS += KokkosCore_UnitTest_OpenMP @@ -208,7 +210,7 @@ endif OBJ_SERIAL += TestSerial_TeamReductionScan.o OBJ_SERIAL += TestSerial_Other.o OBJ_SERIAL += TestSerial_MDRange.o - OBJ_SERIAL += TestSerial_Task.o + OBJ_SERIAL += TestSerial_Task.o TestSerial_WorkGraph.o TARGETS += KokkosCore_UnitTest_Serial diff --git a/lib/kokkos/core/unit_test/TestAggregate.hpp b/lib/kokkos/core/unit_test/TestAggregate.hpp index 6896a27bfb..87440c36be 100644 --- a/lib/kokkos/core/unit_test/TestAggregate.hpp +++ b/lib/kokkos/core/unit_test/TestAggregate.hpp @@ -58,7 +58,7 @@ template< class DeviceType > void TestViewAggregate() { typedef Kokkos::Array< double, 32 > value_type; - typedef Kokkos::Experimental::Impl::ViewDataAnalysis< value_type *, Kokkos::LayoutLeft, value_type > analysis_1d; + typedef Kokkos::Impl::ViewDataAnalysis< value_type *, Kokkos::LayoutLeft, value_type > analysis_1d; static_assert( std::is_same< typename analysis_1d::specialize, Kokkos::Array<> >::value, "" ); diff --git a/lib/kokkos/core/unit_test/TestDefaultDeviceTypeInit.hpp b/lib/kokkos/core/unit_test/TestDefaultDeviceTypeInit.hpp index 401da58a58..68864c8d66 100644 --- a/lib/kokkos/core/unit_test/TestDefaultDeviceTypeInit.hpp +++ b/lib/kokkos/core/unit_test/TestDefaultDeviceTypeInit.hpp @@ -186,6 +186,21 @@ void check_correct_initialization( const Kokkos::InitArguments & argstruct ) { // Figure out the number of threads the HostSpace ExecutionSpace should have initialized to. int expected_nthreads = argstruct.num_threads; +#ifdef KOKKOS_ENABLE_OPENMP + if ( std::is_same< Kokkos::HostSpace::execution_space, Kokkos::OpenMP >::value ) { + // use openmp default num threads + if ( expected_nthreads < 0 || ( expected_nthreads == 0 && !Kokkos::hwloc::available() ) ) { + expected_nthreads = omp_get_max_threads(); + } + // use hwloc if available + else if ( expected_nthreads == 0 && Kokkos::hwloc::available() ) { + expected_nthreads = Kokkos::hwloc::get_available_numa_count() + * Kokkos::hwloc::get_available_cores_per_numa() + * Kokkos::hwloc::get_available_threads_per_core(); + } + } +#endif + if ( expected_nthreads < 1 ) { if ( Kokkos::hwloc::available() ) { expected_nthreads = Kokkos::hwloc::get_available_numa_count() @@ -193,12 +208,6 @@ void check_correct_initialization( const Kokkos::InitArguments & argstruct ) { * Kokkos::hwloc::get_available_threads_per_core(); } else { -#ifdef KOKKOS_ENABLE_OPENMP - if ( std::is_same< Kokkos::HostSpace::execution_space, Kokkos::OpenMP >::value ) { - expected_nthreads = omp_get_max_threads(); - } - else -#endif expected_nthreads = 1; } diff --git a/lib/kokkos/core/unit_test/TestMDRange.hpp b/lib/kokkos/core/unit_test/TestMDRange.hpp index 091591bcbf..f579ddf02c 100644 --- a/lib/kokkos/core/unit_test/TestMDRange.hpp +++ b/lib/kokkos/core/unit_test/TestMDRange.hpp @@ -51,6 +51,180 @@ namespace Test { namespace { +template +struct TestMDRange_ReduceArray_2D { + + using DataType = int; + using ViewType_2 = typename Kokkos::View< DataType**, ExecSpace >; + using HostViewType_2 = typename ViewType_2::HostMirror; + + ViewType_2 input_view; + + using scalar_type = double; + using value_type = scalar_type[]; + const unsigned value_count; + + TestMDRange_ReduceArray_2D( const int N0, const int N1, const unsigned array_size ) + : input_view( "input_view", N0, N1 ) + , value_count( array_size ) + {} + + KOKKOS_INLINE_FUNCTION + void init( scalar_type dst[] ) const + { + for ( unsigned i = 0; i < value_count; ++i ) { + dst[i] = 0.0; + } + } + + KOKKOS_INLINE_FUNCTION + void join( volatile scalar_type dst[], + const volatile scalar_type src[] ) const + { + for ( unsigned i = 0; i < value_count; ++i ) { + dst[i] += src[i]; + } + } + + + KOKKOS_INLINE_FUNCTION + void operator()( const int i, const int j ) const + { + input_view( i, j ) = 1; + } + + KOKKOS_INLINE_FUNCTION + void operator()( const int i, const int j, value_type lsum ) const + { + lsum[0] += input_view( i, j ) * 2; //+=6 each time if InitTag => N0*N1*6 + lsum[1] += input_view( i, j ) ; //+=3 each time if InitTag => N0*N1*3 + } + + // tagged operators + struct InitTag {}; + KOKKOS_INLINE_FUNCTION + void operator()( const InitTag &, const int i, const int j ) const + { + input_view( i, j ) = 3; + } + + static void test_arrayreduce2( const int N0, const int N1 ) + { + using namespace Kokkos::Experimental; + + { + typedef typename Kokkos::Experimental::MDRangePolicy< ExecSpace, Rank<2>, Kokkos::IndexType, InitTag > range_type_init; + typedef typename Kokkos::Experimental::MDRangePolicy< ExecSpace, Rank<2>, Kokkos::IndexType > range_type; + typedef typename range_type::tile_type tile_type; + typedef typename range_type::point_type point_type; + + range_type_init range_init( point_type{ { 0, 0 } }, point_type{ { N0, N1 } }, tile_type{ { 3, 3 } } ); + range_type range( point_type{ { 0, 0 } }, point_type{ { N0, N1 } }, tile_type{ { 3, 3 } } ); + + const unsigned array_size = 2; + + TestMDRange_ReduceArray_2D functor( N0, N1, array_size ); + + parallel_for( range_init, functor ); // Init the view to 3's + + double sums[ array_size ]; + parallel_reduce( range, functor, sums ); + + // Check output + //printf("Array Reduce result. N0 = %d N1 = %d N0*N1 = %d sums[0] = %lf sums[1] = %lf \n", N0, N1, N0*N1, sums[0], sums[1]); + + ASSERT_EQ( sums[0], 6 * N0 * N1 ); + ASSERT_EQ( sums[1], 3 * N0 * N1 ); + } + } +}; + +template +struct TestMDRange_ReduceArray_3D { + + using DataType = int; + using ViewType_3 = typename Kokkos::View< DataType***, ExecSpace >; + using HostViewType_3 = typename ViewType_3::HostMirror; + + ViewType_3 input_view; + + using scalar_type = double; + using value_type = scalar_type[]; + const unsigned value_count; + + TestMDRange_ReduceArray_3D( const int N0, const int N1, const int N2, const unsigned array_size ) + : input_view( "input_view", N0, N1, N2 ) + , value_count( array_size ) + {} + + KOKKOS_INLINE_FUNCTION + void init( scalar_type dst[] ) const + { + for ( unsigned i = 0; i < value_count; ++i ) { + dst[i] = 0.0; + } + } + + KOKKOS_INLINE_FUNCTION + void join( volatile scalar_type dst[], + const volatile scalar_type src[] ) const + { + for ( unsigned i = 0; i < value_count; ++i ) { + dst[i] += src[i]; + } + } + + + KOKKOS_INLINE_FUNCTION + void operator()( const int i, const int j, const int k ) const + { + input_view( i, j, k ) = 1; + } + + KOKKOS_INLINE_FUNCTION + void operator()( const int i, const int j, const int k, value_type lsum ) const + { + lsum[0] += input_view( i, j, k ) * 2; //+=6 each time if InitTag => N0*N1*N2*6 + lsum[1] += input_view( i, j, k ) ; //+=3 each time if InitTag => N0*N1*N2*3 + } + + // tagged operators + struct InitTag {}; + KOKKOS_INLINE_FUNCTION + void operator()( const InitTag &, const int i, const int j, const int k ) const + { + input_view( i, j, k ) = 3; + } + + static void test_arrayreduce3( const int N0, const int N1, const int N2 ) + { + using namespace Kokkos::Experimental; + + { + typedef typename Kokkos::Experimental::MDRangePolicy< ExecSpace, Rank<3>, Kokkos::IndexType, InitTag > range_type_init; + typedef typename Kokkos::Experimental::MDRangePolicy< ExecSpace, Rank<3>, Kokkos::IndexType > range_type; + typedef typename range_type::tile_type tile_type; + typedef typename range_type::point_type point_type; + + range_type_init range_init( point_type{ { 0, 0, 0 } }, point_type{ { N0, N1, N2 } }, tile_type{ { 3, 3, 3 } } ); + range_type range( point_type{ { 0, 0, 0 } }, point_type{ { N0, N1, N2 } }, tile_type{ { 3, 3, 3 } } ); + + const unsigned array_size = 2; + + TestMDRange_ReduceArray_3D functor( N0, N1, N2, array_size ); + + parallel_for( range_init, functor ); // Init the view to 3's + + double sums[ array_size ]; + parallel_reduce( range, functor, sums ); + + ASSERT_EQ( sums[0], 6 * N0 * N1 * N2 ); + ASSERT_EQ( sums[1], 3 * N0 * N1 * N2 ); + } + } +}; + + template struct TestMDRange_2D { using DataType = int; @@ -58,6 +232,7 @@ struct TestMDRange_2D { using HostViewType = typename ViewType::HostMirror; ViewType input_view; + using value_type = double; TestMDRange_2D( const DataType N0, const DataType N1 ) : input_view( "input_view", N0, N1 ) {} @@ -68,7 +243,7 @@ struct TestMDRange_2D { } KOKKOS_INLINE_FUNCTION - void operator()( const int i, const int j, double &lsum ) const + void operator()( const int i, const int j, value_type &lsum ) const { lsum += input_view( i, j ) * 2; } @@ -81,6 +256,13 @@ struct TestMDRange_2D { input_view( i, j ) = 3; } + // reduction tagged operators + KOKKOS_INLINE_FUNCTION + void operator()( const InitTag &, const int i, const int j, value_type &lsum ) const + { + lsum += input_view( i, j ) * 3; + } + static void test_reduce2( const int N0, const int N1 ) { using namespace Kokkos::Experimental; @@ -94,13 +276,85 @@ struct TestMDRange_2D { TestMDRange_2D functor( N0, N1 ); - md_parallel_for( range, functor ); + parallel_for( range, functor ); double sum = 0.0; - md_parallel_reduce( range, functor, sum ); + parallel_reduce( range, functor, sum ); ASSERT_EQ( sum, 2 * N0 * N1 ); } + // Test with reducers - scalar + { + typedef typename Kokkos::Experimental::MDRangePolicy< ExecSpace, Rank<2>, Kokkos::IndexType > range_type; + range_type range( {{ 0, 0 }}, {{ N0, N1 }}, {{ 3, 3 }} ); + + TestMDRange_2D functor( N0, N1 ); + + parallel_for( range, functor ); + + value_type sum = 0.0; + Kokkos::Experimental::Sum< value_type > reducer_scalar( sum ); + + parallel_reduce( range, functor, reducer_scalar ); + + ASSERT_EQ( sum, 2 * N0 * N1 ); + } + // Test with reducers - scalar view + { + typedef typename Kokkos::Experimental::MDRangePolicy< ExecSpace, Rank<2>, Kokkos::IndexType > range_type; + range_type range( {{ 0, 0 }}, {{ N0, N1 }}, {{ 3, 3 }} ); + + TestMDRange_2D functor( N0, N1 ); + + parallel_for( range, functor ); + + value_type sum = 0.0; + Kokkos::View< value_type, Kokkos::HostSpace > sum_view("sum_view"); + sum_view() = sum; + Kokkos::Experimental::Sum< value_type > reducer_view( sum_view ); + + parallel_reduce( range, functor, reducer_view); + sum = sum_view(); + + ASSERT_EQ( sum, 2 * N0 * N1 ); + } + + // Tagged operator test + { + typedef typename Kokkos::Experimental::MDRangePolicy< ExecSpace, Rank<2, Iterate::Default, Iterate::Default >, Kokkos::IndexType, InitTag > range_type; + typedef typename range_type::tile_type tile_type; + typedef typename range_type::point_type point_type; + + range_type range( point_type{ { 0, 0 } }, point_type{ { N0, N1 } }, tile_type{ { 2, 4 } } ); + + TestMDRange_2D functor( N0, N1 ); + + parallel_for( range, functor ); + + // check parallel_for results correct with InitTag + HostViewType h_view = Kokkos::create_mirror_view( functor.input_view ); + Kokkos::deep_copy( h_view, functor.input_view ); + int counter = 0; + for ( int i = 0; i < N0; ++i ) + for ( int j = 0; j < N1; ++j ) + { + if ( h_view( i, j ) != 3 ) { + ++counter; + } + } + + if ( counter != 0 ) { + printf( "Defaults + InitTag op(): Errors in test_for3; mismatches = %d\n\n", counter ); + } + ASSERT_EQ( counter, 0 ); + + + double sum = 0.0; + parallel_reduce( range, functor, sum ); + + ASSERT_EQ( sum, 9 * N0 * N1 ); + } + { typedef typename Kokkos::Experimental::MDRangePolicy< ExecSpace, Rank<2, Iterate::Default, Iterate::Default>, Kokkos::IndexType > range_type; typedef typename range_type::tile_type tile_type; @@ -110,9 +364,9 @@ struct TestMDRange_2D { TestMDRange_2D functor( N0, N1 ); - md_parallel_for( range, functor ); + parallel_for( range, functor ); double sum = 0.0; - md_parallel_reduce( range, functor, sum ); + parallel_reduce( range, functor, sum ); ASSERT_EQ( sum, 2 * N0 * N1 ); } @@ -126,9 +380,9 @@ struct TestMDRange_2D { TestMDRange_2D functor( N0, N1 ); - md_parallel_for( range, functor ); + parallel_for( range, functor ); double sum = 0.0; - md_parallel_reduce( range, functor, sum ); + parallel_reduce( range, functor, sum ); ASSERT_EQ( sum, 2 * N0 * N1 ); } @@ -142,9 +396,9 @@ struct TestMDRange_2D { TestMDRange_2D functor( N0, N1 ); - md_parallel_for( range, functor ); + parallel_for( range, functor ); double sum = 0.0; - md_parallel_reduce( range, functor, sum ); + parallel_reduce( range, functor, sum ); ASSERT_EQ( sum, 2 * N0 * N1 ); } @@ -158,9 +412,9 @@ struct TestMDRange_2D { TestMDRange_2D functor( N0, N1 ); - md_parallel_for( range, functor ); + parallel_for( range, functor ); double sum = 0.0; - md_parallel_reduce( range, functor, sum ); + parallel_reduce( range, functor, sum ); ASSERT_EQ( sum, 2 * N0 * N1 ); } @@ -174,9 +428,9 @@ struct TestMDRange_2D { TestMDRange_2D functor( N0, N1 ); - md_parallel_for( range, functor ); + parallel_for( range, functor ); double sum = 0.0; - md_parallel_reduce( range, functor, sum ); + parallel_reduce( range, functor, sum ); ASSERT_EQ( sum, 2 * N0 * N1 ); } @@ -194,7 +448,7 @@ struct TestMDRange_2D { range_type range( point_type{ { 0, 0 } }, point_type{ { N0, N1 } }, tile_type{ { 3, 3 } } ); TestMDRange_2D functor( N0, N1 ); - md_parallel_for( range, functor ); + parallel_for( range, functor ); HostViewType h_view = Kokkos::create_mirror_view( functor.input_view ); Kokkos::deep_copy( h_view, functor.input_view ); @@ -223,7 +477,7 @@ struct TestMDRange_2D { range_type range( point_type{ { 0, 0 } }, point_type{ { N0, N1 } }, tile_type{ { 3, 3 } } ); TestMDRange_2D functor( N0, N1 ); - md_parallel_for( range, functor ); + parallel_for( range, functor ); HostViewType h_view = Kokkos::create_mirror_view( functor.input_view ); Kokkos::deep_copy( h_view, functor.input_view ); @@ -251,7 +505,7 @@ struct TestMDRange_2D { range_type range( point_type{ { 0, 0 } }, point_type{ { N0, N1 } } ); TestMDRange_2D functor( N0, N1 ); - md_parallel_for( range, functor ); + parallel_for( range, functor ); HostViewType h_view = Kokkos::create_mirror_view( functor.input_view ); Kokkos::deep_copy( h_view, functor.input_view ); @@ -280,7 +534,7 @@ struct TestMDRange_2D { range_type range( point_type{ { 0, 0 } }, point_type{ { N0, N1 } }, tile_type{ { 3, 3 } } ); TestMDRange_2D functor( N0, N1 ); - md_parallel_for( range, functor ); + parallel_for( range, functor ); HostViewType h_view = Kokkos::create_mirror_view( functor.input_view ); Kokkos::deep_copy( h_view, functor.input_view ); @@ -309,7 +563,7 @@ struct TestMDRange_2D { range_type range( point_type{ { 0, 0 } }, point_type{ { N0, N1 } }, tile_type{ { 4, 4 } } ); TestMDRange_2D functor( N0, N1 ); - md_parallel_for( range, functor ); + parallel_for( range, functor ); HostViewType h_view = Kokkos::create_mirror_view( functor.input_view ); Kokkos::deep_copy( h_view, functor.input_view ); @@ -338,7 +592,7 @@ struct TestMDRange_2D { range_type range( point_type{ { 0, 0 } }, point_type{ { N0, N1 } }, tile_type{ { 3, 3 } } ); TestMDRange_2D functor( N0, N1 ); - md_parallel_for( range, functor ); + parallel_for( range, functor ); HostViewType h_view = Kokkos::create_mirror_view( functor.input_view ); Kokkos::deep_copy( h_view, functor.input_view ); @@ -367,7 +621,7 @@ struct TestMDRange_2D { range_type range( point_type{ { 0, 0 } }, point_type{ { N0, N1 } }, tile_type{ { 7, 7 } } ); TestMDRange_2D functor( N0, N1 ); - md_parallel_for( range, functor ); + parallel_for( range, functor ); HostViewType h_view = Kokkos::create_mirror_view( functor.input_view ); Kokkos::deep_copy( h_view, functor.input_view ); @@ -396,7 +650,7 @@ struct TestMDRange_2D { range_type range( point_type{ { 0, 0 } }, point_type{ { N0, N1 } }, tile_type{ { 16, 16 } } ); TestMDRange_2D functor( N0, N1 ); - md_parallel_for( range, functor ); + parallel_for( range, functor ); HostViewType h_view = Kokkos::create_mirror_view( functor.input_view ); Kokkos::deep_copy( h_view, functor.input_view ); @@ -425,7 +679,7 @@ struct TestMDRange_2D { range_type range( point_type{ { 0, 0 } }, point_type{ { N0, N1 } }, tile_type{ { 5, 16 } } ); TestMDRange_2D functor( N0, N1 ); - md_parallel_for( range, functor ); + parallel_for( range, functor ); HostViewType h_view = Kokkos::create_mirror_view( functor.input_view ); Kokkos::deep_copy( h_view, functor.input_view ); @@ -455,6 +709,7 @@ struct TestMDRange_3D { using HostViewType = typename ViewType::HostMirror; ViewType input_view; + using value_type = double; TestMDRange_3D( const DataType N0, const DataType N1, const DataType N2 ) : input_view( "input_view", N0, N1, N2 ) {} @@ -478,6 +733,13 @@ struct TestMDRange_3D { input_view( i, j, k ) = 3; } + // reduction tagged operators + KOKKOS_INLINE_FUNCTION + void operator()( const InitTag &, const int i, const int j, const int k, value_type &lsum ) const + { + lsum += input_view( i, j, k ) * 3; + } + static void test_reduce3( const int N0, const int N1, const int N2 ) { using namespace Kokkos::Experimental; @@ -491,13 +753,86 @@ struct TestMDRange_3D { TestMDRange_3D functor( N0, N1, N2 ); - md_parallel_for( range, functor ); + parallel_for( range, functor ); double sum = 0.0; - md_parallel_reduce( range, functor, sum ); + parallel_reduce( range, functor, sum ); ASSERT_EQ( sum, 2 * N0 * N1 * N2 ); } + // Test with reducers - scalar + { + typedef typename Kokkos::Experimental::MDRangePolicy< ExecSpace, Rank<3>, Kokkos::IndexType > range_type; + range_type range( {{ 0, 0, 0 }}, {{ N0, N1, N2 }}, {{ 3, 3, 3 }} ); + + TestMDRange_3D functor( N0, N1, N2 ); + + parallel_for( range, functor ); + + value_type sum = 0.0; + Kokkos::Experimental::Sum< value_type > reducer_scalar( sum ); + + parallel_reduce( range, functor, reducer_scalar ); + + ASSERT_EQ( sum, 2 * N0 * N1 * N2 ); + } + // Test with reducers - scalar view + { + typedef typename Kokkos::Experimental::MDRangePolicy< ExecSpace, Rank<3>, Kokkos::IndexType > range_type; + range_type range( {{ 0, 0, 0 }}, {{ N0, N1, N2 }}, {{ 3, 3, 3 }} ); + + TestMDRange_3D functor( N0, N1, N2 ); + + parallel_for( range, functor ); + + value_type sum = 0.0; + Kokkos::View< value_type, Kokkos::HostSpace > sum_view("sum_view"); + sum_view() = sum; + Kokkos::Experimental::Sum< value_type > reducer_view( sum_view ); + + parallel_reduce( range, functor, reducer_view); + sum = sum_view(); + + ASSERT_EQ( sum, 2 * N0 * N1 * N2 ); + } + + // Tagged operator test + { + typedef typename Kokkos::Experimental::MDRangePolicy< ExecSpace, Rank<3, Iterate::Default, Iterate::Default >, Kokkos::IndexType, InitTag > range_type; + typedef typename range_type::tile_type tile_type; + typedef typename range_type::point_type point_type; + + range_type range( point_type{ { 0, 0, 0 } }, point_type{ { N0, N1, N2 } }, tile_type{ { 2, 4, 6 } } ); + + TestMDRange_3D functor( N0, N1, N2 ); + + parallel_for( range, functor ); + + // check parallel_for results correct with InitTag + HostViewType h_view = Kokkos::create_mirror_view( functor.input_view ); + Kokkos::deep_copy( h_view, functor.input_view ); + int counter = 0; + for ( int i = 0; i < N0; ++i ) + for ( int j = 0; j < N1; ++j ) + for ( int k = 0; k < N2; ++k ) + { + if ( h_view( i, j, k ) != 3 ) { + ++counter; + } + } + + if ( counter != 0 ) { + printf( "Defaults + InitTag op(): Errors in test_for3; mismatches = %d\n\n", counter ); + } + ASSERT_EQ( counter, 0 ); + + + double sum = 0.0; + parallel_reduce( range, functor, sum ); + + ASSERT_EQ( sum, 9 * N0 * N1 * N2 ); + } + { typedef typename Kokkos::Experimental::MDRangePolicy< ExecSpace, Rank<3, Iterate::Default, Iterate::Default >, Kokkos::IndexType > range_type; typedef typename range_type::tile_type tile_type; @@ -507,9 +842,9 @@ struct TestMDRange_3D { TestMDRange_3D functor( N0, N1, N2 ); - md_parallel_for( range, functor ); + parallel_for( range, functor ); double sum = 0.0; - md_parallel_reduce( range, functor, sum ); + parallel_reduce( range, functor, sum ); ASSERT_EQ( sum, 2 * N0 * N1 * N2 ); } @@ -523,9 +858,9 @@ struct TestMDRange_3D { TestMDRange_3D functor( N0, N1, N2 ); - md_parallel_for( range, functor ); + parallel_for( range, functor ); double sum = 0.0; - md_parallel_reduce( range, functor, sum ); + parallel_reduce( range, functor, sum ); ASSERT_EQ( sum, 2 * N0 * N1 * N2 ); } @@ -539,9 +874,9 @@ struct TestMDRange_3D { TestMDRange_3D functor( N0, N1, N2 ); - md_parallel_for( range, functor ); + parallel_for( range, functor ); double sum = 0.0; - md_parallel_reduce( range, functor, sum ); + parallel_reduce( range, functor, sum ); ASSERT_EQ( sum, 2 * N0 * N1 * N2 ); } @@ -555,9 +890,9 @@ struct TestMDRange_3D { TestMDRange_3D functor( N0, N1, N2 ); - md_parallel_for( range, functor ); + parallel_for( range, functor ); double sum = 0.0; - md_parallel_reduce( range, functor, sum ); + parallel_reduce( range, functor, sum ); ASSERT_EQ( sum, 2 * N0 * N1 * N2 ); } @@ -571,9 +906,9 @@ struct TestMDRange_3D { TestMDRange_3D functor( N0, N1, N2 ); - md_parallel_for( range, functor ); + parallel_for( range, functor ); double sum = 0.0; - md_parallel_reduce( range, functor, sum ); + parallel_reduce( range, functor, sum ); ASSERT_EQ( sum, 2 * N0 * N1 * N2 ); } @@ -590,7 +925,7 @@ struct TestMDRange_3D { range_type range( point_type{ { 0, 0, 0 } }, point_type{ { N0, N1, N2 } } ); TestMDRange_3D functor( N0, N1, N2 ); - md_parallel_for( range, functor ); + parallel_for( range, functor ); HostViewType h_view = Kokkos::create_mirror_view( functor.input_view ); Kokkos::deep_copy( h_view, functor.input_view ); @@ -620,7 +955,7 @@ struct TestMDRange_3D { range_type range( point_type{ { 0, 0, 0 } }, point_type{ { N0, N1, N2 } }, tile_type{ { 3, 3, 3 } } ); TestMDRange_3D functor( N0, N1, N2 ); - md_parallel_for( range, functor ); + parallel_for( range, functor ); HostViewType h_view = Kokkos::create_mirror_view( functor.input_view ); Kokkos::deep_copy( h_view, functor.input_view ); @@ -651,7 +986,7 @@ struct TestMDRange_3D { TestMDRange_3D functor( N0, N1, N2 ); - md_parallel_for( range, functor ); + parallel_for( range, functor ); HostViewType h_view = Kokkos::create_mirror_view( functor.input_view ); Kokkos::deep_copy( h_view, functor.input_view ); @@ -681,7 +1016,7 @@ struct TestMDRange_3D { range_type range( point_type{ { 0, 0, 0 } }, point_type{ { N0, N1, N2 } }, tile_type{ { 3, 3, 3 } } ); TestMDRange_3D functor( N0, N1, N2 ); - md_parallel_for( range, functor ); + parallel_for( range, functor ); HostViewType h_view = Kokkos::create_mirror_view( functor.input_view ); Kokkos::deep_copy( h_view, functor.input_view ); @@ -711,7 +1046,7 @@ struct TestMDRange_3D { range_type range( point_type{ { 0, 0, 0 } }, point_type{ { N0, N1, N2 } }, tile_type{ { 2, 4, 2 } } ); TestMDRange_3D functor( N0, N1, N2 ); - md_parallel_for( range, functor ); + parallel_for( range, functor ); HostViewType h_view = Kokkos::create_mirror_view( functor.input_view ); Kokkos::deep_copy( h_view, functor.input_view ); @@ -741,7 +1076,7 @@ struct TestMDRange_3D { range_type range( point_type{ { 0, 0, 0 } }, point_type{ { N0, N1, N2 } }, tile_type{ { 3, 5, 7 } } ); TestMDRange_3D functor( N0, N1, N2 ); - md_parallel_for( range, functor ); + parallel_for( range, functor ); HostViewType h_view = Kokkos::create_mirror_view( functor.input_view ); Kokkos::deep_copy( h_view, functor.input_view ); @@ -771,7 +1106,7 @@ struct TestMDRange_3D { range_type range( point_type{ { 0, 0, 0 } }, point_type{ { N0, N1, N2 } }, tile_type{ { 8, 8, 8 } } ); TestMDRange_3D functor( N0, N1, N2 ); - md_parallel_for( range, functor ); + parallel_for( range, functor ); HostViewType h_view = Kokkos::create_mirror_view( functor.input_view ); Kokkos::deep_copy( h_view, functor.input_view ); @@ -801,7 +1136,7 @@ struct TestMDRange_3D { range_type range( point_type{ { 0, 0, 0 } }, point_type{ { N0, N1, N2 } }, tile_type{ { 2, 4, 2 } } ); TestMDRange_3D functor( N0, N1, N2 ); - md_parallel_for( range, functor ); + parallel_for( range, functor ); HostViewType h_view = Kokkos::create_mirror_view( functor.input_view ); Kokkos::deep_copy( h_view, functor.input_view ); @@ -832,6 +1167,7 @@ struct TestMDRange_4D { using HostViewType = typename ViewType::HostMirror; ViewType input_view; + using value_type = double; TestMDRange_4D( const DataType N0, const DataType N1, const DataType N2, const DataType N3 ) : input_view( "input_view", N0, N1, N2, N3 ) {} @@ -855,6 +1191,191 @@ struct TestMDRange_4D { input_view( i, j, k, l ) = 3; } + // reduction tagged operators + KOKKOS_INLINE_FUNCTION + void operator()( const InitTag &, const int i, const int j, const int k, const int l, value_type &lsum ) const + { + lsum += input_view( i, j, k, l ) * 3; + } + + static void test_reduce4( const int N0, const int N1, const int N2, const int N3 ) + { + using namespace Kokkos::Experimental; + + { + typedef typename Kokkos::Experimental::MDRangePolicy< ExecSpace, Rank<4>, Kokkos::IndexType > range_type; + typedef typename range_type::tile_type tile_type; + typedef typename range_type::point_type point_type; + + range_type range( point_type{ { 0, 0, 0, 0 } }, point_type{ { N0, N1, N2, N3 } }, tile_type{ { 3, 3, 3, 3 } } ); + + TestMDRange_4D functor( N0, N1, N2, N3 ); + + parallel_for( range, functor ); + double sum = 0.0; + parallel_reduce( range, functor, sum ); + + ASSERT_EQ( sum, 2 * N0 * N1 * N2 * N3 ); + } + + // Test with reducers - scalar + { + typedef typename Kokkos::Experimental::MDRangePolicy< ExecSpace, Rank<4>, Kokkos::IndexType > range_type; + range_type range( {{ 0, 0, 0, 0 }}, {{ N0, N1, N2, N3 }}, {{ 3, 3, 3, 3 }} ); + + TestMDRange_4D functor( N0, N1, N2, N3 ); + + parallel_for( range, functor ); + + value_type sum = 0.0; + Kokkos::Experimental::Sum< value_type > reducer_scalar( sum ); + + parallel_reduce( range, functor, reducer_scalar ); + + ASSERT_EQ( sum, 2 * N0 * N1 * N2 * N3 ); + } + + // Test with reducers - scalar view + { + typedef typename Kokkos::Experimental::MDRangePolicy< ExecSpace, Rank<4>, Kokkos::IndexType > range_type; + range_type range( {{ 0, 0, 0, 0 }}, {{ N0, N1, N2, N3 }}, {{ 3, 3, 3, 3 }} ); + + TestMDRange_4D functor( N0, N1, N2, N3 ); + + parallel_for( range, functor ); + + value_type sum = 0.0; + Kokkos::View< value_type, Kokkos::HostSpace > sum_view("sum_view"); + sum_view() = sum; + Kokkos::Experimental::Sum< value_type > reducer_view( sum_view ); + + parallel_reduce( range, functor, reducer_view); + sum = sum_view(); + + ASSERT_EQ( sum, 2 * N0 * N1 * N2 * N3 ); + } + + // Tagged operator test + { + typedef typename Kokkos::Experimental::MDRangePolicy< ExecSpace, Rank<4, Iterate::Default, Iterate::Default >, Kokkos::IndexType, InitTag > range_type; + typedef typename range_type::tile_type tile_type; + typedef typename range_type::point_type point_type; + + range_type range( point_type{ { 0, 0, 0, 0 } }, point_type{ { N0, N1, N2, N3 } }, tile_type{ { 2, 4, 6, 2 } } ); + + TestMDRange_4D functor( N0, N1, N2, N3 ); + + parallel_for( range, functor ); + + // check parallel_for results correct with InitTag + HostViewType h_view = Kokkos::create_mirror_view( functor.input_view ); + Kokkos::deep_copy( h_view, functor.input_view ); + int counter = 0; + for ( int i = 0; i < N0; ++i ) + for ( int j = 0; j < N1; ++j ) + for ( int k = 0; k < N2; ++k ) + for ( int l = 0; l < N3; ++l ) + { + if ( h_view( i, j, k, l ) != 3 ) { + ++counter; + } + } + + if ( counter != 0 ) { + printf( "Defaults + InitTag op(): Errors in test_reduce4 parallel_for init; mismatches = %d\n\n", counter ); + } + ASSERT_EQ( counter, 0 ); + + + double sum = 0.0; + parallel_reduce( range, functor, sum ); + + ASSERT_EQ( sum, 9 * N0 * N1 * N2 * N3 ); + } + + { + typedef typename Kokkos::Experimental::MDRangePolicy< ExecSpace, Rank<4, Iterate::Default, Iterate::Default >, Kokkos::IndexType > range_type; + typedef typename range_type::tile_type tile_type; + typedef typename range_type::point_type point_type; + + range_type range( point_type{ { 0, 0, 0, 0 } }, point_type{ { N0, N1, N2, N3 } }, tile_type{ { 2, 4, 6, 2 } } ); + + TestMDRange_4D functor( N0, N1, N2, N3 ); + + parallel_for( range, functor ); + double sum = 0.0; + parallel_reduce( range, functor, sum ); + + ASSERT_EQ( sum, 2 * N0 * N1 * N2 * N3 ); + } + + { + typedef typename Kokkos::Experimental::MDRangePolicy< ExecSpace, Rank<4, Iterate::Left, Iterate::Left>, Kokkos::IndexType > range_type; + typedef typename range_type::tile_type tile_type; + typedef typename range_type::point_type point_type; + + range_type range( point_type{ { 0, 0, 0, 0 } }, point_type{ { N0, N1, N2, N3 } }, tile_type{ { 2, 4, 6, 2 } } ); + + TestMDRange_4D functor( N0, N1, N2, N3 ); + + parallel_for( range, functor ); + double sum = 0.0; + parallel_reduce( range, functor, sum ); + + ASSERT_EQ( sum, 2 * N0 * N1 * N2 * N3 ); + } + + { + typedef typename Kokkos::Experimental::MDRangePolicy< ExecSpace, Rank<4, Iterate::Left, Iterate::Right>, Kokkos::IndexType > range_type; + typedef typename range_type::tile_type tile_type; + typedef typename range_type::point_type point_type; + + range_type range( point_type{ { 0, 0, 0, 0 } }, point_type{ { N0, N1, N2, N3 } }, tile_type{ { 2, 4, 6, 2 } } ); + + TestMDRange_4D functor( N0, N1, N2, N3 ); + + parallel_for( range, functor ); + double sum = 0.0; + parallel_reduce( range, functor, sum ); + + ASSERT_EQ( sum, 2 * N0 * N1 * N2 * N3 ); + } + + { + typedef typename Kokkos::Experimental::MDRangePolicy< ExecSpace, Rank<4, Iterate::Right, Iterate::Left>, Kokkos::IndexType > range_type; + typedef typename range_type::tile_type tile_type; + typedef typename range_type::point_type point_type; + + range_type range( point_type{ { 0, 0, 0, 0 } }, point_type{ { N0, N1, N2, N3 } }, tile_type{ { 2, 4, 6, 2 } } ); + + TestMDRange_4D functor( N0, N1, N2, N3 ); + + parallel_for( range, functor ); + double sum = 0.0; + parallel_reduce( range, functor, sum ); + + ASSERT_EQ( sum, 2 * N0 * N1 * N2 * N3 ); + } + + { + typedef typename Kokkos::Experimental::MDRangePolicy< ExecSpace, Rank<4, Iterate::Right, Iterate::Right>, Kokkos::IndexType > range_type; + typedef typename range_type::tile_type tile_type; + typedef typename range_type::point_type point_type; + + range_type range( point_type{ { 0, 0, 0, 0 } }, point_type{ { N0, N1, N2, N3 } }, tile_type{ { 2, 4, 6, 2 } } ); + + TestMDRange_4D functor( N0, N1, N2, N3 ); + + parallel_for( range, functor ); + double sum = 0.0; + parallel_reduce( range, functor, sum ); + + ASSERT_EQ( sum, 2 * N0 * N1 * N2 * N3 ); + } + } // end test_reduce + + + static void test_for4( const int N0, const int N1, const int N2, const int N3 ) { using namespace Kokkos::Experimental; @@ -866,7 +1387,7 @@ struct TestMDRange_4D { range_type range( point_type{ { 0, 0, 0, 0 } }, point_type{ { N0, N1, N2, N3 } } ); TestMDRange_4D functor( N0, N1, N2, N3 ); - md_parallel_for( range, functor ); + parallel_for( range, functor ); HostViewType h_view = Kokkos::create_mirror_view( functor.input_view ); Kokkos::deep_copy( h_view, functor.input_view ); @@ -897,7 +1418,7 @@ struct TestMDRange_4D { range_type range( point_type{ { 0, 0, 0, 0 } }, point_type{ { N0, N1, N2, N3 } }, tile_type{ { 3, 11, 3, 3 } } ); TestMDRange_4D functor( N0, N1, N2, N3 ); - md_parallel_for( range, functor ); + parallel_for( range, functor ); HostViewType h_view = Kokkos::create_mirror_view( functor.input_view ); Kokkos::deep_copy( h_view, functor.input_view ); @@ -929,7 +1450,7 @@ struct TestMDRange_4D { TestMDRange_4D functor( N0, N1, N2, N3 ); - md_parallel_for( range, functor ); + parallel_for( range, functor ); HostViewType h_view = Kokkos::create_mirror_view( functor.input_view ); Kokkos::deep_copy( h_view, functor.input_view ); @@ -961,7 +1482,7 @@ struct TestMDRange_4D { TestMDRange_4D functor( N0, N1, N2, N3 ); - md_parallel_for( range, functor ); + parallel_for( range, functor ); HostViewType h_view = Kokkos::create_mirror_view( functor.input_view ); Kokkos::deep_copy( h_view, functor.input_view ); @@ -993,7 +1514,7 @@ struct TestMDRange_4D { TestMDRange_4D functor( N0, N1, N2, N3 ); - md_parallel_for( range, functor ); + parallel_for( range, functor ); HostViewType h_view = Kokkos::create_mirror_view( functor.input_view ); Kokkos::deep_copy( h_view, functor.input_view ); @@ -1025,7 +1546,7 @@ struct TestMDRange_4D { TestMDRange_4D functor( N0, N1, N2, N3 ); - md_parallel_for( range, functor ); + parallel_for( range, functor ); HostViewType h_view = Kokkos::create_mirror_view( functor.input_view ); Kokkos::deep_copy( h_view, functor.input_view ); @@ -1057,7 +1578,7 @@ struct TestMDRange_4D { TestMDRange_4D functor( N0, N1, N2, N3 ); - md_parallel_for( range, functor ); + parallel_for( range, functor ); HostViewType h_view = Kokkos::create_mirror_view( functor.input_view ); Kokkos::deep_copy( h_view, functor.input_view ); @@ -1089,7 +1610,7 @@ struct TestMDRange_4D { TestMDRange_4D functor( N0, N1, N2, N3 ); - md_parallel_for( range, functor ); + parallel_for( range, functor ); HostViewType h_view = Kokkos::create_mirror_view( functor.input_view ); Kokkos::deep_copy( h_view, functor.input_view ); @@ -1121,6 +1642,7 @@ struct TestMDRange_5D { using HostViewType = typename ViewType::HostMirror; ViewType input_view; + using value_type = double; TestMDRange_5D( const DataType N0, const DataType N1, const DataType N2, const DataType N3, const DataType N4 ) : input_view( "input_view", N0, N1, N2, N3, N4 ) {} @@ -1131,7 +1653,7 @@ struct TestMDRange_5D { } KOKKOS_INLINE_FUNCTION - void operator()( const int i, const int j, const int k, const int l, const int m, double &lsum ) const + void operator()( const int i, const int j, const int k, const int l, const int m, value_type &lsum ) const { lsum += input_view( i, j, k, l, m ) * 2; } @@ -1144,6 +1666,110 @@ struct TestMDRange_5D { input_view( i, j, k, l, m ) = 3; } + // reduction tagged operators + KOKKOS_INLINE_FUNCTION + void operator()( const InitTag &, const int i, const int j, const int k, const int l, const int m, value_type &lsum ) const + { + lsum += input_view( i, j, k, l, m ) * 3; + } + + static void test_reduce5( const int N0, const int N1, const int N2, const int N3, const int N4 ) + { + using namespace Kokkos::Experimental; + + { + typedef typename Kokkos::Experimental::MDRangePolicy< ExecSpace, Rank<5>, Kokkos::IndexType > range_type; + typedef typename range_type::tile_type tile_type; + typedef typename range_type::point_type point_type; + + range_type range( point_type{ { 0, 0, 0, 0, 0 } }, point_type{ { N0, N1, N2, N3, N4 } }, tile_type{ { 3, 3, 3, 3, 3 } } ); + + TestMDRange_5D functor( N0, N1, N2, N3, N4 ); + + parallel_for( range, functor ); + double sum = 0.0; + parallel_reduce( range, functor, sum ); + + ASSERT_EQ( sum, 2 * N0 * N1 * N2 * N3 * N4 ); + } + + // Test with reducers - scalar + { + typedef typename Kokkos::Experimental::MDRangePolicy< ExecSpace, Rank<5>, Kokkos::IndexType > range_type; + range_type range( {{ 0, 0, 0, 0, 0 }}, {{ N0, N1, N2, N3, N4 }}, {{ 3, 3, 3, 3, 3 }} ); + + TestMDRange_5D functor( N0, N1, N2, N3, N4 ); + + parallel_for( range, functor ); + + value_type sum = 0.0; + Kokkos::Experimental::Sum< value_type > reducer_scalar( sum ); + + parallel_reduce( range, functor, reducer_scalar ); + + ASSERT_EQ( sum, 2 * N0 * N1 * N2 * N3 * N4 ); + } + + // Test with reducers - scalar view + { + typedef typename Kokkos::Experimental::MDRangePolicy< ExecSpace, Rank<5>, Kokkos::IndexType > range_type; + range_type range( {{ 0, 0, 0, 0, 0 }}, {{ N0, N1, N2, N3, N4 }}, {{ 3, 3, 3, 3, 3 }} ); + + TestMDRange_5D functor( N0, N1, N2, N3, N4 ); + + parallel_for( range, functor ); + + value_type sum = 0.0; + Kokkos::View< value_type, Kokkos::HostSpace > sum_view("sum_view"); + sum_view() = sum; + Kokkos::Experimental::Sum< value_type > reducer_view( sum_view ); + + parallel_reduce( range, functor, reducer_view); + sum = sum_view(); + + ASSERT_EQ( sum, 2 * N0 * N1 * N2 * N3 * N4 ); + } + + // Tagged operator test + { + typedef typename Kokkos::Experimental::MDRangePolicy< ExecSpace, Rank<5, Iterate::Default, Iterate::Default >, Kokkos::IndexType, InitTag > range_type; + typedef typename range_type::tile_type tile_type; + typedef typename range_type::point_type point_type; + + range_type range( point_type{ { 0, 0, 0, 0, 0 } }, point_type{ { N0, N1, N2, N3, N4 } }, tile_type{ { 2, 4, 6, 2, 2 } } ); + + TestMDRange_5D functor( N0, N1, N2, N3, N4 ); + + parallel_for( range, functor ); + + // check parallel_for results correct with InitTag + HostViewType h_view = Kokkos::create_mirror_view( functor.input_view ); + Kokkos::deep_copy( h_view, functor.input_view ); + int counter = 0; + for ( int i = 0; i < N0; ++i ) + for ( int j = 0; j < N1; ++j ) + for ( int k = 0; k < N2; ++k ) + for ( int l = 0; l < N3; ++l ) + for ( int m = 0; m < N4; ++m ) + { + if ( h_view( i, j, k, l, m ) != 3 ) { + ++counter; + } + } + + if ( counter != 0 ) { + printf( "Defaults + InitTag op(): Errors in test_reduce5 parallel_for init; mismatches = %d\n\n", counter ); + } + ASSERT_EQ( counter, 0 ); + + + double sum = 0.0; + parallel_reduce( range, functor, sum ); + + ASSERT_EQ( sum, 9 * N0 * N1 * N2 * N3 * N4 ); + } + } + static void test_for5( const int N0, const int N1, const int N2, const int N3, const int N4 ) { using namespace Kokkos::Experimental; @@ -1155,7 +1781,7 @@ struct TestMDRange_5D { range_type range( point_type{ { 0, 0, 0, 0, 0 } }, point_type{ { N0, N1, N2, N3, N4 } } ); TestMDRange_5D functor( N0, N1, N2, N3, N4 ); - md_parallel_for( range, functor ); + parallel_for( range, functor ); HostViewType h_view = Kokkos::create_mirror_view( functor.input_view ); Kokkos::deep_copy( h_view, functor.input_view ); @@ -1184,10 +1810,10 @@ struct TestMDRange_5D { typedef typename range_type::tile_type tile_type; typedef typename range_type::point_type point_type; - range_type range( point_type{ { 0, 0, 0, 0, 0 } }, point_type{ { N0, N1, N2, N3, N4 } }, tile_type{ { 3, 3, 3, 3, 7 } } ); + range_type range( point_type{ { 0, 0, 0, 0, 0 } }, point_type{ { N0, N1, N2, N3, N4 } }, tile_type{ { 3, 3, 3, 3, 5 } } ); TestMDRange_5D functor( N0, N1, N2, N3, N4 ); - md_parallel_for( range, functor ); + parallel_for( range, functor ); HostViewType h_view = Kokkos::create_mirror_view( functor.input_view ); Kokkos::deep_copy( h_view, functor.input_view ); @@ -1220,7 +1846,7 @@ struct TestMDRange_5D { TestMDRange_5D functor( N0, N1, N2, N3, N4 ); - md_parallel_for( range, functor ); + parallel_for( range, functor ); HostViewType h_view = Kokkos::create_mirror_view( functor.input_view ); Kokkos::deep_copy( h_view, functor.input_view ); @@ -1253,7 +1879,7 @@ struct TestMDRange_5D { TestMDRange_5D functor( N0, N1, N2, N3, N4 ); - md_parallel_for( range, functor ); + parallel_for( range, functor ); HostViewType h_view = Kokkos::create_mirror_view( functor.input_view ); Kokkos::deep_copy( h_view, functor.input_view ); @@ -1286,7 +1912,7 @@ struct TestMDRange_5D { TestMDRange_5D functor( N0, N1, N2, N3, N4 ); - md_parallel_for( range, functor ); + parallel_for( range, functor ); HostViewType h_view = Kokkos::create_mirror_view( functor.input_view ); Kokkos::deep_copy( h_view, functor.input_view ); @@ -1319,7 +1945,7 @@ struct TestMDRange_5D { TestMDRange_5D functor( N0, N1, N2, N3, N4 ); - md_parallel_for( range, functor ); + parallel_for( range, functor ); HostViewType h_view = Kokkos::create_mirror_view( functor.input_view ); Kokkos::deep_copy( h_view, functor.input_view ); @@ -1352,7 +1978,7 @@ struct TestMDRange_5D { TestMDRange_5D functor( N0, N1, N2, N3, N4 ); - md_parallel_for( range, functor ); + parallel_for( range, functor ); HostViewType h_view = Kokkos::create_mirror_view( functor.input_view ); Kokkos::deep_copy( h_view, functor.input_view ); @@ -1385,7 +2011,7 @@ struct TestMDRange_5D { TestMDRange_5D functor( N0, N1, N2, N3, N4 ); - md_parallel_for( range, functor ); + parallel_for( range, functor ); HostViewType h_view = Kokkos::create_mirror_view( functor.input_view ); Kokkos::deep_copy( h_view, functor.input_view ); @@ -1418,6 +2044,7 @@ struct TestMDRange_6D { using HostViewType = typename ViewType::HostMirror; ViewType input_view; + using value_type = double; TestMDRange_6D( const DataType N0, const DataType N1, const DataType N2, const DataType N3, const DataType N4, const DataType N5 ) : input_view( "input_view", N0, N1, N2, N3, N4, N5 ) {} @@ -1428,7 +2055,7 @@ struct TestMDRange_6D { } KOKKOS_INLINE_FUNCTION - void operator()( const int i, const int j, const int k, const int l, const int m, const int n, double &lsum ) const + void operator()( const int i, const int j, const int k, const int l, const int m, const int n, value_type &lsum ) const { lsum += input_view( i, j, k, l, m, n ) * 2; } @@ -1441,6 +2068,111 @@ struct TestMDRange_6D { input_view( i, j, k, l, m, n ) = 3; } + // reduction tagged operators + KOKKOS_INLINE_FUNCTION + void operator()( const InitTag &, const int i, const int j, const int k, const int l, const int m, const int n, value_type &lsum ) const + { + lsum += input_view( i, j, k, l, m, n ) * 3; + } + + static void test_reduce6( const int N0, const int N1, const int N2, const int N3, const int N4, const int N5 ) + { + using namespace Kokkos::Experimental; + + { + typedef typename Kokkos::Experimental::MDRangePolicy< ExecSpace, Rank<6>, Kokkos::IndexType > range_type; + typedef typename range_type::tile_type tile_type; + typedef typename range_type::point_type point_type; + + range_type range( point_type{ { 0, 0, 0, 0, 0, 0 } }, point_type{ { N0, N1, N2, N3, N4, N5 } }, tile_type{ { 3, 3, 3, 3, 3, 2 } } ); + + TestMDRange_6D functor( N0, N1, N2, N3, N4, N5 ); + + parallel_for( range, functor ); + double sum = 0.0; + parallel_reduce( range, functor, sum ); + + ASSERT_EQ( sum, 2 * N0 * N1 * N2 * N3 * N4 * N5 ); + } + + // Test with reducers - scalar + { + typedef typename Kokkos::Experimental::MDRangePolicy< ExecSpace, Rank<6>, Kokkos::IndexType > range_type; + range_type range( {{ 0, 0, 0, 0, 0, 0 }}, {{ N0, N1, N2, N3, N4, N5 }}, {{ 3, 3, 3, 3, 3, 2 }} ); + + TestMDRange_6D functor( N0, N1, N2, N3, N4, N5 ); + + parallel_for( range, functor ); + + value_type sum = 0.0; + Kokkos::Experimental::Sum< value_type > reducer_scalar( sum ); + + parallel_reduce( range, functor, reducer_scalar ); + + ASSERT_EQ( sum, 2 * N0 * N1 * N2 * N3 * N4 * N5 ); + } + + // Test with reducers - scalar view + { + typedef typename Kokkos::Experimental::MDRangePolicy< ExecSpace, Rank<6>, Kokkos::IndexType > range_type; + range_type range( {{ 0, 0, 0, 0, 0, 0 }}, {{ N0, N1, N2, N3, N4, N5 }}, {{ 3, 3, 3, 3, 3, 2 }} ); + + TestMDRange_6D functor( N0, N1, N2, N3, N4, N5 ); + + parallel_for( range, functor ); + + value_type sum = 0.0; + Kokkos::View< value_type, Kokkos::HostSpace > sum_view("sum_view"); + sum_view() = sum; + Kokkos::Experimental::Sum< value_type > reducer_view( sum_view ); + + parallel_reduce( range, functor, reducer_view); + sum = sum_view(); + + ASSERT_EQ( sum, 2 * N0 * N1 * N2 * N3 * N4 * N5 ); + } + + // Tagged operator test + { + typedef typename Kokkos::Experimental::MDRangePolicy< ExecSpace, Rank<6, Iterate::Default, Iterate::Default >, Kokkos::IndexType, InitTag > range_type; + typedef typename range_type::tile_type tile_type; + typedef typename range_type::point_type point_type; + + range_type range( point_type{ { 0, 0, 0, 0, 0, 0 } }, point_type{ { N0, N1, N2, N3, N4, N5 } }, tile_type{ { 2, 4, 6, 2, 2, 2 } } ); + + TestMDRange_6D functor( N0, N1, N2, N3, N4, N5 ); + + parallel_for( range, functor ); + + // check parallel_for results correct with InitTag + HostViewType h_view = Kokkos::create_mirror_view( functor.input_view ); + Kokkos::deep_copy( h_view, functor.input_view ); + int counter = 0; + for ( int i = 0; i < N0; ++i ) + for ( int j = 0; j < N1; ++j ) + for ( int k = 0; k < N2; ++k ) + for ( int l = 0; l < N3; ++l ) + for ( int m = 0; m < N4; ++m ) + for ( int n = 0; n < N5; ++n ) + { + if ( h_view( i, j, k, l, m, n ) != 3 ) { + ++counter; + } + } + + if ( counter != 0 ) { + printf( "Defaults + InitTag op(): Errors in test_reduce6 parallel_for init; mismatches = %d\n\n", counter ); + } + ASSERT_EQ( counter, 0 ); + + + double sum = 0.0; + parallel_reduce( range, functor, sum ); + + ASSERT_EQ( sum, 9 * N0 * N1 * N2 * N3 * N4 * N5 ); + } + } + static void test_for6( const int N0, const int N1, const int N2, const int N3, const int N4, const int N5 ) { using namespace Kokkos::Experimental; @@ -1452,7 +2184,7 @@ struct TestMDRange_6D { range_type range( point_type{ { 0, 0, 0, 0, 0, 0 } }, point_type{ { N0, N1, N2, N3, N4, N5 } } ); TestMDRange_6D functor( N0, N1, N2, N3, N4, N5 ); - md_parallel_for( range, functor ); + parallel_for( range, functor ); HostViewType h_view = Kokkos::create_mirror_view( functor.input_view ); Kokkos::deep_copy( h_view, functor.input_view ); @@ -1485,7 +2217,7 @@ struct TestMDRange_6D { range_type range( point_type{ { 0, 0, 0, 0, 0, 0 } }, point_type{ { N0, N1, N2, N3, N4, N5 } }, tile_type{ { 3, 3, 3, 3, 2, 3 } } ); //tile dims 3,3,3,3,3,3 more than cuda can handle with debugging TestMDRange_6D functor( N0, N1, N2, N3, N4, N5 ); - md_parallel_for( range, functor ); + parallel_for( range, functor ); HostViewType h_view = Kokkos::create_mirror_view( functor.input_view ); Kokkos::deep_copy( h_view, functor.input_view ); @@ -1519,7 +2251,7 @@ struct TestMDRange_6D { TestMDRange_6D functor( N0, N1, N2, N3, N4, N5 ); - md_parallel_for( range, functor ); + parallel_for( range, functor ); HostViewType h_view = Kokkos::create_mirror_view( functor.input_view ); Kokkos::deep_copy( h_view, functor.input_view ); @@ -1553,7 +2285,7 @@ struct TestMDRange_6D { TestMDRange_6D functor( N0, N1, N2, N3, N4, N5 ); - md_parallel_for( range, functor ); + parallel_for( range, functor ); HostViewType h_view = Kokkos::create_mirror_view( functor.input_view ); Kokkos::deep_copy( h_view, functor.input_view ); @@ -1587,7 +2319,7 @@ struct TestMDRange_6D { TestMDRange_6D functor( N0, N1, N2, N3, N4, N5 ); - md_parallel_for( range, functor ); + parallel_for( range, functor ); HostViewType h_view = Kokkos::create_mirror_view( functor.input_view ); Kokkos::deep_copy( h_view, functor.input_view ); @@ -1621,7 +2353,7 @@ struct TestMDRange_6D { TestMDRange_6D functor( N0, N1, N2, N3, N4, N5 ); - md_parallel_for( range, functor ); + parallel_for( range, functor ); HostViewType h_view = Kokkos::create_mirror_view( functor.input_view ); Kokkos::deep_copy( h_view, functor.input_view ); @@ -1655,7 +2387,7 @@ struct TestMDRange_6D { TestMDRange_6D functor( N0, N1, N2, N3, N4, N5 ); - md_parallel_for( range, functor ); + parallel_for( range, functor ); HostViewType h_view = Kokkos::create_mirror_view( functor.input_view ); Kokkos::deep_copy( h_view, functor.input_view ); @@ -1689,7 +2421,7 @@ struct TestMDRange_6D { TestMDRange_6D functor( N0, N1, N2, N3, N4, N5 ); - md_parallel_for( range, functor ); + parallel_for( range, functor ); HostViewType h_view = Kokkos::create_mirror_view( functor.input_view ); Kokkos::deep_copy( h_view, functor.input_view ); @@ -1726,11 +2458,19 @@ TEST_F( TEST_CATEGORY , mdrange_for ) { TestMDRange_6D< TEST_EXECSPACE >::test_for6( 10, 10, 10, 10, 5, 5 ); } -#ifndef KOKKOS_ENABLE_CUDA TEST_F( TEST_CATEGORY , mdrange_reduce ) { TestMDRange_2D< TEST_EXECSPACE >::test_reduce2( 100, 100 ); TestMDRange_3D< TEST_EXECSPACE >::test_reduce3( 100, 10, 100 ); + TestMDRange_4D< TEST_EXECSPACE >::test_reduce4( 100, 10, 10, 10 ); + TestMDRange_5D< TEST_EXECSPACE >::test_reduce5( 100, 10, 10, 10, 5 ); + TestMDRange_6D< TEST_EXECSPACE >::test_reduce6( 100, 10, 10, 10, 5, 5 ); } -#endif + +//#ifndef KOKKOS_ENABLE_CUDA +TEST_F( TEST_CATEGORY , mdrange_array_reduce ) { + TestMDRange_ReduceArray_2D< TEST_EXECSPACE >::test_arrayreduce2( 4, 5 ); + TestMDRange_ReduceArray_3D< TEST_EXECSPACE >::test_arrayreduce3( 4, 5, 10 ); +} +//#endif } // namespace Test diff --git a/lib/kokkos/core/unit_test/TestMemoryPool.hpp b/lib/kokkos/core/unit_test/TestMemoryPool.hpp index 941cd6c26d..9f708390c2 100644 --- a/lib/kokkos/core/unit_test/TestMemoryPool.hpp +++ b/lib/kokkos/core/unit_test/TestMemoryPool.hpp @@ -54,6 +54,96 @@ namespace TestMemoryPool { +template< typename MemSpace = Kokkos::HostSpace > +void test_host_memory_pool_defaults() +{ + typedef typename MemSpace::execution_space Space ; + typedef typename Kokkos::MemoryPool< Space > MemPool ; + + { + const size_t MemoryCapacity = 32000 ; + const size_t MinBlockSize = 64 ; + const size_t MaxBlockSize = 1024 ; + const size_t SuperBlockSize = 4096 ; + + MemPool pool( MemSpace() + , MemoryCapacity + , MinBlockSize + , MaxBlockSize + , SuperBlockSize + ); + + typename MemPool::usage_statistics stats ; + + pool.get_usage_statistics( stats ); + + ASSERT_LE( MemoryCapacity , stats.capacity_bytes ); + ASSERT_LE( MinBlockSize , stats.min_block_bytes ); + ASSERT_LE( MaxBlockSize , stats.max_block_bytes ); + ASSERT_LE( SuperBlockSize , stats.superblock_bytes ); + } + + { + const size_t MemoryCapacity = 10000 ; + + MemPool pool( MemSpace() + , MemoryCapacity + ); + + typename MemPool::usage_statistics stats ; + + pool.get_usage_statistics( stats ); + + ASSERT_LE( MemoryCapacity , stats.capacity_bytes ); + ASSERT_LE( 64u /* default */ , stats.min_block_bytes ); + ASSERT_LE( stats.min_block_bytes , stats.max_block_bytes ); + ASSERT_LE( stats.max_block_bytes , stats.superblock_bytes ); + ASSERT_LE( stats.superblock_bytes , stats.capacity_bytes ); + } + + { + const size_t MemoryCapacity = 10000 ; + const size_t MinBlockSize = 32 ; // power of two is exact + + MemPool pool( MemSpace() + , MemoryCapacity + , MinBlockSize + ); + + typename MemPool::usage_statistics stats ; + + pool.get_usage_statistics( stats ); + + ASSERT_LE( MemoryCapacity , stats.capacity_bytes ); + ASSERT_EQ( MinBlockSize , stats.min_block_bytes ); + ASSERT_LE( stats.min_block_bytes , stats.max_block_bytes ); + ASSERT_LE( stats.max_block_bytes , stats.superblock_bytes ); + ASSERT_LE( stats.superblock_bytes , stats.capacity_bytes ); + } + + { + const size_t MemoryCapacity = 32000 ; + const size_t MinBlockSize = 32 ; // power of two is exact + const size_t MaxBlockSize = 1024 ; // power of two is exact + + MemPool pool( MemSpace() + , MemoryCapacity + , MinBlockSize + , MaxBlockSize + ); + + typename MemPool::usage_statistics stats ; + + pool.get_usage_statistics( stats ); + + ASSERT_LE( MemoryCapacity , stats.capacity_bytes ); + ASSERT_EQ( MinBlockSize , stats.min_block_bytes ); + ASSERT_EQ( MaxBlockSize , stats.max_block_bytes ); + ASSERT_LE( stats.max_block_bytes , stats.superblock_bytes ); + ASSERT_LE( stats.superblock_bytes , stats.capacity_bytes ); + } +} + template< typename MemSpace = Kokkos::HostSpace > void test_host_memory_pool_stats() { @@ -188,8 +278,8 @@ void print_memory_pool_stats << " bytes reserved = " << stats.reserved_bytes << std::endl << " bytes free = " << ( stats.capacity_bytes - ( stats.consumed_bytes + stats.reserved_bytes ) ) << std::endl - << " alloc used = " << stats.consumed_blocks << std::endl - << " alloc reserved = " << stats.reserved_blocks << std::endl + << " block used = " << stats.consumed_blocks << std::endl + << " block reserved = " << stats.reserved_blocks << std::endl << " super used = " << stats.consumed_superblocks << std::endl << " super reserved = " << ( stats.capacity_superblocks - stats.consumed_superblocks ) << std::endl @@ -302,15 +392,147 @@ void test_memory_pool_v2( const bool print_statistics //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- -} // namespace TestMemoryPool { +template< class DeviceType > +struct TestMemoryPoolCorners { + + typedef Kokkos::View< uintptr_t * , DeviceType > ptrs_type ; + typedef Kokkos::MemoryPool< DeviceType > pool_type ; + + pool_type pool ; + ptrs_type ptrs ; + uint32_t size ; + uint32_t stride ; + + TestMemoryPoolCorners( const pool_type & arg_pool + , const ptrs_type & arg_ptrs + , const uint32_t arg_base + , const uint32_t arg_stride + ) + : pool( arg_pool ) + , ptrs( arg_ptrs ) + , size( arg_base ) + , stride( arg_stride ) + {} + + // Specify reduction argument value_type to + // avoid confusion with tag-dispatch. + + using value_type = long ; + + KOKKOS_INLINE_FUNCTION + void operator()( int i , long & err ) const noexcept + { + unsigned alloc_size = size << ( i % stride ); + if ( 0 == ptrs(i) ) { + ptrs(i) = (uintptr_t) pool.allocate( alloc_size ); + if ( ptrs(i) && ! alloc_size ) { ++err ; } + } + } + + struct TagDealloc {}; + + KOKKOS_INLINE_FUNCTION + void operator()( int i ) const noexcept + { + unsigned alloc_size = size << ( i % stride ); + if ( ptrs(i) ) { pool.deallocate( (void*) ptrs(i) , alloc_size ); } + ptrs(i) = 0 ; + } +}; + +template< class DeviceType > +void test_memory_pool_corners( const bool print_statistics + , const bool print_superblocks ) +{ + typedef typename DeviceType::memory_space memory_space ; + typedef typename DeviceType::execution_space execution_space ; + typedef Kokkos::MemoryPool< DeviceType > pool_type ; + typedef TestMemoryPoolCorners< DeviceType > functor_type ; + typedef typename functor_type::ptrs_type ptrs_type ; + + { + // superblock size 1 << 14 + const size_t min_superblock_size = 1u << 14 ; + + // four superblocks + const size_t total_alloc_size = min_superblock_size * 4 ; + + // block sizes { 64 , 128 , 256 , 512 } + // block counts { 256 , 128 , 64 , 32 } + const unsigned min_block_size = 64 ; + const unsigned max_block_size = 512 ; + const unsigned num_blocks = 480 ; + + pool_type pool( memory_space() + , total_alloc_size + , min_block_size + , max_block_size + , min_superblock_size ); + + // Allocate one block from each superblock to lock that + // superblock into the block size. + + ptrs_type ptrs("ptrs",num_blocks); + + long err = 0 ; + + Kokkos::parallel_reduce + ( Kokkos::RangePolicy< execution_space >(0,4) + , functor_type( pool , ptrs , 64 , 4 ) + , err + ); + + if ( print_statistics || err ) { + + typename pool_type::usage_statistics stats ; + + pool.get_usage_statistics( stats ); + + print_memory_pool_stats< pool_type >( stats ); + } + + if ( print_superblocks || err ) { + pool.print_state( std::cout ); + } + + // Now fill remaining allocations with small size + + Kokkos::parallel_reduce + ( Kokkos::RangePolicy< execution_space >(0,num_blocks) + , functor_type( pool , ptrs , 64 , 1 ) + , err + ); + + if ( print_statistics || err ) { + + typename pool_type::usage_statistics stats ; + + pool.get_usage_statistics( stats ); + + print_memory_pool_stats< pool_type >( stats ); + } + + if ( print_superblocks || err ) { + pool.print_state( std::cout ); + } + } +} + +//---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- + +} // namespace TestMemoryPool namespace Test { TEST_F( TEST_CATEGORY, memory_pool ) { + TestMemoryPool::test_host_memory_pool_defaults<>(); TestMemoryPool::test_host_memory_pool_stats<>(); TestMemoryPool::test_memory_pool_v2< TEST_EXECSPACE >(false,false); + TestMemoryPool::test_memory_pool_corners< TEST_EXECSPACE >(false,false); } + } #endif diff --git a/lib/kokkos/core/unit_test/TestRange.hpp b/lib/kokkos/core/unit_test/TestRange.hpp index f55574761b..3cea1ad4a0 100644 --- a/lib/kokkos/core/unit_test/TestRange.hpp +++ b/lib/kokkos/core/unit_test/TestRange.hpp @@ -72,8 +72,33 @@ struct TestRange { typename view_type::HostMirror host_flags = Kokkos::create_mirror_view( m_flags ); Kokkos::parallel_for( Kokkos::RangePolicy< ExecSpace, ScheduleType >( 0, N ), *this ); + +#if defined(KOKKOS_ENABLE_PROFILING) + { + typedef TestRange< ExecSpace, ScheduleType > ThisType; + std::string label("parallel_for"); + Kokkos::Impl::ParallelConstructName< ThisType, void> pcn(label); + ASSERT_EQ( pcn.get(), label ); + std::string empty_label(""); + Kokkos::Impl::ParallelConstructName< ThisType, void> empty_pcn(empty_label); + ASSERT_EQ( empty_pcn.get(), typeid(ThisType).name() ); + } +#endif + Kokkos::parallel_for( Kokkos::RangePolicy< ExecSpace, ScheduleType, VerifyInitTag >( 0, N ), *this ); +#if defined(KOKKOS_ENABLE_PROFILING) + { + typedef TestRange< ExecSpace, ScheduleType > ThisType; + std::string label("parallel_for"); + Kokkos::Impl::ParallelConstructName< ThisType, VerifyInitTag> pcn(label); + ASSERT_EQ( pcn.get(), label ); + std::string empty_label(""); + Kokkos::Impl::ParallelConstructName< ThisType, VerifyInitTag> empty_pcn(empty_label); + ASSERT_EQ( empty_pcn.get(), std::string(typeid(ThisType).name()) + "/" + typeid(VerifyInitTag).name() ); + } +#endif + Kokkos::deep_copy( host_flags, m_flags ); int error_count = 0; diff --git a/lib/kokkos/core/unit_test/TestResize.hpp b/lib/kokkos/core/unit_test/TestResize.hpp new file mode 100644 index 0000000000..aaf0422b19 --- /dev/null +++ b/lib/kokkos/core/unit_test/TestResize.hpp @@ -0,0 +1,140 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ +#ifndef TESTVIEWSUBVIEW_HPP_ +#define TESTVIEWSUBVIEW_HPP_ + +#include +#include + +namespace TestViewResize { + +template +void testResize () +{ + const int sizes[8] = {2, 3, 4, 5, 6, 7, 8, 9}; + + // Check #904 fix (no reallocation if dimensions didn't change). + { + typedef Kokkos::View view_type; + view_type view_1d ("view_1d", sizes[0]); + const int* oldPointer = view_1d.data (); + EXPECT_TRUE( oldPointer != NULL ); + Kokkos::resize (view_1d, sizes[0]); + const int* newPointer = view_1d.data (); + EXPECT_TRUE( oldPointer == newPointer ); + } + { + typedef Kokkos::View view_type; + view_type view_2d ("view_2d", sizes[0], sizes[1]); + const int* oldPointer = view_2d.data (); + EXPECT_TRUE( oldPointer != NULL ); + Kokkos::resize (view_2d, sizes[0], sizes[1]); + const int* newPointer = view_2d.data (); + EXPECT_TRUE( oldPointer == newPointer ); + } + { + typedef Kokkos::View view_type; + view_type view_3d ("view_3d", sizes[0], sizes[1], sizes[2]); + const int* oldPointer = view_3d.data (); + EXPECT_TRUE( oldPointer != NULL ); + Kokkos::resize (view_3d, sizes[0], sizes[1], sizes[2]); + const int* newPointer = view_3d.data (); + EXPECT_TRUE( oldPointer == newPointer ); + } + { + typedef Kokkos::View view_type; + view_type view_4d ("view_4d", sizes[0], sizes[1], sizes[2], sizes[3]); + const int* oldPointer = view_4d.data (); + EXPECT_TRUE( oldPointer != NULL ); + Kokkos::resize (view_4d, sizes[0], sizes[1], sizes[2], sizes[3]); + const int* newPointer = view_4d.data (); + EXPECT_TRUE( oldPointer == newPointer ); + } + { + typedef Kokkos::View view_type; + view_type view_5d ("view_5d", sizes[0], sizes[1], sizes[2], sizes[3], + sizes[4]); + const int* oldPointer = view_5d.data (); + EXPECT_TRUE( oldPointer != NULL ); + Kokkos::resize (view_5d, sizes[0], sizes[1], sizes[2], sizes[3], sizes[4]); + const int* newPointer = view_5d.data (); + EXPECT_TRUE( oldPointer == newPointer ); + } + { + typedef Kokkos::View view_type; + view_type view_6d ("view_6d", sizes[0], sizes[1], sizes[2], sizes[3], + sizes[4], sizes[5]); + const int* oldPointer = view_6d.data (); + EXPECT_TRUE( oldPointer != NULL ); + Kokkos::resize (view_6d, sizes[0], sizes[1], sizes[2], sizes[3], sizes[4], + sizes[5]); + const int* newPointer = view_6d.data (); + EXPECT_TRUE( oldPointer == newPointer ); + } + { + typedef Kokkos::View view_type; + view_type view_7d ("view_7d", sizes[0], sizes[1], sizes[2], sizes[3], + sizes[4], sizes[5], sizes[6]); + const int* oldPointer = view_7d.data (); + EXPECT_TRUE( oldPointer != NULL ); + Kokkos::resize (view_7d, sizes[0], sizes[1], sizes[2], sizes[3], sizes[4], + sizes[5], sizes[6]); + const int* newPointer = view_7d.data (); + EXPECT_TRUE( oldPointer == newPointer ); + } + { + typedef Kokkos::View view_type; + view_type view_8d ("view_8d", sizes[0], sizes[1], sizes[2], sizes[3], + sizes[4], sizes[5], sizes[6], sizes[7]); + const int* oldPointer = view_8d.data (); + EXPECT_TRUE( oldPointer != NULL ); + Kokkos::resize (view_8d, sizes[0], sizes[1], sizes[2], sizes[3], sizes[4], + sizes[5], sizes[6], sizes[7]); + const int* newPointer = view_8d.data (); + EXPECT_TRUE( oldPointer == newPointer ); + } +} + +} // namespace TestViewSubview + +#endif // TESTVIEWSUBVIEW_HPP_ diff --git a/lib/kokkos/core/unit_test/TestTaskScheduler.hpp b/lib/kokkos/core/unit_test/TestTaskScheduler.hpp index 3a88475620..4e66543857 100644 --- a/lib/kokkos/core/unit_test/TestTaskScheduler.hpp +++ b/lib/kokkos/core/unit_test/TestTaskScheduler.hpp @@ -250,13 +250,21 @@ struct TestTaskDependence { const int n = CHUNK < m_count ? CHUNK : m_count; if ( 1 < m_count ) { - future_type f[ CHUNK ]; + // Test use of memory pool for temporary allocation: + + // Raw allocation: + future_type * const f = + (future_type *) m_sched.memory()->allocate( sizeof(future_type) * n ); + + // In-place construction: + for ( int i = 0; i < n; ++i ) new(f+i) future_type(); const int inc = ( m_count + n - 1 ) / n; for ( int i = 0; i < n; ++i ) { long begin = i * inc; long count = begin + inc < m_count ? inc : m_count - begin; + f[i] = Kokkos::task_spawn( Kokkos::TaskSingle( m_sched ) , TestTaskDependence( count, m_sched, m_accum ) ); } @@ -264,6 +272,12 @@ struct TestTaskDependence { m_count = 0; Kokkos::respawn( this, Kokkos::when_all( f, n ) ); + + // In-place destruction to release future: + for ( int i = 0; i < n; ++i ) (f+i)->~future_type(); + + // Raw deallocation: + m_sched.memory()->deallocate( f , sizeof(future_type) * n ); } else if ( 1 == m_count ) { Kokkos::atomic_increment( & m_accum() ); @@ -641,19 +655,12 @@ namespace Test { TEST_F( TEST_CATEGORY, task_fib ) { - const int N = 24 ; // 25 triggers tbd bug on Cuda/Pascal + const int N = 27 ; for ( int i = 0; i < N; ++i ) { - TestTaskScheduler::TestFib< TEST_EXECSPACE >::run( i , ( i + 1 ) * ( i + 1 ) * 10000 ); + TestTaskScheduler::TestFib< TEST_EXECSPACE >::run( i , ( i + 1 ) * ( i + 1 ) * 2000 ); } } -#if defined(KOKKOS_ARCH_MAXWELL) || defined(KOKKOS_ARCH_PASCAL) - // TODO: Resolve bug in task DAG for Pascal - #define KOKKOS_IMPL_DISABLE_UNIT_TEST_TASK_DAG_PASCAL -#endif - -#ifndef KOKKOS_IMPL_DISABLE_UNIT_TEST_TASK_DAG_PASCAL - TEST_F( TEST_CATEGORY, task_depend ) { for ( int i = 0; i < 25; ++i ) { @@ -667,11 +674,8 @@ TEST_F( TEST_CATEGORY, task_team ) //TestTaskScheduler::TestTaskTeamValue< TEST_EXECSPACE >::run( 1000 ); // Put back after testing. } -#else //ndef KOKKOS_IMPL_DISABLE_UNIT_TEST_TASK_DAG_PASCAL -#undef KOKKOS_IMPL_DISABLE_UNIT_TEST_TASK_DAG_PASCAL -#endif //ndef KOKKOS_IMPL_DISABLE_UNIT_TEST_TASK_DAG_PASCAL - } + #endif // #if defined( KOKKOS_ENABLE_TASKDAG ) #endif // #ifndef KOKKOS_UNITTEST_TASKSCHEDULER_HPP diff --git a/lib/kokkos/core/unit_test/TestTeamVector.hpp b/lib/kokkos/core/unit_test/TestTeamVector.hpp index e9e2f7548a..7f4663d0f9 100644 --- a/lib/kokkos/core/unit_test/TestTeamVector.hpp +++ b/lib/kokkos/core/unit_test/TestTeamVector.hpp @@ -838,6 +838,18 @@ public: }, result ); const ScalarType solution = (ScalarType) nrows * (ScalarType) ncols; + + if ( int64_t(solution) != int64_t(result) ) { + printf( " TestTripleNestedReduce failed solution(%ld) != result(%ld), nrows(%d) ncols(%d) league_size(%d) team_size(%d)\n" + , int64_t(solution) + , int64_t(result) + , int32_t(nrows) + , int32_t(ncols) + , int32_t(nrows/chunk_size) + , int32_t(team_size) + ); + } + ASSERT_EQ( solution, result ); } }; diff --git a/lib/kokkos/core/unit_test/TestTile.hpp b/lib/kokkos/core/unit_test/TestTile.hpp index 8f57dfea75..f15667322f 100644 --- a/lib/kokkos/core/unit_test/TestTile.hpp +++ b/lib/kokkos/core/unit_test/TestTile.hpp @@ -94,7 +94,7 @@ struct ReduceTileErrors const size_t jtile = iwork / tile_dim0; if ( jtile < tile_dim1 ) { - tile_type tile = Kokkos::Experimental::tile_subview( m_array, itile, jtile ); + tile_type tile = Kokkos::tile_subview( m_array, itile, jtile ); if ( tile( 0, 0 ) != ptrdiff_t( ( itile + jtile * tile_dim0 ) * TileLayout::N0 * TileLayout::N1 ) ) { ++errors; diff --git a/lib/kokkos/core/unit_test/TestUniqueToken.hpp b/lib/kokkos/core/unit_test/TestUniqueToken.hpp new file mode 100644 index 0000000000..28add61a8a --- /dev/null +++ b/lib/kokkos/core/unit_test/TestUniqueToken.hpp @@ -0,0 +1,138 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include + +#include + +namespace Test { + +template< class Space > +class TestUniqueToken +{ +public: + typedef typename Space::execution_space execution_space; + typedef Kokkos::View< int * , execution_space > view_type ; + + Kokkos::Experimental::UniqueToken< execution_space , Kokkos::Experimental::UniqueTokenScope::Global > tokens ; + + view_type verify ; + view_type counts ; + view_type errors ; + + KOKKOS_INLINE_FUNCTION + void operator()( long ) const + { + const int32_t t = tokens.acquire(); + + bool ok = true ; + + ok = ok && 0 <= t ; + ok = ok && t < tokens.size(); + ok = ok && 0 == Kokkos::atomic_fetch_add( & verify(t) , 1 ); + + Kokkos::atomic_fetch_add( & counts(t) , 1 ); + + ok = ok && 1 == Kokkos::atomic_fetch_add( & verify(t) , -1 ); + + if ( ! ok ) { Kokkos::atomic_fetch_add( & errors(0) , 1 ) ; } + + tokens.release(t); + } + + TestUniqueToken() + : tokens( execution_space() ) + , verify( "TestUniqueTokenVerify" , tokens.size() ) + , counts( "TestUniqueTokenCounts" , tokens.size() ) + , errors( "TestUniqueTokenErrors" , 1 ) + {} + + static void run() + { + using policy = Kokkos::RangePolicy ; + + TestUniqueToken self ; + + { + const int duplicate = 100 ; + const long n = duplicate * self.tokens.size(); + + Kokkos::parallel_for( policy(0,n) , self ); + Kokkos::parallel_for( policy(0,n) , self ); + Kokkos::parallel_for( policy(0,n) , self ); + Kokkos::fence(); + } + + typename view_type::HostMirror host_counts = + Kokkos::create_mirror_view( self.counts ); + + Kokkos::deep_copy( host_counts , self.counts ); + + int32_t max = 0 ; + + { + const long n = host_counts.extent(0); + for ( long i = 0 ; i < n ; ++i ) { + if ( max < host_counts[i] ) max = host_counts[i] ; + } + } + + std::cout << "TestUniqueToken max reuse = " << max << std::endl ; + + typename view_type::HostMirror host_errors = + Kokkos::create_mirror_view( self.errors ); + + Kokkos::deep_copy( host_errors , self.errors ); + + ASSERT_EQ( host_errors(0) , 0 ); + } +}; + + +TEST_F( TEST_CATEGORY, unique_token ) +{ + TestUniqueToken< TEST_EXECSPACE >::run(); +} + +} // namespace Test + diff --git a/lib/kokkos/core/unit_test/TestViewCtorPropEmbeddedDim.hpp b/lib/kokkos/core/unit_test/TestViewCtorPropEmbeddedDim.hpp new file mode 100644 index 0000000000..305ddb2a1d --- /dev/null +++ b/lib/kokkos/core/unit_test/TestViewCtorPropEmbeddedDim.hpp @@ -0,0 +1,160 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include + +#include + +#include + +#include +#include + +namespace Test { + +namespace { + +template +struct TestViewCtorProp_EmbeddedDim { + + using ViewIntType = typename Kokkos::View< int**, ExecSpace >; + using ViewDoubleType = typename Kokkos::View< double*, ExecSpace >; + + // Cuda 7.0 has issues with using a lamda in parallel_for to initialize the view - replace with this functor + template < class ViewType > + struct Functor { + + ViewType v; + + Functor( const ViewType & v_ ) : v(v_) {} + + KOKKOS_INLINE_FUNCTION + void operator()( const int i ) const { + v(i) = i; + } + + }; + + + static void test_vcpt( const int N0, const int N1 ) + { + + // Create views to test + { + using VIT = typename TestViewCtorProp_EmbeddedDim::ViewIntType ; + using VDT = typename TestViewCtorProp_EmbeddedDim::ViewDoubleType ; + + VIT vi1("vi1", N0, N1); + VDT vd1("vd1", N0); + + // TEST: Test for common type between two views, one with type double, other with type int + // Deduce common value_type and construct a view with that type + { + // Two views + auto view_alloc_arg = Kokkos::common_view_alloc_prop(vi1, vd1); + typedef typename decltype( view_alloc_arg )::value_type CommonViewValueType; + typedef typename Kokkos::View< CommonViewValueType*, ExecSpace > CVT; + typedef typename CVT::HostMirror HostCVT; + + // Construct View using the common type; for case of specialization, an 'embedded_dim' would be stored by view_alloc_arg + CVT cv1( Kokkos::view_alloc( "cv1", view_alloc_arg ), N0*N1 ); + + Kokkos::parallel_for( Kokkos::RangePolicy< ExecSpace >(0, N0*N1), + Functor(cv1) + ); + + HostCVT hcv1 = Kokkos::create_mirror_view( cv1 ); + Kokkos::deep_copy( hcv1, cv1 ); + + ASSERT_EQ( (std::is_same< CommonViewValueType, double >::value) , true ) ; + #if 0 + // debug output + for ( int i = 0; i < N0*N1; ++i ) { + printf(" Output check: hcv1(%d) = %lf\n ", i, hcv1(i) ); + } + + printf( " Common value type view: %s \n", typeid( CVT() ).name() ); + printf( " Common value type: %s \n", typeid( CommonViewValueType() ).name() ); + if ( std::is_same< CommonViewValueType, double >::value == true ) { + printf("Proper common value_type\n"); + } + else { + printf("WRONG common value_type\n"); + } + // end debug output + #endif + } + + { + // Single view + auto view_alloc_arg = Kokkos::common_view_alloc_prop(vi1); + typedef typename decltype( view_alloc_arg )::value_type CommonViewValueType; + typedef typename Kokkos::View< CommonViewValueType*, ExecSpace > CVT; + typedef typename CVT::HostMirror HostCVT; + + // Construct View using the common type; for case of specialization, an 'embedded_dim' would be stored by view_alloc_arg + CVT cv1( Kokkos::view_alloc( "cv1", view_alloc_arg ), N0*N1 ); + + Kokkos::parallel_for( Kokkos::RangePolicy< ExecSpace >(0, N0*N1), + Functor(cv1) + ); + + HostCVT hcv1 = Kokkos::create_mirror_view( cv1 ); + Kokkos::deep_copy( hcv1, cv1 ); + + ASSERT_EQ( (std::is_same< CommonViewValueType, int>::value) , true ) ; + } + + } + + } // end test_vcpt + +}; // end struct + +} // namespace + +TEST_F( TEST_CATEGORY , viewctorprop_embedded_dim ) { + TestViewCtorProp_EmbeddedDim< TEST_EXECSPACE >::test_vcpt( 2, 3 ); +} + +} // namespace Test diff --git a/lib/kokkos/core/unit_test/TestViewMapping_a.hpp b/lib/kokkos/core/unit_test/TestViewMapping_a.hpp index 6830c2e049..810ae72e73 100644 --- a/lib/kokkos/core/unit_test/TestViewMapping_a.hpp +++ b/lib/kokkos/core/unit_test/TestViewMapping_a.hpp @@ -56,24 +56,24 @@ void test_view_mapping() { typedef typename Space::execution_space ExecSpace; - typedef Kokkos::Experimental::Impl::ViewDimension<> dim_0; - typedef Kokkos::Experimental::Impl::ViewDimension< 2 > dim_s2; - typedef Kokkos::Experimental::Impl::ViewDimension< 2, 3 > dim_s2_s3; - typedef Kokkos::Experimental::Impl::ViewDimension< 2, 3, 4 > dim_s2_s3_s4; + typedef Kokkos::Impl::ViewDimension<> dim_0; + typedef Kokkos::Impl::ViewDimension< 2 > dim_s2; + typedef Kokkos::Impl::ViewDimension< 2, 3 > dim_s2_s3; + typedef Kokkos::Impl::ViewDimension< 2, 3, 4 > dim_s2_s3_s4; - typedef Kokkos::Experimental::Impl::ViewDimension< 0 > dim_s0; - typedef Kokkos::Experimental::Impl::ViewDimension< 0, 3 > dim_s0_s3; - typedef Kokkos::Experimental::Impl::ViewDimension< 0, 3, 4 > dim_s0_s3_s4; + typedef Kokkos::Impl::ViewDimension< 0 > dim_s0; + typedef Kokkos::Impl::ViewDimension< 0, 3 > dim_s0_s3; + typedef Kokkos::Impl::ViewDimension< 0, 3, 4 > dim_s0_s3_s4; - typedef Kokkos::Experimental::Impl::ViewDimension< 0, 0 > dim_s0_s0; - typedef Kokkos::Experimental::Impl::ViewDimension< 0, 0, 4 > dim_s0_s0_s4; + typedef Kokkos::Impl::ViewDimension< 0, 0 > dim_s0_s0; + typedef Kokkos::Impl::ViewDimension< 0, 0, 4 > dim_s0_s0_s4; - typedef Kokkos::Experimental::Impl::ViewDimension< 0, 0, 0 > dim_s0_s0_s0; - typedef Kokkos::Experimental::Impl::ViewDimension< 0, 0, 0, 0 > dim_s0_s0_s0_s0; - typedef Kokkos::Experimental::Impl::ViewDimension< 0, 0, 0, 0, 0 > dim_s0_s0_s0_s0_s0; - typedef Kokkos::Experimental::Impl::ViewDimension< 0, 0, 0, 0, 0, 0 > dim_s0_s0_s0_s0_s0_s0; - typedef Kokkos::Experimental::Impl::ViewDimension< 0, 0, 0, 0, 0, 0, 0 > dim_s0_s0_s0_s0_s0_s0_s0; - typedef Kokkos::Experimental::Impl::ViewDimension< 0, 0, 0, 0, 0, 0, 0, 0 > dim_s0_s0_s0_s0_s0_s0_s0_s0; + typedef Kokkos::Impl::ViewDimension< 0, 0, 0 > dim_s0_s0_s0; + typedef Kokkos::Impl::ViewDimension< 0, 0, 0, 0 > dim_s0_s0_s0_s0; + typedef Kokkos::Impl::ViewDimension< 0, 0, 0, 0, 0 > dim_s0_s0_s0_s0_s0; + typedef Kokkos::Impl::ViewDimension< 0, 0, 0, 0, 0, 0 > dim_s0_s0_s0_s0_s0_s0; + typedef Kokkos::Impl::ViewDimension< 0, 0, 0, 0, 0, 0, 0 > dim_s0_s0_s0_s0_s0_s0_s0; + typedef Kokkos::Impl::ViewDimension< 0, 0, 0, 0, 0, 0, 0, 0 > dim_s0_s0_s0_s0_s0_s0_s0_s0; // Fully static dimensions should not be larger than an int. ASSERT_LE( sizeof( dim_0 ), sizeof( int ) ); @@ -186,12 +186,12 @@ void test_view_mapping() //---------------------------------------- - typedef Kokkos::Experimental::Impl::ViewOffset< dim_s0_s0_s0, Kokkos::LayoutStride > stride_s0_s0_s0; + typedef Kokkos::Impl::ViewOffset< dim_s0_s0_s0, Kokkos::LayoutStride > stride_s0_s0_s0; //---------------------------------------- // Static dimension. { - typedef Kokkos::Experimental::Impl::ViewOffset< dim_s2_s3_s4, Kokkos::LayoutLeft > left_s2_s3_s4; + typedef Kokkos::Impl::ViewOffset< dim_s2_s3_s4, Kokkos::LayoutLeft > left_s2_s3_s4; ASSERT_EQ( sizeof( left_s2_s3_s4 ), sizeof( dim_s2_s3_s4 ) ); @@ -223,7 +223,7 @@ void test_view_mapping() //---------------------------------------- // Small dimension is unpadded. { - typedef Kokkos::Experimental::Impl::ViewOffset< dim_s0_s0_s4, Kokkos::LayoutLeft > left_s0_s0_s4; + typedef Kokkos::Impl::ViewOffset< dim_s0_s0_s4, Kokkos::LayoutLeft > left_s0_s0_s4; left_s0_s0_s4 dyn_off3( std::integral_constant< unsigned, sizeof( int ) >() , Kokkos::LayoutLeft( 2, 3, 0, 0, 0, 0, 0, 0 ) ); @@ -275,7 +275,7 @@ void test_view_mapping() constexpr int N0 = 2000; constexpr int N1 = 300; - typedef Kokkos::Experimental::Impl::ViewOffset< dim_s0_s0_s4, Kokkos::LayoutLeft > left_s0_s0_s4; + typedef Kokkos::Impl::ViewOffset< dim_s0_s0_s4, Kokkos::LayoutLeft > left_s0_s0_s4; left_s0_s0_s4 dyn_off3( std::integral_constant< unsigned, sizeof( int ) >() , Kokkos::LayoutLeft( N0, N1, 0, 0, 0, 0, 0, 0 ) ); @@ -314,7 +314,7 @@ void test_view_mapping() //---------------------------------------- // Static dimension. { - typedef Kokkos::Experimental::Impl::ViewOffset< dim_s2_s3_s4, Kokkos::LayoutRight > right_s2_s3_s4; + typedef Kokkos::Impl::ViewOffset< dim_s2_s3_s4, Kokkos::LayoutRight > right_s2_s3_s4; ASSERT_EQ( sizeof( right_s2_s3_s4 ), sizeof( dim_s2_s3_s4 ) ); @@ -350,7 +350,7 @@ void test_view_mapping() //---------------------------------------- // Small dimension is unpadded. { - typedef Kokkos::Experimental::Impl::ViewOffset< dim_s0_s0_s4, Kokkos::LayoutRight > right_s0_s0_s4; + typedef Kokkos::Impl::ViewOffset< dim_s0_s0_s4, Kokkos::LayoutRight > right_s0_s0_s4; right_s0_s0_s4 dyn_off3( std::integral_constant< unsigned, sizeof( int ) >() , Kokkos::LayoutRight( 2, 3, 0, 0, 0, 0, 0, 0 ) ); @@ -391,7 +391,7 @@ void test_view_mapping() constexpr int N0 = 2000; constexpr int N1 = 300; - typedef Kokkos::Experimental::Impl::ViewOffset< dim_s0_s0_s4, Kokkos::LayoutRight > right_s0_s0_s4; + typedef Kokkos::Impl::ViewOffset< dim_s0_s0_s4, Kokkos::LayoutRight > right_s0_s0_s4; right_s0_s0_s4 dyn_off3( std::integral_constant< unsigned, sizeof( int ) >() , Kokkos::LayoutRight( N0, N1, 0, 0, 0, 0, 0, 0 ) ); @@ -431,18 +431,18 @@ void test_view_mapping() // Subview. { // Mapping rank 4 to rank 3 - typedef Kokkos::Experimental::Impl::SubviewExtents< 4, 3 > SubviewExtents; + typedef Kokkos::Impl::SubviewExtents< 4, 3 > SubviewExtents; constexpr int N0 = 1000; constexpr int N1 = 2000; constexpr int N2 = 3000; constexpr int N3 = 4000; - Kokkos::Experimental::Impl::ViewDimension< N0, N1, N2, N3 > dim; + Kokkos::Impl::ViewDimension< N0, N1, N2, N3 > dim; SubviewExtents tmp( dim , N0 / 2 - , Kokkos::Experimental::ALL + , Kokkos::ALL , std::pair< int, int >( N2 / 4, 10 + N2 / 4 ) , Kokkos::pair< int, int >( N3 / 4, 20 + N3 / 4 ) ); @@ -469,12 +469,12 @@ void test_view_mapping() constexpr int sub_N1 = 200; constexpr int sub_N2 = 4; - typedef Kokkos::Experimental::Impl::ViewOffset< dim_s0_s0_s4, Kokkos::LayoutLeft > left_s0_s0_s4; + typedef Kokkos::Impl::ViewOffset< dim_s0_s0_s4, Kokkos::LayoutLeft > left_s0_s0_s4; left_s0_s0_s4 dyn_off3( std::integral_constant< unsigned, sizeof( int ) >() , Kokkos::LayoutLeft( N0, N1, 0, 0, 0, 0, 0, 0 ) ); - Kokkos::Experimental::Impl::SubviewExtents< 3, 3 > + Kokkos::Impl::SubviewExtents< 3, 3 > sub( dyn_off3.m_dim , Kokkos::pair< int, int >( 0, sub_N0 ) , Kokkos::pair< int, int >( 0, sub_N1 ) @@ -509,12 +509,12 @@ void test_view_mapping() constexpr int sub_N1 = 200; constexpr int sub_N2 = 4; - typedef Kokkos::Experimental::Impl::ViewOffset< dim_s0_s0_s4, Kokkos::LayoutRight > right_s0_s0_s4; + typedef Kokkos::Impl::ViewOffset< dim_s0_s0_s4, Kokkos::LayoutRight > right_s0_s0_s4; right_s0_s0_s4 dyn_off3( std::integral_constant< unsigned, sizeof( int ) >() , Kokkos::LayoutRight( N0, N1, 0, 0, 0, 0, 0, 0 ) ); - Kokkos::Experimental::Impl::SubviewExtents< 3, 3 > + Kokkos::Impl::SubviewExtents< 3, 3 > sub( dyn_off3.m_dim , Kokkos::pair< int, int >( 0, sub_N0 ) , Kokkos::pair< int, int >( 0, sub_N1 ) @@ -544,7 +544,7 @@ void test_view_mapping() //---------------------------------------- // View data analysis. { - using namespace Kokkos::Experimental::Impl; + using namespace Kokkos::Impl; static_assert( rank_dynamic<>::value == 0, "" ); static_assert( rank_dynamic< 1 >::value == 0, "" ); @@ -554,7 +554,7 @@ void test_view_mapping() } { - using namespace Kokkos::Experimental::Impl; + using namespace Kokkos::Impl; typedef ViewArrayAnalysis< int[] > a_int_r1; typedef ViewArrayAnalysis< int**[4][5][6] > a_int_r5; @@ -598,7 +598,7 @@ void test_view_mapping() } { - using namespace Kokkos::Experimental::Impl; + using namespace Kokkos::Impl; typedef int t_i4[4]; @@ -616,12 +616,12 @@ void test_view_mapping() } { - using namespace Kokkos::Experimental::Impl; + using namespace Kokkos::Impl; typedef ViewDataAnalysis< const int[], void > a_const_int_r1; static_assert( std::is_same< typename a_const_int_r1::specialize, void >::value, "" ); - static_assert( std::is_same< typename a_const_int_r1::dimension, Kokkos::Experimental::Impl::ViewDimension<0> >::value, "" ); + static_assert( std::is_same< typename a_const_int_r1::dimension, Kokkos::Impl::ViewDimension<0> >::value, "" ); static_assert( std::is_same< typename a_const_int_r1::type, const int * >::value, "" ); static_assert( std::is_same< typename a_const_int_r1::value_type, const int >::value, "" ); @@ -637,7 +637,7 @@ void test_view_mapping() static_assert( std::is_same< typename a_const_int_r3::specialize, void >::value, "" ); - static_assert( std::is_same< typename a_const_int_r3::dimension, Kokkos::Experimental::Impl::ViewDimension<0, 0, 4> >::value, "" ); + static_assert( std::is_same< typename a_const_int_r3::dimension, Kokkos::Impl::ViewDimension<0, 0, 4> >::value, "" ); static_assert( std::is_same< typename a_const_int_r3::type, const int**[4] >::value, "" ); static_assert( std::is_same< typename a_const_int_r3::value_type, const int >::value, "" ); @@ -786,7 +786,7 @@ void test_view_mapping() // The execution space of the memory space must be available for view data initialization. if ( std::is_same< ExecSpace, typename ExecSpace::memory_space::execution_space >::value ) { - using namespace Kokkos::Experimental; + using namespace Kokkos; typedef typename ExecSpace::memory_space memory_space; typedef View< int*, memory_space > V; @@ -811,8 +811,8 @@ void test_view_mapping() { typedef Kokkos::ViewTraits< int***, Kokkos::LayoutStride, ExecSpace > traits_t; - typedef Kokkos::Experimental::Impl::ViewDimension< 0, 0, 0 > dims_t; - typedef Kokkos::Experimental::Impl::ViewOffset< dims_t, Kokkos::LayoutStride > offset_t; + typedef Kokkos::Impl::ViewDimension< 0, 0, 0 > dims_t; + typedef Kokkos::Impl::ViewOffset< dims_t, Kokkos::LayoutStride > offset_t; Kokkos::LayoutStride stride; @@ -836,8 +836,8 @@ void test_view_mapping() ASSERT_EQ( offset.span(), 60 ); ASSERT_TRUE( offset.span_is_contiguous() ); - Kokkos::Experimental::Impl::ViewMapping< traits_t, void > - v( Kokkos::Experimental::Impl::ViewCtorProp< int* >( (int*) 0 ), stride ); + Kokkos::Impl::ViewMapping< traits_t, void > + v( Kokkos::Impl::ViewCtorProp< int* >( (int*) 0 ), stride ); } { @@ -849,8 +849,8 @@ void test_view_mapping() constexpr int N1 = 11; V a( "a", N0, N1 ); - M b = Kokkos::Experimental::create_mirror( a ); - M c = Kokkos::Experimental::create_mirror_view( a ); + M b = Kokkos::create_mirror( a ); + M c = Kokkos::create_mirror_view( a ); M d; for ( int i0 = 0; i0 < N0; ++i0 ) @@ -859,8 +859,8 @@ void test_view_mapping() b( i0, i1 ) = 1 + i0 + i1 * N0; } - Kokkos::Experimental::deep_copy( a, b ); - Kokkos::Experimental::deep_copy( c, a ); + Kokkos::deep_copy( a, b ); + Kokkos::deep_copy( c, a ); for ( int i0 = 0; i0 < N0; ++i0 ) for ( int i1 = 0; i1 < N1; ++i1 ) @@ -868,7 +868,7 @@ void test_view_mapping() ASSERT_EQ( b( i0, i1 ), c( i0, i1 ) ); } - Kokkos::Experimental::resize( b, 5, 6 ); + Kokkos::resize( b, 5, 6 ); for ( int i0 = 0; i0 < 5; ++i0 ) for ( int i1 = 0; i1 < 6; ++i1 ) @@ -878,8 +878,8 @@ void test_view_mapping() ASSERT_EQ( b( i0, i1 ), val ); } - Kokkos::Experimental::realloc( c, 5, 6 ); - Kokkos::Experimental::realloc( d, 5, 6 ); + Kokkos::realloc( c, 5, 6 ); + Kokkos::realloc( d, 5, 6 ); ASSERT_EQ( b.dimension_0(), 5 ); ASSERT_EQ( b.dimension_1(), 6 ); @@ -889,7 +889,7 @@ void test_view_mapping() ASSERT_EQ( d.dimension_1(), 6 ); layout_type layout( 7, 8 ); - Kokkos::Experimental::resize( b, layout ); + Kokkos::resize( b, layout ); for ( int i0 = 0; i0 < 7; ++i0 ) for ( int i1 = 6; i1 < 8; ++i1 ) { @@ -909,8 +909,8 @@ void test_view_mapping() ASSERT_EQ( b( i0, i1 ), val ); } - Kokkos::Experimental::realloc( c, layout ); - Kokkos::Experimental::realloc( d, layout ); + Kokkos::realloc( c, layout ); + Kokkos::realloc( d, layout ); ASSERT_EQ( b.dimension_0(), 7 ); ASSERT_EQ( b.dimension_1(), 8 ); @@ -932,8 +932,8 @@ void test_view_mapping() const int order[] = { 1, 0 }; V a( "a", Kokkos::LayoutStride::order_dimensions( 2, order, dimensions ) ); - M b = Kokkos::Experimental::create_mirror( a ); - M c = Kokkos::Experimental::create_mirror_view( a ); + M b = Kokkos::create_mirror( a ); + M c = Kokkos::create_mirror_view( a ); M d; for ( int i0 = 0; i0 < N0; ++i0 ) @@ -942,8 +942,8 @@ void test_view_mapping() b( i0, i1 ) = 1 + i0 + i1 * N0; } - Kokkos::Experimental::deep_copy( a, b ); - Kokkos::Experimental::deep_copy( c, a ); + Kokkos::deep_copy( a, b ); + Kokkos::deep_copy( c, a ); for ( int i0 = 0; i0 < N0; ++i0 ) for ( int i1 = 0; i1 < N1; ++i1 ) @@ -954,7 +954,7 @@ void test_view_mapping() const int dimensions2[] = { 7, 8 }; const int order2[] = { 1, 0 }; layout_type layout = layout_type::order_dimensions( 2, order2, dimensions2 ); - Kokkos::Experimental::resize( b, layout ); + Kokkos::resize( b, layout ); for ( int i0 = 0; i0 < 7; ++i0 ) for ( int i1 = 0; i1 < 8; ++i1 ) @@ -964,8 +964,8 @@ void test_view_mapping() ASSERT_EQ( b( i0, i1 ), val ); } - Kokkos::Experimental::realloc( c, layout ); - Kokkos::Experimental::realloc( d, layout ); + Kokkos::realloc( c, layout ); + Kokkos::realloc( d, layout ); ASSERT_EQ( b.dimension_0(), 7 ); ASSERT_EQ( b.dimension_1(), 8 ); diff --git a/lib/kokkos/core/unit_test/TestViewSubview.hpp b/lib/kokkos/core/unit_test/TestViewSubview.hpp index e3a12e684e..106323492a 100644 --- a/lib/kokkos/core/unit_test/TestViewSubview.hpp +++ b/lib/kokkos/core/unit_test/TestViewSubview.hpp @@ -915,134 +915,134 @@ void test_3d_subview_5d_impl_layout() { inline void test_subview_legal_args_right() { - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, Kokkos::pair, int, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, int, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, Kokkos::Impl::ALL_t, Kokkos::pair, Kokkos::pair, int, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, Kokkos::Impl::ALL_t, Kokkos::pair, Kokkos::Impl::ALL_t, int, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, Kokkos::pair, Kokkos::Impl::ALL_t, Kokkos::pair, int, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, Kokkos::pair, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, int, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, Kokkos::pair, Kokkos::pair, Kokkos::pair, int, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, Kokkos::pair, Kokkos::pair, Kokkos::Impl::ALL_t, int, int >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, Kokkos::pair, int, int >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, int, int >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, Kokkos::Impl::ALL_t, Kokkos::pair, Kokkos::pair, int, int >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, Kokkos::Impl::ALL_t, Kokkos::pair, Kokkos::Impl::ALL_t, int, int >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, Kokkos::pair, Kokkos::Impl::ALL_t, Kokkos::pair, int, int >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, Kokkos::pair, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, int, int >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, Kokkos::pair, Kokkos::pair, Kokkos::pair, int, int >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, Kokkos::pair, Kokkos::pair, Kokkos::Impl::ALL_t, int, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, Kokkos::Impl::ALL_t, int, Kokkos::Impl::ALL_t, Kokkos::pair, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, Kokkos::Impl::ALL_t, int, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, Kokkos::Impl::ALL_t, int, Kokkos::pair, Kokkos::pair, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, Kokkos::Impl::ALL_t, int, Kokkos::pair, Kokkos::Impl::ALL_t, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, Kokkos::pair, int, Kokkos::Impl::ALL_t, Kokkos::pair, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, Kokkos::pair, int, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, Kokkos::pair, int, Kokkos::pair, Kokkos::pair, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, Kokkos::pair, int, Kokkos::Impl::ALL_t, Kokkos::pair, int >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, Kokkos::Impl::ALL_t, int, Kokkos::Impl::ALL_t, Kokkos::pair, int >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, Kokkos::Impl::ALL_t, int, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, int >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, Kokkos::Impl::ALL_t, int, Kokkos::pair, Kokkos::pair, int >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, Kokkos::Impl::ALL_t, int, Kokkos::pair, Kokkos::Impl::ALL_t, int >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, Kokkos::pair, int, Kokkos::Impl::ALL_t, Kokkos::pair, int >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, Kokkos::pair, int, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, int >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, Kokkos::pair, int, Kokkos::pair, Kokkos::pair, int >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, Kokkos::pair, int, Kokkos::Impl::ALL_t, Kokkos::pair, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, int, Kokkos::pair, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, int, Kokkos::Impl::ALL_t, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, Kokkos::Impl::ALL_t, Kokkos::pair, int, Kokkos::pair, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, Kokkos::Impl::ALL_t, Kokkos::pair, int, Kokkos::Impl::ALL_t, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, Kokkos::pair, Kokkos::Impl::ALL_t, int, Kokkos::pair, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, Kokkos::pair, Kokkos::Impl::ALL_t, int, Kokkos::Impl::ALL_t, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, Kokkos::pair, Kokkos::pair, int, Kokkos::pair, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, Kokkos::pair, Kokkos::Impl::ALL_t, int, Kokkos::pair, int >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, int, Kokkos::pair, int >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, int, Kokkos::Impl::ALL_t, int >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, Kokkos::Impl::ALL_t, Kokkos::pair, int, Kokkos::pair, int >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, Kokkos::Impl::ALL_t, Kokkos::pair, int, Kokkos::Impl::ALL_t, int >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, Kokkos::pair, Kokkos::Impl::ALL_t, int, Kokkos::pair, int >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, Kokkos::pair, Kokkos::Impl::ALL_t, int, Kokkos::Impl::ALL_t, int >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, Kokkos::pair, Kokkos::pair, int, Kokkos::pair, int >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, Kokkos::pair, Kokkos::Impl::ALL_t, int, Kokkos::pair, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, int, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, Kokkos::pair, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, int, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, int, Kokkos::Impl::ALL_t, Kokkos::pair, Kokkos::pair, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, int, Kokkos::Impl::ALL_t, Kokkos::pair, Kokkos::Impl::ALL_t, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, int, Kokkos::pair, Kokkos::Impl::ALL_t, Kokkos::pair, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, int, Kokkos::pair, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, int, Kokkos::pair, Kokkos::pair, Kokkos::pair, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, int, Kokkos::pair, Kokkos::pair, Kokkos::Impl::ALL_t, int >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, int, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, Kokkos::pair, int >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, int, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, int >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, int, Kokkos::Impl::ALL_t, Kokkos::pair, Kokkos::pair, int >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, int, Kokkos::Impl::ALL_t, Kokkos::pair, Kokkos::Impl::ALL_t, int >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, int, Kokkos::pair, Kokkos::Impl::ALL_t, Kokkos::pair, int >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, int, Kokkos::pair, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, int >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, int, Kokkos::pair, Kokkos::pair, Kokkos::pair, int >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, int, Kokkos::pair, Kokkos::pair, Kokkos::Impl::ALL_t, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, int, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, int, Kokkos::pair >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, int, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, int, Kokkos::Impl::ALL_t >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, int, Kokkos::Impl::ALL_t, Kokkos::pair, int, Kokkos::pair >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, int, Kokkos::Impl::ALL_t, Kokkos::pair, int, Kokkos::Impl::ALL_t >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, int, Kokkos::pair, Kokkos::Impl::ALL_t, int, Kokkos::pair >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, int, Kokkos::pair, Kokkos::Impl::ALL_t, int, Kokkos::Impl::ALL_t >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, int, Kokkos::pair, Kokkos::pair, int, Kokkos::pair >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, int, Kokkos::pair, Kokkos::pair, int, Kokkos::Impl::ALL_t >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, int, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, int, Kokkos::pair >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, int, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, int, Kokkos::Impl::ALL_t >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, int, Kokkos::Impl::ALL_t, Kokkos::pair, int, Kokkos::pair >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, int, Kokkos::Impl::ALL_t, Kokkos::pair, int, Kokkos::Impl::ALL_t >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, int, Kokkos::pair, Kokkos::Impl::ALL_t, int, Kokkos::pair >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, int, Kokkos::pair, Kokkos::Impl::ALL_t, int, Kokkos::Impl::ALL_t >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, int, Kokkos::pair, Kokkos::pair, int, Kokkos::pair >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, int, Kokkos::pair, Kokkos::pair, int, Kokkos::Impl::ALL_t >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, int, int, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, Kokkos::pair >::value ) ); - ASSERT_EQ( 1, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, int, int, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, int, int, Kokkos::Impl::ALL_t, Kokkos::pair, Kokkos::pair >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, int, int, Kokkos::Impl::ALL_t, Kokkos::pair, Kokkos::Impl::ALL_t >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, int, int, Kokkos::pair, Kokkos::Impl::ALL_t, Kokkos::pair >::value ) ); - ASSERT_EQ( 1, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, int, int, Kokkos::pair, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, int, int, Kokkos::pair, Kokkos::pair, Kokkos::pair >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, int, int, Kokkos::pair, Kokkos::pair, Kokkos::Impl::ALL_t >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, int, int, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, Kokkos::pair >::value ) ); + ASSERT_EQ( 1, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, int, int, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, int, int, Kokkos::Impl::ALL_t, Kokkos::pair, Kokkos::pair >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, int, int, Kokkos::Impl::ALL_t, Kokkos::pair, Kokkos::Impl::ALL_t >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, int, int, Kokkos::pair, Kokkos::Impl::ALL_t, Kokkos::pair >::value ) ); + ASSERT_EQ( 1, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, int, int, Kokkos::pair, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, int, int, Kokkos::pair, Kokkos::pair, Kokkos::pair >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 5, 0, int, int, Kokkos::pair, Kokkos::pair, Kokkos::Impl::ALL_t >::value ) ); - ASSERT_EQ( 1, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 3, 0, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 3, 0, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, Kokkos::pair >::value ) ); - ASSERT_EQ( 1, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 3, 0, Kokkos::pair, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 3, 0, Kokkos::pair, Kokkos::Impl::ALL_t, Kokkos::pair >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 3, 0, Kokkos::Impl::ALL_t, Kokkos::pair, Kokkos::Impl::ALL_t >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 3, 0, Kokkos::Impl::ALL_t, Kokkos::pair, Kokkos::pair >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 3, 0, Kokkos::pair, Kokkos::pair, Kokkos::Impl::ALL_t >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 3, 0, Kokkos::pair, Kokkos::pair, Kokkos::pair >::value ) ); + ASSERT_EQ( 1, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 3, 0, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 3, 0, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, Kokkos::pair >::value ) ); + ASSERT_EQ( 1, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 3, 0, Kokkos::pair, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 3, 0, Kokkos::pair, Kokkos::Impl::ALL_t, Kokkos::pair >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 3, 0, Kokkos::Impl::ALL_t, Kokkos::pair, Kokkos::Impl::ALL_t >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 3, 0, Kokkos::Impl::ALL_t, Kokkos::pair, Kokkos::pair >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 3, 0, Kokkos::pair, Kokkos::pair, Kokkos::Impl::ALL_t >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutRight, Kokkos::LayoutRight, 3, 3, 0, Kokkos::pair, Kokkos::pair, Kokkos::pair >::value ) ); } inline void test_subview_legal_args_left() { - ASSERT_EQ( 1, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, Kokkos::pair, int, int >::value ) ); - ASSERT_EQ( 1, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, int, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, Kokkos::Impl::ALL_t, Kokkos::pair, Kokkos::pair, int, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, Kokkos::Impl::ALL_t, Kokkos::pair, Kokkos::Impl::ALL_t, int, int >::value ) ); - ASSERT_EQ( 1, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, Kokkos::pair, Kokkos::Impl::ALL_t, Kokkos::pair, int, int >::value ) ); - ASSERT_EQ( 1, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, Kokkos::pair, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, int, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, Kokkos::pair, Kokkos::pair, Kokkos::pair, int, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, Kokkos::pair, Kokkos::pair, Kokkos::Impl::ALL_t, int, int >::value ) ); + ASSERT_EQ( 1, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, Kokkos::pair, int, int >::value ) ); + ASSERT_EQ( 1, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, int, int >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, Kokkos::Impl::ALL_t, Kokkos::pair, Kokkos::pair, int, int >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, Kokkos::Impl::ALL_t, Kokkos::pair, Kokkos::Impl::ALL_t, int, int >::value ) ); + ASSERT_EQ( 1, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, Kokkos::pair, Kokkos::Impl::ALL_t, Kokkos::pair, int, int >::value ) ); + ASSERT_EQ( 1, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, Kokkos::pair, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, int, int >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, Kokkos::pair, Kokkos::pair, Kokkos::pair, int, int >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, Kokkos::pair, Kokkos::pair, Kokkos::Impl::ALL_t, int, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, Kokkos::Impl::ALL_t, int, Kokkos::Impl::ALL_t, Kokkos::pair, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, Kokkos::Impl::ALL_t, int, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, Kokkos::Impl::ALL_t, int, Kokkos::pair, Kokkos::pair, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, Kokkos::Impl::ALL_t, int, Kokkos::pair, Kokkos::Impl::ALL_t, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, Kokkos::pair, int, Kokkos::Impl::ALL_t, Kokkos::pair, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, Kokkos::pair, int, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, Kokkos::pair, int, Kokkos::pair, Kokkos::pair, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, Kokkos::pair, int, Kokkos::Impl::ALL_t, Kokkos::pair, int >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, Kokkos::Impl::ALL_t, int, Kokkos::Impl::ALL_t, Kokkos::pair, int >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, Kokkos::Impl::ALL_t, int, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, int >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, Kokkos::Impl::ALL_t, int, Kokkos::pair, Kokkos::pair, int >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, Kokkos::Impl::ALL_t, int, Kokkos::pair, Kokkos::Impl::ALL_t, int >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, Kokkos::pair, int, Kokkos::Impl::ALL_t, Kokkos::pair, int >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, Kokkos::pair, int, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, int >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, Kokkos::pair, int, Kokkos::pair, Kokkos::pair, int >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, Kokkos::pair, int, Kokkos::Impl::ALL_t, Kokkos::pair, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, int, Kokkos::pair, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, int, Kokkos::Impl::ALL_t, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, Kokkos::Impl::ALL_t, Kokkos::pair, int, Kokkos::pair, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, Kokkos::Impl::ALL_t, Kokkos::pair, int, Kokkos::Impl::ALL_t, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, Kokkos::pair, Kokkos::Impl::ALL_t, int, Kokkos::pair, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, Kokkos::pair, Kokkos::Impl::ALL_t, int, Kokkos::Impl::ALL_t, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, Kokkos::pair, Kokkos::pair, int, Kokkos::pair, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, Kokkos::pair, Kokkos::Impl::ALL_t, int, Kokkos::pair, int >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, int, Kokkos::pair, int >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, int, Kokkos::Impl::ALL_t, int >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, Kokkos::Impl::ALL_t, Kokkos::pair, int, Kokkos::pair, int >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, Kokkos::Impl::ALL_t, Kokkos::pair, int, Kokkos::Impl::ALL_t, int >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, Kokkos::pair, Kokkos::Impl::ALL_t, int, Kokkos::pair, int >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, Kokkos::pair, Kokkos::Impl::ALL_t, int, Kokkos::Impl::ALL_t, int >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, Kokkos::pair, Kokkos::pair, int, Kokkos::pair, int >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, Kokkos::pair, Kokkos::Impl::ALL_t, int, Kokkos::pair, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, int, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, Kokkos::pair, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, int, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, int, Kokkos::Impl::ALL_t, Kokkos::pair, Kokkos::pair, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, int, Kokkos::Impl::ALL_t, Kokkos::pair, Kokkos::Impl::ALL_t, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, int, Kokkos::pair, Kokkos::Impl::ALL_t, Kokkos::pair, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, int, Kokkos::pair, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, int, Kokkos::pair, Kokkos::pair, Kokkos::pair, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, int, Kokkos::pair, Kokkos::pair, Kokkos::Impl::ALL_t, int >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, int, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, Kokkos::pair, int >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, int, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, int >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, int, Kokkos::Impl::ALL_t, Kokkos::pair, Kokkos::pair, int >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, int, Kokkos::Impl::ALL_t, Kokkos::pair, Kokkos::Impl::ALL_t, int >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, int, Kokkos::pair, Kokkos::Impl::ALL_t, Kokkos::pair, int >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, int, Kokkos::pair, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, int >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, int, Kokkos::pair, Kokkos::pair, Kokkos::pair, int >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, int, Kokkos::pair, Kokkos::pair, Kokkos::Impl::ALL_t, int >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, int, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, int, Kokkos::pair >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, int, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, int, Kokkos::Impl::ALL_t >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, int, Kokkos::Impl::ALL_t, Kokkos::pair, int, Kokkos::pair >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, int, Kokkos::Impl::ALL_t, Kokkos::pair, int, Kokkos::Impl::ALL_t >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, int, Kokkos::pair, Kokkos::Impl::ALL_t, int, Kokkos::pair >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, int, Kokkos::pair, Kokkos::Impl::ALL_t, int, Kokkos::Impl::ALL_t >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, int, Kokkos::pair, Kokkos::pair, int, Kokkos::pair >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, int, Kokkos::pair, Kokkos::pair, int, Kokkos::Impl::ALL_t >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, int, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, int, Kokkos::pair >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, int, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, int, Kokkos::Impl::ALL_t >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, int, Kokkos::Impl::ALL_t, Kokkos::pair, int, Kokkos::pair >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, int, Kokkos::Impl::ALL_t, Kokkos::pair, int, Kokkos::Impl::ALL_t >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, int, Kokkos::pair, Kokkos::Impl::ALL_t, int, Kokkos::pair >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, int, Kokkos::pair, Kokkos::Impl::ALL_t, int, Kokkos::Impl::ALL_t >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, int, Kokkos::pair, Kokkos::pair, int, Kokkos::pair >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, int, Kokkos::pair, Kokkos::pair, int, Kokkos::Impl::ALL_t >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, int, int, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, Kokkos::pair >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, int, int, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, int, int, Kokkos::Impl::ALL_t, Kokkos::pair, Kokkos::pair >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, int, int, Kokkos::Impl::ALL_t, Kokkos::pair, Kokkos::Impl::ALL_t >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, int, int, Kokkos::pair, Kokkos::Impl::ALL_t, Kokkos::pair >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, int, int, Kokkos::pair, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, int, int, Kokkos::pair, Kokkos::pair, Kokkos::pair >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, int, int, Kokkos::pair, Kokkos::pair, Kokkos::Impl::ALL_t >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, int, int, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, Kokkos::pair >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, int, int, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, int, int, Kokkos::Impl::ALL_t, Kokkos::pair, Kokkos::pair >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, int, int, Kokkos::Impl::ALL_t, Kokkos::pair, Kokkos::Impl::ALL_t >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, int, int, Kokkos::pair, Kokkos::Impl::ALL_t, Kokkos::pair >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, int, int, Kokkos::pair, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, int, int, Kokkos::pair, Kokkos::pair, Kokkos::pair >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 5, 0, int, int, Kokkos::pair, Kokkos::pair, Kokkos::Impl::ALL_t >::value ) ); - ASSERT_EQ( 1, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 3, 0, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, Kokkos::pair >::value ) ); - ASSERT_EQ( 1, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 3, 0, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t >::value ) ); - ASSERT_EQ( 1, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 3, 0, Kokkos::pair, Kokkos::Impl::ALL_t, Kokkos::pair >::value ) ); - ASSERT_EQ( 1, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 3, 0, Kokkos::pair, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 3, 0, Kokkos::Impl::ALL_t, Kokkos::pair, Kokkos::Impl::ALL_t >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 3, 0, Kokkos::Impl::ALL_t, Kokkos::pair, Kokkos::pair >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 3, 0, Kokkos::pair, Kokkos::pair, Kokkos::Impl::ALL_t >::value ) ); - ASSERT_EQ( 0, ( Kokkos::Experimental::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 3, 0, Kokkos::pair, Kokkos::pair, Kokkos::pair >::value ) ); + ASSERT_EQ( 1, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 3, 0, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, Kokkos::pair >::value ) ); + ASSERT_EQ( 1, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 3, 0, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t >::value ) ); + ASSERT_EQ( 1, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 3, 0, Kokkos::pair, Kokkos::Impl::ALL_t, Kokkos::pair >::value ) ); + ASSERT_EQ( 1, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 3, 0, Kokkos::pair, Kokkos::Impl::ALL_t, Kokkos::Impl::ALL_t >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 3, 0, Kokkos::Impl::ALL_t, Kokkos::pair, Kokkos::Impl::ALL_t >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 3, 0, Kokkos::Impl::ALL_t, Kokkos::pair, Kokkos::pair >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 3, 0, Kokkos::pair, Kokkos::pair, Kokkos::Impl::ALL_t >::value ) ); + ASSERT_EQ( 0, ( Kokkos::Impl::SubviewLegalArgsCompileTime< Kokkos::LayoutLeft, Kokkos::LayoutLeft, 3, 3, 0, Kokkos::pair, Kokkos::pair, Kokkos::pair >::value ) ); } } // namespace Impl diff --git a/lib/kokkos/core/unit_test/TestWorkGraph.hpp b/lib/kokkos/core/unit_test/TestWorkGraph.hpp new file mode 100644 index 0000000000..70cf6b47c0 --- /dev/null +++ b/lib/kokkos/core/unit_test/TestWorkGraph.hpp @@ -0,0 +1,172 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include +#include + +#include + +namespace Test { + +namespace { + +/* This test is meant to be the WorkGraph equivalent of the Task DAG Scheduler test, + please see TestTaskScheduler.hpp for that test. + The algorithm computes the N-th fibonacci number as follows: + - Each "task" or "work item" computes the i-th fibonacci number + - If a task as (i < 2), it will record the known answer ahead of time. + - If a taks has (i >= 2), it will "spawn" two more tasks to compute + the (i - 1) and (i - 2) fibonacci numbers. + We do NOT do any de-duplication of these tasks. + De-duplication would result in only (N - 2) tasks which must be run in serial. + We allow duplicates both to increase the number of tasks and to increase the + amount of available parallelism. + */ + +template< class ExecSpace > +struct TestWorkGraph { + + using MemorySpace = typename ExecSpace::memory_space; + using Policy = Kokkos::Experimental::WorkGraphPolicy; + using Graph = typename Policy::graph_type; + using RowMap = typename Graph::row_map_type; + using Entries = typename Graph::entries_type; + using Values = Kokkos::View; + + long m_input; + Graph m_graph; + Graph m_transpose; + Values m_values; + + TestWorkGraph(long arg_input):m_input(arg_input) { + form_graph(); + transpose_crs(m_transpose, m_graph); + } + + inline + long full_fibonacci( long n ) { + constexpr long mask = 0x03; + long fib[4] = { 0, 1, 1, 2 }; + for ( long i = 2; i <= n; ++i ) { + fib[ i & mask ] = fib[ ( i - 1 ) & mask ] + fib[ ( i - 2 ) & mask ]; + } + return fib[ n & mask ]; + } + + struct HostEntry { + long input; + std::int32_t parent; + }; + std::vector form_host_graph() { + std::vector g; + g.push_back({ m_input , -1 }); + for (std::int32_t i = 0; i < std::int32_t(g.size()); ++i) { + auto e = g.at(std::size_t(i)); + if (e.input < 2) continue; + /* This part of the host graph formation is the equivalent of task spawning + in the Task DAG system. Notice how each task which is not a base case + spawns two more tasks, without any de-duplication */ + g.push_back({ e.input - 1, i }); + g.push_back({ e.input - 2, i }); + } + return g; + } + + void form_graph() { + auto hg = form_host_graph(); + m_graph.row_map = RowMap("row_map", hg.size() + 1); // row map always has one more + m_graph.entries = Entries("entries", hg.size() - 1); // all but the first have a parent + m_values = Values("values", hg.size()); + auto h_row_map = Kokkos::create_mirror_view(m_graph.row_map); + auto h_entries = Kokkos::create_mirror_view(m_graph.entries); + auto h_values = Kokkos::create_mirror_view(m_values); + h_row_map(0) = 0; + for (std::int32_t i = 0; i < std::int32_t(hg.size()); ++i) { + auto& e = hg.at(std::size_t(i)); + h_row_map(i + 1) = i; + if (e.input < 2) { + h_values(i) = e.input; + } + if (e.parent == -1) continue; + h_entries(i - 1) = e.parent; + } + Kokkos::deep_copy(m_graph.row_map, h_row_map); + Kokkos::deep_copy(m_graph.entries, h_entries); + Kokkos::deep_copy(m_values, h_values); + } + + KOKKOS_INLINE_FUNCTION + void operator()(std::int32_t i) const { + auto begin = m_transpose.row_map(i); + auto end = m_transpose.row_map(i + 1); + for (auto j = begin; j < end; ++j) { + auto k = m_transpose.entries(j); + m_values(i) += m_values( k ); + } + } + + void test_for() { + Kokkos::parallel_for(Policy(m_graph), *this); + auto h_values = Kokkos::create_mirror_view(m_values); + Kokkos::deep_copy(h_values, m_values); + ASSERT_EQ( h_values(0), full_fibonacci(m_input) ); + } + +}; + +} // anonymous namespace + +TEST_F( TEST_CATEGORY, DISABLED_workgraph_fib ) +{ + #ifdef KOKKOS_IMPL_CUDA_CLANG_WORKAROUND + int limit = 15; + #else + int limit = 27; + #endif + for ( int i = 0; i < limit; ++i) { + TestWorkGraph< TEST_EXECSPACE > f(i); + f.test_for(); + } +} + +} // namespace Test diff --git a/lib/kokkos/core/unit_test/UnitTestMain.cpp b/lib/kokkos/core/unit_test/UnitTestMain.cpp index 4f52fc9567..a7dc7c4973 100644 --- a/lib/kokkos/core/unit_test/UnitTestMain.cpp +++ b/lib/kokkos/core/unit_test/UnitTestMain.cpp @@ -42,6 +42,7 @@ */ #include +#include int main( int argc, char *argv[] ) { ::testing::InitGoogleTest( &argc, argv ); diff --git a/lib/kokkos/core/unit_test/UnitTestMainInit.cpp b/lib/kokkos/core/unit_test/UnitTestMainInit.cpp index 21f851274b..62a01e9033 100644 --- a/lib/kokkos/core/unit_test/UnitTestMainInit.cpp +++ b/lib/kokkos/core/unit_test/UnitTestMainInit.cpp @@ -42,6 +42,8 @@ */ #include +#include + #include int main( int argc, char *argv[] ) { diff --git a/lib/kokkos/core/unit_test/cuda/TestCuda_Other.cpp b/lib/kokkos/core/unit_test/cuda/TestCuda_Other.cpp index ba06b71192..fa6722615c 100644 --- a/lib/kokkos/core/unit_test/cuda/TestCuda_Other.cpp +++ b/lib/kokkos/core/unit_test/cuda/TestCuda_Other.cpp @@ -48,3 +48,5 @@ #include #include #include + +#include diff --git a/lib/kokkos/core/unit_test/cuda/TestCuda_UniqueToken.cpp b/lib/kokkos/core/unit_test/cuda/TestCuda_UniqueToken.cpp new file mode 100644 index 0000000000..8424ae10d6 --- /dev/null +++ b/lib/kokkos/core/unit_test/cuda/TestCuda_UniqueToken.cpp @@ -0,0 +1,46 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include +#include + diff --git a/lib/kokkos/core/unit_test/cuda/TestCuda_WorkGraph.cpp b/lib/kokkos/core/unit_test/cuda/TestCuda_WorkGraph.cpp new file mode 100644 index 0000000000..663ca1d560 --- /dev/null +++ b/lib/kokkos/core/unit_test/cuda/TestCuda_WorkGraph.cpp @@ -0,0 +1,45 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include +#include diff --git a/lib/kokkos/core/unit_test/default/TestDefaultDeviceTypeResize.cpp b/lib/kokkos/core/unit_test/default/TestDefaultDeviceTypeResize.cpp new file mode 100644 index 0000000000..c02905535b --- /dev/null +++ b/lib/kokkos/core/unit_test/default/TestDefaultDeviceTypeResize.cpp @@ -0,0 +1,57 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include +#include "TestResize.hpp" + +namespace Test { + +TEST( kokkosresize, host_space_access ) +{ + // Test with the default device type. + using TestViewResize::testResize; + typedef Kokkos::View::device_type device_type; + testResize (); +} + +} // namespace Test diff --git a/lib/kokkos/core/unit_test/openmp/TestOpenMP.hpp b/lib/kokkos/core/unit_test/openmp/TestOpenMP.hpp index 2f8daf7ad7..c12574a65a 100644 --- a/lib/kokkos/core/unit_test/openmp/TestOpenMP.hpp +++ b/lib/kokkos/core/unit_test/openmp/TestOpenMP.hpp @@ -86,25 +86,26 @@ class openmp : public ::testing::Test { protected: static void SetUpTestCase() { - const unsigned numa_count = Kokkos::hwloc::get_available_numa_count(); - const unsigned cores_per_numa = Kokkos::hwloc::get_available_cores_per_numa(); - const unsigned threads_per_core = Kokkos::hwloc::get_available_threads_per_core(); + int threads_count = 0; + #pragma omp parallel + { + #pragma omp atomic + ++threads_count; + } - const unsigned threads_count = std::max( 1u, numa_count ) * - std::max( 2u, ( cores_per_numa * threads_per_core ) / 2 ); + if (threads_count > 3) { + threads_count /= 2; + } Kokkos::OpenMP::initialize( threads_count ); Kokkos::print_configuration( std::cout, true ); + srand( 10231 ); } static void TearDownTestCase() { Kokkos::OpenMP::finalize(); - - omp_set_num_threads( 1 ); - - ASSERT_EQ( 1, omp_get_max_threads() ); } }; diff --git a/lib/kokkos/core/unit_test/openmp/TestOpenMP_Other.cpp b/lib/kokkos/core/unit_test/openmp/TestOpenMP_Other.cpp index 5e9535638d..33e7402ce6 100644 --- a/lib/kokkos/core/unit_test/openmp/TestOpenMP_Other.cpp +++ b/lib/kokkos/core/unit_test/openmp/TestOpenMP_Other.cpp @@ -48,3 +48,93 @@ #include #include #include + +#include + +#include + +namespace Test { + +TEST_F( openmp, partition_master ) +{ + using Mutex = Kokkos::Experimental::MasterLock; + + Mutex mtx; + int errors = 0; + + auto master = [&errors, &mtx](int partition_id, int num_partitions) { + + const int pool_size = Kokkos::OpenMP::thread_pool_size(); + + { + std::unique_lock lock(mtx); + if ( Kokkos::OpenMP::in_parallel() ) { + ++errors; + } + if ( Kokkos::OpenMP::thread_pool_rank() != 0 ) { + ++errors; + } + } + + { + int local_errors = 0; + Kokkos::parallel_reduce( Kokkos::RangePolicy(0,1000) + , [pool_size]( const int , int & errs ) { + if ( Kokkos::OpenMP::thread_pool_size() != pool_size ) { + ++errs; + } + } + , local_errors + ); + Kokkos::atomic_add( &errors, local_errors ); + } + + Kokkos::Experimental::UniqueToken< Kokkos::OpenMP > token; + + Kokkos::View count( "", token.size() ); + + Kokkos::parallel_for( Kokkos::RangePolicy(0,1000), + [=] ( const int ) { + int i = token.acquire(); + ++count[i]; + token.release(i); + }); + + Kokkos::View sum (""); + Kokkos::parallel_for( Kokkos::RangePolicy(0,token.size()), + [=] ( const int i ) { + Kokkos::atomic_add( sum.data(), count[i] ); + }); + + if (sum() != 1000) { + Kokkos::atomic_add( &errors, 1 ); + } + }; + + master(0,1); + + ASSERT_EQ( errors, 0 ); + + Kokkos::OpenMP::partition_master( master ); + ASSERT_EQ( errors, 0 ); + + Kokkos::OpenMP::partition_master( master, 4, 0 ); + ASSERT_EQ( errors, 0 ); + + Kokkos::OpenMP::partition_master( master, 0, 4 ); + ASSERT_EQ( errors, 0 ); + + Kokkos::OpenMP::partition_master( master, 2, 2 ); + ASSERT_EQ( errors, 0 ); + + Kokkos::OpenMP::partition_master( master, 8, 0 ); + ASSERT_EQ( errors, 0 ); + + Kokkos::OpenMP::partition_master( master, 0, 8 ); + ASSERT_EQ( errors, 0 ); + + Kokkos::OpenMP::partition_master( master, 8, 8 ); + ASSERT_EQ( errors, 0 ); +} + +} // namespace Test diff --git a/lib/kokkos/core/unit_test/openmp/TestOpenMP_UniqueToken.cpp b/lib/kokkos/core/unit_test/openmp/TestOpenMP_UniqueToken.cpp new file mode 100644 index 0000000000..143a6d9910 --- /dev/null +++ b/lib/kokkos/core/unit_test/openmp/TestOpenMP_UniqueToken.cpp @@ -0,0 +1,46 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include +#include + diff --git a/lib/kokkos/core/unit_test/openmp/TestOpenMP_WorkGraph.cpp b/lib/kokkos/core/unit_test/openmp/TestOpenMP_WorkGraph.cpp new file mode 100644 index 0000000000..ec6fa1653c --- /dev/null +++ b/lib/kokkos/core/unit_test/openmp/TestOpenMP_WorkGraph.cpp @@ -0,0 +1,45 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include +#include diff --git a/lib/kokkos/core/unit_test/serial/TestSerial_Other.cpp b/lib/kokkos/core/unit_test/serial/TestSerial_Other.cpp index a6a76a03bd..bc39b1e160 100644 --- a/lib/kokkos/core/unit_test/serial/TestSerial_Other.cpp +++ b/lib/kokkos/core/unit_test/serial/TestSerial_Other.cpp @@ -48,3 +48,5 @@ #include #include #include + +#include diff --git a/lib/kokkos/core/unit_test/serial/TestSerial_WorkGraph.cpp b/lib/kokkos/core/unit_test/serial/TestSerial_WorkGraph.cpp new file mode 100644 index 0000000000..de1638de5e --- /dev/null +++ b/lib/kokkos/core/unit_test/serial/TestSerial_WorkGraph.cpp @@ -0,0 +1,45 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include +#include diff --git a/lib/kokkos/core/unit_test/threads/TestThreads_Other.cpp b/lib/kokkos/core/unit_test/threads/TestThreads_Other.cpp index c11155c5c0..160b37a2c8 100644 --- a/lib/kokkos/core/unit_test/threads/TestThreads_Other.cpp +++ b/lib/kokkos/core/unit_test/threads/TestThreads_Other.cpp @@ -48,3 +48,5 @@ #include #include #include + +#include diff --git a/lib/kokkos/core/unit_test/threads/TestThreads_WorkGraph.cpp b/lib/kokkos/core/unit_test/threads/TestThreads_WorkGraph.cpp new file mode 100644 index 0000000000..6b7dbb26db --- /dev/null +++ b/lib/kokkos/core/unit_test/threads/TestThreads_WorkGraph.cpp @@ -0,0 +1,45 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include +#include diff --git a/lib/kokkos/example/cmake_build/CMakeLists.txt b/lib/kokkos/example/cmake_build/CMakeLists.txt index 4e149726ee..f92c5c6513 100644 --- a/lib/kokkos/example/cmake_build/CMakeLists.txt +++ b/lib/kokkos/example/cmake_build/CMakeLists.txt @@ -40,5 +40,7 @@ list(APPEND CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} -O3) add_subdirectory(${Example_SOURCE_DIR}/../.. ${Example_BINARY_DIR}/kokkos) +include_directories(${Kokkos_INCLUDE_DIRS_RET}) + add_executable(example cmake_example.cpp) target_link_libraries(example kokkos) diff --git a/lib/kokkos/example/feint/main.cpp b/lib/kokkos/example/feint/main.cpp index 616e584bf6..57a8f8fafb 100644 --- a/lib/kokkos/example/feint/main.cpp +++ b/lib/kokkos/example/feint/main.cpp @@ -69,12 +69,26 @@ int main() #if defined( KOKKOS_ENABLE_OPENMP ) { - // Use 4 cores per NUMA region, unless fewer available - const unsigned use_numa_count = Kokkos::hwloc::get_available_numa_count(); - const unsigned use_cores_per_numa = std::min( 4u , Kokkos::hwloc::get_available_cores_per_numa() ); + int num_threads = 0; + if ( Kokkos::hwloc::available() ) { + // Use 4 cores per NUMA region, unless fewer available + const unsigned use_numa_count = Kokkos::hwloc::get_available_numa_count(); + const unsigned use_cores_per_numa = std::min( 4u , Kokkos::hwloc::get_available_cores_per_numa() ); + num_threads = use_numa_count * use_cores_per_numa; - Kokkos::OpenMP::initialize( use_numa_count * use_cores_per_numa ); + } + else { + #pragma omp parallel + { + #pragma omp atomic + ++num_threads; + } + num_threads = std::max(4, num_threads/4); + } + + + Kokkos::OpenMP::initialize( num_threads ); std::cout << "feint< OpenMP , NotUsingAtomic >" << std::endl ; Kokkos::Example::feint< Kokkos::OpenMP , false >(); diff --git a/lib/kokkos/example/global_2_local_ids/G2L_Main.cpp b/lib/kokkos/example/global_2_local_ids/G2L_Main.cpp index fb33aef56e..b6b8b2f5e0 100644 --- a/lib/kokkos/example/global_2_local_ids/G2L_Main.cpp +++ b/lib/kokkos/example/global_2_local_ids/G2L_Main.cpp @@ -138,7 +138,16 @@ int main(int argc, char *argv[]) #endif #ifdef KOKKOS_ENABLE_OPENMP - Kokkos::OpenMP::initialize( threads_count ); + int num_threads = 0; + #pragma omp parallel + { + #pragma omp atomic + ++num_threads; + } + if( num_threads > 3 ) { + num_threads = std::max(4, num_threads/4); + } + Kokkos::OpenMP::initialize( num_threads ); num_errors += G2L::run_openmp(num_ids,num_find_iterations); Kokkos::OpenMP::finalize(); #endif diff --git a/lib/kokkos/example/grow_array/main.cpp b/lib/kokkos/example/grow_array/main.cpp index e7438a9bf4..3f1d534d93 100644 --- a/lib/kokkos/example/grow_array/main.cpp +++ b/lib/kokkos/example/grow_array/main.cpp @@ -88,7 +88,7 @@ int main( int argc , char ** argv ) #if defined( KOKKOS_ENABLE_OPENMP ) { std::cout << "Kokkos::OpenMP" << std::endl ; - Kokkos::OpenMP::initialize( num_threads , use_numa , use_core ); + Kokkos::OpenMP::initialize(); Example::grow_array< Kokkos::OpenMP >( length_array , span_values ); Kokkos::OpenMP::finalize(); } diff --git a/lib/kokkos/example/tutorial/03_simple_view/Makefile b/lib/kokkos/example/tutorial/03_simple_view/Makefile index e716b765e7..32483a2555 100644 --- a/lib/kokkos/example/tutorial/03_simple_view/Makefile +++ b/lib/kokkos/example/tutorial/03_simple_view/Makefile @@ -33,6 +33,7 @@ include $(KOKKOS_PATH)/Makefile.kokkos build: $(EXE) +#for unit testing only, for best preformance with OpenMP 4.0 or better test: $(EXE) ./$(EXE) diff --git a/lib/kokkos/example/tutorial/Advanced_Views/Makefile b/lib/kokkos/example/tutorial/Advanced_Views/Makefile index bc4012f68c..12ac5652e5 100644 --- a/lib/kokkos/example/tutorial/Advanced_Views/Makefile +++ b/lib/kokkos/example/tutorial/Advanced_Views/Makefile @@ -22,100 +22,102 @@ endif build: mkdir -p 01_data_layouts cd ./01_data_layouts; \ - make build -j 4 -f ${KOKKOS_PATH}/example/tutorial/Advanced_Views/01_data_layouts/Makefile ${KOKKOS_SETTINGS} + $(MAKE) build -f ${KOKKOS_PATH}/example/tutorial/Advanced_Views/01_data_layouts/Makefile ${KOKKOS_SETTINGS} mkdir -p 02_memory_traits cd ./02_memory_traits; \ - make build -j 4 -f ${KOKKOS_PATH}/example/tutorial/Advanced_Views/02_memory_traits/Makefile ${KOKKOS_SETTINGS} + $(MAKE) build -f ${KOKKOS_PATH}/example/tutorial/Advanced_Views/02_memory_traits/Makefile ${KOKKOS_SETTINGS} mkdir -p 03_subviews cd ./03_subviews; \ - make build -j 4 -f ${KOKKOS_PATH}/example/tutorial/Advanced_Views/03_subviews/Makefile ${KOKKOS_SETTINGS} + $(MAKE) build -f ${KOKKOS_PATH}/example/tutorial/Advanced_Views/03_subviews/Makefile ${KOKKOS_SETTINGS} mkdir -p 04_dualviews cd ./04_dualviews; \ - make build -j 4 -f ${KOKKOS_PATH}/example/tutorial/Advanced_Views/04_dualviews/Makefile ${KOKKOS_SETTINGS} + $(MAKE) build -f ${KOKKOS_PATH}/example/tutorial/Advanced_Views/04_dualviews/Makefile ${KOKKOS_SETTINGS} mkdir -p 05_NVIDIA_UVM cd ./05_NVIDIA_UVM; \ - make build -j 4 -f ${KOKKOS_PATH}/example/tutorial/Advanced_Views/05_NVIDIA_UVM/Makefile ${KOKKOS_SETTINGS} + $(MAKE) build -f ${KOKKOS_PATH}/example/tutorial/Advanced_Views/05_NVIDIA_UVM/Makefile ${KOKKOS_SETTINGS} #mkdir -p 06_AtomicViews #cd ./06_AtomicViews; \ - #make build -j 4 -f ${KOKKOS_PATH}/example/tutorial/Advanced_Views/06_AtomicViews/Makefile ${KOKKOS_SETTINGS} + #$(MAKE) build -f ${KOKKOS_PATH}/example/tutorial/Advanced_Views/06_AtomicViews/Makefile ${KOKKOS_SETTINGS} #mkdir -p 07_Overlapping_DeepCopy #cd ./07_Overlapping_DeepCopy; \ - #make build -j 4 -f ${KOKKOS_PATH}/example/tutorial/Advanced_Views/07_Overlapping_DeepCopy/Makefile ${KOKKOS_SETTINGS} + #$(MAKE) build -f ${KOKKOS_PATH}/example/tutorial/Advanced_Views/07_Overlapping_DeepCopy/Makefile ${KOKKOS_SETTINGS} build-insource: cd ./01_data_layouts; \ - make build -j 4 ${KOKKOS_SETTINGS} + $(MAKE) build ${KOKKOS_SETTINGS} cd ./02_memory_traits; \ - make build -j 4 ${KOKKOS_SETTINGS} + $(MAKE) build ${KOKKOS_SETTINGS} cd ./03_subviews; \ - make build -j 4 ${KOKKOS_SETTINGS} + $(MAKE) build ${KOKKOS_SETTINGS} cd ./04_dualviews; \ - make build -j 4 ${KOKKOS_SETTINGS} + $(MAKE) build ${KOKKOS_SETTINGS} cd ./05_NVIDIA_UVM; \ - make build -j 4 ${KOKKOS_SETTINGS} + $(MAKE) build ${KOKKOS_SETTINGS} #cd ./06_AtomicViews; \ - #make build -j 4 ${KOKKOS_SETTINGS} + #$(MAKE) build ${KOKKOS_SETTINGS} #cd ./07_Overlapping_DeepCopy; \ - #make build -j 4 ${KOKKOS_SETTINGS} + #$(MAKE) build ${KOKKOS_SETTINGS} + test: cd ./01_data_layouts; \ - make test -j 4 -f ${KOKKOS_PATH}/example/tutorial/Advanced_Views/01_data_layouts/Makefile ${KOKKOS_SETTINGS} + $(MAKE) test -f ${KOKKOS_PATH}/example/tutorial/Advanced_Views/01_data_layouts/Makefile ${KOKKOS_SETTINGS} cd ./02_memory_traits; \ - make test -j 4 -f ${KOKKOS_PATH}/example/tutorial/Advanced_Views/02_memory_traits/Makefile ${KOKKOS_SETTINGS} + $(MAKE) test -f ${KOKKOS_PATH}/example/tutorial/Advanced_Views/02_memory_traits/Makefile ${KOKKOS_SETTINGS} cd ./03_subviews; \ - make test -j 4 -f ${KOKKOS_PATH}/example/tutorial/Advanced_Views/03_subviews/Makefile ${KOKKOS_SETTINGS} + $(MAKE) test -f ${KOKKOS_PATH}/example/tutorial/Advanced_Views/03_subviews/Makefile ${KOKKOS_SETTINGS} cd ./04_dualviews; \ - make test -j 4 -f ${KOKKOS_PATH}/example/tutorial/Advanced_Views/04_dualviews/Makefile ${KOKKOS_SETTINGS} + $(MAKE) test -f ${KOKKOS_PATH}/example/tutorial/Advanced_Views/04_dualviews/Makefile ${KOKKOS_SETTINGS} cd ./05_NVIDIA_UVM; \ - make test -j 4 -f ${KOKKOS_PATH}/example/tutorial/Advanced_Views/05_NVIDIA_UVM/Makefile ${KOKKOS_SETTINGS} + $(MAKE) test -f ${KOKKOS_PATH}/example/tutorial/Advanced_Views/05_NVIDIA_UVM/Makefile ${KOKKOS_SETTINGS} #cd ./06_AtomicViews; \ - #make test -j 4 -f ${KOKKOS_PATH}/example/tutorial/Advanced_Views/06_AtomicViews/Makefile ${KOKKOS_SETTINGS} + #$(MAKE) test -f ${KOKKOS_PATH}/example/tutorial/Advanced_Views/06_AtomicViews/Makefile ${KOKKOS_SETTINGS} #cd ./07_Overlapping_DeepCopy; \ - #make test -j 4 -f ${KOKKOS_PATH}/example/tutorial/Advanced_Views/07_Overlapping_DeepCopy/Makefile ${KOKKOS_SETTINGS} + #$(MAKE) test -f ${KOKKOS_PATH}/example/tutorial/Advanced_Views/07_Overlapping_DeepCopy/Makefile ${KOKKOS_SETTINGS} test-insource: cd ./01_data_layouts; \ - make test -j 4 ${KOKKOS_SETTINGS} + $(MAKE) test ${KOKKOS_SETTINGS} cd ./02_memory_traits; \ - make test -j 4 ${KOKKOS_SETTINGS} + $(MAKE) test ${KOKKOS_SETTINGS} cd ./03_subviews; \ - make test -j 4 ${KOKKOS_SETTINGS} + $(MAKE) test ${KOKKOS_SETTINGS} cd ./04_dualviews; \ - make test -j 4 ${KOKKOS_SETTINGS} + $(MAKE) test ${KOKKOS_SETTINGS} cd ./05_NVIDIA_UVM; \ - make test -j 4 ${KOKKOS_SETTINGS} + $(MAKE) test ${KOKKOS_SETTINGS} #cd ./06_AtomicViews; \ - #make test -j 4 ${KOKKOS_SETTINGS} + #$(MAKE) test ${KOKKOS_SETTINGS} #cd ./07_Overlapping_DeepCopy; \ - #make test -j 4 ${KOKKOS_SETTINGS} + #$(MAKE) test ${KOKKOS_SETTINGS} + clean: cd ./01_data_layouts; \ - make clean -f ${KOKKOS_PATH}/example/tutorial/Advanced_Views/01_data_layouts/Makefile ${KOKKOS_SETTINGS} + $(MAKE) clean -f ${KOKKOS_PATH}/example/tutorial/Advanced_Views/01_data_layouts/Makefile ${KOKKOS_SETTINGS} cd ./02_memory_traits; \ - make clean -f ${KOKKOS_PATH}/example/tutorial/Advanced_Views/02_memory_traits/Makefile ${KOKKOS_SETTINGS} + $(MAKE) clean -f ${KOKKOS_PATH}/example/tutorial/Advanced_Views/02_memory_traits/Makefile ${KOKKOS_SETTINGS} cd ./03_subviews; \ - make clean -f ${KOKKOS_PATH}/example/tutorial/Advanced_Views/03_subviews/Makefile ${KOKKOS_SETTINGS} + $(MAKE) clean -f ${KOKKOS_PATH}/example/tutorial/Advanced_Views/03_subviews/Makefile ${KOKKOS_SETTINGS} cd ./04_dualviews; \ - make clean -f ${KOKKOS_PATH}/example/tutorial/Advanced_Views/04_dualviews/Makefile ${KOKKOS_SETTINGS} + $(MAKE) clean -f ${KOKKOS_PATH}/example/tutorial/Advanced_Views/04_dualviews/Makefile ${KOKKOS_SETTINGS} cd ./05_NVIDIA_UVM; \ - make clean -f ${KOKKOS_PATH}/example/tutorial/Advanced_Views/05_NVIDIA_UVM/Makefile ${KOKKOS_SETTINGS} + $(MAKE) clean -f ${KOKKOS_PATH}/example/tutorial/Advanced_Views/05_NVIDIA_UVM/Makefile ${KOKKOS_SETTINGS} #cd ./06_AtomicViews; \ - #make clean -f ${KOKKOS_PATH}/example/tutorial/Advanced_Views/06_AtomicViews/Makefile ${KOKKOS_SETTINGS} + #$(MAKE) clean -f ${KOKKOS_PATH}/example/tutorial/Advanced_Views/06_AtomicViews/Makefile ${KOKKOS_SETTINGS} #cd ./07_Overlapping_DeepCopy; \ - #make clean -f ${KOKKOS_PATH}/example/tutorial/Advanced_Views/07_Overlapping_DeepCopy/Makefile ${KOKKOS_SETTINGS} + #$(MAKE) clean -f ${KOKKOS_PATH}/example/tutorial/Advanced_Views/07_Overlapping_DeepCopy/Makefile ${KOKKOS_SETTINGS} clean-insource: cd ./01_data_layouts; \ - make clean ${KOKKOS_SETTINGS} + $(MAKE) clean ${KOKKOS_SETTINGS} cd ./02_memory_traits; \ - make clean ${KOKKOS_SETTINGS} + $(MAKE) clean ${KOKKOS_SETTINGS} cd ./03_subviews; \ - make clean ${KOKKOS_SETTINGS} + $(MAKE) clean ${KOKKOS_SETTINGS} cd ./04_dualviews; \ - make clean ${KOKKOS_SETTINGS} + $(MAKE) clean ${KOKKOS_SETTINGS} cd ./05_NVIDIA_UVM; \ - make clean ${KOKKOS_SETTINGS} + $(MAKE) clean ${KOKKOS_SETTINGS} #cd ./06_AtomicViews; \ - #make clean ${KOKKOS_SETTINGS} + #$(MAKE) clean ${KOKKOS_SETTINGS} #cd ./07_Overlapping_DeepCopy; \ - #make clean ${KOKKOS_SETTINGS} + #$(MAKE) clean ${KOKKOS_SETTINGS} diff --git a/lib/kokkos/example/tutorial/Algorithms/Makefile b/lib/kokkos/example/tutorial/Algorithms/Makefile index ad0b76f9d6..4e70ba7d97 100644 --- a/lib/kokkos/example/tutorial/Algorithms/Makefile +++ b/lib/kokkos/example/tutorial/Algorithms/Makefile @@ -22,22 +22,22 @@ endif build: mkdir -p 01_random_numbers cd ./01_random_numbers; \ - make build -j 4 -f ${KOKKOS_PATH}/example/tutorial/Algorithms/01_random_numbers/Makefile ${KOKKOS_SETTINGS} + $(MAKE) build -f ${KOKKOS_PATH}/example/tutorial/Algorithms/01_random_numbers/Makefile ${KOKKOS_SETTINGS} build-insource: cd ./01_random_numbers; \ - make build -j 4 ${KOKKOS_SETTINGS} + $(MAKE) build ${KOKKOS_SETTINGS} test: cd ./01_random_numbers; \ - make test -j 4 -f ${KOKKOS_PATH}/example/tutorial/Algorithms/01_random_numbers/Makefile ${KOKKOS_SETTINGS} + $(MAKE) test -f ${KOKKOS_PATH}/example/tutorial/Algorithms/01_random_numbers/Makefile ${KOKKOS_SETTINGS} test-insource: cd ./01_random_numbers; \ - make test -j 4 ${KOKKOS_SETTINGS} + $(MAKE) test ${KOKKOS_SETTINGS} clean: cd ./01_random_numbers; \ - make clean -f ${KOKKOS_PATH}/example/tutorial/Algorithms/01_random_numbers/Makefile ${KOKKOS_SETTINGS} + $(MAKE) clean -f ${KOKKOS_PATH}/example/tutorial/Algorithms/01_random_numbers/Makefile ${KOKKOS_SETTINGS} clean-insource: cd ./01_random_numbers; \ - make clean ${KOKKOS_SETTINGS} + $(MAKE) clean ${KOKKOS_SETTINGS} diff --git a/lib/kokkos/example/tutorial/Hierarchical_Parallelism/Makefile b/lib/kokkos/example/tutorial/Hierarchical_Parallelism/Makefile index 44fdf90f8a..4bf6d487ae 100644 --- a/lib/kokkos/example/tutorial/Hierarchical_Parallelism/Makefile +++ b/lib/kokkos/example/tutorial/Hierarchical_Parallelism/Makefile @@ -22,74 +22,74 @@ endif build: mkdir -p 01_thread_teams cd ./01_thread_teams; \ - make build -j 4 -f ${KOKKOS_PATH}/example/tutorial/Hierarchical_Parallelism/01_thread_teams/Makefile ${KOKKOS_SETTINGS} + $(MAKE) build -f ${KOKKOS_PATH}/example/tutorial/Hierarchical_Parallelism/01_thread_teams/Makefile ${KOKKOS_SETTINGS} mkdir -p 01_thread_teams_lambda cd ./01_thread_teams_lambda; \ - make build -j 4 -f ${KOKKOS_PATH}/example/tutorial/Hierarchical_Parallelism/01_thread_teams_lambda/Makefile ${KOKKOS_SETTINGS} + $(MAKE) build -f ${KOKKOS_PATH}/example/tutorial/Hierarchical_Parallelism/01_thread_teams_lambda/Makefile ${KOKKOS_SETTINGS} mkdir -p 02_nested_parallel_for cd ./02_nested_parallel_for; \ - make build -j 4 -f ${KOKKOS_PATH}/example/tutorial/Hierarchical_Parallelism/02_nested_parallel_for/Makefile ${KOKKOS_SETTINGS} + $(MAKE) build -f ${KOKKOS_PATH}/example/tutorial/Hierarchical_Parallelism/02_nested_parallel_for/Makefile ${KOKKOS_SETTINGS} mkdir -p 03_vectorization cd ./03_vectorization; \ - make build -j 4 -f ${KOKKOS_PATH}/example/tutorial/Hierarchical_Parallelism/03_vectorization/Makefile ${KOKKOS_SETTINGS} + $(MAKE) build -f ${KOKKOS_PATH}/example/tutorial/Hierarchical_Parallelism/03_vectorization/Makefile ${KOKKOS_SETTINGS} mkdir -p 04_team_scan cd ./04_team_scan; \ - make build -j 4 -f ${KOKKOS_PATH}/example/tutorial/Hierarchical_Parallelism/04_team_scan/Makefile ${KOKKOS_SETTINGS} + $(MAKE) build -f ${KOKKOS_PATH}/example/tutorial/Hierarchical_Parallelism/04_team_scan/Makefile ${KOKKOS_SETTINGS} build-insource: cd ./01_thread_teams; \ - make build -j 4 ${KOKKOS_SETTINGS} + $(MAKE) build ${KOKKOS_SETTINGS} cd ./01_thread_teams_lambda; \ - make build -j 4 ${KOKKOS_SETTINGS} + $(MAKE) build ${KOKKOS_SETTINGS} cd ./02_nested_parallel_for; \ - make build -j 4 ${KOKKOS_SETTINGS} + $(MAKE) build ${KOKKOS_SETTINGS} cd ./03_vectorization; \ - make build -j 4 ${KOKKOS_SETTINGS} + $(MAKE) build ${KOKKOS_SETTINGS} cd ./04_team_scan; \ - make build -j 4 ${KOKKOS_SETTINGS} + $(MAKE) build ${KOKKOS_SETTINGS} test: cd ./01_thread_teams; \ - make test -j 4 -f ${KOKKOS_PATH}/example/tutorial/Hierarchical_Parallelism/01_thread_teams/Makefile ${KOKKOS_SETTINGS} + $(MAKE) test -f ${KOKKOS_PATH}/example/tutorial/Hierarchical_Parallelism/01_thread_teams/Makefile ${KOKKOS_SETTINGS} cd ./01_thread_teams_lambda; \ - make test -j 4 -f ${KOKKOS_PATH}/example/tutorial/Hierarchical_Parallelism/01_thread_teams_lambda/Makefile ${KOKKOS_SETTINGS} + $(MAKE) test -f ${KOKKOS_PATH}/example/tutorial/Hierarchical_Parallelism/01_thread_teams_lambda/Makefile ${KOKKOS_SETTINGS} cd ./02_nested_parallel_for; \ - make test -j 4 -f ${KOKKOS_PATH}/example/tutorial/Hierarchical_Parallelism/02_nested_parallel_for/Makefile ${KOKKOS_SETTINGS} + $(MAKE) test -f ${KOKKOS_PATH}/example/tutorial/Hierarchical_Parallelism/02_nested_parallel_for/Makefile ${KOKKOS_SETTINGS} cd ./03_vectorization; \ - make test -j 4 -f ${KOKKOS_PATH}/example/tutorial/Hierarchical_Parallelism/03_vectorization/Makefile ${KOKKOS_SETTINGS} + $(MAKE) test -f ${KOKKOS_PATH}/example/tutorial/Hierarchical_Parallelism/03_vectorization/Makefile ${KOKKOS_SETTINGS} cd ./04_team_scan; \ - make test -j 4 -f ${KOKKOS_PATH}/example/tutorial/Hierarchical_Parallelism/04_team_scan/Makefile ${KOKKOS_SETTINGS} + $(MAKE) test -f ${KOKKOS_PATH}/example/tutorial/Hierarchical_Parallelism/04_team_scan/Makefile ${KOKKOS_SETTINGS} test-insource: cd ./01_thread_teams; \ - make test -j 4 ${KOKKOS_SETTINGS} + $(MAKE) test ${KOKKOS_SETTINGS} cd ./01_thread_teams_lambda; \ - make test -j 4 ${KOKKOS_SETTINGS} + $(MAKE) test ${KOKKOS_SETTINGS} cd ./02_nested_parallel_for; \ - make test -j 4 ${KOKKOS_SETTINGS} + $(MAKE) test ${KOKKOS_SETTINGS} cd ./03_vectorization; \ - make test -j 4 ${KOKKOS_SETTINGS} + $(MAKE) test ${KOKKOS_SETTINGS} cd ./04_team_scan; \ - make test -j 4 ${KOKKOS_SETTINGS} + $(MAKE) test ${KOKKOS_SETTINGS} clean: cd ./01_thread_teams; \ - make clean -f ${KOKKOS_PATH}/example/tutorial/Hierarchical_Parallelism/01_thread_teams/Makefile ${KOKKOS_SETTINGS} + $(MAKE) clean -f ${KOKKOS_PATH}/example/tutorial/Hierarchical_Parallelism/01_thread_teams/Makefile ${KOKKOS_SETTINGS} cd ./01_thread_teams_lambda; \ - make clean -f ${KOKKOS_PATH}/example/tutorial/Hierarchical_Parallelism/01_thread_teams_lambda/Makefile ${KOKKOS_SETTINGS} + $(MAKE) clean -f ${KOKKOS_PATH}/example/tutorial/Hierarchical_Parallelism/01_thread_teams_lambda/Makefile ${KOKKOS_SETTINGS} cd ./02_nested_parallel_for; \ - make clean -f ${KOKKOS_PATH}/example/tutorial/Hierarchical_Parallelism/02_nested_parallel_for/Makefile ${KOKKOS_SETTINGS} + $(MAKE) clean -f ${KOKKOS_PATH}/example/tutorial/Hierarchical_Parallelism/02_nested_parallel_for/Makefile ${KOKKOS_SETTINGS} cd ./03_vectorization; \ - make clean -f ${KOKKOS_PATH}/example/tutorial/Hierarchical_Parallelism/03_vectorization/Makefile ${KOKKOS_SETTINGS} + $(MAKE) clean -f ${KOKKOS_PATH}/example/tutorial/Hierarchical_Parallelism/03_vectorization/Makefile ${KOKKOS_SETTINGS} cd ./04_team_scan; \ - make clean -f ${KOKKOS_PATH}/example/tutorial/Hierarchical_Parallelism/04_team_scan/Makefile ${KOKKOS_SETTINGS} + $(MAKE) clean -f ${KOKKOS_PATH}/example/tutorial/Hierarchical_Parallelism/04_team_scan/Makefile ${KOKKOS_SETTINGS} clean-insource: cd ./01_thread_teams; \ - make clean ${KOKKOS_SETTINGS} + $(MAKE) clean ${KOKKOS_SETTINGS} cd ./01_thread_teams_lambda; \ - make clean ${KOKKOS_SETTINGS} + $(MAKE) clean ${KOKKOS_SETTINGS} cd ./02_nested_parallel_for; \ - make clean ${KOKKOS_SETTINGS} + $(MAKE) clean ${KOKKOS_SETTINGS} cd ./03_vectorization; \ - make clean ${KOKKOS_SETTINGS} + $(MAKE) clean ${KOKKOS_SETTINGS} cd ./04_team_scan; \ - make clean ${KOKKOS_SETTINGS} + $(MAKE) clean ${KOKKOS_SETTINGS} diff --git a/lib/kokkos/example/tutorial/Makefile b/lib/kokkos/example/tutorial/Makefile index 063ace8aab..7b2732eeed 100644 --- a/lib/kokkos/example/tutorial/Makefile +++ b/lib/kokkos/example/tutorial/Makefile @@ -23,152 +23,152 @@ endif build: mkdir -p 01_hello_world cd ./01_hello_world; \ - make build -j 4 -f ${KOKKOS_PATH}/example/tutorial/01_hello_world/Makefile ${KOKKOS_SETTINGS} + $(MAKE) build -f ${KOKKOS_PATH}/example/tutorial/01_hello_world/Makefile ${KOKKOS_SETTINGS} mkdir -p 01_hello_world_lambda cd ./01_hello_world_lambda; \ - make build -j 4 -f ${KOKKOS_PATH}/example/tutorial/01_hello_world_lambda/Makefile ${KOKKOS_SETTINGS} + $(MAKE) build -f ${KOKKOS_PATH}/example/tutorial/01_hello_world_lambda/Makefile ${KOKKOS_SETTINGS} mkdir -p 02_simple_reduce cd ./02_simple_reduce; \ - make build -j 4 -f ${KOKKOS_PATH}/example/tutorial/02_simple_reduce/Makefile ${KOKKOS_SETTINGS} + $(MAKE) build -f ${KOKKOS_PATH}/example/tutorial/02_simple_reduce/Makefile ${KOKKOS_SETTINGS} mkdir -p 02_simple_reduce_lambda cd ./02_simple_reduce_lambda; \ - make build -j 4 -f ${KOKKOS_PATH}/example/tutorial/02_simple_reduce_lambda/Makefile ${KOKKOS_SETTINGS} + $(MAKE) build -f ${KOKKOS_PATH}/example/tutorial/02_simple_reduce_lambda/Makefile ${KOKKOS_SETTINGS} mkdir -p 03_simple_view cd ./03_simple_view; \ - make build -j 4 -f ${KOKKOS_PATH}/example/tutorial/03_simple_view/Makefile ${KOKKOS_SETTINGS} + $(MAKE) build -f ${KOKKOS_PATH}/example/tutorial/03_simple_view/Makefile ${KOKKOS_SETTINGS} mkdir -p 03_simple_view_lambda cd ./03_simple_view_lambda; \ - make build -j 4 -f ${KOKKOS_PATH}/example/tutorial/03_simple_view_lambda/Makefile ${KOKKOS_SETTINGS} + $(MAKE) build -f ${KOKKOS_PATH}/example/tutorial/03_simple_view_lambda/Makefile ${KOKKOS_SETTINGS} mkdir -p 04_simple_memoryspaces cd ./04_simple_memoryspaces; \ - make build -j 4 -f ${KOKKOS_PATH}/example/tutorial/04_simple_memoryspaces/Makefile ${KOKKOS_SETTINGS} + $(MAKE) build -f ${KOKKOS_PATH}/example/tutorial/04_simple_memoryspaces/Makefile ${KOKKOS_SETTINGS} mkdir -p 05_simple_atomics cd ./05_simple_atomics; \ - make build -j 4 -f ${KOKKOS_PATH}/example/tutorial/05_simple_atomics/Makefile ${KOKKOS_SETTINGS} + $(MAKE) build -f ${KOKKOS_PATH}/example/tutorial/05_simple_atomics/Makefile ${KOKKOS_SETTINGS} mkdir -p Advanced_Views cd ./Advanced_Views; \ - make build -f ${KOKKOS_PATH}/example/tutorial/Advanced_Views/Makefile KOKKOS_SETTINGS='${KOKKOS_SETTINGS}' + $(MAKE) build -f ${KOKKOS_PATH}/example/tutorial/Advanced_Views/Makefile KOKKOS_SETTINGS='${KOKKOS_SETTINGS}' mkdir -p Algorithms cd ./Algorithms; \ - make build -f ${KOKKOS_PATH}/example/tutorial/Algorithms/Makefile KOKKOS_SETTINGS='${KOKKOS_SETTINGS}' + $(MAKE) build -f ${KOKKOS_PATH}/example/tutorial/Algorithms/Makefile KOKKOS_SETTINGS='${KOKKOS_SETTINGS}' mkdir -p Hierarchical_Parallelism cd ./Hierarchical_Parallelism; \ - make build -f ${KOKKOS_PATH}/example/tutorial/Hierarchical_Parallelism/Makefile KOKKOS_SETTINGS='${KOKKOS_SETTINGS}' + $(MAKE) build -f ${KOKKOS_PATH}/example/tutorial/Hierarchical_Parallelism/Makefile KOKKOS_SETTINGS='${KOKKOS_SETTINGS}' build-insource: cd ./01_hello_world; \ - make build -j 4 ${KOKKOS_SETTINGS} + $(MAKE) build ${KOKKOS_SETTINGS} cd ./01_hello_world_lambda; \ - make build -j 4 ${KOKKOS_SETTINGS} + $(MAKE) build ${KOKKOS_SETTINGS} cd ./02_simple_reduce; \ - make build -j 4 ${KOKKOS_SETTINGS} + $(MAKE) build ${KOKKOS_SETTINGS} cd ./02_simple_reduce_lambda; \ - make build -j 4 ${KOKKOS_SETTINGS} + $(MAKE) build ${KOKKOS_SETTINGS} cd ./03_simple_view; \ - make build -j 4 ${KOKKOS_SETTINGS} + $(MAKE) build ${KOKKOS_SETTINGS} cd ./03_simple_view_lambda; \ - make build -j 4 ${KOKKOS_SETTINGS} + $(MAKE) build ${KOKKOS_SETTINGS} cd ./04_simple_memoryspaces; \ - make build -j 4 ${KOKKOS_SETTINGS} + $(MAKE) build ${KOKKOS_SETTINGS} cd ./05_simple_atomics; \ - make build -j 4 ${KOKKOS_SETTINGS} + $(MAKE) build ${KOKKOS_SETTINGS} cd ./Advanced_Views; \ - make build KOKKOS_SETTINGS='${KOKKOS_SETTINGS}' + $(MAKE) build KOKKOS_SETTINGS='${KOKKOS_SETTINGS}' cd ./Algorithms; \ - make build KOKKOS_SETTINGS='${KOKKOS_SETTINGS}' + $(MAKE) build KOKKOS_SETTINGS='${KOKKOS_SETTINGS}' cd ./Hierarchical_Parallelism; \ - make build KOKKOS_SETTINGS='${KOKKOS_SETTINGS}' + $(MAKE) build KOKKOS_SETTINGS='${KOKKOS_SETTINGS}' test: cd ./01_hello_world; \ - make test -j 4 -f ${KOKKOS_PATH}/example/tutorial/01_hello_world/Makefile ${KOKKOS_SETTINGS} + $(MAKE) test -f ${KOKKOS_PATH}/example/tutorial/01_hello_world/Makefile ${KOKKOS_SETTINGS} cd ./01_hello_world_lambda; \ - make test -j 4 -f ${KOKKOS_PATH}/example/tutorial/01_hello_world_lambda/Makefile ${KOKKOS_SETTINGS} + $(MAKE) test -f ${KOKKOS_PATH}/example/tutorial/01_hello_world_lambda/Makefile ${KOKKOS_SETTINGS} cd ./02_simple_reduce; \ - make test -j 4 -f ${KOKKOS_PATH}/example/tutorial/02_simple_reduce/Makefile ${KOKKOS_SETTINGS} + $(MAKE) test -f ${KOKKOS_PATH}/example/tutorial/02_simple_reduce/Makefile ${KOKKOS_SETTINGS} cd ./02_simple_reduce_lambda; \ - make test -j 4 -f ${KOKKOS_PATH}/example/tutorial/02_simple_reduce_lambda/Makefile ${KOKKOS_SETTINGS} + $(MAKE) test -f ${KOKKOS_PATH}/example/tutorial/02_simple_reduce_lambda/Makefile ${KOKKOS_SETTINGS} cd ./03_simple_view; \ - make test -j 4 -f ${KOKKOS_PATH}/example/tutorial/03_simple_view/Makefile ${KOKKOS_SETTINGS} + $(MAKE) test -f ${KOKKOS_PATH}/example/tutorial/03_simple_view/Makefile ${KOKKOS_SETTINGS} cd ./03_simple_view_lambda; \ - make test -j 4 -f ${KOKKOS_PATH}/example/tutorial/03_simple_view_lambda/Makefile ${KOKKOS_SETTINGS} + $(MAKE) test -f ${KOKKOS_PATH}/example/tutorial/03_simple_view_lambda/Makefile ${KOKKOS_SETTINGS} cd ./04_simple_memoryspaces; \ - make test -j 4 -f ${KOKKOS_PATH}/example/tutorial/04_simple_memoryspaces/Makefile ${KOKKOS_SETTINGS} + $(MAKE) test -f ${KOKKOS_PATH}/example/tutorial/04_simple_memoryspaces/Makefile ${KOKKOS_SETTINGS} cd ./05_simple_atomics; \ - make test -j 4 -f ${KOKKOS_PATH}/example/tutorial/05_simple_atomics/Makefile ${KOKKOS_SETTINGS} + $(MAKE) test -f ${KOKKOS_PATH}/example/tutorial/05_simple_atomics/Makefile ${KOKKOS_SETTINGS} cd ./Advanced_Views; \ - make test -f ${KOKKOS_PATH}/example/tutorial/Advanced_Views/Makefile KOKKOS_SETTINGS='${KOKKOS_SETTINGS}' + $(MAKE) test -f ${KOKKOS_PATH}/example/tutorial/Advanced_Views/Makefile KOKKOS_SETTINGS='${KOKKOS_SETTINGS}' cd ./Algorithms; \ - make test -f ${KOKKOS_PATH}/example/tutorial/Algorithms/Makefile KOKKOS_SETTINGS='${KOKKOS_SETTINGS}' + $(MAKE) test -f ${KOKKOS_PATH}/example/tutorial/Algorithms/Makefile KOKKOS_SETTINGS='${KOKKOS_SETTINGS}' cd ./Hierarchical_Parallelism; \ - make test -f ${KOKKOS_PATH}/example/tutorial/Hierarchical_Parallelism/Makefile KOKKOS_SETTINGS='${KOKKOS_SETTINGS}' + $(MAKE) test -f ${KOKKOS_PATH}/example/tutorial/Hierarchical_Parallelism/Makefile KOKKOS_SETTINGS='${KOKKOS_SETTINGS}' test-insource: cd ./01_hello_world; \ - make test -j 4 ${KOKKOS_SETTINGS} + $(MAKE) test ${KOKKOS_SETTINGS} cd ./01_hello_world_lambda; \ - make test -j 4 ${KOKKOS_SETTINGS} + $(MAKE) test ${KOKKOS_SETTINGS} cd ./02_simple_reduce; \ - make test -j 4 ${KOKKOS_SETTINGS} + $(MAKE) test ${KOKKOS_SETTINGS} cd ./02_simple_reduce_lambda; \ - make test -j 4 ${KOKKOS_SETTINGS} + $(MAKE) test ${KOKKOS_SETTINGS} cd ./03_simple_view; \ - make test -j 4 ${KOKKOS_SETTINGS} + $(MAKE) test ${KOKKOS_SETTINGS} cd ./03_simple_view_lambda; \ - make test -j 4 ${KOKKOS_SETTINGS} + $(MAKE) test ${KOKKOS_SETTINGS} cd ./04_simple_memoryspaces; \ - make test -j 4 ${KOKKOS_SETTINGS} + $(MAKE) test ${KOKKOS_SETTINGS} cd ./05_simple_atomics; \ - make test -j 4 ${KOKKOS_SETTINGS} + $(MAKE) test ${KOKKOS_SETTINGS} cd ./Advanced_Views; \ - make test KOKKOS_SETTINGS='${KOKKOS_SETTINGS}' + $(MAKE) test KOKKOS_SETTINGS='${KOKKOS_SETTINGS}' cd ./Algorithms; \ - make test KOKKOS_SETTINGS='${KOKKOS_SETTINGS}' + $(MAKE) test KOKKOS_SETTINGS='${KOKKOS_SETTINGS}' cd ./Hierarchical_Parallelism; \ - make test KOKKOS_SETTINGS='${KOKKOS_SETTINGS}' + $(MAKE) test KOKKOS_SETTINGS='${KOKKOS_SETTINGS}' clean: cd ./01_hello_world; \ - make clean -f ${KOKKOS_PATH}/example/tutorial/01_hello_world/Makefile ${KOKKOS_SETTINGS} + $(MAKE) clean -f ${KOKKOS_PATH}/example/tutorial/01_hello_world/Makefile ${KOKKOS_SETTINGS} cd ./01_hello_world_lambda; \ - make clean -f ${KOKKOS_PATH}/example/tutorial/01_hello_world_lambda/Makefile ${KOKKOS_SETTINGS} + $(MAKE) clean -f ${KOKKOS_PATH}/example/tutorial/01_hello_world_lambda/Makefile ${KOKKOS_SETTINGS} cd ./02_simple_reduce; \ - make clean -f ${KOKKOS_PATH}/example/tutorial/02_simple_reduce/Makefile ${KOKKOS_SETTINGS} + $(MAKE) clean -f ${KOKKOS_PATH}/example/tutorial/02_simple_reduce/Makefile ${KOKKOS_SETTINGS} cd ./02_simple_reduce_lambda; \ - make clean -f ${KOKKOS_PATH}/example/tutorial/02_simple_reduce_lambda/Makefile ${KOKKOS_SETTINGS} + $(MAKE) clean -f ${KOKKOS_PATH}/example/tutorial/02_simple_reduce_lambda/Makefile ${KOKKOS_SETTINGS} cd ./03_simple_view; \ - make clean -f ${KOKKOS_PATH}/example/tutorial/03_simple_view/Makefile ${KOKKOS_SETTINGS} + $(MAKE) clean -f ${KOKKOS_PATH}/example/tutorial/03_simple_view/Makefile ${KOKKOS_SETTINGS} cd ./03_simple_view_lambda; \ - make clean -f ${KOKKOS_PATH}/example/tutorial/03_simple_view_lambda/Makefile ${KOKKOS_SETTINGS} + $(MAKE) clean -f ${KOKKOS_PATH}/example/tutorial/03_simple_view_lambda/Makefile ${KOKKOS_SETTINGS} cd ./04_simple_memoryspaces; \ - make clean -f ${KOKKOS_PATH}/example/tutorial/04_simple_memoryspaces/Makefile ${KOKKOS_SETTINGS} + $(MAKE) clean -f ${KOKKOS_PATH}/example/tutorial/04_simple_memoryspaces/Makefile ${KOKKOS_SETTINGS} cd ./05_simple_atomics; \ - make clean -f ${KOKKOS_PATH}/example/tutorial/05_simple_atomics/Makefile ${KOKKOS_SETTINGS} + $(MAKE) clean -f ${KOKKOS_PATH}/example/tutorial/05_simple_atomics/Makefile ${KOKKOS_SETTINGS} cd ./Advanced_Views; \ - make clean -f ${KOKKOS_PATH}/example/tutorial/Advanced_Views/Makefile KOKKOS_SETTINGS='${KOKKOS_SETTINGS}' + $(MAKE) clean -f ${KOKKOS_PATH}/example/tutorial/Advanced_Views/Makefile KOKKOS_SETTINGS='${KOKKOS_SETTINGS}' cd ./Algorithms; \ - make clean -f ${KOKKOS_PATH}/example/tutorial/Algorithms/Makefile KOKKOS_SETTINGS='${KOKKOS_SETTINGS}' + $(MAKE) clean -f ${KOKKOS_PATH}/example/tutorial/Algorithms/Makefile KOKKOS_SETTINGS='${KOKKOS_SETTINGS}' cd ./Hierarchical_Parallelism; \ - make clean -f ${KOKKOS_PATH}/example/tutorial/Hierarchical_Parallelism/Makefile KOKKOS_SETTINGS='${KOKKOS_SETTINGS}' + $(MAKE) clean -f ${KOKKOS_PATH}/example/tutorial/Hierarchical_Parallelism/Makefile KOKKOS_SETTINGS='${KOKKOS_SETTINGS}' clean-insource: cd ./01_hello_world; \ - make clean ${KOKKOS_SETTINGS} + $(MAKE) clean ${KOKKOS_SETTINGS} cd ./01_hello_world_lambda; \ - make clean ${KOKKOS_SETTINGS} + $(MAKE) clean ${KOKKOS_SETTINGS} cd ./02_simple_reduce; \ - make clean ${KOKKOS_SETTINGS} + $(MAKE) clean ${KOKKOS_SETTINGS} cd ./02_simple_reduce_lambda; \ - make clean ${KOKKOS_SETTINGS} + $(MAKE) clean ${KOKKOS_SETTINGS} cd ./03_simple_view; \ - make clean ${KOKKOS_SETTINGS} + $(MAKE) clean ${KOKKOS_SETTINGS} cd ./03_simple_view_lambda; \ - make clean ${KOKKOS_SETTINGS} + $(MAKE) clean ${KOKKOS_SETTINGS} cd ./04_simple_memoryspaces; \ - make clean ${KOKKOS_SETTINGS} + $(MAKE) clean ${KOKKOS_SETTINGS} cd ./05_simple_atomics; \ - make clean ${KOKKOS_SETTINGS} + $(MAKE) clean ${KOKKOS_SETTINGS} cd ./Advanced_Views; \ - make clean KOKKOS_SETTINGS='${KOKKOS_SETTINGS}' + $(MAKE) clean KOKKOS_SETTINGS='${KOKKOS_SETTINGS}' cd ./Algorithms; \ - make clean KOKKOS_SETTINGS='${KOKKOS_SETTINGS}' + $(MAKE) clean KOKKOS_SETTINGS='${KOKKOS_SETTINGS}' cd ./Hierarchical_Parallelism; \ - make clean KOKKOS_SETTINGS='${KOKKOS_SETTINGS}' + $(MAKE) clean KOKKOS_SETTINGS='${KOKKOS_SETTINGS}' diff --git a/lib/kokkos/example/tutorial/launch_bounds/CMakeLists.txt b/lib/kokkos/example/tutorial/launch_bounds/CMakeLists.txt new file mode 100644 index 0000000000..7c78db840f --- /dev/null +++ b/lib/kokkos/example/tutorial/launch_bounds/CMakeLists.txt @@ -0,0 +1,10 @@ + +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}) +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) + +# This is a tutorial, not a test, so we don't ask CTest to run it. +TRIBITS_ADD_EXECUTABLE( + tutorial_02_simple_reduce + SOURCES simple_reduce.cpp + COMM serial mpi + ) diff --git a/lib/kokkos/example/tutorial/launch_bounds/Makefile b/lib/kokkos/example/tutorial/launch_bounds/Makefile new file mode 100644 index 0000000000..5b605a4119 --- /dev/null +++ b/lib/kokkos/example/tutorial/launch_bounds/Makefile @@ -0,0 +1,56 @@ +KOKKOS_PATH = ../../.. +KOKKOS_SRC_PATH = ${KOKKOS_PATH} +SRC = $(wildcard ${KOKKOS_SRC_PATH}/example/tutorial/launch_bounds/*.cpp) +vpath %.cpp $(sort $(dir $(SRC))) + +default: build + echo "Start Build" + +ifneq (,$(findstring Cuda,$(KOKKOS_DEVICES))) +CXX = ${KOKKOS_PATH}/bin/nvcc_wrapper +CXXFLAGS = -O3 +LINK = ${CXX} +LINKFLAGS = +EXE = launch_bounds.cuda +KOKKOS_DEVICES = "Cuda,OpenMP" +KOKKOS_ARCH = "SNB,Kepler35" +else +CXX = g++ +CXXFLAGS = -O3 +LINK = ${CXX} +LINKFLAGS = +EXE = launch_bounds.host +KOKKOS_DEVICES = "OpenMP" +KOKKOS_ARCH = "SNB" +endif + +# WAR for "undefined memcpy" w/ Ubuntu + CUDA 7.5 +CXXFLAGS += -D_FORCE_INLINES +# Additional compile-time information +CXXFLAGS += -Xptxas=-v + +DEPFLAGS = -M + +OBJ = $(notdir $(SRC:.cpp=.o)) +LIB = + +include $(KOKKOS_PATH)/Makefile.kokkos + +temp: + echo $(KOKKOS_INTERNAL_USE_CUDA) $(CUDA_PATH) + +build: $(EXE) + +test: $(EXE) + ./$(EXE) + +$(EXE): $(OBJ) $(KOKKOS_LINK_DEPENDS) + $(LINK) $(KOKKOS_LDFLAGS) $(LINKFLAGS) $(EXTRA_PATH) $(OBJ) $(KOKKOS_LIBS) $(LIB) -o $(EXE) + +clean: kokkos-clean + rm -f *.o *.cuda *.host + +# Compilation rules + +%.o:%.cpp $(KOKKOS_CPP_DEPENDS) + $(CXX) $(KOKKOS_CPPFLAGS) $(KOKKOS_CXXFLAGS) $(CXXFLAGS) $(EXTRA_INC) -c $< -o $(notdir $@) diff --git a/lib/kokkos/example/tutorial/launch_bounds/launch_bounds_reduce.cpp b/lib/kokkos/example/tutorial/launch_bounds/launch_bounds_reduce.cpp new file mode 100644 index 0000000000..9a26eda507 --- /dev/null +++ b/lib/kokkos/example/tutorial/launch_bounds/launch_bounds_reduce.cpp @@ -0,0 +1,173 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include +#include + +// +// First reduction (parallel_reduce) example: +// 1. Start up Kokkos +// 2. Execute a parallel_reduce loop in the default execution space, +// using a functor to define the loop body +// 3. Shut down Kokkos +// +struct collision { +// Reduction functor +// For each i, we generate 10 hashes, look for and count collisions +// We use parallel_reduce to count the total collisions +// Note that we're just counting collisions within the 10 generated +// one i. +// This function was chosen as one that very simply can increase the +// register count. + typedef int value_type; + + KOKKOS_INLINE_FUNCTION + int hash(int q) const { + // A simple hash by Justin Sobel + // Thanks to Arash Partow (partow.net) + char* fourchars = (char*)&q; + int hash = 1315423911; + for (int i=0; i<4; fourchars++, i++) { + hash ^= ((hash<<5) + *fourchars + (hash >> 2)); + } + return hash; + } + + KOKKOS_INLINE_FUNCTION + void operator () (const int i, int& lsum) const { + //This is a silly function which generates 10 hashes + // then checks for collisions + int a = hash(i)%64; + int b = hash(i*3)%64; + int c = hash(i*5)%64; + int d = hash(i*7)%64; + int e = hash(i*11)%64; + int f = hash(i*17)%64; + int g = hash(i*23)%64; + int h = hash(i*29)%64; + int j = hash(i*31)%64; + int k = hash(i*37)%64; + + + if (a==b) lsum++; + if (a==c) lsum++; + if (a==d) lsum++; + if (a==e) lsum++; + if (a==f) lsum++; + if (a==g) lsum++; + if (a==h) lsum++; + if (a==j) lsum++; + if (a==k) lsum++; + if (b==c) lsum++; + if (b==d) lsum++; + if (b==e) lsum++; + if (b==f) lsum++; + if (b==g) lsum++; + if (b==h) lsum++; + if (b==j) lsum++; + if (b==k) lsum++; + if (c==d) lsum++; + if (c==e) lsum++; + if (c==f) lsum++; + if (c==g) lsum++; + if (c==h) lsum++; + if (c==j) lsum++; + if (c==k) lsum++; + if (d==e) lsum++; + if (d==f) lsum++; + if (d==g) lsum++; + if (d==h) lsum++; + if (d==j) lsum++; + if (d==k) lsum++; + if (e==f) lsum++; + if (e==g) lsum++; + if (e==h) lsum++; + if (e==j) lsum++; + if (e==k) lsum++; + if (f==g) lsum++; + if (f==h) lsum++; + if (f==j) lsum++; + if (f==k) lsum++; + if (g==h) lsum++; + if (g==j) lsum++; + if (g==k) lsum++; + if (h==j) lsum++; + if (h==k) lsum++; + if (j==k) lsum++; + } + + + +}; + +int main (int argc, char* argv[]) { + Kokkos::initialize (argc, argv); + const int n = 10000; + + // Compute and count hash collisions in + // parallel, using Kokkos. + // This is not really a useful algorithm, but it demonstrates the + // LaunchBounds functionality + int sum1 = 0; + int sum2 = 0; + + //Without LaunchBounds, the kernel uses 56 registers + Kokkos::parallel_reduce (n, collision (), sum1); + + //With LaunchBounds, we can reduce the register usage to 32 + Kokkos::parallel_reduce (Kokkos::RangePolicy>(0,n), collision (), sum2); + + printf ("Number of collisions, " + "computed in parallel, is %i\n", sum1); + + if (sum1 != sum2) { + printf( "Uh-oh! Results do not match\n"); + return -1; + } + + Kokkos::finalize(); + + + return 0; +} + diff --git a/lib/kokkos/generate_makefile.bash b/lib/kokkos/generate_makefile.bash index 5f2442102d..6d636dc7e4 100755 --- a/lib/kokkos/generate_makefile.bash +++ b/lib/kokkos/generate_makefile.bash @@ -1,7 +1,6 @@ #!/bin/bash KOKKOS_DEVICES="" -MAKE_J_OPTION="32" KOKKOS_DO_EXAMPLES="1" @@ -70,7 +69,8 @@ do KOKKOS_DEBUG=yes ;; --make-j*) - MAKE_J_OPTION="${key#*=}" + echo "Warning: ${key} is deprecated" + echo "Call make with appropriate -j flag" ;; --no-examples) KOKKOS_DO_EXAMPLES="0" @@ -110,23 +110,34 @@ do echo "--with-devices: Explicitly add a set of backends." echo "" echo "--arch=[OPT]: Set target architectures. Options are:" + echo " [AMD]" + echo " AMDAVX = AMD CPU" + echo " [ARM]" echo " ARMv80 = ARMv8.0 Compatible CPU" echo " ARMv81 = ARMv8.1 Compatible CPU" echo " ARMv8-ThunderX = ARMv8 Cavium ThunderX CPU" + echo " [IBM]" + echo " Power8 = IBM POWER8 CPUs" + echo " Power9 = IBM POWER9 CPUs" + echo " [Intel]" + echo " WSM = Intel Westmere CPUs" echo " SNB = Intel Sandy/Ivy Bridge CPUs" echo " HSW = Intel Haswell CPUs" echo " BDW = Intel Broadwell Xeon E-class CPUs" echo " SKX = Intel Sky Lake Xeon E-class HPC CPUs (AVX512)" + echo " [Intel Xeon Phi]" echo " KNC = Intel Knights Corner Xeon Phi" echo " KNL = Intel Knights Landing Xeon Phi" + echo " [NVIDIA]" echo " Kepler30 = NVIDIA Kepler generation CC 3.0" + echo " Kepler32 = NVIDIA Kepler generation CC 3.2" echo " Kepler35 = NVIDIA Kepler generation CC 3.5" echo " Kepler37 = NVIDIA Kepler generation CC 3.7" + echo " Maxwell50 = NVIDIA Maxwell generation CC 5.0" + echo " Maxwell52 = NVIDIA Maxwell generation CC 5.2" + echo " Maxwell53 = NVIDIA Maxwell generation CC 5.3" echo " Pascal60 = NVIDIA Pascal generation CC 6.0" echo " Pascal61 = NVIDIA Pascal generation CC 6.1" - echo " Maxwell50 = NVIDIA Maxwell generation CC 5.0" - echo " Power8 = IBM POWER8 CPUs" - echo " Power9 = IBM POWER9 CPUs" echo "" echo "--compiler=/Path/To/Compiler Set the compiler." echo "--debug,-dbg: Enable Debugging." @@ -142,10 +153,14 @@ do echo " tests.)" echo "--with-hwloc=/Path/To/Hwloc: Set path to hwloc." echo "--with-options=[OPT]: Additional options to Kokkos:" + echo " compiler_warnings" echo " aggressive_vectorization = add ivdep on loops" + echo " disable_profiling = do not compile with profiling hooks" + echo " " echo "--with-cuda-options=[OPT]: Additional options to CUDA:" echo " force_uvm, use_ldg, enable_lambda, rdc" - echo "--make-j=[NUM]: Set -j flag used during build." + echo "--make-j=[NUM]: DEPRECATED: call make with appropriate" + echo " -j flag" exit 0 ;; *) @@ -237,27 +252,27 @@ else KOKKOS_INSTALL_PATH=${KOKKOS_TEST_INSTALL_PATH} fi -mkdir install +mkdir -p install echo "#Makefile to satisfy existens of target kokkos-clean before installing the library" > install/Makefile.kokkos echo "kokkos-clean:" >> install/Makefile.kokkos echo "" >> install/Makefile.kokkos -mkdir core -mkdir core/unit_test -mkdir core/perf_test -mkdir containers -mkdir containers/unit_tests -mkdir containers/performance_tests -mkdir algorithms -mkdir algorithms/unit_tests -mkdir algorithms/performance_tests -mkdir example -mkdir example/fixture -mkdir example/feint -mkdir example/fenl -mkdir example/tutorial +mkdir -p core +mkdir -p core/unit_test +mkdir -p core/perf_test +mkdir -p containers +mkdir -p containers/unit_tests +mkdir -p containers/performance_tests +mkdir -p algorithms +mkdir -p algorithms/unit_tests +mkdir -p algorithms/performance_tests +mkdir -p example +mkdir -p example/fixture +mkdir -p example/feint +mkdir -p example/fenl +mkdir -p example/tutorial if [ ${#KOKKOS_ENABLE_EXAMPLE_ICHOL} -gt 0 ]; then - mkdir example/ichol + mkdir -p example/ichol fi KOKKOS_SETTINGS="${KOKKOS_SETTINGS_NO_KOKKOS_PATH} KOKKOS_PATH=${KOKKOS_PATH}" @@ -266,115 +281,115 @@ KOKKOS_SETTINGS="${KOKKOS_SETTINGS_NO_KOKKOS_PATH} KOKKOS_PATH=${KOKKOS_PATH}" echo "KOKKOS_SETTINGS=${KOKKOS_SETTINGS}" > core/unit_test/Makefile echo "" >> core/unit_test/Makefile echo "all:" >> core/unit_test/Makefile -echo -e "\tmake -j ${MAKE_J_OPTION} -f ${KOKKOS_PATH}/core/unit_test/Makefile ${KOKKOS_SETTINGS}" >> core/unit_test/Makefile +echo -e "\t\$(MAKE) -f ${KOKKOS_PATH}/core/unit_test/Makefile ${KOKKOS_SETTINGS}" >> core/unit_test/Makefile echo "" >> core/unit_test/Makefile echo "test: all" >> core/unit_test/Makefile -echo -e "\tmake -f ${KOKKOS_PATH}/core/unit_test/Makefile ${KOKKOS_SETTINGS} test" >> core/unit_test/Makefile +echo -e "\t\$(MAKE) -f ${KOKKOS_PATH}/core/unit_test/Makefile ${KOKKOS_SETTINGS} test" >> core/unit_test/Makefile echo "" >> core/unit_test/Makefile echo "clean:" >> core/unit_test/Makefile -echo -e "\tmake -f ${KOKKOS_PATH}/core/unit_test/Makefile ${KOKKOS_SETTINGS} clean" >> core/unit_test/Makefile +echo -e "\t\$(MAKE) -f ${KOKKOS_PATH}/core/unit_test/Makefile ${KOKKOS_SETTINGS} clean" >> core/unit_test/Makefile echo "KOKKOS_SETTINGS=${KOKKOS_SETTINGS}" > core/perf_test/Makefile echo "" >> core/perf_test/Makefile echo "all:" >> core/perf_test/Makefile -echo -e "\tmake -j ${MAKE_J_OPTION} -f ${KOKKOS_PATH}/core/perf_test/Makefile ${KOKKOS_SETTINGS}" >> core/perf_test/Makefile +echo -e "\t\$(MAKE) -f ${KOKKOS_PATH}/core/perf_test/Makefile ${KOKKOS_SETTINGS}" >> core/perf_test/Makefile echo "" >> core/perf_test/Makefile echo "test: all" >> core/perf_test/Makefile -echo -e "\tmake -f ${KOKKOS_PATH}/core/perf_test/Makefile ${KOKKOS_SETTINGS} test" >> core/perf_test/Makefile +echo -e "\t\$(MAKE) -f ${KOKKOS_PATH}/core/perf_test/Makefile ${KOKKOS_SETTINGS} test" >> core/perf_test/Makefile echo "" >> core/perf_test/Makefile echo "clean:" >> core/perf_test/Makefile -echo -e "\tmake -f ${KOKKOS_PATH}/core/perf_test/Makefile ${KOKKOS_SETTINGS} clean" >> core/perf_test/Makefile +echo -e "\t\$(MAKE) -f ${KOKKOS_PATH}/core/perf_test/Makefile ${KOKKOS_SETTINGS} clean" >> core/perf_test/Makefile echo "KOKKOS_SETTINGS=${KOKKOS_SETTINGS}" > containers/unit_tests/Makefile echo "" >> containers/unit_tests/Makefile echo "all:" >> containers/unit_tests/Makefile -echo -e "\tmake -j ${MAKE_J_OPTION} -f ${KOKKOS_PATH}/containers/unit_tests/Makefile ${KOKKOS_SETTINGS}" >> containers/unit_tests/Makefile +echo -e "\t\$(MAKE) -f ${KOKKOS_PATH}/containers/unit_tests/Makefile ${KOKKOS_SETTINGS}" >> containers/unit_tests/Makefile echo "" >> containers/unit_tests/Makefile echo "test: all" >> containers/unit_tests/Makefile -echo -e "\tmake -f ${KOKKOS_PATH}/containers/unit_tests/Makefile ${KOKKOS_SETTINGS} test" >> containers/unit_tests/Makefile +echo -e "\t\$(MAKE) -f ${KOKKOS_PATH}/containers/unit_tests/Makefile ${KOKKOS_SETTINGS} test" >> containers/unit_tests/Makefile echo "" >> containers/unit_tests/Makefile echo "clean:" >> containers/unit_tests/Makefile -echo -e "\tmake -f ${KOKKOS_PATH}/containers/unit_tests/Makefile ${KOKKOS_SETTINGS} clean" >> containers/unit_tests/Makefile +echo -e "\t\$(MAKE) -f ${KOKKOS_PATH}/containers/unit_tests/Makefile ${KOKKOS_SETTINGS} clean" >> containers/unit_tests/Makefile echo "KOKKOS_SETTINGS=${KOKKOS_SETTINGS}" > containers/performance_tests/Makefile echo "" >> containers/performance_tests/Makefile echo "all:" >> containers/performance_tests/Makefile -echo -e "\tmake -j ${MAKE_J_OPTION} -f ${KOKKOS_PATH}/containers/performance_tests/Makefile ${KOKKOS_SETTINGS}" >> containers/performance_tests/Makefile +echo -e "\t\$(MAKE) -f ${KOKKOS_PATH}/containers/performance_tests/Makefile ${KOKKOS_SETTINGS}" >> containers/performance_tests/Makefile echo "" >> containers/performance_tests/Makefile echo "test: all" >> containers/performance_tests/Makefile -echo -e "\tmake -f ${KOKKOS_PATH}/containers/performance_tests/Makefile ${KOKKOS_SETTINGS} test" >> containers/performance_tests/Makefile +echo -e "\t\$(MAKE) -f ${KOKKOS_PATH}/containers/performance_tests/Makefile ${KOKKOS_SETTINGS} test" >> containers/performance_tests/Makefile echo "" >> containers/performance_tests/Makefile echo "clean:" >> containers/performance_tests/Makefile -echo -e "\tmake -f ${KOKKOS_PATH}/containers/performance_tests/Makefile ${KOKKOS_SETTINGS} clean" >> containers/performance_tests/Makefile +echo -e "\t\$(MAKE) -f ${KOKKOS_PATH}/containers/performance_tests/Makefile ${KOKKOS_SETTINGS} clean" >> containers/performance_tests/Makefile echo "KOKKOS_SETTINGS=${KOKKOS_SETTINGS}" > algorithms/unit_tests/Makefile echo "" >> algorithms/unit_tests/Makefile echo "all:" >> algorithms/unit_tests/Makefile -echo -e "\tmake -j ${MAKE_J_OPTION} -f ${KOKKOS_PATH}/algorithms/unit_tests/Makefile ${KOKKOS_SETTINGS}" >> algorithms/unit_tests/Makefile +echo -e "\t\$(MAKE) -f ${KOKKOS_PATH}/algorithms/unit_tests/Makefile ${KOKKOS_SETTINGS}" >> algorithms/unit_tests/Makefile echo "" >> algorithms/unit_tests/Makefile echo "test: all" >> algorithms/unit_tests/Makefile -echo -e "\tmake -f ${KOKKOS_PATH}/algorithms/unit_tests/Makefile ${KOKKOS_SETTINGS} test" >> algorithms/unit_tests/Makefile +echo -e "\t\$(MAKE) -f ${KOKKOS_PATH}/algorithms/unit_tests/Makefile ${KOKKOS_SETTINGS} test" >> algorithms/unit_tests/Makefile echo "" >> algorithms/unit_tests/Makefile echo "clean:" >> algorithms/unit_tests/Makefile -echo -e "\tmake -f ${KOKKOS_PATH}/algorithms/unit_tests/Makefile ${KOKKOS_SETTINGS} clean" >> algorithms/unit_tests/Makefile +echo -e "\t\$(MAKE) -f ${KOKKOS_PATH}/algorithms/unit_tests/Makefile ${KOKKOS_SETTINGS} clean" >> algorithms/unit_tests/Makefile KOKKOS_SETTINGS="${KOKKOS_SETTINGS_NO_KOKKOS_PATH} KOKKOS_PATH=${KOKKOS_TEST_INSTALL_PATH}" echo "KOKKOS_SETTINGS=${KOKKOS_SETTINGS}" > example/fixture/Makefile echo "" >> example/fixture/Makefile echo "all:" >> example/fixture/Makefile -echo -e "\tmake -j ${MAKE_J_OPTION} -f ${KOKKOS_PATH}/example/fixture/Makefile ${KOKKOS_SETTINGS}" >> example/fixture/Makefile +echo -e "\t\$(MAKE) -f ${KOKKOS_PATH}/example/fixture/Makefile ${KOKKOS_SETTINGS}" >> example/fixture/Makefile echo "" >> example/fixture/Makefile echo "test: all" >> example/fixture/Makefile -echo -e "\tmake -j ${MAKE_J_OPTION} -f ${KOKKOS_PATH}/example/fixture/Makefile ${KOKKOS_SETTINGS} test" >> example/fixture/Makefile +echo -e "\t\$(MAKE) -f ${KOKKOS_PATH}/example/fixture/Makefile ${KOKKOS_SETTINGS} test" >> example/fixture/Makefile echo "" >> example/fixture/Makefile echo "clean:" >> example/fixture/Makefile -echo -e "\tmake -j ${MAKE_J_OPTION} -f ${KOKKOS_PATH}/example/fixture/Makefile ${KOKKOS_SETTINGS} clean" >> example/fixture/Makefile +echo -e "\t\$(MAKE) -f ${KOKKOS_PATH}/example/fixture/Makefile ${KOKKOS_SETTINGS} clean" >> example/fixture/Makefile echo "KOKKOS_SETTINGS=${KOKKOS_SETTINGS}" > example/feint/Makefile echo "" >> example/feint/Makefile echo "all:" >> example/feint/Makefile -echo -e "\tmake -j ${MAKE_J_OPTION} -f ${KOKKOS_PATH}/example/feint/Makefile ${KOKKOS_SETTINGS}" >> example/feint/Makefile +echo -e "\t\$(MAKE) -f ${KOKKOS_PATH}/example/feint/Makefile ${KOKKOS_SETTINGS}" >> example/feint/Makefile echo "" >> example/feint/Makefile echo "test: all" >> example/feint/Makefile -echo -e "\tmake -j ${MAKE_J_OPTION} -f ${KOKKOS_PATH}/example/feint/Makefile ${KOKKOS_SETTINGS} test" >> example/feint/Makefile +echo -e "\t\$(MAKE) -f ${KOKKOS_PATH}/example/feint/Makefile ${KOKKOS_SETTINGS} test" >> example/feint/Makefile echo "" >> example/feint/Makefile echo "clean:" >> example/feint/Makefile -echo -e "\tmake -j ${MAKE_J_OPTION} -f ${KOKKOS_PATH}/example/feint/Makefile ${KOKKOS_SETTINGS} clean" >> example/feint/Makefile +echo -e "\t\$(MAKE) -f ${KOKKOS_PATH}/example/feint/Makefile ${KOKKOS_SETTINGS} clean" >> example/feint/Makefile echo "KOKKOS_SETTINGS=${KOKKOS_SETTINGS}" > example/fenl/Makefile echo "" >> example/fenl/Makefile echo "all:" >> example/fenl/Makefile -echo -e "\tmake -j ${MAKE_J_OPTION} -f ${KOKKOS_PATH}/example/fenl/Makefile ${KOKKOS_SETTINGS}" >> example/fenl/Makefile +echo -e "\t\$(MAKE) -f ${KOKKOS_PATH}/example/fenl/Makefile ${KOKKOS_SETTINGS}" >> example/fenl/Makefile echo "" >> example/fenl/Makefile echo "test: all" >> example/fenl/Makefile -echo -e "\tmake -j ${MAKE_J_OPTION} -f ${KOKKOS_PATH}/example/fenl/Makefile ${KOKKOS_SETTINGS} test" >> example/fenl/Makefile +echo -e "\t\$(MAKE) -f ${KOKKOS_PATH}/example/fenl/Makefile ${KOKKOS_SETTINGS} test" >> example/fenl/Makefile echo "" >> example/fenl/Makefile echo "clean:" >> example/fenl/Makefile -echo -e "\tmake -j ${MAKE_J_OPTION} -f ${KOKKOS_PATH}/example/fenl/Makefile ${KOKKOS_SETTINGS} clean" >> example/fenl/Makefile +echo -e "\t\$(MAKE) -f ${KOKKOS_PATH}/example/fenl/Makefile ${KOKKOS_SETTINGS} clean" >> example/fenl/Makefile echo "KOKKOS_SETTINGS=${KOKKOS_SETTINGS}" > example/tutorial/Makefile echo "" >> example/tutorial/Makefile echo "build:" >> example/tutorial/Makefile -echo -e "\tmake -j ${MAKE_J_OPTION} -f ${KOKKOS_PATH}/example/tutorial/Makefile KOKKOS_SETTINGS='${KOKKOS_SETTINGS}' KOKKOS_PATH=${KOKKOS_PATH} build">> example/tutorial/Makefile +echo -e "\t\$(MAKE) -f ${KOKKOS_PATH}/example/tutorial/Makefile KOKKOS_SETTINGS='${KOKKOS_SETTINGS}' KOKKOS_PATH=${KOKKOS_PATH} build">> example/tutorial/Makefile echo "" >> example/tutorial/Makefile echo "test: build" >> example/tutorial/Makefile -echo -e "\tmake -j ${MAKE_J_OPTION} -f ${KOKKOS_PATH}/example/tutorial/Makefile KOKKOS_SETTINGS='${KOKKOS_SETTINGS}' KOKKOS_PATH=${KOKKOS_PATH} test" >> example/tutorial/Makefile +echo -e "\t\$(MAKE) -f ${KOKKOS_PATH}/example/tutorial/Makefile KOKKOS_SETTINGS='${KOKKOS_SETTINGS}' KOKKOS_PATH=${KOKKOS_PATH} test" >> example/tutorial/Makefile echo "" >> example/tutorial/Makefile echo "clean:" >> example/tutorial/Makefile -echo -e "\tmake -j ${MAKE_J_OPTION} -f ${KOKKOS_PATH}/example/tutorial/Makefile KOKKOS_SETTINGS='${KOKKOS_SETTINGS}' KOKKOS_PATH=${KOKKOS_PATH} clean" >> example/tutorial/Makefile +echo -e "\t\$(MAKE) -f ${KOKKOS_PATH}/example/tutorial/Makefile KOKKOS_SETTINGS='${KOKKOS_SETTINGS}' KOKKOS_PATH=${KOKKOS_PATH} clean" >> example/tutorial/Makefile if [ ${#KOKKOS_ENABLE_EXAMPLE_ICHOL} -gt 0 ]; then echo "KOKKOS_SETTINGS=${KOKKOS_SETTINGS}" > example/ichol/Makefile echo "" >> example/ichol/Makefile echo "all:" >> example/ichol/Makefile -echo -e "\tmake -j ${MAKE_J_OPTION} -f ${KOKKOS_PATH}/example/ichol/Makefile ${KOKKOS_SETTINGS}" >> example/ichol/Makefile +echo -e "\t\$(MAKE) -f ${KOKKOS_PATH}/example/ichol/Makefile ${KOKKOS_SETTINGS}" >> example/ichol/Makefile echo "" >> example/ichol/Makefile echo "test: all" >> example/ichol/Makefile -echo -e "\tmake -j ${MAKE_J_OPTION} -f ${KOKKOS_PATH}/example/ichol/Makefile ${KOKKOS_SETTINGS} test" >> example/ichol/Makefile +echo -e "\t\$(MAKE) -f ${KOKKOS_PATH}/example/ichol/Makefile ${KOKKOS_SETTINGS} test" >> example/ichol/Makefile echo "" >> example/ichol/Makefile echo "clean:" >> example/ichol/Makefile -echo -e "\tmake -j ${MAKE_J_OPTION} -f ${KOKKOS_PATH}/example/ichol/Makefile ${KOKKOS_SETTINGS} clean" >> example/ichol/Makefile +echo -e "\t\$(MAKE) -f ${KOKKOS_PATH}/example/ichol/Makefile ${KOKKOS_SETTINGS} clean" >> example/ichol/Makefile fi KOKKOS_SETTINGS="${KOKKOS_SETTINGS_NO_KOKKOS_PATH} KOKKOS_PATH=${KOKKOS_PATH}" @@ -385,62 +400,64 @@ echo "KOKKOS_SETTINGS=${KOKKOS_SETTINGS}" > Makefile echo "" >> Makefile echo "kokkoslib:" >> Makefile echo -e "\tcd core; \\" >> Makefile -echo -e "\tmake -j ${MAKE_J_OPTION} -f ${KOKKOS_PATH}/core/src/Makefile ${KOKKOS_SETTINGS} PREFIX=${KOKKOS_INSTALL_PATH} build-lib" >> Makefile +echo -e "\t\$(MAKE) -f ${KOKKOS_PATH}/core/src/Makefile ${KOKKOS_SETTINGS} PREFIX=${KOKKOS_INSTALL_PATH} build-lib" >> Makefile echo "" >> Makefile echo "install: kokkoslib" >> Makefile echo -e "\tcd core; \\" >> Makefile -echo -e "\tmake -j ${MAKE_J_OPTION} -f ${KOKKOS_PATH}/core/src/Makefile ${KOKKOS_SETTINGS} PREFIX=${KOKKOS_INSTALL_PATH} install" >> Makefile +echo -e "\t\$(MAKE) -f ${KOKKOS_PATH}/core/src/Makefile ${KOKKOS_SETTINGS} PREFIX=${KOKKOS_INSTALL_PATH} install" >> Makefile echo "" >> Makefile echo "kokkoslib-test:" >> Makefile echo -e "\tcd core; \\" >> Makefile -echo -e "\tmake -j ${MAKE_J_OPTION} -f ${KOKKOS_PATH}/core/src/Makefile ${KOKKOS_SETTINGS} PREFIX=${KOKKOS_TEST_INSTALL_PATH} build-lib" >> Makefile +echo -e "\t\$(MAKE) -f ${KOKKOS_PATH}/core/src/Makefile ${KOKKOS_SETTINGS} PREFIX=${KOKKOS_TEST_INSTALL_PATH} build-lib" >> Makefile echo "" >> Makefile echo "install-test: kokkoslib-test" >> Makefile echo -e "\tcd core; \\" >> Makefile -echo -e "\tmake -j ${MAKE_J_OPTION} -f ${KOKKOS_PATH}/core/src/Makefile ${KOKKOS_SETTINGS} PREFIX=${KOKKOS_TEST_INSTALL_PATH} install" >> Makefile +echo -e "\t\$(MAKE) -f ${KOKKOS_PATH}/core/src/Makefile ${KOKKOS_SETTINGS} PREFIX=${KOKKOS_TEST_INSTALL_PATH} install" >> Makefile echo "" >> Makefile echo "build-test: install-test" >> Makefile -echo -e "\tmake -C core/unit_test" >> Makefile -echo -e "\tmake -C core/perf_test" >> Makefile -echo -e "\tmake -C containers/unit_tests" >> Makefile -echo -e "\tmake -C containers/performance_tests" >> Makefile -echo -e "\tmake -C algorithms/unit_tests" >> Makefile +echo -e "\t\$(MAKE) -C core/unit_test" >> Makefile +echo -e "\t\$(MAKE) -C core/perf_test" >> Makefile +echo -e "\t\$(MAKE) -C containers/unit_tests" >> Makefile +echo -e "\t\$(MAKE) -C containers/performance_tests" >> Makefile +echo -e "\t\$(MAKE) -C algorithms/unit_tests" >> Makefile if [ ${KOKKOS_DO_EXAMPLES} -gt 0 ]; then -echo -e "\tmake -C example/fixture" >> Makefile -echo -e "\tmake -C example/feint" >> Makefile -echo -e "\tmake -C example/fenl" >> Makefile -echo -e "\tmake -C example/tutorial build" >> Makefile +echo -e "\t\$(MAKE) -C example/fixture" >> Makefile +echo -e "\t\$(MAKE) -C example/feint" >> Makefile +echo -e "\t\$(MAKE) -C example/fenl" >> Makefile +echo -e "\t\$(MAKE) -C example/tutorial build" >> Makefile fi echo "" >> Makefile echo "test: build-test" >> Makefile -echo -e "\tmake -C core/unit_test test" >> Makefile -echo -e "\tmake -C core/perf_test test" >> Makefile -echo -e "\tmake -C containers/unit_tests test" >> Makefile -echo -e "\tmake -C containers/performance_tests test" >> Makefile -echo -e "\tmake -C algorithms/unit_tests test" >> Makefile +echo -e "\t\$(MAKE) -C core/unit_test test" >> Makefile +echo -e "\t\$(MAKE) -C core/perf_test test" >> Makefile +echo -e "\t\$(MAKE) -C containers/unit_tests test" >> Makefile +echo -e "\t\$(MAKE) -C containers/performance_tests test" >> Makefile +echo -e "\t\$(MAKE) -C algorithms/unit_tests test" >> Makefile if [ ${KOKKOS_DO_EXAMPLES} -gt 0 ]; then -echo -e "\tmake -C example/fixture test" >> Makefile -echo -e "\tmake -C example/feint test" >> Makefile -echo -e "\tmake -C example/fenl test" >> Makefile -echo -e "\tmake -C example/tutorial test" >> Makefile +echo -e "\t\$(MAKE) -C example/fixture test" >> Makefile +echo -e "\t\$(MAKE) -C example/feint test" >> Makefile +echo -e "\t\$(MAKE) -C example/fenl test" >> Makefile +echo -e "\t\$(MAKE) -C example/tutorial test" >> Makefile fi echo "" >> Makefile echo "unit-tests-only:" >> Makefile -echo -e "\tmake -C core/unit_test test" >> Makefile -echo -e "\tmake -C containers/unit_tests test" >> Makefile -echo -e "\tmake -C algorithms/unit_tests test" >> Makefile +echo -e "\t\$(MAKE) -C core/unit_test test" >> Makefile +echo -e "\t\$(MAKE) -C containers/unit_tests test" >> Makefile +echo -e "\t\$(MAKE) -C algorithms/unit_tests test" >> Makefile echo "" >> Makefile + echo "clean:" >> Makefile -echo -e "\tmake -C core/unit_test clean" >> Makefile -echo -e "\tmake -C core/perf_test clean" >> Makefile -echo -e "\tmake -C containers/unit_tests clean" >> Makefile -echo -e "\tmake -C containers/performance_tests clean" >> Makefile -echo -e "\tmake -C algorithms/unit_tests clean" >> Makefile +echo -e "\t\$(MAKE) -C core/unit_test clean" >> Makefile +echo -e "\t\$(MAKE) -C core/perf_test clean" >> Makefile +echo -e "\t\$(MAKE) -C containers/unit_tests clean" >> Makefile +echo -e "\t\$(MAKE) -C containers/performance_tests clean" >> Makefile +echo -e "\t\$(MAKE) -C algorithms/unit_tests clean" >> Makefile if [ ${KOKKOS_DO_EXAMPLES} -gt 0 ]; then -echo -e "\tmake -C example/fixture clean" >> Makefile -echo -e "\tmake -C example/feint clean" >> Makefile -echo -e "\tmake -C example/fenl clean" >> Makefile -echo -e "\tmake -C example/tutorial clean" >> Makefile +echo -e "\t\$(MAKE) -C example/fixture clean" >> Makefile +echo -e "\t\$(MAKE) -C example/feint clean" >> Makefile +echo -e "\t\$(MAKE) -C example/fenl clean" >> Makefile +echo -e "\t\$(MAKE) -C example/tutorial clean" >> Makefile fi echo -e "\tcd core; \\" >> Makefile -echo -e "\tmake -f ${KOKKOS_PATH}/core/src/Makefile ${KOKKOS_SETTINGS} clean" >> Makefile +echo -e "\t\$(MAKE) -f ${KOKKOS_PATH}/core/src/Makefile ${KOKKOS_SETTINGS} clean" >> Makefile + diff --git a/lib/kokkos/tpls/gtest/gtest/LICENSE b/lib/kokkos/tpls/gtest/gtest/LICENSE new file mode 100644 index 0000000000..1941a11f8c --- /dev/null +++ b/lib/kokkos/tpls/gtest/gtest/LICENSE @@ -0,0 +1,28 @@ +Copyright 2008, Google Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/lib/kokkos/tpls/gtest/gtest/README b/lib/kokkos/tpls/gtest/gtest/README new file mode 100644 index 0000000000..82964ecc32 --- /dev/null +++ b/lib/kokkos/tpls/gtest/gtest/README @@ -0,0 +1,13 @@ +This is a fused source version of gtest 1.7.0. All that should be necessary to +start using gtest in your package is to declare the dependency and include +gtest/gtest.h. + +However, because some of the packages that are developed in Sierra do not use a +fused source version of gtest we need to make it possible for them to build with +this version as well as with their native build. To facilitate this we have +created symlinks for the other gtest headers that they use to the fused source +gtest.h. This will make it possible for them find the headers while still using +the fuse source version. This should not have any ill effects since the header is +protected and allows for only using the non-gtest.h headers in their files. + + diff --git a/lib/kokkos/tpls/gtest/gtest/gtest-all.cc b/lib/kokkos/tpls/gtest/gtest/gtest-all.cc new file mode 100644 index 0000000000..538c78db93 --- /dev/null +++ b/lib/kokkos/tpls/gtest/gtest/gtest-all.cc @@ -0,0 +1,9594 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: mheule@google.com (Markus Heule) +// +// Google C++ Testing Framework (Google Test) +// +// Sometimes it's desirable to build Google Test by compiling a single file. +// This file serves this purpose. + +// This line ensures that gtest.h can be compiled on its own, even +// when it's fused. +#include "gtest/gtest.h" + +// The following lines pull in the real gtest *.cc files. +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) +// +// The Google C++ Testing Framework (Google Test) + +// Copyright 2007, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) +// +// Utilities for testing Google Test itself and code that uses Google Test +// (e.g. frameworks built on top of Google Test). + +#ifndef GTEST_INCLUDE_GTEST_GTEST_SPI_H_ +#define GTEST_INCLUDE_GTEST_GTEST_SPI_H_ + + +namespace testing { + +// This helper class can be used to mock out Google Test failure reporting +// so that we can test Google Test or code that builds on Google Test. +// +// An object of this class appends a TestPartResult object to the +// TestPartResultArray object given in the constructor whenever a Google Test +// failure is reported. It can either intercept only failures that are +// generated in the same thread that created this object or it can intercept +// all generated failures. The scope of this mock object can be controlled with +// the second argument to the two arguments constructor. +class GTEST_API_ ScopedFakeTestPartResultReporter + : public TestPartResultReporterInterface { + public: + // The two possible mocking modes of this object. + enum InterceptMode { + INTERCEPT_ONLY_CURRENT_THREAD, // Intercepts only thread local failures. + INTERCEPT_ALL_THREADS // Intercepts all failures. + }; + + // The c'tor sets this object as the test part result reporter used + // by Google Test. The 'result' parameter specifies where to report the + // results. This reporter will only catch failures generated in the current + // thread. DEPRECATED + explicit ScopedFakeTestPartResultReporter(TestPartResultArray* result); + + // Same as above, but you can choose the interception scope of this object. + ScopedFakeTestPartResultReporter(InterceptMode intercept_mode, + TestPartResultArray* result); + + // The d'tor restores the previous test part result reporter. + virtual ~ScopedFakeTestPartResultReporter(); + + // Appends the TestPartResult object to the TestPartResultArray + // received in the constructor. + // + // This method is from the TestPartResultReporterInterface + // interface. + virtual void ReportTestPartResult(const TestPartResult& result); + private: + void Init(); + + const InterceptMode intercept_mode_; + TestPartResultReporterInterface* old_reporter_; + TestPartResultArray* const result_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedFakeTestPartResultReporter); +}; + +namespace internal { + +// A helper class for implementing EXPECT_FATAL_FAILURE() and +// EXPECT_NONFATAL_FAILURE(). Its destructor verifies that the given +// TestPartResultArray contains exactly one failure that has the given +// type and contains the given substring. If that's not the case, a +// non-fatal failure will be generated. +class GTEST_API_ SingleFailureChecker { + public: + // The constructor remembers the arguments. + SingleFailureChecker(const TestPartResultArray* results, + TestPartResult::Type type, + const string& substr); + ~SingleFailureChecker(); + private: + const TestPartResultArray* const results_; + const TestPartResult::Type type_; + const string substr_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(SingleFailureChecker); +}; + +} // namespace internal + +} // namespace testing + +// A set of macros for testing Google Test assertions or code that's expected +// to generate Google Test fatal failures. It verifies that the given +// statement will cause exactly one fatal Google Test failure with 'substr' +// being part of the failure message. +// +// There are two different versions of this macro. EXPECT_FATAL_FAILURE only +// affects and considers failures generated in the current thread and +// EXPECT_FATAL_FAILURE_ON_ALL_THREADS does the same but for all threads. +// +// The verification of the assertion is done correctly even when the statement +// throws an exception or aborts the current function. +// +// Known restrictions: +// - 'statement' cannot reference local non-static variables or +// non-static members of the current object. +// - 'statement' cannot return a value. +// - You cannot stream a failure message to this macro. +// +// Note that even though the implementations of the following two +// macros are much alike, we cannot refactor them to use a common +// helper macro, due to some peculiarity in how the preprocessor +// works. The AcceptsMacroThatExpandsToUnprotectedComma test in +// gtest_unittest.cc will fail to compile if we do that. +#define EXPECT_FATAL_FAILURE(statement, substr) \ + do { \ + class GTestExpectFatalFailureHelper {\ + public:\ + static void Execute() { statement; }\ + };\ + ::testing::TestPartResultArray gtest_failures;\ + ::testing::internal::SingleFailureChecker gtest_checker(\ + >est_failures, ::testing::TestPartResult::kFatalFailure, (substr));\ + {\ + ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ + ::testing::ScopedFakeTestPartResultReporter:: \ + INTERCEPT_ONLY_CURRENT_THREAD, >est_failures);\ + GTestExpectFatalFailureHelper::Execute();\ + }\ + } while (::testing::internal::AlwaysFalse()) + +#define EXPECT_FATAL_FAILURE_ON_ALL_THREADS(statement, substr) \ + do { \ + class GTestExpectFatalFailureHelper {\ + public:\ + static void Execute() { statement; }\ + };\ + ::testing::TestPartResultArray gtest_failures;\ + ::testing::internal::SingleFailureChecker gtest_checker(\ + >est_failures, ::testing::TestPartResult::kFatalFailure, (substr));\ + {\ + ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ + ::testing::ScopedFakeTestPartResultReporter:: \ + INTERCEPT_ALL_THREADS, >est_failures);\ + GTestExpectFatalFailureHelper::Execute();\ + }\ + } while (::testing::internal::AlwaysFalse()) + +// A macro for testing Google Test assertions or code that's expected to +// generate Google Test non-fatal failures. It asserts that the given +// statement will cause exactly one non-fatal Google Test failure with 'substr' +// being part of the failure message. +// +// There are two different versions of this macro. EXPECT_NONFATAL_FAILURE only +// affects and considers failures generated in the current thread and +// EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS does the same but for all threads. +// +// 'statement' is allowed to reference local variables and members of +// the current object. +// +// The verification of the assertion is done correctly even when the statement +// throws an exception or aborts the current function. +// +// Known restrictions: +// - You cannot stream a failure message to this macro. +// +// Note that even though the implementations of the following two +// macros are much alike, we cannot refactor them to use a common +// helper macro, due to some peculiarity in how the preprocessor +// works. If we do that, the code won't compile when the user gives +// EXPECT_NONFATAL_FAILURE() a statement that contains a macro that +// expands to code containing an unprotected comma. The +// AcceptsMacroThatExpandsToUnprotectedComma test in gtest_unittest.cc +// catches that. +// +// For the same reason, we have to write +// if (::testing::internal::AlwaysTrue()) { statement; } +// instead of +// GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) +// to avoid an MSVC warning on unreachable code. +#define EXPECT_NONFATAL_FAILURE(statement, substr) \ + do {\ + ::testing::TestPartResultArray gtest_failures;\ + ::testing::internal::SingleFailureChecker gtest_checker(\ + >est_failures, ::testing::TestPartResult::kNonFatalFailure, \ + (substr));\ + {\ + ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ + ::testing::ScopedFakeTestPartResultReporter:: \ + INTERCEPT_ONLY_CURRENT_THREAD, >est_failures);\ + if (::testing::internal::AlwaysTrue()) { statement; }\ + }\ + } while (::testing::internal::AlwaysFalse()) + +#define EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(statement, substr) \ + do {\ + ::testing::TestPartResultArray gtest_failures;\ + ::testing::internal::SingleFailureChecker gtest_checker(\ + >est_failures, ::testing::TestPartResult::kNonFatalFailure, \ + (substr));\ + {\ + ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ + ::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS, \ + >est_failures);\ + if (::testing::internal::AlwaysTrue()) { statement; }\ + }\ + } while (::testing::internal::AlwaysFalse()) + +#endif // GTEST_INCLUDE_GTEST_GTEST_SPI_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include // NOLINT +#include +#include + +#if GTEST_OS_LINUX + +// TODO(kenton@google.com): Use autoconf to detect availability of +// gettimeofday(). +# define GTEST_HAS_GETTIMEOFDAY_ 1 + +# include // NOLINT +# include // NOLINT +# include // NOLINT +// Declares vsnprintf(). This header is not available on Windows. +# include // NOLINT +# include // NOLINT +# include // NOLINT +# include // NOLINT +# include + +#elif GTEST_OS_SYMBIAN +# define GTEST_HAS_GETTIMEOFDAY_ 1 +# include // NOLINT + +#elif GTEST_OS_ZOS +# define GTEST_HAS_GETTIMEOFDAY_ 1 +# include // NOLINT + +// On z/OS we additionally need strings.h for strcasecmp. +# include // NOLINT + +#elif GTEST_OS_WINDOWS_MOBILE // We are on Windows CE. + +# include // NOLINT + +#elif GTEST_OS_WINDOWS // We are on Windows proper. + +# include // NOLINT +# include // NOLINT +# include // NOLINT +# include // NOLINT + +# if GTEST_OS_WINDOWS_MINGW +// MinGW has gettimeofday() but not _ftime64(). +// TODO(kenton@google.com): Use autoconf to detect availability of +// gettimeofday(). +// TODO(kenton@google.com): There are other ways to get the time on +// Windows, like GetTickCount() or GetSystemTimeAsFileTime(). MinGW +// supports these. consider using them instead. +# define GTEST_HAS_GETTIMEOFDAY_ 1 +# include // NOLINT +# endif // GTEST_OS_WINDOWS_MINGW + +// cpplint thinks that the header is already included, so we want to +// silence it. +# include // NOLINT + +#else + +// Assume other platforms have gettimeofday(). +// TODO(kenton@google.com): Use autoconf to detect availability of +// gettimeofday(). +# define GTEST_HAS_GETTIMEOFDAY_ 1 + +// cpplint thinks that the header is already included, so we want to +// silence it. +# include // NOLINT +# include // NOLINT + +#endif // GTEST_OS_LINUX + +#if GTEST_HAS_EXCEPTIONS +# include +#endif + +#if GTEST_CAN_STREAM_RESULTS_ +# include // NOLINT +# include // NOLINT +#endif + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION_ 1 +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Utility functions and classes used by the Google C++ testing framework. +// +// Author: wan@google.com (Zhanyong Wan) +// +// This file contains purely Google Test's internal implementation. Please +// DO NOT #INCLUDE IT IN A USER PROGRAM. + +#ifndef GTEST_SRC_GTEST_INTERNAL_INL_H_ +#define GTEST_SRC_GTEST_INTERNAL_INL_H_ + +// GTEST_IMPLEMENTATION_ is defined to 1 iff the current translation unit is +// part of Google Test's implementation; otherwise it's undefined. +#if !GTEST_IMPLEMENTATION_ +// A user is trying to include this from his code - just say no. +# error "gtest-internal-inl.h is part of Google Test's internal implementation." +# error "It must not be included except by Google Test itself." +#endif // GTEST_IMPLEMENTATION_ + +#ifndef _WIN32_WCE +# include +#endif // !_WIN32_WCE +#include +#include // For strtoll/_strtoul64/malloc/free. +#include // For memmove. + +#include +#include +#include + + +#if GTEST_CAN_STREAM_RESULTS_ +# include // NOLINT +# include // NOLINT +#endif + +#if GTEST_OS_WINDOWS +# include // NOLINT +#endif // GTEST_OS_WINDOWS + + +namespace testing { + +// Declares the flags. +// +// We don't want the users to modify this flag in the code, but want +// Google Test's own unit tests to be able to access it. Therefore we +// declare it here as opposed to in gtest.h. +GTEST_DECLARE_bool_(death_test_use_fork); + +namespace internal { + +// The value of GetTestTypeId() as seen from within the Google Test +// library. This is solely for testing GetTestTypeId(). +GTEST_API_ extern const TypeId kTestTypeIdInGoogleTest; + +// Names of the flags (needed for parsing Google Test flags). +const char kAlsoRunDisabledTestsFlag[] = "also_run_disabled_tests"; +const char kBreakOnFailureFlag[] = "break_on_failure"; +const char kCatchExceptionsFlag[] = "catch_exceptions"; +const char kColorFlag[] = "color"; +const char kFilterFlag[] = "filter"; +const char kListTestsFlag[] = "list_tests"; +const char kOutputFlag[] = "output"; +const char kPrintTimeFlag[] = "print_time"; +const char kRandomSeedFlag[] = "random_seed"; +const char kRepeatFlag[] = "repeat"; +const char kShuffleFlag[] = "shuffle"; +const char kStackTraceDepthFlag[] = "stack_trace_depth"; +const char kStreamResultToFlag[] = "stream_result_to"; +const char kThrowOnFailureFlag[] = "throw_on_failure"; + +// A valid random seed must be in [1, kMaxRandomSeed]. +const int kMaxRandomSeed = 99999; + +// g_help_flag is true iff the --help flag or an equivalent form is +// specified on the command line. +GTEST_API_ extern bool g_help_flag; + +// Returns the current time in milliseconds. +GTEST_API_ TimeInMillis GetTimeInMillis(); + +// Returns true iff Google Test should use colors in the output. +GTEST_API_ bool ShouldUseColor(bool stdout_is_tty); + +// Formats the given time in milliseconds as seconds. +GTEST_API_ std::string FormatTimeInMillisAsSeconds(TimeInMillis ms); + +// Converts the given time in milliseconds to a date string in the ISO 8601 +// format, without the timezone information. N.B.: due to the use the +// non-reentrant localtime() function, this function is not thread safe. Do +// not use it in any code that can be called from multiple threads. +GTEST_API_ std::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms); + +// Parses a string for an Int32 flag, in the form of "--flag=value". +// +// On success, stores the value of the flag in *value, and returns +// true. On failure, returns false without changing *value. +GTEST_API_ bool ParseInt32Flag( + const char* str, const char* flag, Int32* value); + +// Returns a random seed in range [1, kMaxRandomSeed] based on the +// given --gtest_random_seed flag value. +inline int GetRandomSeedFromFlag(Int32 random_seed_flag) { + const unsigned int raw_seed = (random_seed_flag == 0) ? + static_cast(GetTimeInMillis()) : + static_cast(random_seed_flag); + + // Normalizes the actual seed to range [1, kMaxRandomSeed] such that + // it's easy to type. + const int normalized_seed = + static_cast((raw_seed - 1U) % + static_cast(kMaxRandomSeed)) + 1; + return normalized_seed; +} + +// Returns the first valid random seed after 'seed'. The behavior is +// undefined if 'seed' is invalid. The seed after kMaxRandomSeed is +// considered to be 1. +inline int GetNextRandomSeed(int seed) { + GTEST_CHECK_(1 <= seed && seed <= kMaxRandomSeed) + << "Invalid random seed " << seed << " - must be in [1, " + << kMaxRandomSeed << "]."; + const int next_seed = seed + 1; + return (next_seed > kMaxRandomSeed) ? 1 : next_seed; +} + +// This class saves the values of all Google Test flags in its c'tor, and +// restores them in its d'tor. +class GTestFlagSaver { + public: + // The c'tor. + GTestFlagSaver() { + also_run_disabled_tests_ = GTEST_FLAG(also_run_disabled_tests); + break_on_failure_ = GTEST_FLAG(break_on_failure); + catch_exceptions_ = GTEST_FLAG(catch_exceptions); + color_ = GTEST_FLAG(color); + death_test_style_ = GTEST_FLAG(death_test_style); + death_test_use_fork_ = GTEST_FLAG(death_test_use_fork); + filter_ = GTEST_FLAG(filter); + internal_run_death_test_ = GTEST_FLAG(internal_run_death_test); + list_tests_ = GTEST_FLAG(list_tests); + output_ = GTEST_FLAG(output); + print_time_ = GTEST_FLAG(print_time); + random_seed_ = GTEST_FLAG(random_seed); + repeat_ = GTEST_FLAG(repeat); + shuffle_ = GTEST_FLAG(shuffle); + stack_trace_depth_ = GTEST_FLAG(stack_trace_depth); + stream_result_to_ = GTEST_FLAG(stream_result_to); + throw_on_failure_ = GTEST_FLAG(throw_on_failure); + } + + // The d'tor is not virtual. DO NOT INHERIT FROM THIS CLASS. + ~GTestFlagSaver() { + GTEST_FLAG(also_run_disabled_tests) = also_run_disabled_tests_; + GTEST_FLAG(break_on_failure) = break_on_failure_; + GTEST_FLAG(catch_exceptions) = catch_exceptions_; + GTEST_FLAG(color) = color_; + GTEST_FLAG(death_test_style) = death_test_style_; + GTEST_FLAG(death_test_use_fork) = death_test_use_fork_; + GTEST_FLAG(filter) = filter_; + GTEST_FLAG(internal_run_death_test) = internal_run_death_test_; + GTEST_FLAG(list_tests) = list_tests_; + GTEST_FLAG(output) = output_; + GTEST_FLAG(print_time) = print_time_; + GTEST_FLAG(random_seed) = random_seed_; + GTEST_FLAG(repeat) = repeat_; + GTEST_FLAG(shuffle) = shuffle_; + GTEST_FLAG(stack_trace_depth) = stack_trace_depth_; + GTEST_FLAG(stream_result_to) = stream_result_to_; + GTEST_FLAG(throw_on_failure) = throw_on_failure_; + } + + private: + // Fields for saving the original values of flags. + bool also_run_disabled_tests_; + bool break_on_failure_; + bool catch_exceptions_; + std::string color_; + std::string death_test_style_; + bool death_test_use_fork_; + std::string filter_; + std::string internal_run_death_test_; + bool list_tests_; + std::string output_; + bool print_time_; + internal::Int32 random_seed_; + internal::Int32 repeat_; + bool shuffle_; + internal::Int32 stack_trace_depth_; + std::string stream_result_to_; + bool throw_on_failure_; +} GTEST_ATTRIBUTE_UNUSED_; + +// Converts a Unicode code point to a narrow string in UTF-8 encoding. +// code_point parameter is of type UInt32 because wchar_t may not be +// wide enough to contain a code point. +// If the code_point is not a valid Unicode code point +// (i.e. outside of Unicode range U+0 to U+10FFFF) it will be converted +// to "(Invalid Unicode 0xXXXXXXXX)". +GTEST_API_ std::string CodePointToUtf8(UInt32 code_point); + +// Converts a wide string to a narrow string in UTF-8 encoding. +// The wide string is assumed to have the following encoding: +// UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin, Symbian OS) +// UTF-32 if sizeof(wchar_t) == 4 (on Linux) +// Parameter str points to a null-terminated wide string. +// Parameter num_chars may additionally limit the number +// of wchar_t characters processed. -1 is used when the entire string +// should be processed. +// If the string contains code points that are not valid Unicode code points +// (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output +// as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding +// and contains invalid UTF-16 surrogate pairs, values in those pairs +// will be encoded as individual Unicode characters from Basic Normal Plane. +GTEST_API_ std::string WideStringToUtf8(const wchar_t* str, int num_chars); + +// Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file +// if the variable is present. If a file already exists at this location, this +// function will write over it. If the variable is present, but the file cannot +// be created, prints an error and exits. +void WriteToShardStatusFileIfNeeded(); + +// Checks whether sharding is enabled by examining the relevant +// environment variable values. If the variables are present, +// but inconsistent (e.g., shard_index >= total_shards), prints +// an error and exits. If in_subprocess_for_death_test, sharding is +// disabled because it must only be applied to the original test +// process. Otherwise, we could filter out death tests we intended to execute. +GTEST_API_ bool ShouldShard(const char* total_shards_str, + const char* shard_index_str, + bool in_subprocess_for_death_test); + +// Parses the environment variable var as an Int32. If it is unset, +// returns default_val. If it is not an Int32, prints an error and +// and aborts. +GTEST_API_ Int32 Int32FromEnvOrDie(const char* env_var, Int32 default_val); + +// Given the total number of shards, the shard index, and the test id, +// returns true iff the test should be run on this shard. The test id is +// some arbitrary but unique non-negative integer assigned to each test +// method. Assumes that 0 <= shard_index < total_shards. +GTEST_API_ bool ShouldRunTestOnShard( + int total_shards, int shard_index, int test_id); + +// STL container utilities. + +// Returns the number of elements in the given container that satisfy +// the given predicate. +template +inline int CountIf(const Container& c, Predicate predicate) { + // Implemented as an explicit loop since std::count_if() in libCstd on + // Solaris has a non-standard signature. + int count = 0; + for (typename Container::const_iterator it = c.begin(); it != c.end(); ++it) { + if (predicate(*it)) + ++count; + } + return count; +} + +// Applies a function/functor to each element in the container. +template +void ForEach(const Container& c, Functor functor) { + std::for_each(c.begin(), c.end(), functor); +} + +// Returns the i-th element of the vector, or default_value if i is not +// in range [0, v.size()). +template +inline E GetElementOr(const std::vector& v, int i, E default_value) { + return (i < 0 || i >= static_cast(v.size())) ? default_value : v[i]; +} + +// Performs an in-place shuffle of a range of the vector's elements. +// 'begin' and 'end' are element indices as an STL-style range; +// i.e. [begin, end) are shuffled, where 'end' == size() means to +// shuffle to the end of the vector. +template +void ShuffleRange(internal::Random* random, int begin, int end, + std::vector* v) { + const int size = static_cast(v->size()); + GTEST_CHECK_(0 <= begin && begin <= size) + << "Invalid shuffle range start " << begin << ": must be in range [0, " + << size << "]."; + GTEST_CHECK_(begin <= end && end <= size) + << "Invalid shuffle range finish " << end << ": must be in range [" + << begin << ", " << size << "]."; + + // Fisher-Yates shuffle, from + // http://en.wikipedia.org/wiki/Fisher-Yates_shuffle + for (int range_width = end - begin; range_width >= 2; range_width--) { + const int last_in_range = begin + range_width - 1; + const int selected = begin + random->Generate(range_width); + std::swap((*v)[selected], (*v)[last_in_range]); + } +} + +// Performs an in-place shuffle of the vector's elements. +template +inline void Shuffle(internal::Random* random, std::vector* v) { + ShuffleRange(random, 0, static_cast(v->size()), v); +} + +// A function for deleting an object. Handy for being used as a +// functor. +template +static void Delete(T* x) { + delete x; +} + +// A predicate that checks the key of a TestProperty against a known key. +// +// TestPropertyKeyIs is copyable. +class TestPropertyKeyIs { + public: + // Constructor. + // + // TestPropertyKeyIs has NO default constructor. + explicit TestPropertyKeyIs(const std::string& key) : key_(key) {} + + // Returns true iff the test name of test property matches on key_. + bool operator()(const TestProperty& test_property) const { + return test_property.key() == key_; + } + + private: + std::string key_; +}; + +// Class UnitTestOptions. +// +// This class contains functions for processing options the user +// specifies when running the tests. It has only static members. +// +// In most cases, the user can specify an option using either an +// environment variable or a command line flag. E.g. you can set the +// test filter using either GTEST_FILTER or --gtest_filter. If both +// the variable and the flag are present, the latter overrides the +// former. +class GTEST_API_ UnitTestOptions { + public: + // Functions for processing the gtest_output flag. + + // Returns the output format, or "" for normal printed output. + static std::string GetOutputFormat(); + + // Returns the absolute path of the requested output file, or the + // default (test_detail.xml in the original working directory) if + // none was explicitly specified. + static std::string GetAbsolutePathToOutputFile(); + + // Functions for processing the gtest_filter flag. + + // Returns true iff the wildcard pattern matches the string. The + // first ':' or '\0' character in pattern marks the end of it. + // + // This recursive algorithm isn't very efficient, but is clear and + // works well enough for matching test names, which are short. + static bool PatternMatchesString(const char *pattern, const char *str); + + // Returns true iff the user-specified filter matches the test case + // name and the test name. + static bool FilterMatchesTest(const std::string &test_case_name, + const std::string &test_name); + +#if GTEST_OS_WINDOWS + // Function for supporting the gtest_catch_exception flag. + + // Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the + // given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise. + // This function is useful as an __except condition. + static int GTestShouldProcessSEH(DWORD exception_code); +#endif // GTEST_OS_WINDOWS + + // Returns true if "name" matches the ':' separated list of glob-style + // filters in "filter". + static bool MatchesFilter(const std::string& name, const char* filter); +}; + +// Returns the current application's name, removing directory path if that +// is present. Used by UnitTestOptions::GetOutputFile. +GTEST_API_ FilePath GetCurrentExecutableName(); + +// The role interface for getting the OS stack trace as a string. +class OsStackTraceGetterInterface { + public: + OsStackTraceGetterInterface() {} + virtual ~OsStackTraceGetterInterface() {} + + // Returns the current OS stack trace as an std::string. Parameters: + // + // max_depth - the maximum number of stack frames to be included + // in the trace. + // skip_count - the number of top frames to be skipped; doesn't count + // against max_depth. + virtual string CurrentStackTrace(int max_depth, int skip_count) = 0; + + // UponLeavingGTest() should be called immediately before Google Test calls + // user code. It saves some information about the current stack that + // CurrentStackTrace() will use to find and hide Google Test stack frames. + virtual void UponLeavingGTest() = 0; + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetterInterface); +}; + +// A working implementation of the OsStackTraceGetterInterface interface. +class OsStackTraceGetter : public OsStackTraceGetterInterface { + public: + OsStackTraceGetter() : caller_frame_(NULL) {} + + virtual string CurrentStackTrace(int max_depth, int skip_count) + GTEST_LOCK_EXCLUDED_(mutex_); + + virtual void UponLeavingGTest() GTEST_LOCK_EXCLUDED_(mutex_); + + // This string is inserted in place of stack frames that are part of + // Google Test's implementation. + static const char* const kElidedFramesMarker; + + private: + Mutex mutex_; // protects all internal state + + // We save the stack frame below the frame that calls user code. + // We do this because the address of the frame immediately below + // the user code changes between the call to UponLeavingGTest() + // and any calls to CurrentStackTrace() from within the user code. + void* caller_frame_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetter); +}; + +// Information about a Google Test trace point. +struct TraceInfo { + const char* file; + int line; + std::string message; +}; + +// This is the default global test part result reporter used in UnitTestImpl. +// This class should only be used by UnitTestImpl. +class DefaultGlobalTestPartResultReporter + : public TestPartResultReporterInterface { + public: + explicit DefaultGlobalTestPartResultReporter(UnitTestImpl* unit_test); + // Implements the TestPartResultReporterInterface. Reports the test part + // result in the current test. + virtual void ReportTestPartResult(const TestPartResult& result); + + private: + UnitTestImpl* const unit_test_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultGlobalTestPartResultReporter); +}; + +// This is the default per thread test part result reporter used in +// UnitTestImpl. This class should only be used by UnitTestImpl. +class DefaultPerThreadTestPartResultReporter + : public TestPartResultReporterInterface { + public: + explicit DefaultPerThreadTestPartResultReporter(UnitTestImpl* unit_test); + // Implements the TestPartResultReporterInterface. The implementation just + // delegates to the current global test part result reporter of *unit_test_. + virtual void ReportTestPartResult(const TestPartResult& result); + + private: + UnitTestImpl* const unit_test_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultPerThreadTestPartResultReporter); +}; + +// The private implementation of the UnitTest class. We don't protect +// the methods under a mutex, as this class is not accessible by a +// user and the UnitTest class that delegates work to this class does +// proper locking. +class GTEST_API_ UnitTestImpl { + public: + explicit UnitTestImpl(UnitTest* parent); + virtual ~UnitTestImpl(); + + // There are two different ways to register your own TestPartResultReporter. + // You can register your own repoter to listen either only for test results + // from the current thread or for results from all threads. + // By default, each per-thread test result repoter just passes a new + // TestPartResult to the global test result reporter, which registers the + // test part result for the currently running test. + + // Returns the global test part result reporter. + TestPartResultReporterInterface* GetGlobalTestPartResultReporter(); + + // Sets the global test part result reporter. + void SetGlobalTestPartResultReporter( + TestPartResultReporterInterface* reporter); + + // Returns the test part result reporter for the current thread. + TestPartResultReporterInterface* GetTestPartResultReporterForCurrentThread(); + + // Sets the test part result reporter for the current thread. + void SetTestPartResultReporterForCurrentThread( + TestPartResultReporterInterface* reporter); + + // Gets the number of successful test cases. + int successful_test_case_count() const; + + // Gets the number of failed test cases. + int failed_test_case_count() const; + + // Gets the number of all test cases. + int total_test_case_count() const; + + // Gets the number of all test cases that contain at least one test + // that should run. + int test_case_to_run_count() const; + + // Gets the number of successful tests. + int successful_test_count() const; + + // Gets the number of failed tests. + int failed_test_count() const; + + // Gets the number of disabled tests that will be reported in the XML report. + int reportable_disabled_test_count() const; + + // Gets the number of disabled tests. + int disabled_test_count() const; + + // Gets the number of tests to be printed in the XML report. + int reportable_test_count() const; + + // Gets the number of all tests. + int total_test_count() const; + + // Gets the number of tests that should run. + int test_to_run_count() const; + + // Gets the time of the test program start, in ms from the start of the + // UNIX epoch. + TimeInMillis start_timestamp() const { return start_timestamp_; } + + // Gets the elapsed time, in milliseconds. + TimeInMillis elapsed_time() const { return elapsed_time_; } + + // Returns true iff the unit test passed (i.e. all test cases passed). + bool Passed() const { return !Failed(); } + + // Returns true iff the unit test failed (i.e. some test case failed + // or something outside of all tests failed). + bool Failed() const { + return failed_test_case_count() > 0 || ad_hoc_test_result()->Failed(); + } + + // Gets the i-th test case among all the test cases. i can range from 0 to + // total_test_case_count() - 1. If i is not in that range, returns NULL. + const TestCase* GetTestCase(int i) const { + const int index = GetElementOr(test_case_indices_, i, -1); + return index < 0 ? NULL : test_cases_[i]; + } + + // Gets the i-th test case among all the test cases. i can range from 0 to + // total_test_case_count() - 1. If i is not in that range, returns NULL. + TestCase* GetMutableTestCase(int i) { + const int index = GetElementOr(test_case_indices_, i, -1); + return index < 0 ? NULL : test_cases_[index]; + } + + // Provides access to the event listener list. + TestEventListeners* listeners() { return &listeners_; } + + // Returns the TestResult for the test that's currently running, or + // the TestResult for the ad hoc test if no test is running. + TestResult* current_test_result(); + + // Returns the TestResult for the ad hoc test. + const TestResult* ad_hoc_test_result() const { return &ad_hoc_test_result_; } + + // Sets the OS stack trace getter. + // + // Does nothing if the input and the current OS stack trace getter + // are the same; otherwise, deletes the old getter and makes the + // input the current getter. + void set_os_stack_trace_getter(OsStackTraceGetterInterface* getter); + + // Returns the current OS stack trace getter if it is not NULL; + // otherwise, creates an OsStackTraceGetter, makes it the current + // getter, and returns it. + OsStackTraceGetterInterface* os_stack_trace_getter(); + + // Returns the current OS stack trace as an std::string. + // + // The maximum number of stack frames to be included is specified by + // the gtest_stack_trace_depth flag. The skip_count parameter + // specifies the number of top frames to be skipped, which doesn't + // count against the number of frames to be included. + // + // For example, if Foo() calls Bar(), which in turn calls + // CurrentOsStackTraceExceptTop(1), Foo() will be included in the + // trace but Bar() and CurrentOsStackTraceExceptTop() won't. + std::string CurrentOsStackTraceExceptTop(int skip_count) GTEST_NO_INLINE_; + + // Finds and returns a TestCase with the given name. If one doesn't + // exist, creates one and returns it. + // + // Arguments: + // + // test_case_name: name of the test case + // type_param: the name of the test's type parameter, or NULL if + // this is not a typed or a type-parameterized test. + // set_up_tc: pointer to the function that sets up the test case + // tear_down_tc: pointer to the function that tears down the test case + TestCase* GetTestCase(const char* test_case_name, + const char* type_param, + Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc); + + // Adds a TestInfo to the unit test. + // + // Arguments: + // + // set_up_tc: pointer to the function that sets up the test case + // tear_down_tc: pointer to the function that tears down the test case + // test_info: the TestInfo object + void AddTestInfo(Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc, + TestInfo* test_info) { + // In order to support thread-safe death tests, we need to + // remember the original working directory when the test program + // was first invoked. We cannot do this in RUN_ALL_TESTS(), as + // the user may have changed the current directory before calling + // RUN_ALL_TESTS(). Therefore we capture the current directory in + // AddTestInfo(), which is called to register a TEST or TEST_F + // before main() is reached. + if (original_working_dir_.IsEmpty()) { + original_working_dir_.Set(FilePath::GetCurrentDir()); + GTEST_CHECK_(!original_working_dir_.IsEmpty()) + << "Failed to get the current working directory."; + } + + GetTestCase(test_info->test_case_name(), + test_info->type_param(), + set_up_tc, + tear_down_tc)->AddTestInfo(test_info); + } + +#if GTEST_HAS_PARAM_TEST + // Returns ParameterizedTestCaseRegistry object used to keep track of + // value-parameterized tests and instantiate and register them. + internal::ParameterizedTestCaseRegistry& parameterized_test_registry() { + return parameterized_test_registry_; + } +#endif // GTEST_HAS_PARAM_TEST + + // Sets the TestCase object for the test that's currently running. + void set_current_test_case(TestCase* a_current_test_case) { + current_test_case_ = a_current_test_case; + } + + // Sets the TestInfo object for the test that's currently running. If + // current_test_info is NULL, the assertion results will be stored in + // ad_hoc_test_result_. + void set_current_test_info(TestInfo* a_current_test_info) { + current_test_info_ = a_current_test_info; + } + + // Registers all parameterized tests defined using TEST_P and + // INSTANTIATE_TEST_CASE_P, creating regular tests for each test/parameter + // combination. This method can be called more then once; it has guards + // protecting from registering the tests more then once. If + // value-parameterized tests are disabled, RegisterParameterizedTests is + // present but does nothing. + void RegisterParameterizedTests(); + + // Runs all tests in this UnitTest object, prints the result, and + // returns true if all tests are successful. If any exception is + // thrown during a test, this test is considered to be failed, but + // the rest of the tests will still be run. + bool RunAllTests(); + + // Clears the results of all tests, except the ad hoc tests. + void ClearNonAdHocTestResult() { + ForEach(test_cases_, TestCase::ClearTestCaseResult); + } + + // Clears the results of ad-hoc test assertions. + void ClearAdHocTestResult() { + ad_hoc_test_result_.Clear(); + } + + // Adds a TestProperty to the current TestResult object when invoked in a + // context of a test or a test case, or to the global property set. If the + // result already contains a property with the same key, the value will be + // updated. + void RecordProperty(const TestProperty& test_property); + + enum ReactionToSharding { + HONOR_SHARDING_PROTOCOL, + IGNORE_SHARDING_PROTOCOL + }; + + // Matches the full name of each test against the user-specified + // filter to decide whether the test should run, then records the + // result in each TestCase and TestInfo object. + // If shard_tests == HONOR_SHARDING_PROTOCOL, further filters tests + // based on sharding variables in the environment. + // Returns the number of tests that should run. + int FilterTests(ReactionToSharding shard_tests); + + // Prints the names of the tests matching the user-specified filter flag. + void ListTestsMatchingFilter(); + + const TestCase* current_test_case() const { return current_test_case_; } + TestInfo* current_test_info() { return current_test_info_; } + const TestInfo* current_test_info() const { return current_test_info_; } + + // Returns the vector of environments that need to be set-up/torn-down + // before/after the tests are run. + std::vector& environments() { return environments_; } + + // Getters for the per-thread Google Test trace stack. + std::vector& gtest_trace_stack() { + return *(gtest_trace_stack_.pointer()); + } + const std::vector& gtest_trace_stack() const { + return gtest_trace_stack_.get(); + } + +#if GTEST_HAS_DEATH_TEST + void InitDeathTestSubprocessControlInfo() { + internal_run_death_test_flag_.reset(ParseInternalRunDeathTestFlag()); + } + // Returns a pointer to the parsed --gtest_internal_run_death_test + // flag, or NULL if that flag was not specified. + // This information is useful only in a death test child process. + // Must not be called before a call to InitGoogleTest. + const InternalRunDeathTestFlag* internal_run_death_test_flag() const { + return internal_run_death_test_flag_.get(); + } + + // Returns a pointer to the current death test factory. + internal::DeathTestFactory* death_test_factory() { + return death_test_factory_.get(); + } + + void SuppressTestEventsIfInSubprocess(); + + friend class ReplaceDeathTestFactory; +#endif // GTEST_HAS_DEATH_TEST + + // Initializes the event listener performing XML output as specified by + // UnitTestOptions. Must not be called before InitGoogleTest. + void ConfigureXmlOutput(); + +#if GTEST_CAN_STREAM_RESULTS_ + // Initializes the event listener for streaming test results to a socket. + // Must not be called before InitGoogleTest. + void ConfigureStreamingOutput(); +#endif + + // Performs initialization dependent upon flag values obtained in + // ParseGoogleTestFlagsOnly. Is called from InitGoogleTest after the call to + // ParseGoogleTestFlagsOnly. In case a user neglects to call InitGoogleTest + // this function is also called from RunAllTests. Since this function can be + // called more than once, it has to be idempotent. + void PostFlagParsingInit(); + + // Gets the random seed used at the start of the current test iteration. + int random_seed() const { return random_seed_; } + + // Gets the random number generator. + internal::Random* random() { return &random_; } + + // Shuffles all test cases, and the tests within each test case, + // making sure that death tests are still run first. + void ShuffleTests(); + + // Restores the test cases and tests to their order before the first shuffle. + void UnshuffleTests(); + + // Returns the value of GTEST_FLAG(catch_exceptions) at the moment + // UnitTest::Run() starts. + bool catch_exceptions() const { return catch_exceptions_; } + + private: + friend class ::testing::UnitTest; + + // Used by UnitTest::Run() to capture the state of + // GTEST_FLAG(catch_exceptions) at the moment it starts. + void set_catch_exceptions(bool value) { catch_exceptions_ = value; } + + // The UnitTest object that owns this implementation object. + UnitTest* const parent_; + + // The working directory when the first TEST() or TEST_F() was + // executed. + internal::FilePath original_working_dir_; + + // The default test part result reporters. + DefaultGlobalTestPartResultReporter default_global_test_part_result_reporter_; + DefaultPerThreadTestPartResultReporter + default_per_thread_test_part_result_reporter_; + + // Points to (but doesn't own) the global test part result reporter. + TestPartResultReporterInterface* global_test_part_result_repoter_; + + // Protects read and write access to global_test_part_result_reporter_. + internal::Mutex global_test_part_result_reporter_mutex_; + + // Points to (but doesn't own) the per-thread test part result reporter. + internal::ThreadLocal + per_thread_test_part_result_reporter_; + + // The vector of environments that need to be set-up/torn-down + // before/after the tests are run. + std::vector environments_; + + // The vector of TestCases in their original order. It owns the + // elements in the vector. + std::vector test_cases_; + + // Provides a level of indirection for the test case list to allow + // easy shuffling and restoring the test case order. The i-th + // element of this vector is the index of the i-th test case in the + // shuffled order. + std::vector test_case_indices_; + +#if GTEST_HAS_PARAM_TEST + // ParameterizedTestRegistry object used to register value-parameterized + // tests. + internal::ParameterizedTestCaseRegistry parameterized_test_registry_; + + // Indicates whether RegisterParameterizedTests() has been called already. + bool parameterized_tests_registered_; +#endif // GTEST_HAS_PARAM_TEST + + // Index of the last death test case registered. Initially -1. + int last_death_test_case_; + + // This points to the TestCase for the currently running test. It + // changes as Google Test goes through one test case after another. + // When no test is running, this is set to NULL and Google Test + // stores assertion results in ad_hoc_test_result_. Initially NULL. + TestCase* current_test_case_; + + // This points to the TestInfo for the currently running test. It + // changes as Google Test goes through one test after another. When + // no test is running, this is set to NULL and Google Test stores + // assertion results in ad_hoc_test_result_. Initially NULL. + TestInfo* current_test_info_; + + // Normally, a user only writes assertions inside a TEST or TEST_F, + // or inside a function called by a TEST or TEST_F. Since Google + // Test keeps track of which test is current running, it can + // associate such an assertion with the test it belongs to. + // + // If an assertion is encountered when no TEST or TEST_F is running, + // Google Test attributes the assertion result to an imaginary "ad hoc" + // test, and records the result in ad_hoc_test_result_. + TestResult ad_hoc_test_result_; + + // The list of event listeners that can be used to track events inside + // Google Test. + TestEventListeners listeners_; + + // The OS stack trace getter. Will be deleted when the UnitTest + // object is destructed. By default, an OsStackTraceGetter is used, + // but the user can set this field to use a custom getter if that is + // desired. + OsStackTraceGetterInterface* os_stack_trace_getter_; + + // True iff PostFlagParsingInit() has been called. + bool post_flag_parse_init_performed_; + + // The random number seed used at the beginning of the test run. + int random_seed_; + + // Our random number generator. + internal::Random random_; + + // The time of the test program start, in ms from the start of the + // UNIX epoch. + TimeInMillis start_timestamp_; + + // How long the test took to run, in milliseconds. + TimeInMillis elapsed_time_; + +#if GTEST_HAS_DEATH_TEST + // The decomposed components of the gtest_internal_run_death_test flag, + // parsed when RUN_ALL_TESTS is called. + internal::scoped_ptr internal_run_death_test_flag_; + internal::scoped_ptr death_test_factory_; +#endif // GTEST_HAS_DEATH_TEST + + // A per-thread stack of traces created by the SCOPED_TRACE() macro. + internal::ThreadLocal > gtest_trace_stack_; + + // The value of GTEST_FLAG(catch_exceptions) at the moment RunAllTests() + // starts. + bool catch_exceptions_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTestImpl); +}; // class UnitTestImpl + +// Convenience function for accessing the global UnitTest +// implementation object. +inline UnitTestImpl* GetUnitTestImpl() { + return UnitTest::GetInstance()->impl(); +} + +#if GTEST_USES_SIMPLE_RE + +// Internal helper functions for implementing the simple regular +// expression matcher. +GTEST_API_ bool IsInSet(char ch, const char* str); +GTEST_API_ bool IsAsciiDigit(char ch); +GTEST_API_ bool IsAsciiPunct(char ch); +GTEST_API_ bool IsRepeat(char ch); +GTEST_API_ bool IsAsciiWhiteSpace(char ch); +GTEST_API_ bool IsAsciiWordChar(char ch); +GTEST_API_ bool IsValidEscape(char ch); +GTEST_API_ bool AtomMatchesChar(bool escaped, char pattern, char ch); +GTEST_API_ bool ValidateRegex(const char* regex); +GTEST_API_ bool MatchRegexAtHead(const char* regex, const char* str); +GTEST_API_ bool MatchRepetitionAndRegexAtHead( + bool escaped, char ch, char repeat, const char* regex, const char* str); +GTEST_API_ bool MatchRegexAnywhere(const char* regex, const char* str); + +#endif // GTEST_USES_SIMPLE_RE + +// Parses the command line for Google Test flags, without initializing +// other parts of Google Test. +GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, char** argv); +GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv); + +#if GTEST_HAS_DEATH_TEST + +// Returns the message describing the last system error, regardless of the +// platform. +GTEST_API_ std::string GetLastErrnoDescription(); + +# if GTEST_OS_WINDOWS +// Provides leak-safe Windows kernel handle ownership. +class AutoHandle { + public: + AutoHandle() : handle_(INVALID_HANDLE_VALUE) {} + explicit AutoHandle(HANDLE handle) : handle_(handle) {} + + ~AutoHandle() { Reset(); } + + HANDLE Get() const { return handle_; } + void Reset() { Reset(INVALID_HANDLE_VALUE); } + void Reset(HANDLE handle) { + if (handle != handle_) { + if (handle_ != INVALID_HANDLE_VALUE) + ::CloseHandle(handle_); + handle_ = handle; + } + } + + private: + HANDLE handle_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(AutoHandle); +}; +# endif // GTEST_OS_WINDOWS + +// Attempts to parse a string into a positive integer pointed to by the +// number parameter. Returns true if that is possible. +// GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we can use +// it here. +template +bool ParseNaturalNumber(const ::std::string& str, Integer* number) { + // Fail fast if the given string does not begin with a digit; + // this bypasses strtoXXX's "optional leading whitespace and plus + // or minus sign" semantics, which are undesirable here. + if (str.empty() || !IsDigit(str[0])) { + return false; + } + errno = 0; + + char* end; + // BiggestConvertible is the largest integer type that system-provided + // string-to-number conversion routines can return. + +# if GTEST_OS_WINDOWS && !defined(__GNUC__) + + // MSVC and C++ Builder define __int64 instead of the standard long long. + typedef unsigned __int64 BiggestConvertible; + const BiggestConvertible parsed = _strtoui64(str.c_str(), &end, 10); + +# else + + typedef unsigned long long BiggestConvertible; // NOLINT + const BiggestConvertible parsed = strtoull(str.c_str(), &end, 10); + +# endif // GTEST_OS_WINDOWS && !defined(__GNUC__) + + const bool parse_success = *end == '\0' && errno == 0; + + // TODO(vladl@google.com): Convert this to compile time assertion when it is + // available. + GTEST_CHECK_(sizeof(Integer) <= sizeof(parsed)); + + const Integer result = static_cast(parsed); + if (parse_success && static_cast(result) == parsed) { + *number = result; + return true; + } + return false; +} +#endif // GTEST_HAS_DEATH_TEST + +// TestResult contains some private methods that should be hidden from +// Google Test user but are required for testing. This class allow our tests +// to access them. +// +// This class is supplied only for the purpose of testing Google Test's own +// constructs. Do not use it in user tests, either directly or indirectly. +class TestResultAccessor { + public: + static void RecordProperty(TestResult* test_result, + const std::string& xml_element, + const TestProperty& property) { + test_result->RecordProperty(xml_element, property); + } + + static void ClearTestPartResults(TestResult* test_result) { + test_result->ClearTestPartResults(); + } + + static const std::vector& test_part_results( + const TestResult& test_result) { + return test_result.test_part_results(); + } +}; + +#if GTEST_CAN_STREAM_RESULTS_ + +// Streams test results to the given port on the given host machine. +class StreamingListener : public EmptyTestEventListener { + public: + // Abstract base class for writing strings to a socket. + class AbstractSocketWriter { + public: + virtual ~AbstractSocketWriter() {} + + // Sends a string to the socket. + virtual void Send(const string& message) = 0; + + // Closes the socket. + virtual void CloseConnection() {} + + // Sends a string and a newline to the socket. + void SendLn(const string& message) { + Send(message + "\n"); + } + }; + + // Concrete class for actually writing strings to a socket. + class SocketWriter : public AbstractSocketWriter { + public: + SocketWriter(const string& host, const string& port) + : sockfd_(-1), host_name_(host), port_num_(port) { + MakeConnection(); + } + + virtual ~SocketWriter() { + if (sockfd_ != -1) + CloseConnection(); + } + + // Sends a string to the socket. + virtual void Send(const string& message) { + GTEST_CHECK_(sockfd_ != -1) + << "Send() can be called only when there is a connection."; + + const int len = static_cast(message.length()); + if (write(sockfd_, message.c_str(), len) != len) { + GTEST_LOG_(WARNING) + << "stream_result_to: failed to stream to " + << host_name_ << ":" << port_num_; + } + } + + private: + // Creates a client socket and connects to the server. + void MakeConnection(); + + // Closes the socket. + void CloseConnection() { + GTEST_CHECK_(sockfd_ != -1) + << "CloseConnection() can be called only when there is a connection."; + + close(sockfd_); + sockfd_ = -1; + } + + int sockfd_; // socket file descriptor + const string host_name_; + const string port_num_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(SocketWriter); + }; // class SocketWriter + + // Escapes '=', '&', '%', and '\n' characters in str as "%xx". + static string UrlEncode(const char* str); + + StreamingListener(const string& host, const string& port) + : socket_writer_(new SocketWriter(host, port)) { Start(); } + + explicit StreamingListener(AbstractSocketWriter* socket_writer) + : socket_writer_(socket_writer) { Start(); } + + void OnTestProgramStart(const UnitTest& /* unit_test */) { + SendLn("event=TestProgramStart"); + } + + void OnTestProgramEnd(const UnitTest& unit_test) { + // Note that Google Test current only report elapsed time for each + // test iteration, not for the entire test program. + SendLn("event=TestProgramEnd&passed=" + FormatBool(unit_test.Passed())); + + // Notify the streaming server to stop. + socket_writer_->CloseConnection(); + } + + void OnTestIterationStart(const UnitTest& /* unit_test */, int iteration) { + SendLn("event=TestIterationStart&iteration=" + + StreamableToString(iteration)); + } + + void OnTestIterationEnd(const UnitTest& unit_test, int /* iteration */) { + SendLn("event=TestIterationEnd&passed=" + + FormatBool(unit_test.Passed()) + "&elapsed_time=" + + StreamableToString(unit_test.elapsed_time()) + "ms"); + } + + void OnTestCaseStart(const TestCase& test_case) { + SendLn(std::string("event=TestCaseStart&name=") + test_case.name()); + } + + void OnTestCaseEnd(const TestCase& test_case) { + SendLn("event=TestCaseEnd&passed=" + FormatBool(test_case.Passed()) + + "&elapsed_time=" + StreamableToString(test_case.elapsed_time()) + + "ms"); + } + + void OnTestStart(const TestInfo& test_info) { + SendLn(std::string("event=TestStart&name=") + test_info.name()); + } + + void OnTestEnd(const TestInfo& test_info) { + SendLn("event=TestEnd&passed=" + + FormatBool((test_info.result())->Passed()) + + "&elapsed_time=" + + StreamableToString((test_info.result())->elapsed_time()) + "ms"); + } + + void OnTestPartResult(const TestPartResult& test_part_result) { + const char* file_name = test_part_result.file_name(); + if (file_name == NULL) + file_name = ""; + SendLn("event=TestPartResult&file=" + UrlEncode(file_name) + + "&line=" + StreamableToString(test_part_result.line_number()) + + "&message=" + UrlEncode(test_part_result.message())); + } + + private: + // Sends the given message and a newline to the socket. + void SendLn(const string& message) { socket_writer_->SendLn(message); } + + // Called at the start of streaming to notify the receiver what + // protocol we are using. + void Start() { SendLn("gtest_streaming_protocol_version=1.0"); } + + string FormatBool(bool value) { return value ? "1" : "0"; } + + const scoped_ptr socket_writer_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(StreamingListener); +}; // class StreamingListener + +#endif // GTEST_CAN_STREAM_RESULTS_ + +} // namespace internal +} // namespace testing + +#endif // GTEST_SRC_GTEST_INTERNAL_INL_H_ +#undef GTEST_IMPLEMENTATION_ + +#if GTEST_OS_WINDOWS +# define vsnprintf _vsnprintf +#endif // GTEST_OS_WINDOWS + +namespace testing { + +using internal::CountIf; +using internal::ForEach; +using internal::GetElementOr; +using internal::Shuffle; + +// Constants. + +// A test whose test case name or test name matches this filter is +// disabled and not run. +static const char kDisableTestFilter[] = "DISABLED_*:*/DISABLED_*"; + +// A test case whose name matches this filter is considered a death +// test case and will be run before test cases whose name doesn't +// match this filter. +static const char kDeathTestCaseFilter[] = "*DeathTest:*DeathTest/*"; + +// A test filter that matches everything. +static const char kUniversalFilter[] = "*"; + +// The default output file for XML output. +static const char kDefaultOutputFile[] = "test_detail.xml"; + +// The environment variable name for the test shard index. +static const char kTestShardIndex[] = "GTEST_SHARD_INDEX"; +// The environment variable name for the total number of test shards. +static const char kTestTotalShards[] = "GTEST_TOTAL_SHARDS"; +// The environment variable name for the test shard status file. +static const char kTestShardStatusFile[] = "GTEST_SHARD_STATUS_FILE"; + +namespace internal { + +// The text used in failure messages to indicate the start of the +// stack trace. +const char kStackTraceMarker[] = "\nStack trace:\n"; + +// g_help_flag is true iff the --help flag or an equivalent form is +// specified on the command line. +bool g_help_flag = false; + +} // namespace internal + +static const char* GetDefaultFilter() { + return kUniversalFilter; +} + +GTEST_DEFINE_bool_( + also_run_disabled_tests, + internal::BoolFromGTestEnv("also_run_disabled_tests", false), + "Run disabled tests too, in addition to the tests normally being run."); + +GTEST_DEFINE_bool_( + break_on_failure, + internal::BoolFromGTestEnv("break_on_failure", false), + "True iff a failed assertion should be a debugger break-point."); + +GTEST_DEFINE_bool_( + catch_exceptions, + internal::BoolFromGTestEnv("catch_exceptions", true), + "True iff " GTEST_NAME_ + " should catch exceptions and treat them as test failures."); + +GTEST_DEFINE_string_( + color, + internal::StringFromGTestEnv("color", "auto"), + "Whether to use colors in the output. Valid values: yes, no, " + "and auto. 'auto' means to use colors if the output is " + "being sent to a terminal and the TERM environment variable " + "is set to a terminal type that supports colors."); + +GTEST_DEFINE_string_( + filter, + internal::StringFromGTestEnv("filter", GetDefaultFilter()), + "A colon-separated list of glob (not regex) patterns " + "for filtering the tests to run, optionally followed by a " + "'-' and a : separated list of negative patterns (tests to " + "exclude). A test is run if it matches one of the positive " + "patterns and does not match any of the negative patterns."); + +GTEST_DEFINE_bool_(list_tests, false, + "List all tests without running them."); + +GTEST_DEFINE_string_( + output, + internal::StringFromGTestEnv("output", ""), + "A format (currently must be \"xml\"), optionally followed " + "by a colon and an output file name or directory. A directory " + "is indicated by a trailing pathname separator. " + "Examples: \"xml:filename.xml\", \"xml::directoryname/\". " + "If a directory is specified, output files will be created " + "within that directory, with file-names based on the test " + "executable's name and, if necessary, made unique by adding " + "digits."); + +GTEST_DEFINE_bool_( + print_time, + internal::BoolFromGTestEnv("print_time", true), + "True iff " GTEST_NAME_ + " should display elapsed time in text output."); + +GTEST_DEFINE_int32_( + random_seed, + internal::Int32FromGTestEnv("random_seed", 0), + "Random number seed to use when shuffling test orders. Must be in range " + "[1, 99999], or 0 to use a seed based on the current time."); + +GTEST_DEFINE_int32_( + repeat, + internal::Int32FromGTestEnv("repeat", 1), + "How many times to repeat each test. Specify a negative number " + "for repeating forever. Useful for shaking out flaky tests."); + +GTEST_DEFINE_bool_( + show_internal_stack_frames, false, + "True iff " GTEST_NAME_ " should include internal stack frames when " + "printing test failure stack traces."); + +GTEST_DEFINE_bool_( + shuffle, + internal::BoolFromGTestEnv("shuffle", false), + "True iff " GTEST_NAME_ + " should randomize tests' order on every run."); + +GTEST_DEFINE_int32_( + stack_trace_depth, + internal::Int32FromGTestEnv("stack_trace_depth", kMaxStackTraceDepth), + "The maximum number of stack frames to print when an " + "assertion fails. The valid range is 0 through 100, inclusive."); + +GTEST_DEFINE_string_( + stream_result_to, + internal::StringFromGTestEnv("stream_result_to", ""), + "This flag specifies the host name and the port number on which to stream " + "test results. Example: \"localhost:555\". The flag is effective only on " + "Linux."); + +GTEST_DEFINE_bool_( + throw_on_failure, + internal::BoolFromGTestEnv("throw_on_failure", false), + "When this flag is specified, a failed assertion will throw an exception " + "if exceptions are enabled or exit the program with a non-zero code " + "otherwise."); + +namespace internal { + +// Generates a random number from [0, range), using a Linear +// Congruential Generator (LCG). Crashes if 'range' is 0 or greater +// than kMaxRange. +UInt32 Random::Generate(UInt32 range) { + // These constants are the same as are used in glibc's rand(3). + state_ = (1103515245U*state_ + 12345U) % kMaxRange; + + GTEST_CHECK_(range > 0) + << "Cannot generate a number in the range [0, 0)."; + GTEST_CHECK_(range <= kMaxRange) + << "Generation of a number in [0, " << range << ") was requested, " + << "but this can only generate numbers in [0, " << kMaxRange << ")."; + + // Converting via modulus introduces a bit of downward bias, but + // it's simple, and a linear congruential generator isn't too good + // to begin with. + return state_ % range; +} + +// GTestIsInitialized() returns true iff the user has initialized +// Google Test. Useful for catching the user mistake of not initializing +// Google Test before calling RUN_ALL_TESTS(). +// +// A user must call testing::InitGoogleTest() to initialize Google +// Test. g_init_gtest_count is set to the number of times +// InitGoogleTest() has been called. We don't protect this variable +// under a mutex as it is only accessed in the main thread. +GTEST_API_ int g_init_gtest_count = 0; +static bool GTestIsInitialized() { return g_init_gtest_count != 0; } + +// Iterates over a vector of TestCases, keeping a running sum of the +// results of calling a given int-returning method on each. +// Returns the sum. +static int SumOverTestCaseList(const std::vector& case_list, + int (TestCase::*method)() const) { + int sum = 0; + for (size_t i = 0; i < case_list.size(); i++) { + sum += (case_list[i]->*method)(); + } + return sum; +} + +// Returns true iff the test case passed. +static bool TestCasePassed(const TestCase* test_case) { + return test_case->should_run() && test_case->Passed(); +} + +// Returns true iff the test case failed. +static bool TestCaseFailed(const TestCase* test_case) { + return test_case->should_run() && test_case->Failed(); +} + +// Returns true iff test_case contains at least one test that should +// run. +static bool ShouldRunTestCase(const TestCase* test_case) { + return test_case->should_run(); +} + +// AssertHelper constructor. +AssertHelper::AssertHelper(TestPartResult::Type type, + const char* file, + int line, + const char* message) + : data_(new AssertHelperData(type, file, line, message)) { +} + +AssertHelper::~AssertHelper() { + delete data_; +} + +// Message assignment, for assertion streaming support. +void AssertHelper::operator=(const Message& message) const { + UnitTest::GetInstance()-> + AddTestPartResult(data_->type, data_->file, data_->line, + AppendUserMessage(data_->message, message), + UnitTest::GetInstance()->impl() + ->CurrentOsStackTraceExceptTop(1) + // Skips the stack frame for this function itself. + ); // NOLINT +} + +// Mutex for linked pointers. +GTEST_API_ GTEST_DEFINE_STATIC_MUTEX_(g_linked_ptr_mutex); + +// Application pathname gotten in InitGoogleTest. +std::string g_executable_path; + +// Returns the current application's name, removing directory path if that +// is present. +FilePath GetCurrentExecutableName() { + FilePath result; + +#if GTEST_OS_WINDOWS + result.Set(FilePath(g_executable_path).RemoveExtension("exe")); +#else + result.Set(FilePath(g_executable_path)); +#endif // GTEST_OS_WINDOWS + + return result.RemoveDirectoryName(); +} + +// Functions for processing the gtest_output flag. + +// Returns the output format, or "" for normal printed output. +std::string UnitTestOptions::GetOutputFormat() { + const char* const gtest_output_flag = GTEST_FLAG(output).c_str(); + if (gtest_output_flag == NULL) return std::string(""); + + const char* const colon = strchr(gtest_output_flag, ':'); + return (colon == NULL) ? + std::string(gtest_output_flag) : + std::string(gtest_output_flag, colon - gtest_output_flag); +} + +// Returns the name of the requested output file, or the default if none +// was explicitly specified. +std::string UnitTestOptions::GetAbsolutePathToOutputFile() { + const char* const gtest_output_flag = GTEST_FLAG(output).c_str(); + if (gtest_output_flag == NULL) + return ""; + + const char* const colon = strchr(gtest_output_flag, ':'); + if (colon == NULL) + return internal::FilePath::ConcatPaths( + internal::FilePath( + UnitTest::GetInstance()->original_working_dir()), + internal::FilePath(kDefaultOutputFile)).string(); + + internal::FilePath output_name(colon + 1); + if (!output_name.IsAbsolutePath()) + // TODO(wan@google.com): on Windows \some\path is not an absolute + // path (as its meaning depends on the current drive), yet the + // following logic for turning it into an absolute path is wrong. + // Fix it. + output_name = internal::FilePath::ConcatPaths( + internal::FilePath(UnitTest::GetInstance()->original_working_dir()), + internal::FilePath(colon + 1)); + + if (!output_name.IsDirectory()) + return output_name.string(); + + internal::FilePath result(internal::FilePath::GenerateUniqueFileName( + output_name, internal::GetCurrentExecutableName(), + GetOutputFormat().c_str())); + return result.string(); +} + +// Returns true iff the wildcard pattern matches the string. The +// first ':' or '\0' character in pattern marks the end of it. +// +// This recursive algorithm isn't very efficient, but is clear and +// works well enough for matching test names, which are short. +bool UnitTestOptions::PatternMatchesString(const char *pattern, + const char *str) { + switch (*pattern) { + case '\0': + case ':': // Either ':' or '\0' marks the end of the pattern. + return *str == '\0'; + case '?': // Matches any single character. + return *str != '\0' && PatternMatchesString(pattern + 1, str + 1); + case '*': // Matches any string (possibly empty) of characters. + return (*str != '\0' && PatternMatchesString(pattern, str + 1)) || + PatternMatchesString(pattern + 1, str); + default: // Non-special character. Matches itself. + return *pattern == *str && + PatternMatchesString(pattern + 1, str + 1); + } +} + +bool UnitTestOptions::MatchesFilter( + const std::string& name, const char* filter) { + const char *cur_pattern = filter; + for (;;) { + if (PatternMatchesString(cur_pattern, name.c_str())) { + return true; + } + + // Finds the next pattern in the filter. + cur_pattern = strchr(cur_pattern, ':'); + + // Returns if no more pattern can be found. + if (cur_pattern == NULL) { + return false; + } + + // Skips the pattern separater (the ':' character). + cur_pattern++; + } +} + +// Returns true iff the user-specified filter matches the test case +// name and the test name. +bool UnitTestOptions::FilterMatchesTest(const std::string &test_case_name, + const std::string &test_name) { + const std::string& full_name = test_case_name + "." + test_name.c_str(); + + // Split --gtest_filter at '-', if there is one, to separate into + // positive filter and negative filter portions + const char* const p = GTEST_FLAG(filter).c_str(); + const char* const dash = strchr(p, '-'); + std::string positive; + std::string negative; + if (dash == NULL) { + positive = GTEST_FLAG(filter).c_str(); // Whole string is a positive filter + negative = ""; + } else { + positive = std::string(p, dash); // Everything up to the dash + negative = std::string(dash + 1); // Everything after the dash + if (positive.empty()) { + // Treat '-test1' as the same as '*-test1' + positive = kUniversalFilter; + } + } + + // A filter is a colon-separated list of patterns. It matches a + // test if any pattern in it matches the test. + return (MatchesFilter(full_name, positive.c_str()) && + !MatchesFilter(full_name, negative.c_str())); +} + +#if GTEST_HAS_SEH +// Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the +// given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise. +// This function is useful as an __except condition. +int UnitTestOptions::GTestShouldProcessSEH(DWORD exception_code) { + // Google Test should handle a SEH exception if: + // 1. the user wants it to, AND + // 2. this is not a breakpoint exception, AND + // 3. this is not a C++ exception (VC++ implements them via SEH, + // apparently). + // + // SEH exception code for C++ exceptions. + // (see http://support.microsoft.com/kb/185294 for more information). + const DWORD kCxxExceptionCode = 0xe06d7363; + + bool should_handle = true; + + if (!GTEST_FLAG(catch_exceptions)) + should_handle = false; + else if (exception_code == EXCEPTION_BREAKPOINT) + should_handle = false; + else if (exception_code == kCxxExceptionCode) + should_handle = false; + + return should_handle ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH; +} +#endif // GTEST_HAS_SEH + +} // namespace internal + +// The c'tor sets this object as the test part result reporter used by +// Google Test. The 'result' parameter specifies where to report the +// results. Intercepts only failures from the current thread. +ScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter( + TestPartResultArray* result) + : intercept_mode_(INTERCEPT_ONLY_CURRENT_THREAD), + result_(result) { + Init(); +} + +// The c'tor sets this object as the test part result reporter used by +// Google Test. The 'result' parameter specifies where to report the +// results. +ScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter( + InterceptMode intercept_mode, TestPartResultArray* result) + : intercept_mode_(intercept_mode), + result_(result) { + Init(); +} + +void ScopedFakeTestPartResultReporter::Init() { + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + if (intercept_mode_ == INTERCEPT_ALL_THREADS) { + old_reporter_ = impl->GetGlobalTestPartResultReporter(); + impl->SetGlobalTestPartResultReporter(this); + } else { + old_reporter_ = impl->GetTestPartResultReporterForCurrentThread(); + impl->SetTestPartResultReporterForCurrentThread(this); + } +} + +// The d'tor restores the test part result reporter used by Google Test +// before. +ScopedFakeTestPartResultReporter::~ScopedFakeTestPartResultReporter() { + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + if (intercept_mode_ == INTERCEPT_ALL_THREADS) { + impl->SetGlobalTestPartResultReporter(old_reporter_); + } else { + impl->SetTestPartResultReporterForCurrentThread(old_reporter_); + } +} + +// Increments the test part result count and remembers the result. +// This method is from the TestPartResultReporterInterface interface. +void ScopedFakeTestPartResultReporter::ReportTestPartResult( + const TestPartResult& result) { + result_->Append(result); +} + +namespace internal { + +// Returns the type ID of ::testing::Test. We should always call this +// instead of GetTypeId< ::testing::Test>() to get the type ID of +// testing::Test. This is to work around a suspected linker bug when +// using Google Test as a framework on Mac OS X. The bug causes +// GetTypeId< ::testing::Test>() to return different values depending +// on whether the call is from the Google Test framework itself or +// from user test code. GetTestTypeId() is guaranteed to always +// return the same value, as it always calls GetTypeId<>() from the +// gtest.cc, which is within the Google Test framework. +TypeId GetTestTypeId() { + return GetTypeId(); +} + +// The value of GetTestTypeId() as seen from within the Google Test +// library. This is solely for testing GetTestTypeId(). +extern const TypeId kTestTypeIdInGoogleTest = GetTestTypeId(); + +// This predicate-formatter checks that 'results' contains a test part +// failure of the given type and that the failure message contains the +// given substring. +AssertionResult HasOneFailure(const char* /* results_expr */, + const char* /* type_expr */, + const char* /* substr_expr */, + const TestPartResultArray& results, + TestPartResult::Type type, + const string& substr) { + const std::string expected(type == TestPartResult::kFatalFailure ? + "1 fatal failure" : + "1 non-fatal failure"); + Message msg; + if (results.size() != 1) { + msg << "Expected: " << expected << "\n" + << " Actual: " << results.size() << " failures"; + for (int i = 0; i < results.size(); i++) { + msg << "\n" << results.GetTestPartResult(i); + } + return AssertionFailure() << msg; + } + + const TestPartResult& r = results.GetTestPartResult(0); + if (r.type() != type) { + return AssertionFailure() << "Expected: " << expected << "\n" + << " Actual:\n" + << r; + } + + if (strstr(r.message(), substr.c_str()) == NULL) { + return AssertionFailure() << "Expected: " << expected << " containing \"" + << substr << "\"\n" + << " Actual:\n" + << r; + } + + return AssertionSuccess(); +} + +// The constructor of SingleFailureChecker remembers where to look up +// test part results, what type of failure we expect, and what +// substring the failure message should contain. +SingleFailureChecker:: SingleFailureChecker( + const TestPartResultArray* results, + TestPartResult::Type type, + const string& substr) + : results_(results), + type_(type), + substr_(substr) {} + +// The destructor of SingleFailureChecker verifies that the given +// TestPartResultArray contains exactly one failure that has the given +// type and contains the given substring. If that's not the case, a +// non-fatal failure will be generated. +SingleFailureChecker::~SingleFailureChecker() { + EXPECT_PRED_FORMAT3(HasOneFailure, *results_, type_, substr_); +} + +DefaultGlobalTestPartResultReporter::DefaultGlobalTestPartResultReporter( + UnitTestImpl* unit_test) : unit_test_(unit_test) {} + +void DefaultGlobalTestPartResultReporter::ReportTestPartResult( + const TestPartResult& result) { + unit_test_->current_test_result()->AddTestPartResult(result); + unit_test_->listeners()->repeater()->OnTestPartResult(result); +} + +DefaultPerThreadTestPartResultReporter::DefaultPerThreadTestPartResultReporter( + UnitTestImpl* unit_test) : unit_test_(unit_test) {} + +void DefaultPerThreadTestPartResultReporter::ReportTestPartResult( + const TestPartResult& result) { + unit_test_->GetGlobalTestPartResultReporter()->ReportTestPartResult(result); +} + +// Returns the global test part result reporter. +TestPartResultReporterInterface* +UnitTestImpl::GetGlobalTestPartResultReporter() { + internal::MutexLock lock(&global_test_part_result_reporter_mutex_); + return global_test_part_result_repoter_; +} + +// Sets the global test part result reporter. +void UnitTestImpl::SetGlobalTestPartResultReporter( + TestPartResultReporterInterface* reporter) { + internal::MutexLock lock(&global_test_part_result_reporter_mutex_); + global_test_part_result_repoter_ = reporter; +} + +// Returns the test part result reporter for the current thread. +TestPartResultReporterInterface* +UnitTestImpl::GetTestPartResultReporterForCurrentThread() { + return per_thread_test_part_result_reporter_.get(); +} + +// Sets the test part result reporter for the current thread. +void UnitTestImpl::SetTestPartResultReporterForCurrentThread( + TestPartResultReporterInterface* reporter) { + per_thread_test_part_result_reporter_.set(reporter); +} + +// Gets the number of successful test cases. +int UnitTestImpl::successful_test_case_count() const { + return CountIf(test_cases_, TestCasePassed); +} + +// Gets the number of failed test cases. +int UnitTestImpl::failed_test_case_count() const { + return CountIf(test_cases_, TestCaseFailed); +} + +// Gets the number of all test cases. +int UnitTestImpl::total_test_case_count() const { + return static_cast(test_cases_.size()); +} + +// Gets the number of all test cases that contain at least one test +// that should run. +int UnitTestImpl::test_case_to_run_count() const { + return CountIf(test_cases_, ShouldRunTestCase); +} + +// Gets the number of successful tests. +int UnitTestImpl::successful_test_count() const { + return SumOverTestCaseList(test_cases_, &TestCase::successful_test_count); +} + +// Gets the number of failed tests. +int UnitTestImpl::failed_test_count() const { + return SumOverTestCaseList(test_cases_, &TestCase::failed_test_count); +} + +// Gets the number of disabled tests that will be reported in the XML report. +int UnitTestImpl::reportable_disabled_test_count() const { + return SumOverTestCaseList(test_cases_, + &TestCase::reportable_disabled_test_count); +} + +// Gets the number of disabled tests. +int UnitTestImpl::disabled_test_count() const { + return SumOverTestCaseList(test_cases_, &TestCase::disabled_test_count); +} + +// Gets the number of tests to be printed in the XML report. +int UnitTestImpl::reportable_test_count() const { + return SumOverTestCaseList(test_cases_, &TestCase::reportable_test_count); +} + +// Gets the number of all tests. +int UnitTestImpl::total_test_count() const { + return SumOverTestCaseList(test_cases_, &TestCase::total_test_count); +} + +// Gets the number of tests that should run. +int UnitTestImpl::test_to_run_count() const { + return SumOverTestCaseList(test_cases_, &TestCase::test_to_run_count); +} + +// Returns the current OS stack trace as an std::string. +// +// The maximum number of stack frames to be included is specified by +// the gtest_stack_trace_depth flag. The skip_count parameter +// specifies the number of top frames to be skipped, which doesn't +// count against the number of frames to be included. +// +// For example, if Foo() calls Bar(), which in turn calls +// CurrentOsStackTraceExceptTop(1), Foo() will be included in the +// trace but Bar() and CurrentOsStackTraceExceptTop() won't. +std::string UnitTestImpl::CurrentOsStackTraceExceptTop(int skip_count) { + (void)skip_count; + return ""; +} + +// Returns the current time in milliseconds. +TimeInMillis GetTimeInMillis() { +#if GTEST_OS_WINDOWS_MOBILE || defined(__BORLANDC__) + // Difference between 1970-01-01 and 1601-01-01 in milliseconds. + // http://analogous.blogspot.com/2005/04/epoch.html + const TimeInMillis kJavaEpochToWinFileTimeDelta = + static_cast(116444736UL) * 100000UL; + const DWORD kTenthMicrosInMilliSecond = 10000; + + SYSTEMTIME now_systime; + FILETIME now_filetime; + ULARGE_INTEGER now_int64; + // TODO(kenton@google.com): Shouldn't this just use + // GetSystemTimeAsFileTime()? + GetSystemTime(&now_systime); + if (SystemTimeToFileTime(&now_systime, &now_filetime)) { + now_int64.LowPart = now_filetime.dwLowDateTime; + now_int64.HighPart = now_filetime.dwHighDateTime; + now_int64.QuadPart = (now_int64.QuadPart / kTenthMicrosInMilliSecond) - + kJavaEpochToWinFileTimeDelta; + return now_int64.QuadPart; + } + return 0; +#elif GTEST_OS_WINDOWS && !GTEST_HAS_GETTIMEOFDAY_ + __timeb64 now; + +# ifdef _MSC_VER + + // MSVC 8 deprecates _ftime64(), so we want to suppress warning 4996 + // (deprecated function) there. + // TODO(kenton@google.com): Use GetTickCount()? Or use + // SystemTimeToFileTime() +# pragma warning(push) // Saves the current warning state. +# pragma warning(disable:4996) // Temporarily disables warning 4996. + _ftime64(&now); +# pragma warning(pop) // Restores the warning state. +# else + + _ftime64(&now); + +# endif // _MSC_VER + + return static_cast(now.time) * 1000 + now.millitm; +#elif GTEST_HAS_GETTIMEOFDAY_ + struct timeval now; + gettimeofday(&now, NULL); + return static_cast(now.tv_sec) * 1000 + now.tv_usec / 1000; +#else +# error "Don't know how to get the current time on your system." +#endif +} + +// Utilities + +// class String. + +#if GTEST_OS_WINDOWS_MOBILE +// Creates a UTF-16 wide string from the given ANSI string, allocating +// memory using new. The caller is responsible for deleting the return +// value using delete[]. Returns the wide string, or NULL if the +// input is NULL. +LPCWSTR String::AnsiToUtf16(const char* ansi) { + if (!ansi) return NULL; + const int length = strlen(ansi); + const int unicode_length = + MultiByteToWideChar(CP_ACP, 0, ansi, length, + NULL, 0); + WCHAR* unicode = new WCHAR[unicode_length + 1]; + MultiByteToWideChar(CP_ACP, 0, ansi, length, + unicode, unicode_length); + unicode[unicode_length] = 0; + return unicode; +} + +// Creates an ANSI string from the given wide string, allocating +// memory using new. The caller is responsible for deleting the return +// value using delete[]. Returns the ANSI string, or NULL if the +// input is NULL. +const char* String::Utf16ToAnsi(LPCWSTR utf16_str) { + if (!utf16_str) return NULL; + const int ansi_length = + WideCharToMultiByte(CP_ACP, 0, utf16_str, -1, + NULL, 0, NULL, NULL); + char* ansi = new char[ansi_length + 1]; + WideCharToMultiByte(CP_ACP, 0, utf16_str, -1, + ansi, ansi_length, NULL, NULL); + ansi[ansi_length] = 0; + return ansi; +} + +#endif // GTEST_OS_WINDOWS_MOBILE + +// Compares two C strings. Returns true iff they have the same content. +// +// Unlike strcmp(), this function can handle NULL argument(s). A NULL +// C string is considered different to any non-NULL C string, +// including the empty string. +bool String::CStringEquals(const char * lhs, const char * rhs) { + if ( lhs == NULL ) return rhs == NULL; + + if ( rhs == NULL ) return false; + + return strcmp(lhs, rhs) == 0; +} + +#if GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING + +// Converts an array of wide chars to a narrow string using the UTF-8 +// encoding, and streams the result to the given Message object. +static void StreamWideCharsToMessage(const wchar_t* wstr, size_t length, + Message* msg) { + for (size_t i = 0; i != length; ) { // NOLINT + if (wstr[i] != L'\0') { + *msg << WideStringToUtf8(wstr + i, static_cast(length - i)); + while (i != length && wstr[i] != L'\0') + i++; + } else { + *msg << '\0'; + i++; + } + } +} + +#endif // GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING + +} // namespace internal + +// Constructs an empty Message. +// We allocate the stringstream separately because otherwise each use of +// ASSERT/EXPECT in a procedure adds over 200 bytes to the procedure's +// stack frame leading to huge stack frames in some cases; gcc does not reuse +// the stack space. +Message::Message() : ss_(new ::std::stringstream) { + // By default, we want there to be enough precision when printing + // a double to a Message. + *ss_ << std::setprecision(std::numeric_limits::digits10 + 2); +} + +// These two overloads allow streaming a wide C string to a Message +// using the UTF-8 encoding. +Message& Message::operator <<(const wchar_t* wide_c_str) { + return *this << internal::String::ShowWideCString(wide_c_str); +} +Message& Message::operator <<(wchar_t* wide_c_str) { + return *this << internal::String::ShowWideCString(wide_c_str); +} + +#if GTEST_HAS_STD_WSTRING +// Converts the given wide string to a narrow string using the UTF-8 +// encoding, and streams the result to this Message object. +Message& Message::operator <<(const ::std::wstring& wstr) { + internal::StreamWideCharsToMessage(wstr.c_str(), wstr.length(), this); + return *this; +} +#endif // GTEST_HAS_STD_WSTRING + +#if GTEST_HAS_GLOBAL_WSTRING +// Converts the given wide string to a narrow string using the UTF-8 +// encoding, and streams the result to this Message object. +Message& Message::operator <<(const ::wstring& wstr) { + internal::StreamWideCharsToMessage(wstr.c_str(), wstr.length(), this); + return *this; +} +#endif // GTEST_HAS_GLOBAL_WSTRING + +// Gets the text streamed to this object so far as an std::string. +// Each '\0' character in the buffer is replaced with "\\0". +std::string Message::GetString() const { + return internal::StringStreamToString(ss_.get()); +} + +// AssertionResult constructors. +// Used in EXPECT_TRUE/FALSE(assertion_result). +AssertionResult::AssertionResult(const AssertionResult& other) + : success_(other.success_), + message_(other.message_.get() != NULL ? + new ::std::string(*other.message_) : + static_cast< ::std::string*>(NULL)) { +} + +// Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE. +AssertionResult AssertionResult::operator!() const { + AssertionResult negation(!success_); + if (message_.get() != NULL) + negation << *message_; + return negation; +} + +// Makes a successful assertion result. +AssertionResult AssertionSuccess() { + return AssertionResult(true); +} + +// Makes a failed assertion result. +AssertionResult AssertionFailure() { + return AssertionResult(false); +} + +// Makes a failed assertion result with the given failure message. +// Deprecated; use AssertionFailure() << message. +AssertionResult AssertionFailure(const Message& message) { + return AssertionFailure() << message; +} + +namespace internal { + +// Constructs and returns the message for an equality assertion +// (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure. +// +// The first four parameters are the expressions used in the assertion +// and their values, as strings. For example, for ASSERT_EQ(foo, bar) +// where foo is 5 and bar is 6, we have: +// +// expected_expression: "foo" +// actual_expression: "bar" +// expected_value: "5" +// actual_value: "6" +// +// The ignoring_case parameter is true iff the assertion is a +// *_STRCASEEQ*. When it's true, the string " (ignoring case)" will +// be inserted into the message. +AssertionResult EqFailure(const char* expected_expression, + const char* actual_expression, + const std::string& expected_value, + const std::string& actual_value, + bool ignoring_case) { + Message msg; + msg << "Value of: " << actual_expression; + if (actual_value != actual_expression) { + msg << "\n Actual: " << actual_value; + } + + msg << "\nExpected: " << expected_expression; + if (ignoring_case) { + msg << " (ignoring case)"; + } + if (expected_value != expected_expression) { + msg << "\nWhich is: " << expected_value; + } + + return AssertionFailure() << msg; +} + +// Constructs a failure message for Boolean assertions such as EXPECT_TRUE. +std::string GetBoolAssertionFailureMessage( + const AssertionResult& assertion_result, + const char* expression_text, + const char* actual_predicate_value, + const char* expected_predicate_value) { + const char* actual_message = assertion_result.message(); + Message msg; + msg << "Value of: " << expression_text + << "\n Actual: " << actual_predicate_value; + if (actual_message[0] != '\0') + msg << " (" << actual_message << ")"; + msg << "\nExpected: " << expected_predicate_value; + return msg.GetString(); +} + +// Helper function for implementing ASSERT_NEAR. +AssertionResult DoubleNearPredFormat(const char* expr1, + const char* expr2, + const char* abs_error_expr, + double val1, + double val2, + double abs_error) { + const double diff = fabs(val1 - val2); + if (diff <= abs_error) return AssertionSuccess(); + + // TODO(wan): do not print the value of an expression if it's + // already a literal. + return AssertionFailure() + << "The difference between " << expr1 << " and " << expr2 + << " is " << diff << ", which exceeds " << abs_error_expr << ", where\n" + << expr1 << " evaluates to " << val1 << ",\n" + << expr2 << " evaluates to " << val2 << ", and\n" + << abs_error_expr << " evaluates to " << abs_error << "."; +} + + +// Helper template for implementing FloatLE() and DoubleLE(). +template +AssertionResult FloatingPointLE(const char* expr1, + const char* expr2, + RawType val1, + RawType val2) { + // Returns success if val1 is less than val2, + if (val1 < val2) { + return AssertionSuccess(); + } + + // or if val1 is almost equal to val2. + const FloatingPoint lhs(val1), rhs(val2); + if (lhs.AlmostEquals(rhs)) { + return AssertionSuccess(); + } + + // Note that the above two checks will both fail if either val1 or + // val2 is NaN, as the IEEE floating-point standard requires that + // any predicate involving a NaN must return false. + + ::std::stringstream val1_ss; + val1_ss << std::setprecision(std::numeric_limits::digits10 + 2) + << val1; + + ::std::stringstream val2_ss; + val2_ss << std::setprecision(std::numeric_limits::digits10 + 2) + << val2; + + return AssertionFailure() + << "Expected: (" << expr1 << ") <= (" << expr2 << ")\n" + << " Actual: " << StringStreamToString(&val1_ss) << " vs " + << StringStreamToString(&val2_ss); +} + +} // namespace internal + +// Asserts that val1 is less than, or almost equal to, val2. Fails +// otherwise. In particular, it fails if either val1 or val2 is NaN. +AssertionResult FloatLE(const char* expr1, const char* expr2, + float val1, float val2) { + return internal::FloatingPointLE(expr1, expr2, val1, val2); +} + +// Asserts that val1 is less than, or almost equal to, val2. Fails +// otherwise. In particular, it fails if either val1 or val2 is NaN. +AssertionResult DoubleLE(const char* expr1, const char* expr2, + double val1, double val2) { + return internal::FloatingPointLE(expr1, expr2, val1, val2); +} + +namespace internal { + +// The helper function for {ASSERT|EXPECT}_EQ with int or enum +// arguments. +AssertionResult CmpHelperEQ(const char* expected_expression, + const char* actual_expression, + BiggestInt expected, + BiggestInt actual) { + if (expected == actual) { + return AssertionSuccess(); + } + + return EqFailure(expected_expression, + actual_expression, + FormatForComparisonFailureMessage(expected, actual), + FormatForComparisonFailureMessage(actual, expected), + false); +} + +// A macro for implementing the helper functions needed to implement +// ASSERT_?? and EXPECT_?? with integer or enum arguments. It is here +// just to avoid copy-and-paste of similar code. +#define GTEST_IMPL_CMP_HELPER_(op_name, op)\ +AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \ + BiggestInt val1, BiggestInt val2) {\ + if (val1 op val2) {\ + return AssertionSuccess();\ + } else {\ + return AssertionFailure() \ + << "Expected: (" << expr1 << ") " #op " (" << expr2\ + << "), actual: " << FormatForComparisonFailureMessage(val1, val2)\ + << " vs " << FormatForComparisonFailureMessage(val2, val1);\ + }\ +} + +// Implements the helper function for {ASSERT|EXPECT}_NE with int or +// enum arguments. +GTEST_IMPL_CMP_HELPER_(NE, !=) +// Implements the helper function for {ASSERT|EXPECT}_LE with int or +// enum arguments. +GTEST_IMPL_CMP_HELPER_(LE, <=) +// Implements the helper function for {ASSERT|EXPECT}_LT with int or +// enum arguments. +GTEST_IMPL_CMP_HELPER_(LT, < ) +// Implements the helper function for {ASSERT|EXPECT}_GE with int or +// enum arguments. +GTEST_IMPL_CMP_HELPER_(GE, >=) +// Implements the helper function for {ASSERT|EXPECT}_GT with int or +// enum arguments. +GTEST_IMPL_CMP_HELPER_(GT, > ) + +#undef GTEST_IMPL_CMP_HELPER_ + +// The helper function for {ASSERT|EXPECT}_STREQ. +AssertionResult CmpHelperSTREQ(const char* expected_expression, + const char* actual_expression, + const char* expected, + const char* actual) { + if (String::CStringEquals(expected, actual)) { + return AssertionSuccess(); + } + + return EqFailure(expected_expression, + actual_expression, + PrintToString(expected), + PrintToString(actual), + false); +} + +// The helper function for {ASSERT|EXPECT}_STRCASEEQ. +AssertionResult CmpHelperSTRCASEEQ(const char* expected_expression, + const char* actual_expression, + const char* expected, + const char* actual) { + if (String::CaseInsensitiveCStringEquals(expected, actual)) { + return AssertionSuccess(); + } + + return EqFailure(expected_expression, + actual_expression, + PrintToString(expected), + PrintToString(actual), + true); +} + +// The helper function for {ASSERT|EXPECT}_STRNE. +AssertionResult CmpHelperSTRNE(const char* s1_expression, + const char* s2_expression, + const char* s1, + const char* s2) { + if (!String::CStringEquals(s1, s2)) { + return AssertionSuccess(); + } else { + return AssertionFailure() << "Expected: (" << s1_expression << ") != (" + << s2_expression << "), actual: \"" + << s1 << "\" vs \"" << s2 << "\""; + } +} + +// The helper function for {ASSERT|EXPECT}_STRCASENE. +AssertionResult CmpHelperSTRCASENE(const char* s1_expression, + const char* s2_expression, + const char* s1, + const char* s2) { + if (!String::CaseInsensitiveCStringEquals(s1, s2)) { + return AssertionSuccess(); + } else { + return AssertionFailure() + << "Expected: (" << s1_expression << ") != (" + << s2_expression << ") (ignoring case), actual: \"" + << s1 << "\" vs \"" << s2 << "\""; + } +} + +} // namespace internal + +namespace { + +// Helper functions for implementing IsSubString() and IsNotSubstring(). + +// This group of overloaded functions return true iff needle is a +// substring of haystack. NULL is considered a substring of itself +// only. + +bool IsSubstringPred(const char* needle, const char* haystack) { + if (needle == NULL || haystack == NULL) + return needle == haystack; + + return strstr(haystack, needle) != NULL; +} + +bool IsSubstringPred(const wchar_t* needle, const wchar_t* haystack) { + if (needle == NULL || haystack == NULL) + return needle == haystack; + + return wcsstr(haystack, needle) != NULL; +} + +// StringType here can be either ::std::string or ::std::wstring. +template +bool IsSubstringPred(const StringType& needle, + const StringType& haystack) { + return haystack.find(needle) != StringType::npos; +} + +// This function implements either IsSubstring() or IsNotSubstring(), +// depending on the value of the expected_to_be_substring parameter. +// StringType here can be const char*, const wchar_t*, ::std::string, +// or ::std::wstring. +template +AssertionResult IsSubstringImpl( + bool expected_to_be_substring, + const char* needle_expr, const char* haystack_expr, + const StringType& needle, const StringType& haystack) { + if (IsSubstringPred(needle, haystack) == expected_to_be_substring) + return AssertionSuccess(); + + const bool is_wide_string = sizeof(needle[0]) > 1; + const char* const begin_string_quote = is_wide_string ? "L\"" : "\""; + return AssertionFailure() + << "Value of: " << needle_expr << "\n" + << " Actual: " << begin_string_quote << needle << "\"\n" + << "Expected: " << (expected_to_be_substring ? "" : "not ") + << "a substring of " << haystack_expr << "\n" + << "Which is: " << begin_string_quote << haystack << "\""; +} + +} // namespace + +// IsSubstring() and IsNotSubstring() check whether needle is a +// substring of haystack (NULL is considered a substring of itself +// only), and return an appropriate error message when they fail. + +AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const char* needle, const char* haystack) { + return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const wchar_t* needle, const wchar_t* haystack) { + return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const char* needle, const char* haystack) { + return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const wchar_t* needle, const wchar_t* haystack) { + return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::string& needle, const ::std::string& haystack) { + return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::string& needle, const ::std::string& haystack) { + return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); +} + +#if GTEST_HAS_STD_WSTRING +AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::wstring& needle, const ::std::wstring& haystack) { + return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::wstring& needle, const ::std::wstring& haystack) { + return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); +} +#endif // GTEST_HAS_STD_WSTRING + +namespace internal { + +#if GTEST_OS_WINDOWS + +namespace { + +// Helper function for IsHRESULT{SuccessFailure} predicates +AssertionResult HRESULTFailureHelper(const char* expr, + const char* expected, + long hr) { // NOLINT +# if GTEST_OS_WINDOWS_MOBILE + + // Windows CE doesn't support FormatMessage. + const char error_text[] = ""; + +# else + + // Looks up the human-readable system message for the HRESULT code + // and since we're not passing any params to FormatMessage, we don't + // want inserts expanded. + const DWORD kFlags = FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS; + const DWORD kBufSize = 4096; + // Gets the system's human readable message string for this HRESULT. + char error_text[kBufSize] = { '\0' }; + DWORD message_length = ::FormatMessageA(kFlags, + 0, // no source, we're asking system + hr, // the error + 0, // no line width restrictions + error_text, // output buffer + kBufSize, // buf size + NULL); // no arguments for inserts + // Trims tailing white space (FormatMessage leaves a trailing CR-LF) + for (; message_length && IsSpace(error_text[message_length - 1]); + --message_length) { + error_text[message_length - 1] = '\0'; + } + +# endif // GTEST_OS_WINDOWS_MOBILE + + const std::string error_hex("0x" + String::FormatHexInt(hr)); + return ::testing::AssertionFailure() + << "Expected: " << expr << " " << expected << ".\n" + << " Actual: " << error_hex << " " << error_text << "\n"; +} + +} // namespace + +AssertionResult IsHRESULTSuccess(const char* expr, long hr) { // NOLINT + if (SUCCEEDED(hr)) { + return AssertionSuccess(); + } + return HRESULTFailureHelper(expr, "succeeds", hr); +} + +AssertionResult IsHRESULTFailure(const char* expr, long hr) { // NOLINT + if (FAILED(hr)) { + return AssertionSuccess(); + } + return HRESULTFailureHelper(expr, "fails", hr); +} + +#endif // GTEST_OS_WINDOWS + +// Utility functions for encoding Unicode text (wide strings) in +// UTF-8. + +// A Unicode code-point can have upto 21 bits, and is encoded in UTF-8 +// like this: +// +// Code-point length Encoding +// 0 - 7 bits 0xxxxxxx +// 8 - 11 bits 110xxxxx 10xxxxxx +// 12 - 16 bits 1110xxxx 10xxxxxx 10xxxxxx +// 17 - 21 bits 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + +// The maximum code-point a one-byte UTF-8 sequence can represent. +const UInt32 kMaxCodePoint1 = (static_cast(1) << 7) - 1; + +// The maximum code-point a two-byte UTF-8 sequence can represent. +const UInt32 kMaxCodePoint2 = (static_cast(1) << (5 + 6)) - 1; + +// The maximum code-point a three-byte UTF-8 sequence can represent. +const UInt32 kMaxCodePoint3 = (static_cast(1) << (4 + 2*6)) - 1; + +// The maximum code-point a four-byte UTF-8 sequence can represent. +const UInt32 kMaxCodePoint4 = (static_cast(1) << (3 + 3*6)) - 1; + +// Chops off the n lowest bits from a bit pattern. Returns the n +// lowest bits. As a side effect, the original bit pattern will be +// shifted to the right by n bits. +inline UInt32 ChopLowBits(UInt32* bits, int n) { + const UInt32 low_bits = *bits & ((static_cast(1) << n) - 1); + *bits >>= n; + return low_bits; +} + +// Converts a Unicode code point to a narrow string in UTF-8 encoding. +// code_point parameter is of type UInt32 because wchar_t may not be +// wide enough to contain a code point. +// If the code_point is not a valid Unicode code point +// (i.e. outside of Unicode range U+0 to U+10FFFF) it will be converted +// to "(Invalid Unicode 0xXXXXXXXX)". +std::string CodePointToUtf8(UInt32 code_point) { + if (code_point > kMaxCodePoint4) { + return "(Invalid Unicode 0x" + String::FormatHexInt(code_point) + ")"; + } + + char str[5]; // Big enough for the largest valid code point. + if (code_point <= kMaxCodePoint1) { + str[1] = '\0'; + str[0] = static_cast(code_point); // 0xxxxxxx + } else if (code_point <= kMaxCodePoint2) { + str[2] = '\0'; + str[1] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[0] = static_cast(0xC0 | code_point); // 110xxxxx + } else if (code_point <= kMaxCodePoint3) { + str[3] = '\0'; + str[2] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[1] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[0] = static_cast(0xE0 | code_point); // 1110xxxx + } else { // code_point <= kMaxCodePoint4 + str[4] = '\0'; + str[3] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[2] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[1] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[0] = static_cast(0xF0 | code_point); // 11110xxx + } + return str; +} + +// The following two functions only make sense if the the system +// uses UTF-16 for wide string encoding. All supported systems +// with 16 bit wchar_t (Windows, Cygwin, Symbian OS) do use UTF-16. + +// Determines if the arguments constitute UTF-16 surrogate pair +// and thus should be combined into a single Unicode code point +// using CreateCodePointFromUtf16SurrogatePair. +inline bool IsUtf16SurrogatePair(wchar_t first, wchar_t second) { + return sizeof(wchar_t) == 2 && + (first & 0xFC00) == 0xD800 && (second & 0xFC00) == 0xDC00; +} + +// Creates a Unicode code point from UTF16 surrogate pair. +inline UInt32 CreateCodePointFromUtf16SurrogatePair(wchar_t first, + wchar_t second) { + const UInt32 mask = (1 << 10) - 1; + return (sizeof(wchar_t) == 2) ? + (((first & mask) << 10) | (second & mask)) + 0x10000 : + // This function should not be called when the condition is + // false, but we provide a sensible default in case it is. + static_cast(first); +} + +// Converts a wide string to a narrow string in UTF-8 encoding. +// The wide string is assumed to have the following encoding: +// UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin, Symbian OS) +// UTF-32 if sizeof(wchar_t) == 4 (on Linux) +// Parameter str points to a null-terminated wide string. +// Parameter num_chars may additionally limit the number +// of wchar_t characters processed. -1 is used when the entire string +// should be processed. +// If the string contains code points that are not valid Unicode code points +// (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output +// as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding +// and contains invalid UTF-16 surrogate pairs, values in those pairs +// will be encoded as individual Unicode characters from Basic Normal Plane. +std::string WideStringToUtf8(const wchar_t* str, int num_chars) { + if (num_chars == -1) + num_chars = static_cast(wcslen(str)); + + ::std::stringstream stream; + for (int i = 0; i < num_chars; ++i) { + UInt32 unicode_code_point; + + if (str[i] == L'\0') { + break; + } else if (i + 1 < num_chars && IsUtf16SurrogatePair(str[i], str[i + 1])) { + unicode_code_point = CreateCodePointFromUtf16SurrogatePair(str[i], + str[i + 1]); + i++; + } else { + unicode_code_point = static_cast(str[i]); + } + + stream << CodePointToUtf8(unicode_code_point); + } + return StringStreamToString(&stream); +} + +// Converts a wide C string to an std::string using the UTF-8 encoding. +// NULL will be converted to "(null)". +std::string String::ShowWideCString(const wchar_t * wide_c_str) { + if (wide_c_str == NULL) return "(null)"; + + return internal::WideStringToUtf8(wide_c_str, -1); +} + +// Compares two wide C strings. Returns true iff they have the same +// content. +// +// Unlike wcscmp(), this function can handle NULL argument(s). A NULL +// C string is considered different to any non-NULL C string, +// including the empty string. +bool String::WideCStringEquals(const wchar_t * lhs, const wchar_t * rhs) { + if (lhs == NULL) return rhs == NULL; + + if (rhs == NULL) return false; + + return wcscmp(lhs, rhs) == 0; +} + +// Helper function for *_STREQ on wide strings. +AssertionResult CmpHelperSTREQ(const char* expected_expression, + const char* actual_expression, + const wchar_t* expected, + const wchar_t* actual) { + if (String::WideCStringEquals(expected, actual)) { + return AssertionSuccess(); + } + + return EqFailure(expected_expression, + actual_expression, + PrintToString(expected), + PrintToString(actual), + false); +} + +// Helper function for *_STRNE on wide strings. +AssertionResult CmpHelperSTRNE(const char* s1_expression, + const char* s2_expression, + const wchar_t* s1, + const wchar_t* s2) { + if (!String::WideCStringEquals(s1, s2)) { + return AssertionSuccess(); + } + + return AssertionFailure() << "Expected: (" << s1_expression << ") != (" + << s2_expression << "), actual: " + << PrintToString(s1) + << " vs " << PrintToString(s2); +} + +// Compares two C strings, ignoring case. Returns true iff they have +// the same content. +// +// Unlike strcasecmp(), this function can handle NULL argument(s). A +// NULL C string is considered different to any non-NULL C string, +// including the empty string. +bool String::CaseInsensitiveCStringEquals(const char * lhs, const char * rhs) { + if (lhs == NULL) + return rhs == NULL; + if (rhs == NULL) + return false; + return posix::StrCaseCmp(lhs, rhs) == 0; +} + + // Compares two wide C strings, ignoring case. Returns true iff they + // have the same content. + // + // Unlike wcscasecmp(), this function can handle NULL argument(s). + // A NULL C string is considered different to any non-NULL wide C string, + // including the empty string. + // NB: The implementations on different platforms slightly differ. + // On windows, this method uses _wcsicmp which compares according to LC_CTYPE + // environment variable. On GNU platform this method uses wcscasecmp + // which compares according to LC_CTYPE category of the current locale. + // On MacOS X, it uses towlower, which also uses LC_CTYPE category of the + // current locale. +bool String::CaseInsensitiveWideCStringEquals(const wchar_t* lhs, + const wchar_t* rhs) { + if (lhs == NULL) return rhs == NULL; + + if (rhs == NULL) return false; + +#if GTEST_OS_WINDOWS + return _wcsicmp(lhs, rhs) == 0; +#elif GTEST_OS_LINUX && !GTEST_OS_LINUX_ANDROID + return wcscasecmp(lhs, rhs) == 0; +#else + // Android, Mac OS X and Cygwin don't define wcscasecmp. + // Other unknown OSes may not define it either. + wint_t left, right; + do { + left = towlower(*lhs++); + right = towlower(*rhs++); + } while (left && left == right); + return left == right; +#endif // OS selector +} + +// Returns true iff str ends with the given suffix, ignoring case. +// Any string is considered to end with an empty suffix. +bool String::EndsWithCaseInsensitive( + const std::string& str, const std::string& suffix) { + const size_t str_len = str.length(); + const size_t suffix_len = suffix.length(); + return (str_len >= suffix_len) && + CaseInsensitiveCStringEquals(str.c_str() + str_len - suffix_len, + suffix.c_str()); +} + +// Formats an int value as "%02d". +std::string String::FormatIntWidth2(int value) { + std::stringstream ss; + ss << std::setfill('0') << std::setw(2) << value; + return ss.str(); +} + +// Formats an int value as "%X". +std::string String::FormatHexInt(int value) { + std::stringstream ss; + ss << std::hex << std::uppercase << value; + return ss.str(); +} + +// Formats a byte as "%02X". +std::string String::FormatByte(unsigned char value) { + std::stringstream ss; + ss << std::setfill('0') << std::setw(2) << std::hex << std::uppercase + << static_cast(value); + return ss.str(); +} + +// Converts the buffer in a stringstream to an std::string, converting NUL +// bytes to "\\0" along the way. +std::string StringStreamToString(::std::stringstream* ss) { + const ::std::string& str = ss->str(); + const char* const start = str.c_str(); + const char* const end = start + str.length(); + + std::string result; + result.reserve(2 * (end - start)); + for (const char* ch = start; ch != end; ++ch) { + if (*ch == '\0') { + result += "\\0"; // Replaces NUL with "\\0"; + } else { + result += *ch; + } + } + + return result; +} + +// Appends the user-supplied message to the Google-Test-generated message. +std::string AppendUserMessage(const std::string& gtest_msg, + const Message& user_msg) { + // Appends the user message if it's non-empty. + const std::string user_msg_string = user_msg.GetString(); + if (user_msg_string.empty()) { + return gtest_msg; + } + + return gtest_msg + "\n" + user_msg_string; +} + +} // namespace internal + +// class TestResult + +// Creates an empty TestResult. +TestResult::TestResult() + : death_test_count_(0), + elapsed_time_(0) { +} + +// D'tor. +TestResult::~TestResult() { +} + +// Returns the i-th test part result among all the results. i can +// range from 0 to total_part_count() - 1. If i is not in that range, +// aborts the program. +const TestPartResult& TestResult::GetTestPartResult(int i) const { + if (i < 0 || i >= total_part_count()) + internal::posix::Abort(); + return test_part_results_.at(i); +} + +// Returns the i-th test property. i can range from 0 to +// test_property_count() - 1. If i is not in that range, aborts the +// program. +const TestProperty& TestResult::GetTestProperty(int i) const { + if (i < 0 || i >= test_property_count()) + internal::posix::Abort(); + return test_properties_.at(i); +} + +// Clears the test part results. +void TestResult::ClearTestPartResults() { + test_part_results_.clear(); +} + +// Adds a test part result to the list. +void TestResult::AddTestPartResult(const TestPartResult& test_part_result) { + test_part_results_.push_back(test_part_result); +} + +// Adds a test property to the list. If a property with the same key as the +// supplied property is already represented, the value of this test_property +// replaces the old value for that key. +void TestResult::RecordProperty(const std::string& xml_element, + const TestProperty& test_property) { + if (!ValidateTestProperty(xml_element, test_property)) { + return; + } + internal::MutexLock lock(&test_properites_mutex_); + const std::vector::iterator property_with_matching_key = + std::find_if(test_properties_.begin(), test_properties_.end(), + internal::TestPropertyKeyIs(test_property.key())); + if (property_with_matching_key == test_properties_.end()) { + test_properties_.push_back(test_property); + return; + } + property_with_matching_key->SetValue(test_property.value()); +} + +// The list of reserved attributes used in the element of XML +// output. +static const char* const kReservedTestSuitesAttributes[] = { + "disabled", + "errors", + "failures", + "name", + "random_seed", + "tests", + "time", + "timestamp" +}; + +// The list of reserved attributes used in the element of XML +// output. +static const char* const kReservedTestSuiteAttributes[] = { + "disabled", + "errors", + "failures", + "name", + "tests", + "time" +}; + +// The list of reserved attributes used in the element of XML output. +static const char* const kReservedTestCaseAttributes[] = { + "classname", + "name", + "status", + "time", + "type_param", + "value_param" +}; + +template +std::vector ArrayAsVector(const char* const (&array)[kSize]) { + return std::vector(array, array + kSize); +} + +static std::vector GetReservedAttributesForElement( + const std::string& xml_element) { + if (xml_element == "testsuites") { + return ArrayAsVector(kReservedTestSuitesAttributes); + } else if (xml_element == "testsuite") { + return ArrayAsVector(kReservedTestSuiteAttributes); + } else if (xml_element == "testcase") { + return ArrayAsVector(kReservedTestCaseAttributes); + } else { + GTEST_CHECK_(false) << "Unrecognized xml_element provided: " << xml_element; + } + // This code is unreachable but some compilers may not realizes that. + return std::vector(); +} + +static std::string FormatWordList(const std::vector& words) { + Message word_list; + for (size_t i = 0; i < words.size(); ++i) { + if (i > 0 && words.size() > 2) { + word_list << ", "; + } + if (i == words.size() - 1) { + word_list << "and "; + } + word_list << "'" << words[i] << "'"; + } + return word_list.GetString(); +} + +bool ValidateTestPropertyName(const std::string& property_name, + const std::vector& reserved_names) { + if (std::find(reserved_names.begin(), reserved_names.end(), property_name) != + reserved_names.end()) { + ADD_FAILURE() << "Reserved key used in RecordProperty(): " << property_name + << " (" << FormatWordList(reserved_names) + << " are reserved by " << GTEST_NAME_ << ")"; + return false; + } + return true; +} + +// Adds a failure if the key is a reserved attribute of the element named +// xml_element. Returns true if the property is valid. +bool TestResult::ValidateTestProperty(const std::string& xml_element, + const TestProperty& test_property) { + return ValidateTestPropertyName(test_property.key(), + GetReservedAttributesForElement(xml_element)); +} + +// Clears the object. +void TestResult::Clear() { + test_part_results_.clear(); + test_properties_.clear(); + death_test_count_ = 0; + elapsed_time_ = 0; +} + +// Returns true iff the test failed. +bool TestResult::Failed() const { + for (int i = 0; i < total_part_count(); ++i) { + if (GetTestPartResult(i).failed()) + return true; + } + return false; +} + +// Returns true iff the test part fatally failed. +static bool TestPartFatallyFailed(const TestPartResult& result) { + return result.fatally_failed(); +} + +// Returns true iff the test fatally failed. +bool TestResult::HasFatalFailure() const { + return CountIf(test_part_results_, TestPartFatallyFailed) > 0; +} + +// Returns true iff the test part non-fatally failed. +static bool TestPartNonfatallyFailed(const TestPartResult& result) { + return result.nonfatally_failed(); +} + +// Returns true iff the test has a non-fatal failure. +bool TestResult::HasNonfatalFailure() const { + return CountIf(test_part_results_, TestPartNonfatallyFailed) > 0; +} + +// Gets the number of all test parts. This is the sum of the number +// of successful test parts and the number of failed test parts. +int TestResult::total_part_count() const { + return static_cast(test_part_results_.size()); +} + +// Returns the number of the test properties. +int TestResult::test_property_count() const { + return static_cast(test_properties_.size()); +} + +// class Test + +// Creates a Test object. + +// The c'tor saves the values of all Google Test flags. +Test::Test() + : gtest_flag_saver_(new internal::GTestFlagSaver) { +} + +// The d'tor restores the values of all Google Test flags. +Test::~Test() { + delete gtest_flag_saver_; +} + +// Sets up the test fixture. +// +// A sub-class may override this. +void Test::SetUp() { +} + +// Tears down the test fixture. +// +// A sub-class may override this. +void Test::TearDown() { +} + +// Allows user supplied key value pairs to be recorded for later output. +void Test::RecordProperty(const std::string& key, const std::string& value) { + UnitTest::GetInstance()->RecordProperty(key, value); +} + +// Allows user supplied key value pairs to be recorded for later output. +void Test::RecordProperty(const std::string& key, int value) { + Message value_message; + value_message << value; + RecordProperty(key, value_message.GetString().c_str()); +} + +namespace internal { + +void ReportFailureInUnknownLocation(TestPartResult::Type result_type, + const std::string& message) { + // This function is a friend of UnitTest and as such has access to + // AddTestPartResult. + UnitTest::GetInstance()->AddTestPartResult( + result_type, + NULL, // No info about the source file where the exception occurred. + -1, // We have no info on which line caused the exception. + message, + ""); // No stack trace, either. +} + +} // namespace internal + +// Google Test requires all tests in the same test case to use the same test +// fixture class. This function checks if the current test has the +// same fixture class as the first test in the current test case. If +// yes, it returns true; otherwise it generates a Google Test failure and +// returns false. +bool Test::HasSameFixtureClass() { + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + const TestCase* const test_case = impl->current_test_case(); + + // Info about the first test in the current test case. + const TestInfo* const first_test_info = test_case->test_info_list()[0]; + const internal::TypeId first_fixture_id = first_test_info->fixture_class_id_; + const char* const first_test_name = first_test_info->name(); + + // Info about the current test. + const TestInfo* const this_test_info = impl->current_test_info(); + const internal::TypeId this_fixture_id = this_test_info->fixture_class_id_; + const char* const this_test_name = this_test_info->name(); + + if (this_fixture_id != first_fixture_id) { + // Is the first test defined using TEST? + const bool first_is_TEST = first_fixture_id == internal::GetTestTypeId(); + // Is this test defined using TEST? + const bool this_is_TEST = this_fixture_id == internal::GetTestTypeId(); + + if (first_is_TEST || this_is_TEST) { + // The user mixed TEST and TEST_F in this test case - we'll tell + // him/her how to fix it. + + // Gets the name of the TEST and the name of the TEST_F. Note + // that first_is_TEST and this_is_TEST cannot both be true, as + // the fixture IDs are different for the two tests. + const char* const TEST_name = + first_is_TEST ? first_test_name : this_test_name; + const char* const TEST_F_name = + first_is_TEST ? this_test_name : first_test_name; + + ADD_FAILURE() + << "All tests in the same test case must use the same test fixture\n" + << "class, so mixing TEST_F and TEST in the same test case is\n" + << "illegal. In test case " << this_test_info->test_case_name() + << ",\n" + << "test " << TEST_F_name << " is defined using TEST_F but\n" + << "test " << TEST_name << " is defined using TEST. You probably\n" + << "want to change the TEST to TEST_F or move it to another test\n" + << "case."; + } else { + // The user defined two fixture classes with the same name in + // two namespaces - we'll tell him/her how to fix it. + ADD_FAILURE() + << "All tests in the same test case must use the same test fixture\n" + << "class. However, in test case " + << this_test_info->test_case_name() << ",\n" + << "you defined test " << first_test_name + << " and test " << this_test_name << "\n" + << "using two different test fixture classes. This can happen if\n" + << "the two classes are from different namespaces or translation\n" + << "units and have the same name. You should probably rename one\n" + << "of the classes to put the tests into different test cases."; + } + return false; + } + + return true; +} + +#if GTEST_HAS_SEH + +// Adds an "exception thrown" fatal failure to the current test. This +// function returns its result via an output parameter pointer because VC++ +// prohibits creation of objects with destructors on stack in functions +// using __try (see error C2712). +static std::string* FormatSehExceptionMessage(DWORD exception_code, + const char* location) { + Message message; + message << "SEH exception with code 0x" << std::setbase(16) << + exception_code << std::setbase(10) << " thrown in " << location << "."; + + return new std::string(message.GetString()); +} + +#endif // GTEST_HAS_SEH + +namespace internal { + +#if GTEST_HAS_EXCEPTIONS + +// Adds an "exception thrown" fatal failure to the current test. +static std::string FormatCxxExceptionMessage(const char* description, + const char* location) { + Message message; + if (description != NULL) { + message << "C++ exception with description \"" << description << "\""; + } else { + message << "Unknown C++ exception"; + } + message << " thrown in " << location << "."; + + return message.GetString(); +} + +static std::string PrintTestPartResultToString( + const TestPartResult& test_part_result); + +GoogleTestFailureException::GoogleTestFailureException( + const TestPartResult& failure) + : ::std::runtime_error(PrintTestPartResultToString(failure).c_str()) {} + +#endif // GTEST_HAS_EXCEPTIONS + +// We put these helper functions in the internal namespace as IBM's xlC +// compiler rejects the code if they were declared static. + +// Runs the given method and handles SEH exceptions it throws, when +// SEH is supported; returns the 0-value for type Result in case of an +// SEH exception. (Microsoft compilers cannot handle SEH and C++ +// exceptions in the same function. Therefore, we provide a separate +// wrapper function for handling SEH exceptions.) +template +Result HandleSehExceptionsInMethodIfSupported( + T* object, Result (T::*method)(), const char* location) { +#if GTEST_HAS_SEH + __try { + return (object->*method)(); + } __except (internal::UnitTestOptions::GTestShouldProcessSEH( // NOLINT + GetExceptionCode())) { + // We create the exception message on the heap because VC++ prohibits + // creation of objects with destructors on stack in functions using __try + // (see error C2712). + std::string* exception_message = FormatSehExceptionMessage( + GetExceptionCode(), location); + internal::ReportFailureInUnknownLocation(TestPartResult::kFatalFailure, + *exception_message); + delete exception_message; + return static_cast(0); + } +#else + (void)location; + return (object->*method)(); +#endif // GTEST_HAS_SEH +} + +// Runs the given method and catches and reports C++ and/or SEH-style +// exceptions, if they are supported; returns the 0-value for type +// Result in case of an SEH exception. +template +Result HandleExceptionsInMethodIfSupported( + T* object, Result (T::*method)(), const char* location) { + // NOTE: The user code can affect the way in which Google Test handles + // exceptions by setting GTEST_FLAG(catch_exceptions), but only before + // RUN_ALL_TESTS() starts. It is technically possible to check the flag + // after the exception is caught and either report or re-throw the + // exception based on the flag's value: + // + // try { + // // Perform the test method. + // } catch (...) { + // if (GTEST_FLAG(catch_exceptions)) + // // Report the exception as failure. + // else + // throw; // Re-throws the original exception. + // } + // + // However, the purpose of this flag is to allow the program to drop into + // the debugger when the exception is thrown. On most platforms, once the + // control enters the catch block, the exception origin information is + // lost and the debugger will stop the program at the point of the + // re-throw in this function -- instead of at the point of the original + // throw statement in the code under test. For this reason, we perform + // the check early, sacrificing the ability to affect Google Test's + // exception handling in the method where the exception is thrown. + if (internal::GetUnitTestImpl()->catch_exceptions()) { +#if GTEST_HAS_EXCEPTIONS + try { + return HandleSehExceptionsInMethodIfSupported(object, method, location); + } catch (const internal::GoogleTestFailureException&) { // NOLINT + // This exception type can only be thrown by a failed Google + // Test assertion with the intention of letting another testing + // framework catch it. Therefore we just re-throw it. + throw; + } catch (const std::exception& e) { // NOLINT + internal::ReportFailureInUnknownLocation( + TestPartResult::kFatalFailure, + FormatCxxExceptionMessage(e.what(), location)); + } catch (...) { // NOLINT + internal::ReportFailureInUnknownLocation( + TestPartResult::kFatalFailure, + FormatCxxExceptionMessage(NULL, location)); + } + return static_cast(0); +#else + return HandleSehExceptionsInMethodIfSupported(object, method, location); +#endif // GTEST_HAS_EXCEPTIONS + } else { + return (object->*method)(); + } +} + +} // namespace internal + +// Runs the test and updates the test result. +void Test::Run() { + if (!HasSameFixtureClass()) return; + + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + impl->os_stack_trace_getter()->UponLeavingGTest(); + internal::HandleExceptionsInMethodIfSupported(this, &Test::SetUp, "SetUp()"); + // We will run the test only if SetUp() was successful. + if (!HasFatalFailure()) { + impl->os_stack_trace_getter()->UponLeavingGTest(); + internal::HandleExceptionsInMethodIfSupported( + this, &Test::TestBody, "the test body"); + } + + // However, we want to clean up as much as possible. Hence we will + // always call TearDown(), even if SetUp() or the test body has + // failed. + impl->os_stack_trace_getter()->UponLeavingGTest(); + internal::HandleExceptionsInMethodIfSupported( + this, &Test::TearDown, "TearDown()"); +} + +// Returns true iff the current test has a fatal failure. +bool Test::HasFatalFailure() { + return internal::GetUnitTestImpl()->current_test_result()->HasFatalFailure(); +} + +// Returns true iff the current test has a non-fatal failure. +bool Test::HasNonfatalFailure() { + return internal::GetUnitTestImpl()->current_test_result()-> + HasNonfatalFailure(); +} + +// class TestInfo + +// Constructs a TestInfo object. It assumes ownership of the test factory +// object. +TestInfo::TestInfo(const std::string& a_test_case_name, + const std::string& a_name, + const char* a_type_param, + const char* a_value_param, + internal::TypeId fixture_class_id, + internal::TestFactoryBase* factory) + : test_case_name_(a_test_case_name), + name_(a_name), + type_param_(a_type_param ? new std::string(a_type_param) : NULL), + value_param_(a_value_param ? new std::string(a_value_param) : NULL), + fixture_class_id_(fixture_class_id), + should_run_(false), + is_disabled_(false), + matches_filter_(false), + factory_(factory), + result_() {} + +// Destructs a TestInfo object. +TestInfo::~TestInfo() { delete factory_; } + +namespace internal { + +// Creates a new TestInfo object and registers it with Google Test; +// returns the created object. +// +// Arguments: +// +// test_case_name: name of the test case +// name: name of the test +// type_param: the name of the test's type parameter, or NULL if +// this is not a typed or a type-parameterized test. +// value_param: text representation of the test's value parameter, +// or NULL if this is not a value-parameterized test. +// fixture_class_id: ID of the test fixture class +// set_up_tc: pointer to the function that sets up the test case +// tear_down_tc: pointer to the function that tears down the test case +// factory: pointer to the factory that creates a test object. +// The newly created TestInfo instance will assume +// ownership of the factory object. +TestInfo* MakeAndRegisterTestInfo( + const char* test_case_name, + const char* name, + const char* type_param, + const char* value_param, + TypeId fixture_class_id, + SetUpTestCaseFunc set_up_tc, + TearDownTestCaseFunc tear_down_tc, + TestFactoryBase* factory) { + TestInfo* const test_info = + new TestInfo(test_case_name, name, type_param, value_param, + fixture_class_id, factory); + GetUnitTestImpl()->AddTestInfo(set_up_tc, tear_down_tc, test_info); + return test_info; +} + +#if GTEST_HAS_PARAM_TEST +void ReportInvalidTestCaseType(const char* test_case_name, + const char* file, int line) { + Message errors; + errors + << "Attempted redefinition of test case " << test_case_name << ".\n" + << "All tests in the same test case must use the same test fixture\n" + << "class. However, in test case " << test_case_name << ", you tried\n" + << "to define a test using a fixture class different from the one\n" + << "used earlier. This can happen if the two fixture classes are\n" + << "from different namespaces and have the same name. You should\n" + << "probably rename one of the classes to put the tests into different\n" + << "test cases."; + + fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(), + errors.GetString().c_str()); +} +#endif // GTEST_HAS_PARAM_TEST + +} // namespace internal + +namespace { + +// A predicate that checks the test name of a TestInfo against a known +// value. +// +// This is used for implementation of the TestCase class only. We put +// it in the anonymous namespace to prevent polluting the outer +// namespace. +// +// TestNameIs is copyable. + +//Commenting out this class since its not used and wherefor produces warnings +// class TestNameIs { +// public: +// // Constructor. +// // +// // TestNameIs has NO default constructor. +// explicit TestNameIs(const char* name) +// : name_(name) {} +// +// // Returns true iff the test name of test_info matches name_. +// bool operator()(const TestInfo * test_info) const { +// return test_info && test_info->name() == name_; +// } +// +// private: +// std::string name_; +//}; + +} // namespace + +namespace internal { + +// This method expands all parameterized tests registered with macros TEST_P +// and INSTANTIATE_TEST_CASE_P into regular tests and registers those. +// This will be done just once during the program runtime. +void UnitTestImpl::RegisterParameterizedTests() { +#if GTEST_HAS_PARAM_TEST + if (!parameterized_tests_registered_) { + parameterized_test_registry_.RegisterTests(); + parameterized_tests_registered_ = true; + } +#endif +} + +} // namespace internal + +// Creates the test object, runs it, records its result, and then +// deletes it. +void TestInfo::Run() { + if (!should_run_) return; + + // Tells UnitTest where to store test result. + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + impl->set_current_test_info(this); + + TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater(); + + // Notifies the unit test event listeners that a test is about to start. + repeater->OnTestStart(*this); + + const TimeInMillis start = internal::GetTimeInMillis(); + + impl->os_stack_trace_getter()->UponLeavingGTest(); + + // Creates the test object. + Test* const test = internal::HandleExceptionsInMethodIfSupported( + factory_, &internal::TestFactoryBase::CreateTest, + "the test fixture's constructor"); + + // Runs the test only if the test object was created and its + // constructor didn't generate a fatal failure. + if ((test != NULL) && !Test::HasFatalFailure()) { + // This doesn't throw as all user code that can throw are wrapped into + // exception handling code. + test->Run(); + } + + // Deletes the test object. + impl->os_stack_trace_getter()->UponLeavingGTest(); + internal::HandleExceptionsInMethodIfSupported( + test, &Test::DeleteSelf_, "the test fixture's destructor"); + + result_.set_elapsed_time(internal::GetTimeInMillis() - start); + + // Notifies the unit test event listener that a test has just finished. + repeater->OnTestEnd(*this); + + // Tells UnitTest to stop associating assertion results to this + // test. + impl->set_current_test_info(NULL); +} + +// class TestCase + +// Gets the number of successful tests in this test case. +int TestCase::successful_test_count() const { + return CountIf(test_info_list_, TestPassed); +} + +// Gets the number of failed tests in this test case. +int TestCase::failed_test_count() const { + return CountIf(test_info_list_, TestFailed); +} + +// Gets the number of disabled tests that will be reported in the XML report. +int TestCase::reportable_disabled_test_count() const { + return CountIf(test_info_list_, TestReportableDisabled); +} + +// Gets the number of disabled tests in this test case. +int TestCase::disabled_test_count() const { + return CountIf(test_info_list_, TestDisabled); +} + +// Gets the number of tests to be printed in the XML report. +int TestCase::reportable_test_count() const { + return CountIf(test_info_list_, TestReportable); +} + +// Get the number of tests in this test case that should run. +int TestCase::test_to_run_count() const { + return CountIf(test_info_list_, ShouldRunTest); +} + +// Gets the number of all tests. +int TestCase::total_test_count() const { + return static_cast(test_info_list_.size()); +} + +// Creates a TestCase with the given name. +// +// Arguments: +// +// name: name of the test case +// a_type_param: the name of the test case's type parameter, or NULL if +// this is not a typed or a type-parameterized test case. +// set_up_tc: pointer to the function that sets up the test case +// tear_down_tc: pointer to the function that tears down the test case +TestCase::TestCase(const char* a_name, const char* a_type_param, + Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc) + : name_(a_name), + type_param_(a_type_param ? new std::string(a_type_param) : NULL), + set_up_tc_(set_up_tc), + tear_down_tc_(tear_down_tc), + should_run_(false), + elapsed_time_(0) { +} + +// Destructor of TestCase. +TestCase::~TestCase() { + // Deletes every Test in the collection. + ForEach(test_info_list_, internal::Delete); +} + +// Returns the i-th test among all the tests. i can range from 0 to +// total_test_count() - 1. If i is not in that range, returns NULL. +const TestInfo* TestCase::GetTestInfo(int i) const { + const int index = GetElementOr(test_indices_, i, -1); + return index < 0 ? NULL : test_info_list_[index]; +} + +// Returns the i-th test among all the tests. i can range from 0 to +// total_test_count() - 1. If i is not in that range, returns NULL. +TestInfo* TestCase::GetMutableTestInfo(int i) { + const int index = GetElementOr(test_indices_, i, -1); + return index < 0 ? NULL : test_info_list_[index]; +} + +// Adds a test to this test case. Will delete the test upon +// destruction of the TestCase object. +void TestCase::AddTestInfo(TestInfo * test_info) { + test_info_list_.push_back(test_info); + test_indices_.push_back(static_cast(test_indices_.size())); +} + +// Runs every test in this TestCase. +void TestCase::Run() { + if (!should_run_) return; + + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + impl->set_current_test_case(this); + + TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater(); + + repeater->OnTestCaseStart(*this); + impl->os_stack_trace_getter()->UponLeavingGTest(); + internal::HandleExceptionsInMethodIfSupported( + this, &TestCase::RunSetUpTestCase, "SetUpTestCase()"); + + const internal::TimeInMillis start = internal::GetTimeInMillis(); + for (int i = 0; i < total_test_count(); i++) { + GetMutableTestInfo(i)->Run(); + } + elapsed_time_ = internal::GetTimeInMillis() - start; + + impl->os_stack_trace_getter()->UponLeavingGTest(); + internal::HandleExceptionsInMethodIfSupported( + this, &TestCase::RunTearDownTestCase, "TearDownTestCase()"); + + repeater->OnTestCaseEnd(*this); + impl->set_current_test_case(NULL); +} + +// Clears the results of all tests in this test case. +void TestCase::ClearResult() { + ad_hoc_test_result_.Clear(); + ForEach(test_info_list_, TestInfo::ClearTestResult); +} + +// Shuffles the tests in this test case. +void TestCase::ShuffleTests(internal::Random* random) { + Shuffle(random, &test_indices_); +} + +// Restores the test order to before the first shuffle. +void TestCase::UnshuffleTests() { + for (size_t i = 0; i < test_indices_.size(); i++) { + test_indices_[i] = static_cast(i); + } +} + +// Formats a countable noun. Depending on its quantity, either the +// singular form or the plural form is used. e.g. +// +// FormatCountableNoun(1, "formula", "formuli") returns "1 formula". +// FormatCountableNoun(5, "book", "books") returns "5 books". +static std::string FormatCountableNoun(int count, + const char * singular_form, + const char * plural_form) { + return internal::StreamableToString(count) + " " + + (count == 1 ? singular_form : plural_form); +} + +// Formats the count of tests. +static std::string FormatTestCount(int test_count) { + return FormatCountableNoun(test_count, "test", "tests"); +} + +// Formats the count of test cases. +static std::string FormatTestCaseCount(int test_case_count) { + return FormatCountableNoun(test_case_count, "test case", "test cases"); +} + +// Converts a TestPartResult::Type enum to human-friendly string +// representation. Both kNonFatalFailure and kFatalFailure are translated +// to "Failure", as the user usually doesn't care about the difference +// between the two when viewing the test result. +static const char * TestPartResultTypeToString(TestPartResult::Type type) { + switch (type) { + case TestPartResult::kSuccess: + return "Success"; + + case TestPartResult::kNonFatalFailure: + case TestPartResult::kFatalFailure: +#ifdef _MSC_VER + return "error: "; +#else + return "Failure\n"; +#endif + default: + return "Unknown result type"; + } +} + +namespace internal { + +// Prints a TestPartResult to an std::string. +static std::string PrintTestPartResultToString( + const TestPartResult& test_part_result) { + return (Message() + << internal::FormatFileLocation(test_part_result.file_name(), + test_part_result.line_number()) + << " " << TestPartResultTypeToString(test_part_result.type()) + << test_part_result.message()).GetString(); +} + +// Prints a TestPartResult. +static void PrintTestPartResult(const TestPartResult& test_part_result) { + const std::string& result = + PrintTestPartResultToString(test_part_result); + printf("%s\n", result.c_str()); + fflush(stdout); + // If the test program runs in Visual Studio or a debugger, the + // following statements add the test part result message to the Output + // window such that the user can double-click on it to jump to the + // corresponding source code location; otherwise they do nothing. +#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE + // We don't call OutputDebugString*() on Windows Mobile, as printing + // to stdout is done by OutputDebugString() there already - we don't + // want the same message printed twice. + ::OutputDebugStringA(result.c_str()); + ::OutputDebugStringA("\n"); +#endif +} + +// class PrettyUnitTestResultPrinter + +enum GTestColor { + COLOR_DEFAULT, + COLOR_RED, + COLOR_GREEN, + COLOR_YELLOW +}; + +#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE + +// Returns the character attribute for the given color. +WORD GetColorAttribute(GTestColor color) { + switch (color) { + case COLOR_RED: return FOREGROUND_RED; + case COLOR_GREEN: return FOREGROUND_GREEN; + case COLOR_YELLOW: return FOREGROUND_RED | FOREGROUND_GREEN; + default: return 0; + } +} + +#else + +// Returns the ANSI color code for the given color. COLOR_DEFAULT is +// an invalid input. +const char* GetAnsiColorCode(GTestColor color) { + switch (color) { + case COLOR_RED: return "1"; + case COLOR_GREEN: return "2"; + case COLOR_YELLOW: return "3"; + default: return NULL; + }; +} + +#endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE + +// Returns true iff Google Test should use colors in the output. +bool ShouldUseColor(bool stdout_is_tty) { + const char* const gtest_color = GTEST_FLAG(color).c_str(); + + if (String::CaseInsensitiveCStringEquals(gtest_color, "auto")) { +#if GTEST_OS_WINDOWS + // On Windows the TERM variable is usually not set, but the + // console there does support colors. + return stdout_is_tty; +#else + // On non-Windows platforms, we rely on the TERM variable. + const char* const term = posix::GetEnv("TERM"); + const bool term_supports_color = + String::CStringEquals(term, "xterm") || + String::CStringEquals(term, "xterm-color") || + String::CStringEquals(term, "xterm-256color") || + String::CStringEquals(term, "screen") || + String::CStringEquals(term, "screen-256color") || + String::CStringEquals(term, "linux") || + String::CStringEquals(term, "cygwin"); + return stdout_is_tty && term_supports_color; +#endif // GTEST_OS_WINDOWS + } + + return String::CaseInsensitiveCStringEquals(gtest_color, "yes") || + String::CaseInsensitiveCStringEquals(gtest_color, "true") || + String::CaseInsensitiveCStringEquals(gtest_color, "t") || + String::CStringEquals(gtest_color, "1"); + // We take "yes", "true", "t", and "1" as meaning "yes". If the + // value is neither one of these nor "auto", we treat it as "no" to + // be conservative. +} + +// Helpers for printing colored strings to stdout. Note that on Windows, we +// cannot simply emit special characters and have the terminal change colors. +// This routine must actually emit the characters rather than return a string +// that would be colored when printed, as can be done on Linux. +void ColoredPrintf(GTestColor color, const char* fmt, ...) { + va_list args; + va_start(args, fmt); + +#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS || GTEST_OS_IOS + const bool use_color = false; +#else + static const bool in_color_mode = + ShouldUseColor(posix::IsATTY(posix::FileNo(stdout)) != 0); + const bool use_color = in_color_mode && (color != COLOR_DEFAULT); +#endif // GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS + // The '!= 0' comparison is necessary to satisfy MSVC 7.1. + + if (!use_color) { + vprintf(fmt, args); + va_end(args); + return; + } + +#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE + const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE); + + // Gets the current text color. + CONSOLE_SCREEN_BUFFER_INFO buffer_info; + GetConsoleScreenBufferInfo(stdout_handle, &buffer_info); + const WORD old_color_attrs = buffer_info.wAttributes; + + // We need to flush the stream buffers into the console before each + // SetConsoleTextAttribute call lest it affect the text that is already + // printed but has not yet reached the console. + fflush(stdout); + SetConsoleTextAttribute(stdout_handle, + GetColorAttribute(color) | FOREGROUND_INTENSITY); + vprintf(fmt, args); + + fflush(stdout); + // Restores the text color. + SetConsoleTextAttribute(stdout_handle, old_color_attrs); +#else + printf("\033[0;3%sm", GetAnsiColorCode(color)); + vprintf(fmt, args); + printf("\033[m"); // Resets the terminal to default. +#endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE + va_end(args); +} + +// Text printed in Google Test's text output and --gunit_list_tests +// output to label the type parameter and value parameter for a test. +static const char kTypeParamLabel[] = "TypeParam"; +static const char kValueParamLabel[] = "GetParam()"; + +void PrintFullTestCommentIfPresent(const TestInfo& test_info) { + const char* const type_param = test_info.type_param(); + const char* const value_param = test_info.value_param(); + + if (type_param != NULL || value_param != NULL) { + printf(", where "); + if (type_param != NULL) { + printf("%s = %s", kTypeParamLabel, type_param); + if (value_param != NULL) + printf(" and "); + } + if (value_param != NULL) { + printf("%s = %s", kValueParamLabel, value_param); + } + } +} + +// This class implements the TestEventListener interface. +// +// Class PrettyUnitTestResultPrinter is copyable. +class PrettyUnitTestResultPrinter : public TestEventListener { + public: + PrettyUnitTestResultPrinter() {} + static void PrintTestName(const char * test_case, const char * test) { + printf("%s.%s", test_case, test); + } + + // The following methods override what's in the TestEventListener class. + virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {} + virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration); + virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test); + virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {} + virtual void OnTestCaseStart(const TestCase& test_case); + virtual void OnTestStart(const TestInfo& test_info); + virtual void OnTestPartResult(const TestPartResult& result); + virtual void OnTestEnd(const TestInfo& test_info); + virtual void OnTestCaseEnd(const TestCase& test_case); + virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test); + virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {} + virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration); + virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {} + + private: + static void PrintFailedTests(const UnitTest& unit_test); +}; + + // Fired before each iteration of tests starts. +void PrettyUnitTestResultPrinter::OnTestIterationStart( + const UnitTest& unit_test, int iteration) { + if (GTEST_FLAG(repeat) != 1) + printf("\nRepeating all tests (iteration %d) . . .\n\n", iteration + 1); + + const char* const filter = GTEST_FLAG(filter).c_str(); + + // Prints the filter if it's not *. This reminds the user that some + // tests may be skipped. + if (!String::CStringEquals(filter, kUniversalFilter)) { + ColoredPrintf(COLOR_YELLOW, + "Note: %s filter = %s\n", GTEST_NAME_, filter); + } + + if (internal::ShouldShard(kTestTotalShards, kTestShardIndex, false)) { + const Int32 shard_index = Int32FromEnvOrDie(kTestShardIndex, -1); + ColoredPrintf(COLOR_YELLOW, + "Note: This is test shard %d of %s.\n", + static_cast(shard_index) + 1, + internal::posix::GetEnv(kTestTotalShards)); + } + + if (GTEST_FLAG(shuffle)) { + ColoredPrintf(COLOR_YELLOW, + "Note: Randomizing tests' orders with a seed of %d .\n", + unit_test.random_seed()); + } + + ColoredPrintf(COLOR_GREEN, "[==========] "); + printf("Running %s from %s.\n", + FormatTestCount(unit_test.test_to_run_count()).c_str(), + FormatTestCaseCount(unit_test.test_case_to_run_count()).c_str()); + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnEnvironmentsSetUpStart( + const UnitTest& /*unit_test*/) { + ColoredPrintf(COLOR_GREEN, "[----------] "); + printf("Global test environment set-up.\n"); + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnTestCaseStart(const TestCase& test_case) { + const std::string counts = + FormatCountableNoun(test_case.test_to_run_count(), "test", "tests"); + ColoredPrintf(COLOR_GREEN, "[----------] "); + printf("%s from %s", counts.c_str(), test_case.name()); + if (test_case.type_param() == NULL) { + printf("\n"); + } else { + printf(", where %s = %s\n", kTypeParamLabel, test_case.type_param()); + } + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnTestStart(const TestInfo& test_info) { + ColoredPrintf(COLOR_GREEN, "[ RUN ] "); + PrintTestName(test_info.test_case_name(), test_info.name()); + printf("\n"); + fflush(stdout); +} + +// Called after an assertion failure. +void PrettyUnitTestResultPrinter::OnTestPartResult( + const TestPartResult& result) { + // If the test part succeeded, we don't need to do anything. + if (result.type() == TestPartResult::kSuccess) + return; + + // Print failure message from the assertion (e.g. expected this and got that). + PrintTestPartResult(result); + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo& test_info) { + if (test_info.result()->Passed()) { + ColoredPrintf(COLOR_GREEN, "[ OK ] "); + } else { + ColoredPrintf(COLOR_RED, "[ FAILED ] "); + } + PrintTestName(test_info.test_case_name(), test_info.name()); + if (test_info.result()->Failed()) + PrintFullTestCommentIfPresent(test_info); + + if (GTEST_FLAG(print_time)) { + printf(" (%s ms)\n", internal::StreamableToString( + test_info.result()->elapsed_time()).c_str()); + } else { + printf("\n"); + } + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnTestCaseEnd(const TestCase& test_case) { + if (!GTEST_FLAG(print_time)) return; + + const std::string counts = + FormatCountableNoun(test_case.test_to_run_count(), "test", "tests"); + ColoredPrintf(COLOR_GREEN, "[----------] "); + printf("%s from %s (%s ms total)\n\n", + counts.c_str(), test_case.name(), + internal::StreamableToString(test_case.elapsed_time()).c_str()); + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnEnvironmentsTearDownStart( + const UnitTest& /*unit_test*/) { + ColoredPrintf(COLOR_GREEN, "[----------] "); + printf("Global test environment tear-down\n"); + fflush(stdout); +} + +// Internal helper for printing the list of failed tests. +void PrettyUnitTestResultPrinter::PrintFailedTests(const UnitTest& unit_test) { + const int failed_test_count = unit_test.failed_test_count(); + if (failed_test_count == 0) { + return; + } + + for (int i = 0; i < unit_test.total_test_case_count(); ++i) { + const TestCase& test_case = *unit_test.GetTestCase(i); + if (!test_case.should_run() || (test_case.failed_test_count() == 0)) { + continue; + } + for (int j = 0; j < test_case.total_test_count(); ++j) { + const TestInfo& test_info = *test_case.GetTestInfo(j); + if (!test_info.should_run() || test_info.result()->Passed()) { + continue; + } + ColoredPrintf(COLOR_RED, "[ FAILED ] "); + printf("%s.%s", test_case.name(), test_info.name()); + PrintFullTestCommentIfPresent(test_info); + printf("\n"); + } + } +} + +void PrettyUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, + int /*iteration*/) { + ColoredPrintf(COLOR_GREEN, "[==========] "); + printf("%s from %s ran.", + FormatTestCount(unit_test.test_to_run_count()).c_str(), + FormatTestCaseCount(unit_test.test_case_to_run_count()).c_str()); + if (GTEST_FLAG(print_time)) { + printf(" (%s ms total)", + internal::StreamableToString(unit_test.elapsed_time()).c_str()); + } + printf("\n"); + ColoredPrintf(COLOR_GREEN, "[ PASSED ] "); + printf("%s.\n", FormatTestCount(unit_test.successful_test_count()).c_str()); + + int num_failures = unit_test.failed_test_count(); + if (!unit_test.Passed()) { + const int failed_test_count = unit_test.failed_test_count(); + ColoredPrintf(COLOR_RED, "[ FAILED ] "); + printf("%s, listed below:\n", FormatTestCount(failed_test_count).c_str()); + PrintFailedTests(unit_test); + printf("\n%2d FAILED %s\n", num_failures, + num_failures == 1 ? "TEST" : "TESTS"); + } + + int num_disabled = unit_test.reportable_disabled_test_count(); + if (num_disabled && !GTEST_FLAG(also_run_disabled_tests)) { + if (!num_failures) { + printf("\n"); // Add a spacer if no FAILURE banner is displayed. + } + ColoredPrintf(COLOR_YELLOW, + " YOU HAVE %d DISABLED %s\n\n", + num_disabled, + num_disabled == 1 ? "TEST" : "TESTS"); + } + // Ensure that Google Test output is printed before, e.g., heapchecker output. + fflush(stdout); +} + +// End PrettyUnitTestResultPrinter + +// class TestEventRepeater +// +// This class forwards events to other event listeners. +class TestEventRepeater : public TestEventListener { + public: + TestEventRepeater() : forwarding_enabled_(true) {} + virtual ~TestEventRepeater(); + void Append(TestEventListener *listener); + TestEventListener* Release(TestEventListener* listener); + + // Controls whether events will be forwarded to listeners_. Set to false + // in death test child processes. + bool forwarding_enabled() const { return forwarding_enabled_; } + void set_forwarding_enabled(bool enable) { forwarding_enabled_ = enable; } + + virtual void OnTestProgramStart(const UnitTest& unit_test); + virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration); + virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test); + virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test); + virtual void OnTestCaseStart(const TestCase& test_case); + virtual void OnTestStart(const TestInfo& test_info); + virtual void OnTestPartResult(const TestPartResult& result); + virtual void OnTestEnd(const TestInfo& test_info); + virtual void OnTestCaseEnd(const TestCase& test_case); + virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test); + virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test); + virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration); + virtual void OnTestProgramEnd(const UnitTest& unit_test); + + private: + // Controls whether events will be forwarded to listeners_. Set to false + // in death test child processes. + bool forwarding_enabled_; + // The list of listeners that receive events. + std::vector listeners_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventRepeater); +}; + +TestEventRepeater::~TestEventRepeater() { + ForEach(listeners_, Delete); +} + +void TestEventRepeater::Append(TestEventListener *listener) { + listeners_.push_back(listener); +} + +// TODO(vladl@google.com): Factor the search functionality into Vector::Find. +TestEventListener* TestEventRepeater::Release(TestEventListener *listener) { + for (size_t i = 0; i < listeners_.size(); ++i) { + if (listeners_[i] == listener) { + listeners_.erase(listeners_.begin() + i); + return listener; + } + } + + return NULL; +} + +// Since most methods are very similar, use macros to reduce boilerplate. +// This defines a member that forwards the call to all listeners. +#define GTEST_REPEATER_METHOD_(Name, Type) \ +void TestEventRepeater::Name(const Type& parameter) { \ + if (forwarding_enabled_) { \ + for (size_t i = 0; i < listeners_.size(); i++) { \ + listeners_[i]->Name(parameter); \ + } \ + } \ +} +// This defines a member that forwards the call to all listeners in reverse +// order. +#define GTEST_REVERSE_REPEATER_METHOD_(Name, Type) \ +void TestEventRepeater::Name(const Type& parameter) { \ + if (forwarding_enabled_) { \ + for (int i = static_cast(listeners_.size()) - 1; i >= 0; i--) { \ + listeners_[i]->Name(parameter); \ + } \ + } \ +} + +GTEST_REPEATER_METHOD_(OnTestProgramStart, UnitTest) +GTEST_REPEATER_METHOD_(OnEnvironmentsSetUpStart, UnitTest) +GTEST_REPEATER_METHOD_(OnTestCaseStart, TestCase) +GTEST_REPEATER_METHOD_(OnTestStart, TestInfo) +GTEST_REPEATER_METHOD_(OnTestPartResult, TestPartResult) +GTEST_REPEATER_METHOD_(OnEnvironmentsTearDownStart, UnitTest) +GTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsSetUpEnd, UnitTest) +GTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsTearDownEnd, UnitTest) +GTEST_REVERSE_REPEATER_METHOD_(OnTestEnd, TestInfo) +GTEST_REVERSE_REPEATER_METHOD_(OnTestCaseEnd, TestCase) +GTEST_REVERSE_REPEATER_METHOD_(OnTestProgramEnd, UnitTest) + +#undef GTEST_REPEATER_METHOD_ +#undef GTEST_REVERSE_REPEATER_METHOD_ + +void TestEventRepeater::OnTestIterationStart(const UnitTest& unit_test, + int iteration) { + if (forwarding_enabled_) { + for (size_t i = 0; i < listeners_.size(); i++) { + listeners_[i]->OnTestIterationStart(unit_test, iteration); + } + } +} + +void TestEventRepeater::OnTestIterationEnd(const UnitTest& unit_test, + int iteration) { + if (forwarding_enabled_) { + for (int i = static_cast(listeners_.size()) - 1; i >= 0; i--) { + listeners_[i]->OnTestIterationEnd(unit_test, iteration); + } + } +} + +// End TestEventRepeater + +// This class generates an XML output file. +class XmlUnitTestResultPrinter : public EmptyTestEventListener { + public: + explicit XmlUnitTestResultPrinter(const char* output_file); + + virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration); + + private: + // Is c a whitespace character that is normalized to a space character + // when it appears in an XML attribute value? + static bool IsNormalizableWhitespace(char c) { + return c == 0x9 || c == 0xA || c == 0xD; + } + + // May c appear in a well-formed XML document? + static bool IsValidXmlCharacter(char c) { + return IsNormalizableWhitespace(c) || c >= 0x20; + } + + // Returns an XML-escaped copy of the input string str. If + // is_attribute is true, the text is meant to appear as an attribute + // value, and normalizable whitespace is preserved by replacing it + // with character references. + static std::string EscapeXml(const std::string& str, bool is_attribute); + + // Returns the given string with all characters invalid in XML removed. + static std::string RemoveInvalidXmlCharacters(const std::string& str); + + // Convenience wrapper around EscapeXml when str is an attribute value. + static std::string EscapeXmlAttribute(const std::string& str) { + return EscapeXml(str, true); + } + + // Convenience wrapper around EscapeXml when str is not an attribute value. + static std::string EscapeXmlText(const char* str) { + return EscapeXml(str, false); + } + + // Verifies that the given attribute belongs to the given element and + // streams the attribute as XML. + static void OutputXmlAttribute(std::ostream* stream, + const std::string& element_name, + const std::string& name, + const std::string& value); + + // Streams an XML CDATA section, escaping invalid CDATA sequences as needed. + static void OutputXmlCDataSection(::std::ostream* stream, const char* data); + + // Streams an XML representation of a TestInfo object. + static void OutputXmlTestInfo(::std::ostream* stream, + const char* test_case_name, + const TestInfo& test_info); + + // Prints an XML representation of a TestCase object + static void PrintXmlTestCase(::std::ostream* stream, + const TestCase& test_case); + + // Prints an XML summary of unit_test to output stream out. + static void PrintXmlUnitTest(::std::ostream* stream, + const UnitTest& unit_test); + + // Produces a string representing the test properties in a result as space + // delimited XML attributes based on the property key="value" pairs. + // When the std::string is not empty, it includes a space at the beginning, + // to delimit this attribute from prior attributes. + static std::string TestPropertiesAsXmlAttributes(const TestResult& result); + + // The output file. + const std::string output_file_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(XmlUnitTestResultPrinter); +}; + +// Creates a new XmlUnitTestResultPrinter. +XmlUnitTestResultPrinter::XmlUnitTestResultPrinter(const char* output_file) + : output_file_(output_file) { + if (output_file_.c_str() == NULL || output_file_.empty()) { + fprintf(stderr, "XML output file may not be null\n"); + fflush(stderr); + exit(EXIT_FAILURE); + } +} + +// Called after the unit test ends. +void XmlUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, + int /*iteration*/) { + FILE* xmlout = NULL; + FilePath output_file(output_file_); + FilePath output_dir(output_file.RemoveFileName()); + + if (output_dir.CreateDirectoriesRecursively()) { + xmlout = posix::FOpen(output_file_.c_str(), "w"); + } + if (xmlout == NULL) { + // TODO(wan): report the reason of the failure. + // + // We don't do it for now as: + // + // 1. There is no urgent need for it. + // 2. It's a bit involved to make the errno variable thread-safe on + // all three operating systems (Linux, Windows, and Mac OS). + // 3. To interpret the meaning of errno in a thread-safe way, + // we need the strerror_r() function, which is not available on + // Windows. + fprintf(stderr, + "Unable to open file \"%s\"\n", + output_file_.c_str()); + fflush(stderr); + exit(EXIT_FAILURE); + } + std::stringstream stream; + PrintXmlUnitTest(&stream, unit_test); + fprintf(xmlout, "%s", StringStreamToString(&stream).c_str()); + fclose(xmlout); +} + +// Returns an XML-escaped copy of the input string str. If is_attribute +// is true, the text is meant to appear as an attribute value, and +// normalizable whitespace is preserved by replacing it with character +// references. +// +// Invalid XML characters in str, if any, are stripped from the output. +// It is expected that most, if not all, of the text processed by this +// module will consist of ordinary English text. +// If this module is ever modified to produce version 1.1 XML output, +// most invalid characters can be retained using character references. +// TODO(wan): It might be nice to have a minimally invasive, human-readable +// escaping scheme for invalid characters, rather than dropping them. +std::string XmlUnitTestResultPrinter::EscapeXml( + const std::string& str, bool is_attribute) { + Message m; + + for (size_t i = 0; i < str.size(); ++i) { + const char ch = str[i]; + switch (ch) { + case '<': + m << "<"; + break; + case '>': + m << ">"; + break; + case '&': + m << "&"; + break; + case '\'': + if (is_attribute) + m << "'"; + else + m << '\''; + break; + case '"': + if (is_attribute) + m << """; + else + m << '"'; + break; + default: + if (IsValidXmlCharacter(ch)) { + if (is_attribute && IsNormalizableWhitespace(ch)) + m << "&#x" << String::FormatByte(static_cast(ch)) + << ";"; + else + m << ch; + } + break; + } + } + + return m.GetString(); +} + +// Returns the given string with all characters invalid in XML removed. +// Currently invalid characters are dropped from the string. An +// alternative is to replace them with certain characters such as . or ?. +std::string XmlUnitTestResultPrinter::RemoveInvalidXmlCharacters( + const std::string& str) { + std::string output; + output.reserve(str.size()); + for (std::string::const_iterator it = str.begin(); it != str.end(); ++it) + if (IsValidXmlCharacter(*it)) + output.push_back(*it); + + return output; +} + +// The following routines generate an XML representation of a UnitTest +// object. +// +// This is how Google Test concepts map to the DTD: +// +// <-- corresponds to a UnitTest object +// <-- corresponds to a TestCase object +// <-- corresponds to a TestInfo object +// ... +// ... +// ... +// <-- individual assertion failures +// +// +// + +// Formats the given time in milliseconds as seconds. +std::string FormatTimeInMillisAsSeconds(TimeInMillis ms) { + ::std::stringstream ss; + ss << ms/1000.0; + return ss.str(); +} + +// Converts the given epoch time in milliseconds to a date string in the ISO +// 8601 format, without the timezone information. +std::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms) { + // Using non-reentrant version as localtime_r is not portable. + time_t seconds = static_cast(ms / 1000); +#ifdef _MSC_VER +# pragma warning(push) // Saves the current warning state. +# pragma warning(disable:4996) // Temporarily disables warning 4996 + // (function or variable may be unsafe). + const struct tm* const time_struct = localtime(&seconds); // NOLINT +# pragma warning(pop) // Restores the warning state again. +#else + const struct tm* const time_struct = localtime(&seconds); // NOLINT +#endif + if (time_struct == NULL) + return ""; // Invalid ms value + + // YYYY-MM-DDThh:mm:ss + return StreamableToString(time_struct->tm_year + 1900) + "-" + + String::FormatIntWidth2(time_struct->tm_mon + 1) + "-" + + String::FormatIntWidth2(time_struct->tm_mday) + "T" + + String::FormatIntWidth2(time_struct->tm_hour) + ":" + + String::FormatIntWidth2(time_struct->tm_min) + ":" + + String::FormatIntWidth2(time_struct->tm_sec); +} + +// Streams an XML CDATA section, escaping invalid CDATA sequences as needed. +void XmlUnitTestResultPrinter::OutputXmlCDataSection(::std::ostream* stream, + const char* data) { + const char* segment = data; + *stream << ""); + if (next_segment != NULL) { + stream->write( + segment, static_cast(next_segment - segment)); + *stream << "]]>]]>"); + } else { + *stream << segment; + break; + } + } + *stream << "]]>"; +} + +void XmlUnitTestResultPrinter::OutputXmlAttribute( + std::ostream* stream, + const std::string& element_name, + const std::string& name, + const std::string& value) { + const std::vector& allowed_names = + GetReservedAttributesForElement(element_name); + + GTEST_CHECK_(std::find(allowed_names.begin(), allowed_names.end(), name) != + allowed_names.end()) + << "Attribute " << name << " is not allowed for element <" << element_name + << ">."; + + *stream << " " << name << "=\"" << EscapeXmlAttribute(value) << "\""; +} + +// Prints an XML representation of a TestInfo object. +// TODO(wan): There is also value in printing properties with the plain printer. +void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream, + const char* test_case_name, + const TestInfo& test_info) { + const TestResult& result = *test_info.result(); + const std::string kTestcase = "testcase"; + + *stream << " \n"; + } + const string location = internal::FormatCompilerIndependentFileLocation( + part.file_name(), part.line_number()); + const string summary = location + "\n" + part.summary(); + *stream << " "; + const string detail = location + "\n" + part.message(); + OutputXmlCDataSection(stream, RemoveInvalidXmlCharacters(detail).c_str()); + *stream << "\n"; + } + } + + if (failures == 0) + *stream << " />\n"; + else + *stream << " \n"; +} + +// Prints an XML representation of a TestCase object +void XmlUnitTestResultPrinter::PrintXmlTestCase(std::ostream* stream, + const TestCase& test_case) { + const std::string kTestsuite = "testsuite"; + *stream << " <" << kTestsuite; + OutputXmlAttribute(stream, kTestsuite, "name", test_case.name()); + OutputXmlAttribute(stream, kTestsuite, "tests", + StreamableToString(test_case.reportable_test_count())); + OutputXmlAttribute(stream, kTestsuite, "failures", + StreamableToString(test_case.failed_test_count())); + OutputXmlAttribute( + stream, kTestsuite, "disabled", + StreamableToString(test_case.reportable_disabled_test_count())); + OutputXmlAttribute(stream, kTestsuite, "errors", "0"); + OutputXmlAttribute(stream, kTestsuite, "time", + FormatTimeInMillisAsSeconds(test_case.elapsed_time())); + *stream << TestPropertiesAsXmlAttributes(test_case.ad_hoc_test_result()) + << ">\n"; + + for (int i = 0; i < test_case.total_test_count(); ++i) { + if (test_case.GetTestInfo(i)->is_reportable()) + OutputXmlTestInfo(stream, test_case.name(), *test_case.GetTestInfo(i)); + } + *stream << " \n"; +} + +// Prints an XML summary of unit_test to output stream out. +void XmlUnitTestResultPrinter::PrintXmlUnitTest(std::ostream* stream, + const UnitTest& unit_test) { + const std::string kTestsuites = "testsuites"; + + *stream << "\n"; + *stream << "<" << kTestsuites; + + OutputXmlAttribute(stream, kTestsuites, "tests", + StreamableToString(unit_test.reportable_test_count())); + OutputXmlAttribute(stream, kTestsuites, "failures", + StreamableToString(unit_test.failed_test_count())); + OutputXmlAttribute( + stream, kTestsuites, "disabled", + StreamableToString(unit_test.reportable_disabled_test_count())); + OutputXmlAttribute(stream, kTestsuites, "errors", "0"); + OutputXmlAttribute( + stream, kTestsuites, "timestamp", + FormatEpochTimeInMillisAsIso8601(unit_test.start_timestamp())); + OutputXmlAttribute(stream, kTestsuites, "time", + FormatTimeInMillisAsSeconds(unit_test.elapsed_time())); + + if (GTEST_FLAG(shuffle)) { + OutputXmlAttribute(stream, kTestsuites, "random_seed", + StreamableToString(unit_test.random_seed())); + } + + *stream << TestPropertiesAsXmlAttributes(unit_test.ad_hoc_test_result()); + + OutputXmlAttribute(stream, kTestsuites, "name", "AllTests"); + *stream << ">\n"; + + for (int i = 0; i < unit_test.total_test_case_count(); ++i) { + if (unit_test.GetTestCase(i)->reportable_test_count() > 0) + PrintXmlTestCase(stream, *unit_test.GetTestCase(i)); + } + *stream << "\n"; +} + +// Produces a string representing the test properties in a result as space +// delimited XML attributes based on the property key="value" pairs. +std::string XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes( + const TestResult& result) { + Message attributes; + for (int i = 0; i < result.test_property_count(); ++i) { + const TestProperty& property = result.GetTestProperty(i); + attributes << " " << property.key() << "=" + << "\"" << EscapeXmlAttribute(property.value()) << "\""; + } + return attributes.GetString(); +} + +// End XmlUnitTestResultPrinter + +#if GTEST_CAN_STREAM_RESULTS_ + +// Checks if str contains '=', '&', '%' or '\n' characters. If yes, +// replaces them by "%xx" where xx is their hexadecimal value. For +// example, replaces "=" with "%3D". This algorithm is O(strlen(str)) +// in both time and space -- important as the input str may contain an +// arbitrarily long test failure message and stack trace. +string StreamingListener::UrlEncode(const char* str) { + string result; + result.reserve(strlen(str) + 1); + for (char ch = *str; ch != '\0'; ch = *++str) { + switch (ch) { + case '%': + case '=': + case '&': + case '\n': + result.append("%" + String::FormatByte(static_cast(ch))); + break; + default: + result.push_back(ch); + break; + } + } + return result; +} + +void StreamingListener::SocketWriter::MakeConnection() { + GTEST_CHECK_(sockfd_ == -1) + << "MakeConnection() can't be called when there is already a connection."; + + addrinfo hints; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; // To allow both IPv4 and IPv6 addresses. + hints.ai_socktype = SOCK_STREAM; + addrinfo* servinfo = NULL; + + // Use the getaddrinfo() to get a linked list of IP addresses for + // the given host name. + const int error_num = getaddrinfo( + host_name_.c_str(), port_num_.c_str(), &hints, &servinfo); + if (error_num != 0) { + GTEST_LOG_(WARNING) << "stream_result_to: getaddrinfo() failed: " + << gai_strerror(error_num); + } + + // Loop through all the results and connect to the first we can. + for (addrinfo* cur_addr = servinfo; sockfd_ == -1 && cur_addr != NULL; + cur_addr = cur_addr->ai_next) { + sockfd_ = socket( + cur_addr->ai_family, cur_addr->ai_socktype, cur_addr->ai_protocol); + if (sockfd_ != -1) { + // Connect the client socket to the server socket. + if (connect(sockfd_, cur_addr->ai_addr, cur_addr->ai_addrlen) == -1) { + close(sockfd_); + sockfd_ = -1; + } + } + } + + freeaddrinfo(servinfo); // all done with this structure + + if (sockfd_ == -1) { + GTEST_LOG_(WARNING) << "stream_result_to: failed to connect to " + << host_name_ << ":" << port_num_; + } +} + +// End of class Streaming Listener +#endif // GTEST_CAN_STREAM_RESULTS__ + +// Class ScopedTrace + +// Pushes the given source file location and message onto a per-thread +// trace stack maintained by Google Test. +ScopedTrace::ScopedTrace(const char* file, int line, const Message& message) + GTEST_LOCK_EXCLUDED_(&UnitTest::mutex_) { + TraceInfo trace; + trace.file = file; + trace.line = line; + trace.message = message.GetString(); + + UnitTest::GetInstance()->PushGTestTrace(trace); +} + +// Pops the info pushed by the c'tor. +ScopedTrace::~ScopedTrace() + GTEST_LOCK_EXCLUDED_(&UnitTest::mutex_) { + UnitTest::GetInstance()->PopGTestTrace(); +} + + +// class OsStackTraceGetter + +// Returns the current OS stack trace as an std::string. Parameters: +// +// max_depth - the maximum number of stack frames to be included +// in the trace. +// skip_count - the number of top frames to be skipped; doesn't count +// against max_depth. +// +string OsStackTraceGetter::CurrentStackTrace(int /* max_depth */, + int /* skip_count */) + GTEST_LOCK_EXCLUDED_(mutex_) { + return ""; +} + +void OsStackTraceGetter::UponLeavingGTest() + GTEST_LOCK_EXCLUDED_(mutex_) { +} + +const char* const +OsStackTraceGetter::kElidedFramesMarker = + "... " GTEST_NAME_ " internal frames ..."; + +// A helper class that creates the premature-exit file in its +// constructor and deletes the file in its destructor. +class ScopedPrematureExitFile { + public: + explicit ScopedPrematureExitFile(const char* premature_exit_filepath) + : premature_exit_filepath_(premature_exit_filepath) { + // If a path to the premature-exit file is specified... + if (premature_exit_filepath != NULL && *premature_exit_filepath != '\0') { + // create the file with a single "0" character in it. I/O + // errors are ignored as there's nothing better we can do and we + // don't want to fail the test because of this. + FILE* pfile = posix::FOpen(premature_exit_filepath, "w"); + fwrite("0", 1, 1, pfile); + fclose(pfile); + } + } + + ~ScopedPrematureExitFile() { + if (premature_exit_filepath_ != NULL && *premature_exit_filepath_ != '\0') { + remove(premature_exit_filepath_); + } + } + + private: + const char* const premature_exit_filepath_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedPrematureExitFile); +}; + +} // namespace internal + +// class TestEventListeners + +TestEventListeners::TestEventListeners() + : repeater_(new internal::TestEventRepeater()), + default_result_printer_(NULL), + default_xml_generator_(NULL) { +} + +TestEventListeners::~TestEventListeners() { delete repeater_; } + +// Returns the standard listener responsible for the default console +// output. Can be removed from the listeners list to shut down default +// console output. Note that removing this object from the listener list +// with Release transfers its ownership to the user. +void TestEventListeners::Append(TestEventListener* listener) { + repeater_->Append(listener); +} + +// Removes the given event listener from the list and returns it. It then +// becomes the caller's responsibility to delete the listener. Returns +// NULL if the listener is not found in the list. +TestEventListener* TestEventListeners::Release(TestEventListener* listener) { + if (listener == default_result_printer_) + default_result_printer_ = NULL; + else if (listener == default_xml_generator_) + default_xml_generator_ = NULL; + return repeater_->Release(listener); +} + +// Returns repeater that broadcasts the TestEventListener events to all +// subscribers. +TestEventListener* TestEventListeners::repeater() { return repeater_; } + +// Sets the default_result_printer attribute to the provided listener. +// The listener is also added to the listener list and previous +// default_result_printer is removed from it and deleted. The listener can +// also be NULL in which case it will not be added to the list. Does +// nothing if the previous and the current listener objects are the same. +void TestEventListeners::SetDefaultResultPrinter(TestEventListener* listener) { + if (default_result_printer_ != listener) { + // It is an error to pass this method a listener that is already in the + // list. + delete Release(default_result_printer_); + default_result_printer_ = listener; + if (listener != NULL) + Append(listener); + } +} + +// Sets the default_xml_generator attribute to the provided listener. The +// listener is also added to the listener list and previous +// default_xml_generator is removed from it and deleted. The listener can +// also be NULL in which case it will not be added to the list. Does +// nothing if the previous and the current listener objects are the same. +void TestEventListeners::SetDefaultXmlGenerator(TestEventListener* listener) { + if (default_xml_generator_ != listener) { + // It is an error to pass this method a listener that is already in the + // list. + delete Release(default_xml_generator_); + default_xml_generator_ = listener; + if (listener != NULL) + Append(listener); + } +} + +// Controls whether events will be forwarded by the repeater to the +// listeners in the list. +bool TestEventListeners::EventForwardingEnabled() const { + return repeater_->forwarding_enabled(); +} + +void TestEventListeners::SuppressEventForwarding() { + repeater_->set_forwarding_enabled(false); +} + +// class UnitTest + +// Gets the singleton UnitTest object. The first time this method is +// called, a UnitTest object is constructed and returned. Consecutive +// calls will return the same object. +// +// We don't protect this under mutex_ as a user is not supposed to +// call this before main() starts, from which point on the return +// value will never change. +UnitTest* UnitTest::GetInstance() { + // When compiled with MSVC 7.1 in optimized mode, destroying the + // UnitTest object upon exiting the program messes up the exit code, + // causing successful tests to appear failed. We have to use a + // different implementation in this case to bypass the compiler bug. + // This implementation makes the compiler happy, at the cost of + // leaking the UnitTest object. + + // CodeGear C++Builder insists on a public destructor for the + // default implementation. Use this implementation to keep good OO + // design with private destructor. + +#if (_MSC_VER == 1310 && !defined(_DEBUG)) || defined(__BORLANDC__) + static UnitTest* const instance = new UnitTest; + return instance; +#else + static UnitTest instance; + return &instance; +#endif // (_MSC_VER == 1310 && !defined(_DEBUG)) || defined(__BORLANDC__) +} + +// Gets the number of successful test cases. +int UnitTest::successful_test_case_count() const { + return impl()->successful_test_case_count(); +} + +// Gets the number of failed test cases. +int UnitTest::failed_test_case_count() const { + return impl()->failed_test_case_count(); +} + +// Gets the number of all test cases. +int UnitTest::total_test_case_count() const { + return impl()->total_test_case_count(); +} + +// Gets the number of all test cases that contain at least one test +// that should run. +int UnitTest::test_case_to_run_count() const { + return impl()->test_case_to_run_count(); +} + +// Gets the number of successful tests. +int UnitTest::successful_test_count() const { + return impl()->successful_test_count(); +} + +// Gets the number of failed tests. +int UnitTest::failed_test_count() const { return impl()->failed_test_count(); } + +// Gets the number of disabled tests that will be reported in the XML report. +int UnitTest::reportable_disabled_test_count() const { + return impl()->reportable_disabled_test_count(); +} + +// Gets the number of disabled tests. +int UnitTest::disabled_test_count() const { + return impl()->disabled_test_count(); +} + +// Gets the number of tests to be printed in the XML report. +int UnitTest::reportable_test_count() const { + return impl()->reportable_test_count(); +} + +// Gets the number of all tests. +int UnitTest::total_test_count() const { return impl()->total_test_count(); } + +// Gets the number of tests that should run. +int UnitTest::test_to_run_count() const { return impl()->test_to_run_count(); } + +// Gets the time of the test program start, in ms from the start of the +// UNIX epoch. +internal::TimeInMillis UnitTest::start_timestamp() const { + return impl()->start_timestamp(); +} + +// Gets the elapsed time, in milliseconds. +internal::TimeInMillis UnitTest::elapsed_time() const { + return impl()->elapsed_time(); +} + +// Returns true iff the unit test passed (i.e. all test cases passed). +bool UnitTest::Passed() const { return impl()->Passed(); } + +// Returns true iff the unit test failed (i.e. some test case failed +// or something outside of all tests failed). +bool UnitTest::Failed() const { return impl()->Failed(); } + +// Gets the i-th test case among all the test cases. i can range from 0 to +// total_test_case_count() - 1. If i is not in that range, returns NULL. +const TestCase* UnitTest::GetTestCase(int i) const { + return impl()->GetTestCase(i); +} + +// Returns the TestResult containing information on test failures and +// properties logged outside of individual test cases. +const TestResult& UnitTest::ad_hoc_test_result() const { + return *impl()->ad_hoc_test_result(); +} + +// Gets the i-th test case among all the test cases. i can range from 0 to +// total_test_case_count() - 1. If i is not in that range, returns NULL. +TestCase* UnitTest::GetMutableTestCase(int i) { + return impl()->GetMutableTestCase(i); +} + +// Returns the list of event listeners that can be used to track events +// inside Google Test. +TestEventListeners& UnitTest::listeners() { + return *impl()->listeners(); +} + +// Registers and returns a global test environment. When a test +// program is run, all global test environments will be set-up in the +// order they were registered. After all tests in the program have +// finished, all global test environments will be torn-down in the +// *reverse* order they were registered. +// +// The UnitTest object takes ownership of the given environment. +// +// We don't protect this under mutex_, as we only support calling it +// from the main thread. +Environment* UnitTest::AddEnvironment(Environment* env) { + if (env == NULL) { + return NULL; + } + + impl_->environments().push_back(env); + return env; +} + +// Adds a TestPartResult to the current TestResult object. All Google Test +// assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) eventually call +// this to report their results. The user code should use the +// assertion macros instead of calling this directly. +void UnitTest::AddTestPartResult( + TestPartResult::Type result_type, + const char* file_name, + int line_number, + const std::string& message, + const std::string& os_stack_trace) GTEST_LOCK_EXCLUDED_(mutex_) { + Message msg; + msg << message; + + internal::MutexLock lock(&mutex_); + if (impl_->gtest_trace_stack().size() > 0) { + msg << "\n" << GTEST_NAME_ << " trace:"; + + for (int i = static_cast(impl_->gtest_trace_stack().size()); + i > 0; --i) { + const internal::TraceInfo& trace = impl_->gtest_trace_stack()[i - 1]; + msg << "\n" << internal::FormatFileLocation(trace.file, trace.line) + << " " << trace.message; + } + } + + if (os_stack_trace.c_str() != NULL && !os_stack_trace.empty()) { + msg << internal::kStackTraceMarker << os_stack_trace; + } + + const TestPartResult result = + TestPartResult(result_type, file_name, line_number, + msg.GetString().c_str()); + impl_->GetTestPartResultReporterForCurrentThread()-> + ReportTestPartResult(result); + + if (result_type != TestPartResult::kSuccess) { + // gtest_break_on_failure takes precedence over + // gtest_throw_on_failure. This allows a user to set the latter + // in the code (perhaps in order to use Google Test assertions + // with another testing framework) and specify the former on the + // command line for debugging. + if (GTEST_FLAG(break_on_failure)) { +#if GTEST_OS_WINDOWS + // Using DebugBreak on Windows allows gtest to still break into a debugger + // when a failure happens and both the --gtest_break_on_failure and + // the --gtest_catch_exceptions flags are specified. + DebugBreak(); +#else + // Dereference NULL through a volatile pointer to prevent the compiler + // from removing. We use this rather than abort() or __builtin_trap() for + // portability: Symbian doesn't implement abort() well, and some debuggers + // don't correctly trap abort(). + *static_cast(NULL) = 1; +#endif // GTEST_OS_WINDOWS + } else if (GTEST_FLAG(throw_on_failure)) { +#if GTEST_HAS_EXCEPTIONS + throw internal::GoogleTestFailureException(result); +#else + // We cannot call abort() as it generates a pop-up in debug mode + // that cannot be suppressed in VC 7.1 or below. + exit(1); +#endif + } + } +} + +// Adds a TestProperty to the current TestResult object when invoked from +// inside a test, to current TestCase's ad_hoc_test_result_ when invoked +// from SetUpTestCase or TearDownTestCase, or to the global property set +// when invoked elsewhere. If the result already contains a property with +// the same key, the value will be updated. +void UnitTest::RecordProperty(const std::string& key, + const std::string& value) { + impl_->RecordProperty(TestProperty(key, value)); +} + +// Runs all tests in this UnitTest object and prints the result. +// Returns 0 if successful, or 1 otherwise. +// +// We don't protect this under mutex_, as we only support calling it +// from the main thread. +int UnitTest::Run() { + const bool in_death_test_child_process = + internal::GTEST_FLAG(internal_run_death_test).length() > 0; + + // Google Test implements this protocol for catching that a test + // program exits before returning control to Google Test: + // + // 1. Upon start, Google Test creates a file whose absolute path + // is specified by the environment variable + // TEST_PREMATURE_EXIT_FILE. + // 2. When Google Test has finished its work, it deletes the file. + // + // This allows a test runner to set TEST_PREMATURE_EXIT_FILE before + // running a Google-Test-based test program and check the existence + // of the file at the end of the test execution to see if it has + // exited prematurely. + + // If we are in the child process of a death test, don't + // create/delete the premature exit file, as doing so is unnecessary + // and will confuse the parent process. Otherwise, create/delete + // the file upon entering/leaving this function. If the program + // somehow exits before this function has a chance to return, the + // premature-exit file will be left undeleted, causing a test runner + // that understands the premature-exit-file protocol to report the + // test as having failed. + const internal::ScopedPrematureExitFile premature_exit_file( + in_death_test_child_process ? + NULL : internal::posix::GetEnv("TEST_PREMATURE_EXIT_FILE")); + + // Captures the value of GTEST_FLAG(catch_exceptions). This value will be + // used for the duration of the program. + impl()->set_catch_exceptions(GTEST_FLAG(catch_exceptions)); + +#if GTEST_HAS_SEH + // Either the user wants Google Test to catch exceptions thrown by the + // tests or this is executing in the context of death test child + // process. In either case the user does not want to see pop-up dialogs + // about crashes - they are expected. + if (impl()->catch_exceptions() || in_death_test_child_process) { +# if !GTEST_OS_WINDOWS_MOBILE + // SetErrorMode doesn't exist on CE. + SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT | + SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX); +# endif // !GTEST_OS_WINDOWS_MOBILE + +# if (defined(_MSC_VER) || GTEST_OS_WINDOWS_MINGW) && !GTEST_OS_WINDOWS_MOBILE + // Death test children can be terminated with _abort(). On Windows, + // _abort() can show a dialog with a warning message. This forces the + // abort message to go to stderr instead. + _set_error_mode(_OUT_TO_STDERR); +# endif + +# if _MSC_VER >= 1400 && !GTEST_OS_WINDOWS_MOBILE + // In the debug version, Visual Studio pops up a separate dialog + // offering a choice to debug the aborted program. We need to suppress + // this dialog or it will pop up for every EXPECT/ASSERT_DEATH statement + // executed. Google Test will notify the user of any unexpected + // failure via stderr. + // + // VC++ doesn't define _set_abort_behavior() prior to the version 8.0. + // Users of prior VC versions shall suffer the agony and pain of + // clicking through the countless debug dialogs. + // TODO(vladl@google.com): find a way to suppress the abort dialog() in the + // debug mode when compiled with VC 7.1 or lower. + if (!GTEST_FLAG(break_on_failure)) + _set_abort_behavior( + 0x0, // Clear the following flags: + _WRITE_ABORT_MSG | _CALL_REPORTFAULT); // pop-up window, core dump. +# endif + } +#endif // GTEST_HAS_SEH + + return internal::HandleExceptionsInMethodIfSupported( + impl(), + &internal::UnitTestImpl::RunAllTests, + "auxiliary test code (environments or event listeners)") ? 0 : 1; +} + +// Returns the working directory when the first TEST() or TEST_F() was +// executed. +const char* UnitTest::original_working_dir() const { + return impl_->original_working_dir_.c_str(); +} + +// Returns the TestCase object for the test that's currently running, +// or NULL if no test is running. +const TestCase* UnitTest::current_test_case() const + GTEST_LOCK_EXCLUDED_(mutex_) { + internal::MutexLock lock(&mutex_); + return impl_->current_test_case(); +} + +// Returns the TestInfo object for the test that's currently running, +// or NULL if no test is running. +const TestInfo* UnitTest::current_test_info() const + GTEST_LOCK_EXCLUDED_(mutex_) { + internal::MutexLock lock(&mutex_); + return impl_->current_test_info(); +} + +// Returns the random seed used at the start of the current test run. +int UnitTest::random_seed() const { return impl_->random_seed(); } + +#if GTEST_HAS_PARAM_TEST +// Returns ParameterizedTestCaseRegistry object used to keep track of +// value-parameterized tests and instantiate and register them. +internal::ParameterizedTestCaseRegistry& + UnitTest::parameterized_test_registry() + GTEST_LOCK_EXCLUDED_(mutex_) { + return impl_->parameterized_test_registry(); +} +#endif // GTEST_HAS_PARAM_TEST + +// Creates an empty UnitTest. +UnitTest::UnitTest() { + impl_ = new internal::UnitTestImpl(this); +} + +// Destructor of UnitTest. +UnitTest::~UnitTest() { + delete impl_; +} + +// Pushes a trace defined by SCOPED_TRACE() on to the per-thread +// Google Test trace stack. +void UnitTest::PushGTestTrace(const internal::TraceInfo& trace) + GTEST_LOCK_EXCLUDED_(mutex_) { + internal::MutexLock lock(&mutex_); + impl_->gtest_trace_stack().push_back(trace); +} + +// Pops a trace from the per-thread Google Test trace stack. +void UnitTest::PopGTestTrace() + GTEST_LOCK_EXCLUDED_(mutex_) { + internal::MutexLock lock(&mutex_); + impl_->gtest_trace_stack().pop_back(); +} + +namespace internal { + +UnitTestImpl::UnitTestImpl(UnitTest* parent) + : parent_(parent), +#ifdef _MSC_VER +# pragma warning(push) // Saves the current warning state. +# pragma warning(disable:4355) // Temporarily disables warning 4355 + // (using this in initializer). + default_global_test_part_result_reporter_(this), + default_per_thread_test_part_result_reporter_(this), +# pragma warning(pop) // Restores the warning state again. +#else + default_global_test_part_result_reporter_(this), + default_per_thread_test_part_result_reporter_(this), +#endif // _MSC_VER + global_test_part_result_repoter_( + &default_global_test_part_result_reporter_), + per_thread_test_part_result_reporter_( + &default_per_thread_test_part_result_reporter_), +#if GTEST_HAS_PARAM_TEST + parameterized_test_registry_(), + parameterized_tests_registered_(false), +#endif // GTEST_HAS_PARAM_TEST + last_death_test_case_(-1), + current_test_case_(NULL), + current_test_info_(NULL), + ad_hoc_test_result_(), + os_stack_trace_getter_(NULL), + post_flag_parse_init_performed_(false), + random_seed_(0), // Will be overridden by the flag before first use. + random_(0), // Will be reseeded before first use. + start_timestamp_(0), + elapsed_time_(0), +#if GTEST_HAS_DEATH_TEST + death_test_factory_(new DefaultDeathTestFactory), +#endif + // Will be overridden by the flag before first use. + catch_exceptions_(false) { + listeners()->SetDefaultResultPrinter(new PrettyUnitTestResultPrinter); +} + +UnitTestImpl::~UnitTestImpl() { + // Deletes every TestCase. + ForEach(test_cases_, internal::Delete); + + // Deletes every Environment. + ForEach(environments_, internal::Delete); + + delete os_stack_trace_getter_; +} + +// Adds a TestProperty to the current TestResult object when invoked in a +// context of a test, to current test case's ad_hoc_test_result when invoke +// from SetUpTestCase/TearDownTestCase, or to the global property set +// otherwise. If the result already contains a property with the same key, +// the value will be updated. +void UnitTestImpl::RecordProperty(const TestProperty& test_property) { + std::string xml_element; + TestResult* test_result; // TestResult appropriate for property recording. + + if (current_test_info_ != NULL) { + xml_element = "testcase"; + test_result = &(current_test_info_->result_); + } else if (current_test_case_ != NULL) { + xml_element = "testsuite"; + test_result = &(current_test_case_->ad_hoc_test_result_); + } else { + xml_element = "testsuites"; + test_result = &ad_hoc_test_result_; + } + test_result->RecordProperty(xml_element, test_property); +} + +#if GTEST_HAS_DEATH_TEST +// Disables event forwarding if the control is currently in a death test +// subprocess. Must not be called before InitGoogleTest. +void UnitTestImpl::SuppressTestEventsIfInSubprocess() { + if (internal_run_death_test_flag_.get() != NULL) + listeners()->SuppressEventForwarding(); +} +#endif // GTEST_HAS_DEATH_TEST + +// Initializes event listeners performing XML output as specified by +// UnitTestOptions. Must not be called before InitGoogleTest. +void UnitTestImpl::ConfigureXmlOutput() { + const std::string& output_format = UnitTestOptions::GetOutputFormat(); + if (output_format == "xml") { + listeners()->SetDefaultXmlGenerator(new XmlUnitTestResultPrinter( + UnitTestOptions::GetAbsolutePathToOutputFile().c_str())); + } else if (output_format != "") { + printf("WARNING: unrecognized output format \"%s\" ignored.\n", + output_format.c_str()); + fflush(stdout); + } +} + +#if GTEST_CAN_STREAM_RESULTS_ +// Initializes event listeners for streaming test results in string form. +// Must not be called before InitGoogleTest. +void UnitTestImpl::ConfigureStreamingOutput() { + const std::string& target = GTEST_FLAG(stream_result_to); + if (!target.empty()) { + const size_t pos = target.find(':'); + if (pos != std::string::npos) { + listeners()->Append(new StreamingListener(target.substr(0, pos), + target.substr(pos+1))); + } else { + printf("WARNING: unrecognized streaming target \"%s\" ignored.\n", + target.c_str()); + fflush(stdout); + } + } +} +#endif // GTEST_CAN_STREAM_RESULTS_ + +// Performs initialization dependent upon flag values obtained in +// ParseGoogleTestFlagsOnly. Is called from InitGoogleTest after the call to +// ParseGoogleTestFlagsOnly. In case a user neglects to call InitGoogleTest +// this function is also called from RunAllTests. Since this function can be +// called more than once, it has to be idempotent. +void UnitTestImpl::PostFlagParsingInit() { + // Ensures that this function does not execute more than once. + if (!post_flag_parse_init_performed_) { + post_flag_parse_init_performed_ = true; + +#if GTEST_HAS_DEATH_TEST + InitDeathTestSubprocessControlInfo(); + SuppressTestEventsIfInSubprocess(); +#endif // GTEST_HAS_DEATH_TEST + + // Registers parameterized tests. This makes parameterized tests + // available to the UnitTest reflection API without running + // RUN_ALL_TESTS. + RegisterParameterizedTests(); + + // Configures listeners for XML output. This makes it possible for users + // to shut down the default XML output before invoking RUN_ALL_TESTS. + ConfigureXmlOutput(); + +#if GTEST_CAN_STREAM_RESULTS_ + // Configures listeners for streaming test results to the specified server. + ConfigureStreamingOutput(); +#endif // GTEST_CAN_STREAM_RESULTS_ + } +} + +// A predicate that checks the name of a TestCase against a known +// value. +// +// This is used for implementation of the UnitTest class only. We put +// it in the anonymous namespace to prevent polluting the outer +// namespace. +// +// TestCaseNameIs is copyable. +class TestCaseNameIs { + public: + // Constructor. + explicit TestCaseNameIs(const std::string& name) + : name_(name) {} + + // Returns true iff the name of test_case matches name_. + bool operator()(const TestCase* test_case) const { + return test_case != NULL && strcmp(test_case->name(), name_.c_str()) == 0; + } + + private: + std::string name_; +}; + +// Finds and returns a TestCase with the given name. If one doesn't +// exist, creates one and returns it. It's the CALLER'S +// RESPONSIBILITY to ensure that this function is only called WHEN THE +// TESTS ARE NOT SHUFFLED. +// +// Arguments: +// +// test_case_name: name of the test case +// type_param: the name of the test case's type parameter, or NULL if +// this is not a typed or a type-parameterized test case. +// set_up_tc: pointer to the function that sets up the test case +// tear_down_tc: pointer to the function that tears down the test case +TestCase* UnitTestImpl::GetTestCase(const char* test_case_name, + const char* type_param, + Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc) { + // Can we find a TestCase with the given name? + const std::vector::const_iterator test_case = + std::find_if(test_cases_.begin(), test_cases_.end(), + TestCaseNameIs(test_case_name)); + + if (test_case != test_cases_.end()) + return *test_case; + + // No. Let's create one. + TestCase* const new_test_case = + new TestCase(test_case_name, type_param, set_up_tc, tear_down_tc); + + // Is this a death test case? + if (internal::UnitTestOptions::MatchesFilter(test_case_name, + kDeathTestCaseFilter)) { + // Yes. Inserts the test case after the last death test case + // defined so far. This only works when the test cases haven't + // been shuffled. Otherwise we may end up running a death test + // after a non-death test. + ++last_death_test_case_; + test_cases_.insert(test_cases_.begin() + last_death_test_case_, + new_test_case); + } else { + // No. Appends to the end of the list. + test_cases_.push_back(new_test_case); + } + + test_case_indices_.push_back(static_cast(test_case_indices_.size())); + return new_test_case; +} + +// Helpers for setting up / tearing down the given environment. They +// are for use in the ForEach() function. +static void SetUpEnvironment(Environment* env) { env->SetUp(); } +static void TearDownEnvironment(Environment* env) { env->TearDown(); } + +// Runs all tests in this UnitTest object, prints the result, and +// returns true if all tests are successful. If any exception is +// thrown during a test, the test is considered to be failed, but the +// rest of the tests will still be run. +// +// When parameterized tests are enabled, it expands and registers +// parameterized tests first in RegisterParameterizedTests(). +// All other functions called from RunAllTests() may safely assume that +// parameterized tests are ready to be counted and run. +bool UnitTestImpl::RunAllTests() { + // Makes sure InitGoogleTest() was called. + if (!GTestIsInitialized()) { + printf("%s", + "\nThis test program did NOT call ::testing::InitGoogleTest " + "before calling RUN_ALL_TESTS(). Please fix it.\n"); + return false; + } + + // Do not run any test if the --help flag was specified. + if (g_help_flag) + return true; + + // Repeats the call to the post-flag parsing initialization in case the + // user didn't call InitGoogleTest. + PostFlagParsingInit(); + + // Even if sharding is not on, test runners may want to use the + // GTEST_SHARD_STATUS_FILE to query whether the test supports the sharding + // protocol. + internal::WriteToShardStatusFileIfNeeded(); + + // True iff we are in a subprocess for running a thread-safe-style + // death test. + bool in_subprocess_for_death_test = false; + +#if GTEST_HAS_DEATH_TEST + in_subprocess_for_death_test = (internal_run_death_test_flag_.get() != NULL); +#endif // GTEST_HAS_DEATH_TEST + + const bool should_shard = ShouldShard(kTestTotalShards, kTestShardIndex, + in_subprocess_for_death_test); + + // Compares the full test names with the filter to decide which + // tests to run. + const bool has_tests_to_run = FilterTests(should_shard + ? HONOR_SHARDING_PROTOCOL + : IGNORE_SHARDING_PROTOCOL) > 0; + + // Lists the tests and exits if the --gtest_list_tests flag was specified. + if (GTEST_FLAG(list_tests)) { + // This must be called *after* FilterTests() has been called. + ListTestsMatchingFilter(); + return true; + } + + random_seed_ = GTEST_FLAG(shuffle) ? + GetRandomSeedFromFlag(GTEST_FLAG(random_seed)) : 0; + + // True iff at least one test has failed. + bool failed = false; + + TestEventListener* repeater = listeners()->repeater(); + + start_timestamp_ = GetTimeInMillis(); + repeater->OnTestProgramStart(*parent_); + + // How many times to repeat the tests? We don't want to repeat them + // when we are inside the subprocess of a death test. + const int repeat = in_subprocess_for_death_test ? 1 : GTEST_FLAG(repeat); + // Repeats forever if the repeat count is negative. + const bool forever = repeat < 0; + for (int i = 0; forever || i != repeat; i++) { + // We want to preserve failures generated by ad-hoc test + // assertions executed before RUN_ALL_TESTS(). + ClearNonAdHocTestResult(); + + const TimeInMillis start = GetTimeInMillis(); + + // Shuffles test cases and tests if requested. + if (has_tests_to_run && GTEST_FLAG(shuffle)) { + random()->Reseed(random_seed_); + // This should be done before calling OnTestIterationStart(), + // such that a test event listener can see the actual test order + // in the event. + ShuffleTests(); + } + + // Tells the unit test event listeners that the tests are about to start. + repeater->OnTestIterationStart(*parent_, i); + + // Runs each test case if there is at least one test to run. + if (has_tests_to_run) { + // Sets up all environments beforehand. + repeater->OnEnvironmentsSetUpStart(*parent_); + ForEach(environments_, SetUpEnvironment); + repeater->OnEnvironmentsSetUpEnd(*parent_); + + // Runs the tests only if there was no fatal failure during global + // set-up. + if (!Test::HasFatalFailure()) { + for (int test_index = 0; test_index < total_test_case_count(); + test_index++) { + GetMutableTestCase(test_index)->Run(); + } + } + + // Tears down all environments in reverse order afterwards. + repeater->OnEnvironmentsTearDownStart(*parent_); + std::for_each(environments_.rbegin(), environments_.rend(), + TearDownEnvironment); + repeater->OnEnvironmentsTearDownEnd(*parent_); + } + + elapsed_time_ = GetTimeInMillis() - start; + + // Tells the unit test event listener that the tests have just finished. + repeater->OnTestIterationEnd(*parent_, i); + + // Gets the result and clears it. + if (!Passed()) { + failed = true; + } + + // Restores the original test order after the iteration. This + // allows the user to quickly repro a failure that happens in the + // N-th iteration without repeating the first (N - 1) iterations. + // This is not enclosed in "if (GTEST_FLAG(shuffle)) { ... }", in + // case the user somehow changes the value of the flag somewhere + // (it's always safe to unshuffle the tests). + UnshuffleTests(); + + if (GTEST_FLAG(shuffle)) { + // Picks a new random seed for each iteration. + random_seed_ = GetNextRandomSeed(random_seed_); + } + } + + repeater->OnTestProgramEnd(*parent_); + + return !failed; +} + +// Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file +// if the variable is present. If a file already exists at this location, this +// function will write over it. If the variable is present, but the file cannot +// be created, prints an error and exits. +void WriteToShardStatusFileIfNeeded() { + const char* const test_shard_file = posix::GetEnv(kTestShardStatusFile); + if (test_shard_file != NULL) { + FILE* const file = posix::FOpen(test_shard_file, "w"); + if (file == NULL) { + ColoredPrintf(COLOR_RED, + "Could not write to the test shard status file \"%s\" " + "specified by the %s environment variable.\n", + test_shard_file, kTestShardStatusFile); + fflush(stdout); + exit(EXIT_FAILURE); + } + fclose(file); + } +} + +// Checks whether sharding is enabled by examining the relevant +// environment variable values. If the variables are present, +// but inconsistent (i.e., shard_index >= total_shards), prints +// an error and exits. If in_subprocess_for_death_test, sharding is +// disabled because it must only be applied to the original test +// process. Otherwise, we could filter out death tests we intended to execute. +bool ShouldShard(const char* total_shards_env, + const char* shard_index_env, + bool in_subprocess_for_death_test) { + if (in_subprocess_for_death_test) { + return false; + } + + const Int32 total_shards = Int32FromEnvOrDie(total_shards_env, -1); + const Int32 shard_index = Int32FromEnvOrDie(shard_index_env, -1); + + if (total_shards == -1 && shard_index == -1) { + return false; + } else if (total_shards == -1 && shard_index != -1) { + const Message msg = Message() + << "Invalid environment variables: you have " + << kTestShardIndex << " = " << shard_index + << ", but have left " << kTestTotalShards << " unset.\n"; + ColoredPrintf(COLOR_RED, msg.GetString().c_str()); + fflush(stdout); + exit(EXIT_FAILURE); + } else if (total_shards != -1 && shard_index == -1) { + const Message msg = Message() + << "Invalid environment variables: you have " + << kTestTotalShards << " = " << total_shards + << ", but have left " << kTestShardIndex << " unset.\n"; + ColoredPrintf(COLOR_RED, msg.GetString().c_str()); + fflush(stdout); + exit(EXIT_FAILURE); + } else if (shard_index < 0 || shard_index >= total_shards) { + const Message msg = Message() + << "Invalid environment variables: we require 0 <= " + << kTestShardIndex << " < " << kTestTotalShards + << ", but you have " << kTestShardIndex << "=" << shard_index + << ", " << kTestTotalShards << "=" << total_shards << ".\n"; + ColoredPrintf(COLOR_RED, msg.GetString().c_str()); + fflush(stdout); + exit(EXIT_FAILURE); + } + + return total_shards > 1; +} + +// Parses the environment variable var as an Int32. If it is unset, +// returns default_val. If it is not an Int32, prints an error +// and aborts. +Int32 Int32FromEnvOrDie(const char* var, Int32 default_val) { + const char* str_val = posix::GetEnv(var); + if (str_val == NULL) { + return default_val; + } + + Int32 result; + if (!ParseInt32(Message() << "The value of environment variable " << var, + str_val, &result)) { + exit(EXIT_FAILURE); + } + return result; +} + +// Given the total number of shards, the shard index, and the test id, +// returns true iff the test should be run on this shard. The test id is +// some arbitrary but unique non-negative integer assigned to each test +// method. Assumes that 0 <= shard_index < total_shards. +bool ShouldRunTestOnShard(int total_shards, int shard_index, int test_id) { + return (test_id % total_shards) == shard_index; +} + +// Compares the name of each test with the user-specified filter to +// decide whether the test should be run, then records the result in +// each TestCase and TestInfo object. +// If shard_tests == true, further filters tests based on sharding +// variables in the environment - see +// http://code.google.com/p/googletest/wiki/GoogleTestAdvancedGuide. +// Returns the number of tests that should run. +int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) { + const Int32 total_shards = shard_tests == HONOR_SHARDING_PROTOCOL ? + Int32FromEnvOrDie(kTestTotalShards, -1) : -1; + const Int32 shard_index = shard_tests == HONOR_SHARDING_PROTOCOL ? + Int32FromEnvOrDie(kTestShardIndex, -1) : -1; + + // num_runnable_tests are the number of tests that will + // run across all shards (i.e., match filter and are not disabled). + // num_selected_tests are the number of tests to be run on + // this shard. + int num_runnable_tests = 0; + int num_selected_tests = 0; + for (size_t i = 0; i < test_cases_.size(); i++) { + TestCase* const test_case = test_cases_[i]; + const std::string &test_case_name = test_case->name(); + test_case->set_should_run(false); + + for (size_t j = 0; j < test_case->test_info_list().size(); j++) { + TestInfo* const test_info = test_case->test_info_list()[j]; + const std::string test_name(test_info->name()); + // A test is disabled if test case name or test name matches + // kDisableTestFilter. + const bool is_disabled = + internal::UnitTestOptions::MatchesFilter(test_case_name, + kDisableTestFilter) || + internal::UnitTestOptions::MatchesFilter(test_name, + kDisableTestFilter); + test_info->is_disabled_ = is_disabled; + + const bool matches_filter = + internal::UnitTestOptions::FilterMatchesTest(test_case_name, + test_name); + test_info->matches_filter_ = matches_filter; + + const bool is_runnable = + (GTEST_FLAG(also_run_disabled_tests) || !is_disabled) && + matches_filter; + + const bool is_selected = is_runnable && + (shard_tests == IGNORE_SHARDING_PROTOCOL || + ShouldRunTestOnShard(total_shards, shard_index, + num_runnable_tests)); + + num_runnable_tests += is_runnable; + num_selected_tests += is_selected; + + test_info->should_run_ = is_selected; + test_case->set_should_run(test_case->should_run() || is_selected); + } + } + return num_selected_tests; +} + +// Prints the given C-string on a single line by replacing all '\n' +// characters with string "\\n". If the output takes more than +// max_length characters, only prints the first max_length characters +// and "...". +static void PrintOnOneLine(const char* str, int max_length) { + if (str != NULL) { + for (int i = 0; *str != '\0'; ++str) { + if (i >= max_length) { + printf("..."); + break; + } + if (*str == '\n') { + printf("\\n"); + i += 2; + } else { + printf("%c", *str); + ++i; + } + } + } +} + +// Prints the names of the tests matching the user-specified filter flag. +void UnitTestImpl::ListTestsMatchingFilter() { + // Print at most this many characters for each type/value parameter. + const int kMaxParamLength = 250; + + for (size_t i = 0; i < test_cases_.size(); i++) { + const TestCase* const test_case = test_cases_[i]; + bool printed_test_case_name = false; + + for (size_t j = 0; j < test_case->test_info_list().size(); j++) { + const TestInfo* const test_info = + test_case->test_info_list()[j]; + if (test_info->matches_filter_) { + if (!printed_test_case_name) { + printed_test_case_name = true; + printf("%s.", test_case->name()); + if (test_case->type_param() != NULL) { + printf(" # %s = ", kTypeParamLabel); + // We print the type parameter on a single line to make + // the output easy to parse by a program. + PrintOnOneLine(test_case->type_param(), kMaxParamLength); + } + printf("\n"); + } + printf(" %s", test_info->name()); + if (test_info->value_param() != NULL) { + printf(" # %s = ", kValueParamLabel); + // We print the value parameter on a single line to make the + // output easy to parse by a program. + PrintOnOneLine(test_info->value_param(), kMaxParamLength); + } + printf("\n"); + } + } + } + fflush(stdout); +} + +// Sets the OS stack trace getter. +// +// Does nothing if the input and the current OS stack trace getter are +// the same; otherwise, deletes the old getter and makes the input the +// current getter. +void UnitTestImpl::set_os_stack_trace_getter( + OsStackTraceGetterInterface* getter) { + if (os_stack_trace_getter_ != getter) { + delete os_stack_trace_getter_; + os_stack_trace_getter_ = getter; + } +} + +// Returns the current OS stack trace getter if it is not NULL; +// otherwise, creates an OsStackTraceGetter, makes it the current +// getter, and returns it. +OsStackTraceGetterInterface* UnitTestImpl::os_stack_trace_getter() { + if (os_stack_trace_getter_ == NULL) { + os_stack_trace_getter_ = new OsStackTraceGetter; + } + + return os_stack_trace_getter_; +} + +// Returns the TestResult for the test that's currently running, or +// the TestResult for the ad hoc test if no test is running. +TestResult* UnitTestImpl::current_test_result() { + return current_test_info_ ? + &(current_test_info_->result_) : &ad_hoc_test_result_; +} + +// Shuffles all test cases, and the tests within each test case, +// making sure that death tests are still run first. +void UnitTestImpl::ShuffleTests() { + // Shuffles the death test cases. + ShuffleRange(random(), 0, last_death_test_case_ + 1, &test_case_indices_); + + // Shuffles the non-death test cases. + ShuffleRange(random(), last_death_test_case_ + 1, + static_cast(test_cases_.size()), &test_case_indices_); + + // Shuffles the tests inside each test case. + for (size_t i = 0; i < test_cases_.size(); i++) { + test_cases_[i]->ShuffleTests(random()); + } +} + +// Restores the test cases and tests to their order before the first shuffle. +void UnitTestImpl::UnshuffleTests() { + for (size_t i = 0; i < test_cases_.size(); i++) { + // Unshuffles the tests in each test case. + test_cases_[i]->UnshuffleTests(); + // Resets the index of each test case. + test_case_indices_[i] = static_cast(i); + } +} + +// Returns the current OS stack trace as an std::string. +// +// The maximum number of stack frames to be included is specified by +// the gtest_stack_trace_depth flag. The skip_count parameter +// specifies the number of top frames to be skipped, which doesn't +// count against the number of frames to be included. +// +// For example, if Foo() calls Bar(), which in turn calls +// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in +// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't. +std::string GetCurrentOsStackTraceExceptTop(UnitTest* /*unit_test*/, + int skip_count) { + // We pass skip_count + 1 to skip this wrapper function in addition + // to what the user really wants to skip. + return GetUnitTestImpl()->CurrentOsStackTraceExceptTop(skip_count + 1); +} + +// Used by the GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_ macro to +// suppress unreachable code warnings. +namespace { +class ClassUniqueToAlwaysTrue {}; +} + +bool IsTrue(bool condition) { return condition; } + +bool AlwaysTrue() { +#if GTEST_HAS_EXCEPTIONS + // This condition is always false so AlwaysTrue() never actually throws, + // but it makes the compiler think that it may throw. + if (IsTrue(false)) + throw ClassUniqueToAlwaysTrue(); +#endif // GTEST_HAS_EXCEPTIONS + return true; +} + +// If *pstr starts with the given prefix, modifies *pstr to be right +// past the prefix and returns true; otherwise leaves *pstr unchanged +// and returns false. None of pstr, *pstr, and prefix can be NULL. +bool SkipPrefix(const char* prefix, const char** pstr) { + const size_t prefix_len = strlen(prefix); + if (strncmp(*pstr, prefix, prefix_len) == 0) { + *pstr += prefix_len; + return true; + } + return false; +} + +// Parses a string as a command line flag. The string should have +// the format "--flag=value". When def_optional is true, the "=value" +// part can be omitted. +// +// Returns the value of the flag, or NULL if the parsing failed. +const char* ParseFlagValue(const char* str, + const char* flag, + bool def_optional) { + // str and flag must not be NULL. + if (str == NULL || flag == NULL) return NULL; + + // The flag must start with "--" followed by GTEST_FLAG_PREFIX_. + const std::string flag_str = std::string("--") + GTEST_FLAG_PREFIX_ + flag; + const size_t flag_len = flag_str.length(); + if (strncmp(str, flag_str.c_str(), flag_len) != 0) return NULL; + + // Skips the flag name. + const char* flag_end = str + flag_len; + + // When def_optional is true, it's OK to not have a "=value" part. + if (def_optional && (flag_end[0] == '\0')) { + return flag_end; + } + + // If def_optional is true and there are more characters after the + // flag name, or if def_optional is false, there must be a '=' after + // the flag name. + if (flag_end[0] != '=') return NULL; + + // Returns the string after "=". + return flag_end + 1; +} + +// Parses a string for a bool flag, in the form of either +// "--flag=value" or "--flag". +// +// In the former case, the value is taken as true as long as it does +// not start with '0', 'f', or 'F'. +// +// In the latter case, the value is taken as true. +// +// On success, stores the value of the flag in *value, and returns +// true. On failure, returns false without changing *value. +bool ParseBoolFlag(const char* str, const char* flag, bool* value) { + // Gets the value of the flag as a string. + const char* const value_str = ParseFlagValue(str, flag, true); + + // Aborts if the parsing failed. + if (value_str == NULL) return false; + + // Converts the string value to a bool. + *value = !(*value_str == '0' || *value_str == 'f' || *value_str == 'F'); + return true; +} + +// Parses a string for an Int32 flag, in the form of +// "--flag=value". +// +// On success, stores the value of the flag in *value, and returns +// true. On failure, returns false without changing *value. +bool ParseInt32Flag(const char* str, const char* flag, Int32* value) { + // Gets the value of the flag as a string. + const char* const value_str = ParseFlagValue(str, flag, false); + + // Aborts if the parsing failed. + if (value_str == NULL) return false; + + // Sets *value to the value of the flag. + return ParseInt32(Message() << "The value of flag --" << flag, + value_str, value); +} + +// Parses a string for a string flag, in the form of +// "--flag=value". +// +// On success, stores the value of the flag in *value, and returns +// true. On failure, returns false without changing *value. +bool ParseStringFlag(const char* str, const char* flag, std::string* value) { + // Gets the value of the flag as a string. + const char* const value_str = ParseFlagValue(str, flag, false); + + // Aborts if the parsing failed. + if (value_str == NULL) return false; + + // Sets *value to the value of the flag. + *value = value_str; + return true; +} + +// Determines whether a string has a prefix that Google Test uses for its +// flags, i.e., starts with GTEST_FLAG_PREFIX_ or GTEST_FLAG_PREFIX_DASH_. +// If Google Test detects that a command line flag has its prefix but is not +// recognized, it will print its help message. Flags starting with +// GTEST_INTERNAL_PREFIX_ followed by "internal_" are considered Google Test +// internal flags and do not trigger the help message. +static bool HasGoogleTestFlagPrefix(const char* str) { + return (SkipPrefix("--", &str) || + SkipPrefix("-", &str) || + SkipPrefix("/", &str)) && + !SkipPrefix(GTEST_FLAG_PREFIX_ "internal_", &str) && + (SkipPrefix(GTEST_FLAG_PREFIX_, &str) || + SkipPrefix(GTEST_FLAG_PREFIX_DASH_, &str)); +} + +// Prints a string containing code-encoded text. The following escape +// sequences can be used in the string to control the text color: +// +// @@ prints a single '@' character. +// @R changes the color to red. +// @G changes the color to green. +// @Y changes the color to yellow. +// @D changes to the default terminal text color. +// +// TODO(wan@google.com): Write tests for this once we add stdout +// capturing to Google Test. +static void PrintColorEncoded(const char* str) { + GTestColor color = COLOR_DEFAULT; // The current color. + + // Conceptually, we split the string into segments divided by escape + // sequences. Then we print one segment at a time. At the end of + // each iteration, the str pointer advances to the beginning of the + // next segment. + for (;;) { + const char* p = strchr(str, '@'); + if (p == NULL) { + ColoredPrintf(color, "%s", str); + return; + } + + ColoredPrintf(color, "%s", std::string(str, p).c_str()); + + const char ch = p[1]; + str = p + 2; + if (ch == '@') { + ColoredPrintf(color, "@"); + } else if (ch == 'D') { + color = COLOR_DEFAULT; + } else if (ch == 'R') { + color = COLOR_RED; + } else if (ch == 'G') { + color = COLOR_GREEN; + } else if (ch == 'Y') { + color = COLOR_YELLOW; + } else { + --str; + } + } +} + +static const char kColorEncodedHelpMessage[] = +"This program contains tests written using " GTEST_NAME_ ". You can use the\n" +"following command line flags to control its behavior:\n" +"\n" +"Test Selection:\n" +" @G--" GTEST_FLAG_PREFIX_ "list_tests@D\n" +" List the names of all tests instead of running them. The name of\n" +" TEST(Foo, Bar) is \"Foo.Bar\".\n" +" @G--" GTEST_FLAG_PREFIX_ "filter=@YPOSTIVE_PATTERNS" + "[@G-@YNEGATIVE_PATTERNS]@D\n" +" Run only the tests whose name matches one of the positive patterns but\n" +" none of the negative patterns. '?' matches any single character; '*'\n" +" matches any substring; ':' separates two patterns.\n" +" @G--" GTEST_FLAG_PREFIX_ "also_run_disabled_tests@D\n" +" Run all disabled tests too.\n" +"\n" +"Test Execution:\n" +" @G--" GTEST_FLAG_PREFIX_ "repeat=@Y[COUNT]@D\n" +" Run the tests repeatedly; use a negative count to repeat forever.\n" +" @G--" GTEST_FLAG_PREFIX_ "shuffle@D\n" +" Randomize tests' orders on every iteration.\n" +" @G--" GTEST_FLAG_PREFIX_ "random_seed=@Y[NUMBER]@D\n" +" Random number seed to use for shuffling test orders (between 1 and\n" +" 99999, or 0 to use a seed based on the current time).\n" +"\n" +"Test Output:\n" +" @G--" GTEST_FLAG_PREFIX_ "color=@Y(@Gyes@Y|@Gno@Y|@Gauto@Y)@D\n" +" Enable/disable colored output. The default is @Gauto@D.\n" +" -@G-" GTEST_FLAG_PREFIX_ "print_time=0@D\n" +" Don't print the elapsed time of each test.\n" +" @G--" GTEST_FLAG_PREFIX_ "output=xml@Y[@G:@YDIRECTORY_PATH@G" + GTEST_PATH_SEP_ "@Y|@G:@YFILE_PATH]@D\n" +" Generate an XML report in the given directory or with the given file\n" +" name. @YFILE_PATH@D defaults to @Gtest_details.xml@D.\n" +#if GTEST_CAN_STREAM_RESULTS_ +" @G--" GTEST_FLAG_PREFIX_ "stream_result_to=@YHOST@G:@YPORT@D\n" +" Stream test results to the given server.\n" +#endif // GTEST_CAN_STREAM_RESULTS_ +"\n" +"Assertion Behavior:\n" +#if GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS +" @G--" GTEST_FLAG_PREFIX_ "death_test_style=@Y(@Gfast@Y|@Gthreadsafe@Y)@D\n" +" Set the default death test style.\n" +#endif // GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS +" @G--" GTEST_FLAG_PREFIX_ "break_on_failure@D\n" +" Turn assertion failures into debugger break-points.\n" +" @G--" GTEST_FLAG_PREFIX_ "throw_on_failure@D\n" +" Turn assertion failures into C++ exceptions.\n" +" @G--" GTEST_FLAG_PREFIX_ "catch_exceptions=0@D\n" +" Do not report exceptions as test failures. Instead, allow them\n" +" to crash the program or throw a pop-up (on Windows).\n" +"\n" +"Except for @G--" GTEST_FLAG_PREFIX_ "list_tests@D, you can alternatively set " + "the corresponding\n" +"environment variable of a flag (all letters in upper-case). For example, to\n" +"disable colored text output, you can either specify @G--" GTEST_FLAG_PREFIX_ + "color=no@D or set\n" +"the @G" GTEST_FLAG_PREFIX_UPPER_ "COLOR@D environment variable to @Gno@D.\n" +"\n" +"For more information, please read the " GTEST_NAME_ " documentation at\n" +"@G" GTEST_PROJECT_URL_ "@D. If you find a bug in " GTEST_NAME_ "\n" +"(not one in your own code or tests), please report it to\n" +"@G<" GTEST_DEV_EMAIL_ ">@D.\n"; + +// Parses the command line for Google Test flags, without initializing +// other parts of Google Test. The type parameter CharType can be +// instantiated to either char or wchar_t. +template +void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) { + for (int i = 1; i < *argc; i++) { + const std::string arg_string = StreamableToString(argv[i]); + const char* const arg = arg_string.c_str(); + + using internal::ParseBoolFlag; + using internal::ParseInt32Flag; + using internal::ParseStringFlag; + + // Do we see a Google Test flag? + if (ParseBoolFlag(arg, kAlsoRunDisabledTestsFlag, + >EST_FLAG(also_run_disabled_tests)) || + ParseBoolFlag(arg, kBreakOnFailureFlag, + >EST_FLAG(break_on_failure)) || + ParseBoolFlag(arg, kCatchExceptionsFlag, + >EST_FLAG(catch_exceptions)) || + ParseStringFlag(arg, kColorFlag, >EST_FLAG(color)) || + ParseStringFlag(arg, kDeathTestStyleFlag, + >EST_FLAG(death_test_style)) || + ParseBoolFlag(arg, kDeathTestUseFork, + >EST_FLAG(death_test_use_fork)) || + ParseStringFlag(arg, kFilterFlag, >EST_FLAG(filter)) || + ParseStringFlag(arg, kInternalRunDeathTestFlag, + >EST_FLAG(internal_run_death_test)) || + ParseBoolFlag(arg, kListTestsFlag, >EST_FLAG(list_tests)) || + ParseStringFlag(arg, kOutputFlag, >EST_FLAG(output)) || + ParseBoolFlag(arg, kPrintTimeFlag, >EST_FLAG(print_time)) || + ParseInt32Flag(arg, kRandomSeedFlag, >EST_FLAG(random_seed)) || + ParseInt32Flag(arg, kRepeatFlag, >EST_FLAG(repeat)) || + ParseBoolFlag(arg, kShuffleFlag, >EST_FLAG(shuffle)) || + ParseInt32Flag(arg, kStackTraceDepthFlag, + >EST_FLAG(stack_trace_depth)) || + ParseStringFlag(arg, kStreamResultToFlag, + >EST_FLAG(stream_result_to)) || + ParseBoolFlag(arg, kThrowOnFailureFlag, + >EST_FLAG(throw_on_failure)) + ) { + // Yes. Shift the remainder of the argv list left by one. Note + // that argv has (*argc + 1) elements, the last one always being + // NULL. The following loop moves the trailing NULL element as + // well. + for (int j = i; j != *argc; j++) { + argv[j] = argv[j + 1]; + } + + // Decrements the argument count. + (*argc)--; + + // We also need to decrement the iterator as we just removed + // an element. + i--; + } else if (arg_string == "--help" || arg_string == "-h" || + arg_string == "-?" || arg_string == "/?" || + HasGoogleTestFlagPrefix(arg)) { + // Both help flag and unrecognized Google Test flags (excluding + // internal ones) trigger help display. + g_help_flag = true; + } + } + + if (g_help_flag) { + // We print the help here instead of in RUN_ALL_TESTS(), as the + // latter may not be called at all if the user is using Google + // Test with another testing framework. + PrintColorEncoded(kColorEncodedHelpMessage); + } +} + +// Parses the command line for Google Test flags, without initializing +// other parts of Google Test. +void ParseGoogleTestFlagsOnly(int* argc, char** argv) { + ParseGoogleTestFlagsOnlyImpl(argc, argv); +} +void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv) { + ParseGoogleTestFlagsOnlyImpl(argc, argv); +} + +// The internal implementation of InitGoogleTest(). +// +// The type parameter CharType can be instantiated to either char or +// wchar_t. +template +void InitGoogleTestImpl(int* argc, CharType** argv) { + g_init_gtest_count++; + + // We don't want to run the initialization code twice. + if (g_init_gtest_count != 1) return; + + if (*argc <= 0) return; + + internal::g_executable_path = internal::StreamableToString(argv[0]); + +#if GTEST_HAS_DEATH_TEST + + g_argvs.clear(); + for (int i = 0; i != *argc; i++) { + g_argvs.push_back(StreamableToString(argv[i])); + } + +#endif // GTEST_HAS_DEATH_TEST + + ParseGoogleTestFlagsOnly(argc, argv); + GetUnitTestImpl()->PostFlagParsingInit(); +} + +} // namespace internal + +// Initializes Google Test. This must be called before calling +// RUN_ALL_TESTS(). In particular, it parses a command line for the +// flags that Google Test recognizes. Whenever a Google Test flag is +// seen, it is removed from argv, and *argc is decremented. +// +// No value is returned. Instead, the Google Test flag variables are +// updated. +// +// Calling the function for the second time has no user-visible effect. +void InitGoogleTest(int* argc, char** argv) { + internal::InitGoogleTestImpl(argc, argv); +} + +// This overloaded version can be used in Windows programs compiled in +// UNICODE mode. +void InitGoogleTest(int* argc, wchar_t** argv) { + internal::InitGoogleTestImpl(argc, argv); +} + +} // namespace testing +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan), vladl@google.com (Vlad Losev) +// +// This file implements death tests. + + +#if GTEST_HAS_DEATH_TEST + +# if GTEST_OS_MAC +# include +# endif // GTEST_OS_MAC + +# include +# include +# include + +# if GTEST_OS_LINUX +# include +# endif // GTEST_OS_LINUX + +# include + +# if GTEST_OS_WINDOWS +# include +# else +# include +# include +# endif // GTEST_OS_WINDOWS + +# if GTEST_OS_QNX +# include +# endif // GTEST_OS_QNX + +#endif // GTEST_HAS_DEATH_TEST + + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION_ 1 +#undef GTEST_IMPLEMENTATION_ + +namespace testing { + +// Constants. + +// The default death test style. +static const char kDefaultDeathTestStyle[] = "fast"; + +GTEST_DEFINE_string_( + death_test_style, + internal::StringFromGTestEnv("death_test_style", kDefaultDeathTestStyle), + "Indicates how to run a death test in a forked child process: " + "\"threadsafe\" (child process re-executes the test binary " + "from the beginning, running only the specific death test) or " + "\"fast\" (child process runs the death test immediately " + "after forking)."); + +GTEST_DEFINE_bool_( + death_test_use_fork, + internal::BoolFromGTestEnv("death_test_use_fork", false), + "Instructs to use fork()/_exit() instead of clone() in death tests. " + "Ignored and always uses fork() on POSIX systems where clone() is not " + "implemented. Useful when running under valgrind or similar tools if " + "those do not support clone(). Valgrind 3.3.1 will just fail if " + "it sees an unsupported combination of clone() flags. " + "It is not recommended to use this flag w/o valgrind though it will " + "work in 99% of the cases. Once valgrind is fixed, this flag will " + "most likely be removed."); + +namespace internal { +GTEST_DEFINE_string_( + internal_run_death_test, "", + "Indicates the file, line number, temporal index of " + "the single death test to run, and a file descriptor to " + "which a success code may be sent, all separated by " + "the '|' characters. This flag is specified if and only if the current " + "process is a sub-process launched for running a thread-safe " + "death test. FOR INTERNAL USE ONLY."); +} // namespace internal + +#if GTEST_HAS_DEATH_TEST + +namespace internal { + +// Valid only for fast death tests. Indicates the code is running in the +// child process of a fast style death test. +static bool g_in_fast_death_test_child = false; + +// Returns a Boolean value indicating whether the caller is currently +// executing in the context of the death test child process. Tools such as +// Valgrind heap checkers may need this to modify their behavior in death +// tests. IMPORTANT: This is an internal utility. Using it may break the +// implementation of death tests. User code MUST NOT use it. +bool InDeathTestChild() { +# if GTEST_OS_WINDOWS + + // On Windows, death tests are thread-safe regardless of the value of the + // death_test_style flag. + return !GTEST_FLAG(internal_run_death_test).empty(); + +# else + + if (GTEST_FLAG(death_test_style) == "threadsafe") + return !GTEST_FLAG(internal_run_death_test).empty(); + else + return g_in_fast_death_test_child; +#endif +} + +} // namespace internal + +// ExitedWithCode constructor. +ExitedWithCode::ExitedWithCode(int exit_code) : exit_code_(exit_code) { +} + +// ExitedWithCode function-call operator. +bool ExitedWithCode::operator()(int exit_status) const { +# if GTEST_OS_WINDOWS + + return exit_status == exit_code_; + +# else + + return WIFEXITED(exit_status) && WEXITSTATUS(exit_status) == exit_code_; + +# endif // GTEST_OS_WINDOWS +} + +# if !GTEST_OS_WINDOWS +// KilledBySignal constructor. +KilledBySignal::KilledBySignal(int signum) : signum_(signum) { +} + +// KilledBySignal function-call operator. +bool KilledBySignal::operator()(int exit_status) const { + return WIFSIGNALED(exit_status) && WTERMSIG(exit_status) == signum_; +} +# endif // !GTEST_OS_WINDOWS + +namespace internal { + +// Utilities needed for death tests. + +// Generates a textual description of a given exit code, in the format +// specified by wait(2). +static std::string ExitSummary(int exit_code) { + Message m; + +# if GTEST_OS_WINDOWS + + m << "Exited with exit status " << exit_code; + +# else + + if (WIFEXITED(exit_code)) { + m << "Exited with exit status " << WEXITSTATUS(exit_code); + } else if (WIFSIGNALED(exit_code)) { + m << "Terminated by signal " << WTERMSIG(exit_code); + } +# ifdef WCOREDUMP + if (WCOREDUMP(exit_code)) { + m << " (core dumped)"; + } +# endif +# endif // GTEST_OS_WINDOWS + + return m.GetString(); +} + +// Returns true if exit_status describes a process that was terminated +// by a signal, or exited normally with a nonzero exit code. +bool ExitedUnsuccessfully(int exit_status) { + return !ExitedWithCode(0)(exit_status); +} + +# if !GTEST_OS_WINDOWS +// Generates a textual failure message when a death test finds more than +// one thread running, or cannot determine the number of threads, prior +// to executing the given statement. It is the responsibility of the +// caller not to pass a thread_count of 1. +static std::string DeathTestThreadWarning(size_t thread_count) { + Message msg; + msg << "Death tests use fork(), which is unsafe particularly" + << " in a threaded context. For this test, " << GTEST_NAME_ << " "; + if (thread_count == 0) + msg << "couldn't detect the number of threads."; + else + msg << "detected " << thread_count << " threads."; + return msg.GetString(); +} +# endif // !GTEST_OS_WINDOWS + +// Flag characters for reporting a death test that did not die. +static const char kDeathTestLived = 'L'; +static const char kDeathTestReturned = 'R'; +static const char kDeathTestThrew = 'T'; +static const char kDeathTestInternalError = 'I'; + +// An enumeration describing all of the possible ways that a death test can +// conclude. DIED means that the process died while executing the test +// code; LIVED means that process lived beyond the end of the test code; +// RETURNED means that the test statement attempted to execute a return +// statement, which is not allowed; THREW means that the test statement +// returned control by throwing an exception. IN_PROGRESS means the test +// has not yet concluded. +// TODO(vladl@google.com): Unify names and possibly values for +// AbortReason, DeathTestOutcome, and flag characters above. +enum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED, THREW }; + +// Routine for aborting the program which is safe to call from an +// exec-style death test child process, in which case the error +// message is propagated back to the parent process. Otherwise, the +// message is simply printed to stderr. In either case, the program +// then exits with status 1. +void DeathTestAbort(const std::string& message) { + // On a POSIX system, this function may be called from a threadsafe-style + // death test child process, which operates on a very small stack. Use + // the heap for any additional non-minuscule memory requirements. + const InternalRunDeathTestFlag* const flag = + GetUnitTestImpl()->internal_run_death_test_flag(); + if (flag != NULL) { + FILE* parent = posix::FDOpen(flag->write_fd(), "w"); + fputc(kDeathTestInternalError, parent); + fprintf(parent, "%s", message.c_str()); + fflush(parent); + _exit(1); + } else { + fprintf(stderr, "%s", message.c_str()); + fflush(stderr); + posix::Abort(); + } +} + +// A replacement for CHECK that calls DeathTestAbort if the assertion +// fails. +# define GTEST_DEATH_TEST_CHECK_(expression) \ + do { \ + if (!::testing::internal::IsTrue(expression)) { \ + DeathTestAbort( \ + ::std::string("CHECK failed: File ") + __FILE__ + ", line " \ + + ::testing::internal::StreamableToString(__LINE__) + ": " \ + + #expression); \ + } \ + } while (::testing::internal::AlwaysFalse()) + +// This macro is similar to GTEST_DEATH_TEST_CHECK_, but it is meant for +// evaluating any system call that fulfills two conditions: it must return +// -1 on failure, and set errno to EINTR when it is interrupted and +// should be tried again. The macro expands to a loop that repeatedly +// evaluates the expression as long as it evaluates to -1 and sets +// errno to EINTR. If the expression evaluates to -1 but errno is +// something other than EINTR, DeathTestAbort is called. +# define GTEST_DEATH_TEST_CHECK_SYSCALL_(expression) \ + do { \ + int gtest_retval; \ + do { \ + gtest_retval = (expression); \ + } while (gtest_retval == -1 && errno == EINTR); \ + if (gtest_retval == -1) { \ + DeathTestAbort( \ + ::std::string("CHECK failed: File ") + __FILE__ + ", line " \ + + ::testing::internal::StreamableToString(__LINE__) + ": " \ + + #expression + " != -1"); \ + } \ + } while (::testing::internal::AlwaysFalse()) + +// Returns the message describing the last system error in errno. +std::string GetLastErrnoDescription() { + return errno == 0 ? "" : posix::StrError(errno); +} + +// This is called from a death test parent process to read a failure +// message from the death test child process and log it with the FATAL +// severity. On Windows, the message is read from a pipe handle. On other +// platforms, it is read from a file descriptor. +static void FailFromInternalError(int fd) { + Message error; + char buffer[256]; + int num_read; + + do { + while ((num_read = posix::Read(fd, buffer, 255)) > 0) { + buffer[num_read] = '\0'; + error << buffer; + } + } while (num_read == -1 && errno == EINTR); + + if (num_read == 0) { + GTEST_LOG_(FATAL) << error.GetString(); + } else { + const int last_error = errno; + GTEST_LOG_(FATAL) << "Error while reading death test internal: " + << GetLastErrnoDescription() << " [" << last_error << "]"; + } +} + +// Death test constructor. Increments the running death test count +// for the current test. +DeathTest::DeathTest() { + TestInfo* const info = GetUnitTestImpl()->current_test_info(); + if (info == NULL) { + DeathTestAbort("Cannot run a death test outside of a TEST or " + "TEST_F construct"); + } +} + +// Creates and returns a death test by dispatching to the current +// death test factory. +bool DeathTest::Create(const char* statement, const RE* regex, + const char* file, int line, DeathTest** test) { + return GetUnitTestImpl()->death_test_factory()->Create( + statement, regex, file, line, test); +} + +const char* DeathTest::LastMessage() { + return last_death_test_message_.c_str(); +} + +void DeathTest::set_last_death_test_message(const std::string& message) { + last_death_test_message_ = message; +} + +std::string DeathTest::last_death_test_message_; + +// Provides cross platform implementation for some death functionality. +class DeathTestImpl : public DeathTest { + protected: + DeathTestImpl(const char* a_statement, const RE* a_regex) + : statement_(a_statement), + regex_(a_regex), + spawned_(false), + status_(-1), + outcome_(IN_PROGRESS), + read_fd_(-1), + write_fd_(-1) {} + + // read_fd_ is expected to be closed and cleared by a derived class. + ~DeathTestImpl() { GTEST_DEATH_TEST_CHECK_(read_fd_ == -1); } + + void Abort(AbortReason reason); + virtual bool Passed(bool status_ok); + + const char* statement() const { return statement_; } + const RE* regex() const { return regex_; } + bool spawned() const { return spawned_; } + void set_spawned(bool is_spawned) { spawned_ = is_spawned; } + int status() const { return status_; } + void set_status(int a_status) { status_ = a_status; } + DeathTestOutcome outcome() const { return outcome_; } + void set_outcome(DeathTestOutcome an_outcome) { outcome_ = an_outcome; } + int read_fd() const { return read_fd_; } + void set_read_fd(int fd) { read_fd_ = fd; } + int write_fd() const { return write_fd_; } + void set_write_fd(int fd) { write_fd_ = fd; } + + // Called in the parent process only. Reads the result code of the death + // test child process via a pipe, interprets it to set the outcome_ + // member, and closes read_fd_. Outputs diagnostics and terminates in + // case of unexpected codes. + void ReadAndInterpretStatusByte(); + + private: + // The textual content of the code this object is testing. This class + // doesn't own this string and should not attempt to delete it. + const char* const statement_; + // The regular expression which test output must match. DeathTestImpl + // doesn't own this object and should not attempt to delete it. + const RE* const regex_; + // True if the death test child process has been successfully spawned. + bool spawned_; + // The exit status of the child process. + int status_; + // How the death test concluded. + DeathTestOutcome outcome_; + // Descriptor to the read end of the pipe to the child process. It is + // always -1 in the child process. The child keeps its write end of the + // pipe in write_fd_. + int read_fd_; + // Descriptor to the child's write end of the pipe to the parent process. + // It is always -1 in the parent process. The parent keeps its end of the + // pipe in read_fd_. + int write_fd_; +}; + +// Called in the parent process only. Reads the result code of the death +// test child process via a pipe, interprets it to set the outcome_ +// member, and closes read_fd_. Outputs diagnostics and terminates in +// case of unexpected codes. +void DeathTestImpl::ReadAndInterpretStatusByte() { + char flag; + int bytes_read; + + // The read() here blocks until data is available (signifying the + // failure of the death test) or until the pipe is closed (signifying + // its success), so it's okay to call this in the parent before + // the child process has exited. + do { + bytes_read = posix::Read(read_fd(), &flag, 1); + } while (bytes_read == -1 && errno == EINTR); + + if (bytes_read == 0) { + set_outcome(DIED); + } else if (bytes_read == 1) { + switch (flag) { + case kDeathTestReturned: + set_outcome(RETURNED); + break; + case kDeathTestThrew: + set_outcome(THREW); + break; + case kDeathTestLived: + set_outcome(LIVED); + break; + case kDeathTestInternalError: + FailFromInternalError(read_fd()); // Does not return. + break; + default: + GTEST_LOG_(FATAL) << "Death test child process reported " + << "unexpected status byte (" + << static_cast(flag) << ")"; + } + } else { + GTEST_LOG_(FATAL) << "Read from death test child process failed: " + << GetLastErrnoDescription(); + } + GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Close(read_fd())); + set_read_fd(-1); +} + +// Signals that the death test code which should have exited, didn't. +// Should be called only in a death test child process. +// Writes a status byte to the child's status file descriptor, then +// calls _exit(1). +void DeathTestImpl::Abort(AbortReason reason) { + // The parent process considers the death test to be a failure if + // it finds any data in our pipe. So, here we write a single flag byte + // to the pipe, then exit. + const char status_ch = + reason == TEST_DID_NOT_DIE ? kDeathTestLived : + reason == TEST_THREW_EXCEPTION ? kDeathTestThrew : kDeathTestReturned; + + GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Write(write_fd(), &status_ch, 1)); + // We are leaking the descriptor here because on some platforms (i.e., + // when built as Windows DLL), destructors of global objects will still + // run after calling _exit(). On such systems, write_fd_ will be + // indirectly closed from the destructor of UnitTestImpl, causing double + // close if it is also closed here. On debug configurations, double close + // may assert. As there are no in-process buffers to flush here, we are + // relying on the OS to close the descriptor after the process terminates + // when the destructors are not run. + _exit(1); // Exits w/o any normal exit hooks (we were supposed to crash) +} + +// Returns an indented copy of stderr output for a death test. +// This makes distinguishing death test output lines from regular log lines +// much easier. +static ::std::string FormatDeathTestOutput(const ::std::string& output) { + ::std::string ret; + for (size_t at = 0; ; ) { + const size_t line_end = output.find('\n', at); + ret += "[ DEATH ] "; + if (line_end == ::std::string::npos) { + ret += output.substr(at); + break; + } + ret += output.substr(at, line_end + 1 - at); + at = line_end + 1; + } + return ret; +} + +// Assesses the success or failure of a death test, using both private +// members which have previously been set, and one argument: +// +// Private data members: +// outcome: An enumeration describing how the death test +// concluded: DIED, LIVED, THREW, or RETURNED. The death test +// fails in the latter three cases. +// status: The exit status of the child process. On *nix, it is in the +// in the format specified by wait(2). On Windows, this is the +// value supplied to the ExitProcess() API or a numeric code +// of the exception that terminated the program. +// regex: A regular expression object to be applied to +// the test's captured standard error output; the death test +// fails if it does not match. +// +// Argument: +// status_ok: true if exit_status is acceptable in the context of +// this particular death test, which fails if it is false +// +// Returns true iff all of the above conditions are met. Otherwise, the +// first failing condition, in the order given above, is the one that is +// reported. Also sets the last death test message string. +bool DeathTestImpl::Passed(bool status_ok) { + if (!spawned()) + return false; + + const std::string error_message = GetCapturedStderr(); + + bool success = false; + Message buffer; + + buffer << "Death test: " << statement() << "\n"; + switch (outcome()) { + case LIVED: + buffer << " Result: failed to die.\n" + << " Error msg:\n" << FormatDeathTestOutput(error_message); + break; + case THREW: + buffer << " Result: threw an exception.\n" + << " Error msg:\n" << FormatDeathTestOutput(error_message); + break; + case RETURNED: + buffer << " Result: illegal return in test statement.\n" + << " Error msg:\n" << FormatDeathTestOutput(error_message); + break; + case DIED: + if (status_ok) { + const bool matched = RE::PartialMatch(error_message.c_str(), *regex()); + if (matched) { + success = true; + } else { + buffer << " Result: died but not with expected error.\n" + << " Expected: " << regex()->pattern() << "\n" + << "Actual msg:\n" << FormatDeathTestOutput(error_message); + } + } else { + buffer << " Result: died but not with expected exit code:\n" + << " " << ExitSummary(status()) << "\n" + << "Actual msg:\n" << FormatDeathTestOutput(error_message); + } + break; + case IN_PROGRESS: + default: + GTEST_LOG_(FATAL) + << "DeathTest::Passed somehow called before conclusion of test"; + } + + DeathTest::set_last_death_test_message(buffer.GetString()); + return success; +} + +# if GTEST_OS_WINDOWS +// WindowsDeathTest implements death tests on Windows. Due to the +// specifics of starting new processes on Windows, death tests there are +// always threadsafe, and Google Test considers the +// --gtest_death_test_style=fast setting to be equivalent to +// --gtest_death_test_style=threadsafe there. +// +// A few implementation notes: Like the Linux version, the Windows +// implementation uses pipes for child-to-parent communication. But due to +// the specifics of pipes on Windows, some extra steps are required: +// +// 1. The parent creates a communication pipe and stores handles to both +// ends of it. +// 2. The parent starts the child and provides it with the information +// necessary to acquire the handle to the write end of the pipe. +// 3. The child acquires the write end of the pipe and signals the parent +// using a Windows event. +// 4. Now the parent can release the write end of the pipe on its side. If +// this is done before step 3, the object's reference count goes down to +// 0 and it is destroyed, preventing the child from acquiring it. The +// parent now has to release it, or read operations on the read end of +// the pipe will not return when the child terminates. +// 5. The parent reads child's output through the pipe (outcome code and +// any possible error messages) from the pipe, and its stderr and then +// determines whether to fail the test. +// +// Note: to distinguish Win32 API calls from the local method and function +// calls, the former are explicitly resolved in the global namespace. +// +class WindowsDeathTest : public DeathTestImpl { + public: + WindowsDeathTest(const char* a_statement, + const RE* a_regex, + const char* file, + int line) + : DeathTestImpl(a_statement, a_regex), file_(file), line_(line) {} + + // All of these virtual functions are inherited from DeathTest. + virtual int Wait(); + virtual TestRole AssumeRole(); + + private: + // The name of the file in which the death test is located. + const char* const file_; + // The line number on which the death test is located. + const int line_; + // Handle to the write end of the pipe to the child process. + AutoHandle write_handle_; + // Child process handle. + AutoHandle child_handle_; + // Event the child process uses to signal the parent that it has + // acquired the handle to the write end of the pipe. After seeing this + // event the parent can release its own handles to make sure its + // ReadFile() calls return when the child terminates. + AutoHandle event_handle_; +}; + +// Waits for the child in a death test to exit, returning its exit +// status, or 0 if no child process exists. As a side effect, sets the +// outcome data member. +int WindowsDeathTest::Wait() { + if (!spawned()) + return 0; + + // Wait until the child either signals that it has acquired the write end + // of the pipe or it dies. + const HANDLE wait_handles[2] = { child_handle_.Get(), event_handle_.Get() }; + switch (::WaitForMultipleObjects(2, + wait_handles, + FALSE, // Waits for any of the handles. + INFINITE)) { + case WAIT_OBJECT_0: + case WAIT_OBJECT_0 + 1: + break; + default: + GTEST_DEATH_TEST_CHECK_(false); // Should not get here. + } + + // The child has acquired the write end of the pipe or exited. + // We release the handle on our side and continue. + write_handle_.Reset(); + event_handle_.Reset(); + + ReadAndInterpretStatusByte(); + + // Waits for the child process to exit if it haven't already. This + // returns immediately if the child has already exited, regardless of + // whether previous calls to WaitForMultipleObjects synchronized on this + // handle or not. + GTEST_DEATH_TEST_CHECK_( + WAIT_OBJECT_0 == ::WaitForSingleObject(child_handle_.Get(), + INFINITE)); + DWORD status_code; + GTEST_DEATH_TEST_CHECK_( + ::GetExitCodeProcess(child_handle_.Get(), &status_code) != FALSE); + child_handle_.Reset(); + set_status(static_cast(status_code)); + return status(); +} + +// The AssumeRole process for a Windows death test. It creates a child +// process with the same executable as the current process to run the +// death test. The child process is given the --gtest_filter and +// --gtest_internal_run_death_test flags such that it knows to run the +// current death test only. +DeathTest::TestRole WindowsDeathTest::AssumeRole() { + const UnitTestImpl* const impl = GetUnitTestImpl(); + const InternalRunDeathTestFlag* const flag = + impl->internal_run_death_test_flag(); + const TestInfo* const info = impl->current_test_info(); + const int death_test_index = info->result()->death_test_count(); + + if (flag != NULL) { + // ParseInternalRunDeathTestFlag() has performed all the necessary + // processing. + set_write_fd(flag->write_fd()); + return EXECUTE_TEST; + } + + // WindowsDeathTest uses an anonymous pipe to communicate results of + // a death test. + SECURITY_ATTRIBUTES handles_are_inheritable = { + sizeof(SECURITY_ATTRIBUTES), NULL, TRUE }; + HANDLE read_handle, write_handle; + GTEST_DEATH_TEST_CHECK_( + ::CreatePipe(&read_handle, &write_handle, &handles_are_inheritable, + 0) // Default buffer size. + != FALSE); + set_read_fd(::_open_osfhandle(reinterpret_cast(read_handle), + O_RDONLY)); + write_handle_.Reset(write_handle); + event_handle_.Reset(::CreateEvent( + &handles_are_inheritable, + TRUE, // The event will automatically reset to non-signaled state. + FALSE, // The initial state is non-signalled. + NULL)); // The even is unnamed. + GTEST_DEATH_TEST_CHECK_(event_handle_.Get() != NULL); + const std::string filter_flag = + std::string("--") + GTEST_FLAG_PREFIX_ + kFilterFlag + "=" + + info->test_case_name() + "." + info->name(); + const std::string internal_flag = + std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag + + "=" + file_ + "|" + StreamableToString(line_) + "|" + + StreamableToString(death_test_index) + "|" + + StreamableToString(static_cast(::GetCurrentProcessId())) + + // size_t has the same width as pointers on both 32-bit and 64-bit + // Windows platforms. + // See http://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx. + "|" + StreamableToString(reinterpret_cast(write_handle)) + + "|" + StreamableToString(reinterpret_cast(event_handle_.Get())); + + char executable_path[_MAX_PATH + 1]; // NOLINT + GTEST_DEATH_TEST_CHECK_( + _MAX_PATH + 1 != ::GetModuleFileNameA(NULL, + executable_path, + _MAX_PATH)); + + std::string command_line = + std::string(::GetCommandLineA()) + " " + filter_flag + " \"" + + internal_flag + "\""; + + DeathTest::set_last_death_test_message(""); + + CaptureStderr(); + // Flush the log buffers since the log streams are shared with the child. + FlushInfoLog(); + + // The child process will share the standard handles with the parent. + STARTUPINFOA startup_info; + memset(&startup_info, 0, sizeof(STARTUPINFO)); + startup_info.dwFlags = STARTF_USESTDHANDLES; + startup_info.hStdInput = ::GetStdHandle(STD_INPUT_HANDLE); + startup_info.hStdOutput = ::GetStdHandle(STD_OUTPUT_HANDLE); + startup_info.hStdError = ::GetStdHandle(STD_ERROR_HANDLE); + + PROCESS_INFORMATION process_info; + GTEST_DEATH_TEST_CHECK_(::CreateProcessA( + executable_path, + const_cast(command_line.c_str()), + NULL, // Retuned process handle is not inheritable. + NULL, // Retuned thread handle is not inheritable. + TRUE, // Child inherits all inheritable handles (for write_handle_). + 0x0, // Default creation flags. + NULL, // Inherit the parent's environment. + UnitTest::GetInstance()->original_working_dir(), + &startup_info, + &process_info) != FALSE); + child_handle_.Reset(process_info.hProcess); + ::CloseHandle(process_info.hThread); + set_spawned(true); + return OVERSEE_TEST; +} +# else // We are not on Windows. + +// ForkingDeathTest provides implementations for most of the abstract +// methods of the DeathTest interface. Only the AssumeRole method is +// left undefined. +class ForkingDeathTest : public DeathTestImpl { + public: + ForkingDeathTest(const char* statement, const RE* regex); + + // All of these virtual functions are inherited from DeathTest. + virtual int Wait(); + + protected: + void set_child_pid(pid_t child_pid) { child_pid_ = child_pid; } + + private: + // PID of child process during death test; 0 in the child process itself. + pid_t child_pid_; +}; + +// Constructs a ForkingDeathTest. +ForkingDeathTest::ForkingDeathTest(const char* a_statement, const RE* a_regex) + : DeathTestImpl(a_statement, a_regex), + child_pid_(-1) {} + +// Waits for the child in a death test to exit, returning its exit +// status, or 0 if no child process exists. As a side effect, sets the +// outcome data member. +int ForkingDeathTest::Wait() { + if (!spawned()) + return 0; + + ReadAndInterpretStatusByte(); + + int status_value; + GTEST_DEATH_TEST_CHECK_SYSCALL_(waitpid(child_pid_, &status_value, 0)); + set_status(status_value); + return status_value; +} + +// A concrete death test class that forks, then immediately runs the test +// in the child process. +class NoExecDeathTest : public ForkingDeathTest { + public: + NoExecDeathTest(const char* a_statement, const RE* a_regex) : + ForkingDeathTest(a_statement, a_regex) { } + virtual TestRole AssumeRole(); +}; + +// The AssumeRole process for a fork-and-run death test. It implements a +// straightforward fork, with a simple pipe to transmit the status byte. +DeathTest::TestRole NoExecDeathTest::AssumeRole() { + const size_t thread_count = GetThreadCount(); + if (thread_count != 1) { + GTEST_LOG_(WARNING) << DeathTestThreadWarning(thread_count); + } + + int pipe_fd[2]; + GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1); + + DeathTest::set_last_death_test_message(""); + CaptureStderr(); + // When we fork the process below, the log file buffers are copied, but the + // file descriptors are shared. We flush all log files here so that closing + // the file descriptors in the child process doesn't throw off the + // synchronization between descriptors and buffers in the parent process. + // This is as close to the fork as possible to avoid a race condition in case + // there are multiple threads running before the death test, and another + // thread writes to the log file. + FlushInfoLog(); + + const pid_t child_pid = fork(); + GTEST_DEATH_TEST_CHECK_(child_pid != -1); + set_child_pid(child_pid); + if (child_pid == 0) { + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[0])); + set_write_fd(pipe_fd[1]); + // Redirects all logging to stderr in the child process to prevent + // concurrent writes to the log files. We capture stderr in the parent + // process and append the child process' output to a log. + LogToStderr(); + // Event forwarding to the listeners of event listener API mush be shut + // down in death test subprocesses. + GetUnitTestImpl()->listeners()->SuppressEventForwarding(); + g_in_fast_death_test_child = true; + return EXECUTE_TEST; + } else { + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); + set_read_fd(pipe_fd[0]); + set_spawned(true); + return OVERSEE_TEST; + } +} + +// A concrete death test class that forks and re-executes the main +// program from the beginning, with command-line flags set that cause +// only this specific death test to be run. +class ExecDeathTest : public ForkingDeathTest { + public: + ExecDeathTest(const char* a_statement, const RE* a_regex, + const char* file, int line) : + ForkingDeathTest(a_statement, a_regex), file_(file), line_(line) { } + virtual TestRole AssumeRole(); + private: + static ::std::vector + GetArgvsForDeathTestChildProcess() { + ::std::vector args = GetInjectableArgvs(); + return args; + } + // The name of the file in which the death test is located. + const char* const file_; + // The line number on which the death test is located. + const int line_; +}; + +// Utility class for accumulating command-line arguments. +class Arguments { + public: + Arguments() { + args_.push_back(NULL); + } + + ~Arguments() { + for (std::vector::iterator i = args_.begin(); i != args_.end(); + ++i) { + free(*i); + } + } + void AddArgument(const char* argument) { + args_.insert(args_.end() - 1, posix::StrDup(argument)); + } + + template + void AddArguments(const ::std::vector& arguments) { + for (typename ::std::vector::const_iterator i = arguments.begin(); + i != arguments.end(); + ++i) { + args_.insert(args_.end() - 1, posix::StrDup(i->c_str())); + } + } + char* const* Argv() { + return &args_[0]; + } + + private: + std::vector args_; +}; + +// A struct that encompasses the arguments to the child process of a +// threadsafe-style death test process. +struct ExecDeathTestArgs { + char* const* argv; // Command-line arguments for the child's call to exec + int close_fd; // File descriptor to close; the read end of a pipe +}; + +# if GTEST_OS_MAC +inline char** GetEnviron() { + // When Google Test is built as a framework on MacOS X, the environ variable + // is unavailable. Apple's documentation (man environ) recommends using + // _NSGetEnviron() instead. + return *_NSGetEnviron(); +} +# else +// Some POSIX platforms expect you to declare environ. extern "C" makes +// it reside in the global namespace. +extern "C" char** environ; +inline char** GetEnviron() { return environ; } +# endif // GTEST_OS_MAC + +# if !GTEST_OS_QNX +// The main function for a threadsafe-style death test child process. +// This function is called in a clone()-ed process and thus must avoid +// any potentially unsafe operations like malloc or libc functions. +static int ExecDeathTestChildMain(void* child_arg) { + ExecDeathTestArgs* const args = static_cast(child_arg); + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(args->close_fd)); + + // We need to execute the test program in the same environment where + // it was originally invoked. Therefore we change to the original + // working directory first. + const char* const original_dir = + UnitTest::GetInstance()->original_working_dir(); + // We can safely call chdir() as it's a direct system call. + if (chdir(original_dir) != 0) { + DeathTestAbort(std::string("chdir(\"") + original_dir + "\") failed: " + + GetLastErrnoDescription()); + return EXIT_FAILURE; + } + + // We can safely call execve() as it's a direct system call. We + // cannot use execvp() as it's a libc function and thus potentially + // unsafe. Since execve() doesn't search the PATH, the user must + // invoke the test program via a valid path that contains at least + // one path separator. + execve(args->argv[0], args->argv, GetEnviron()); + DeathTestAbort(std::string("execve(") + args->argv[0] + ", ...) in " + + original_dir + " failed: " + + GetLastErrnoDescription()); + return EXIT_FAILURE; +} +# endif // !GTEST_OS_QNX + +// Two utility routines that together determine the direction the stack +// grows. +// This could be accomplished more elegantly by a single recursive +// function, but we want to guard against the unlikely possibility of +// a smart compiler optimizing the recursion away. +// +// GTEST_NO_INLINE_ is required to prevent GCC 4.6 from inlining +// StackLowerThanAddress into StackGrowsDown, which then doesn't give +// correct answer. +void StackLowerThanAddress(const void* ptr, bool* result) GTEST_NO_INLINE_; +void StackLowerThanAddress(const void* ptr, bool* result) { + int dummy; + *result = (&dummy < ptr); +} + +bool StackGrowsDown() { + int dummy; + bool result; + StackLowerThanAddress(&dummy, &result); + return result; +} + +// Spawns a child process with the same executable as the current process in +// a thread-safe manner and instructs it to run the death test. The +// implementation uses fork(2) + exec. On systems where clone(2) is +// available, it is used instead, being slightly more thread-safe. On QNX, +// fork supports only single-threaded environments, so this function uses +// spawn(2) there instead. The function dies with an error message if +// anything goes wrong. +static pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) { + ExecDeathTestArgs args = { argv, close_fd }; + pid_t child_pid = -1; + +# if GTEST_OS_QNX + // Obtains the current directory and sets it to be closed in the child + // process. + const int cwd_fd = open(".", O_RDONLY); + GTEST_DEATH_TEST_CHECK_(cwd_fd != -1); + GTEST_DEATH_TEST_CHECK_SYSCALL_(fcntl(cwd_fd, F_SETFD, FD_CLOEXEC)); + // We need to execute the test program in the same environment where + // it was originally invoked. Therefore we change to the original + // working directory first. + const char* const original_dir = + UnitTest::GetInstance()->original_working_dir(); + // We can safely call chdir() as it's a direct system call. + if (chdir(original_dir) != 0) { + DeathTestAbort(std::string("chdir(\"") + original_dir + "\") failed: " + + GetLastErrnoDescription()); + return EXIT_FAILURE; + } + + int fd_flags; + // Set close_fd to be closed after spawn. + GTEST_DEATH_TEST_CHECK_SYSCALL_(fd_flags = fcntl(close_fd, F_GETFD)); + GTEST_DEATH_TEST_CHECK_SYSCALL_(fcntl(close_fd, F_SETFD, + fd_flags | FD_CLOEXEC)); + struct inheritance inherit = {0}; + // spawn is a system call. + child_pid = spawn(args.argv[0], 0, NULL, &inherit, args.argv, GetEnviron()); + // Restores the current working directory. + GTEST_DEATH_TEST_CHECK_(fchdir(cwd_fd) != -1); + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(cwd_fd)); + +# else // GTEST_OS_QNX +# if GTEST_OS_LINUX + // When a SIGPROF signal is received while fork() or clone() are executing, + // the process may hang. To avoid this, we ignore SIGPROF here and re-enable + // it after the call to fork()/clone() is complete. + struct sigaction saved_sigprof_action; + struct sigaction ignore_sigprof_action; + memset(&ignore_sigprof_action, 0, sizeof(ignore_sigprof_action)); + sigemptyset(&ignore_sigprof_action.sa_mask); + ignore_sigprof_action.sa_handler = SIG_IGN; + GTEST_DEATH_TEST_CHECK_SYSCALL_(sigaction( + SIGPROF, &ignore_sigprof_action, &saved_sigprof_action)); +# endif // GTEST_OS_LINUX + +# if GTEST_HAS_CLONE + const bool use_fork = GTEST_FLAG(death_test_use_fork); + + if (!use_fork) { + static const bool stack_grows_down = StackGrowsDown(); + const size_t stack_size = getpagesize(); + // MMAP_ANONYMOUS is not defined on Mac, so we use MAP_ANON instead. + void* const stack = mmap(NULL, stack_size, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE, -1, 0); + GTEST_DEATH_TEST_CHECK_(stack != MAP_FAILED); + + // Maximum stack alignment in bytes: For a downward-growing stack, this + // amount is subtracted from size of the stack space to get an address + // that is within the stack space and is aligned on all systems we care + // about. As far as I know there is no ABI with stack alignment greater + // than 64. We assume stack and stack_size already have alignment of + // kMaxStackAlignment. + const size_t kMaxStackAlignment = 64; + void* const stack_top = + static_cast(stack) + + (stack_grows_down ? stack_size - kMaxStackAlignment : 0); + GTEST_DEATH_TEST_CHECK_(stack_size > kMaxStackAlignment && + reinterpret_cast(stack_top) % kMaxStackAlignment == 0); + + child_pid = clone(&ExecDeathTestChildMain, stack_top, SIGCHLD, &args); + + GTEST_DEATH_TEST_CHECK_(munmap(stack, stack_size) != -1); + } +# else + const bool use_fork = true; +# endif // GTEST_HAS_CLONE + + if (use_fork && (child_pid = fork()) == 0) { + ExecDeathTestChildMain(&args); + _exit(0); + } +# endif // GTEST_OS_QNX +# if GTEST_OS_LINUX + GTEST_DEATH_TEST_CHECK_SYSCALL_( + sigaction(SIGPROF, &saved_sigprof_action, NULL)); +# endif // GTEST_OS_LINUX + + GTEST_DEATH_TEST_CHECK_(child_pid != -1); + return child_pid; +} + +// The AssumeRole process for a fork-and-exec death test. It re-executes the +// main program from the beginning, setting the --gtest_filter +// and --gtest_internal_run_death_test flags to cause only the current +// death test to be re-run. +DeathTest::TestRole ExecDeathTest::AssumeRole() { + const UnitTestImpl* const impl = GetUnitTestImpl(); + const InternalRunDeathTestFlag* const flag = + impl->internal_run_death_test_flag(); + const TestInfo* const info = impl->current_test_info(); + const int death_test_index = info->result()->death_test_count(); + + if (flag != NULL) { + set_write_fd(flag->write_fd()); + return EXECUTE_TEST; + } + + int pipe_fd[2]; + GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1); + // Clear the close-on-exec flag on the write end of the pipe, lest + // it be closed when the child process does an exec: + GTEST_DEATH_TEST_CHECK_(fcntl(pipe_fd[1], F_SETFD, 0) != -1); + + const std::string filter_flag = + std::string("--") + GTEST_FLAG_PREFIX_ + kFilterFlag + "=" + + info->test_case_name() + "." + info->name(); + const std::string internal_flag = + std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag + "=" + + file_ + "|" + StreamableToString(line_) + "|" + + StreamableToString(death_test_index) + "|" + + StreamableToString(pipe_fd[1]); + Arguments args; + args.AddArguments(GetArgvsForDeathTestChildProcess()); + args.AddArgument(filter_flag.c_str()); + args.AddArgument(internal_flag.c_str()); + + DeathTest::set_last_death_test_message(""); + + CaptureStderr(); + // See the comment in NoExecDeathTest::AssumeRole for why the next line + // is necessary. + FlushInfoLog(); + + const pid_t child_pid = ExecDeathTestSpawnChild(args.Argv(), pipe_fd[0]); + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); + set_child_pid(child_pid); + set_read_fd(pipe_fd[0]); + set_spawned(true); + return OVERSEE_TEST; +} + +# endif // !GTEST_OS_WINDOWS + +// Creates a concrete DeathTest-derived class that depends on the +// --gtest_death_test_style flag, and sets the pointer pointed to +// by the "test" argument to its address. If the test should be +// skipped, sets that pointer to NULL. Returns true, unless the +// flag is set to an invalid value. +bool DefaultDeathTestFactory::Create(const char* statement, const RE* regex, + const char* file, int line, + DeathTest** test) { + UnitTestImpl* const impl = GetUnitTestImpl(); + const InternalRunDeathTestFlag* const flag = + impl->internal_run_death_test_flag(); + const int death_test_index = impl->current_test_info() + ->increment_death_test_count(); + + if (flag != NULL) { + if (death_test_index > flag->index()) { + DeathTest::set_last_death_test_message( + "Death test count (" + StreamableToString(death_test_index) + + ") somehow exceeded expected maximum (" + + StreamableToString(flag->index()) + ")"); + return false; + } + + if (!(flag->file() == file && flag->line() == line && + flag->index() == death_test_index)) { + *test = NULL; + return true; + } + } + +# if GTEST_OS_WINDOWS + + if (GTEST_FLAG(death_test_style) == "threadsafe" || + GTEST_FLAG(death_test_style) == "fast") { + *test = new WindowsDeathTest(statement, regex, file, line); + } + +# else + + if (GTEST_FLAG(death_test_style) == "threadsafe") { + *test = new ExecDeathTest(statement, regex, file, line); + } else if (GTEST_FLAG(death_test_style) == "fast") { + *test = new NoExecDeathTest(statement, regex); + } + +# endif // GTEST_OS_WINDOWS + + else { // NOLINT - this is more readable than unbalanced brackets inside #if. + DeathTest::set_last_death_test_message( + "Unknown death test style \"" + GTEST_FLAG(death_test_style) + + "\" encountered"); + return false; + } + + return true; +} + +// Splits a given string on a given delimiter, populating a given +// vector with the fields. GTEST_HAS_DEATH_TEST implies that we have +// ::std::string, so we can use it here. +static void SplitString(const ::std::string& str, char delimiter, + ::std::vector< ::std::string>* dest) { + ::std::vector< ::std::string> parsed; + ::std::string::size_type pos = 0; + while (::testing::internal::AlwaysTrue()) { + const ::std::string::size_type colon = str.find(delimiter, pos); + if (colon == ::std::string::npos) { + parsed.push_back(str.substr(pos)); + break; + } else { + parsed.push_back(str.substr(pos, colon - pos)); + pos = colon + 1; + } + } + dest->swap(parsed); +} + +# if GTEST_OS_WINDOWS +// Recreates the pipe and event handles from the provided parameters, +// signals the event, and returns a file descriptor wrapped around the pipe +// handle. This function is called in the child process only. +int GetStatusFileDescriptor(unsigned int parent_process_id, + size_t write_handle_as_size_t, + size_t event_handle_as_size_t) { + AutoHandle parent_process_handle(::OpenProcess(PROCESS_DUP_HANDLE, + FALSE, // Non-inheritable. + parent_process_id)); + if (parent_process_handle.Get() == INVALID_HANDLE_VALUE) { + DeathTestAbort("Unable to open parent process " + + StreamableToString(parent_process_id)); + } + + // TODO(vladl@google.com): Replace the following check with a + // compile-time assertion when available. + GTEST_CHECK_(sizeof(HANDLE) <= sizeof(size_t)); + + const HANDLE write_handle = + reinterpret_cast(write_handle_as_size_t); + HANDLE dup_write_handle; + + // The newly initialized handle is accessible only in in the parent + // process. To obtain one accessible within the child, we need to use + // DuplicateHandle. + if (!::DuplicateHandle(parent_process_handle.Get(), write_handle, + ::GetCurrentProcess(), &dup_write_handle, + 0x0, // Requested privileges ignored since + // DUPLICATE_SAME_ACCESS is used. + FALSE, // Request non-inheritable handler. + DUPLICATE_SAME_ACCESS)) { + DeathTestAbort("Unable to duplicate the pipe handle " + + StreamableToString(write_handle_as_size_t) + + " from the parent process " + + StreamableToString(parent_process_id)); + } + + const HANDLE event_handle = reinterpret_cast(event_handle_as_size_t); + HANDLE dup_event_handle; + + if (!::DuplicateHandle(parent_process_handle.Get(), event_handle, + ::GetCurrentProcess(), &dup_event_handle, + 0x0, + FALSE, + DUPLICATE_SAME_ACCESS)) { + DeathTestAbort("Unable to duplicate the event handle " + + StreamableToString(event_handle_as_size_t) + + " from the parent process " + + StreamableToString(parent_process_id)); + } + + const int write_fd = + ::_open_osfhandle(reinterpret_cast(dup_write_handle), O_APPEND); + if (write_fd == -1) { + DeathTestAbort("Unable to convert pipe handle " + + StreamableToString(write_handle_as_size_t) + + " to a file descriptor"); + } + + // Signals the parent that the write end of the pipe has been acquired + // so the parent can release its own write end. + ::SetEvent(dup_event_handle); + + return write_fd; +} +# endif // GTEST_OS_WINDOWS + +// Returns a newly created InternalRunDeathTestFlag object with fields +// initialized from the GTEST_FLAG(internal_run_death_test) flag if +// the flag is specified; otherwise returns NULL. +InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() { + if (GTEST_FLAG(internal_run_death_test) == "") return NULL; + + // GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we + // can use it here. + int line = -1; + int index = -1; + ::std::vector< ::std::string> fields; + SplitString(GTEST_FLAG(internal_run_death_test).c_str(), '|', &fields); + int write_fd = -1; + +# if GTEST_OS_WINDOWS + + unsigned int parent_process_id = 0; + size_t write_handle_as_size_t = 0; + size_t event_handle_as_size_t = 0; + + if (fields.size() != 6 + || !ParseNaturalNumber(fields[1], &line) + || !ParseNaturalNumber(fields[2], &index) + || !ParseNaturalNumber(fields[3], &parent_process_id) + || !ParseNaturalNumber(fields[4], &write_handle_as_size_t) + || !ParseNaturalNumber(fields[5], &event_handle_as_size_t)) { + DeathTestAbort("Bad --gtest_internal_run_death_test flag: " + + GTEST_FLAG(internal_run_death_test)); + } + write_fd = GetStatusFileDescriptor(parent_process_id, + write_handle_as_size_t, + event_handle_as_size_t); +# else + + if (fields.size() != 4 + || !ParseNaturalNumber(fields[1], &line) + || !ParseNaturalNumber(fields[2], &index) + || !ParseNaturalNumber(fields[3], &write_fd)) { + DeathTestAbort("Bad --gtest_internal_run_death_test flag: " + + GTEST_FLAG(internal_run_death_test)); + } + +# endif // GTEST_OS_WINDOWS + + return new InternalRunDeathTestFlag(fields[0], line, index, write_fd); +} + +} // namespace internal + +#endif // GTEST_HAS_DEATH_TEST + +} // namespace testing +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: keith.ray@gmail.com (Keith Ray) + + +#include + +#if GTEST_OS_WINDOWS_MOBILE +# include +#elif GTEST_OS_WINDOWS +# include +# include +#elif GTEST_OS_SYMBIAN +// Symbian OpenC has PATH_MAX in sys/syslimits.h +# include +#else +# include +# include // Some Linux distributions define PATH_MAX here. +#endif // GTEST_OS_WINDOWS_MOBILE + +#if GTEST_OS_WINDOWS +# define GTEST_PATH_MAX_ _MAX_PATH +#elif defined(PATH_MAX) +# define GTEST_PATH_MAX_ PATH_MAX +#elif defined(_XOPEN_PATH_MAX) +# define GTEST_PATH_MAX_ _XOPEN_PATH_MAX +#else +# define GTEST_PATH_MAX_ _POSIX_PATH_MAX +#endif // GTEST_OS_WINDOWS + + +namespace testing { +namespace internal { + +#if GTEST_OS_WINDOWS +// On Windows, '\\' is the standard path separator, but many tools and the +// Windows API also accept '/' as an alternate path separator. Unless otherwise +// noted, a file path can contain either kind of path separators, or a mixture +// of them. +const char kPathSeparator = '\\'; +const char kAlternatePathSeparator = '/'; +//const char kPathSeparatorString[] = "\\"; +const char kAlternatePathSeparatorString[] = "/"; +# if GTEST_OS_WINDOWS_MOBILE +// Windows CE doesn't have a current directory. You should not use +// the current directory in tests on Windows CE, but this at least +// provides a reasonable fallback. +const char kCurrentDirectoryString[] = "\\"; +// Windows CE doesn't define INVALID_FILE_ATTRIBUTES +const DWORD kInvalidFileAttributes = 0xffffffff; +# else +const char kCurrentDirectoryString[] = ".\\"; +# endif // GTEST_OS_WINDOWS_MOBILE +#else +const char kPathSeparator = '/'; +//const char kPathSeparatorString[] = "/"; +const char kCurrentDirectoryString[] = "./"; +#endif // GTEST_OS_WINDOWS + +// Returns whether the given character is a valid path separator. +static bool IsPathSeparator(char c) { +#if GTEST_HAS_ALT_PATH_SEP_ + return (c == kPathSeparator) || (c == kAlternatePathSeparator); +#else + return c == kPathSeparator; +#endif +} + +// Returns the current working directory, or "" if unsuccessful. +FilePath FilePath::GetCurrentDir() { +#if GTEST_OS_WINDOWS_MOBILE + // Windows CE doesn't have a current directory, so we just return + // something reasonable. + return FilePath(kCurrentDirectoryString); +#elif GTEST_OS_WINDOWS + char cwd[GTEST_PATH_MAX_ + 1] = { '\0' }; + return FilePath(_getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd); +#else + char cwd[GTEST_PATH_MAX_ + 1] = { '\0' }; + return FilePath(getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd); +#endif // GTEST_OS_WINDOWS_MOBILE +} + +// Returns a copy of the FilePath with the case-insensitive extension removed. +// Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns +// FilePath("dir/file"). If a case-insensitive extension is not +// found, returns a copy of the original FilePath. +FilePath FilePath::RemoveExtension(const char* extension) const { + const std::string dot_extension = std::string(".") + extension; + if (String::EndsWithCaseInsensitive(pathname_, dot_extension)) { + return FilePath(pathname_.substr( + 0, pathname_.length() - dot_extension.length())); + } + return *this; +} + +// Returns a pointer to the last occurence of a valid path separator in +// the FilePath. On Windows, for example, both '/' and '\' are valid path +// separators. Returns NULL if no path separator was found. +const char* FilePath::FindLastPathSeparator() const { + const char* const last_sep = strrchr(c_str(), kPathSeparator); +#if GTEST_HAS_ALT_PATH_SEP_ + const char* const last_alt_sep = strrchr(c_str(), kAlternatePathSeparator); + // Comparing two pointers of which only one is NULL is undefined. + if (last_alt_sep != NULL && + (last_sep == NULL || last_alt_sep > last_sep)) { + return last_alt_sep; + } +#endif + return last_sep; +} + +// Returns a copy of the FilePath with the directory part removed. +// Example: FilePath("path/to/file").RemoveDirectoryName() returns +// FilePath("file"). If there is no directory part ("just_a_file"), it returns +// the FilePath unmodified. If there is no file part ("just_a_dir/") it +// returns an empty FilePath (""). +// On Windows platform, '\' is the path separator, otherwise it is '/'. +FilePath FilePath::RemoveDirectoryName() const { + const char* const last_sep = FindLastPathSeparator(); + return last_sep ? FilePath(last_sep + 1) : *this; +} + +// RemoveFileName returns the directory path with the filename removed. +// Example: FilePath("path/to/file").RemoveFileName() returns "path/to/". +// If the FilePath is "a_file" or "/a_file", RemoveFileName returns +// FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does +// not have a file, like "just/a/dir/", it returns the FilePath unmodified. +// On Windows platform, '\' is the path separator, otherwise it is '/'. +FilePath FilePath::RemoveFileName() const { + const char* const last_sep = FindLastPathSeparator(); + std::string dir; + if (last_sep) { + dir = std::string(c_str(), last_sep + 1 - c_str()); + } else { + dir = kCurrentDirectoryString; + } + return FilePath(dir); +} + +// Helper functions for naming files in a directory for xml output. + +// Given directory = "dir", base_name = "test", number = 0, +// extension = "xml", returns "dir/test.xml". If number is greater +// than zero (e.g., 12), returns "dir/test_12.xml". +// On Windows platform, uses \ as the separator rather than /. +FilePath FilePath::MakeFileName(const FilePath& directory, + const FilePath& base_name, + int number, + const char* extension) { + std::string file; + if (number == 0) { + file = base_name.string() + "." + extension; + } else { + file = base_name.string() + "_" + StreamableToString(number) + + "." + extension; + } + return ConcatPaths(directory, FilePath(file)); +} + +// Given directory = "dir", relative_path = "test.xml", returns "dir/test.xml". +// On Windows, uses \ as the separator rather than /. +FilePath FilePath::ConcatPaths(const FilePath& directory, + const FilePath& relative_path) { + if (directory.IsEmpty()) + return relative_path; + const FilePath dir(directory.RemoveTrailingPathSeparator()); + return FilePath(dir.string() + kPathSeparator + relative_path.string()); +} + +// Returns true if pathname describes something findable in the file-system, +// either a file, directory, or whatever. +bool FilePath::FileOrDirectoryExists() const { +#if GTEST_OS_WINDOWS_MOBILE + LPCWSTR unicode = String::AnsiToUtf16(pathname_.c_str()); + const DWORD attributes = GetFileAttributes(unicode); + delete [] unicode; + return attributes != kInvalidFileAttributes; +#else + posix::StatStruct file_stat; + return posix::Stat(pathname_.c_str(), &file_stat) == 0; +#endif // GTEST_OS_WINDOWS_MOBILE +} + +// Returns true if pathname describes a directory in the file-system +// that exists. +bool FilePath::DirectoryExists() const { + bool result = false; +#if GTEST_OS_WINDOWS + // Don't strip off trailing separator if path is a root directory on + // Windows (like "C:\\"). + const FilePath& path(IsRootDirectory() ? *this : + RemoveTrailingPathSeparator()); +#else + const FilePath& path(*this); +#endif + +#if GTEST_OS_WINDOWS_MOBILE + LPCWSTR unicode = String::AnsiToUtf16(path.c_str()); + const DWORD attributes = GetFileAttributes(unicode); + delete [] unicode; + if ((attributes != kInvalidFileAttributes) && + (attributes & FILE_ATTRIBUTE_DIRECTORY)) { + result = true; + } +#else + posix::StatStruct file_stat; + result = posix::Stat(path.c_str(), &file_stat) == 0 && + posix::IsDir(file_stat); +#endif // GTEST_OS_WINDOWS_MOBILE + + return result; +} + +// Returns true if pathname describes a root directory. (Windows has one +// root directory per disk drive.) +bool FilePath::IsRootDirectory() const { +#if GTEST_OS_WINDOWS + // TODO(wan@google.com): on Windows a network share like + // \\server\share can be a root directory, although it cannot be the + // current directory. Handle this properly. + return pathname_.length() == 3 && IsAbsolutePath(); +#else + return pathname_.length() == 1 && IsPathSeparator(pathname_.c_str()[0]); +#endif +} + +// Returns true if pathname describes an absolute path. +bool FilePath::IsAbsolutePath() const { + const char* const name = pathname_.c_str(); +#if GTEST_OS_WINDOWS + return pathname_.length() >= 3 && + ((name[0] >= 'a' && name[0] <= 'z') || + (name[0] >= 'A' && name[0] <= 'Z')) && + name[1] == ':' && + IsPathSeparator(name[2]); +#else + return IsPathSeparator(name[0]); +#endif +} + +// Returns a pathname for a file that does not currently exist. The pathname +// will be directory/base_name.extension or +// directory/base_name_.extension if directory/base_name.extension +// already exists. The number will be incremented until a pathname is found +// that does not already exist. +// Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'. +// There could be a race condition if two or more processes are calling this +// function at the same time -- they could both pick the same filename. +FilePath FilePath::GenerateUniqueFileName(const FilePath& directory, + const FilePath& base_name, + const char* extension) { + FilePath full_pathname; + int number = 0; + do { + full_pathname.Set(MakeFileName(directory, base_name, number++, extension)); + } while (full_pathname.FileOrDirectoryExists()); + return full_pathname; +} + +// Returns true if FilePath ends with a path separator, which indicates that +// it is intended to represent a directory. Returns false otherwise. +// This does NOT check that a directory (or file) actually exists. +bool FilePath::IsDirectory() const { + return !pathname_.empty() && + IsPathSeparator(pathname_.c_str()[pathname_.length() - 1]); +} + +// Create directories so that path exists. Returns true if successful or if +// the directories already exist; returns false if unable to create directories +// for any reason. +bool FilePath::CreateDirectoriesRecursively() const { + if (!this->IsDirectory()) { + return false; + } + + if (pathname_.length() == 0 || this->DirectoryExists()) { + return true; + } + + const FilePath parent(this->RemoveTrailingPathSeparator().RemoveFileName()); + return parent.CreateDirectoriesRecursively() && this->CreateFolder(); +} + +// Create the directory so that path exists. Returns true if successful or +// if the directory already exists; returns false if unable to create the +// directory for any reason, including if the parent directory does not +// exist. Not named "CreateDirectory" because that's a macro on Windows. +bool FilePath::CreateFolder() const { +#if GTEST_OS_WINDOWS_MOBILE + FilePath removed_sep(this->RemoveTrailingPathSeparator()); + LPCWSTR unicode = String::AnsiToUtf16(removed_sep.c_str()); + int result = CreateDirectory(unicode, NULL) ? 0 : -1; + delete [] unicode; +#elif GTEST_OS_WINDOWS + int result = _mkdir(pathname_.c_str()); +#else + int result = mkdir(pathname_.c_str(), 0777); +#endif // GTEST_OS_WINDOWS_MOBILE + + if (result == -1) { + return this->DirectoryExists(); // An error is OK if the directory exists. + } + return true; // No error. +} + +// If input name has a trailing separator character, remove it and return the +// name, otherwise return the name string unmodified. +// On Windows platform, uses \ as the separator, other platforms use /. +FilePath FilePath::RemoveTrailingPathSeparator() const { + return IsDirectory() + ? FilePath(pathname_.substr(0, pathname_.length() - 1)) + : *this; +} + +// Removes any redundant separators that might be in the pathname. +// For example, "bar///foo" becomes "bar/foo". Does not eliminate other +// redundancies that might be in a pathname involving "." or "..". +// TODO(wan@google.com): handle Windows network shares (e.g. \\server\share). +void FilePath::Normalize() { + if (pathname_.c_str() == NULL) { + pathname_ = ""; + return; + } + const char* src = pathname_.c_str(); + char* const dest = new char[pathname_.length() + 1]; + char* dest_ptr = dest; + memset(dest_ptr, 0, pathname_.length() + 1); + + while (*src != '\0') { + *dest_ptr = *src; + if (!IsPathSeparator(*src)) { + src++; + } else { +#if GTEST_HAS_ALT_PATH_SEP_ + if (*dest_ptr == kAlternatePathSeparator) { + *dest_ptr = kPathSeparator; + } +#endif + while (IsPathSeparator(*src)) + src++; + } + dest_ptr++; + } + *dest_ptr = '\0'; + pathname_ = dest; + delete[] dest; +} + +} // namespace internal +} // namespace testing +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) + + +#include +#include +#include +#include + +#if GTEST_OS_WINDOWS_MOBILE +# include // For TerminateProcess() +#elif GTEST_OS_WINDOWS +# include +# include +#else +# include +#endif // GTEST_OS_WINDOWS_MOBILE + +#if GTEST_OS_MAC +# include +# include +# include +#endif // GTEST_OS_MAC + +#if GTEST_OS_QNX +# include +# include +#endif // GTEST_OS_QNX + + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION_ 1 +#undef GTEST_IMPLEMENTATION_ + +namespace testing { +namespace internal { + +#if defined(_MSC_VER) || defined(__BORLANDC__) +// MSVC and C++Builder do not provide a definition of STDERR_FILENO. +const int kStdOutFileno = 1; +const int kStdErrFileno = 2; +#else +const int kStdOutFileno = STDOUT_FILENO; +const int kStdErrFileno = STDERR_FILENO; +#endif // _MSC_VER + +#if GTEST_OS_MAC + +// Returns the number of threads running in the process, or 0 to indicate that +// we cannot detect it. +size_t GetThreadCount() { + const task_t task = mach_task_self(); + mach_msg_type_number_t thread_count; + thread_act_array_t thread_list; + const kern_return_t status = task_threads(task, &thread_list, &thread_count); + if (status == KERN_SUCCESS) { + // task_threads allocates resources in thread_list and we need to free them + // to avoid leaks. + vm_deallocate(task, + reinterpret_cast(thread_list), + sizeof(thread_t) * thread_count); + return static_cast(thread_count); + } else { + return 0; + } +} + +#elif GTEST_OS_QNX + +// Returns the number of threads running in the process, or 0 to indicate that +// we cannot detect it. +size_t GetThreadCount() { + const int fd = open("/proc/self/as", O_RDONLY); + if (fd < 0) { + return 0; + } + procfs_info process_info; + const int status = + devctl(fd, DCMD_PROC_INFO, &process_info, sizeof(process_info), NULL); + close(fd); + if (status == EOK) { + return static_cast(process_info.num_threads); + } else { + return 0; + } +} + +#else + +size_t GetThreadCount() { + // There's no portable way to detect the number of threads, so we just + // return 0 to indicate that we cannot detect it. + return 0; +} + +#endif // GTEST_OS_MAC + +#if GTEST_USES_POSIX_RE + +// Implements RE. Currently only needed for death tests. + +RE::~RE() { + if (is_valid_) { + // regfree'ing an invalid regex might crash because the content + // of the regex is undefined. Since the regex's are essentially + // the same, one cannot be valid (or invalid) without the other + // being so too. + regfree(&partial_regex_); + regfree(&full_regex_); + } + free(const_cast(pattern_)); +} + +// Returns true iff regular expression re matches the entire str. +bool RE::FullMatch(const char* str, const RE& re) { + if (!re.is_valid_) return false; + + regmatch_t match; + return regexec(&re.full_regex_, str, 1, &match, 0) == 0; +} + +// Returns true iff regular expression re matches a substring of str +// (including str itself). +bool RE::PartialMatch(const char* str, const RE& re) { + if (!re.is_valid_) return false; + + regmatch_t match; + return regexec(&re.partial_regex_, str, 1, &match, 0) == 0; +} + +// Initializes an RE from its string representation. +void RE::Init(const char* regex) { + pattern_ = posix::StrDup(regex); + + // Reserves enough bytes to hold the regular expression used for a + // full match. + const size_t full_regex_len = strlen(regex) + 10; + char* const full_pattern = new char[full_regex_len]; + + snprintf(full_pattern, full_regex_len, "^(%s)$", regex); + is_valid_ = regcomp(&full_regex_, full_pattern, REG_EXTENDED) == 0; + // We want to call regcomp(&partial_regex_, ...) even if the + // previous expression returns false. Otherwise partial_regex_ may + // not be properly initialized can may cause trouble when it's + // freed. + // + // Some implementation of POSIX regex (e.g. on at least some + // versions of Cygwin) doesn't accept the empty string as a valid + // regex. We change it to an equivalent form "()" to be safe. + if (is_valid_) { + const char* const partial_regex = (*regex == '\0') ? "()" : regex; + is_valid_ = regcomp(&partial_regex_, partial_regex, REG_EXTENDED) == 0; + } + EXPECT_TRUE(is_valid_) + << "Regular expression \"" << regex + << "\" is not a valid POSIX Extended regular expression."; + + delete[] full_pattern; +} + +#elif GTEST_USES_SIMPLE_RE + +// Returns true iff ch appears anywhere in str (excluding the +// terminating '\0' character). +bool IsInSet(char ch, const char* str) { + return ch != '\0' && strchr(str, ch) != NULL; +} + +// Returns true iff ch belongs to the given classification. Unlike +// similar functions in , these aren't affected by the +// current locale. +bool IsAsciiDigit(char ch) { return '0' <= ch && ch <= '9'; } +bool IsAsciiPunct(char ch) { + return IsInSet(ch, "^-!\"#$%&'()*+,./:;<=>?@[\\]_`{|}~"); +} +bool IsRepeat(char ch) { return IsInSet(ch, "?*+"); } +bool IsAsciiWhiteSpace(char ch) { return IsInSet(ch, " \f\n\r\t\v"); } +bool IsAsciiWordChar(char ch) { + return ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') || + ('0' <= ch && ch <= '9') || ch == '_'; +} + +// Returns true iff "\\c" is a supported escape sequence. +bool IsValidEscape(char c) { + return (IsAsciiPunct(c) || IsInSet(c, "dDfnrsStvwW")); +} + +// Returns true iff the given atom (specified by escaped and pattern) +// matches ch. The result is undefined if the atom is invalid. +bool AtomMatchesChar(bool escaped, char pattern_char, char ch) { + if (escaped) { // "\\p" where p is pattern_char. + switch (pattern_char) { + case 'd': return IsAsciiDigit(ch); + case 'D': return !IsAsciiDigit(ch); + case 'f': return ch == '\f'; + case 'n': return ch == '\n'; + case 'r': return ch == '\r'; + case 's': return IsAsciiWhiteSpace(ch); + case 'S': return !IsAsciiWhiteSpace(ch); + case 't': return ch == '\t'; + case 'v': return ch == '\v'; + case 'w': return IsAsciiWordChar(ch); + case 'W': return !IsAsciiWordChar(ch); + } + return IsAsciiPunct(pattern_char) && pattern_char == ch; + } + + return (pattern_char == '.' && ch != '\n') || pattern_char == ch; +} + +// Helper function used by ValidateRegex() to format error messages. +std::string FormatRegexSyntaxError(const char* regex, int index) { + return (Message() << "Syntax error at index " << index + << " in simple regular expression \"" << regex << "\": ").GetString(); +} + +// Generates non-fatal failures and returns false if regex is invalid; +// otherwise returns true. +bool ValidateRegex(const char* regex) { + if (regex == NULL) { + // TODO(wan@google.com): fix the source file location in the + // assertion failures to match where the regex is used in user + // code. + ADD_FAILURE() << "NULL is not a valid simple regular expression."; + return false; + } + + bool is_valid = true; + + // True iff ?, *, or + can follow the previous atom. + bool prev_repeatable = false; + for (int i = 0; regex[i]; i++) { + if (regex[i] == '\\') { // An escape sequence + i++; + if (regex[i] == '\0') { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1) + << "'\\' cannot appear at the end."; + return false; + } + + if (!IsValidEscape(regex[i])) { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1) + << "invalid escape sequence \"\\" << regex[i] << "\"."; + is_valid = false; + } + prev_repeatable = true; + } else { // Not an escape sequence. + const char ch = regex[i]; + + if (ch == '^' && i > 0) { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i) + << "'^' can only appear at the beginning."; + is_valid = false; + } else if (ch == '$' && regex[i + 1] != '\0') { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i) + << "'$' can only appear at the end."; + is_valid = false; + } else if (IsInSet(ch, "()[]{}|")) { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i) + << "'" << ch << "' is unsupported."; + is_valid = false; + } else if (IsRepeat(ch) && !prev_repeatable) { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i) + << "'" << ch << "' can only follow a repeatable token."; + is_valid = false; + } + + prev_repeatable = !IsInSet(ch, "^$?*+"); + } + } + + return is_valid; +} + +// Matches a repeated regex atom followed by a valid simple regular +// expression. The regex atom is defined as c if escaped is false, +// or \c otherwise. repeat is the repetition meta character (?, *, +// or +). The behavior is undefined if str contains too many +// characters to be indexable by size_t, in which case the test will +// probably time out anyway. We are fine with this limitation as +// std::string has it too. +bool MatchRepetitionAndRegexAtHead( + bool escaped, char c, char repeat, const char* regex, + const char* str) { + const size_t min_count = (repeat == '+') ? 1 : 0; + const size_t max_count = (repeat == '?') ? 1 : + static_cast(-1) - 1; + // We cannot call numeric_limits::max() as it conflicts with the + // max() macro on Windows. + + for (size_t i = 0; i <= max_count; ++i) { + // We know that the atom matches each of the first i characters in str. + if (i >= min_count && MatchRegexAtHead(regex, str + i)) { + // We have enough matches at the head, and the tail matches too. + // Since we only care about *whether* the pattern matches str + // (as opposed to *how* it matches), there is no need to find a + // greedy match. + return true; + } + if (str[i] == '\0' || !AtomMatchesChar(escaped, c, str[i])) + return false; + } + return false; +} + +// Returns true iff regex matches a prefix of str. regex must be a +// valid simple regular expression and not start with "^", or the +// result is undefined. +bool MatchRegexAtHead(const char* regex, const char* str) { + if (*regex == '\0') // An empty regex matches a prefix of anything. + return true; + + // "$" only matches the end of a string. Note that regex being + // valid guarantees that there's nothing after "$" in it. + if (*regex == '$') + return *str == '\0'; + + // Is the first thing in regex an escape sequence? + const bool escaped = *regex == '\\'; + if (escaped) + ++regex; + if (IsRepeat(regex[1])) { + // MatchRepetitionAndRegexAtHead() calls MatchRegexAtHead(), so + // here's an indirect recursion. It terminates as the regex gets + // shorter in each recursion. + return MatchRepetitionAndRegexAtHead( + escaped, regex[0], regex[1], regex + 2, str); + } else { + // regex isn't empty, isn't "$", and doesn't start with a + // repetition. We match the first atom of regex with the first + // character of str and recurse. + return (*str != '\0') && AtomMatchesChar(escaped, *regex, *str) && + MatchRegexAtHead(regex + 1, str + 1); + } +} + +// Returns true iff regex matches any substring of str. regex must be +// a valid simple regular expression, or the result is undefined. +// +// The algorithm is recursive, but the recursion depth doesn't exceed +// the regex length, so we won't need to worry about running out of +// stack space normally. In rare cases the time complexity can be +// exponential with respect to the regex length + the string length, +// but usually it's must faster (often close to linear). +bool MatchRegexAnywhere(const char* regex, const char* str) { + if (regex == NULL || str == NULL) + return false; + + if (*regex == '^') + return MatchRegexAtHead(regex + 1, str); + + // A successful match can be anywhere in str. + do { + if (MatchRegexAtHead(regex, str)) + return true; + } while (*str++ != '\0'); + return false; +} + +// Implements the RE class. + +RE::~RE() { + free(const_cast(pattern_)); + free(const_cast(full_pattern_)); +} + +// Returns true iff regular expression re matches the entire str. +bool RE::FullMatch(const char* str, const RE& re) { + return re.is_valid_ && MatchRegexAnywhere(re.full_pattern_, str); +} + +// Returns true iff regular expression re matches a substring of str +// (including str itself). +bool RE::PartialMatch(const char* str, const RE& re) { + return re.is_valid_ && MatchRegexAnywhere(re.pattern_, str); +} + +// Initializes an RE from its string representation. +void RE::Init(const char* regex) { + pattern_ = full_pattern_ = NULL; + if (regex != NULL) { + pattern_ = posix::StrDup(regex); + } + + is_valid_ = ValidateRegex(regex); + if (!is_valid_) { + // No need to calculate the full pattern when the regex is invalid. + return; + } + + const size_t len = strlen(regex); + // Reserves enough bytes to hold the regular expression used for a + // full match: we need space to prepend a '^', append a '$', and + // terminate the string with '\0'. + char* buffer = static_cast(malloc(len + 3)); + full_pattern_ = buffer; + + if (*regex != '^') + *buffer++ = '^'; // Makes sure full_pattern_ starts with '^'. + + // We don't use snprintf or strncpy, as they trigger a warning when + // compiled with VC++ 8.0. + memcpy(buffer, regex, len); + buffer += len; + + if (len == 0 || regex[len - 1] != '$') + *buffer++ = '$'; // Makes sure full_pattern_ ends with '$'. + + *buffer = '\0'; +} + +#endif // GTEST_USES_POSIX_RE + +const char kUnknownFile[] = "unknown file"; + +// Formats a source file path and a line number as they would appear +// in an error message from the compiler used to compile this code. +GTEST_API_ ::std::string FormatFileLocation(const char* file, int line) { + const std::string file_name(file == NULL ? kUnknownFile : file); + + if (line < 0) { + return file_name + ":"; + } +#ifdef _MSC_VER + return file_name + "(" + StreamableToString(line) + "):"; +#else + return file_name + ":" + StreamableToString(line) + ":"; +#endif // _MSC_VER +} + +// Formats a file location for compiler-independent XML output. +// Although this function is not platform dependent, we put it next to +// FormatFileLocation in order to contrast the two functions. +// Note that FormatCompilerIndependentFileLocation() does NOT append colon +// to the file location it produces, unlike FormatFileLocation(). +GTEST_API_ ::std::string FormatCompilerIndependentFileLocation( + const char* file, int line) { + const std::string file_name(file == NULL ? kUnknownFile : file); + + if (line < 0) + return file_name; + else + return file_name + ":" + StreamableToString(line); +} + + +GTestLog::GTestLog(GTestLogSeverity severity, const char* file, int line) + : severity_(severity) { + const char* const marker = + severity == GTEST_INFO ? "[ INFO ]" : + severity == GTEST_WARNING ? "[WARNING]" : + severity == GTEST_ERROR ? "[ ERROR ]" : "[ FATAL ]"; + GetStream() << ::std::endl << marker << " " + << FormatFileLocation(file, line).c_str() << ": "; +} + +// Flushes the buffers and, if severity is GTEST_FATAL, aborts the program. +GTestLog::~GTestLog() { + GetStream() << ::std::endl; + if (severity_ == GTEST_FATAL) { + fflush(stderr); + posix::Abort(); + } +} +// Disable Microsoft deprecation warnings for POSIX functions called from +// this class (creat, dup, dup2, and close) +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4996) +#endif // _MSC_VER + +#if GTEST_HAS_STREAM_REDIRECTION + +// Object that captures an output stream (stdout/stderr). +class CapturedStream { + public: + // The ctor redirects the stream to a temporary file. + explicit CapturedStream(int fd) : fd_(fd), uncaptured_fd_(dup(fd)) { +# if GTEST_OS_WINDOWS + char temp_dir_path[MAX_PATH + 1] = { '\0' }; // NOLINT + char temp_file_path[MAX_PATH + 1] = { '\0' }; // NOLINT + + ::GetTempPathA(sizeof(temp_dir_path), temp_dir_path); + const UINT success = ::GetTempFileNameA(temp_dir_path, + "gtest_redir", + 0, // Generate unique file name. + temp_file_path); + GTEST_CHECK_(success != 0) + << "Unable to create a temporary file in " << temp_dir_path; + const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE); + GTEST_CHECK_(captured_fd != -1) << "Unable to open temporary file " + << temp_file_path; + filename_ = temp_file_path; +# else + // There's no guarantee that a test has write access to the current + // directory, so we create the temporary file in the /tmp directory + // instead. We use /tmp on most systems, and /sdcard on Android. + // That's because Android doesn't have /tmp. +# if GTEST_OS_LINUX_ANDROID + // Note: Android applications are expected to call the framework's + // Context.getExternalStorageDirectory() method through JNI to get + // the location of the world-writable SD Card directory. However, + // this requires a Context handle, which cannot be retrieved + // globally from native code. Doing so also precludes running the + // code as part of a regular standalone executable, which doesn't + // run in a Dalvik process (e.g. when running it through 'adb shell'). + // + // The location /sdcard is directly accessible from native code + // and is the only location (unofficially) supported by the Android + // team. It's generally a symlink to the real SD Card mount point + // which can be /mnt/sdcard, /mnt/sdcard0, /system/media/sdcard, or + // other OEM-customized locations. Never rely on these, and always + // use /sdcard. + char name_template[] = "/sdcard/gtest_captured_stream.XXXXXX"; +# else + char name_template[] = "/tmp/captured_stream.XXXXXX"; +# endif // GTEST_OS_LINUX_ANDROID + const int captured_fd = mkstemp(name_template); + filename_ = name_template; +# endif // GTEST_OS_WINDOWS + fflush(NULL); + dup2(captured_fd, fd_); + close(captured_fd); + } + + ~CapturedStream() { + remove(filename_.c_str()); + } + + std::string GetCapturedString() { + if (uncaptured_fd_ != -1) { + // Restores the original stream. + fflush(NULL); + dup2(uncaptured_fd_, fd_); + close(uncaptured_fd_); + uncaptured_fd_ = -1; + } + + FILE* const file = posix::FOpen(filename_.c_str(), "r"); + const std::string content = ReadEntireFile(file); + posix::FClose(file); + return content; + } + + private: + // Reads the entire content of a file as an std::string. + static std::string ReadEntireFile(FILE* file); + + // Returns the size (in bytes) of a file. + static size_t GetFileSize(FILE* file); + + const int fd_; // A stream to capture. + int uncaptured_fd_; + // Name of the temporary file holding the stderr output. + ::std::string filename_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(CapturedStream); +}; + +// Returns the size (in bytes) of a file. +size_t CapturedStream::GetFileSize(FILE* file) { + fseek(file, 0, SEEK_END); + return static_cast(ftell(file)); +} + +// Reads the entire content of a file as a string. +std::string CapturedStream::ReadEntireFile(FILE* file) { + const size_t file_size = GetFileSize(file); + char* const buffer = new char[file_size]; + + size_t bytes_last_read = 0; // # of bytes read in the last fread() + size_t bytes_read = 0; // # of bytes read so far + + fseek(file, 0, SEEK_SET); + + // Keeps reading the file until we cannot read further or the + // pre-determined file size is reached. + do { + bytes_last_read = fread(buffer+bytes_read, 1, file_size-bytes_read, file); + bytes_read += bytes_last_read; + } while (bytes_last_read > 0 && bytes_read < file_size); + + const std::string content(buffer, bytes_read); + delete[] buffer; + + return content; +} + +# ifdef _MSC_VER +# pragma warning(pop) +# endif // _MSC_VER + +static CapturedStream* g_captured_stderr = NULL; +static CapturedStream* g_captured_stdout = NULL; + +// Starts capturing an output stream (stdout/stderr). +void CaptureStream(int fd, const char* stream_name, CapturedStream** stream) { + if (*stream != NULL) { + GTEST_LOG_(FATAL) << "Only one " << stream_name + << " capturer can exist at a time."; + } + *stream = new CapturedStream(fd); +} + +// Stops capturing the output stream and returns the captured string. +std::string GetCapturedStream(CapturedStream** captured_stream) { + const std::string content = (*captured_stream)->GetCapturedString(); + + delete *captured_stream; + *captured_stream = NULL; + + return content; +} + +// Starts capturing stdout. +void CaptureStdout() { + CaptureStream(kStdOutFileno, "stdout", &g_captured_stdout); +} + +// Starts capturing stderr. +void CaptureStderr() { + CaptureStream(kStdErrFileno, "stderr", &g_captured_stderr); +} + +// Stops capturing stdout and returns the captured string. +std::string GetCapturedStdout() { + return GetCapturedStream(&g_captured_stdout); +} + +// Stops capturing stderr and returns the captured string. +std::string GetCapturedStderr() { + return GetCapturedStream(&g_captured_stderr); +} + +#endif // GTEST_HAS_STREAM_REDIRECTION + +#if GTEST_HAS_DEATH_TEST + +// A copy of all command line arguments. Set by InitGoogleTest(). +::std::vector g_argvs; + +static const ::std::vector* g_injected_test_argvs = + NULL; // Owned. + +void SetInjectableArgvs(const ::std::vector* argvs) { + if (g_injected_test_argvs != argvs) + delete g_injected_test_argvs; + g_injected_test_argvs = argvs; +} + +const ::std::vector& GetInjectableArgvs() { + if (g_injected_test_argvs != NULL) { + return *g_injected_test_argvs; + } + return g_argvs; +} +#endif // GTEST_HAS_DEATH_TEST + +#if GTEST_OS_WINDOWS_MOBILE +namespace posix { +void Abort() { + DebugBreak(); + TerminateProcess(GetCurrentProcess(), 1); +} +} // namespace posix +#endif // GTEST_OS_WINDOWS_MOBILE + +// Returns the name of the environment variable corresponding to the +// given flag. For example, FlagToEnvVar("foo") will return +// "GTEST_FOO" in the open-source version. +static std::string FlagToEnvVar(const char* flag) { + const std::string full_flag = + (Message() << GTEST_FLAG_PREFIX_ << flag).GetString(); + + Message env_var; + for (size_t i = 0; i != full_flag.length(); i++) { + env_var << ToUpper(full_flag.c_str()[i]); + } + + return env_var.GetString(); +} + +// Parses 'str' for a 32-bit signed integer. If successful, writes +// the result to *value and returns true; otherwise leaves *value +// unchanged and returns false. +bool ParseInt32(const Message& src_text, const char* str, Int32* value) { + // Parses the environment variable as a decimal integer. + char* end = NULL; + const long long_value = strtol(str, &end, 10); // NOLINT + + // Has strtol() consumed all characters in the string? + if (*end != '\0') { + // No - an invalid character was encountered. + Message msg; + msg << "WARNING: " << src_text + << " is expected to be a 32-bit integer, but actually" + << " has value \"" << str << "\".\n"; + printf("%s", msg.GetString().c_str()); + fflush(stdout); + return false; + } + + // Is the parsed value in the range of an Int32? + const Int32 result = static_cast(long_value); + if (long_value == LONG_MAX || long_value == LONG_MIN || + // The parsed value overflows as a long. (strtol() returns + // LONG_MAX or LONG_MIN when the input overflows.) + result != long_value + // The parsed value overflows as an Int32. + ) { + Message msg; + msg << "WARNING: " << src_text + << " is expected to be a 32-bit integer, but actually" + << " has value " << str << ", which overflows.\n"; + printf("%s", msg.GetString().c_str()); + fflush(stdout); + return false; + } + + *value = result; + return true; +} + +// Reads and returns the Boolean environment variable corresponding to +// the given flag; if it's not set, returns default_value. +// +// The value is considered true iff it's not "0". +bool BoolFromGTestEnv(const char* flag, bool default_value) { + const std::string env_var = FlagToEnvVar(flag); + const char* const string_value = posix::GetEnv(env_var.c_str()); + return string_value == NULL ? + default_value : strcmp(string_value, "0") != 0; +} + +// Reads and returns a 32-bit integer stored in the environment +// variable corresponding to the given flag; if it isn't set or +// doesn't represent a valid 32-bit integer, returns default_value. +Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) { + const std::string env_var = FlagToEnvVar(flag); + const char* const string_value = posix::GetEnv(env_var.c_str()); + if (string_value == NULL) { + // The environment variable is not set. + return default_value; + } + + Int32 result = default_value; + if (!ParseInt32(Message() << "Environment variable " << env_var, + string_value, &result)) { + printf("The default value %s is used.\n", + (Message() << default_value).GetString().c_str()); + fflush(stdout); + return default_value; + } + + return result; +} + +// Reads and returns the string environment variable corresponding to +// the given flag; if it's not set, returns default_value. +const char* StringFromGTestEnv(const char* flag, const char* default_value) { + const std::string env_var = FlagToEnvVar(flag); + const char* const value = posix::GetEnv(env_var.c_str()); + return value == NULL ? default_value : value; +} + +} // namespace internal +} // namespace testing +// Copyright 2007, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) + +// Google Test - The Google C++ Testing Framework +// +// This file implements a universal value printer that can print a +// value of any type T: +// +// void ::testing::internal::UniversalPrinter::Print(value, ostream_ptr); +// +// It uses the << operator when possible, and prints the bytes in the +// object otherwise. A user can override its behavior for a class +// type Foo by defining either operator<<(::std::ostream&, const Foo&) +// or void PrintTo(const Foo&, ::std::ostream*) in the namespace that +// defines Foo. + +#include +#include +#include // NOLINT +#include + +namespace testing { + +namespace { + +using ::std::ostream; + +// Prints a segment of bytes in the given object. +void PrintByteSegmentInObjectTo(const unsigned char* obj_bytes, size_t start, + size_t count, ostream* os) { + char text[5] = ""; + for (size_t i = 0; i != count; i++) { + const size_t j = start + i; + if (i != 0) { + // Organizes the bytes into groups of 2 for easy parsing by + // human. + if ((j % 2) == 0) + *os << ' '; + else + *os << '-'; + } + GTEST_SNPRINTF_(text, sizeof(text), "%02X", obj_bytes[j]); + *os << text; + } +} + +// Prints the bytes in the given value to the given ostream. +void PrintBytesInObjectToImpl(const unsigned char* obj_bytes, size_t count, + ostream* os) { + // Tells the user how big the object is. + *os << count << "-byte object <"; + + const size_t kThreshold = 132; + const size_t kChunkSize = 64; + // If the object size is bigger than kThreshold, we'll have to omit + // some details by printing only the first and the last kChunkSize + // bytes. + // TODO(wan): let the user control the threshold using a flag. + if (count < kThreshold) { + PrintByteSegmentInObjectTo(obj_bytes, 0, count, os); + } else { + PrintByteSegmentInObjectTo(obj_bytes, 0, kChunkSize, os); + *os << " ... "; + // Rounds up to 2-byte boundary. + const size_t resume_pos = (count - kChunkSize + 1)/2*2; + PrintByteSegmentInObjectTo(obj_bytes, resume_pos, count - resume_pos, os); + } + *os << ">"; +} + +} // namespace + +namespace internal2 { + +// Delegates to PrintBytesInObjectToImpl() to print the bytes in the +// given object. The delegation simplifies the implementation, which +// uses the << operator and thus is easier done outside of the +// ::testing::internal namespace, which contains a << operator that +// sometimes conflicts with the one in STL. +void PrintBytesInObjectTo(const unsigned char* obj_bytes, size_t count, + ostream* os) { + PrintBytesInObjectToImpl(obj_bytes, count, os); +} + +} // namespace internal2 + +namespace internal { + +// Depending on the value of a char (or wchar_t), we print it in one +// of three formats: +// - as is if it's a printable ASCII (e.g. 'a', '2', ' '), +// - as a hexidecimal escape sequence (e.g. '\x7F'), or +// - as a special escape sequence (e.g. '\r', '\n'). +enum CharFormat { + kAsIs, + kHexEscape, + kSpecialEscape +}; + +// Returns true if c is a printable ASCII character. We test the +// value of c directly instead of calling isprint(), which is buggy on +// Windows Mobile. +inline bool IsPrintableAscii(wchar_t c) { + return 0x20 <= c && c <= 0x7E; +} + +// Prints a wide or narrow char c as a character literal without the +// quotes, escaping it when necessary; returns how c was formatted. +// The template argument UnsignedChar is the unsigned version of Char, +// which is the type of c. +template +static CharFormat PrintAsCharLiteralTo(Char c, ostream* os) { + switch (static_cast(c)) { + case L'\0': + *os << "\\0"; + break; + case L'\'': + *os << "\\'"; + break; + case L'\\': + *os << "\\\\"; + break; + case L'\a': + *os << "\\a"; + break; + case L'\b': + *os << "\\b"; + break; + case L'\f': + *os << "\\f"; + break; + case L'\n': + *os << "\\n"; + break; + case L'\r': + *os << "\\r"; + break; + case L'\t': + *os << "\\t"; + break; + case L'\v': + *os << "\\v"; + break; + default: + if (IsPrintableAscii(c)) { + *os << static_cast(c); + return kAsIs; + } else { + *os << "\\x" + String::FormatHexInt(static_cast(c)); + return kHexEscape; + } + } + return kSpecialEscape; +} + +// Prints a wchar_t c as if it's part of a string literal, escaping it when +// necessary; returns how c was formatted. +static CharFormat PrintAsStringLiteralTo(wchar_t c, ostream* os) { + switch (c) { + case L'\'': + *os << "'"; + return kAsIs; + case L'"': + *os << "\\\""; + return kSpecialEscape; + default: + return PrintAsCharLiteralTo(c, os); + } +} + +// Prints a char c as if it's part of a string literal, escaping it when +// necessary; returns how c was formatted. +static CharFormat PrintAsStringLiteralTo(char c, ostream* os) { + return PrintAsStringLiteralTo( + static_cast(static_cast(c)), os); +} + +// Prints a wide or narrow character c and its code. '\0' is printed +// as "'\\0'", other unprintable characters are also properly escaped +// using the standard C++ escape sequence. The template argument +// UnsignedChar is the unsigned version of Char, which is the type of c. +template +void PrintCharAndCodeTo(Char c, ostream* os) { + // First, print c as a literal in the most readable form we can find. + *os << ((sizeof(c) > 1) ? "L'" : "'"); + const CharFormat format = PrintAsCharLiteralTo(c, os); + *os << "'"; + + // To aid user debugging, we also print c's code in decimal, unless + // it's 0 (in which case c was printed as '\\0', making the code + // obvious). + if (c == 0) + return; + *os << " (" << static_cast(c); + + // For more convenience, we print c's code again in hexidecimal, + // unless c was already printed in the form '\x##' or the code is in + // [1, 9]. + if (format == kHexEscape || (1 <= c && c <= 9)) { + // Do nothing. + } else { + *os << ", 0x" << String::FormatHexInt(static_cast(c)); + } + *os << ")"; +} + +void PrintTo(unsigned char c, ::std::ostream* os) { + PrintCharAndCodeTo(c, os); +} +void PrintTo(signed char c, ::std::ostream* os) { + PrintCharAndCodeTo(c, os); +} + +// Prints a wchar_t as a symbol if it is printable or as its internal +// code otherwise and also as its code. L'\0' is printed as "L'\\0'". +void PrintTo(wchar_t wc, ostream* os) { + PrintCharAndCodeTo(wc, os); +} + +// Prints the given array of characters to the ostream. CharType must be either +// char or wchar_t. +// The array starts at begin, the length is len, it may include '\0' characters +// and may not be NUL-terminated. +template +static void PrintCharsAsStringTo( + const CharType* begin, size_t len, ostream* os) { + const char* const kQuoteBegin = sizeof(CharType) == 1 ? "\"" : "L\""; + *os << kQuoteBegin; + bool is_previous_hex = false; + for (size_t index = 0; index < len; ++index) { + const CharType cur = begin[index]; + if (is_previous_hex && IsXDigit(cur)) { + // Previous character is of '\x..' form and this character can be + // interpreted as another hexadecimal digit in its number. Break string to + // disambiguate. + *os << "\" " << kQuoteBegin; + } + is_previous_hex = PrintAsStringLiteralTo(cur, os) == kHexEscape; + } + *os << "\""; +} + +// Prints a (const) char/wchar_t array of 'len' elements, starting at address +// 'begin'. CharType must be either char or wchar_t. +template +static void UniversalPrintCharArray( + const CharType* begin, size_t len, ostream* os) { + // The code + // const char kFoo[] = "foo"; + // generates an array of 4, not 3, elements, with the last one being '\0'. + // + // Therefore when printing a char array, we don't print the last element if + // it's '\0', such that the output matches the string literal as it's + // written in the source code. + if (len > 0 && begin[len - 1] == '\0') { + PrintCharsAsStringTo(begin, len - 1, os); + return; + } + + // If, however, the last element in the array is not '\0', e.g. + // const char kFoo[] = { 'f', 'o', 'o' }; + // we must print the entire array. We also print a message to indicate + // that the array is not NUL-terminated. + PrintCharsAsStringTo(begin, len, os); + *os << " (no terminating NUL)"; +} + +// Prints a (const) char array of 'len' elements, starting at address 'begin'. +void UniversalPrintArray(const char* begin, size_t len, ostream* os) { + UniversalPrintCharArray(begin, len, os); +} + +// Prints a (const) wchar_t array of 'len' elements, starting at address +// 'begin'. +void UniversalPrintArray(const wchar_t* begin, size_t len, ostream* os) { + UniversalPrintCharArray(begin, len, os); +} + +// Prints the given C string to the ostream. +void PrintTo(const char* s, ostream* os) { + if (s == NULL) { + *os << "NULL"; + } else { + *os << ImplicitCast_(s) << " pointing to "; + PrintCharsAsStringTo(s, strlen(s), os); + } +} + +// MSVC compiler can be configured to define whar_t as a typedef +// of unsigned short. Defining an overload for const wchar_t* in that case +// would cause pointers to unsigned shorts be printed as wide strings, +// possibly accessing more memory than intended and causing invalid +// memory accesses. MSVC defines _NATIVE_WCHAR_T_DEFINED symbol when +// wchar_t is implemented as a native type. +#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) +// Prints the given wide C string to the ostream. +void PrintTo(const wchar_t* s, ostream* os) { + if (s == NULL) { + *os << "NULL"; + } else { + *os << ImplicitCast_(s) << " pointing to "; + PrintCharsAsStringTo(s, wcslen(s), os); + } +} +#endif // wchar_t is native + +// Prints a ::string object. +#if GTEST_HAS_GLOBAL_STRING +void PrintStringTo(const ::string& s, ostream* os) { + PrintCharsAsStringTo(s.data(), s.size(), os); +} +#endif // GTEST_HAS_GLOBAL_STRING + +void PrintStringTo(const ::std::string& s, ostream* os) { + PrintCharsAsStringTo(s.data(), s.size(), os); +} + +// Prints a ::wstring object. +#if GTEST_HAS_GLOBAL_WSTRING +void PrintWideStringTo(const ::wstring& s, ostream* os) { + PrintCharsAsStringTo(s.data(), s.size(), os); +} +#endif // GTEST_HAS_GLOBAL_WSTRING + +#if GTEST_HAS_STD_WSTRING +void PrintWideStringTo(const ::std::wstring& s, ostream* os) { + PrintCharsAsStringTo(s.data(), s.size(), os); +} +#endif // GTEST_HAS_STD_WSTRING + +} // namespace internal + +} // namespace testing +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: mheule@google.com (Markus Heule) +// +// The Google C++ Testing Framework (Google Test) + + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION_ 1 +#undef GTEST_IMPLEMENTATION_ + +namespace testing { + +using internal::GetUnitTestImpl; + +// Gets the summary of the failure message by omitting the stack trace +// in it. +std::string TestPartResult::ExtractSummary(const char* message) { + const char* const stack_trace = strstr(message, internal::kStackTraceMarker); + return stack_trace == NULL ? message : + std::string(message, stack_trace); +} + +// Prints a TestPartResult object. +std::ostream& operator<<(std::ostream& os, const TestPartResult& result) { + return os + << result.file_name() << ":" << result.line_number() << ": " + << (result.type() == TestPartResult::kSuccess ? "Success" : + result.type() == TestPartResult::kFatalFailure ? "Fatal failure" : + "Non-fatal failure") << ":\n" + << result.message() << std::endl; +} + +// Appends a TestPartResult to the array. +void TestPartResultArray::Append(const TestPartResult& result) { + array_.push_back(result); +} + +// Returns the TestPartResult at the given index (0-based). +const TestPartResult& TestPartResultArray::GetTestPartResult(int index) const { + if (index < 0 || index >= size()) { + printf("\nInvalid index (%d) into TestPartResultArray.\n", index); + internal::posix::Abort(); + } + + return array_[index]; +} + +// Returns the number of TestPartResult objects in the array. +int TestPartResultArray::size() const { + return static_cast(array_.size()); +} + +namespace internal { + +HasNewFatalFailureHelper::HasNewFatalFailureHelper() + : has_new_fatal_failure_(false), + original_reporter_(GetUnitTestImpl()-> + GetTestPartResultReporterForCurrentThread()) { + GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(this); +} + +HasNewFatalFailureHelper::~HasNewFatalFailureHelper() { + GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread( + original_reporter_); +} + +void HasNewFatalFailureHelper::ReportTestPartResult( + const TestPartResult& result) { + if (result.fatally_failed()) + has_new_fatal_failure_ = true; + original_reporter_->ReportTestPartResult(result); +} + +} // namespace internal + +} // namespace testing +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) + + +namespace testing { +namespace internal { + +#if GTEST_HAS_TYPED_TEST_P + +// Skips to the first non-space char in str. Returns an empty string if str +// contains only whitespace characters. +static const char* SkipSpaces(const char* str) { + while (IsSpace(*str)) + str++; + return str; +} + +// Verifies that registered_tests match the test names in +// defined_test_names_; returns registered_tests if successful, or +// aborts the program otherwise. +const char* TypedTestCasePState::VerifyRegisteredTestNames( + const char* file, int line, const char* registered_tests) { + typedef ::std::set::const_iterator DefinedTestIter; + registered_ = true; + + // Skip initial whitespace in registered_tests since some + // preprocessors prefix stringizied literals with whitespace. + registered_tests = SkipSpaces(registered_tests); + + Message errors; + ::std::set tests; + for (const char* names = registered_tests; names != NULL; + names = SkipComma(names)) { + const std::string name = GetPrefixUntilComma(names); + if (tests.count(name) != 0) { + errors << "Test " << name << " is listed more than once.\n"; + continue; + } + + bool found = false; + for (DefinedTestIter it = defined_test_names_.begin(); + it != defined_test_names_.end(); + ++it) { + if (name == *it) { + found = true; + break; + } + } + + if (found) { + tests.insert(name); + } else { + errors << "No test named " << name + << " can be found in this test case.\n"; + } + } + + for (DefinedTestIter it = defined_test_names_.begin(); + it != defined_test_names_.end(); + ++it) { + if (tests.count(*it) == 0) { + errors << "You forgot to list test " << *it << ".\n"; + } + } + + const std::string& errors_str = errors.GetString(); + if (errors_str != "") { + fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(), + errors_str.c_str()); + fflush(stderr); + posix::Abort(); + } + + return registered_tests; +} + +#endif // GTEST_HAS_TYPED_TEST_P + +} // namespace internal +} // namespace testing diff --git a/lib/kokkos/tpls/gtest/gtest/gtest-test-part.h b/lib/kokkos/tpls/gtest/gtest/gtest-test-part.h new file mode 120000 index 0000000000..48d39090f1 --- /dev/null +++ b/lib/kokkos/tpls/gtest/gtest/gtest-test-part.h @@ -0,0 +1 @@ +gtest.h \ No newline at end of file diff --git a/lib/kokkos/tpls/gtest/gtest/gtest.h b/lib/kokkos/tpls/gtest/gtest/gtest.h new file mode 100644 index 0000000000..c74d098fa9 --- /dev/null +++ b/lib/kokkos/tpls/gtest/gtest/gtest.h @@ -0,0 +1,20065 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) +// +// The Google C++ Testing Framework (Google Test) +// +// This header file defines the public API for Google Test. It should be +// included by any test program that uses Google Test. +// +// IMPORTANT NOTE: Due to limitation of the C++ language, we have to +// leave some internal implementation details in this header file. +// They are clearly marked by comments like this: +// +// // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +// +// Such code is NOT meant to be used by a user directly, and is subject +// to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user +// program! +// +// Acknowledgment: Google Test borrowed the idea of automatic test +// registration from Barthelemy Dagenais' (barthelemy@prologique.com) +// easyUnit framework. + +#ifdef __GNUC__ +#pragma GCC system_header +#endif + +#ifndef GTEST_INCLUDE_GTEST_GTEST_H_ +#define GTEST_INCLUDE_GTEST_GTEST_H_ + +#include +#include +#include + +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee) +// +// The Google C++ Testing Framework (Google Test) +// +// This header file declares functions and macros used internally by +// Google Test. They are subject to change without notice. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ + +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: wan@google.com (Zhanyong Wan) +// +// Low-level types and utilities for porting Google Test to various +// platforms. They are subject to change without notice. DO NOT USE +// THEM IN USER CODE. +// +// This file is fundamental to Google Test. All other Google Test source +// files are expected to #include this. Therefore, it cannot #include +// any other Google Test header. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ + +// The user can define the following macros in the build script to +// control Google Test's behavior. If the user doesn't define a macro +// in this list, Google Test will define it. +// +// GTEST_HAS_CLONE - Define it to 1/0 to indicate that clone(2) +// is/isn't available. +// GTEST_HAS_EXCEPTIONS - Define it to 1/0 to indicate that exceptions +// are enabled. +// GTEST_HAS_GLOBAL_STRING - Define it to 1/0 to indicate that ::string +// is/isn't available (some systems define +// ::string, which is different to std::string). +// GTEST_HAS_GLOBAL_WSTRING - Define it to 1/0 to indicate that ::string +// is/isn't available (some systems define +// ::wstring, which is different to std::wstring). +// GTEST_HAS_POSIX_RE - Define it to 1/0 to indicate that POSIX regular +// expressions are/aren't available. +// GTEST_HAS_PTHREAD - Define it to 1/0 to indicate that +// is/isn't available. +// GTEST_HAS_RTTI - Define it to 1/0 to indicate that RTTI is/isn't +// enabled. +// GTEST_HAS_STD_WSTRING - Define it to 1/0 to indicate that +// std::wstring does/doesn't work (Google Test can +// be used where std::wstring is unavailable). +// GTEST_HAS_TR1_TUPLE - Define it to 1/0 to indicate tr1::tuple +// is/isn't available. +// GTEST_HAS_SEH - Define it to 1/0 to indicate whether the +// compiler supports Microsoft's "Structured +// Exception Handling". +// GTEST_HAS_STREAM_REDIRECTION +// - Define it to 1/0 to indicate whether the +// platform supports I/O stream redirection using +// dup() and dup2(). +// GTEST_USE_OWN_TR1_TUPLE - Define it to 1/0 to indicate whether Google +// Test's own tr1 tuple implementation should be +// used. Unused when the user sets +// GTEST_HAS_TR1_TUPLE to 0. +// GTEST_LANG_CXX11 - Define it to 1/0 to indicate that Google Test +// is building in C++11/C++98 mode. +// GTEST_LINKED_AS_SHARED_LIBRARY +// - Define to 1 when compiling tests that use +// Google Test as a shared library (known as +// DLL on Windows). +// GTEST_CREATE_SHARED_LIBRARY +// - Define to 1 when compiling Google Test itself +// as a shared library. + +// This header defines the following utilities: +// +// Macros indicating the current platform (defined to 1 if compiled on +// the given platform; otherwise undefined): +// GTEST_OS_AIX - IBM AIX +// GTEST_OS_CYGWIN - Cygwin +// GTEST_OS_HPUX - HP-UX +// GTEST_OS_LINUX - Linux +// GTEST_OS_LINUX_ANDROID - Google Android +// GTEST_OS_MAC - Mac OS X +// GTEST_OS_IOS - iOS +// GTEST_OS_IOS_SIMULATOR - iOS simulator +// GTEST_OS_NACL - Google Native Client (NaCl) +// GTEST_OS_OPENBSD - OpenBSD +// GTEST_OS_QNX - QNX +// GTEST_OS_SOLARIS - Sun Solaris +// GTEST_OS_SYMBIAN - Symbian +// GTEST_OS_WINDOWS - Windows (Desktop, MinGW, or Mobile) +// GTEST_OS_WINDOWS_DESKTOP - Windows Desktop +// GTEST_OS_WINDOWS_MINGW - MinGW +// GTEST_OS_WINDOWS_MOBILE - Windows Mobile +// GTEST_OS_ZOS - z/OS +// +// Among the platforms, Cygwin, Linux, Max OS X, and Windows have the +// most stable support. Since core members of the Google Test project +// don't have access to other platforms, support for them may be less +// stable. If you notice any problems on your platform, please notify +// googletestframework@googlegroups.com (patches for fixing them are +// even more welcome!). +// +// Note that it is possible that none of the GTEST_OS_* macros are defined. +// +// Macros indicating available Google Test features (defined to 1 if +// the corresponding feature is supported; otherwise undefined): +// GTEST_HAS_COMBINE - the Combine() function (for value-parameterized +// tests) +// GTEST_HAS_DEATH_TEST - death tests +// GTEST_HAS_PARAM_TEST - value-parameterized tests +// GTEST_HAS_TYPED_TEST - typed tests +// GTEST_HAS_TYPED_TEST_P - type-parameterized tests +// GTEST_USES_POSIX_RE - enhanced POSIX regex is used. Do not confuse with +// GTEST_HAS_POSIX_RE (see above) which users can +// define themselves. +// GTEST_USES_SIMPLE_RE - our own simple regex is used; +// the above two are mutually exclusive. +// GTEST_CAN_COMPARE_NULL - accepts untyped NULL in EXPECT_EQ(). +// +// Macros for basic C++ coding: +// GTEST_AMBIGUOUS_ELSE_BLOCKER_ - for disabling a gcc warning. +// GTEST_ATTRIBUTE_UNUSED_ - declares that a class' instances or a +// variable don't have to be used. +// GTEST_DISALLOW_ASSIGN_ - disables operator=. +// GTEST_DISALLOW_COPY_AND_ASSIGN_ - disables copy ctor and operator=. +// GTEST_MUST_USE_RESULT_ - declares that a function's result must be used. +// +// Synchronization: +// Mutex, MutexLock, ThreadLocal, GetThreadCount() +// - synchronization primitives. +// GTEST_IS_THREADSAFE - defined to 1 to indicate that the above +// synchronization primitives have real implementations +// and Google Test is thread-safe; or 0 otherwise. +// +// Template meta programming: +// is_pointer - as in TR1; needed on Symbian and IBM XL C/C++ only. +// IteratorTraits - partial implementation of std::iterator_traits, which +// is not available in libCstd when compiled with Sun C++. +// +// Smart pointers: +// scoped_ptr - as in TR2. +// +// Regular expressions: +// RE - a simple regular expression class using the POSIX +// Extended Regular Expression syntax on UNIX-like +// platforms, or a reduced regular exception syntax on +// other platforms, including Windows. +// +// Logging: +// GTEST_LOG_() - logs messages at the specified severity level. +// LogToStderr() - directs all log messages to stderr. +// FlushInfoLog() - flushes informational log messages. +// +// Stdout and stderr capturing: +// CaptureStdout() - starts capturing stdout. +// GetCapturedStdout() - stops capturing stdout and returns the captured +// string. +// CaptureStderr() - starts capturing stderr. +// GetCapturedStderr() - stops capturing stderr and returns the captured +// string. +// +// Integer types: +// TypeWithSize - maps an integer to a int type. +// Int32, UInt32, Int64, UInt64, TimeInMillis +// - integers of known sizes. +// BiggestInt - the biggest signed integer type. +// +// Command-line utilities: +// GTEST_FLAG() - references a flag. +// GTEST_DECLARE_*() - declares a flag. +// GTEST_DEFINE_*() - defines a flag. +// GetInjectableArgvs() - returns the command line as a vector of strings. +// +// Environment variable utilities: +// GetEnv() - gets the value of an environment variable. +// BoolFromGTestEnv() - parses a bool environment variable. +// Int32FromGTestEnv() - parses an Int32 environment variable. +// StringFromGTestEnv() - parses a string environment variable. + +#include // for isspace, etc +#include // for ptrdiff_t +#include +#include +#include +#ifndef _WIN32_WCE +# include +# include +#endif // !_WIN32_WCE + +#if defined __APPLE__ +# include +# include +#endif + +#include // NOLINT +#include // NOLINT +#include // NOLINT + +#define GTEST_DEV_EMAIL_ "googletestframework@@googlegroups.com" +#define GTEST_FLAG_PREFIX_ "gtest_" +#define GTEST_FLAG_PREFIX_DASH_ "gtest-" +#define GTEST_FLAG_PREFIX_UPPER_ "GTEST_" +#define GTEST_NAME_ "Google Test" +#define GTEST_PROJECT_URL_ "http://code.google.com/p/googletest/" + +// Determines the version of gcc that is used to compile this. +#ifdef __GNUC__ +// 40302 means version 4.3.2. +# define GTEST_GCC_VER_ \ + (__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__) +#endif // __GNUC__ + +// Determines the platform on which Google Test is compiled. +#ifdef __CYGWIN__ +# define GTEST_OS_CYGWIN 1 +#elif defined __SYMBIAN32__ +# define GTEST_OS_SYMBIAN 1 +#elif defined _WIN32 +# define GTEST_OS_WINDOWS 1 +# ifdef _WIN32_WCE +# define GTEST_OS_WINDOWS_MOBILE 1 +# elif defined(__MINGW__) || defined(__MINGW32__) +# define GTEST_OS_WINDOWS_MINGW 1 +# else +# define GTEST_OS_WINDOWS_DESKTOP 1 +# endif // _WIN32_WCE +#elif defined __APPLE__ +# define GTEST_OS_MAC 1 +# if TARGET_OS_IPHONE +# define GTEST_OS_IOS 1 +# if TARGET_IPHONE_SIMULATOR +# define GTEST_OS_IOS_SIMULATOR 1 +# endif +# endif +#elif defined __linux__ +# define GTEST_OS_LINUX 1 +# if defined __ANDROID__ +# define GTEST_OS_LINUX_ANDROID 1 +# endif +#elif defined __MVS__ +# define GTEST_OS_ZOS 1 +#elif defined(__sun) && defined(__SVR4) +# define GTEST_OS_SOLARIS 1 +#elif defined(_AIX) +# define GTEST_OS_AIX 1 +#elif defined(__hpux) +# define GTEST_OS_HPUX 1 +#elif defined __native_client__ +# define GTEST_OS_NACL 1 +#elif defined __OpenBSD__ +# define GTEST_OS_OPENBSD 1 +#elif defined __QNX__ +# define GTEST_OS_QNX 1 +#endif // __CYGWIN__ + +#ifndef GTEST_LANG_CXX11 +// gcc and clang define __GXX_EXPERIMENTAL_CXX0X__ when +// -std={c,gnu}++{0x,11} is passed. The C++11 standard specifies a +// value for __cplusplus, and recent versions of clang, gcc, and +// probably other compilers set that too in C++11 mode. +# if __GXX_EXPERIMENTAL_CXX0X__ || __cplusplus >= 201103L +// Compiling in at least C++11 mode. +# define GTEST_LANG_CXX11 1 +# else +# define GTEST_LANG_CXX11 0 +# endif +#endif + +// Brings in definitions for functions used in the testing::internal::posix +// namespace (read, write, close, chdir, isatty, stat). We do not currently +// use them on Windows Mobile. +#if !GTEST_OS_WINDOWS +// This assumes that non-Windows OSes provide unistd.h. For OSes where this +// is not the case, we need to include headers that provide the functions +// mentioned above. +# include +# include +#elif !GTEST_OS_WINDOWS_MOBILE +# include +# include +#endif + +#if GTEST_OS_LINUX_ANDROID +// Used to define __ANDROID_API__ matching the target NDK API level. +# include // NOLINT +#endif + +// Defines this to true iff Google Test can use POSIX regular expressions. +#ifndef GTEST_HAS_POSIX_RE +# if GTEST_OS_LINUX_ANDROID +// On Android, is only available starting with Gingerbread. +# define GTEST_HAS_POSIX_RE (__ANDROID_API__ >= 9) +# else +# define GTEST_HAS_POSIX_RE (!GTEST_OS_WINDOWS) +# endif +#endif + +#if GTEST_HAS_POSIX_RE + +// On some platforms, needs someone to define size_t, and +// won't compile otherwise. We can #include it here as we already +// included , which is guaranteed to define size_t through +// . +# include // NOLINT + +# define GTEST_USES_POSIX_RE 1 + +#elif GTEST_OS_WINDOWS + +// is not available on Windows. Use our own simple regex +// implementation instead. +# define GTEST_USES_SIMPLE_RE 1 + +#else + +// may not be available on this platform. Use our own +// simple regex implementation instead. +# define GTEST_USES_SIMPLE_RE 1 + +#endif // GTEST_HAS_POSIX_RE + +#ifndef GTEST_HAS_EXCEPTIONS +// The user didn't tell us whether exceptions are enabled, so we need +// to figure it out. +# if defined(_MSC_VER) || defined(__BORLANDC__) +// MSVC's and C++Builder's implementations of the STL use the _HAS_EXCEPTIONS +// macro to enable exceptions, so we'll do the same. +// Assumes that exceptions are enabled by default. +# ifndef _HAS_EXCEPTIONS +# define _HAS_EXCEPTIONS 1 +# endif // _HAS_EXCEPTIONS +# define GTEST_HAS_EXCEPTIONS _HAS_EXCEPTIONS +# elif defined(__GNUC__) && __EXCEPTIONS +// gcc defines __EXCEPTIONS to 1 iff exceptions are enabled. +# define GTEST_HAS_EXCEPTIONS 1 +# elif defined(__SUNPRO_CC) +// Sun Pro CC supports exceptions. However, there is no compile-time way of +// detecting whether they are enabled or not. Therefore, we assume that +// they are enabled unless the user tells us otherwise. +# define GTEST_HAS_EXCEPTIONS 1 +# elif defined(__IBMCPP__) && __EXCEPTIONS +// xlC defines __EXCEPTIONS to 1 iff exceptions are enabled. +# define GTEST_HAS_EXCEPTIONS 1 +# elif defined(__HP_aCC) +// Exception handling is in effect by default in HP aCC compiler. It has to +// be turned of by +noeh compiler option if desired. +# define GTEST_HAS_EXCEPTIONS 1 +# else +// For other compilers, we assume exceptions are disabled to be +// conservative. +# define GTEST_HAS_EXCEPTIONS 0 +# endif // defined(_MSC_VER) || defined(__BORLANDC__) +#endif // GTEST_HAS_EXCEPTIONS + +#if !defined(GTEST_HAS_STD_STRING) +// Even though we don't use this macro any longer, we keep it in case +// some clients still depend on it. +# define GTEST_HAS_STD_STRING 1 +#elif !GTEST_HAS_STD_STRING +// The user told us that ::std::string isn't available. +# error "Google Test cannot be used where ::std::string isn't available." +#endif // !defined(GTEST_HAS_STD_STRING) + +#ifndef GTEST_HAS_GLOBAL_STRING +// The user didn't tell us whether ::string is available, so we need +// to figure it out. + +# define GTEST_HAS_GLOBAL_STRING 0 + +#endif // GTEST_HAS_GLOBAL_STRING + +#ifndef GTEST_HAS_STD_WSTRING +// The user didn't tell us whether ::std::wstring is available, so we need +// to figure it out. +// TODO(wan@google.com): uses autoconf to detect whether ::std::wstring +// is available. + +// Cygwin 1.7 and below doesn't support ::std::wstring. +// Solaris' libc++ doesn't support it either. Android has +// no support for it at least as recent as Froyo (2.2). +# define GTEST_HAS_STD_WSTRING \ + (!(GTEST_OS_LINUX_ANDROID || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS)) + +#endif // GTEST_HAS_STD_WSTRING + +#ifndef GTEST_HAS_GLOBAL_WSTRING +// The user didn't tell us whether ::wstring is available, so we need +// to figure it out. +# define GTEST_HAS_GLOBAL_WSTRING \ + (GTEST_HAS_STD_WSTRING && GTEST_HAS_GLOBAL_STRING) +#endif // GTEST_HAS_GLOBAL_WSTRING + +// Determines whether RTTI is available. +#ifndef GTEST_HAS_RTTI +// The user didn't tell us whether RTTI is enabled, so we need to +// figure it out. + +# ifdef _MSC_VER + +# ifdef _CPPRTTI // MSVC defines this macro iff RTTI is enabled. +# define GTEST_HAS_RTTI 1 +# else +# define GTEST_HAS_RTTI 0 +# endif + +// Starting with version 4.3.2, gcc defines __GXX_RTTI iff RTTI is enabled. +# elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40302) + +# ifdef __GXX_RTTI +// When building against STLport with the Android NDK and with +// -frtti -fno-exceptions, the build fails at link time with undefined +// references to __cxa_bad_typeid. Note sure if STL or toolchain bug, +// so disable RTTI when detected. +# if GTEST_OS_LINUX_ANDROID && defined(_STLPORT_MAJOR) && \ + !defined(__EXCEPTIONS) +# define GTEST_HAS_RTTI 0 +# else +# define GTEST_HAS_RTTI 1 +# endif // GTEST_OS_LINUX_ANDROID && __STLPORT_MAJOR && !__EXCEPTIONS +# else +# define GTEST_HAS_RTTI 0 +# endif // __GXX_RTTI + +// Clang defines __GXX_RTTI starting with version 3.0, but its manual recommends +// using has_feature instead. has_feature(cxx_rtti) is supported since 2.7, the +// first version with C++ support. +# elif defined(__clang__) + +# define GTEST_HAS_RTTI __has_feature(cxx_rtti) + +// Starting with version 9.0 IBM Visual Age defines __RTTI_ALL__ to 1 if +// both the typeid and dynamic_cast features are present. +# elif defined(__IBMCPP__) && (__IBMCPP__ >= 900) + +# ifdef __RTTI_ALL__ +# define GTEST_HAS_RTTI 1 +# else +# define GTEST_HAS_RTTI 0 +# endif + +# else + +// For all other compilers, we assume RTTI is enabled. +# define GTEST_HAS_RTTI 1 + +# endif // _MSC_VER + +#endif // GTEST_HAS_RTTI + +// It's this header's responsibility to #include when RTTI +// is enabled. +#if GTEST_HAS_RTTI +# include +#endif + +// Determines whether Google Test can use the pthreads library. +#ifndef GTEST_HAS_PTHREAD +// The user didn't tell us explicitly, so we assume pthreads support is +// available on Linux and Mac. +// +// To disable threading support in Google Test, add -DGTEST_HAS_PTHREAD=0 +// to your compiler flags. +# define GTEST_HAS_PTHREAD (GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_HPUX \ + || GTEST_OS_QNX) +#endif // GTEST_HAS_PTHREAD + +#if GTEST_HAS_PTHREAD +// gtest-port.h guarantees to #include when GTEST_HAS_PTHREAD is +// true. +# include // NOLINT + +// For timespec and nanosleep, used below. +# include // NOLINT +#endif + +// Determines whether Google Test can use tr1/tuple. You can define +// this macro to 0 to prevent Google Test from using tuple (any +// feature depending on tuple with be disabled in this mode). +#ifndef GTEST_HAS_TR1_TUPLE +# if GTEST_OS_LINUX_ANDROID && defined(_STLPORT_MAJOR) +// STLport, provided with the Android NDK, has neither or . +# define GTEST_HAS_TR1_TUPLE 0 +# else +// The user didn't tell us not to do it, so we assume it's OK. +# define GTEST_HAS_TR1_TUPLE 1 +# endif +#endif // GTEST_HAS_TR1_TUPLE + +// Determines whether Google Test's own tr1 tuple implementation +// should be used. +#ifndef GTEST_USE_OWN_TR1_TUPLE +// The user didn't tell us, so we need to figure it out. + +// We use our own TR1 tuple if we aren't sure the user has an +// implementation of it already. At this time, libstdc++ 4.0.0+ and +// MSVC 2010 are the only mainstream standard libraries that come +// with a TR1 tuple implementation. NVIDIA's CUDA NVCC compiler +// pretends to be GCC by defining __GNUC__ and friends, but cannot +// compile GCC's tuple implementation. MSVC 2008 (9.0) provides TR1 +// tuple in a 323 MB Feature Pack download, which we cannot assume the +// user has. QNX's QCC compiler is a modified GCC but it doesn't +// support TR1 tuple. libc++ only provides std::tuple, in C++11 mode, +// and it can be used with some compilers that define __GNUC__. +# if (defined(__GNUC__) && !defined(__CUDACC__) && (GTEST_GCC_VER_ >= 40000) \ + && !GTEST_OS_QNX && !defined(_LIBCPP_VERSION)) || _MSC_VER >= 1600 +# define GTEST_ENV_HAS_TR1_TUPLE_ 1 +# endif + +// C++11 specifies that provides std::tuple. Use that if gtest is used +// in C++11 mode and libstdc++ isn't very old (binaries targeting OS X 10.6 +// can build with clang but need to use gcc4.2's libstdc++). +# if GTEST_LANG_CXX11 && (!defined(__GLIBCXX__) || __GLIBCXX__ > 20110325) +# define GTEST_ENV_HAS_STD_TUPLE_ 1 +# endif + +# if GTEST_ENV_HAS_TR1_TUPLE_ || GTEST_ENV_HAS_STD_TUPLE_ +# define GTEST_USE_OWN_TR1_TUPLE 0 +# else +# define GTEST_USE_OWN_TR1_TUPLE 1 +# endif + +#endif // GTEST_USE_OWN_TR1_TUPLE + +// To avoid conditional compilation everywhere, we make it +// gtest-port.h's responsibility to #include the header implementing +// tr1/tuple. +#if GTEST_HAS_TR1_TUPLE + +# if GTEST_USE_OWN_TR1_TUPLE +// This file was GENERATED by command: +// pump.py gtest-tuple.h.pump +// DO NOT EDIT BY HAND!!! + +// Copyright 2009 Google Inc. +// All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) + +// Implements a subset of TR1 tuple needed by Google Test and Google Mock. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ + +#include // For ::std::pair. + +// The compiler used in Symbian has a bug that prevents us from declaring the +// tuple template as a friend (it complains that tuple is redefined). This +// hack bypasses the bug by declaring the members that should otherwise be +// private as public. +// Sun Studio versions < 12 also have the above bug. +#if defined(__SYMBIAN32__) || (defined(__SUNPRO_CC) && __SUNPRO_CC < 0x590) +# define GTEST_DECLARE_TUPLE_AS_FRIEND_ public: +#else +# define GTEST_DECLARE_TUPLE_AS_FRIEND_ \ + template friend class tuple; \ + private: +#endif + +// GTEST_n_TUPLE_(T) is the type of an n-tuple. +#define GTEST_0_TUPLE_(T) tuple<> +#define GTEST_1_TUPLE_(T) tuple +#define GTEST_2_TUPLE_(T) tuple +#define GTEST_3_TUPLE_(T) tuple +#define GTEST_4_TUPLE_(T) tuple +#define GTEST_5_TUPLE_(T) tuple +#define GTEST_6_TUPLE_(T) tuple +#define GTEST_7_TUPLE_(T) tuple +#define GTEST_8_TUPLE_(T) tuple +#define GTEST_9_TUPLE_(T) tuple +#define GTEST_10_TUPLE_(T) tuple + +// GTEST_n_TYPENAMES_(T) declares a list of n typenames. +#define GTEST_0_TYPENAMES_(T) +#define GTEST_1_TYPENAMES_(T) typename T##0 +#define GTEST_2_TYPENAMES_(T) typename T##0, typename T##1 +#define GTEST_3_TYPENAMES_(T) typename T##0, typename T##1, typename T##2 +#define GTEST_4_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3 +#define GTEST_5_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3, typename T##4 +#define GTEST_6_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3, typename T##4, typename T##5 +#define GTEST_7_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3, typename T##4, typename T##5, typename T##6 +#define GTEST_8_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3, typename T##4, typename T##5, typename T##6, typename T##7 +#define GTEST_9_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3, typename T##4, typename T##5, typename T##6, \ + typename T##7, typename T##8 +#define GTEST_10_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3, typename T##4, typename T##5, typename T##6, \ + typename T##7, typename T##8, typename T##9 + +// In theory, defining stuff in the ::std namespace is undefined +// behavior. We can do this as we are playing the role of a standard +// library vendor. +namespace std { +namespace tr1 { + +template +class tuple; + +// Anything in namespace gtest_internal is Google Test's INTERNAL +// IMPLEMENTATION DETAIL and MUST NOT BE USED DIRECTLY in user code. +namespace gtest_internal { + +// ByRef::type is T if T is a reference; otherwise it's const T&. +template +struct ByRef { typedef const T& type; }; // NOLINT +template +struct ByRef { typedef T& type; }; // NOLINT + +// A handy wrapper for ByRef. +#define GTEST_BY_REF_(T) typename ::std::tr1::gtest_internal::ByRef::type + +// AddRef::type is T if T is a reference; otherwise it's T&. This +// is the same as tr1::add_reference::type. +template +struct AddRef { typedef T& type; }; // NOLINT +template +struct AddRef { typedef T& type; }; // NOLINT + +// A handy wrapper for AddRef. +#define GTEST_ADD_REF_(T) typename ::std::tr1::gtest_internal::AddRef::type + +// A helper for implementing get(). +template class Get; + +// A helper for implementing tuple_element. kIndexValid is true +// iff k < the number of fields in tuple type T. +template +struct TupleElement; + +template +struct TupleElement { + typedef T0 type; +}; + +template +struct TupleElement { + typedef T1 type; +}; + +template +struct TupleElement { + typedef T2 type; +}; + +template +struct TupleElement { + typedef T3 type; +}; + +template +struct TupleElement { + typedef T4 type; +}; + +template +struct TupleElement { + typedef T5 type; +}; + +template +struct TupleElement { + typedef T6 type; +}; + +template +struct TupleElement { + typedef T7 type; +}; + +template +struct TupleElement { + typedef T8 type; +}; + +template +struct TupleElement { + typedef T9 type; +}; + +} // namespace gtest_internal + +template <> +class tuple<> { + public: + tuple() {} + tuple(const tuple& /* t */) {} + tuple& operator=(const tuple& /* t */) { return *this; } +}; + +template +class GTEST_1_TUPLE_(T) { + public: + template friend class gtest_internal::Get; + + tuple() : f0_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0) : f0_(f0) {} + + tuple(const tuple& t) : f0_(t.f0_) {} + + template + tuple(const GTEST_1_TUPLE_(U)& t) : f0_(t.f0_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_1_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_1_TUPLE_(U)& t) { + f0_ = t.f0_; + return *this; + } + + T0 f0_; +}; + +template +class GTEST_2_TUPLE_(T) { + public: + template friend class gtest_internal::Get; + + tuple() : f0_(), f1_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1) : f0_(f0), + f1_(f1) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_) {} + + template + tuple(const GTEST_2_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_) {} + template + tuple(const ::std::pair& p) : f0_(p.first), f1_(p.second) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_2_TUPLE_(U)& t) { + return CopyFrom(t); + } + template + tuple& operator=(const ::std::pair& p) { + f0_ = p.first; + f1_ = p.second; + return *this; + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_2_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + return *this; + } + + T0 f0_; + T1 f1_; +}; + +template +class GTEST_3_TUPLE_(T) { + public: + template friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2) : f0_(f0), f1_(f1), f2_(f2) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_) {} + + template + tuple(const GTEST_3_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_3_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_3_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; +}; + +template +class GTEST_4_TUPLE_(T) { + public: + template friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3) : f0_(f0), f1_(f1), f2_(f2), + f3_(f3) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_) {} + + template + tuple(const GTEST_4_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_4_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_4_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; +}; + +template +class GTEST_5_TUPLE_(T) { + public: + template friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_(), f4_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, + GTEST_BY_REF_(T4) f4) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), + f4_(t.f4_) {} + + template + tuple(const GTEST_5_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_), f4_(t.f4_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_5_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_5_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + f4_ = t.f4_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; + T4 f4_; +}; + +template +class GTEST_6_TUPLE_(T) { + public: + template friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, + GTEST_BY_REF_(T5) f5) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4), + f5_(f5) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), + f4_(t.f4_), f5_(t.f5_) {} + + template + tuple(const GTEST_6_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_), f4_(t.f4_), f5_(t.f5_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_6_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_6_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + f4_ = t.f4_; + f5_ = t.f5_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; + T4 f4_; + T5 f5_; +}; + +template +class GTEST_7_TUPLE_(T) { + public: + template friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, + GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6) : f0_(f0), f1_(f1), f2_(f2), + f3_(f3), f4_(f4), f5_(f5), f6_(f6) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), + f4_(t.f4_), f5_(t.f5_), f6_(t.f6_) {} + + template + tuple(const GTEST_7_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_7_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_7_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + f4_ = t.f4_; + f5_ = t.f5_; + f6_ = t.f6_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; + T4 f4_; + T5 f5_; + T6 f6_; +}; + +template +class GTEST_8_TUPLE_(T) { + public: + template friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, + GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, + GTEST_BY_REF_(T7) f7) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4), + f5_(f5), f6_(f6), f7_(f7) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), + f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_) {} + + template + tuple(const GTEST_8_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_8_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_8_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + f4_ = t.f4_; + f5_ = t.f5_; + f6_ = t.f6_; + f7_ = t.f7_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; + T4 f4_; + T5 f5_; + T6 f6_; + T7 f7_; +}; + +template +class GTEST_9_TUPLE_(T) { + public: + template friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_(), f8_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, + GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, GTEST_BY_REF_(T7) f7, + GTEST_BY_REF_(T8) f8) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4), + f5_(f5), f6_(f6), f7_(f7), f8_(f8) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), + f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_) {} + + template + tuple(const GTEST_9_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_9_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_9_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + f4_ = t.f4_; + f5_ = t.f5_; + f6_ = t.f6_; + f7_ = t.f7_; + f8_ = t.f8_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; + T4 f4_; + T5 f5_; + T6 f6_; + T7 f7_; + T8 f8_; +}; + +template +class tuple { + public: + template friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_(), f8_(), + f9_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, + GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, GTEST_BY_REF_(T7) f7, + GTEST_BY_REF_(T8) f8, GTEST_BY_REF_(T9) f9) : f0_(f0), f1_(f1), f2_(f2), + f3_(f3), f4_(f4), f5_(f5), f6_(f6), f7_(f7), f8_(f8), f9_(f9) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), + f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_), f9_(t.f9_) {} + + template + tuple(const GTEST_10_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_), + f9_(t.f9_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_10_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_10_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + f4_ = t.f4_; + f5_ = t.f5_; + f6_ = t.f6_; + f7_ = t.f7_; + f8_ = t.f8_; + f9_ = t.f9_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; + T4 f4_; + T5 f5_; + T6 f6_; + T7 f7_; + T8 f8_; + T9 f9_; +}; + +// 6.1.3.2 Tuple creation functions. + +// Known limitations: we don't support passing an +// std::tr1::reference_wrapper to make_tuple(). And we don't +// implement tie(). + +inline tuple<> make_tuple() { return tuple<>(); } + +template +inline GTEST_1_TUPLE_(T) make_tuple(const T0& f0) { + return GTEST_1_TUPLE_(T)(f0); +} + +template +inline GTEST_2_TUPLE_(T) make_tuple(const T0& f0, const T1& f1) { + return GTEST_2_TUPLE_(T)(f0, f1); +} + +template +inline GTEST_3_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2) { + return GTEST_3_TUPLE_(T)(f0, f1, f2); +} + +template +inline GTEST_4_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3) { + return GTEST_4_TUPLE_(T)(f0, f1, f2, f3); +} + +template +inline GTEST_5_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3, const T4& f4) { + return GTEST_5_TUPLE_(T)(f0, f1, f2, f3, f4); +} + +template +inline GTEST_6_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3, const T4& f4, const T5& f5) { + return GTEST_6_TUPLE_(T)(f0, f1, f2, f3, f4, f5); +} + +template +inline GTEST_7_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3, const T4& f4, const T5& f5, const T6& f6) { + return GTEST_7_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6); +} + +template +inline GTEST_8_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7) { + return GTEST_8_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7); +} + +template +inline GTEST_9_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7, + const T8& f8) { + return GTEST_9_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7, f8); +} + +template +inline GTEST_10_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7, + const T8& f8, const T9& f9) { + return GTEST_10_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7, f8, f9); +} + +// 6.1.3.3 Tuple helper classes. + +template struct tuple_size; + +template +struct tuple_size { + static const int value = 0; +}; + +template +struct tuple_size { + static const int value = 1; +}; + +template +struct tuple_size { + static const int value = 2; +}; + +template +struct tuple_size { + static const int value = 3; +}; + +template +struct tuple_size { + static const int value = 4; +}; + +template +struct tuple_size { + static const int value = 5; +}; + +template +struct tuple_size { + static const int value = 6; +}; + +template +struct tuple_size { + static const int value = 7; +}; + +template +struct tuple_size { + static const int value = 8; +}; + +template +struct tuple_size { + static const int value = 9; +}; + +template +struct tuple_size { + static const int value = 10; +}; + +template +struct tuple_element { + typedef typename gtest_internal::TupleElement< + k < (tuple_size::value), k, Tuple>::type type; +}; + +#define GTEST_TUPLE_ELEMENT_(k, Tuple) typename tuple_element::type + +// 6.1.3.4 Element access. + +namespace gtest_internal { + +template <> +class Get<0> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(0, Tuple)) + Field(Tuple& t) { return t.f0_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(0, Tuple)) + ConstField(const Tuple& t) { return t.f0_; } +}; + +template <> +class Get<1> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(1, Tuple)) + Field(Tuple& t) { return t.f1_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(1, Tuple)) + ConstField(const Tuple& t) { return t.f1_; } +}; + +template <> +class Get<2> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(2, Tuple)) + Field(Tuple& t) { return t.f2_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(2, Tuple)) + ConstField(const Tuple& t) { return t.f2_; } +}; + +template <> +class Get<3> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(3, Tuple)) + Field(Tuple& t) { return t.f3_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(3, Tuple)) + ConstField(const Tuple& t) { return t.f3_; } +}; + +template <> +class Get<4> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(4, Tuple)) + Field(Tuple& t) { return t.f4_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(4, Tuple)) + ConstField(const Tuple& t) { return t.f4_; } +}; + +template <> +class Get<5> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(5, Tuple)) + Field(Tuple& t) { return t.f5_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(5, Tuple)) + ConstField(const Tuple& t) { return t.f5_; } +}; + +template <> +class Get<6> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(6, Tuple)) + Field(Tuple& t) { return t.f6_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(6, Tuple)) + ConstField(const Tuple& t) { return t.f6_; } +}; + +template <> +class Get<7> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(7, Tuple)) + Field(Tuple& t) { return t.f7_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(7, Tuple)) + ConstField(const Tuple& t) { return t.f7_; } +}; + +template <> +class Get<8> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(8, Tuple)) + Field(Tuple& t) { return t.f8_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(8, Tuple)) + ConstField(const Tuple& t) { return t.f8_; } +}; + +template <> +class Get<9> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(9, Tuple)) + Field(Tuple& t) { return t.f9_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(9, Tuple)) + ConstField(const Tuple& t) { return t.f9_; } +}; + +} // namespace gtest_internal + +template +GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_10_TUPLE_(T))) +get(GTEST_10_TUPLE_(T)& t) { + return gtest_internal::Get::Field(t); +} + +template +GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_10_TUPLE_(T))) +get(const GTEST_10_TUPLE_(T)& t) { + return gtest_internal::Get::ConstField(t); +} + +// 6.1.3.5 Relational operators + +// We only implement == and !=, as we don't have a need for the rest yet. + +namespace gtest_internal { + +// SameSizeTuplePrefixComparator::Eq(t1, t2) returns true if the +// first k fields of t1 equals the first k fields of t2. +// SameSizeTuplePrefixComparator(k1, k2) would be a compiler error if +// k1 != k2. +template +struct SameSizeTuplePrefixComparator; + +template <> +struct SameSizeTuplePrefixComparator<0, 0> { + template + static bool Eq(const Tuple1& /* t1 */, const Tuple2& /* t2 */) { + return true; + } +}; + +template +struct SameSizeTuplePrefixComparator { + template + static bool Eq(const Tuple1& t1, const Tuple2& t2) { + return SameSizeTuplePrefixComparator::Eq(t1, t2) && + ::std::tr1::get(t1) == ::std::tr1::get(t2); + } +}; + +} // namespace gtest_internal + +template +inline bool operator==(const GTEST_10_TUPLE_(T)& t, + const GTEST_10_TUPLE_(U)& u) { + return gtest_internal::SameSizeTuplePrefixComparator< + tuple_size::value, + tuple_size::value>::Eq(t, u); +} + +template +inline bool operator!=(const GTEST_10_TUPLE_(T)& t, + const GTEST_10_TUPLE_(U)& u) { return !(t == u); } + +// 6.1.4 Pairs. +// Unimplemented. + +} // namespace tr1 +} // namespace std + +#undef GTEST_0_TUPLE_ +#undef GTEST_1_TUPLE_ +#undef GTEST_2_TUPLE_ +#undef GTEST_3_TUPLE_ +#undef GTEST_4_TUPLE_ +#undef GTEST_5_TUPLE_ +#undef GTEST_6_TUPLE_ +#undef GTEST_7_TUPLE_ +#undef GTEST_8_TUPLE_ +#undef GTEST_9_TUPLE_ +#undef GTEST_10_TUPLE_ + +#undef GTEST_0_TYPENAMES_ +#undef GTEST_1_TYPENAMES_ +#undef GTEST_2_TYPENAMES_ +#undef GTEST_3_TYPENAMES_ +#undef GTEST_4_TYPENAMES_ +#undef GTEST_5_TYPENAMES_ +#undef GTEST_6_TYPENAMES_ +#undef GTEST_7_TYPENAMES_ +#undef GTEST_8_TYPENAMES_ +#undef GTEST_9_TYPENAMES_ +#undef GTEST_10_TYPENAMES_ + +#undef GTEST_DECLARE_TUPLE_AS_FRIEND_ +#undef GTEST_BY_REF_ +#undef GTEST_ADD_REF_ +#undef GTEST_TUPLE_ELEMENT_ + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ +# elif GTEST_ENV_HAS_STD_TUPLE_ +# include +// C++11 puts its tuple into the ::std namespace rather than +// ::std::tr1. gtest expects tuple to live in ::std::tr1, so put it there. +// This causes undefined behavior, but supported compilers react in +// the way we intend. +namespace std { +namespace tr1 { +using ::std::get; +using ::std::make_tuple; +using ::std::tuple; +using ::std::tuple_element; +using ::std::tuple_size; +} +} + +# elif GTEST_OS_SYMBIAN + +// On Symbian, BOOST_HAS_TR1_TUPLE causes Boost's TR1 tuple library to +// use STLport's tuple implementation, which unfortunately doesn't +// work as the copy of STLport distributed with Symbian is incomplete. +// By making sure BOOST_HAS_TR1_TUPLE is undefined, we force Boost to +// use its own tuple implementation. +# ifdef BOOST_HAS_TR1_TUPLE +# undef BOOST_HAS_TR1_TUPLE +# endif // BOOST_HAS_TR1_TUPLE + +// This prevents , which defines +// BOOST_HAS_TR1_TUPLE, from being #included by Boost's . +# define BOOST_TR1_DETAIL_CONFIG_HPP_INCLUDED +# include + +# elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40000) +// GCC 4.0+ implements tr1/tuple in the header. This does +// not conform to the TR1 spec, which requires the header to be . + +# if !GTEST_HAS_RTTI && GTEST_GCC_VER_ < 40302 +// Until version 4.3.2, gcc has a bug that causes , +// which is #included by , to not compile when RTTI is +// disabled. _TR1_FUNCTIONAL is the header guard for +// . Hence the following #define is a hack to prevent +// from being included. +# define _TR1_FUNCTIONAL 1 +# include +# undef _TR1_FUNCTIONAL // Allows the user to #include + // if he chooses to. +# else +# include // NOLINT +# endif // !GTEST_HAS_RTTI && GTEST_GCC_VER_ < 40302 + +# else +// If the compiler is not GCC 4.0+, we assume the user is using a +// spec-conforming TR1 implementation. +# include // NOLINT +# endif // GTEST_USE_OWN_TR1_TUPLE + +#endif // GTEST_HAS_TR1_TUPLE + +// Determines whether clone(2) is supported. +// Usually it will only be available on Linux, excluding +// Linux on the Itanium architecture. +// Also see http://linux.die.net/man/2/clone. +#ifndef GTEST_HAS_CLONE +// The user didn't tell us, so we need to figure it out. + +# if GTEST_OS_LINUX && !defined(__ia64__) +# if GTEST_OS_LINUX_ANDROID +// On Android, clone() is only available on ARM starting with Gingerbread. +# if defined(__arm__) && __ANDROID_API__ >= 9 +# define GTEST_HAS_CLONE 1 +# else +# define GTEST_HAS_CLONE 0 +# endif +# else +# define GTEST_HAS_CLONE 1 +# endif +# else +# define GTEST_HAS_CLONE 0 +# endif // GTEST_OS_LINUX && !defined(__ia64__) + +#endif // GTEST_HAS_CLONE + +// Determines whether to support stream redirection. This is used to test +// output correctness and to implement death tests. +#ifndef GTEST_HAS_STREAM_REDIRECTION +// By default, we assume that stream redirection is supported on all +// platforms except known mobile ones. +# if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN +# define GTEST_HAS_STREAM_REDIRECTION 0 +# else +# define GTEST_HAS_STREAM_REDIRECTION 1 +# endif // !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_SYMBIAN +#endif // GTEST_HAS_STREAM_REDIRECTION + +// Determines whether to support death tests. +// Google Test does not support death tests for VC 7.1 and earlier as +// abort() in a VC 7.1 application compiled as GUI in debug config +// pops up a dialog window that cannot be suppressed programmatically. +#if (GTEST_OS_LINUX || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || \ + (GTEST_OS_MAC && !GTEST_OS_IOS) || GTEST_OS_IOS_SIMULATOR || \ + (GTEST_OS_WINDOWS_DESKTOP && _MSC_VER >= 1400) || \ + GTEST_OS_WINDOWS_MINGW || GTEST_OS_AIX || GTEST_OS_HPUX || \ + GTEST_OS_OPENBSD || GTEST_OS_QNX) +# define GTEST_HAS_DEATH_TEST 1 +# include // NOLINT +#endif + +// We don't support MSVC 7.1 with exceptions disabled now. Therefore +// all the compilers we care about are adequate for supporting +// value-parameterized tests. +#define GTEST_HAS_PARAM_TEST 1 + +// Determines whether to support type-driven tests. + +// Typed tests need and variadic macros, which GCC, VC++ 8.0, +// Sun Pro CC, IBM Visual Age, and HP aCC support. +#if defined(__GNUC__) || (_MSC_VER >= 1400) || defined(__SUNPRO_CC) || \ + defined(__IBMCPP__) || defined(__HP_aCC) +# define GTEST_HAS_TYPED_TEST 1 +# define GTEST_HAS_TYPED_TEST_P 1 +#endif + +// Determines whether to support Combine(). This only makes sense when +// value-parameterized tests are enabled. The implementation doesn't +// work on Sun Studio since it doesn't understand templated conversion +// operators. +#if GTEST_HAS_PARAM_TEST && GTEST_HAS_TR1_TUPLE && !defined(__SUNPRO_CC) +# define GTEST_HAS_COMBINE 1 +#endif + +// Determines whether the system compiler uses UTF-16 for encoding wide strings. +#define GTEST_WIDE_STRING_USES_UTF16_ \ + (GTEST_OS_WINDOWS || GTEST_OS_CYGWIN || GTEST_OS_SYMBIAN || GTEST_OS_AIX) + +// Determines whether test results can be streamed to a socket. +#if GTEST_OS_LINUX +# define GTEST_CAN_STREAM_RESULTS_ 1 +#endif + +// Defines some utility macros. + +// The GNU compiler emits a warning if nested "if" statements are followed by +// an "else" statement and braces are not used to explicitly disambiguate the +// "else" binding. This leads to problems with code like: +// +// if (gate) +// ASSERT_*(condition) << "Some message"; +// +// The "switch (0) case 0:" idiom is used to suppress this. +#ifdef __INTEL_COMPILER +# define GTEST_AMBIGUOUS_ELSE_BLOCKER_ +#else +# define GTEST_AMBIGUOUS_ELSE_BLOCKER_ switch (0) case 0: default: // NOLINT +#endif + +// Use this annotation at the end of a struct/class definition to +// prevent the compiler from optimizing away instances that are never +// used. This is useful when all interesting logic happens inside the +// c'tor and / or d'tor. Example: +// +// struct Foo { +// Foo() { ... } +// } GTEST_ATTRIBUTE_UNUSED_; +// +// Also use it after a variable or parameter declaration to tell the +// compiler the variable/parameter does not have to be used. +#if defined(__GNUC__) && !defined(COMPILER_ICC) +# define GTEST_ATTRIBUTE_UNUSED_ __attribute__ ((unused)) +#else +# define GTEST_ATTRIBUTE_UNUSED_ +#endif + +// A macro to disallow operator= +// This should be used in the private: declarations for a class. +#define GTEST_DISALLOW_ASSIGN_(type)\ + void operator=(type const &) + +// A macro to disallow copy constructor and operator= +// This should be used in the private: declarations for a class. +#define GTEST_DISALLOW_COPY_AND_ASSIGN_(type)\ + type(type const &);\ + GTEST_DISALLOW_ASSIGN_(type) + +// Tell the compiler to warn about unused return values for functions declared +// with this macro. The macro should be used on function declarations +// following the argument list: +// +// Sprocket* AllocateSprocket() GTEST_MUST_USE_RESULT_; +#if defined(__GNUC__) && (GTEST_GCC_VER_ >= 30400) && !defined(COMPILER_ICC) +# define GTEST_MUST_USE_RESULT_ __attribute__ ((warn_unused_result)) +#else +# define GTEST_MUST_USE_RESULT_ +#endif // __GNUC__ && (GTEST_GCC_VER_ >= 30400) && !COMPILER_ICC + +// Determine whether the compiler supports Microsoft's Structured Exception +// Handling. This is supported by several Windows compilers but generally +// does not exist on any other system. +#ifndef GTEST_HAS_SEH +// The user didn't tell us, so we need to figure it out. + +# if defined(_MSC_VER) || defined(__BORLANDC__) +// These two compilers are known to support SEH. +# define GTEST_HAS_SEH 1 +# else +// Assume no SEH. +# define GTEST_HAS_SEH 0 +# endif + +#endif // GTEST_HAS_SEH + +#ifdef _MSC_VER + +# if GTEST_LINKED_AS_SHARED_LIBRARY +# define GTEST_API_ __declspec(dllimport) +# elif GTEST_CREATE_SHARED_LIBRARY +# define GTEST_API_ __declspec(dllexport) +# endif + +#endif // _MSC_VER + +#ifndef GTEST_API_ +# define GTEST_API_ +#endif + +#ifdef __GNUC__ +// Ask the compiler to never inline a given function. +# define GTEST_NO_INLINE_ __attribute__((noinline)) +#else +# define GTEST_NO_INLINE_ +#endif + +// _LIBCPP_VERSION is defined by the libc++ library from the LLVM project. +#if defined(__GLIBCXX__) || defined(_LIBCPP_VERSION) +# define GTEST_HAS_CXXABI_H_ 1 +#else +# define GTEST_HAS_CXXABI_H_ 0 +#endif + +namespace testing { + +class Message; + +namespace internal { + +// A secret type that Google Test users don't know about. It has no +// definition on purpose. Therefore it's impossible to create a +// Secret object, which is what we want. +class Secret; + +// The GTEST_COMPILE_ASSERT_ macro can be used to verify that a compile time +// expression is true. For example, you could use it to verify the +// size of a static array: +// +// GTEST_COMPILE_ASSERT_(ARRAYSIZE(content_type_names) == CONTENT_NUM_TYPES, +// content_type_names_incorrect_size); +// +// or to make sure a struct is smaller than a certain size: +// +// GTEST_COMPILE_ASSERT_(sizeof(foo) < 128, foo_too_large); +// +// The second argument to the macro is the name of the variable. If +// the expression is false, most compilers will issue a warning/error +// containing the name of the variable. + +template +struct CompileAssert { +}; + +#define GTEST_COMPILE_ASSERT_(expr, msg) \ + typedef ::testing::internal::CompileAssert<(static_cast(expr))> \ + msg[static_cast(expr) ? 1 : -1] GTEST_ATTRIBUTE_UNUSED_ + +// Implementation details of GTEST_COMPILE_ASSERT_: +// +// - GTEST_COMPILE_ASSERT_ works by defining an array type that has -1 +// elements (and thus is invalid) when the expression is false. +// +// - The simpler definition +// +// #define GTEST_COMPILE_ASSERT_(expr, msg) typedef char msg[(expr) ? 1 : -1] +// +// does not work, as gcc supports variable-length arrays whose sizes +// are determined at run-time (this is gcc's extension and not part +// of the C++ standard). As a result, gcc fails to reject the +// following code with the simple definition: +// +// int foo; +// GTEST_COMPILE_ASSERT_(foo, msg); // not supposed to compile as foo is +// // not a compile-time constant. +// +// - By using the type CompileAssert<(bool(expr))>, we ensures that +// expr is a compile-time constant. (Template arguments must be +// determined at compile-time.) +// +// - The outter parentheses in CompileAssert<(bool(expr))> are necessary +// to work around a bug in gcc 3.4.4 and 4.0.1. If we had written +// +// CompileAssert +// +// instead, these compilers will refuse to compile +// +// GTEST_COMPILE_ASSERT_(5 > 0, some_message); +// +// (They seem to think the ">" in "5 > 0" marks the end of the +// template argument list.) +// +// - The array size is (bool(expr) ? 1 : -1), instead of simply +// +// ((expr) ? 1 : -1). +// +// This is to avoid running into a bug in MS VC 7.1, which +// causes ((0.0) ? 1 : -1) to incorrectly evaluate to 1. + +// StaticAssertTypeEqHelper is used by StaticAssertTypeEq defined in gtest.h. +// +// This template is declared, but intentionally undefined. +template +struct StaticAssertTypeEqHelper; + +template +struct StaticAssertTypeEqHelper {}; + +#if GTEST_HAS_GLOBAL_STRING +typedef ::string string; +#else +typedef ::std::string string; +#endif // GTEST_HAS_GLOBAL_STRING + +#if GTEST_HAS_GLOBAL_WSTRING +typedef ::wstring wstring; +#elif GTEST_HAS_STD_WSTRING +typedef ::std::wstring wstring; +#endif // GTEST_HAS_GLOBAL_WSTRING + +// A helper for suppressing warnings on constant condition. It just +// returns 'condition'. +GTEST_API_ bool IsTrue(bool condition); + +// Defines scoped_ptr. + +// This implementation of scoped_ptr is PARTIAL - it only contains +// enough stuff to satisfy Google Test's need. +template +class scoped_ptr { + public: + typedef T element_type; + + explicit scoped_ptr(T* p = NULL) : ptr_(p) {} + ~scoped_ptr() { reset(); } + + T& operator*() const { return *ptr_; } + T* operator->() const { return ptr_; } + T* get() const { return ptr_; } + + T* release() { + T* const ptr = ptr_; + ptr_ = NULL; + return ptr; + } + + void reset(T* p = NULL) { + if (p != ptr_) { + if (IsTrue(sizeof(T) > 0)) { // Makes sure T is a complete type. + delete ptr_; + } + ptr_ = p; + } + } + + private: + T* ptr_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(scoped_ptr); +}; + +// Defines RE. + +// A simple C++ wrapper for . It uses the POSIX Extended +// Regular Expression syntax. +class GTEST_API_ RE { + public: + // A copy constructor is required by the Standard to initialize object + // references from r-values. + RE(const RE& other) { Init(other.pattern()); } + + // Constructs an RE from a string. + RE(const ::std::string& regex) { Init(regex.c_str()); } // NOLINT + +#if GTEST_HAS_GLOBAL_STRING + + RE(const ::string& regex) { Init(regex.c_str()); } // NOLINT + +#endif // GTEST_HAS_GLOBAL_STRING + + RE(const char* regex) { Init(regex); } // NOLINT + ~RE(); + + // Returns the string representation of the regex. + const char* pattern() const { return pattern_; } + + // FullMatch(str, re) returns true iff regular expression re matches + // the entire str. + // PartialMatch(str, re) returns true iff regular expression re + // matches a substring of str (including str itself). + // + // TODO(wan@google.com): make FullMatch() and PartialMatch() work + // when str contains NUL characters. + static bool FullMatch(const ::std::string& str, const RE& re) { + return FullMatch(str.c_str(), re); + } + static bool PartialMatch(const ::std::string& str, const RE& re) { + return PartialMatch(str.c_str(), re); + } + +#if GTEST_HAS_GLOBAL_STRING + + static bool FullMatch(const ::string& str, const RE& re) { + return FullMatch(str.c_str(), re); + } + static bool PartialMatch(const ::string& str, const RE& re) { + return PartialMatch(str.c_str(), re); + } + +#endif // GTEST_HAS_GLOBAL_STRING + + static bool FullMatch(const char* str, const RE& re); + static bool PartialMatch(const char* str, const RE& re); + + private: + void Init(const char* regex); + + // We use a const char* instead of an std::string, as Google Test used to be + // used where std::string is not available. TODO(wan@google.com): change to + // std::string. + const char* pattern_; + bool is_valid_; + +#if GTEST_USES_POSIX_RE + + regex_t full_regex_; // For FullMatch(). + regex_t partial_regex_; // For PartialMatch(). + +#else // GTEST_USES_SIMPLE_RE + + const char* full_pattern_; // For FullMatch(); + +#endif + + GTEST_DISALLOW_ASSIGN_(RE); +}; + +// Formats a source file path and a line number as they would appear +// in an error message from the compiler used to compile this code. +GTEST_API_ ::std::string FormatFileLocation(const char* file, int line); + +// Formats a file location for compiler-independent XML output. +// Although this function is not platform dependent, we put it next to +// FormatFileLocation in order to contrast the two functions. +GTEST_API_ ::std::string FormatCompilerIndependentFileLocation(const char* file, + int line); + +// Defines logging utilities: +// GTEST_LOG_(severity) - logs messages at the specified severity level. The +// message itself is streamed into the macro. +// LogToStderr() - directs all log messages to stderr. +// FlushInfoLog() - flushes informational log messages. + +enum GTestLogSeverity { + GTEST_INFO, + GTEST_WARNING, + GTEST_ERROR, + GTEST_FATAL +}; + +// Formats log entry severity, provides a stream object for streaming the +// log message, and terminates the message with a newline when going out of +// scope. +class GTEST_API_ GTestLog { + public: + GTestLog(GTestLogSeverity severity, const char* file, int line); + + // Flushes the buffers and, if severity is GTEST_FATAL, aborts the program. + ~GTestLog(); + + ::std::ostream& GetStream() { return ::std::cerr; } + + private: + const GTestLogSeverity severity_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestLog); +}; + +#define GTEST_LOG_(severity) \ + ::testing::internal::GTestLog(::testing::internal::GTEST_##severity, \ + __FILE__, __LINE__).GetStream() + +inline void LogToStderr() {} +inline void FlushInfoLog() { fflush(NULL); } + +// INTERNAL IMPLEMENTATION - DO NOT USE. +// +// GTEST_CHECK_ is an all-mode assert. It aborts the program if the condition +// is not satisfied. +// Synopsys: +// GTEST_CHECK_(boolean_condition); +// or +// GTEST_CHECK_(boolean_condition) << "Additional message"; +// +// This checks the condition and if the condition is not satisfied +// it prints message about the condition violation, including the +// condition itself, plus additional message streamed into it, if any, +// and then it aborts the program. It aborts the program irrespective of +// whether it is built in the debug mode or not. +#define GTEST_CHECK_(condition) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::IsTrue(condition)) \ + ; \ + else \ + GTEST_LOG_(FATAL) << "Condition " #condition " failed. " + +// An all-mode assert to verify that the given POSIX-style function +// call returns 0 (indicating success). Known limitation: this +// doesn't expand to a balanced 'if' statement, so enclose the macro +// in {} if you need to use it as the only statement in an 'if' +// branch. +#define GTEST_CHECK_POSIX_SUCCESS_(posix_call) \ + if (const int gtest_error = (posix_call)) \ + GTEST_LOG_(FATAL) << #posix_call << "failed with error " \ + << gtest_error + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Use ImplicitCast_ as a safe version of static_cast for upcasting in +// the type hierarchy (e.g. casting a Foo* to a SuperclassOfFoo* or a +// const Foo*). When you use ImplicitCast_, the compiler checks that +// the cast is safe. Such explicit ImplicitCast_s are necessary in +// surprisingly many situations where C++ demands an exact type match +// instead of an argument type convertable to a target type. +// +// The syntax for using ImplicitCast_ is the same as for static_cast: +// +// ImplicitCast_(expr) +// +// ImplicitCast_ would have been part of the C++ standard library, +// but the proposal was submitted too late. It will probably make +// its way into the language in the future. +// +// This relatively ugly name is intentional. It prevents clashes with +// similar functions users may have (e.g., implicit_cast). The internal +// namespace alone is not enough because the function can be found by ADL. +template +inline To ImplicitCast_(To x) { return x; } + +// When you upcast (that is, cast a pointer from type Foo to type +// SuperclassOfFoo), it's fine to use ImplicitCast_<>, since upcasts +// always succeed. When you downcast (that is, cast a pointer from +// type Foo to type SubclassOfFoo), static_cast<> isn't safe, because +// how do you know the pointer is really of type SubclassOfFoo? It +// could be a bare Foo, or of type DifferentSubclassOfFoo. Thus, +// when you downcast, you should use this macro. In debug mode, we +// use dynamic_cast<> to double-check the downcast is legal (we die +// if it's not). In normal mode, we do the efficient static_cast<> +// instead. Thus, it's important to test in debug mode to make sure +// the cast is legal! +// This is the only place in the code we should use dynamic_cast<>. +// In particular, you SHOULDN'T be using dynamic_cast<> in order to +// do RTTI (eg code like this: +// if (dynamic_cast(foo)) HandleASubclass1Object(foo); +// if (dynamic_cast(foo)) HandleASubclass2Object(foo); +// You should design the code some other way not to need this. +// +// This relatively ugly name is intentional. It prevents clashes with +// similar functions users may have (e.g., down_cast). The internal +// namespace alone is not enough because the function can be found by ADL. +template // use like this: DownCast_(foo); +inline To DownCast_(From* f) { // so we only accept pointers + // Ensures that To is a sub-type of From *. This test is here only + // for compile-time type checking, and has no overhead in an + // optimized build at run-time, as it will be optimized away + // completely. + if (false) { + const To to = NULL; + ::testing::internal::ImplicitCast_(to); + } + +#if GTEST_HAS_RTTI + // RTTI: debug mode only! + GTEST_CHECK_(f == NULL || dynamic_cast(f) != NULL); +#endif + return static_cast(f); +} + +// Downcasts the pointer of type Base to Derived. +// Derived must be a subclass of Base. The parameter MUST +// point to a class of type Derived, not any subclass of it. +// When RTTI is available, the function performs a runtime +// check to enforce this. +template +Derived* CheckedDowncastToActualType(Base* base) { +#if GTEST_HAS_RTTI + GTEST_CHECK_(typeid(*base) == typeid(Derived)); + return dynamic_cast(base); // NOLINT +#else + return static_cast(base); // Poor man's downcast. +#endif +} + +#if GTEST_HAS_STREAM_REDIRECTION + +// Defines the stderr capturer: +// CaptureStdout - starts capturing stdout. +// GetCapturedStdout - stops capturing stdout and returns the captured string. +// CaptureStderr - starts capturing stderr. +// GetCapturedStderr - stops capturing stderr and returns the captured string. +// +GTEST_API_ void CaptureStdout(); +GTEST_API_ std::string GetCapturedStdout(); +GTEST_API_ void CaptureStderr(); +GTEST_API_ std::string GetCapturedStderr(); + +#endif // GTEST_HAS_STREAM_REDIRECTION + + +#if GTEST_HAS_DEATH_TEST + +const ::std::vector& GetInjectableArgvs(); +void SetInjectableArgvs(const ::std::vector* + new_argvs); + +// A copy of all command line arguments. Set by InitGoogleTest(). +extern ::std::vector g_argvs; + +#endif // GTEST_HAS_DEATH_TEST + +// Defines synchronization primitives. + +#if GTEST_HAS_PTHREAD + +// Sleeps for (roughly) n milli-seconds. This function is only for +// testing Google Test's own constructs. Don't use it in user tests, +// either directly or indirectly. +inline void SleepMilliseconds(int n) { + const timespec time = { + 0, // 0 seconds. + n * 1000L * 1000L, // And n ms. + }; + nanosleep(&time, NULL); +} + +// Allows a controller thread to pause execution of newly created +// threads until notified. Instances of this class must be created +// and destroyed in the controller thread. +// +// This class is only for testing Google Test's own constructs. Do not +// use it in user tests, either directly or indirectly. +class Notification { + public: + Notification() : notified_(false) { + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, NULL)); + } + ~Notification() { + pthread_mutex_destroy(&mutex_); + } + + // Notifies all threads created with this notification to start. Must + // be called from the controller thread. + void Notify() { + pthread_mutex_lock(&mutex_); + notified_ = true; + pthread_mutex_unlock(&mutex_); + } + + // Blocks until the controller thread notifies. Must be called from a test + // thread. + void WaitForNotification() { + for (;;) { + pthread_mutex_lock(&mutex_); + const bool notified = notified_; + pthread_mutex_unlock(&mutex_); + if (notified) + break; + SleepMilliseconds(10); + } + } + + private: + pthread_mutex_t mutex_; + bool notified_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(Notification); +}; + +// As a C-function, ThreadFuncWithCLinkage cannot be templated itself. +// Consequently, it cannot select a correct instantiation of ThreadWithParam +// in order to call its Run(). Introducing ThreadWithParamBase as a +// non-templated base class for ThreadWithParam allows us to bypass this +// problem. +class ThreadWithParamBase { + public: + virtual ~ThreadWithParamBase() {} + virtual void Run() = 0; +}; + +// pthread_create() accepts a pointer to a function type with the C linkage. +// According to the Standard (7.5/1), function types with different linkages +// are different even if they are otherwise identical. Some compilers (for +// example, SunStudio) treat them as different types. Since class methods +// cannot be defined with C-linkage we need to define a free C-function to +// pass into pthread_create(). +extern "C" inline void* ThreadFuncWithCLinkage(void* thread) { + static_cast(thread)->Run(); + return NULL; +} + +// Helper class for testing Google Test's multi-threading constructs. +// To use it, write: +// +// void ThreadFunc(int param) { /* Do things with param */ } +// Notification thread_can_start; +// ... +// // The thread_can_start parameter is optional; you can supply NULL. +// ThreadWithParam thread(&ThreadFunc, 5, &thread_can_start); +// thread_can_start.Notify(); +// +// These classes are only for testing Google Test's own constructs. Do +// not use them in user tests, either directly or indirectly. +template +class ThreadWithParam : public ThreadWithParamBase { + public: + typedef void (*UserThreadFunc)(T); + + ThreadWithParam( + UserThreadFunc func, T param, Notification* thread_can_start) + : func_(func), + param_(param), + thread_can_start_(thread_can_start), + finished_(false) { + ThreadWithParamBase* const base = this; + // The thread can be created only after all fields except thread_ + // have been initialized. + GTEST_CHECK_POSIX_SUCCESS_( + pthread_create(&thread_, 0, &ThreadFuncWithCLinkage, base)); + } + ~ThreadWithParam() { Join(); } + + void Join() { + if (!finished_) { + GTEST_CHECK_POSIX_SUCCESS_(pthread_join(thread_, 0)); + finished_ = true; + } + } + + virtual void Run() { + if (thread_can_start_ != NULL) + thread_can_start_->WaitForNotification(); + func_(param_); + } + + private: + const UserThreadFunc func_; // User-supplied thread function. + const T param_; // User-supplied parameter to the thread function. + // When non-NULL, used to block execution until the controller thread + // notifies. + Notification* const thread_can_start_; + bool finished_; // true iff we know that the thread function has finished. + pthread_t thread_; // The native thread object. + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadWithParam); +}; + +// MutexBase and Mutex implement mutex on pthreads-based platforms. They +// are used in conjunction with class MutexLock: +// +// Mutex mutex; +// ... +// MutexLock lock(&mutex); // Acquires the mutex and releases it at the end +// // of the current scope. +// +// MutexBase implements behavior for both statically and dynamically +// allocated mutexes. Do not use MutexBase directly. Instead, write +// the following to define a static mutex: +// +// GTEST_DEFINE_STATIC_MUTEX_(g_some_mutex); +// +// You can forward declare a static mutex like this: +// +// GTEST_DECLARE_STATIC_MUTEX_(g_some_mutex); +// +// To create a dynamic mutex, just define an object of type Mutex. +class MutexBase { + public: + // Acquires this mutex. + void Lock() { + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&mutex_)); + owner_ = pthread_self(); + has_owner_ = true; + } + + // Releases this mutex. + void Unlock() { + // Since the lock is being released the owner_ field should no longer be + // considered valid. We don't protect writing to has_owner_ here, as it's + // the caller's responsibility to ensure that the current thread holds the + // mutex when this is called. + has_owner_ = false; + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_unlock(&mutex_)); + } + + // Does nothing if the current thread holds the mutex. Otherwise, crashes + // with high probability. + void AssertHeld() const { + GTEST_CHECK_(has_owner_ && pthread_equal(owner_, pthread_self())) + << "The current thread is not holding the mutex @" << this; + } + + // A static mutex may be used before main() is entered. It may even + // be used before the dynamic initialization stage. Therefore we + // must be able to initialize a static mutex object at link time. + // This means MutexBase has to be a POD and its member variables + // have to be public. + public: + pthread_mutex_t mutex_; // The underlying pthread mutex. + // has_owner_ indicates whether the owner_ field below contains a valid thread + // ID and is therefore safe to inspect (e.g., to use in pthread_equal()). All + // accesses to the owner_ field should be protected by a check of this field. + // An alternative might be to memset() owner_ to all zeros, but there's no + // guarantee that a zero'd pthread_t is necessarily invalid or even different + // from pthread_self(). + bool has_owner_; + pthread_t owner_; // The thread holding the mutex. +}; + +// Forward-declares a static mutex. +# define GTEST_DECLARE_STATIC_MUTEX_(mutex) \ + extern ::testing::internal::MutexBase mutex + +// Defines and statically (i.e. at link time) initializes a static mutex. +// The initialization list here does not explicitly initialize each field, +// instead relying on default initialization for the unspecified fields. In +// particular, the owner_ field (a pthread_t) is not explicitly initialized. +// This allows initialization to work whether pthread_t is a scalar or struct. +// The flag -Wmissing-field-initializers must not be specified for this to work. +# define GTEST_DEFINE_STATIC_MUTEX_(mutex) \ + ::testing::internal::MutexBase mutex = { PTHREAD_MUTEX_INITIALIZER, false } + +// The Mutex class can only be used for mutexes created at runtime. It +// shares its API with MutexBase otherwise. +class Mutex : public MutexBase { + public: + Mutex() { + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, NULL)); + has_owner_ = false; + } + ~Mutex() { + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_destroy(&mutex_)); + } + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(Mutex); +}; + +// We cannot name this class MutexLock as the ctor declaration would +// conflict with a macro named MutexLock, which is defined on some +// platforms. Hence the typedef trick below. +class GTestMutexLock { + public: + explicit GTestMutexLock(MutexBase* mutex) + : mutex_(mutex) { mutex_->Lock(); } + + ~GTestMutexLock() { mutex_->Unlock(); } + + private: + MutexBase* const mutex_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestMutexLock); +}; + +typedef GTestMutexLock MutexLock; + +// Helpers for ThreadLocal. + +// pthread_key_create() requires DeleteThreadLocalValue() to have +// C-linkage. Therefore it cannot be templatized to access +// ThreadLocal. Hence the need for class +// ThreadLocalValueHolderBase. +class ThreadLocalValueHolderBase { + public: + virtual ~ThreadLocalValueHolderBase() {} +}; + +// Called by pthread to delete thread-local data stored by +// pthread_setspecific(). +extern "C" inline void DeleteThreadLocalValue(void* value_holder) { + delete static_cast(value_holder); +} + +// Implements thread-local storage on pthreads-based systems. +// +// // Thread 1 +// ThreadLocal tl(100); // 100 is the default value for each thread. +// +// // Thread 2 +// tl.set(150); // Changes the value for thread 2 only. +// EXPECT_EQ(150, tl.get()); +// +// // Thread 1 +// EXPECT_EQ(100, tl.get()); // In thread 1, tl has the original value. +// tl.set(200); +// EXPECT_EQ(200, tl.get()); +// +// The template type argument T must have a public copy constructor. +// In addition, the default ThreadLocal constructor requires T to have +// a public default constructor. +// +// An object managed for a thread by a ThreadLocal instance is deleted +// when the thread exits. Or, if the ThreadLocal instance dies in +// that thread, when the ThreadLocal dies. It's the user's +// responsibility to ensure that all other threads using a ThreadLocal +// have exited when it dies, or the per-thread objects for those +// threads will not be deleted. +// +// Google Test only uses global ThreadLocal objects. That means they +// will die after main() has returned. Therefore, no per-thread +// object managed by Google Test will be leaked as long as all threads +// using Google Test have exited when main() returns. +template +class ThreadLocal { + public: + ThreadLocal() : key_(CreateKey()), + default_() {} + explicit ThreadLocal(const T& value) : key_(CreateKey()), + default_(value) {} + + ~ThreadLocal() { + // Destroys the managed object for the current thread, if any. + DeleteThreadLocalValue(pthread_getspecific(key_)); + + // Releases resources associated with the key. This will *not* + // delete managed objects for other threads. + GTEST_CHECK_POSIX_SUCCESS_(pthread_key_delete(key_)); + } + + T* pointer() { return GetOrCreateValue(); } + const T* pointer() const { return GetOrCreateValue(); } + const T& get() const { return *pointer(); } + void set(const T& value) { *pointer() = value; } + + private: + // Holds a value of type T. + class ValueHolder : public ThreadLocalValueHolderBase { + public: + explicit ValueHolder(const T& value) : value_(value) {} + + T* pointer() { return &value_; } + + private: + T value_; + GTEST_DISALLOW_COPY_AND_ASSIGN_(ValueHolder); + }; + + static pthread_key_t CreateKey() { + pthread_key_t key; + // When a thread exits, DeleteThreadLocalValue() will be called on + // the object managed for that thread. + GTEST_CHECK_POSIX_SUCCESS_( + pthread_key_create(&key, &DeleteThreadLocalValue)); + return key; + } + + T* GetOrCreateValue() const { + ThreadLocalValueHolderBase* const holder = + static_cast(pthread_getspecific(key_)); + if (holder != NULL) { + return CheckedDowncastToActualType(holder)->pointer(); + } + + ValueHolder* const new_holder = new ValueHolder(default_); + ThreadLocalValueHolderBase* const holder_base = new_holder; + GTEST_CHECK_POSIX_SUCCESS_(pthread_setspecific(key_, holder_base)); + return new_holder->pointer(); + } + + // A key pthreads uses for looking up per-thread values. + const pthread_key_t key_; + const T default_; // The default value for each thread. + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocal); +}; + +# define GTEST_IS_THREADSAFE 1 + +#else // GTEST_HAS_PTHREAD + +// A dummy implementation of synchronization primitives (mutex, lock, +// and thread-local variable). Necessary for compiling Google Test where +// mutex is not supported - using Google Test in multiple threads is not +// supported on such platforms. + +class Mutex { + public: + Mutex() {} + void Lock() {} + void Unlock() {} + void AssertHeld() const {} +}; + +# define GTEST_DECLARE_STATIC_MUTEX_(mutex) \ + extern ::testing::internal::Mutex mutex + +# define GTEST_DEFINE_STATIC_MUTEX_(mutex) ::testing::internal::Mutex mutex + +class GTestMutexLock { + public: + explicit GTestMutexLock(Mutex*) {} // NOLINT +}; + +typedef GTestMutexLock MutexLock; + +template +class ThreadLocal { + public: + ThreadLocal() : value_() {} + explicit ThreadLocal(const T& value) : value_(value) {} + T* pointer() { return &value_; } + const T* pointer() const { return &value_; } + const T& get() const { return value_; } + void set(const T& value) { value_ = value; } + private: + T value_; +}; + +// The above synchronization primitives have dummy implementations. +// Therefore Google Test is not thread-safe. +# define GTEST_IS_THREADSAFE 0 + +#endif // GTEST_HAS_PTHREAD + +// Returns the number of threads running in the process, or 0 to indicate that +// we cannot detect it. +GTEST_API_ size_t GetThreadCount(); + +// Passing non-POD classes through ellipsis (...) crashes the ARM +// compiler and generates a warning in Sun Studio. The Nokia Symbian +// and the IBM XL C/C++ compiler try to instantiate a copy constructor +// for objects passed through ellipsis (...), failing for uncopyable +// objects. We define this to ensure that only POD is passed through +// ellipsis on these systems. +#if defined(__SYMBIAN32__) || defined(__IBMCPP__) || defined(__SUNPRO_CC) +// We lose support for NULL detection where the compiler doesn't like +// passing non-POD classes through ellipsis (...). +# define GTEST_ELLIPSIS_NEEDS_POD_ 1 +#else +# define GTEST_CAN_COMPARE_NULL 1 +#endif + +// The Nokia Symbian and IBM XL C/C++ compilers cannot decide between +// const T& and const T* in a function template. These compilers +// _can_ decide between class template specializations for T and T*, +// so a tr1::type_traits-like is_pointer works. +#if defined(__SYMBIAN32__) || defined(__IBMCPP__) +# define GTEST_NEEDS_IS_POINTER_ 1 +#endif + +template +struct bool_constant { + typedef bool_constant type; + static const bool value = bool_value; +}; +template const bool bool_constant::value; + +typedef bool_constant false_type; +typedef bool_constant true_type; + +template +struct is_pointer : public false_type {}; + +template +struct is_pointer : public true_type {}; + +template +struct IteratorTraits { + typedef typename Iterator::value_type value_type; +}; + +template +struct IteratorTraits { + typedef T value_type; +}; + +template +struct IteratorTraits { + typedef T value_type; +}; + +#if GTEST_OS_WINDOWS +# define GTEST_PATH_SEP_ "\\" +# define GTEST_HAS_ALT_PATH_SEP_ 1 +// The biggest signed integer type the compiler supports. +typedef __int64 BiggestInt; +#else +# define GTEST_PATH_SEP_ "/" +# define GTEST_HAS_ALT_PATH_SEP_ 0 +typedef long long BiggestInt; // NOLINT +#endif // GTEST_OS_WINDOWS + +// Utilities for char. + +// isspace(int ch) and friends accept an unsigned char or EOF. char +// may be signed, depending on the compiler (or compiler flags). +// Therefore we need to cast a char to unsigned char before calling +// isspace(), etc. + +inline bool IsAlpha(char ch) { + return isalpha(static_cast(ch)) != 0; +} +inline bool IsAlNum(char ch) { + return isalnum(static_cast(ch)) != 0; +} +inline bool IsDigit(char ch) { + return isdigit(static_cast(ch)) != 0; +} +inline bool IsLower(char ch) { + return islower(static_cast(ch)) != 0; +} +inline bool IsSpace(char ch) { + return isspace(static_cast(ch)) != 0; +} +inline bool IsUpper(char ch) { + return isupper(static_cast(ch)) != 0; +} +inline bool IsXDigit(char ch) { + return isxdigit(static_cast(ch)) != 0; +} +inline bool IsXDigit(wchar_t ch) { + const unsigned char low_byte = static_cast(ch); + return ch == low_byte && isxdigit(low_byte) != 0; +} + +inline char ToLower(char ch) { + return static_cast(tolower(static_cast(ch))); +} +inline char ToUpper(char ch) { + return static_cast(toupper(static_cast(ch))); +} + +// The testing::internal::posix namespace holds wrappers for common +// POSIX functions. These wrappers hide the differences between +// Windows/MSVC and POSIX systems. Since some compilers define these +// standard functions as macros, the wrapper cannot have the same name +// as the wrapped function. + +namespace posix { + +// Functions with a different name on Windows. + +#if GTEST_OS_WINDOWS + +typedef struct _stat StatStruct; + +# ifdef __BORLANDC__ +inline int IsATTY(int fd) { return isatty(fd); } +inline int StrCaseCmp(const char* s1, const char* s2) { + return stricmp(s1, s2); +} +inline char* StrDup(const char* src) { return strdup(src); } +# else // !__BORLANDC__ +# if GTEST_OS_WINDOWS_MOBILE +inline int IsATTY(int /* fd */) { return 0; } +# else +inline int IsATTY(int fd) { return _isatty(fd); } +# endif // GTEST_OS_WINDOWS_MOBILE +inline int StrCaseCmp(const char* s1, const char* s2) { + return _stricmp(s1, s2); +} +inline char* StrDup(const char* src) { return _strdup(src); } +# endif // __BORLANDC__ + +# if GTEST_OS_WINDOWS_MOBILE +inline int FileNo(FILE* file) { return reinterpret_cast(_fileno(file)); } +// Stat(), RmDir(), and IsDir() are not needed on Windows CE at this +// time and thus not defined there. +# else +inline int FileNo(FILE* file) { return _fileno(file); } +inline int Stat(const char* path, StatStruct* buf) { return _stat(path, buf); } +inline int RmDir(const char* dir) { return _rmdir(dir); } +inline bool IsDir(const StatStruct& st) { + return (_S_IFDIR & st.st_mode) != 0; +} +# endif // GTEST_OS_WINDOWS_MOBILE + +#else + +typedef struct stat StatStruct; + +inline int FileNo(FILE* file) { return fileno(file); } +inline int IsATTY(int fd) { return isatty(fd); } +inline int Stat(const char* path, StatStruct* buf) { return stat(path, buf); } +inline int StrCaseCmp(const char* s1, const char* s2) { + return strcasecmp(s1, s2); +} +inline char* StrDup(const char* src) { return strdup(src); } +inline int RmDir(const char* dir) { return rmdir(dir); } +inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); } + +#endif // GTEST_OS_WINDOWS + +// Functions deprecated by MSVC 8.0. + +#ifdef _MSC_VER +// Temporarily disable warning 4996 (deprecated function). +# pragma warning(push) +# pragma warning(disable:4996) +#endif + +inline const char* StrNCpy(char* dest, const char* src, size_t n) { + return strncpy(dest, src, n); +} + +// ChDir(), FReopen(), FDOpen(), Read(), Write(), Close(), and +// StrError() aren't needed on Windows CE at this time and thus not +// defined there. + +#if !GTEST_OS_WINDOWS_MOBILE +inline int ChDir(const char* dir) { return chdir(dir); } +#endif +inline FILE* FOpen(const char* path, const char* mode) { + return fopen(path, mode); +} +#if !GTEST_OS_WINDOWS_MOBILE +inline FILE *FReopen(const char* path, const char* mode, FILE* stream) { + return freopen(path, mode, stream); +} +inline FILE* FDOpen(int fd, const char* mode) { return fdopen(fd, mode); } +#endif +inline int FClose(FILE* fp) { return fclose(fp); } +#if !GTEST_OS_WINDOWS_MOBILE +inline int Read(int fd, void* buf, unsigned int count) { + return static_cast(read(fd, buf, count)); +} +inline int Write(int fd, const void* buf, unsigned int count) { + return static_cast(write(fd, buf, count)); +} +inline int Close(int fd) { return close(fd); } +inline const char* StrError(int errnum) { return strerror(errnum); } +#endif +inline const char* GetEnv(const char* name) { +#if GTEST_OS_WINDOWS_MOBILE + // We are on Windows CE, which has no environment variables. + return NULL; +#elif defined(__BORLANDC__) || defined(__SunOS_5_8) || defined(__SunOS_5_9) + // Environment variables which we programmatically clear will be set to the + // empty string rather than unset (NULL). Handle that case. + const char* const env = getenv(name); + return (env != NULL && env[0] != '\0') ? env : NULL; +#else + return getenv(name); +#endif +} + +#ifdef _MSC_VER +# pragma warning(pop) // Restores the warning state. +#endif + +#if GTEST_OS_WINDOWS_MOBILE +// Windows CE has no C library. The abort() function is used in +// several places in Google Test. This implementation provides a reasonable +// imitation of standard behaviour. +void Abort(); +#else +inline void Abort() { abort(); } +#endif // GTEST_OS_WINDOWS_MOBILE + +} // namespace posix + +// MSVC "deprecates" snprintf and issues warnings wherever it is used. In +// order to avoid these warnings, we need to use _snprintf or _snprintf_s on +// MSVC-based platforms. We map the GTEST_SNPRINTF_ macro to the appropriate +// function in order to achieve that. We use macro definition here because +// snprintf is a variadic function. +#if _MSC_VER >= 1400 && !GTEST_OS_WINDOWS_MOBILE +// MSVC 2005 and above support variadic macros. +# define GTEST_SNPRINTF_(buffer, size, format, ...) \ + _snprintf_s(buffer, size, size, format, __VA_ARGS__) +#elif defined(_MSC_VER) +// Windows CE does not define _snprintf_s and MSVC prior to 2005 doesn't +// complain about _snprintf. +# define GTEST_SNPRINTF_ _snprintf +#else +# define GTEST_SNPRINTF_ snprintf +#endif + +// The maximum number a BiggestInt can represent. This definition +// works no matter BiggestInt is represented in one's complement or +// two's complement. +// +// We cannot rely on numeric_limits in STL, as __int64 and long long +// are not part of standard C++ and numeric_limits doesn't need to be +// defined for them. +const BiggestInt kMaxBiggestInt = + ~(static_cast(1) << (8*sizeof(BiggestInt) - 1)); + +// This template class serves as a compile-time function from size to +// type. It maps a size in bytes to a primitive type with that +// size. e.g. +// +// TypeWithSize<4>::UInt +// +// is typedef-ed to be unsigned int (unsigned integer made up of 4 +// bytes). +// +// Such functionality should belong to STL, but I cannot find it +// there. +// +// Google Test uses this class in the implementation of floating-point +// comparison. +// +// For now it only handles UInt (unsigned int) as that's all Google Test +// needs. Other types can be easily added in the future if need +// arises. +template +class TypeWithSize { + public: + // This prevents the user from using TypeWithSize with incorrect + // values of N. + typedef void UInt; +}; + +// The specialization for size 4. +template <> +class TypeWithSize<4> { + public: + // unsigned int has size 4 in both gcc and MSVC. + // + // As base/basictypes.h doesn't compile on Windows, we cannot use + // uint32, uint64, and etc here. + typedef int Int; + typedef unsigned int UInt; +}; + +// The specialization for size 8. +template <> +class TypeWithSize<8> { + public: +#if GTEST_OS_WINDOWS + typedef __int64 Int; + typedef unsigned __int64 UInt; +#else + typedef long long Int; // NOLINT + typedef unsigned long long UInt; // NOLINT +#endif // GTEST_OS_WINDOWS +}; + +// Integer types of known sizes. +typedef TypeWithSize<4>::Int Int32; +typedef TypeWithSize<4>::UInt UInt32; +typedef TypeWithSize<8>::Int Int64; +typedef TypeWithSize<8>::UInt UInt64; +typedef TypeWithSize<8>::Int TimeInMillis; // Represents time in milliseconds. + +// Utilities for command line flags and environment variables. + +// Macro for referencing flags. +#define GTEST_FLAG(name) FLAGS_gtest_##name + +// Macros for declaring flags. +#define GTEST_DECLARE_bool_(name) GTEST_API_ extern bool GTEST_FLAG(name) +#define GTEST_DECLARE_int32_(name) \ + GTEST_API_ extern ::testing::internal::Int32 GTEST_FLAG(name) +#define GTEST_DECLARE_string_(name) \ + GTEST_API_ extern ::std::string GTEST_FLAG(name) + +// Macros for defining flags. +#define GTEST_DEFINE_bool_(name, default_val, doc) \ + GTEST_API_ bool GTEST_FLAG(name) = (default_val) +#define GTEST_DEFINE_int32_(name, default_val, doc) \ + GTEST_API_ ::testing::internal::Int32 GTEST_FLAG(name) = (default_val) +#define GTEST_DEFINE_string_(name, default_val, doc) \ + GTEST_API_ ::std::string GTEST_FLAG(name) = (default_val) + +// Thread annotations +#define GTEST_EXCLUSIVE_LOCK_REQUIRED_(locks) +#define GTEST_LOCK_EXCLUDED_(locks) + +// Parses 'str' for a 32-bit signed integer. If successful, writes the result +// to *value and returns true; otherwise leaves *value unchanged and returns +// false. +// TODO(chandlerc): Find a better way to refactor flag and environment parsing +// out of both gtest-port.cc and gtest.cc to avoid exporting this utility +// function. +bool ParseInt32(const Message& src_text, const char* str, Int32* value); + +// Parses a bool/Int32/string from the environment variable +// corresponding to the given Google Test flag. +bool BoolFromGTestEnv(const char* flag, bool default_val); +GTEST_API_ Int32 Int32FromGTestEnv(const char* flag, Int32 default_val); +const char* StringFromGTestEnv(const char* flag, const char* default_val); + +} // namespace internal +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ + +#if GTEST_OS_LINUX +# include +# include +# include +# include +#endif // GTEST_OS_LINUX + +#if GTEST_HAS_EXCEPTIONS +# include +#endif + +#include +#include +#include +#include +#include +#include + +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) +// +// The Google C++ Testing Framework (Google Test) +// +// This header file defines the Message class. +// +// IMPORTANT NOTE: Due to limitation of the C++ language, we have to +// leave some internal implementation details in this header file. +// They are clearly marked by comments like this: +// +// // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +// +// Such code is NOT meant to be used by a user directly, and is subject +// to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user +// program! + +#ifndef GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ +#define GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ + +#include + + +// Ensures that there is at least one operator<< in the global namespace. +// See Message& operator<<(...) below for why. +void operator<<(const testing::internal::Secret&, int); + +namespace testing { + +// The Message class works like an ostream repeater. +// +// Typical usage: +// +// 1. You stream a bunch of values to a Message object. +// It will remember the text in a stringstream. +// 2. Then you stream the Message object to an ostream. +// This causes the text in the Message to be streamed +// to the ostream. +// +// For example; +// +// testing::Message foo; +// foo << 1 << " != " << 2; +// std::cout << foo; +// +// will print "1 != 2". +// +// Message is not intended to be inherited from. In particular, its +// destructor is not virtual. +// +// Note that stringstream behaves differently in gcc and in MSVC. You +// can stream a NULL char pointer to it in the former, but not in the +// latter (it causes an access violation if you do). The Message +// class hides this difference by treating a NULL char pointer as +// "(null)". +class GTEST_API_ Message { + private: + // The type of basic IO manipulators (endl, ends, and flush) for + // narrow streams. + typedef std::ostream& (*BasicNarrowIoManip)(std::ostream&); + + public: + // Constructs an empty Message. + Message(); + + // Copy constructor. + Message(const Message& msg) : ss_(new ::std::stringstream) { // NOLINT + *ss_ << msg.GetString(); + } + + // Constructs a Message from a C-string. + explicit Message(const char* str) : ss_(new ::std::stringstream) { + *ss_ << str; + } + +#if GTEST_OS_SYMBIAN + // Streams a value (either a pointer or not) to this object. + template + inline Message& operator <<(const T& value) { + StreamHelper(typename internal::is_pointer::type(), value); + return *this; + } +#else + // Streams a non-pointer value to this object. + template + inline Message& operator <<(const T& val) { + // Some libraries overload << for STL containers. These + // overloads are defined in the global namespace instead of ::std. + // + // C++'s symbol lookup rule (i.e. Koenig lookup) says that these + // overloads are visible in either the std namespace or the global + // namespace, but not other namespaces, including the testing + // namespace which Google Test's Message class is in. + // + // To allow STL containers (and other types that has a << operator + // defined in the global namespace) to be used in Google Test + // assertions, testing::Message must access the custom << operator + // from the global namespace. With this using declaration, + // overloads of << defined in the global namespace and those + // visible via Koenig lookup are both exposed in this function. + using ::operator <<; + *ss_ << val; + return *this; + } + + // Streams a pointer value to this object. + // + // This function is an overload of the previous one. When you + // stream a pointer to a Message, this definition will be used as it + // is more specialized. (The C++ Standard, section + // [temp.func.order].) If you stream a non-pointer, then the + // previous definition will be used. + // + // The reason for this overload is that streaming a NULL pointer to + // ostream is undefined behavior. Depending on the compiler, you + // may get "0", "(nil)", "(null)", or an access violation. To + // ensure consistent result across compilers, we always treat NULL + // as "(null)". + template + inline Message& operator <<(T* const& pointer) { // NOLINT + if (pointer == NULL) { + *ss_ << "(null)"; + } else { + *ss_ << pointer; + } + return *this; + } +#endif // GTEST_OS_SYMBIAN + + // Since the basic IO manipulators are overloaded for both narrow + // and wide streams, we have to provide this specialized definition + // of operator <<, even though its body is the same as the + // templatized version above. Without this definition, streaming + // endl or other basic IO manipulators to Message will confuse the + // compiler. + Message& operator <<(BasicNarrowIoManip val) { + *ss_ << val; + return *this; + } + + // Instead of 1/0, we want to see true/false for bool values. + Message& operator <<(bool b) { + return *this << (b ? "true" : "false"); + } + + // These two overloads allow streaming a wide C string to a Message + // using the UTF-8 encoding. + Message& operator <<(const wchar_t* wide_c_str); + Message& operator <<(wchar_t* wide_c_str); + +#if GTEST_HAS_STD_WSTRING + // Converts the given wide string to a narrow string using the UTF-8 + // encoding, and streams the result to this Message object. + Message& operator <<(const ::std::wstring& wstr); +#endif // GTEST_HAS_STD_WSTRING + +#if GTEST_HAS_GLOBAL_WSTRING + // Converts the given wide string to a narrow string using the UTF-8 + // encoding, and streams the result to this Message object. + Message& operator <<(const ::wstring& wstr); +#endif // GTEST_HAS_GLOBAL_WSTRING + + // Gets the text streamed to this object so far as an std::string. + // Each '\0' character in the buffer is replaced with "\\0". + // + // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. + std::string GetString() const; + + private: + +#if GTEST_OS_SYMBIAN + // These are needed as the Nokia Symbian Compiler cannot decide between + // const T& and const T* in a function template. The Nokia compiler _can_ + // decide between class template specializations for T and T*, so a + // tr1::type_traits-like is_pointer works, and we can overload on that. + template + inline void StreamHelper(internal::true_type /*is_pointer*/, T* pointer) { + if (pointer == NULL) { + *ss_ << "(null)"; + } else { + *ss_ << pointer; + } + } + template + inline void StreamHelper(internal::false_type /*is_pointer*/, + const T& value) { + // See the comments in Message& operator <<(const T&) above for why + // we need this using statement. + using ::operator <<; + *ss_ << value; + } +#endif // GTEST_OS_SYMBIAN + + // We'll hold the text streamed to this object here. + const internal::scoped_ptr< ::std::stringstream> ss_; + + // We declare (but don't implement) this to prevent the compiler + // from implementing the assignment operator. + void operator=(const Message&); +}; + +// Streams a Message to an ostream. +inline std::ostream& operator <<(std::ostream& os, const Message& sb) { + return os << sb.GetString(); +} + +namespace internal { + +// Converts a streamable value to an std::string. A NULL pointer is +// converted to "(null)". When the input value is a ::string, +// ::std::string, ::wstring, or ::std::wstring object, each NUL +// character in it is replaced with "\\0". +template +std::string StreamableToString(const T& streamable) { + return (Message() << streamable).GetString(); +} + +} // namespace internal +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee) +// +// The Google C++ Testing Framework (Google Test) +// +// This header file declares the String class and functions used internally by +// Google Test. They are subject to change without notice. They should not used +// by code external to Google Test. +// +// This header file is #included by . +// It should not be #included by other files. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ + +#ifdef __BORLANDC__ +// string.h is not guaranteed to provide strcpy on C++ Builder. +# include +#endif + +#include +#include + + +namespace testing { +namespace internal { + +// String - an abstract class holding static string utilities. +class GTEST_API_ String { + public: + // Static utility methods + + // Clones a 0-terminated C string, allocating memory using new. The + // caller is responsible for deleting the return value using + // delete[]. Returns the cloned string, or NULL if the input is + // NULL. + // + // This is different from strdup() in string.h, which allocates + // memory using malloc(). + static const char* CloneCString(const char* c_str); + +#if GTEST_OS_WINDOWS_MOBILE + // Windows CE does not have the 'ANSI' versions of Win32 APIs. To be + // able to pass strings to Win32 APIs on CE we need to convert them + // to 'Unicode', UTF-16. + + // Creates a UTF-16 wide string from the given ANSI string, allocating + // memory using new. The caller is responsible for deleting the return + // value using delete[]. Returns the wide string, or NULL if the + // input is NULL. + // + // The wide string is created using the ANSI codepage (CP_ACP) to + // match the behaviour of the ANSI versions of Win32 calls and the + // C runtime. + static LPCWSTR AnsiToUtf16(const char* c_str); + + // Creates an ANSI string from the given wide string, allocating + // memory using new. The caller is responsible for deleting the return + // value using delete[]. Returns the ANSI string, or NULL if the + // input is NULL. + // + // The returned string is created using the ANSI codepage (CP_ACP) to + // match the behaviour of the ANSI versions of Win32 calls and the + // C runtime. + static const char* Utf16ToAnsi(LPCWSTR utf16_str); +#endif + + // Compares two C strings. Returns true iff they have the same content. + // + // Unlike strcmp(), this function can handle NULL argument(s). A + // NULL C string is considered different to any non-NULL C string, + // including the empty string. + static bool CStringEquals(const char* lhs, const char* rhs); + + // Converts a wide C string to a String using the UTF-8 encoding. + // NULL will be converted to "(null)". If an error occurred during + // the conversion, "(failed to convert from wide string)" is + // returned. + static std::string ShowWideCString(const wchar_t* wide_c_str); + + // Compares two wide C strings. Returns true iff they have the same + // content. + // + // Unlike wcscmp(), this function can handle NULL argument(s). A + // NULL C string is considered different to any non-NULL C string, + // including the empty string. + static bool WideCStringEquals(const wchar_t* lhs, const wchar_t* rhs); + + // Compares two C strings, ignoring case. Returns true iff they + // have the same content. + // + // Unlike strcasecmp(), this function can handle NULL argument(s). + // A NULL C string is considered different to any non-NULL C string, + // including the empty string. + static bool CaseInsensitiveCStringEquals(const char* lhs, + const char* rhs); + + // Compares two wide C strings, ignoring case. Returns true iff they + // have the same content. + // + // Unlike wcscasecmp(), this function can handle NULL argument(s). + // A NULL C string is considered different to any non-NULL wide C string, + // including the empty string. + // NB: The implementations on different platforms slightly differ. + // On windows, this method uses _wcsicmp which compares according to LC_CTYPE + // environment variable. On GNU platform this method uses wcscasecmp + // which compares according to LC_CTYPE category of the current locale. + // On MacOS X, it uses towlower, which also uses LC_CTYPE category of the + // current locale. + static bool CaseInsensitiveWideCStringEquals(const wchar_t* lhs, + const wchar_t* rhs); + + // Returns true iff the given string ends with the given suffix, ignoring + // case. Any string is considered to end with an empty suffix. + static bool EndsWithCaseInsensitive( + const std::string& str, const std::string& suffix); + + // Formats an int value as "%02d". + static std::string FormatIntWidth2(int value); // "%02d" for width == 2 + + // Formats an int value as "%X". + static std::string FormatHexInt(int value); + + // Formats a byte as "%02X". + static std::string FormatByte(unsigned char value); + + private: + String(); // Not meant to be instantiated. +}; // class String + +// Gets the content of the stringstream's buffer as an std::string. Each '\0' +// character in the buffer is replaced with "\\0". +GTEST_API_ std::string StringStreamToString(::std::stringstream* stream); + +} // namespace internal +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: keith.ray@gmail.com (Keith Ray) +// +// Google Test filepath utilities +// +// This header file declares classes and functions used internally by +// Google Test. They are subject to change without notice. +// +// This file is #included in . +// Do not include this header file separately! + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ + + +namespace testing { +namespace internal { + +// FilePath - a class for file and directory pathname manipulation which +// handles platform-specific conventions (like the pathname separator). +// Used for helper functions for naming files in a directory for xml output. +// Except for Set methods, all methods are const or static, which provides an +// "immutable value object" -- useful for peace of mind. +// A FilePath with a value ending in a path separator ("like/this/") represents +// a directory, otherwise it is assumed to represent a file. In either case, +// it may or may not represent an actual file or directory in the file system. +// Names are NOT checked for syntax correctness -- no checking for illegal +// characters, malformed paths, etc. + +class GTEST_API_ FilePath { + public: + FilePath() : pathname_("") { } + FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) { } + + explicit FilePath(const std::string& pathname) : pathname_(pathname) { + Normalize(); + } + + FilePath& operator=(const FilePath& rhs) { + Set(rhs); + return *this; + } + + void Set(const FilePath& rhs) { + pathname_ = rhs.pathname_; + } + + const std::string& string() const { return pathname_; } + const char* c_str() const { return pathname_.c_str(); } + + // Returns the current working directory, or "" if unsuccessful. + static FilePath GetCurrentDir(); + + // Given directory = "dir", base_name = "test", number = 0, + // extension = "xml", returns "dir/test.xml". If number is greater + // than zero (e.g., 12), returns "dir/test_12.xml". + // On Windows platform, uses \ as the separator rather than /. + static FilePath MakeFileName(const FilePath& directory, + const FilePath& base_name, + int number, + const char* extension); + + // Given directory = "dir", relative_path = "test.xml", + // returns "dir/test.xml". + // On Windows, uses \ as the separator rather than /. + static FilePath ConcatPaths(const FilePath& directory, + const FilePath& relative_path); + + // Returns a pathname for a file that does not currently exist. The pathname + // will be directory/base_name.extension or + // directory/base_name_.extension if directory/base_name.extension + // already exists. The number will be incremented until a pathname is found + // that does not already exist. + // Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'. + // There could be a race condition if two or more processes are calling this + // function at the same time -- they could both pick the same filename. + static FilePath GenerateUniqueFileName(const FilePath& directory, + const FilePath& base_name, + const char* extension); + + // Returns true iff the path is "". + bool IsEmpty() const { return pathname_.empty(); } + + // If input name has a trailing separator character, removes it and returns + // the name, otherwise return the name string unmodified. + // On Windows platform, uses \ as the separator, other platforms use /. + FilePath RemoveTrailingPathSeparator() const; + + // Returns a copy of the FilePath with the directory part removed. + // Example: FilePath("path/to/file").RemoveDirectoryName() returns + // FilePath("file"). If there is no directory part ("just_a_file"), it returns + // the FilePath unmodified. If there is no file part ("just_a_dir/") it + // returns an empty FilePath (""). + // On Windows platform, '\' is the path separator, otherwise it is '/'. + FilePath RemoveDirectoryName() const; + + // RemoveFileName returns the directory path with the filename removed. + // Example: FilePath("path/to/file").RemoveFileName() returns "path/to/". + // If the FilePath is "a_file" or "/a_file", RemoveFileName returns + // FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does + // not have a file, like "just/a/dir/", it returns the FilePath unmodified. + // On Windows platform, '\' is the path separator, otherwise it is '/'. + FilePath RemoveFileName() const; + + // Returns a copy of the FilePath with the case-insensitive extension removed. + // Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns + // FilePath("dir/file"). If a case-insensitive extension is not + // found, returns a copy of the original FilePath. + FilePath RemoveExtension(const char* extension) const; + + // Creates directories so that path exists. Returns true if successful or if + // the directories already exist; returns false if unable to create + // directories for any reason. Will also return false if the FilePath does + // not represent a directory (that is, it doesn't end with a path separator). + bool CreateDirectoriesRecursively() const; + + // Create the directory so that path exists. Returns true if successful or + // if the directory already exists; returns false if unable to create the + // directory for any reason, including if the parent directory does not + // exist. Not named "CreateDirectory" because that's a macro on Windows. + bool CreateFolder() const; + + // Returns true if FilePath describes something in the file-system, + // either a file, directory, or whatever, and that something exists. + bool FileOrDirectoryExists() const; + + // Returns true if pathname describes a directory in the file-system + // that exists. + bool DirectoryExists() const; + + // Returns true if FilePath ends with a path separator, which indicates that + // it is intended to represent a directory. Returns false otherwise. + // This does NOT check that a directory (or file) actually exists. + bool IsDirectory() const; + + // Returns true if pathname describes a root directory. (Windows has one + // root directory per disk drive.) + bool IsRootDirectory() const; + + // Returns true if pathname describes an absolute path. + bool IsAbsolutePath() const; + + private: + // Replaces multiple consecutive separators with a single separator. + // For example, "bar///foo" becomes "bar/foo". Does not eliminate other + // redundancies that might be in a pathname involving "." or "..". + // + // A pathname with multiple consecutive separators may occur either through + // user error or as a result of some scripts or APIs that generate a pathname + // with a trailing separator. On other platforms the same API or script + // may NOT generate a pathname with a trailing "/". Then elsewhere that + // pathname may have another "/" and pathname components added to it, + // without checking for the separator already being there. + // The script language and operating system may allow paths like "foo//bar" + // but some of the functions in FilePath will not handle that correctly. In + // particular, RemoveTrailingPathSeparator() only removes one separator, and + // it is called in CreateDirectoriesRecursively() assuming that it will change + // a pathname from directory syntax (trailing separator) to filename syntax. + // + // On Windows this method also replaces the alternate path separator '/' with + // the primary path separator '\\', so that for example "bar\\/\\foo" becomes + // "bar\\foo". + + void Normalize(); + + // Returns a pointer to the last occurence of a valid path separator in + // the FilePath. On Windows, for example, both '/' and '\' are valid path + // separators. Returns NULL if no path separator was found. + const char* FindLastPathSeparator() const; + + std::string pathname_; +}; // class FilePath + +} // namespace internal +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ +// This file was GENERATED by command: +// pump.py gtest-type-util.h.pump +// DO NOT EDIT BY HAND!!! + +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) + +// Type utilities needed for implementing typed and type-parameterized +// tests. This file is generated by a SCRIPT. DO NOT EDIT BY HAND! +// +// Currently we support at most 50 types in a list, and at most 50 +// type-parameterized tests in one type-parameterized test case. +// Please contact googletestframework@googlegroups.com if you need +// more. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ + + +// #ifdef __GNUC__ is too general here. It is possible to use gcc without using +// libstdc++ (which is where cxxabi.h comes from). +# if GTEST_HAS_CXXABI_H_ +# include +# elif defined(__HP_aCC) +# include +# endif // GTEST_HASH_CXXABI_H_ + +namespace testing { +namespace internal { + +// GetTypeName() returns a human-readable name of type T. +// NB: This function is also used in Google Mock, so don't move it inside of +// the typed-test-only section below. +template +std::string GetTypeName() { +# if GTEST_HAS_RTTI + + const char* const name = typeid(T).name(); +# if GTEST_HAS_CXXABI_H_ || defined(__HP_aCC) + int status = 0; + // gcc's implementation of typeid(T).name() mangles the type name, + // so we have to demangle it. +# if GTEST_HAS_CXXABI_H_ + using abi::__cxa_demangle; +# endif // GTEST_HAS_CXXABI_H_ + char* const readable_name = __cxa_demangle(name, 0, 0, &status); + const std::string name_str(status == 0 ? readable_name : name); + free(readable_name); + return name_str; +# else + return name; +# endif // GTEST_HAS_CXXABI_H_ || __HP_aCC + +# else + + return ""; + +# endif // GTEST_HAS_RTTI +} + +#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P + +// AssertyTypeEq::type is defined iff T1 and T2 are the same +// type. This can be used as a compile-time assertion to ensure that +// two types are equal. + +template +struct AssertTypeEq; + +template +struct AssertTypeEq { + typedef bool type; +}; + +// A unique type used as the default value for the arguments of class +// template Types. This allows us to simulate variadic templates +// (e.g. Types, Type, and etc), which C++ doesn't +// support directly. +struct None {}; + +// The following family of struct and struct templates are used to +// represent type lists. In particular, TypesN +// represents a type list with N types (T1, T2, ..., and TN) in it. +// Except for Types0, every struct in the family has two member types: +// Head for the first type in the list, and Tail for the rest of the +// list. + +// The empty type list. +struct Types0 {}; + +// Type lists of length 1, 2, 3, and so on. + +template +struct Types1 { + typedef T1 Head; + typedef Types0 Tail; +}; +template +struct Types2 { + typedef T1 Head; + typedef Types1 Tail; +}; + +template +struct Types3 { + typedef T1 Head; + typedef Types2 Tail; +}; + +template +struct Types4 { + typedef T1 Head; + typedef Types3 Tail; +}; + +template +struct Types5 { + typedef T1 Head; + typedef Types4 Tail; +}; + +template +struct Types6 { + typedef T1 Head; + typedef Types5 Tail; +}; + +template +struct Types7 { + typedef T1 Head; + typedef Types6 Tail; +}; + +template +struct Types8 { + typedef T1 Head; + typedef Types7 Tail; +}; + +template +struct Types9 { + typedef T1 Head; + typedef Types8 Tail; +}; + +template +struct Types10 { + typedef T1 Head; + typedef Types9 Tail; +}; + +template +struct Types11 { + typedef T1 Head; + typedef Types10 Tail; +}; + +template +struct Types12 { + typedef T1 Head; + typedef Types11 Tail; +}; + +template +struct Types13 { + typedef T1 Head; + typedef Types12 Tail; +}; + +template +struct Types14 { + typedef T1 Head; + typedef Types13 Tail; +}; + +template +struct Types15 { + typedef T1 Head; + typedef Types14 Tail; +}; + +template +struct Types16 { + typedef T1 Head; + typedef Types15 Tail; +}; + +template +struct Types17 { + typedef T1 Head; + typedef Types16 Tail; +}; + +template +struct Types18 { + typedef T1 Head; + typedef Types17 Tail; +}; + +template +struct Types19 { + typedef T1 Head; + typedef Types18 Tail; +}; + +template +struct Types20 { + typedef T1 Head; + typedef Types19 Tail; +}; + +template +struct Types21 { + typedef T1 Head; + typedef Types20 Tail; +}; + +template +struct Types22 { + typedef T1 Head; + typedef Types21 Tail; +}; + +template +struct Types23 { + typedef T1 Head; + typedef Types22 Tail; +}; + +template +struct Types24 { + typedef T1 Head; + typedef Types23 Tail; +}; + +template +struct Types25 { + typedef T1 Head; + typedef Types24 Tail; +}; + +template +struct Types26 { + typedef T1 Head; + typedef Types25 Tail; +}; + +template +struct Types27 { + typedef T1 Head; + typedef Types26 Tail; +}; + +template +struct Types28 { + typedef T1 Head; + typedef Types27 Tail; +}; + +template +struct Types29 { + typedef T1 Head; + typedef Types28 Tail; +}; + +template +struct Types30 { + typedef T1 Head; + typedef Types29 Tail; +}; + +template +struct Types31 { + typedef T1 Head; + typedef Types30 Tail; +}; + +template +struct Types32 { + typedef T1 Head; + typedef Types31 Tail; +}; + +template +struct Types33 { + typedef T1 Head; + typedef Types32 Tail; +}; + +template +struct Types34 { + typedef T1 Head; + typedef Types33 Tail; +}; + +template +struct Types35 { + typedef T1 Head; + typedef Types34 Tail; +}; + +template +struct Types36 { + typedef T1 Head; + typedef Types35 Tail; +}; + +template +struct Types37 { + typedef T1 Head; + typedef Types36 Tail; +}; + +template +struct Types38 { + typedef T1 Head; + typedef Types37 Tail; +}; + +template +struct Types39 { + typedef T1 Head; + typedef Types38 Tail; +}; + +template +struct Types40 { + typedef T1 Head; + typedef Types39 Tail; +}; + +template +struct Types41 { + typedef T1 Head; + typedef Types40 Tail; +}; + +template +struct Types42 { + typedef T1 Head; + typedef Types41 Tail; +}; + +template +struct Types43 { + typedef T1 Head; + typedef Types42 Tail; +}; + +template +struct Types44 { + typedef T1 Head; + typedef Types43 Tail; +}; + +template +struct Types45 { + typedef T1 Head; + typedef Types44 Tail; +}; + +template +struct Types46 { + typedef T1 Head; + typedef Types45 Tail; +}; + +template +struct Types47 { + typedef T1 Head; + typedef Types46 Tail; +}; + +template +struct Types48 { + typedef T1 Head; + typedef Types47 Tail; +}; + +template +struct Types49 { + typedef T1 Head; + typedef Types48 Tail; +}; + +template +struct Types50 { + typedef T1 Head; + typedef Types49 Tail; +}; + + +} // namespace internal + +// We don't want to require the users to write TypesN<...> directly, +// as that would require them to count the length. Types<...> is much +// easier to write, but generates horrible messages when there is a +// compiler error, as gcc insists on printing out each template +// argument, even if it has the default value (this means Types +// will appear as Types in the compiler +// errors). +// +// Our solution is to combine the best part of the two approaches: a +// user would write Types, and Google Test will translate +// that to TypesN internally to make error messages +// readable. The translation is done by the 'type' member of the +// Types template. +template +struct Types { + typedef internal::Types50 type; +}; + +template <> +struct Types { + typedef internal::Types0 type; +}; +template +struct Types { + typedef internal::Types1 type; +}; +template +struct Types { + typedef internal::Types2 type; +}; +template +struct Types { + typedef internal::Types3 type; +}; +template +struct Types { + typedef internal::Types4 type; +}; +template +struct Types { + typedef internal::Types5 type; +}; +template +struct Types { + typedef internal::Types6 type; +}; +template +struct Types { + typedef internal::Types7 type; +}; +template +struct Types { + typedef internal::Types8 type; +}; +template +struct Types { + typedef internal::Types9 type; +}; +template +struct Types { + typedef internal::Types10 type; +}; +template +struct Types { + typedef internal::Types11 type; +}; +template +struct Types { + typedef internal::Types12 type; +}; +template +struct Types { + typedef internal::Types13 type; +}; +template +struct Types { + typedef internal::Types14 type; +}; +template +struct Types { + typedef internal::Types15 type; +}; +template +struct Types { + typedef internal::Types16 type; +}; +template +struct Types { + typedef internal::Types17 type; +}; +template +struct Types { + typedef internal::Types18 type; +}; +template +struct Types { + typedef internal::Types19 type; +}; +template +struct Types { + typedef internal::Types20 type; +}; +template +struct Types { + typedef internal::Types21 type; +}; +template +struct Types { + typedef internal::Types22 type; +}; +template +struct Types { + typedef internal::Types23 type; +}; +template +struct Types { + typedef internal::Types24 type; +}; +template +struct Types { + typedef internal::Types25 type; +}; +template +struct Types { + typedef internal::Types26 type; +}; +template +struct Types { + typedef internal::Types27 type; +}; +template +struct Types { + typedef internal::Types28 type; +}; +template +struct Types { + typedef internal::Types29 type; +}; +template +struct Types { + typedef internal::Types30 type; +}; +template +struct Types { + typedef internal::Types31 type; +}; +template +struct Types { + typedef internal::Types32 type; +}; +template +struct Types { + typedef internal::Types33 type; +}; +template +struct Types { + typedef internal::Types34 type; +}; +template +struct Types { + typedef internal::Types35 type; +}; +template +struct Types { + typedef internal::Types36 type; +}; +template +struct Types { + typedef internal::Types37 type; +}; +template +struct Types { + typedef internal::Types38 type; +}; +template +struct Types { + typedef internal::Types39 type; +}; +template +struct Types { + typedef internal::Types40 type; +}; +template +struct Types { + typedef internal::Types41 type; +}; +template +struct Types { + typedef internal::Types42 type; +}; +template +struct Types { + typedef internal::Types43 type; +}; +template +struct Types { + typedef internal::Types44 type; +}; +template +struct Types { + typedef internal::Types45 type; +}; +template +struct Types { + typedef internal::Types46 type; +}; +template +struct Types { + typedef internal::Types47 type; +}; +template +struct Types { + typedef internal::Types48 type; +}; +template +struct Types { + typedef internal::Types49 type; +}; + +namespace internal { + +# define GTEST_TEMPLATE_ template class + +// The template "selector" struct TemplateSel is used to +// represent Tmpl, which must be a class template with one type +// parameter, as a type. TemplateSel::Bind::type is defined +// as the type Tmpl. This allows us to actually instantiate the +// template "selected" by TemplateSel. +// +// This trick is necessary for simulating typedef for class templates, +// which C++ doesn't support directly. +template +struct TemplateSel { + template + struct Bind { + typedef Tmpl type; + }; +}; + +# define GTEST_BIND_(TmplSel, T) \ + TmplSel::template Bind::type + +// A unique struct template used as the default value for the +// arguments of class template Templates. This allows us to simulate +// variadic templates (e.g. Templates, Templates, +// and etc), which C++ doesn't support directly. +template +struct NoneT {}; + +// The following family of struct and struct templates are used to +// represent template lists. In particular, TemplatesN represents a list of N templates (T1, T2, ..., and TN). Except +// for Templates0, every struct in the family has two member types: +// Head for the selector of the first template in the list, and Tail +// for the rest of the list. + +// The empty template list. +struct Templates0 {}; + +// Template lists of length 1, 2, 3, and so on. + +template +struct Templates1 { + typedef TemplateSel Head; + typedef Templates0 Tail; +}; +template +struct Templates2 { + typedef TemplateSel Head; + typedef Templates1 Tail; +}; + +template +struct Templates3 { + typedef TemplateSel Head; + typedef Templates2 Tail; +}; + +template +struct Templates4 { + typedef TemplateSel Head; + typedef Templates3 Tail; +}; + +template +struct Templates5 { + typedef TemplateSel Head; + typedef Templates4 Tail; +}; + +template +struct Templates6 { + typedef TemplateSel Head; + typedef Templates5 Tail; +}; + +template +struct Templates7 { + typedef TemplateSel Head; + typedef Templates6 Tail; +}; + +template +struct Templates8 { + typedef TemplateSel Head; + typedef Templates7 Tail; +}; + +template +struct Templates9 { + typedef TemplateSel Head; + typedef Templates8 Tail; +}; + +template +struct Templates10 { + typedef TemplateSel Head; + typedef Templates9 Tail; +}; + +template +struct Templates11 { + typedef TemplateSel Head; + typedef Templates10 Tail; +}; + +template +struct Templates12 { + typedef TemplateSel Head; + typedef Templates11 Tail; +}; + +template +struct Templates13 { + typedef TemplateSel Head; + typedef Templates12 Tail; +}; + +template +struct Templates14 { + typedef TemplateSel Head; + typedef Templates13 Tail; +}; + +template +struct Templates15 { + typedef TemplateSel Head; + typedef Templates14 Tail; +}; + +template +struct Templates16 { + typedef TemplateSel Head; + typedef Templates15 Tail; +}; + +template +struct Templates17 { + typedef TemplateSel Head; + typedef Templates16 Tail; +}; + +template +struct Templates18 { + typedef TemplateSel Head; + typedef Templates17 Tail; +}; + +template +struct Templates19 { + typedef TemplateSel Head; + typedef Templates18 Tail; +}; + +template +struct Templates20 { + typedef TemplateSel Head; + typedef Templates19 Tail; +}; + +template +struct Templates21 { + typedef TemplateSel Head; + typedef Templates20 Tail; +}; + +template +struct Templates22 { + typedef TemplateSel Head; + typedef Templates21 Tail; +}; + +template +struct Templates23 { + typedef TemplateSel Head; + typedef Templates22 Tail; +}; + +template +struct Templates24 { + typedef TemplateSel Head; + typedef Templates23 Tail; +}; + +template +struct Templates25 { + typedef TemplateSel Head; + typedef Templates24 Tail; +}; + +template +struct Templates26 { + typedef TemplateSel Head; + typedef Templates25 Tail; +}; + +template +struct Templates27 { + typedef TemplateSel Head; + typedef Templates26 Tail; +}; + +template +struct Templates28 { + typedef TemplateSel Head; + typedef Templates27 Tail; +}; + +template +struct Templates29 { + typedef TemplateSel Head; + typedef Templates28 Tail; +}; + +template +struct Templates30 { + typedef TemplateSel Head; + typedef Templates29 Tail; +}; + +template +struct Templates31 { + typedef TemplateSel Head; + typedef Templates30 Tail; +}; + +template +struct Templates32 { + typedef TemplateSel Head; + typedef Templates31 Tail; +}; + +template +struct Templates33 { + typedef TemplateSel Head; + typedef Templates32 Tail; +}; + +template +struct Templates34 { + typedef TemplateSel Head; + typedef Templates33 Tail; +}; + +template +struct Templates35 { + typedef TemplateSel Head; + typedef Templates34 Tail; +}; + +template +struct Templates36 { + typedef TemplateSel Head; + typedef Templates35 Tail; +}; + +template +struct Templates37 { + typedef TemplateSel Head; + typedef Templates36 Tail; +}; + +template +struct Templates38 { + typedef TemplateSel Head; + typedef Templates37 Tail; +}; + +template +struct Templates39 { + typedef TemplateSel Head; + typedef Templates38 Tail; +}; + +template +struct Templates40 { + typedef TemplateSel Head; + typedef Templates39 Tail; +}; + +template +struct Templates41 { + typedef TemplateSel Head; + typedef Templates40 Tail; +}; + +template +struct Templates42 { + typedef TemplateSel Head; + typedef Templates41 Tail; +}; + +template +struct Templates43 { + typedef TemplateSel Head; + typedef Templates42 Tail; +}; + +template +struct Templates44 { + typedef TemplateSel Head; + typedef Templates43 Tail; +}; + +template +struct Templates45 { + typedef TemplateSel Head; + typedef Templates44 Tail; +}; + +template +struct Templates46 { + typedef TemplateSel Head; + typedef Templates45 Tail; +}; + +template +struct Templates47 { + typedef TemplateSel Head; + typedef Templates46 Tail; +}; + +template +struct Templates48 { + typedef TemplateSel Head; + typedef Templates47 Tail; +}; + +template +struct Templates49 { + typedef TemplateSel Head; + typedef Templates48 Tail; +}; + +template +struct Templates50 { + typedef TemplateSel Head; + typedef Templates49 Tail; +}; + + +// We don't want to require the users to write TemplatesN<...> directly, +// as that would require them to count the length. Templates<...> is much +// easier to write, but generates horrible messages when there is a +// compiler error, as gcc insists on printing out each template +// argument, even if it has the default value (this means Templates +// will appear as Templates in the compiler +// errors). +// +// Our solution is to combine the best part of the two approaches: a +// user would write Templates, and Google Test will translate +// that to TemplatesN internally to make error messages +// readable. The translation is done by the 'type' member of the +// Templates template. +template +struct Templates { + typedef Templates50 type; +}; + +template <> +struct Templates { + typedef Templates0 type; +}; +template +struct Templates { + typedef Templates1 type; +}; +template +struct Templates { + typedef Templates2 type; +}; +template +struct Templates { + typedef Templates3 type; +}; +template +struct Templates { + typedef Templates4 type; +}; +template +struct Templates { + typedef Templates5 type; +}; +template +struct Templates { + typedef Templates6 type; +}; +template +struct Templates { + typedef Templates7 type; +}; +template +struct Templates { + typedef Templates8 type; +}; +template +struct Templates { + typedef Templates9 type; +}; +template +struct Templates { + typedef Templates10 type; +}; +template +struct Templates { + typedef Templates11 type; +}; +template +struct Templates { + typedef Templates12 type; +}; +template +struct Templates { + typedef Templates13 type; +}; +template +struct Templates { + typedef Templates14 type; +}; +template +struct Templates { + typedef Templates15 type; +}; +template +struct Templates { + typedef Templates16 type; +}; +template +struct Templates { + typedef Templates17 type; +}; +template +struct Templates { + typedef Templates18 type; +}; +template +struct Templates { + typedef Templates19 type; +}; +template +struct Templates { + typedef Templates20 type; +}; +template +struct Templates { + typedef Templates21 type; +}; +template +struct Templates { + typedef Templates22 type; +}; +template +struct Templates { + typedef Templates23 type; +}; +template +struct Templates { + typedef Templates24 type; +}; +template +struct Templates { + typedef Templates25 type; +}; +template +struct Templates { + typedef Templates26 type; +}; +template +struct Templates { + typedef Templates27 type; +}; +template +struct Templates { + typedef Templates28 type; +}; +template +struct Templates { + typedef Templates29 type; +}; +template +struct Templates { + typedef Templates30 type; +}; +template +struct Templates { + typedef Templates31 type; +}; +template +struct Templates { + typedef Templates32 type; +}; +template +struct Templates { + typedef Templates33 type; +}; +template +struct Templates { + typedef Templates34 type; +}; +template +struct Templates { + typedef Templates35 type; +}; +template +struct Templates { + typedef Templates36 type; +}; +template +struct Templates { + typedef Templates37 type; +}; +template +struct Templates { + typedef Templates38 type; +}; +template +struct Templates { + typedef Templates39 type; +}; +template +struct Templates { + typedef Templates40 type; +}; +template +struct Templates { + typedef Templates41 type; +}; +template +struct Templates { + typedef Templates42 type; +}; +template +struct Templates { + typedef Templates43 type; +}; +template +struct Templates { + typedef Templates44 type; +}; +template +struct Templates { + typedef Templates45 type; +}; +template +struct Templates { + typedef Templates46 type; +}; +template +struct Templates { + typedef Templates47 type; +}; +template +struct Templates { + typedef Templates48 type; +}; +template +struct Templates { + typedef Templates49 type; +}; + +// The TypeList template makes it possible to use either a single type +// or a Types<...> list in TYPED_TEST_CASE() and +// INSTANTIATE_TYPED_TEST_CASE_P(). + +template +struct TypeList { + typedef Types1 type; +}; + +template +struct TypeList > { + typedef typename Types::type type; +}; + +#endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P + +} // namespace internal +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ + +// Due to C++ preprocessor weirdness, we need double indirection to +// concatenate two tokens when one of them is __LINE__. Writing +// +// foo ## __LINE__ +// +// will result in the token foo__LINE__, instead of foo followed by +// the current line number. For more details, see +// http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.6 +#define GTEST_CONCAT_TOKEN_(foo, bar) GTEST_CONCAT_TOKEN_IMPL_(foo, bar) +#define GTEST_CONCAT_TOKEN_IMPL_(foo, bar) foo ## bar + +class ProtocolMessage; +namespace proto2 { class Message; } + +namespace testing { + +// Forward declarations. + +class AssertionResult; // Result of an assertion. +class Message; // Represents a failure message. +class Test; // Represents a test. +class TestInfo; // Information about a test. +class TestPartResult; // Result of a test part. +class UnitTest; // A collection of test cases. + +template +::std::string PrintToString(const T& value); + +namespace internal { + +struct TraceInfo; // Information about a trace point. +class ScopedTrace; // Implements scoped trace. +class TestInfoImpl; // Opaque implementation of TestInfo +class UnitTestImpl; // Opaque implementation of UnitTest + +// How many times InitGoogleTest() has been called. +GTEST_API_ extern int g_init_gtest_count; + +// The text used in failure messages to indicate the start of the +// stack trace. +GTEST_API_ extern const char kStackTraceMarker[]; + +// Two overloaded helpers for checking at compile time whether an +// expression is a null pointer literal (i.e. NULL or any 0-valued +// compile-time integral constant). Their return values have +// different sizes, so we can use sizeof() to test which version is +// picked by the compiler. These helpers have no implementations, as +// we only need their signatures. +// +// Given IsNullLiteralHelper(x), the compiler will pick the first +// version if x can be implicitly converted to Secret*, and pick the +// second version otherwise. Since Secret is a secret and incomplete +// type, the only expression a user can write that has type Secret* is +// a null pointer literal. Therefore, we know that x is a null +// pointer literal if and only if the first version is picked by the +// compiler. +char IsNullLiteralHelper(Secret* p); +char (&IsNullLiteralHelper(...))[2]; // NOLINT + +// A compile-time bool constant that is true if and only if x is a +// null pointer literal (i.e. NULL or any 0-valued compile-time +// integral constant). +#ifdef GTEST_ELLIPSIS_NEEDS_POD_ +// We lose support for NULL detection where the compiler doesn't like +// passing non-POD classes through ellipsis (...). +# define GTEST_IS_NULL_LITERAL_(x) false +#else +# define GTEST_IS_NULL_LITERAL_(x) \ + (sizeof(::testing::internal::IsNullLiteralHelper(x)) == 1) +#endif // GTEST_ELLIPSIS_NEEDS_POD_ + +// Appends the user-supplied message to the Google-Test-generated message. +GTEST_API_ std::string AppendUserMessage( + const std::string& gtest_msg, const Message& user_msg); + +#if GTEST_HAS_EXCEPTIONS + +// This exception is thrown by (and only by) a failed Google Test +// assertion when GTEST_FLAG(throw_on_failure) is true (if exceptions +// are enabled). We derive it from std::runtime_error, which is for +// errors presumably detectable only at run time. Since +// std::runtime_error inherits from std::exception, many testing +// frameworks know how to extract and print the message inside it. +class GTEST_API_ GoogleTestFailureException : public ::std::runtime_error { + public: + explicit GoogleTestFailureException(const TestPartResult& failure); +}; + +#endif // GTEST_HAS_EXCEPTIONS + +// A helper class for creating scoped traces in user programs. +class GTEST_API_ ScopedTrace { + public: + // The c'tor pushes the given source file location and message onto + // a trace stack maintained by Google Test. + ScopedTrace(const char* file, int line, const Message& message); + + // The d'tor pops the info pushed by the c'tor. + // + // Note that the d'tor is not virtual in order to be efficient. + // Don't inherit from ScopedTrace! + ~ScopedTrace(); + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedTrace); +} GTEST_ATTRIBUTE_UNUSED_; // A ScopedTrace object does its job in its + // c'tor and d'tor. Therefore it doesn't + // need to be used otherwise. + +// Constructs and returns the message for an equality assertion +// (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure. +// +// The first four parameters are the expressions used in the assertion +// and their values, as strings. For example, for ASSERT_EQ(foo, bar) +// where foo is 5 and bar is 6, we have: +// +// expected_expression: "foo" +// actual_expression: "bar" +// expected_value: "5" +// actual_value: "6" +// +// The ignoring_case parameter is true iff the assertion is a +// *_STRCASEEQ*. When it's true, the string " (ignoring case)" will +// be inserted into the message. +GTEST_API_ AssertionResult EqFailure(const char* expected_expression, + const char* actual_expression, + const std::string& expected_value, + const std::string& actual_value, + bool ignoring_case); + +// Constructs a failure message for Boolean assertions such as EXPECT_TRUE. +GTEST_API_ std::string GetBoolAssertionFailureMessage( + const AssertionResult& assertion_result, + const char* expression_text, + const char* actual_predicate_value, + const char* expected_predicate_value); + +// This template class represents an IEEE floating-point number +// (either single-precision or double-precision, depending on the +// template parameters). +// +// The purpose of this class is to do more sophisticated number +// comparison. (Due to round-off error, etc, it's very unlikely that +// two floating-points will be equal exactly. Hence a naive +// comparison by the == operation often doesn't work.) +// +// Format of IEEE floating-point: +// +// The most-significant bit being the leftmost, an IEEE +// floating-point looks like +// +// sign_bit exponent_bits fraction_bits +// +// Here, sign_bit is a single bit that designates the sign of the +// number. +// +// For float, there are 8 exponent bits and 23 fraction bits. +// +// For double, there are 11 exponent bits and 52 fraction bits. +// +// More details can be found at +// http://en.wikipedia.org/wiki/IEEE_floating-point_standard. +// +// Template parameter: +// +// RawType: the raw floating-point type (either float or double) +template +class FloatingPoint { + public: + // Defines the unsigned integer type that has the same size as the + // floating point number. + typedef typename TypeWithSize::UInt Bits; + + // Constants. + + // # of bits in a number. + static const size_t kBitCount = 8*sizeof(RawType); + + // # of fraction bits in a number. + static const size_t kFractionBitCount = + std::numeric_limits::digits - 1; + + // # of exponent bits in a number. + static const size_t kExponentBitCount = kBitCount - 1 - kFractionBitCount; + + // The mask for the sign bit. + static const Bits kSignBitMask = static_cast(1) << (kBitCount - 1); + + // The mask for the fraction bits. + static const Bits kFractionBitMask = + ~static_cast(0) >> (kExponentBitCount + 1); + + // The mask for the exponent bits. + static const Bits kExponentBitMask = ~(kSignBitMask | kFractionBitMask); + + // How many ULP's (Units in the Last Place) we want to tolerate when + // comparing two numbers. The larger the value, the more error we + // allow. A 0 value means that two numbers must be exactly the same + // to be considered equal. + // + // The maximum error of a single floating-point operation is 0.5 + // units in the last place. On Intel CPU's, all floating-point + // calculations are done with 80-bit precision, while double has 64 + // bits. Therefore, 4 should be enough for ordinary use. + // + // See the following article for more details on ULP: + // http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/ + static const size_t kMaxUlps = 4; + + // Constructs a FloatingPoint from a raw floating-point number. + // + // On an Intel CPU, passing a non-normalized NAN (Not a Number) + // around may change its bits, although the new value is guaranteed + // to be also a NAN. Therefore, don't expect this constructor to + // preserve the bits in x when x is a NAN. + explicit FloatingPoint(const RawType& x) { u_.value_ = x; } + + // Static methods + + // Reinterprets a bit pattern as a floating-point number. + // + // This function is needed to test the AlmostEquals() method. + static RawType ReinterpretBits(const Bits bits) { + FloatingPoint fp(0); + fp.u_.bits_ = bits; + return fp.u_.value_; + } + + // Returns the floating-point number that represent positive infinity. + static RawType Infinity() { + return ReinterpretBits(kExponentBitMask); + } + + // Returns the maximum representable finite floating-point number. + static RawType Max(); + + // Non-static methods + + // Returns the bits that represents this number. + const Bits &bits() const { return u_.bits_; } + + // Returns the exponent bits of this number. + Bits exponent_bits() const { return kExponentBitMask & u_.bits_; } + + // Returns the fraction bits of this number. + Bits fraction_bits() const { return kFractionBitMask & u_.bits_; } + + // Returns the sign bit of this number. + Bits sign_bit() const { return kSignBitMask & u_.bits_; } + + // Returns true iff this is NAN (not a number). + bool is_nan() const { + // It's a NAN if the exponent bits are all ones and the fraction + // bits are not entirely zeros. + return (exponent_bits() == kExponentBitMask) && (fraction_bits() != 0); + } + + // Returns true iff this number is at most kMaxUlps ULP's away from + // rhs. In particular, this function: + // + // - returns false if either number is (or both are) NAN. + // - treats really large numbers as almost equal to infinity. + // - thinks +0.0 and -0.0 are 0 DLP's apart. + bool AlmostEquals(const FloatingPoint& rhs) const { + // The IEEE standard says that any comparison operation involving + // a NAN must return false. + if (is_nan() || rhs.is_nan()) return false; + + return DistanceBetweenSignAndMagnitudeNumbers(u_.bits_, rhs.u_.bits_) + <= kMaxUlps; + } + + private: + // The data type used to store the actual floating-point number. + union FloatingPointUnion { + RawType value_; // The raw floating-point number. + Bits bits_; // The bits that represent the number. + }; + + // Converts an integer from the sign-and-magnitude representation to + // the biased representation. More precisely, let N be 2 to the + // power of (kBitCount - 1), an integer x is represented by the + // unsigned number x + N. + // + // For instance, + // + // -N + 1 (the most negative number representable using + // sign-and-magnitude) is represented by 1; + // 0 is represented by N; and + // N - 1 (the biggest number representable using + // sign-and-magnitude) is represented by 2N - 1. + // + // Read http://en.wikipedia.org/wiki/Signed_number_representations + // for more details on signed number representations. + static Bits SignAndMagnitudeToBiased(const Bits &sam) { + if (kSignBitMask & sam) { + // sam represents a negative number. + return ~sam + 1; + } else { + // sam represents a positive number. + return kSignBitMask | sam; + } + } + + // Given two numbers in the sign-and-magnitude representation, + // returns the distance between them as an unsigned number. + static Bits DistanceBetweenSignAndMagnitudeNumbers(const Bits &sam1, + const Bits &sam2) { + const Bits biased1 = SignAndMagnitudeToBiased(sam1); + const Bits biased2 = SignAndMagnitudeToBiased(sam2); + return (biased1 >= biased2) ? (biased1 - biased2) : (biased2 - biased1); + } + + FloatingPointUnion u_; +}; + +// We cannot use std::numeric_limits::max() as it clashes with the max() +// macro defined by . +template <> +inline float FloatingPoint::Max() { return FLT_MAX; } +template <> +inline double FloatingPoint::Max() { return DBL_MAX; } + +// Typedefs the instances of the FloatingPoint template class that we +// care to use. +typedef FloatingPoint Float; +typedef FloatingPoint Double; + +// In order to catch the mistake of putting tests that use different +// test fixture classes in the same test case, we need to assign +// unique IDs to fixture classes and compare them. The TypeId type is +// used to hold such IDs. The user should treat TypeId as an opaque +// type: the only operation allowed on TypeId values is to compare +// them for equality using the == operator. +typedef const void* TypeId; + +template +class TypeIdHelper { + public: + // dummy_ must not have a const type. Otherwise an overly eager + // compiler (e.g. MSVC 7.1 & 8.0) may try to merge + // TypeIdHelper::dummy_ for different Ts as an "optimization". + static bool dummy_; +}; + +template +bool TypeIdHelper::dummy_ = false; + +// GetTypeId() returns the ID of type T. Different values will be +// returned for different types. Calling the function twice with the +// same type argument is guaranteed to return the same ID. +template +TypeId GetTypeId() { + // The compiler is required to allocate a different + // TypeIdHelper::dummy_ variable for each T used to instantiate + // the template. Therefore, the address of dummy_ is guaranteed to + // be unique. + return &(TypeIdHelper::dummy_); +} + +// Returns the type ID of ::testing::Test. Always call this instead +// of GetTypeId< ::testing::Test>() to get the type ID of +// ::testing::Test, as the latter may give the wrong result due to a +// suspected linker bug when compiling Google Test as a Mac OS X +// framework. +GTEST_API_ TypeId GetTestTypeId(); + +// Defines the abstract factory interface that creates instances +// of a Test object. +class TestFactoryBase { + public: + virtual ~TestFactoryBase() {} + + // Creates a test instance to run. The instance is both created and destroyed + // within TestInfoImpl::Run() + virtual Test* CreateTest() = 0; + + protected: + TestFactoryBase() {} + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestFactoryBase); +}; + +// This class provides implementation of TeastFactoryBase interface. +// It is used in TEST and TEST_F macros. +template +class TestFactoryImpl : public TestFactoryBase { + public: + virtual Test* CreateTest() { return new TestClass; } +}; + +#if GTEST_OS_WINDOWS + +// Predicate-formatters for implementing the HRESULT checking macros +// {ASSERT|EXPECT}_HRESULT_{SUCCEEDED|FAILED} +// We pass a long instead of HRESULT to avoid causing an +// include dependency for the HRESULT type. +GTEST_API_ AssertionResult IsHRESULTSuccess(const char* expr, + long hr); // NOLINT +GTEST_API_ AssertionResult IsHRESULTFailure(const char* expr, + long hr); // NOLINT + +#endif // GTEST_OS_WINDOWS + +// Types of SetUpTestCase() and TearDownTestCase() functions. +typedef void (*SetUpTestCaseFunc)(); +typedef void (*TearDownTestCaseFunc)(); + +// Creates a new TestInfo object and registers it with Google Test; +// returns the created object. +// +// Arguments: +// +// test_case_name: name of the test case +// name: name of the test +// type_param the name of the test's type parameter, or NULL if +// this is not a typed or a type-parameterized test. +// value_param text representation of the test's value parameter, +// or NULL if this is not a type-parameterized test. +// fixture_class_id: ID of the test fixture class +// set_up_tc: pointer to the function that sets up the test case +// tear_down_tc: pointer to the function that tears down the test case +// factory: pointer to the factory that creates a test object. +// The newly created TestInfo instance will assume +// ownership of the factory object. +GTEST_API_ TestInfo* MakeAndRegisterTestInfo( + const char* test_case_name, + const char* name, + const char* type_param, + const char* value_param, + TypeId fixture_class_id, + SetUpTestCaseFunc set_up_tc, + TearDownTestCaseFunc tear_down_tc, + TestFactoryBase* factory); + +// If *pstr starts with the given prefix, modifies *pstr to be right +// past the prefix and returns true; otherwise leaves *pstr unchanged +// and returns false. None of pstr, *pstr, and prefix can be NULL. +GTEST_API_ bool SkipPrefix(const char* prefix, const char** pstr); + +#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P + +// State of the definition of a type-parameterized test case. +class GTEST_API_ TypedTestCasePState { + public: + TypedTestCasePState() : registered_(false) {} + + // Adds the given test name to defined_test_names_ and return true + // if the test case hasn't been registered; otherwise aborts the + // program. + bool AddTestName(const char* file, int line, const char* case_name, + const char* test_name) { + if (registered_) { + fprintf(stderr, "%s Test %s must be defined before " + "REGISTER_TYPED_TEST_CASE_P(%s, ...).\n", + FormatFileLocation(file, line).c_str(), test_name, case_name); + fflush(stderr); + posix::Abort(); + } + defined_test_names_.insert(test_name); + return true; + } + + // Verifies that registered_tests match the test names in + // defined_test_names_; returns registered_tests if successful, or + // aborts the program otherwise. + const char* VerifyRegisteredTestNames( + const char* file, int line, const char* registered_tests); + + private: + bool registered_; + ::std::set defined_test_names_; +}; + +// Skips to the first non-space char after the first comma in 'str'; +// returns NULL if no comma is found in 'str'. +inline const char* SkipComma(const char* str) { + const char* comma = strchr(str, ','); + if (comma == NULL) { + return NULL; + } + while (IsSpace(*(++comma))) {} + return comma; +} + +// Returns the prefix of 'str' before the first comma in it; returns +// the entire string if it contains no comma. +inline std::string GetPrefixUntilComma(const char* str) { + const char* comma = strchr(str, ','); + return comma == NULL ? str : std::string(str, comma); +} + +// TypeParameterizedTest::Register() +// registers a list of type-parameterized tests with Google Test. The +// return value is insignificant - we just need to return something +// such that we can call this function in a namespace scope. +// +// Implementation note: The GTEST_TEMPLATE_ macro declares a template +// template parameter. It's defined in gtest-type-util.h. +template +class TypeParameterizedTest { + public: + // 'index' is the index of the test in the type list 'Types' + // specified in INSTANTIATE_TYPED_TEST_CASE_P(Prefix, TestCase, + // Types). Valid values for 'index' are [0, N - 1] where N is the + // length of Types. + static bool Register(const char* prefix, const char* case_name, + const char* test_names, int index) { + typedef typename Types::Head Type; + typedef Fixture FixtureClass; + typedef typename GTEST_BIND_(TestSel, Type) TestClass; + + // First, registers the first type-parameterized test in the type + // list. + MakeAndRegisterTestInfo( + (std::string(prefix) + (prefix[0] == '\0' ? "" : "/") + case_name + "/" + + StreamableToString(index)).c_str(), + GetPrefixUntilComma(test_names).c_str(), + GetTypeName().c_str(), + NULL, // No value parameter. + GetTypeId(), + TestClass::SetUpTestCase, + TestClass::TearDownTestCase, + new TestFactoryImpl); + + // Next, recurses (at compile time) with the tail of the type list. + return TypeParameterizedTest + ::Register(prefix, case_name, test_names, index + 1); + } +}; + +// The base case for the compile time recursion. +template +class TypeParameterizedTest { + public: + static bool Register(const char* /*prefix*/, const char* /*case_name*/, + const char* /*test_names*/, int /*index*/) { + return true; + } +}; + +// TypeParameterizedTestCase::Register() +// registers *all combinations* of 'Tests' and 'Types' with Google +// Test. The return value is insignificant - we just need to return +// something such that we can call this function in a namespace scope. +template +class TypeParameterizedTestCase { + public: + static bool Register(const char* prefix, const char* case_name, + const char* test_names) { + typedef typename Tests::Head Head; + + // First, register the first test in 'Test' for each type in 'Types'. + TypeParameterizedTest::Register( + prefix, case_name, test_names, 0); + + // Next, recurses (at compile time) with the tail of the test list. + return TypeParameterizedTestCase + ::Register(prefix, case_name, SkipComma(test_names)); + } +}; + +// The base case for the compile time recursion. +template +class TypeParameterizedTestCase { + public: + static bool Register(const char* /*prefix*/, const char* /*case_name*/, + const char* /*test_names*/) { + return true; + } +}; + +#endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P + +// Returns the current OS stack trace as an std::string. +// +// The maximum number of stack frames to be included is specified by +// the gtest_stack_trace_depth flag. The skip_count parameter +// specifies the number of top frames to be skipped, which doesn't +// count against the number of frames to be included. +// +// For example, if Foo() calls Bar(), which in turn calls +// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in +// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't. +GTEST_API_ std::string GetCurrentOsStackTraceExceptTop( + UnitTest* unit_test, int skip_count); + +// Helpers for suppressing warnings on unreachable code or constant +// condition. + +// Always returns true. +GTEST_API_ bool AlwaysTrue(); + +// Always returns false. +inline bool AlwaysFalse() { return !AlwaysTrue(); } + +// Helper for suppressing false warning from Clang on a const char* +// variable declared in a conditional expression always being NULL in +// the else branch. +struct GTEST_API_ ConstCharPtr { + ConstCharPtr(const char* str) : value(str) {} + operator bool() const { return true; } + const char* value; +}; + +// A simple Linear Congruential Generator for generating random +// numbers with a uniform distribution. Unlike rand() and srand(), it +// doesn't use global state (and therefore can't interfere with user +// code). Unlike rand_r(), it's portable. An LCG isn't very random, +// but it's good enough for our purposes. +class GTEST_API_ Random { + public: + static const UInt32 kMaxRange = 1u << 31; + + explicit Random(UInt32 seed) : state_(seed) {} + + void Reseed(UInt32 seed) { state_ = seed; } + + // Generates a random number from [0, range). Crashes if 'range' is + // 0 or greater than kMaxRange. + UInt32 Generate(UInt32 range); + + private: + UInt32 state_; + GTEST_DISALLOW_COPY_AND_ASSIGN_(Random); +}; + +// Defining a variable of type CompileAssertTypesEqual will cause a +// compiler error iff T1 and T2 are different types. +template +struct CompileAssertTypesEqual; + +template +struct CompileAssertTypesEqual { +}; + +// Removes the reference from a type if it is a reference type, +// otherwise leaves it unchanged. This is the same as +// tr1::remove_reference, which is not widely available yet. +template +struct RemoveReference { typedef T type; }; // NOLINT +template +struct RemoveReference { typedef T type; }; // NOLINT + +// A handy wrapper around RemoveReference that works when the argument +// T depends on template parameters. +#define GTEST_REMOVE_REFERENCE_(T) \ + typename ::testing::internal::RemoveReference::type + +// Removes const from a type if it is a const type, otherwise leaves +// it unchanged. This is the same as tr1::remove_const, which is not +// widely available yet. +template +struct RemoveConst { typedef T type; }; // NOLINT +template +struct RemoveConst { typedef T type; }; // NOLINT + +// MSVC 8.0, Sun C++, and IBM XL C++ have a bug which causes the above +// definition to fail to remove the const in 'const int[3]' and 'const +// char[3][4]'. The following specialization works around the bug. +template +struct RemoveConst { + typedef typename RemoveConst::type type[N]; +}; + +#if defined(_MSC_VER) && _MSC_VER < 1400 +// This is the only specialization that allows VC++ 7.1 to remove const in +// 'const int[3] and 'const int[3][4]'. However, it causes trouble with GCC +// and thus needs to be conditionally compiled. +template +struct RemoveConst { + typedef typename RemoveConst::type type[N]; +}; +#endif + +// A handy wrapper around RemoveConst that works when the argument +// T depends on template parameters. +#define GTEST_REMOVE_CONST_(T) \ + typename ::testing::internal::RemoveConst::type + +// Turns const U&, U&, const U, and U all into U. +#define GTEST_REMOVE_REFERENCE_AND_CONST_(T) \ + GTEST_REMOVE_CONST_(GTEST_REMOVE_REFERENCE_(T)) + +// Adds reference to a type if it is not a reference type, +// otherwise leaves it unchanged. This is the same as +// tr1::add_reference, which is not widely available yet. +template +struct AddReference { typedef T& type; }; // NOLINT +template +struct AddReference { typedef T& type; }; // NOLINT + +// A handy wrapper around AddReference that works when the argument T +// depends on template parameters. +#define GTEST_ADD_REFERENCE_(T) \ + typename ::testing::internal::AddReference::type + +// Adds a reference to const on top of T as necessary. For example, +// it transforms +// +// char ==> const char& +// const char ==> const char& +// char& ==> const char& +// const char& ==> const char& +// +// The argument T must depend on some template parameters. +#define GTEST_REFERENCE_TO_CONST_(T) \ + GTEST_ADD_REFERENCE_(const GTEST_REMOVE_REFERENCE_(T)) + +// ImplicitlyConvertible::value is a compile-time bool +// constant that's true iff type From can be implicitly converted to +// type To. +template +class ImplicitlyConvertible { + private: + // We need the following helper functions only for their types. + // They have no implementations. + + // MakeFrom() is an expression whose type is From. We cannot simply + // use From(), as the type From may not have a public default + // constructor. + static From MakeFrom(); + + // These two functions are overloaded. Given an expression + // Helper(x), the compiler will pick the first version if x can be + // implicitly converted to type To; otherwise it will pick the + // second version. + // + // The first version returns a value of size 1, and the second + // version returns a value of size 2. Therefore, by checking the + // size of Helper(x), which can be done at compile time, we can tell + // which version of Helper() is used, and hence whether x can be + // implicitly converted to type To. + static char Helper(To); + static char (&Helper(...))[2]; // NOLINT + + // We have to put the 'public' section after the 'private' section, + // or MSVC refuses to compile the code. + public: + // MSVC warns about implicitly converting from double to int for + // possible loss of data, so we need to temporarily disable the + // warning. +#ifdef _MSC_VER +# pragma warning(push) // Saves the current warning state. +# pragma warning(disable:4244) // Temporarily disables warning 4244. + + static const bool value = + sizeof(Helper(ImplicitlyConvertible::MakeFrom())) == 1; +# pragma warning(pop) // Restores the warning state. +#elif defined(__BORLANDC__) + // C++Builder cannot use member overload resolution during template + // instantiation. The simplest workaround is to use its C++0x type traits + // functions (C++Builder 2009 and above only). + static const bool value = __is_convertible(From, To); +#else + static const bool value = + sizeof(Helper(ImplicitlyConvertible::MakeFrom())) == 1; +#endif // _MSV_VER +}; +template +const bool ImplicitlyConvertible::value; + +// IsAProtocolMessage::value is a compile-time bool constant that's +// true iff T is type ProtocolMessage, proto2::Message, or a subclass +// of those. +template +struct IsAProtocolMessage + : public bool_constant< + ImplicitlyConvertible::value || + ImplicitlyConvertible::value> { +}; + +// When the compiler sees expression IsContainerTest(0), if C is an +// STL-style container class, the first overload of IsContainerTest +// will be viable (since both C::iterator* and C::const_iterator* are +// valid types and NULL can be implicitly converted to them). It will +// be picked over the second overload as 'int' is a perfect match for +// the type of argument 0. If C::iterator or C::const_iterator is not +// a valid type, the first overload is not viable, and the second +// overload will be picked. Therefore, we can determine whether C is +// a container class by checking the type of IsContainerTest(0). +// The value of the expression is insignificant. +// +// Note that we look for both C::iterator and C::const_iterator. The +// reason is that C++ injects the name of a class as a member of the +// class itself (e.g. you can refer to class iterator as either +// 'iterator' or 'iterator::iterator'). If we look for C::iterator +// only, for example, we would mistakenly think that a class named +// iterator is an STL container. +// +// Also note that the simpler approach of overloading +// IsContainerTest(typename C::const_iterator*) and +// IsContainerTest(...) doesn't work with Visual Age C++ and Sun C++. +typedef int IsContainer; +template +IsContainer IsContainerTest(int /* dummy */, + typename C::iterator* /* it */ = NULL, + typename C::const_iterator* /* const_it */ = NULL) { + return 0; +} + +typedef char IsNotContainer; +template +IsNotContainer IsContainerTest(long /* dummy */) { return '\0'; } + +// EnableIf::type is void when 'Cond' is true, and +// undefined when 'Cond' is false. To use SFINAE to make a function +// overload only apply when a particular expression is true, add +// "typename EnableIf::type* = 0" as the last parameter. +template struct EnableIf; +template<> struct EnableIf { typedef void type; }; // NOLINT + +// Utilities for native arrays. + +// ArrayEq() compares two k-dimensional native arrays using the +// elements' operator==, where k can be any integer >= 0. When k is +// 0, ArrayEq() degenerates into comparing a single pair of values. + +template +bool ArrayEq(const T* lhs, size_t size, const U* rhs); + +// This generic version is used when k is 0. +template +inline bool ArrayEq(const T& lhs, const U& rhs) { return lhs == rhs; } + +// This overload is used when k >= 1. +template +inline bool ArrayEq(const T(&lhs)[N], const U(&rhs)[N]) { + return internal::ArrayEq(lhs, N, rhs); +} + +// This helper reduces code bloat. If we instead put its logic inside +// the previous ArrayEq() function, arrays with different sizes would +// lead to different copies of the template code. +template +bool ArrayEq(const T* lhs, size_t size, const U* rhs) { + for (size_t i = 0; i != size; i++) { + if (!internal::ArrayEq(lhs[i], rhs[i])) + return false; + } + return true; +} + +// Finds the first element in the iterator range [begin, end) that +// equals elem. Element may be a native array type itself. +template +Iter ArrayAwareFind(Iter begin, Iter end, const Element& elem) { + for (Iter it = begin; it != end; ++it) { + if (internal::ArrayEq(*it, elem)) + return it; + } + return end; +} + +// CopyArray() copies a k-dimensional native array using the elements' +// operator=, where k can be any integer >= 0. When k is 0, +// CopyArray() degenerates into copying a single value. + +template +void CopyArray(const T* from, size_t size, U* to); + +// This generic version is used when k is 0. +template +inline void CopyArray(const T& from, U* to) { *to = from; } + +// This overload is used when k >= 1. +template +inline void CopyArray(const T(&from)[N], U(*to)[N]) { + internal::CopyArray(from, N, *to); +} + +// This helper reduces code bloat. If we instead put its logic inside +// the previous CopyArray() function, arrays with different sizes +// would lead to different copies of the template code. +template +void CopyArray(const T* from, size_t size, U* to) { + for (size_t i = 0; i != size; i++) { + internal::CopyArray(from[i], to + i); + } +} + +// The relation between an NativeArray object (see below) and the +// native array it represents. +enum RelationToSource { + kReference, // The NativeArray references the native array. + kCopy // The NativeArray makes a copy of the native array and + // owns the copy. +}; + +// Adapts a native array to a read-only STL-style container. Instead +// of the complete STL container concept, this adaptor only implements +// members useful for Google Mock's container matchers. New members +// should be added as needed. To simplify the implementation, we only +// support Element being a raw type (i.e. having no top-level const or +// reference modifier). It's the client's responsibility to satisfy +// this requirement. Element can be an array type itself (hence +// multi-dimensional arrays are supported). +template +class NativeArray { + public: + // STL-style container typedefs. + typedef Element value_type; + typedef Element* iterator; + typedef const Element* const_iterator; + + // Constructs from a native array. + NativeArray(const Element* array, size_t count, RelationToSource relation) { + Init(array, count, relation); + } + + // Copy constructor. + NativeArray(const NativeArray& rhs) { + Init(rhs.array_, rhs.size_, rhs.relation_to_source_); + } + + ~NativeArray() { + // Ensures that the user doesn't instantiate NativeArray with a + // const or reference type. + static_cast(StaticAssertTypeEqHelper()); + if (relation_to_source_ == kCopy) + delete[] array_; + } + + // STL-style container methods. + size_t size() const { return size_; } + const_iterator begin() const { return array_; } + const_iterator end() const { return array_ + size_; } + bool operator==(const NativeArray& rhs) const { + return size() == rhs.size() && + ArrayEq(begin(), size(), rhs.begin()); + } + + private: + // Initializes this object; makes a copy of the input array if + // 'relation' is kCopy. + void Init(const Element* array, size_t a_size, RelationToSource relation) { + if (relation == kReference) { + array_ = array; + } else { + Element* const copy = new Element[a_size]; + CopyArray(array, a_size, copy); + array_ = copy; + } + size_ = a_size; + relation_to_source_ = relation; + } + + const Element* array_; + size_t size_; + RelationToSource relation_to_source_; + + GTEST_DISALLOW_ASSIGN_(NativeArray); +}; + +} // namespace internal +} // namespace testing + +#define GTEST_MESSAGE_AT_(file, line, message, result_type) \ + ::testing::internal::AssertHelper(result_type, file, line, message) \ + = ::testing::Message() + +#define GTEST_MESSAGE_(message, result_type) \ + GTEST_MESSAGE_AT_(__FILE__, __LINE__, message, result_type) + +#define GTEST_FATAL_FAILURE_(message) \ + return GTEST_MESSAGE_(message, ::testing::TestPartResult::kFatalFailure) + +#define GTEST_NONFATAL_FAILURE_(message) \ + GTEST_MESSAGE_(message, ::testing::TestPartResult::kNonFatalFailure) + +#define GTEST_SUCCESS_(message) \ + GTEST_MESSAGE_(message, ::testing::TestPartResult::kSuccess) + +// Suppresses MSVC warnings 4072 (unreachable code) for the code following +// statement if it returns or throws (or doesn't return or throw in some +// situations). +#define GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) \ + if (::testing::internal::AlwaysTrue()) { statement; } + +#define GTEST_TEST_THROW_(statement, expected_exception, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::ConstCharPtr gtest_msg = "") { \ + bool gtest_caught_expected = false; \ + try { \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + } \ + catch (expected_exception const&) { \ + gtest_caught_expected = true; \ + } \ + catch (...) { \ + gtest_msg.value = \ + "Expected: " #statement " throws an exception of type " \ + #expected_exception ".\n Actual: it throws a different type."; \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ + } \ + if (!gtest_caught_expected) { \ + gtest_msg.value = \ + "Expected: " #statement " throws an exception of type " \ + #expected_exception ".\n Actual: it throws nothing."; \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ + } \ + } else \ + GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__): \ + fail(gtest_msg.value) + +#define GTEST_TEST_NO_THROW_(statement, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::AlwaysTrue()) { \ + try { \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + } \ + catch (...) { \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__); \ + } \ + } else \ + GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__): \ + fail("Expected: " #statement " doesn't throw an exception.\n" \ + " Actual: it throws.") + +#define GTEST_TEST_ANY_THROW_(statement, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::AlwaysTrue()) { \ + bool gtest_caught_any = false; \ + try { \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + } \ + catch (...) { \ + gtest_caught_any = true; \ + } \ + if (!gtest_caught_any) { \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__); \ + } \ + } else \ + GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__): \ + fail("Expected: " #statement " throws an exception.\n" \ + " Actual: it doesn't.") + + +// Implements Boolean test assertions such as EXPECT_TRUE. expression can be +// either a boolean expression or an AssertionResult. text is a textual +// represenation of expression as it was passed into the EXPECT_TRUE. +#define GTEST_TEST_BOOLEAN_(expression, text, actual, expected, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (const ::testing::AssertionResult gtest_ar_ = \ + ::testing::AssertionResult(expression)) \ + ; \ + else \ + fail(::testing::internal::GetBoolAssertionFailureMessage(\ + gtest_ar_, text, #actual, #expected).c_str()) + +#define GTEST_TEST_NO_FATAL_FAILURE_(statement, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::AlwaysTrue()) { \ + ::testing::internal::HasNewFatalFailureHelper gtest_fatal_failure_checker; \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + if (gtest_fatal_failure_checker.has_new_fatal_failure()) { \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__); \ + } \ + } else \ + GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__): \ + fail("Expected: " #statement " doesn't generate new fatal " \ + "failures in the current thread.\n" \ + " Actual: it does.") + +// Expands to the name of the class that implements the given test. +#define GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \ + test_case_name##_##test_name##_Test + +// Helper macro for defining tests. +#define GTEST_TEST_(test_case_name, test_name, parent_class, parent_id)\ +class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) : public parent_class {\ + public:\ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {}\ + private:\ + virtual void TestBody();\ + static ::testing::TestInfo* const test_info_ GTEST_ATTRIBUTE_UNUSED_;\ + GTEST_DISALLOW_COPY_AND_ASSIGN_(\ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name));\ +};\ +\ +::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_case_name, test_name)\ + ::test_info_ =\ + ::testing::internal::MakeAndRegisterTestInfo(\ + #test_case_name, #test_name, NULL, NULL, \ + (parent_id), \ + parent_class::SetUpTestCase, \ + parent_class::TearDownTestCase, \ + new ::testing::internal::TestFactoryImpl<\ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>);\ +void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody() + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) +// +// The Google C++ Testing Framework (Google Test) +// +// This header file defines the public API for death tests. It is +// #included by gtest.h so a user doesn't need to include this +// directly. + +#ifndef GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ +#define GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ + +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee) +// +// The Google C++ Testing Framework (Google Test) +// +// This header file defines internal utilities needed for implementing +// death tests. They are subject to change without notice. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ + + +#include + +namespace testing { +namespace internal { + +GTEST_DECLARE_string_(internal_run_death_test); + +// Names of the flags (needed for parsing Google Test flags). +const char kDeathTestStyleFlag[] = "death_test_style"; +const char kDeathTestUseFork[] = "death_test_use_fork"; +const char kInternalRunDeathTestFlag[] = "internal_run_death_test"; + +#if GTEST_HAS_DEATH_TEST + +// DeathTest is a class that hides much of the complexity of the +// GTEST_DEATH_TEST_ macro. It is abstract; its static Create method +// returns a concrete class that depends on the prevailing death test +// style, as defined by the --gtest_death_test_style and/or +// --gtest_internal_run_death_test flags. + +// In describing the results of death tests, these terms are used with +// the corresponding definitions: +// +// exit status: The integer exit information in the format specified +// by wait(2) +// exit code: The integer code passed to exit(3), _exit(2), or +// returned from main() +class GTEST_API_ DeathTest { + public: + // Create returns false if there was an error determining the + // appropriate action to take for the current death test; for example, + // if the gtest_death_test_style flag is set to an invalid value. + // The LastMessage method will return a more detailed message in that + // case. Otherwise, the DeathTest pointer pointed to by the "test" + // argument is set. If the death test should be skipped, the pointer + // is set to NULL; otherwise, it is set to the address of a new concrete + // DeathTest object that controls the execution of the current test. + static bool Create(const char* statement, const RE* regex, + const char* file, int line, DeathTest** test); + DeathTest(); + virtual ~DeathTest() { } + + // A helper class that aborts a death test when it's deleted. + class ReturnSentinel { + public: + explicit ReturnSentinel(DeathTest* test) : test_(test) { } + ~ReturnSentinel() { test_->Abort(TEST_ENCOUNTERED_RETURN_STATEMENT); } + private: + DeathTest* const test_; + GTEST_DISALLOW_COPY_AND_ASSIGN_(ReturnSentinel); + } GTEST_ATTRIBUTE_UNUSED_; + + // An enumeration of possible roles that may be taken when a death + // test is encountered. EXECUTE means that the death test logic should + // be executed immediately. OVERSEE means that the program should prepare + // the appropriate environment for a child process to execute the death + // test, then wait for it to complete. + enum TestRole { OVERSEE_TEST, EXECUTE_TEST }; + + // An enumeration of the three reasons that a test might be aborted. + enum AbortReason { + TEST_ENCOUNTERED_RETURN_STATEMENT, + TEST_THREW_EXCEPTION, + TEST_DID_NOT_DIE + }; + + // Assumes one of the above roles. + virtual TestRole AssumeRole() = 0; + + // Waits for the death test to finish and returns its status. + virtual int Wait() = 0; + + // Returns true if the death test passed; that is, the test process + // exited during the test, its exit status matches a user-supplied + // predicate, and its stderr output matches a user-supplied regular + // expression. + // The user-supplied predicate may be a macro expression rather + // than a function pointer or functor, or else Wait and Passed could + // be combined. + virtual bool Passed(bool exit_status_ok) = 0; + + // Signals that the death test did not die as expected. + virtual void Abort(AbortReason reason) = 0; + + // Returns a human-readable outcome message regarding the outcome of + // the last death test. + static const char* LastMessage(); + + static void set_last_death_test_message(const std::string& message); + + private: + // A string containing a description of the outcome of the last death test. + static std::string last_death_test_message_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(DeathTest); +}; + +// Factory interface for death tests. May be mocked out for testing. +class DeathTestFactory { + public: + virtual ~DeathTestFactory() { } + virtual bool Create(const char* statement, const RE* regex, + const char* file, int line, DeathTest** test) = 0; +}; + +// A concrete DeathTestFactory implementation for normal use. +class DefaultDeathTestFactory : public DeathTestFactory { + public: + virtual bool Create(const char* statement, const RE* regex, + const char* file, int line, DeathTest** test); +}; + +// Returns true if exit_status describes a process that was terminated +// by a signal, or exited normally with a nonzero exit code. +GTEST_API_ bool ExitedUnsuccessfully(int exit_status); + +// Traps C++ exceptions escaping statement and reports them as test +// failures. Note that trapping SEH exceptions is not implemented here. +# if GTEST_HAS_EXCEPTIONS +# define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \ + try { \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + } catch (const ::std::exception& gtest_exception) { \ + fprintf(\ + stderr, \ + "\n%s: Caught std::exception-derived exception escaping the " \ + "death test statement. Exception message: %s\n", \ + ::testing::internal::FormatFileLocation(__FILE__, __LINE__).c_str(), \ + gtest_exception.what()); \ + fflush(stderr); \ + death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \ + } catch (...) { \ + death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \ + } + +# else +# define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) + +# endif + +// This macro is for implementing ASSERT_DEATH*, EXPECT_DEATH*, +// ASSERT_EXIT*, and EXPECT_EXIT*. +# define GTEST_DEATH_TEST_(statement, predicate, regex, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::AlwaysTrue()) { \ + const ::testing::internal::RE& gtest_regex = (regex); \ + ::testing::internal::DeathTest* gtest_dt; \ + if (!::testing::internal::DeathTest::Create(#statement, >est_regex, \ + __FILE__, __LINE__, >est_dt)) { \ + goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \ + } \ + if (gtest_dt != NULL) { \ + ::testing::internal::scoped_ptr< ::testing::internal::DeathTest> \ + gtest_dt_ptr(gtest_dt); \ + switch (gtest_dt->AssumeRole()) { \ + case ::testing::internal::DeathTest::OVERSEE_TEST: \ + if (!gtest_dt->Passed(predicate(gtest_dt->Wait()))) { \ + goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \ + } \ + break; \ + case ::testing::internal::DeathTest::EXECUTE_TEST: { \ + ::testing::internal::DeathTest::ReturnSentinel \ + gtest_sentinel(gtest_dt); \ + GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, gtest_dt); \ + gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \ + break; \ + } \ + default: \ + break; \ + } \ + } \ + } else \ + GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__): \ + fail(::testing::internal::DeathTest::LastMessage()) +// The symbol "fail" here expands to something into which a message +// can be streamed. + +// This macro is for implementing ASSERT/EXPECT_DEBUG_DEATH when compiled in +// NDEBUG mode. In this case we need the statements to be executed, the regex is +// ignored, and the macro must accept a streamed message even though the message +// is never printed. +# define GTEST_EXECUTE_STATEMENT_(statement, regex) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::AlwaysTrue()) { \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + } else \ + ::testing::Message() + +// A class representing the parsed contents of the +// --gtest_internal_run_death_test flag, as it existed when +// RUN_ALL_TESTS was called. +class InternalRunDeathTestFlag { + public: + InternalRunDeathTestFlag(const std::string& a_file, + int a_line, + int an_index, + int a_write_fd) + : file_(a_file), line_(a_line), index_(an_index), + write_fd_(a_write_fd) {} + + ~InternalRunDeathTestFlag() { + if (write_fd_ >= 0) + posix::Close(write_fd_); + } + + const std::string& file() const { return file_; } + int line() const { return line_; } + int index() const { return index_; } + int write_fd() const { return write_fd_; } + + private: + std::string file_; + int line_; + int index_; + int write_fd_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(InternalRunDeathTestFlag); +}; + +// Returns a newly created InternalRunDeathTestFlag object with fields +// initialized from the GTEST_FLAG(internal_run_death_test) flag if +// the flag is specified; otherwise returns NULL. +InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag(); + +#else // GTEST_HAS_DEATH_TEST + +// This macro is used for implementing macros such as +// EXPECT_DEATH_IF_SUPPORTED and ASSERT_DEATH_IF_SUPPORTED on systems where +// death tests are not supported. Those macros must compile on such systems +// iff EXPECT_DEATH and ASSERT_DEATH compile with the same parameters on +// systems that support death tests. This allows one to write such a macro +// on a system that does not support death tests and be sure that it will +// compile on a death-test supporting system. +// +// Parameters: +// statement - A statement that a macro such as EXPECT_DEATH would test +// for program termination. This macro has to make sure this +// statement is compiled but not executed, to ensure that +// EXPECT_DEATH_IF_SUPPORTED compiles with a certain +// parameter iff EXPECT_DEATH compiles with it. +// regex - A regex that a macro such as EXPECT_DEATH would use to test +// the output of statement. This parameter has to be +// compiled but not evaluated by this macro, to ensure that +// this macro only accepts expressions that a macro such as +// EXPECT_DEATH would accept. +// terminator - Must be an empty statement for EXPECT_DEATH_IF_SUPPORTED +// and a return statement for ASSERT_DEATH_IF_SUPPORTED. +// This ensures that ASSERT_DEATH_IF_SUPPORTED will not +// compile inside functions where ASSERT_DEATH doesn't +// compile. +// +// The branch that has an always false condition is used to ensure that +// statement and regex are compiled (and thus syntactically correct) but +// never executed. The unreachable code macro protects the terminator +// statement from generating an 'unreachable code' warning in case +// statement unconditionally returns or throws. The Message constructor at +// the end allows the syntax of streaming additional messages into the +// macro, for compilational compatibility with EXPECT_DEATH/ASSERT_DEATH. +# define GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, terminator) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::AlwaysTrue()) { \ + GTEST_LOG_(WARNING) \ + << "Death tests are not supported on this platform.\n" \ + << "Statement '" #statement "' cannot be verified."; \ + } else if (::testing::internal::AlwaysFalse()) { \ + ::testing::internal::RE::PartialMatch(".*", (regex)); \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + terminator; \ + } else \ + ::testing::Message() + +#endif // GTEST_HAS_DEATH_TEST + +} // namespace internal +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ + +namespace testing { + +// This flag controls the style of death tests. Valid values are "threadsafe", +// meaning that the death test child process will re-execute the test binary +// from the start, running only a single death test, or "fast", +// meaning that the child process will execute the test logic immediately +// after forking. +GTEST_DECLARE_string_(death_test_style); + +#if GTEST_HAS_DEATH_TEST + +namespace internal { + +// Returns a Boolean value indicating whether the caller is currently +// executing in the context of the death test child process. Tools such as +// Valgrind heap checkers may need this to modify their behavior in death +// tests. IMPORTANT: This is an internal utility. Using it may break the +// implementation of death tests. User code MUST NOT use it. +GTEST_API_ bool InDeathTestChild(); + +} // namespace internal + +// The following macros are useful for writing death tests. + +// Here's what happens when an ASSERT_DEATH* or EXPECT_DEATH* is +// executed: +// +// 1. It generates a warning if there is more than one active +// thread. This is because it's safe to fork() or clone() only +// when there is a single thread. +// +// 2. The parent process clone()s a sub-process and runs the death +// test in it; the sub-process exits with code 0 at the end of the +// death test, if it hasn't exited already. +// +// 3. The parent process waits for the sub-process to terminate. +// +// 4. The parent process checks the exit code and error message of +// the sub-process. +// +// Examples: +// +// ASSERT_DEATH(server.SendMessage(56, "Hello"), "Invalid port number"); +// for (int i = 0; i < 5; i++) { +// EXPECT_DEATH(server.ProcessRequest(i), +// "Invalid request .* in ProcessRequest()") +// << "Failed to die on request " << i; +// } +// +// ASSERT_EXIT(server.ExitNow(), ::testing::ExitedWithCode(0), "Exiting"); +// +// bool KilledBySIGHUP(int exit_code) { +// return WIFSIGNALED(exit_code) && WTERMSIG(exit_code) == SIGHUP; +// } +// +// ASSERT_EXIT(client.HangUpServer(), KilledBySIGHUP, "Hanging up!"); +// +// On the regular expressions used in death tests: +// +// On POSIX-compliant systems (*nix), we use the library, +// which uses the POSIX extended regex syntax. +// +// On other platforms (e.g. Windows), we only support a simple regex +// syntax implemented as part of Google Test. This limited +// implementation should be enough most of the time when writing +// death tests; though it lacks many features you can find in PCRE +// or POSIX extended regex syntax. For example, we don't support +// union ("x|y"), grouping ("(xy)"), brackets ("[xy]"), and +// repetition count ("x{5,7}"), among others. +// +// Below is the syntax that we do support. We chose it to be a +// subset of both PCRE and POSIX extended regex, so it's easy to +// learn wherever you come from. In the following: 'A' denotes a +// literal character, period (.), or a single \\ escape sequence; +// 'x' and 'y' denote regular expressions; 'm' and 'n' are for +// natural numbers. +// +// c matches any literal character c +// \\d matches any decimal digit +// \\D matches any character that's not a decimal digit +// \\f matches \f +// \\n matches \n +// \\r matches \r +// \\s matches any ASCII whitespace, including \n +// \\S matches any character that's not a whitespace +// \\t matches \t +// \\v matches \v +// \\w matches any letter, _, or decimal digit +// \\W matches any character that \\w doesn't match +// \\c matches any literal character c, which must be a punctuation +// . matches any single character except \n +// A? matches 0 or 1 occurrences of A +// A* matches 0 or many occurrences of A +// A+ matches 1 or many occurrences of A +// ^ matches the beginning of a string (not that of each line) +// $ matches the end of a string (not that of each line) +// xy matches x followed by y +// +// If you accidentally use PCRE or POSIX extended regex features +// not implemented by us, you will get a run-time failure. In that +// case, please try to rewrite your regular expression within the +// above syntax. +// +// This implementation is *not* meant to be as highly tuned or robust +// as a compiled regex library, but should perform well enough for a +// death test, which already incurs significant overhead by launching +// a child process. +// +// Known caveats: +// +// A "threadsafe" style death test obtains the path to the test +// program from argv[0] and re-executes it in the sub-process. For +// simplicity, the current implementation doesn't search the PATH +// when launching the sub-process. This means that the user must +// invoke the test program via a path that contains at least one +// path separator (e.g. path/to/foo_test and +// /absolute/path/to/bar_test are fine, but foo_test is not). This +// is rarely a problem as people usually don't put the test binary +// directory in PATH. +// +// TODO(wan@google.com): make thread-safe death tests search the PATH. + +// Asserts that a given statement causes the program to exit, with an +// integer exit status that satisfies predicate, and emitting error output +// that matches regex. +# define ASSERT_EXIT(statement, predicate, regex) \ + GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_FATAL_FAILURE_) + +// Like ASSERT_EXIT, but continues on to successive tests in the +// test case, if any: +# define EXPECT_EXIT(statement, predicate, regex) \ + GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_NONFATAL_FAILURE_) + +// Asserts that a given statement causes the program to exit, either by +// explicitly exiting with a nonzero exit code or being killed by a +// signal, and emitting error output that matches regex. +# define ASSERT_DEATH(statement, regex) \ + ASSERT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex) + +// Like ASSERT_DEATH, but continues on to successive tests in the +// test case, if any: +# define EXPECT_DEATH(statement, regex) \ + EXPECT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex) + +// Two predicate classes that can be used in {ASSERT,EXPECT}_EXIT*: + +// Tests that an exit code describes a normal exit with a given exit code. +class GTEST_API_ ExitedWithCode { + public: + explicit ExitedWithCode(int exit_code); + bool operator()(int exit_status) const; + private: + // No implementation - assignment is unsupported. + void operator=(const ExitedWithCode& other); + + const int exit_code_; +}; + +# if !GTEST_OS_WINDOWS +// Tests that an exit code describes an exit due to termination by a +// given signal. +class GTEST_API_ KilledBySignal { + public: + explicit KilledBySignal(int signum); + bool operator()(int exit_status) const; + private: + const int signum_; +}; +# endif // !GTEST_OS_WINDOWS + +// EXPECT_DEBUG_DEATH asserts that the given statements die in debug mode. +// The death testing framework causes this to have interesting semantics, +// since the sideeffects of the call are only visible in opt mode, and not +// in debug mode. +// +// In practice, this can be used to test functions that utilize the +// LOG(DFATAL) macro using the following style: +// +// int DieInDebugOr12(int* sideeffect) { +// if (sideeffect) { +// *sideeffect = 12; +// } +// LOG(DFATAL) << "death"; +// return 12; +// } +// +// TEST(TestCase, TestDieOr12WorksInDgbAndOpt) { +// int sideeffect = 0; +// // Only asserts in dbg. +// EXPECT_DEBUG_DEATH(DieInDebugOr12(&sideeffect), "death"); +// +// #ifdef NDEBUG +// // opt-mode has sideeffect visible. +// EXPECT_EQ(12, sideeffect); +// #else +// // dbg-mode no visible sideeffect. +// EXPECT_EQ(0, sideeffect); +// #endif +// } +// +// This will assert that DieInDebugReturn12InOpt() crashes in debug +// mode, usually due to a DCHECK or LOG(DFATAL), but returns the +// appropriate fallback value (12 in this case) in opt mode. If you +// need to test that a function has appropriate side-effects in opt +// mode, include assertions against the side-effects. A general +// pattern for this is: +// +// EXPECT_DEBUG_DEATH({ +// // Side-effects here will have an effect after this statement in +// // opt mode, but none in debug mode. +// EXPECT_EQ(12, DieInDebugOr12(&sideeffect)); +// }, "death"); +// +# ifdef NDEBUG + +# define EXPECT_DEBUG_DEATH(statement, regex) \ + GTEST_EXECUTE_STATEMENT_(statement, regex) + +# define ASSERT_DEBUG_DEATH(statement, regex) \ + GTEST_EXECUTE_STATEMENT_(statement, regex) + +# else + +# define EXPECT_DEBUG_DEATH(statement, regex) \ + EXPECT_DEATH(statement, regex) + +# define ASSERT_DEBUG_DEATH(statement, regex) \ + ASSERT_DEATH(statement, regex) + +# endif // NDEBUG for EXPECT_DEBUG_DEATH +#endif // GTEST_HAS_DEATH_TEST + +// EXPECT_DEATH_IF_SUPPORTED(statement, regex) and +// ASSERT_DEATH_IF_SUPPORTED(statement, regex) expand to real death tests if +// death tests are supported; otherwise they just issue a warning. This is +// useful when you are combining death test assertions with normal test +// assertions in one test. +#if GTEST_HAS_DEATH_TEST +# define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ + EXPECT_DEATH(statement, regex) +# define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \ + ASSERT_DEATH(statement, regex) +#else +# define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ + GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, ) +# define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \ + GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, return) +#endif + +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ +// This file was GENERATED by command: +// pump.py gtest-param-test.h.pump +// DO NOT EDIT BY HAND!!! + +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: vladl@google.com (Vlad Losev) +// +// Macros and functions for implementing parameterized tests +// in Google C++ Testing Framework (Google Test) +// +// This file is generated by a SCRIPT. DO NOT EDIT BY HAND! +// +#ifndef GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ +#define GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ + + +// Value-parameterized tests allow you to test your code with different +// parameters without writing multiple copies of the same test. +// +// Here is how you use value-parameterized tests: + +#if 0 + +// To write value-parameterized tests, first you should define a fixture +// class. It is usually derived from testing::TestWithParam (see below for +// another inheritance scheme that's sometimes useful in more complicated +// class hierarchies), where the type of your parameter values. +// TestWithParam is itself derived from testing::Test. T can be any +// copyable type. If it's a raw pointer, you are responsible for managing the +// lifespan of the pointed values. + +class FooTest : public ::testing::TestWithParam { + // You can implement all the usual class fixture members here. +}; + +// Then, use the TEST_P macro to define as many parameterized tests +// for this fixture as you want. The _P suffix is for "parameterized" +// or "pattern", whichever you prefer to think. + +TEST_P(FooTest, DoesBlah) { + // Inside a test, access the test parameter with the GetParam() method + // of the TestWithParam class: + EXPECT_TRUE(foo.Blah(GetParam())); + ... +} + +TEST_P(FooTest, HasBlahBlah) { + ... +} + +// Finally, you can use INSTANTIATE_TEST_CASE_P to instantiate the test +// case with any set of parameters you want. Google Test defines a number +// of functions for generating test parameters. They return what we call +// (surprise!) parameter generators. Here is a summary of them, which +// are all in the testing namespace: +// +// +// Range(begin, end [, step]) - Yields values {begin, begin+step, +// begin+step+step, ...}. The values do not +// include end. step defaults to 1. +// Values(v1, v2, ..., vN) - Yields values {v1, v2, ..., vN}. +// ValuesIn(container) - Yields values from a C-style array, an STL +// ValuesIn(begin,end) container, or an iterator range [begin, end). +// Bool() - Yields sequence {false, true}. +// Combine(g1, g2, ..., gN) - Yields all combinations (the Cartesian product +// for the math savvy) of the values generated +// by the N generators. +// +// For more details, see comments at the definitions of these functions below +// in this file. +// +// The following statement will instantiate tests from the FooTest test case +// each with parameter values "meeny", "miny", and "moe". + +INSTANTIATE_TEST_CASE_P(InstantiationName, + FooTest, + Values("meeny", "miny", "moe")); + +// To distinguish different instances of the pattern, (yes, you +// can instantiate it more then once) the first argument to the +// INSTANTIATE_TEST_CASE_P macro is a prefix that will be added to the +// actual test case name. Remember to pick unique prefixes for different +// instantiations. The tests from the instantiation above will have +// these names: +// +// * InstantiationName/FooTest.DoesBlah/0 for "meeny" +// * InstantiationName/FooTest.DoesBlah/1 for "miny" +// * InstantiationName/FooTest.DoesBlah/2 for "moe" +// * InstantiationName/FooTest.HasBlahBlah/0 for "meeny" +// * InstantiationName/FooTest.HasBlahBlah/1 for "miny" +// * InstantiationName/FooTest.HasBlahBlah/2 for "moe" +// +// You can use these names in --gtest_filter. +// +// This statement will instantiate all tests from FooTest again, each +// with parameter values "cat" and "dog": + +const char* pets[] = {"cat", "dog"}; +INSTANTIATE_TEST_CASE_P(AnotherInstantiationName, FooTest, ValuesIn(pets)); + +// The tests from the instantiation above will have these names: +// +// * AnotherInstantiationName/FooTest.DoesBlah/0 for "cat" +// * AnotherInstantiationName/FooTest.DoesBlah/1 for "dog" +// * AnotherInstantiationName/FooTest.HasBlahBlah/0 for "cat" +// * AnotherInstantiationName/FooTest.HasBlahBlah/1 for "dog" +// +// Please note that INSTANTIATE_TEST_CASE_P will instantiate all tests +// in the given test case, whether their definitions come before or +// AFTER the INSTANTIATE_TEST_CASE_P statement. +// +// Please also note that generator expressions (including parameters to the +// generators) are evaluated in InitGoogleTest(), after main() has started. +// This allows the user on one hand, to adjust generator parameters in order +// to dynamically determine a set of tests to run and on the other hand, +// give the user a chance to inspect the generated tests with Google Test +// reflection API before RUN_ALL_TESTS() is executed. +// +// You can see samples/sample7_unittest.cc and samples/sample8_unittest.cc +// for more examples. +// +// In the future, we plan to publish the API for defining new parameter +// generators. But for now this interface remains part of the internal +// implementation and is subject to change. +// +// +// A parameterized test fixture must be derived from testing::Test and from +// testing::WithParamInterface, where T is the type of the parameter +// values. Inheriting from TestWithParam satisfies that requirement because +// TestWithParam inherits from both Test and WithParamInterface. In more +// complicated hierarchies, however, it is occasionally useful to inherit +// separately from Test and WithParamInterface. For example: + +class BaseTest : public ::testing::Test { + // You can inherit all the usual members for a non-parameterized test + // fixture here. +}; + +class DerivedTest : public BaseTest, public ::testing::WithParamInterface { + // The usual test fixture members go here too. +}; + +TEST_F(BaseTest, HasFoo) { + // This is an ordinary non-parameterized test. +} + +TEST_P(DerivedTest, DoesBlah) { + // GetParam works just the same here as if you inherit from TestWithParam. + EXPECT_TRUE(foo.Blah(GetParam())); +} + +#endif // 0 + + +#if !GTEST_OS_SYMBIAN +# include +#endif + +// scripts/fuse_gtest.py depends on gtest's own header being #included +// *unconditionally*. Therefore these #includes cannot be moved +// inside #if GTEST_HAS_PARAM_TEST. +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: vladl@google.com (Vlad Losev) + +// Type and function utilities for implementing parameterized tests. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ + +#include +#include +#include + +// scripts/fuse_gtest.py depends on gtest's own header being #included +// *unconditionally*. Therefore these #includes cannot be moved +// inside #if GTEST_HAS_PARAM_TEST. +// Copyright 2003 Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Dan Egnor (egnor@google.com) +// +// A "smart" pointer type with reference tracking. Every pointer to a +// particular object is kept on a circular linked list. When the last pointer +// to an object is destroyed or reassigned, the object is deleted. +// +// Used properly, this deletes the object when the last reference goes away. +// There are several caveats: +// - Like all reference counting schemes, cycles lead to leaks. +// - Each smart pointer is actually two pointers (8 bytes instead of 4). +// - Every time a pointer is assigned, the entire list of pointers to that +// object is traversed. This class is therefore NOT SUITABLE when there +// will often be more than two or three pointers to a particular object. +// - References are only tracked as long as linked_ptr<> objects are copied. +// If a linked_ptr<> is converted to a raw pointer and back, BAD THINGS +// will happen (double deletion). +// +// A good use of this class is storing object references in STL containers. +// You can safely put linked_ptr<> in a vector<>. +// Other uses may not be as good. +// +// Note: If you use an incomplete type with linked_ptr<>, the class +// *containing* linked_ptr<> must have a constructor and destructor (even +// if they do nothing!). +// +// Bill Gibbons suggested we use something like this. +// +// Thread Safety: +// Unlike other linked_ptr implementations, in this implementation +// a linked_ptr object is thread-safe in the sense that: +// - it's safe to copy linked_ptr objects concurrently, +// - it's safe to copy *from* a linked_ptr and read its underlying +// raw pointer (e.g. via get()) concurrently, and +// - it's safe to write to two linked_ptrs that point to the same +// shared object concurrently. +// TODO(wan@google.com): rename this to safe_linked_ptr to avoid +// confusion with normal linked_ptr. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_ + +#include +#include + + +namespace testing { +namespace internal { + +// Protects copying of all linked_ptr objects. +GTEST_API_ GTEST_DECLARE_STATIC_MUTEX_(g_linked_ptr_mutex); + +// This is used internally by all instances of linked_ptr<>. It needs to be +// a non-template class because different types of linked_ptr<> can refer to +// the same object (linked_ptr(obj) vs linked_ptr(obj)). +// So, it needs to be possible for different types of linked_ptr to participate +// in the same circular linked list, so we need a single class type here. +// +// DO NOT USE THIS CLASS DIRECTLY YOURSELF. Use linked_ptr. +class linked_ptr_internal { + public: + // Create a new circle that includes only this instance. + void join_new() { + next_ = this; + } + + // Many linked_ptr operations may change p.link_ for some linked_ptr + // variable p in the same circle as this object. Therefore we need + // to prevent two such operations from occurring concurrently. + // + // Note that different types of linked_ptr objects can coexist in a + // circle (e.g. linked_ptr, linked_ptr, and + // linked_ptr). Therefore we must use a single mutex to + // protect all linked_ptr objects. This can create serious + // contention in production code, but is acceptable in a testing + // framework. + + // Join an existing circle. + void join(linked_ptr_internal const* ptr) + GTEST_LOCK_EXCLUDED_(g_linked_ptr_mutex) { + MutexLock lock(&g_linked_ptr_mutex); + + linked_ptr_internal const* p = ptr; + while (p->next_ != ptr) p = p->next_; + p->next_ = this; + next_ = ptr; + } + + // Leave whatever circle we're part of. Returns true if we were the + // last member of the circle. Once this is done, you can join() another. + bool depart() + GTEST_LOCK_EXCLUDED_(g_linked_ptr_mutex) { + MutexLock lock(&g_linked_ptr_mutex); + + if (next_ == this) return true; + linked_ptr_internal const* p = next_; + while (p->next_ != this) p = p->next_; + p->next_ = next_; + return false; + } + + private: + mutable linked_ptr_internal const* next_; +}; + +template +class linked_ptr { + public: + typedef T element_type; + + // Take over ownership of a raw pointer. This should happen as soon as + // possible after the object is created. + explicit linked_ptr(T* ptr = NULL) { capture(ptr); } + ~linked_ptr() { depart(); } + + // Copy an existing linked_ptr<>, adding ourselves to the list of references. + template linked_ptr(linked_ptr const& ptr) { copy(&ptr); } + linked_ptr(linked_ptr const& ptr) { // NOLINT + assert(&ptr != this); + copy(&ptr); + } + + // Assignment releases the old value and acquires the new. + template linked_ptr& operator=(linked_ptr const& ptr) { + depart(); + copy(&ptr); + return *this; + } + + linked_ptr& operator=(linked_ptr const& ptr) { + if (&ptr != this) { + depart(); + copy(&ptr); + } + return *this; + } + + // Smart pointer members. + void reset(T* ptr = NULL) { + depart(); + capture(ptr); + } + T* get() const { return value_; } + T* operator->() const { return value_; } + T& operator*() const { return *value_; } + + bool operator==(T* p) const { return value_ == p; } + bool operator!=(T* p) const { return value_ != p; } + template + bool operator==(linked_ptr const& ptr) const { + return value_ == ptr.get(); + } + template + bool operator!=(linked_ptr const& ptr) const { + return value_ != ptr.get(); + } + + private: + template + friend class linked_ptr; + + T* value_; + linked_ptr_internal link_; + + void depart() { + if (link_.depart()) delete value_; + } + + void capture(T* ptr) { + value_ = ptr; + link_.join_new(); + } + + template void copy(linked_ptr const* ptr) { + value_ = ptr->get(); + if (value_) + link_.join(&ptr->link_); + else + link_.join_new(); + } +}; + +template inline +bool operator==(T* ptr, const linked_ptr& x) { + return ptr == x.get(); +} + +template inline +bool operator!=(T* ptr, const linked_ptr& x) { + return ptr != x.get(); +} + +// A function to convert T* into linked_ptr +// Doing e.g. make_linked_ptr(new FooBarBaz(arg)) is a shorter notation +// for linked_ptr >(new FooBarBaz(arg)) +template +linked_ptr make_linked_ptr(T* ptr) { + return linked_ptr(ptr); +} + +} // namespace internal +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_ +// Copyright 2007, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) + +// Google Test - The Google C++ Testing Framework +// +// This file implements a universal value printer that can print a +// value of any type T: +// +// void ::testing::internal::UniversalPrinter::Print(value, ostream_ptr); +// +// A user can teach this function how to print a class type T by +// defining either operator<<() or PrintTo() in the namespace that +// defines T. More specifically, the FIRST defined function in the +// following list will be used (assuming T is defined in namespace +// foo): +// +// 1. foo::PrintTo(const T&, ostream*) +// 2. operator<<(ostream&, const T&) defined in either foo or the +// global namespace. +// +// If none of the above is defined, it will print the debug string of +// the value if it is a protocol buffer, or print the raw bytes in the +// value otherwise. +// +// To aid debugging: when T is a reference type, the address of the +// value is also printed; when T is a (const) char pointer, both the +// pointer value and the NUL-terminated string it points to are +// printed. +// +// We also provide some convenient wrappers: +// +// // Prints a value to a string. For a (const or not) char +// // pointer, the NUL-terminated string (but not the pointer) is +// // printed. +// std::string ::testing::PrintToString(const T& value); +// +// // Prints a value tersely: for a reference type, the referenced +// // value (but not the address) is printed; for a (const or not) char +// // pointer, the NUL-terminated string (but not the pointer) is +// // printed. +// void ::testing::internal::UniversalTersePrint(const T& value, ostream*); +// +// // Prints value using the type inferred by the compiler. The difference +// // from UniversalTersePrint() is that this function prints both the +// // pointer and the NUL-terminated string for a (const or not) char pointer. +// void ::testing::internal::UniversalPrint(const T& value, ostream*); +// +// // Prints the fields of a tuple tersely to a string vector, one +// // element for each field. Tuple support must be enabled in +// // gtest-port.h. +// std::vector UniversalTersePrintTupleFieldsToStrings( +// const Tuple& value); +// +// Known limitation: +// +// The print primitives print the elements of an STL-style container +// using the compiler-inferred type of *iter where iter is a +// const_iterator of the container. When const_iterator is an input +// iterator but not a forward iterator, this inferred type may not +// match value_type, and the print output may be incorrect. In +// practice, this is rarely a problem as for most containers +// const_iterator is a forward iterator. We'll fix this if there's an +// actual need for it. Note that this fix cannot rely on value_type +// being defined as many user-defined container types don't have +// value_type. + +#ifndef GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_ +#define GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_ + +#include // NOLINT +#include +#include +#include +#include + +namespace testing { + +// Definitions in the 'internal' and 'internal2' name spaces are +// subject to change without notice. DO NOT USE THEM IN USER CODE! +namespace internal2 { + +// Prints the given number of bytes in the given object to the given +// ostream. +GTEST_API_ void PrintBytesInObjectTo(const unsigned char* obj_bytes, + size_t count, + ::std::ostream* os); + +// For selecting which printer to use when a given type has neither << +// nor PrintTo(). +enum TypeKind { + kProtobuf, // a protobuf type + kConvertibleToInteger, // a type implicitly convertible to BiggestInt + // (e.g. a named or unnamed enum type) + kOtherType // anything else +}; + +// TypeWithoutFormatter::PrintValue(value, os) is called +// by the universal printer to print a value of type T when neither +// operator<< nor PrintTo() is defined for T, where kTypeKind is the +// "kind" of T as defined by enum TypeKind. +template +class TypeWithoutFormatter { + public: + // This default version is called when kTypeKind is kOtherType. + static void PrintValue(const T& value, ::std::ostream* os) { + PrintBytesInObjectTo(reinterpret_cast(&value), + sizeof(value), os); + } +}; + +// We print a protobuf using its ShortDebugString() when the string +// doesn't exceed this many characters; otherwise we print it using +// DebugString() for better readability. +const size_t kProtobufOneLinerMaxLength = 50; + +template +class TypeWithoutFormatter { + public: + static void PrintValue(const T& value, ::std::ostream* os) { + const ::testing::internal::string short_str = value.ShortDebugString(); + const ::testing::internal::string pretty_str = + short_str.length() <= kProtobufOneLinerMaxLength ? + short_str : ("\n" + value.DebugString()); + *os << ("<" + pretty_str + ">"); + } +}; + +template +class TypeWithoutFormatter { + public: + // Since T has no << operator or PrintTo() but can be implicitly + // converted to BiggestInt, we print it as a BiggestInt. + // + // Most likely T is an enum type (either named or unnamed), in which + // case printing it as an integer is the desired behavior. In case + // T is not an enum, printing it as an integer is the best we can do + // given that it has no user-defined printer. + static void PrintValue(const T& value, ::std::ostream* os) { + const internal::BiggestInt kBigInt = value; + *os << kBigInt; + } +}; + +// Prints the given value to the given ostream. If the value is a +// protocol message, its debug string is printed; if it's an enum or +// of a type implicitly convertible to BiggestInt, it's printed as an +// integer; otherwise the bytes in the value are printed. This is +// what UniversalPrinter::Print() does when it knows nothing about +// type T and T has neither << operator nor PrintTo(). +// +// A user can override this behavior for a class type Foo by defining +// a << operator in the namespace where Foo is defined. +// +// We put this operator in namespace 'internal2' instead of 'internal' +// to simplify the implementation, as much code in 'internal' needs to +// use << in STL, which would conflict with our own << were it defined +// in 'internal'. +// +// Note that this operator<< takes a generic std::basic_ostream type instead of the more restricted std::ostream. If +// we define it to take an std::ostream instead, we'll get an +// "ambiguous overloads" compiler error when trying to print a type +// Foo that supports streaming to std::basic_ostream, as the compiler cannot tell whether +// operator<<(std::ostream&, const T&) or +// operator<<(std::basic_stream, const Foo&) is more +// specific. +template +::std::basic_ostream& operator<<( + ::std::basic_ostream& os, const T& x) { + TypeWithoutFormatter::value ? kProtobuf : + internal::ImplicitlyConvertible::value ? + kConvertibleToInteger : kOtherType)>::PrintValue(x, &os); + return os; +} + +} // namespace internal2 +} // namespace testing + +// This namespace MUST NOT BE NESTED IN ::testing, or the name look-up +// magic needed for implementing UniversalPrinter won't work. +namespace testing_internal { + +// Used to print a value that is not an STL-style container when the +// user doesn't define PrintTo() for it. +template +void DefaultPrintNonContainerTo(const T& value, ::std::ostream* os) { + // With the following statement, during unqualified name lookup, + // testing::internal2::operator<< appears as if it was declared in + // the nearest enclosing namespace that contains both + // ::testing_internal and ::testing::internal2, i.e. the global + // namespace. For more details, refer to the C++ Standard section + // 7.3.4-1 [namespace.udir]. This allows us to fall back onto + // testing::internal2::operator<< in case T doesn't come with a << + // operator. + // + // We cannot write 'using ::testing::internal2::operator<<;', which + // gcc 3.3 fails to compile due to a compiler bug. + using namespace ::testing::internal2; // NOLINT + + // Assuming T is defined in namespace foo, in the next statement, + // the compiler will consider all of: + // + // 1. foo::operator<< (thanks to Koenig look-up), + // 2. ::operator<< (as the current namespace is enclosed in ::), + // 3. testing::internal2::operator<< (thanks to the using statement above). + // + // The operator<< whose type matches T best will be picked. + // + // We deliberately allow #2 to be a candidate, as sometimes it's + // impossible to define #1 (e.g. when foo is ::std, defining + // anything in it is undefined behavior unless you are a compiler + // vendor.). + *os << value; +} + +} // namespace testing_internal + +namespace testing { +namespace internal { + +// UniversalPrinter::Print(value, ostream_ptr) prints the given +// value to the given ostream. The caller must ensure that +// 'ostream_ptr' is not NULL, or the behavior is undefined. +// +// We define UniversalPrinter as a class template (as opposed to a +// function template), as we need to partially specialize it for +// reference types, which cannot be done with function templates. +template +class UniversalPrinter; + +template +void UniversalPrint(const T& value, ::std::ostream* os); + +// Used to print an STL-style container when the user doesn't define +// a PrintTo() for it. +template +void DefaultPrintTo(IsContainer /* dummy */, + false_type /* is not a pointer */, + const C& container, ::std::ostream* os) { + const size_t kMaxCount = 32; // The maximum number of elements to print. + *os << '{'; + size_t count = 0; + for (typename C::const_iterator it = container.begin(); + it != container.end(); ++it, ++count) { + if (count > 0) { + *os << ','; + if (count == kMaxCount) { // Enough has been printed. + *os << " ..."; + break; + } + } + *os << ' '; + // We cannot call PrintTo(*it, os) here as PrintTo() doesn't + // handle *it being a native array. + internal::UniversalPrint(*it, os); + } + + if (count > 0) { + *os << ' '; + } + *os << '}'; +} + +// Used to print a pointer that is neither a char pointer nor a member +// pointer, when the user doesn't define PrintTo() for it. (A member +// variable pointer or member function pointer doesn't really point to +// a location in the address space. Their representation is +// implementation-defined. Therefore they will be printed as raw +// bytes.) +template +void DefaultPrintTo(IsNotContainer /* dummy */, + true_type /* is a pointer */, + T* p, ::std::ostream* os) { + if (p == NULL) { + *os << "NULL"; + } else { + // C++ doesn't allow casting from a function pointer to any object + // pointer. + // + // IsTrue() silences warnings: "Condition is always true", + // "unreachable code". + if (IsTrue(ImplicitlyConvertible::value)) { + // T is not a function type. We just call << to print p, + // relying on ADL to pick up user-defined << for their pointer + // types, if any. + *os << p; + } else { + // T is a function type, so '*os << p' doesn't do what we want + // (it just prints p as bool). We want to print p as a const + // void*. However, we cannot cast it to const void* directly, + // even using reinterpret_cast, as earlier versions of gcc + // (e.g. 3.4.5) cannot compile the cast when p is a function + // pointer. Casting to UInt64 first solves the problem. + *os << reinterpret_cast( + reinterpret_cast(p)); + } + } +} + +// Used to print a non-container, non-pointer value when the user +// doesn't define PrintTo() for it. +template +void DefaultPrintTo(IsNotContainer /* dummy */, + false_type /* is not a pointer */, + const T& value, ::std::ostream* os) { + ::testing_internal::DefaultPrintNonContainerTo(value, os); +} + +// Prints the given value using the << operator if it has one; +// otherwise prints the bytes in it. This is what +// UniversalPrinter::Print() does when PrintTo() is not specialized +// or overloaded for type T. +// +// A user can override this behavior for a class type Foo by defining +// an overload of PrintTo() in the namespace where Foo is defined. We +// give the user this option as sometimes defining a << operator for +// Foo is not desirable (e.g. the coding style may prevent doing it, +// or there is already a << operator but it doesn't do what the user +// wants). +template +void PrintTo(const T& value, ::std::ostream* os) { + // DefaultPrintTo() is overloaded. The type of its first two + // arguments determine which version will be picked. If T is an + // STL-style container, the version for container will be called; if + // T is a pointer, the pointer version will be called; otherwise the + // generic version will be called. + // + // Note that we check for container types here, prior to we check + // for protocol message types in our operator<<. The rationale is: + // + // For protocol messages, we want to give people a chance to + // override Google Mock's format by defining a PrintTo() or + // operator<<. For STL containers, other formats can be + // incompatible with Google Mock's format for the container + // elements; therefore we check for container types here to ensure + // that our format is used. + // + // The second argument of DefaultPrintTo() is needed to bypass a bug + // in Symbian's C++ compiler that prevents it from picking the right + // overload between: + // + // PrintTo(const T& x, ...); + // PrintTo(T* x, ...); + DefaultPrintTo(IsContainerTest(0), is_pointer(), value, os); +} + +// The following list of PrintTo() overloads tells +// UniversalPrinter::Print() how to print standard types (built-in +// types, strings, plain arrays, and pointers). + +// Overloads for various char types. +GTEST_API_ void PrintTo(unsigned char c, ::std::ostream* os); +GTEST_API_ void PrintTo(signed char c, ::std::ostream* os); +inline void PrintTo(char c, ::std::ostream* os) { + // When printing a plain char, we always treat it as unsigned. This + // way, the output won't be affected by whether the compiler thinks + // char is signed or not. + PrintTo(static_cast(c), os); +} + +// Overloads for other simple built-in types. +inline void PrintTo(bool x, ::std::ostream* os) { + *os << (x ? "true" : "false"); +} + +// Overload for wchar_t type. +// Prints a wchar_t as a symbol if it is printable or as its internal +// code otherwise and also as its decimal code (except for L'\0'). +// The L'\0' char is printed as "L'\\0'". The decimal code is printed +// as signed integer when wchar_t is implemented by the compiler +// as a signed type and is printed as an unsigned integer when wchar_t +// is implemented as an unsigned type. +GTEST_API_ void PrintTo(wchar_t wc, ::std::ostream* os); + +// Overloads for C strings. +GTEST_API_ void PrintTo(const char* s, ::std::ostream* os); +inline void PrintTo(char* s, ::std::ostream* os) { + PrintTo(ImplicitCast_(s), os); +} + +// signed/unsigned char is often used for representing binary data, so +// we print pointers to it as void* to be safe. +inline void PrintTo(const signed char* s, ::std::ostream* os) { + PrintTo(ImplicitCast_(s), os); +} +inline void PrintTo(signed char* s, ::std::ostream* os) { + PrintTo(ImplicitCast_(s), os); +} +inline void PrintTo(const unsigned char* s, ::std::ostream* os) { + PrintTo(ImplicitCast_(s), os); +} +inline void PrintTo(unsigned char* s, ::std::ostream* os) { + PrintTo(ImplicitCast_(s), os); +} + +// MSVC can be configured to define wchar_t as a typedef of unsigned +// short. It defines _NATIVE_WCHAR_T_DEFINED when wchar_t is a native +// type. When wchar_t is a typedef, defining an overload for const +// wchar_t* would cause unsigned short* be printed as a wide string, +// possibly causing invalid memory accesses. +#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) +// Overloads for wide C strings +GTEST_API_ void PrintTo(const wchar_t* s, ::std::ostream* os); +inline void PrintTo(wchar_t* s, ::std::ostream* os) { + PrintTo(ImplicitCast_(s), os); +} +#endif + +// Overload for C arrays. Multi-dimensional arrays are printed +// properly. + +// Prints the given number of elements in an array, without printing +// the curly braces. +template +void PrintRawArrayTo(const T a[], size_t count, ::std::ostream* os) { + UniversalPrint(a[0], os); + for (size_t i = 1; i != count; i++) { + *os << ", "; + UniversalPrint(a[i], os); + } +} + +// Overloads for ::string and ::std::string. +#if GTEST_HAS_GLOBAL_STRING +GTEST_API_ void PrintStringTo(const ::string&s, ::std::ostream* os); +inline void PrintTo(const ::string& s, ::std::ostream* os) { + PrintStringTo(s, os); +} +#endif // GTEST_HAS_GLOBAL_STRING + +GTEST_API_ void PrintStringTo(const ::std::string&s, ::std::ostream* os); +inline void PrintTo(const ::std::string& s, ::std::ostream* os) { + PrintStringTo(s, os); +} + +// Overloads for ::wstring and ::std::wstring. +#if GTEST_HAS_GLOBAL_WSTRING +GTEST_API_ void PrintWideStringTo(const ::wstring&s, ::std::ostream* os); +inline void PrintTo(const ::wstring& s, ::std::ostream* os) { + PrintWideStringTo(s, os); +} +#endif // GTEST_HAS_GLOBAL_WSTRING + +#if GTEST_HAS_STD_WSTRING +GTEST_API_ void PrintWideStringTo(const ::std::wstring&s, ::std::ostream* os); +inline void PrintTo(const ::std::wstring& s, ::std::ostream* os) { + PrintWideStringTo(s, os); +} +#endif // GTEST_HAS_STD_WSTRING + +#if GTEST_HAS_TR1_TUPLE +// Overload for ::std::tr1::tuple. Needed for printing function arguments, +// which are packed as tuples. + +// Helper function for printing a tuple. T must be instantiated with +// a tuple type. +template +void PrintTupleTo(const T& t, ::std::ostream* os); + +// Overloaded PrintTo() for tuples of various arities. We support +// tuples of up-to 10 fields. The following implementation works +// regardless of whether tr1::tuple is implemented using the +// non-standard variadic template feature or not. + +inline void PrintTo(const ::std::tr1::tuple<>& t, ::std::ostream* os) { + PrintTupleTo(t, os); +} + +template +void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { + PrintTupleTo(t, os); +} + +template +void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { + PrintTupleTo(t, os); +} + +template +void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { + PrintTupleTo(t, os); +} + +template +void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { + PrintTupleTo(t, os); +} + +template +void PrintTo(const ::std::tr1::tuple& t, + ::std::ostream* os) { + PrintTupleTo(t, os); +} + +template +void PrintTo(const ::std::tr1::tuple& t, + ::std::ostream* os) { + PrintTupleTo(t, os); +} + +template +void PrintTo(const ::std::tr1::tuple& t, + ::std::ostream* os) { + PrintTupleTo(t, os); +} + +template +void PrintTo(const ::std::tr1::tuple& t, + ::std::ostream* os) { + PrintTupleTo(t, os); +} + +template +void PrintTo(const ::std::tr1::tuple& t, + ::std::ostream* os) { + PrintTupleTo(t, os); +} + +template +void PrintTo( + const ::std::tr1::tuple& t, + ::std::ostream* os) { + PrintTupleTo(t, os); +} +#endif // GTEST_HAS_TR1_TUPLE + +// Overload for std::pair. +template +void PrintTo(const ::std::pair& value, ::std::ostream* os) { + *os << '('; + // We cannot use UniversalPrint(value.first, os) here, as T1 may be + // a reference type. The same for printing value.second. + UniversalPrinter::Print(value.first, os); + *os << ", "; + UniversalPrinter::Print(value.second, os); + *os << ')'; +} + +// Implements printing a non-reference type T by letting the compiler +// pick the right overload of PrintTo() for T. +template +class UniversalPrinter { + public: + // MSVC warns about adding const to a function type, so we want to + // disable the warning. +#ifdef _MSC_VER +# pragma warning(push) // Saves the current warning state. +# pragma warning(disable:4180) // Temporarily disables warning 4180. +#endif // _MSC_VER + + // Note: we deliberately don't call this PrintTo(), as that name + // conflicts with ::testing::internal::PrintTo in the body of the + // function. + static void Print(const T& value, ::std::ostream* os) { + // By default, ::testing::internal::PrintTo() is used for printing + // the value. + // + // Thanks to Koenig look-up, if T is a class and has its own + // PrintTo() function defined in its namespace, that function will + // be visible here. Since it is more specific than the generic ones + // in ::testing::internal, it will be picked by the compiler in the + // following statement - exactly what we want. + PrintTo(value, os); + } + +#ifdef _MSC_VER +# pragma warning(pop) // Restores the warning state. +#endif // _MSC_VER +}; + +// UniversalPrintArray(begin, len, os) prints an array of 'len' +// elements, starting at address 'begin'. +template +void UniversalPrintArray(const T* begin, size_t len, ::std::ostream* os) { + if (len == 0) { + *os << "{}"; + } else { + *os << "{ "; + const size_t kThreshold = 18; + const size_t kChunkSize = 8; + // If the array has more than kThreshold elements, we'll have to + // omit some details by printing only the first and the last + // kChunkSize elements. + // TODO(wan@google.com): let the user control the threshold using a flag. + if (len <= kThreshold) { + PrintRawArrayTo(begin, len, os); + } else { + PrintRawArrayTo(begin, kChunkSize, os); + *os << ", ..., "; + PrintRawArrayTo(begin + len - kChunkSize, kChunkSize, os); + } + *os << " }"; + } +} +// This overload prints a (const) char array compactly. +GTEST_API_ void UniversalPrintArray( + const char* begin, size_t len, ::std::ostream* os); + +// This overload prints a (const) wchar_t array compactly. +GTEST_API_ void UniversalPrintArray( + const wchar_t* begin, size_t len, ::std::ostream* os); + +// Implements printing an array type T[N]. +template +class UniversalPrinter { + public: + // Prints the given array, omitting some elements when there are too + // many. + static void Print(const T (&a)[N], ::std::ostream* os) { + UniversalPrintArray(a, N, os); + } +}; + +// Implements printing a reference type T&. +template +class UniversalPrinter { + public: + // MSVC warns about adding const to a function type, so we want to + // disable the warning. +#ifdef _MSC_VER +# pragma warning(push) // Saves the current warning state. +# pragma warning(disable:4180) // Temporarily disables warning 4180. +#endif // _MSC_VER + + static void Print(const T& value, ::std::ostream* os) { + // Prints the address of the value. We use reinterpret_cast here + // as static_cast doesn't compile when T is a function type. + *os << "@" << reinterpret_cast(&value) << " "; + + // Then prints the value itself. + UniversalPrint(value, os); + } + +#ifdef _MSC_VER +# pragma warning(pop) // Restores the warning state. +#endif // _MSC_VER +}; + +// Prints a value tersely: for a reference type, the referenced value +// (but not the address) is printed; for a (const) char pointer, the +// NUL-terminated string (but not the pointer) is printed. + +template +class UniversalTersePrinter { + public: + static void Print(const T& value, ::std::ostream* os) { + UniversalPrint(value, os); + } +}; +template +class UniversalTersePrinter { + public: + static void Print(const T& value, ::std::ostream* os) { + UniversalPrint(value, os); + } +}; +template +class UniversalTersePrinter { + public: + static void Print(const T (&value)[N], ::std::ostream* os) { + UniversalPrinter::Print(value, os); + } +}; +template <> +class UniversalTersePrinter { + public: + static void Print(const char* str, ::std::ostream* os) { + if (str == NULL) { + *os << "NULL"; + } else { + UniversalPrint(string(str), os); + } + } +}; +template <> +class UniversalTersePrinter { + public: + static void Print(char* str, ::std::ostream* os) { + UniversalTersePrinter::Print(str, os); + } +}; + +#if GTEST_HAS_STD_WSTRING +template <> +class UniversalTersePrinter { + public: + static void Print(const wchar_t* str, ::std::ostream* os) { + if (str == NULL) { + *os << "NULL"; + } else { + UniversalPrint(::std::wstring(str), os); + } + } +}; +#endif + +template <> +class UniversalTersePrinter { + public: + static void Print(wchar_t* str, ::std::ostream* os) { + UniversalTersePrinter::Print(str, os); + } +}; + +template +void UniversalTersePrint(const T& value, ::std::ostream* os) { + UniversalTersePrinter::Print(value, os); +} + +// Prints a value using the type inferred by the compiler. The +// difference between this and UniversalTersePrint() is that for a +// (const) char pointer, this prints both the pointer and the +// NUL-terminated string. +template +void UniversalPrint(const T& value, ::std::ostream* os) { + // A workarond for the bug in VC++ 7.1 that prevents us from instantiating + // UniversalPrinter with T directly. + typedef T T1; + UniversalPrinter::Print(value, os); +} + +#if GTEST_HAS_TR1_TUPLE +typedef ::std::vector Strings; + +// This helper template allows PrintTo() for tuples and +// UniversalTersePrintTupleFieldsToStrings() to be defined by +// induction on the number of tuple fields. The idea is that +// TuplePrefixPrinter::PrintPrefixTo(t, os) prints the first N +// fields in tuple t, and can be defined in terms of +// TuplePrefixPrinter. + +// The inductive case. +template +struct TuplePrefixPrinter { + // Prints the first N fields of a tuple. + template + static void PrintPrefixTo(const Tuple& t, ::std::ostream* os) { + TuplePrefixPrinter::PrintPrefixTo(t, os); + *os << ", "; + UniversalPrinter::type> + ::Print(::std::tr1::get(t), os); + } + + // Tersely prints the first N fields of a tuple to a string vector, + // one element for each field. + template + static void TersePrintPrefixToStrings(const Tuple& t, Strings* strings) { + TuplePrefixPrinter::TersePrintPrefixToStrings(t, strings); + ::std::stringstream ss; + UniversalTersePrint(::std::tr1::get(t), &ss); + strings->push_back(ss.str()); + } +}; + +// Base cases. +template <> +struct TuplePrefixPrinter<0> { + template + static void PrintPrefixTo(const Tuple&, ::std::ostream*) {} + + template + static void TersePrintPrefixToStrings(const Tuple&, Strings*) {} +}; +// We have to specialize the entire TuplePrefixPrinter<> class +// template here, even though the definition of +// TersePrintPrefixToStrings() is the same as the generic version, as +// Embarcadero (formerly CodeGear, formerly Borland) C++ doesn't +// support specializing a method template of a class template. +template <> +struct TuplePrefixPrinter<1> { + template + static void PrintPrefixTo(const Tuple& t, ::std::ostream* os) { + UniversalPrinter::type>:: + Print(::std::tr1::get<0>(t), os); + } + + template + static void TersePrintPrefixToStrings(const Tuple& t, Strings* strings) { + ::std::stringstream ss; + UniversalTersePrint(::std::tr1::get<0>(t), &ss); + strings->push_back(ss.str()); + } +}; + +// Helper function for printing a tuple. T must be instantiated with +// a tuple type. +template +void PrintTupleTo(const T& t, ::std::ostream* os) { + *os << "("; + TuplePrefixPrinter< ::std::tr1::tuple_size::value>:: + PrintPrefixTo(t, os); + *os << ")"; +} + +// Prints the fields of a tuple tersely to a string vector, one +// element for each field. See the comment before +// UniversalTersePrint() for how we define "tersely". +template +Strings UniversalTersePrintTupleFieldsToStrings(const Tuple& value) { + Strings result; + TuplePrefixPrinter< ::std::tr1::tuple_size::value>:: + TersePrintPrefixToStrings(value, &result); + return result; +} +#endif // GTEST_HAS_TR1_TUPLE + +} // namespace internal + +template +::std::string PrintToString(const T& value) { + ::std::stringstream ss; + internal::UniversalTersePrinter::Print(value, &ss); + return ss.str(); +} + +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_ + +#if GTEST_HAS_PARAM_TEST + +namespace testing { +namespace internal { + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Outputs a message explaining invalid registration of different +// fixture class for the same test case. This may happen when +// TEST_P macro is used to define two tests with the same name +// but in different namespaces. +GTEST_API_ void ReportInvalidTestCaseType(const char* test_case_name, + const char* file, int line); + +template class ParamGeneratorInterface; +template class ParamGenerator; + +// Interface for iterating over elements provided by an implementation +// of ParamGeneratorInterface. +template +class ParamIteratorInterface { + public: + virtual ~ParamIteratorInterface() {} + // A pointer to the base generator instance. + // Used only for the purposes of iterator comparison + // to make sure that two iterators belong to the same generator. + virtual const ParamGeneratorInterface* BaseGenerator() const = 0; + // Advances iterator to point to the next element + // provided by the generator. The caller is responsible + // for not calling Advance() on an iterator equal to + // BaseGenerator()->End(). + virtual void Advance() = 0; + // Clones the iterator object. Used for implementing copy semantics + // of ParamIterator. + virtual ParamIteratorInterface* Clone() const = 0; + // Dereferences the current iterator and provides (read-only) access + // to the pointed value. It is the caller's responsibility not to call + // Current() on an iterator equal to BaseGenerator()->End(). + // Used for implementing ParamGenerator::operator*(). + virtual const T* Current() const = 0; + // Determines whether the given iterator and other point to the same + // element in the sequence generated by the generator. + // Used for implementing ParamGenerator::operator==(). + virtual bool Equals(const ParamIteratorInterface& other) const = 0; +}; + +// Class iterating over elements provided by an implementation of +// ParamGeneratorInterface. It wraps ParamIteratorInterface +// and implements the const forward iterator concept. +template +class ParamIterator { + public: + typedef T value_type; + typedef const T& reference; + typedef ptrdiff_t difference_type; + + // ParamIterator assumes ownership of the impl_ pointer. + ParamIterator(const ParamIterator& other) : impl_(other.impl_->Clone()) {} + ParamIterator& operator=(const ParamIterator& other) { + if (this != &other) + impl_.reset(other.impl_->Clone()); + return *this; + } + + const T& operator*() const { return *impl_->Current(); } + const T* operator->() const { return impl_->Current(); } + // Prefix version of operator++. + ParamIterator& operator++() { + impl_->Advance(); + return *this; + } + // Postfix version of operator++. + ParamIterator operator++(int /*unused*/) { + ParamIteratorInterface* clone = impl_->Clone(); + impl_->Advance(); + return ParamIterator(clone); + } + bool operator==(const ParamIterator& other) const { + return impl_.get() == other.impl_.get() || impl_->Equals(*other.impl_); + } + bool operator!=(const ParamIterator& other) const { + return !(*this == other); + } + + private: + friend class ParamGenerator; + explicit ParamIterator(ParamIteratorInterface* impl) : impl_(impl) {} + scoped_ptr > impl_; +}; + +// ParamGeneratorInterface is the binary interface to access generators +// defined in other translation units. +template +class ParamGeneratorInterface { + public: + typedef T ParamType; + + virtual ~ParamGeneratorInterface() {} + + // Generator interface definition + virtual ParamIteratorInterface* Begin() const = 0; + virtual ParamIteratorInterface* End() const = 0; +}; + +// Wraps ParamGeneratorInterface and provides general generator syntax +// compatible with the STL Container concept. +// This class implements copy initialization semantics and the contained +// ParamGeneratorInterface instance is shared among all copies +// of the original object. This is possible because that instance is immutable. +template +class ParamGenerator { + public: + typedef ParamIterator iterator; + + explicit ParamGenerator(ParamGeneratorInterface* impl) : impl_(impl) {} + ParamGenerator(const ParamGenerator& other) : impl_(other.impl_) {} + + ParamGenerator& operator=(const ParamGenerator& other) { + impl_ = other.impl_; + return *this; + } + + iterator begin() const { return iterator(impl_->Begin()); } + iterator end() const { return iterator(impl_->End()); } + + private: + linked_ptr > impl_; +}; + +// Generates values from a range of two comparable values. Can be used to +// generate sequences of user-defined types that implement operator+() and +// operator<(). +// This class is used in the Range() function. +template +class RangeGenerator : public ParamGeneratorInterface { + public: + RangeGenerator(T begin, T end, IncrementT step) + : begin_(begin), end_(end), + step_(step), end_index_(CalculateEndIndex(begin, end, step)) {} + virtual ~RangeGenerator() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, begin_, 0, step_); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, end_, end_index_, step_); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, T value, int index, + IncrementT step) + : base_(base), value_(value), index_(index), step_(step) {} + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + virtual void Advance() { + value_ = value_ + step_; + index_++; + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const T* Current() const { return &value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const int other_index = + CheckedDowncastToActualType(&other)->index_; + return index_ == other_index; + } + + private: + Iterator(const Iterator& other) + : ParamIteratorInterface(), + base_(other.base_), value_(other.value_), index_(other.index_), + step_(other.step_) {} + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + T value_; + int index_; + const IncrementT step_; + }; // class RangeGenerator::Iterator + + static int CalculateEndIndex(const T& begin, + const T& end, + const IncrementT& step) { + int end_index = 0; + for (T i = begin; i < end; i = i + step) + end_index++; + return end_index; + } + + // No implementation - assignment is unsupported. + void operator=(const RangeGenerator& other); + + const T begin_; + const T end_; + const IncrementT step_; + // The index for the end() iterator. All the elements in the generated + // sequence are indexed (0-based) to aid iterator comparison. + const int end_index_; +}; // class RangeGenerator + + +// Generates values from a pair of STL-style iterators. Used in the +// ValuesIn() function. The elements are copied from the source range +// since the source can be located on the stack, and the generator +// is likely to persist beyond that stack frame. +template +class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface { + public: + template + ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end) + : container_(begin, end) {} + virtual ~ValuesInIteratorRangeGenerator() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, container_.begin()); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, container_.end()); + } + + private: + typedef typename ::std::vector ContainerType; + + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + typename ContainerType::const_iterator iterator) + : base_(base), iterator_(iterator) {} + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + virtual void Advance() { + ++iterator_; + value_.reset(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + // We need to use cached value referenced by iterator_ because *iterator_ + // can return a temporary object (and of type other then T), so just + // having "return &*iterator_;" doesn't work. + // value_ is updated here and not in Advance() because Advance() + // can advance iterator_ beyond the end of the range, and we cannot + // detect that fact. The client code, on the other hand, is + // responsible for not calling Current() on an out-of-range iterator. + virtual const T* Current() const { + if (value_.get() == NULL) + value_.reset(new T(*iterator_)); + return value_.get(); + } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + return iterator_ == + CheckedDowncastToActualType(&other)->iterator_; + } + + private: + Iterator(const Iterator& other) + // The explicit constructor call suppresses a false warning + // emitted by gcc when supplied with the -Wextra option. + : ParamIteratorInterface(), + base_(other.base_), + iterator_(other.iterator_) {} + + const ParamGeneratorInterface* const base_; + typename ContainerType::const_iterator iterator_; + // A cached value of *iterator_. We keep it here to allow access by + // pointer in the wrapping iterator's operator->(). + // value_ needs to be mutable to be accessed in Current(). + // Use of scoped_ptr helps manage cached value's lifetime, + // which is bound by the lifespan of the iterator itself. + mutable scoped_ptr value_; + }; // class ValuesInIteratorRangeGenerator::Iterator + + // No implementation - assignment is unsupported. + void operator=(const ValuesInIteratorRangeGenerator& other); + + const ContainerType container_; +}; // class ValuesInIteratorRangeGenerator + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Stores a parameter value and later creates tests parameterized with that +// value. +template +class ParameterizedTestFactory : public TestFactoryBase { + public: + typedef typename TestClass::ParamType ParamType; + explicit ParameterizedTestFactory(ParamType parameter) : + parameter_(parameter) {} + virtual Test* CreateTest() { + TestClass::SetParam(¶meter_); + return new TestClass(); + } + + private: + const ParamType parameter_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestFactory); +}; + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// TestMetaFactoryBase is a base class for meta-factories that create +// test factories for passing into MakeAndRegisterTestInfo function. +template +class TestMetaFactoryBase { + public: + virtual ~TestMetaFactoryBase() {} + + virtual TestFactoryBase* CreateTestFactory(ParamType parameter) = 0; +}; + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// TestMetaFactory creates test factories for passing into +// MakeAndRegisterTestInfo function. Since MakeAndRegisterTestInfo receives +// ownership of test factory pointer, same factory object cannot be passed +// into that method twice. But ParameterizedTestCaseInfo is going to call +// it for each Test/Parameter value combination. Thus it needs meta factory +// creator class. +template +class TestMetaFactory + : public TestMetaFactoryBase { + public: + typedef typename TestCase::ParamType ParamType; + + TestMetaFactory() {} + + virtual TestFactoryBase* CreateTestFactory(ParamType parameter) { + return new ParameterizedTestFactory(parameter); + } + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestMetaFactory); +}; + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// ParameterizedTestCaseInfoBase is a generic interface +// to ParameterizedTestCaseInfo classes. ParameterizedTestCaseInfoBase +// accumulates test information provided by TEST_P macro invocations +// and generators provided by INSTANTIATE_TEST_CASE_P macro invocations +// and uses that information to register all resulting test instances +// in RegisterTests method. The ParameterizeTestCaseRegistry class holds +// a collection of pointers to the ParameterizedTestCaseInfo objects +// and calls RegisterTests() on each of them when asked. +class ParameterizedTestCaseInfoBase { + public: + virtual ~ParameterizedTestCaseInfoBase() {} + + // Base part of test case name for display purposes. + virtual const string& GetTestCaseName() const = 0; + // Test case id to verify identity. + virtual TypeId GetTestCaseTypeId() const = 0; + // UnitTest class invokes this method to register tests in this + // test case right before running them in RUN_ALL_TESTS macro. + // This method should not be called more then once on any single + // instance of a ParameterizedTestCaseInfoBase derived class. + virtual void RegisterTests() = 0; + + protected: + ParameterizedTestCaseInfoBase() {} + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfoBase); +}; + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// ParameterizedTestCaseInfo accumulates tests obtained from TEST_P +// macro invocations for a particular test case and generators +// obtained from INSTANTIATE_TEST_CASE_P macro invocations for that +// test case. It registers tests with all values generated by all +// generators when asked. +template +class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase { + public: + // ParamType and GeneratorCreationFunc are private types but are required + // for declarations of public methods AddTestPattern() and + // AddTestCaseInstantiation(). + typedef typename TestCase::ParamType ParamType; + // A function that returns an instance of appropriate generator type. + typedef ParamGenerator(GeneratorCreationFunc)(); + + explicit ParameterizedTestCaseInfo(const char* name) + : test_case_name_(name) {} + + // Test case base name for display purposes. + virtual const string& GetTestCaseName() const { return test_case_name_; } + // Test case id to verify identity. + virtual TypeId GetTestCaseTypeId() const { return GetTypeId(); } + // TEST_P macro uses AddTestPattern() to record information + // about a single test in a LocalTestInfo structure. + // test_case_name is the base name of the test case (without invocation + // prefix). test_base_name is the name of an individual test without + // parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is + // test case base name and DoBar is test base name. + void AddTestPattern(const char* test_case_name, + const char* test_base_name, + TestMetaFactoryBase* meta_factory) { + tests_.push_back(linked_ptr(new TestInfo(test_case_name, + test_base_name, + meta_factory))); + } + // INSTANTIATE_TEST_CASE_P macro uses AddGenerator() to record information + // about a generator. + int AddTestCaseInstantiation(const string& instantiation_name, + GeneratorCreationFunc* func, + const char* /* file */, + int /* line */) { + instantiations_.push_back(::std::make_pair(instantiation_name, func)); + return 0; // Return value used only to run this method in namespace scope. + } + // UnitTest class invokes this method to register tests in this test case + // test cases right before running tests in RUN_ALL_TESTS macro. + // This method should not be called more then once on any single + // instance of a ParameterizedTestCaseInfoBase derived class. + // UnitTest has a guard to prevent from calling this method more then once. + virtual void RegisterTests() { + for (typename TestInfoContainer::iterator test_it = tests_.begin(); + test_it != tests_.end(); ++test_it) { + linked_ptr test_info = *test_it; + for (typename InstantiationContainer::iterator gen_it = + instantiations_.begin(); gen_it != instantiations_.end(); + ++gen_it) { + const string& instantiation_name = gen_it->first; + ParamGenerator generator((*gen_it->second)()); + + string test_case_name; + if ( !instantiation_name.empty() ) + test_case_name = instantiation_name + "/"; + test_case_name += test_info->test_case_base_name; + + int i = 0; + for (typename ParamGenerator::iterator param_it = + generator.begin(); + param_it != generator.end(); ++param_it, ++i) { + Message test_name_stream; + test_name_stream << test_info->test_base_name << "/" << i; + MakeAndRegisterTestInfo( + test_case_name.c_str(), + test_name_stream.GetString().c_str(), + NULL, // No type parameter. + PrintToString(*param_it).c_str(), + GetTestCaseTypeId(), + TestCase::SetUpTestCase, + TestCase::TearDownTestCase, + test_info->test_meta_factory->CreateTestFactory(*param_it)); + } // for param_it + } // for gen_it + } // for test_it + } // RegisterTests + + private: + // LocalTestInfo structure keeps information about a single test registered + // with TEST_P macro. + struct TestInfo { + TestInfo(const char* a_test_case_base_name, + const char* a_test_base_name, + TestMetaFactoryBase* a_test_meta_factory) : + test_case_base_name(a_test_case_base_name), + test_base_name(a_test_base_name), + test_meta_factory(a_test_meta_factory) {} + + const string test_case_base_name; + const string test_base_name; + const scoped_ptr > test_meta_factory; + }; + typedef ::std::vector > TestInfoContainer; + // Keeps pairs of + // received from INSTANTIATE_TEST_CASE_P macros. + typedef ::std::vector > + InstantiationContainer; + + const string test_case_name_; + TestInfoContainer tests_; + InstantiationContainer instantiations_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfo); +}; // class ParameterizedTestCaseInfo + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// ParameterizedTestCaseRegistry contains a map of ParameterizedTestCaseInfoBase +// classes accessed by test case names. TEST_P and INSTANTIATE_TEST_CASE_P +// macros use it to locate their corresponding ParameterizedTestCaseInfo +// descriptors. +class ParameterizedTestCaseRegistry { + public: + ParameterizedTestCaseRegistry() {} + ~ParameterizedTestCaseRegistry() { + for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); + it != test_case_infos_.end(); ++it) { + delete *it; + } + } + + // Looks up or creates and returns a structure containing information about + // tests and instantiations of a particular test case. + template + ParameterizedTestCaseInfo* GetTestCasePatternHolder( + const char* test_case_name, + const char* file, + int line) { + ParameterizedTestCaseInfo* typed_test_info = NULL; + for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); + it != test_case_infos_.end(); ++it) { + if ((*it)->GetTestCaseName() == test_case_name) { + if ((*it)->GetTestCaseTypeId() != GetTypeId()) { + // Complain about incorrect usage of Google Test facilities + // and terminate the program since we cannot guaranty correct + // test case setup and tear-down in this case. + ReportInvalidTestCaseType(test_case_name, file, line); + posix::Abort(); + } else { + // At this point we are sure that the object we found is of the same + // type we are looking for, so we downcast it to that type + // without further checks. + typed_test_info = CheckedDowncastToActualType< + ParameterizedTestCaseInfo >(*it); + } + break; + } + } + if (typed_test_info == NULL) { + typed_test_info = new ParameterizedTestCaseInfo(test_case_name); + test_case_infos_.push_back(typed_test_info); + } + return typed_test_info; + } + void RegisterTests() { + for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); + it != test_case_infos_.end(); ++it) { + (*it)->RegisterTests(); + } + } + + private: + typedef ::std::vector TestCaseInfoContainer; + + TestCaseInfoContainer test_case_infos_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseRegistry); +}; + +} // namespace internal +} // namespace testing + +#endif // GTEST_HAS_PARAM_TEST + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ +// This file was GENERATED by command: +// pump.py gtest-param-util-generated.h.pump +// DO NOT EDIT BY HAND!!! + +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: vladl@google.com (Vlad Losev) + +// Type and function utilities for implementing parameterized tests. +// This file is generated by a SCRIPT. DO NOT EDIT BY HAND! +// +// Currently Google Test supports at most 50 arguments in Values, +// and at most 10 arguments in Combine. Please contact +// googletestframework@googlegroups.com if you need more. +// Please note that the number of arguments to Combine is limited +// by the maximum arity of the implementation of tr1::tuple which is +// currently set at 10. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ + +// scripts/fuse_gtest.py depends on gtest's own header being #included +// *unconditionally*. Therefore these #includes cannot be moved +// inside #if GTEST_HAS_PARAM_TEST. + +#if GTEST_HAS_PARAM_TEST + +namespace testing { + +// Forward declarations of ValuesIn(), which is implemented in +// include/gtest/gtest-param-test.h. +template +internal::ParamGenerator< + typename ::testing::internal::IteratorTraits::value_type> +ValuesIn(ForwardIterator begin, ForwardIterator end); + +template +internal::ParamGenerator ValuesIn(const T (&array)[N]); + +template +internal::ParamGenerator ValuesIn( + const Container& container); + +namespace internal { + +// Used in the Values() function to provide polymorphic capabilities. +template +class ValueArray1 { + public: + explicit ValueArray1(T1 v1) : v1_(v1) {} + + template + operator ParamGenerator() const { return ValuesIn(&v1_, &v1_ + 1); } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray1& other); + + const T1 v1_; +}; + +template +class ValueArray2 { + public: + ValueArray2(T1 v1, T2 v2) : v1_(v1), v2_(v2) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray2& other); + + const T1 v1_; + const T2 v2_; +}; + +template +class ValueArray3 { + public: + ValueArray3(T1 v1, T2 v2, T3 v3) : v1_(v1), v2_(v2), v3_(v3) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray3& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; +}; + +template +class ValueArray4 { + public: + ValueArray4(T1 v1, T2 v2, T3 v3, T4 v4) : v1_(v1), v2_(v2), v3_(v3), + v4_(v4) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray4& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; +}; + +template +class ValueArray5 { + public: + ValueArray5(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) : v1_(v1), v2_(v2), v3_(v3), + v4_(v4), v5_(v5) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray5& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; +}; + +template +class ValueArray6 { + public: + ValueArray6(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6) : v1_(v1), v2_(v2), + v3_(v3), v4_(v4), v5_(v5), v6_(v6) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray6& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; +}; + +template +class ValueArray7 { + public: + ValueArray7(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7) : v1_(v1), + v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray7& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; +}; + +template +class ValueArray8 { + public: + ValueArray8(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray8& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; +}; + +template +class ValueArray9 { + public: + ValueArray9(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, + T9 v9) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray9& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; +}; + +template +class ValueArray10 { + public: + ValueArray10(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray10& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; +}; + +template +class ValueArray11 { + public: + ValueArray11(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), + v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray11& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; +}; + +template +class ValueArray12 { + public: + ValueArray12(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), + v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray12& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; +}; + +template +class ValueArray13 { + public: + ValueArray13(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), + v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), + v12_(v12), v13_(v13) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray13& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; +}; + +template +class ValueArray14 { + public: + ValueArray14(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) : v1_(v1), v2_(v2), v3_(v3), + v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray14& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; +}; + +template +class ValueArray15 { + public: + ValueArray15(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15) : v1_(v1), v2_(v2), + v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray15& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; +}; + +template +class ValueArray16 { + public: + ValueArray16(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16) : v1_(v1), + v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), + v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), + v16_(v16) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray16& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; +}; + +template +class ValueArray17 { + public: + ValueArray17(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, + T17 v17) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray17& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; +}; + +template +class ValueArray18 { + public: + ValueArray18(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray18& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; +}; + +template +class ValueArray19 { + public: + ValueArray19(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), + v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), + v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray19& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; +}; + +template +class ValueArray20 { + public: + ValueArray20(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), + v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), + v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), + v19_(v19), v20_(v20) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray20& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; +}; + +template +class ValueArray21 { + public: + ValueArray21(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), + v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), + v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), + v18_(v18), v19_(v19), v20_(v20), v21_(v21) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray21& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; +}; + +template +class ValueArray22 { + public: + ValueArray22(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22) : v1_(v1), v2_(v2), v3_(v3), + v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray22& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; +}; + +template +class ValueArray23 { + public: + ValueArray23(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23) : v1_(v1), v2_(v2), + v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), + v23_(v23) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray23& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; +}; + +template +class ValueArray24 { + public: + ValueArray24(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24) : v1_(v1), + v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), + v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), + v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), + v22_(v22), v23_(v23), v24_(v24) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray24& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; +}; + +template +class ValueArray25 { + public: + ValueArray25(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, + T25 v25) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray25& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; +}; + +template +class ValueArray26 { + public: + ValueArray26(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray26& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; +}; + +template +class ValueArray27 { + public: + ValueArray27(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), + v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), + v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), + v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), + v26_(v26), v27_(v27) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray27& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; +}; + +template +class ValueArray28 { + public: + ValueArray28(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), + v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), + v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), + v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), + v25_(v25), v26_(v26), v27_(v27), v28_(v28) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray28& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; +}; + +template +class ValueArray29 { + public: + ValueArray29(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), + v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), + v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), + v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), + v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray29& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; +}; + +template +class ValueArray30 { + public: + ValueArray30(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30) : v1_(v1), v2_(v2), v3_(v3), + v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), + v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), + v29_(v29), v30_(v30) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray30& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; +}; + +template +class ValueArray31 { + public: + ValueArray31(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31) : v1_(v1), v2_(v2), + v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), + v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), + v29_(v29), v30_(v30), v31_(v31) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray31& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; +}; + +template +class ValueArray32 { + public: + ValueArray32(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32) : v1_(v1), + v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), + v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), + v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), + v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), + v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray32& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; +}; + +template +class ValueArray33 { + public: + ValueArray33(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, + T33 v33) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), + v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), + v33_(v33) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray33& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; +}; + +template +class ValueArray34 { + public: + ValueArray34(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), + v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), + v33_(v33), v34_(v34) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray34& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; +}; + +template +class ValueArray35 { + public: + ValueArray35(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), + v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), + v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), + v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), + v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), + v32_(v32), v33_(v33), v34_(v34), v35_(v35) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray35& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; +}; + +template +class ValueArray36 { + public: + ValueArray36(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), + v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), + v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), + v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), + v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), + v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray36& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; +}; + +template +class ValueArray37 { + public: + ValueArray37(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), + v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), + v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), + v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), + v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), + v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), + v36_(v36), v37_(v37) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray37& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; +}; + +template +class ValueArray38 { + public: + ValueArray38(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38) : v1_(v1), v2_(v2), v3_(v3), + v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), + v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), + v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), + v35_(v35), v36_(v36), v37_(v37), v38_(v38) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray38& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; +}; + +template +class ValueArray39 { + public: + ValueArray39(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39) : v1_(v1), v2_(v2), + v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), + v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), + v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), + v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_), + static_cast(v39_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray39& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; +}; + +template +class ValueArray40 { + public: + ValueArray40(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40) : v1_(v1), + v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), + v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), + v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), + v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), + v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), + v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), + v40_(v40) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_), + static_cast(v39_), static_cast(v40_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray40& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; +}; + +template +class ValueArray41 { + public: + ValueArray41(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, + T41 v41) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), + v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), + v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), + v39_(v39), v40_(v40), v41_(v41) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_), + static_cast(v39_), static_cast(v40_), static_cast(v41_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray41& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; +}; + +template +class ValueArray42 { + public: + ValueArray42(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), + v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), + v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), + v39_(v39), v40_(v40), v41_(v41), v42_(v42) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_), + static_cast(v39_), static_cast(v40_), static_cast(v41_), + static_cast(v42_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray42& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; +}; + +template +class ValueArray43 { + public: + ValueArray43(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), + v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), + v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), + v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), + v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), + v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), + v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_), + static_cast(v39_), static_cast(v40_), static_cast(v41_), + static_cast(v42_), static_cast(v43_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray43& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; +}; + +template +class ValueArray44 { + public: + ValueArray44(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), + v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), + v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), + v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), + v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), + v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), + v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), + v43_(v43), v44_(v44) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_), + static_cast(v39_), static_cast(v40_), static_cast(v41_), + static_cast(v42_), static_cast(v43_), static_cast(v44_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray44& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; +}; + +template +class ValueArray45 { + public: + ValueArray45(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44, T45 v45) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), + v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), + v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), + v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), + v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), + v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), + v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), + v42_(v42), v43_(v43), v44_(v44), v45_(v45) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_), + static_cast(v39_), static_cast(v40_), static_cast(v41_), + static_cast(v42_), static_cast(v43_), static_cast(v44_), + static_cast(v45_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray45& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; + const T45 v45_; +}; + +template +class ValueArray46 { + public: + ValueArray46(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44, T45 v45, T46 v46) : v1_(v1), v2_(v2), v3_(v3), + v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), + v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), + v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), + v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), + v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_), + static_cast(v39_), static_cast(v40_), static_cast(v41_), + static_cast(v42_), static_cast(v43_), static_cast(v44_), + static_cast(v45_), static_cast(v46_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray46& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; + const T45 v45_; + const T46 v46_; +}; + +template +class ValueArray47 { + public: + ValueArray47(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47) : v1_(v1), v2_(v2), + v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), + v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), + v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), + v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), + v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46), + v47_(v47) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_), + static_cast(v39_), static_cast(v40_), static_cast(v41_), + static_cast(v42_), static_cast(v43_), static_cast(v44_), + static_cast(v45_), static_cast(v46_), static_cast(v47_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray47& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; + const T45 v45_; + const T46 v46_; + const T47 v47_; +}; + +template +class ValueArray48 { + public: + ValueArray48(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48) : v1_(v1), + v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), + v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), + v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), + v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), + v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), + v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), + v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), + v46_(v46), v47_(v47), v48_(v48) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_), + static_cast(v39_), static_cast(v40_), static_cast(v41_), + static_cast(v42_), static_cast(v43_), static_cast(v44_), + static_cast(v45_), static_cast(v46_), static_cast(v47_), + static_cast(v48_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray48& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; + const T45 v45_; + const T46 v46_; + const T47 v47_; + const T48 v48_; +}; + +template +class ValueArray49 { + public: + ValueArray49(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48, + T49 v49) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), + v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), + v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), + v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), + v45_(v45), v46_(v46), v47_(v47), v48_(v48), v49_(v49) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_), + static_cast(v39_), static_cast(v40_), static_cast(v41_), + static_cast(v42_), static_cast(v43_), static_cast(v44_), + static_cast(v45_), static_cast(v46_), static_cast(v47_), + static_cast(v48_), static_cast(v49_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray49& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; + const T45 v45_; + const T46 v46_; + const T47 v47_; + const T48 v48_; + const T49 v49_; +}; + +template +class ValueArray50 { + public: + ValueArray50(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48, T49 v49, + T50 v50) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), + v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), + v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), + v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), + v45_(v45), v46_(v46), v47_(v47), v48_(v48), v49_(v49), v50_(v50) {} + + template + operator ParamGenerator() const { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_), + static_cast(v39_), static_cast(v40_), static_cast(v41_), + static_cast(v42_), static_cast(v43_), static_cast(v44_), + static_cast(v45_), static_cast(v46_), static_cast(v47_), + static_cast(v48_), static_cast(v49_), static_cast(v50_)}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray50& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; + const T45 v45_; + const T46 v46_; + const T47 v47_; + const T48 v48_; + const T49 v49_; + const T50 v50_; +}; + +# if GTEST_HAS_COMBINE +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Generates values from the Cartesian product of values produced +// by the argument generators. +// +template +class CartesianProductGenerator2 + : public ParamGeneratorInterface< ::std::tr1::tuple > { + public: + typedef ::std::tr1::tuple ParamType; + + CartesianProductGenerator2(const ParamGenerator& g1, + const ParamGenerator& g2) + : g1_(g1), g2_(g2) {} + virtual ~CartesianProductGenerator2() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin()); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end()); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current2_; + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + ParamType current_value_; + }; // class CartesianProductGenerator2::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator2& other); + + const ParamGenerator g1_; + const ParamGenerator g2_; +}; // class CartesianProductGenerator2 + + +template +class CartesianProductGenerator3 + : public ParamGeneratorInterface< ::std::tr1::tuple > { + public: + typedef ::std::tr1::tuple ParamType; + + CartesianProductGenerator3(const ParamGenerator& g1, + const ParamGenerator& g2, const ParamGenerator& g3) + : g1_(g1), g2_(g2), g3_(g3) {} + virtual ~CartesianProductGenerator3() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin()); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end()); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2, + const ParamGenerator& g3, + const typename ParamGenerator::iterator& current3) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current3_; + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + const typename ParamGenerator::iterator begin3_; + const typename ParamGenerator::iterator end3_; + typename ParamGenerator::iterator current3_; + ParamType current_value_; + }; // class CartesianProductGenerator3::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator3& other); + + const ParamGenerator g1_; + const ParamGenerator g2_; + const ParamGenerator g3_; +}; // class CartesianProductGenerator3 + + +template +class CartesianProductGenerator4 + : public ParamGeneratorInterface< ::std::tr1::tuple > { + public: + typedef ::std::tr1::tuple ParamType; + + CartesianProductGenerator4(const ParamGenerator& g1, + const ParamGenerator& g2, const ParamGenerator& g3, + const ParamGenerator& g4) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4) {} + virtual ~CartesianProductGenerator4() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin()); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end()); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2, + const ParamGenerator& g3, + const typename ParamGenerator::iterator& current3, + const ParamGenerator& g4, + const typename ParamGenerator::iterator& current4) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3), + begin4_(g4.begin()), end4_(g4.end()), current4_(current4) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current4_; + if (current4_ == end4_) { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + const typename ParamGenerator::iterator begin3_; + const typename ParamGenerator::iterator end3_; + typename ParamGenerator::iterator current3_; + const typename ParamGenerator::iterator begin4_; + const typename ParamGenerator::iterator end4_; + typename ParamGenerator::iterator current4_; + ParamType current_value_; + }; // class CartesianProductGenerator4::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator4& other); + + const ParamGenerator g1_; + const ParamGenerator g2_; + const ParamGenerator g3_; + const ParamGenerator g4_; +}; // class CartesianProductGenerator4 + + +template +class CartesianProductGenerator5 + : public ParamGeneratorInterface< ::std::tr1::tuple > { + public: + typedef ::std::tr1::tuple ParamType; + + CartesianProductGenerator5(const ParamGenerator& g1, + const ParamGenerator& g2, const ParamGenerator& g3, + const ParamGenerator& g4, const ParamGenerator& g5) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5) {} + virtual ~CartesianProductGenerator5() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin()); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end(), g5_, g5_.end()); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2, + const ParamGenerator& g3, + const typename ParamGenerator::iterator& current3, + const ParamGenerator& g4, + const typename ParamGenerator::iterator& current4, + const ParamGenerator& g5, + const typename ParamGenerator::iterator& current5) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3), + begin4_(g4.begin()), end4_(g4.end()), current4_(current4), + begin5_(g5.begin()), end5_(g5.end()), current5_(current5) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current5_; + if (current5_ == end5_) { + current5_ = begin5_; + ++current4_; + } + if (current4_ == end4_) { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_ && + current5_ == typed_other->current5_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_), + begin5_(other.begin5_), + end5_(other.end5_), + current5_(other.current5_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_, *current5_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_ || + current5_ == end5_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + const typename ParamGenerator::iterator begin3_; + const typename ParamGenerator::iterator end3_; + typename ParamGenerator::iterator current3_; + const typename ParamGenerator::iterator begin4_; + const typename ParamGenerator::iterator end4_; + typename ParamGenerator::iterator current4_; + const typename ParamGenerator::iterator begin5_; + const typename ParamGenerator::iterator end5_; + typename ParamGenerator::iterator current5_; + ParamType current_value_; + }; // class CartesianProductGenerator5::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator5& other); + + const ParamGenerator g1_; + const ParamGenerator g2_; + const ParamGenerator g3_; + const ParamGenerator g4_; + const ParamGenerator g5_; +}; // class CartesianProductGenerator5 + + +template +class CartesianProductGenerator6 + : public ParamGeneratorInterface< ::std::tr1::tuple > { + public: + typedef ::std::tr1::tuple ParamType; + + CartesianProductGenerator6(const ParamGenerator& g1, + const ParamGenerator& g2, const ParamGenerator& g3, + const ParamGenerator& g4, const ParamGenerator& g5, + const ParamGenerator& g6) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6) {} + virtual ~CartesianProductGenerator6() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin()); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end()); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2, + const ParamGenerator& g3, + const typename ParamGenerator::iterator& current3, + const ParamGenerator& g4, + const typename ParamGenerator::iterator& current4, + const ParamGenerator& g5, + const typename ParamGenerator::iterator& current5, + const ParamGenerator& g6, + const typename ParamGenerator::iterator& current6) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3), + begin4_(g4.begin()), end4_(g4.end()), current4_(current4), + begin5_(g5.begin()), end5_(g5.end()), current5_(current5), + begin6_(g6.begin()), end6_(g6.end()), current6_(current6) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current6_; + if (current6_ == end6_) { + current6_ = begin6_; + ++current5_; + } + if (current5_ == end5_) { + current5_ = begin5_; + ++current4_; + } + if (current4_ == end4_) { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_ && + current5_ == typed_other->current5_ && + current6_ == typed_other->current6_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_), + begin5_(other.begin5_), + end5_(other.end5_), + current5_(other.current5_), + begin6_(other.begin6_), + end6_(other.end6_), + current6_(other.current6_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_, *current5_, *current6_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_ || + current5_ == end5_ || + current6_ == end6_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + const typename ParamGenerator::iterator begin3_; + const typename ParamGenerator::iterator end3_; + typename ParamGenerator::iterator current3_; + const typename ParamGenerator::iterator begin4_; + const typename ParamGenerator::iterator end4_; + typename ParamGenerator::iterator current4_; + const typename ParamGenerator::iterator begin5_; + const typename ParamGenerator::iterator end5_; + typename ParamGenerator::iterator current5_; + const typename ParamGenerator::iterator begin6_; + const typename ParamGenerator::iterator end6_; + typename ParamGenerator::iterator current6_; + ParamType current_value_; + }; // class CartesianProductGenerator6::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator6& other); + + const ParamGenerator g1_; + const ParamGenerator g2_; + const ParamGenerator g3_; + const ParamGenerator g4_; + const ParamGenerator g5_; + const ParamGenerator g6_; +}; // class CartesianProductGenerator6 + + +template +class CartesianProductGenerator7 + : public ParamGeneratorInterface< ::std::tr1::tuple > { + public: + typedef ::std::tr1::tuple ParamType; + + CartesianProductGenerator7(const ParamGenerator& g1, + const ParamGenerator& g2, const ParamGenerator& g3, + const ParamGenerator& g4, const ParamGenerator& g5, + const ParamGenerator& g6, const ParamGenerator& g7) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7) {} + virtual ~CartesianProductGenerator7() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, + g7_.begin()); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end()); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2, + const ParamGenerator& g3, + const typename ParamGenerator::iterator& current3, + const ParamGenerator& g4, + const typename ParamGenerator::iterator& current4, + const ParamGenerator& g5, + const typename ParamGenerator::iterator& current5, + const ParamGenerator& g6, + const typename ParamGenerator::iterator& current6, + const ParamGenerator& g7, + const typename ParamGenerator::iterator& current7) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3), + begin4_(g4.begin()), end4_(g4.end()), current4_(current4), + begin5_(g5.begin()), end5_(g5.end()), current5_(current5), + begin6_(g6.begin()), end6_(g6.end()), current6_(current6), + begin7_(g7.begin()), end7_(g7.end()), current7_(current7) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current7_; + if (current7_ == end7_) { + current7_ = begin7_; + ++current6_; + } + if (current6_ == end6_) { + current6_ = begin6_; + ++current5_; + } + if (current5_ == end5_) { + current5_ = begin5_; + ++current4_; + } + if (current4_ == end4_) { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_ && + current5_ == typed_other->current5_ && + current6_ == typed_other->current6_ && + current7_ == typed_other->current7_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_), + begin5_(other.begin5_), + end5_(other.end5_), + current5_(other.current5_), + begin6_(other.begin6_), + end6_(other.end6_), + current6_(other.current6_), + begin7_(other.begin7_), + end7_(other.end7_), + current7_(other.current7_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_, *current5_, *current6_, *current7_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_ || + current5_ == end5_ || + current6_ == end6_ || + current7_ == end7_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + const typename ParamGenerator::iterator begin3_; + const typename ParamGenerator::iterator end3_; + typename ParamGenerator::iterator current3_; + const typename ParamGenerator::iterator begin4_; + const typename ParamGenerator::iterator end4_; + typename ParamGenerator::iterator current4_; + const typename ParamGenerator::iterator begin5_; + const typename ParamGenerator::iterator end5_; + typename ParamGenerator::iterator current5_; + const typename ParamGenerator::iterator begin6_; + const typename ParamGenerator::iterator end6_; + typename ParamGenerator::iterator current6_; + const typename ParamGenerator::iterator begin7_; + const typename ParamGenerator::iterator end7_; + typename ParamGenerator::iterator current7_; + ParamType current_value_; + }; // class CartesianProductGenerator7::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator7& other); + + const ParamGenerator g1_; + const ParamGenerator g2_; + const ParamGenerator g3_; + const ParamGenerator g4_; + const ParamGenerator g5_; + const ParamGenerator g6_; + const ParamGenerator g7_; +}; // class CartesianProductGenerator7 + + +template +class CartesianProductGenerator8 + : public ParamGeneratorInterface< ::std::tr1::tuple > { + public: + typedef ::std::tr1::tuple ParamType; + + CartesianProductGenerator8(const ParamGenerator& g1, + const ParamGenerator& g2, const ParamGenerator& g3, + const ParamGenerator& g4, const ParamGenerator& g5, + const ParamGenerator& g6, const ParamGenerator& g7, + const ParamGenerator& g8) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), + g8_(g8) {} + virtual ~CartesianProductGenerator8() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, + g7_.begin(), g8_, g8_.begin()); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_, + g8_.end()); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2, + const ParamGenerator& g3, + const typename ParamGenerator::iterator& current3, + const ParamGenerator& g4, + const typename ParamGenerator::iterator& current4, + const ParamGenerator& g5, + const typename ParamGenerator::iterator& current5, + const ParamGenerator& g6, + const typename ParamGenerator::iterator& current6, + const ParamGenerator& g7, + const typename ParamGenerator::iterator& current7, + const ParamGenerator& g8, + const typename ParamGenerator::iterator& current8) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3), + begin4_(g4.begin()), end4_(g4.end()), current4_(current4), + begin5_(g5.begin()), end5_(g5.end()), current5_(current5), + begin6_(g6.begin()), end6_(g6.end()), current6_(current6), + begin7_(g7.begin()), end7_(g7.end()), current7_(current7), + begin8_(g8.begin()), end8_(g8.end()), current8_(current8) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current8_; + if (current8_ == end8_) { + current8_ = begin8_; + ++current7_; + } + if (current7_ == end7_) { + current7_ = begin7_; + ++current6_; + } + if (current6_ == end6_) { + current6_ = begin6_; + ++current5_; + } + if (current5_ == end5_) { + current5_ = begin5_; + ++current4_; + } + if (current4_ == end4_) { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_ && + current5_ == typed_other->current5_ && + current6_ == typed_other->current6_ && + current7_ == typed_other->current7_ && + current8_ == typed_other->current8_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_), + begin5_(other.begin5_), + end5_(other.end5_), + current5_(other.current5_), + begin6_(other.begin6_), + end6_(other.end6_), + current6_(other.current6_), + begin7_(other.begin7_), + end7_(other.end7_), + current7_(other.current7_), + begin8_(other.begin8_), + end8_(other.end8_), + current8_(other.current8_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_, *current5_, *current6_, *current7_, *current8_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_ || + current5_ == end5_ || + current6_ == end6_ || + current7_ == end7_ || + current8_ == end8_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + const typename ParamGenerator::iterator begin3_; + const typename ParamGenerator::iterator end3_; + typename ParamGenerator::iterator current3_; + const typename ParamGenerator::iterator begin4_; + const typename ParamGenerator::iterator end4_; + typename ParamGenerator::iterator current4_; + const typename ParamGenerator::iterator begin5_; + const typename ParamGenerator::iterator end5_; + typename ParamGenerator::iterator current5_; + const typename ParamGenerator::iterator begin6_; + const typename ParamGenerator::iterator end6_; + typename ParamGenerator::iterator current6_; + const typename ParamGenerator::iterator begin7_; + const typename ParamGenerator::iterator end7_; + typename ParamGenerator::iterator current7_; + const typename ParamGenerator::iterator begin8_; + const typename ParamGenerator::iterator end8_; + typename ParamGenerator::iterator current8_; + ParamType current_value_; + }; // class CartesianProductGenerator8::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator8& other); + + const ParamGenerator g1_; + const ParamGenerator g2_; + const ParamGenerator g3_; + const ParamGenerator g4_; + const ParamGenerator g5_; + const ParamGenerator g6_; + const ParamGenerator g7_; + const ParamGenerator g8_; +}; // class CartesianProductGenerator8 + + +template +class CartesianProductGenerator9 + : public ParamGeneratorInterface< ::std::tr1::tuple > { + public: + typedef ::std::tr1::tuple ParamType; + + CartesianProductGenerator9(const ParamGenerator& g1, + const ParamGenerator& g2, const ParamGenerator& g3, + const ParamGenerator& g4, const ParamGenerator& g5, + const ParamGenerator& g6, const ParamGenerator& g7, + const ParamGenerator& g8, const ParamGenerator& g9) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), + g9_(g9) {} + virtual ~CartesianProductGenerator9() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, + g7_.begin(), g8_, g8_.begin(), g9_, g9_.begin()); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_, + g8_.end(), g9_, g9_.end()); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2, + const ParamGenerator& g3, + const typename ParamGenerator::iterator& current3, + const ParamGenerator& g4, + const typename ParamGenerator::iterator& current4, + const ParamGenerator& g5, + const typename ParamGenerator::iterator& current5, + const ParamGenerator& g6, + const typename ParamGenerator::iterator& current6, + const ParamGenerator& g7, + const typename ParamGenerator::iterator& current7, + const ParamGenerator& g8, + const typename ParamGenerator::iterator& current8, + const ParamGenerator& g9, + const typename ParamGenerator::iterator& current9) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3), + begin4_(g4.begin()), end4_(g4.end()), current4_(current4), + begin5_(g5.begin()), end5_(g5.end()), current5_(current5), + begin6_(g6.begin()), end6_(g6.end()), current6_(current6), + begin7_(g7.begin()), end7_(g7.end()), current7_(current7), + begin8_(g8.begin()), end8_(g8.end()), current8_(current8), + begin9_(g9.begin()), end9_(g9.end()), current9_(current9) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current9_; + if (current9_ == end9_) { + current9_ = begin9_; + ++current8_; + } + if (current8_ == end8_) { + current8_ = begin8_; + ++current7_; + } + if (current7_ == end7_) { + current7_ = begin7_; + ++current6_; + } + if (current6_ == end6_) { + current6_ = begin6_; + ++current5_; + } + if (current5_ == end5_) { + current5_ = begin5_; + ++current4_; + } + if (current4_ == end4_) { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_ && + current5_ == typed_other->current5_ && + current6_ == typed_other->current6_ && + current7_ == typed_other->current7_ && + current8_ == typed_other->current8_ && + current9_ == typed_other->current9_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_), + begin5_(other.begin5_), + end5_(other.end5_), + current5_(other.current5_), + begin6_(other.begin6_), + end6_(other.end6_), + current6_(other.current6_), + begin7_(other.begin7_), + end7_(other.end7_), + current7_(other.current7_), + begin8_(other.begin8_), + end8_(other.end8_), + current8_(other.current8_), + begin9_(other.begin9_), + end9_(other.end9_), + current9_(other.current9_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_, *current5_, *current6_, *current7_, *current8_, + *current9_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_ || + current5_ == end5_ || + current6_ == end6_ || + current7_ == end7_ || + current8_ == end8_ || + current9_ == end9_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + const typename ParamGenerator::iterator begin3_; + const typename ParamGenerator::iterator end3_; + typename ParamGenerator::iterator current3_; + const typename ParamGenerator::iterator begin4_; + const typename ParamGenerator::iterator end4_; + typename ParamGenerator::iterator current4_; + const typename ParamGenerator::iterator begin5_; + const typename ParamGenerator::iterator end5_; + typename ParamGenerator::iterator current5_; + const typename ParamGenerator::iterator begin6_; + const typename ParamGenerator::iterator end6_; + typename ParamGenerator::iterator current6_; + const typename ParamGenerator::iterator begin7_; + const typename ParamGenerator::iterator end7_; + typename ParamGenerator::iterator current7_; + const typename ParamGenerator::iterator begin8_; + const typename ParamGenerator::iterator end8_; + typename ParamGenerator::iterator current8_; + const typename ParamGenerator::iterator begin9_; + const typename ParamGenerator::iterator end9_; + typename ParamGenerator::iterator current9_; + ParamType current_value_; + }; // class CartesianProductGenerator9::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator9& other); + + const ParamGenerator g1_; + const ParamGenerator g2_; + const ParamGenerator g3_; + const ParamGenerator g4_; + const ParamGenerator g5_; + const ParamGenerator g6_; + const ParamGenerator g7_; + const ParamGenerator g8_; + const ParamGenerator g9_; +}; // class CartesianProductGenerator9 + + +template +class CartesianProductGenerator10 + : public ParamGeneratorInterface< ::std::tr1::tuple > { + public: + typedef ::std::tr1::tuple ParamType; + + CartesianProductGenerator10(const ParamGenerator& g1, + const ParamGenerator& g2, const ParamGenerator& g3, + const ParamGenerator& g4, const ParamGenerator& g5, + const ParamGenerator& g6, const ParamGenerator& g7, + const ParamGenerator& g8, const ParamGenerator& g9, + const ParamGenerator& g10) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), + g9_(g9), g10_(g10) {} + virtual ~CartesianProductGenerator10() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, + g7_.begin(), g8_, g8_.begin(), g9_, g9_.begin(), g10_, g10_.begin()); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_, + g8_.end(), g9_, g9_.end(), g10_, g10_.end()); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2, + const ParamGenerator& g3, + const typename ParamGenerator::iterator& current3, + const ParamGenerator& g4, + const typename ParamGenerator::iterator& current4, + const ParamGenerator& g5, + const typename ParamGenerator::iterator& current5, + const ParamGenerator& g6, + const typename ParamGenerator::iterator& current6, + const ParamGenerator& g7, + const typename ParamGenerator::iterator& current7, + const ParamGenerator& g8, + const typename ParamGenerator::iterator& current8, + const ParamGenerator& g9, + const typename ParamGenerator::iterator& current9, + const ParamGenerator& g10, + const typename ParamGenerator::iterator& current10) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3), + begin4_(g4.begin()), end4_(g4.end()), current4_(current4), + begin5_(g5.begin()), end5_(g5.end()), current5_(current5), + begin6_(g6.begin()), end6_(g6.end()), current6_(current6), + begin7_(g7.begin()), end7_(g7.end()), current7_(current7), + begin8_(g8.begin()), end8_(g8.end()), current8_(current8), + begin9_(g9.begin()), end9_(g9.end()), current9_(current9), + begin10_(g10.begin()), end10_(g10.end()), current10_(current10) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current10_; + if (current10_ == end10_) { + current10_ = begin10_; + ++current9_; + } + if (current9_ == end9_) { + current9_ = begin9_; + ++current8_; + } + if (current8_ == end8_) { + current8_ = begin8_; + ++current7_; + } + if (current7_ == end7_) { + current7_ = begin7_; + ++current6_; + } + if (current6_ == end6_) { + current6_ = begin6_; + ++current5_; + } + if (current5_ == end5_) { + current5_ = begin5_; + ++current4_; + } + if (current4_ == end4_) { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_ && + current5_ == typed_other->current5_ && + current6_ == typed_other->current6_ && + current7_ == typed_other->current7_ && + current8_ == typed_other->current8_ && + current9_ == typed_other->current9_ && + current10_ == typed_other->current10_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_), + begin5_(other.begin5_), + end5_(other.end5_), + current5_(other.current5_), + begin6_(other.begin6_), + end6_(other.end6_), + current6_(other.current6_), + begin7_(other.begin7_), + end7_(other.end7_), + current7_(other.current7_), + begin8_(other.begin8_), + end8_(other.end8_), + current8_(other.current8_), + begin9_(other.begin9_), + end9_(other.end9_), + current9_(other.current9_), + begin10_(other.begin10_), + end10_(other.end10_), + current10_(other.current10_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_, *current5_, *current6_, *current7_, *current8_, + *current9_, *current10_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_ || + current5_ == end5_ || + current6_ == end6_ || + current7_ == end7_ || + current8_ == end8_ || + current9_ == end9_ || + current10_ == end10_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + const typename ParamGenerator::iterator begin3_; + const typename ParamGenerator::iterator end3_; + typename ParamGenerator::iterator current3_; + const typename ParamGenerator::iterator begin4_; + const typename ParamGenerator::iterator end4_; + typename ParamGenerator::iterator current4_; + const typename ParamGenerator::iterator begin5_; + const typename ParamGenerator::iterator end5_; + typename ParamGenerator::iterator current5_; + const typename ParamGenerator::iterator begin6_; + const typename ParamGenerator::iterator end6_; + typename ParamGenerator::iterator current6_; + const typename ParamGenerator::iterator begin7_; + const typename ParamGenerator::iterator end7_; + typename ParamGenerator::iterator current7_; + const typename ParamGenerator::iterator begin8_; + const typename ParamGenerator::iterator end8_; + typename ParamGenerator::iterator current8_; + const typename ParamGenerator::iterator begin9_; + const typename ParamGenerator::iterator end9_; + typename ParamGenerator::iterator current9_; + const typename ParamGenerator::iterator begin10_; + const typename ParamGenerator::iterator end10_; + typename ParamGenerator::iterator current10_; + ParamType current_value_; + }; // class CartesianProductGenerator10::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator10& other); + + const ParamGenerator g1_; + const ParamGenerator g2_; + const ParamGenerator g3_; + const ParamGenerator g4_; + const ParamGenerator g5_; + const ParamGenerator g6_; + const ParamGenerator g7_; + const ParamGenerator g8_; + const ParamGenerator g9_; + const ParamGenerator g10_; +}; // class CartesianProductGenerator10 + + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Helper classes providing Combine() with polymorphic features. They allow +// casting CartesianProductGeneratorN to ParamGenerator if T is +// convertible to U. +// +template +class CartesianProductHolder2 { + public: +CartesianProductHolder2(const Generator1& g1, const Generator2& g2) + : g1_(g1), g2_(g2) {} + template + operator ParamGenerator< ::std::tr1::tuple >() const { + return ParamGenerator< ::std::tr1::tuple >( + new CartesianProductGenerator2( + static_cast >(g1_), + static_cast >(g2_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder2& other); + + const Generator1 g1_; + const Generator2 g2_; +}; // class CartesianProductHolder2 + +template +class CartesianProductHolder3 { + public: +CartesianProductHolder3(const Generator1& g1, const Generator2& g2, + const Generator3& g3) + : g1_(g1), g2_(g2), g3_(g3) {} + template + operator ParamGenerator< ::std::tr1::tuple >() const { + return ParamGenerator< ::std::tr1::tuple >( + new CartesianProductGenerator3( + static_cast >(g1_), + static_cast >(g2_), + static_cast >(g3_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder3& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; +}; // class CartesianProductHolder3 + +template +class CartesianProductHolder4 { + public: +CartesianProductHolder4(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4) {} + template + operator ParamGenerator< ::std::tr1::tuple >() const { + return ParamGenerator< ::std::tr1::tuple >( + new CartesianProductGenerator4( + static_cast >(g1_), + static_cast >(g2_), + static_cast >(g3_), + static_cast >(g4_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder4& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; +}; // class CartesianProductHolder4 + +template +class CartesianProductHolder5 { + public: +CartesianProductHolder5(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4, const Generator5& g5) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5) {} + template + operator ParamGenerator< ::std::tr1::tuple >() const { + return ParamGenerator< ::std::tr1::tuple >( + new CartesianProductGenerator5( + static_cast >(g1_), + static_cast >(g2_), + static_cast >(g3_), + static_cast >(g4_), + static_cast >(g5_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder5& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; + const Generator5 g5_; +}; // class CartesianProductHolder5 + +template +class CartesianProductHolder6 { + public: +CartesianProductHolder6(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4, const Generator5& g5, + const Generator6& g6) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6) {} + template + operator ParamGenerator< ::std::tr1::tuple >() const { + return ParamGenerator< ::std::tr1::tuple >( + new CartesianProductGenerator6( + static_cast >(g1_), + static_cast >(g2_), + static_cast >(g3_), + static_cast >(g4_), + static_cast >(g5_), + static_cast >(g6_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder6& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; + const Generator5 g5_; + const Generator6 g6_; +}; // class CartesianProductHolder6 + +template +class CartesianProductHolder7 { + public: +CartesianProductHolder7(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4, const Generator5& g5, + const Generator6& g6, const Generator7& g7) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7) {} + template + operator ParamGenerator< ::std::tr1::tuple >() const { + return ParamGenerator< ::std::tr1::tuple >( + new CartesianProductGenerator7( + static_cast >(g1_), + static_cast >(g2_), + static_cast >(g3_), + static_cast >(g4_), + static_cast >(g5_), + static_cast >(g6_), + static_cast >(g7_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder7& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; + const Generator5 g5_; + const Generator6 g6_; + const Generator7 g7_; +}; // class CartesianProductHolder7 + +template +class CartesianProductHolder8 { + public: +CartesianProductHolder8(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4, const Generator5& g5, + const Generator6& g6, const Generator7& g7, const Generator8& g8) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), + g8_(g8) {} + template + operator ParamGenerator< ::std::tr1::tuple >() const { + return ParamGenerator< ::std::tr1::tuple >( + new CartesianProductGenerator8( + static_cast >(g1_), + static_cast >(g2_), + static_cast >(g3_), + static_cast >(g4_), + static_cast >(g5_), + static_cast >(g6_), + static_cast >(g7_), + static_cast >(g8_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder8& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; + const Generator5 g5_; + const Generator6 g6_; + const Generator7 g7_; + const Generator8 g8_; +}; // class CartesianProductHolder8 + +template +class CartesianProductHolder9 { + public: +CartesianProductHolder9(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4, const Generator5& g5, + const Generator6& g6, const Generator7& g7, const Generator8& g8, + const Generator9& g9) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), + g9_(g9) {} + template + operator ParamGenerator< ::std::tr1::tuple >() const { + return ParamGenerator< ::std::tr1::tuple >( + new CartesianProductGenerator9( + static_cast >(g1_), + static_cast >(g2_), + static_cast >(g3_), + static_cast >(g4_), + static_cast >(g5_), + static_cast >(g6_), + static_cast >(g7_), + static_cast >(g8_), + static_cast >(g9_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder9& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; + const Generator5 g5_; + const Generator6 g6_; + const Generator7 g7_; + const Generator8 g8_; + const Generator9 g9_; +}; // class CartesianProductHolder9 + +template +class CartesianProductHolder10 { + public: +CartesianProductHolder10(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4, const Generator5& g5, + const Generator6& g6, const Generator7& g7, const Generator8& g8, + const Generator9& g9, const Generator10& g10) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), + g9_(g9), g10_(g10) {} + template + operator ParamGenerator< ::std::tr1::tuple >() const { + return ParamGenerator< ::std::tr1::tuple >( + new CartesianProductGenerator10( + static_cast >(g1_), + static_cast >(g2_), + static_cast >(g3_), + static_cast >(g4_), + static_cast >(g5_), + static_cast >(g6_), + static_cast >(g7_), + static_cast >(g8_), + static_cast >(g9_), + static_cast >(g10_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder10& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; + const Generator5 g5_; + const Generator6 g6_; + const Generator7 g7_; + const Generator8 g8_; + const Generator9 g9_; + const Generator10 g10_; +}; // class CartesianProductHolder10 + +# endif // GTEST_HAS_COMBINE + +} // namespace internal +} // namespace testing + +#endif // GTEST_HAS_PARAM_TEST + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ + +#if GTEST_HAS_PARAM_TEST + +namespace testing { + +// Functions producing parameter generators. +// +// Google Test uses these generators to produce parameters for value- +// parameterized tests. When a parameterized test case is instantiated +// with a particular generator, Google Test creates and runs tests +// for each element in the sequence produced by the generator. +// +// In the following sample, tests from test case FooTest are instantiated +// each three times with parameter values 3, 5, and 8: +// +// class FooTest : public TestWithParam { ... }; +// +// TEST_P(FooTest, TestThis) { +// } +// TEST_P(FooTest, TestThat) { +// } +// INSTANTIATE_TEST_CASE_P(TestSequence, FooTest, Values(3, 5, 8)); +// + +// Range() returns generators providing sequences of values in a range. +// +// Synopsis: +// Range(start, end) +// - returns a generator producing a sequence of values {start, start+1, +// start+2, ..., }. +// Range(start, end, step) +// - returns a generator producing a sequence of values {start, start+step, +// start+step+step, ..., }. +// Notes: +// * The generated sequences never include end. For example, Range(1, 5) +// returns a generator producing a sequence {1, 2, 3, 4}. Range(1, 9, 2) +// returns a generator producing {1, 3, 5, 7}. +// * start and end must have the same type. That type may be any integral or +// floating-point type or a user defined type satisfying these conditions: +// * It must be assignable (have operator=() defined). +// * It must have operator+() (operator+(int-compatible type) for +// two-operand version). +// * It must have operator<() defined. +// Elements in the resulting sequences will also have that type. +// * Condition start < end must be satisfied in order for resulting sequences +// to contain any elements. +// +template +internal::ParamGenerator Range(T start, T end, IncrementT step) { + return internal::ParamGenerator( + new internal::RangeGenerator(start, end, step)); +} + +template +internal::ParamGenerator Range(T start, T end) { + return Range(start, end, 1); +} + +// ValuesIn() function allows generation of tests with parameters coming from +// a container. +// +// Synopsis: +// ValuesIn(const T (&array)[N]) +// - returns a generator producing sequences with elements from +// a C-style array. +// ValuesIn(const Container& container) +// - returns a generator producing sequences with elements from +// an STL-style container. +// ValuesIn(Iterator begin, Iterator end) +// - returns a generator producing sequences with elements from +// a range [begin, end) defined by a pair of STL-style iterators. These +// iterators can also be plain C pointers. +// +// Please note that ValuesIn copies the values from the containers +// passed in and keeps them to generate tests in RUN_ALL_TESTS(). +// +// Examples: +// +// This instantiates tests from test case StringTest +// each with C-string values of "foo", "bar", and "baz": +// +// const char* strings[] = {"foo", "bar", "baz"}; +// INSTANTIATE_TEST_CASE_P(StringSequence, SrtingTest, ValuesIn(strings)); +// +// This instantiates tests from test case StlStringTest +// each with STL strings with values "a" and "b": +// +// ::std::vector< ::std::string> GetParameterStrings() { +// ::std::vector< ::std::string> v; +// v.push_back("a"); +// v.push_back("b"); +// return v; +// } +// +// INSTANTIATE_TEST_CASE_P(CharSequence, +// StlStringTest, +// ValuesIn(GetParameterStrings())); +// +// +// This will also instantiate tests from CharTest +// each with parameter values 'a' and 'b': +// +// ::std::list GetParameterChars() { +// ::std::list list; +// list.push_back('a'); +// list.push_back('b'); +// return list; +// } +// ::std::list l = GetParameterChars(); +// INSTANTIATE_TEST_CASE_P(CharSequence2, +// CharTest, +// ValuesIn(l.begin(), l.end())); +// +template +internal::ParamGenerator< + typename ::testing::internal::IteratorTraits::value_type> +ValuesIn(ForwardIterator begin, ForwardIterator end) { + typedef typename ::testing::internal::IteratorTraits + ::value_type ParamType; + return internal::ParamGenerator( + new internal::ValuesInIteratorRangeGenerator(begin, end)); +} + +template +internal::ParamGenerator ValuesIn(const T (&array)[N]) { + return ValuesIn(array, array + N); +} + +template +internal::ParamGenerator ValuesIn( + const Container& container) { + return ValuesIn(container.begin(), container.end()); +} + +// Values() allows generating tests from explicitly specified list of +// parameters. +// +// Synopsis: +// Values(T v1, T v2, ..., T vN) +// - returns a generator producing sequences with elements v1, v2, ..., vN. +// +// For example, this instantiates tests from test case BarTest each +// with values "one", "two", and "three": +// +// INSTANTIATE_TEST_CASE_P(NumSequence, BarTest, Values("one", "two", "three")); +// +// This instantiates tests from test case BazTest each with values 1, 2, 3.5. +// The exact type of values will depend on the type of parameter in BazTest. +// +// INSTANTIATE_TEST_CASE_P(FloatingNumbers, BazTest, Values(1, 2, 3.5)); +// +// Currently, Values() supports from 1 to 50 parameters. +// +template +internal::ValueArray1 Values(T1 v1) { + return internal::ValueArray1(v1); +} + +template +internal::ValueArray2 Values(T1 v1, T2 v2) { + return internal::ValueArray2(v1, v2); +} + +template +internal::ValueArray3 Values(T1 v1, T2 v2, T3 v3) { + return internal::ValueArray3(v1, v2, v3); +} + +template +internal::ValueArray4 Values(T1 v1, T2 v2, T3 v3, T4 v4) { + return internal::ValueArray4(v1, v2, v3, v4); +} + +template +internal::ValueArray5 Values(T1 v1, T2 v2, T3 v3, T4 v4, + T5 v5) { + return internal::ValueArray5(v1, v2, v3, v4, v5); +} + +template +internal::ValueArray6 Values(T1 v1, T2 v2, T3 v3, + T4 v4, T5 v5, T6 v6) { + return internal::ValueArray6(v1, v2, v3, v4, v5, v6); +} + +template +internal::ValueArray7 Values(T1 v1, T2 v2, T3 v3, + T4 v4, T5 v5, T6 v6, T7 v7) { + return internal::ValueArray7(v1, v2, v3, v4, v5, + v6, v7); +} + +template +internal::ValueArray8 Values(T1 v1, T2 v2, + T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8) { + return internal::ValueArray8(v1, v2, v3, v4, + v5, v6, v7, v8); +} + +template +internal::ValueArray9 Values(T1 v1, T2 v2, + T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9) { + return internal::ValueArray9(v1, v2, v3, + v4, v5, v6, v7, v8, v9); +} + +template +internal::ValueArray10 Values(T1 v1, + T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10) { + return internal::ValueArray10(v1, + v2, v3, v4, v5, v6, v7, v8, v9, v10); +} + +template +internal::ValueArray11 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11) { + return internal::ValueArray11(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11); +} + +template +internal::ValueArray12 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12) { + return internal::ValueArray12(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12); +} + +template +internal::ValueArray13 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13) { + return internal::ValueArray13(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13); +} + +template +internal::ValueArray14 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) { + return internal::ValueArray14(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, + v14); +} + +template +internal::ValueArray15 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, + T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15) { + return internal::ValueArray15(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, + v13, v14, v15); +} + +template +internal::ValueArray16 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16) { + return internal::ValueArray16(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, + v12, v13, v14, v15, v16); +} + +template +internal::ValueArray17 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17) { + return internal::ValueArray17(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, + v11, v12, v13, v14, v15, v16, v17); +} + +template +internal::ValueArray18 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, + T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18) { + return internal::ValueArray18(v1, v2, v3, v4, v5, v6, v7, v8, v9, + v10, v11, v12, v13, v14, v15, v16, v17, v18); +} + +template +internal::ValueArray19 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, + T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, + T15 v15, T16 v16, T17 v17, T18 v18, T19 v19) { + return internal::ValueArray19(v1, v2, v3, v4, v5, v6, v7, v8, + v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19); +} + +template +internal::ValueArray20 Values(T1 v1, T2 v2, T3 v3, T4 v4, + T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, + T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20) { + return internal::ValueArray20(v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20); +} + +template +internal::ValueArray21 Values(T1 v1, T2 v2, T3 v3, T4 v4, + T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, + T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21) { + return internal::ValueArray21(v1, v2, v3, v4, v5, v6, + v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21); +} + +template +internal::ValueArray22 Values(T1 v1, T2 v2, T3 v3, + T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, + T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, + T21 v21, T22 v22) { + return internal::ValueArray22(v1, v2, v3, v4, + v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, + v20, v21, v22); +} + +template +internal::ValueArray23 Values(T1 v1, T2 v2, + T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, + T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, + T21 v21, T22 v22, T23 v23) { + return internal::ValueArray23(v1, v2, v3, + v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, + v20, v21, v22, v23); +} + +template +internal::ValueArray24 Values(T1 v1, T2 v2, + T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, + T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, + T21 v21, T22 v22, T23 v23, T24 v24) { + return internal::ValueArray24(v1, v2, + v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, + v19, v20, v21, v22, v23, v24); +} + +template +internal::ValueArray25 Values(T1 v1, + T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, + T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, + T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25) { + return internal::ValueArray25(v1, + v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, + v18, v19, v20, v21, v22, v23, v24, v25); +} + +template +internal::ValueArray26 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26) { + return internal::ValueArray26(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, + v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26); +} + +template +internal::ValueArray27 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27) { + return internal::ValueArray27(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, + v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27); +} + +template +internal::ValueArray28 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28) { + return internal::ValueArray28(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, + v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, + v28); +} + +template +internal::ValueArray29 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29) { + return internal::ValueArray29(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, + v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, + v27, v28, v29); +} + +template +internal::ValueArray30 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, + T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, + T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, + T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30) { + return internal::ValueArray30(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, + v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, + v26, v27, v28, v29, v30); +} + +template +internal::ValueArray31 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, + T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31) { + return internal::ValueArray31(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, + v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, + v25, v26, v27, v28, v29, v30, v31); +} + +template +internal::ValueArray32 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, + T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, + T32 v32) { + return internal::ValueArray32(v1, v2, v3, v4, v5, v6, v7, v8, v9, + v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, + v24, v25, v26, v27, v28, v29, v30, v31, v32); +} + +template +internal::ValueArray33 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, + T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, + T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, + T32 v32, T33 v33) { + return internal::ValueArray33(v1, v2, v3, v4, v5, v6, v7, v8, + v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, + v24, v25, v26, v27, v28, v29, v30, v31, v32, v33); +} + +template +internal::ValueArray34 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, + T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, + T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, + T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, + T31 v31, T32 v32, T33 v33, T34 v34) { + return internal::ValueArray34(v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, + v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34); +} + +template +internal::ValueArray35 Values(T1 v1, T2 v2, T3 v3, T4 v4, + T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, + T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, + T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, + T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35) { + return internal::ValueArray35(v1, v2, v3, v4, v5, v6, + v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, + v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35); +} + +template +internal::ValueArray36 Values(T1 v1, T2 v2, T3 v3, T4 v4, + T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, + T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, + T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, + T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36) { + return internal::ValueArray36(v1, v2, v3, v4, + v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, + v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, + v34, v35, v36); +} + +template +internal::ValueArray37 Values(T1 v1, T2 v2, T3 v3, + T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, + T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, + T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, + T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, + T37 v37) { + return internal::ValueArray37(v1, v2, v3, + v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, + v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, + v34, v35, v36, v37); +} + +template +internal::ValueArray38 Values(T1 v1, T2 v2, + T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, + T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, + T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, + T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, + T37 v37, T38 v38) { + return internal::ValueArray38(v1, v2, + v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, + v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, + v33, v34, v35, v36, v37, v38); +} + +template +internal::ValueArray39 Values(T1 v1, T2 v2, + T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, + T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, + T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, + T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, + T37 v37, T38 v38, T39 v39) { + return internal::ValueArray39(v1, + v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, + v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, + v32, v33, v34, v35, v36, v37, v38, v39); +} + +template +internal::ValueArray40 Values(T1 v1, + T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, + T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, + T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, + T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, + T36 v36, T37 v37, T38 v38, T39 v39, T40 v40) { + return internal::ValueArray40(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, + v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, + v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40); +} + +template +internal::ValueArray41 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41) { + return internal::ValueArray41(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, + v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, + v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41); +} + +template +internal::ValueArray42 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42) { + return internal::ValueArray42(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, + v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, + v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, + v42); +} + +template +internal::ValueArray43 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43) { + return internal::ValueArray43(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, + v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, + v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, + v41, v42, v43); +} + +template +internal::ValueArray44 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44) { + return internal::ValueArray44(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, + v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, + v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, + v40, v41, v42, v43, v44); +} + +template +internal::ValueArray45 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, + T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, + T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, + T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, + T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, + T41 v41, T42 v42, T43 v43, T44 v44, T45 v45) { + return internal::ValueArray45(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, + v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, + v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, + v39, v40, v41, v42, v43, v44, v45); +} + +template +internal::ValueArray46 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, + T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, + T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, + T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46) { + return internal::ValueArray46(v1, v2, v3, v4, v5, v6, v7, v8, v9, + v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, + v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, + v38, v39, v40, v41, v42, v43, v44, v45, v46); +} + +template +internal::ValueArray47 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, + T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, + T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, + T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47) { + return internal::ValueArray47(v1, v2, v3, v4, v5, v6, v7, v8, + v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, + v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, + v38, v39, v40, v41, v42, v43, v44, v45, v46, v47); +} + +template +internal::ValueArray48 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, + T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, + T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, + T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, + T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, + T48 v48) { + return internal::ValueArray48(v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, + v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, + v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48); +} + +template +internal::ValueArray49 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, + T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, + T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, + T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, + T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, + T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, + T47 v47, T48 v48, T49 v49) { + return internal::ValueArray49(v1, v2, v3, v4, v5, v6, + v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, + v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, + v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49); +} + +template +internal::ValueArray50 Values(T1 v1, T2 v2, T3 v3, T4 v4, + T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, + T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, + T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, + T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, + T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, + T46 v46, T47 v47, T48 v48, T49 v49, T50 v50) { + return internal::ValueArray50(v1, v2, v3, v4, + v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, + v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, + v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, + v48, v49, v50); +} + +// Bool() allows generating tests with parameters in a set of (false, true). +// +// Synopsis: +// Bool() +// - returns a generator producing sequences with elements {false, true}. +// +// It is useful when testing code that depends on Boolean flags. Combinations +// of multiple flags can be tested when several Bool()'s are combined using +// Combine() function. +// +// In the following example all tests in the test case FlagDependentTest +// will be instantiated twice with parameters false and true. +// +// class FlagDependentTest : public testing::TestWithParam { +// virtual void SetUp() { +// external_flag = GetParam(); +// } +// } +// INSTANTIATE_TEST_CASE_P(BoolSequence, FlagDependentTest, Bool()); +// +inline internal::ParamGenerator Bool() { + return Values(false, true); +} + +# if GTEST_HAS_COMBINE +// Combine() allows the user to combine two or more sequences to produce +// values of a Cartesian product of those sequences' elements. +// +// Synopsis: +// Combine(gen1, gen2, ..., genN) +// - returns a generator producing sequences with elements coming from +// the Cartesian product of elements from the sequences generated by +// gen1, gen2, ..., genN. The sequence elements will have a type of +// tuple where T1, T2, ..., TN are the types +// of elements from sequences produces by gen1, gen2, ..., genN. +// +// Combine can have up to 10 arguments. This number is currently limited +// by the maximum number of elements in the tuple implementation used by Google +// Test. +// +// Example: +// +// This will instantiate tests in test case AnimalTest each one with +// the parameter values tuple("cat", BLACK), tuple("cat", WHITE), +// tuple("dog", BLACK), and tuple("dog", WHITE): +// +// enum Color { BLACK, GRAY, WHITE }; +// class AnimalTest +// : public testing::TestWithParam > {...}; +// +// TEST_P(AnimalTest, AnimalLooksNice) {...} +// +// INSTANTIATE_TEST_CASE_P(AnimalVariations, AnimalTest, +// Combine(Values("cat", "dog"), +// Values(BLACK, WHITE))); +// +// This will instantiate tests in FlagDependentTest with all variations of two +// Boolean flags: +// +// class FlagDependentTest +// : public testing::TestWithParam > { +// virtual void SetUp() { +// // Assigns external_flag_1 and external_flag_2 values from the tuple. +// tie(external_flag_1, external_flag_2) = GetParam(); +// } +// }; +// +// TEST_P(FlagDependentTest, TestFeature1) { +// // Test your code using external_flag_1 and external_flag_2 here. +// } +// INSTANTIATE_TEST_CASE_P(TwoBoolSequence, FlagDependentTest, +// Combine(Bool(), Bool())); +// +template +internal::CartesianProductHolder2 Combine( + const Generator1& g1, const Generator2& g2) { + return internal::CartesianProductHolder2( + g1, g2); +} + +template +internal::CartesianProductHolder3 Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3) { + return internal::CartesianProductHolder3( + g1, g2, g3); +} + +template +internal::CartesianProductHolder4 Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4) { + return internal::CartesianProductHolder4( + g1, g2, g3, g4); +} + +template +internal::CartesianProductHolder5 Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4, const Generator5& g5) { + return internal::CartesianProductHolder5( + g1, g2, g3, g4, g5); +} + +template +internal::CartesianProductHolder6 Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4, const Generator5& g5, const Generator6& g6) { + return internal::CartesianProductHolder6( + g1, g2, g3, g4, g5, g6); +} + +template +internal::CartesianProductHolder7 Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4, const Generator5& g5, const Generator6& g6, + const Generator7& g7) { + return internal::CartesianProductHolder7( + g1, g2, g3, g4, g5, g6, g7); +} + +template +internal::CartesianProductHolder8 Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4, const Generator5& g5, const Generator6& g6, + const Generator7& g7, const Generator8& g8) { + return internal::CartesianProductHolder8( + g1, g2, g3, g4, g5, g6, g7, g8); +} + +template +internal::CartesianProductHolder9 Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4, const Generator5& g5, const Generator6& g6, + const Generator7& g7, const Generator8& g8, const Generator9& g9) { + return internal::CartesianProductHolder9( + g1, g2, g3, g4, g5, g6, g7, g8, g9); +} + +template +internal::CartesianProductHolder10 Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4, const Generator5& g5, const Generator6& g6, + const Generator7& g7, const Generator8& g8, const Generator9& g9, + const Generator10& g10) { + return internal::CartesianProductHolder10( + g1, g2, g3, g4, g5, g6, g7, g8, g9, g10); +} +# endif // GTEST_HAS_COMBINE + + + +# define TEST_P(test_case_name, test_name) \ + class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \ + : public test_case_name { \ + public: \ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {} \ + virtual void TestBody(); \ + private: \ + static int AddToRegistry() { \ + ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \ + GetTestCasePatternHolder(\ + #test_case_name, __FILE__, __LINE__)->AddTestPattern(\ + #test_case_name, \ + #test_name, \ + new ::testing::internal::TestMetaFactory< \ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>()); \ + return 0; \ + } \ + static int gtest_registering_dummy_; \ + GTEST_DISALLOW_COPY_AND_ASSIGN_(\ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)); \ + }; \ + int GTEST_TEST_CLASS_NAME_(test_case_name, \ + test_name)::gtest_registering_dummy_ = \ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::AddToRegistry(); \ + void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody() + +# define INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) \ + ::testing::internal::ParamGenerator \ + gtest_##prefix##test_case_name##_EvalGenerator_() { return generator; } \ + int gtest_##prefix##test_case_name##_dummy_ = \ + ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \ + GetTestCasePatternHolder(\ + #test_case_name, __FILE__, __LINE__)->AddTestCaseInstantiation(\ + #prefix, \ + >est_##prefix##test_case_name##_EvalGenerator_, \ + __FILE__, __LINE__) + +} // namespace testing + +#endif // GTEST_HAS_PARAM_TEST + +#endif // GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ +// Copyright 2006, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) +// +// Google C++ Testing Framework definitions useful in production code. + +#ifndef GTEST_INCLUDE_GTEST_GTEST_PROD_H_ +#define GTEST_INCLUDE_GTEST_GTEST_PROD_H_ + +// When you need to test the private or protected members of a class, +// use the FRIEND_TEST macro to declare your tests as friends of the +// class. For example: +// +// class MyClass { +// private: +// void MyMethod(); +// FRIEND_TEST(MyClassTest, MyMethod); +// }; +// +// class MyClassTest : public testing::Test { +// // ... +// }; +// +// TEST_F(MyClassTest, MyMethod) { +// // Can call MyClass::MyMethod() here. +// } + +#define FRIEND_TEST(test_case_name, test_name)\ +friend class test_case_name##_##test_name##_Test + +#endif // GTEST_INCLUDE_GTEST_GTEST_PROD_H_ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: mheule@google.com (Markus Heule) +// + +#ifndef GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ +#define GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ + +#include +#include + +namespace testing { + +// A copyable object representing the result of a test part (i.e. an +// assertion or an explicit FAIL(), ADD_FAILURE(), or SUCCESS()). +// +// Don't inherit from TestPartResult as its destructor is not virtual. +class GTEST_API_ TestPartResult { + public: + // The possible outcomes of a test part (i.e. an assertion or an + // explicit SUCCEED(), FAIL(), or ADD_FAILURE()). + enum Type { + kSuccess, // Succeeded. + kNonFatalFailure, // Failed but the test can continue. + kFatalFailure // Failed and the test should be terminated. + }; + + // C'tor. TestPartResult does NOT have a default constructor. + // Always use this constructor (with parameters) to create a + // TestPartResult object. + TestPartResult(Type a_type, + const char* a_file_name, + int a_line_number, + const char* a_message) + : type_(a_type), + file_name_(a_file_name == NULL ? "" : a_file_name), + line_number_(a_line_number), + summary_(ExtractSummary(a_message)), + message_(a_message) { + } + + // Gets the outcome of the test part. + Type type() const { return type_; } + + // Gets the name of the source file where the test part took place, or + // NULL if it's unknown. + const char* file_name() const { + return file_name_.empty() ? NULL : file_name_.c_str(); + } + + // Gets the line in the source file where the test part took place, + // or -1 if it's unknown. + int line_number() const { return line_number_; } + + // Gets the summary of the failure message. + const char* summary() const { return summary_.c_str(); } + + // Gets the message associated with the test part. + const char* message() const { return message_.c_str(); } + + // Returns true iff the test part passed. + bool passed() const { return type_ == kSuccess; } + + // Returns true iff the test part failed. + bool failed() const { return type_ != kSuccess; } + + // Returns true iff the test part non-fatally failed. + bool nonfatally_failed() const { return type_ == kNonFatalFailure; } + + // Returns true iff the test part fatally failed. + bool fatally_failed() const { return type_ == kFatalFailure; } + + private: + Type type_; + + // Gets the summary of the failure message by omitting the stack + // trace in it. + static std::string ExtractSummary(const char* message); + + // The name of the source file where the test part took place, or + // "" if the source file is unknown. + std::string file_name_; + // The line in the source file where the test part took place, or -1 + // if the line number is unknown. + int line_number_; + std::string summary_; // The test failure summary. + std::string message_; // The test failure message. +}; + +// Prints a TestPartResult object. +std::ostream& operator<<(std::ostream& os, const TestPartResult& result); + +// An array of TestPartResult objects. +// +// Don't inherit from TestPartResultArray as its destructor is not +// virtual. +class GTEST_API_ TestPartResultArray { + public: + TestPartResultArray() {} + + // Appends the given TestPartResult to the array. + void Append(const TestPartResult& result); + + // Returns the TestPartResult at the given index (0-based). + const TestPartResult& GetTestPartResult(int index) const; + + // Returns the number of TestPartResult objects in the array. + int size() const; + + private: + std::vector array_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestPartResultArray); +}; + +// This interface knows how to report a test part result. +class TestPartResultReporterInterface { + public: + virtual ~TestPartResultReporterInterface() {} + + virtual void ReportTestPartResult(const TestPartResult& result) = 0; +}; + +namespace internal { + +// This helper class is used by {ASSERT|EXPECT}_NO_FATAL_FAILURE to check if a +// statement generates new fatal failures. To do so it registers itself as the +// current test part result reporter. Besides checking if fatal failures were +// reported, it only delegates the reporting to the former result reporter. +// The original result reporter is restored in the destructor. +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +class GTEST_API_ HasNewFatalFailureHelper + : public TestPartResultReporterInterface { + public: + HasNewFatalFailureHelper(); + virtual ~HasNewFatalFailureHelper(); + virtual void ReportTestPartResult(const TestPartResult& result); + bool has_new_fatal_failure() const { return has_new_fatal_failure_; } + private: + bool has_new_fatal_failure_; + TestPartResultReporterInterface* original_reporter_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(HasNewFatalFailureHelper); +}; + +} // namespace internal + +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) + +#ifndef GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ +#define GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ + +// This header implements typed tests and type-parameterized tests. + +// Typed (aka type-driven) tests repeat the same test for types in a +// list. You must know which types you want to test with when writing +// typed tests. Here's how you do it: + +#if 0 + +// First, define a fixture class template. It should be parameterized +// by a type. Remember to derive it from testing::Test. +template +class FooTest : public testing::Test { + public: + ... + typedef std::list List; + static T shared_; + T value_; +}; + +// Next, associate a list of types with the test case, which will be +// repeated for each type in the list. The typedef is necessary for +// the macro to parse correctly. +typedef testing::Types MyTypes; +TYPED_TEST_CASE(FooTest, MyTypes); + +// If the type list contains only one type, you can write that type +// directly without Types<...>: +// TYPED_TEST_CASE(FooTest, int); + +// Then, use TYPED_TEST() instead of TEST_F() to define as many typed +// tests for this test case as you want. +TYPED_TEST(FooTest, DoesBlah) { + // Inside a test, refer to TypeParam to get the type parameter. + // Since we are inside a derived class template, C++ requires use to + // visit the members of FooTest via 'this'. + TypeParam n = this->value_; + + // To visit static members of the fixture, add the TestFixture:: + // prefix. + n += TestFixture::shared_; + + // To refer to typedefs in the fixture, add the "typename + // TestFixture::" prefix. + typename TestFixture::List values; + values.push_back(n); + ... +} + +TYPED_TEST(FooTest, HasPropertyA) { ... } + +#endif // 0 + +// Type-parameterized tests are abstract test patterns parameterized +// by a type. Compared with typed tests, type-parameterized tests +// allow you to define the test pattern without knowing what the type +// parameters are. The defined pattern can be instantiated with +// different types any number of times, in any number of translation +// units. +// +// If you are designing an interface or concept, you can define a +// suite of type-parameterized tests to verify properties that any +// valid implementation of the interface/concept should have. Then, +// each implementation can easily instantiate the test suite to verify +// that it conforms to the requirements, without having to write +// similar tests repeatedly. Here's an example: + +#if 0 + +// First, define a fixture class template. It should be parameterized +// by a type. Remember to derive it from testing::Test. +template +class FooTest : public testing::Test { + ... +}; + +// Next, declare that you will define a type-parameterized test case +// (the _P suffix is for "parameterized" or "pattern", whichever you +// prefer): +TYPED_TEST_CASE_P(FooTest); + +// Then, use TYPED_TEST_P() to define as many type-parameterized tests +// for this type-parameterized test case as you want. +TYPED_TEST_P(FooTest, DoesBlah) { + // Inside a test, refer to TypeParam to get the type parameter. + TypeParam n = 0; + ... +} + +TYPED_TEST_P(FooTest, HasPropertyA) { ... } + +// Now the tricky part: you need to register all test patterns before +// you can instantiate them. The first argument of the macro is the +// test case name; the rest are the names of the tests in this test +// case. +REGISTER_TYPED_TEST_CASE_P(FooTest, + DoesBlah, HasPropertyA); + +// Finally, you are free to instantiate the pattern with the types you +// want. If you put the above code in a header file, you can #include +// it in multiple C++ source files and instantiate it multiple times. +// +// To distinguish different instances of the pattern, the first +// argument to the INSTANTIATE_* macro is a prefix that will be added +// to the actual test case name. Remember to pick unique prefixes for +// different instances. +typedef testing::Types MyTypes; +INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes); + +// If the type list contains only one type, you can write that type +// directly without Types<...>: +// INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, int); + +#endif // 0 + + +// Implements typed tests. + +#if GTEST_HAS_TYPED_TEST + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Expands to the name of the typedef for the type parameters of the +// given test case. +# define GTEST_TYPE_PARAMS_(TestCaseName) gtest_type_params_##TestCaseName##_ + +// The 'Types' template argument below must have spaces around it +// since some compilers may choke on '>>' when passing a template +// instance (e.g. Types) +# define TYPED_TEST_CASE(CaseName, Types) \ + typedef ::testing::internal::TypeList< Types >::type \ + GTEST_TYPE_PARAMS_(CaseName) + +# define TYPED_TEST(CaseName, TestName) \ + template \ + class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \ + : public CaseName { \ + private: \ + typedef CaseName TestFixture; \ + typedef gtest_TypeParam_ TypeParam; \ + virtual void TestBody(); \ + }; \ + bool gtest_##CaseName##_##TestName##_registered_ GTEST_ATTRIBUTE_UNUSED_ = \ + ::testing::internal::TypeParameterizedTest< \ + CaseName, \ + ::testing::internal::TemplateSel< \ + GTEST_TEST_CLASS_NAME_(CaseName, TestName)>, \ + GTEST_TYPE_PARAMS_(CaseName)>::Register(\ + "", #CaseName, #TestName, 0); \ + template \ + void GTEST_TEST_CLASS_NAME_(CaseName, TestName)::TestBody() + +#endif // GTEST_HAS_TYPED_TEST + +// Implements type-parameterized tests. + +#if GTEST_HAS_TYPED_TEST_P + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Expands to the namespace name that the type-parameterized tests for +// the given type-parameterized test case are defined in. The exact +// name of the namespace is subject to change without notice. +# define GTEST_CASE_NAMESPACE_(TestCaseName) \ + gtest_case_##TestCaseName##_ + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Expands to the name of the variable used to remember the names of +// the defined tests in the given test case. +# define GTEST_TYPED_TEST_CASE_P_STATE_(TestCaseName) \ + gtest_typed_test_case_p_state_##TestCaseName##_ + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE DIRECTLY. +// +// Expands to the name of the variable used to remember the names of +// the registered tests in the given test case. +# define GTEST_REGISTERED_TEST_NAMES_(TestCaseName) \ + gtest_registered_test_names_##TestCaseName##_ + +// The variables defined in the type-parameterized test macros are +// static as typically these macros are used in a .h file that can be +// #included in multiple translation units linked together. +# define TYPED_TEST_CASE_P(CaseName) \ + static ::testing::internal::TypedTestCasePState \ + GTEST_TYPED_TEST_CASE_P_STATE_(CaseName) + +# define TYPED_TEST_P(CaseName, TestName) \ + namespace GTEST_CASE_NAMESPACE_(CaseName) { \ + template \ + class TestName : public CaseName { \ + private: \ + typedef CaseName TestFixture; \ + typedef gtest_TypeParam_ TypeParam; \ + virtual void TestBody(); \ + }; \ + static bool gtest_##TestName##_defined_ GTEST_ATTRIBUTE_UNUSED_ = \ + GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).AddTestName(\ + __FILE__, __LINE__, #CaseName, #TestName); \ + } \ + template \ + void GTEST_CASE_NAMESPACE_(CaseName)::TestName::TestBody() + +# define REGISTER_TYPED_TEST_CASE_P(CaseName, ...) \ + namespace GTEST_CASE_NAMESPACE_(CaseName) { \ + typedef ::testing::internal::Templates<__VA_ARGS__>::type gtest_AllTests_; \ + } \ + static const char* const GTEST_REGISTERED_TEST_NAMES_(CaseName) = \ + GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).VerifyRegisteredTestNames(\ + __FILE__, __LINE__, #__VA_ARGS__) + +// The 'Types' template argument below must have spaces around it +// since some compilers may choke on '>>' when passing a template +// instance (e.g. Types) +# define INSTANTIATE_TYPED_TEST_CASE_P(Prefix, CaseName, Types) \ + bool gtest_##Prefix##_##CaseName GTEST_ATTRIBUTE_UNUSED_ = \ + ::testing::internal::TypeParameterizedTestCase::type>::Register(\ + #Prefix, #CaseName, GTEST_REGISTERED_TEST_NAMES_(CaseName)) + +#endif // GTEST_HAS_TYPED_TEST_P + +#endif // GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ + +// Depending on the platform, different string classes are available. +// On Linux, in addition to ::std::string, Google also makes use of +// class ::string, which has the same interface as ::std::string, but +// has a different implementation. +// +// The user can define GTEST_HAS_GLOBAL_STRING to 1 to indicate that +// ::string is available AND is a distinct type to ::std::string, or +// define it to 0 to indicate otherwise. +// +// If the user's ::std::string and ::string are the same class due to +// aliasing, he should define GTEST_HAS_GLOBAL_STRING to 0. +// +// If the user doesn't define GTEST_HAS_GLOBAL_STRING, it is defined +// heuristically. + +namespace testing { + +// Declares the flags. + +// This flag temporary enables the disabled tests. +GTEST_DECLARE_bool_(also_run_disabled_tests); + +// This flag brings the debugger on an assertion failure. +GTEST_DECLARE_bool_(break_on_failure); + +// This flag controls whether Google Test catches all test-thrown exceptions +// and logs them as failures. +GTEST_DECLARE_bool_(catch_exceptions); + +// This flag enables using colors in terminal output. Available values are +// "yes" to enable colors, "no" (disable colors), or "auto" (the default) +// to let Google Test decide. +GTEST_DECLARE_string_(color); + +// This flag sets up the filter to select by name using a glob pattern +// the tests to run. If the filter is not given all tests are executed. +GTEST_DECLARE_string_(filter); + +// This flag causes the Google Test to list tests. None of the tests listed +// are actually run if the flag is provided. +GTEST_DECLARE_bool_(list_tests); + +// This flag controls whether Google Test emits a detailed XML report to a file +// in addition to its normal textual output. +GTEST_DECLARE_string_(output); + +// This flags control whether Google Test prints the elapsed time for each +// test. +GTEST_DECLARE_bool_(print_time); + +// This flag specifies the random number seed. +GTEST_DECLARE_int32_(random_seed); + +// This flag sets how many times the tests are repeated. The default value +// is 1. If the value is -1 the tests are repeating forever. +GTEST_DECLARE_int32_(repeat); + +// This flag controls whether Google Test includes Google Test internal +// stack frames in failure stack traces. +GTEST_DECLARE_bool_(show_internal_stack_frames); + +// When this flag is specified, tests' order is randomized on every iteration. +GTEST_DECLARE_bool_(shuffle); + +// This flag specifies the maximum number of stack frames to be +// printed in a failure message. +GTEST_DECLARE_int32_(stack_trace_depth); + +// When this flag is specified, a failed assertion will throw an +// exception if exceptions are enabled, or exit the program with a +// non-zero code otherwise. +GTEST_DECLARE_bool_(throw_on_failure); + +// When this flag is set with a "host:port" string, on supported +// platforms test results are streamed to the specified port on +// the specified host machine. +GTEST_DECLARE_string_(stream_result_to); + +// The upper limit for valid stack trace depths. +const int kMaxStackTraceDepth = 100; + +namespace internal { + +class AssertHelper; +class DefaultGlobalTestPartResultReporter; +class ExecDeathTest; +class NoExecDeathTest; +class FinalSuccessChecker; +class GTestFlagSaver; +class StreamingListenerTest; +class TestResultAccessor; +class TestEventListenersAccessor; +class TestEventRepeater; +class UnitTestRecordPropertyTestHelper; +class WindowsDeathTest; +class UnitTestImpl* GetUnitTestImpl(); +void ReportFailureInUnknownLocation(TestPartResult::Type result_type, + const std::string& message); + +} // namespace internal + +// The friend relationship of some of these classes is cyclic. +// If we don't forward declare them the compiler might confuse the classes +// in friendship clauses with same named classes on the scope. +class Test; +class TestCase; +class TestInfo; +class UnitTest; + +// A class for indicating whether an assertion was successful. When +// the assertion wasn't successful, the AssertionResult object +// remembers a non-empty message that describes how it failed. +// +// To create an instance of this class, use one of the factory functions +// (AssertionSuccess() and AssertionFailure()). +// +// This class is useful for two purposes: +// 1. Defining predicate functions to be used with Boolean test assertions +// EXPECT_TRUE/EXPECT_FALSE and their ASSERT_ counterparts +// 2. Defining predicate-format functions to be +// used with predicate assertions (ASSERT_PRED_FORMAT*, etc). +// +// For example, if you define IsEven predicate: +// +// testing::AssertionResult IsEven(int n) { +// if ((n % 2) == 0) +// return testing::AssertionSuccess(); +// else +// return testing::AssertionFailure() << n << " is odd"; +// } +// +// Then the failed expectation EXPECT_TRUE(IsEven(Fib(5))) +// will print the message +// +// Value of: IsEven(Fib(5)) +// Actual: false (5 is odd) +// Expected: true +// +// instead of a more opaque +// +// Value of: IsEven(Fib(5)) +// Actual: false +// Expected: true +// +// in case IsEven is a simple Boolean predicate. +// +// If you expect your predicate to be reused and want to support informative +// messages in EXPECT_FALSE and ASSERT_FALSE (negative assertions show up +// about half as often as positive ones in our tests), supply messages for +// both success and failure cases: +// +// testing::AssertionResult IsEven(int n) { +// if ((n % 2) == 0) +// return testing::AssertionSuccess() << n << " is even"; +// else +// return testing::AssertionFailure() << n << " is odd"; +// } +// +// Then a statement EXPECT_FALSE(IsEven(Fib(6))) will print +// +// Value of: IsEven(Fib(6)) +// Actual: true (8 is even) +// Expected: false +// +// NB: Predicates that support negative Boolean assertions have reduced +// performance in positive ones so be careful not to use them in tests +// that have lots (tens of thousands) of positive Boolean assertions. +// +// To use this class with EXPECT_PRED_FORMAT assertions such as: +// +// // Verifies that Foo() returns an even number. +// EXPECT_PRED_FORMAT1(IsEven, Foo()); +// +// you need to define: +// +// testing::AssertionResult IsEven(const char* expr, int n) { +// if ((n % 2) == 0) +// return testing::AssertionSuccess(); +// else +// return testing::AssertionFailure() +// << "Expected: " << expr << " is even\n Actual: it's " << n; +// } +// +// If Foo() returns 5, you will see the following message: +// +// Expected: Foo() is even +// Actual: it's 5 +// +class GTEST_API_ AssertionResult { + public: + // Copy constructor. + // Used in EXPECT_TRUE/FALSE(assertion_result). + AssertionResult(const AssertionResult& other); + // Used in the EXPECT_TRUE/FALSE(bool_expression). + explicit AssertionResult(bool success) : success_(success) {} + + // Returns true iff the assertion succeeded. + operator bool() const { return success_; } // NOLINT + + // Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE. + AssertionResult operator!() const; + + // Returns the text streamed into this AssertionResult. Test assertions + // use it when they fail (i.e., the predicate's outcome doesn't match the + // assertion's expectation). When nothing has been streamed into the + // object, returns an empty string. + const char* message() const { + return message_.get() != NULL ? message_->c_str() : ""; + } + // TODO(vladl@google.com): Remove this after making sure no clients use it. + // Deprecated; please use message() instead. + const char* failure_message() const { return message(); } + + // Streams a custom failure message into this object. + template AssertionResult& operator<<(const T& value) { + AppendMessage(Message() << value); + return *this; + } + + // Allows streaming basic output manipulators such as endl or flush into + // this object. + AssertionResult& operator<<( + ::std::ostream& (*basic_manipulator)(::std::ostream& stream)) { + AppendMessage(Message() << basic_manipulator); + return *this; + } + + private: + // Appends the contents of message to message_. + void AppendMessage(const Message& a_message) { + if (message_.get() == NULL) + message_.reset(new ::std::string); + message_->append(a_message.GetString().c_str()); + } + + // Stores result of the assertion predicate. + bool success_; + // Stores the message describing the condition in case the expectation + // construct is not satisfied with the predicate's outcome. + // Referenced via a pointer to avoid taking too much stack frame space + // with test assertions. + internal::scoped_ptr< ::std::string> message_; + + GTEST_DISALLOW_ASSIGN_(AssertionResult); +}; + +// Makes a successful assertion result. +GTEST_API_ AssertionResult AssertionSuccess(); + +// Makes a failed assertion result. +GTEST_API_ AssertionResult AssertionFailure(); + +// Makes a failed assertion result with the given failure message. +// Deprecated; use AssertionFailure() << msg. +GTEST_API_ AssertionResult AssertionFailure(const Message& msg); + +// The abstract class that all tests inherit from. +// +// In Google Test, a unit test program contains one or many TestCases, and +// each TestCase contains one or many Tests. +// +// When you define a test using the TEST macro, you don't need to +// explicitly derive from Test - the TEST macro automatically does +// this for you. +// +// The only time you derive from Test is when defining a test fixture +// to be used a TEST_F. For example: +// +// class FooTest : public testing::Test { +// protected: +// virtual void SetUp() { ... } +// virtual void TearDown() { ... } +// ... +// }; +// +// TEST_F(FooTest, Bar) { ... } +// TEST_F(FooTest, Baz) { ... } +// +// Test is not copyable. +class GTEST_API_ Test { + public: + friend class TestInfo; + + // Defines types for pointers to functions that set up and tear down + // a test case. + typedef internal::SetUpTestCaseFunc SetUpTestCaseFunc; + typedef internal::TearDownTestCaseFunc TearDownTestCaseFunc; + + // The d'tor is virtual as we intend to inherit from Test. + virtual ~Test(); + + // Sets up the stuff shared by all tests in this test case. + // + // Google Test will call Foo::SetUpTestCase() before running the first + // test in test case Foo. Hence a sub-class can define its own + // SetUpTestCase() method to shadow the one defined in the super + // class. + static void SetUpTestCase() {} + + // Tears down the stuff shared by all tests in this test case. + // + // Google Test will call Foo::TearDownTestCase() after running the last + // test in test case Foo. Hence a sub-class can define its own + // TearDownTestCase() method to shadow the one defined in the super + // class. + static void TearDownTestCase() {} + + // Returns true iff the current test has a fatal failure. + static bool HasFatalFailure(); + + // Returns true iff the current test has a non-fatal failure. + static bool HasNonfatalFailure(); + + // Returns true iff the current test has a (either fatal or + // non-fatal) failure. + static bool HasFailure() { return HasFatalFailure() || HasNonfatalFailure(); } + + // Logs a property for the current test, test case, or for the entire + // invocation of the test program when used outside of the context of a + // test case. Only the last value for a given key is remembered. These + // are public static so they can be called from utility functions that are + // not members of the test fixture. Calls to RecordProperty made during + // lifespan of the test (from the moment its constructor starts to the + // moment its destructor finishes) will be output in XML as attributes of + // the element. Properties recorded from fixture's + // SetUpTestCase or TearDownTestCase are logged as attributes of the + // corresponding element. Calls to RecordProperty made in the + // global context (before or after invocation of RUN_ALL_TESTS and from + // SetUp/TearDown method of Environment objects registered with Google + // Test) will be output as attributes of the element. + static void RecordProperty(const std::string& key, const std::string& value); + static void RecordProperty(const std::string& key, int value); + + protected: + // Creates a Test object. + Test(); + + // Sets up the test fixture. + virtual void SetUp(); + + // Tears down the test fixture. + virtual void TearDown(); + + private: + // Returns true iff the current test has the same fixture class as + // the first test in the current test case. + static bool HasSameFixtureClass(); + + // Runs the test after the test fixture has been set up. + // + // A sub-class must implement this to define the test logic. + // + // DO NOT OVERRIDE THIS FUNCTION DIRECTLY IN A USER PROGRAM. + // Instead, use the TEST or TEST_F macro. + virtual void TestBody() = 0; + + // Sets up, executes, and tears down the test. + void Run(); + + // Deletes self. We deliberately pick an unusual name for this + // internal method to avoid clashing with names used in user TESTs. + void DeleteSelf_() { delete this; } + + // Uses a GTestFlagSaver to save and restore all Google Test flags. + const internal::GTestFlagSaver* const gtest_flag_saver_; + + // Often a user mis-spells SetUp() as Setup() and spends a long time + // wondering why it is never called by Google Test. The declaration of + // the following method is solely for catching such an error at + // compile time: + // + // - The return type is deliberately chosen to be not void, so it + // will be a conflict if a user declares void Setup() in his test + // fixture. + // + // - This method is private, so it will be another compiler error + // if a user calls it from his test fixture. + // + // DO NOT OVERRIDE THIS FUNCTION. + // + // If you see an error about overriding the following function or + // about it being private, you have mis-spelled SetUp() as Setup(). + struct Setup_should_be_spelled_SetUp {}; + virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; } + + // We disallow copying Tests. + GTEST_DISALLOW_COPY_AND_ASSIGN_(Test); +}; + +typedef internal::TimeInMillis TimeInMillis; + +// A copyable object representing a user specified test property which can be +// output as a key/value string pair. +// +// Don't inherit from TestProperty as its destructor is not virtual. +class TestProperty { + public: + // C'tor. TestProperty does NOT have a default constructor. + // Always use this constructor (with parameters) to create a + // TestProperty object. + TestProperty(const std::string& a_key, const std::string& a_value) : + key_(a_key), value_(a_value) { + } + + // Gets the user supplied key. + const char* key() const { + return key_.c_str(); + } + + // Gets the user supplied value. + const char* value() const { + return value_.c_str(); + } + + // Sets a new value, overriding the one supplied in the constructor. + void SetValue(const std::string& new_value) { + value_ = new_value; + } + + private: + // The key supplied by the user. + std::string key_; + // The value supplied by the user. + std::string value_; +}; + +// The result of a single Test. This includes a list of +// TestPartResults, a list of TestProperties, a count of how many +// death tests there are in the Test, and how much time it took to run +// the Test. +// +// TestResult is not copyable. +class GTEST_API_ TestResult { + public: + // Creates an empty TestResult. + TestResult(); + + // D'tor. Do not inherit from TestResult. + ~TestResult(); + + // Gets the number of all test parts. This is the sum of the number + // of successful test parts and the number of failed test parts. + int total_part_count() const; + + // Returns the number of the test properties. + int test_property_count() const; + + // Returns true iff the test passed (i.e. no test part failed). + bool Passed() const { return !Failed(); } + + // Returns true iff the test failed. + bool Failed() const; + + // Returns true iff the test fatally failed. + bool HasFatalFailure() const; + + // Returns true iff the test has a non-fatal failure. + bool HasNonfatalFailure() const; + + // Returns the elapsed time, in milliseconds. + TimeInMillis elapsed_time() const { return elapsed_time_; } + + // Returns the i-th test part result among all the results. i can range + // from 0 to test_property_count() - 1. If i is not in that range, aborts + // the program. + const TestPartResult& GetTestPartResult(int i) const; + + // Returns the i-th test property. i can range from 0 to + // test_property_count() - 1. If i is not in that range, aborts the + // program. + const TestProperty& GetTestProperty(int i) const; + + private: + friend class TestInfo; + friend class TestCase; + friend class UnitTest; + friend class internal::DefaultGlobalTestPartResultReporter; + friend class internal::ExecDeathTest; + friend class internal::TestResultAccessor; + friend class internal::UnitTestImpl; + friend class internal::WindowsDeathTest; + + // Gets the vector of TestPartResults. + const std::vector& test_part_results() const { + return test_part_results_; + } + + // Gets the vector of TestProperties. + const std::vector& test_properties() const { + return test_properties_; + } + + // Sets the elapsed time. + void set_elapsed_time(TimeInMillis elapsed) { elapsed_time_ = elapsed; } + + // Adds a test property to the list. The property is validated and may add + // a non-fatal failure if invalid (e.g., if it conflicts with reserved + // key names). If a property is already recorded for the same key, the + // value will be updated, rather than storing multiple values for the same + // key. xml_element specifies the element for which the property is being + // recorded and is used for validation. + void RecordProperty(const std::string& xml_element, + const TestProperty& test_property); + + // Adds a failure if the key is a reserved attribute of Google Test + // testcase tags. Returns true if the property is valid. + // TODO(russr): Validate attribute names are legal and human readable. + static bool ValidateTestProperty(const std::string& xml_element, + const TestProperty& test_property); + + // Adds a test part result to the list. + void AddTestPartResult(const TestPartResult& test_part_result); + + // Returns the death test count. + int death_test_count() const { return death_test_count_; } + + // Increments the death test count, returning the new count. + int increment_death_test_count() { return ++death_test_count_; } + + // Clears the test part results. + void ClearTestPartResults(); + + // Clears the object. + void Clear(); + + // Protects mutable state of the property vector and of owned + // properties, whose values may be updated. + internal::Mutex test_properites_mutex_; + + // The vector of TestPartResults + std::vector test_part_results_; + // The vector of TestProperties + std::vector test_properties_; + // Running count of death tests. + int death_test_count_; + // The elapsed time, in milliseconds. + TimeInMillis elapsed_time_; + + // We disallow copying TestResult. + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestResult); +}; // class TestResult + +// A TestInfo object stores the following information about a test: +// +// Test case name +// Test name +// Whether the test should be run +// A function pointer that creates the test object when invoked +// Test result +// +// The constructor of TestInfo registers itself with the UnitTest +// singleton such that the RUN_ALL_TESTS() macro knows which tests to +// run. +class GTEST_API_ TestInfo { + public: + // Destructs a TestInfo object. This function is not virtual, so + // don't inherit from TestInfo. + ~TestInfo(); + + // Returns the test case name. + const char* test_case_name() const { return test_case_name_.c_str(); } + + // Returns the test name. + const char* name() const { return name_.c_str(); } + + // Returns the name of the parameter type, or NULL if this is not a typed + // or a type-parameterized test. + const char* type_param() const { + if (type_param_.get() != NULL) + return type_param_->c_str(); + return NULL; + } + + // Returns the text representation of the value parameter, or NULL if this + // is not a value-parameterized test. + const char* value_param() const { + if (value_param_.get() != NULL) + return value_param_->c_str(); + return NULL; + } + + // Returns true if this test should run, that is if the test is not + // disabled (or it is disabled but the also_run_disabled_tests flag has + // been specified) and its full name matches the user-specified filter. + // + // Google Test allows the user to filter the tests by their full names. + // The full name of a test Bar in test case Foo is defined as + // "Foo.Bar". Only the tests that match the filter will run. + // + // A filter is a colon-separated list of glob (not regex) patterns, + // optionally followed by a '-' and a colon-separated list of + // negative patterns (tests to exclude). A test is run if it + // matches one of the positive patterns and does not match any of + // the negative patterns. + // + // For example, *A*:Foo.* is a filter that matches any string that + // contains the character 'A' or starts with "Foo.". + bool should_run() const { return should_run_; } + + // Returns true iff this test will appear in the XML report. + bool is_reportable() const { + // For now, the XML report includes all tests matching the filter. + // In the future, we may trim tests that are excluded because of + // sharding. + return matches_filter_; + } + + // Returns the result of the test. + const TestResult* result() const { return &result_; } + + private: +#if GTEST_HAS_DEATH_TEST + friend class internal::DefaultDeathTestFactory; +#endif // GTEST_HAS_DEATH_TEST + friend class Test; + friend class TestCase; + friend class internal::UnitTestImpl; + friend class internal::StreamingListenerTest; + friend TestInfo* internal::MakeAndRegisterTestInfo( + const char* test_case_name, + const char* name, + const char* type_param, + const char* value_param, + internal::TypeId fixture_class_id, + Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc, + internal::TestFactoryBase* factory); + + // Constructs a TestInfo object. The newly constructed instance assumes + // ownership of the factory object. + TestInfo(const std::string& test_case_name, + const std::string& name, + const char* a_type_param, // NULL if not a type-parameterized test + const char* a_value_param, // NULL if not a value-parameterized test + internal::TypeId fixture_class_id, + internal::TestFactoryBase* factory); + + // Increments the number of death tests encountered in this test so + // far. + int increment_death_test_count() { + return result_.increment_death_test_count(); + } + + // Creates the test object, runs it, records its result, and then + // deletes it. + void Run(); + + static void ClearTestResult(TestInfo* test_info) { + test_info->result_.Clear(); + } + + // These fields are immutable properties of the test. + const std::string test_case_name_; // Test case name + const std::string name_; // Test name + // Name of the parameter type, or NULL if this is not a typed or a + // type-parameterized test. + const internal::scoped_ptr type_param_; + // Text representation of the value parameter, or NULL if this is not a + // value-parameterized test. + const internal::scoped_ptr value_param_; + const internal::TypeId fixture_class_id_; // ID of the test fixture class + bool should_run_; // True iff this test should run + bool is_disabled_; // True iff this test is disabled + bool matches_filter_; // True if this test matches the + // user-specified filter. + internal::TestFactoryBase* const factory_; // The factory that creates + // the test object + + // This field is mutable and needs to be reset before running the + // test for the second time. + TestResult result_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestInfo); +}; + +// A test case, which consists of a vector of TestInfos. +// +// TestCase is not copyable. +class GTEST_API_ TestCase { + public: + // Creates a TestCase with the given name. + // + // TestCase does NOT have a default constructor. Always use this + // constructor to create a TestCase object. + // + // Arguments: + // + // name: name of the test case + // a_type_param: the name of the test's type parameter, or NULL if + // this is not a type-parameterized test. + // set_up_tc: pointer to the function that sets up the test case + // tear_down_tc: pointer to the function that tears down the test case + TestCase(const char* name, const char* a_type_param, + Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc); + + // Destructor of TestCase. + virtual ~TestCase(); + + // Gets the name of the TestCase. + const char* name() const { return name_.c_str(); } + + // Returns the name of the parameter type, or NULL if this is not a + // type-parameterized test case. + const char* type_param() const { + if (type_param_.get() != NULL) + return type_param_->c_str(); + return NULL; + } + + // Returns true if any test in this test case should run. + bool should_run() const { return should_run_; } + + // Gets the number of successful tests in this test case. + int successful_test_count() const; + + // Gets the number of failed tests in this test case. + int failed_test_count() const; + + // Gets the number of disabled tests that will be reported in the XML report. + int reportable_disabled_test_count() const; + + // Gets the number of disabled tests in this test case. + int disabled_test_count() const; + + // Gets the number of tests to be printed in the XML report. + int reportable_test_count() const; + + // Get the number of tests in this test case that should run. + int test_to_run_count() const; + + // Gets the number of all tests in this test case. + int total_test_count() const; + + // Returns true iff the test case passed. + bool Passed() const { return !Failed(); } + + // Returns true iff the test case failed. + bool Failed() const { return failed_test_count() > 0; } + + // Returns the elapsed time, in milliseconds. + TimeInMillis elapsed_time() const { return elapsed_time_; } + + // Returns the i-th test among all the tests. i can range from 0 to + // total_test_count() - 1. If i is not in that range, returns NULL. + const TestInfo* GetTestInfo(int i) const; + + // Returns the TestResult that holds test properties recorded during + // execution of SetUpTestCase and TearDownTestCase. + const TestResult& ad_hoc_test_result() const { return ad_hoc_test_result_; } + + private: + friend class Test; + friend class internal::UnitTestImpl; + + // Gets the (mutable) vector of TestInfos in this TestCase. + std::vector& test_info_list() { return test_info_list_; } + + // Gets the (immutable) vector of TestInfos in this TestCase. + const std::vector& test_info_list() const { + return test_info_list_; + } + + // Returns the i-th test among all the tests. i can range from 0 to + // total_test_count() - 1. If i is not in that range, returns NULL. + TestInfo* GetMutableTestInfo(int i); + + // Sets the should_run member. + void set_should_run(bool should) { should_run_ = should; } + + // Adds a TestInfo to this test case. Will delete the TestInfo upon + // destruction of the TestCase object. + void AddTestInfo(TestInfo * test_info); + + // Clears the results of all tests in this test case. + void ClearResult(); + + // Clears the results of all tests in the given test case. + static void ClearTestCaseResult(TestCase* test_case) { + test_case->ClearResult(); + } + + // Runs every test in this TestCase. + void Run(); + + // Runs SetUpTestCase() for this TestCase. This wrapper is needed + // for catching exceptions thrown from SetUpTestCase(). + void RunSetUpTestCase() { (*set_up_tc_)(); } + + // Runs TearDownTestCase() for this TestCase. This wrapper is + // needed for catching exceptions thrown from TearDownTestCase(). + void RunTearDownTestCase() { (*tear_down_tc_)(); } + + // Returns true iff test passed. + static bool TestPassed(const TestInfo* test_info) { + return test_info->should_run() && test_info->result()->Passed(); + } + + // Returns true iff test failed. + static bool TestFailed(const TestInfo* test_info) { + return test_info->should_run() && test_info->result()->Failed(); + } + + // Returns true iff the test is disabled and will be reported in the XML + // report. + static bool TestReportableDisabled(const TestInfo* test_info) { + return test_info->is_reportable() && test_info->is_disabled_; + } + + // Returns true iff test is disabled. + static bool TestDisabled(const TestInfo* test_info) { + return test_info->is_disabled_; + } + + // Returns true iff this test will appear in the XML report. + static bool TestReportable(const TestInfo* test_info) { + return test_info->is_reportable(); + } + + // Returns true if the given test should run. + static bool ShouldRunTest(const TestInfo* test_info) { + return test_info->should_run(); + } + + // Shuffles the tests in this test case. + void ShuffleTests(internal::Random* random); + + // Restores the test order to before the first shuffle. + void UnshuffleTests(); + + // Name of the test case. + std::string name_; + // Name of the parameter type, or NULL if this is not a typed or a + // type-parameterized test. + const internal::scoped_ptr type_param_; + // The vector of TestInfos in their original order. It owns the + // elements in the vector. + std::vector test_info_list_; + // Provides a level of indirection for the test list to allow easy + // shuffling and restoring the test order. The i-th element in this + // vector is the index of the i-th test in the shuffled test list. + std::vector test_indices_; + // Pointer to the function that sets up the test case. + Test::SetUpTestCaseFunc set_up_tc_; + // Pointer to the function that tears down the test case. + Test::TearDownTestCaseFunc tear_down_tc_; + // True iff any test in this test case should run. + bool should_run_; + // Elapsed time, in milliseconds. + TimeInMillis elapsed_time_; + // Holds test properties recorded during execution of SetUpTestCase and + // TearDownTestCase. + TestResult ad_hoc_test_result_; + + // We disallow copying TestCases. + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestCase); +}; + +// An Environment object is capable of setting up and tearing down an +// environment. The user should subclass this to define his own +// environment(s). +// +// An Environment object does the set-up and tear-down in virtual +// methods SetUp() and TearDown() instead of the constructor and the +// destructor, as: +// +// 1. You cannot safely throw from a destructor. This is a problem +// as in some cases Google Test is used where exceptions are enabled, and +// we may want to implement ASSERT_* using exceptions where they are +// available. +// 2. You cannot use ASSERT_* directly in a constructor or +// destructor. +class Environment { + public: + // The d'tor is virtual as we need to subclass Environment. + virtual ~Environment() {} + + // Override this to define how to set up the environment. + virtual void SetUp() {} + + // Override this to define how to tear down the environment. + virtual void TearDown() {} + private: + // If you see an error about overriding the following function or + // about it being private, you have mis-spelled SetUp() as Setup(). + struct Setup_should_be_spelled_SetUp {}; + virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; } +}; + +// The interface for tracing execution of tests. The methods are organized in +// the order the corresponding events are fired. +class TestEventListener { + public: + virtual ~TestEventListener() {} + + // Fired before any test activity starts. + virtual void OnTestProgramStart(const UnitTest& unit_test) = 0; + + // Fired before each iteration of tests starts. There may be more than + // one iteration if GTEST_FLAG(repeat) is set. iteration is the iteration + // index, starting from 0. + virtual void OnTestIterationStart(const UnitTest& unit_test, + int iteration) = 0; + + // Fired before environment set-up for each iteration of tests starts. + virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test) = 0; + + // Fired after environment set-up for each iteration of tests ends. + virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test) = 0; + + // Fired before the test case starts. + virtual void OnTestCaseStart(const TestCase& test_case) = 0; + + // Fired before the test starts. + virtual void OnTestStart(const TestInfo& test_info) = 0; + + // Fired after a failed assertion or a SUCCEED() invocation. + virtual void OnTestPartResult(const TestPartResult& test_part_result) = 0; + + // Fired after the test ends. + virtual void OnTestEnd(const TestInfo& test_info) = 0; + + // Fired after the test case ends. + virtual void OnTestCaseEnd(const TestCase& test_case) = 0; + + // Fired before environment tear-down for each iteration of tests starts. + virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test) = 0; + + // Fired after environment tear-down for each iteration of tests ends. + virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test) = 0; + + // Fired after each iteration of tests finishes. + virtual void OnTestIterationEnd(const UnitTest& unit_test, + int iteration) = 0; + + // Fired after all test activities have ended. + virtual void OnTestProgramEnd(const UnitTest& unit_test) = 0; +}; + +// The convenience class for users who need to override just one or two +// methods and are not concerned that a possible change to a signature of +// the methods they override will not be caught during the build. For +// comments about each method please see the definition of TestEventListener +// above. +class EmptyTestEventListener : public TestEventListener { + public: + virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {} + virtual void OnTestIterationStart(const UnitTest& /*unit_test*/, + int /*iteration*/) {} + virtual void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) {} + virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {} + virtual void OnTestCaseStart(const TestCase& /*test_case*/) {} + virtual void OnTestStart(const TestInfo& /*test_info*/) {} + virtual void OnTestPartResult(const TestPartResult& /*test_part_result*/) {} + virtual void OnTestEnd(const TestInfo& /*test_info*/) {} + virtual void OnTestCaseEnd(const TestCase& /*test_case*/) {} + virtual void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) {} + virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {} + virtual void OnTestIterationEnd(const UnitTest& /*unit_test*/, + int /*iteration*/) {} + virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {} +}; + +// TestEventListeners lets users add listeners to track events in Google Test. +class GTEST_API_ TestEventListeners { + public: + TestEventListeners(); + ~TestEventListeners(); + + // Appends an event listener to the end of the list. Google Test assumes + // the ownership of the listener (i.e. it will delete the listener when + // the test program finishes). + void Append(TestEventListener* listener); + + // Removes the given event listener from the list and returns it. It then + // becomes the caller's responsibility to delete the listener. Returns + // NULL if the listener is not found in the list. + TestEventListener* Release(TestEventListener* listener); + + // Returns the standard listener responsible for the default console + // output. Can be removed from the listeners list to shut down default + // console output. Note that removing this object from the listener list + // with Release transfers its ownership to the caller and makes this + // function return NULL the next time. + TestEventListener* default_result_printer() const { + return default_result_printer_; + } + + // Returns the standard listener responsible for the default XML output + // controlled by the --gtest_output=xml flag. Can be removed from the + // listeners list by users who want to shut down the default XML output + // controlled by this flag and substitute it with custom one. Note that + // removing this object from the listener list with Release transfers its + // ownership to the caller and makes this function return NULL the next + // time. + TestEventListener* default_xml_generator() const { + return default_xml_generator_; + } + + private: + friend class TestCase; + friend class TestInfo; + friend class internal::DefaultGlobalTestPartResultReporter; + friend class internal::NoExecDeathTest; + friend class internal::TestEventListenersAccessor; + friend class internal::UnitTestImpl; + + // Returns repeater that broadcasts the TestEventListener events to all + // subscribers. + TestEventListener* repeater(); + + // Sets the default_result_printer attribute to the provided listener. + // The listener is also added to the listener list and previous + // default_result_printer is removed from it and deleted. The listener can + // also be NULL in which case it will not be added to the list. Does + // nothing if the previous and the current listener objects are the same. + void SetDefaultResultPrinter(TestEventListener* listener); + + // Sets the default_xml_generator attribute to the provided listener. The + // listener is also added to the listener list and previous + // default_xml_generator is removed from it and deleted. The listener can + // also be NULL in which case it will not be added to the list. Does + // nothing if the previous and the current listener objects are the same. + void SetDefaultXmlGenerator(TestEventListener* listener); + + // Controls whether events will be forwarded by the repeater to the + // listeners in the list. + bool EventForwardingEnabled() const; + void SuppressEventForwarding(); + + // The actual list of listeners. + internal::TestEventRepeater* repeater_; + // Listener responsible for the standard result output. + TestEventListener* default_result_printer_; + // Listener responsible for the creation of the XML output file. + TestEventListener* default_xml_generator_; + + // We disallow copying TestEventListeners. + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventListeners); +}; + +// A UnitTest consists of a vector of TestCases. +// +// This is a singleton class. The only instance of UnitTest is +// created when UnitTest::GetInstance() is first called. This +// instance is never deleted. +// +// UnitTest is not copyable. +// +// This class is thread-safe as long as the methods are called +// according to their specification. +class GTEST_API_ UnitTest { + public: + // Gets the singleton UnitTest object. The first time this method + // is called, a UnitTest object is constructed and returned. + // Consecutive calls will return the same object. + static UnitTest* GetInstance(); + + // Runs all tests in this UnitTest object and prints the result. + // Returns 0 if successful, or 1 otherwise. + // + // This method can only be called from the main thread. + // + // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. + int Run() GTEST_MUST_USE_RESULT_; + + // Returns the working directory when the first TEST() or TEST_F() + // was executed. The UnitTest object owns the string. + const char* original_working_dir() const; + + // Returns the TestCase object for the test that's currently running, + // or NULL if no test is running. + const TestCase* current_test_case() const + GTEST_LOCK_EXCLUDED_(mutex_); + + // Returns the TestInfo object for the test that's currently running, + // or NULL if no test is running. + const TestInfo* current_test_info() const + GTEST_LOCK_EXCLUDED_(mutex_); + + // Returns the random seed used at the start of the current test run. + int random_seed() const; + +#if GTEST_HAS_PARAM_TEST + // Returns the ParameterizedTestCaseRegistry object used to keep track of + // value-parameterized tests and instantiate and register them. + // + // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. + internal::ParameterizedTestCaseRegistry& parameterized_test_registry() + GTEST_LOCK_EXCLUDED_(mutex_); +#endif // GTEST_HAS_PARAM_TEST + + // Gets the number of successful test cases. + int successful_test_case_count() const; + + // Gets the number of failed test cases. + int failed_test_case_count() const; + + // Gets the number of all test cases. + int total_test_case_count() const; + + // Gets the number of all test cases that contain at least one test + // that should run. + int test_case_to_run_count() const; + + // Gets the number of successful tests. + int successful_test_count() const; + + // Gets the number of failed tests. + int failed_test_count() const; + + // Gets the number of disabled tests that will be reported in the XML report. + int reportable_disabled_test_count() const; + + // Gets the number of disabled tests. + int disabled_test_count() const; + + // Gets the number of tests to be printed in the XML report. + int reportable_test_count() const; + + // Gets the number of all tests. + int total_test_count() const; + + // Gets the number of tests that should run. + int test_to_run_count() const; + + // Gets the time of the test program start, in ms from the start of the + // UNIX epoch. + TimeInMillis start_timestamp() const; + + // Gets the elapsed time, in milliseconds. + TimeInMillis elapsed_time() const; + + // Returns true iff the unit test passed (i.e. all test cases passed). + bool Passed() const; + + // Returns true iff the unit test failed (i.e. some test case failed + // or something outside of all tests failed). + bool Failed() const; + + // Gets the i-th test case among all the test cases. i can range from 0 to + // total_test_case_count() - 1. If i is not in that range, returns NULL. + const TestCase* GetTestCase(int i) const; + + // Returns the TestResult containing information on test failures and + // properties logged outside of individual test cases. + const TestResult& ad_hoc_test_result() const; + + // Returns the list of event listeners that can be used to track events + // inside Google Test. + TestEventListeners& listeners(); + + private: + // Registers and returns a global test environment. When a test + // program is run, all global test environments will be set-up in + // the order they were registered. After all tests in the program + // have finished, all global test environments will be torn-down in + // the *reverse* order they were registered. + // + // The UnitTest object takes ownership of the given environment. + // + // This method can only be called from the main thread. + Environment* AddEnvironment(Environment* env); + + // Adds a TestPartResult to the current TestResult object. All + // Google Test assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) + // eventually call this to report their results. The user code + // should use the assertion macros instead of calling this directly. + void AddTestPartResult(TestPartResult::Type result_type, + const char* file_name, + int line_number, + const std::string& message, + const std::string& os_stack_trace) + GTEST_LOCK_EXCLUDED_(mutex_); + + // Adds a TestProperty to the current TestResult object when invoked from + // inside a test, to current TestCase's ad_hoc_test_result_ when invoked + // from SetUpTestCase or TearDownTestCase, or to the global property set + // when invoked elsewhere. If the result already contains a property with + // the same key, the value will be updated. + void RecordProperty(const std::string& key, const std::string& value); + + // Gets the i-th test case among all the test cases. i can range from 0 to + // total_test_case_count() - 1. If i is not in that range, returns NULL. + TestCase* GetMutableTestCase(int i); + + // Accessors for the implementation object. + internal::UnitTestImpl* impl() { return impl_; } + const internal::UnitTestImpl* impl() const { return impl_; } + + // These classes and funcions are friends as they need to access private + // members of UnitTest. + friend class Test; + friend class internal::AssertHelper; + friend class internal::ScopedTrace; + friend class internal::StreamingListenerTest; + friend class internal::UnitTestRecordPropertyTestHelper; + friend Environment* AddGlobalTestEnvironment(Environment* env); + friend internal::UnitTestImpl* internal::GetUnitTestImpl(); + friend void internal::ReportFailureInUnknownLocation( + TestPartResult::Type result_type, + const std::string& message); + + // Creates an empty UnitTest. + UnitTest(); + + // D'tor + virtual ~UnitTest(); + + // Pushes a trace defined by SCOPED_TRACE() on to the per-thread + // Google Test trace stack. + void PushGTestTrace(const internal::TraceInfo& trace) + GTEST_LOCK_EXCLUDED_(mutex_); + + // Pops a trace from the per-thread Google Test trace stack. + void PopGTestTrace() + GTEST_LOCK_EXCLUDED_(mutex_); + + // Protects mutable state in *impl_. This is mutable as some const + // methods need to lock it too. + mutable internal::Mutex mutex_; + + // Opaque implementation object. This field is never changed once + // the object is constructed. We don't mark it as const here, as + // doing so will cause a warning in the constructor of UnitTest. + // Mutable state in *impl_ is protected by mutex_. + internal::UnitTestImpl* impl_; + + // We disallow copying UnitTest. + GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTest); +}; + +// A convenient wrapper for adding an environment for the test +// program. +// +// You should call this before RUN_ALL_TESTS() is called, probably in +// main(). If you use gtest_main, you need to call this before main() +// starts for it to take effect. For example, you can define a global +// variable like this: +// +// testing::Environment* const foo_env = +// testing::AddGlobalTestEnvironment(new FooEnvironment); +// +// However, we strongly recommend you to write your own main() and +// call AddGlobalTestEnvironment() there, as relying on initialization +// of global variables makes the code harder to read and may cause +// problems when you register multiple environments from different +// translation units and the environments have dependencies among them +// (remember that the compiler doesn't guarantee the order in which +// global variables from different translation units are initialized). +inline Environment* AddGlobalTestEnvironment(Environment* env) { + return UnitTest::GetInstance()->AddEnvironment(env); +} + +// Initializes Google Test. This must be called before calling +// RUN_ALL_TESTS(). In particular, it parses a command line for the +// flags that Google Test recognizes. Whenever a Google Test flag is +// seen, it is removed from argv, and *argc is decremented. +// +// No value is returned. Instead, the Google Test flag variables are +// updated. +// +// Calling the function for the second time has no user-visible effect. +GTEST_API_ void InitGoogleTest(int* argc, char** argv); + +// This overloaded version can be used in Windows programs compiled in +// UNICODE mode. +GTEST_API_ void InitGoogleTest(int* argc, wchar_t** argv); + +namespace internal { + +// FormatForComparison::Format(value) formats a +// value of type ToPrint that is an operand of a comparison assertion +// (e.g. ASSERT_EQ). OtherOperand is the type of the other operand in +// the comparison, and is used to help determine the best way to +// format the value. In particular, when the value is a C string +// (char pointer) and the other operand is an STL string object, we +// want to format the C string as a string, since we know it is +// compared by value with the string object. If the value is a char +// pointer but the other operand is not an STL string object, we don't +// know whether the pointer is supposed to point to a NUL-terminated +// string, and thus want to print it as a pointer to be safe. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. + +// The default case. +template +class FormatForComparison { + public: + static ::std::string Format(const ToPrint& value) { + return ::testing::PrintToString(value); + } +}; + +// Array. +template +class FormatForComparison { + public: + static ::std::string Format(const ToPrint* value) { + return FormatForComparison::Format(value); + } +}; + +// By default, print C string as pointers to be safe, as we don't know +// whether they actually point to a NUL-terminated string. + +#define GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(CharType) \ + template \ + class FormatForComparison { \ + public: \ + static ::std::string Format(CharType* value) { \ + return ::testing::PrintToString(static_cast(value)); \ + } \ + } + +GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char); +GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char); +GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(wchar_t); +GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const wchar_t); + +#undef GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_ + +// If a C string is compared with an STL string object, we know it's meant +// to point to a NUL-terminated string, and thus can print it as a string. + +#define GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(CharType, OtherStringType) \ + template <> \ + class FormatForComparison { \ + public: \ + static ::std::string Format(CharType* value) { \ + return ::testing::PrintToString(value); \ + } \ + } + +GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char, ::std::string); +GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char, ::std::string); + +#if GTEST_HAS_GLOBAL_STRING +GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char, ::string); +GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char, ::string); +#endif + +#if GTEST_HAS_GLOBAL_WSTRING +GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(wchar_t, ::wstring); +GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const wchar_t, ::wstring); +#endif + +#if GTEST_HAS_STD_WSTRING +GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(wchar_t, ::std::wstring); +GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const wchar_t, ::std::wstring); +#endif + +#undef GTEST_IMPL_FORMAT_C_STRING_AS_STRING_ + +// Formats a comparison assertion (e.g. ASSERT_EQ, EXPECT_LT, and etc) +// operand to be used in a failure message. The type (but not value) +// of the other operand may affect the format. This allows us to +// print a char* as a raw pointer when it is compared against another +// char* or void*, and print it as a C string when it is compared +// against an std::string object, for example. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +template +std::string FormatForComparisonFailureMessage( + const T1& value, const T2& /* other_operand */) { + return FormatForComparison::Format(value); +} + +// The helper function for {ASSERT|EXPECT}_EQ. +template +AssertionResult CmpHelperEQ(const char* expected_expression, + const char* actual_expression, + const T1& expected, + const T2& actual) { +#ifdef _MSC_VER +# pragma warning(push) // Saves the current warning state. +# pragma warning(disable:4389) // Temporarily disables warning on + // signed/unsigned mismatch. +#endif + + if (expected == actual) { + return AssertionSuccess(); + } + +#ifdef _MSC_VER +# pragma warning(pop) // Restores the warning state. +#endif + + return EqFailure(expected_expression, + actual_expression, + FormatForComparisonFailureMessage(expected, actual), + FormatForComparisonFailureMessage(actual, expected), + false); +} + +// With this overloaded version, we allow anonymous enums to be used +// in {ASSERT|EXPECT}_EQ when compiled with gcc 4, as anonymous enums +// can be implicitly cast to BiggestInt. +GTEST_API_ AssertionResult CmpHelperEQ(const char* expected_expression, + const char* actual_expression, + BiggestInt expected, + BiggestInt actual); + +// The helper class for {ASSERT|EXPECT}_EQ. The template argument +// lhs_is_null_literal is true iff the first argument to ASSERT_EQ() +// is a null pointer literal. The following default implementation is +// for lhs_is_null_literal being false. +template +class EqHelper { + public: + // This templatized version is for the general case. + template + static AssertionResult Compare(const char* expected_expression, + const char* actual_expression, + const T1& expected, + const T2& actual) { + return CmpHelperEQ(expected_expression, actual_expression, expected, + actual); + } + + // With this overloaded version, we allow anonymous enums to be used + // in {ASSERT|EXPECT}_EQ when compiled with gcc 4, as anonymous + // enums can be implicitly cast to BiggestInt. + // + // Even though its body looks the same as the above version, we + // cannot merge the two, as it will make anonymous enums unhappy. + static AssertionResult Compare(const char* expected_expression, + const char* actual_expression, + BiggestInt expected, + BiggestInt actual) { + return CmpHelperEQ(expected_expression, actual_expression, expected, + actual); + } +}; + +// This specialization is used when the first argument to ASSERT_EQ() +// is a null pointer literal, like NULL, false, or 0. +template <> +class EqHelper { + public: + // We define two overloaded versions of Compare(). The first + // version will be picked when the second argument to ASSERT_EQ() is + // NOT a pointer, e.g. ASSERT_EQ(0, AnIntFunction()) or + // EXPECT_EQ(false, a_bool). + template + static AssertionResult Compare( + const char* expected_expression, + const char* actual_expression, + const T1& expected, + const T2& actual, + // The following line prevents this overload from being considered if T2 + // is not a pointer type. We need this because ASSERT_EQ(NULL, my_ptr) + // expands to Compare("", "", NULL, my_ptr), which requires a conversion + // to match the Secret* in the other overload, which would otherwise make + // this template match better. + typename EnableIf::value>::type* = 0) { + return CmpHelperEQ(expected_expression, actual_expression, expected, + actual); + } + + // This version will be picked when the second argument to ASSERT_EQ() is a + // pointer, e.g. ASSERT_EQ(NULL, a_pointer). + template + static AssertionResult Compare( + const char* expected_expression, + const char* actual_expression, + // We used to have a second template parameter instead of Secret*. That + // template parameter would deduce to 'long', making this a better match + // than the first overload even without the first overload's EnableIf. + // Unfortunately, gcc with -Wconversion-null warns when "passing NULL to + // non-pointer argument" (even a deduced integral argument), so the old + // implementation caused warnings in user code. + Secret* /* expected (NULL) */, + T* actual) { + // We already know that 'expected' is a null pointer. + return CmpHelperEQ(expected_expression, actual_expression, + static_cast(NULL), actual); + } +}; + +// A macro for implementing the helper functions needed to implement +// ASSERT_?? and EXPECT_??. It is here just to avoid copy-and-paste +// of similar code. +// +// For each templatized helper function, we also define an overloaded +// version for BiggestInt in order to reduce code bloat and allow +// anonymous enums to be used with {ASSERT|EXPECT}_?? when compiled +// with gcc 4. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +#define GTEST_IMPL_CMP_HELPER_(op_name, op)\ +template \ +AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \ + const T1& val1, const T2& val2) {\ + if (val1 op val2) {\ + return AssertionSuccess();\ + } else {\ + return AssertionFailure() \ + << "Expected: (" << expr1 << ") " #op " (" << expr2\ + << "), actual: " << FormatForComparisonFailureMessage(val1, val2)\ + << " vs " << FormatForComparisonFailureMessage(val2, val1);\ + }\ +}\ +GTEST_API_ AssertionResult CmpHelper##op_name(\ + const char* expr1, const char* expr2, BiggestInt val1, BiggestInt val2) + +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. + +// Implements the helper function for {ASSERT|EXPECT}_NE +GTEST_IMPL_CMP_HELPER_(NE, !=); +// Implements the helper function for {ASSERT|EXPECT}_LE +GTEST_IMPL_CMP_HELPER_(LE, <=); +// Implements the helper function for {ASSERT|EXPECT}_LT +GTEST_IMPL_CMP_HELPER_(LT, <); +// Implements the helper function for {ASSERT|EXPECT}_GE +GTEST_IMPL_CMP_HELPER_(GE, >=); +// Implements the helper function for {ASSERT|EXPECT}_GT +GTEST_IMPL_CMP_HELPER_(GT, >); + +#undef GTEST_IMPL_CMP_HELPER_ + +// The helper function for {ASSERT|EXPECT}_STREQ. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult CmpHelperSTREQ(const char* expected_expression, + const char* actual_expression, + const char* expected, + const char* actual); + +// The helper function for {ASSERT|EXPECT}_STRCASEEQ. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult CmpHelperSTRCASEEQ(const char* expected_expression, + const char* actual_expression, + const char* expected, + const char* actual); + +// The helper function for {ASSERT|EXPECT}_STRNE. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression, + const char* s2_expression, + const char* s1, + const char* s2); + +// The helper function for {ASSERT|EXPECT}_STRCASENE. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult CmpHelperSTRCASENE(const char* s1_expression, + const char* s2_expression, + const char* s1, + const char* s2); + + +// Helper function for *_STREQ on wide strings. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult CmpHelperSTREQ(const char* expected_expression, + const char* actual_expression, + const wchar_t* expected, + const wchar_t* actual); + +// Helper function for *_STRNE on wide strings. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression, + const char* s2_expression, + const wchar_t* s1, + const wchar_t* s2); + +} // namespace internal + +// IsSubstring() and IsNotSubstring() are intended to be used as the +// first argument to {EXPECT,ASSERT}_PRED_FORMAT2(), not by +// themselves. They check whether needle is a substring of haystack +// (NULL is considered a substring of itself only), and return an +// appropriate error message when they fail. +// +// The {needle,haystack}_expr arguments are the stringified +// expressions that generated the two real arguments. +GTEST_API_ AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const char* needle, const char* haystack); +GTEST_API_ AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const wchar_t* needle, const wchar_t* haystack); +GTEST_API_ AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const char* needle, const char* haystack); +GTEST_API_ AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const wchar_t* needle, const wchar_t* haystack); +GTEST_API_ AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::string& needle, const ::std::string& haystack); +GTEST_API_ AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::string& needle, const ::std::string& haystack); + +#if GTEST_HAS_STD_WSTRING +GTEST_API_ AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::wstring& needle, const ::std::wstring& haystack); +GTEST_API_ AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::wstring& needle, const ::std::wstring& haystack); +#endif // GTEST_HAS_STD_WSTRING + +namespace internal { + +// Helper template function for comparing floating-points. +// +// Template parameter: +// +// RawType: the raw floating-point type (either float or double) +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +template +AssertionResult CmpHelperFloatingPointEQ(const char* expected_expression, + const char* actual_expression, + RawType expected, + RawType actual) { + const FloatingPoint lhs(expected), rhs(actual); + + if (lhs.AlmostEquals(rhs)) { + return AssertionSuccess(); + } + + ::std::stringstream expected_ss; + expected_ss << std::setprecision(std::numeric_limits::digits10 + 2) + << expected; + + ::std::stringstream actual_ss; + actual_ss << std::setprecision(std::numeric_limits::digits10 + 2) + << actual; + + return EqFailure(expected_expression, + actual_expression, + StringStreamToString(&expected_ss), + StringStreamToString(&actual_ss), + false); +} + +// Helper function for implementing ASSERT_NEAR. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult DoubleNearPredFormat(const char* expr1, + const char* expr2, + const char* abs_error_expr, + double val1, + double val2, + double abs_error); + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// A class that enables one to stream messages to assertion macros +class GTEST_API_ AssertHelper { + public: + // Constructor. + AssertHelper(TestPartResult::Type type, + const char* file, + int line, + const char* message); + ~AssertHelper(); + + // Message assignment is a semantic trick to enable assertion + // streaming; see the GTEST_MESSAGE_ macro below. + void operator=(const Message& message) const; + + private: + // We put our data in a struct so that the size of the AssertHelper class can + // be as small as possible. This is important because gcc is incapable of + // re-using stack space even for temporary variables, so every EXPECT_EQ + // reserves stack space for another AssertHelper. + struct AssertHelperData { + AssertHelperData(TestPartResult::Type t, + const char* srcfile, + int line_num, + const char* msg) + : type(t), file(srcfile), line(line_num), message(msg) { } + + TestPartResult::Type const type; + const char* const file; + int const line; + std::string const message; + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelperData); + }; + + AssertHelperData* const data_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelper); +}; + +} // namespace internal + +#if GTEST_HAS_PARAM_TEST +// The pure interface class that all value-parameterized tests inherit from. +// A value-parameterized class must inherit from both ::testing::Test and +// ::testing::WithParamInterface. In most cases that just means inheriting +// from ::testing::TestWithParam, but more complicated test hierarchies +// may need to inherit from Test and WithParamInterface at different levels. +// +// This interface has support for accessing the test parameter value via +// the GetParam() method. +// +// Use it with one of the parameter generator defining functions, like Range(), +// Values(), ValuesIn(), Bool(), and Combine(). +// +// class FooTest : public ::testing::TestWithParam { +// protected: +// FooTest() { +// // Can use GetParam() here. +// } +// virtual ~FooTest() { +// // Can use GetParam() here. +// } +// virtual void SetUp() { +// // Can use GetParam() here. +// } +// virtual void TearDown { +// // Can use GetParam() here. +// } +// }; +// TEST_P(FooTest, DoesBar) { +// // Can use GetParam() method here. +// Foo foo; +// ASSERT_TRUE(foo.DoesBar(GetParam())); +// } +// INSTANTIATE_TEST_CASE_P(OneToTenRange, FooTest, ::testing::Range(1, 10)); + +template +class WithParamInterface { + public: + typedef T ParamType; + virtual ~WithParamInterface() {} + + // The current parameter value. Is also available in the test fixture's + // constructor. This member function is non-static, even though it only + // references static data, to reduce the opportunity for incorrect uses + // like writing 'WithParamInterface::GetParam()' for a test that + // uses a fixture whose parameter type is int. + const ParamType& GetParam() const { + GTEST_CHECK_(parameter_ != NULL) + << "GetParam() can only be called inside a value-parameterized test " + << "-- did you intend to write TEST_P instead of TEST_F?"; + return *parameter_; + } + + private: + // Sets parameter value. The caller is responsible for making sure the value + // remains alive and unchanged throughout the current test. + static void SetParam(const ParamType* parameter) { + parameter_ = parameter; + } + + // Static value used for accessing parameter during a test lifetime. + static const ParamType* parameter_; + + // TestClass must be a subclass of WithParamInterface and Test. + template friend class internal::ParameterizedTestFactory; +}; + +template +const T* WithParamInterface::parameter_ = NULL; + +// Most value-parameterized classes can ignore the existence of +// WithParamInterface, and can just inherit from ::testing::TestWithParam. + +template +class TestWithParam : public Test, public WithParamInterface { +}; + +#endif // GTEST_HAS_PARAM_TEST + +// Macros for indicating success/failure in test code. + +// ADD_FAILURE unconditionally adds a failure to the current test. +// SUCCEED generates a success - it doesn't automatically make the +// current test successful, as a test is only successful when it has +// no failure. +// +// EXPECT_* verifies that a certain condition is satisfied. If not, +// it behaves like ADD_FAILURE. In particular: +// +// EXPECT_TRUE verifies that a Boolean condition is true. +// EXPECT_FALSE verifies that a Boolean condition is false. +// +// FAIL and ASSERT_* are similar to ADD_FAILURE and EXPECT_*, except +// that they will also abort the current function on failure. People +// usually want the fail-fast behavior of FAIL and ASSERT_*, but those +// writing data-driven tests often find themselves using ADD_FAILURE +// and EXPECT_* more. + +// Generates a nonfatal failure with a generic message. +#define ADD_FAILURE() GTEST_NONFATAL_FAILURE_("Failed") + +// Generates a nonfatal failure at the given source file location with +// a generic message. +#define ADD_FAILURE_AT(file, line) \ + GTEST_MESSAGE_AT_(file, line, "Failed", \ + ::testing::TestPartResult::kNonFatalFailure) + +// Generates a fatal failure with a generic message. +#define GTEST_FAIL() GTEST_FATAL_FAILURE_("Failed") + +// Define this macro to 1 to omit the definition of FAIL(), which is a +// generic name and clashes with some other libraries. +#if !GTEST_DONT_DEFINE_FAIL +# define FAIL() GTEST_FAIL() +#endif + +// Generates a success with a generic message. +#define GTEST_SUCCEED() GTEST_SUCCESS_("Succeeded") + +// Define this macro to 1 to omit the definition of SUCCEED(), which +// is a generic name and clashes with some other libraries. +#if !GTEST_DONT_DEFINE_SUCCEED +# define SUCCEED() GTEST_SUCCEED() +#endif + +// Macros for testing exceptions. +// +// * {ASSERT|EXPECT}_THROW(statement, expected_exception): +// Tests that the statement throws the expected exception. +// * {ASSERT|EXPECT}_NO_THROW(statement): +// Tests that the statement doesn't throw any exception. +// * {ASSERT|EXPECT}_ANY_THROW(statement): +// Tests that the statement throws an exception. + +#define EXPECT_THROW(statement, expected_exception) \ + GTEST_TEST_THROW_(statement, expected_exception, GTEST_NONFATAL_FAILURE_) +#define EXPECT_NO_THROW(statement) \ + GTEST_TEST_NO_THROW_(statement, GTEST_NONFATAL_FAILURE_) +#define EXPECT_ANY_THROW(statement) \ + GTEST_TEST_ANY_THROW_(statement, GTEST_NONFATAL_FAILURE_) +#define ASSERT_THROW(statement, expected_exception) \ + GTEST_TEST_THROW_(statement, expected_exception, GTEST_FATAL_FAILURE_) +#define ASSERT_NO_THROW(statement) \ + GTEST_TEST_NO_THROW_(statement, GTEST_FATAL_FAILURE_) +#define ASSERT_ANY_THROW(statement) \ + GTEST_TEST_ANY_THROW_(statement, GTEST_FATAL_FAILURE_) + +// Boolean assertions. Condition can be either a Boolean expression or an +// AssertionResult. For more information on how to use AssertionResult with +// these macros see comments on that class. +#define EXPECT_TRUE(condition) \ + GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \ + GTEST_NONFATAL_FAILURE_) +#define EXPECT_FALSE(condition) \ + GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \ + GTEST_NONFATAL_FAILURE_) +#define ASSERT_TRUE(condition) \ + GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \ + GTEST_FATAL_FAILURE_) +#define ASSERT_FALSE(condition) \ + GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \ + GTEST_FATAL_FAILURE_) + +// Includes the auto-generated header that implements a family of +// generic predicate assertion macros. +// Copyright 2006, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// This file is AUTOMATICALLY GENERATED on 10/31/2011 by command +// 'gen_gtest_pred_impl.py 5'. DO NOT EDIT BY HAND! +// +// Implements a family of generic predicate assertion macros. + +#ifndef GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ +#define GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ + +// Makes sure this header is not included before gtest.h. +#ifndef GTEST_INCLUDE_GTEST_GTEST_H_ +# error Do not include gtest_pred_impl.h directly. Include gtest.h instead. +#endif // GTEST_INCLUDE_GTEST_GTEST_H_ + +// This header implements a family of generic predicate assertion +// macros: +// +// ASSERT_PRED_FORMAT1(pred_format, v1) +// ASSERT_PRED_FORMAT2(pred_format, v1, v2) +// ... +// +// where pred_format is a function or functor that takes n (in the +// case of ASSERT_PRED_FORMATn) values and their source expression +// text, and returns a testing::AssertionResult. See the definition +// of ASSERT_EQ in gtest.h for an example. +// +// If you don't care about formatting, you can use the more +// restrictive version: +// +// ASSERT_PRED1(pred, v1) +// ASSERT_PRED2(pred, v1, v2) +// ... +// +// where pred is an n-ary function or functor that returns bool, +// and the values v1, v2, ..., must support the << operator for +// streaming to std::ostream. +// +// We also define the EXPECT_* variations. +// +// For now we only support predicates whose arity is at most 5. +// Please email googletestframework@googlegroups.com if you need +// support for higher arities. + +// GTEST_ASSERT_ is the basic statement to which all of the assertions +// in this file reduce. Don't use this in your code. + +#define GTEST_ASSERT_(expression, on_failure) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (const ::testing::AssertionResult gtest_ar = (expression)) \ + ; \ + else \ + on_failure(gtest_ar.failure_message()) + + +// Helper function for implementing {EXPECT|ASSERT}_PRED1. Don't use +// this in your code. +template +AssertionResult AssertPred1Helper(const char* pred_text, + const char* e1, + Pred pred, + const T1& v1) { + if (pred(v1)) return AssertionSuccess(); + + return AssertionFailure() << pred_text << "(" + << e1 << ") evaluates to false, where" + << "\n" << e1 << " evaluates to " << v1; +} + +// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT1. +// Don't use this in your code. +#define GTEST_PRED_FORMAT1_(pred_format, v1, on_failure)\ + GTEST_ASSERT_(pred_format(#v1, v1), \ + on_failure) + +// Internal macro for implementing {EXPECT|ASSERT}_PRED1. Don't use +// this in your code. +#define GTEST_PRED1_(pred, v1, on_failure)\ + GTEST_ASSERT_(::testing::AssertPred1Helper(#pred, \ + #v1, \ + pred, \ + v1), on_failure) + +// Unary predicate assertion macros. +#define EXPECT_PRED_FORMAT1(pred_format, v1) \ + GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_NONFATAL_FAILURE_) +#define EXPECT_PRED1(pred, v1) \ + GTEST_PRED1_(pred, v1, GTEST_NONFATAL_FAILURE_) +#define ASSERT_PRED_FORMAT1(pred_format, v1) \ + GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_FATAL_FAILURE_) +#define ASSERT_PRED1(pred, v1) \ + GTEST_PRED1_(pred, v1, GTEST_FATAL_FAILURE_) + + + +// Helper function for implementing {EXPECT|ASSERT}_PRED2. Don't use +// this in your code. +template +AssertionResult AssertPred2Helper(const char* pred_text, + const char* e1, + const char* e2, + Pred pred, + const T1& v1, + const T2& v2) { + if (pred(v1, v2)) return AssertionSuccess(); + + return AssertionFailure() << pred_text << "(" + << e1 << ", " + << e2 << ") evaluates to false, where" + << "\n" << e1 << " evaluates to " << v1 + << "\n" << e2 << " evaluates to " << v2; +} + +// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT2. +// Don't use this in your code. +#define GTEST_PRED_FORMAT2_(pred_format, v1, v2, on_failure)\ + GTEST_ASSERT_(pred_format(#v1, #v2, v1, v2), \ + on_failure) + +// Internal macro for implementing {EXPECT|ASSERT}_PRED2. Don't use +// this in your code. +#define GTEST_PRED2_(pred, v1, v2, on_failure)\ + GTEST_ASSERT_(::testing::AssertPred2Helper(#pred, \ + #v1, \ + #v2, \ + pred, \ + v1, \ + v2), on_failure) + +// Binary predicate assertion macros. +#define EXPECT_PRED_FORMAT2(pred_format, v1, v2) \ + GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_NONFATAL_FAILURE_) +#define EXPECT_PRED2(pred, v1, v2) \ + GTEST_PRED2_(pred, v1, v2, GTEST_NONFATAL_FAILURE_) +#define ASSERT_PRED_FORMAT2(pred_format, v1, v2) \ + GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_FATAL_FAILURE_) +#define ASSERT_PRED2(pred, v1, v2) \ + GTEST_PRED2_(pred, v1, v2, GTEST_FATAL_FAILURE_) + + + +// Helper function for implementing {EXPECT|ASSERT}_PRED3. Don't use +// this in your code. +template +AssertionResult AssertPred3Helper(const char* pred_text, + const char* e1, + const char* e2, + const char* e3, + Pred pred, + const T1& v1, + const T2& v2, + const T3& v3) { + if (pred(v1, v2, v3)) return AssertionSuccess(); + + return AssertionFailure() << pred_text << "(" + << e1 << ", " + << e2 << ", " + << e3 << ") evaluates to false, where" + << "\n" << e1 << " evaluates to " << v1 + << "\n" << e2 << " evaluates to " << v2 + << "\n" << e3 << " evaluates to " << v3; +} + +// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT3. +// Don't use this in your code. +#define GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, on_failure)\ + GTEST_ASSERT_(pred_format(#v1, #v2, #v3, v1, v2, v3), \ + on_failure) + +// Internal macro for implementing {EXPECT|ASSERT}_PRED3. Don't use +// this in your code. +#define GTEST_PRED3_(pred, v1, v2, v3, on_failure)\ + GTEST_ASSERT_(::testing::AssertPred3Helper(#pred, \ + #v1, \ + #v2, \ + #v3, \ + pred, \ + v1, \ + v2, \ + v3), on_failure) + +// Ternary predicate assertion macros. +#define EXPECT_PRED_FORMAT3(pred_format, v1, v2, v3) \ + GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_NONFATAL_FAILURE_) +#define EXPECT_PRED3(pred, v1, v2, v3) \ + GTEST_PRED3_(pred, v1, v2, v3, GTEST_NONFATAL_FAILURE_) +#define ASSERT_PRED_FORMAT3(pred_format, v1, v2, v3) \ + GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_FATAL_FAILURE_) +#define ASSERT_PRED3(pred, v1, v2, v3) \ + GTEST_PRED3_(pred, v1, v2, v3, GTEST_FATAL_FAILURE_) + + + +// Helper function for implementing {EXPECT|ASSERT}_PRED4. Don't use +// this in your code. +template +AssertionResult AssertPred4Helper(const char* pred_text, + const char* e1, + const char* e2, + const char* e3, + const char* e4, + Pred pred, + const T1& v1, + const T2& v2, + const T3& v3, + const T4& v4) { + if (pred(v1, v2, v3, v4)) return AssertionSuccess(); + + return AssertionFailure() << pred_text << "(" + << e1 << ", " + << e2 << ", " + << e3 << ", " + << e4 << ") evaluates to false, where" + << "\n" << e1 << " evaluates to " << v1 + << "\n" << e2 << " evaluates to " << v2 + << "\n" << e3 << " evaluates to " << v3 + << "\n" << e4 << " evaluates to " << v4; +} + +// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT4. +// Don't use this in your code. +#define GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, on_failure)\ + GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, v1, v2, v3, v4), \ + on_failure) + +// Internal macro for implementing {EXPECT|ASSERT}_PRED4. Don't use +// this in your code. +#define GTEST_PRED4_(pred, v1, v2, v3, v4, on_failure)\ + GTEST_ASSERT_(::testing::AssertPred4Helper(#pred, \ + #v1, \ + #v2, \ + #v3, \ + #v4, \ + pred, \ + v1, \ + v2, \ + v3, \ + v4), on_failure) + +// 4-ary predicate assertion macros. +#define EXPECT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \ + GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_) +#define EXPECT_PRED4(pred, v1, v2, v3, v4) \ + GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_) +#define ASSERT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \ + GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_FATAL_FAILURE_) +#define ASSERT_PRED4(pred, v1, v2, v3, v4) \ + GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_FATAL_FAILURE_) + + + +// Helper function for implementing {EXPECT|ASSERT}_PRED5. Don't use +// this in your code. +template +AssertionResult AssertPred5Helper(const char* pred_text, + const char* e1, + const char* e2, + const char* e3, + const char* e4, + const char* e5, + Pred pred, + const T1& v1, + const T2& v2, + const T3& v3, + const T4& v4, + const T5& v5) { + if (pred(v1, v2, v3, v4, v5)) return AssertionSuccess(); + + return AssertionFailure() << pred_text << "(" + << e1 << ", " + << e2 << ", " + << e3 << ", " + << e4 << ", " + << e5 << ") evaluates to false, where" + << "\n" << e1 << " evaluates to " << v1 + << "\n" << e2 << " evaluates to " << v2 + << "\n" << e3 << " evaluates to " << v3 + << "\n" << e4 << " evaluates to " << v4 + << "\n" << e5 << " evaluates to " << v5; +} + +// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT5. +// Don't use this in your code. +#define GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, on_failure)\ + GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, #v5, v1, v2, v3, v4, v5), \ + on_failure) + +// Internal macro for implementing {EXPECT|ASSERT}_PRED5. Don't use +// this in your code. +#define GTEST_PRED5_(pred, v1, v2, v3, v4, v5, on_failure)\ + GTEST_ASSERT_(::testing::AssertPred5Helper(#pred, \ + #v1, \ + #v2, \ + #v3, \ + #v4, \ + #v5, \ + pred, \ + v1, \ + v2, \ + v3, \ + v4, \ + v5), on_failure) + +// 5-ary predicate assertion macros. +#define EXPECT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \ + GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_) +#define EXPECT_PRED5(pred, v1, v2, v3, v4, v5) \ + GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_) +#define ASSERT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \ + GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_) +#define ASSERT_PRED5(pred, v1, v2, v3, v4, v5) \ + GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_) + + + +#endif // GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ + +// Macros for testing equalities and inequalities. +// +// * {ASSERT|EXPECT}_EQ(expected, actual): Tests that expected == actual +// * {ASSERT|EXPECT}_NE(v1, v2): Tests that v1 != v2 +// * {ASSERT|EXPECT}_LT(v1, v2): Tests that v1 < v2 +// * {ASSERT|EXPECT}_LE(v1, v2): Tests that v1 <= v2 +// * {ASSERT|EXPECT}_GT(v1, v2): Tests that v1 > v2 +// * {ASSERT|EXPECT}_GE(v1, v2): Tests that v1 >= v2 +// +// When they are not, Google Test prints both the tested expressions and +// their actual values. The values must be compatible built-in types, +// or you will get a compiler error. By "compatible" we mean that the +// values can be compared by the respective operator. +// +// Note: +// +// 1. It is possible to make a user-defined type work with +// {ASSERT|EXPECT}_??(), but that requires overloading the +// comparison operators and is thus discouraged by the Google C++ +// Usage Guide. Therefore, you are advised to use the +// {ASSERT|EXPECT}_TRUE() macro to assert that two objects are +// equal. +// +// 2. The {ASSERT|EXPECT}_??() macros do pointer comparisons on +// pointers (in particular, C strings). Therefore, if you use it +// with two C strings, you are testing how their locations in memory +// are related, not how their content is related. To compare two C +// strings by content, use {ASSERT|EXPECT}_STR*(). +// +// 3. {ASSERT|EXPECT}_EQ(expected, actual) is preferred to +// {ASSERT|EXPECT}_TRUE(expected == actual), as the former tells you +// what the actual value is when it fails, and similarly for the +// other comparisons. +// +// 4. Do not depend on the order in which {ASSERT|EXPECT}_??() +// evaluate their arguments, which is undefined. +// +// 5. These macros evaluate their arguments exactly once. +// +// Examples: +// +// EXPECT_NE(5, Foo()); +// EXPECT_EQ(NULL, a_pointer); +// ASSERT_LT(i, array_size); +// ASSERT_GT(records.size(), 0) << "There is no record left."; + +#define EXPECT_EQ(expected, actual) \ + EXPECT_PRED_FORMAT2(::testing::internal:: \ + EqHelper::Compare, \ + expected, actual) +#define EXPECT_NE(expected, actual) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperNE, expected, actual) +#define EXPECT_LE(val1, val2) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLE, val1, val2) +#define EXPECT_LT(val1, val2) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2) +#define EXPECT_GE(val1, val2) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGE, val1, val2) +#define EXPECT_GT(val1, val2) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2) + +#define GTEST_ASSERT_EQ(expected, actual) \ + ASSERT_PRED_FORMAT2(::testing::internal:: \ + EqHelper::Compare, \ + expected, actual) +#define GTEST_ASSERT_NE(val1, val2) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperNE, val1, val2) +#define GTEST_ASSERT_LE(val1, val2) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperLE, val1, val2) +#define GTEST_ASSERT_LT(val1, val2) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2) +#define GTEST_ASSERT_GE(val1, val2) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperGE, val1, val2) +#define GTEST_ASSERT_GT(val1, val2) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2) + +// Define macro GTEST_DONT_DEFINE_ASSERT_XY to 1 to omit the definition of +// ASSERT_XY(), which clashes with some users' own code. + +#if !GTEST_DONT_DEFINE_ASSERT_EQ +# define ASSERT_EQ(val1, val2) GTEST_ASSERT_EQ(val1, val2) +#endif + +#if !GTEST_DONT_DEFINE_ASSERT_NE +# define ASSERT_NE(val1, val2) GTEST_ASSERT_NE(val1, val2) +#endif + +#if !GTEST_DONT_DEFINE_ASSERT_LE +# define ASSERT_LE(val1, val2) GTEST_ASSERT_LE(val1, val2) +#endif + +#if !GTEST_DONT_DEFINE_ASSERT_LT +# define ASSERT_LT(val1, val2) GTEST_ASSERT_LT(val1, val2) +#endif + +#if !GTEST_DONT_DEFINE_ASSERT_GE +# define ASSERT_GE(val1, val2) GTEST_ASSERT_GE(val1, val2) +#endif + +#if !GTEST_DONT_DEFINE_ASSERT_GT +# define ASSERT_GT(val1, val2) GTEST_ASSERT_GT(val1, val2) +#endif + +// C-string Comparisons. All tests treat NULL and any non-NULL string +// as different. Two NULLs are equal. +// +// * {ASSERT|EXPECT}_STREQ(s1, s2): Tests that s1 == s2 +// * {ASSERT|EXPECT}_STRNE(s1, s2): Tests that s1 != s2 +// * {ASSERT|EXPECT}_STRCASEEQ(s1, s2): Tests that s1 == s2, ignoring case +// * {ASSERT|EXPECT}_STRCASENE(s1, s2): Tests that s1 != s2, ignoring case +// +// For wide or narrow string objects, you can use the +// {ASSERT|EXPECT}_??() macros. +// +// Don't depend on the order in which the arguments are evaluated, +// which is undefined. +// +// These macros evaluate their arguments exactly once. + +#define EXPECT_STREQ(expected, actual) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTREQ, expected, actual) +#define EXPECT_STRNE(s1, s2) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2) +#define EXPECT_STRCASEEQ(expected, actual) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, expected, actual) +#define EXPECT_STRCASENE(s1, s2)\ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2) + +#define ASSERT_STREQ(expected, actual) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTREQ, expected, actual) +#define ASSERT_STRNE(s1, s2) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2) +#define ASSERT_STRCASEEQ(expected, actual) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, expected, actual) +#define ASSERT_STRCASENE(s1, s2)\ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2) + +// Macros for comparing floating-point numbers. +// +// * {ASSERT|EXPECT}_FLOAT_EQ(expected, actual): +// Tests that two float values are almost equal. +// * {ASSERT|EXPECT}_DOUBLE_EQ(expected, actual): +// Tests that two double values are almost equal. +// * {ASSERT|EXPECT}_NEAR(v1, v2, abs_error): +// Tests that v1 and v2 are within the given distance to each other. +// +// Google Test uses ULP-based comparison to automatically pick a default +// error bound that is appropriate for the operands. See the +// FloatingPoint template class in gtest-internal.h if you are +// interested in the implementation details. + +#define EXPECT_FLOAT_EQ(expected, actual)\ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ + expected, actual) + +#define EXPECT_DOUBLE_EQ(expected, actual)\ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ + expected, actual) + +#define ASSERT_FLOAT_EQ(expected, actual)\ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ + expected, actual) + +#define ASSERT_DOUBLE_EQ(expected, actual)\ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ + expected, actual) + +#define EXPECT_NEAR(val1, val2, abs_error)\ + EXPECT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, \ + val1, val2, abs_error) + +#define ASSERT_NEAR(val1, val2, abs_error)\ + ASSERT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, \ + val1, val2, abs_error) + +// These predicate format functions work on floating-point values, and +// can be used in {ASSERT|EXPECT}_PRED_FORMAT2*(), e.g. +// +// EXPECT_PRED_FORMAT2(testing::DoubleLE, Foo(), 5.0); + +// Asserts that val1 is less than, or almost equal to, val2. Fails +// otherwise. In particular, it fails if either val1 or val2 is NaN. +GTEST_API_ AssertionResult FloatLE(const char* expr1, const char* expr2, + float val1, float val2); +GTEST_API_ AssertionResult DoubleLE(const char* expr1, const char* expr2, + double val1, double val2); + + +#if GTEST_OS_WINDOWS + +// Macros that test for HRESULT failure and success, these are only useful +// on Windows, and rely on Windows SDK macros and APIs to compile. +// +// * {ASSERT|EXPECT}_HRESULT_{SUCCEEDED|FAILED}(expr) +// +// When expr unexpectedly fails or succeeds, Google Test prints the +// expected result and the actual result with both a human-readable +// string representation of the error, if available, as well as the +// hex result code. +# define EXPECT_HRESULT_SUCCEEDED(expr) \ + EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr)) + +# define ASSERT_HRESULT_SUCCEEDED(expr) \ + ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr)) + +# define EXPECT_HRESULT_FAILED(expr) \ + EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr)) + +# define ASSERT_HRESULT_FAILED(expr) \ + ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr)) + +#endif // GTEST_OS_WINDOWS + +// Macros that execute statement and check that it doesn't generate new fatal +// failures in the current thread. +// +// * {ASSERT|EXPECT}_NO_FATAL_FAILURE(statement); +// +// Examples: +// +// EXPECT_NO_FATAL_FAILURE(Process()); +// ASSERT_NO_FATAL_FAILURE(Process()) << "Process() failed"; +// +#define ASSERT_NO_FATAL_FAILURE(statement) \ + GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_FATAL_FAILURE_) +#define EXPECT_NO_FATAL_FAILURE(statement) \ + GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_NONFATAL_FAILURE_) + +// Causes a trace (including the source file path, the current line +// number, and the given message) to be included in every test failure +// message generated by code in the current scope. The effect is +// undone when the control leaves the current scope. +// +// The message argument can be anything streamable to std::ostream. +// +// In the implementation, we include the current line number as part +// of the dummy variable name, thus allowing multiple SCOPED_TRACE()s +// to appear in the same block - as long as they are on different +// lines. +#define SCOPED_TRACE(message) \ + ::testing::internal::ScopedTrace GTEST_CONCAT_TOKEN_(gtest_trace_, __LINE__)(\ + __FILE__, __LINE__, ::testing::Message() << (message)) + +// Compile-time assertion for type equality. +// StaticAssertTypeEq() compiles iff type1 and type2 are +// the same type. The value it returns is not interesting. +// +// Instead of making StaticAssertTypeEq a class template, we make it a +// function template that invokes a helper class template. This +// prevents a user from misusing StaticAssertTypeEq by +// defining objects of that type. +// +// CAVEAT: +// +// When used inside a method of a class template, +// StaticAssertTypeEq() is effective ONLY IF the method is +// instantiated. For example, given: +// +// template class Foo { +// public: +// void Bar() { testing::StaticAssertTypeEq(); } +// }; +// +// the code: +// +// void Test1() { Foo foo; } +// +// will NOT generate a compiler error, as Foo::Bar() is never +// actually instantiated. Instead, you need: +// +// void Test2() { Foo foo; foo.Bar(); } +// +// to cause a compiler error. +template +bool StaticAssertTypeEq() { + (void)internal::StaticAssertTypeEqHelper(); + return true; +} + +// Defines a test. +// +// The first parameter is the name of the test case, and the second +// parameter is the name of the test within the test case. +// +// The convention is to end the test case name with "Test". For +// example, a test case for the Foo class can be named FooTest. +// +// The user should put his test code between braces after using this +// macro. Example: +// +// TEST(FooTest, InitializesCorrectly) { +// Foo foo; +// EXPECT_TRUE(foo.StatusIsOK()); +// } + +// Note that we call GetTestTypeId() instead of GetTypeId< +// ::testing::Test>() here to get the type ID of testing::Test. This +// is to work around a suspected linker bug when using Google Test as +// a framework on Mac OS X. The bug causes GetTypeId< +// ::testing::Test>() to return different values depending on whether +// the call is from the Google Test framework itself or from user test +// code. GetTestTypeId() is guaranteed to always return the same +// value, as it always calls GetTypeId<>() from the Google Test +// framework. +#define GTEST_TEST(test_case_name, test_name)\ + GTEST_TEST_(test_case_name, test_name, \ + ::testing::Test, ::testing::internal::GetTestTypeId()) + +// Define this macro to 1 to omit the definition of TEST(), which +// is a generic name and clashes with some other libraries. +#if !GTEST_DONT_DEFINE_TEST +# define TEST(test_case_name, test_name) GTEST_TEST(test_case_name, test_name) +#endif + +// Defines a test that uses a test fixture. +// +// The first parameter is the name of the test fixture class, which +// also doubles as the test case name. The second parameter is the +// name of the test within the test case. +// +// A test fixture class must be declared earlier. The user should put +// his test code between braces after using this macro. Example: +// +// class FooTest : public testing::Test { +// protected: +// virtual void SetUp() { b_.AddElement(3); } +// +// Foo a_; +// Foo b_; +// }; +// +// TEST_F(FooTest, InitializesCorrectly) { +// EXPECT_TRUE(a_.StatusIsOK()); +// } +// +// TEST_F(FooTest, ReturnsElementCountCorrectly) { +// EXPECT_EQ(0, a_.size()); +// EXPECT_EQ(1, b_.size()); +// } + +#define TEST_F(test_fixture, test_name)\ + GTEST_TEST_(test_fixture, test_name, test_fixture, \ + ::testing::internal::GetTypeId()) + +} // namespace testing + +// Use this function in main() to run all tests. It returns 0 if all +// tests are successful, or 1 otherwise. +// +// RUN_ALL_TESTS() should be invoked after the command line has been +// parsed by InitGoogleTest(). +// +// This function was formerly a macro; thus, it is in the global +// namespace and has an all-caps name. +int RUN_ALL_TESTS() GTEST_MUST_USE_RESULT_; + +inline int RUN_ALL_TESTS() { + return ::testing::UnitTest::GetInstance()->Run(); +} + +#endif // GTEST_INCLUDE_GTEST_GTEST_H_ From 8431ca5fecbc26d7f23143c26599bc809e917565 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Mon, 31 Jul 2017 10:54:07 -0600 Subject: [PATCH 349/439] Remove tpls directory --- lib/kokkos/tpls/gtest/gtest/LICENSE | 28 - lib/kokkos/tpls/gtest/gtest/README | 13 - lib/kokkos/tpls/gtest/gtest/gtest-all.cc | 9594 -------- lib/kokkos/tpls/gtest/gtest/gtest-test-part.h | 1 - lib/kokkos/tpls/gtest/gtest/gtest.h | 20065 ---------------- 5 files changed, 29701 deletions(-) delete mode 100644 lib/kokkos/tpls/gtest/gtest/LICENSE delete mode 100644 lib/kokkos/tpls/gtest/gtest/README delete mode 100644 lib/kokkos/tpls/gtest/gtest/gtest-all.cc delete mode 120000 lib/kokkos/tpls/gtest/gtest/gtest-test-part.h delete mode 100644 lib/kokkos/tpls/gtest/gtest/gtest.h diff --git a/lib/kokkos/tpls/gtest/gtest/LICENSE b/lib/kokkos/tpls/gtest/gtest/LICENSE deleted file mode 100644 index 1941a11f8c..0000000000 --- a/lib/kokkos/tpls/gtest/gtest/LICENSE +++ /dev/null @@ -1,28 +0,0 @@ -Copyright 2008, Google Inc. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/lib/kokkos/tpls/gtest/gtest/README b/lib/kokkos/tpls/gtest/gtest/README deleted file mode 100644 index 82964ecc32..0000000000 --- a/lib/kokkos/tpls/gtest/gtest/README +++ /dev/null @@ -1,13 +0,0 @@ -This is a fused source version of gtest 1.7.0. All that should be necessary to -start using gtest in your package is to declare the dependency and include -gtest/gtest.h. - -However, because some of the packages that are developed in Sierra do not use a -fused source version of gtest we need to make it possible for them to build with -this version as well as with their native build. To facilitate this we have -created symlinks for the other gtest headers that they use to the fused source -gtest.h. This will make it possible for them find the headers while still using -the fuse source version. This should not have any ill effects since the header is -protected and allows for only using the non-gtest.h headers in their files. - - diff --git a/lib/kokkos/tpls/gtest/gtest/gtest-all.cc b/lib/kokkos/tpls/gtest/gtest/gtest-all.cc deleted file mode 100644 index 538c78db93..0000000000 --- a/lib/kokkos/tpls/gtest/gtest/gtest-all.cc +++ /dev/null @@ -1,9594 +0,0 @@ -// Copyright 2008, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: mheule@google.com (Markus Heule) -// -// Google C++ Testing Framework (Google Test) -// -// Sometimes it's desirable to build Google Test by compiling a single file. -// This file serves this purpose. - -// This line ensures that gtest.h can be compiled on its own, even -// when it's fused. -#include "gtest/gtest.h" - -// The following lines pull in the real gtest *.cc files. -// Copyright 2005, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: wan@google.com (Zhanyong Wan) -// -// The Google C++ Testing Framework (Google Test) - -// Copyright 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: wan@google.com (Zhanyong Wan) -// -// Utilities for testing Google Test itself and code that uses Google Test -// (e.g. frameworks built on top of Google Test). - -#ifndef GTEST_INCLUDE_GTEST_GTEST_SPI_H_ -#define GTEST_INCLUDE_GTEST_GTEST_SPI_H_ - - -namespace testing { - -// This helper class can be used to mock out Google Test failure reporting -// so that we can test Google Test or code that builds on Google Test. -// -// An object of this class appends a TestPartResult object to the -// TestPartResultArray object given in the constructor whenever a Google Test -// failure is reported. It can either intercept only failures that are -// generated in the same thread that created this object or it can intercept -// all generated failures. The scope of this mock object can be controlled with -// the second argument to the two arguments constructor. -class GTEST_API_ ScopedFakeTestPartResultReporter - : public TestPartResultReporterInterface { - public: - // The two possible mocking modes of this object. - enum InterceptMode { - INTERCEPT_ONLY_CURRENT_THREAD, // Intercepts only thread local failures. - INTERCEPT_ALL_THREADS // Intercepts all failures. - }; - - // The c'tor sets this object as the test part result reporter used - // by Google Test. The 'result' parameter specifies where to report the - // results. This reporter will only catch failures generated in the current - // thread. DEPRECATED - explicit ScopedFakeTestPartResultReporter(TestPartResultArray* result); - - // Same as above, but you can choose the interception scope of this object. - ScopedFakeTestPartResultReporter(InterceptMode intercept_mode, - TestPartResultArray* result); - - // The d'tor restores the previous test part result reporter. - virtual ~ScopedFakeTestPartResultReporter(); - - // Appends the TestPartResult object to the TestPartResultArray - // received in the constructor. - // - // This method is from the TestPartResultReporterInterface - // interface. - virtual void ReportTestPartResult(const TestPartResult& result); - private: - void Init(); - - const InterceptMode intercept_mode_; - TestPartResultReporterInterface* old_reporter_; - TestPartResultArray* const result_; - - GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedFakeTestPartResultReporter); -}; - -namespace internal { - -// A helper class for implementing EXPECT_FATAL_FAILURE() and -// EXPECT_NONFATAL_FAILURE(). Its destructor verifies that the given -// TestPartResultArray contains exactly one failure that has the given -// type and contains the given substring. If that's not the case, a -// non-fatal failure will be generated. -class GTEST_API_ SingleFailureChecker { - public: - // The constructor remembers the arguments. - SingleFailureChecker(const TestPartResultArray* results, - TestPartResult::Type type, - const string& substr); - ~SingleFailureChecker(); - private: - const TestPartResultArray* const results_; - const TestPartResult::Type type_; - const string substr_; - - GTEST_DISALLOW_COPY_AND_ASSIGN_(SingleFailureChecker); -}; - -} // namespace internal - -} // namespace testing - -// A set of macros for testing Google Test assertions or code that's expected -// to generate Google Test fatal failures. It verifies that the given -// statement will cause exactly one fatal Google Test failure with 'substr' -// being part of the failure message. -// -// There are two different versions of this macro. EXPECT_FATAL_FAILURE only -// affects and considers failures generated in the current thread and -// EXPECT_FATAL_FAILURE_ON_ALL_THREADS does the same but for all threads. -// -// The verification of the assertion is done correctly even when the statement -// throws an exception or aborts the current function. -// -// Known restrictions: -// - 'statement' cannot reference local non-static variables or -// non-static members of the current object. -// - 'statement' cannot return a value. -// - You cannot stream a failure message to this macro. -// -// Note that even though the implementations of the following two -// macros are much alike, we cannot refactor them to use a common -// helper macro, due to some peculiarity in how the preprocessor -// works. The AcceptsMacroThatExpandsToUnprotectedComma test in -// gtest_unittest.cc will fail to compile if we do that. -#define EXPECT_FATAL_FAILURE(statement, substr) \ - do { \ - class GTestExpectFatalFailureHelper {\ - public:\ - static void Execute() { statement; }\ - };\ - ::testing::TestPartResultArray gtest_failures;\ - ::testing::internal::SingleFailureChecker gtest_checker(\ - >est_failures, ::testing::TestPartResult::kFatalFailure, (substr));\ - {\ - ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ - ::testing::ScopedFakeTestPartResultReporter:: \ - INTERCEPT_ONLY_CURRENT_THREAD, >est_failures);\ - GTestExpectFatalFailureHelper::Execute();\ - }\ - } while (::testing::internal::AlwaysFalse()) - -#define EXPECT_FATAL_FAILURE_ON_ALL_THREADS(statement, substr) \ - do { \ - class GTestExpectFatalFailureHelper {\ - public:\ - static void Execute() { statement; }\ - };\ - ::testing::TestPartResultArray gtest_failures;\ - ::testing::internal::SingleFailureChecker gtest_checker(\ - >est_failures, ::testing::TestPartResult::kFatalFailure, (substr));\ - {\ - ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ - ::testing::ScopedFakeTestPartResultReporter:: \ - INTERCEPT_ALL_THREADS, >est_failures);\ - GTestExpectFatalFailureHelper::Execute();\ - }\ - } while (::testing::internal::AlwaysFalse()) - -// A macro for testing Google Test assertions or code that's expected to -// generate Google Test non-fatal failures. It asserts that the given -// statement will cause exactly one non-fatal Google Test failure with 'substr' -// being part of the failure message. -// -// There are two different versions of this macro. EXPECT_NONFATAL_FAILURE only -// affects and considers failures generated in the current thread and -// EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS does the same but for all threads. -// -// 'statement' is allowed to reference local variables and members of -// the current object. -// -// The verification of the assertion is done correctly even when the statement -// throws an exception or aborts the current function. -// -// Known restrictions: -// - You cannot stream a failure message to this macro. -// -// Note that even though the implementations of the following two -// macros are much alike, we cannot refactor them to use a common -// helper macro, due to some peculiarity in how the preprocessor -// works. If we do that, the code won't compile when the user gives -// EXPECT_NONFATAL_FAILURE() a statement that contains a macro that -// expands to code containing an unprotected comma. The -// AcceptsMacroThatExpandsToUnprotectedComma test in gtest_unittest.cc -// catches that. -// -// For the same reason, we have to write -// if (::testing::internal::AlwaysTrue()) { statement; } -// instead of -// GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) -// to avoid an MSVC warning on unreachable code. -#define EXPECT_NONFATAL_FAILURE(statement, substr) \ - do {\ - ::testing::TestPartResultArray gtest_failures;\ - ::testing::internal::SingleFailureChecker gtest_checker(\ - >est_failures, ::testing::TestPartResult::kNonFatalFailure, \ - (substr));\ - {\ - ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ - ::testing::ScopedFakeTestPartResultReporter:: \ - INTERCEPT_ONLY_CURRENT_THREAD, >est_failures);\ - if (::testing::internal::AlwaysTrue()) { statement; }\ - }\ - } while (::testing::internal::AlwaysFalse()) - -#define EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(statement, substr) \ - do {\ - ::testing::TestPartResultArray gtest_failures;\ - ::testing::internal::SingleFailureChecker gtest_checker(\ - >est_failures, ::testing::TestPartResult::kNonFatalFailure, \ - (substr));\ - {\ - ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ - ::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS, \ - >est_failures);\ - if (::testing::internal::AlwaysTrue()) { statement; }\ - }\ - } while (::testing::internal::AlwaysFalse()) - -#endif // GTEST_INCLUDE_GTEST_GTEST_SPI_H_ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include // NOLINT -#include -#include - -#if GTEST_OS_LINUX - -// TODO(kenton@google.com): Use autoconf to detect availability of -// gettimeofday(). -# define GTEST_HAS_GETTIMEOFDAY_ 1 - -# include // NOLINT -# include // NOLINT -# include // NOLINT -// Declares vsnprintf(). This header is not available on Windows. -# include // NOLINT -# include // NOLINT -# include // NOLINT -# include // NOLINT -# include - -#elif GTEST_OS_SYMBIAN -# define GTEST_HAS_GETTIMEOFDAY_ 1 -# include // NOLINT - -#elif GTEST_OS_ZOS -# define GTEST_HAS_GETTIMEOFDAY_ 1 -# include // NOLINT - -// On z/OS we additionally need strings.h for strcasecmp. -# include // NOLINT - -#elif GTEST_OS_WINDOWS_MOBILE // We are on Windows CE. - -# include // NOLINT - -#elif GTEST_OS_WINDOWS // We are on Windows proper. - -# include // NOLINT -# include // NOLINT -# include // NOLINT -# include // NOLINT - -# if GTEST_OS_WINDOWS_MINGW -// MinGW has gettimeofday() but not _ftime64(). -// TODO(kenton@google.com): Use autoconf to detect availability of -// gettimeofday(). -// TODO(kenton@google.com): There are other ways to get the time on -// Windows, like GetTickCount() or GetSystemTimeAsFileTime(). MinGW -// supports these. consider using them instead. -# define GTEST_HAS_GETTIMEOFDAY_ 1 -# include // NOLINT -# endif // GTEST_OS_WINDOWS_MINGW - -// cpplint thinks that the header is already included, so we want to -// silence it. -# include // NOLINT - -#else - -// Assume other platforms have gettimeofday(). -// TODO(kenton@google.com): Use autoconf to detect availability of -// gettimeofday(). -# define GTEST_HAS_GETTIMEOFDAY_ 1 - -// cpplint thinks that the header is already included, so we want to -// silence it. -# include // NOLINT -# include // NOLINT - -#endif // GTEST_OS_LINUX - -#if GTEST_HAS_EXCEPTIONS -# include -#endif - -#if GTEST_CAN_STREAM_RESULTS_ -# include // NOLINT -# include // NOLINT -#endif - -// Indicates that this translation unit is part of Google Test's -// implementation. It must come before gtest-internal-inl.h is -// included, or there will be a compiler error. This trick is to -// prevent a user from accidentally including gtest-internal-inl.h in -// his code. -#define GTEST_IMPLEMENTATION_ 1 -// Copyright 2005, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Utility functions and classes used by the Google C++ testing framework. -// -// Author: wan@google.com (Zhanyong Wan) -// -// This file contains purely Google Test's internal implementation. Please -// DO NOT #INCLUDE IT IN A USER PROGRAM. - -#ifndef GTEST_SRC_GTEST_INTERNAL_INL_H_ -#define GTEST_SRC_GTEST_INTERNAL_INL_H_ - -// GTEST_IMPLEMENTATION_ is defined to 1 iff the current translation unit is -// part of Google Test's implementation; otherwise it's undefined. -#if !GTEST_IMPLEMENTATION_ -// A user is trying to include this from his code - just say no. -# error "gtest-internal-inl.h is part of Google Test's internal implementation." -# error "It must not be included except by Google Test itself." -#endif // GTEST_IMPLEMENTATION_ - -#ifndef _WIN32_WCE -# include -#endif // !_WIN32_WCE -#include -#include // For strtoll/_strtoul64/malloc/free. -#include // For memmove. - -#include -#include -#include - - -#if GTEST_CAN_STREAM_RESULTS_ -# include // NOLINT -# include // NOLINT -#endif - -#if GTEST_OS_WINDOWS -# include // NOLINT -#endif // GTEST_OS_WINDOWS - - -namespace testing { - -// Declares the flags. -// -// We don't want the users to modify this flag in the code, but want -// Google Test's own unit tests to be able to access it. Therefore we -// declare it here as opposed to in gtest.h. -GTEST_DECLARE_bool_(death_test_use_fork); - -namespace internal { - -// The value of GetTestTypeId() as seen from within the Google Test -// library. This is solely for testing GetTestTypeId(). -GTEST_API_ extern const TypeId kTestTypeIdInGoogleTest; - -// Names of the flags (needed for parsing Google Test flags). -const char kAlsoRunDisabledTestsFlag[] = "also_run_disabled_tests"; -const char kBreakOnFailureFlag[] = "break_on_failure"; -const char kCatchExceptionsFlag[] = "catch_exceptions"; -const char kColorFlag[] = "color"; -const char kFilterFlag[] = "filter"; -const char kListTestsFlag[] = "list_tests"; -const char kOutputFlag[] = "output"; -const char kPrintTimeFlag[] = "print_time"; -const char kRandomSeedFlag[] = "random_seed"; -const char kRepeatFlag[] = "repeat"; -const char kShuffleFlag[] = "shuffle"; -const char kStackTraceDepthFlag[] = "stack_trace_depth"; -const char kStreamResultToFlag[] = "stream_result_to"; -const char kThrowOnFailureFlag[] = "throw_on_failure"; - -// A valid random seed must be in [1, kMaxRandomSeed]. -const int kMaxRandomSeed = 99999; - -// g_help_flag is true iff the --help flag or an equivalent form is -// specified on the command line. -GTEST_API_ extern bool g_help_flag; - -// Returns the current time in milliseconds. -GTEST_API_ TimeInMillis GetTimeInMillis(); - -// Returns true iff Google Test should use colors in the output. -GTEST_API_ bool ShouldUseColor(bool stdout_is_tty); - -// Formats the given time in milliseconds as seconds. -GTEST_API_ std::string FormatTimeInMillisAsSeconds(TimeInMillis ms); - -// Converts the given time in milliseconds to a date string in the ISO 8601 -// format, without the timezone information. N.B.: due to the use the -// non-reentrant localtime() function, this function is not thread safe. Do -// not use it in any code that can be called from multiple threads. -GTEST_API_ std::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms); - -// Parses a string for an Int32 flag, in the form of "--flag=value". -// -// On success, stores the value of the flag in *value, and returns -// true. On failure, returns false without changing *value. -GTEST_API_ bool ParseInt32Flag( - const char* str, const char* flag, Int32* value); - -// Returns a random seed in range [1, kMaxRandomSeed] based on the -// given --gtest_random_seed flag value. -inline int GetRandomSeedFromFlag(Int32 random_seed_flag) { - const unsigned int raw_seed = (random_seed_flag == 0) ? - static_cast(GetTimeInMillis()) : - static_cast(random_seed_flag); - - // Normalizes the actual seed to range [1, kMaxRandomSeed] such that - // it's easy to type. - const int normalized_seed = - static_cast((raw_seed - 1U) % - static_cast(kMaxRandomSeed)) + 1; - return normalized_seed; -} - -// Returns the first valid random seed after 'seed'. The behavior is -// undefined if 'seed' is invalid. The seed after kMaxRandomSeed is -// considered to be 1. -inline int GetNextRandomSeed(int seed) { - GTEST_CHECK_(1 <= seed && seed <= kMaxRandomSeed) - << "Invalid random seed " << seed << " - must be in [1, " - << kMaxRandomSeed << "]."; - const int next_seed = seed + 1; - return (next_seed > kMaxRandomSeed) ? 1 : next_seed; -} - -// This class saves the values of all Google Test flags in its c'tor, and -// restores them in its d'tor. -class GTestFlagSaver { - public: - // The c'tor. - GTestFlagSaver() { - also_run_disabled_tests_ = GTEST_FLAG(also_run_disabled_tests); - break_on_failure_ = GTEST_FLAG(break_on_failure); - catch_exceptions_ = GTEST_FLAG(catch_exceptions); - color_ = GTEST_FLAG(color); - death_test_style_ = GTEST_FLAG(death_test_style); - death_test_use_fork_ = GTEST_FLAG(death_test_use_fork); - filter_ = GTEST_FLAG(filter); - internal_run_death_test_ = GTEST_FLAG(internal_run_death_test); - list_tests_ = GTEST_FLAG(list_tests); - output_ = GTEST_FLAG(output); - print_time_ = GTEST_FLAG(print_time); - random_seed_ = GTEST_FLAG(random_seed); - repeat_ = GTEST_FLAG(repeat); - shuffle_ = GTEST_FLAG(shuffle); - stack_trace_depth_ = GTEST_FLAG(stack_trace_depth); - stream_result_to_ = GTEST_FLAG(stream_result_to); - throw_on_failure_ = GTEST_FLAG(throw_on_failure); - } - - // The d'tor is not virtual. DO NOT INHERIT FROM THIS CLASS. - ~GTestFlagSaver() { - GTEST_FLAG(also_run_disabled_tests) = also_run_disabled_tests_; - GTEST_FLAG(break_on_failure) = break_on_failure_; - GTEST_FLAG(catch_exceptions) = catch_exceptions_; - GTEST_FLAG(color) = color_; - GTEST_FLAG(death_test_style) = death_test_style_; - GTEST_FLAG(death_test_use_fork) = death_test_use_fork_; - GTEST_FLAG(filter) = filter_; - GTEST_FLAG(internal_run_death_test) = internal_run_death_test_; - GTEST_FLAG(list_tests) = list_tests_; - GTEST_FLAG(output) = output_; - GTEST_FLAG(print_time) = print_time_; - GTEST_FLAG(random_seed) = random_seed_; - GTEST_FLAG(repeat) = repeat_; - GTEST_FLAG(shuffle) = shuffle_; - GTEST_FLAG(stack_trace_depth) = stack_trace_depth_; - GTEST_FLAG(stream_result_to) = stream_result_to_; - GTEST_FLAG(throw_on_failure) = throw_on_failure_; - } - - private: - // Fields for saving the original values of flags. - bool also_run_disabled_tests_; - bool break_on_failure_; - bool catch_exceptions_; - std::string color_; - std::string death_test_style_; - bool death_test_use_fork_; - std::string filter_; - std::string internal_run_death_test_; - bool list_tests_; - std::string output_; - bool print_time_; - internal::Int32 random_seed_; - internal::Int32 repeat_; - bool shuffle_; - internal::Int32 stack_trace_depth_; - std::string stream_result_to_; - bool throw_on_failure_; -} GTEST_ATTRIBUTE_UNUSED_; - -// Converts a Unicode code point to a narrow string in UTF-8 encoding. -// code_point parameter is of type UInt32 because wchar_t may not be -// wide enough to contain a code point. -// If the code_point is not a valid Unicode code point -// (i.e. outside of Unicode range U+0 to U+10FFFF) it will be converted -// to "(Invalid Unicode 0xXXXXXXXX)". -GTEST_API_ std::string CodePointToUtf8(UInt32 code_point); - -// Converts a wide string to a narrow string in UTF-8 encoding. -// The wide string is assumed to have the following encoding: -// UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin, Symbian OS) -// UTF-32 if sizeof(wchar_t) == 4 (on Linux) -// Parameter str points to a null-terminated wide string. -// Parameter num_chars may additionally limit the number -// of wchar_t characters processed. -1 is used when the entire string -// should be processed. -// If the string contains code points that are not valid Unicode code points -// (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output -// as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding -// and contains invalid UTF-16 surrogate pairs, values in those pairs -// will be encoded as individual Unicode characters from Basic Normal Plane. -GTEST_API_ std::string WideStringToUtf8(const wchar_t* str, int num_chars); - -// Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file -// if the variable is present. If a file already exists at this location, this -// function will write over it. If the variable is present, but the file cannot -// be created, prints an error and exits. -void WriteToShardStatusFileIfNeeded(); - -// Checks whether sharding is enabled by examining the relevant -// environment variable values. If the variables are present, -// but inconsistent (e.g., shard_index >= total_shards), prints -// an error and exits. If in_subprocess_for_death_test, sharding is -// disabled because it must only be applied to the original test -// process. Otherwise, we could filter out death tests we intended to execute. -GTEST_API_ bool ShouldShard(const char* total_shards_str, - const char* shard_index_str, - bool in_subprocess_for_death_test); - -// Parses the environment variable var as an Int32. If it is unset, -// returns default_val. If it is not an Int32, prints an error and -// and aborts. -GTEST_API_ Int32 Int32FromEnvOrDie(const char* env_var, Int32 default_val); - -// Given the total number of shards, the shard index, and the test id, -// returns true iff the test should be run on this shard. The test id is -// some arbitrary but unique non-negative integer assigned to each test -// method. Assumes that 0 <= shard_index < total_shards. -GTEST_API_ bool ShouldRunTestOnShard( - int total_shards, int shard_index, int test_id); - -// STL container utilities. - -// Returns the number of elements in the given container that satisfy -// the given predicate. -template -inline int CountIf(const Container& c, Predicate predicate) { - // Implemented as an explicit loop since std::count_if() in libCstd on - // Solaris has a non-standard signature. - int count = 0; - for (typename Container::const_iterator it = c.begin(); it != c.end(); ++it) { - if (predicate(*it)) - ++count; - } - return count; -} - -// Applies a function/functor to each element in the container. -template -void ForEach(const Container& c, Functor functor) { - std::for_each(c.begin(), c.end(), functor); -} - -// Returns the i-th element of the vector, or default_value if i is not -// in range [0, v.size()). -template -inline E GetElementOr(const std::vector& v, int i, E default_value) { - return (i < 0 || i >= static_cast(v.size())) ? default_value : v[i]; -} - -// Performs an in-place shuffle of a range of the vector's elements. -// 'begin' and 'end' are element indices as an STL-style range; -// i.e. [begin, end) are shuffled, where 'end' == size() means to -// shuffle to the end of the vector. -template -void ShuffleRange(internal::Random* random, int begin, int end, - std::vector* v) { - const int size = static_cast(v->size()); - GTEST_CHECK_(0 <= begin && begin <= size) - << "Invalid shuffle range start " << begin << ": must be in range [0, " - << size << "]."; - GTEST_CHECK_(begin <= end && end <= size) - << "Invalid shuffle range finish " << end << ": must be in range [" - << begin << ", " << size << "]."; - - // Fisher-Yates shuffle, from - // http://en.wikipedia.org/wiki/Fisher-Yates_shuffle - for (int range_width = end - begin; range_width >= 2; range_width--) { - const int last_in_range = begin + range_width - 1; - const int selected = begin + random->Generate(range_width); - std::swap((*v)[selected], (*v)[last_in_range]); - } -} - -// Performs an in-place shuffle of the vector's elements. -template -inline void Shuffle(internal::Random* random, std::vector* v) { - ShuffleRange(random, 0, static_cast(v->size()), v); -} - -// A function for deleting an object. Handy for being used as a -// functor. -template -static void Delete(T* x) { - delete x; -} - -// A predicate that checks the key of a TestProperty against a known key. -// -// TestPropertyKeyIs is copyable. -class TestPropertyKeyIs { - public: - // Constructor. - // - // TestPropertyKeyIs has NO default constructor. - explicit TestPropertyKeyIs(const std::string& key) : key_(key) {} - - // Returns true iff the test name of test property matches on key_. - bool operator()(const TestProperty& test_property) const { - return test_property.key() == key_; - } - - private: - std::string key_; -}; - -// Class UnitTestOptions. -// -// This class contains functions for processing options the user -// specifies when running the tests. It has only static members. -// -// In most cases, the user can specify an option using either an -// environment variable or a command line flag. E.g. you can set the -// test filter using either GTEST_FILTER or --gtest_filter. If both -// the variable and the flag are present, the latter overrides the -// former. -class GTEST_API_ UnitTestOptions { - public: - // Functions for processing the gtest_output flag. - - // Returns the output format, or "" for normal printed output. - static std::string GetOutputFormat(); - - // Returns the absolute path of the requested output file, or the - // default (test_detail.xml in the original working directory) if - // none was explicitly specified. - static std::string GetAbsolutePathToOutputFile(); - - // Functions for processing the gtest_filter flag. - - // Returns true iff the wildcard pattern matches the string. The - // first ':' or '\0' character in pattern marks the end of it. - // - // This recursive algorithm isn't very efficient, but is clear and - // works well enough for matching test names, which are short. - static bool PatternMatchesString(const char *pattern, const char *str); - - // Returns true iff the user-specified filter matches the test case - // name and the test name. - static bool FilterMatchesTest(const std::string &test_case_name, - const std::string &test_name); - -#if GTEST_OS_WINDOWS - // Function for supporting the gtest_catch_exception flag. - - // Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the - // given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise. - // This function is useful as an __except condition. - static int GTestShouldProcessSEH(DWORD exception_code); -#endif // GTEST_OS_WINDOWS - - // Returns true if "name" matches the ':' separated list of glob-style - // filters in "filter". - static bool MatchesFilter(const std::string& name, const char* filter); -}; - -// Returns the current application's name, removing directory path if that -// is present. Used by UnitTestOptions::GetOutputFile. -GTEST_API_ FilePath GetCurrentExecutableName(); - -// The role interface for getting the OS stack trace as a string. -class OsStackTraceGetterInterface { - public: - OsStackTraceGetterInterface() {} - virtual ~OsStackTraceGetterInterface() {} - - // Returns the current OS stack trace as an std::string. Parameters: - // - // max_depth - the maximum number of stack frames to be included - // in the trace. - // skip_count - the number of top frames to be skipped; doesn't count - // against max_depth. - virtual string CurrentStackTrace(int max_depth, int skip_count) = 0; - - // UponLeavingGTest() should be called immediately before Google Test calls - // user code. It saves some information about the current stack that - // CurrentStackTrace() will use to find and hide Google Test stack frames. - virtual void UponLeavingGTest() = 0; - - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetterInterface); -}; - -// A working implementation of the OsStackTraceGetterInterface interface. -class OsStackTraceGetter : public OsStackTraceGetterInterface { - public: - OsStackTraceGetter() : caller_frame_(NULL) {} - - virtual string CurrentStackTrace(int max_depth, int skip_count) - GTEST_LOCK_EXCLUDED_(mutex_); - - virtual void UponLeavingGTest() GTEST_LOCK_EXCLUDED_(mutex_); - - // This string is inserted in place of stack frames that are part of - // Google Test's implementation. - static const char* const kElidedFramesMarker; - - private: - Mutex mutex_; // protects all internal state - - // We save the stack frame below the frame that calls user code. - // We do this because the address of the frame immediately below - // the user code changes between the call to UponLeavingGTest() - // and any calls to CurrentStackTrace() from within the user code. - void* caller_frame_; - - GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetter); -}; - -// Information about a Google Test trace point. -struct TraceInfo { - const char* file; - int line; - std::string message; -}; - -// This is the default global test part result reporter used in UnitTestImpl. -// This class should only be used by UnitTestImpl. -class DefaultGlobalTestPartResultReporter - : public TestPartResultReporterInterface { - public: - explicit DefaultGlobalTestPartResultReporter(UnitTestImpl* unit_test); - // Implements the TestPartResultReporterInterface. Reports the test part - // result in the current test. - virtual void ReportTestPartResult(const TestPartResult& result); - - private: - UnitTestImpl* const unit_test_; - - GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultGlobalTestPartResultReporter); -}; - -// This is the default per thread test part result reporter used in -// UnitTestImpl. This class should only be used by UnitTestImpl. -class DefaultPerThreadTestPartResultReporter - : public TestPartResultReporterInterface { - public: - explicit DefaultPerThreadTestPartResultReporter(UnitTestImpl* unit_test); - // Implements the TestPartResultReporterInterface. The implementation just - // delegates to the current global test part result reporter of *unit_test_. - virtual void ReportTestPartResult(const TestPartResult& result); - - private: - UnitTestImpl* const unit_test_; - - GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultPerThreadTestPartResultReporter); -}; - -// The private implementation of the UnitTest class. We don't protect -// the methods under a mutex, as this class is not accessible by a -// user and the UnitTest class that delegates work to this class does -// proper locking. -class GTEST_API_ UnitTestImpl { - public: - explicit UnitTestImpl(UnitTest* parent); - virtual ~UnitTestImpl(); - - // There are two different ways to register your own TestPartResultReporter. - // You can register your own repoter to listen either only for test results - // from the current thread or for results from all threads. - // By default, each per-thread test result repoter just passes a new - // TestPartResult to the global test result reporter, which registers the - // test part result for the currently running test. - - // Returns the global test part result reporter. - TestPartResultReporterInterface* GetGlobalTestPartResultReporter(); - - // Sets the global test part result reporter. - void SetGlobalTestPartResultReporter( - TestPartResultReporterInterface* reporter); - - // Returns the test part result reporter for the current thread. - TestPartResultReporterInterface* GetTestPartResultReporterForCurrentThread(); - - // Sets the test part result reporter for the current thread. - void SetTestPartResultReporterForCurrentThread( - TestPartResultReporterInterface* reporter); - - // Gets the number of successful test cases. - int successful_test_case_count() const; - - // Gets the number of failed test cases. - int failed_test_case_count() const; - - // Gets the number of all test cases. - int total_test_case_count() const; - - // Gets the number of all test cases that contain at least one test - // that should run. - int test_case_to_run_count() const; - - // Gets the number of successful tests. - int successful_test_count() const; - - // Gets the number of failed tests. - int failed_test_count() const; - - // Gets the number of disabled tests that will be reported in the XML report. - int reportable_disabled_test_count() const; - - // Gets the number of disabled tests. - int disabled_test_count() const; - - // Gets the number of tests to be printed in the XML report. - int reportable_test_count() const; - - // Gets the number of all tests. - int total_test_count() const; - - // Gets the number of tests that should run. - int test_to_run_count() const; - - // Gets the time of the test program start, in ms from the start of the - // UNIX epoch. - TimeInMillis start_timestamp() const { return start_timestamp_; } - - // Gets the elapsed time, in milliseconds. - TimeInMillis elapsed_time() const { return elapsed_time_; } - - // Returns true iff the unit test passed (i.e. all test cases passed). - bool Passed() const { return !Failed(); } - - // Returns true iff the unit test failed (i.e. some test case failed - // or something outside of all tests failed). - bool Failed() const { - return failed_test_case_count() > 0 || ad_hoc_test_result()->Failed(); - } - - // Gets the i-th test case among all the test cases. i can range from 0 to - // total_test_case_count() - 1. If i is not in that range, returns NULL. - const TestCase* GetTestCase(int i) const { - const int index = GetElementOr(test_case_indices_, i, -1); - return index < 0 ? NULL : test_cases_[i]; - } - - // Gets the i-th test case among all the test cases. i can range from 0 to - // total_test_case_count() - 1. If i is not in that range, returns NULL. - TestCase* GetMutableTestCase(int i) { - const int index = GetElementOr(test_case_indices_, i, -1); - return index < 0 ? NULL : test_cases_[index]; - } - - // Provides access to the event listener list. - TestEventListeners* listeners() { return &listeners_; } - - // Returns the TestResult for the test that's currently running, or - // the TestResult for the ad hoc test if no test is running. - TestResult* current_test_result(); - - // Returns the TestResult for the ad hoc test. - const TestResult* ad_hoc_test_result() const { return &ad_hoc_test_result_; } - - // Sets the OS stack trace getter. - // - // Does nothing if the input and the current OS stack trace getter - // are the same; otherwise, deletes the old getter and makes the - // input the current getter. - void set_os_stack_trace_getter(OsStackTraceGetterInterface* getter); - - // Returns the current OS stack trace getter if it is not NULL; - // otherwise, creates an OsStackTraceGetter, makes it the current - // getter, and returns it. - OsStackTraceGetterInterface* os_stack_trace_getter(); - - // Returns the current OS stack trace as an std::string. - // - // The maximum number of stack frames to be included is specified by - // the gtest_stack_trace_depth flag. The skip_count parameter - // specifies the number of top frames to be skipped, which doesn't - // count against the number of frames to be included. - // - // For example, if Foo() calls Bar(), which in turn calls - // CurrentOsStackTraceExceptTop(1), Foo() will be included in the - // trace but Bar() and CurrentOsStackTraceExceptTop() won't. - std::string CurrentOsStackTraceExceptTop(int skip_count) GTEST_NO_INLINE_; - - // Finds and returns a TestCase with the given name. If one doesn't - // exist, creates one and returns it. - // - // Arguments: - // - // test_case_name: name of the test case - // type_param: the name of the test's type parameter, or NULL if - // this is not a typed or a type-parameterized test. - // set_up_tc: pointer to the function that sets up the test case - // tear_down_tc: pointer to the function that tears down the test case - TestCase* GetTestCase(const char* test_case_name, - const char* type_param, - Test::SetUpTestCaseFunc set_up_tc, - Test::TearDownTestCaseFunc tear_down_tc); - - // Adds a TestInfo to the unit test. - // - // Arguments: - // - // set_up_tc: pointer to the function that sets up the test case - // tear_down_tc: pointer to the function that tears down the test case - // test_info: the TestInfo object - void AddTestInfo(Test::SetUpTestCaseFunc set_up_tc, - Test::TearDownTestCaseFunc tear_down_tc, - TestInfo* test_info) { - // In order to support thread-safe death tests, we need to - // remember the original working directory when the test program - // was first invoked. We cannot do this in RUN_ALL_TESTS(), as - // the user may have changed the current directory before calling - // RUN_ALL_TESTS(). Therefore we capture the current directory in - // AddTestInfo(), which is called to register a TEST or TEST_F - // before main() is reached. - if (original_working_dir_.IsEmpty()) { - original_working_dir_.Set(FilePath::GetCurrentDir()); - GTEST_CHECK_(!original_working_dir_.IsEmpty()) - << "Failed to get the current working directory."; - } - - GetTestCase(test_info->test_case_name(), - test_info->type_param(), - set_up_tc, - tear_down_tc)->AddTestInfo(test_info); - } - -#if GTEST_HAS_PARAM_TEST - // Returns ParameterizedTestCaseRegistry object used to keep track of - // value-parameterized tests and instantiate and register them. - internal::ParameterizedTestCaseRegistry& parameterized_test_registry() { - return parameterized_test_registry_; - } -#endif // GTEST_HAS_PARAM_TEST - - // Sets the TestCase object for the test that's currently running. - void set_current_test_case(TestCase* a_current_test_case) { - current_test_case_ = a_current_test_case; - } - - // Sets the TestInfo object for the test that's currently running. If - // current_test_info is NULL, the assertion results will be stored in - // ad_hoc_test_result_. - void set_current_test_info(TestInfo* a_current_test_info) { - current_test_info_ = a_current_test_info; - } - - // Registers all parameterized tests defined using TEST_P and - // INSTANTIATE_TEST_CASE_P, creating regular tests for each test/parameter - // combination. This method can be called more then once; it has guards - // protecting from registering the tests more then once. If - // value-parameterized tests are disabled, RegisterParameterizedTests is - // present but does nothing. - void RegisterParameterizedTests(); - - // Runs all tests in this UnitTest object, prints the result, and - // returns true if all tests are successful. If any exception is - // thrown during a test, this test is considered to be failed, but - // the rest of the tests will still be run. - bool RunAllTests(); - - // Clears the results of all tests, except the ad hoc tests. - void ClearNonAdHocTestResult() { - ForEach(test_cases_, TestCase::ClearTestCaseResult); - } - - // Clears the results of ad-hoc test assertions. - void ClearAdHocTestResult() { - ad_hoc_test_result_.Clear(); - } - - // Adds a TestProperty to the current TestResult object when invoked in a - // context of a test or a test case, or to the global property set. If the - // result already contains a property with the same key, the value will be - // updated. - void RecordProperty(const TestProperty& test_property); - - enum ReactionToSharding { - HONOR_SHARDING_PROTOCOL, - IGNORE_SHARDING_PROTOCOL - }; - - // Matches the full name of each test against the user-specified - // filter to decide whether the test should run, then records the - // result in each TestCase and TestInfo object. - // If shard_tests == HONOR_SHARDING_PROTOCOL, further filters tests - // based on sharding variables in the environment. - // Returns the number of tests that should run. - int FilterTests(ReactionToSharding shard_tests); - - // Prints the names of the tests matching the user-specified filter flag. - void ListTestsMatchingFilter(); - - const TestCase* current_test_case() const { return current_test_case_; } - TestInfo* current_test_info() { return current_test_info_; } - const TestInfo* current_test_info() const { return current_test_info_; } - - // Returns the vector of environments that need to be set-up/torn-down - // before/after the tests are run. - std::vector& environments() { return environments_; } - - // Getters for the per-thread Google Test trace stack. - std::vector& gtest_trace_stack() { - return *(gtest_trace_stack_.pointer()); - } - const std::vector& gtest_trace_stack() const { - return gtest_trace_stack_.get(); - } - -#if GTEST_HAS_DEATH_TEST - void InitDeathTestSubprocessControlInfo() { - internal_run_death_test_flag_.reset(ParseInternalRunDeathTestFlag()); - } - // Returns a pointer to the parsed --gtest_internal_run_death_test - // flag, or NULL if that flag was not specified. - // This information is useful only in a death test child process. - // Must not be called before a call to InitGoogleTest. - const InternalRunDeathTestFlag* internal_run_death_test_flag() const { - return internal_run_death_test_flag_.get(); - } - - // Returns a pointer to the current death test factory. - internal::DeathTestFactory* death_test_factory() { - return death_test_factory_.get(); - } - - void SuppressTestEventsIfInSubprocess(); - - friend class ReplaceDeathTestFactory; -#endif // GTEST_HAS_DEATH_TEST - - // Initializes the event listener performing XML output as specified by - // UnitTestOptions. Must not be called before InitGoogleTest. - void ConfigureXmlOutput(); - -#if GTEST_CAN_STREAM_RESULTS_ - // Initializes the event listener for streaming test results to a socket. - // Must not be called before InitGoogleTest. - void ConfigureStreamingOutput(); -#endif - - // Performs initialization dependent upon flag values obtained in - // ParseGoogleTestFlagsOnly. Is called from InitGoogleTest after the call to - // ParseGoogleTestFlagsOnly. In case a user neglects to call InitGoogleTest - // this function is also called from RunAllTests. Since this function can be - // called more than once, it has to be idempotent. - void PostFlagParsingInit(); - - // Gets the random seed used at the start of the current test iteration. - int random_seed() const { return random_seed_; } - - // Gets the random number generator. - internal::Random* random() { return &random_; } - - // Shuffles all test cases, and the tests within each test case, - // making sure that death tests are still run first. - void ShuffleTests(); - - // Restores the test cases and tests to their order before the first shuffle. - void UnshuffleTests(); - - // Returns the value of GTEST_FLAG(catch_exceptions) at the moment - // UnitTest::Run() starts. - bool catch_exceptions() const { return catch_exceptions_; } - - private: - friend class ::testing::UnitTest; - - // Used by UnitTest::Run() to capture the state of - // GTEST_FLAG(catch_exceptions) at the moment it starts. - void set_catch_exceptions(bool value) { catch_exceptions_ = value; } - - // The UnitTest object that owns this implementation object. - UnitTest* const parent_; - - // The working directory when the first TEST() or TEST_F() was - // executed. - internal::FilePath original_working_dir_; - - // The default test part result reporters. - DefaultGlobalTestPartResultReporter default_global_test_part_result_reporter_; - DefaultPerThreadTestPartResultReporter - default_per_thread_test_part_result_reporter_; - - // Points to (but doesn't own) the global test part result reporter. - TestPartResultReporterInterface* global_test_part_result_repoter_; - - // Protects read and write access to global_test_part_result_reporter_. - internal::Mutex global_test_part_result_reporter_mutex_; - - // Points to (but doesn't own) the per-thread test part result reporter. - internal::ThreadLocal - per_thread_test_part_result_reporter_; - - // The vector of environments that need to be set-up/torn-down - // before/after the tests are run. - std::vector environments_; - - // The vector of TestCases in their original order. It owns the - // elements in the vector. - std::vector test_cases_; - - // Provides a level of indirection for the test case list to allow - // easy shuffling and restoring the test case order. The i-th - // element of this vector is the index of the i-th test case in the - // shuffled order. - std::vector test_case_indices_; - -#if GTEST_HAS_PARAM_TEST - // ParameterizedTestRegistry object used to register value-parameterized - // tests. - internal::ParameterizedTestCaseRegistry parameterized_test_registry_; - - // Indicates whether RegisterParameterizedTests() has been called already. - bool parameterized_tests_registered_; -#endif // GTEST_HAS_PARAM_TEST - - // Index of the last death test case registered. Initially -1. - int last_death_test_case_; - - // This points to the TestCase for the currently running test. It - // changes as Google Test goes through one test case after another. - // When no test is running, this is set to NULL and Google Test - // stores assertion results in ad_hoc_test_result_. Initially NULL. - TestCase* current_test_case_; - - // This points to the TestInfo for the currently running test. It - // changes as Google Test goes through one test after another. When - // no test is running, this is set to NULL and Google Test stores - // assertion results in ad_hoc_test_result_. Initially NULL. - TestInfo* current_test_info_; - - // Normally, a user only writes assertions inside a TEST or TEST_F, - // or inside a function called by a TEST or TEST_F. Since Google - // Test keeps track of which test is current running, it can - // associate such an assertion with the test it belongs to. - // - // If an assertion is encountered when no TEST or TEST_F is running, - // Google Test attributes the assertion result to an imaginary "ad hoc" - // test, and records the result in ad_hoc_test_result_. - TestResult ad_hoc_test_result_; - - // The list of event listeners that can be used to track events inside - // Google Test. - TestEventListeners listeners_; - - // The OS stack trace getter. Will be deleted when the UnitTest - // object is destructed. By default, an OsStackTraceGetter is used, - // but the user can set this field to use a custom getter if that is - // desired. - OsStackTraceGetterInterface* os_stack_trace_getter_; - - // True iff PostFlagParsingInit() has been called. - bool post_flag_parse_init_performed_; - - // The random number seed used at the beginning of the test run. - int random_seed_; - - // Our random number generator. - internal::Random random_; - - // The time of the test program start, in ms from the start of the - // UNIX epoch. - TimeInMillis start_timestamp_; - - // How long the test took to run, in milliseconds. - TimeInMillis elapsed_time_; - -#if GTEST_HAS_DEATH_TEST - // The decomposed components of the gtest_internal_run_death_test flag, - // parsed when RUN_ALL_TESTS is called. - internal::scoped_ptr internal_run_death_test_flag_; - internal::scoped_ptr death_test_factory_; -#endif // GTEST_HAS_DEATH_TEST - - // A per-thread stack of traces created by the SCOPED_TRACE() macro. - internal::ThreadLocal > gtest_trace_stack_; - - // The value of GTEST_FLAG(catch_exceptions) at the moment RunAllTests() - // starts. - bool catch_exceptions_; - - GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTestImpl); -}; // class UnitTestImpl - -// Convenience function for accessing the global UnitTest -// implementation object. -inline UnitTestImpl* GetUnitTestImpl() { - return UnitTest::GetInstance()->impl(); -} - -#if GTEST_USES_SIMPLE_RE - -// Internal helper functions for implementing the simple regular -// expression matcher. -GTEST_API_ bool IsInSet(char ch, const char* str); -GTEST_API_ bool IsAsciiDigit(char ch); -GTEST_API_ bool IsAsciiPunct(char ch); -GTEST_API_ bool IsRepeat(char ch); -GTEST_API_ bool IsAsciiWhiteSpace(char ch); -GTEST_API_ bool IsAsciiWordChar(char ch); -GTEST_API_ bool IsValidEscape(char ch); -GTEST_API_ bool AtomMatchesChar(bool escaped, char pattern, char ch); -GTEST_API_ bool ValidateRegex(const char* regex); -GTEST_API_ bool MatchRegexAtHead(const char* regex, const char* str); -GTEST_API_ bool MatchRepetitionAndRegexAtHead( - bool escaped, char ch, char repeat, const char* regex, const char* str); -GTEST_API_ bool MatchRegexAnywhere(const char* regex, const char* str); - -#endif // GTEST_USES_SIMPLE_RE - -// Parses the command line for Google Test flags, without initializing -// other parts of Google Test. -GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, char** argv); -GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv); - -#if GTEST_HAS_DEATH_TEST - -// Returns the message describing the last system error, regardless of the -// platform. -GTEST_API_ std::string GetLastErrnoDescription(); - -# if GTEST_OS_WINDOWS -// Provides leak-safe Windows kernel handle ownership. -class AutoHandle { - public: - AutoHandle() : handle_(INVALID_HANDLE_VALUE) {} - explicit AutoHandle(HANDLE handle) : handle_(handle) {} - - ~AutoHandle() { Reset(); } - - HANDLE Get() const { return handle_; } - void Reset() { Reset(INVALID_HANDLE_VALUE); } - void Reset(HANDLE handle) { - if (handle != handle_) { - if (handle_ != INVALID_HANDLE_VALUE) - ::CloseHandle(handle_); - handle_ = handle; - } - } - - private: - HANDLE handle_; - - GTEST_DISALLOW_COPY_AND_ASSIGN_(AutoHandle); -}; -# endif // GTEST_OS_WINDOWS - -// Attempts to parse a string into a positive integer pointed to by the -// number parameter. Returns true if that is possible. -// GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we can use -// it here. -template -bool ParseNaturalNumber(const ::std::string& str, Integer* number) { - // Fail fast if the given string does not begin with a digit; - // this bypasses strtoXXX's "optional leading whitespace and plus - // or minus sign" semantics, which are undesirable here. - if (str.empty() || !IsDigit(str[0])) { - return false; - } - errno = 0; - - char* end; - // BiggestConvertible is the largest integer type that system-provided - // string-to-number conversion routines can return. - -# if GTEST_OS_WINDOWS && !defined(__GNUC__) - - // MSVC and C++ Builder define __int64 instead of the standard long long. - typedef unsigned __int64 BiggestConvertible; - const BiggestConvertible parsed = _strtoui64(str.c_str(), &end, 10); - -# else - - typedef unsigned long long BiggestConvertible; // NOLINT - const BiggestConvertible parsed = strtoull(str.c_str(), &end, 10); - -# endif // GTEST_OS_WINDOWS && !defined(__GNUC__) - - const bool parse_success = *end == '\0' && errno == 0; - - // TODO(vladl@google.com): Convert this to compile time assertion when it is - // available. - GTEST_CHECK_(sizeof(Integer) <= sizeof(parsed)); - - const Integer result = static_cast(parsed); - if (parse_success && static_cast(result) == parsed) { - *number = result; - return true; - } - return false; -} -#endif // GTEST_HAS_DEATH_TEST - -// TestResult contains some private methods that should be hidden from -// Google Test user but are required for testing. This class allow our tests -// to access them. -// -// This class is supplied only for the purpose of testing Google Test's own -// constructs. Do not use it in user tests, either directly or indirectly. -class TestResultAccessor { - public: - static void RecordProperty(TestResult* test_result, - const std::string& xml_element, - const TestProperty& property) { - test_result->RecordProperty(xml_element, property); - } - - static void ClearTestPartResults(TestResult* test_result) { - test_result->ClearTestPartResults(); - } - - static const std::vector& test_part_results( - const TestResult& test_result) { - return test_result.test_part_results(); - } -}; - -#if GTEST_CAN_STREAM_RESULTS_ - -// Streams test results to the given port on the given host machine. -class StreamingListener : public EmptyTestEventListener { - public: - // Abstract base class for writing strings to a socket. - class AbstractSocketWriter { - public: - virtual ~AbstractSocketWriter() {} - - // Sends a string to the socket. - virtual void Send(const string& message) = 0; - - // Closes the socket. - virtual void CloseConnection() {} - - // Sends a string and a newline to the socket. - void SendLn(const string& message) { - Send(message + "\n"); - } - }; - - // Concrete class for actually writing strings to a socket. - class SocketWriter : public AbstractSocketWriter { - public: - SocketWriter(const string& host, const string& port) - : sockfd_(-1), host_name_(host), port_num_(port) { - MakeConnection(); - } - - virtual ~SocketWriter() { - if (sockfd_ != -1) - CloseConnection(); - } - - // Sends a string to the socket. - virtual void Send(const string& message) { - GTEST_CHECK_(sockfd_ != -1) - << "Send() can be called only when there is a connection."; - - const int len = static_cast(message.length()); - if (write(sockfd_, message.c_str(), len) != len) { - GTEST_LOG_(WARNING) - << "stream_result_to: failed to stream to " - << host_name_ << ":" << port_num_; - } - } - - private: - // Creates a client socket and connects to the server. - void MakeConnection(); - - // Closes the socket. - void CloseConnection() { - GTEST_CHECK_(sockfd_ != -1) - << "CloseConnection() can be called only when there is a connection."; - - close(sockfd_); - sockfd_ = -1; - } - - int sockfd_; // socket file descriptor - const string host_name_; - const string port_num_; - - GTEST_DISALLOW_COPY_AND_ASSIGN_(SocketWriter); - }; // class SocketWriter - - // Escapes '=', '&', '%', and '\n' characters in str as "%xx". - static string UrlEncode(const char* str); - - StreamingListener(const string& host, const string& port) - : socket_writer_(new SocketWriter(host, port)) { Start(); } - - explicit StreamingListener(AbstractSocketWriter* socket_writer) - : socket_writer_(socket_writer) { Start(); } - - void OnTestProgramStart(const UnitTest& /* unit_test */) { - SendLn("event=TestProgramStart"); - } - - void OnTestProgramEnd(const UnitTest& unit_test) { - // Note that Google Test current only report elapsed time for each - // test iteration, not for the entire test program. - SendLn("event=TestProgramEnd&passed=" + FormatBool(unit_test.Passed())); - - // Notify the streaming server to stop. - socket_writer_->CloseConnection(); - } - - void OnTestIterationStart(const UnitTest& /* unit_test */, int iteration) { - SendLn("event=TestIterationStart&iteration=" + - StreamableToString(iteration)); - } - - void OnTestIterationEnd(const UnitTest& unit_test, int /* iteration */) { - SendLn("event=TestIterationEnd&passed=" + - FormatBool(unit_test.Passed()) + "&elapsed_time=" + - StreamableToString(unit_test.elapsed_time()) + "ms"); - } - - void OnTestCaseStart(const TestCase& test_case) { - SendLn(std::string("event=TestCaseStart&name=") + test_case.name()); - } - - void OnTestCaseEnd(const TestCase& test_case) { - SendLn("event=TestCaseEnd&passed=" + FormatBool(test_case.Passed()) - + "&elapsed_time=" + StreamableToString(test_case.elapsed_time()) - + "ms"); - } - - void OnTestStart(const TestInfo& test_info) { - SendLn(std::string("event=TestStart&name=") + test_info.name()); - } - - void OnTestEnd(const TestInfo& test_info) { - SendLn("event=TestEnd&passed=" + - FormatBool((test_info.result())->Passed()) + - "&elapsed_time=" + - StreamableToString((test_info.result())->elapsed_time()) + "ms"); - } - - void OnTestPartResult(const TestPartResult& test_part_result) { - const char* file_name = test_part_result.file_name(); - if (file_name == NULL) - file_name = ""; - SendLn("event=TestPartResult&file=" + UrlEncode(file_name) + - "&line=" + StreamableToString(test_part_result.line_number()) + - "&message=" + UrlEncode(test_part_result.message())); - } - - private: - // Sends the given message and a newline to the socket. - void SendLn(const string& message) { socket_writer_->SendLn(message); } - - // Called at the start of streaming to notify the receiver what - // protocol we are using. - void Start() { SendLn("gtest_streaming_protocol_version=1.0"); } - - string FormatBool(bool value) { return value ? "1" : "0"; } - - const scoped_ptr socket_writer_; - - GTEST_DISALLOW_COPY_AND_ASSIGN_(StreamingListener); -}; // class StreamingListener - -#endif // GTEST_CAN_STREAM_RESULTS_ - -} // namespace internal -} // namespace testing - -#endif // GTEST_SRC_GTEST_INTERNAL_INL_H_ -#undef GTEST_IMPLEMENTATION_ - -#if GTEST_OS_WINDOWS -# define vsnprintf _vsnprintf -#endif // GTEST_OS_WINDOWS - -namespace testing { - -using internal::CountIf; -using internal::ForEach; -using internal::GetElementOr; -using internal::Shuffle; - -// Constants. - -// A test whose test case name or test name matches this filter is -// disabled and not run. -static const char kDisableTestFilter[] = "DISABLED_*:*/DISABLED_*"; - -// A test case whose name matches this filter is considered a death -// test case and will be run before test cases whose name doesn't -// match this filter. -static const char kDeathTestCaseFilter[] = "*DeathTest:*DeathTest/*"; - -// A test filter that matches everything. -static const char kUniversalFilter[] = "*"; - -// The default output file for XML output. -static const char kDefaultOutputFile[] = "test_detail.xml"; - -// The environment variable name for the test shard index. -static const char kTestShardIndex[] = "GTEST_SHARD_INDEX"; -// The environment variable name for the total number of test shards. -static const char kTestTotalShards[] = "GTEST_TOTAL_SHARDS"; -// The environment variable name for the test shard status file. -static const char kTestShardStatusFile[] = "GTEST_SHARD_STATUS_FILE"; - -namespace internal { - -// The text used in failure messages to indicate the start of the -// stack trace. -const char kStackTraceMarker[] = "\nStack trace:\n"; - -// g_help_flag is true iff the --help flag or an equivalent form is -// specified on the command line. -bool g_help_flag = false; - -} // namespace internal - -static const char* GetDefaultFilter() { - return kUniversalFilter; -} - -GTEST_DEFINE_bool_( - also_run_disabled_tests, - internal::BoolFromGTestEnv("also_run_disabled_tests", false), - "Run disabled tests too, in addition to the tests normally being run."); - -GTEST_DEFINE_bool_( - break_on_failure, - internal::BoolFromGTestEnv("break_on_failure", false), - "True iff a failed assertion should be a debugger break-point."); - -GTEST_DEFINE_bool_( - catch_exceptions, - internal::BoolFromGTestEnv("catch_exceptions", true), - "True iff " GTEST_NAME_ - " should catch exceptions and treat them as test failures."); - -GTEST_DEFINE_string_( - color, - internal::StringFromGTestEnv("color", "auto"), - "Whether to use colors in the output. Valid values: yes, no, " - "and auto. 'auto' means to use colors if the output is " - "being sent to a terminal and the TERM environment variable " - "is set to a terminal type that supports colors."); - -GTEST_DEFINE_string_( - filter, - internal::StringFromGTestEnv("filter", GetDefaultFilter()), - "A colon-separated list of glob (not regex) patterns " - "for filtering the tests to run, optionally followed by a " - "'-' and a : separated list of negative patterns (tests to " - "exclude). A test is run if it matches one of the positive " - "patterns and does not match any of the negative patterns."); - -GTEST_DEFINE_bool_(list_tests, false, - "List all tests without running them."); - -GTEST_DEFINE_string_( - output, - internal::StringFromGTestEnv("output", ""), - "A format (currently must be \"xml\"), optionally followed " - "by a colon and an output file name or directory. A directory " - "is indicated by a trailing pathname separator. " - "Examples: \"xml:filename.xml\", \"xml::directoryname/\". " - "If a directory is specified, output files will be created " - "within that directory, with file-names based on the test " - "executable's name and, if necessary, made unique by adding " - "digits."); - -GTEST_DEFINE_bool_( - print_time, - internal::BoolFromGTestEnv("print_time", true), - "True iff " GTEST_NAME_ - " should display elapsed time in text output."); - -GTEST_DEFINE_int32_( - random_seed, - internal::Int32FromGTestEnv("random_seed", 0), - "Random number seed to use when shuffling test orders. Must be in range " - "[1, 99999], or 0 to use a seed based on the current time."); - -GTEST_DEFINE_int32_( - repeat, - internal::Int32FromGTestEnv("repeat", 1), - "How many times to repeat each test. Specify a negative number " - "for repeating forever. Useful for shaking out flaky tests."); - -GTEST_DEFINE_bool_( - show_internal_stack_frames, false, - "True iff " GTEST_NAME_ " should include internal stack frames when " - "printing test failure stack traces."); - -GTEST_DEFINE_bool_( - shuffle, - internal::BoolFromGTestEnv("shuffle", false), - "True iff " GTEST_NAME_ - " should randomize tests' order on every run."); - -GTEST_DEFINE_int32_( - stack_trace_depth, - internal::Int32FromGTestEnv("stack_trace_depth", kMaxStackTraceDepth), - "The maximum number of stack frames to print when an " - "assertion fails. The valid range is 0 through 100, inclusive."); - -GTEST_DEFINE_string_( - stream_result_to, - internal::StringFromGTestEnv("stream_result_to", ""), - "This flag specifies the host name and the port number on which to stream " - "test results. Example: \"localhost:555\". The flag is effective only on " - "Linux."); - -GTEST_DEFINE_bool_( - throw_on_failure, - internal::BoolFromGTestEnv("throw_on_failure", false), - "When this flag is specified, a failed assertion will throw an exception " - "if exceptions are enabled or exit the program with a non-zero code " - "otherwise."); - -namespace internal { - -// Generates a random number from [0, range), using a Linear -// Congruential Generator (LCG). Crashes if 'range' is 0 or greater -// than kMaxRange. -UInt32 Random::Generate(UInt32 range) { - // These constants are the same as are used in glibc's rand(3). - state_ = (1103515245U*state_ + 12345U) % kMaxRange; - - GTEST_CHECK_(range > 0) - << "Cannot generate a number in the range [0, 0)."; - GTEST_CHECK_(range <= kMaxRange) - << "Generation of a number in [0, " << range << ") was requested, " - << "but this can only generate numbers in [0, " << kMaxRange << ")."; - - // Converting via modulus introduces a bit of downward bias, but - // it's simple, and a linear congruential generator isn't too good - // to begin with. - return state_ % range; -} - -// GTestIsInitialized() returns true iff the user has initialized -// Google Test. Useful for catching the user mistake of not initializing -// Google Test before calling RUN_ALL_TESTS(). -// -// A user must call testing::InitGoogleTest() to initialize Google -// Test. g_init_gtest_count is set to the number of times -// InitGoogleTest() has been called. We don't protect this variable -// under a mutex as it is only accessed in the main thread. -GTEST_API_ int g_init_gtest_count = 0; -static bool GTestIsInitialized() { return g_init_gtest_count != 0; } - -// Iterates over a vector of TestCases, keeping a running sum of the -// results of calling a given int-returning method on each. -// Returns the sum. -static int SumOverTestCaseList(const std::vector& case_list, - int (TestCase::*method)() const) { - int sum = 0; - for (size_t i = 0; i < case_list.size(); i++) { - sum += (case_list[i]->*method)(); - } - return sum; -} - -// Returns true iff the test case passed. -static bool TestCasePassed(const TestCase* test_case) { - return test_case->should_run() && test_case->Passed(); -} - -// Returns true iff the test case failed. -static bool TestCaseFailed(const TestCase* test_case) { - return test_case->should_run() && test_case->Failed(); -} - -// Returns true iff test_case contains at least one test that should -// run. -static bool ShouldRunTestCase(const TestCase* test_case) { - return test_case->should_run(); -} - -// AssertHelper constructor. -AssertHelper::AssertHelper(TestPartResult::Type type, - const char* file, - int line, - const char* message) - : data_(new AssertHelperData(type, file, line, message)) { -} - -AssertHelper::~AssertHelper() { - delete data_; -} - -// Message assignment, for assertion streaming support. -void AssertHelper::operator=(const Message& message) const { - UnitTest::GetInstance()-> - AddTestPartResult(data_->type, data_->file, data_->line, - AppendUserMessage(data_->message, message), - UnitTest::GetInstance()->impl() - ->CurrentOsStackTraceExceptTop(1) - // Skips the stack frame for this function itself. - ); // NOLINT -} - -// Mutex for linked pointers. -GTEST_API_ GTEST_DEFINE_STATIC_MUTEX_(g_linked_ptr_mutex); - -// Application pathname gotten in InitGoogleTest. -std::string g_executable_path; - -// Returns the current application's name, removing directory path if that -// is present. -FilePath GetCurrentExecutableName() { - FilePath result; - -#if GTEST_OS_WINDOWS - result.Set(FilePath(g_executable_path).RemoveExtension("exe")); -#else - result.Set(FilePath(g_executable_path)); -#endif // GTEST_OS_WINDOWS - - return result.RemoveDirectoryName(); -} - -// Functions for processing the gtest_output flag. - -// Returns the output format, or "" for normal printed output. -std::string UnitTestOptions::GetOutputFormat() { - const char* const gtest_output_flag = GTEST_FLAG(output).c_str(); - if (gtest_output_flag == NULL) return std::string(""); - - const char* const colon = strchr(gtest_output_flag, ':'); - return (colon == NULL) ? - std::string(gtest_output_flag) : - std::string(gtest_output_flag, colon - gtest_output_flag); -} - -// Returns the name of the requested output file, or the default if none -// was explicitly specified. -std::string UnitTestOptions::GetAbsolutePathToOutputFile() { - const char* const gtest_output_flag = GTEST_FLAG(output).c_str(); - if (gtest_output_flag == NULL) - return ""; - - const char* const colon = strchr(gtest_output_flag, ':'); - if (colon == NULL) - return internal::FilePath::ConcatPaths( - internal::FilePath( - UnitTest::GetInstance()->original_working_dir()), - internal::FilePath(kDefaultOutputFile)).string(); - - internal::FilePath output_name(colon + 1); - if (!output_name.IsAbsolutePath()) - // TODO(wan@google.com): on Windows \some\path is not an absolute - // path (as its meaning depends on the current drive), yet the - // following logic for turning it into an absolute path is wrong. - // Fix it. - output_name = internal::FilePath::ConcatPaths( - internal::FilePath(UnitTest::GetInstance()->original_working_dir()), - internal::FilePath(colon + 1)); - - if (!output_name.IsDirectory()) - return output_name.string(); - - internal::FilePath result(internal::FilePath::GenerateUniqueFileName( - output_name, internal::GetCurrentExecutableName(), - GetOutputFormat().c_str())); - return result.string(); -} - -// Returns true iff the wildcard pattern matches the string. The -// first ':' or '\0' character in pattern marks the end of it. -// -// This recursive algorithm isn't very efficient, but is clear and -// works well enough for matching test names, which are short. -bool UnitTestOptions::PatternMatchesString(const char *pattern, - const char *str) { - switch (*pattern) { - case '\0': - case ':': // Either ':' or '\0' marks the end of the pattern. - return *str == '\0'; - case '?': // Matches any single character. - return *str != '\0' && PatternMatchesString(pattern + 1, str + 1); - case '*': // Matches any string (possibly empty) of characters. - return (*str != '\0' && PatternMatchesString(pattern, str + 1)) || - PatternMatchesString(pattern + 1, str); - default: // Non-special character. Matches itself. - return *pattern == *str && - PatternMatchesString(pattern + 1, str + 1); - } -} - -bool UnitTestOptions::MatchesFilter( - const std::string& name, const char* filter) { - const char *cur_pattern = filter; - for (;;) { - if (PatternMatchesString(cur_pattern, name.c_str())) { - return true; - } - - // Finds the next pattern in the filter. - cur_pattern = strchr(cur_pattern, ':'); - - // Returns if no more pattern can be found. - if (cur_pattern == NULL) { - return false; - } - - // Skips the pattern separater (the ':' character). - cur_pattern++; - } -} - -// Returns true iff the user-specified filter matches the test case -// name and the test name. -bool UnitTestOptions::FilterMatchesTest(const std::string &test_case_name, - const std::string &test_name) { - const std::string& full_name = test_case_name + "." + test_name.c_str(); - - // Split --gtest_filter at '-', if there is one, to separate into - // positive filter and negative filter portions - const char* const p = GTEST_FLAG(filter).c_str(); - const char* const dash = strchr(p, '-'); - std::string positive; - std::string negative; - if (dash == NULL) { - positive = GTEST_FLAG(filter).c_str(); // Whole string is a positive filter - negative = ""; - } else { - positive = std::string(p, dash); // Everything up to the dash - negative = std::string(dash + 1); // Everything after the dash - if (positive.empty()) { - // Treat '-test1' as the same as '*-test1' - positive = kUniversalFilter; - } - } - - // A filter is a colon-separated list of patterns. It matches a - // test if any pattern in it matches the test. - return (MatchesFilter(full_name, positive.c_str()) && - !MatchesFilter(full_name, negative.c_str())); -} - -#if GTEST_HAS_SEH -// Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the -// given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise. -// This function is useful as an __except condition. -int UnitTestOptions::GTestShouldProcessSEH(DWORD exception_code) { - // Google Test should handle a SEH exception if: - // 1. the user wants it to, AND - // 2. this is not a breakpoint exception, AND - // 3. this is not a C++ exception (VC++ implements them via SEH, - // apparently). - // - // SEH exception code for C++ exceptions. - // (see http://support.microsoft.com/kb/185294 for more information). - const DWORD kCxxExceptionCode = 0xe06d7363; - - bool should_handle = true; - - if (!GTEST_FLAG(catch_exceptions)) - should_handle = false; - else if (exception_code == EXCEPTION_BREAKPOINT) - should_handle = false; - else if (exception_code == kCxxExceptionCode) - should_handle = false; - - return should_handle ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH; -} -#endif // GTEST_HAS_SEH - -} // namespace internal - -// The c'tor sets this object as the test part result reporter used by -// Google Test. The 'result' parameter specifies where to report the -// results. Intercepts only failures from the current thread. -ScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter( - TestPartResultArray* result) - : intercept_mode_(INTERCEPT_ONLY_CURRENT_THREAD), - result_(result) { - Init(); -} - -// The c'tor sets this object as the test part result reporter used by -// Google Test. The 'result' parameter specifies where to report the -// results. -ScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter( - InterceptMode intercept_mode, TestPartResultArray* result) - : intercept_mode_(intercept_mode), - result_(result) { - Init(); -} - -void ScopedFakeTestPartResultReporter::Init() { - internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); - if (intercept_mode_ == INTERCEPT_ALL_THREADS) { - old_reporter_ = impl->GetGlobalTestPartResultReporter(); - impl->SetGlobalTestPartResultReporter(this); - } else { - old_reporter_ = impl->GetTestPartResultReporterForCurrentThread(); - impl->SetTestPartResultReporterForCurrentThread(this); - } -} - -// The d'tor restores the test part result reporter used by Google Test -// before. -ScopedFakeTestPartResultReporter::~ScopedFakeTestPartResultReporter() { - internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); - if (intercept_mode_ == INTERCEPT_ALL_THREADS) { - impl->SetGlobalTestPartResultReporter(old_reporter_); - } else { - impl->SetTestPartResultReporterForCurrentThread(old_reporter_); - } -} - -// Increments the test part result count and remembers the result. -// This method is from the TestPartResultReporterInterface interface. -void ScopedFakeTestPartResultReporter::ReportTestPartResult( - const TestPartResult& result) { - result_->Append(result); -} - -namespace internal { - -// Returns the type ID of ::testing::Test. We should always call this -// instead of GetTypeId< ::testing::Test>() to get the type ID of -// testing::Test. This is to work around a suspected linker bug when -// using Google Test as a framework on Mac OS X. The bug causes -// GetTypeId< ::testing::Test>() to return different values depending -// on whether the call is from the Google Test framework itself or -// from user test code. GetTestTypeId() is guaranteed to always -// return the same value, as it always calls GetTypeId<>() from the -// gtest.cc, which is within the Google Test framework. -TypeId GetTestTypeId() { - return GetTypeId(); -} - -// The value of GetTestTypeId() as seen from within the Google Test -// library. This is solely for testing GetTestTypeId(). -extern const TypeId kTestTypeIdInGoogleTest = GetTestTypeId(); - -// This predicate-formatter checks that 'results' contains a test part -// failure of the given type and that the failure message contains the -// given substring. -AssertionResult HasOneFailure(const char* /* results_expr */, - const char* /* type_expr */, - const char* /* substr_expr */, - const TestPartResultArray& results, - TestPartResult::Type type, - const string& substr) { - const std::string expected(type == TestPartResult::kFatalFailure ? - "1 fatal failure" : - "1 non-fatal failure"); - Message msg; - if (results.size() != 1) { - msg << "Expected: " << expected << "\n" - << " Actual: " << results.size() << " failures"; - for (int i = 0; i < results.size(); i++) { - msg << "\n" << results.GetTestPartResult(i); - } - return AssertionFailure() << msg; - } - - const TestPartResult& r = results.GetTestPartResult(0); - if (r.type() != type) { - return AssertionFailure() << "Expected: " << expected << "\n" - << " Actual:\n" - << r; - } - - if (strstr(r.message(), substr.c_str()) == NULL) { - return AssertionFailure() << "Expected: " << expected << " containing \"" - << substr << "\"\n" - << " Actual:\n" - << r; - } - - return AssertionSuccess(); -} - -// The constructor of SingleFailureChecker remembers where to look up -// test part results, what type of failure we expect, and what -// substring the failure message should contain. -SingleFailureChecker:: SingleFailureChecker( - const TestPartResultArray* results, - TestPartResult::Type type, - const string& substr) - : results_(results), - type_(type), - substr_(substr) {} - -// The destructor of SingleFailureChecker verifies that the given -// TestPartResultArray contains exactly one failure that has the given -// type and contains the given substring. If that's not the case, a -// non-fatal failure will be generated. -SingleFailureChecker::~SingleFailureChecker() { - EXPECT_PRED_FORMAT3(HasOneFailure, *results_, type_, substr_); -} - -DefaultGlobalTestPartResultReporter::DefaultGlobalTestPartResultReporter( - UnitTestImpl* unit_test) : unit_test_(unit_test) {} - -void DefaultGlobalTestPartResultReporter::ReportTestPartResult( - const TestPartResult& result) { - unit_test_->current_test_result()->AddTestPartResult(result); - unit_test_->listeners()->repeater()->OnTestPartResult(result); -} - -DefaultPerThreadTestPartResultReporter::DefaultPerThreadTestPartResultReporter( - UnitTestImpl* unit_test) : unit_test_(unit_test) {} - -void DefaultPerThreadTestPartResultReporter::ReportTestPartResult( - const TestPartResult& result) { - unit_test_->GetGlobalTestPartResultReporter()->ReportTestPartResult(result); -} - -// Returns the global test part result reporter. -TestPartResultReporterInterface* -UnitTestImpl::GetGlobalTestPartResultReporter() { - internal::MutexLock lock(&global_test_part_result_reporter_mutex_); - return global_test_part_result_repoter_; -} - -// Sets the global test part result reporter. -void UnitTestImpl::SetGlobalTestPartResultReporter( - TestPartResultReporterInterface* reporter) { - internal::MutexLock lock(&global_test_part_result_reporter_mutex_); - global_test_part_result_repoter_ = reporter; -} - -// Returns the test part result reporter for the current thread. -TestPartResultReporterInterface* -UnitTestImpl::GetTestPartResultReporterForCurrentThread() { - return per_thread_test_part_result_reporter_.get(); -} - -// Sets the test part result reporter for the current thread. -void UnitTestImpl::SetTestPartResultReporterForCurrentThread( - TestPartResultReporterInterface* reporter) { - per_thread_test_part_result_reporter_.set(reporter); -} - -// Gets the number of successful test cases. -int UnitTestImpl::successful_test_case_count() const { - return CountIf(test_cases_, TestCasePassed); -} - -// Gets the number of failed test cases. -int UnitTestImpl::failed_test_case_count() const { - return CountIf(test_cases_, TestCaseFailed); -} - -// Gets the number of all test cases. -int UnitTestImpl::total_test_case_count() const { - return static_cast(test_cases_.size()); -} - -// Gets the number of all test cases that contain at least one test -// that should run. -int UnitTestImpl::test_case_to_run_count() const { - return CountIf(test_cases_, ShouldRunTestCase); -} - -// Gets the number of successful tests. -int UnitTestImpl::successful_test_count() const { - return SumOverTestCaseList(test_cases_, &TestCase::successful_test_count); -} - -// Gets the number of failed tests. -int UnitTestImpl::failed_test_count() const { - return SumOverTestCaseList(test_cases_, &TestCase::failed_test_count); -} - -// Gets the number of disabled tests that will be reported in the XML report. -int UnitTestImpl::reportable_disabled_test_count() const { - return SumOverTestCaseList(test_cases_, - &TestCase::reportable_disabled_test_count); -} - -// Gets the number of disabled tests. -int UnitTestImpl::disabled_test_count() const { - return SumOverTestCaseList(test_cases_, &TestCase::disabled_test_count); -} - -// Gets the number of tests to be printed in the XML report. -int UnitTestImpl::reportable_test_count() const { - return SumOverTestCaseList(test_cases_, &TestCase::reportable_test_count); -} - -// Gets the number of all tests. -int UnitTestImpl::total_test_count() const { - return SumOverTestCaseList(test_cases_, &TestCase::total_test_count); -} - -// Gets the number of tests that should run. -int UnitTestImpl::test_to_run_count() const { - return SumOverTestCaseList(test_cases_, &TestCase::test_to_run_count); -} - -// Returns the current OS stack trace as an std::string. -// -// The maximum number of stack frames to be included is specified by -// the gtest_stack_trace_depth flag. The skip_count parameter -// specifies the number of top frames to be skipped, which doesn't -// count against the number of frames to be included. -// -// For example, if Foo() calls Bar(), which in turn calls -// CurrentOsStackTraceExceptTop(1), Foo() will be included in the -// trace but Bar() and CurrentOsStackTraceExceptTop() won't. -std::string UnitTestImpl::CurrentOsStackTraceExceptTop(int skip_count) { - (void)skip_count; - return ""; -} - -// Returns the current time in milliseconds. -TimeInMillis GetTimeInMillis() { -#if GTEST_OS_WINDOWS_MOBILE || defined(__BORLANDC__) - // Difference between 1970-01-01 and 1601-01-01 in milliseconds. - // http://analogous.blogspot.com/2005/04/epoch.html - const TimeInMillis kJavaEpochToWinFileTimeDelta = - static_cast(116444736UL) * 100000UL; - const DWORD kTenthMicrosInMilliSecond = 10000; - - SYSTEMTIME now_systime; - FILETIME now_filetime; - ULARGE_INTEGER now_int64; - // TODO(kenton@google.com): Shouldn't this just use - // GetSystemTimeAsFileTime()? - GetSystemTime(&now_systime); - if (SystemTimeToFileTime(&now_systime, &now_filetime)) { - now_int64.LowPart = now_filetime.dwLowDateTime; - now_int64.HighPart = now_filetime.dwHighDateTime; - now_int64.QuadPart = (now_int64.QuadPart / kTenthMicrosInMilliSecond) - - kJavaEpochToWinFileTimeDelta; - return now_int64.QuadPart; - } - return 0; -#elif GTEST_OS_WINDOWS && !GTEST_HAS_GETTIMEOFDAY_ - __timeb64 now; - -# ifdef _MSC_VER - - // MSVC 8 deprecates _ftime64(), so we want to suppress warning 4996 - // (deprecated function) there. - // TODO(kenton@google.com): Use GetTickCount()? Or use - // SystemTimeToFileTime() -# pragma warning(push) // Saves the current warning state. -# pragma warning(disable:4996) // Temporarily disables warning 4996. - _ftime64(&now); -# pragma warning(pop) // Restores the warning state. -# else - - _ftime64(&now); - -# endif // _MSC_VER - - return static_cast(now.time) * 1000 + now.millitm; -#elif GTEST_HAS_GETTIMEOFDAY_ - struct timeval now; - gettimeofday(&now, NULL); - return static_cast(now.tv_sec) * 1000 + now.tv_usec / 1000; -#else -# error "Don't know how to get the current time on your system." -#endif -} - -// Utilities - -// class String. - -#if GTEST_OS_WINDOWS_MOBILE -// Creates a UTF-16 wide string from the given ANSI string, allocating -// memory using new. The caller is responsible for deleting the return -// value using delete[]. Returns the wide string, or NULL if the -// input is NULL. -LPCWSTR String::AnsiToUtf16(const char* ansi) { - if (!ansi) return NULL; - const int length = strlen(ansi); - const int unicode_length = - MultiByteToWideChar(CP_ACP, 0, ansi, length, - NULL, 0); - WCHAR* unicode = new WCHAR[unicode_length + 1]; - MultiByteToWideChar(CP_ACP, 0, ansi, length, - unicode, unicode_length); - unicode[unicode_length] = 0; - return unicode; -} - -// Creates an ANSI string from the given wide string, allocating -// memory using new. The caller is responsible for deleting the return -// value using delete[]. Returns the ANSI string, or NULL if the -// input is NULL. -const char* String::Utf16ToAnsi(LPCWSTR utf16_str) { - if (!utf16_str) return NULL; - const int ansi_length = - WideCharToMultiByte(CP_ACP, 0, utf16_str, -1, - NULL, 0, NULL, NULL); - char* ansi = new char[ansi_length + 1]; - WideCharToMultiByte(CP_ACP, 0, utf16_str, -1, - ansi, ansi_length, NULL, NULL); - ansi[ansi_length] = 0; - return ansi; -} - -#endif // GTEST_OS_WINDOWS_MOBILE - -// Compares two C strings. Returns true iff they have the same content. -// -// Unlike strcmp(), this function can handle NULL argument(s). A NULL -// C string is considered different to any non-NULL C string, -// including the empty string. -bool String::CStringEquals(const char * lhs, const char * rhs) { - if ( lhs == NULL ) return rhs == NULL; - - if ( rhs == NULL ) return false; - - return strcmp(lhs, rhs) == 0; -} - -#if GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING - -// Converts an array of wide chars to a narrow string using the UTF-8 -// encoding, and streams the result to the given Message object. -static void StreamWideCharsToMessage(const wchar_t* wstr, size_t length, - Message* msg) { - for (size_t i = 0; i != length; ) { // NOLINT - if (wstr[i] != L'\0') { - *msg << WideStringToUtf8(wstr + i, static_cast(length - i)); - while (i != length && wstr[i] != L'\0') - i++; - } else { - *msg << '\0'; - i++; - } - } -} - -#endif // GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING - -} // namespace internal - -// Constructs an empty Message. -// We allocate the stringstream separately because otherwise each use of -// ASSERT/EXPECT in a procedure adds over 200 bytes to the procedure's -// stack frame leading to huge stack frames in some cases; gcc does not reuse -// the stack space. -Message::Message() : ss_(new ::std::stringstream) { - // By default, we want there to be enough precision when printing - // a double to a Message. - *ss_ << std::setprecision(std::numeric_limits::digits10 + 2); -} - -// These two overloads allow streaming a wide C string to a Message -// using the UTF-8 encoding. -Message& Message::operator <<(const wchar_t* wide_c_str) { - return *this << internal::String::ShowWideCString(wide_c_str); -} -Message& Message::operator <<(wchar_t* wide_c_str) { - return *this << internal::String::ShowWideCString(wide_c_str); -} - -#if GTEST_HAS_STD_WSTRING -// Converts the given wide string to a narrow string using the UTF-8 -// encoding, and streams the result to this Message object. -Message& Message::operator <<(const ::std::wstring& wstr) { - internal::StreamWideCharsToMessage(wstr.c_str(), wstr.length(), this); - return *this; -} -#endif // GTEST_HAS_STD_WSTRING - -#if GTEST_HAS_GLOBAL_WSTRING -// Converts the given wide string to a narrow string using the UTF-8 -// encoding, and streams the result to this Message object. -Message& Message::operator <<(const ::wstring& wstr) { - internal::StreamWideCharsToMessage(wstr.c_str(), wstr.length(), this); - return *this; -} -#endif // GTEST_HAS_GLOBAL_WSTRING - -// Gets the text streamed to this object so far as an std::string. -// Each '\0' character in the buffer is replaced with "\\0". -std::string Message::GetString() const { - return internal::StringStreamToString(ss_.get()); -} - -// AssertionResult constructors. -// Used in EXPECT_TRUE/FALSE(assertion_result). -AssertionResult::AssertionResult(const AssertionResult& other) - : success_(other.success_), - message_(other.message_.get() != NULL ? - new ::std::string(*other.message_) : - static_cast< ::std::string*>(NULL)) { -} - -// Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE. -AssertionResult AssertionResult::operator!() const { - AssertionResult negation(!success_); - if (message_.get() != NULL) - negation << *message_; - return negation; -} - -// Makes a successful assertion result. -AssertionResult AssertionSuccess() { - return AssertionResult(true); -} - -// Makes a failed assertion result. -AssertionResult AssertionFailure() { - return AssertionResult(false); -} - -// Makes a failed assertion result with the given failure message. -// Deprecated; use AssertionFailure() << message. -AssertionResult AssertionFailure(const Message& message) { - return AssertionFailure() << message; -} - -namespace internal { - -// Constructs and returns the message for an equality assertion -// (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure. -// -// The first four parameters are the expressions used in the assertion -// and their values, as strings. For example, for ASSERT_EQ(foo, bar) -// where foo is 5 and bar is 6, we have: -// -// expected_expression: "foo" -// actual_expression: "bar" -// expected_value: "5" -// actual_value: "6" -// -// The ignoring_case parameter is true iff the assertion is a -// *_STRCASEEQ*. When it's true, the string " (ignoring case)" will -// be inserted into the message. -AssertionResult EqFailure(const char* expected_expression, - const char* actual_expression, - const std::string& expected_value, - const std::string& actual_value, - bool ignoring_case) { - Message msg; - msg << "Value of: " << actual_expression; - if (actual_value != actual_expression) { - msg << "\n Actual: " << actual_value; - } - - msg << "\nExpected: " << expected_expression; - if (ignoring_case) { - msg << " (ignoring case)"; - } - if (expected_value != expected_expression) { - msg << "\nWhich is: " << expected_value; - } - - return AssertionFailure() << msg; -} - -// Constructs a failure message for Boolean assertions such as EXPECT_TRUE. -std::string GetBoolAssertionFailureMessage( - const AssertionResult& assertion_result, - const char* expression_text, - const char* actual_predicate_value, - const char* expected_predicate_value) { - const char* actual_message = assertion_result.message(); - Message msg; - msg << "Value of: " << expression_text - << "\n Actual: " << actual_predicate_value; - if (actual_message[0] != '\0') - msg << " (" << actual_message << ")"; - msg << "\nExpected: " << expected_predicate_value; - return msg.GetString(); -} - -// Helper function for implementing ASSERT_NEAR. -AssertionResult DoubleNearPredFormat(const char* expr1, - const char* expr2, - const char* abs_error_expr, - double val1, - double val2, - double abs_error) { - const double diff = fabs(val1 - val2); - if (diff <= abs_error) return AssertionSuccess(); - - // TODO(wan): do not print the value of an expression if it's - // already a literal. - return AssertionFailure() - << "The difference between " << expr1 << " and " << expr2 - << " is " << diff << ", which exceeds " << abs_error_expr << ", where\n" - << expr1 << " evaluates to " << val1 << ",\n" - << expr2 << " evaluates to " << val2 << ", and\n" - << abs_error_expr << " evaluates to " << abs_error << "."; -} - - -// Helper template for implementing FloatLE() and DoubleLE(). -template -AssertionResult FloatingPointLE(const char* expr1, - const char* expr2, - RawType val1, - RawType val2) { - // Returns success if val1 is less than val2, - if (val1 < val2) { - return AssertionSuccess(); - } - - // or if val1 is almost equal to val2. - const FloatingPoint lhs(val1), rhs(val2); - if (lhs.AlmostEquals(rhs)) { - return AssertionSuccess(); - } - - // Note that the above two checks will both fail if either val1 or - // val2 is NaN, as the IEEE floating-point standard requires that - // any predicate involving a NaN must return false. - - ::std::stringstream val1_ss; - val1_ss << std::setprecision(std::numeric_limits::digits10 + 2) - << val1; - - ::std::stringstream val2_ss; - val2_ss << std::setprecision(std::numeric_limits::digits10 + 2) - << val2; - - return AssertionFailure() - << "Expected: (" << expr1 << ") <= (" << expr2 << ")\n" - << " Actual: " << StringStreamToString(&val1_ss) << " vs " - << StringStreamToString(&val2_ss); -} - -} // namespace internal - -// Asserts that val1 is less than, or almost equal to, val2. Fails -// otherwise. In particular, it fails if either val1 or val2 is NaN. -AssertionResult FloatLE(const char* expr1, const char* expr2, - float val1, float val2) { - return internal::FloatingPointLE(expr1, expr2, val1, val2); -} - -// Asserts that val1 is less than, or almost equal to, val2. Fails -// otherwise. In particular, it fails if either val1 or val2 is NaN. -AssertionResult DoubleLE(const char* expr1, const char* expr2, - double val1, double val2) { - return internal::FloatingPointLE(expr1, expr2, val1, val2); -} - -namespace internal { - -// The helper function for {ASSERT|EXPECT}_EQ with int or enum -// arguments. -AssertionResult CmpHelperEQ(const char* expected_expression, - const char* actual_expression, - BiggestInt expected, - BiggestInt actual) { - if (expected == actual) { - return AssertionSuccess(); - } - - return EqFailure(expected_expression, - actual_expression, - FormatForComparisonFailureMessage(expected, actual), - FormatForComparisonFailureMessage(actual, expected), - false); -} - -// A macro for implementing the helper functions needed to implement -// ASSERT_?? and EXPECT_?? with integer or enum arguments. It is here -// just to avoid copy-and-paste of similar code. -#define GTEST_IMPL_CMP_HELPER_(op_name, op)\ -AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \ - BiggestInt val1, BiggestInt val2) {\ - if (val1 op val2) {\ - return AssertionSuccess();\ - } else {\ - return AssertionFailure() \ - << "Expected: (" << expr1 << ") " #op " (" << expr2\ - << "), actual: " << FormatForComparisonFailureMessage(val1, val2)\ - << " vs " << FormatForComparisonFailureMessage(val2, val1);\ - }\ -} - -// Implements the helper function for {ASSERT|EXPECT}_NE with int or -// enum arguments. -GTEST_IMPL_CMP_HELPER_(NE, !=) -// Implements the helper function for {ASSERT|EXPECT}_LE with int or -// enum arguments. -GTEST_IMPL_CMP_HELPER_(LE, <=) -// Implements the helper function for {ASSERT|EXPECT}_LT with int or -// enum arguments. -GTEST_IMPL_CMP_HELPER_(LT, < ) -// Implements the helper function for {ASSERT|EXPECT}_GE with int or -// enum arguments. -GTEST_IMPL_CMP_HELPER_(GE, >=) -// Implements the helper function for {ASSERT|EXPECT}_GT with int or -// enum arguments. -GTEST_IMPL_CMP_HELPER_(GT, > ) - -#undef GTEST_IMPL_CMP_HELPER_ - -// The helper function for {ASSERT|EXPECT}_STREQ. -AssertionResult CmpHelperSTREQ(const char* expected_expression, - const char* actual_expression, - const char* expected, - const char* actual) { - if (String::CStringEquals(expected, actual)) { - return AssertionSuccess(); - } - - return EqFailure(expected_expression, - actual_expression, - PrintToString(expected), - PrintToString(actual), - false); -} - -// The helper function for {ASSERT|EXPECT}_STRCASEEQ. -AssertionResult CmpHelperSTRCASEEQ(const char* expected_expression, - const char* actual_expression, - const char* expected, - const char* actual) { - if (String::CaseInsensitiveCStringEquals(expected, actual)) { - return AssertionSuccess(); - } - - return EqFailure(expected_expression, - actual_expression, - PrintToString(expected), - PrintToString(actual), - true); -} - -// The helper function for {ASSERT|EXPECT}_STRNE. -AssertionResult CmpHelperSTRNE(const char* s1_expression, - const char* s2_expression, - const char* s1, - const char* s2) { - if (!String::CStringEquals(s1, s2)) { - return AssertionSuccess(); - } else { - return AssertionFailure() << "Expected: (" << s1_expression << ") != (" - << s2_expression << "), actual: \"" - << s1 << "\" vs \"" << s2 << "\""; - } -} - -// The helper function for {ASSERT|EXPECT}_STRCASENE. -AssertionResult CmpHelperSTRCASENE(const char* s1_expression, - const char* s2_expression, - const char* s1, - const char* s2) { - if (!String::CaseInsensitiveCStringEquals(s1, s2)) { - return AssertionSuccess(); - } else { - return AssertionFailure() - << "Expected: (" << s1_expression << ") != (" - << s2_expression << ") (ignoring case), actual: \"" - << s1 << "\" vs \"" << s2 << "\""; - } -} - -} // namespace internal - -namespace { - -// Helper functions for implementing IsSubString() and IsNotSubstring(). - -// This group of overloaded functions return true iff needle is a -// substring of haystack. NULL is considered a substring of itself -// only. - -bool IsSubstringPred(const char* needle, const char* haystack) { - if (needle == NULL || haystack == NULL) - return needle == haystack; - - return strstr(haystack, needle) != NULL; -} - -bool IsSubstringPred(const wchar_t* needle, const wchar_t* haystack) { - if (needle == NULL || haystack == NULL) - return needle == haystack; - - return wcsstr(haystack, needle) != NULL; -} - -// StringType here can be either ::std::string or ::std::wstring. -template -bool IsSubstringPred(const StringType& needle, - const StringType& haystack) { - return haystack.find(needle) != StringType::npos; -} - -// This function implements either IsSubstring() or IsNotSubstring(), -// depending on the value of the expected_to_be_substring parameter. -// StringType here can be const char*, const wchar_t*, ::std::string, -// or ::std::wstring. -template -AssertionResult IsSubstringImpl( - bool expected_to_be_substring, - const char* needle_expr, const char* haystack_expr, - const StringType& needle, const StringType& haystack) { - if (IsSubstringPred(needle, haystack) == expected_to_be_substring) - return AssertionSuccess(); - - const bool is_wide_string = sizeof(needle[0]) > 1; - const char* const begin_string_quote = is_wide_string ? "L\"" : "\""; - return AssertionFailure() - << "Value of: " << needle_expr << "\n" - << " Actual: " << begin_string_quote << needle << "\"\n" - << "Expected: " << (expected_to_be_substring ? "" : "not ") - << "a substring of " << haystack_expr << "\n" - << "Which is: " << begin_string_quote << haystack << "\""; -} - -} // namespace - -// IsSubstring() and IsNotSubstring() check whether needle is a -// substring of haystack (NULL is considered a substring of itself -// only), and return an appropriate error message when they fail. - -AssertionResult IsSubstring( - const char* needle_expr, const char* haystack_expr, - const char* needle, const char* haystack) { - return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); -} - -AssertionResult IsSubstring( - const char* needle_expr, const char* haystack_expr, - const wchar_t* needle, const wchar_t* haystack) { - return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); -} - -AssertionResult IsNotSubstring( - const char* needle_expr, const char* haystack_expr, - const char* needle, const char* haystack) { - return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); -} - -AssertionResult IsNotSubstring( - const char* needle_expr, const char* haystack_expr, - const wchar_t* needle, const wchar_t* haystack) { - return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); -} - -AssertionResult IsSubstring( - const char* needle_expr, const char* haystack_expr, - const ::std::string& needle, const ::std::string& haystack) { - return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); -} - -AssertionResult IsNotSubstring( - const char* needle_expr, const char* haystack_expr, - const ::std::string& needle, const ::std::string& haystack) { - return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); -} - -#if GTEST_HAS_STD_WSTRING -AssertionResult IsSubstring( - const char* needle_expr, const char* haystack_expr, - const ::std::wstring& needle, const ::std::wstring& haystack) { - return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); -} - -AssertionResult IsNotSubstring( - const char* needle_expr, const char* haystack_expr, - const ::std::wstring& needle, const ::std::wstring& haystack) { - return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); -} -#endif // GTEST_HAS_STD_WSTRING - -namespace internal { - -#if GTEST_OS_WINDOWS - -namespace { - -// Helper function for IsHRESULT{SuccessFailure} predicates -AssertionResult HRESULTFailureHelper(const char* expr, - const char* expected, - long hr) { // NOLINT -# if GTEST_OS_WINDOWS_MOBILE - - // Windows CE doesn't support FormatMessage. - const char error_text[] = ""; - -# else - - // Looks up the human-readable system message for the HRESULT code - // and since we're not passing any params to FormatMessage, we don't - // want inserts expanded. - const DWORD kFlags = FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS; - const DWORD kBufSize = 4096; - // Gets the system's human readable message string for this HRESULT. - char error_text[kBufSize] = { '\0' }; - DWORD message_length = ::FormatMessageA(kFlags, - 0, // no source, we're asking system - hr, // the error - 0, // no line width restrictions - error_text, // output buffer - kBufSize, // buf size - NULL); // no arguments for inserts - // Trims tailing white space (FormatMessage leaves a trailing CR-LF) - for (; message_length && IsSpace(error_text[message_length - 1]); - --message_length) { - error_text[message_length - 1] = '\0'; - } - -# endif // GTEST_OS_WINDOWS_MOBILE - - const std::string error_hex("0x" + String::FormatHexInt(hr)); - return ::testing::AssertionFailure() - << "Expected: " << expr << " " << expected << ".\n" - << " Actual: " << error_hex << " " << error_text << "\n"; -} - -} // namespace - -AssertionResult IsHRESULTSuccess(const char* expr, long hr) { // NOLINT - if (SUCCEEDED(hr)) { - return AssertionSuccess(); - } - return HRESULTFailureHelper(expr, "succeeds", hr); -} - -AssertionResult IsHRESULTFailure(const char* expr, long hr) { // NOLINT - if (FAILED(hr)) { - return AssertionSuccess(); - } - return HRESULTFailureHelper(expr, "fails", hr); -} - -#endif // GTEST_OS_WINDOWS - -// Utility functions for encoding Unicode text (wide strings) in -// UTF-8. - -// A Unicode code-point can have upto 21 bits, and is encoded in UTF-8 -// like this: -// -// Code-point length Encoding -// 0 - 7 bits 0xxxxxxx -// 8 - 11 bits 110xxxxx 10xxxxxx -// 12 - 16 bits 1110xxxx 10xxxxxx 10xxxxxx -// 17 - 21 bits 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx - -// The maximum code-point a one-byte UTF-8 sequence can represent. -const UInt32 kMaxCodePoint1 = (static_cast(1) << 7) - 1; - -// The maximum code-point a two-byte UTF-8 sequence can represent. -const UInt32 kMaxCodePoint2 = (static_cast(1) << (5 + 6)) - 1; - -// The maximum code-point a three-byte UTF-8 sequence can represent. -const UInt32 kMaxCodePoint3 = (static_cast(1) << (4 + 2*6)) - 1; - -// The maximum code-point a four-byte UTF-8 sequence can represent. -const UInt32 kMaxCodePoint4 = (static_cast(1) << (3 + 3*6)) - 1; - -// Chops off the n lowest bits from a bit pattern. Returns the n -// lowest bits. As a side effect, the original bit pattern will be -// shifted to the right by n bits. -inline UInt32 ChopLowBits(UInt32* bits, int n) { - const UInt32 low_bits = *bits & ((static_cast(1) << n) - 1); - *bits >>= n; - return low_bits; -} - -// Converts a Unicode code point to a narrow string in UTF-8 encoding. -// code_point parameter is of type UInt32 because wchar_t may not be -// wide enough to contain a code point. -// If the code_point is not a valid Unicode code point -// (i.e. outside of Unicode range U+0 to U+10FFFF) it will be converted -// to "(Invalid Unicode 0xXXXXXXXX)". -std::string CodePointToUtf8(UInt32 code_point) { - if (code_point > kMaxCodePoint4) { - return "(Invalid Unicode 0x" + String::FormatHexInt(code_point) + ")"; - } - - char str[5]; // Big enough for the largest valid code point. - if (code_point <= kMaxCodePoint1) { - str[1] = '\0'; - str[0] = static_cast(code_point); // 0xxxxxxx - } else if (code_point <= kMaxCodePoint2) { - str[2] = '\0'; - str[1] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx - str[0] = static_cast(0xC0 | code_point); // 110xxxxx - } else if (code_point <= kMaxCodePoint3) { - str[3] = '\0'; - str[2] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx - str[1] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx - str[0] = static_cast(0xE0 | code_point); // 1110xxxx - } else { // code_point <= kMaxCodePoint4 - str[4] = '\0'; - str[3] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx - str[2] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx - str[1] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx - str[0] = static_cast(0xF0 | code_point); // 11110xxx - } - return str; -} - -// The following two functions only make sense if the the system -// uses UTF-16 for wide string encoding. All supported systems -// with 16 bit wchar_t (Windows, Cygwin, Symbian OS) do use UTF-16. - -// Determines if the arguments constitute UTF-16 surrogate pair -// and thus should be combined into a single Unicode code point -// using CreateCodePointFromUtf16SurrogatePair. -inline bool IsUtf16SurrogatePair(wchar_t first, wchar_t second) { - return sizeof(wchar_t) == 2 && - (first & 0xFC00) == 0xD800 && (second & 0xFC00) == 0xDC00; -} - -// Creates a Unicode code point from UTF16 surrogate pair. -inline UInt32 CreateCodePointFromUtf16SurrogatePair(wchar_t first, - wchar_t second) { - const UInt32 mask = (1 << 10) - 1; - return (sizeof(wchar_t) == 2) ? - (((first & mask) << 10) | (second & mask)) + 0x10000 : - // This function should not be called when the condition is - // false, but we provide a sensible default in case it is. - static_cast(first); -} - -// Converts a wide string to a narrow string in UTF-8 encoding. -// The wide string is assumed to have the following encoding: -// UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin, Symbian OS) -// UTF-32 if sizeof(wchar_t) == 4 (on Linux) -// Parameter str points to a null-terminated wide string. -// Parameter num_chars may additionally limit the number -// of wchar_t characters processed. -1 is used when the entire string -// should be processed. -// If the string contains code points that are not valid Unicode code points -// (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output -// as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding -// and contains invalid UTF-16 surrogate pairs, values in those pairs -// will be encoded as individual Unicode characters from Basic Normal Plane. -std::string WideStringToUtf8(const wchar_t* str, int num_chars) { - if (num_chars == -1) - num_chars = static_cast(wcslen(str)); - - ::std::stringstream stream; - for (int i = 0; i < num_chars; ++i) { - UInt32 unicode_code_point; - - if (str[i] == L'\0') { - break; - } else if (i + 1 < num_chars && IsUtf16SurrogatePair(str[i], str[i + 1])) { - unicode_code_point = CreateCodePointFromUtf16SurrogatePair(str[i], - str[i + 1]); - i++; - } else { - unicode_code_point = static_cast(str[i]); - } - - stream << CodePointToUtf8(unicode_code_point); - } - return StringStreamToString(&stream); -} - -// Converts a wide C string to an std::string using the UTF-8 encoding. -// NULL will be converted to "(null)". -std::string String::ShowWideCString(const wchar_t * wide_c_str) { - if (wide_c_str == NULL) return "(null)"; - - return internal::WideStringToUtf8(wide_c_str, -1); -} - -// Compares two wide C strings. Returns true iff they have the same -// content. -// -// Unlike wcscmp(), this function can handle NULL argument(s). A NULL -// C string is considered different to any non-NULL C string, -// including the empty string. -bool String::WideCStringEquals(const wchar_t * lhs, const wchar_t * rhs) { - if (lhs == NULL) return rhs == NULL; - - if (rhs == NULL) return false; - - return wcscmp(lhs, rhs) == 0; -} - -// Helper function for *_STREQ on wide strings. -AssertionResult CmpHelperSTREQ(const char* expected_expression, - const char* actual_expression, - const wchar_t* expected, - const wchar_t* actual) { - if (String::WideCStringEquals(expected, actual)) { - return AssertionSuccess(); - } - - return EqFailure(expected_expression, - actual_expression, - PrintToString(expected), - PrintToString(actual), - false); -} - -// Helper function for *_STRNE on wide strings. -AssertionResult CmpHelperSTRNE(const char* s1_expression, - const char* s2_expression, - const wchar_t* s1, - const wchar_t* s2) { - if (!String::WideCStringEquals(s1, s2)) { - return AssertionSuccess(); - } - - return AssertionFailure() << "Expected: (" << s1_expression << ") != (" - << s2_expression << "), actual: " - << PrintToString(s1) - << " vs " << PrintToString(s2); -} - -// Compares two C strings, ignoring case. Returns true iff they have -// the same content. -// -// Unlike strcasecmp(), this function can handle NULL argument(s). A -// NULL C string is considered different to any non-NULL C string, -// including the empty string. -bool String::CaseInsensitiveCStringEquals(const char * lhs, const char * rhs) { - if (lhs == NULL) - return rhs == NULL; - if (rhs == NULL) - return false; - return posix::StrCaseCmp(lhs, rhs) == 0; -} - - // Compares two wide C strings, ignoring case. Returns true iff they - // have the same content. - // - // Unlike wcscasecmp(), this function can handle NULL argument(s). - // A NULL C string is considered different to any non-NULL wide C string, - // including the empty string. - // NB: The implementations on different platforms slightly differ. - // On windows, this method uses _wcsicmp which compares according to LC_CTYPE - // environment variable. On GNU platform this method uses wcscasecmp - // which compares according to LC_CTYPE category of the current locale. - // On MacOS X, it uses towlower, which also uses LC_CTYPE category of the - // current locale. -bool String::CaseInsensitiveWideCStringEquals(const wchar_t* lhs, - const wchar_t* rhs) { - if (lhs == NULL) return rhs == NULL; - - if (rhs == NULL) return false; - -#if GTEST_OS_WINDOWS - return _wcsicmp(lhs, rhs) == 0; -#elif GTEST_OS_LINUX && !GTEST_OS_LINUX_ANDROID - return wcscasecmp(lhs, rhs) == 0; -#else - // Android, Mac OS X and Cygwin don't define wcscasecmp. - // Other unknown OSes may not define it either. - wint_t left, right; - do { - left = towlower(*lhs++); - right = towlower(*rhs++); - } while (left && left == right); - return left == right; -#endif // OS selector -} - -// Returns true iff str ends with the given suffix, ignoring case. -// Any string is considered to end with an empty suffix. -bool String::EndsWithCaseInsensitive( - const std::string& str, const std::string& suffix) { - const size_t str_len = str.length(); - const size_t suffix_len = suffix.length(); - return (str_len >= suffix_len) && - CaseInsensitiveCStringEquals(str.c_str() + str_len - suffix_len, - suffix.c_str()); -} - -// Formats an int value as "%02d". -std::string String::FormatIntWidth2(int value) { - std::stringstream ss; - ss << std::setfill('0') << std::setw(2) << value; - return ss.str(); -} - -// Formats an int value as "%X". -std::string String::FormatHexInt(int value) { - std::stringstream ss; - ss << std::hex << std::uppercase << value; - return ss.str(); -} - -// Formats a byte as "%02X". -std::string String::FormatByte(unsigned char value) { - std::stringstream ss; - ss << std::setfill('0') << std::setw(2) << std::hex << std::uppercase - << static_cast(value); - return ss.str(); -} - -// Converts the buffer in a stringstream to an std::string, converting NUL -// bytes to "\\0" along the way. -std::string StringStreamToString(::std::stringstream* ss) { - const ::std::string& str = ss->str(); - const char* const start = str.c_str(); - const char* const end = start + str.length(); - - std::string result; - result.reserve(2 * (end - start)); - for (const char* ch = start; ch != end; ++ch) { - if (*ch == '\0') { - result += "\\0"; // Replaces NUL with "\\0"; - } else { - result += *ch; - } - } - - return result; -} - -// Appends the user-supplied message to the Google-Test-generated message. -std::string AppendUserMessage(const std::string& gtest_msg, - const Message& user_msg) { - // Appends the user message if it's non-empty. - const std::string user_msg_string = user_msg.GetString(); - if (user_msg_string.empty()) { - return gtest_msg; - } - - return gtest_msg + "\n" + user_msg_string; -} - -} // namespace internal - -// class TestResult - -// Creates an empty TestResult. -TestResult::TestResult() - : death_test_count_(0), - elapsed_time_(0) { -} - -// D'tor. -TestResult::~TestResult() { -} - -// Returns the i-th test part result among all the results. i can -// range from 0 to total_part_count() - 1. If i is not in that range, -// aborts the program. -const TestPartResult& TestResult::GetTestPartResult(int i) const { - if (i < 0 || i >= total_part_count()) - internal::posix::Abort(); - return test_part_results_.at(i); -} - -// Returns the i-th test property. i can range from 0 to -// test_property_count() - 1. If i is not in that range, aborts the -// program. -const TestProperty& TestResult::GetTestProperty(int i) const { - if (i < 0 || i >= test_property_count()) - internal::posix::Abort(); - return test_properties_.at(i); -} - -// Clears the test part results. -void TestResult::ClearTestPartResults() { - test_part_results_.clear(); -} - -// Adds a test part result to the list. -void TestResult::AddTestPartResult(const TestPartResult& test_part_result) { - test_part_results_.push_back(test_part_result); -} - -// Adds a test property to the list. If a property with the same key as the -// supplied property is already represented, the value of this test_property -// replaces the old value for that key. -void TestResult::RecordProperty(const std::string& xml_element, - const TestProperty& test_property) { - if (!ValidateTestProperty(xml_element, test_property)) { - return; - } - internal::MutexLock lock(&test_properites_mutex_); - const std::vector::iterator property_with_matching_key = - std::find_if(test_properties_.begin(), test_properties_.end(), - internal::TestPropertyKeyIs(test_property.key())); - if (property_with_matching_key == test_properties_.end()) { - test_properties_.push_back(test_property); - return; - } - property_with_matching_key->SetValue(test_property.value()); -} - -// The list of reserved attributes used in the element of XML -// output. -static const char* const kReservedTestSuitesAttributes[] = { - "disabled", - "errors", - "failures", - "name", - "random_seed", - "tests", - "time", - "timestamp" -}; - -// The list of reserved attributes used in the element of XML -// output. -static const char* const kReservedTestSuiteAttributes[] = { - "disabled", - "errors", - "failures", - "name", - "tests", - "time" -}; - -// The list of reserved attributes used in the element of XML output. -static const char* const kReservedTestCaseAttributes[] = { - "classname", - "name", - "status", - "time", - "type_param", - "value_param" -}; - -template -std::vector ArrayAsVector(const char* const (&array)[kSize]) { - return std::vector(array, array + kSize); -} - -static std::vector GetReservedAttributesForElement( - const std::string& xml_element) { - if (xml_element == "testsuites") { - return ArrayAsVector(kReservedTestSuitesAttributes); - } else if (xml_element == "testsuite") { - return ArrayAsVector(kReservedTestSuiteAttributes); - } else if (xml_element == "testcase") { - return ArrayAsVector(kReservedTestCaseAttributes); - } else { - GTEST_CHECK_(false) << "Unrecognized xml_element provided: " << xml_element; - } - // This code is unreachable but some compilers may not realizes that. - return std::vector(); -} - -static std::string FormatWordList(const std::vector& words) { - Message word_list; - for (size_t i = 0; i < words.size(); ++i) { - if (i > 0 && words.size() > 2) { - word_list << ", "; - } - if (i == words.size() - 1) { - word_list << "and "; - } - word_list << "'" << words[i] << "'"; - } - return word_list.GetString(); -} - -bool ValidateTestPropertyName(const std::string& property_name, - const std::vector& reserved_names) { - if (std::find(reserved_names.begin(), reserved_names.end(), property_name) != - reserved_names.end()) { - ADD_FAILURE() << "Reserved key used in RecordProperty(): " << property_name - << " (" << FormatWordList(reserved_names) - << " are reserved by " << GTEST_NAME_ << ")"; - return false; - } - return true; -} - -// Adds a failure if the key is a reserved attribute of the element named -// xml_element. Returns true if the property is valid. -bool TestResult::ValidateTestProperty(const std::string& xml_element, - const TestProperty& test_property) { - return ValidateTestPropertyName(test_property.key(), - GetReservedAttributesForElement(xml_element)); -} - -// Clears the object. -void TestResult::Clear() { - test_part_results_.clear(); - test_properties_.clear(); - death_test_count_ = 0; - elapsed_time_ = 0; -} - -// Returns true iff the test failed. -bool TestResult::Failed() const { - for (int i = 0; i < total_part_count(); ++i) { - if (GetTestPartResult(i).failed()) - return true; - } - return false; -} - -// Returns true iff the test part fatally failed. -static bool TestPartFatallyFailed(const TestPartResult& result) { - return result.fatally_failed(); -} - -// Returns true iff the test fatally failed. -bool TestResult::HasFatalFailure() const { - return CountIf(test_part_results_, TestPartFatallyFailed) > 0; -} - -// Returns true iff the test part non-fatally failed. -static bool TestPartNonfatallyFailed(const TestPartResult& result) { - return result.nonfatally_failed(); -} - -// Returns true iff the test has a non-fatal failure. -bool TestResult::HasNonfatalFailure() const { - return CountIf(test_part_results_, TestPartNonfatallyFailed) > 0; -} - -// Gets the number of all test parts. This is the sum of the number -// of successful test parts and the number of failed test parts. -int TestResult::total_part_count() const { - return static_cast(test_part_results_.size()); -} - -// Returns the number of the test properties. -int TestResult::test_property_count() const { - return static_cast(test_properties_.size()); -} - -// class Test - -// Creates a Test object. - -// The c'tor saves the values of all Google Test flags. -Test::Test() - : gtest_flag_saver_(new internal::GTestFlagSaver) { -} - -// The d'tor restores the values of all Google Test flags. -Test::~Test() { - delete gtest_flag_saver_; -} - -// Sets up the test fixture. -// -// A sub-class may override this. -void Test::SetUp() { -} - -// Tears down the test fixture. -// -// A sub-class may override this. -void Test::TearDown() { -} - -// Allows user supplied key value pairs to be recorded for later output. -void Test::RecordProperty(const std::string& key, const std::string& value) { - UnitTest::GetInstance()->RecordProperty(key, value); -} - -// Allows user supplied key value pairs to be recorded for later output. -void Test::RecordProperty(const std::string& key, int value) { - Message value_message; - value_message << value; - RecordProperty(key, value_message.GetString().c_str()); -} - -namespace internal { - -void ReportFailureInUnknownLocation(TestPartResult::Type result_type, - const std::string& message) { - // This function is a friend of UnitTest and as such has access to - // AddTestPartResult. - UnitTest::GetInstance()->AddTestPartResult( - result_type, - NULL, // No info about the source file where the exception occurred. - -1, // We have no info on which line caused the exception. - message, - ""); // No stack trace, either. -} - -} // namespace internal - -// Google Test requires all tests in the same test case to use the same test -// fixture class. This function checks if the current test has the -// same fixture class as the first test in the current test case. If -// yes, it returns true; otherwise it generates a Google Test failure and -// returns false. -bool Test::HasSameFixtureClass() { - internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); - const TestCase* const test_case = impl->current_test_case(); - - // Info about the first test in the current test case. - const TestInfo* const first_test_info = test_case->test_info_list()[0]; - const internal::TypeId first_fixture_id = first_test_info->fixture_class_id_; - const char* const first_test_name = first_test_info->name(); - - // Info about the current test. - const TestInfo* const this_test_info = impl->current_test_info(); - const internal::TypeId this_fixture_id = this_test_info->fixture_class_id_; - const char* const this_test_name = this_test_info->name(); - - if (this_fixture_id != first_fixture_id) { - // Is the first test defined using TEST? - const bool first_is_TEST = first_fixture_id == internal::GetTestTypeId(); - // Is this test defined using TEST? - const bool this_is_TEST = this_fixture_id == internal::GetTestTypeId(); - - if (first_is_TEST || this_is_TEST) { - // The user mixed TEST and TEST_F in this test case - we'll tell - // him/her how to fix it. - - // Gets the name of the TEST and the name of the TEST_F. Note - // that first_is_TEST and this_is_TEST cannot both be true, as - // the fixture IDs are different for the two tests. - const char* const TEST_name = - first_is_TEST ? first_test_name : this_test_name; - const char* const TEST_F_name = - first_is_TEST ? this_test_name : first_test_name; - - ADD_FAILURE() - << "All tests in the same test case must use the same test fixture\n" - << "class, so mixing TEST_F and TEST in the same test case is\n" - << "illegal. In test case " << this_test_info->test_case_name() - << ",\n" - << "test " << TEST_F_name << " is defined using TEST_F but\n" - << "test " << TEST_name << " is defined using TEST. You probably\n" - << "want to change the TEST to TEST_F or move it to another test\n" - << "case."; - } else { - // The user defined two fixture classes with the same name in - // two namespaces - we'll tell him/her how to fix it. - ADD_FAILURE() - << "All tests in the same test case must use the same test fixture\n" - << "class. However, in test case " - << this_test_info->test_case_name() << ",\n" - << "you defined test " << first_test_name - << " and test " << this_test_name << "\n" - << "using two different test fixture classes. This can happen if\n" - << "the two classes are from different namespaces or translation\n" - << "units and have the same name. You should probably rename one\n" - << "of the classes to put the tests into different test cases."; - } - return false; - } - - return true; -} - -#if GTEST_HAS_SEH - -// Adds an "exception thrown" fatal failure to the current test. This -// function returns its result via an output parameter pointer because VC++ -// prohibits creation of objects with destructors on stack in functions -// using __try (see error C2712). -static std::string* FormatSehExceptionMessage(DWORD exception_code, - const char* location) { - Message message; - message << "SEH exception with code 0x" << std::setbase(16) << - exception_code << std::setbase(10) << " thrown in " << location << "."; - - return new std::string(message.GetString()); -} - -#endif // GTEST_HAS_SEH - -namespace internal { - -#if GTEST_HAS_EXCEPTIONS - -// Adds an "exception thrown" fatal failure to the current test. -static std::string FormatCxxExceptionMessage(const char* description, - const char* location) { - Message message; - if (description != NULL) { - message << "C++ exception with description \"" << description << "\""; - } else { - message << "Unknown C++ exception"; - } - message << " thrown in " << location << "."; - - return message.GetString(); -} - -static std::string PrintTestPartResultToString( - const TestPartResult& test_part_result); - -GoogleTestFailureException::GoogleTestFailureException( - const TestPartResult& failure) - : ::std::runtime_error(PrintTestPartResultToString(failure).c_str()) {} - -#endif // GTEST_HAS_EXCEPTIONS - -// We put these helper functions in the internal namespace as IBM's xlC -// compiler rejects the code if they were declared static. - -// Runs the given method and handles SEH exceptions it throws, when -// SEH is supported; returns the 0-value for type Result in case of an -// SEH exception. (Microsoft compilers cannot handle SEH and C++ -// exceptions in the same function. Therefore, we provide a separate -// wrapper function for handling SEH exceptions.) -template -Result HandleSehExceptionsInMethodIfSupported( - T* object, Result (T::*method)(), const char* location) { -#if GTEST_HAS_SEH - __try { - return (object->*method)(); - } __except (internal::UnitTestOptions::GTestShouldProcessSEH( // NOLINT - GetExceptionCode())) { - // We create the exception message on the heap because VC++ prohibits - // creation of objects with destructors on stack in functions using __try - // (see error C2712). - std::string* exception_message = FormatSehExceptionMessage( - GetExceptionCode(), location); - internal::ReportFailureInUnknownLocation(TestPartResult::kFatalFailure, - *exception_message); - delete exception_message; - return static_cast(0); - } -#else - (void)location; - return (object->*method)(); -#endif // GTEST_HAS_SEH -} - -// Runs the given method and catches and reports C++ and/or SEH-style -// exceptions, if they are supported; returns the 0-value for type -// Result in case of an SEH exception. -template -Result HandleExceptionsInMethodIfSupported( - T* object, Result (T::*method)(), const char* location) { - // NOTE: The user code can affect the way in which Google Test handles - // exceptions by setting GTEST_FLAG(catch_exceptions), but only before - // RUN_ALL_TESTS() starts. It is technically possible to check the flag - // after the exception is caught and either report or re-throw the - // exception based on the flag's value: - // - // try { - // // Perform the test method. - // } catch (...) { - // if (GTEST_FLAG(catch_exceptions)) - // // Report the exception as failure. - // else - // throw; // Re-throws the original exception. - // } - // - // However, the purpose of this flag is to allow the program to drop into - // the debugger when the exception is thrown. On most platforms, once the - // control enters the catch block, the exception origin information is - // lost and the debugger will stop the program at the point of the - // re-throw in this function -- instead of at the point of the original - // throw statement in the code under test. For this reason, we perform - // the check early, sacrificing the ability to affect Google Test's - // exception handling in the method where the exception is thrown. - if (internal::GetUnitTestImpl()->catch_exceptions()) { -#if GTEST_HAS_EXCEPTIONS - try { - return HandleSehExceptionsInMethodIfSupported(object, method, location); - } catch (const internal::GoogleTestFailureException&) { // NOLINT - // This exception type can only be thrown by a failed Google - // Test assertion with the intention of letting another testing - // framework catch it. Therefore we just re-throw it. - throw; - } catch (const std::exception& e) { // NOLINT - internal::ReportFailureInUnknownLocation( - TestPartResult::kFatalFailure, - FormatCxxExceptionMessage(e.what(), location)); - } catch (...) { // NOLINT - internal::ReportFailureInUnknownLocation( - TestPartResult::kFatalFailure, - FormatCxxExceptionMessage(NULL, location)); - } - return static_cast(0); -#else - return HandleSehExceptionsInMethodIfSupported(object, method, location); -#endif // GTEST_HAS_EXCEPTIONS - } else { - return (object->*method)(); - } -} - -} // namespace internal - -// Runs the test and updates the test result. -void Test::Run() { - if (!HasSameFixtureClass()) return; - - internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); - impl->os_stack_trace_getter()->UponLeavingGTest(); - internal::HandleExceptionsInMethodIfSupported(this, &Test::SetUp, "SetUp()"); - // We will run the test only if SetUp() was successful. - if (!HasFatalFailure()) { - impl->os_stack_trace_getter()->UponLeavingGTest(); - internal::HandleExceptionsInMethodIfSupported( - this, &Test::TestBody, "the test body"); - } - - // However, we want to clean up as much as possible. Hence we will - // always call TearDown(), even if SetUp() or the test body has - // failed. - impl->os_stack_trace_getter()->UponLeavingGTest(); - internal::HandleExceptionsInMethodIfSupported( - this, &Test::TearDown, "TearDown()"); -} - -// Returns true iff the current test has a fatal failure. -bool Test::HasFatalFailure() { - return internal::GetUnitTestImpl()->current_test_result()->HasFatalFailure(); -} - -// Returns true iff the current test has a non-fatal failure. -bool Test::HasNonfatalFailure() { - return internal::GetUnitTestImpl()->current_test_result()-> - HasNonfatalFailure(); -} - -// class TestInfo - -// Constructs a TestInfo object. It assumes ownership of the test factory -// object. -TestInfo::TestInfo(const std::string& a_test_case_name, - const std::string& a_name, - const char* a_type_param, - const char* a_value_param, - internal::TypeId fixture_class_id, - internal::TestFactoryBase* factory) - : test_case_name_(a_test_case_name), - name_(a_name), - type_param_(a_type_param ? new std::string(a_type_param) : NULL), - value_param_(a_value_param ? new std::string(a_value_param) : NULL), - fixture_class_id_(fixture_class_id), - should_run_(false), - is_disabled_(false), - matches_filter_(false), - factory_(factory), - result_() {} - -// Destructs a TestInfo object. -TestInfo::~TestInfo() { delete factory_; } - -namespace internal { - -// Creates a new TestInfo object and registers it with Google Test; -// returns the created object. -// -// Arguments: -// -// test_case_name: name of the test case -// name: name of the test -// type_param: the name of the test's type parameter, or NULL if -// this is not a typed or a type-parameterized test. -// value_param: text representation of the test's value parameter, -// or NULL if this is not a value-parameterized test. -// fixture_class_id: ID of the test fixture class -// set_up_tc: pointer to the function that sets up the test case -// tear_down_tc: pointer to the function that tears down the test case -// factory: pointer to the factory that creates a test object. -// The newly created TestInfo instance will assume -// ownership of the factory object. -TestInfo* MakeAndRegisterTestInfo( - const char* test_case_name, - const char* name, - const char* type_param, - const char* value_param, - TypeId fixture_class_id, - SetUpTestCaseFunc set_up_tc, - TearDownTestCaseFunc tear_down_tc, - TestFactoryBase* factory) { - TestInfo* const test_info = - new TestInfo(test_case_name, name, type_param, value_param, - fixture_class_id, factory); - GetUnitTestImpl()->AddTestInfo(set_up_tc, tear_down_tc, test_info); - return test_info; -} - -#if GTEST_HAS_PARAM_TEST -void ReportInvalidTestCaseType(const char* test_case_name, - const char* file, int line) { - Message errors; - errors - << "Attempted redefinition of test case " << test_case_name << ".\n" - << "All tests in the same test case must use the same test fixture\n" - << "class. However, in test case " << test_case_name << ", you tried\n" - << "to define a test using a fixture class different from the one\n" - << "used earlier. This can happen if the two fixture classes are\n" - << "from different namespaces and have the same name. You should\n" - << "probably rename one of the classes to put the tests into different\n" - << "test cases."; - - fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(), - errors.GetString().c_str()); -} -#endif // GTEST_HAS_PARAM_TEST - -} // namespace internal - -namespace { - -// A predicate that checks the test name of a TestInfo against a known -// value. -// -// This is used for implementation of the TestCase class only. We put -// it in the anonymous namespace to prevent polluting the outer -// namespace. -// -// TestNameIs is copyable. - -//Commenting out this class since its not used and wherefor produces warnings -// class TestNameIs { -// public: -// // Constructor. -// // -// // TestNameIs has NO default constructor. -// explicit TestNameIs(const char* name) -// : name_(name) {} -// -// // Returns true iff the test name of test_info matches name_. -// bool operator()(const TestInfo * test_info) const { -// return test_info && test_info->name() == name_; -// } -// -// private: -// std::string name_; -//}; - -} // namespace - -namespace internal { - -// This method expands all parameterized tests registered with macros TEST_P -// and INSTANTIATE_TEST_CASE_P into regular tests and registers those. -// This will be done just once during the program runtime. -void UnitTestImpl::RegisterParameterizedTests() { -#if GTEST_HAS_PARAM_TEST - if (!parameterized_tests_registered_) { - parameterized_test_registry_.RegisterTests(); - parameterized_tests_registered_ = true; - } -#endif -} - -} // namespace internal - -// Creates the test object, runs it, records its result, and then -// deletes it. -void TestInfo::Run() { - if (!should_run_) return; - - // Tells UnitTest where to store test result. - internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); - impl->set_current_test_info(this); - - TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater(); - - // Notifies the unit test event listeners that a test is about to start. - repeater->OnTestStart(*this); - - const TimeInMillis start = internal::GetTimeInMillis(); - - impl->os_stack_trace_getter()->UponLeavingGTest(); - - // Creates the test object. - Test* const test = internal::HandleExceptionsInMethodIfSupported( - factory_, &internal::TestFactoryBase::CreateTest, - "the test fixture's constructor"); - - // Runs the test only if the test object was created and its - // constructor didn't generate a fatal failure. - if ((test != NULL) && !Test::HasFatalFailure()) { - // This doesn't throw as all user code that can throw are wrapped into - // exception handling code. - test->Run(); - } - - // Deletes the test object. - impl->os_stack_trace_getter()->UponLeavingGTest(); - internal::HandleExceptionsInMethodIfSupported( - test, &Test::DeleteSelf_, "the test fixture's destructor"); - - result_.set_elapsed_time(internal::GetTimeInMillis() - start); - - // Notifies the unit test event listener that a test has just finished. - repeater->OnTestEnd(*this); - - // Tells UnitTest to stop associating assertion results to this - // test. - impl->set_current_test_info(NULL); -} - -// class TestCase - -// Gets the number of successful tests in this test case. -int TestCase::successful_test_count() const { - return CountIf(test_info_list_, TestPassed); -} - -// Gets the number of failed tests in this test case. -int TestCase::failed_test_count() const { - return CountIf(test_info_list_, TestFailed); -} - -// Gets the number of disabled tests that will be reported in the XML report. -int TestCase::reportable_disabled_test_count() const { - return CountIf(test_info_list_, TestReportableDisabled); -} - -// Gets the number of disabled tests in this test case. -int TestCase::disabled_test_count() const { - return CountIf(test_info_list_, TestDisabled); -} - -// Gets the number of tests to be printed in the XML report. -int TestCase::reportable_test_count() const { - return CountIf(test_info_list_, TestReportable); -} - -// Get the number of tests in this test case that should run. -int TestCase::test_to_run_count() const { - return CountIf(test_info_list_, ShouldRunTest); -} - -// Gets the number of all tests. -int TestCase::total_test_count() const { - return static_cast(test_info_list_.size()); -} - -// Creates a TestCase with the given name. -// -// Arguments: -// -// name: name of the test case -// a_type_param: the name of the test case's type parameter, or NULL if -// this is not a typed or a type-parameterized test case. -// set_up_tc: pointer to the function that sets up the test case -// tear_down_tc: pointer to the function that tears down the test case -TestCase::TestCase(const char* a_name, const char* a_type_param, - Test::SetUpTestCaseFunc set_up_tc, - Test::TearDownTestCaseFunc tear_down_tc) - : name_(a_name), - type_param_(a_type_param ? new std::string(a_type_param) : NULL), - set_up_tc_(set_up_tc), - tear_down_tc_(tear_down_tc), - should_run_(false), - elapsed_time_(0) { -} - -// Destructor of TestCase. -TestCase::~TestCase() { - // Deletes every Test in the collection. - ForEach(test_info_list_, internal::Delete); -} - -// Returns the i-th test among all the tests. i can range from 0 to -// total_test_count() - 1. If i is not in that range, returns NULL. -const TestInfo* TestCase::GetTestInfo(int i) const { - const int index = GetElementOr(test_indices_, i, -1); - return index < 0 ? NULL : test_info_list_[index]; -} - -// Returns the i-th test among all the tests. i can range from 0 to -// total_test_count() - 1. If i is not in that range, returns NULL. -TestInfo* TestCase::GetMutableTestInfo(int i) { - const int index = GetElementOr(test_indices_, i, -1); - return index < 0 ? NULL : test_info_list_[index]; -} - -// Adds a test to this test case. Will delete the test upon -// destruction of the TestCase object. -void TestCase::AddTestInfo(TestInfo * test_info) { - test_info_list_.push_back(test_info); - test_indices_.push_back(static_cast(test_indices_.size())); -} - -// Runs every test in this TestCase. -void TestCase::Run() { - if (!should_run_) return; - - internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); - impl->set_current_test_case(this); - - TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater(); - - repeater->OnTestCaseStart(*this); - impl->os_stack_trace_getter()->UponLeavingGTest(); - internal::HandleExceptionsInMethodIfSupported( - this, &TestCase::RunSetUpTestCase, "SetUpTestCase()"); - - const internal::TimeInMillis start = internal::GetTimeInMillis(); - for (int i = 0; i < total_test_count(); i++) { - GetMutableTestInfo(i)->Run(); - } - elapsed_time_ = internal::GetTimeInMillis() - start; - - impl->os_stack_trace_getter()->UponLeavingGTest(); - internal::HandleExceptionsInMethodIfSupported( - this, &TestCase::RunTearDownTestCase, "TearDownTestCase()"); - - repeater->OnTestCaseEnd(*this); - impl->set_current_test_case(NULL); -} - -// Clears the results of all tests in this test case. -void TestCase::ClearResult() { - ad_hoc_test_result_.Clear(); - ForEach(test_info_list_, TestInfo::ClearTestResult); -} - -// Shuffles the tests in this test case. -void TestCase::ShuffleTests(internal::Random* random) { - Shuffle(random, &test_indices_); -} - -// Restores the test order to before the first shuffle. -void TestCase::UnshuffleTests() { - for (size_t i = 0; i < test_indices_.size(); i++) { - test_indices_[i] = static_cast(i); - } -} - -// Formats a countable noun. Depending on its quantity, either the -// singular form or the plural form is used. e.g. -// -// FormatCountableNoun(1, "formula", "formuli") returns "1 formula". -// FormatCountableNoun(5, "book", "books") returns "5 books". -static std::string FormatCountableNoun(int count, - const char * singular_form, - const char * plural_form) { - return internal::StreamableToString(count) + " " + - (count == 1 ? singular_form : plural_form); -} - -// Formats the count of tests. -static std::string FormatTestCount(int test_count) { - return FormatCountableNoun(test_count, "test", "tests"); -} - -// Formats the count of test cases. -static std::string FormatTestCaseCount(int test_case_count) { - return FormatCountableNoun(test_case_count, "test case", "test cases"); -} - -// Converts a TestPartResult::Type enum to human-friendly string -// representation. Both kNonFatalFailure and kFatalFailure are translated -// to "Failure", as the user usually doesn't care about the difference -// between the two when viewing the test result. -static const char * TestPartResultTypeToString(TestPartResult::Type type) { - switch (type) { - case TestPartResult::kSuccess: - return "Success"; - - case TestPartResult::kNonFatalFailure: - case TestPartResult::kFatalFailure: -#ifdef _MSC_VER - return "error: "; -#else - return "Failure\n"; -#endif - default: - return "Unknown result type"; - } -} - -namespace internal { - -// Prints a TestPartResult to an std::string. -static std::string PrintTestPartResultToString( - const TestPartResult& test_part_result) { - return (Message() - << internal::FormatFileLocation(test_part_result.file_name(), - test_part_result.line_number()) - << " " << TestPartResultTypeToString(test_part_result.type()) - << test_part_result.message()).GetString(); -} - -// Prints a TestPartResult. -static void PrintTestPartResult(const TestPartResult& test_part_result) { - const std::string& result = - PrintTestPartResultToString(test_part_result); - printf("%s\n", result.c_str()); - fflush(stdout); - // If the test program runs in Visual Studio or a debugger, the - // following statements add the test part result message to the Output - // window such that the user can double-click on it to jump to the - // corresponding source code location; otherwise they do nothing. -#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE - // We don't call OutputDebugString*() on Windows Mobile, as printing - // to stdout is done by OutputDebugString() there already - we don't - // want the same message printed twice. - ::OutputDebugStringA(result.c_str()); - ::OutputDebugStringA("\n"); -#endif -} - -// class PrettyUnitTestResultPrinter - -enum GTestColor { - COLOR_DEFAULT, - COLOR_RED, - COLOR_GREEN, - COLOR_YELLOW -}; - -#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE - -// Returns the character attribute for the given color. -WORD GetColorAttribute(GTestColor color) { - switch (color) { - case COLOR_RED: return FOREGROUND_RED; - case COLOR_GREEN: return FOREGROUND_GREEN; - case COLOR_YELLOW: return FOREGROUND_RED | FOREGROUND_GREEN; - default: return 0; - } -} - -#else - -// Returns the ANSI color code for the given color. COLOR_DEFAULT is -// an invalid input. -const char* GetAnsiColorCode(GTestColor color) { - switch (color) { - case COLOR_RED: return "1"; - case COLOR_GREEN: return "2"; - case COLOR_YELLOW: return "3"; - default: return NULL; - }; -} - -#endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE - -// Returns true iff Google Test should use colors in the output. -bool ShouldUseColor(bool stdout_is_tty) { - const char* const gtest_color = GTEST_FLAG(color).c_str(); - - if (String::CaseInsensitiveCStringEquals(gtest_color, "auto")) { -#if GTEST_OS_WINDOWS - // On Windows the TERM variable is usually not set, but the - // console there does support colors. - return stdout_is_tty; -#else - // On non-Windows platforms, we rely on the TERM variable. - const char* const term = posix::GetEnv("TERM"); - const bool term_supports_color = - String::CStringEquals(term, "xterm") || - String::CStringEquals(term, "xterm-color") || - String::CStringEquals(term, "xterm-256color") || - String::CStringEquals(term, "screen") || - String::CStringEquals(term, "screen-256color") || - String::CStringEquals(term, "linux") || - String::CStringEquals(term, "cygwin"); - return stdout_is_tty && term_supports_color; -#endif // GTEST_OS_WINDOWS - } - - return String::CaseInsensitiveCStringEquals(gtest_color, "yes") || - String::CaseInsensitiveCStringEquals(gtest_color, "true") || - String::CaseInsensitiveCStringEquals(gtest_color, "t") || - String::CStringEquals(gtest_color, "1"); - // We take "yes", "true", "t", and "1" as meaning "yes". If the - // value is neither one of these nor "auto", we treat it as "no" to - // be conservative. -} - -// Helpers for printing colored strings to stdout. Note that on Windows, we -// cannot simply emit special characters and have the terminal change colors. -// This routine must actually emit the characters rather than return a string -// that would be colored when printed, as can be done on Linux. -void ColoredPrintf(GTestColor color, const char* fmt, ...) { - va_list args; - va_start(args, fmt); - -#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS || GTEST_OS_IOS - const bool use_color = false; -#else - static const bool in_color_mode = - ShouldUseColor(posix::IsATTY(posix::FileNo(stdout)) != 0); - const bool use_color = in_color_mode && (color != COLOR_DEFAULT); -#endif // GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS - // The '!= 0' comparison is necessary to satisfy MSVC 7.1. - - if (!use_color) { - vprintf(fmt, args); - va_end(args); - return; - } - -#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE - const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE); - - // Gets the current text color. - CONSOLE_SCREEN_BUFFER_INFO buffer_info; - GetConsoleScreenBufferInfo(stdout_handle, &buffer_info); - const WORD old_color_attrs = buffer_info.wAttributes; - - // We need to flush the stream buffers into the console before each - // SetConsoleTextAttribute call lest it affect the text that is already - // printed but has not yet reached the console. - fflush(stdout); - SetConsoleTextAttribute(stdout_handle, - GetColorAttribute(color) | FOREGROUND_INTENSITY); - vprintf(fmt, args); - - fflush(stdout); - // Restores the text color. - SetConsoleTextAttribute(stdout_handle, old_color_attrs); -#else - printf("\033[0;3%sm", GetAnsiColorCode(color)); - vprintf(fmt, args); - printf("\033[m"); // Resets the terminal to default. -#endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE - va_end(args); -} - -// Text printed in Google Test's text output and --gunit_list_tests -// output to label the type parameter and value parameter for a test. -static const char kTypeParamLabel[] = "TypeParam"; -static const char kValueParamLabel[] = "GetParam()"; - -void PrintFullTestCommentIfPresent(const TestInfo& test_info) { - const char* const type_param = test_info.type_param(); - const char* const value_param = test_info.value_param(); - - if (type_param != NULL || value_param != NULL) { - printf(", where "); - if (type_param != NULL) { - printf("%s = %s", kTypeParamLabel, type_param); - if (value_param != NULL) - printf(" and "); - } - if (value_param != NULL) { - printf("%s = %s", kValueParamLabel, value_param); - } - } -} - -// This class implements the TestEventListener interface. -// -// Class PrettyUnitTestResultPrinter is copyable. -class PrettyUnitTestResultPrinter : public TestEventListener { - public: - PrettyUnitTestResultPrinter() {} - static void PrintTestName(const char * test_case, const char * test) { - printf("%s.%s", test_case, test); - } - - // The following methods override what's in the TestEventListener class. - virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {} - virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration); - virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test); - virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {} - virtual void OnTestCaseStart(const TestCase& test_case); - virtual void OnTestStart(const TestInfo& test_info); - virtual void OnTestPartResult(const TestPartResult& result); - virtual void OnTestEnd(const TestInfo& test_info); - virtual void OnTestCaseEnd(const TestCase& test_case); - virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test); - virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {} - virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration); - virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {} - - private: - static void PrintFailedTests(const UnitTest& unit_test); -}; - - // Fired before each iteration of tests starts. -void PrettyUnitTestResultPrinter::OnTestIterationStart( - const UnitTest& unit_test, int iteration) { - if (GTEST_FLAG(repeat) != 1) - printf("\nRepeating all tests (iteration %d) . . .\n\n", iteration + 1); - - const char* const filter = GTEST_FLAG(filter).c_str(); - - // Prints the filter if it's not *. This reminds the user that some - // tests may be skipped. - if (!String::CStringEquals(filter, kUniversalFilter)) { - ColoredPrintf(COLOR_YELLOW, - "Note: %s filter = %s\n", GTEST_NAME_, filter); - } - - if (internal::ShouldShard(kTestTotalShards, kTestShardIndex, false)) { - const Int32 shard_index = Int32FromEnvOrDie(kTestShardIndex, -1); - ColoredPrintf(COLOR_YELLOW, - "Note: This is test shard %d of %s.\n", - static_cast(shard_index) + 1, - internal::posix::GetEnv(kTestTotalShards)); - } - - if (GTEST_FLAG(shuffle)) { - ColoredPrintf(COLOR_YELLOW, - "Note: Randomizing tests' orders with a seed of %d .\n", - unit_test.random_seed()); - } - - ColoredPrintf(COLOR_GREEN, "[==========] "); - printf("Running %s from %s.\n", - FormatTestCount(unit_test.test_to_run_count()).c_str(), - FormatTestCaseCount(unit_test.test_case_to_run_count()).c_str()); - fflush(stdout); -} - -void PrettyUnitTestResultPrinter::OnEnvironmentsSetUpStart( - const UnitTest& /*unit_test*/) { - ColoredPrintf(COLOR_GREEN, "[----------] "); - printf("Global test environment set-up.\n"); - fflush(stdout); -} - -void PrettyUnitTestResultPrinter::OnTestCaseStart(const TestCase& test_case) { - const std::string counts = - FormatCountableNoun(test_case.test_to_run_count(), "test", "tests"); - ColoredPrintf(COLOR_GREEN, "[----------] "); - printf("%s from %s", counts.c_str(), test_case.name()); - if (test_case.type_param() == NULL) { - printf("\n"); - } else { - printf(", where %s = %s\n", kTypeParamLabel, test_case.type_param()); - } - fflush(stdout); -} - -void PrettyUnitTestResultPrinter::OnTestStart(const TestInfo& test_info) { - ColoredPrintf(COLOR_GREEN, "[ RUN ] "); - PrintTestName(test_info.test_case_name(), test_info.name()); - printf("\n"); - fflush(stdout); -} - -// Called after an assertion failure. -void PrettyUnitTestResultPrinter::OnTestPartResult( - const TestPartResult& result) { - // If the test part succeeded, we don't need to do anything. - if (result.type() == TestPartResult::kSuccess) - return; - - // Print failure message from the assertion (e.g. expected this and got that). - PrintTestPartResult(result); - fflush(stdout); -} - -void PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo& test_info) { - if (test_info.result()->Passed()) { - ColoredPrintf(COLOR_GREEN, "[ OK ] "); - } else { - ColoredPrintf(COLOR_RED, "[ FAILED ] "); - } - PrintTestName(test_info.test_case_name(), test_info.name()); - if (test_info.result()->Failed()) - PrintFullTestCommentIfPresent(test_info); - - if (GTEST_FLAG(print_time)) { - printf(" (%s ms)\n", internal::StreamableToString( - test_info.result()->elapsed_time()).c_str()); - } else { - printf("\n"); - } - fflush(stdout); -} - -void PrettyUnitTestResultPrinter::OnTestCaseEnd(const TestCase& test_case) { - if (!GTEST_FLAG(print_time)) return; - - const std::string counts = - FormatCountableNoun(test_case.test_to_run_count(), "test", "tests"); - ColoredPrintf(COLOR_GREEN, "[----------] "); - printf("%s from %s (%s ms total)\n\n", - counts.c_str(), test_case.name(), - internal::StreamableToString(test_case.elapsed_time()).c_str()); - fflush(stdout); -} - -void PrettyUnitTestResultPrinter::OnEnvironmentsTearDownStart( - const UnitTest& /*unit_test*/) { - ColoredPrintf(COLOR_GREEN, "[----------] "); - printf("Global test environment tear-down\n"); - fflush(stdout); -} - -// Internal helper for printing the list of failed tests. -void PrettyUnitTestResultPrinter::PrintFailedTests(const UnitTest& unit_test) { - const int failed_test_count = unit_test.failed_test_count(); - if (failed_test_count == 0) { - return; - } - - for (int i = 0; i < unit_test.total_test_case_count(); ++i) { - const TestCase& test_case = *unit_test.GetTestCase(i); - if (!test_case.should_run() || (test_case.failed_test_count() == 0)) { - continue; - } - for (int j = 0; j < test_case.total_test_count(); ++j) { - const TestInfo& test_info = *test_case.GetTestInfo(j); - if (!test_info.should_run() || test_info.result()->Passed()) { - continue; - } - ColoredPrintf(COLOR_RED, "[ FAILED ] "); - printf("%s.%s", test_case.name(), test_info.name()); - PrintFullTestCommentIfPresent(test_info); - printf("\n"); - } - } -} - -void PrettyUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, - int /*iteration*/) { - ColoredPrintf(COLOR_GREEN, "[==========] "); - printf("%s from %s ran.", - FormatTestCount(unit_test.test_to_run_count()).c_str(), - FormatTestCaseCount(unit_test.test_case_to_run_count()).c_str()); - if (GTEST_FLAG(print_time)) { - printf(" (%s ms total)", - internal::StreamableToString(unit_test.elapsed_time()).c_str()); - } - printf("\n"); - ColoredPrintf(COLOR_GREEN, "[ PASSED ] "); - printf("%s.\n", FormatTestCount(unit_test.successful_test_count()).c_str()); - - int num_failures = unit_test.failed_test_count(); - if (!unit_test.Passed()) { - const int failed_test_count = unit_test.failed_test_count(); - ColoredPrintf(COLOR_RED, "[ FAILED ] "); - printf("%s, listed below:\n", FormatTestCount(failed_test_count).c_str()); - PrintFailedTests(unit_test); - printf("\n%2d FAILED %s\n", num_failures, - num_failures == 1 ? "TEST" : "TESTS"); - } - - int num_disabled = unit_test.reportable_disabled_test_count(); - if (num_disabled && !GTEST_FLAG(also_run_disabled_tests)) { - if (!num_failures) { - printf("\n"); // Add a spacer if no FAILURE banner is displayed. - } - ColoredPrintf(COLOR_YELLOW, - " YOU HAVE %d DISABLED %s\n\n", - num_disabled, - num_disabled == 1 ? "TEST" : "TESTS"); - } - // Ensure that Google Test output is printed before, e.g., heapchecker output. - fflush(stdout); -} - -// End PrettyUnitTestResultPrinter - -// class TestEventRepeater -// -// This class forwards events to other event listeners. -class TestEventRepeater : public TestEventListener { - public: - TestEventRepeater() : forwarding_enabled_(true) {} - virtual ~TestEventRepeater(); - void Append(TestEventListener *listener); - TestEventListener* Release(TestEventListener* listener); - - // Controls whether events will be forwarded to listeners_. Set to false - // in death test child processes. - bool forwarding_enabled() const { return forwarding_enabled_; } - void set_forwarding_enabled(bool enable) { forwarding_enabled_ = enable; } - - virtual void OnTestProgramStart(const UnitTest& unit_test); - virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration); - virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test); - virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test); - virtual void OnTestCaseStart(const TestCase& test_case); - virtual void OnTestStart(const TestInfo& test_info); - virtual void OnTestPartResult(const TestPartResult& result); - virtual void OnTestEnd(const TestInfo& test_info); - virtual void OnTestCaseEnd(const TestCase& test_case); - virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test); - virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test); - virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration); - virtual void OnTestProgramEnd(const UnitTest& unit_test); - - private: - // Controls whether events will be forwarded to listeners_. Set to false - // in death test child processes. - bool forwarding_enabled_; - // The list of listeners that receive events. - std::vector listeners_; - - GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventRepeater); -}; - -TestEventRepeater::~TestEventRepeater() { - ForEach(listeners_, Delete); -} - -void TestEventRepeater::Append(TestEventListener *listener) { - listeners_.push_back(listener); -} - -// TODO(vladl@google.com): Factor the search functionality into Vector::Find. -TestEventListener* TestEventRepeater::Release(TestEventListener *listener) { - for (size_t i = 0; i < listeners_.size(); ++i) { - if (listeners_[i] == listener) { - listeners_.erase(listeners_.begin() + i); - return listener; - } - } - - return NULL; -} - -// Since most methods are very similar, use macros to reduce boilerplate. -// This defines a member that forwards the call to all listeners. -#define GTEST_REPEATER_METHOD_(Name, Type) \ -void TestEventRepeater::Name(const Type& parameter) { \ - if (forwarding_enabled_) { \ - for (size_t i = 0; i < listeners_.size(); i++) { \ - listeners_[i]->Name(parameter); \ - } \ - } \ -} -// This defines a member that forwards the call to all listeners in reverse -// order. -#define GTEST_REVERSE_REPEATER_METHOD_(Name, Type) \ -void TestEventRepeater::Name(const Type& parameter) { \ - if (forwarding_enabled_) { \ - for (int i = static_cast(listeners_.size()) - 1; i >= 0; i--) { \ - listeners_[i]->Name(parameter); \ - } \ - } \ -} - -GTEST_REPEATER_METHOD_(OnTestProgramStart, UnitTest) -GTEST_REPEATER_METHOD_(OnEnvironmentsSetUpStart, UnitTest) -GTEST_REPEATER_METHOD_(OnTestCaseStart, TestCase) -GTEST_REPEATER_METHOD_(OnTestStart, TestInfo) -GTEST_REPEATER_METHOD_(OnTestPartResult, TestPartResult) -GTEST_REPEATER_METHOD_(OnEnvironmentsTearDownStart, UnitTest) -GTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsSetUpEnd, UnitTest) -GTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsTearDownEnd, UnitTest) -GTEST_REVERSE_REPEATER_METHOD_(OnTestEnd, TestInfo) -GTEST_REVERSE_REPEATER_METHOD_(OnTestCaseEnd, TestCase) -GTEST_REVERSE_REPEATER_METHOD_(OnTestProgramEnd, UnitTest) - -#undef GTEST_REPEATER_METHOD_ -#undef GTEST_REVERSE_REPEATER_METHOD_ - -void TestEventRepeater::OnTestIterationStart(const UnitTest& unit_test, - int iteration) { - if (forwarding_enabled_) { - for (size_t i = 0; i < listeners_.size(); i++) { - listeners_[i]->OnTestIterationStart(unit_test, iteration); - } - } -} - -void TestEventRepeater::OnTestIterationEnd(const UnitTest& unit_test, - int iteration) { - if (forwarding_enabled_) { - for (int i = static_cast(listeners_.size()) - 1; i >= 0; i--) { - listeners_[i]->OnTestIterationEnd(unit_test, iteration); - } - } -} - -// End TestEventRepeater - -// This class generates an XML output file. -class XmlUnitTestResultPrinter : public EmptyTestEventListener { - public: - explicit XmlUnitTestResultPrinter(const char* output_file); - - virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration); - - private: - // Is c a whitespace character that is normalized to a space character - // when it appears in an XML attribute value? - static bool IsNormalizableWhitespace(char c) { - return c == 0x9 || c == 0xA || c == 0xD; - } - - // May c appear in a well-formed XML document? - static bool IsValidXmlCharacter(char c) { - return IsNormalizableWhitespace(c) || c >= 0x20; - } - - // Returns an XML-escaped copy of the input string str. If - // is_attribute is true, the text is meant to appear as an attribute - // value, and normalizable whitespace is preserved by replacing it - // with character references. - static std::string EscapeXml(const std::string& str, bool is_attribute); - - // Returns the given string with all characters invalid in XML removed. - static std::string RemoveInvalidXmlCharacters(const std::string& str); - - // Convenience wrapper around EscapeXml when str is an attribute value. - static std::string EscapeXmlAttribute(const std::string& str) { - return EscapeXml(str, true); - } - - // Convenience wrapper around EscapeXml when str is not an attribute value. - static std::string EscapeXmlText(const char* str) { - return EscapeXml(str, false); - } - - // Verifies that the given attribute belongs to the given element and - // streams the attribute as XML. - static void OutputXmlAttribute(std::ostream* stream, - const std::string& element_name, - const std::string& name, - const std::string& value); - - // Streams an XML CDATA section, escaping invalid CDATA sequences as needed. - static void OutputXmlCDataSection(::std::ostream* stream, const char* data); - - // Streams an XML representation of a TestInfo object. - static void OutputXmlTestInfo(::std::ostream* stream, - const char* test_case_name, - const TestInfo& test_info); - - // Prints an XML representation of a TestCase object - static void PrintXmlTestCase(::std::ostream* stream, - const TestCase& test_case); - - // Prints an XML summary of unit_test to output stream out. - static void PrintXmlUnitTest(::std::ostream* stream, - const UnitTest& unit_test); - - // Produces a string representing the test properties in a result as space - // delimited XML attributes based on the property key="value" pairs. - // When the std::string is not empty, it includes a space at the beginning, - // to delimit this attribute from prior attributes. - static std::string TestPropertiesAsXmlAttributes(const TestResult& result); - - // The output file. - const std::string output_file_; - - GTEST_DISALLOW_COPY_AND_ASSIGN_(XmlUnitTestResultPrinter); -}; - -// Creates a new XmlUnitTestResultPrinter. -XmlUnitTestResultPrinter::XmlUnitTestResultPrinter(const char* output_file) - : output_file_(output_file) { - if (output_file_.c_str() == NULL || output_file_.empty()) { - fprintf(stderr, "XML output file may not be null\n"); - fflush(stderr); - exit(EXIT_FAILURE); - } -} - -// Called after the unit test ends. -void XmlUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, - int /*iteration*/) { - FILE* xmlout = NULL; - FilePath output_file(output_file_); - FilePath output_dir(output_file.RemoveFileName()); - - if (output_dir.CreateDirectoriesRecursively()) { - xmlout = posix::FOpen(output_file_.c_str(), "w"); - } - if (xmlout == NULL) { - // TODO(wan): report the reason of the failure. - // - // We don't do it for now as: - // - // 1. There is no urgent need for it. - // 2. It's a bit involved to make the errno variable thread-safe on - // all three operating systems (Linux, Windows, and Mac OS). - // 3. To interpret the meaning of errno in a thread-safe way, - // we need the strerror_r() function, which is not available on - // Windows. - fprintf(stderr, - "Unable to open file \"%s\"\n", - output_file_.c_str()); - fflush(stderr); - exit(EXIT_FAILURE); - } - std::stringstream stream; - PrintXmlUnitTest(&stream, unit_test); - fprintf(xmlout, "%s", StringStreamToString(&stream).c_str()); - fclose(xmlout); -} - -// Returns an XML-escaped copy of the input string str. If is_attribute -// is true, the text is meant to appear as an attribute value, and -// normalizable whitespace is preserved by replacing it with character -// references. -// -// Invalid XML characters in str, if any, are stripped from the output. -// It is expected that most, if not all, of the text processed by this -// module will consist of ordinary English text. -// If this module is ever modified to produce version 1.1 XML output, -// most invalid characters can be retained using character references. -// TODO(wan): It might be nice to have a minimally invasive, human-readable -// escaping scheme for invalid characters, rather than dropping them. -std::string XmlUnitTestResultPrinter::EscapeXml( - const std::string& str, bool is_attribute) { - Message m; - - for (size_t i = 0; i < str.size(); ++i) { - const char ch = str[i]; - switch (ch) { - case '<': - m << "<"; - break; - case '>': - m << ">"; - break; - case '&': - m << "&"; - break; - case '\'': - if (is_attribute) - m << "'"; - else - m << '\''; - break; - case '"': - if (is_attribute) - m << """; - else - m << '"'; - break; - default: - if (IsValidXmlCharacter(ch)) { - if (is_attribute && IsNormalizableWhitespace(ch)) - m << "&#x" << String::FormatByte(static_cast(ch)) - << ";"; - else - m << ch; - } - break; - } - } - - return m.GetString(); -} - -// Returns the given string with all characters invalid in XML removed. -// Currently invalid characters are dropped from the string. An -// alternative is to replace them with certain characters such as . or ?. -std::string XmlUnitTestResultPrinter::RemoveInvalidXmlCharacters( - const std::string& str) { - std::string output; - output.reserve(str.size()); - for (std::string::const_iterator it = str.begin(); it != str.end(); ++it) - if (IsValidXmlCharacter(*it)) - output.push_back(*it); - - return output; -} - -// The following routines generate an XML representation of a UnitTest -// object. -// -// This is how Google Test concepts map to the DTD: -// -// <-- corresponds to a UnitTest object -// <-- corresponds to a TestCase object -// <-- corresponds to a TestInfo object -// ... -// ... -// ... -// <-- individual assertion failures -// -// -// - -// Formats the given time in milliseconds as seconds. -std::string FormatTimeInMillisAsSeconds(TimeInMillis ms) { - ::std::stringstream ss; - ss << ms/1000.0; - return ss.str(); -} - -// Converts the given epoch time in milliseconds to a date string in the ISO -// 8601 format, without the timezone information. -std::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms) { - // Using non-reentrant version as localtime_r is not portable. - time_t seconds = static_cast(ms / 1000); -#ifdef _MSC_VER -# pragma warning(push) // Saves the current warning state. -# pragma warning(disable:4996) // Temporarily disables warning 4996 - // (function or variable may be unsafe). - const struct tm* const time_struct = localtime(&seconds); // NOLINT -# pragma warning(pop) // Restores the warning state again. -#else - const struct tm* const time_struct = localtime(&seconds); // NOLINT -#endif - if (time_struct == NULL) - return ""; // Invalid ms value - - // YYYY-MM-DDThh:mm:ss - return StreamableToString(time_struct->tm_year + 1900) + "-" + - String::FormatIntWidth2(time_struct->tm_mon + 1) + "-" + - String::FormatIntWidth2(time_struct->tm_mday) + "T" + - String::FormatIntWidth2(time_struct->tm_hour) + ":" + - String::FormatIntWidth2(time_struct->tm_min) + ":" + - String::FormatIntWidth2(time_struct->tm_sec); -} - -// Streams an XML CDATA section, escaping invalid CDATA sequences as needed. -void XmlUnitTestResultPrinter::OutputXmlCDataSection(::std::ostream* stream, - const char* data) { - const char* segment = data; - *stream << ""); - if (next_segment != NULL) { - stream->write( - segment, static_cast(next_segment - segment)); - *stream << "]]>]]>"); - } else { - *stream << segment; - break; - } - } - *stream << "]]>"; -} - -void XmlUnitTestResultPrinter::OutputXmlAttribute( - std::ostream* stream, - const std::string& element_name, - const std::string& name, - const std::string& value) { - const std::vector& allowed_names = - GetReservedAttributesForElement(element_name); - - GTEST_CHECK_(std::find(allowed_names.begin(), allowed_names.end(), name) != - allowed_names.end()) - << "Attribute " << name << " is not allowed for element <" << element_name - << ">."; - - *stream << " " << name << "=\"" << EscapeXmlAttribute(value) << "\""; -} - -// Prints an XML representation of a TestInfo object. -// TODO(wan): There is also value in printing properties with the plain printer. -void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream, - const char* test_case_name, - const TestInfo& test_info) { - const TestResult& result = *test_info.result(); - const std::string kTestcase = "testcase"; - - *stream << " \n"; - } - const string location = internal::FormatCompilerIndependentFileLocation( - part.file_name(), part.line_number()); - const string summary = location + "\n" + part.summary(); - *stream << " "; - const string detail = location + "\n" + part.message(); - OutputXmlCDataSection(stream, RemoveInvalidXmlCharacters(detail).c_str()); - *stream << "\n"; - } - } - - if (failures == 0) - *stream << " />\n"; - else - *stream << " \n"; -} - -// Prints an XML representation of a TestCase object -void XmlUnitTestResultPrinter::PrintXmlTestCase(std::ostream* stream, - const TestCase& test_case) { - const std::string kTestsuite = "testsuite"; - *stream << " <" << kTestsuite; - OutputXmlAttribute(stream, kTestsuite, "name", test_case.name()); - OutputXmlAttribute(stream, kTestsuite, "tests", - StreamableToString(test_case.reportable_test_count())); - OutputXmlAttribute(stream, kTestsuite, "failures", - StreamableToString(test_case.failed_test_count())); - OutputXmlAttribute( - stream, kTestsuite, "disabled", - StreamableToString(test_case.reportable_disabled_test_count())); - OutputXmlAttribute(stream, kTestsuite, "errors", "0"); - OutputXmlAttribute(stream, kTestsuite, "time", - FormatTimeInMillisAsSeconds(test_case.elapsed_time())); - *stream << TestPropertiesAsXmlAttributes(test_case.ad_hoc_test_result()) - << ">\n"; - - for (int i = 0; i < test_case.total_test_count(); ++i) { - if (test_case.GetTestInfo(i)->is_reportable()) - OutputXmlTestInfo(stream, test_case.name(), *test_case.GetTestInfo(i)); - } - *stream << " \n"; -} - -// Prints an XML summary of unit_test to output stream out. -void XmlUnitTestResultPrinter::PrintXmlUnitTest(std::ostream* stream, - const UnitTest& unit_test) { - const std::string kTestsuites = "testsuites"; - - *stream << "\n"; - *stream << "<" << kTestsuites; - - OutputXmlAttribute(stream, kTestsuites, "tests", - StreamableToString(unit_test.reportable_test_count())); - OutputXmlAttribute(stream, kTestsuites, "failures", - StreamableToString(unit_test.failed_test_count())); - OutputXmlAttribute( - stream, kTestsuites, "disabled", - StreamableToString(unit_test.reportable_disabled_test_count())); - OutputXmlAttribute(stream, kTestsuites, "errors", "0"); - OutputXmlAttribute( - stream, kTestsuites, "timestamp", - FormatEpochTimeInMillisAsIso8601(unit_test.start_timestamp())); - OutputXmlAttribute(stream, kTestsuites, "time", - FormatTimeInMillisAsSeconds(unit_test.elapsed_time())); - - if (GTEST_FLAG(shuffle)) { - OutputXmlAttribute(stream, kTestsuites, "random_seed", - StreamableToString(unit_test.random_seed())); - } - - *stream << TestPropertiesAsXmlAttributes(unit_test.ad_hoc_test_result()); - - OutputXmlAttribute(stream, kTestsuites, "name", "AllTests"); - *stream << ">\n"; - - for (int i = 0; i < unit_test.total_test_case_count(); ++i) { - if (unit_test.GetTestCase(i)->reportable_test_count() > 0) - PrintXmlTestCase(stream, *unit_test.GetTestCase(i)); - } - *stream << "\n"; -} - -// Produces a string representing the test properties in a result as space -// delimited XML attributes based on the property key="value" pairs. -std::string XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes( - const TestResult& result) { - Message attributes; - for (int i = 0; i < result.test_property_count(); ++i) { - const TestProperty& property = result.GetTestProperty(i); - attributes << " " << property.key() << "=" - << "\"" << EscapeXmlAttribute(property.value()) << "\""; - } - return attributes.GetString(); -} - -// End XmlUnitTestResultPrinter - -#if GTEST_CAN_STREAM_RESULTS_ - -// Checks if str contains '=', '&', '%' or '\n' characters. If yes, -// replaces them by "%xx" where xx is their hexadecimal value. For -// example, replaces "=" with "%3D". This algorithm is O(strlen(str)) -// in both time and space -- important as the input str may contain an -// arbitrarily long test failure message and stack trace. -string StreamingListener::UrlEncode(const char* str) { - string result; - result.reserve(strlen(str) + 1); - for (char ch = *str; ch != '\0'; ch = *++str) { - switch (ch) { - case '%': - case '=': - case '&': - case '\n': - result.append("%" + String::FormatByte(static_cast(ch))); - break; - default: - result.push_back(ch); - break; - } - } - return result; -} - -void StreamingListener::SocketWriter::MakeConnection() { - GTEST_CHECK_(sockfd_ == -1) - << "MakeConnection() can't be called when there is already a connection."; - - addrinfo hints; - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_UNSPEC; // To allow both IPv4 and IPv6 addresses. - hints.ai_socktype = SOCK_STREAM; - addrinfo* servinfo = NULL; - - // Use the getaddrinfo() to get a linked list of IP addresses for - // the given host name. - const int error_num = getaddrinfo( - host_name_.c_str(), port_num_.c_str(), &hints, &servinfo); - if (error_num != 0) { - GTEST_LOG_(WARNING) << "stream_result_to: getaddrinfo() failed: " - << gai_strerror(error_num); - } - - // Loop through all the results and connect to the first we can. - for (addrinfo* cur_addr = servinfo; sockfd_ == -1 && cur_addr != NULL; - cur_addr = cur_addr->ai_next) { - sockfd_ = socket( - cur_addr->ai_family, cur_addr->ai_socktype, cur_addr->ai_protocol); - if (sockfd_ != -1) { - // Connect the client socket to the server socket. - if (connect(sockfd_, cur_addr->ai_addr, cur_addr->ai_addrlen) == -1) { - close(sockfd_); - sockfd_ = -1; - } - } - } - - freeaddrinfo(servinfo); // all done with this structure - - if (sockfd_ == -1) { - GTEST_LOG_(WARNING) << "stream_result_to: failed to connect to " - << host_name_ << ":" << port_num_; - } -} - -// End of class Streaming Listener -#endif // GTEST_CAN_STREAM_RESULTS__ - -// Class ScopedTrace - -// Pushes the given source file location and message onto a per-thread -// trace stack maintained by Google Test. -ScopedTrace::ScopedTrace(const char* file, int line, const Message& message) - GTEST_LOCK_EXCLUDED_(&UnitTest::mutex_) { - TraceInfo trace; - trace.file = file; - trace.line = line; - trace.message = message.GetString(); - - UnitTest::GetInstance()->PushGTestTrace(trace); -} - -// Pops the info pushed by the c'tor. -ScopedTrace::~ScopedTrace() - GTEST_LOCK_EXCLUDED_(&UnitTest::mutex_) { - UnitTest::GetInstance()->PopGTestTrace(); -} - - -// class OsStackTraceGetter - -// Returns the current OS stack trace as an std::string. Parameters: -// -// max_depth - the maximum number of stack frames to be included -// in the trace. -// skip_count - the number of top frames to be skipped; doesn't count -// against max_depth. -// -string OsStackTraceGetter::CurrentStackTrace(int /* max_depth */, - int /* skip_count */) - GTEST_LOCK_EXCLUDED_(mutex_) { - return ""; -} - -void OsStackTraceGetter::UponLeavingGTest() - GTEST_LOCK_EXCLUDED_(mutex_) { -} - -const char* const -OsStackTraceGetter::kElidedFramesMarker = - "... " GTEST_NAME_ " internal frames ..."; - -// A helper class that creates the premature-exit file in its -// constructor and deletes the file in its destructor. -class ScopedPrematureExitFile { - public: - explicit ScopedPrematureExitFile(const char* premature_exit_filepath) - : premature_exit_filepath_(premature_exit_filepath) { - // If a path to the premature-exit file is specified... - if (premature_exit_filepath != NULL && *premature_exit_filepath != '\0') { - // create the file with a single "0" character in it. I/O - // errors are ignored as there's nothing better we can do and we - // don't want to fail the test because of this. - FILE* pfile = posix::FOpen(premature_exit_filepath, "w"); - fwrite("0", 1, 1, pfile); - fclose(pfile); - } - } - - ~ScopedPrematureExitFile() { - if (premature_exit_filepath_ != NULL && *premature_exit_filepath_ != '\0') { - remove(premature_exit_filepath_); - } - } - - private: - const char* const premature_exit_filepath_; - - GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedPrematureExitFile); -}; - -} // namespace internal - -// class TestEventListeners - -TestEventListeners::TestEventListeners() - : repeater_(new internal::TestEventRepeater()), - default_result_printer_(NULL), - default_xml_generator_(NULL) { -} - -TestEventListeners::~TestEventListeners() { delete repeater_; } - -// Returns the standard listener responsible for the default console -// output. Can be removed from the listeners list to shut down default -// console output. Note that removing this object from the listener list -// with Release transfers its ownership to the user. -void TestEventListeners::Append(TestEventListener* listener) { - repeater_->Append(listener); -} - -// Removes the given event listener from the list and returns it. It then -// becomes the caller's responsibility to delete the listener. Returns -// NULL if the listener is not found in the list. -TestEventListener* TestEventListeners::Release(TestEventListener* listener) { - if (listener == default_result_printer_) - default_result_printer_ = NULL; - else if (listener == default_xml_generator_) - default_xml_generator_ = NULL; - return repeater_->Release(listener); -} - -// Returns repeater that broadcasts the TestEventListener events to all -// subscribers. -TestEventListener* TestEventListeners::repeater() { return repeater_; } - -// Sets the default_result_printer attribute to the provided listener. -// The listener is also added to the listener list and previous -// default_result_printer is removed from it and deleted. The listener can -// also be NULL in which case it will not be added to the list. Does -// nothing if the previous and the current listener objects are the same. -void TestEventListeners::SetDefaultResultPrinter(TestEventListener* listener) { - if (default_result_printer_ != listener) { - // It is an error to pass this method a listener that is already in the - // list. - delete Release(default_result_printer_); - default_result_printer_ = listener; - if (listener != NULL) - Append(listener); - } -} - -// Sets the default_xml_generator attribute to the provided listener. The -// listener is also added to the listener list and previous -// default_xml_generator is removed from it and deleted. The listener can -// also be NULL in which case it will not be added to the list. Does -// nothing if the previous and the current listener objects are the same. -void TestEventListeners::SetDefaultXmlGenerator(TestEventListener* listener) { - if (default_xml_generator_ != listener) { - // It is an error to pass this method a listener that is already in the - // list. - delete Release(default_xml_generator_); - default_xml_generator_ = listener; - if (listener != NULL) - Append(listener); - } -} - -// Controls whether events will be forwarded by the repeater to the -// listeners in the list. -bool TestEventListeners::EventForwardingEnabled() const { - return repeater_->forwarding_enabled(); -} - -void TestEventListeners::SuppressEventForwarding() { - repeater_->set_forwarding_enabled(false); -} - -// class UnitTest - -// Gets the singleton UnitTest object. The first time this method is -// called, a UnitTest object is constructed and returned. Consecutive -// calls will return the same object. -// -// We don't protect this under mutex_ as a user is not supposed to -// call this before main() starts, from which point on the return -// value will never change. -UnitTest* UnitTest::GetInstance() { - // When compiled with MSVC 7.1 in optimized mode, destroying the - // UnitTest object upon exiting the program messes up the exit code, - // causing successful tests to appear failed. We have to use a - // different implementation in this case to bypass the compiler bug. - // This implementation makes the compiler happy, at the cost of - // leaking the UnitTest object. - - // CodeGear C++Builder insists on a public destructor for the - // default implementation. Use this implementation to keep good OO - // design with private destructor. - -#if (_MSC_VER == 1310 && !defined(_DEBUG)) || defined(__BORLANDC__) - static UnitTest* const instance = new UnitTest; - return instance; -#else - static UnitTest instance; - return &instance; -#endif // (_MSC_VER == 1310 && !defined(_DEBUG)) || defined(__BORLANDC__) -} - -// Gets the number of successful test cases. -int UnitTest::successful_test_case_count() const { - return impl()->successful_test_case_count(); -} - -// Gets the number of failed test cases. -int UnitTest::failed_test_case_count() const { - return impl()->failed_test_case_count(); -} - -// Gets the number of all test cases. -int UnitTest::total_test_case_count() const { - return impl()->total_test_case_count(); -} - -// Gets the number of all test cases that contain at least one test -// that should run. -int UnitTest::test_case_to_run_count() const { - return impl()->test_case_to_run_count(); -} - -// Gets the number of successful tests. -int UnitTest::successful_test_count() const { - return impl()->successful_test_count(); -} - -// Gets the number of failed tests. -int UnitTest::failed_test_count() const { return impl()->failed_test_count(); } - -// Gets the number of disabled tests that will be reported in the XML report. -int UnitTest::reportable_disabled_test_count() const { - return impl()->reportable_disabled_test_count(); -} - -// Gets the number of disabled tests. -int UnitTest::disabled_test_count() const { - return impl()->disabled_test_count(); -} - -// Gets the number of tests to be printed in the XML report. -int UnitTest::reportable_test_count() const { - return impl()->reportable_test_count(); -} - -// Gets the number of all tests. -int UnitTest::total_test_count() const { return impl()->total_test_count(); } - -// Gets the number of tests that should run. -int UnitTest::test_to_run_count() const { return impl()->test_to_run_count(); } - -// Gets the time of the test program start, in ms from the start of the -// UNIX epoch. -internal::TimeInMillis UnitTest::start_timestamp() const { - return impl()->start_timestamp(); -} - -// Gets the elapsed time, in milliseconds. -internal::TimeInMillis UnitTest::elapsed_time() const { - return impl()->elapsed_time(); -} - -// Returns true iff the unit test passed (i.e. all test cases passed). -bool UnitTest::Passed() const { return impl()->Passed(); } - -// Returns true iff the unit test failed (i.e. some test case failed -// or something outside of all tests failed). -bool UnitTest::Failed() const { return impl()->Failed(); } - -// Gets the i-th test case among all the test cases. i can range from 0 to -// total_test_case_count() - 1. If i is not in that range, returns NULL. -const TestCase* UnitTest::GetTestCase(int i) const { - return impl()->GetTestCase(i); -} - -// Returns the TestResult containing information on test failures and -// properties logged outside of individual test cases. -const TestResult& UnitTest::ad_hoc_test_result() const { - return *impl()->ad_hoc_test_result(); -} - -// Gets the i-th test case among all the test cases. i can range from 0 to -// total_test_case_count() - 1. If i is not in that range, returns NULL. -TestCase* UnitTest::GetMutableTestCase(int i) { - return impl()->GetMutableTestCase(i); -} - -// Returns the list of event listeners that can be used to track events -// inside Google Test. -TestEventListeners& UnitTest::listeners() { - return *impl()->listeners(); -} - -// Registers and returns a global test environment. When a test -// program is run, all global test environments will be set-up in the -// order they were registered. After all tests in the program have -// finished, all global test environments will be torn-down in the -// *reverse* order they were registered. -// -// The UnitTest object takes ownership of the given environment. -// -// We don't protect this under mutex_, as we only support calling it -// from the main thread. -Environment* UnitTest::AddEnvironment(Environment* env) { - if (env == NULL) { - return NULL; - } - - impl_->environments().push_back(env); - return env; -} - -// Adds a TestPartResult to the current TestResult object. All Google Test -// assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) eventually call -// this to report their results. The user code should use the -// assertion macros instead of calling this directly. -void UnitTest::AddTestPartResult( - TestPartResult::Type result_type, - const char* file_name, - int line_number, - const std::string& message, - const std::string& os_stack_trace) GTEST_LOCK_EXCLUDED_(mutex_) { - Message msg; - msg << message; - - internal::MutexLock lock(&mutex_); - if (impl_->gtest_trace_stack().size() > 0) { - msg << "\n" << GTEST_NAME_ << " trace:"; - - for (int i = static_cast(impl_->gtest_trace_stack().size()); - i > 0; --i) { - const internal::TraceInfo& trace = impl_->gtest_trace_stack()[i - 1]; - msg << "\n" << internal::FormatFileLocation(trace.file, trace.line) - << " " << trace.message; - } - } - - if (os_stack_trace.c_str() != NULL && !os_stack_trace.empty()) { - msg << internal::kStackTraceMarker << os_stack_trace; - } - - const TestPartResult result = - TestPartResult(result_type, file_name, line_number, - msg.GetString().c_str()); - impl_->GetTestPartResultReporterForCurrentThread()-> - ReportTestPartResult(result); - - if (result_type != TestPartResult::kSuccess) { - // gtest_break_on_failure takes precedence over - // gtest_throw_on_failure. This allows a user to set the latter - // in the code (perhaps in order to use Google Test assertions - // with another testing framework) and specify the former on the - // command line for debugging. - if (GTEST_FLAG(break_on_failure)) { -#if GTEST_OS_WINDOWS - // Using DebugBreak on Windows allows gtest to still break into a debugger - // when a failure happens and both the --gtest_break_on_failure and - // the --gtest_catch_exceptions flags are specified. - DebugBreak(); -#else - // Dereference NULL through a volatile pointer to prevent the compiler - // from removing. We use this rather than abort() or __builtin_trap() for - // portability: Symbian doesn't implement abort() well, and some debuggers - // don't correctly trap abort(). - *static_cast(NULL) = 1; -#endif // GTEST_OS_WINDOWS - } else if (GTEST_FLAG(throw_on_failure)) { -#if GTEST_HAS_EXCEPTIONS - throw internal::GoogleTestFailureException(result); -#else - // We cannot call abort() as it generates a pop-up in debug mode - // that cannot be suppressed in VC 7.1 or below. - exit(1); -#endif - } - } -} - -// Adds a TestProperty to the current TestResult object when invoked from -// inside a test, to current TestCase's ad_hoc_test_result_ when invoked -// from SetUpTestCase or TearDownTestCase, or to the global property set -// when invoked elsewhere. If the result already contains a property with -// the same key, the value will be updated. -void UnitTest::RecordProperty(const std::string& key, - const std::string& value) { - impl_->RecordProperty(TestProperty(key, value)); -} - -// Runs all tests in this UnitTest object and prints the result. -// Returns 0 if successful, or 1 otherwise. -// -// We don't protect this under mutex_, as we only support calling it -// from the main thread. -int UnitTest::Run() { - const bool in_death_test_child_process = - internal::GTEST_FLAG(internal_run_death_test).length() > 0; - - // Google Test implements this protocol for catching that a test - // program exits before returning control to Google Test: - // - // 1. Upon start, Google Test creates a file whose absolute path - // is specified by the environment variable - // TEST_PREMATURE_EXIT_FILE. - // 2. When Google Test has finished its work, it deletes the file. - // - // This allows a test runner to set TEST_PREMATURE_EXIT_FILE before - // running a Google-Test-based test program and check the existence - // of the file at the end of the test execution to see if it has - // exited prematurely. - - // If we are in the child process of a death test, don't - // create/delete the premature exit file, as doing so is unnecessary - // and will confuse the parent process. Otherwise, create/delete - // the file upon entering/leaving this function. If the program - // somehow exits before this function has a chance to return, the - // premature-exit file will be left undeleted, causing a test runner - // that understands the premature-exit-file protocol to report the - // test as having failed. - const internal::ScopedPrematureExitFile premature_exit_file( - in_death_test_child_process ? - NULL : internal::posix::GetEnv("TEST_PREMATURE_EXIT_FILE")); - - // Captures the value of GTEST_FLAG(catch_exceptions). This value will be - // used for the duration of the program. - impl()->set_catch_exceptions(GTEST_FLAG(catch_exceptions)); - -#if GTEST_HAS_SEH - // Either the user wants Google Test to catch exceptions thrown by the - // tests or this is executing in the context of death test child - // process. In either case the user does not want to see pop-up dialogs - // about crashes - they are expected. - if (impl()->catch_exceptions() || in_death_test_child_process) { -# if !GTEST_OS_WINDOWS_MOBILE - // SetErrorMode doesn't exist on CE. - SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT | - SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX); -# endif // !GTEST_OS_WINDOWS_MOBILE - -# if (defined(_MSC_VER) || GTEST_OS_WINDOWS_MINGW) && !GTEST_OS_WINDOWS_MOBILE - // Death test children can be terminated with _abort(). On Windows, - // _abort() can show a dialog with a warning message. This forces the - // abort message to go to stderr instead. - _set_error_mode(_OUT_TO_STDERR); -# endif - -# if _MSC_VER >= 1400 && !GTEST_OS_WINDOWS_MOBILE - // In the debug version, Visual Studio pops up a separate dialog - // offering a choice to debug the aborted program. We need to suppress - // this dialog or it will pop up for every EXPECT/ASSERT_DEATH statement - // executed. Google Test will notify the user of any unexpected - // failure via stderr. - // - // VC++ doesn't define _set_abort_behavior() prior to the version 8.0. - // Users of prior VC versions shall suffer the agony and pain of - // clicking through the countless debug dialogs. - // TODO(vladl@google.com): find a way to suppress the abort dialog() in the - // debug mode when compiled with VC 7.1 or lower. - if (!GTEST_FLAG(break_on_failure)) - _set_abort_behavior( - 0x0, // Clear the following flags: - _WRITE_ABORT_MSG | _CALL_REPORTFAULT); // pop-up window, core dump. -# endif - } -#endif // GTEST_HAS_SEH - - return internal::HandleExceptionsInMethodIfSupported( - impl(), - &internal::UnitTestImpl::RunAllTests, - "auxiliary test code (environments or event listeners)") ? 0 : 1; -} - -// Returns the working directory when the first TEST() or TEST_F() was -// executed. -const char* UnitTest::original_working_dir() const { - return impl_->original_working_dir_.c_str(); -} - -// Returns the TestCase object for the test that's currently running, -// or NULL if no test is running. -const TestCase* UnitTest::current_test_case() const - GTEST_LOCK_EXCLUDED_(mutex_) { - internal::MutexLock lock(&mutex_); - return impl_->current_test_case(); -} - -// Returns the TestInfo object for the test that's currently running, -// or NULL if no test is running. -const TestInfo* UnitTest::current_test_info() const - GTEST_LOCK_EXCLUDED_(mutex_) { - internal::MutexLock lock(&mutex_); - return impl_->current_test_info(); -} - -// Returns the random seed used at the start of the current test run. -int UnitTest::random_seed() const { return impl_->random_seed(); } - -#if GTEST_HAS_PARAM_TEST -// Returns ParameterizedTestCaseRegistry object used to keep track of -// value-parameterized tests and instantiate and register them. -internal::ParameterizedTestCaseRegistry& - UnitTest::parameterized_test_registry() - GTEST_LOCK_EXCLUDED_(mutex_) { - return impl_->parameterized_test_registry(); -} -#endif // GTEST_HAS_PARAM_TEST - -// Creates an empty UnitTest. -UnitTest::UnitTest() { - impl_ = new internal::UnitTestImpl(this); -} - -// Destructor of UnitTest. -UnitTest::~UnitTest() { - delete impl_; -} - -// Pushes a trace defined by SCOPED_TRACE() on to the per-thread -// Google Test trace stack. -void UnitTest::PushGTestTrace(const internal::TraceInfo& trace) - GTEST_LOCK_EXCLUDED_(mutex_) { - internal::MutexLock lock(&mutex_); - impl_->gtest_trace_stack().push_back(trace); -} - -// Pops a trace from the per-thread Google Test trace stack. -void UnitTest::PopGTestTrace() - GTEST_LOCK_EXCLUDED_(mutex_) { - internal::MutexLock lock(&mutex_); - impl_->gtest_trace_stack().pop_back(); -} - -namespace internal { - -UnitTestImpl::UnitTestImpl(UnitTest* parent) - : parent_(parent), -#ifdef _MSC_VER -# pragma warning(push) // Saves the current warning state. -# pragma warning(disable:4355) // Temporarily disables warning 4355 - // (using this in initializer). - default_global_test_part_result_reporter_(this), - default_per_thread_test_part_result_reporter_(this), -# pragma warning(pop) // Restores the warning state again. -#else - default_global_test_part_result_reporter_(this), - default_per_thread_test_part_result_reporter_(this), -#endif // _MSC_VER - global_test_part_result_repoter_( - &default_global_test_part_result_reporter_), - per_thread_test_part_result_reporter_( - &default_per_thread_test_part_result_reporter_), -#if GTEST_HAS_PARAM_TEST - parameterized_test_registry_(), - parameterized_tests_registered_(false), -#endif // GTEST_HAS_PARAM_TEST - last_death_test_case_(-1), - current_test_case_(NULL), - current_test_info_(NULL), - ad_hoc_test_result_(), - os_stack_trace_getter_(NULL), - post_flag_parse_init_performed_(false), - random_seed_(0), // Will be overridden by the flag before first use. - random_(0), // Will be reseeded before first use. - start_timestamp_(0), - elapsed_time_(0), -#if GTEST_HAS_DEATH_TEST - death_test_factory_(new DefaultDeathTestFactory), -#endif - // Will be overridden by the flag before first use. - catch_exceptions_(false) { - listeners()->SetDefaultResultPrinter(new PrettyUnitTestResultPrinter); -} - -UnitTestImpl::~UnitTestImpl() { - // Deletes every TestCase. - ForEach(test_cases_, internal::Delete); - - // Deletes every Environment. - ForEach(environments_, internal::Delete); - - delete os_stack_trace_getter_; -} - -// Adds a TestProperty to the current TestResult object when invoked in a -// context of a test, to current test case's ad_hoc_test_result when invoke -// from SetUpTestCase/TearDownTestCase, or to the global property set -// otherwise. If the result already contains a property with the same key, -// the value will be updated. -void UnitTestImpl::RecordProperty(const TestProperty& test_property) { - std::string xml_element; - TestResult* test_result; // TestResult appropriate for property recording. - - if (current_test_info_ != NULL) { - xml_element = "testcase"; - test_result = &(current_test_info_->result_); - } else if (current_test_case_ != NULL) { - xml_element = "testsuite"; - test_result = &(current_test_case_->ad_hoc_test_result_); - } else { - xml_element = "testsuites"; - test_result = &ad_hoc_test_result_; - } - test_result->RecordProperty(xml_element, test_property); -} - -#if GTEST_HAS_DEATH_TEST -// Disables event forwarding if the control is currently in a death test -// subprocess. Must not be called before InitGoogleTest. -void UnitTestImpl::SuppressTestEventsIfInSubprocess() { - if (internal_run_death_test_flag_.get() != NULL) - listeners()->SuppressEventForwarding(); -} -#endif // GTEST_HAS_DEATH_TEST - -// Initializes event listeners performing XML output as specified by -// UnitTestOptions. Must not be called before InitGoogleTest. -void UnitTestImpl::ConfigureXmlOutput() { - const std::string& output_format = UnitTestOptions::GetOutputFormat(); - if (output_format == "xml") { - listeners()->SetDefaultXmlGenerator(new XmlUnitTestResultPrinter( - UnitTestOptions::GetAbsolutePathToOutputFile().c_str())); - } else if (output_format != "") { - printf("WARNING: unrecognized output format \"%s\" ignored.\n", - output_format.c_str()); - fflush(stdout); - } -} - -#if GTEST_CAN_STREAM_RESULTS_ -// Initializes event listeners for streaming test results in string form. -// Must not be called before InitGoogleTest. -void UnitTestImpl::ConfigureStreamingOutput() { - const std::string& target = GTEST_FLAG(stream_result_to); - if (!target.empty()) { - const size_t pos = target.find(':'); - if (pos != std::string::npos) { - listeners()->Append(new StreamingListener(target.substr(0, pos), - target.substr(pos+1))); - } else { - printf("WARNING: unrecognized streaming target \"%s\" ignored.\n", - target.c_str()); - fflush(stdout); - } - } -} -#endif // GTEST_CAN_STREAM_RESULTS_ - -// Performs initialization dependent upon flag values obtained in -// ParseGoogleTestFlagsOnly. Is called from InitGoogleTest after the call to -// ParseGoogleTestFlagsOnly. In case a user neglects to call InitGoogleTest -// this function is also called from RunAllTests. Since this function can be -// called more than once, it has to be idempotent. -void UnitTestImpl::PostFlagParsingInit() { - // Ensures that this function does not execute more than once. - if (!post_flag_parse_init_performed_) { - post_flag_parse_init_performed_ = true; - -#if GTEST_HAS_DEATH_TEST - InitDeathTestSubprocessControlInfo(); - SuppressTestEventsIfInSubprocess(); -#endif // GTEST_HAS_DEATH_TEST - - // Registers parameterized tests. This makes parameterized tests - // available to the UnitTest reflection API without running - // RUN_ALL_TESTS. - RegisterParameterizedTests(); - - // Configures listeners for XML output. This makes it possible for users - // to shut down the default XML output before invoking RUN_ALL_TESTS. - ConfigureXmlOutput(); - -#if GTEST_CAN_STREAM_RESULTS_ - // Configures listeners for streaming test results to the specified server. - ConfigureStreamingOutput(); -#endif // GTEST_CAN_STREAM_RESULTS_ - } -} - -// A predicate that checks the name of a TestCase against a known -// value. -// -// This is used for implementation of the UnitTest class only. We put -// it in the anonymous namespace to prevent polluting the outer -// namespace. -// -// TestCaseNameIs is copyable. -class TestCaseNameIs { - public: - // Constructor. - explicit TestCaseNameIs(const std::string& name) - : name_(name) {} - - // Returns true iff the name of test_case matches name_. - bool operator()(const TestCase* test_case) const { - return test_case != NULL && strcmp(test_case->name(), name_.c_str()) == 0; - } - - private: - std::string name_; -}; - -// Finds and returns a TestCase with the given name. If one doesn't -// exist, creates one and returns it. It's the CALLER'S -// RESPONSIBILITY to ensure that this function is only called WHEN THE -// TESTS ARE NOT SHUFFLED. -// -// Arguments: -// -// test_case_name: name of the test case -// type_param: the name of the test case's type parameter, or NULL if -// this is not a typed or a type-parameterized test case. -// set_up_tc: pointer to the function that sets up the test case -// tear_down_tc: pointer to the function that tears down the test case -TestCase* UnitTestImpl::GetTestCase(const char* test_case_name, - const char* type_param, - Test::SetUpTestCaseFunc set_up_tc, - Test::TearDownTestCaseFunc tear_down_tc) { - // Can we find a TestCase with the given name? - const std::vector::const_iterator test_case = - std::find_if(test_cases_.begin(), test_cases_.end(), - TestCaseNameIs(test_case_name)); - - if (test_case != test_cases_.end()) - return *test_case; - - // No. Let's create one. - TestCase* const new_test_case = - new TestCase(test_case_name, type_param, set_up_tc, tear_down_tc); - - // Is this a death test case? - if (internal::UnitTestOptions::MatchesFilter(test_case_name, - kDeathTestCaseFilter)) { - // Yes. Inserts the test case after the last death test case - // defined so far. This only works when the test cases haven't - // been shuffled. Otherwise we may end up running a death test - // after a non-death test. - ++last_death_test_case_; - test_cases_.insert(test_cases_.begin() + last_death_test_case_, - new_test_case); - } else { - // No. Appends to the end of the list. - test_cases_.push_back(new_test_case); - } - - test_case_indices_.push_back(static_cast(test_case_indices_.size())); - return new_test_case; -} - -// Helpers for setting up / tearing down the given environment. They -// are for use in the ForEach() function. -static void SetUpEnvironment(Environment* env) { env->SetUp(); } -static void TearDownEnvironment(Environment* env) { env->TearDown(); } - -// Runs all tests in this UnitTest object, prints the result, and -// returns true if all tests are successful. If any exception is -// thrown during a test, the test is considered to be failed, but the -// rest of the tests will still be run. -// -// When parameterized tests are enabled, it expands and registers -// parameterized tests first in RegisterParameterizedTests(). -// All other functions called from RunAllTests() may safely assume that -// parameterized tests are ready to be counted and run. -bool UnitTestImpl::RunAllTests() { - // Makes sure InitGoogleTest() was called. - if (!GTestIsInitialized()) { - printf("%s", - "\nThis test program did NOT call ::testing::InitGoogleTest " - "before calling RUN_ALL_TESTS(). Please fix it.\n"); - return false; - } - - // Do not run any test if the --help flag was specified. - if (g_help_flag) - return true; - - // Repeats the call to the post-flag parsing initialization in case the - // user didn't call InitGoogleTest. - PostFlagParsingInit(); - - // Even if sharding is not on, test runners may want to use the - // GTEST_SHARD_STATUS_FILE to query whether the test supports the sharding - // protocol. - internal::WriteToShardStatusFileIfNeeded(); - - // True iff we are in a subprocess for running a thread-safe-style - // death test. - bool in_subprocess_for_death_test = false; - -#if GTEST_HAS_DEATH_TEST - in_subprocess_for_death_test = (internal_run_death_test_flag_.get() != NULL); -#endif // GTEST_HAS_DEATH_TEST - - const bool should_shard = ShouldShard(kTestTotalShards, kTestShardIndex, - in_subprocess_for_death_test); - - // Compares the full test names with the filter to decide which - // tests to run. - const bool has_tests_to_run = FilterTests(should_shard - ? HONOR_SHARDING_PROTOCOL - : IGNORE_SHARDING_PROTOCOL) > 0; - - // Lists the tests and exits if the --gtest_list_tests flag was specified. - if (GTEST_FLAG(list_tests)) { - // This must be called *after* FilterTests() has been called. - ListTestsMatchingFilter(); - return true; - } - - random_seed_ = GTEST_FLAG(shuffle) ? - GetRandomSeedFromFlag(GTEST_FLAG(random_seed)) : 0; - - // True iff at least one test has failed. - bool failed = false; - - TestEventListener* repeater = listeners()->repeater(); - - start_timestamp_ = GetTimeInMillis(); - repeater->OnTestProgramStart(*parent_); - - // How many times to repeat the tests? We don't want to repeat them - // when we are inside the subprocess of a death test. - const int repeat = in_subprocess_for_death_test ? 1 : GTEST_FLAG(repeat); - // Repeats forever if the repeat count is negative. - const bool forever = repeat < 0; - for (int i = 0; forever || i != repeat; i++) { - // We want to preserve failures generated by ad-hoc test - // assertions executed before RUN_ALL_TESTS(). - ClearNonAdHocTestResult(); - - const TimeInMillis start = GetTimeInMillis(); - - // Shuffles test cases and tests if requested. - if (has_tests_to_run && GTEST_FLAG(shuffle)) { - random()->Reseed(random_seed_); - // This should be done before calling OnTestIterationStart(), - // such that a test event listener can see the actual test order - // in the event. - ShuffleTests(); - } - - // Tells the unit test event listeners that the tests are about to start. - repeater->OnTestIterationStart(*parent_, i); - - // Runs each test case if there is at least one test to run. - if (has_tests_to_run) { - // Sets up all environments beforehand. - repeater->OnEnvironmentsSetUpStart(*parent_); - ForEach(environments_, SetUpEnvironment); - repeater->OnEnvironmentsSetUpEnd(*parent_); - - // Runs the tests only if there was no fatal failure during global - // set-up. - if (!Test::HasFatalFailure()) { - for (int test_index = 0; test_index < total_test_case_count(); - test_index++) { - GetMutableTestCase(test_index)->Run(); - } - } - - // Tears down all environments in reverse order afterwards. - repeater->OnEnvironmentsTearDownStart(*parent_); - std::for_each(environments_.rbegin(), environments_.rend(), - TearDownEnvironment); - repeater->OnEnvironmentsTearDownEnd(*parent_); - } - - elapsed_time_ = GetTimeInMillis() - start; - - // Tells the unit test event listener that the tests have just finished. - repeater->OnTestIterationEnd(*parent_, i); - - // Gets the result and clears it. - if (!Passed()) { - failed = true; - } - - // Restores the original test order after the iteration. This - // allows the user to quickly repro a failure that happens in the - // N-th iteration without repeating the first (N - 1) iterations. - // This is not enclosed in "if (GTEST_FLAG(shuffle)) { ... }", in - // case the user somehow changes the value of the flag somewhere - // (it's always safe to unshuffle the tests). - UnshuffleTests(); - - if (GTEST_FLAG(shuffle)) { - // Picks a new random seed for each iteration. - random_seed_ = GetNextRandomSeed(random_seed_); - } - } - - repeater->OnTestProgramEnd(*parent_); - - return !failed; -} - -// Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file -// if the variable is present. If a file already exists at this location, this -// function will write over it. If the variable is present, but the file cannot -// be created, prints an error and exits. -void WriteToShardStatusFileIfNeeded() { - const char* const test_shard_file = posix::GetEnv(kTestShardStatusFile); - if (test_shard_file != NULL) { - FILE* const file = posix::FOpen(test_shard_file, "w"); - if (file == NULL) { - ColoredPrintf(COLOR_RED, - "Could not write to the test shard status file \"%s\" " - "specified by the %s environment variable.\n", - test_shard_file, kTestShardStatusFile); - fflush(stdout); - exit(EXIT_FAILURE); - } - fclose(file); - } -} - -// Checks whether sharding is enabled by examining the relevant -// environment variable values. If the variables are present, -// but inconsistent (i.e., shard_index >= total_shards), prints -// an error and exits. If in_subprocess_for_death_test, sharding is -// disabled because it must only be applied to the original test -// process. Otherwise, we could filter out death tests we intended to execute. -bool ShouldShard(const char* total_shards_env, - const char* shard_index_env, - bool in_subprocess_for_death_test) { - if (in_subprocess_for_death_test) { - return false; - } - - const Int32 total_shards = Int32FromEnvOrDie(total_shards_env, -1); - const Int32 shard_index = Int32FromEnvOrDie(shard_index_env, -1); - - if (total_shards == -1 && shard_index == -1) { - return false; - } else if (total_shards == -1 && shard_index != -1) { - const Message msg = Message() - << "Invalid environment variables: you have " - << kTestShardIndex << " = " << shard_index - << ", but have left " << kTestTotalShards << " unset.\n"; - ColoredPrintf(COLOR_RED, msg.GetString().c_str()); - fflush(stdout); - exit(EXIT_FAILURE); - } else if (total_shards != -1 && shard_index == -1) { - const Message msg = Message() - << "Invalid environment variables: you have " - << kTestTotalShards << " = " << total_shards - << ", but have left " << kTestShardIndex << " unset.\n"; - ColoredPrintf(COLOR_RED, msg.GetString().c_str()); - fflush(stdout); - exit(EXIT_FAILURE); - } else if (shard_index < 0 || shard_index >= total_shards) { - const Message msg = Message() - << "Invalid environment variables: we require 0 <= " - << kTestShardIndex << " < " << kTestTotalShards - << ", but you have " << kTestShardIndex << "=" << shard_index - << ", " << kTestTotalShards << "=" << total_shards << ".\n"; - ColoredPrintf(COLOR_RED, msg.GetString().c_str()); - fflush(stdout); - exit(EXIT_FAILURE); - } - - return total_shards > 1; -} - -// Parses the environment variable var as an Int32. If it is unset, -// returns default_val. If it is not an Int32, prints an error -// and aborts. -Int32 Int32FromEnvOrDie(const char* var, Int32 default_val) { - const char* str_val = posix::GetEnv(var); - if (str_val == NULL) { - return default_val; - } - - Int32 result; - if (!ParseInt32(Message() << "The value of environment variable " << var, - str_val, &result)) { - exit(EXIT_FAILURE); - } - return result; -} - -// Given the total number of shards, the shard index, and the test id, -// returns true iff the test should be run on this shard. The test id is -// some arbitrary but unique non-negative integer assigned to each test -// method. Assumes that 0 <= shard_index < total_shards. -bool ShouldRunTestOnShard(int total_shards, int shard_index, int test_id) { - return (test_id % total_shards) == shard_index; -} - -// Compares the name of each test with the user-specified filter to -// decide whether the test should be run, then records the result in -// each TestCase and TestInfo object. -// If shard_tests == true, further filters tests based on sharding -// variables in the environment - see -// http://code.google.com/p/googletest/wiki/GoogleTestAdvancedGuide. -// Returns the number of tests that should run. -int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) { - const Int32 total_shards = shard_tests == HONOR_SHARDING_PROTOCOL ? - Int32FromEnvOrDie(kTestTotalShards, -1) : -1; - const Int32 shard_index = shard_tests == HONOR_SHARDING_PROTOCOL ? - Int32FromEnvOrDie(kTestShardIndex, -1) : -1; - - // num_runnable_tests are the number of tests that will - // run across all shards (i.e., match filter and are not disabled). - // num_selected_tests are the number of tests to be run on - // this shard. - int num_runnable_tests = 0; - int num_selected_tests = 0; - for (size_t i = 0; i < test_cases_.size(); i++) { - TestCase* const test_case = test_cases_[i]; - const std::string &test_case_name = test_case->name(); - test_case->set_should_run(false); - - for (size_t j = 0; j < test_case->test_info_list().size(); j++) { - TestInfo* const test_info = test_case->test_info_list()[j]; - const std::string test_name(test_info->name()); - // A test is disabled if test case name or test name matches - // kDisableTestFilter. - const bool is_disabled = - internal::UnitTestOptions::MatchesFilter(test_case_name, - kDisableTestFilter) || - internal::UnitTestOptions::MatchesFilter(test_name, - kDisableTestFilter); - test_info->is_disabled_ = is_disabled; - - const bool matches_filter = - internal::UnitTestOptions::FilterMatchesTest(test_case_name, - test_name); - test_info->matches_filter_ = matches_filter; - - const bool is_runnable = - (GTEST_FLAG(also_run_disabled_tests) || !is_disabled) && - matches_filter; - - const bool is_selected = is_runnable && - (shard_tests == IGNORE_SHARDING_PROTOCOL || - ShouldRunTestOnShard(total_shards, shard_index, - num_runnable_tests)); - - num_runnable_tests += is_runnable; - num_selected_tests += is_selected; - - test_info->should_run_ = is_selected; - test_case->set_should_run(test_case->should_run() || is_selected); - } - } - return num_selected_tests; -} - -// Prints the given C-string on a single line by replacing all '\n' -// characters with string "\\n". If the output takes more than -// max_length characters, only prints the first max_length characters -// and "...". -static void PrintOnOneLine(const char* str, int max_length) { - if (str != NULL) { - for (int i = 0; *str != '\0'; ++str) { - if (i >= max_length) { - printf("..."); - break; - } - if (*str == '\n') { - printf("\\n"); - i += 2; - } else { - printf("%c", *str); - ++i; - } - } - } -} - -// Prints the names of the tests matching the user-specified filter flag. -void UnitTestImpl::ListTestsMatchingFilter() { - // Print at most this many characters for each type/value parameter. - const int kMaxParamLength = 250; - - for (size_t i = 0; i < test_cases_.size(); i++) { - const TestCase* const test_case = test_cases_[i]; - bool printed_test_case_name = false; - - for (size_t j = 0; j < test_case->test_info_list().size(); j++) { - const TestInfo* const test_info = - test_case->test_info_list()[j]; - if (test_info->matches_filter_) { - if (!printed_test_case_name) { - printed_test_case_name = true; - printf("%s.", test_case->name()); - if (test_case->type_param() != NULL) { - printf(" # %s = ", kTypeParamLabel); - // We print the type parameter on a single line to make - // the output easy to parse by a program. - PrintOnOneLine(test_case->type_param(), kMaxParamLength); - } - printf("\n"); - } - printf(" %s", test_info->name()); - if (test_info->value_param() != NULL) { - printf(" # %s = ", kValueParamLabel); - // We print the value parameter on a single line to make the - // output easy to parse by a program. - PrintOnOneLine(test_info->value_param(), kMaxParamLength); - } - printf("\n"); - } - } - } - fflush(stdout); -} - -// Sets the OS stack trace getter. -// -// Does nothing if the input and the current OS stack trace getter are -// the same; otherwise, deletes the old getter and makes the input the -// current getter. -void UnitTestImpl::set_os_stack_trace_getter( - OsStackTraceGetterInterface* getter) { - if (os_stack_trace_getter_ != getter) { - delete os_stack_trace_getter_; - os_stack_trace_getter_ = getter; - } -} - -// Returns the current OS stack trace getter if it is not NULL; -// otherwise, creates an OsStackTraceGetter, makes it the current -// getter, and returns it. -OsStackTraceGetterInterface* UnitTestImpl::os_stack_trace_getter() { - if (os_stack_trace_getter_ == NULL) { - os_stack_trace_getter_ = new OsStackTraceGetter; - } - - return os_stack_trace_getter_; -} - -// Returns the TestResult for the test that's currently running, or -// the TestResult for the ad hoc test if no test is running. -TestResult* UnitTestImpl::current_test_result() { - return current_test_info_ ? - &(current_test_info_->result_) : &ad_hoc_test_result_; -} - -// Shuffles all test cases, and the tests within each test case, -// making sure that death tests are still run first. -void UnitTestImpl::ShuffleTests() { - // Shuffles the death test cases. - ShuffleRange(random(), 0, last_death_test_case_ + 1, &test_case_indices_); - - // Shuffles the non-death test cases. - ShuffleRange(random(), last_death_test_case_ + 1, - static_cast(test_cases_.size()), &test_case_indices_); - - // Shuffles the tests inside each test case. - for (size_t i = 0; i < test_cases_.size(); i++) { - test_cases_[i]->ShuffleTests(random()); - } -} - -// Restores the test cases and tests to their order before the first shuffle. -void UnitTestImpl::UnshuffleTests() { - for (size_t i = 0; i < test_cases_.size(); i++) { - // Unshuffles the tests in each test case. - test_cases_[i]->UnshuffleTests(); - // Resets the index of each test case. - test_case_indices_[i] = static_cast(i); - } -} - -// Returns the current OS stack trace as an std::string. -// -// The maximum number of stack frames to be included is specified by -// the gtest_stack_trace_depth flag. The skip_count parameter -// specifies the number of top frames to be skipped, which doesn't -// count against the number of frames to be included. -// -// For example, if Foo() calls Bar(), which in turn calls -// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in -// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't. -std::string GetCurrentOsStackTraceExceptTop(UnitTest* /*unit_test*/, - int skip_count) { - // We pass skip_count + 1 to skip this wrapper function in addition - // to what the user really wants to skip. - return GetUnitTestImpl()->CurrentOsStackTraceExceptTop(skip_count + 1); -} - -// Used by the GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_ macro to -// suppress unreachable code warnings. -namespace { -class ClassUniqueToAlwaysTrue {}; -} - -bool IsTrue(bool condition) { return condition; } - -bool AlwaysTrue() { -#if GTEST_HAS_EXCEPTIONS - // This condition is always false so AlwaysTrue() never actually throws, - // but it makes the compiler think that it may throw. - if (IsTrue(false)) - throw ClassUniqueToAlwaysTrue(); -#endif // GTEST_HAS_EXCEPTIONS - return true; -} - -// If *pstr starts with the given prefix, modifies *pstr to be right -// past the prefix and returns true; otherwise leaves *pstr unchanged -// and returns false. None of pstr, *pstr, and prefix can be NULL. -bool SkipPrefix(const char* prefix, const char** pstr) { - const size_t prefix_len = strlen(prefix); - if (strncmp(*pstr, prefix, prefix_len) == 0) { - *pstr += prefix_len; - return true; - } - return false; -} - -// Parses a string as a command line flag. The string should have -// the format "--flag=value". When def_optional is true, the "=value" -// part can be omitted. -// -// Returns the value of the flag, or NULL if the parsing failed. -const char* ParseFlagValue(const char* str, - const char* flag, - bool def_optional) { - // str and flag must not be NULL. - if (str == NULL || flag == NULL) return NULL; - - // The flag must start with "--" followed by GTEST_FLAG_PREFIX_. - const std::string flag_str = std::string("--") + GTEST_FLAG_PREFIX_ + flag; - const size_t flag_len = flag_str.length(); - if (strncmp(str, flag_str.c_str(), flag_len) != 0) return NULL; - - // Skips the flag name. - const char* flag_end = str + flag_len; - - // When def_optional is true, it's OK to not have a "=value" part. - if (def_optional && (flag_end[0] == '\0')) { - return flag_end; - } - - // If def_optional is true and there are more characters after the - // flag name, or if def_optional is false, there must be a '=' after - // the flag name. - if (flag_end[0] != '=') return NULL; - - // Returns the string after "=". - return flag_end + 1; -} - -// Parses a string for a bool flag, in the form of either -// "--flag=value" or "--flag". -// -// In the former case, the value is taken as true as long as it does -// not start with '0', 'f', or 'F'. -// -// In the latter case, the value is taken as true. -// -// On success, stores the value of the flag in *value, and returns -// true. On failure, returns false without changing *value. -bool ParseBoolFlag(const char* str, const char* flag, bool* value) { - // Gets the value of the flag as a string. - const char* const value_str = ParseFlagValue(str, flag, true); - - // Aborts if the parsing failed. - if (value_str == NULL) return false; - - // Converts the string value to a bool. - *value = !(*value_str == '0' || *value_str == 'f' || *value_str == 'F'); - return true; -} - -// Parses a string for an Int32 flag, in the form of -// "--flag=value". -// -// On success, stores the value of the flag in *value, and returns -// true. On failure, returns false without changing *value. -bool ParseInt32Flag(const char* str, const char* flag, Int32* value) { - // Gets the value of the flag as a string. - const char* const value_str = ParseFlagValue(str, flag, false); - - // Aborts if the parsing failed. - if (value_str == NULL) return false; - - // Sets *value to the value of the flag. - return ParseInt32(Message() << "The value of flag --" << flag, - value_str, value); -} - -// Parses a string for a string flag, in the form of -// "--flag=value". -// -// On success, stores the value of the flag in *value, and returns -// true. On failure, returns false without changing *value. -bool ParseStringFlag(const char* str, const char* flag, std::string* value) { - // Gets the value of the flag as a string. - const char* const value_str = ParseFlagValue(str, flag, false); - - // Aborts if the parsing failed. - if (value_str == NULL) return false; - - // Sets *value to the value of the flag. - *value = value_str; - return true; -} - -// Determines whether a string has a prefix that Google Test uses for its -// flags, i.e., starts with GTEST_FLAG_PREFIX_ or GTEST_FLAG_PREFIX_DASH_. -// If Google Test detects that a command line flag has its prefix but is not -// recognized, it will print its help message. Flags starting with -// GTEST_INTERNAL_PREFIX_ followed by "internal_" are considered Google Test -// internal flags and do not trigger the help message. -static bool HasGoogleTestFlagPrefix(const char* str) { - return (SkipPrefix("--", &str) || - SkipPrefix("-", &str) || - SkipPrefix("/", &str)) && - !SkipPrefix(GTEST_FLAG_PREFIX_ "internal_", &str) && - (SkipPrefix(GTEST_FLAG_PREFIX_, &str) || - SkipPrefix(GTEST_FLAG_PREFIX_DASH_, &str)); -} - -// Prints a string containing code-encoded text. The following escape -// sequences can be used in the string to control the text color: -// -// @@ prints a single '@' character. -// @R changes the color to red. -// @G changes the color to green. -// @Y changes the color to yellow. -// @D changes to the default terminal text color. -// -// TODO(wan@google.com): Write tests for this once we add stdout -// capturing to Google Test. -static void PrintColorEncoded(const char* str) { - GTestColor color = COLOR_DEFAULT; // The current color. - - // Conceptually, we split the string into segments divided by escape - // sequences. Then we print one segment at a time. At the end of - // each iteration, the str pointer advances to the beginning of the - // next segment. - for (;;) { - const char* p = strchr(str, '@'); - if (p == NULL) { - ColoredPrintf(color, "%s", str); - return; - } - - ColoredPrintf(color, "%s", std::string(str, p).c_str()); - - const char ch = p[1]; - str = p + 2; - if (ch == '@') { - ColoredPrintf(color, "@"); - } else if (ch == 'D') { - color = COLOR_DEFAULT; - } else if (ch == 'R') { - color = COLOR_RED; - } else if (ch == 'G') { - color = COLOR_GREEN; - } else if (ch == 'Y') { - color = COLOR_YELLOW; - } else { - --str; - } - } -} - -static const char kColorEncodedHelpMessage[] = -"This program contains tests written using " GTEST_NAME_ ". You can use the\n" -"following command line flags to control its behavior:\n" -"\n" -"Test Selection:\n" -" @G--" GTEST_FLAG_PREFIX_ "list_tests@D\n" -" List the names of all tests instead of running them. The name of\n" -" TEST(Foo, Bar) is \"Foo.Bar\".\n" -" @G--" GTEST_FLAG_PREFIX_ "filter=@YPOSTIVE_PATTERNS" - "[@G-@YNEGATIVE_PATTERNS]@D\n" -" Run only the tests whose name matches one of the positive patterns but\n" -" none of the negative patterns. '?' matches any single character; '*'\n" -" matches any substring; ':' separates two patterns.\n" -" @G--" GTEST_FLAG_PREFIX_ "also_run_disabled_tests@D\n" -" Run all disabled tests too.\n" -"\n" -"Test Execution:\n" -" @G--" GTEST_FLAG_PREFIX_ "repeat=@Y[COUNT]@D\n" -" Run the tests repeatedly; use a negative count to repeat forever.\n" -" @G--" GTEST_FLAG_PREFIX_ "shuffle@D\n" -" Randomize tests' orders on every iteration.\n" -" @G--" GTEST_FLAG_PREFIX_ "random_seed=@Y[NUMBER]@D\n" -" Random number seed to use for shuffling test orders (between 1 and\n" -" 99999, or 0 to use a seed based on the current time).\n" -"\n" -"Test Output:\n" -" @G--" GTEST_FLAG_PREFIX_ "color=@Y(@Gyes@Y|@Gno@Y|@Gauto@Y)@D\n" -" Enable/disable colored output. The default is @Gauto@D.\n" -" -@G-" GTEST_FLAG_PREFIX_ "print_time=0@D\n" -" Don't print the elapsed time of each test.\n" -" @G--" GTEST_FLAG_PREFIX_ "output=xml@Y[@G:@YDIRECTORY_PATH@G" - GTEST_PATH_SEP_ "@Y|@G:@YFILE_PATH]@D\n" -" Generate an XML report in the given directory or with the given file\n" -" name. @YFILE_PATH@D defaults to @Gtest_details.xml@D.\n" -#if GTEST_CAN_STREAM_RESULTS_ -" @G--" GTEST_FLAG_PREFIX_ "stream_result_to=@YHOST@G:@YPORT@D\n" -" Stream test results to the given server.\n" -#endif // GTEST_CAN_STREAM_RESULTS_ -"\n" -"Assertion Behavior:\n" -#if GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS -" @G--" GTEST_FLAG_PREFIX_ "death_test_style=@Y(@Gfast@Y|@Gthreadsafe@Y)@D\n" -" Set the default death test style.\n" -#endif // GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS -" @G--" GTEST_FLAG_PREFIX_ "break_on_failure@D\n" -" Turn assertion failures into debugger break-points.\n" -" @G--" GTEST_FLAG_PREFIX_ "throw_on_failure@D\n" -" Turn assertion failures into C++ exceptions.\n" -" @G--" GTEST_FLAG_PREFIX_ "catch_exceptions=0@D\n" -" Do not report exceptions as test failures. Instead, allow them\n" -" to crash the program or throw a pop-up (on Windows).\n" -"\n" -"Except for @G--" GTEST_FLAG_PREFIX_ "list_tests@D, you can alternatively set " - "the corresponding\n" -"environment variable of a flag (all letters in upper-case). For example, to\n" -"disable colored text output, you can either specify @G--" GTEST_FLAG_PREFIX_ - "color=no@D or set\n" -"the @G" GTEST_FLAG_PREFIX_UPPER_ "COLOR@D environment variable to @Gno@D.\n" -"\n" -"For more information, please read the " GTEST_NAME_ " documentation at\n" -"@G" GTEST_PROJECT_URL_ "@D. If you find a bug in " GTEST_NAME_ "\n" -"(not one in your own code or tests), please report it to\n" -"@G<" GTEST_DEV_EMAIL_ ">@D.\n"; - -// Parses the command line for Google Test flags, without initializing -// other parts of Google Test. The type parameter CharType can be -// instantiated to either char or wchar_t. -template -void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) { - for (int i = 1; i < *argc; i++) { - const std::string arg_string = StreamableToString(argv[i]); - const char* const arg = arg_string.c_str(); - - using internal::ParseBoolFlag; - using internal::ParseInt32Flag; - using internal::ParseStringFlag; - - // Do we see a Google Test flag? - if (ParseBoolFlag(arg, kAlsoRunDisabledTestsFlag, - >EST_FLAG(also_run_disabled_tests)) || - ParseBoolFlag(arg, kBreakOnFailureFlag, - >EST_FLAG(break_on_failure)) || - ParseBoolFlag(arg, kCatchExceptionsFlag, - >EST_FLAG(catch_exceptions)) || - ParseStringFlag(arg, kColorFlag, >EST_FLAG(color)) || - ParseStringFlag(arg, kDeathTestStyleFlag, - >EST_FLAG(death_test_style)) || - ParseBoolFlag(arg, kDeathTestUseFork, - >EST_FLAG(death_test_use_fork)) || - ParseStringFlag(arg, kFilterFlag, >EST_FLAG(filter)) || - ParseStringFlag(arg, kInternalRunDeathTestFlag, - >EST_FLAG(internal_run_death_test)) || - ParseBoolFlag(arg, kListTestsFlag, >EST_FLAG(list_tests)) || - ParseStringFlag(arg, kOutputFlag, >EST_FLAG(output)) || - ParseBoolFlag(arg, kPrintTimeFlag, >EST_FLAG(print_time)) || - ParseInt32Flag(arg, kRandomSeedFlag, >EST_FLAG(random_seed)) || - ParseInt32Flag(arg, kRepeatFlag, >EST_FLAG(repeat)) || - ParseBoolFlag(arg, kShuffleFlag, >EST_FLAG(shuffle)) || - ParseInt32Flag(arg, kStackTraceDepthFlag, - >EST_FLAG(stack_trace_depth)) || - ParseStringFlag(arg, kStreamResultToFlag, - >EST_FLAG(stream_result_to)) || - ParseBoolFlag(arg, kThrowOnFailureFlag, - >EST_FLAG(throw_on_failure)) - ) { - // Yes. Shift the remainder of the argv list left by one. Note - // that argv has (*argc + 1) elements, the last one always being - // NULL. The following loop moves the trailing NULL element as - // well. - for (int j = i; j != *argc; j++) { - argv[j] = argv[j + 1]; - } - - // Decrements the argument count. - (*argc)--; - - // We also need to decrement the iterator as we just removed - // an element. - i--; - } else if (arg_string == "--help" || arg_string == "-h" || - arg_string == "-?" || arg_string == "/?" || - HasGoogleTestFlagPrefix(arg)) { - // Both help flag and unrecognized Google Test flags (excluding - // internal ones) trigger help display. - g_help_flag = true; - } - } - - if (g_help_flag) { - // We print the help here instead of in RUN_ALL_TESTS(), as the - // latter may not be called at all if the user is using Google - // Test with another testing framework. - PrintColorEncoded(kColorEncodedHelpMessage); - } -} - -// Parses the command line for Google Test flags, without initializing -// other parts of Google Test. -void ParseGoogleTestFlagsOnly(int* argc, char** argv) { - ParseGoogleTestFlagsOnlyImpl(argc, argv); -} -void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv) { - ParseGoogleTestFlagsOnlyImpl(argc, argv); -} - -// The internal implementation of InitGoogleTest(). -// -// The type parameter CharType can be instantiated to either char or -// wchar_t. -template -void InitGoogleTestImpl(int* argc, CharType** argv) { - g_init_gtest_count++; - - // We don't want to run the initialization code twice. - if (g_init_gtest_count != 1) return; - - if (*argc <= 0) return; - - internal::g_executable_path = internal::StreamableToString(argv[0]); - -#if GTEST_HAS_DEATH_TEST - - g_argvs.clear(); - for (int i = 0; i != *argc; i++) { - g_argvs.push_back(StreamableToString(argv[i])); - } - -#endif // GTEST_HAS_DEATH_TEST - - ParseGoogleTestFlagsOnly(argc, argv); - GetUnitTestImpl()->PostFlagParsingInit(); -} - -} // namespace internal - -// Initializes Google Test. This must be called before calling -// RUN_ALL_TESTS(). In particular, it parses a command line for the -// flags that Google Test recognizes. Whenever a Google Test flag is -// seen, it is removed from argv, and *argc is decremented. -// -// No value is returned. Instead, the Google Test flag variables are -// updated. -// -// Calling the function for the second time has no user-visible effect. -void InitGoogleTest(int* argc, char** argv) { - internal::InitGoogleTestImpl(argc, argv); -} - -// This overloaded version can be used in Windows programs compiled in -// UNICODE mode. -void InitGoogleTest(int* argc, wchar_t** argv) { - internal::InitGoogleTestImpl(argc, argv); -} - -} // namespace testing -// Copyright 2005, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: wan@google.com (Zhanyong Wan), vladl@google.com (Vlad Losev) -// -// This file implements death tests. - - -#if GTEST_HAS_DEATH_TEST - -# if GTEST_OS_MAC -# include -# endif // GTEST_OS_MAC - -# include -# include -# include - -# if GTEST_OS_LINUX -# include -# endif // GTEST_OS_LINUX - -# include - -# if GTEST_OS_WINDOWS -# include -# else -# include -# include -# endif // GTEST_OS_WINDOWS - -# if GTEST_OS_QNX -# include -# endif // GTEST_OS_QNX - -#endif // GTEST_HAS_DEATH_TEST - - -// Indicates that this translation unit is part of Google Test's -// implementation. It must come before gtest-internal-inl.h is -// included, or there will be a compiler error. This trick is to -// prevent a user from accidentally including gtest-internal-inl.h in -// his code. -#define GTEST_IMPLEMENTATION_ 1 -#undef GTEST_IMPLEMENTATION_ - -namespace testing { - -// Constants. - -// The default death test style. -static const char kDefaultDeathTestStyle[] = "fast"; - -GTEST_DEFINE_string_( - death_test_style, - internal::StringFromGTestEnv("death_test_style", kDefaultDeathTestStyle), - "Indicates how to run a death test in a forked child process: " - "\"threadsafe\" (child process re-executes the test binary " - "from the beginning, running only the specific death test) or " - "\"fast\" (child process runs the death test immediately " - "after forking)."); - -GTEST_DEFINE_bool_( - death_test_use_fork, - internal::BoolFromGTestEnv("death_test_use_fork", false), - "Instructs to use fork()/_exit() instead of clone() in death tests. " - "Ignored and always uses fork() on POSIX systems where clone() is not " - "implemented. Useful when running under valgrind or similar tools if " - "those do not support clone(). Valgrind 3.3.1 will just fail if " - "it sees an unsupported combination of clone() flags. " - "It is not recommended to use this flag w/o valgrind though it will " - "work in 99% of the cases. Once valgrind is fixed, this flag will " - "most likely be removed."); - -namespace internal { -GTEST_DEFINE_string_( - internal_run_death_test, "", - "Indicates the file, line number, temporal index of " - "the single death test to run, and a file descriptor to " - "which a success code may be sent, all separated by " - "the '|' characters. This flag is specified if and only if the current " - "process is a sub-process launched for running a thread-safe " - "death test. FOR INTERNAL USE ONLY."); -} // namespace internal - -#if GTEST_HAS_DEATH_TEST - -namespace internal { - -// Valid only for fast death tests. Indicates the code is running in the -// child process of a fast style death test. -static bool g_in_fast_death_test_child = false; - -// Returns a Boolean value indicating whether the caller is currently -// executing in the context of the death test child process. Tools such as -// Valgrind heap checkers may need this to modify their behavior in death -// tests. IMPORTANT: This is an internal utility. Using it may break the -// implementation of death tests. User code MUST NOT use it. -bool InDeathTestChild() { -# if GTEST_OS_WINDOWS - - // On Windows, death tests are thread-safe regardless of the value of the - // death_test_style flag. - return !GTEST_FLAG(internal_run_death_test).empty(); - -# else - - if (GTEST_FLAG(death_test_style) == "threadsafe") - return !GTEST_FLAG(internal_run_death_test).empty(); - else - return g_in_fast_death_test_child; -#endif -} - -} // namespace internal - -// ExitedWithCode constructor. -ExitedWithCode::ExitedWithCode(int exit_code) : exit_code_(exit_code) { -} - -// ExitedWithCode function-call operator. -bool ExitedWithCode::operator()(int exit_status) const { -# if GTEST_OS_WINDOWS - - return exit_status == exit_code_; - -# else - - return WIFEXITED(exit_status) && WEXITSTATUS(exit_status) == exit_code_; - -# endif // GTEST_OS_WINDOWS -} - -# if !GTEST_OS_WINDOWS -// KilledBySignal constructor. -KilledBySignal::KilledBySignal(int signum) : signum_(signum) { -} - -// KilledBySignal function-call operator. -bool KilledBySignal::operator()(int exit_status) const { - return WIFSIGNALED(exit_status) && WTERMSIG(exit_status) == signum_; -} -# endif // !GTEST_OS_WINDOWS - -namespace internal { - -// Utilities needed for death tests. - -// Generates a textual description of a given exit code, in the format -// specified by wait(2). -static std::string ExitSummary(int exit_code) { - Message m; - -# if GTEST_OS_WINDOWS - - m << "Exited with exit status " << exit_code; - -# else - - if (WIFEXITED(exit_code)) { - m << "Exited with exit status " << WEXITSTATUS(exit_code); - } else if (WIFSIGNALED(exit_code)) { - m << "Terminated by signal " << WTERMSIG(exit_code); - } -# ifdef WCOREDUMP - if (WCOREDUMP(exit_code)) { - m << " (core dumped)"; - } -# endif -# endif // GTEST_OS_WINDOWS - - return m.GetString(); -} - -// Returns true if exit_status describes a process that was terminated -// by a signal, or exited normally with a nonzero exit code. -bool ExitedUnsuccessfully(int exit_status) { - return !ExitedWithCode(0)(exit_status); -} - -# if !GTEST_OS_WINDOWS -// Generates a textual failure message when a death test finds more than -// one thread running, or cannot determine the number of threads, prior -// to executing the given statement. It is the responsibility of the -// caller not to pass a thread_count of 1. -static std::string DeathTestThreadWarning(size_t thread_count) { - Message msg; - msg << "Death tests use fork(), which is unsafe particularly" - << " in a threaded context. For this test, " << GTEST_NAME_ << " "; - if (thread_count == 0) - msg << "couldn't detect the number of threads."; - else - msg << "detected " << thread_count << " threads."; - return msg.GetString(); -} -# endif // !GTEST_OS_WINDOWS - -// Flag characters for reporting a death test that did not die. -static const char kDeathTestLived = 'L'; -static const char kDeathTestReturned = 'R'; -static const char kDeathTestThrew = 'T'; -static const char kDeathTestInternalError = 'I'; - -// An enumeration describing all of the possible ways that a death test can -// conclude. DIED means that the process died while executing the test -// code; LIVED means that process lived beyond the end of the test code; -// RETURNED means that the test statement attempted to execute a return -// statement, which is not allowed; THREW means that the test statement -// returned control by throwing an exception. IN_PROGRESS means the test -// has not yet concluded. -// TODO(vladl@google.com): Unify names and possibly values for -// AbortReason, DeathTestOutcome, and flag characters above. -enum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED, THREW }; - -// Routine for aborting the program which is safe to call from an -// exec-style death test child process, in which case the error -// message is propagated back to the parent process. Otherwise, the -// message is simply printed to stderr. In either case, the program -// then exits with status 1. -void DeathTestAbort(const std::string& message) { - // On a POSIX system, this function may be called from a threadsafe-style - // death test child process, which operates on a very small stack. Use - // the heap for any additional non-minuscule memory requirements. - const InternalRunDeathTestFlag* const flag = - GetUnitTestImpl()->internal_run_death_test_flag(); - if (flag != NULL) { - FILE* parent = posix::FDOpen(flag->write_fd(), "w"); - fputc(kDeathTestInternalError, parent); - fprintf(parent, "%s", message.c_str()); - fflush(parent); - _exit(1); - } else { - fprintf(stderr, "%s", message.c_str()); - fflush(stderr); - posix::Abort(); - } -} - -// A replacement for CHECK that calls DeathTestAbort if the assertion -// fails. -# define GTEST_DEATH_TEST_CHECK_(expression) \ - do { \ - if (!::testing::internal::IsTrue(expression)) { \ - DeathTestAbort( \ - ::std::string("CHECK failed: File ") + __FILE__ + ", line " \ - + ::testing::internal::StreamableToString(__LINE__) + ": " \ - + #expression); \ - } \ - } while (::testing::internal::AlwaysFalse()) - -// This macro is similar to GTEST_DEATH_TEST_CHECK_, but it is meant for -// evaluating any system call that fulfills two conditions: it must return -// -1 on failure, and set errno to EINTR when it is interrupted and -// should be tried again. The macro expands to a loop that repeatedly -// evaluates the expression as long as it evaluates to -1 and sets -// errno to EINTR. If the expression evaluates to -1 but errno is -// something other than EINTR, DeathTestAbort is called. -# define GTEST_DEATH_TEST_CHECK_SYSCALL_(expression) \ - do { \ - int gtest_retval; \ - do { \ - gtest_retval = (expression); \ - } while (gtest_retval == -1 && errno == EINTR); \ - if (gtest_retval == -1) { \ - DeathTestAbort( \ - ::std::string("CHECK failed: File ") + __FILE__ + ", line " \ - + ::testing::internal::StreamableToString(__LINE__) + ": " \ - + #expression + " != -1"); \ - } \ - } while (::testing::internal::AlwaysFalse()) - -// Returns the message describing the last system error in errno. -std::string GetLastErrnoDescription() { - return errno == 0 ? "" : posix::StrError(errno); -} - -// This is called from a death test parent process to read a failure -// message from the death test child process and log it with the FATAL -// severity. On Windows, the message is read from a pipe handle. On other -// platforms, it is read from a file descriptor. -static void FailFromInternalError(int fd) { - Message error; - char buffer[256]; - int num_read; - - do { - while ((num_read = posix::Read(fd, buffer, 255)) > 0) { - buffer[num_read] = '\0'; - error << buffer; - } - } while (num_read == -1 && errno == EINTR); - - if (num_read == 0) { - GTEST_LOG_(FATAL) << error.GetString(); - } else { - const int last_error = errno; - GTEST_LOG_(FATAL) << "Error while reading death test internal: " - << GetLastErrnoDescription() << " [" << last_error << "]"; - } -} - -// Death test constructor. Increments the running death test count -// for the current test. -DeathTest::DeathTest() { - TestInfo* const info = GetUnitTestImpl()->current_test_info(); - if (info == NULL) { - DeathTestAbort("Cannot run a death test outside of a TEST or " - "TEST_F construct"); - } -} - -// Creates and returns a death test by dispatching to the current -// death test factory. -bool DeathTest::Create(const char* statement, const RE* regex, - const char* file, int line, DeathTest** test) { - return GetUnitTestImpl()->death_test_factory()->Create( - statement, regex, file, line, test); -} - -const char* DeathTest::LastMessage() { - return last_death_test_message_.c_str(); -} - -void DeathTest::set_last_death_test_message(const std::string& message) { - last_death_test_message_ = message; -} - -std::string DeathTest::last_death_test_message_; - -// Provides cross platform implementation for some death functionality. -class DeathTestImpl : public DeathTest { - protected: - DeathTestImpl(const char* a_statement, const RE* a_regex) - : statement_(a_statement), - regex_(a_regex), - spawned_(false), - status_(-1), - outcome_(IN_PROGRESS), - read_fd_(-1), - write_fd_(-1) {} - - // read_fd_ is expected to be closed and cleared by a derived class. - ~DeathTestImpl() { GTEST_DEATH_TEST_CHECK_(read_fd_ == -1); } - - void Abort(AbortReason reason); - virtual bool Passed(bool status_ok); - - const char* statement() const { return statement_; } - const RE* regex() const { return regex_; } - bool spawned() const { return spawned_; } - void set_spawned(bool is_spawned) { spawned_ = is_spawned; } - int status() const { return status_; } - void set_status(int a_status) { status_ = a_status; } - DeathTestOutcome outcome() const { return outcome_; } - void set_outcome(DeathTestOutcome an_outcome) { outcome_ = an_outcome; } - int read_fd() const { return read_fd_; } - void set_read_fd(int fd) { read_fd_ = fd; } - int write_fd() const { return write_fd_; } - void set_write_fd(int fd) { write_fd_ = fd; } - - // Called in the parent process only. Reads the result code of the death - // test child process via a pipe, interprets it to set the outcome_ - // member, and closes read_fd_. Outputs diagnostics and terminates in - // case of unexpected codes. - void ReadAndInterpretStatusByte(); - - private: - // The textual content of the code this object is testing. This class - // doesn't own this string and should not attempt to delete it. - const char* const statement_; - // The regular expression which test output must match. DeathTestImpl - // doesn't own this object and should not attempt to delete it. - const RE* const regex_; - // True if the death test child process has been successfully spawned. - bool spawned_; - // The exit status of the child process. - int status_; - // How the death test concluded. - DeathTestOutcome outcome_; - // Descriptor to the read end of the pipe to the child process. It is - // always -1 in the child process. The child keeps its write end of the - // pipe in write_fd_. - int read_fd_; - // Descriptor to the child's write end of the pipe to the parent process. - // It is always -1 in the parent process. The parent keeps its end of the - // pipe in read_fd_. - int write_fd_; -}; - -// Called in the parent process only. Reads the result code of the death -// test child process via a pipe, interprets it to set the outcome_ -// member, and closes read_fd_. Outputs diagnostics and terminates in -// case of unexpected codes. -void DeathTestImpl::ReadAndInterpretStatusByte() { - char flag; - int bytes_read; - - // The read() here blocks until data is available (signifying the - // failure of the death test) or until the pipe is closed (signifying - // its success), so it's okay to call this in the parent before - // the child process has exited. - do { - bytes_read = posix::Read(read_fd(), &flag, 1); - } while (bytes_read == -1 && errno == EINTR); - - if (bytes_read == 0) { - set_outcome(DIED); - } else if (bytes_read == 1) { - switch (flag) { - case kDeathTestReturned: - set_outcome(RETURNED); - break; - case kDeathTestThrew: - set_outcome(THREW); - break; - case kDeathTestLived: - set_outcome(LIVED); - break; - case kDeathTestInternalError: - FailFromInternalError(read_fd()); // Does not return. - break; - default: - GTEST_LOG_(FATAL) << "Death test child process reported " - << "unexpected status byte (" - << static_cast(flag) << ")"; - } - } else { - GTEST_LOG_(FATAL) << "Read from death test child process failed: " - << GetLastErrnoDescription(); - } - GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Close(read_fd())); - set_read_fd(-1); -} - -// Signals that the death test code which should have exited, didn't. -// Should be called only in a death test child process. -// Writes a status byte to the child's status file descriptor, then -// calls _exit(1). -void DeathTestImpl::Abort(AbortReason reason) { - // The parent process considers the death test to be a failure if - // it finds any data in our pipe. So, here we write a single flag byte - // to the pipe, then exit. - const char status_ch = - reason == TEST_DID_NOT_DIE ? kDeathTestLived : - reason == TEST_THREW_EXCEPTION ? kDeathTestThrew : kDeathTestReturned; - - GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Write(write_fd(), &status_ch, 1)); - // We are leaking the descriptor here because on some platforms (i.e., - // when built as Windows DLL), destructors of global objects will still - // run after calling _exit(). On such systems, write_fd_ will be - // indirectly closed from the destructor of UnitTestImpl, causing double - // close if it is also closed here. On debug configurations, double close - // may assert. As there are no in-process buffers to flush here, we are - // relying on the OS to close the descriptor after the process terminates - // when the destructors are not run. - _exit(1); // Exits w/o any normal exit hooks (we were supposed to crash) -} - -// Returns an indented copy of stderr output for a death test. -// This makes distinguishing death test output lines from regular log lines -// much easier. -static ::std::string FormatDeathTestOutput(const ::std::string& output) { - ::std::string ret; - for (size_t at = 0; ; ) { - const size_t line_end = output.find('\n', at); - ret += "[ DEATH ] "; - if (line_end == ::std::string::npos) { - ret += output.substr(at); - break; - } - ret += output.substr(at, line_end + 1 - at); - at = line_end + 1; - } - return ret; -} - -// Assesses the success or failure of a death test, using both private -// members which have previously been set, and one argument: -// -// Private data members: -// outcome: An enumeration describing how the death test -// concluded: DIED, LIVED, THREW, or RETURNED. The death test -// fails in the latter three cases. -// status: The exit status of the child process. On *nix, it is in the -// in the format specified by wait(2). On Windows, this is the -// value supplied to the ExitProcess() API or a numeric code -// of the exception that terminated the program. -// regex: A regular expression object to be applied to -// the test's captured standard error output; the death test -// fails if it does not match. -// -// Argument: -// status_ok: true if exit_status is acceptable in the context of -// this particular death test, which fails if it is false -// -// Returns true iff all of the above conditions are met. Otherwise, the -// first failing condition, in the order given above, is the one that is -// reported. Also sets the last death test message string. -bool DeathTestImpl::Passed(bool status_ok) { - if (!spawned()) - return false; - - const std::string error_message = GetCapturedStderr(); - - bool success = false; - Message buffer; - - buffer << "Death test: " << statement() << "\n"; - switch (outcome()) { - case LIVED: - buffer << " Result: failed to die.\n" - << " Error msg:\n" << FormatDeathTestOutput(error_message); - break; - case THREW: - buffer << " Result: threw an exception.\n" - << " Error msg:\n" << FormatDeathTestOutput(error_message); - break; - case RETURNED: - buffer << " Result: illegal return in test statement.\n" - << " Error msg:\n" << FormatDeathTestOutput(error_message); - break; - case DIED: - if (status_ok) { - const bool matched = RE::PartialMatch(error_message.c_str(), *regex()); - if (matched) { - success = true; - } else { - buffer << " Result: died but not with expected error.\n" - << " Expected: " << regex()->pattern() << "\n" - << "Actual msg:\n" << FormatDeathTestOutput(error_message); - } - } else { - buffer << " Result: died but not with expected exit code:\n" - << " " << ExitSummary(status()) << "\n" - << "Actual msg:\n" << FormatDeathTestOutput(error_message); - } - break; - case IN_PROGRESS: - default: - GTEST_LOG_(FATAL) - << "DeathTest::Passed somehow called before conclusion of test"; - } - - DeathTest::set_last_death_test_message(buffer.GetString()); - return success; -} - -# if GTEST_OS_WINDOWS -// WindowsDeathTest implements death tests on Windows. Due to the -// specifics of starting new processes on Windows, death tests there are -// always threadsafe, and Google Test considers the -// --gtest_death_test_style=fast setting to be equivalent to -// --gtest_death_test_style=threadsafe there. -// -// A few implementation notes: Like the Linux version, the Windows -// implementation uses pipes for child-to-parent communication. But due to -// the specifics of pipes on Windows, some extra steps are required: -// -// 1. The parent creates a communication pipe and stores handles to both -// ends of it. -// 2. The parent starts the child and provides it with the information -// necessary to acquire the handle to the write end of the pipe. -// 3. The child acquires the write end of the pipe and signals the parent -// using a Windows event. -// 4. Now the parent can release the write end of the pipe on its side. If -// this is done before step 3, the object's reference count goes down to -// 0 and it is destroyed, preventing the child from acquiring it. The -// parent now has to release it, or read operations on the read end of -// the pipe will not return when the child terminates. -// 5. The parent reads child's output through the pipe (outcome code and -// any possible error messages) from the pipe, and its stderr and then -// determines whether to fail the test. -// -// Note: to distinguish Win32 API calls from the local method and function -// calls, the former are explicitly resolved in the global namespace. -// -class WindowsDeathTest : public DeathTestImpl { - public: - WindowsDeathTest(const char* a_statement, - const RE* a_regex, - const char* file, - int line) - : DeathTestImpl(a_statement, a_regex), file_(file), line_(line) {} - - // All of these virtual functions are inherited from DeathTest. - virtual int Wait(); - virtual TestRole AssumeRole(); - - private: - // The name of the file in which the death test is located. - const char* const file_; - // The line number on which the death test is located. - const int line_; - // Handle to the write end of the pipe to the child process. - AutoHandle write_handle_; - // Child process handle. - AutoHandle child_handle_; - // Event the child process uses to signal the parent that it has - // acquired the handle to the write end of the pipe. After seeing this - // event the parent can release its own handles to make sure its - // ReadFile() calls return when the child terminates. - AutoHandle event_handle_; -}; - -// Waits for the child in a death test to exit, returning its exit -// status, or 0 if no child process exists. As a side effect, sets the -// outcome data member. -int WindowsDeathTest::Wait() { - if (!spawned()) - return 0; - - // Wait until the child either signals that it has acquired the write end - // of the pipe or it dies. - const HANDLE wait_handles[2] = { child_handle_.Get(), event_handle_.Get() }; - switch (::WaitForMultipleObjects(2, - wait_handles, - FALSE, // Waits for any of the handles. - INFINITE)) { - case WAIT_OBJECT_0: - case WAIT_OBJECT_0 + 1: - break; - default: - GTEST_DEATH_TEST_CHECK_(false); // Should not get here. - } - - // The child has acquired the write end of the pipe or exited. - // We release the handle on our side and continue. - write_handle_.Reset(); - event_handle_.Reset(); - - ReadAndInterpretStatusByte(); - - // Waits for the child process to exit if it haven't already. This - // returns immediately if the child has already exited, regardless of - // whether previous calls to WaitForMultipleObjects synchronized on this - // handle or not. - GTEST_DEATH_TEST_CHECK_( - WAIT_OBJECT_0 == ::WaitForSingleObject(child_handle_.Get(), - INFINITE)); - DWORD status_code; - GTEST_DEATH_TEST_CHECK_( - ::GetExitCodeProcess(child_handle_.Get(), &status_code) != FALSE); - child_handle_.Reset(); - set_status(static_cast(status_code)); - return status(); -} - -// The AssumeRole process for a Windows death test. It creates a child -// process with the same executable as the current process to run the -// death test. The child process is given the --gtest_filter and -// --gtest_internal_run_death_test flags such that it knows to run the -// current death test only. -DeathTest::TestRole WindowsDeathTest::AssumeRole() { - const UnitTestImpl* const impl = GetUnitTestImpl(); - const InternalRunDeathTestFlag* const flag = - impl->internal_run_death_test_flag(); - const TestInfo* const info = impl->current_test_info(); - const int death_test_index = info->result()->death_test_count(); - - if (flag != NULL) { - // ParseInternalRunDeathTestFlag() has performed all the necessary - // processing. - set_write_fd(flag->write_fd()); - return EXECUTE_TEST; - } - - // WindowsDeathTest uses an anonymous pipe to communicate results of - // a death test. - SECURITY_ATTRIBUTES handles_are_inheritable = { - sizeof(SECURITY_ATTRIBUTES), NULL, TRUE }; - HANDLE read_handle, write_handle; - GTEST_DEATH_TEST_CHECK_( - ::CreatePipe(&read_handle, &write_handle, &handles_are_inheritable, - 0) // Default buffer size. - != FALSE); - set_read_fd(::_open_osfhandle(reinterpret_cast(read_handle), - O_RDONLY)); - write_handle_.Reset(write_handle); - event_handle_.Reset(::CreateEvent( - &handles_are_inheritable, - TRUE, // The event will automatically reset to non-signaled state. - FALSE, // The initial state is non-signalled. - NULL)); // The even is unnamed. - GTEST_DEATH_TEST_CHECK_(event_handle_.Get() != NULL); - const std::string filter_flag = - std::string("--") + GTEST_FLAG_PREFIX_ + kFilterFlag + "=" + - info->test_case_name() + "." + info->name(); - const std::string internal_flag = - std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag + - "=" + file_ + "|" + StreamableToString(line_) + "|" + - StreamableToString(death_test_index) + "|" + - StreamableToString(static_cast(::GetCurrentProcessId())) + - // size_t has the same width as pointers on both 32-bit and 64-bit - // Windows platforms. - // See http://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx. - "|" + StreamableToString(reinterpret_cast(write_handle)) + - "|" + StreamableToString(reinterpret_cast(event_handle_.Get())); - - char executable_path[_MAX_PATH + 1]; // NOLINT - GTEST_DEATH_TEST_CHECK_( - _MAX_PATH + 1 != ::GetModuleFileNameA(NULL, - executable_path, - _MAX_PATH)); - - std::string command_line = - std::string(::GetCommandLineA()) + " " + filter_flag + " \"" + - internal_flag + "\""; - - DeathTest::set_last_death_test_message(""); - - CaptureStderr(); - // Flush the log buffers since the log streams are shared with the child. - FlushInfoLog(); - - // The child process will share the standard handles with the parent. - STARTUPINFOA startup_info; - memset(&startup_info, 0, sizeof(STARTUPINFO)); - startup_info.dwFlags = STARTF_USESTDHANDLES; - startup_info.hStdInput = ::GetStdHandle(STD_INPUT_HANDLE); - startup_info.hStdOutput = ::GetStdHandle(STD_OUTPUT_HANDLE); - startup_info.hStdError = ::GetStdHandle(STD_ERROR_HANDLE); - - PROCESS_INFORMATION process_info; - GTEST_DEATH_TEST_CHECK_(::CreateProcessA( - executable_path, - const_cast(command_line.c_str()), - NULL, // Retuned process handle is not inheritable. - NULL, // Retuned thread handle is not inheritable. - TRUE, // Child inherits all inheritable handles (for write_handle_). - 0x0, // Default creation flags. - NULL, // Inherit the parent's environment. - UnitTest::GetInstance()->original_working_dir(), - &startup_info, - &process_info) != FALSE); - child_handle_.Reset(process_info.hProcess); - ::CloseHandle(process_info.hThread); - set_spawned(true); - return OVERSEE_TEST; -} -# else // We are not on Windows. - -// ForkingDeathTest provides implementations for most of the abstract -// methods of the DeathTest interface. Only the AssumeRole method is -// left undefined. -class ForkingDeathTest : public DeathTestImpl { - public: - ForkingDeathTest(const char* statement, const RE* regex); - - // All of these virtual functions are inherited from DeathTest. - virtual int Wait(); - - protected: - void set_child_pid(pid_t child_pid) { child_pid_ = child_pid; } - - private: - // PID of child process during death test; 0 in the child process itself. - pid_t child_pid_; -}; - -// Constructs a ForkingDeathTest. -ForkingDeathTest::ForkingDeathTest(const char* a_statement, const RE* a_regex) - : DeathTestImpl(a_statement, a_regex), - child_pid_(-1) {} - -// Waits for the child in a death test to exit, returning its exit -// status, or 0 if no child process exists. As a side effect, sets the -// outcome data member. -int ForkingDeathTest::Wait() { - if (!spawned()) - return 0; - - ReadAndInterpretStatusByte(); - - int status_value; - GTEST_DEATH_TEST_CHECK_SYSCALL_(waitpid(child_pid_, &status_value, 0)); - set_status(status_value); - return status_value; -} - -// A concrete death test class that forks, then immediately runs the test -// in the child process. -class NoExecDeathTest : public ForkingDeathTest { - public: - NoExecDeathTest(const char* a_statement, const RE* a_regex) : - ForkingDeathTest(a_statement, a_regex) { } - virtual TestRole AssumeRole(); -}; - -// The AssumeRole process for a fork-and-run death test. It implements a -// straightforward fork, with a simple pipe to transmit the status byte. -DeathTest::TestRole NoExecDeathTest::AssumeRole() { - const size_t thread_count = GetThreadCount(); - if (thread_count != 1) { - GTEST_LOG_(WARNING) << DeathTestThreadWarning(thread_count); - } - - int pipe_fd[2]; - GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1); - - DeathTest::set_last_death_test_message(""); - CaptureStderr(); - // When we fork the process below, the log file buffers are copied, but the - // file descriptors are shared. We flush all log files here so that closing - // the file descriptors in the child process doesn't throw off the - // synchronization between descriptors and buffers in the parent process. - // This is as close to the fork as possible to avoid a race condition in case - // there are multiple threads running before the death test, and another - // thread writes to the log file. - FlushInfoLog(); - - const pid_t child_pid = fork(); - GTEST_DEATH_TEST_CHECK_(child_pid != -1); - set_child_pid(child_pid); - if (child_pid == 0) { - GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[0])); - set_write_fd(pipe_fd[1]); - // Redirects all logging to stderr in the child process to prevent - // concurrent writes to the log files. We capture stderr in the parent - // process and append the child process' output to a log. - LogToStderr(); - // Event forwarding to the listeners of event listener API mush be shut - // down in death test subprocesses. - GetUnitTestImpl()->listeners()->SuppressEventForwarding(); - g_in_fast_death_test_child = true; - return EXECUTE_TEST; - } else { - GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); - set_read_fd(pipe_fd[0]); - set_spawned(true); - return OVERSEE_TEST; - } -} - -// A concrete death test class that forks and re-executes the main -// program from the beginning, with command-line flags set that cause -// only this specific death test to be run. -class ExecDeathTest : public ForkingDeathTest { - public: - ExecDeathTest(const char* a_statement, const RE* a_regex, - const char* file, int line) : - ForkingDeathTest(a_statement, a_regex), file_(file), line_(line) { } - virtual TestRole AssumeRole(); - private: - static ::std::vector - GetArgvsForDeathTestChildProcess() { - ::std::vector args = GetInjectableArgvs(); - return args; - } - // The name of the file in which the death test is located. - const char* const file_; - // The line number on which the death test is located. - const int line_; -}; - -// Utility class for accumulating command-line arguments. -class Arguments { - public: - Arguments() { - args_.push_back(NULL); - } - - ~Arguments() { - for (std::vector::iterator i = args_.begin(); i != args_.end(); - ++i) { - free(*i); - } - } - void AddArgument(const char* argument) { - args_.insert(args_.end() - 1, posix::StrDup(argument)); - } - - template - void AddArguments(const ::std::vector& arguments) { - for (typename ::std::vector::const_iterator i = arguments.begin(); - i != arguments.end(); - ++i) { - args_.insert(args_.end() - 1, posix::StrDup(i->c_str())); - } - } - char* const* Argv() { - return &args_[0]; - } - - private: - std::vector args_; -}; - -// A struct that encompasses the arguments to the child process of a -// threadsafe-style death test process. -struct ExecDeathTestArgs { - char* const* argv; // Command-line arguments for the child's call to exec - int close_fd; // File descriptor to close; the read end of a pipe -}; - -# if GTEST_OS_MAC -inline char** GetEnviron() { - // When Google Test is built as a framework on MacOS X, the environ variable - // is unavailable. Apple's documentation (man environ) recommends using - // _NSGetEnviron() instead. - return *_NSGetEnviron(); -} -# else -// Some POSIX platforms expect you to declare environ. extern "C" makes -// it reside in the global namespace. -extern "C" char** environ; -inline char** GetEnviron() { return environ; } -# endif // GTEST_OS_MAC - -# if !GTEST_OS_QNX -// The main function for a threadsafe-style death test child process. -// This function is called in a clone()-ed process and thus must avoid -// any potentially unsafe operations like malloc or libc functions. -static int ExecDeathTestChildMain(void* child_arg) { - ExecDeathTestArgs* const args = static_cast(child_arg); - GTEST_DEATH_TEST_CHECK_SYSCALL_(close(args->close_fd)); - - // We need to execute the test program in the same environment where - // it was originally invoked. Therefore we change to the original - // working directory first. - const char* const original_dir = - UnitTest::GetInstance()->original_working_dir(); - // We can safely call chdir() as it's a direct system call. - if (chdir(original_dir) != 0) { - DeathTestAbort(std::string("chdir(\"") + original_dir + "\") failed: " + - GetLastErrnoDescription()); - return EXIT_FAILURE; - } - - // We can safely call execve() as it's a direct system call. We - // cannot use execvp() as it's a libc function and thus potentially - // unsafe. Since execve() doesn't search the PATH, the user must - // invoke the test program via a valid path that contains at least - // one path separator. - execve(args->argv[0], args->argv, GetEnviron()); - DeathTestAbort(std::string("execve(") + args->argv[0] + ", ...) in " + - original_dir + " failed: " + - GetLastErrnoDescription()); - return EXIT_FAILURE; -} -# endif // !GTEST_OS_QNX - -// Two utility routines that together determine the direction the stack -// grows. -// This could be accomplished more elegantly by a single recursive -// function, but we want to guard against the unlikely possibility of -// a smart compiler optimizing the recursion away. -// -// GTEST_NO_INLINE_ is required to prevent GCC 4.6 from inlining -// StackLowerThanAddress into StackGrowsDown, which then doesn't give -// correct answer. -void StackLowerThanAddress(const void* ptr, bool* result) GTEST_NO_INLINE_; -void StackLowerThanAddress(const void* ptr, bool* result) { - int dummy; - *result = (&dummy < ptr); -} - -bool StackGrowsDown() { - int dummy; - bool result; - StackLowerThanAddress(&dummy, &result); - return result; -} - -// Spawns a child process with the same executable as the current process in -// a thread-safe manner and instructs it to run the death test. The -// implementation uses fork(2) + exec. On systems where clone(2) is -// available, it is used instead, being slightly more thread-safe. On QNX, -// fork supports only single-threaded environments, so this function uses -// spawn(2) there instead. The function dies with an error message if -// anything goes wrong. -static pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) { - ExecDeathTestArgs args = { argv, close_fd }; - pid_t child_pid = -1; - -# if GTEST_OS_QNX - // Obtains the current directory and sets it to be closed in the child - // process. - const int cwd_fd = open(".", O_RDONLY); - GTEST_DEATH_TEST_CHECK_(cwd_fd != -1); - GTEST_DEATH_TEST_CHECK_SYSCALL_(fcntl(cwd_fd, F_SETFD, FD_CLOEXEC)); - // We need to execute the test program in the same environment where - // it was originally invoked. Therefore we change to the original - // working directory first. - const char* const original_dir = - UnitTest::GetInstance()->original_working_dir(); - // We can safely call chdir() as it's a direct system call. - if (chdir(original_dir) != 0) { - DeathTestAbort(std::string("chdir(\"") + original_dir + "\") failed: " + - GetLastErrnoDescription()); - return EXIT_FAILURE; - } - - int fd_flags; - // Set close_fd to be closed after spawn. - GTEST_DEATH_TEST_CHECK_SYSCALL_(fd_flags = fcntl(close_fd, F_GETFD)); - GTEST_DEATH_TEST_CHECK_SYSCALL_(fcntl(close_fd, F_SETFD, - fd_flags | FD_CLOEXEC)); - struct inheritance inherit = {0}; - // spawn is a system call. - child_pid = spawn(args.argv[0], 0, NULL, &inherit, args.argv, GetEnviron()); - // Restores the current working directory. - GTEST_DEATH_TEST_CHECK_(fchdir(cwd_fd) != -1); - GTEST_DEATH_TEST_CHECK_SYSCALL_(close(cwd_fd)); - -# else // GTEST_OS_QNX -# if GTEST_OS_LINUX - // When a SIGPROF signal is received while fork() or clone() are executing, - // the process may hang. To avoid this, we ignore SIGPROF here and re-enable - // it after the call to fork()/clone() is complete. - struct sigaction saved_sigprof_action; - struct sigaction ignore_sigprof_action; - memset(&ignore_sigprof_action, 0, sizeof(ignore_sigprof_action)); - sigemptyset(&ignore_sigprof_action.sa_mask); - ignore_sigprof_action.sa_handler = SIG_IGN; - GTEST_DEATH_TEST_CHECK_SYSCALL_(sigaction( - SIGPROF, &ignore_sigprof_action, &saved_sigprof_action)); -# endif // GTEST_OS_LINUX - -# if GTEST_HAS_CLONE - const bool use_fork = GTEST_FLAG(death_test_use_fork); - - if (!use_fork) { - static const bool stack_grows_down = StackGrowsDown(); - const size_t stack_size = getpagesize(); - // MMAP_ANONYMOUS is not defined on Mac, so we use MAP_ANON instead. - void* const stack = mmap(NULL, stack_size, PROT_READ | PROT_WRITE, - MAP_ANON | MAP_PRIVATE, -1, 0); - GTEST_DEATH_TEST_CHECK_(stack != MAP_FAILED); - - // Maximum stack alignment in bytes: For a downward-growing stack, this - // amount is subtracted from size of the stack space to get an address - // that is within the stack space and is aligned on all systems we care - // about. As far as I know there is no ABI with stack alignment greater - // than 64. We assume stack and stack_size already have alignment of - // kMaxStackAlignment. - const size_t kMaxStackAlignment = 64; - void* const stack_top = - static_cast(stack) + - (stack_grows_down ? stack_size - kMaxStackAlignment : 0); - GTEST_DEATH_TEST_CHECK_(stack_size > kMaxStackAlignment && - reinterpret_cast(stack_top) % kMaxStackAlignment == 0); - - child_pid = clone(&ExecDeathTestChildMain, stack_top, SIGCHLD, &args); - - GTEST_DEATH_TEST_CHECK_(munmap(stack, stack_size) != -1); - } -# else - const bool use_fork = true; -# endif // GTEST_HAS_CLONE - - if (use_fork && (child_pid = fork()) == 0) { - ExecDeathTestChildMain(&args); - _exit(0); - } -# endif // GTEST_OS_QNX -# if GTEST_OS_LINUX - GTEST_DEATH_TEST_CHECK_SYSCALL_( - sigaction(SIGPROF, &saved_sigprof_action, NULL)); -# endif // GTEST_OS_LINUX - - GTEST_DEATH_TEST_CHECK_(child_pid != -1); - return child_pid; -} - -// The AssumeRole process for a fork-and-exec death test. It re-executes the -// main program from the beginning, setting the --gtest_filter -// and --gtest_internal_run_death_test flags to cause only the current -// death test to be re-run. -DeathTest::TestRole ExecDeathTest::AssumeRole() { - const UnitTestImpl* const impl = GetUnitTestImpl(); - const InternalRunDeathTestFlag* const flag = - impl->internal_run_death_test_flag(); - const TestInfo* const info = impl->current_test_info(); - const int death_test_index = info->result()->death_test_count(); - - if (flag != NULL) { - set_write_fd(flag->write_fd()); - return EXECUTE_TEST; - } - - int pipe_fd[2]; - GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1); - // Clear the close-on-exec flag on the write end of the pipe, lest - // it be closed when the child process does an exec: - GTEST_DEATH_TEST_CHECK_(fcntl(pipe_fd[1], F_SETFD, 0) != -1); - - const std::string filter_flag = - std::string("--") + GTEST_FLAG_PREFIX_ + kFilterFlag + "=" - + info->test_case_name() + "." + info->name(); - const std::string internal_flag = - std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag + "=" - + file_ + "|" + StreamableToString(line_) + "|" - + StreamableToString(death_test_index) + "|" - + StreamableToString(pipe_fd[1]); - Arguments args; - args.AddArguments(GetArgvsForDeathTestChildProcess()); - args.AddArgument(filter_flag.c_str()); - args.AddArgument(internal_flag.c_str()); - - DeathTest::set_last_death_test_message(""); - - CaptureStderr(); - // See the comment in NoExecDeathTest::AssumeRole for why the next line - // is necessary. - FlushInfoLog(); - - const pid_t child_pid = ExecDeathTestSpawnChild(args.Argv(), pipe_fd[0]); - GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); - set_child_pid(child_pid); - set_read_fd(pipe_fd[0]); - set_spawned(true); - return OVERSEE_TEST; -} - -# endif // !GTEST_OS_WINDOWS - -// Creates a concrete DeathTest-derived class that depends on the -// --gtest_death_test_style flag, and sets the pointer pointed to -// by the "test" argument to its address. If the test should be -// skipped, sets that pointer to NULL. Returns true, unless the -// flag is set to an invalid value. -bool DefaultDeathTestFactory::Create(const char* statement, const RE* regex, - const char* file, int line, - DeathTest** test) { - UnitTestImpl* const impl = GetUnitTestImpl(); - const InternalRunDeathTestFlag* const flag = - impl->internal_run_death_test_flag(); - const int death_test_index = impl->current_test_info() - ->increment_death_test_count(); - - if (flag != NULL) { - if (death_test_index > flag->index()) { - DeathTest::set_last_death_test_message( - "Death test count (" + StreamableToString(death_test_index) - + ") somehow exceeded expected maximum (" - + StreamableToString(flag->index()) + ")"); - return false; - } - - if (!(flag->file() == file && flag->line() == line && - flag->index() == death_test_index)) { - *test = NULL; - return true; - } - } - -# if GTEST_OS_WINDOWS - - if (GTEST_FLAG(death_test_style) == "threadsafe" || - GTEST_FLAG(death_test_style) == "fast") { - *test = new WindowsDeathTest(statement, regex, file, line); - } - -# else - - if (GTEST_FLAG(death_test_style) == "threadsafe") { - *test = new ExecDeathTest(statement, regex, file, line); - } else if (GTEST_FLAG(death_test_style) == "fast") { - *test = new NoExecDeathTest(statement, regex); - } - -# endif // GTEST_OS_WINDOWS - - else { // NOLINT - this is more readable than unbalanced brackets inside #if. - DeathTest::set_last_death_test_message( - "Unknown death test style \"" + GTEST_FLAG(death_test_style) - + "\" encountered"); - return false; - } - - return true; -} - -// Splits a given string on a given delimiter, populating a given -// vector with the fields. GTEST_HAS_DEATH_TEST implies that we have -// ::std::string, so we can use it here. -static void SplitString(const ::std::string& str, char delimiter, - ::std::vector< ::std::string>* dest) { - ::std::vector< ::std::string> parsed; - ::std::string::size_type pos = 0; - while (::testing::internal::AlwaysTrue()) { - const ::std::string::size_type colon = str.find(delimiter, pos); - if (colon == ::std::string::npos) { - parsed.push_back(str.substr(pos)); - break; - } else { - parsed.push_back(str.substr(pos, colon - pos)); - pos = colon + 1; - } - } - dest->swap(parsed); -} - -# if GTEST_OS_WINDOWS -// Recreates the pipe and event handles from the provided parameters, -// signals the event, and returns a file descriptor wrapped around the pipe -// handle. This function is called in the child process only. -int GetStatusFileDescriptor(unsigned int parent_process_id, - size_t write_handle_as_size_t, - size_t event_handle_as_size_t) { - AutoHandle parent_process_handle(::OpenProcess(PROCESS_DUP_HANDLE, - FALSE, // Non-inheritable. - parent_process_id)); - if (parent_process_handle.Get() == INVALID_HANDLE_VALUE) { - DeathTestAbort("Unable to open parent process " + - StreamableToString(parent_process_id)); - } - - // TODO(vladl@google.com): Replace the following check with a - // compile-time assertion when available. - GTEST_CHECK_(sizeof(HANDLE) <= sizeof(size_t)); - - const HANDLE write_handle = - reinterpret_cast(write_handle_as_size_t); - HANDLE dup_write_handle; - - // The newly initialized handle is accessible only in in the parent - // process. To obtain one accessible within the child, we need to use - // DuplicateHandle. - if (!::DuplicateHandle(parent_process_handle.Get(), write_handle, - ::GetCurrentProcess(), &dup_write_handle, - 0x0, // Requested privileges ignored since - // DUPLICATE_SAME_ACCESS is used. - FALSE, // Request non-inheritable handler. - DUPLICATE_SAME_ACCESS)) { - DeathTestAbort("Unable to duplicate the pipe handle " + - StreamableToString(write_handle_as_size_t) + - " from the parent process " + - StreamableToString(parent_process_id)); - } - - const HANDLE event_handle = reinterpret_cast(event_handle_as_size_t); - HANDLE dup_event_handle; - - if (!::DuplicateHandle(parent_process_handle.Get(), event_handle, - ::GetCurrentProcess(), &dup_event_handle, - 0x0, - FALSE, - DUPLICATE_SAME_ACCESS)) { - DeathTestAbort("Unable to duplicate the event handle " + - StreamableToString(event_handle_as_size_t) + - " from the parent process " + - StreamableToString(parent_process_id)); - } - - const int write_fd = - ::_open_osfhandle(reinterpret_cast(dup_write_handle), O_APPEND); - if (write_fd == -1) { - DeathTestAbort("Unable to convert pipe handle " + - StreamableToString(write_handle_as_size_t) + - " to a file descriptor"); - } - - // Signals the parent that the write end of the pipe has been acquired - // so the parent can release its own write end. - ::SetEvent(dup_event_handle); - - return write_fd; -} -# endif // GTEST_OS_WINDOWS - -// Returns a newly created InternalRunDeathTestFlag object with fields -// initialized from the GTEST_FLAG(internal_run_death_test) flag if -// the flag is specified; otherwise returns NULL. -InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() { - if (GTEST_FLAG(internal_run_death_test) == "") return NULL; - - // GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we - // can use it here. - int line = -1; - int index = -1; - ::std::vector< ::std::string> fields; - SplitString(GTEST_FLAG(internal_run_death_test).c_str(), '|', &fields); - int write_fd = -1; - -# if GTEST_OS_WINDOWS - - unsigned int parent_process_id = 0; - size_t write_handle_as_size_t = 0; - size_t event_handle_as_size_t = 0; - - if (fields.size() != 6 - || !ParseNaturalNumber(fields[1], &line) - || !ParseNaturalNumber(fields[2], &index) - || !ParseNaturalNumber(fields[3], &parent_process_id) - || !ParseNaturalNumber(fields[4], &write_handle_as_size_t) - || !ParseNaturalNumber(fields[5], &event_handle_as_size_t)) { - DeathTestAbort("Bad --gtest_internal_run_death_test flag: " + - GTEST_FLAG(internal_run_death_test)); - } - write_fd = GetStatusFileDescriptor(parent_process_id, - write_handle_as_size_t, - event_handle_as_size_t); -# else - - if (fields.size() != 4 - || !ParseNaturalNumber(fields[1], &line) - || !ParseNaturalNumber(fields[2], &index) - || !ParseNaturalNumber(fields[3], &write_fd)) { - DeathTestAbort("Bad --gtest_internal_run_death_test flag: " - + GTEST_FLAG(internal_run_death_test)); - } - -# endif // GTEST_OS_WINDOWS - - return new InternalRunDeathTestFlag(fields[0], line, index, write_fd); -} - -} // namespace internal - -#endif // GTEST_HAS_DEATH_TEST - -} // namespace testing -// Copyright 2008, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Authors: keith.ray@gmail.com (Keith Ray) - - -#include - -#if GTEST_OS_WINDOWS_MOBILE -# include -#elif GTEST_OS_WINDOWS -# include -# include -#elif GTEST_OS_SYMBIAN -// Symbian OpenC has PATH_MAX in sys/syslimits.h -# include -#else -# include -# include // Some Linux distributions define PATH_MAX here. -#endif // GTEST_OS_WINDOWS_MOBILE - -#if GTEST_OS_WINDOWS -# define GTEST_PATH_MAX_ _MAX_PATH -#elif defined(PATH_MAX) -# define GTEST_PATH_MAX_ PATH_MAX -#elif defined(_XOPEN_PATH_MAX) -# define GTEST_PATH_MAX_ _XOPEN_PATH_MAX -#else -# define GTEST_PATH_MAX_ _POSIX_PATH_MAX -#endif // GTEST_OS_WINDOWS - - -namespace testing { -namespace internal { - -#if GTEST_OS_WINDOWS -// On Windows, '\\' is the standard path separator, but many tools and the -// Windows API also accept '/' as an alternate path separator. Unless otherwise -// noted, a file path can contain either kind of path separators, or a mixture -// of them. -const char kPathSeparator = '\\'; -const char kAlternatePathSeparator = '/'; -//const char kPathSeparatorString[] = "\\"; -const char kAlternatePathSeparatorString[] = "/"; -# if GTEST_OS_WINDOWS_MOBILE -// Windows CE doesn't have a current directory. You should not use -// the current directory in tests on Windows CE, but this at least -// provides a reasonable fallback. -const char kCurrentDirectoryString[] = "\\"; -// Windows CE doesn't define INVALID_FILE_ATTRIBUTES -const DWORD kInvalidFileAttributes = 0xffffffff; -# else -const char kCurrentDirectoryString[] = ".\\"; -# endif // GTEST_OS_WINDOWS_MOBILE -#else -const char kPathSeparator = '/'; -//const char kPathSeparatorString[] = "/"; -const char kCurrentDirectoryString[] = "./"; -#endif // GTEST_OS_WINDOWS - -// Returns whether the given character is a valid path separator. -static bool IsPathSeparator(char c) { -#if GTEST_HAS_ALT_PATH_SEP_ - return (c == kPathSeparator) || (c == kAlternatePathSeparator); -#else - return c == kPathSeparator; -#endif -} - -// Returns the current working directory, or "" if unsuccessful. -FilePath FilePath::GetCurrentDir() { -#if GTEST_OS_WINDOWS_MOBILE - // Windows CE doesn't have a current directory, so we just return - // something reasonable. - return FilePath(kCurrentDirectoryString); -#elif GTEST_OS_WINDOWS - char cwd[GTEST_PATH_MAX_ + 1] = { '\0' }; - return FilePath(_getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd); -#else - char cwd[GTEST_PATH_MAX_ + 1] = { '\0' }; - return FilePath(getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd); -#endif // GTEST_OS_WINDOWS_MOBILE -} - -// Returns a copy of the FilePath with the case-insensitive extension removed. -// Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns -// FilePath("dir/file"). If a case-insensitive extension is not -// found, returns a copy of the original FilePath. -FilePath FilePath::RemoveExtension(const char* extension) const { - const std::string dot_extension = std::string(".") + extension; - if (String::EndsWithCaseInsensitive(pathname_, dot_extension)) { - return FilePath(pathname_.substr( - 0, pathname_.length() - dot_extension.length())); - } - return *this; -} - -// Returns a pointer to the last occurence of a valid path separator in -// the FilePath. On Windows, for example, both '/' and '\' are valid path -// separators. Returns NULL if no path separator was found. -const char* FilePath::FindLastPathSeparator() const { - const char* const last_sep = strrchr(c_str(), kPathSeparator); -#if GTEST_HAS_ALT_PATH_SEP_ - const char* const last_alt_sep = strrchr(c_str(), kAlternatePathSeparator); - // Comparing two pointers of which only one is NULL is undefined. - if (last_alt_sep != NULL && - (last_sep == NULL || last_alt_sep > last_sep)) { - return last_alt_sep; - } -#endif - return last_sep; -} - -// Returns a copy of the FilePath with the directory part removed. -// Example: FilePath("path/to/file").RemoveDirectoryName() returns -// FilePath("file"). If there is no directory part ("just_a_file"), it returns -// the FilePath unmodified. If there is no file part ("just_a_dir/") it -// returns an empty FilePath (""). -// On Windows platform, '\' is the path separator, otherwise it is '/'. -FilePath FilePath::RemoveDirectoryName() const { - const char* const last_sep = FindLastPathSeparator(); - return last_sep ? FilePath(last_sep + 1) : *this; -} - -// RemoveFileName returns the directory path with the filename removed. -// Example: FilePath("path/to/file").RemoveFileName() returns "path/to/". -// If the FilePath is "a_file" or "/a_file", RemoveFileName returns -// FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does -// not have a file, like "just/a/dir/", it returns the FilePath unmodified. -// On Windows platform, '\' is the path separator, otherwise it is '/'. -FilePath FilePath::RemoveFileName() const { - const char* const last_sep = FindLastPathSeparator(); - std::string dir; - if (last_sep) { - dir = std::string(c_str(), last_sep + 1 - c_str()); - } else { - dir = kCurrentDirectoryString; - } - return FilePath(dir); -} - -// Helper functions for naming files in a directory for xml output. - -// Given directory = "dir", base_name = "test", number = 0, -// extension = "xml", returns "dir/test.xml". If number is greater -// than zero (e.g., 12), returns "dir/test_12.xml". -// On Windows platform, uses \ as the separator rather than /. -FilePath FilePath::MakeFileName(const FilePath& directory, - const FilePath& base_name, - int number, - const char* extension) { - std::string file; - if (number == 0) { - file = base_name.string() + "." + extension; - } else { - file = base_name.string() + "_" + StreamableToString(number) - + "." + extension; - } - return ConcatPaths(directory, FilePath(file)); -} - -// Given directory = "dir", relative_path = "test.xml", returns "dir/test.xml". -// On Windows, uses \ as the separator rather than /. -FilePath FilePath::ConcatPaths(const FilePath& directory, - const FilePath& relative_path) { - if (directory.IsEmpty()) - return relative_path; - const FilePath dir(directory.RemoveTrailingPathSeparator()); - return FilePath(dir.string() + kPathSeparator + relative_path.string()); -} - -// Returns true if pathname describes something findable in the file-system, -// either a file, directory, or whatever. -bool FilePath::FileOrDirectoryExists() const { -#if GTEST_OS_WINDOWS_MOBILE - LPCWSTR unicode = String::AnsiToUtf16(pathname_.c_str()); - const DWORD attributes = GetFileAttributes(unicode); - delete [] unicode; - return attributes != kInvalidFileAttributes; -#else - posix::StatStruct file_stat; - return posix::Stat(pathname_.c_str(), &file_stat) == 0; -#endif // GTEST_OS_WINDOWS_MOBILE -} - -// Returns true if pathname describes a directory in the file-system -// that exists. -bool FilePath::DirectoryExists() const { - bool result = false; -#if GTEST_OS_WINDOWS - // Don't strip off trailing separator if path is a root directory on - // Windows (like "C:\\"). - const FilePath& path(IsRootDirectory() ? *this : - RemoveTrailingPathSeparator()); -#else - const FilePath& path(*this); -#endif - -#if GTEST_OS_WINDOWS_MOBILE - LPCWSTR unicode = String::AnsiToUtf16(path.c_str()); - const DWORD attributes = GetFileAttributes(unicode); - delete [] unicode; - if ((attributes != kInvalidFileAttributes) && - (attributes & FILE_ATTRIBUTE_DIRECTORY)) { - result = true; - } -#else - posix::StatStruct file_stat; - result = posix::Stat(path.c_str(), &file_stat) == 0 && - posix::IsDir(file_stat); -#endif // GTEST_OS_WINDOWS_MOBILE - - return result; -} - -// Returns true if pathname describes a root directory. (Windows has one -// root directory per disk drive.) -bool FilePath::IsRootDirectory() const { -#if GTEST_OS_WINDOWS - // TODO(wan@google.com): on Windows a network share like - // \\server\share can be a root directory, although it cannot be the - // current directory. Handle this properly. - return pathname_.length() == 3 && IsAbsolutePath(); -#else - return pathname_.length() == 1 && IsPathSeparator(pathname_.c_str()[0]); -#endif -} - -// Returns true if pathname describes an absolute path. -bool FilePath::IsAbsolutePath() const { - const char* const name = pathname_.c_str(); -#if GTEST_OS_WINDOWS - return pathname_.length() >= 3 && - ((name[0] >= 'a' && name[0] <= 'z') || - (name[0] >= 'A' && name[0] <= 'Z')) && - name[1] == ':' && - IsPathSeparator(name[2]); -#else - return IsPathSeparator(name[0]); -#endif -} - -// Returns a pathname for a file that does not currently exist. The pathname -// will be directory/base_name.extension or -// directory/base_name_.extension if directory/base_name.extension -// already exists. The number will be incremented until a pathname is found -// that does not already exist. -// Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'. -// There could be a race condition if two or more processes are calling this -// function at the same time -- they could both pick the same filename. -FilePath FilePath::GenerateUniqueFileName(const FilePath& directory, - const FilePath& base_name, - const char* extension) { - FilePath full_pathname; - int number = 0; - do { - full_pathname.Set(MakeFileName(directory, base_name, number++, extension)); - } while (full_pathname.FileOrDirectoryExists()); - return full_pathname; -} - -// Returns true if FilePath ends with a path separator, which indicates that -// it is intended to represent a directory. Returns false otherwise. -// This does NOT check that a directory (or file) actually exists. -bool FilePath::IsDirectory() const { - return !pathname_.empty() && - IsPathSeparator(pathname_.c_str()[pathname_.length() - 1]); -} - -// Create directories so that path exists. Returns true if successful or if -// the directories already exist; returns false if unable to create directories -// for any reason. -bool FilePath::CreateDirectoriesRecursively() const { - if (!this->IsDirectory()) { - return false; - } - - if (pathname_.length() == 0 || this->DirectoryExists()) { - return true; - } - - const FilePath parent(this->RemoveTrailingPathSeparator().RemoveFileName()); - return parent.CreateDirectoriesRecursively() && this->CreateFolder(); -} - -// Create the directory so that path exists. Returns true if successful or -// if the directory already exists; returns false if unable to create the -// directory for any reason, including if the parent directory does not -// exist. Not named "CreateDirectory" because that's a macro on Windows. -bool FilePath::CreateFolder() const { -#if GTEST_OS_WINDOWS_MOBILE - FilePath removed_sep(this->RemoveTrailingPathSeparator()); - LPCWSTR unicode = String::AnsiToUtf16(removed_sep.c_str()); - int result = CreateDirectory(unicode, NULL) ? 0 : -1; - delete [] unicode; -#elif GTEST_OS_WINDOWS - int result = _mkdir(pathname_.c_str()); -#else - int result = mkdir(pathname_.c_str(), 0777); -#endif // GTEST_OS_WINDOWS_MOBILE - - if (result == -1) { - return this->DirectoryExists(); // An error is OK if the directory exists. - } - return true; // No error. -} - -// If input name has a trailing separator character, remove it and return the -// name, otherwise return the name string unmodified. -// On Windows platform, uses \ as the separator, other platforms use /. -FilePath FilePath::RemoveTrailingPathSeparator() const { - return IsDirectory() - ? FilePath(pathname_.substr(0, pathname_.length() - 1)) - : *this; -} - -// Removes any redundant separators that might be in the pathname. -// For example, "bar///foo" becomes "bar/foo". Does not eliminate other -// redundancies that might be in a pathname involving "." or "..". -// TODO(wan@google.com): handle Windows network shares (e.g. \\server\share). -void FilePath::Normalize() { - if (pathname_.c_str() == NULL) { - pathname_ = ""; - return; - } - const char* src = pathname_.c_str(); - char* const dest = new char[pathname_.length() + 1]; - char* dest_ptr = dest; - memset(dest_ptr, 0, pathname_.length() + 1); - - while (*src != '\0') { - *dest_ptr = *src; - if (!IsPathSeparator(*src)) { - src++; - } else { -#if GTEST_HAS_ALT_PATH_SEP_ - if (*dest_ptr == kAlternatePathSeparator) { - *dest_ptr = kPathSeparator; - } -#endif - while (IsPathSeparator(*src)) - src++; - } - dest_ptr++; - } - *dest_ptr = '\0'; - pathname_ = dest; - delete[] dest; -} - -} // namespace internal -} // namespace testing -// Copyright 2008, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: wan@google.com (Zhanyong Wan) - - -#include -#include -#include -#include - -#if GTEST_OS_WINDOWS_MOBILE -# include // For TerminateProcess() -#elif GTEST_OS_WINDOWS -# include -# include -#else -# include -#endif // GTEST_OS_WINDOWS_MOBILE - -#if GTEST_OS_MAC -# include -# include -# include -#endif // GTEST_OS_MAC - -#if GTEST_OS_QNX -# include -# include -#endif // GTEST_OS_QNX - - -// Indicates that this translation unit is part of Google Test's -// implementation. It must come before gtest-internal-inl.h is -// included, or there will be a compiler error. This trick is to -// prevent a user from accidentally including gtest-internal-inl.h in -// his code. -#define GTEST_IMPLEMENTATION_ 1 -#undef GTEST_IMPLEMENTATION_ - -namespace testing { -namespace internal { - -#if defined(_MSC_VER) || defined(__BORLANDC__) -// MSVC and C++Builder do not provide a definition of STDERR_FILENO. -const int kStdOutFileno = 1; -const int kStdErrFileno = 2; -#else -const int kStdOutFileno = STDOUT_FILENO; -const int kStdErrFileno = STDERR_FILENO; -#endif // _MSC_VER - -#if GTEST_OS_MAC - -// Returns the number of threads running in the process, or 0 to indicate that -// we cannot detect it. -size_t GetThreadCount() { - const task_t task = mach_task_self(); - mach_msg_type_number_t thread_count; - thread_act_array_t thread_list; - const kern_return_t status = task_threads(task, &thread_list, &thread_count); - if (status == KERN_SUCCESS) { - // task_threads allocates resources in thread_list and we need to free them - // to avoid leaks. - vm_deallocate(task, - reinterpret_cast(thread_list), - sizeof(thread_t) * thread_count); - return static_cast(thread_count); - } else { - return 0; - } -} - -#elif GTEST_OS_QNX - -// Returns the number of threads running in the process, or 0 to indicate that -// we cannot detect it. -size_t GetThreadCount() { - const int fd = open("/proc/self/as", O_RDONLY); - if (fd < 0) { - return 0; - } - procfs_info process_info; - const int status = - devctl(fd, DCMD_PROC_INFO, &process_info, sizeof(process_info), NULL); - close(fd); - if (status == EOK) { - return static_cast(process_info.num_threads); - } else { - return 0; - } -} - -#else - -size_t GetThreadCount() { - // There's no portable way to detect the number of threads, so we just - // return 0 to indicate that we cannot detect it. - return 0; -} - -#endif // GTEST_OS_MAC - -#if GTEST_USES_POSIX_RE - -// Implements RE. Currently only needed for death tests. - -RE::~RE() { - if (is_valid_) { - // regfree'ing an invalid regex might crash because the content - // of the regex is undefined. Since the regex's are essentially - // the same, one cannot be valid (or invalid) without the other - // being so too. - regfree(&partial_regex_); - regfree(&full_regex_); - } - free(const_cast(pattern_)); -} - -// Returns true iff regular expression re matches the entire str. -bool RE::FullMatch(const char* str, const RE& re) { - if (!re.is_valid_) return false; - - regmatch_t match; - return regexec(&re.full_regex_, str, 1, &match, 0) == 0; -} - -// Returns true iff regular expression re matches a substring of str -// (including str itself). -bool RE::PartialMatch(const char* str, const RE& re) { - if (!re.is_valid_) return false; - - regmatch_t match; - return regexec(&re.partial_regex_, str, 1, &match, 0) == 0; -} - -// Initializes an RE from its string representation. -void RE::Init(const char* regex) { - pattern_ = posix::StrDup(regex); - - // Reserves enough bytes to hold the regular expression used for a - // full match. - const size_t full_regex_len = strlen(regex) + 10; - char* const full_pattern = new char[full_regex_len]; - - snprintf(full_pattern, full_regex_len, "^(%s)$", regex); - is_valid_ = regcomp(&full_regex_, full_pattern, REG_EXTENDED) == 0; - // We want to call regcomp(&partial_regex_, ...) even if the - // previous expression returns false. Otherwise partial_regex_ may - // not be properly initialized can may cause trouble when it's - // freed. - // - // Some implementation of POSIX regex (e.g. on at least some - // versions of Cygwin) doesn't accept the empty string as a valid - // regex. We change it to an equivalent form "()" to be safe. - if (is_valid_) { - const char* const partial_regex = (*regex == '\0') ? "()" : regex; - is_valid_ = regcomp(&partial_regex_, partial_regex, REG_EXTENDED) == 0; - } - EXPECT_TRUE(is_valid_) - << "Regular expression \"" << regex - << "\" is not a valid POSIX Extended regular expression."; - - delete[] full_pattern; -} - -#elif GTEST_USES_SIMPLE_RE - -// Returns true iff ch appears anywhere in str (excluding the -// terminating '\0' character). -bool IsInSet(char ch, const char* str) { - return ch != '\0' && strchr(str, ch) != NULL; -} - -// Returns true iff ch belongs to the given classification. Unlike -// similar functions in , these aren't affected by the -// current locale. -bool IsAsciiDigit(char ch) { return '0' <= ch && ch <= '9'; } -bool IsAsciiPunct(char ch) { - return IsInSet(ch, "^-!\"#$%&'()*+,./:;<=>?@[\\]_`{|}~"); -} -bool IsRepeat(char ch) { return IsInSet(ch, "?*+"); } -bool IsAsciiWhiteSpace(char ch) { return IsInSet(ch, " \f\n\r\t\v"); } -bool IsAsciiWordChar(char ch) { - return ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') || - ('0' <= ch && ch <= '9') || ch == '_'; -} - -// Returns true iff "\\c" is a supported escape sequence. -bool IsValidEscape(char c) { - return (IsAsciiPunct(c) || IsInSet(c, "dDfnrsStvwW")); -} - -// Returns true iff the given atom (specified by escaped and pattern) -// matches ch. The result is undefined if the atom is invalid. -bool AtomMatchesChar(bool escaped, char pattern_char, char ch) { - if (escaped) { // "\\p" where p is pattern_char. - switch (pattern_char) { - case 'd': return IsAsciiDigit(ch); - case 'D': return !IsAsciiDigit(ch); - case 'f': return ch == '\f'; - case 'n': return ch == '\n'; - case 'r': return ch == '\r'; - case 's': return IsAsciiWhiteSpace(ch); - case 'S': return !IsAsciiWhiteSpace(ch); - case 't': return ch == '\t'; - case 'v': return ch == '\v'; - case 'w': return IsAsciiWordChar(ch); - case 'W': return !IsAsciiWordChar(ch); - } - return IsAsciiPunct(pattern_char) && pattern_char == ch; - } - - return (pattern_char == '.' && ch != '\n') || pattern_char == ch; -} - -// Helper function used by ValidateRegex() to format error messages. -std::string FormatRegexSyntaxError(const char* regex, int index) { - return (Message() << "Syntax error at index " << index - << " in simple regular expression \"" << regex << "\": ").GetString(); -} - -// Generates non-fatal failures and returns false if regex is invalid; -// otherwise returns true. -bool ValidateRegex(const char* regex) { - if (regex == NULL) { - // TODO(wan@google.com): fix the source file location in the - // assertion failures to match where the regex is used in user - // code. - ADD_FAILURE() << "NULL is not a valid simple regular expression."; - return false; - } - - bool is_valid = true; - - // True iff ?, *, or + can follow the previous atom. - bool prev_repeatable = false; - for (int i = 0; regex[i]; i++) { - if (regex[i] == '\\') { // An escape sequence - i++; - if (regex[i] == '\0') { - ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1) - << "'\\' cannot appear at the end."; - return false; - } - - if (!IsValidEscape(regex[i])) { - ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1) - << "invalid escape sequence \"\\" << regex[i] << "\"."; - is_valid = false; - } - prev_repeatable = true; - } else { // Not an escape sequence. - const char ch = regex[i]; - - if (ch == '^' && i > 0) { - ADD_FAILURE() << FormatRegexSyntaxError(regex, i) - << "'^' can only appear at the beginning."; - is_valid = false; - } else if (ch == '$' && regex[i + 1] != '\0') { - ADD_FAILURE() << FormatRegexSyntaxError(regex, i) - << "'$' can only appear at the end."; - is_valid = false; - } else if (IsInSet(ch, "()[]{}|")) { - ADD_FAILURE() << FormatRegexSyntaxError(regex, i) - << "'" << ch << "' is unsupported."; - is_valid = false; - } else if (IsRepeat(ch) && !prev_repeatable) { - ADD_FAILURE() << FormatRegexSyntaxError(regex, i) - << "'" << ch << "' can only follow a repeatable token."; - is_valid = false; - } - - prev_repeatable = !IsInSet(ch, "^$?*+"); - } - } - - return is_valid; -} - -// Matches a repeated regex atom followed by a valid simple regular -// expression. The regex atom is defined as c if escaped is false, -// or \c otherwise. repeat is the repetition meta character (?, *, -// or +). The behavior is undefined if str contains too many -// characters to be indexable by size_t, in which case the test will -// probably time out anyway. We are fine with this limitation as -// std::string has it too. -bool MatchRepetitionAndRegexAtHead( - bool escaped, char c, char repeat, const char* regex, - const char* str) { - const size_t min_count = (repeat == '+') ? 1 : 0; - const size_t max_count = (repeat == '?') ? 1 : - static_cast(-1) - 1; - // We cannot call numeric_limits::max() as it conflicts with the - // max() macro on Windows. - - for (size_t i = 0; i <= max_count; ++i) { - // We know that the atom matches each of the first i characters in str. - if (i >= min_count && MatchRegexAtHead(regex, str + i)) { - // We have enough matches at the head, and the tail matches too. - // Since we only care about *whether* the pattern matches str - // (as opposed to *how* it matches), there is no need to find a - // greedy match. - return true; - } - if (str[i] == '\0' || !AtomMatchesChar(escaped, c, str[i])) - return false; - } - return false; -} - -// Returns true iff regex matches a prefix of str. regex must be a -// valid simple regular expression and not start with "^", or the -// result is undefined. -bool MatchRegexAtHead(const char* regex, const char* str) { - if (*regex == '\0') // An empty regex matches a prefix of anything. - return true; - - // "$" only matches the end of a string. Note that regex being - // valid guarantees that there's nothing after "$" in it. - if (*regex == '$') - return *str == '\0'; - - // Is the first thing in regex an escape sequence? - const bool escaped = *regex == '\\'; - if (escaped) - ++regex; - if (IsRepeat(regex[1])) { - // MatchRepetitionAndRegexAtHead() calls MatchRegexAtHead(), so - // here's an indirect recursion. It terminates as the regex gets - // shorter in each recursion. - return MatchRepetitionAndRegexAtHead( - escaped, regex[0], regex[1], regex + 2, str); - } else { - // regex isn't empty, isn't "$", and doesn't start with a - // repetition. We match the first atom of regex with the first - // character of str and recurse. - return (*str != '\0') && AtomMatchesChar(escaped, *regex, *str) && - MatchRegexAtHead(regex + 1, str + 1); - } -} - -// Returns true iff regex matches any substring of str. regex must be -// a valid simple regular expression, or the result is undefined. -// -// The algorithm is recursive, but the recursion depth doesn't exceed -// the regex length, so we won't need to worry about running out of -// stack space normally. In rare cases the time complexity can be -// exponential with respect to the regex length + the string length, -// but usually it's must faster (often close to linear). -bool MatchRegexAnywhere(const char* regex, const char* str) { - if (regex == NULL || str == NULL) - return false; - - if (*regex == '^') - return MatchRegexAtHead(regex + 1, str); - - // A successful match can be anywhere in str. - do { - if (MatchRegexAtHead(regex, str)) - return true; - } while (*str++ != '\0'); - return false; -} - -// Implements the RE class. - -RE::~RE() { - free(const_cast(pattern_)); - free(const_cast(full_pattern_)); -} - -// Returns true iff regular expression re matches the entire str. -bool RE::FullMatch(const char* str, const RE& re) { - return re.is_valid_ && MatchRegexAnywhere(re.full_pattern_, str); -} - -// Returns true iff regular expression re matches a substring of str -// (including str itself). -bool RE::PartialMatch(const char* str, const RE& re) { - return re.is_valid_ && MatchRegexAnywhere(re.pattern_, str); -} - -// Initializes an RE from its string representation. -void RE::Init(const char* regex) { - pattern_ = full_pattern_ = NULL; - if (regex != NULL) { - pattern_ = posix::StrDup(regex); - } - - is_valid_ = ValidateRegex(regex); - if (!is_valid_) { - // No need to calculate the full pattern when the regex is invalid. - return; - } - - const size_t len = strlen(regex); - // Reserves enough bytes to hold the regular expression used for a - // full match: we need space to prepend a '^', append a '$', and - // terminate the string with '\0'. - char* buffer = static_cast(malloc(len + 3)); - full_pattern_ = buffer; - - if (*regex != '^') - *buffer++ = '^'; // Makes sure full_pattern_ starts with '^'. - - // We don't use snprintf or strncpy, as they trigger a warning when - // compiled with VC++ 8.0. - memcpy(buffer, regex, len); - buffer += len; - - if (len == 0 || regex[len - 1] != '$') - *buffer++ = '$'; // Makes sure full_pattern_ ends with '$'. - - *buffer = '\0'; -} - -#endif // GTEST_USES_POSIX_RE - -const char kUnknownFile[] = "unknown file"; - -// Formats a source file path and a line number as they would appear -// in an error message from the compiler used to compile this code. -GTEST_API_ ::std::string FormatFileLocation(const char* file, int line) { - const std::string file_name(file == NULL ? kUnknownFile : file); - - if (line < 0) { - return file_name + ":"; - } -#ifdef _MSC_VER - return file_name + "(" + StreamableToString(line) + "):"; -#else - return file_name + ":" + StreamableToString(line) + ":"; -#endif // _MSC_VER -} - -// Formats a file location for compiler-independent XML output. -// Although this function is not platform dependent, we put it next to -// FormatFileLocation in order to contrast the two functions. -// Note that FormatCompilerIndependentFileLocation() does NOT append colon -// to the file location it produces, unlike FormatFileLocation(). -GTEST_API_ ::std::string FormatCompilerIndependentFileLocation( - const char* file, int line) { - const std::string file_name(file == NULL ? kUnknownFile : file); - - if (line < 0) - return file_name; - else - return file_name + ":" + StreamableToString(line); -} - - -GTestLog::GTestLog(GTestLogSeverity severity, const char* file, int line) - : severity_(severity) { - const char* const marker = - severity == GTEST_INFO ? "[ INFO ]" : - severity == GTEST_WARNING ? "[WARNING]" : - severity == GTEST_ERROR ? "[ ERROR ]" : "[ FATAL ]"; - GetStream() << ::std::endl << marker << " " - << FormatFileLocation(file, line).c_str() << ": "; -} - -// Flushes the buffers and, if severity is GTEST_FATAL, aborts the program. -GTestLog::~GTestLog() { - GetStream() << ::std::endl; - if (severity_ == GTEST_FATAL) { - fflush(stderr); - posix::Abort(); - } -} -// Disable Microsoft deprecation warnings for POSIX functions called from -// this class (creat, dup, dup2, and close) -#ifdef _MSC_VER -# pragma warning(push) -# pragma warning(disable: 4996) -#endif // _MSC_VER - -#if GTEST_HAS_STREAM_REDIRECTION - -// Object that captures an output stream (stdout/stderr). -class CapturedStream { - public: - // The ctor redirects the stream to a temporary file. - explicit CapturedStream(int fd) : fd_(fd), uncaptured_fd_(dup(fd)) { -# if GTEST_OS_WINDOWS - char temp_dir_path[MAX_PATH + 1] = { '\0' }; // NOLINT - char temp_file_path[MAX_PATH + 1] = { '\0' }; // NOLINT - - ::GetTempPathA(sizeof(temp_dir_path), temp_dir_path); - const UINT success = ::GetTempFileNameA(temp_dir_path, - "gtest_redir", - 0, // Generate unique file name. - temp_file_path); - GTEST_CHECK_(success != 0) - << "Unable to create a temporary file in " << temp_dir_path; - const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE); - GTEST_CHECK_(captured_fd != -1) << "Unable to open temporary file " - << temp_file_path; - filename_ = temp_file_path; -# else - // There's no guarantee that a test has write access to the current - // directory, so we create the temporary file in the /tmp directory - // instead. We use /tmp on most systems, and /sdcard on Android. - // That's because Android doesn't have /tmp. -# if GTEST_OS_LINUX_ANDROID - // Note: Android applications are expected to call the framework's - // Context.getExternalStorageDirectory() method through JNI to get - // the location of the world-writable SD Card directory. However, - // this requires a Context handle, which cannot be retrieved - // globally from native code. Doing so also precludes running the - // code as part of a regular standalone executable, which doesn't - // run in a Dalvik process (e.g. when running it through 'adb shell'). - // - // The location /sdcard is directly accessible from native code - // and is the only location (unofficially) supported by the Android - // team. It's generally a symlink to the real SD Card mount point - // which can be /mnt/sdcard, /mnt/sdcard0, /system/media/sdcard, or - // other OEM-customized locations. Never rely on these, and always - // use /sdcard. - char name_template[] = "/sdcard/gtest_captured_stream.XXXXXX"; -# else - char name_template[] = "/tmp/captured_stream.XXXXXX"; -# endif // GTEST_OS_LINUX_ANDROID - const int captured_fd = mkstemp(name_template); - filename_ = name_template; -# endif // GTEST_OS_WINDOWS - fflush(NULL); - dup2(captured_fd, fd_); - close(captured_fd); - } - - ~CapturedStream() { - remove(filename_.c_str()); - } - - std::string GetCapturedString() { - if (uncaptured_fd_ != -1) { - // Restores the original stream. - fflush(NULL); - dup2(uncaptured_fd_, fd_); - close(uncaptured_fd_); - uncaptured_fd_ = -1; - } - - FILE* const file = posix::FOpen(filename_.c_str(), "r"); - const std::string content = ReadEntireFile(file); - posix::FClose(file); - return content; - } - - private: - // Reads the entire content of a file as an std::string. - static std::string ReadEntireFile(FILE* file); - - // Returns the size (in bytes) of a file. - static size_t GetFileSize(FILE* file); - - const int fd_; // A stream to capture. - int uncaptured_fd_; - // Name of the temporary file holding the stderr output. - ::std::string filename_; - - GTEST_DISALLOW_COPY_AND_ASSIGN_(CapturedStream); -}; - -// Returns the size (in bytes) of a file. -size_t CapturedStream::GetFileSize(FILE* file) { - fseek(file, 0, SEEK_END); - return static_cast(ftell(file)); -} - -// Reads the entire content of a file as a string. -std::string CapturedStream::ReadEntireFile(FILE* file) { - const size_t file_size = GetFileSize(file); - char* const buffer = new char[file_size]; - - size_t bytes_last_read = 0; // # of bytes read in the last fread() - size_t bytes_read = 0; // # of bytes read so far - - fseek(file, 0, SEEK_SET); - - // Keeps reading the file until we cannot read further or the - // pre-determined file size is reached. - do { - bytes_last_read = fread(buffer+bytes_read, 1, file_size-bytes_read, file); - bytes_read += bytes_last_read; - } while (bytes_last_read > 0 && bytes_read < file_size); - - const std::string content(buffer, bytes_read); - delete[] buffer; - - return content; -} - -# ifdef _MSC_VER -# pragma warning(pop) -# endif // _MSC_VER - -static CapturedStream* g_captured_stderr = NULL; -static CapturedStream* g_captured_stdout = NULL; - -// Starts capturing an output stream (stdout/stderr). -void CaptureStream(int fd, const char* stream_name, CapturedStream** stream) { - if (*stream != NULL) { - GTEST_LOG_(FATAL) << "Only one " << stream_name - << " capturer can exist at a time."; - } - *stream = new CapturedStream(fd); -} - -// Stops capturing the output stream and returns the captured string. -std::string GetCapturedStream(CapturedStream** captured_stream) { - const std::string content = (*captured_stream)->GetCapturedString(); - - delete *captured_stream; - *captured_stream = NULL; - - return content; -} - -// Starts capturing stdout. -void CaptureStdout() { - CaptureStream(kStdOutFileno, "stdout", &g_captured_stdout); -} - -// Starts capturing stderr. -void CaptureStderr() { - CaptureStream(kStdErrFileno, "stderr", &g_captured_stderr); -} - -// Stops capturing stdout and returns the captured string. -std::string GetCapturedStdout() { - return GetCapturedStream(&g_captured_stdout); -} - -// Stops capturing stderr and returns the captured string. -std::string GetCapturedStderr() { - return GetCapturedStream(&g_captured_stderr); -} - -#endif // GTEST_HAS_STREAM_REDIRECTION - -#if GTEST_HAS_DEATH_TEST - -// A copy of all command line arguments. Set by InitGoogleTest(). -::std::vector g_argvs; - -static const ::std::vector* g_injected_test_argvs = - NULL; // Owned. - -void SetInjectableArgvs(const ::std::vector* argvs) { - if (g_injected_test_argvs != argvs) - delete g_injected_test_argvs; - g_injected_test_argvs = argvs; -} - -const ::std::vector& GetInjectableArgvs() { - if (g_injected_test_argvs != NULL) { - return *g_injected_test_argvs; - } - return g_argvs; -} -#endif // GTEST_HAS_DEATH_TEST - -#if GTEST_OS_WINDOWS_MOBILE -namespace posix { -void Abort() { - DebugBreak(); - TerminateProcess(GetCurrentProcess(), 1); -} -} // namespace posix -#endif // GTEST_OS_WINDOWS_MOBILE - -// Returns the name of the environment variable corresponding to the -// given flag. For example, FlagToEnvVar("foo") will return -// "GTEST_FOO" in the open-source version. -static std::string FlagToEnvVar(const char* flag) { - const std::string full_flag = - (Message() << GTEST_FLAG_PREFIX_ << flag).GetString(); - - Message env_var; - for (size_t i = 0; i != full_flag.length(); i++) { - env_var << ToUpper(full_flag.c_str()[i]); - } - - return env_var.GetString(); -} - -// Parses 'str' for a 32-bit signed integer. If successful, writes -// the result to *value and returns true; otherwise leaves *value -// unchanged and returns false. -bool ParseInt32(const Message& src_text, const char* str, Int32* value) { - // Parses the environment variable as a decimal integer. - char* end = NULL; - const long long_value = strtol(str, &end, 10); // NOLINT - - // Has strtol() consumed all characters in the string? - if (*end != '\0') { - // No - an invalid character was encountered. - Message msg; - msg << "WARNING: " << src_text - << " is expected to be a 32-bit integer, but actually" - << " has value \"" << str << "\".\n"; - printf("%s", msg.GetString().c_str()); - fflush(stdout); - return false; - } - - // Is the parsed value in the range of an Int32? - const Int32 result = static_cast(long_value); - if (long_value == LONG_MAX || long_value == LONG_MIN || - // The parsed value overflows as a long. (strtol() returns - // LONG_MAX or LONG_MIN when the input overflows.) - result != long_value - // The parsed value overflows as an Int32. - ) { - Message msg; - msg << "WARNING: " << src_text - << " is expected to be a 32-bit integer, but actually" - << " has value " << str << ", which overflows.\n"; - printf("%s", msg.GetString().c_str()); - fflush(stdout); - return false; - } - - *value = result; - return true; -} - -// Reads and returns the Boolean environment variable corresponding to -// the given flag; if it's not set, returns default_value. -// -// The value is considered true iff it's not "0". -bool BoolFromGTestEnv(const char* flag, bool default_value) { - const std::string env_var = FlagToEnvVar(flag); - const char* const string_value = posix::GetEnv(env_var.c_str()); - return string_value == NULL ? - default_value : strcmp(string_value, "0") != 0; -} - -// Reads and returns a 32-bit integer stored in the environment -// variable corresponding to the given flag; if it isn't set or -// doesn't represent a valid 32-bit integer, returns default_value. -Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) { - const std::string env_var = FlagToEnvVar(flag); - const char* const string_value = posix::GetEnv(env_var.c_str()); - if (string_value == NULL) { - // The environment variable is not set. - return default_value; - } - - Int32 result = default_value; - if (!ParseInt32(Message() << "Environment variable " << env_var, - string_value, &result)) { - printf("The default value %s is used.\n", - (Message() << default_value).GetString().c_str()); - fflush(stdout); - return default_value; - } - - return result; -} - -// Reads and returns the string environment variable corresponding to -// the given flag; if it's not set, returns default_value. -const char* StringFromGTestEnv(const char* flag, const char* default_value) { - const std::string env_var = FlagToEnvVar(flag); - const char* const value = posix::GetEnv(env_var.c_str()); - return value == NULL ? default_value : value; -} - -} // namespace internal -} // namespace testing -// Copyright 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: wan@google.com (Zhanyong Wan) - -// Google Test - The Google C++ Testing Framework -// -// This file implements a universal value printer that can print a -// value of any type T: -// -// void ::testing::internal::UniversalPrinter::Print(value, ostream_ptr); -// -// It uses the << operator when possible, and prints the bytes in the -// object otherwise. A user can override its behavior for a class -// type Foo by defining either operator<<(::std::ostream&, const Foo&) -// or void PrintTo(const Foo&, ::std::ostream*) in the namespace that -// defines Foo. - -#include -#include -#include // NOLINT -#include - -namespace testing { - -namespace { - -using ::std::ostream; - -// Prints a segment of bytes in the given object. -void PrintByteSegmentInObjectTo(const unsigned char* obj_bytes, size_t start, - size_t count, ostream* os) { - char text[5] = ""; - for (size_t i = 0; i != count; i++) { - const size_t j = start + i; - if (i != 0) { - // Organizes the bytes into groups of 2 for easy parsing by - // human. - if ((j % 2) == 0) - *os << ' '; - else - *os << '-'; - } - GTEST_SNPRINTF_(text, sizeof(text), "%02X", obj_bytes[j]); - *os << text; - } -} - -// Prints the bytes in the given value to the given ostream. -void PrintBytesInObjectToImpl(const unsigned char* obj_bytes, size_t count, - ostream* os) { - // Tells the user how big the object is. - *os << count << "-byte object <"; - - const size_t kThreshold = 132; - const size_t kChunkSize = 64; - // If the object size is bigger than kThreshold, we'll have to omit - // some details by printing only the first and the last kChunkSize - // bytes. - // TODO(wan): let the user control the threshold using a flag. - if (count < kThreshold) { - PrintByteSegmentInObjectTo(obj_bytes, 0, count, os); - } else { - PrintByteSegmentInObjectTo(obj_bytes, 0, kChunkSize, os); - *os << " ... "; - // Rounds up to 2-byte boundary. - const size_t resume_pos = (count - kChunkSize + 1)/2*2; - PrintByteSegmentInObjectTo(obj_bytes, resume_pos, count - resume_pos, os); - } - *os << ">"; -} - -} // namespace - -namespace internal2 { - -// Delegates to PrintBytesInObjectToImpl() to print the bytes in the -// given object. The delegation simplifies the implementation, which -// uses the << operator and thus is easier done outside of the -// ::testing::internal namespace, which contains a << operator that -// sometimes conflicts with the one in STL. -void PrintBytesInObjectTo(const unsigned char* obj_bytes, size_t count, - ostream* os) { - PrintBytesInObjectToImpl(obj_bytes, count, os); -} - -} // namespace internal2 - -namespace internal { - -// Depending on the value of a char (or wchar_t), we print it in one -// of three formats: -// - as is if it's a printable ASCII (e.g. 'a', '2', ' '), -// - as a hexidecimal escape sequence (e.g. '\x7F'), or -// - as a special escape sequence (e.g. '\r', '\n'). -enum CharFormat { - kAsIs, - kHexEscape, - kSpecialEscape -}; - -// Returns true if c is a printable ASCII character. We test the -// value of c directly instead of calling isprint(), which is buggy on -// Windows Mobile. -inline bool IsPrintableAscii(wchar_t c) { - return 0x20 <= c && c <= 0x7E; -} - -// Prints a wide or narrow char c as a character literal without the -// quotes, escaping it when necessary; returns how c was formatted. -// The template argument UnsignedChar is the unsigned version of Char, -// which is the type of c. -template -static CharFormat PrintAsCharLiteralTo(Char c, ostream* os) { - switch (static_cast(c)) { - case L'\0': - *os << "\\0"; - break; - case L'\'': - *os << "\\'"; - break; - case L'\\': - *os << "\\\\"; - break; - case L'\a': - *os << "\\a"; - break; - case L'\b': - *os << "\\b"; - break; - case L'\f': - *os << "\\f"; - break; - case L'\n': - *os << "\\n"; - break; - case L'\r': - *os << "\\r"; - break; - case L'\t': - *os << "\\t"; - break; - case L'\v': - *os << "\\v"; - break; - default: - if (IsPrintableAscii(c)) { - *os << static_cast(c); - return kAsIs; - } else { - *os << "\\x" + String::FormatHexInt(static_cast(c)); - return kHexEscape; - } - } - return kSpecialEscape; -} - -// Prints a wchar_t c as if it's part of a string literal, escaping it when -// necessary; returns how c was formatted. -static CharFormat PrintAsStringLiteralTo(wchar_t c, ostream* os) { - switch (c) { - case L'\'': - *os << "'"; - return kAsIs; - case L'"': - *os << "\\\""; - return kSpecialEscape; - default: - return PrintAsCharLiteralTo(c, os); - } -} - -// Prints a char c as if it's part of a string literal, escaping it when -// necessary; returns how c was formatted. -static CharFormat PrintAsStringLiteralTo(char c, ostream* os) { - return PrintAsStringLiteralTo( - static_cast(static_cast(c)), os); -} - -// Prints a wide or narrow character c and its code. '\0' is printed -// as "'\\0'", other unprintable characters are also properly escaped -// using the standard C++ escape sequence. The template argument -// UnsignedChar is the unsigned version of Char, which is the type of c. -template -void PrintCharAndCodeTo(Char c, ostream* os) { - // First, print c as a literal in the most readable form we can find. - *os << ((sizeof(c) > 1) ? "L'" : "'"); - const CharFormat format = PrintAsCharLiteralTo(c, os); - *os << "'"; - - // To aid user debugging, we also print c's code in decimal, unless - // it's 0 (in which case c was printed as '\\0', making the code - // obvious). - if (c == 0) - return; - *os << " (" << static_cast(c); - - // For more convenience, we print c's code again in hexidecimal, - // unless c was already printed in the form '\x##' or the code is in - // [1, 9]. - if (format == kHexEscape || (1 <= c && c <= 9)) { - // Do nothing. - } else { - *os << ", 0x" << String::FormatHexInt(static_cast(c)); - } - *os << ")"; -} - -void PrintTo(unsigned char c, ::std::ostream* os) { - PrintCharAndCodeTo(c, os); -} -void PrintTo(signed char c, ::std::ostream* os) { - PrintCharAndCodeTo(c, os); -} - -// Prints a wchar_t as a symbol if it is printable or as its internal -// code otherwise and also as its code. L'\0' is printed as "L'\\0'". -void PrintTo(wchar_t wc, ostream* os) { - PrintCharAndCodeTo(wc, os); -} - -// Prints the given array of characters to the ostream. CharType must be either -// char or wchar_t. -// The array starts at begin, the length is len, it may include '\0' characters -// and may not be NUL-terminated. -template -static void PrintCharsAsStringTo( - const CharType* begin, size_t len, ostream* os) { - const char* const kQuoteBegin = sizeof(CharType) == 1 ? "\"" : "L\""; - *os << kQuoteBegin; - bool is_previous_hex = false; - for (size_t index = 0; index < len; ++index) { - const CharType cur = begin[index]; - if (is_previous_hex && IsXDigit(cur)) { - // Previous character is of '\x..' form and this character can be - // interpreted as another hexadecimal digit in its number. Break string to - // disambiguate. - *os << "\" " << kQuoteBegin; - } - is_previous_hex = PrintAsStringLiteralTo(cur, os) == kHexEscape; - } - *os << "\""; -} - -// Prints a (const) char/wchar_t array of 'len' elements, starting at address -// 'begin'. CharType must be either char or wchar_t. -template -static void UniversalPrintCharArray( - const CharType* begin, size_t len, ostream* os) { - // The code - // const char kFoo[] = "foo"; - // generates an array of 4, not 3, elements, with the last one being '\0'. - // - // Therefore when printing a char array, we don't print the last element if - // it's '\0', such that the output matches the string literal as it's - // written in the source code. - if (len > 0 && begin[len - 1] == '\0') { - PrintCharsAsStringTo(begin, len - 1, os); - return; - } - - // If, however, the last element in the array is not '\0', e.g. - // const char kFoo[] = { 'f', 'o', 'o' }; - // we must print the entire array. We also print a message to indicate - // that the array is not NUL-terminated. - PrintCharsAsStringTo(begin, len, os); - *os << " (no terminating NUL)"; -} - -// Prints a (const) char array of 'len' elements, starting at address 'begin'. -void UniversalPrintArray(const char* begin, size_t len, ostream* os) { - UniversalPrintCharArray(begin, len, os); -} - -// Prints a (const) wchar_t array of 'len' elements, starting at address -// 'begin'. -void UniversalPrintArray(const wchar_t* begin, size_t len, ostream* os) { - UniversalPrintCharArray(begin, len, os); -} - -// Prints the given C string to the ostream. -void PrintTo(const char* s, ostream* os) { - if (s == NULL) { - *os << "NULL"; - } else { - *os << ImplicitCast_(s) << " pointing to "; - PrintCharsAsStringTo(s, strlen(s), os); - } -} - -// MSVC compiler can be configured to define whar_t as a typedef -// of unsigned short. Defining an overload for const wchar_t* in that case -// would cause pointers to unsigned shorts be printed as wide strings, -// possibly accessing more memory than intended and causing invalid -// memory accesses. MSVC defines _NATIVE_WCHAR_T_DEFINED symbol when -// wchar_t is implemented as a native type. -#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) -// Prints the given wide C string to the ostream. -void PrintTo(const wchar_t* s, ostream* os) { - if (s == NULL) { - *os << "NULL"; - } else { - *os << ImplicitCast_(s) << " pointing to "; - PrintCharsAsStringTo(s, wcslen(s), os); - } -} -#endif // wchar_t is native - -// Prints a ::string object. -#if GTEST_HAS_GLOBAL_STRING -void PrintStringTo(const ::string& s, ostream* os) { - PrintCharsAsStringTo(s.data(), s.size(), os); -} -#endif // GTEST_HAS_GLOBAL_STRING - -void PrintStringTo(const ::std::string& s, ostream* os) { - PrintCharsAsStringTo(s.data(), s.size(), os); -} - -// Prints a ::wstring object. -#if GTEST_HAS_GLOBAL_WSTRING -void PrintWideStringTo(const ::wstring& s, ostream* os) { - PrintCharsAsStringTo(s.data(), s.size(), os); -} -#endif // GTEST_HAS_GLOBAL_WSTRING - -#if GTEST_HAS_STD_WSTRING -void PrintWideStringTo(const ::std::wstring& s, ostream* os) { - PrintCharsAsStringTo(s.data(), s.size(), os); -} -#endif // GTEST_HAS_STD_WSTRING - -} // namespace internal - -} // namespace testing -// Copyright 2008, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: mheule@google.com (Markus Heule) -// -// The Google C++ Testing Framework (Google Test) - - -// Indicates that this translation unit is part of Google Test's -// implementation. It must come before gtest-internal-inl.h is -// included, or there will be a compiler error. This trick is to -// prevent a user from accidentally including gtest-internal-inl.h in -// his code. -#define GTEST_IMPLEMENTATION_ 1 -#undef GTEST_IMPLEMENTATION_ - -namespace testing { - -using internal::GetUnitTestImpl; - -// Gets the summary of the failure message by omitting the stack trace -// in it. -std::string TestPartResult::ExtractSummary(const char* message) { - const char* const stack_trace = strstr(message, internal::kStackTraceMarker); - return stack_trace == NULL ? message : - std::string(message, stack_trace); -} - -// Prints a TestPartResult object. -std::ostream& operator<<(std::ostream& os, const TestPartResult& result) { - return os - << result.file_name() << ":" << result.line_number() << ": " - << (result.type() == TestPartResult::kSuccess ? "Success" : - result.type() == TestPartResult::kFatalFailure ? "Fatal failure" : - "Non-fatal failure") << ":\n" - << result.message() << std::endl; -} - -// Appends a TestPartResult to the array. -void TestPartResultArray::Append(const TestPartResult& result) { - array_.push_back(result); -} - -// Returns the TestPartResult at the given index (0-based). -const TestPartResult& TestPartResultArray::GetTestPartResult(int index) const { - if (index < 0 || index >= size()) { - printf("\nInvalid index (%d) into TestPartResultArray.\n", index); - internal::posix::Abort(); - } - - return array_[index]; -} - -// Returns the number of TestPartResult objects in the array. -int TestPartResultArray::size() const { - return static_cast(array_.size()); -} - -namespace internal { - -HasNewFatalFailureHelper::HasNewFatalFailureHelper() - : has_new_fatal_failure_(false), - original_reporter_(GetUnitTestImpl()-> - GetTestPartResultReporterForCurrentThread()) { - GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(this); -} - -HasNewFatalFailureHelper::~HasNewFatalFailureHelper() { - GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread( - original_reporter_); -} - -void HasNewFatalFailureHelper::ReportTestPartResult( - const TestPartResult& result) { - if (result.fatally_failed()) - has_new_fatal_failure_ = true; - original_reporter_->ReportTestPartResult(result); -} - -} // namespace internal - -} // namespace testing -// Copyright 2008 Google Inc. -// All Rights Reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: wan@google.com (Zhanyong Wan) - - -namespace testing { -namespace internal { - -#if GTEST_HAS_TYPED_TEST_P - -// Skips to the first non-space char in str. Returns an empty string if str -// contains only whitespace characters. -static const char* SkipSpaces(const char* str) { - while (IsSpace(*str)) - str++; - return str; -} - -// Verifies that registered_tests match the test names in -// defined_test_names_; returns registered_tests if successful, or -// aborts the program otherwise. -const char* TypedTestCasePState::VerifyRegisteredTestNames( - const char* file, int line, const char* registered_tests) { - typedef ::std::set::const_iterator DefinedTestIter; - registered_ = true; - - // Skip initial whitespace in registered_tests since some - // preprocessors prefix stringizied literals with whitespace. - registered_tests = SkipSpaces(registered_tests); - - Message errors; - ::std::set tests; - for (const char* names = registered_tests; names != NULL; - names = SkipComma(names)) { - const std::string name = GetPrefixUntilComma(names); - if (tests.count(name) != 0) { - errors << "Test " << name << " is listed more than once.\n"; - continue; - } - - bool found = false; - for (DefinedTestIter it = defined_test_names_.begin(); - it != defined_test_names_.end(); - ++it) { - if (name == *it) { - found = true; - break; - } - } - - if (found) { - tests.insert(name); - } else { - errors << "No test named " << name - << " can be found in this test case.\n"; - } - } - - for (DefinedTestIter it = defined_test_names_.begin(); - it != defined_test_names_.end(); - ++it) { - if (tests.count(*it) == 0) { - errors << "You forgot to list test " << *it << ".\n"; - } - } - - const std::string& errors_str = errors.GetString(); - if (errors_str != "") { - fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(), - errors_str.c_str()); - fflush(stderr); - posix::Abort(); - } - - return registered_tests; -} - -#endif // GTEST_HAS_TYPED_TEST_P - -} // namespace internal -} // namespace testing diff --git a/lib/kokkos/tpls/gtest/gtest/gtest-test-part.h b/lib/kokkos/tpls/gtest/gtest/gtest-test-part.h deleted file mode 120000 index 48d39090f1..0000000000 --- a/lib/kokkos/tpls/gtest/gtest/gtest-test-part.h +++ /dev/null @@ -1 +0,0 @@ -gtest.h \ No newline at end of file diff --git a/lib/kokkos/tpls/gtest/gtest/gtest.h b/lib/kokkos/tpls/gtest/gtest/gtest.h deleted file mode 100644 index c74d098fa9..0000000000 --- a/lib/kokkos/tpls/gtest/gtest/gtest.h +++ /dev/null @@ -1,20065 +0,0 @@ -// Copyright 2005, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: wan@google.com (Zhanyong Wan) -// -// The Google C++ Testing Framework (Google Test) -// -// This header file defines the public API for Google Test. It should be -// included by any test program that uses Google Test. -// -// IMPORTANT NOTE: Due to limitation of the C++ language, we have to -// leave some internal implementation details in this header file. -// They are clearly marked by comments like this: -// -// // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. -// -// Such code is NOT meant to be used by a user directly, and is subject -// to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user -// program! -// -// Acknowledgment: Google Test borrowed the idea of automatic test -// registration from Barthelemy Dagenais' (barthelemy@prologique.com) -// easyUnit framework. - -#ifdef __GNUC__ -#pragma GCC system_header -#endif - -#ifndef GTEST_INCLUDE_GTEST_GTEST_H_ -#define GTEST_INCLUDE_GTEST_GTEST_H_ - -#include -#include -#include - -// Copyright 2005, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee) -// -// The Google C++ Testing Framework (Google Test) -// -// This header file declares functions and macros used internally by -// Google Test. They are subject to change without notice. - -#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ -#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ - -// Copyright 2005, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Authors: wan@google.com (Zhanyong Wan) -// -// Low-level types and utilities for porting Google Test to various -// platforms. They are subject to change without notice. DO NOT USE -// THEM IN USER CODE. -// -// This file is fundamental to Google Test. All other Google Test source -// files are expected to #include this. Therefore, it cannot #include -// any other Google Test header. - -#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ -#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ - -// The user can define the following macros in the build script to -// control Google Test's behavior. If the user doesn't define a macro -// in this list, Google Test will define it. -// -// GTEST_HAS_CLONE - Define it to 1/0 to indicate that clone(2) -// is/isn't available. -// GTEST_HAS_EXCEPTIONS - Define it to 1/0 to indicate that exceptions -// are enabled. -// GTEST_HAS_GLOBAL_STRING - Define it to 1/0 to indicate that ::string -// is/isn't available (some systems define -// ::string, which is different to std::string). -// GTEST_HAS_GLOBAL_WSTRING - Define it to 1/0 to indicate that ::string -// is/isn't available (some systems define -// ::wstring, which is different to std::wstring). -// GTEST_HAS_POSIX_RE - Define it to 1/0 to indicate that POSIX regular -// expressions are/aren't available. -// GTEST_HAS_PTHREAD - Define it to 1/0 to indicate that -// is/isn't available. -// GTEST_HAS_RTTI - Define it to 1/0 to indicate that RTTI is/isn't -// enabled. -// GTEST_HAS_STD_WSTRING - Define it to 1/0 to indicate that -// std::wstring does/doesn't work (Google Test can -// be used where std::wstring is unavailable). -// GTEST_HAS_TR1_TUPLE - Define it to 1/0 to indicate tr1::tuple -// is/isn't available. -// GTEST_HAS_SEH - Define it to 1/0 to indicate whether the -// compiler supports Microsoft's "Structured -// Exception Handling". -// GTEST_HAS_STREAM_REDIRECTION -// - Define it to 1/0 to indicate whether the -// platform supports I/O stream redirection using -// dup() and dup2(). -// GTEST_USE_OWN_TR1_TUPLE - Define it to 1/0 to indicate whether Google -// Test's own tr1 tuple implementation should be -// used. Unused when the user sets -// GTEST_HAS_TR1_TUPLE to 0. -// GTEST_LANG_CXX11 - Define it to 1/0 to indicate that Google Test -// is building in C++11/C++98 mode. -// GTEST_LINKED_AS_SHARED_LIBRARY -// - Define to 1 when compiling tests that use -// Google Test as a shared library (known as -// DLL on Windows). -// GTEST_CREATE_SHARED_LIBRARY -// - Define to 1 when compiling Google Test itself -// as a shared library. - -// This header defines the following utilities: -// -// Macros indicating the current platform (defined to 1 if compiled on -// the given platform; otherwise undefined): -// GTEST_OS_AIX - IBM AIX -// GTEST_OS_CYGWIN - Cygwin -// GTEST_OS_HPUX - HP-UX -// GTEST_OS_LINUX - Linux -// GTEST_OS_LINUX_ANDROID - Google Android -// GTEST_OS_MAC - Mac OS X -// GTEST_OS_IOS - iOS -// GTEST_OS_IOS_SIMULATOR - iOS simulator -// GTEST_OS_NACL - Google Native Client (NaCl) -// GTEST_OS_OPENBSD - OpenBSD -// GTEST_OS_QNX - QNX -// GTEST_OS_SOLARIS - Sun Solaris -// GTEST_OS_SYMBIAN - Symbian -// GTEST_OS_WINDOWS - Windows (Desktop, MinGW, or Mobile) -// GTEST_OS_WINDOWS_DESKTOP - Windows Desktop -// GTEST_OS_WINDOWS_MINGW - MinGW -// GTEST_OS_WINDOWS_MOBILE - Windows Mobile -// GTEST_OS_ZOS - z/OS -// -// Among the platforms, Cygwin, Linux, Max OS X, and Windows have the -// most stable support. Since core members of the Google Test project -// don't have access to other platforms, support for them may be less -// stable. If you notice any problems on your platform, please notify -// googletestframework@googlegroups.com (patches for fixing them are -// even more welcome!). -// -// Note that it is possible that none of the GTEST_OS_* macros are defined. -// -// Macros indicating available Google Test features (defined to 1 if -// the corresponding feature is supported; otherwise undefined): -// GTEST_HAS_COMBINE - the Combine() function (for value-parameterized -// tests) -// GTEST_HAS_DEATH_TEST - death tests -// GTEST_HAS_PARAM_TEST - value-parameterized tests -// GTEST_HAS_TYPED_TEST - typed tests -// GTEST_HAS_TYPED_TEST_P - type-parameterized tests -// GTEST_USES_POSIX_RE - enhanced POSIX regex is used. Do not confuse with -// GTEST_HAS_POSIX_RE (see above) which users can -// define themselves. -// GTEST_USES_SIMPLE_RE - our own simple regex is used; -// the above two are mutually exclusive. -// GTEST_CAN_COMPARE_NULL - accepts untyped NULL in EXPECT_EQ(). -// -// Macros for basic C++ coding: -// GTEST_AMBIGUOUS_ELSE_BLOCKER_ - for disabling a gcc warning. -// GTEST_ATTRIBUTE_UNUSED_ - declares that a class' instances or a -// variable don't have to be used. -// GTEST_DISALLOW_ASSIGN_ - disables operator=. -// GTEST_DISALLOW_COPY_AND_ASSIGN_ - disables copy ctor and operator=. -// GTEST_MUST_USE_RESULT_ - declares that a function's result must be used. -// -// Synchronization: -// Mutex, MutexLock, ThreadLocal, GetThreadCount() -// - synchronization primitives. -// GTEST_IS_THREADSAFE - defined to 1 to indicate that the above -// synchronization primitives have real implementations -// and Google Test is thread-safe; or 0 otherwise. -// -// Template meta programming: -// is_pointer - as in TR1; needed on Symbian and IBM XL C/C++ only. -// IteratorTraits - partial implementation of std::iterator_traits, which -// is not available in libCstd when compiled with Sun C++. -// -// Smart pointers: -// scoped_ptr - as in TR2. -// -// Regular expressions: -// RE - a simple regular expression class using the POSIX -// Extended Regular Expression syntax on UNIX-like -// platforms, or a reduced regular exception syntax on -// other platforms, including Windows. -// -// Logging: -// GTEST_LOG_() - logs messages at the specified severity level. -// LogToStderr() - directs all log messages to stderr. -// FlushInfoLog() - flushes informational log messages. -// -// Stdout and stderr capturing: -// CaptureStdout() - starts capturing stdout. -// GetCapturedStdout() - stops capturing stdout and returns the captured -// string. -// CaptureStderr() - starts capturing stderr. -// GetCapturedStderr() - stops capturing stderr and returns the captured -// string. -// -// Integer types: -// TypeWithSize - maps an integer to a int type. -// Int32, UInt32, Int64, UInt64, TimeInMillis -// - integers of known sizes. -// BiggestInt - the biggest signed integer type. -// -// Command-line utilities: -// GTEST_FLAG() - references a flag. -// GTEST_DECLARE_*() - declares a flag. -// GTEST_DEFINE_*() - defines a flag. -// GetInjectableArgvs() - returns the command line as a vector of strings. -// -// Environment variable utilities: -// GetEnv() - gets the value of an environment variable. -// BoolFromGTestEnv() - parses a bool environment variable. -// Int32FromGTestEnv() - parses an Int32 environment variable. -// StringFromGTestEnv() - parses a string environment variable. - -#include // for isspace, etc -#include // for ptrdiff_t -#include -#include -#include -#ifndef _WIN32_WCE -# include -# include -#endif // !_WIN32_WCE - -#if defined __APPLE__ -# include -# include -#endif - -#include // NOLINT -#include // NOLINT -#include // NOLINT - -#define GTEST_DEV_EMAIL_ "googletestframework@@googlegroups.com" -#define GTEST_FLAG_PREFIX_ "gtest_" -#define GTEST_FLAG_PREFIX_DASH_ "gtest-" -#define GTEST_FLAG_PREFIX_UPPER_ "GTEST_" -#define GTEST_NAME_ "Google Test" -#define GTEST_PROJECT_URL_ "http://code.google.com/p/googletest/" - -// Determines the version of gcc that is used to compile this. -#ifdef __GNUC__ -// 40302 means version 4.3.2. -# define GTEST_GCC_VER_ \ - (__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__) -#endif // __GNUC__ - -// Determines the platform on which Google Test is compiled. -#ifdef __CYGWIN__ -# define GTEST_OS_CYGWIN 1 -#elif defined __SYMBIAN32__ -# define GTEST_OS_SYMBIAN 1 -#elif defined _WIN32 -# define GTEST_OS_WINDOWS 1 -# ifdef _WIN32_WCE -# define GTEST_OS_WINDOWS_MOBILE 1 -# elif defined(__MINGW__) || defined(__MINGW32__) -# define GTEST_OS_WINDOWS_MINGW 1 -# else -# define GTEST_OS_WINDOWS_DESKTOP 1 -# endif // _WIN32_WCE -#elif defined __APPLE__ -# define GTEST_OS_MAC 1 -# if TARGET_OS_IPHONE -# define GTEST_OS_IOS 1 -# if TARGET_IPHONE_SIMULATOR -# define GTEST_OS_IOS_SIMULATOR 1 -# endif -# endif -#elif defined __linux__ -# define GTEST_OS_LINUX 1 -# if defined __ANDROID__ -# define GTEST_OS_LINUX_ANDROID 1 -# endif -#elif defined __MVS__ -# define GTEST_OS_ZOS 1 -#elif defined(__sun) && defined(__SVR4) -# define GTEST_OS_SOLARIS 1 -#elif defined(_AIX) -# define GTEST_OS_AIX 1 -#elif defined(__hpux) -# define GTEST_OS_HPUX 1 -#elif defined __native_client__ -# define GTEST_OS_NACL 1 -#elif defined __OpenBSD__ -# define GTEST_OS_OPENBSD 1 -#elif defined __QNX__ -# define GTEST_OS_QNX 1 -#endif // __CYGWIN__ - -#ifndef GTEST_LANG_CXX11 -// gcc and clang define __GXX_EXPERIMENTAL_CXX0X__ when -// -std={c,gnu}++{0x,11} is passed. The C++11 standard specifies a -// value for __cplusplus, and recent versions of clang, gcc, and -// probably other compilers set that too in C++11 mode. -# if __GXX_EXPERIMENTAL_CXX0X__ || __cplusplus >= 201103L -// Compiling in at least C++11 mode. -# define GTEST_LANG_CXX11 1 -# else -# define GTEST_LANG_CXX11 0 -# endif -#endif - -// Brings in definitions for functions used in the testing::internal::posix -// namespace (read, write, close, chdir, isatty, stat). We do not currently -// use them on Windows Mobile. -#if !GTEST_OS_WINDOWS -// This assumes that non-Windows OSes provide unistd.h. For OSes where this -// is not the case, we need to include headers that provide the functions -// mentioned above. -# include -# include -#elif !GTEST_OS_WINDOWS_MOBILE -# include -# include -#endif - -#if GTEST_OS_LINUX_ANDROID -// Used to define __ANDROID_API__ matching the target NDK API level. -# include // NOLINT -#endif - -// Defines this to true iff Google Test can use POSIX regular expressions. -#ifndef GTEST_HAS_POSIX_RE -# if GTEST_OS_LINUX_ANDROID -// On Android, is only available starting with Gingerbread. -# define GTEST_HAS_POSIX_RE (__ANDROID_API__ >= 9) -# else -# define GTEST_HAS_POSIX_RE (!GTEST_OS_WINDOWS) -# endif -#endif - -#if GTEST_HAS_POSIX_RE - -// On some platforms, needs someone to define size_t, and -// won't compile otherwise. We can #include it here as we already -// included , which is guaranteed to define size_t through -// . -# include // NOLINT - -# define GTEST_USES_POSIX_RE 1 - -#elif GTEST_OS_WINDOWS - -// is not available on Windows. Use our own simple regex -// implementation instead. -# define GTEST_USES_SIMPLE_RE 1 - -#else - -// may not be available on this platform. Use our own -// simple regex implementation instead. -# define GTEST_USES_SIMPLE_RE 1 - -#endif // GTEST_HAS_POSIX_RE - -#ifndef GTEST_HAS_EXCEPTIONS -// The user didn't tell us whether exceptions are enabled, so we need -// to figure it out. -# if defined(_MSC_VER) || defined(__BORLANDC__) -// MSVC's and C++Builder's implementations of the STL use the _HAS_EXCEPTIONS -// macro to enable exceptions, so we'll do the same. -// Assumes that exceptions are enabled by default. -# ifndef _HAS_EXCEPTIONS -# define _HAS_EXCEPTIONS 1 -# endif // _HAS_EXCEPTIONS -# define GTEST_HAS_EXCEPTIONS _HAS_EXCEPTIONS -# elif defined(__GNUC__) && __EXCEPTIONS -// gcc defines __EXCEPTIONS to 1 iff exceptions are enabled. -# define GTEST_HAS_EXCEPTIONS 1 -# elif defined(__SUNPRO_CC) -// Sun Pro CC supports exceptions. However, there is no compile-time way of -// detecting whether they are enabled or not. Therefore, we assume that -// they are enabled unless the user tells us otherwise. -# define GTEST_HAS_EXCEPTIONS 1 -# elif defined(__IBMCPP__) && __EXCEPTIONS -// xlC defines __EXCEPTIONS to 1 iff exceptions are enabled. -# define GTEST_HAS_EXCEPTIONS 1 -# elif defined(__HP_aCC) -// Exception handling is in effect by default in HP aCC compiler. It has to -// be turned of by +noeh compiler option if desired. -# define GTEST_HAS_EXCEPTIONS 1 -# else -// For other compilers, we assume exceptions are disabled to be -// conservative. -# define GTEST_HAS_EXCEPTIONS 0 -# endif // defined(_MSC_VER) || defined(__BORLANDC__) -#endif // GTEST_HAS_EXCEPTIONS - -#if !defined(GTEST_HAS_STD_STRING) -// Even though we don't use this macro any longer, we keep it in case -// some clients still depend on it. -# define GTEST_HAS_STD_STRING 1 -#elif !GTEST_HAS_STD_STRING -// The user told us that ::std::string isn't available. -# error "Google Test cannot be used where ::std::string isn't available." -#endif // !defined(GTEST_HAS_STD_STRING) - -#ifndef GTEST_HAS_GLOBAL_STRING -// The user didn't tell us whether ::string is available, so we need -// to figure it out. - -# define GTEST_HAS_GLOBAL_STRING 0 - -#endif // GTEST_HAS_GLOBAL_STRING - -#ifndef GTEST_HAS_STD_WSTRING -// The user didn't tell us whether ::std::wstring is available, so we need -// to figure it out. -// TODO(wan@google.com): uses autoconf to detect whether ::std::wstring -// is available. - -// Cygwin 1.7 and below doesn't support ::std::wstring. -// Solaris' libc++ doesn't support it either. Android has -// no support for it at least as recent as Froyo (2.2). -# define GTEST_HAS_STD_WSTRING \ - (!(GTEST_OS_LINUX_ANDROID || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS)) - -#endif // GTEST_HAS_STD_WSTRING - -#ifndef GTEST_HAS_GLOBAL_WSTRING -// The user didn't tell us whether ::wstring is available, so we need -// to figure it out. -# define GTEST_HAS_GLOBAL_WSTRING \ - (GTEST_HAS_STD_WSTRING && GTEST_HAS_GLOBAL_STRING) -#endif // GTEST_HAS_GLOBAL_WSTRING - -// Determines whether RTTI is available. -#ifndef GTEST_HAS_RTTI -// The user didn't tell us whether RTTI is enabled, so we need to -// figure it out. - -# ifdef _MSC_VER - -# ifdef _CPPRTTI // MSVC defines this macro iff RTTI is enabled. -# define GTEST_HAS_RTTI 1 -# else -# define GTEST_HAS_RTTI 0 -# endif - -// Starting with version 4.3.2, gcc defines __GXX_RTTI iff RTTI is enabled. -# elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40302) - -# ifdef __GXX_RTTI -// When building against STLport with the Android NDK and with -// -frtti -fno-exceptions, the build fails at link time with undefined -// references to __cxa_bad_typeid. Note sure if STL or toolchain bug, -// so disable RTTI when detected. -# if GTEST_OS_LINUX_ANDROID && defined(_STLPORT_MAJOR) && \ - !defined(__EXCEPTIONS) -# define GTEST_HAS_RTTI 0 -# else -# define GTEST_HAS_RTTI 1 -# endif // GTEST_OS_LINUX_ANDROID && __STLPORT_MAJOR && !__EXCEPTIONS -# else -# define GTEST_HAS_RTTI 0 -# endif // __GXX_RTTI - -// Clang defines __GXX_RTTI starting with version 3.0, but its manual recommends -// using has_feature instead. has_feature(cxx_rtti) is supported since 2.7, the -// first version with C++ support. -# elif defined(__clang__) - -# define GTEST_HAS_RTTI __has_feature(cxx_rtti) - -// Starting with version 9.0 IBM Visual Age defines __RTTI_ALL__ to 1 if -// both the typeid and dynamic_cast features are present. -# elif defined(__IBMCPP__) && (__IBMCPP__ >= 900) - -# ifdef __RTTI_ALL__ -# define GTEST_HAS_RTTI 1 -# else -# define GTEST_HAS_RTTI 0 -# endif - -# else - -// For all other compilers, we assume RTTI is enabled. -# define GTEST_HAS_RTTI 1 - -# endif // _MSC_VER - -#endif // GTEST_HAS_RTTI - -// It's this header's responsibility to #include when RTTI -// is enabled. -#if GTEST_HAS_RTTI -# include -#endif - -// Determines whether Google Test can use the pthreads library. -#ifndef GTEST_HAS_PTHREAD -// The user didn't tell us explicitly, so we assume pthreads support is -// available on Linux and Mac. -// -// To disable threading support in Google Test, add -DGTEST_HAS_PTHREAD=0 -// to your compiler flags. -# define GTEST_HAS_PTHREAD (GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_HPUX \ - || GTEST_OS_QNX) -#endif // GTEST_HAS_PTHREAD - -#if GTEST_HAS_PTHREAD -// gtest-port.h guarantees to #include when GTEST_HAS_PTHREAD is -// true. -# include // NOLINT - -// For timespec and nanosleep, used below. -# include // NOLINT -#endif - -// Determines whether Google Test can use tr1/tuple. You can define -// this macro to 0 to prevent Google Test from using tuple (any -// feature depending on tuple with be disabled in this mode). -#ifndef GTEST_HAS_TR1_TUPLE -# if GTEST_OS_LINUX_ANDROID && defined(_STLPORT_MAJOR) -// STLport, provided with the Android NDK, has neither or . -# define GTEST_HAS_TR1_TUPLE 0 -# else -// The user didn't tell us not to do it, so we assume it's OK. -# define GTEST_HAS_TR1_TUPLE 1 -# endif -#endif // GTEST_HAS_TR1_TUPLE - -// Determines whether Google Test's own tr1 tuple implementation -// should be used. -#ifndef GTEST_USE_OWN_TR1_TUPLE -// The user didn't tell us, so we need to figure it out. - -// We use our own TR1 tuple if we aren't sure the user has an -// implementation of it already. At this time, libstdc++ 4.0.0+ and -// MSVC 2010 are the only mainstream standard libraries that come -// with a TR1 tuple implementation. NVIDIA's CUDA NVCC compiler -// pretends to be GCC by defining __GNUC__ and friends, but cannot -// compile GCC's tuple implementation. MSVC 2008 (9.0) provides TR1 -// tuple in a 323 MB Feature Pack download, which we cannot assume the -// user has. QNX's QCC compiler is a modified GCC but it doesn't -// support TR1 tuple. libc++ only provides std::tuple, in C++11 mode, -// and it can be used with some compilers that define __GNUC__. -# if (defined(__GNUC__) && !defined(__CUDACC__) && (GTEST_GCC_VER_ >= 40000) \ - && !GTEST_OS_QNX && !defined(_LIBCPP_VERSION)) || _MSC_VER >= 1600 -# define GTEST_ENV_HAS_TR1_TUPLE_ 1 -# endif - -// C++11 specifies that provides std::tuple. Use that if gtest is used -// in C++11 mode and libstdc++ isn't very old (binaries targeting OS X 10.6 -// can build with clang but need to use gcc4.2's libstdc++). -# if GTEST_LANG_CXX11 && (!defined(__GLIBCXX__) || __GLIBCXX__ > 20110325) -# define GTEST_ENV_HAS_STD_TUPLE_ 1 -# endif - -# if GTEST_ENV_HAS_TR1_TUPLE_ || GTEST_ENV_HAS_STD_TUPLE_ -# define GTEST_USE_OWN_TR1_TUPLE 0 -# else -# define GTEST_USE_OWN_TR1_TUPLE 1 -# endif - -#endif // GTEST_USE_OWN_TR1_TUPLE - -// To avoid conditional compilation everywhere, we make it -// gtest-port.h's responsibility to #include the header implementing -// tr1/tuple. -#if GTEST_HAS_TR1_TUPLE - -# if GTEST_USE_OWN_TR1_TUPLE -// This file was GENERATED by command: -// pump.py gtest-tuple.h.pump -// DO NOT EDIT BY HAND!!! - -// Copyright 2009 Google Inc. -// All Rights Reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: wan@google.com (Zhanyong Wan) - -// Implements a subset of TR1 tuple needed by Google Test and Google Mock. - -#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ -#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ - -#include // For ::std::pair. - -// The compiler used in Symbian has a bug that prevents us from declaring the -// tuple template as a friend (it complains that tuple is redefined). This -// hack bypasses the bug by declaring the members that should otherwise be -// private as public. -// Sun Studio versions < 12 also have the above bug. -#if defined(__SYMBIAN32__) || (defined(__SUNPRO_CC) && __SUNPRO_CC < 0x590) -# define GTEST_DECLARE_TUPLE_AS_FRIEND_ public: -#else -# define GTEST_DECLARE_TUPLE_AS_FRIEND_ \ - template friend class tuple; \ - private: -#endif - -// GTEST_n_TUPLE_(T) is the type of an n-tuple. -#define GTEST_0_TUPLE_(T) tuple<> -#define GTEST_1_TUPLE_(T) tuple -#define GTEST_2_TUPLE_(T) tuple -#define GTEST_3_TUPLE_(T) tuple -#define GTEST_4_TUPLE_(T) tuple -#define GTEST_5_TUPLE_(T) tuple -#define GTEST_6_TUPLE_(T) tuple -#define GTEST_7_TUPLE_(T) tuple -#define GTEST_8_TUPLE_(T) tuple -#define GTEST_9_TUPLE_(T) tuple -#define GTEST_10_TUPLE_(T) tuple - -// GTEST_n_TYPENAMES_(T) declares a list of n typenames. -#define GTEST_0_TYPENAMES_(T) -#define GTEST_1_TYPENAMES_(T) typename T##0 -#define GTEST_2_TYPENAMES_(T) typename T##0, typename T##1 -#define GTEST_3_TYPENAMES_(T) typename T##0, typename T##1, typename T##2 -#define GTEST_4_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ - typename T##3 -#define GTEST_5_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ - typename T##3, typename T##4 -#define GTEST_6_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ - typename T##3, typename T##4, typename T##5 -#define GTEST_7_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ - typename T##3, typename T##4, typename T##5, typename T##6 -#define GTEST_8_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ - typename T##3, typename T##4, typename T##5, typename T##6, typename T##7 -#define GTEST_9_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ - typename T##3, typename T##4, typename T##5, typename T##6, \ - typename T##7, typename T##8 -#define GTEST_10_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ - typename T##3, typename T##4, typename T##5, typename T##6, \ - typename T##7, typename T##8, typename T##9 - -// In theory, defining stuff in the ::std namespace is undefined -// behavior. We can do this as we are playing the role of a standard -// library vendor. -namespace std { -namespace tr1 { - -template -class tuple; - -// Anything in namespace gtest_internal is Google Test's INTERNAL -// IMPLEMENTATION DETAIL and MUST NOT BE USED DIRECTLY in user code. -namespace gtest_internal { - -// ByRef::type is T if T is a reference; otherwise it's const T&. -template -struct ByRef { typedef const T& type; }; // NOLINT -template -struct ByRef { typedef T& type; }; // NOLINT - -// A handy wrapper for ByRef. -#define GTEST_BY_REF_(T) typename ::std::tr1::gtest_internal::ByRef::type - -// AddRef::type is T if T is a reference; otherwise it's T&. This -// is the same as tr1::add_reference::type. -template -struct AddRef { typedef T& type; }; // NOLINT -template -struct AddRef { typedef T& type; }; // NOLINT - -// A handy wrapper for AddRef. -#define GTEST_ADD_REF_(T) typename ::std::tr1::gtest_internal::AddRef::type - -// A helper for implementing get(). -template class Get; - -// A helper for implementing tuple_element. kIndexValid is true -// iff k < the number of fields in tuple type T. -template -struct TupleElement; - -template -struct TupleElement { - typedef T0 type; -}; - -template -struct TupleElement { - typedef T1 type; -}; - -template -struct TupleElement { - typedef T2 type; -}; - -template -struct TupleElement { - typedef T3 type; -}; - -template -struct TupleElement { - typedef T4 type; -}; - -template -struct TupleElement { - typedef T5 type; -}; - -template -struct TupleElement { - typedef T6 type; -}; - -template -struct TupleElement { - typedef T7 type; -}; - -template -struct TupleElement { - typedef T8 type; -}; - -template -struct TupleElement { - typedef T9 type; -}; - -} // namespace gtest_internal - -template <> -class tuple<> { - public: - tuple() {} - tuple(const tuple& /* t */) {} - tuple& operator=(const tuple& /* t */) { return *this; } -}; - -template -class GTEST_1_TUPLE_(T) { - public: - template friend class gtest_internal::Get; - - tuple() : f0_() {} - - explicit tuple(GTEST_BY_REF_(T0) f0) : f0_(f0) {} - - tuple(const tuple& t) : f0_(t.f0_) {} - - template - tuple(const GTEST_1_TUPLE_(U)& t) : f0_(t.f0_) {} - - tuple& operator=(const tuple& t) { return CopyFrom(t); } - - template - tuple& operator=(const GTEST_1_TUPLE_(U)& t) { - return CopyFrom(t); - } - - GTEST_DECLARE_TUPLE_AS_FRIEND_ - - template - tuple& CopyFrom(const GTEST_1_TUPLE_(U)& t) { - f0_ = t.f0_; - return *this; - } - - T0 f0_; -}; - -template -class GTEST_2_TUPLE_(T) { - public: - template friend class gtest_internal::Get; - - tuple() : f0_(), f1_() {} - - explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1) : f0_(f0), - f1_(f1) {} - - tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_) {} - - template - tuple(const GTEST_2_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_) {} - template - tuple(const ::std::pair& p) : f0_(p.first), f1_(p.second) {} - - tuple& operator=(const tuple& t) { return CopyFrom(t); } - - template - tuple& operator=(const GTEST_2_TUPLE_(U)& t) { - return CopyFrom(t); - } - template - tuple& operator=(const ::std::pair& p) { - f0_ = p.first; - f1_ = p.second; - return *this; - } - - GTEST_DECLARE_TUPLE_AS_FRIEND_ - - template - tuple& CopyFrom(const GTEST_2_TUPLE_(U)& t) { - f0_ = t.f0_; - f1_ = t.f1_; - return *this; - } - - T0 f0_; - T1 f1_; -}; - -template -class GTEST_3_TUPLE_(T) { - public: - template friend class gtest_internal::Get; - - tuple() : f0_(), f1_(), f2_() {} - - explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, - GTEST_BY_REF_(T2) f2) : f0_(f0), f1_(f1), f2_(f2) {} - - tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_) {} - - template - tuple(const GTEST_3_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_) {} - - tuple& operator=(const tuple& t) { return CopyFrom(t); } - - template - tuple& operator=(const GTEST_3_TUPLE_(U)& t) { - return CopyFrom(t); - } - - GTEST_DECLARE_TUPLE_AS_FRIEND_ - - template - tuple& CopyFrom(const GTEST_3_TUPLE_(U)& t) { - f0_ = t.f0_; - f1_ = t.f1_; - f2_ = t.f2_; - return *this; - } - - T0 f0_; - T1 f1_; - T2 f2_; -}; - -template -class GTEST_4_TUPLE_(T) { - public: - template friend class gtest_internal::Get; - - tuple() : f0_(), f1_(), f2_(), f3_() {} - - explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, - GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3) : f0_(f0), f1_(f1), f2_(f2), - f3_(f3) {} - - tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_) {} - - template - tuple(const GTEST_4_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), - f3_(t.f3_) {} - - tuple& operator=(const tuple& t) { return CopyFrom(t); } - - template - tuple& operator=(const GTEST_4_TUPLE_(U)& t) { - return CopyFrom(t); - } - - GTEST_DECLARE_TUPLE_AS_FRIEND_ - - template - tuple& CopyFrom(const GTEST_4_TUPLE_(U)& t) { - f0_ = t.f0_; - f1_ = t.f1_; - f2_ = t.f2_; - f3_ = t.f3_; - return *this; - } - - T0 f0_; - T1 f1_; - T2 f2_; - T3 f3_; -}; - -template -class GTEST_5_TUPLE_(T) { - public: - template friend class gtest_internal::Get; - - tuple() : f0_(), f1_(), f2_(), f3_(), f4_() {} - - explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, - GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, - GTEST_BY_REF_(T4) f4) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4) {} - - tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), - f4_(t.f4_) {} - - template - tuple(const GTEST_5_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), - f3_(t.f3_), f4_(t.f4_) {} - - tuple& operator=(const tuple& t) { return CopyFrom(t); } - - template - tuple& operator=(const GTEST_5_TUPLE_(U)& t) { - return CopyFrom(t); - } - - GTEST_DECLARE_TUPLE_AS_FRIEND_ - - template - tuple& CopyFrom(const GTEST_5_TUPLE_(U)& t) { - f0_ = t.f0_; - f1_ = t.f1_; - f2_ = t.f2_; - f3_ = t.f3_; - f4_ = t.f4_; - return *this; - } - - T0 f0_; - T1 f1_; - T2 f2_; - T3 f3_; - T4 f4_; -}; - -template -class GTEST_6_TUPLE_(T) { - public: - template friend class gtest_internal::Get; - - tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_() {} - - explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, - GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, - GTEST_BY_REF_(T5) f5) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4), - f5_(f5) {} - - tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), - f4_(t.f4_), f5_(t.f5_) {} - - template - tuple(const GTEST_6_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), - f3_(t.f3_), f4_(t.f4_), f5_(t.f5_) {} - - tuple& operator=(const tuple& t) { return CopyFrom(t); } - - template - tuple& operator=(const GTEST_6_TUPLE_(U)& t) { - return CopyFrom(t); - } - - GTEST_DECLARE_TUPLE_AS_FRIEND_ - - template - tuple& CopyFrom(const GTEST_6_TUPLE_(U)& t) { - f0_ = t.f0_; - f1_ = t.f1_; - f2_ = t.f2_; - f3_ = t.f3_; - f4_ = t.f4_; - f5_ = t.f5_; - return *this; - } - - T0 f0_; - T1 f1_; - T2 f2_; - T3 f3_; - T4 f4_; - T5 f5_; -}; - -template -class GTEST_7_TUPLE_(T) { - public: - template friend class gtest_internal::Get; - - tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_() {} - - explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, - GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, - GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6) : f0_(f0), f1_(f1), f2_(f2), - f3_(f3), f4_(f4), f5_(f5), f6_(f6) {} - - tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), - f4_(t.f4_), f5_(t.f5_), f6_(t.f6_) {} - - template - tuple(const GTEST_7_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), - f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_) {} - - tuple& operator=(const tuple& t) { return CopyFrom(t); } - - template - tuple& operator=(const GTEST_7_TUPLE_(U)& t) { - return CopyFrom(t); - } - - GTEST_DECLARE_TUPLE_AS_FRIEND_ - - template - tuple& CopyFrom(const GTEST_7_TUPLE_(U)& t) { - f0_ = t.f0_; - f1_ = t.f1_; - f2_ = t.f2_; - f3_ = t.f3_; - f4_ = t.f4_; - f5_ = t.f5_; - f6_ = t.f6_; - return *this; - } - - T0 f0_; - T1 f1_; - T2 f2_; - T3 f3_; - T4 f4_; - T5 f5_; - T6 f6_; -}; - -template -class GTEST_8_TUPLE_(T) { - public: - template friend class gtest_internal::Get; - - tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_() {} - - explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, - GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, - GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, - GTEST_BY_REF_(T7) f7) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4), - f5_(f5), f6_(f6), f7_(f7) {} - - tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), - f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_) {} - - template - tuple(const GTEST_8_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), - f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_) {} - - tuple& operator=(const tuple& t) { return CopyFrom(t); } - - template - tuple& operator=(const GTEST_8_TUPLE_(U)& t) { - return CopyFrom(t); - } - - GTEST_DECLARE_TUPLE_AS_FRIEND_ - - template - tuple& CopyFrom(const GTEST_8_TUPLE_(U)& t) { - f0_ = t.f0_; - f1_ = t.f1_; - f2_ = t.f2_; - f3_ = t.f3_; - f4_ = t.f4_; - f5_ = t.f5_; - f6_ = t.f6_; - f7_ = t.f7_; - return *this; - } - - T0 f0_; - T1 f1_; - T2 f2_; - T3 f3_; - T4 f4_; - T5 f5_; - T6 f6_; - T7 f7_; -}; - -template -class GTEST_9_TUPLE_(T) { - public: - template friend class gtest_internal::Get; - - tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_(), f8_() {} - - explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, - GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, - GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, GTEST_BY_REF_(T7) f7, - GTEST_BY_REF_(T8) f8) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4), - f5_(f5), f6_(f6), f7_(f7), f8_(f8) {} - - tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), - f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_) {} - - template - tuple(const GTEST_9_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), - f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_) {} - - tuple& operator=(const tuple& t) { return CopyFrom(t); } - - template - tuple& operator=(const GTEST_9_TUPLE_(U)& t) { - return CopyFrom(t); - } - - GTEST_DECLARE_TUPLE_AS_FRIEND_ - - template - tuple& CopyFrom(const GTEST_9_TUPLE_(U)& t) { - f0_ = t.f0_; - f1_ = t.f1_; - f2_ = t.f2_; - f3_ = t.f3_; - f4_ = t.f4_; - f5_ = t.f5_; - f6_ = t.f6_; - f7_ = t.f7_; - f8_ = t.f8_; - return *this; - } - - T0 f0_; - T1 f1_; - T2 f2_; - T3 f3_; - T4 f4_; - T5 f5_; - T6 f6_; - T7 f7_; - T8 f8_; -}; - -template -class tuple { - public: - template friend class gtest_internal::Get; - - tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_(), f8_(), - f9_() {} - - explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, - GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, - GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, GTEST_BY_REF_(T7) f7, - GTEST_BY_REF_(T8) f8, GTEST_BY_REF_(T9) f9) : f0_(f0), f1_(f1), f2_(f2), - f3_(f3), f4_(f4), f5_(f5), f6_(f6), f7_(f7), f8_(f8), f9_(f9) {} - - tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), - f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_), f9_(t.f9_) {} - - template - tuple(const GTEST_10_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), - f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_), - f9_(t.f9_) {} - - tuple& operator=(const tuple& t) { return CopyFrom(t); } - - template - tuple& operator=(const GTEST_10_TUPLE_(U)& t) { - return CopyFrom(t); - } - - GTEST_DECLARE_TUPLE_AS_FRIEND_ - - template - tuple& CopyFrom(const GTEST_10_TUPLE_(U)& t) { - f0_ = t.f0_; - f1_ = t.f1_; - f2_ = t.f2_; - f3_ = t.f3_; - f4_ = t.f4_; - f5_ = t.f5_; - f6_ = t.f6_; - f7_ = t.f7_; - f8_ = t.f8_; - f9_ = t.f9_; - return *this; - } - - T0 f0_; - T1 f1_; - T2 f2_; - T3 f3_; - T4 f4_; - T5 f5_; - T6 f6_; - T7 f7_; - T8 f8_; - T9 f9_; -}; - -// 6.1.3.2 Tuple creation functions. - -// Known limitations: we don't support passing an -// std::tr1::reference_wrapper to make_tuple(). And we don't -// implement tie(). - -inline tuple<> make_tuple() { return tuple<>(); } - -template -inline GTEST_1_TUPLE_(T) make_tuple(const T0& f0) { - return GTEST_1_TUPLE_(T)(f0); -} - -template -inline GTEST_2_TUPLE_(T) make_tuple(const T0& f0, const T1& f1) { - return GTEST_2_TUPLE_(T)(f0, f1); -} - -template -inline GTEST_3_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2) { - return GTEST_3_TUPLE_(T)(f0, f1, f2); -} - -template -inline GTEST_4_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, - const T3& f3) { - return GTEST_4_TUPLE_(T)(f0, f1, f2, f3); -} - -template -inline GTEST_5_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, - const T3& f3, const T4& f4) { - return GTEST_5_TUPLE_(T)(f0, f1, f2, f3, f4); -} - -template -inline GTEST_6_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, - const T3& f3, const T4& f4, const T5& f5) { - return GTEST_6_TUPLE_(T)(f0, f1, f2, f3, f4, f5); -} - -template -inline GTEST_7_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, - const T3& f3, const T4& f4, const T5& f5, const T6& f6) { - return GTEST_7_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6); -} - -template -inline GTEST_8_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, - const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7) { - return GTEST_8_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7); -} - -template -inline GTEST_9_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, - const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7, - const T8& f8) { - return GTEST_9_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7, f8); -} - -template -inline GTEST_10_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, - const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7, - const T8& f8, const T9& f9) { - return GTEST_10_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7, f8, f9); -} - -// 6.1.3.3 Tuple helper classes. - -template struct tuple_size; - -template -struct tuple_size { - static const int value = 0; -}; - -template -struct tuple_size { - static const int value = 1; -}; - -template -struct tuple_size { - static const int value = 2; -}; - -template -struct tuple_size { - static const int value = 3; -}; - -template -struct tuple_size { - static const int value = 4; -}; - -template -struct tuple_size { - static const int value = 5; -}; - -template -struct tuple_size { - static const int value = 6; -}; - -template -struct tuple_size { - static const int value = 7; -}; - -template -struct tuple_size { - static const int value = 8; -}; - -template -struct tuple_size { - static const int value = 9; -}; - -template -struct tuple_size { - static const int value = 10; -}; - -template -struct tuple_element { - typedef typename gtest_internal::TupleElement< - k < (tuple_size::value), k, Tuple>::type type; -}; - -#define GTEST_TUPLE_ELEMENT_(k, Tuple) typename tuple_element::type - -// 6.1.3.4 Element access. - -namespace gtest_internal { - -template <> -class Get<0> { - public: - template - static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(0, Tuple)) - Field(Tuple& t) { return t.f0_; } // NOLINT - - template - static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(0, Tuple)) - ConstField(const Tuple& t) { return t.f0_; } -}; - -template <> -class Get<1> { - public: - template - static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(1, Tuple)) - Field(Tuple& t) { return t.f1_; } // NOLINT - - template - static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(1, Tuple)) - ConstField(const Tuple& t) { return t.f1_; } -}; - -template <> -class Get<2> { - public: - template - static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(2, Tuple)) - Field(Tuple& t) { return t.f2_; } // NOLINT - - template - static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(2, Tuple)) - ConstField(const Tuple& t) { return t.f2_; } -}; - -template <> -class Get<3> { - public: - template - static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(3, Tuple)) - Field(Tuple& t) { return t.f3_; } // NOLINT - - template - static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(3, Tuple)) - ConstField(const Tuple& t) { return t.f3_; } -}; - -template <> -class Get<4> { - public: - template - static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(4, Tuple)) - Field(Tuple& t) { return t.f4_; } // NOLINT - - template - static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(4, Tuple)) - ConstField(const Tuple& t) { return t.f4_; } -}; - -template <> -class Get<5> { - public: - template - static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(5, Tuple)) - Field(Tuple& t) { return t.f5_; } // NOLINT - - template - static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(5, Tuple)) - ConstField(const Tuple& t) { return t.f5_; } -}; - -template <> -class Get<6> { - public: - template - static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(6, Tuple)) - Field(Tuple& t) { return t.f6_; } // NOLINT - - template - static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(6, Tuple)) - ConstField(const Tuple& t) { return t.f6_; } -}; - -template <> -class Get<7> { - public: - template - static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(7, Tuple)) - Field(Tuple& t) { return t.f7_; } // NOLINT - - template - static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(7, Tuple)) - ConstField(const Tuple& t) { return t.f7_; } -}; - -template <> -class Get<8> { - public: - template - static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(8, Tuple)) - Field(Tuple& t) { return t.f8_; } // NOLINT - - template - static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(8, Tuple)) - ConstField(const Tuple& t) { return t.f8_; } -}; - -template <> -class Get<9> { - public: - template - static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(9, Tuple)) - Field(Tuple& t) { return t.f9_; } // NOLINT - - template - static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(9, Tuple)) - ConstField(const Tuple& t) { return t.f9_; } -}; - -} // namespace gtest_internal - -template -GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_10_TUPLE_(T))) -get(GTEST_10_TUPLE_(T)& t) { - return gtest_internal::Get::Field(t); -} - -template -GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_10_TUPLE_(T))) -get(const GTEST_10_TUPLE_(T)& t) { - return gtest_internal::Get::ConstField(t); -} - -// 6.1.3.5 Relational operators - -// We only implement == and !=, as we don't have a need for the rest yet. - -namespace gtest_internal { - -// SameSizeTuplePrefixComparator::Eq(t1, t2) returns true if the -// first k fields of t1 equals the first k fields of t2. -// SameSizeTuplePrefixComparator(k1, k2) would be a compiler error if -// k1 != k2. -template -struct SameSizeTuplePrefixComparator; - -template <> -struct SameSizeTuplePrefixComparator<0, 0> { - template - static bool Eq(const Tuple1& /* t1 */, const Tuple2& /* t2 */) { - return true; - } -}; - -template -struct SameSizeTuplePrefixComparator { - template - static bool Eq(const Tuple1& t1, const Tuple2& t2) { - return SameSizeTuplePrefixComparator::Eq(t1, t2) && - ::std::tr1::get(t1) == ::std::tr1::get(t2); - } -}; - -} // namespace gtest_internal - -template -inline bool operator==(const GTEST_10_TUPLE_(T)& t, - const GTEST_10_TUPLE_(U)& u) { - return gtest_internal::SameSizeTuplePrefixComparator< - tuple_size::value, - tuple_size::value>::Eq(t, u); -} - -template -inline bool operator!=(const GTEST_10_TUPLE_(T)& t, - const GTEST_10_TUPLE_(U)& u) { return !(t == u); } - -// 6.1.4 Pairs. -// Unimplemented. - -} // namespace tr1 -} // namespace std - -#undef GTEST_0_TUPLE_ -#undef GTEST_1_TUPLE_ -#undef GTEST_2_TUPLE_ -#undef GTEST_3_TUPLE_ -#undef GTEST_4_TUPLE_ -#undef GTEST_5_TUPLE_ -#undef GTEST_6_TUPLE_ -#undef GTEST_7_TUPLE_ -#undef GTEST_8_TUPLE_ -#undef GTEST_9_TUPLE_ -#undef GTEST_10_TUPLE_ - -#undef GTEST_0_TYPENAMES_ -#undef GTEST_1_TYPENAMES_ -#undef GTEST_2_TYPENAMES_ -#undef GTEST_3_TYPENAMES_ -#undef GTEST_4_TYPENAMES_ -#undef GTEST_5_TYPENAMES_ -#undef GTEST_6_TYPENAMES_ -#undef GTEST_7_TYPENAMES_ -#undef GTEST_8_TYPENAMES_ -#undef GTEST_9_TYPENAMES_ -#undef GTEST_10_TYPENAMES_ - -#undef GTEST_DECLARE_TUPLE_AS_FRIEND_ -#undef GTEST_BY_REF_ -#undef GTEST_ADD_REF_ -#undef GTEST_TUPLE_ELEMENT_ - -#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ -# elif GTEST_ENV_HAS_STD_TUPLE_ -# include -// C++11 puts its tuple into the ::std namespace rather than -// ::std::tr1. gtest expects tuple to live in ::std::tr1, so put it there. -// This causes undefined behavior, but supported compilers react in -// the way we intend. -namespace std { -namespace tr1 { -using ::std::get; -using ::std::make_tuple; -using ::std::tuple; -using ::std::tuple_element; -using ::std::tuple_size; -} -} - -# elif GTEST_OS_SYMBIAN - -// On Symbian, BOOST_HAS_TR1_TUPLE causes Boost's TR1 tuple library to -// use STLport's tuple implementation, which unfortunately doesn't -// work as the copy of STLport distributed with Symbian is incomplete. -// By making sure BOOST_HAS_TR1_TUPLE is undefined, we force Boost to -// use its own tuple implementation. -# ifdef BOOST_HAS_TR1_TUPLE -# undef BOOST_HAS_TR1_TUPLE -# endif // BOOST_HAS_TR1_TUPLE - -// This prevents , which defines -// BOOST_HAS_TR1_TUPLE, from being #included by Boost's . -# define BOOST_TR1_DETAIL_CONFIG_HPP_INCLUDED -# include - -# elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40000) -// GCC 4.0+ implements tr1/tuple in the header. This does -// not conform to the TR1 spec, which requires the header to be . - -# if !GTEST_HAS_RTTI && GTEST_GCC_VER_ < 40302 -// Until version 4.3.2, gcc has a bug that causes , -// which is #included by , to not compile when RTTI is -// disabled. _TR1_FUNCTIONAL is the header guard for -// . Hence the following #define is a hack to prevent -// from being included. -# define _TR1_FUNCTIONAL 1 -# include -# undef _TR1_FUNCTIONAL // Allows the user to #include - // if he chooses to. -# else -# include // NOLINT -# endif // !GTEST_HAS_RTTI && GTEST_GCC_VER_ < 40302 - -# else -// If the compiler is not GCC 4.0+, we assume the user is using a -// spec-conforming TR1 implementation. -# include // NOLINT -# endif // GTEST_USE_OWN_TR1_TUPLE - -#endif // GTEST_HAS_TR1_TUPLE - -// Determines whether clone(2) is supported. -// Usually it will only be available on Linux, excluding -// Linux on the Itanium architecture. -// Also see http://linux.die.net/man/2/clone. -#ifndef GTEST_HAS_CLONE -// The user didn't tell us, so we need to figure it out. - -# if GTEST_OS_LINUX && !defined(__ia64__) -# if GTEST_OS_LINUX_ANDROID -// On Android, clone() is only available on ARM starting with Gingerbread. -# if defined(__arm__) && __ANDROID_API__ >= 9 -# define GTEST_HAS_CLONE 1 -# else -# define GTEST_HAS_CLONE 0 -# endif -# else -# define GTEST_HAS_CLONE 1 -# endif -# else -# define GTEST_HAS_CLONE 0 -# endif // GTEST_OS_LINUX && !defined(__ia64__) - -#endif // GTEST_HAS_CLONE - -// Determines whether to support stream redirection. This is used to test -// output correctness and to implement death tests. -#ifndef GTEST_HAS_STREAM_REDIRECTION -// By default, we assume that stream redirection is supported on all -// platforms except known mobile ones. -# if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN -# define GTEST_HAS_STREAM_REDIRECTION 0 -# else -# define GTEST_HAS_STREAM_REDIRECTION 1 -# endif // !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_SYMBIAN -#endif // GTEST_HAS_STREAM_REDIRECTION - -// Determines whether to support death tests. -// Google Test does not support death tests for VC 7.1 and earlier as -// abort() in a VC 7.1 application compiled as GUI in debug config -// pops up a dialog window that cannot be suppressed programmatically. -#if (GTEST_OS_LINUX || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || \ - (GTEST_OS_MAC && !GTEST_OS_IOS) || GTEST_OS_IOS_SIMULATOR || \ - (GTEST_OS_WINDOWS_DESKTOP && _MSC_VER >= 1400) || \ - GTEST_OS_WINDOWS_MINGW || GTEST_OS_AIX || GTEST_OS_HPUX || \ - GTEST_OS_OPENBSD || GTEST_OS_QNX) -# define GTEST_HAS_DEATH_TEST 1 -# include // NOLINT -#endif - -// We don't support MSVC 7.1 with exceptions disabled now. Therefore -// all the compilers we care about are adequate for supporting -// value-parameterized tests. -#define GTEST_HAS_PARAM_TEST 1 - -// Determines whether to support type-driven tests. - -// Typed tests need and variadic macros, which GCC, VC++ 8.0, -// Sun Pro CC, IBM Visual Age, and HP aCC support. -#if defined(__GNUC__) || (_MSC_VER >= 1400) || defined(__SUNPRO_CC) || \ - defined(__IBMCPP__) || defined(__HP_aCC) -# define GTEST_HAS_TYPED_TEST 1 -# define GTEST_HAS_TYPED_TEST_P 1 -#endif - -// Determines whether to support Combine(). This only makes sense when -// value-parameterized tests are enabled. The implementation doesn't -// work on Sun Studio since it doesn't understand templated conversion -// operators. -#if GTEST_HAS_PARAM_TEST && GTEST_HAS_TR1_TUPLE && !defined(__SUNPRO_CC) -# define GTEST_HAS_COMBINE 1 -#endif - -// Determines whether the system compiler uses UTF-16 for encoding wide strings. -#define GTEST_WIDE_STRING_USES_UTF16_ \ - (GTEST_OS_WINDOWS || GTEST_OS_CYGWIN || GTEST_OS_SYMBIAN || GTEST_OS_AIX) - -// Determines whether test results can be streamed to a socket. -#if GTEST_OS_LINUX -# define GTEST_CAN_STREAM_RESULTS_ 1 -#endif - -// Defines some utility macros. - -// The GNU compiler emits a warning if nested "if" statements are followed by -// an "else" statement and braces are not used to explicitly disambiguate the -// "else" binding. This leads to problems with code like: -// -// if (gate) -// ASSERT_*(condition) << "Some message"; -// -// The "switch (0) case 0:" idiom is used to suppress this. -#ifdef __INTEL_COMPILER -# define GTEST_AMBIGUOUS_ELSE_BLOCKER_ -#else -# define GTEST_AMBIGUOUS_ELSE_BLOCKER_ switch (0) case 0: default: // NOLINT -#endif - -// Use this annotation at the end of a struct/class definition to -// prevent the compiler from optimizing away instances that are never -// used. This is useful when all interesting logic happens inside the -// c'tor and / or d'tor. Example: -// -// struct Foo { -// Foo() { ... } -// } GTEST_ATTRIBUTE_UNUSED_; -// -// Also use it after a variable or parameter declaration to tell the -// compiler the variable/parameter does not have to be used. -#if defined(__GNUC__) && !defined(COMPILER_ICC) -# define GTEST_ATTRIBUTE_UNUSED_ __attribute__ ((unused)) -#else -# define GTEST_ATTRIBUTE_UNUSED_ -#endif - -// A macro to disallow operator= -// This should be used in the private: declarations for a class. -#define GTEST_DISALLOW_ASSIGN_(type)\ - void operator=(type const &) - -// A macro to disallow copy constructor and operator= -// This should be used in the private: declarations for a class. -#define GTEST_DISALLOW_COPY_AND_ASSIGN_(type)\ - type(type const &);\ - GTEST_DISALLOW_ASSIGN_(type) - -// Tell the compiler to warn about unused return values for functions declared -// with this macro. The macro should be used on function declarations -// following the argument list: -// -// Sprocket* AllocateSprocket() GTEST_MUST_USE_RESULT_; -#if defined(__GNUC__) && (GTEST_GCC_VER_ >= 30400) && !defined(COMPILER_ICC) -# define GTEST_MUST_USE_RESULT_ __attribute__ ((warn_unused_result)) -#else -# define GTEST_MUST_USE_RESULT_ -#endif // __GNUC__ && (GTEST_GCC_VER_ >= 30400) && !COMPILER_ICC - -// Determine whether the compiler supports Microsoft's Structured Exception -// Handling. This is supported by several Windows compilers but generally -// does not exist on any other system. -#ifndef GTEST_HAS_SEH -// The user didn't tell us, so we need to figure it out. - -# if defined(_MSC_VER) || defined(__BORLANDC__) -// These two compilers are known to support SEH. -# define GTEST_HAS_SEH 1 -# else -// Assume no SEH. -# define GTEST_HAS_SEH 0 -# endif - -#endif // GTEST_HAS_SEH - -#ifdef _MSC_VER - -# if GTEST_LINKED_AS_SHARED_LIBRARY -# define GTEST_API_ __declspec(dllimport) -# elif GTEST_CREATE_SHARED_LIBRARY -# define GTEST_API_ __declspec(dllexport) -# endif - -#endif // _MSC_VER - -#ifndef GTEST_API_ -# define GTEST_API_ -#endif - -#ifdef __GNUC__ -// Ask the compiler to never inline a given function. -# define GTEST_NO_INLINE_ __attribute__((noinline)) -#else -# define GTEST_NO_INLINE_ -#endif - -// _LIBCPP_VERSION is defined by the libc++ library from the LLVM project. -#if defined(__GLIBCXX__) || defined(_LIBCPP_VERSION) -# define GTEST_HAS_CXXABI_H_ 1 -#else -# define GTEST_HAS_CXXABI_H_ 0 -#endif - -namespace testing { - -class Message; - -namespace internal { - -// A secret type that Google Test users don't know about. It has no -// definition on purpose. Therefore it's impossible to create a -// Secret object, which is what we want. -class Secret; - -// The GTEST_COMPILE_ASSERT_ macro can be used to verify that a compile time -// expression is true. For example, you could use it to verify the -// size of a static array: -// -// GTEST_COMPILE_ASSERT_(ARRAYSIZE(content_type_names) == CONTENT_NUM_TYPES, -// content_type_names_incorrect_size); -// -// or to make sure a struct is smaller than a certain size: -// -// GTEST_COMPILE_ASSERT_(sizeof(foo) < 128, foo_too_large); -// -// The second argument to the macro is the name of the variable. If -// the expression is false, most compilers will issue a warning/error -// containing the name of the variable. - -template -struct CompileAssert { -}; - -#define GTEST_COMPILE_ASSERT_(expr, msg) \ - typedef ::testing::internal::CompileAssert<(static_cast(expr))> \ - msg[static_cast(expr) ? 1 : -1] GTEST_ATTRIBUTE_UNUSED_ - -// Implementation details of GTEST_COMPILE_ASSERT_: -// -// - GTEST_COMPILE_ASSERT_ works by defining an array type that has -1 -// elements (and thus is invalid) when the expression is false. -// -// - The simpler definition -// -// #define GTEST_COMPILE_ASSERT_(expr, msg) typedef char msg[(expr) ? 1 : -1] -// -// does not work, as gcc supports variable-length arrays whose sizes -// are determined at run-time (this is gcc's extension and not part -// of the C++ standard). As a result, gcc fails to reject the -// following code with the simple definition: -// -// int foo; -// GTEST_COMPILE_ASSERT_(foo, msg); // not supposed to compile as foo is -// // not a compile-time constant. -// -// - By using the type CompileAssert<(bool(expr))>, we ensures that -// expr is a compile-time constant. (Template arguments must be -// determined at compile-time.) -// -// - The outter parentheses in CompileAssert<(bool(expr))> are necessary -// to work around a bug in gcc 3.4.4 and 4.0.1. If we had written -// -// CompileAssert -// -// instead, these compilers will refuse to compile -// -// GTEST_COMPILE_ASSERT_(5 > 0, some_message); -// -// (They seem to think the ">" in "5 > 0" marks the end of the -// template argument list.) -// -// - The array size is (bool(expr) ? 1 : -1), instead of simply -// -// ((expr) ? 1 : -1). -// -// This is to avoid running into a bug in MS VC 7.1, which -// causes ((0.0) ? 1 : -1) to incorrectly evaluate to 1. - -// StaticAssertTypeEqHelper is used by StaticAssertTypeEq defined in gtest.h. -// -// This template is declared, but intentionally undefined. -template -struct StaticAssertTypeEqHelper; - -template -struct StaticAssertTypeEqHelper {}; - -#if GTEST_HAS_GLOBAL_STRING -typedef ::string string; -#else -typedef ::std::string string; -#endif // GTEST_HAS_GLOBAL_STRING - -#if GTEST_HAS_GLOBAL_WSTRING -typedef ::wstring wstring; -#elif GTEST_HAS_STD_WSTRING -typedef ::std::wstring wstring; -#endif // GTEST_HAS_GLOBAL_WSTRING - -// A helper for suppressing warnings on constant condition. It just -// returns 'condition'. -GTEST_API_ bool IsTrue(bool condition); - -// Defines scoped_ptr. - -// This implementation of scoped_ptr is PARTIAL - it only contains -// enough stuff to satisfy Google Test's need. -template -class scoped_ptr { - public: - typedef T element_type; - - explicit scoped_ptr(T* p = NULL) : ptr_(p) {} - ~scoped_ptr() { reset(); } - - T& operator*() const { return *ptr_; } - T* operator->() const { return ptr_; } - T* get() const { return ptr_; } - - T* release() { - T* const ptr = ptr_; - ptr_ = NULL; - return ptr; - } - - void reset(T* p = NULL) { - if (p != ptr_) { - if (IsTrue(sizeof(T) > 0)) { // Makes sure T is a complete type. - delete ptr_; - } - ptr_ = p; - } - } - - private: - T* ptr_; - - GTEST_DISALLOW_COPY_AND_ASSIGN_(scoped_ptr); -}; - -// Defines RE. - -// A simple C++ wrapper for . It uses the POSIX Extended -// Regular Expression syntax. -class GTEST_API_ RE { - public: - // A copy constructor is required by the Standard to initialize object - // references from r-values. - RE(const RE& other) { Init(other.pattern()); } - - // Constructs an RE from a string. - RE(const ::std::string& regex) { Init(regex.c_str()); } // NOLINT - -#if GTEST_HAS_GLOBAL_STRING - - RE(const ::string& regex) { Init(regex.c_str()); } // NOLINT - -#endif // GTEST_HAS_GLOBAL_STRING - - RE(const char* regex) { Init(regex); } // NOLINT - ~RE(); - - // Returns the string representation of the regex. - const char* pattern() const { return pattern_; } - - // FullMatch(str, re) returns true iff regular expression re matches - // the entire str. - // PartialMatch(str, re) returns true iff regular expression re - // matches a substring of str (including str itself). - // - // TODO(wan@google.com): make FullMatch() and PartialMatch() work - // when str contains NUL characters. - static bool FullMatch(const ::std::string& str, const RE& re) { - return FullMatch(str.c_str(), re); - } - static bool PartialMatch(const ::std::string& str, const RE& re) { - return PartialMatch(str.c_str(), re); - } - -#if GTEST_HAS_GLOBAL_STRING - - static bool FullMatch(const ::string& str, const RE& re) { - return FullMatch(str.c_str(), re); - } - static bool PartialMatch(const ::string& str, const RE& re) { - return PartialMatch(str.c_str(), re); - } - -#endif // GTEST_HAS_GLOBAL_STRING - - static bool FullMatch(const char* str, const RE& re); - static bool PartialMatch(const char* str, const RE& re); - - private: - void Init(const char* regex); - - // We use a const char* instead of an std::string, as Google Test used to be - // used where std::string is not available. TODO(wan@google.com): change to - // std::string. - const char* pattern_; - bool is_valid_; - -#if GTEST_USES_POSIX_RE - - regex_t full_regex_; // For FullMatch(). - regex_t partial_regex_; // For PartialMatch(). - -#else // GTEST_USES_SIMPLE_RE - - const char* full_pattern_; // For FullMatch(); - -#endif - - GTEST_DISALLOW_ASSIGN_(RE); -}; - -// Formats a source file path and a line number as they would appear -// in an error message from the compiler used to compile this code. -GTEST_API_ ::std::string FormatFileLocation(const char* file, int line); - -// Formats a file location for compiler-independent XML output. -// Although this function is not platform dependent, we put it next to -// FormatFileLocation in order to contrast the two functions. -GTEST_API_ ::std::string FormatCompilerIndependentFileLocation(const char* file, - int line); - -// Defines logging utilities: -// GTEST_LOG_(severity) - logs messages at the specified severity level. The -// message itself is streamed into the macro. -// LogToStderr() - directs all log messages to stderr. -// FlushInfoLog() - flushes informational log messages. - -enum GTestLogSeverity { - GTEST_INFO, - GTEST_WARNING, - GTEST_ERROR, - GTEST_FATAL -}; - -// Formats log entry severity, provides a stream object for streaming the -// log message, and terminates the message with a newline when going out of -// scope. -class GTEST_API_ GTestLog { - public: - GTestLog(GTestLogSeverity severity, const char* file, int line); - - // Flushes the buffers and, if severity is GTEST_FATAL, aborts the program. - ~GTestLog(); - - ::std::ostream& GetStream() { return ::std::cerr; } - - private: - const GTestLogSeverity severity_; - - GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestLog); -}; - -#define GTEST_LOG_(severity) \ - ::testing::internal::GTestLog(::testing::internal::GTEST_##severity, \ - __FILE__, __LINE__).GetStream() - -inline void LogToStderr() {} -inline void FlushInfoLog() { fflush(NULL); } - -// INTERNAL IMPLEMENTATION - DO NOT USE. -// -// GTEST_CHECK_ is an all-mode assert. It aborts the program if the condition -// is not satisfied. -// Synopsys: -// GTEST_CHECK_(boolean_condition); -// or -// GTEST_CHECK_(boolean_condition) << "Additional message"; -// -// This checks the condition and if the condition is not satisfied -// it prints message about the condition violation, including the -// condition itself, plus additional message streamed into it, if any, -// and then it aborts the program. It aborts the program irrespective of -// whether it is built in the debug mode or not. -#define GTEST_CHECK_(condition) \ - GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ - if (::testing::internal::IsTrue(condition)) \ - ; \ - else \ - GTEST_LOG_(FATAL) << "Condition " #condition " failed. " - -// An all-mode assert to verify that the given POSIX-style function -// call returns 0 (indicating success). Known limitation: this -// doesn't expand to a balanced 'if' statement, so enclose the macro -// in {} if you need to use it as the only statement in an 'if' -// branch. -#define GTEST_CHECK_POSIX_SUCCESS_(posix_call) \ - if (const int gtest_error = (posix_call)) \ - GTEST_LOG_(FATAL) << #posix_call << "failed with error " \ - << gtest_error - -// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. -// -// Use ImplicitCast_ as a safe version of static_cast for upcasting in -// the type hierarchy (e.g. casting a Foo* to a SuperclassOfFoo* or a -// const Foo*). When you use ImplicitCast_, the compiler checks that -// the cast is safe. Such explicit ImplicitCast_s are necessary in -// surprisingly many situations where C++ demands an exact type match -// instead of an argument type convertable to a target type. -// -// The syntax for using ImplicitCast_ is the same as for static_cast: -// -// ImplicitCast_(expr) -// -// ImplicitCast_ would have been part of the C++ standard library, -// but the proposal was submitted too late. It will probably make -// its way into the language in the future. -// -// This relatively ugly name is intentional. It prevents clashes with -// similar functions users may have (e.g., implicit_cast). The internal -// namespace alone is not enough because the function can be found by ADL. -template -inline To ImplicitCast_(To x) { return x; } - -// When you upcast (that is, cast a pointer from type Foo to type -// SuperclassOfFoo), it's fine to use ImplicitCast_<>, since upcasts -// always succeed. When you downcast (that is, cast a pointer from -// type Foo to type SubclassOfFoo), static_cast<> isn't safe, because -// how do you know the pointer is really of type SubclassOfFoo? It -// could be a bare Foo, or of type DifferentSubclassOfFoo. Thus, -// when you downcast, you should use this macro. In debug mode, we -// use dynamic_cast<> to double-check the downcast is legal (we die -// if it's not). In normal mode, we do the efficient static_cast<> -// instead. Thus, it's important to test in debug mode to make sure -// the cast is legal! -// This is the only place in the code we should use dynamic_cast<>. -// In particular, you SHOULDN'T be using dynamic_cast<> in order to -// do RTTI (eg code like this: -// if (dynamic_cast(foo)) HandleASubclass1Object(foo); -// if (dynamic_cast(foo)) HandleASubclass2Object(foo); -// You should design the code some other way not to need this. -// -// This relatively ugly name is intentional. It prevents clashes with -// similar functions users may have (e.g., down_cast). The internal -// namespace alone is not enough because the function can be found by ADL. -template // use like this: DownCast_(foo); -inline To DownCast_(From* f) { // so we only accept pointers - // Ensures that To is a sub-type of From *. This test is here only - // for compile-time type checking, and has no overhead in an - // optimized build at run-time, as it will be optimized away - // completely. - if (false) { - const To to = NULL; - ::testing::internal::ImplicitCast_(to); - } - -#if GTEST_HAS_RTTI - // RTTI: debug mode only! - GTEST_CHECK_(f == NULL || dynamic_cast(f) != NULL); -#endif - return static_cast(f); -} - -// Downcasts the pointer of type Base to Derived. -// Derived must be a subclass of Base. The parameter MUST -// point to a class of type Derived, not any subclass of it. -// When RTTI is available, the function performs a runtime -// check to enforce this. -template -Derived* CheckedDowncastToActualType(Base* base) { -#if GTEST_HAS_RTTI - GTEST_CHECK_(typeid(*base) == typeid(Derived)); - return dynamic_cast(base); // NOLINT -#else - return static_cast(base); // Poor man's downcast. -#endif -} - -#if GTEST_HAS_STREAM_REDIRECTION - -// Defines the stderr capturer: -// CaptureStdout - starts capturing stdout. -// GetCapturedStdout - stops capturing stdout and returns the captured string. -// CaptureStderr - starts capturing stderr. -// GetCapturedStderr - stops capturing stderr and returns the captured string. -// -GTEST_API_ void CaptureStdout(); -GTEST_API_ std::string GetCapturedStdout(); -GTEST_API_ void CaptureStderr(); -GTEST_API_ std::string GetCapturedStderr(); - -#endif // GTEST_HAS_STREAM_REDIRECTION - - -#if GTEST_HAS_DEATH_TEST - -const ::std::vector& GetInjectableArgvs(); -void SetInjectableArgvs(const ::std::vector* - new_argvs); - -// A copy of all command line arguments. Set by InitGoogleTest(). -extern ::std::vector g_argvs; - -#endif // GTEST_HAS_DEATH_TEST - -// Defines synchronization primitives. - -#if GTEST_HAS_PTHREAD - -// Sleeps for (roughly) n milli-seconds. This function is only for -// testing Google Test's own constructs. Don't use it in user tests, -// either directly or indirectly. -inline void SleepMilliseconds(int n) { - const timespec time = { - 0, // 0 seconds. - n * 1000L * 1000L, // And n ms. - }; - nanosleep(&time, NULL); -} - -// Allows a controller thread to pause execution of newly created -// threads until notified. Instances of this class must be created -// and destroyed in the controller thread. -// -// This class is only for testing Google Test's own constructs. Do not -// use it in user tests, either directly or indirectly. -class Notification { - public: - Notification() : notified_(false) { - GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, NULL)); - } - ~Notification() { - pthread_mutex_destroy(&mutex_); - } - - // Notifies all threads created with this notification to start. Must - // be called from the controller thread. - void Notify() { - pthread_mutex_lock(&mutex_); - notified_ = true; - pthread_mutex_unlock(&mutex_); - } - - // Blocks until the controller thread notifies. Must be called from a test - // thread. - void WaitForNotification() { - for (;;) { - pthread_mutex_lock(&mutex_); - const bool notified = notified_; - pthread_mutex_unlock(&mutex_); - if (notified) - break; - SleepMilliseconds(10); - } - } - - private: - pthread_mutex_t mutex_; - bool notified_; - - GTEST_DISALLOW_COPY_AND_ASSIGN_(Notification); -}; - -// As a C-function, ThreadFuncWithCLinkage cannot be templated itself. -// Consequently, it cannot select a correct instantiation of ThreadWithParam -// in order to call its Run(). Introducing ThreadWithParamBase as a -// non-templated base class for ThreadWithParam allows us to bypass this -// problem. -class ThreadWithParamBase { - public: - virtual ~ThreadWithParamBase() {} - virtual void Run() = 0; -}; - -// pthread_create() accepts a pointer to a function type with the C linkage. -// According to the Standard (7.5/1), function types with different linkages -// are different even if they are otherwise identical. Some compilers (for -// example, SunStudio) treat them as different types. Since class methods -// cannot be defined with C-linkage we need to define a free C-function to -// pass into pthread_create(). -extern "C" inline void* ThreadFuncWithCLinkage(void* thread) { - static_cast(thread)->Run(); - return NULL; -} - -// Helper class for testing Google Test's multi-threading constructs. -// To use it, write: -// -// void ThreadFunc(int param) { /* Do things with param */ } -// Notification thread_can_start; -// ... -// // The thread_can_start parameter is optional; you can supply NULL. -// ThreadWithParam thread(&ThreadFunc, 5, &thread_can_start); -// thread_can_start.Notify(); -// -// These classes are only for testing Google Test's own constructs. Do -// not use them in user tests, either directly or indirectly. -template -class ThreadWithParam : public ThreadWithParamBase { - public: - typedef void (*UserThreadFunc)(T); - - ThreadWithParam( - UserThreadFunc func, T param, Notification* thread_can_start) - : func_(func), - param_(param), - thread_can_start_(thread_can_start), - finished_(false) { - ThreadWithParamBase* const base = this; - // The thread can be created only after all fields except thread_ - // have been initialized. - GTEST_CHECK_POSIX_SUCCESS_( - pthread_create(&thread_, 0, &ThreadFuncWithCLinkage, base)); - } - ~ThreadWithParam() { Join(); } - - void Join() { - if (!finished_) { - GTEST_CHECK_POSIX_SUCCESS_(pthread_join(thread_, 0)); - finished_ = true; - } - } - - virtual void Run() { - if (thread_can_start_ != NULL) - thread_can_start_->WaitForNotification(); - func_(param_); - } - - private: - const UserThreadFunc func_; // User-supplied thread function. - const T param_; // User-supplied parameter to the thread function. - // When non-NULL, used to block execution until the controller thread - // notifies. - Notification* const thread_can_start_; - bool finished_; // true iff we know that the thread function has finished. - pthread_t thread_; // The native thread object. - - GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadWithParam); -}; - -// MutexBase and Mutex implement mutex on pthreads-based platforms. They -// are used in conjunction with class MutexLock: -// -// Mutex mutex; -// ... -// MutexLock lock(&mutex); // Acquires the mutex and releases it at the end -// // of the current scope. -// -// MutexBase implements behavior for both statically and dynamically -// allocated mutexes. Do not use MutexBase directly. Instead, write -// the following to define a static mutex: -// -// GTEST_DEFINE_STATIC_MUTEX_(g_some_mutex); -// -// You can forward declare a static mutex like this: -// -// GTEST_DECLARE_STATIC_MUTEX_(g_some_mutex); -// -// To create a dynamic mutex, just define an object of type Mutex. -class MutexBase { - public: - // Acquires this mutex. - void Lock() { - GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&mutex_)); - owner_ = pthread_self(); - has_owner_ = true; - } - - // Releases this mutex. - void Unlock() { - // Since the lock is being released the owner_ field should no longer be - // considered valid. We don't protect writing to has_owner_ here, as it's - // the caller's responsibility to ensure that the current thread holds the - // mutex when this is called. - has_owner_ = false; - GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_unlock(&mutex_)); - } - - // Does nothing if the current thread holds the mutex. Otherwise, crashes - // with high probability. - void AssertHeld() const { - GTEST_CHECK_(has_owner_ && pthread_equal(owner_, pthread_self())) - << "The current thread is not holding the mutex @" << this; - } - - // A static mutex may be used before main() is entered. It may even - // be used before the dynamic initialization stage. Therefore we - // must be able to initialize a static mutex object at link time. - // This means MutexBase has to be a POD and its member variables - // have to be public. - public: - pthread_mutex_t mutex_; // The underlying pthread mutex. - // has_owner_ indicates whether the owner_ field below contains a valid thread - // ID and is therefore safe to inspect (e.g., to use in pthread_equal()). All - // accesses to the owner_ field should be protected by a check of this field. - // An alternative might be to memset() owner_ to all zeros, but there's no - // guarantee that a zero'd pthread_t is necessarily invalid or even different - // from pthread_self(). - bool has_owner_; - pthread_t owner_; // The thread holding the mutex. -}; - -// Forward-declares a static mutex. -# define GTEST_DECLARE_STATIC_MUTEX_(mutex) \ - extern ::testing::internal::MutexBase mutex - -// Defines and statically (i.e. at link time) initializes a static mutex. -// The initialization list here does not explicitly initialize each field, -// instead relying on default initialization for the unspecified fields. In -// particular, the owner_ field (a pthread_t) is not explicitly initialized. -// This allows initialization to work whether pthread_t is a scalar or struct. -// The flag -Wmissing-field-initializers must not be specified for this to work. -# define GTEST_DEFINE_STATIC_MUTEX_(mutex) \ - ::testing::internal::MutexBase mutex = { PTHREAD_MUTEX_INITIALIZER, false } - -// The Mutex class can only be used for mutexes created at runtime. It -// shares its API with MutexBase otherwise. -class Mutex : public MutexBase { - public: - Mutex() { - GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, NULL)); - has_owner_ = false; - } - ~Mutex() { - GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_destroy(&mutex_)); - } - - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(Mutex); -}; - -// We cannot name this class MutexLock as the ctor declaration would -// conflict with a macro named MutexLock, which is defined on some -// platforms. Hence the typedef trick below. -class GTestMutexLock { - public: - explicit GTestMutexLock(MutexBase* mutex) - : mutex_(mutex) { mutex_->Lock(); } - - ~GTestMutexLock() { mutex_->Unlock(); } - - private: - MutexBase* const mutex_; - - GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestMutexLock); -}; - -typedef GTestMutexLock MutexLock; - -// Helpers for ThreadLocal. - -// pthread_key_create() requires DeleteThreadLocalValue() to have -// C-linkage. Therefore it cannot be templatized to access -// ThreadLocal. Hence the need for class -// ThreadLocalValueHolderBase. -class ThreadLocalValueHolderBase { - public: - virtual ~ThreadLocalValueHolderBase() {} -}; - -// Called by pthread to delete thread-local data stored by -// pthread_setspecific(). -extern "C" inline void DeleteThreadLocalValue(void* value_holder) { - delete static_cast(value_holder); -} - -// Implements thread-local storage on pthreads-based systems. -// -// // Thread 1 -// ThreadLocal tl(100); // 100 is the default value for each thread. -// -// // Thread 2 -// tl.set(150); // Changes the value for thread 2 only. -// EXPECT_EQ(150, tl.get()); -// -// // Thread 1 -// EXPECT_EQ(100, tl.get()); // In thread 1, tl has the original value. -// tl.set(200); -// EXPECT_EQ(200, tl.get()); -// -// The template type argument T must have a public copy constructor. -// In addition, the default ThreadLocal constructor requires T to have -// a public default constructor. -// -// An object managed for a thread by a ThreadLocal instance is deleted -// when the thread exits. Or, if the ThreadLocal instance dies in -// that thread, when the ThreadLocal dies. It's the user's -// responsibility to ensure that all other threads using a ThreadLocal -// have exited when it dies, or the per-thread objects for those -// threads will not be deleted. -// -// Google Test only uses global ThreadLocal objects. That means they -// will die after main() has returned. Therefore, no per-thread -// object managed by Google Test will be leaked as long as all threads -// using Google Test have exited when main() returns. -template -class ThreadLocal { - public: - ThreadLocal() : key_(CreateKey()), - default_() {} - explicit ThreadLocal(const T& value) : key_(CreateKey()), - default_(value) {} - - ~ThreadLocal() { - // Destroys the managed object for the current thread, if any. - DeleteThreadLocalValue(pthread_getspecific(key_)); - - // Releases resources associated with the key. This will *not* - // delete managed objects for other threads. - GTEST_CHECK_POSIX_SUCCESS_(pthread_key_delete(key_)); - } - - T* pointer() { return GetOrCreateValue(); } - const T* pointer() const { return GetOrCreateValue(); } - const T& get() const { return *pointer(); } - void set(const T& value) { *pointer() = value; } - - private: - // Holds a value of type T. - class ValueHolder : public ThreadLocalValueHolderBase { - public: - explicit ValueHolder(const T& value) : value_(value) {} - - T* pointer() { return &value_; } - - private: - T value_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(ValueHolder); - }; - - static pthread_key_t CreateKey() { - pthread_key_t key; - // When a thread exits, DeleteThreadLocalValue() will be called on - // the object managed for that thread. - GTEST_CHECK_POSIX_SUCCESS_( - pthread_key_create(&key, &DeleteThreadLocalValue)); - return key; - } - - T* GetOrCreateValue() const { - ThreadLocalValueHolderBase* const holder = - static_cast(pthread_getspecific(key_)); - if (holder != NULL) { - return CheckedDowncastToActualType(holder)->pointer(); - } - - ValueHolder* const new_holder = new ValueHolder(default_); - ThreadLocalValueHolderBase* const holder_base = new_holder; - GTEST_CHECK_POSIX_SUCCESS_(pthread_setspecific(key_, holder_base)); - return new_holder->pointer(); - } - - // A key pthreads uses for looking up per-thread values. - const pthread_key_t key_; - const T default_; // The default value for each thread. - - GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocal); -}; - -# define GTEST_IS_THREADSAFE 1 - -#else // GTEST_HAS_PTHREAD - -// A dummy implementation of synchronization primitives (mutex, lock, -// and thread-local variable). Necessary for compiling Google Test where -// mutex is not supported - using Google Test in multiple threads is not -// supported on such platforms. - -class Mutex { - public: - Mutex() {} - void Lock() {} - void Unlock() {} - void AssertHeld() const {} -}; - -# define GTEST_DECLARE_STATIC_MUTEX_(mutex) \ - extern ::testing::internal::Mutex mutex - -# define GTEST_DEFINE_STATIC_MUTEX_(mutex) ::testing::internal::Mutex mutex - -class GTestMutexLock { - public: - explicit GTestMutexLock(Mutex*) {} // NOLINT -}; - -typedef GTestMutexLock MutexLock; - -template -class ThreadLocal { - public: - ThreadLocal() : value_() {} - explicit ThreadLocal(const T& value) : value_(value) {} - T* pointer() { return &value_; } - const T* pointer() const { return &value_; } - const T& get() const { return value_; } - void set(const T& value) { value_ = value; } - private: - T value_; -}; - -// The above synchronization primitives have dummy implementations. -// Therefore Google Test is not thread-safe. -# define GTEST_IS_THREADSAFE 0 - -#endif // GTEST_HAS_PTHREAD - -// Returns the number of threads running in the process, or 0 to indicate that -// we cannot detect it. -GTEST_API_ size_t GetThreadCount(); - -// Passing non-POD classes through ellipsis (...) crashes the ARM -// compiler and generates a warning in Sun Studio. The Nokia Symbian -// and the IBM XL C/C++ compiler try to instantiate a copy constructor -// for objects passed through ellipsis (...), failing for uncopyable -// objects. We define this to ensure that only POD is passed through -// ellipsis on these systems. -#if defined(__SYMBIAN32__) || defined(__IBMCPP__) || defined(__SUNPRO_CC) -// We lose support for NULL detection where the compiler doesn't like -// passing non-POD classes through ellipsis (...). -# define GTEST_ELLIPSIS_NEEDS_POD_ 1 -#else -# define GTEST_CAN_COMPARE_NULL 1 -#endif - -// The Nokia Symbian and IBM XL C/C++ compilers cannot decide between -// const T& and const T* in a function template. These compilers -// _can_ decide between class template specializations for T and T*, -// so a tr1::type_traits-like is_pointer works. -#if defined(__SYMBIAN32__) || defined(__IBMCPP__) -# define GTEST_NEEDS_IS_POINTER_ 1 -#endif - -template -struct bool_constant { - typedef bool_constant type; - static const bool value = bool_value; -}; -template const bool bool_constant::value; - -typedef bool_constant false_type; -typedef bool_constant true_type; - -template -struct is_pointer : public false_type {}; - -template -struct is_pointer : public true_type {}; - -template -struct IteratorTraits { - typedef typename Iterator::value_type value_type; -}; - -template -struct IteratorTraits { - typedef T value_type; -}; - -template -struct IteratorTraits { - typedef T value_type; -}; - -#if GTEST_OS_WINDOWS -# define GTEST_PATH_SEP_ "\\" -# define GTEST_HAS_ALT_PATH_SEP_ 1 -// The biggest signed integer type the compiler supports. -typedef __int64 BiggestInt; -#else -# define GTEST_PATH_SEP_ "/" -# define GTEST_HAS_ALT_PATH_SEP_ 0 -typedef long long BiggestInt; // NOLINT -#endif // GTEST_OS_WINDOWS - -// Utilities for char. - -// isspace(int ch) and friends accept an unsigned char or EOF. char -// may be signed, depending on the compiler (or compiler flags). -// Therefore we need to cast a char to unsigned char before calling -// isspace(), etc. - -inline bool IsAlpha(char ch) { - return isalpha(static_cast(ch)) != 0; -} -inline bool IsAlNum(char ch) { - return isalnum(static_cast(ch)) != 0; -} -inline bool IsDigit(char ch) { - return isdigit(static_cast(ch)) != 0; -} -inline bool IsLower(char ch) { - return islower(static_cast(ch)) != 0; -} -inline bool IsSpace(char ch) { - return isspace(static_cast(ch)) != 0; -} -inline bool IsUpper(char ch) { - return isupper(static_cast(ch)) != 0; -} -inline bool IsXDigit(char ch) { - return isxdigit(static_cast(ch)) != 0; -} -inline bool IsXDigit(wchar_t ch) { - const unsigned char low_byte = static_cast(ch); - return ch == low_byte && isxdigit(low_byte) != 0; -} - -inline char ToLower(char ch) { - return static_cast(tolower(static_cast(ch))); -} -inline char ToUpper(char ch) { - return static_cast(toupper(static_cast(ch))); -} - -// The testing::internal::posix namespace holds wrappers for common -// POSIX functions. These wrappers hide the differences between -// Windows/MSVC and POSIX systems. Since some compilers define these -// standard functions as macros, the wrapper cannot have the same name -// as the wrapped function. - -namespace posix { - -// Functions with a different name on Windows. - -#if GTEST_OS_WINDOWS - -typedef struct _stat StatStruct; - -# ifdef __BORLANDC__ -inline int IsATTY(int fd) { return isatty(fd); } -inline int StrCaseCmp(const char* s1, const char* s2) { - return stricmp(s1, s2); -} -inline char* StrDup(const char* src) { return strdup(src); } -# else // !__BORLANDC__ -# if GTEST_OS_WINDOWS_MOBILE -inline int IsATTY(int /* fd */) { return 0; } -# else -inline int IsATTY(int fd) { return _isatty(fd); } -# endif // GTEST_OS_WINDOWS_MOBILE -inline int StrCaseCmp(const char* s1, const char* s2) { - return _stricmp(s1, s2); -} -inline char* StrDup(const char* src) { return _strdup(src); } -# endif // __BORLANDC__ - -# if GTEST_OS_WINDOWS_MOBILE -inline int FileNo(FILE* file) { return reinterpret_cast(_fileno(file)); } -// Stat(), RmDir(), and IsDir() are not needed on Windows CE at this -// time and thus not defined there. -# else -inline int FileNo(FILE* file) { return _fileno(file); } -inline int Stat(const char* path, StatStruct* buf) { return _stat(path, buf); } -inline int RmDir(const char* dir) { return _rmdir(dir); } -inline bool IsDir(const StatStruct& st) { - return (_S_IFDIR & st.st_mode) != 0; -} -# endif // GTEST_OS_WINDOWS_MOBILE - -#else - -typedef struct stat StatStruct; - -inline int FileNo(FILE* file) { return fileno(file); } -inline int IsATTY(int fd) { return isatty(fd); } -inline int Stat(const char* path, StatStruct* buf) { return stat(path, buf); } -inline int StrCaseCmp(const char* s1, const char* s2) { - return strcasecmp(s1, s2); -} -inline char* StrDup(const char* src) { return strdup(src); } -inline int RmDir(const char* dir) { return rmdir(dir); } -inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); } - -#endif // GTEST_OS_WINDOWS - -// Functions deprecated by MSVC 8.0. - -#ifdef _MSC_VER -// Temporarily disable warning 4996 (deprecated function). -# pragma warning(push) -# pragma warning(disable:4996) -#endif - -inline const char* StrNCpy(char* dest, const char* src, size_t n) { - return strncpy(dest, src, n); -} - -// ChDir(), FReopen(), FDOpen(), Read(), Write(), Close(), and -// StrError() aren't needed on Windows CE at this time and thus not -// defined there. - -#if !GTEST_OS_WINDOWS_MOBILE -inline int ChDir(const char* dir) { return chdir(dir); } -#endif -inline FILE* FOpen(const char* path, const char* mode) { - return fopen(path, mode); -} -#if !GTEST_OS_WINDOWS_MOBILE -inline FILE *FReopen(const char* path, const char* mode, FILE* stream) { - return freopen(path, mode, stream); -} -inline FILE* FDOpen(int fd, const char* mode) { return fdopen(fd, mode); } -#endif -inline int FClose(FILE* fp) { return fclose(fp); } -#if !GTEST_OS_WINDOWS_MOBILE -inline int Read(int fd, void* buf, unsigned int count) { - return static_cast(read(fd, buf, count)); -} -inline int Write(int fd, const void* buf, unsigned int count) { - return static_cast(write(fd, buf, count)); -} -inline int Close(int fd) { return close(fd); } -inline const char* StrError(int errnum) { return strerror(errnum); } -#endif -inline const char* GetEnv(const char* name) { -#if GTEST_OS_WINDOWS_MOBILE - // We are on Windows CE, which has no environment variables. - return NULL; -#elif defined(__BORLANDC__) || defined(__SunOS_5_8) || defined(__SunOS_5_9) - // Environment variables which we programmatically clear will be set to the - // empty string rather than unset (NULL). Handle that case. - const char* const env = getenv(name); - return (env != NULL && env[0] != '\0') ? env : NULL; -#else - return getenv(name); -#endif -} - -#ifdef _MSC_VER -# pragma warning(pop) // Restores the warning state. -#endif - -#if GTEST_OS_WINDOWS_MOBILE -// Windows CE has no C library. The abort() function is used in -// several places in Google Test. This implementation provides a reasonable -// imitation of standard behaviour. -void Abort(); -#else -inline void Abort() { abort(); } -#endif // GTEST_OS_WINDOWS_MOBILE - -} // namespace posix - -// MSVC "deprecates" snprintf and issues warnings wherever it is used. In -// order to avoid these warnings, we need to use _snprintf or _snprintf_s on -// MSVC-based platforms. We map the GTEST_SNPRINTF_ macro to the appropriate -// function in order to achieve that. We use macro definition here because -// snprintf is a variadic function. -#if _MSC_VER >= 1400 && !GTEST_OS_WINDOWS_MOBILE -// MSVC 2005 and above support variadic macros. -# define GTEST_SNPRINTF_(buffer, size, format, ...) \ - _snprintf_s(buffer, size, size, format, __VA_ARGS__) -#elif defined(_MSC_VER) -// Windows CE does not define _snprintf_s and MSVC prior to 2005 doesn't -// complain about _snprintf. -# define GTEST_SNPRINTF_ _snprintf -#else -# define GTEST_SNPRINTF_ snprintf -#endif - -// The maximum number a BiggestInt can represent. This definition -// works no matter BiggestInt is represented in one's complement or -// two's complement. -// -// We cannot rely on numeric_limits in STL, as __int64 and long long -// are not part of standard C++ and numeric_limits doesn't need to be -// defined for them. -const BiggestInt kMaxBiggestInt = - ~(static_cast(1) << (8*sizeof(BiggestInt) - 1)); - -// This template class serves as a compile-time function from size to -// type. It maps a size in bytes to a primitive type with that -// size. e.g. -// -// TypeWithSize<4>::UInt -// -// is typedef-ed to be unsigned int (unsigned integer made up of 4 -// bytes). -// -// Such functionality should belong to STL, but I cannot find it -// there. -// -// Google Test uses this class in the implementation of floating-point -// comparison. -// -// For now it only handles UInt (unsigned int) as that's all Google Test -// needs. Other types can be easily added in the future if need -// arises. -template -class TypeWithSize { - public: - // This prevents the user from using TypeWithSize with incorrect - // values of N. - typedef void UInt; -}; - -// The specialization for size 4. -template <> -class TypeWithSize<4> { - public: - // unsigned int has size 4 in both gcc and MSVC. - // - // As base/basictypes.h doesn't compile on Windows, we cannot use - // uint32, uint64, and etc here. - typedef int Int; - typedef unsigned int UInt; -}; - -// The specialization for size 8. -template <> -class TypeWithSize<8> { - public: -#if GTEST_OS_WINDOWS - typedef __int64 Int; - typedef unsigned __int64 UInt; -#else - typedef long long Int; // NOLINT - typedef unsigned long long UInt; // NOLINT -#endif // GTEST_OS_WINDOWS -}; - -// Integer types of known sizes. -typedef TypeWithSize<4>::Int Int32; -typedef TypeWithSize<4>::UInt UInt32; -typedef TypeWithSize<8>::Int Int64; -typedef TypeWithSize<8>::UInt UInt64; -typedef TypeWithSize<8>::Int TimeInMillis; // Represents time in milliseconds. - -// Utilities for command line flags and environment variables. - -// Macro for referencing flags. -#define GTEST_FLAG(name) FLAGS_gtest_##name - -// Macros for declaring flags. -#define GTEST_DECLARE_bool_(name) GTEST_API_ extern bool GTEST_FLAG(name) -#define GTEST_DECLARE_int32_(name) \ - GTEST_API_ extern ::testing::internal::Int32 GTEST_FLAG(name) -#define GTEST_DECLARE_string_(name) \ - GTEST_API_ extern ::std::string GTEST_FLAG(name) - -// Macros for defining flags. -#define GTEST_DEFINE_bool_(name, default_val, doc) \ - GTEST_API_ bool GTEST_FLAG(name) = (default_val) -#define GTEST_DEFINE_int32_(name, default_val, doc) \ - GTEST_API_ ::testing::internal::Int32 GTEST_FLAG(name) = (default_val) -#define GTEST_DEFINE_string_(name, default_val, doc) \ - GTEST_API_ ::std::string GTEST_FLAG(name) = (default_val) - -// Thread annotations -#define GTEST_EXCLUSIVE_LOCK_REQUIRED_(locks) -#define GTEST_LOCK_EXCLUDED_(locks) - -// Parses 'str' for a 32-bit signed integer. If successful, writes the result -// to *value and returns true; otherwise leaves *value unchanged and returns -// false. -// TODO(chandlerc): Find a better way to refactor flag and environment parsing -// out of both gtest-port.cc and gtest.cc to avoid exporting this utility -// function. -bool ParseInt32(const Message& src_text, const char* str, Int32* value); - -// Parses a bool/Int32/string from the environment variable -// corresponding to the given Google Test flag. -bool BoolFromGTestEnv(const char* flag, bool default_val); -GTEST_API_ Int32 Int32FromGTestEnv(const char* flag, Int32 default_val); -const char* StringFromGTestEnv(const char* flag, const char* default_val); - -} // namespace internal -} // namespace testing - -#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ - -#if GTEST_OS_LINUX -# include -# include -# include -# include -#endif // GTEST_OS_LINUX - -#if GTEST_HAS_EXCEPTIONS -# include -#endif - -#include -#include -#include -#include -#include -#include - -// Copyright 2005, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: wan@google.com (Zhanyong Wan) -// -// The Google C++ Testing Framework (Google Test) -// -// This header file defines the Message class. -// -// IMPORTANT NOTE: Due to limitation of the C++ language, we have to -// leave some internal implementation details in this header file. -// They are clearly marked by comments like this: -// -// // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. -// -// Such code is NOT meant to be used by a user directly, and is subject -// to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user -// program! - -#ifndef GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ -#define GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ - -#include - - -// Ensures that there is at least one operator<< in the global namespace. -// See Message& operator<<(...) below for why. -void operator<<(const testing::internal::Secret&, int); - -namespace testing { - -// The Message class works like an ostream repeater. -// -// Typical usage: -// -// 1. You stream a bunch of values to a Message object. -// It will remember the text in a stringstream. -// 2. Then you stream the Message object to an ostream. -// This causes the text in the Message to be streamed -// to the ostream. -// -// For example; -// -// testing::Message foo; -// foo << 1 << " != " << 2; -// std::cout << foo; -// -// will print "1 != 2". -// -// Message is not intended to be inherited from. In particular, its -// destructor is not virtual. -// -// Note that stringstream behaves differently in gcc and in MSVC. You -// can stream a NULL char pointer to it in the former, but not in the -// latter (it causes an access violation if you do). The Message -// class hides this difference by treating a NULL char pointer as -// "(null)". -class GTEST_API_ Message { - private: - // The type of basic IO manipulators (endl, ends, and flush) for - // narrow streams. - typedef std::ostream& (*BasicNarrowIoManip)(std::ostream&); - - public: - // Constructs an empty Message. - Message(); - - // Copy constructor. - Message(const Message& msg) : ss_(new ::std::stringstream) { // NOLINT - *ss_ << msg.GetString(); - } - - // Constructs a Message from a C-string. - explicit Message(const char* str) : ss_(new ::std::stringstream) { - *ss_ << str; - } - -#if GTEST_OS_SYMBIAN - // Streams a value (either a pointer or not) to this object. - template - inline Message& operator <<(const T& value) { - StreamHelper(typename internal::is_pointer::type(), value); - return *this; - } -#else - // Streams a non-pointer value to this object. - template - inline Message& operator <<(const T& val) { - // Some libraries overload << for STL containers. These - // overloads are defined in the global namespace instead of ::std. - // - // C++'s symbol lookup rule (i.e. Koenig lookup) says that these - // overloads are visible in either the std namespace or the global - // namespace, but not other namespaces, including the testing - // namespace which Google Test's Message class is in. - // - // To allow STL containers (and other types that has a << operator - // defined in the global namespace) to be used in Google Test - // assertions, testing::Message must access the custom << operator - // from the global namespace. With this using declaration, - // overloads of << defined in the global namespace and those - // visible via Koenig lookup are both exposed in this function. - using ::operator <<; - *ss_ << val; - return *this; - } - - // Streams a pointer value to this object. - // - // This function is an overload of the previous one. When you - // stream a pointer to a Message, this definition will be used as it - // is more specialized. (The C++ Standard, section - // [temp.func.order].) If you stream a non-pointer, then the - // previous definition will be used. - // - // The reason for this overload is that streaming a NULL pointer to - // ostream is undefined behavior. Depending on the compiler, you - // may get "0", "(nil)", "(null)", or an access violation. To - // ensure consistent result across compilers, we always treat NULL - // as "(null)". - template - inline Message& operator <<(T* const& pointer) { // NOLINT - if (pointer == NULL) { - *ss_ << "(null)"; - } else { - *ss_ << pointer; - } - return *this; - } -#endif // GTEST_OS_SYMBIAN - - // Since the basic IO manipulators are overloaded for both narrow - // and wide streams, we have to provide this specialized definition - // of operator <<, even though its body is the same as the - // templatized version above. Without this definition, streaming - // endl or other basic IO manipulators to Message will confuse the - // compiler. - Message& operator <<(BasicNarrowIoManip val) { - *ss_ << val; - return *this; - } - - // Instead of 1/0, we want to see true/false for bool values. - Message& operator <<(bool b) { - return *this << (b ? "true" : "false"); - } - - // These two overloads allow streaming a wide C string to a Message - // using the UTF-8 encoding. - Message& operator <<(const wchar_t* wide_c_str); - Message& operator <<(wchar_t* wide_c_str); - -#if GTEST_HAS_STD_WSTRING - // Converts the given wide string to a narrow string using the UTF-8 - // encoding, and streams the result to this Message object. - Message& operator <<(const ::std::wstring& wstr); -#endif // GTEST_HAS_STD_WSTRING - -#if GTEST_HAS_GLOBAL_WSTRING - // Converts the given wide string to a narrow string using the UTF-8 - // encoding, and streams the result to this Message object. - Message& operator <<(const ::wstring& wstr); -#endif // GTEST_HAS_GLOBAL_WSTRING - - // Gets the text streamed to this object so far as an std::string. - // Each '\0' character in the buffer is replaced with "\\0". - // - // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. - std::string GetString() const; - - private: - -#if GTEST_OS_SYMBIAN - // These are needed as the Nokia Symbian Compiler cannot decide between - // const T& and const T* in a function template. The Nokia compiler _can_ - // decide between class template specializations for T and T*, so a - // tr1::type_traits-like is_pointer works, and we can overload on that. - template - inline void StreamHelper(internal::true_type /*is_pointer*/, T* pointer) { - if (pointer == NULL) { - *ss_ << "(null)"; - } else { - *ss_ << pointer; - } - } - template - inline void StreamHelper(internal::false_type /*is_pointer*/, - const T& value) { - // See the comments in Message& operator <<(const T&) above for why - // we need this using statement. - using ::operator <<; - *ss_ << value; - } -#endif // GTEST_OS_SYMBIAN - - // We'll hold the text streamed to this object here. - const internal::scoped_ptr< ::std::stringstream> ss_; - - // We declare (but don't implement) this to prevent the compiler - // from implementing the assignment operator. - void operator=(const Message&); -}; - -// Streams a Message to an ostream. -inline std::ostream& operator <<(std::ostream& os, const Message& sb) { - return os << sb.GetString(); -} - -namespace internal { - -// Converts a streamable value to an std::string. A NULL pointer is -// converted to "(null)". When the input value is a ::string, -// ::std::string, ::wstring, or ::std::wstring object, each NUL -// character in it is replaced with "\\0". -template -std::string StreamableToString(const T& streamable) { - return (Message() << streamable).GetString(); -} - -} // namespace internal -} // namespace testing - -#endif // GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ -// Copyright 2005, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee) -// -// The Google C++ Testing Framework (Google Test) -// -// This header file declares the String class and functions used internally by -// Google Test. They are subject to change without notice. They should not used -// by code external to Google Test. -// -// This header file is #included by . -// It should not be #included by other files. - -#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ -#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ - -#ifdef __BORLANDC__ -// string.h is not guaranteed to provide strcpy on C++ Builder. -# include -#endif - -#include -#include - - -namespace testing { -namespace internal { - -// String - an abstract class holding static string utilities. -class GTEST_API_ String { - public: - // Static utility methods - - // Clones a 0-terminated C string, allocating memory using new. The - // caller is responsible for deleting the return value using - // delete[]. Returns the cloned string, or NULL if the input is - // NULL. - // - // This is different from strdup() in string.h, which allocates - // memory using malloc(). - static const char* CloneCString(const char* c_str); - -#if GTEST_OS_WINDOWS_MOBILE - // Windows CE does not have the 'ANSI' versions of Win32 APIs. To be - // able to pass strings to Win32 APIs on CE we need to convert them - // to 'Unicode', UTF-16. - - // Creates a UTF-16 wide string from the given ANSI string, allocating - // memory using new. The caller is responsible for deleting the return - // value using delete[]. Returns the wide string, or NULL if the - // input is NULL. - // - // The wide string is created using the ANSI codepage (CP_ACP) to - // match the behaviour of the ANSI versions of Win32 calls and the - // C runtime. - static LPCWSTR AnsiToUtf16(const char* c_str); - - // Creates an ANSI string from the given wide string, allocating - // memory using new. The caller is responsible for deleting the return - // value using delete[]. Returns the ANSI string, or NULL if the - // input is NULL. - // - // The returned string is created using the ANSI codepage (CP_ACP) to - // match the behaviour of the ANSI versions of Win32 calls and the - // C runtime. - static const char* Utf16ToAnsi(LPCWSTR utf16_str); -#endif - - // Compares two C strings. Returns true iff they have the same content. - // - // Unlike strcmp(), this function can handle NULL argument(s). A - // NULL C string is considered different to any non-NULL C string, - // including the empty string. - static bool CStringEquals(const char* lhs, const char* rhs); - - // Converts a wide C string to a String using the UTF-8 encoding. - // NULL will be converted to "(null)". If an error occurred during - // the conversion, "(failed to convert from wide string)" is - // returned. - static std::string ShowWideCString(const wchar_t* wide_c_str); - - // Compares two wide C strings. Returns true iff they have the same - // content. - // - // Unlike wcscmp(), this function can handle NULL argument(s). A - // NULL C string is considered different to any non-NULL C string, - // including the empty string. - static bool WideCStringEquals(const wchar_t* lhs, const wchar_t* rhs); - - // Compares two C strings, ignoring case. Returns true iff they - // have the same content. - // - // Unlike strcasecmp(), this function can handle NULL argument(s). - // A NULL C string is considered different to any non-NULL C string, - // including the empty string. - static bool CaseInsensitiveCStringEquals(const char* lhs, - const char* rhs); - - // Compares two wide C strings, ignoring case. Returns true iff they - // have the same content. - // - // Unlike wcscasecmp(), this function can handle NULL argument(s). - // A NULL C string is considered different to any non-NULL wide C string, - // including the empty string. - // NB: The implementations on different platforms slightly differ. - // On windows, this method uses _wcsicmp which compares according to LC_CTYPE - // environment variable. On GNU platform this method uses wcscasecmp - // which compares according to LC_CTYPE category of the current locale. - // On MacOS X, it uses towlower, which also uses LC_CTYPE category of the - // current locale. - static bool CaseInsensitiveWideCStringEquals(const wchar_t* lhs, - const wchar_t* rhs); - - // Returns true iff the given string ends with the given suffix, ignoring - // case. Any string is considered to end with an empty suffix. - static bool EndsWithCaseInsensitive( - const std::string& str, const std::string& suffix); - - // Formats an int value as "%02d". - static std::string FormatIntWidth2(int value); // "%02d" for width == 2 - - // Formats an int value as "%X". - static std::string FormatHexInt(int value); - - // Formats a byte as "%02X". - static std::string FormatByte(unsigned char value); - - private: - String(); // Not meant to be instantiated. -}; // class String - -// Gets the content of the stringstream's buffer as an std::string. Each '\0' -// character in the buffer is replaced with "\\0". -GTEST_API_ std::string StringStreamToString(::std::stringstream* stream); - -} // namespace internal -} // namespace testing - -#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ -// Copyright 2008, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: keith.ray@gmail.com (Keith Ray) -// -// Google Test filepath utilities -// -// This header file declares classes and functions used internally by -// Google Test. They are subject to change without notice. -// -// This file is #included in . -// Do not include this header file separately! - -#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ -#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ - - -namespace testing { -namespace internal { - -// FilePath - a class for file and directory pathname manipulation which -// handles platform-specific conventions (like the pathname separator). -// Used for helper functions for naming files in a directory for xml output. -// Except for Set methods, all methods are const or static, which provides an -// "immutable value object" -- useful for peace of mind. -// A FilePath with a value ending in a path separator ("like/this/") represents -// a directory, otherwise it is assumed to represent a file. In either case, -// it may or may not represent an actual file or directory in the file system. -// Names are NOT checked for syntax correctness -- no checking for illegal -// characters, malformed paths, etc. - -class GTEST_API_ FilePath { - public: - FilePath() : pathname_("") { } - FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) { } - - explicit FilePath(const std::string& pathname) : pathname_(pathname) { - Normalize(); - } - - FilePath& operator=(const FilePath& rhs) { - Set(rhs); - return *this; - } - - void Set(const FilePath& rhs) { - pathname_ = rhs.pathname_; - } - - const std::string& string() const { return pathname_; } - const char* c_str() const { return pathname_.c_str(); } - - // Returns the current working directory, or "" if unsuccessful. - static FilePath GetCurrentDir(); - - // Given directory = "dir", base_name = "test", number = 0, - // extension = "xml", returns "dir/test.xml". If number is greater - // than zero (e.g., 12), returns "dir/test_12.xml". - // On Windows platform, uses \ as the separator rather than /. - static FilePath MakeFileName(const FilePath& directory, - const FilePath& base_name, - int number, - const char* extension); - - // Given directory = "dir", relative_path = "test.xml", - // returns "dir/test.xml". - // On Windows, uses \ as the separator rather than /. - static FilePath ConcatPaths(const FilePath& directory, - const FilePath& relative_path); - - // Returns a pathname for a file that does not currently exist. The pathname - // will be directory/base_name.extension or - // directory/base_name_.extension if directory/base_name.extension - // already exists. The number will be incremented until a pathname is found - // that does not already exist. - // Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'. - // There could be a race condition if two or more processes are calling this - // function at the same time -- they could both pick the same filename. - static FilePath GenerateUniqueFileName(const FilePath& directory, - const FilePath& base_name, - const char* extension); - - // Returns true iff the path is "". - bool IsEmpty() const { return pathname_.empty(); } - - // If input name has a trailing separator character, removes it and returns - // the name, otherwise return the name string unmodified. - // On Windows platform, uses \ as the separator, other platforms use /. - FilePath RemoveTrailingPathSeparator() const; - - // Returns a copy of the FilePath with the directory part removed. - // Example: FilePath("path/to/file").RemoveDirectoryName() returns - // FilePath("file"). If there is no directory part ("just_a_file"), it returns - // the FilePath unmodified. If there is no file part ("just_a_dir/") it - // returns an empty FilePath (""). - // On Windows platform, '\' is the path separator, otherwise it is '/'. - FilePath RemoveDirectoryName() const; - - // RemoveFileName returns the directory path with the filename removed. - // Example: FilePath("path/to/file").RemoveFileName() returns "path/to/". - // If the FilePath is "a_file" or "/a_file", RemoveFileName returns - // FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does - // not have a file, like "just/a/dir/", it returns the FilePath unmodified. - // On Windows platform, '\' is the path separator, otherwise it is '/'. - FilePath RemoveFileName() const; - - // Returns a copy of the FilePath with the case-insensitive extension removed. - // Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns - // FilePath("dir/file"). If a case-insensitive extension is not - // found, returns a copy of the original FilePath. - FilePath RemoveExtension(const char* extension) const; - - // Creates directories so that path exists. Returns true if successful or if - // the directories already exist; returns false if unable to create - // directories for any reason. Will also return false if the FilePath does - // not represent a directory (that is, it doesn't end with a path separator). - bool CreateDirectoriesRecursively() const; - - // Create the directory so that path exists. Returns true if successful or - // if the directory already exists; returns false if unable to create the - // directory for any reason, including if the parent directory does not - // exist. Not named "CreateDirectory" because that's a macro on Windows. - bool CreateFolder() const; - - // Returns true if FilePath describes something in the file-system, - // either a file, directory, or whatever, and that something exists. - bool FileOrDirectoryExists() const; - - // Returns true if pathname describes a directory in the file-system - // that exists. - bool DirectoryExists() const; - - // Returns true if FilePath ends with a path separator, which indicates that - // it is intended to represent a directory. Returns false otherwise. - // This does NOT check that a directory (or file) actually exists. - bool IsDirectory() const; - - // Returns true if pathname describes a root directory. (Windows has one - // root directory per disk drive.) - bool IsRootDirectory() const; - - // Returns true if pathname describes an absolute path. - bool IsAbsolutePath() const; - - private: - // Replaces multiple consecutive separators with a single separator. - // For example, "bar///foo" becomes "bar/foo". Does not eliminate other - // redundancies that might be in a pathname involving "." or "..". - // - // A pathname with multiple consecutive separators may occur either through - // user error or as a result of some scripts or APIs that generate a pathname - // with a trailing separator. On other platforms the same API or script - // may NOT generate a pathname with a trailing "/". Then elsewhere that - // pathname may have another "/" and pathname components added to it, - // without checking for the separator already being there. - // The script language and operating system may allow paths like "foo//bar" - // but some of the functions in FilePath will not handle that correctly. In - // particular, RemoveTrailingPathSeparator() only removes one separator, and - // it is called in CreateDirectoriesRecursively() assuming that it will change - // a pathname from directory syntax (trailing separator) to filename syntax. - // - // On Windows this method also replaces the alternate path separator '/' with - // the primary path separator '\\', so that for example "bar\\/\\foo" becomes - // "bar\\foo". - - void Normalize(); - - // Returns a pointer to the last occurence of a valid path separator in - // the FilePath. On Windows, for example, both '/' and '\' are valid path - // separators. Returns NULL if no path separator was found. - const char* FindLastPathSeparator() const; - - std::string pathname_; -}; // class FilePath - -} // namespace internal -} // namespace testing - -#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ -// This file was GENERATED by command: -// pump.py gtest-type-util.h.pump -// DO NOT EDIT BY HAND!!! - -// Copyright 2008 Google Inc. -// All Rights Reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: wan@google.com (Zhanyong Wan) - -// Type utilities needed for implementing typed and type-parameterized -// tests. This file is generated by a SCRIPT. DO NOT EDIT BY HAND! -// -// Currently we support at most 50 types in a list, and at most 50 -// type-parameterized tests in one type-parameterized test case. -// Please contact googletestframework@googlegroups.com if you need -// more. - -#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ -#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ - - -// #ifdef __GNUC__ is too general here. It is possible to use gcc without using -// libstdc++ (which is where cxxabi.h comes from). -# if GTEST_HAS_CXXABI_H_ -# include -# elif defined(__HP_aCC) -# include -# endif // GTEST_HASH_CXXABI_H_ - -namespace testing { -namespace internal { - -// GetTypeName() returns a human-readable name of type T. -// NB: This function is also used in Google Mock, so don't move it inside of -// the typed-test-only section below. -template -std::string GetTypeName() { -# if GTEST_HAS_RTTI - - const char* const name = typeid(T).name(); -# if GTEST_HAS_CXXABI_H_ || defined(__HP_aCC) - int status = 0; - // gcc's implementation of typeid(T).name() mangles the type name, - // so we have to demangle it. -# if GTEST_HAS_CXXABI_H_ - using abi::__cxa_demangle; -# endif // GTEST_HAS_CXXABI_H_ - char* const readable_name = __cxa_demangle(name, 0, 0, &status); - const std::string name_str(status == 0 ? readable_name : name); - free(readable_name); - return name_str; -# else - return name; -# endif // GTEST_HAS_CXXABI_H_ || __HP_aCC - -# else - - return ""; - -# endif // GTEST_HAS_RTTI -} - -#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P - -// AssertyTypeEq::type is defined iff T1 and T2 are the same -// type. This can be used as a compile-time assertion to ensure that -// two types are equal. - -template -struct AssertTypeEq; - -template -struct AssertTypeEq { - typedef bool type; -}; - -// A unique type used as the default value for the arguments of class -// template Types. This allows us to simulate variadic templates -// (e.g. Types, Type, and etc), which C++ doesn't -// support directly. -struct None {}; - -// The following family of struct and struct templates are used to -// represent type lists. In particular, TypesN -// represents a type list with N types (T1, T2, ..., and TN) in it. -// Except for Types0, every struct in the family has two member types: -// Head for the first type in the list, and Tail for the rest of the -// list. - -// The empty type list. -struct Types0 {}; - -// Type lists of length 1, 2, 3, and so on. - -template -struct Types1 { - typedef T1 Head; - typedef Types0 Tail; -}; -template -struct Types2 { - typedef T1 Head; - typedef Types1 Tail; -}; - -template -struct Types3 { - typedef T1 Head; - typedef Types2 Tail; -}; - -template -struct Types4 { - typedef T1 Head; - typedef Types3 Tail; -}; - -template -struct Types5 { - typedef T1 Head; - typedef Types4 Tail; -}; - -template -struct Types6 { - typedef T1 Head; - typedef Types5 Tail; -}; - -template -struct Types7 { - typedef T1 Head; - typedef Types6 Tail; -}; - -template -struct Types8 { - typedef T1 Head; - typedef Types7 Tail; -}; - -template -struct Types9 { - typedef T1 Head; - typedef Types8 Tail; -}; - -template -struct Types10 { - typedef T1 Head; - typedef Types9 Tail; -}; - -template -struct Types11 { - typedef T1 Head; - typedef Types10 Tail; -}; - -template -struct Types12 { - typedef T1 Head; - typedef Types11 Tail; -}; - -template -struct Types13 { - typedef T1 Head; - typedef Types12 Tail; -}; - -template -struct Types14 { - typedef T1 Head; - typedef Types13 Tail; -}; - -template -struct Types15 { - typedef T1 Head; - typedef Types14 Tail; -}; - -template -struct Types16 { - typedef T1 Head; - typedef Types15 Tail; -}; - -template -struct Types17 { - typedef T1 Head; - typedef Types16 Tail; -}; - -template -struct Types18 { - typedef T1 Head; - typedef Types17 Tail; -}; - -template -struct Types19 { - typedef T1 Head; - typedef Types18 Tail; -}; - -template -struct Types20 { - typedef T1 Head; - typedef Types19 Tail; -}; - -template -struct Types21 { - typedef T1 Head; - typedef Types20 Tail; -}; - -template -struct Types22 { - typedef T1 Head; - typedef Types21 Tail; -}; - -template -struct Types23 { - typedef T1 Head; - typedef Types22 Tail; -}; - -template -struct Types24 { - typedef T1 Head; - typedef Types23 Tail; -}; - -template -struct Types25 { - typedef T1 Head; - typedef Types24 Tail; -}; - -template -struct Types26 { - typedef T1 Head; - typedef Types25 Tail; -}; - -template -struct Types27 { - typedef T1 Head; - typedef Types26 Tail; -}; - -template -struct Types28 { - typedef T1 Head; - typedef Types27 Tail; -}; - -template -struct Types29 { - typedef T1 Head; - typedef Types28 Tail; -}; - -template -struct Types30 { - typedef T1 Head; - typedef Types29 Tail; -}; - -template -struct Types31 { - typedef T1 Head; - typedef Types30 Tail; -}; - -template -struct Types32 { - typedef T1 Head; - typedef Types31 Tail; -}; - -template -struct Types33 { - typedef T1 Head; - typedef Types32 Tail; -}; - -template -struct Types34 { - typedef T1 Head; - typedef Types33 Tail; -}; - -template -struct Types35 { - typedef T1 Head; - typedef Types34 Tail; -}; - -template -struct Types36 { - typedef T1 Head; - typedef Types35 Tail; -}; - -template -struct Types37 { - typedef T1 Head; - typedef Types36 Tail; -}; - -template -struct Types38 { - typedef T1 Head; - typedef Types37 Tail; -}; - -template -struct Types39 { - typedef T1 Head; - typedef Types38 Tail; -}; - -template -struct Types40 { - typedef T1 Head; - typedef Types39 Tail; -}; - -template -struct Types41 { - typedef T1 Head; - typedef Types40 Tail; -}; - -template -struct Types42 { - typedef T1 Head; - typedef Types41 Tail; -}; - -template -struct Types43 { - typedef T1 Head; - typedef Types42 Tail; -}; - -template -struct Types44 { - typedef T1 Head; - typedef Types43 Tail; -}; - -template -struct Types45 { - typedef T1 Head; - typedef Types44 Tail; -}; - -template -struct Types46 { - typedef T1 Head; - typedef Types45 Tail; -}; - -template -struct Types47 { - typedef T1 Head; - typedef Types46 Tail; -}; - -template -struct Types48 { - typedef T1 Head; - typedef Types47 Tail; -}; - -template -struct Types49 { - typedef T1 Head; - typedef Types48 Tail; -}; - -template -struct Types50 { - typedef T1 Head; - typedef Types49 Tail; -}; - - -} // namespace internal - -// We don't want to require the users to write TypesN<...> directly, -// as that would require them to count the length. Types<...> is much -// easier to write, but generates horrible messages when there is a -// compiler error, as gcc insists on printing out each template -// argument, even if it has the default value (this means Types -// will appear as Types in the compiler -// errors). -// -// Our solution is to combine the best part of the two approaches: a -// user would write Types, and Google Test will translate -// that to TypesN internally to make error messages -// readable. The translation is done by the 'type' member of the -// Types template. -template -struct Types { - typedef internal::Types50 type; -}; - -template <> -struct Types { - typedef internal::Types0 type; -}; -template -struct Types { - typedef internal::Types1 type; -}; -template -struct Types { - typedef internal::Types2 type; -}; -template -struct Types { - typedef internal::Types3 type; -}; -template -struct Types { - typedef internal::Types4 type; -}; -template -struct Types { - typedef internal::Types5 type; -}; -template -struct Types { - typedef internal::Types6 type; -}; -template -struct Types { - typedef internal::Types7 type; -}; -template -struct Types { - typedef internal::Types8 type; -}; -template -struct Types { - typedef internal::Types9 type; -}; -template -struct Types { - typedef internal::Types10 type; -}; -template -struct Types { - typedef internal::Types11 type; -}; -template -struct Types { - typedef internal::Types12 type; -}; -template -struct Types { - typedef internal::Types13 type; -}; -template -struct Types { - typedef internal::Types14 type; -}; -template -struct Types { - typedef internal::Types15 type; -}; -template -struct Types { - typedef internal::Types16 type; -}; -template -struct Types { - typedef internal::Types17 type; -}; -template -struct Types { - typedef internal::Types18 type; -}; -template -struct Types { - typedef internal::Types19 type; -}; -template -struct Types { - typedef internal::Types20 type; -}; -template -struct Types { - typedef internal::Types21 type; -}; -template -struct Types { - typedef internal::Types22 type; -}; -template -struct Types { - typedef internal::Types23 type; -}; -template -struct Types { - typedef internal::Types24 type; -}; -template -struct Types { - typedef internal::Types25 type; -}; -template -struct Types { - typedef internal::Types26 type; -}; -template -struct Types { - typedef internal::Types27 type; -}; -template -struct Types { - typedef internal::Types28 type; -}; -template -struct Types { - typedef internal::Types29 type; -}; -template -struct Types { - typedef internal::Types30 type; -}; -template -struct Types { - typedef internal::Types31 type; -}; -template -struct Types { - typedef internal::Types32 type; -}; -template -struct Types { - typedef internal::Types33 type; -}; -template -struct Types { - typedef internal::Types34 type; -}; -template -struct Types { - typedef internal::Types35 type; -}; -template -struct Types { - typedef internal::Types36 type; -}; -template -struct Types { - typedef internal::Types37 type; -}; -template -struct Types { - typedef internal::Types38 type; -}; -template -struct Types { - typedef internal::Types39 type; -}; -template -struct Types { - typedef internal::Types40 type; -}; -template -struct Types { - typedef internal::Types41 type; -}; -template -struct Types { - typedef internal::Types42 type; -}; -template -struct Types { - typedef internal::Types43 type; -}; -template -struct Types { - typedef internal::Types44 type; -}; -template -struct Types { - typedef internal::Types45 type; -}; -template -struct Types { - typedef internal::Types46 type; -}; -template -struct Types { - typedef internal::Types47 type; -}; -template -struct Types { - typedef internal::Types48 type; -}; -template -struct Types { - typedef internal::Types49 type; -}; - -namespace internal { - -# define GTEST_TEMPLATE_ template class - -// The template "selector" struct TemplateSel is used to -// represent Tmpl, which must be a class template with one type -// parameter, as a type. TemplateSel::Bind::type is defined -// as the type Tmpl. This allows us to actually instantiate the -// template "selected" by TemplateSel. -// -// This trick is necessary for simulating typedef for class templates, -// which C++ doesn't support directly. -template -struct TemplateSel { - template - struct Bind { - typedef Tmpl type; - }; -}; - -# define GTEST_BIND_(TmplSel, T) \ - TmplSel::template Bind::type - -// A unique struct template used as the default value for the -// arguments of class template Templates. This allows us to simulate -// variadic templates (e.g. Templates, Templates, -// and etc), which C++ doesn't support directly. -template -struct NoneT {}; - -// The following family of struct and struct templates are used to -// represent template lists. In particular, TemplatesN represents a list of N templates (T1, T2, ..., and TN). Except -// for Templates0, every struct in the family has two member types: -// Head for the selector of the first template in the list, and Tail -// for the rest of the list. - -// The empty template list. -struct Templates0 {}; - -// Template lists of length 1, 2, 3, and so on. - -template -struct Templates1 { - typedef TemplateSel Head; - typedef Templates0 Tail; -}; -template -struct Templates2 { - typedef TemplateSel Head; - typedef Templates1 Tail; -}; - -template -struct Templates3 { - typedef TemplateSel Head; - typedef Templates2 Tail; -}; - -template -struct Templates4 { - typedef TemplateSel Head; - typedef Templates3 Tail; -}; - -template -struct Templates5 { - typedef TemplateSel Head; - typedef Templates4 Tail; -}; - -template -struct Templates6 { - typedef TemplateSel Head; - typedef Templates5 Tail; -}; - -template -struct Templates7 { - typedef TemplateSel Head; - typedef Templates6 Tail; -}; - -template -struct Templates8 { - typedef TemplateSel Head; - typedef Templates7 Tail; -}; - -template -struct Templates9 { - typedef TemplateSel Head; - typedef Templates8 Tail; -}; - -template -struct Templates10 { - typedef TemplateSel Head; - typedef Templates9 Tail; -}; - -template -struct Templates11 { - typedef TemplateSel Head; - typedef Templates10 Tail; -}; - -template -struct Templates12 { - typedef TemplateSel Head; - typedef Templates11 Tail; -}; - -template -struct Templates13 { - typedef TemplateSel Head; - typedef Templates12 Tail; -}; - -template -struct Templates14 { - typedef TemplateSel Head; - typedef Templates13 Tail; -}; - -template -struct Templates15 { - typedef TemplateSel Head; - typedef Templates14 Tail; -}; - -template -struct Templates16 { - typedef TemplateSel Head; - typedef Templates15 Tail; -}; - -template -struct Templates17 { - typedef TemplateSel Head; - typedef Templates16 Tail; -}; - -template -struct Templates18 { - typedef TemplateSel Head; - typedef Templates17 Tail; -}; - -template -struct Templates19 { - typedef TemplateSel Head; - typedef Templates18 Tail; -}; - -template -struct Templates20 { - typedef TemplateSel Head; - typedef Templates19 Tail; -}; - -template -struct Templates21 { - typedef TemplateSel Head; - typedef Templates20 Tail; -}; - -template -struct Templates22 { - typedef TemplateSel Head; - typedef Templates21 Tail; -}; - -template -struct Templates23 { - typedef TemplateSel Head; - typedef Templates22 Tail; -}; - -template -struct Templates24 { - typedef TemplateSel Head; - typedef Templates23 Tail; -}; - -template -struct Templates25 { - typedef TemplateSel Head; - typedef Templates24 Tail; -}; - -template -struct Templates26 { - typedef TemplateSel Head; - typedef Templates25 Tail; -}; - -template -struct Templates27 { - typedef TemplateSel Head; - typedef Templates26 Tail; -}; - -template -struct Templates28 { - typedef TemplateSel Head; - typedef Templates27 Tail; -}; - -template -struct Templates29 { - typedef TemplateSel Head; - typedef Templates28 Tail; -}; - -template -struct Templates30 { - typedef TemplateSel Head; - typedef Templates29 Tail; -}; - -template -struct Templates31 { - typedef TemplateSel Head; - typedef Templates30 Tail; -}; - -template -struct Templates32 { - typedef TemplateSel Head; - typedef Templates31 Tail; -}; - -template -struct Templates33 { - typedef TemplateSel Head; - typedef Templates32 Tail; -}; - -template -struct Templates34 { - typedef TemplateSel Head; - typedef Templates33 Tail; -}; - -template -struct Templates35 { - typedef TemplateSel Head; - typedef Templates34 Tail; -}; - -template -struct Templates36 { - typedef TemplateSel Head; - typedef Templates35 Tail; -}; - -template -struct Templates37 { - typedef TemplateSel Head; - typedef Templates36 Tail; -}; - -template -struct Templates38 { - typedef TemplateSel Head; - typedef Templates37 Tail; -}; - -template -struct Templates39 { - typedef TemplateSel Head; - typedef Templates38 Tail; -}; - -template -struct Templates40 { - typedef TemplateSel Head; - typedef Templates39 Tail; -}; - -template -struct Templates41 { - typedef TemplateSel Head; - typedef Templates40 Tail; -}; - -template -struct Templates42 { - typedef TemplateSel Head; - typedef Templates41 Tail; -}; - -template -struct Templates43 { - typedef TemplateSel Head; - typedef Templates42 Tail; -}; - -template -struct Templates44 { - typedef TemplateSel Head; - typedef Templates43 Tail; -}; - -template -struct Templates45 { - typedef TemplateSel Head; - typedef Templates44 Tail; -}; - -template -struct Templates46 { - typedef TemplateSel Head; - typedef Templates45 Tail; -}; - -template -struct Templates47 { - typedef TemplateSel Head; - typedef Templates46 Tail; -}; - -template -struct Templates48 { - typedef TemplateSel Head; - typedef Templates47 Tail; -}; - -template -struct Templates49 { - typedef TemplateSel Head; - typedef Templates48 Tail; -}; - -template -struct Templates50 { - typedef TemplateSel Head; - typedef Templates49 Tail; -}; - - -// We don't want to require the users to write TemplatesN<...> directly, -// as that would require them to count the length. Templates<...> is much -// easier to write, but generates horrible messages when there is a -// compiler error, as gcc insists on printing out each template -// argument, even if it has the default value (this means Templates -// will appear as Templates in the compiler -// errors). -// -// Our solution is to combine the best part of the two approaches: a -// user would write Templates, and Google Test will translate -// that to TemplatesN internally to make error messages -// readable. The translation is done by the 'type' member of the -// Templates template. -template -struct Templates { - typedef Templates50 type; -}; - -template <> -struct Templates { - typedef Templates0 type; -}; -template -struct Templates { - typedef Templates1 type; -}; -template -struct Templates { - typedef Templates2 type; -}; -template -struct Templates { - typedef Templates3 type; -}; -template -struct Templates { - typedef Templates4 type; -}; -template -struct Templates { - typedef Templates5 type; -}; -template -struct Templates { - typedef Templates6 type; -}; -template -struct Templates { - typedef Templates7 type; -}; -template -struct Templates { - typedef Templates8 type; -}; -template -struct Templates { - typedef Templates9 type; -}; -template -struct Templates { - typedef Templates10 type; -}; -template -struct Templates { - typedef Templates11 type; -}; -template -struct Templates { - typedef Templates12 type; -}; -template -struct Templates { - typedef Templates13 type; -}; -template -struct Templates { - typedef Templates14 type; -}; -template -struct Templates { - typedef Templates15 type; -}; -template -struct Templates { - typedef Templates16 type; -}; -template -struct Templates { - typedef Templates17 type; -}; -template -struct Templates { - typedef Templates18 type; -}; -template -struct Templates { - typedef Templates19 type; -}; -template -struct Templates { - typedef Templates20 type; -}; -template -struct Templates { - typedef Templates21 type; -}; -template -struct Templates { - typedef Templates22 type; -}; -template -struct Templates { - typedef Templates23 type; -}; -template -struct Templates { - typedef Templates24 type; -}; -template -struct Templates { - typedef Templates25 type; -}; -template -struct Templates { - typedef Templates26 type; -}; -template -struct Templates { - typedef Templates27 type; -}; -template -struct Templates { - typedef Templates28 type; -}; -template -struct Templates { - typedef Templates29 type; -}; -template -struct Templates { - typedef Templates30 type; -}; -template -struct Templates { - typedef Templates31 type; -}; -template -struct Templates { - typedef Templates32 type; -}; -template -struct Templates { - typedef Templates33 type; -}; -template -struct Templates { - typedef Templates34 type; -}; -template -struct Templates { - typedef Templates35 type; -}; -template -struct Templates { - typedef Templates36 type; -}; -template -struct Templates { - typedef Templates37 type; -}; -template -struct Templates { - typedef Templates38 type; -}; -template -struct Templates { - typedef Templates39 type; -}; -template -struct Templates { - typedef Templates40 type; -}; -template -struct Templates { - typedef Templates41 type; -}; -template -struct Templates { - typedef Templates42 type; -}; -template -struct Templates { - typedef Templates43 type; -}; -template -struct Templates { - typedef Templates44 type; -}; -template -struct Templates { - typedef Templates45 type; -}; -template -struct Templates { - typedef Templates46 type; -}; -template -struct Templates { - typedef Templates47 type; -}; -template -struct Templates { - typedef Templates48 type; -}; -template -struct Templates { - typedef Templates49 type; -}; - -// The TypeList template makes it possible to use either a single type -// or a Types<...> list in TYPED_TEST_CASE() and -// INSTANTIATE_TYPED_TEST_CASE_P(). - -template -struct TypeList { - typedef Types1 type; -}; - -template -struct TypeList > { - typedef typename Types::type type; -}; - -#endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P - -} // namespace internal -} // namespace testing - -#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ - -// Due to C++ preprocessor weirdness, we need double indirection to -// concatenate two tokens when one of them is __LINE__. Writing -// -// foo ## __LINE__ -// -// will result in the token foo__LINE__, instead of foo followed by -// the current line number. For more details, see -// http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.6 -#define GTEST_CONCAT_TOKEN_(foo, bar) GTEST_CONCAT_TOKEN_IMPL_(foo, bar) -#define GTEST_CONCAT_TOKEN_IMPL_(foo, bar) foo ## bar - -class ProtocolMessage; -namespace proto2 { class Message; } - -namespace testing { - -// Forward declarations. - -class AssertionResult; // Result of an assertion. -class Message; // Represents a failure message. -class Test; // Represents a test. -class TestInfo; // Information about a test. -class TestPartResult; // Result of a test part. -class UnitTest; // A collection of test cases. - -template -::std::string PrintToString(const T& value); - -namespace internal { - -struct TraceInfo; // Information about a trace point. -class ScopedTrace; // Implements scoped trace. -class TestInfoImpl; // Opaque implementation of TestInfo -class UnitTestImpl; // Opaque implementation of UnitTest - -// How many times InitGoogleTest() has been called. -GTEST_API_ extern int g_init_gtest_count; - -// The text used in failure messages to indicate the start of the -// stack trace. -GTEST_API_ extern const char kStackTraceMarker[]; - -// Two overloaded helpers for checking at compile time whether an -// expression is a null pointer literal (i.e. NULL or any 0-valued -// compile-time integral constant). Their return values have -// different sizes, so we can use sizeof() to test which version is -// picked by the compiler. These helpers have no implementations, as -// we only need their signatures. -// -// Given IsNullLiteralHelper(x), the compiler will pick the first -// version if x can be implicitly converted to Secret*, and pick the -// second version otherwise. Since Secret is a secret and incomplete -// type, the only expression a user can write that has type Secret* is -// a null pointer literal. Therefore, we know that x is a null -// pointer literal if and only if the first version is picked by the -// compiler. -char IsNullLiteralHelper(Secret* p); -char (&IsNullLiteralHelper(...))[2]; // NOLINT - -// A compile-time bool constant that is true if and only if x is a -// null pointer literal (i.e. NULL or any 0-valued compile-time -// integral constant). -#ifdef GTEST_ELLIPSIS_NEEDS_POD_ -// We lose support for NULL detection where the compiler doesn't like -// passing non-POD classes through ellipsis (...). -# define GTEST_IS_NULL_LITERAL_(x) false -#else -# define GTEST_IS_NULL_LITERAL_(x) \ - (sizeof(::testing::internal::IsNullLiteralHelper(x)) == 1) -#endif // GTEST_ELLIPSIS_NEEDS_POD_ - -// Appends the user-supplied message to the Google-Test-generated message. -GTEST_API_ std::string AppendUserMessage( - const std::string& gtest_msg, const Message& user_msg); - -#if GTEST_HAS_EXCEPTIONS - -// This exception is thrown by (and only by) a failed Google Test -// assertion when GTEST_FLAG(throw_on_failure) is true (if exceptions -// are enabled). We derive it from std::runtime_error, which is for -// errors presumably detectable only at run time. Since -// std::runtime_error inherits from std::exception, many testing -// frameworks know how to extract and print the message inside it. -class GTEST_API_ GoogleTestFailureException : public ::std::runtime_error { - public: - explicit GoogleTestFailureException(const TestPartResult& failure); -}; - -#endif // GTEST_HAS_EXCEPTIONS - -// A helper class for creating scoped traces in user programs. -class GTEST_API_ ScopedTrace { - public: - // The c'tor pushes the given source file location and message onto - // a trace stack maintained by Google Test. - ScopedTrace(const char* file, int line, const Message& message); - - // The d'tor pops the info pushed by the c'tor. - // - // Note that the d'tor is not virtual in order to be efficient. - // Don't inherit from ScopedTrace! - ~ScopedTrace(); - - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedTrace); -} GTEST_ATTRIBUTE_UNUSED_; // A ScopedTrace object does its job in its - // c'tor and d'tor. Therefore it doesn't - // need to be used otherwise. - -// Constructs and returns the message for an equality assertion -// (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure. -// -// The first four parameters are the expressions used in the assertion -// and their values, as strings. For example, for ASSERT_EQ(foo, bar) -// where foo is 5 and bar is 6, we have: -// -// expected_expression: "foo" -// actual_expression: "bar" -// expected_value: "5" -// actual_value: "6" -// -// The ignoring_case parameter is true iff the assertion is a -// *_STRCASEEQ*. When it's true, the string " (ignoring case)" will -// be inserted into the message. -GTEST_API_ AssertionResult EqFailure(const char* expected_expression, - const char* actual_expression, - const std::string& expected_value, - const std::string& actual_value, - bool ignoring_case); - -// Constructs a failure message for Boolean assertions such as EXPECT_TRUE. -GTEST_API_ std::string GetBoolAssertionFailureMessage( - const AssertionResult& assertion_result, - const char* expression_text, - const char* actual_predicate_value, - const char* expected_predicate_value); - -// This template class represents an IEEE floating-point number -// (either single-precision or double-precision, depending on the -// template parameters). -// -// The purpose of this class is to do more sophisticated number -// comparison. (Due to round-off error, etc, it's very unlikely that -// two floating-points will be equal exactly. Hence a naive -// comparison by the == operation often doesn't work.) -// -// Format of IEEE floating-point: -// -// The most-significant bit being the leftmost, an IEEE -// floating-point looks like -// -// sign_bit exponent_bits fraction_bits -// -// Here, sign_bit is a single bit that designates the sign of the -// number. -// -// For float, there are 8 exponent bits and 23 fraction bits. -// -// For double, there are 11 exponent bits and 52 fraction bits. -// -// More details can be found at -// http://en.wikipedia.org/wiki/IEEE_floating-point_standard. -// -// Template parameter: -// -// RawType: the raw floating-point type (either float or double) -template -class FloatingPoint { - public: - // Defines the unsigned integer type that has the same size as the - // floating point number. - typedef typename TypeWithSize::UInt Bits; - - // Constants. - - // # of bits in a number. - static const size_t kBitCount = 8*sizeof(RawType); - - // # of fraction bits in a number. - static const size_t kFractionBitCount = - std::numeric_limits::digits - 1; - - // # of exponent bits in a number. - static const size_t kExponentBitCount = kBitCount - 1 - kFractionBitCount; - - // The mask for the sign bit. - static const Bits kSignBitMask = static_cast(1) << (kBitCount - 1); - - // The mask for the fraction bits. - static const Bits kFractionBitMask = - ~static_cast(0) >> (kExponentBitCount + 1); - - // The mask for the exponent bits. - static const Bits kExponentBitMask = ~(kSignBitMask | kFractionBitMask); - - // How many ULP's (Units in the Last Place) we want to tolerate when - // comparing two numbers. The larger the value, the more error we - // allow. A 0 value means that two numbers must be exactly the same - // to be considered equal. - // - // The maximum error of a single floating-point operation is 0.5 - // units in the last place. On Intel CPU's, all floating-point - // calculations are done with 80-bit precision, while double has 64 - // bits. Therefore, 4 should be enough for ordinary use. - // - // See the following article for more details on ULP: - // http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/ - static const size_t kMaxUlps = 4; - - // Constructs a FloatingPoint from a raw floating-point number. - // - // On an Intel CPU, passing a non-normalized NAN (Not a Number) - // around may change its bits, although the new value is guaranteed - // to be also a NAN. Therefore, don't expect this constructor to - // preserve the bits in x when x is a NAN. - explicit FloatingPoint(const RawType& x) { u_.value_ = x; } - - // Static methods - - // Reinterprets a bit pattern as a floating-point number. - // - // This function is needed to test the AlmostEquals() method. - static RawType ReinterpretBits(const Bits bits) { - FloatingPoint fp(0); - fp.u_.bits_ = bits; - return fp.u_.value_; - } - - // Returns the floating-point number that represent positive infinity. - static RawType Infinity() { - return ReinterpretBits(kExponentBitMask); - } - - // Returns the maximum representable finite floating-point number. - static RawType Max(); - - // Non-static methods - - // Returns the bits that represents this number. - const Bits &bits() const { return u_.bits_; } - - // Returns the exponent bits of this number. - Bits exponent_bits() const { return kExponentBitMask & u_.bits_; } - - // Returns the fraction bits of this number. - Bits fraction_bits() const { return kFractionBitMask & u_.bits_; } - - // Returns the sign bit of this number. - Bits sign_bit() const { return kSignBitMask & u_.bits_; } - - // Returns true iff this is NAN (not a number). - bool is_nan() const { - // It's a NAN if the exponent bits are all ones and the fraction - // bits are not entirely zeros. - return (exponent_bits() == kExponentBitMask) && (fraction_bits() != 0); - } - - // Returns true iff this number is at most kMaxUlps ULP's away from - // rhs. In particular, this function: - // - // - returns false if either number is (or both are) NAN. - // - treats really large numbers as almost equal to infinity. - // - thinks +0.0 and -0.0 are 0 DLP's apart. - bool AlmostEquals(const FloatingPoint& rhs) const { - // The IEEE standard says that any comparison operation involving - // a NAN must return false. - if (is_nan() || rhs.is_nan()) return false; - - return DistanceBetweenSignAndMagnitudeNumbers(u_.bits_, rhs.u_.bits_) - <= kMaxUlps; - } - - private: - // The data type used to store the actual floating-point number. - union FloatingPointUnion { - RawType value_; // The raw floating-point number. - Bits bits_; // The bits that represent the number. - }; - - // Converts an integer from the sign-and-magnitude representation to - // the biased representation. More precisely, let N be 2 to the - // power of (kBitCount - 1), an integer x is represented by the - // unsigned number x + N. - // - // For instance, - // - // -N + 1 (the most negative number representable using - // sign-and-magnitude) is represented by 1; - // 0 is represented by N; and - // N - 1 (the biggest number representable using - // sign-and-magnitude) is represented by 2N - 1. - // - // Read http://en.wikipedia.org/wiki/Signed_number_representations - // for more details on signed number representations. - static Bits SignAndMagnitudeToBiased(const Bits &sam) { - if (kSignBitMask & sam) { - // sam represents a negative number. - return ~sam + 1; - } else { - // sam represents a positive number. - return kSignBitMask | sam; - } - } - - // Given two numbers in the sign-and-magnitude representation, - // returns the distance between them as an unsigned number. - static Bits DistanceBetweenSignAndMagnitudeNumbers(const Bits &sam1, - const Bits &sam2) { - const Bits biased1 = SignAndMagnitudeToBiased(sam1); - const Bits biased2 = SignAndMagnitudeToBiased(sam2); - return (biased1 >= biased2) ? (biased1 - biased2) : (biased2 - biased1); - } - - FloatingPointUnion u_; -}; - -// We cannot use std::numeric_limits::max() as it clashes with the max() -// macro defined by . -template <> -inline float FloatingPoint::Max() { return FLT_MAX; } -template <> -inline double FloatingPoint::Max() { return DBL_MAX; } - -// Typedefs the instances of the FloatingPoint template class that we -// care to use. -typedef FloatingPoint Float; -typedef FloatingPoint Double; - -// In order to catch the mistake of putting tests that use different -// test fixture classes in the same test case, we need to assign -// unique IDs to fixture classes and compare them. The TypeId type is -// used to hold such IDs. The user should treat TypeId as an opaque -// type: the only operation allowed on TypeId values is to compare -// them for equality using the == operator. -typedef const void* TypeId; - -template -class TypeIdHelper { - public: - // dummy_ must not have a const type. Otherwise an overly eager - // compiler (e.g. MSVC 7.1 & 8.0) may try to merge - // TypeIdHelper::dummy_ for different Ts as an "optimization". - static bool dummy_; -}; - -template -bool TypeIdHelper::dummy_ = false; - -// GetTypeId() returns the ID of type T. Different values will be -// returned for different types. Calling the function twice with the -// same type argument is guaranteed to return the same ID. -template -TypeId GetTypeId() { - // The compiler is required to allocate a different - // TypeIdHelper::dummy_ variable for each T used to instantiate - // the template. Therefore, the address of dummy_ is guaranteed to - // be unique. - return &(TypeIdHelper::dummy_); -} - -// Returns the type ID of ::testing::Test. Always call this instead -// of GetTypeId< ::testing::Test>() to get the type ID of -// ::testing::Test, as the latter may give the wrong result due to a -// suspected linker bug when compiling Google Test as a Mac OS X -// framework. -GTEST_API_ TypeId GetTestTypeId(); - -// Defines the abstract factory interface that creates instances -// of a Test object. -class TestFactoryBase { - public: - virtual ~TestFactoryBase() {} - - // Creates a test instance to run. The instance is both created and destroyed - // within TestInfoImpl::Run() - virtual Test* CreateTest() = 0; - - protected: - TestFactoryBase() {} - - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(TestFactoryBase); -}; - -// This class provides implementation of TeastFactoryBase interface. -// It is used in TEST and TEST_F macros. -template -class TestFactoryImpl : public TestFactoryBase { - public: - virtual Test* CreateTest() { return new TestClass; } -}; - -#if GTEST_OS_WINDOWS - -// Predicate-formatters for implementing the HRESULT checking macros -// {ASSERT|EXPECT}_HRESULT_{SUCCEEDED|FAILED} -// We pass a long instead of HRESULT to avoid causing an -// include dependency for the HRESULT type. -GTEST_API_ AssertionResult IsHRESULTSuccess(const char* expr, - long hr); // NOLINT -GTEST_API_ AssertionResult IsHRESULTFailure(const char* expr, - long hr); // NOLINT - -#endif // GTEST_OS_WINDOWS - -// Types of SetUpTestCase() and TearDownTestCase() functions. -typedef void (*SetUpTestCaseFunc)(); -typedef void (*TearDownTestCaseFunc)(); - -// Creates a new TestInfo object and registers it with Google Test; -// returns the created object. -// -// Arguments: -// -// test_case_name: name of the test case -// name: name of the test -// type_param the name of the test's type parameter, or NULL if -// this is not a typed or a type-parameterized test. -// value_param text representation of the test's value parameter, -// or NULL if this is not a type-parameterized test. -// fixture_class_id: ID of the test fixture class -// set_up_tc: pointer to the function that sets up the test case -// tear_down_tc: pointer to the function that tears down the test case -// factory: pointer to the factory that creates a test object. -// The newly created TestInfo instance will assume -// ownership of the factory object. -GTEST_API_ TestInfo* MakeAndRegisterTestInfo( - const char* test_case_name, - const char* name, - const char* type_param, - const char* value_param, - TypeId fixture_class_id, - SetUpTestCaseFunc set_up_tc, - TearDownTestCaseFunc tear_down_tc, - TestFactoryBase* factory); - -// If *pstr starts with the given prefix, modifies *pstr to be right -// past the prefix and returns true; otherwise leaves *pstr unchanged -// and returns false. None of pstr, *pstr, and prefix can be NULL. -GTEST_API_ bool SkipPrefix(const char* prefix, const char** pstr); - -#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P - -// State of the definition of a type-parameterized test case. -class GTEST_API_ TypedTestCasePState { - public: - TypedTestCasePState() : registered_(false) {} - - // Adds the given test name to defined_test_names_ and return true - // if the test case hasn't been registered; otherwise aborts the - // program. - bool AddTestName(const char* file, int line, const char* case_name, - const char* test_name) { - if (registered_) { - fprintf(stderr, "%s Test %s must be defined before " - "REGISTER_TYPED_TEST_CASE_P(%s, ...).\n", - FormatFileLocation(file, line).c_str(), test_name, case_name); - fflush(stderr); - posix::Abort(); - } - defined_test_names_.insert(test_name); - return true; - } - - // Verifies that registered_tests match the test names in - // defined_test_names_; returns registered_tests if successful, or - // aborts the program otherwise. - const char* VerifyRegisteredTestNames( - const char* file, int line, const char* registered_tests); - - private: - bool registered_; - ::std::set defined_test_names_; -}; - -// Skips to the first non-space char after the first comma in 'str'; -// returns NULL if no comma is found in 'str'. -inline const char* SkipComma(const char* str) { - const char* comma = strchr(str, ','); - if (comma == NULL) { - return NULL; - } - while (IsSpace(*(++comma))) {} - return comma; -} - -// Returns the prefix of 'str' before the first comma in it; returns -// the entire string if it contains no comma. -inline std::string GetPrefixUntilComma(const char* str) { - const char* comma = strchr(str, ','); - return comma == NULL ? str : std::string(str, comma); -} - -// TypeParameterizedTest::Register() -// registers a list of type-parameterized tests with Google Test. The -// return value is insignificant - we just need to return something -// such that we can call this function in a namespace scope. -// -// Implementation note: The GTEST_TEMPLATE_ macro declares a template -// template parameter. It's defined in gtest-type-util.h. -template -class TypeParameterizedTest { - public: - // 'index' is the index of the test in the type list 'Types' - // specified in INSTANTIATE_TYPED_TEST_CASE_P(Prefix, TestCase, - // Types). Valid values for 'index' are [0, N - 1] where N is the - // length of Types. - static bool Register(const char* prefix, const char* case_name, - const char* test_names, int index) { - typedef typename Types::Head Type; - typedef Fixture FixtureClass; - typedef typename GTEST_BIND_(TestSel, Type) TestClass; - - // First, registers the first type-parameterized test in the type - // list. - MakeAndRegisterTestInfo( - (std::string(prefix) + (prefix[0] == '\0' ? "" : "/") + case_name + "/" - + StreamableToString(index)).c_str(), - GetPrefixUntilComma(test_names).c_str(), - GetTypeName().c_str(), - NULL, // No value parameter. - GetTypeId(), - TestClass::SetUpTestCase, - TestClass::TearDownTestCase, - new TestFactoryImpl); - - // Next, recurses (at compile time) with the tail of the type list. - return TypeParameterizedTest - ::Register(prefix, case_name, test_names, index + 1); - } -}; - -// The base case for the compile time recursion. -template -class TypeParameterizedTest { - public: - static bool Register(const char* /*prefix*/, const char* /*case_name*/, - const char* /*test_names*/, int /*index*/) { - return true; - } -}; - -// TypeParameterizedTestCase::Register() -// registers *all combinations* of 'Tests' and 'Types' with Google -// Test. The return value is insignificant - we just need to return -// something such that we can call this function in a namespace scope. -template -class TypeParameterizedTestCase { - public: - static bool Register(const char* prefix, const char* case_name, - const char* test_names) { - typedef typename Tests::Head Head; - - // First, register the first test in 'Test' for each type in 'Types'. - TypeParameterizedTest::Register( - prefix, case_name, test_names, 0); - - // Next, recurses (at compile time) with the tail of the test list. - return TypeParameterizedTestCase - ::Register(prefix, case_name, SkipComma(test_names)); - } -}; - -// The base case for the compile time recursion. -template -class TypeParameterizedTestCase { - public: - static bool Register(const char* /*prefix*/, const char* /*case_name*/, - const char* /*test_names*/) { - return true; - } -}; - -#endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P - -// Returns the current OS stack trace as an std::string. -// -// The maximum number of stack frames to be included is specified by -// the gtest_stack_trace_depth flag. The skip_count parameter -// specifies the number of top frames to be skipped, which doesn't -// count against the number of frames to be included. -// -// For example, if Foo() calls Bar(), which in turn calls -// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in -// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't. -GTEST_API_ std::string GetCurrentOsStackTraceExceptTop( - UnitTest* unit_test, int skip_count); - -// Helpers for suppressing warnings on unreachable code or constant -// condition. - -// Always returns true. -GTEST_API_ bool AlwaysTrue(); - -// Always returns false. -inline bool AlwaysFalse() { return !AlwaysTrue(); } - -// Helper for suppressing false warning from Clang on a const char* -// variable declared in a conditional expression always being NULL in -// the else branch. -struct GTEST_API_ ConstCharPtr { - ConstCharPtr(const char* str) : value(str) {} - operator bool() const { return true; } - const char* value; -}; - -// A simple Linear Congruential Generator for generating random -// numbers with a uniform distribution. Unlike rand() and srand(), it -// doesn't use global state (and therefore can't interfere with user -// code). Unlike rand_r(), it's portable. An LCG isn't very random, -// but it's good enough for our purposes. -class GTEST_API_ Random { - public: - static const UInt32 kMaxRange = 1u << 31; - - explicit Random(UInt32 seed) : state_(seed) {} - - void Reseed(UInt32 seed) { state_ = seed; } - - // Generates a random number from [0, range). Crashes if 'range' is - // 0 or greater than kMaxRange. - UInt32 Generate(UInt32 range); - - private: - UInt32 state_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(Random); -}; - -// Defining a variable of type CompileAssertTypesEqual will cause a -// compiler error iff T1 and T2 are different types. -template -struct CompileAssertTypesEqual; - -template -struct CompileAssertTypesEqual { -}; - -// Removes the reference from a type if it is a reference type, -// otherwise leaves it unchanged. This is the same as -// tr1::remove_reference, which is not widely available yet. -template -struct RemoveReference { typedef T type; }; // NOLINT -template -struct RemoveReference { typedef T type; }; // NOLINT - -// A handy wrapper around RemoveReference that works when the argument -// T depends on template parameters. -#define GTEST_REMOVE_REFERENCE_(T) \ - typename ::testing::internal::RemoveReference::type - -// Removes const from a type if it is a const type, otherwise leaves -// it unchanged. This is the same as tr1::remove_const, which is not -// widely available yet. -template -struct RemoveConst { typedef T type; }; // NOLINT -template -struct RemoveConst { typedef T type; }; // NOLINT - -// MSVC 8.0, Sun C++, and IBM XL C++ have a bug which causes the above -// definition to fail to remove the const in 'const int[3]' and 'const -// char[3][4]'. The following specialization works around the bug. -template -struct RemoveConst { - typedef typename RemoveConst::type type[N]; -}; - -#if defined(_MSC_VER) && _MSC_VER < 1400 -// This is the only specialization that allows VC++ 7.1 to remove const in -// 'const int[3] and 'const int[3][4]'. However, it causes trouble with GCC -// and thus needs to be conditionally compiled. -template -struct RemoveConst { - typedef typename RemoveConst::type type[N]; -}; -#endif - -// A handy wrapper around RemoveConst that works when the argument -// T depends on template parameters. -#define GTEST_REMOVE_CONST_(T) \ - typename ::testing::internal::RemoveConst::type - -// Turns const U&, U&, const U, and U all into U. -#define GTEST_REMOVE_REFERENCE_AND_CONST_(T) \ - GTEST_REMOVE_CONST_(GTEST_REMOVE_REFERENCE_(T)) - -// Adds reference to a type if it is not a reference type, -// otherwise leaves it unchanged. This is the same as -// tr1::add_reference, which is not widely available yet. -template -struct AddReference { typedef T& type; }; // NOLINT -template -struct AddReference { typedef T& type; }; // NOLINT - -// A handy wrapper around AddReference that works when the argument T -// depends on template parameters. -#define GTEST_ADD_REFERENCE_(T) \ - typename ::testing::internal::AddReference::type - -// Adds a reference to const on top of T as necessary. For example, -// it transforms -// -// char ==> const char& -// const char ==> const char& -// char& ==> const char& -// const char& ==> const char& -// -// The argument T must depend on some template parameters. -#define GTEST_REFERENCE_TO_CONST_(T) \ - GTEST_ADD_REFERENCE_(const GTEST_REMOVE_REFERENCE_(T)) - -// ImplicitlyConvertible::value is a compile-time bool -// constant that's true iff type From can be implicitly converted to -// type To. -template -class ImplicitlyConvertible { - private: - // We need the following helper functions only for their types. - // They have no implementations. - - // MakeFrom() is an expression whose type is From. We cannot simply - // use From(), as the type From may not have a public default - // constructor. - static From MakeFrom(); - - // These two functions are overloaded. Given an expression - // Helper(x), the compiler will pick the first version if x can be - // implicitly converted to type To; otherwise it will pick the - // second version. - // - // The first version returns a value of size 1, and the second - // version returns a value of size 2. Therefore, by checking the - // size of Helper(x), which can be done at compile time, we can tell - // which version of Helper() is used, and hence whether x can be - // implicitly converted to type To. - static char Helper(To); - static char (&Helper(...))[2]; // NOLINT - - // We have to put the 'public' section after the 'private' section, - // or MSVC refuses to compile the code. - public: - // MSVC warns about implicitly converting from double to int for - // possible loss of data, so we need to temporarily disable the - // warning. -#ifdef _MSC_VER -# pragma warning(push) // Saves the current warning state. -# pragma warning(disable:4244) // Temporarily disables warning 4244. - - static const bool value = - sizeof(Helper(ImplicitlyConvertible::MakeFrom())) == 1; -# pragma warning(pop) // Restores the warning state. -#elif defined(__BORLANDC__) - // C++Builder cannot use member overload resolution during template - // instantiation. The simplest workaround is to use its C++0x type traits - // functions (C++Builder 2009 and above only). - static const bool value = __is_convertible(From, To); -#else - static const bool value = - sizeof(Helper(ImplicitlyConvertible::MakeFrom())) == 1; -#endif // _MSV_VER -}; -template -const bool ImplicitlyConvertible::value; - -// IsAProtocolMessage::value is a compile-time bool constant that's -// true iff T is type ProtocolMessage, proto2::Message, or a subclass -// of those. -template -struct IsAProtocolMessage - : public bool_constant< - ImplicitlyConvertible::value || - ImplicitlyConvertible::value> { -}; - -// When the compiler sees expression IsContainerTest(0), if C is an -// STL-style container class, the first overload of IsContainerTest -// will be viable (since both C::iterator* and C::const_iterator* are -// valid types and NULL can be implicitly converted to them). It will -// be picked over the second overload as 'int' is a perfect match for -// the type of argument 0. If C::iterator or C::const_iterator is not -// a valid type, the first overload is not viable, and the second -// overload will be picked. Therefore, we can determine whether C is -// a container class by checking the type of IsContainerTest(0). -// The value of the expression is insignificant. -// -// Note that we look for both C::iterator and C::const_iterator. The -// reason is that C++ injects the name of a class as a member of the -// class itself (e.g. you can refer to class iterator as either -// 'iterator' or 'iterator::iterator'). If we look for C::iterator -// only, for example, we would mistakenly think that a class named -// iterator is an STL container. -// -// Also note that the simpler approach of overloading -// IsContainerTest(typename C::const_iterator*) and -// IsContainerTest(...) doesn't work with Visual Age C++ and Sun C++. -typedef int IsContainer; -template -IsContainer IsContainerTest(int /* dummy */, - typename C::iterator* /* it */ = NULL, - typename C::const_iterator* /* const_it */ = NULL) { - return 0; -} - -typedef char IsNotContainer; -template -IsNotContainer IsContainerTest(long /* dummy */) { return '\0'; } - -// EnableIf::type is void when 'Cond' is true, and -// undefined when 'Cond' is false. To use SFINAE to make a function -// overload only apply when a particular expression is true, add -// "typename EnableIf::type* = 0" as the last parameter. -template struct EnableIf; -template<> struct EnableIf { typedef void type; }; // NOLINT - -// Utilities for native arrays. - -// ArrayEq() compares two k-dimensional native arrays using the -// elements' operator==, where k can be any integer >= 0. When k is -// 0, ArrayEq() degenerates into comparing a single pair of values. - -template -bool ArrayEq(const T* lhs, size_t size, const U* rhs); - -// This generic version is used when k is 0. -template -inline bool ArrayEq(const T& lhs, const U& rhs) { return lhs == rhs; } - -// This overload is used when k >= 1. -template -inline bool ArrayEq(const T(&lhs)[N], const U(&rhs)[N]) { - return internal::ArrayEq(lhs, N, rhs); -} - -// This helper reduces code bloat. If we instead put its logic inside -// the previous ArrayEq() function, arrays with different sizes would -// lead to different copies of the template code. -template -bool ArrayEq(const T* lhs, size_t size, const U* rhs) { - for (size_t i = 0; i != size; i++) { - if (!internal::ArrayEq(lhs[i], rhs[i])) - return false; - } - return true; -} - -// Finds the first element in the iterator range [begin, end) that -// equals elem. Element may be a native array type itself. -template -Iter ArrayAwareFind(Iter begin, Iter end, const Element& elem) { - for (Iter it = begin; it != end; ++it) { - if (internal::ArrayEq(*it, elem)) - return it; - } - return end; -} - -// CopyArray() copies a k-dimensional native array using the elements' -// operator=, where k can be any integer >= 0. When k is 0, -// CopyArray() degenerates into copying a single value. - -template -void CopyArray(const T* from, size_t size, U* to); - -// This generic version is used when k is 0. -template -inline void CopyArray(const T& from, U* to) { *to = from; } - -// This overload is used when k >= 1. -template -inline void CopyArray(const T(&from)[N], U(*to)[N]) { - internal::CopyArray(from, N, *to); -} - -// This helper reduces code bloat. If we instead put its logic inside -// the previous CopyArray() function, arrays with different sizes -// would lead to different copies of the template code. -template -void CopyArray(const T* from, size_t size, U* to) { - for (size_t i = 0; i != size; i++) { - internal::CopyArray(from[i], to + i); - } -} - -// The relation between an NativeArray object (see below) and the -// native array it represents. -enum RelationToSource { - kReference, // The NativeArray references the native array. - kCopy // The NativeArray makes a copy of the native array and - // owns the copy. -}; - -// Adapts a native array to a read-only STL-style container. Instead -// of the complete STL container concept, this adaptor only implements -// members useful for Google Mock's container matchers. New members -// should be added as needed. To simplify the implementation, we only -// support Element being a raw type (i.e. having no top-level const or -// reference modifier). It's the client's responsibility to satisfy -// this requirement. Element can be an array type itself (hence -// multi-dimensional arrays are supported). -template -class NativeArray { - public: - // STL-style container typedefs. - typedef Element value_type; - typedef Element* iterator; - typedef const Element* const_iterator; - - // Constructs from a native array. - NativeArray(const Element* array, size_t count, RelationToSource relation) { - Init(array, count, relation); - } - - // Copy constructor. - NativeArray(const NativeArray& rhs) { - Init(rhs.array_, rhs.size_, rhs.relation_to_source_); - } - - ~NativeArray() { - // Ensures that the user doesn't instantiate NativeArray with a - // const or reference type. - static_cast(StaticAssertTypeEqHelper()); - if (relation_to_source_ == kCopy) - delete[] array_; - } - - // STL-style container methods. - size_t size() const { return size_; } - const_iterator begin() const { return array_; } - const_iterator end() const { return array_ + size_; } - bool operator==(const NativeArray& rhs) const { - return size() == rhs.size() && - ArrayEq(begin(), size(), rhs.begin()); - } - - private: - // Initializes this object; makes a copy of the input array if - // 'relation' is kCopy. - void Init(const Element* array, size_t a_size, RelationToSource relation) { - if (relation == kReference) { - array_ = array; - } else { - Element* const copy = new Element[a_size]; - CopyArray(array, a_size, copy); - array_ = copy; - } - size_ = a_size; - relation_to_source_ = relation; - } - - const Element* array_; - size_t size_; - RelationToSource relation_to_source_; - - GTEST_DISALLOW_ASSIGN_(NativeArray); -}; - -} // namespace internal -} // namespace testing - -#define GTEST_MESSAGE_AT_(file, line, message, result_type) \ - ::testing::internal::AssertHelper(result_type, file, line, message) \ - = ::testing::Message() - -#define GTEST_MESSAGE_(message, result_type) \ - GTEST_MESSAGE_AT_(__FILE__, __LINE__, message, result_type) - -#define GTEST_FATAL_FAILURE_(message) \ - return GTEST_MESSAGE_(message, ::testing::TestPartResult::kFatalFailure) - -#define GTEST_NONFATAL_FAILURE_(message) \ - GTEST_MESSAGE_(message, ::testing::TestPartResult::kNonFatalFailure) - -#define GTEST_SUCCESS_(message) \ - GTEST_MESSAGE_(message, ::testing::TestPartResult::kSuccess) - -// Suppresses MSVC warnings 4072 (unreachable code) for the code following -// statement if it returns or throws (or doesn't return or throw in some -// situations). -#define GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) \ - if (::testing::internal::AlwaysTrue()) { statement; } - -#define GTEST_TEST_THROW_(statement, expected_exception, fail) \ - GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ - if (::testing::internal::ConstCharPtr gtest_msg = "") { \ - bool gtest_caught_expected = false; \ - try { \ - GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ - } \ - catch (expected_exception const&) { \ - gtest_caught_expected = true; \ - } \ - catch (...) { \ - gtest_msg.value = \ - "Expected: " #statement " throws an exception of type " \ - #expected_exception ".\n Actual: it throws a different type."; \ - goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ - } \ - if (!gtest_caught_expected) { \ - gtest_msg.value = \ - "Expected: " #statement " throws an exception of type " \ - #expected_exception ".\n Actual: it throws nothing."; \ - goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ - } \ - } else \ - GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__): \ - fail(gtest_msg.value) - -#define GTEST_TEST_NO_THROW_(statement, fail) \ - GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ - if (::testing::internal::AlwaysTrue()) { \ - try { \ - GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ - } \ - catch (...) { \ - goto GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__); \ - } \ - } else \ - GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__): \ - fail("Expected: " #statement " doesn't throw an exception.\n" \ - " Actual: it throws.") - -#define GTEST_TEST_ANY_THROW_(statement, fail) \ - GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ - if (::testing::internal::AlwaysTrue()) { \ - bool gtest_caught_any = false; \ - try { \ - GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ - } \ - catch (...) { \ - gtest_caught_any = true; \ - } \ - if (!gtest_caught_any) { \ - goto GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__); \ - } \ - } else \ - GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__): \ - fail("Expected: " #statement " throws an exception.\n" \ - " Actual: it doesn't.") - - -// Implements Boolean test assertions such as EXPECT_TRUE. expression can be -// either a boolean expression or an AssertionResult. text is a textual -// represenation of expression as it was passed into the EXPECT_TRUE. -#define GTEST_TEST_BOOLEAN_(expression, text, actual, expected, fail) \ - GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ - if (const ::testing::AssertionResult gtest_ar_ = \ - ::testing::AssertionResult(expression)) \ - ; \ - else \ - fail(::testing::internal::GetBoolAssertionFailureMessage(\ - gtest_ar_, text, #actual, #expected).c_str()) - -#define GTEST_TEST_NO_FATAL_FAILURE_(statement, fail) \ - GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ - if (::testing::internal::AlwaysTrue()) { \ - ::testing::internal::HasNewFatalFailureHelper gtest_fatal_failure_checker; \ - GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ - if (gtest_fatal_failure_checker.has_new_fatal_failure()) { \ - goto GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__); \ - } \ - } else \ - GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__): \ - fail("Expected: " #statement " doesn't generate new fatal " \ - "failures in the current thread.\n" \ - " Actual: it does.") - -// Expands to the name of the class that implements the given test. -#define GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \ - test_case_name##_##test_name##_Test - -// Helper macro for defining tests. -#define GTEST_TEST_(test_case_name, test_name, parent_class, parent_id)\ -class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) : public parent_class {\ - public:\ - GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {}\ - private:\ - virtual void TestBody();\ - static ::testing::TestInfo* const test_info_ GTEST_ATTRIBUTE_UNUSED_;\ - GTEST_DISALLOW_COPY_AND_ASSIGN_(\ - GTEST_TEST_CLASS_NAME_(test_case_name, test_name));\ -};\ -\ -::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_case_name, test_name)\ - ::test_info_ =\ - ::testing::internal::MakeAndRegisterTestInfo(\ - #test_case_name, #test_name, NULL, NULL, \ - (parent_id), \ - parent_class::SetUpTestCase, \ - parent_class::TearDownTestCase, \ - new ::testing::internal::TestFactoryImpl<\ - GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>);\ -void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody() - -#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ -// Copyright 2005, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: wan@google.com (Zhanyong Wan) -// -// The Google C++ Testing Framework (Google Test) -// -// This header file defines the public API for death tests. It is -// #included by gtest.h so a user doesn't need to include this -// directly. - -#ifndef GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ -#define GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ - -// Copyright 2005, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee) -// -// The Google C++ Testing Framework (Google Test) -// -// This header file defines internal utilities needed for implementing -// death tests. They are subject to change without notice. - -#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ -#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ - - -#include - -namespace testing { -namespace internal { - -GTEST_DECLARE_string_(internal_run_death_test); - -// Names of the flags (needed for parsing Google Test flags). -const char kDeathTestStyleFlag[] = "death_test_style"; -const char kDeathTestUseFork[] = "death_test_use_fork"; -const char kInternalRunDeathTestFlag[] = "internal_run_death_test"; - -#if GTEST_HAS_DEATH_TEST - -// DeathTest is a class that hides much of the complexity of the -// GTEST_DEATH_TEST_ macro. It is abstract; its static Create method -// returns a concrete class that depends on the prevailing death test -// style, as defined by the --gtest_death_test_style and/or -// --gtest_internal_run_death_test flags. - -// In describing the results of death tests, these terms are used with -// the corresponding definitions: -// -// exit status: The integer exit information in the format specified -// by wait(2) -// exit code: The integer code passed to exit(3), _exit(2), or -// returned from main() -class GTEST_API_ DeathTest { - public: - // Create returns false if there was an error determining the - // appropriate action to take for the current death test; for example, - // if the gtest_death_test_style flag is set to an invalid value. - // The LastMessage method will return a more detailed message in that - // case. Otherwise, the DeathTest pointer pointed to by the "test" - // argument is set. If the death test should be skipped, the pointer - // is set to NULL; otherwise, it is set to the address of a new concrete - // DeathTest object that controls the execution of the current test. - static bool Create(const char* statement, const RE* regex, - const char* file, int line, DeathTest** test); - DeathTest(); - virtual ~DeathTest() { } - - // A helper class that aborts a death test when it's deleted. - class ReturnSentinel { - public: - explicit ReturnSentinel(DeathTest* test) : test_(test) { } - ~ReturnSentinel() { test_->Abort(TEST_ENCOUNTERED_RETURN_STATEMENT); } - private: - DeathTest* const test_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(ReturnSentinel); - } GTEST_ATTRIBUTE_UNUSED_; - - // An enumeration of possible roles that may be taken when a death - // test is encountered. EXECUTE means that the death test logic should - // be executed immediately. OVERSEE means that the program should prepare - // the appropriate environment for a child process to execute the death - // test, then wait for it to complete. - enum TestRole { OVERSEE_TEST, EXECUTE_TEST }; - - // An enumeration of the three reasons that a test might be aborted. - enum AbortReason { - TEST_ENCOUNTERED_RETURN_STATEMENT, - TEST_THREW_EXCEPTION, - TEST_DID_NOT_DIE - }; - - // Assumes one of the above roles. - virtual TestRole AssumeRole() = 0; - - // Waits for the death test to finish and returns its status. - virtual int Wait() = 0; - - // Returns true if the death test passed; that is, the test process - // exited during the test, its exit status matches a user-supplied - // predicate, and its stderr output matches a user-supplied regular - // expression. - // The user-supplied predicate may be a macro expression rather - // than a function pointer or functor, or else Wait and Passed could - // be combined. - virtual bool Passed(bool exit_status_ok) = 0; - - // Signals that the death test did not die as expected. - virtual void Abort(AbortReason reason) = 0; - - // Returns a human-readable outcome message regarding the outcome of - // the last death test. - static const char* LastMessage(); - - static void set_last_death_test_message(const std::string& message); - - private: - // A string containing a description of the outcome of the last death test. - static std::string last_death_test_message_; - - GTEST_DISALLOW_COPY_AND_ASSIGN_(DeathTest); -}; - -// Factory interface for death tests. May be mocked out for testing. -class DeathTestFactory { - public: - virtual ~DeathTestFactory() { } - virtual bool Create(const char* statement, const RE* regex, - const char* file, int line, DeathTest** test) = 0; -}; - -// A concrete DeathTestFactory implementation for normal use. -class DefaultDeathTestFactory : public DeathTestFactory { - public: - virtual bool Create(const char* statement, const RE* regex, - const char* file, int line, DeathTest** test); -}; - -// Returns true if exit_status describes a process that was terminated -// by a signal, or exited normally with a nonzero exit code. -GTEST_API_ bool ExitedUnsuccessfully(int exit_status); - -// Traps C++ exceptions escaping statement and reports them as test -// failures. Note that trapping SEH exceptions is not implemented here. -# if GTEST_HAS_EXCEPTIONS -# define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \ - try { \ - GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ - } catch (const ::std::exception& gtest_exception) { \ - fprintf(\ - stderr, \ - "\n%s: Caught std::exception-derived exception escaping the " \ - "death test statement. Exception message: %s\n", \ - ::testing::internal::FormatFileLocation(__FILE__, __LINE__).c_str(), \ - gtest_exception.what()); \ - fflush(stderr); \ - death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \ - } catch (...) { \ - death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \ - } - -# else -# define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \ - GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) - -# endif - -// This macro is for implementing ASSERT_DEATH*, EXPECT_DEATH*, -// ASSERT_EXIT*, and EXPECT_EXIT*. -# define GTEST_DEATH_TEST_(statement, predicate, regex, fail) \ - GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ - if (::testing::internal::AlwaysTrue()) { \ - const ::testing::internal::RE& gtest_regex = (regex); \ - ::testing::internal::DeathTest* gtest_dt; \ - if (!::testing::internal::DeathTest::Create(#statement, >est_regex, \ - __FILE__, __LINE__, >est_dt)) { \ - goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \ - } \ - if (gtest_dt != NULL) { \ - ::testing::internal::scoped_ptr< ::testing::internal::DeathTest> \ - gtest_dt_ptr(gtest_dt); \ - switch (gtest_dt->AssumeRole()) { \ - case ::testing::internal::DeathTest::OVERSEE_TEST: \ - if (!gtest_dt->Passed(predicate(gtest_dt->Wait()))) { \ - goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \ - } \ - break; \ - case ::testing::internal::DeathTest::EXECUTE_TEST: { \ - ::testing::internal::DeathTest::ReturnSentinel \ - gtest_sentinel(gtest_dt); \ - GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, gtest_dt); \ - gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \ - break; \ - } \ - default: \ - break; \ - } \ - } \ - } else \ - GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__): \ - fail(::testing::internal::DeathTest::LastMessage()) -// The symbol "fail" here expands to something into which a message -// can be streamed. - -// This macro is for implementing ASSERT/EXPECT_DEBUG_DEATH when compiled in -// NDEBUG mode. In this case we need the statements to be executed, the regex is -// ignored, and the macro must accept a streamed message even though the message -// is never printed. -# define GTEST_EXECUTE_STATEMENT_(statement, regex) \ - GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ - if (::testing::internal::AlwaysTrue()) { \ - GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ - } else \ - ::testing::Message() - -// A class representing the parsed contents of the -// --gtest_internal_run_death_test flag, as it existed when -// RUN_ALL_TESTS was called. -class InternalRunDeathTestFlag { - public: - InternalRunDeathTestFlag(const std::string& a_file, - int a_line, - int an_index, - int a_write_fd) - : file_(a_file), line_(a_line), index_(an_index), - write_fd_(a_write_fd) {} - - ~InternalRunDeathTestFlag() { - if (write_fd_ >= 0) - posix::Close(write_fd_); - } - - const std::string& file() const { return file_; } - int line() const { return line_; } - int index() const { return index_; } - int write_fd() const { return write_fd_; } - - private: - std::string file_; - int line_; - int index_; - int write_fd_; - - GTEST_DISALLOW_COPY_AND_ASSIGN_(InternalRunDeathTestFlag); -}; - -// Returns a newly created InternalRunDeathTestFlag object with fields -// initialized from the GTEST_FLAG(internal_run_death_test) flag if -// the flag is specified; otherwise returns NULL. -InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag(); - -#else // GTEST_HAS_DEATH_TEST - -// This macro is used for implementing macros such as -// EXPECT_DEATH_IF_SUPPORTED and ASSERT_DEATH_IF_SUPPORTED on systems where -// death tests are not supported. Those macros must compile on such systems -// iff EXPECT_DEATH and ASSERT_DEATH compile with the same parameters on -// systems that support death tests. This allows one to write such a macro -// on a system that does not support death tests and be sure that it will -// compile on a death-test supporting system. -// -// Parameters: -// statement - A statement that a macro such as EXPECT_DEATH would test -// for program termination. This macro has to make sure this -// statement is compiled but not executed, to ensure that -// EXPECT_DEATH_IF_SUPPORTED compiles with a certain -// parameter iff EXPECT_DEATH compiles with it. -// regex - A regex that a macro such as EXPECT_DEATH would use to test -// the output of statement. This parameter has to be -// compiled but not evaluated by this macro, to ensure that -// this macro only accepts expressions that a macro such as -// EXPECT_DEATH would accept. -// terminator - Must be an empty statement for EXPECT_DEATH_IF_SUPPORTED -// and a return statement for ASSERT_DEATH_IF_SUPPORTED. -// This ensures that ASSERT_DEATH_IF_SUPPORTED will not -// compile inside functions where ASSERT_DEATH doesn't -// compile. -// -// The branch that has an always false condition is used to ensure that -// statement and regex are compiled (and thus syntactically correct) but -// never executed. The unreachable code macro protects the terminator -// statement from generating an 'unreachable code' warning in case -// statement unconditionally returns or throws. The Message constructor at -// the end allows the syntax of streaming additional messages into the -// macro, for compilational compatibility with EXPECT_DEATH/ASSERT_DEATH. -# define GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, terminator) \ - GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ - if (::testing::internal::AlwaysTrue()) { \ - GTEST_LOG_(WARNING) \ - << "Death tests are not supported on this platform.\n" \ - << "Statement '" #statement "' cannot be verified."; \ - } else if (::testing::internal::AlwaysFalse()) { \ - ::testing::internal::RE::PartialMatch(".*", (regex)); \ - GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ - terminator; \ - } else \ - ::testing::Message() - -#endif // GTEST_HAS_DEATH_TEST - -} // namespace internal -} // namespace testing - -#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ - -namespace testing { - -// This flag controls the style of death tests. Valid values are "threadsafe", -// meaning that the death test child process will re-execute the test binary -// from the start, running only a single death test, or "fast", -// meaning that the child process will execute the test logic immediately -// after forking. -GTEST_DECLARE_string_(death_test_style); - -#if GTEST_HAS_DEATH_TEST - -namespace internal { - -// Returns a Boolean value indicating whether the caller is currently -// executing in the context of the death test child process. Tools such as -// Valgrind heap checkers may need this to modify their behavior in death -// tests. IMPORTANT: This is an internal utility. Using it may break the -// implementation of death tests. User code MUST NOT use it. -GTEST_API_ bool InDeathTestChild(); - -} // namespace internal - -// The following macros are useful for writing death tests. - -// Here's what happens when an ASSERT_DEATH* or EXPECT_DEATH* is -// executed: -// -// 1. It generates a warning if there is more than one active -// thread. This is because it's safe to fork() or clone() only -// when there is a single thread. -// -// 2. The parent process clone()s a sub-process and runs the death -// test in it; the sub-process exits with code 0 at the end of the -// death test, if it hasn't exited already. -// -// 3. The parent process waits for the sub-process to terminate. -// -// 4. The parent process checks the exit code and error message of -// the sub-process. -// -// Examples: -// -// ASSERT_DEATH(server.SendMessage(56, "Hello"), "Invalid port number"); -// for (int i = 0; i < 5; i++) { -// EXPECT_DEATH(server.ProcessRequest(i), -// "Invalid request .* in ProcessRequest()") -// << "Failed to die on request " << i; -// } -// -// ASSERT_EXIT(server.ExitNow(), ::testing::ExitedWithCode(0), "Exiting"); -// -// bool KilledBySIGHUP(int exit_code) { -// return WIFSIGNALED(exit_code) && WTERMSIG(exit_code) == SIGHUP; -// } -// -// ASSERT_EXIT(client.HangUpServer(), KilledBySIGHUP, "Hanging up!"); -// -// On the regular expressions used in death tests: -// -// On POSIX-compliant systems (*nix), we use the library, -// which uses the POSIX extended regex syntax. -// -// On other platforms (e.g. Windows), we only support a simple regex -// syntax implemented as part of Google Test. This limited -// implementation should be enough most of the time when writing -// death tests; though it lacks many features you can find in PCRE -// or POSIX extended regex syntax. For example, we don't support -// union ("x|y"), grouping ("(xy)"), brackets ("[xy]"), and -// repetition count ("x{5,7}"), among others. -// -// Below is the syntax that we do support. We chose it to be a -// subset of both PCRE and POSIX extended regex, so it's easy to -// learn wherever you come from. In the following: 'A' denotes a -// literal character, period (.), or a single \\ escape sequence; -// 'x' and 'y' denote regular expressions; 'm' and 'n' are for -// natural numbers. -// -// c matches any literal character c -// \\d matches any decimal digit -// \\D matches any character that's not a decimal digit -// \\f matches \f -// \\n matches \n -// \\r matches \r -// \\s matches any ASCII whitespace, including \n -// \\S matches any character that's not a whitespace -// \\t matches \t -// \\v matches \v -// \\w matches any letter, _, or decimal digit -// \\W matches any character that \\w doesn't match -// \\c matches any literal character c, which must be a punctuation -// . matches any single character except \n -// A? matches 0 or 1 occurrences of A -// A* matches 0 or many occurrences of A -// A+ matches 1 or many occurrences of A -// ^ matches the beginning of a string (not that of each line) -// $ matches the end of a string (not that of each line) -// xy matches x followed by y -// -// If you accidentally use PCRE or POSIX extended regex features -// not implemented by us, you will get a run-time failure. In that -// case, please try to rewrite your regular expression within the -// above syntax. -// -// This implementation is *not* meant to be as highly tuned or robust -// as a compiled regex library, but should perform well enough for a -// death test, which already incurs significant overhead by launching -// a child process. -// -// Known caveats: -// -// A "threadsafe" style death test obtains the path to the test -// program from argv[0] and re-executes it in the sub-process. For -// simplicity, the current implementation doesn't search the PATH -// when launching the sub-process. This means that the user must -// invoke the test program via a path that contains at least one -// path separator (e.g. path/to/foo_test and -// /absolute/path/to/bar_test are fine, but foo_test is not). This -// is rarely a problem as people usually don't put the test binary -// directory in PATH. -// -// TODO(wan@google.com): make thread-safe death tests search the PATH. - -// Asserts that a given statement causes the program to exit, with an -// integer exit status that satisfies predicate, and emitting error output -// that matches regex. -# define ASSERT_EXIT(statement, predicate, regex) \ - GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_FATAL_FAILURE_) - -// Like ASSERT_EXIT, but continues on to successive tests in the -// test case, if any: -# define EXPECT_EXIT(statement, predicate, regex) \ - GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_NONFATAL_FAILURE_) - -// Asserts that a given statement causes the program to exit, either by -// explicitly exiting with a nonzero exit code or being killed by a -// signal, and emitting error output that matches regex. -# define ASSERT_DEATH(statement, regex) \ - ASSERT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex) - -// Like ASSERT_DEATH, but continues on to successive tests in the -// test case, if any: -# define EXPECT_DEATH(statement, regex) \ - EXPECT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex) - -// Two predicate classes that can be used in {ASSERT,EXPECT}_EXIT*: - -// Tests that an exit code describes a normal exit with a given exit code. -class GTEST_API_ ExitedWithCode { - public: - explicit ExitedWithCode(int exit_code); - bool operator()(int exit_status) const; - private: - // No implementation - assignment is unsupported. - void operator=(const ExitedWithCode& other); - - const int exit_code_; -}; - -# if !GTEST_OS_WINDOWS -// Tests that an exit code describes an exit due to termination by a -// given signal. -class GTEST_API_ KilledBySignal { - public: - explicit KilledBySignal(int signum); - bool operator()(int exit_status) const; - private: - const int signum_; -}; -# endif // !GTEST_OS_WINDOWS - -// EXPECT_DEBUG_DEATH asserts that the given statements die in debug mode. -// The death testing framework causes this to have interesting semantics, -// since the sideeffects of the call are only visible in opt mode, and not -// in debug mode. -// -// In practice, this can be used to test functions that utilize the -// LOG(DFATAL) macro using the following style: -// -// int DieInDebugOr12(int* sideeffect) { -// if (sideeffect) { -// *sideeffect = 12; -// } -// LOG(DFATAL) << "death"; -// return 12; -// } -// -// TEST(TestCase, TestDieOr12WorksInDgbAndOpt) { -// int sideeffect = 0; -// // Only asserts in dbg. -// EXPECT_DEBUG_DEATH(DieInDebugOr12(&sideeffect), "death"); -// -// #ifdef NDEBUG -// // opt-mode has sideeffect visible. -// EXPECT_EQ(12, sideeffect); -// #else -// // dbg-mode no visible sideeffect. -// EXPECT_EQ(0, sideeffect); -// #endif -// } -// -// This will assert that DieInDebugReturn12InOpt() crashes in debug -// mode, usually due to a DCHECK or LOG(DFATAL), but returns the -// appropriate fallback value (12 in this case) in opt mode. If you -// need to test that a function has appropriate side-effects in opt -// mode, include assertions against the side-effects. A general -// pattern for this is: -// -// EXPECT_DEBUG_DEATH({ -// // Side-effects here will have an effect after this statement in -// // opt mode, but none in debug mode. -// EXPECT_EQ(12, DieInDebugOr12(&sideeffect)); -// }, "death"); -// -# ifdef NDEBUG - -# define EXPECT_DEBUG_DEATH(statement, regex) \ - GTEST_EXECUTE_STATEMENT_(statement, regex) - -# define ASSERT_DEBUG_DEATH(statement, regex) \ - GTEST_EXECUTE_STATEMENT_(statement, regex) - -# else - -# define EXPECT_DEBUG_DEATH(statement, regex) \ - EXPECT_DEATH(statement, regex) - -# define ASSERT_DEBUG_DEATH(statement, regex) \ - ASSERT_DEATH(statement, regex) - -# endif // NDEBUG for EXPECT_DEBUG_DEATH -#endif // GTEST_HAS_DEATH_TEST - -// EXPECT_DEATH_IF_SUPPORTED(statement, regex) and -// ASSERT_DEATH_IF_SUPPORTED(statement, regex) expand to real death tests if -// death tests are supported; otherwise they just issue a warning. This is -// useful when you are combining death test assertions with normal test -// assertions in one test. -#if GTEST_HAS_DEATH_TEST -# define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ - EXPECT_DEATH(statement, regex) -# define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \ - ASSERT_DEATH(statement, regex) -#else -# define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ - GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, ) -# define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \ - GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, return) -#endif - -} // namespace testing - -#endif // GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ -// This file was GENERATED by command: -// pump.py gtest-param-test.h.pump -// DO NOT EDIT BY HAND!!! - -// Copyright 2008, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Authors: vladl@google.com (Vlad Losev) -// -// Macros and functions for implementing parameterized tests -// in Google C++ Testing Framework (Google Test) -// -// This file is generated by a SCRIPT. DO NOT EDIT BY HAND! -// -#ifndef GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ -#define GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ - - -// Value-parameterized tests allow you to test your code with different -// parameters without writing multiple copies of the same test. -// -// Here is how you use value-parameterized tests: - -#if 0 - -// To write value-parameterized tests, first you should define a fixture -// class. It is usually derived from testing::TestWithParam (see below for -// another inheritance scheme that's sometimes useful in more complicated -// class hierarchies), where the type of your parameter values. -// TestWithParam is itself derived from testing::Test. T can be any -// copyable type. If it's a raw pointer, you are responsible for managing the -// lifespan of the pointed values. - -class FooTest : public ::testing::TestWithParam { - // You can implement all the usual class fixture members here. -}; - -// Then, use the TEST_P macro to define as many parameterized tests -// for this fixture as you want. The _P suffix is for "parameterized" -// or "pattern", whichever you prefer to think. - -TEST_P(FooTest, DoesBlah) { - // Inside a test, access the test parameter with the GetParam() method - // of the TestWithParam class: - EXPECT_TRUE(foo.Blah(GetParam())); - ... -} - -TEST_P(FooTest, HasBlahBlah) { - ... -} - -// Finally, you can use INSTANTIATE_TEST_CASE_P to instantiate the test -// case with any set of parameters you want. Google Test defines a number -// of functions for generating test parameters. They return what we call -// (surprise!) parameter generators. Here is a summary of them, which -// are all in the testing namespace: -// -// -// Range(begin, end [, step]) - Yields values {begin, begin+step, -// begin+step+step, ...}. The values do not -// include end. step defaults to 1. -// Values(v1, v2, ..., vN) - Yields values {v1, v2, ..., vN}. -// ValuesIn(container) - Yields values from a C-style array, an STL -// ValuesIn(begin,end) container, or an iterator range [begin, end). -// Bool() - Yields sequence {false, true}. -// Combine(g1, g2, ..., gN) - Yields all combinations (the Cartesian product -// for the math savvy) of the values generated -// by the N generators. -// -// For more details, see comments at the definitions of these functions below -// in this file. -// -// The following statement will instantiate tests from the FooTest test case -// each with parameter values "meeny", "miny", and "moe". - -INSTANTIATE_TEST_CASE_P(InstantiationName, - FooTest, - Values("meeny", "miny", "moe")); - -// To distinguish different instances of the pattern, (yes, you -// can instantiate it more then once) the first argument to the -// INSTANTIATE_TEST_CASE_P macro is a prefix that will be added to the -// actual test case name. Remember to pick unique prefixes for different -// instantiations. The tests from the instantiation above will have -// these names: -// -// * InstantiationName/FooTest.DoesBlah/0 for "meeny" -// * InstantiationName/FooTest.DoesBlah/1 for "miny" -// * InstantiationName/FooTest.DoesBlah/2 for "moe" -// * InstantiationName/FooTest.HasBlahBlah/0 for "meeny" -// * InstantiationName/FooTest.HasBlahBlah/1 for "miny" -// * InstantiationName/FooTest.HasBlahBlah/2 for "moe" -// -// You can use these names in --gtest_filter. -// -// This statement will instantiate all tests from FooTest again, each -// with parameter values "cat" and "dog": - -const char* pets[] = {"cat", "dog"}; -INSTANTIATE_TEST_CASE_P(AnotherInstantiationName, FooTest, ValuesIn(pets)); - -// The tests from the instantiation above will have these names: -// -// * AnotherInstantiationName/FooTest.DoesBlah/0 for "cat" -// * AnotherInstantiationName/FooTest.DoesBlah/1 for "dog" -// * AnotherInstantiationName/FooTest.HasBlahBlah/0 for "cat" -// * AnotherInstantiationName/FooTest.HasBlahBlah/1 for "dog" -// -// Please note that INSTANTIATE_TEST_CASE_P will instantiate all tests -// in the given test case, whether their definitions come before or -// AFTER the INSTANTIATE_TEST_CASE_P statement. -// -// Please also note that generator expressions (including parameters to the -// generators) are evaluated in InitGoogleTest(), after main() has started. -// This allows the user on one hand, to adjust generator parameters in order -// to dynamically determine a set of tests to run and on the other hand, -// give the user a chance to inspect the generated tests with Google Test -// reflection API before RUN_ALL_TESTS() is executed. -// -// You can see samples/sample7_unittest.cc and samples/sample8_unittest.cc -// for more examples. -// -// In the future, we plan to publish the API for defining new parameter -// generators. But for now this interface remains part of the internal -// implementation and is subject to change. -// -// -// A parameterized test fixture must be derived from testing::Test and from -// testing::WithParamInterface, where T is the type of the parameter -// values. Inheriting from TestWithParam satisfies that requirement because -// TestWithParam inherits from both Test and WithParamInterface. In more -// complicated hierarchies, however, it is occasionally useful to inherit -// separately from Test and WithParamInterface. For example: - -class BaseTest : public ::testing::Test { - // You can inherit all the usual members for a non-parameterized test - // fixture here. -}; - -class DerivedTest : public BaseTest, public ::testing::WithParamInterface { - // The usual test fixture members go here too. -}; - -TEST_F(BaseTest, HasFoo) { - // This is an ordinary non-parameterized test. -} - -TEST_P(DerivedTest, DoesBlah) { - // GetParam works just the same here as if you inherit from TestWithParam. - EXPECT_TRUE(foo.Blah(GetParam())); -} - -#endif // 0 - - -#if !GTEST_OS_SYMBIAN -# include -#endif - -// scripts/fuse_gtest.py depends on gtest's own header being #included -// *unconditionally*. Therefore these #includes cannot be moved -// inside #if GTEST_HAS_PARAM_TEST. -// Copyright 2008 Google Inc. -// All Rights Reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: vladl@google.com (Vlad Losev) - -// Type and function utilities for implementing parameterized tests. - -#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ -#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ - -#include -#include -#include - -// scripts/fuse_gtest.py depends on gtest's own header being #included -// *unconditionally*. Therefore these #includes cannot be moved -// inside #if GTEST_HAS_PARAM_TEST. -// Copyright 2003 Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Authors: Dan Egnor (egnor@google.com) -// -// A "smart" pointer type with reference tracking. Every pointer to a -// particular object is kept on a circular linked list. When the last pointer -// to an object is destroyed or reassigned, the object is deleted. -// -// Used properly, this deletes the object when the last reference goes away. -// There are several caveats: -// - Like all reference counting schemes, cycles lead to leaks. -// - Each smart pointer is actually two pointers (8 bytes instead of 4). -// - Every time a pointer is assigned, the entire list of pointers to that -// object is traversed. This class is therefore NOT SUITABLE when there -// will often be more than two or three pointers to a particular object. -// - References are only tracked as long as linked_ptr<> objects are copied. -// If a linked_ptr<> is converted to a raw pointer and back, BAD THINGS -// will happen (double deletion). -// -// A good use of this class is storing object references in STL containers. -// You can safely put linked_ptr<> in a vector<>. -// Other uses may not be as good. -// -// Note: If you use an incomplete type with linked_ptr<>, the class -// *containing* linked_ptr<> must have a constructor and destructor (even -// if they do nothing!). -// -// Bill Gibbons suggested we use something like this. -// -// Thread Safety: -// Unlike other linked_ptr implementations, in this implementation -// a linked_ptr object is thread-safe in the sense that: -// - it's safe to copy linked_ptr objects concurrently, -// - it's safe to copy *from* a linked_ptr and read its underlying -// raw pointer (e.g. via get()) concurrently, and -// - it's safe to write to two linked_ptrs that point to the same -// shared object concurrently. -// TODO(wan@google.com): rename this to safe_linked_ptr to avoid -// confusion with normal linked_ptr. - -#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_ -#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_ - -#include -#include - - -namespace testing { -namespace internal { - -// Protects copying of all linked_ptr objects. -GTEST_API_ GTEST_DECLARE_STATIC_MUTEX_(g_linked_ptr_mutex); - -// This is used internally by all instances of linked_ptr<>. It needs to be -// a non-template class because different types of linked_ptr<> can refer to -// the same object (linked_ptr(obj) vs linked_ptr(obj)). -// So, it needs to be possible for different types of linked_ptr to participate -// in the same circular linked list, so we need a single class type here. -// -// DO NOT USE THIS CLASS DIRECTLY YOURSELF. Use linked_ptr. -class linked_ptr_internal { - public: - // Create a new circle that includes only this instance. - void join_new() { - next_ = this; - } - - // Many linked_ptr operations may change p.link_ for some linked_ptr - // variable p in the same circle as this object. Therefore we need - // to prevent two such operations from occurring concurrently. - // - // Note that different types of linked_ptr objects can coexist in a - // circle (e.g. linked_ptr, linked_ptr, and - // linked_ptr). Therefore we must use a single mutex to - // protect all linked_ptr objects. This can create serious - // contention in production code, but is acceptable in a testing - // framework. - - // Join an existing circle. - void join(linked_ptr_internal const* ptr) - GTEST_LOCK_EXCLUDED_(g_linked_ptr_mutex) { - MutexLock lock(&g_linked_ptr_mutex); - - linked_ptr_internal const* p = ptr; - while (p->next_ != ptr) p = p->next_; - p->next_ = this; - next_ = ptr; - } - - // Leave whatever circle we're part of. Returns true if we were the - // last member of the circle. Once this is done, you can join() another. - bool depart() - GTEST_LOCK_EXCLUDED_(g_linked_ptr_mutex) { - MutexLock lock(&g_linked_ptr_mutex); - - if (next_ == this) return true; - linked_ptr_internal const* p = next_; - while (p->next_ != this) p = p->next_; - p->next_ = next_; - return false; - } - - private: - mutable linked_ptr_internal const* next_; -}; - -template -class linked_ptr { - public: - typedef T element_type; - - // Take over ownership of a raw pointer. This should happen as soon as - // possible after the object is created. - explicit linked_ptr(T* ptr = NULL) { capture(ptr); } - ~linked_ptr() { depart(); } - - // Copy an existing linked_ptr<>, adding ourselves to the list of references. - template linked_ptr(linked_ptr const& ptr) { copy(&ptr); } - linked_ptr(linked_ptr const& ptr) { // NOLINT - assert(&ptr != this); - copy(&ptr); - } - - // Assignment releases the old value and acquires the new. - template linked_ptr& operator=(linked_ptr const& ptr) { - depart(); - copy(&ptr); - return *this; - } - - linked_ptr& operator=(linked_ptr const& ptr) { - if (&ptr != this) { - depart(); - copy(&ptr); - } - return *this; - } - - // Smart pointer members. - void reset(T* ptr = NULL) { - depart(); - capture(ptr); - } - T* get() const { return value_; } - T* operator->() const { return value_; } - T& operator*() const { return *value_; } - - bool operator==(T* p) const { return value_ == p; } - bool operator!=(T* p) const { return value_ != p; } - template - bool operator==(linked_ptr const& ptr) const { - return value_ == ptr.get(); - } - template - bool operator!=(linked_ptr const& ptr) const { - return value_ != ptr.get(); - } - - private: - template - friend class linked_ptr; - - T* value_; - linked_ptr_internal link_; - - void depart() { - if (link_.depart()) delete value_; - } - - void capture(T* ptr) { - value_ = ptr; - link_.join_new(); - } - - template void copy(linked_ptr const* ptr) { - value_ = ptr->get(); - if (value_) - link_.join(&ptr->link_); - else - link_.join_new(); - } -}; - -template inline -bool operator==(T* ptr, const linked_ptr& x) { - return ptr == x.get(); -} - -template inline -bool operator!=(T* ptr, const linked_ptr& x) { - return ptr != x.get(); -} - -// A function to convert T* into linked_ptr -// Doing e.g. make_linked_ptr(new FooBarBaz(arg)) is a shorter notation -// for linked_ptr >(new FooBarBaz(arg)) -template -linked_ptr make_linked_ptr(T* ptr) { - return linked_ptr(ptr); -} - -} // namespace internal -} // namespace testing - -#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_ -// Copyright 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: wan@google.com (Zhanyong Wan) - -// Google Test - The Google C++ Testing Framework -// -// This file implements a universal value printer that can print a -// value of any type T: -// -// void ::testing::internal::UniversalPrinter::Print(value, ostream_ptr); -// -// A user can teach this function how to print a class type T by -// defining either operator<<() or PrintTo() in the namespace that -// defines T. More specifically, the FIRST defined function in the -// following list will be used (assuming T is defined in namespace -// foo): -// -// 1. foo::PrintTo(const T&, ostream*) -// 2. operator<<(ostream&, const T&) defined in either foo or the -// global namespace. -// -// If none of the above is defined, it will print the debug string of -// the value if it is a protocol buffer, or print the raw bytes in the -// value otherwise. -// -// To aid debugging: when T is a reference type, the address of the -// value is also printed; when T is a (const) char pointer, both the -// pointer value and the NUL-terminated string it points to are -// printed. -// -// We also provide some convenient wrappers: -// -// // Prints a value to a string. For a (const or not) char -// // pointer, the NUL-terminated string (but not the pointer) is -// // printed. -// std::string ::testing::PrintToString(const T& value); -// -// // Prints a value tersely: for a reference type, the referenced -// // value (but not the address) is printed; for a (const or not) char -// // pointer, the NUL-terminated string (but not the pointer) is -// // printed. -// void ::testing::internal::UniversalTersePrint(const T& value, ostream*); -// -// // Prints value using the type inferred by the compiler. The difference -// // from UniversalTersePrint() is that this function prints both the -// // pointer and the NUL-terminated string for a (const or not) char pointer. -// void ::testing::internal::UniversalPrint(const T& value, ostream*); -// -// // Prints the fields of a tuple tersely to a string vector, one -// // element for each field. Tuple support must be enabled in -// // gtest-port.h. -// std::vector UniversalTersePrintTupleFieldsToStrings( -// const Tuple& value); -// -// Known limitation: -// -// The print primitives print the elements of an STL-style container -// using the compiler-inferred type of *iter where iter is a -// const_iterator of the container. When const_iterator is an input -// iterator but not a forward iterator, this inferred type may not -// match value_type, and the print output may be incorrect. In -// practice, this is rarely a problem as for most containers -// const_iterator is a forward iterator. We'll fix this if there's an -// actual need for it. Note that this fix cannot rely on value_type -// being defined as many user-defined container types don't have -// value_type. - -#ifndef GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_ -#define GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_ - -#include // NOLINT -#include -#include -#include -#include - -namespace testing { - -// Definitions in the 'internal' and 'internal2' name spaces are -// subject to change without notice. DO NOT USE THEM IN USER CODE! -namespace internal2 { - -// Prints the given number of bytes in the given object to the given -// ostream. -GTEST_API_ void PrintBytesInObjectTo(const unsigned char* obj_bytes, - size_t count, - ::std::ostream* os); - -// For selecting which printer to use when a given type has neither << -// nor PrintTo(). -enum TypeKind { - kProtobuf, // a protobuf type - kConvertibleToInteger, // a type implicitly convertible to BiggestInt - // (e.g. a named or unnamed enum type) - kOtherType // anything else -}; - -// TypeWithoutFormatter::PrintValue(value, os) is called -// by the universal printer to print a value of type T when neither -// operator<< nor PrintTo() is defined for T, where kTypeKind is the -// "kind" of T as defined by enum TypeKind. -template -class TypeWithoutFormatter { - public: - // This default version is called when kTypeKind is kOtherType. - static void PrintValue(const T& value, ::std::ostream* os) { - PrintBytesInObjectTo(reinterpret_cast(&value), - sizeof(value), os); - } -}; - -// We print a protobuf using its ShortDebugString() when the string -// doesn't exceed this many characters; otherwise we print it using -// DebugString() for better readability. -const size_t kProtobufOneLinerMaxLength = 50; - -template -class TypeWithoutFormatter { - public: - static void PrintValue(const T& value, ::std::ostream* os) { - const ::testing::internal::string short_str = value.ShortDebugString(); - const ::testing::internal::string pretty_str = - short_str.length() <= kProtobufOneLinerMaxLength ? - short_str : ("\n" + value.DebugString()); - *os << ("<" + pretty_str + ">"); - } -}; - -template -class TypeWithoutFormatter { - public: - // Since T has no << operator or PrintTo() but can be implicitly - // converted to BiggestInt, we print it as a BiggestInt. - // - // Most likely T is an enum type (either named or unnamed), in which - // case printing it as an integer is the desired behavior. In case - // T is not an enum, printing it as an integer is the best we can do - // given that it has no user-defined printer. - static void PrintValue(const T& value, ::std::ostream* os) { - const internal::BiggestInt kBigInt = value; - *os << kBigInt; - } -}; - -// Prints the given value to the given ostream. If the value is a -// protocol message, its debug string is printed; if it's an enum or -// of a type implicitly convertible to BiggestInt, it's printed as an -// integer; otherwise the bytes in the value are printed. This is -// what UniversalPrinter::Print() does when it knows nothing about -// type T and T has neither << operator nor PrintTo(). -// -// A user can override this behavior for a class type Foo by defining -// a << operator in the namespace where Foo is defined. -// -// We put this operator in namespace 'internal2' instead of 'internal' -// to simplify the implementation, as much code in 'internal' needs to -// use << in STL, which would conflict with our own << were it defined -// in 'internal'. -// -// Note that this operator<< takes a generic std::basic_ostream type instead of the more restricted std::ostream. If -// we define it to take an std::ostream instead, we'll get an -// "ambiguous overloads" compiler error when trying to print a type -// Foo that supports streaming to std::basic_ostream, as the compiler cannot tell whether -// operator<<(std::ostream&, const T&) or -// operator<<(std::basic_stream, const Foo&) is more -// specific. -template -::std::basic_ostream& operator<<( - ::std::basic_ostream& os, const T& x) { - TypeWithoutFormatter::value ? kProtobuf : - internal::ImplicitlyConvertible::value ? - kConvertibleToInteger : kOtherType)>::PrintValue(x, &os); - return os; -} - -} // namespace internal2 -} // namespace testing - -// This namespace MUST NOT BE NESTED IN ::testing, or the name look-up -// magic needed for implementing UniversalPrinter won't work. -namespace testing_internal { - -// Used to print a value that is not an STL-style container when the -// user doesn't define PrintTo() for it. -template -void DefaultPrintNonContainerTo(const T& value, ::std::ostream* os) { - // With the following statement, during unqualified name lookup, - // testing::internal2::operator<< appears as if it was declared in - // the nearest enclosing namespace that contains both - // ::testing_internal and ::testing::internal2, i.e. the global - // namespace. For more details, refer to the C++ Standard section - // 7.3.4-1 [namespace.udir]. This allows us to fall back onto - // testing::internal2::operator<< in case T doesn't come with a << - // operator. - // - // We cannot write 'using ::testing::internal2::operator<<;', which - // gcc 3.3 fails to compile due to a compiler bug. - using namespace ::testing::internal2; // NOLINT - - // Assuming T is defined in namespace foo, in the next statement, - // the compiler will consider all of: - // - // 1. foo::operator<< (thanks to Koenig look-up), - // 2. ::operator<< (as the current namespace is enclosed in ::), - // 3. testing::internal2::operator<< (thanks to the using statement above). - // - // The operator<< whose type matches T best will be picked. - // - // We deliberately allow #2 to be a candidate, as sometimes it's - // impossible to define #1 (e.g. when foo is ::std, defining - // anything in it is undefined behavior unless you are a compiler - // vendor.). - *os << value; -} - -} // namespace testing_internal - -namespace testing { -namespace internal { - -// UniversalPrinter::Print(value, ostream_ptr) prints the given -// value to the given ostream. The caller must ensure that -// 'ostream_ptr' is not NULL, or the behavior is undefined. -// -// We define UniversalPrinter as a class template (as opposed to a -// function template), as we need to partially specialize it for -// reference types, which cannot be done with function templates. -template -class UniversalPrinter; - -template -void UniversalPrint(const T& value, ::std::ostream* os); - -// Used to print an STL-style container when the user doesn't define -// a PrintTo() for it. -template -void DefaultPrintTo(IsContainer /* dummy */, - false_type /* is not a pointer */, - const C& container, ::std::ostream* os) { - const size_t kMaxCount = 32; // The maximum number of elements to print. - *os << '{'; - size_t count = 0; - for (typename C::const_iterator it = container.begin(); - it != container.end(); ++it, ++count) { - if (count > 0) { - *os << ','; - if (count == kMaxCount) { // Enough has been printed. - *os << " ..."; - break; - } - } - *os << ' '; - // We cannot call PrintTo(*it, os) here as PrintTo() doesn't - // handle *it being a native array. - internal::UniversalPrint(*it, os); - } - - if (count > 0) { - *os << ' '; - } - *os << '}'; -} - -// Used to print a pointer that is neither a char pointer nor a member -// pointer, when the user doesn't define PrintTo() for it. (A member -// variable pointer or member function pointer doesn't really point to -// a location in the address space. Their representation is -// implementation-defined. Therefore they will be printed as raw -// bytes.) -template -void DefaultPrintTo(IsNotContainer /* dummy */, - true_type /* is a pointer */, - T* p, ::std::ostream* os) { - if (p == NULL) { - *os << "NULL"; - } else { - // C++ doesn't allow casting from a function pointer to any object - // pointer. - // - // IsTrue() silences warnings: "Condition is always true", - // "unreachable code". - if (IsTrue(ImplicitlyConvertible::value)) { - // T is not a function type. We just call << to print p, - // relying on ADL to pick up user-defined << for their pointer - // types, if any. - *os << p; - } else { - // T is a function type, so '*os << p' doesn't do what we want - // (it just prints p as bool). We want to print p as a const - // void*. However, we cannot cast it to const void* directly, - // even using reinterpret_cast, as earlier versions of gcc - // (e.g. 3.4.5) cannot compile the cast when p is a function - // pointer. Casting to UInt64 first solves the problem. - *os << reinterpret_cast( - reinterpret_cast(p)); - } - } -} - -// Used to print a non-container, non-pointer value when the user -// doesn't define PrintTo() for it. -template -void DefaultPrintTo(IsNotContainer /* dummy */, - false_type /* is not a pointer */, - const T& value, ::std::ostream* os) { - ::testing_internal::DefaultPrintNonContainerTo(value, os); -} - -// Prints the given value using the << operator if it has one; -// otherwise prints the bytes in it. This is what -// UniversalPrinter::Print() does when PrintTo() is not specialized -// or overloaded for type T. -// -// A user can override this behavior for a class type Foo by defining -// an overload of PrintTo() in the namespace where Foo is defined. We -// give the user this option as sometimes defining a << operator for -// Foo is not desirable (e.g. the coding style may prevent doing it, -// or there is already a << operator but it doesn't do what the user -// wants). -template -void PrintTo(const T& value, ::std::ostream* os) { - // DefaultPrintTo() is overloaded. The type of its first two - // arguments determine which version will be picked. If T is an - // STL-style container, the version for container will be called; if - // T is a pointer, the pointer version will be called; otherwise the - // generic version will be called. - // - // Note that we check for container types here, prior to we check - // for protocol message types in our operator<<. The rationale is: - // - // For protocol messages, we want to give people a chance to - // override Google Mock's format by defining a PrintTo() or - // operator<<. For STL containers, other formats can be - // incompatible with Google Mock's format for the container - // elements; therefore we check for container types here to ensure - // that our format is used. - // - // The second argument of DefaultPrintTo() is needed to bypass a bug - // in Symbian's C++ compiler that prevents it from picking the right - // overload between: - // - // PrintTo(const T& x, ...); - // PrintTo(T* x, ...); - DefaultPrintTo(IsContainerTest(0), is_pointer(), value, os); -} - -// The following list of PrintTo() overloads tells -// UniversalPrinter::Print() how to print standard types (built-in -// types, strings, plain arrays, and pointers). - -// Overloads for various char types. -GTEST_API_ void PrintTo(unsigned char c, ::std::ostream* os); -GTEST_API_ void PrintTo(signed char c, ::std::ostream* os); -inline void PrintTo(char c, ::std::ostream* os) { - // When printing a plain char, we always treat it as unsigned. This - // way, the output won't be affected by whether the compiler thinks - // char is signed or not. - PrintTo(static_cast(c), os); -} - -// Overloads for other simple built-in types. -inline void PrintTo(bool x, ::std::ostream* os) { - *os << (x ? "true" : "false"); -} - -// Overload for wchar_t type. -// Prints a wchar_t as a symbol if it is printable or as its internal -// code otherwise and also as its decimal code (except for L'\0'). -// The L'\0' char is printed as "L'\\0'". The decimal code is printed -// as signed integer when wchar_t is implemented by the compiler -// as a signed type and is printed as an unsigned integer when wchar_t -// is implemented as an unsigned type. -GTEST_API_ void PrintTo(wchar_t wc, ::std::ostream* os); - -// Overloads for C strings. -GTEST_API_ void PrintTo(const char* s, ::std::ostream* os); -inline void PrintTo(char* s, ::std::ostream* os) { - PrintTo(ImplicitCast_(s), os); -} - -// signed/unsigned char is often used for representing binary data, so -// we print pointers to it as void* to be safe. -inline void PrintTo(const signed char* s, ::std::ostream* os) { - PrintTo(ImplicitCast_(s), os); -} -inline void PrintTo(signed char* s, ::std::ostream* os) { - PrintTo(ImplicitCast_(s), os); -} -inline void PrintTo(const unsigned char* s, ::std::ostream* os) { - PrintTo(ImplicitCast_(s), os); -} -inline void PrintTo(unsigned char* s, ::std::ostream* os) { - PrintTo(ImplicitCast_(s), os); -} - -// MSVC can be configured to define wchar_t as a typedef of unsigned -// short. It defines _NATIVE_WCHAR_T_DEFINED when wchar_t is a native -// type. When wchar_t is a typedef, defining an overload for const -// wchar_t* would cause unsigned short* be printed as a wide string, -// possibly causing invalid memory accesses. -#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) -// Overloads for wide C strings -GTEST_API_ void PrintTo(const wchar_t* s, ::std::ostream* os); -inline void PrintTo(wchar_t* s, ::std::ostream* os) { - PrintTo(ImplicitCast_(s), os); -} -#endif - -// Overload for C arrays. Multi-dimensional arrays are printed -// properly. - -// Prints the given number of elements in an array, without printing -// the curly braces. -template -void PrintRawArrayTo(const T a[], size_t count, ::std::ostream* os) { - UniversalPrint(a[0], os); - for (size_t i = 1; i != count; i++) { - *os << ", "; - UniversalPrint(a[i], os); - } -} - -// Overloads for ::string and ::std::string. -#if GTEST_HAS_GLOBAL_STRING -GTEST_API_ void PrintStringTo(const ::string&s, ::std::ostream* os); -inline void PrintTo(const ::string& s, ::std::ostream* os) { - PrintStringTo(s, os); -} -#endif // GTEST_HAS_GLOBAL_STRING - -GTEST_API_ void PrintStringTo(const ::std::string&s, ::std::ostream* os); -inline void PrintTo(const ::std::string& s, ::std::ostream* os) { - PrintStringTo(s, os); -} - -// Overloads for ::wstring and ::std::wstring. -#if GTEST_HAS_GLOBAL_WSTRING -GTEST_API_ void PrintWideStringTo(const ::wstring&s, ::std::ostream* os); -inline void PrintTo(const ::wstring& s, ::std::ostream* os) { - PrintWideStringTo(s, os); -} -#endif // GTEST_HAS_GLOBAL_WSTRING - -#if GTEST_HAS_STD_WSTRING -GTEST_API_ void PrintWideStringTo(const ::std::wstring&s, ::std::ostream* os); -inline void PrintTo(const ::std::wstring& s, ::std::ostream* os) { - PrintWideStringTo(s, os); -} -#endif // GTEST_HAS_STD_WSTRING - -#if GTEST_HAS_TR1_TUPLE -// Overload for ::std::tr1::tuple. Needed for printing function arguments, -// which are packed as tuples. - -// Helper function for printing a tuple. T must be instantiated with -// a tuple type. -template -void PrintTupleTo(const T& t, ::std::ostream* os); - -// Overloaded PrintTo() for tuples of various arities. We support -// tuples of up-to 10 fields. The following implementation works -// regardless of whether tr1::tuple is implemented using the -// non-standard variadic template feature or not. - -inline void PrintTo(const ::std::tr1::tuple<>& t, ::std::ostream* os) { - PrintTupleTo(t, os); -} - -template -void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { - PrintTupleTo(t, os); -} - -template -void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { - PrintTupleTo(t, os); -} - -template -void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { - PrintTupleTo(t, os); -} - -template -void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { - PrintTupleTo(t, os); -} - -template -void PrintTo(const ::std::tr1::tuple& t, - ::std::ostream* os) { - PrintTupleTo(t, os); -} - -template -void PrintTo(const ::std::tr1::tuple& t, - ::std::ostream* os) { - PrintTupleTo(t, os); -} - -template -void PrintTo(const ::std::tr1::tuple& t, - ::std::ostream* os) { - PrintTupleTo(t, os); -} - -template -void PrintTo(const ::std::tr1::tuple& t, - ::std::ostream* os) { - PrintTupleTo(t, os); -} - -template -void PrintTo(const ::std::tr1::tuple& t, - ::std::ostream* os) { - PrintTupleTo(t, os); -} - -template -void PrintTo( - const ::std::tr1::tuple& t, - ::std::ostream* os) { - PrintTupleTo(t, os); -} -#endif // GTEST_HAS_TR1_TUPLE - -// Overload for std::pair. -template -void PrintTo(const ::std::pair& value, ::std::ostream* os) { - *os << '('; - // We cannot use UniversalPrint(value.first, os) here, as T1 may be - // a reference type. The same for printing value.second. - UniversalPrinter::Print(value.first, os); - *os << ", "; - UniversalPrinter::Print(value.second, os); - *os << ')'; -} - -// Implements printing a non-reference type T by letting the compiler -// pick the right overload of PrintTo() for T. -template -class UniversalPrinter { - public: - // MSVC warns about adding const to a function type, so we want to - // disable the warning. -#ifdef _MSC_VER -# pragma warning(push) // Saves the current warning state. -# pragma warning(disable:4180) // Temporarily disables warning 4180. -#endif // _MSC_VER - - // Note: we deliberately don't call this PrintTo(), as that name - // conflicts with ::testing::internal::PrintTo in the body of the - // function. - static void Print(const T& value, ::std::ostream* os) { - // By default, ::testing::internal::PrintTo() is used for printing - // the value. - // - // Thanks to Koenig look-up, if T is a class and has its own - // PrintTo() function defined in its namespace, that function will - // be visible here. Since it is more specific than the generic ones - // in ::testing::internal, it will be picked by the compiler in the - // following statement - exactly what we want. - PrintTo(value, os); - } - -#ifdef _MSC_VER -# pragma warning(pop) // Restores the warning state. -#endif // _MSC_VER -}; - -// UniversalPrintArray(begin, len, os) prints an array of 'len' -// elements, starting at address 'begin'. -template -void UniversalPrintArray(const T* begin, size_t len, ::std::ostream* os) { - if (len == 0) { - *os << "{}"; - } else { - *os << "{ "; - const size_t kThreshold = 18; - const size_t kChunkSize = 8; - // If the array has more than kThreshold elements, we'll have to - // omit some details by printing only the first and the last - // kChunkSize elements. - // TODO(wan@google.com): let the user control the threshold using a flag. - if (len <= kThreshold) { - PrintRawArrayTo(begin, len, os); - } else { - PrintRawArrayTo(begin, kChunkSize, os); - *os << ", ..., "; - PrintRawArrayTo(begin + len - kChunkSize, kChunkSize, os); - } - *os << " }"; - } -} -// This overload prints a (const) char array compactly. -GTEST_API_ void UniversalPrintArray( - const char* begin, size_t len, ::std::ostream* os); - -// This overload prints a (const) wchar_t array compactly. -GTEST_API_ void UniversalPrintArray( - const wchar_t* begin, size_t len, ::std::ostream* os); - -// Implements printing an array type T[N]. -template -class UniversalPrinter { - public: - // Prints the given array, omitting some elements when there are too - // many. - static void Print(const T (&a)[N], ::std::ostream* os) { - UniversalPrintArray(a, N, os); - } -}; - -// Implements printing a reference type T&. -template -class UniversalPrinter { - public: - // MSVC warns about adding const to a function type, so we want to - // disable the warning. -#ifdef _MSC_VER -# pragma warning(push) // Saves the current warning state. -# pragma warning(disable:4180) // Temporarily disables warning 4180. -#endif // _MSC_VER - - static void Print(const T& value, ::std::ostream* os) { - // Prints the address of the value. We use reinterpret_cast here - // as static_cast doesn't compile when T is a function type. - *os << "@" << reinterpret_cast(&value) << " "; - - // Then prints the value itself. - UniversalPrint(value, os); - } - -#ifdef _MSC_VER -# pragma warning(pop) // Restores the warning state. -#endif // _MSC_VER -}; - -// Prints a value tersely: for a reference type, the referenced value -// (but not the address) is printed; for a (const) char pointer, the -// NUL-terminated string (but not the pointer) is printed. - -template -class UniversalTersePrinter { - public: - static void Print(const T& value, ::std::ostream* os) { - UniversalPrint(value, os); - } -}; -template -class UniversalTersePrinter { - public: - static void Print(const T& value, ::std::ostream* os) { - UniversalPrint(value, os); - } -}; -template -class UniversalTersePrinter { - public: - static void Print(const T (&value)[N], ::std::ostream* os) { - UniversalPrinter::Print(value, os); - } -}; -template <> -class UniversalTersePrinter { - public: - static void Print(const char* str, ::std::ostream* os) { - if (str == NULL) { - *os << "NULL"; - } else { - UniversalPrint(string(str), os); - } - } -}; -template <> -class UniversalTersePrinter { - public: - static void Print(char* str, ::std::ostream* os) { - UniversalTersePrinter::Print(str, os); - } -}; - -#if GTEST_HAS_STD_WSTRING -template <> -class UniversalTersePrinter { - public: - static void Print(const wchar_t* str, ::std::ostream* os) { - if (str == NULL) { - *os << "NULL"; - } else { - UniversalPrint(::std::wstring(str), os); - } - } -}; -#endif - -template <> -class UniversalTersePrinter { - public: - static void Print(wchar_t* str, ::std::ostream* os) { - UniversalTersePrinter::Print(str, os); - } -}; - -template -void UniversalTersePrint(const T& value, ::std::ostream* os) { - UniversalTersePrinter::Print(value, os); -} - -// Prints a value using the type inferred by the compiler. The -// difference between this and UniversalTersePrint() is that for a -// (const) char pointer, this prints both the pointer and the -// NUL-terminated string. -template -void UniversalPrint(const T& value, ::std::ostream* os) { - // A workarond for the bug in VC++ 7.1 that prevents us from instantiating - // UniversalPrinter with T directly. - typedef T T1; - UniversalPrinter::Print(value, os); -} - -#if GTEST_HAS_TR1_TUPLE -typedef ::std::vector Strings; - -// This helper template allows PrintTo() for tuples and -// UniversalTersePrintTupleFieldsToStrings() to be defined by -// induction on the number of tuple fields. The idea is that -// TuplePrefixPrinter::PrintPrefixTo(t, os) prints the first N -// fields in tuple t, and can be defined in terms of -// TuplePrefixPrinter. - -// The inductive case. -template -struct TuplePrefixPrinter { - // Prints the first N fields of a tuple. - template - static void PrintPrefixTo(const Tuple& t, ::std::ostream* os) { - TuplePrefixPrinter::PrintPrefixTo(t, os); - *os << ", "; - UniversalPrinter::type> - ::Print(::std::tr1::get(t), os); - } - - // Tersely prints the first N fields of a tuple to a string vector, - // one element for each field. - template - static void TersePrintPrefixToStrings(const Tuple& t, Strings* strings) { - TuplePrefixPrinter::TersePrintPrefixToStrings(t, strings); - ::std::stringstream ss; - UniversalTersePrint(::std::tr1::get(t), &ss); - strings->push_back(ss.str()); - } -}; - -// Base cases. -template <> -struct TuplePrefixPrinter<0> { - template - static void PrintPrefixTo(const Tuple&, ::std::ostream*) {} - - template - static void TersePrintPrefixToStrings(const Tuple&, Strings*) {} -}; -// We have to specialize the entire TuplePrefixPrinter<> class -// template here, even though the definition of -// TersePrintPrefixToStrings() is the same as the generic version, as -// Embarcadero (formerly CodeGear, formerly Borland) C++ doesn't -// support specializing a method template of a class template. -template <> -struct TuplePrefixPrinter<1> { - template - static void PrintPrefixTo(const Tuple& t, ::std::ostream* os) { - UniversalPrinter::type>:: - Print(::std::tr1::get<0>(t), os); - } - - template - static void TersePrintPrefixToStrings(const Tuple& t, Strings* strings) { - ::std::stringstream ss; - UniversalTersePrint(::std::tr1::get<0>(t), &ss); - strings->push_back(ss.str()); - } -}; - -// Helper function for printing a tuple. T must be instantiated with -// a tuple type. -template -void PrintTupleTo(const T& t, ::std::ostream* os) { - *os << "("; - TuplePrefixPrinter< ::std::tr1::tuple_size::value>:: - PrintPrefixTo(t, os); - *os << ")"; -} - -// Prints the fields of a tuple tersely to a string vector, one -// element for each field. See the comment before -// UniversalTersePrint() for how we define "tersely". -template -Strings UniversalTersePrintTupleFieldsToStrings(const Tuple& value) { - Strings result; - TuplePrefixPrinter< ::std::tr1::tuple_size::value>:: - TersePrintPrefixToStrings(value, &result); - return result; -} -#endif // GTEST_HAS_TR1_TUPLE - -} // namespace internal - -template -::std::string PrintToString(const T& value) { - ::std::stringstream ss; - internal::UniversalTersePrinter::Print(value, &ss); - return ss.str(); -} - -} // namespace testing - -#endif // GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_ - -#if GTEST_HAS_PARAM_TEST - -namespace testing { -namespace internal { - -// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. -// -// Outputs a message explaining invalid registration of different -// fixture class for the same test case. This may happen when -// TEST_P macro is used to define two tests with the same name -// but in different namespaces. -GTEST_API_ void ReportInvalidTestCaseType(const char* test_case_name, - const char* file, int line); - -template class ParamGeneratorInterface; -template class ParamGenerator; - -// Interface for iterating over elements provided by an implementation -// of ParamGeneratorInterface. -template -class ParamIteratorInterface { - public: - virtual ~ParamIteratorInterface() {} - // A pointer to the base generator instance. - // Used only for the purposes of iterator comparison - // to make sure that two iterators belong to the same generator. - virtual const ParamGeneratorInterface* BaseGenerator() const = 0; - // Advances iterator to point to the next element - // provided by the generator. The caller is responsible - // for not calling Advance() on an iterator equal to - // BaseGenerator()->End(). - virtual void Advance() = 0; - // Clones the iterator object. Used for implementing copy semantics - // of ParamIterator. - virtual ParamIteratorInterface* Clone() const = 0; - // Dereferences the current iterator and provides (read-only) access - // to the pointed value. It is the caller's responsibility not to call - // Current() on an iterator equal to BaseGenerator()->End(). - // Used for implementing ParamGenerator::operator*(). - virtual const T* Current() const = 0; - // Determines whether the given iterator and other point to the same - // element in the sequence generated by the generator. - // Used for implementing ParamGenerator::operator==(). - virtual bool Equals(const ParamIteratorInterface& other) const = 0; -}; - -// Class iterating over elements provided by an implementation of -// ParamGeneratorInterface. It wraps ParamIteratorInterface -// and implements the const forward iterator concept. -template -class ParamIterator { - public: - typedef T value_type; - typedef const T& reference; - typedef ptrdiff_t difference_type; - - // ParamIterator assumes ownership of the impl_ pointer. - ParamIterator(const ParamIterator& other) : impl_(other.impl_->Clone()) {} - ParamIterator& operator=(const ParamIterator& other) { - if (this != &other) - impl_.reset(other.impl_->Clone()); - return *this; - } - - const T& operator*() const { return *impl_->Current(); } - const T* operator->() const { return impl_->Current(); } - // Prefix version of operator++. - ParamIterator& operator++() { - impl_->Advance(); - return *this; - } - // Postfix version of operator++. - ParamIterator operator++(int /*unused*/) { - ParamIteratorInterface* clone = impl_->Clone(); - impl_->Advance(); - return ParamIterator(clone); - } - bool operator==(const ParamIterator& other) const { - return impl_.get() == other.impl_.get() || impl_->Equals(*other.impl_); - } - bool operator!=(const ParamIterator& other) const { - return !(*this == other); - } - - private: - friend class ParamGenerator; - explicit ParamIterator(ParamIteratorInterface* impl) : impl_(impl) {} - scoped_ptr > impl_; -}; - -// ParamGeneratorInterface is the binary interface to access generators -// defined in other translation units. -template -class ParamGeneratorInterface { - public: - typedef T ParamType; - - virtual ~ParamGeneratorInterface() {} - - // Generator interface definition - virtual ParamIteratorInterface* Begin() const = 0; - virtual ParamIteratorInterface* End() const = 0; -}; - -// Wraps ParamGeneratorInterface and provides general generator syntax -// compatible with the STL Container concept. -// This class implements copy initialization semantics and the contained -// ParamGeneratorInterface instance is shared among all copies -// of the original object. This is possible because that instance is immutable. -template -class ParamGenerator { - public: - typedef ParamIterator iterator; - - explicit ParamGenerator(ParamGeneratorInterface* impl) : impl_(impl) {} - ParamGenerator(const ParamGenerator& other) : impl_(other.impl_) {} - - ParamGenerator& operator=(const ParamGenerator& other) { - impl_ = other.impl_; - return *this; - } - - iterator begin() const { return iterator(impl_->Begin()); } - iterator end() const { return iterator(impl_->End()); } - - private: - linked_ptr > impl_; -}; - -// Generates values from a range of two comparable values. Can be used to -// generate sequences of user-defined types that implement operator+() and -// operator<(). -// This class is used in the Range() function. -template -class RangeGenerator : public ParamGeneratorInterface { - public: - RangeGenerator(T begin, T end, IncrementT step) - : begin_(begin), end_(end), - step_(step), end_index_(CalculateEndIndex(begin, end, step)) {} - virtual ~RangeGenerator() {} - - virtual ParamIteratorInterface* Begin() const { - return new Iterator(this, begin_, 0, step_); - } - virtual ParamIteratorInterface* End() const { - return new Iterator(this, end_, end_index_, step_); - } - - private: - class Iterator : public ParamIteratorInterface { - public: - Iterator(const ParamGeneratorInterface* base, T value, int index, - IncrementT step) - : base_(base), value_(value), index_(index), step_(step) {} - virtual ~Iterator() {} - - virtual const ParamGeneratorInterface* BaseGenerator() const { - return base_; - } - virtual void Advance() { - value_ = value_ + step_; - index_++; - } - virtual ParamIteratorInterface* Clone() const { - return new Iterator(*this); - } - virtual const T* Current() const { return &value_; } - virtual bool Equals(const ParamIteratorInterface& other) const { - // Having the same base generator guarantees that the other - // iterator is of the same type and we can downcast. - GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) - << "The program attempted to compare iterators " - << "from different generators." << std::endl; - const int other_index = - CheckedDowncastToActualType(&other)->index_; - return index_ == other_index; - } - - private: - Iterator(const Iterator& other) - : ParamIteratorInterface(), - base_(other.base_), value_(other.value_), index_(other.index_), - step_(other.step_) {} - - // No implementation - assignment is unsupported. - void operator=(const Iterator& other); - - const ParamGeneratorInterface* const base_; - T value_; - int index_; - const IncrementT step_; - }; // class RangeGenerator::Iterator - - static int CalculateEndIndex(const T& begin, - const T& end, - const IncrementT& step) { - int end_index = 0; - for (T i = begin; i < end; i = i + step) - end_index++; - return end_index; - } - - // No implementation - assignment is unsupported. - void operator=(const RangeGenerator& other); - - const T begin_; - const T end_; - const IncrementT step_; - // The index for the end() iterator. All the elements in the generated - // sequence are indexed (0-based) to aid iterator comparison. - const int end_index_; -}; // class RangeGenerator - - -// Generates values from a pair of STL-style iterators. Used in the -// ValuesIn() function. The elements are copied from the source range -// since the source can be located on the stack, and the generator -// is likely to persist beyond that stack frame. -template -class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface { - public: - template - ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end) - : container_(begin, end) {} - virtual ~ValuesInIteratorRangeGenerator() {} - - virtual ParamIteratorInterface* Begin() const { - return new Iterator(this, container_.begin()); - } - virtual ParamIteratorInterface* End() const { - return new Iterator(this, container_.end()); - } - - private: - typedef typename ::std::vector ContainerType; - - class Iterator : public ParamIteratorInterface { - public: - Iterator(const ParamGeneratorInterface* base, - typename ContainerType::const_iterator iterator) - : base_(base), iterator_(iterator) {} - virtual ~Iterator() {} - - virtual const ParamGeneratorInterface* BaseGenerator() const { - return base_; - } - virtual void Advance() { - ++iterator_; - value_.reset(); - } - virtual ParamIteratorInterface* Clone() const { - return new Iterator(*this); - } - // We need to use cached value referenced by iterator_ because *iterator_ - // can return a temporary object (and of type other then T), so just - // having "return &*iterator_;" doesn't work. - // value_ is updated here and not in Advance() because Advance() - // can advance iterator_ beyond the end of the range, and we cannot - // detect that fact. The client code, on the other hand, is - // responsible for not calling Current() on an out-of-range iterator. - virtual const T* Current() const { - if (value_.get() == NULL) - value_.reset(new T(*iterator_)); - return value_.get(); - } - virtual bool Equals(const ParamIteratorInterface& other) const { - // Having the same base generator guarantees that the other - // iterator is of the same type and we can downcast. - GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) - << "The program attempted to compare iterators " - << "from different generators." << std::endl; - return iterator_ == - CheckedDowncastToActualType(&other)->iterator_; - } - - private: - Iterator(const Iterator& other) - // The explicit constructor call suppresses a false warning - // emitted by gcc when supplied with the -Wextra option. - : ParamIteratorInterface(), - base_(other.base_), - iterator_(other.iterator_) {} - - const ParamGeneratorInterface* const base_; - typename ContainerType::const_iterator iterator_; - // A cached value of *iterator_. We keep it here to allow access by - // pointer in the wrapping iterator's operator->(). - // value_ needs to be mutable to be accessed in Current(). - // Use of scoped_ptr helps manage cached value's lifetime, - // which is bound by the lifespan of the iterator itself. - mutable scoped_ptr value_; - }; // class ValuesInIteratorRangeGenerator::Iterator - - // No implementation - assignment is unsupported. - void operator=(const ValuesInIteratorRangeGenerator& other); - - const ContainerType container_; -}; // class ValuesInIteratorRangeGenerator - -// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. -// -// Stores a parameter value and later creates tests parameterized with that -// value. -template -class ParameterizedTestFactory : public TestFactoryBase { - public: - typedef typename TestClass::ParamType ParamType; - explicit ParameterizedTestFactory(ParamType parameter) : - parameter_(parameter) {} - virtual Test* CreateTest() { - TestClass::SetParam(¶meter_); - return new TestClass(); - } - - private: - const ParamType parameter_; - - GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestFactory); -}; - -// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. -// -// TestMetaFactoryBase is a base class for meta-factories that create -// test factories for passing into MakeAndRegisterTestInfo function. -template -class TestMetaFactoryBase { - public: - virtual ~TestMetaFactoryBase() {} - - virtual TestFactoryBase* CreateTestFactory(ParamType parameter) = 0; -}; - -// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. -// -// TestMetaFactory creates test factories for passing into -// MakeAndRegisterTestInfo function. Since MakeAndRegisterTestInfo receives -// ownership of test factory pointer, same factory object cannot be passed -// into that method twice. But ParameterizedTestCaseInfo is going to call -// it for each Test/Parameter value combination. Thus it needs meta factory -// creator class. -template -class TestMetaFactory - : public TestMetaFactoryBase { - public: - typedef typename TestCase::ParamType ParamType; - - TestMetaFactory() {} - - virtual TestFactoryBase* CreateTestFactory(ParamType parameter) { - return new ParameterizedTestFactory(parameter); - } - - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(TestMetaFactory); -}; - -// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. -// -// ParameterizedTestCaseInfoBase is a generic interface -// to ParameterizedTestCaseInfo classes. ParameterizedTestCaseInfoBase -// accumulates test information provided by TEST_P macro invocations -// and generators provided by INSTANTIATE_TEST_CASE_P macro invocations -// and uses that information to register all resulting test instances -// in RegisterTests method. The ParameterizeTestCaseRegistry class holds -// a collection of pointers to the ParameterizedTestCaseInfo objects -// and calls RegisterTests() on each of them when asked. -class ParameterizedTestCaseInfoBase { - public: - virtual ~ParameterizedTestCaseInfoBase() {} - - // Base part of test case name for display purposes. - virtual const string& GetTestCaseName() const = 0; - // Test case id to verify identity. - virtual TypeId GetTestCaseTypeId() const = 0; - // UnitTest class invokes this method to register tests in this - // test case right before running them in RUN_ALL_TESTS macro. - // This method should not be called more then once on any single - // instance of a ParameterizedTestCaseInfoBase derived class. - virtual void RegisterTests() = 0; - - protected: - ParameterizedTestCaseInfoBase() {} - - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfoBase); -}; - -// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. -// -// ParameterizedTestCaseInfo accumulates tests obtained from TEST_P -// macro invocations for a particular test case and generators -// obtained from INSTANTIATE_TEST_CASE_P macro invocations for that -// test case. It registers tests with all values generated by all -// generators when asked. -template -class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase { - public: - // ParamType and GeneratorCreationFunc are private types but are required - // for declarations of public methods AddTestPattern() and - // AddTestCaseInstantiation(). - typedef typename TestCase::ParamType ParamType; - // A function that returns an instance of appropriate generator type. - typedef ParamGenerator(GeneratorCreationFunc)(); - - explicit ParameterizedTestCaseInfo(const char* name) - : test_case_name_(name) {} - - // Test case base name for display purposes. - virtual const string& GetTestCaseName() const { return test_case_name_; } - // Test case id to verify identity. - virtual TypeId GetTestCaseTypeId() const { return GetTypeId(); } - // TEST_P macro uses AddTestPattern() to record information - // about a single test in a LocalTestInfo structure. - // test_case_name is the base name of the test case (without invocation - // prefix). test_base_name is the name of an individual test without - // parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is - // test case base name and DoBar is test base name. - void AddTestPattern(const char* test_case_name, - const char* test_base_name, - TestMetaFactoryBase* meta_factory) { - tests_.push_back(linked_ptr(new TestInfo(test_case_name, - test_base_name, - meta_factory))); - } - // INSTANTIATE_TEST_CASE_P macro uses AddGenerator() to record information - // about a generator. - int AddTestCaseInstantiation(const string& instantiation_name, - GeneratorCreationFunc* func, - const char* /* file */, - int /* line */) { - instantiations_.push_back(::std::make_pair(instantiation_name, func)); - return 0; // Return value used only to run this method in namespace scope. - } - // UnitTest class invokes this method to register tests in this test case - // test cases right before running tests in RUN_ALL_TESTS macro. - // This method should not be called more then once on any single - // instance of a ParameterizedTestCaseInfoBase derived class. - // UnitTest has a guard to prevent from calling this method more then once. - virtual void RegisterTests() { - for (typename TestInfoContainer::iterator test_it = tests_.begin(); - test_it != tests_.end(); ++test_it) { - linked_ptr test_info = *test_it; - for (typename InstantiationContainer::iterator gen_it = - instantiations_.begin(); gen_it != instantiations_.end(); - ++gen_it) { - const string& instantiation_name = gen_it->first; - ParamGenerator generator((*gen_it->second)()); - - string test_case_name; - if ( !instantiation_name.empty() ) - test_case_name = instantiation_name + "/"; - test_case_name += test_info->test_case_base_name; - - int i = 0; - for (typename ParamGenerator::iterator param_it = - generator.begin(); - param_it != generator.end(); ++param_it, ++i) { - Message test_name_stream; - test_name_stream << test_info->test_base_name << "/" << i; - MakeAndRegisterTestInfo( - test_case_name.c_str(), - test_name_stream.GetString().c_str(), - NULL, // No type parameter. - PrintToString(*param_it).c_str(), - GetTestCaseTypeId(), - TestCase::SetUpTestCase, - TestCase::TearDownTestCase, - test_info->test_meta_factory->CreateTestFactory(*param_it)); - } // for param_it - } // for gen_it - } // for test_it - } // RegisterTests - - private: - // LocalTestInfo structure keeps information about a single test registered - // with TEST_P macro. - struct TestInfo { - TestInfo(const char* a_test_case_base_name, - const char* a_test_base_name, - TestMetaFactoryBase* a_test_meta_factory) : - test_case_base_name(a_test_case_base_name), - test_base_name(a_test_base_name), - test_meta_factory(a_test_meta_factory) {} - - const string test_case_base_name; - const string test_base_name; - const scoped_ptr > test_meta_factory; - }; - typedef ::std::vector > TestInfoContainer; - // Keeps pairs of - // received from INSTANTIATE_TEST_CASE_P macros. - typedef ::std::vector > - InstantiationContainer; - - const string test_case_name_; - TestInfoContainer tests_; - InstantiationContainer instantiations_; - - GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfo); -}; // class ParameterizedTestCaseInfo - -// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. -// -// ParameterizedTestCaseRegistry contains a map of ParameterizedTestCaseInfoBase -// classes accessed by test case names. TEST_P and INSTANTIATE_TEST_CASE_P -// macros use it to locate their corresponding ParameterizedTestCaseInfo -// descriptors. -class ParameterizedTestCaseRegistry { - public: - ParameterizedTestCaseRegistry() {} - ~ParameterizedTestCaseRegistry() { - for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); - it != test_case_infos_.end(); ++it) { - delete *it; - } - } - - // Looks up or creates and returns a structure containing information about - // tests and instantiations of a particular test case. - template - ParameterizedTestCaseInfo* GetTestCasePatternHolder( - const char* test_case_name, - const char* file, - int line) { - ParameterizedTestCaseInfo* typed_test_info = NULL; - for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); - it != test_case_infos_.end(); ++it) { - if ((*it)->GetTestCaseName() == test_case_name) { - if ((*it)->GetTestCaseTypeId() != GetTypeId()) { - // Complain about incorrect usage of Google Test facilities - // and terminate the program since we cannot guaranty correct - // test case setup and tear-down in this case. - ReportInvalidTestCaseType(test_case_name, file, line); - posix::Abort(); - } else { - // At this point we are sure that the object we found is of the same - // type we are looking for, so we downcast it to that type - // without further checks. - typed_test_info = CheckedDowncastToActualType< - ParameterizedTestCaseInfo >(*it); - } - break; - } - } - if (typed_test_info == NULL) { - typed_test_info = new ParameterizedTestCaseInfo(test_case_name); - test_case_infos_.push_back(typed_test_info); - } - return typed_test_info; - } - void RegisterTests() { - for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); - it != test_case_infos_.end(); ++it) { - (*it)->RegisterTests(); - } - } - - private: - typedef ::std::vector TestCaseInfoContainer; - - TestCaseInfoContainer test_case_infos_; - - GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseRegistry); -}; - -} // namespace internal -} // namespace testing - -#endif // GTEST_HAS_PARAM_TEST - -#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ -// This file was GENERATED by command: -// pump.py gtest-param-util-generated.h.pump -// DO NOT EDIT BY HAND!!! - -// Copyright 2008 Google Inc. -// All Rights Reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: vladl@google.com (Vlad Losev) - -// Type and function utilities for implementing parameterized tests. -// This file is generated by a SCRIPT. DO NOT EDIT BY HAND! -// -// Currently Google Test supports at most 50 arguments in Values, -// and at most 10 arguments in Combine. Please contact -// googletestframework@googlegroups.com if you need more. -// Please note that the number of arguments to Combine is limited -// by the maximum arity of the implementation of tr1::tuple which is -// currently set at 10. - -#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ -#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ - -// scripts/fuse_gtest.py depends on gtest's own header being #included -// *unconditionally*. Therefore these #includes cannot be moved -// inside #if GTEST_HAS_PARAM_TEST. - -#if GTEST_HAS_PARAM_TEST - -namespace testing { - -// Forward declarations of ValuesIn(), which is implemented in -// include/gtest/gtest-param-test.h. -template -internal::ParamGenerator< - typename ::testing::internal::IteratorTraits::value_type> -ValuesIn(ForwardIterator begin, ForwardIterator end); - -template -internal::ParamGenerator ValuesIn(const T (&array)[N]); - -template -internal::ParamGenerator ValuesIn( - const Container& container); - -namespace internal { - -// Used in the Values() function to provide polymorphic capabilities. -template -class ValueArray1 { - public: - explicit ValueArray1(T1 v1) : v1_(v1) {} - - template - operator ParamGenerator() const { return ValuesIn(&v1_, &v1_ + 1); } - - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray1& other); - - const T1 v1_; -}; - -template -class ValueArray2 { - public: - ValueArray2(T1 v1, T2 v2) : v1_(v1), v2_(v2) {} - - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_)}; - return ValuesIn(array); - } - - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray2& other); - - const T1 v1_; - const T2 v2_; -}; - -template -class ValueArray3 { - public: - ValueArray3(T1 v1, T2 v2, T3 v3) : v1_(v1), v2_(v2), v3_(v3) {} - - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_)}; - return ValuesIn(array); - } - - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray3& other); - - const T1 v1_; - const T2 v2_; - const T3 v3_; -}; - -template -class ValueArray4 { - public: - ValueArray4(T1 v1, T2 v2, T3 v3, T4 v4) : v1_(v1), v2_(v2), v3_(v3), - v4_(v4) {} - - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_)}; - return ValuesIn(array); - } - - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray4& other); - - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; -}; - -template -class ValueArray5 { - public: - ValueArray5(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) : v1_(v1), v2_(v2), v3_(v3), - v4_(v4), v5_(v5) {} - - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_)}; - return ValuesIn(array); - } - - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray5& other); - - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; -}; - -template -class ValueArray6 { - public: - ValueArray6(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6) : v1_(v1), v2_(v2), - v3_(v3), v4_(v4), v5_(v5), v6_(v6) {} - - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_)}; - return ValuesIn(array); - } - - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray6& other); - - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; -}; - -template -class ValueArray7 { - public: - ValueArray7(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7) : v1_(v1), - v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7) {} - - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_)}; - return ValuesIn(array); - } - - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray7& other); - - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; -}; - -template -class ValueArray8 { - public: - ValueArray8(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, - T8 v8) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), - v8_(v8) {} - - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_)}; - return ValuesIn(array); - } - - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray8& other); - - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; -}; - -template -class ValueArray9 { - public: - ValueArray9(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, - T9 v9) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), - v8_(v8), v9_(v9) {} - - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_)}; - return ValuesIn(array); - } - - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray9& other); - - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; -}; - -template -class ValueArray10 { - public: - ValueArray10(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), - v8_(v8), v9_(v9), v10_(v10) {} - - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_)}; - return ValuesIn(array); - } - - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray10& other); - - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; -}; - -template -class ValueArray11 { - public: - ValueArray11(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), - v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11) {} - - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_)}; - return ValuesIn(array); - } - - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray11& other); - - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; -}; - -template -class ValueArray12 { - public: - ValueArray12(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), - v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12) {} - - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_)}; - return ValuesIn(array); - } - - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray12& other); - - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; -}; - -template -class ValueArray13 { - public: - ValueArray13(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), - v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), - v12_(v12), v13_(v13) {} - - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_)}; - return ValuesIn(array); - } - - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray13& other); - - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; -}; - -template -class ValueArray14 { - public: - ValueArray14(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) : v1_(v1), v2_(v2), v3_(v3), - v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), - v11_(v11), v12_(v12), v13_(v13), v14_(v14) {} - - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_)}; - return ValuesIn(array); - } - - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray14& other); - - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; -}; - -template -class ValueArray15 { - public: - ValueArray15(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15) : v1_(v1), v2_(v2), - v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), - v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15) {} - - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_)}; - return ValuesIn(array); - } - - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray15& other); - - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; -}; - -template -class ValueArray16 { - public: - ValueArray16(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16) : v1_(v1), - v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), - v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), - v16_(v16) {} - - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_)}; - return ValuesIn(array); - } - - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray16& other); - - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; -}; - -template -class ValueArray17 { - public: - ValueArray17(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, - T17 v17) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), - v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), - v15_(v15), v16_(v16), v17_(v17) {} - - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_)}; - return ValuesIn(array); - } - - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray17& other); - - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; -}; - -template -class ValueArray18 { - public: - ValueArray18(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), - v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), - v15_(v15), v16_(v16), v17_(v17), v18_(v18) {} - - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_)}; - return ValuesIn(array); - } - - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray18& other); - - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; -}; - -template -class ValueArray19 { - public: - ValueArray19(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), - v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), - v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19) {} - - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_)}; - return ValuesIn(array); - } - - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray19& other); - - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; -}; - -template -class ValueArray20 { - public: - ValueArray20(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), - v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), - v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), - v19_(v19), v20_(v20) {} - - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_)}; - return ValuesIn(array); - } - - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray20& other); - - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; -}; - -template -class ValueArray21 { - public: - ValueArray21(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), - v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), - v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), - v18_(v18), v19_(v19), v20_(v20), v21_(v21) {} - - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_), - static_cast(v21_)}; - return ValuesIn(array); - } - - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray21& other); - - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; - const T21 v21_; -}; - -template -class ValueArray22 { - public: - ValueArray22(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22) : v1_(v1), v2_(v2), v3_(v3), - v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), - v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), - v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22) {} - - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_), - static_cast(v21_), static_cast(v22_)}; - return ValuesIn(array); - } - - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray22& other); - - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; - const T21 v21_; - const T22 v22_; -}; - -template -class ValueArray23 { - public: - ValueArray23(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23) : v1_(v1), v2_(v2), - v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), - v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), - v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), - v23_(v23) {} - - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_), - static_cast(v21_), static_cast(v22_), static_cast(v23_)}; - return ValuesIn(array); - } - - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray23& other); - - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; - const T21 v21_; - const T22 v22_; - const T23 v23_; -}; - -template -class ValueArray24 { - public: - ValueArray24(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24) : v1_(v1), - v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), - v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), - v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), - v22_(v22), v23_(v23), v24_(v24) {} - - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_), - static_cast(v21_), static_cast(v22_), static_cast(v23_), - static_cast(v24_)}; - return ValuesIn(array); - } - - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray24& other); - - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; - const T21 v21_; - const T22 v22_; - const T23 v23_; - const T24 v24_; -}; - -template -class ValueArray25 { - public: - ValueArray25(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, - T25 v25) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), - v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), - v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), - v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25) {} - - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_), - static_cast(v21_), static_cast(v22_), static_cast(v23_), - static_cast(v24_), static_cast(v25_)}; - return ValuesIn(array); - } - - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray25& other); - - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; - const T21 v21_; - const T22 v22_; - const T23 v23_; - const T24 v24_; - const T25 v25_; -}; - -template -class ValueArray26 { - public: - ValueArray26(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), - v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), - v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), - v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26) {} - - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_), - static_cast(v21_), static_cast(v22_), static_cast(v23_), - static_cast(v24_), static_cast(v25_), static_cast(v26_)}; - return ValuesIn(array); - } - - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray26& other); - - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; - const T21 v21_; - const T22 v22_; - const T23 v23_; - const T24 v24_; - const T25 v25_; - const T26 v26_; -}; - -template -class ValueArray27 { - public: - ValueArray27(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), - v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), - v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), - v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), - v26_(v26), v27_(v27) {} - - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_), - static_cast(v21_), static_cast(v22_), static_cast(v23_), - static_cast(v24_), static_cast(v25_), static_cast(v26_), - static_cast(v27_)}; - return ValuesIn(array); - } - - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray27& other); - - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; - const T21 v21_; - const T22 v22_; - const T23 v23_; - const T24 v24_; - const T25 v25_; - const T26 v26_; - const T27 v27_; -}; - -template -class ValueArray28 { - public: - ValueArray28(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27, T28 v28) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), - v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), - v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), - v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), - v25_(v25), v26_(v26), v27_(v27), v28_(v28) {} - - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_), - static_cast(v21_), static_cast(v22_), static_cast(v23_), - static_cast(v24_), static_cast(v25_), static_cast(v26_), - static_cast(v27_), static_cast(v28_)}; - return ValuesIn(array); - } - - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray28& other); - - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; - const T21 v21_; - const T22 v22_; - const T23 v23_; - const T24 v24_; - const T25 v25_; - const T26 v26_; - const T27 v27_; - const T28 v28_; -}; - -template -class ValueArray29 { - public: - ValueArray29(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27, T28 v28, T29 v29) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), - v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), - v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), - v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), - v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29) {} - - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_), - static_cast(v21_), static_cast(v22_), static_cast(v23_), - static_cast(v24_), static_cast(v25_), static_cast(v26_), - static_cast(v27_), static_cast(v28_), static_cast(v29_)}; - return ValuesIn(array); - } - - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray29& other); - - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; - const T21 v21_; - const T22 v22_; - const T23 v23_; - const T24 v24_; - const T25 v25_; - const T26 v26_; - const T27 v27_; - const T28 v28_; - const T29 v29_; -}; - -template -class ValueArray30 { - public: - ValueArray30(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27, T28 v28, T29 v29, T30 v30) : v1_(v1), v2_(v2), v3_(v3), - v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), - v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), - v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), - v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), - v29_(v29), v30_(v30) {} - - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_), - static_cast(v21_), static_cast(v22_), static_cast(v23_), - static_cast(v24_), static_cast(v25_), static_cast(v26_), - static_cast(v27_), static_cast(v28_), static_cast(v29_), - static_cast(v30_)}; - return ValuesIn(array); - } - - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray30& other); - - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; - const T21 v21_; - const T22 v22_; - const T23 v23_; - const T24 v24_; - const T25 v25_; - const T26 v26_; - const T27 v27_; - const T28 v28_; - const T29 v29_; - const T30 v30_; -}; - -template -class ValueArray31 { - public: - ValueArray31(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31) : v1_(v1), v2_(v2), - v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), - v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), - v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), - v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), - v29_(v29), v30_(v30), v31_(v31) {} - - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_), - static_cast(v21_), static_cast(v22_), static_cast(v23_), - static_cast(v24_), static_cast(v25_), static_cast(v26_), - static_cast(v27_), static_cast(v28_), static_cast(v29_), - static_cast(v30_), static_cast(v31_)}; - return ValuesIn(array); - } - - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray31& other); - - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; - const T21 v21_; - const T22 v22_; - const T23 v23_; - const T24 v24_; - const T25 v25_; - const T26 v26_; - const T27 v27_; - const T28 v28_; - const T29 v29_; - const T30 v30_; - const T31 v31_; -}; - -template -class ValueArray32 { - public: - ValueArray32(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32) : v1_(v1), - v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), - v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), - v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), - v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), - v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32) {} - - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_), - static_cast(v21_), static_cast(v22_), static_cast(v23_), - static_cast(v24_), static_cast(v25_), static_cast(v26_), - static_cast(v27_), static_cast(v28_), static_cast(v29_), - static_cast(v30_), static_cast(v31_), static_cast(v32_)}; - return ValuesIn(array); - } - - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray32& other); - - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; - const T21 v21_; - const T22 v22_; - const T23 v23_; - const T24 v24_; - const T25 v25_; - const T26 v26_; - const T27 v27_; - const T28 v28_; - const T29 v29_; - const T30 v30_; - const T31 v31_; - const T32 v32_; -}; - -template -class ValueArray33 { - public: - ValueArray33(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, - T33 v33) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), - v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), - v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), - v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), - v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), - v33_(v33) {} - - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_), - static_cast(v21_), static_cast(v22_), static_cast(v23_), - static_cast(v24_), static_cast(v25_), static_cast(v26_), - static_cast(v27_), static_cast(v28_), static_cast(v29_), - static_cast(v30_), static_cast(v31_), static_cast(v32_), - static_cast(v33_)}; - return ValuesIn(array); - } - - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray33& other); - - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; - const T21 v21_; - const T22 v22_; - const T23 v23_; - const T24 v24_; - const T25 v25_; - const T26 v26_; - const T27 v27_; - const T28 v28_; - const T29 v29_; - const T30 v30_; - const T31 v31_; - const T32 v32_; - const T33 v33_; -}; - -template -class ValueArray34 { - public: - ValueArray34(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, - T34 v34) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), - v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), - v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), - v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), - v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), - v33_(v33), v34_(v34) {} - - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_), - static_cast(v21_), static_cast(v22_), static_cast(v23_), - static_cast(v24_), static_cast(v25_), static_cast(v26_), - static_cast(v27_), static_cast(v28_), static_cast(v29_), - static_cast(v30_), static_cast(v31_), static_cast(v32_), - static_cast(v33_), static_cast(v34_)}; - return ValuesIn(array); - } - - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray34& other); - - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; - const T21 v21_; - const T22 v22_; - const T23 v23_; - const T24 v24_; - const T25 v25_; - const T26 v26_; - const T27 v27_; - const T28 v28_; - const T29 v29_; - const T30 v30_; - const T31 v31_; - const T32 v32_; - const T33 v33_; - const T34 v34_; -}; - -template -class ValueArray35 { - public: - ValueArray35(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, - T34 v34, T35 v35) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), - v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), - v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), - v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), - v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), - v32_(v32), v33_(v33), v34_(v34), v35_(v35) {} - - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_), - static_cast(v21_), static_cast(v22_), static_cast(v23_), - static_cast(v24_), static_cast(v25_), static_cast(v26_), - static_cast(v27_), static_cast(v28_), static_cast(v29_), - static_cast(v30_), static_cast(v31_), static_cast(v32_), - static_cast(v33_), static_cast(v34_), static_cast(v35_)}; - return ValuesIn(array); - } - - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray35& other); - - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; - const T21 v21_; - const T22 v22_; - const T23 v23_; - const T24 v24_; - const T25 v25_; - const T26 v26_; - const T27 v27_; - const T28 v28_; - const T29 v29_; - const T30 v30_; - const T31 v31_; - const T32 v32_; - const T33 v33_; - const T34 v34_; - const T35 v35_; -}; - -template -class ValueArray36 { - public: - ValueArray36(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, - T34 v34, T35 v35, T36 v36) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), - v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), - v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), - v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), - v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), - v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36) {} - - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_), - static_cast(v21_), static_cast(v22_), static_cast(v23_), - static_cast(v24_), static_cast(v25_), static_cast(v26_), - static_cast(v27_), static_cast(v28_), static_cast(v29_), - static_cast(v30_), static_cast(v31_), static_cast(v32_), - static_cast(v33_), static_cast(v34_), static_cast(v35_), - static_cast(v36_)}; - return ValuesIn(array); - } - - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray36& other); - - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; - const T21 v21_; - const T22 v22_; - const T23 v23_; - const T24 v24_; - const T25 v25_; - const T26 v26_; - const T27 v27_; - const T28 v28_; - const T29 v29_; - const T30 v30_; - const T31 v31_; - const T32 v32_; - const T33 v33_; - const T34 v34_; - const T35 v35_; - const T36 v36_; -}; - -template -class ValueArray37 { - public: - ValueArray37(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, - T34 v34, T35 v35, T36 v36, T37 v37) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), - v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), - v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), - v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), - v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), - v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), - v36_(v36), v37_(v37) {} - - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_), - static_cast(v21_), static_cast(v22_), static_cast(v23_), - static_cast(v24_), static_cast(v25_), static_cast(v26_), - static_cast(v27_), static_cast(v28_), static_cast(v29_), - static_cast(v30_), static_cast(v31_), static_cast(v32_), - static_cast(v33_), static_cast(v34_), static_cast(v35_), - static_cast(v36_), static_cast(v37_)}; - return ValuesIn(array); - } - - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray37& other); - - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; - const T21 v21_; - const T22 v22_; - const T23 v23_; - const T24 v24_; - const T25 v25_; - const T26 v26_; - const T27 v27_; - const T28 v28_; - const T29 v29_; - const T30 v30_; - const T31 v31_; - const T32 v32_; - const T33 v33_; - const T34 v34_; - const T35 v35_; - const T36 v36_; - const T37 v37_; -}; - -template -class ValueArray38 { - public: - ValueArray38(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, - T34 v34, T35 v35, T36 v36, T37 v37, T38 v38) : v1_(v1), v2_(v2), v3_(v3), - v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), - v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), - v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), - v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), - v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), - v35_(v35), v36_(v36), v37_(v37), v38_(v38) {} - - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_), - static_cast(v21_), static_cast(v22_), static_cast(v23_), - static_cast(v24_), static_cast(v25_), static_cast(v26_), - static_cast(v27_), static_cast(v28_), static_cast(v29_), - static_cast(v30_), static_cast(v31_), static_cast(v32_), - static_cast(v33_), static_cast(v34_), static_cast(v35_), - static_cast(v36_), static_cast(v37_), static_cast(v38_)}; - return ValuesIn(array); - } - - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray38& other); - - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; - const T21 v21_; - const T22 v22_; - const T23 v23_; - const T24 v24_; - const T25 v25_; - const T26 v26_; - const T27 v27_; - const T28 v28_; - const T29 v29_; - const T30 v30_; - const T31 v31_; - const T32 v32_; - const T33 v33_; - const T34 v34_; - const T35 v35_; - const T36 v36_; - const T37 v37_; - const T38 v38_; -}; - -template -class ValueArray39 { - public: - ValueArray39(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, - T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39) : v1_(v1), v2_(v2), - v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), - v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), - v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), - v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), - v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), - v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39) {} - - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_), - static_cast(v21_), static_cast(v22_), static_cast(v23_), - static_cast(v24_), static_cast(v25_), static_cast(v26_), - static_cast(v27_), static_cast(v28_), static_cast(v29_), - static_cast(v30_), static_cast(v31_), static_cast(v32_), - static_cast(v33_), static_cast(v34_), static_cast(v35_), - static_cast(v36_), static_cast(v37_), static_cast(v38_), - static_cast(v39_)}; - return ValuesIn(array); - } - - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray39& other); - - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; - const T21 v21_; - const T22 v22_; - const T23 v23_; - const T24 v24_; - const T25 v25_; - const T26 v26_; - const T27 v27_; - const T28 v28_; - const T29 v29_; - const T30 v30_; - const T31 v31_; - const T32 v32_; - const T33 v33_; - const T34 v34_; - const T35 v35_; - const T36 v36_; - const T37 v37_; - const T38 v38_; - const T39 v39_; -}; - -template -class ValueArray40 { - public: - ValueArray40(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, - T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40) : v1_(v1), - v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), - v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), - v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), - v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), - v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), - v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), - v40_(v40) {} - - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_), - static_cast(v21_), static_cast(v22_), static_cast(v23_), - static_cast(v24_), static_cast(v25_), static_cast(v26_), - static_cast(v27_), static_cast(v28_), static_cast(v29_), - static_cast(v30_), static_cast(v31_), static_cast(v32_), - static_cast(v33_), static_cast(v34_), static_cast(v35_), - static_cast(v36_), static_cast(v37_), static_cast(v38_), - static_cast(v39_), static_cast(v40_)}; - return ValuesIn(array); - } - - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray40& other); - - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; - const T21 v21_; - const T22 v22_; - const T23 v23_; - const T24 v24_; - const T25 v25_; - const T26 v26_; - const T27 v27_; - const T28 v28_; - const T29 v29_; - const T30 v30_; - const T31 v31_; - const T32 v32_; - const T33 v33_; - const T34 v34_; - const T35 v35_; - const T36 v36_; - const T37 v37_; - const T38 v38_; - const T39 v39_; - const T40 v40_; -}; - -template -class ValueArray41 { - public: - ValueArray41(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, - T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, - T41 v41) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), - v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), - v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), - v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), - v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), - v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), - v39_(v39), v40_(v40), v41_(v41) {} - - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_), - static_cast(v21_), static_cast(v22_), static_cast(v23_), - static_cast(v24_), static_cast(v25_), static_cast(v26_), - static_cast(v27_), static_cast(v28_), static_cast(v29_), - static_cast(v30_), static_cast(v31_), static_cast(v32_), - static_cast(v33_), static_cast(v34_), static_cast(v35_), - static_cast(v36_), static_cast(v37_), static_cast(v38_), - static_cast(v39_), static_cast(v40_), static_cast(v41_)}; - return ValuesIn(array); - } - - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray41& other); - - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; - const T21 v21_; - const T22 v22_; - const T23 v23_; - const T24 v24_; - const T25 v25_; - const T26 v26_; - const T27 v27_; - const T28 v28_; - const T29 v29_; - const T30 v30_; - const T31 v31_; - const T32 v32_; - const T33 v33_; - const T34 v34_; - const T35 v35_; - const T36 v36_; - const T37 v37_; - const T38 v38_; - const T39 v39_; - const T40 v40_; - const T41 v41_; -}; - -template -class ValueArray42 { - public: - ValueArray42(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, - T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, - T42 v42) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), - v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), - v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), - v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), - v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), - v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), - v39_(v39), v40_(v40), v41_(v41), v42_(v42) {} - - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_), - static_cast(v21_), static_cast(v22_), static_cast(v23_), - static_cast(v24_), static_cast(v25_), static_cast(v26_), - static_cast(v27_), static_cast(v28_), static_cast(v29_), - static_cast(v30_), static_cast(v31_), static_cast(v32_), - static_cast(v33_), static_cast(v34_), static_cast(v35_), - static_cast(v36_), static_cast(v37_), static_cast(v38_), - static_cast(v39_), static_cast(v40_), static_cast(v41_), - static_cast(v42_)}; - return ValuesIn(array); - } - - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray42& other); - - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; - const T21 v21_; - const T22 v22_; - const T23 v23_; - const T24 v24_; - const T25 v25_; - const T26 v26_; - const T27 v27_; - const T28 v28_; - const T29 v29_; - const T30 v30_; - const T31 v31_; - const T32 v32_; - const T33 v33_; - const T34 v34_; - const T35 v35_; - const T36 v36_; - const T37 v37_; - const T38 v38_; - const T39 v39_; - const T40 v40_; - const T41 v41_; - const T42 v42_; -}; - -template -class ValueArray43 { - public: - ValueArray43(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, - T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, - T42 v42, T43 v43) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), - v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), - v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), - v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), - v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), - v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), - v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43) {} - - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_), - static_cast(v21_), static_cast(v22_), static_cast(v23_), - static_cast(v24_), static_cast(v25_), static_cast(v26_), - static_cast(v27_), static_cast(v28_), static_cast(v29_), - static_cast(v30_), static_cast(v31_), static_cast(v32_), - static_cast(v33_), static_cast(v34_), static_cast(v35_), - static_cast(v36_), static_cast(v37_), static_cast(v38_), - static_cast(v39_), static_cast(v40_), static_cast(v41_), - static_cast(v42_), static_cast(v43_)}; - return ValuesIn(array); - } - - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray43& other); - - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; - const T21 v21_; - const T22 v22_; - const T23 v23_; - const T24 v24_; - const T25 v25_; - const T26 v26_; - const T27 v27_; - const T28 v28_; - const T29 v29_; - const T30 v30_; - const T31 v31_; - const T32 v32_; - const T33 v33_; - const T34 v34_; - const T35 v35_; - const T36 v36_; - const T37 v37_; - const T38 v38_; - const T39 v39_; - const T40 v40_; - const T41 v41_; - const T42 v42_; - const T43 v43_; -}; - -template -class ValueArray44 { - public: - ValueArray44(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, - T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, - T42 v42, T43 v43, T44 v44) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), - v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), - v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), - v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), - v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), - v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), - v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), - v43_(v43), v44_(v44) {} - - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_), - static_cast(v21_), static_cast(v22_), static_cast(v23_), - static_cast(v24_), static_cast(v25_), static_cast(v26_), - static_cast(v27_), static_cast(v28_), static_cast(v29_), - static_cast(v30_), static_cast(v31_), static_cast(v32_), - static_cast(v33_), static_cast(v34_), static_cast(v35_), - static_cast(v36_), static_cast(v37_), static_cast(v38_), - static_cast(v39_), static_cast(v40_), static_cast(v41_), - static_cast(v42_), static_cast(v43_), static_cast(v44_)}; - return ValuesIn(array); - } - - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray44& other); - - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; - const T21 v21_; - const T22 v22_; - const T23 v23_; - const T24 v24_; - const T25 v25_; - const T26 v26_; - const T27 v27_; - const T28 v28_; - const T29 v29_; - const T30 v30_; - const T31 v31_; - const T32 v32_; - const T33 v33_; - const T34 v34_; - const T35 v35_; - const T36 v36_; - const T37 v37_; - const T38 v38_; - const T39 v39_; - const T40 v40_; - const T41 v41_; - const T42 v42_; - const T43 v43_; - const T44 v44_; -}; - -template -class ValueArray45 { - public: - ValueArray45(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, - T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, - T42 v42, T43 v43, T44 v44, T45 v45) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), - v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), - v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), - v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), - v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), - v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), - v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), - v42_(v42), v43_(v43), v44_(v44), v45_(v45) {} - - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_), - static_cast(v21_), static_cast(v22_), static_cast(v23_), - static_cast(v24_), static_cast(v25_), static_cast(v26_), - static_cast(v27_), static_cast(v28_), static_cast(v29_), - static_cast(v30_), static_cast(v31_), static_cast(v32_), - static_cast(v33_), static_cast(v34_), static_cast(v35_), - static_cast(v36_), static_cast(v37_), static_cast(v38_), - static_cast(v39_), static_cast(v40_), static_cast(v41_), - static_cast(v42_), static_cast(v43_), static_cast(v44_), - static_cast(v45_)}; - return ValuesIn(array); - } - - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray45& other); - - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; - const T21 v21_; - const T22 v22_; - const T23 v23_; - const T24 v24_; - const T25 v25_; - const T26 v26_; - const T27 v27_; - const T28 v28_; - const T29 v29_; - const T30 v30_; - const T31 v31_; - const T32 v32_; - const T33 v33_; - const T34 v34_; - const T35 v35_; - const T36 v36_; - const T37 v37_; - const T38 v38_; - const T39 v39_; - const T40 v40_; - const T41 v41_; - const T42 v42_; - const T43 v43_; - const T44 v44_; - const T45 v45_; -}; - -template -class ValueArray46 { - public: - ValueArray46(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, - T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, - T42 v42, T43 v43, T44 v44, T45 v45, T46 v46) : v1_(v1), v2_(v2), v3_(v3), - v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), - v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), - v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), - v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), - v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), - v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), - v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46) {} - - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_), - static_cast(v21_), static_cast(v22_), static_cast(v23_), - static_cast(v24_), static_cast(v25_), static_cast(v26_), - static_cast(v27_), static_cast(v28_), static_cast(v29_), - static_cast(v30_), static_cast(v31_), static_cast(v32_), - static_cast(v33_), static_cast(v34_), static_cast(v35_), - static_cast(v36_), static_cast(v37_), static_cast(v38_), - static_cast(v39_), static_cast(v40_), static_cast(v41_), - static_cast(v42_), static_cast(v43_), static_cast(v44_), - static_cast(v45_), static_cast(v46_)}; - return ValuesIn(array); - } - - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray46& other); - - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; - const T21 v21_; - const T22 v22_; - const T23 v23_; - const T24 v24_; - const T25 v25_; - const T26 v26_; - const T27 v27_; - const T28 v28_; - const T29 v29_; - const T30 v30_; - const T31 v31_; - const T32 v32_; - const T33 v33_; - const T34 v34_; - const T35 v35_; - const T36 v36_; - const T37 v37_; - const T38 v38_; - const T39 v39_; - const T40 v40_; - const T41 v41_; - const T42 v42_; - const T43 v43_; - const T44 v44_; - const T45 v45_; - const T46 v46_; -}; - -template -class ValueArray47 { - public: - ValueArray47(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, - T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, - T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47) : v1_(v1), v2_(v2), - v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), - v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), - v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), - v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), - v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), - v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), - v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46), - v47_(v47) {} - - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_), - static_cast(v21_), static_cast(v22_), static_cast(v23_), - static_cast(v24_), static_cast(v25_), static_cast(v26_), - static_cast(v27_), static_cast(v28_), static_cast(v29_), - static_cast(v30_), static_cast(v31_), static_cast(v32_), - static_cast(v33_), static_cast(v34_), static_cast(v35_), - static_cast(v36_), static_cast(v37_), static_cast(v38_), - static_cast(v39_), static_cast(v40_), static_cast(v41_), - static_cast(v42_), static_cast(v43_), static_cast(v44_), - static_cast(v45_), static_cast(v46_), static_cast(v47_)}; - return ValuesIn(array); - } - - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray47& other); - - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; - const T21 v21_; - const T22 v22_; - const T23 v23_; - const T24 v24_; - const T25 v25_; - const T26 v26_; - const T27 v27_; - const T28 v28_; - const T29 v29_; - const T30 v30_; - const T31 v31_; - const T32 v32_; - const T33 v33_; - const T34 v34_; - const T35 v35_; - const T36 v36_; - const T37 v37_; - const T38 v38_; - const T39 v39_; - const T40 v40_; - const T41 v41_; - const T42 v42_; - const T43 v43_; - const T44 v44_; - const T45 v45_; - const T46 v46_; - const T47 v47_; -}; - -template -class ValueArray48 { - public: - ValueArray48(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, - T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, - T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48) : v1_(v1), - v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), - v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), - v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), - v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), - v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), - v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), - v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), - v46_(v46), v47_(v47), v48_(v48) {} - - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_), - static_cast(v21_), static_cast(v22_), static_cast(v23_), - static_cast(v24_), static_cast(v25_), static_cast(v26_), - static_cast(v27_), static_cast(v28_), static_cast(v29_), - static_cast(v30_), static_cast(v31_), static_cast(v32_), - static_cast(v33_), static_cast(v34_), static_cast(v35_), - static_cast(v36_), static_cast(v37_), static_cast(v38_), - static_cast(v39_), static_cast(v40_), static_cast(v41_), - static_cast(v42_), static_cast(v43_), static_cast(v44_), - static_cast(v45_), static_cast(v46_), static_cast(v47_), - static_cast(v48_)}; - return ValuesIn(array); - } - - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray48& other); - - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; - const T21 v21_; - const T22 v22_; - const T23 v23_; - const T24 v24_; - const T25 v25_; - const T26 v26_; - const T27 v27_; - const T28 v28_; - const T29 v29_; - const T30 v30_; - const T31 v31_; - const T32 v32_; - const T33 v33_; - const T34 v34_; - const T35 v35_; - const T36 v36_; - const T37 v37_; - const T38 v38_; - const T39 v39_; - const T40 v40_; - const T41 v41_; - const T42 v42_; - const T43 v43_; - const T44 v44_; - const T45 v45_; - const T46 v46_; - const T47 v47_; - const T48 v48_; -}; - -template -class ValueArray49 { - public: - ValueArray49(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, - T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, - T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48, - T49 v49) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), - v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), - v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), - v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), - v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), - v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), - v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), - v45_(v45), v46_(v46), v47_(v47), v48_(v48), v49_(v49) {} - - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_), - static_cast(v21_), static_cast(v22_), static_cast(v23_), - static_cast(v24_), static_cast(v25_), static_cast(v26_), - static_cast(v27_), static_cast(v28_), static_cast(v29_), - static_cast(v30_), static_cast(v31_), static_cast(v32_), - static_cast(v33_), static_cast(v34_), static_cast(v35_), - static_cast(v36_), static_cast(v37_), static_cast(v38_), - static_cast(v39_), static_cast(v40_), static_cast(v41_), - static_cast(v42_), static_cast(v43_), static_cast(v44_), - static_cast(v45_), static_cast(v46_), static_cast(v47_), - static_cast(v48_), static_cast(v49_)}; - return ValuesIn(array); - } - - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray49& other); - - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; - const T21 v21_; - const T22 v22_; - const T23 v23_; - const T24 v24_; - const T25 v25_; - const T26 v26_; - const T27 v27_; - const T28 v28_; - const T29 v29_; - const T30 v30_; - const T31 v31_; - const T32 v32_; - const T33 v33_; - const T34 v34_; - const T35 v35_; - const T36 v36_; - const T37 v37_; - const T38 v38_; - const T39 v39_; - const T40 v40_; - const T41 v41_; - const T42 v42_; - const T43 v43_; - const T44 v44_; - const T45 v45_; - const T46 v46_; - const T47 v47_; - const T48 v48_; - const T49 v49_; -}; - -template -class ValueArray50 { - public: - ValueArray50(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, - T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, - T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48, T49 v49, - T50 v50) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), - v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), - v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), - v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), - v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), - v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), - v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), - v45_(v45), v46_(v46), v47_(v47), v48_(v48), v49_(v49), v50_(v50) {} - - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_), - static_cast(v21_), static_cast(v22_), static_cast(v23_), - static_cast(v24_), static_cast(v25_), static_cast(v26_), - static_cast(v27_), static_cast(v28_), static_cast(v29_), - static_cast(v30_), static_cast(v31_), static_cast(v32_), - static_cast(v33_), static_cast(v34_), static_cast(v35_), - static_cast(v36_), static_cast(v37_), static_cast(v38_), - static_cast(v39_), static_cast(v40_), static_cast(v41_), - static_cast(v42_), static_cast(v43_), static_cast(v44_), - static_cast(v45_), static_cast(v46_), static_cast(v47_), - static_cast(v48_), static_cast(v49_), static_cast(v50_)}; - return ValuesIn(array); - } - - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray50& other); - - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; - const T21 v21_; - const T22 v22_; - const T23 v23_; - const T24 v24_; - const T25 v25_; - const T26 v26_; - const T27 v27_; - const T28 v28_; - const T29 v29_; - const T30 v30_; - const T31 v31_; - const T32 v32_; - const T33 v33_; - const T34 v34_; - const T35 v35_; - const T36 v36_; - const T37 v37_; - const T38 v38_; - const T39 v39_; - const T40 v40_; - const T41 v41_; - const T42 v42_; - const T43 v43_; - const T44 v44_; - const T45 v45_; - const T46 v46_; - const T47 v47_; - const T48 v48_; - const T49 v49_; - const T50 v50_; -}; - -# if GTEST_HAS_COMBINE -// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. -// -// Generates values from the Cartesian product of values produced -// by the argument generators. -// -template -class CartesianProductGenerator2 - : public ParamGeneratorInterface< ::std::tr1::tuple > { - public: - typedef ::std::tr1::tuple ParamType; - - CartesianProductGenerator2(const ParamGenerator& g1, - const ParamGenerator& g2) - : g1_(g1), g2_(g2) {} - virtual ~CartesianProductGenerator2() {} - - virtual ParamIteratorInterface* Begin() const { - return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin()); - } - virtual ParamIteratorInterface* End() const { - return new Iterator(this, g1_, g1_.end(), g2_, g2_.end()); - } - - private: - class Iterator : public ParamIteratorInterface { - public: - Iterator(const ParamGeneratorInterface* base, - const ParamGenerator& g1, - const typename ParamGenerator::iterator& current1, - const ParamGenerator& g2, - const typename ParamGenerator::iterator& current2) - : base_(base), - begin1_(g1.begin()), end1_(g1.end()), current1_(current1), - begin2_(g2.begin()), end2_(g2.end()), current2_(current2) { - ComputeCurrentValue(); - } - virtual ~Iterator() {} - - virtual const ParamGeneratorInterface* BaseGenerator() const { - return base_; - } - // Advance should not be called on beyond-of-range iterators - // so no component iterators must be beyond end of range, either. - virtual void Advance() { - assert(!AtEnd()); - ++current2_; - if (current2_ == end2_) { - current2_ = begin2_; - ++current1_; - } - ComputeCurrentValue(); - } - virtual ParamIteratorInterface* Clone() const { - return new Iterator(*this); - } - virtual const ParamType* Current() const { return ¤t_value_; } - virtual bool Equals(const ParamIteratorInterface& other) const { - // Having the same base generator guarantees that the other - // iterator is of the same type and we can downcast. - GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) - << "The program attempted to compare iterators " - << "from different generators." << std::endl; - const Iterator* typed_other = - CheckedDowncastToActualType(&other); - // We must report iterators equal if they both point beyond their - // respective ranges. That can happen in a variety of fashions, - // so we have to consult AtEnd(). - return (AtEnd() && typed_other->AtEnd()) || - ( - current1_ == typed_other->current1_ && - current2_ == typed_other->current2_); - } - - private: - Iterator(const Iterator& other) - : base_(other.base_), - begin1_(other.begin1_), - end1_(other.end1_), - current1_(other.current1_), - begin2_(other.begin2_), - end2_(other.end2_), - current2_(other.current2_) { - ComputeCurrentValue(); - } - - void ComputeCurrentValue() { - if (!AtEnd()) - current_value_ = ParamType(*current1_, *current2_); - } - bool AtEnd() const { - // We must report iterator past the end of the range when either of the - // component iterators has reached the end of its range. - return - current1_ == end1_ || - current2_ == end2_; - } - - // No implementation - assignment is unsupported. - void operator=(const Iterator& other); - - const ParamGeneratorInterface* const base_; - // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. - // current[i]_ is the actual traversing iterator. - const typename ParamGenerator::iterator begin1_; - const typename ParamGenerator::iterator end1_; - typename ParamGenerator::iterator current1_; - const typename ParamGenerator::iterator begin2_; - const typename ParamGenerator::iterator end2_; - typename ParamGenerator::iterator current2_; - ParamType current_value_; - }; // class CartesianProductGenerator2::Iterator - - // No implementation - assignment is unsupported. - void operator=(const CartesianProductGenerator2& other); - - const ParamGenerator g1_; - const ParamGenerator g2_; -}; // class CartesianProductGenerator2 - - -template -class CartesianProductGenerator3 - : public ParamGeneratorInterface< ::std::tr1::tuple > { - public: - typedef ::std::tr1::tuple ParamType; - - CartesianProductGenerator3(const ParamGenerator& g1, - const ParamGenerator& g2, const ParamGenerator& g3) - : g1_(g1), g2_(g2), g3_(g3) {} - virtual ~CartesianProductGenerator3() {} - - virtual ParamIteratorInterface* Begin() const { - return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, - g3_.begin()); - } - virtual ParamIteratorInterface* End() const { - return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end()); - } - - private: - class Iterator : public ParamIteratorInterface { - public: - Iterator(const ParamGeneratorInterface* base, - const ParamGenerator& g1, - const typename ParamGenerator::iterator& current1, - const ParamGenerator& g2, - const typename ParamGenerator::iterator& current2, - const ParamGenerator& g3, - const typename ParamGenerator::iterator& current3) - : base_(base), - begin1_(g1.begin()), end1_(g1.end()), current1_(current1), - begin2_(g2.begin()), end2_(g2.end()), current2_(current2), - begin3_(g3.begin()), end3_(g3.end()), current3_(current3) { - ComputeCurrentValue(); - } - virtual ~Iterator() {} - - virtual const ParamGeneratorInterface* BaseGenerator() const { - return base_; - } - // Advance should not be called on beyond-of-range iterators - // so no component iterators must be beyond end of range, either. - virtual void Advance() { - assert(!AtEnd()); - ++current3_; - if (current3_ == end3_) { - current3_ = begin3_; - ++current2_; - } - if (current2_ == end2_) { - current2_ = begin2_; - ++current1_; - } - ComputeCurrentValue(); - } - virtual ParamIteratorInterface* Clone() const { - return new Iterator(*this); - } - virtual const ParamType* Current() const { return ¤t_value_; } - virtual bool Equals(const ParamIteratorInterface& other) const { - // Having the same base generator guarantees that the other - // iterator is of the same type and we can downcast. - GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) - << "The program attempted to compare iterators " - << "from different generators." << std::endl; - const Iterator* typed_other = - CheckedDowncastToActualType(&other); - // We must report iterators equal if they both point beyond their - // respective ranges. That can happen in a variety of fashions, - // so we have to consult AtEnd(). - return (AtEnd() && typed_other->AtEnd()) || - ( - current1_ == typed_other->current1_ && - current2_ == typed_other->current2_ && - current3_ == typed_other->current3_); - } - - private: - Iterator(const Iterator& other) - : base_(other.base_), - begin1_(other.begin1_), - end1_(other.end1_), - current1_(other.current1_), - begin2_(other.begin2_), - end2_(other.end2_), - current2_(other.current2_), - begin3_(other.begin3_), - end3_(other.end3_), - current3_(other.current3_) { - ComputeCurrentValue(); - } - - void ComputeCurrentValue() { - if (!AtEnd()) - current_value_ = ParamType(*current1_, *current2_, *current3_); - } - bool AtEnd() const { - // We must report iterator past the end of the range when either of the - // component iterators has reached the end of its range. - return - current1_ == end1_ || - current2_ == end2_ || - current3_ == end3_; - } - - // No implementation - assignment is unsupported. - void operator=(const Iterator& other); - - const ParamGeneratorInterface* const base_; - // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. - // current[i]_ is the actual traversing iterator. - const typename ParamGenerator::iterator begin1_; - const typename ParamGenerator::iterator end1_; - typename ParamGenerator::iterator current1_; - const typename ParamGenerator::iterator begin2_; - const typename ParamGenerator::iterator end2_; - typename ParamGenerator::iterator current2_; - const typename ParamGenerator::iterator begin3_; - const typename ParamGenerator::iterator end3_; - typename ParamGenerator::iterator current3_; - ParamType current_value_; - }; // class CartesianProductGenerator3::Iterator - - // No implementation - assignment is unsupported. - void operator=(const CartesianProductGenerator3& other); - - const ParamGenerator g1_; - const ParamGenerator g2_; - const ParamGenerator g3_; -}; // class CartesianProductGenerator3 - - -template -class CartesianProductGenerator4 - : public ParamGeneratorInterface< ::std::tr1::tuple > { - public: - typedef ::std::tr1::tuple ParamType; - - CartesianProductGenerator4(const ParamGenerator& g1, - const ParamGenerator& g2, const ParamGenerator& g3, - const ParamGenerator& g4) - : g1_(g1), g2_(g2), g3_(g3), g4_(g4) {} - virtual ~CartesianProductGenerator4() {} - - virtual ParamIteratorInterface* Begin() const { - return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, - g3_.begin(), g4_, g4_.begin()); - } - virtual ParamIteratorInterface* End() const { - return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), - g4_, g4_.end()); - } - - private: - class Iterator : public ParamIteratorInterface { - public: - Iterator(const ParamGeneratorInterface* base, - const ParamGenerator& g1, - const typename ParamGenerator::iterator& current1, - const ParamGenerator& g2, - const typename ParamGenerator::iterator& current2, - const ParamGenerator& g3, - const typename ParamGenerator::iterator& current3, - const ParamGenerator& g4, - const typename ParamGenerator::iterator& current4) - : base_(base), - begin1_(g1.begin()), end1_(g1.end()), current1_(current1), - begin2_(g2.begin()), end2_(g2.end()), current2_(current2), - begin3_(g3.begin()), end3_(g3.end()), current3_(current3), - begin4_(g4.begin()), end4_(g4.end()), current4_(current4) { - ComputeCurrentValue(); - } - virtual ~Iterator() {} - - virtual const ParamGeneratorInterface* BaseGenerator() const { - return base_; - } - // Advance should not be called on beyond-of-range iterators - // so no component iterators must be beyond end of range, either. - virtual void Advance() { - assert(!AtEnd()); - ++current4_; - if (current4_ == end4_) { - current4_ = begin4_; - ++current3_; - } - if (current3_ == end3_) { - current3_ = begin3_; - ++current2_; - } - if (current2_ == end2_) { - current2_ = begin2_; - ++current1_; - } - ComputeCurrentValue(); - } - virtual ParamIteratorInterface* Clone() const { - return new Iterator(*this); - } - virtual const ParamType* Current() const { return ¤t_value_; } - virtual bool Equals(const ParamIteratorInterface& other) const { - // Having the same base generator guarantees that the other - // iterator is of the same type and we can downcast. - GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) - << "The program attempted to compare iterators " - << "from different generators." << std::endl; - const Iterator* typed_other = - CheckedDowncastToActualType(&other); - // We must report iterators equal if they both point beyond their - // respective ranges. That can happen in a variety of fashions, - // so we have to consult AtEnd(). - return (AtEnd() && typed_other->AtEnd()) || - ( - current1_ == typed_other->current1_ && - current2_ == typed_other->current2_ && - current3_ == typed_other->current3_ && - current4_ == typed_other->current4_); - } - - private: - Iterator(const Iterator& other) - : base_(other.base_), - begin1_(other.begin1_), - end1_(other.end1_), - current1_(other.current1_), - begin2_(other.begin2_), - end2_(other.end2_), - current2_(other.current2_), - begin3_(other.begin3_), - end3_(other.end3_), - current3_(other.current3_), - begin4_(other.begin4_), - end4_(other.end4_), - current4_(other.current4_) { - ComputeCurrentValue(); - } - - void ComputeCurrentValue() { - if (!AtEnd()) - current_value_ = ParamType(*current1_, *current2_, *current3_, - *current4_); - } - bool AtEnd() const { - // We must report iterator past the end of the range when either of the - // component iterators has reached the end of its range. - return - current1_ == end1_ || - current2_ == end2_ || - current3_ == end3_ || - current4_ == end4_; - } - - // No implementation - assignment is unsupported. - void operator=(const Iterator& other); - - const ParamGeneratorInterface* const base_; - // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. - // current[i]_ is the actual traversing iterator. - const typename ParamGenerator::iterator begin1_; - const typename ParamGenerator::iterator end1_; - typename ParamGenerator::iterator current1_; - const typename ParamGenerator::iterator begin2_; - const typename ParamGenerator::iterator end2_; - typename ParamGenerator::iterator current2_; - const typename ParamGenerator::iterator begin3_; - const typename ParamGenerator::iterator end3_; - typename ParamGenerator::iterator current3_; - const typename ParamGenerator::iterator begin4_; - const typename ParamGenerator::iterator end4_; - typename ParamGenerator::iterator current4_; - ParamType current_value_; - }; // class CartesianProductGenerator4::Iterator - - // No implementation - assignment is unsupported. - void operator=(const CartesianProductGenerator4& other); - - const ParamGenerator g1_; - const ParamGenerator g2_; - const ParamGenerator g3_; - const ParamGenerator g4_; -}; // class CartesianProductGenerator4 - - -template -class CartesianProductGenerator5 - : public ParamGeneratorInterface< ::std::tr1::tuple > { - public: - typedef ::std::tr1::tuple ParamType; - - CartesianProductGenerator5(const ParamGenerator& g1, - const ParamGenerator& g2, const ParamGenerator& g3, - const ParamGenerator& g4, const ParamGenerator& g5) - : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5) {} - virtual ~CartesianProductGenerator5() {} - - virtual ParamIteratorInterface* Begin() const { - return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, - g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin()); - } - virtual ParamIteratorInterface* End() const { - return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), - g4_, g4_.end(), g5_, g5_.end()); - } - - private: - class Iterator : public ParamIteratorInterface { - public: - Iterator(const ParamGeneratorInterface* base, - const ParamGenerator& g1, - const typename ParamGenerator::iterator& current1, - const ParamGenerator& g2, - const typename ParamGenerator::iterator& current2, - const ParamGenerator& g3, - const typename ParamGenerator::iterator& current3, - const ParamGenerator& g4, - const typename ParamGenerator::iterator& current4, - const ParamGenerator& g5, - const typename ParamGenerator::iterator& current5) - : base_(base), - begin1_(g1.begin()), end1_(g1.end()), current1_(current1), - begin2_(g2.begin()), end2_(g2.end()), current2_(current2), - begin3_(g3.begin()), end3_(g3.end()), current3_(current3), - begin4_(g4.begin()), end4_(g4.end()), current4_(current4), - begin5_(g5.begin()), end5_(g5.end()), current5_(current5) { - ComputeCurrentValue(); - } - virtual ~Iterator() {} - - virtual const ParamGeneratorInterface* BaseGenerator() const { - return base_; - } - // Advance should not be called on beyond-of-range iterators - // so no component iterators must be beyond end of range, either. - virtual void Advance() { - assert(!AtEnd()); - ++current5_; - if (current5_ == end5_) { - current5_ = begin5_; - ++current4_; - } - if (current4_ == end4_) { - current4_ = begin4_; - ++current3_; - } - if (current3_ == end3_) { - current3_ = begin3_; - ++current2_; - } - if (current2_ == end2_) { - current2_ = begin2_; - ++current1_; - } - ComputeCurrentValue(); - } - virtual ParamIteratorInterface* Clone() const { - return new Iterator(*this); - } - virtual const ParamType* Current() const { return ¤t_value_; } - virtual bool Equals(const ParamIteratorInterface& other) const { - // Having the same base generator guarantees that the other - // iterator is of the same type and we can downcast. - GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) - << "The program attempted to compare iterators " - << "from different generators." << std::endl; - const Iterator* typed_other = - CheckedDowncastToActualType(&other); - // We must report iterators equal if they both point beyond their - // respective ranges. That can happen in a variety of fashions, - // so we have to consult AtEnd(). - return (AtEnd() && typed_other->AtEnd()) || - ( - current1_ == typed_other->current1_ && - current2_ == typed_other->current2_ && - current3_ == typed_other->current3_ && - current4_ == typed_other->current4_ && - current5_ == typed_other->current5_); - } - - private: - Iterator(const Iterator& other) - : base_(other.base_), - begin1_(other.begin1_), - end1_(other.end1_), - current1_(other.current1_), - begin2_(other.begin2_), - end2_(other.end2_), - current2_(other.current2_), - begin3_(other.begin3_), - end3_(other.end3_), - current3_(other.current3_), - begin4_(other.begin4_), - end4_(other.end4_), - current4_(other.current4_), - begin5_(other.begin5_), - end5_(other.end5_), - current5_(other.current5_) { - ComputeCurrentValue(); - } - - void ComputeCurrentValue() { - if (!AtEnd()) - current_value_ = ParamType(*current1_, *current2_, *current3_, - *current4_, *current5_); - } - bool AtEnd() const { - // We must report iterator past the end of the range when either of the - // component iterators has reached the end of its range. - return - current1_ == end1_ || - current2_ == end2_ || - current3_ == end3_ || - current4_ == end4_ || - current5_ == end5_; - } - - // No implementation - assignment is unsupported. - void operator=(const Iterator& other); - - const ParamGeneratorInterface* const base_; - // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. - // current[i]_ is the actual traversing iterator. - const typename ParamGenerator::iterator begin1_; - const typename ParamGenerator::iterator end1_; - typename ParamGenerator::iterator current1_; - const typename ParamGenerator::iterator begin2_; - const typename ParamGenerator::iterator end2_; - typename ParamGenerator::iterator current2_; - const typename ParamGenerator::iterator begin3_; - const typename ParamGenerator::iterator end3_; - typename ParamGenerator::iterator current3_; - const typename ParamGenerator::iterator begin4_; - const typename ParamGenerator::iterator end4_; - typename ParamGenerator::iterator current4_; - const typename ParamGenerator::iterator begin5_; - const typename ParamGenerator::iterator end5_; - typename ParamGenerator::iterator current5_; - ParamType current_value_; - }; // class CartesianProductGenerator5::Iterator - - // No implementation - assignment is unsupported. - void operator=(const CartesianProductGenerator5& other); - - const ParamGenerator g1_; - const ParamGenerator g2_; - const ParamGenerator g3_; - const ParamGenerator g4_; - const ParamGenerator g5_; -}; // class CartesianProductGenerator5 - - -template -class CartesianProductGenerator6 - : public ParamGeneratorInterface< ::std::tr1::tuple > { - public: - typedef ::std::tr1::tuple ParamType; - - CartesianProductGenerator6(const ParamGenerator& g1, - const ParamGenerator& g2, const ParamGenerator& g3, - const ParamGenerator& g4, const ParamGenerator& g5, - const ParamGenerator& g6) - : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6) {} - virtual ~CartesianProductGenerator6() {} - - virtual ParamIteratorInterface* Begin() const { - return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, - g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin()); - } - virtual ParamIteratorInterface* End() const { - return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), - g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end()); - } - - private: - class Iterator : public ParamIteratorInterface { - public: - Iterator(const ParamGeneratorInterface* base, - const ParamGenerator& g1, - const typename ParamGenerator::iterator& current1, - const ParamGenerator& g2, - const typename ParamGenerator::iterator& current2, - const ParamGenerator& g3, - const typename ParamGenerator::iterator& current3, - const ParamGenerator& g4, - const typename ParamGenerator::iterator& current4, - const ParamGenerator& g5, - const typename ParamGenerator::iterator& current5, - const ParamGenerator& g6, - const typename ParamGenerator::iterator& current6) - : base_(base), - begin1_(g1.begin()), end1_(g1.end()), current1_(current1), - begin2_(g2.begin()), end2_(g2.end()), current2_(current2), - begin3_(g3.begin()), end3_(g3.end()), current3_(current3), - begin4_(g4.begin()), end4_(g4.end()), current4_(current4), - begin5_(g5.begin()), end5_(g5.end()), current5_(current5), - begin6_(g6.begin()), end6_(g6.end()), current6_(current6) { - ComputeCurrentValue(); - } - virtual ~Iterator() {} - - virtual const ParamGeneratorInterface* BaseGenerator() const { - return base_; - } - // Advance should not be called on beyond-of-range iterators - // so no component iterators must be beyond end of range, either. - virtual void Advance() { - assert(!AtEnd()); - ++current6_; - if (current6_ == end6_) { - current6_ = begin6_; - ++current5_; - } - if (current5_ == end5_) { - current5_ = begin5_; - ++current4_; - } - if (current4_ == end4_) { - current4_ = begin4_; - ++current3_; - } - if (current3_ == end3_) { - current3_ = begin3_; - ++current2_; - } - if (current2_ == end2_) { - current2_ = begin2_; - ++current1_; - } - ComputeCurrentValue(); - } - virtual ParamIteratorInterface* Clone() const { - return new Iterator(*this); - } - virtual const ParamType* Current() const { return ¤t_value_; } - virtual bool Equals(const ParamIteratorInterface& other) const { - // Having the same base generator guarantees that the other - // iterator is of the same type and we can downcast. - GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) - << "The program attempted to compare iterators " - << "from different generators." << std::endl; - const Iterator* typed_other = - CheckedDowncastToActualType(&other); - // We must report iterators equal if they both point beyond their - // respective ranges. That can happen in a variety of fashions, - // so we have to consult AtEnd(). - return (AtEnd() && typed_other->AtEnd()) || - ( - current1_ == typed_other->current1_ && - current2_ == typed_other->current2_ && - current3_ == typed_other->current3_ && - current4_ == typed_other->current4_ && - current5_ == typed_other->current5_ && - current6_ == typed_other->current6_); - } - - private: - Iterator(const Iterator& other) - : base_(other.base_), - begin1_(other.begin1_), - end1_(other.end1_), - current1_(other.current1_), - begin2_(other.begin2_), - end2_(other.end2_), - current2_(other.current2_), - begin3_(other.begin3_), - end3_(other.end3_), - current3_(other.current3_), - begin4_(other.begin4_), - end4_(other.end4_), - current4_(other.current4_), - begin5_(other.begin5_), - end5_(other.end5_), - current5_(other.current5_), - begin6_(other.begin6_), - end6_(other.end6_), - current6_(other.current6_) { - ComputeCurrentValue(); - } - - void ComputeCurrentValue() { - if (!AtEnd()) - current_value_ = ParamType(*current1_, *current2_, *current3_, - *current4_, *current5_, *current6_); - } - bool AtEnd() const { - // We must report iterator past the end of the range when either of the - // component iterators has reached the end of its range. - return - current1_ == end1_ || - current2_ == end2_ || - current3_ == end3_ || - current4_ == end4_ || - current5_ == end5_ || - current6_ == end6_; - } - - // No implementation - assignment is unsupported. - void operator=(const Iterator& other); - - const ParamGeneratorInterface* const base_; - // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. - // current[i]_ is the actual traversing iterator. - const typename ParamGenerator::iterator begin1_; - const typename ParamGenerator::iterator end1_; - typename ParamGenerator::iterator current1_; - const typename ParamGenerator::iterator begin2_; - const typename ParamGenerator::iterator end2_; - typename ParamGenerator::iterator current2_; - const typename ParamGenerator::iterator begin3_; - const typename ParamGenerator::iterator end3_; - typename ParamGenerator::iterator current3_; - const typename ParamGenerator::iterator begin4_; - const typename ParamGenerator::iterator end4_; - typename ParamGenerator::iterator current4_; - const typename ParamGenerator::iterator begin5_; - const typename ParamGenerator::iterator end5_; - typename ParamGenerator::iterator current5_; - const typename ParamGenerator::iterator begin6_; - const typename ParamGenerator::iterator end6_; - typename ParamGenerator::iterator current6_; - ParamType current_value_; - }; // class CartesianProductGenerator6::Iterator - - // No implementation - assignment is unsupported. - void operator=(const CartesianProductGenerator6& other); - - const ParamGenerator g1_; - const ParamGenerator g2_; - const ParamGenerator g3_; - const ParamGenerator g4_; - const ParamGenerator g5_; - const ParamGenerator g6_; -}; // class CartesianProductGenerator6 - - -template -class CartesianProductGenerator7 - : public ParamGeneratorInterface< ::std::tr1::tuple > { - public: - typedef ::std::tr1::tuple ParamType; - - CartesianProductGenerator7(const ParamGenerator& g1, - const ParamGenerator& g2, const ParamGenerator& g3, - const ParamGenerator& g4, const ParamGenerator& g5, - const ParamGenerator& g6, const ParamGenerator& g7) - : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7) {} - virtual ~CartesianProductGenerator7() {} - - virtual ParamIteratorInterface* Begin() const { - return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, - g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, - g7_.begin()); - } - virtual ParamIteratorInterface* End() const { - return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), - g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end()); - } - - private: - class Iterator : public ParamIteratorInterface { - public: - Iterator(const ParamGeneratorInterface* base, - const ParamGenerator& g1, - const typename ParamGenerator::iterator& current1, - const ParamGenerator& g2, - const typename ParamGenerator::iterator& current2, - const ParamGenerator& g3, - const typename ParamGenerator::iterator& current3, - const ParamGenerator& g4, - const typename ParamGenerator::iterator& current4, - const ParamGenerator& g5, - const typename ParamGenerator::iterator& current5, - const ParamGenerator& g6, - const typename ParamGenerator::iterator& current6, - const ParamGenerator& g7, - const typename ParamGenerator::iterator& current7) - : base_(base), - begin1_(g1.begin()), end1_(g1.end()), current1_(current1), - begin2_(g2.begin()), end2_(g2.end()), current2_(current2), - begin3_(g3.begin()), end3_(g3.end()), current3_(current3), - begin4_(g4.begin()), end4_(g4.end()), current4_(current4), - begin5_(g5.begin()), end5_(g5.end()), current5_(current5), - begin6_(g6.begin()), end6_(g6.end()), current6_(current6), - begin7_(g7.begin()), end7_(g7.end()), current7_(current7) { - ComputeCurrentValue(); - } - virtual ~Iterator() {} - - virtual const ParamGeneratorInterface* BaseGenerator() const { - return base_; - } - // Advance should not be called on beyond-of-range iterators - // so no component iterators must be beyond end of range, either. - virtual void Advance() { - assert(!AtEnd()); - ++current7_; - if (current7_ == end7_) { - current7_ = begin7_; - ++current6_; - } - if (current6_ == end6_) { - current6_ = begin6_; - ++current5_; - } - if (current5_ == end5_) { - current5_ = begin5_; - ++current4_; - } - if (current4_ == end4_) { - current4_ = begin4_; - ++current3_; - } - if (current3_ == end3_) { - current3_ = begin3_; - ++current2_; - } - if (current2_ == end2_) { - current2_ = begin2_; - ++current1_; - } - ComputeCurrentValue(); - } - virtual ParamIteratorInterface* Clone() const { - return new Iterator(*this); - } - virtual const ParamType* Current() const { return ¤t_value_; } - virtual bool Equals(const ParamIteratorInterface& other) const { - // Having the same base generator guarantees that the other - // iterator is of the same type and we can downcast. - GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) - << "The program attempted to compare iterators " - << "from different generators." << std::endl; - const Iterator* typed_other = - CheckedDowncastToActualType(&other); - // We must report iterators equal if they both point beyond their - // respective ranges. That can happen in a variety of fashions, - // so we have to consult AtEnd(). - return (AtEnd() && typed_other->AtEnd()) || - ( - current1_ == typed_other->current1_ && - current2_ == typed_other->current2_ && - current3_ == typed_other->current3_ && - current4_ == typed_other->current4_ && - current5_ == typed_other->current5_ && - current6_ == typed_other->current6_ && - current7_ == typed_other->current7_); - } - - private: - Iterator(const Iterator& other) - : base_(other.base_), - begin1_(other.begin1_), - end1_(other.end1_), - current1_(other.current1_), - begin2_(other.begin2_), - end2_(other.end2_), - current2_(other.current2_), - begin3_(other.begin3_), - end3_(other.end3_), - current3_(other.current3_), - begin4_(other.begin4_), - end4_(other.end4_), - current4_(other.current4_), - begin5_(other.begin5_), - end5_(other.end5_), - current5_(other.current5_), - begin6_(other.begin6_), - end6_(other.end6_), - current6_(other.current6_), - begin7_(other.begin7_), - end7_(other.end7_), - current7_(other.current7_) { - ComputeCurrentValue(); - } - - void ComputeCurrentValue() { - if (!AtEnd()) - current_value_ = ParamType(*current1_, *current2_, *current3_, - *current4_, *current5_, *current6_, *current7_); - } - bool AtEnd() const { - // We must report iterator past the end of the range when either of the - // component iterators has reached the end of its range. - return - current1_ == end1_ || - current2_ == end2_ || - current3_ == end3_ || - current4_ == end4_ || - current5_ == end5_ || - current6_ == end6_ || - current7_ == end7_; - } - - // No implementation - assignment is unsupported. - void operator=(const Iterator& other); - - const ParamGeneratorInterface* const base_; - // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. - // current[i]_ is the actual traversing iterator. - const typename ParamGenerator::iterator begin1_; - const typename ParamGenerator::iterator end1_; - typename ParamGenerator::iterator current1_; - const typename ParamGenerator::iterator begin2_; - const typename ParamGenerator::iterator end2_; - typename ParamGenerator::iterator current2_; - const typename ParamGenerator::iterator begin3_; - const typename ParamGenerator::iterator end3_; - typename ParamGenerator::iterator current3_; - const typename ParamGenerator::iterator begin4_; - const typename ParamGenerator::iterator end4_; - typename ParamGenerator::iterator current4_; - const typename ParamGenerator::iterator begin5_; - const typename ParamGenerator::iterator end5_; - typename ParamGenerator::iterator current5_; - const typename ParamGenerator::iterator begin6_; - const typename ParamGenerator::iterator end6_; - typename ParamGenerator::iterator current6_; - const typename ParamGenerator::iterator begin7_; - const typename ParamGenerator::iterator end7_; - typename ParamGenerator::iterator current7_; - ParamType current_value_; - }; // class CartesianProductGenerator7::Iterator - - // No implementation - assignment is unsupported. - void operator=(const CartesianProductGenerator7& other); - - const ParamGenerator g1_; - const ParamGenerator g2_; - const ParamGenerator g3_; - const ParamGenerator g4_; - const ParamGenerator g5_; - const ParamGenerator g6_; - const ParamGenerator g7_; -}; // class CartesianProductGenerator7 - - -template -class CartesianProductGenerator8 - : public ParamGeneratorInterface< ::std::tr1::tuple > { - public: - typedef ::std::tr1::tuple ParamType; - - CartesianProductGenerator8(const ParamGenerator& g1, - const ParamGenerator& g2, const ParamGenerator& g3, - const ParamGenerator& g4, const ParamGenerator& g5, - const ParamGenerator& g6, const ParamGenerator& g7, - const ParamGenerator& g8) - : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), - g8_(g8) {} - virtual ~CartesianProductGenerator8() {} - - virtual ParamIteratorInterface* Begin() const { - return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, - g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, - g7_.begin(), g8_, g8_.begin()); - } - virtual ParamIteratorInterface* End() const { - return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), - g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_, - g8_.end()); - } - - private: - class Iterator : public ParamIteratorInterface { - public: - Iterator(const ParamGeneratorInterface* base, - const ParamGenerator& g1, - const typename ParamGenerator::iterator& current1, - const ParamGenerator& g2, - const typename ParamGenerator::iterator& current2, - const ParamGenerator& g3, - const typename ParamGenerator::iterator& current3, - const ParamGenerator& g4, - const typename ParamGenerator::iterator& current4, - const ParamGenerator& g5, - const typename ParamGenerator::iterator& current5, - const ParamGenerator& g6, - const typename ParamGenerator::iterator& current6, - const ParamGenerator& g7, - const typename ParamGenerator::iterator& current7, - const ParamGenerator& g8, - const typename ParamGenerator::iterator& current8) - : base_(base), - begin1_(g1.begin()), end1_(g1.end()), current1_(current1), - begin2_(g2.begin()), end2_(g2.end()), current2_(current2), - begin3_(g3.begin()), end3_(g3.end()), current3_(current3), - begin4_(g4.begin()), end4_(g4.end()), current4_(current4), - begin5_(g5.begin()), end5_(g5.end()), current5_(current5), - begin6_(g6.begin()), end6_(g6.end()), current6_(current6), - begin7_(g7.begin()), end7_(g7.end()), current7_(current7), - begin8_(g8.begin()), end8_(g8.end()), current8_(current8) { - ComputeCurrentValue(); - } - virtual ~Iterator() {} - - virtual const ParamGeneratorInterface* BaseGenerator() const { - return base_; - } - // Advance should not be called on beyond-of-range iterators - // so no component iterators must be beyond end of range, either. - virtual void Advance() { - assert(!AtEnd()); - ++current8_; - if (current8_ == end8_) { - current8_ = begin8_; - ++current7_; - } - if (current7_ == end7_) { - current7_ = begin7_; - ++current6_; - } - if (current6_ == end6_) { - current6_ = begin6_; - ++current5_; - } - if (current5_ == end5_) { - current5_ = begin5_; - ++current4_; - } - if (current4_ == end4_) { - current4_ = begin4_; - ++current3_; - } - if (current3_ == end3_) { - current3_ = begin3_; - ++current2_; - } - if (current2_ == end2_) { - current2_ = begin2_; - ++current1_; - } - ComputeCurrentValue(); - } - virtual ParamIteratorInterface* Clone() const { - return new Iterator(*this); - } - virtual const ParamType* Current() const { return ¤t_value_; } - virtual bool Equals(const ParamIteratorInterface& other) const { - // Having the same base generator guarantees that the other - // iterator is of the same type and we can downcast. - GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) - << "The program attempted to compare iterators " - << "from different generators." << std::endl; - const Iterator* typed_other = - CheckedDowncastToActualType(&other); - // We must report iterators equal if they both point beyond their - // respective ranges. That can happen in a variety of fashions, - // so we have to consult AtEnd(). - return (AtEnd() && typed_other->AtEnd()) || - ( - current1_ == typed_other->current1_ && - current2_ == typed_other->current2_ && - current3_ == typed_other->current3_ && - current4_ == typed_other->current4_ && - current5_ == typed_other->current5_ && - current6_ == typed_other->current6_ && - current7_ == typed_other->current7_ && - current8_ == typed_other->current8_); - } - - private: - Iterator(const Iterator& other) - : base_(other.base_), - begin1_(other.begin1_), - end1_(other.end1_), - current1_(other.current1_), - begin2_(other.begin2_), - end2_(other.end2_), - current2_(other.current2_), - begin3_(other.begin3_), - end3_(other.end3_), - current3_(other.current3_), - begin4_(other.begin4_), - end4_(other.end4_), - current4_(other.current4_), - begin5_(other.begin5_), - end5_(other.end5_), - current5_(other.current5_), - begin6_(other.begin6_), - end6_(other.end6_), - current6_(other.current6_), - begin7_(other.begin7_), - end7_(other.end7_), - current7_(other.current7_), - begin8_(other.begin8_), - end8_(other.end8_), - current8_(other.current8_) { - ComputeCurrentValue(); - } - - void ComputeCurrentValue() { - if (!AtEnd()) - current_value_ = ParamType(*current1_, *current2_, *current3_, - *current4_, *current5_, *current6_, *current7_, *current8_); - } - bool AtEnd() const { - // We must report iterator past the end of the range when either of the - // component iterators has reached the end of its range. - return - current1_ == end1_ || - current2_ == end2_ || - current3_ == end3_ || - current4_ == end4_ || - current5_ == end5_ || - current6_ == end6_ || - current7_ == end7_ || - current8_ == end8_; - } - - // No implementation - assignment is unsupported. - void operator=(const Iterator& other); - - const ParamGeneratorInterface* const base_; - // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. - // current[i]_ is the actual traversing iterator. - const typename ParamGenerator::iterator begin1_; - const typename ParamGenerator::iterator end1_; - typename ParamGenerator::iterator current1_; - const typename ParamGenerator::iterator begin2_; - const typename ParamGenerator::iterator end2_; - typename ParamGenerator::iterator current2_; - const typename ParamGenerator::iterator begin3_; - const typename ParamGenerator::iterator end3_; - typename ParamGenerator::iterator current3_; - const typename ParamGenerator::iterator begin4_; - const typename ParamGenerator::iterator end4_; - typename ParamGenerator::iterator current4_; - const typename ParamGenerator::iterator begin5_; - const typename ParamGenerator::iterator end5_; - typename ParamGenerator::iterator current5_; - const typename ParamGenerator::iterator begin6_; - const typename ParamGenerator::iterator end6_; - typename ParamGenerator::iterator current6_; - const typename ParamGenerator::iterator begin7_; - const typename ParamGenerator::iterator end7_; - typename ParamGenerator::iterator current7_; - const typename ParamGenerator::iterator begin8_; - const typename ParamGenerator::iterator end8_; - typename ParamGenerator::iterator current8_; - ParamType current_value_; - }; // class CartesianProductGenerator8::Iterator - - // No implementation - assignment is unsupported. - void operator=(const CartesianProductGenerator8& other); - - const ParamGenerator g1_; - const ParamGenerator g2_; - const ParamGenerator g3_; - const ParamGenerator g4_; - const ParamGenerator g5_; - const ParamGenerator g6_; - const ParamGenerator g7_; - const ParamGenerator g8_; -}; // class CartesianProductGenerator8 - - -template -class CartesianProductGenerator9 - : public ParamGeneratorInterface< ::std::tr1::tuple > { - public: - typedef ::std::tr1::tuple ParamType; - - CartesianProductGenerator9(const ParamGenerator& g1, - const ParamGenerator& g2, const ParamGenerator& g3, - const ParamGenerator& g4, const ParamGenerator& g5, - const ParamGenerator& g6, const ParamGenerator& g7, - const ParamGenerator& g8, const ParamGenerator& g9) - : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), - g9_(g9) {} - virtual ~CartesianProductGenerator9() {} - - virtual ParamIteratorInterface* Begin() const { - return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, - g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, - g7_.begin(), g8_, g8_.begin(), g9_, g9_.begin()); - } - virtual ParamIteratorInterface* End() const { - return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), - g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_, - g8_.end(), g9_, g9_.end()); - } - - private: - class Iterator : public ParamIteratorInterface { - public: - Iterator(const ParamGeneratorInterface* base, - const ParamGenerator& g1, - const typename ParamGenerator::iterator& current1, - const ParamGenerator& g2, - const typename ParamGenerator::iterator& current2, - const ParamGenerator& g3, - const typename ParamGenerator::iterator& current3, - const ParamGenerator& g4, - const typename ParamGenerator::iterator& current4, - const ParamGenerator& g5, - const typename ParamGenerator::iterator& current5, - const ParamGenerator& g6, - const typename ParamGenerator::iterator& current6, - const ParamGenerator& g7, - const typename ParamGenerator::iterator& current7, - const ParamGenerator& g8, - const typename ParamGenerator::iterator& current8, - const ParamGenerator& g9, - const typename ParamGenerator::iterator& current9) - : base_(base), - begin1_(g1.begin()), end1_(g1.end()), current1_(current1), - begin2_(g2.begin()), end2_(g2.end()), current2_(current2), - begin3_(g3.begin()), end3_(g3.end()), current3_(current3), - begin4_(g4.begin()), end4_(g4.end()), current4_(current4), - begin5_(g5.begin()), end5_(g5.end()), current5_(current5), - begin6_(g6.begin()), end6_(g6.end()), current6_(current6), - begin7_(g7.begin()), end7_(g7.end()), current7_(current7), - begin8_(g8.begin()), end8_(g8.end()), current8_(current8), - begin9_(g9.begin()), end9_(g9.end()), current9_(current9) { - ComputeCurrentValue(); - } - virtual ~Iterator() {} - - virtual const ParamGeneratorInterface* BaseGenerator() const { - return base_; - } - // Advance should not be called on beyond-of-range iterators - // so no component iterators must be beyond end of range, either. - virtual void Advance() { - assert(!AtEnd()); - ++current9_; - if (current9_ == end9_) { - current9_ = begin9_; - ++current8_; - } - if (current8_ == end8_) { - current8_ = begin8_; - ++current7_; - } - if (current7_ == end7_) { - current7_ = begin7_; - ++current6_; - } - if (current6_ == end6_) { - current6_ = begin6_; - ++current5_; - } - if (current5_ == end5_) { - current5_ = begin5_; - ++current4_; - } - if (current4_ == end4_) { - current4_ = begin4_; - ++current3_; - } - if (current3_ == end3_) { - current3_ = begin3_; - ++current2_; - } - if (current2_ == end2_) { - current2_ = begin2_; - ++current1_; - } - ComputeCurrentValue(); - } - virtual ParamIteratorInterface* Clone() const { - return new Iterator(*this); - } - virtual const ParamType* Current() const { return ¤t_value_; } - virtual bool Equals(const ParamIteratorInterface& other) const { - // Having the same base generator guarantees that the other - // iterator is of the same type and we can downcast. - GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) - << "The program attempted to compare iterators " - << "from different generators." << std::endl; - const Iterator* typed_other = - CheckedDowncastToActualType(&other); - // We must report iterators equal if they both point beyond their - // respective ranges. That can happen in a variety of fashions, - // so we have to consult AtEnd(). - return (AtEnd() && typed_other->AtEnd()) || - ( - current1_ == typed_other->current1_ && - current2_ == typed_other->current2_ && - current3_ == typed_other->current3_ && - current4_ == typed_other->current4_ && - current5_ == typed_other->current5_ && - current6_ == typed_other->current6_ && - current7_ == typed_other->current7_ && - current8_ == typed_other->current8_ && - current9_ == typed_other->current9_); - } - - private: - Iterator(const Iterator& other) - : base_(other.base_), - begin1_(other.begin1_), - end1_(other.end1_), - current1_(other.current1_), - begin2_(other.begin2_), - end2_(other.end2_), - current2_(other.current2_), - begin3_(other.begin3_), - end3_(other.end3_), - current3_(other.current3_), - begin4_(other.begin4_), - end4_(other.end4_), - current4_(other.current4_), - begin5_(other.begin5_), - end5_(other.end5_), - current5_(other.current5_), - begin6_(other.begin6_), - end6_(other.end6_), - current6_(other.current6_), - begin7_(other.begin7_), - end7_(other.end7_), - current7_(other.current7_), - begin8_(other.begin8_), - end8_(other.end8_), - current8_(other.current8_), - begin9_(other.begin9_), - end9_(other.end9_), - current9_(other.current9_) { - ComputeCurrentValue(); - } - - void ComputeCurrentValue() { - if (!AtEnd()) - current_value_ = ParamType(*current1_, *current2_, *current3_, - *current4_, *current5_, *current6_, *current7_, *current8_, - *current9_); - } - bool AtEnd() const { - // We must report iterator past the end of the range when either of the - // component iterators has reached the end of its range. - return - current1_ == end1_ || - current2_ == end2_ || - current3_ == end3_ || - current4_ == end4_ || - current5_ == end5_ || - current6_ == end6_ || - current7_ == end7_ || - current8_ == end8_ || - current9_ == end9_; - } - - // No implementation - assignment is unsupported. - void operator=(const Iterator& other); - - const ParamGeneratorInterface* const base_; - // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. - // current[i]_ is the actual traversing iterator. - const typename ParamGenerator::iterator begin1_; - const typename ParamGenerator::iterator end1_; - typename ParamGenerator::iterator current1_; - const typename ParamGenerator::iterator begin2_; - const typename ParamGenerator::iterator end2_; - typename ParamGenerator::iterator current2_; - const typename ParamGenerator::iterator begin3_; - const typename ParamGenerator::iterator end3_; - typename ParamGenerator::iterator current3_; - const typename ParamGenerator::iterator begin4_; - const typename ParamGenerator::iterator end4_; - typename ParamGenerator::iterator current4_; - const typename ParamGenerator::iterator begin5_; - const typename ParamGenerator::iterator end5_; - typename ParamGenerator::iterator current5_; - const typename ParamGenerator::iterator begin6_; - const typename ParamGenerator::iterator end6_; - typename ParamGenerator::iterator current6_; - const typename ParamGenerator::iterator begin7_; - const typename ParamGenerator::iterator end7_; - typename ParamGenerator::iterator current7_; - const typename ParamGenerator::iterator begin8_; - const typename ParamGenerator::iterator end8_; - typename ParamGenerator::iterator current8_; - const typename ParamGenerator::iterator begin9_; - const typename ParamGenerator::iterator end9_; - typename ParamGenerator::iterator current9_; - ParamType current_value_; - }; // class CartesianProductGenerator9::Iterator - - // No implementation - assignment is unsupported. - void operator=(const CartesianProductGenerator9& other); - - const ParamGenerator g1_; - const ParamGenerator g2_; - const ParamGenerator g3_; - const ParamGenerator g4_; - const ParamGenerator g5_; - const ParamGenerator g6_; - const ParamGenerator g7_; - const ParamGenerator g8_; - const ParamGenerator g9_; -}; // class CartesianProductGenerator9 - - -template -class CartesianProductGenerator10 - : public ParamGeneratorInterface< ::std::tr1::tuple > { - public: - typedef ::std::tr1::tuple ParamType; - - CartesianProductGenerator10(const ParamGenerator& g1, - const ParamGenerator& g2, const ParamGenerator& g3, - const ParamGenerator& g4, const ParamGenerator& g5, - const ParamGenerator& g6, const ParamGenerator& g7, - const ParamGenerator& g8, const ParamGenerator& g9, - const ParamGenerator& g10) - : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), - g9_(g9), g10_(g10) {} - virtual ~CartesianProductGenerator10() {} - - virtual ParamIteratorInterface* Begin() const { - return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, - g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, - g7_.begin(), g8_, g8_.begin(), g9_, g9_.begin(), g10_, g10_.begin()); - } - virtual ParamIteratorInterface* End() const { - return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), - g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_, - g8_.end(), g9_, g9_.end(), g10_, g10_.end()); - } - - private: - class Iterator : public ParamIteratorInterface { - public: - Iterator(const ParamGeneratorInterface* base, - const ParamGenerator& g1, - const typename ParamGenerator::iterator& current1, - const ParamGenerator& g2, - const typename ParamGenerator::iterator& current2, - const ParamGenerator& g3, - const typename ParamGenerator::iterator& current3, - const ParamGenerator& g4, - const typename ParamGenerator::iterator& current4, - const ParamGenerator& g5, - const typename ParamGenerator::iterator& current5, - const ParamGenerator& g6, - const typename ParamGenerator::iterator& current6, - const ParamGenerator& g7, - const typename ParamGenerator::iterator& current7, - const ParamGenerator& g8, - const typename ParamGenerator::iterator& current8, - const ParamGenerator& g9, - const typename ParamGenerator::iterator& current9, - const ParamGenerator& g10, - const typename ParamGenerator::iterator& current10) - : base_(base), - begin1_(g1.begin()), end1_(g1.end()), current1_(current1), - begin2_(g2.begin()), end2_(g2.end()), current2_(current2), - begin3_(g3.begin()), end3_(g3.end()), current3_(current3), - begin4_(g4.begin()), end4_(g4.end()), current4_(current4), - begin5_(g5.begin()), end5_(g5.end()), current5_(current5), - begin6_(g6.begin()), end6_(g6.end()), current6_(current6), - begin7_(g7.begin()), end7_(g7.end()), current7_(current7), - begin8_(g8.begin()), end8_(g8.end()), current8_(current8), - begin9_(g9.begin()), end9_(g9.end()), current9_(current9), - begin10_(g10.begin()), end10_(g10.end()), current10_(current10) { - ComputeCurrentValue(); - } - virtual ~Iterator() {} - - virtual const ParamGeneratorInterface* BaseGenerator() const { - return base_; - } - // Advance should not be called on beyond-of-range iterators - // so no component iterators must be beyond end of range, either. - virtual void Advance() { - assert(!AtEnd()); - ++current10_; - if (current10_ == end10_) { - current10_ = begin10_; - ++current9_; - } - if (current9_ == end9_) { - current9_ = begin9_; - ++current8_; - } - if (current8_ == end8_) { - current8_ = begin8_; - ++current7_; - } - if (current7_ == end7_) { - current7_ = begin7_; - ++current6_; - } - if (current6_ == end6_) { - current6_ = begin6_; - ++current5_; - } - if (current5_ == end5_) { - current5_ = begin5_; - ++current4_; - } - if (current4_ == end4_) { - current4_ = begin4_; - ++current3_; - } - if (current3_ == end3_) { - current3_ = begin3_; - ++current2_; - } - if (current2_ == end2_) { - current2_ = begin2_; - ++current1_; - } - ComputeCurrentValue(); - } - virtual ParamIteratorInterface* Clone() const { - return new Iterator(*this); - } - virtual const ParamType* Current() const { return ¤t_value_; } - virtual bool Equals(const ParamIteratorInterface& other) const { - // Having the same base generator guarantees that the other - // iterator is of the same type and we can downcast. - GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) - << "The program attempted to compare iterators " - << "from different generators." << std::endl; - const Iterator* typed_other = - CheckedDowncastToActualType(&other); - // We must report iterators equal if they both point beyond their - // respective ranges. That can happen in a variety of fashions, - // so we have to consult AtEnd(). - return (AtEnd() && typed_other->AtEnd()) || - ( - current1_ == typed_other->current1_ && - current2_ == typed_other->current2_ && - current3_ == typed_other->current3_ && - current4_ == typed_other->current4_ && - current5_ == typed_other->current5_ && - current6_ == typed_other->current6_ && - current7_ == typed_other->current7_ && - current8_ == typed_other->current8_ && - current9_ == typed_other->current9_ && - current10_ == typed_other->current10_); - } - - private: - Iterator(const Iterator& other) - : base_(other.base_), - begin1_(other.begin1_), - end1_(other.end1_), - current1_(other.current1_), - begin2_(other.begin2_), - end2_(other.end2_), - current2_(other.current2_), - begin3_(other.begin3_), - end3_(other.end3_), - current3_(other.current3_), - begin4_(other.begin4_), - end4_(other.end4_), - current4_(other.current4_), - begin5_(other.begin5_), - end5_(other.end5_), - current5_(other.current5_), - begin6_(other.begin6_), - end6_(other.end6_), - current6_(other.current6_), - begin7_(other.begin7_), - end7_(other.end7_), - current7_(other.current7_), - begin8_(other.begin8_), - end8_(other.end8_), - current8_(other.current8_), - begin9_(other.begin9_), - end9_(other.end9_), - current9_(other.current9_), - begin10_(other.begin10_), - end10_(other.end10_), - current10_(other.current10_) { - ComputeCurrentValue(); - } - - void ComputeCurrentValue() { - if (!AtEnd()) - current_value_ = ParamType(*current1_, *current2_, *current3_, - *current4_, *current5_, *current6_, *current7_, *current8_, - *current9_, *current10_); - } - bool AtEnd() const { - // We must report iterator past the end of the range when either of the - // component iterators has reached the end of its range. - return - current1_ == end1_ || - current2_ == end2_ || - current3_ == end3_ || - current4_ == end4_ || - current5_ == end5_ || - current6_ == end6_ || - current7_ == end7_ || - current8_ == end8_ || - current9_ == end9_ || - current10_ == end10_; - } - - // No implementation - assignment is unsupported. - void operator=(const Iterator& other); - - const ParamGeneratorInterface* const base_; - // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. - // current[i]_ is the actual traversing iterator. - const typename ParamGenerator::iterator begin1_; - const typename ParamGenerator::iterator end1_; - typename ParamGenerator::iterator current1_; - const typename ParamGenerator::iterator begin2_; - const typename ParamGenerator::iterator end2_; - typename ParamGenerator::iterator current2_; - const typename ParamGenerator::iterator begin3_; - const typename ParamGenerator::iterator end3_; - typename ParamGenerator::iterator current3_; - const typename ParamGenerator::iterator begin4_; - const typename ParamGenerator::iterator end4_; - typename ParamGenerator::iterator current4_; - const typename ParamGenerator::iterator begin5_; - const typename ParamGenerator::iterator end5_; - typename ParamGenerator::iterator current5_; - const typename ParamGenerator::iterator begin6_; - const typename ParamGenerator::iterator end6_; - typename ParamGenerator::iterator current6_; - const typename ParamGenerator::iterator begin7_; - const typename ParamGenerator::iterator end7_; - typename ParamGenerator::iterator current7_; - const typename ParamGenerator::iterator begin8_; - const typename ParamGenerator::iterator end8_; - typename ParamGenerator::iterator current8_; - const typename ParamGenerator::iterator begin9_; - const typename ParamGenerator::iterator end9_; - typename ParamGenerator::iterator current9_; - const typename ParamGenerator::iterator begin10_; - const typename ParamGenerator::iterator end10_; - typename ParamGenerator::iterator current10_; - ParamType current_value_; - }; // class CartesianProductGenerator10::Iterator - - // No implementation - assignment is unsupported. - void operator=(const CartesianProductGenerator10& other); - - const ParamGenerator g1_; - const ParamGenerator g2_; - const ParamGenerator g3_; - const ParamGenerator g4_; - const ParamGenerator g5_; - const ParamGenerator g6_; - const ParamGenerator g7_; - const ParamGenerator g8_; - const ParamGenerator g9_; - const ParamGenerator g10_; -}; // class CartesianProductGenerator10 - - -// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. -// -// Helper classes providing Combine() with polymorphic features. They allow -// casting CartesianProductGeneratorN to ParamGenerator if T is -// convertible to U. -// -template -class CartesianProductHolder2 { - public: -CartesianProductHolder2(const Generator1& g1, const Generator2& g2) - : g1_(g1), g2_(g2) {} - template - operator ParamGenerator< ::std::tr1::tuple >() const { - return ParamGenerator< ::std::tr1::tuple >( - new CartesianProductGenerator2( - static_cast >(g1_), - static_cast >(g2_))); - } - - private: - // No implementation - assignment is unsupported. - void operator=(const CartesianProductHolder2& other); - - const Generator1 g1_; - const Generator2 g2_; -}; // class CartesianProductHolder2 - -template -class CartesianProductHolder3 { - public: -CartesianProductHolder3(const Generator1& g1, const Generator2& g2, - const Generator3& g3) - : g1_(g1), g2_(g2), g3_(g3) {} - template - operator ParamGenerator< ::std::tr1::tuple >() const { - return ParamGenerator< ::std::tr1::tuple >( - new CartesianProductGenerator3( - static_cast >(g1_), - static_cast >(g2_), - static_cast >(g3_))); - } - - private: - // No implementation - assignment is unsupported. - void operator=(const CartesianProductHolder3& other); - - const Generator1 g1_; - const Generator2 g2_; - const Generator3 g3_; -}; // class CartesianProductHolder3 - -template -class CartesianProductHolder4 { - public: -CartesianProductHolder4(const Generator1& g1, const Generator2& g2, - const Generator3& g3, const Generator4& g4) - : g1_(g1), g2_(g2), g3_(g3), g4_(g4) {} - template - operator ParamGenerator< ::std::tr1::tuple >() const { - return ParamGenerator< ::std::tr1::tuple >( - new CartesianProductGenerator4( - static_cast >(g1_), - static_cast >(g2_), - static_cast >(g3_), - static_cast >(g4_))); - } - - private: - // No implementation - assignment is unsupported. - void operator=(const CartesianProductHolder4& other); - - const Generator1 g1_; - const Generator2 g2_; - const Generator3 g3_; - const Generator4 g4_; -}; // class CartesianProductHolder4 - -template -class CartesianProductHolder5 { - public: -CartesianProductHolder5(const Generator1& g1, const Generator2& g2, - const Generator3& g3, const Generator4& g4, const Generator5& g5) - : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5) {} - template - operator ParamGenerator< ::std::tr1::tuple >() const { - return ParamGenerator< ::std::tr1::tuple >( - new CartesianProductGenerator5( - static_cast >(g1_), - static_cast >(g2_), - static_cast >(g3_), - static_cast >(g4_), - static_cast >(g5_))); - } - - private: - // No implementation - assignment is unsupported. - void operator=(const CartesianProductHolder5& other); - - const Generator1 g1_; - const Generator2 g2_; - const Generator3 g3_; - const Generator4 g4_; - const Generator5 g5_; -}; // class CartesianProductHolder5 - -template -class CartesianProductHolder6 { - public: -CartesianProductHolder6(const Generator1& g1, const Generator2& g2, - const Generator3& g3, const Generator4& g4, const Generator5& g5, - const Generator6& g6) - : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6) {} - template - operator ParamGenerator< ::std::tr1::tuple >() const { - return ParamGenerator< ::std::tr1::tuple >( - new CartesianProductGenerator6( - static_cast >(g1_), - static_cast >(g2_), - static_cast >(g3_), - static_cast >(g4_), - static_cast >(g5_), - static_cast >(g6_))); - } - - private: - // No implementation - assignment is unsupported. - void operator=(const CartesianProductHolder6& other); - - const Generator1 g1_; - const Generator2 g2_; - const Generator3 g3_; - const Generator4 g4_; - const Generator5 g5_; - const Generator6 g6_; -}; // class CartesianProductHolder6 - -template -class CartesianProductHolder7 { - public: -CartesianProductHolder7(const Generator1& g1, const Generator2& g2, - const Generator3& g3, const Generator4& g4, const Generator5& g5, - const Generator6& g6, const Generator7& g7) - : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7) {} - template - operator ParamGenerator< ::std::tr1::tuple >() const { - return ParamGenerator< ::std::tr1::tuple >( - new CartesianProductGenerator7( - static_cast >(g1_), - static_cast >(g2_), - static_cast >(g3_), - static_cast >(g4_), - static_cast >(g5_), - static_cast >(g6_), - static_cast >(g7_))); - } - - private: - // No implementation - assignment is unsupported. - void operator=(const CartesianProductHolder7& other); - - const Generator1 g1_; - const Generator2 g2_; - const Generator3 g3_; - const Generator4 g4_; - const Generator5 g5_; - const Generator6 g6_; - const Generator7 g7_; -}; // class CartesianProductHolder7 - -template -class CartesianProductHolder8 { - public: -CartesianProductHolder8(const Generator1& g1, const Generator2& g2, - const Generator3& g3, const Generator4& g4, const Generator5& g5, - const Generator6& g6, const Generator7& g7, const Generator8& g8) - : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), - g8_(g8) {} - template - operator ParamGenerator< ::std::tr1::tuple >() const { - return ParamGenerator< ::std::tr1::tuple >( - new CartesianProductGenerator8( - static_cast >(g1_), - static_cast >(g2_), - static_cast >(g3_), - static_cast >(g4_), - static_cast >(g5_), - static_cast >(g6_), - static_cast >(g7_), - static_cast >(g8_))); - } - - private: - // No implementation - assignment is unsupported. - void operator=(const CartesianProductHolder8& other); - - const Generator1 g1_; - const Generator2 g2_; - const Generator3 g3_; - const Generator4 g4_; - const Generator5 g5_; - const Generator6 g6_; - const Generator7 g7_; - const Generator8 g8_; -}; // class CartesianProductHolder8 - -template -class CartesianProductHolder9 { - public: -CartesianProductHolder9(const Generator1& g1, const Generator2& g2, - const Generator3& g3, const Generator4& g4, const Generator5& g5, - const Generator6& g6, const Generator7& g7, const Generator8& g8, - const Generator9& g9) - : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), - g9_(g9) {} - template - operator ParamGenerator< ::std::tr1::tuple >() const { - return ParamGenerator< ::std::tr1::tuple >( - new CartesianProductGenerator9( - static_cast >(g1_), - static_cast >(g2_), - static_cast >(g3_), - static_cast >(g4_), - static_cast >(g5_), - static_cast >(g6_), - static_cast >(g7_), - static_cast >(g8_), - static_cast >(g9_))); - } - - private: - // No implementation - assignment is unsupported. - void operator=(const CartesianProductHolder9& other); - - const Generator1 g1_; - const Generator2 g2_; - const Generator3 g3_; - const Generator4 g4_; - const Generator5 g5_; - const Generator6 g6_; - const Generator7 g7_; - const Generator8 g8_; - const Generator9 g9_; -}; // class CartesianProductHolder9 - -template -class CartesianProductHolder10 { - public: -CartesianProductHolder10(const Generator1& g1, const Generator2& g2, - const Generator3& g3, const Generator4& g4, const Generator5& g5, - const Generator6& g6, const Generator7& g7, const Generator8& g8, - const Generator9& g9, const Generator10& g10) - : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), - g9_(g9), g10_(g10) {} - template - operator ParamGenerator< ::std::tr1::tuple >() const { - return ParamGenerator< ::std::tr1::tuple >( - new CartesianProductGenerator10( - static_cast >(g1_), - static_cast >(g2_), - static_cast >(g3_), - static_cast >(g4_), - static_cast >(g5_), - static_cast >(g6_), - static_cast >(g7_), - static_cast >(g8_), - static_cast >(g9_), - static_cast >(g10_))); - } - - private: - // No implementation - assignment is unsupported. - void operator=(const CartesianProductHolder10& other); - - const Generator1 g1_; - const Generator2 g2_; - const Generator3 g3_; - const Generator4 g4_; - const Generator5 g5_; - const Generator6 g6_; - const Generator7 g7_; - const Generator8 g8_; - const Generator9 g9_; - const Generator10 g10_; -}; // class CartesianProductHolder10 - -# endif // GTEST_HAS_COMBINE - -} // namespace internal -} // namespace testing - -#endif // GTEST_HAS_PARAM_TEST - -#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ - -#if GTEST_HAS_PARAM_TEST - -namespace testing { - -// Functions producing parameter generators. -// -// Google Test uses these generators to produce parameters for value- -// parameterized tests. When a parameterized test case is instantiated -// with a particular generator, Google Test creates and runs tests -// for each element in the sequence produced by the generator. -// -// In the following sample, tests from test case FooTest are instantiated -// each three times with parameter values 3, 5, and 8: -// -// class FooTest : public TestWithParam { ... }; -// -// TEST_P(FooTest, TestThis) { -// } -// TEST_P(FooTest, TestThat) { -// } -// INSTANTIATE_TEST_CASE_P(TestSequence, FooTest, Values(3, 5, 8)); -// - -// Range() returns generators providing sequences of values in a range. -// -// Synopsis: -// Range(start, end) -// - returns a generator producing a sequence of values {start, start+1, -// start+2, ..., }. -// Range(start, end, step) -// - returns a generator producing a sequence of values {start, start+step, -// start+step+step, ..., }. -// Notes: -// * The generated sequences never include end. For example, Range(1, 5) -// returns a generator producing a sequence {1, 2, 3, 4}. Range(1, 9, 2) -// returns a generator producing {1, 3, 5, 7}. -// * start and end must have the same type. That type may be any integral or -// floating-point type or a user defined type satisfying these conditions: -// * It must be assignable (have operator=() defined). -// * It must have operator+() (operator+(int-compatible type) for -// two-operand version). -// * It must have operator<() defined. -// Elements in the resulting sequences will also have that type. -// * Condition start < end must be satisfied in order for resulting sequences -// to contain any elements. -// -template -internal::ParamGenerator Range(T start, T end, IncrementT step) { - return internal::ParamGenerator( - new internal::RangeGenerator(start, end, step)); -} - -template -internal::ParamGenerator Range(T start, T end) { - return Range(start, end, 1); -} - -// ValuesIn() function allows generation of tests with parameters coming from -// a container. -// -// Synopsis: -// ValuesIn(const T (&array)[N]) -// - returns a generator producing sequences with elements from -// a C-style array. -// ValuesIn(const Container& container) -// - returns a generator producing sequences with elements from -// an STL-style container. -// ValuesIn(Iterator begin, Iterator end) -// - returns a generator producing sequences with elements from -// a range [begin, end) defined by a pair of STL-style iterators. These -// iterators can also be plain C pointers. -// -// Please note that ValuesIn copies the values from the containers -// passed in and keeps them to generate tests in RUN_ALL_TESTS(). -// -// Examples: -// -// This instantiates tests from test case StringTest -// each with C-string values of "foo", "bar", and "baz": -// -// const char* strings[] = {"foo", "bar", "baz"}; -// INSTANTIATE_TEST_CASE_P(StringSequence, SrtingTest, ValuesIn(strings)); -// -// This instantiates tests from test case StlStringTest -// each with STL strings with values "a" and "b": -// -// ::std::vector< ::std::string> GetParameterStrings() { -// ::std::vector< ::std::string> v; -// v.push_back("a"); -// v.push_back("b"); -// return v; -// } -// -// INSTANTIATE_TEST_CASE_P(CharSequence, -// StlStringTest, -// ValuesIn(GetParameterStrings())); -// -// -// This will also instantiate tests from CharTest -// each with parameter values 'a' and 'b': -// -// ::std::list GetParameterChars() { -// ::std::list list; -// list.push_back('a'); -// list.push_back('b'); -// return list; -// } -// ::std::list l = GetParameterChars(); -// INSTANTIATE_TEST_CASE_P(CharSequence2, -// CharTest, -// ValuesIn(l.begin(), l.end())); -// -template -internal::ParamGenerator< - typename ::testing::internal::IteratorTraits::value_type> -ValuesIn(ForwardIterator begin, ForwardIterator end) { - typedef typename ::testing::internal::IteratorTraits - ::value_type ParamType; - return internal::ParamGenerator( - new internal::ValuesInIteratorRangeGenerator(begin, end)); -} - -template -internal::ParamGenerator ValuesIn(const T (&array)[N]) { - return ValuesIn(array, array + N); -} - -template -internal::ParamGenerator ValuesIn( - const Container& container) { - return ValuesIn(container.begin(), container.end()); -} - -// Values() allows generating tests from explicitly specified list of -// parameters. -// -// Synopsis: -// Values(T v1, T v2, ..., T vN) -// - returns a generator producing sequences with elements v1, v2, ..., vN. -// -// For example, this instantiates tests from test case BarTest each -// with values "one", "two", and "three": -// -// INSTANTIATE_TEST_CASE_P(NumSequence, BarTest, Values("one", "two", "three")); -// -// This instantiates tests from test case BazTest each with values 1, 2, 3.5. -// The exact type of values will depend on the type of parameter in BazTest. -// -// INSTANTIATE_TEST_CASE_P(FloatingNumbers, BazTest, Values(1, 2, 3.5)); -// -// Currently, Values() supports from 1 to 50 parameters. -// -template -internal::ValueArray1 Values(T1 v1) { - return internal::ValueArray1(v1); -} - -template -internal::ValueArray2 Values(T1 v1, T2 v2) { - return internal::ValueArray2(v1, v2); -} - -template -internal::ValueArray3 Values(T1 v1, T2 v2, T3 v3) { - return internal::ValueArray3(v1, v2, v3); -} - -template -internal::ValueArray4 Values(T1 v1, T2 v2, T3 v3, T4 v4) { - return internal::ValueArray4(v1, v2, v3, v4); -} - -template -internal::ValueArray5 Values(T1 v1, T2 v2, T3 v3, T4 v4, - T5 v5) { - return internal::ValueArray5(v1, v2, v3, v4, v5); -} - -template -internal::ValueArray6 Values(T1 v1, T2 v2, T3 v3, - T4 v4, T5 v5, T6 v6) { - return internal::ValueArray6(v1, v2, v3, v4, v5, v6); -} - -template -internal::ValueArray7 Values(T1 v1, T2 v2, T3 v3, - T4 v4, T5 v5, T6 v6, T7 v7) { - return internal::ValueArray7(v1, v2, v3, v4, v5, - v6, v7); -} - -template -internal::ValueArray8 Values(T1 v1, T2 v2, - T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8) { - return internal::ValueArray8(v1, v2, v3, v4, - v5, v6, v7, v8); -} - -template -internal::ValueArray9 Values(T1 v1, T2 v2, - T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9) { - return internal::ValueArray9(v1, v2, v3, - v4, v5, v6, v7, v8, v9); -} - -template -internal::ValueArray10 Values(T1 v1, - T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10) { - return internal::ValueArray10(v1, - v2, v3, v4, v5, v6, v7, v8, v9, v10); -} - -template -internal::ValueArray11 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11) { - return internal::ValueArray11(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11); -} - -template -internal::ValueArray12 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12) { - return internal::ValueArray12(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12); -} - -template -internal::ValueArray13 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13) { - return internal::ValueArray13(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13); -} - -template -internal::ValueArray14 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) { - return internal::ValueArray14(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, - v14); -} - -template -internal::ValueArray15 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, - T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15) { - return internal::ValueArray15(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, - v13, v14, v15); -} - -template -internal::ValueArray16 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, - T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, - T16 v16) { - return internal::ValueArray16(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, - v12, v13, v14, v15, v16); -} - -template -internal::ValueArray17 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, - T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, - T16 v16, T17 v17) { - return internal::ValueArray17(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, - v11, v12, v13, v14, v15, v16, v17); -} - -template -internal::ValueArray18 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, - T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, - T16 v16, T17 v17, T18 v18) { - return internal::ValueArray18(v1, v2, v3, v4, v5, v6, v7, v8, v9, - v10, v11, v12, v13, v14, v15, v16, v17, v18); -} - -template -internal::ValueArray19 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, - T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, - T15 v15, T16 v16, T17 v17, T18 v18, T19 v19) { - return internal::ValueArray19(v1, v2, v3, v4, v5, v6, v7, v8, - v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19); -} - -template -internal::ValueArray20 Values(T1 v1, T2 v2, T3 v3, T4 v4, - T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, - T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20) { - return internal::ValueArray20(v1, v2, v3, v4, v5, v6, v7, - v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20); -} - -template -internal::ValueArray21 Values(T1 v1, T2 v2, T3 v3, T4 v4, - T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, - T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21) { - return internal::ValueArray21(v1, v2, v3, v4, v5, v6, - v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21); -} - -template -internal::ValueArray22 Values(T1 v1, T2 v2, T3 v3, - T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, - T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, - T21 v21, T22 v22) { - return internal::ValueArray22(v1, v2, v3, v4, - v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, - v20, v21, v22); -} - -template -internal::ValueArray23 Values(T1 v1, T2 v2, - T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, - T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, - T21 v21, T22 v22, T23 v23) { - return internal::ValueArray23(v1, v2, v3, - v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, - v20, v21, v22, v23); -} - -template -internal::ValueArray24 Values(T1 v1, T2 v2, - T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, - T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, - T21 v21, T22 v22, T23 v23, T24 v24) { - return internal::ValueArray24(v1, v2, - v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, - v19, v20, v21, v22, v23, v24); -} - -template -internal::ValueArray25 Values(T1 v1, - T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, - T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, - T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25) { - return internal::ValueArray25(v1, - v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, - v18, v19, v20, v21, v22, v23, v24, v25); -} - -template -internal::ValueArray26 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26) { - return internal::ValueArray26(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, - v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26); -} - -template -internal::ValueArray27 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27) { - return internal::ValueArray27(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, - v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27); -} - -template -internal::ValueArray28 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27, T28 v28) { - return internal::ValueArray28(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, - v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, - v28); -} - -template -internal::ValueArray29 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27, T28 v28, T29 v29) { - return internal::ValueArray29(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, - v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, - v27, v28, v29); -} - -template -internal::ValueArray30 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, - T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, - T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, - T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30) { - return internal::ValueArray30(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, - v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, - v26, v27, v28, v29, v30); -} - -template -internal::ValueArray31 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, - T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, - T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, - T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31) { - return internal::ValueArray31(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, - v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, - v25, v26, v27, v28, v29, v30, v31); -} - -template -internal::ValueArray32 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, - T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, - T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, - T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, - T32 v32) { - return internal::ValueArray32(v1, v2, v3, v4, v5, v6, v7, v8, v9, - v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, - v24, v25, v26, v27, v28, v29, v30, v31, v32); -} - -template -internal::ValueArray33 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, - T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, - T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, - T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, - T32 v32, T33 v33) { - return internal::ValueArray33(v1, v2, v3, v4, v5, v6, v7, v8, - v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, - v24, v25, v26, v27, v28, v29, v30, v31, v32, v33); -} - -template -internal::ValueArray34 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, - T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, - T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, - T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, - T31 v31, T32 v32, T33 v33, T34 v34) { - return internal::ValueArray34(v1, v2, v3, v4, v5, v6, v7, - v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, - v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34); -} - -template -internal::ValueArray35 Values(T1 v1, T2 v2, T3 v3, T4 v4, - T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, - T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, - T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, - T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35) { - return internal::ValueArray35(v1, v2, v3, v4, v5, v6, - v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, - v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35); -} - -template -internal::ValueArray36 Values(T1 v1, T2 v2, T3 v3, T4 v4, - T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, - T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, - T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, - T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36) { - return internal::ValueArray36(v1, v2, v3, v4, - v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, - v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, - v34, v35, v36); -} - -template -internal::ValueArray37 Values(T1 v1, T2 v2, T3 v3, - T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, - T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, - T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, - T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, - T37 v37) { - return internal::ValueArray37(v1, v2, v3, - v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, - v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, - v34, v35, v36, v37); -} - -template -internal::ValueArray38 Values(T1 v1, T2 v2, - T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, - T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, - T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, - T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, - T37 v37, T38 v38) { - return internal::ValueArray38(v1, v2, - v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, - v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, - v33, v34, v35, v36, v37, v38); -} - -template -internal::ValueArray39 Values(T1 v1, T2 v2, - T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, - T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, - T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, - T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, - T37 v37, T38 v38, T39 v39) { - return internal::ValueArray39(v1, - v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, - v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, - v32, v33, v34, v35, v36, v37, v38, v39); -} - -template -internal::ValueArray40 Values(T1 v1, - T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, - T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, - T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, - T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, - T36 v36, T37 v37, T38 v38, T39 v39, T40 v40) { - return internal::ValueArray40(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, - v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, - v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40); -} - -template -internal::ValueArray41 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, - T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41) { - return internal::ValueArray41(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, - v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, - v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41); -} - -template -internal::ValueArray42 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, - T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, - T42 v42) { - return internal::ValueArray42(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, - v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, - v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, - v42); -} - -template -internal::ValueArray43 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, - T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, - T42 v42, T43 v43) { - return internal::ValueArray43(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, - v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, - v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, - v41, v42, v43); -} - -template -internal::ValueArray44 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, - T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, - T42 v42, T43 v43, T44 v44) { - return internal::ValueArray44(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, - v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, - v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, - v40, v41, v42, v43, v44); -} - -template -internal::ValueArray45 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, - T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, - T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, - T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, - T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, - T41 v41, T42 v42, T43 v43, T44 v44, T45 v45) { - return internal::ValueArray45(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, - v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, - v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, - v39, v40, v41, v42, v43, v44, v45); -} - -template -internal::ValueArray46 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, - T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, - T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, - T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, - T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, - T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46) { - return internal::ValueArray46(v1, v2, v3, v4, v5, v6, v7, v8, v9, - v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, - v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, - v38, v39, v40, v41, v42, v43, v44, v45, v46); -} - -template -internal::ValueArray47 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, - T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, - T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, - T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, - T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, - T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47) { - return internal::ValueArray47(v1, v2, v3, v4, v5, v6, v7, v8, - v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, - v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, - v38, v39, v40, v41, v42, v43, v44, v45, v46, v47); -} - -template -internal::ValueArray48 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, - T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, - T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, - T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, - T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, - T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, - T48 v48) { - return internal::ValueArray48(v1, v2, v3, v4, v5, v6, v7, - v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, - v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, - v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48); -} - -template -internal::ValueArray49 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, - T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, - T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, - T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, - T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, - T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, - T47 v47, T48 v48, T49 v49) { - return internal::ValueArray49(v1, v2, v3, v4, v5, v6, - v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, - v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, - v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49); -} - -template -internal::ValueArray50 Values(T1 v1, T2 v2, T3 v3, T4 v4, - T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, - T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, - T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, - T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, - T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, - T46 v46, T47 v47, T48 v48, T49 v49, T50 v50) { - return internal::ValueArray50(v1, v2, v3, v4, - v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, - v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, - v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, - v48, v49, v50); -} - -// Bool() allows generating tests with parameters in a set of (false, true). -// -// Synopsis: -// Bool() -// - returns a generator producing sequences with elements {false, true}. -// -// It is useful when testing code that depends on Boolean flags. Combinations -// of multiple flags can be tested when several Bool()'s are combined using -// Combine() function. -// -// In the following example all tests in the test case FlagDependentTest -// will be instantiated twice with parameters false and true. -// -// class FlagDependentTest : public testing::TestWithParam { -// virtual void SetUp() { -// external_flag = GetParam(); -// } -// } -// INSTANTIATE_TEST_CASE_P(BoolSequence, FlagDependentTest, Bool()); -// -inline internal::ParamGenerator Bool() { - return Values(false, true); -} - -# if GTEST_HAS_COMBINE -// Combine() allows the user to combine two or more sequences to produce -// values of a Cartesian product of those sequences' elements. -// -// Synopsis: -// Combine(gen1, gen2, ..., genN) -// - returns a generator producing sequences with elements coming from -// the Cartesian product of elements from the sequences generated by -// gen1, gen2, ..., genN. The sequence elements will have a type of -// tuple where T1, T2, ..., TN are the types -// of elements from sequences produces by gen1, gen2, ..., genN. -// -// Combine can have up to 10 arguments. This number is currently limited -// by the maximum number of elements in the tuple implementation used by Google -// Test. -// -// Example: -// -// This will instantiate tests in test case AnimalTest each one with -// the parameter values tuple("cat", BLACK), tuple("cat", WHITE), -// tuple("dog", BLACK), and tuple("dog", WHITE): -// -// enum Color { BLACK, GRAY, WHITE }; -// class AnimalTest -// : public testing::TestWithParam > {...}; -// -// TEST_P(AnimalTest, AnimalLooksNice) {...} -// -// INSTANTIATE_TEST_CASE_P(AnimalVariations, AnimalTest, -// Combine(Values("cat", "dog"), -// Values(BLACK, WHITE))); -// -// This will instantiate tests in FlagDependentTest with all variations of two -// Boolean flags: -// -// class FlagDependentTest -// : public testing::TestWithParam > { -// virtual void SetUp() { -// // Assigns external_flag_1 and external_flag_2 values from the tuple. -// tie(external_flag_1, external_flag_2) = GetParam(); -// } -// }; -// -// TEST_P(FlagDependentTest, TestFeature1) { -// // Test your code using external_flag_1 and external_flag_2 here. -// } -// INSTANTIATE_TEST_CASE_P(TwoBoolSequence, FlagDependentTest, -// Combine(Bool(), Bool())); -// -template -internal::CartesianProductHolder2 Combine( - const Generator1& g1, const Generator2& g2) { - return internal::CartesianProductHolder2( - g1, g2); -} - -template -internal::CartesianProductHolder3 Combine( - const Generator1& g1, const Generator2& g2, const Generator3& g3) { - return internal::CartesianProductHolder3( - g1, g2, g3); -} - -template -internal::CartesianProductHolder4 Combine( - const Generator1& g1, const Generator2& g2, const Generator3& g3, - const Generator4& g4) { - return internal::CartesianProductHolder4( - g1, g2, g3, g4); -} - -template -internal::CartesianProductHolder5 Combine( - const Generator1& g1, const Generator2& g2, const Generator3& g3, - const Generator4& g4, const Generator5& g5) { - return internal::CartesianProductHolder5( - g1, g2, g3, g4, g5); -} - -template -internal::CartesianProductHolder6 Combine( - const Generator1& g1, const Generator2& g2, const Generator3& g3, - const Generator4& g4, const Generator5& g5, const Generator6& g6) { - return internal::CartesianProductHolder6( - g1, g2, g3, g4, g5, g6); -} - -template -internal::CartesianProductHolder7 Combine( - const Generator1& g1, const Generator2& g2, const Generator3& g3, - const Generator4& g4, const Generator5& g5, const Generator6& g6, - const Generator7& g7) { - return internal::CartesianProductHolder7( - g1, g2, g3, g4, g5, g6, g7); -} - -template -internal::CartesianProductHolder8 Combine( - const Generator1& g1, const Generator2& g2, const Generator3& g3, - const Generator4& g4, const Generator5& g5, const Generator6& g6, - const Generator7& g7, const Generator8& g8) { - return internal::CartesianProductHolder8( - g1, g2, g3, g4, g5, g6, g7, g8); -} - -template -internal::CartesianProductHolder9 Combine( - const Generator1& g1, const Generator2& g2, const Generator3& g3, - const Generator4& g4, const Generator5& g5, const Generator6& g6, - const Generator7& g7, const Generator8& g8, const Generator9& g9) { - return internal::CartesianProductHolder9( - g1, g2, g3, g4, g5, g6, g7, g8, g9); -} - -template -internal::CartesianProductHolder10 Combine( - const Generator1& g1, const Generator2& g2, const Generator3& g3, - const Generator4& g4, const Generator5& g5, const Generator6& g6, - const Generator7& g7, const Generator8& g8, const Generator9& g9, - const Generator10& g10) { - return internal::CartesianProductHolder10( - g1, g2, g3, g4, g5, g6, g7, g8, g9, g10); -} -# endif // GTEST_HAS_COMBINE - - - -# define TEST_P(test_case_name, test_name) \ - class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \ - : public test_case_name { \ - public: \ - GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {} \ - virtual void TestBody(); \ - private: \ - static int AddToRegistry() { \ - ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \ - GetTestCasePatternHolder(\ - #test_case_name, __FILE__, __LINE__)->AddTestPattern(\ - #test_case_name, \ - #test_name, \ - new ::testing::internal::TestMetaFactory< \ - GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>()); \ - return 0; \ - } \ - static int gtest_registering_dummy_; \ - GTEST_DISALLOW_COPY_AND_ASSIGN_(\ - GTEST_TEST_CLASS_NAME_(test_case_name, test_name)); \ - }; \ - int GTEST_TEST_CLASS_NAME_(test_case_name, \ - test_name)::gtest_registering_dummy_ = \ - GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::AddToRegistry(); \ - void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody() - -# define INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) \ - ::testing::internal::ParamGenerator \ - gtest_##prefix##test_case_name##_EvalGenerator_() { return generator; } \ - int gtest_##prefix##test_case_name##_dummy_ = \ - ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \ - GetTestCasePatternHolder(\ - #test_case_name, __FILE__, __LINE__)->AddTestCaseInstantiation(\ - #prefix, \ - >est_##prefix##test_case_name##_EvalGenerator_, \ - __FILE__, __LINE__) - -} // namespace testing - -#endif // GTEST_HAS_PARAM_TEST - -#endif // GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ -// Copyright 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: wan@google.com (Zhanyong Wan) -// -// Google C++ Testing Framework definitions useful in production code. - -#ifndef GTEST_INCLUDE_GTEST_GTEST_PROD_H_ -#define GTEST_INCLUDE_GTEST_GTEST_PROD_H_ - -// When you need to test the private or protected members of a class, -// use the FRIEND_TEST macro to declare your tests as friends of the -// class. For example: -// -// class MyClass { -// private: -// void MyMethod(); -// FRIEND_TEST(MyClassTest, MyMethod); -// }; -// -// class MyClassTest : public testing::Test { -// // ... -// }; -// -// TEST_F(MyClassTest, MyMethod) { -// // Can call MyClass::MyMethod() here. -// } - -#define FRIEND_TEST(test_case_name, test_name)\ -friend class test_case_name##_##test_name##_Test - -#endif // GTEST_INCLUDE_GTEST_GTEST_PROD_H_ -// Copyright 2008, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: mheule@google.com (Markus Heule) -// - -#ifndef GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ -#define GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ - -#include -#include - -namespace testing { - -// A copyable object representing the result of a test part (i.e. an -// assertion or an explicit FAIL(), ADD_FAILURE(), or SUCCESS()). -// -// Don't inherit from TestPartResult as its destructor is not virtual. -class GTEST_API_ TestPartResult { - public: - // The possible outcomes of a test part (i.e. an assertion or an - // explicit SUCCEED(), FAIL(), or ADD_FAILURE()). - enum Type { - kSuccess, // Succeeded. - kNonFatalFailure, // Failed but the test can continue. - kFatalFailure // Failed and the test should be terminated. - }; - - // C'tor. TestPartResult does NOT have a default constructor. - // Always use this constructor (with parameters) to create a - // TestPartResult object. - TestPartResult(Type a_type, - const char* a_file_name, - int a_line_number, - const char* a_message) - : type_(a_type), - file_name_(a_file_name == NULL ? "" : a_file_name), - line_number_(a_line_number), - summary_(ExtractSummary(a_message)), - message_(a_message) { - } - - // Gets the outcome of the test part. - Type type() const { return type_; } - - // Gets the name of the source file where the test part took place, or - // NULL if it's unknown. - const char* file_name() const { - return file_name_.empty() ? NULL : file_name_.c_str(); - } - - // Gets the line in the source file where the test part took place, - // or -1 if it's unknown. - int line_number() const { return line_number_; } - - // Gets the summary of the failure message. - const char* summary() const { return summary_.c_str(); } - - // Gets the message associated with the test part. - const char* message() const { return message_.c_str(); } - - // Returns true iff the test part passed. - bool passed() const { return type_ == kSuccess; } - - // Returns true iff the test part failed. - bool failed() const { return type_ != kSuccess; } - - // Returns true iff the test part non-fatally failed. - bool nonfatally_failed() const { return type_ == kNonFatalFailure; } - - // Returns true iff the test part fatally failed. - bool fatally_failed() const { return type_ == kFatalFailure; } - - private: - Type type_; - - // Gets the summary of the failure message by omitting the stack - // trace in it. - static std::string ExtractSummary(const char* message); - - // The name of the source file where the test part took place, or - // "" if the source file is unknown. - std::string file_name_; - // The line in the source file where the test part took place, or -1 - // if the line number is unknown. - int line_number_; - std::string summary_; // The test failure summary. - std::string message_; // The test failure message. -}; - -// Prints a TestPartResult object. -std::ostream& operator<<(std::ostream& os, const TestPartResult& result); - -// An array of TestPartResult objects. -// -// Don't inherit from TestPartResultArray as its destructor is not -// virtual. -class GTEST_API_ TestPartResultArray { - public: - TestPartResultArray() {} - - // Appends the given TestPartResult to the array. - void Append(const TestPartResult& result); - - // Returns the TestPartResult at the given index (0-based). - const TestPartResult& GetTestPartResult(int index) const; - - // Returns the number of TestPartResult objects in the array. - int size() const; - - private: - std::vector array_; - - GTEST_DISALLOW_COPY_AND_ASSIGN_(TestPartResultArray); -}; - -// This interface knows how to report a test part result. -class TestPartResultReporterInterface { - public: - virtual ~TestPartResultReporterInterface() {} - - virtual void ReportTestPartResult(const TestPartResult& result) = 0; -}; - -namespace internal { - -// This helper class is used by {ASSERT|EXPECT}_NO_FATAL_FAILURE to check if a -// statement generates new fatal failures. To do so it registers itself as the -// current test part result reporter. Besides checking if fatal failures were -// reported, it only delegates the reporting to the former result reporter. -// The original result reporter is restored in the destructor. -// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. -class GTEST_API_ HasNewFatalFailureHelper - : public TestPartResultReporterInterface { - public: - HasNewFatalFailureHelper(); - virtual ~HasNewFatalFailureHelper(); - virtual void ReportTestPartResult(const TestPartResult& result); - bool has_new_fatal_failure() const { return has_new_fatal_failure_; } - private: - bool has_new_fatal_failure_; - TestPartResultReporterInterface* original_reporter_; - - GTEST_DISALLOW_COPY_AND_ASSIGN_(HasNewFatalFailureHelper); -}; - -} // namespace internal - -} // namespace testing - -#endif // GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ -// Copyright 2008 Google Inc. -// All Rights Reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: wan@google.com (Zhanyong Wan) - -#ifndef GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ -#define GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ - -// This header implements typed tests and type-parameterized tests. - -// Typed (aka type-driven) tests repeat the same test for types in a -// list. You must know which types you want to test with when writing -// typed tests. Here's how you do it: - -#if 0 - -// First, define a fixture class template. It should be parameterized -// by a type. Remember to derive it from testing::Test. -template -class FooTest : public testing::Test { - public: - ... - typedef std::list List; - static T shared_; - T value_; -}; - -// Next, associate a list of types with the test case, which will be -// repeated for each type in the list. The typedef is necessary for -// the macro to parse correctly. -typedef testing::Types MyTypes; -TYPED_TEST_CASE(FooTest, MyTypes); - -// If the type list contains only one type, you can write that type -// directly without Types<...>: -// TYPED_TEST_CASE(FooTest, int); - -// Then, use TYPED_TEST() instead of TEST_F() to define as many typed -// tests for this test case as you want. -TYPED_TEST(FooTest, DoesBlah) { - // Inside a test, refer to TypeParam to get the type parameter. - // Since we are inside a derived class template, C++ requires use to - // visit the members of FooTest via 'this'. - TypeParam n = this->value_; - - // To visit static members of the fixture, add the TestFixture:: - // prefix. - n += TestFixture::shared_; - - // To refer to typedefs in the fixture, add the "typename - // TestFixture::" prefix. - typename TestFixture::List values; - values.push_back(n); - ... -} - -TYPED_TEST(FooTest, HasPropertyA) { ... } - -#endif // 0 - -// Type-parameterized tests are abstract test patterns parameterized -// by a type. Compared with typed tests, type-parameterized tests -// allow you to define the test pattern without knowing what the type -// parameters are. The defined pattern can be instantiated with -// different types any number of times, in any number of translation -// units. -// -// If you are designing an interface or concept, you can define a -// suite of type-parameterized tests to verify properties that any -// valid implementation of the interface/concept should have. Then, -// each implementation can easily instantiate the test suite to verify -// that it conforms to the requirements, without having to write -// similar tests repeatedly. Here's an example: - -#if 0 - -// First, define a fixture class template. It should be parameterized -// by a type. Remember to derive it from testing::Test. -template -class FooTest : public testing::Test { - ... -}; - -// Next, declare that you will define a type-parameterized test case -// (the _P suffix is for "parameterized" or "pattern", whichever you -// prefer): -TYPED_TEST_CASE_P(FooTest); - -// Then, use TYPED_TEST_P() to define as many type-parameterized tests -// for this type-parameterized test case as you want. -TYPED_TEST_P(FooTest, DoesBlah) { - // Inside a test, refer to TypeParam to get the type parameter. - TypeParam n = 0; - ... -} - -TYPED_TEST_P(FooTest, HasPropertyA) { ... } - -// Now the tricky part: you need to register all test patterns before -// you can instantiate them. The first argument of the macro is the -// test case name; the rest are the names of the tests in this test -// case. -REGISTER_TYPED_TEST_CASE_P(FooTest, - DoesBlah, HasPropertyA); - -// Finally, you are free to instantiate the pattern with the types you -// want. If you put the above code in a header file, you can #include -// it in multiple C++ source files and instantiate it multiple times. -// -// To distinguish different instances of the pattern, the first -// argument to the INSTANTIATE_* macro is a prefix that will be added -// to the actual test case name. Remember to pick unique prefixes for -// different instances. -typedef testing::Types MyTypes; -INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes); - -// If the type list contains only one type, you can write that type -// directly without Types<...>: -// INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, int); - -#endif // 0 - - -// Implements typed tests. - -#if GTEST_HAS_TYPED_TEST - -// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. -// -// Expands to the name of the typedef for the type parameters of the -// given test case. -# define GTEST_TYPE_PARAMS_(TestCaseName) gtest_type_params_##TestCaseName##_ - -// The 'Types' template argument below must have spaces around it -// since some compilers may choke on '>>' when passing a template -// instance (e.g. Types) -# define TYPED_TEST_CASE(CaseName, Types) \ - typedef ::testing::internal::TypeList< Types >::type \ - GTEST_TYPE_PARAMS_(CaseName) - -# define TYPED_TEST(CaseName, TestName) \ - template \ - class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \ - : public CaseName { \ - private: \ - typedef CaseName TestFixture; \ - typedef gtest_TypeParam_ TypeParam; \ - virtual void TestBody(); \ - }; \ - bool gtest_##CaseName##_##TestName##_registered_ GTEST_ATTRIBUTE_UNUSED_ = \ - ::testing::internal::TypeParameterizedTest< \ - CaseName, \ - ::testing::internal::TemplateSel< \ - GTEST_TEST_CLASS_NAME_(CaseName, TestName)>, \ - GTEST_TYPE_PARAMS_(CaseName)>::Register(\ - "", #CaseName, #TestName, 0); \ - template \ - void GTEST_TEST_CLASS_NAME_(CaseName, TestName)::TestBody() - -#endif // GTEST_HAS_TYPED_TEST - -// Implements type-parameterized tests. - -#if GTEST_HAS_TYPED_TEST_P - -// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. -// -// Expands to the namespace name that the type-parameterized tests for -// the given type-parameterized test case are defined in. The exact -// name of the namespace is subject to change without notice. -# define GTEST_CASE_NAMESPACE_(TestCaseName) \ - gtest_case_##TestCaseName##_ - -// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. -// -// Expands to the name of the variable used to remember the names of -// the defined tests in the given test case. -# define GTEST_TYPED_TEST_CASE_P_STATE_(TestCaseName) \ - gtest_typed_test_case_p_state_##TestCaseName##_ - -// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE DIRECTLY. -// -// Expands to the name of the variable used to remember the names of -// the registered tests in the given test case. -# define GTEST_REGISTERED_TEST_NAMES_(TestCaseName) \ - gtest_registered_test_names_##TestCaseName##_ - -// The variables defined in the type-parameterized test macros are -// static as typically these macros are used in a .h file that can be -// #included in multiple translation units linked together. -# define TYPED_TEST_CASE_P(CaseName) \ - static ::testing::internal::TypedTestCasePState \ - GTEST_TYPED_TEST_CASE_P_STATE_(CaseName) - -# define TYPED_TEST_P(CaseName, TestName) \ - namespace GTEST_CASE_NAMESPACE_(CaseName) { \ - template \ - class TestName : public CaseName { \ - private: \ - typedef CaseName TestFixture; \ - typedef gtest_TypeParam_ TypeParam; \ - virtual void TestBody(); \ - }; \ - static bool gtest_##TestName##_defined_ GTEST_ATTRIBUTE_UNUSED_ = \ - GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).AddTestName(\ - __FILE__, __LINE__, #CaseName, #TestName); \ - } \ - template \ - void GTEST_CASE_NAMESPACE_(CaseName)::TestName::TestBody() - -# define REGISTER_TYPED_TEST_CASE_P(CaseName, ...) \ - namespace GTEST_CASE_NAMESPACE_(CaseName) { \ - typedef ::testing::internal::Templates<__VA_ARGS__>::type gtest_AllTests_; \ - } \ - static const char* const GTEST_REGISTERED_TEST_NAMES_(CaseName) = \ - GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).VerifyRegisteredTestNames(\ - __FILE__, __LINE__, #__VA_ARGS__) - -// The 'Types' template argument below must have spaces around it -// since some compilers may choke on '>>' when passing a template -// instance (e.g. Types) -# define INSTANTIATE_TYPED_TEST_CASE_P(Prefix, CaseName, Types) \ - bool gtest_##Prefix##_##CaseName GTEST_ATTRIBUTE_UNUSED_ = \ - ::testing::internal::TypeParameterizedTestCase::type>::Register(\ - #Prefix, #CaseName, GTEST_REGISTERED_TEST_NAMES_(CaseName)) - -#endif // GTEST_HAS_TYPED_TEST_P - -#endif // GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ - -// Depending on the platform, different string classes are available. -// On Linux, in addition to ::std::string, Google also makes use of -// class ::string, which has the same interface as ::std::string, but -// has a different implementation. -// -// The user can define GTEST_HAS_GLOBAL_STRING to 1 to indicate that -// ::string is available AND is a distinct type to ::std::string, or -// define it to 0 to indicate otherwise. -// -// If the user's ::std::string and ::string are the same class due to -// aliasing, he should define GTEST_HAS_GLOBAL_STRING to 0. -// -// If the user doesn't define GTEST_HAS_GLOBAL_STRING, it is defined -// heuristically. - -namespace testing { - -// Declares the flags. - -// This flag temporary enables the disabled tests. -GTEST_DECLARE_bool_(also_run_disabled_tests); - -// This flag brings the debugger on an assertion failure. -GTEST_DECLARE_bool_(break_on_failure); - -// This flag controls whether Google Test catches all test-thrown exceptions -// and logs them as failures. -GTEST_DECLARE_bool_(catch_exceptions); - -// This flag enables using colors in terminal output. Available values are -// "yes" to enable colors, "no" (disable colors), or "auto" (the default) -// to let Google Test decide. -GTEST_DECLARE_string_(color); - -// This flag sets up the filter to select by name using a glob pattern -// the tests to run. If the filter is not given all tests are executed. -GTEST_DECLARE_string_(filter); - -// This flag causes the Google Test to list tests. None of the tests listed -// are actually run if the flag is provided. -GTEST_DECLARE_bool_(list_tests); - -// This flag controls whether Google Test emits a detailed XML report to a file -// in addition to its normal textual output. -GTEST_DECLARE_string_(output); - -// This flags control whether Google Test prints the elapsed time for each -// test. -GTEST_DECLARE_bool_(print_time); - -// This flag specifies the random number seed. -GTEST_DECLARE_int32_(random_seed); - -// This flag sets how many times the tests are repeated. The default value -// is 1. If the value is -1 the tests are repeating forever. -GTEST_DECLARE_int32_(repeat); - -// This flag controls whether Google Test includes Google Test internal -// stack frames in failure stack traces. -GTEST_DECLARE_bool_(show_internal_stack_frames); - -// When this flag is specified, tests' order is randomized on every iteration. -GTEST_DECLARE_bool_(shuffle); - -// This flag specifies the maximum number of stack frames to be -// printed in a failure message. -GTEST_DECLARE_int32_(stack_trace_depth); - -// When this flag is specified, a failed assertion will throw an -// exception if exceptions are enabled, or exit the program with a -// non-zero code otherwise. -GTEST_DECLARE_bool_(throw_on_failure); - -// When this flag is set with a "host:port" string, on supported -// platforms test results are streamed to the specified port on -// the specified host machine. -GTEST_DECLARE_string_(stream_result_to); - -// The upper limit for valid stack trace depths. -const int kMaxStackTraceDepth = 100; - -namespace internal { - -class AssertHelper; -class DefaultGlobalTestPartResultReporter; -class ExecDeathTest; -class NoExecDeathTest; -class FinalSuccessChecker; -class GTestFlagSaver; -class StreamingListenerTest; -class TestResultAccessor; -class TestEventListenersAccessor; -class TestEventRepeater; -class UnitTestRecordPropertyTestHelper; -class WindowsDeathTest; -class UnitTestImpl* GetUnitTestImpl(); -void ReportFailureInUnknownLocation(TestPartResult::Type result_type, - const std::string& message); - -} // namespace internal - -// The friend relationship of some of these classes is cyclic. -// If we don't forward declare them the compiler might confuse the classes -// in friendship clauses with same named classes on the scope. -class Test; -class TestCase; -class TestInfo; -class UnitTest; - -// A class for indicating whether an assertion was successful. When -// the assertion wasn't successful, the AssertionResult object -// remembers a non-empty message that describes how it failed. -// -// To create an instance of this class, use one of the factory functions -// (AssertionSuccess() and AssertionFailure()). -// -// This class is useful for two purposes: -// 1. Defining predicate functions to be used with Boolean test assertions -// EXPECT_TRUE/EXPECT_FALSE and their ASSERT_ counterparts -// 2. Defining predicate-format functions to be -// used with predicate assertions (ASSERT_PRED_FORMAT*, etc). -// -// For example, if you define IsEven predicate: -// -// testing::AssertionResult IsEven(int n) { -// if ((n % 2) == 0) -// return testing::AssertionSuccess(); -// else -// return testing::AssertionFailure() << n << " is odd"; -// } -// -// Then the failed expectation EXPECT_TRUE(IsEven(Fib(5))) -// will print the message -// -// Value of: IsEven(Fib(5)) -// Actual: false (5 is odd) -// Expected: true -// -// instead of a more opaque -// -// Value of: IsEven(Fib(5)) -// Actual: false -// Expected: true -// -// in case IsEven is a simple Boolean predicate. -// -// If you expect your predicate to be reused and want to support informative -// messages in EXPECT_FALSE and ASSERT_FALSE (negative assertions show up -// about half as often as positive ones in our tests), supply messages for -// both success and failure cases: -// -// testing::AssertionResult IsEven(int n) { -// if ((n % 2) == 0) -// return testing::AssertionSuccess() << n << " is even"; -// else -// return testing::AssertionFailure() << n << " is odd"; -// } -// -// Then a statement EXPECT_FALSE(IsEven(Fib(6))) will print -// -// Value of: IsEven(Fib(6)) -// Actual: true (8 is even) -// Expected: false -// -// NB: Predicates that support negative Boolean assertions have reduced -// performance in positive ones so be careful not to use them in tests -// that have lots (tens of thousands) of positive Boolean assertions. -// -// To use this class with EXPECT_PRED_FORMAT assertions such as: -// -// // Verifies that Foo() returns an even number. -// EXPECT_PRED_FORMAT1(IsEven, Foo()); -// -// you need to define: -// -// testing::AssertionResult IsEven(const char* expr, int n) { -// if ((n % 2) == 0) -// return testing::AssertionSuccess(); -// else -// return testing::AssertionFailure() -// << "Expected: " << expr << " is even\n Actual: it's " << n; -// } -// -// If Foo() returns 5, you will see the following message: -// -// Expected: Foo() is even -// Actual: it's 5 -// -class GTEST_API_ AssertionResult { - public: - // Copy constructor. - // Used in EXPECT_TRUE/FALSE(assertion_result). - AssertionResult(const AssertionResult& other); - // Used in the EXPECT_TRUE/FALSE(bool_expression). - explicit AssertionResult(bool success) : success_(success) {} - - // Returns true iff the assertion succeeded. - operator bool() const { return success_; } // NOLINT - - // Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE. - AssertionResult operator!() const; - - // Returns the text streamed into this AssertionResult. Test assertions - // use it when they fail (i.e., the predicate's outcome doesn't match the - // assertion's expectation). When nothing has been streamed into the - // object, returns an empty string. - const char* message() const { - return message_.get() != NULL ? message_->c_str() : ""; - } - // TODO(vladl@google.com): Remove this after making sure no clients use it. - // Deprecated; please use message() instead. - const char* failure_message() const { return message(); } - - // Streams a custom failure message into this object. - template AssertionResult& operator<<(const T& value) { - AppendMessage(Message() << value); - return *this; - } - - // Allows streaming basic output manipulators such as endl or flush into - // this object. - AssertionResult& operator<<( - ::std::ostream& (*basic_manipulator)(::std::ostream& stream)) { - AppendMessage(Message() << basic_manipulator); - return *this; - } - - private: - // Appends the contents of message to message_. - void AppendMessage(const Message& a_message) { - if (message_.get() == NULL) - message_.reset(new ::std::string); - message_->append(a_message.GetString().c_str()); - } - - // Stores result of the assertion predicate. - bool success_; - // Stores the message describing the condition in case the expectation - // construct is not satisfied with the predicate's outcome. - // Referenced via a pointer to avoid taking too much stack frame space - // with test assertions. - internal::scoped_ptr< ::std::string> message_; - - GTEST_DISALLOW_ASSIGN_(AssertionResult); -}; - -// Makes a successful assertion result. -GTEST_API_ AssertionResult AssertionSuccess(); - -// Makes a failed assertion result. -GTEST_API_ AssertionResult AssertionFailure(); - -// Makes a failed assertion result with the given failure message. -// Deprecated; use AssertionFailure() << msg. -GTEST_API_ AssertionResult AssertionFailure(const Message& msg); - -// The abstract class that all tests inherit from. -// -// In Google Test, a unit test program contains one or many TestCases, and -// each TestCase contains one or many Tests. -// -// When you define a test using the TEST macro, you don't need to -// explicitly derive from Test - the TEST macro automatically does -// this for you. -// -// The only time you derive from Test is when defining a test fixture -// to be used a TEST_F. For example: -// -// class FooTest : public testing::Test { -// protected: -// virtual void SetUp() { ... } -// virtual void TearDown() { ... } -// ... -// }; -// -// TEST_F(FooTest, Bar) { ... } -// TEST_F(FooTest, Baz) { ... } -// -// Test is not copyable. -class GTEST_API_ Test { - public: - friend class TestInfo; - - // Defines types for pointers to functions that set up and tear down - // a test case. - typedef internal::SetUpTestCaseFunc SetUpTestCaseFunc; - typedef internal::TearDownTestCaseFunc TearDownTestCaseFunc; - - // The d'tor is virtual as we intend to inherit from Test. - virtual ~Test(); - - // Sets up the stuff shared by all tests in this test case. - // - // Google Test will call Foo::SetUpTestCase() before running the first - // test in test case Foo. Hence a sub-class can define its own - // SetUpTestCase() method to shadow the one defined in the super - // class. - static void SetUpTestCase() {} - - // Tears down the stuff shared by all tests in this test case. - // - // Google Test will call Foo::TearDownTestCase() after running the last - // test in test case Foo. Hence a sub-class can define its own - // TearDownTestCase() method to shadow the one defined in the super - // class. - static void TearDownTestCase() {} - - // Returns true iff the current test has a fatal failure. - static bool HasFatalFailure(); - - // Returns true iff the current test has a non-fatal failure. - static bool HasNonfatalFailure(); - - // Returns true iff the current test has a (either fatal or - // non-fatal) failure. - static bool HasFailure() { return HasFatalFailure() || HasNonfatalFailure(); } - - // Logs a property for the current test, test case, or for the entire - // invocation of the test program when used outside of the context of a - // test case. Only the last value for a given key is remembered. These - // are public static so they can be called from utility functions that are - // not members of the test fixture. Calls to RecordProperty made during - // lifespan of the test (from the moment its constructor starts to the - // moment its destructor finishes) will be output in XML as attributes of - // the element. Properties recorded from fixture's - // SetUpTestCase or TearDownTestCase are logged as attributes of the - // corresponding element. Calls to RecordProperty made in the - // global context (before or after invocation of RUN_ALL_TESTS and from - // SetUp/TearDown method of Environment objects registered with Google - // Test) will be output as attributes of the element. - static void RecordProperty(const std::string& key, const std::string& value); - static void RecordProperty(const std::string& key, int value); - - protected: - // Creates a Test object. - Test(); - - // Sets up the test fixture. - virtual void SetUp(); - - // Tears down the test fixture. - virtual void TearDown(); - - private: - // Returns true iff the current test has the same fixture class as - // the first test in the current test case. - static bool HasSameFixtureClass(); - - // Runs the test after the test fixture has been set up. - // - // A sub-class must implement this to define the test logic. - // - // DO NOT OVERRIDE THIS FUNCTION DIRECTLY IN A USER PROGRAM. - // Instead, use the TEST or TEST_F macro. - virtual void TestBody() = 0; - - // Sets up, executes, and tears down the test. - void Run(); - - // Deletes self. We deliberately pick an unusual name for this - // internal method to avoid clashing with names used in user TESTs. - void DeleteSelf_() { delete this; } - - // Uses a GTestFlagSaver to save and restore all Google Test flags. - const internal::GTestFlagSaver* const gtest_flag_saver_; - - // Often a user mis-spells SetUp() as Setup() and spends a long time - // wondering why it is never called by Google Test. The declaration of - // the following method is solely for catching such an error at - // compile time: - // - // - The return type is deliberately chosen to be not void, so it - // will be a conflict if a user declares void Setup() in his test - // fixture. - // - // - This method is private, so it will be another compiler error - // if a user calls it from his test fixture. - // - // DO NOT OVERRIDE THIS FUNCTION. - // - // If you see an error about overriding the following function or - // about it being private, you have mis-spelled SetUp() as Setup(). - struct Setup_should_be_spelled_SetUp {}; - virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; } - - // We disallow copying Tests. - GTEST_DISALLOW_COPY_AND_ASSIGN_(Test); -}; - -typedef internal::TimeInMillis TimeInMillis; - -// A copyable object representing a user specified test property which can be -// output as a key/value string pair. -// -// Don't inherit from TestProperty as its destructor is not virtual. -class TestProperty { - public: - // C'tor. TestProperty does NOT have a default constructor. - // Always use this constructor (with parameters) to create a - // TestProperty object. - TestProperty(const std::string& a_key, const std::string& a_value) : - key_(a_key), value_(a_value) { - } - - // Gets the user supplied key. - const char* key() const { - return key_.c_str(); - } - - // Gets the user supplied value. - const char* value() const { - return value_.c_str(); - } - - // Sets a new value, overriding the one supplied in the constructor. - void SetValue(const std::string& new_value) { - value_ = new_value; - } - - private: - // The key supplied by the user. - std::string key_; - // The value supplied by the user. - std::string value_; -}; - -// The result of a single Test. This includes a list of -// TestPartResults, a list of TestProperties, a count of how many -// death tests there are in the Test, and how much time it took to run -// the Test. -// -// TestResult is not copyable. -class GTEST_API_ TestResult { - public: - // Creates an empty TestResult. - TestResult(); - - // D'tor. Do not inherit from TestResult. - ~TestResult(); - - // Gets the number of all test parts. This is the sum of the number - // of successful test parts and the number of failed test parts. - int total_part_count() const; - - // Returns the number of the test properties. - int test_property_count() const; - - // Returns true iff the test passed (i.e. no test part failed). - bool Passed() const { return !Failed(); } - - // Returns true iff the test failed. - bool Failed() const; - - // Returns true iff the test fatally failed. - bool HasFatalFailure() const; - - // Returns true iff the test has a non-fatal failure. - bool HasNonfatalFailure() const; - - // Returns the elapsed time, in milliseconds. - TimeInMillis elapsed_time() const { return elapsed_time_; } - - // Returns the i-th test part result among all the results. i can range - // from 0 to test_property_count() - 1. If i is not in that range, aborts - // the program. - const TestPartResult& GetTestPartResult(int i) const; - - // Returns the i-th test property. i can range from 0 to - // test_property_count() - 1. If i is not in that range, aborts the - // program. - const TestProperty& GetTestProperty(int i) const; - - private: - friend class TestInfo; - friend class TestCase; - friend class UnitTest; - friend class internal::DefaultGlobalTestPartResultReporter; - friend class internal::ExecDeathTest; - friend class internal::TestResultAccessor; - friend class internal::UnitTestImpl; - friend class internal::WindowsDeathTest; - - // Gets the vector of TestPartResults. - const std::vector& test_part_results() const { - return test_part_results_; - } - - // Gets the vector of TestProperties. - const std::vector& test_properties() const { - return test_properties_; - } - - // Sets the elapsed time. - void set_elapsed_time(TimeInMillis elapsed) { elapsed_time_ = elapsed; } - - // Adds a test property to the list. The property is validated and may add - // a non-fatal failure if invalid (e.g., if it conflicts with reserved - // key names). If a property is already recorded for the same key, the - // value will be updated, rather than storing multiple values for the same - // key. xml_element specifies the element for which the property is being - // recorded and is used for validation. - void RecordProperty(const std::string& xml_element, - const TestProperty& test_property); - - // Adds a failure if the key is a reserved attribute of Google Test - // testcase tags. Returns true if the property is valid. - // TODO(russr): Validate attribute names are legal and human readable. - static bool ValidateTestProperty(const std::string& xml_element, - const TestProperty& test_property); - - // Adds a test part result to the list. - void AddTestPartResult(const TestPartResult& test_part_result); - - // Returns the death test count. - int death_test_count() const { return death_test_count_; } - - // Increments the death test count, returning the new count. - int increment_death_test_count() { return ++death_test_count_; } - - // Clears the test part results. - void ClearTestPartResults(); - - // Clears the object. - void Clear(); - - // Protects mutable state of the property vector and of owned - // properties, whose values may be updated. - internal::Mutex test_properites_mutex_; - - // The vector of TestPartResults - std::vector test_part_results_; - // The vector of TestProperties - std::vector test_properties_; - // Running count of death tests. - int death_test_count_; - // The elapsed time, in milliseconds. - TimeInMillis elapsed_time_; - - // We disallow copying TestResult. - GTEST_DISALLOW_COPY_AND_ASSIGN_(TestResult); -}; // class TestResult - -// A TestInfo object stores the following information about a test: -// -// Test case name -// Test name -// Whether the test should be run -// A function pointer that creates the test object when invoked -// Test result -// -// The constructor of TestInfo registers itself with the UnitTest -// singleton such that the RUN_ALL_TESTS() macro knows which tests to -// run. -class GTEST_API_ TestInfo { - public: - // Destructs a TestInfo object. This function is not virtual, so - // don't inherit from TestInfo. - ~TestInfo(); - - // Returns the test case name. - const char* test_case_name() const { return test_case_name_.c_str(); } - - // Returns the test name. - const char* name() const { return name_.c_str(); } - - // Returns the name of the parameter type, or NULL if this is not a typed - // or a type-parameterized test. - const char* type_param() const { - if (type_param_.get() != NULL) - return type_param_->c_str(); - return NULL; - } - - // Returns the text representation of the value parameter, or NULL if this - // is not a value-parameterized test. - const char* value_param() const { - if (value_param_.get() != NULL) - return value_param_->c_str(); - return NULL; - } - - // Returns true if this test should run, that is if the test is not - // disabled (or it is disabled but the also_run_disabled_tests flag has - // been specified) and its full name matches the user-specified filter. - // - // Google Test allows the user to filter the tests by their full names. - // The full name of a test Bar in test case Foo is defined as - // "Foo.Bar". Only the tests that match the filter will run. - // - // A filter is a colon-separated list of glob (not regex) patterns, - // optionally followed by a '-' and a colon-separated list of - // negative patterns (tests to exclude). A test is run if it - // matches one of the positive patterns and does not match any of - // the negative patterns. - // - // For example, *A*:Foo.* is a filter that matches any string that - // contains the character 'A' or starts with "Foo.". - bool should_run() const { return should_run_; } - - // Returns true iff this test will appear in the XML report. - bool is_reportable() const { - // For now, the XML report includes all tests matching the filter. - // In the future, we may trim tests that are excluded because of - // sharding. - return matches_filter_; - } - - // Returns the result of the test. - const TestResult* result() const { return &result_; } - - private: -#if GTEST_HAS_DEATH_TEST - friend class internal::DefaultDeathTestFactory; -#endif // GTEST_HAS_DEATH_TEST - friend class Test; - friend class TestCase; - friend class internal::UnitTestImpl; - friend class internal::StreamingListenerTest; - friend TestInfo* internal::MakeAndRegisterTestInfo( - const char* test_case_name, - const char* name, - const char* type_param, - const char* value_param, - internal::TypeId fixture_class_id, - Test::SetUpTestCaseFunc set_up_tc, - Test::TearDownTestCaseFunc tear_down_tc, - internal::TestFactoryBase* factory); - - // Constructs a TestInfo object. The newly constructed instance assumes - // ownership of the factory object. - TestInfo(const std::string& test_case_name, - const std::string& name, - const char* a_type_param, // NULL if not a type-parameterized test - const char* a_value_param, // NULL if not a value-parameterized test - internal::TypeId fixture_class_id, - internal::TestFactoryBase* factory); - - // Increments the number of death tests encountered in this test so - // far. - int increment_death_test_count() { - return result_.increment_death_test_count(); - } - - // Creates the test object, runs it, records its result, and then - // deletes it. - void Run(); - - static void ClearTestResult(TestInfo* test_info) { - test_info->result_.Clear(); - } - - // These fields are immutable properties of the test. - const std::string test_case_name_; // Test case name - const std::string name_; // Test name - // Name of the parameter type, or NULL if this is not a typed or a - // type-parameterized test. - const internal::scoped_ptr type_param_; - // Text representation of the value parameter, or NULL if this is not a - // value-parameterized test. - const internal::scoped_ptr value_param_; - const internal::TypeId fixture_class_id_; // ID of the test fixture class - bool should_run_; // True iff this test should run - bool is_disabled_; // True iff this test is disabled - bool matches_filter_; // True if this test matches the - // user-specified filter. - internal::TestFactoryBase* const factory_; // The factory that creates - // the test object - - // This field is mutable and needs to be reset before running the - // test for the second time. - TestResult result_; - - GTEST_DISALLOW_COPY_AND_ASSIGN_(TestInfo); -}; - -// A test case, which consists of a vector of TestInfos. -// -// TestCase is not copyable. -class GTEST_API_ TestCase { - public: - // Creates a TestCase with the given name. - // - // TestCase does NOT have a default constructor. Always use this - // constructor to create a TestCase object. - // - // Arguments: - // - // name: name of the test case - // a_type_param: the name of the test's type parameter, or NULL if - // this is not a type-parameterized test. - // set_up_tc: pointer to the function that sets up the test case - // tear_down_tc: pointer to the function that tears down the test case - TestCase(const char* name, const char* a_type_param, - Test::SetUpTestCaseFunc set_up_tc, - Test::TearDownTestCaseFunc tear_down_tc); - - // Destructor of TestCase. - virtual ~TestCase(); - - // Gets the name of the TestCase. - const char* name() const { return name_.c_str(); } - - // Returns the name of the parameter type, or NULL if this is not a - // type-parameterized test case. - const char* type_param() const { - if (type_param_.get() != NULL) - return type_param_->c_str(); - return NULL; - } - - // Returns true if any test in this test case should run. - bool should_run() const { return should_run_; } - - // Gets the number of successful tests in this test case. - int successful_test_count() const; - - // Gets the number of failed tests in this test case. - int failed_test_count() const; - - // Gets the number of disabled tests that will be reported in the XML report. - int reportable_disabled_test_count() const; - - // Gets the number of disabled tests in this test case. - int disabled_test_count() const; - - // Gets the number of tests to be printed in the XML report. - int reportable_test_count() const; - - // Get the number of tests in this test case that should run. - int test_to_run_count() const; - - // Gets the number of all tests in this test case. - int total_test_count() const; - - // Returns true iff the test case passed. - bool Passed() const { return !Failed(); } - - // Returns true iff the test case failed. - bool Failed() const { return failed_test_count() > 0; } - - // Returns the elapsed time, in milliseconds. - TimeInMillis elapsed_time() const { return elapsed_time_; } - - // Returns the i-th test among all the tests. i can range from 0 to - // total_test_count() - 1. If i is not in that range, returns NULL. - const TestInfo* GetTestInfo(int i) const; - - // Returns the TestResult that holds test properties recorded during - // execution of SetUpTestCase and TearDownTestCase. - const TestResult& ad_hoc_test_result() const { return ad_hoc_test_result_; } - - private: - friend class Test; - friend class internal::UnitTestImpl; - - // Gets the (mutable) vector of TestInfos in this TestCase. - std::vector& test_info_list() { return test_info_list_; } - - // Gets the (immutable) vector of TestInfos in this TestCase. - const std::vector& test_info_list() const { - return test_info_list_; - } - - // Returns the i-th test among all the tests. i can range from 0 to - // total_test_count() - 1. If i is not in that range, returns NULL. - TestInfo* GetMutableTestInfo(int i); - - // Sets the should_run member. - void set_should_run(bool should) { should_run_ = should; } - - // Adds a TestInfo to this test case. Will delete the TestInfo upon - // destruction of the TestCase object. - void AddTestInfo(TestInfo * test_info); - - // Clears the results of all tests in this test case. - void ClearResult(); - - // Clears the results of all tests in the given test case. - static void ClearTestCaseResult(TestCase* test_case) { - test_case->ClearResult(); - } - - // Runs every test in this TestCase. - void Run(); - - // Runs SetUpTestCase() for this TestCase. This wrapper is needed - // for catching exceptions thrown from SetUpTestCase(). - void RunSetUpTestCase() { (*set_up_tc_)(); } - - // Runs TearDownTestCase() for this TestCase. This wrapper is - // needed for catching exceptions thrown from TearDownTestCase(). - void RunTearDownTestCase() { (*tear_down_tc_)(); } - - // Returns true iff test passed. - static bool TestPassed(const TestInfo* test_info) { - return test_info->should_run() && test_info->result()->Passed(); - } - - // Returns true iff test failed. - static bool TestFailed(const TestInfo* test_info) { - return test_info->should_run() && test_info->result()->Failed(); - } - - // Returns true iff the test is disabled and will be reported in the XML - // report. - static bool TestReportableDisabled(const TestInfo* test_info) { - return test_info->is_reportable() && test_info->is_disabled_; - } - - // Returns true iff test is disabled. - static bool TestDisabled(const TestInfo* test_info) { - return test_info->is_disabled_; - } - - // Returns true iff this test will appear in the XML report. - static bool TestReportable(const TestInfo* test_info) { - return test_info->is_reportable(); - } - - // Returns true if the given test should run. - static bool ShouldRunTest(const TestInfo* test_info) { - return test_info->should_run(); - } - - // Shuffles the tests in this test case. - void ShuffleTests(internal::Random* random); - - // Restores the test order to before the first shuffle. - void UnshuffleTests(); - - // Name of the test case. - std::string name_; - // Name of the parameter type, or NULL if this is not a typed or a - // type-parameterized test. - const internal::scoped_ptr type_param_; - // The vector of TestInfos in their original order. It owns the - // elements in the vector. - std::vector test_info_list_; - // Provides a level of indirection for the test list to allow easy - // shuffling and restoring the test order. The i-th element in this - // vector is the index of the i-th test in the shuffled test list. - std::vector test_indices_; - // Pointer to the function that sets up the test case. - Test::SetUpTestCaseFunc set_up_tc_; - // Pointer to the function that tears down the test case. - Test::TearDownTestCaseFunc tear_down_tc_; - // True iff any test in this test case should run. - bool should_run_; - // Elapsed time, in milliseconds. - TimeInMillis elapsed_time_; - // Holds test properties recorded during execution of SetUpTestCase and - // TearDownTestCase. - TestResult ad_hoc_test_result_; - - // We disallow copying TestCases. - GTEST_DISALLOW_COPY_AND_ASSIGN_(TestCase); -}; - -// An Environment object is capable of setting up and tearing down an -// environment. The user should subclass this to define his own -// environment(s). -// -// An Environment object does the set-up and tear-down in virtual -// methods SetUp() and TearDown() instead of the constructor and the -// destructor, as: -// -// 1. You cannot safely throw from a destructor. This is a problem -// as in some cases Google Test is used where exceptions are enabled, and -// we may want to implement ASSERT_* using exceptions where they are -// available. -// 2. You cannot use ASSERT_* directly in a constructor or -// destructor. -class Environment { - public: - // The d'tor is virtual as we need to subclass Environment. - virtual ~Environment() {} - - // Override this to define how to set up the environment. - virtual void SetUp() {} - - // Override this to define how to tear down the environment. - virtual void TearDown() {} - private: - // If you see an error about overriding the following function or - // about it being private, you have mis-spelled SetUp() as Setup(). - struct Setup_should_be_spelled_SetUp {}; - virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; } -}; - -// The interface for tracing execution of tests. The methods are organized in -// the order the corresponding events are fired. -class TestEventListener { - public: - virtual ~TestEventListener() {} - - // Fired before any test activity starts. - virtual void OnTestProgramStart(const UnitTest& unit_test) = 0; - - // Fired before each iteration of tests starts. There may be more than - // one iteration if GTEST_FLAG(repeat) is set. iteration is the iteration - // index, starting from 0. - virtual void OnTestIterationStart(const UnitTest& unit_test, - int iteration) = 0; - - // Fired before environment set-up for each iteration of tests starts. - virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test) = 0; - - // Fired after environment set-up for each iteration of tests ends. - virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test) = 0; - - // Fired before the test case starts. - virtual void OnTestCaseStart(const TestCase& test_case) = 0; - - // Fired before the test starts. - virtual void OnTestStart(const TestInfo& test_info) = 0; - - // Fired after a failed assertion or a SUCCEED() invocation. - virtual void OnTestPartResult(const TestPartResult& test_part_result) = 0; - - // Fired after the test ends. - virtual void OnTestEnd(const TestInfo& test_info) = 0; - - // Fired after the test case ends. - virtual void OnTestCaseEnd(const TestCase& test_case) = 0; - - // Fired before environment tear-down for each iteration of tests starts. - virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test) = 0; - - // Fired after environment tear-down for each iteration of tests ends. - virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test) = 0; - - // Fired after each iteration of tests finishes. - virtual void OnTestIterationEnd(const UnitTest& unit_test, - int iteration) = 0; - - // Fired after all test activities have ended. - virtual void OnTestProgramEnd(const UnitTest& unit_test) = 0; -}; - -// The convenience class for users who need to override just one or two -// methods and are not concerned that a possible change to a signature of -// the methods they override will not be caught during the build. For -// comments about each method please see the definition of TestEventListener -// above. -class EmptyTestEventListener : public TestEventListener { - public: - virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {} - virtual void OnTestIterationStart(const UnitTest& /*unit_test*/, - int /*iteration*/) {} - virtual void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) {} - virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {} - virtual void OnTestCaseStart(const TestCase& /*test_case*/) {} - virtual void OnTestStart(const TestInfo& /*test_info*/) {} - virtual void OnTestPartResult(const TestPartResult& /*test_part_result*/) {} - virtual void OnTestEnd(const TestInfo& /*test_info*/) {} - virtual void OnTestCaseEnd(const TestCase& /*test_case*/) {} - virtual void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) {} - virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {} - virtual void OnTestIterationEnd(const UnitTest& /*unit_test*/, - int /*iteration*/) {} - virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {} -}; - -// TestEventListeners lets users add listeners to track events in Google Test. -class GTEST_API_ TestEventListeners { - public: - TestEventListeners(); - ~TestEventListeners(); - - // Appends an event listener to the end of the list. Google Test assumes - // the ownership of the listener (i.e. it will delete the listener when - // the test program finishes). - void Append(TestEventListener* listener); - - // Removes the given event listener from the list and returns it. It then - // becomes the caller's responsibility to delete the listener. Returns - // NULL if the listener is not found in the list. - TestEventListener* Release(TestEventListener* listener); - - // Returns the standard listener responsible for the default console - // output. Can be removed from the listeners list to shut down default - // console output. Note that removing this object from the listener list - // with Release transfers its ownership to the caller and makes this - // function return NULL the next time. - TestEventListener* default_result_printer() const { - return default_result_printer_; - } - - // Returns the standard listener responsible for the default XML output - // controlled by the --gtest_output=xml flag. Can be removed from the - // listeners list by users who want to shut down the default XML output - // controlled by this flag and substitute it with custom one. Note that - // removing this object from the listener list with Release transfers its - // ownership to the caller and makes this function return NULL the next - // time. - TestEventListener* default_xml_generator() const { - return default_xml_generator_; - } - - private: - friend class TestCase; - friend class TestInfo; - friend class internal::DefaultGlobalTestPartResultReporter; - friend class internal::NoExecDeathTest; - friend class internal::TestEventListenersAccessor; - friend class internal::UnitTestImpl; - - // Returns repeater that broadcasts the TestEventListener events to all - // subscribers. - TestEventListener* repeater(); - - // Sets the default_result_printer attribute to the provided listener. - // The listener is also added to the listener list and previous - // default_result_printer is removed from it and deleted. The listener can - // also be NULL in which case it will not be added to the list. Does - // nothing if the previous and the current listener objects are the same. - void SetDefaultResultPrinter(TestEventListener* listener); - - // Sets the default_xml_generator attribute to the provided listener. The - // listener is also added to the listener list and previous - // default_xml_generator is removed from it and deleted. The listener can - // also be NULL in which case it will not be added to the list. Does - // nothing if the previous and the current listener objects are the same. - void SetDefaultXmlGenerator(TestEventListener* listener); - - // Controls whether events will be forwarded by the repeater to the - // listeners in the list. - bool EventForwardingEnabled() const; - void SuppressEventForwarding(); - - // The actual list of listeners. - internal::TestEventRepeater* repeater_; - // Listener responsible for the standard result output. - TestEventListener* default_result_printer_; - // Listener responsible for the creation of the XML output file. - TestEventListener* default_xml_generator_; - - // We disallow copying TestEventListeners. - GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventListeners); -}; - -// A UnitTest consists of a vector of TestCases. -// -// This is a singleton class. The only instance of UnitTest is -// created when UnitTest::GetInstance() is first called. This -// instance is never deleted. -// -// UnitTest is not copyable. -// -// This class is thread-safe as long as the methods are called -// according to their specification. -class GTEST_API_ UnitTest { - public: - // Gets the singleton UnitTest object. The first time this method - // is called, a UnitTest object is constructed and returned. - // Consecutive calls will return the same object. - static UnitTest* GetInstance(); - - // Runs all tests in this UnitTest object and prints the result. - // Returns 0 if successful, or 1 otherwise. - // - // This method can only be called from the main thread. - // - // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. - int Run() GTEST_MUST_USE_RESULT_; - - // Returns the working directory when the first TEST() or TEST_F() - // was executed. The UnitTest object owns the string. - const char* original_working_dir() const; - - // Returns the TestCase object for the test that's currently running, - // or NULL if no test is running. - const TestCase* current_test_case() const - GTEST_LOCK_EXCLUDED_(mutex_); - - // Returns the TestInfo object for the test that's currently running, - // or NULL if no test is running. - const TestInfo* current_test_info() const - GTEST_LOCK_EXCLUDED_(mutex_); - - // Returns the random seed used at the start of the current test run. - int random_seed() const; - -#if GTEST_HAS_PARAM_TEST - // Returns the ParameterizedTestCaseRegistry object used to keep track of - // value-parameterized tests and instantiate and register them. - // - // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. - internal::ParameterizedTestCaseRegistry& parameterized_test_registry() - GTEST_LOCK_EXCLUDED_(mutex_); -#endif // GTEST_HAS_PARAM_TEST - - // Gets the number of successful test cases. - int successful_test_case_count() const; - - // Gets the number of failed test cases. - int failed_test_case_count() const; - - // Gets the number of all test cases. - int total_test_case_count() const; - - // Gets the number of all test cases that contain at least one test - // that should run. - int test_case_to_run_count() const; - - // Gets the number of successful tests. - int successful_test_count() const; - - // Gets the number of failed tests. - int failed_test_count() const; - - // Gets the number of disabled tests that will be reported in the XML report. - int reportable_disabled_test_count() const; - - // Gets the number of disabled tests. - int disabled_test_count() const; - - // Gets the number of tests to be printed in the XML report. - int reportable_test_count() const; - - // Gets the number of all tests. - int total_test_count() const; - - // Gets the number of tests that should run. - int test_to_run_count() const; - - // Gets the time of the test program start, in ms from the start of the - // UNIX epoch. - TimeInMillis start_timestamp() const; - - // Gets the elapsed time, in milliseconds. - TimeInMillis elapsed_time() const; - - // Returns true iff the unit test passed (i.e. all test cases passed). - bool Passed() const; - - // Returns true iff the unit test failed (i.e. some test case failed - // or something outside of all tests failed). - bool Failed() const; - - // Gets the i-th test case among all the test cases. i can range from 0 to - // total_test_case_count() - 1. If i is not in that range, returns NULL. - const TestCase* GetTestCase(int i) const; - - // Returns the TestResult containing information on test failures and - // properties logged outside of individual test cases. - const TestResult& ad_hoc_test_result() const; - - // Returns the list of event listeners that can be used to track events - // inside Google Test. - TestEventListeners& listeners(); - - private: - // Registers and returns a global test environment. When a test - // program is run, all global test environments will be set-up in - // the order they were registered. After all tests in the program - // have finished, all global test environments will be torn-down in - // the *reverse* order they were registered. - // - // The UnitTest object takes ownership of the given environment. - // - // This method can only be called from the main thread. - Environment* AddEnvironment(Environment* env); - - // Adds a TestPartResult to the current TestResult object. All - // Google Test assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) - // eventually call this to report their results. The user code - // should use the assertion macros instead of calling this directly. - void AddTestPartResult(TestPartResult::Type result_type, - const char* file_name, - int line_number, - const std::string& message, - const std::string& os_stack_trace) - GTEST_LOCK_EXCLUDED_(mutex_); - - // Adds a TestProperty to the current TestResult object when invoked from - // inside a test, to current TestCase's ad_hoc_test_result_ when invoked - // from SetUpTestCase or TearDownTestCase, or to the global property set - // when invoked elsewhere. If the result already contains a property with - // the same key, the value will be updated. - void RecordProperty(const std::string& key, const std::string& value); - - // Gets the i-th test case among all the test cases. i can range from 0 to - // total_test_case_count() - 1. If i is not in that range, returns NULL. - TestCase* GetMutableTestCase(int i); - - // Accessors for the implementation object. - internal::UnitTestImpl* impl() { return impl_; } - const internal::UnitTestImpl* impl() const { return impl_; } - - // These classes and funcions are friends as they need to access private - // members of UnitTest. - friend class Test; - friend class internal::AssertHelper; - friend class internal::ScopedTrace; - friend class internal::StreamingListenerTest; - friend class internal::UnitTestRecordPropertyTestHelper; - friend Environment* AddGlobalTestEnvironment(Environment* env); - friend internal::UnitTestImpl* internal::GetUnitTestImpl(); - friend void internal::ReportFailureInUnknownLocation( - TestPartResult::Type result_type, - const std::string& message); - - // Creates an empty UnitTest. - UnitTest(); - - // D'tor - virtual ~UnitTest(); - - // Pushes a trace defined by SCOPED_TRACE() on to the per-thread - // Google Test trace stack. - void PushGTestTrace(const internal::TraceInfo& trace) - GTEST_LOCK_EXCLUDED_(mutex_); - - // Pops a trace from the per-thread Google Test trace stack. - void PopGTestTrace() - GTEST_LOCK_EXCLUDED_(mutex_); - - // Protects mutable state in *impl_. This is mutable as some const - // methods need to lock it too. - mutable internal::Mutex mutex_; - - // Opaque implementation object. This field is never changed once - // the object is constructed. We don't mark it as const here, as - // doing so will cause a warning in the constructor of UnitTest. - // Mutable state in *impl_ is protected by mutex_. - internal::UnitTestImpl* impl_; - - // We disallow copying UnitTest. - GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTest); -}; - -// A convenient wrapper for adding an environment for the test -// program. -// -// You should call this before RUN_ALL_TESTS() is called, probably in -// main(). If you use gtest_main, you need to call this before main() -// starts for it to take effect. For example, you can define a global -// variable like this: -// -// testing::Environment* const foo_env = -// testing::AddGlobalTestEnvironment(new FooEnvironment); -// -// However, we strongly recommend you to write your own main() and -// call AddGlobalTestEnvironment() there, as relying on initialization -// of global variables makes the code harder to read and may cause -// problems when you register multiple environments from different -// translation units and the environments have dependencies among them -// (remember that the compiler doesn't guarantee the order in which -// global variables from different translation units are initialized). -inline Environment* AddGlobalTestEnvironment(Environment* env) { - return UnitTest::GetInstance()->AddEnvironment(env); -} - -// Initializes Google Test. This must be called before calling -// RUN_ALL_TESTS(). In particular, it parses a command line for the -// flags that Google Test recognizes. Whenever a Google Test flag is -// seen, it is removed from argv, and *argc is decremented. -// -// No value is returned. Instead, the Google Test flag variables are -// updated. -// -// Calling the function for the second time has no user-visible effect. -GTEST_API_ void InitGoogleTest(int* argc, char** argv); - -// This overloaded version can be used in Windows programs compiled in -// UNICODE mode. -GTEST_API_ void InitGoogleTest(int* argc, wchar_t** argv); - -namespace internal { - -// FormatForComparison::Format(value) formats a -// value of type ToPrint that is an operand of a comparison assertion -// (e.g. ASSERT_EQ). OtherOperand is the type of the other operand in -// the comparison, and is used to help determine the best way to -// format the value. In particular, when the value is a C string -// (char pointer) and the other operand is an STL string object, we -// want to format the C string as a string, since we know it is -// compared by value with the string object. If the value is a char -// pointer but the other operand is not an STL string object, we don't -// know whether the pointer is supposed to point to a NUL-terminated -// string, and thus want to print it as a pointer to be safe. -// -// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. - -// The default case. -template -class FormatForComparison { - public: - static ::std::string Format(const ToPrint& value) { - return ::testing::PrintToString(value); - } -}; - -// Array. -template -class FormatForComparison { - public: - static ::std::string Format(const ToPrint* value) { - return FormatForComparison::Format(value); - } -}; - -// By default, print C string as pointers to be safe, as we don't know -// whether they actually point to a NUL-terminated string. - -#define GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(CharType) \ - template \ - class FormatForComparison { \ - public: \ - static ::std::string Format(CharType* value) { \ - return ::testing::PrintToString(static_cast(value)); \ - } \ - } - -GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char); -GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char); -GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(wchar_t); -GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const wchar_t); - -#undef GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_ - -// If a C string is compared with an STL string object, we know it's meant -// to point to a NUL-terminated string, and thus can print it as a string. - -#define GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(CharType, OtherStringType) \ - template <> \ - class FormatForComparison { \ - public: \ - static ::std::string Format(CharType* value) { \ - return ::testing::PrintToString(value); \ - } \ - } - -GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char, ::std::string); -GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char, ::std::string); - -#if GTEST_HAS_GLOBAL_STRING -GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char, ::string); -GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char, ::string); -#endif - -#if GTEST_HAS_GLOBAL_WSTRING -GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(wchar_t, ::wstring); -GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const wchar_t, ::wstring); -#endif - -#if GTEST_HAS_STD_WSTRING -GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(wchar_t, ::std::wstring); -GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const wchar_t, ::std::wstring); -#endif - -#undef GTEST_IMPL_FORMAT_C_STRING_AS_STRING_ - -// Formats a comparison assertion (e.g. ASSERT_EQ, EXPECT_LT, and etc) -// operand to be used in a failure message. The type (but not value) -// of the other operand may affect the format. This allows us to -// print a char* as a raw pointer when it is compared against another -// char* or void*, and print it as a C string when it is compared -// against an std::string object, for example. -// -// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. -template -std::string FormatForComparisonFailureMessage( - const T1& value, const T2& /* other_operand */) { - return FormatForComparison::Format(value); -} - -// The helper function for {ASSERT|EXPECT}_EQ. -template -AssertionResult CmpHelperEQ(const char* expected_expression, - const char* actual_expression, - const T1& expected, - const T2& actual) { -#ifdef _MSC_VER -# pragma warning(push) // Saves the current warning state. -# pragma warning(disable:4389) // Temporarily disables warning on - // signed/unsigned mismatch. -#endif - - if (expected == actual) { - return AssertionSuccess(); - } - -#ifdef _MSC_VER -# pragma warning(pop) // Restores the warning state. -#endif - - return EqFailure(expected_expression, - actual_expression, - FormatForComparisonFailureMessage(expected, actual), - FormatForComparisonFailureMessage(actual, expected), - false); -} - -// With this overloaded version, we allow anonymous enums to be used -// in {ASSERT|EXPECT}_EQ when compiled with gcc 4, as anonymous enums -// can be implicitly cast to BiggestInt. -GTEST_API_ AssertionResult CmpHelperEQ(const char* expected_expression, - const char* actual_expression, - BiggestInt expected, - BiggestInt actual); - -// The helper class for {ASSERT|EXPECT}_EQ. The template argument -// lhs_is_null_literal is true iff the first argument to ASSERT_EQ() -// is a null pointer literal. The following default implementation is -// for lhs_is_null_literal being false. -template -class EqHelper { - public: - // This templatized version is for the general case. - template - static AssertionResult Compare(const char* expected_expression, - const char* actual_expression, - const T1& expected, - const T2& actual) { - return CmpHelperEQ(expected_expression, actual_expression, expected, - actual); - } - - // With this overloaded version, we allow anonymous enums to be used - // in {ASSERT|EXPECT}_EQ when compiled with gcc 4, as anonymous - // enums can be implicitly cast to BiggestInt. - // - // Even though its body looks the same as the above version, we - // cannot merge the two, as it will make anonymous enums unhappy. - static AssertionResult Compare(const char* expected_expression, - const char* actual_expression, - BiggestInt expected, - BiggestInt actual) { - return CmpHelperEQ(expected_expression, actual_expression, expected, - actual); - } -}; - -// This specialization is used when the first argument to ASSERT_EQ() -// is a null pointer literal, like NULL, false, or 0. -template <> -class EqHelper { - public: - // We define two overloaded versions of Compare(). The first - // version will be picked when the second argument to ASSERT_EQ() is - // NOT a pointer, e.g. ASSERT_EQ(0, AnIntFunction()) or - // EXPECT_EQ(false, a_bool). - template - static AssertionResult Compare( - const char* expected_expression, - const char* actual_expression, - const T1& expected, - const T2& actual, - // The following line prevents this overload from being considered if T2 - // is not a pointer type. We need this because ASSERT_EQ(NULL, my_ptr) - // expands to Compare("", "", NULL, my_ptr), which requires a conversion - // to match the Secret* in the other overload, which would otherwise make - // this template match better. - typename EnableIf::value>::type* = 0) { - return CmpHelperEQ(expected_expression, actual_expression, expected, - actual); - } - - // This version will be picked when the second argument to ASSERT_EQ() is a - // pointer, e.g. ASSERT_EQ(NULL, a_pointer). - template - static AssertionResult Compare( - const char* expected_expression, - const char* actual_expression, - // We used to have a second template parameter instead of Secret*. That - // template parameter would deduce to 'long', making this a better match - // than the first overload even without the first overload's EnableIf. - // Unfortunately, gcc with -Wconversion-null warns when "passing NULL to - // non-pointer argument" (even a deduced integral argument), so the old - // implementation caused warnings in user code. - Secret* /* expected (NULL) */, - T* actual) { - // We already know that 'expected' is a null pointer. - return CmpHelperEQ(expected_expression, actual_expression, - static_cast(NULL), actual); - } -}; - -// A macro for implementing the helper functions needed to implement -// ASSERT_?? and EXPECT_??. It is here just to avoid copy-and-paste -// of similar code. -// -// For each templatized helper function, we also define an overloaded -// version for BiggestInt in order to reduce code bloat and allow -// anonymous enums to be used with {ASSERT|EXPECT}_?? when compiled -// with gcc 4. -// -// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. -#define GTEST_IMPL_CMP_HELPER_(op_name, op)\ -template \ -AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \ - const T1& val1, const T2& val2) {\ - if (val1 op val2) {\ - return AssertionSuccess();\ - } else {\ - return AssertionFailure() \ - << "Expected: (" << expr1 << ") " #op " (" << expr2\ - << "), actual: " << FormatForComparisonFailureMessage(val1, val2)\ - << " vs " << FormatForComparisonFailureMessage(val2, val1);\ - }\ -}\ -GTEST_API_ AssertionResult CmpHelper##op_name(\ - const char* expr1, const char* expr2, BiggestInt val1, BiggestInt val2) - -// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. - -// Implements the helper function for {ASSERT|EXPECT}_NE -GTEST_IMPL_CMP_HELPER_(NE, !=); -// Implements the helper function for {ASSERT|EXPECT}_LE -GTEST_IMPL_CMP_HELPER_(LE, <=); -// Implements the helper function for {ASSERT|EXPECT}_LT -GTEST_IMPL_CMP_HELPER_(LT, <); -// Implements the helper function for {ASSERT|EXPECT}_GE -GTEST_IMPL_CMP_HELPER_(GE, >=); -// Implements the helper function for {ASSERT|EXPECT}_GT -GTEST_IMPL_CMP_HELPER_(GT, >); - -#undef GTEST_IMPL_CMP_HELPER_ - -// The helper function for {ASSERT|EXPECT}_STREQ. -// -// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. -GTEST_API_ AssertionResult CmpHelperSTREQ(const char* expected_expression, - const char* actual_expression, - const char* expected, - const char* actual); - -// The helper function for {ASSERT|EXPECT}_STRCASEEQ. -// -// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. -GTEST_API_ AssertionResult CmpHelperSTRCASEEQ(const char* expected_expression, - const char* actual_expression, - const char* expected, - const char* actual); - -// The helper function for {ASSERT|EXPECT}_STRNE. -// -// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. -GTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression, - const char* s2_expression, - const char* s1, - const char* s2); - -// The helper function for {ASSERT|EXPECT}_STRCASENE. -// -// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. -GTEST_API_ AssertionResult CmpHelperSTRCASENE(const char* s1_expression, - const char* s2_expression, - const char* s1, - const char* s2); - - -// Helper function for *_STREQ on wide strings. -// -// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. -GTEST_API_ AssertionResult CmpHelperSTREQ(const char* expected_expression, - const char* actual_expression, - const wchar_t* expected, - const wchar_t* actual); - -// Helper function for *_STRNE on wide strings. -// -// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. -GTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression, - const char* s2_expression, - const wchar_t* s1, - const wchar_t* s2); - -} // namespace internal - -// IsSubstring() and IsNotSubstring() are intended to be used as the -// first argument to {EXPECT,ASSERT}_PRED_FORMAT2(), not by -// themselves. They check whether needle is a substring of haystack -// (NULL is considered a substring of itself only), and return an -// appropriate error message when they fail. -// -// The {needle,haystack}_expr arguments are the stringified -// expressions that generated the two real arguments. -GTEST_API_ AssertionResult IsSubstring( - const char* needle_expr, const char* haystack_expr, - const char* needle, const char* haystack); -GTEST_API_ AssertionResult IsSubstring( - const char* needle_expr, const char* haystack_expr, - const wchar_t* needle, const wchar_t* haystack); -GTEST_API_ AssertionResult IsNotSubstring( - const char* needle_expr, const char* haystack_expr, - const char* needle, const char* haystack); -GTEST_API_ AssertionResult IsNotSubstring( - const char* needle_expr, const char* haystack_expr, - const wchar_t* needle, const wchar_t* haystack); -GTEST_API_ AssertionResult IsSubstring( - const char* needle_expr, const char* haystack_expr, - const ::std::string& needle, const ::std::string& haystack); -GTEST_API_ AssertionResult IsNotSubstring( - const char* needle_expr, const char* haystack_expr, - const ::std::string& needle, const ::std::string& haystack); - -#if GTEST_HAS_STD_WSTRING -GTEST_API_ AssertionResult IsSubstring( - const char* needle_expr, const char* haystack_expr, - const ::std::wstring& needle, const ::std::wstring& haystack); -GTEST_API_ AssertionResult IsNotSubstring( - const char* needle_expr, const char* haystack_expr, - const ::std::wstring& needle, const ::std::wstring& haystack); -#endif // GTEST_HAS_STD_WSTRING - -namespace internal { - -// Helper template function for comparing floating-points. -// -// Template parameter: -// -// RawType: the raw floating-point type (either float or double) -// -// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. -template -AssertionResult CmpHelperFloatingPointEQ(const char* expected_expression, - const char* actual_expression, - RawType expected, - RawType actual) { - const FloatingPoint lhs(expected), rhs(actual); - - if (lhs.AlmostEquals(rhs)) { - return AssertionSuccess(); - } - - ::std::stringstream expected_ss; - expected_ss << std::setprecision(std::numeric_limits::digits10 + 2) - << expected; - - ::std::stringstream actual_ss; - actual_ss << std::setprecision(std::numeric_limits::digits10 + 2) - << actual; - - return EqFailure(expected_expression, - actual_expression, - StringStreamToString(&expected_ss), - StringStreamToString(&actual_ss), - false); -} - -// Helper function for implementing ASSERT_NEAR. -// -// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. -GTEST_API_ AssertionResult DoubleNearPredFormat(const char* expr1, - const char* expr2, - const char* abs_error_expr, - double val1, - double val2, - double abs_error); - -// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. -// A class that enables one to stream messages to assertion macros -class GTEST_API_ AssertHelper { - public: - // Constructor. - AssertHelper(TestPartResult::Type type, - const char* file, - int line, - const char* message); - ~AssertHelper(); - - // Message assignment is a semantic trick to enable assertion - // streaming; see the GTEST_MESSAGE_ macro below. - void operator=(const Message& message) const; - - private: - // We put our data in a struct so that the size of the AssertHelper class can - // be as small as possible. This is important because gcc is incapable of - // re-using stack space even for temporary variables, so every EXPECT_EQ - // reserves stack space for another AssertHelper. - struct AssertHelperData { - AssertHelperData(TestPartResult::Type t, - const char* srcfile, - int line_num, - const char* msg) - : type(t), file(srcfile), line(line_num), message(msg) { } - - TestPartResult::Type const type; - const char* const file; - int const line; - std::string const message; - - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelperData); - }; - - AssertHelperData* const data_; - - GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelper); -}; - -} // namespace internal - -#if GTEST_HAS_PARAM_TEST -// The pure interface class that all value-parameterized tests inherit from. -// A value-parameterized class must inherit from both ::testing::Test and -// ::testing::WithParamInterface. In most cases that just means inheriting -// from ::testing::TestWithParam, but more complicated test hierarchies -// may need to inherit from Test and WithParamInterface at different levels. -// -// This interface has support for accessing the test parameter value via -// the GetParam() method. -// -// Use it with one of the parameter generator defining functions, like Range(), -// Values(), ValuesIn(), Bool(), and Combine(). -// -// class FooTest : public ::testing::TestWithParam { -// protected: -// FooTest() { -// // Can use GetParam() here. -// } -// virtual ~FooTest() { -// // Can use GetParam() here. -// } -// virtual void SetUp() { -// // Can use GetParam() here. -// } -// virtual void TearDown { -// // Can use GetParam() here. -// } -// }; -// TEST_P(FooTest, DoesBar) { -// // Can use GetParam() method here. -// Foo foo; -// ASSERT_TRUE(foo.DoesBar(GetParam())); -// } -// INSTANTIATE_TEST_CASE_P(OneToTenRange, FooTest, ::testing::Range(1, 10)); - -template -class WithParamInterface { - public: - typedef T ParamType; - virtual ~WithParamInterface() {} - - // The current parameter value. Is also available in the test fixture's - // constructor. This member function is non-static, even though it only - // references static data, to reduce the opportunity for incorrect uses - // like writing 'WithParamInterface::GetParam()' for a test that - // uses a fixture whose parameter type is int. - const ParamType& GetParam() const { - GTEST_CHECK_(parameter_ != NULL) - << "GetParam() can only be called inside a value-parameterized test " - << "-- did you intend to write TEST_P instead of TEST_F?"; - return *parameter_; - } - - private: - // Sets parameter value. The caller is responsible for making sure the value - // remains alive and unchanged throughout the current test. - static void SetParam(const ParamType* parameter) { - parameter_ = parameter; - } - - // Static value used for accessing parameter during a test lifetime. - static const ParamType* parameter_; - - // TestClass must be a subclass of WithParamInterface and Test. - template friend class internal::ParameterizedTestFactory; -}; - -template -const T* WithParamInterface::parameter_ = NULL; - -// Most value-parameterized classes can ignore the existence of -// WithParamInterface, and can just inherit from ::testing::TestWithParam. - -template -class TestWithParam : public Test, public WithParamInterface { -}; - -#endif // GTEST_HAS_PARAM_TEST - -// Macros for indicating success/failure in test code. - -// ADD_FAILURE unconditionally adds a failure to the current test. -// SUCCEED generates a success - it doesn't automatically make the -// current test successful, as a test is only successful when it has -// no failure. -// -// EXPECT_* verifies that a certain condition is satisfied. If not, -// it behaves like ADD_FAILURE. In particular: -// -// EXPECT_TRUE verifies that a Boolean condition is true. -// EXPECT_FALSE verifies that a Boolean condition is false. -// -// FAIL and ASSERT_* are similar to ADD_FAILURE and EXPECT_*, except -// that they will also abort the current function on failure. People -// usually want the fail-fast behavior of FAIL and ASSERT_*, but those -// writing data-driven tests often find themselves using ADD_FAILURE -// and EXPECT_* more. - -// Generates a nonfatal failure with a generic message. -#define ADD_FAILURE() GTEST_NONFATAL_FAILURE_("Failed") - -// Generates a nonfatal failure at the given source file location with -// a generic message. -#define ADD_FAILURE_AT(file, line) \ - GTEST_MESSAGE_AT_(file, line, "Failed", \ - ::testing::TestPartResult::kNonFatalFailure) - -// Generates a fatal failure with a generic message. -#define GTEST_FAIL() GTEST_FATAL_FAILURE_("Failed") - -// Define this macro to 1 to omit the definition of FAIL(), which is a -// generic name and clashes with some other libraries. -#if !GTEST_DONT_DEFINE_FAIL -# define FAIL() GTEST_FAIL() -#endif - -// Generates a success with a generic message. -#define GTEST_SUCCEED() GTEST_SUCCESS_("Succeeded") - -// Define this macro to 1 to omit the definition of SUCCEED(), which -// is a generic name and clashes with some other libraries. -#if !GTEST_DONT_DEFINE_SUCCEED -# define SUCCEED() GTEST_SUCCEED() -#endif - -// Macros for testing exceptions. -// -// * {ASSERT|EXPECT}_THROW(statement, expected_exception): -// Tests that the statement throws the expected exception. -// * {ASSERT|EXPECT}_NO_THROW(statement): -// Tests that the statement doesn't throw any exception. -// * {ASSERT|EXPECT}_ANY_THROW(statement): -// Tests that the statement throws an exception. - -#define EXPECT_THROW(statement, expected_exception) \ - GTEST_TEST_THROW_(statement, expected_exception, GTEST_NONFATAL_FAILURE_) -#define EXPECT_NO_THROW(statement) \ - GTEST_TEST_NO_THROW_(statement, GTEST_NONFATAL_FAILURE_) -#define EXPECT_ANY_THROW(statement) \ - GTEST_TEST_ANY_THROW_(statement, GTEST_NONFATAL_FAILURE_) -#define ASSERT_THROW(statement, expected_exception) \ - GTEST_TEST_THROW_(statement, expected_exception, GTEST_FATAL_FAILURE_) -#define ASSERT_NO_THROW(statement) \ - GTEST_TEST_NO_THROW_(statement, GTEST_FATAL_FAILURE_) -#define ASSERT_ANY_THROW(statement) \ - GTEST_TEST_ANY_THROW_(statement, GTEST_FATAL_FAILURE_) - -// Boolean assertions. Condition can be either a Boolean expression or an -// AssertionResult. For more information on how to use AssertionResult with -// these macros see comments on that class. -#define EXPECT_TRUE(condition) \ - GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \ - GTEST_NONFATAL_FAILURE_) -#define EXPECT_FALSE(condition) \ - GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \ - GTEST_NONFATAL_FAILURE_) -#define ASSERT_TRUE(condition) \ - GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \ - GTEST_FATAL_FAILURE_) -#define ASSERT_FALSE(condition) \ - GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \ - GTEST_FATAL_FAILURE_) - -// Includes the auto-generated header that implements a family of -// generic predicate assertion macros. -// Copyright 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// This file is AUTOMATICALLY GENERATED on 10/31/2011 by command -// 'gen_gtest_pred_impl.py 5'. DO NOT EDIT BY HAND! -// -// Implements a family of generic predicate assertion macros. - -#ifndef GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ -#define GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ - -// Makes sure this header is not included before gtest.h. -#ifndef GTEST_INCLUDE_GTEST_GTEST_H_ -# error Do not include gtest_pred_impl.h directly. Include gtest.h instead. -#endif // GTEST_INCLUDE_GTEST_GTEST_H_ - -// This header implements a family of generic predicate assertion -// macros: -// -// ASSERT_PRED_FORMAT1(pred_format, v1) -// ASSERT_PRED_FORMAT2(pred_format, v1, v2) -// ... -// -// where pred_format is a function or functor that takes n (in the -// case of ASSERT_PRED_FORMATn) values and their source expression -// text, and returns a testing::AssertionResult. See the definition -// of ASSERT_EQ in gtest.h for an example. -// -// If you don't care about formatting, you can use the more -// restrictive version: -// -// ASSERT_PRED1(pred, v1) -// ASSERT_PRED2(pred, v1, v2) -// ... -// -// where pred is an n-ary function or functor that returns bool, -// and the values v1, v2, ..., must support the << operator for -// streaming to std::ostream. -// -// We also define the EXPECT_* variations. -// -// For now we only support predicates whose arity is at most 5. -// Please email googletestframework@googlegroups.com if you need -// support for higher arities. - -// GTEST_ASSERT_ is the basic statement to which all of the assertions -// in this file reduce. Don't use this in your code. - -#define GTEST_ASSERT_(expression, on_failure) \ - GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ - if (const ::testing::AssertionResult gtest_ar = (expression)) \ - ; \ - else \ - on_failure(gtest_ar.failure_message()) - - -// Helper function for implementing {EXPECT|ASSERT}_PRED1. Don't use -// this in your code. -template -AssertionResult AssertPred1Helper(const char* pred_text, - const char* e1, - Pred pred, - const T1& v1) { - if (pred(v1)) return AssertionSuccess(); - - return AssertionFailure() << pred_text << "(" - << e1 << ") evaluates to false, where" - << "\n" << e1 << " evaluates to " << v1; -} - -// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT1. -// Don't use this in your code. -#define GTEST_PRED_FORMAT1_(pred_format, v1, on_failure)\ - GTEST_ASSERT_(pred_format(#v1, v1), \ - on_failure) - -// Internal macro for implementing {EXPECT|ASSERT}_PRED1. Don't use -// this in your code. -#define GTEST_PRED1_(pred, v1, on_failure)\ - GTEST_ASSERT_(::testing::AssertPred1Helper(#pred, \ - #v1, \ - pred, \ - v1), on_failure) - -// Unary predicate assertion macros. -#define EXPECT_PRED_FORMAT1(pred_format, v1) \ - GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_NONFATAL_FAILURE_) -#define EXPECT_PRED1(pred, v1) \ - GTEST_PRED1_(pred, v1, GTEST_NONFATAL_FAILURE_) -#define ASSERT_PRED_FORMAT1(pred_format, v1) \ - GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_FATAL_FAILURE_) -#define ASSERT_PRED1(pred, v1) \ - GTEST_PRED1_(pred, v1, GTEST_FATAL_FAILURE_) - - - -// Helper function for implementing {EXPECT|ASSERT}_PRED2. Don't use -// this in your code. -template -AssertionResult AssertPred2Helper(const char* pred_text, - const char* e1, - const char* e2, - Pred pred, - const T1& v1, - const T2& v2) { - if (pred(v1, v2)) return AssertionSuccess(); - - return AssertionFailure() << pred_text << "(" - << e1 << ", " - << e2 << ") evaluates to false, where" - << "\n" << e1 << " evaluates to " << v1 - << "\n" << e2 << " evaluates to " << v2; -} - -// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT2. -// Don't use this in your code. -#define GTEST_PRED_FORMAT2_(pred_format, v1, v2, on_failure)\ - GTEST_ASSERT_(pred_format(#v1, #v2, v1, v2), \ - on_failure) - -// Internal macro for implementing {EXPECT|ASSERT}_PRED2. Don't use -// this in your code. -#define GTEST_PRED2_(pred, v1, v2, on_failure)\ - GTEST_ASSERT_(::testing::AssertPred2Helper(#pred, \ - #v1, \ - #v2, \ - pred, \ - v1, \ - v2), on_failure) - -// Binary predicate assertion macros. -#define EXPECT_PRED_FORMAT2(pred_format, v1, v2) \ - GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_NONFATAL_FAILURE_) -#define EXPECT_PRED2(pred, v1, v2) \ - GTEST_PRED2_(pred, v1, v2, GTEST_NONFATAL_FAILURE_) -#define ASSERT_PRED_FORMAT2(pred_format, v1, v2) \ - GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_FATAL_FAILURE_) -#define ASSERT_PRED2(pred, v1, v2) \ - GTEST_PRED2_(pred, v1, v2, GTEST_FATAL_FAILURE_) - - - -// Helper function for implementing {EXPECT|ASSERT}_PRED3. Don't use -// this in your code. -template -AssertionResult AssertPred3Helper(const char* pred_text, - const char* e1, - const char* e2, - const char* e3, - Pred pred, - const T1& v1, - const T2& v2, - const T3& v3) { - if (pred(v1, v2, v3)) return AssertionSuccess(); - - return AssertionFailure() << pred_text << "(" - << e1 << ", " - << e2 << ", " - << e3 << ") evaluates to false, where" - << "\n" << e1 << " evaluates to " << v1 - << "\n" << e2 << " evaluates to " << v2 - << "\n" << e3 << " evaluates to " << v3; -} - -// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT3. -// Don't use this in your code. -#define GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, on_failure)\ - GTEST_ASSERT_(pred_format(#v1, #v2, #v3, v1, v2, v3), \ - on_failure) - -// Internal macro for implementing {EXPECT|ASSERT}_PRED3. Don't use -// this in your code. -#define GTEST_PRED3_(pred, v1, v2, v3, on_failure)\ - GTEST_ASSERT_(::testing::AssertPred3Helper(#pred, \ - #v1, \ - #v2, \ - #v3, \ - pred, \ - v1, \ - v2, \ - v3), on_failure) - -// Ternary predicate assertion macros. -#define EXPECT_PRED_FORMAT3(pred_format, v1, v2, v3) \ - GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_NONFATAL_FAILURE_) -#define EXPECT_PRED3(pred, v1, v2, v3) \ - GTEST_PRED3_(pred, v1, v2, v3, GTEST_NONFATAL_FAILURE_) -#define ASSERT_PRED_FORMAT3(pred_format, v1, v2, v3) \ - GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_FATAL_FAILURE_) -#define ASSERT_PRED3(pred, v1, v2, v3) \ - GTEST_PRED3_(pred, v1, v2, v3, GTEST_FATAL_FAILURE_) - - - -// Helper function for implementing {EXPECT|ASSERT}_PRED4. Don't use -// this in your code. -template -AssertionResult AssertPred4Helper(const char* pred_text, - const char* e1, - const char* e2, - const char* e3, - const char* e4, - Pred pred, - const T1& v1, - const T2& v2, - const T3& v3, - const T4& v4) { - if (pred(v1, v2, v3, v4)) return AssertionSuccess(); - - return AssertionFailure() << pred_text << "(" - << e1 << ", " - << e2 << ", " - << e3 << ", " - << e4 << ") evaluates to false, where" - << "\n" << e1 << " evaluates to " << v1 - << "\n" << e2 << " evaluates to " << v2 - << "\n" << e3 << " evaluates to " << v3 - << "\n" << e4 << " evaluates to " << v4; -} - -// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT4. -// Don't use this in your code. -#define GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, on_failure)\ - GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, v1, v2, v3, v4), \ - on_failure) - -// Internal macro for implementing {EXPECT|ASSERT}_PRED4. Don't use -// this in your code. -#define GTEST_PRED4_(pred, v1, v2, v3, v4, on_failure)\ - GTEST_ASSERT_(::testing::AssertPred4Helper(#pred, \ - #v1, \ - #v2, \ - #v3, \ - #v4, \ - pred, \ - v1, \ - v2, \ - v3, \ - v4), on_failure) - -// 4-ary predicate assertion macros. -#define EXPECT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \ - GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_) -#define EXPECT_PRED4(pred, v1, v2, v3, v4) \ - GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_) -#define ASSERT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \ - GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_FATAL_FAILURE_) -#define ASSERT_PRED4(pred, v1, v2, v3, v4) \ - GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_FATAL_FAILURE_) - - - -// Helper function for implementing {EXPECT|ASSERT}_PRED5. Don't use -// this in your code. -template -AssertionResult AssertPred5Helper(const char* pred_text, - const char* e1, - const char* e2, - const char* e3, - const char* e4, - const char* e5, - Pred pred, - const T1& v1, - const T2& v2, - const T3& v3, - const T4& v4, - const T5& v5) { - if (pred(v1, v2, v3, v4, v5)) return AssertionSuccess(); - - return AssertionFailure() << pred_text << "(" - << e1 << ", " - << e2 << ", " - << e3 << ", " - << e4 << ", " - << e5 << ") evaluates to false, where" - << "\n" << e1 << " evaluates to " << v1 - << "\n" << e2 << " evaluates to " << v2 - << "\n" << e3 << " evaluates to " << v3 - << "\n" << e4 << " evaluates to " << v4 - << "\n" << e5 << " evaluates to " << v5; -} - -// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT5. -// Don't use this in your code. -#define GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, on_failure)\ - GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, #v5, v1, v2, v3, v4, v5), \ - on_failure) - -// Internal macro for implementing {EXPECT|ASSERT}_PRED5. Don't use -// this in your code. -#define GTEST_PRED5_(pred, v1, v2, v3, v4, v5, on_failure)\ - GTEST_ASSERT_(::testing::AssertPred5Helper(#pred, \ - #v1, \ - #v2, \ - #v3, \ - #v4, \ - #v5, \ - pred, \ - v1, \ - v2, \ - v3, \ - v4, \ - v5), on_failure) - -// 5-ary predicate assertion macros. -#define EXPECT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \ - GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_) -#define EXPECT_PRED5(pred, v1, v2, v3, v4, v5) \ - GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_) -#define ASSERT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \ - GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_) -#define ASSERT_PRED5(pred, v1, v2, v3, v4, v5) \ - GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_) - - - -#endif // GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ - -// Macros for testing equalities and inequalities. -// -// * {ASSERT|EXPECT}_EQ(expected, actual): Tests that expected == actual -// * {ASSERT|EXPECT}_NE(v1, v2): Tests that v1 != v2 -// * {ASSERT|EXPECT}_LT(v1, v2): Tests that v1 < v2 -// * {ASSERT|EXPECT}_LE(v1, v2): Tests that v1 <= v2 -// * {ASSERT|EXPECT}_GT(v1, v2): Tests that v1 > v2 -// * {ASSERT|EXPECT}_GE(v1, v2): Tests that v1 >= v2 -// -// When they are not, Google Test prints both the tested expressions and -// their actual values. The values must be compatible built-in types, -// or you will get a compiler error. By "compatible" we mean that the -// values can be compared by the respective operator. -// -// Note: -// -// 1. It is possible to make a user-defined type work with -// {ASSERT|EXPECT}_??(), but that requires overloading the -// comparison operators and is thus discouraged by the Google C++ -// Usage Guide. Therefore, you are advised to use the -// {ASSERT|EXPECT}_TRUE() macro to assert that two objects are -// equal. -// -// 2. The {ASSERT|EXPECT}_??() macros do pointer comparisons on -// pointers (in particular, C strings). Therefore, if you use it -// with two C strings, you are testing how their locations in memory -// are related, not how their content is related. To compare two C -// strings by content, use {ASSERT|EXPECT}_STR*(). -// -// 3. {ASSERT|EXPECT}_EQ(expected, actual) is preferred to -// {ASSERT|EXPECT}_TRUE(expected == actual), as the former tells you -// what the actual value is when it fails, and similarly for the -// other comparisons. -// -// 4. Do not depend on the order in which {ASSERT|EXPECT}_??() -// evaluate their arguments, which is undefined. -// -// 5. These macros evaluate their arguments exactly once. -// -// Examples: -// -// EXPECT_NE(5, Foo()); -// EXPECT_EQ(NULL, a_pointer); -// ASSERT_LT(i, array_size); -// ASSERT_GT(records.size(), 0) << "There is no record left."; - -#define EXPECT_EQ(expected, actual) \ - EXPECT_PRED_FORMAT2(::testing::internal:: \ - EqHelper::Compare, \ - expected, actual) -#define EXPECT_NE(expected, actual) \ - EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperNE, expected, actual) -#define EXPECT_LE(val1, val2) \ - EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLE, val1, val2) -#define EXPECT_LT(val1, val2) \ - EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2) -#define EXPECT_GE(val1, val2) \ - EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGE, val1, val2) -#define EXPECT_GT(val1, val2) \ - EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2) - -#define GTEST_ASSERT_EQ(expected, actual) \ - ASSERT_PRED_FORMAT2(::testing::internal:: \ - EqHelper::Compare, \ - expected, actual) -#define GTEST_ASSERT_NE(val1, val2) \ - ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperNE, val1, val2) -#define GTEST_ASSERT_LE(val1, val2) \ - ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperLE, val1, val2) -#define GTEST_ASSERT_LT(val1, val2) \ - ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2) -#define GTEST_ASSERT_GE(val1, val2) \ - ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperGE, val1, val2) -#define GTEST_ASSERT_GT(val1, val2) \ - ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2) - -// Define macro GTEST_DONT_DEFINE_ASSERT_XY to 1 to omit the definition of -// ASSERT_XY(), which clashes with some users' own code. - -#if !GTEST_DONT_DEFINE_ASSERT_EQ -# define ASSERT_EQ(val1, val2) GTEST_ASSERT_EQ(val1, val2) -#endif - -#if !GTEST_DONT_DEFINE_ASSERT_NE -# define ASSERT_NE(val1, val2) GTEST_ASSERT_NE(val1, val2) -#endif - -#if !GTEST_DONT_DEFINE_ASSERT_LE -# define ASSERT_LE(val1, val2) GTEST_ASSERT_LE(val1, val2) -#endif - -#if !GTEST_DONT_DEFINE_ASSERT_LT -# define ASSERT_LT(val1, val2) GTEST_ASSERT_LT(val1, val2) -#endif - -#if !GTEST_DONT_DEFINE_ASSERT_GE -# define ASSERT_GE(val1, val2) GTEST_ASSERT_GE(val1, val2) -#endif - -#if !GTEST_DONT_DEFINE_ASSERT_GT -# define ASSERT_GT(val1, val2) GTEST_ASSERT_GT(val1, val2) -#endif - -// C-string Comparisons. All tests treat NULL and any non-NULL string -// as different. Two NULLs are equal. -// -// * {ASSERT|EXPECT}_STREQ(s1, s2): Tests that s1 == s2 -// * {ASSERT|EXPECT}_STRNE(s1, s2): Tests that s1 != s2 -// * {ASSERT|EXPECT}_STRCASEEQ(s1, s2): Tests that s1 == s2, ignoring case -// * {ASSERT|EXPECT}_STRCASENE(s1, s2): Tests that s1 != s2, ignoring case -// -// For wide or narrow string objects, you can use the -// {ASSERT|EXPECT}_??() macros. -// -// Don't depend on the order in which the arguments are evaluated, -// which is undefined. -// -// These macros evaluate their arguments exactly once. - -#define EXPECT_STREQ(expected, actual) \ - EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTREQ, expected, actual) -#define EXPECT_STRNE(s1, s2) \ - EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2) -#define EXPECT_STRCASEEQ(expected, actual) \ - EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, expected, actual) -#define EXPECT_STRCASENE(s1, s2)\ - EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2) - -#define ASSERT_STREQ(expected, actual) \ - ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTREQ, expected, actual) -#define ASSERT_STRNE(s1, s2) \ - ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2) -#define ASSERT_STRCASEEQ(expected, actual) \ - ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, expected, actual) -#define ASSERT_STRCASENE(s1, s2)\ - ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2) - -// Macros for comparing floating-point numbers. -// -// * {ASSERT|EXPECT}_FLOAT_EQ(expected, actual): -// Tests that two float values are almost equal. -// * {ASSERT|EXPECT}_DOUBLE_EQ(expected, actual): -// Tests that two double values are almost equal. -// * {ASSERT|EXPECT}_NEAR(v1, v2, abs_error): -// Tests that v1 and v2 are within the given distance to each other. -// -// Google Test uses ULP-based comparison to automatically pick a default -// error bound that is appropriate for the operands. See the -// FloatingPoint template class in gtest-internal.h if you are -// interested in the implementation details. - -#define EXPECT_FLOAT_EQ(expected, actual)\ - EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ - expected, actual) - -#define EXPECT_DOUBLE_EQ(expected, actual)\ - EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ - expected, actual) - -#define ASSERT_FLOAT_EQ(expected, actual)\ - ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ - expected, actual) - -#define ASSERT_DOUBLE_EQ(expected, actual)\ - ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ - expected, actual) - -#define EXPECT_NEAR(val1, val2, abs_error)\ - EXPECT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, \ - val1, val2, abs_error) - -#define ASSERT_NEAR(val1, val2, abs_error)\ - ASSERT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, \ - val1, val2, abs_error) - -// These predicate format functions work on floating-point values, and -// can be used in {ASSERT|EXPECT}_PRED_FORMAT2*(), e.g. -// -// EXPECT_PRED_FORMAT2(testing::DoubleLE, Foo(), 5.0); - -// Asserts that val1 is less than, or almost equal to, val2. Fails -// otherwise. In particular, it fails if either val1 or val2 is NaN. -GTEST_API_ AssertionResult FloatLE(const char* expr1, const char* expr2, - float val1, float val2); -GTEST_API_ AssertionResult DoubleLE(const char* expr1, const char* expr2, - double val1, double val2); - - -#if GTEST_OS_WINDOWS - -// Macros that test for HRESULT failure and success, these are only useful -// on Windows, and rely on Windows SDK macros and APIs to compile. -// -// * {ASSERT|EXPECT}_HRESULT_{SUCCEEDED|FAILED}(expr) -// -// When expr unexpectedly fails or succeeds, Google Test prints the -// expected result and the actual result with both a human-readable -// string representation of the error, if available, as well as the -// hex result code. -# define EXPECT_HRESULT_SUCCEEDED(expr) \ - EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr)) - -# define ASSERT_HRESULT_SUCCEEDED(expr) \ - ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr)) - -# define EXPECT_HRESULT_FAILED(expr) \ - EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr)) - -# define ASSERT_HRESULT_FAILED(expr) \ - ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr)) - -#endif // GTEST_OS_WINDOWS - -// Macros that execute statement and check that it doesn't generate new fatal -// failures in the current thread. -// -// * {ASSERT|EXPECT}_NO_FATAL_FAILURE(statement); -// -// Examples: -// -// EXPECT_NO_FATAL_FAILURE(Process()); -// ASSERT_NO_FATAL_FAILURE(Process()) << "Process() failed"; -// -#define ASSERT_NO_FATAL_FAILURE(statement) \ - GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_FATAL_FAILURE_) -#define EXPECT_NO_FATAL_FAILURE(statement) \ - GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_NONFATAL_FAILURE_) - -// Causes a trace (including the source file path, the current line -// number, and the given message) to be included in every test failure -// message generated by code in the current scope. The effect is -// undone when the control leaves the current scope. -// -// The message argument can be anything streamable to std::ostream. -// -// In the implementation, we include the current line number as part -// of the dummy variable name, thus allowing multiple SCOPED_TRACE()s -// to appear in the same block - as long as they are on different -// lines. -#define SCOPED_TRACE(message) \ - ::testing::internal::ScopedTrace GTEST_CONCAT_TOKEN_(gtest_trace_, __LINE__)(\ - __FILE__, __LINE__, ::testing::Message() << (message)) - -// Compile-time assertion for type equality. -// StaticAssertTypeEq() compiles iff type1 and type2 are -// the same type. The value it returns is not interesting. -// -// Instead of making StaticAssertTypeEq a class template, we make it a -// function template that invokes a helper class template. This -// prevents a user from misusing StaticAssertTypeEq by -// defining objects of that type. -// -// CAVEAT: -// -// When used inside a method of a class template, -// StaticAssertTypeEq() is effective ONLY IF the method is -// instantiated. For example, given: -// -// template class Foo { -// public: -// void Bar() { testing::StaticAssertTypeEq(); } -// }; -// -// the code: -// -// void Test1() { Foo foo; } -// -// will NOT generate a compiler error, as Foo::Bar() is never -// actually instantiated. Instead, you need: -// -// void Test2() { Foo foo; foo.Bar(); } -// -// to cause a compiler error. -template -bool StaticAssertTypeEq() { - (void)internal::StaticAssertTypeEqHelper(); - return true; -} - -// Defines a test. -// -// The first parameter is the name of the test case, and the second -// parameter is the name of the test within the test case. -// -// The convention is to end the test case name with "Test". For -// example, a test case for the Foo class can be named FooTest. -// -// The user should put his test code between braces after using this -// macro. Example: -// -// TEST(FooTest, InitializesCorrectly) { -// Foo foo; -// EXPECT_TRUE(foo.StatusIsOK()); -// } - -// Note that we call GetTestTypeId() instead of GetTypeId< -// ::testing::Test>() here to get the type ID of testing::Test. This -// is to work around a suspected linker bug when using Google Test as -// a framework on Mac OS X. The bug causes GetTypeId< -// ::testing::Test>() to return different values depending on whether -// the call is from the Google Test framework itself or from user test -// code. GetTestTypeId() is guaranteed to always return the same -// value, as it always calls GetTypeId<>() from the Google Test -// framework. -#define GTEST_TEST(test_case_name, test_name)\ - GTEST_TEST_(test_case_name, test_name, \ - ::testing::Test, ::testing::internal::GetTestTypeId()) - -// Define this macro to 1 to omit the definition of TEST(), which -// is a generic name and clashes with some other libraries. -#if !GTEST_DONT_DEFINE_TEST -# define TEST(test_case_name, test_name) GTEST_TEST(test_case_name, test_name) -#endif - -// Defines a test that uses a test fixture. -// -// The first parameter is the name of the test fixture class, which -// also doubles as the test case name. The second parameter is the -// name of the test within the test case. -// -// A test fixture class must be declared earlier. The user should put -// his test code between braces after using this macro. Example: -// -// class FooTest : public testing::Test { -// protected: -// virtual void SetUp() { b_.AddElement(3); } -// -// Foo a_; -// Foo b_; -// }; -// -// TEST_F(FooTest, InitializesCorrectly) { -// EXPECT_TRUE(a_.StatusIsOK()); -// } -// -// TEST_F(FooTest, ReturnsElementCountCorrectly) { -// EXPECT_EQ(0, a_.size()); -// EXPECT_EQ(1, b_.size()); -// } - -#define TEST_F(test_fixture, test_name)\ - GTEST_TEST_(test_fixture, test_name, test_fixture, \ - ::testing::internal::GetTypeId()) - -} // namespace testing - -// Use this function in main() to run all tests. It returns 0 if all -// tests are successful, or 1 otherwise. -// -// RUN_ALL_TESTS() should be invoked after the command line has been -// parsed by InitGoogleTest(). -// -// This function was formerly a macro; thus, it is in the global -// namespace and has an all-caps name. -int RUN_ALL_TESTS() GTEST_MUST_USE_RESULT_; - -inline int RUN_ALL_TESTS() { - return ::testing::UnitTest::GetInstance()->Run(); -} - -#endif // GTEST_INCLUDE_GTEST_GTEST_H_ From 408d9d99a9464c80e4af32834b0873a8a567ac7a Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Mon, 31 Jul 2017 11:35:41 -0600 Subject: [PATCH 350/439] cmake: improve some error messages --- cmake/CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index d691386c05..59a2cc1f7b 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -179,7 +179,7 @@ if(ENABLE_PYTHON) endif() install(FILES ${CMAKE_SOURCE_DIR}/../python/lammps.py DESTINATION ${PYTHON_INSTDIR}) if(NOT BUILD_SHARED_LIBS) - message(FATAL_ERROR "Python package need lammps to be build shared, -DBUILD_SHARED_LIBS=ON") + message(FATAL_ERROR "Python package need lammps to be build shared, use -DBUILD_SHARED_LIBS=ON") endif() endif() @@ -451,7 +451,7 @@ if(ENABLE_GPU) find_package(CUDA REQUIRED) find_program(BIN2C bin2c) if(NOT BIN2C) - message(FATAL_ERROR "Couldn't find bin2c") + message(FATAL_ERROR "Couldn't find bin2c, use -DBIN2C helping cmake to find it.") endif() include_directories(${CUDA_INCLUDE_DIRS}) list(APPEND LAMMPS_LINK_LIBS ${CUDA_LIBRARIES} ${CUDA_CUDA_LIBRARY}) @@ -522,7 +522,7 @@ if(INSTALL_LIB) install(TARGETS lammps LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) install(FILES ${LAMMPS_SOURCE_DIR}/lammps.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) elseif(BUILD_SHARED_LIBS) - message(FATAL_ERROR "Shared library has to be installed, use -DBUILD_SHARED_LIBS=ON to install lammps with a library") + message(FATAL_ERROR "Shared library has to be installed, use -DINSTALL_LIB=ON to install lammps with a library") endif() add_executable(lmp ${LMP_SOURCES}) From 72f50c91ee01cf7744ba14ae320d4c7ac09e991a Mon Sep 17 00:00:00 2001 From: Richard Berger Date: Mon, 31 Jul 2017 11:48:22 -0600 Subject: [PATCH 351/439] Add -DLAMMPS_EXCEPTIONS flag --- cmake/CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index d691386c05..efc0eac5ca 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -69,6 +69,11 @@ add_definitions(-D${LAMMPS_SIZE_LIMIT}) set(LAMMPS_MEMALIGN "64" CACHE STRING "enables the use of the posix_memalign() call instead of malloc() when large chunks or memory are allocated by LAMMPS") add_definitions(-DLAMMPS_MEMALIGN=${LAMMPS_MEMALIGN}) +option(LAMMPS_EXCEPTIONS "enable the use of C++ exceptions for error messages (useful for library interface)" OFF) +if(LAMMPS_EXCEPTIONS) + add_definitions(-DLAMMPS_EXCEPTIONS) +endif() + option(CMAKE_VERBOSE_MAKEFILE "Verbose makefile" OFF) option(ENABLE_TESTING "Enable testing" OFF) From 5cd1dc93dc5956a89a1ba42858c69abc84488958 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Mon, 31 Jul 2017 15:32:20 -0600 Subject: [PATCH 352/439] Revert 7edb294b447c62d3d2dbd4f9df984fb8d14f9a7c temporarily --- src/KOKKOS/comm_kokkos.cpp | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/src/KOKKOS/comm_kokkos.cpp b/src/KOKKOS/comm_kokkos.cpp index adc8da501c..2b19908396 100644 --- a/src/KOKKOS/comm_kokkos.cpp +++ b/src/KOKKOS/comm_kokkos.cpp @@ -472,6 +472,8 @@ void CommKokkos::exchange_device() subhi = domain->subhi_lamda; } + atomKK->sync(ExecutionSpaceFromDevice::space,ALL_MASK); + // loop over dimensions for (int dim = 0; dim < 3; dim++) { @@ -600,6 +602,8 @@ void CommKokkos::exchange_device() } + atomKK->modified(ExecutionSpaceFromDevice::space,ALL_MASK); + if (atom->firstgroupname) { /* this is not yet implemented with Kokkos */ atomKK->sync(Host,ALL_MASK); @@ -700,8 +704,8 @@ void CommKokkos::borders_device() { AtomVecKokkos *avec = (AtomVecKokkos *) atom->avec; ExecutionSpace exec_space = ExecutionSpaceFromDevice::space; - k_sendlist.sync(); - atomKK->sync(exec_space,X_MASK); + k_sendlist.modify(); + atomKK->sync(exec_space,ALL_MASK); // do swaps over all 3 dimensions @@ -750,10 +754,12 @@ void CommKokkos::borders_device() { if (sendflag) { if (!bordergroup || ineed >= 2) { if (style == SINGLE) { - DAT::tdual_int_1d total_send("TS",1); + typename ArrayTypes::tdual_int_1d total_send("TS",1); total_send.h_view(0) = 0; - total_send.template modify(); - total_send.template sync(); + if(exec_space == Device) { + total_send.template modify(); + total_send.template sync(); + } BuildBorderListFunctor f(atomKK->k_x,k_sendlist, total_send,nfirst,nlast,dim,lo,hi,iswap,maxsendlist[iswap]); @@ -767,17 +773,16 @@ void CommKokkos::borders_device() { if(total_send.h_view(0) >= maxsendlist[iswap]) { grow_list(iswap,total_send.h_view(0)); k_sendlist.modify(); - total_send.h_view(0) = 0; - total_send.template modify(); - total_send.template sync(); - + if(exec_space == Device) { + total_send.template modify(); + total_send.template sync(); + } BuildBorderListFunctor f(atomKK->k_x,k_sendlist, total_send,nfirst,nlast,dim,lo,hi,iswap,maxsendlist[iswap]); Kokkos::TeamPolicy config((nlast-nfirst+127)/128,128); Kokkos::parallel_for(config,f); DeviceType::fence(); - total_send.template modify(); total_send.template sync(); } @@ -904,7 +909,9 @@ void CommKokkos::borders_device() { // reset global->local map - k_sendlist.template modify(); + if (exec_space == Host) k_sendlist.sync(); + atomKK->modified(exec_space,ALL_MASK); + DeviceType::fence(); atomKK->sync(Host,TAG_MASK); if (map_style) atom->map_set(); } From 8a7a831bd6c08bfa3016c05bf23de354b8d120de Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 8 Aug 2017 12:57:22 -0600 Subject: [PATCH 353/439] Remove redundant check in Makefile.kokkos --- lib/kokkos/Makefile.kokkos | 6 ------ 1 file changed, 6 deletions(-) diff --git a/lib/kokkos/Makefile.kokkos b/lib/kokkos/Makefile.kokkos index acb6c36134..d2967cf9a3 100644 --- a/lib/kokkos/Makefile.kokkos +++ b/lib/kokkos/Makefile.kokkos @@ -87,12 +87,6 @@ ifneq ($(MPICH_CXX),) endif KOKKOS_INTERNAL_COMPILER_CLANG := $(strip $(shell $(CXX) --version 2>&1 | grep clang | wc -l)) KOKKOS_INTERNAL_COMPILER_APPLE_CLANG := $(strip $(shell $(CXX) --version 2>&1 | grep "apple-darwin" | wc -l)) -ifneq ($(OMPI_CXX),) - KOKKOS_INTERNAL_COMPILER_NVCC := $(strip $(shell $(OMPI_CXX) --version 2>&1 | grep "nvcc" | wc -l)) -endif -ifneq ($(MPICH_CXX),) - KOKKOS_INTERNAL_COMPILER_NVCC := $(strip $(shell $(MPICH_CXX) --version 2>&1 | grep "nvcc" | wc -l)) -endif ifeq ($(KOKKOS_INTERNAL_COMPILER_CLANG), 2) KOKKOS_INTERNAL_COMPILER_CLANG = 1 From 3e9b41c6b74d7f72bb8326e5933420ec9d6dd736 Mon Sep 17 00:00:00 2001 From: Trung Nguyen Date: Wed, 9 Aug 2017 10:05:14 -0500 Subject: [PATCH 354/439] Added references to GPU package citations --- src/GPU/fix_gpu.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/GPU/fix_gpu.cpp b/src/GPU/fix_gpu.cpp index 22ec8dde3b..87db73bd12 100644 --- a/src/GPU/fix_gpu.cpp +++ b/src/GPU/fix_gpu.cpp @@ -71,6 +71,22 @@ static const char cite_gpu_package[] = " year = 2013,\n" " volume = 184,\n" " pages = {2785--2793}\n" + "}\n\n" + "@Article{Trung15,\n" + " author = {T. D. Nguyen, S. J. Plimpton},\n" + " title = {Accelerating dissipative particle dynamics simulations for soft matter systems},\n" + " journal = {Comput.~Mater.~Sci.},\n" + " year = 2015,\n" + " volume = 100,\n" + " pages = {173--180}\n" + "}\n\n" + "@Article{Trung17,\n" + " author = {T. D. Nguyen},\n" + " title = {GPU-accelerated Tersoff potentials for massively parallel Molecular Dynamics simulations},\n" + " journal = {Comp.~Phys.~Comm.},\n" + " year = 2017,\n" + " volume = 212,\n" + " pages = {113--122}\n" "}\n\n"; /* ---------------------------------------------------------------------- */ From da01be7c1857c0eff27a61036c7dffeef747079b Mon Sep 17 00:00:00 2001 From: Giacomo Fiorin Date: Thu, 10 Aug 2017 09:22:53 -0400 Subject: [PATCH 355/439] More robust change from initial to target restraint centers in Colvars --- doc/src/PDF/colvars-refman-lammps.pdf | Bin 570332 -> 570258 bytes lib/colvars/README | 6 +- lib/colvars/colvar.h | 7 +- lib/colvars/colvaratoms.h | 7 +- lib/colvars/colvarbias.cpp | 1 + lib/colvars/colvarbias.h | 6 +- lib/colvars/colvarbias_restraint.cpp | 157 ++++++++++-------- lib/colvars/colvarbias_restraint.h | 11 +- lib/colvars/colvarcomp.h | 8 +- lib/colvars/colvardeps.cpp | 12 +- lib/colvars/colvardeps.h | 3 +- lib/colvars/colvars_version.h | 4 +- lib/colvars/colvarscript.cpp | 2 +- lib/colvars/colvartypes.cpp | 32 +++- lib/colvars/colvartypes.h | 10 -- lib/colvars/colvarvalue.cpp | 44 +++++ lib/colvars/colvarvalue.h | 18 +- src/USER-COLVARS/colvarproxy_lammps_version.h | 2 +- 18 files changed, 217 insertions(+), 113 deletions(-) diff --git a/doc/src/PDF/colvars-refman-lammps.pdf b/doc/src/PDF/colvars-refman-lammps.pdf index a14d93cd69e7a2aced22919a7755d66714405d47..ad15752107cc006471cc4b3e7a400aa1658f26e2 100644 GIT binary patch delta 89319 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 z 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 delta 89364 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

Th4nX1vn_oq-H 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

*;IdwJc%+DP8?-?V>`E|9N?i7G`lXV-3 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 diff --git a/lib/colvars/README b/lib/colvars/README index ce1d319974..5df9612dfa 100644 --- a/lib/colvars/README +++ b/lib/colvars/README @@ -32,7 +32,7 @@ where Makefile.g++ uses the GNU C++ compiler and is a good template to start. **Optional**: if you use the Install.py script provided in this folder, you can give the machine name as the '-m' argument. This can be the suffix of one -of the files from either this folder, or from src/MAKE. +of the files from either this folder, or from src/MAKE/MACHINES. *This is only supported by the Install.py within the lib/colvars folder*. When you are done building this library, two files should @@ -53,10 +53,10 @@ settings in Makefile.common should work. For the reference manual see: http://colvars.github.io/colvars-refman-lammps -A copy of reference manual is also in: +A copy of the reference manual is also in: doc/PDF/colvars-refman-lammps.pdf -Also included is a Doxygen-based developer documentation: +Also available is a Doxygen-based developer documentation: http://colvars.github.io/doxygen/html/ The reference article is: diff --git a/lib/colvars/colvar.h b/lib/colvars/colvar.h index 6113e1678b..dfa9e093a5 100644 --- a/lib/colvars/colvar.h +++ b/lib/colvars/colvar.h @@ -88,7 +88,12 @@ public: static std::vector cv_features; /// \brief Implementation of the feature list accessor for colvar - std::vector &features() { + virtual const std::vector &features() + { + return cv_features; + } + virtual std::vector &modify_features() + { return cv_features; } diff --git a/lib/colvars/colvaratoms.h b/lib/colvars/colvaratoms.h index dba2890abc..6113fb38a9 100644 --- a/lib/colvars/colvaratoms.h +++ b/lib/colvars/colvaratoms.h @@ -206,7 +206,12 @@ public: static std::vector ag_features; /// \brief Implementation of the feature list accessor for atom group - virtual std::vector &features() { + virtual const std::vector &features() + { + return ag_features; + } + virtual std::vector &modify_features() + { return ag_features; } diff --git a/lib/colvars/colvarbias.cpp b/lib/colvars/colvarbias.cpp index e437466be9..636727ca39 100644 --- a/lib/colvars/colvarbias.cpp +++ b/lib/colvars/colvarbias.cpp @@ -384,6 +384,7 @@ std::ostream & colvarbias::write_traj(std::ostream &os) os << " "; if (b_output_energy) os << " " + << std::setprecision(cvm::en_prec) << std::setw(cvm::en_width) << bias_energy; return os; } diff --git a/lib/colvars/colvarbias.h b/lib/colvars/colvarbias.h index 205e761cfc..a147cd3210 100644 --- a/lib/colvars/colvarbias.h +++ b/lib/colvars/colvarbias.h @@ -175,7 +175,11 @@ public: static std::vector cvb_features; /// \brief Implementation of the feature list accessor for colvarbias - virtual std::vector &features() + virtual const std::vector &features() + { + return cvb_features; + } + virtual std::vector &modify_features() { return cvb_features; } diff --git a/lib/colvars/colvarbias_restraint.cpp b/lib/colvars/colvarbias_restraint.cpp index bb6d6164e5..6879190968 100644 --- a/lib/colvars/colvarbias_restraint.cpp +++ b/lib/colvars/colvarbias_restraint.cpp @@ -99,12 +99,9 @@ int colvarbias_restraint_centers::init(std::string const &conf) if (null_centers) { // try to initialize the restraint centers for the first time colvar_centers.resize(num_variables()); - colvar_centers_raw.resize(num_variables()); for (i = 0; i < num_variables(); i++) { colvar_centers[i].type(variables(i)->value()); colvar_centers[i].reset(); - colvar_centers_raw[i].type(variables(i)->value()); - colvar_centers_raw[i].reset(); } } @@ -113,7 +110,6 @@ int colvarbias_restraint_centers::init(std::string const &conf) if (cvm::debug()) { cvm::log("colvarbias_restraint: parsing initial centers, i = "+cvm::to_str(i)+".\n"); } - colvar_centers_raw[i] = colvar_centers[i]; colvar_centers[i].apply_constraints(); } null_centers = false; @@ -141,8 +137,6 @@ int colvarbias_restraint_centers::change_configuration(std::string const &conf) for (size_t i = 0; i < num_variables(); i++) { colvar_centers[i].type(variables(i)->value()); colvar_centers[i].apply_constraints(); - colvar_centers_raw[i].type(variables(i)->value()); - colvar_centers_raw[i] = colvar_centers[i]; } } return COLVARS_OK; @@ -232,7 +226,6 @@ int colvarbias_restraint_moving::set_state_params(std::string const &conf) { if (b_chg_centers || b_chg_force_k) { if (target_nstages) { - // cvm::log ("Reading current stage from the restart.\n"); if (!get_keyval(conf, "stage", stage)) cvm::error("Error: current stage is missing from the restart.\n"); } @@ -265,100 +258,127 @@ int colvarbias_restraint_centers_moving::init(std::string const &conf) size_t i; if (get_keyval(conf, "targetCenters", target_centers, colvar_centers)) { - if (colvar_centers.size() != num_variables()) { + if (target_centers.size() != num_variables()) { cvm::error("Error: number of target centers does not match " - "that of collective variables.\n"); + "that of collective variables.\n", INPUT_ERROR); } b_chg_centers = true; for (i = 0; i < target_centers.size(); i++) { target_centers[i].apply_constraints(); + centers_incr.push_back(colvar_centers[i]); + centers_incr[i].reset(); } } if (b_chg_centers) { - // parse moving restraint options + // parse moving schedule options colvarbias_restraint_moving::init(conf); + if (initial_centers.size() == 0) { + // One-time init + initial_centers = colvar_centers; + } + // Call to check that the definition is correct + for (i = 0; i < num_variables(); i++) { + colvarvalue const midpoint = + colvarvalue::interpolate(initial_centers[i], + target_centers[i], + 0.5); + } } else { target_centers.clear(); return COLVARS_OK; } get_keyval(conf, "outputCenters", b_output_centers, b_output_centers); - get_keyval(conf, "outputAccumulatedWork", b_output_acc_work, b_output_acc_work); + get_keyval(conf, "outputAccumulatedWork", b_output_acc_work, + b_output_acc_work); // TODO this conflicts with stages return COLVARS_OK; } +int colvarbias_restraint_centers_moving::update_centers(cvm::real lambda) +{ + if (cvm::debug()) { + cvm::log("Updating centers for the restraint bias \""+ + this->name+"\": "+cvm::to_str(colvar_centers)+".\n"); + } + size_t i; + for (i = 0; i < num_variables(); i++) { + colvarvalue const c_new = colvarvalue::interpolate(initial_centers[i], + target_centers[i], + lambda); + centers_incr[i] = (c_new).dist2_grad(colvar_centers[i]); + colvar_centers[i] = c_new; + variables(i)->wrap(colvar_centers[i]); + } + if (cvm::debug()) { + cvm::log("New centers for the restraint bias \""+ + this->name+"\": "+cvm::to_str(colvar_centers)+".\n"); + } + return cvm::get_error(); +} + + int colvarbias_restraint_centers_moving::update() { if (b_chg_centers) { - if (cvm::debug()) { - cvm::log("Updating centers for the restraint bias \""+ - this->name+"\": "+cvm::to_str(colvar_centers)+".\n"); - } - - if (!centers_incr.size()) { - // if this is the first calculation, calculate the advancement - // at each simulation step (or stage, if applicable) - // (take current stage into account: it can be non-zero - // if we are restarting a staged calculation) - centers_incr.resize(num_variables()); - for (size_t i = 0; i < num_variables(); i++) { - centers_incr[i].type(variables(i)->value()); - centers_incr[i] = (target_centers[i] - colvar_centers_raw[i]) / - cvm::real( target_nstages ? (target_nstages - stage) : - (target_nsteps - cvm::step_absolute())); - } - if (cvm::debug()) { - cvm::log("Center increment for the restraint bias \""+ - this->name+"\": "+cvm::to_str(centers_incr)+" at stage "+cvm::to_str(stage)+ ".\n"); - } - } - if (target_nstages) { - if ((cvm::step_relative() > 0) - && (cvm::step_absolute() % target_nsteps) == 0 - && stage < target_nstages) { - - for (size_t i = 0; i < num_variables(); i++) { - colvar_centers_raw[i] += centers_incr[i]; - colvar_centers[i] = colvar_centers_raw[i]; - variables(i)->wrap(colvar_centers[i]); - colvar_centers[i].apply_constraints(); + // Staged update + if (stage <= target_nstages) { + if ((cvm::step_relative() > 0) && + ((cvm::step_absolute() % target_nsteps) == 1)) { + cvm::real const lambda = + cvm::real(stage)/cvm::real(target_nstages); + update_centers(lambda); + stage++; + cvm::log("Moving restraint \"" + this->name + + "\" stage " + cvm::to_str(stage) + + " : setting centers to " + cvm::to_str(colvar_centers) + + " at step " + cvm::to_str(cvm::step_absolute())); + } else { + for (size_t i = 0; i < num_variables(); i++) { + centers_incr[i].reset(); + } } - stage++; - cvm::log("Moving restraint \"" + this->name + - "\" stage " + cvm::to_str(stage) + - " : setting centers to " + cvm::to_str(colvar_centers) + - " at step " + cvm::to_str(cvm::step_absolute())); } - } else if ((cvm::step_relative() > 0) && (cvm::step_absolute() <= target_nsteps)) { - // move the restraint centers in the direction of the targets - // (slow growth) + } else { + // Continuous update + if (cvm::step_absolute() <= target_nsteps) { + cvm::real const lambda = + cvm::real(cvm::step_absolute())/cvm::real(target_nsteps); + update_centers(lambda); + } else { + for (size_t i = 0; i < num_variables(); i++) { + centers_incr[i].reset(); + } + } + } + + if (cvm::step_relative() == 0) { for (size_t i = 0; i < num_variables(); i++) { - colvar_centers_raw[i] += centers_incr[i]; - colvar_centers[i] = colvar_centers_raw[i]; - variables(i)->wrap(colvar_centers[i]); - colvar_centers[i].apply_constraints(); + // finite differences are undefined when restarting + centers_incr[i].reset(); } } if (cvm::debug()) { - cvm::log("New centers for the restraint bias \""+ - this->name+"\": "+cvm::to_str(colvar_centers)+".\n"); + cvm::log("Center increment for the restraint bias \""+ + this->name+"\": "+cvm::to_str(centers_incr)+ + " at stage "+cvm::to_str(stage)+ ".\n"); } } - return COLVARS_OK; + return cvm::get_error(); } int colvarbias_restraint_centers_moving::update_acc_work() { if (b_output_acc_work) { - if ((cvm::step_relative() > 0) || (cvm::step_absolute() == 0)) { + if ((cvm::step_relative() > 0) && + (cvm::step_absolute() <= 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]; @@ -383,13 +403,6 @@ std::string const colvarbias_restraint_centers_moving::get_state_params() const << colvar_centers[i]; } os << "\n"; - os << "centers_raw "; - for (i = 0; i < num_variables(); i++) { - os << " " - << std::setprecision(cvm::cv_prec) << std::setw(cvm::cv_width) - << colvar_centers_raw[i]; - } - os << "\n"; if (b_output_acc_work) { os << "accumulatedWork " @@ -398,7 +411,7 @@ std::string const colvarbias_restraint_centers_moving::get_state_params() const } } - return colvarbias_restraint_moving::get_state_params() + os.str(); + return os.str(); } @@ -410,8 +423,6 @@ int colvarbias_restraint_centers_moving::set_state_params(std::string const &con // cvm::log ("Reading the updated restraint centers from the restart.\n"); if (!get_keyval(conf, "centers", colvar_centers)) cvm::error("Error: restraint centers are missing from the restart.\n"); - if (!get_keyval(conf, "centers_raw", colvar_centers_raw)) - cvm::error("Error: \"raw\" restraint centers are missing from the restart.\n"); if (b_output_acc_work) { if (!get_keyval(conf, "accumulatedWork", acc_work)) cvm::error("Error: accumulatedWork is missing from the restart.\n"); @@ -609,7 +620,7 @@ std::string const colvarbias_restraint_k_moving::get_state_params() const << std::setprecision(cvm::en_prec) << std::setw(cvm::en_width) << force_k << "\n"; } - return colvarbias_restraint_moving::get_state_params() + os.str(); + return os.str(); } @@ -770,6 +781,7 @@ cvm::real colvarbias_restraint_harmonic::d_restraint_potential_dk(size_t i) cons std::string const colvarbias_restraint_harmonic::get_state_params() const { return colvarbias_restraint::get_state_params() + + colvarbias_restraint_moving::get_state_params() + colvarbias_restraint_centers_moving::get_state_params() + colvarbias_restraint_k_moving::get_state_params(); } @@ -779,6 +791,7 @@ int colvarbias_restraint_harmonic::set_state_params(std::string const &conf) { int error_code = COLVARS_OK; error_code |= colvarbias_restraint::set_state_params(conf); + error_code |= colvarbias_restraint_moving::set_state_params(conf); error_code |= colvarbias_restraint_centers_moving::set_state_params(conf); error_code |= colvarbias_restraint_k_moving::set_state_params(conf); return error_code; @@ -1037,6 +1050,7 @@ cvm::real colvarbias_restraint_harmonic_walls::d_restraint_potential_dk(size_t i std::string const colvarbias_restraint_harmonic_walls::get_state_params() const { return colvarbias_restraint::get_state_params() + + colvarbias_restraint_moving::get_state_params() + colvarbias_restraint_k_moving::get_state_params(); } @@ -1045,6 +1059,7 @@ int colvarbias_restraint_harmonic_walls::set_state_params(std::string const &con { int error_code = COLVARS_OK; error_code |= colvarbias_restraint::set_state_params(conf); + error_code |= colvarbias_restraint_moving::set_state_params(conf); error_code |= colvarbias_restraint_k_moving::set_state_params(conf); return error_code; } @@ -1164,6 +1179,7 @@ cvm::real colvarbias_restraint_linear::d_restraint_potential_dk(size_t i) const std::string const colvarbias_restraint_linear::get_state_params() const { return colvarbias_restraint::get_state_params() + + colvarbias_restraint_moving::get_state_params() + colvarbias_restraint_centers_moving::get_state_params() + colvarbias_restraint_k_moving::get_state_params(); } @@ -1173,6 +1189,7 @@ int colvarbias_restraint_linear::set_state_params(std::string const &conf) { int error_code = COLVARS_OK; error_code |= colvarbias_restraint::set_state_params(conf); + error_code |= colvarbias_restraint_moving::set_state_params(conf); error_code |= colvarbias_restraint_centers_moving::set_state_params(conf); error_code |= colvarbias_restraint_k_moving::set_state_params(conf); return error_code; diff --git a/lib/colvars/colvarbias_restraint.h b/lib/colvars/colvarbias_restraint.h index 98b967abdb..8c3a1537fc 100644 --- a/lib/colvars/colvarbias_restraint.h +++ b/lib/colvars/colvarbias_restraint.h @@ -74,9 +74,6 @@ protected: /// \brief Restraint centers std::vector colvar_centers; - - /// \brief Restraint centers outside the domain of the colvars (no wrapping or constraints applied) - std::vector colvar_centers_raw; }; @@ -156,10 +153,16 @@ protected: /// \brief New restraint centers std::vector target_centers; + /// \brief Initial value of the restraint centers + std::vector initial_centers; + /// \brief Amplitude of the restraint centers' increment at each step - /// (or stage) towards the new values (calculated from target_nsteps) + /// towards the new values (calculated from target_nsteps) std::vector centers_incr; + /// \brief Update the centers by interpolating between initial and target + virtual int update_centers(cvm::real lambda); + /// Whether to write the current restraint centers to the trajectory file bool b_output_centers; diff --git a/lib/colvars/colvarcomp.h b/lib/colvars/colvarcomp.h index 2c865a166b..3c1ec2495c 100644 --- a/lib/colvars/colvarcomp.h +++ b/lib/colvars/colvarcomp.h @@ -132,9 +132,15 @@ public: static std::vector cvc_features; /// \brief Implementation of the feature list accessor for colvar - virtual std::vector &features() { + virtual const std::vector &features() + { return cvc_features; } + virtual std::vector &modify_features() + { + return cvc_features; + } + /// \brief Obtain data needed for the calculation for the backend virtual void read_data(); diff --git a/lib/colvars/colvardeps.cpp b/lib/colvars/colvardeps.cpp index 5402836f53..8f241a6255 100644 --- a/lib/colvars/colvardeps.cpp +++ b/lib/colvars/colvardeps.cpp @@ -374,8 +374,8 @@ int colvardeps::decr_ref_count(int feature_id) { } void colvardeps::init_feature(int feature_id, const char *description, feature_type type) { - features()[feature_id]->description = description; - features()[feature_id]->type = type; + modify_features()[feature_id]->description = description; + modify_features()[feature_id]->type = type; } // Shorthand macros for describing dependencies @@ -401,7 +401,7 @@ void colvardeps::init_cvb_requires() { int i; if (features().size() == 0) { for (i = 0; i < f_cvb_ntot; i++) { - features().push_back(new feature); + modify_features().push_back(new feature); } init_feature(f_cvb_active, "active", f_type_dynamic); @@ -438,7 +438,7 @@ void colvardeps::init_cv_requires() { size_t i; if (features().size() == 0) { for (i = 0; i < f_cv_ntot; i++) { - features().push_back(new feature); + modify_features().push_back(new feature); } init_feature(f_cv_active, "active", f_type_dynamic); @@ -554,7 +554,7 @@ void colvardeps::init_cvc_requires() { // Initialize static array once and for all if (features().size() == 0) { for (i = 0; i < colvardeps::f_cvc_ntot; i++) { - features().push_back(new feature); + modify_features().push_back(new feature); } init_feature(f_cvc_active, "active", f_type_dynamic); @@ -633,7 +633,7 @@ void colvardeps::init_ag_requires() { // Initialize static array once and for all if (features().size() == 0) { for (i = 0; i < f_ag_ntot; i++) { - features().push_back(new feature); + modify_features().push_back(new feature); } init_feature(f_ag_active, "active", f_type_dynamic); diff --git a/lib/colvars/colvardeps.h b/lib/colvars/colvardeps.h index b810a5fca1..dfb10d00e4 100644 --- a/lib/colvars/colvardeps.h +++ b/lib/colvars/colvardeps.h @@ -135,7 +135,8 @@ public: // with a non-static array // Intermediate classes (colvarbias and colvarcomp, which are also base classes) // implement this as virtual to allow overriding - virtual std::vector&features() = 0; + virtual const std::vector&features() = 0; + virtual std::vector&modify_features() = 0; void add_child(colvardeps *child); diff --git a/lib/colvars/colvars_version.h b/lib/colvars/colvars_version.h index e544756428..312c0fd1a0 100644 --- a/lib/colvars/colvars_version.h +++ b/lib/colvars/colvars_version.h @@ -1,4 +1,5 @@ -#define COLVARS_VERSION "2017-07-15" +#ifndef COLVARS_VERSION +#define COLVARS_VERSION "2017-08-06" // 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 @@ -6,3 +7,4 @@ // If you wish to distribute your changes, please submit them to the // Colvars repository at GitHub. +#endif diff --git a/lib/colvars/colvarscript.cpp b/lib/colvars/colvarscript.cpp index 5bb2faae24..89302a16a2 100644 --- a/lib/colvars/colvarscript.cpp +++ b/lib/colvars/colvarscript.cpp @@ -472,7 +472,7 @@ int colvarscript::proc_features(colvardeps *obj, } if ((subcmd == "get") || (subcmd == "set")) { - std::vector &features = obj->features(); + std::vector const &features = obj->features(); std::string const req_feature(obj_to_str(objv[3])); colvardeps::feature *f = NULL; int fid = 0; diff --git a/lib/colvars/colvartypes.cpp b/lib/colvars/colvartypes.cpp index 5200d4d041..428fe1a4b1 100644 --- a/lib/colvars/colvartypes.cpp +++ b/lib/colvars/colvartypes.cpp @@ -19,6 +19,17 @@ bool colvarmodule::rotation::monitor_crossings = false; cvm::real colvarmodule::rotation::crossing_threshold = 1.0E-02; +/// Numerical recipes diagonalization +static int jacobi(cvm::real **a, cvm::real *d, cvm::real **v, int *nrot); + +/// Eigenvector sort +static int eigsrt(cvm::real *d, cvm::real **v); + +/// Transpose the matrix +static int transpose(cvm::real **v); + + + std::string cvm::rvector::to_simple_string() const { std::ostringstream os; @@ -286,7 +297,12 @@ void colvarmodule::rotation::diagonalize_matrix(cvm::matrix2d &S, // diagonalize int jac_nrot = 0; - jacobi(S.c_array(), S_eigval.c_array(), S_eigvec.c_array(), &jac_nrot); + if (jacobi(S.c_array(), S_eigval.c_array(), S_eigvec.c_array(), &jac_nrot) != + COLVARS_OK) { + cvm::error("Too many iterations in routine jacobi.\n" + "This is usually the result of an ill-defined set of atoms for " + "rotational alignment (RMSD, rotateReference, etc).\n"); + } eigsrt(S_eigval.c_array(), S_eigvec.c_array()); // jacobi saves eigenvectors by columns transpose(S_eigvec.c_array()); @@ -528,7 +544,7 @@ void colvarmodule::rotation::calc_optimal_rotation(std::vector co #define n 4 -void jacobi(cvm::real **a, cvm::real *d, cvm::real **v, int *nrot) +int jacobi(cvm::real **a, cvm::real *d, cvm::real **v, int *nrot) { int j,iq,ip,i; cvm::real tresh,theta,tau,t,sm,s,h,g,c; @@ -554,7 +570,7 @@ void jacobi(cvm::real **a, cvm::real *d, cvm::real **v, int *nrot) sm += std::fabs(a[ip][iq]); } if (sm == 0.0) { - return; + return COLVARS_OK; } if (i < 4) tresh=0.2*sm/(n*n); @@ -606,10 +622,11 @@ void jacobi(cvm::real **a, cvm::real *d, cvm::real **v, int *nrot) z[ip]=0.0; } } - cvm::error("Too many iterations in routine jacobi.\n"); + return COLVARS_ERROR; } -void eigsrt(cvm::real *d, cvm::real **v) + +int eigsrt(cvm::real *d, cvm::real **v) { int k,j,i; cvm::real p; @@ -628,9 +645,11 @@ void eigsrt(cvm::real *d, cvm::real **v) } } } + return COLVARS_OK; } -void transpose(cvm::real **v) + +int transpose(cvm::real **v) { cvm::real p; int i,j; @@ -641,6 +660,7 @@ void transpose(cvm::real **v) v[j][i]=p; } } + return COLVARS_OK; } #undef n diff --git a/lib/colvars/colvartypes.h b/lib/colvars/colvartypes.h index 17c09a5095..fe3160eb4b 100644 --- a/lib/colvars/colvartypes.h +++ b/lib/colvars/colvartypes.h @@ -1020,16 +1020,6 @@ inline cvm::rvector operator * (cvm::rmatrix const &m, } -/// Numerical recipes diagonalization -void jacobi(cvm::real **a, cvm::real *d, cvm::real **v, int *nrot); - -/// Eigenvector sort -void eigsrt(cvm::real *d, cvm::real **v); - -/// Transpose the matrix -void transpose(cvm::real **v); - - /// \brief 1-dimensional vector of real numbers with four components and diff --git a/lib/colvars/colvarvalue.cpp b/lib/colvars/colvarvalue.cpp index 7b498be6d6..312d101603 100644 --- a/lib/colvars/colvarvalue.cpp +++ b/lib/colvars/colvarvalue.cpp @@ -570,6 +570,50 @@ colvarvalue colvarvalue::dist2_grad(colvarvalue const &x2) const } +/// Return the midpoint between x1 and x2, optionally weighted by lambda +/// (which must be between 0.0 and 1.0) +colvarvalue const colvarvalue::interpolate(colvarvalue const &x1, + colvarvalue const &x2, + cvm::real const lambda) +{ + colvarvalue::check_types(x1, x2); + + if ((lambda < 0.0) || (lambda > 1.0)) { + cvm::error("Error: trying to interpolate between two colvarvalues with a " + "lamdba outside [0:1].\n", BUG_ERROR); + } + + colvarvalue interp = ((1.0-lambda)*x1 + lambda*x2); + cvm::real const d2 = x1.dist2(x2); + + switch (x1.type()) { + case colvarvalue::type_scalar: + case colvarvalue::type_3vector: + case colvarvalue::type_vector: + case colvarvalue::type_unit3vectorderiv: + case colvarvalue::type_quaternionderiv: + return interp; + break; + case colvarvalue::type_unit3vector: + case colvarvalue::type_quaternion: + if (interp.norm()/std::sqrt(d2) < 1.0e-6) { + cvm::error("Error: interpolation between "+cvm::to_str(x1)+" and "+ + cvm::to_str(x2)+" with lambda = "+cvm::to_str(lambda)+ + " is undefined: result = "+cvm::to_str(interp)+"\n", + INPUT_ERROR); + } + interp.apply_constraints(); + return interp; + break; + case colvarvalue::type_notset: + default: + x1.undef_op(); + break; + } + return colvarvalue(colvarvalue::type_notset); +} + + std::string colvarvalue::to_simple_string() const { switch (type()) { diff --git a/lib/colvars/colvarvalue.h b/lib/colvars/colvarvalue.h index fce0e1a970..41759e92b0 100644 --- a/lib/colvars/colvarvalue.h +++ b/lib/colvars/colvarvalue.h @@ -193,6 +193,12 @@ public: /// Derivative with respect to this \link colvarvalue \endlink of the square distance colvarvalue dist2_grad(colvarvalue const &x2) const; + /// Return the midpoint between x1 and x2, optionally weighted by lambda + /// (which must be between 0.0 and 1.0) + static colvarvalue const interpolate(colvarvalue const &x1, + colvarvalue const &x2, + cvm::real const lambda = 0.5); + /// Assignment operator (type of x is checked) colvarvalue & operator = (colvarvalue const &x); @@ -285,10 +291,10 @@ public: cvm::real & operator [] (int const i); /// Ensure that the two types are the same within a binary operator - int static check_types(colvarvalue const &x1, colvarvalue const &x2); + static int check_types(colvarvalue const &x1, colvarvalue const &x2); /// Ensure that the two types are the same within an assignment, or that the left side is type_notset - int static check_types_assign(Type const &vt1, Type const &vt2); + static int check_types_assign(Type const &vt1, Type const &vt2); /// Undefined operation void undef_op() const; @@ -317,14 +323,14 @@ public: /// \brief Optimized routine for the inner product of one collective /// variable with an array - void static inner_opt(colvarvalue const &x, + static void inner_opt(colvarvalue const &x, std::vector::iterator &xv, std::vector::iterator const &xv_end, std::vector::iterator &result); /// \brief Optimized routine for the inner product of one collective /// variable with an array - void static inner_opt(colvarvalue const &x, + static void inner_opt(colvarvalue const &x, std::list::iterator &xv, std::list::iterator const &xv_end, std::vector::iterator &result); @@ -332,14 +338,14 @@ public: /// \brief Optimized routine for the second order Legendre /// polynomial, (3cos^2(w)-1)/2, of one collective variable with an /// array - void static p2leg_opt(colvarvalue const &x, + static void p2leg_opt(colvarvalue const &x, std::vector::iterator &xv, std::vector::iterator const &xv_end, std::vector::iterator &result); /// \brief Optimized routine for the second order Legendre /// polynomial of one collective variable with an array - void static p2leg_opt(colvarvalue const &x, + static void p2leg_opt(colvarvalue const &x, std::list::iterator &xv, std::list::iterator const &xv_end, std::vector::iterator &result); diff --git a/src/USER-COLVARS/colvarproxy_lammps_version.h b/src/USER-COLVARS/colvarproxy_lammps_version.h index 834bd1748a..0eb6f2d95a 100644 --- a/src/USER-COLVARS/colvarproxy_lammps_version.h +++ b/src/USER-COLVARS/colvarproxy_lammps_version.h @@ -1,5 +1,5 @@ #ifndef COLVARPROXY_VERSION -#define COLVARPROXY_VERSION "2017-07-15" +#define COLVARPROXY_VERSION "2017-07-19" // 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 From 2a7d2dee3652a229ad7a2a02e77ef558d63ed0a5 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 10 Aug 2017 14:49:51 -0400 Subject: [PATCH 356/439] add more strict checking of data when parsing molecule files to detect format errors --- src/molecule.cpp | 433 +++++++++++++++++++++++------------------------ 1 file changed, 213 insertions(+), 220 deletions(-) diff --git a/src/molecule.cpp b/src/molecule.cpp index e0e9ec8aaf..b0fec4bcbc 100644 --- a/src/molecule.cpp +++ b/src/molecule.cpp @@ -427,47 +427,61 @@ void Molecule::read(int flag) // search line for header keywords and set corresponding variable - if (strstr(line,"atoms")) sscanf(line,"%d",&natoms); - else if (strstr(line,"bonds")) sscanf(line,"%d",&nbonds); - else if (strstr(line,"angles")) sscanf(line,"%d",&nangles); - else if (strstr(line,"dihedrals")) sscanf(line,"%d",&ndihedrals); - else if (strstr(line,"impropers")) sscanf(line,"%d",&nimpropers); - - else if (strstr(line,"mass")) { + int nmatch = 0; + int nwant = 0; + if (strstr(line,"atoms")) { + nmatch = sscanf(line,"%d",&natoms); + nwant = 1; + } else if (strstr(line,"bonds")) { + nmatch = sscanf(line,"%d",&nbonds); + nwant = 1; + } else if (strstr(line,"angles")) { + nmatch = sscanf(line,"%d",&nangles); + nwant = 1; + } else if (strstr(line,"dihedrals")) { + nmatch = sscanf(line,"%d",&ndihedrals); + nwant = 1; + } else if (strstr(line,"impropers")) { + nmatch = sscanf(line,"%d",&nimpropers); + nwant = 1; + } else if (strstr(line,"mass")) { massflag = 1; - sscanf(line,"%lg",&masstotal); + nmatch = sscanf(line,"%lg",&masstotal); + nwant = 1; masstotal *= sizescale*sizescale*sizescale; - } - else if (strstr(line,"com")) { + } else if (strstr(line,"com")) { comflag = 1; - sscanf(line,"%lg %lg %lg",&com[0],&com[1],&com[2]); + nmatch = sscanf(line,"%lg %lg %lg",&com[0],&com[1],&com[2]); + nwant = 3; com[0] *= sizescale; com[1] *= sizescale; com[2] *= sizescale; if (domain->dimension == 2 && com[2] != 0.0) error->all(FLERR,"Molecule file z center-of-mass must be 0.0 for 2d"); - } - else if (strstr(line,"inertia")) { + } else if (strstr(line,"inertia")) { inertiaflag = 1; - sscanf(line,"%lg %lg %lg %lg %lg %lg", - &itensor[0],&itensor[1],&itensor[2], - &itensor[3],&itensor[4],&itensor[5]); - itensor[0] *= sizescale*sizescale*sizescale*sizescale*sizescale; - itensor[1] *= sizescale*sizescale*sizescale*sizescale*sizescale; - itensor[2] *= sizescale*sizescale*sizescale*sizescale*sizescale; - itensor[3] *= sizescale*sizescale*sizescale*sizescale*sizescale; - itensor[4] *= sizescale*sizescale*sizescale*sizescale*sizescale; - itensor[5] *= sizescale*sizescale*sizescale*sizescale*sizescale; - } - else if (strstr(line,"body")) { + nmatch = sscanf(line,"%lg %lg %lg %lg %lg %lg", + &itensor[0],&itensor[1],&itensor[2], + &itensor[3],&itensor[4],&itensor[5]); + nwant = 6; + const double scale5 = sizescale*sizescale*sizescale*sizescale*sizescale; + itensor[0] *= scale5; + itensor[1] *= scale5; + itensor[2] *= scale5; + itensor[3] *= scale5; + itensor[4] *= scale5; + itensor[5] *= scale5; + } else if (strstr(line,"body")) { bodyflag = 1; avec_body = (AtomVecBody *) atom->style_match("body"); if (!avec_body) error->all(FLERR,"Molecule file requires atom style body"); - sscanf(line,"%d %d",&nibody,&ndbody); - } + nmatch = sscanf(line,"%d %d",&nibody,&ndbody); + nwant = 2; + } else break; - else break; + if (nmatch != nwant) + error->all(FLERR,"Invalid header in molecule file"); } // error checks @@ -493,7 +507,7 @@ void Molecule::read(int flag) // loop over sections of molecule file - while (strlen(keyword)) { + while (strlen(keyword) > 0) { if (strcmp(keyword,"Coords") == 0) { xflag = 1; if (flag) coords(line); @@ -517,22 +531,22 @@ void Molecule::read(int flag) } else if (strcmp(keyword,"Bonds") == 0) { if (nbonds == 0) - error->all(FLERR,"Molecule file has bonds but no nbonds setting"); + error->all(FLERR,"Molecule file has bonds but no nbonds setting"); bondflag = tag_require = 1; bonds(flag,line); } else if (strcmp(keyword,"Angles") == 0) { if (nangles == 0) - error->all(FLERR,"Molecule file has angles but no nangles setting"); + error->all(FLERR,"Molecule file has angles but no nangles setting"); angleflag = tag_require = 1; angles(flag,line); } else if (strcmp(keyword,"Dihedrals") == 0) { if (ndihedrals == 0) error->all(FLERR,"Molecule file has dihedrals " - "but no ndihedrals setting"); + "but no ndihedrals setting"); dihedralflag = tag_require = 1; dihedrals(flag,line); } else if (strcmp(keyword,"Impropers") == 0) { if (nimpropers == 0) error->all(FLERR,"Molecule file has impropers " - "but no nimpropers setting"); + "but no nimpropers setting"); improperflag = tag_require = 1; impropers(flag,line); @@ -552,26 +566,26 @@ void Molecule::read(int flag) shakeatomflag = tag_require = 1; if (shaketypeflag) shakeflag = 1; if (!shakeflagflag) - error->all(FLERR,"Molecule file shake flags not before shake atoms"); + error->all(FLERR,"Molecule file shake flags not before shake atoms"); if (flag) shakeatom_read(line); else skip_lines(natoms,line); } else if (strcmp(keyword,"Shake Bond Types") == 0) { shaketypeflag = 1; if (shakeatomflag) shakeflag = 1; if (!shakeflagflag) - error->all(FLERR,"Molecule file shake flags not before shake bonds"); + error->all(FLERR,"Molecule file shake flags not before shake bonds"); if (flag) shaketype_read(line); else skip_lines(natoms,line); } else if (strcmp(keyword,"Body Integers") == 0) { if (bodyflag == 0 || nibody == 0) - error->all(FLERR,"Molecule file has body params " + error->all(FLERR,"Molecule file has body params " "but no setting for them"); ibodyflag = 1; body(flag,0,line); } else if (strcmp(keyword,"Body Doubles") == 0) { if (bodyflag == 0 || ndbody == 0) - error->all(FLERR,"Molecule file has body params " + error->all(FLERR,"Molecule file has body params " "but no setting for them"); dbodyflag = 1; body(flag,1,line); @@ -618,7 +632,7 @@ void Molecule::read(int flag) // body particle must have natom = 1 // set radius by having body class compute its own radius - + if (bodyflag) { radiusflag = 1; if (natoms != 1) @@ -641,12 +655,9 @@ void Molecule::coords(char *line) int tmp; for (int i = 0; i < natoms; i++) { readline(line); - if (i == 0) { - int nwords = atom->count_words(line); - if (nwords != 4) - error->all(FLERR,"Invalid Coords section in molecule file"); - } - sscanf(line,"%d %lg %lg %lg",&tmp,&x[i][0],&x[i][1],&x[i][2]); + if (4 != sscanf(line,"%d %lg %lg %lg",&tmp,&x[i][0],&x[i][1],&x[i][2])) + error->all(FLERR,"Invalid Coords section in molecule file"); + x[i][0] *= sizescale; x[i][1] *= sizescale; x[i][2] *= sizescale; @@ -669,12 +680,8 @@ void Molecule::types(char *line) int tmp; for (int i = 0; i < natoms; i++) { readline(line); - if (i == 0) { - int nwords = atom->count_words(line); - if (nwords != 2) - error->all(FLERR,"Invalid Types section in molecule file"); - } - sscanf(line,"%d %d",&tmp,&type[i]); + if (2 != sscanf(line,"%d %d",&tmp,&type[i])) + error->all(FLERR,"Invalid Types section in molecule file"); type[i] += toffset; } @@ -695,12 +702,8 @@ void Molecule::charges(char *line) int tmp; for (int i = 0; i < natoms; i++) { readline(line); - if (i == 0) { - int nwords = atom->count_words(line); - if (nwords != 2) - error->all(FLERR,"Invalid Charges section in molecule file"); - } - sscanf(line,"%d %lg",&tmp,&q[i]); + if (2 != sscanf(line,"%d %lg",&tmp,&q[i])) + error->all(FLERR,"Invalid Charges section in molecule file"); } } @@ -714,12 +717,8 @@ void Molecule::diameters(char *line) maxradius = 0.0; for (int i = 0; i < natoms; i++) { readline(line); - if (i == 0) { - int nwords = atom->count_words(line); - if (nwords != 2) - error->all(FLERR,"Invalid Diameters section in molecule file"); - } - sscanf(line,"%d %lg",&tmp,&radius[i]); + if (2 != sscanf(line,"%d %lg",&tmp,&radius[i])) + error->all(FLERR,"Invalid Diameters section in molecule file"); radius[i] *= sizescale; radius[i] *= 0.5; maxradius = MAX(maxradius,radius[i]); @@ -739,12 +738,8 @@ void Molecule::masses(char *line) int tmp; for (int i = 0; i < natoms; i++) { readline(line); - if (i == 0) { - int nwords = atom->count_words(line); - if (nwords != 2) - error->all(FLERR,"Invalid Masses section in molecule file"); - } - sscanf(line,"%d %lg",&tmp,&rmass[i]); + if (2 != sscanf(line,"%d %lg",&tmp,&rmass[i])) + error->all(FLERR,"Invalid Masses section in molecule file"); rmass[i] *= sizescale*sizescale*sizescale; } @@ -773,17 +768,13 @@ void Molecule::bonds(int flag, char *line) for (int i = 0; i < nbonds; i++) { readline(line); - if (i == 0) { - int nwords = atom->count_words(line); - if (nwords != 4) - error->all(FLERR,"Invalid Bonds section in molecule file"); - } - sscanf(line,"%d %d " TAGINT_FORMAT " " TAGINT_FORMAT, - &tmp,&itype,&atom1,&atom2); + if (4 != sscanf(line,"%d %d " TAGINT_FORMAT " " TAGINT_FORMAT, + &tmp,&itype,&atom1,&atom2)) + error->all(FLERR,"Invalid Bonds section in molecule file"); itype += boffset; if (atom1 <= 0 || atom1 > natoms || - atom2 <= 0 || atom2 > natoms) + atom2 <= 0 || atom2 > natoms) error->one(FLERR,"Invalid atom ID in Bonds section of molecule file"); if (itype <= 0) error->one(FLERR,"Invalid bond type in Bonds section of molecule file"); @@ -795,10 +786,10 @@ void Molecule::bonds(int flag, char *line) bond_atom[m][num_bond[m]] = atom2; num_bond[m]++; if (newton_bond == 0) { - m = atom2-1; - bond_type[m][num_bond[m]] = itype; - bond_atom[m][num_bond[m]] = atom1; - num_bond[m]++; + m = atom2-1; + bond_type[m][num_bond[m]] = itype; + bond_atom[m][num_bond[m]] = atom1; + num_bond[m]++; } } else { count[atom1-1]++; @@ -835,13 +826,9 @@ void Molecule::angles(int flag, char *line) for (int i = 0; i < nangles; i++) { readline(line); - if (i == 0) { - int nwords = atom->count_words(line); - if (nwords != 5) - error->all(FLERR,"Invalid Angles section in molecule file"); - } - sscanf(line,"%d %d " TAGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT, - &tmp,&itype,&atom1,&atom2,&atom3); + if (5 != sscanf(line,"%d %d " TAGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT, + &tmp,&itype,&atom1,&atom2,&atom3)) + error->all(FLERR,"Invalid Angles section in molecule file"); itype += aoffset; if (atom1 <= 0 || atom1 > natoms || @@ -860,24 +847,24 @@ void Molecule::angles(int flag, char *line) angle_atom3[m][num_angle[m]] = atom3; num_angle[m]++; if (newton_bond == 0) { - m = atom1-1; - angle_type[m][num_angle[m]] = itype; - angle_atom1[m][num_angle[m]] = atom1; - angle_atom2[m][num_angle[m]] = atom2; - angle_atom3[m][num_angle[m]] = atom3; - num_angle[m]++; - m = atom3-1; - angle_type[m][num_angle[m]] = itype; - angle_atom1[m][num_angle[m]] = atom1; - angle_atom2[m][num_angle[m]] = atom2; - angle_atom3[m][num_angle[m]] = atom3; - num_angle[m]++; + m = atom1-1; + angle_type[m][num_angle[m]] = itype; + angle_atom1[m][num_angle[m]] = atom1; + angle_atom2[m][num_angle[m]] = atom2; + angle_atom3[m][num_angle[m]] = atom3; + num_angle[m]++; + m = atom3-1; + angle_type[m][num_angle[m]] = itype; + angle_atom1[m][num_angle[m]] = atom1; + angle_atom2[m][num_angle[m]] = atom2; + angle_atom3[m][num_angle[m]] = atom3; + num_angle[m]++; } } else { count[atom2-1]++; if (newton_bond == 0) { - count[atom1-1]++; - count[atom3-1]++; + count[atom1-1]++; + count[atom3-1]++; } } } @@ -911,14 +898,10 @@ void Molecule::dihedrals(int flag, char *line) for (int i = 0; i < ndihedrals; i++) { readline(line); - if (i == 0) { - int nwords = atom->count_words(line); - if (nwords != 6) - error->all(FLERR,"Invalid Dihedrals section in molecule file"); - } - sscanf(line,"%d %d " TAGINT_FORMAT " " TAGINT_FORMAT " " + if (6 != sscanf(line,"%d %d " TAGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT " ", - &tmp,&itype,&atom1,&atom2,&atom3,&atom4); + &tmp,&itype,&atom1,&atom2,&atom3,&atom4)) + error->all(FLERR,"Invalid Dihedrals section in molecule file"); itype += doffset; if (atom1 <= 0 || atom1 > natoms || @@ -926,10 +909,10 @@ void Molecule::dihedrals(int flag, char *line) atom3 <= 0 || atom3 > natoms || atom4 <= 0 || atom4 > natoms) error->one(FLERR, - "Invalid atom ID in dihedrals section of molecule file"); + "Invalid atom ID in dihedrals section of molecule file"); if (itype <= 0) error->one(FLERR, - "Invalid dihedral type in dihedrals section of molecule file"); + "Invalid dihedral type in dihedrals section of molecule file"); if (flag) { m = atom2-1; @@ -941,34 +924,34 @@ void Molecule::dihedrals(int flag, char *line) dihedral_atom4[m][num_dihedral[m]] = atom4; num_dihedral[m]++; if (newton_bond == 0) { - m = atom1-1; - dihedral_type[m][num_dihedral[m]] = itype; - dihedral_atom1[m][num_dihedral[m]] = atom1; - dihedral_atom2[m][num_dihedral[m]] = atom2; - dihedral_atom3[m][num_dihedral[m]] = atom3; - dihedral_atom4[m][num_dihedral[m]] = atom4; - num_dihedral[m]++; - m = atom3-1; - dihedral_type[m][num_dihedral[m]] = itype; - dihedral_atom1[m][num_dihedral[m]] = atom1; - dihedral_atom2[m][num_dihedral[m]] = atom2; - dihedral_atom3[m][num_dihedral[m]] = atom3; - dihedral_atom4[m][num_dihedral[m]] = atom4; - num_dihedral[m]++; - m = atom4-1; - dihedral_type[m][num_dihedral[m]] = itype; - dihedral_atom1[m][num_dihedral[m]] = atom1; - dihedral_atom2[m][num_dihedral[m]] = atom2; - dihedral_atom3[m][num_dihedral[m]] = atom3; - dihedral_atom4[m][num_dihedral[m]] = atom4; - num_dihedral[m]++; + m = atom1-1; + dihedral_type[m][num_dihedral[m]] = itype; + dihedral_atom1[m][num_dihedral[m]] = atom1; + dihedral_atom2[m][num_dihedral[m]] = atom2; + dihedral_atom3[m][num_dihedral[m]] = atom3; + dihedral_atom4[m][num_dihedral[m]] = atom4; + num_dihedral[m]++; + m = atom3-1; + dihedral_type[m][num_dihedral[m]] = itype; + dihedral_atom1[m][num_dihedral[m]] = atom1; + dihedral_atom2[m][num_dihedral[m]] = atom2; + dihedral_atom3[m][num_dihedral[m]] = atom3; + dihedral_atom4[m][num_dihedral[m]] = atom4; + num_dihedral[m]++; + m = atom4-1; + dihedral_type[m][num_dihedral[m]] = itype; + dihedral_atom1[m][num_dihedral[m]] = atom1; + dihedral_atom2[m][num_dihedral[m]] = atom2; + dihedral_atom3[m][num_dihedral[m]] = atom3; + dihedral_atom4[m][num_dihedral[m]] = atom4; + num_dihedral[m]++; } } else { count[atom2-1]++; if (newton_bond == 0) { - count[atom1-1]++; - count[atom3-1]++; - count[atom4-1]++; + count[atom1-1]++; + count[atom3-1]++; + count[atom4-1]++; } } } @@ -1002,14 +985,10 @@ void Molecule::impropers(int flag, char *line) for (int i = 0; i < nimpropers; i++) { readline(line); - if (i == 0) { - int nwords = atom->count_words(line); - if (nwords != 6) - error->all(FLERR,"Invalid Impropers section in molecule file"); - } - sscanf(line,"%d %d " TAGINT_FORMAT " " TAGINT_FORMAT " " + if (6 != sscanf(line,"%d %d " TAGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT " ", - &tmp,&itype,&atom1,&atom2,&atom3,&atom4); + &tmp,&itype,&atom1,&atom2,&atom3,&atom4)) + error->all(FLERR,"Invalid Impropers section in molecule file"); itype += ioffset; if (atom1 <= 0 || atom1 > natoms || @@ -1017,10 +996,10 @@ void Molecule::impropers(int flag, char *line) atom3 <= 0 || atom3 > natoms || atom4 <= 0 || atom4 > natoms) error->one(FLERR, - "Invalid atom ID in impropers section of molecule file"); + "Invalid atom ID in impropers section of molecule file"); if (itype <= 0) error->one(FLERR, - "Invalid improper type in impropers section of molecule file"); + "Invalid improper type in impropers section of molecule file"); if (flag) { m = atom2-1; @@ -1032,34 +1011,34 @@ void Molecule::impropers(int flag, char *line) improper_atom4[m][num_improper[m]] = atom4; num_improper[m]++; if (newton_bond == 0) { - m = atom1-1; - improper_type[m][num_improper[m]] = itype; - improper_atom1[m][num_improper[m]] = atom1; - improper_atom2[m][num_improper[m]] = atom2; - improper_atom3[m][num_improper[m]] = atom3; - improper_atom4[m][num_improper[m]] = atom4; - num_improper[m]++; - m = atom3-1; - improper_type[m][num_improper[m]] = itype; - improper_atom1[m][num_improper[m]] = atom1; - improper_atom2[m][num_improper[m]] = atom2; - improper_atom3[m][num_improper[m]] = atom3; - improper_atom4[m][num_improper[m]] = atom4; - num_improper[m]++; - m = atom4-1; - improper_type[m][num_improper[m]] = itype; - improper_atom1[m][num_improper[m]] = atom1; - improper_atom2[m][num_improper[m]] = atom2; - improper_atom3[m][num_improper[m]] = atom3; - improper_atom4[m][num_improper[m]] = atom4; - num_improper[m]++; + m = atom1-1; + improper_type[m][num_improper[m]] = itype; + improper_atom1[m][num_improper[m]] = atom1; + improper_atom2[m][num_improper[m]] = atom2; + improper_atom3[m][num_improper[m]] = atom3; + improper_atom4[m][num_improper[m]] = atom4; + num_improper[m]++; + m = atom3-1; + improper_type[m][num_improper[m]] = itype; + improper_atom1[m][num_improper[m]] = atom1; + improper_atom2[m][num_improper[m]] = atom2; + improper_atom3[m][num_improper[m]] = atom3; + improper_atom4[m][num_improper[m]] = atom4; + num_improper[m]++; + m = atom4-1; + improper_type[m][num_improper[m]] = itype; + improper_atom1[m][num_improper[m]] = atom1; + improper_atom2[m][num_improper[m]] = atom2; + improper_atom3[m][num_improper[m]] = atom3; + improper_atom4[m][num_improper[m]] = atom4; + num_improper[m]++; } } else { count[atom2-1]++; if (newton_bond == 0) { - count[atom1-1]++; - count[atom3-1]++; - count[atom4-1]++; + count[atom1-1]++; + count[atom3-1]++; + count[atom4-1]++; } } } @@ -1087,13 +1066,9 @@ void Molecule::nspecial_read(int flag, char *line) for (int i = 0; i < natoms; i++) { readline(line); - if (i == 0) { - int nwords = atom->count_words(line); - if (nwords != 4) - error->all(FLERR,"Invalid Special Bond Counts section in " - "molecule file"); - } - sscanf(line,"%d %d %d %d",&tmp,&c1,&c2,&c3); + if (4 != sscanf(line,"%d %d %d %d",&tmp,&c1,&c2,&c3)) + error->all(FLERR,"Invalid Special Bond Counts section in " + "molecule file"); if (flag) { nspecial[i][0] = c1; @@ -1117,13 +1092,13 @@ void Molecule::special_read(char *line) nwords = parse(line,words,maxspecial+1); if (nwords != nspecial[i][2]+1) error->all(FLERR,"Molecule file special list " - "does not match special count"); + "does not match special count"); for (m = 1; m < nwords; m++) { special[i][m-1] = ATOTAGINT(words[m]); if (special[i][m-1] <= 0 || special[i][m-1] > natoms || - special[i][m-1] == i+1) - error->all(FLERR,"Invalid special atom index in molecule file"); + special[i][m-1] == i+1) + error->all(FLERR,"Invalid special atom index in molecule file"); } } @@ -1229,7 +1204,8 @@ void Molecule::shakeflag_read(char *line) int tmp; for (int i = 0; i < natoms; i++) { readline(line); - sscanf(line,"%d %d",&tmp,&shake_flag[i]); + if (2 != sscanf(line,"%d %d",&tmp,&shake_flag[i])) + error->all(FLERR,"Invalid Shake Flags section in molecule file"); } for (int i = 0; i < natoms; i++) @@ -1243,23 +1219,32 @@ void Molecule::shakeflag_read(char *line) void Molecule::shakeatom_read(char *line) { - int tmp; + int tmp, nmatch, nwant; for (int i = 0; i < natoms; i++) { readline(line); - if (shake_flag[i] == 1) - sscanf(line,"%d " TAGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT, - &tmp,&shake_atom[i][0],&shake_atom[i][1],&shake_atom[i][2]); - else if (shake_flag[i] == 2) - sscanf(line,"%d " TAGINT_FORMAT " " TAGINT_FORMAT, - &tmp,&shake_atom[i][0],&shake_atom[i][1]); - else if (shake_flag[i] == 3) - sscanf(line,"%d " TAGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT, - &tmp,&shake_atom[i][0],&shake_atom[i][1],&shake_atom[i][2]); - else if (shake_flag[i] == 4) - sscanf(line,"%d " TAGINT_FORMAT " " TAGINT_FORMAT " " - TAGINT_FORMAT " " TAGINT_FORMAT, - &tmp,&shake_atom[i][0],&shake_atom[i][1], - &shake_atom[i][2],&shake_atom[i][3]); + if (shake_flag[i] == 1) { + nmatch = sscanf(line,"%d " TAGINT_FORMAT " " TAGINT_FORMAT + " " TAGINT_FORMAT,&tmp,&shake_atom[i][0], + &shake_atom[i][1],&shake_atom[i][2]); + nwant = 4; + } else if (shake_flag[i] == 2) { + nmatch = sscanf(line,"%d " TAGINT_FORMAT " " TAGINT_FORMAT, + &tmp,&shake_atom[i][0],&shake_atom[i][1]); + nwant = 3; + } else if (shake_flag[i] == 3) { + nmatch = sscanf(line,"%d " TAGINT_FORMAT " " TAGINT_FORMAT + " " TAGINT_FORMAT,&tmp,&shake_atom[i][0], + &shake_atom[i][1],&shake_atom[i][2]); + nwant = 4; + } else if (shake_flag[i] == 4) { + nmatch = sscanf(line,"%d " TAGINT_FORMAT " " TAGINT_FORMAT " " + TAGINT_FORMAT " " TAGINT_FORMAT, + &tmp,&shake_atom[i][0],&shake_atom[i][1], + &shake_atom[i][2],&shake_atom[i][3]); + nwant = 5; + } + if (nmatch != nwant) + error->all(FLERR,"Invalid shake atom in molecule file"); } for (int i = 0; i < natoms; i++) { @@ -1277,19 +1262,27 @@ void Molecule::shakeatom_read(char *line) void Molecule::shaketype_read(char *line) { - int tmp; + int tmp,nmatch,nwant; for (int i = 0; i < natoms; i++) { readline(line); - if (shake_flag[i] == 1) - sscanf(line,"%d %d %d %d",&tmp, - &shake_type[i][0],&shake_type[i][1],&shake_type[i][2]); - else if (shake_flag[i] == 2) - sscanf(line,"%d %d",&tmp,&shake_type[i][0]); - else if (shake_flag[i] == 3) - sscanf(line,"%d %d %d",&tmp,&shake_type[i][0],&shake_type[i][1]); - else if (shake_flag[i] == 4) - sscanf(line,"%d %d %d %d",&tmp, - &shake_type[i][0],&shake_type[i][1],&shake_type[i][2]); + if (shake_flag[i] == 1) { + nmatch = sscanf(line,"%d %d %d %d",&tmp,&shake_type[i][0], + &shake_type[i][1],&shake_type[i][2]); + nwant = 4; + } else if (shake_flag[i] == 2) { + nmatch = sscanf(line,"%d %d",&tmp,&shake_type[i][0]); + nwant = 2; + } else if (shake_flag[i] == 3) { + nmatch = sscanf(line,"%d %d %d",&tmp,&shake_type[i][0], + &shake_type[i][1]); + nwant = 3; + } else if (shake_flag[i] == 4) { + nmatch = sscanf(line,"%d %d %d %d",&tmp,&shake_type[i][0], + &shake_type[i][1],&shake_type[i][2]); + nwant = 4; + } + if (nmatch != nwant) + error->all(FLERR,"Invalid shake type data in molecule file"); } for (int i = 0; i < natoms; i++) { @@ -1501,46 +1494,46 @@ void Molecule::allocate() if (bondflag) { memory->create(bond_type,natoms,bond_per_atom, - "molecule:bond_type"); + "molecule:bond_type"); memory->create(bond_atom,natoms,bond_per_atom, - "molecule:bond_atom"); + "molecule:bond_atom"); } if (angleflag) { memory->create(angle_type,natoms,angle_per_atom, - "molecule:angle_type"); + "molecule:angle_type"); memory->create(angle_atom1,natoms,angle_per_atom, - "molecule:angle_atom1"); + "molecule:angle_atom1"); memory->create(angle_atom2,natoms,angle_per_atom, - "molecule:angle_atom2"); + "molecule:angle_atom2"); memory->create(angle_atom3,natoms,angle_per_atom, - "molecule:angle_atom3"); + "molecule:angle_atom3"); } if (dihedralflag) { memory->create(dihedral_type,natoms,dihedral_per_atom, - "molecule:dihedral_type"); + "molecule:dihedral_type"); memory->create(dihedral_atom1,natoms,dihedral_per_atom, - "molecule:dihedral_atom1"); + "molecule:dihedral_atom1"); memory->create(dihedral_atom2,natoms,dihedral_per_atom, - "molecule:dihedral_atom2"); + "molecule:dihedral_atom2"); memory->create(dihedral_atom3,natoms,dihedral_per_atom, - "molecule:dihedral_atom3"); + "molecule:dihedral_atom3"); memory->create(dihedral_atom4,natoms,dihedral_per_atom, - "molecule:dihedral_atom4"); + "molecule:dihedral_atom4"); } if (improperflag) { memory->create(improper_type,natoms,improper_per_atom, - "molecule:improper_type"); + "molecule:improper_type"); memory->create(improper_atom1,natoms,improper_per_atom, - "molecule:improper_atom1"); + "molecule:improper_atom1"); memory->create(improper_atom2,natoms,improper_per_atom, - "molecule:improper_atom2"); + "molecule:improper_atom2"); memory->create(improper_atom3,natoms,improper_per_atom, - "molecule:improper_atom3"); + "molecule:improper_atom3"); memory->create(improper_atom4,natoms,improper_per_atom, - "molecule:improper_atom4"); + "molecule:improper_atom4"); } if (shakeflag) { @@ -1653,7 +1646,7 @@ void Molecule::parse_keyword(int flag, char *line, char *keyword) if (me == 0) { if (fgets(line,MAXLINE,fp) == NULL) eof = 1; while (eof == 0 && strspn(line," \t\n\r") == strlen(line)) { - if (fgets(line,MAXLINE,fp) == NULL) eof = 1; + if (fgets(line,MAXLINE,fp) == NULL) eof = 1; } if (fgets(keyword,MAXLINE,fp) == NULL) eof = 1; } From c8741f3a01a2067c5a79dcafa0a187e95ee6a138 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 10 Aug 2017 15:12:56 -0400 Subject: [PATCH 357/439] remove special_bonds extra keyword and refer to read_data and create_box instead --- doc/src/Section_errors.txt | 8 +++---- doc/src/fix_bond_create.txt | 5 ++--- doc/src/special_bonds.txt | 42 ++++++------------------------------- doc/src/tutorial_drude.txt | 5 +++-- src/force.cpp | 6 ------ src/input.cpp | 4 +--- 6 files changed, 16 insertions(+), 54 deletions(-) diff --git a/doc/src/Section_errors.txt b/doc/src/Section_errors.txt index 408c01d52c..f5829f92fb 100644 --- a/doc/src/Section_errors.txt +++ b/doc/src/Section_errors.txt @@ -7886,8 +7886,8 @@ keyword to allow for additional bonds to be formed :dd {New bond exceeded special list size in fix bond/create} :dt -See the "special_bonds extra" command -(or the "read_data extra/special/per/atom" command) +See the "read_data extra/special/per/atom" command +(or the "create_box extra/special/per/atom" command) for info on how to leave space in the special bonds list to allow for additional bonds to be formed. :dd @@ -9666,8 +9666,8 @@ you are running. :dd {Special list size exceeded in fix bond/create} :dt -See the special_bonds extra command -(or the read_data extra/special/per/atom command) +See the "read_data extra/special/per/atom" command +(or the "create_box extra/special/per/atom" command) for info on how to leave space in the special bonds list to allow for additional bonds to be formed. :dd diff --git a/doc/src/fix_bond_create.txt b/doc/src/fix_bond_create.txt index a44c3103dd..c0045ac0f0 100644 --- a/doc/src/fix_bond_create.txt +++ b/doc/src/fix_bond_create.txt @@ -150,10 +150,9 @@ atoms. Note that adding a single bond always adds a new 1st neighbor but may also induce *many* new 2nd and 3rd neighbors, depending on the molecular topology of your system. The "extra special per atom" parameter must typically be set to allow for the new maximum total -size (1st + 2nd + 3rd neighbors) of this per-atom list. There are 3 +size (1st + 2nd + 3rd neighbors) of this per-atom list. There are 2 ways to do this. See the "read_data"_read_data.html or -"create_box"_create_box.html or "special_bonds extra" commands for -details. +"create_box"_create_box.html commands for details. NOTE: Even if you do not use the {atype}, {dtype}, or {itype} keywords, the list of topological neighbors is updated for atoms diff --git a/doc/src/special_bonds.txt b/doc/src/special_bonds.txt index 6a661015bd..1021c4856b 100644 --- a/doc/src/special_bonds.txt +++ b/doc/src/special_bonds.txt @@ -25,9 +25,7 @@ keyword = {amber} or {charmm} or {dreiding} or {fene} or {lj/coul} or {lj} or {c {coul} values = w1,w2,w3 w1,w2,w3 = weights (0.0 to 1.0) on pairwise Coulombic interactions {angle} value = {yes} or {no} - {dihedral} value = {yes} or {no} - {extra} value = N - N = number of extra 1-2,1-3,1-4 interactions to save space for :pre + {dihedral} value = {yes} or {no} :pre :ule Examples: @@ -36,8 +34,7 @@ special_bonds amber special_bonds charmm special_bonds fene dihedral no special_bonds lj/coul 0.0 0.0 0.5 angle yes dihedral yes -special_bonds lj 0.0 0.0 0.5 coul 0.0 0.0 0.0 dihedral yes -special_bonds lj/coul 0 1 1 extra 2 :pre +special_bonds lj 0.0 0.0 0.5 coul 0.0 0.0 0.0 dihedral yes :pre [Description:] @@ -178,14 +175,6 @@ interaction between atoms 2 and 5 will be unaffected (full weighting of 1.0). If the {dihedral} keyword is specified as {no} which is the default, then the 2,5 interaction will also be weighted by 0.5. -The {extra} keyword can be used when additional bonds will be created -during a simulation run, e.g. by the "fix -bond/create"_fix_bond_create.html command. It can also be used if -molecules will be added to the system, e.g. via the "fix -deposit"_fix_deposit.html, or "fix pour"_fix_pour.html commands, which -will have atoms with more special neighbors than any atom in the -current system has. - :line NOTE: LAMMPS stores and maintains a data structure with a list of the @@ -194,8 +183,9 @@ the system). If new bonds are created (or molecules added containing atoms with more special neighbors), the size of this list needs to grow. Note that adding a single bond always adds a new 1st neighbor but may also induce *many* new 2nd and 3rd neighbors, depending on the -molecular topology of your system. Using the {extra} keyword leaves -empty space in the list for this N additional 1st, 2nd, or 3rd +molecular topology of your system. Using the {extra/special/per/atom} +keyword to either "read_data"_read_data.html or "create_box"_create_box.html +reserves empty space in the list for this N additional 1st, 2nd, or 3rd neighbors to be added. If you do not do this, you may get an error when bonds (or molecules) are added. @@ -203,8 +193,7 @@ when bonds (or molecules) are added. NOTE: If you reuse this command in an input script, you should set all the options you need each time. This command cannot be used a 2nd -time incrementally, e.g. to add some extra storage locations via the -{extra} keyword. E.g. these two commands: +time incrementally. E.g. these two commands: special_bonds lj 0.0 1.0 1.0 special_bonds coul 0.0 0.0 1.0 @@ -221,25 +210,6 @@ Coul: coul 0.0 0.0 1.0 because the LJ settings are reset to their default values each time the command is issued. -Likewise - -special_bonds amber -special_bonds extra 2 :pre - -is not the same as this single command: - -special_bonds amber extra 2 :pre - -since in the former case, the 2nd command will reset all the LJ and -Coulombic weights to 0.0 (the default). - -One exception to this rule is the {extra} option itself. It is not -reset to its default value of 0 each time the special_bonds command is -invoked. This is because it can also be set by the -"read_data"_read_data.html and "create_box"_create_box.html commands, -so this command will not override those settings unless you explicitly -use {extra} as an option. - [Restrictions:] none [Related commands:] diff --git a/doc/src/tutorial_drude.txt b/doc/src/tutorial_drude.txt index b9a167b804..f6e7eed40b 100644 --- a/doc/src/tutorial_drude.txt +++ b/doc/src/tutorial_drude.txt @@ -176,12 +176,13 @@ By recognizing the fix {drude}, LAMMPS will find and store matching DC-DP pairs and will treat DP as equivalent to their DC in the {special bonds} relations. It may be necessary to extend the space for storing such special relations. In this case extra space should -be reserved by using the {extra} keyword of the {special_bonds} +be reserved by using the {extra/special/per/atom} keyword of either +the "read_data"_read_data.html or "create_box"_create_box.html command. With our phenol, there is 1 more special neighbor for which space is required. Otherwise LAMMPS crashes and gives the required value. -special_bonds lj/coul 0.0 0.0 0.5 extra 1 :pre +read_data data-p.lmp extra/special/per/atom 1 :pre Let us assume we want to run a simple NVT simulation at 300 K. Note that Drude oscillators need to be thermalized at a low temperature in diff --git a/src/force.cpp b/src/force.cpp index 33e6630406..060cae10eb 100644 --- a/src/force.cpp +++ b/src/force.cpp @@ -833,10 +833,6 @@ void Force::set_special(int narg, char **arg) else if (strcmp(arg[iarg+1],"yes") == 0) special_dihedral = 1; else error->all(FLERR,"Illegal special_bonds command"); iarg += 2; - } else if (strcmp(arg[iarg],"extra") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal special_bonds command"); - special_extra = atoi(arg[iarg+1]); - iarg += 2; } else error->all(FLERR,"Illegal special_bonds command"); } @@ -844,8 +840,6 @@ void Force::set_special(int narg, char **arg) if (special_lj[i] < 0.0 || special_lj[i] > 1.0 || special_coul[i] < 0.0 || special_coul[i] > 1.0) error->all(FLERR,"Illegal special_bonds command"); - - if (special_extra < 0) error->all(FLERR,"Illegal special_bonds command"); } /* ---------------------------------------------------------------------- diff --git a/src/input.cpp b/src/input.cpp index 570560373a..7d11b8741b 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -1867,7 +1867,6 @@ void Input::special_bonds() double coul3 = force->special_coul[3]; int angle = force->special_angle; int dihedral = force->special_dihedral; - int extra = force->special_extra; force->set_special(narg,arg); @@ -1877,8 +1876,7 @@ void Input::special_bonds() if (lj2 != force->special_lj[2] || lj3 != force->special_lj[3] || coul2 != force->special_coul[2] || coul3 != force->special_coul[3] || angle != force->special_angle || - dihedral != force->special_dihedral || - extra != force->special_extra) { + dihedral != force->special_dihedral) { Special special(lmp); special.build(); } From 8c16ea1bfca530875edc25ebd33aa061274c7e34 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 10 Aug 2017 15:58:51 -0400 Subject: [PATCH 358/439] add automatic triggering of review requests with a code owners file --- .github/CODEOWNERS | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 .github/CODEOWNERS diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000000..fdee6325d0 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,21 @@ +# This file contains file patterns that triggers automatic +# code review requests from users that are owners of these files +# Order matters, the last match has the highest precedence + +# library folders +lib/colvars/* @giacomofiorin +lib/compress/* @akohlmey +lib/kokkos/* @stanmoore1 +lib/molfile/* @akohlmey +lib/qmmm/* @akohlmey +lib/vtk/* @rbberger + +# packages +src/KOKKOS @stanmoore1 +src/USER-CGSDK @akohlmey +src/USER-COLVARS @giacomofiorin +src/USER-OMP @akohlmey +src/USER-QMMM @akohlmey + +# tools +tools/msi2lmp/* @akohlmey From 81e7d4a94259b90dd141829be57f36b3dc4ccb8a Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sat, 12 Aug 2017 00:35:50 -0400 Subject: [PATCH 359/439] fix incorrect preprocessor define for windows --- src/info.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/info.cpp b/src/info.cpp index 9fcc24fde9..03eb1e10ed 100644 --- a/src/info.cpp +++ b/src/info.cpp @@ -45,7 +45,7 @@ #include #ifdef _WIN32 -#define PSAPI_VERSION=1 +#define PSAPI_VERSION 1 #include #include #include From 60e14f14906c5b2914362c57558afc1c64a4cc25 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 14 Aug 2017 08:54:26 -0400 Subject: [PATCH 360/439] add comment to msi2lmp README about symmetry limitations --- tools/msi2lmp/README | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/msi2lmp/README b/tools/msi2lmp/README index db9b1aca5e..9ac7af5607 100644 --- a/tools/msi2lmp/README +++ b/tools/msi2lmp/README @@ -140,6 +140,8 @@ msi2lmp has the following known limitations: - there is no support for auto-equivalences to supplement fully parameterized interactions with heuristic ones - there is no support for bond increments +- there is no support for coordinates defined by symmetry operations, + i.e. the .mdf file has to be set up for space group P1 ------------------------------------------------------------------------ From cee87d7a54b59d65d21ed68a5b7407067ccc8e5a Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 15 Aug 2017 16:19:09 -0400 Subject: [PATCH 361/439] update manual to point to packages.lammps.org instead of rpm.lammps.org --- doc/src/Manual.txt | 2 +- doc/src/Section_start.txt | 54 +++++++++++++++++----------- doc/src/tutorial_bash_on_windows.txt | 0 doc/src/tutorials.txt | 0 4 files changed, 34 insertions(+), 22 deletions(-) mode change 100755 => 100644 doc/src/tutorial_bash_on_windows.txt mode change 100755 => 100644 doc/src/tutorials.txt diff --git a/doc/src/Manual.txt b/doc/src/Manual.txt index 07f0c8df41..d78df81a5b 100644 --- a/doc/src/Manual.txt +++ b/doc/src/Manual.txt @@ -79,7 +79,7 @@ bug reports and feature requests are mainly coordinated through the "LAMMPS project on GitHub."_https://github.com/lammps/lammps The lammps.org domain, currently hosting "public continuous integration testing"_https://ci.lammps.org/job/lammps/ and "precompiled Linux -RPM and Windows installer packages"_http://rpm.lammps.org is located +RPM and Windows installer packages"_http://packages.lammps.org is located at Temple University and managed by Richard Berger, richard.berger at temple.edu. diff --git a/doc/src/Section_start.txt b/doc/src/Section_start.txt index 6eef155be2..a25ec11cfe 100644 --- a/doc/src/Section_start.txt +++ b/doc/src/Section_start.txt @@ -662,27 +662,25 @@ your own build system. Due to differences between the Windows OS and Windows system libraries to Unix-like environments like Linux or MacOS, when compiling for Windows a few adjustments may be needed: -Do not set the -DLAMMPS_MEMALIGN define (see LMP_INC makefile variable) +Do [not] set the -DLAMMPS_MEMALIGN define (see LMP_INC makefile variable) Add -lwsock32 -lpsapi to the linker flags (see LIB makefile variable) -Try adding -static-libgcc or -static or both to the linker flags when your -LAMMPS executable complains about missing .dll files :ul +Try adding -static-libgcc or -static or both to the linker flags when your LAMMPS executable complains about missing .dll files :ul -Since none of the current LAMMPS core developers -has significant experience building executables on Windows, we are -happy to distribute contributed instructions and modifications, but -we cannot provide support for those. +Since none of the current LAMMPS core developers has significant +experience building executables on Windows, we are happy to distribute +contributed instructions and modifications to improve the situation, +but we cannot provide support for those. With the so-called "Anniversary Update" to Windows 10, there is a Ubuntu Linux subsystem available for Windows, that can be installed and then used to compile/install LAMMPS as if you are running on a Ubuntu Linux system instead of Windows. -As an alternative, you can download "daily builds" (and some older -versions) of the installer packages from -"rpm.lammps.org/windows.html"_http://rpm.lammps.org/windows.html. -These executables are built with most optional packages and the -download includes documentation, potential files, some tools and -many examples, but no source code. +As an alternative, you can download pre-compiled installer packages from +"packages.lammps.org/windows.html"_http://packages.lammps.org/windows.html. +These executables are built with most optional packages included and the +download includes documentation, potential files, some tools and many +examples, but no source code. :line @@ -1095,7 +1093,7 @@ LAMMPS to be built with one or more of its optional packages. :line On a Windows box, you can skip making LAMMPS and simply download an -installer package from "here"_http://rpm.lammps.org/windows.html +installer package from "here"_http://packages.lammps.org/windows.html For running the non-MPI executable, follow these steps: @@ -1107,18 +1105,27 @@ the [in.lj] input from the bench folder. (e.g. by typing: cd "Documents"). :l At the command prompt, type "lmp_serial -in in.lj", replacing [in.lj] with the name of your LAMMPS input script. :l + +The serial executable includes support for multi-threading +parallelization from the styles in the USER-OMP packages. + +To run with, e.g. 4 threads, type "lmp_serial -in in.lj -pk omp 4 -sf omp" :ule -For the MPI version, which allows you to run LAMMPS under Windows on -multiple processors, follow these steps: +For the MPI version, which allows you to run LAMMPS under Windows with +the more general message passing parallel library (LAMMPS has been +designed from ground up to use MPI efficiently), follow these steps: -Download and install -"MPICH2"_http://www.mcs.anl.gov/research/projects/mpich2/downloads/index.php?s=downloads -for Windows. :ulb,l +Download and install a compatible MPI library binary package: +for 32-bit Windows +"mpich2-1.4.1p1-win-ia32.msi"_download.lammps.org/thirdparty/mpich2-1.4.1p1-win-ia32.msi +and for 64-bit Windows +"mpich2-1.4.1p1-win-x86-64.msi"_download.lammps.org/thirdparty/mpich2-1.4.1p1-win-x86-64.msi +:ulb,l The LAMMPS Windows installer packages will automatically adjust your path for the default location of this MPI package. After the installation -of the MPICH software, it needs to be integrated into the system. +of the MPICH2 software, it needs to be integrated into the system. For this you need to start a Command Prompt in {Administrator Mode} (right click on the icon and select it). Change into the MPICH2 installation directory, then into the subdirectory [bin] and execute @@ -1137,7 +1144,7 @@ or mpiexec -np 4 lmp_mpi -in in.lj :pre -replacing in.lj with the name of your LAMMPS input script. For the latter +replacing [in.lj] with the name of your LAMMPS input script. For the latter case, you may be prompted to enter your password. :l In this mode, output may not immediately show up on the screen, so if @@ -1149,6 +1156,11 @@ something like: lmp_mpi -in in.lj :pre +And the parallel executable also includes OpenMP multi-threading, which +can be combined with MPI using something like: + +mpiexec -localonly 2 lmp_mpi -in in.lj -pk omp 2 -sf omp :pre + :ule :line diff --git a/doc/src/tutorial_bash_on_windows.txt b/doc/src/tutorial_bash_on_windows.txt old mode 100755 new mode 100644 diff --git a/doc/src/tutorials.txt b/doc/src/tutorials.txt old mode 100755 new mode 100644 From 1d4d2155a23bedcb3bda3c471940dc65fa09a523 Mon Sep 17 00:00:00 2001 From: Steve Plimpton Date: Tue, 15 Aug 2017 17:12:07 -0600 Subject: [PATCH 362/439] USER-INTEL add-ons from Mike --- doc/src/JPG/user_intel.png | Bin 14487 -> 20491 bytes doc/src/accelerate_intel.txt | 6 +- doc/src/pair_airebo.txt | 3 + doc/src/pair_charmm.txt | 1 + doc/src/pair_eam.txt | 2 + src/MAKE/OPTIONS/Makefile.intel_cpu_intelmpi | 2 +- src/MAKE/OPTIONS/Makefile.intel_cpu_mpich | 2 +- src/MAKE/OPTIONS/Makefile.intel_cpu_openmpi | 2 +- src/USER-INTEL/Install.sh | 1 + src/USER-INTEL/README | 2 +- src/USER-INTEL/TEST/README | 2 + src/USER-INTEL/TEST/in.intel.airebo | 47 + src/USER-INTEL/TEST/in.intel.eam | 1 - src/USER-INTEL/TEST/in.intel.rhodo | 1 - src/USER-INTEL/intel_buffers.cpp | 47 +- src/USER-INTEL/intel_buffers.h | 18 +- src/USER-INTEL/intel_intrinsics_airebo.h | 2279 ++++++++ src/USER-INTEL/nbin_intel.cpp | 12 +- src/USER-INTEL/npair_full_bin_ghost_intel.cpp | 593 ++ src/USER-INTEL/npair_full_bin_ghost_intel.h | 55 + src/USER-INTEL/npair_intel.cpp | 25 +- src/USER-INTEL/pair_airebo_intel.cpp | 4891 +++++++++++++++++ src/USER-INTEL/pair_airebo_intel.h | 110 + src/USER-INTEL/pair_airebo_morse_intel.cpp | 37 + src/USER-INTEL/pair_airebo_morse_intel.h | 40 + src/USER-INTEL/pair_eam_alloy_intel.cpp | 326 ++ src/USER-INTEL/pair_eam_alloy_intel.h | 43 + src/USER-INTEL/pair_eam_fs_intel.cpp | 335 ++ src/USER-INTEL/pair_eam_fs_intel.h | 43 + src/USER-INTEL/pair_gayberne_intel.cpp | 2 +- .../pair_lj_charmm_coul_charmm_intel.cpp | 595 ++ .../pair_lj_charmm_coul_charmm_intel.h | 100 + src/USER-INTEL/pair_rebo_intel.cpp | 42 + src/USER-INTEL/pair_rebo_intel.h | 40 + src/USER-INTEL/pair_sw_intel.cpp | 19 +- 35 files changed, 9675 insertions(+), 49 deletions(-) create mode 100644 src/USER-INTEL/TEST/in.intel.airebo create mode 100644 src/USER-INTEL/intel_intrinsics_airebo.h create mode 100644 src/USER-INTEL/npair_full_bin_ghost_intel.cpp create mode 100644 src/USER-INTEL/npair_full_bin_ghost_intel.h create mode 100644 src/USER-INTEL/pair_airebo_intel.cpp create mode 100644 src/USER-INTEL/pair_airebo_intel.h create mode 100644 src/USER-INTEL/pair_airebo_morse_intel.cpp create mode 100644 src/USER-INTEL/pair_airebo_morse_intel.h create mode 100644 src/USER-INTEL/pair_eam_alloy_intel.cpp create mode 100644 src/USER-INTEL/pair_eam_alloy_intel.h create mode 100644 src/USER-INTEL/pair_eam_fs_intel.cpp create mode 100644 src/USER-INTEL/pair_eam_fs_intel.h create mode 100644 src/USER-INTEL/pair_lj_charmm_coul_charmm_intel.cpp create mode 100644 src/USER-INTEL/pair_lj_charmm_coul_charmm_intel.h create mode 100644 src/USER-INTEL/pair_rebo_intel.cpp create mode 100644 src/USER-INTEL/pair_rebo_intel.h diff --git a/doc/src/JPG/user_intel.png b/doc/src/JPG/user_intel.png index 302b50124a0429d0f64df1a9979a5265051f8112..7ec83b3207b06c4bbda7d56f2a7d9d94a15d115d 100755 GIT binary patch literal 20491 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 C<%a

0" then "processors * * * grid numa" + +variable root getenv LMP_ROOT + +units metal +atom_style atomic + +read_data ${root}/examples/airebo/data.airebo + +replicate ${xx} ${yy} ${zz} + +neighbor 0.5 bin +neigh_modify delay 5 every 1 + +pair_style airebo 3.0 1 1 +pair_coeff * * ${root}/potentials/CH.airebo C H + +velocity all create 300.0 761341 + +fix 1 all nve +timestep 0.0005 + +thermo 50 + +if "$p > 0" then "run_style verlet/power" + +if "$w > 0" then "run $w" +run ${rr} diff --git a/src/USER-INTEL/TEST/in.intel.eam b/src/USER-INTEL/TEST/in.intel.eam index 5a3b3064af..6486b22ee9 100644 --- a/src/USER-INTEL/TEST/in.intel.eam +++ b/src/USER-INTEL/TEST/in.intel.eam @@ -5,7 +5,6 @@ variable w index 10 # Warmup Timesteps variable t index 3100 # Main Run Timesteps variable m index 1 # Main Run Timestep Multiplier variable n index 0 # Use NUMA Mapping for Multi-Node -variable b index 3 # Neighbor binsize variable p index 0 # Use Power Measurement variable x index 4 diff --git a/src/USER-INTEL/TEST/in.intel.rhodo b/src/USER-INTEL/TEST/in.intel.rhodo index 05145d79c0..7ce7eb4452 100644 --- a/src/USER-INTEL/TEST/in.intel.rhodo +++ b/src/USER-INTEL/TEST/in.intel.rhodo @@ -5,7 +5,6 @@ variable w index 10 # Warmup Timesteps variable t index 520 # Main Run Timesteps variable m index 1 # Main Run Timestep Multiplier variable n index 0 # Use NUMA Mapping for Multi-Node -variable b index 3 # Neighbor binsize variable p index 0 # Use Power Measurement variable c index 0 # 1 to use collectives for PPPM variable d index 1 # 1 to use 'diff ad' for PPPM diff --git a/src/USER-INTEL/intel_buffers.cpp b/src/USER-INTEL/intel_buffers.cpp index 3664bc248b..b4b664cb94 100644 --- a/src/USER-INTEL/intel_buffers.cpp +++ b/src/USER-INTEL/intel_buffers.cpp @@ -30,6 +30,9 @@ IntelBuffers::IntelBuffers(class LAMMPS *lmp_in) : _off_map_listlocal = 0; _ccachex = 0; _ncache_alloc = 0; + _ncachetag = 0; + _cutneighsq = 0; + _cutneighghostsq = 0; #ifdef _LMP_INTEL_OFFLOAD _separate_buffers = 0; _off_f = 0; @@ -447,12 +450,17 @@ void IntelBuffers::free_ncache() flt_t *ncachez = _ncachez; int *ncachej = _ncachej; int *ncachejtype = _ncachejtype; + int *ncachetag = _ncachetag; #ifdef _LMP_INTEL_OFFLOAD if (_off_ncache) { #pragma offload_transfer target(mic:_cop) \ nocopy(ncachex,ncachey,ncachez,ncachej:alloc_if(0) free_if(1)) \ nocopy(ncachejtype:alloc_if(0) free_if(1)) + if (ncachetag) { + #pragma offload_transfer target(mic:_cop) \ + nocopy(ncachetag:alloc_if(0) free_if(1)) + } } _off_ncache = 0; #endif @@ -462,8 +470,10 @@ void IntelBuffers::free_ncache() lmp->memory->destroy(ncachez); lmp->memory->destroy(ncachej); lmp->memory->destroy(ncachejtype); - + if (ncachetag) + lmp->memory->destroy(ncachetag); _ncache_alloc = 0; + _ncachetag = 0; } } @@ -480,7 +490,7 @@ void IntelBuffers::grow_ncache(const int off_flag, const int vsize = _ncache_stride * nt; if (_ncache_alloc) { - if (vsize > _ncache_alloc) + if (vsize > _ncache_alloc || (need_tag() && _ncachetag == 0)) free_ncache(); #ifdef _LMP_INTEL_OFFLOAD else if (off_flag && _off_ncache == 0) @@ -495,6 +505,8 @@ void IntelBuffers::grow_ncache(const int off_flag, lmp->memory->create(_ncachez, vsize, "_ncachez"); lmp->memory->create(_ncachej, vsize, "_ncachej"); lmp->memory->create(_ncachejtype, vsize, "_ncachejtype"); + if (need_tag()) + lmp->memory->create(_ncachetag, vsize, "_ncachetag"); _ncache_alloc = vsize; @@ -513,6 +525,14 @@ void IntelBuffers::grow_ncache(const int off_flag, nocopy(ncachez,ncachej:length(vsize) alloc_if(1) free_if(0)) \ nocopy(ncachejtype:length(vsize) alloc_if(1) free_if(0)) } + int tsize = vsize; + if (!need_tag()) { + tsize = 16; + lmp->memory->create(_ncachetag, tsize, "_ncachetag"); + } + int *ncachetag = _ncachetag; + #pragma offload_transfer target(mic:_cop) \ + nocopy(ncachetag:length(tsize) alloc_if(1) free_if(0)) _off_ncache = 1; } #endif @@ -548,7 +568,8 @@ void IntelBuffers::fdotr_reduce(const int nall, /* ---------------------------------------------------------------------- */ template -void IntelBuffers::set_ntypes(const int ntypes) +void IntelBuffers::set_ntypes(const int ntypes, + const int use_ghost_cut) { if (ntypes != _ntypes) { if (_ntypes > 0) { @@ -558,16 +579,34 @@ void IntelBuffers::set_ntypes(const int ntypes) #pragma offload_transfer target(mic:_cop) \ nocopy(cutneighsqo:alloc_if(0) free_if(1)) } + flt_t * cutneighghostsqo; + if (_cutneighghostsq && _off_threads > 0 && cutneighghostsqo != 0) { + cutneighghostsqo = _cutneighghostsq[0]; + #pragma offload_transfer target(mic:_cop) \ + nocopy(cutneighghostsqo:alloc_if(0) free_if(1)) + } #endif lmp->memory->destroy(_cutneighsq); + if (_cutneighghostsq != 0) lmp->memory->destroy(_cutneighghostsq); } if (ntypes > 0) { lmp->memory->create(_cutneighsq, ntypes, ntypes, "_cutneighsq"); + if (use_ghost_cut) + lmp->memory->create(_cutneighghostsq, ntypes, ntypes, + "_cutneighghostsq"); #ifdef _LMP_INTEL_OFFLOAD flt_t * cutneighsqo = _cutneighsq[0]; + const int ntypes2 = ntypes * ntypes; if (_off_threads > 0 && cutneighsqo != NULL) { #pragma offload_transfer target(mic:_cop) \ - nocopy(cutneighsqo:length(ntypes * ntypes) alloc_if(1) free_if(0)) + nocopy(cutneighsqo:length(ntypes2) alloc_if(1) free_if(0)) + } + if (use_ghost_cut) { + flt_t * cutneighghostsqo = _cutneighghostsq[0]; + if (_off_threads > 0 && cutneighghostsqo != NULL) { + #pragma offload_transfer target(mic:_cop) \ + nocopy(cutneighghostsqo:length(ntypes2) alloc_if(1) free_if(0)) + } } #endif } diff --git a/src/USER-INTEL/intel_buffers.h b/src/USER-INTEL/intel_buffers.h index 7a7640a203..8040715b2e 100644 --- a/src/USER-INTEL/intel_buffers.h +++ b/src/USER-INTEL/intel_buffers.h @@ -109,12 +109,14 @@ class IntelBuffers { void free_ncache(); void grow_ncache(const int off_flag, const int nthreads); + void grow_ncachetag(const int off_flag, const int nthreads); inline int ncache_stride() { return _ncache_stride; } inline flt_t * get_ncachex() { return _ncachex; } inline flt_t * get_ncachey() { return _ncachey; } inline flt_t * get_ncachez() { return _ncachez; } inline int * get_ncachej() { return _ncachej; } inline int * get_ncachejtype() { return _ncachejtype; } + inline int * get_ncachetag() { return _ncachetag; } inline int get_max_nbors() { int mn = lmp->neighbor->oneatom * sizeof(int) / @@ -131,7 +133,7 @@ class IntelBuffers { _grow_nbor_list(list, nlocal, nthreads, offload_end, pack_width); } - void set_ntypes(const int ntypes); + void set_ntypes(const int ntypes, const int use_ghost_cut = 0); inline int * firstneigh(const NeighList *list) { return _list_alloc; } inline int * cnumneigh(const NeighList *list) { return _cnumneigh; } @@ -162,6 +164,7 @@ class IntelBuffers { inline void zero_ev() { for (int i = 0; i < 8; i++) _ev_global[i] = _ev_global_host[i] = 0.0; } inline flt_t ** get_cutneighsq() { return _cutneighsq; } + inline flt_t ** get_cutneighghostsq() { return _cutneighghostsq; } inline int get_off_threads() { return _off_threads; } #ifdef _LMP_INTEL_OFFLOAD inline void set_off_params(const int n, const int cop, @@ -274,13 +277,10 @@ class IntelBuffers { used_ghost * sizeof(flt_t)); } } + #endif inline int need_tag() { return _need_tag; } inline void need_tag(const int nt) { _need_tag = nt; } - #else - inline int need_tag() { return 0; } - inline void need_tag(const int nt) { } - #endif double memory_usage(const int nthreads); @@ -298,7 +298,7 @@ class IntelBuffers { int _list_alloc_atoms; int *_list_alloc, *_cnumneigh, *_atombin, *_binpacked; - flt_t **_cutneighsq; + flt_t **_cutneighsq, **_cutneighghostsq; int _ntypes; int _ccache_stride; @@ -307,7 +307,10 @@ class IntelBuffers { int _ncache_stride, _ncache_alloc; flt_t *_ncachex, *_ncachey, *_ncachez; - int *_ncachej, *_ncachejtype; + int *_ncachej, *_ncachejtype, *_ncachetag; + + int _need_tag, _host_nmax; + #ifdef LMP_USE_AVXCD int _ccache_stride3; acc_t * _ccachef; @@ -324,7 +327,6 @@ class IntelBuffers { int *_off_map_special, *_off_map_nspecial, *_off_map_tag; int *_off_map_numneigh; bool _off_list_alloc; - int _need_tag, _host_nmax; #endif int _buf_size, _buf_local_size; diff --git a/src/USER-INTEL/intel_intrinsics_airebo.h b/src/USER-INTEL/intel_intrinsics_airebo.h new file mode 100644 index 0000000000..7b091a4ba1 --- /dev/null +++ b/src/USER-INTEL/intel_intrinsics_airebo.h @@ -0,0 +1,2279 @@ +#ifndef LMP_INTEL_AIREBO_SCALAR +# ifdef __INTEL_COMPILER +# if defined(__MIC__) || defined(__AVX512F__) +# define LMP_INTEL_AIREBO_512 +# elif defined(__AVX__) +# define LMP_INTEL_AIREBO_256 +# else +# define LMP_INTEL_AIREBO_SCALAR +# endif +# else +# define LMP_INTEL_AIREBO_SCALAR +# endif +#endif + +#ifdef LMP_INTEL_AIREBO_512 + +#include +#include + +#define VEC_INLINE __attribute__((always_inline)) + + +#ifndef FVEC_FIRST_PASS +# define FVEC_LEN 8 +# define FVEC_SUFFIX(a) a##pd +# define FVEC_SUFFIX_MASK(a) a##pd_mask +# define FVEC_MASK_T __mmask8 +# define FVEC_VEC_T __m512d +# define FVEC_SCAL_T double +# define IVEC_NAME ivec8 +# define FVEC_NAME fvec8pd +# define BVEC_NAME bvec8 +# define AVEC_NAME avec8pd +#else +# undef FVEC_LEN +# undef FVEC_SUFFIX +# undef FVEC_SUFFIX_MASK +# undef FVEC_MASK_T +# undef FVEC_VEC_T +# undef FVEC_SCAL_T +# undef IVEC_NAME +# undef FVEC_NAME +# undef BVEC_NAME +# undef AVEC_NAME + +# define FVEC_LEN 16 +# define FVEC_SUFFIX(a) a##ps +# define FVEC_SUFFIX_MASK(a) a##ps_mask +# define FVEC_MASK_T __mmask16 +# define FVEC_VEC_T __m512 +# define FVEC_SCAL_T float +# define IVEC_NAME ivec16 +# define FVEC_NAME fvec16ps +# define BVEC_NAME bvec16 +# define AVEC_NAME avec16ps +#endif + +namespace mm512 { + +#ifndef __AVX512F__ + +#ifndef FVEC_FIRST_PASS +VEC_INLINE static inline __m512i _mm512_mask_expand_epi32(__m512i src, + __mmask16 k, + __m512i a) { + int buf[16] __attribute__((aligned(64))); + _mm512_store_epi32(buf, a); + return _mm512_mask_loadunpacklo_epi32(src, k, buf); +} +VEC_INLINE static inline __m512i _mm512_maskz_expand_epi32(__mmask16 k, + __m512i a) { + int buf[16] __attribute__((aligned(64))); + _mm512_store_epi32(buf, a); + return _mm512_mask_loadunpacklo_epi32(_mm512_setzero_epi32(), k, buf); +} +VEC_INLINE static inline __m512i _mm512_mask_compress_epi32(__m512i src, + __mmask16 k, + __m512i a) { + int buf[16] __attribute__((aligned(64))); + _mm512_store_epi32(buf, src); + _mm512_mask_packstorelo_epi32(buf, k, a); + return _mm512_load_epi32(buf); +} +VEC_INLINE static inline __m512i _mm512_maskz_compress_epi32(__mmask16 k, + __m512i a) { + int buf[16] __attribute__((aligned(64))) = {0}; + _mm512_mask_packstorelo_epi32(buf, k, a); + return _mm512_load_epi32(buf); +} + +VEC_INLINE static inline void _mm512_mask_compressstoreu_epi32(int * dest, + __mmask16 mask, + __m512i src) { + _mm512_mask_packstorelo_epi32(dest, mask, src); + _mm512_mask_packstorehi_epi32(dest + 16, mask, src); +} + +VEC_INLINE static inline __m512i _mm512_mask_loadu_epi32(__m512i src, + __mmask16 k, + const int * mem_addr) { + assert((k & (k + 1)) == 0); + __m512i ret = _mm512_mask_loadunpacklo_epi32(src, k, mem_addr); + ret = _mm512_mask_loadunpackhi_epi32(ret, k, mem_addr + 16); + return ret; +} +VEC_INLINE static inline __m512i _mm512_maskz_loadu_epi32(__mmask16 k, + const int * mem_addr) { + assert((k & (k + 1)) == 0); + __m512i ret = _mm512_mask_loadunpacklo_epi32(_mm512_setzero_epi32(), k, + mem_addr); + ret = _mm512_mask_loadunpackhi_epi32(ret, k, mem_addr + 16); + return ret; +} +VEC_INLINE static inline void _mm512_mask_storeu_epi32(int * dest, + __mmask16 mask, + __m512i src) { + assert((mask & (mask + 1)) == 0); + _mm512_mask_packstorelo_epi32(dest, mask, src); + _mm512_mask_packstorehi_epi32(dest + 16, mask, src); +} +#endif + +VEC_INLINE static inline FVEC_VEC_T FVEC_SUFFIX(_mm512_mask_expand_) + (FVEC_VEC_T src, __mmask16 k, FVEC_VEC_T a) { + FVEC_SCAL_T buf[FVEC_LEN] __attribute__((aligned(64))); + FVEC_SUFFIX(_mm512_store_)(buf, a); + return FVEC_SUFFIX(_mm512_mask_loadunpacklo_)(src, k, buf); +} +VEC_INLINE static inline FVEC_VEC_T FVEC_SUFFIX(_mm512_maskz_expand_) + (__mmask16 k, FVEC_VEC_T a) { + FVEC_SCAL_T buf[FVEC_LEN] __attribute__((aligned(64))); + FVEC_SUFFIX(_mm512_store_)(buf, a); + return FVEC_SUFFIX(_mm512_mask_loadunpacklo_)(FVEC_SUFFIX(_mm512_setzero_)(), + k, buf); +} +VEC_INLINE static inline FVEC_VEC_T FVEC_SUFFIX(_mm512_mask_compress_) + (FVEC_VEC_T src, __mmask16 k, FVEC_VEC_T a) { + FVEC_SCAL_T buf[FVEC_LEN] __attribute__((aligned(64))); + FVEC_SUFFIX(_mm512_store_)(buf, src); + FVEC_SUFFIX(_mm512_mask_packstorelo_)(buf, k, a); + return FVEC_SUFFIX(_mm512_load_)(buf); +} +VEC_INLINE static inline FVEC_VEC_T FVEC_SUFFIX(_mm512_maskz_compress_) + (__mmask16 k, FVEC_VEC_T a) { + FVEC_SCAL_T buf[FVEC_LEN] __attribute__((aligned(64))) = {0}; + FVEC_SUFFIX(_mm512_mask_packstorelo_)(buf, k, a); + return FVEC_SUFFIX(_mm512_load_)(buf); +} +VEC_INLINE static inline void FVEC_SUFFIX(_mm512_mask_storeu_) + (FVEC_SCAL_T * dest, FVEC_MASK_T mask, FVEC_VEC_T src) { + assert((mask & (mask + 1)) == 0); + FVEC_SUFFIX(_mm512_mask_packstorelo_)(dest, mask, src); + FVEC_SUFFIX(_mm512_mask_packstorehi_)(dest + FVEC_LEN, mask, src); +} +#endif + + +class FVEC_NAME; +class IVEC_NAME; +class AVEC_NAME; +class BVEC_NAME { + friend class FVEC_NAME; + friend class IVEC_NAME; + friend class AVEC_NAME; +# if FVEC_LEN==16 + friend class avec16pd; +# endif + FVEC_MASK_T val_; + VEC_INLINE BVEC_NAME(const FVEC_MASK_T &v) : val_(v) {} +public: + VEC_INLINE BVEC_NAME() {} + VEC_INLINE static BVEC_NAME kand(const BVEC_NAME &a, const BVEC_NAME &b) { + return _mm512_kand(a.val_, b.val_); + } + VEC_INLINE static BVEC_NAME kandn(const BVEC_NAME &a, const BVEC_NAME &b) { + return _mm512_kandn(a.val_, b.val_); + } + VEC_INLINE static BVEC_NAME knot(const BVEC_NAME &a) { + return _mm512_knot(a.val_); + } + VEC_INLINE static int kortestz(const BVEC_NAME &a, const BVEC_NAME &b) { + return _mm512_kortestz(a.val_, b.val_); + } + VEC_INLINE static BVEC_NAME masku_compress(const BVEC_NAME &mask, + const BVEC_NAME &a) { + const __m512i c_i1 = _mm512_set1_epi32(1); + __m512i a_int_vec = _mm512_mask_blend_epi32(a.val_, _mm512_setzero_epi32(), + c_i1); + __m512i compressed = _mm512_mask_compress_epi32(_mm512_undefined_epi32(), + mask.val_, a_int_vec); + return _mm512_cmpeq_epi32_mask(compressed, c_i1); + } + VEC_INLINE static BVEC_NAME mask_expand(const BVEC_NAME &src, + const BVEC_NAME &mask, + const BVEC_NAME &a) { + const __m512i c_i1 = _mm512_set1_epi32(1); + __m512i a_int_vec = _mm512_mask_blend_epi32(a.val_, _mm512_setzero_epi32(), + c_i1); + __m512i src_int_vec = _mm512_mask_blend_epi32(src.val_, + _mm512_setzero_epi32(), c_i1); + __m512i compressed = _mm512_mask_expand_epi32(src_int_vec, mask.val_, + a_int_vec); + return _mm512_cmpeq_epi32_mask(compressed, c_i1); + } + VEC_INLINE static BVEC_NAME full() { + return static_cast(0xFFFF); + } + VEC_INLINE static BVEC_NAME empty() { + return 0; + } + VEC_INLINE static BVEC_NAME only(int n) { + return full().val_ >> (FVEC_LEN - n); + } + VEC_INLINE static BVEC_NAME after(int n) { + return full().val_ << n; + } + VEC_INLINE static BVEC_NAME onlyafter(int only, int after) { + return (full().val_ >> (FVEC_LEN - only)) << after; + } + VEC_INLINE static int popcnt(const BVEC_NAME &a) { + return _popcnt32(a.val_); + } + VEC_INLINE static bool test_all_unset(const BVEC_NAME &a) { + return _mm512_kortestz(a.val_, a.val_); + } + VEC_INLINE static bool test_any_set(const BVEC_NAME &a) { + return ! test_all_unset(a); + } + VEC_INLINE static bool test_at(const BVEC_NAME &a, int i) { + assert(i < FVEC_LEN); + return a.val_ & (1 << i); + } + VEC_INLINE BVEC_NAME operator &(const BVEC_NAME &b) const { + return _mm512_kand(val_, b.val_); + } + VEC_INLINE BVEC_NAME operator |(const BVEC_NAME &b) const { + return _mm512_kor(val_, b.val_); + } + VEC_INLINE BVEC_NAME operator ~() const { + return _mm512_knot(val_); + } +}; + +class IVEC_NAME { + friend class FVEC_NAME; + friend class AVEC_NAME; +# if FVEC_LEN==16 + friend class avec16pd; +# endif + __m512i val_; + VEC_INLINE IVEC_NAME(const __m512i &v) : val_(v) {} +public: + static const int VL = 16; + VEC_INLINE IVEC_NAME() {} + + #define IVEC_MASK_BINFN_B(the_name) \ + VEC_INLINE static BVEC_NAME the_name(const IVEC_NAME &a, \ + const IVEC_NAME &b) { \ + return _mm512_##the_name##_epi32_mask(a.val_, b.val_); \ + } \ + VEC_INLINE static BVEC_NAME mask_##the_name( \ + const BVEC_NAME &mask, \ + const IVEC_NAME &a, \ + const IVEC_NAME &b \ + ) { \ + return _mm512_mask_##the_name##_epi32_mask( \ + mask.val_, a.val_, b.val_); \ + } + IVEC_MASK_BINFN_B(cmpeq) + IVEC_MASK_BINFN_B(cmplt) + IVEC_MASK_BINFN_B(cmpneq) + IVEC_MASK_BINFN_B(cmpgt) + + #define IVEC_MASK_BINFN_I(the_name) \ + VEC_INLINE static IVEC_NAME mask_##the_name( \ + const IVEC_NAME &src, const BVEC_NAME &mask, \ + const IVEC_NAME &a, const IVEC_NAME &b \ + ) { \ + return _mm512_mask_##the_name##_epi32( \ + src.val_, mask.val_, a.val_, b.val_); \ + } + IVEC_MASK_BINFN_I(add) + VEC_INLINE static IVEC_NAME mask_blend( + const BVEC_NAME &mask, const IVEC_NAME &a, const IVEC_NAME &b + ) { + return _mm512_mask_blend_epi32(mask.val_, a.val_, b.val_); + } + + #define IVEC_BINFN_I(the_name) \ + VEC_INLINE static IVEC_NAME the_name(const IVEC_NAME &a, \ + const IVEC_NAME &b) { \ + return _mm512_##the_name##_epi32(a.val_, b.val_); \ + } + IVEC_BINFN_I(mullo) + IVEC_BINFN_I(srlv) + VEC_INLINE static IVEC_NAME the_and(const IVEC_NAME &a, const IVEC_NAME &b) { + return _mm512_and_epi32(a.val_, b.val_); + } + + VEC_INLINE static IVEC_NAME mask_expand( + const IVEC_NAME &src, const BVEC_NAME &a, const IVEC_NAME &b + ) { + return _mm512_mask_expand_epi32(src.val_, + a.val_, b.val_); + } + VEC_INLINE static IVEC_NAME masku_compress( + const BVEC_NAME &a, const IVEC_NAME &b + ) { + return _mm512_mask_compress_epi32(_mm512_undefined_epi32(), a.val_, b.val_); + } + + VEC_INLINE static int at(const IVEC_NAME &a, int b) { + int data[16] __attribute__((aligned(64))); + _mm512_store_epi32(data, a.val_); + return data[b]; + } + + VEC_INLINE static IVEC_NAME load(const int * src) { + return _mm512_load_epi32(src); + } + VEC_INLINE static IVEC_NAME mask_loadu(const BVEC_NAME &mask, + const int * src) { + assert((mask.val_ & (mask.val_ + 1)) == 0); + assert(mask.val_ <= BVEC_NAME::full().val_); + return _mm512_mask_loadu_epi32(_mm512_undefined_epi32(), mask.val_, src); + } + VEC_INLINE static IVEC_NAME maskz_loadu(const BVEC_NAME &mask, + const int * src) { + assert((mask.val_ & (mask.val_ + 1)) == 0); + assert(mask.val_ <= BVEC_NAME::full().val_); + return _mm512_maskz_loadu_epi32(mask.val_, src); + } + VEC_INLINE static void mask_storeu(const BVEC_NAME &mask, int * dest, + const IVEC_NAME &src) { + assert((mask.val_ & (mask.val_ + 1)) == 0); + assert(mask.val_ <= BVEC_NAME::full().val_); + _mm512_mask_storeu_epi32(dest, mask.val_, src.val_); + } + VEC_INLINE static void store(int * dest, const IVEC_NAME &src) { + _mm512_store_epi32(dest, src.val_); + } + + VEC_INLINE static IVEC_NAME mask_gather( + const IVEC_NAME &src, const BVEC_NAME &mask, const IVEC_NAME &idx, + const int * mem, const int scale + ) { + assert(mask.val_ <= BVEC_NAME::full().val_); + assert(scale == sizeof(int)); + return _mm512_mask_i32gather_epi32(src.val_, mask.val_, idx.val_, mem, + sizeof(int)); + } + VEC_INLINE static void mask_i32scatter( + int * mem, const BVEC_NAME &mask, const IVEC_NAME &idx, + const IVEC_NAME &a, const int scale + ) { + assert(mask.val_ <= BVEC_NAME::full().val_); + assert(scale == sizeof(int)); + _mm512_mask_i32scatter_epi32(mem, mask.val_, idx.val_, a.val_, sizeof(int)); + } + + VEC_INLINE static void mask_compressstore(const BVEC_NAME &mask, int * dest, + const IVEC_NAME &src) { + _mm512_mask_compressstoreu_epi32(dest, mask.val_, src.val_); + } + + VEC_INLINE static IVEC_NAME set1(int i) { + return _mm512_set1_epi32(i); + } + VEC_INLINE static IVEC_NAME setzero() { + return _mm512_setzero_epi32(); + } + VEC_INLINE static IVEC_NAME undefined() { + return _mm512_undefined_epi32(); + } + + VEC_INLINE IVEC_NAME operator +(const IVEC_NAME &b) const { + return _mm512_add_epi32(this->val_, b.val_); + } + VEC_INLINE static void print(const char * str, const IVEC_NAME &a) { + int data[8] __attribute__((aligned(32))); + store(data, a); + printf("%s:", str); + for (int i = 0; i < FVEC_LEN; i++) { + printf(" %d", data[i]); + } + printf("\n"); + } +}; + +class FVEC_NAME { + friend class AVEC_NAME; +#if FVEC_LEN==16 + friend class avec16pd; +#endif + FVEC_VEC_T val_; + VEC_INLINE FVEC_NAME(const FVEC_VEC_T &v) : val_(v) {} +public: + static const int VL = FVEC_LEN; + VEC_INLINE FVEC_NAME() {} + VEC_INLINE static FVEC_SCAL_T at(const FVEC_NAME &a, int i) { + assert(i < FVEC_LEN); + FVEC_SCAL_T data[FVEC_LEN] __attribute__((aligned(64))); + FVEC_SUFFIX(_mm512_store_)(data, a.val_); + return data[i]; + } + VEC_INLINE static bool fast_compress() { return true; } + + #define FVEC_MASK_BINFN_B(the_name) \ + VEC_INLINE static BVEC_NAME the_name(const FVEC_NAME &a, \ + const FVEC_NAME &b) { \ + return FVEC_SUFFIX_MASK(_mm512_##the_name##_)(a.val_, b.val_); \ + } \ + VEC_INLINE static BVEC_NAME mask_##the_name( \ + const BVEC_NAME &mask, \ + const FVEC_NAME &a, const FVEC_NAME &b \ + ) { \ + return FVEC_SUFFIX_MASK(_mm512_mask_##the_name##_)( \ + mask.val_, a.val_, b.val_); \ + } + FVEC_MASK_BINFN_B(cmple) + FVEC_MASK_BINFN_B(cmplt) + FVEC_MASK_BINFN_B(cmpneq) + FVEC_MASK_BINFN_B(cmpnle) + FVEC_MASK_BINFN_B(cmpnlt) + + #define FVEC_UNFN_F(the_name) \ + VEC_INLINE static FVEC_NAME the_name(const FVEC_NAME &a) { \ + return FVEC_SUFFIX(_mm512_##the_name##_)(a.val_); \ + } + FVEC_UNFN_F(abs) + FVEC_UNFN_F(exp) + FVEC_UNFN_F(invsqrt) + FVEC_UNFN_F(recip) + FVEC_UNFN_F(sqrt) + + #define FVEC_MASK_UNFN_F(the_name) \ + VEC_INLINE static FVEC_NAME mask_##the_name( \ + const FVEC_NAME &src, const BVEC_NAME &mask, \ + const FVEC_NAME &a \ + ) { \ + return FVEC_SUFFIX(_mm512_mask_##the_name##_)( \ + src.val_, mask.val_, a.val_); \ + } + FVEC_MASK_UNFN_F(cos) + FVEC_MASK_UNFN_F(recip) + FVEC_MASK_UNFN_F(sqrt) + + #define FVEC_BINFN_F(the_name) \ + VEC_INLINE static FVEC_NAME the_name(const FVEC_NAME &a, \ + const FVEC_NAME &b) { \ + return FVEC_SUFFIX(_mm512_##the_name##_)(a.val_, b.val_); \ + } + FVEC_BINFN_F(max) + FVEC_BINFN_F(min) + + #define FVEC_MASK_BINFN_F(the_name) \ + VEC_INLINE static FVEC_NAME mask_##the_name( \ + const FVEC_NAME &src, const BVEC_NAME &mask, \ + const FVEC_NAME &a, const FVEC_NAME &b \ + ) { \ + return FVEC_SUFFIX(_mm512_mask_##the_name##_)( \ + src.val_, mask.val_, a.val_, b.val_); \ + } + FVEC_MASK_BINFN_F(add) + FVEC_MASK_BINFN_F(div) + FVEC_MASK_BINFN_F(mul) + FVEC_MASK_BINFN_F(sub) + VEC_INLINE static FVEC_NAME mask_blend( + const BVEC_NAME &mask, const FVEC_NAME &a, const FVEC_NAME &b + ) { + return FVEC_SUFFIX(_mm512_mask_blend_)(mask.val_, a.val_, b.val_); + } + + VEC_INLINE static FVEC_NAME mask_expand( + const FVEC_NAME &src, const BVEC_NAME &a, const FVEC_NAME &b + ) { + return FVEC_SUFFIX(_mm512_mask_expand_)(src.val_, + a.val_, b.val_); + } + VEC_INLINE static FVEC_NAME masku_compress( + const BVEC_NAME &a, const FVEC_NAME &b + ) { + return FVEC_SUFFIX(_mm512_mask_compress_)(FVEC_SUFFIX(_mm512_undefined_)(), + a.val_, b.val_); + } + + VEC_INLINE static FVEC_NAME set1(const FVEC_SCAL_T &a) { + return FVEC_SUFFIX(_mm512_set1_)(a); + } + VEC_INLINE static FVEC_NAME setzero() { + return FVEC_SUFFIX(_mm512_setzero_)(); + } + VEC_INLINE static FVEC_NAME undefined() { + return FVEC_SUFFIX(_mm512_undefined_)(); + } + + VEC_INLINE static FVEC_NAME load(const FVEC_SCAL_T *mem) { + return FVEC_SUFFIX(_mm512_load_)(mem); + } + VEC_INLINE static void mask_storeu(const BVEC_NAME &mask, FVEC_SCAL_T * dest, + const FVEC_NAME &a) { + FVEC_SUFFIX(_mm512_mask_storeu_)(dest, mask.val_, a.val_); + } + VEC_INLINE static void store(FVEC_SCAL_T * dest, const FVEC_NAME &a) { + FVEC_SUFFIX(_mm512_store_)(dest, a.val_); + } + + VEC_INLINE static FVEC_NAME gather(const IVEC_NAME &idx, + const FVEC_SCAL_T * mem, + const int scale) { + assert(scale == sizeof(FVEC_SCAL_T)); +# if FVEC_LEN==8 + return FVEC_SUFFIX(_mm512_i32logather_)(idx.val_, mem, sizeof(FVEC_SCAL_T)); +# else + return FVEC_SUFFIX(_mm512_i32gather_)(idx.val_, mem, sizeof(FVEC_SCAL_T)); +# endif + } + VEC_INLINE static FVEC_NAME mask_gather( + const FVEC_NAME &src, const BVEC_NAME &mask, const IVEC_NAME &idx, + const FVEC_SCAL_T * mem, const int scale + ) { + assert(scale == sizeof(FVEC_SCAL_T)); +# if FVEC_LEN==8 + return FVEC_SUFFIX(_mm512_mask_i32logather_)(src.val_, mask.val_, idx.val_, + mem, sizeof(FVEC_SCAL_T)); +# else + return FVEC_SUFFIX(_mm512_mask_i32gather_)(src.val_, mask.val_, idx.val_, + mem, sizeof(FVEC_SCAL_T)); +# endif + } + + VEC_INLINE static void gather_3_adjacent(const IVEC_NAME &idx, + const FVEC_SCAL_T * mem, + const int scale, + FVEC_NAME * out_0, + FVEC_NAME * out_1, + FVEC_NAME * out_2) { + assert(scale == sizeof(FVEC_SCAL_T)); + *out_0 = FVEC_NAME::gather(idx, mem + 0, scale); + *out_1 = FVEC_NAME::gather(idx, mem + 1, scale); + *out_2 = FVEC_NAME::gather(idx, mem + 2, scale); + } + VEC_INLINE static void gather_4_adjacent(const IVEC_NAME &idx, + const FVEC_SCAL_T * mem, + const int scale, FVEC_NAME * out_0, + FVEC_NAME * out_1, + FVEC_NAME * out_2, + FVEC_NAME * out_3) { + assert(scale == sizeof(FVEC_SCAL_T)); + *out_0 = FVEC_NAME::gather(idx, mem + 0, scale); + *out_1 = FVEC_NAME::gather(idx, mem + 1, scale); + *out_2 = FVEC_NAME::gather(idx, mem + 2, scale); + *out_3 = FVEC_NAME::gather(idx, mem + 3, scale); + } + + VEC_INLINE static FVEC_SCAL_T mask_reduce_add(const BVEC_NAME &mask, + const FVEC_NAME &a) { + return FVEC_SUFFIX(_mm512_mask_reduce_add_)(mask.val_, a.val_); + } + VEC_INLINE static FVEC_SCAL_T reduce_add(const FVEC_NAME &a) { + return FVEC_SUFFIX(_mm512_reduce_add_)(a.val_); + } + + VEC_INLINE static IVEC_NAME unpackloepi32(const FVEC_NAME &a) { +# if FVEC_LEN==8 + return _mm512_maskz_compress_epi32(0x5555, _mm512_castpd_si512(a.val_)); +# else + return _mm512_castps_si512(a.val_); +# endif + } + + VEC_INLINE static FVEC_NAME mask_sincos( + FVEC_NAME * cos, const FVEC_NAME &src_a, const FVEC_NAME &src_b, + const BVEC_NAME &mask, const FVEC_NAME &arg + ) { + return FVEC_SUFFIX(_mm512_mask_sincos_)(&cos->val_, src_a.val_, src_b.val_, + mask.val_, arg.val_); + } + + #define FVEC_BINOP(the_sym, the_name) \ + VEC_INLINE inline FVEC_NAME operator the_sym(const FVEC_NAME &b) const { \ + return FVEC_SUFFIX(_mm512_##the_name##_)(this->val_, b.val_); \ + } + FVEC_BINOP(+, add) + FVEC_BINOP(-, sub) + FVEC_BINOP(*, mul) + FVEC_BINOP(/, div) + + VEC_INLINE static void gather_prefetch0(const IVEC_NAME &a, void * mem) { + #ifdef __AVX512PF__ + _mm512_mask_prefetch_i32gather_ps(a.val_, BVEC_NAME::full().val_, mem, + sizeof(FVEC_SCAL_T), _MM_HINT_T0); + #endif + } +}; + +class AVEC_NAME { + FVEC_VEC_T val_; + VEC_INLINE AVEC_NAME(const FVEC_VEC_T &a) : val_(a) {} +public: + VEC_INLINE AVEC_NAME(const FVEC_NAME &a) : val_(a.val_) {} + VEC_INLINE static AVEC_NAME undefined() { + return FVEC_SUFFIX(_mm512_undefined_)(); + } + VEC_INLINE static AVEC_NAME mask_gather( + const AVEC_NAME &src, const BVEC_NAME &mask, const IVEC_NAME &idx, + const FVEC_SCAL_T * mem, const int scale + ) { + assert(scale == sizeof(FVEC_SCAL_T)); +# if FVEC_LEN==8 + return FVEC_SUFFIX(_mm512_mask_i32logather_)(src.val_, mask.val_, idx.val_, + mem, sizeof(FVEC_SCAL_T)); +# else + return FVEC_SUFFIX(_mm512_mask_i32gather_)(src.val_, mask.val_, idx.val_, + mem, sizeof(FVEC_SCAL_T)); +# endif + } + VEC_INLINE static void mask_i32loscatter( + FVEC_SCAL_T * mem, const BVEC_NAME &mask, const IVEC_NAME &idx, + const AVEC_NAME &a, const int scale + ) { + assert(scale == sizeof(FVEC_SCAL_T)); +# if FVEC_LEN==8 + FVEC_SUFFIX(_mm512_mask_i32loscatter_)(mem, mask.val_, idx.val_, a.val_, + sizeof(FVEC_SCAL_T)); +# else + FVEC_SUFFIX(_mm512_mask_i32scatter_)(mem, mask.val_, idx.val_, a.val_, + sizeof(FVEC_SCAL_T)); +# endif + } + + #define AVEC_BINOP(the_sym, the_name) \ + VEC_INLINE inline AVEC_NAME operator the_sym(const AVEC_NAME &b) const { \ + return FVEC_SUFFIX(_mm512_##the_name##_)(this->val_, b.val_); \ + } + AVEC_BINOP(-, sub) + + VEC_INLINE static void gather_prefetch0(const IVEC_NAME &a, void * mem) { + _mm512_mask_prefetch_i32gather_ps(a.val_, BVEC_NAME::full().val_, mem, + sizeof(FVEC_SCAL_T), _MM_HINT_T0); + } +}; + +#if FVEC_LEN==16 +class avec16pd { + __m512d lo_, hi_; + VEC_INLINE avec16pd(const __m512d &lo, const __m512d &hi) : lo_(lo), hi_(hi) + {} + VEC_INLINE static __mmask8 get_bvec_hi(__mmask16 a) { + return a >> 8; + } + VEC_INLINE static __m512i get_ivec_hi(__m512i a) { + return _mm512_permute4f128_epi32(a, _MM_PERM_BADC); + } +public: + VEC_INLINE avec16pd(const FVEC_NAME &a) { + lo_ = _mm512_cvtpslo_pd(a.val_); + hi_ = _mm512_cvtpslo_pd(_mm512_permute4f128_ps(a.val_, _MM_PERM_BADC)); + } + VEC_INLINE static avec16pd undefined() { + return avec16pd(_mm512_undefined_pd(), _mm512_undefined_pd()); + } + VEC_INLINE static avec16pd mask_gather( + const avec16pd &src, const BVEC_NAME &mask, const IVEC_NAME &idx, + const double * mem, const int scale + ) { + assert(scale == sizeof(double)); + __m512d lo = _mm512_mask_i32logather_pd(src.lo_, mask.val_, idx.val_, mem, + sizeof(double)); + __m512d hi = _mm512_mask_i32logather_pd(src.hi_, get_bvec_hi(mask.val_), + get_ivec_hi(idx.val_), mem, + sizeof(double)); + return avec16pd(lo, hi); + } + VEC_INLINE static void mask_i32loscatter( + double * mem, const BVEC_NAME &mask, const IVEC_NAME &idx, + const avec16pd &a, const int scale + ) { + assert(scale == sizeof(double)); + _mm512_mask_i32loscatter_pd(mem, mask.val_, idx.val_, a.lo_, + sizeof(double)); + _mm512_mask_i32loscatter_pd(mem, get_bvec_hi(mask.val_), + get_ivec_hi(idx.val_), a.hi_, sizeof(double)); + } + + #define AVEC2_BINOP(the_sym, the_name) \ + VEC_INLINE inline avec16pd operator the_sym(const avec16pd &b) const { \ + __m512d lo = _mm512_##the_name##_pd(this->lo_, b.lo_); \ + __m512d hi = _mm512_##the_name##_pd(this->hi_, b.hi_); \ + return avec16pd(lo, hi); \ + } + AVEC2_BINOP(-, sub) + + VEC_INLINE static void gather_prefetch0(const IVEC_NAME &a, void * mem) { + _mm512_mask_prefetch_i32gather_ps(a.val_, BVEC_NAME::full().val_, mem, + sizeof(double), _MM_HINT_T0); + } +}; +#endif + +} + + +#ifdef FVEC_FIRST_PASS + +template +struct intr_types; + +template<> +struct intr_types { + typedef mm512::fvec8pd fvec; + typedef mm512::ivec8 ivec; + typedef mm512::bvec8 bvec; + typedef mm512::avec8pd avec; +}; + +template<> +struct intr_types { + typedef mm512::fvec16ps fvec; + typedef mm512::ivec16 ivec; + typedef mm512::bvec16 bvec; + typedef mm512::avec16ps avec; +}; + +template<> +struct intr_types { + typedef mm512::fvec16ps fvec; + typedef mm512::ivec16 ivec; + typedef mm512::bvec16 bvec; + typedef mm512::avec16pd avec; +}; + +#endif + + +#ifndef FVEC_FIRST_PASS +# define FVEC_FIRST_PASS +# include "intel_intrinsics_airebo.h" +#endif + +#endif + +#ifdef LMP_INTEL_AIREBO_256 + +#include +#include +#include + +#define VEC_INLINE __attribute__((always_inline)) + + +#ifndef FVEC_FIRST_PASS +# define FVEC_LEN 4 +# define FVEC_SUFFIX(a) a##pd +# define FVEC_MASK_T __m256d +# define FVEC_VEC_T __m256d +# define FVEC_SCAL_T double +# define IVEC_NAME ivec4 +# define FVEC_NAME fvec4pd +# define BVEC_NAME bvec4 +# define AVEC_NAME avec4pd +#else +# undef FVEC_LEN +# undef FVEC_SUFFIX +# undef FVEC_SUFFIX_MASK +# undef FVEC_MASK_T +# undef FVEC_VEC_T +# undef FVEC_SCAL_T +# undef IVEC_NAME +# undef FVEC_NAME +# undef BVEC_NAME +# undef AVEC_NAME + +# define FVEC_LEN 8 +# define FVEC_SUFFIX(a) a##ps +# define FVEC_MASK_T __m256 +# define FVEC_VEC_T __m256 +# define FVEC_SCAL_T float +# define IVEC_NAME ivec8 +# define FVEC_NAME fvec8ps +# define BVEC_NAME bvec8 +# define AVEC_NAME avec8ps +#endif + + + +namespace mm256 { + +//#define __AVX2__ __AVX2__ + +#if !defined(__AVX2__) && !defined(FVEC_FIRST_PASS) + +#define IVEC_EM_BIN(op) \ + __m128i a_lo = _mm256_castsi256_si128(a); \ + __m128i b_lo = _mm256_castsi256_si128(b); \ + __m128i a_hi = _mm256_extractf128_si256(a, 1); \ + __m128i b_hi = _mm256_extractf128_si256(b, 1); \ + __m128i c_lo = op(a_lo, b_lo); \ + __m128i c_hi = op(a_hi, b_hi); \ + __m256i ret = _mm256_setr_m128i(c_lo, c_hi); \ + return ret; + +VEC_INLINE inline __m256i _cm256_add_epi32(const __m256i &a, const __m256i &b) { + IVEC_EM_BIN(_mm_add_epi32) +} + +VEC_INLINE inline __m256i _cm256_and_si256(const __m256i &a, const __m256i &b) { + IVEC_EM_BIN(_mm_and_si128) +} + +VEC_INLINE inline __m256i _cm256_andnot_si256(const __m256i &a, + const __m256i &b) { + IVEC_EM_BIN(_mm_andnot_si128) +} + +VEC_INLINE inline __m256i _cm256_cmpeq_epi32(const __m256i &a, + const __m256i &b) { + IVEC_EM_BIN(_mm_cmpeq_epi32) +} + +VEC_INLINE inline __m256i _cm256_cmpgt_epi32(const __m256i &a, + const __m256i &b) { + IVEC_EM_BIN(_mm_cmpgt_epi32) +} + +VEC_INLINE inline __m256i _cm256_cvtepu8_epi32(const __m128i &a) { + __m128i a_hi = _mm_castps_si128(_mm_permute_ps(_mm_castsi128_ps(a), 1)); + __m128i c_lo = _mm_cvtepu8_epi32(a); + __m128i c_hi = _mm_cvtepu8_epi32(a_hi); + __m256i ret = _mm256_setr_m128i(c_lo, c_hi); + return ret; + +} + +#define IVEC_EM_SCAL(op) \ + int buf_a[8] __attribute__((aligned(32))); \ + int buf_b[8] __attribute__((aligned(32))); \ + int dest[8] __attribute__((aligned(32))); \ + _mm256_store_si256((__m256i*)buf_a, a); \ + _mm256_store_si256((__m256i*)buf_b, b); \ + for (int i = 0; i < 8; i++) { \ + dest[i] = op; \ + } \ + return _mm256_load_si256((__m256i*) dest); + +VEC_INLINE inline __m256i _cm256_permutevar8x32_epi32(const __m256i &a, + const __m256i &b) { + IVEC_EM_SCAL(buf_a[buf_b[i]]) +} + +VEC_INLINE inline __m256i _cm256_mullo_epi32(__m256i a, __m256i b) { + IVEC_EM_BIN(_mm_mullo_epi32) +} + +VEC_INLINE inline __m256i _cm256_srlv_epi32(__m256i a, __m256i b) { + IVEC_EM_SCAL(buf_a[i] >> buf_b[i]) +} + + +VEC_INLINE inline __m256 _cm256_permutevar8x32_ps(const __m256 &a, + const __m256i &b) { + return _mm256_castsi256_ps(_cm256_permutevar8x32_epi32(_mm256_castps_si256(a), + b)); +} + +VEC_INLINE inline __m128i _cm_maskload_epi32(int const * mem, __m128i mask) { + return _mm_castps_si128(_mm_maskload_ps((float const *) mem, mask)); +} + +VEC_INLINE inline __m256i _cm256_maskload_epi32(int const * mem, __m256i mask) { + __m128i a_lo = _mm256_castsi256_si128(mask); + __m128i a_hi = _mm256_extractf128_si256(mask, 1); + __m128i c_lo = _cm_maskload_epi32(mem, a_lo); + __m128i c_hi = _cm_maskload_epi32(mem + 4, a_hi); + __m256i ret = _mm256_setr_m128i(c_lo, c_hi); + return ret; +} + + +VEC_INLINE inline __m256i _cm256_mask_i32gather_epi32(__m256i src, + int const * base_addr, + __m256i index, + __m256i mask, + const int scale) { + assert(scale == sizeof(int)); + int buf_index[8] __attribute__((aligned(32))); + int buf_mask[8] __attribute__((aligned(32))); + int dest[8] __attribute__((aligned(32))); + _mm256_store_si256((__m256i*)dest, src); + _mm256_store_si256((__m256i*)buf_index, index); + _mm256_store_si256((__m256i*)buf_mask, mask); + for (int i = 0; i < 8; i++) { + if (buf_mask[i]) dest[i] = base_addr[buf_index[i]]; + } + return _mm256_load_si256((__m256i*) dest); +} + +VEC_INLINE inline __m256 _cm256_mask_i32gather_ps(__m256 src, + float const * base_addr, + __m256i index, __m256 mask, + const int scale) { + return _mm256_castsi256_ps(_cm256_mask_i32gather_epi32( + _mm256_castps_si256(src), (const int *) base_addr, index, + _mm256_castps_si256(mask), scale)); +} + +VEC_INLINE inline __m256d _cm256_mask_i32gather_pd(__m256d src, + double const * base_addr, + __m128i index, __m256d mask, + const int scale) { + assert(scale == sizeof(double)); + int buf_index[4] __attribute__((aligned(32))); + int buf_mask[8] __attribute__((aligned(32))); + double dest[4] __attribute__((aligned(32))); + _mm256_store_pd(dest, src); + _mm_store_si128((__m128i*)buf_index, index); + _mm256_store_si256((__m256i*)buf_mask, _mm256_castpd_si256(mask)); + for (int i = 0; i < 4; i++) { + if (buf_mask[2*i]) dest[i] = base_addr[buf_index[i]]; + } + return _mm256_load_pd(dest); +} + +VEC_INLINE inline __m256i _cm256_i32gather_epi32(int const * base_addr, + __m256i index, + const int scale) { + assert(scale == sizeof(int)); + int buf_index[8] __attribute__((aligned(32))); + int dest[8] __attribute__((aligned(32))); + _mm256_store_si256((__m256i*)buf_index, index); + for (int i = 0; i < 8; i++) { + dest[i] = base_addr[buf_index[i]]; + } + return _mm256_load_si256((__m256i*) dest); +} + +VEC_INLINE inline __m256 _cm256_i32gather_ps(float const * base_addr, + __m256i index, const int scale) { + return _mm256_castsi256_ps(_cm256_i32gather_epi32((const int *) base_addr, + index, scale)); +} + +VEC_INLINE inline __m256d _cm256_i32gather_pd(double const * base_addr, + __m128i index, const int scale) { + assert(scale == sizeof(double)); + int buf_index[4] __attribute__((aligned(32))); + double dest[4] __attribute__((aligned(32))); + _mm_store_si128((__m128i*)buf_index, index); + for (int i = 0; i < 4; i++) { + dest[i] = base_addr[buf_index[i]]; + } + return _mm256_load_pd(dest); +} + +VEC_INLINE inline uint64_t _cdep_u64(uint64_t tmp, uint64_t mask) { + uint64_t dst = 0; + uint64_t k = 0; + const uint64_t one = 1; + const uint64_t zero = 0; + for (uint64_t m = 0; m < 64; m++) { + if (mask & (one << m)) { + dst |= static_cast((tmp & (one << k)) != zero) << m; + k += 1; + } + } + return dst; +} + +VEC_INLINE inline uint64_t _cext_u64(uint64_t tmp, uint64_t mask) { + uint64_t dst = 0; + uint64_t k = 0; + const uint64_t one = 1; + const uint64_t zero = 0; + for (uint64_t m = 0; m < 64; m++) { + if (mask & (one << m)) { + dst |= static_cast((tmp & (one << m)) != zero) << k; + k += 1; + } + } + return dst; +} + +#define _mm256_add_epi32 _cm256_add_epi32 +#define _mm256_and_si256 _cm256_and_si256 +#define _mm256_andnot_si256 _cm256_andnot_si256 +#define _mm256_cmpeq_epi32 _cm256_cmpeq_epi32 +#define _mm256_cmpgt_epi32 _cm256_cmpgt_epi32 +#define _mm256_permutevar8x32_epi32 _cm256_permutevar8x32_epi32 +#define _mm256_permutevar8x32_ps _cm256_permutevar8x32_ps +#define _mm_maskload_epi32 _cm_maskload_epi32 +#define _mm256_maskload_epi32 _cm256_maskload_epi32 +#define _mm256_mullo_epi32 _cm256_mullo_epi32 +#define _mm256_srlv_epi32 _cm256_srlv_epi32 +#define _mm256_mask_i32gather_epi32 _cm256_mask_i32gather_epi32 +#define _mm256_mask_i32gather_pd _cm256_mask_i32gather_pd +#define _mm256_mask_i32gather_ps _cm256_mask_i32gather_ps +#define _mm256_i32gather_epi32 _cm256_i32gather_epi32 +#define _mm256_i32gather_pd _cm256_i32gather_pd +#define _mm256_i32gather_ps _cm256_i32gather_ps +#define _pdep_u64 _cdep_u64 +#define _pext_u64 _cext_u64 +#define _mm256_cvtepu8_epi32 _cm256_cvtepu8_epi32 + +#endif + +#ifndef FVEC_FIRST_PASS + +VEC_INLINE inline __m256 _mm256_compress_ps(__m256 mask, __m256 a) { +# ifdef __AVX2__ + uint64_t expanded_mask = _pdep_u64(_mm256_movemask_ps(mask), + 0x0101010101010101); + // unpack each bit to a byte + expanded_mask *= 0xFF; // mask |= mask<<1 | mask<<2 | ... | mask<<7; + // the identity shuffle for vpermps, packed to one index per byte + const uint64_t identity_indices = 0x0706050403020100; + uint64_t wanted_indices = _pext_u64(identity_indices, expanded_mask); + + __m128i bytevec = _mm_cvtsi64_si128(wanted_indices); + __m256i shufmask = _mm256_cvtepu8_epi32(bytevec); + + return _mm256_permutevar8x32_ps(a, shufmask); +# else + int mask_buf[8] __attribute__((aligned(32))); + float a_buf[8] __attribute__((aligned(32))); + float dst_buf[8] __attribute__((aligned(32))); + _mm256_store_si256((__m256i*) mask_buf, _mm256_castps_si256(mask)); + _mm256_store_ps(a_buf, a); + int k = 0; + for (int i = 0; i < 8; i++) { + if (mask[i]) { + dst_buf[k++] = a_buf[i]; + } + } + return _mm256_load_ps(dst_buf); +# endif +} +VEC_INLINE inline __m256 _mm256_expand_ps(__m256 mask, __m256 a) { +# ifdef __AVX2__ + uint64_t expanded_mask = _pdep_u64(_mm256_movemask_ps(mask), + 0x0101010101010101); + expanded_mask *= 0xFF; + const uint64_t identity_indices = 0x0706050403020100; + uint64_t wanted_indices = _pdep_u64(identity_indices, expanded_mask); + __m128i bytevec = _mm_cvtsi64_si128(wanted_indices); + __m256i shufmask = _mm256_cvtepu8_epi32(bytevec); + return _mm256_permutevar8x32_ps(a, shufmask); +# else + int mask_buf[8] __attribute__((aligned(32))); + float a_buf[8] __attribute__((aligned(32))); + float dst_buf[8] __attribute__((aligned(32))) = {0}; + _mm256_store_si256((__m256i*) mask_buf, _mm256_castps_si256(mask)); + _mm256_store_ps(a_buf, a); + int k = 0; + for (int i = 0; i < 8; i++) { + if (mask[i]) { + dst_buf[i] = a_buf[k++]; + } + } + return _mm256_load_ps(dst_buf); +# endif +} + +VEC_INLINE inline __m256d _mm256_compress_pd(__m256d mask, __m256d a) { + return _mm256_castps_pd(_mm256_compress_ps(_mm256_castpd_ps(mask), + _mm256_castpd_ps(a))); +} +VEC_INLINE inline __m256d _mm256_expand_pd(__m256d mask, __m256d a) { + return _mm256_castps_pd(_mm256_expand_ps(_mm256_castpd_ps(mask), + _mm256_castpd_ps(a))); +} +#endif + + +class FVEC_NAME; +class IVEC_NAME; +class AVEC_NAME; +class BVEC_NAME { + friend class FVEC_NAME; + friend class IVEC_NAME; + friend class AVEC_NAME; +# if FVEC_LEN==8 + friend class avec8pd; +# endif + FVEC_MASK_T val_; + VEC_INLINE BVEC_NAME(const FVEC_MASK_T &v) : val_(v) {} + VEC_INLINE BVEC_NAME(const __m256i &v) : val_(FVEC_SUFFIX(_mm256_castsi256_) + (v)) {} +public: + VEC_INLINE BVEC_NAME() {} + VEC_INLINE static BVEC_NAME kand(const BVEC_NAME &a, const BVEC_NAME &b) { + return FVEC_SUFFIX(_mm256_and_)(a.val_, b.val_); + } + VEC_INLINE static BVEC_NAME kandn(const BVEC_NAME &a, const BVEC_NAME &b) { + return FVEC_SUFFIX(_mm256_andnot_)(a.val_, b.val_); + } + VEC_INLINE static BVEC_NAME masku_compress(const BVEC_NAME &mask, + const BVEC_NAME &a) { + return FVEC_SUFFIX(_mm256_compress_)(mask.val_, a.val_); + } + VEC_INLINE static BVEC_NAME mask_expand(const BVEC_NAME &src, + const BVEC_NAME &mask, + const BVEC_NAME &a) { + FVEC_MASK_T ret = FVEC_SUFFIX(_mm256_expand_)(mask.val_, a.val_); + ret = FVEC_SUFFIX(_mm256_and_)(mask.val_, ret); + ret = FVEC_SUFFIX(_mm256_or_)(ret, FVEC_SUFFIX(_mm256_andnot_) + (mask.val_, src.val_)); + return ret; + } + VEC_INLINE static BVEC_NAME full() { + __m256i a = _mm256_undefined_si256(); + return FVEC_SUFFIX(_mm256_castsi256_)(_mm256_cmpeq_epi32(a, a)); + } + VEC_INLINE static BVEC_NAME empty() { + return FVEC_SUFFIX(_mm256_setzero_)(); + } + VEC_INLINE static BVEC_NAME only(int n) { + static const unsigned int FULL_ps = (unsigned int) -1; + static const unsigned int LUT_ps[9][8] = { + {0, 0, 0, 0, 0, 0, 0, 0}, + {FULL_ps, 0, 0, 0, 0, 0, 0, 0}, + {FULL_ps, FULL_ps, 0, 0, 0, 0, 0, 0}, + {FULL_ps, FULL_ps, FULL_ps, 0, 0, 0, 0, 0}, + {FULL_ps, FULL_ps, FULL_ps, FULL_ps, 0, 0, 0, 0}, + {FULL_ps, FULL_ps, FULL_ps, FULL_ps, FULL_ps, 0, 0, 0}, + {FULL_ps, FULL_ps, FULL_ps, FULL_ps, FULL_ps, FULL_ps, 0, 0}, + {FULL_ps, FULL_ps, FULL_ps, FULL_ps, FULL_ps, FULL_ps, FULL_ps, 0}, + {FULL_ps, FULL_ps, FULL_ps, FULL_ps, FULL_ps, FULL_ps, FULL_ps, FULL_ps}, + }; + static const unsigned long long FULL_pd = (unsigned long long) -1; + static const unsigned long long LUT_pd[5][4] = { + {0, 0, 0, 0}, + {FULL_pd, 0, 0, 0}, + {FULL_pd, FULL_pd, 0, 0}, + {FULL_pd, FULL_pd, FULL_pd, 0}, + {FULL_pd, FULL_pd, FULL_pd, FULL_pd}, + }; + return FVEC_SUFFIX(_mm256_load_)((const FVEC_SCAL_T*) FVEC_SUFFIX(LUT_)[n]); + } + VEC_INLINE static BVEC_NAME after(int n) { + static const unsigned int FULL_ps = (unsigned int) -1; + static const unsigned int LUT_ps[9][8] = { + {FULL_ps, FULL_ps, FULL_ps, FULL_ps, FULL_ps, FULL_ps, FULL_ps, FULL_ps}, + {0, FULL_ps, FULL_ps, FULL_ps, FULL_ps, FULL_ps, FULL_ps, FULL_ps}, + {0, 0, FULL_ps, FULL_ps, FULL_ps, FULL_ps, FULL_ps, FULL_ps}, + {0, 0, 0, FULL_ps, FULL_ps, FULL_ps, FULL_ps, FULL_ps}, + {0, 0, 0, 0, FULL_ps, FULL_ps, FULL_ps, FULL_ps}, + {0, 0, 0, 0, 0, FULL_ps, FULL_ps, FULL_ps}, + {0, 0, 0, 0, 0, 0, FULL_ps, FULL_ps}, + {0, 0, 0, 0, 0, 0, 0, FULL_ps}, + {0, 0, 0, 0, 0, 0, 0, 0}, + }; + static const unsigned long long FULL_pd = (unsigned long long) -1; + static const unsigned long long LUT_pd[5][4] = { + {FULL_pd, FULL_pd, FULL_pd, FULL_pd}, + {0, FULL_pd, FULL_pd, FULL_pd}, + {0, 0, FULL_pd, FULL_pd}, + {0, 0, 0, FULL_pd}, + {0, 0, 0, 0}, + }; + return FVEC_SUFFIX(_mm256_load_)((const FVEC_SCAL_T*) FVEC_SUFFIX(LUT_)[n]); + } + VEC_INLINE static BVEC_NAME onlyafter(int only_, int after_) { + return kand(after(after_), only(after_ + only_)); + } + VEC_INLINE static int popcnt(const BVEC_NAME &a) { + return _popcnt32(FVEC_SUFFIX(_mm256_movemask_)(a.val_)); + } + VEC_INLINE static bool test_all_unset(const BVEC_NAME &a) { + return FVEC_SUFFIX(_mm256_testz_)(a.val_, a.val_); + } + VEC_INLINE static bool test_any_set(const BVEC_NAME &a) { + return ! test_all_unset(a); + } + VEC_INLINE static bool test_at(const BVEC_NAME &a, int i) { + assert(i < FVEC_LEN); + return FVEC_SUFFIX(_mm256_movemask_)(a.val_) & (1 << i); + } + VEC_INLINE BVEC_NAME operator &(const BVEC_NAME &b) const { + return FVEC_SUFFIX(_mm256_and_)(val_, b.val_); + } + VEC_INLINE BVEC_NAME operator |(const BVEC_NAME &b) const { + return FVEC_SUFFIX(_mm256_or_)(val_, b.val_); + } + VEC_INLINE BVEC_NAME operator ~() const { + return FVEC_SUFFIX(_mm256_andnot_)(val_, full().val_); + } +}; + +class IVEC_NAME { + friend class FVEC_NAME; + friend class AVEC_NAME; +# if FVEC_LEN==8 + friend class avec8pd; +# endif + __m256i val_; + VEC_INLINE IVEC_NAME(const __m256i &v) : val_(v) {} + VEC_INLINE static __m256i to(const FVEC_VEC_T &a) { +# if FVEC_LEN==4 + return _mm256_castpd_si256(a); +# else + return _mm256_castps_si256(a); +# endif + } + VEC_INLINE static FVEC_VEC_T from(const __m256i &a) { + return FVEC_SUFFIX(_mm256_castsi256_)(a); + } +public: + static const int VL = 8; + VEC_INLINE IVEC_NAME() {} + + #define IVEC_MASK_BINFN_B(the_name) \ + VEC_INLINE static BVEC_NAME the_name(const IVEC_NAME &a, \ + const IVEC_NAME &b) { \ + return _mm256_##the_name##_epi32(a.val_, b.val_); \ + } \ + VEC_INLINE static BVEC_NAME mask_##the_name( \ + const BVEC_NAME &mask, \ + const IVEC_NAME &a, const IVEC_NAME &b \ + ) { \ + BVEC_NAME ret = _mm256_##the_name##_epi32( \ + a.val_, b.val_); \ + return mask & ret; \ + } + IVEC_MASK_BINFN_B(cmpeq) + IVEC_MASK_BINFN_B(cmpgt) + + VEC_INLINE static __m256i _mm256_cmplt_epi32(__m256i a, __m256i b) { + __m256i le = _mm256_cmpgt_epi32(b, a); + __m256i eq = _mm256_cmpeq_epi32(a, b); + return _mm256_andnot_si256(eq, le); + } + + VEC_INLINE static __m256i _mm256_cmpneq_epi32(__m256i a, __m256i b) { + __m256i eq = _mm256_cmpeq_epi32(a, b); + __m256i t = _mm256_undefined_si256(); + __m256i f = _mm256_cmpeq_epi32(t, t); + return _mm256_andnot_si256(eq, f); + } + + IVEC_MASK_BINFN_B(cmplt) + IVEC_MASK_BINFN_B(cmpneq) + #undef IVEC_MASK_BINFN_B + + VEC_INLINE static IVEC_NAME mask_blend( + const BVEC_NAME &mask, const IVEC_NAME &a, const IVEC_NAME &b + ) { + return to(FVEC_SUFFIX(_mm256_blendv_)(from(a.val_), from(b.val_), + mask.val_)); + } + #define IVEC_MASK_BINFN_I(the_name) \ + VEC_INLINE static IVEC_NAME mask_##the_name( \ + const IVEC_NAME &src, const BVEC_NAME &mask, \ + const IVEC_NAME &a, const IVEC_NAME &b \ + ) { \ + IVEC_NAME ret = _mm256_##the_name##_epi32( \ + a.val_, b.val_); \ + return mask_blend(mask, src, ret); \ + } + IVEC_MASK_BINFN_I(add) + #undef IVEC_MASK_BINFN_I + + #define IVEC_BINFN_I(the_name) \ + VEC_INLINE static IVEC_NAME the_name(const IVEC_NAME &a, \ + const IVEC_NAME &b) { \ + return _mm256_##the_name##_epi32(a.val_, b.val_); \ + } + IVEC_BINFN_I(mullo) + IVEC_BINFN_I(srlv) + #undef IVEC_BINFN_I + VEC_INLINE static IVEC_NAME the_and(const IVEC_NAME &a, const IVEC_NAME &b) { + return _mm256_and_si256(a.val_, b.val_); + } + + VEC_INLINE static IVEC_NAME masku_compress(const BVEC_NAME &mask, + const IVEC_NAME &b) { + return to(FVEC_SUFFIX(_mm256_compress_)(mask.val_, from(b.val_))); + } + VEC_INLINE static IVEC_NAME mask_expand( + const IVEC_NAME &src, const BVEC_NAME &mask, const IVEC_NAME &b + ) { + FVEC_VEC_T ret = FVEC_SUFFIX(_mm256_expand_)(mask.val_, from(b.val_)); + ret = FVEC_SUFFIX(_mm256_and_)(mask.val_, ret); + ret = FVEC_SUFFIX(_mm256_or_)(ret, FVEC_SUFFIX(_mm256_andnot_) + (mask.val_, from(src.val_))); + return to(ret); + } + + VEC_INLINE static void store(int * dest, const IVEC_NAME &src) { + _mm256_store_si256((__m256i*)dest, src.val_); +# if FVEC_LEN==4 + dest[1] = dest[2]; + dest[2] = dest[4]; + dest[3] = dest[6]; +# endif + } + + VEC_INLINE static int at(const IVEC_NAME &a, int b) { + int data[8] __attribute__((aligned(32))); + store(data, a); + return data[b]; + } + + VEC_INLINE static void print(const char * str, const IVEC_NAME &a) { + int data[8] __attribute__((aligned(32))); + store(data, a); + printf("%s:", str); + for (int i = 0; i < FVEC_LEN; i++) { + printf(" %d", data[i]); + } + printf("\n"); + } + + VEC_INLINE static IVEC_NAME maskz_loadu(const BVEC_NAME &mask, + const int * src) { + FVEC_VEC_T mask_val = mask.val_; +# if FVEC_LEN==4 +# ifdef __AVX2__ + static const unsigned int mask_shuffle[8] __attribute__((aligned(32))) = + {0, 2, 4, 6, 0, 0, 0, 0}; + __m256 m = _mm256_castpd_ps(mask_val); + m = _mm256_permutevar8x32_ps(m, _mm256_load_si256((__m256i*)mask_shuffle)); + __m128i ret = _mm_maskload_epi32(src, + _mm256_castsi256_si128(_mm256_castps_si256(m))); + static const unsigned int load_shuffle[8] __attribute__((aligned(32))) = + {0, 0, 1, 1, 2, 2, 3, 3}; + return _mm256_permutevar8x32_epi32(_mm256_castsi128_si256(ret), + _mm256_load_si256((__m256i*)load_shuffle)); +# else + int dest[8] __attribute__((aligned(32))) = {0}; + int mask_buf[8] __attribute__((aligned(32))); + _mm256_store_pd((double*) mask_buf, mask.val_); + for (int i = 0; i < 4; i++) { + if (mask_buf[2*i]) { + int val = src[i]; + dest[2*i+0] = val; + dest[2*i+1] = val; + } + } + return _mm256_load_si256((__m256i*) dest); +# endif +# else + return _mm256_maskload_epi32(src, to(mask_val)); +# endif + } + + VEC_INLINE static IVEC_NAME mask_gather( + const IVEC_NAME &src, const BVEC_NAME &mask, const IVEC_NAME &idx, + const int * mem, const int scale + ) { + assert(scale == sizeof(int)); + return _mm256_mask_i32gather_epi32(src.val_, mem, idx.val_, to(mask.val_), + sizeof(int)); + } + + VEC_INLINE static void mask_compressstore(const BVEC_NAME &mask, int * dest, + const IVEC_NAME &src) { + int buf[8] __attribute__((aligned(64))); + const int stride = FVEC_LEN==4 ? 2 : 1; + _mm256_store_si256((__m256i*)buf, src.val_); + int mask_val = FVEC_SUFFIX(_mm256_movemask_)(mask.val_); + int k = 0; + #pragma unroll + for (int i = 0; i < FVEC_LEN; i++) { + if (mask_val & (1 << i)) + dest[k++] = buf[stride*i]; + } + } + + VEC_INLINE static IVEC_NAME set1(int i) { + return _mm256_set1_epi32(i); + } + VEC_INLINE static IVEC_NAME setzero() { + return _mm256_setzero_si256(); + } + VEC_INLINE static IVEC_NAME undefined() { + return _mm256_undefined_si256(); + } + + VEC_INLINE IVEC_NAME operator +(const IVEC_NAME &b) const { + return _mm256_add_epi32(this->val_, b.val_); + } +}; + +class FVEC_NAME { + friend class AVEC_NAME; +#if FVEC_LEN==8 + friend class avec8pd; +#endif + FVEC_VEC_T val_; + VEC_INLINE FVEC_NAME(const FVEC_VEC_T &v) : val_(v) {} +public: + static const int VL = FVEC_LEN; +# if defined(__AVX2__) || defined(__MIC__) || defined(__AVX512F__) + VEC_INLINE static bool fast_compress() { return true; } +# else + VEC_INLINE static bool fast_compress() { return false; } +# endif + VEC_INLINE FVEC_NAME() {} + VEC_INLINE static FVEC_SCAL_T at(const FVEC_NAME &a, int i) { + assert(i < FVEC_LEN); + FVEC_SCAL_T data[FVEC_LEN] __attribute__((aligned(64))); + FVEC_SUFFIX(_mm256_store_)(data, a.val_); + return data[i]; + } + + #define FVEC_MASK_BINFN_B(the_name, the_imm) \ + VEC_INLINE static BVEC_NAME the_name(const FVEC_NAME &a, \ + const FVEC_NAME &b) { \ + return FVEC_SUFFIX(_mm256_cmp_)(a.val_, b.val_, the_imm); \ + } \ + VEC_INLINE static BVEC_NAME mask_##the_name( \ + const BVEC_NAME &mask, \ + const FVEC_NAME &a, const FVEC_NAME &b \ + ) { \ + BVEC_NAME ret = FVEC_SUFFIX(_mm256_cmp_)( \ + a.val_, b.val_, the_imm); \ + return mask & ret; \ + } + FVEC_MASK_BINFN_B(cmple, _CMP_LE_OS) + FVEC_MASK_BINFN_B(cmplt, _CMP_LT_OS) + FVEC_MASK_BINFN_B(cmpneq, _CMP_NEQ_UQ) + FVEC_MASK_BINFN_B(cmpnle, _CMP_NLE_US) + FVEC_MASK_BINFN_B(cmpnlt, _CMP_NLT_US) + #undef FVEC_MASK_BINFN_B + + VEC_INLINE static __m256d _mm256_recip_pd(__m256d a) { + __m256d c_1 = _mm256_set1_pd(1); + return _mm256_div_pd(c_1, a); + } + VEC_INLINE static __m256 _mm256_recip_ps(__m256 a) { + return _mm256_rcp_ps(a); + } + VEC_INLINE static __m256d _mm256_abs_pd(__m256d a) { + const unsigned long long abs_mask = 0x7FFFFFFFFFFFFFFF; + const unsigned long long abs_full[8] = + {abs_mask, abs_mask, abs_mask, abs_mask, abs_mask, abs_mask, abs_mask, + abs_mask}; + return _mm256_and_pd(_mm256_load_pd((double*)abs_full), a); + } + VEC_INLINE static __m256 _mm256_abs_ps(__m256 a) { + const unsigned long long abs_mask = 0x7FFFFFFF; + const unsigned long long abs_full[16] = + {abs_mask, abs_mask, abs_mask, abs_mask, abs_mask, abs_mask, abs_mask, + abs_mask, abs_mask, abs_mask, abs_mask, abs_mask, abs_mask, + abs_mask, abs_mask, abs_mask}; + return _mm256_and_ps(_mm256_load_ps((float*)abs_full), a); + } + + #define FVEC_UNFN_F(the_name) \ + VEC_INLINE static FVEC_NAME the_name(const FVEC_NAME &a) { \ + return FVEC_SUFFIX(_mm256_##the_name##_)(a.val_); \ + } + FVEC_UNFN_F(abs) + FVEC_UNFN_F(exp) + FVEC_UNFN_F(invsqrt) + FVEC_UNFN_F(recip) + FVEC_UNFN_F(sqrt) + #undef FVEC_UNFN_F + + VEC_INLINE static FVEC_NAME mask_blend( + const BVEC_NAME &mask, const FVEC_NAME &a, const FVEC_NAME &b + ) { + return FVEC_SUFFIX(_mm256_blendv_)(a.val_, b.val_, mask.val_); + } + #define FVEC_MASK_UNFN_F(the_name) \ + VEC_INLINE static FVEC_NAME mask_##the_name( \ + const FVEC_NAME &src, const BVEC_NAME &mask, \ + const FVEC_NAME &a \ + ) { \ + FVEC_NAME ret = FVEC_SUFFIX(_mm256_##the_name##_)( \ + a.val_); \ + return mask_blend(mask, src, ret); \ + } + FVEC_MASK_UNFN_F(cos) + FVEC_MASK_UNFN_F(recip) + FVEC_MASK_UNFN_F(sqrt) + #undef FVEC_MASK_UNFN_F + + #define FVEC_BINFN_F(the_name) \ + VEC_INLINE static FVEC_NAME the_name(const FVEC_NAME &a, \ + const FVEC_NAME &b) { \ + return FVEC_SUFFIX(_mm256_##the_name##_)(a.val_, b.val_); \ + } + FVEC_BINFN_F(max) + FVEC_BINFN_F(min) + #undef FVEC_BINFN_F + + #define FVEC_MASK_BINFN_F(the_name) \ + VEC_INLINE static FVEC_NAME mask_##the_name( \ + const FVEC_NAME &src, const BVEC_NAME &mask, \ + const FVEC_NAME &a, const FVEC_NAME &b \ + ) { \ + FVEC_NAME ret = FVEC_SUFFIX(_mm256_##the_name##_)( \ + a.val_, b.val_); \ + return mask_blend(mask, src, ret); \ + } + FVEC_MASK_BINFN_F(add) + FVEC_MASK_BINFN_F(div) + FVEC_MASK_BINFN_F(mul) + FVEC_MASK_BINFN_F(sub) + #undef FVEC_MASK_BINFN_F + + VEC_INLINE static FVEC_NAME mask_expand( + const FVEC_NAME &src, const BVEC_NAME &mask, const FVEC_NAME &b + ) { + FVEC_VEC_T ret = FVEC_SUFFIX(_mm256_expand_)(mask.val_, b.val_); + ret = FVEC_SUFFIX(_mm256_and_)(mask.val_, ret); + ret = FVEC_SUFFIX(_mm256_or_)(ret, FVEC_SUFFIX(_mm256_andnot_) + (mask.val_, src.val_)); + return ret; + } + VEC_INLINE static FVEC_NAME masku_compress( + const BVEC_NAME &mask, const FVEC_NAME &b + ) { + return FVEC_SUFFIX(_mm256_compress_)(mask.val_, b.val_); + } + + VEC_INLINE static FVEC_NAME set1(const FVEC_SCAL_T &a) { + return FVEC_SUFFIX(_mm256_set1_)(a); + } + VEC_INLINE static FVEC_NAME setzero() { + return FVEC_SUFFIX(_mm256_setzero_)(); + } + VEC_INLINE static FVEC_NAME undefined() { + return FVEC_SUFFIX(_mm256_undefined_)(); + } + + VEC_INLINE static FVEC_NAME load(const FVEC_SCAL_T *mem) { + return FVEC_SUFFIX(_mm256_load_)(mem); + } + VEC_INLINE static void store(FVEC_SCAL_T * dest, const FVEC_NAME &a) { + FVEC_SUFFIX(_mm256_store_)(dest, a.val_); + } + + + VEC_INLINE static FVEC_NAME gather(const IVEC_NAME &idx, + const FVEC_SCAL_T * mem, const int scale) { + assert(scale == sizeof(FVEC_SCAL_T)); +# if FVEC_LEN==4 +# ifdef __AVX2__ + static const unsigned int mask_shuffle[8] __attribute__((aligned(32))) = + {0, 2, 4, 6, 0, 0, 0, 0}; + __m256i m = _mm256_permutevar8x32_epi32(idx.val_, + _mm256_load_si256((__m256i*)mask_shuffle)); + __m128i idx_short = _mm256_castsi256_si128(m); + return FVEC_SUFFIX(_mm256_i32gather_)(mem, idx_short, sizeof(FVEC_SCAL_T)); +# else + int idx_buf[8] __attribute__((aligned(32))); + _mm256_store_si256((__m256i*) idx_buf, idx.val_); + double dest[4] __attribute__((aligned(32))); + for (int i = 0; i < 4; i++) { + dest[i] = mem[idx_buf[2*i]]; + } + return _mm256_load_pd(dest); +# endif +# else + return FVEC_SUFFIX(_mm256_i32gather_)(mem, idx.val_, sizeof(FVEC_SCAL_T)); +# endif + } + VEC_INLINE static FVEC_NAME mask_gather( + const FVEC_NAME &src, const BVEC_NAME &mask, const IVEC_NAME &idx, + const FVEC_SCAL_T * mem, const int scale + ) { + assert(scale == sizeof(FVEC_SCAL_T)); +# if FVEC_LEN==4 +# ifdef __AVX2__ + static const unsigned int mask_shuffle[8] __attribute__((aligned(32))) = + {0, 2, 4, 6, 0, 0, 0, 0}; + __m256i m = _mm256_permutevar8x32_epi32(idx.val_, + _mm256_load_si256((__m256i*)mask_shuffle)); + __m128i idx_short = _mm256_castsi256_si128(m); + return FVEC_SUFFIX(_mm256_mask_i32gather_)(src.val_, mem, idx_short, + mask.val_, sizeof(FVEC_SCAL_T)); +# else + int idx_buf[8] __attribute__((aligned(32))); + int mask_buf[8] __attribute__((aligned(32))); + _mm256_store_si256((__m256i*) idx_buf, idx.val_); + _mm256_store_pd((double*) mask_buf, mask.val_); + double dest[4] __attribute__((aligned(32))); + _mm256_store_pd((double*) dest, src.val_); + for (int i = 0; i < 4; i++) { + if (mask_buf[2*i]) + dest[i] = mem[idx_buf[2*i]]; + } + return _mm256_load_pd(dest); +# endif +# else + return FVEC_SUFFIX(_mm256_mask_i32gather_)(src.val_, mem, idx.val_, + mask.val_, sizeof(FVEC_SCAL_T)); +# endif + } + + VEC_INLINE static void gather_4_adjacent(const IVEC_NAME &idx, + const FVEC_SCAL_T * mem, const int scale, FVEC_NAME * out_0, + FVEC_NAME * out_1, FVEC_NAME * out_2, FVEC_NAME * out_3) { + assert(scale == sizeof(FVEC_SCAL_T)); + int idx_buf[8] __attribute__((aligned(32))); + _mm256_store_si256((__m256i*) idx_buf, idx.val_); +# if FVEC_LEN==4 + __m256d a0 = _mm256_load_pd(&mem[idx_buf[0]]); + __m256d a1 = _mm256_load_pd(&mem[idx_buf[2]]); + __m256d a2 = _mm256_load_pd(&mem[idx_buf[4]]); + __m256d a3 = _mm256_load_pd(&mem[idx_buf[6]]); + __m256d b0 = _mm256_unpacklo_pd(a0, a1); + __m256d b1 = _mm256_unpackhi_pd(a0, a1); + __m256d b2 = _mm256_unpacklo_pd(a2, a3); + __m256d b3 = _mm256_unpackhi_pd(a2, a3); + *out_0 = _mm256_permute2f128_pd(b0, b2, 0x20); + *out_1 = _mm256_permute2f128_pd(b1, b3, 0x20); + *out_2 = _mm256_permute2f128_pd(b0, b2, 0x31); + *out_3 = _mm256_permute2f128_pd(b1, b3, 0x31); +# else + const float *e0 = &mem[idx_buf[0]]; + const float *e1 = &mem[idx_buf[1]]; + const float *e2 = &mem[idx_buf[2]]; + const float *e3 = &mem[idx_buf[3]]; + const float *e4 = &mem[idx_buf[4]]; + const float *e5 = &mem[idx_buf[5]]; + const float *e6 = &mem[idx_buf[6]]; + const float *e7 = &mem[idx_buf[7]]; + __m256 a0 = _mm256_loadu2_m128(e4, e0); + __m256 a1 = _mm256_loadu2_m128(e5, e1); + __m256 b0 = _mm256_unpacklo_ps(a0, a1); + __m256 b1 = _mm256_unpackhi_ps(a0, a1); + __m256 a2 = _mm256_loadu2_m128(e6, e2); + __m256 a3 = _mm256_loadu2_m128(e7, e3); + __m256 b2 = _mm256_unpacklo_ps(a2, a3); + __m256 b3 = _mm256_unpackhi_ps(a2, a3); + *out_0 = _mm256_shuffle_ps(b0, b2, 0x44); + *out_1 = _mm256_shuffle_ps(b0, b2, 0xEE); + *out_2 = _mm256_shuffle_ps(b1, b3, 0x44); + *out_3 = _mm256_shuffle_ps(b1, b3, 0xEE); +# endif + } + VEC_INLINE static void gather_3_adjacent(const IVEC_NAME &idx, + const FVEC_SCAL_T * mem, + const int scale, + FVEC_NAME * out_0, + FVEC_NAME * out_1, + FVEC_NAME * out_2) { + assert(scale == sizeof(FVEC_SCAL_T)); + FVEC_NAME tmp_3; + gather_4_adjacent(idx, mem, scale, out_0, out_1, out_2, &tmp_3); + } + + VEC_INLINE static double _mm256_reduce_add_pd(__m256d a) { + __m256d t1 = _mm256_hadd_pd(a, a); + __m128d t2 = _mm256_extractf128_pd(t1, 1); + __m128d t3 = _mm256_castpd256_pd128(t1); + return _mm_cvtsd_f64(_mm_add_pd(t2, t3)); + } + + VEC_INLINE static float _mm256_reduce_add_ps(__m256 a) { + __m256 t1 = _mm256_hadd_ps(a, a); + __m128 t2 = _mm256_extractf128_ps(t1, 1); + __m128 t3 = _mm256_castps256_ps128(t1); + __m128 t4 = _mm_add_ps(t2, t3); + __m128 t5 = _mm_permute_ps(t4, 0x1B); // 0x1B = reverse + return _mm_cvtss_f32(_mm_add_ps(t4, t5)); + } + + VEC_INLINE static FVEC_SCAL_T reduce_add(const FVEC_NAME &a) { + return FVEC_SUFFIX(_mm256_reduce_add_)(a.val_); + } + VEC_INLINE static FVEC_SCAL_T mask_reduce_add(const BVEC_NAME &mask, + const FVEC_NAME &a) { + return reduce_add(FVEC_SUFFIX(_mm256_and_)(mask.val_, a.val_)); + } + + VEC_INLINE static IVEC_NAME unpackloepi32(const FVEC_NAME &a) { +# if FVEC_LEN==4 +# if __AVX2__ + static const unsigned int mask_shuffle[8] __attribute__((aligned(32))) = + {0, 0, 2, 2, 4, 4, 6, 6}; + __m256 m = _mm256_permutevar8x32_ps(_mm256_castpd_ps(a.val_), + _mm256_load_si256((__m256i*)mask_shuffle)); + return _mm256_castps_si256(m); +# else + __m128i a_lo = _mm256_castsi256_si128(_mm256_castpd_si256(a.val_)); + __m128i a_hi = _mm256_extractf128_si256(_mm256_castpd_si256(a.val_), 1); + __m128i c_lo = _mm_shuffle_epi32(a_lo, 0xA0); /*1010 0000*/ + __m128i c_hi = _mm_shuffle_epi32(a_hi, 0xA0); + __m256i ret = _mm256_setr_m128i(c_lo, c_hi); + return ret; +# endif +# else + return _mm256_castps_si256(a.val_); +# endif + } + + VEC_INLINE static FVEC_NAME mask_sincos( + FVEC_NAME * cos, const FVEC_NAME &src_a, const FVEC_NAME &src_b, + const BVEC_NAME &mask, const FVEC_NAME &arg + ) { + FVEC_VEC_T c, s = FVEC_SUFFIX(_mm256_sincos_)(&c, arg.val_); + *cos = mask_blend(mask, src_b, c); + return mask_blend(mask, src_a, s); + } + + #define FVEC_BINOP(the_sym, the_name) \ + VEC_INLINE inline FVEC_NAME operator the_sym(const FVEC_NAME &b) const { \ + return FVEC_SUFFIX(_mm256_##the_name##_)(this->val_, b.val_); \ + } + FVEC_BINOP(+, add) + FVEC_BINOP(-, sub) + FVEC_BINOP(*, mul) + FVEC_BINOP(/, div) + #undef FVEC_BINOP + + VEC_INLINE static void gather_prefetch0(const IVEC_NAME &a, void * mem) { + /* NOP */ + } +}; + +class AVEC_NAME { + friend class avec8pd; + FVEC_VEC_T val_; + VEC_INLINE AVEC_NAME(const FVEC_VEC_T &a) : val_(a) {} +public: + VEC_INLINE AVEC_NAME(const FVEC_NAME &a) : val_(a.val_) {} + VEC_INLINE static AVEC_NAME undefined() { + return FVEC_SUFFIX(_mm256_undefined_)(); + } + VEC_INLINE static AVEC_NAME mask_gather( + const AVEC_NAME &src, const BVEC_NAME &mask, const IVEC_NAME &idx, + const FVEC_SCAL_T * mem, const int scale + ) { + assert(scale == sizeof(FVEC_SCAL_T)); + return FVEC_NAME::mask_gather(src.val_, mask, idx, mem, scale); + } + VEC_INLINE static void mask_i32loscatter( + FVEC_SCAL_T * mem, const BVEC_NAME &mask, const IVEC_NAME &idx, + const AVEC_NAME &a, const int scale + ) { + assert(scale == sizeof(FVEC_SCAL_T)); + for (int l = 0; l < FVEC_NAME::VL; l++) { + if (BVEC_NAME::test_at(mask, l)) + mem[IVEC_NAME::at(idx, l)] = FVEC_NAME::at(a.val_, l); + } + } + + #define AVEC_BINOP(the_sym, the_name) \ + VEC_INLINE inline AVEC_NAME operator the_sym(const AVEC_NAME &b) const { \ + return FVEC_SUFFIX(_mm256_##the_name##_)(this->val_, b.val_); \ + } + AVEC_BINOP(-, sub) + #undef AVEC_BINOP +}; + +#if FVEC_LEN==8 +class avec8pd { + __m256d lo_, hi_; + VEC_INLINE avec8pd(const __m256d &lo, const __m256d &hi) : lo_(lo), hi_(hi) {} + VEC_INLINE static __m128 get_ps_hi(__m256 a) { + return _mm256_extractf128_ps(a, 1); + } + VEC_INLINE static __m128 get_ps_lo(__m256 a) { + return _mm256_castps256_ps128(a); + } + VEC_INLINE static __m128i get_si_hi(__m256i a) { + return _mm_castps_si128(get_ps_hi(_mm256_castsi256_ps(a))); + } + VEC_INLINE static __m128i get_si_lo(__m256i a) { + return _mm_castps_si128(get_ps_lo(_mm256_castsi256_ps(a))); + } +public: + VEC_INLINE avec8pd(const FVEC_NAME &a) { + lo_ = _mm256_cvtps_pd(get_ps_lo(a.val_)); + hi_ = _mm256_cvtps_pd(get_ps_hi(a.val_)); + } + VEC_INLINE static avec8pd undefined() { + return avec8pd(_mm256_undefined_pd(), _mm256_undefined_pd()); + } + VEC_INLINE static avec8pd mask_gather( + const avec8pd &src, const BVEC_NAME &mask, const IVEC_NAME &idx, + const double * mem, const int scale + ) { +# ifndef __AVX2__ + assert(scale == sizeof(double)); + int idx_buf[8] __attribute__((aligned(32))); + _mm256_store_si256((__m256i*) idx_buf, idx.val_); + int mask_val = _mm256_movemask_ps(mask.val_); + double ret_buf[8] __attribute__((aligned(32))); + _mm256_store_pd(&ret_buf[0], src.lo_); + _mm256_store_pd(&ret_buf[4], src.hi_); + for (int i = 0; i < 8; i++) { + if (mask_val & (1 << i)) { + ret_buf[i] = mem[idx_buf[i]]; + } + } + __m256d lo = _mm256_load_pd(&ret_buf[0]); + __m256d hi = _mm256_load_pd(&ret_buf[4]); +# else + static const unsigned int lo_shuffle[8] __attribute__((aligned(32))) = + {0, 0, 1, 1, 2, 2, 3, 3}; + static const unsigned int hi_shuffle[8] __attribute__((aligned(32))) = + {4, 4, 5, 5, 6, 6, 7, 7}; + __m256d lo_mask = _mm256_castps_pd(_mm256_permutevar8x32_ps(mask.val_, + _mm256_load_si256((__m256i*) lo_shuffle))); + __m256d hi_mask = _mm256_castps_pd(_mm256_permutevar8x32_ps(mask.val_, + _mm256_load_si256((__m256i*) hi_shuffle))); + __m256d lo = _mm256_mask_i32gather_pd(src.lo_, mem, get_si_lo(idx.val_), + lo_mask, sizeof(double)); + __m256d hi = _mm256_mask_i32gather_pd(src.hi_, mem, get_si_hi(idx.val_), + hi_mask, sizeof(double)); +# endif + return avec8pd(lo, hi); + } + VEC_INLINE static void mask_i32loscatter( + double * mem, const BVEC_NAME &mask, const IVEC_NAME &idx, + const avec8pd &a, const int scale + ) { + assert(scale == sizeof(double)); + double a_buf[8] __attribute__((aligned(32))); + _mm256_store_pd(a_buf, a.lo_); + _mm256_store_pd(&a_buf[4], a.hi_); + int idx_buf[8] __attribute__((aligned(32))); + _mm256_store_si256((__m256i*)idx_buf, idx.val_); + int mask_val = _mm256_movemask_ps(mask.val_); + for (int i = 0; i < 8; i++) { + if (mask_val & (1 << i)) + mem[idx_buf[i]] = a_buf[i]; + } + } + + #define AVEC2_BINOP(the_sym, the_name) \ + VEC_INLINE inline avec8pd operator the_sym(const avec8pd &b) const { \ + __m256d lo = _mm256_##the_name##_pd(this->lo_, b.lo_); \ + __m256d hi = _mm256_##the_name##_pd(this->hi_, b.hi_); \ + return avec8pd(lo, hi); \ + } + AVEC2_BINOP(-, sub) +}; +#endif + +} + + +#ifdef FVEC_FIRST_PASS + +template +struct intr_types; + +template<> +struct intr_types { + typedef mm256::fvec4pd fvec; + typedef mm256::ivec4 ivec; + typedef mm256::bvec4 bvec; + typedef mm256::avec4pd avec; +}; + +template<> +struct intr_types { + typedef mm256::fvec8ps fvec; + typedef mm256::ivec8 ivec; + typedef mm256::bvec8 bvec; + typedef mm256::avec8ps avec; +}; + +template<> +struct intr_types { + typedef mm256::fvec8ps fvec; + typedef mm256::ivec8 ivec; + typedef mm256::bvec8 bvec; + typedef mm256::avec8pd avec; +}; + +#endif + +#ifndef FVEC_FIRST_PASS +# define FVEC_FIRST_PASS +# include "intel_intrinsics_airebo.h" +#endif + +#endif + +#ifdef LMP_INTEL_AIREBO_SCALAR + +#include +#include +#include + +#define VEC_INLINE __attribute__((always_inline)) + +template +struct intr_types { + +class fvec; +class ivec; +class avec; +class bvec { + friend class fvec; + friend class ivec; + friend class avec; + bool val_; + VEC_INLINE bvec(const bool &v) : val_(v) {} +public: + VEC_INLINE bvec() {} + VEC_INLINE static bvec kand(const bvec &a, const bvec &b) { + return a.val_ && b.val_; + } + VEC_INLINE static bvec kandn(const bvec &a, const bvec &b) { + return (! a.val_) && b.val_; + } + VEC_INLINE static bvec knot(const bvec &a) { + return ! a.val_; + } + VEC_INLINE static int kortestz(const bvec &a, const bvec &b) { + return (! a.val_) && (! b.val_) ? true : false; + } + VEC_INLINE static bvec masku_compress(const bvec &mask, const bvec &a) { + return mask.val_ ? a.val_ : false; + } + VEC_INLINE static bvec mask_expand(const bvec &src, const bvec &mask, + const bvec &a) { + return mask.val_ ? a.val_ : src.val_; + } + VEC_INLINE static bvec full() { + return true; + } + VEC_INLINE static bvec empty() { + return false; + } + VEC_INLINE static bvec only(int n) { + return n == 1 ? true : false; + } + VEC_INLINE static bvec after(int n) { + return n == 0 ? true : false; + } + VEC_INLINE static bvec onlyafter(int only, int after) { + return after == 0 && only == 1 ? true : false; + } + VEC_INLINE static int popcnt(const bvec &a) { + return static_cast(a.val_); + } + VEC_INLINE static bool test_all_unset(const bvec &a) { + return kortestz(a, a); + } + VEC_INLINE static bool test_any_set(const bvec &a) { + return ! test_all_unset(a); + } + VEC_INLINE static bool test_at(const bvec &a, int i) { + assert(i < 1); + return a.val_; + } + VEC_INLINE bvec operator &(const bvec &b) const { + return val_ && b.val_; + } + VEC_INLINE bvec operator |(const bvec &b) const { + return val_ || b.val_; + } + VEC_INLINE bvec operator ~() const { + return ! val_; + } +}; + +class ivec { + friend class fvec; + friend class avec; + int val_; + VEC_INLINE ivec(const int &v) : val_(v) {} +public: + static const int VL = 1; + VEC_INLINE ivec() {} + + #define IVEC_MASK_BINFN_B(the_name, the_op) \ + VEC_INLINE static bvec the_name(const ivec &a, const ivec &b) { \ + return a.val_ the_op b.val_; \ + } \ + VEC_INLINE static bvec mask_##the_name( \ + const bvec &mask, \ + const ivec &a, const ivec &b \ + ) { \ + return mask.val_ && (a.val_ the_op b.val_); \ + \ + } + IVEC_MASK_BINFN_B(cmpeq, ==) + IVEC_MASK_BINFN_B(cmplt, <) + IVEC_MASK_BINFN_B(cmpneq, !=) + IVEC_MASK_BINFN_B(cmpgt, >) + + #define IVEC_MASK_BINFN_I(the_name, the_op) \ + VEC_INLINE static ivec mask_##the_name( \ + const ivec &src, const bvec &mask, \ + const ivec &a, const ivec &b \ + ) { \ + return mask.val_ ? a.val_ the_op b.val_ : src.val_; \ + } + IVEC_MASK_BINFN_I(add, +) + VEC_INLINE static ivec mask_blend( + const bvec &mask, const ivec &a, const ivec &b + ) { + return mask.val_ ? b.val_ : a.val_; + } + + #define IVEC_BINFN_I(the_name, the_op) \ + VEC_INLINE static ivec the_name(const ivec &a, const ivec &b) { \ + return a.val_ the_op b.val_; \ + } + IVEC_BINFN_I(mullo, *) + IVEC_BINFN_I(srlv, >>) + VEC_INLINE static ivec the_and(const ivec &a, const ivec &b) { + return a.val_ & b.val_; + } + + VEC_INLINE static ivec mask_expand( + const ivec &src, const bvec &a, const ivec &b + ) { + return a.val_ ? b.val_ : src.val_; + } + VEC_INLINE static ivec masku_compress( + const bvec &a, const ivec &b + ) { + return a.val_ ? b.val_ : 0; + } + + VEC_INLINE static int at(const ivec &a, int b) { + assert(b == 0); + return a.val_; + } + + VEC_INLINE static ivec load(const int * src) { + return *src; + } + VEC_INLINE static ivec mask_loadu(const bvec &mask, const int * src) { + return mask.val_ ? *src : 0xDEAD; + } + VEC_INLINE static ivec maskz_loadu(const bvec &mask, const int * src) { + return mask.val_ ? *src : 0; + } + VEC_INLINE static void mask_storeu(const bvec &mask, int * dest, + const ivec &src) { + if (mask.val_) *dest = src.val_; + } + VEC_INLINE static void store(int * dest, const ivec &src) { + *dest = src.val_; + } + + VEC_INLINE static ivec mask_gather( + const ivec &src, const bvec &mask, const ivec &idx, const int * mem, + const int scale + ) { + return mask.val_ ? *reinterpret_cast + (reinterpret_cast(mem) + scale * idx.val_) : src.val_; + } + VEC_INLINE static void mask_i32scatter( + int * mem, const bvec &mask, const ivec &idx, const ivec &a, + const int scale + ) { + if (mask.val_) *reinterpret_cast(reinterpret_cast(mem) + + scale * idx.val_) = a.val_; + } + + VEC_INLINE static void mask_compressstore(const bvec &mask, int * dest, + const ivec &src) { + if (mask.val_) *dest = src.val_; + } + + VEC_INLINE static ivec set( + int i15, int i14, int i13, int i12, int i11, int i10, int i9, int i8, + int i7, int i6, int i5, int i4, int i3, int i2, int i1, int i0 + ) { + return i0; + } + VEC_INLINE static ivec set1(int i) { + return i; + } + VEC_INLINE static ivec setzero() { + return 0; + } + VEC_INLINE static ivec undefined() { + return 0xDEAD; + } + + VEC_INLINE ivec operator +(const ivec &b) const { + return val_ + b.val_; + } +}; + +class fvec { + friend class avec; + flt_t val_; + VEC_INLINE fvec(const flt_t &v) : val_(v) {} +public: + static const int VL = 1; + VEC_INLINE fvec() {} + VEC_INLINE static flt_t at(const fvec &a, int i) { + assert(i < 1); + return a.val_; + } + VEC_INLINE static bool fast_compress() { return false; } + + #define FVEC_MASK_BINFN_B(the_name, the_op) \ + VEC_INLINE static bvec the_name(const fvec &a, const fvec &b) { \ + return a.val_ the_op b.val_; \ + } \ + VEC_INLINE static bvec mask_##the_name( \ + const bvec &mask, \ + const fvec &a, const fvec &b \ + ) { \ + return mask.val_ && (a.val_ the_op b.val_); \ + } + FVEC_MASK_BINFN_B(cmple, <=) + FVEC_MASK_BINFN_B(cmplt, <) + FVEC_MASK_BINFN_B(cmpneq, !=) + FVEC_MASK_BINFN_B(cmpnle, >) + FVEC_MASK_BINFN_B(cmpnlt, >=) + + #define FVEC_UNFN_F(the_name, the_fn) \ + VEC_INLINE static fvec the_name(const fvec &a) { \ + return the_fn(a.val_); \ + } + FVEC_UNFN_F(abs, fabs) + FVEC_UNFN_F(exp, ::exp) + FVEC_UNFN_F(invsqrt, 1/std::sqrt) + FVEC_UNFN_F(recip, 1/) + FVEC_UNFN_F(sqrt, std::sqrt) + + #define FVEC_MASK_UNFN_F(the_name, the_fn) \ + VEC_INLINE static fvec mask_##the_name( \ + const fvec &src, const bvec &mask, \ + const fvec &a \ + ) { \ + return mask.val_ ? the_fn(a.val_) : src.val_; \ + } + FVEC_MASK_UNFN_F(cos, std::cos) + FVEC_MASK_UNFN_F(recip, 1/) + FVEC_MASK_UNFN_F(sqrt, std::sqrt) + + #define FVEC_BINFN_F(the_name, the_fn) \ + VEC_INLINE static fvec the_name(const fvec &a, const fvec &b) { \ + return the_fn(a.val_, b.val_); \ + } + FVEC_BINFN_F(max, ::fmax) + FVEC_BINFN_F(min, ::fmin) + + #define FVEC_MASK_BINFN_F(the_name, the_op) \ + VEC_INLINE static fvec mask_##the_name( \ + const fvec &src, const bvec &mask, \ + const fvec &a, const fvec &b \ + ) { \ + return mask.val_ ? a.val_ the_op b.val_ : src.val_; \ + } + FVEC_MASK_BINFN_F(add, +) + FVEC_MASK_BINFN_F(div, /) + FVEC_MASK_BINFN_F(mul, *) + FVEC_MASK_BINFN_F(sub, -) + VEC_INLINE static fvec mask_blend( + const bvec &mask, const fvec &a, const fvec &b + ) { + return mask.val_ ? b.val_ : a.val_; + } + + VEC_INLINE static fvec mask_expand( + const fvec &src, const bvec &a, const fvec &b + ) { + return a.val_ ? b.val_ : src.val_; + } + VEC_INLINE static fvec masku_compress( + const bvec &a, const fvec &b + ) { + return a.val_ ? b.val_ : 0; + } + + VEC_INLINE static fvec set1(const flt_t &a) { + return a; + } + VEC_INLINE static fvec setzero() { + return 0; + } + VEC_INLINE static fvec undefined() { + return 1337.1337; + } + + VEC_INLINE static fvec load(const flt_t *mem) { + return *mem; + } + VEC_INLINE static void mask_storeu(const bvec &mask, flt_t * dest, + const fvec &a) { + if (mask.val_) *dest = a.val_; + } + VEC_INLINE static void store(flt_t * dest, const fvec &a) { + *dest = a.val_; + } + + VEC_INLINE static fvec gather(const ivec &idx, const flt_t * mem, + const int scale) { + return *reinterpret_cast(reinterpret_cast(mem) + + scale * idx.val_); + } + VEC_INLINE static fvec mask_gather( + const fvec &src, const bvec &mask, const ivec &idx, + const flt_t * mem, const int scale + ) { + return mask.val_ ? *reinterpret_cast + (reinterpret_cast(mem) + scale * idx.val_) : src.val_; + } + + VEC_INLINE static void gather_3_adjacent(const ivec &idx, const flt_t * mem, + const int scale, fvec * out_0, + fvec * out_1, fvec * out_2) { + assert(scale == sizeof(flt_t)); + *out_0 = gather(idx, mem + 0, scale); + *out_1 = gather(idx, mem + 1, scale); + *out_2 = gather(idx, mem + 2, scale); + } + VEC_INLINE static void gather_4_adjacent(const ivec &idx, const flt_t * mem, + const int scale, fvec * out_0, + fvec * out_1, fvec * out_2, + fvec * out_3) { + assert(scale == sizeof(flt_t)); + *out_0 = gather(idx, mem + 0, scale); + *out_1 = gather(idx, mem + 1, scale); + *out_2 = gather(idx, mem + 2, scale); + *out_3 = gather(idx, mem + 3, scale); + } + + VEC_INLINE static flt_t mask_reduce_add(const bvec &mask, const fvec &a) { + return mask.val_ ? a.val_ : 0; + } + VEC_INLINE static flt_t reduce_add(const fvec &a) { + return a.val_; + } + + VEC_INLINE static ivec unpackloepi32(const fvec &a) { + return reinterpret_cast(&a.val_)[0]; + } + + VEC_INLINE static fvec mask_sincos( + fvec * cos_out, const fvec &src_a, const fvec &src_b, + const bvec &mask, const fvec &arg + ) { + cos_out->val_ = mask.val_ ? ::cos(arg.val_) : src_b.val_; + return mask.val_ ? ::sin(arg.val_) : src_a.val_; + } + + #define FVEC_BINOP(the_sym, the_name) \ + VEC_INLINE inline fvec operator the_sym(const fvec &b) const { \ + return this->val_ the_sym b.val_; \ + } + FVEC_BINOP(+, add) + FVEC_BINOP(-, sub) + FVEC_BINOP(*, mul) + FVEC_BINOP(/, div) + + VEC_INLINE static void gather_prefetch0(const ivec &idx, const void * mem) {} +}; + +class avec { + acc_t val_; + VEC_INLINE avec(const acc_t &a) : val_(a) {} +public: + VEC_INLINE avec(const fvec &a) : val_(a.val_) {} + VEC_INLINE static avec undefined() { + return 1337.1337; + } + VEC_INLINE static avec mask_gather(const avec &src, const bvec &mask, + const ivec &idx, const acc_t * mem, + const int scale) { + return mask.val_ ? *reinterpret_cast + (reinterpret_cast(mem) + scale * idx.val_) : src.val_; + } + VEC_INLINE static void mask_i32loscatter(acc_t * mem, const bvec &mask, + const ivec &idx, const avec &a, + const int scale) { + if (mask.val_) *reinterpret_cast(reinterpret_cast(mem) + + idx.val_ * scale) = a.val_; + } + + #define AVEC_BINOP(the_sym, the_name) \ + VEC_INLINE inline avec operator the_sym(const avec &b) const { \ + return this->val_ the_sym b.val_; \ + } + AVEC_BINOP(-, sub) +}; + +}; + +#endif diff --git a/src/USER-INTEL/nbin_intel.cpp b/src/USER-INTEL/nbin_intel.cpp index c5574a78c7..3a36ead499 100644 --- a/src/USER-INTEL/nbin_intel.cpp +++ b/src/USER-INTEL/nbin_intel.cpp @@ -211,6 +211,8 @@ void NBinIntel::bin_atoms(IntelBuffers * buffers) { for (i = nall-1; i >= nlocal; i--) { if (mask[i] & bitmask) { ibin = coord2bin(atom->x[i]); + // Only necessary to store when neighboring ghost + atombin[i] = ibin; bins[i] = binhead[ibin]; binhead[ibin] = i; } @@ -222,14 +224,10 @@ void NBinIntel::bin_atoms(IntelBuffers * buffers) { binhead[ibin] = i; } } else { - for (i = nall-1; i >= nlocal; i--) { + for (i = nall-1; i >= 0; i--) { ibin = coord2bin(atom->x[i]); - bins[i] = binhead[ibin]; - binhead[ibin] = i; - } - for (i = nlocal-1; i >= 0; i--) { - ibin = coord2bin(atom->x[i]); - atombin[i]=ibin; + // Only necessary to store for ghost when neighboring ghost + atombin[i] = ibin; bins[i] = binhead[ibin]; binhead[ibin] = i; } diff --git a/src/USER-INTEL/npair_full_bin_ghost_intel.cpp b/src/USER-INTEL/npair_full_bin_ghost_intel.cpp new file mode 100644 index 0000000000..12101712f1 --- /dev/null +++ b/src/USER-INTEL/npair_full_bin_ghost_intel.cpp @@ -0,0 +1,593 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing authors: W. Michael Brown (Intel) +------------------------------------------------------------------------- */ + +#include "npair_full_bin_ghost_intel.h" +#include "neighbor.h" +#include "nstencil.h" +#include "neigh_list.h" +#include "atom.h" +#include "atom_vec.h" +#include "molecule.h" +#include "error.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +NPairFullBinGhostIntel::NPairFullBinGhostIntel(LAMMPS *lmp) : NPairIntel(lmp) {} + +/* ---------------------------------------------------------------------- + binned neighbor list construction for all neighbors + include neighbors of ghost atoms, but no "special neighbors" for ghosts + every neighbor pair appears in list of both atoms i and j +------------------------------------------------------------------------- */ + +void NPairFullBinGhostIntel::build(NeighList *list) +{ + #ifdef _LMP_INTEL_OFFLOAD + if (_fix->offload_noghost()) + error->all(FLERR, + "The 'ghost no' option cannot be used with this USER-INTEL pair style."); + #endif + + if (nstencil > INTEL_MAX_STENCIL_CHECK) + error->all(FLERR, "Too many neighbor bins for USER-INTEL package."); + + #ifdef _LMP_INTEL_OFFLOAD + if (exclude) + error->all(FLERR, "Exclusion lists not yet supported for Intel offload"); + #endif + + if (_fix->precision() == FixIntel::PREC_MODE_MIXED) + fbi(list, _fix->get_mixed_buffers()); + else if (_fix->precision() == FixIntel::PREC_MODE_DOUBLE) + fbi(list, _fix->get_double_buffers()); + else + fbi(list, _fix->get_single_buffers()); + + _fix->stop_watch(TIME_HOST_NEIGHBOR); +} + +/* ---------------------------------------------------------------------- */ + +template +void NPairFullBinGhostIntel::fbi(NeighList * list, + IntelBuffers * buffers) +{ + const int nlocal = atom->nlocal; + const int nall = atom->nlocal + atom->nghost; + list->inum = atom->nlocal; + list->gnum = atom->nghost; + + int host_start = _fix->host_start_neighbor(); + const int off_end = _fix->offload_end_neighbor(); + + #ifdef _LMP_INTEL_OFFLOAD + if (off_end) grow_stencil(); + if (_fix->full_host_list()) host_start = 0; + int offload_noghost = _fix->offload_noghost(); + #endif + + // only uses offload_end_neighbor to check whether we are doing offloading + // at all, no need to correct this later + buffers->grow_list(list, nall, comm->nthreads, off_end, + _fix->nbor_pack_width()); + + int need_ic = 0; + if (atom->molecular) + dminimum_image_check(need_ic, neighbor->cutneighmax, neighbor->cutneighmax, + neighbor->cutneighmax); + + if (need_ic) { + fbi(1, list, buffers, 0, off_end); + fbi(0, list, buffers, host_start, nlocal); + } else { + fbi(1, list, buffers, 0, off_end); + fbi(0, list, buffers, host_start, nlocal); + } +} + +/* ---------------------------------------------------------------------- */ + +template +void NPairFullBinGhostIntel::fbi(const int offload, NeighList * list, + IntelBuffers * buffers, + const int pstart, const int pend) { + if (pend-pstart == 0) return; + + const int nall = atom->nlocal + atom->nghost; + int pad = 1; + int nall_t = nall; + const int aend = nall; + + const int pack_width = _fix->nbor_pack_width(); + const ATOM_T * _noalias const x = buffers->get_x(); + int * _noalias const firstneigh = buffers->firstneigh(list); + const int e_nall = nall_t; + + const int molecular = atom->molecular; + int *ns = NULL; + tagint *s = NULL; + int tag_size = 0, special_size; + if (buffers->need_tag()) tag_size = e_nall; + if (molecular) { + s = atom->special[0]; + ns = atom->nspecial[0]; + special_size = aend; + } else { + s = &buffers->_special_holder; + ns = &buffers->_nspecial_holder; + special_size = 0; + } + const tagint * _noalias const special = s; + const int * _noalias const nspecial = ns; + const int maxspecial = atom->maxspecial; + const tagint * _noalias const tag = atom->tag; + + int * _noalias const ilist = list->ilist; + int * _noalias numneigh = list->numneigh; + int * _noalias const cnumneigh = buffers->cnumneigh(list); + const int nstencil = this->nstencil; + const int * _noalias const stencil = this->stencil; + const flt_t * _noalias const cutneighsq = buffers->get_cutneighsq()[0]; + const flt_t * _noalias const cutneighghostsq = + buffers->get_cutneighghostsq()[0]; + const int ntypes = atom->ntypes + 1; + const int nlocal = atom->nlocal; + + #ifndef _LMP_INTEL_OFFLOAD + int * const mask = atom->mask; + tagint * const molecule = atom->molecule; + #endif + + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; + int moltemplate; + if (molecular == 2) moltemplate = 1; + else moltemplate = 0; + if (moltemplate) + error->all(FLERR, + "Can't use moltemplate with npair style full/bin/ghost/intel."); + + int tnum; + int *overflow; + double *timer_compute; + #ifdef _LMP_INTEL_OFFLOAD + if (offload) { + timer_compute = _fix->off_watch_neighbor(); + tnum = buffers->get_off_threads(); + overflow = _fix->get_off_overflow_flag(); + _fix->stop_watch(TIME_HOST_NEIGHBOR); + _fix->start_watch(TIME_OFFLOAD_LATENCY); + } else + #endif + { + tnum = comm->nthreads; + overflow = _fix->get_overflow_flag(); + } + const int nthreads = tnum; + const int maxnbors = buffers->get_max_nbors(); + int * _noalias const atombin = buffers->get_atombin(); + const int * _noalias const binpacked = buffers->get_binpacked(); + + const int xperiodic = domain->xperiodic; + const int yperiodic = domain->yperiodic; + const int zperiodic = domain->zperiodic; + const flt_t xprd_half = domain->xprd_half; + const flt_t yprd_half = domain->yprd_half; + const flt_t zprd_half = domain->zprd_half; + + flt_t * _noalias const ncachex = buffers->get_ncachex(); + flt_t * _noalias const ncachey = buffers->get_ncachey(); + flt_t * _noalias const ncachez = buffers->get_ncachez(); + int * _noalias const ncachej = buffers->get_ncachej(); + int * _noalias const ncachejtype = buffers->get_ncachejtype(); + int * _noalias const ncachetag = buffers->get_ncachetag(); + const int ncache_stride = buffers->ncache_stride(); + + const int mbinx = this->mbinx; + const int mbiny = this->mbiny; + const int mbinz = this->mbinz; + const int * const stencilxyz = &this->stencilxyz[0][0]; + + #ifdef _LMP_INTEL_OFFLOAD + const int * _noalias const binhead = this->binhead; + const int * _noalias const bins = this->bins; + const int cop = _fix->coprocessor_number(); + const int separate_buffers = _fix->separate_buffers(); + #pragma offload target(mic:cop) if(offload) \ + in(x:length(e_nall+1) alloc_if(0) free_if(0)) \ + in(tag:length(tag_size) alloc_if(0) free_if(0)) \ + in(special:length(special_size*maxspecial) alloc_if(0) free_if(0)) \ + in(nspecial:length(special_size*3) alloc_if(0) free_if(0)) \ + in(bins,binpacked:length(nall) alloc_if(0) free_if(0)) \ + in(binhead:length(mbins+1) alloc_if(0) free_if(0)) \ + in(cutneighsq:length(0) alloc_if(0) free_if(0)) \ + in(cutneighghostsq:length(0) alloc_if(0) free_if(0)) \ + in(firstneigh:length(0) alloc_if(0) free_if(0)) \ + in(cnumneigh:length(0) alloc_if(0) free_if(0)) \ + in(numneigh:length(0) alloc_if(0) free_if(0)) \ + in(ilist:length(0) alloc_if(0) free_if(0)) \ + in(atombin:length(aend) alloc_if(0) free_if(0)) \ + in(stencil:length(nstencil) alloc_if(0) free_if(0)) \ + in(ncachex,ncachey,ncachez,ncachej:length(0) alloc_if(0) free_if(0)) \ + in(ncachejtype,ncachetag:length(0) alloc_if(0) free_if(0)) \ + in(ncache_stride,maxnbors,nthreads,maxspecial,nstencil,e_nall,offload) \ + in(separate_buffers,aend,nlocal,molecular,ntypes,mbinx,mbiny) \ + in(mbinz,xperiodic,yperiodic,zperiodic,xprd_half,yprd_half,zprd_half) \ + in(stencilxyz:length(3*nstencil)) \ + out(overflow:length(5) alloc_if(0) free_if(0)) \ + out(timer_compute:length(1) alloc_if(0) free_if(0)) \ + signal(tag) + #endif + { + #if defined(__MIC__) && defined(_LMP_INTEL_OFFLOAD) + *timer_compute = MIC_Wtime(); + #endif + + #ifdef _LMP_INTEL_OFFLOAD + overflow[LMP_LOCAL_MIN] = 0; + overflow[LMP_LOCAL_MAX] = aend - 1; + overflow[LMP_GHOST_MIN] = e_nall; + overflow[LMP_GHOST_MAX] = -1; + #endif + + int nstencilp = 0; + int binstart[INTEL_MAX_STENCIL], binend[INTEL_MAX_STENCIL]; + for (int k = 0; k < nstencil; k++) { + binstart[nstencilp] = stencil[k]; + int end = stencil[k] + 1; + for (int kk = k + 1; kk < nstencil; kk++) { + if (stencil[kk-1]+1 == stencil[kk]) { + end++; + k++; + } else break; + } + binend[nstencilp] = end; + nstencilp++; + } + + const int mbinyx = mbiny * mbinx; + + #if defined(_OPENMP) + #pragma omp parallel + #endif + { + const int num = aend; + int tid, ifrom, ito; + + const double balance_factor = 2.0; + const double ibalance_factor = 1.0 / balance_factor; + const int gnum = num - nlocal; + const int wlocal = static_cast(ceil(balance_factor * nlocal)); + const int snum = wlocal + gnum; + IP_PRE_omp_range_id(ifrom, ito, tid, snum, nthreads); + if (ifrom < wlocal) ifrom = static_cast(ibalance_factor * ifrom); + else ifrom -= wlocal - nlocal; + if (ito < wlocal) ito = static_cast(ibalance_factor * ito); + else ito -= wlocal - nlocal; + + int e_ito = ito; + const int list_size = (e_ito + tid * 2 + 2) * maxnbors; + + int which; + + int pack_offset = maxnbors; + int ct = (ifrom + tid * 2) * maxnbors; + int *neighptr = firstneigh + ct; + const int obound = pack_offset + maxnbors * 2; + + const int toffs = tid * ncache_stride; + flt_t * _noalias const tx = ncachex + toffs; + flt_t * _noalias const ty = ncachey + toffs; + flt_t * _noalias const tz = ncachez + toffs; + int * _noalias const tj = ncachej + toffs; + int * _noalias const tjtype = ncachejtype + toffs; + int * _noalias const ttag = ncachetag + toffs; + + // loop over all atoms in other bins in stencil, store every pair + int istart, icount, ncount, oldbin = -9999999, lane, max_chunk; + for (int i = ifrom; i < ito; i++) { + const flt_t xtmp = x[i].x; + const flt_t ytmp = x[i].y; + const flt_t ztmp = x[i].z; + const int itype = x[i].w; + const tagint itag = tag[i]; + const int ioffset = ntypes * itype; + + const int ibin = atombin[i]; + if (ibin != oldbin) { + oldbin = ibin; + ncount = 0; + if (i < nlocal) { + for (int k = 0; k < nstencilp; k++) { + const int bstart = binhead[ibin + binstart[k]]; + const int bend = binhead[ibin + binend[k]]; + #if defined(LMP_SIMD_COMPILER) + #pragma vector aligned + #pragma simd + #endif + for (int jj = bstart; jj < bend; jj++) + tj[ncount++] = binpacked[jj]; + } + } else { + const int zbin = ibin / mbinyx; + const int zrem = ibin % mbinyx; + const int ybin = zrem / mbinx; + const int xbin = zrem % mbinx; + for (int k = 0; k < nstencil; k++) { + const int xbin2 = xbin + stencilxyz[3 * k + 0]; + const int ybin2 = ybin + stencilxyz[3 * k + 1]; + const int zbin2 = zbin + stencilxyz[3 * k + 2]; + if (xbin2 < 0 || xbin2 >= mbinx || + ybin2 < 0 || ybin2 >= mbiny || + zbin2 < 0 || zbin2 >= mbinz) continue; + + const int bstart = binhead[ibin + stencil[k]]; + const int bend = binhead[ibin + stencil[k] + 1]; + #if defined(LMP_SIMD_COMPILER) + #pragma vector aligned + #pragma simd + #endif + for (int jj = bstart; jj < bend; jj++) + tj[ncount++] = binpacked[jj]; + } + } // if i < nlocal + #if defined(LMP_SIMD_COMPILER) + #pragma vector aligned + #pragma simd + #endif + for (int u = 0; u < ncount; u++) { + const int j = tj[u]; + tx[u] = x[j].x; + ty[u] = x[j].y; + tz[u] = x[j].z; + tjtype[u] = x[j].w; + ttag[u] = tag[j]; + } + } // if ibin != oldbin + + // ---------------------- Loop over other bins + + int n = maxnbors; + int n2 = n * 2; + int *neighptr2 = neighptr; + const flt_t * _noalias cutsq; + if (i < nlocal) cutsq = cutneighsq; + else cutsq = cutneighghostsq; + + const int icp = i; + + #if defined(LMP_SIMD_COMPILER) + #pragma vector aligned + #pragma ivdep + #endif + for (int u = 0; u < ncount; u++) { + int addme = 1; + int j = tj[u]; + + if (i == j) addme = 0; + + // Cutoff Check + const flt_t delx = xtmp - tx[u]; + const flt_t dely = ytmp - ty[u]; + const flt_t delz = ztmp - tz[u]; + const int jtype = tjtype[u]; + const int jtag = ttag[u]; + const flt_t rsq = delx * delx + dely * dely + delz * delz; + if (rsq > cutsq[ioffset + jtype]) addme = 0; + + if (need_ic && icp < nlocal) { + int no_special; + ominimum_image_check(no_special, delx, dely, delz); + if (no_special) + j = -j - 1; + } + + int flist = 0; + if (itag > jtag) { + if (((itag+jtag) & 1) == 0) flist = 1; + } else if (itag < jtag) { + if (((itag+jtag) & 1) == 1) flist = 1; + } else { + if (tz[u] < ztmp) flist = 1; + else if (tz[u] == ztmp && ty[u] < ytmp) flist = 1; + else if (tz[u] == ztmp && ty[u] == ytmp && tx[u] < xtmp) + flist = 1; + } + if (addme) { + if (flist) + neighptr2[n2++] = j; + else + neighptr[n++] = j; + } + } // for u + + #ifndef _LMP_INTEL_OFFLOAD + if (exclude) { + int alln = n; + n = maxnbors; + for (int u = pack_offset; u < alln; u++) { + const int j = neighptr[u]; + int pj = j; + if (need_ic) + if (pj < 0) pj = -j - 1; + const int jtype = x[pj].w; + if (exclusion(i,pj,itype,jtype,mask,molecule)) continue; + neighptr[n++] = j; + } + alln = n2; + n2 = maxnbors * 2; + for (int u = n2; u < alln; u++) { + const int j = neighptr[u]; + int pj = j; + if (need_ic) + if (pj < 0) pj = -j - 1; + const int jtype = x[pj].w; + if (exclusion(i,pj,itype,jtype,mask,molecule)) continue; + neighptr[n2++] = j; + } + } + #endif + int ns = n - maxnbors; + int alln = n; + atombin[i] = ns; + n = 0; + for (int u = maxnbors; u < alln; u++) + neighptr[n++] = neighptr[u]; + ns += n2 - maxnbors * 2; + for (int u = maxnbors * 2; u < n2; u++) + neighptr[n++] = neighptr[u]; + if (ns > maxnbors) *overflow = 1; + + ilist[i] = i; + cnumneigh[i] = ct; + numneigh[i] = ns; + + ct += ns; + const int alignb = (INTEL_DATA_ALIGN / sizeof(int)); + const int edge = ct & (alignb - 1); + if (edge) ct += alignb - edge; + neighptr = firstneigh + ct; + if (ct + obound > list_size) { + if (i < ito - 1) { + *overflow = 1; + ct = (ifrom + tid * 2) * maxnbors; + } + } + } + + if (*overflow == 1) + for (int i = ifrom; i < ito; i++) + numneigh[i] = 0; + + #ifdef _LMP_INTEL_OFFLOAD + int ghost_offset = 0, nall_offset = e_nall; + if (separate_buffers) { + for (int i = ifrom; i < ito; ++i) { + int * _noalias jlist = firstneigh + cnumneigh[i]; + const int jnum = numneigh[i]; + #if __INTEL_COMPILER+0 > 1499 + #pragma vector aligned + #pragma simd + #endif + for (int jj = 0; jj < jnum; jj++) { + int j = jlist[jj]; + if (need_ic && j < 0) j = -j - 1; + } + } + + overflow[LMP_LOCAL_MIN] = 0; + overflow[LMP_LOCAL_MAX] = nlocal - 1; + overflow[LMP_GHOST_MIN] = nlocal; + overflow[LMP_GHOST_MAX] = e_nall - 1; + + int nghost = overflow[LMP_GHOST_MAX] + 1 - overflow[LMP_GHOST_MIN]; + if (nghost < 0) nghost = 0; + if (offload) { + ghost_offset = overflow[LMP_GHOST_MIN] - overflow[LMP_LOCAL_MAX] - 1; + nall_offset = overflow[LMP_LOCAL_MAX] + 1 + nghost; + } else { + ghost_offset = overflow[LMP_GHOST_MIN] - nlocal; + nall_offset = nlocal + nghost; + } + } // if separate_buffers + #endif + + if (molecular) { + int ito_m = ito; + if (ito >= nlocal) ito_m = nlocal; + for (int i = ifrom; i < ito_m; ++i) { + int * _noalias jlist = firstneigh + cnumneigh[i]; + const int jnum = numneigh[i]; + + #if defined(LMP_SIMD_COMPILER) + #pragma vector aligned + #pragma simd + #endif + for (int jj = 0; jj < jnum; jj++) { + const int j = jlist[jj]; + if (need_ic && j < 0) { + which = 0; + jlist[jj] = -j - 1; + } else + ofind_special(which, special, nspecial, i, tag[j]); + #ifdef _LMP_INTEL_OFFLOAD + if (j >= nlocal) { + if (j == e_nall) + jlist[jj] = nall_offset; + else if (which) + jlist[jj] = (j-ghost_offset) ^ (which << SBBITS); + else jlist[jj]-=ghost_offset; + } else + #endif + if (which) jlist[jj] = j ^ (which << SBBITS); + } + } // for i + } // if molecular + #ifdef _LMP_INTEL_OFFLOAD + else if (separate_buffers) { + for (int i = ifrom; i < ito; ++i) { + int * _noalias jlist = firstneigh + cnumneigh[i]; + const int jnum = numneigh[i]; + int jj = 0; + #pragma vector aligned + #pragma simd + for (jj = 0; jj < jnum; jj++) { + if (jlist[jj] >= nlocal) { + if (jlist[jj] == e_nall) jlist[jj] = nall_offset; + else jlist[jj] -= ghost_offset; + } + } + } + } + #endif + } // end omp + #if defined(__MIC__) && defined(_LMP_INTEL_OFFLOAD) + *timer_compute = MIC_Wtime() - *timer_compute; + #endif + } // end offload + + #ifdef _LMP_INTEL_OFFLOAD + if (offload) { + _fix->stop_watch(TIME_OFFLOAD_LATENCY); + _fix->start_watch(TIME_HOST_NEIGHBOR); + for (int n = 0; n < aend; n++) { + ilist[n] = n; + numneigh[n] = 0; + } + } else { + for (int i = 0; i < aend; i++) + list->firstneigh[i] = firstneigh + cnumneigh[i]; + if (separate_buffers) { + _fix->start_watch(TIME_PACK); + _fix->set_neighbor_host_sizes(); + buffers->pack_sep_from_single(_fix->host_min_local(), + _fix->host_used_local(), + _fix->host_min_ghost(), + _fix->host_used_ghost()); + _fix->stop_watch(TIME_PACK); + } + } + #else + #pragma vector aligned + #pragma simd + for (int i = 0; i < aend; i++) + list->firstneigh[i] = firstneigh + cnumneigh[i]; + #endif +} diff --git a/src/USER-INTEL/npair_full_bin_ghost_intel.h b/src/USER-INTEL/npair_full_bin_ghost_intel.h new file mode 100644 index 0000000000..4449dfa1e1 --- /dev/null +++ b/src/USER-INTEL/npair_full_bin_ghost_intel.h @@ -0,0 +1,55 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing authors: W. Michael Brown (Intel) +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(full/bin/ghost/intel, + NPairFullBinGhostIntel, + NP_FULL | NP_BIN | NP_GHOST | NP_NEWTON | NP_NEWTOFF | + NP_ORTHO | NP_TRI | NP_INTEL) + +#else + +#ifndef LMP_NPAIR_FULL_BIN_GHOST_INTEL_H +#define LMP_NPAIR_FULL_BIN_GHOST_INTEL_H + +#include "npair_intel.h" + +namespace LAMMPS_NS { + +class NPairFullBinGhostIntel : public NPairIntel { + public: + NPairFullBinGhostIntel(class LAMMPS *); + ~NPairFullBinGhostIntel() {} + void build(class NeighList *); + private: + template + void fbi(NeighList * list, IntelBuffers * buffers); + template + void fbi(const int offload, NeighList * list, + IntelBuffers * buffers, + const int astart, const int aend); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/USER-INTEL/npair_intel.cpp b/src/USER-INTEL/npair_intel.cpp index b20b1dcd08..79dc75366e 100644 --- a/src/USER-INTEL/npair_intel.cpp +++ b/src/USER-INTEL/npair_intel.cpp @@ -143,6 +143,7 @@ void NPairIntel::bin_newton(const int offload, NeighList *list, flt_t * _noalias const ncachez = buffers->get_ncachez(); int * _noalias const ncachej = buffers->get_ncachej(); int * _noalias const ncachejtype = buffers->get_ncachejtype(); + int * _noalias const ncachetag = buffers->get_ncachetag(); const int ncache_stride = buffers->ncache_stride(); #ifdef _LMP_INTEL_OFFLOAD @@ -165,7 +166,7 @@ void NPairIntel::bin_newton(const int offload, NeighList *list, in(atombin:length(aend) alloc_if(0) free_if(0)) \ in(stencil:length(nstencil) alloc_if(0) free_if(0)) \ in(ncachex,ncachey,ncachez,ncachej:length(0) alloc_if(0) free_if(0)) \ - in(ncachejtype:length(0) alloc_if(0) free_if(0)) \ + in(ncachejtype,ncachetag:length(0) alloc_if(0) free_if(0)) \ in(ncache_stride,maxnbors,nthreads,maxspecial,nstencil,e_nall,offload) \ in(pad_width,offload_end,separate_buffers,astart,aend,nlocal,molecular) \ in(ntypes,xperiodic,yperiodic,zperiodic,xprd_half,yprd_half,zprd_half) \ @@ -222,7 +223,7 @@ void NPairIntel::bin_newton(const int offload, NeighList *list, ito += astart; int e_ito = ito; if (THREE && ito == num) { - int imod = ito % pack_width; + int imod = ito & (pack_width - 1); if (imod) e_ito += pack_width - imod; } const int list_size = (e_ito + tid * 2 + 2) * maxnbors; @@ -241,6 +242,7 @@ void NPairIntel::bin_newton(const int offload, NeighList *list, flt_t * _noalias const tz = ncachez + toffs; int * _noalias const tj = ncachej + toffs; int * _noalias const tjtype = ncachejtype + toffs; + int * _noalias const ttag = ncachetag + toffs; flt_t * _noalias itx; flt_t * _noalias ity; @@ -287,13 +289,14 @@ void NPairIntel::bin_newton(const int offload, NeighList *list, ty[u] = x[j].y; tz[u] = x[j].z; tjtype[u] = x[j].w; + if (THREE) ttag[u] = tag[j]; } if (FULL == 0 || TRI == 1) { icount = 0; istart = ncount; const int alignb = INTEL_DATA_ALIGN / sizeof(int); - int nedge = istart % alignb; + int nedge = istart & (alignb - 1); if (nedge) istart + (alignb - nedge); itx = tx + istart; ity = ty + istart; @@ -343,7 +346,7 @@ void NPairIntel::bin_newton(const int offload, NeighList *list, // i bin (half) check and offload ghost check if (j < nlocal) { - const int ijmod = (i + j) % 2; + const int ijmod = (i + j) & 1; if (i > j) { if (ijmod == 0) addme = 0; } else if (i < j) { @@ -424,8 +427,6 @@ void NPairIntel::bin_newton(const int offload, NeighList *list, } #endif - int pj; - if (THREE) pj = j; if (need_ic) { int no_special; ominimum_image_check(no_special, delx, dely, delz); @@ -434,12 +435,12 @@ void NPairIntel::bin_newton(const int offload, NeighList *list, } if (THREE) { - const int jtag = tag[pj]; + const int jtag = ttag[u]; int flist = 0; if (itag > jtag) { - if ((itag+jtag) % 2 == 0) flist = 1; + if (((itag+jtag) & 1) == 0) flist = 1; } else if (itag < jtag) { - if ((itag+jtag) % 2 == 1) flist = 1; + if (((itag+jtag) & 1) == 1) flist = 1; } else { if (tz[u] < ztmp) flist = 1; else if (tz[u] == ztmp && ty[u] < ytmp) flist = 1; @@ -512,7 +513,7 @@ void NPairIntel::bin_newton(const int offload, NeighList *list, cnumneigh[i] += lane; numneigh[i] = ns; } else { - int edge = (n % pad_width); + int edge = n & (pad_width - 1); if (edge) { const int pad_end = n + (pad_width - edge); #if defined(LMP_SIMD_COMPILER) @@ -532,7 +533,7 @@ void NPairIntel::bin_newton(const int offload, NeighList *list, if (lane == pack_width) { ct += max_chunk * pack_width; const int alignb = (INTEL_DATA_ALIGN / sizeof(int)); - const int edge = (ct % alignb); + const int edge = ct & (alignb - 1); if (edge) ct += alignb - edge; neighptr = firstneigh + ct; max_chunk = 0; @@ -548,7 +549,7 @@ void NPairIntel::bin_newton(const int offload, NeighList *list, } else { ct += n; const int alignb = (INTEL_DATA_ALIGN / sizeof(int)); - const int edge = (ct % alignb); + const int edge = ct & (alignb - 1); if (edge) ct += alignb - edge; neighptr = firstneigh + ct; if (ct + obound > list_size) { diff --git a/src/USER-INTEL/pair_airebo_intel.cpp b/src/USER-INTEL/pair_airebo_intel.cpp new file mode 100644 index 0000000000..ad3c97c9df --- /dev/null +++ b/src/USER-INTEL/pair_airebo_intel.cpp @@ -0,0 +1,4891 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Markus Hohnerbach (RWTH) +------------------------------------------------------------------------- */ + +#ifdef __INTEL_OFFLOAD +#pragma offload_attribute(push, target(mic)) +#endif +#include +#include +#include +#include +#include +#include +#include +#include "lmptype.h" +#include "intel_preprocess.h" +#include "intel_intrinsics_airebo.h" +#ifdef __INTEL_OFFLOAD +#pragma offload_attribute(pop) +#endif + +#include +#include +#include "pair_airebo_intel.h" +#include "atom.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "neigh_request.h" +#include "force.h" +#include "comm.h" +#include "memory.h" +#include "error.h" +#include "group.h" +#include "kspace.h" +#include "modify.h" +#include "suffix.h" + +using namespace LAMMPS_NS; + +#ifdef __INTEL_OFFLOAD +#pragma offload_attribute(push, target(mic)) +#endif + +template +struct LAMMPS_NS::PairAIREBOIntelParam { + flt_t cutlj, cutljrebosq, cut3rebo; + flt_t sigmin, sigcut; + flt_t cutljsq[2][2]; + flt_t lj1[2][2], lj2[2][2], lj3[2][2], lj4[2][2]; + + flt_t smin, Nmin, Nmax, NCmin, NCmax, thmin, thmax; + flt_t rcmin[2][2], rcmax[2][2], rcmaxsq[2][2], rcmaxp[2][2]; + flt_t Q[2][2], alpha[2][2], A[2][2], rho[2][2], BIJc[2][2][3], + Beta[2][2][3]; + flt_t rcLJmin[2][2], rcLJmax[2][2], rcLJmaxsq[2][2], bLJmin[2][2], + bLJmax[2][2]; + flt_t epsilon[2][2], sigma[2][2], epsilonT[2][2]; + + // spline coefficients + + flt_t gCdom[5], gC1[4][6], gC2[4][6], gHdom[4], gH[3][6]; + flt_t gDom[5+4]; + flt_t gVal[(4+4+3)*6]; + flt_t pCCdom[2][2], pCHdom[2][2], pCC[4][4][16], pCH[4][4][16]; + flt_t piCCdom[3][2], piCHdom[3][2], piHHdom[3][2]; + acc_t piCC[4][4][9][64], piCH[4][4][9][64], piHH[4][4][9][64]; + flt_t Tijdom[3][2]; + acc_t Tijc[4][4][9][64]; + + // spline knot values + + flt_t PCCf[5][5], PCCdfdx[5][5], PCCdfdy[5][5], PCHf[5][5]; + flt_t PCHdfdx[5][5], PCHdfdy[5][5]; + flt_t piCCf[5][5][11], piCCdfdx[5][5][11]; + flt_t piCCdfdy[5][5][11], piCCdfdz[5][5][11]; + flt_t piCHf[5][5][11], piCHdfdx[5][5][11]; + flt_t piCHdfdy[5][5][11], piCHdfdz[5][5][11]; + flt_t piHHf[5][5][11], piHHdfdx[5][5][11]; + flt_t piHHdfdy[5][5][11], piHHdfdz[5][5][11]; + flt_t Tf[5][5][10], Tdfdx[5][5][10], Tdfdy[5][5][10], Tdfdz[5][5][10]; +}; + +namespace { + +struct NeighListAIREBO { + int * num; /* num_all */ + int * num_half; /* num_all */ + int * offset; /* num_all */ + int * entries; /* num_all * num_neighs_per_atom */ +}; + +template +struct AtomAIREBOT { + flt_t x, y, z; + int w; +}; + +template +struct ResultForceT { + acc_t x, y, z, w; +}; + +template +struct KernelArgsAIREBOT { + int num_local; + int num_all; + int num_neighs_per_atom; + int num_types; + int frebo_from_atom, frebo_to_atom; + int neigh_from_atom, neigh_to_atom; + int rebuild_flag; + flt_t skin; + struct NeighListAIREBO neigh_lmp; + struct NeighListAIREBO neigh_rebo; + PairAIREBOIntelParam params; + struct AtomAIREBOT * x; /* num_all */ + int * tag; /* num_all */ + flt_t * nC, * nH; /* num_all */ + int * map; /* num_types+1 */ + struct ResultForceT * result_f; /* num_all */ + acc_t result_eng; +}; + +template +void aut_lennard_jones(KernelArgsAIREBOT * ka, int morseflag); +template +void aut_rebo_neigh(KernelArgsAIREBOT * ka); +template +void aut_frebo(KernelArgsAIREBOT * ka, int torsion_flag); + +} + +#ifdef __INTEL_OFFLOAD +#pragma offload_attribute(pop) +#endif + +/* ---------------------------------------------------------------------- */ + +PairAIREBOIntel::PairAIREBOIntel(LAMMPS *lmp) : PairAIREBO(lmp) +{ + suffix_flag |= Suffix::INTEL; + REBO_cnumneigh = NULL; + REBO_num_skin = NULL; + REBO_list_data = NULL; + fix = NULL; +} + +/* ---------------------------------------------------------------------- */ + +PairAIREBOIntel::~PairAIREBOIntel() +{ + memory->destroy(REBO_cnumneigh); + memory->destroy(REBO_num_skin); + memory->destroy(REBO_list_data); +} + +/* ---------------------------------------------------------------------- */ + +void PairAIREBOIntel::init_style() +{ + PairAIREBO::init_style(); + neighbor->requests[neighbor->nrequest-1]->intel = 1; + + int ifix = modify->find_fix("package_intel"); + if (ifix < 0) + error->all(FLERR, + "The 'package intel' command is required for /intel styles"); + fix = static_cast(modify->fix[ifix]); + + fix->pair_init_check(); + #ifdef _LMP_INTEL_OFFLOAD + _cop = fix->coprocessor_number(); + #endif + + if (fix->precision() == FixIntel::PREC_MODE_MIXED) { + pack_force_const(fix->get_mixed_buffers()); + fix->get_mixed_buffers()->need_tag(1); + } else if (fix->precision() == FixIntel::PREC_MODE_DOUBLE) { + pack_force_const(fix->get_double_buffers()); + fix->get_double_buffers()->need_tag(1); + } else { + pack_force_const(fix->get_single_buffers()); + fix->get_single_buffers()->need_tag(1); + } + + #ifdef _LMP_INTEL_OFFLOAD + if (fix->offload_noghost()) + error->all(FLERR,"The 'ghost no' option cannot be used with airebo/intel."); + #endif +} + +/* ---------------------------------------------------------------------- */ + +template +T * calloc_it(size_t size) { + return static_cast(calloc(size, sizeof(T))); +} + +void PairAIREBOIntel::compute(int eflag, int vflag) +{ + if (fix->precision()==FixIntel::PREC_MODE_MIXED) + compute(eflag, vflag, fix->get_mixed_buffers()); + else if (fix->precision()==FixIntel::PREC_MODE_DOUBLE) + compute(eflag, vflag, fix->get_double_buffers()); + else + compute(eflag, vflag, fix->get_single_buffers()); + + fix->balance_stamp(); + vflag_fdotr = 0; +} + +/* ---------------------------------------------------------------------- */ + +template +PairAIREBOIntelParam PairAIREBOIntel::get_param() +{ + PairAIREBOIntelParam fc; + +#define A(a) \ + for (int i = 0; i < sizeof(this->a)/sizeof(double); i++) { \ + reinterpret_cast(&fc.a)[i] = \ + reinterpret_cast(&this->a)[i]; \ + } +#define A0(a) \ + for (int i = 0; i < sizeof(fc.a)/sizeof(flt_t); i++) { \ + reinterpret_cast(&fc.a)[i] = \ + reinterpret_cast(this->a[0])[i]; \ + } +#define B(a) \ + for (int i = 0; i < sizeof(this->a)/sizeof(double); i++) { \ + reinterpret_cast(&fc.a)[i] = \ + reinterpret_cast(&this->a)[i]; \ + } + + A(cutlj) A(cutljrebosq) A(cut3rebo) A(sigmin); + A(sigcut) A0(cutljsq) A0(lj1) A0(lj2) A0(lj3); + A0(lj4) A(smin) A(Nmin) A(Nmax) A(NCmin) A(NCmax) A(thmin) A(thmax); + A(rcmin) A(rcmax) A(rcmaxsq) A(rcmaxp) A(Q) A(alpha) A(A) A(rho) A(BIJc); + A(Beta) A(rcLJmin) A(rcLJmax) A(rcLJmaxsq) A(bLJmin) A(bLJmax) A(epsilon); + A(sigma) A(epsilonT) A(gCdom) A(gC1) A(gC2) A(gHdom) A(gH) A(pCCdom); + A(pCHdom) A(pCC) A(pCH) A(piCCdom) A(piCHdom) A(piHHdom) B(piCC); + B(piCH) B(piHH) A(Tijdom) B(Tijc) A(PCCf) A(PCCdfdx) A(PCCdfdy) A(PCHf); + A(PCHdfdx) A(PCHdfdy) A(piCCf) A(piCCdfdx) A(piCCdfdy) A(piCCdfdz); + A(piCHf) A(piCHdfdx) A(piCHdfdy) A(piCHdfdz) A(piHHf) A(piHHdfdx); + A(piHHdfdy) A(piHHdfdz) A(Tf) A(Tdfdx) A(Tdfdy) A(Tdfdz); + +#undef A +#undef A0 +#undef B + for (int i = 0; i < 5; i++) fc.gDom[i] = fc.gCdom[i]; + for (int i = 0; i < 4; i++) fc.gDom[5+i] = fc.gHdom[i]; + for (int i = 0; i < 4; i++) for (int j = 0; j < 6; j++) + fc.gVal[6*i+j] = fc.gC1[i][j]; + for (int i = 0; i < 4; i++) for (int j = 0; j < 6; j++) + fc.gVal[4*6+6*i+j] = fc.gC2[i][j]; + for (int i = 0; i < 3; i++) for (int j = 0; j < 6; j++) + fc.gVal[8*6+6*i+j] = fc.gH[i][j]; + + return fc; +} + +/* ---------------------------------------------------------------------- */ + +template +void PairAIREBOIntel::compute( + int eflag, int vflag, IntelBuffers * buffers +) { + if (eflag || vflag) ev_setup(eflag,vflag); + else evflag = vflag_fdotr = vflag_atom = 0; + pvector[0] = pvector[1] = pvector[2] = 0.0; + + const int inum = list->inum; + const int nthreads = comm->nthreads; + const int host_start = fix->host_start_pair(); + const int offload_end = fix->offload_end_pair(); + const int ago = neighbor->ago; + + if (ago != 0 && fix->separate_buffers() == 0) { + fix->start_watch(TIME_PACK); + int packthreads; + if (nthreads > INTEL_HTHREADS) packthreads = nthreads; + else packthreads = 1; + #if defined(_OPENMP) + #pragma omp parallel if(packthreads > 1) + #endif + { + int ifrom, ito, tid; + IP_PRE_omp_range_id_align(ifrom, ito, tid, atom->nlocal + atom->nghost, + packthreads, sizeof(ATOM_T)); + buffers->thr_pack(ifrom,ito,ago); + } + fix->stop_watch(TIME_PACK); + } + + if (atom->nmax > maxlocal) { + #ifdef LMP_INTEL_OFFLOAD + if (maxlocal > 0 && _cop >= 0) { + int * const REBO_numneigh = this->REBO_numneigh; + int * const REBO_num_skin = this->REBO_num_skin; + int * const REBO_cnumneigh = this->REBO_cnumneigh; + int * const REBO_list_data = this->REBO_list_data; + double * const nC = this->nC; + double * const nH = this->nH; + #pragma offload_transfer target(mic:_cop) \ + nocopy(REBO_numneigh: alloc_if(0) free_if(1)) \ + nocopy(REBO_cnumneigh: alloc_if(0) free_if(1)) \ + nocopy(REBO_num_skin: alloc_if(0) free_if(1)) \ + nocopy(REBO_list_data: alloc_if(0) free_if(1)) \ + nocopy(nH: alloc_if(0) free_if(1)) \ + nocopy(nC: alloc_if(0) free_if(1)) + } + #endif + maxlocal = atom->nmax; + memory->destroy(REBO_numneigh); + memory->destroy(REBO_cnumneigh); + memory->destroy(REBO_list_data); + memory->sfree(REBO_firstneigh); + memory->destroy(nC); + memory->destroy(nH); + memory->create(REBO_numneigh,maxlocal,"AIREBO:numneigh"); + memory->create(REBO_cnumneigh,maxlocal,"AIREBO:cnumneigh"); + memory->create(REBO_num_skin,maxlocal,"AIREBO:cnumneigh"); + int max_nbors = buffers->get_max_nbors(); + memory->create(REBO_list_data,maxlocal * max_nbors,"AIREBO:list_data"); + REBO_firstneigh = (int **) memory->smalloc(maxlocal*sizeof(int *), + "AIREBO:firstneigh"); + memory->create(nC,maxlocal,"AIREBO:nC"); + memory->create(nH,maxlocal,"AIREBO:nH"); + #ifdef _LMP_INTEL_OFFLOAD + if (_cop >= 0) { + int * const REBO_numneigh = this->REBO_numneigh; + int * const REBO_num_skin = this->REBO_num_skin; + int * const REBO_cnumneigh = this->REBO_cnumneigh; + int * const REBO_list_data = this->REBO_list_data; + double * const nC = this->nC; + double * const nH = this->nH; + const int mnml = max_nbors * maxlocal; + #pragma offload_transfer target(mic:_cop) \ + nocopy(REBO_numneigh: length(maxlocal) alloc_if(1) free_if(0)) \ + nocopy(REBO_cnumneigh:length(maxlocal) alloc_if(1) free_if(0)) \ + nocopy(REBO_num_skin: length(maxlocal) alloc_if(1) free_if(0)) \ + nocopy(REBO_list_data:length(mnml) alloc_if(1) free_if(0)) \ + nocopy(nH: length(maxlocal) alloc_if(1) free_if(0)) \ + nocopy(nC: length(maxlocal) alloc_if(1) free_if(0)) + } + #endif + } + + if (evflag || vflag_fdotr) { + int ovflag = 0; + if (vflag_fdotr) ovflag = 2; + else if (vflag) ovflag = 1; + if (eflag) { + eval<1,1>(1, ovflag, buffers, 0, offload_end); + eval<1,1>(0, ovflag, buffers, host_start, inum); + } else { + eval<1,0>(1, ovflag, buffers, 0, offload_end); + eval<1,0>(0, ovflag, buffers, host_start, inum); + } + } else { + eval<0,0>(1, 0, buffers, 0, offload_end); + eval<0,0>(0, 0, buffers, host_start, inum); + } +} + +/* ---------------------------------------------------------------------- */ + +template +void PairAIREBOIntel::eval( + const int offload, const int vflag, + IntelBuffers * buffers, + const int astart, const int aend +) { + const int inum = aend - astart; + if (inum == 0) { + return; + } + int nlocal, nall, minlocal; + fix->get_buffern(offload, nlocal, nall, minlocal); + + const int ago = neighbor->ago; + IP_PRE_pack_separate_buffers(fix, buffers, ago, offload, nlocal, nall); + + ATOM_T * _noalias const x = buffers->get_x(offload); + const int * _noalias const numneighhalf = buffers->get_atombin(); + const int * _noalias const numneigh = list->numneigh; + const int * _noalias const cnumneigh = buffers->cnumneigh(list); + const int * _noalias const firstneigh = buffers->firstneigh(list); + int * const tag = atom->tag; + + const int ntypes = atom->ntypes + 1; + const int eatom = this->eflag_atom; + + int x_size, q_size, f_stride, ev_size, separate_flag; + IP_PRE_get_transfern(ago, 1 /*NEWTON_PAIR*/, EFLAG, vflag, + buffers, offload, fix, separate_flag, + x_size, q_size, ev_size, f_stride); + + int tc; + FORCE_T * _noalias f_start; + acc_t * _noalias ev_global; + IP_PRE_get_buffers(offload, buffers, fix, tc, f_start, ev_global); + + const int nthreads = tc; + const double skin = neighbor->skin; + const int max_nbor = buffers->get_max_nbors(); + const PairAIREBOIntelParam param = get_param(); + + // offload here + #ifdef _LMP_INTEL_OFFLOAD + int *overflow = fix->get_off_overflow_flag(); + double *timer_compute = fix->off_watch_pair(); + + int * const REBO_numneigh = this->REBO_numneigh; + int * const REBO_num_skin = this->REBO_num_skin; + int * const REBO_cnumneigh = this->REBO_cnumneigh; + int * const REBO_list_data = this->REBO_list_data; + double * const nC = this->nC; + double * const nH = this->nH; + const int torflag = this->torflag; + const int ljflag = this->ljflag; + const int morseflag = this->morseflag; + int * const map = this->map; + + if (offload) fix->start_watch(TIME_OFFLOAD_LATENCY); + + #pragma offload target(mic:_cop) if(offload) \ + in(firstneigh:length(0) alloc_if(0) free_if(0)) \ + in(cnumneigh:length(0) alloc_if(0) free_if(0)) \ + in(numneigh:length(0) alloc_if(0) free_if(0)) \ + in(numneighhalf:length(0) alloc_if(0) free_if(0)) \ + in(x:length(x_size) alloc_if(0) free_if(0)) \ + in(overflow:length(0) alloc_if(0) free_if(0)) \ + in(astart,nthreads,inum,nall,ntypes,vflag,eatom) \ + in(f_stride,nlocal,minlocal,separate_flag,offload) \ + out(f_start:length(f_stride) alloc_if(0) free_if(0)) \ + out(ev_global:length(ev_size) alloc_if(0) free_if(0)) \ + out(timer_compute:length(1) alloc_if(0) free_if(0)) \ + in(param,skin,max_nbor) \ + in(tag: length(0) alloc_if(0) free_if(0)) \ + in(torflag, ljflag, morseflag, ago) \ + in(nC: length(0) alloc_if(0) free_if(0)) \ + in(nH: length(0) alloc_if(0) free_if(0)) \ + in(REBO_numneigh: length(0) alloc_if(0) free_if(0)) \ + in(REBO_cnumneigh: length(0) alloc_if(0) free_if(0)) \ + in(REBO_num_skin: length(0) alloc_if(0) free_if(0)) \ + in(REBO_list_data: length(0) alloc_if(0) free_if(0)) \ + in(map: length(0) alloc_if(0) free_if(0)) \ + signal(f_start) + #endif + { + #if defined(__MIC__) && defined(_LMP_INTEL_OFFLOAD) + *timer_compute = MIC_Wtime(); + #endif + + IP_PRE_repack_for_offload(1 /*NEWTON_PAIR*/, separate_flag, nlocal, nall, + f_stride, x, 0/*q*/); + + acc_t oevdwl, oecoul, ov0, ov1, ov2, ov3, ov4, ov5; + if (EVFLAG) { + oevdwl = oecoul = (acc_t)0; + if (vflag) ov0 = ov1 = ov2 = ov3 = ov4 = ov5 = (acc_t)0; + } + + // loop over neighbors of my atoms + #if defined(_OPENMP) + #pragma omp parallel \ + shared(f_start,f_stride,nlocal,nall,minlocal) \ + reduction(+:oevdwl,oecoul,ov0,ov1,ov2,ov3,ov4,ov5) + #endif + { + int iifrom, iito, tid; + IP_PRE_omp_range_id(iifrom, iito, tid, inum, nthreads); + iifrom += astart; + iito += astart; + + int neigh_iifrom, neigh_iito; + IP_PRE_omp_range(neigh_iifrom, neigh_iito, tid, nall, nthreads); + + FORCE_T * _noalias const f = f_start - minlocal + (tid * f_stride); + memset(f + minlocal, 0, f_stride * sizeof(FORCE_T)); + + KernelArgsAIREBOT args; + args.num_local = nlocal; + args.num_all = nall; + args.num_neighs_per_atom = max_nbor; + args.num_types = ntypes; + args.frebo_from_atom = 0; + args.frebo_to_atom = args.num_local; + args.neigh_from_atom = 0; + args.neigh_to_atom = args.num_all; + args.rebuild_flag = ago == 0; + args.skin = skin; + args.neigh_lmp.num = const_cast(numneigh); + args.neigh_lmp.num_half = const_cast(numneighhalf); + args.neigh_lmp.offset = const_cast(cnumneigh); + args.neigh_lmp.entries = const_cast(firstneigh); + args.neigh_rebo.num = REBO_numneigh; + args.neigh_rebo.num_half = REBO_num_skin; + args.neigh_rebo.offset = REBO_cnumneigh; + args.neigh_rebo.entries = REBO_list_data; + args.params = param; + args.tag = tag; + args.nC = reinterpret_cast(nC); + args.nH = reinterpret_cast(nH); + args.map = map; + args.result_eng = 0; + args.x = (AtomAIREBOT*) x; + + args.result_f = (ResultForceT *) f; + args.neigh_from_atom = neigh_iifrom; + args.neigh_to_atom = neigh_iito; + args.frebo_from_atom = iifrom; + args.frebo_to_atom = iito; + + aut_rebo_neigh(&args); + #if defined(_OPENMP) + #pragma omp barrier + #endif + aut_frebo(&args, torflag); + if (ljflag) aut_lennard_jones(&args, morseflag); + + oevdwl += args.result_eng; + + IP_PRE_fdotr_reduce_omp(1, nall, minlocal, nthreads, f_start, f_stride, x, + offload, vflag, ov0, ov1, ov2, ov3, ov4, ov5); + } // end of omp parallel region + IP_PRE_fdotr_reduce(1, nall, nthreads, f_stride, vflag, + ov0, ov1, ov2, ov3, ov4, ov5); + if (EVFLAG) { + if (EFLAG) { + ev_global[0] = oevdwl; + ev_global[1] = oecoul; + } + if (vflag) { + ev_global[2] = ov0; + ev_global[3] = ov1; + ev_global[4] = ov2; + ev_global[5] = ov3; + ev_global[6] = ov4; + ev_global[7] = ov5; + } + } + #if defined(__MIC__) && defined(_LMP_INTEL_OFFLOAD) + *timer_compute = MIC_Wtime() - *timer_compute; + #endif + } // end of offload region + + if (offload) + fix->stop_watch(TIME_OFFLOAD_LATENCY); + else + fix->stop_watch(TIME_HOST_PAIR); + + if (EVFLAG) + fix->add_result_array(f_start, ev_global, offload, eatom, 0, vflag); + else + fix->add_result_array(f_start, 0, offload); +} + +/* ---------------------------------------------------------------------- */ + +template +void PairAIREBOIntel::pack_force_const(IntelBuffers * buffers) { + int tp1 = atom->ntypes + 1; + + buffers->set_ntypes(tp1,1); + flt_t **cutneighsq = buffers->get_cutneighsq(); + flt_t **cutneighghostsq = buffers->get_cutneighghostsq(); + + // Repeat cutsq calculation because done after call to init_style + double cut, cutneigh; + for (int i = 1; i <= atom->ntypes; i++) { + for (int j = i; j <= atom->ntypes; j++) { + if (setflag[i][j] != 0 || (setflag[i][i] != 0 && setflag[j][j] != 0)) { + cut = init_one(i, j); + cutneigh = cut + neighbor->skin; + cutsq[i][j] = cutsq[j][i] = cut*cut; + cutneighsq[i][j] = cutneighsq[j][i] = cutneigh * cutneigh; + cut = cutghost[i][j] + neighbor->skin; + cutneighghostsq[i][j] = cutneighghostsq[j][i] = cut*cut; + } + } + } + + #ifdef _LMP_INTEL_OFFLOAD + if (_cop < 0) return; + flt_t * ocutneighsq = cutneighsq[0]; + size_t VL = 512 / 8 / sizeof(flt_t); + int ntypes = tp1; + int tp1sq = tp1 * tp1; + // TODO the lifecycle of "map" is currently not 100% correct + // it might not be freed if this method is called more than once + int * map = this->map; + #pragma offload_transfer target(mic:_cop) \ + in(ocutneighsq: length(tp1sq) alloc_if(0) free_if(0)) \ + in(map: length(tp1) alloc_if(1) free_if(0)) + #endif + +} + +/* ---------------------------------------------------------------------- + Implementation + ---------------------------------------------------------------------- */ + +namespace { + +#ifdef __INTEL_OFFLOAD +#pragma offload_attribute(push, target(mic)) +#endif + +namespace overloaded { + double sqrt(double a) { return ::sqrt(a); } + float sqrt(float a) { return ::sqrtf(a); } + double sin(double a) { return ::sin(a); } + float sin(float a) { return ::sinf(a); } + double cos(double a) { return ::cos(a); } + float cos(float a) { return ::cosf(a); } + double exp(double a) { return ::exp(a); } + float exp(float a) { return ::expf(a); } + double pow(double a, double b) { return ::pow(a, b); } + float pow(float a, float b) { return ::powf(a, b); } +} + +/* ---------------------------------------------------------------------- + Scalar AIREBO implementation, standalone, with massive code reuse + compared to original code. + ---------------------------------------------------------------------- */ + +#define M_PI 3.14159265358979323846 /* pi */ + +#define CARBON 0 +#define HYDROGEN 1 +#define TOL 1.0e-9 + +template +inline T fmin_nonan(T a, T b) { + return a < b ? a : b; +} +template +inline T fmax_nonan(T a, T b) { + return a > b ? a : b; +} + +template +inline flt_t Sp(flt_t r, flt_t lo, flt_t hi, flt_t * del) { + flt_t t = (r - lo) / (hi - lo); + if (t <= 0) { + if (del) *del = 0; + return 1; + } else if (t >= 1) { + if (del) *del = 0; + return 0; + } else { + t *= static_cast(M_PI); + if (del) *del = static_cast(-0.5 * M_PI) + * overloaded::sin(t) / (hi - lo); + return static_cast(0.5) * (1 + overloaded::cos(t)); + } +} + +template +inline flt_t Sp2(flt_t r, flt_t lo, flt_t hi, flt_t * del) { + flt_t t = (r - lo) / (hi - lo); + if (t <= 0) { + if (del) *del = 0; + return 1; + } else if (t >= 1) { + if (del) *del = 0; + return 0; + } else { + if (del) *del = 6 * (t * t - t) / (hi - lo); + return 1 - t * t * (3 - 2 * t); + } +} + +template +inline flt_t eval_poly_lin(int n, flt_t * coeffs, flt_t x, flt_t * deriv) { + flt_t result = coeffs[n - 1]; + *deriv = coeffs[n - 1] * (n - 1); + for (int i = n - 2; i > 0; i--) { + result = coeffs[i] + x * result; + *deriv = coeffs[i] * i + x * (*deriv); + } + result = coeffs[0] + x * result; + return result; +} + +template +inline flt_t gSpline(KernelArgsAIREBOT * ka, int itype, flt_t cos, flt_t N, flt_t * dgdc, flt_t * dgdN) { + flt_t NCmin = ka->params.NCmin; + flt_t NCmax = ka->params.NCmax; + int index = 0; + flt_t * gDom = NULL; + int nDom = 0; + int offs = 0; + if (itype == 0) { + nDom = 4; + gDom = &ka->params.gCdom[0]; + if (N > NCmin) offs = 4 * 6; + } else { + nDom = 3; + gDom = &ka->params.gHdom[0]; + offs = 8 * 6; + } + cos = fmax_nonan(gDom[0], fmin_nonan(gDom[nDom], cos)); + int i; + for (i = 0; i < nDom; i++) { + if (cos >= gDom[i] && cos <= gDom[i + 1]) { + index = i; + } + } + flt_t g = eval_poly_lin(6, &ka->params.gVal[offs+index*6], cos, dgdc); + *dgdN = 0; + if (itype == 0 && N > NCmin && N < NCmax) { + flt_t dg1; + flt_t g1 = eval_poly_lin(6, &ka->params.gVal[index*6], cos, &dg1); + flt_t dS; + flt_t cut = Sp(N, NCmin, NCmax, &dS); + *dgdN = dS * (g1 - g); + g = g + cut * (g1 - g); + *dgdc = *dgdc + cut * (dg1 - *dgdc); + } + return g; +} + +template +inline flt_t eval_poly_bi(int n, flt_t * coeffs, flt_t x, flt_t y, + flt_t * deriv) { + flt_t dy; + flt_t vy = eval_poly_lin(n, &coeffs[n * (n - 1)], y, &dy); + flt_t result = vy; + deriv[0] = vy * (n - 1); + deriv[1] = dy; + for (int i = n - 2; i > 0; i--) { + vy = eval_poly_lin(n, &coeffs[n * i], y, &dy); + result = vy + x * result; + deriv[0] = vy * i + x * deriv[0]; + deriv[1] = dy + x * deriv[1]; + } + result = eval_poly_lin(n, &coeffs[0], y, &dy) + x * result; + deriv[1] = dy + x * deriv[1]; + return result; +} + +template +inline flt_t eval_poly_tri(int n, flt_t * coeffs, flt_t x, flt_t y, flt_t z, + flt_t * deriv) { + flt_t dyz[2]; + flt_t vyz = eval_poly_bi(n, &coeffs[n * n * (n - 1)], y, z, &dyz[0]); + flt_t result = vyz; + deriv[0] = vyz * (n - 1); + deriv[1] = dyz[0]; + deriv[2] = dyz[1]; + for (int i = n - 2; i > 0; i--) { + vyz = eval_poly_bi(n, &coeffs[n * n * i], y, z, &dyz[0]); + result = vyz + x * result; + deriv[0] = vyz * i + x * deriv[0]; + deriv[1] = dyz[0] + x * deriv[1]; + deriv[2] = dyz[1] + x * deriv[2]; + } + result = eval_poly_bi(n, &coeffs[0], y, z, &dyz[0]) + x * result; + deriv[1] = dyz[0] + x * deriv[1]; + deriv[2] = dyz[1] + x * deriv[2]; + return result; +} + +template +inline flt_t PijSpline(KernelArgsAIREBOT * ka, int itype, + int jtype, flt_t NC, flt_t NH, flt_t * dN) { + dN[0] = 0.0; + dN[1] = 0.0; + if (itype == HYDROGEN) return 0; + flt_t *pCJdom = jtype == CARBON ? &ka->params.pCCdom[0][0] : + &ka->params.pCHdom[0][0]; + NC = fmax_nonan(pCJdom[0], fmin_nonan(pCJdom[1], NC)); + NH = fmax_nonan(pCJdom[2], fmin_nonan(pCJdom[3], NH)); + int nC = floor(NC); + int nH = floor(NH); + #define PijSelect(a, b) (jtype == CARBON ? ka->params.a : ka->params.b) + if (fabs(NC - nC) < TOL && fabs(NH - nH) < TOL) { + dN[0] = PijSelect(PCCdfdx, PCHdfdx)[nC][nH]; + dN[1] = PijSelect(PCCdfdy, PCHdfdy)[nC][nH]; + return PijSelect(PCCf, PCHf)[nC][nH]; + } + if (NC == pCJdom[1]) nC -= 1; + if (NH == pCJdom[3]) nH -= 1; + return eval_poly_bi(4, &PijSelect(pCC, pCH)[nC][nH][0], NC, NH, dN); + #undef PijSelect +} + +template +inline flt_t TijSpline(KernelArgsAIREBOT * ka, flt_t Nij, + flt_t Nji, flt_t Nijconj, acc_t * dN3) { + flt_t * Tijdom = &ka->params.Tijdom[0][0]; + Nij = fmax_nonan(Tijdom[0], fmin_nonan(Tijdom[1], Nij)); + Nji = fmax_nonan(Tijdom[2], fmin_nonan(Tijdom[3], Nji)); + Nijconj = fmax_nonan(Tijdom[4], fmin_nonan(Tijdom[5], Nijconj)); + int nij = floor(Nij); + int nji = floor(Nji); + int nijconj = floor(Nijconj); + if (fabs(Nij - nij) < TOL && fabs(Nji - nji) < + TOL && fabs(Nijconj - nijconj) < TOL) { + dN3[0] = ka->params.Tdfdx[nij][nji][nijconj]; + dN3[1] = ka->params.Tdfdy[nij][nji][nijconj]; + dN3[2] = ka->params.Tdfdz[nij][nji][nijconj]; + return ka->params.Tf[nij][nji][nijconj]; + } + if (Nij == Tijdom[1]) nij -= 1; + if (Nji == Tijdom[3]) nji -= 1; + if (Nijconj == Tijdom[5]) nijconj -= 1; + return eval_poly_tri(4, &ka->params.Tijc[nij][nji][nijconj][0], Nij, + Nji, Nijconj, dN3); +} + +template +inline flt_t piRCSpline(KernelArgsAIREBOT * ka, int itype, + int jtype, flt_t Nij, flt_t Nji, flt_t Nijconj, acc_t * dN3) { + const int HH = 2; + const int CH = 1; + /* const int CC = 0; */ + int select = itype + jtype; + #define piRCSelect(a, b, c) (select == HH ? ka->params.a : select == CH ? \ + ka->params.b : ka->params.c) + flt_t * piIJdom = &piRCSelect(piHHdom, piCHdom, piCCdom)[0][0]; + if (select == HH) { + if (Nij < piIJdom[0] || Nij > piIJdom[1] || Nji < piIJdom[2] || + Nji > piIJdom[3] || Nijconj < piIJdom[4] || Nijconj > piIJdom[5]) { + Nij = 0; + Nji = 0; + Nijconj = 0; + } + } + Nij = fmax_nonan(piIJdom[0], fmin_nonan(piIJdom[1], Nij)); + Nji = fmax_nonan(piIJdom[2], fmin_nonan(piIJdom[3], Nji)); + Nijconj = fmax_nonan(piIJdom[4], fmin_nonan(piIJdom[5], Nijconj)); + int nij = floor(Nij); + int nji = floor(Nji); + int nijconj = floor(Nijconj); + if (fabs(Nij - nij) < TOL && fabs(Nji - nji) < + TOL && fabs(Nijconj - nijconj) < TOL) { + dN3[0] = piRCSelect(piHHdfdx, piCHdfdx, piCCdfdx)[nij][nji][nijconj]; + dN3[1] = piRCSelect(piHHdfdy, piCHdfdy, piCCdfdy)[nij][nji][nijconj]; + dN3[2] = piRCSelect(piHHdfdz, piCHdfdz, piCCdfdz)[nij][nji][nijconj]; + return piRCSelect(piHHf, piCHf, piCCf)[nij][nji][nijconj]; + } + if (Nij == piIJdom[1]) nij -= 1; + if (Nji == piIJdom[3]) nji -= 1; + if (Nijconj == piIJdom[5]) nijconj -= 1; + return eval_poly_tri(4, + &piRCSelect(piHH, piCH, piCC)[nij][nji][nijconj][0], Nij, Nji, Nijconj, + dN3); + #undef piRCSelect +} + +/* + * Implements the p_ij term in airebo, which occurs on 4 different occasions + * in the original lammps code. + */ +template +inline flt_t frebo_pij(KernelArgsAIREBOT * ka, int i, int j, + flt_t rijx, flt_t rijy, flt_t rijz, flt_t rijmag, flt_t wij, flt_t VA, + flt_t * sum_N, acc_t fij[3]) { + ResultForceT * result_f = ka->result_f; + AtomAIREBOT * x = ka->x; + int * map = ka->map; + flt_t * nC = ka->nC; + flt_t * nH = ka->nH; + flt_t x_i = x[i].x; + flt_t y_i = x[i].y; + flt_t z_i = x[i].z; + int itype = map[x[i].w]; + int jtype = map[x[j].w]; + flt_t invrijm = 1 / rijmag; + flt_t invrijm2 = invrijm * invrijm; + flt_t rcminij = ka->params.rcmin[itype][jtype]; + flt_t rcmaxij = ka->params.rcmax[itype][jtype]; + flt_t Nmin = ka->params.Nmin; + flt_t Nmax = ka->params.Nmax; + flt_t Nij = nC[i] + nH[i] - wij; + flt_t NijC = nC[i] - wij * (1 - jtype); + flt_t NijH = nH[i] - wij * jtype; + flt_t sum_pij = 0; + flt_t sum_dpij_dN = 0; + flt_t dN2[2] = {0}; + flt_t pij = 0; + *sum_N = 0; + int * neighs = ka->neigh_rebo.entries + ka->neigh_rebo.offset[i]; + int pass; + for (pass = 0; pass < 2; pass++) { + int kk; + int knum = ka->neigh_rebo.num[i]; + for (kk = 0; kk < knum; kk++) { + int k = neighs[kk]; + if (k == j) continue; + flt_t rikx = x_i - x[k].x; + flt_t riky = y_i - x[k].y; + flt_t rikz = z_i - x[k].z; + int ktype = map[x[k].w]; + flt_t rikmag = overloaded::sqrt(rikx * rikx + riky * riky + rikz * rikz); + 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 rcminik = ka->params.rcmin[itype][ktype]; + flt_t rcmaxik = ka->params.rcmax[itype][ktype]; + flt_t dwik; + flt_t wik = Sp(rikmag, rcminik, rcmaxik, &dwik); + flt_t Nki = nC[k] + nH[k] - wik; + flt_t cosjik = (rijx * rikx + rijy * riky + rijz * rikz) / + (rijmag * rikmag); + cosjik = fmin_nonan(1, fmax_nonan(-1, cosjik)); + flt_t dgdc, dgdN; + flt_t g = gSpline(ka, itype, cosjik, Nij, &dgdc, &dgdN); + if (pass == 0) { + sum_pij += wik * g * ex_lam; + sum_dpij_dN += wik * dgdN * ex_lam; + flt_t cutN = Sp(Nki, Nmin, Nmax, NULL); + *sum_N += (1 - ktype) * wik * cutN; + } else { + flt_t tmp = -0.5 * pij * pij * pij; + flt_t invrikm = 1 / rikmag; + flt_t rjkx = rikx - rijx; + flt_t rjky = riky - rijy; + flt_t rjkz = rikz - rijz; + flt_t rjkmag = sqrt(rjkx * rjkx + rjky * rjky + rjkz * rjkz); + flt_t rijrik = 2 * rijmag * rikmag; + flt_t rr = rijmag * rijmag - rikmag * rikmag; + flt_t dctdjk = -2 / rijrik; + flt_t dctdik = (-rr + rjkmag * rjkmag) / (rijrik * rikmag * rikmag); + flt_t dctdij = (rr + rjkmag * rjkmag) / (rijrik * rijmag * rijmag); + + acc_t fi[3], fj[3], fk[3]; + flt_t pref = 0.5 * VA * tmp; + flt_t tmp20 = pref * wik * dgdc * ex_lam; + fj[0] = fj[1] = fj[2] = 0; + fi[0] = -tmp20 * dctdik * rikx; + fi[1] = -tmp20 * dctdik * riky; + fi[2] = -tmp20 * dctdik * rikz; + fk[0] = tmp20 * dctdik * rikx; + fk[1] = tmp20 * dctdik * riky; + fk[2] = tmp20 * dctdik * rikz; + + fij[0] += -tmp20 * dctdij * rijx; + fij[1] += -tmp20 * dctdij * rijy; + fij[2] += -tmp20 * dctdij * rijz; + + fi[0] += -tmp20 * dctdjk * rjkx; + fi[1] += -tmp20 * dctdjk * rjky; + fi[2] += -tmp20 * dctdjk * rjkz; + fk[0] += tmp20 * dctdjk * rjkx; + fk[1] += tmp20 * dctdjk * rjky; + fk[2] += tmp20 * dctdjk * rjkz; + fij[0] -= -tmp20 * dctdjk * rjkx; + fij[1] -= -tmp20 * dctdjk * rjky; + fij[2] -= -tmp20 * dctdjk * rjkz; + + flt_t tmp21 = pref * (wik * g * ex_lam * 4 * itype); + fij[0] -= 1 * tmp21 * rijx * invrijm; + fij[1] -= 1 * tmp21 * rijy * invrijm; + fij[2] -= 1 * tmp21 * rijz * invrijm; + fi[0] -= tmp21 * (-rikx * invrikm); + fi[1] -= tmp21 * (-riky * invrikm); + fi[2] -= tmp21 * (-rikz * invrikm); + fk[0] -= tmp21 * (rikx * invrikm); + fk[1] -= tmp21 * (riky * invrikm); + fk[2] -= tmp21 * (rikz * invrikm); + + // coordination forces + + // dwik forces + flt_t tmp22 = pref * dwik * g * ex_lam * invrikm; + fi[0] -= tmp22 * rikx; + fi[1] -= tmp22 * riky; + fi[2] -= tmp22 * rikz; + fk[0] += tmp22 * rikx; + fk[1] += tmp22 * riky; + fk[2] += tmp22 * rikz; + + // PIJ forces + flt_t tmp23 = pref * dN2[ktype] * dwik * invrikm; + fi[0] -= tmp23 * rikx; + fi[1] -= tmp23 * riky; + fi[2] -= tmp23 * rikz; + fk[0] += tmp23 * rikx; + fk[1] += tmp23 * riky; + fk[2] += tmp23 * rikz; + + // dgdN forces + flt_t tmp24 = pref * sum_dpij_dN * dwik * invrikm; + fi[0] -= tmp24 * rikx; + fi[1] -= tmp24 * riky; + fi[2] -= tmp24 * rikz; + fk[0] += tmp24 * rikx; + fk[1] += tmp24 * riky; + fk[2] += tmp24 * rikz; + + result_f[i].x += fi[0]; + result_f[i].y += fi[1]; + result_f[i].z += fi[2]; + result_f[j].x += fj[0]; + result_f[j].y += fj[1]; + result_f[j].z += fj[2]; + result_f[k].x += fk[0]; + result_f[k].y += fk[1]; + result_f[k].z += fk[2]; + } + } + if (pass == 0) { + flt_t PijS = PijSpline(ka, itype, jtype, NijC, NijH, dN2); + pij = 1 / overloaded::sqrt(1 + sum_pij + PijS); + } + } + return pij; +} + +template +inline flt_t frebo_pi_rc(KernelArgsAIREBOT * ka, int itype, + int jtype, flt_t Nij, flt_t Nji, flt_t Nijconj, flt_t * dN3) { + acc_t dN3tmp[3] = {0}; + flt_t ret = piRCSpline(ka, itype, jtype, Nij, Nji, Nijconj, dN3tmp); + dN3[0] = dN3tmp[0]; + dN3[1] = dN3tmp[1]; + dN3[2] = dN3tmp[2]; + return ret; +} + +template +inline flt_t frebo_Tij(KernelArgsAIREBOT * ka, int itype, + int jtype, flt_t Nij, flt_t Nji, flt_t Nijconj, flt_t * dN3) { + dN3[0] = 0; + dN3[1] = 0; + dN3[2] = 0; + if (itype == HYDROGEN || jtype == HYDROGEN) return 0; + acc_t dN3tmp[3] = {0}; + flt_t ret = TijSpline(ka, Nij, Nji, Nijconj, dN3tmp); + dN3[0] = dN3tmp[0]; + dN3[1] = dN3tmp[1]; + dN3[2] = dN3tmp[2]; + return ret; +} + +/* + * Implements a scalar version of the sum cos^1(omega) term used in pi^dh_ij. + * Occurs in both bondorder and bondorderLJ. + */ +template +inline flt_t frebo_sum_omega(KernelArgsAIREBOT * ka, int i, int j, + flt_t r23x, flt_t r23y, flt_t r23z, flt_t r23mag, flt_t VA, acc_t fij[3]) { + ResultForceT * result_f = ka->result_f; + acc_t sum_omega = 0; + int a2 = i; + int a3 = j; + flt_t r32x = - r23x; + flt_t r32y = - r23y; + flt_t r32z = - r23z; + int * map = ka->map; + AtomAIREBOT * x = ka->x; + flt_t thmin = ka->params.thmin; + flt_t thmax = ka->params.thmax; + int itype = map[x[i].w]; + int jtype = map[x[j].w]; + int * neighs_i = ka->neigh_rebo.entries + ka->neigh_rebo.offset[i]; + int * neighs_j = ka->neigh_rebo.entries + ka->neigh_rebo.offset[j]; + int num_i = ka->neigh_rebo.num[i]; + int num_j = ka->neigh_rebo.num[j]; + int kk; + for (kk = 0; kk < num_i; kk++) { + int k = neighs_i[kk]; + if (k == j) continue; + int a1 = k; + int ktype = map[x[k].w]; + flt_t r21x = x[a2].x - x[a1].x; + flt_t r21y = x[a2].y - x[a1].y; + flt_t r21z = x[a2].z - x[a1].z; + flt_t r21mag = overloaded::sqrt(r21x * r21x + r21y * r21y + r21z * r21z); + flt_t cos321 = (r23x * r21x + r23y * r21y + r23z * r21z) / + (r23mag * r21mag); + cos321 = fmin_nonan(1, fmax_nonan(-1, cos321)); + flt_t sin321 = overloaded::sqrt(1 - cos321 * cos321); + if (sin321 == 0) continue; + flt_t sink2i = 1 / (sin321 * sin321); + flt_t rik2i = 1 / (r21mag * r21mag); + flt_t rr = r23mag * r23mag - r21mag * r21mag; + flt_t r31x = r21x - r23x; + flt_t r31y = r21y - r23y; + flt_t r31z = r21z - r23z; + flt_t r31mag2 = r31x * r31x + r31y * r31y + r31z * r31z; + flt_t rijrik = 2 * r23mag * r21mag; + flt_t r21mag2 = r21mag * r21mag; + flt_t dctik = (-rr + r31mag2) / (rijrik * r21mag2); + flt_t dctij = (rr + r31mag2) / (rijrik * r23mag * r23mag); + flt_t dctjk = -2 / rijrik; + flt_t rcmin21 = ka->params.rcmin [itype][ktype]; + flt_t rcmaxp21 = ka->params.rcmaxp[itype][ktype]; + flt_t dw21; + flt_t w21 = Sp(r21mag, rcmin21, rcmaxp21, &dw21); + // why does this additional cutoff in the cosine exist? + // the original code by stuart answers this: + // it avoid issues when bonds in the dihedral are linear + // by switching the dihedral off beforehand. + // This is the reason for both the sin == 0 checks and the + // tspjik = Sp2(..) calls. + // Unfortunately, this is not exactly stated in the original paper. + // It might be similar in purpose to the H(sin - s^min) term that + // appears in that paper, but can not be found in original REBO papers. + flt_t dtsjik; + flt_t tspjik = Sp2(cos321, thmin, thmax, &dtsjik); + dtsjik = - dtsjik; + int ll; + for (ll = 0; ll < num_j; ll++) { + int l = neighs_j[ll]; + if (l == i || l == k) continue; + int ltype = map[x[l].w]; + int a4 = l; + flt_t r34x = x[a3].x - x[a4].x; + flt_t r34y = x[a3].y - x[a4].y; + flt_t r34z = x[a3].z - x[a4].z; + flt_t r34mag = overloaded::sqrt(r34x * r34x + r34y * r34y + r34z * r34z); + flt_t cos234 = (r32x * r34x + r32y * r34y + r32z * r34z) / + (r23mag * r34mag); + cos234 = fmin_nonan(1, fmax_nonan(-1, cos234)); + flt_t sin234 = overloaded::sqrt(1 - cos234 * cos234); + if (sin234 == 0) continue; + flt_t sinl2i = 1 / (sin234 * sin234); + flt_t rjl2i = 1 / (r34mag * r34mag); + + flt_t rcminjl = ka->params.rcmin[jtype][ltype]; + flt_t rcmaxpjl = ka->params.rcmaxp[jtype][ltype]; + flt_t dw34; + flt_t w34 = Sp(r34mag, rcminjl, rcmaxpjl, &dw34); + flt_t rr = (r23mag * r23mag) - (r34mag * r34mag); + flt_t r24x = r23x + r34x; + flt_t r24y = r23y + r34y; + flt_t r24z = r23z + r34z; + flt_t r242 = + (r24x * r24x) + (r24y * r24y) + (r24z * r24z); + flt_t rijrjl = 2 * r23mag * r34mag; + flt_t rjl2 = r34mag * r34mag; + flt_t dctjl = (-rr + r242) / (rijrjl * rjl2); + flt_t dctji = (rr + r242) / (rijrjl * r23mag * r23mag); + flt_t dctil = -2 / rijrjl; + flt_t dtsijl; + flt_t tspijl = Sp2(cos234, thmin, thmax, &dtsijl); + dtsijl = -dtsijl; // need minus sign + flt_t prefactor = VA; + + flt_t cross321x = (r32y * r21z) - (r32z * r21y); + flt_t cross321y = (r32z * r21x) - (r32x * r21z); + flt_t cross321z = (r32x * r21y) - (r32y * r21x); + flt_t cross234x = (r23y * r34z) - (r23z * r34y); + flt_t cross234y = (r23z * r34x) - (r23x * r34z); + flt_t cross234z = (r23x * r34y) - (r23y * r34x); + + flt_t cwnum = (cross321x * cross234x) + + (cross321y * cross234y) + + (cross321z * cross234z); + flt_t cwnom = r21mag * r34mag * r23mag * r23mag * sin321 * sin234; + flt_t om1234 = cwnum / cwnom; + flt_t cw = om1234; + sum_omega += ((1 - (om1234 * om1234)) * w21 * w34) * + (1 - tspjik) * (1 - tspijl); + if (VA == static_cast(0.0)) continue; + + flt_t dt1dik = (rik2i) - (dctik * sink2i * cos321); + flt_t dt1djk = (-dctjk * sink2i * cos321); + flt_t dt1djl = (rjl2i) - (dctjl * sinl2i * cos234); + flt_t dt1dil = (-dctil * sinl2i * cos234); + flt_t dt1dij = (2 / (r23mag * r23mag)) - + (dctij * sink2i * cos321) - + (dctji * sinl2i * cos234); + + flt_t dt2dikx = (-r23z * cross234y) + (r23y * cross234z); + flt_t dt2diky = (-r23x * cross234z) + (r23z * cross234x); + flt_t dt2dikz = (-r23y * cross234x) + (r23x * cross234y); + + flt_t dt2djlx = (-r23y * cross321z) + (r23z * cross321y); + flt_t dt2djly = (-r23z * cross321x) + (r23x * cross321z); + flt_t dt2djlz = (-r23x * cross321y) + (r23y * cross321x); + + flt_t dt2dijx = (r21z * cross234y) - (r34z * cross321y) - + flt_t (r21y * cross234z) + (r34y * cross321z); + flt_t dt2dijy = (r21x * cross234z) - (r34x * cross321z) - + flt_t (r21z * cross234x) + (r34z * cross321x); + flt_t dt2dijz = (r21y * cross234x) - (r34y * cross321x) - + flt_t (r21x * cross234y) + (r34x * cross321y); + + flt_t aa = (prefactor * 2 * cw / cwnom) * w21 * w34 * + (1 - tspjik) * (1 - tspijl); + flt_t aaa1 = -prefactor * (1 - (om1234 * om1234)) * + (1 - tspjik) * (1 - tspijl); + flt_t aaa2 = -prefactor * (1 - (om1234 * om1234)) * w21 * w34; + flt_t at2 = aa * cwnum; + + flt_t fcijpc = (-dt1dij * at2) + + (aaa2 * dtsjik * dctij * (1 - tspijl)) + + (aaa2 * dtsijl * dctji * (1 - tspjik)); + flt_t fcikpc = (-dt1dik * at2) + + (aaa2 * dtsjik * dctik * (1 - tspijl)); + flt_t fcjlpc = (-dt1djl * at2) + + (aaa2 * dtsijl * dctjl * (1 - tspjik)); + flt_t fcjkpc = (-dt1djk * at2) + + (aaa2 * dtsjik * dctjk * (1 - tspijl)); + flt_t fcilpc = (-dt1dil * at2) + + (aaa2 * dtsijl * dctil * (1 - tspjik)); + + flt_t F23x = (fcijpc * r23x) + (aa * dt2dijx); + flt_t F23y = (fcijpc * r23y) + (aa * dt2dijy); + flt_t F23z = (fcijpc * r23z) + (aa * dt2dijz); + + flt_t F12x = (fcikpc * r21x) + (aa * dt2dikx); + flt_t F12y = (fcikpc * r21y) + (aa * dt2diky); + flt_t F12z = (fcikpc * r21z) + (aa * dt2dikz); + + flt_t F34x = (fcjlpc * r34x) + (aa * dt2djlx); + flt_t F34y = (fcjlpc * r34y) + (aa * dt2djly); + flt_t F34z = (fcjlpc * r34z) + (aa * dt2djlz); + + flt_t F31x = (fcjkpc * r31x); + flt_t F31y = (fcjkpc * r31y); + flt_t F31z = (fcjkpc * r31z); + + flt_t F24x = (fcilpc * r24x); + flt_t F24y = (fcilpc * r24y); + flt_t F24z = (fcilpc * r24z); + + flt_t f1x = -F12x - F31x; + flt_t f1y = -F12y - F31y; + flt_t f1z = -F12z - F31z; + flt_t f2x = F12x + F31x; + flt_t f2y = F12y + F31y; + flt_t f2z = F12z + F31z; + flt_t f3x = F34x + F24x; + flt_t f3y = F34y + F24y; + flt_t f3z = F34z + F24z; + flt_t f4x = -F34x - F24x; + flt_t f4y = -F34y - F24y; + flt_t f4z = -F34z - F24z; + + fij[0] += F23x + F24x - F31x; + fij[1] += F23y + F24y - F31y; + fij[2] += F23z + F24z - F31z; + + // coordination forces + + flt_t tmp20 = VA * ((1 - (om1234 * om1234))) * + (1 - tspjik) * (1 - tspijl) * dw21 * w34 / r21mag; + f2x -= tmp20 * r21x; + f2y -= tmp20 * r21y; + f2z -= tmp20 * r21z; + f1x += tmp20 * r21x; + f1y += tmp20 * r21y; + f1z += tmp20 * r21z; + + flt_t tmp21 = VA * ((1 - (om1234 * om1234))) * + (1 - tspjik) * (1 - tspijl) * w21 * dw34 / r34mag; + f3x -= tmp21 * r34x; + f3y -= tmp21 * r34y; + f3z -= tmp21 * r34z; + f4x += tmp21 * r34x; + f4y += tmp21 * r34y; + f4z += tmp21 * r34z; + + result_f[a1].x += f1x; + result_f[a1].y += f1y; + result_f[a1].z += f1z; + result_f[a2].x += f2x; + result_f[a2].y += f2y; + result_f[a2].z += f2z; + result_f[a3].x += f3x; + result_f[a3].y += f3y; + result_f[a3].z += f3z; + result_f[a4].x += f4x; + result_f[a4].y += f4y; + result_f[a4].z += f4z; + } + } + return sum_omega; +} + +/* + * Implements a scalar implementation the force update due to splines. + * It is used for both pi^rc_ij and T_ij. + * Occurs four times in each bondorder and bondorderLJ. + */ +template +inline void frebo_N_spline_force(KernelArgsAIREBOT * ka, int i, + int j, flt_t VA, flt_t dN, flt_t dNconj, flt_t Nconj) { + int * map = ka->map; + AtomAIREBOT * x = ka->x; + ResultForceT * result_f = ka->result_f; + flt_t * nC = ka->nC; + flt_t * nH = ka->nH; + flt_t Nmin = ka->params.Nmin; + flt_t Nmax = ka->params.Nmax; + int itype = map[x[i].w]; + int * neighs = ka->neigh_rebo.entries + ka->neigh_rebo.offset[i]; + int knum = ka->neigh_rebo.num[i]; + int kk; + for (kk = 0; kk < knum; kk++) { + int k = neighs[kk]; + if (k == j) continue; + flt_t rikx = x[i].x - x[k].x; + flt_t riky = x[i].y - x[k].y; + flt_t rikz = x[i].z - x[k].z; + flt_t rikmag = overloaded::sqrt(rikx * rikx + riky * riky + rikz * rikz); + int ktype = map[x[k].w]; + flt_t rcminik = ka->params.rcmin[itype][ktype]; + flt_t rcmaxik = ka->params.rcmax[itype][ktype]; + flt_t dwik; + flt_t wik = Sp(rikmag, rcminik, rcmaxik, &dwik); + flt_t Nki = nC[k] + nH[k] - wik; + flt_t dNki; + flt_t SpN = Sp(Nki, Nmin, Nmax, &dNki); + flt_t fdN = VA * dN * dwik / rikmag; + flt_t fdNconj = VA * dNconj * 2 * Nconj * dwik * SpN / rikmag; + flt_t ffactor = fdN; + if (ktype == 0) ffactor += fdNconj; + flt_t fkx = ffactor * rikx; + flt_t fky = ffactor * riky; + flt_t fkz = ffactor * rikz; + result_f[i].x -= fkx; + result_f[i].y -= fky; + result_f[i].z -= fkz; + result_f[k].x += fkx; + result_f[k].y += fky; + result_f[k].z += fkz; + if (ktype != 0 || fabs(dNki) <= TOL) continue; + int * neighs_k = ka->neigh_rebo.entries + ka->neigh_rebo.offset[k]; + int nnum = ka->neigh_rebo.num[k]; + int nn; + for (nn = 0; nn < nnum; nn++) { + int n = neighs_k[nn]; + if (n == i) continue; + flt_t rknx = x[k].x - x[n].x; + flt_t rkny = x[k].y - x[n].y; + flt_t rknz = x[k].z - x[n].z; + flt_t rknmag = overloaded::sqrt(rknx * rknx + rkny * rkny + rknz * rknz); + int ntype = map[x[n].w]; + flt_t rcminkn = ka->params.rcmin[ktype][ntype]; + flt_t rcmaxkn = ka->params.rcmax[ktype][ntype]; + flt_t dwkn; + Sp(rknmag, rcminkn, rcmaxkn, &dwkn); + flt_t ffactor = VA * dNconj * 2 * Nconj * wik * dNki * dwkn / rknmag; + result_f[k].x -= ffactor * rknx; + result_f[k].y -= ffactor * rkny; + result_f[k].z -= ffactor * rknz; + result_f[n].x += ffactor * rknx; + result_f[n].y += ffactor * rkny; + result_f[n].z += ffactor * rknz; + } + } +} + +/* + * This data-structure contains the result of a search through neighbor-lists. + * It is used to calculate C_ij and the corresponding force updates. + */ +template +struct LennardJonesPathAIREBOT { + AtomAIREBOT del[3]; + int num; + flt_t w[3]; + flt_t dw[3]; + flt_t r[3]; + int idx[4]; +}; + +/* + * Checks a candidate path stored in idxs whether it is better than *path + * and updates *path accordingly. + */ +template +inline flt_t ref_lennard_jones_test_path_single( + KernelArgsAIREBOT * ka, flt_t best, int num, int * idxs, + LennardJonesPathAIREBOT * path) { + LennardJonesPathAIREBOT result; + AtomAIREBOT * x = ka->x; + int * map = ka->map; + result.num = num; + flt_t combined = 1; + for (int i = num - 2; i >= 0; i--) { + int a0 = idxs[i+0]; + int a1 = idxs[i+1]; + flt_t delx = x[a1].x - x[a0].x; + flt_t dely = x[a1].y - x[a0].y; + flt_t delz = x[a1].z - x[a0].z; + flt_t rsq = delx * delx + dely * dely + delz * delz; + int type0 = map[x[a0].w]; + int type1 = map[x[a1].w]; + if (rsq >= ka->params.rcmaxsq[type0][type1]) return best; + flt_t r = overloaded::sqrt(rsq); + flt_t dw, w = Sp(r, ka->params.rcmin[type0][type1], + ka->params.rcmax[type0][type1], &dw); + if (w == 0) return best; + combined *= w; + if (combined <= best) return best; + result.idx[i] = a0; + result.del[i].x = delx; + result.del[i].y = dely; + result.del[i].z = delz; + result.r[i] = r; + result.w[i] = w; + result.dw[i] = dw; + } + result.idx[num - 1] = idxs[num - 1]; + *path = result; + return combined; +} + +/* + * Test through all paths surrounding i and j to find the corresponding + * best path. Uses the same iteration ordering as FLJ() does. + * Note that an optimization would use the j neighlist instead in the inner + * loop. + */ +template +inline flt_t ref_lennard_jones_test_path(KernelArgsAIREBOT * ka, + int i, int j, flt_t rij, flt_t rcmax, + LennardJonesPathAIREBOT * path) { + int idxs[4]; + idxs[0] = i; + idxs[1] = j; + flt_t best = 0; + if (rij <= rcmax) { + best = ref_lennard_jones_test_path_single(ka, best, 2, idxs, path); + if (best == static_cast(1.0)) return 0; + } + for (int kk = 0; kk < ka->neigh_rebo.num[i]; kk++) { + int k = ka->neigh_rebo.entries[ka->neigh_rebo.offset[i] + kk]; + if (k == j) continue; + idxs[1] = k; + idxs[2] = j; + best = ref_lennard_jones_test_path_single(ka, best, 3, idxs, path); + if (best == static_cast(1.0)) return 0; + for (int mm = 0; mm < ka->neigh_rebo.num[k]; mm++) { + int m = ka->neigh_rebo.entries[ka->neigh_rebo.offset[k] + mm]; + if (m == i || m == j) continue; + idxs[2] = m; + idxs[3] = j; + best = ref_lennard_jones_test_path_single(ka, best, 4, idxs, path); + if (best == static_cast(1.0)) return 0; + } + } + return 1 - best; +} + +/* + * Conducts the force update due to C_ij, given the active path. + */ +template +inline void ref_lennard_jones_force_path(KernelArgsAIREBOT * ka, + flt_t dC, LennardJonesPathAIREBOT * path) { + AtomAIREBOT * x = ka->x; + ResultForceT * result_f = ka->result_f; + for (int i = 0; i < path->num - 1; i++) { + flt_t fpair = dC * path->dw[i] / path->r[i]; + for (int j = 0; j < path->num - 1; j++) { + if (i != j) fpair *= path->w[j]; + } + result_f[path->idx[i+0]].x -= fpair * path->del[i].x; + result_f[path->idx[i+0]].y -= fpair * path->del[i].y; + result_f[path->idx[i+0]].z -= fpair * path->del[i].z; + result_f[path->idx[i+1]].x += fpair * path->del[i].x; + result_f[path->idx[i+1]].y += fpair * path->del[i].y; + result_f[path->idx[i+1]].z += fpair * path->del[i].z; + } +} + +/* + * Calculate the bondorderLJ term. + */ +template +inline flt_t ref_lennard_jones_bondorder(KernelArgsAIREBOT * ka, + int i, int j, flt_t VA, acc_t fij[3]) { + AtomAIREBOT * x = ka->x; + int * map = ka->map; + ResultForceT * result_f = ka->result_f; + + int itype = map[x[i].w]; + int jtype = map[x[j].w]; + + flt_t delx = x[i].x - x[j].x; + flt_t dely = x[i].y - x[j].y; + flt_t delz = x[i].z - x[j].z; + flt_t rsq = delx * delx + dely * dely + delz * delz; + flt_t rij = overloaded::sqrt(rsq); + + flt_t rcminij = ka->params.rcmin[itype][jtype]; + flt_t rcmaxij = ka->params.rcmax[itype][jtype]; + flt_t dwij; + flt_t wij = Sp(rij, rcminij, rcmaxij, &dwij); + + flt_t the_r = ka->params.rcmin[itype][jtype]; + flt_t scale = the_r / rij; + flt_t Nij = ka->nH[i] + ka->nC[i] - wij; + flt_t Nji = ka->nH[j] + ka->nC[j] - wij; + flt_t NconjtmpI; + acc_t fijc[3] = {0}, fjic[3] = {0}; + flt_t pij = frebo_pij(ka, i, j, delx * scale, dely * scale, + delz * scale, the_r, wij, 0.0, &NconjtmpI, fijc); + flt_t NconjtmpJ; + flt_t pji = frebo_pij(ka, j, i, -delx * scale, -dely * scale, + -delz * scale, the_r, wij, 0.0, &NconjtmpJ, fjic); + flt_t Nijconj = 1.0 + (NconjtmpI * NconjtmpI) + (NconjtmpJ * NconjtmpJ); + flt_t dN3_pi_rc[3]; + flt_t pi_rc = frebo_pi_rc(ka, itype, jtype, Nij, Nji, Nijconj, + dN3_pi_rc); + flt_t dN3_Tij[3]; + flt_t Tij = frebo_Tij(ka, itype, jtype, Nij, Nji, Nijconj, + dN3_Tij); + flt_t sum_omega = 0; + if (fabs(Tij) > TOL) { + sum_omega = frebo_sum_omega(ka, i, j, delx * scale, dely * + scale, delz * scale, the_r, 0.0, + fijc); + } + flt_t pi_dh = Tij * sum_omega; + flt_t bij = 0.5 * (pij + pji) + pi_rc + pi_dh; + flt_t dStb; + flt_t Stb = Sp2(bij, ka->params.bLJmin[itype][jtype], + ka->params.bLJmax[itype][jtype], &dStb); + if (dStb != 0) { + flt_t pij_reverse = frebo_pij(ka, i, j, delx * scale, + dely * scale, delz * scale, the_r, wij, VA * dStb, &NconjtmpI, fijc); + flt_t pji_reverse = frebo_pij(ka, j, i, -delx * scale, + -dely * scale, -delz * scale, the_r, wij, VA * dStb, &NconjtmpJ, fjic); + fijc[0] -= fjic[0]; + fijc[1] -= fjic[1]; + fijc[2] -= fjic[2]; + frebo_N_spline_force(ka, i, j, VA * dStb, dN3_pi_rc[0], + dN3_pi_rc[2], NconjtmpI); + frebo_N_spline_force(ka, j, i, VA * dStb, dN3_pi_rc[1], + dN3_pi_rc[2], NconjtmpJ); + if (fabs(Tij) > TOL) { + flt_t sum_omega_reverse = frebo_sum_omega(ka, i, j, + delx * scale, dely * scale, delz * scale, the_r, VA * dStb * Tij, fijc); + frebo_N_spline_force(ka, i, j, VA * dStb * sum_omega, dN3_Tij[0], + dN3_Tij[2], NconjtmpI); + frebo_N_spline_force(ka, j, i, VA * dStb * sum_omega, dN3_Tij[1], + dN3_Tij[2], NconjtmpJ); + } + assert(fij[0] == 0); + assert(fij[1] == 0); + assert(fij[2] == 0); + fij[0] = scale * (fijc[0] - (delx * delx * fijc[0] + dely * delx * + fijc[1] + delz * delx * fijc[2]) / rsq); + fij[1] = scale * (fijc[1] - (delx * dely * fijc[0] + dely * dely * + fijc[1] + delz * dely * fijc[2]) / rsq); + fij[2] = scale * (fijc[2] - (delx * delz * fijc[0] + dely * delz * + fijc[1] + delz * delz * fijc[2]) / rsq); + } + return Stb; +} + +/* + * Scalar reference implementation of neighbor routine. + */ +template +void ref_rebo_neigh(KernelArgsAIREBOT * ka) { + int offset = ka->neigh_from_atom * ka->num_neighs_per_atom; + for (int i = ka->neigh_from_atom; i < ka->neigh_to_atom; i++) { + ka->neigh_rebo.offset[i] = offset; + int itype = ka->map[ka->x[i].w]; + int n = 0; + ka->nC[i] = 0; + ka->nH[i] = 0; + for (int j = 0; j < ka->neigh_lmp.num[i]; j++) { + int ji = ka->neigh_lmp.entries[ka->neigh_lmp.offset[i] + j]; + flt_t delx = ka->x[i].x - ka->x[ji].x; + flt_t dely = ka->x[i].y - ka->x[ji].y; + flt_t delz = ka->x[i].z - ka->x[ji].z; + flt_t rsq = delx * delx + dely * dely + delz * delz; + int jtype = ka->map[ka->x[ji].w]; + if (rsq < ka->params.rcmaxsq[itype][jtype]) { + ka->neigh_rebo.entries[offset + n++] = ji; + flt_t rcmin = ka->params.rcmin[itype][jtype]; + flt_t rcmax = ka->params.rcmax[itype][jtype]; + if (jtype == CARBON) + ka->nC[i] += Sp(overloaded::sqrt(rsq), rcmin, rcmax, NULL); + else + ka->nH[i] += Sp(overloaded::sqrt(rsq), rcmin, rcmax, NULL); + } + } + ka->neigh_rebo.num[i] = n; + offset += n; + } +} + +template +void ref_torsion_single_interaction(KernelArgsAIREBOT * ka, int i, + int j) { + AtomAIREBOT * x = ka->x; + int * map = ka->map; + ResultForceT * f = ka->result_f; + flt_t (*rcmin)[2] = ka->params.rcmin; + flt_t (*rcmax)[2] = ka->params.rcmax; + flt_t (*epsilonT)[2] = ka->params.epsilonT; + flt_t thmin = ka->params.thmin; + flt_t thmax = ka->params.thmax; + int itype = map[x[i].w]; + flt_t xtmp = x[i].x; + flt_t ytmp = x[i].y; + flt_t ztmp = x[i].z; + int * REBO_neighs_i = &ka->neigh_rebo.entries[ka->neigh_rebo.offset[i]]; + int jnum = ka->neigh_rebo.num[i]; + int jtype = map[x[j].w]; + + flt_t del32x = x[j].x-x[i].x; + flt_t del32y = x[j].y-x[i].y; + flt_t del32z = x[j].z-x[i].z; + flt_t rsq = del32x*del32x + del32y*del32y + del32z*del32z; + flt_t r32 = overloaded::sqrt(rsq); + flt_t del23x = -del32x; + flt_t del23y = -del32y; + flt_t del23z = -del32z; + flt_t r23 = r32; + flt_t dw23, w23 = Sp(r23,rcmin[itype][jtype],rcmax[itype][jtype], + &dw23); + + assert(itype == 0); + assert(jtype == 0); + + for (int kk = 0; kk < jnum; kk++) { + int k = REBO_neighs_i[kk]; + int ktype = map[x[k].w]; + if (k == j) continue; + flt_t del21x = x[i].x-x[k].x; + flt_t del21y = x[i].y-x[k].y; + flt_t del21z = x[i].z-x[k].z; + flt_t rsq = del21x*del21x + del21y*del21y + del21z*del21z; + flt_t r21 = overloaded::sqrt(rsq); + flt_t cos321 = - ((del21x*del32x) + (del21y*del32y) + + (del21z*del32z)) / (r21*r32); + cos321 = fmin(cos321,1); + cos321 = fmax(cos321,-1); + flt_t sin321 = overloaded::sqrt(1 - cos321*cos321); + if (sin321 < TOL) continue; + + flt_t deljkx = del21x-del23x; + flt_t deljky = del21y-del23y; + flt_t deljkz = del21z-del23z; + flt_t rjk2 = deljkx*deljkx + deljky*deljky + deljkz*deljkz; + flt_t rjk = overloaded::sqrt(rjk2); + flt_t rik2 = r21*r21; + flt_t dw21, w21 = Sp(r21,rcmin[itype][ktype],rcmax[itype][ktype], + &dw21); + + flt_t rij = r32; + flt_t rik = r21; + flt_t rij2 = r32*r32; + flt_t costmp = static_cast(0.5)*(rij2+rik2-rjk2)/rij/rik; + flt_t dtsjik, tspjik = Sp2(costmp,thmin,thmax,&dtsjik); + dtsjik = -dtsjik; + + int * REBO_neighs_j = &ka->neigh_rebo.entries[ka->neigh_rebo.offset[j]]; + int lnum = ka->neigh_rebo.num[j]; + for (int ll = 0; ll < lnum; ll++) { + int l = REBO_neighs_j[ll]; + int ltype = map[x[l].w]; + if (l == i || l == k) continue; + flt_t del34x = x[j].x-x[l].x; + flt_t del34y = x[j].y-x[l].y; + flt_t del34z = x[j].z-x[l].z; + flt_t rsq = del34x*del34x + del34y*del34y + del34z*del34z; + flt_t r34 = overloaded::sqrt(rsq); + flt_t cos234 = (del32x*del34x + del32y*del34y + + del32z*del34z) / (r32*r34); + cos234 = fmin(cos234,1); + cos234 = fmax(cos234,-1); + flt_t sin234 = overloaded::sqrt(1 - cos234*cos234); + if (sin234 < TOL) continue; + flt_t dw34, w34 = Sp(r34,rcmin[jtype][ltype],rcmax[jtype][ltype], + &dw34); + flt_t delilx = del23x + del34x; + flt_t delily = del23y + del34y; + flt_t delilz = del23z + del34z; + flt_t ril2 = delilx*delilx + delily*delily + delilz*delilz; + flt_t ril = overloaded::sqrt(ril2); + flt_t rjl2 = r34*r34; + + flt_t rjl = r34; + flt_t costmp = static_cast(0.5)*(rij2+rjl2-ril2)/rij/rjl; + flt_t dtsijl, tspijl = Sp2(costmp,thmin,thmax,&dtsijl); + dtsijl = -dtsijl; //need minus sign + flt_t cross321x = (del32y*del21z)-(del32z*del21y); + flt_t cross321y = (del32z*del21x)-(del32x*del21z); + flt_t cross321z = (del32x*del21y)-(del32y*del21x); + flt_t cross321mag = overloaded::sqrt(cross321x*cross321x+ + cross321y*cross321y + cross321z*cross321z); + flt_t cross234x = (del23y*del34z)-(del23z*del34y); + flt_t cross234y = (del23z*del34x)-(del23x*del34z); + flt_t cross234z = (del23x*del34y)-(del23y*del34x); + flt_t cross234mag = overloaded::sqrt(cross234x*cross234x+ + cross234y*cross234y + cross234z*cross234z); + flt_t cwnum = (cross321x*cross234x) + + (cross321y*cross234y)+(cross321z*cross234z); + flt_t cwnom = r21*r34*r32*r32*sin321*sin234; + flt_t cw = cwnum/cwnom; + + flt_t cw2 = (static_cast(.5)*(1-cw)); + flt_t ekijl = epsilonT[ktype][ltype]; + flt_t Ec = 256*ekijl/405; + flt_t Vtors = (Ec*(overloaded::pow(cw2,5)))-(ekijl/10); + + ka->result_eng += Vtors*w21*w23*w34*(1-tspjik)*(1-tspijl); + + flt_t dndijx = (cross234y*del21z)-(cross234z*del21y); + flt_t dndijy = (cross234z*del21x)-(cross234x*del21z); + flt_t dndijz = (cross234x*del21y)-(cross234y*del21x); + + flt_t tmpvecx = (del34y*cross321z)-(del34z*cross321y); + flt_t tmpvecy = (del34z*cross321x)-(del34x*cross321z); + flt_t tmpvecz = (del34x*cross321y)-(del34y*cross321x); + + dndijx = dndijx+tmpvecx; + dndijy = dndijy+tmpvecy; + dndijz = dndijz+tmpvecz; + + flt_t dndikx = (del23y*cross234z)-(del23z*cross234y); + flt_t dndiky = (del23z*cross234x)-(del23x*cross234z); + flt_t dndikz = (del23x*cross234y)-(del23y*cross234x); + + flt_t dndjlx = (cross321y*del23z)-(cross321z*del23y); + flt_t dndjly = (cross321z*del23x)-(cross321x*del23z); + flt_t dndjlz = (cross321x*del23y)-(cross321y*del23x); + + flt_t dcidij = ((r23*r23)-(r21*r21)+(rjk*rjk))/(2*r23*r23*r21); + flt_t dcidik = ((r21*r21)-(r23*r23)+(rjk*rjk))/(2*r23*r21*r21); + flt_t dcidjk = (-rjk)/(r23*r21); + flt_t dcjdji = ((r23*r23)-(r34*r34)+(ril*ril))/(2*r23*r23*r34); + flt_t dcjdjl = ((r34*r34)-(r23*r23)+(ril*ril))/(2*r23*r34*r34); + flt_t dcjdil = (-ril)/(r23*r34); + + flt_t dsidij = (-cos321/sin321)*dcidij; + flt_t dsidik = (-cos321/sin321)*dcidik; + flt_t dsidjk = (-cos321/sin321)*dcidjk; + + flt_t dsjdji = (-cos234/sin234)*dcjdji; + flt_t dsjdjl = (-cos234/sin234)*dcjdjl; + flt_t dsjdil = (-cos234/sin234)*dcjdil; + + flt_t dxidij = (r21*sin321)+(r23*r21*dsidij); + flt_t dxidik = (r23*sin321)+(r23*r21*dsidik); + flt_t dxidjk = (r23*r21*dsidjk); + + flt_t dxjdji = (r34*sin234)+(r23*r34*dsjdji); + flt_t dxjdjl = (r23*sin234)+(r23*r34*dsjdjl); + flt_t dxjdil = (r23*r34*dsjdil); + + flt_t ddndij = (dxidij*cross234mag)+(cross321mag*dxjdji); + flt_t ddndik = dxidik*cross234mag; + flt_t ddndjk = dxidjk*cross234mag; + flt_t ddndjl = cross321mag*dxjdjl; + flt_t ddndil = cross321mag*dxjdil; + flt_t dcwddn = -cwnum/(cwnom*cwnom); + flt_t dcwdn = 1/cwnom; + flt_t dvpdcw = (-1)*Ec*static_cast(-0.5)*5*overloaded::pow(cw2,4)* + w23*w21*w34*(1-tspjik)*(1-tspijl); + + flt_t Ftmpx = dvpdcw*((dcwdn*dndijx)+(dcwddn*ddndij*del23x/r23)); + flt_t Ftmpy = dvpdcw*((dcwdn*dndijy)+(dcwddn*ddndij*del23y/r23)); + flt_t Ftmpz = dvpdcw*((dcwdn*dndijz)+(dcwddn*ddndij*del23z/r23)); + flt_t fix = Ftmpx; + flt_t fiy = Ftmpy; + flt_t fiz = Ftmpz; + flt_t fjx = -Ftmpx; + flt_t fjy = -Ftmpy; + flt_t fjz = -Ftmpz; + + Ftmpx = dvpdcw*((dcwdn*dndikx)+(dcwddn*ddndik*del21x/r21)); + Ftmpy = dvpdcw*((dcwdn*dndiky)+(dcwddn*ddndik*del21y/r21)); + Ftmpz = dvpdcw*((dcwdn*dndikz)+(dcwddn*ddndik*del21z/r21)); + fix += Ftmpx; + fiy += Ftmpy; + fiz += Ftmpz; + flt_t fkx = -Ftmpx; + flt_t fky = -Ftmpy; + flt_t fkz = -Ftmpz; + + Ftmpx = (dvpdcw*dcwddn*ddndjk*deljkx)/rjk; + Ftmpy = (dvpdcw*dcwddn*ddndjk*deljky)/rjk; + Ftmpz = (dvpdcw*dcwddn*ddndjk*deljkz)/rjk; + fjx += Ftmpx; + fjy += Ftmpy; + fjz += Ftmpz; + fkx -= Ftmpx; + fky -= Ftmpy; + fkz -= Ftmpz; + + Ftmpx = dvpdcw*((dcwdn*dndjlx)+(dcwddn*ddndjl*del34x/r34)); + Ftmpy = dvpdcw*((dcwdn*dndjly)+(dcwddn*ddndjl*del34y/r34)); + Ftmpz = dvpdcw*((dcwdn*dndjlz)+(dcwddn*ddndjl*del34z/r34)); + fjx += Ftmpx; + fjy += Ftmpy; + fjz += Ftmpz; + flt_t flx = -Ftmpx; + flt_t fly = -Ftmpy; + flt_t flz = -Ftmpz; + + Ftmpx = (dvpdcw*dcwddn*ddndil*delilx)/ril; + Ftmpy = (dvpdcw*dcwddn*ddndil*delily)/ril; + Ftmpz = (dvpdcw*dcwddn*ddndil*delilz)/ril; + fix += Ftmpx; + fiy += Ftmpy; + fiz += Ftmpz; + flx -= Ftmpx; + fly -= Ftmpy; + flz -= Ftmpz; + + // coordination forces + + flt_t fpair = Vtors*dw21*w23*w34*(1-tspjik)*(1-tspijl) / r21; + fix -= del21x*fpair; + fiy -= del21y*fpair; + fiz -= del21z*fpair; + fkx += del21x*fpair; + fky += del21y*fpair; + fkz += del21z*fpair; + + fpair = Vtors*w21*dw23*w34*(1-tspjik)*(1-tspijl) / r23; + fix -= del23x*fpair; + fiy -= del23y*fpair; + fiz -= del23z*fpair; + fjx += del23x*fpair; + fjy += del23y*fpair; + fjz += del23z*fpair; + + fpair = Vtors*w21*w23*dw34*(1-tspjik)*(1-tspijl) / r34; + fjx -= del34x*fpair; + fjy -= del34y*fpair; + fjz -= del34z*fpair; + flx += del34x*fpair; + fly += del34y*fpair; + flz += del34z*fpair; + + // additional cut off function forces + + flt_t fcpc = -Vtors*w21*w23*w34*dtsjik*(1-tspijl); + fpair = fcpc*dcidij/rij; + fix += fpair*del23x; + fiy += fpair*del23y; + fiz += fpair*del23z; + fjx -= fpair*del23x; + fjy -= fpair*del23y; + fjz -= fpair*del23z; + + fpair = fcpc*dcidik/rik; + fix += fpair*del21x; + fiy += fpair*del21y; + fiz += fpair*del21z; + fkx -= fpair*del21x; + fky -= fpair*del21y; + fkz -= fpair*del21z; + + fpair = fcpc*dcidjk/rjk; + fjx += fpair*deljkx; + fjy += fpair*deljky; + fjz += fpair*deljkz; + fkx -= fpair*deljkx; + fky -= fpair*deljky; + fkz -= fpair*deljkz; + + fcpc = -Vtors*w21*w23*w34*(1-tspjik)*dtsijl; + fpair = fcpc*dcjdji/rij; + fix += fpair*del23x; + fiy += fpair*del23y; + fiz += fpair*del23z; + fjx -= fpair*del23x; + fjy -= fpair*del23y; + fjz -= fpair*del23z; + + fpair = fcpc*dcjdjl/rjl; + fjx += fpair*del34x; + fjy += fpair*del34y; + fjz += fpair*del34z; + flx -= fpair*del34x; + fly -= fpair*del34y; + flz -= fpair*del34z; + + fpair = fcpc*dcjdil/ril; + fix += fpair*delilx; + fiy += fpair*delily; + fiz += fpair*delilz; + flx -= fpair*delilx; + fly -= fpair*delily; + flz -= fpair*delilz; + + // sum per-atom forces into atom force array + + f[i].x += fix; f[i].y += fiy; f[i].z += fiz; + f[j].x += fjx; f[j].y += fjy; f[j].z += fjz; + f[k].x += fkx; f[k].y += fky; f[k].z += fkz; + f[l].x += flx; f[l].y += fly; f[l].z += flz; + } + } +} + +template +void ref_torsion(KernelArgsAIREBOT * ka) { + AtomAIREBOT * x = ka->x; + int * map = ka->map; + int * tag = ka->tag; + for (int ii = ka->frebo_from_atom; ii < ka->frebo_to_atom; ii++) { + int i = ii; + int itag = tag[i]; + int itype = map[x[i].w]; + if (itype != 0) continue; + flt_t xtmp = x[i].x; + flt_t ytmp = x[i].y; + flt_t ztmp = x[i].z; + int * REBO_neighs_i = &ka->neigh_rebo.entries[ka->neigh_rebo.offset[i]]; + int jnum = ka->neigh_rebo.num[i]; + for (int jj = 0; jj < jnum; jj++) { + int j = REBO_neighs_i[jj]; + int jtag = tag[j]; + + if (itag > jtag) { + if (((itag+jtag) & 1) == 0) continue; + } else if (itag < jtag) { + if (((itag+jtag) & 1) == 1) continue; + } else { + if (x[j].z < ztmp) continue; + if (x[j].z == ztmp && x[j].y < ytmp) continue; + if (x[j].z == ztmp && x[j].y == ytmp && x[j].x < xtmp) continue; + } + + int jtype = map[x[j].w]; + if (jtype != 0) continue; + ref_torsion_single_interaction(ka, i, j); + } + } +} + +/* + * Calculate single REBO interaction. + * Corresponds to FREBO method. Note that the bondorder() function is + * inlined. + */ +template +void ref_frebo_single_interaction(KernelArgsAIREBOT * ka, int i, + int j) { + AtomAIREBOT * x = ka->x; + int * map = ka->map; + ResultForceT * result_f = ka->result_f; + int jj; + int itype = map[x[i].w]; + flt_t x_i = x[i].x; + flt_t y_i = x[i].y; + flt_t z_i = x[i].z; + int jtype = map[x[j].w]; + flt_t delx = x[i].x - x[j].x; + flt_t dely = x[i].y - x[j].y; + flt_t delz = x[i].z - x[j].z; + flt_t rsq = delx * delx + dely * dely + delz * delz; + flt_t rij = overloaded::sqrt(rsq); + flt_t rcminij = ka->params.rcmin[itype][jtype]; + flt_t rcmaxij = ka->params.rcmax[itype][jtype]; + flt_t dwij; + flt_t wij = Sp(rij, rcminij, rcmaxij, &dwij); + if (wij <= TOL) return; + + flt_t Qij = ka->params.Q[itype][jtype]; + flt_t Aij = ka->params.A[itype][jtype]; + flt_t alphaij = ka->params.alpha[itype][jtype]; + + flt_t exp_alphar = exp(-alphaij * rij); + flt_t VR_by_wij = (1.0 + (Qij / rij)) * Aij * exp_alphar; + flt_t VR = wij * VR_by_wij; + flt_t pre = wij * Aij * exp_alphar; + flt_t dVRdi = pre * ((-alphaij) - (Qij / rsq) - (Qij * alphaij / rij)); + dVRdi += VR_by_wij * dwij; + + flt_t VA_by_wij = 0, dVA = 0; + for (int k = 0; k < 3; k++) { + flt_t BIJc = ka->params.BIJc[itype][jtype][k]; + flt_t Betaij = ka->params.Beta[itype][jtype][k]; + flt_t term = -BIJc * overloaded::exp(-Betaij * rij); + VA_by_wij += term; + dVA += -Betaij * wij * term; + } + dVA += VA_by_wij * dwij; + flt_t VA = VA_by_wij * wij; + + acc_t fij[3] = {0}; + flt_t Nij = ka->nH[i] + ka->nC[i] - wij; + flt_t Nji = ka->nH[j] + ka->nC[j] - wij; + flt_t NconjtmpI; + flt_t pij = frebo_pij(ka, i, j, delx, dely, delz, rij, wij, VA, &NconjtmpI, + fij); + flt_t NconjtmpJ; + acc_t fji[3] = {0}; + flt_t pji = frebo_pij(ka, j, i, -delx, -dely, -delz, rij, wij, VA, + &NconjtmpJ, fji); + fij[0] -= fji[0]; fij[1] -= fji[1]; fij[2] -= fji[2]; + flt_t Nijconj = 1.0 + (NconjtmpI * NconjtmpI) + (NconjtmpJ * NconjtmpJ); + flt_t dN3[3]; + flt_t pi_rc = frebo_pi_rc(ka, itype, jtype, Nij, Nji, Nijconj, dN3); + frebo_N_spline_force(ka, i, j, VA, dN3[0], dN3[2], NconjtmpI); + frebo_N_spline_force(ka, j, i, VA, dN3[1], dN3[2], NconjtmpJ); + flt_t Tij = frebo_Tij(ka, itype, jtype, Nij, Nji, Nijconj, dN3); + flt_t sum_omega = 0.0; + if (fabs(Tij) > TOL) { + sum_omega = frebo_sum_omega(ka, i, j, delx, dely, delz, rij, VA * Tij, fij); + frebo_N_spline_force(ka, i, j, VA * sum_omega, dN3[0], dN3[2], NconjtmpI); + frebo_N_spline_force(ka, j, i, VA * sum_omega, dN3[1], dN3[2], NconjtmpJ); + } + flt_t pi_dh = Tij * sum_omega; + flt_t bij = static_cast(0.5) * (pij + pji) + pi_rc + pi_dh; + flt_t dVAdi = bij * dVA; + flt_t fpair = -(dVRdi + dVAdi) / rij; + + result_f[i].x += fpair * delx + fij[0]; + result_f[i].y += fpair * dely + fij[1]; + result_f[i].z += fpair * delz + fij[2]; + result_f[j].x -= fpair * delx + fij[0]; + result_f[j].y -= fpair * dely + fij[1]; + result_f[j].z -= fpair * delz + fij[2]; + + flt_t evdwl = VR + bij * VA; + ka->result_eng += evdwl; + result_f[i].w += 0.5 * evdwl; + result_f[j].w += 0.5 * evdwl; +} + + +template +inline void ref_frebo_single_atom(KernelArgsAIREBOT * ka, int i) { + AtomAIREBOT * x = ka->x; + int * tag = ka->tag; + int jj; + int itag = tag[i]; + flt_t x_i = x[i].x; + flt_t y_i = x[i].y; + flt_t z_i = x[i].z; + int * neighs = ka->neigh_rebo.entries + ka->neigh_rebo.offset[i]; + int jnum = ka->neigh_rebo.num[i]; + for (jj = 0; jj < jnum; jj++) { + int j = neighs[jj]; + int jtag = tag[j]; + if (itag > jtag) { + if (((itag + jtag) & 1) == 0) + continue; + } else if (itag < jtag) { + if (((itag + jtag) & 1) == 1) + continue; + } else { + if (x[j].z < z_i) + continue; + if (x[j].z == z_i && x[j].y < y_i) + continue; + if (x[j].z == z_i && x[j].y == y_i && x[j].x < x_i) + continue; + } + ref_frebo_single_interaction(ka, i, j); + } +} + + +template +void ref_frebo(KernelArgsAIREBOT * ka, int torflag) { + for (int i = ka->frebo_from_atom; i < ka->frebo_to_atom; i++) { + ref_frebo_single_atom(ka, i); + } + if (torflag) ref_torsion(ka); +} + +template +void ref_lennard_jones_single_interaction(KernelArgsAIREBOT * ka, + int i, int j, int morseflag) { + AtomAIREBOT * x = ka->x; + int * map = ka->map; + ResultForceT * result_f = ka->result_f; + + int itype = map[x[i].w]; + int jtype = map[x[j].w]; + + flt_t delx = x[i].x - x[j].x; + flt_t dely = x[i].y - x[j].y; + flt_t delz = x[i].z - x[j].z; + flt_t rsq = delx * delx + dely * dely + delz * delz; + + if (rsq >= ka->params.cutljsq[itype][jtype]) { return; } + flt_t rij = overloaded::sqrt(rsq); + + LennardJonesPathAIREBOT testpath; + flt_t cij = 1.0; + if (rij < ka->params.cut3rebo) { + #pragma noinline + cij = ref_lennard_jones_test_path(ka, i, j, rij, + ka->params.rcmax[itype][jtype], &testpath); + } + if (cij == 0) { + return; + } + + flt_t sigcut = ka->params.sigcut; + flt_t sigmin = ka->params.sigmin; + flt_t sigma = ka->params.sigma[itype][jtype]; + flt_t rljmax = sigcut * sigma; + flt_t rljmin = sigmin * sigma; + + flt_t dslw, slw = Sp2(rij, rljmin, rljmax, &dslw); + + flt_t vdw, dvdw; + if (morseflag) { + const flt_t exr = exp(-rij * ka->params.lj4[itype][jtype]); + vdw = ka->params.lj1[itype][jtype] * exr * + (ka->params.lj2[itype][jtype]*exr - 2); + dvdw = ka->params.lj3[itype][jtype] * exr * + (1 - ka->params.lj2[itype][jtype]*exr); + } else { + flt_t r2inv = 1 / rsq; + flt_t r6inv = r2inv * r2inv * r2inv; + + vdw = r6inv * (ka->params.lj3[itype][jtype]*r6inv - + ka->params.lj4[itype][jtype]); + dvdw = -r6inv * (ka->params.lj1[itype][jtype]*r6inv - + ka->params.lj2[itype][jtype]) / rij; + } + + flt_t VLJ = vdw * slw; + flt_t dVLJ = dvdw * slw + vdw * dslw; + + flt_t dStr, Str = Sp2(rij, ka->params.rcLJmin[itype][jtype], + ka->params.rcLJmax[itype][jtype], &dStr); + flt_t VA = Str * cij * VLJ; + flt_t Stb = 0; + acc_t fij[3] = {0}; + if (Str > 0) { + #pragma noinline + Stb = ref_lennard_jones_bondorder(ka, i, j, VA, fij); + } + flt_t fpair = -(dStr * (Stb * cij * VLJ - cij * VLJ) + + dVLJ * (Str * Stb * cij + cij - Str * cij)) / rij; + flt_t evdwl = VA * Stb + (1 - Str) * cij * VLJ; + result_f[i].x += fpair * delx + fij[0]; + result_f[i].y += fpair * dely + fij[1]; + result_f[i].z += fpair * delz + fij[2]; + result_f[j].x -= fpair * delx + fij[0]; + result_f[j].y -= fpair * dely + fij[1]; + result_f[j].z -= fpair * delz + fij[2]; + ka->result_eng += evdwl; + + if (cij < 1) { + #pragma noinline + ref_lennard_jones_force_path(ka, Str * Stb * VLJ + (1 - Str) * VLJ, + &testpath); + } +} + +template +void ref_lennard_jones_single_atom(KernelArgsAIREBOT * ka, int i, + int morseflag) { + AtomAIREBOT * x = ka->x; + int * tag = ka->tag; + int jj; + int itag = tag[i]; + int * neighs = ka->neigh_lmp.entries + ka->neigh_lmp.offset[i]; + int jnum = ka->neigh_lmp.num_half[i]; + for (jj = 0; jj < jnum; jj++) { + int j = neighs[jj]; + ref_lennard_jones_single_interaction(ka, i, j, morseflag); + } +} + +template +void ref_lennard_jones(KernelArgsAIREBOT * ka, int morseflag) { + for (int i = ka->frebo_from_atom; i < ka->frebo_to_atom; i++) { + #pragma noinline + ref_lennard_jones_single_atom(ka, i, morseflag); + } +} + +/* ---------------------------------------------------------------------- + Vectorized AIREBO implementation, standalone, using caching to reduce + memory access. + ---------------------------------------------------------------------- */ + +template +struct aut_wrap { + +typedef typename intr_types::fvec fvec; +typedef typename intr_types::avec avec; +typedef typename intr_types::ivec ivec; +typedef typename intr_types::bvec bvec; + +VEC_INLINE inline +static void aut_loadatoms_vec( + AtomAIREBOT * atoms, ivec j_vec, + fvec *x, fvec * y, fvec * z, bvec * type_mask, int * map, ivec map_i, + ivec c_1 +) { + const ivec c_4 = ivec::set1(4); + ivec j_vec_4 = ivec::mullo(c_4, j_vec); + fvec w; + fvec::gather_4_adjacent(j_vec_4, &atoms[0].x, sizeof(flt_t), x, y, z, &w); + ivec jtype = fvec::unpackloepi32(w); + jtype = ivec::srlv(map_i, jtype); //_mm512_castpd_si512(w)); + jtype = ivec::the_and(c_1, jtype); + bvec jtype_mask = ivec::cmpneq(jtype, ivec::setzero()); + *type_mask = jtype_mask; +} + +VEC_INLINE inline +static void aut_loadatoms_vec_notype( + AtomAIREBOT * atoms, ivec j_vec, + fvec *x, fvec * y, fvec * z +) { + const ivec c_4 = ivec::set1(4); + ivec j_vec_4 = ivec::mullo(c_4, j_vec); + fvec::gather_3_adjacent(j_vec_4, &atoms[0].x, sizeof(flt_t), x, y, z); +} + +static fvec aut_Sp2_deriv(fvec r, fvec lo, fvec hi, fvec * d) { + fvec c_1 = fvec::set1(1); + fvec c_2 = fvec::set1(2); + fvec c_3 = fvec::set1(3); + fvec c_6 = fvec::set1(6); + bvec m_lo = fvec::cmple(r, lo); + bvec m_hi = fvec::cmpnlt(r, hi); // nlt == ge + bvec m_tr = bvec::kandn(m_lo, ~ m_hi); + fvec ret = c_1; + ret = fvec::mask_blend(m_hi, ret, fvec::setzero()); + fvec der = fvec::setzero(); + if (bvec::test_any_set(m_tr)) { + fvec diff = hi - lo; + fvec rcp = fvec::recip(diff); + fvec t = (r - lo) * rcp; + fvec v = c_1 - t * t * ( c_3 - c_2 * t); + ret = fvec::mask_blend(m_tr, ret, v); + fvec dv = c_6 * rcp * ( t * t - t); + der = fvec::mask_blend(m_tr, der, dv); + } + *d = der; + return ret; +} + +static fvec aut_Sp_deriv(fvec r, fvec lo, fvec hi, fvec * d) { + fvec c_1 = fvec::set1(1); + fvec c_0_5 = fvec::set1(0.5); + fvec c_m0_5 = fvec::set1(-0.5); + fvec c_PI = fvec::set1(M_PI); + bvec m_lo = fvec::cmple(r, lo); + bvec m_hi = fvec::cmpnlt(r, hi); // nlt == ge + bvec m_tr = bvec::kandn(m_lo, ~ m_hi); + fvec ret = c_1; + ret = fvec::mask_blend(m_hi, ret, fvec::setzero()); + fvec der = fvec::setzero(); + if (bvec::test_any_set(m_tr)) { + fvec diff = hi - lo; + fvec rcp = fvec::mask_recip(c_1, m_tr, diff); + fvec t = (r - lo) / diff; + fvec sinval, cosval; + sinval = fvec::mask_sincos(&cosval, fvec::setzero(), c_1, m_tr, c_PI * t); + fvec v = c_0_5 * ( c_1 + cosval); + ret = fvec::mask_blend(m_tr, ret, v); + fvec dv = c_PI * c_m0_5 * rcp * sinval; + der = fvec::mask_blend(m_tr, der, dv); + } + *d = der; + return ret; +} + +static fvec aut_mask_Sp(bvec mask, fvec r, fvec lo, fvec hi) { + fvec c_1 = fvec::set1(1); + fvec c_0_5 = fvec::set1(0.5); + fvec c_PI = fvec::set1(M_PI); + bvec m_lo = fvec::mask_cmple(mask, r, lo); + bvec m_hi = fvec::mask_cmpnlt(mask, r, hi); // nlt == ge + bvec m_tr = bvec::kandn(m_lo, bvec::kandn(m_hi, mask)); + fvec ret = c_1; + ret = fvec::mask_blend(m_hi, ret, fvec::setzero()); + if (bvec::test_any_set(m_tr)) { + fvec rcp = fvec::mask_recip(c_1, m_tr, hi - lo); + fvec t = (r - lo) * rcp; + fvec v = c_0_5 * ( c_1 + fvec::mask_cos(c_1, m_tr, c_PI * t)); + ret = fvec::mask_blend(m_tr, ret, v); + } + return ret; +} + +static void aut_rebo_neigh(KernelArgsAIREBOT * ka) { + int offset = ka->neigh_from_atom * ka->num_neighs_per_atom; + ivec c_CARBON = ivec::setzero(); + int map_i = 0; + int i; + for (i = 1; i < ka->num_types; i++) { + if (ka->map[i]) + map_i |= (1 << i); + } + ivec c_i1 = ivec::set1(1); + ivec c_im = ivec::set1(map_i); + AtomAIREBOT * _noalias x = ka->x; + + for (i = ka->neigh_from_atom; i < ka->neigh_to_atom; i++) { + + fvec x_i = fvec::set1(x[i].x); + fvec y_i = fvec::set1(x[i].y); + fvec z_i = fvec::set1(x[i].z); + int itype = ka->map[ka->x[i].w]; + + fvec rcmaxsq0 = fvec::set1(ka->params.rcmaxsq[itype][0]); + fvec rcmaxsq1 = fvec::set1(ka->params.rcmaxsq[itype][1]); + fvec rcmax0 = fvec::set1(ka->params.rcmax[itype][0]); + fvec rcmax1 = fvec::set1(ka->params.rcmax[itype][1]); + fvec rcmin0 = fvec::set1(ka->params.rcmin[itype][0]); + fvec rcmin1 = fvec::set1(ka->params.rcmin[itype][1]); + fvec rcmaxskinsq0 = fvec::set1( + (ka->params.rcmax[itype][0] + ka->skin) * (ka->params.rcmax[itype][0] + + ka->skin)); + fvec rcmaxskinsq1 = fvec::set1( + (ka->params.rcmax[itype][1] + ka->skin) * (ka->params.rcmax[itype][1] + + ka->skin)); + fvec nC = fvec::setzero(); + fvec nH = fvec::setzero(); + + ka->neigh_rebo.offset[i] = offset; + + int jnum = ka->rebuild_flag ? ka->neigh_lmp.num[i] : + ka->neigh_rebo.num_half[i]; + int * neighs = ka->rebuild_flag ? + &ka->neigh_lmp.entries[ka->neigh_lmp.offset[i]] : + &ka->neigh_rebo.entries[ka->neigh_rebo.offset[i]+jnum]; + int * skin_target = &ka->neigh_rebo.entries[offset+ka->num_neighs_per_atom]; + int n = 0; + int n_skin = 0; + + int lowest_idx; + #pragma unroll(4) + for (lowest_idx = 0; lowest_idx < jnum; lowest_idx += fvec::VL) { + bvec j_mask = bvec::full(); + if (lowest_idx + fvec::VL > jnum) j_mask = bvec::only(jnum - lowest_idx); + + int * _noalias neighs_l = neighs + lowest_idx; + fvec x_j, y_j, z_j; + bvec jtype_mask; + ivec ji = ivec::maskz_loadu(j_mask, neighs_l); + aut_loadatoms_vec(x, ji, + &x_j, &y_j, &z_j, &jtype_mask, ka->map, c_im, c_i1); + fvec delx = x_i - x_j; + fvec dely = y_i - y_j; + fvec delz = z_i - z_j; + fvec rsq = delx * delx + dely * dely + delz * delz; + if (ka->rebuild_flag) { + fvec rcmaxskinsq = fvec::mask_blend(jtype_mask, rcmaxskinsq0, + rcmaxskinsq1); + bvec c_mask = fvec::mask_cmplt(j_mask, rsq, rcmaxskinsq); + ivec::mask_compressstore(c_mask, &skin_target[n_skin], ji); + n_skin += bvec::popcnt(c_mask); + } + fvec rcmaxsq = fvec::mask_blend(jtype_mask, rcmaxsq0, rcmaxsq1); + bvec c_mask = fvec::mask_cmplt(j_mask, rsq, rcmaxsq); + if (bvec::test_all_unset(c_mask)) continue; + ivec::mask_compressstore(c_mask, &ka->neigh_rebo.entries[offset + n], ji); + n += bvec::popcnt(c_mask); + fvec rcmax = fvec::mask_blend(jtype_mask, rcmax0, rcmax1); + fvec rcmin = fvec::mask_blend(jtype_mask, rcmin0, rcmin1); + fvec sp = aut_mask_Sp(c_mask, fvec::sqrt(rsq), rcmin, rcmax); + nC = fvec::mask_add(nC, bvec::kandn(jtype_mask, c_mask), nC, sp); + nH = fvec::mask_add(nH, bvec::kand (jtype_mask, c_mask), nH, sp); + } + ka->neigh_rebo.num[i] = n; + if (ka->rebuild_flag) { + for (int i = 0; i < n_skin; i++) { + ka->neigh_rebo.entries[offset+n_skin+i] = skin_target[i]; + } + } + if (ka->rebuild_flag) { + assert(n <= n_skin); + offset += 2 * n_skin; + ka->neigh_rebo.num_half[i] = n_skin; + } else { + assert(n <= jnum); + offset += 2 * jnum; + } + ka->nC[i] = fvec::reduce_add(nC); + ka->nH[i] = fvec::reduce_add(nH); + } +} + + +static fvec aut_eval_poly_lin_pd_2(int n, flt_t * vals, ivec idx, fvec x, + fvec * deriv) { + fvec c_1 = fvec::set1(1); + fvec x_i = c_1; + fvec x_im1 = fvec::setzero(); + fvec result = fvec::setzero(); + fvec i_v = fvec::setzero(); + *deriv = fvec::setzero(); + int i; + for (i = 0; i < n; i++) { + fvec coeff = fvec::gather(idx, vals + i, sizeof(flt_t)); + result = result + coeff * x_i; + *deriv = *deriv + coeff * x_im1 * i_v; + x_im1 = x_i; + x_i = x_i * x; + i_v = i_v + c_1; + } + return result; +} + +static fvec aut_mask_gSpline_pd_2(KernelArgsAIREBOT * ka, + bvec active_mask, int itype, fvec cosjik, + fvec Nij, fvec *dgdc, fvec *dgdN) { + int i; + flt_t * gDom = NULL; + int nDom = 0; + ivec offs = ivec::setzero(); + fvec NCmin = fvec::set1(ka->params.NCmin); + bvec Ngt = fvec::cmpnle(Nij, NCmin); //gt + if (itype == 0) { + nDom = 4; + gDom = &ka->params.gCdom[0]; + offs = ivec::mask_blend(Ngt, offs, ivec::set1(4*6)); + } else { + nDom = 3; + gDom = &ka->params.gHdom[0]; + offs = ivec::set1(8 * 6); + } + cosjik = fvec::max(fvec::set1(gDom[0]), fvec::min(fvec::set1(gDom[nDom]), + cosjik)); + ivec index6 = ivec::setzero(); + for (i = 0; i < nDom; i++) { + bvec cosge = fvec::cmpnlt(cosjik, fvec::set1(gDom[i])); //ge + bvec cosle = fvec::cmple(cosjik, fvec::set1(gDom[i+1])); + index6 = ivec::mask_blend(cosge & cosle, index6, ivec::set1(6*i)); + } + fvec g = aut_eval_poly_lin_pd_2(6, &ka->params.gVal[0], offs + index6, + cosjik, dgdc); + *dgdN = fvec::setzero(); + if (itype == 0) { + fvec NCmax = fvec::set1(ka->params.NCmax); + bvec Nlt = fvec::cmplt(Nij, NCmax); //gt + bvec Nmask = Ngt & Nlt; + if (bvec::test_any_set(Nmask)) { + fvec dg1; + fvec g1 = aut_eval_poly_lin_pd_2(6, &ka->params.gVal[0], index6, cosjik, + &dg1); + fvec dS; + fvec cut = aut_Sp_deriv(Nij, NCmin, NCmax, &dS); + *dgdN = fvec::mask_mul(*dgdN, Nmask, dS, g1 - g); + g = fvec::mask_add(g, Nmask, g, cut * ( g1 - g)); + *dgdc = fvec::mask_add(*dgdc, Nmask, *dgdc, cut * ( dg1 - *dgdc)); + } + } + return g; +} + +static fvec aut_PijSpline(KernelArgsAIREBOT * ka, int itype, + int jtype, fvec NijC, fvec NijH, fvec *dN2) { + flt_t ret[fvec::VL] __attribute__((aligned(64))); + flt_t dN20[fvec::VL] __attribute__((aligned(64))); + flt_t dN21[fvec::VL] __attribute__((aligned(64))); + flt_t NijC_[fvec::VL] __attribute__((aligned(64))); + flt_t NijH_[fvec::VL] __attribute__((aligned(64))); + flt_t tmp_dN2[2]; + fvec::store(NijC_, NijC); + fvec::store(NijH_, NijH); + int i; + for (i = 0; i < fvec::VL; i++) { + ret[i] = PijSpline(ka, itype, jtype, NijC_[i], NijH_[i], tmp_dN2); + dN20[i] = tmp_dN2[0]; + dN21[i] = tmp_dN2[1]; + } + dN2[0] = fvec::load(dN20); + dN2[1] = fvec::load(dN21); + return fvec::load(ret); +} + +/* + * aut_frebo_data stores all the short-ranged coordinations + * and intermediate values that get reused frequently during + * bondorder calculations. + * BUF_CAP should rarely exceed 4, so 8 is a very conservative + * value. + */ +static const int BUF_CAP = 8; +struct aut_frebo_data { + fvec rikx_buf[BUF_CAP]; + fvec riky_buf[BUF_CAP]; + fvec rikz_buf[BUF_CAP]; + fvec rikmag_buf[BUF_CAP]; + fvec cosjik_buf[BUF_CAP]; + ivec k_buf[BUF_CAP]; + fvec g_buf[BUF_CAP]; + fvec dgdc_buf[BUF_CAP]; + fvec ex_lam_buf[BUF_CAP]; + fvec wik_buf[BUF_CAP]; + fvec dwik_buf[BUF_CAP]; + fvec cutN_buf[BUF_CAP]; + fvec dcutN_buf[BUF_CAP]; + bvec ktype_buf[BUF_CAP]; + bvec mask_buf[BUF_CAP]; + fvec force_k_x_buf[BUF_CAP]; + fvec force_k_y_buf[BUF_CAP]; + fvec force_k_z_buf[BUF_CAP]; + int buf_len; + fvec x_i; + fvec y_i; + fvec z_i; + fvec x_j; + fvec y_j; + fvec z_j; + fvec nCi; + fvec nHi; + fvec force_i_x; + fvec force_i_y; + fvec force_i_z; + fvec force_j_x; + fvec force_j_y; + fvec force_j_z; +}; + +/* + * Initialize values in aut_frebo_data and perform the calculations + * for p_ij. + */ +static fvec aut_frebo_pij_pd_2( + KernelArgsAIREBOT * _noalias ka, + struct aut_frebo_data * _noalias data, + int itype, int jtype, + ivec vi, ivec vj, + fvec rijx, fvec rijy, fvec rijz, fvec rijmag, + fvec wij, fvec VA, fvec * sum_N, fvec fij[3] +) { + AtomAIREBOT * _noalias x = ka->x; + int * _noalias map = ka->map; + flt_t * _noalias nC = ka->nC; + flt_t * _noalias nH = ka->nH; + fvec x_i, y_i, z_i; + fvec x_j, y_j, z_j; + x_i = data->x_i; + y_i = data->y_i; + z_i = data->z_i; + x_j = data->x_j; + y_j = data->y_j; + z_j = data->z_j; + fvec invrijm = fvec::recip(rijmag); + fvec invrijm2 = invrijm * invrijm; + fvec rcminij = fvec::set1(ka->params.rcmin[itype][jtype]); + fvec rcmaxij = fvec::set1(ka->params.rcmax[itype][jtype]); + fvec Nmin = fvec::set1(ka->params.Nmin); + fvec Nmax = fvec::set1(ka->params.Nmax); + int map_i_scalar = 0; + { + int i; + for (i = 1; i < ka->num_types; i++) { + if (ka->map[i]) + map_i_scalar |= (1 << i); + } + } + ivec map_i = ivec::set1(map_i_scalar); + fvec nCi = data->nCi; + fvec nHi = data->nHi; + fvec Nij = nHi + nCi - wij; + fvec factor_jtype, factor_not_jtype; + if (jtype) { + factor_jtype = fvec::set1(1); + factor_not_jtype = fvec::set1(0); + } else { + factor_jtype = fvec::set1(0); + factor_not_jtype = fvec::set1(1); + } + fvec NijC = nCi - wij * factor_not_jtype; + fvec NijH = nHi - wij * factor_jtype; + fvec sum_pij = fvec::setzero(); + fvec sum_dpij_dN = fvec::setzero(); + fvec dN2[2]; + ivec offseti = ivec::mask_gather(ivec::setzero(), bvec::full(), vi, + ka->neigh_rebo.offset, sizeof(int)); + int buf_len = 0; + ivec knum = ivec::mask_gather(ivec::setzero(), bvec::full(), vi, + ka->neigh_rebo.num, sizeof(int)); + ivec kk = ivec::setzero(); + bvec active_mask = ivec::cmplt(kk, knum); + ivec c_i1 = ivec::set1(1); + fvec rho_j = fvec::set1(ka->params.rho[jtype][1]); + fvec rho_k0 = fvec::set1(ka->params.rho[0][1]); + fvec rho_k1 = fvec::set1(ka->params.rho[1][1]); + fvec c_4 = fvec::set1(4); + fvec c_2_0 = fvec::set1(2.0); + fvec c_m2_0 = fvec::set1(-2.0); + fvec c_4_0 = fvec::set1(4.0); + fvec c_0_5 = fvec::set1(0.5); + fvec c_m0_5 = fvec::set1(-0.5); + fvec c_1 = fvec::set1(1); + fvec c_m1 = fvec::set1(-1); + fvec factor_itype = itype ? c_1 : fvec::setzero(); + fvec rcmax0 = fvec::set1(ka->params.rcmax[itype][0]); + fvec rcmax1 = fvec::set1(ka->params.rcmax[itype][1]); + fvec rcmin0 = fvec::set1(ka->params.rcmin[itype][0]); + fvec rcmin1 = fvec::set1(ka->params.rcmin[itype][1]); + fvec result_f_i_x = fvec::setzero(); + fvec result_f_i_y = fvec::setzero(); + fvec result_f_i_z = fvec::setzero(); + fvec result_f_j_x = fvec::setzero(); + fvec result_f_j_y = fvec::setzero(); + fvec result_f_j_z = fvec::setzero(); + *sum_N = fvec::setzero(); + { + while (bvec::test_any_set(active_mask)) { + ivec k = ivec::mask_gather(ivec::setzero(), active_mask, kk + offseti, + ka->neigh_rebo.entries, sizeof(int)); + bvec excluded_mask = ivec::cmpeq(k, vj) & active_mask; + if (bvec::test_any_set(excluded_mask)) { + kk = ivec::mask_add(kk, excluded_mask, kk, c_i1); + active_mask = ivec::cmplt(kk, knum); + continue; + } + fvec x_k, y_k, z_k; + bvec ktype_mask; + aut_loadatoms_vec(x, k, &x_k, &y_k, &z_k, &ktype_mask, ka->map, map_i, + c_i1); + fvec rikx = x_i - x_k; + fvec riky = y_i - y_k; + fvec rikz = z_i - z_k; + fvec rikmag = fvec::sqrt(rikx * rikx + riky * riky + rikz * rikz); + fvec rho_k = fvec::mask_blend(ktype_mask, rho_k0, rho_k1); + fvec lamdajik = c_4 * factor_itype * ( rho_k - rikmag - ( rho_j - + rijmag)); + fvec ex_lam = fvec::exp(lamdajik); + fvec rcmax = fvec::mask_blend(ktype_mask, rcmax0, rcmax1); + fvec rcmin = fvec::mask_blend(ktype_mask, rcmin0, rcmin1); + fvec dwik; + fvec wik = aut_Sp_deriv(rikmag, rcmin, rcmax, &dwik); + fvec Nki = fvec::gather(k, nC, sizeof(flt_t)) + + fvec::gather(k, nH, sizeof(flt_t)) - wik; + fvec cosjik = (rijx * rikx + rijy * riky + rijz * rikz) / + ( rijmag * rikmag); + cosjik = fvec::min(c_1, fvec::max(c_m1, cosjik)); + fvec dgdc, dgdN; + fvec g = aut_mask_gSpline_pd_2(ka, active_mask, itype, cosjik, Nij, + &dgdc, &dgdN); + sum_pij = fvec::mask_add(sum_pij, active_mask, sum_pij, wik * g * ex_lam); + sum_dpij_dN = fvec::mask_add(sum_dpij_dN, active_mask, sum_dpij_dN, + wik * ex_lam * dgdN); + fvec dcutN; + fvec cutN = aut_Sp_deriv(Nki, Nmin, Nmax, &dcutN); + *sum_N = fvec::mask_add(*sum_N, active_mask, *sum_N, + fvec::mask_blend(ktype_mask, c_1, + fvec::setzero()) * wik * cutN); + if (buf_len == BUF_CAP) goto exceed_buffer; + data->rikx_buf[buf_len] = rikx; + data->riky_buf[buf_len] = riky; + data->rikz_buf[buf_len] = rikz; + data->rikmag_buf[buf_len] = rikmag; + data->cosjik_buf[buf_len] = cosjik; + data->ktype_buf[buf_len] = ktype_mask; + data->k_buf[buf_len] = k; + data->g_buf[buf_len] = g; + data->dgdc_buf[buf_len] = dgdc; + data->ex_lam_buf[buf_len] = ex_lam; + data->wik_buf[buf_len] = wik; + data->dwik_buf[buf_len] = dwik; + data->mask_buf[buf_len] = active_mask; + data->cutN_buf[buf_len] = cutN; + data->dcutN_buf[buf_len] = dcutN; + buf_len += 1; + kk = ivec::mask_add(kk, active_mask, kk, c_i1); + active_mask = ivec::cmplt(kk, knum); + } + data->buf_len = buf_len; + fvec PijS = aut_PijSpline(ka, itype, jtype, NijC, NijH, &dN2[0]); + fvec pij = fvec::invsqrt(c_1 + sum_pij + PijS); + fvec tmp = c_m0_5 * pij * pij * pij; + int buf_idx; + for (buf_idx = 0; buf_idx < buf_len; buf_idx++) { + fvec rikx = data->rikx_buf[buf_idx]; + fvec riky = data->riky_buf[buf_idx]; + fvec rikz = data->rikz_buf[buf_idx]; + fvec rikmag = data->rikmag_buf[buf_idx]; + fvec cosjik = data->cosjik_buf[buf_idx]; + bvec ktype_mask = data->ktype_buf[buf_idx]; + ivec k = data->k_buf[buf_idx]; + fvec g = data->g_buf[buf_idx]; + fvec dgdc = data->dgdc_buf[buf_idx]; + fvec ex_lam = data->ex_lam_buf[buf_idx]; + fvec wik = data->wik_buf[buf_idx]; + fvec dwik = data->dwik_buf[buf_idx]; + bvec mask = data->mask_buf[buf_idx]; + fvec invrikm = fvec::recip(rikmag); + fvec rjkx = rikx - rijx; + fvec rjky = riky - rijy; + fvec rjkz = rikz - rijz; + fvec rjkmag = fvec::sqrt( + rjkx * rjkx + rjky * rjky + rjkz * rjkz); + fvec rijrik = c_2_0 * rijmag * rikmag; + fvec rr = rijmag * rijmag - rikmag * rikmag; + fvec dctdjk = c_m2_0 / rijrik; + fvec dctdik = (rjkmag * rjkmag - rr) / ( rijrik * rikmag * rikmag); + fvec dctdij = (rjkmag * rjkmag + rr) / ( rijrik * rijmag * rijmag); + fvec fi[3], fj[3], fk[3]; + fvec pref = c_0_5 * VA * tmp; + fvec tmp20 = pref * wik * dgdc * ex_lam; + fj[0] = fj[1] = fj[2] = fvec::setzero(); + fvec tmpdik = tmp20 * dctdik; + fi[0] = fvec::setzero() - tmpdik * rikx; + fi[1] = fvec::setzero() - tmpdik * riky; + fi[2] = fvec::setzero() - tmpdik * rikz; + fk[0] = tmpdik * rikx; + fk[1] = tmpdik * riky; + fk[2] = tmpdik * rikz; + + fvec tmpdij = tmp20 * dctdij; + fij[0] = fvec::mask_sub(fij[0], mask, fij[0], tmpdij * rijx); + fij[1] = fvec::mask_sub(fij[1], mask, fij[1], tmpdij * rijy); + fij[2] = fvec::mask_sub(fij[2], mask, fij[2], tmpdij * rijz); + + fvec tmpdjk = tmp20 * dctdjk; + fi[0] = fi[0] - tmpdjk * rjkx; + fi[1] = fi[1] - tmpdjk * rjky; + fi[2] = fi[2] - tmpdjk * rjkz; + fk[0] = fk[0] + tmpdjk * rjkx; + fk[1] = fk[1] + tmpdjk * rjky; + fk[2] = fk[2] + tmpdjk * rjkz; + fij[0] = fvec::mask_add(fij[0], mask, fij[0], tmpdjk * rjkx); + fij[1] = fvec::mask_add(fij[1], mask, fij[1], tmpdjk * rjky); + fij[2] = fvec::mask_add(fij[2], mask, fij[2], tmpdjk * rjkz); + + if (itype) { + fvec tmp21 = pref * wik * g * ex_lam * c_4_0; + fvec tmp21ij = tmp21 * invrijm; + fij[0] = fvec::mask_sub(fij[0], mask, fij[0], tmp21ij * rijx); + fij[1] = fvec::mask_sub(fij[1], mask, fij[1], tmp21ij * rijy); + fij[2] = fvec::mask_sub(fij[2], mask, fij[2], tmp21ij * rijz); + fvec tmp21ik = tmp21 * invrikm; + fi[0] = fi[0] + tmp21ik * rikx; + fi[1] = fi[1] + tmp21ik * riky; + fi[2] = fi[2] + tmp21ik * rikz; + fk[0] = fk[0] - tmp21ik * rikx; + fk[1] = fk[1] - tmp21ik * riky; + fk[2] = fk[2] - tmp21ik * rikz; + } + + // coordination forces + + // dwik forces + fvec tmp22 = pref * dwik * g * ex_lam * invrikm; + fi[0] = fi[0] - tmp22 * rikx; + fi[1] = fi[1] - tmp22 * riky; + fi[2] = fi[2] - tmp22 * rikz; + fk[0] = fk[0] + tmp22 * rikx; + fk[1] = fk[1] + tmp22 * riky; + fk[2] = fk[2] + tmp22 * rikz; + + // PIJ forces + fvec dN2ktype = fvec::mask_blend(ktype_mask, dN2[0], dN2[1]); + fvec tmp23 = pref * dN2ktype * dwik * invrikm; + fi[0] = fi[0] - tmp23 * rikx; + fi[1] = fi[1] - tmp23 * riky; + fi[2] = fi[2] - tmp23 * rikz; + fk[0] = fk[0] + tmp23 * rikx; + fk[1] = fk[1] + tmp23 * riky; + fk[2] = fk[2] + tmp23 * rikz; + + // dgdN forces + fvec tmp24 = pref * sum_dpij_dN * dwik * invrikm; + fi[0] = fi[0] - tmp24 * rikx; + fi[1] = fi[1] - tmp24 * riky; + fi[2] = fi[2] - tmp24 * rikz; + fk[0] = fk[0] + tmp24 * rikx; + fk[1] = fk[1] + tmp24 * riky; + fk[2] = fk[2] + tmp24 * rikz; + + result_f_i_x = fvec::mask_add(result_f_i_x, mask, result_f_i_x, fi[0]); + result_f_i_y = fvec::mask_add(result_f_i_y, mask, result_f_i_y, fi[1]); + result_f_i_z = fvec::mask_add(result_f_i_z, mask, result_f_i_z, fi[2]); + result_f_j_x = fvec::mask_add(result_f_j_x, mask, result_f_j_x, fj[0]); + result_f_j_y = fvec::mask_add(result_f_j_y, mask, result_f_j_y, fj[1]); + result_f_j_z = fvec::mask_add(result_f_j_z, mask, result_f_j_z, fj[2]); + + data->force_k_x_buf[buf_idx] = fk[0]; + data->force_k_y_buf[buf_idx] = fk[1]; + data->force_k_z_buf[buf_idx] = fk[2]; + } + data->force_i_x = result_f_i_x; + data->force_i_y = result_f_i_y; + data->force_i_z = result_f_i_z; + data->force_j_x = result_f_j_x; + data->force_j_y = result_f_j_y; + data->force_j_z = result_f_j_z; + return pij; + } + exceed_buffer: + data->buf_len = -1; + return fvec::setzero(); +} + +/* + * Apply the force values stored iin aut_frebo_data to + * the respective neighbors. + */ +static void aut_frebo_data_writeback( + KernelArgsAIREBOT * _noalias ka, + struct aut_frebo_data * _noalias data) { + ResultForceT * _noalias result_f = ka->result_f; + flt_t fk_x_buf[fvec::VL] __attribute__((aligned(64))); + flt_t fk_y_buf[fvec::VL] __attribute__((aligned(64))); + flt_t fk_z_buf[fvec::VL] __attribute__((aligned(64))); + int fk_k_buf[ivec::VL] __attribute__((aligned(64))); + int buf_idx; + for (buf_idx = 0; buf_idx < data->buf_len; buf_idx++) { + ivec k = data->k_buf[buf_idx]; + bvec active_mask = data->mask_buf[buf_idx]; + + fvec::store(fk_x_buf, data->force_k_x_buf[buf_idx]); + fvec::store(fk_y_buf, data->force_k_y_buf[buf_idx]); + fvec::store(fk_z_buf, data->force_k_z_buf[buf_idx]); + ivec::store(fk_k_buf, k); + + int lane; + for (lane = 0; lane < fvec::VL; lane++) { + if (bvec::test_at(active_mask, lane)) {} else continue; + int kk = fk_k_buf[lane]; + result_f[kk].x += fk_x_buf[lane]; + result_f[kk].y += fk_y_buf[lane]; + result_f[kk].z += fk_z_buf[lane]; + } + } +} + +static void aut_frebo_N_spline_force( + KernelArgsAIREBOT * _noalias ka, + struct aut_frebo_data * _noalias data, int itype, int jtype, ivec vi, + ivec vj, fvec VA, fvec dN, fvec dNconj, fvec Nconj) { + ivec c_i1 = ivec::set1(1); + fvec c_2 = fvec::set1(2); + fvec c_TOL = fvec::set1(TOL); + ResultForceT * _noalias result_f = ka->result_f; + AtomAIREBOT * _noalias x = ka->x; + int * _noalias map = ka->map; + flt_t * _noalias nC = ka->nC; + flt_t * _noalias nH = ka->nH; + fvec x_i, y_i, z_i; + x_i = data->x_i; + y_i = data->y_i; + z_i = data->z_i; + fvec Nmin = fvec::set1(ka->params.Nmin); + fvec Nmax = fvec::set1(ka->params.Nmax); + int map_i_scalar = 0; + { + int i; + for (i = 1; i < ka->num_types; i++) { + if (ka->map[i]) + map_i_scalar |= (1 << i); + } + } + ivec map_i = ivec::set1(map_i_scalar); + fvec dN2[2]; + ivec kk = ivec::setzero(); + fvec rcmax0 = fvec::set1(ka->params.rcmax[itype][0]); + fvec rcmax1 = fvec::set1(ka->params.rcmax[itype][1]); + fvec rcmin0 = fvec::set1(ka->params.rcmin[itype][0]); + fvec rcmin1 = fvec::set1(ka->params.rcmin[itype][1]); + fvec result_f_i_x = fvec::setzero(); + fvec result_f_i_y = fvec::setzero(); + fvec result_f_i_z = fvec::setzero(); + int buf_idx; + for (buf_idx = 0; buf_idx < data->buf_len; buf_idx++) { + ivec k = data->k_buf[buf_idx]; + bvec active_mask = data->mask_buf[buf_idx]; + fvec rikx = data->rikx_buf[buf_idx]; + fvec riky = data->riky_buf[buf_idx]; + fvec rikz = data->rikz_buf[buf_idx]; + fvec rikmag = data->rikmag_buf[buf_idx]; + bvec ktype_mask = data->ktype_buf[buf_idx]; + + fvec dwik = data->dwik_buf[buf_idx]; + fvec wik = data->wik_buf[buf_idx]; + + fvec dNki = data->dcutN_buf[buf_idx]; + fvec SpN = data->cutN_buf[buf_idx]; + + fvec invrikmag = fvec::recip(rikmag); + fvec pref = VA * dwik * invrikmag; + fvec fdN = dN * pref; + fvec fdNconj = pref * SpN * c_2 * dNconj * Nconj; + fvec ffactor = fdN; + bvec ktype_is_C = ~ ktype_mask; + ffactor = fvec::mask_add(ffactor, ktype_is_C, ffactor, fdNconj); + + fvec fkx = ffactor * rikx; + fvec fky = ffactor * riky; + fvec fkz = ffactor * rikz; + + data->force_k_x_buf[buf_idx] = data->force_k_x_buf[buf_idx] + fkx; + data->force_k_y_buf[buf_idx] = data->force_k_y_buf[buf_idx] + fky; + data->force_k_z_buf[buf_idx] = data->force_k_z_buf[buf_idx] + fkz; + + result_f_i_x = fvec::mask_sub(result_f_i_x, active_mask, result_f_i_x, fkx); + result_f_i_y = fvec::mask_sub(result_f_i_y, active_mask, result_f_i_y, fky); + result_f_i_z = fvec::mask_sub(result_f_i_z, active_mask, result_f_i_z, fkz); + + bvec need_k_neighs = fvec::mask_cmpnle(active_mask, fvec::abs(dNki), c_TOL) + & ktype_is_C; + if (bvec::test_any_set(need_k_neighs)) { + int lane; + for (lane = 0; lane < fvec::VL; lane++) { + if (! bvec::test_at(need_k_neighs, lane)) continue; + int kk = ivec::at(k, lane); + int k = kk; + int ktype = map[x[k].w]; + int i = ivec::at(vi, lane); + fvec oldVA = VA; + double VA = fvec::at(oldVA, lane); + fvec oldwik = wik; + double wik = fvec::at(oldwik, lane); + fvec olddNconj = dNconj; + double dNconj = fvec::at(olddNconj, lane); + fvec oldNconj = Nconj; + double Nconj = fvec::at(oldNconj, lane); + fvec olddNki = dNki; + double dNki = fvec::at(olddNki, lane); + int * neighs_k = ka->neigh_rebo.entries + ka->neigh_rebo.offset[k]; + int nnum = ka->neigh_rebo.num[k]; + int nn; + for (nn = 0; nn < nnum; nn++) { + int n = neighs_k[nn]; + if (n == i) continue; + double rknx = x[k].x - x[n].x; + double rkny = x[k].y - x[n].y; + double rknz = x[k].z - x[n].z; + double rknmag = sqrt(rknx * rknx + rkny * rkny + rknz * rknz); + int ntype = map[x[n].w]; + double rcminkn = ka->params.rcmin[ktype][ntype]; + double rcmaxkn = ka->params.rcmax[ktype][ntype]; + double dwkn; + Sp(rknmag, rcminkn, rcmaxkn, &dwkn); + double ffactor = VA * dNconj * 2 * Nconj * wik * dNki * dwkn / rknmag; + result_f[k].x -= ffactor * rknx; + result_f[k].y -= ffactor * rkny; + result_f[k].z -= ffactor * rknz; + result_f[n].x += ffactor * rknx; + result_f[n].y += ffactor * rkny; + result_f[n].z += ffactor * rknz; + } + } + } + } + data->force_i_x = data->force_i_x + result_f_i_x; + data->force_i_y = data->force_i_y + result_f_i_y; + data->force_i_z = data->force_i_z + result_f_i_z; +} + +static fvec aut_frebo_pi_rc_pd(KernelArgsAIREBOT * ka, int itype, + int jtype, fvec Nij, fvec Nji, fvec Nijconj, + fvec * dN3) { + flt_t ret[fvec::VL] __attribute__((aligned(64))); + flt_t dN3ret[3][fvec::VL] __attribute__((aligned(64))); + int i; + for (i = 0; i < fvec::VL; i++) { + flt_t dN3tmp[3]; + ret[i] = frebo_pi_rc(ka, itype, jtype, fvec::at(Nij, i), fvec::at(Nji, i), + fvec::at(Nijconj, i), &dN3tmp[0]); + dN3ret[0][i] = dN3tmp[0]; + dN3ret[1][i] = dN3tmp[1]; + dN3ret[2][i] = dN3tmp[2]; + } + dN3[0] = fvec::load(&dN3ret[0][0]); + dN3[1] = fvec::load(&dN3ret[1][0]); + dN3[2] = fvec::load(&dN3ret[2][0]); + return fvec::load(&ret[0]); +} + +static fvec aut_frebo_Tij(KernelArgsAIREBOT * ka, int itype, + int jtype, fvec Nij, fvec Nji, fvec Nijconj, + fvec * dN3) { + flt_t ret[fvec::VL] __attribute__((aligned(64))); + flt_t dN3ret[3][fvec::VL] __attribute__((aligned(64))); + int i; + for (i = 0; i < fvec::VL; i++) { + flt_t dN3tmp[3]; + ret[i] = frebo_Tij(ka, itype, jtype, fvec::at(Nij, i), fvec::at(Nji, i), + fvec::at(Nijconj, i), &dN3tmp[0]); + dN3ret[0][i] = dN3tmp[0]; + dN3ret[1][i] = dN3tmp[1]; + dN3ret[2][i] = dN3tmp[2]; + } + dN3[0] = fvec::load(&dN3ret[0][0]); + dN3[1] = fvec::load(&dN3ret[1][0]); + dN3[2] = fvec::load(&dN3ret[2][0]); + return fvec::load(&ret[0]); +} + +static fvec aut_frebo_sum_omega( + KernelArgsAIREBOT * _noalias ka, + struct aut_frebo_data * _noalias i_data, + struct aut_frebo_data * _noalias j_data, + int itype, int jtype, + ivec vi, ivec vj, + fvec r23x, fvec r23y, fvec r23z, fvec r23mag, + fvec VA, fvec fij[3] +) { + fvec c_1 = fvec::set1(1); + fvec c_m1 = fvec::set1(-1); + fvec c_2 = fvec::set1(2); + fvec c_m2 = fvec::set1(-2); + fvec sum_omega = fvec::setzero(); + fvec thmin = fvec::set1(ka->params.thmin); + fvec thmax = fvec::set1(ka->params.thmax); + // 2 == i, 3 == j + fvec r32x = fvec::setzero() - r23x; + fvec r32y = fvec::setzero() - r23y; + fvec r32z = fvec::setzero() - r23z; + int buf_idx_i, buf_idx_j; + for (buf_idx_i = 0; buf_idx_i < i_data->buf_len; buf_idx_i++) { + // a1 == k == buf_idx_i + bvec mask_start = i_data->mask_buf[buf_idx_i]; + fvec r21x = i_data->rikx_buf[buf_idx_i]; // a2 - a1 -> i - k + fvec r21y = i_data->riky_buf[buf_idx_i]; // a2 - a1 -> i - k + fvec r21z = i_data->rikz_buf[buf_idx_i]; // a2 - a1 -> i - k + fvec r21mag = i_data->rikmag_buf[buf_idx_i]; + // TODO use buffered cosjik + fvec cos321 = ( + r23x * r21x + r23y * r21y + r23z * r21z) / ( r23mag * r21mag); + cos321 = fvec::min(c_1, fvec::max(c_m1, cos321)); + fvec sin321 = fvec::sqrt(c_1 - cos321 * cos321); + bvec mask_outer = fvec::cmpneq(fvec::setzero(), sin321) & mask_start; + // add "continue" + fvec sink2i = fvec::mask_recip(fvec::undefined(), mask_outer, + sin321 * sin321); + fvec rik2i = fvec::mask_recip(fvec::undefined(), mask_outer, + r21mag * r21mag); + fvec rr = r23mag * r23mag - r21mag * r21mag; + fvec r31x = r21x - r23x; + fvec r31y = r21y - r23y; + fvec r31z = r21z - r23z; + fvec r31mag2 = r31x * r31x + r31y * r31y + r31z * r31z; + fvec rijrik = c_2 * r23mag * r21mag; + fvec r21mag2 = r21mag * r21mag; + fvec dctik = fvec::mask_div(fvec::undefined(), mask_outer, r31mag2 - rr, + rijrik * r21mag2); + fvec dctij = fvec::mask_div(fvec::undefined(), mask_outer, r31mag2 + rr, + rijrik * r23mag * r23mag); + fvec dctjk = fvec::mask_div(fvec::undefined(), mask_outer, c_m2, rijrik); + fvec dw21 = i_data->dwik_buf[buf_idx_i]; + fvec w21 = i_data->wik_buf[buf_idx_i]; + fvec dtsjik; + fvec tspjik = aut_Sp2_deriv(cos321, thmin, thmax, &dtsjik); + dtsjik = fvec::setzero() - dtsjik; // todo replace by appropriate xor. + ivec k = i_data->k_buf[buf_idx_i]; + for (buf_idx_j = 0; buf_idx_j < j_data->buf_len; buf_idx_j++) { + // check l == k in second loop. + // l == a4 == buf_idx_j + ivec l = j_data->k_buf[buf_idx_j]; + bvec mask_inner_0 = ivec::mask_cmpneq(mask_outer, k, l) & + j_data->mask_buf[buf_idx_j]; + // add "continue" + fvec r34x = j_data->rikx_buf[buf_idx_j]; + fvec r34y = j_data->riky_buf[buf_idx_j]; + fvec r34z = j_data->rikz_buf[buf_idx_j]; + fvec r34mag = j_data->rikmag_buf[buf_idx_j]; + fvec cos234 = fvec::mask_div(fvec::undefined(), mask_inner_0, + r32x * r34x + r32y * r34y + r32z * r34z, + r23mag * r34mag); + cos234 = fvec::min(c_1, fvec::max(c_m1, cos234)); + fvec sin234 = fvec::mask_sqrt(fvec::undefined(), mask_inner_0, + c_1 - cos234 * cos234); + bvec mask_inner_1 = fvec::mask_cmpneq(mask_inner_0, sin234, + fvec::setzero()); + // add "continue" + fvec sinl2i = fvec::mask_recip(fvec::undefined(), mask_inner_1, + sin234 * sin234); + fvec rjl2i = fvec::mask_recip(fvec::undefined(), mask_inner_1, + r34mag * r34mag); + fvec dw34 = j_data->dwik_buf[buf_idx_j]; + fvec w34 = j_data->wik_buf[buf_idx_j]; + fvec rr = r23mag * r23mag - r34mag * r34mag; + fvec r24x = r23x + r34x; + fvec r24y = r23y + r34y; + fvec r24z = r23z + r34z; + fvec r242 = r24x * r24x + r24y * r24y + r24z * r24z; + fvec rijrjl = c_2 * r23mag * r34mag; + fvec rjl2 = r34mag * r34mag; + fvec dctjl = fvec::mask_div(fvec::undefined(), mask_inner_1, r242 - rr, + rijrjl * rjl2); + fvec dctji = fvec::mask_div(fvec::undefined(), mask_inner_1, r242 + rr, + rijrjl * r23mag * r23mag); + fvec dctil = fvec::mask_div(fvec::undefined(), mask_inner_1, c_m2, + rijrjl); + fvec dtsijl; + fvec tspijl = aut_Sp2_deriv(cos234, thmin, thmax, &dtsijl); + dtsijl = fvec::setzero() - dtsijl; + fvec prefactor = VA; + + fvec cross321x = r32y * r21z - r32z * r21y; + fvec cross321y = r32z * r21x - r32x * r21z; + fvec cross321z = r32x * r21y - r32y * r21x; + fvec cross234x = r23y * r34z - r23z * r34y; + fvec cross234y = r23z * r34x - r23x * r34z; + fvec cross234z = r23x * r34y - r23y * r34x; + + fvec cwnum = cross321x * cross234x + cross321y * cross234y + cross321z * + cross234z; + fvec cwnom = r21mag * r34mag * r23mag * r23mag * sin321 * sin234; + fvec om1234 = fvec::mask_div(fvec::undefined(), mask_inner_1, cwnum, + cwnom); + fvec cw = om1234; + fvec sum_omega_contrib = (c_1 - om1234 * om1234) * w21 * w34 * + (c_1 - tspjik) * ( c_1 - tspijl); + sum_omega = fvec::mask_add(sum_omega, mask_inner_1, sum_omega, + sum_omega_contrib); + fvec dt1dik = rik2i - dctik * sink2i * cos321; + fvec dt1djk = fvec::setzero() - dctjk * sink2i * cos321; + fvec dt1djl = rjl2i - dctjl * sinl2i * cos234; + fvec dt1dil = fvec::setzero() - dctil * sinl2i * cos234; + fvec dt1dij = fvec::mask_div(fvec::undefined(), mask_inner_1, c_2, + r23mag * r23mag) - + dctij * sink2i * cos321 - dctji * sinl2i * cos234; + + fvec dt2dikx = r23y * cross234z - r23z * cross234y; + fvec dt2diky = r23z * cross234x - r23x * cross234z; + fvec dt2dikz = r23x * cross234y - r23y * cross234x; + + fvec dt2djlx = r23z * cross321y - r23y * cross321z; + fvec dt2djly = r23x * cross321z - r23z * cross321x; + fvec dt2djlz = r23y * cross321x - r23x * cross321y; + + fvec dt2dijx = r21z * cross234y + r34y * cross321z - + ( r34z * cross321y + r21y * cross234z); + fvec dt2dijy = r21x * cross234z + r34z * cross321x - + ( r34x * cross321z + r21z * cross234x); + fvec dt2dijz = r21y * cross234x + r34x * cross321y - + ( r34y * cross321x + r21x * cross234y); + + fvec aa = prefactor * c_2 * fvec::mask_div(fvec::undefined(), + mask_inner_1, cw, cwnom) * + w21 * w34 * (c_1 - tspjik) * ( c_1 - tspijl); + fvec aaa1 = (fvec::setzero() - prefactor) * (c_1 - om1234 * om1234) * + (c_1 - tspjik) * (c_1 - tspijl); + fvec aaa2 = (fvec::setzero() - prefactor) * (c_1 - om1234 * om1234) * + w21 * w34; + fvec at2 = aa * cwnum; + + fvec fcijpc = aaa2 * dtsjik * dctij * (c_1 - tspijl) + aaa2 * dtsijl * + dctji * (c_1 - tspjik) - dt1dij * at2; + fvec fcikpc = aaa2 * dtsjik * dctik * (c_1 - tspijl) - dt1dik * at2; + fvec fcjlpc = aaa2 * dtsijl * dctjl * (c_1 - tspjik) - dt1djl * at2; + fvec fcjkpc = aaa2 * dtsjik * dctjk * (c_1 - tspijl) - dt1djk * at2; + fvec fcilpc = aaa2 * dtsijl * dctil * (c_1 - tspjik) - dt1dil * at2; + + fvec F23x = fcijpc * r23x + aa * dt2dijx; + fvec F23y = fcijpc * r23y + aa * dt2dijy; + fvec F23z = fcijpc * r23z + aa * dt2dijz; + + fvec F12x = fcikpc * r21x + aa * dt2dikx; + fvec F12y = fcikpc * r21y + aa * dt2diky; + fvec F12z = fcikpc * r21z + aa * dt2dikz; + + fvec F34x = fcjlpc * r34x + aa * dt2djlx; + fvec F34y = fcjlpc * r34y + aa * dt2djly; + fvec F34z = fcjlpc * r34z + aa * dt2djlz; + + fvec F31x = fcjkpc * r31x; + fvec F31y = fcjkpc * r31y; + fvec F31z = fcjkpc * r31z; + + fvec F24x = fcilpc * r24x; + fvec F24y = fcilpc * r24y; + fvec F24z = fcilpc * r24z; + + fvec f1x = fvec::setzero() - ( F12x + F31x); + fvec f1y = fvec::setzero() - ( F12y + F31y); + fvec f1z = fvec::setzero() - ( F12z + F31z); + fvec f2x = F12x + F31x; + fvec f2y = F12y + F31y; + fvec f2z = F12z + F31z; + fvec f3x = F34x + F24x; + fvec f3y = F34y + F24y; + fvec f3z = F34z + F24z; + fvec f4x = fvec::setzero() - ( F34x + F24x); + fvec f4y = fvec::setzero() - ( F34y + F24y); + fvec f4z = fvec::setzero() - ( F34z + F24z); + + fij[0] = fvec::mask_add(fij[0], mask_inner_1, fij[0], + F23x + F24x - F31x); + fij[1] = fvec::mask_add(fij[1], mask_inner_1, fij[1], + F23y + F24y - F31y); + fij[2] = fvec::mask_add(fij[2], mask_inner_1, fij[2], + F23z + F24z - F31z); + + fvec tmp20 = VA * (c_1 - om1234 * om1234) * (c_1 - tspjik) * + (c_1 - tspijl) * dw21 * w34 * fvec::mask_recip(fvec::undefined(), + mask_inner_1, r21mag); + f2x = f2x - tmp20 * r21x; + f2y = f2y - tmp20 * r21y; + f2z = f2z - tmp20 * r21z; + f1x = f1x + tmp20 * r21x; + f1y = f1y + tmp20 * r21y; + f1z = f1z + tmp20 * r21z; + + fvec tmp21 = VA * (c_1 - om1234 * om1234) * (c_1 - tspjik) * + (c_1 - tspijl) * w21 * dw34 * fvec::mask_recip(fvec::undefined(), + mask_inner_1, r34mag); + f3x = f3x - tmp21 * r34x; + f3y = f3y - tmp21 * r34y; + f3z = f3z - tmp21 * r34z; + f4x = f4x + tmp21 * r34x; + f4y = f4y + tmp21 * r34y; + f4z = f4z + tmp21 * r34z; + + // 1 == buf_idx_i, 2 == i, 3 == j, 4 == buf_idx_j + i_data->force_k_x_buf[buf_idx_i] = + fvec::mask_add(i_data->force_k_x_buf[buf_idx_i], + mask_inner_1, i_data->force_k_x_buf[buf_idx_i], f1x); + i_data->force_k_y_buf[buf_idx_i] = + fvec::mask_add(i_data->force_k_y_buf[buf_idx_i], mask_inner_1, + i_data->force_k_y_buf[buf_idx_i], f1y); + i_data->force_k_z_buf[buf_idx_i] = + fvec::mask_add(i_data->force_k_z_buf[buf_idx_i], mask_inner_1, + i_data->force_k_z_buf[buf_idx_i], f1z); + i_data->force_i_x = + fvec::mask_add(i_data->force_i_x, mask_inner_1, i_data->force_i_x, f2x); + i_data->force_i_y = + fvec::mask_add(i_data->force_i_y, mask_inner_1, i_data->force_i_y, f2y); + i_data->force_i_z = + fvec::mask_add(i_data->force_i_z, mask_inner_1, i_data->force_i_z, f2z); + j_data->force_i_x = + fvec::mask_add(j_data->force_i_x, mask_inner_1, j_data->force_i_x, f3x); + j_data->force_i_y = + fvec::mask_add(j_data->force_i_y, mask_inner_1, j_data->force_i_y, f3y); + j_data->force_i_z = + fvec::mask_add(j_data->force_i_z, mask_inner_1, j_data->force_i_z, f3z); + j_data->force_k_x_buf[buf_idx_j] = + fvec::mask_add(j_data->force_k_x_buf[buf_idx_j], mask_inner_1, + j_data->force_k_x_buf[buf_idx_j], f4x); + j_data->force_k_y_buf[buf_idx_j] = + fvec::mask_add(j_data->force_k_y_buf[buf_idx_j], mask_inner_1, + j_data->force_k_y_buf[buf_idx_j], f4y); + j_data->force_k_z_buf[buf_idx_j] = + fvec::mask_add(j_data->force_k_z_buf[buf_idx_j], mask_inner_1, + j_data->force_k_z_buf[buf_idx_j], f4z); + } + } + return sum_omega; +} + +static fvec aut_frebo_pi_dh( + KernelArgsAIREBOT * _noalias ka, + struct aut_frebo_data * _noalias i_data, + struct aut_frebo_data * _noalias j_data, + int itype, int jtype, ivec vi, ivec vj, + fvec r23x, fvec r23y, fvec r23z, fvec r23mag, + fvec VA, + fvec Nij, fvec Nji, fvec Nijconj, fvec NconjtmpI, fvec NconjtmpJ, + fvec fij[3] +) { + fvec c_TOL = fvec::set1(TOL); + fvec dN3[3]; + fvec Tij = aut_frebo_Tij(ka, itype, jtype, Nij, Nji, Nijconj, &dN3[0]); + bvec TijgtTOLmask = fvec::cmpnle(fvec::abs(Tij), c_TOL); + fvec sum_omega = fvec::setzero(); + if (bvec::test_any_set(TijgtTOLmask)) { + sum_omega = aut_frebo_sum_omega( + ka, i_data, j_data, itype, jtype, vi, vj, + r23x, r23y, r23z, r23mag, VA * Tij, fij); + sum_omega = fvec::mask_blend(TijgtTOLmask, fvec::setzero(), sum_omega); + aut_frebo_N_spline_force(ka, i_data, itype, jtype, vi, vj, VA * sum_omega, + dN3[0], dN3[2], NconjtmpI); + aut_frebo_N_spline_force(ka, j_data, jtype, itype, vj, vi, VA * sum_omega, + dN3[1], dN3[2], NconjtmpJ); + } + return Tij * sum_omega; +} + +/* + We can reuse the aut_frebo_data buffers here to do this calculation very + cheaply. +*/ +static void aut_torsion_vec( + KernelArgsAIREBOT * ka, + struct aut_frebo_data * i_data, + struct aut_frebo_data * j_data, + ivec i, ivec j, fvec wij, fvec dwij +) { + AtomAIREBOT * x = ka->x; + int * map = ka->map; + flt_t (*epsilonT)[2] = ka->params.epsilonT; + fvec epsilonT00 = fvec::set1(epsilonT[0][0]); + fvec epsilonT01 = fvec::set1(epsilonT[0][1]); + fvec epsilonT10 = fvec::set1(epsilonT[1][0]); + fvec epsilonT11 = fvec::set1(epsilonT[1][1]); + fvec thmin = fvec::set1(ka->params.thmin); + fvec thmax = fvec::set1(ka->params.thmax); + + const fvec c_1_0 = fvec::set1(1.0); + const fvec c_0_5 = fvec::set1(0.5); + const fvec c_0_1 = fvec::set1(0.1); + const fvec c_2_0 = fvec::set1(2.0); + const fvec c_2_5 = fvec::set1(2.5); + const fvec c_256_405 = fvec::set1(256.0/405.0); + + fvec del32x = j_data->x_i - i_data->x_i; + fvec del32y = j_data->y_i - i_data->y_i; + fvec del32z = j_data->z_i - i_data->z_i; + fvec rsq = del32x * del32x + del32y * del32y + del32z * del32z; + fvec r32 = fvec::sqrt(rsq); + fvec del23x = fvec::setzero() - del32x; + fvec del23y = fvec::setzero() - del32y; + fvec del23z = fvec::setzero() - del32z; + fvec r23 = r32; + fvec w23 = wij; + fvec dw23 = dwij; + + for (int buf_idx_i = 0; buf_idx_i < i_data->buf_len; buf_idx_i++) { + bvec mask_start = i_data->mask_buf[buf_idx_i]; + fvec del21x = i_data->rikx_buf[buf_idx_i]; // a2 - a1 -> i - k + fvec del21y = i_data->riky_buf[buf_idx_i]; // a2 - a1 -> i - k + fvec del21z = i_data->rikz_buf[buf_idx_i]; // a2 - a1 -> i - k + fvec r21 = i_data->rikmag_buf[buf_idx_i]; + fvec cos321 = i_data->cosjik_buf[buf_idx_i]; + fvec sin321 = fvec::sqrt(c_1_0 - cos321 * cos321); + // strictly equivalent to sin321 < TOL + mask_start = fvec::mask_cmpneq(mask_start, fvec::setzero(), sin321); + if (! bvec::test_any_set(mask_start)) continue; + + fvec deljkx = del21x - del23x; + fvec deljky = del21y - del23y; + fvec deljkz = del21z - del23z; + fvec rjk2 = deljkx * deljkx + deljky * deljky + deljkz * deljkz; + fvec rjk = fvec::sqrt(rjk2); + fvec rik2 = r21 * r21; + fvec w21 = i_data->wik_buf[buf_idx_i]; + fvec dw21 = i_data->dwik_buf[buf_idx_i]; + + fvec rij = r32; + fvec rik = r21; + fvec rij2 = r32 * r32; + fvec dtsjik; + fvec tspjik = aut_Sp2_deriv(cos321, thmin, thmax, &dtsjik); + dtsjik = fvec::setzero() - dtsjik; + + bvec ktype_mask = i_data->ktype_buf[buf_idx_i]; + fvec epsilonT0 = fvec::mask_blend(ktype_mask, epsilonT00, epsilonT10); + fvec epsilonT1 = fvec::mask_blend(ktype_mask, epsilonT01, epsilonT11); + + ivec k = i_data->k_buf[buf_idx_i]; + for (int buf_idx_j = 0; buf_idx_j < j_data->buf_len; buf_idx_j++) { + ivec l = j_data->k_buf[buf_idx_j]; + bvec mask_inner_0 = ivec::mask_cmpneq(mask_start, k, l) & + j_data->mask_buf[buf_idx_j]; + if (! bvec::test_any_set(mask_inner_0)) continue; + fvec del34x = j_data->rikx_buf[buf_idx_j]; + fvec del34y = j_data->riky_buf[buf_idx_j]; + fvec del34z = j_data->rikz_buf[buf_idx_j]; + fvec r34 = j_data->rikmag_buf[buf_idx_j]; + bvec ltype_mask = j_data->ktype_buf[buf_idx_j]; + fvec cos234 = j_data->cosjik_buf[buf_idx_j]; + fvec sin234 = fvec::sqrt(c_1_0 - cos234 * cos234); + // strictly equivalent to sin234 < TOL + mask_inner_0 = fvec::mask_cmpneq(mask_inner_0, sin234, fvec::setzero()); + if (! bvec::test_any_set(mask_inner_0)) continue; + fvec dw34 = j_data->dwik_buf[buf_idx_j]; + fvec w34 = j_data->wik_buf[buf_idx_j]; + fvec delilx = del23x + del34x; + fvec delily = del23y + del34y; + fvec delilz = del23z + del34z; + fvec ril2 = delilx * delilx + delily * delily + delilz * delilz; + fvec ril = fvec::sqrt(ril2); + fvec rjl2 = r34 * r34; + + fvec rjl = r34; + fvec dtsijl; + fvec tspijl = aut_Sp2_deriv(cos234, thmin, thmax, &dtsijl); + dtsijl = fvec::setzero() - dtsijl; + fvec cross321x = del32y * del21z - del32z * del21y; + fvec cross321y = del32z * del21x - del32x * del21z; + fvec cross321z = del32x * del21y - del32y * del21x; + fvec cross321mag = fvec::sqrt(cross321x * cross321x + + cross321y * cross321y + + cross321z * cross321z); + fvec cross234x = del23y * del34z - del23z * del34y; + fvec cross234y = del23z * del34x - del23x * del34z; + fvec cross234z = del23x * del34y - del23y * del34x; + fvec cross234mag = fvec::sqrt(cross234x * cross234x + + cross234y * cross234y + + cross234z * cross234z); + fvec cwnum = cross321x * cross234x + cross321y * cross234y + + cross321z * cross234z; + fvec cwnom = r21 * r34 * r32 * r32 * sin321 * sin234; + fvec cw = cwnum / cwnom; + + fvec cw2 = c_0_5 * ( c_1_0 - cw); + fvec ekijl = fvec::mask_blend(ltype_mask, epsilonT0, epsilonT1); + fvec Ec = c_256_405 * ekijl; + fvec cw2_5 = cw2 * cw2 * cw2 * cw2 * cw2; + fvec Vtors = Ec * cw2_5 - ekijl * c_0_1; + + fvec evdwl = Vtors * w21 * w23 * w34 * (c_1_0-tspjik) * (c_1_0-tspijl); + ka->result_eng += fvec::mask_reduce_add(mask_inner_0, evdwl); + + fvec dndijx = cross234y * del21z - cross234z * del21y; + fvec dndijy = cross234z * del21x - cross234x * del21z; + fvec dndijz = cross234x * del21y - cross234y * del21x; + + fvec tmpvecx = del34y * cross321z - del34z * cross321y; + fvec tmpvecy = del34z * cross321x - del34x * cross321z; + fvec tmpvecz = del34x * cross321y - del34y * cross321x; + + dndijx = dndijx + tmpvecx; + dndijy = dndijy + tmpvecy; + dndijz = dndijz + tmpvecz; + + fvec dndikx = del23y * cross234z - del23z * cross234y; + fvec dndiky = del23z * cross234x - del23x * cross234z; + fvec dndikz = del23x * cross234y - del23y * cross234x; + + fvec dndjlx = cross321y * del23z - cross321z * del23y; + fvec dndjly = cross321z * del23x - cross321x * del23z; + fvec dndjlz = cross321x * del23y - cross321y * del23x; + + fvec r23sq = r23 * r23; + fvec r21sq = r21 * r21; + fvec r34sq = r34 * r34; + fvec rjksq = rjk * rjk; + fvec rilsq = ril * ril; + fvec dcidij = (r23sq - r21sq + rjksq) / ( c_2_0 * r23sq * r21); + fvec dcidik = (r21sq - r23sq + rjksq) / ( c_2_0 * r21sq * r23); + fvec dcidjk = fvec::setzero() - rjk / ( r23 * r21); + fvec dcjdji = (r23sq - r34sq + rilsq) / ( c_2_0 * r23sq * r34); + fvec dcjdjl = (r34sq - r23sq + rilsq) / ( c_2_0 * r34sq * r23); + fvec dcjdil = fvec::setzero() - ril / ( r23 * r34); + + fvec dsidij = fvec::setzero() - cos321 / sin321 * dcidij; + fvec dsidik = fvec::setzero() - cos321 / sin321 * dcidik; + fvec dsidjk = fvec::setzero() - cos321 / sin321 * dcidjk; + + fvec dsjdji = fvec::setzero() - cos234 / sin234 * dcjdji; + fvec dsjdjl = fvec::setzero() - cos234 / sin234 * dcjdjl; + fvec dsjdil = fvec::setzero() - cos234 / sin234 * dcjdil; + + fvec dxidij = r21 * sin321 + r23 * r21 * dsidij; + fvec dxidik = r23 * sin321 + r23 * r21 * dsidik; + fvec dxidjk = r23 * r21 * dsidjk; + + fvec dxjdji = r34 * sin234 + r23 * r34 * dsjdji; + fvec dxjdjl = r23 * sin234 + r23 * r34 * dsjdjl; + fvec dxjdil = r23 * r34 * dsjdil; + + fvec ddndij = dxidij * cross234mag + cross321mag * dxjdji; + fvec ddndik = dxidik * cross234mag; + fvec ddndjk = dxidjk * cross234mag; + fvec ddndjl = cross321mag * dxjdjl; + fvec ddndil = cross321mag * dxjdil; + fvec dcwddn = fvec::setzero() - cwnum / ( cwnom * cwnom); + fvec dcwdn = fvec::recip(cwnom); + fvec cw2_4 = cw2 * cw2 * cw2 * cw2; + fvec dvpdcw = c_2_5 * Ec * cw2_4 * w23 * w21 * w34 * (c_1_0 - tspjik) * + (c_1_0 - tspijl); + + fvec Ftmpx = dvpdcw * (dcwdn * dndijx + dcwddn * ddndij * del23x / r23); + fvec Ftmpy = dvpdcw * (dcwdn * dndijy + dcwddn * ddndij * del23y / r23); + fvec Ftmpz = dvpdcw * (dcwdn * dndijz + dcwddn * ddndij * del23z / r23); + fvec fix = Ftmpx; + fvec fiy = Ftmpy; + fvec fiz = Ftmpz; + fvec fjx = fvec::setzero() - Ftmpx; + fvec fjy = fvec::setzero() - Ftmpy; + fvec fjz = fvec::setzero() - Ftmpz; + + Ftmpx = dvpdcw * (dcwdn * dndikx + dcwddn * ddndik * del21x / r21); + Ftmpy = dvpdcw * (dcwdn * dndiky + dcwddn * ddndik * del21y / r21); + Ftmpz = dvpdcw * (dcwdn * dndikz + dcwddn * ddndik * del21z / r21); + fix = fix + Ftmpx; + fiy = fiy + Ftmpy; + fiz = fiz + Ftmpz; + fvec fkx = fvec::setzero() - Ftmpx; + fvec fky = fvec::setzero() - Ftmpy; + fvec fkz = fvec::setzero() - Ftmpz; + + Ftmpx = dvpdcw * dcwddn * ddndjk * deljkx / rjk; + Ftmpy = dvpdcw * dcwddn * ddndjk * deljky / rjk; + Ftmpz = dvpdcw * dcwddn * ddndjk * deljkz / rjk; + fjx = fjx + Ftmpx; + fjy = fjy + Ftmpy; + fjz = fjz + Ftmpz; + fkx = fkx - Ftmpx; + fky = fky - Ftmpy; + fkz = fkz - Ftmpz; + + Ftmpx = dvpdcw * (dcwdn * dndjlx + dcwddn * ddndjl * del34x / r34); + Ftmpy = dvpdcw * (dcwdn * dndjly + dcwddn * ddndjl * del34y / r34); + Ftmpz = dvpdcw * (dcwdn * dndjlz + dcwddn * ddndjl * del34z / r34); + fjx = fjx + Ftmpx; + fjy = fjy + Ftmpy; + fjz = fjz + Ftmpz; + fvec flx = fvec::setzero() - Ftmpx; + fvec fly = fvec::setzero() - Ftmpy; + fvec flz = fvec::setzero() - Ftmpz; + + Ftmpx = dvpdcw * dcwddn * ddndil * delilx / ril; + Ftmpy = dvpdcw * dcwddn * ddndil * delily / ril; + Ftmpz = dvpdcw * dcwddn * ddndil * delilz / ril; + fix = fix + Ftmpx; + fiy = fiy + Ftmpy; + fiz = fiz + Ftmpz; + flx = flx - Ftmpx; + fly = fly - Ftmpy; + flz = flz - Ftmpz; + + // coordination forces + + fvec fpair = Vtors * dw21 * w23 * w34 * (c_1_0 - tspjik) * + (c_1_0 - tspijl) / r21; + fix = fix - del21x * fpair; + fiy = fiy - del21y * fpair; + fiz = fiz - del21z * fpair; + fkx = fkx + del21x * fpair; + fky = fky + del21y * fpair; + fkz = fkz + del21z * fpair; + + fpair = Vtors * w21 * dw23 * w34 * (c_1_0 - tspjik) * (c_1_0 - tspijl) / + r23; + fix = fix - del23x * fpair; + fiy = fiy - del23y * fpair; + fiz = fiz - del23z * fpair; + fjx = fjx + del23x * fpair; + fjy = fjy + del23y * fpair; + fjz = fjz + del23z * fpair; + + fpair = Vtors * w21 * w23 * dw34 * (c_1_0 - tspjik) * (c_1_0 - tspijl) / + r34; + fjx = fjx - del34x * fpair; + fjy = fjy - del34y * fpair; + fjz = fjz - del34z * fpair; + flx = flx + del34x * fpair; + fly = fly + del34y * fpair; + flz = flz + del34z * fpair; + + // additional cut off function forces + + fvec fcpc = fvec::setzero() - Vtors * w21 * w23 * w34 * dtsjik * (c_1_0 - + tspijl); + fpair = fcpc * dcidij / rij; + fix = fix + fpair * del23x; + fiy = fiy + fpair * del23y; + fiz = fiz + fpair * del23z; + fjx = fjx - fpair * del23x; + fjy = fjy - fpair * del23y; + fjz = fjz - fpair * del23z; + + fpair = fcpc * dcidik / rik; + fix = fix + fpair * del21x; + fiy = fiy + fpair * del21y; + fiz = fiz + fpair * del21z; + fkx = fkx - fpair * del21x; + fky = fky - fpair * del21y; + fkz = fkz - fpair * del21z; + + fpair = fcpc * dcidjk / rjk; + fjx = fjx + fpair * deljkx; + fjy = fjy + fpair * deljky; + fjz = fjz + fpair * deljkz; + fkx = fkx - fpair * deljkx; + fky = fky - fpair * deljky; + fkz = fkz - fpair * deljkz; + + fcpc = fvec::setzero() - Vtors * w21 * w23 * w34 * (c_1_0 - tspjik) * + dtsijl; + fpair = fcpc * dcjdji / rij; + fix = fix + fpair * del23x; + fiy = fiy + fpair * del23y; + fiz = fiz + fpair * del23z; + fjx = fjx - fpair * del23x; + fjy = fjy - fpair * del23y; + fjz = fjz - fpair * del23z; + + fpair = fcpc * dcjdjl / rjl; + fjx = fjx + fpair * del34x; + fjy = fjy + fpair * del34y; + fjz = fjz + fpair * del34z; + flx = flx - fpair * del34x; + fly = fly - fpair * del34y; + flz = flz - fpair * del34z; + + fpair = fcpc * dcjdil / ril; + fix = fix + fpair * delilx; + fiy = fiy + fpair * delily; + fiz = fiz + fpair * delilz; + flx = flx - fpair * delilx; + fly = fly - fpair * delily; + flz = flz - fpair * delilz; + + // sum per-atom forces into atom force array + + i_data->force_i_x = fvec::mask_add(i_data->force_i_x, mask_inner_0, + i_data->force_i_x, fix); + i_data->force_i_y = fvec::mask_add(i_data->force_i_y, mask_inner_0, + i_data->force_i_y, fiy); + i_data->force_i_z = fvec::mask_add(i_data->force_i_z, mask_inner_0, + i_data->force_i_z, fiz); + i_data->force_j_x = fvec::mask_add(i_data->force_j_x, mask_inner_0, + i_data->force_j_x, fjx); + i_data->force_j_y = fvec::mask_add(i_data->force_j_y, mask_inner_0, + i_data->force_j_y, fjy); + i_data->force_j_z = fvec::mask_add(i_data->force_j_z, mask_inner_0, + i_data->force_j_z, fjz); + i_data->force_k_x_buf[buf_idx_i] = + fvec::mask_add(i_data->force_k_x_buf[buf_idx_i], mask_inner_0, + i_data->force_k_x_buf[buf_idx_i], fkx); + i_data->force_k_y_buf[buf_idx_i] = + fvec::mask_add(i_data->force_k_y_buf[buf_idx_i], mask_inner_0, + i_data->force_k_y_buf[buf_idx_i], fky); + i_data->force_k_z_buf[buf_idx_i] = + fvec::mask_add(i_data->force_k_z_buf[buf_idx_i], mask_inner_0, + i_data->force_k_z_buf[buf_idx_i], fkz); + j_data->force_k_x_buf[buf_idx_j] = + fvec::mask_add(j_data->force_k_x_buf[buf_idx_j], mask_inner_0, + j_data->force_k_x_buf[buf_idx_j], flx); + j_data->force_k_y_buf[buf_idx_j] = + fvec::mask_add(j_data->force_k_y_buf[buf_idx_j], mask_inner_0, + j_data->force_k_y_buf[buf_idx_j], fly); + j_data->force_k_z_buf[buf_idx_j] = + fvec::mask_add(j_data->force_k_z_buf[buf_idx_j], mask_inner_0, + j_data->force_k_z_buf[buf_idx_j], flz); + } + } +} + +/* + * Processes VL elements of the same type itype/jtype for REBO and TORSION + * interactions. This allows us to reuse the aut_frebo_data buffes in the + * torsion calculaltion. + */ +static void aut_frebo_batch_of_kind(KernelArgsAIREBOT * ka, + int torflag, int itype, int jtype, + int * i_buf, int * j_buf) { + { // jump-scope for exceed_limits + AtomAIREBOT * x = ka->x; + int * tag = ka->tag; + int * map = ka->map; + ResultForceT * result_f = ka->result_f; + flt_t rcminij = ka->params.rcmin[itype][jtype]; + flt_t rcmaxij = ka->params.rcmax[itype][jtype]; + flt_t Qij = ka->params.Q[itype][jtype]; + flt_t Aij = ka->params.A[itype][jtype]; + flt_t alphaij = ka->params.alpha[itype][jtype]; + fvec vrcminij = fvec::set1(ka->params.rcmin[itype][jtype]); + fvec vrcmaxij = fvec::set1(ka->params.rcmax[itype][jtype]); + fvec vQij = fvec::set1(ka->params.Q[itype][jtype]); + fvec vAij = fvec::set1(ka->params.A[itype][jtype]); + fvec malphaij = fvec::set1(-ka->params.alpha[itype][jtype]); + fvec c_1_0 = fvec::set1(1); + fvec c_0_5 = fvec::set1(0.5); + fvec c_TOL = fvec::set1(1e-9); + struct aut_frebo_data i_data, j_data; + + fvec evdwl_vacc = fvec::setzero(); + ivec vi = ivec::maskz_loadu(bvec::full(), i_buf); + int tmp; + ivec vj = ivec::maskz_loadu(bvec::full(), j_buf); + fvec x_i, y_i, z_i; + fvec x_j, y_j, z_j; + aut_loadatoms_vec_notype(x, vi, &x_i, &y_i, &z_i); + aut_loadatoms_vec_notype(x, vj, &x_j, &y_j, &z_j); + i_data.x_i = x_i; + i_data.y_i = y_i; + i_data.z_i = z_i; + i_data.x_j = x_j; + i_data.y_j = y_j; + i_data.z_j = z_j; + j_data.x_i = x_j; + j_data.y_i = y_j; + j_data.z_i = z_j; + j_data.x_j = x_i; + j_data.y_j = y_i; + j_data.z_j = z_i; + fvec delx = x_i - x_j; + fvec dely = y_i - y_j; + fvec delz = z_i - z_j; + fvec rsq = delx * delx + dely * dely + delz * delz; + fvec rij = fvec::sqrt(rsq); + fvec dwij; + fvec wij = aut_Sp_deriv(rij, vrcminij, vrcmaxij, &dwij); + + fvec exp_alphar = fvec::exp(malphaij * rij); + fvec Qij_over_rij = vQij / rij; + fvec Qij_over_rsq = vQij / rsq; + fvec VR_by_wij = ( c_1_0 + Qij_over_rij) * vAij * exp_alphar; + fvec VR = wij * VR_by_wij; + fvec pre = wij * vAij * exp_alphar; + fvec dVRdi = pre * ( malphaij + malphaij * Qij_over_rij - Qij_over_rsq); + dVRdi = dVRdi + VR_by_wij * dwij; + + fvec VA_by_wij = fvec::setzero(); + fvec dVA = fvec::setzero(); + + int k; + for (k = 0; k < 3; k++) { + fvec mBIJc = fvec::set1(-ka->params.BIJc[itype][jtype][k]); + fvec mBetaij = fvec::set1(-ka->params.Beta[itype][jtype][k]); + fvec term = mBIJc * fvec::exp(mBetaij * rij); + VA_by_wij = VA_by_wij + term; + dVA = dVA + mBetaij * wij * term; + } + + dVA = dVA + dwij * VA_by_wij; + fvec VA = wij * VA_by_wij; + + bvec tol_check = fvec::cmplt(wij, c_TOL); + VA = fvec::mask_blend(tol_check, VA, fvec::setzero()); + dVA = fvec::mask_blend(tol_check, dVA, fvec::setzero()); + VR = fvec::mask_blend(tol_check, VR, fvec::setzero()); + dVRdi = fvec::mask_blend(tol_check, dVRdi, fvec::setzero()); + + fvec nHi = fvec::gather(vi, ka->nH, sizeof(flt_t)); + fvec nCi = fvec::gather(vi, ka->nC, sizeof(flt_t)); + fvec nHj = fvec::gather(vj, ka->nH, sizeof(flt_t)); + fvec nCj = fvec::gather(vj, ka->nC, sizeof(flt_t)); + fvec Nij = (nHi + nCi) - wij; + fvec Nji = (nHj + nCj) - wij; + i_data.nHi = nHi; + i_data.nCi = nCi; + j_data.nHi = nHj; + j_data.nCi = nCj; + fvec fij[3], fji[3]; + fij[0] = fvec::setzero(); fij[1] = fvec::setzero(); + fij[2] = fvec::setzero(); + fji[0] = fvec::setzero(); fji[1] = fvec::setzero(); + fji[2] = fvec::setzero(); + + fvec NconjtmpI; + fvec pij = aut_frebo_pij_pd_2( + ka, &i_data, itype, jtype, vi, vj, + delx, dely, delz, rij, wij, VA, &NconjtmpI, fij); + + if (i_data.buf_len < 0) goto exceed_limits; + + fvec NconjtmpJ; + fvec rjix = fvec::setzero() - delx; + fvec rjiy = fvec::setzero() - dely; + fvec rjiz = fvec::setzero() - delz; + fvec pji = aut_frebo_pij_pd_2( + ka, &j_data, jtype, itype, vj, vi, + rjix, rjiy, rjiz, rij, wij, VA, &NconjtmpJ, fji); + fij[0] = fij[0] - fji[0]; + fij[1] = fij[1] - fji[1]; + fij[2] = fij[2] - fji[2]; + + if (j_data.buf_len < 0) goto exceed_limits; + + if (torflag && itype == 0 && jtype == 0) + aut_torsion_vec(ka, &i_data, &j_data, vi, vj, wij, dwij); + + fvec Nijconj = c_1_0 + NconjtmpI * NconjtmpI + NconjtmpJ * NconjtmpJ; + fvec dN3[3]; + fvec pi_rc = aut_frebo_pi_rc_pd(ka, itype, jtype, Nij, Nji, Nijconj, dN3); + aut_frebo_N_spline_force(ka, &i_data, itype, jtype, vi, vj, VA, dN3[0], + dN3[2], NconjtmpI); + aut_frebo_N_spline_force(ka, &j_data, jtype, itype, vj, vi, VA, dN3[1], + dN3[2], NconjtmpJ); + fvec pi_dh = aut_frebo_pi_dh(ka, &i_data, &j_data, itype, jtype, vi, vj, + delx, dely, delz, rij, VA, Nij, Nji, Nijconj, + NconjtmpI, NconjtmpJ, fij); + + fvec bij = c_0_5 * ( pij + pji) + pi_rc + pi_dh; + fvec dVAdi = bij * dVA; + fvec fpair = (dVAdi + dVRdi) * fvec::recip(rij); + fvec result_f_j_x = fpair * delx - fij[0]; + fvec result_f_j_y = fpair * dely - fij[1]; + fvec result_f_j_z = fpair * delz - fij[2]; + fvec result_f_i_x = fvec::setzero() - result_f_j_x; + fvec result_f_i_y = fvec::setzero() - result_f_j_y; + fvec result_f_i_z = fvec::setzero() - result_f_j_z; + fvec evdwl = VR + bij * VA; + evdwl_vacc = evdwl_vacc + evdwl; + + aut_frebo_data_writeback(ka, &i_data); + aut_frebo_data_writeback(ka, &j_data); + + flt_t fi_x_buf[fvec::VL] __attribute__((aligned(64))); + flt_t fi_y_buf[fvec::VL] __attribute__((aligned(64))); + flt_t fi_z_buf[fvec::VL] __attribute__((aligned(64))); + int fi_i_buf[ivec::VL] __attribute__((aligned(64))); + flt_t fj_x_buf[fvec::VL] __attribute__((aligned(64))); + flt_t fj_y_buf[fvec::VL] __attribute__((aligned(64))); + flt_t fj_z_buf[fvec::VL] __attribute__((aligned(64))); + int fj_j_buf[ivec::VL] __attribute__((aligned(64))); + flt_t evdwl_buf[fvec::VL] __attribute__((aligned(64))); + + result_f_i_x = i_data.force_i_x + result_f_i_x; + result_f_i_y = i_data.force_i_y + result_f_i_y; + result_f_i_z = i_data.force_i_z + result_f_i_z; + result_f_j_x = i_data.force_j_x + result_f_j_x; + result_f_j_y = i_data.force_j_y + result_f_j_y; + result_f_j_z = i_data.force_j_z + result_f_j_z; + + result_f_i_x = j_data.force_j_x + result_f_i_x; + result_f_i_y = j_data.force_j_y + result_f_i_y; + result_f_i_z = j_data.force_j_z + result_f_i_z; + result_f_j_x = j_data.force_i_x + result_f_j_x; + result_f_j_y = j_data.force_i_y + result_f_j_y; + result_f_j_z = j_data.force_i_z + result_f_j_z; + + fvec::store(fi_x_buf, result_f_i_x); + fvec::store(fi_y_buf, result_f_i_y); + fvec::store(fi_z_buf, result_f_i_z); + ivec::store(fi_i_buf, vi); + fvec::store(fj_x_buf, result_f_j_x); + fvec::store(fj_y_buf, result_f_j_y); + fvec::store(fj_z_buf, result_f_j_z); + ivec::store(fj_j_buf, vj); + fvec::store(evdwl_buf, evdwl); + + int lane; + for (lane = 0; lane < fvec::VL; lane++) { + int ii = fi_i_buf[lane]; + result_f[ii].x += fi_x_buf[lane]; + result_f[ii].y += fi_y_buf[lane]; + result_f[ii].z += fi_z_buf[lane]; + result_f[ii].w += 0.5 * evdwl_buf[lane]; + int jj = fj_j_buf[lane]; + result_f[jj].x += fj_x_buf[lane]; + result_f[jj].y += fj_y_buf[lane]; + result_f[jj].z += fj_z_buf[lane]; + result_f[jj].w += 0.5 * evdwl_buf[lane]; + } + ka->result_eng += fvec::reduce_add(evdwl_vacc); + return; + } +exceed_limits: + for (int l = 0; l < fvec::VL; l++) { + int i = i_buf[l]; + int j = j_buf[l]; + ref_frebo_single_interaction(ka, i, j); + if (torflag && itype == 0 && jtype == 0) + ref_torsion_single_interaction(ka, i, j); + } +} + +/* + Orders the interactions by itype and jtype and passes chunks to the above + method. +*/ +static void aut_frebo(KernelArgsAIREBOT * ka, int torflag) { + AtomAIREBOT * _noalias x = ka->x; + int * _noalias tag = ka->tag; + int * _noalias map = ka->map; + int i_buf[2][2][fvec::VL]; + int j_buf[2][2][fvec::VL]; + int n_buf[2][2] = {0}; + for (int i = ka->frebo_from_atom; i < ka->frebo_to_atom; i++) { + int itag = tag[i]; + int itype = map[x[i].w]; + flt_t x_i = x[i].x; + flt_t y_i = x[i].y; + flt_t z_i = x[i].z; + int * neighs = ka->neigh_rebo.entries + ka->neigh_rebo.offset[i]; + int jnum = ka->neigh_rebo.num[i]; + for (int jj = 0; jj < jnum; jj++) { + int j = neighs[jj]; + int jtag = tag[j]; + if (itag > jtag) { + if (((itag + jtag) & 1) == 0) + continue; + } else if (itag < jtag) { + if (((itag + jtag) & 1) == 1) + continue; + } else { + if (x[j].z < z_i) + continue; + if (x[j].z == z_i && x[j].y < y_i) + continue; + if (x[j].z == z_i && x[j].y == y_i && x[j].x < x_i) + continue; + } + int jtype = map[x[j].w]; + int ins = n_buf[itype][jtype]; + i_buf[itype][jtype][ins] = i; + j_buf[itype][jtype][ins] = j; + n_buf[itype][jtype] += 1; + if (n_buf[itype][jtype] == fvec::VL) { + aut_frebo_batch_of_kind(ka, torflag, itype, jtype, + i_buf[itype][jtype], j_buf[itype][jtype]); + n_buf[itype][jtype] = 0; + } + } + } + for (int itype = 0; itype < 2; itype++) { + for (int jtype = 0; jtype < 2; jtype++) { + for (int l = 0; l < n_buf[itype][jtype]; l++) { + int i = i_buf[itype][jtype][l]; + int j = j_buf[itype][jtype][l]; + ref_frebo_single_interaction(ka, i, j); + if (torflag && itype == 0 && jtype == 0) + ref_torsion_single_interaction(ka, i, j); + } + } + } +} + +/* + * Apply paths in scalar fashion, not crucial for performance. + */ +static void aut_airebo_lj_force_path(KernelArgsAIREBOT * ka, + bvec mask, fvec dC, LennardJonesPathAIREBOT path[fvec::VL]) { + for (int i = 0; i < fvec::VL; i++) { + if (bvec::test_at(mask, i)) { + ref_lennard_jones_force_path(ka, fvec::at(dC, i), &path[i]); + } + } +} + +/* + * Hash-Map for efficient calculation of C_ij. + * Can have up to ITEMS entries with associated paths, as well as + * 1024 entries. Open addressing, invalidation by using a different i. + * Only needs to be reset once per timestep. + */ +static const int OPT_TEST_PATH_SIZE = 1024; +static const int OPT_TEST_PATH_ITEMS = 128; +struct aut_airebo_lj_test_path_result_data { + LennardJonesPathAIREBOT testpath[OPT_TEST_PATH_ITEMS]; + int i[OPT_TEST_PATH_SIZE]; + int j[OPT_TEST_PATH_SIZE]; + flt_t cij[OPT_TEST_PATH_SIZE]; + int testpath_idx[OPT_TEST_PATH_SIZE]; +}; +static const unsigned int OPT_TEST_PATH_HASH = 2654435761; + +static int aut_lj_tap_hash_fn(int j, int attempt) { + uint32_t result = j; + result *= (uint32_t) OPT_TEST_PATH_HASH; + result += (uint32_t) attempt; + result %= (uint32_t) OPT_TEST_PATH_SIZE; + return result; +} + +static ivec aut_airebo_lj_tap_hash_fn_vec(ivec val, ivec attempt) { + const ivec golden = ivec::set1(OPT_TEST_PATH_HASH); + const ivec mask = ivec::set1(OPT_TEST_PATH_SIZE - 1); + ivec a = ivec::mullo(golden, val); + ivec b = a + attempt; + ivec c = ivec::the_and(b, mask); + return c; +} + +/* + * Enter all those (potential) neighbors of i (including 2nd and 3rd degree) + * into the hash-map. There is no good way to vectorize this, and it does not + * seem time-critical. + */ +static bool aut_airebo_lj_test_all_paths(KernelArgsAIREBOT * ka, + int i, struct aut_airebo_lj_test_path_result_data * result) { + AtomAIREBOT * x = ka->x; + int * map = ka->map; + flt_t (*rcmin)[2] = &ka->params.rcmin[0]; + flt_t (*rcmax)[2] = &ka->params.rcmax[0]; + flt_t rcminsq[2][2]; + rcminsq[0][0] = rcmin[0][0] * rcmin[0][0]; + rcminsq[0][1] = rcmin[0][1] * rcmin[0][1]; + rcminsq[1][0] = rcmin[1][0] * rcmin[1][0]; + rcminsq[1][1] = rcmin[1][1] * rcmin[1][1]; + int * neighs_i = &ka->neigh_rebo.entries[ka->neigh_rebo.offset[i]]; + int itype = map[x[i].w]; + int path_insert_pos = 0; + for (int jj = 0; jj < ka->neigh_rebo.num[i]; jj++) { + int j = neighs_i[jj]; + int jtype = map[x[j].w]; + flt_t dijx = x[j].x - x[i].x; + flt_t dijy = x[j].y - x[i].y; + flt_t dijz = x[j].z - x[i].z; + flt_t rijsq = dijx * dijx + dijy * dijy + dijz * dijz; + flt_t wj = 1, dwj = 0; + flt_t rij = 0; + if (rijsq >= rcminsq[itype][jtype]) { + rij = overloaded::sqrt(rijsq); + wj = Sp(rij, rcmin[itype][jtype], rcmax[itype][jtype], &dwj); + } + int attempt = 0; + int start_hash_slot = aut_lj_tap_hash_fn(j, attempt); + int hash_slot = start_hash_slot; + while (result->i[hash_slot] == i && result->j[hash_slot] != j && + attempt < OPT_TEST_PATH_SIZE) { + hash_slot = aut_lj_tap_hash_fn(j, ++attempt); + } + if (attempt >= OPT_TEST_PATH_SIZE) goto exceed_limits; + bool init_slot = result->i[hash_slot] != i; + if (init_slot || (1 - wj < result->cij[hash_slot])) { + result->i[hash_slot] = i; + result->j[hash_slot] = j; + result->cij[hash_slot] = 1 - wj; + if (wj != 1.0) { + if (path_insert_pos >= OPT_TEST_PATH_ITEMS) goto exceed_limits; + result->testpath_idx[hash_slot] = path_insert_pos; + LennardJonesPathAIREBOT *path = + &result->testpath[path_insert_pos++]; + path->num = 2; + path->del[0].x = dijx; + path->del[0].y = dijy; + path->del[0].z = dijz; + if (rij == 0) rij = sqrt(rijsq); + path->r[0] = rij; + path->w[0] = wj; + path->dw[0] = dwj; + path->idx[0] = i; + path->idx[1] = j; + } + } + int * neighs_j = &ka->neigh_rebo.entries[ka->neigh_rebo.offset[j]]; + for (int kk = 0; kk < ka->neigh_rebo.num[j]; kk++) { + int k = neighs_j[kk]; + if (k == i) continue; + int ktype = map[x[k].w]; + flt_t djkx = x[k].x - x[j].x; + flt_t djky = x[k].y - x[j].y; + flt_t djkz = x[k].z - x[j].z; + flt_t rjksq = djkx * djkx + djky * djky + djkz * djkz; + flt_t wk = 1, dwk = 0; + flt_t rjk = 0; + if (rjksq >= rcminsq[jtype][ktype]) { + rjk = overloaded::sqrt(rjksq); + wk = Sp(rjk, rcmin[jtype][ktype], rcmax[jtype][ktype], &dwk); + } + int attempt = 0; + int start_hash_slot = aut_lj_tap_hash_fn(k, attempt); + int hash_slot = start_hash_slot; + while (result->i[hash_slot] == i && result->j[hash_slot] != k && + attempt < OPT_TEST_PATH_SIZE) { + hash_slot = aut_lj_tap_hash_fn(k, ++attempt); + } + if (attempt >= OPT_TEST_PATH_SIZE) goto exceed_limits; + bool init_slot = result->i[hash_slot] != i; + if (init_slot || (1 - wj * wk < result->cij[hash_slot])) { + result->i[hash_slot] = i; + result->j[hash_slot] = k; + result->cij[hash_slot] = 1 - wj * wk; + if (wj * wk != 1.0) { + if (path_insert_pos >= OPT_TEST_PATH_ITEMS) goto exceed_limits; + result->testpath_idx[hash_slot] = path_insert_pos; + LennardJonesPathAIREBOT *path = + &result->testpath[path_insert_pos++]; + path->num = 3; + path->del[0].x = dijx; + path->del[0].y = dijy; + path->del[0].z = dijz; + if (rij == 0) rij = sqrt(rijsq); + path->r[0] = rij; + path->del[1].x = djkx; + path->del[1].y = djky; + path->del[1].z = djkz; + if (rjk == 0) rjk = sqrt(rjksq); + path->r[1] = rjk; + path->w[0] = wj; + path->dw[0] = dwj; + path->w[1] = wk; + path->dw[1] = dwk; + path->idx[0] = i; + path->idx[1] = j; + path->idx[2] = k; + } + } + int * neighs_k = &ka->neigh_rebo.entries[ka->neigh_rebo.offset[k]]; + for (int ll = 0; ll < ka->neigh_rebo.num[k]; ll++) { + int l = neighs_k[ll]; + if ((l == i) || (l == j)) continue; + int ltype = map[x[l].w]; + flt_t dklx = x[l].x - x[k].x; + flt_t dkly = x[l].y - x[k].y; + flt_t dklz = x[l].z - x[k].z; + flt_t rklsq = dklx * dklx + dkly * dkly + dklz * dklz; + flt_t wl = 1, dwl = 0; + flt_t rkl = 0; + if (rklsq >= rcminsq[ktype][ltype]) { + rkl = overloaded::sqrt(rklsq); + wl = Sp(rkl, rcmin[ktype][ltype], rcmax[ktype][ltype], &dwl); + } + int attempt = 0; + int start_hash_slot = aut_lj_tap_hash_fn(l, attempt); + int hash_slot = start_hash_slot; + while (result->i[hash_slot] == i && result->j[hash_slot] != l && + attempt < OPT_TEST_PATH_SIZE) { + hash_slot = aut_lj_tap_hash_fn(l, ++attempt); + } + if (attempt >= OPT_TEST_PATH_SIZE) goto exceed_limits; + bool init_slot = result->i[hash_slot] != i; + if (init_slot || (1 - wj * wk * wl < result->cij[hash_slot])) { + result->i[hash_slot] = i; + result->j[hash_slot] = l; + result->cij[hash_slot] = 1 - wj * wk * wl; + if (wj * wk * wl != 1.0) { + if (path_insert_pos >= OPT_TEST_PATH_ITEMS) goto exceed_limits; + result->testpath_idx[hash_slot] = path_insert_pos; + LennardJonesPathAIREBOT *path = + &result->testpath[path_insert_pos++]; + path->num = 4; + path->del[0].x = dijx; + path->del[0].y = dijy; + path->del[0].z = dijz; + if (rij == 0) rij = sqrt(rijsq); + path->r[0] = rij; + path->del[1].x = djkx; + path->del[1].y = djky; + path->del[1].z = djkz; + if (rjk == 0) rjk = sqrt(rjksq); + path->r[1] = rjk; + path->del[2].x = dklx; + path->del[2].y = dkly; + path->del[2].z = dklz; + if (rkl == 0) rkl = sqrt(rklsq); + path->r[2] = rkl; + path->w[0] = wj; + path->dw[0] = dwj; + path->w[1] = wk; + path->dw[1] = dwk; + path->w[2] = wl; + path->dw[2] = dwl; + path->idx[0] = i; + path->idx[1] = j; + path->idx[2] = k; + path->idx[3] = l; + } + } + } + } + } + return true; +exceed_limits: + return false; +} + +/* + * Attempt to look up an element in the hash-map. + */ +static fvec aut_airebo_lj_tap_test_path(KernelArgsAIREBOT * ka, + struct aut_airebo_lj_test_path_result_data * test_path_result, + bvec need_search, ivec i_bc, ivec j, + LennardJonesPathAIREBOT path[fvec::VL] +) { + const ivec c_i1 = ivec::set1(1); + fvec cij = fvec::set1(1.0); + // first round: hash all j + // lookup i/j in hash list. + // if i matches and j matches: congrats + // if i matches and j does not: look up attempts + // if attempts > current_attempts: + // do another round of hashing + // for all those found: + + // fill in the path + // ----------------------------------------------- + // find all the correct hash slots, and a mask of where found. + ivec attempt = ivec::setzero(); + ivec hash_slot = aut_airebo_lj_tap_hash_fn_vec(j, attempt); + ivec lookup_i = ivec::mask_gather(ivec::undefined(), need_search, hash_slot, + &test_path_result->i[0], sizeof(int)); + bvec correct_i = ivec::mask_cmpeq(need_search, lookup_i, i_bc); + ivec lookup_j = ivec::mask_gather(ivec::undefined(), correct_i, hash_slot, + &test_path_result->j[0], sizeof(int)); + bvec found_items = ivec::mask_cmpeq(correct_i, lookup_j, j); + bvec another_attempt = correct_i & ~ found_items; + while (bvec::test_any_set(another_attempt)) { + attempt = ivec::mask_add(attempt, another_attempt, attempt, c_i1); + hash_slot = aut_airebo_lj_tap_hash_fn_vec(j, attempt); + ivec lookup_i_2 = ivec::mask_gather(lookup_i, another_attempt, hash_slot, + &test_path_result->i[0], sizeof(int)); + lookup_i = lookup_i_2; + correct_i = ivec::mask_cmpeq(need_search, lookup_i, i_bc); + lookup_j = ivec::mask_gather(lookup_j, another_attempt, hash_slot, + &test_path_result->j[0], sizeof(int)); + found_items = ivec::mask_cmpeq(correct_i, lookup_j, j); + another_attempt = correct_i & ~ found_items; + } + cij = fvec::mask_gather(cij, found_items, hash_slot, + &test_path_result->cij[0], sizeof(flt_t)); + bvec need_testpath = fvec::mask_cmplt(found_items, fvec::setzero(), cij); + if (bvec::test_any_set(need_testpath)) { + for (int i = 0; i < fvec::VL; i++) { + if (bvec::test_at(need_testpath, i)) { + int testpath_idx = + test_path_result->testpath_idx[ivec::at(hash_slot, i)]; + path[i] = test_path_result->testpath[testpath_idx]; + } + } + } + return cij; +} + +/* + * This function calculates the Lennard-Jones interaciton for those + * elements that require a bond-order calculation. + * It is similarly structured as the aut_frebo_batch_of_kind function. + * The forces due to bondorders are calculated speculatively and later + * updated with the correct outer derivative. + */ +template +static void aut_lj_with_bo( + KernelArgsAIREBOT * ka, + int itype, int jtype, + ivec i, ivec j, + fvec cij, LennardJonesPathAIREBOT testpath[fvec::VL] +) { + { // jump-scope for exceed_limits + AtomAIREBOT * _noalias x = ka->x; + ResultForceT * result_f = ka->result_f; + + ivec c_i4 = ivec::set1(4); + fvec c_1_0 = fvec::set1(1.0); + fvec c_2_0 = fvec::set1(2.0); + fvec c_0_5 = fvec::set1(0.5); + + fvec x_i, y_i, z_i; + aut_loadatoms_vec_notype(x, i, &x_i, &y_i, &z_i); + fvec x_j, y_j, z_j; + aut_loadatoms_vec_notype(x, j, &x_j, &y_j, &z_j); + fvec delx = x_i - x_j; + fvec dely = y_i - y_j; + fvec delz = z_i - z_j; + fvec rsq = delx * delx + dely * dely + delz * delz; + + fvec rij = fvec::sqrt(rsq); + bvec need_path_force = fvec::cmplt(cij, c_1_0); + flt_t sigcut = ka->params.sigcut; + flt_t sigmin = ka->params.sigmin; + flt_t sigma = ka->params.sigma[itype][jtype]; + flt_t rljmax = sigcut * sigma; + flt_t rljmin = sigmin * sigma; + fvec p_rljmin = fvec::set1(rljmin); + fvec p_rljmax = fvec::set1(rljmax); + + fvec dslw, slw = aut_Sp2_deriv(rij, p_rljmin, p_rljmax, &dslw); + + fvec p_lj1 = fvec::set1(ka->params.lj1[itype][jtype]); + fvec p_lj2 = fvec::set1(ka->params.lj2[itype][jtype]); + fvec p_lj3 = fvec::set1(ka->params.lj3[itype][jtype]); + fvec p_lj4 = fvec::set1(ka->params.lj4[itype][jtype]); + + fvec r2inv = fvec::recip(rsq); + + fvec vdw, dvdw; + if (MORSEFLAG) { + fvec exr = fvec::exp(fvec::setzero() - rij * p_lj4); + vdw = p_lj1 * exr * (p_lj2 * exr - c_2_0); + dvdw = p_lj3 * exr * (c_1_0 - p_lj2 * exr); + } else { + fvec r6inv = r2inv * r2inv * r2inv; + + vdw = r6inv * ( p_lj3 * r6inv - p_lj4); + fvec r7inv = r6inv * rij * r2inv; + dvdw = r7inv * ( p_lj2 - p_lj1 * r6inv); + } + + fvec VLJ = vdw * slw; + fvec dVLJ = dvdw * slw + vdw * dslw; + + fvec p_rcLJmin = fvec::set1(ka->params.rcLJmin[itype][jtype]); + fvec p_rcLJmax = fvec::set1(ka->params.rcLJmax[itype][jtype]); + fvec dStr, Str = aut_Sp2_deriv(rij, p_rcLJmin, p_rcLJmax, &dStr); + fvec VA = cij * VLJ * Str; + + fvec fij[3], fji[3]; + fij[0] = fvec::setzero(); fij[1] = fvec::setzero(); + fij[2] = fvec::setzero(); + fji[0] = fvec::setzero(); fji[1] = fvec::setzero(); + fji[2] = fvec::setzero(); + + ivec vi = i; + ivec vj = j; + + struct aut_frebo_data i_data, j_data; + i_data.x_i = x_i; + i_data.y_i = y_i; + i_data.z_i = z_i; + i_data.x_j = x_j; + i_data.y_j = y_j; + i_data.z_j = z_j; + j_data.x_i = x_j; + j_data.y_i = y_j; + j_data.z_i = z_j; + j_data.x_j = x_i; + j_data.y_j = y_i; + j_data.z_j = z_i; + + fvec p_rcmin = fvec::set1(ka->params.rcmin[itype][jtype]); + fvec p_rcmax = fvec::set1(ka->params.rcmax[itype][jtype]); + fvec dwij; + fvec wij = aut_Sp_deriv(rij, p_rcmin, p_rcmax, &dwij); + + fvec nHi = fvec::gather(vi, ka->nH, sizeof(flt_t)); + fvec nCi = fvec::gather(vi, ka->nC, sizeof(flt_t)); + fvec nHj = fvec::gather(vj, ka->nH, sizeof(flt_t)); + fvec nCj = fvec::gather(vj, ka->nC, sizeof(flt_t)); + fvec Nij = nHi + nCi - wij; + fvec Nji = nHj + nCj - wij; + i_data.nHi = nHi; + i_data.nCi = nCi; + j_data.nHi = nHj; + j_data.nCi = nCj; + + fvec the_r = fvec::set1(ka->params.rcmin[itype][jtype]); + fvec scale = the_r / rij; + + fvec NconjtmpI; + fvec pij = aut_frebo_pij_pd_2(ka, &i_data, itype, jtype, vi, vj, + delx * scale, dely * scale, delz * scale, + the_r, wij, VA, &NconjtmpI, fij); + + if (i_data.buf_len < 0) goto exceed_limits; + + fvec NconjtmpJ; + fvec rjix = fvec::setzero() - delx; + fvec rjiy = fvec::setzero() - dely; + fvec rjiz = fvec::setzero() - delz; + fvec pji = aut_frebo_pij_pd_2(ka, &j_data, jtype, itype, vj, vi, + rjix * scale, rjiy * scale, rjiz * scale, + the_r, wij, VA, &NconjtmpJ, fji); + fij[0] = fij[0] - fji[0]; + fij[1] = fij[1] - fji[1]; + fij[2] = fij[2] - fji[2]; + + if (j_data.buf_len < 0) goto exceed_limits; + + fvec Nijconj = c_1_0 + NconjtmpI * NconjtmpI + NconjtmpJ * NconjtmpJ; + fvec dN3[3]; + fvec pi_rc = aut_frebo_pi_rc_pd(ka, itype, jtype, Nij, Nji, Nijconj, dN3); + + fvec c_TOL = fvec::set1(TOL); + fvec dN3_dh[3]; + fvec Tij = aut_frebo_Tij(ka, itype, jtype, Nij, Nji, Nijconj, &dN3_dh[0]); + bvec TijgtTOLmask = fvec::cmpnle(fvec::abs(Tij), c_TOL); + fvec sum_omega = fvec::setzero(); + if (bvec::test_any_set(TijgtTOLmask)) { + sum_omega = aut_frebo_sum_omega( + ka, &i_data, &j_data, itype, jtype, vi, vj, + delx * scale, dely * scale, delz * scale, the_r, VA * Tij, fij); + sum_omega = fvec::mask_blend(TijgtTOLmask, fvec::setzero(), sum_omega); + } + fvec pi_dh = Tij * sum_omega; + + fvec bij = c_0_5 * ( pij + pji) + pi_rc + pi_dh; + + fvec p_bLJmin = fvec::set1(ka->params.bLJmin[itype][jtype]); + fvec p_bLJmax = fvec::set1(ka->params.bLJmax[itype][jtype]); + fvec dStb, Stb = aut_Sp2_deriv(bij, p_bLJmin, p_bLJmax, &dStb); + + bvec need_bo_deriv = fvec::cmpneq(dStb, fvec::setzero()); + // fix up j_data, i_data, fij: + // multiply each by dStb + if (bvec::test_any_set(need_bo_deriv)) { + i_data.force_i_x = dStb * i_data.force_i_x; + i_data.force_i_y = dStb * i_data.force_i_y; + i_data.force_i_z = dStb * i_data.force_i_z; + i_data.force_j_x = dStb * i_data.force_j_x; + i_data.force_j_y = dStb * i_data.force_j_y; + i_data.force_j_z = dStb * i_data.force_j_z; + j_data.force_i_x = dStb * j_data.force_i_x; + j_data.force_i_y = dStb * j_data.force_i_y; + j_data.force_i_z = dStb * j_data.force_i_z; + j_data.force_j_x = dStb * j_data.force_j_x; + j_data.force_j_y = dStb * j_data.force_j_y; + j_data.force_j_z = dStb * j_data.force_j_z; + for (int k = 0; k < i_data.buf_len; k++) { + i_data.force_k_x_buf[k] = dStb * i_data.force_k_x_buf[k]; + i_data.force_k_y_buf[k] = dStb * i_data.force_k_y_buf[k]; + i_data.force_k_z_buf[k] = dStb * i_data.force_k_z_buf[k]; + } + for (int k = 0; k < j_data.buf_len; k++) { + j_data.force_k_x_buf[k] = dStb * j_data.force_k_x_buf[k]; + j_data.force_k_y_buf[k] = dStb * j_data.force_k_y_buf[k]; + j_data.force_k_z_buf[k] = dStb * j_data.force_k_z_buf[k]; + } + fvec fijc[3]; + fijc[0] = dStb * fij[0]; + fijc[1] = dStb * fij[1]; + fijc[2] = dStb * fij[2]; + fij[0] = scale * (fijc[0] - (delx * delx * fijc[0] + dely * delx * + fijc[1] + delz * delx * fijc[2]) / rsq); + fij[1] = scale * (fijc[1] - (delx * dely * fijc[0] + dely * dely * + fijc[1] + delz * dely * fijc[2]) / rsq); + fij[2] = scale * (fijc[2] - (delx * delz * fijc[0] + dely * delz * + fijc[1] + delz * delz * fijc[2]) / rsq); + + aut_frebo_N_spline_force(ka, &i_data, itype, jtype, vi, vj, dStb * VA, + dN3[0], dN3[2], NconjtmpI); + aut_frebo_N_spline_force(ka, &j_data, jtype, itype, vj, vi, dStb * VA, + dN3[1], dN3[2], NconjtmpJ); + if (bvec::test_any_set(TijgtTOLmask)) { + aut_frebo_N_spline_force(ka, &i_data, itype, jtype, vi, vj, + dStb * VA * sum_omega, dN3_dh[0], dN3_dh[2], + NconjtmpI); + aut_frebo_N_spline_force(ka, &j_data, jtype, itype, vj, vi, + dStb * VA * sum_omega, dN3_dh[1], dN3_dh[2], + NconjtmpJ); + } + + aut_frebo_data_writeback(ka, &i_data); + aut_frebo_data_writeback(ka, &j_data); + } else { + fij[0] = fvec::setzero(); + fij[1] = fvec::setzero(); + fij[2] = fvec::setzero(); + } + + fvec fpdVLJ = cij * dVLJ * ( c_1_0 + Str * ( Stb - c_1_0)); + fvec fpdStr = dStr * cij * ( Stb * VLJ - VLJ); + fvec fpair = r2inv * rij * ( fvec::setzero() - ( fpdVLJ + fpdStr)); + fvec evdwl = VA * Stb + cij * VLJ * ( c_1_0 - Str); + + fvec result_f_i_x = fpair * delx + fij[0]; + fvec result_f_i_y = fpair * dely + fij[1]; + fvec result_f_i_z = fpair * delz + fij[2]; + fvec result_f_j_x = fvec::setzero() - result_f_i_x; + fvec result_f_j_y = fvec::setzero() - result_f_i_y; + fvec result_f_j_z = fvec::setzero() - result_f_i_z; + + flt_t fi_x_buf[fvec::VL] __attribute__((aligned(64))); + flt_t fi_y_buf[fvec::VL] __attribute__((aligned(64))); + flt_t fi_z_buf[fvec::VL] __attribute__((aligned(64))); + int fi_i_buf[ivec::VL] __attribute__((aligned(64))); + flt_t fj_x_buf[fvec::VL] __attribute__((aligned(64))); + flt_t fj_y_buf[fvec::VL] __attribute__((aligned(64))); + flt_t fj_z_buf[fvec::VL] __attribute__((aligned(64))); + int fj_j_buf[ivec::VL] __attribute__((aligned(64))); + flt_t evdwl_buf[fvec::VL] __attribute__((aligned(64))); + + if (bvec::test_any_set(need_bo_deriv)) { + result_f_i_x = i_data.force_i_x + result_f_i_x; + result_f_i_y = i_data.force_i_y + result_f_i_y; + result_f_i_z = i_data.force_i_z + result_f_i_z; + result_f_j_x = i_data.force_j_x + result_f_j_x; + result_f_j_y = i_data.force_j_y + result_f_j_y; + result_f_j_z = i_data.force_j_z + result_f_j_z; + + result_f_i_x = j_data.force_j_x + result_f_i_x; + result_f_i_y = j_data.force_j_y + result_f_i_y; + result_f_i_z = j_data.force_j_z + result_f_i_z; + result_f_j_x = j_data.force_i_x + result_f_j_x; + result_f_j_y = j_data.force_i_y + result_f_j_y; + result_f_j_z = j_data.force_i_z + result_f_j_z; + } + + fvec::store(fi_x_buf, result_f_i_x); + fvec::store(fi_y_buf, result_f_i_y); + fvec::store(fi_z_buf, result_f_i_z); + ivec::store(fi_i_buf, vi); + fvec::store(fj_x_buf, result_f_j_x); + fvec::store(fj_y_buf, result_f_j_y); + fvec::store(fj_z_buf, result_f_j_z); + ivec::store(fj_j_buf, vj); + fvec::store(evdwl_buf, evdwl); + + int lane; + for (lane = 0; lane < fvec::VL; lane++) { + int ii = fi_i_buf[lane]; + result_f[ii].x += fi_x_buf[lane]; + result_f[ii].y += fi_y_buf[lane]; + result_f[ii].z += fi_z_buf[lane]; + result_f[ii].w += 0.5 * evdwl_buf[lane]; + int jj = fj_j_buf[lane]; + result_f[jj].x += fj_x_buf[lane]; + result_f[jj].y += fj_y_buf[lane]; + result_f[jj].z += fj_z_buf[lane]; + result_f[jj].w += 0.5 * evdwl_buf[lane]; + } + ka->result_eng += fvec::reduce_add(evdwl); + + if (bvec::test_any_set(need_path_force)) { + fvec dC = VLJ * ( Str * Stb + c_1_0 - Str); + aut_airebo_lj_force_path(ka, need_path_force, dC, testpath); + } + return; + } +exceed_limits: + for (int l = 0; l < fvec::VL; l++) { + ref_lennard_jones_single_interaction(ka, ivec::at(i, l), ivec::at(j, l), + MORSEFLAG); + } + return; +} + +/* + * Calculate the lennard-jones interaction. + * Uses the above hash-map, and outlines the calculation if the bondorder is + * needed. + * Agressively compresses to get the most values calculated. + */ +template +static void aut_lennard_jones(KernelArgsAIREBOT * ka) { + AtomAIREBOT * x = ka->x; + int * tag = ka->tag; + int * map = ka->map; + ResultForceT * result_f = ka->result_f; + ivec c_i1 = ivec::set1(1); + ivec c_i4 = ivec::set1(4); + fvec c_1_0 = fvec::set1(1.0); + fvec c_2_0 = fvec::set1(2.0); + fvec c_0_0 = fvec::set1(0.0); + int map_i_scalar = 0; + { + int i; + for (i = 1; i < ka->num_types; i++) { + if (ka->map[i]) + map_i_scalar |= (1 << i); + } + } + ivec map_i = ivec::set1(map_i_scalar); + fvec result_eng = fvec::setzero(); + + struct aut_airebo_lj_test_path_result_data test_path_result; + for (int i = 0; i < OPT_TEST_PATH_SIZE; i++) { + test_path_result.i[i] = -1; + } + + ivec i_bo[2][2]; + ivec j_bo[2][2]; + fvec cij_bo[2][2]; + LennardJonesPathAIREBOT testpath_bo[2][2][fvec::VL]; + int num_bo[2][2] = {0}; + + for (int i = ka->frebo_from_atom; i < ka->frebo_to_atom; i++) { + ivec itag_bc = ivec::set1(tag[i]); + int itype = map[x[i].w]; + fvec x_i = fvec::set1(x[i].x); + fvec y_i = fvec::set1(x[i].y); + fvec z_i = fvec::set1(x[i].z); + ivec i_bc = ivec::set1(i); + + fvec cutljsq0 = fvec::set1(ka->params.cutljsq[itype][0]); + fvec cutljsq1 = fvec::set1(ka->params.cutljsq[itype][1]); + fvec p_rcmax0 = fvec::set1(ka->params.rcmax[itype][0]); + fvec p_rcmax1 = fvec::set1(ka->params.rcmax[itype][1]); + flt_t sigcut = ka->params.sigcut; + flt_t sigmin = ka->params.sigmin; + flt_t sigma0 = ka->params.sigma[itype][0]; + flt_t rljmax0 = sigcut * sigma0; + flt_t rljmin0 = sigmin * sigma0; + flt_t sigma1 = ka->params.sigma[itype][1]; + flt_t rljmax1 = sigcut * sigma1; + flt_t rljmin1 = sigmin * sigma1; + fvec p_rljmax0 = fvec::set1(rljmax0); + fvec p_rljmax1 = fvec::set1(rljmax1); + fvec p_rljmin0 = fvec::set1(rljmin0); + fvec p_rljmin1 = fvec::set1(rljmin1); + fvec p_rcLJmax0 = fvec::set1(ka->params.rcLJmax[itype][0]); + fvec p_rcLJmax1 = fvec::set1(ka->params.rcLJmax[itype][1]); + fvec p_rcLJmin0 = fvec::set1(ka->params.rcLJmin[itype][0]); + fvec p_rcLJmin1 = fvec::set1(ka->params.rcLJmin[itype][1]); + fvec p_lj10 = fvec::set1(ka->params.lj1[itype][0]); + fvec p_lj11 = fvec::set1(ka->params.lj1[itype][1]); + fvec p_lj20 = fvec::set1(ka->params.lj2[itype][0]); + fvec p_lj21 = fvec::set1(ka->params.lj2[itype][1]); + fvec p_lj30 = fvec::set1(ka->params.lj3[itype][0]); + fvec p_lj31 = fvec::set1(ka->params.lj3[itype][1]); + fvec p_lj40 = fvec::set1(ka->params.lj4[itype][0]); + fvec p_lj41 = fvec::set1(ka->params.lj4[itype][1]); + + int * neighs = ka->neigh_lmp.entries + ka->neigh_lmp.offset[i]; + int jnum = ka->neigh_lmp.num_half[i]; + + bool tap_success = aut_airebo_lj_test_all_paths(ka, i, &test_path_result); + if (! tap_success) { + for (int jj = 0; jj < jnum; jj++) { + ref_lennard_jones_single_interaction(ka, i, neighs[jj], MORSEFLAG); + } + continue; + } + + ivec j_2; + fvec delx_2, dely_2, delz_2, rsq_2; + bvec jtype_mask_2; + int num_2 = 0; + + fvec result_f_i_x = fvec::setzero(); + fvec result_f_i_y = fvec::setzero(); + fvec result_f_i_z = fvec::setzero(); + + int jj = 0; + bool rest_j = jj < jnum; + bool rest_2 = fvec::fast_compress(); + #pragma forceinline recursive + while (rest_j || rest_2) { + fvec delx, dely, delz, rsq; + bvec jtype_mask, within_cutoff; + ivec j; + if (rest_j) { + bvec mask_0 = bvec::full(); + //0xFF >> (8 - (jnum - jj)); + if (jj + (fvec::VL - 1) >= jnum) mask_0 = bvec::only(jnum - jj); + j = ivec::maskz_loadu(mask_0, &neighs[jj]); + fvec x_j, y_j, z_j; + aut_loadatoms_vec(x, j, &x_j, &y_j, &z_j, &jtype_mask, map, map_i, + c_i1); + fvec::gather_prefetch0(ivec::mullo(c_i4, + ivec::maskz_loadu(bvec::full(), &neighs[jj + fvec::VL])), x); + _mm_prefetch((const char*)&neighs[jj + 2 * fvec::VL], _MM_HINT_T0); + delx = x_i - x_j; + dely = y_i - y_j; + delz = z_i - z_j; + rsq = delx * delx + dely * dely + delz * delz; + fvec cutoff_sq = fvec::mask_blend(jtype_mask, cutljsq0, cutljsq1); + within_cutoff = fvec::mask_cmplt(mask_0, rsq, cutoff_sq); + + if (fvec::fast_compress()) { + j = ivec::masku_compress(within_cutoff, j); + delx = fvec::masku_compress(within_cutoff, delx); + dely = fvec::masku_compress(within_cutoff, dely); + delz = fvec::masku_compress(within_cutoff, delz); + rsq = fvec::masku_compress(within_cutoff, rsq); + jtype_mask = bvec::masku_compress(within_cutoff, jtype_mask); + //within_cutoff = 0xFF >> (8 - _cc_popcnt(within_cutoff)); + + bvec mask_2 = bvec::after(num_2);//0xFF << num_2; + j_2 = ivec::mask_expand(j_2, mask_2, j); + delx_2 = fvec::mask_expand(delx_2, mask_2, delx); + dely_2 = fvec::mask_expand(dely_2, mask_2, dely); + delz_2 = fvec::mask_expand(delz_2, mask_2, delz); + rsq_2 = fvec::mask_expand(rsq_2, mask_2, rsq); + jtype_mask_2 = bvec::mask_expand(jtype_mask_2, mask_2, jtype_mask); + num_2 = num_2 + bvec::popcnt(within_cutoff); + if (num_2 < fvec::VL) { + jj += fvec::VL; + rest_j = jj < jnum; + continue; + } + + num_2 -= fvec::VL; + //(0xFF >> (8 - num_2)) << (_cc_popcnt(within_cutoff) - num_2); + mask_2 = bvec::onlyafter(num_2, bvec::popcnt(within_cutoff) - num_2); + { + ivec tmp_j = j_2; + j_2 = ivec::masku_compress(mask_2, j); + j = tmp_j; + fvec tmp_delx = delx_2; + delx_2 = fvec::masku_compress(mask_2, delx); + delx = tmp_delx; + fvec tmp_dely = dely_2; + dely_2 = fvec::masku_compress(mask_2, dely); + dely = tmp_dely; + fvec tmp_delz = delz_2; + delz_2 = fvec::masku_compress(mask_2, delz); + delz = tmp_delz; + fvec tmp_rsq = rsq_2; + rsq_2 = fvec::masku_compress(mask_2, rsq); + rsq = tmp_rsq; + bvec tmp_jtype_mask = jtype_mask_2; + jtype_mask_2 = bvec::masku_compress(mask_2, jtype_mask); + jtype_mask = tmp_jtype_mask; + within_cutoff = bvec::full(); + } + } + } else if (rest_2) { + rest_2 = false; + j = j_2; + delx = delx_2; + dely = dely_2; + delz = delz_2; + rsq = rsq_2; + jtype_mask = jtype_mask_2; + within_cutoff = bvec::only(num_2); + num_2 = 0; + } + + bvec current_mask = within_cutoff; + if (bvec::test_all_unset(current_mask)) { + jj += fvec::VL; + rest_j = jj < jnum; + continue; + } + + fvec rij = fvec::sqrt(rsq); + LennardJonesPathAIREBOT testpath[fvec::VL]; + fvec cij = c_1_0; + fvec p_cut3rebo = fvec::set1(ka->params.cut3rebo); + bvec need_search = fvec::mask_cmplt(current_mask, rij, p_cut3rebo); + if (bvec::test_any_set(need_search)) { + fvec p_rcmax = fvec::mask_blend(jtype_mask, p_rcmax0, p_rcmax1); + #pragma noinline + cij = aut_airebo_lj_tap_test_path(ka, &test_path_result, need_search, + i_bc, j, testpath); + } + current_mask = fvec::mask_cmplt(current_mask, c_0_0, cij); + if (bvec::test_all_unset(current_mask)) { + jj += fvec::VL; + rest_j = jj < jnum; + continue; + } + bvec need_path_force = fvec::mask_cmplt(current_mask, cij, c_1_0); + + fvec p_rljmax = fvec::mask_blend(jtype_mask, p_rljmax0, p_rljmax1); + fvec p_rljmin = fvec::mask_blend(jtype_mask, p_rljmin0, p_rljmin1); + + fvec dslw, slw = aut_Sp2_deriv(rij, p_rljmin, p_rljmax, &dslw); + + fvec p_lj1 = fvec::mask_blend(jtype_mask, p_lj10, p_lj11); + fvec p_lj2 = fvec::mask_blend(jtype_mask, p_lj20, p_lj21); + fvec p_lj3 = fvec::mask_blend(jtype_mask, p_lj30, p_lj31); + fvec p_lj4 = fvec::mask_blend(jtype_mask, p_lj40, p_lj41); + + fvec vdw, dvdw; + + fvec r2inv = fvec::recip(rsq); + + if (MORSEFLAG) { + fvec exr = fvec::exp(fvec::setzero() - rij * p_lj4); + vdw = p_lj1 * exr * (p_lj2 * exr - c_2_0); + dvdw = p_lj3 * exr * (c_1_0 - p_lj2 * exr); + } else { + fvec r6inv = r2inv * r2inv * r2inv; + + vdw = r6inv * ( p_lj3 * r6inv - p_lj4); + fvec r7inv = r6inv * rij * r2inv; + dvdw = r7inv * ( p_lj2 - p_lj1 * r6inv); + } + + fvec VLJ = vdw * slw; + fvec dVLJ = dvdw * slw + vdw * dslw; + + fvec p_rcLJmin = fvec::mask_blend(jtype_mask, p_rcLJmin0, p_rcLJmin1); + fvec p_rcLJmax = fvec::mask_blend(jtype_mask, p_rcLJmax0, p_rcLJmax1); + fvec dStr, Str = aut_Sp2_deriv(rij, p_rcLJmin, p_rcLJmax, &dStr); + fvec VA = cij * VLJ * Str; + bvec need_bondorder = fvec::mask_cmplt(current_mask, c_0_0, Str); + fvec Stb = fvec::setzero(); + fvec fij[3]; + fij[0] = fvec::setzero(); + fij[1] = fvec::setzero(); + fij[2] = fvec::setzero(); + if (bvec::test_any_set(need_bondorder)) { + for (int jtype = 0; jtype < 2; jtype++) { + bvec need_bo_with_jtype = need_bondorder; + if (jtype) need_bo_with_jtype = need_bo_with_jtype & jtype_mask; + else need_bo_with_jtype = need_bo_with_jtype & ~ jtype_mask; + ivec jtmp = ivec::masku_compress(need_bo_with_jtype, j); + ivec itmp = ivec::masku_compress(need_bo_with_jtype, ivec::set1(i)); + fvec cijtmp = fvec::masku_compress(need_bo_with_jtype, cij); + bvec insert_mask = bvec::after(num_bo[itype][jtype]); + i_bo[itype][jtype] = ivec::mask_expand(i_bo[itype][jtype], + insert_mask, itmp); + j_bo[itype][jtype] = ivec::mask_expand(j_bo[itype][jtype], + insert_mask, jtmp); + cij_bo[itype][jtype] = fvec::mask_expand(cij_bo[itype][jtype], + insert_mask, cijtmp); + bvec need_path_force_with_jtype = need_bo_with_jtype & + need_path_force; + int testpath_end = fvec::VL; + if (bvec::test_any_set(need_path_force_with_jtype)) { + int pos = num_bo[itype][jtype]; + for (int l = 0; l < fvec::VL; l++) { + if (pos >= fvec::VL) { + testpath_end = l; + break; + } + if (bvec::test_at(need_path_force_with_jtype, l)) { + testpath_bo[itype][jtype][pos] = testpath[l]; + } + if (bvec::test_at(need_bo_with_jtype, l)) { + pos += 1; + } + } + } + num_bo[itype][jtype] = num_bo[itype][jtype] + + bvec::popcnt(need_bo_with_jtype); + if (num_bo[itype][jtype] >= fvec::VL) { + #pragma noinline + aut_lj_with_bo(ka, itype, jtype, i_bo[itype][jtype], + j_bo[itype][jtype], cij_bo[itype][jtype], + testpath_bo[itype][jtype]); + num_bo[itype][jtype] -= fvec::VL; + insert_mask = bvec::onlyafter(num_bo[itype][jtype], + bvec::popcnt(need_bo_with_jtype) - + num_bo[itype][jtype]); + i_bo[itype][jtype] = ivec::masku_compress(insert_mask, itmp); + j_bo[itype][jtype] = ivec::masku_compress(insert_mask, jtmp); + cij_bo[itype][jtype] = fvec::masku_compress(insert_mask, cijtmp); + if (bvec::test_any_set(need_path_force_with_jtype)) { + int pos = 0; + for (int l = testpath_end; l < fvec::VL; l++) { + if (bvec::test_at(need_path_force_with_jtype, l)) { + testpath_bo[itype][jtype][pos] = testpath[l]; + } + if (bvec::test_at(need_bo_with_jtype, l)) { + pos += 1; + } + } + } + } + } + current_mask = current_mask & ~ need_bondorder; + need_path_force = need_path_force & ~ need_bondorder; + } + + fvec fpdVLJ = cij * dVLJ * ( c_1_0 + Str * ( Stb - c_1_0)); + fvec fpdStr = dStr * cij * ( Stb * VLJ - VLJ); + fvec fpair = r2inv * rij * ( fvec::setzero() - ( fpdVLJ + fpdStr)); + fvec evdwl = VA * Stb + cij * VLJ * ( c_1_0 - Str); + + fvec fix = fpair * delx + fij[0]; + fvec fiy = fpair * dely + fij[1]; + fvec fiz = fpair * delz + fij[2]; + result_f_i_x = fvec::mask_add(result_f_i_x, current_mask, result_f_i_x, + fix); + result_f_i_y = fvec::mask_add(result_f_i_y, current_mask, result_f_i_y, + fiy); + result_f_i_z = fvec::mask_add(result_f_i_z, current_mask, result_f_i_z, + fiz); + result_eng = fvec::mask_add(result_eng, current_mask, result_eng, evdwl); + + ivec j_dbl_idx = ivec::mullo(j, c_i4); + avec fjx = avec::mask_gather(avec::undefined(), current_mask, j_dbl_idx, + &ka->result_f[0].x, sizeof(acc_t)); + avec fjy = avec::mask_gather(avec::undefined(), current_mask, j_dbl_idx, + &ka->result_f[0].y, sizeof(acc_t)); + avec fjz = avec::mask_gather(avec::undefined(), current_mask, j_dbl_idx, + &ka->result_f[0].z, sizeof(acc_t)); + + fjx = fjx - fix; + fjy = fjy - fiy; + fjz = fjz - fiz; + avec::mask_i32loscatter(&ka->result_f[0].x, current_mask, j_dbl_idx, fjx, + sizeof(acc_t)); + avec::mask_i32loscatter(&ka->result_f[0].y, current_mask, j_dbl_idx, fjy, + sizeof(acc_t)); + avec::mask_i32loscatter(&ka->result_f[0].z, current_mask, j_dbl_idx, fjz, + sizeof(acc_t)); + + if (bvec::test_any_set(need_path_force)) { + fvec dC = VLJ * ( Str * Stb + c_1_0 - Str); + #pragma noinline + aut_airebo_lj_force_path(ka, need_path_force, dC, testpath); + } + jj += fvec::VL; + rest_j = jj < jnum; + } + ka->result_f[i].x += fvec::reduce_add(result_f_i_x); + ka->result_f[i].y += fvec::reduce_add(result_f_i_y); + ka->result_f[i].z += fvec::reduce_add(result_f_i_z); + } + for (int itype = 0; itype < 2; itype++) { + for (int jtype = 0; jtype < 2; jtype++) { + for (int l = 0; l < num_bo[itype][jtype]; l++) { + ref_lennard_jones_single_interaction(ka,ivec::at(i_bo[itype][jtype],l), + ivec::at(j_bo[itype][jtype], l), + MORSEFLAG); + } + } + } + ka->result_eng += fvec::reduce_add(result_eng); +} + +}; + +template +void aut_lennard_jones(KernelArgsAIREBOT * ka, int morseflag) { +#ifdef LMP_INTEL_AIREBO_REF + ref_lennard_jones(ka, morseflag); +#else + if (morseflag) { + aut_wrap::template aut_lennard_jones<1>(ka); + } else { + aut_wrap::template aut_lennard_jones<0>(ka); + } +#endif +} + +template +void aut_rebo_neigh(KernelArgsAIREBOT * ka) { +#ifdef LMP_INTEL_AIREBO_REF + ref_rebo_neigh(ka); +#else + aut_wrap::aut_rebo_neigh(ka); +#endif +} + +template +void aut_frebo(KernelArgsAIREBOT * ka, int torsion_flag) { +#ifdef LMP_INTEL_AIREBO_REF + ref_frebo(ka, torsion_flag); +#else + aut_wrap::aut_frebo(ka, torsion_flag); +#endif +} + +#ifdef __INTEL_OFFLOAD +#pragma offload_attribute(pop) +#endif + +} + diff --git a/src/USER-INTEL/pair_airebo_intel.h b/src/USER-INTEL/pair_airebo_intel.h new file mode 100644 index 0000000000..d3179c09f1 --- /dev/null +++ b/src/USER-INTEL/pair_airebo_intel.h @@ -0,0 +1,110 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Markus Hohnerbach (RWTH) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(airebo/intel,PairAIREBOIntel) + +#else + +#ifndef LMP_PAIR_AIREBO_INTEL_H +#define LMP_PAIR_AIREBO_INTEL_H + +#include "pair.h" +#include "fix_intel.h" +#include "pair_airebo.h" +//#include "airebo_common.h" + +namespace LAMMPS_NS { + +template +struct PairAIREBOIntelParam; + +class PairAIREBOIntel : public PairAIREBO { + public: + PairAIREBOIntel(class LAMMPS *); + virtual ~PairAIREBOIntel(); + virtual void compute(int, int); + virtual void init_style(); + protected: + + template + void compute(int eflag, int vflag, IntelBuffers *buffers); + + template + void eval(const int offload, const int vflag, + IntelBuffers * buffers, + const int astart, const int aend); + + template + void pack_force_const(IntelBuffers * buffers); + + template + PairAIREBOIntelParam get_param(); + + FixIntel * fix; + int _cop; + + int * REBO_cnumneigh; + int * REBO_num_skin; + int * REBO_list_data; + +}; + +} + +#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: Pair style AIREBO requires atom IDs + +This is a requirement to use the AIREBO potential. + +E: Pair style AIREBO requires newton pair on + +See the newton command. This is a restriction to use the AIREBO +potential. + +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. + +E: Neighbor list overflow, boost neigh_modify one + +There are too many neighbors of a single atom. Use the neigh_modify +command to increase the max number of neighbors allowed for one atom. +You may also want to boost the page size. + +E: Cannot open AIREBO potential file %s + +The specified AIREBO potential file cannot be opened. Check that the +path and name are correct. + +*/ diff --git a/src/USER-INTEL/pair_airebo_morse_intel.cpp b/src/USER-INTEL/pair_airebo_morse_intel.cpp new file mode 100644 index 0000000000..9c0f3b8ed0 --- /dev/null +++ b/src/USER-INTEL/pair_airebo_morse_intel.cpp @@ -0,0 +1,37 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Markus Hohnerbach (RWTH) +------------------------------------------------------------------------- */ + +#include "pair_airebo_morse_intel.h" +#include "error.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +PairAIREBOMorseIntel::PairAIREBOMorseIntel(LAMMPS *lmp) + : PairAIREBOIntel(lmp) {} + +/* ---------------------------------------------------------------------- + global settings +------------------------------------------------------------------------- */ + +void PairAIREBOMorseIntel::settings(int narg, char **arg) +{ + PairAIREBOIntel::settings(narg,arg); + + morseflag = 1; +} diff --git a/src/USER-INTEL/pair_airebo_morse_intel.h b/src/USER-INTEL/pair_airebo_morse_intel.h new file mode 100644 index 0000000000..5210ea80ee --- /dev/null +++ b/src/USER-INTEL/pair_airebo_morse_intel.h @@ -0,0 +1,40 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Markus Hohnerbach (RWTH) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(airebo/morse/intel,PairAIREBOMorseIntel) + +#else + +#ifndef LMP_PAIR_AIREBO_MORSE_INTEL_H +#define LMP_PAIR_AIREBO_MORSE_INTEL_H + +#include "pair_airebo_intel.h" + +namespace LAMMPS_NS { + +class PairAIREBOMorseIntel : public PairAIREBOIntel { + public: + PairAIREBOMorseIntel(class LAMMPS *); + virtual void settings(int, char **); +}; + +} + +#endif +#endif diff --git a/src/USER-INTEL/pair_eam_alloy_intel.cpp b/src/USER-INTEL/pair_eam_alloy_intel.cpp new file mode 100644 index 0000000000..4f47c7ee23 --- /dev/null +++ b/src/USER-INTEL/pair_eam_alloy_intel.cpp @@ -0,0 +1,326 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing authors: Stephen Foiles (SNL), Murray Daw (SNL) +------------------------------------------------------------------------- */ + +#include +#include +#include +#include "pair_eam_alloy_intel.h" +#include "atom.h" +#include "comm.h" +#include "force.h" +#include "memory.h" +#include "error.h" + +using namespace LAMMPS_NS; + +#define MAXLINE 1024 + +/* ---------------------------------------------------------------------- */ + +PairEAMAlloyIntel::PairEAMAlloyIntel(LAMMPS *lmp) : PairEAMIntel(lmp) +{ + one_coeff = 1; +} + +/* ---------------------------------------------------------------------- + set coeffs for one or more type pairs + read DYNAMO setfl file +------------------------------------------------------------------------- */ + +void PairEAMAlloyIntel::coeff(int narg, char **arg) +{ + int i,j; + + if (!allocated) allocate(); + + if (narg != 3 + atom->ntypes) + error->all(FLERR,"Incorrect args for pair coefficients"); + + // insure I,J args are * * + + if (strcmp(arg[0],"*") != 0 || strcmp(arg[1],"*") != 0) + error->all(FLERR,"Incorrect args for pair coefficients"); + + // read EAM setfl file + + if (setfl) { + for (i = 0; i < setfl->nelements; i++) delete [] setfl->elements[i]; + delete [] setfl->elements; + delete [] setfl->mass; + memory->destroy(setfl->frho); + memory->destroy(setfl->rhor); + memory->destroy(setfl->z2r); + delete setfl; + } + setfl = new Setfl(); + read_file(arg[2]); + + // read args that map atom types to elements in potential file + // map[i] = which element the Ith atom type is, -1 if NULL + + for (i = 3; i < narg; i++) { + if (strcmp(arg[i],"NULL") == 0) { + map[i-2] = -1; + continue; + } + for (j = 0; j < setfl->nelements; j++) + if (strcmp(arg[i],setfl->elements[j]) == 0) break; + if (j < setfl->nelements) map[i-2] = j; + else error->all(FLERR,"No matching element in EAM potential file"); + } + + // clear setflag since coeff() called once with I,J = * * + + int n = atom->ntypes; + for (i = 1; i <= n; i++) + for (j = i; j <= n; j++) + setflag[i][j] = 0; + + // set setflag i,j for type pairs where both are mapped to elements + // set mass of atom type if i = j + + int count = 0; + for (i = 1; i <= n; i++) { + for (j = i; j <= n; j++) { + if (map[i] >= 0 && map[j] >= 0) { + setflag[i][j] = 1; + if (i == j) atom->set_mass(FLERR,i,setfl->mass[map[i]]); + count++; + } + scale[i][j] = 1.0; + } + } + + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); +} + +/* ---------------------------------------------------------------------- + read a multi-element DYNAMO setfl file +------------------------------------------------------------------------- */ + +void PairEAMAlloyIntel::read_file(char *filename) +{ + Setfl *file = setfl; + + // open potential file + + int me = comm->me; + FILE *fptr; + char line[MAXLINE]; + + if (me == 0) { + fptr = force->open_potential(filename); + if (fptr == NULL) { + char str[128]; + sprintf(str,"Cannot open EAM potential file %s",filename); + error->one(FLERR,str); + } + } + + // read and broadcast header + // extract element names from nelements line + + int n; + if (me == 0) { + fgets(line,MAXLINE,fptr); + fgets(line,MAXLINE,fptr); + fgets(line,MAXLINE,fptr); + fgets(line,MAXLINE,fptr); + n = strlen(line) + 1; + } + MPI_Bcast(&n,1,MPI_INT,0,world); + MPI_Bcast(line,n,MPI_CHAR,0,world); + + sscanf(line,"%d",&file->nelements); + int nwords = atom->count_words(line); + if (nwords != file->nelements + 1) + error->all(FLERR,"Incorrect element names in EAM potential file"); + + char **words = new char*[file->nelements+1]; + nwords = 0; + strtok(line," \t\n\r\f"); + while ((words[nwords++] = strtok(NULL," \t\n\r\f"))) continue; + + file->elements = new char*[file->nelements]; + for (int i = 0; i < file->nelements; i++) { + n = strlen(words[i]) + 1; + file->elements[i] = new char[n]; + strcpy(file->elements[i],words[i]); + } + delete [] words; + + if (me == 0) { + fgets(line,MAXLINE,fptr); + sscanf(line,"%d %lg %d %lg %lg", + &file->nrho,&file->drho,&file->nr,&file->dr,&file->cut); + } + + MPI_Bcast(&file->nrho,1,MPI_INT,0,world); + MPI_Bcast(&file->drho,1,MPI_DOUBLE,0,world); + MPI_Bcast(&file->nr,1,MPI_INT,0,world); + MPI_Bcast(&file->dr,1,MPI_DOUBLE,0,world); + MPI_Bcast(&file->cut,1,MPI_DOUBLE,0,world); + + file->mass = new double[file->nelements]; + memory->create(file->frho,file->nelements,file->nrho+1,"pair:frho"); + memory->create(file->rhor,file->nelements,file->nr+1,"pair:rhor"); + memory->create(file->z2r,file->nelements,file->nelements,file->nr+1, + "pair:z2r"); + + int i,j,tmp; + for (i = 0; i < file->nelements; i++) { + if (me == 0) { + fgets(line,MAXLINE,fptr); + sscanf(line,"%d %lg",&tmp,&file->mass[i]); + } + MPI_Bcast(&file->mass[i],1,MPI_DOUBLE,0,world); + + if (me == 0) grab(fptr,file->nrho,&file->frho[i][1]); + MPI_Bcast(&file->frho[i][1],file->nrho,MPI_DOUBLE,0,world); + if (me == 0) grab(fptr,file->nr,&file->rhor[i][1]); + MPI_Bcast(&file->rhor[i][1],file->nr,MPI_DOUBLE,0,world); + } + + for (i = 0; i < file->nelements; i++) + for (j = 0; j <= i; j++) { + if (me == 0) grab(fptr,file->nr,&file->z2r[i][j][1]); + MPI_Bcast(&file->z2r[i][j][1],file->nr,MPI_DOUBLE,0,world); + } + + // close the potential file + + if (me == 0) fclose(fptr); +} + +/* ---------------------------------------------------------------------- + copy read-in setfl potential to standard array format +------------------------------------------------------------------------- */ + +void PairEAMAlloyIntel::file2array() +{ + int i,j,m,n; + int ntypes = atom->ntypes; + + // set function params directly from setfl file + + nrho = setfl->nrho; + nr = setfl->nr; + drho = setfl->drho; + dr = setfl->dr; + rhomax = (nrho-1) * drho; + + // ------------------------------------------------------------------ + // setup frho arrays + // ------------------------------------------------------------------ + + // allocate frho arrays + // nfrho = # of setfl elements + 1 for zero array + + nfrho = setfl->nelements + 1; + memory->destroy(frho); + memory->create(frho,nfrho,nrho+1,"pair:frho"); + + // copy each element's frho to global frho + + for (i = 0; i < setfl->nelements; i++) + for (m = 1; m <= nrho; m++) frho[i][m] = setfl->frho[i][m]; + + // add extra frho of zeroes for non-EAM types to point to (pair hybrid) + // this is necessary b/c fp is still computed for non-EAM atoms + + for (m = 1; m <= nrho; m++) frho[nfrho-1][m] = 0.0; + + // type2frho[i] = which frho array (0 to nfrho-1) each atom type maps to + // if atom type doesn't point to element (non-EAM atom in pair hybrid) + // then map it to last frho array of zeroes + + for (i = 1; i <= ntypes; i++) + if (map[i] >= 0) type2frho[i] = map[i]; + else type2frho[i] = nfrho-1; + + // ------------------------------------------------------------------ + // setup rhor arrays + // ------------------------------------------------------------------ + + // allocate rhor arrays + // nrhor = # of setfl elements + + nrhor = setfl->nelements; + memory->destroy(rhor); + memory->create(rhor,nrhor,nr+1,"pair:rhor"); + + // copy each element's rhor to global rhor + + for (i = 0; i < setfl->nelements; i++) + for (m = 1; m <= nr; m++) rhor[i][m] = setfl->rhor[i][m]; + + // type2rhor[i][j] = which rhor array (0 to nrhor-1) each type pair maps to + // for setfl files, I,J mapping only depends on I + // OK if map = -1 (non-EAM atom in pair hybrid) b/c type2rhor not used + + for (i = 1; i <= ntypes; i++) + for (j = 1; j <= ntypes; j++) + type2rhor[i][j] = map[i]; + + // ------------------------------------------------------------------ + // setup z2r arrays + // ------------------------------------------------------------------ + + // allocate z2r arrays + // nz2r = N*(N+1)/2 where N = # of setfl elements + + nz2r = setfl->nelements * (setfl->nelements+1) / 2; + memory->destroy(z2r); + memory->create(z2r,nz2r,nr+1,"pair:z2r"); + + // copy each element pair z2r to global z2r, only for I >= J + + n = 0; + for (i = 0; i < setfl->nelements; i++) + for (j = 0; j <= i; j++) { + for (m = 1; m <= nr; m++) z2r[n][m] = setfl->z2r[i][j][m]; + n++; + } + + // type2z2r[i][j] = which z2r array (0 to nz2r-1) each type pair maps to + // set of z2r arrays only fill lower triangular Nelement matrix + // value = n = sum over rows of lower-triangular matrix until reach irow,icol + // swap indices when irow < icol to stay lower triangular + // if map = -1 (non-EAM atom in pair hybrid): + // type2z2r is not used by non-opt + // but set type2z2r to 0 since accessed by opt + + int irow,icol; + for (i = 1; i <= ntypes; i++) { + for (j = 1; j <= ntypes; j++) { + irow = map[i]; + icol = map[j]; + if (irow == -1 || icol == -1) { + type2z2r[i][j] = 0; + continue; + } + if (irow < icol) { + irow = map[j]; + icol = map[i]; + } + n = 0; + for (m = 0; m < irow; m++) n += m + 1; + n += icol; + type2z2r[i][j] = n; + } + } +} diff --git a/src/USER-INTEL/pair_eam_alloy_intel.h b/src/USER-INTEL/pair_eam_alloy_intel.h new file mode 100644 index 0000000000..4967c3709d --- /dev/null +++ b/src/USER-INTEL/pair_eam_alloy_intel.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(eam/alloy/intel,PairEAMAlloyIntel) + +#else + +#ifndef LMP_PAIR_EAM_ALLOY_INTEL_H +#define LMP_PAIR_EAM_ALLOY_INTEL_H + +#include "pair_eam_intel.h" + +namespace LAMMPS_NS { + +// need virtual public b/c of how eam/alloy/opt inherits from it + +class PairEAMAlloyIntel : virtual public PairEAMIntel { + public: + PairEAMAlloyIntel(class LAMMPS *); + virtual ~PairEAMAlloyIntel() {} + void coeff(int, char **); + + protected: + void read_file(char *); + void file2array(); +}; + +} + +#endif +#endif diff --git a/src/USER-INTEL/pair_eam_fs_intel.cpp b/src/USER-INTEL/pair_eam_fs_intel.cpp new file mode 100644 index 0000000000..cfcc8200cc --- /dev/null +++ b/src/USER-INTEL/pair_eam_fs_intel.cpp @@ -0,0 +1,335 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing authors: Tim Lau (MIT) +------------------------------------------------------------------------- */ + +#include +#include +#include +#include "pair_eam_fs_intel.h" +#include "atom.h" +#include "comm.h" +#include "force.h" +#include "memory.h" +#include "error.h" + +using namespace LAMMPS_NS; + +#define MAXLINE 1024 + +/* ---------------------------------------------------------------------- */ + +PairEAMFSIntel::PairEAMFSIntel(LAMMPS *lmp) : PairEAMIntel(lmp) +{ + one_coeff = 1; +} + +/* ---------------------------------------------------------------------- + set coeffs for one or more type pairs + read EAM Finnis-Sinclair file +------------------------------------------------------------------------- */ + +void PairEAMFSIntel::coeff(int narg, char **arg) +{ + int i,j; + + if (!allocated) allocate(); + + if (narg != 3 + atom->ntypes) + error->all(FLERR,"Incorrect args for pair coefficients"); + + // insure I,J args are * * + + if (strcmp(arg[0],"*") != 0 || strcmp(arg[1],"*") != 0) + error->all(FLERR,"Incorrect args for pair coefficients"); + + // read EAM Finnis-Sinclair file + + if (fs) { + for (i = 0; i < fs->nelements; i++) delete [] fs->elements[i]; + delete [] fs->elements; + delete [] fs->mass; + memory->destroy(fs->frho); + memory->destroy(fs->rhor); + memory->destroy(fs->z2r); + delete fs; + } + fs = new Fs(); + read_file(arg[2]); + + // read args that map atom types to elements in potential file + // map[i] = which element the Ith atom type is, -1 if NULL + + for (i = 3; i < narg; i++) { + if (strcmp(arg[i],"NULL") == 0) { + map[i-2] = -1; + continue; + } + for (j = 0; j < fs->nelements; j++) + if (strcmp(arg[i],fs->elements[j]) == 0) break; + if (j < fs->nelements) map[i-2] = j; + else error->all(FLERR,"No matching element in EAM potential file"); + } + + // clear setflag since coeff() called once with I,J = * * + + int n = atom->ntypes; + for (i = 1; i <= n; i++) + for (j = i; j <= n; j++) + setflag[i][j] = 0; + + // set setflag i,j for type pairs where both are mapped to elements + // set mass of atom type if i = j + + int count = 0; + for (i = 1; i <= n; i++) { + for (j = i; j <= n; j++) { + if (map[i] >= 0 && map[j] >= 0) { + setflag[i][j] = 1; + if (i == j) atom->set_mass(FLERR,i,fs->mass[map[i]]); + count++; + } + scale[i][j] = 1.0; + } + } + + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); +} + +/* ---------------------------------------------------------------------- + read a multi-element DYNAMO setfl file +------------------------------------------------------------------------- */ + +void PairEAMFSIntel::read_file(char *filename) +{ + Fs *file = fs; + + // open potential file + + int me = comm->me; + FILE *fptr; + char line[MAXLINE]; + + if (me == 0) { + fptr = force->open_potential(filename); + if (fptr == NULL) { + char str[128]; + sprintf(str,"Cannot open EAM potential file %s",filename); + error->one(FLERR,str); + } + } + + // read and broadcast header + // extract element names from nelements line + + int n; + if (me == 0) { + fgets(line,MAXLINE,fptr); + fgets(line,MAXLINE,fptr); + fgets(line,MAXLINE,fptr); + fgets(line,MAXLINE,fptr); + n = strlen(line) + 1; + } + MPI_Bcast(&n,1,MPI_INT,0,world); + MPI_Bcast(line,n,MPI_CHAR,0,world); + + sscanf(line,"%d",&file->nelements); + int nwords = atom->count_words(line); + if (nwords != file->nelements + 1) + error->all(FLERR,"Incorrect element names in EAM potential file"); + + char **words = new char*[file->nelements+1]; + nwords = 0; + strtok(line," \t\n\r\f"); + while ((words[nwords++] = strtok(NULL," \t\n\r\f"))) continue; + + file->elements = new char*[file->nelements]; + for (int i = 0; i < file->nelements; i++) { + n = strlen(words[i]) + 1; + file->elements[i] = new char[n]; + strcpy(file->elements[i],words[i]); + } + delete [] words; + + if (me == 0) { + fgets(line,MAXLINE,fptr); + sscanf(line,"%d %lg %d %lg %lg", + &file->nrho,&file->drho,&file->nr,&file->dr,&file->cut); + } + + MPI_Bcast(&file->nrho,1,MPI_INT,0,world); + MPI_Bcast(&file->drho,1,MPI_DOUBLE,0,world); + MPI_Bcast(&file->nr,1,MPI_INT,0,world); + MPI_Bcast(&file->dr,1,MPI_DOUBLE,0,world); + MPI_Bcast(&file->cut,1,MPI_DOUBLE,0,world); + + file->mass = new double[file->nelements]; + memory->create(file->frho,file->nelements,file->nrho+1, + "pair:frho"); + memory->create(file->rhor,file->nelements,file->nelements, + file->nr+1,"pair:rhor"); + memory->create(file->z2r,file->nelements,file->nelements, + file->nr+1,"pair:z2r"); + + int i,j,tmp; + for (i = 0; i < file->nelements; i++) { + if (me == 0) { + fgets(line,MAXLINE,fptr); + sscanf(line,"%d %lg",&tmp,&file->mass[i]); + } + MPI_Bcast(&file->mass[i],1,MPI_DOUBLE,0,world); + + if (me == 0) grab(fptr,file->nrho,&file->frho[i][1]); + MPI_Bcast(&file->frho[i][1],file->nrho,MPI_DOUBLE,0,world); + + for (j = 0; j < file->nelements; j++) { + if (me == 0) grab(fptr,file->nr,&file->rhor[i][j][1]); + MPI_Bcast(&file->rhor[i][j][1],file->nr,MPI_DOUBLE,0,world); + } + } + + for (i = 0; i < file->nelements; i++) + for (j = 0; j <= i; j++) { + if (me == 0) grab(fptr,file->nr,&file->z2r[i][j][1]); + MPI_Bcast(&file->z2r[i][j][1],file->nr,MPI_DOUBLE,0,world); + } + + // close the potential file + + if (me == 0) fclose(fptr); +} + +/* ---------------------------------------------------------------------- + copy read-in setfl potential to standard array format +------------------------------------------------------------------------- */ + +void PairEAMFSIntel::file2array() +{ + int i,j,m,n; + int ntypes = atom->ntypes; + + // set function params directly from fs file + + nrho = fs->nrho; + nr = fs->nr; + drho = fs->drho; + dr = fs->dr; + rhomax = (nrho-1) * drho; + + // ------------------------------------------------------------------ + // setup frho arrays + // ------------------------------------------------------------------ + + // allocate frho arrays + // nfrho = # of fs elements + 1 for zero array + + nfrho = fs->nelements + 1; + memory->destroy(frho); + memory->create(frho,nfrho,nrho+1,"pair:frho"); + + // copy each element's frho to global frho + + for (i = 0; i < fs->nelements; i++) + for (m = 1; m <= nrho; m++) frho[i][m] = fs->frho[i][m]; + + // add extra frho of zeroes for non-EAM types to point to (pair hybrid) + // this is necessary b/c fp is still computed for non-EAM atoms + + for (m = 1; m <= nrho; m++) frho[nfrho-1][m] = 0.0; + + // type2frho[i] = which frho array (0 to nfrho-1) each atom type maps to + // if atom type doesn't point to element (non-EAM atom in pair hybrid) + // then map it to last frho array of zeroes + + for (i = 1; i <= ntypes; i++) + if (map[i] >= 0) type2frho[i] = map[i]; + else type2frho[i] = nfrho-1; + + // ------------------------------------------------------------------ + // setup rhor arrays + // ------------------------------------------------------------------ + + // allocate rhor arrays + // nrhor = square of # of fs elements + + nrhor = fs->nelements * fs->nelements; + memory->destroy(rhor); + memory->create(rhor,nrhor,nr+1,"pair:rhor"); + + // copy each element pair rhor to global rhor + + n = 0; + for (i = 0; i < fs->nelements; i++) + for (j = 0; j < fs->nelements; j++) { + for (m = 1; m <= nr; m++) rhor[n][m] = fs->rhor[i][j][m]; + n++; + } + + // type2rhor[i][j] = which rhor array (0 to nrhor-1) each type pair maps to + // for fs files, there is a full NxN set of rhor arrays + // OK if map = -1 (non-EAM atom in pair hybrid) b/c type2rhor not used + + for (i = 1; i <= ntypes; i++) + for (j = 1; j <= ntypes; j++) + type2rhor[i][j] = map[i] * fs->nelements + map[j]; + + // ------------------------------------------------------------------ + // setup z2r arrays + // ------------------------------------------------------------------ + + // allocate z2r arrays + // nz2r = N*(N+1)/2 where N = # of fs elements + + nz2r = fs->nelements * (fs->nelements+1) / 2; + memory->destroy(z2r); + memory->create(z2r,nz2r,nr+1,"pair:z2r"); + + // copy each element pair z2r to global z2r, only for I >= J + + n = 0; + for (i = 0; i < fs->nelements; i++) + for (j = 0; j <= i; j++) { + for (m = 1; m <= nr; m++) z2r[n][m] = fs->z2r[i][j][m]; + n++; + } + + // type2z2r[i][j] = which z2r array (0 to nz2r-1) each type pair maps to + // set of z2r arrays only fill lower triangular Nelement matrix + // value = n = sum over rows of lower-triangular matrix until reach irow,icol + // swap indices when irow < icol to stay lower triangular + // if map = -1 (non-EAM atom in pair hybrid): + // type2z2r is not used by non-opt + // but set type2z2r to 0 since accessed by opt + + int irow,icol; + for (i = 1; i <= ntypes; i++) { + for (j = 1; j <= ntypes; j++) { + irow = map[i]; + icol = map[j]; + if (irow == -1 || icol == -1) { + type2z2r[i][j] = 0; + continue; + } + if (irow < icol) { + irow = map[j]; + icol = map[i]; + } + n = 0; + for (m = 0; m < irow; m++) n += m + 1; + n += icol; + type2z2r[i][j] = n; + } + } +} diff --git a/src/USER-INTEL/pair_eam_fs_intel.h b/src/USER-INTEL/pair_eam_fs_intel.h new file mode 100644 index 0000000000..da2ab9d2d7 --- /dev/null +++ b/src/USER-INTEL/pair_eam_fs_intel.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(eam/fs/intel,PairEAMFSIntel) + +#else + +#ifndef LMP_PAIR_EAM_FS_INTEL_H +#define LMP_PAIR_EAM_FS_INTEL_H + +#include "pair_eam_intel.h" + +namespace LAMMPS_NS { + +// need virtual public b/c of how eam/fs/opt inherits from it + +class PairEAMFSIntel : virtual public PairEAMIntel { + public: + PairEAMFSIntel(class LAMMPS *); + virtual ~PairEAMFSIntel() {} + void coeff(int, char **); + + protected: + void read_file(char *); + void file2array(); +}; + +} + +#endif +#endif diff --git a/src/USER-INTEL/pair_gayberne_intel.cpp b/src/USER-INTEL/pair_gayberne_intel.cpp index ed7dd424af..3fbb58308b 100644 --- a/src/USER-INTEL/pair_gayberne_intel.cpp +++ b/src/USER-INTEL/pair_gayberne_intel.cpp @@ -428,7 +428,7 @@ void PairGayBerneIntel::eval(const int offload, const int vflag, } else multiple_forms = true; } - const int edge = (packed_j % pad_width); + const int edge = packed_j & (pad_width - 1); if (edge) { const int packed_end = packed_j + (pad_width - edge); #if defined(LMP_SIMD_COMPILER) diff --git a/src/USER-INTEL/pair_lj_charmm_coul_charmm_intel.cpp b/src/USER-INTEL/pair_lj_charmm_coul_charmm_intel.cpp new file mode 100644 index 0000000000..0dc2c275e8 --- /dev/null +++ b/src/USER-INTEL/pair_lj_charmm_coul_charmm_intel.cpp @@ -0,0 +1,595 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + This software is distributed under the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: W. Michael Brown (Intel) +------------------------------------------------------------------------- */ + +#include +#include "pair_lj_charmm_coul_charmm_intel.h" +#include "atom.h" +#include "comm.h" +#include "force.h" +#include "group.h" +#include "memory.h" +#include "modify.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "neigh_request.h" +#include "memory.h" +#include "suffix.h" +using namespace LAMMPS_NS; + +#define LJ_T typename IntelBuffers::vec4_t + +/* ---------------------------------------------------------------------- */ + +PairLJCharmmCoulCharmmIntel::PairLJCharmmCoulCharmmIntel(LAMMPS *lmp) : + PairLJCharmmCoulCharmm(lmp) +{ + suffix_flag |= Suffix::INTEL; +} + +/* ---------------------------------------------------------------------- */ + +PairLJCharmmCoulCharmmIntel::~PairLJCharmmCoulCharmmIntel() +{ +} + +/* ---------------------------------------------------------------------- */ + +void PairLJCharmmCoulCharmmIntel::compute(int eflag, int vflag) +{ + if (fix->precision()==FixIntel::PREC_MODE_MIXED) + compute(eflag, vflag, fix->get_mixed_buffers(), + force_const_single); + else if (fix->precision()==FixIntel::PREC_MODE_DOUBLE) + compute(eflag, vflag, fix->get_double_buffers(), + force_const_double); + else + compute(eflag, vflag, fix->get_single_buffers(), + force_const_single); + + fix->balance_stamp(); + vflag_fdotr = 0; +} + +template +void PairLJCharmmCoulCharmmIntel::compute(int eflag, int vflag, + IntelBuffers *buffers, + const ForceConst &fc) +{ + if (eflag || vflag) { + ev_setup(eflag,vflag); + } else evflag = vflag_fdotr = 0; + + const int inum = list->inum; + const int nthreads = comm->nthreads; + const int host_start = fix->host_start_pair(); + const int offload_end = fix->offload_end_pair(); + const int ago = neighbor->ago; + + if (ago != 0 && fix->separate_buffers() == 0) { + fix->start_watch(TIME_PACK); + + int packthreads; + if (nthreads > INTEL_HTHREADS) packthreads = nthreads; + else packthreads = 1; + #if defined(_OPENMP) + #pragma omp parallel if(packthreads > 1) + #endif + { + int ifrom, ito, tid; + IP_PRE_omp_range_id_align(ifrom, ito, tid, atom->nlocal+atom->nghost, + packthreads, sizeof(ATOM_T)); + buffers->thr_pack(ifrom,ito,ago); + } + fix->stop_watch(TIME_PACK); + } + + // -------------------- Regular version + int ovflag = 0; + if (vflag_fdotr) ovflag = 2; + else if (vflag) ovflag = 1; + if (eflag) { + if (force->newton_pair) { + eval<1,1>(1, ovflag, buffers, fc, 0, offload_end); + eval<1,1>(0, ovflag, buffers, fc, host_start, inum); + } else { + eval<1,0>(1, ovflag, buffers, fc, 0, offload_end); + eval<1,0>(0, ovflag, buffers, fc, host_start, inum); + } + } else { + if (force->newton_pair) { + eval<0,1>(1, ovflag, buffers, fc, 0, offload_end); + eval<0,1>(0, ovflag, buffers, fc, host_start, inum); + } else { + eval<0,0>(1, ovflag, buffers, fc, 0, offload_end); + eval<0,0>(0, ovflag, buffers, fc, host_start, inum); + } + } +} + +/* ---------------------------------------------------------------------- */ + +template +void PairLJCharmmCoulCharmmIntel::eval(const int offload, const int vflag, + IntelBuffers *buffers, + const ForceConst &fc, + const int astart, const int aend) +{ + const int inum = aend - astart; + if (inum == 0) return; + int nlocal, nall, minlocal; + fix->get_buffern(offload, nlocal, nall, minlocal); + + const int ago = neighbor->ago; + IP_PRE_pack_separate_buffers(fix, buffers, ago, offload, nlocal, nall); + + ATOM_T * _noalias const x = buffers->get_x(offload); + flt_t * _noalias const q = buffers->get_q(offload); + + const int * _noalias const numneigh = list->numneigh; + const int * _noalias const cnumneigh = buffers->cnumneigh(list); + const int * _noalias const firstneigh = buffers->firstneigh(list); + + const flt_t * _noalias const special_coul = fc.special_coul; + const flt_t * _noalias const special_lj = fc.special_lj; + const flt_t qqrd2e = force->qqrd2e; + const flt_t inv_denom_lj = (flt_t)1.0/denom_lj; + const flt_t inv_denom_coul = (flt_t)1.0/denom_coul; + + const flt_t * _noalias const cutsq = fc.cutsq[0]; + const LJ_T * _noalias const lj = fc.lj[0]; + const flt_t cut_ljsq = fc.cut_ljsq; + const flt_t cut_lj_innersq = fc.cut_lj_innersq; + const flt_t cut_coul_innersq = fc.cut_coul_innersq; + const flt_t cut_coulsq = fc.cut_coulsq; + + const int ntypes = atom->ntypes + 1; + const int eatom = this->eflag_atom; + + flt_t * _noalias const ccachex = buffers->get_ccachex(); + flt_t * _noalias const ccachey = buffers->get_ccachey(); + flt_t * _noalias const ccachez = buffers->get_ccachez(); + flt_t * _noalias const ccachew = buffers->get_ccachew(); + int * _noalias const ccachei = buffers->get_ccachei(); + int * _noalias const ccachej = buffers->get_ccachej(); + const int ccache_stride = _ccache_stride; + + // Determine how much data to transfer + int x_size, q_size, f_stride, ev_size, separate_flag; + IP_PRE_get_transfern(ago, NEWTON_PAIR, EFLAG, vflag, + buffers, offload, fix, separate_flag, + x_size, q_size, ev_size, f_stride); + + int tc; + FORCE_T * _noalias f_start; + acc_t * _noalias ev_global; + IP_PRE_get_buffers(offload, buffers, fix, tc, f_start, ev_global); + + const int nthreads = tc; + #ifdef _LMP_INTEL_OFFLOAD + int *overflow = fix->get_off_overflow_flag(); + double *timer_compute = fix->off_watch_pair(); + + if (offload) fix->start_watch(TIME_OFFLOAD_LATENCY); + #pragma offload target(mic:_cop) if(offload) \ + in(special_lj,special_coul:length(0) alloc_if(0) free_if(0)) \ + in(cutsq,lj:length(0) alloc_if(0) free_if(0)) \ + in(firstneigh:length(0) alloc_if(0) free_if(0)) \ + in(cnumneigh:length(0) alloc_if(0) free_if(0)) \ + in(numneigh:length(0) alloc_if(0) free_if(0)) \ + in(x:length(x_size) alloc_if(0) free_if(0)) \ + in(q:length(q_size) alloc_if(0) free_if(0)) \ + in(overflow:length(0) alloc_if(0) free_if(0)) \ + in(ccachex,ccachey,ccachez,ccachew:length(0) alloc_if(0) free_if(0)) \ + in(ccachei,ccachej:length(0) alloc_if(0) free_if(0)) \ + in(ccache_stride,nthreads,qqrd2e,inum,nall,ntypes,cut_coulsq) \ + in(vflag,eatom,f_stride,separate_flag,offload) \ + in(astart,cut_ljsq,cut_lj_innersq,nlocal,inv_denom_lj,minlocal) \ + in(inv_denom_coul,cut_coul_innersq) \ + out(f_start:length(f_stride) alloc_if(0) free_if(0)) \ + out(ev_global:length(ev_size) alloc_if(0) free_if(0)) \ + out(timer_compute:length(1) alloc_if(0) free_if(0)) \ + signal(f_start) + #endif + { + #if defined(__MIC__) && defined(_LMP_INTEL_OFFLOAD) + *timer_compute = MIC_Wtime(); + #endif + + IP_PRE_repack_for_offload(NEWTON_PAIR, separate_flag, nlocal, nall, + f_stride, x, q); + + acc_t oevdwl, oecoul, ov0, ov1, ov2, ov3, ov4, ov5; + if (EFLAG) oevdwl = oecoul = (acc_t)0; + if (vflag) ov0 = ov1 = ov2 = ov3 = ov4 = ov5 = (acc_t)0; + + // loop over neighbors of my atoms + #if defined(_OPENMP) + #pragma omp parallel reduction(+:oevdwl,oecoul,ov0,ov1,ov2,ov3,ov4,ov5) + #endif + { + int iifrom, iip, iito, tid; + IP_PRE_omp_stride_id(iifrom, iip, iito, tid, inum, nthreads); + iifrom += astart; + iito += astart; + + int foff; + if (NEWTON_PAIR) foff = tid * f_stride - minlocal; + else foff = -minlocal; + FORCE_T * _noalias const f = f_start + foff; + if (NEWTON_PAIR) memset(f + minlocal, 0, f_stride * sizeof(FORCE_T)); + flt_t cutboth = cut_coulsq; + + const int toffs = tid * ccache_stride; + flt_t * _noalias const tdelx = ccachex + toffs; + flt_t * _noalias const tdely = ccachey + toffs; + flt_t * _noalias const tdelz = ccachez + toffs; + flt_t * _noalias const trsq = ccachew + toffs; + int * _noalias const tj = ccachei + toffs; + int * _noalias const tjtype = ccachej + toffs; + + for (int i = iifrom; i < iito; i += iip) { + // const int i = ilist[ii]; + const int itype = x[i].w; + + const int ptr_off = itype * ntypes; + const flt_t * _noalias const cutsqi = cutsq + ptr_off; + const LJ_T * _noalias const lji = lj + ptr_off; + + const int * _noalias const jlist = firstneigh + cnumneigh[i]; + const int jnum = numneigh[i]; + + acc_t fxtmp,fytmp,fztmp,fwtmp; + acc_t sevdwl, secoul, sv0, sv1, sv2, sv3, sv4, sv5; + + const flt_t xtmp = x[i].x; + const flt_t ytmp = x[i].y; + const flt_t ztmp = x[i].z; + const flt_t qtmp = q[i]; + fxtmp = fytmp = fztmp = (acc_t)0; + if (EFLAG) fwtmp = sevdwl = secoul = (acc_t)0; + if (NEWTON_PAIR == 0) + if (vflag==1) sv0 = sv1 = sv2 = sv3 = sv4 = sv5 = (acc_t)0; + + int ej = 0; + #if defined(LMP_SIMD_COMPILER) + #pragma vector aligned + #pragma ivdep + #endif + for (int jj = 0; jj < jnum; jj++) { + const int j = jlist[jj] & NEIGHMASK; + const flt_t delx = xtmp - x[j].x; + const flt_t dely = ytmp - x[j].y; + const flt_t delz = ztmp - x[j].z; + const flt_t rsq = delx * delx + dely * dely + delz * delz; + + if (rsq < cut_coulsq) { + trsq[ej]=rsq; + tdelx[ej]=delx; + tdely[ej]=dely; + tdelz[ej]=delz; + tjtype[ej]=x[j].w; + tj[ej]=jlist[jj]; + ej++; + } + } + + #if defined(LMP_SIMD_COMPILER) + #pragma vector aligned + #pragma simd reduction(+:fxtmp, fytmp, fztmp, fwtmp, sevdwl, secoul, \ + sv0, sv1, sv2, sv3, sv4, sv5) + #endif + for (int jj = 0; jj < ej; jj++) { + flt_t forcecoul, forcelj, evdwl; + forcecoul = forcelj = evdwl = (flt_t)0.0; + + const int j = tj[jj] & NEIGHMASK; + 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); + forcecoul = qqrd2e * qtmp * q[j] * r_inv; + if (rsq > cut_coul_innersq) { + const flt_t ccr = cut_coulsq - rsq; + const flt_t switch1 = ccr * ccr * inv_denom_coul * + (cut_coulsq + (flt_t)2.0 * rsq - (flt_t)3.0 * cut_coul_innersq); + forcecoul *= switch1; + } + + #ifdef INTEL_VMASK + if (rsq < cut_ljsq) { + #endif + const int jtype = tjtype[jj]; + flt_t r6inv = r2inv * r2inv * r2inv; + forcelj = r6inv * (lji[jtype].x * r6inv - lji[jtype].y); + if (EFLAG) evdwl = r6inv*(lji[jtype].z * r6inv - lji[jtype].w); + + #ifdef INTEL_VMASK + if (rsq > cut_lj_innersq) { + #endif + const flt_t drsq = cut_ljsq - rsq; + const flt_t cut2 = (rsq - cut_lj_innersq) * drsq; + const flt_t switch1 = drsq * (drsq * drsq + (flt_t)3.0 * cut2) * + inv_denom_lj; + const flt_t switch2 = (flt_t)12.0 * rsq * cut2 * inv_denom_lj; + if (EFLAG) { + #ifndef INTEL_VMASK + if (rsq > cut_lj_innersq) { + #endif + forcelj = forcelj * switch1 + evdwl * switch2; + evdwl *= switch1; + #ifndef INTEL_VMASK + } + #endif + } else { + const flt_t philj = r6inv * (lji[jtype].z*r6inv - + lji[jtype].w); + #ifndef INTEL_VMASK + if (rsq > cut_lj_innersq) + #endif + forcelj = forcelj * switch1 + philj * switch2; + } + #ifdef INTEL_VMASK + } + #endif + + #ifdef INTEL_VMASK + } + #else + if (rsq > cut_ljsq) { forcelj = (flt_t)0.0; evdwl = (flt_t)0.0; } + #endif + if (sbindex) { + const flt_t factor_coul = special_coul[sbindex]; + forcecoul *= factor_coul; + const flt_t factor_lj = special_lj[sbindex]; + forcelj *= factor_lj; + if (EFLAG) evdwl *= factor_lj; + } + + const flt_t fpair = (forcecoul + forcelj) * r2inv; + const flt_t fpx = fpair * tdelx[jj]; + fxtmp += fpx; + if (NEWTON_PAIR) f[j].x -= fpx; + const flt_t fpy = fpair * tdely[jj]; + fytmp += fpy; + if (NEWTON_PAIR) f[j].y -= fpy; + const flt_t fpz = fpair * tdelz[jj]; + fztmp += fpz; + if (NEWTON_PAIR) f[j].z -= fpz; + + if (EFLAG) { + sevdwl += evdwl; + secoul += forcecoul; + if (eatom) { + fwtmp += (flt_t)0.5 * evdwl + (flt_t)0.5 * forcecoul; + if (NEWTON_PAIR) + f[j].w += (flt_t)0.5 * evdwl + (flt_t)0.5 * forcecoul; + } + } + if (NEWTON_PAIR == 0) + IP_PRE_ev_tally_nborv(vflag, tdelx[jj], tdely[jj], tdelz[jj], + fpx, fpy, fpz); + } // for jj + if (NEWTON_PAIR) { + f[i].x += fxtmp; + f[i].y += fytmp; + f[i].z += fztmp; + } else { + f[i].x = fxtmp; + f[i].y = fytmp; + f[i].z = fztmp; + } + IP_PRE_ev_tally_atomq(NEWTON_PAIR, EFLAG, vflag, f, fwtmp); + } // for ii + + IP_PRE_fdotr_reduce_omp(NEWTON_PAIR, nall, minlocal, nthreads, f_start, + f_stride, x, offload, vflag, ov0, ov1, ov2, ov3, + ov4, ov5); + } // end of omp parallel region + + IP_PRE_fdotr_reduce(NEWTON_PAIR, nall, nthreads, f_stride, vflag, + ov0, ov1, ov2, ov3, ov4, ov5); + + if (EFLAG) { + if (NEWTON_PAIR == 0) { + oevdwl *= (acc_t)0.5; + oecoul *= (acc_t)0.5; + } + ev_global[0] = oevdwl; + ev_global[1] = oecoul; + } + if (vflag) { + if (NEWTON_PAIR == 0) { + ov0 *= (acc_t)0.5; + ov1 *= (acc_t)0.5; + ov2 *= (acc_t)0.5; + ov3 *= (acc_t)0.5; + ov4 *= (acc_t)0.5; + ov5 *= (acc_t)0.5; + } + ev_global[2] = ov0; + ev_global[3] = ov1; + ev_global[4] = ov2; + ev_global[5] = ov3; + ev_global[6] = ov4; + ev_global[7] = ov5; + } + #if defined(__MIC__) && defined(_LMP_INTEL_OFFLOAD) + *timer_compute = MIC_Wtime() - *timer_compute; + #endif + } // end of offload region + + if (offload) + fix->stop_watch(TIME_OFFLOAD_LATENCY); + else + fix->stop_watch(TIME_HOST_PAIR); + + if (EFLAG || vflag) + fix->add_result_array(f_start, ev_global, offload, eatom, 0, vflag); + else + fix->add_result_array(f_start, 0, offload); +} + +/* ---------------------------------------------------------------------- */ + +void PairLJCharmmCoulCharmmIntel::init_style() +{ + PairLJCharmmCoulCharmm::init_style(); + if (force->newton_pair == 0) { + neighbor->requests[neighbor->nrequest-1]->half = 0; + neighbor->requests[neighbor->nrequest-1]->full = 1; + } + neighbor->requests[neighbor->nrequest-1]->intel = 1; + + int ifix = modify->find_fix("package_intel"); + if (ifix < 0) + error->all(FLERR, + "The 'package intel' command is required for /intel styles"); + fix = static_cast(modify->fix[ifix]); + + fix->pair_init_check(); + #ifdef _LMP_INTEL_OFFLOAD + _cop = fix->coprocessor_number(); + #endif + + if (fix->precision() == FixIntel::PREC_MODE_MIXED) + pack_force_const(force_const_single, fix->get_mixed_buffers()); + else if (fix->precision() == FixIntel::PREC_MODE_DOUBLE) + pack_force_const(force_const_double, fix->get_double_buffers()); + else + pack_force_const(force_const_single, fix->get_single_buffers()); +} + +template +void PairLJCharmmCoulCharmmIntel::pack_force_const(ForceConst &fc, + IntelBuffers *buffers) +{ + int off_ccache = 0; + #ifdef _LMP_INTEL_OFFLOAD + if (_cop >= 0) off_ccache = 1; + #endif + buffers->grow_ccache(off_ccache, comm->nthreads, 1); + _ccache_stride = buffers->ccache_stride(); + + int tp1 = atom->ntypes + 1; + + fc.set_ntypes(tp1, memory, _cop); + buffers->set_ntypes(tp1); + flt_t **cutneighsq = buffers->get_cutneighsq(); + + // Repeat cutsq calculation because done after call to init_style + double cut, cutneigh; + if (cut_lj > cut_coul) + error->all(FLERR, + "Intel varient of lj/charmm/coul/long expects lj cutoff<=coulombic"); + for (int i = 1; i <= atom->ntypes; i++) { + for (int j = i; j <= atom->ntypes; j++) { + if (setflag[i][j] != 0 || (setflag[i][i] != 0 && setflag[j][j] != 0)) { + cut = init_one(i, j); + cutneigh = cut + neighbor->skin; + cutsq[i][j] = cutsq[j][i] = cut*cut; + cutneighsq[i][j] = cutneighsq[j][i] = cutneigh * cutneigh; + } + } + } + + cut_coul_innersq = cut_coul_inner * cut_coul_inner; + cut_lj_innersq = cut_lj_inner * cut_lj_inner; + cut_ljsq = cut_lj * cut_lj; + cut_coulsq = cut_coul * cut_coul; + cut_bothsq = MAX(cut_ljsq, cut_coulsq); + + fc.cut_coulsq = cut_coulsq; + fc.cut_ljsq = cut_ljsq; + fc.cut_coul_innersq = cut_coul_innersq; + fc.cut_lj_innersq = cut_lj_innersq; + + for (int i = 0; i < 4; i++) { + fc.special_lj[i] = force->special_lj[i]; + fc.special_coul[i] = force->special_coul[i]; + fc.special_coul[0] = 1.0; + fc.special_lj[0] = 1.0; + } + + for (int i = 0; i < tp1; i++) { + for (int j = 0; j < tp1; j++) { + fc.lj[i][j].x = lj1[i][j]; + fc.lj[i][j].y = lj2[i][j]; + fc.lj[i][j].z = lj3[i][j]; + fc.lj[i][j].w = lj4[i][j]; + fc.cutsq[i][j] = cutsq[i][j]; + } + } + + #ifdef _LMP_INTEL_OFFLOAD + if (_cop < 0) return; + flt_t * special_lj = fc.special_lj; + flt_t * special_coul = fc.special_coul; + flt_t * cutsq = fc.cutsq[0]; + LJ_T * lj = fc.lj[0]; + flt_t * ocutneighsq = cutneighsq[0]; + int tp1sq = tp1 * tp1; + #pragma offload_transfer target(mic:_cop) \ + in(special_lj, special_coul: length(4) alloc_if(0) free_if(0)) \ + in(cutsq,lj: length(tp1sq) alloc_if(0) free_if(0)) \ + in(ocutneighsq: length(tp1sq) alloc_if(0) free_if(0)) + #endif +} + +/* ---------------------------------------------------------------------- */ + +template +void PairLJCharmmCoulCharmmIntel::ForceConst::set_ntypes( + const int ntypes, Memory *memory, const int cop) { + if (ntypes != _ntypes) { + if (_ntypes > 0) { + #ifdef _LMP_INTEL_OFFLOAD + flt_t * ospecial_lj = special_lj; + flt_t * ospecial_coul = special_coul; + flt_t * ocutsq = cutsq[0]; + typename IntelBuffers::vec4_t * olj = lj[0]; + if (ospecial_lj != NULL && ocutsq != NULL && olj != NULL && + ospecial_coul != NULL && cop >= 0) { + #pragma offload_transfer target(mic:cop) \ + nocopy(ospecial_lj, ospecial_coul: alloc_if(0) free_if(1)) \ + nocopy(ocutsq, olj: alloc_if(0) free_if(1)) + } + #endif + + _memory->destroy(cutsq); + _memory->destroy(lj); + } + if (ntypes > 0) { + _cop = cop; + memory->create(cutsq,ntypes,ntypes,"fc.cutsq"); + memory->create(lj,ntypes,ntypes,"fc.lj"); + + #ifdef _LMP_INTEL_OFFLOAD + flt_t * ospecial_lj = special_lj; + flt_t * ospecial_coul = special_coul; + flt_t * ocutsq = cutsq[0]; + typename IntelBuffers::vec4_t * olj = lj[0]; + int tp1sq = ntypes*ntypes; + if (ospecial_lj != NULL && ocutsq != NULL && olj != NULL && + ospecial_coul != NULL && cop >= 0) { + #pragma offload_transfer target(mic:cop) \ + nocopy(ospecial_lj: length(4) alloc_if(1) free_if(0)) \ + nocopy(ospecial_coul: length(4) alloc_if(1) free_if(0)) \ + nocopy(ocutsq,olj: length(tp1sq) alloc_if(1) free_if(0)) + } + #endif + } + } + _ntypes=ntypes; + _memory=memory; +} diff --git a/src/USER-INTEL/pair_lj_charmm_coul_charmm_intel.h b/src/USER-INTEL/pair_lj_charmm_coul_charmm_intel.h new file mode 100644 index 0000000000..64d6077477 --- /dev/null +++ b/src/USER-INTEL/pair_lj_charmm_coul_charmm_intel.h @@ -0,0 +1,100 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: W. Michael Brown (Intel) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(lj/charmm/coul/charmm/intel,PairLJCharmmCoulCharmmIntel) + +#else + +#ifndef LMP_PAIR_LJ_CHARMM_COUL_CHARMM_INTEL_H +#define LMP_PAIR_LJ_CHARMM_COUL_CHARMM_INTEL_H + +#include "pair_lj_charmm_coul_charmm.h" +#include "fix_intel.h" + +namespace LAMMPS_NS { + +class PairLJCharmmCoulCharmmIntel : public PairLJCharmmCoulCharmm { + + public: + PairLJCharmmCoulCharmmIntel(class LAMMPS *); + virtual ~PairLJCharmmCoulCharmmIntel(); + + virtual void compute(int, int); + void init_style(); + + typedef struct { float x,y,z; int w; } sng4_t; + + private: + FixIntel *fix; + int _cop, _ccache_stride; + + template class ForceConst; + template + void compute(int eflag, int vflag, IntelBuffers *buffers, + const ForceConst &fc); + template + void eval(const int offload, const int vflag, + IntelBuffers * buffers, + const ForceConst &fc, const int astart, const int aend); + + template + void pack_force_const(ForceConst &fc, + IntelBuffers *buffers); + + // ---------------------------------------------------------------------- + template + class ForceConst { + public: + _alignvar(flt_t special_coul[4],64); + _alignvar(flt_t special_lj[4],64); + flt_t **cutsq; + flt_t cut_coulsq, cut_ljsq; + flt_t cut_coul_innersq, cut_lj_innersq; + typename IntelBuffers::vec4_t **lj; + + ForceConst() : _ntypes(0) {} + ~ForceConst() { set_ntypes(0,NULL,_cop); } + + void set_ntypes(const int ntypes, Memory *memory, const int cop); + + private: + int _ntypes, _cop; + Memory *_memory; + }; + ForceConst force_const_single; + ForceConst force_const_double; +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +E: The 'package intel' command is required for /intel styles + +Self-explanatory. + +E: Intel varient of lj/charmm/coul/charmm expects lj cutoff<=coulombic + +The intel accelerated version of the CHARMM style requires that the +Lennard-Jones cutoff is not greater than the coulombic cutoff. + +*/ diff --git a/src/USER-INTEL/pair_rebo_intel.cpp b/src/USER-INTEL/pair_rebo_intel.cpp new file mode 100644 index 0000000000..006830a5fa --- /dev/null +++ b/src/USER-INTEL/pair_rebo_intel.cpp @@ -0,0 +1,42 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Markus Hohnerbach (RWTH) +------------------------------------------------------------------------- */ + +#include "pair_rebo_intel.h" +#include "error.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +PairREBOIntel::PairREBOIntel(LAMMPS *lmp) : PairAIREBOIntel(lmp) {} + +/* ---------------------------------------------------------------------- + global settings +------------------------------------------------------------------------- */ + +void PairREBOIntel::settings(int narg, char **arg) +{ + if (narg != 0) error->all(FLERR,"Illegal pair_style command"); + + cutlj = 0.0; + ljflag = torflag = 0; + // + // this one parameter for C-C interactions is different in REBO vs AIREBO + // see Favata, Micheletti, Ryu, Pugno, Comp Phys Comm (2016) + + PCCf_2_0 = 0.0; +} diff --git a/src/USER-INTEL/pair_rebo_intel.h b/src/USER-INTEL/pair_rebo_intel.h new file mode 100644 index 0000000000..e76279a248 --- /dev/null +++ b/src/USER-INTEL/pair_rebo_intel.h @@ -0,0 +1,40 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Markus Hohnerbach (RWTH) +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(rebo/intel,PairREBOIntel) + +#else + +#ifndef LMP_PAIR_REBO_INTEL_H +#define LMP_PAIR_REBO_INTEL_H + +#include "pair_airebo_intel.h" + +namespace LAMMPS_NS { + +class PairREBOIntel : public PairAIREBOIntel { + public: + PairREBOIntel(class LAMMPS *); + virtual void settings(int, char **); +}; + +} + +#endif +#endif diff --git a/src/USER-INTEL/pair_sw_intel.cpp b/src/USER-INTEL/pair_sw_intel.cpp index 7a6b7afd92..fff104f39b 100644 --- a/src/USER-INTEL/pair_sw_intel.cpp +++ b/src/USER-INTEL/pair_sw_intel.cpp @@ -345,16 +345,17 @@ void PairSWIntel::eval(const int offload, const int vflag, if (jj < jnumhalf) ejnumhalf++; } } - int ejnum_pad = ejnum; - while ( (ejnum_pad % pad_width) != 0) { - tdelx[ejnum_pad] = (flt_t)0.0; - tdely[ejnum_pad] = (flt_t)0.0; - tdelz[ejnum_pad] = (flt_t)0.0; - trsq[ejnum_pad] = p2[3].cutsq + (flt_t)1.0; - tj[ejnum_pad] = nall; - if (!ONETYPE) tjtype[ejnum_pad] = 0; - ejnum_pad++; + int ejrem = ejnum & (pad_width - 1); + if (ejrem) ejrem = pad_width - ejrem; + const int ejnum_pad = ejnum + ejrem; + for (int jj = ejnum; jj < ejnum_pad; jj++) { + tdelx[jj] = (flt_t)0.0; + tdely[jj] = (flt_t)0.0; + tdelz[jj] = (flt_t)0.0; + trsq[jj] = p2[3].cutsq + (flt_t)1.0; + tj[jj] = nall; + if (!ONETYPE) tjtype[jj] = 0; } #if defined(LMP_SIMD_COMPILER) From e34b20405c2807bc0638cf631fe3c4ee333f300a Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 15 Aug 2017 21:10:05 -0400 Subject: [PATCH 363/439] Fix a couple of typos in the docs --- doc/src/accelerate_intel.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/src/accelerate_intel.txt b/doc/src/accelerate_intel.txt index f5e25d6b64..a7c3382caa 100644 --- a/doc/src/accelerate_intel.txt +++ b/doc/src/accelerate_intel.txt @@ -30,8 +30,8 @@ Dihedral Styles: charmm, harmonic, opls :l Fixes: nve, npt, nvt, nvt/sllod :l Improper Styles: cvff, harmonic :l Pair Styles: airebo, airebo/morse, buck/coul/cut, buck/coul/long, -buck, eam, eam/alloy, eam/fs, gayberne, charmm/coul/charmm, -charmm/coul/long, lj/cut, lj/cut/coul/long, lj/long/coul/long, rebo, +buck, eam, eam/alloy, eam/fs, gayberne, lj/charmm/coul/charmm, +lj/charmm/coul/long, lj/cut, lj/cut/coul/long, lj/long/coul/long, rebo, sw, tersoff :l K-Space Styles: pppm, pppm/disp :l :ule From 7175abcc7170330109c954410f381172cfd1a232 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 16 Aug 2017 13:58:46 -0400 Subject: [PATCH 364/439] flag more pair styles as supporting USER-INTEL to match newly added code --- doc/src/Section_commands.txt | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/doc/src/Section_commands.txt b/doc/src/Section_commands.txt index f1eb225fe5..571c6c4920 100644 --- a/doc/src/Section_commands.txt +++ b/doc/src/Section_commands.txt @@ -892,8 +892,8 @@ KOKKOS, o = USER-OMP, t = OPT. "hybrid"_pair_hybrid.html, "hybrid/overlay"_pair_hybrid.html, "adp (o)"_pair_adp.html, -"airebo (o)"_pair_airebo.html, -"airebo/morse (o)"_pair_airebo.html, +"airebo (oi)"_pair_airebo.html, +"airebo/morse (oi)"_pair_airebo.html, "beck (go)"_pair_beck.html, "body"_pair_body.html, "bop"_pair_bop.html, @@ -927,8 +927,8 @@ KOKKOS, o = USER-OMP, t = OPT. "dpd/tstat (go)"_pair_dpd.html, "dsmc"_pair_dsmc.html, "eam (gkiot)"_pair_eam.html, -"eam/alloy (gkot)"_pair_eam.html, -"eam/fs (gkot)"_pair_eam.html, +"eam/alloy (gkiot)"_pair_eam.html, +"eam/fs (gkiot)"_pair_eam.html, "eim (o)"_pair_eim.html, "gauss (go)"_pair_gauss.html, "gayberne (gio)"_pair_gayberne.html, @@ -942,9 +942,9 @@ KOKKOS, o = USER-OMP, t = OPT. "kim"_pair_kim.html, "lcbop"_pair_lcbop.html, "line/lj"_pair_line_lj.html, -"lj/charmm/coul/charmm (ko)"_pair_charmm.html, +"lj/charmm/coul/charmm (kio)"_pair_charmm.html, "lj/charmm/coul/charmm/implicit (ko)"_pair_charmm.html, -"lj/charmm/coul/long (giko)"_pair_charmm.html, +"lj/charmm/coul/long (gkio)"_pair_charmm.html, "lj/charmm/coul/msm"_pair_charmm.html, "lj/charmmfsw/coul/charmmfsh"_pair_charmm.html, "lj/charmmfsw/coul/long"_pair_charmm.html, @@ -990,7 +990,7 @@ KOKKOS, o = USER-OMP, t = OPT. "polymorphic"_pair_polymorphic.html, "python"_pair_python.html, "reax"_pair_reax.html, -"rebo (o)"_pair_airebo.html, +"rebo (oi)"_pair_airebo.html, "resquared (go)"_pair_resquared.html, "snap"_pair_snap.html, "soft (go)"_pair_soft.html, From 7ddcb6812b44cdd13ea4ce5278f57874f544d693 Mon Sep 17 00:00:00 2001 From: Steve Plimpton Date: Thu, 17 Aug 2017 16:02:20 -0600 Subject: [PATCH 365/439] patch 17Aug17 --- doc/src/Manual.txt | 4 ++-- src/version.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/src/Manual.txt b/doc/src/Manual.txt index a840c2e0c6..bb2e1b8114 100644 --- a/doc/src/Manual.txt +++ b/doc/src/Manual.txt @@ -1,7 +1,7 @@ LAMMPS Users Manual - + @@ -21,7 +21,7 @@

LAMMPS Documentation :c,h3 -11 Aug 2017 version :c,h4 +17 Aug 2017 version :c,h4 Version info: :h4 diff --git a/src/version.h b/src/version.h index 0c7d5a2307..ff33fa3b06 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define LAMMPS_VERSION "11 Aug 2017" +#define LAMMPS_VERSION "17 Aug 2017" From 9e85b3178a14f45fc5ab88e1408e71dc15a4cf38 Mon Sep 17 00:00:00 2001 From: jrgissing Date: Thu, 17 Aug 2017 21:39:25 -0600 Subject: [PATCH 366/439] molecule maxspecial value corrected when specials autogenerated --- src/molecule.cpp | 52 +++++++++++++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 21 deletions(-) diff --git a/src/molecule.cpp b/src/molecule.cpp index b0fec4bcbc..77ceea8781 100644 --- a/src/molecule.cpp +++ b/src/molecule.cpp @@ -615,14 +615,12 @@ void Molecule::read(int flag) } // auto-generate special bonds if needed and not in file - // set maxspecial on first pass, so allocate() has a size if (bondflag && specialflag == 0) { if (domain->box_exist == 0) error->all(FLERR,"Cannot auto-generate special bonds before " "simulation box is defined"); - maxspecial = atom->maxspecial; if (flag) { special_generate(); specialflag = 1; @@ -1115,6 +1113,9 @@ void Molecule::special_generate() tagint atom1,atom2; int count[natoms]; + // temporary special array + tagint spec_temp[natoms][atom->maxspecial]; + for (int i = 0; i < natoms; i++) count[i] = 0; // 1-2 neighbors @@ -1126,10 +1127,10 @@ void Molecule::special_generate() atom2 = bond_atom[i][j]-1; nspecial[i][0]++; nspecial[atom2][0]++; - if (count[i] >= maxspecial || count[atom2] >= maxspecial) + if (count[i] >= atom->maxspecial || count[atom2] >= atom->maxspecial) error->one(FLERR,"Molecule auto special bond generation overflow"); - special[i][count[i]++] = atom2 + 1; - special[atom2][count[atom2]++] = i + 1; + spec_temp[i][count[i]++] = atom2 + 1; + spec_temp[atom2][count[atom2]++] = i + 1; } } } else { @@ -1138,9 +1139,9 @@ void Molecule::special_generate() for (int j = 0; j < num_bond[i]; j++) { atom1 = i; atom2 = bond_atom[i][j]; - if (count[atom1] >= maxspecial) + if (count[atom1] >= atom->maxspecial) error->one(FLERR,"Molecule auto special bond generation overflow"); - special[i][count[atom1]++] = atom2; + spec_temp[i][count[atom1]++] = atom2; } } } @@ -1152,18 +1153,18 @@ void Molecule::special_generate() int dedup; for (int i = 0; i < natoms; i++) { for (int m = 0; m < nspecial[i][0]; m++) { - for (int j = 0; j < nspecial[special[i][m]-1][0]; j++) { + for (int j = 0; j < nspecial[spec_temp[i][m]-1][0]; j++) { dedup = 0; for (int k =0; k < count[i]; k++) { - if (special[special[i][m]-1][j] == special[i][k] || - special[special[i][m]-1][j] == i+1) { + if (spec_temp[spec_temp[i][m]-1][j] == spec_temp[i][k] || + spec_temp[spec_temp[i][m]-1][j] == i+1) { dedup = 1; } } if (!dedup) { - if (count[i] >= maxspecial) + if (count[i] >= atom->maxspecial) error->one(FLERR,"Molecule auto special bond generation overflow"); - special[i][count[i]++] = special[special[i][m]-1][j]; + spec_temp[i][count[i]++] = spec_temp[spec_temp[i][m]-1][j]; nspecial[i][1]++; } } @@ -1176,23 +1177,32 @@ void Molecule::special_generate() for (int i = 0; i < natoms; i++) { for (int m = nspecial[i][0]; m < nspecial[i][1]; m++) { - for (int j = 0; j < nspecial[special[i][m]-1][0]; j++) { + for (int j = 0; j < nspecial[spec_temp[i][m]-1][0]; j++) { dedup = 0; for (int k =0; k < count[i]; k++) { - if (special[special[i][m]-1][j] == special[i][k] || - special[special[i][m]-1][j] == i+1) { + if (spec_temp[spec_temp[i][m]-1][j] == spec_temp[i][k] || + spec_temp[spec_temp[i][m]-1][j] == i+1) { dedup = 1; } } if (!dedup) { - if (count[i] >= maxspecial) + if (count[i] >= atom->maxspecial) error->one(FLERR,"Molecule auto special bond generation overflow"); - special[i][count[i]++] = special[special[i][m]-1][j]; + spec_temp[i][count[i]++] = spec_temp[spec_temp[i][m]-1][j]; nspecial[i][2]++; } } } } + + maxspecial = 0; + for (int i = 0; i < natoms; i++) + maxspecial = MAX(maxspecial,nspecial[i][2]); + + memory->create(special,natoms,maxspecial,"molecule:special"); + for (int i = 0; i < natoms; i++) + for (int j = 0; j < nspecial[i][2]; j++) + special[i][j] = spec_temp[i][j]; } /* ---------------------------------------------------------------------- @@ -1473,7 +1483,7 @@ void Molecule::allocate() if (radiusflag) memory->create(radius,natoms,"molecule:radius"); if (rmassflag) memory->create(rmass,natoms,"molecule:rmass"); - // always allocate num_bond,num_angle,etc and special+nspecial + // always allocate num_bond,num_angle,etc and nspecial // even if not in molecule file, initialize to 0 // this is so methods that use these arrays don't have to check they exist @@ -1485,12 +1495,12 @@ void Molecule::allocate() for (int i = 0; i < natoms; i++) num_dihedral[i] = 0; memory->create(num_improper,natoms,"molecule:num_improper"); for (int i = 0; i < natoms; i++) num_improper[i] = 0; - - memory->create(special,natoms,maxspecial,"molecule:special"); - memory->create(nspecial,natoms,3,"molecule:nspecial"); for (int i = 0; i < natoms; i++) nspecial[i][0] = nspecial[i][1] = nspecial[i][2] = 0; + + if (specialflag) + memory->create(special,natoms,maxspecial,"molecule:special"); if (bondflag) { memory->create(bond_type,natoms,bond_per_atom, From bf7cff73d42a2fc446942be5be736808bb484c98 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 18 Aug 2017 14:23:48 -0400 Subject: [PATCH 367/439] allocate the temporary special array on the heap and not the stack (it may get too big quickly) and clear the array before use. --- src/molecule.cpp | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/src/molecule.cpp b/src/molecule.cpp index 77ceea8781..3a93fdb1e2 100644 --- a/src/molecule.cpp +++ b/src/molecule.cpp @@ -1113,9 +1113,12 @@ void Molecule::special_generate() tagint atom1,atom2; int count[natoms]; - // temporary special array - tagint spec_temp[natoms][atom->maxspecial]; - + // temporary array for special atoms + + tagint **tmpspecial; + memory->create(tmpspecial,natoms,atom->maxspecial,"molecule:tmpspecial"); + memset(&tmpspecial[0][0],0,sizeof(tagint)*natoms*atom->maxspecial); + for (int i = 0; i < natoms; i++) count[i] = 0; // 1-2 neighbors @@ -1129,8 +1132,8 @@ void Molecule::special_generate() nspecial[atom2][0]++; if (count[i] >= atom->maxspecial || count[atom2] >= atom->maxspecial) error->one(FLERR,"Molecule auto special bond generation overflow"); - spec_temp[i][count[i]++] = atom2 + 1; - spec_temp[atom2][count[atom2]++] = i + 1; + tmpspecial[i][count[i]++] = atom2 + 1; + tmpspecial[atom2][count[atom2]++] = i + 1; } } } else { @@ -1141,7 +1144,7 @@ void Molecule::special_generate() atom2 = bond_atom[i][j]; if (count[atom1] >= atom->maxspecial) error->one(FLERR,"Molecule auto special bond generation overflow"); - spec_temp[i][count[atom1]++] = atom2; + tmpspecial[i][count[atom1]++] = atom2; } } } @@ -1153,18 +1156,18 @@ void Molecule::special_generate() int dedup; for (int i = 0; i < natoms; i++) { for (int m = 0; m < nspecial[i][0]; m++) { - for (int j = 0; j < nspecial[spec_temp[i][m]-1][0]; j++) { + for (int j = 0; j < nspecial[tmpspecial[i][m]-1][0]; j++) { dedup = 0; for (int k =0; k < count[i]; k++) { - if (spec_temp[spec_temp[i][m]-1][j] == spec_temp[i][k] || - spec_temp[spec_temp[i][m]-1][j] == i+1) { + if (tmpspecial[tmpspecial[i][m]-1][j] == tmpspecial[i][k] || + tmpspecial[tmpspecial[i][m]-1][j] == i+1) { dedup = 1; } } if (!dedup) { if (count[i] >= atom->maxspecial) error->one(FLERR,"Molecule auto special bond generation overflow"); - spec_temp[i][count[i]++] = spec_temp[spec_temp[i][m]-1][j]; + tmpspecial[i][count[i]++] = tmpspecial[tmpspecial[i][m]-1][j]; nspecial[i][1]++; } } @@ -1177,32 +1180,34 @@ void Molecule::special_generate() for (int i = 0; i < natoms; i++) { for (int m = nspecial[i][0]; m < nspecial[i][1]; m++) { - for (int j = 0; j < nspecial[spec_temp[i][m]-1][0]; j++) { + for (int j = 0; j < nspecial[tmpspecial[i][m]-1][0]; j++) { dedup = 0; for (int k =0; k < count[i]; k++) { - if (spec_temp[spec_temp[i][m]-1][j] == spec_temp[i][k] || - spec_temp[spec_temp[i][m]-1][j] == i+1) { + if (tmpspecial[tmpspecial[i][m]-1][j] == tmpspecial[i][k] || + tmpspecial[tmpspecial[i][m]-1][j] == i+1) { dedup = 1; } } if (!dedup) { if (count[i] >= atom->maxspecial) error->one(FLERR,"Molecule auto special bond generation overflow"); - spec_temp[i][count[i]++] = spec_temp[spec_temp[i][m]-1][j]; + tmpspecial[i][count[i]++] = tmpspecial[tmpspecial[i][m]-1][j]; nspecial[i][2]++; } } } } - + maxspecial = 0; for (int i = 0; i < natoms; i++) maxspecial = MAX(maxspecial,nspecial[i][2]); - + memory->create(special,natoms,maxspecial,"molecule:special"); for (int i = 0; i < natoms; i++) for (int j = 0; j < nspecial[i][2]; j++) - special[i][j] = spec_temp[i][j]; + special[i][j] = tmpspecial[i][j]; + + memory->destroy(tmpspecial); } /* ---------------------------------------------------------------------- From d671a04274f9b3d7d0e07c7dd8ee04c7af24db5d Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 18 Aug 2017 14:24:09 -0400 Subject: [PATCH 368/439] whitespace cleanup --- src/molecule.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/molecule.cpp b/src/molecule.cpp index 3a93fdb1e2..7dbefdd82f 100644 --- a/src/molecule.cpp +++ b/src/molecule.cpp @@ -173,7 +173,7 @@ Molecule::~Molecule() compute center = geometric center of molecule also compute: dx = displacement of each atom from center - molradius = radius of molecule from center + molradius = radius of molecule from center including finite-size particles or body particles ------------------------------------------------------------------------- */ @@ -474,7 +474,7 @@ void Molecule::read(int flag) } else if (strstr(line,"body")) { bodyflag = 1; avec_body = (AtomVecBody *) atom->style_match("body"); - if (!avec_body) + if (!avec_body) error->all(FLERR,"Molecule file requires atom style body"); nmatch = sscanf(line,"%d %d",&nibody,&ndbody); nwant = 2; @@ -486,7 +486,7 @@ void Molecule::read(int flag) // error checks - if (natoms < 1) + if (natoms < 1) error->all(FLERR,"No count or invalid atom count in molecule file"); if (nbonds < 0) error->all(FLERR,"Invalid bond count in molecule file"); if (nangles < 0) error->all(FLERR,"Invalid angle count in molecule file"); @@ -633,7 +633,7 @@ void Molecule::read(int flag) if (bodyflag) { radiusflag = 1; - if (natoms != 1) + if (natoms != 1) error->all(FLERR,"Molecule natoms must be 1 for body particle"); if (sizescale != 1.0) error->all(FLERR,"Molecule sizescale must be 1.0 for body particle"); @@ -1331,19 +1331,19 @@ void Molecule::body(int flag, int pflag, char *line) ncount = atom->count_words(line); if (ncount == 0) error->one(FLERR,"Too few values in body section of molecule file"); - if (nword+ncount > nparam) + if (nword+ncount > nparam) error->all(FLERR,"Too many values in body section of molecule file"); - + if (flag) { if (pflag == 0) { ibodyparams[nword++] = force->inumeric(FLERR,strtok(line," \t\n\r\f")); for (i = 1; i < ncount; i++) - ibodyparams[nword++] = + ibodyparams[nword++] = force->inumeric(FLERR,strtok(NULL," \t\n\r\f")); } else { dbodyparams[nword++] = force->numeric(FLERR,strtok(line," \t\n\r\f")); for (i = 1; i < ncount; i++) - dbodyparams[nword++] = + dbodyparams[nword++] = force->numeric(FLERR,strtok(NULL," \t\n\r\f")); } } else nword += ncount; @@ -1503,8 +1503,8 @@ void Molecule::allocate() memory->create(nspecial,natoms,3,"molecule:nspecial"); for (int i = 0; i < natoms; i++) nspecial[i][0] = nspecial[i][1] = nspecial[i][2] = 0; - - if (specialflag) + + if (specialflag) memory->create(special,natoms,maxspecial,"molecule:special"); if (bondflag) { From 6aa756968d40f71b65af0e849bdd647b6d08da26 Mon Sep 17 00:00:00 2001 From: Amulya Date: Fri, 18 Aug 2017 15:21:49 -0400 Subject: [PATCH 369/439] Temper_NPT and example New function that allows for parallel tempering (replica exchange) in MD in LAMMPS in the isothermal-isobaric ensemble (NPT) Similar to temper which works in the canonical (NVT) ensemble. An example is included that uses temper_npt --- src/REPLICA/data.peptide | 6531 ++++++++++++++++++++++++++++++++++++ src/REPLICA/in.temper_npt | 32 + src/REPLICA/temper_npt.cpp | 381 +++ src/REPLICA/temper_npt.h | 118 + 4 files changed, 7062 insertions(+) create mode 100644 src/REPLICA/data.peptide create mode 100644 src/REPLICA/in.temper_npt create mode 100644 src/REPLICA/temper_npt.cpp create mode 100644 src/REPLICA/temper_npt.h diff --git a/src/REPLICA/data.peptide b/src/REPLICA/data.peptide new file mode 100644 index 0000000000..f9dfb6e485 --- /dev/null +++ b/src/REPLICA/data.peptide @@ -0,0 +1,6531 @@ +LAMMPS Description + + 2004 atoms + 1365 bonds + 786 angles + 207 dihedrals + 12 impropers + + 14 atom types + 18 bond types + 31 angle types + 21 dihedral types + 2 improper types + + 36.840194 64.211560 xlo xhi + 41.013691 68.385058 ylo yhi + 29.768095 57.139462 zlo zhi + +Masses + + 1 12.0110 + 2 12.0110 + 3 15.9990 + 4 1.0080 + 5 14.0070 + 6 12.0110 + 7 12.0110 + 8 12.0110 + 9 15.9990 + 10 1.0080 + 11 1.0080 + 12 32.0660 + 13 16.0000 + 14 1.0100 + +Pair Coeffs + + 1 0.110000 3.563595 0.110000 3.563595 + 2 0.080000 3.670503 0.010000 3.385415 + 3 0.120000 3.029056 0.120000 2.494516 + 4 0.022000 2.351973 0.022000 2.351973 + 5 0.200000 3.296325 0.200000 2.761786 + 6 0.020000 4.053589 0.010000 3.385415 + 7 0.055000 3.875410 0.010000 3.385415 + 8 0.070000 3.550053 0.070000 3.550053 + 9 0.152100 3.153782 0.152100 3.153782 + 10 0.046000 0.400014 0.046000 0.400014 + 11 0.030000 2.420037 0.030000 2.420037 + 12 0.450000 3.563595 0.450000 3.563595 + 13 0.152100 3.150570 0.152100 3.150570 + 14 0.046000 0.400014 0.046000 0.400014 + +Bond Coeffs + + 1 249.999999 1.490000 + 2 620.000001 1.230000 + 3 370.000000 1.345000 + 4 322.000001 1.111000 + 5 319.999999 1.430000 + 6 440.000000 0.997000 + 7 222.500001 1.538000 + 8 330.000001 1.080000 + 9 230.000000 1.490000 + 10 309.000001 1.111000 + 11 305.000000 1.375000 + 12 340.000001 1.080000 + 13 334.300000 1.411000 + 14 545.000001 0.960000 + 15 222.500001 1.530000 + 16 198.000000 1.818000 + 17 239.999999 1.816000 + 18 450.000000 0.957200 + +Angle Coeffs + + 1 33.000000 109.500000 30.000000 2.163000 + 2 50.000000 120.000000 0.000000 0.000000 + 3 34.000000 123.000000 0.000000 0.000000 + 4 80.000000 121.000000 0.000000 0.000000 + 5 80.000000 116.500000 0.000000 0.000000 + 6 80.000000 122.500000 0.000000 0.000000 + 7 35.500000 108.400000 5.400000 1.802000 + 8 50.000000 107.000000 0.000000 0.000000 + 9 70.000000 113.500000 0.000000 0.000000 + 10 48.000000 108.000000 0.000000 0.000000 + 11 35.000000 117.000000 0.000000 0.000000 + 12 51.800000 107.500000 0.000000 0.000000 + 13 33.430000 110.100000 22.530000 2.179000 + 14 52.000000 108.000000 0.000000 0.000000 + 15 50.000000 109.500000 0.000000 0.000000 + 16 35.000000 111.000000 0.000000 0.000000 + 17 45.800000 122.300000 0.000000 0.000000 + 18 49.300000 107.500000 0.000000 0.000000 + 19 40.000000 120.000000 35.000000 2.416200 + 20 30.000000 120.000000 22.000000 2.152500 + 21 45.200000 120.000000 0.000000 0.000000 + 22 65.000000 108.000000 0.000000 0.000000 + 23 35.500000 109.000000 5.400000 1.802000 + 24 36.000000 115.000000 0.000000 0.000000 + 25 58.350000 113.500000 11.160000 2.561000 + 26 58.000000 114.500000 0.000000 0.000000 + 27 26.500000 110.100000 22.530000 2.179000 + 28 34.000000 95.000000 0.000000 0.000000 + 29 46.100000 111.300000 0.000000 0.000000 + 30 51.500000 109.500000 0.000000 0.000000 + 31 55.000000 104.520000 0.000000 0.000000 + +Dihedral Coeffs + + 1 0.200000 1 180 1.000000 + 2 1.800000 1 0 1.000000 + 3 0.000000 1 0 1.000000 + 4 1.600000 1 0 0.500000 + 5 2.500000 2 180 0.500000 + 6 2.500000 2 180 1.000000 + 7 0.600000 1 0 1.000000 + 8 0.200000 3 0 1.000000 + 9 0.230000 2 180 1.000000 + 10 0.040000 3 0 1.000000 + 11 1.400000 1 0 1.000000 + 12 3.100000 2 180 1.000000 + 13 4.200000 2 180 1.000000 + 14 3.100000 2 180 0.500000 + 15 0.990000 2 180 1.000000 + 16 2.400000 2 180 1.000000 + 17 0.195000 3 0 1.000000 + 18 0.240000 1 180 0.500000 + 19 0.370000 3 0 0.500000 + 20 0.280000 3 0 1.000000 + 21 0.010000 3 0 1.000000 + +Improper Coeffs + + 1 120.000000 0.000000 + 2 20.000000 0.000000 + +Atoms + + 1 1 1 0.510 43.99993 58.52678 36.78550 0 0 0 + 2 1 2 -0.270 45.10395 58.23499 35.86693 0 0 0 + 3 1 3 -0.510 43.81519 59.54928 37.43995 0 0 0 + 4 1 4 0.090 45.71714 57.34797 36.13434 0 0 0 + 5 1 4 0.090 45.72261 59.13657 35.67007 0 0 0 + 6 1 4 0.090 44.66624 58.09539 34.85538 0 0 0 + 7 1 5 -0.470 43.28193 57.47427 36.91953 0 0 0 + 8 1 6 0.070 42.07157 57.45486 37.62418 0 0 0 + 9 1 1 0.510 42.19985 57.57789 39.12163 0 0 0 + 10 1 3 -0.510 41.88641 58.62251 39.70398 0 0 0 + 11 1 7 -0.180 41.25052 56.15304 37.41811 0 0 0 + 12 1 8 0.000 40.88511 55.94638 35.97460 0 0 0 + 13 1 8 -0.115 41.48305 54.96372 35.11223 0 0 0 + 14 1 8 -0.115 39.74003 56.60996 35.46443 0 0 0 + 15 1 8 -0.115 41.02111 54.75715 33.80764 0 0 0 + 16 1 8 -0.115 39.26180 56.39194 34.12024 0 0 0 + 17 1 8 0.110 39.92330 55.46092 33.27135 0 0 0 + 18 1 9 -0.540 39.48164 55.22919 31.91865 0 0 0 + 19 1 10 0.310 43.60633 56.61693 36.52744 0 0 0 + 20 1 4 0.090 41.49619 58.31145 37.30543 0 0 0 + 21 1 4 0.090 41.88498 55.29476 37.72657 0 0 0 + 22 1 4 0.090 40.30899 56.19690 38.00627 0 0 0 + 23 1 11 0.115 42.31528 54.36176 35.44606 0 0 0 + 24 1 11 0.115 39.26330 57.31216 36.13230 0 0 0 + 25 1 11 0.115 41.62695 54.10606 33.19490 0 0 0 + 26 1 11 0.115 38.42147 56.98236 33.78612 0 0 0 + 27 1 10 0.430 38.78233 55.86217 31.74004 0 0 0 + 28 1 5 -0.470 42.79933 56.56370 39.79000 0 0 0 + 29 1 7 -0.020 42.96709 56.75379 41.28116 0 0 0 + 30 1 1 0.510 43.83019 55.68988 41.92255 0 0 0 + 31 1 3 -0.510 44.98521 55.93104 42.21713 0 0 0 + 32 1 10 0.310 43.13466 55.75696 39.30966 0 0 0 + 33 1 4 0.090 42.04692 56.86721 41.83507 0 0 0 + 34 1 4 0.090 43.52938 57.66324 41.43329 0 0 0 + 35 1 5 -0.470 43.26792 54.43342 42.07043 0 0 0 + 36 1 7 -0.020 43.92411 53.28930 42.63327 0 0 0 + 37 1 1 0.510 43.51012 53.02289 44.10510 0 0 0 + 38 1 3 -0.510 42.35086 53.07863 44.50806 0 0 0 + 39 1 10 0.310 42.28859 54.34993 41.90323 0 0 0 + 40 1 4 0.090 44.98464 53.47473 42.54797 0 0 0 + 41 1 4 0.090 43.49715 52.54787 41.97419 0 0 0 + 42 1 5 -0.470 44.51925 52.64535 44.88133 0 0 0 + 43 1 6 0.070 44.47588 52.35054 46.24397 0 0 0 + 44 1 1 0.510 45.40218 53.34579 46.94730 0 0 0 + 45 1 3 -0.510 45.23520 54.55893 46.92038 0 0 0 + 46 1 7 -0.180 44.77960 50.82831 46.50232 0 0 0 + 47 1 8 0.000 43.72184 49.84551 45.98093 0 0 0 + 48 1 8 -0.115 44.14810 49.00477 44.97195 0 0 0 + 49 1 8 -0.115 42.43499 49.66652 46.53541 0 0 0 + 50 1 8 -0.115 43.26154 48.00434 44.46769 0 0 0 + 51 1 8 -0.115 41.54732 48.79670 45.95416 0 0 0 + 52 1 8 -0.115 41.98220 47.90746 44.95574 0 0 0 + 53 1 10 0.310 45.39510 52.50937 44.42482 0 0 0 + 54 1 4 0.090 43.51312 52.58974 46.67092 0 0 0 + 55 1 4 0.090 44.89709 50.54313 47.56965 0 0 0 + 56 1 4 0.090 45.72096 50.49337 46.01654 0 0 0 + 57 1 11 0.115 45.13573 49.07933 44.54134 0 0 0 + 58 1 11 0.115 42.07869 50.34816 47.29358 0 0 0 + 59 1 11 0.115 43.47793 47.29281 43.68456 0 0 0 + 60 1 11 0.115 40.52625 48.76134 46.30425 0 0 0 + 61 1 11 0.115 41.35446 47.13287 44.54059 0 0 0 + 62 1 5 -0.470 46.41448 52.86278 47.68291 0 0 0 + 63 1 6 0.070 47.25136 53.68184 48.51163 0 0 0 + 64 1 1 0.510 48.33905 54.40097 47.73886 0 0 0 + 65 1 3 -0.510 49.27132 53.85220 47.16549 0 0 0 + 66 1 7 -0.180 47.88329 52.75681 49.60227 0 0 0 + 67 1 7 -0.140 48.82515 53.51102 50.61578 0 0 0 + 68 1 12 -0.090 48.12492 55.00373 51.43039 0 0 0 + 69 1 2 -0.220 47.70783 54.12980 53.04072 0 0 0 + 70 1 10 0.310 46.67199 51.90088 47.73231 0 0 0 + 71 1 4 0.090 46.64593 54.43552 48.99310 0 0 0 + 72 1 4 0.090 48.41361 51.90817 49.11968 0 0 0 + 73 1 4 0.090 47.08748 52.35196 50.26341 0 0 0 + 74 1 4 0.090 49.16067 52.81305 51.41238 0 0 0 + 75 1 4 0.090 49.73705 53.67062 50.00155 0 0 0 + 76 1 4 0.090 47.18593 54.84215 53.71488 0 0 0 + 77 1 4 0.090 48.69939 53.91624 53.49408 0 0 0 + 78 1 4 0.090 47.19749 53.18294 52.76264 0 0 0 + 79 1 5 -0.470 48.34472 55.71775 47.80498 0 0 0 + 80 1 2 -0.110 49.37792 56.51754 47.29492 0 0 0 + 81 1 10 0.310 47.51777 56.11617 48.19410 0 0 0 + 82 1 4 0.090 50.41495 56.13038 47.38980 0 0 0 + 83 1 4 0.090 49.23515 57.51193 47.76940 0 0 0 + 84 1 4 0.090 49.28612 56.52094 46.18773 0 0 0 + 85 2 13 -0.834 52.28049 45.72878 41.48140 -1 0 1 + 86 2 14 0.417 51.97210 46.07066 40.64218 -1 0 1 + 87 2 14 0.417 52.43689 44.79855 41.31868 -1 0 1 + 88 3 13 -0.834 43.84472 45.66062 47.17660 -2 -1 -1 + 89 3 14 0.417 43.42120 44.88337 46.81226 -2 -1 -1 + 90 3 14 0.417 44.31099 46.04907 46.43636 -2 -1 -1 + 91 4 13 -0.834 51.27805 50.25403 54.67397 0 0 -1 + 92 4 14 0.417 50.81295 50.23728 53.83753 0 0 -1 + 93 4 14 0.417 52.00273 49.63953 54.55795 0 0 -1 + 94 5 13 -0.834 44.71976 53.72011 56.43834 -1 0 -1 + 95 5 14 0.417 44.56050 53.84218 55.50241 -1 0 -1 + 96 5 14 0.417 44.91937 52.78829 56.52828 -1 0 -1 + 97 6 13 -0.834 37.07074 62.07204 53.35752 -1 -1 -1 + 98 6 14 0.417 64.17057 61.77089 52.49043 -2 -1 -1 + 99 6 14 0.417 37.90147 62.52273 53.20573 -1 -1 -1 + 100 7 13 -0.834 38.31817 66.10834 49.17406 0 -1 0 + 101 7 14 0.417 37.39300 65.93985 48.99534 0 -1 0 + 102 7 14 0.417 38.36506 66.20528 50.12520 0 -1 0 + 103 8 13 -0.834 60.90915 45.97690 35.53863 -1 -1 1 + 104 8 14 0.417 61.19898 46.87819 35.39745 -1 -1 1 + 105 8 14 0.417 59.98680 45.97855 35.28269 -1 -1 1 + 106 9 13 -0.834 54.33913 64.47210 51.00391 -1 -2 0 + 107 9 14 0.417 54.43191 63.71377 50.42724 -1 -2 0 + 108 9 14 0.417 55.16289 64.94980 50.90662 -1 -2 0 + 109 10 13 -0.834 44.58017 54.03749 53.84708 1 0 -1 + 110 10 14 0.417 43.87040 54.43768 53.34476 1 0 -1 + 111 10 14 0.417 45.02999 53.47261 53.21873 1 0 -1 + 112 11 13 -0.834 45.48693 52.12363 34.38241 0 -1 1 + 113 11 14 0.417 45.46898 52.67450 33.59981 0 -1 1 + 114 11 14 0.417 44.61476 52.22113 34.76457 0 -1 1 + 115 12 13 -0.834 60.15770 61.68799 54.74753 1 0 -2 + 116 12 14 0.417 59.23977 61.46439 54.59378 1 0 -2 + 117 12 14 0.417 60.43785 61.08922 55.43980 1 0 -2 + 118 13 13 -0.834 60.74732 66.72156 42.80906 1 -2 0 + 119 13 14 0.417 60.34713 66.21969 42.09898 1 -2 0 + 120 13 14 0.417 60.92444 66.07344 43.49082 1 -2 0 + 121 14 13 -0.834 60.82245 64.17281 50.54212 0 0 0 + 122 14 14 0.417 61.43571 64.88448 50.35863 0 0 0 + 123 14 14 0.417 60.87804 64.04633 51.48930 0 0 0 + 124 15 13 -0.834 36.92704 63.01353 56.05215 0 -1 0 + 125 15 14 0.417 37.10744 62.17054 56.46815 0 -1 0 + 126 15 14 0.417 64.06237 62.79109 55.15157 -1 -1 0 + 127 16 13 -0.834 48.35559 58.70568 56.14001 1 0 0 + 128 16 14 0.417 48.11655 59.48087 55.63191 1 0 0 + 129 16 14 0.417 47.93212 58.83502 56.98865 1 0 0 + 130 17 13 -0.834 58.14651 57.18542 51.08241 0 -1 -1 + 131 17 14 0.417 57.88523 56.72609 51.88052 0 -1 -1 + 132 17 14 0.417 57.35121 57.63116 50.79076 0 -1 -1 + 133 18 13 -0.834 58.09837 59.68005 36.16995 -1 0 0 + 134 18 14 0.417 58.25901 58.76822 36.41283 -1 0 0 + 135 18 14 0.417 58.56239 60.19049 36.83355 -1 0 0 + 136 19 13 -0.834 52.29019 60.51169 50.55611 0 -2 1 + 137 19 14 0.417 52.61972 60.01708 51.30645 0 -2 1 + 138 19 14 0.417 52.55621 59.99722 49.79401 0 -2 1 + 139 20 13 -0.834 41.36642 50.33705 42.98530 0 -1 -1 + 140 20 14 0.417 41.27846 50.09969 43.90844 0 -1 -1 + 141 20 14 0.417 40.99321 51.21659 42.92708 0 -1 -1 + 142 21 13 -0.834 53.76920 67.02645 32.18667 -1 0 1 + 143 21 14 0.417 53.59447 67.18509 31.25901 -1 0 1 + 144 21 14 0.417 54.65308 67.36647 32.32596 -1 0 1 + 145 22 13 -0.834 57.83691 45.33663 46.94671 0 0 -2 + 146 22 14 0.417 57.36287 45.59552 46.15647 0 0 -2 + 147 22 14 0.417 58.62995 44.91017 46.62197 0 0 -2 + 148 23 13 -0.834 60.34518 45.83000 45.57964 -1 0 0 + 149 23 14 0.417 60.61871 44.93757 45.79176 -1 0 0 + 150 23 14 0.417 61.09971 46.21212 45.13141 -1 0 0 + 151 24 13 -0.834 55.97902 46.85046 56.80163 0 1 1 + 152 24 14 0.417 56.57528 46.69952 30.16370 0 1 2 + 153 24 14 0.417 55.81156 47.79276 56.81850 0 1 1 + 154 25 13 -0.834 57.54668 45.52135 31.46139 -1 0 1 + 155 25 14 0.417 58.36291 46.00311 31.32743 -1 0 1 + 156 25 14 0.417 57.54151 45.31312 32.39566 -1 0 1 + 157 26 13 -0.834 58.03029 52.86783 46.33564 -1 -1 0 + 158 26 14 0.417 58.13662 52.56730 47.23820 -1 -1 0 + 159 26 14 0.417 58.81317 52.55269 45.88396 -1 -1 0 + 160 27 13 -0.834 62.89253 60.86549 46.75131 -2 -1 0 + 161 27 14 0.417 63.83924 60.74010 46.81653 -2 -1 0 + 162 27 14 0.417 62.51896 60.12788 47.23361 -2 -1 0 + 163 28 13 -0.834 43.29171 48.58106 31.82206 -1 0 2 + 164 28 14 0.417 43.07532 49.46362 32.12290 -1 0 2 + 165 28 14 0.417 43.82286 48.21072 32.52701 -1 0 2 + 166 29 13 -0.834 64.19867 44.17673 45.81391 -1 1 -1 + 167 29 14 0.417 63.72986 44.44010 45.02202 -1 1 -1 + 168 29 14 0.417 37.02069 43.24876 45.68087 0 1 -1 + 169 30 13 -0.834 50.42749 42.01163 53.60484 0 2 0 + 170 30 14 0.417 51.03177 41.90084 52.87081 0 2 0 + 171 30 14 0.417 50.77279 42.76181 54.08882 0 2 0 + 172 31 13 -0.834 38.63739 61.71113 49.95150 1 0 0 + 173 31 14 0.417 38.55432 62.15607 49.10808 1 0 0 + 174 31 14 0.417 37.81718 61.22751 50.04950 1 0 0 + 175 32 13 -0.834 61.47262 53.02922 33.08309 -1 -1 0 + 176 32 14 0.417 61.21894 52.67931 33.93717 -1 -1 0 + 177 32 14 0.417 61.89351 53.86564 33.28182 -1 -1 0 + 178 33 13 -0.834 54.44545 60.06011 48.63522 -1 0 1 + 179 33 14 0.417 54.80032 60.94424 48.72810 -1 0 1 + 180 33 14 0.417 54.09041 60.03614 47.74662 -1 0 1 + 181 34 13 -0.834 56.34364 60.90201 52.60838 -1 -1 0 + 182 34 14 0.417 56.48857 60.19161 53.23333 -1 -1 0 + 183 34 14 0.417 56.17362 61.67024 53.15351 -1 -1 0 + 184 35 13 -0.834 56.05881 51.84328 55.76103 -1 0 0 + 185 35 14 0.417 55.59060 51.75146 54.93121 -1 0 0 + 186 35 14 0.417 55.46974 52.35732 56.31335 -1 0 0 + 187 36 13 -0.834 39.00621 42.74743 30.97845 0 0 1 + 188 36 14 0.417 39.67620 42.11390 30.72152 0 0 1 + 189 36 14 0.417 39.43456 43.29673 31.63499 0 0 1 + 190 37 13 -0.834 46.77585 55.39774 30.24026 0 1 0 + 191 37 14 0.417 46.10274 54.90237 29.77360 0 1 0 + 192 37 14 0.417 46.39626 56.26890 30.35527 0 1 0 + 193 38 13 -0.834 45.10722 57.60431 31.54688 -1 0 0 + 194 38 14 0.417 44.80783 58.50032 31.70105 -1 0 0 + 195 38 14 0.417 44.44237 57.22463 30.97238 -1 0 0 + 196 39 13 -0.834 43.94230 46.99244 34.45668 -2 1 1 + 197 39 14 0.417 44.62010 46.49140 34.00306 -2 1 1 + 198 39 14 0.417 44.38150 47.79794 34.72964 -2 1 1 + 199 40 13 -0.834 51.39443 50.96507 34.69072 -1 1 0 + 200 40 14 0.417 51.18729 50.42829 35.45570 -1 1 0 + 201 40 14 0.417 51.33198 51.86665 35.00616 -1 1 0 + 202 41 13 -0.834 58.96398 48.19727 42.98856 -2 1 0 + 203 41 14 0.417 58.42587 48.90112 42.62618 -2 1 0 + 204 41 14 0.417 58.82383 48.25054 43.93397 -2 1 0 + 205 42 13 -0.834 62.89335 41.94260 37.40820 0 0 0 + 206 42 14 0.417 62.48690 41.07818 37.46980 0 0 0 + 207 42 14 0.417 63.01802 42.08284 36.46957 0 0 0 + 208 43 13 -0.834 54.19388 47.88689 36.24110 -1 0 1 + 209 43 14 0.417 54.32054 48.63090 35.65235 -1 0 1 + 210 43 14 0.417 53.24370 47.78935 36.30358 -1 0 1 + 211 44 13 -0.834 39.19734 57.40342 41.28495 0 0 -2 + 212 44 14 0.417 39.05428 57.72940 40.39641 0 0 -2 + 213 44 14 0.417 39.30846 56.45861 41.17895 0 0 -2 + 214 45 13 -0.834 52.85483 61.73749 54.63897 0 0 0 + 215 45 14 0.417 53.34938 62.52765 54.42147 0 0 0 + 216 45 14 0.417 53.01046 61.14656 53.90221 0 0 0 + 217 46 13 -0.834 47.09467 62.01384 35.02302 1 0 1 + 218 46 14 0.417 47.54527 61.47644 35.67448 1 0 1 + 219 46 14 0.417 47.10116 62.89626 35.39385 1 0 1 + 220 47 13 -0.834 46.80497 49.60334 37.05700 0 0 1 + 221 47 14 0.417 46.70216 49.79770 36.12540 0 0 1 + 222 47 14 0.417 45.91311 49.45393 37.37084 0 0 1 + 223 48 13 -0.834 63.21969 59.12311 54.43455 -1 -1 -1 + 224 48 14 0.417 63.94585 59.72833 54.28405 -1 -1 -1 + 225 48 14 0.417 63.63016 58.34481 54.81141 -1 -1 -1 + 226 49 13 -0.834 59.88416 59.64215 44.04914 -2 1 0 + 227 49 14 0.417 59.74255 59.14412 44.85422 -2 1 0 + 228 49 14 0.417 59.02635 60.01323 43.84248 -2 1 0 + 229 50 13 -0.834 40.50825 42.85328 50.81112 -1 1 0 + 230 50 14 0.417 40.34650 43.39801 51.58141 -1 1 0 + 231 50 14 0.417 39.63964 42.69867 50.43985 -1 1 0 + 232 51 13 -0.834 63.77522 64.97067 44.83010 -2 0 0 + 233 51 14 0.417 37.00507 65.56132 45.28388 -1 0 0 + 234 51 14 0.417 64.14243 64.88383 43.95041 -2 0 0 + 235 52 13 -0.834 62.47161 67.86189 47.38235 -1 0 -1 + 236 52 14 0.417 61.58819 67.64608 47.08360 -1 0 -1 + 237 52 14 0.417 62.79136 67.05596 47.78790 -1 0 -1 + 238 53 13 -0.834 43.90800 54.16107 50.35199 0 0 0 + 239 53 14 0.417 43.96769 53.24711 50.07388 0 0 0 + 240 53 14 0.417 43.72593 54.64554 49.54677 0 0 0 + 241 54 13 -0.834 63.46829 44.63390 34.73615 -1 1 1 + 242 54 14 0.417 62.63731 45.04623 34.97217 -1 1 1 + 243 54 14 0.417 64.11050 45.03645 35.32075 -1 1 1 + 244 55 13 -0.834 37.30679 58.22047 51.04345 0 0 0 + 245 55 14 0.417 38.18596 58.37862 50.69950 0 0 0 + 246 55 14 0.417 36.85723 59.06017 50.94824 0 0 0 + 247 56 13 -0.834 58.72649 42.45768 31.23820 -1 1 -1 + 248 56 14 0.417 59.43634 42.77561 30.68028 -1 1 -1 + 249 56 14 0.417 58.76581 41.50474 31.15690 -1 1 -1 + 250 57 13 -0.834 52.47101 42.85691 41.60986 0 1 -1 + 251 57 14 0.417 51.62289 42.91562 41.16997 0 1 -1 + 252 57 14 0.417 52.53109 41.94497 41.89448 0 1 -1 + 253 58 13 -0.834 60.63476 59.78356 56.53663 -2 -1 -1 + 254 58 14 0.417 60.87428 58.86269 56.43247 -2 -1 -1 + 255 58 14 0.417 59.72615 59.76269 56.83705 -2 -1 -1 + 256 59 13 -0.834 52.78127 57.47386 30.66786 -1 -1 0 + 257 59 14 0.417 52.55495 58.26092 30.17228 -1 -1 0 + 258 59 14 0.417 53.05203 56.84104 30.00267 -1 -1 0 + 259 60 13 -0.834 46.04848 57.65321 54.89998 0 3 -1 + 260 60 14 0.417 46.96883 57.71336 55.15607 0 3 -1 + 261 60 14 0.417 46.02768 57.98076 54.00081 0 3 -1 + 262 61 13 -0.834 60.39356 51.43705 35.66109 -1 1 -1 + 263 61 14 0.417 60.57739 52.08235 36.34376 -1 1 -1 + 264 61 14 0.417 59.59475 50.99860 35.95414 -1 1 -1 + 265 62 13 -0.834 50.32338 62.46972 35.65752 -1 0 2 + 266 62 14 0.417 51.24156 62.23287 35.52678 -1 0 2 + 267 62 14 0.417 49.89601 61.64851 35.90085 -1 0 2 + 268 63 13 -0.834 38.23983 45.11908 50.02773 0 1 0 + 269 63 14 0.417 38.61336 45.27494 50.89515 0 1 0 + 270 63 14 0.417 38.91224 45.42406 49.41856 0 1 0 + 271 64 13 -0.834 58.93720 57.36605 46.08362 -3 0 0 + 272 64 14 0.417 58.65753 56.63297 46.63190 -3 0 0 + 273 64 14 0.417 58.29914 58.05674 46.26268 -3 0 0 + 274 65 13 -0.834 47.99806 43.44789 47.43046 -1 0 0 + 275 65 14 0.417 48.39580 43.78289 46.62684 -1 0 0 + 276 65 14 0.417 47.85848 44.22523 47.97128 -1 0 0 + 277 66 13 -0.834 51.26744 52.05593 47.09995 -1 0 0 + 278 66 14 0.417 51.36736 52.09873 46.14894 -1 0 0 + 279 66 14 0.417 50.33779 52.22629 47.25149 -1 0 0 + 280 67 13 -0.834 39.06132 52.11517 46.39010 0 0 -1 + 281 67 14 0.417 38.53402 51.36282 46.65876 0 0 -1 + 282 67 14 0.417 39.47133 52.42190 47.19884 0 0 -1 + 283 68 13 -0.834 60.17907 58.95174 50.22759 -1 1 0 + 284 68 14 0.417 60.34080 59.56538 50.94420 -1 1 0 + 285 68 14 0.417 59.41497 58.44908 50.50992 -1 1 0 + 286 69 13 -0.834 40.47698 59.65154 34.92537 0 -1 1 + 287 69 14 0.417 40.89044 60.49055 35.12877 0 -1 1 + 288 69 14 0.417 41.17964 59.12336 34.54648 0 -1 1 + 289 70 13 -0.834 60.12998 66.51474 47.03971 -1 0 -1 + 290 70 14 0.417 59.26620 66.39701 47.43506 -1 0 -1 + 291 70 14 0.417 60.21358 65.78625 46.42443 -1 0 -1 + 292 71 13 -0.834 49.25986 47.27506 43.03372 -1 0 1 + 293 71 14 0.417 49.11810 48.15331 42.68041 -1 0 1 + 294 71 14 0.417 49.86162 47.40550 43.76662 -1 0 1 + 295 72 13 -0.834 41.48105 63.65699 31.84433 0 0 1 + 296 72 14 0.417 41.11022 64.48589 32.14713 0 0 1 + 297 72 14 0.417 40.89461 63.37379 31.14281 0 0 1 + 298 73 13 -0.834 47.82875 47.97039 54.56720 0 2 0 + 299 73 14 0.417 46.99167 47.50633 54.55352 0 2 0 + 300 73 14 0.417 47.60488 48.87558 54.35102 0 2 0 + 301 74 13 -0.834 62.36735 58.64445 48.35778 -2 1 0 + 302 74 14 0.417 62.88767 57.90867 48.68045 -2 1 0 + 303 74 14 0.417 61.65918 58.73544 48.99531 -2 1 0 + 304 75 13 -0.834 52.09508 65.08907 32.87560 0 0 0 + 305 75 14 0.417 52.67402 65.75058 32.49683 0 0 0 + 306 75 14 0.417 52.41855 64.97003 33.76859 0 0 0 + 307 76 13 -0.834 39.06932 41.62988 40.69498 1 1 0 + 308 76 14 0.417 39.51114 41.04433 40.08003 1 1 0 + 309 76 14 0.417 38.93584 42.43936 40.20186 1 1 0 + 310 77 13 -0.834 37.68325 49.50718 46.00750 0 2 0 + 311 77 14 0.417 64.11601 49.67107 45.91568 -1 2 0 + 312 77 14 0.417 37.90845 48.96991 45.24796 0 2 0 + 313 78 13 -0.834 53.00757 59.49351 52.98404 -2 1 -1 + 314 78 14 0.417 52.16721 59.28329 53.39127 -2 1 -1 + 315 78 14 0.417 53.61000 58.83023 53.32076 -2 1 -1 + 316 79 13 -0.834 51.89369 64.75001 56.68467 1 0 0 + 317 79 14 0.417 51.88079 65.63682 56.32462 1 0 0 + 318 79 14 0.417 52.40589 64.82531 30.11841 1 0 1 + 319 80 13 -0.834 48.43261 63.10155 32.63566 0 0 1 + 320 80 14 0.417 47.68021 63.01753 32.04993 0 0 1 + 321 80 14 0.417 48.13916 62.71424 33.46035 0 0 1 + 322 81 13 -0.834 62.41171 68.18251 30.67168 0 -1 2 + 323 81 14 0.417 61.79235 41.16145 30.03143 0 0 2 + 324 81 14 0.417 63.18314 67.94790 30.15584 0 -1 2 + 325 82 13 -0.834 42.57575 41.32197 37.66791 0 0 1 + 326 82 14 0.417 42.98116 41.36016 36.80164 0 0 1 + 327 82 14 0.417 42.32522 42.22654 37.85569 0 0 1 + 328 83 13 -0.834 50.17315 67.44398 36.91606 0 -2 0 + 329 83 14 0.417 50.08765 67.03449 37.77701 0 -2 0 + 330 83 14 0.417 50.35347 66.71621 36.32101 0 -2 0 + 331 84 13 -0.834 39.70163 60.45247 40.03790 0 -2 -1 + 332 84 14 0.417 38.85282 60.01540 40.10676 0 -2 -1 + 333 84 14 0.417 40.20579 60.11563 40.77858 0 -2 -1 + 334 85 13 -0.834 51.74323 42.80814 51.33239 0 0 -1 + 335 85 14 0.417 52.44810 43.22892 51.82466 0 0 -1 + 336 85 14 0.417 51.80961 43.17998 50.45286 0 0 -1 + 337 86 13 -0.834 51.34695 47.68316 36.38089 0 0 1 + 338 86 14 0.417 50.77701 46.92707 36.52138 0 0 1 + 339 86 14 0.417 51.27109 47.87031 35.44523 0 0 1 + 340 87 13 -0.834 62.66950 50.66085 43.15883 -2 0 0 + 341 87 14 0.417 63.57796 50.36318 43.11051 -2 0 0 + 342 87 14 0.417 62.24654 50.26548 42.39659 -2 0 0 + 343 88 13 -0.834 46.37996 60.13914 31.06428 -2 -1 1 + 344 88 14 0.417 46.89125 59.89673 31.83632 -2 -1 1 + 345 88 14 0.417 45.51811 60.37092 31.41028 -2 -1 1 + 346 89 13 -0.834 50.23251 41.17559 46.18435 0 1 2 + 347 89 14 0.417 49.40509 68.16142 45.89628 0 0 2 + 348 89 14 0.417 50.55747 67.94506 46.85395 0 0 2 + 349 90 13 -0.834 56.10446 66.70018 42.60390 0 -2 1 + 350 90 14 0.417 56.27454 67.42915 42.00732 0 -2 1 + 351 90 14 0.417 56.27819 67.05729 43.47483 0 -2 1 + 352 91 13 -0.834 55.53824 48.43866 51.97225 -1 0 1 + 353 91 14 0.417 56.26440 48.96682 52.30388 -1 0 1 + 354 91 14 0.417 55.26306 48.88494 51.17140 -1 0 1 + 355 92 13 -0.834 37.88016 52.62502 33.55552 0 -1 0 + 356 92 14 0.417 37.58757 51.72397 33.41859 0 -1 0 + 357 92 14 0.417 38.51960 52.77804 32.85986 0 -1 0 + 358 93 13 -0.834 50.40592 66.14455 39.40035 -1 -2 -1 + 359 93 14 0.417 49.74974 66.37168 40.05920 -1 -2 -1 + 360 93 14 0.417 50.22642 65.22843 39.18876 -1 -2 -1 + 361 94 13 -0.834 59.56315 43.63477 50.02876 -1 0 0 + 362 94 14 0.417 60.08533 44.36640 50.35782 -1 0 0 + 363 94 14 0.417 60.10101 42.86112 50.19730 -1 0 0 + 364 95 13 -0.834 57.16125 61.75981 55.17964 0 0 -1 + 365 95 14 0.417 56.45534 61.68609 55.82189 0 0 -1 + 366 95 14 0.417 57.38335 62.69087 55.17297 0 0 -1 + 367 96 13 -0.834 54.81274 43.48714 43.13392 -1 2 1 + 368 96 14 0.417 53.88771 43.40698 42.90124 -1 2 1 + 369 96 14 0.417 54.97915 42.74512 43.71525 -1 2 1 + 370 97 13 -0.834 41.23040 49.49766 49.75568 0 -2 0 + 371 97 14 0.417 40.54278 49.43865 49.09241 0 -2 0 + 372 97 14 0.417 41.81904 48.76959 49.55653 0 -2 0 + 373 98 13 -0.834 54.20957 45.39084 54.97428 -1 0 0 + 374 98 14 0.417 54.66721 46.06623 55.47493 -1 0 0 + 375 98 14 0.417 53.74016 44.87996 55.63374 -1 0 0 + 376 99 13 -0.834 61.27515 64.38553 39.98716 -1 0 1 + 377 99 14 0.417 61.56153 64.23410 40.88787 -1 0 1 + 378 99 14 0.417 60.44736 63.91029 39.91542 -1 0 1 + 379 100 13 -0.834 55.67284 58.14856 42.21767 -1 1 2 + 380 100 14 0.417 55.46369 57.24253 42.44485 -1 1 2 + 381 100 14 0.417 56.62771 58.19397 42.26677 -1 1 2 + 382 101 13 -0.834 43.66528 51.07118 53.71174 0 0 0 + 383 101 14 0.417 42.87715 50.89079 53.19934 0 0 0 + 384 101 14 0.417 43.37793 51.68815 54.38481 0 0 0 + 385 102 13 -0.834 39.90899 44.53973 36.42818 0 2 0 + 386 102 14 0.417 39.84006 43.65427 36.07118 0 2 0 + 387 102 14 0.417 40.52179 44.98683 35.84438 0 2 0 + 388 103 13 -0.834 51.24695 66.96031 48.71611 -1 -1 1 + 389 103 14 0.417 50.88275 67.26607 49.54684 -1 -1 1 + 390 103 14 0.417 52.19366 66.95318 48.85726 -1 -1 1 + 391 104 13 -0.834 55.15911 56.17347 57.08906 -1 0 0 + 392 104 14 0.417 55.86241 55.65189 56.70232 -1 0 0 + 393 104 14 0.417 54.93977 55.71619 30.52949 -1 0 1 + 394 105 13 -0.834 37.33282 54.30424 56.96734 0 0 0 + 395 105 14 0.417 64.15558 54.97773 29.99806 -1 0 1 + 396 105 14 0.417 64.13467 53.88397 56.32293 -1 0 0 + 397 106 13 -0.834 53.07827 51.20543 32.31512 -1 0 1 + 398 106 14 0.417 52.39494 50.78813 31.79057 -1 0 1 + 399 106 14 0.417 52.65819 51.38698 33.15584 -1 0 1 + 400 107 13 -0.834 43.06086 51.65229 35.75926 1 1 1 + 401 107 14 0.417 42.70958 52.01746 36.57135 1 1 1 + 402 107 14 0.417 43.42908 50.80682 36.01586 1 1 1 + 403 108 13 -0.834 53.92253 56.24460 34.48089 0 0 1 + 404 108 14 0.417 53.22007 56.39276 35.11401 0 0 1 + 405 108 14 0.417 54.59075 55.76600 34.97147 0 0 1 + 406 109 13 -0.834 61.71524 66.84153 38.60005 -1 -1 0 + 407 109 14 0.417 61.25397 66.04877 38.87388 -1 -1 0 + 408 109 14 0.417 62.23260 67.09437 39.36467 -1 -1 0 + 409 110 13 -0.834 43.52824 62.78695 41.49939 0 -1 -1 + 410 110 14 0.417 43.61050 61.97218 41.00379 0 -1 -1 + 411 110 14 0.417 43.53140 63.47437 40.83330 0 -1 -1 + 412 111 13 -0.834 51.13822 55.54090 53.50461 0 1 -2 + 413 111 14 0.417 50.69587 56.38179 53.62064 0 1 -2 + 414 111 14 0.417 51.43262 55.54828 52.59383 0 1 -2 + 415 112 13 -0.834 46.94709 50.11761 31.92599 0 0 0 + 416 112 14 0.417 47.19652 51.02564 31.75423 0 0 0 + 417 112 14 0.417 46.57462 49.81059 31.09941 0 0 0 + 418 113 13 -0.834 47.96666 45.13049 44.46108 -1 2 -1 + 419 113 14 0.417 47.01871 45.24108 44.53489 -1 2 -1 + 420 113 14 0.417 48.26343 45.91034 43.99202 -1 2 -1 + 421 114 13 -0.834 44.43868 43.44849 32.90814 -1 -1 1 + 422 114 14 0.417 43.86055 43.24165 33.64245 -1 -1 1 + 423 114 14 0.417 45.31670 43.24154 33.22828 -1 -1 1 + 424 115 13 -0.834 61.07172 47.80130 53.14504 -1 1 -1 + 425 115 14 0.417 61.34864 48.71600 53.19864 -1 1 -1 + 426 115 14 0.417 60.72118 47.60538 54.01394 -1 1 -1 + 427 116 13 -0.834 51.38727 44.10864 54.92855 -1 0 -1 + 428 116 14 0.417 50.77962 44.80360 55.18160 -1 0 -1 + 429 116 14 0.417 52.05111 44.10744 55.61815 -1 0 -1 + 430 117 13 -0.834 41.05585 60.12319 49.44785 1 -1 0 + 431 117 14 0.417 41.72702 60.76812 49.67116 1 -1 0 + 432 117 14 0.417 40.24373 60.62784 49.40265 1 -1 0 + 433 118 13 -0.834 50.88548 68.33364 33.37284 -1 0 -1 + 434 118 14 0.417 50.48275 67.46671 33.32310 -1 0 -1 + 435 118 14 0.417 51.82702 68.16119 33.37343 -1 0 -1 + 436 119 13 -0.834 38.79644 59.29061 55.22446 1 1 -1 + 437 119 14 0.417 38.82887 59.83550 56.01077 1 1 -1 + 438 119 14 0.417 39.26097 59.79985 54.56028 1 1 -1 + 439 120 13 -0.834 56.31813 41.68729 51.11871 -2 0 -1 + 440 120 14 0.417 55.45155 41.35580 51.35412 -2 0 -1 + 441 120 14 0.417 56.14879 42.34135 50.44062 -2 0 -1 + 442 121 13 -0.834 45.53697 59.28154 47.22033 -1 0 -1 + 443 121 14 0.417 45.45062 59.55577 46.30733 -1 0 -1 + 444 121 14 0.417 46.00774 59.99977 47.64313 -1 0 -1 + 445 122 13 -0.834 60.47636 43.28130 46.20944 -1 0 -1 + 446 122 14 0.417 60.97762 42.59184 45.77396 -1 0 -1 + 447 122 14 0.417 59.72992 42.82584 46.59884 -1 0 -1 + 448 123 13 -0.834 58.49080 48.18289 45.77215 0 0 -1 + 449 123 14 0.417 58.74342 47.25991 45.74879 0 0 -1 + 450 123 14 0.417 58.17926 48.32386 46.66621 0 0 -1 + 451 124 13 -0.834 50.93473 56.12663 41.58575 -1 0 0 + 452 124 14 0.417 50.36171 56.05214 42.34885 -1 0 0 + 453 124 14 0.417 50.40135 56.57242 40.92771 -1 0 0 + 454 125 13 -0.834 60.55008 41.95542 56.22749 -1 0 -1 + 455 125 14 0.417 59.65163 41.78987 55.94175 -1 0 -1 + 456 125 14 0.417 61.09463 41.59967 55.52524 -1 0 -1 + 457 126 13 -0.834 58.58373 51.69338 48.78985 -1 1 0 + 458 126 14 0.417 58.38773 52.01803 49.66874 -1 1 0 + 459 126 14 0.417 58.66973 50.74614 48.89756 -1 1 0 + 460 127 13 -0.834 37.82769 45.69808 30.85100 0 1 3 + 461 127 14 0.417 38.37007 45.10637 31.37248 0 1 3 + 462 127 14 0.417 37.14646 45.99401 31.45481 0 1 3 + 463 128 13 -0.834 50.96455 60.06361 33.68049 0 0 0 + 464 128 14 0.417 51.72055 60.15430 34.26055 0 0 0 + 465 128 14 0.417 51.05673 60.77997 33.05234 0 0 0 + 466 129 13 -0.834 46.43413 68.11245 51.48833 -1 0 -1 + 467 129 14 0.417 46.82151 41.36005 50.86943 -1 1 -1 + 468 129 14 0.417 47.09847 67.43153 51.59433 -1 0 -1 + 469 130 13 -0.834 61.79997 47.41648 57.05141 -1 -1 0 + 470 130 14 0.417 62.68713 47.23872 56.73898 -1 -1 0 + 471 130 14 0.417 61.48917 46.57417 30.01195 -1 -1 1 + 472 131 13 -0.834 45.30689 46.58119 54.43763 0 1 -1 + 473 131 14 0.417 45.67282 45.73922 54.70859 0 1 -1 + 474 131 14 0.417 44.46622 46.35973 54.03705 0 1 -1 + 475 132 13 -0.834 62.60829 48.56385 49.02640 -1 1 0 + 476 132 14 0.417 62.44761 48.65968 48.08766 -1 1 0 + 477 132 14 0.417 62.98242 47.68753 49.11762 -1 1 0 + 478 133 13 -0.834 63.49107 56.77075 38.74961 -1 0 2 + 479 133 14 0.417 63.12281 56.39554 39.54952 -1 0 2 + 480 133 14 0.417 62.84612 57.42058 38.47033 -1 0 2 + 481 134 13 -0.834 50.74846 48.34849 33.46075 0 0 1 + 482 134 14 0.417 50.75342 49.30521 33.43086 0 0 1 + 483 134 14 0.417 50.91203 48.07929 32.55686 0 0 1 + 484 135 13 -0.834 44.40923 67.37148 56.42156 0 0 0 + 485 135 14 0.417 43.93400 67.78902 29.76856 0 0 1 + 486 135 14 0.417 44.94884 66.70468 56.84633 0 0 0 + 487 136 13 -0.834 44.25343 64.95349 43.22104 0 0 0 + 488 136 14 0.417 44.13229 64.08173 42.84472 0 0 0 + 489 136 14 0.417 44.01188 65.55470 42.51643 0 0 0 + 490 137 13 -0.834 46.68300 67.52863 32.69859 -1 -1 0 + 491 137 14 0.417 46.68369 68.22637 33.35389 -1 -1 0 + 492 137 14 0.417 47.60248 67.43099 32.45106 -1 -1 0 + 493 138 13 -0.834 57.25376 61.01737 33.86507 -2 1 1 + 494 138 14 0.417 57.40827 60.52366 34.67043 -2 1 1 + 495 138 14 0.417 57.35792 60.37307 33.16488 -2 1 1 + 496 139 13 -0.834 57.39946 54.16835 56.70699 0 -1 -1 + 497 139 14 0.417 57.31939 53.23092 56.53080 0 -1 -1 + 498 139 14 0.417 57.32300 54.24112 30.28699 0 -1 0 + 499 140 13 -0.834 52.36697 48.69246 41.49227 -1 1 0 + 500 140 14 0.417 51.78735 47.93629 41.40021 -1 1 0 + 501 140 14 0.417 53.21603 48.31702 41.72547 -1 1 0 + 502 141 13 -0.834 54.69200 49.57915 45.55048 0 0 -1 + 503 141 14 0.417 54.95958 48.66911 45.42211 0 0 -1 + 504 141 14 0.417 55.28513 50.08439 44.99446 0 0 -1 + 505 142 13 -0.834 37.26724 53.17896 42.50469 1 -1 -1 + 506 142 14 0.417 63.93194 53.34801 43.12782 0 -1 -1 + 507 142 14 0.417 36.94831 52.45044 41.97199 1 -1 -1 + 508 143 13 -0.834 42.56283 66.92379 33.49577 -1 0 1 + 509 143 14 0.417 41.71356 66.58931 33.20750 -1 0 1 + 510 143 14 0.417 43.03645 66.14842 33.79697 -1 0 1 + 511 144 13 -0.834 61.43331 45.62855 38.97695 0 1 1 + 512 144 14 0.417 61.20190 45.98514 39.83458 0 1 1 + 513 144 14 0.417 62.31351 45.96414 38.80708 0 1 1 + 514 145 13 -0.834 49.37935 56.26031 56.72879 1 1 0 + 515 145 14 0.417 49.03977 57.11146 56.45221 1 1 0 + 516 145 14 0.417 48.60052 55.75658 56.96530 1 1 0 + 517 146 13 -0.834 63.13959 56.23999 49.92079 -1 0 -1 + 518 146 14 0.417 63.72474 55.58123 50.29478 -1 0 -1 + 519 146 14 0.417 63.40966 57.06154 50.33112 -1 0 -1 + 520 147 13 -0.834 58.55937 66.56287 54.17345 -1 0 0 + 521 147 14 0.417 59.28260 66.81524 53.59945 -1 0 0 + 522 147 14 0.417 58.28559 67.38088 54.58834 -1 0 0 + 523 148 13 -0.834 55.49901 62.14366 46.01274 -1 0 -1 + 524 148 14 0.417 55.08057 61.57956 45.36238 -1 0 -1 + 525 148 14 0.417 55.53371 63.00495 45.59652 -1 0 -1 + 526 149 13 -0.834 48.09589 47.38106 38.97384 0 1 0 + 527 149 14 0.417 47.94178 48.02346 38.28116 0 1 0 + 528 149 14 0.417 47.26125 47.32494 39.43910 0 1 0 + 529 150 13 -0.834 40.27661 53.03711 48.83757 0 0 0 + 530 150 14 0.417 40.32476 53.91333 49.21992 0 0 0 + 531 150 14 0.417 41.18363 52.81848 48.62365 0 0 0 + 532 151 13 -0.834 36.85277 41.68065 44.81488 1 2 0 + 533 151 14 0.417 36.95709 68.34807 45.45504 1 1 0 + 534 151 14 0.417 37.14062 41.29651 43.98673 1 2 0 + 535 152 13 -0.834 37.74881 65.81650 33.58759 -1 0 1 + 536 152 14 0.417 37.69052 65.99217 34.52673 -1 0 1 + 537 152 14 0.417 37.02193 65.21970 33.40951 -1 0 1 + 538 153 13 -0.834 63.01838 46.13766 43.99274 -2 0 0 + 539 153 14 0.417 62.72780 46.33504 43.10232 -2 0 0 + 540 153 14 0.417 63.75125 46.73459 44.14387 -2 0 0 + 541 154 13 -0.834 43.83288 53.92104 38.64974 0 2 1 + 542 154 14 0.417 44.46072 53.30394 39.02556 0 2 1 + 543 154 14 0.417 44.17373 54.10726 37.77488 0 2 1 + 544 155 13 -0.834 54.48021 41.30441 45.39416 1 1 -2 + 545 155 14 0.417 54.42996 67.86451 44.88861 1 0 -2 + 546 155 14 0.417 54.84291 41.03852 46.23914 1 1 -2 + 547 156 13 -0.834 51.26407 63.10699 50.73012 0 0 -2 + 548 156 14 0.417 51.64016 62.23294 50.83411 0 0 -2 + 549 156 14 0.417 51.56733 63.39797 49.87011 0 0 -2 + 550 157 13 -0.834 54.61161 63.67709 53.56970 0 1 1 + 551 157 14 0.417 55.55339 63.81655 53.47054 0 1 1 + 552 157 14 0.417 54.24805 63.87070 52.70565 0 1 1 + 553 158 13 -0.834 46.57444 42.69363 30.13287 -1 0 1 + 554 158 14 0.417 45.93025 42.28051 30.70783 -1 0 1 + 555 158 14 0.417 47.27305 42.04459 30.04973 -1 0 1 + 556 159 13 -0.834 37.92811 50.36816 42.31352 1 1 0 + 557 159 14 0.417 38.62401 50.90050 42.69899 1 1 0 + 558 159 14 0.417 38.11553 50.37135 41.37484 1 1 0 + 559 160 13 -0.834 40.53318 48.69302 33.52502 -1 0 0 + 560 160 14 0.417 40.10720 48.55075 32.67972 -1 0 0 + 561 160 14 0.417 41.22323 49.33057 33.34173 -1 0 0 + 562 161 13 -0.834 58.20095 45.48345 42.83426 1 0 -1 + 563 161 14 0.417 58.76156 46.25356 42.92849 1 0 -1 + 564 161 14 0.417 58.80813 44.74348 42.83158 1 0 -1 + 565 162 13 -0.834 59.85909 67.06752 31.43173 -1 1 0 + 566 162 14 0.417 59.95062 66.12180 31.54782 -1 1 0 + 567 162 14 0.417 60.75672 67.38534 31.33437 -1 1 0 + 568 163 13 -0.834 48.48808 51.17807 55.92072 -2 0 0 + 569 163 14 0.417 49.24951 51.62602 55.55219 -2 0 0 + 570 163 14 0.417 48.81105 50.30745 56.15303 -2 0 0 + 571 164 13 -0.834 47.51169 45.69616 48.99410 0 0 -1 + 572 164 14 0.417 48.36822 46.03425 48.73281 0 0 -1 + 573 164 14 0.417 47.56201 45.62598 49.94740 0 0 -1 + 574 165 13 -0.834 51.10678 64.23082 47.99167 0 -2 -1 + 575 165 14 0.417 51.33188 65.16116 47.98611 0 -2 -1 + 576 165 14 0.417 50.15837 64.21415 48.12002 0 -2 -1 + 577 166 13 -0.834 42.97263 56.29674 30.18230 0 0 0 + 578 166 14 0.417 42.45756 55.50818 30.01170 0 0 0 + 579 166 14 0.417 42.79675 56.86516 56.80386 0 0 -1 + 580 167 13 -0.834 44.45917 53.64338 31.85015 -1 0 0 + 581 167 14 0.417 44.64093 54.17218 31.07325 -1 0 0 + 582 167 14 0.417 43.66299 53.15965 31.63030 -1 0 0 + 583 168 13 -0.834 52.20677 49.92062 48.65330 1 0 0 + 584 168 14 0.417 52.24176 50.63538 49.28902 1 0 0 + 585 168 14 0.417 52.01918 50.35058 47.81890 1 0 0 + 586 169 13 -0.834 45.94013 51.43638 56.49888 0 0 0 + 587 169 14 0.417 46.89200 51.34153 56.53372 0 0 0 + 588 169 14 0.417 45.60504 50.66051 56.94833 0 0 0 + 589 170 13 -0.834 45.61845 41.38709 48.05698 1 0 0 + 590 170 14 0.417 46.42604 41.83441 47.80406 1 0 0 + 591 170 14 0.417 45.31743 41.85685 48.83477 1 0 0 + 592 171 13 -0.834 47.68232 42.84819 52.92728 0 1 0 + 593 171 14 0.417 47.61830 42.41414 52.07654 0 1 0 + 594 171 14 0.417 48.39202 42.39011 53.37758 0 1 0 + 595 172 13 -0.834 37.01774 65.84057 36.39542 1 -1 0 + 596 172 14 0.417 36.84918 65.13561 37.02061 1 -1 0 + 597 172 14 0.417 63.52368 66.19949 36.19938 0 -1 0 + 598 173 13 -0.834 51.52891 58.65207 39.31760 -1 -3 -1 + 599 173 14 0.417 51.57384 59.35596 39.96472 -1 -3 -1 + 600 173 14 0.417 51.00435 59.01522 38.60403 -1 -3 -1 + 601 174 13 -0.834 49.06578 54.25781 44.33488 0 -1 -1 + 602 174 14 0.417 48.81980 55.18018 44.26437 0 -1 -1 + 603 174 14 0.417 49.41695 54.17018 45.22104 0 -1 -1 + 604 175 13 -0.834 47.03819 42.38557 34.31948 -1 -1 0 + 605 175 14 0.417 47.39035 41.82883 35.01393 -1 -1 0 + 606 175 14 0.417 47.47024 43.23019 34.44673 -1 -1 0 + 607 176 13 -0.834 41.64025 43.65472 38.33192 0 1 0 + 608 176 14 0.417 41.17224 44.02383 37.58295 0 1 0 + 609 176 14 0.417 41.46027 44.26142 39.05008 0 1 0 + 610 177 13 -0.834 61.41261 58.14241 37.49312 -2 0 0 + 611 177 14 0.417 61.24368 59.06676 37.67551 -2 0 0 + 612 177 14 0.417 60.57871 57.80631 37.16465 -2 0 0 + 613 178 13 -0.834 48.58355 55.60536 32.34542 0 -2 -2 + 614 178 14 0.417 48.05292 55.64371 31.54969 0 -2 -2 + 615 178 14 0.417 49.00004 56.46561 32.39784 0 -2 -2 + 616 179 13 -0.834 51.18618 52.33768 44.26866 0 -1 0 + 617 179 14 0.417 50.47419 52.97535 44.21659 0 -1 0 + 618 179 14 0.417 51.18053 51.90159 43.41657 0 -1 0 + 619 180 13 -0.834 63.77008 46.64985 53.45124 -2 0 -1 + 620 180 14 0.417 37.25943 46.94040 53.14955 -1 0 -1 + 621 180 14 0.417 63.15834 47.28506 53.07904 -2 0 -1 + 622 181 13 -0.834 37.28071 56.79400 31.30862 1 1 0 + 623 181 14 0.417 37.34297 57.68998 31.63963 1 1 0 + 624 181 14 0.417 36.99543 56.89301 30.40030 1 1 0 + 625 182 13 -0.834 38.98742 57.66608 44.07685 1 0 1 + 626 182 14 0.417 39.04152 57.61214 43.12270 1 0 1 + 627 182 14 0.417 39.46043 56.89430 44.38805 1 0 1 + 628 183 13 -0.834 64.13749 51.25767 48.28997 0 -1 0 + 629 183 14 0.417 64.05120 52.19840 48.13566 0 -1 0 + 630 183 14 0.417 63.26932 50.90255 48.09918 0 -1 0 + 631 184 13 -0.834 41.02949 42.14202 43.02064 0 0 -1 + 632 184 14 0.417 40.60130 42.82178 43.54104 0 0 -1 + 633 184 14 0.417 40.43829 41.99723 42.28189 0 0 -1 + 634 185 13 -0.834 49.87332 48.21836 52.83028 0 1 0 + 635 185 14 0.417 49.13733 48.15035 53.43849 0 1 0 + 636 185 14 0.417 50.32176 47.37567 52.90100 0 1 0 + 637 186 13 -0.834 56.06860 48.51217 38.12813 -1 1 0 + 638 186 14 0.417 56.55702 47.73454 38.39826 -1 1 0 + 639 186 14 0.417 55.52690 48.21357 37.39762 -1 1 0 + 640 187 13 -0.834 54.22718 59.47740 40.22374 -1 0 1 + 641 187 14 0.417 53.93839 59.03820 39.42377 -1 0 1 + 642 187 14 0.417 54.74005 58.81629 40.68868 -1 0 1 + 643 188 13 -0.834 60.09461 46.88146 32.04739 -1 0 -1 + 644 188 14 0.417 60.91535 46.43611 31.83683 -1 0 -1 + 645 188 14 0.417 60.13630 47.02716 32.99253 -1 0 -1 + 646 189 13 -0.834 45.18646 44.57845 41.54076 0 0 0 + 647 189 14 0.417 44.28239 44.89208 41.51774 0 0 0 + 648 189 14 0.417 45.34481 44.23786 40.66033 0 0 0 + 649 190 13 -0.834 42.47099 45.68692 31.56356 1 0 1 + 650 190 14 0.417 43.26152 45.18821 31.76995 1 0 1 + 651 190 14 0.417 42.78187 46.58070 31.41951 1 0 1 + 652 191 13 -0.834 41.23413 47.67043 41.85221 0 1 0 + 653 191 14 0.417 41.04508 48.58329 42.06946 0 1 0 + 654 191 14 0.417 40.84394 47.54379 40.98737 0 1 0 + 655 192 13 -0.834 48.84750 60.39708 36.57115 0 0 0 + 656 192 14 0.417 48.57626 59.48478 36.46920 0 0 0 + 657 192 14 0.417 48.59448 60.62409 37.46597 0 0 0 + 658 193 13 -0.834 56.78263 43.55464 49.12966 -1 0 -1 + 659 193 14 0.417 56.56851 44.25428 48.51250 -1 0 -1 + 660 193 14 0.417 57.66563 43.76469 49.43365 -1 0 -1 + 661 194 13 -0.834 59.52236 53.66894 43.24587 -1 2 0 + 662 194 14 0.417 59.44365 54.61174 43.10041 -1 2 0 + 663 194 14 0.417 59.73284 53.58637 44.17598 -1 2 0 + 664 195 13 -0.834 63.61393 61.54696 40.57053 -1 -1 1 + 665 195 14 0.417 36.90989 60.94398 40.24291 0 -1 1 + 666 195 14 0.417 63.74510 61.55794 41.51864 -1 -1 1 + 667 196 13 -0.834 54.91742 43.16160 33.69639 0 0 -1 + 668 196 14 0.417 55.84062 43.16106 33.94925 0 0 -1 + 669 196 14 0.417 54.73416 44.07060 33.45898 0 0 -1 + 670 197 13 -0.834 41.09699 64.92982 48.38401 0 -1 -1 + 671 197 14 0.417 40.19042 64.83711 48.67687 0 -1 -1 + 672 197 14 0.417 41.27055 64.13206 47.88433 0 -1 -1 + 673 198 13 -0.834 49.09688 60.43369 49.80048 0 0 -1 + 674 198 14 0.417 49.75346 61.03633 50.14971 0 0 -1 + 675 198 14 0.417 49.51718 59.57440 49.83534 0 0 -1 + 676 199 13 -0.834 45.06873 45.25146 44.50830 0 1 0 + 677 199 14 0.417 45.08807 45.11881 43.56053 0 1 0 + 678 199 14 0.417 44.41198 44.63084 44.82413 0 1 0 + 679 200 13 -0.834 37.63886 45.88962 36.45768 0 0 2 + 680 200 14 0.417 38.32892 45.23766 36.58017 0 0 2 + 681 200 14 0.417 37.24627 45.98938 37.32495 0 0 2 + 682 201 13 -0.834 45.25770 47.01692 51.04211 -1 0 -2 + 683 201 14 0.417 45.49830 47.82868 50.59555 -1 0 -2 + 684 201 14 0.417 46.08295 46.68269 51.39354 -1 0 -2 + 685 202 13 -0.834 63.44567 60.77839 50.98507 -2 0 0 + 686 202 14 0.417 62.95029 60.46072 51.74001 -2 0 0 + 687 202 14 0.417 62.77774 61.08133 50.36998 -2 0 0 + 688 203 13 -0.834 48.00038 59.99003 33.31045 0 1 1 + 689 203 14 0.417 48.92391 59.89924 33.54518 0 1 1 + 690 203 14 0.417 47.68314 60.70831 33.85788 0 1 1 + 691 204 13 -0.834 51.29617 53.45952 36.10138 -1 -1 1 + 692 204 14 0.417 50.79623 53.20605 36.87731 -1 -1 1 + 693 204 14 0.417 51.41983 54.40421 36.19363 -1 -1 1 + 694 205 13 -0.834 48.55343 45.13540 34.47517 0 0 0 + 695 205 14 0.417 48.10547 45.97105 34.34382 0 0 0 + 696 205 14 0.417 49.13373 45.28879 35.22081 0 0 0 + 697 206 13 -0.834 48.34844 61.02741 54.77908 1 -1 -1 + 698 206 14 0.417 47.77364 61.75290 55.02301 1 -1 -1 + 699 206 14 0.417 49.14675 61.17253 55.28690 1 -1 -1 + 700 207 13 -0.834 38.97661 48.73541 31.27301 2 -1 0 + 701 207 14 0.417 38.86774 47.99634 30.67453 2 -1 0 + 702 207 14 0.417 38.60214 49.48112 30.80404 2 -1 0 + 703 208 13 -0.834 56.37687 61.69299 40.12439 0 -1 -1 + 704 208 14 0.417 56.35009 61.71409 39.16778 0 -1 -1 + 705 208 14 0.417 55.62486 61.15580 40.37371 0 -1 -1 + 706 209 13 -0.834 47.86700 41.38854 36.76722 -1 0 0 + 707 209 14 0.417 48.79854 41.26117 36.94678 -1 0 0 + 708 209 14 0.417 47.57553 42.00602 37.43804 -1 0 0 + 709 210 13 -0.834 43.22089 60.92576 39.48904 -1 -1 0 + 710 210 14 0.417 42.70029 60.20976 39.85311 -1 -1 0 + 711 210 14 0.417 43.25319 60.74538 38.54954 -1 -1 0 + 712 211 13 -0.834 56.26248 49.03317 34.29585 -1 0 0 + 713 211 14 0.417 56.69244 49.86416 34.09381 -1 0 0 + 714 211 14 0.417 55.61194 48.92467 33.60212 -1 0 0 + 715 212 13 -0.834 47.52063 49.37901 51.21673 1 0 0 + 716 212 14 0.417 48.35964 48.95385 51.03909 1 0 0 + 717 212 14 0.417 47.47856 49.43746 52.17122 1 0 0 + 718 213 13 -0.834 62.35532 56.31018 41.33556 0 0 0 + 719 213 14 0.417 62.07506 57.22150 41.42032 0 0 0 + 720 213 14 0.417 62.92184 56.16192 42.09274 0 0 0 + 721 214 13 -0.834 61.09797 64.53756 45.11003 -1 0 1 + 722 214 14 0.417 61.11801 63.59600 44.93887 -1 0 1 + 723 214 14 0.417 61.95676 64.85132 44.82670 -1 0 1 + 724 215 13 -0.834 51.22661 62.08872 31.93454 0 0 0 + 725 215 14 0.417 51.98994 62.65586 32.04369 0 0 0 + 726 215 14 0.417 50.47877 62.65171 32.13456 0 0 0 + 727 216 13 -0.834 40.65443 48.64853 54.43476 0 0 -1 + 728 216 14 0.417 40.25608 47.97845 54.99023 0 0 -1 + 729 216 14 0.417 41.58025 48.64240 54.67776 0 0 -1 + 730 217 13 -0.834 39.34873 63.07587 52.07209 1 1 -1 + 731 217 14 0.417 39.17266 63.98076 51.81438 1 1 -1 + 732 217 14 0.417 39.29792 62.57948 51.25523 1 1 -1 + 733 218 13 -0.834 45.66307 65.90840 47.75613 -1 0 0 + 734 218 14 0.417 44.99427 65.52542 48.32381 -1 0 0 + 735 218 14 0.417 45.75913 66.80721 48.07102 -1 0 0 + 736 219 13 -0.834 45.83158 51.91442 38.93974 0 0 0 + 737 219 14 0.417 46.07939 51.87422 39.86344 0 0 0 + 738 219 14 0.417 45.49928 51.03877 38.74210 0 0 0 + 739 220 13 -0.834 58.03934 67.88594 44.36036 -1 1 -1 + 740 220 14 0.417 58.69084 68.22520 43.74661 -1 1 -1 + 741 220 14 0.417 58.24719 68.31309 45.19138 -1 1 -1 + 742 221 13 -0.834 57.23319 66.95459 30.42832 0 0 0 + 743 221 14 0.417 56.95316 66.93560 31.34345 0 0 0 + 744 221 14 0.417 58.18154 66.82998 30.46491 0 0 0 + 745 222 13 -0.834 60.87005 44.72970 53.74755 -1 0 -1 + 746 222 14 0.417 60.02694 44.42275 53.41412 -1 0 -1 + 747 222 14 0.417 61.31963 45.07903 52.97808 -1 0 -1 + 748 223 13 -0.834 50.61352 50.44308 31.66369 0 -1 0 + 749 223 14 0.417 50.38691 49.95555 30.87173 0 -1 0 + 750 223 14 0.417 50.16704 51.28387 31.56391 0 -1 0 + 751 224 13 -0.834 42.70363 42.07925 34.73823 0 1 0 + 752 224 14 0.417 42.74630 41.15512 34.49249 0 1 0 + 753 224 14 0.417 41.77538 42.23983 34.90796 0 1 0 + 754 225 13 -0.834 50.34157 43.80796 44.49841 -1 1 0 + 755 225 14 0.417 49.44649 44.14718 44.50119 -1 1 0 + 756 225 14 0.417 50.24323 42.86994 44.66171 -1 1 0 + 757 226 13 -0.834 62.39528 64.92163 33.72829 -3 -1 1 + 758 226 14 0.417 61.94679 64.42233 34.41078 -3 -1 1 + 759 226 14 0.417 61.94061 64.68505 32.91986 -3 -1 1 + 760 227 13 -0.834 46.62188 47.13429 41.79430 0 1 1 + 761 227 14 0.417 46.21721 46.28415 41.62178 0 1 1 + 762 227 14 0.417 47.40198 46.92861 42.30946 0 1 1 + 763 228 13 -0.834 41.35469 54.31275 56.45453 0 0 -1 + 764 228 14 0.417 41.79769 53.47653 56.31055 0 0 -1 + 765 228 14 0.417 40.57273 54.26794 55.90425 0 0 -1 + 766 229 13 -0.834 48.43878 42.20000 49.94999 0 0 0 + 767 229 14 0.417 49.34431 42.29756 50.24447 0 0 0 + 768 229 14 0.417 48.41583 42.63350 49.09688 0 0 0 + 769 230 13 -0.834 37.29829 50.04209 33.34795 0 1 0 + 770 230 14 0.417 36.96213 49.51969 34.07619 0 1 0 + 771 230 14 0.417 37.98470 49.49933 32.96002 0 1 0 + 772 231 13 -0.834 58.91995 56.17895 33.02333 -1 0 0 + 773 231 14 0.417 59.83980 56.43785 32.96791 -1 0 0 + 774 231 14 0.417 58.89269 55.54120 33.73661 -1 0 0 + 775 232 13 -0.834 39.86900 65.81481 43.81866 0 0 -1 + 776 232 14 0.417 40.31483 64.99515 43.60502 0 0 -1 + 777 232 14 0.417 40.41298 66.21397 44.49762 0 0 -1 + 778 233 13 -0.834 62.71324 65.93556 51.55400 -1 0 0 + 779 233 14 0.417 62.38032 66.39597 52.32436 -1 0 0 + 780 233 14 0.417 63.52336 65.52245 51.85285 -1 0 0 + 781 234 13 -0.834 59.23324 49.58642 31.35843 0 0 0 + 782 234 14 0.417 59.28102 48.68976 31.69001 0 0 0 + 783 234 14 0.417 59.95115 50.04304 31.79700 0 0 0 + 784 235 13 -0.834 41.02310 67.21389 51.60243 0 0 0 + 785 235 14 0.417 41.77450 67.79064 51.74021 0 0 0 + 786 235 14 0.417 40.36922 67.76899 51.17753 0 0 0 + 787 236 13 -0.834 41.38918 62.43794 34.42449 0 0 1 + 788 236 14 0.417 41.26665 63.14612 33.79227 0 0 1 + 789 236 14 0.417 42.30454 62.51275 34.69423 0 0 1 + 790 237 13 -0.834 52.28796 56.01034 50.59905 0 -1 -1 + 791 237 14 0.417 53.14113 56.07317 51.02851 0 -1 -1 + 792 237 14 0.417 52.14509 55.07070 50.48548 0 -1 -1 + 793 238 13 -0.834 53.25204 66.52198 39.76351 0 -1 0 + 794 238 14 0.417 52.30774 66.44732 39.62571 0 -1 0 + 795 238 14 0.417 53.47725 67.38617 39.41895 0 -1 0 + 796 239 13 -0.834 59.77604 60.82055 48.12264 -1 -1 -1 + 797 239 14 0.417 59.80699 60.05926 48.70205 -1 -1 -1 + 798 239 14 0.417 58.96049 60.71611 47.63253 -1 -1 -1 + 799 240 13 -0.834 48.99693 51.07559 36.89084 0 -1 1 + 800 240 14 0.417 48.22315 50.55308 37.10175 0 -1 1 + 801 240 14 0.417 48.88824 51.30348 35.96753 0 -1 1 + 802 241 13 -0.834 50.67863 62.63916 55.60559 1 0 -2 + 803 241 14 0.417 51.43406 62.16856 55.25331 1 0 -2 + 804 241 14 0.417 51.05760 63.36945 56.09477 1 0 -2 + 805 242 13 -0.834 41.05301 64.77947 55.72335 1 -1 -1 + 806 242 14 0.417 41.95836 64.58666 55.96711 1 -1 -1 + 807 242 14 0.417 41.07998 65.67647 55.39035 1 -1 -1 + 808 243 13 -0.834 59.16096 63.30207 34.55147 0 -1 2 + 809 243 14 0.417 58.62636 62.51316 34.64131 0 -1 2 + 810 243 14 0.417 59.80830 63.23451 35.25333 0 -1 2 + 811 244 13 -0.834 59.86542 53.52546 55.50419 0 -1 -1 + 812 244 14 0.417 60.26921 53.79963 56.32761 0 -1 -1 + 813 244 14 0.417 58.96256 53.83773 55.56399 0 -1 -1 + 814 245 13 -0.834 56.48528 44.99075 44.65443 1 0 0 + 815 245 14 0.417 55.84854 44.49932 44.13551 1 0 0 + 816 245 14 0.417 57.18258 45.20803 44.03571 1 0 0 + 817 246 13 -0.834 37.25407 54.85866 36.86076 0 -1 -1 + 818 246 14 0.417 37.37951 55.31820 36.03050 0 -1 -1 + 819 246 14 0.417 36.91899 55.52805 37.45731 0 -1 -1 + 820 247 13 -0.834 54.42875 47.21339 48.23883 -1 -1 -1 + 821 247 14 0.417 54.60966 48.13349 48.43097 -1 -1 -1 + 822 247 14 0.417 54.44092 47.16092 47.28312 -1 -1 -1 + 823 248 13 -0.834 42.61226 41.78391 40.84493 1 0 1 + 824 248 14 0.417 41.98531 41.90233 41.55849 1 0 1 + 825 248 14 0.417 42.35866 42.43623 40.19194 1 0 1 + 826 249 13 -0.834 37.83522 41.95649 50.31377 0 0 -2 + 827 249 14 0.417 37.42231 42.81133 50.19124 0 0 -2 + 828 249 14 0.417 37.46684 41.41031 49.61934 0 0 -2 + 829 250 13 -0.834 44.80898 44.15062 49.20688 0 -1 0 + 830 250 14 0.417 44.80289 44.55594 48.33975 0 -1 0 + 831 250 14 0.417 45.29722 44.76463 49.75537 0 -1 0 + 832 251 13 -0.834 37.44321 44.03405 38.75076 1 0 1 + 833 251 14 0.417 37.12277 44.06014 39.65235 1 0 1 + 834 251 14 0.417 64.13547 43.56266 38.26824 0 0 1 + 835 252 13 -0.834 38.82113 46.15070 46.12915 1 0 0 + 836 252 14 0.417 38.96657 46.44867 47.02709 1 0 0 + 837 252 14 0.417 38.09796 45.52731 46.19733 1 0 0 + 838 253 13 -0.834 43.08482 60.65520 45.34135 -1 0 1 + 839 253 14 0.417 42.82882 59.73347 45.30784 -1 0 1 + 840 253 14 0.417 44.00885 60.65685 45.09147 -1 0 1 + 841 254 13 -0.834 45.72190 46.51173 32.51384 1 0 0 + 842 254 14 0.417 46.00925 45.78294 31.96381 1 0 0 + 843 254 14 0.417 46.53186 46.95248 32.77064 1 0 0 + 844 255 13 -0.834 63.64359 44.33728 41.24417 -1 0 0 + 845 255 14 0.417 63.60411 43.61794 41.87443 -1 0 0 + 846 255 14 0.417 62.76926 44.36407 40.85550 -1 0 0 + 847 256 13 -0.834 48.53353 66.27879 51.60437 0 0 -1 + 848 256 14 0.417 49.21611 66.24938 50.93396 0 0 -1 + 849 256 14 0.417 48.67507 65.48862 52.12577 0 0 -1 + 850 257 13 -0.834 54.11962 54.32751 39.83526 -1 1 1 + 851 257 14 0.417 53.37975 54.47391 39.24585 -1 1 1 + 852 257 14 0.417 53.95747 53.46346 40.21391 -1 1 1 + 853 258 13 -0.834 53.72785 66.08707 44.78384 -1 -1 0 + 854 258 14 0.417 54.65423 65.85662 44.85413 -1 -1 0 + 855 258 14 0.417 53.26300 65.26936 44.96130 -1 -1 0 + 856 259 13 -0.834 39.06287 51.40870 53.96063 0 0 -1 + 857 259 14 0.417 39.12854 51.34243 53.00796 0 0 -1 + 858 259 14 0.417 38.38057 52.06341 54.10916 0 0 -1 + 859 260 13 -0.834 58.77064 49.77012 37.45292 0 0 0 + 860 260 14 0.417 59.49652 49.20688 37.72142 0 0 0 + 861 260 14 0.417 57.98575 49.25379 37.63621 0 0 0 + 862 261 13 -0.834 37.94204 48.36591 35.22049 -1 0 0 + 863 261 14 0.417 37.94000 47.48368 35.59187 -1 0 0 + 864 261 14 0.417 38.86901 48.59216 35.14453 -1 0 0 + 865 262 13 -0.834 47.05754 54.06564 40.63628 0 -2 1 + 866 262 14 0.417 47.01965 53.22193 41.08679 0 -2 1 + 867 262 14 0.417 46.68660 54.68838 41.26145 0 -2 1 + 868 263 13 -0.834 46.01283 65.88108 53.59469 0 0 0 + 869 263 14 0.417 45.30729 66.50296 53.77277 0 0 0 + 870 263 14 0.417 46.76378 66.42902 53.36650 0 0 0 + 871 264 13 -0.834 45.32546 67.91008 39.11365 -1 -1 0 + 872 264 14 0.417 44.38981 67.96233 38.91853 -1 -1 0 + 873 264 14 0.417 45.70517 67.47097 38.35257 -1 -1 0 + 874 265 13 -0.834 55.39761 51.53823 53.16553 -1 1 -1 + 875 265 14 0.417 54.64975 52.10179 53.36389 -1 1 -1 + 876 265 14 0.417 55.78119 51.91789 52.37499 -1 1 -1 + 877 266 13 -0.834 57.06415 51.22923 32.75117 -1 -1 0 + 878 266 14 0.417 56.79908 52.11139 32.49079 -1 -1 0 + 879 266 14 0.417 57.98399 51.16910 32.49322 -1 -1 0 + 880 267 13 -0.834 50.05222 47.30342 45.67457 0 0 -2 + 881 267 14 0.417 49.85957 46.82324 46.47990 0 0 -2 + 882 267 14 0.417 50.60617 46.70964 45.16781 0 0 -2 + 883 268 13 -0.834 50.46819 45.47822 52.51129 0 1 -1 + 884 268 14 0.417 50.78823 45.07196 53.31677 0 1 -1 + 885 268 14 0.417 51.03886 45.13243 51.82499 0 1 -1 + 886 269 13 -0.834 47.44130 61.30175 47.80124 0 0 0 + 887 269 14 0.417 48.02715 60.89314 48.43850 0 0 0 + 888 269 14 0.417 47.98636 61.43626 47.02595 0 0 0 + 889 270 13 -0.834 41.31630 52.47434 39.71677 1 0 0 + 890 270 14 0.417 41.07609 52.94514 40.51485 1 0 0 + 891 270 14 0.417 42.05418 52.96849 39.35955 1 0 0 + 892 271 13 -0.834 55.90762 58.63213 50.47814 0 1 0 + 893 271 14 0.417 55.80273 59.37784 51.06903 0 1 0 + 894 271 14 0.417 55.41449 58.87554 49.69468 0 1 0 + 895 272 13 -0.834 42.23424 55.62725 53.35280 0 1 -1 + 896 272 14 0.417 41.62946 55.10926 53.88399 0 1 -1 + 897 272 14 0.417 41.75761 56.43615 53.16647 0 1 -1 + 898 273 13 -0.834 62.31754 63.97065 42.48774 0 0 1 + 899 273 14 0.417 63.27023 64.05391 42.44669 0 0 1 + 900 273 14 0.417 62.16851 63.13573 42.93152 0 0 1 + 901 274 13 -0.834 60.93154 49.79182 56.13812 0 -1 0 + 902 274 14 0.417 61.38991 48.97402 56.33134 0 -1 0 + 903 274 14 0.417 60.29808 49.88575 56.84955 0 -1 0 + 904 275 13 -0.834 50.39572 45.11274 36.60756 0 1 -1 + 905 275 14 0.417 50.88541 44.33834 36.33051 0 1 -1 + 906 275 14 0.417 50.38352 45.05976 37.56322 0 1 -1 + 907 276 13 -0.834 46.57204 43.12189 39.29488 -1 2 -1 + 908 276 14 0.417 46.48449 42.17951 39.43813 -1 2 -1 + 909 276 14 0.417 47.49357 43.30747 39.47547 -1 2 -1 + 910 277 13 -0.834 54.39979 41.37518 38.62483 0 0 1 + 911 277 14 0.417 54.27469 42.27221 38.31511 0 0 1 + 912 277 14 0.417 54.57135 68.24024 37.83080 0 -1 1 + 913 278 13 -0.834 60.57638 52.40343 41.12327 -1 1 -1 + 914 278 14 0.417 60.40196 53.27982 40.78010 -1 1 -1 + 915 278 14 0.417 60.37657 52.46726 42.05721 -1 1 -1 + 916 279 13 -0.834 61.77806 59.06524 41.98029 0 0 0 + 917 279 14 0.417 62.58317 59.36537 42.40214 0 0 0 + 918 279 14 0.417 61.10430 59.16112 42.65342 0 0 0 + 919 280 13 -0.834 43.46789 48.64833 54.88223 0 1 -2 + 920 280 14 0.417 43.60676 49.48200 54.43286 0 1 -2 + 921 280 14 0.417 43.74339 47.98554 54.24895 0 1 -2 + 922 281 13 -0.834 51.98628 58.37454 48.60562 -1 0 0 + 923 281 14 0.417 51.81372 57.54909 49.05852 -1 0 0 + 924 281 14 0.417 52.67545 58.16319 47.97583 -1 0 0 + 925 282 13 -0.834 55.00551 65.64176 56.63926 0 -1 -1 + 926 282 14 0.417 55.59134 66.11131 29.86167 0 -1 0 + 927 282 14 0.417 54.80211 66.27584 55.95165 0 -1 -1 + 928 283 13 -0.834 55.02996 52.59142 50.59986 -1 1 0 + 929 283 14 0.417 54.13615 52.66743 50.26585 -1 1 0 + 930 283 14 0.417 55.48513 53.35419 50.24316 -1 1 0 + 931 284 13 -0.834 37.39245 67.88600 56.81733 0 -1 -1 + 932 284 14 0.417 38.13326 41.09044 56.62787 0 0 -1 + 933 284 14 0.417 37.74351 67.00148 56.71419 0 -1 -1 + 934 285 13 -0.834 42.83234 60.22766 53.36959 0 0 0 + 935 285 14 0.417 43.51497 59.86233 52.80672 0 0 0 + 936 285 14 0.417 43.27782 60.90528 53.87815 0 0 0 + 937 286 13 -0.834 59.24806 43.81265 38.44265 1 0 0 + 938 286 14 0.417 59.12140 43.55748 39.35647 1 0 0 + 939 286 14 0.417 60.07673 44.29174 38.43991 1 0 0 + 940 287 13 -0.834 61.29263 60.52642 52.74164 -1 1 -1 + 941 287 14 0.417 61.73918 60.02180 53.42149 -1 1 -1 + 942 287 14 0.417 60.93759 61.28711 53.20156 -1 1 -1 + 943 288 13 -0.834 63.43980 43.30119 30.90384 -1 1 0 + 944 288 14 0.417 63.34979 42.36405 30.73085 -1 1 0 + 945 288 14 0.417 64.20504 43.56693 30.39393 -1 1 0 + 946 289 13 -0.834 57.11924 59.06522 54.48909 -1 0 0 + 947 289 14 0.417 57.40605 59.83488 54.98062 -1 0 0 + 948 289 14 0.417 57.59698 58.33614 54.88463 -1 0 0 + 949 290 13 -0.834 51.89759 59.82680 44.82923 1 1 -1 + 950 290 14 0.417 51.33588 59.94068 44.06258 1 1 -1 + 951 290 14 0.417 51.32846 60.01914 45.57443 1 1 -1 + 952 291 13 -0.834 57.64696 65.49112 47.86068 -1 0 0 + 953 291 14 0.417 57.31105 65.98457 48.60895 -1 0 0 + 954 291 14 0.417 57.73765 64.59519 48.18521 -1 0 0 + 955 292 13 -0.834 50.35232 57.73892 32.55459 0 1 0 + 956 292 14 0.417 51.07441 57.69034 31.92813 0 1 0 + 957 292 14 0.417 50.48339 58.57180 33.00777 0 1 0 + 958 293 13 -0.834 46.20166 60.82812 38.38269 0 1 1 + 959 293 14 0.417 46.12191 61.76977 38.53504 0 1 1 + 960 293 14 0.417 45.30555 60.53505 38.21735 0 1 1 + 961 294 13 -0.834 41.42660 51.46433 55.94150 1 0 -1 + 962 294 14 0.417 40.58025 51.71240 55.56944 1 0 -1 + 963 294 14 0.417 41.63094 50.62307 55.53311 1 0 -1 + 964 295 13 -0.834 56.72642 53.95840 32.00323 0 -1 0 + 965 295 14 0.417 57.12177 54.49254 32.69216 0 -1 0 + 966 295 14 0.417 55.80349 54.21231 32.00259 0 -1 0 + 967 296 13 -0.834 43.25852 41.40642 31.27656 0 1 0 + 968 296 14 0.417 43.58058 42.21308 31.67880 0 1 0 + 969 296 14 0.417 43.16985 68.16459 32.00619 0 0 0 + 970 297 13 -0.834 54.50477 52.62435 30.30235 -2 1 0 + 971 297 14 0.417 54.04985 52.22243 31.04245 -2 1 0 + 972 297 14 0.417 54.36900 53.56465 30.41915 -2 1 0 + 973 298 13 -0.834 38.11258 59.33341 36.21749 1 0 0 + 974 298 14 0.417 38.95754 58.91929 36.04205 1 0 0 + 975 298 14 0.417 38.14750 60.16192 35.73940 1 0 0 + 976 299 13 -0.834 39.65020 64.70254 40.48616 -1 0 1 + 977 299 14 0.417 39.87581 65.58596 40.19474 -1 0 1 + 978 299 14 0.417 39.66086 64.17611 39.68676 -1 0 1 + 979 300 13 -0.834 63.26661 53.84973 48.10281 -1 1 1 + 980 300 14 0.417 63.38261 54.75210 48.40032 -1 1 1 + 981 300 14 0.417 62.32830 53.68505 48.19603 -1 1 1 + 982 301 13 -0.834 43.65966 61.04202 50.03088 0 0 0 + 983 301 14 0.417 44.11377 60.35973 50.52538 0 0 0 + 984 301 14 0.417 44.30508 61.74317 49.94108 0 0 0 + 985 302 13 -0.834 61.75204 50.20037 32.39414 0 0 0 + 986 302 14 0.417 62.04749 51.09027 32.58663 0 0 0 + 987 302 14 0.417 62.55370 49.67736 32.38826 0 0 0 + 988 303 13 -0.834 53.79071 58.98335 36.25336 -1 -2 -1 + 989 303 14 0.417 53.17711 58.26833 36.42220 -1 -2 -1 + 990 303 14 0.417 54.65389 58.60140 36.41235 -1 -2 -1 + 991 304 13 -0.834 50.47963 50.13918 42.58243 1 -1 -2 + 992 304 14 0.417 51.28111 49.63880 42.42915 1 -1 -2 + 993 304 14 0.417 50.33279 50.61369 41.76419 1 -1 -2 + 994 305 13 -0.834 50.28770 49.02182 56.79391 1 -1 -2 + 995 305 14 0.417 50.66164 48.14920 56.91622 1 -1 -2 + 996 305 14 0.417 50.60501 49.30063 55.93493 1 -1 -2 + 997 306 13 -0.834 41.36930 46.36343 34.87469 1 1 0 + 998 306 14 0.417 42.25704 46.59841 34.60463 1 1 0 + 999 306 14 0.417 40.85961 47.16333 34.74582 1 1 0 + 1000 307 13 -0.834 61.15349 47.47016 41.71779 0 1 0 + 1001 307 14 0.417 61.50139 48.29469 41.37818 0 1 0 + 1002 307 14 0.417 60.28203 47.69385 42.04454 0 1 0 + 1003 308 13 -0.834 58.35337 46.83622 34.81712 0 0 1 + 1004 308 14 0.417 57.63221 46.22391 34.67141 0 0 1 + 1005 308 14 0.417 57.97297 47.69883 34.65146 0 0 1 + 1006 309 13 -0.834 38.79812 57.92803 48.26323 1 -2 -1 + 1007 309 14 0.417 38.67444 56.98130 48.33141 1 -2 -1 + 1008 309 14 0.417 39.70990 58.06987 48.51776 1 -2 -1 + 1009 310 13 -0.834 42.15963 57.96891 45.03230 1 0 0 + 1010 310 14 0.417 42.11698 57.98663 45.98839 1 0 0 + 1011 310 14 0.417 41.83611 57.10021 44.79371 1 0 0 + 1012 311 13 -0.834 55.17551 54.72671 36.49400 0 -1 0 + 1013 311 14 0.417 55.26386 53.77738 36.57890 0 -1 0 + 1014 311 14 0.417 55.36463 55.06457 37.36939 0 -1 0 + 1015 312 13 -0.834 58.64573 63.28550 41.10609 -1 -2 -1 + 1016 312 14 0.417 58.98147 62.66636 41.75429 -1 -2 -1 + 1017 312 14 0.417 57.90273 62.83419 40.70545 -1 -2 -1 + 1018 313 13 -0.834 49.96498 59.98797 42.54359 0 -1 0 + 1019 313 14 0.417 50.57886 60.48612 42.00390 0 -1 0 + 1020 313 14 0.417 49.10600 60.17526 42.16501 0 -1 0 + 1021 314 13 -0.834 57.54750 44.35075 52.12722 -1 -1 -1 + 1022 314 14 0.417 57.86221 43.84739 51.37633 -1 -1 -1 + 1023 314 14 0.417 56.76423 44.79718 51.80558 -1 -1 -1 + 1024 315 13 -0.834 58.07892 59.46258 41.31930 1 -1 0 + 1025 315 14 0.417 58.27344 60.10968 41.99729 1 -1 0 + 1026 315 14 0.417 57.80524 59.98199 40.56328 1 -1 0 + 1027 316 13 -0.834 42.21869 44.49848 55.65511 2 1 0 + 1028 316 14 0.417 42.77458 44.78017 56.38166 2 1 0 + 1029 316 14 0.417 42.83052 44.15513 55.00395 2 1 0 + 1030 317 13 -0.834 56.38334 63.45614 43.52622 -1 -1 0 + 1031 317 14 0.417 55.66283 63.62998 42.92052 -1 -1 0 + 1032 317 14 0.417 56.48976 64.27319 44.01338 -1 -1 0 + 1033 318 13 -0.834 43.21354 46.04700 52.52965 1 1 0 + 1034 318 14 0.417 43.24360 45.09879 52.40226 1 1 0 + 1035 318 14 0.417 43.99839 46.37328 52.08943 1 1 0 + 1036 319 13 -0.834 55.96174 45.94863 35.39660 -1 0 1 + 1037 319 14 0.417 55.64687 46.44680 36.15088 -1 0 1 + 1038 319 14 0.417 55.28305 46.06527 34.73174 -1 0 1 + 1039 320 13 -0.834 47.36406 54.82690 34.84439 -1 -1 2 + 1040 320 14 0.417 47.90093 54.86776 34.05295 -1 -1 2 + 1041 320 14 0.417 47.23152 53.89118 34.99640 -1 -1 2 + 1042 321 13 -0.834 49.62685 50.00229 45.27362 1 0 -2 + 1043 321 14 0.417 49.70876 49.05477 45.38192 1 0 -2 + 1044 321 14 0.417 49.82566 50.15634 44.35005 1 0 -2 + 1045 322 13 -0.834 49.58249 46.02940 55.43310 -1 0 -2 + 1046 322 14 0.417 49.10378 46.80060 55.12924 -1 0 -2 + 1047 322 14 0.417 49.31802 45.92761 56.34739 -1 0 -2 + 1048 323 13 -0.834 51.72150 51.53491 51.55558 0 -1 -1 + 1049 323 14 0.417 51.50292 52.17946 50.88251 0 -1 -1 + 1050 323 14 0.417 52.14568 52.04382 52.24646 0 -1 -1 + 1051 324 13 -0.834 37.98107 56.66338 52.98024 0 1 0 + 1052 324 14 0.417 37.64467 57.53823 52.78607 0 1 0 + 1053 324 14 0.417 38.15999 56.27913 52.12200 0 1 0 + 1054 325 13 -0.834 59.20226 51.55233 53.16877 -1 1 0 + 1055 325 14 0.417 59.68851 51.88535 53.92302 -1 1 0 + 1056 325 14 0.417 58.63621 50.87031 53.53025 -1 1 0 + 1057 326 13 -0.834 45.75783 63.62117 39.24032 1 1 -1 + 1058 326 14 0.417 46.25179 64.38626 39.53508 1 1 -1 + 1059 326 14 0.417 44.85376 63.80686 39.49409 1 1 -1 + 1060 327 13 -0.834 58.00953 52.38584 37.67148 -1 1 1 + 1061 327 14 0.417 58.24242 51.47235 37.50553 -1 1 1 + 1062 327 14 0.417 57.26453 52.33853 38.27062 -1 1 1 + 1063 328 13 -0.834 50.62838 66.20855 42.36072 0 0 -1 + 1064 328 14 0.417 51.45434 66.68250 42.45770 0 0 -1 + 1065 328 14 0.417 49.99531 66.87945 42.10506 0 0 -1 + 1066 329 13 -0.834 53.69444 52.39171 45.41982 1 0 0 + 1067 329 14 0.417 53.84961 51.45739 45.55855 1 0 0 + 1068 329 14 0.417 52.75879 52.45359 45.22750 1 0 0 + 1069 330 13 -0.834 38.34038 60.92162 30.12773 2 0 0 + 1070 330 14 0.417 39.08908 61.47644 29.90887 2 0 0 + 1071 330 14 0.417 38.64185 60.39196 30.86585 2 0 0 + 1072 331 13 -0.834 48.03336 64.84935 43.13262 -1 0 -2 + 1073 331 14 0.417 48.90813 65.00919 43.48682 -1 0 -2 + 1074 331 14 0.417 47.46214 65.43367 43.63114 -1 0 -2 + 1075 332 13 -0.834 39.68760 66.88962 36.60665 2 0 0 + 1076 332 14 0.417 38.74743 66.72116 36.66944 2 0 0 + 1077 332 14 0.417 40.05009 66.08888 36.22764 2 0 0 + 1078 333 13 -0.834 51.94118 65.49897 51.83197 0 -1 -2 + 1079 333 14 0.417 52.71282 65.06165 51.47204 0 -1 -2 + 1080 333 14 0.417 51.22446 64.88225 51.68297 0 -1 -2 + 1081 334 13 -0.834 43.33066 57.53264 55.09930 -1 0 -2 + 1082 334 14 0.417 43.05496 56.76932 54.59178 -1 0 -2 + 1083 334 14 0.417 44.28179 57.55937 54.99503 -1 0 -2 + 1084 335 13 -0.834 47.70128 45.69178 52.17773 -1 3 -1 + 1085 335 14 0.417 47.54566 44.86273 52.63016 -1 3 -1 + 1086 335 14 0.417 48.58530 45.94693 52.44163 -1 3 -1 + 1087 336 13 -0.834 58.71603 41.81571 40.73899 -1 0 0 + 1088 336 14 0.417 57.77048 41.84330 40.88539 -1 0 0 + 1089 336 14 0.417 58.81275 41.43332 39.86682 -1 0 0 + 1090 337 13 -0.834 57.56034 60.98533 43.60766 0 -1 0 + 1091 337 14 0.417 56.67639 60.61816 43.59917 0 -1 0 + 1092 337 14 0.417 57.42830 61.92611 43.72486 0 -1 0 + 1093 338 13 -0.834 44.68088 65.08579 34.27880 -1 0 2 + 1094 338 14 0.417 45.54678 65.09564 34.68668 -1 0 2 + 1095 338 14 0.417 44.45037 64.15818 34.22739 -1 0 2 + 1096 339 13 -0.834 54.98236 48.04093 42.26075 0 0 0 + 1097 339 14 0.417 55.16505 47.86552 43.18384 0 0 0 + 1098 339 14 0.417 55.70493 48.59999 41.97513 0 0 0 + 1099 340 13 -0.834 60.57099 56.88773 56.53671 0 0 1 + 1100 340 14 0.417 60.67151 56.21616 29.83998 0 0 2 + 1101 340 14 0.417 61.34465 56.78824 55.98192 0 0 1 + 1102 341 13 -0.834 48.05045 49.69974 47.93542 -1 0 0 + 1103 341 14 0.417 48.70922 49.23613 48.45249 -1 0 0 + 1104 341 14 0.417 48.26410 49.48583 47.02721 -1 0 0 + 1105 342 13 -0.834 40.63207 55.77589 49.21695 1 0 -1 + 1106 342 14 0.417 40.84917 56.26844 50.00847 1 0 -1 + 1107 342 14 0.417 41.40772 55.85904 48.66226 1 0 -1 + 1108 343 13 -0.834 61.66015 42.71355 39.91223 0 0 0 + 1109 343 14 0.417 61.87748 41.86774 40.30419 0 0 0 + 1110 343 14 0.417 61.98864 42.65380 39.01514 0 0 0 + 1111 344 13 -0.834 38.52157 65.12766 57.04010 0 -1 -1 + 1112 344 14 0.417 38.04157 64.32142 56.85084 0 -1 -1 + 1113 344 14 0.417 39.36310 65.01535 56.59799 0 -1 -1 + 1114 345 13 -0.834 54.26556 44.72348 38.61852 -1 0 0 + 1115 345 14 0.417 54.65781 45.53245 38.94708 -1 0 0 + 1116 345 14 0.417 54.97105 44.29396 38.13473 -1 0 0 + 1117 346 13 -0.834 55.38993 55.61246 43.96322 -1 0 1 + 1118 346 14 0.417 54.74535 54.99107 43.62461 -1 0 1 + 1119 346 14 0.417 55.11835 55.77119 44.86726 -1 0 1 + 1120 347 13 -0.834 56.42023 55.00369 50.06211 -1 -1 0 + 1121 347 14 0.417 55.77599 55.59187 50.45611 -1 -1 0 + 1122 347 14 0.417 56.93756 54.68448 50.80151 -1 -1 0 + 1123 348 13 -0.834 45.79495 66.88952 36.56670 1 1 -1 + 1124 348 14 0.417 45.28578 66.71904 35.77429 1 1 -1 + 1125 348 14 0.417 46.57709 67.34552 36.25591 1 1 -1 + 1126 349 13 -0.834 62.75278 45.54084 32.23733 0 0 0 + 1127 349 14 0.417 62.61586 44.79986 31.64705 0 0 0 + 1128 349 14 0.417 62.96974 45.14017 33.07913 0 0 0 + 1129 350 13 -0.834 57.50625 65.62986 39.74454 0 0 0 + 1130 350 14 0.417 57.73342 64.85584 40.25983 0 0 0 + 1131 350 14 0.417 57.07082 66.21286 40.36642 0 0 0 + 1132 351 13 -0.834 55.96293 62.10636 50.17062 0 1 -1 + 1133 351 14 0.417 56.24333 61.70901 50.99507 0 1 -1 + 1134 351 14 0.417 56.67888 62.69531 49.93234 0 1 -1 + 1135 352 13 -0.834 37.45010 41.11856 53.00894 0 0 0 + 1136 352 14 0.417 37.99062 41.49514 53.70339 0 0 0 + 1137 352 14 0.417 37.83337 41.45341 52.19826 0 0 0 + 1138 353 13 -0.834 40.59344 47.85232 38.52244 1 0 1 + 1139 353 14 0.417 41.31256 47.71502 37.90580 1 0 1 + 1140 353 14 0.417 40.21612 48.69426 38.26747 1 0 1 + 1141 354 13 -0.834 60.77214 62.31711 30.33695 0 2 -1 + 1142 354 14 0.417 59.83662 62.43212 30.17023 0 2 -1 + 1143 354 14 0.417 60.97856 61.45964 29.96496 0 2 -1 + 1144 355 13 -0.834 47.83829 64.26042 48.43592 0 1 -1 + 1145 355 14 0.417 47.12209 64.85952 48.22523 0 1 -1 + 1146 355 14 0.417 47.44823 63.38856 48.37295 0 1 -1 + 1147 356 13 -0.834 38.69679 45.31108 42.13672 1 1 0 + 1148 356 14 0.417 39.20464 45.52138 41.35308 1 1 0 + 1149 356 14 0.417 37.90440 44.89009 41.80335 1 1 0 + 1150 357 13 -0.834 38.90832 47.67164 52.69089 0 1 0 + 1151 357 14 0.417 39.51269 48.14149 53.26554 0 1 0 + 1152 357 14 0.417 38.42834 48.36117 52.23218 0 1 0 + 1153 358 13 -0.834 45.13879 48.98199 29.96256 0 2 1 + 1154 358 14 0.417 44.63649 48.48457 30.60794 0 2 1 + 1155 358 14 0.417 44.70163 48.80464 56.50106 0 2 0 + 1156 359 13 -0.834 54.78460 57.58368 54.24956 1 1 -1 + 1157 359 14 0.417 54.71436 57.34891 55.17486 1 1 -1 + 1158 359 14 0.417 55.60599 58.07122 54.18735 1 1 -1 + 1159 360 13 -0.834 40.77006 67.09387 46.34204 0 0 1 + 1160 360 14 0.417 40.91087 66.51539 47.09156 0 0 1 + 1161 360 14 0.417 41.47386 67.73986 46.40192 0 0 1 + 1162 361 13 -0.834 53.75960 49.21723 54.03526 1 0 -1 + 1163 361 14 0.417 54.17778 50.07537 53.96484 1 0 -1 + 1164 361 14 0.417 54.18187 48.68822 53.35846 1 0 -1 + 1165 362 13 -0.834 46.41755 62.84035 30.52059 0 0 1 + 1166 362 14 0.417 46.37357 61.90548 30.72136 0 0 1 + 1167 362 14 0.417 46.76359 62.87829 57.00030 0 0 0 + 1168 363 13 -0.834 51.27491 42.28113 30.83818 0 -1 0 + 1169 363 14 0.417 51.18814 42.11416 31.77671 0 -1 0 + 1170 363 14 0.417 50.41560 42.60836 30.57220 0 -1 0 + 1171 364 13 -0.834 52.36258 42.54738 46.83477 0 -1 -1 + 1172 364 14 0.417 51.62853 42.02025 46.51928 0 -1 -1 + 1173 364 14 0.417 53.11771 42.22680 46.34158 0 -1 -1 + 1174 365 13 -0.834 40.11442 46.69570 48.71466 3 -2 1 + 1175 365 14 0.417 39.89820 47.61495 48.55824 3 -2 1 + 1176 365 14 0.417 40.87520 46.72352 49.29493 3 -2 1 + 1177 366 13 -0.834 56.56957 65.78976 45.32589 0 -2 -1 + 1178 366 14 0.417 56.86196 65.56407 46.20896 0 -2 -1 + 1179 366 14 0.417 57.34222 66.16870 44.90678 0 -2 -1 + 1180 367 13 -0.834 38.37373 47.63723 43.98242 2 0 0 + 1181 367 14 0.417 38.78516 47.21384 44.73589 2 0 0 + 1182 367 14 0.417 38.73588 47.18051 43.22315 2 0 0 + 1183 368 13 -0.834 45.69445 49.36872 40.50736 -1 0 -2 + 1184 368 14 0.417 44.73771 49.39892 40.51002 -1 0 -2 + 1185 368 14 0.417 45.90701 48.47357 40.77155 -1 0 -2 + 1186 369 13 -0.834 53.93830 54.76570 31.99728 0 -1 0 + 1187 369 14 0.417 53.94849 55.50033 32.61083 0 -1 0 + 1188 369 14 0.417 53.13070 54.29402 32.20107 0 -1 0 + 1189 370 13 -0.834 58.79125 64.07093 37.97498 -1 -1 -2 + 1190 370 14 0.417 58.48296 64.72380 38.60343 -1 -1 -2 + 1191 370 14 0.417 58.20942 64.16977 37.22136 -1 -1 -2 + 1192 371 13 -0.834 51.76123 61.42281 40.82794 0 -1 0 + 1193 371 14 0.417 52.69114 61.24136 40.69160 0 -1 0 + 1194 371 14 0.417 51.74755 62.21395 41.36660 0 -1 0 + 1195 372 13 -0.834 44.28377 63.70509 53.71234 -1 -2 -1 + 1196 372 14 0.417 44.98211 64.35001 53.59994 -1 -2 -1 + 1197 372 14 0.417 43.75271 63.78587 52.92008 -1 -2 -1 + 1198 373 13 -0.834 61.50835 48.76378 34.91047 0 0 -1 + 1199 373 14 0.417 61.23254 49.09753 34.05678 0 0 -1 + 1200 373 14 0.417 61.51672 49.53447 35.47812 0 0 -1 + 1201 374 13 -0.834 61.51337 41.63477 44.26291 -1 -1 0 + 1202 374 14 0.417 62.42662 41.58544 44.54543 -1 -1 0 + 1203 374 14 0.417 61.34749 68.16405 43.83907 -1 -2 0 + 1204 375 13 -0.834 57.73267 43.39213 33.64792 0 -1 0 + 1205 375 14 0.417 58.46456 43.28438 34.25535 0 -1 0 + 1206 375 14 0.417 58.09278 43.15396 32.79362 0 -1 0 + 1207 376 13 -0.834 63.51473 49.31549 51.59705 -1 1 -1 + 1208 376 14 0.417 63.13045 49.03534 50.76631 -1 1 -1 + 1209 376 14 0.417 62.84038 49.86142 52.00137 -1 1 -1 + 1210 377 13 -0.834 58.21462 44.79010 54.73553 -1 -1 -1 + 1211 377 14 0.417 58.08068 43.94884 55.17209 -1 -1 -1 + 1212 377 14 0.417 57.81645 44.67856 53.87224 -1 -1 -1 + 1213 378 13 -0.834 57.08090 55.14561 52.86183 0 -2 1 + 1214 378 14 0.417 57.05215 55.46811 53.76261 0 -2 1 + 1215 378 14 0.417 57.69965 54.41575 52.88786 0 -2 1 + 1216 379 13 -0.834 60.83502 54.45436 45.82182 1 0 -1 + 1217 379 14 0.417 61.05342 55.38616 45.83857 1 0 -1 + 1218 379 14 0.417 60.79443 54.20077 46.74392 1 0 -1 + 1219 380 13 -0.834 60.86442 48.23162 37.95658 0 0 2 + 1220 380 14 0.417 61.77710 48.43881 37.75572 0 0 2 + 1221 380 14 0.417 60.87611 47.30540 38.19788 0 0 2 + 1222 381 13 -0.834 43.21478 43.26953 44.97859 2 1 -1 + 1223 381 14 0.417 42.50778 42.78849 44.54850 2 1 -1 + 1224 381 14 0.417 43.42173 42.74895 45.75474 2 1 -1 + 1225 382 13 -0.834 39.01904 49.57571 48.28198 1 -1 -1 + 1226 382 14 0.417 38.68877 49.32064 47.42052 1 -1 -1 + 1227 382 14 0.417 38.42357 50.26661 48.57234 1 -1 -1 + 1228 383 13 -0.834 47.20253 45.34580 30.26781 0 0 1 + 1229 383 14 0.417 47.05738 44.40526 30.16508 0 0 1 + 1230 383 14 0.417 46.80592 45.73631 56.86044 0 0 0 + 1231 384 13 -0.834 44.57742 55.88746 33.53830 0 -1 0 + 1232 384 14 0.417 45.13093 56.49768 33.05096 0 -1 0 + 1233 384 14 0.417 44.41092 55.17196 32.92464 0 -1 0 + 1234 385 13 -0.834 42.17091 64.36626 51.74369 1 0 0 + 1235 385 14 0.417 41.78583 65.24128 51.69570 1 0 0 + 1236 385 14 0.417 41.41926 63.77568 51.79343 1 0 0 + 1237 386 13 -0.834 43.82615 43.47821 52.97551 0 0 0 + 1238 386 14 0.417 43.64099 42.56407 52.76025 0 0 0 + 1239 386 14 0.417 44.58924 43.43914 53.55207 0 0 0 + 1240 387 13 -0.834 63.58286 63.91035 38.47173 0 -1 -1 + 1241 387 14 0.417 64.14591 63.71296 39.22023 0 -1 -1 + 1242 387 14 0.417 62.70901 64.01191 38.84896 0 -1 -1 + 1243 388 13 -0.834 57.85225 42.19019 46.82252 1 1 -2 + 1244 388 14 0.417 57.61712 42.29475 47.74450 1 1 -2 + 1245 388 14 0.417 57.29406 42.81537 46.36013 1 1 -2 + 1246 389 13 -0.834 57.90802 64.30101 52.26362 1 0 1 + 1247 389 14 0.417 58.43907 64.81717 52.87010 1 0 1 + 1248 389 14 0.417 58.54387 63.78888 51.76396 1 0 1 + 1249 390 13 -0.834 53.18379 66.68791 54.05156 1 -2 0 + 1250 390 14 0.417 52.23394 66.79510 54.00115 1 -2 0 + 1251 390 14 0.417 53.33447 65.77140 53.82015 1 -2 0 + 1252 391 13 -0.834 56.95394 68.26036 36.42711 -1 1 1 + 1253 391 14 0.417 56.91362 41.83232 36.58445 -1 2 1 + 1254 391 14 0.417 57.79173 67.98998 36.80292 -1 1 1 + 1255 392 13 -0.834 64.19252 44.20158 54.88143 0 0 0 + 1256 392 14 0.417 64.09322 45.07899 54.51194 0 0 0 + 1257 392 14 0.417 63.39239 43.74201 54.62684 0 0 0 + 1258 393 13 -0.834 63.10536 65.42626 48.53464 0 0 0 + 1259 393 14 0.417 62.79665 64.63036 48.10166 0 0 0 + 1260 393 14 0.417 62.77768 65.35429 49.43112 0 0 0 + 1261 394 13 -0.834 49.28836 66.20367 32.27628 1 -1 0 + 1262 394 14 0.417 49.46858 65.88738 33.16155 1 -1 0 + 1263 394 14 0.417 49.29197 65.41476 31.73420 1 -1 0 + 1264 395 13 -0.834 46.11216 66.09570 44.77896 0 -1 0 + 1265 395 14 0.417 45.90309 66.07762 45.71287 0 -1 0 + 1266 395 14 0.417 45.36137 65.67813 44.35683 0 -1 0 + 1267 396 13 -0.834 41.43943 50.30026 52.32584 1 0 0 + 1268 396 14 0.417 41.39866 49.93140 51.44351 1 0 0 + 1269 396 14 0.417 40.92759 49.69528 52.86275 1 0 0 + 1270 397 13 -0.834 54.69177 57.80859 32.50623 0 -1 -1 + 1271 397 14 0.417 53.99890 57.66594 31.86139 0 -1 -1 + 1272 397 14 0.417 54.37599 57.37325 33.29806 0 -1 -1 + 1273 398 13 -0.834 43.56781 46.79065 37.17838 0 1 0 + 1274 398 14 0.417 43.18325 46.24795 36.49004 0 1 0 + 1275 398 14 0.417 44.03819 46.17194 37.73711 0 1 0 + 1276 399 13 -0.834 55.33436 45.90772 50.69068 -1 0 0 + 1277 399 14 0.417 55.55455 46.77982 51.01809 -1 0 0 + 1278 399 14 0.417 55.09425 46.04877 49.77488 -1 0 0 + 1279 400 13 -0.834 56.15383 51.87018 43.92178 -1 0 1 + 1280 400 14 0.417 55.25073 52.12373 44.11256 -1 0 1 + 1281 400 14 0.417 56.65027 52.68628 43.98319 -1 0 1 + 1282 401 13 -0.834 62.38946 50.01240 45.94802 0 1 -2 + 1283 401 14 0.417 62.43815 50.07607 44.99418 0 1 -2 + 1284 401 14 0.417 61.47369 50.19932 46.15457 0 1 -2 + 1285 402 13 -0.834 53.60920 58.35575 46.37412 0 0 1 + 1286 402 14 0.417 53.25556 59.03071 45.79481 0 0 1 + 1287 402 14 0.417 53.24753 57.53627 46.03666 0 0 1 + 1288 403 13 -0.834 43.13375 42.07203 50.04429 1 0 0 + 1289 403 14 0.417 43.76099 42.76922 49.85267 1 0 0 + 1290 403 14 0.417 42.35437 42.53016 50.35879 1 0 0 + 1291 404 13 -0.834 47.41498 59.41146 52.77687 -1 -1 0 + 1292 404 14 0.417 47.81303 59.83868 53.53534 -1 -1 0 + 1293 404 14 0.417 48.01011 59.60512 52.05261 -1 -1 0 + 1294 405 13 -0.834 63.75607 47.28104 38.80571 0 2 -1 + 1295 405 14 0.417 63.78573 48.20840 38.57042 0 2 -1 + 1296 405 14 0.417 37.08655 47.17376 39.44769 1 2 -1 + 1297 406 13 -0.834 46.67594 56.20863 44.42866 1 1 0 + 1298 406 14 0.417 45.82140 56.15280 44.00100 1 1 0 + 1299 406 14 0.417 46.48292 56.12468 45.36243 1 1 0 + 1300 407 13 -0.834 62.54251 68.21194 54.20445 0 -1 1 + 1301 407 14 0.417 63.31640 41.15490 53.73696 0 0 1 + 1302 407 14 0.417 62.78865 67.34176 54.51819 0 -1 1 + 1303 408 13 -0.834 60.27010 54.96049 39.87633 0 0 0 + 1304 408 14 0.417 59.62959 55.67175 39.88547 0 0 0 + 1305 408 14 0.417 61.04761 55.33233 40.29281 0 0 0 + 1306 409 13 -0.834 40.02595 44.30132 44.29580 0 -2 0 + 1307 409 14 0.417 39.70595 44.75009 45.07839 0 -2 0 + 1308 409 14 0.417 39.56836 44.72725 43.57092 0 -2 0 + 1309 410 13 -0.834 54.20011 41.08252 35.61017 0 1 0 + 1310 410 14 0.417 55.10396 68.23613 35.83794 0 0 0 + 1311 410 14 0.417 54.27044 41.57221 34.79072 0 1 0 + 1312 411 13 -0.834 60.64478 45.93023 50.84376 1 1 -1 + 1313 411 14 0.417 60.80088 46.54647 51.55941 1 1 -1 + 1314 411 14 0.417 61.20574 46.24077 50.13303 1 1 -1 + 1315 412 13 -0.834 44.55137 44.47403 38.16771 1 0 -1 + 1316 412 14 0.417 45.28189 43.86333 38.26597 1 0 -1 + 1317 412 14 0.417 43.77025 43.93754 38.30281 1 0 -1 + 1318 413 13 -0.834 58.08933 62.76987 30.45191 1 -1 0 + 1319 413 14 0.417 57.64138 63.31997 29.80927 1 -1 0 + 1320 413 14 0.417 57.43674 62.11708 30.70545 1 -1 0 + 1321 414 13 -0.834 55.65273 56.71117 38.74877 1 0 1 + 1322 414 14 0.417 56.53260 56.59636 39.10779 1 0 1 + 1323 414 14 0.417 55.14964 55.98047 39.10825 1 0 1 + 1324 415 13 -0.834 55.50009 51.16952 38.77962 0 0 0 + 1325 415 14 0.417 54.95350 51.23711 37.99672 0 0 0 + 1326 415 14 0.417 55.53220 50.23190 38.96963 0 0 0 + 1327 416 13 -0.834 47.64702 52.79911 31.71446 0 -1 0 + 1328 416 14 0.417 48.52504 53.09556 31.47481 0 -1 0 + 1329 416 14 0.417 47.06032 53.44853 31.32681 0 -1 0 + 1330 417 13 -0.834 49.26727 42.35880 39.18566 1 1 -2 + 1331 417 14 0.417 50.02784 42.93912 39.15429 1 1 -2 + 1332 417 14 0.417 49.46495 41.74196 39.89040 1 1 -2 + 1333 418 13 -0.834 47.22542 64.65021 35.82232 1 -1 0 + 1334 418 14 0.417 46.76114 65.20346 36.45050 1 -1 0 + 1335 418 14 0.417 47.98585 65.16966 35.56120 1 -1 0 + 1336 419 13 -0.834 58.53686 56.85468 40.78587 1 1 0 + 1337 419 14 0.417 58.45283 56.63469 41.71365 1 1 0 + 1338 419 14 0.417 58.36285 57.79507 40.74550 1 1 0 + 1339 420 13 -0.834 50.09436 46.17981 48.16619 -1 -1 -2 + 1340 420 14 0.417 50.67249 45.42897 48.30138 -1 -1 -2 + 1341 420 14 0.417 50.49629 46.88624 48.67183 -1 -1 -2 + 1342 421 13 -0.834 42.30297 57.95379 33.48633 0 -1 1 + 1343 421 14 0.417 41.56921 57.39445 33.23136 0 -1 1 + 1344 421 14 0.417 43.00718 57.34235 33.70193 0 -1 1 + 1345 422 13 -0.834 45.76518 43.79811 54.82490 0 -1 0 + 1346 422 14 0.417 46.45133 43.55343 54.20397 0 -1 0 + 1347 422 14 0.417 45.87205 43.18693 55.55379 0 -1 0 + 1348 423 13 -0.834 59.33326 61.34125 37.96927 -1 -1 1 + 1349 423 14 0.417 59.29007 62.29004 38.08827 -1 -1 1 + 1350 423 14 0.417 59.90006 61.03609 38.67769 -1 -1 1 + 1351 424 13 -0.834 40.95662 63.48104 42.72192 1 -1 0 + 1352 424 14 0.417 40.33618 63.69074 42.02383 1 -1 0 + 1353 424 14 0.417 41.73946 63.17568 42.26346 1 -1 0 + 1354 425 13 -0.834 38.13662 59.25720 46.08402 1 -1 -1 + 1355 425 14 0.417 38.31499 59.03616 46.99811 1 -1 -1 + 1356 425 14 0.417 38.55502 58.55783 45.58196 1 -1 -1 + 1357 426 13 -0.834 48.88681 66.85051 54.82298 1 -2 0 + 1358 426 14 0.417 49.16879 67.45078 54.13275 1 -2 0 + 1359 426 14 0.417 49.42353 66.06836 54.69484 1 -2 0 + 1360 427 13 -0.834 45.88049 57.05477 48.46508 0 0 -1 + 1361 427 14 0.417 45.73709 57.90911 48.05793 0 0 -1 + 1362 427 14 0.417 45.83791 57.22701 49.40569 0 0 -1 + 1363 428 13 -0.834 39.37333 50.31613 37.93447 0 1 0 + 1364 428 14 0.417 39.11456 50.97624 37.29140 0 1 0 + 1365 428 14 0.417 38.97424 50.60960 38.75352 0 1 0 + 1366 429 13 -0.834 37.89753 62.82745 47.39297 0 -1 0 + 1367 429 14 0.417 38.39122 62.78202 46.57414 0 -1 0 + 1368 429 14 0.417 37.01605 63.08963 47.12747 0 -1 0 + 1369 430 13 -0.834 43.16514 41.31420 47.01379 0 1 0 + 1370 430 14 0.417 42.71409 41.22965 47.85382 0 1 0 + 1371 430 14 0.417 44.05112 68.36565 47.18386 0 0 0 + 1372 431 13 -0.834 47.03179 42.44477 42.46475 1 0 0 + 1373 431 14 0.417 46.12350 42.65285 42.24573 1 0 0 + 1374 431 14 0.417 47.53228 43.19970 42.15516 1 0 0 + 1375 432 13 -0.834 55.35894 54.15040 46.85340 0 -1 0 + 1376 432 14 0.417 54.76544 53.43667 46.61975 0 -1 0 + 1377 432 14 0.417 56.17133 53.71318 47.10853 0 -1 0 + 1378 433 13 -0.834 47.00663 55.28313 38.22800 -1 -2 1 + 1379 433 14 0.417 46.53490 56.00706 38.63987 -1 -2 1 + 1380 433 14 0.417 47.07459 54.61953 38.91449 -1 -2 1 + 1381 434 13 -0.834 57.16336 58.62297 32.33349 -1 0 2 + 1382 434 14 0.417 57.63330 57.80350 32.48798 -1 0 2 + 1383 434 14 0.417 56.24209 58.36680 32.29014 -1 0 2 + 1384 435 13 -0.834 37.23245 47.62479 56.34765 0 1 -1 + 1385 435 14 0.417 37.24274 47.21497 55.48268 0 1 -1 + 1386 435 14 0.417 37.36000 46.89905 56.95860 0 1 -1 + 1387 436 13 -0.834 48.77030 41.06015 29.86683 2 1 0 + 1388 436 14 0.417 48.81141 67.97117 56.39997 2 0 -1 + 1389 436 14 0.417 49.05230 67.78232 30.51123 2 0 0 + 1390 437 13 -0.834 49.10149 56.15638 36.66346 0 0 1 + 1391 437 14 0.417 48.50786 55.61659 36.14146 0 0 1 + 1392 437 14 0.417 48.61812 56.33305 37.47053 0 0 1 + 1393 438 13 -0.834 58.15731 59.39698 29.96092 0 -1 1 + 1394 438 14 0.417 58.20240 59.10993 30.87296 0 -1 1 + 1395 438 14 0.417 57.30076 59.81721 29.88367 0 -1 1 + 1396 439 13 -0.834 59.37068 41.03089 37.87324 1 0 0 + 1397 439 14 0.417 59.56889 41.95335 37.71194 1 0 0 + 1398 439 14 0.417 60.22643 67.97433 37.90167 1 -1 0 + 1399 440 13 -0.834 38.32241 55.03397 50.58952 1 0 0 + 1400 440 14 0.417 38.22793 54.19584 50.13692 1 0 0 + 1401 440 14 0.417 39.21785 55.31153 50.39614 1 0 0 + 1402 441 13 -0.834 36.94673 59.01778 33.00159 1 -1 2 + 1403 441 14 0.417 36.95260 59.97305 32.94091 1 -1 2 + 1404 441 14 0.417 63.71798 58.82680 33.72245 0 -1 2 + 1405 442 13 -0.834 62.50746 54.84239 54.03343 0 -1 0 + 1406 442 14 0.417 61.69710 54.35984 54.19681 0 -1 0 + 1407 442 14 0.417 63.09119 54.20097 53.62833 0 -1 0 + 1408 443 13 -0.834 40.59690 62.80012 38.69405 1 -1 1 + 1409 443 14 0.417 41.53881 62.90970 38.82458 1 -1 1 + 1410 443 14 0.417 40.36980 62.03187 39.21794 1 -1 1 + 1411 444 13 -0.834 37.67477 67.71471 42.59127 0 -1 -1 + 1412 444 14 0.417 38.12213 68.13627 41.85751 0 -1 -1 + 1413 444 14 0.417 38.28279 67.03643 42.88534 0 -1 -1 + 1414 445 13 -0.834 42.73681 50.65782 33.30839 1 1 0 + 1415 445 14 0.417 42.84587 51.15085 34.12157 1 1 0 + 1416 445 14 0.417 42.32631 51.27747 32.70527 1 1 0 + 1417 446 13 -0.834 37.13349 57.05842 55.81927 0 0 0 + 1418 446 14 0.417 37.95375 57.53453 55.68979 0 0 0 + 1419 446 14 0.417 36.99014 56.59807 54.99236 0 0 0 + 1420 447 13 -0.834 61.08039 63.50929 36.52096 -1 0 0 + 1421 447 14 0.417 60.44389 63.87414 37.13579 -1 0 0 + 1422 447 14 0.417 61.70642 63.04107 37.07331 -1 0 0 + 1423 448 13 -0.834 57.12289 46.04019 38.75954 0 0 0 + 1424 448 14 0.417 56.81351 45.55997 39.52760 0 0 0 + 1425 448 14 0.417 57.99543 45.68504 38.58988 0 0 0 + 1426 449 13 -0.834 45.45003 49.45347 49.54397 0 0 -1 + 1427 449 14 0.417 45.96611 49.34591 48.74502 0 0 -1 + 1428 449 14 0.417 46.09930 49.60861 50.22999 0 0 -1 + 1429 450 13 -0.834 37.77009 64.51990 42.66941 1 0 0 + 1430 450 14 0.417 38.49339 64.80040 43.23011 1 0 0 + 1431 450 14 0.417 38.14071 64.50928 41.78694 1 0 0 + 1432 451 13 -0.834 45.78323 57.65378 39.37062 1 0 0 + 1433 451 14 0.417 46.03758 58.03295 40.21190 1 0 0 + 1434 451 14 0.417 44.96217 58.09258 39.14803 1 0 0 + 1435 452 13 -0.834 56.96672 60.41636 47.59314 0 -1 1 + 1436 452 14 0.417 56.18373 60.11455 48.05365 0 -1 1 + 1437 452 14 0.417 56.65889 61.13663 47.04297 0 -1 1 + 1438 453 13 -0.834 52.44356 65.82746 35.82081 -1 -1 0 + 1439 453 14 0.417 53.10567 65.14225 35.91211 -1 -1 0 + 1440 453 14 0.417 52.93741 66.64611 35.86748 -1 -1 0 + 1441 454 13 -0.834 50.70912 51.42252 40.30021 0 0 -1 + 1442 454 14 0.417 50.97387 50.70177 39.72866 0 0 -1 + 1443 454 14 0.417 50.17774 51.98938 39.74116 0 0 -1 + 1444 455 13 -0.834 39.22290 45.94023 39.69239 2 1 -1 + 1445 455 14 0.417 39.63836 46.66722 39.22859 2 1 -1 + 1446 455 14 0.417 38.97218 45.32685 39.00164 2 1 -1 + 1447 456 13 -0.834 43.73041 61.86387 55.46954 2 0 0 + 1448 456 14 0.417 43.61274 62.32163 56.30192 2 0 0 + 1449 456 14 0.417 43.90401 62.55964 54.83549 2 0 0 + 1450 457 13 -0.834 61.51877 56.42039 33.84869 0 0 1 + 1451 457 14 0.417 62.17805 55.74211 33.70200 0 0 1 + 1452 457 14 0.417 62.00943 57.15723 34.21276 0 0 1 + 1453 458 13 -0.834 51.72050 63.63199 42.34406 1 0 1 + 1454 458 14 0.417 51.24482 64.43296 42.56407 1 0 1 + 1455 458 14 0.417 52.62118 63.92057 42.19669 1 0 1 + 1456 459 13 -0.834 54.73666 56.51839 51.73687 0 0 -1 + 1457 459 14 0.417 54.77503 56.56844 52.69200 0 0 -1 + 1458 459 14 0.417 54.91702 57.41111 51.44234 0 0 -1 + 1459 460 13 -0.834 50.97984 54.35591 33.27919 0 1 0 + 1460 460 14 0.417 50.47200 55.12727 33.02747 0 1 0 + 1461 460 14 0.417 50.36917 53.82187 33.78725 0 1 0 + 1462 461 13 -0.834 44.82656 54.45280 36.09973 1 0 2 + 1463 461 14 0.417 45.75766 54.23599 36.14740 1 0 2 + 1464 461 14 0.417 44.76968 55.11700 35.41283 1 0 2 + 1465 462 13 -0.834 58.05791 56.64716 55.29041 1 1 0 + 1466 462 14 0.417 58.98499 56.81997 55.45441 1 1 0 + 1467 462 14 0.417 57.82639 55.96338 55.91897 1 1 0 + 1468 463 13 -0.834 55.95112 61.02029 30.79757 1 0 1 + 1469 463 14 0.417 55.28483 61.63344 30.48711 1 0 1 + 1470 463 14 0.417 55.45357 60.27206 31.12748 1 0 1 + 1471 464 13 -0.834 54.80996 46.88659 45.41700 -1 0 0 + 1472 464 14 0.417 55.42348 46.16300 45.28950 -1 0 0 + 1473 464 14 0.417 54.08129 46.68997 44.82826 -1 0 0 + 1474 465 13 -0.834 60.19361 64.43268 31.92053 0 -1 2 + 1475 465 14 0.417 60.05792 63.85315 32.67017 0 -1 2 + 1476 465 14 0.417 60.47170 63.84993 31.21392 0 -1 2 + 1477 466 13 -0.834 45.55496 65.56032 30.88251 0 -1 1 + 1478 466 14 0.417 45.97644 64.70102 30.89691 0 -1 1 + 1479 466 14 0.417 45.82502 65.97384 31.70248 0 -1 1 + 1480 467 13 -0.834 52.92714 44.06759 29.88429 0 1 0 + 1481 467 14 0.417 52.39641 43.38446 30.29405 0 1 0 + 1482 467 14 0.417 53.79372 43.96686 30.27818 0 1 0 + 1483 468 13 -0.834 40.71534 55.31247 44.93070 1 0 0 + 1484 468 14 0.417 39.81994 55.07165 45.16841 1 0 0 + 1485 468 14 0.417 41.16802 54.47609 44.82218 1 0 0 + 1486 469 13 -0.834 64.04777 59.80626 42.91634 0 -1 -1 + 1487 469 14 0.417 37.09051 60.51146 43.41377 1 -1 -1 + 1488 469 14 0.417 37.01609 59.00291 43.31068 1 -1 -1 + 1489 470 13 -0.834 57.05030 49.72625 41.88829 -1 1 1 + 1490 470 14 0.417 56.75150 50.53290 42.30818 -1 1 1 + 1491 470 14 0.417 57.52176 50.02159 41.10935 -1 1 1 + 1492 471 13 -0.834 62.59447 67.67898 41.14714 -2 -2 1 + 1493 471 14 0.417 63.45155 67.57764 41.56112 -2 -2 1 + 1494 471 14 0.417 61.96974 67.40478 41.81854 -2 -2 1 + 1495 472 13 -0.834 62.98029 58.34420 35.34278 0 0 1 + 1496 472 14 0.417 62.45371 58.26151 36.13783 0 0 1 + 1497 472 14 0.417 63.83636 58.64077 35.65169 0 0 1 + 1498 473 13 -0.834 63.44584 56.74146 44.14484 0 1 -2 + 1499 473 14 0.417 64.13590 56.53036 44.77371 0 1 -2 + 1500 473 14 0.417 62.70665 57.02149 44.68470 0 1 -2 + 1501 474 13 -0.834 44.05905 56.56929 51.60681 1 0 -1 + 1502 474 14 0.417 43.57850 56.15764 52.32504 1 0 -1 + 1503 474 14 0.417 43.90344 55.99747 50.85512 1 0 -1 + 1504 475 13 -0.834 37.49588 59.31379 39.05252 0 0 0 + 1505 475 14 0.417 37.07904 58.45297 39.09112 0 0 0 + 1506 475 14 0.417 37.58867 59.49374 38.11696 0 0 0 + 1507 476 13 -0.834 54.75747 41.52122 56.48609 -1 1 0 + 1508 476 14 0.417 54.79987 42.39714 56.86981 -1 1 0 + 1509 476 14 0.417 54.80582 41.67034 55.54179 -1 1 0 + 1510 477 13 -0.834 42.91665 58.39379 47.91495 1 0 0 + 1511 477 14 0.417 43.70923 58.91951 47.80683 1 0 0 + 1512 477 14 0.417 42.28811 58.98861 48.32409 1 0 0 + 1513 478 13 -0.834 60.63731 64.78822 56.03697 -2 1 -1 + 1514 478 14 0.417 60.86485 63.91302 56.35082 -2 1 -1 + 1515 478 14 0.417 60.50973 65.30321 56.83369 -2 1 -1 + 1516 479 13 -0.834 52.85180 54.69512 43.09842 0 0 1 + 1517 479 14 0.417 52.31485 55.13373 42.43846 0 0 1 + 1518 479 14 0.417 53.08000 53.85428 42.70200 0 0 1 + 1519 480 13 -0.834 51.49497 54.97356 38.95012 -2 1 -1 + 1520 480 14 0.417 50.77717 54.34090 38.97811 -2 1 -1 + 1521 480 14 0.417 51.51597 55.35169 39.82923 -2 1 -1 + 1522 481 13 -0.834 40.46924 62.02458 56.36341 1 0 -1 + 1523 481 14 0.417 40.45814 61.65439 55.48076 1 0 -1 + 1524 481 14 0.417 40.81799 62.90856 56.24853 1 0 -1 + 1525 482 13 -0.834 52.26692 56.29032 45.24820 0 2 1 + 1526 482 14 0.417 51.65227 56.79794 44.71834 0 2 1 + 1527 482 14 0.417 52.43092 55.49973 44.73408 0 2 1 + 1528 483 13 -0.834 53.46372 44.63556 52.39623 -1 1 1 + 1529 483 14 0.417 53.51664 45.03502 53.26448 -1 1 1 + 1530 483 14 0.417 54.08491 45.13343 51.86474 -1 1 1 + 1531 484 13 -0.834 42.90202 49.87822 40.32919 0 2 1 + 1532 484 14 0.417 42.40392 49.63281 41.10889 0 2 1 + 1533 484 14 0.417 42.31302 50.45172 39.83885 0 2 1 + 1534 485 13 -0.834 43.07357 64.57931 39.44006 2 1 1 + 1535 485 14 0.417 42.79300 64.80186 38.55237 2 1 1 + 1536 485 14 0.417 43.26869 65.42268 39.84860 2 1 1 + 1537 486 13 -0.834 38.86691 42.35197 55.12826 1 1 -1 + 1538 486 14 0.417 38.06621 42.87541 55.16185 1 1 -1 + 1539 486 14 0.417 39.52681 42.89488 55.55954 1 1 -1 + 1540 487 13 -0.834 59.15412 47.19863 55.46904 0 -1 0 + 1541 487 14 0.417 59.83963 46.99833 56.10636 0 -1 0 + 1542 487 14 0.417 58.74433 46.35364 55.28381 0 -1 0 + 1543 488 13 -0.834 52.12071 45.94110 44.23903 1 1 0 + 1544 488 14 0.417 51.89927 45.05144 44.51416 1 1 0 + 1545 488 14 0.417 52.26697 45.87115 43.29566 1 1 0 + 1546 489 13 -0.834 41.73140 52.23741 31.27732 0 0 1 + 1547 489 14 0.417 40.84403 52.55314 31.44796 0 0 1 + 1548 489 14 0.417 41.81503 52.26011 30.32405 0 0 1 + 1549 490 13 -0.834 38.46034 66.01701 52.27886 1 0 -1 + 1550 490 14 0.417 39.39276 66.02392 52.49517 1 0 -1 + 1551 490 14 0.417 38.11246 66.80769 52.69121 1 0 -1 + 1552 491 13 -0.834 42.13838 67.12262 54.88509 0 0 -3 + 1553 491 14 0.417 42.22460 67.38235 53.96784 0 0 -3 + 1554 491 14 0.417 42.96673 67.38388 55.28736 0 0 -3 + 1555 492 13 -0.834 37.89607 66.86351 46.16867 -1 -1 -1 + 1556 492 14 0.417 38.03129 66.98073 47.10899 -1 -1 -1 + 1557 492 14 0.417 38.75367 66.60168 45.83369 -1 -1 -1 + 1558 493 13 -0.834 40.37538 58.21424 30.88318 0 -1 0 + 1559 493 14 0.417 41.23010 58.63566 30.79307 0 -1 0 + 1560 493 14 0.417 40.45502 57.40101 30.38463 0 -1 0 + 1561 494 13 -0.834 54.56531 48.85249 32.17940 1 -2 2 + 1562 494 14 0.417 54.90082 48.98086 31.29216 1 -2 2 + 1563 494 14 0.417 54.03604 49.63141 32.35086 1 -2 2 + 1564 495 13 -0.834 63.56488 49.70113 37.88594 0 -1 1 + 1565 495 14 0.417 63.93261 49.40780 37.05228 0 -1 1 + 1566 495 14 0.417 63.98151 50.54765 38.04739 0 -1 1 + 1567 496 13 -0.834 39.26126 54.76920 54.71493 2 -1 2 + 1568 496 14 0.417 38.75402 55.21237 54.03483 2 -1 2 + 1569 496 14 0.417 38.67139 54.73109 55.46781 2 -1 2 + 1570 497 13 -0.834 42.78607 47.20625 49.30057 2 -1 0 + 1571 497 14 0.417 42.93670 46.34815 48.90404 2 -1 0 + 1572 497 14 0.417 43.53800 47.33917 49.87780 2 -1 0 + 1573 498 13 -0.834 59.99490 55.30114 50.55687 0 1 -1 + 1574 498 14 0.417 60.84158 55.66821 50.81111 0 1 -1 + 1575 498 14 0.417 59.38335 56.03363 50.63237 0 1 -1 + 1576 499 13 -0.834 57.95276 49.30660 54.37087 1 -1 -1 + 1577 499 14 0.417 57.34184 49.29544 55.10769 1 -1 -1 + 1578 499 14 0.417 58.55272 48.58151 54.54557 1 -1 -1 + 1579 500 13 -0.834 43.43041 64.04345 57.10111 1 -1 -1 + 1580 500 14 0.417 43.03742 64.07155 30.60210 1 -1 0 + 1581 500 14 0.417 44.26016 64.51104 29.82515 1 -1 0 + 1582 501 13 -0.834 40.71066 57.82778 50.85579 1 -1 -1 + 1583 501 14 0.417 41.04411 57.83612 51.75299 1 -1 -1 + 1584 501 14 0.417 40.96886 58.67633 50.49590 1 -1 -1 + 1585 502 13 -0.834 61.21331 60.53661 39.63578 1 -1 0 + 1586 502 14 0.417 61.87151 61.23113 39.61011 1 -1 0 + 1587 502 14 0.417 61.32085 60.13583 40.49837 1 -1 0 + 1588 503 13 -0.834 43.54081 65.33296 49.47114 1 -1 -1 + 1589 503 14 0.417 42.67637 65.41138 49.06762 1 -1 -1 + 1590 503 14 0.417 43.36562 64.99829 50.35065 1 -1 -1 + 1591 504 13 -0.834 50.27329 53.06087 30.87109 -1 0 1 + 1592 504 14 0.417 50.38769 53.42204 29.99204 -1 0 1 + 1593 504 14 0.417 50.86354 53.57620 31.42092 -1 0 1 + 1594 505 13 -0.834 40.29157 66.01889 32.67757 0 -1 0 + 1595 505 14 0.417 40.18198 66.27998 31.76320 0 -1 0 + 1596 505 14 0.417 39.39873 65.90460 33.00317 0 -1 0 + 1597 506 13 -0.834 48.15372 67.97019 44.25255 1 -1 1 + 1598 506 14 0.417 47.34263 67.52534 44.49854 1 -1 1 + 1599 506 14 0.417 47.87159 41.31478 43.68328 1 0 1 + 1600 507 13 -0.834 53.38019 63.98437 38.13827 0 0 -1 + 1601 507 14 0.417 54.19463 63.69976 37.72362 0 0 -1 + 1602 507 14 0.417 53.59582 64.82739 38.53711 0 0 -1 + 1603 508 13 -0.834 40.87597 58.12305 53.50808 0 0 0 + 1604 508 14 0.417 40.17916 58.26636 54.14852 0 0 0 + 1605 508 14 0.417 41.66044 58.48234 53.92256 0 0 0 + 1606 509 13 -0.834 38.19887 52.28056 36.30714 2 0 -1 + 1607 509 14 0.417 38.20463 53.19038 36.60452 2 0 -1 + 1608 509 14 0.417 38.09924 52.33929 35.35695 2 0 -1 + 1609 510 13 -0.834 49.63883 57.32410 43.72359 0 -1 0 + 1610 510 14 0.417 49.72446 58.17232 43.28833 0 -1 0 + 1611 510 14 0.417 48.76183 57.33851 44.10688 0 -1 0 + 1612 511 13 -0.834 42.58791 59.61362 29.86455 1 0 0 + 1613 511 14 0.417 43.07246 58.91969 56.78877 1 0 -1 + 1614 511 14 0.417 42.69535 60.38141 56.67447 1 0 -1 + 1615 512 13 -0.834 50.76111 60.95449 46.98165 -1 0 -1 + 1616 512 14 0.417 50.90477 61.15450 47.90663 -1 0 -1 + 1617 512 14 0.417 50.20825 61.66875 46.66473 -1 0 -1 + 1618 513 13 -0.834 43.18406 55.61939 48.08539 1 0 0 + 1619 513 14 0.417 43.11229 56.55752 47.90932 1 0 0 + 1620 513 14 0.417 44.01330 55.36231 47.68228 1 0 0 + 1621 514 13 -0.834 54.67377 64.76817 41.62522 1 0 1 + 1622 514 14 0.417 54.39407 65.19031 40.81294 1 0 1 + 1623 514 14 0.417 55.29742 65.38243 42.01250 1 0 1 + 1624 515 13 -0.834 53.87383 68.12810 51.72031 0 -1 0 + 1625 515 14 0.417 53.06918 41.24938 51.55887 0 0 0 + 1626 515 14 0.417 53.74278 67.72971 52.58074 0 -1 0 + 1627 516 13 -0.834 38.24785 41.26767 33.50598 2 0 0 + 1628 516 14 0.417 38.16490 67.75301 33.15337 2 -1 0 + 1629 516 14 0.417 37.95757 41.83753 32.79377 2 0 0 + 1630 517 13 -0.834 47.35008 61.96125 42.94580 2 -2 0 + 1631 517 14 0.417 47.46077 62.90828 43.03015 2 -2 0 + 1632 517 14 0.417 47.09087 61.83022 42.03373 2 -2 0 + 1633 518 13 -0.834 40.55210 54.00820 41.89137 1 -1 1 + 1634 518 14 0.417 39.80099 54.24986 41.34946 1 -1 1 + 1635 518 14 0.417 40.19429 53.40377 42.54166 1 -1 1 + 1636 519 13 -0.834 57.17705 64.40362 55.44286 1 -1 -1 + 1637 519 14 0.417 56.34510 64.78670 55.72097 1 -1 -1 + 1638 519 14 0.417 57.64987 65.12814 55.03330 1 -1 -1 + 1639 520 13 -0.834 41.86955 59.84132 42.65268 0 -1 1 + 1640 520 14 0.417 41.72011 59.11980 43.26367 0 -1 1 + 1641 520 14 0.417 42.24995 60.53605 43.19017 0 -1 1 + 1642 521 13 -0.834 61.62566 57.26645 46.18447 0 -1 -1 + 1643 521 14 0.417 60.68119 57.41642 46.22577 0 -1 -1 + 1644 521 14 0.417 61.98987 57.84356 46.85569 0 -1 -1 + 1645 522 13 -0.834 46.82701 65.68647 41.03579 0 0 0 + 1646 522 14 0.417 46.01385 65.85266 41.51264 0 0 0 + 1647 522 14 0.417 47.44009 65.38297 41.70531 0 0 0 + 1648 523 13 -0.834 54.12960 45.94549 32.81485 0 0 1 + 1649 523 14 0.417 53.25962 45.65636 32.53955 0 0 1 + 1650 523 14 0.417 54.18942 46.85072 32.50950 0 0 1 + 1651 524 13 -0.834 43.71268 59.97805 32.34985 1 1 0 + 1652 524 14 0.417 43.46300 59.27568 32.95033 1 1 0 + 1653 524 14 0.417 42.94131 60.10757 31.79808 1 1 0 + 1654 525 13 -0.834 50.10604 48.47250 49.62054 1 0 -2 + 1655 525 14 0.417 50.96037 48.77303 49.31064 1 0 -2 + 1656 525 14 0.417 50.19320 48.44287 50.57331 1 0 -2 + 1657 526 13 -0.834 54.68660 60.38920 43.62499 0 0 0 + 1658 526 14 0.417 54.62862 59.85089 42.83561 0 0 0 + 1659 526 14 0.417 53.78667 60.44045 43.94712 0 0 0 + 1660 527 13 -0.834 56.35115 44.75736 40.87552 0 -1 -1 + 1661 527 14 0.417 56.99705 44.99197 41.54186 0 -1 -1 + 1662 527 14 0.417 55.55387 44.56808 41.37024 0 -1 -1 + 1663 528 13 -0.834 48.77009 62.36934 40.44473 0 -1 0 + 1664 528 14 0.417 49.30266 62.60520 41.20432 0 -1 0 + 1665 528 14 0.417 49.04689 62.97756 39.75939 0 -1 0 + 1666 529 13 -0.834 45.88757 58.55209 41.94547 0 1 0 + 1667 529 14 0.417 46.76719 58.27665 42.20365 0 1 0 + 1668 529 14 0.417 45.35604 57.75963 42.02128 0 1 0 + 1669 530 13 -0.834 39.44116 52.22097 43.65725 1 0 2 + 1670 530 14 0.417 39.30570 52.06689 44.59221 1 0 2 + 1671 530 14 0.417 38.61744 52.60378 43.35530 1 0 2 + 1672 531 13 -0.834 43.95976 66.73852 41.23250 1 0 1 + 1673 531 14 0.417 44.64454 67.13772 40.69588 1 0 1 + 1674 531 14 0.417 43.40678 67.47232 41.50081 1 0 1 + 1675 532 13 -0.834 62.99634 65.50241 54.70446 0 -1 -1 + 1676 532 14 0.417 63.58398 64.98613 55.25617 0 -1 -1 + 1677 532 14 0.417 62.12519 65.14960 54.88585 0 -1 -1 + 1678 533 13 -0.834 62.92898 53.27582 44.77167 0 0 0 + 1679 533 14 0.417 62.08998 53.60880 45.09018 0 0 0 + 1680 533 14 0.417 62.85751 52.32504 44.85618 0 0 0 + 1681 534 13 -0.834 63.31201 43.08081 48.29805 -1 0 -1 + 1682 534 14 0.417 63.01276 42.23705 47.95930 -1 0 -1 + 1683 534 14 0.417 63.67142 43.53221 47.53431 -1 0 -1 + 1684 535 13 -0.834 47.11867 63.34781 55.06249 0 0 -1 + 1685 535 14 0.417 47.19267 64.30022 55.00160 0 0 -1 + 1686 535 14 0.417 46.22495 63.15783 54.77716 0 0 -1 + 1687 536 13 -0.834 60.37216 67.91341 52.27568 -1 0 0 + 1688 536 14 0.417 61.05051 68.14950 52.90839 -1 0 0 + 1689 536 14 0.417 60.81546 67.93922 51.42771 -1 0 0 + 1690 537 13 -0.834 60.04315 43.26291 35.25445 -1 1 1 + 1691 537 14 0.417 60.42501 44.05815 35.62593 -1 1 1 + 1692 537 14 0.417 60.79709 42.72574 35.01102 -1 1 1 + 1693 538 13 -0.834 53.03851 55.52589 47.75769 0 0 -1 + 1694 538 14 0.417 53.93635 55.46537 47.43136 0 0 -1 + 1695 538 14 0.417 52.51527 55.73342 46.98347 0 0 -1 + 1696 539 13 -0.834 37.91895 50.43697 56.37325 0 0 0 + 1697 539 14 0.417 37.51622 49.56884 56.35299 0 0 0 + 1698 539 14 0.417 38.37591 50.50915 55.53527 0 0 0 + 1699 540 13 -0.834 50.50006 63.56852 38.27177 1 1 0 + 1700 540 14 0.417 50.22462 63.18436 37.43944 1 1 0 + 1701 540 14 0.417 51.44083 63.71275 38.16986 1 1 0 + 1702 541 13 -0.834 49.44600 43.95446 42.01861 0 0 1 + 1703 541 14 0.417 49.59639 44.80378 41.60354 0 0 1 + 1704 541 14 0.417 49.73882 44.07372 42.92211 0 0 1 + 1705 542 13 -0.834 50.98365 47.23031 39.51901 1 0 1 + 1706 542 14 0.417 51.18743 48.09631 39.16579 1 0 1 + 1707 542 14 0.417 50.03928 47.13635 39.39410 1 0 1 + 1708 543 13 -0.834 45.54625 60.20130 44.30493 0 0 2 + 1709 543 14 0.417 46.27140 60.62480 43.84553 0 0 2 + 1710 543 14 0.417 45.09838 59.69256 43.62904 0 0 2 + 1711 544 13 -0.834 60.48207 53.69772 48.42686 0 0 1 + 1712 544 14 0.417 60.03677 54.31581 49.00644 0 0 1 + 1713 544 14 0.417 59.89364 52.94407 48.38216 0 0 1 + 1714 545 13 -0.834 63.04952 45.83903 48.97963 -1 1 1 + 1715 545 14 0.417 63.88202 45.63831 49.40729 -1 1 1 + 1716 545 14 0.417 62.76408 45.00498 48.60667 -1 1 1 + 1717 546 13 -0.834 40.62890 44.95273 52.60003 2 -1 -2 + 1718 546 14 0.417 41.29110 45.55853 52.26721 2 -1 -2 + 1719 546 14 0.417 40.33885 45.34348 53.42431 2 -1 -2 + 1720 547 13 -0.834 39.91743 46.12102 55.72693 -1 1 -1 + 1721 547 14 0.417 40.70381 45.68274 56.05216 -1 1 -1 + 1722 547 14 0.417 39.19323 45.65943 56.14967 -1 1 -1 + 1723 548 13 -0.834 42.06829 45.07566 41.79962 0 0 -1 + 1724 548 14 0.417 41.61985 45.91039 41.93531 0 0 -1 + 1725 548 14 0.417 41.86481 44.56390 42.58253 0 0 -1 + 1726 549 13 -0.834 44.17588 49.40877 37.86902 1 1 0 + 1727 549 14 0.417 43.85185 49.35470 38.76808 1 1 0 + 1728 549 14 0.417 43.95346 48.56183 37.48242 1 1 0 + 1729 550 13 -0.834 52.64793 63.92130 45.68237 0 1 0 + 1730 550 14 0.417 52.63502 62.96908 45.58561 0 1 0 + 1731 550 14 0.417 52.43571 64.07178 46.60356 0 1 0 + 1732 551 13 -0.834 51.57615 43.64864 38.83377 1 1 0 + 1733 551 14 0.417 51.74260 43.03820 38.11551 1 1 0 + 1734 551 14 0.417 52.20192 44.35945 38.69449 1 1 0 + 1735 552 13 -0.834 62.02099 63.12241 47.73587 0 1 0 + 1736 552 14 0.417 61.17806 62.75352 47.99973 0 1 0 + 1737 552 14 0.417 62.48263 62.39363 47.32116 0 1 0 + 1738 553 13 -0.834 38.41497 51.40373 50.93034 1 1 0 + 1739 553 14 0.417 37.60807 51.12879 50.49494 1 1 0 + 1740 553 14 0.417 38.99796 51.65996 50.21571 1 1 0 + 1741 554 13 -0.834 51.96339 44.25313 49.02477 0 0 0 + 1742 554 14 0.417 52.81680 44.60151 49.28274 0 0 0 + 1743 554 14 0.417 52.16570 43.57682 48.37831 0 0 0 + 1744 555 13 -0.834 43.58422 51.42052 49.88959 0 1 -1 + 1745 555 14 0.417 42.74054 51.00549 50.06897 0 1 -1 + 1746 555 14 0.417 44.20160 50.69175 49.82657 0 1 -1 + 1747 556 13 -0.834 52.39836 53.43568 49.29165 1 0 -1 + 1748 556 14 0.417 51.88756 52.90169 48.68323 1 0 -1 + 1749 556 14 0.417 52.64451 54.20889 48.78391 1 0 -1 + 1750 557 13 -0.834 57.76885 46.61656 49.32842 0 1 0 + 1751 557 14 0.417 57.83718 46.26991 48.43879 0 1 0 + 1752 557 14 0.417 58.65246 46.53329 49.68694 0 1 0 + 1753 558 13 -0.834 59.20868 56.75211 36.79427 0 1 -1 + 1754 558 14 0.417 59.74268 56.20033 36.22276 0 1 -1 + 1755 558 14 0.417 58.75094 56.13459 37.36470 0 1 -1 + 1756 559 13 -0.834 51.74055 42.45875 36.24184 0 1 1 + 1757 559 14 0.417 51.04879 41.79745 36.22260 0 1 1 + 1758 559 14 0.417 52.52794 41.99055 35.96429 0 1 1 + 1759 560 13 -0.834 56.37631 67.32150 33.05439 -1 0 1 + 1760 560 14 0.417 56.52797 66.39716 33.25152 -1 0 1 + 1761 560 14 0.417 56.88845 67.79399 33.71068 -1 0 1 + 1762 561 13 -0.834 54.61713 62.99597 56.69158 0 1 -1 + 1763 561 14 0.417 54.59393 63.94258 56.83172 0 1 -1 + 1764 561 14 0.417 54.12883 62.86158 55.87934 0 1 -1 + 1765 562 13 -0.834 59.12420 67.78462 34.49420 0 -1 1 + 1766 562 14 0.417 59.61921 67.94665 33.69111 0 -1 1 + 1767 562 14 0.417 59.22686 41.21594 35.00547 0 0 1 + 1768 563 13 -0.834 63.35827 53.14027 38.43168 -1 0 0 + 1769 563 14 0.417 62.48186 53.05933 38.05538 -1 0 0 + 1770 563 14 0.417 63.87715 53.55740 37.74392 -1 0 0 + 1771 564 13 -0.834 50.05518 64.80335 44.94078 1 0 -2 + 1772 564 14 0.417 50.16173 65.71408 44.66608 1 0 -2 + 1773 564 14 0.417 50.94818 64.48993 45.08424 1 0 -2 + 1774 565 13 -0.834 61.91076 61.67486 44.00650 0 -3 0 + 1775 565 14 0.417 61.40514 60.86646 44.09077 0 -3 0 + 1776 565 14 0.417 62.58390 61.60857 44.68380 0 -3 0 + 1777 566 13 -0.834 61.53884 41.33016 50.02212 -1 0 -1 + 1778 566 14 0.417 61.75835 68.35836 49.15591 -1 -1 -1 + 1779 566 14 0.417 62.19075 42.01255 50.18215 -1 0 -1 + 1780 567 13 -0.834 54.81641 49.94673 49.66324 0 -1 -1 + 1781 567 14 0.417 54.81533 50.72359 50.22249 0 -1 -1 + 1782 567 14 0.417 53.94410 49.93341 49.26932 0 -1 -1 + 1783 568 13 -0.834 60.68933 64.00249 53.56679 -1 -1 -1 + 1784 568 14 0.417 60.72666 63.10922 53.90872 -1 -1 -1 + 1785 568 14 0.417 60.37485 64.52808 54.30238 -1 -1 -1 + 1786 569 13 -0.834 55.51605 42.60469 53.96890 0 -1 0 + 1787 569 14 0.417 55.82084 42.66633 53.06360 0 -1 0 + 1788 569 14 0.417 54.99565 43.39708 54.10137 0 -1 0 + 1789 570 13 -0.834 43.79008 68.23755 52.31171 2 -1 1 + 1790 570 14 0.417 43.47705 41.06627 51.42954 2 0 1 + 1791 570 14 0.417 44.72624 68.07073 52.20206 2 -1 1 + 1792 571 13 -0.834 40.19615 44.94623 32.57234 0 0 1 + 1793 571 14 0.417 40.90940 45.49825 32.25173 0 0 1 + 1794 571 14 0.417 40.42796 44.75889 33.48196 0 0 1 + 1795 572 13 -0.834 51.93921 56.60019 36.60262 -1 0 1 + 1796 572 14 0.417 51.78399 56.35099 37.51368 -1 0 1 + 1797 572 14 0.417 51.06469 56.74242 36.24039 -1 0 1 + 1798 573 13 -0.834 61.66916 50.48338 53.29865 -1 0 -2 + 1799 573 14 0.417 61.63036 50.41309 54.25248 -1 0 -2 + 1800 573 14 0.417 60.77283 50.69388 53.03687 -1 0 -2 + 1801 574 13 -0.834 51.74160 54.87485 56.16871 0 -1 0 + 1802 574 14 0.417 50.91429 55.26706 56.44795 0 -1 0 + 1803 574 14 0.417 51.91124 55.25931 55.30869 0 -1 0 + 1804 575 13 -0.834 40.85698 68.18248 30.13155 1 -1 0 + 1805 575 14 0.417 41.30492 67.87357 56.71541 1 -1 -1 + 1806 575 14 0.417 41.55175 41.19073 30.66952 1 0 0 + 1807 576 13 -0.834 50.89809 58.89690 54.50288 -1 0 0 + 1808 576 14 0.417 50.06229 58.64352 54.89466 -1 0 0 + 1809 576 14 0.417 51.37024 59.33797 55.20914 -1 0 0 + 1810 577 13 -0.834 58.37524 67.95427 49.91095 0 1 0 + 1811 577 14 0.417 57.83519 41.29391 50.25604 0 2 0 + 1812 577 14 0.417 59.26942 68.19076 50.15744 0 1 0 + 1813 578 13 -0.834 51.40785 46.48357 30.68744 1 0 1 + 1814 578 14 0.417 52.21871 45.99275 30.55389 1 0 1 + 1815 578 14 0.417 50.76683 45.82189 30.94725 1 0 1 + 1816 579 13 -0.834 57.04032 43.52295 36.91237 0 0 0 + 1817 579 14 0.417 56.97310 44.35969 36.45239 0 0 0 + 1818 579 14 0.417 57.91622 43.53095 37.29833 0 0 0 + 1819 580 13 -0.834 48.05479 47.92450 33.11226 0 0 1 + 1820 580 14 0.417 47.68291 48.79527 32.97186 0 0 1 + 1821 580 14 0.417 48.92592 48.09081 33.47242 0 0 1 + 1822 581 13 -0.834 52.31083 59.89064 56.95945 1 -2 -1 + 1823 581 14 0.417 51.77727 60.32576 30.25310 1 -2 0 + 1824 581 14 0.417 52.84806 60.59010 56.58744 1 -2 -1 + 1825 582 13 -0.834 49.28190 53.14534 38.62511 0 0 1 + 1826 582 14 0.417 48.56647 53.70668 38.92395 0 0 1 + 1827 582 14 0.417 48.86634 52.52585 38.02526 0 0 1 + 1828 583 13 -0.834 48.15214 51.90611 34.43290 2 0 0 + 1829 583 14 0.417 48.57405 51.97443 33.57642 2 0 0 + 1830 583 14 0.417 47.22654 51.76503 34.23389 2 0 0 + 1831 584 13 -0.834 61.27546 54.09168 30.34511 0 1 1 + 1832 584 14 0.417 61.26898 53.84689 31.27046 0 1 1 + 1833 584 14 0.417 62.02427 53.62196 29.97785 0 1 1 + 1834 585 13 -0.834 47.15916 50.47662 53.78471 0 -1 0 + 1835 585 14 0.417 47.32648 50.93912 54.60588 0 -1 0 + 1836 585 14 0.417 46.29671 50.78520 53.50690 0 -1 0 + 1837 586 13 -0.834 58.58091 63.09753 49.23949 0 -1 1 + 1838 586 14 0.417 59.43607 63.50227 49.38484 0 -1 1 + 1839 586 14 0.417 58.76326 62.34843 48.67219 0 -1 1 + 1840 587 13 -0.834 55.82082 49.65937 30.11648 0 1 1 + 1841 587 14 0.417 56.52757 49.92139 30.70647 0 1 1 + 1842 587 14 0.417 55.68213 50.42183 56.92602 0 1 0 + 1843 588 13 -0.834 63.79581 52.53565 53.17702 0 -2 1 + 1844 588 14 0.417 36.89869 52.41207 52.35479 1 -2 1 + 1845 588 14 0.417 63.12882 51.84908 53.17487 0 -2 1 + 1846 589 13 -0.834 58.30874 56.36537 43.52715 0 0 3 + 1847 589 14 0.417 58.58025 56.80205 44.33452 0 0 3 + 1848 589 14 0.417 57.40732 56.09029 43.69457 0 0 3 + 1849 590 13 -0.834 38.42652 61.06904 33.48425 0 -2 -1 + 1850 590 14 0.417 39.08604 61.75763 33.56856 0 -2 -1 + 1851 590 14 0.417 38.90648 60.25628 33.64334 0 -2 -1 + 1852 591 13 -0.834 46.61439 51.58566 41.81121 1 -1 0 + 1853 591 14 0.417 46.97646 51.37067 42.67082 1 -1 0 + 1854 591 14 0.417 46.41089 50.73724 41.41750 1 -1 0 + 1855 592 13 -0.834 60.01555 43.31814 42.71405 1 0 1 + 1856 592 14 0.417 60.52150 42.79903 43.33920 1 0 1 + 1857 592 14 0.417 59.90024 42.74003 41.95989 1 0 1 + 1858 593 13 -0.834 44.88246 59.34852 51.75271 1 0 -1 + 1859 593 14 0.417 45.75263 59.37400 52.15069 1 0 -1 + 1860 593 14 0.417 44.67274 58.41644 51.69374 1 0 -1 + 1861 594 13 -0.834 58.22051 53.10280 51.15729 0 -1 0 + 1862 594 14 0.417 58.53381 52.60654 51.91346 0 -1 0 + 1863 594 14 0.417 58.92607 53.72100 50.96688 0 -1 0 + 1864 595 13 -0.834 52.85332 67.67658 42.66705 0 -1 0 + 1865 595 14 0.417 53.29462 67.40699 41.86157 0 -1 0 + 1866 595 14 0.417 53.28090 67.16860 43.35652 0 -1 0 + 1867 596 13 -0.834 60.42773 53.38162 37.56585 0 0 1 + 1868 596 14 0.417 60.55482 53.97513 38.30601 0 0 1 + 1869 596 14 0.417 59.53313 53.05721 37.66924 0 0 1 + 1870 597 13 -0.834 56.52028 65.87791 50.38146 0 0 1 + 1871 597 14 0.417 56.94337 66.73645 50.39389 0 0 1 + 1872 597 14 0.417 57.02985 65.35034 50.99649 0 0 1 + 1873 598 13 -0.834 54.80064 62.49993 33.68680 1 0 1 + 1874 598 14 0.417 55.58425 61.96146 33.79744 1 0 1 + 1875 598 14 0.417 55.10591 63.27334 33.21259 1 0 1 + 1876 599 13 -0.834 44.11783 61.90196 34.52932 1 1 -1 + 1877 599 14 0.417 44.98641 61.86349 34.92975 1 1 -1 + 1878 599 14 0.417 44.21923 61.44892 33.69223 1 1 -1 + 1879 600 13 -0.834 47.64060 51.80694 44.33090 -1 -1 0 + 1880 600 14 0.417 48.33775 51.24158 44.66345 -1 -1 0 + 1881 600 14 0.417 47.96940 52.69619 44.46262 -1 -1 0 + 1882 601 13 -0.834 56.93644 64.17109 32.73010 0 -2 0 + 1883 601 14 0.417 57.35484 63.79547 31.95543 0 -2 0 + 1884 601 14 0.417 57.46604 63.85913 33.46389 0 -2 0 + 1885 602 13 -0.834 40.19928 60.95715 53.68963 1 0 -1 + 1886 602 14 0.417 41.08822 60.76154 53.39341 1 0 -1 + 1887 602 14 0.417 39.80336 61.43545 52.96114 1 0 -1 + 1888 603 13 -0.834 56.02366 41.52320 41.07986 0 1 0 + 1889 603 14 0.417 55.42766 41.48842 40.33165 0 1 0 + 1890 603 14 0.417 55.93467 42.41489 41.41631 0 1 0 + 1891 604 13 -0.834 52.35261 67.43639 29.83633 -1 0 0 + 1892 604 14 0.417 53.08703 67.77971 56.69878 -1 0 -1 + 1893 604 14 0.417 51.97673 68.20568 30.26426 -1 0 0 + 1894 605 13 -0.834 51.14102 49.90060 37.90539 1 0 1 + 1895 605 14 0.417 51.41236 49.08269 37.48865 1 0 1 + 1896 605 14 0.417 50.32915 50.13989 37.45830 1 0 1 + 1897 606 13 -0.834 48.40753 57.18555 40.43062 0 0 0 + 1898 606 14 0.417 47.74030 57.19949 39.74445 0 0 0 + 1899 606 14 0.417 48.68357 58.09814 40.51553 0 0 0 + 1900 607 13 -0.834 38.43185 54.52830 40.23522 1 -2 1 + 1901 607 14 0.417 37.76601 54.24704 40.86274 1 -2 1 + 1902 607 14 0.417 37.95756 54.62565 39.40951 1 -2 1 + 1903 608 13 -0.834 52.97765 52.38562 41.57118 0 0 0 + 1904 608 14 0.417 52.16773 52.00413 41.23247 0 0 0 + 1905 608 14 0.417 53.62059 51.67937 41.50742 0 0 0 + 1906 609 13 -0.834 52.82978 61.35779 35.40768 0 1 -2 + 1907 609 14 0.417 53.63682 61.71145 35.03372 0 1 -2 + 1908 609 14 0.417 53.10766 60.57217 35.87865 0 1 -2 + 1909 610 13 -0.834 55.37636 43.79165 30.66790 0 0 0 + 1910 610 14 0.417 55.82860 43.25432 31.31827 0 0 0 + 1911 610 14 0.417 55.97415 44.52040 30.50110 0 0 0 + 1912 611 13 -0.834 37.90570 54.55715 45.50029 1 -2 -1 + 1913 611 14 0.417 37.12871 54.09851 45.18066 1 -2 -1 + 1914 611 14 0.417 38.24821 53.99402 46.19441 1 -2 -1 + 1915 612 13 -0.834 60.01324 50.96528 45.16358 1 1 0 + 1916 612 14 0.417 59.85669 51.13906 44.23539 1 1 0 + 1917 612 14 0.417 59.48415 50.19096 45.35532 1 1 0 + 1918 613 13 -0.834 38.84394 52.32942 30.93040 2 1 0 + 1919 613 14 0.417 38.51878 51.61086 30.38802 2 1 0 + 1920 613 14 0.417 38.41000 53.10831 30.58218 2 1 0 + 1921 614 13 -0.834 38.99542 61.66171 44.80992 1 0 2 + 1922 614 14 0.417 38.78488 60.74588 44.99207 1 0 2 + 1923 614 14 0.417 39.68427 61.62223 44.14648 1 0 2 + 1924 615 13 -0.834 57.70791 41.72720 55.47643 0 1 -2 + 1925 615 14 0.417 57.25844 41.36846 56.24163 0 1 -2 + 1926 615 14 0.417 57.00496 41.93588 54.86116 0 1 -2 + 1927 616 13 -0.834 58.08999 54.20225 35.53764 0 -1 0 + 1928 616 14 0.417 58.28608 53.46338 36.11372 0 -1 0 + 1929 616 14 0.417 57.15628 54.11553 35.34551 0 -1 0 + 1930 617 13 -0.834 53.05217 52.71850 54.07873 0 0 -1 + 1931 617 14 0.417 52.72353 53.45661 54.59199 0 0 -1 + 1932 617 14 0.417 52.69237 51.94509 54.51306 0 0 -1 + 1933 618 13 -0.834 49.92059 65.13477 35.13462 0 1 1 + 1934 618 14 0.417 50.86780 65.25694 35.19866 0 1 1 + 1935 618 14 0.417 49.79534 64.18846 35.20565 0 1 1 + 1936 619 13 -0.834 41.32410 62.50943 46.98364 1 -1 0 + 1937 619 14 0.417 40.63048 62.20572 46.39807 1 -1 0 + 1938 619 14 0.417 41.96090 61.79482 46.99226 1 -1 0 + 1939 620 13 -0.834 53.94559 67.39201 49.11860 0 0 0 + 1940 620 14 0.417 54.46912 66.60137 48.98810 0 0 0 + 1941 620 14 0.417 54.03461 67.58755 50.05138 0 0 0 + 1942 621 13 -0.834 62.73724 52.28919 56.37358 -2 0 0 + 1943 621 14 0.417 61.94239 51.76764 56.26203 -2 0 0 + 1944 621 14 0.417 63.44036 51.64333 56.44233 -2 0 0 + 1945 622 13 -0.834 40.38118 67.16060 39.18721 2 1 1 + 1946 622 14 0.417 41.33280 67.21360 39.09858 2 1 1 + 1947 622 14 0.417 40.05780 67.12713 38.28691 2 1 1 + 1948 623 13 -0.834 62.86517 42.00727 34.57539 -1 0 -1 + 1949 623 14 0.417 63.37239 42.81882 34.59420 -1 0 -1 + 1950 623 14 0.417 63.40838 41.39624 34.07760 -1 0 -1 + 1951 624 13 -0.834 45.52270 49.32960 34.34348 1 -1 1 + 1952 624 14 0.417 45.92383 49.19413 33.48500 1 -1 1 + 1953 624 14 0.417 45.24004 50.24407 34.33468 1 -1 1 + 1954 625 13 -0.834 61.03811 44.77668 56.49913 1 1 0 + 1955 625 14 0.417 60.72892 43.87199 56.45248 1 1 0 + 1956 625 14 0.417 60.93423 45.11202 55.60864 1 1 0 + 1957 626 13 -0.834 37.82896 51.65548 39.75440 0 1 1 + 1958 626 14 0.417 37.05574 52.05171 39.35268 0 1 1 + 1959 626 14 0.417 38.46628 52.36806 39.80236 0 1 1 + 1960 627 13 -0.834 57.87448 65.36125 35.56679 -1 -1 0 + 1961 627 14 0.417 58.45940 64.84211 35.01489 -1 -1 0 + 1962 627 14 0.417 58.01580 66.26448 35.28319 -1 -1 0 + 1963 628 13 -0.834 41.02352 64.37669 36.41484 0 0 1 + 1964 628 14 0.417 40.85775 63.95254 37.25679 0 0 1 + 1965 628 14 0.417 41.32667 63.66948 35.84545 0 0 1 + 1966 629 13 -0.834 48.62923 67.86173 41.06030 1 0 1 + 1967 629 14 0.417 48.15680 41.13844 41.58283 1 1 1 + 1968 629 14 0.417 47.94185 67.35115 40.63246 1 0 1 + 1969 630 13 -0.834 57.99331 55.69311 47.88478 1 2 0 + 1970 630 14 0.417 57.70999 55.65425 48.79826 1 2 0 + 1971 630 14 0.417 57.37284 55.13407 47.41709 1 2 0 + 1972 631 13 -0.834 48.67013 62.47689 45.75332 -1 -1 0 + 1973 631 14 0.417 49.00300 63.35392 45.56291 -1 -1 0 + 1974 631 14 0.417 48.17776 62.23177 44.96992 -1 -1 0 + 1975 632 13 -0.834 63.70160 54.96100 33.30497 -1 0 0 + 1976 632 14 0.417 64.21034 55.41699 32.63452 -1 0 0 + 1977 632 14 0.417 36.84822 54.18301 33.51151 0 0 0 + 1978 633 13 -0.834 61.71933 50.02843 40.52579 1 0 -1 + 1979 633 14 0.417 61.89605 49.89083 39.59516 1 0 -1 + 1980 633 14 0.417 61.20325 50.83404 40.55551 1 0 -1 + 1981 634 13 -0.834 49.51254 64.46386 53.41539 0 -1 -1 + 1982 634 14 0.417 48.93704 63.81647 53.00803 0 -1 -1 + 1983 634 14 0.417 49.96102 63.98252 54.11066 0 -1 -1 + 1984 635 13 -0.834 49.54405 44.64373 31.53722 1 2 1 + 1985 635 14 0.417 49.17415 44.45447 32.39954 1 2 1 + 1986 635 14 0.417 48.78808 44.87386 30.99705 1 2 1 + 1987 636 13 -0.834 55.54392 65.92737 37.61921 0 -1 -1 + 1988 636 14 0.417 56.11408 65.75233 38.36791 0 -1 -1 + 1989 636 14 0.417 56.12096 66.32174 36.96519 0 -1 -1 + 1990 637 13 -0.834 55.12269 51.83986 35.86341 1 0 1 + 1991 637 14 0.417 55.56426 51.26412 35.23910 1 0 1 + 1992 637 14 0.417 54.23658 51.93728 35.51477 1 0 1 + 1993 638 13 -0.834 55.63681 62.23759 37.50835 1 -1 0 + 1994 638 14 0.417 55.30920 61.35525 37.33403 1 -1 0 + 1995 638 14 0.417 56.23965 62.41667 36.78672 1 -1 0 + 1996 639 13 -0.834 39.91450 42.04260 35.59226 0 0 0 + 1997 639 14 0.417 39.72903 41.27571 36.13422 0 0 0 + 1998 639 14 0.417 39.23583 42.02933 34.91737 0 0 0 + 1999 640 13 -0.834 48.26433 59.84813 40.16126 0 1 0 + 2000 640 14 0.417 48.74870 60.67004 40.23938 0 1 0 + 2001 640 14 0.417 47.50743 60.06639 39.61748 0 1 0 + 2002 641 13 -0.834 57.35097 49.28414 48.37687 1 1 1 + 2003 641 14 0.417 57.35715 48.51028 48.94022 1 1 1 + 2004 641 14 0.417 56.55074 49.75049 48.61854 1 1 1 + +Velocities + + 1 -0.000671 -0.002823 0.003832 + 2 -0.001597 0.002405 -0.003777 + 3 0.005494 0.003807 -0.002300 + 4 -0.000077 0.004524 -0.000287 + 5 0.003116 -0.007135 -0.034325 + 6 -0.006676 0.004889 -0.001939 + 7 0.003499 -0.004774 0.000159 + 8 -0.003460 0.000694 0.000994 + 9 -0.000065 -0.001353 -0.002848 + 10 -0.001260 -0.002649 0.000699 + 11 -0.002820 -0.002457 -0.005671 + 12 0.005156 -0.005914 0.000984 + 13 -0.002342 -0.001592 0.004306 + 14 0.004397 -0.000231 0.003308 + 15 -0.003258 -0.000006 0.001838 + 16 -0.001637 -0.004429 0.003154 + 17 0.007073 -0.000472 -0.003331 + 18 -0.003380 -0.001390 0.005013 + 19 -0.011019 -0.005332 -0.010451 + 20 -0.005433 0.000844 0.004938 + 21 0.002988 0.000244 -0.009941 + 22 -0.003695 0.006546 -0.007678 + 23 0.009473 0.023276 0.019457 + 24 -0.010016 -0.024193 0.018017 + 25 0.004015 0.008726 -0.000397 + 26 -0.001741 -0.001861 0.007862 + 27 -0.009771 -0.011577 -0.005703 + 28 0.003573 0.006265 -0.005932 + 29 0.004789 0.001987 -0.004620 + 30 0.008858 -0.001064 -0.001455 + 31 -0.001403 0.000613 0.002330 + 32 -0.005808 -0.001620 0.000816 + 33 -0.004160 0.001188 -0.019638 + 34 -0.006899 0.006285 0.013256 + 35 0.000717 -0.000432 -0.006883 + 36 0.002110 0.002628 -0.004683 + 37 0.000765 -0.007298 0.000289 + 38 -0.000128 -0.002893 0.004065 + 39 -0.000411 -0.021741 0.010968 + 40 0.002858 0.000302 0.000042 + 41 0.014233 -0.004599 -0.004060 + 42 -0.001473 -0.003572 -0.006228 + 43 0.009129 -0.002755 0.001456 + 44 0.003931 0.000151 0.003472 + 45 0.001621 0.005391 -0.006087 + 46 -0.004269 -0.001973 0.002735 + 47 -0.006898 -0.001187 -0.003394 + 48 -0.008556 -0.000163 -0.001387 + 49 -0.000633 -0.001754 0.011460 + 50 0.004854 -0.002902 -0.005057 + 51 0.000678 0.003272 0.006218 + 52 0.006502 0.006365 -0.000215 + 53 0.005708 0.012368 0.002955 + 54 0.008627 -0.007839 0.003177 + 55 0.004394 0.000132 0.002346 + 56 -0.004641 0.009426 -0.005548 + 57 -0.004801 -0.024766 0.002851 + 58 -0.002703 0.001589 0.007521 + 59 0.023718 -0.006559 0.003743 + 60 -0.010013 -0.042894 -0.029745 + 61 0.016140 -0.000721 -0.001747 + 62 -0.004871 0.002439 0.001990 + 63 0.009632 0.007144 0.001203 + 64 -0.001150 0.001648 -0.003018 + 65 0.006658 -0.002268 0.006874 + 66 -0.002617 0.003321 0.002230 + 67 -0.000803 0.002802 0.003258 + 68 -0.000984 -0.001579 -0.001813 + 69 0.001316 0.000607 0.003431 + 70 -0.010901 0.000580 -0.004134 + 71 0.005370 -0.003909 0.013130 + 72 -0.012282 0.007114 -0.015100 + 73 0.004641 -0.007554 0.004302 + 74 0.017455 0.013344 0.004896 + 75 0.006200 0.026885 0.020665 + 76 -0.010372 0.000470 -0.005601 + 77 -0.003368 -0.004484 0.010962 + 78 0.012416 -0.004728 0.000719 + 79 -0.005789 0.005198 -0.007541 + 80 0.005480 -0.004049 0.003455 + 81 -0.004935 0.005839 -0.006405 + 82 0.001157 -0.011200 0.018491 + 83 -0.029013 -0.016935 0.021131 + 84 -0.020335 0.020972 0.006071 + 85 0.003304 0.007374 -0.005056 + 86 0.029227 0.010776 -0.013183 + 87 0.001651 0.006570 -0.002085 + 88 0.001533 -0.009172 0.007562 + 89 0.018153 -0.022223 0.015786 + 90 -0.010012 -0.004911 0.002561 + 91 0.000435 0.003941 -0.005468 + 92 0.003301 0.001183 -0.006999 + 93 0.006788 0.011331 -0.004427 + 94 0.001392 0.005663 -0.002907 + 95 -0.001849 -0.002229 -0.003422 + 96 -0.000820 0.005872 0.004561 + 97 -0.003264 0.002461 -0.009257 + 98 0.000160 0.016954 -0.015355 + 99 -0.006597 0.011858 0.000426 + 100 0.001816 -0.005854 -0.001317 + 101 -0.001936 -0.006103 0.018111 + 102 0.024621 -0.022735 -0.000704 + 103 -0.001102 0.008384 -0.003086 + 104 0.012559 0.004375 -0.000361 + 105 0.008377 0.014814 -0.037755 + 106 -0.002851 -0.000200 -0.000722 + 107 0.010701 0.006888 -0.007831 + 108 -0.008490 0.011514 0.009399 + 109 -0.001181 0.001853 0.002176 + 110 -0.018912 -0.023868 0.006706 + 111 -0.000415 -0.001525 0.005751 + 112 -0.001172 0.001329 -0.001270 + 113 -0.006700 -0.006243 -0.006459 + 114 0.000018 0.001429 0.001376 + 115 0.001269 0.002521 0.005249 + 116 -0.002179 0.015666 0.006861 + 117 -0.007158 0.000981 0.007353 + 118 0.001047 0.000840 -0.004404 + 119 0.000974 -0.012527 0.005053 + 120 0.026729 0.008884 -0.003350 + 121 0.001181 -0.004040 -0.002037 + 122 0.006556 -0.007438 0.002656 + 123 0.005056 -0.015002 -0.003727 + 124 -0.002704 -0.003683 -0.001021 + 125 0.025048 0.007258 0.008873 + 126 0.019645 -0.020824 -0.002539 + 127 0.000061 0.001072 0.002612 + 128 0.005132 0.013203 0.018763 + 129 0.033473 0.004804 0.018651 + 130 -0.003459 -0.000309 -0.001348 + 131 -0.008088 0.023660 0.011047 + 132 0.010962 0.031994 0.008711 + 133 0.000181 -0.002894 -0.001677 + 134 0.024049 -0.000711 -0.009405 + 135 0.018702 0.003422 -0.019522 + 136 -0.000836 -0.003270 -0.005700 + 137 0.012246 0.016524 0.001525 + 138 0.006270 -0.011288 0.002224 + 139 -0.005169 0.005097 -0.000688 + 140 -0.006982 0.003044 -0.001383 + 141 0.012227 0.012767 0.004047 + 142 -0.001169 0.006070 -0.007989 + 143 0.005451 0.002569 -0.009841 + 144 0.001825 -0.002822 -0.005341 + 145 0.000911 0.004242 -0.002026 + 146 0.012072 -0.001187 -0.010498 + 147 0.007366 0.005541 0.012099 + 148 0.009820 0.000588 0.001087 + 149 0.013758 0.005140 0.015262 + 150 0.015580 0.003311 0.013079 + 151 0.002031 0.000411 0.003403 + 152 -0.001996 0.003750 0.007387 + 153 0.000790 0.000281 -0.000919 + 154 -0.004168 0.001886 -0.004993 + 155 -0.011049 0.015294 0.001052 + 156 -0.012308 0.010348 -0.003128 + 157 -0.001609 -0.004040 -0.002294 + 158 -0.005715 -0.015529 -0.005700 + 159 0.014489 0.026653 0.004024 + 160 0.004070 0.000866 0.003373 + 161 0.004691 0.005062 0.002569 + 162 0.007082 -0.019961 -0.026174 + 163 0.005501 0.000902 -0.001325 + 164 0.007503 0.001448 -0.001472 + 165 0.013628 0.003649 -0.005952 + 166 -0.000639 0.003162 -0.007271 + 167 0.007342 -0.011001 -0.016849 + 168 -0.018400 -0.004772 0.020839 + 169 0.000214 -0.000386 0.002706 + 170 -0.005862 0.010449 -0.003793 + 171 -0.013612 0.011870 -0.006417 + 172 -0.005485 0.006465 0.005343 + 173 0.001788 0.008428 0.005641 + 174 -0.018354 0.029579 0.010717 + 175 0.002627 -0.000754 0.000071 + 176 -0.018080 0.018546 0.001794 + 177 0.006754 -0.000962 -0.007786 + 178 0.002343 0.002166 0.004945 + 179 -0.001724 0.003155 0.010761 + 180 0.010728 0.003441 0.001544 + 181 -0.000849 -0.002856 0.001461 + 182 0.009366 -0.003672 -0.001935 + 183 0.016615 -0.001746 0.005238 + 184 -0.002730 -0.000316 -0.004583 + 185 -0.014755 -0.011310 0.003338 + 186 0.005862 0.008235 -0.003200 + 187 -0.003189 -0.006285 0.009536 + 188 -0.005114 -0.007060 0.006450 + 189 -0.000516 -0.008757 0.009854 + 190 -0.000859 0.005266 0.001864 + 191 0.003108 -0.007021 0.009190 + 192 -0.015949 -0.002050 0.007021 + 193 -0.007008 0.002608 -0.004583 + 194 -0.020431 -0.004004 0.008047 + 195 -0.000364 0.001236 -0.011425 + 196 0.002420 0.006931 0.002031 + 197 0.007178 0.006129 0.009924 + 198 -0.005981 0.016623 -0.013067 + 199 0.003142 -0.001394 -0.001846 + 200 0.011374 -0.002895 -0.000674 + 201 0.032698 -0.002552 0.007288 + 202 -0.005709 0.000071 0.005037 + 203 -0.013193 -0.012592 -0.008102 + 204 -0.008194 0.014723 0.003840 + 205 -0.003270 -0.006146 0.004301 + 206 0.004399 -0.010132 -0.001197 + 207 -0.030308 0.012803 0.003540 + 208 0.002110 0.002374 0.006075 + 209 -0.000845 -0.004182 -0.002795 + 210 0.002582 -0.004671 0.002224 + 211 -0.003768 0.002130 0.001339 + 212 0.022509 0.017397 0.002782 + 213 0.020609 0.006682 -0.014082 + 214 0.003956 0.004282 -0.005023 + 215 0.007499 0.004128 0.002237 + 216 0.034882 -0.005096 0.008948 + 217 -0.002552 -0.000287 -0.001907 + 218 0.025445 0.005560 -0.016526 + 219 0.002741 0.000814 -0.004654 + 220 0.002162 -0.001203 0.000936 + 221 0.004071 0.004725 0.001938 + 222 0.002393 -0.013063 -0.003950 + 223 -0.001609 -0.003218 -0.004310 + 224 -0.012550 0.009033 -0.007868 + 225 0.014344 0.000886 -0.013005 + 226 0.005863 0.010335 -0.003424 + 227 0.011104 -0.005602 -0.012415 + 228 0.001222 0.002408 0.001546 + 229 -0.002038 0.001858 0.002991 + 230 -0.017517 -0.020932 0.016099 + 231 0.005257 0.011588 -0.018236 + 232 -0.002660 -0.006193 0.003186 + 233 -0.021995 0.012375 0.004372 + 234 -0.013906 0.028004 -0.004997 + 235 0.002339 -0.001255 -0.003548 + 236 0.001689 0.005243 -0.006337 + 237 0.000498 -0.007782 -0.015260 + 238 0.001142 0.002234 0.003408 + 239 0.007521 0.004622 -0.003272 + 240 -0.001154 0.006952 0.006739 + 241 -0.000938 -0.004609 0.002499 + 242 0.004903 0.001117 0.013021 + 243 0.008126 -0.013873 -0.001075 + 244 -0.004097 0.002491 -0.002459 + 245 0.002093 -0.002989 0.010881 + 246 0.008552 0.010436 0.008330 + 247 -0.000211 0.002295 0.001935 + 248 0.004346 0.003486 0.008405 + 249 -0.006182 0.002873 -0.007955 + 250 0.002466 0.001439 -0.002302 + 251 -0.003246 0.007233 0.009469 + 252 -0.002606 0.002646 0.002563 + 253 0.000833 -0.001794 -0.003483 + 254 -0.001066 -0.001277 -0.012569 + 255 -0.003354 -0.002604 -0.016130 + 256 0.007379 0.006324 -0.003535 + 257 0.025411 0.006788 -0.010928 + 258 0.011648 0.000201 0.004051 + 259 -0.000385 -0.000823 -0.000593 + 260 -0.001070 -0.019569 0.006235 + 261 0.011350 0.009136 0.002805 + 262 -0.001688 0.002178 0.004704 + 263 -0.011748 0.007674 0.002198 + 264 -0.005358 0.003728 -0.002879 + 265 -0.004209 0.000686 -0.004990 + 266 0.000586 0.011928 0.008080 + 267 0.004512 -0.002493 -0.000297 + 268 -0.000130 0.007801 -0.005732 + 269 -0.006259 -0.000991 -0.001515 + 270 0.015560 -0.011483 0.001826 + 271 -0.003544 0.003178 0.000326 + 272 0.006639 0.005731 0.008812 + 273 -0.009361 -0.001371 -0.002830 + 274 -0.000226 0.001739 0.001787 + 275 -0.001846 -0.005637 -0.002071 + 276 0.009461 0.005629 -0.001253 + 277 0.003294 -0.005377 -0.000680 + 278 0.027740 0.013288 0.002669 + 279 0.003403 0.012169 -0.019874 + 280 -0.001383 0.000386 -0.006636 + 281 -0.005910 0.003429 -0.006992 + 282 0.002649 -0.004178 -0.006969 + 283 0.004768 -0.001680 0.000104 + 284 -0.012916 0.017467 -0.012201 + 285 0.010278 -0.007970 0.003734 + 286 0.000005 0.000300 0.006224 + 287 0.003150 -0.001535 0.007443 + 288 -0.000547 -0.003737 0.010794 + 289 0.003054 0.005656 0.000426 + 290 0.006673 0.002252 0.007300 + 291 0.004185 0.001696 0.005292 + 292 -0.001277 -0.005156 -0.001765 + 293 0.005969 -0.004326 -0.002540 + 294 -0.026915 -0.005145 0.019233 + 295 -0.003352 -0.000356 -0.001610 + 296 -0.023375 -0.003718 -0.017075 + 297 0.006387 -0.025086 0.000315 + 298 -0.005064 0.001395 0.004436 + 299 -0.004111 0.000853 -0.032909 + 300 0.000933 0.005949 0.017391 + 301 0.000607 0.002490 -0.002786 + 302 0.002638 0.008857 0.008537 + 303 0.001294 0.011357 -0.003275 + 304 -0.001798 -0.003127 -0.000795 + 305 -0.003320 0.000996 0.004122 + 306 -0.008728 -0.000634 0.002033 + 307 -0.003535 -0.002662 -0.002777 + 308 -0.005954 -0.002781 -0.004403 + 309 -0.002147 -0.001477 -0.001223 + 310 -0.002595 -0.001397 0.002359 + 311 -0.003605 -0.000224 0.015269 + 312 -0.014002 -0.002828 0.000027 + 313 0.001583 -0.005357 0.002380 + 314 -0.002955 -0.014106 -0.011581 + 315 0.000151 -0.006411 0.002865 + 316 0.004278 -0.004088 0.000114 + 317 -0.019291 0.001584 0.015204 + 318 -0.013439 -0.000674 0.010987 + 319 0.000024 0.000995 0.005326 + 320 -0.009041 0.020464 0.014139 + 321 0.004208 -0.003482 0.004723 + 322 0.001489 -0.003292 0.000500 + 323 0.000364 0.006211 0.006844 + 324 0.007467 0.021162 -0.001636 + 325 0.009527 -0.000863 -0.005483 + 326 -0.009936 0.006496 -0.014136 + 327 -0.007595 -0.006469 -0.002090 + 328 -0.002856 -0.010388 -0.000678 + 329 -0.026693 -0.007624 -0.001572 + 330 0.029582 -0.010319 0.009090 + 331 -0.009062 0.000913 0.000368 + 332 -0.019327 0.020501 -0.000560 + 333 -0.018764 -0.008632 0.002570 + 334 0.004502 0.001200 -0.008087 + 335 0.008714 -0.005091 -0.008624 + 336 0.004610 0.003623 -0.007048 + 337 0.002461 -0.000759 0.003913 + 338 0.021591 -0.013925 0.009416 + 339 -0.017190 0.002325 0.006138 + 340 0.003361 0.004027 0.006986 + 341 0.006850 0.012752 0.018496 + 342 0.019589 0.009932 -0.004987 + 343 0.000463 0.005037 -0.000723 + 344 0.008333 0.006382 -0.005532 + 345 0.004288 0.006565 0.007800 + 346 -0.001505 -0.001295 0.001190 + 347 -0.015747 0.011253 0.025149 + 348 0.014871 -0.012646 -0.016815 + 349 -0.000186 0.002115 -0.002539 + 350 0.001936 0.000958 -0.003366 + 351 -0.014299 0.007078 -0.001653 + 352 -0.000876 -0.001637 -0.002032 + 353 -0.001168 0.005556 -0.012749 + 354 -0.003162 -0.016318 -0.009468 + 355 -0.000674 -0.001888 -0.003265 + 356 0.017652 -0.009515 0.007889 + 357 0.015313 -0.006079 0.010454 + 358 -0.000964 -0.004354 0.000067 + 359 0.004137 -0.002540 0.004500 + 360 -0.011376 -0.000921 -0.006123 + 361 0.002023 0.003210 -0.000511 + 362 0.012560 -0.011698 0.016109 + 363 -0.013295 -0.009379 -0.009014 + 364 0.003315 0.003249 0.007620 + 365 -0.010739 0.000915 -0.008118 + 366 -0.015293 0.007564 -0.004343 + 367 0.000192 0.002269 -0.000485 + 368 0.002520 -0.012494 -0.004632 + 369 0.010222 0.003093 -0.002247 + 370 0.003953 0.000628 0.004147 + 371 0.001165 -0.005271 0.007550 + 372 -0.013412 -0.019696 0.026961 + 373 0.001883 0.002252 -0.003560 + 374 0.005482 -0.004609 0.002380 + 375 -0.008048 0.004473 -0.008866 + 376 -0.002663 0.001073 0.001951 + 377 0.010178 0.018964 0.000820 + 378 0.007583 -0.018984 0.016464 + 379 0.001136 0.007646 0.002719 + 380 0.006251 0.008125 0.009187 + 381 0.001284 0.011634 -0.004097 + 382 -0.000767 0.000265 -0.000818 + 383 -0.000089 0.001579 -0.002300 + 384 -0.004565 -0.011251 0.008186 + 385 0.004778 -0.000871 0.002405 + 386 0.006618 -0.002801 0.006849 + 387 0.029884 -0.012377 0.019662 + 388 -0.002799 -0.005785 0.000693 + 389 -0.006988 0.014716 -0.008738 + 390 -0.003130 0.004832 0.002982 + 391 0.000036 -0.002467 0.000498 + 392 -0.001382 -0.006847 0.003863 + 393 -0.003623 0.001391 0.001664 + 394 0.004431 0.000182 0.002043 + 395 0.007177 -0.001675 0.008884 + 396 0.000324 0.003728 0.003379 + 397 0.004107 -0.000618 0.000098 + 398 0.019272 -0.008832 -0.013192 + 399 -0.025041 0.027976 -0.020594 + 400 0.002982 -0.002889 -0.005826 + 401 0.010564 -0.003899 -0.002078 + 402 0.005218 -0.003308 -0.010357 + 403 0.002304 -0.003833 -0.008812 + 404 -0.013421 -0.017603 -0.023172 + 405 -0.003134 -0.000582 0.001712 + 406 -0.003398 -0.002176 0.001635 + 407 -0.015813 0.008046 0.010515 + 408 0.003940 -0.004144 -0.002666 + 409 0.008428 -0.002203 -0.004077 + 410 -0.004859 0.004207 -0.016803 + 411 -0.022714 0.005614 0.004119 + 412 -0.000677 -0.000486 0.001019 + 413 0.004137 0.001524 0.004810 + 414 -0.011495 -0.003293 -0.002498 + 415 -0.004277 -0.004620 -0.002973 + 416 0.005727 -0.002611 0.021922 + 417 0.009759 0.016284 -0.017136 + 418 0.001140 -0.003169 0.001021 + 419 0.002072 0.019101 -0.019824 + 420 0.029356 -0.011686 0.004675 + 421 0.001175 0.002540 0.001846 + 422 0.009479 -0.017538 0.002696 + 423 0.008327 0.028039 -0.001246 + 424 0.002971 -0.004730 0.000069 + 425 0.010168 -0.005904 -0.016535 + 426 0.009223 0.011295 0.006248 + 427 -0.003323 0.000861 0.005020 + 428 -0.005244 0.001685 -0.001864 + 429 0.000994 0.014826 0.000976 + 430 -0.002795 0.003958 -0.004848 + 431 0.010698 -0.011688 -0.000537 + 432 0.008158 0.021591 -0.003259 + 433 0.000363 0.002223 0.004053 + 434 -0.002225 0.004315 -0.010042 + 435 -0.000151 -0.000572 0.000675 + 436 0.006996 -0.000559 0.003307 + 437 -0.011410 -0.004708 0.006782 + 438 -0.015909 0.022113 0.004877 + 439 -0.002401 -0.002279 0.002655 + 440 -0.002478 0.000164 0.005849 + 441 -0.003545 0.002314 0.007358 + 442 0.002189 0.006935 -0.001251 + 443 -0.007190 0.031224 0.006804 + 444 0.004661 -0.003296 0.013412 + 445 0.003709 0.001514 -0.003921 + 446 0.015678 0.007604 0.000133 + 447 -0.004648 -0.004474 -0.027064 + 448 0.001807 -0.004146 0.004203 + 449 0.029598 0.003434 0.012408 + 450 -0.004603 -0.006201 0.002287 + 451 -0.003031 -0.004136 -0.006564 + 452 0.009003 0.019264 0.004529 + 453 -0.000188 0.010449 0.001077 + 454 0.003891 0.002752 0.005629 + 455 0.001092 0.012776 0.008682 + 456 -0.002762 0.015371 -0.005857 + 457 0.002697 -0.003406 -0.002865 + 458 0.007823 -0.013511 0.002023 + 459 -0.030492 -0.008107 -0.020624 + 460 0.000483 0.001162 0.002651 + 461 0.002571 -0.007508 -0.009384 + 462 -0.010774 -0.027329 0.003619 + 463 0.005791 0.000086 0.004298 + 464 0.008820 0.016257 -0.002226 + 465 0.000317 -0.014932 -0.013621 + 466 0.003540 0.001551 -0.001349 + 467 0.008241 0.020014 0.019807 + 468 -0.004258 -0.010227 -0.029599 + 469 0.007640 0.001287 -0.003128 + 470 0.004600 -0.001555 -0.010230 + 471 0.007870 0.002461 0.000094 + 472 0.001001 0.005160 -0.001529 + 473 0.006073 0.015127 0.022819 + 474 0.006356 -0.012345 -0.003131 + 475 -0.005549 -0.000151 0.001312 + 476 -0.015747 0.009610 0.004075 + 477 0.009345 0.004620 -0.013632 + 478 -0.005694 -0.004777 0.002781 + 479 -0.015785 0.018249 0.008919 + 480 0.007264 0.001342 -0.012954 + 481 -0.002601 -0.003124 -0.001775 + 482 -0.010924 -0.002942 0.001676 + 483 0.020644 0.001519 0.001050 + 484 -0.003829 -0.001681 0.001973 + 485 -0.009248 -0.008096 0.002166 + 486 -0.004627 -0.003317 0.000426 + 487 0.004750 0.008629 -0.001691 + 488 -0.009177 0.001481 0.019567 + 489 -0.000748 -0.004703 -0.011184 + 490 -0.000930 -0.004032 -0.001796 + 491 -0.007051 -0.001375 -0.004647 + 492 -0.000505 0.005436 -0.004029 + 493 -0.000767 -0.000313 -0.004426 + 494 0.007019 0.022441 0.008035 + 495 0.002030 -0.018016 0.012244 + 496 -0.000430 -0.004092 0.001186 + 497 0.012447 -0.008156 0.016405 + 498 -0.008008 0.011043 -0.000527 + 499 0.001752 0.001451 -0.008850 + 500 -0.001696 0.002950 -0.000035 + 501 0.006054 -0.001180 -0.028952 + 502 0.001434 -0.008124 -0.001958 + 503 0.001762 -0.007034 -0.009244 + 504 -0.008796 -0.004759 -0.009928 + 505 0.000249 0.001170 0.006380 + 506 -0.005081 0.014461 -0.003259 + 507 -0.002522 0.001324 0.007841 + 508 0.003441 0.001538 0.006742 + 509 0.007735 -0.006583 0.003492 + 510 0.009681 0.006088 0.008608 + 511 -0.006695 -0.001970 0.000807 + 512 0.004268 0.004052 0.001263 + 513 -0.004129 -0.012886 -0.007489 + 514 -0.002878 0.001158 0.006535 + 515 -0.007680 -0.001896 0.002953 + 516 -0.000917 -0.006257 -0.002762 + 517 -0.001401 -0.003523 -0.005778 + 518 -0.001854 0.007834 0.015061 + 519 -0.010095 0.007049 -0.021128 + 520 -0.000766 -0.000153 0.007009 + 521 0.009064 -0.003223 0.017921 + 522 0.000864 -0.000043 0.007876 + 523 -0.001025 0.001319 -0.006573 + 524 -0.006395 0.000755 -0.002686 + 525 -0.032670 0.007943 0.004175 + 526 0.002953 0.006520 0.004065 + 527 0.009139 -0.008077 -0.010889 + 528 -0.002820 0.012454 -0.005504 + 529 -0.008727 0.003418 0.002451 + 530 -0.007112 -0.005703 0.023446 + 531 -0.011285 0.014165 -0.019563 + 532 -0.002562 0.003192 -0.002295 + 533 -0.003618 0.007211 0.002298 + 534 0.010325 0.001834 0.002853 + 535 0.002563 0.000345 -0.002878 + 536 0.002396 0.022293 -0.006961 + 537 0.001693 -0.002677 0.010576 + 538 -0.001561 0.000734 0.001793 + 539 -0.008542 0.015338 0.007321 + 540 -0.015880 0.015140 0.014642 + 541 0.001092 0.000090 0.000997 + 542 -0.004522 -0.004004 0.003687 + 543 0.003258 -0.006156 0.000500 + 544 -0.001608 0.002026 0.003790 + 545 -0.010430 -0.004583 0.015482 + 546 0.002628 0.011416 0.004923 + 547 -0.002068 0.005845 0.001850 + 548 0.001194 0.007931 0.007672 + 549 -0.020261 -0.007195 -0.008896 + 550 0.005399 0.001999 0.000211 + 551 0.004420 0.012603 0.006214 + 552 0.007790 0.005534 0.000006 + 553 -0.004249 0.001186 -0.000260 + 554 0.006385 -0.014925 0.000020 + 555 0.009902 0.016988 -0.004080 + 556 0.006637 -0.003469 0.000450 + 557 -0.002010 0.011423 -0.004361 + 558 -0.009074 0.013716 -0.002539 + 559 0.003243 -0.003710 -0.002565 + 560 -0.000480 -0.009433 0.000267 + 561 0.002981 -0.005587 -0.010088 + 562 0.002665 0.008169 0.002667 + 563 -0.001817 0.009035 0.022525 + 564 0.005689 0.010678 0.000603 + 565 0.003217 0.002617 0.001072 + 566 0.025108 0.001061 -0.027288 + 567 -0.003091 0.028727 0.028529 + 568 0.003991 -0.002246 0.002528 + 569 0.011195 -0.007917 0.010511 + 570 -0.006686 -0.007088 -0.000640 + 571 0.005302 0.003751 0.001484 + 572 0.001250 0.007658 -0.006666 + 573 0.018145 -0.005375 0.000139 + 574 -0.003857 0.003583 0.000238 + 575 0.006752 0.001063 0.004538 + 576 -0.006479 0.014326 -0.017669 + 577 0.001793 0.003661 0.002509 + 578 0.010186 -0.003147 0.008687 + 579 -0.001160 -0.005645 -0.003812 + 580 -0.002296 0.006997 0.000837 + 581 -0.031138 0.017223 0.000984 + 582 0.002587 -0.007480 0.015277 + 583 0.000288 -0.000668 0.001548 + 584 0.016041 -0.004051 0.004629 + 585 -0.025116 0.003224 0.009356 + 586 -0.000853 0.003188 0.004014 + 587 -0.001700 -0.004491 0.006716 + 588 -0.008947 -0.009004 -0.023328 + 589 0.005432 -0.003893 -0.001000 + 590 -0.019524 0.021049 -0.035976 + 591 0.009404 0.004475 -0.004525 + 592 -0.006508 -0.002709 0.000481 + 593 0.010852 -0.015643 0.005754 + 594 0.006526 0.026156 0.009018 + 595 -0.004611 -0.001841 0.002205 + 596 -0.013411 -0.011893 -0.011510 + 597 -0.002150 -0.000804 -0.006730 + 598 -0.002593 -0.000356 0.003104 + 599 0.009483 0.002951 -0.001362 + 600 -0.015523 -0.003843 0.010828 + 601 -0.001229 0.003953 0.000471 + 602 -0.017788 0.002114 0.033354 + 603 0.015187 -0.017947 -0.007994 + 604 -0.001335 -0.000196 0.007281 + 605 0.015188 0.007448 0.005030 + 606 -0.001538 0.002386 -0.009662 + 607 -0.001172 0.004261 0.002894 + 608 -0.002229 0.015661 0.009134 + 609 0.017428 0.004976 0.006974 + 610 -0.001490 0.003604 0.004586 + 611 -0.017720 0.006222 -0.023144 + 612 0.010016 -0.015847 -0.004678 + 613 -0.002648 0.000934 0.000698 + 614 -0.011832 0.016782 0.007626 + 615 -0.005427 0.001385 0.015386 + 616 0.003669 -0.001949 0.003946 + 617 0.005164 0.000243 0.009975 + 618 -0.000161 0.003111 0.001353 + 619 0.002976 -0.004733 0.001868 + 620 -0.002832 -0.014197 -0.023534 + 621 -0.003347 -0.011551 0.000693 + 622 0.004912 0.001701 -0.000793 + 623 0.013809 0.007164 -0.016905 + 624 0.024958 -0.010962 -0.008428 + 625 0.007422 -0.002948 -0.001308 + 626 -0.016590 -0.032000 -0.001025 + 627 0.011367 0.004098 0.010259 + 628 -0.002045 -0.000742 0.000577 + 629 -0.030845 0.001448 0.030396 + 630 0.001781 -0.017639 0.014980 + 631 0.002233 -0.004427 -0.002429 + 632 0.018586 -0.001402 0.006993 + 633 -0.012356 0.003736 0.007796 + 634 -0.004338 0.007766 0.000310 + 635 0.001990 0.000209 0.007107 + 636 -0.006343 0.005190 -0.018263 + 637 -0.005455 0.000492 -0.002847 + 638 0.000522 0.006495 0.003755 + 639 -0.001841 -0.009429 -0.001507 + 640 -0.002314 -0.002516 -0.005613 + 641 0.018652 0.002237 -0.015930 + 642 -0.002326 -0.000776 -0.003132 + 643 -0.005512 -0.000623 -0.000619 + 644 -0.001015 0.005882 0.003225 + 645 0.000586 0.023218 -0.004529 + 646 -0.001138 0.000800 0.002687 + 647 0.003627 0.013371 -0.016172 + 648 0.018968 0.017228 -0.000038 + 649 -0.002086 -0.000112 -0.007393 + 650 0.016103 0.035588 0.008775 + 651 -0.038516 0.012158 -0.009536 + 652 0.002958 0.004862 -0.007554 + 653 0.024333 0.013052 -0.023133 + 654 0.002379 -0.000049 -0.006601 + 655 0.003804 -0.003076 -0.001112 + 656 -0.004763 0.002283 -0.025897 + 657 -0.036538 -0.010672 -0.010599 + 658 -0.000713 0.003957 0.002151 + 659 -0.016531 0.001472 0.004862 + 660 -0.009287 0.028134 0.010480 + 661 0.004192 -0.003835 0.000568 + 662 0.011523 0.002433 0.036479 + 663 -0.009197 -0.041577 0.000393 + 664 0.000280 -0.002373 -0.004460 + 665 0.002206 -0.003211 0.000957 + 666 0.006211 0.013469 -0.005353 + 667 -0.000522 0.001664 -0.004748 + 668 0.004459 -0.024042 -0.023029 + 669 0.011377 0.013403 0.030836 + 670 0.003382 -0.002813 0.000451 + 671 0.000766 0.000074 -0.006820 + 672 0.013252 -0.015598 0.024274 + 673 -0.003243 0.006406 -0.002570 + 674 0.019962 -0.008888 -0.019769 + 675 -0.027628 -0.005508 -0.000297 + 676 -0.007770 -0.003882 0.002155 + 677 -0.001777 0.012358 0.000036 + 678 -0.024978 0.005564 -0.015024 + 679 0.000188 0.001017 0.004117 + 680 -0.006440 -0.003105 0.019733 + 681 -0.016780 0.005575 -0.004078 + 682 0.000151 0.001697 -0.001387 + 683 -0.002925 0.000955 -0.004378 + 684 0.000826 0.008069 0.003052 + 685 -0.003543 -0.000321 -0.000587 + 686 -0.012205 0.000432 -0.005990 + 687 0.004010 0.009678 -0.003793 + 688 0.001940 -0.000340 0.003900 + 689 0.005837 0.014815 -0.005621 + 690 -0.008710 -0.017653 0.020395 + 691 -0.001931 -0.003975 -0.002577 + 692 -0.003368 -0.014386 -0.006878 + 693 -0.013782 -0.002984 0.003522 + 694 0.004968 -0.000283 -0.003322 + 695 0.019160 0.006665 -0.007077 + 696 0.022604 -0.000847 -0.016983 + 697 0.002571 0.000550 -0.007379 + 698 -0.001443 -0.002487 -0.007727 + 699 -0.011487 -0.013883 0.019460 + 700 0.001096 -0.004750 0.003965 + 701 -0.016603 -0.010473 0.014272 + 702 0.023559 -0.001392 -0.008500 + 703 -0.002022 -0.005262 -0.004485 + 704 0.002332 -0.014942 -0.004917 + 705 -0.009402 0.006267 -0.002020 + 706 -0.000288 0.003264 -0.003564 + 707 0.004565 0.033122 -0.006655 + 708 -0.018922 -0.009521 0.000208 + 709 -0.003485 0.003285 -0.000556 + 710 0.004587 -0.002798 -0.000984 + 711 -0.006054 0.007231 -0.001425 + 712 0.004718 0.000201 -0.003948 + 713 -0.014114 0.009800 -0.004955 + 714 -0.008099 -0.004168 0.008689 + 715 0.000410 -0.000654 0.009605 + 716 0.008711 0.018707 0.002740 + 717 0.003459 -0.008185 0.010239 + 718 0.003479 0.000757 0.004467 + 719 0.000433 -0.000495 0.007710 + 720 0.012945 0.003286 -0.002052 + 721 -0.010010 -0.003567 0.006956 + 722 0.005307 -0.001615 -0.002198 + 723 -0.012515 0.011984 0.016669 + 724 0.001378 -0.002186 -0.001614 + 725 0.012587 -0.019891 0.012237 + 726 0.012601 0.007024 0.014776 + 727 -0.002983 -0.001722 -0.004228 + 728 0.015268 -0.011359 -0.002815 + 729 -0.003967 0.028638 0.000653 + 730 -0.000313 -0.000495 0.001546 + 731 -0.030938 -0.009463 -0.008649 + 732 -0.033474 -0.019299 0.015331 + 733 0.000845 -0.003919 -0.003202 + 734 -0.027178 0.011071 -0.026350 + 735 -0.007741 0.001470 -0.016184 + 736 -0.001239 0.001989 -0.002789 + 737 0.011285 0.001382 -0.006222 + 738 0.022813 -0.006205 -0.006536 + 739 0.003987 -0.004190 -0.005010 + 740 -0.007915 0.002670 -0.013878 + 741 0.004194 0.006086 -0.010350 + 742 0.006539 -0.005074 0.002196 + 743 0.015306 0.008181 0.005081 + 744 0.007865 0.003022 -0.004716 + 745 -0.001784 -0.010062 0.004309 + 746 -0.002378 -0.011275 0.006933 + 747 -0.008336 -0.001053 0.004620 + 748 -0.002979 0.004768 -0.002497 + 749 -0.000959 0.004004 -0.002600 + 750 -0.019512 -0.002978 0.005044 + 751 -0.004903 -0.000550 0.000659 + 752 -0.005086 0.005639 -0.022167 + 753 -0.008131 0.001631 -0.018889 + 754 -0.001761 -0.001628 0.000503 + 755 -0.003957 -0.007199 -0.006609 + 756 0.003155 -0.001306 0.005143 + 757 0.000937 0.008247 -0.008723 + 758 0.028994 0.004889 0.007225 + 759 -0.000469 -0.025903 0.001925 + 760 -0.001834 -0.000370 -0.001605 + 761 0.007234 -0.001225 -0.019036 + 762 -0.003442 -0.001966 0.000209 + 763 0.000445 0.007510 0.001158 + 764 -0.008348 0.004439 -0.007776 + 765 -0.012793 0.011539 0.019680 + 766 0.000065 -0.000962 -0.004032 + 767 -0.002013 -0.005477 0.003901 + 768 0.003529 0.021570 0.007224 + 769 -0.002661 0.002604 -0.003268 + 770 0.005668 -0.003962 -0.004196 + 771 -0.003633 0.008263 -0.012842 + 772 0.001811 0.001915 0.002764 + 773 0.007995 -0.017893 0.012738 + 774 -0.018466 -0.002519 -0.001997 + 775 -0.002231 0.000080 0.000338 + 776 -0.020092 -0.012422 0.010443 + 777 0.017610 0.006562 -0.019411 + 778 -0.001733 0.005494 0.004582 + 779 0.013495 0.017522 0.004058 + 780 0.014733 0.026971 -0.010419 + 781 0.001950 0.000577 -0.000870 + 782 -0.025830 0.001269 0.005271 + 783 0.007534 -0.015453 0.006553 + 784 0.004959 0.000931 -0.005022 + 785 -0.008754 0.005835 0.049441 + 786 0.010447 0.012462 0.001546 + 787 -0.001107 0.002522 0.000433 + 788 0.009871 0.011686 0.008446 + 789 -0.006988 0.002247 0.021211 + 790 0.004245 0.001822 -0.000253 + 791 0.000153 -0.002603 0.008675 + 792 0.006252 0.003177 -0.013109 + 793 -0.002534 0.003863 0.000617 + 794 -0.000057 0.004391 -0.016346 + 795 0.005974 -0.000584 -0.004834 + 796 0.001827 -0.002339 -0.002010 + 797 -0.023150 0.007693 0.012507 + 798 0.012203 0.000464 -0.020004 + 799 -0.000293 -0.001883 -0.002470 + 800 -0.004248 0.006084 0.002613 + 801 -0.013517 0.015693 0.003574 + 802 -0.009450 0.005229 -0.003400 + 803 -0.015058 -0.007700 0.001796 + 804 -0.000196 -0.003546 0.002537 + 805 0.008758 -0.003257 0.005431 + 806 0.012998 -0.011952 -0.017276 + 807 0.008558 -0.002765 0.006723 + 808 -0.001470 -0.000539 0.002965 + 809 0.024028 -0.019423 -0.012788 + 810 0.003892 0.003966 -0.001573 + 811 0.000254 0.001510 0.000089 + 812 0.024395 0.007424 -0.013783 + 813 0.006830 0.017138 0.017010 + 814 -0.001535 -0.003749 -0.001708 + 815 0.013748 -0.018314 -0.006646 + 816 0.003900 0.002047 0.006451 + 817 0.006585 0.003832 -0.000629 + 818 0.021540 0.003252 0.001280 + 819 0.007897 0.007247 -0.003727 + 820 -0.002115 -0.002434 -0.005025 + 821 -0.016735 0.003360 -0.019137 + 822 0.003237 -0.017804 -0.004111 + 823 -0.003907 0.002878 -0.003988 + 824 -0.005419 -0.002010 -0.004476 + 825 -0.006449 0.003104 -0.002766 + 826 -0.013638 -0.002258 -0.002448 + 827 -0.007838 0.000023 -0.005866 + 828 -0.006633 0.001312 -0.008943 + 829 0.001696 0.003761 -0.002125 + 830 -0.001113 -0.010288 -0.008692 + 831 0.010380 0.008838 -0.015548 + 832 -0.003164 0.004544 -0.002070 + 833 -0.001495 -0.013094 -0.000890 + 834 0.011945 -0.015741 -0.003378 + 835 -0.008802 -0.001939 -0.005442 + 836 -0.002949 -0.007279 -0.004665 + 837 0.008414 -0.021459 -0.000948 + 838 0.001330 0.000622 0.000916 + 839 -0.001965 0.001331 0.006138 + 840 0.003081 -0.004825 0.007272 + 841 0.001557 -0.005770 -0.001563 + 842 0.014285 0.020628 -0.029634 + 843 -0.006815 0.003616 0.008747 + 844 0.001116 -0.003881 -0.003556 + 845 0.008316 -0.005783 -0.005256 + 846 -0.011615 0.015346 0.026431 + 847 0.004309 0.003546 -0.004311 + 848 0.007868 -0.013572 0.000073 + 849 -0.011699 0.005875 0.003604 + 850 0.000505 -0.004069 -0.002113 + 851 0.001211 -0.005770 -0.003436 + 852 -0.004651 0.001028 0.007154 + 853 -0.003913 -0.006795 -0.004733 + 854 -0.004339 -0.014527 -0.023555 + 855 -0.006756 -0.006056 -0.008714 + 856 0.007493 0.001588 -0.006408 + 857 0.020526 0.022065 -0.006921 + 858 0.010862 0.004031 -0.001655 + 859 0.003459 -0.001125 -0.001494 + 860 -0.000710 0.004855 0.022662 + 861 -0.000022 0.009082 0.012428 + 862 -0.000591 0.002648 0.002517 + 863 0.017910 0.003993 0.005847 + 864 -0.004999 0.014284 -0.016199 + 865 -0.001700 -0.002300 0.001206 + 866 -0.016994 -0.008747 -0.012103 + 867 -0.008118 -0.008616 0.003715 + 868 -0.002056 -0.003732 -0.006667 + 869 -0.002586 -0.005666 -0.002032 + 870 -0.002179 -0.001361 -0.001378 + 871 0.001952 0.000747 -0.004175 + 872 -0.000006 -0.004573 0.003592 + 873 -0.004377 -0.012174 0.000091 + 874 -0.006945 -0.004708 0.004295 + 875 -0.011724 -0.010397 0.002368 + 876 0.006805 0.012734 0.019238 + 877 0.004959 0.005871 -0.001277 + 878 -0.012228 -0.000867 -0.006672 + 879 0.014516 0.032640 0.025985 + 880 0.000767 -0.000179 0.004816 + 881 0.006242 0.002132 0.007465 + 882 0.006812 0.003103 0.007707 + 883 0.005120 -0.003059 -0.001062 + 884 -0.008255 -0.016076 -0.002362 + 885 -0.001789 -0.014152 -0.001194 + 886 -0.009000 0.001340 0.001690 + 887 -0.020559 -0.017599 0.000329 + 888 -0.003544 -0.006539 0.004087 + 889 -0.000933 0.000538 -0.001999 + 890 0.032797 0.013397 0.000525 + 891 -0.012354 -0.008526 -0.038077 + 892 0.002953 -0.002317 -0.004454 + 893 -0.029479 -0.014864 0.005868 + 894 0.019223 0.000709 -0.013773 + 895 0.002346 -0.003694 -0.004486 + 896 -0.005275 -0.001221 -0.010755 + 897 0.010883 0.001918 -0.002099 + 898 -0.000263 -0.000830 0.005518 + 899 0.000399 -0.005578 0.011643 + 900 -0.007207 -0.006080 -0.006632 + 901 -0.000868 0.002637 -0.000416 + 902 -0.003601 0.001456 0.001019 + 903 0.003465 0.009000 0.002627 + 904 -0.005492 0.001153 0.005034 + 905 0.008501 0.009963 0.005133 + 906 0.002740 0.005510 0.005387 + 907 0.001230 0.003701 -0.010904 + 908 0.005640 0.000943 -0.026378 + 909 -0.001655 0.006661 0.001080 + 910 0.000417 -0.004485 0.000899 + 911 0.004051 -0.003590 0.002016 + 912 0.010109 -0.002124 0.001500 + 913 0.002439 0.006335 0.003103 + 914 -0.006325 0.005901 0.006397 + 915 0.008058 0.002545 0.004591 + 916 -0.001774 -0.003954 -0.005522 + 917 -0.001697 -0.002110 -0.006988 + 918 0.000641 -0.012660 -0.001878 + 919 0.000840 0.002158 -0.002127 + 920 -0.006972 -0.005865 -0.019536 + 921 -0.009078 -0.009093 0.005319 + 922 -0.002466 0.001612 -0.002348 + 923 -0.007997 0.000173 -0.007016 + 924 -0.005167 0.000122 -0.004809 + 925 0.000182 0.007626 -0.005820 + 926 -0.000187 0.006758 -0.004766 + 927 -0.005146 0.010941 -0.001145 + 928 -0.001035 0.003329 -0.000156 + 929 -0.002925 0.005286 0.005381 + 930 -0.007353 0.014383 0.015446 + 931 0.001566 0.003779 -0.001844 + 932 0.014111 -0.006162 0.016836 + 933 -0.008051 -0.000942 0.006114 + 934 0.000472 0.000581 0.003898 + 935 0.010438 -0.015336 0.026259 + 936 -0.009803 0.018803 -0.011113 + 937 -0.002622 0.001845 -0.004649 + 938 0.000192 0.006195 -0.003034 + 939 -0.004379 0.004856 -0.008876 + 940 0.005312 -0.005320 -0.000644 + 941 0.004197 0.002434 0.005873 + 942 0.001054 -0.002144 -0.009156 + 943 0.001818 0.002764 0.000410 + 944 0.002489 0.005354 -0.014128 + 945 0.003819 0.010472 0.007403 + 946 0.005262 -0.000699 0.001191 + 947 -0.002052 -0.008290 0.017377 + 948 -0.012921 -0.009037 0.007720 + 949 0.002875 -0.000206 -0.005514 + 950 0.004620 -0.003924 -0.007344 + 951 0.004396 0.015332 -0.008395 + 952 -0.001773 -0.005567 0.004807 + 953 0.014650 -0.004337 0.011316 + 954 0.007355 -0.004603 0.004796 + 955 0.001050 0.002663 -0.000049 + 956 -0.000422 0.019759 -0.003121 + 957 -0.011736 0.001700 0.005445 + 958 0.002314 -0.007359 0.001422 + 959 0.000226 -0.009157 0.011161 + 960 0.002971 -0.007641 -0.001658 + 961 0.002025 0.003310 0.000085 + 962 0.003783 0.005544 -0.002440 + 963 -0.003390 -0.001680 0.007759 + 964 -0.000259 -0.001517 -0.001671 + 965 -0.009891 -0.000275 0.002930 + 966 -0.004798 -0.018121 0.000493 + 967 0.002742 0.002196 0.002639 + 968 -0.032110 0.008681 0.017593 + 969 -0.005767 -0.003804 -0.003447 + 970 -0.001025 -0.001901 0.007377 + 971 -0.025416 -0.005633 -0.009650 + 972 -0.002448 -0.002342 0.009184 + 973 0.000510 -0.004313 0.003297 + 974 -0.004244 -0.006185 -0.015114 + 975 0.002817 0.008222 0.025232 + 976 -0.005979 0.000432 0.003264 + 977 0.000348 0.000126 0.007237 + 978 -0.031461 0.008376 -0.002490 + 979 -0.003066 -0.005264 0.001528 + 980 0.000500 -0.005194 -0.000082 + 981 -0.006145 0.003915 -0.013465 + 982 -0.002081 -0.001596 0.001268 + 983 0.004918 -0.004802 -0.009499 + 984 -0.008729 0.005751 0.010881 + 985 0.002456 -0.001947 -0.001558 + 986 -0.006566 -0.000024 0.003315 + 987 0.007532 0.005898 -0.002575 + 988 -0.004247 -0.003264 -0.000409 + 989 0.002165 -0.007499 0.004990 + 990 -0.000419 0.003692 -0.004472 + 991 -0.001571 -0.000159 -0.000431 + 992 0.005413 0.009517 0.004397 + 993 -0.002643 -0.002292 -0.001478 + 994 -0.003884 0.005066 -0.000457 + 995 0.006816 0.009263 -0.003376 + 996 -0.007273 0.011919 0.000514 + 997 0.000030 0.001409 0.005477 + 998 0.005334 -0.020033 0.004464 + 999 0.016228 0.009598 -0.007106 + 1000 -0.002283 -0.004481 0.001317 + 1001 -0.002631 -0.006631 -0.004233 + 1002 0.004184 0.000805 0.014756 + 1003 0.000408 -0.003693 0.003308 + 1004 0.004530 -0.006410 -0.006453 + 1005 -0.004928 -0.003846 0.015168 + 1006 0.003101 -0.001511 0.005308 + 1007 0.014081 -0.002443 0.012313 + 1008 0.002846 0.010440 -0.000376 + 1009 0.003569 -0.002175 -0.006662 + 1010 -0.008368 -0.011644 -0.006989 + 1011 0.019824 -0.004949 -0.018661 + 1012 0.003202 -0.011850 0.003160 + 1013 0.014918 -0.009378 0.018579 + 1014 -0.002594 0.004575 -0.001959 + 1015 -0.002298 0.000413 -0.003910 + 1016 0.012837 -0.003799 -0.015681 + 1017 -0.005955 -0.000660 0.004171 + 1018 0.001582 0.000975 0.000146 + 1019 0.006776 -0.014144 -0.007821 + 1020 0.004234 -0.001693 -0.007198 + 1021 -0.001802 -0.002656 0.003257 + 1022 0.028537 0.012512 0.005966 + 1023 -0.000026 -0.011732 -0.013572 + 1024 0.006685 0.008417 -0.002619 + 1025 -0.018380 0.006240 0.006444 + 1026 0.014195 0.009753 -0.004447 + 1027 -0.000769 -0.006799 -0.003510 + 1028 -0.003532 0.013774 -0.009337 + 1029 0.005263 0.018084 -0.010946 + 1030 0.004102 0.004262 -0.002426 + 1031 -0.003256 -0.005354 0.003498 + 1032 -0.021894 -0.003478 0.016467 + 1033 0.001456 -0.004355 -0.002070 + 1034 -0.005859 -0.004113 -0.005871 + 1035 -0.005758 -0.006886 -0.016585 + 1036 0.001562 0.006459 -0.000209 + 1037 0.001331 0.004667 0.000892 + 1038 0.012898 0.027063 -0.008125 + 1039 0.002117 0.007131 0.002457 + 1040 0.026605 0.010046 0.019045 + 1041 -0.017364 0.007077 -0.014953 + 1042 -0.000452 0.009291 0.004625 + 1043 -0.011059 0.009571 0.015357 + 1044 0.027928 -0.000208 0.009437 + 1045 0.003475 -0.004274 -0.000546 + 1046 0.012160 -0.001385 -0.006922 + 1047 -0.016274 -0.008100 -0.006675 + 1048 -0.003853 -0.003278 -0.001388 + 1049 0.014697 -0.003341 -0.007454 + 1050 0.011346 -0.009086 -0.006461 + 1051 -0.001161 -0.003940 -0.002833 + 1052 0.011182 0.001281 -0.000803 + 1053 -0.001345 -0.002375 -0.003580 + 1054 0.004028 0.002256 0.000990 + 1055 0.013302 0.008212 -0.007566 + 1056 0.029179 -0.014499 0.008878 + 1057 0.000706 0.001652 0.001826 + 1058 0.000498 -0.007266 0.024956 + 1059 0.001324 -0.008155 0.011295 + 1060 0.000971 -0.006253 -0.004688 + 1061 -0.004746 -0.005680 -0.016047 + 1062 -0.000356 -0.009050 -0.006561 + 1063 -0.000866 0.005460 0.000045 + 1064 -0.006882 0.011747 0.020163 + 1065 -0.000733 0.001409 -0.010900 + 1066 -0.003804 0.003558 0.001444 + 1067 0.004513 0.002071 -0.017536 + 1068 -0.000869 -0.002704 -0.014336 + 1069 -0.003015 0.003241 -0.002075 + 1070 0.003734 -0.005456 -0.000879 + 1071 -0.006686 -0.008010 -0.008654 + 1072 -0.000541 -0.003669 -0.004373 + 1073 0.003151 -0.002513 -0.013951 + 1074 0.003979 -0.005557 0.002931 + 1075 -0.005175 -0.004387 0.000228 + 1076 -0.005613 -0.012392 -0.029351 + 1077 0.009704 0.009953 -0.015680 + 1078 -0.000915 0.003660 -0.003078 + 1079 0.002529 0.001465 0.006987 + 1080 0.000880 0.001866 -0.004217 + 1081 0.000835 -0.000410 0.000029 + 1082 0.003324 -0.009356 0.012151 + 1083 -0.000797 0.009753 -0.012613 + 1084 0.004557 -0.006851 0.000257 + 1085 0.014378 -0.010986 -0.004036 + 1086 0.001889 0.001865 0.000904 + 1087 0.003881 0.000306 -0.000266 + 1088 0.006043 -0.030376 0.018797 + 1089 -0.001012 -0.002296 0.000324 + 1090 0.007042 0.008682 0.007323 + 1091 0.010016 0.002442 -0.028255 + 1092 -0.004827 0.009414 -0.012200 + 1093 0.002178 0.003272 0.000190 + 1094 0.003486 0.001815 -0.002585 + 1095 0.006020 0.002953 -0.010998 + 1096 0.002573 -0.000704 0.002051 + 1097 -0.010233 0.004335 0.005568 + 1098 0.003397 0.002649 0.010631 + 1099 -0.000367 -0.008657 0.004003 + 1100 0.006810 -0.008282 0.003316 + 1101 -0.008301 -0.011638 -0.006525 + 1102 -0.001900 -0.008810 0.001531 + 1103 0.003628 0.008111 0.009571 + 1104 0.017147 0.000173 0.003988 + 1105 0.006161 0.005444 0.001389 + 1106 -0.033784 0.028714 -0.002486 + 1107 0.022179 0.015181 0.025221 + 1108 0.002935 0.001125 -0.009560 + 1109 0.013392 0.009490 0.002655 + 1110 0.015380 -0.002935 -0.004728 + 1111 0.002760 -0.001052 0.002516 + 1112 -0.006737 0.002302 0.012384 + 1113 -0.004649 -0.009652 -0.009326 + 1114 -0.003333 0.004385 -0.006004 + 1115 -0.014175 0.007089 0.000199 + 1116 0.009875 0.004925 0.012791 + 1117 -0.004828 0.000366 0.001718 + 1118 0.009618 -0.007069 -0.012330 + 1119 -0.021489 -0.009155 -0.001603 + 1120 -0.001360 0.002089 -0.003585 + 1121 0.003530 -0.001847 0.010254 + 1122 0.016468 0.005240 -0.014692 + 1123 0.001989 -0.000949 0.003286 + 1124 0.022107 -0.012110 -0.007316 + 1125 0.012518 -0.010337 0.015891 + 1126 0.000850 -0.001413 -0.001737 + 1127 -0.014943 0.000360 -0.000490 + 1128 -0.027983 -0.005206 0.004037 + 1129 0.011232 0.000349 -0.006679 + 1130 -0.005484 -0.003095 -0.004430 + 1131 -0.005050 -0.002005 -0.015837 + 1132 -0.000470 0.001924 0.001131 + 1133 -0.016506 0.005240 0.008171 + 1134 0.011977 -0.012388 0.003671 + 1135 -0.000818 0.001081 0.001571 + 1136 0.009956 -0.006601 -0.002667 + 1137 -0.013344 0.009962 -0.000602 + 1138 -0.004379 0.004681 0.005655 + 1139 -0.022717 0.009805 -0.016911 + 1140 -0.017223 0.002867 0.018671 + 1141 -0.000339 -0.000149 -0.001276 + 1142 0.002292 0.016872 -0.004987 + 1143 -0.012964 -0.000693 -0.007140 + 1144 -0.002149 0.004008 -0.001355 + 1145 0.012575 0.018012 -0.011467 + 1146 -0.018572 0.011663 -0.005755 + 1147 0.000951 -0.000232 0.005705 + 1148 0.001030 -0.002411 0.005162 + 1149 -0.004871 0.010528 0.006213 + 1150 -0.003431 0.005236 0.003321 + 1151 -0.006083 0.008172 0.003730 + 1152 0.021201 0.002738 -0.026021 + 1153 -0.000559 -0.001274 0.002074 + 1154 -0.000342 -0.008595 -0.003314 + 1155 -0.004563 0.013150 0.001114 + 1156 0.002547 -0.003346 0.000793 + 1157 -0.004000 0.002915 0.001908 + 1158 0.008526 -0.013385 0.001263 + 1159 0.003331 -0.001629 -0.001592 + 1160 0.012216 0.004263 0.001290 + 1161 -0.024729 0.027722 0.012828 + 1162 -0.004556 0.005331 -0.000790 + 1163 -0.001260 0.004809 0.012624 + 1164 0.009151 0.007740 0.005908 + 1165 0.006739 -0.002486 0.000962 + 1166 0.002801 -0.001010 0.007063 + 1167 0.006266 -0.009780 0.000447 + 1168 -0.001756 -0.006121 -0.000399 + 1169 0.002128 0.011752 0.003187 + 1170 -0.000744 -0.004455 -0.001624 + 1171 -0.003120 -0.007987 0.008768 + 1172 -0.001279 -0.014309 0.014916 + 1173 -0.003496 -0.005392 0.006518 + 1174 -0.005252 -0.000094 0.002610 + 1175 -0.004319 0.000327 0.003799 + 1176 0.014469 -0.001407 -0.023557 + 1177 -0.001733 0.011173 0.001097 + 1178 0.019607 0.000729 -0.008577 + 1179 -0.013430 0.021297 -0.011104 + 1180 0.005550 -0.002953 -0.004489 + 1181 -0.021164 -0.004283 0.009224 + 1182 0.020762 -0.011806 0.008058 + 1183 -0.003934 -0.006346 0.000789 + 1184 -0.004154 -0.012917 -0.000804 + 1185 0.001834 -0.003234 0.006486 + 1186 -0.003359 -0.000166 0.000482 + 1187 -0.010938 -0.009570 0.011838 + 1188 -0.006339 -0.002743 -0.017319 + 1189 -0.002008 -0.000238 -0.002842 + 1190 0.009730 0.002797 -0.000255 + 1191 0.004802 0.018470 -0.005529 + 1192 0.002978 0.003254 0.000406 + 1193 0.001762 -0.016118 0.017481 + 1194 0.009625 0.005549 -0.002833 + 1195 -0.005277 -0.000015 -0.004247 + 1196 0.008535 -0.018189 -0.023760 + 1197 -0.020839 0.008581 0.007193 + 1198 0.001976 -0.001531 0.001386 + 1199 -0.012488 -0.005613 0.004418 + 1200 0.012387 0.001324 -0.002579 + 1201 0.004612 0.001574 0.002430 + 1202 0.004011 0.024078 0.008286 + 1203 0.028635 -0.001749 -0.000378 + 1204 -0.001292 -0.004163 0.001688 + 1205 0.018917 -0.005327 -0.022863 + 1206 -0.021498 0.026796 -0.015481 + 1207 -0.004360 -0.003023 -0.007483 + 1208 0.015222 -0.007834 -0.014901 + 1209 -0.015487 -0.004003 -0.024684 + 1210 0.000162 -0.000232 -0.002511 + 1211 0.005663 0.001759 0.003041 + 1212 -0.026577 0.001752 0.009499 + 1213 -0.002118 -0.004800 0.002106 + 1214 0.012772 0.013880 -0.004149 + 1215 0.008831 0.004495 0.004278 + 1216 -0.001002 0.000396 0.000450 + 1217 0.001493 -0.000300 0.006615 + 1218 0.022789 -0.011336 -0.001626 + 1219 -0.002165 0.002305 -0.004399 + 1220 -0.001727 0.010653 0.006150 + 1221 0.001799 -0.000399 -0.015101 + 1222 -0.002535 -0.001664 0.000167 + 1223 -0.007939 0.009699 -0.003581 + 1224 -0.009214 -0.009452 -0.003331 + 1225 -0.002745 0.003249 0.011490 + 1226 0.010727 -0.015563 0.011870 + 1227 -0.003771 0.013856 -0.015486 + 1228 -0.000932 0.001513 0.000721 + 1229 -0.002528 0.000192 0.015301 + 1230 -0.027023 -0.007231 0.009659 + 1231 -0.005525 0.001099 -0.001369 + 1232 -0.002318 -0.008510 -0.009719 + 1233 -0.005945 -0.008347 0.009845 + 1234 -0.000817 -0.006097 -0.001394 + 1235 0.026844 0.005400 -0.013998 + 1236 -0.019837 0.017329 -0.010038 + 1237 -0.002691 -0.005371 -0.000786 + 1238 -0.007304 -0.006372 0.007409 + 1239 -0.014066 -0.005252 0.014237 + 1240 -0.000660 -0.004157 -0.007445 + 1241 -0.015343 -0.015681 0.000525 + 1242 -0.004856 0.008296 -0.020506 + 1243 -0.000451 -0.006253 0.005274 + 1244 -0.016626 -0.024128 0.003146 + 1245 0.003430 -0.001516 0.006995 + 1246 0.002369 0.000761 -0.000692 + 1247 -0.011034 0.017913 -0.003576 + 1248 0.014886 0.005052 0.010870 + 1249 0.000976 0.003044 0.004043 + 1250 0.002084 0.009119 -0.003484 + 1251 -0.004682 -0.003095 0.024419 + 1252 -0.001872 0.005519 -0.003878 + 1253 0.014045 0.004474 0.006660 + 1254 -0.006683 -0.012923 -0.006357 + 1255 -0.007125 -0.002296 0.002894 + 1256 -0.009126 -0.000293 0.008175 + 1257 -0.005668 -0.002902 -0.000640 + 1258 -0.009805 0.000500 -0.001546 + 1259 -0.007254 -0.007274 0.010849 + 1260 0.005786 0.004719 0.004479 + 1261 0.000767 -0.007091 -0.002809 + 1262 -0.010861 -0.024470 -0.006678 + 1263 0.010352 0.003874 -0.018616 + 1264 -0.001332 -0.000776 -0.001533 + 1265 0.005055 -0.002761 -0.000154 + 1266 0.001293 -0.010766 0.003695 + 1267 0.004101 0.005423 0.004161 + 1268 -0.006495 -0.001645 0.007645 + 1269 0.024277 0.000761 0.018148 + 1270 0.000384 -0.004677 0.001777 + 1271 -0.000305 -0.022286 0.006378 + 1272 0.014900 -0.009298 0.005029 + 1273 -0.002201 -0.002422 -0.001266 + 1274 0.002419 0.000621 -0.006170 + 1275 0.002242 -0.003567 -0.006329 + 1276 0.001155 0.006214 -0.002164 + 1277 -0.025679 0.011598 0.001775 + 1278 -0.016652 0.005061 0.002255 + 1279 -0.000163 0.000193 -0.001041 + 1280 -0.002822 -0.004131 -0.007696 + 1281 -0.007029 0.005316 -0.012422 + 1282 -0.001259 -0.001443 0.001295 + 1283 -0.000992 -0.027820 -0.000474 + 1284 -0.012190 -0.043729 -0.008054 + 1285 -0.001840 -0.001572 0.001104 + 1286 0.008311 0.001263 -0.001841 + 1287 0.001277 0.000429 -0.007113 + 1288 -0.005029 -0.002280 -0.002761 + 1289 -0.024723 0.012515 -0.012864 + 1290 -0.013845 -0.020399 0.001674 + 1291 -0.000161 0.002303 0.004199 + 1292 -0.010956 -0.010528 0.017163 + 1293 0.023554 -0.006815 0.021159 + 1294 0.000772 -0.000829 0.004462 + 1295 0.024106 -0.007189 -0.017980 + 1296 -0.011795 0.000225 0.018351 + 1297 -0.002503 0.000288 -0.000931 + 1298 -0.001901 -0.006775 -0.001166 + 1299 -0.002626 0.004209 -0.000596 + 1300 -0.003248 -0.009856 0.001496 + 1301 -0.008616 0.000206 -0.000660 + 1302 0.012991 -0.001944 0.010735 + 1303 0.000183 0.003767 -0.002207 + 1304 0.002875 0.006021 0.006091 + 1305 -0.003343 -0.008883 0.015455 + 1306 -0.003761 0.009400 -0.007147 + 1307 -0.002601 -0.012510 0.005900 + 1308 -0.013464 0.021935 0.006364 + 1309 0.007717 -0.006568 -0.004280 + 1310 0.004551 -0.013432 0.001741 + 1311 0.016676 -0.009730 -0.005415 + 1312 -0.003518 -0.000115 0.000120 + 1313 -0.018566 -0.004441 0.007076 + 1314 0.011422 0.004168 0.013848 + 1315 -0.002232 0.003004 -0.005210 + 1316 -0.004985 -0.000655 -0.007286 + 1317 -0.004756 0.005461 -0.010032 + 1318 0.003296 -0.000345 0.003797 + 1319 0.000013 0.003387 0.009258 + 1320 -0.001175 0.009021 0.016554 + 1321 0.004610 0.000563 0.001890 + 1322 0.001511 0.004957 0.010795 + 1323 -0.000517 0.009529 0.012695 + 1324 0.003561 -0.002127 -0.002139 + 1325 -0.016355 -0.004573 0.011414 + 1326 0.002437 -0.000969 0.003958 + 1327 -0.003191 0.002772 0.003706 + 1328 0.002188 0.004078 0.024902 + 1329 0.005804 0.008997 0.000514 + 1330 0.000169 -0.001823 0.006601 + 1331 -0.012837 0.016738 0.032499 + 1332 -0.003787 -0.003993 0.005792 + 1333 -0.006500 -0.001952 -0.005568 + 1334 0.004632 0.002607 -0.001417 + 1335 0.007826 -0.018417 0.003893 + 1336 0.001400 0.000629 -0.002329 + 1337 -0.026090 -0.010827 -0.007428 + 1338 0.014757 0.003359 0.005866 + 1339 0.005344 0.002452 0.000637 + 1340 0.002304 0.001516 0.008371 + 1341 0.003116 0.003502 0.000920 + 1342 0.000219 0.006872 -0.006361 + 1343 0.004872 0.004948 -0.015461 + 1344 0.002293 0.008990 -0.007103 + 1345 -0.000248 -0.001405 -0.000404 + 1346 0.016050 0.005473 0.014883 + 1347 0.000661 0.010958 0.009762 + 1348 0.002507 0.004854 0.004016 + 1349 -0.000026 0.005865 -0.004933 + 1350 -0.003541 0.012071 0.011984 + 1351 -0.000388 -0.001662 -0.002624 + 1352 -0.008781 0.002236 0.005933 + 1353 -0.002303 0.010321 -0.013971 + 1354 0.000266 0.005381 0.006218 + 1355 -0.030793 -0.017551 0.006520 + 1356 -0.001710 0.006198 0.003481 + 1357 -0.000575 0.000387 0.003498 + 1358 0.011844 0.006387 0.013823 + 1359 -0.004149 -0.001630 0.001064 + 1360 0.002966 -0.001211 -0.000529 + 1361 0.011026 0.001160 0.001568 + 1362 0.015143 -0.001234 0.000065 + 1363 0.000976 0.001952 -0.002769 + 1364 0.013527 0.011152 0.001594 + 1365 -0.000179 -0.000211 -0.002554 + 1366 -0.005351 -0.004969 -0.002979 + 1367 -0.006889 0.021662 -0.005435 + 1368 -0.002462 0.016113 0.008657 + 1369 -0.000975 0.000751 -0.000755 + 1370 -0.003243 0.006738 -0.001393 + 1371 -0.002267 -0.000779 0.003167 + 1372 0.001566 -0.003190 -0.000583 + 1373 -0.002018 -0.005136 0.012563 + 1374 -0.006828 0.007134 0.011132 + 1375 0.005244 -0.004715 -0.003319 + 1376 -0.010064 -0.001392 0.024842 + 1377 -0.003331 -0.012180 0.011450 + 1378 0.005044 -0.003538 0.000197 + 1379 0.014932 -0.005316 0.014871 + 1380 0.002959 -0.015155 -0.010790 + 1381 0.004288 0.003508 0.003045 + 1382 0.010516 0.006731 0.001181 + 1383 0.003157 0.002004 0.039661 + 1384 -0.003464 -0.000341 -0.002519 + 1385 0.000767 -0.010574 0.002375 + 1386 0.012132 0.009405 0.005728 + 1387 -0.002537 0.005096 -0.000141 + 1388 0.008455 -0.000335 0.003398 + 1389 0.000567 0.012932 0.006368 + 1390 0.007440 -0.002304 0.001444 + 1391 0.003946 0.007849 -0.005030 + 1392 0.012038 -0.016280 0.007159 + 1393 -0.001061 -0.002610 -0.000083 + 1394 0.010905 -0.006613 -0.001941 + 1395 -0.013885 -0.027620 0.005494 + 1396 0.013746 0.003525 0.007163 + 1397 0.003586 0.002644 -0.010792 + 1398 0.018544 0.013850 0.017322 + 1399 0.004571 0.000027 -0.001760 + 1400 0.012220 0.001858 -0.006751 + 1401 0.009850 -0.002003 0.019339 + 1402 -0.001383 0.002281 -0.007042 + 1403 -0.003363 0.001654 -0.017801 + 1404 0.011330 0.009635 0.005470 + 1405 0.000650 -0.001098 -0.005942 + 1406 0.005198 -0.008028 -0.003832 + 1407 0.017668 -0.005738 0.026099 + 1408 -0.001891 0.001162 0.003476 + 1409 -0.003537 0.018838 0.000972 + 1410 0.007980 0.016250 0.030292 + 1411 -0.001348 0.000197 0.004181 + 1412 -0.002255 -0.008393 -0.001355 + 1413 -0.008567 -0.008184 -0.000151 + 1414 -0.001145 0.001777 -0.004250 + 1415 -0.002565 -0.000609 -0.002622 + 1416 0.017182 0.009342 -0.008899 + 1417 -0.000336 -0.000833 -0.006619 + 1418 0.006594 -0.014023 -0.011705 + 1419 -0.010047 -0.002912 -0.003804 + 1420 0.005759 0.000406 0.005233 + 1421 -0.013174 -0.018780 -0.002966 + 1422 -0.003551 -0.005212 0.011087 + 1423 -0.001811 -0.005836 -0.002120 + 1424 -0.008296 0.022099 0.012646 + 1425 0.010130 0.006059 0.033707 + 1426 0.001039 -0.001025 -0.000459 + 1427 0.004468 0.000527 0.001539 + 1428 -0.001728 -0.005304 0.003140 + 1429 -0.000141 -0.003112 0.003400 + 1430 0.007530 -0.026022 0.005020 + 1431 -0.011982 0.032142 -0.001998 + 1432 -0.001642 0.003923 -0.003350 + 1433 0.016086 -0.002664 -0.005695 + 1434 -0.010354 0.000136 0.021071 + 1435 0.001502 -0.001507 0.005856 + 1436 -0.003359 -0.017617 -0.013060 + 1437 -0.001621 -0.013764 -0.008355 + 1438 -0.006074 0.001165 0.001910 + 1439 -0.004946 0.003618 0.011324 + 1440 -0.007761 0.002697 -0.006763 + 1441 -0.009332 0.000898 0.000750 + 1442 -0.017083 -0.010335 0.011191 + 1443 0.020780 0.013466 -0.015083 + 1444 -0.008140 -0.008032 -0.000180 + 1445 -0.001836 -0.008988 0.003973 + 1446 -0.008280 -0.004548 -0.003224 + 1447 0.000996 -0.002062 -0.001184 + 1448 -0.001863 -0.012096 0.003957 + 1449 -0.027050 0.007989 0.002157 + 1450 -0.001321 -0.000325 0.001355 + 1451 -0.006885 -0.000536 -0.022446 + 1452 0.008792 -0.007975 0.003329 + 1453 -0.003682 -0.004782 -0.002567 + 1454 -0.001180 -0.009011 0.018662 + 1455 -0.000958 -0.004899 0.013723 + 1456 0.000545 0.011919 -0.001753 + 1457 0.023799 0.010298 -0.002649 + 1458 0.014717 0.007757 -0.005400 + 1459 -0.004576 -0.007691 0.001365 + 1460 -0.006577 -0.016846 -0.022862 + 1461 -0.005206 0.003687 0.012428 + 1462 0.001923 -0.004758 -0.001993 + 1463 0.006600 0.017503 0.006935 + 1464 -0.006747 -0.003482 -0.000067 + 1465 0.000613 0.004580 0.004038 + 1466 -0.001945 0.022605 -0.000652 + 1467 0.017624 -0.001392 0.003829 + 1468 -0.003065 -0.003003 -0.000747 + 1469 -0.012664 -0.016566 -0.007030 + 1470 0.008660 -0.008358 0.004763 + 1471 -0.004008 0.000421 -0.006040 + 1472 0.003555 0.008566 -0.015842 + 1473 -0.001032 0.001700 -0.010204 + 1474 -0.000556 0.000599 0.003074 + 1475 0.001542 0.002939 0.005269 + 1476 -0.005281 -0.001944 0.003338 + 1477 -0.000195 -0.000293 -0.001004 + 1478 -0.009991 -0.005354 -0.013386 + 1479 -0.000476 -0.017594 0.007900 + 1480 0.000550 -0.000431 0.001422 + 1481 0.018094 -0.005183 0.016234 + 1482 0.010706 0.011668 -0.017772 + 1483 0.001291 0.006499 0.000951 + 1484 0.009985 -0.016962 0.009714 + 1485 0.020849 0.018365 -0.008351 + 1486 0.006940 0.004692 -0.002409 + 1487 0.022308 0.010182 -0.022897 + 1488 0.000269 0.008847 0.011834 + 1489 0.002051 0.007334 -0.000125 + 1490 -0.023048 0.013759 -0.030276 + 1491 0.023523 -0.005817 0.007754 + 1492 -0.001269 0.002979 0.001311 + 1493 -0.005596 0.006174 0.011007 + 1494 -0.009061 0.022719 0.002133 + 1495 -0.001128 0.004307 -0.002381 + 1496 -0.004340 0.013891 -0.003505 + 1497 0.001822 -0.005505 -0.001135 + 1498 -0.000910 0.001437 0.000165 + 1499 0.004510 -0.000360 -0.006425 + 1500 0.003993 0.000498 0.007321 + 1501 -0.002868 -0.000316 -0.000509 + 1502 0.000620 0.011286 0.008461 + 1503 -0.013079 -0.008157 0.007561 + 1504 -0.003002 0.003413 0.004968 + 1505 0.015262 -0.005133 0.012052 + 1506 -0.003968 -0.003643 0.003514 + 1507 0.005087 -0.001882 -0.000518 + 1508 0.000932 -0.002238 0.000800 + 1509 -0.008149 0.000695 -0.000827 + 1510 -0.001261 -0.003375 0.000333 + 1511 -0.001224 -0.004135 -0.003080 + 1512 0.009246 -0.010372 0.026354 + 1513 0.000697 -0.003200 0.001222 + 1514 -0.002319 0.003800 0.022860 + 1515 -0.018205 0.011600 -0.011416 + 1516 -0.001731 -0.001076 0.002612 + 1517 -0.004661 -0.010783 -0.001505 + 1518 0.016208 0.002810 0.004482 + 1519 0.003508 -0.001750 0.002537 + 1520 0.024576 -0.026041 -0.004083 + 1521 -0.019140 0.000844 0.001909 + 1522 -0.000341 0.001152 0.001967 + 1523 -0.020076 0.003364 0.001315 + 1524 -0.000942 0.000692 -0.003283 + 1525 -0.006519 -0.000419 0.000991 + 1526 -0.004033 0.006531 0.004791 + 1527 0.005626 0.012187 -0.014266 + 1528 0.001113 -0.004253 0.011930 + 1529 -0.010144 0.003567 0.009059 + 1530 -0.003464 0.001115 0.011591 + 1531 0.000006 0.000074 0.005751 + 1532 0.003604 0.008464 0.010627 + 1533 -0.004351 -0.009621 -0.000453 + 1534 -0.000196 -0.001160 0.002795 + 1535 -0.006855 0.001414 0.005552 + 1536 -0.000894 -0.002102 0.005053 + 1537 -0.002040 -0.005887 -0.003590 + 1538 -0.006852 -0.011947 -0.023080 + 1539 -0.016070 0.000160 0.010390 + 1540 0.004712 0.002848 -0.002998 + 1541 -0.004259 0.007840 0.008142 + 1542 -0.004861 0.004263 0.011728 + 1543 0.006968 -0.004871 0.004119 + 1544 -0.016558 -0.002046 -0.006090 + 1545 -0.006229 0.004475 0.001436 + 1546 -0.002341 -0.004733 -0.003946 + 1547 0.003563 0.004733 0.009615 + 1548 -0.013018 0.004747 -0.004733 + 1549 0.001703 -0.000331 0.003605 + 1550 0.005459 -0.002653 -0.012447 + 1551 0.013689 0.008625 -0.003301 + 1552 0.003195 0.001205 -0.000779 + 1553 -0.003336 -0.011439 -0.004979 + 1554 0.001015 0.018568 -0.007361 + 1555 -0.001647 -0.003759 0.001214 + 1556 0.015583 -0.016961 0.000384 + 1557 -0.011138 -0.013161 -0.015913 + 1558 0.005848 -0.002193 -0.007682 + 1559 0.009577 -0.005765 0.010025 + 1560 0.006984 0.005858 -0.020668 + 1561 -0.005040 0.001396 0.001932 + 1562 0.007071 0.009231 0.007700 + 1563 0.001743 0.005137 0.005850 + 1564 0.001857 0.002145 -0.004455 + 1565 -0.007462 0.014047 -0.012730 + 1566 0.013730 -0.006385 0.009586 + 1567 -0.002000 0.003453 -0.001882 + 1568 -0.009622 -0.007424 -0.003371 + 1569 -0.006993 -0.018224 -0.006858 + 1570 0.001461 0.001281 -0.002568 + 1571 0.018901 0.002357 0.001811 + 1572 -0.001592 0.019333 -0.002732 + 1573 -0.001308 -0.005730 -0.002519 + 1574 -0.014074 0.007287 0.021518 + 1575 -0.017324 -0.018775 -0.005647 + 1576 0.002340 -0.001593 0.004994 + 1577 -0.000516 0.003608 0.002676 + 1578 -0.014840 -0.017283 -0.001508 + 1579 -0.001557 -0.002471 -0.002555 + 1580 0.016654 -0.033672 0.006595 + 1581 0.013351 -0.030070 0.003443 + 1582 0.003752 0.001449 0.001862 + 1583 -0.011257 -0.002704 0.007355 + 1584 0.002139 0.006577 0.012771 + 1585 0.002251 0.002492 -0.002180 + 1586 0.010691 -0.005615 -0.001517 + 1587 -0.018738 0.016070 0.006914 + 1588 -0.001600 0.000180 0.001378 + 1589 0.004891 -0.007732 -0.013906 + 1590 -0.015149 0.011285 0.002913 + 1591 0.003944 -0.001162 -0.002407 + 1592 -0.013220 -0.006427 -0.006873 + 1593 -0.008388 0.022805 -0.011588 + 1594 0.000621 -0.004836 0.005509 + 1595 0.006148 -0.013451 0.002326 + 1596 -0.001161 -0.012639 -0.002024 + 1597 -0.005042 0.000613 0.003072 + 1598 -0.002560 -0.009516 -0.007164 + 1599 -0.007736 0.003315 0.007824 + 1600 -0.002409 -0.002549 -0.003082 + 1601 -0.002839 0.004415 -0.008830 + 1602 -0.006633 -0.001003 -0.004060 + 1603 -0.004810 -0.007495 -0.004047 + 1604 0.005200 -0.017270 0.009101 + 1605 0.000670 -0.009280 -0.012848 + 1606 -0.003830 0.001924 -0.002728 + 1607 -0.035525 0.007821 -0.020602 + 1608 0.016575 -0.019547 -0.006176 + 1609 0.003828 0.000099 -0.002605 + 1610 0.017387 0.007652 0.014875 + 1611 0.012190 0.014852 0.016071 + 1612 -0.003436 0.002187 -0.001035 + 1613 -0.005586 -0.003901 0.006033 + 1614 -0.005884 -0.005331 -0.011796 + 1615 -0.001799 -0.005019 0.004011 + 1616 0.002094 -0.028579 0.008471 + 1617 0.023334 0.020189 0.016696 + 1618 -0.000653 -0.003079 -0.001689 + 1619 -0.005925 -0.004542 -0.007489 + 1620 0.003980 0.000361 0.005598 + 1621 -0.000999 0.004025 -0.003724 + 1622 0.000058 0.024442 0.006515 + 1623 0.011473 -0.013431 0.004073 + 1624 0.002923 -0.003314 0.001931 + 1625 0.003377 -0.006029 -0.008704 + 1626 0.002413 0.015094 0.010447 + 1627 0.003654 -0.000619 -0.001261 + 1628 -0.004232 -0.000930 0.001384 + 1629 0.019160 0.000313 -0.006734 + 1630 0.003534 0.002394 -0.000501 + 1631 -0.008068 0.002953 0.008451 + 1632 0.014612 0.006975 -0.004278 + 1633 0.001620 0.003004 0.003226 + 1634 -0.007605 -0.007788 0.011245 + 1635 0.020296 -0.014907 -0.003043 + 1636 -0.002678 -0.006261 0.001869 + 1637 -0.007968 -0.013586 -0.003793 + 1638 -0.015202 -0.007224 -0.014352 + 1639 -0.005816 -0.003019 0.006480 + 1640 -0.001607 -0.004084 0.006246 + 1641 0.008520 -0.008049 0.002824 + 1642 -0.000658 -0.004008 -0.000300 + 1643 -0.000444 0.000650 -0.012168 + 1644 -0.006399 -0.006883 0.005254 + 1645 -0.001317 0.006093 0.001522 + 1646 -0.010770 -0.004270 -0.010989 + 1647 -0.005520 0.020979 0.012203 + 1648 -0.004763 0.001957 0.003649 + 1649 -0.010531 0.001095 0.022741 + 1650 0.001695 -0.009764 -0.029750 + 1651 0.000561 0.003660 0.004562 + 1652 0.004814 -0.011887 -0.011791 + 1653 0.015151 -0.017660 -0.020515 + 1654 -0.003720 -0.008154 0.002101 + 1655 -0.006836 0.005342 0.006830 + 1656 -0.008891 -0.005752 0.002656 + 1657 -0.004211 -0.006534 0.001470 + 1658 0.024344 -0.009232 0.001415 + 1659 -0.010793 -0.032076 -0.013330 + 1660 -0.000393 0.010082 -0.000260 + 1661 -0.003386 0.024037 -0.002341 + 1662 0.005231 -0.007154 0.002310 + 1663 0.004778 0.000685 -0.001247 + 1664 0.006845 -0.000146 -0.002439 + 1665 0.002831 0.001509 -0.001312 + 1666 -0.004575 0.002015 0.002231 + 1667 -0.008714 0.004773 0.019310 + 1668 -0.009036 0.006437 0.017025 + 1669 -0.001102 -0.003004 0.003294 + 1670 0.004690 0.016121 0.007181 + 1671 -0.000881 -0.003815 0.001639 + 1672 -0.000053 -0.001708 0.002633 + 1673 -0.004620 0.003536 0.000715 + 1674 -0.002636 -0.005429 0.007498 + 1675 0.002307 0.001406 0.002665 + 1676 -0.005270 -0.001969 0.007587 + 1677 0.001417 -0.009022 -0.021912 + 1678 0.000203 0.002930 -0.002177 + 1679 0.003819 0.012652 -0.002939 + 1680 -0.001040 0.005171 0.022221 + 1681 -0.001765 0.004140 -0.001020 + 1682 0.015888 -0.002384 -0.000464 + 1683 -0.019573 0.014814 -0.003047 + 1684 -0.002840 -0.000626 0.000097 + 1685 0.019011 -0.004434 -0.031132 + 1686 -0.011722 0.011711 0.019623 + 1687 -0.000720 0.008278 0.001232 + 1688 -0.000014 -0.005707 0.005722 + 1689 0.006445 -0.004607 0.004541 + 1690 -0.008451 -0.005406 -0.003097 + 1691 -0.025859 -0.004092 0.011942 + 1692 0.003198 0.017013 -0.015979 + 1693 0.001237 0.005482 0.001012 + 1694 -0.003233 0.012773 -0.012817 + 1695 -0.013658 -0.008102 0.007350 + 1696 0.004867 0.002547 -0.001769 + 1697 0.019074 -0.004173 0.005165 + 1698 0.008487 0.001064 0.000080 + 1699 0.002766 -0.001251 -0.001561 + 1700 -0.019200 0.027169 -0.007481 + 1701 0.006036 -0.028485 -0.009388 + 1702 -0.005460 0.002563 0.001784 + 1703 -0.017462 0.006398 0.005231 + 1704 -0.014453 0.005484 0.004388 + 1705 0.002956 -0.001348 0.006512 + 1706 0.009654 0.004653 0.025184 + 1707 0.006226 -0.001478 -0.018062 + 1708 0.003757 -0.000921 -0.000401 + 1709 0.004307 -0.009700 -0.007768 + 1710 0.003780 -0.012914 0.008582 + 1711 0.004846 -0.002032 -0.000808 + 1712 -0.000823 -0.002500 -0.004619 + 1713 0.014769 -0.010350 0.008970 + 1714 -0.001580 -0.000837 0.000021 + 1715 -0.002003 -0.002972 -0.000158 + 1716 -0.004469 -0.000404 0.001257 + 1717 -0.001782 0.001231 -0.003624 + 1718 -0.009550 0.008477 -0.006010 + 1719 -0.003240 -0.001801 -0.002707 + 1720 -0.003131 -0.002749 -0.002782 + 1721 -0.003319 -0.008008 -0.009572 + 1722 -0.003280 -0.008289 -0.009069 + 1723 -0.006776 0.001807 0.000809 + 1724 0.000630 0.005359 0.003033 + 1725 0.016012 0.013546 0.014364 + 1726 -0.005383 0.003683 -0.001052 + 1727 -0.000343 -0.021814 -0.000655 + 1728 0.015975 0.004809 -0.015863 + 1729 -0.002843 0.002136 0.000031 + 1730 0.008511 0.002265 -0.002748 + 1731 -0.026285 -0.002274 -0.004757 + 1732 0.005294 -0.003565 0.004694 + 1733 -0.002668 0.001103 -0.001112 + 1734 -0.009429 0.006969 -0.008965 + 1735 -0.001634 0.000110 0.001819 + 1736 -0.004942 0.001203 -0.007254 + 1737 -0.002655 0.002573 -0.003610 + 1738 -0.004831 0.005860 0.001407 + 1739 -0.014232 0.009476 0.016389 + 1740 -0.017895 0.005674 -0.009379 + 1741 0.003013 -0.002508 -0.001228 + 1742 0.000746 0.006449 -0.005992 + 1743 0.006650 -0.002762 0.000152 + 1744 0.002550 -0.008457 0.001324 + 1745 -0.001868 -0.010233 -0.023525 + 1746 0.003968 -0.007880 0.008439 + 1747 -0.000591 0.004322 -0.003592 + 1748 -0.014424 0.009132 0.003708 + 1749 0.012052 -0.004950 -0.011581 + 1750 0.001849 0.003842 -0.009164 + 1751 0.009453 -0.005684 -0.004817 + 1752 0.001564 0.018776 -0.004831 + 1753 0.000794 0.000968 -0.001710 + 1754 -0.003816 -0.004723 -0.000498 + 1755 -0.011972 0.005633 -0.006975 + 1756 -0.004635 0.005064 -0.004764 + 1757 -0.010722 0.012077 -0.027297 + 1758 -0.003376 0.000707 0.006078 + 1759 0.001092 0.005159 -0.000557 + 1760 0.014326 0.002844 -0.021424 + 1761 0.019579 -0.002405 -0.009532 + 1762 -0.000565 0.006632 0.002294 + 1763 -0.025047 0.006219 0.001583 + 1764 -0.004637 -0.007484 0.007079 + 1765 0.002563 -0.001616 -0.003316 + 1766 -0.001239 0.014897 -0.002355 + 1767 -0.001256 -0.009226 0.009450 + 1768 0.001056 0.005329 -0.003831 + 1769 -0.012555 0.037676 0.021233 + 1770 -0.005969 -0.003116 -0.014248 + 1771 0.000691 0.001302 0.002405 + 1772 -0.015733 0.001224 -0.004288 + 1773 0.006783 0.015986 -0.003342 + 1774 0.002355 0.002897 -0.002965 + 1775 -0.000435 0.005789 0.007980 + 1776 0.014211 0.000855 -0.014841 + 1777 -0.004596 -0.002169 0.000774 + 1778 0.002630 -0.027237 0.012553 + 1779 -0.000727 -0.003394 -0.009924 + 1780 0.001821 -0.001310 0.000540 + 1781 0.005476 -0.002057 0.001588 + 1782 0.008060 0.013457 -0.013767 + 1783 0.003078 -0.007047 0.009501 + 1784 -0.004392 -0.004982 0.015684 + 1785 -0.021173 -0.003917 -0.003013 + 1786 0.001492 -0.007162 -0.003460 + 1787 0.020179 0.025050 0.005018 + 1788 -0.018378 -0.021938 0.007656 + 1789 -0.000363 0.004076 -0.003991 + 1790 0.012179 0.023942 -0.003853 + 1791 0.002207 0.011773 0.006443 + 1792 0.001993 0.000538 0.002365 + 1793 0.008602 -0.013779 -0.007218 + 1794 0.007374 0.001122 0.001108 + 1795 0.003207 -0.011319 -0.004081 + 1796 0.010332 -0.007827 -0.001929 + 1797 0.001869 0.022609 0.012256 + 1798 0.001101 0.003835 0.002357 + 1799 -0.003624 0.011759 0.002745 + 1800 0.001557 -0.002337 -0.004179 + 1801 0.003327 -0.001910 -0.005250 + 1802 0.011996 0.003017 0.013309 + 1803 -0.013682 -0.002775 -0.008939 + 1804 -0.002064 -0.000934 0.000427 + 1805 -0.012146 0.024406 -0.015171 + 1806 0.005030 -0.019570 0.004311 + 1807 0.003003 0.004365 0.002257 + 1808 0.000823 0.000086 -0.005161 + 1809 -0.003001 0.001206 0.008241 + 1810 0.005602 -0.001423 0.002945 + 1811 0.000330 0.001483 -0.011075 + 1812 0.003652 0.009252 -0.000166 + 1813 0.004531 -0.000860 -0.000170 + 1814 0.018728 0.013621 0.031510 + 1815 0.011579 -0.009257 -0.004100 + 1816 0.002862 0.000330 -0.002342 + 1817 -0.003456 -0.001426 -0.004566 + 1818 -0.006589 0.018593 0.018322 + 1819 -0.001663 0.002113 0.003120 + 1820 0.002523 0.005185 0.010725 + 1821 -0.006456 -0.005159 0.018366 + 1822 -0.000677 -0.000638 0.005530 + 1823 0.006499 0.011396 0.003392 + 1824 0.000945 -0.008826 -0.007441 + 1825 -0.002582 0.001006 0.000170 + 1826 -0.000739 0.010378 -0.012944 + 1827 -0.004082 -0.009693 0.012271 + 1828 -0.002259 -0.002179 0.001812 + 1829 0.004365 0.028602 0.007523 + 1830 -0.001047 0.006781 -0.010318 + 1831 0.003053 0.002227 0.004523 + 1832 -0.004297 -0.007295 0.001900 + 1833 0.002925 0.002066 0.004473 + 1834 0.003171 0.000025 0.002189 + 1835 0.001188 0.002838 0.001014 + 1836 0.006142 0.003073 -0.003689 + 1837 0.009818 0.005253 0.006222 + 1838 0.013907 -0.003607 0.006764 + 1839 -0.000327 0.015573 -0.010930 + 1840 -0.003110 -0.005538 0.000400 + 1841 0.006244 -0.021206 -0.003853 + 1842 -0.010299 0.008474 0.021147 + 1843 -0.001053 -0.000598 0.004581 + 1844 -0.013621 0.002557 -0.003175 + 1845 -0.002495 0.000789 0.011106 + 1846 -0.000137 -0.004006 -0.000014 + 1847 -0.017819 -0.013981 0.011316 + 1848 -0.005844 -0.000863 -0.025248 + 1849 -0.002799 0.002996 -0.002499 + 1850 -0.012455 0.012490 -0.004469 + 1851 0.010514 0.009490 -0.009495 + 1852 -0.000560 -0.004144 -0.000656 + 1853 -0.007255 0.002559 0.003817 + 1854 0.004602 -0.007276 0.003469 + 1855 0.000128 0.001144 -0.008402 + 1856 0.008157 0.001721 -0.014464 + 1857 -0.004034 0.002739 -0.008982 + 1858 0.002856 0.004731 -0.003812 + 1859 0.008481 -0.004184 -0.015612 + 1860 -0.004966 0.006658 -0.006541 + 1861 0.005415 -0.007185 0.002622 + 1862 -0.000791 0.004294 0.012806 + 1863 0.006266 -0.008943 0.000048 + 1864 -0.004891 -0.000259 0.002435 + 1865 0.000775 -0.012600 0.009738 + 1866 -0.000239 0.020688 0.014963 + 1867 0.007752 0.006605 0.003522 + 1868 0.005559 0.005449 0.004823 + 1869 0.001382 0.020031 -0.009484 + 1870 0.000269 -0.000837 -0.001948 + 1871 -0.015324 0.006379 0.032972 + 1872 -0.010895 -0.006739 0.002233 + 1873 0.002406 -0.005817 -0.007929 + 1874 0.011974 0.013774 0.020789 + 1875 -0.005616 -0.012309 -0.023698 + 1876 -0.002712 -0.000118 0.000894 + 1877 -0.000559 -0.018665 -0.005699 + 1878 -0.022904 -0.016730 0.007620 + 1879 -0.006235 -0.000119 -0.005440 + 1880 -0.008616 0.001720 0.002602 + 1881 -0.019263 0.001295 0.018377 + 1882 -0.002493 0.002824 -0.002915 + 1883 0.007384 0.000692 0.003462 + 1884 -0.019228 -0.005451 0.005676 + 1885 0.002956 0.004628 -0.002177 + 1886 0.005617 0.021792 -0.005623 + 1887 -0.010771 -0.007154 -0.002600 + 1888 -0.006932 -0.006388 0.001795 + 1889 -0.026638 0.002211 0.017012 + 1890 -0.006429 -0.013703 0.021233 + 1891 0.004179 0.001508 -0.002942 + 1892 -0.015358 0.009799 -0.025507 + 1893 -0.009827 0.001263 -0.015038 + 1894 0.002515 0.004808 -0.006083 + 1895 -0.001395 -0.005178 0.010798 + 1896 0.005498 0.001296 -0.013456 + 1897 -0.006679 0.000004 0.000833 + 1898 -0.006339 0.003210 0.000555 + 1899 -0.007815 -0.000155 0.006317 + 1900 -0.003334 -0.000730 -0.000139 + 1901 -0.003197 -0.021225 -0.009098 + 1902 0.003310 -0.008203 -0.004863 + 1903 -0.007379 0.001152 -0.003847 + 1904 -0.008175 0.003836 -0.004939 + 1905 -0.007216 0.002039 -0.012076 + 1906 -0.002751 -0.006050 -0.001404 + 1907 -0.005827 0.008129 0.005351 + 1908 0.010377 0.010628 0.018761 + 1909 -0.002571 -0.007065 0.006215 + 1910 -0.004848 -0.014622 0.001577 + 1911 -0.004351 -0.002361 0.020679 + 1912 0.006139 0.001291 0.002464 + 1913 0.004939 0.003608 0.002097 + 1914 0.004274 0.000152 0.002451 + 1915 0.002989 0.000832 -0.000352 + 1916 -0.014159 -0.000914 0.002187 + 1917 0.012237 -0.003167 0.009134 + 1918 -0.004575 -0.001662 0.000082 + 1919 -0.007883 -0.002056 0.002571 + 1920 -0.003336 -0.001305 -0.000658 + 1921 0.004366 0.000439 0.001158 + 1922 -0.000155 0.003368 0.010592 + 1923 -0.014972 -0.009424 -0.018312 + 1924 -0.000613 -0.002374 0.000797 + 1925 0.007460 -0.016336 -0.000977 + 1926 -0.006787 0.004573 0.010255 + 1927 -0.002452 -0.000122 0.000124 + 1928 -0.015584 -0.009431 -0.007285 + 1929 -0.000101 0.008080 -0.015191 + 1930 0.002197 0.002310 -0.001612 + 1931 0.016237 -0.005090 0.018070 + 1932 0.001709 -0.003220 -0.011865 + 1933 -0.001150 0.000898 0.004173 + 1934 0.000323 -0.000312 -0.014495 + 1935 0.000516 -0.000491 -0.011422 + 1936 -0.005815 -0.002965 0.000187 + 1937 0.008195 0.018425 -0.027236 + 1938 -0.010921 -0.007575 -0.002217 + 1939 -0.004740 0.002745 0.006330 + 1940 0.002035 0.006523 0.010880 + 1941 -0.012191 0.004818 0.006605 + 1942 -0.003197 -0.004418 -0.003375 + 1943 0.003590 -0.017196 0.008070 + 1944 0.004548 0.006106 0.016045 + 1945 0.005444 0.002200 0.004561 + 1946 0.004448 0.009092 -0.001577 + 1947 -0.000522 0.006033 0.006559 + 1948 0.005450 0.001267 0.002269 + 1949 0.027952 -0.012604 0.001935 + 1950 -0.004826 -0.018174 0.014813 + 1951 0.005498 -0.000626 0.001156 + 1952 0.001428 -0.010472 0.000805 + 1953 -0.010198 -0.005573 -0.014564 + 1954 0.001605 -0.006572 0.005587 + 1955 -0.002403 -0.004981 0.000460 + 1956 0.010287 -0.003414 0.005774 + 1957 -0.005679 0.003540 -0.003175 + 1958 -0.005054 0.005203 -0.002733 + 1959 -0.006462 0.003843 0.002657 + 1960 -0.006606 -0.002499 -0.001538 + 1961 0.027567 -0.002565 0.034908 + 1962 0.001905 -0.003739 -0.001134 + 1963 -0.000871 0.002779 0.006534 + 1964 -0.013473 -0.002631 0.001200 + 1965 -0.008136 0.003625 0.001725 + 1966 0.002375 -0.002767 -0.000214 + 1967 0.015603 0.001192 0.006785 + 1968 -0.008229 0.002751 0.010337 + 1969 -0.002111 -0.006139 0.006236 + 1970 0.025783 -0.003684 0.015052 + 1971 -0.008026 -0.018580 0.028847 + 1972 -0.001966 -0.005103 0.002533 + 1973 0.025504 -0.012928 0.014439 + 1974 0.015919 0.008653 -0.013047 + 1975 -0.002145 -0.003853 -0.002353 + 1976 0.020573 0.023626 0.033600 + 1977 0.002418 -0.000127 0.000258 + 1978 -0.000168 -0.002747 0.002505 + 1979 0.011847 0.007945 0.003222 + 1980 0.002222 -0.001343 0.005437 + 1981 -0.004734 0.003071 -0.000955 + 1982 0.003752 -0.001882 -0.005052 + 1983 -0.008195 0.007844 0.004577 + 1984 0.007575 0.002209 -0.000466 + 1985 -0.005510 0.009650 -0.004399 + 1986 0.018263 0.019292 -0.008157 + 1987 -0.005098 -0.001581 -0.000328 + 1988 -0.004522 -0.021884 -0.005509 + 1989 -0.001598 -0.001668 0.002704 + 1990 -0.000494 0.002205 0.012458 + 1991 0.003153 0.001522 0.015672 + 1992 -0.000092 -0.002603 0.010098 + 1993 0.001919 -0.007389 0.001539 + 1994 -0.002690 -0.003376 -0.009963 + 1995 -0.005006 0.002932 -0.001670 + 1996 -0.003089 -0.005736 0.003689 + 1997 0.010713 -0.027613 -0.023000 + 1998 -0.006878 0.009457 0.006998 + 1999 -0.001817 0.000266 -0.004238 + 2000 -0.010974 0.005190 0.000117 + 2001 -0.008937 -0.003277 0.004337 + 2002 -0.000987 -0.001334 -0.004265 + 2003 -0.022280 -0.011677 -0.018343 + 2004 -0.010076 -0.005729 -0.026032 + +Bonds + + 1 3 1 7 + 2 2 1 3 + 3 1 1 2 + 4 4 2 5 + 5 4 2 6 + 6 4 2 4 + 7 6 7 19 + 8 5 7 8 + 9 1 8 9 + 10 7 8 11 + 11 8 8 20 + 12 3 9 28 + 13 2 9 10 + 14 10 11 21 + 15 9 11 12 + 16 10 11 22 + 17 11 12 14 + 18 11 12 13 + 19 12 13 23 + 20 11 13 15 + 21 12 14 24 + 22 11 14 16 + 23 11 15 17 + 24 12 15 25 + 25 11 16 17 + 26 12 16 26 + 27 13 17 18 + 28 14 18 27 + 29 5 28 29 + 30 6 28 32 + 31 1 29 30 + 32 8 29 33 + 33 8 29 34 + 34 3 30 35 + 35 2 30 31 + 36 5 35 36 + 37 6 35 39 + 38 1 36 37 + 39 8 36 40 + 40 8 36 41 + 41 2 37 38 + 42 3 37 42 + 43 6 42 53 + 44 5 42 43 + 45 1 43 44 + 46 7 43 46 + 47 8 43 54 + 48 3 44 62 + 49 2 44 45 + 50 10 46 56 + 51 10 46 55 + 52 9 46 47 + 53 11 47 48 + 54 11 47 49 + 55 11 48 50 + 56 12 48 57 + 57 11 49 51 + 58 12 49 58 + 59 11 50 52 + 60 12 50 59 + 61 11 51 52 + 62 12 51 60 + 63 12 52 61 + 64 6 62 70 + 65 5 62 63 + 66 7 63 66 + 67 1 63 64 + 68 8 63 71 + 69 2 64 65 + 70 3 64 79 + 71 15 66 67 + 72 10 66 73 + 73 10 66 72 + 74 10 67 75 + 75 10 67 74 + 76 16 67 68 + 77 17 68 69 + 78 4 69 76 + 79 4 69 78 + 80 4 69 77 + 81 5 79 80 + 82 6 79 81 + 83 4 80 84 + 84 4 80 83 + 85 4 80 82 + 86 18 85 86 + 87 18 85 87 + 88 18 88 90 + 89 18 88 89 + 90 18 91 93 + 91 18 91 92 + 92 18 94 96 + 93 18 94 95 + 94 18 97 98 + 95 18 97 99 + 96 18 100 101 + 97 18 100 102 + 98 18 103 104 + 99 18 103 105 + 100 18 106 107 + 101 18 106 108 + 102 18 109 111 + 103 18 109 110 + 104 18 112 114 + 105 18 112 113 + 106 18 115 116 + 107 18 115 117 + 108 18 118 120 + 109 18 118 119 + 110 18 121 123 + 111 18 121 122 + 112 18 124 126 + 113 18 124 125 + 114 18 127 128 + 115 18 127 129 + 116 18 130 132 + 117 18 130 131 + 118 18 133 134 + 119 18 133 135 + 120 18 136 137 + 121 18 136 138 + 122 18 139 140 + 123 18 139 141 + 124 18 142 144 + 125 18 142 143 + 126 18 145 147 + 127 18 145 146 + 128 18 148 150 + 129 18 148 149 + 130 18 151 152 + 131 18 151 153 + 132 18 154 156 + 133 18 154 155 + 134 18 157 159 + 135 18 157 158 + 136 18 160 162 + 137 18 160 161 + 138 18 163 164 + 139 18 163 165 + 140 18 166 168 + 141 18 166 167 + 142 18 169 171 + 143 18 169 170 + 144 18 172 174 + 145 18 172 173 + 146 18 175 177 + 147 18 175 176 + 148 18 178 180 + 149 18 178 179 + 150 18 181 182 + 151 18 181 183 + 152 18 184 186 + 153 18 184 185 + 154 18 187 188 + 155 18 187 189 + 156 18 190 191 + 157 18 190 192 + 158 18 193 194 + 159 18 193 195 + 160 18 196 197 + 161 18 196 198 + 162 18 199 201 + 163 18 199 200 + 164 18 202 204 + 165 18 202 203 + 166 18 205 206 + 167 18 205 207 + 168 18 208 210 + 169 18 208 209 + 170 18 211 212 + 171 18 211 213 + 172 18 214 215 + 173 18 214 216 + 174 18 217 219 + 175 18 217 218 + 176 18 220 222 + 177 18 220 221 + 178 18 223 224 + 179 18 223 225 + 180 18 226 228 + 181 18 226 227 + 182 18 229 231 + 183 18 229 230 + 184 18 232 233 + 185 18 232 234 + 186 18 235 236 + 187 18 235 237 + 188 18 238 240 + 189 18 238 239 + 190 18 241 242 + 191 18 241 243 + 192 18 244 246 + 193 18 244 245 + 194 18 247 248 + 195 18 247 249 + 196 18 250 251 + 197 18 250 252 + 198 18 253 254 + 199 18 253 255 + 200 18 256 257 + 201 18 256 258 + 202 18 259 261 + 203 18 259 260 + 204 18 262 264 + 205 18 262 263 + 206 18 265 266 + 207 18 265 267 + 208 18 268 269 + 209 18 268 270 + 210 18 271 272 + 211 18 271 273 + 212 18 274 275 + 213 18 274 276 + 214 18 277 279 + 215 18 277 278 + 216 18 280 282 + 217 18 280 281 + 218 18 283 284 + 219 18 283 285 + 220 18 286 287 + 221 18 286 288 + 222 18 289 290 + 223 18 289 291 + 224 18 292 294 + 225 18 292 293 + 226 18 295 296 + 227 18 295 297 + 228 18 298 299 + 229 18 298 300 + 230 18 301 303 + 231 18 301 302 + 232 18 304 305 + 233 18 304 306 + 234 18 307 309 + 235 18 307 308 + 236 18 310 311 + 237 18 310 312 + 238 18 313 314 + 239 18 313 315 + 240 18 316 317 + 241 18 316 318 + 242 18 319 321 + 243 18 319 320 + 244 18 322 323 + 245 18 322 324 + 246 18 325 327 + 247 18 325 326 + 248 18 328 329 + 249 18 328 330 + 250 18 331 332 + 251 18 331 333 + 252 18 334 335 + 253 18 334 336 + 254 18 337 339 + 255 18 337 338 + 256 18 340 341 + 257 18 340 342 + 258 18 343 344 + 259 18 343 345 + 260 18 346 347 + 261 18 346 348 + 262 18 349 350 + 263 18 349 351 + 264 18 352 353 + 265 18 352 354 + 266 18 355 356 + 267 18 355 357 + 268 18 358 359 + 269 18 358 360 + 270 18 361 362 + 271 18 361 363 + 272 18 364 365 + 273 18 364 366 + 274 18 367 369 + 275 18 367 368 + 276 18 370 372 + 277 18 370 371 + 278 18 373 374 + 279 18 373 375 + 280 18 376 378 + 281 18 376 377 + 282 18 379 381 + 283 18 379 380 + 284 18 382 383 + 285 18 382 384 + 286 18 385 386 + 287 18 385 387 + 288 18 388 390 + 289 18 388 389 + 290 18 391 393 + 291 18 391 392 + 292 18 394 395 + 293 18 394 396 + 294 18 397 399 + 295 18 397 398 + 296 18 400 402 + 297 18 400 401 + 298 18 403 405 + 299 18 403 404 + 300 18 406 407 + 301 18 406 408 + 302 18 409 411 + 303 18 409 410 + 304 18 412 413 + 305 18 412 414 + 306 18 415 417 + 307 18 415 416 + 308 18 418 420 + 309 18 418 419 + 310 18 421 422 + 311 18 421 423 + 312 18 424 425 + 313 18 424 426 + 314 18 427 428 + 315 18 427 429 + 316 18 430 432 + 317 18 430 431 + 318 18 433 435 + 319 18 433 434 + 320 18 436 437 + 321 18 436 438 + 322 18 439 440 + 323 18 439 441 + 324 18 442 443 + 325 18 442 444 + 326 18 445 447 + 327 18 445 446 + 328 18 448 449 + 329 18 448 450 + 330 18 451 453 + 331 18 451 452 + 332 18 454 456 + 333 18 454 455 + 334 18 457 458 + 335 18 457 459 + 336 18 460 462 + 337 18 460 461 + 338 18 463 465 + 339 18 463 464 + 340 18 466 467 + 341 18 466 468 + 342 18 469 470 + 343 18 469 471 + 344 18 472 473 + 345 18 472 474 + 346 18 475 476 + 347 18 475 477 + 348 18 478 479 + 349 18 478 480 + 350 18 481 482 + 351 18 481 483 + 352 18 484 485 + 353 18 484 486 + 354 18 487 489 + 355 18 487 488 + 356 18 490 492 + 357 18 490 491 + 358 18 493 495 + 359 18 493 494 + 360 18 496 497 + 361 18 496 498 + 362 18 499 501 + 363 18 499 500 + 364 18 502 503 + 365 18 502 504 + 366 18 505 507 + 367 18 505 506 + 368 18 508 509 + 369 18 508 510 + 370 18 511 513 + 371 18 511 512 + 372 18 514 516 + 373 18 514 515 + 374 18 517 518 + 375 18 517 519 + 376 18 520 521 + 377 18 520 522 + 378 18 523 525 + 379 18 523 524 + 380 18 526 528 + 381 18 526 527 + 382 18 529 530 + 383 18 529 531 + 384 18 532 533 + 385 18 532 534 + 386 18 535 536 + 387 18 535 537 + 388 18 538 540 + 389 18 538 539 + 390 18 541 542 + 391 18 541 543 + 392 18 544 546 + 393 18 544 545 + 394 18 547 549 + 395 18 547 548 + 396 18 550 551 + 397 18 550 552 + 398 18 553 555 + 399 18 553 554 + 400 18 556 557 + 401 18 556 558 + 402 18 559 561 + 403 18 559 560 + 404 18 562 563 + 405 18 562 564 + 406 18 565 567 + 407 18 565 566 + 408 18 568 570 + 409 18 568 569 + 410 18 571 573 + 411 18 571 572 + 412 18 574 575 + 413 18 574 576 + 414 18 577 579 + 415 18 577 578 + 416 18 580 581 + 417 18 580 582 + 418 18 583 585 + 419 18 583 584 + 420 18 586 588 + 421 18 586 587 + 422 18 589 590 + 423 18 589 591 + 424 18 592 594 + 425 18 592 593 + 426 18 595 597 + 427 18 595 596 + 428 18 598 600 + 429 18 598 599 + 430 18 601 602 + 431 18 601 603 + 432 18 604 606 + 433 18 604 605 + 434 18 607 609 + 435 18 607 608 + 436 18 610 611 + 437 18 610 612 + 438 18 613 615 + 439 18 613 614 + 440 18 616 618 + 441 18 616 617 + 442 18 619 620 + 443 18 619 621 + 444 18 622 623 + 445 18 622 624 + 446 18 625 627 + 447 18 625 626 + 448 18 628 629 + 449 18 628 630 + 450 18 631 632 + 451 18 631 633 + 452 18 634 635 + 453 18 634 636 + 454 18 637 639 + 455 18 637 638 + 456 18 640 642 + 457 18 640 641 + 458 18 643 644 + 459 18 643 645 + 460 18 646 647 + 461 18 646 648 + 462 18 649 650 + 463 18 649 651 + 464 18 652 653 + 465 18 652 654 + 466 18 655 657 + 467 18 655 656 + 468 18 658 660 + 469 18 658 659 + 470 18 661 663 + 471 18 661 662 + 472 18 664 665 + 473 18 664 666 + 474 18 667 669 + 475 18 667 668 + 476 18 670 672 + 477 18 670 671 + 478 18 673 674 + 479 18 673 675 + 480 18 676 677 + 481 18 676 678 + 482 18 679 681 + 483 18 679 680 + 484 18 682 684 + 485 18 682 683 + 486 18 685 686 + 487 18 685 687 + 488 18 688 690 + 489 18 688 689 + 490 18 691 693 + 491 18 691 692 + 492 18 694 695 + 493 18 694 696 + 494 18 697 698 + 495 18 697 699 + 496 18 700 701 + 497 18 700 702 + 498 18 703 704 + 499 18 703 705 + 500 18 706 707 + 501 18 706 708 + 502 18 709 710 + 503 18 709 711 + 504 18 712 714 + 505 18 712 713 + 506 18 715 716 + 507 18 715 717 + 508 18 718 719 + 509 18 718 720 + 510 18 721 722 + 511 18 721 723 + 512 18 724 726 + 513 18 724 725 + 514 18 727 728 + 515 18 727 729 + 516 18 730 731 + 517 18 730 732 + 518 18 733 735 + 519 18 733 734 + 520 18 736 737 + 521 18 736 738 + 522 18 739 741 + 523 18 739 740 + 524 18 742 743 + 525 18 742 744 + 526 18 745 746 + 527 18 745 747 + 528 18 748 750 + 529 18 748 749 + 530 18 751 753 + 531 18 751 752 + 532 18 754 756 + 533 18 754 755 + 534 18 757 758 + 535 18 757 759 + 536 18 760 762 + 537 18 760 761 + 538 18 763 764 + 539 18 763 765 + 540 18 766 767 + 541 18 766 768 + 542 18 769 770 + 543 18 769 771 + 544 18 772 774 + 545 18 772 773 + 546 18 775 777 + 547 18 775 776 + 548 18 778 780 + 549 18 778 779 + 550 18 781 783 + 551 18 781 782 + 552 18 784 786 + 553 18 784 785 + 554 18 787 789 + 555 18 787 788 + 556 18 790 791 + 557 18 790 792 + 558 18 793 795 + 559 18 793 794 + 560 18 796 797 + 561 18 796 798 + 562 18 799 801 + 563 18 799 800 + 564 18 802 803 + 565 18 802 804 + 566 18 805 806 + 567 18 805 807 + 568 18 808 809 + 569 18 808 810 + 570 18 811 813 + 571 18 811 812 + 572 18 814 815 + 573 18 814 816 + 574 18 817 818 + 575 18 817 819 + 576 18 820 821 + 577 18 820 822 + 578 18 823 824 + 579 18 823 825 + 580 18 826 828 + 581 18 826 827 + 582 18 829 830 + 583 18 829 831 + 584 18 832 834 + 585 18 832 833 + 586 18 835 837 + 587 18 835 836 + 588 18 838 839 + 589 18 838 840 + 590 18 841 842 + 591 18 841 843 + 592 18 844 845 + 593 18 844 846 + 594 18 847 848 + 595 18 847 849 + 596 18 850 852 + 597 18 850 851 + 598 18 853 854 + 599 18 853 855 + 600 18 856 858 + 601 18 856 857 + 602 18 859 861 + 603 18 859 860 + 604 18 862 863 + 605 18 862 864 + 606 18 865 866 + 607 18 865 867 + 608 18 868 869 + 609 18 868 870 + 610 18 871 873 + 611 18 871 872 + 612 18 874 875 + 613 18 874 876 + 614 18 877 878 + 615 18 877 879 + 616 18 880 882 + 617 18 880 881 + 618 18 883 884 + 619 18 883 885 + 620 18 886 887 + 621 18 886 888 + 622 18 889 891 + 623 18 889 890 + 624 18 892 894 + 625 18 892 893 + 626 18 895 896 + 627 18 895 897 + 628 18 898 899 + 629 18 898 900 + 630 18 901 903 + 631 18 901 902 + 632 18 904 905 + 633 18 904 906 + 634 18 907 908 + 635 18 907 909 + 636 18 910 911 + 637 18 910 912 + 638 18 913 915 + 639 18 913 914 + 640 18 916 917 + 641 18 916 918 + 642 18 919 920 + 643 18 919 921 + 644 18 922 924 + 645 18 922 923 + 646 18 925 927 + 647 18 925 926 + 648 18 928 930 + 649 18 928 929 + 650 18 931 932 + 651 18 931 933 + 652 18 934 935 + 653 18 934 936 + 654 18 937 939 + 655 18 937 938 + 656 18 940 942 + 657 18 940 941 + 658 18 943 945 + 659 18 943 944 + 660 18 946 948 + 661 18 946 947 + 662 18 949 950 + 663 18 949 951 + 664 18 952 953 + 665 18 952 954 + 666 18 955 956 + 667 18 955 957 + 668 18 958 960 + 669 18 958 959 + 670 18 961 963 + 671 18 961 962 + 672 18 964 965 + 673 18 964 966 + 674 18 967 969 + 675 18 967 968 + 676 18 970 972 + 677 18 970 971 + 678 18 973 975 + 679 18 973 974 + 680 18 976 978 + 681 18 976 977 + 682 18 979 981 + 683 18 979 980 + 684 18 982 983 + 685 18 982 984 + 686 18 985 987 + 687 18 985 986 + 688 18 988 989 + 689 18 988 990 + 690 18 991 993 + 691 18 991 992 + 692 18 994 996 + 693 18 994 995 + 694 18 997 998 + 695 18 997 999 + 696 18 1000 1001 + 697 18 1000 1002 + 698 18 1003 1005 + 699 18 1003 1004 + 700 18 1006 1007 + 701 18 1006 1008 + 702 18 1009 1011 + 703 18 1009 1010 + 704 18 1012 1013 + 705 18 1012 1014 + 706 18 1015 1017 + 707 18 1015 1016 + 708 18 1018 1020 + 709 18 1018 1019 + 710 18 1021 1023 + 711 18 1021 1022 + 712 18 1024 1025 + 713 18 1024 1026 + 714 18 1027 1028 + 715 18 1027 1029 + 716 18 1030 1032 + 717 18 1030 1031 + 718 18 1033 1034 + 719 18 1033 1035 + 720 18 1036 1037 + 721 18 1036 1038 + 722 18 1039 1041 + 723 18 1039 1040 + 724 18 1042 1043 + 725 18 1042 1044 + 726 18 1045 1046 + 727 18 1045 1047 + 728 18 1048 1050 + 729 18 1048 1049 + 730 18 1051 1053 + 731 18 1051 1052 + 732 18 1054 1056 + 733 18 1054 1055 + 734 18 1057 1058 + 735 18 1057 1059 + 736 18 1060 1062 + 737 18 1060 1061 + 738 18 1063 1064 + 739 18 1063 1065 + 740 18 1066 1068 + 741 18 1066 1067 + 742 18 1069 1071 + 743 18 1069 1070 + 744 18 1072 1074 + 745 18 1072 1073 + 746 18 1075 1077 + 747 18 1075 1076 + 748 18 1078 1079 + 749 18 1078 1080 + 750 18 1081 1082 + 751 18 1081 1083 + 752 18 1084 1085 + 753 18 1084 1086 + 754 18 1087 1089 + 755 18 1087 1088 + 756 18 1090 1092 + 757 18 1090 1091 + 758 18 1093 1095 + 759 18 1093 1094 + 760 18 1096 1097 + 761 18 1096 1098 + 762 18 1099 1100 + 763 18 1099 1101 + 764 18 1102 1103 + 765 18 1102 1104 + 766 18 1105 1107 + 767 18 1105 1106 + 768 18 1108 1110 + 769 18 1108 1109 + 770 18 1111 1112 + 771 18 1111 1113 + 772 18 1114 1116 + 773 18 1114 1115 + 774 18 1117 1119 + 775 18 1117 1118 + 776 18 1120 1121 + 777 18 1120 1122 + 778 18 1123 1124 + 779 18 1123 1125 + 780 18 1126 1128 + 781 18 1126 1127 + 782 18 1129 1130 + 783 18 1129 1131 + 784 18 1132 1133 + 785 18 1132 1134 + 786 18 1135 1137 + 787 18 1135 1136 + 788 18 1138 1140 + 789 18 1138 1139 + 790 18 1141 1142 + 791 18 1141 1143 + 792 18 1144 1146 + 793 18 1144 1145 + 794 18 1147 1149 + 795 18 1147 1148 + 796 18 1150 1152 + 797 18 1150 1151 + 798 18 1153 1155 + 799 18 1153 1154 + 800 18 1156 1158 + 801 18 1156 1157 + 802 18 1159 1160 + 803 18 1159 1161 + 804 18 1162 1164 + 805 18 1162 1163 + 806 18 1165 1166 + 807 18 1165 1167 + 808 18 1168 1170 + 809 18 1168 1169 + 810 18 1171 1172 + 811 18 1171 1173 + 812 18 1174 1175 + 813 18 1174 1176 + 814 18 1177 1179 + 815 18 1177 1178 + 816 18 1180 1182 + 817 18 1180 1181 + 818 18 1183 1185 + 819 18 1183 1184 + 820 18 1186 1187 + 821 18 1186 1188 + 822 18 1189 1190 + 823 18 1189 1191 + 824 18 1192 1194 + 825 18 1192 1193 + 826 18 1195 1196 + 827 18 1195 1197 + 828 18 1198 1199 + 829 18 1198 1200 + 830 18 1201 1202 + 831 18 1201 1203 + 832 18 1204 1205 + 833 18 1204 1206 + 834 18 1207 1209 + 835 18 1207 1208 + 836 18 1210 1212 + 837 18 1210 1211 + 838 18 1213 1214 + 839 18 1213 1215 + 840 18 1216 1218 + 841 18 1216 1217 + 842 18 1219 1221 + 843 18 1219 1220 + 844 18 1222 1224 + 845 18 1222 1223 + 846 18 1225 1226 + 847 18 1225 1227 + 848 18 1228 1229 + 849 18 1228 1230 + 850 18 1231 1232 + 851 18 1231 1233 + 852 18 1234 1236 + 853 18 1234 1235 + 854 18 1237 1239 + 855 18 1237 1238 + 856 18 1240 1242 + 857 18 1240 1241 + 858 18 1243 1244 + 859 18 1243 1245 + 860 18 1246 1248 + 861 18 1246 1247 + 862 18 1249 1250 + 863 18 1249 1251 + 864 18 1252 1254 + 865 18 1252 1253 + 866 18 1255 1256 + 867 18 1255 1257 + 868 18 1258 1259 + 869 18 1258 1260 + 870 18 1261 1263 + 871 18 1261 1262 + 872 18 1264 1265 + 873 18 1264 1266 + 874 18 1267 1268 + 875 18 1267 1269 + 876 18 1270 1271 + 877 18 1270 1272 + 878 18 1273 1274 + 879 18 1273 1275 + 880 18 1276 1277 + 881 18 1276 1278 + 882 18 1279 1280 + 883 18 1279 1281 + 884 18 1282 1283 + 885 18 1282 1284 + 886 18 1285 1286 + 887 18 1285 1287 + 888 18 1288 1289 + 889 18 1288 1290 + 890 18 1291 1293 + 891 18 1291 1292 + 892 18 1294 1295 + 893 18 1294 1296 + 894 18 1297 1299 + 895 18 1297 1298 + 896 18 1300 1302 + 897 18 1300 1301 + 898 18 1303 1304 + 899 18 1303 1305 + 900 18 1306 1308 + 901 18 1306 1307 + 902 18 1309 1311 + 903 18 1309 1310 + 904 18 1312 1314 + 905 18 1312 1313 + 906 18 1315 1317 + 907 18 1315 1316 + 908 18 1318 1320 + 909 18 1318 1319 + 910 18 1321 1323 + 911 18 1321 1322 + 912 18 1324 1325 + 913 18 1324 1326 + 914 18 1327 1329 + 915 18 1327 1328 + 916 18 1330 1332 + 917 18 1330 1331 + 918 18 1333 1334 + 919 18 1333 1335 + 920 18 1336 1337 + 921 18 1336 1338 + 922 18 1339 1340 + 923 18 1339 1341 + 924 18 1342 1344 + 925 18 1342 1343 + 926 18 1345 1347 + 927 18 1345 1346 + 928 18 1348 1350 + 929 18 1348 1349 + 930 18 1351 1352 + 931 18 1351 1353 + 932 18 1354 1355 + 933 18 1354 1356 + 934 18 1357 1358 + 935 18 1357 1359 + 936 18 1360 1362 + 937 18 1360 1361 + 938 18 1363 1365 + 939 18 1363 1364 + 940 18 1366 1368 + 941 18 1366 1367 + 942 18 1369 1370 + 943 18 1369 1371 + 944 18 1372 1373 + 945 18 1372 1374 + 946 18 1375 1377 + 947 18 1375 1376 + 948 18 1378 1379 + 949 18 1378 1380 + 950 18 1381 1382 + 951 18 1381 1383 + 952 18 1384 1385 + 953 18 1384 1386 + 954 18 1387 1388 + 955 18 1387 1389 + 956 18 1390 1392 + 957 18 1390 1391 + 958 18 1393 1395 + 959 18 1393 1394 + 960 18 1396 1397 + 961 18 1396 1398 + 962 18 1399 1401 + 963 18 1399 1400 + 964 18 1402 1403 + 965 18 1402 1404 + 966 18 1405 1406 + 967 18 1405 1407 + 968 18 1408 1409 + 969 18 1408 1410 + 970 18 1411 1412 + 971 18 1411 1413 + 972 18 1414 1416 + 973 18 1414 1415 + 974 18 1417 1419 + 975 18 1417 1418 + 976 18 1420 1422 + 977 18 1420 1421 + 978 18 1423 1425 + 979 18 1423 1424 + 980 18 1426 1428 + 981 18 1426 1427 + 982 18 1429 1430 + 983 18 1429 1431 + 984 18 1432 1434 + 985 18 1432 1433 + 986 18 1435 1436 + 987 18 1435 1437 + 988 18 1438 1439 + 989 18 1438 1440 + 990 18 1441 1442 + 991 18 1441 1443 + 992 18 1444 1445 + 993 18 1444 1446 + 994 18 1447 1448 + 995 18 1447 1449 + 996 18 1450 1451 + 997 18 1450 1452 + 998 18 1453 1455 + 999 18 1453 1454 + 1000 18 1456 1457 + 1001 18 1456 1458 + 1002 18 1459 1461 + 1003 18 1459 1460 + 1004 18 1462 1463 + 1005 18 1462 1464 + 1006 18 1465 1466 + 1007 18 1465 1467 + 1008 18 1468 1470 + 1009 18 1468 1469 + 1010 18 1471 1472 + 1011 18 1471 1473 + 1012 18 1474 1476 + 1013 18 1474 1475 + 1014 18 1477 1478 + 1015 18 1477 1479 + 1016 18 1480 1482 + 1017 18 1480 1481 + 1018 18 1483 1485 + 1019 18 1483 1484 + 1020 18 1486 1488 + 1021 18 1486 1487 + 1022 18 1489 1491 + 1023 18 1489 1490 + 1024 18 1492 1493 + 1025 18 1492 1494 + 1026 18 1495 1496 + 1027 18 1495 1497 + 1028 18 1498 1499 + 1029 18 1498 1500 + 1030 18 1501 1502 + 1031 18 1501 1503 + 1032 18 1504 1505 + 1033 18 1504 1506 + 1034 18 1507 1509 + 1035 18 1507 1508 + 1036 18 1510 1512 + 1037 18 1510 1511 + 1038 18 1513 1515 + 1039 18 1513 1514 + 1040 18 1516 1518 + 1041 18 1516 1517 + 1042 18 1519 1520 + 1043 18 1519 1521 + 1044 18 1522 1524 + 1045 18 1522 1523 + 1046 18 1525 1526 + 1047 18 1525 1527 + 1048 18 1528 1529 + 1049 18 1528 1530 + 1050 18 1531 1533 + 1051 18 1531 1532 + 1052 18 1534 1536 + 1053 18 1534 1535 + 1054 18 1537 1539 + 1055 18 1537 1538 + 1056 18 1540 1541 + 1057 18 1540 1542 + 1058 18 1543 1545 + 1059 18 1543 1544 + 1060 18 1546 1547 + 1061 18 1546 1548 + 1062 18 1549 1551 + 1063 18 1549 1550 + 1064 18 1552 1553 + 1065 18 1552 1554 + 1066 18 1555 1557 + 1067 18 1555 1556 + 1068 18 1558 1559 + 1069 18 1558 1560 + 1070 18 1561 1562 + 1071 18 1561 1563 + 1072 18 1564 1565 + 1073 18 1564 1566 + 1074 18 1567 1569 + 1075 18 1567 1568 + 1076 18 1570 1571 + 1077 18 1570 1572 + 1078 18 1573 1575 + 1079 18 1573 1574 + 1080 18 1576 1578 + 1081 18 1576 1577 + 1082 18 1579 1581 + 1083 18 1579 1580 + 1084 18 1582 1584 + 1085 18 1582 1583 + 1086 18 1585 1586 + 1087 18 1585 1587 + 1088 18 1588 1590 + 1089 18 1588 1589 + 1090 18 1591 1592 + 1091 18 1591 1593 + 1092 18 1594 1596 + 1093 18 1594 1595 + 1094 18 1597 1598 + 1095 18 1597 1599 + 1096 18 1600 1602 + 1097 18 1600 1601 + 1098 18 1603 1605 + 1099 18 1603 1604 + 1100 18 1606 1608 + 1101 18 1606 1607 + 1102 18 1609 1610 + 1103 18 1609 1611 + 1104 18 1612 1614 + 1105 18 1612 1613 + 1106 18 1615 1617 + 1107 18 1615 1616 + 1108 18 1618 1620 + 1109 18 1618 1619 + 1110 18 1621 1623 + 1111 18 1621 1622 + 1112 18 1624 1625 + 1113 18 1624 1626 + 1114 18 1627 1629 + 1115 18 1627 1628 + 1116 18 1630 1631 + 1117 18 1630 1632 + 1118 18 1633 1635 + 1119 18 1633 1634 + 1120 18 1636 1637 + 1121 18 1636 1638 + 1122 18 1639 1641 + 1123 18 1639 1640 + 1124 18 1642 1643 + 1125 18 1642 1644 + 1126 18 1645 1646 + 1127 18 1645 1647 + 1128 18 1648 1650 + 1129 18 1648 1649 + 1130 18 1651 1653 + 1131 18 1651 1652 + 1132 18 1654 1656 + 1133 18 1654 1655 + 1134 18 1657 1658 + 1135 18 1657 1659 + 1136 18 1660 1661 + 1137 18 1660 1662 + 1138 18 1663 1664 + 1139 18 1663 1665 + 1140 18 1666 1668 + 1141 18 1666 1667 + 1142 18 1669 1670 + 1143 18 1669 1671 + 1144 18 1672 1674 + 1145 18 1672 1673 + 1146 18 1675 1676 + 1147 18 1675 1677 + 1148 18 1678 1680 + 1149 18 1678 1679 + 1150 18 1681 1683 + 1151 18 1681 1682 + 1152 18 1684 1685 + 1153 18 1684 1686 + 1154 18 1687 1688 + 1155 18 1687 1689 + 1156 18 1690 1691 + 1157 18 1690 1692 + 1158 18 1693 1695 + 1159 18 1693 1694 + 1160 18 1696 1697 + 1161 18 1696 1698 + 1162 18 1699 1701 + 1163 18 1699 1700 + 1164 18 1702 1703 + 1165 18 1702 1704 + 1166 18 1705 1707 + 1167 18 1705 1706 + 1168 18 1708 1709 + 1169 18 1708 1710 + 1170 18 1711 1712 + 1171 18 1711 1713 + 1172 18 1714 1716 + 1173 18 1714 1715 + 1174 18 1717 1718 + 1175 18 1717 1719 + 1176 18 1720 1721 + 1177 18 1720 1722 + 1178 18 1723 1724 + 1179 18 1723 1725 + 1180 18 1726 1727 + 1181 18 1726 1728 + 1182 18 1729 1730 + 1183 18 1729 1731 + 1184 18 1732 1734 + 1185 18 1732 1733 + 1186 18 1735 1737 + 1187 18 1735 1736 + 1188 18 1738 1740 + 1189 18 1738 1739 + 1190 18 1741 1743 + 1191 18 1741 1742 + 1192 18 1744 1745 + 1193 18 1744 1746 + 1194 18 1747 1749 + 1195 18 1747 1748 + 1196 18 1750 1751 + 1197 18 1750 1752 + 1198 18 1753 1755 + 1199 18 1753 1754 + 1200 18 1756 1758 + 1201 18 1756 1757 + 1202 18 1759 1760 + 1203 18 1759 1761 + 1204 18 1762 1764 + 1205 18 1762 1763 + 1206 18 1765 1767 + 1207 18 1765 1766 + 1208 18 1768 1769 + 1209 18 1768 1770 + 1210 18 1771 1773 + 1211 18 1771 1772 + 1212 18 1774 1776 + 1213 18 1774 1775 + 1214 18 1777 1779 + 1215 18 1777 1778 + 1216 18 1780 1781 + 1217 18 1780 1782 + 1218 18 1783 1784 + 1219 18 1783 1785 + 1220 18 1786 1787 + 1221 18 1786 1788 + 1222 18 1789 1790 + 1223 18 1789 1791 + 1224 18 1792 1793 + 1225 18 1792 1794 + 1226 18 1795 1796 + 1227 18 1795 1797 + 1228 18 1798 1799 + 1229 18 1798 1800 + 1230 18 1801 1803 + 1231 18 1801 1802 + 1232 18 1804 1806 + 1233 18 1804 1805 + 1234 18 1807 1809 + 1235 18 1807 1808 + 1236 18 1810 1812 + 1237 18 1810 1811 + 1238 18 1813 1815 + 1239 18 1813 1814 + 1240 18 1816 1818 + 1241 18 1816 1817 + 1242 18 1819 1821 + 1243 18 1819 1820 + 1244 18 1822 1823 + 1245 18 1822 1824 + 1246 18 1825 1827 + 1247 18 1825 1826 + 1248 18 1828 1830 + 1249 18 1828 1829 + 1250 18 1831 1832 + 1251 18 1831 1833 + 1252 18 1834 1835 + 1253 18 1834 1836 + 1254 18 1837 1838 + 1255 18 1837 1839 + 1256 18 1840 1842 + 1257 18 1840 1841 + 1258 18 1843 1845 + 1259 18 1843 1844 + 1260 18 1846 1848 + 1261 18 1846 1847 + 1262 18 1849 1851 + 1263 18 1849 1850 + 1264 18 1852 1854 + 1265 18 1852 1853 + 1266 18 1855 1856 + 1267 18 1855 1857 + 1268 18 1858 1859 + 1269 18 1858 1860 + 1270 18 1861 1862 + 1271 18 1861 1863 + 1272 18 1864 1866 + 1273 18 1864 1865 + 1274 18 1867 1869 + 1275 18 1867 1868 + 1276 18 1870 1871 + 1277 18 1870 1872 + 1278 18 1873 1874 + 1279 18 1873 1875 + 1280 18 1876 1877 + 1281 18 1876 1878 + 1282 18 1879 1881 + 1283 18 1879 1880 + 1284 18 1882 1883 + 1285 18 1882 1884 + 1286 18 1885 1886 + 1287 18 1885 1887 + 1288 18 1888 1890 + 1289 18 1888 1889 + 1290 18 1891 1892 + 1291 18 1891 1893 + 1292 18 1894 1896 + 1293 18 1894 1895 + 1294 18 1897 1898 + 1295 18 1897 1899 + 1296 18 1900 1902 + 1297 18 1900 1901 + 1298 18 1903 1905 + 1299 18 1903 1904 + 1300 18 1906 1908 + 1301 18 1906 1907 + 1302 18 1909 1911 + 1303 18 1909 1910 + 1304 18 1912 1913 + 1305 18 1912 1914 + 1306 18 1915 1916 + 1307 18 1915 1917 + 1308 18 1918 1920 + 1309 18 1918 1919 + 1310 18 1921 1923 + 1311 18 1921 1922 + 1312 18 1924 1926 + 1313 18 1924 1925 + 1314 18 1927 1929 + 1315 18 1927 1928 + 1316 18 1930 1932 + 1317 18 1930 1931 + 1318 18 1933 1935 + 1319 18 1933 1934 + 1320 18 1936 1937 + 1321 18 1936 1938 + 1322 18 1939 1940 + 1323 18 1939 1941 + 1324 18 1942 1944 + 1325 18 1942 1943 + 1326 18 1945 1947 + 1327 18 1945 1946 + 1328 18 1948 1950 + 1329 18 1948 1949 + 1330 18 1951 1953 + 1331 18 1951 1952 + 1332 18 1954 1955 + 1333 18 1954 1956 + 1334 18 1957 1959 + 1335 18 1957 1958 + 1336 18 1960 1961 + 1337 18 1960 1962 + 1338 18 1963 1965 + 1339 18 1963 1964 + 1340 18 1966 1967 + 1341 18 1966 1968 + 1342 18 1969 1970 + 1343 18 1969 1971 + 1344 18 1972 1974 + 1345 18 1972 1973 + 1346 18 1975 1977 + 1347 18 1975 1976 + 1348 18 1978 1979 + 1349 18 1978 1980 + 1350 18 1981 1982 + 1351 18 1981 1983 + 1352 18 1984 1986 + 1353 18 1984 1985 + 1354 18 1987 1988 + 1355 18 1987 1989 + 1356 18 1990 1992 + 1357 18 1990 1991 + 1358 18 1993 1995 + 1359 18 1993 1994 + 1360 18 1996 1998 + 1361 18 1996 1997 + 1362 18 1999 2000 + 1363 18 1999 2001 + 1364 18 2002 2004 + 1365 18 2002 2003 + +Angles + + 1 5 2 1 7 + 2 4 2 1 3 + 3 6 3 1 7 + 4 7 4 2 5 + 5 7 5 2 6 + 6 1 1 2 5 + 7 1 1 2 6 + 8 1 1 2 4 + 9 7 4 2 6 + 10 2 1 7 8 + 11 3 1 7 19 + 12 11 8 7 19 + 13 9 7 8 11 + 14 8 7 8 9 + 15 16 11 8 20 + 16 15 9 8 20 + 17 14 9 8 11 + 18 10 7 8 20 + 19 5 8 9 28 + 20 4 8 9 10 + 21 6 10 9 28 + 22 18 12 11 22 + 23 23 21 11 22 + 24 12 8 11 12 + 25 13 8 11 21 + 26 18 12 11 21 + 27 13 8 11 22 + 28 19 13 12 14 + 29 17 11 12 14 + 30 17 11 12 13 + 31 20 15 13 23 + 32 20 12 13 23 + 33 19 12 13 15 + 34 20 12 14 24 + 35 20 16 14 24 + 36 19 12 14 16 + 37 20 13 15 25 + 38 20 17 15 25 + 39 19 13 15 17 + 40 20 14 16 26 + 41 19 14 16 17 + 42 20 17 16 26 + 43 21 15 17 18 + 44 19 15 17 16 + 45 21 16 17 18 + 46 22 17 18 27 + 47 2 9 28 29 + 48 3 9 28 32 + 49 11 29 28 32 + 50 15 30 29 34 + 51 10 28 29 33 + 52 10 28 29 34 + 53 15 30 29 33 + 54 24 33 29 34 + 55 8 28 29 30 + 56 6 31 30 35 + 57 5 29 30 35 + 58 4 29 30 31 + 59 2 30 35 36 + 60 3 30 35 39 + 61 11 36 35 39 + 62 8 35 36 37 + 63 10 35 36 41 + 64 10 35 36 40 + 65 24 40 36 41 + 66 15 37 36 40 + 67 15 37 36 41 + 68 6 38 37 42 + 69 5 36 37 42 + 70 4 36 37 38 + 71 11 43 42 53 + 72 2 37 42 43 + 73 3 37 42 53 + 74 10 42 43 54 + 75 16 46 43 54 + 76 14 44 43 46 + 77 9 42 43 46 + 78 8 42 43 44 + 79 15 44 43 54 + 80 5 43 44 62 + 81 6 45 44 62 + 82 4 43 44 45 + 83 13 43 46 55 + 84 13 43 46 56 + 85 12 43 46 47 + 86 23 55 46 56 + 87 18 47 46 56 + 88 18 47 46 55 + 89 17 46 47 49 + 90 17 46 47 48 + 91 19 48 47 49 + 92 20 50 48 57 + 93 19 47 48 50 + 94 20 47 48 57 + 95 20 51 49 58 + 96 19 47 49 51 + 97 20 47 49 58 + 98 20 48 50 59 + 99 19 48 50 52 + 100 20 52 50 59 + 101 20 52 51 60 + 102 20 49 51 60 + 103 19 49 51 52 + 104 20 50 52 61 + 105 19 50 52 51 + 106 20 51 52 61 + 107 2 44 62 63 + 108 3 44 62 70 + 109 11 63 62 70 + 110 16 66 63 71 + 111 15 64 63 71 + 112 14 64 63 66 + 113 10 62 63 71 + 114 9 62 63 66 + 115 8 62 63 64 + 116 4 63 64 65 + 117 6 65 64 79 + 118 5 63 64 79 + 119 23 72 66 73 + 120 27 67 66 73 + 121 27 67 66 72 + 122 25 63 66 67 + 123 13 63 66 73 + 124 13 63 66 72 + 125 29 68 67 75 + 126 23 74 67 75 + 127 29 68 67 74 + 128 26 66 67 68 + 129 27 66 67 74 + 130 27 66 67 75 + 131 28 67 68 69 + 132 29 68 69 76 + 133 29 68 69 77 + 134 29 68 69 78 + 135 7 76 69 78 + 136 7 76 69 77 + 137 7 77 69 78 + 138 3 64 79 81 + 139 2 64 79 80 + 140 11 80 79 81 + 141 7 83 80 84 + 142 30 79 80 84 + 143 7 82 80 83 + 144 30 79 80 83 + 145 30 79 80 82 + 146 7 82 80 84 + 147 31 86 85 87 + 148 31 89 88 90 + 149 31 92 91 93 + 150 31 95 94 96 + 151 31 98 97 99 + 152 31 101 100 102 + 153 31 104 103 105 + 154 31 107 106 108 + 155 31 110 109 111 + 156 31 113 112 114 + 157 31 116 115 117 + 158 31 119 118 120 + 159 31 122 121 123 + 160 31 125 124 126 + 161 31 128 127 129 + 162 31 131 130 132 + 163 31 134 133 135 + 164 31 137 136 138 + 165 31 140 139 141 + 166 31 143 142 144 + 167 31 146 145 147 + 168 31 149 148 150 + 169 31 152 151 153 + 170 31 155 154 156 + 171 31 158 157 159 + 172 31 161 160 162 + 173 31 164 163 165 + 174 31 167 166 168 + 175 31 170 169 171 + 176 31 173 172 174 + 177 31 176 175 177 + 178 31 179 178 180 + 179 31 182 181 183 + 180 31 185 184 186 + 181 31 188 187 189 + 182 31 191 190 192 + 183 31 194 193 195 + 184 31 197 196 198 + 185 31 200 199 201 + 186 31 203 202 204 + 187 31 206 205 207 + 188 31 209 208 210 + 189 31 212 211 213 + 190 31 215 214 216 + 191 31 218 217 219 + 192 31 221 220 222 + 193 31 224 223 225 + 194 31 227 226 228 + 195 31 230 229 231 + 196 31 233 232 234 + 197 31 236 235 237 + 198 31 239 238 240 + 199 31 242 241 243 + 200 31 245 244 246 + 201 31 248 247 249 + 202 31 251 250 252 + 203 31 254 253 255 + 204 31 257 256 258 + 205 31 260 259 261 + 206 31 263 262 264 + 207 31 266 265 267 + 208 31 269 268 270 + 209 31 272 271 273 + 210 31 275 274 276 + 211 31 278 277 279 + 212 31 281 280 282 + 213 31 284 283 285 + 214 31 287 286 288 + 215 31 290 289 291 + 216 31 293 292 294 + 217 31 296 295 297 + 218 31 299 298 300 + 219 31 302 301 303 + 220 31 305 304 306 + 221 31 308 307 309 + 222 31 311 310 312 + 223 31 314 313 315 + 224 31 317 316 318 + 225 31 320 319 321 + 226 31 323 322 324 + 227 31 326 325 327 + 228 31 329 328 330 + 229 31 332 331 333 + 230 31 335 334 336 + 231 31 338 337 339 + 232 31 341 340 342 + 233 31 344 343 345 + 234 31 347 346 348 + 235 31 350 349 351 + 236 31 353 352 354 + 237 31 356 355 357 + 238 31 359 358 360 + 239 31 362 361 363 + 240 31 365 364 366 + 241 31 368 367 369 + 242 31 371 370 372 + 243 31 374 373 375 + 244 31 377 376 378 + 245 31 380 379 381 + 246 31 383 382 384 + 247 31 386 385 387 + 248 31 389 388 390 + 249 31 392 391 393 + 250 31 395 394 396 + 251 31 398 397 399 + 252 31 401 400 402 + 253 31 404 403 405 + 254 31 407 406 408 + 255 31 410 409 411 + 256 31 413 412 414 + 257 31 416 415 417 + 258 31 419 418 420 + 259 31 422 421 423 + 260 31 425 424 426 + 261 31 428 427 429 + 262 31 431 430 432 + 263 31 434 433 435 + 264 31 437 436 438 + 265 31 440 439 441 + 266 31 443 442 444 + 267 31 446 445 447 + 268 31 449 448 450 + 269 31 452 451 453 + 270 31 455 454 456 + 271 31 458 457 459 + 272 31 461 460 462 + 273 31 464 463 465 + 274 31 467 466 468 + 275 31 470 469 471 + 276 31 473 472 474 + 277 31 476 475 477 + 278 31 479 478 480 + 279 31 482 481 483 + 280 31 485 484 486 + 281 31 488 487 489 + 282 31 491 490 492 + 283 31 494 493 495 + 284 31 497 496 498 + 285 31 500 499 501 + 286 31 503 502 504 + 287 31 506 505 507 + 288 31 509 508 510 + 289 31 512 511 513 + 290 31 515 514 516 + 291 31 518 517 519 + 292 31 521 520 522 + 293 31 524 523 525 + 294 31 527 526 528 + 295 31 530 529 531 + 296 31 533 532 534 + 297 31 536 535 537 + 298 31 539 538 540 + 299 31 542 541 543 + 300 31 545 544 546 + 301 31 548 547 549 + 302 31 551 550 552 + 303 31 554 553 555 + 304 31 557 556 558 + 305 31 560 559 561 + 306 31 563 562 564 + 307 31 566 565 567 + 308 31 569 568 570 + 309 31 572 571 573 + 310 31 575 574 576 + 311 31 578 577 579 + 312 31 581 580 582 + 313 31 584 583 585 + 314 31 587 586 588 + 315 31 590 589 591 + 316 31 593 592 594 + 317 31 596 595 597 + 318 31 599 598 600 + 319 31 602 601 603 + 320 31 605 604 606 + 321 31 608 607 609 + 322 31 611 610 612 + 323 31 614 613 615 + 324 31 617 616 618 + 325 31 620 619 621 + 326 31 623 622 624 + 327 31 626 625 627 + 328 31 629 628 630 + 329 31 632 631 633 + 330 31 635 634 636 + 331 31 638 637 639 + 332 31 641 640 642 + 333 31 644 643 645 + 334 31 647 646 648 + 335 31 650 649 651 + 336 31 653 652 654 + 337 31 656 655 657 + 338 31 659 658 660 + 339 31 662 661 663 + 340 31 665 664 666 + 341 31 668 667 669 + 342 31 671 670 672 + 343 31 674 673 675 + 344 31 677 676 678 + 345 31 680 679 681 + 346 31 683 682 684 + 347 31 686 685 687 + 348 31 689 688 690 + 349 31 692 691 693 + 350 31 695 694 696 + 351 31 698 697 699 + 352 31 701 700 702 + 353 31 704 703 705 + 354 31 707 706 708 + 355 31 710 709 711 + 356 31 713 712 714 + 357 31 716 715 717 + 358 31 719 718 720 + 359 31 722 721 723 + 360 31 725 724 726 + 361 31 728 727 729 + 362 31 731 730 732 + 363 31 734 733 735 + 364 31 737 736 738 + 365 31 740 739 741 + 366 31 743 742 744 + 367 31 746 745 747 + 368 31 749 748 750 + 369 31 752 751 753 + 370 31 755 754 756 + 371 31 758 757 759 + 372 31 761 760 762 + 373 31 764 763 765 + 374 31 767 766 768 + 375 31 770 769 771 + 376 31 773 772 774 + 377 31 776 775 777 + 378 31 779 778 780 + 379 31 782 781 783 + 380 31 785 784 786 + 381 31 788 787 789 + 382 31 791 790 792 + 383 31 794 793 795 + 384 31 797 796 798 + 385 31 800 799 801 + 386 31 803 802 804 + 387 31 806 805 807 + 388 31 809 808 810 + 389 31 812 811 813 + 390 31 815 814 816 + 391 31 818 817 819 + 392 31 821 820 822 + 393 31 824 823 825 + 394 31 827 826 828 + 395 31 830 829 831 + 396 31 833 832 834 + 397 31 836 835 837 + 398 31 839 838 840 + 399 31 842 841 843 + 400 31 845 844 846 + 401 31 848 847 849 + 402 31 851 850 852 + 403 31 854 853 855 + 404 31 857 856 858 + 405 31 860 859 861 + 406 31 863 862 864 + 407 31 866 865 867 + 408 31 869 868 870 + 409 31 872 871 873 + 410 31 875 874 876 + 411 31 878 877 879 + 412 31 881 880 882 + 413 31 884 883 885 + 414 31 887 886 888 + 415 31 890 889 891 + 416 31 893 892 894 + 417 31 896 895 897 + 418 31 899 898 900 + 419 31 902 901 903 + 420 31 905 904 906 + 421 31 908 907 909 + 422 31 911 910 912 + 423 31 914 913 915 + 424 31 917 916 918 + 425 31 920 919 921 + 426 31 923 922 924 + 427 31 926 925 927 + 428 31 929 928 930 + 429 31 932 931 933 + 430 31 935 934 936 + 431 31 938 937 939 + 432 31 941 940 942 + 433 31 944 943 945 + 434 31 947 946 948 + 435 31 950 949 951 + 436 31 953 952 954 + 437 31 956 955 957 + 438 31 959 958 960 + 439 31 962 961 963 + 440 31 965 964 966 + 441 31 968 967 969 + 442 31 971 970 972 + 443 31 974 973 975 + 444 31 977 976 978 + 445 31 980 979 981 + 446 31 983 982 984 + 447 31 986 985 987 + 448 31 989 988 990 + 449 31 992 991 993 + 450 31 995 994 996 + 451 31 998 997 999 + 452 31 1001 1000 1002 + 453 31 1004 1003 1005 + 454 31 1007 1006 1008 + 455 31 1010 1009 1011 + 456 31 1013 1012 1014 + 457 31 1016 1015 1017 + 458 31 1019 1018 1020 + 459 31 1022 1021 1023 + 460 31 1025 1024 1026 + 461 31 1028 1027 1029 + 462 31 1031 1030 1032 + 463 31 1034 1033 1035 + 464 31 1037 1036 1038 + 465 31 1040 1039 1041 + 466 31 1043 1042 1044 + 467 31 1046 1045 1047 + 468 31 1049 1048 1050 + 469 31 1052 1051 1053 + 470 31 1055 1054 1056 + 471 31 1058 1057 1059 + 472 31 1061 1060 1062 + 473 31 1064 1063 1065 + 474 31 1067 1066 1068 + 475 31 1070 1069 1071 + 476 31 1073 1072 1074 + 477 31 1076 1075 1077 + 478 31 1079 1078 1080 + 479 31 1082 1081 1083 + 480 31 1085 1084 1086 + 481 31 1088 1087 1089 + 482 31 1091 1090 1092 + 483 31 1094 1093 1095 + 484 31 1097 1096 1098 + 485 31 1100 1099 1101 + 486 31 1103 1102 1104 + 487 31 1106 1105 1107 + 488 31 1109 1108 1110 + 489 31 1112 1111 1113 + 490 31 1115 1114 1116 + 491 31 1118 1117 1119 + 492 31 1121 1120 1122 + 493 31 1124 1123 1125 + 494 31 1127 1126 1128 + 495 31 1130 1129 1131 + 496 31 1133 1132 1134 + 497 31 1136 1135 1137 + 498 31 1139 1138 1140 + 499 31 1142 1141 1143 + 500 31 1145 1144 1146 + 501 31 1148 1147 1149 + 502 31 1151 1150 1152 + 503 31 1154 1153 1155 + 504 31 1157 1156 1158 + 505 31 1160 1159 1161 + 506 31 1163 1162 1164 + 507 31 1166 1165 1167 + 508 31 1169 1168 1170 + 509 31 1172 1171 1173 + 510 31 1175 1174 1176 + 511 31 1178 1177 1179 + 512 31 1181 1180 1182 + 513 31 1184 1183 1185 + 514 31 1187 1186 1188 + 515 31 1190 1189 1191 + 516 31 1193 1192 1194 + 517 31 1196 1195 1197 + 518 31 1199 1198 1200 + 519 31 1202 1201 1203 + 520 31 1205 1204 1206 + 521 31 1208 1207 1209 + 522 31 1211 1210 1212 + 523 31 1214 1213 1215 + 524 31 1217 1216 1218 + 525 31 1220 1219 1221 + 526 31 1223 1222 1224 + 527 31 1226 1225 1227 + 528 31 1229 1228 1230 + 529 31 1232 1231 1233 + 530 31 1235 1234 1236 + 531 31 1238 1237 1239 + 532 31 1241 1240 1242 + 533 31 1244 1243 1245 + 534 31 1247 1246 1248 + 535 31 1250 1249 1251 + 536 31 1253 1252 1254 + 537 31 1256 1255 1257 + 538 31 1259 1258 1260 + 539 31 1262 1261 1263 + 540 31 1265 1264 1266 + 541 31 1268 1267 1269 + 542 31 1271 1270 1272 + 543 31 1274 1273 1275 + 544 31 1277 1276 1278 + 545 31 1280 1279 1281 + 546 31 1283 1282 1284 + 547 31 1286 1285 1287 + 548 31 1289 1288 1290 + 549 31 1292 1291 1293 + 550 31 1295 1294 1296 + 551 31 1298 1297 1299 + 552 31 1301 1300 1302 + 553 31 1304 1303 1305 + 554 31 1307 1306 1308 + 555 31 1310 1309 1311 + 556 31 1313 1312 1314 + 557 31 1316 1315 1317 + 558 31 1319 1318 1320 + 559 31 1322 1321 1323 + 560 31 1325 1324 1326 + 561 31 1328 1327 1329 + 562 31 1331 1330 1332 + 563 31 1334 1333 1335 + 564 31 1337 1336 1338 + 565 31 1340 1339 1341 + 566 31 1343 1342 1344 + 567 31 1346 1345 1347 + 568 31 1349 1348 1350 + 569 31 1352 1351 1353 + 570 31 1355 1354 1356 + 571 31 1358 1357 1359 + 572 31 1361 1360 1362 + 573 31 1364 1363 1365 + 574 31 1367 1366 1368 + 575 31 1370 1369 1371 + 576 31 1373 1372 1374 + 577 31 1376 1375 1377 + 578 31 1379 1378 1380 + 579 31 1382 1381 1383 + 580 31 1385 1384 1386 + 581 31 1388 1387 1389 + 582 31 1391 1390 1392 + 583 31 1394 1393 1395 + 584 31 1397 1396 1398 + 585 31 1400 1399 1401 + 586 31 1403 1402 1404 + 587 31 1406 1405 1407 + 588 31 1409 1408 1410 + 589 31 1412 1411 1413 + 590 31 1415 1414 1416 + 591 31 1418 1417 1419 + 592 31 1421 1420 1422 + 593 31 1424 1423 1425 + 594 31 1427 1426 1428 + 595 31 1430 1429 1431 + 596 31 1433 1432 1434 + 597 31 1436 1435 1437 + 598 31 1439 1438 1440 + 599 31 1442 1441 1443 + 600 31 1445 1444 1446 + 601 31 1448 1447 1449 + 602 31 1451 1450 1452 + 603 31 1454 1453 1455 + 604 31 1457 1456 1458 + 605 31 1460 1459 1461 + 606 31 1463 1462 1464 + 607 31 1466 1465 1467 + 608 31 1469 1468 1470 + 609 31 1472 1471 1473 + 610 31 1475 1474 1476 + 611 31 1478 1477 1479 + 612 31 1481 1480 1482 + 613 31 1484 1483 1485 + 614 31 1487 1486 1488 + 615 31 1490 1489 1491 + 616 31 1493 1492 1494 + 617 31 1496 1495 1497 + 618 31 1499 1498 1500 + 619 31 1502 1501 1503 + 620 31 1505 1504 1506 + 621 31 1508 1507 1509 + 622 31 1511 1510 1512 + 623 31 1514 1513 1515 + 624 31 1517 1516 1518 + 625 31 1520 1519 1521 + 626 31 1523 1522 1524 + 627 31 1526 1525 1527 + 628 31 1529 1528 1530 + 629 31 1532 1531 1533 + 630 31 1535 1534 1536 + 631 31 1538 1537 1539 + 632 31 1541 1540 1542 + 633 31 1544 1543 1545 + 634 31 1547 1546 1548 + 635 31 1550 1549 1551 + 636 31 1553 1552 1554 + 637 31 1556 1555 1557 + 638 31 1559 1558 1560 + 639 31 1562 1561 1563 + 640 31 1565 1564 1566 + 641 31 1568 1567 1569 + 642 31 1571 1570 1572 + 643 31 1574 1573 1575 + 644 31 1577 1576 1578 + 645 31 1580 1579 1581 + 646 31 1583 1582 1584 + 647 31 1586 1585 1587 + 648 31 1589 1588 1590 + 649 31 1592 1591 1593 + 650 31 1595 1594 1596 + 651 31 1598 1597 1599 + 652 31 1601 1600 1602 + 653 31 1604 1603 1605 + 654 31 1607 1606 1608 + 655 31 1610 1609 1611 + 656 31 1613 1612 1614 + 657 31 1616 1615 1617 + 658 31 1619 1618 1620 + 659 31 1622 1621 1623 + 660 31 1625 1624 1626 + 661 31 1628 1627 1629 + 662 31 1631 1630 1632 + 663 31 1634 1633 1635 + 664 31 1637 1636 1638 + 665 31 1640 1639 1641 + 666 31 1643 1642 1644 + 667 31 1646 1645 1647 + 668 31 1649 1648 1650 + 669 31 1652 1651 1653 + 670 31 1655 1654 1656 + 671 31 1658 1657 1659 + 672 31 1661 1660 1662 + 673 31 1664 1663 1665 + 674 31 1667 1666 1668 + 675 31 1670 1669 1671 + 676 31 1673 1672 1674 + 677 31 1676 1675 1677 + 678 31 1679 1678 1680 + 679 31 1682 1681 1683 + 680 31 1685 1684 1686 + 681 31 1688 1687 1689 + 682 31 1691 1690 1692 + 683 31 1694 1693 1695 + 684 31 1697 1696 1698 + 685 31 1700 1699 1701 + 686 31 1703 1702 1704 + 687 31 1706 1705 1707 + 688 31 1709 1708 1710 + 689 31 1712 1711 1713 + 690 31 1715 1714 1716 + 691 31 1718 1717 1719 + 692 31 1721 1720 1722 + 693 31 1724 1723 1725 + 694 31 1727 1726 1728 + 695 31 1730 1729 1731 + 696 31 1733 1732 1734 + 697 31 1736 1735 1737 + 698 31 1739 1738 1740 + 699 31 1742 1741 1743 + 700 31 1745 1744 1746 + 701 31 1748 1747 1749 + 702 31 1751 1750 1752 + 703 31 1754 1753 1755 + 704 31 1757 1756 1758 + 705 31 1760 1759 1761 + 706 31 1763 1762 1764 + 707 31 1766 1765 1767 + 708 31 1769 1768 1770 + 709 31 1772 1771 1773 + 710 31 1775 1774 1776 + 711 31 1778 1777 1779 + 712 31 1781 1780 1782 + 713 31 1784 1783 1785 + 714 31 1787 1786 1788 + 715 31 1790 1789 1791 + 716 31 1793 1792 1794 + 717 31 1796 1795 1797 + 718 31 1799 1798 1800 + 719 31 1802 1801 1803 + 720 31 1805 1804 1806 + 721 31 1808 1807 1809 + 722 31 1811 1810 1812 + 723 31 1814 1813 1815 + 724 31 1817 1816 1818 + 725 31 1820 1819 1821 + 726 31 1823 1822 1824 + 727 31 1826 1825 1827 + 728 31 1829 1828 1830 + 729 31 1832 1831 1833 + 730 31 1835 1834 1836 + 731 31 1838 1837 1839 + 732 31 1841 1840 1842 + 733 31 1844 1843 1845 + 734 31 1847 1846 1848 + 735 31 1850 1849 1851 + 736 31 1853 1852 1854 + 737 31 1856 1855 1857 + 738 31 1859 1858 1860 + 739 31 1862 1861 1863 + 740 31 1865 1864 1866 + 741 31 1868 1867 1869 + 742 31 1871 1870 1872 + 743 31 1874 1873 1875 + 744 31 1877 1876 1878 + 745 31 1880 1879 1881 + 746 31 1883 1882 1884 + 747 31 1886 1885 1887 + 748 31 1889 1888 1890 + 749 31 1892 1891 1893 + 750 31 1895 1894 1896 + 751 31 1898 1897 1899 + 752 31 1901 1900 1902 + 753 31 1904 1903 1905 + 754 31 1907 1906 1908 + 755 31 1910 1909 1911 + 756 31 1913 1912 1914 + 757 31 1916 1915 1917 + 758 31 1919 1918 1920 + 759 31 1922 1921 1923 + 760 31 1925 1924 1926 + 761 31 1928 1927 1929 + 762 31 1931 1930 1932 + 763 31 1934 1933 1935 + 764 31 1937 1936 1938 + 765 31 1940 1939 1941 + 766 31 1943 1942 1944 + 767 31 1946 1945 1947 + 768 31 1949 1948 1950 + 769 31 1952 1951 1953 + 770 31 1955 1954 1956 + 771 31 1958 1957 1959 + 772 31 1961 1960 1962 + 773 31 1964 1963 1965 + 774 31 1967 1966 1968 + 775 31 1970 1969 1971 + 776 31 1973 1972 1974 + 777 31 1976 1975 1977 + 778 31 1979 1978 1980 + 779 31 1982 1981 1983 + 780 31 1985 1984 1986 + 781 31 1988 1987 1989 + 782 31 1991 1990 1992 + 783 31 1994 1993 1995 + 784 31 1997 1996 1998 + 785 31 2000 1999 2001 + 786 31 2003 2002 2004 + +Dihedrals + + 1 6 3 1 7 8 + 2 6 2 1 7 19 + 3 4 2 1 7 8 + 4 5 2 1 7 8 + 5 6 3 1 7 19 + 6 3 3 1 2 4 + 7 3 3 1 2 6 + 8 3 3 1 2 5 + 9 3 5 2 1 7 + 10 3 4 2 1 7 + 11 3 6 2 1 7 + 12 3 19 7 8 20 + 13 1 1 7 8 9 + 14 3 1 7 8 20 + 15 2 1 7 8 11 + 16 8 9 8 11 22 + 17 3 7 8 9 10 + 18 7 7 8 9 28 + 19 8 7 8 11 21 + 20 8 7 8 11 12 + 21 3 9 8 7 19 + 22 3 11 8 9 28 + 23 8 7 8 11 22 + 24 3 11 8 7 19 + 25 10 9 8 11 12 + 26 3 20 8 9 28 + 27 8 9 8 11 21 + 28 8 20 8 11 22 + 29 8 20 8 11 21 + 30 4 8 9 28 29 + 31 5 8 9 28 29 + 32 6 10 9 28 29 + 33 11 10 9 8 11 + 34 6 10 9 28 32 + 35 3 10 9 8 20 + 36 6 8 9 28 32 + 37 9 8 11 12 13 + 38 8 12 11 8 20 + 39 9 8 11 12 14 + 40 14 14 12 13 15 + 41 13 13 12 14 24 + 42 3 13 12 11 22 + 43 14 13 12 14 16 + 44 3 14 12 11 22 + 45 3 13 12 11 21 + 46 13 11 12 14 24 + 47 12 11 12 14 16 + 48 3 14 12 11 21 + 49 13 11 12 13 23 + 50 13 14 12 13 23 + 51 12 11 12 13 15 + 52 16 23 13 15 25 + 53 13 12 13 15 25 + 54 14 12 13 15 17 + 55 14 12 14 16 17 + 56 13 12 14 16 26 + 57 16 24 14 16 26 + 58 12 13 15 17 18 + 59 13 17 15 13 23 + 60 14 13 15 17 16 + 61 12 14 16 17 18 + 62 13 17 16 14 24 + 63 14 14 16 17 15 + 64 15 16 17 18 27 + 65 13 15 17 16 26 + 66 13 18 17 15 25 + 67 15 15 17 18 27 + 68 13 16 17 15 25 + 69 13 18 17 16 26 + 70 1 9 28 29 30 + 71 3 32 28 29 33 + 72 3 9 28 29 33 + 73 3 9 28 29 34 + 74 3 32 28 29 34 + 75 3 33 29 30 35 + 76 3 30 29 28 32 + 77 3 34 29 30 35 + 78 7 28 29 30 35 + 79 3 28 29 30 31 + 80 6 29 30 35 39 + 81 4 29 30 35 36 + 82 5 29 30 35 36 + 83 3 31 30 29 34 + 84 3 31 30 29 33 + 85 6 31 30 35 39 + 86 6 31 30 35 36 + 87 1 30 35 36 37 + 88 3 39 35 36 41 + 89 3 30 35 36 40 + 90 3 30 35 36 41 + 91 3 39 35 36 40 + 92 3 40 36 37 42 + 93 3 41 36 37 42 + 94 7 35 36 37 42 + 95 3 35 36 37 38 + 96 3 37 36 35 39 + 97 6 38 37 42 53 + 98 3 38 37 36 40 + 99 6 38 37 42 43 + 100 4 36 37 42 43 + 101 6 36 37 42 53 + 102 5 36 37 42 43 + 103 3 38 37 36 41 + 104 3 37 42 43 54 + 105 1 37 42 43 44 + 106 3 53 42 43 54 + 107 2 37 42 43 46 + 108 10 44 43 46 47 + 109 3 44 43 42 53 + 110 8 42 43 46 56 + 111 8 42 43 46 55 + 112 8 42 43 46 47 + 113 3 46 43 42 53 + 114 8 44 43 46 55 + 115 8 54 43 46 56 + 116 7 42 43 44 62 + 117 3 42 43 44 45 + 118 3 46 43 44 62 + 119 3 54 43 44 62 + 120 8 54 43 46 55 + 121 8 44 43 46 56 + 122 5 43 44 62 63 + 123 6 45 44 62 70 + 124 6 43 44 62 70 + 125 4 43 44 62 63 + 126 11 45 44 43 46 + 127 3 45 44 43 54 + 128 6 45 44 62 63 + 129 9 43 46 47 48 + 130 8 47 46 43 54 + 131 9 43 46 47 49 + 132 3 49 47 46 55 + 133 13 46 47 48 57 + 134 14 49 47 48 50 + 135 3 49 47 46 56 + 136 12 46 47 48 50 + 137 12 46 47 49 51 + 138 14 48 47 49 51 + 139 13 46 47 49 58 + 140 3 48 47 46 55 + 141 3 48 47 46 56 + 142 13 48 47 49 58 + 143 13 49 47 48 57 + 144 14 47 48 50 52 + 145 16 57 48 50 59 + 146 13 47 48 50 59 + 147 16 58 49 51 60 + 148 13 47 49 51 60 + 149 14 47 49 51 52 + 150 13 48 50 52 61 + 151 14 48 50 52 51 + 152 16 59 50 52 61 + 153 13 52 50 48 57 + 154 14 49 51 52 50 + 155 13 49 51 52 61 + 156 13 52 51 49 58 + 157 16 60 51 52 61 + 158 13 51 52 50 59 + 159 13 50 52 51 60 + 160 3 70 62 63 71 + 161 2 44 62 63 66 + 162 1 44 62 63 64 + 163 3 44 62 63 71 + 164 8 62 63 66 72 + 165 8 62 63 66 67 + 166 3 71 63 64 79 + 167 3 62 63 64 65 + 168 3 64 63 62 70 + 169 8 62 63 66 73 + 170 7 62 63 64 79 + 171 8 64 63 66 67 + 172 3 66 63 64 79 + 173 8 64 63 66 72 + 174 3 66 63 62 70 + 175 8 71 63 66 73 + 176 8 64 63 66 73 + 177 8 71 63 66 72 + 178 6 63 64 79 81 + 179 6 65 64 79 80 + 180 3 65 64 63 71 + 181 4 63 64 79 80 + 182 6 65 64 79 81 + 183 5 63 64 79 80 + 184 11 65 64 63 66 + 185 8 67 66 63 71 + 186 17 63 66 67 74 + 187 17 72 66 67 75 + 188 17 63 66 67 75 + 189 17 63 66 67 68 + 190 17 73 66 67 74 + 191 17 73 66 67 75 + 192 17 72 66 67 74 + 193 19 66 67 68 69 + 194 21 68 67 66 72 + 195 18 66 67 68 69 + 196 21 68 67 66 73 + 197 20 69 68 67 74 + 198 20 69 68 67 75 + 199 20 67 68 69 77 + 200 20 67 68 69 76 + 201 20 67 68 69 78 + 202 3 81 79 80 83 + 203 3 81 79 80 84 + 204 3 64 79 80 84 + 205 3 81 79 80 82 + 206 3 64 79 80 83 + 207 3 64 79 80 82 + +Impropers + + 1 2 7 1 8 19 + 2 1 1 2 7 3 + 3 1 9 8 28 10 + 4 2 28 9 29 32 + 5 1 30 29 35 31 + 6 2 35 30 36 39 + 7 1 37 36 42 38 + 8 2 42 37 43 53 + 9 1 44 43 62 45 + 10 2 62 44 63 70 + 11 1 64 63 79 65 + 12 2 79 64 80 81 diff --git a/src/REPLICA/in.temper_npt b/src/REPLICA/in.temper_npt new file mode 100644 index 0000000000..40db3c9604 --- /dev/null +++ b/src/REPLICA/in.temper_npt @@ -0,0 +1,32 @@ +# Solvated 5-mer peptide +# Demonstrating temper_npt +units real +atom_style full + +pair_style lj/charmm/coul/long 8.0 10.0 10.0 +bond_style harmonic +angle_style charmm +dihedral_style charmm +improper_style harmonic +kspace_style pppm 0.0001 + +read_data data.peptide + +neighbor 2.0 bin +neigh_modify delay 5 + +timestep 2.0 + +thermo_style custom step temp epair emol etotal press density +thermo 50 + +variable temper_T world 275 280 285 290 295 300 305 310 +variable rep world 0 1 2 3 4 5 6 7 +fix myfix all npt temp ${temper_T} ${temper_T} 100.0 iso 1 1 1000 +run 500 +temper_npt 2000 100 ${temper_T} myfix 0 58728 1 +fix 2 all shake 0.0001 10 100 b 4 6 8 10 12 14 18 a 31 +group peptide type <= 12 + + + diff --git a/src/REPLICA/temper_npt.cpp b/src/REPLICA/temper_npt.cpp new file mode 100644 index 0000000000..a043c61407 --- /dev/null +++ b/src/REPLICA/temper_npt.cpp @@ -0,0 +1,381 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing Authors: Amulya K. Pervaje and Cody K. Addington + Contact Email: amulyapervaje@gmail.com + temper_npt is a modification of temper that is applicable to the NPT ensemble + uses the npt acceptance criteria for parallel tempering (replica exchange) as given in + Mori, Y .; Okamoto, Y . Generalized-Ensemble Algorithms for the Isobaric–Isothermal Ensemble. J. Phys. Soc. Japan 2010, 79, 74003. + + temper_npt N M temp fix-ID seed1 seed2 pressure index(optional) + refer to documentation for temper, only difference with temper_npt is that the pressure is specified as the 7th argument, the 8th argument is the same optional index argument used in temper +------------------------------------------------------------------------- */ + +#include +#include +#include +#include "temper_npt.h" +#include "universe.h" +#include "domain.h" +#include "atom.h" +#include "update.h" +#include "integrate.h" +#include "modify.h" +#include "compute.h" +#include "force.h" +#include "output.h" +#include "thermo.h" +#include "fix.h" +#include "random_park.h" +#include "finish.h" +#include "timer.h" +#include "memory.h" +#include "error.h" + +using namespace LAMMPS_NS; + +#define TEMPER_DEBUG 0 + +/* ---------------------------------------------------------------------- */ + +TemperNpt::TemperNpt(LAMMPS *lmp) : Pointers(lmp) {} + +/* ---------------------------------------------------------------------- */ + +TemperNpt::~TemperNpt() +{ + MPI_Comm_free(&roots); + if (ranswap) delete ranswap; + delete ranboltz; + delete [] set_temp; + delete [] temp2world; + delete [] world2temp; + delete [] world2root; +} + +/* ---------------------------------------------------------------------- + perform tempering with inter-world swaps +------------------------------------------------------------------------- */ + +void TemperNpt::command(int narg, char **arg) +{ + if (universe->nworlds == 1) + error->all(FLERR,"Must have more than one processor partition to temper"); + if (domain->box_exist == 0) + error->all(FLERR,"temper_npt command before simulation box is defined"); + if (narg != 7 && narg != 8) + error->universe_all(FLERR,"Illegal temper command"); + + int nsteps = force->inumeric(FLERR,arg[0]); + nevery = force->inumeric(FLERR,arg[1]); + double temp = force->numeric(FLERR,arg[2]); + double press_set = force->numeric(FLERR,arg[6]); + + for (whichfix = 0; whichfix < modify->nfix; whichfix++) + if (strcmp(arg[3],modify->fix[whichfix]->id) == 0) break; + if (whichfix == modify->nfix) + error->universe_all(FLERR,"Tempering fix ID is not defined"); + + seed_swap = force->inumeric(FLERR,arg[4]); + seed_boltz = force->inumeric(FLERR,arg[5]); + + my_set_temp = universe->iworld; + if (narg == 8) my_set_temp = force->inumeric(FLERR,arg[6]); + + // swap frequency must evenly divide total # of timesteps + + if (nevery <= 0) + error->universe_all(FLERR,"Invalid frequency in temper command"); + nswaps = nsteps/nevery; + if (nswaps*nevery != nsteps) + error->universe_all(FLERR,"Non integer # of swaps in temper command"); + + // fix style must be appropriate for temperature control, i.e. it needs + // to provide a working Fix::reset_target() and must not change the volume. + + if ((strcmp(modify->fix[whichfix]->style,"npt") != 0)) error->universe_all(FLERR,"Tempering temperature fix is not supported"); + + // setup for long tempering run + + update->whichflag = 1; + update->nsteps = nsteps; + update->beginstep = update->firststep = update->ntimestep; + update->endstep = update->laststep = update->firststep + nsteps; + if (update->laststep < 0) + error->all(FLERR,"Too many timesteps"); + + lmp->init(); + + // local storage + + me_universe = universe->me; + MPI_Comm_rank(world,&me); + nworlds = universe->nworlds; + iworld = universe->iworld; + boltz = force->boltz; + nktv2p = force->nktv2p; + + // pe_compute = ptr to thermo_pe compute + // notify compute it will be called at first swap + + int id = modify->find_compute("thermo_pe"); + if (id < 0) error->all(FLERR,"Tempering could not find thermo_pe compute"); + Compute *pe_compute = modify->compute[id]; + pe_compute->addstep(update->ntimestep + nevery); + + // create MPI communicator for root proc from each world + + int color; + if (me == 0) color = 0; + else color = 1; + MPI_Comm_split(universe->uworld,color,0,&roots); + + // RNGs for swaps and Boltzmann test + // warm up Boltzmann RNG + + if (seed_swap) ranswap = new RanPark(lmp,seed_swap); + else ranswap = NULL; + ranboltz = new RanPark(lmp,seed_boltz + me_universe); + for (int i = 0; i < 100; i++) ranboltz->uniform(); + + // world2root[i] = global proc that is root proc of world i + + world2root = new int[nworlds]; + if (me == 0) + MPI_Allgather(&me_universe,1,MPI_INT,world2root,1,MPI_INT,roots); + MPI_Bcast(world2root,nworlds,MPI_INT,0,world); + + // create static list of set temperatures + // allgather tempering arg "temp" across root procs + // bcast from each root to other procs in world + + set_temp = new double[nworlds]; + if (me == 0) MPI_Allgather(&temp,1,MPI_DOUBLE,set_temp,1,MPI_DOUBLE,roots); + MPI_Bcast(set_temp,nworlds,MPI_DOUBLE,0,world); + + // create world2temp only on root procs from my_set_temp + // create temp2world on root procs from world2temp, + // then bcast to all procs within world + + world2temp = new int[nworlds]; + temp2world = new int[nworlds]; + if (me == 0) { + MPI_Allgather(&my_set_temp,1,MPI_INT,world2temp,1,MPI_INT,roots); + for (int i = 0; i < nworlds; i++) temp2world[world2temp[i]] = i; + } + MPI_Bcast(temp2world,nworlds,MPI_INT,0,world); + + // if restarting tempering, reset temp target of Fix to current my_set_temp + + if (narg == 8) { + double new_temp = set_temp[my_set_temp]; + modify->fix[whichfix]->reset_target(new_temp); + } + + // setup tempering runs + + int i,which,partner,swap,partner_set_temp,partner_world; + double pe,pe_partner, delr,boltz_factor,new_temp, press_units; + + if (me_universe == 0 && universe->uscreen) + fprintf(universe->uscreen,"Setting up tempering ...\n"); + + update->integrate->setup(); + + if (me_universe == 0) { + if (universe->uscreen) { + fprintf(universe->uscreen,"Step"); + for (int i = 0; i < nworlds; i++) + fprintf(universe->uscreen," T%d",i); + fprintf(universe->uscreen,"\n"); + } + if (universe->ulogfile) { + fprintf(universe->ulogfile,"Step"); + for (int i = 0; i < nworlds; i++) + fprintf(universe->ulogfile," T%d",i); + fprintf(universe->ulogfile,"\n"); + } + print_status(); + } + + timer->init(); + timer->barrier_start(); + + for (int iswap = 0; iswap < nswaps; iswap++) { + + // run for nevery timesteps + + update->integrate->run(nevery); + + // compute PE + // notify compute it will be called at next swap + + pe = pe_compute->compute_scalar(); + pe_compute->addstep(update->ntimestep + nevery); + double boxlox=domain->boxlo[0]; + double boxhix=domain->boxhi[0]; + double boxloy=domain->boxlo[1]; + double boxhiy=domain->boxhi[1]; + double boxloz=domain->boxlo[2]; + double boxhiz=domain->boxhi[2]; + double vol = (boxhix - boxlox)*(boxhiy - boxloy)*(boxhiz - boxloz); + double vol_partner = vol; + // which = which of 2 kinds of swaps to do (0,1) + + if (!ranswap) which = iswap % 2; + else if (ranswap->uniform() < 0.5) which = 0; + else which = 1; + + // partner_set_temp = which set temp I am partnering with for this swap + + if (which == 0) { + if (my_set_temp % 2 == 0) partner_set_temp = my_set_temp + 1; + else partner_set_temp = my_set_temp - 1; + } else { + if (my_set_temp % 2 == 1) partner_set_temp = my_set_temp + 1; + else partner_set_temp = my_set_temp - 1; + } + + // partner = proc ID to swap with + // if partner = -1, then I am not a proc that swaps + + partner = -1; + if (me == 0 && partner_set_temp >= 0 && partner_set_temp < nworlds) { + partner_world = temp2world[partner_set_temp]; + partner = world2root[partner_world]; + } + + // swap with a partner, only root procs in each world participate + // hi proc sends PE to low proc + // lo proc make Boltzmann decision on whether to swap + // lo proc communicates decision back to hi proc + + swap = 0; + if (partner != -1) { + if (me_universe > partner) { + MPI_Send(&pe,1,MPI_DOUBLE,partner,0,universe->uworld); + } + else { + MPI_Recv(&pe_partner,1,MPI_DOUBLE,partner,0,universe->uworld,MPI_STATUS_IGNORE); + } + if (me_universe > partner) { + MPI_Send(&vol,1, MPI_DOUBLE,partner,0,universe->uworld); + } + else { + MPI_Recv(&vol_partner,1,MPI_DOUBLE,partner,0,universe->uworld,MPI_STATUS_IGNORE); + } + // Acceptance criteria changed for NPT ensemble + if (me_universe < partner) { + press_units = press_set/nktv2p; + delr = (pe_partner - pe)*(1.0/(boltz*set_temp[my_set_temp]) - 1.0/(boltz*set_temp[partner_set_temp])) + press_units*(1.0/(boltz*set_temp[my_set_temp]) - 1.0/(boltz*set_temp[partner_set_temp]))*(vol_partner - vol); + boltz_factor = -delr; + if (boltz_factor >= 0.0) swap = 1; + else if (ranboltz->uniform() < exp(boltz_factor)) swap = 1; + } + + if (me_universe < partner) + MPI_Send(&swap,1,MPI_INT,partner,0,universe->uworld); + else + MPI_Recv(&swap,1,MPI_INT,partner,0,universe->uworld,MPI_STATUS_IGNORE); +#ifdef TEMPER_DEBUG + if (me_universe < partner) + fprintf(universe->uscreen,"SWAP %d & %d: yes = %d,Ts = %d %d, PEs = %g %g, Bz = %g %g, vol = %g %g\n", + me_universe,partner,swap,my_set_temp,partner_set_temp, + pe,pe_partner,boltz_factor,exp(boltz_factor), vol, vol_partner); +#endif + + } + + // bcast swap result to other procs in my world + + MPI_Bcast(&swap,1,MPI_INT,0,world); + + // rescale kinetic energy via velocities if move is accepted + + if (swap) scale_velocities(partner_set_temp,my_set_temp); + + // if my world swapped, all procs in world reset temp target of Fix + + if (swap) { + new_temp = set_temp[partner_set_temp]; + modify->fix[whichfix]->reset_target(new_temp); + } + + // update my_set_temp and temp2world on every proc + // root procs update their value if swap took place + // allgather across root procs + // bcast within my world + + if (swap) my_set_temp = partner_set_temp; + if (me == 0) { + MPI_Allgather(&my_set_temp,1,MPI_INT,world2temp,1,MPI_INT,roots); + for (i = 0; i < nworlds; i++) temp2world[world2temp[i]] = i; + } + MPI_Bcast(temp2world,nworlds,MPI_INT,0,world); + + // print out current swap status + + if (me_universe == 0) print_status(); + } + + timer->barrier_stop(); + + update->integrate->cleanup(); + + Finish finish(lmp); + finish.end(1); + + update->whichflag = 0; + update->firststep = update->laststep = 0; + update->beginstep = update->endstep = 0; +} + +/* ---------------------------------------------------------------------- + scale kinetic energy via velocities a la Sugita +------------------------------------------------------------------------- */ + +void TemperNpt::scale_velocities(int t_partner, int t_me) +{ + double sfactor = sqrt(set_temp[t_partner]/set_temp[t_me]); + + double **v = atom->v; + int nlocal = atom->nlocal; + + for (int i = 0; i < nlocal; i++) { + v[i][0] = v[i][0]*sfactor; + v[i][1] = v[i][1]*sfactor; + v[i][2] = v[i][2]*sfactor; + } +} + +/* ---------------------------------------------------------------------- + proc 0 prints current tempering status +------------------------------------------------------------------------- */ + +void TemperNpt::print_status() +{ + if (universe->uscreen) { + fprintf(universe->uscreen,BIGINT_FORMAT,update->ntimestep); + for (int i = 0; i < nworlds; i++) + fprintf(universe->uscreen," %d",world2temp[i]); + fprintf(universe->uscreen,"\n"); + } + if (universe->ulogfile) { + fprintf(universe->ulogfile,BIGINT_FORMAT,update->ntimestep); + for (int i = 0; i < nworlds; i++) + fprintf(universe->ulogfile," %d",world2temp[i]); + fprintf(universe->ulogfile,"\n"); + fflush(universe->ulogfile); + } +} diff --git a/src/REPLICA/temper_npt.h b/src/REPLICA/temper_npt.h new file mode 100644 index 0000000000..984f2839b1 --- /dev/null +++ b/src/REPLICA/temper_npt.h @@ -0,0 +1,118 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. + + Contributing Authors: Amulya K. Pervaje and Cody K. Addington + Contact Email: amulyapervaje@gmail.com + temper_npt is a modification of temper that is applicable to the NPT ensemble + uses the npt acceptance criteria for parallel tempering (replica exchange) as given in + Mori, Y .; Okamoto, Y . Generalized-Ensemble Algorithms for the Isobaric–Isothermal Ensemble. J. Phys. Soc. Japan 2010, 79, 74003. + + temper_npt N M temp fix-ID seed1 seed2 pressure index(optional) + refer to documentation for temper, only difference with temper_npt is that the pressure is s +pecified as the 7th argument, the 8th argument is the same optional index argument used in temp +er +------------------------------------------------------------------------- */ + +#ifdef COMMAND_CLASS + +CommandStyle(temper_npt,TemperNpt) + +#else + +#ifndef LMP_TEMPERNPT_H +#define LMP_TEMPERNPT_H + +#include "pointers.h" + +namespace LAMMPS_NS { + +class TemperNpt : protected Pointers { + public: + TemperNpt(class LAMMPS *); + ~TemperNpt(); + void command(int, char **); + + private: + int me,me_universe; // my proc ID in world and universe + int iworld,nworlds; // world info + double boltz; // copy from output->boltz + double nktv2p; + MPI_Comm roots; // MPI comm with 1 root proc from each world + class RanPark *ranswap,*ranboltz; // RNGs for swapping and Boltz factor + int nevery; // # of timesteps between swaps + int nswaps; // # of tempering swaps to perform + int seed_swap; // 0 = toggle swaps, n = RNG for swap direction + int seed_boltz; // seed for Boltz factor comparison + int whichfix; // index of temperature fix to use + int fixstyle; // what kind of temperature fix is used + + int my_set_temp; // which set temp I am simulating + double *set_temp; // static list of replica set temperatures + int *temp2world; // temp2world[i] = world simulating set temp i + int *world2temp; // world2temp[i] = temp simulated by world i + int *world2root; // world2root[i] = root proc of world i + + void scale_velocities(int, int); + void print_status(); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +E: Must have more than one processor partition to temper + +Cannot use the temper command with only one processor partition. Use +the -partition command-line option. + +E: TemperNpt command before simulation box is defined + +The temper command cannot be used before a read_data, read_restart, or +create_box command. + +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: Tempering fix ID is not defined + +The fix ID specified by the temper command does not exist. + +E: Invalid frequency in temper command + +Nevery must be > 0. + +E: Non integer # of swaps in temper command + +Swap frequency in temper command must evenly divide the total # of +timesteps. + +E: Tempering temperature fix is not valid + +The fix specified by the temper command is not one that controls +temperature (nvt or langevin). + +E: Too many timesteps + +The cummulative timesteps must fit in a 64-bit integer. + +E: Tempering could not find thermo_pe compute + +This compute is created by the thermo command. It must have been +explicitly deleted by a uncompute command. + +*/ From 6f66e6c45445bfbd459ac2beeeb7a8ea1fa1c083 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 18 Aug 2017 19:07:32 -0400 Subject: [PATCH 370/439] add new compute fragment/atom --- src/compute_cluster_atom.h | 2 +- src/compute_fragment_atom.cpp | 210 ++++++++++++++++++++++++++++++++++ src/compute_fragment_atom.h | 67 +++++++++++ 3 files changed, 278 insertions(+), 1 deletion(-) create mode 100644 src/compute_fragment_atom.cpp create mode 100644 src/compute_fragment_atom.h diff --git a/src/compute_cluster_atom.h b/src/compute_cluster_atom.h index aae4747781..253396b40e 100644 --- a/src/compute_cluster_atom.h +++ b/src/compute_cluster_atom.h @@ -59,7 +59,7 @@ E: Cannot use compute cluster/atom unless atoms have IDs Atom IDs are used to identify clusters. -E: Compute cluster/atom requires a pair style be defined +E: Compute cluster/atom requires a pair style to be defined This is so that the pair style defines a cutoff distance which is used to find clusters. diff --git a/src/compute_fragment_atom.cpp b/src/compute_fragment_atom.cpp new file mode 100644 index 0000000000..02a0b8e7dc --- /dev/null +++ b/src/compute_fragment_atom.cpp @@ -0,0 +1,210 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include +#include "compute_fragment_atom.h" +#include "atom.h" +#include "atom_vec.h" +#include "update.h" +#include "modify.h" +#include "neighbor.h" +#include "force.h" +#include "pair.h" +#include "comm.h" +#include "memory.h" +#include "error.h" + +#include "group.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +ComputeFragmentAtom::ComputeFragmentAtom(LAMMPS *lmp, int narg, char **arg) : + Compute(lmp, narg, arg), + fragmentID(NULL) +{ + if (narg != 3) error->all(FLERR,"Illegal compute fragment/atom command"); + + if (atom->avec->bonds_allow == 0) + error->all(FLERR,"Compute fragment/atom used when bonds are not allowed"); + + peratom_flag = 1; + size_peratom_cols = 0; + comm_forward = 1; + + nmax = 0; +} + +/* ---------------------------------------------------------------------- */ + +ComputeFragmentAtom::~ComputeFragmentAtom() +{ + memory->destroy(fragmentID); +} + +/* ---------------------------------------------------------------------- */ + +void ComputeFragmentAtom::init() +{ + if (atom->tag_enable == 0) + error->all(FLERR,"Cannot use compute fragment/atom unless atoms have IDs"); + if (force->bond == NULL) + error->all(FLERR,"Compute fragment/atom requires a bond style to be defined"); + + int count = 0; + for (int i = 0; i < modify->ncompute; i++) + if (strcmp(modify->compute[i]->style,"fragment/atom") == 0) count++; + if (count > 1 && comm->me == 0) + error->warning(FLERR,"More than one compute fragment/atom"); +} + +/* ---------------------------------------------------------------------- */ + +void ComputeFragmentAtom::compute_peratom() +{ + int i,j,k; + + invoked_peratom = update->ntimestep; + + // grow fragmentID array if necessary + + if (atom->nmax > nmax) { + memory->destroy(fragmentID); + nmax = atom->nmax; + memory->create(fragmentID,nmax,"fragment/atom:fragmentID"); + vector_atom = fragmentID; + } + + int nbondlist = neighbor->nbondlist; + int **bondlist = neighbor->bondlist; + + // if group is dynamic, insure ghost atom masks are current + + if (group->dynamic[igroup]) { + commflag = 0; + comm->forward_comm_compute(this); + } + + // every bond starts in its own fragment, + // with fragmentID = MIN(b1atomID,b2atomID) + // only bonds wholly contained in the group are considered + + tagint *tag = atom->tag; + int *mask = atom->mask; + + for (i = 0; i < nbondlist; i++) { + const int b1 = bondlist[i][0]; + const int b2 = bondlist[i][1]; + + if ((mask[b1] & groupbit) && (mask[b2] & groupbit)) + fragmentID[b1] = fragmentID[b2] = MIN(tag[b1],tag[b2]); + else fragmentID[b1] = fragmentID[b2] = 0; + } + + // loop until no more changes on any proc: + // acquire fragmentIDs of ghost atoms + // loop over my atoms, and check atoms bound to it + // if both atoms are in fragment, assign lowest fragmentID to both + // iterate until no changes in my atoms + // then check if any proc made changes + + commflag = 1; + int nlocal = atom->nlocal; + int *num_bond = atom->num_bond; + tagint **bond_atom = atom->bond_atom; + + int change,done,anychange; + + while (1) { + comm->forward_comm_compute(this); + + change = 0; + while (1) { + done = 1; + for (i = 0; i < nlocal; i++) { + if (!(mask[i] & groupbit)) continue; + + for (j = 0; j < num_bond[i]; j++) { + k = bond_atom[i][j]; + if (!(mask[k] & groupbit)) continue; + if (fragmentID[i] == fragmentID[k]) continue; + + fragmentID[i] = fragmentID[k] = MIN(fragmentID[i],fragmentID[k]); + done = 0; + } + } + if (!done) change = 1; + if (done) break; + } + + // stop if all procs are done + + MPI_Allreduce(&change,&anychange,1,MPI_INT,MPI_MAX,world); + if (!anychange) break; + } +} + +/* ---------------------------------------------------------------------- */ + +int ComputeFragmentAtom::pack_forward_comm(int n, int *list, double *buf, + int pbc_flag, int *pbc) +{ + int i,j,m; + + m = 0; + if (commflag) { + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = fragmentID[j]; + } + } else { + int *mask = atom->mask; + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = ubuf(mask[j]).d; + } + } + + return m; +} + +/* ---------------------------------------------------------------------- */ + +void ComputeFragmentAtom::unpack_forward_comm(int n, int first, double *buf) +{ + int i,m,last; + + m = 0; + last = first + n; + if (commflag) + for (i = first; i < last; i++) fragmentID[i] = buf[m++]; + else { + int *mask = atom->mask; + for (i = first; i < last; i++) mask[i] = (int) ubuf(buf[m++]).i; + } +} + +/* ---------------------------------------------------------------------- + memory usage of local atom-based array +------------------------------------------------------------------------- */ + +double ComputeFragmentAtom::memory_usage() +{ + double bytes = nmax * sizeof(double); + return bytes; +} diff --git a/src/compute_fragment_atom.h b/src/compute_fragment_atom.h new file mode 100644 index 0000000000..a56239dbda --- /dev/null +++ b/src/compute_fragment_atom.h @@ -0,0 +1,67 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef COMPUTE_CLASS + +ComputeStyle(fragment/atom,ComputeFragmentAtom) + +#else + +#ifndef LMP_COMPUTE_FRAGMENT_ATOM_H +#define LMP_COMPUTE_FRAGMENT_ATOM_H + +#include "compute.h" + +namespace LAMMPS_NS { + +class ComputeFragmentAtom : public Compute { + public: + ComputeFragmentAtom(class LAMMPS *, int, char **); + ~ComputeFragmentAtom(); + void init(); + void compute_peratom(); + int pack_forward_comm(int, int *, double *, int, int *); + void unpack_forward_comm(int, int, double *); + double memory_usage(); + + private: + int nmax,commflag; + double *fragmentID; +}; + +} + +#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: Cannot use compute fragment/atom unless atoms have IDs + +Atom IDs are used to identify fragments. + +E: Compute fragment/atom requires a bond style to be defined + +This is so that a bond list is generated which is used to find fragments. + +W: More than one compute fragment/atom + +It is not efficient to use compute fragment/atom more than once. + +*/ From 2e6a928aa3150c608151ccebe8a3414da1a80530 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 18 Aug 2017 19:23:33 -0400 Subject: [PATCH 371/439] ignore file recently added to USER-INTEL --- src/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/src/.gitignore b/src/.gitignore index 80166e260e..3a97524c82 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -57,6 +57,7 @@ /intel_buffers.cpp /intel_buffers.h /intel_intrinsics.h +/intel_intrinsics_airebo.h /intel_preprocess.h /intel_simd.h From 44ccdb86df24ec1d8299ea198d0ce0c6e01a7b48 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 18 Aug 2017 19:24:39 -0400 Subject: [PATCH 372/439] add checks when reading QEQ parameter file to avoid segfaults and memory corruption on incorrect files --- src/QEQ/fix_qeq.cpp | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/src/QEQ/fix_qeq.cpp b/src/QEQ/fix_qeq.cpp index c5b566eef7..38bfec8b96 100644 --- a/src/QEQ/fix_qeq.cpp +++ b/src/QEQ/fix_qeq.cpp @@ -747,18 +747,26 @@ void FixQEq::read_file(char *file) nwords = atom->count_words(line); if (nwords == 0) continue; - // words = ptrs to all words in line + // must have 6 parameters per line. - nwords = 0; - words[nwords++] = strtok(line," \t\n\r\f"); - while ((words[nwords++] = strtok(NULL," \t\n\r\f"))) continue; + if (nwords < 6) + error->all(FLERR,"Invalid fix qeq parameter file"); - itype = atoi(words[0]); - chi[itype] = atof(words[1]); - eta[itype] = atof(words[2]); - gamma[itype] = atof(words[3]); - zeta[itype] = atof(words[4]); - zcore[itype] = atof(words[5]); + + // words = ptrs to first 6 words in line + + for (n=0, words[n] = strtok(line," \t\n\r\f"); + n < 6; + words[++n] = strtok(NULL," \t\n\r\f")); + + itype = force->inumeric(FLERR,words[0]); + if ((itype < 1) || (itype > atom->ntypes)) + error->all(FLERR,"Invalid fix qeq parameter file"); + chi[itype] = force->numeric(FLERR,words[1]); + eta[itype] = force->numeric(FLERR,words[2]); + gamma[itype] = force->numeric(FLERR,words[3]); + zeta[itype] = force->numeric(FLERR,words[4]); + zcore[itype] = force->numeric(FLERR,words[5]); } delete [] words; } From f945d4567d4f291fbf8c05ea22ec906ef3ee2ec9 Mon Sep 17 00:00:00 2001 From: Steve Plimpton Date: Fri, 18 Aug 2017 17:33:42 -0600 Subject: [PATCH 373/439] new USER-MESO package --- doc/src/Eqs/fix_mvv_dpd.jpg | Bin 0 -> 29281 bytes doc/src/Eqs/fix_mvv_dpd.tex | 21 + doc/src/Eqs/pair_edpd_force.jpg | Bin 0 -> 32395 bytes doc/src/Eqs/pair_edpd_force.tex | 33 + doc/src/Eqs/pair_edpd_gov.jpg | Bin 0 -> 17725 bytes doc/src/Eqs/pair_edpd_gov.tex | 15 + doc/src/Eqs/pair_edpd_heat.jpg | Bin 0 -> 46952 bytes doc/src/Eqs/pair_edpd_heat.tex | 29 + doc/src/Eqs/pair_edpd_kappa.jpg | Bin 0 -> 5626 bytes doc/src/Eqs/pair_edpd_kappa.tex | 9 + doc/src/Eqs/pair_mdpd_force.jpg | Bin 0 -> 19465 bytes doc/src/Eqs/pair_mdpd_force.tex | 17 + doc/src/Eqs/pair_tdpd_flux.jpg | Bin 0 -> 22023 bytes doc/src/Eqs/pair_tdpd_flux.tex | 21 + doc/src/Eqs/pair_tdpd_force.jpg | Bin 0 -> 25842 bytes doc/src/Eqs/pair_tdpd_force.tex | 29 + doc/src/Eqs/pair_tdpd_gov.jpg | Bin 0 -> 18141 bytes doc/src/Eqs/pair_tdpd_gov.tex | 13 + doc/src/JPG/examples_edpd.jpg | Bin 0 -> 15776 bytes doc/src/JPG/examples_mdpd.gif | Bin 0 -> 916813 bytes doc/src/JPG/examples_mdpd_first.jpg | Bin 0 -> 115446 bytes doc/src/JPG/examples_mdpd_last.jpg | Bin 0 -> 38463 bytes doc/src/JPG/examples_tdpd.jpg | Bin 0 -> 10789 bytes doc/src/Section_commands.txt | 11 + doc/src/Section_packages.txt | 65 +- doc/src/atom_style.txt | 46 +- doc/src/compute_edpd_temp_atom.txt | 61 ++ doc/src/compute_tdpd_cc_atom.txt | 60 ++ doc/src/fix_dpd_source.txt | 101 ++ doc/src/fix_mvv_dpd.txt | 97 ++ doc/src/pair_meso.txt | 277 +++++ doc/src/read_data.txt | 54 +- doc/src/set.txt | 22 +- examples/USER/meso/README | 40 + examples/USER/meso/edpd/in.edpd | 54 + .../USER/meso/edpd/log.16Aug17.edpd.g++.1 | 142 +++ .../USER/meso/edpd/log.16Aug17.edpd.g++.4 | 142 +++ .../meso/edpd/temp.profile.16Aug17.edpd.g++.1 | 24 + .../meso/edpd/temp.profile.16Aug17.edpd.g++.4 | 24 + examples/USER/meso/mdpd/in.mdpd | 52 + .../USER/meso/mdpd/log.16Aug17.mdpd.g++.1 | 147 +++ .../USER/meso/mdpd/log.16Aug17.mdpd.g++.4 | 147 +++ .../meso/tdpd/cc.profile.16Aug17.tdpd.g++.1 | 24 + .../meso/tdpd/cc.profile.16Aug17.tdpd.g++.4 | 24 + examples/USER/meso/tdpd/in.tdpd | 54 + .../USER/meso/tdpd/log.16Aug17.tdpd.g++.1 | 146 +++ .../USER/meso/tdpd/log.16Aug17.tdpd.g++.4 | 146 +++ src/Makefile | 3 +- src/USER-MESO/README | 50 + src/USER-MESO/atom_vec_edpd.cpp | 844 ++++++++++++++++ src/USER-MESO/atom_vec_edpd.h | 68 ++ src/USER-MESO/atom_vec_mdpd.cpp | 951 ++++++++++++++++++ src/USER-MESO/atom_vec_mdpd.h | 79 ++ src/USER-MESO/atom_vec_tdpd.cpp | 879 ++++++++++++++++ src/USER-MESO/atom_vec_tdpd.h | 83 ++ src/USER-MESO/compute_edpd_temp_atom.cpp | 97 ++ src/USER-MESO/compute_edpd_temp_atom.h | 43 + src/USER-MESO/compute_tdpd_cc_atom.cpp | 98 ++ src/USER-MESO/compute_tdpd_cc_atom.h | 44 + src/USER-MESO/fix_edpd_source.cpp | 120 +++ src/USER-MESO/fix_edpd_source.h | 44 + src/USER-MESO/fix_mvv_dpd.cpp | 136 +++ src/USER-MESO/fix_mvv_dpd.h | 45 + src/USER-MESO/fix_mvv_edpd.cpp | 163 +++ src/USER-MESO/fix_mvv_edpd.h | 45 + src/USER-MESO/fix_mvv_tdpd.cpp | 156 +++ src/USER-MESO/fix_mvv_tdpd.h | 46 + src/USER-MESO/fix_tdpd_source.cpp | 120 +++ src/USER-MESO/fix_tdpd_source.h | 45 + src/USER-MESO/pair_edpd.cpp | 551 ++++++++++ src/USER-MESO/pair_edpd.h | 85 ++ src/USER-MESO/pair_mdpd.cpp | 425 ++++++++ src/USER-MESO/pair_mdpd.h | 84 ++ src/USER-MESO/pair_mdpd_rhosum.cpp | 267 +++++ src/USER-MESO/pair_mdpd_rhosum.h | 50 + src/USER-MESO/pair_tdpd.cpp | 477 +++++++++ src/USER-MESO/pair_tdpd.h | 81 ++ src/atom.cpp | 14 +- src/atom.h | 9 +- src/set.cpp | 72 +- src/set.h | 3 +- 81 files changed, 8358 insertions(+), 66 deletions(-) create mode 100644 doc/src/Eqs/fix_mvv_dpd.jpg create mode 100644 doc/src/Eqs/fix_mvv_dpd.tex create mode 100644 doc/src/Eqs/pair_edpd_force.jpg create mode 100644 doc/src/Eqs/pair_edpd_force.tex create mode 100644 doc/src/Eqs/pair_edpd_gov.jpg create mode 100644 doc/src/Eqs/pair_edpd_gov.tex create mode 100644 doc/src/Eqs/pair_edpd_heat.jpg create mode 100644 doc/src/Eqs/pair_edpd_heat.tex create mode 100644 doc/src/Eqs/pair_edpd_kappa.jpg create mode 100644 doc/src/Eqs/pair_edpd_kappa.tex create mode 100644 doc/src/Eqs/pair_mdpd_force.jpg create mode 100644 doc/src/Eqs/pair_mdpd_force.tex create mode 100644 doc/src/Eqs/pair_tdpd_flux.jpg create mode 100644 doc/src/Eqs/pair_tdpd_flux.tex create mode 100644 doc/src/Eqs/pair_tdpd_force.jpg create mode 100644 doc/src/Eqs/pair_tdpd_force.tex create mode 100644 doc/src/Eqs/pair_tdpd_gov.jpg create mode 100644 doc/src/Eqs/pair_tdpd_gov.tex create mode 100644 doc/src/JPG/examples_edpd.jpg create mode 100644 doc/src/JPG/examples_mdpd.gif create mode 100644 doc/src/JPG/examples_mdpd_first.jpg create mode 100644 doc/src/JPG/examples_mdpd_last.jpg create mode 100644 doc/src/JPG/examples_tdpd.jpg create mode 100644 doc/src/compute_edpd_temp_atom.txt create mode 100644 doc/src/compute_tdpd_cc_atom.txt create mode 100644 doc/src/fix_dpd_source.txt create mode 100644 doc/src/fix_mvv_dpd.txt create mode 100644 doc/src/pair_meso.txt create mode 100644 examples/USER/meso/README create mode 100644 examples/USER/meso/edpd/in.edpd create mode 100644 examples/USER/meso/edpd/log.16Aug17.edpd.g++.1 create mode 100644 examples/USER/meso/edpd/log.16Aug17.edpd.g++.4 create mode 100644 examples/USER/meso/edpd/temp.profile.16Aug17.edpd.g++.1 create mode 100644 examples/USER/meso/edpd/temp.profile.16Aug17.edpd.g++.4 create mode 100644 examples/USER/meso/mdpd/in.mdpd create mode 100644 examples/USER/meso/mdpd/log.16Aug17.mdpd.g++.1 create mode 100644 examples/USER/meso/mdpd/log.16Aug17.mdpd.g++.4 create mode 100644 examples/USER/meso/tdpd/cc.profile.16Aug17.tdpd.g++.1 create mode 100644 examples/USER/meso/tdpd/cc.profile.16Aug17.tdpd.g++.4 create mode 100644 examples/USER/meso/tdpd/in.tdpd create mode 100644 examples/USER/meso/tdpd/log.16Aug17.tdpd.g++.1 create mode 100644 examples/USER/meso/tdpd/log.16Aug17.tdpd.g++.4 create mode 100644 src/USER-MESO/README create mode 100644 src/USER-MESO/atom_vec_edpd.cpp create mode 100644 src/USER-MESO/atom_vec_edpd.h create mode 100644 src/USER-MESO/atom_vec_mdpd.cpp create mode 100644 src/USER-MESO/atom_vec_mdpd.h create mode 100644 src/USER-MESO/atom_vec_tdpd.cpp create mode 100644 src/USER-MESO/atom_vec_tdpd.h create mode 100644 src/USER-MESO/compute_edpd_temp_atom.cpp create mode 100644 src/USER-MESO/compute_edpd_temp_atom.h create mode 100644 src/USER-MESO/compute_tdpd_cc_atom.cpp create mode 100644 src/USER-MESO/compute_tdpd_cc_atom.h create mode 100644 src/USER-MESO/fix_edpd_source.cpp create mode 100644 src/USER-MESO/fix_edpd_source.h create mode 100644 src/USER-MESO/fix_mvv_dpd.cpp create mode 100644 src/USER-MESO/fix_mvv_dpd.h create mode 100644 src/USER-MESO/fix_mvv_edpd.cpp create mode 100644 src/USER-MESO/fix_mvv_edpd.h create mode 100644 src/USER-MESO/fix_mvv_tdpd.cpp create mode 100644 src/USER-MESO/fix_mvv_tdpd.h create mode 100644 src/USER-MESO/fix_tdpd_source.cpp create mode 100644 src/USER-MESO/fix_tdpd_source.h create mode 100644 src/USER-MESO/pair_edpd.cpp create mode 100644 src/USER-MESO/pair_edpd.h create mode 100644 src/USER-MESO/pair_mdpd.cpp create mode 100644 src/USER-MESO/pair_mdpd.h create mode 100644 src/USER-MESO/pair_mdpd_rhosum.cpp create mode 100644 src/USER-MESO/pair_mdpd_rhosum.h create mode 100644 src/USER-MESO/pair_tdpd.cpp create mode 100644 src/USER-MESO/pair_tdpd.h diff --git a/doc/src/Eqs/fix_mvv_dpd.jpg b/doc/src/Eqs/fix_mvv_dpd.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f62ae28bc4092c7f38d1e796c3db33ff118bd8bd GIT binary patch literal 29281 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 SFR}hV4M+KpNC)$O^ZyqW>I4`7 literal 0 HcmV?d00001 diff --git a/doc/src/Eqs/fix_mvv_dpd.tex b/doc/src/Eqs/fix_mvv_dpd.tex new file mode 100644 index 0000000000..4652d54b77 --- /dev/null +++ b/doc/src/Eqs/fix_mvv_dpd.tex @@ -0,0 +1,21 @@ +\documentclass[12pt]{article} + +\begin{document} + +$$ + v(t+\frac{\Delta t}{2}) = v(t) + \frac{\Delta t}{2}\cdot a(t), +$$ + +$$ + r(t+\Delta t) = r(t) + \Delta t\cdot v(t+\frac{\Delta t}{2}), +$$ + +$$ + a(t+\Delta t) = \frac{1}{m}\cdot F\left[ r(t+\Delta t), v(t) +\lambda \cdot \Delta t\cdot a(t)\right], +$$ + +$$ + v(t+\Delta t) = v(t+\frac{\Delta t}{2}) + \frac{\Delta t}{2}\cdot a(t++\Delta t), +$$ + +\end{document} diff --git a/doc/src/Eqs/pair_edpd_force.jpg b/doc/src/Eqs/pair_edpd_force.jpg new file mode 100644 index 0000000000000000000000000000000000000000..fabb6f772e2b61f199d6f36bb4f192f328e42aaf GIT binary patch literal 32395 zcmb5V1yCHp_b$2+B)CI>;O>Fo?yw69uvqY*!QCB#JIgK-TowuL5+o4Z-4+QRJU9e< z{OeEto<2Ppy-0Z2&50Opqs@QeV+0bU{h zNB*;a^&%)}DF2byXlSTt7_TugFh4T8PB0d%d*2~rZpYr?@K=2w#5J~4153V;N71$c#o zgar7%1r-hb#SRiO#!In2J^<+z3NjKh3NjiBDmE?_015dO3IG+20G*KTH4!mAuMCL> zDFdIZsS5^K$lM!7VQ|`eemUJwdSDU+l-Ch`*UcPeu;YI`RJHHXUAoaXlOcRS?Hq=g4jT+(obl}G- zxT%gT!0G9he}iWynj@`&J8rtT#UprR^&dT# zcRzT?9rd5^Wtiw9BFRhi*c~u2Wdc5itTHlT0lt^bgy83=K%;u>)k)8U1g%@;d(+2Qnq z7{=wd9k`)21*CsGel`j=prRv(0Cf&kk$RT4Y2EmK2LT-;CVOsG)!n*2E9or{^%vYn z?PldX1Go)uXE+)bSDTkAIE~W$gAo@5fxN{E@z1e~N9{r0G16S11LZ7etBbixIyGrfR)ZfLwu7?VZHV10~%z#l~Y z{W}rMkM;USsQP%kViXAlrA`bmp@ID3G7vbbi(420JUNV(Rg9Q*7th9g)WsfjaU`G) z5fyXlPg?%wQ9`uDAsZ2+ETyjSWkmxrPF7JL>jYU%asI_r$Dr(E={Vdtq|{2#m$C!; znEkmFqV!!6sPnyj8?dEy!HCdeY0meFay^6MkX9yXT5 z_9*p6n5oZL3c1-0rgqbx#{nA8KP3#EQ}*|Cgj@G2Nb=XZE|+(9oR_eDlav7V%}MV~ zGJf+`YC3B7jB|$82no{P=WA+HdXyEubtL_ zngK>&IY&Y$M3%T9m#VS0bMEvksC)Mb&=S?^hjpu zY#VC6>nx{__Hpnk8#5hg$uB(_Y#u-swGd~>mnw7B1QWyHl-I-lDO%oHM`1U}0u_HS zepaAG@D{!kGoPt&!_u?ksO^F&_k4q#{pbr_9op?AnOrt+X{5uvX}h<8(V5WdI#Dth z+kSeKY^w;0c#l0nyPc!n&m%%#ooXl>(6&ITIi+XWE#X4=&@^+DPuq~|6P#2vf>KJt z(Pz(3|Mfous@JDz_I{!Lj)%ucgdu9Fb;L^P^4rtf0~!~O$lE8}+z53Igud&tj%aQg zh{;$SVpsWS_4oAt&okiaE6USRwKlj8<+VPu>h~`4l}a*yW`uLCtJBq2)Y*#0WPf?G zPGQtiqBSfBB?)D=M}4AuNl#BZ$t$YCC1#2D$eZo-W_jChGlNLo4e^m&*O7{$4@)?q zuWw$lvdPc}!@m|*QWckFh4&}9Wkv`j*S|A3#}@tl1NO}|{U&K9fv?HPq5qz-vaxA1 z6hfTRS;R`9&qx-kz^FXzIFkb|wBV2X++SnfHqfEjU+2t&-@hY{yG}jh)9*B|&HX$1 ziI-1oCc{hxoTD@U&(Nmtnwx|$4;DBrLz&9JeCpghHpqhBwzADG|2p9zJgOT*4oDkc zR9)R7Ly5Xd1J}G$31_-c#BlDuc=&b22c4N3`;HMa!$CF*NF>Xu`{>58&V3~oWa7Tq58r=|L5}WaT#v^-5D}33JqG^; z$v)T(D$_h&eHc6u!BvPwoW<1*&x^fh?+~*x^uEE1VGo5|#Hf3)DQQcPiasDUkO?e8 zPs*2GrCY|%6!3}lRJ}i|Ankc5YII}M=dP4ZXy8BG*LCv2`je)y_|V%_APB%uH^HzJ zs#a;Yi((Pajk8MMXzSX-R|uI6@oL`g-rOpmGCAhrTm*(Ib{lIYCo>s zNwofm352$KX4GcVqXKZJ4@khQ_cxNOIc@$-g99xjx!2a;*-w-R zaDH$1rL_DZP(8}fX0%u#hv6(IY&Yij6ID?|)FT8|#3b{xcCk{i%doFILp4!FJbA!7 zN5*;ZLbZ5`&9$mN)?w&}s-_JP_!`5Zrg)NEmJnGz8*g+$h_L$%=}d4wEJ;a)xn(eq zc6b5jYt%*$zg?^+;Oj11mabQZsX_6&|sGktJ)PqDe$s){~iXn2>=h39ZPrLB$(D zD$oJv{pR>IRh5G=CN4TpZrQkWp6SQ8VXzn#=YshRsGC}GC`t@}hkiJHAU)+&+~0h8 zq5EKTxblO8s7}lcpPMjd&GWr+02D^!(3k{A6;A!fWI+hYtLhXmGM*d|schSrk1SdR z{b{Z3J4W5a_?2pM-7&BE=d$vN(020~5ER{F;q$gt;u&DKYP6}R^MF?}bI%SRx+WKr z(tN8Ifv5(Xuk1?s4Od_MhWt9wTeMKLLQchy98P1()2zYF1pfpj^j(B-#dMc^5!a(* z>guTzN&8_fb<}j2@*Nspa?5lzYv z$v8ljGc~jlw>5wMSM^QKNC08_C>@)eQIl5T4oKtN9YB;`@sO}@mMF$CpjW%HqM37q z_5~x_hR*i2z$(bP?)RRUvGT_2we=qa`3 z(sDAP5921XhzmtLF;v;Rf0aP76CtVT*=wxqn3+#rXs~X0u-!;rF<0?o8qlj3pWVmq zw<+t{CsjKn2?I?{fh$jltlz5h4SKsm_e4tKk#MbR^>NB7|+k9H%HFt_`g(oV%)!&6wx_+4(Z{gF4js$#G^!G(Z6?rUStoNbN-DvCqbNTx-evJTa_={HGdHVMDkSQ(kbrlpri zxX5PY7V#J?4fB8ARrpKpWR~HrS9)>CwCOVq16el1+@+}Ib0lDk`M+UKmW;DiPH{Y> zKQC~lx3P{V*fJ?*&fFLb3g4Wq#$&TR147MMx$zO-F>z73>^|v&JM)kR#htxP2haeX z$RBu08-*?^zD{>qOEu#_!_J!$jx#SaL|KjMimyG_6%t8>tebUelr( zuR4^4)F(Au@o+!;xk%&>G$4&Cr}(ax=`9fG)r+AV4X?sn#Ycy}26(Ds@Z~pBsZ)B; z1tI4;^-NBJ0ea^kC~o8TDZ3oN1>lP46j#fjH*OdVEns2;(f@y{hn8h3hYzB`MV!QC zjNY`53RdjB&ww&9f$wCPF1+piuA1+@$UB}>`jRv@2x}gZJ9@Cm4q|-f!k|8w71;9) z2h;3v6UV!zS*45$%jshIwy8w5hteA-R3?|;8yL}=Iy zxjkb~nL6WeZ>X_-Zl}2%Zor>B97PE@S=rcv9P)n_acs+Au(2=BPKF7FHHC%2X#wby zNG9La-;k=$F5jF^5dTkKT7gXJZL?at^x$ik*!UK%rXoIRaE5Wrl5zLZatv7cp13IV z_3Dey-9yA*(G2qrV%ZTP<9NIFAsPL3mwslWQSEhQeA$4(4RHx{wyOIB+x(!70qCc+ zgm39J1&l39yyK*l(dd*a4T#WWp0uyY@qI-XLe;29$6*7oc4x$YO^vh=b8pjtuooPh zw-XmEkd0Whi7=o55lXH<1G+S?s&?4;fV*`s=r#1^Gk=dAyw&kb9SU=y)^H;YOHZL& zp)a0Z>59RFv#FHnLt*@f(wun@gUi=NtTZLSRLT@j z6Xpy{Y86(d+%SI2hNFk!^IoR!GYiOl%93)bG1S;nj9RZJ6ti#Af?qixG1Nh|3iEFm zA!;iSyVUS<4roNy1D>wg>ZxmzPpEDB3@dcE&P42XjJ_&f;f&n|i3u+JnlX{u z<|lgGILj`conm+$aPs;i&)=1Cg({b)nFFzEIp=BtGyl_Q0}MO zHFVj?ROxnollmjV-0j0+tKfmZr5;Uu<5@388BB;f;jO=G@#}(JS8|e zqw{2CS1AkoHGInT0s4Y|%8IhX*enS2vBeJ%ULX07!y8rYm_CnNf|%+?-!1CrfRz`g zQ>R6nBAcL8?!q8;jZOl&2OqTJq7(~OxWzQo+&H&A6d4~ zIv%A-q#=~iv>tiW|Hc-JOrX~n!#v$4Hrk`j5aClKE%`4#Ct?ZgzK<;h$L?n2NtGdU zT^_&_PwC0^S=~LV?KQ!XlaG2Xk~00(x@dZYZ=)T5C_&CC7=!B~=Cz1w6t5~{LYwK} z2WpIimBQIEp1=Uu-@jZ(WqWC}rGEk-$vYqxX+|H$VDWE{i}01b<;85z=0F;H*??cf z68`R0pJK(dTFHfyV=P@d~ds>r6#!GBqRrL{9q%TnH&*f^&TyU%Ek>B-BlI17Gv0{qDKXv$h_b);)!;7c z^?YT6!p3;qSU0_th3&|2QZE%0Kv+I9LishlG0JF>V5OC>l{5oz+$vKev72~TRT$9r zbdJGrtwUs5;WsCD^2xi#l~J2?_j7Zsr~FK`k|o-=q%ffJGa!+CU@|Cl%)Cfqk`nAyCYF2Hk&ZSkTyCh~K{z1*G+A}qCl$>xde<{ocHHzUQx@qLeBwrd*o zOrkmI+DZGy!R)6vq3zt?P?l$aHlsk5Uls9{1QOLpP_Uss1#>{ue8+puh6*{ zYAR}ztpo?D)}=2`%|qLymR5U zyG1BnOn|5W8VdVmk66BGC?L#(3o2;BOTpia< zYZVm*cxn{@Xf!WTBn@{3(&LAc$*sb4Sy|xsNGOLxw)_?5;(Pb&xYBjo?E}Gmbz8cA zP&>^9G0Q&_4_y1`<)GB%#V_TSmaH5OA3fMPr|)mpT@zs@f{nkQ zv}^up4tsw|ZBdG;(6OJP9;|Mm3LTU9qjO)Vrre|=Ph;*RxEzz@-mESgd{KK{tpu({ zd0>`^Xv(6>w+^|{jNWoHWW(W_C1N=$bXvkGBoDcT?ShsqT2j?1EuDn7Vnjjs2vZgP z#O)-t(7@n16|`|q^Z2~o3lWl)I)sZ4vv8vSRmTJ+^={1{=_|Uf0EUz+lWyU|H$RBj5lkI;` ze4MG$RSm?c6MFlJai~tlr0FO8?_x4BP#9dDrd)M92F!yOgWG2W`Wm+fFAAqr8Q4wOs=MZ{78(A$ZCZ_rm zJhwVECrS1>0U|P-OM`XGXpnPs7!r^k~2*IA_wEWB~9Nyyc9m85*MWx6CE%B*r`UKU~GWx|)VoVu9=@stJ4 zN}nx0+M*{3BgnQ7HA(F&y&C%CZXt<1P8Y}AUKnh5*pgK#VY2%ekC37-YiN)rpJt`g z4u!7qukom*N?e!>{WiUmA%4DGQ?C_jCx=F%lC(pyzBC9w`4WH!(9sOnum0Zu{zqji zG$WVHw`oxwc7&FhLI+$(gr?0m96rn=9?Er7TXA}Q2IKCl;f{uT7c`Br)6 zDB#j7eBJlCy)Df#d6Q`*HcAXDeS=$BT`HihG5Z-n@hkI;VnbNTP%)Wuw_)KEm&k-F z?lx7Ki?P$tqx`0LVGsD7Bv&tAR*VIuzZKsP15z6o-7ld%nYVw&+4`rkA=5?To#iy^Rgf zI0nLD5BKD0I8?mLe(DLs+C7&EALJX6qYM|k-}9oy(amoCgN>N=LUpl~HB5ADF?1V& z;3ZLp&@9C%Kk+dYC2qz%{Oe8M7HSC)J_J6#gAEBrU4K!}ozKs%)ND_boQg^d9heLi zx-Q3T(S*#5>q3rQIjSG#wye9 z+uUjKD}6N_p?IQ-G!l5*UF~Yfm*3}5EiM$*Wag|si4Z|hc0sx5?w8=c(SiMLey9hzfp^#Y33gHxv|mDSAP zo(wey-jUJ$;vebSiA26BiH7>hbhz4~5%go`mH(=OO5O6aa z^XS^T5h^Mj3hQ}m#qm8*L{<*<_s!4+ml0Stlo+Hm@rg6~DeK~G0Lz0potZ=oyVs7> zC}h@iTI&5$w-Gm^&FEo{4_QVAD5nN1pq^-e`OrbdN~-OlIYX*_DNx#}=5Imw{FSbM zA!SDPZmRHwx$wM1jOvG_br&Wn8fTE&uYB6XjHVxHpw67%*2o}I6y&UT9-{gzmFYBd z->2T~wKiilhNvxwVt&^x_p?z#3#6;l>vw9oI*?hP78lFzu>`_Ge})dzi_3bcNH+rd%NoLLAWI1-6oP z944fJU)30dD?XAlSO=A?*Idc-9b$Snye=wP)p!(fvH!T%3w=-wLpZyzhvT^x_e~li zGjRpApe;qB{IwSi*`eaP#tcs!BRP_0TndvPY*sKvcoQgwn;I_F78{bYA=f;an?S3$y1AeF4Q7#f5t(s9l%R?OE7 zan)4ypaz9B+}YoE8%>9%Kd0Ms)4it7{ZDE?`VLo$c+nUKaBnn^WZ&?&fSSz71h)nE zdLQ0GW>T2BEKtfCdNsdmM&BVrp-#0J)u6tZUe=0VG0O&)5z{l)%99{4Kj5hw*zop3 zj~+KTrBpDCC`u%pbFrpd8O;v~KAv2Ve_s81qy3lj%TlmK`3Uz0S$`dtb@K`tIR|8s zj&3p+p_E(l^@b1)U{cMr@D^GM=CxqQ@O43=ex3 z94u_|ZWX1mEaiTZ8%;uDL@tmDHFAC|pIYHE{UOt5Jba#R8w;`Gg9ZNJD{NHMj0Wk& zs68Qt@l7P65DJ&V9C7Q_{LyU#N}1pgyMu_*j06!;o3yd?hym_&@G|? zR(#YYORy;nYoOnv7~G-+#aD5ll7C&GcrTejRr?jGYP@ zK8^ZW&L4aMoMgrcsZsjbO22OR;rsF>`^I@=wPpTalb7uIHY?j*`y^uLx*dx`1T`7C zIbNgq56Wd5>vx8HXiBcroxjs4YNF=B#ic>G9{^EYE9R_Q9$Mrg5Apqw$g8<_H9D9s zNU4PI$PfceKUfy^YhN#|ZmRZmt#VlMG5DK!|Kwy+aAIOp0&C~7-(>I3v%Sp?aZyz0 z&y9XBcwSQJN}XENN+JIy0+7 zN`#hRTGh}|Xj&@O%}=zhLJoc87IEe$aKRmI7xoa%ZZqX#na14AR{F?)h(n4tZ>Tm( zQdG*a+j6eNZR)SSD;zhhI*+F5Z8d=8vLX5pB@Kz~Mk`p(`tIX=CDJqCgC(hW@z?=b z?z^{#=mB2hJlOrktD`&bnkKoM0W%s)bf1aaqk3eap<=Y6IX^u~+ANwfbO%4^e{+E< z`pQ|^7!N~x)GX;3^qDN_&@F7(HO{4paX9VdYWbXd`S%4asO3$N-pXZ}BT>#K@-n0g zePG%L>1h8adjDM!*t24uwo^LJr>fVw5H^rV@UfNY_snR`zEA4vXHNce^@Esc(r_Dn zDRlv_iiqw5hRbTEQ5QqIh>IU_qZF=O%?g6Y**N4_mOM;2Y;H4)m--n0tV>@Nw&8tK z*laVE*z$0W!x0#m_SC;(FYC|Bh(4d^jQfF`dRQyTEKjx^P%v|5`EJAEno8yomTv=A zJ{Pwqe9gR|70RQBLJ9fL^2`6=Qv4UC;=fac`aZdUu5*h7mRcii=T5mMF?UGm@pasY zLuaa1=;=|KShWJ%y7Bkp*+2N@Uln%!FeF05mPq4gPdu1&-ao442<72#42K{f%AL5w^ z!OfH|AQv^d-w-7GeY#hNS7*8pzIz7-tUX*lmftV>ZIZp3lv;QR6>@y>VWQJIl$vGG z0>E)qH~O7!c2}|HL(1o%;XgF@(E`pr^?2&JMbufGdV*Mqi|>}=p(2t~P$_3mvnjKr zVv3~U%>kUEV8a8f!aAb8pUigr7oRZpAJz)2-k9v~MBrq{~s8q;8CJOI_rf@hnz;$?-I%kwaP>GjH|W{ksds=3oY zTgP?hnH1|u)6W2yUDR)&bE|p8Gyv@xVC+{$p`-mz=^*#9__q9!X(gzo{BmC5AgU$! z2KUU&fSqbK2iQ^?azjgrzw|^&GhT->Wn=4J9eo5A1CUhHQU%+wjNOs3cDjOv{hL7 zxaP;TqLV2R%17I_-V{HQv#EZNTDb68aLP%B5!u*yV3@r@-`cs~j}Xs=Vn-Y2tzJ~Z zZ-T|I_vPB`XbZ{97j{hjiVS{#N261_;^Y`3ENeEG+<>2^|A~gYCa(Kgl473;%q2wRPtX;@{GW>c`<9YnJ2VzXust)X=m8MoiRu!A=~ zqNU{><`Cui&5#|*t86RM6?DQ@%LOgrEz(`T2>mIS8!cG_OTeQ}V;QUR!z{`3e4$sITcfh?~P`56{tqPN?w*)GQz`|kHntorSORf_5zG@HvVjA*FkdL{!FxX zJYN>0)Kzb3c~lIdY8$40C=z%oq_TZ=#T772a8H}dKBe*RpqQPEO{h=Sj4S@C*DwRa zQFR+_w$!CZ3*JWfn~i!;Za|gUVVq z^G$n|4WQKECEb>mKg;S94UkGgX`N*BxODjHN#Bt{HF4K`=oUUgiV1->DtUihHkBm482q5&=MV#oG_ZKbGtueOGEDQ}bb*s1- z`K=_W!^29OU}ytctT!fF@jj9YYJo9hEFLD~e68N7n-hV#w5{>0R<&PRP!q3WPkD-L zFc>BjM2q+vvV#p}2h?HLZI#wGm>zTR*V61@s5^iL{K4u8UP*tmf0Ilbjv~t2dj7`E z_j=6+COqAJPh5$iE|p%Ipa2$8n%@3X$EV9l_&!dfW%Q$EqwoRaXxu9shlYnkFti3) z^MdO3LeDK~qrCxW9|Zk*Ftf-N5o?e8j!H}~TH>uJ$!ddJk$=pkQSaY}NX9<6pT=(! z2X*Al4o2Zk3;z@0oY5k*wl-+$+{KlCWBzv?jUJwJrdYDRzv78eXhLXXmhq^r8SM%I zMWQ2YYFhkD$CF9YQYNFAleoI(=&!|FU?8_88tp->R*Oo zWjkw7=eX$lp5b@Lfv2D~mAvTcu7G)kFyGuRBMG(9jfc)Y(xo^{L8rc!>uro<4^_)b z!k&byMr+Y!rF(o(;_)9}+4h-3yQr##afT*WJW@GTdqm`p0A!0U%(|@Qx8L8N)S$PP zjP5jGXw0H;eR4(CYVS3-Vy~kkFCI%1y$TQS)W<#-;Pea}4m?@DX8{2z)smEA5T+~d z$r`#x$+^U$ZN}Zekrz%|Gc(26F5-meq`5qN=8i!CIMwF4VS#FA$XoM z+f??}S>`iO97((WXCo^`&j4nNX@+H$*2*nwa3Tk7J?lL2l$MGK4R8_)zD-4 zV5RT2N+Aio(Tj6kn~LXU?{0(u<}OM>Nn)}E8xPTG+Y2G~9nO*-(fwRyK~ZbWpH>ox zC8K6J;v)TMnh&nFhDd-x4~+#u+kMY~C)PPflHBUhmSdmA?LHw$U^4tGvC1Ro50t2# z-)9yAXOatzCxC#?4u3oSGsT&hfz0r#Be$Tdr7uwkf0lQ~_SbGk&w!l6vN6BG!bM?t zcImDcW4$<1XH)4jpekcA=vxDvcj#fe_=nF}Ny3>u1drFKf*Uk^e0^h28WisGiy2I# zuVY#__{qUm9|2sB940K#f`(IU*KXa!Msit*G@fIoM>~f0Mf8w@{TlLU(&$7PgSTQV zJE&;Rj1J{>4PXIME=~d}jbqyeMw@m`pMQt{)ngi7PVJb$k}y+#@l9VDK`|EM59-zD z`>sTy2|gG^pk$t{GLFrzQ=C2(9L};7pNOReFJE9}kPI{285=-BLws*)R!;hwR8tXL zy)uud4#7X!Cr^Mn!RnQvb(HOaJeOYGOI8M->n3dbKF2fPF-2BEz5t=OvS6aq5tjiB zUByYkN<0dRip0p)le-ba_vp|%CvZz3CDdfILlRAl>i)}5#I#m*q!q{l73g9l8_+}L zbl^^;eQHlB^p4+}9zd3&m_Dcjm&TxNyCIsl$f~CLtj=Quu2oZ&EYREI`S>#B3?3ir zo7j}auj$8-UT}2~*vXApv(!Pq&a_D%x#x-JR<+u8AgXngGe|lHw2|GlR81YEarZ zB6B+~LB4pXkMUQ<5ze7Da|2=5$wzs^z6OP}|A&FWLmC9seRC06YRqjHd7Bnq?Nw4} zY`WS-uDv`%ffXh95$+KD&>*!!hCY{I(m3p7c?c+GcBllrpWgYR*B)kk4?- z{hQ=uEU=XTd2?>k)@k~gSXcCRbU z61s@d#U?T%FlBHnt5zCzT958=5ea9RB_j+U*^d?T+in%FQ~K@N{(#zAnth^&R#24t z`%|X*%m7@jNP;D%4=qsAd1Q!h#h;k*R^611vnqlV7t5+gzMCP)5#DIMw5pQE83bP0 zZ!SRWqb&QD0tar()v#`vja&~=Hm`_wiDk$_HV-Vo6Se1;7^}cmW21f5>_fQ{AZAi) z-xa%QwV2A7<;kri8qjxJ>fN4Z@m(d_Q`V4{4F4eMCD>JB0}j-BL_MXel^Lp-J`!R% z;q3pG=rF)_LyphL=oD0*Om6K{zjYA)GM!L_Z~D_qQMg2~4NOVnY&BV@t|qQ&eqdtP zJ!1?FYO3^Dh?_@GZK@=u!1}>0<2~$Isk4RILpQ`l?11v`+KFpN7Yk-}iTY@O9Yg zHx>AVca?hPdUiSRhBG+wZa*TAjF1?lqiSLV!kALQip*oOVNew zowpt7!Xp`y;92X}rjeLSO$H2}oC>m0RI@rS(bo=~GGA&!jM7!=E4FA?(hr}1-Xdr^ z7WtwF+oXr~)>Ej;MWMeq+h?OfQ1^ya6#5_Q;jiXEPDTl*AWVW`dcOPwuV4%EEL%(e zv5WWF%SOulajazD{vv3;WBX!dQS35&QHUnAz&oTPONDGr=6X1C*)%hC?q^>>kCGP5 zPdr8cSOnOrdcD2u^6TN%DiA-a|NSmj4!8y>I~5`Zpy$FGE1m(23wa0egN9rK?In^E zu4BJfizPm%&-E{--yDW97Y;i$H{Cjl4a&Gk%)y~4dxyW(gKzD6qe<(D46Bm3Nwljt znU3-SOWU~Qy}j$My*?^5u2w32Pf!ueeY@;1%gJ>I=ZZ-0NJcU|M%n-H3~J7f-^7AFsX(};Hil8W7|g`JXV1Xgw)uXv%f@no;i} znulkdNu3|X_9}1hphBISriD^66<+gkd+?zOXckrkC@M{I$Djnvu1=8Gtns$K3GbPs z8sRUs4c?Xv;d-+}B~gPu>G4*p6s{OlS%&Znz+sfOuKRvTQ82(tm_ zeD1Ohg2-%lHV{e+Bq{m(v9TMsLgT;4o_F%w*kVL<@&2tV$1m&OAuJn}(&03b^V892EaYzmRcy`|CisNy`!q6!dP!dfKQ0nf!jX@p)2SUN z*`XMeQ?v`hhd5)^;y-+L*Q9Hie_q^PayrgfX%!d!Aa4+E-f3^90B2HfmCJ&WSPC(~ z4cc?u889uq=ns$8H#1#4UCcfe;oM|Z|0i-fJ)+0}iHfC-xU>CnOdkk4w zUmZ#b>Pwe?aug5I?o|7AM?=tf273m?)mq=#`MVcHr*EXLC>7V3zUf{Z7b$+c4$%PV zfMKYmp1?Vqw058#w~B4cTDF7d53B-vVH?K#8Fz46_Tqdd%BAw+QPse(X1Rcjv~oV9 zJDJZ9^D#{@Qp>9+4M{nlB9oM}>N0UGNOf!v3f48tw`M9=lDHkg0f!loM%96RDd{#H zV|*p7C7bG08>9OnI&&urHb`p!l`Yb>e(O}BUXFT1HPVTT->8+D4FqoNw_8t`JY6+a zeu=(LzuEd>GyK_d!Ju*Ym~T89XE}wxP7{eI3_c$IGQl#jVH|CydUS~~reo#c5XDxe z8J0)hPGyeE@tGA-x}FRtglB*u+Y1ytY#;dG4j;?dUgNT1pgg|Li%yA($DZ6L65#cp zlEs$Z6;-esH%FqEH!Qz3HXls<7un`Aw?}8S<Lv7_IH8-L#;(xJwNumbZD&BPvCQi<0*4^)TnR+VQ77ck-7{Urgt#h zu6A}GpYjc!=oQfynHY-JhiIx`;=yD)aQkkR_tmEcD9@zB9Z-D=J&BWo;TbUgJuUx1 zD98H+*$=iPIQ7gp+an))xY72#NeOH={Ls2EzAZPa3(ZT|Ym-z59APX`UX8J?W3Z$% zn4{MM5?4w$Z1UTq#G2+9xvhe-H&X za?x2@AD=KWvE3;S9cA}G^Z6>Ya{Z^F@c(4(C}`|-3f5iVkz1^oB()vtJbYWeYTeUc z@cdCC(|bB#kuXgUtgJal?EKU} z#y_5#eBosk4ZU_GRyVeeWN28a0&81b+7E4 zRvhMaU`3ZMHlmWUQ35HhIV6J*8K_UV;R92=59DM9(q#Q7s+Ad}*26Y;*sq7^=2!F) zx9%lnO0sZR;%hKh^Tszqr)_N9N(tAbb3buBaN*XEY-Tj z>7qs?f0I@6rrz)m&OdXcP%{54wz0Ne$rLq)@%lan>zeI z*=R3Ir=_>eBld`f5l*4UeZkATkw1bFTD1-Npns^)eWSp9CdNN(V)RLHcF9BkrX>=h zGo>f0*2H2CC)U6U(XQ7Z*dc$8DqTp(EY*ekVGkWtx&2jGOa{AC*K!BTs=vKN;^d&j9@~Su4l}@+(3mb!|C7p zJNkzWm064+vXP;<-2%4Nq82Mf-ZNN&7JW8+Xv117XsPL@7#e?3n({<3CnQ96~(I+ z{^hiVd*y}eStr6z+h&F~HsmM`+=t9Oo6W6uqPS!JesymdAJIKnkuE{tBz^!%-1%dQ zM58a(P`<0g(tVEhKfWWx#c5KVvHs&ePH=V+9i56SI2X!9i-+7n{Mfb{H~_OtU;lyT zuV&fHq#&`Z&#yRBfP{W*z*TGgDvBKJIQS1012U=feupyVN_+5OXn-&7x^O+)F!Qs6 zYd)5LZmdINNgLH|kkcv`@f|J-)S9RZ?MIwyPitDj9P^layl;Ps5r*tSrXrnZ4;}s>h z@b2O^ut)A+@U`u>8#%#}m3h{=2(3PGk0&8{T9D%^di0=&tTdk3JyBU-#rPV?#+N6< z8LE4RwzHyL+DhcUTcGe9KLgz5a_rQ{OnQ@8Z&u$)E<8<_yQN2e zln-d(Y3hXu=8aVG8_JSZ!$8ttP_QVYC*?o;0K4_u8Jeg~nq5h|pw7oRE4WGSvfW^;$>v?M%pDP8(nPXey4I)z4Mz#C!))9R$x}P87T%rb z(9t_U#Q$ZcgC7PGIQ%%r>Bc4eO@_h!x|Z0_X^@3nqm)|+f{~3*gi@Xi7(dOy%9>I=o!3McQANu7?mbkP5xU`hD z%SG0Xt9o3hza0HTmLHL8w=*Ir`%`tYyFQQ}`YVrsOFjr{{-uA>rFI>tmDyZx!Jl}-Jah86F zXJun}jAVMsccxc=r)v=|fcD)M<<(FhiKgCPqe}-Xm;2`FTBQG zcj0g$Q0Q{iLQDC_(m7vQ{@0+|J%x#v^ywFNWc2?@)vsw>J_CMb&2Z02rTkSE+9x$} zmh)JkasbMGJDHBPRco1U5aaJ06r}{tDOpmd1xW7tFqLo(34b4A-?2y-6}D5cwaKR{ zZ2IPsI-8o~fIf`BsYU3K_X5}{H==%yKU~Rec715&Ovw^%yMnEI-z1;Cp4wTvUB2F# zinTjM(~x{Wl@(7H)*=IX`{%blW~cEW1{0lvtgFI;)HvM}1|?>PsVWeI$dQb#W;9|+ zswutaZDg0B;>;@O|0?XQg5rw4ecdKN2oPL?OVGv=lF+zoH{Q4tG`PFFyIaskf)i+5 z65QP_IKkZ^r~kWl-F?nIRrfx1t(UI#Fl)^@#`wP96p^;=Zl;ufNf8Yo9q$OYLW_?n z%7qrxW!uiDZN0OGT#dKewf*v42majqsgRd1{t`k~e%8}kt|=kF&#a{`8u?{4b6b_` z9JMI80VteFWzEnfJy8aJE-J-5wtu2Gh`c)uwc7OQv|8Kezgl~^c{ucSxmpzkk1<)q zeV(W1LS}7@xS%9dCk-)r@`{u0{dg$ux~!_!vZXxHP=VUAne8Ac%K$-ubp>E1llhTp z29oc*9A_)ijKdJ0Ql%wwM_rh^MKaDPgvM_F^&rhFi5&-CV%G7`wELqxM~<=_KtNfY zR0Q}TCJxQOGL|@)NHmD0u=|cK+pb?d8mcqeX>Wlo+dN=x@rh}`L2=OD=c**zKIS>R zJO`-bREe)H5`g|6AX)Xbaj@oPt400#dRxJ##CjlTcxBl#HKpW7U>e@sOn&u9j!%Qi zRjD=w%@1^o_|i7L-)%nKpzwu%0Lq?rkp?ltzNl9Uk`B3K{HA&>@R^boF@a|c5gL57 zKuP^F$fScqqPhrH9wH`y2oe+$ygB#Ov6m}e4_bXW$Nqx;v$djf;fScL_)1YVI89fW znVjXalZY3>C|l;*B38RptY2jZOOK~(W)Y9%dt-yn0*$)>%zh5GaVq!|z5T9q$mld> z!0UYzsNNr*o$QsLVs$btG%Y-sui-I4vq~#$)7)*O3zjcS+v-?wXjICFF@V*72T;8c z!g2y2_A~%;7xJ+vSm614{eEa3)-zhhLH;K>CgR~8EynHC&^^IeT@^PtQKg}DdNMn@ zGfF(6n64(0NI?6cAs(%J6o*T(H8cK*)+f5A=??*Q(~)3wgByID8x6;lv@e3N(5*vB z@o;-rx|jQ;*{>^jVLR#X2n|=X{I(bb9r~6`KUZDCx*f?AC+Z9`CuL)WN+_V&4yf|9 z64iUm{N*lN(Y3N^T$&!D*@h*I4La1p*GEJp_Ugn0I6C|7O?7({$&bD=NAb>l8X5xa z{{Xn_^w+q~FklFW78XG3ol0%4&~-ZyqE7T5>fwLJ>;Jz`9^LcOAhS09-|r4PNl~Jn z80kjSm}6e3k)T-?ws9z4QLI1_;iSmRiO4H1xDf~O{?BE8xm4T>na2=%>VJTiO5#j? zj@N>ZZB#OUv_*Ixq*o~4=w<#VB|_8hhjll9&#}9z5ckNo)`xoq9h?5b`fvvm+M6|J z7O@#B3lrik_(K2~*>mmCjtXtwMWlY&BcTa!&qI6GGPsT1ldy~N2!R$bunILBZ0}?j zKI<-4MATk^v3L&saUswpZDzVlWB zc5#CO80+14QG;K}gtU}sO8%9(^v|psTf3iI zeZA5a>jZApWz9l+o7LB&f{4Pl`2M(egjDg{z{Zghg_QGLo-6~{v3Kde*&eVK1pi{+ zHeO4k*k&jGF9!!RY$tVOsV_TlVkKBgH$z#>KnC*I@6$)@j81kk6@Ga&KmAulRS8!j z7-qi6$~&g^{j*W;WdzA=>L})VD?j#I^KIG0i%#g!J6deonqW{v`8NGyS6L5-b!UT^GU@7+By^fJ(keTW~2DAe6kE zS#=h8qP*fS&|jlb0@UgN;t13`Rt^ojY|ar|bLD48rH8>R z7=+&NGa0Lo^i4XqF09E1ZW`*-A-`XxIm-WpkE68d=hNUjlynQ`qw$xZe;wwPPdDYH zii2mC(i{~HC7n(2t3r^jig2cWGas3EqmjBXdwt?*vCsoDn9$c+=>uJg8j*2d)v z-J#vt2B#Cd#EE7IHrShn-GKA>1T^h6H*CDmrKDRqa6ew6TZr1a?l`DrOOS5DdG3|o zEEzd7teQa+K1J%tD$ii!rl^+x4ccLtS6hHxLGH?%#Vb!^N5>L^l)6MwY0cP<1iR7? z_}>i5|E^9=1g3}H4Re?Vp7p&wi%GgbDWe}}gH2jB^ols@=7o6waDs^2guMEGf{L4$ zn1no2KC6K%6u^QTILs#TbybteVJK+)X1#+=_Tu%Cg!_gxrY891tdQ<#A+; zzk{?~_%e;SuXj~FNBz#VP}Lf%EH)KOJ5E7-q1AP?)rT!1EzEd}^w__^)lTNvyWY#O z3tM^&3&)8L6^V<95^z{QeP8Mk7|FD88(36IYjdNJI5t&)&PvU$F2a^O!tN)ZPnSW= zs}5G1#ikw-c`0YahF5g~K5H{%(X=#2$PS%=7NK4d1O=jz1E1azTGuTp$t;(PfDdG* z(q<0T*ezRlo$4goS}k&r9198{dBb8V41q-Q1Kui84NnZdtvS0f=a8r7--as zHm+^?kNSG4x|6Y5g^Toply4Q1cY9z0gegto2|Do`kVM=KMN=B@GJ@>eWNtM7Q{60^ zVOz_FC5L9WH^0{|CyI1oss7&02U< z%-6nV)vgH{KG7i;UG0Yx`8d%|LBp2Ccf5Ij8&}E1p<72U!=+-W$>pbch1XSYe=}Nv z#x%P=VKQVMp3p~VMDfq_Y;>+E*3G039eG>mpM-5&#l;nv5I^Bi1f}YxIkflJ_gL<* z_xP9WFeHcR(zv5k*Ph?cGky*FsvBa?bK)1a_{j>IE!&5+xi+$})AKU)+z2hYA?M>; zs65Xw-6^Q?(GbEst`V4$E-3Vk^(;X+bqa{OM=Fi_bm>IvNT_h3rN@hA#}<@jBR;6w zbawaRZN6&d_esaaEe(Gu{DB!>BRnb$`HN5*++cCHU(PjNLYF)5xmJEYm|tzgt{NFQ zAY|+n8|!8fk5BLA!XiaX?@o%2S#5g05QZRcs1Gq8uncuz#yg#nwEjt3*yFhvMLZ-h`8!?mSd z=^n?VuwYmW03srkl(cuX3-g6dpB_HN5_Q!Ht#%UhRVGF}4Q+uGUw$fB_Sdy_M>`7e z<1}cQ%Xcm_XwPId3@*rl!ZLJBO>O#pBm(mvp>7MYZ&+(YH8dRK{{exvd(k6-1OjCruw zEw@`u@tL(%kMRb5cz|yms?;#Z1@t4jyukG0f|g4>h7n;jqQ9v1%S2(v;wW zVqsnjihHhx+>YEY3tUv;An=J_&f1*aiTsW!NrLYd3_D1~ZNH>*Tx-vtxJ(TkEHW8D z61zMSZNWpN(%7cy<;1#aWC7SGa^#UE-AS(@si|{ms>3X@0XA&F1`yYu5N2x9xVMWO zx>4i0Tf>uekFa9ackbzu&GuQ5MP*Ue_9f$oi%x$TWxM-Ar`+0A!-}+QR!=D^T^)tD z97%>!tVpNERt7V_7WsSoRsv&T>@lD4$4yFMKnAgFT6XIfS?xf{?*XGZSeyh=8%`B3 zhO2L=Xxyw??ToIjX@`q#M&}1Ph}w3&o6r}YLydL5f`a3O6_C2ehs)oHZk|uldvx7q{ z>J>5sP)lQK7mBpSE}=V0f_SSd+c`;-D)y}5H4V3$_R zUB&v8^it+laCqE~!!wcSyih3;T^YgD7$fZcu5xNxd{nY((CwJcPAyzuA& zn*~KN)UVi$!sdPPteV&)8g!B<8DvEdZ_5T5w8Nkv3e>b^0N$i{anDZtJ05bt( zQ+H@lx?A0DM4RY|jvQS33O@945_4Za&lpg5r9ZtpKT%XkSV5ct1ay+x7NH6evf+)% z>_P%S`app|NsFs0qLfLG>cD4lL(mwX8ATQvBl|DcHr}SEuZaUvX^x5cmyJl^wPX-? zeNK_TD6(JQCs|iLlbCqz!c~$eW@h;6*euI3y@e!Gn}!m7J zTLClFHI#6uhAP)0yE-h)6OnhAoh5@zCo%PMCXUY zJf>}rc^)(s<~tQGB=Br$U%JX4KL6#P3LiZ3)f58=4|I zZo!Aqv-3|PNmx@7Tvr&+t{g>n_uNJYQ4iau4rj&m{WKoYDdHs(y9CKP6n1PbYjOma z&HROV=hmwdU0g4doMI#UQ8V+vNvSS}kZ2{Cc9kD-^109k^lj6pSiEqZqbK5Ukyj@V zxX^(8f?Pv4RoU$^UjQ*C+g6drMNFda<=m&{&~hJ((r|8Oqf!8ab-LWq@m}1HO}@NN zGV2e&*NXTHtLut>yniFCT4p?+8FMvl>)~#5$`?NmZ@Xn^HmL|y7?IY!*<>BRpUn7b zaQQI?p@c_^g_)*@ZMY3MDXkauOqf`fhvlePid0; zVUBiC(`v1-nU%N}rD+YRpL_1~7MwL@dmH{7>~8%JkiE>xqBH#92GJp>9ZQRK4;kZ@ z!&)`~l;fDwrCyLbN-2KQ!PAPmcB=jjDp74fnz4`pVz6MKAZgw(Mg9ZGkWaIv!yR)K zKqHh9oXQS%@8pjO5>OlQVcaAFf_VkW*Y|DTGRHCh0rI#-Q5-Wxm%@~j$$QRfcHfM# z(s{<|LP?b+977U$vqNpbE)C0oA5s#Z^y$|LZ|+qpaxgq5+c$0 z88FsWNo}4e?C>YunSmYq-k%S&FP+4^5j}Tw{K5sg4?Q5v{T4Md+ior7hoAY3ZF+0 zcc7yI4Zj7YF54jQC;unTWSg}XqVOiK?yb7u!G?85fBe_gqZ4*z1{h_h`X8h@U4?$v zxmT_^aT&}?Q;BbKV8BGP6yja>XhB~o)e~MTy}!jlZ<<-i&7eAz_5LTV!Lf(u?cPIA zqY!9BB4U>F-*X-|TLgHkn?JA^Qzj7Q+@~DAMXEVy6QkYz5AcrjEqAHIc7D$l*k%?u z%Z{mG6xs!GmbdWG=gF>{XhkV2H(LMr=rplF>qr;x^@;cmGv*ng)HpPcFOiVZLR2dB z>#iZXzzCAS29}-`H7$MDO8O3KRq5Ic0ru)~@BVy!zxqvR{g)hitFH5{{;7hGY*HY! zFl`5tx-@1TV}=s?N?O*$^ZOhR5g)>a6t;f=BC=c<;}aq+tFsA;`U%l!P;=3+3Eb%| z{~3)cYYO`~9U^fh7R~~&6E_7eBAbg}RL%ZhiHfQ&eTbsFL6;p~mPnZ4=9bzcg>ZM( zi)dw)1w{|ylXDOUOa?kHrPos7$v+w?FKpiprA9Q4P#u+>v(JNFEg&k`pNe69_V7zn z4hEL9{Oh@Jnz%}Bi`^l=jD1lH)5((g`C{l^;aIY>gBL?o5cCNw2Ct`N%rQh ziaeAVNW>)Np%ZNkXM2|ayrJJlS;;UNlu!)zTT7nM64fSb475SH$Mi3El!{DSy%u}Hu>o`dr~p1R+wY2p`^(Sm6L zL2n-L46K+DJzV$16^ftHdmW7iTPp#F^e#=VFrB$+$FJ7Uit6;Bx$&f9d{--tN<4>m zxNjyRC?iu!xdWxeDS1s0gGYowFRl0Cru<8kvuto;*vV8dj}5GWU7>YSmIfs#4>yFl zbRUoiCX}R8)&DwFXRSyQ`od(?wqmARjmxgUYuOl4-Szc0G0gN)!XLT>R))fpU#0^6 zf!sfaI9>`rP6zBPe#f#LZ~~Hq%t;BeOqRpl%}!|FcM`07-*TigxzIc zH;MASVyXz}B*0f5jo~EPMSj^ltcG^`X#zSU9Mn9|_7hNb@%?rPaYwU}BX zw_wD+{s_Wd>|-J#$Jr$LlF)#1{pqNfsA}E2QO|TN!p>_Qv?q>FA+l`Yro$fMgOSL! zfK%KhK$QWPn`-9^*ncN7l2C@^$nQ;A#v(rs0H@n7O= zTcbm?70#lP6;oMJQEg!t5o$iVf%S#RQIGF`TIUo490)9_#&n!K^%g1XHLL^Y+YU{9 zrnZVdL#V~V2!*Z-*D7jG=jPc}a$&@sn?%euN99R2wGz5)50on{VrDR;EJ{XT>P9$gtwg)I(y9BY(bF@O zaAZpf_ows=a!59GfI6)Ep-iGo`Yuu4Q@f0cnE#Ti>RBE;rWki}%gQreM*!tDQo`jzyKiUy84FwXq6n5s9QLF>Qg1_EocX$%R*>S(87f*mn zFz{u>5FZn1F!G5^>6R%xa-aeGCb>apR3de@)ydK>aS!b6Yrdc8m z={x?o_CXs)t?xARD*=@t*8FaBbRA6Q@hcfFM5@EQmSUw|~MLlWyl@j||+!QJrU)Qcu5B4w_?@Rq!px5B$LBxRSewZeL zgBGz!$~|aafhVZITv$e<_A9VG<1JpB)RRN>lS6x^23q-&T7?)K)frGk(7T&RWYhN$IA#<4)gY%lO}7Bu=Z$#OIXVK5X|9xiZ|O zTnT77WgB6QB>Avy--{2pK$L|27HCQcOd`mwL2j2KkYbRXQ7`Zpk_|&IK-);Rj_@$Z zuceSOPjUKMEU)QjTE%@3MOenrm`$BSE5r3bEz!l76%uPnlQJtUKp6*H(}6k|EH(j^ znFTwVm-rIx@{d;2Y>x>wu2&H|v!_=JmEgfuU5oYJK*f&<_LiK1-74CmcT^ojN*Si>ZOyjYRb(O*o_!;R5l#zMe+jKSm8G!x zzR_pz^>Je&EO5<`=1fz_EB55iE zd{{33rYJLb+HDaKh=y$3B$t#7=byy{Rr;{FMKm>%ZjAB%JTK-*OS7#<=(aLSDpNVy zk!wEFkHZeV?3TiraZ7pbd^3C0I!yLQT}qr~ADYdS$>gH=$I1qtaV8%1qA;kHw81o} zB|dKz@zR#C)<*N>%q@+P1XAByckFWn4DbZLo)ek*fkw1g>G9#mi^w2tkM*+qFm?SO zSI7M21(zOD$A{AUb?NssIj1|9`u;x`D$HX~QGAOOnb z0#(JCMDV2^g)v6&**wR|mU`$0uU|92dow$$_AH}u0Ih9lX)Zl2owx{!KY(bxZS{{P zJG7cxy1le!Nu{ckzH}ca4|yo!0U(elLM3n5LbBMUp`u}}3)YEJq&M=SyAly^kI{jWbcQ|%f~Du!uA{wLE`!Ki^@bxa!2yxR-Da=;$$Lfu+Z6jvV{cw z>EG>uy-{Tz4ZLRKIm{~21c^JV8&mhB_>~O4qhD@6NWMzgSz7X2gS-#xh^mS5Rh_=( zhsC35609PX*|*49eBqC*W@U}Ob1yx8;Aq@Cd=L)wK!i5)-9KyDpFYl0U;ClFTq5F| zBRoU8X}baroMV~$?fLv=X(o3dLG4Pf@~6iSz3;{m za^;MldIlo28!jM;7Y3SWht(k_1UJXklx=I}f;-fTPrRd_j#ci3QG$FEOm9)R^&IAA zl6k9+nc+o`F|6W0WsidL>vPmN7;YL)aMr0xCy+6nk3_HH>RyF07rgxj(s5qwi$J)d1H>U&-yLUvAI9 zp_R`sJv11C@Yi*-3Ipky7wA=`l>fR-pO`0VJFX-}RwP!b%N%uw*29Z4@s{{4N=R+M z7P}MP`PdAiOxmwt_wxegk#{p^u}x;{M1dIVIi1Nq7HJXk5} zW5aW)(}-drS;B`3q}jJF@xt|99dOk*zG?_}EM{H_UO3GlrgOd7;hLS1;!Y2-aG*1` zxWJB}!j2&NzQ##D|H@Nk^DXgS`Wj4Pz*e12|Ir9Nw%e(b&>lSoo&8JN;-t&$4K{vN zJNUj)KYQ@*5^Ma<@wiuWD!;2v*w(Wj=j^J83(5Mp$ji_jHI1A~sF$o-JnM`?pY`i8 z@}~i(PE|O!?w##jNRg5Nfi7|c)_6B|PPK+kWfj)$+I8Lbq$}$mH06aNcAB8V>e~5) zTXM8s#G0Cd70+ik46XD!!=+MVrAIjMvOd(MA>X7^Z{jVh_a!d{ag>*xKXl*Eb@ykW zR8-@}+D-bBT@q1;trb`Y_RP?uL4|^02JjHy3*rzQ6xC4j&@BP4sO6dw(9|jd!!ln8 z!)pMF7Fp-GDzh+|B!cOaw&(e2W1Z(DOhjpt7NjJ8pgT#uHqU#{m$~~YG3XWQ4`kwD z6Xvsx9t*Zw%FwB0c~C-8K2Qb;2>1s0!b)-FJbY{~huQ+Ll)U%{cn?a-KReNbl~rQl zP-4iu5c%$4UQZ2%%NdiK2*tk=Q+`*_7EVBsS_ zbfyVT?u1M3;8(u~_fKr_wNyrxcrlqQir;ixyYN)`5t65cY#=(PDEVs;zAU+p-n4w$ zX8inB)P?!hVLdDmQRx0P4487NlonJ-xvcOVkIBKfyuCKXq6PyiUkh$5cME0v(+R&8u`^$TJYb>c3$NwZs z2{()3i_@eq0R9o89N}mBS|B}n>bq1}cq52kee@dsFzS&;mi^dNO~3fQopC2%Ren%; z5v-DE$Tzf*J_SW$(Wu{W08**Km4vQcQphIL7x04>6L&f`r|r1kuL|y$>zG3z@t24I zO`Nzzr3F4AbV8KxATtMV}rMF2BkI0R^`Q=n_nABkYc-#0BbhE?>v!{3$G7mi*6$IKe6~rSQCDkOy<&jOZ4Ak_! zs5f-N@;f5Q+Q)Xm2jFWhNdy3J{h8w$q|QC&&JLeBJW%CvY`TyrN&l9cg6XcOgUyWd zBaonTKtufhpvWpSQ~YVfiUw2OMN16QEYL~}pDNkjhGrddIJ0`@)jZtzntUwLV~?@= zw;b5p|}&1F~K{bse`%NvpV9bMU?;=e?|D_^d)jtzqXK->IZC>DfAI}sZFVaSK3qL z-XwF(t{+`>YaQNd6Tma@&X+BzYb8Hc#yznJE?5)7SZrX2HbucSxQR#y+*d^MJJgS6 zLuX@OL@+I#Fa28R1Esr`XTtDtmUokzA|@Y7I(M|?%~ovvAWm)b3F@y3i=hrt(8d~L zF&3N(UrFdne9(O;o+|!cpnbKt;swojBUS%7kqNt z?0h1JpozoS*74XW7b)K;WA>j#DmtffNwohwSoX3n7IWKWaWhz(rWG?viVwQ(aGpj( z=Tcr_Of=-ZlIn-&Scx?}b>j6qtr+cvn$FFvSkI>qNASJR*2aHiA%mieVgTX>B9r4N z!xNSwNQ>aZ%(6E5bfQ3H5u9z7kBbf2Qp%s_yC1}=&b5Yo=t`olS>{v*7ov=+klP|=sA{&ThuoWGi>Q%=*O8Etj@JY1q!P~axrH#&_4D<>kbtDm7VcC(L7FVD@&`kY+gBoFz{h-2|_bK9CO~ZuU_c**G4&Ek96hpbu z$CGPgI6Y?YcWcs;`1pL4Z%}DzC0Y4|p;hk4@rO4%X$%!Ix2NB&#Q(d^SoQ9`q{oe^ zAStY!y0LCE9wY1MOI67MNPtp`we`qc=%*ZewN))`+9UhKW!kAK#QcKpBvtlIf%AFf-z~ z!iRg<;ug~Pwc)&W7Ru!NRRafuilVb3c=>PvJfaIct+XG>io&TW(bvcbBgXe3pKg)5iDmYspp&!ABfZEiK z1z=%EaFyl%o>;WdX+KnRNXVbImF> zA)<+aQiS0@7;uubqsLMqlIz{JU!9>A_GN@ulH_`B)jg{Jc!BVN10J0+Y*l=q4`gdf zAC?FKj3uX_hW_Dt)8^>;~It4>2a$sdD;sPX5 zgHu8xpF`MaMi|%X5u98Kxr^6lZQ3{DoD`>fogK7zPKM}3YK9213sR^LIP?v*lzhcJ z%B$DElh+dcO=ixxC3W|V_nouSeaS@9d-)GMn6|#mK^+ceU{yM(MgpS^aCMOQ|FKUf zYxvwa^!{dK1$`WMG?9~LpRLDKm^1eWZ~TWD81z!#dgD8&nag}zU-$R9#c3Tq7xA@U z1nM3l-L^h|55FKM5cC?3Wh9~EH{Z!HU5qjx1CR;atg@|fET88$*6h%T)USAc$1$3$o$|`?t4Zj(m}?Qw zR7)vpJ_Ha*G;@b&A{aIYZD8}1&rag z+$Nl@srJ9t30R$Vs{bK-))Pdu3%cYWURBgkO7Sj-B(+-^&Uz)?o2`ePscQ^RD*cK2 zR;SP;!2uAwSbBF<#>Zq~A58c>pzV#kSxRA?pxMspY23SMs>JbgHfEtvZa~8}HZ8R$ zgUn@?4G3n{UUUBY=4j&xM~`x{z(#@CGfQ7tPiztGH|nmJba}ATk1KZ8$SVs zUvX$T=-C-qCdtXs286rj*~Q+6nBYo;s1DtWWBxu>e{#IHPq&?y(o4dBi)m7JL1|GJ z-|*;=&uz=A zJf)S=mQmJqaGNg-rb}+bDqS4KsSO6&`T5Q9TnwH+iug3@yIf6GA7ajo3txUprHa5f z#C%oXBoN$SXVn&;bpLKuSh1feh4?3R=a%(2`LFezOjS-}>vLgzq0NbWqR>S+s zmz~H3TLM4QdTBG&eF7WkpN?*hl-F}bG8SkMX8pMJvZwOP_=_>D=Wwoq6#^Dbiz(9_9~cyLZO)E2klG1p!{|Sl8u(D|WPEshb!9goBgYv4c71PE0%(reD-?y@uNju5IS>s;6G;T2>Hj(Q9;D$^1Z~8r#pWsFP~%^MiW;{{S0vEEr8#H`GqZ z&cZ;ULxuUHszoYEtKLehRy{qa4yH|NmW^Px&mJM}vV6&HDhxMX__H#v2EEY&y^d^i zbYtFNyU=^_Fe=t*15atVdhx`HGrJWnP??@dpC!$+DY|;5Jqk;wOjqCog&U(!?wECn z8ZpcGllpQ-^=6Il?|R9t%7Nj`AsAoSTON!M^p5XZ9Bjbr)6)gez=Qj~-&kI`c=Nc3 z%!%j{c8PLtQ}_weUlgi*6?4SWE?2u*j9O*d{&>n=)KYHKA_a7{Rh^i?aITvwL~X)- z!*YNfaQP#(?h+f-cbMdtkwS}9CnWsnhDNu-DUa{SH95Iy)0Z|Gm4V?KO3<~^(;;3h z>%-tnym#c^6@J@Iw)b4H+H0(pD%-Sd{-@{A37pGn2}oa7T856}PTTjnW#<8`#^d{c z01`*OnW}XgZyvH2;otRLn3{V&qW!Hwp4|#z&Ms8DjSBaoS`KjcJ0_e{*u2ww` z-cIK3T>AvtC|g-F0Z@*88Rrrxor92u8Xc@XSBXOojho4w_>lmhGNj6*R?}rmS0erH z7I}VMnboJ`^l?ijd4-Wr+U1tYXY|Sjt3HL@l1~Uf>55CG%`g+YjwZd2cUwKMDh3#JAl3m@3*wW8NTIB^OcNqsto&e4Q ztkVVgj_=216=EDdC0#ux)Qjdu<6uT-KLo>i3bft{ul@B85R98fD4ZjOsc3~we}oL? zzmu~hbRpThKrW-fDvDUOQMxaQ+u5G0;B`FxX!ov{FU#5LyP$)=DRCAD4{q68TBaZP z;LDqGmpQAsL$Awp|Et-LxlRk_`dj`!Vn}CdmHXD#caQU8=P?DRel=@39sten3AFHG zFBXSB)d^Yy8wRTvud*NHWuBOaj(@f6KqHaU`1hvi5lUwDY3Uy1Q&WBc7dX2(@vbrCt(8Nb+6mQZ|QkYY5Z^^V;IJtj;*d`@&vks;q$-NO5HIP#JsIZ!yIQ@YKZK7$$1t7HXp<4S= zcC^Ed!LzvMq*PH`Nx(Z#yw@rm>8MF7rYHgc;Z$p&MNCSY9_V1wc5kiU{c%* zR?3dQlnr4@GYbPg=$a3R*@eG%u5e!~@uN$}G6~ULIA@*oLumP^;`r5D6@|nX?tEpvsgZhur zmGTD|1I7p3yx>RUs>f4943qh{iK`g=3mrV82P#R%b(bF$@$hF%n~=wEnKg`-Fp_a! z&q(XV9C_^Clmf4_tgMQTx8`ztC^QdDR~dEZj6ZezLe;R@+)rETV_+;w%1bYGZH;l= zDF>|K6?6ToY6mVSzRE(DGnhv@G@>fP7)$=BZ-Mu6$JCNUY&l5^Bn^g_LQ;h?D3{T; zYHRrC;glva`~wul=bl%RP()Yhvq?sGQ}Q?ppC>+FR`<@kDq<&Ga`%cDs;nvZEAM*g_#gjWMtB5KJ%I!RsO= z|Ik?}pqd{;c|8WFQWvOAsKuq+O!i?+lLKq>AUvz3kSCob6~>U<0rez8OiD}nn83nA zZE=SoW8!`7wA&z^P@-sw2KX~9L?$k2Ao(A_RM+_X0pt&e7{+!CVMVi4zVN0tRWta! zIreee8U9^-E82khZArP&wRzkZ8aq#_3!?l^;judAKTc@*De!pKAKU$vjpPXd@jExH z*8DxhIYyrhS8~#a$n0s#L}g8Lv#*eE1hD)onIkJ4m+?n$aV)1P*JC?Il44tF^I@Fm zcf%gnDR%wJgoL@m!pgVhW5Ur}?kNo*Zw+erVjiueMU-9mimO=MOfU_~(Z0`*X2-_0 z6YplzWK9=hS;|zM1N)L~SLZNto0_CsW{buf;j_V~Ln(^0kJSlGl~PWbyIq>2!hiOS zXHA7_X}A(M-Em$mry3Q;Up(5tW~}KEMd~0C`C)2lLkt>vHeuw2ucR z9-^z%w#Js<%t=iyxbq?M_p5kGt^@U!1Ygu**RH4DV>;|MlVbQJ=NvQJ#|}~{`upyd zW5tVBBr5#Dc^WI)FAwfPs32wZCvU&Kx-6-dxuFO{`t81UYGS$lVwJsk{7rge*Z5dU ze4T*Zh876DJv(0kGm}q+KahoQ>zbnu-0Q^JcVKjHeD!cCz9oO(v^s4BVp29XNnqjk z-IC`p^xCnJr(s85Qr%Nba(j{7`ff1fvG->C8?hXpI(MK{^AAGa43uJenH(T|NiKxp zqpp}BJZKOAG&smws9O2XFy?`i&Pk=bJeoY?7XOmqY-_BeJ5=;^7||KM)Sszv%F1Bu!58NX+^F^;pxe`}MK> z#>&-$UA$HYp~ORD{l(?W%>Mz*Y86G&+m_K_N7~o!)Hgbxbt_u_RC=h)qs`ng{R4oC z`)|}c(;XDwIg+)SKiNc?^epuU>by_yA6ox>v8eugqnRSF>AfZ#v9{OkucGneWk8Z8)O) zE*q0Th2~ynMk-^?(|(P|+sZ@+k93O?OnDxlcoo(kwK*mA&`hu-Fk$4!#D0u$V1>?ZEn?cEq_~hP zoZP{&g8$TNprLmkrC*tQ-kQzYnY|~PvEY}rkl~|3+tIB4vW-aeX5Z13@8=2G#JYL= zG^!ExJ8wXCz>+r)kqt%^Q`|k+SkJ zk*&t%0%B1WN7ITHZKe})NaDl`R^vv3N{g(a@5TUb>Icd?wJ-q@6 zQ^T^;e={ov-thl`&!5PT*LI=ffEKQ6%ek0e(vj+l|AKk@mGqIiMY}YB?@F;X1*O2+|I_n4#^osT;$ARTjqjwtNK( z=4qYSQKrOY-hCGqad$oOg49Qn`e_qdgt~Z?kk8B@ZAor{ekMas?W4w>(o_fjh@(%^TXw5%ew<(GQB(TXHr|&l|9xPLS3cE8;X+rfZ?F(_II44A&_51{r)Lp15(B zYK}+z)JDg52j|zbnbJ#;x%tHl6M^YRj8TM(s zQ#~?DzcI&4=_|E45PC8+xJ*(ODuS%D2$*jYx{cWpFg71{VC@ifY%q8}EOM)^Q-A6S z%h4XTghos$6(}VaB{KkJz(ByP-HaQn_BjXZcxBVh31RdYL;Poqnd!f(osl_f0@SlX z%hz%4igAJp9VvFdtch)DHod)wSZ)lB<}_0`W{80L(_m|qfE@@l)SsL_{`Fv?uLjQ! zyQTs^()7)33d^69&U8`mKR}MQXqAWCBtevK^0%OGi~r4lJ7s>Pz6^0SkL=|CPRF)05(FaF<1=YM`e5<{N36TnG3z}rn@*U~b%7@YZk{=vV+{{{PUkv;$b literal 0 HcmV?d00001 diff --git a/doc/src/Eqs/pair_edpd_force.tex b/doc/src/Eqs/pair_edpd_force.tex new file mode 100644 index 0000000000..f6a0ca0d3c --- /dev/null +++ b/doc/src/Eqs/pair_edpd_force.tex @@ -0,0 +1,33 @@ +\documentclass[12pt]{article} + +\begin{document} + +$$ + \mathbf{F}_{ij}^{C} = \alpha_{ij}{\omega_{C}}(r_{ij})\mathbf{e}_{ij}, +$$ + +$$ + \mathbf{F}_{ij}^{D} = -\gamma {\omega_{D}}(r_{ij})(\mathbf{e}_{ij} \cdot \mathbf{v}_{ij})\mathbf{e}_{ij}, +$$ + +$$ + \mathbf{F}_{ij}^{R} = \sigma {\omega_{R}}(r_{ij}){\xi_{ij}}\Delta t^{-1/2} \mathbf{e}_{ij}, +$$ + +$$ + \omega_{C}(r) = 1 - r/r_c, +$$ + +$$ + \alpha_{ij} = A\cdot k_B(T_i + T_j)/2, +$$ + +$$ + \omega_{D}(r) = \omega^2_{R}(r) = (1-r/r_c)^s, +$$ + +$$ + \sigma_{ij}^2 = 4\gamma k_B T_i T_j/(T_i + T_j), +$$ + +\end{document} diff --git a/doc/src/Eqs/pair_edpd_gov.jpg b/doc/src/Eqs/pair_edpd_gov.jpg new file mode 100644 index 0000000000000000000000000000000000000000..10b303a218b0fa1f1bcf78fa6a416162189f2cd0 GIT binary patch literal 17725 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'U2uLLTQIA_8%I(#of1||JU2$LnE% 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 E0IUS%5C8xG literal 0 HcmV?d00001 diff --git a/doc/src/Eqs/pair_edpd_gov.tex b/doc/src/Eqs/pair_edpd_gov.tex new file mode 100644 index 0000000000..782cdec99e --- /dev/null +++ b/doc/src/Eqs/pair_edpd_gov.tex @@ -0,0 +1,15 @@ +\documentclass[12pt]{article} + +\begin{document} + +$$ + \frac{\mathrm{d}^2 \mathbf{r}_i}{\mathrm{d} t^2}= + \frac{\mathrm{d} \mathbf{v}_i}{\mathrm{d} t} + =\mathbf{F}_{i}=\sum_{i\neq j}(\mathbf{F}_{ij}^{C}+\mathbf{F}_{ij}^{D}+\mathbf{F}_{ij}^{R}), +$$ + +$$ + C_v\frac{\mathrm{d} T_i}{\mathrm{d} t}= q_{i} = \sum_{i\neq j}(q_{ij}^{C}+q_{ij}^{V}+q_{ij}^{R}), +$$ + +\end{document} diff --git a/doc/src/Eqs/pair_edpd_heat.jpg b/doc/src/Eqs/pair_edpd_heat.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b9256a1d13301ad83ffe4bb538b10090aa73b223 GIT binary patch literal 46952 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

3G|$svlyG2#rwLqyuF^(Xc`H)d(Wq;J$3ncg?U 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 P|LQT=|59^M{GI+EmjCBP literal 0 HcmV?d00001 diff --git a/doc/src/Eqs/pair_edpd_heat.tex b/doc/src/Eqs/pair_edpd_heat.tex new file mode 100644 index 0000000000..241a1bad64 --- /dev/null +++ b/doc/src/Eqs/pair_edpd_heat.tex @@ -0,0 +1,29 @@ +\documentclass[12pt]{article} + +\begin{document} + +$$ + q_i^C = \sum_{j \ne i} k_{ij} \omega_{CT}(r_{ij}) \left( \frac{1}{T_i} - \frac{1}{T_j} \right), +$$ + +$$ + q_i^V = \frac{1}{2 C_v}\sum_{j \ne i}{ \left\{ \omega_D(r_{ij})\left[\gamma_{ij} \left( \mathbf{e}_{ij} \cdot \mathbf{v}_{ij} \right)^2 - \frac{\left( \sigma _{ij} \right)^2}{m}\right] - \sigma _{ij} \omega_R(r_{ij})\left( \mathbf{e}_{ij} \cdot \mathbf{v}_{ij} \right){\xi_{ij}} \right\} }, +$$ + +$$ + q_i^R = \sum_{j \ne i} \beta _{ij} \omega_{RT}(r_{ij}) d {t^{ - 1/2}} \xi_{ij}^e, +$$ + +$$ + \omega_{CT}(r)=\omega_{RT}^2(r)=\left(1-r/r_{ct}\right)^{s_T}, +$$ + +$$ + k_{ij}=C_v^2\kappa(T_i + T_j)^2/4k_B, +$$ + +$$ + \beta_{ij}^2=2k_Bk_{ij}, +$$ + +\end{document} diff --git a/doc/src/Eqs/pair_edpd_kappa.jpg b/doc/src/Eqs/pair_edpd_kappa.jpg new file mode 100644 index 0000000000000000000000000000000000000000..158974d37427261ccecdedbc98ed7503ad82760f GIT binary patch literal 5626 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�maTAZGUv1_2op;@S$|Bn0#WetT}~bev2kt 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 Si-+SpW2!{c|9^4%L;o9zdQ)lu literal 0 HcmV?d00001 diff --git a/doc/src/Eqs/pair_mdpd_force.tex b/doc/src/Eqs/pair_mdpd_force.tex new file mode 100644 index 0000000000..b5c8d9be4a --- /dev/null +++ b/doc/src/Eqs/pair_mdpd_force.tex @@ -0,0 +1,17 @@ +\documentclass[12pt]{article} + +\begin{document} + +$$ + \mathbf{F}_{ij}^C = Aw_c(r_{ij})\mathbf{e}_{ij} + B(\rho_i+\rho_j)w_d(r_{ij})\mathbf{e}_{ij}, +$$ + +$$ + \mathbf{F}_{ij}^{D} = -\gamma {\omega_{D}}(r_{ij})(\mathbf{e}_{ij} \cdot \mathbf{v}_{ij})\mathbf{e}_{ij}, +$$ + +$$ + \mathbf{F}_{ij}^{R} = \sigma {\omega_{R}}(r_{ij}){\xi_{ij}}\Delta t^{-1/2} \mathbf{e}_{ij}, +$$ + +\end{document} diff --git a/doc/src/Eqs/pair_tdpd_flux.jpg b/doc/src/Eqs/pair_tdpd_flux.jpg new file mode 100644 index 0000000000000000000000000000000000000000..9da788ae9bdb1b4f927af09206a55c307926d3fc GIT binary patch literal 22023 zcmb5Vbyyt1*Dg4?y9Wp`xCeL53@!m?AOv@pf#8G$0>RzgZ3q(F-Ccvb1$PUQ<#+en zz26`AK704{^K^B0Rrjf`u0DOvdEfrG@NWZvuOz1^2S7kT1TeiWfPc$?_W&fs|HyyV zNUws7iu@lzM@2B$K!oa{Gz`@1C$0xwY#3m#n#3y>)#{bVn z5dL!}5;FShiTGF;Sg%L_f6Bj300BCn0AUvi0SG`OKtLiu_}2@d1|R?skq}-5@c#%Z z8Zrtx5+VY|Yqcsq009XZ5dra4H3}Lk-fQF6eE1XruohHX$IRukdqPrv_0-Jk<;ee|=)b9YRf&Lzg#20~Oz^4* z0Tl%i83p;ZKmVzC?Iax`kBo+iKN2i9_Z;|(h_`D>HXttVf?l(F6S;1=^5Wfuf+f?-@Q^z>KBAPG=n))fnI9}iPU}9_ zIC38;U7c3OGd?o!5>JMq=K%q=)5lCA8Q!W7llsPA82HyfCmx;>?15*T$$A!tSVGDI z{T%l$Xf>L^R<7DDzdTuZSoV-zwn%K#g9ki{ZQDm%BSFs;rRXAd$NrNG#Uy1sPAn?D z;D-EXw2@0O_j!xkSfPT8jpY5te}H)veaucvQb$mCp%It+-prlq%9a8?MM(N&d?aDL zZAfNf6?CcS=#2FHu!e-<{!?G9v!Ay1Lz0-bNEE#gJ5SU3Xndt2FG*IWSnHoWrl%ZW z1-u%=3V-E&w6e-Sz&qT0_SoskTT_ncIrHo#b^6FY3m5T+R_YObm6R-SoJzy~15wJ@ z+QjG9k!F5}pF&xVT1Ld%Ke}q|qn+$y6tG(`;h4qm=cMem?Y~RyhD-5X8k9KDhk;@# zNe0?!X5!Kk1`xur7OzX9~7II-XG+)i!3a&~F&0h}s&5N@W;P;iWZe~?mtW^FhK z4{Ij;geMfTgeqxHjvDdhdfZGtv72okmpIRek$`FS_LNo{npis@a zhkZ6vcp+^}7E6JWuw?(h&gByfb5Dy{D4UI!I3WN&`Ov4x5`8W_(qff{n(#?k$bW zn4_;N=HH$s#x!D|h$C-0pNIk9kWVnE7Ce`QED#ErcG6QFWDP9h*|T}Q<3xX0yI#4A ziA=)X!(89GB|9K91EwLU6#5*i&R_&m-wSEFfxw`hHCeI~R|m*Z@^uDy_%+22;r1YD zU67PHeS#cgC0yQt>~gBTST4Sb)+a`6BkH=|&40XjfvDEB+#8~OGW-$e$J4lw&k*@{ z(f5HpQuxc?MxwElE_k_F9+eLH!~B-W{7Tzw+hC6JJ$z#2OFhwsv5$p8y2=@7`7Li% z)IA|-I&VIM`p`9?BwEUaIpu>k-f{C0L-e@p(?i7uq|zB5tcgcsiM$Ea**dz!%Y8J1 zK_BZ!GTX15qTT9LY#}15`9E8y+=)p3vT<5KRRi?j_BHhgY~4IKB%|}VVktQAFG_Al zj9C*MOI{gY{sa7ugIXC>!0hWw8$!ov<@~9KxC#FOAOJ|{*JE(Woj}C>k3U(-*R+v| zIE?#0xF5TyWzgJql1FUTM&4Td1Gu}YFeIlVuU9Q{`K$VUU;NOV_h491x}l?cqx;vL zqTwxf{eE%|L#q|*qpDQL9!f%pea%yv*`kHi_pk7Bos?S*_Bn30-CMz3$$8?7xt?=Y zm3QXrC!9M380Vh{lr+c}!fM0krWwx`wBRSBu14q4qukT9Zv(&aG3ev)QepYgw%}Nv z<`Cte-s|Z5sceUO6!dSopbFlssxK+vtbSx=`?`1=^XPPM+c2sc%y>Yst!y!G`bLNr zp%-X9`yob^Xb>KXVdK{ue)p3Z7U8yxU|MD#KCP^3+P8F?}h5Npth(%yZL0PS9{KNn2lKhe7W6V8pF=lH1BBHS4AV*$j^EGRI;k4ZIAVXJX_u z#E`oWj1ex#5JPxDX?eN6fZ2@jgsqPE42Ykn;Ew-T^e6iK$mg=!7JRASzVFcVjb}>P ztUK9~*Ltqn+~r<~p)qc>pC9jDe?NB$~Cqr+(T_4(WU zNIeo1J<)+*2gpt$bh(ktYnjdX9X3iDgb9TNtpA&WjC)_(hUXt(n4mvZ;vZnQro(@Y z^S3;eD%w`bJ!N^=vqX0kTp=5Z&s~vJxv_%{%1Gi`RpR@Q;-VZ^DCaJ&Y0>5ZYgi$$ znW8S5MUQ0{qVIzpH>2yhC@T}C*lfg1G=}{c>1;vM7_uE+P4~> zuMqS~TYPuzC$FA)3VyNPr#|P9>U8ZjJu&%HG5#*!;9haK zbXbVt5@tn9oQtJ)EaUza7zH>P|GF*qm@pMjpq6zKleZSDK5N%6bcW z8CBRI7Kng;2zG?og0>JJF+DINh?D=oEv&HujiQg7%b6`Z93>D+P=(HQu$tR zvP(tdGn~b&R@FhWE>WrCW-b2<8JpED{ao=~$acrQ8S|5Ao5`jhd^xEn{);s1>Y}fU zIn623yj~5Fdz8f}yb=moa#F6GvfV8FU_2bC5HxOBNzu4>r^dFi%&`;B{%%CKN!e#n zJ~l-#NB4*M65O4}lRhfZ?J7_E2yeoLiapibIm?&Sr>2Idp$2csnqVcY0DF*Bg|Yf5 z>V`oU1&K`bkHQB^8Bm#_AyK&csKesZ$a}~26Z`_boH2UIQF-5V=5O*}{48wRDjF`2 zyrJNW4%jVSyrHQ%S-PkMESP%GVGwQAI*c!n$zEhKmfAW50a|m+URg+P4|vDedj&*x z`9bu#3$tUc3SfUAA>%xNn6JytU?zlh%N@4VME&Hq|GBAOaG6rGIT=9?Q&DedKu>!S z){mkpZ+eL6Kp+@y_>`ErP(J>?7b*5_pOX+}1o_W#+r6LV{{W5W;pAxXr z|9DUVd45j+1$vd*9Te-`x)miJg}7Q1{mZB5Q*56f#Phku7c&3+!9}+CFZ_Dwmx>Qh zePkJ9U4x*QQv+i~ue5#pqPxTI6_WQ3U66$oHbU+x&05FvI~oZ|iJcR|=@Sxa)YIJ0 zNo2TDw7K<~eY3vlhW?iXB~Sj_yQ*pgRWc&+b4k)q70GzFWzVLl(tZc9r?DR=qTFQ? z_3O?%Bd6NEf^7@#_w|f%->*_J(oa!ewj_^?h9EP?b;=vJ!A(MQH1DV~D*06O2%@d4 zc@VkuTqB7tD@X2LUvLYUVxI-iG2d%jQ1Ow#*6oo-w-EPFIgQVedf@!T93uGUf+qiHM z4qgKPYB47xfCj}JYdI_u;#3pz^J(`%@nwi1;W!g2ed*i!g<|nsDn)uD?r}A0?ilP5 zx;a>K1bOm686A{5Ugxn7Uk1>VWi!Ey&{1RV-t(VxEwdLhqP zv)sqET}V&a2!>OuK%t^>%ogR}7QW~MPW9E|rc7#bX=4=SpDrg7;un7+Sy4J3@W4j4 zeffm@U02#3_l&%nO1(}E%ol&Y(Aj+W@K*@-yf#RTciMze8?jt5Nv)vj2anE2%ae-y`yrLBM4my z*D_u-Yk~2e7xGNqnNxfv`Md%(+BV3bwAn2RppVVk8gt3i5rJXX(xx5)-EYvzr~@Kb z7QdY7raVr?N;I~@TorA<@82bpXAQF*{R3E@#(%Xa4VDCF3Vrv&r2h4Fe68;^^4Ip? zBa&YA>gOYa{v<1>rZwGB*Ee*w_bYk=k$Bc+b|Dpn5`};1Ct5FxZ`0*;&a^=($0Je4 zik#sQt;oyYjAThv*|`6fP4t_5eKP4J>*;XKIJ~Swi#zG^-26HuZqHbJU6*rb6G^Nd zvKq-9;ymEc3+!3gZPWdr3dHQkZC2lf6hBCDoSISz`ED;S9ZbS1K{`i8v2VDi`lC!6gE?t|(rxPnEdCZF5zl+t#Ux>u7#s-=P!&Rt6>E3o7_ z4ZNiTN4lW8nuU5)o8Y+cHIAL`x(AM^@!8+!#=r{>yXggol0t7&-H57lj|Ly6XDfQb z7A}5Cb>}smi2}Km;^`K74Q19Lu)B~92?w`@WIY4u`=JbvOe2va+>zsySyn-8Z>pxz z#-c&~%w`6bl&bCAFA03fG}y{}y4m$EfrEyFi!o%ff*2WpnthQ^4p zZESU8JYPR}i2FaJknxz*WAUKVzjGAkyJKF45FZ!ZucXK>ooGnZPII+B+YT36@@SiA zN&R|TF4Zbe{SVMXA+=3ny77DEaL!aABQ$Zzg}qtSyv8BPtggDeqB*+Cg~p&bGr4L1 zS}A6_7MmlMJ>}V27rUAZd;D~;EZkH)9M|A{PRfJazu9_Ejul87x4hE~{ zosf+mz1?yZ@3ORl1Hs;Mo`}mx%+%dUe{DOZKQ7d4wW@5E@y*WX!8rdKNUm$Ev)xp<~&Kk2%As~$y=cawb| zmm_9ybtcrivUb6)F%S6Iyi@{b4F2Gov%P;=+8WKJq?rIJWCi_ii;_JblM!BaeCZxO z)4mGTv2fx>VA2m!t-VsI4pAMoR$g_UIAkqw@ar(Xktiq2&f&U6%N$;rK1Q4MKb6gfdAxbQ zZD%n{y0<%h7HeSCZdk#^AIZ@abpzILAknDrMX2u-gwrC1fm#?-=cM|d8WIhf^7%KO z+9fJB`H1WFPPct(`rP@=9Cd}iQ~cI5e z(yjzD_dJv|6B9N6XC&&|xFEX7zmba&77Bcx@~gw%9;et=V37**$S`n)Fe3R%Jk;+z}EcOR^+ zD3~}_jyeaT@iSeN2WLjB4qHbYtA0d^(;l#fk&}ii-+*R^RX)y`iQ$^NXGfj0JM#ab zLkKHMP|)elD_*oaX`uA_92#X1aWlef+`U_LOM{jXTPGHJzOukUvT5fX@w&LA)E zdCEHc@P7>7gG2usGVE1VYcA#q+4E;`;aF9MQS2|fA0%m?WOpr^>m!xJ)F`bta_N{y zF&WsxSX#i~3!}y?iinN#xAohky&0nnWnIt_GE2-R!; zpt&Q^=EXH)MuuepZ#5OnN*-4W%FQg#4&xe^4Hq(}3VEtsFR z>{$ISyj_mYYQZq3?Q!9Yl_ud9#yFMliVY;hlNexr_KLXj_qqm=PjETn+2o`%QY;VV zw0j+mUs0Pe2tKP{>Y%jTu~-d}aJw;wXI2P()FOVfbz0$h?}u zmY}1{V(g2SQBNk?3Q_R=3$7Hlf^vQBZk?)VsPUm=H=Wtdo%Hy zxl(~l&>W>sh0XyJ*2)C~bT^!q8z_P|XJTLmR^DB2|#qTma zsBdzrsfM$m`1Zn8(&OL*xvn1&gP+&5%OT!RFM_=vCx2}QL|dQ`P`G>;`pKEDE8tT4 z(5%RtWts}B3Xu6NuF@NV774Sr{C#w_;rtY#w6Xl2s(1wztHuiP0V+bU?lnMW%BFPS zprgEh!d$D*E8^iZs@E<$isdV`$tZ8fkduw4sf`1u#Q8b4w4>8+?akBUV^0OovJ9Z^&+aWoM@9ofA zeh)hRX>ZE7Y(^=!IYjoNYTf61vd$pEN`Mx&}wd5=x8vpOEoxOq@| zjcCB&>3;xG|Kbq69#l?z5k;iK`Xvfsot#8dSY6nWbw9oG(3&Cz$*i2)=089~Z<@m= zys7%BFI6;EVP9Uu$ksX+ZTWGp!hZnrt)nho=M^QJPn9BKoJiGHD>70(xM+=m3s`y} z*d@_JqBIJLSfT$&vhqoMSPkVk*N~X!cav-;B(ob<1gfE0_3cH%GCY}un;NR?$bMBl z@3Um$J&fuOOlg_cJZq1nDnO2ii_T#N8iEPz5;bvA zs=WhEFn7Q0f%&v+1ns1vuX9#qrF5@4%@p^=I0R(ZAK^8t=Fk|h)dOY2FH3&wAWEc+ zZmy`E4Qk=4DSOn{eQsuTAZQ}gT4VaAbNS6D6WOnuC6TLb4fyFz1YwH1jC#T>Q;PM6 z&~Ab0ibM_3kX#DC0OWQz_<76tV6Ogg)v@O?(S~xIgZ?hnPE`FZK^~nm8*MqgpK(f(;77dFGQ?QOC%bW*rJqla#WEP>5dT;^s;>C-FspRv7aIU=W^tGNNRrvJhI3aoP1ezh2t zgS&(4=%<9tEB<*X>dj7Wb0lw=e+d7$Q|lCNDCJ~w`NoskE>GCmi8F+-3ZRv96$UfW z4+)-We7r@%qKkV$!t4^F^;!SCno=Fp&BtTlo2d9(YXvrYwlEvK$0+lrg-7d9gi@MTOj#M+lVK49=#BB^OrkZu=MR$w*}wK&Y8T@{G*Hx{N}H^ z$@W*zudk|lg3fb7S-=CP!|)6fO7qqSnwYl>LkNqt;Ts`eWq)6HSWG|s)s!m2)s)Q7 zp|!8ww7BU-T8Va#Zyqmn#lzZtx3T86o|YdkIEvfHaa=!WpC{PU5y-pWKhE%%JxbD1 zu&7<(BQ^Yh9WUB*TJ8NG8J^?c_P1vgb8zsbR=Faqp?lZWw~!a8ptmG?CHuXNtG2Wd zj*@F_KJ#}cs`HU?9LJ4K{vf}Z5Y6ukRH^t`_0mwcn~KbJ{58hZ8x}kW1 zKIy)hvm}<%77>nKxGH*J1}@emkC`gvL2BF;$QzAW1{o_(VrEwg^FVzy;VqTy>n?uM z%`hVZ*#@O1v$6UnlFOYR?vG+o!It@tsxcX*$f5$)`VPn>#2H`>!u!OetG6P9_kK8T z!4c~Y5A4-z$(}(3_gGHR6j8lcRBJvf^v-EAt}DbKO)v@s{E_|5>VACSV497n*S@Fj zN~lk~*ElSTwtf(n&|1TE;RCCK(AD*SAhE%aVr#uB7c9H^6Lq9qs7z6mZc=5D)K|Yu zjE|s7o977vJu+&hY@dzX#AXOFcPP6fn4p(*BoZ7nAi}f;R`qcH0Zt2TzSzBc@&mSx zM>1kwc#sSCzeC52l5L(y!e*!+@sS5(qbm}iOH@xkjX)6JbcIK|Y`sA0}XR` zQ-DGo=~@}H6Z1D$#u_p{$SN1O}k0n4MSej+3T76fsWGX>!f-mzMdUYpAqCIay^ahxYY zGe=W@rc*smu5U*hp5Q|JR{sEblz$_$dcRi*af(KGNd=PmB`uv1G-2wF>bKc!Q8HFT z!d>s|#=)OW2TW=Q7|^(g)}VjZ-N4ewAbLKCVGctxbej7V&0&w-e%eZ~Wt)i8kt&q+ z+@Gbe-my^)i+Y8tVA-IV&P}bG{xWzv@2Mknx#>Gkm8rHaI~skbBLQ#yncsRNX))Of z>hf)}!h!&y%UnoF-U{s$SFxWaevi9jt%L zwS5cHcLrFf_vY>q-eh|s{vjGyw~i`u4kcmNh<^1Mc3q!y2Xt#A?7sh$*4{5jOveA< zt-v5nW1|S^@Ti7>R4X%qQ_h3Ct7klp_ebwI&)02Q%&Rh@scz?fz0O%_b*oZ%0A?)P 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 U7qww?A%^K<{_pHi`_ugY2LLZ6EC2ui literal 0 HcmV?d00001 diff --git a/doc/src/JPG/examples_mdpd.gif b/doc/src/JPG/examples_mdpd.gif new file mode 100644 index 0000000000000000000000000000000000000000..29ace1a0b2558d110a9afdf5f2d136121e50d628 GIT binary patch literal 916813 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


y~ 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�+$&YYv^wg*bD-3LIZK~+rw*_B7JnH< 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�!O6E9GDpB@uQE}IC0E&QBFGPa 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

@Gf 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 k=|iU~-}>zITW2Z{pa1Xmd2*!sf2yPLbpQYW literal 0 HcmV?d00001 diff --git a/doc/src/JPG/examples_mdpd_first.jpg b/doc/src/JPG/examples_mdpd_first.jpg new file mode 100644 index 0000000000000000000000000000000000000000..958912e662fc5ae032f26a9dfa390b75b52a6c07 GIT binary patch literal 115446 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�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 literal 0 HcmV?d00001 diff --git a/doc/src/JPG/examples_mdpd_last.jpg b/doc/src/JPG/examples_mdpd_last.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1bf8b9ac8274e38fcebea62fe8fb79365f56892e GIT binary patch literal 38463 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 J`q;l;{s$eKHX{H4 literal 0 HcmV?d00001 diff --git a/doc/src/JPG/examples_tdpd.jpg b/doc/src/JPG/examples_tdpd.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c00e83e00342334106b9aa465de8f71b9ac937ce GIT binary patch literal 10789 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 hS}NFz!y*pQF;p;shtAzE{2yY*=2HLw literal 0 HcmV?d00001 diff --git a/doc/src/Section_commands.txt b/doc/src/Section_commands.txt index 571c6c4920..fda727ec05 100644 --- a/doc/src/Section_commands.txt +++ b/doc/src/Section_commands.txt @@ -685,6 +685,7 @@ package"_Section_start.html#start_3. "drude"_fix_drude.html, "drude/transform/direct"_fix_drude_transform.html, "drude/transform/reverse"_fix_drude_transform.html, +"edpd/source"_fix_dpd_source.html, "eos/cv"_fix_eos_cv.html, "eos/table"_fix_eos_table.html, "eos/table/rx"_fix_eos_table_rx.html, @@ -704,6 +705,9 @@ package"_Section_start.html#start_3. "meso"_fix_meso.html, "manifoldforce"_fix_manifoldforce.html, "meso/stationary"_fix_meso_stationary.html, +"mvv/dpd"_fix_mvv_dpd.html, +"mvv/edpd"_fix_mvv_dpd.html, +"mvv/tdpd"_fix_mvv_dpd.html, "nve/dot"_fix_nve_dot.html, "nve/dotc/langevin"_fix_nve_dotc_langevin.html, "nve/manifold/rattle"_fix_nve_manifold_rattle.html, @@ -732,6 +736,7 @@ package"_Section_start.html#start_3. "smd/move/triangulated/surface"_fix_smd_move_triangulated_surface.html, "smd/setvel"_fix_smd_setvel.html, "smd/wall/surface"_fix_smd_wall_surface.html, +"tdpd/source"_fix_dpd_source.html, "temp/rescale/eff"_fix_temp_rescale_eff.html, "ti/spring"_fix_ti_spring.html, "ttm/mod"_fix_ttm.html, @@ -836,6 +841,7 @@ package"_Section_start.html#start_3. "cnp/atom"_compute_cnp_atom.html, "dpd"_compute_dpd.html, "dpd/atom"_compute_dpd_atom.html, +"edpd/temp/atom"_compute_edpd_temp_atom.html, "fep"_compute_fep.html, "force/tally"_compute_tally.html, "heat/flux/tally"_compute_tally.html, @@ -868,6 +874,7 @@ package"_Section_start.html#start_3. "smd/ulsph/stress"_compute_smd_ulsph_stress.html, "smd/vol"_compute_smd_vol.html, "stress/tally"_compute_tally.html, +"tdpd/cc/atom"_compute_tdpd_cc_atom.html, "temp/drude"_compute_temp_drude.html, "temp/eff"_compute_temp_eff.html, "temp/deform/eff"_compute_temp_deform_eff.html, @@ -1024,6 +1031,7 @@ package"_Section_start.html#start_3. "eam/cd (o)"_pair_eam.html, "edip (o)"_pair_edip.html, "edip/multi"_pair_edip.html, +"edpd"_pair_meso.html, "eff/cut"_pair_eff.html, "exp6/rx"_pair_exp6_rx.html, "gauss/cut"_pair_gauss.html, @@ -1041,6 +1049,8 @@ package"_Section_start.html#start_3. "lj/sdk (gko)"_pair_sdk.html, "lj/sdk/coul/long (go)"_pair_sdk.html, "lj/sdk/coul/msm (o)"_pair_sdk.html, +"mdpd"_pair_meso.html, +"mdpd/rhosum"_pair_meso.html, "meam/c"_pair_meam.html, "meam/spline (o)"_pair_meam_spline.html, "meam/sw/spline"_pair_meam_sw_spline.html, @@ -1074,6 +1084,7 @@ package"_Section_start.html#start_3. "sph/taitwater/morris"_pair_sph_taitwater_morris.html, "srp"_pair_srp.html, "table/rx"_pair_table_rx.html, +"tdpd"_pair_meso.html, "tersoff/table (o)"_pair_tersoff.html, "thole"_pair_thole.html, "tip4p/long/soft (o)"_pair_lj_soft.html :tb(c=4,ea=c) diff --git a/doc/src/Section_packages.txt b/doc/src/Section_packages.txt index 16864bcdc4..6122dfac78 100644 --- a/doc/src/Section_packages.txt +++ b/doc/src/Section_packages.txt @@ -112,7 +112,7 @@ Package, Description, Doc page, Example, Library "REPLICA"_#REPLICA, multi-replica methods, "Section 6.6.5"_Section_howto.html#howto_5, tad, - "RIGID"_#RIGID, rigid bodies and constraints, "fix rigid"_fix_rigid.html, rigid, - "SHOCK"_#SHOCK, shock loading methods, "fix msst"_fix_msst.html, -, - -"SNAP"_#SNAP, quantum-fitted potential, "pair snap"_pair_snap.html, snap, - +"SNAP"_#SNAP, quantum-fitted potential, "pair_style snap"_pair_snap.html, snap, - "SRD"_#SRD, stochastic rotation dynamics, "fix srd"_fix_srd.html, srd, - "VORONOI"_#VORONOI, Voronoi tesselation, "compute voronoi/atom"_compute_voronoi_atom.html, -, ext :tb(ea=c,ca1=l) @@ -134,6 +134,7 @@ Package, Description, Doc page, Example, Library "USER-LB"_#USER-LB, Lattice Boltzmann fluid,"fix lb/fluid"_fix_lb_fluid.html, USER/lb, - "USER-MANIFOLD"_#USER-MANIFOLD, motion on 2d surfaces,"fix manifoldforce"_fix_manifoldforce.html, USER/manifold, - "USER-MEAMC"_#USER-MEAMC, modified EAM potential (C++), "pair_style meam/c"_pair_meam.html, meam, - +"USER-MESO"_#USER-MESO, mesoscale DPD models, "pair_style edpd"_pair_meso.html, USER/meso, - "USER-MGPT"_#USER-MGPT, fast MGPT multi-ion potentials, "pair_style mgpt"_pair_mgpt.html, USER/mgpt, - "USER-MISC"_#USER-MISC, single-file contributions, USER-MISC/README, USER/misc, - "USER-MOLFILE"_#USER-MOLFILE, "VMD"_vmd_home molfile plug-ins,"dump molfile"_dump_molfile.html, -, ext @@ -1342,7 +1343,7 @@ make machine :pre [Supporting info:] src/SNAP: filenames -> commands -"pair snap"_pair_snap.html +"pair_style snap"_pair_snap.html "compute sna/atom"_compute_sna_atom.html "compute snad/atom"_compute_sna_atom.html "compute snav/atom"_compute_sna_atom.html @@ -1556,7 +1557,7 @@ make machine :pre src/USER-AWPMD: filenames -> commands src/USER-AWPMD/README -"pair awpmd/cut"_pair_awpmd.html +"pair_style awpmd/cut"_pair_awpmd.html examples/USER/awpmd :ul :line @@ -1745,12 +1746,12 @@ src/USER-DPD: filenames -> commands "fix eos/table/rx"_fix_eos_table_rx.html "fix shardlow"_fix_shardlow.html "fix rx"_fix_rx.html -"pair table/rx"_pair_table_rx.html -"pair dpd/fdt"_pair_dpd_fdt.html -"pair dpd/fdt/energy"_pair_dpd_fdt.html -"pair exp6/rx"_pair_exp6_rx.html -"pair multi/lucy"_pair_multi_lucy.html -"pair multi/lucy/rx"_pair_multi_lucy_rx.html +"pair_style table/rx"_pair_table_rx.html +"pair_style dpd/fdt"_pair_dpd_fdt.html +"pair_style dpd/fdt/energy"_pair_dpd_fdt.html +"pair_style exp6/rx"_pair_exp6_rx.html +"pair_style multi/lucy"_pair_multi_lucy.html +"pair_style multi/lucy/rx"_pair_multi_lucy_rx.html examples/USER/dpd :ul :line @@ -1785,8 +1786,8 @@ src/USER-DRUDE/README "fix drude"_fix_drude.html "fix drude/transform/*"_fix_drude_transform.html "compute temp/drude"_compute_temp_drude.html -"pair thole"_pair_thole.html -"pair lj/cut/thole/long"_pair_thole.html +"pair_style thole"_pair_thole.html +"pair_style lj/cut/thole/long"_pair_thole.html examples/USER/drude tools/drude :ul @@ -1824,8 +1825,8 @@ src/USER-EFF/README "fix npt/eff"_fix_nh_eff.html "fix langevin/eff"_fix_langevin_eff.html "compute temp/eff"_compute_temp_eff.html -"pair eff/cut"_pair_eff.html -"pair eff/inline"_pair_eff.html +"pair_style eff/cut"_pair_eff.html +"pair_style eff/inline"_pair_eff.html examples/USER/eff tools/eff/README tools/eff @@ -2155,11 +2156,47 @@ make machine :pre src/USER-MEAMC: filenames -> commands src/USER-MEAMC/README -"pair meam/c"_pair_meam.html +"pair_style meam/c"_pair_meam.html examples/meam :ul :line +USER-MESO package :link(USER-MESO),h4 + +[Contents:] + +Several extensions of the the dissipative particle dynamics (DPD) +method. Specifically, energy-conserving DPD (eDPD) that can model +non-isothermal processes, many-body DPD (mDPD) for simulating +vapor-liquid coexistence, and transport DPD (tDPD) for modeling +advection-diffuion-reaction systems. The equations of motion of these +DPD extensions are integrated through a modified velocity-Verlet (MVV) +algorithm. + +[Author:] Zhen Li (Division of Applied Mathematics, Brown University) + +[Install or un-install:] + +make yes-user-meso +make machine :pre + +make no-user-meso +make machine :pre + +[Supporting info:] + +src/USER-MESO: filenames -> commands +src/USER-MESO/README +"atom_style edpd"_atom_style.html +"pair_style edpd"_pair_meso.html +"pair_style mdpd"_pair_meso.html +"pair_style tdpd"_pair_meso.html +"fix mvv/dpd"_fix_mvv.html +examples/USER/meso +http://lammps.sandia.gov/movies.html#mesodpd :ul + +:line + USER-MOLFILE package :link(USER-MOLFILE),h4 [Contents:] diff --git a/doc/src/atom_style.txt b/doc/src/atom_style.txt index 077636dfd1..49d9dde791 100644 --- a/doc/src/atom_style.txt +++ b/doc/src/atom_style.txt @@ -13,17 +13,19 @@ atom_style command :h3 atom_style style args :pre style = {angle} or {atomic} or {body} or {bond} or {charge} or {dipole} or \ - {dpd} or {electron} or {ellipsoid} or {full} or {line} or {meso} or \ - {molecular} or {peri} or {smd} or {sphere} or {tri} or \ - {template} or {hybrid} :ulb,l + {dpd} or {edpd} or {mdpd} or {tdpd} or {electron} or {ellipsoid} or \ + {full} or {line} or {meso} or {molecular} or {peri} or {smd} or \ + {sphere} or {tri} or {template} or {hybrid} :ulb,l args = none for any style except the following - {body} args = bstyle bstyle-args - bstyle = style of body particles - bstyle-args = additional arguments specific to the bstyle - see the "body"_body.html doc page for details - {template} args = template-ID - template-ID = ID of molecule template specified in a separate "molecule"_molecule.html command - {hybrid} args = list of one or more sub-styles, each with their args :pre + {body} args = bstyle bstyle-args + bstyle = style of body particles + bstyle-args = additional arguments specific to the bstyle + see the "body"_body.html doc page for details + {tdpd} arg = Nspecies + Nspecies = # of chemical species + {template} arg = template-ID + template-ID = ID of molecule template specified in a separate "molecule"_molecule.html command + {hybrid} args = list of one or more sub-styles, each with their args :pre accelerated styles (with same args) = {angle/kk} or {atomic/kk} or {bond/kk} or {charge/kk} or {full/kk} or {molecular/kk} :l :ule @@ -36,7 +38,8 @@ atom_style full atom_style body nparticle 2 10 atom_style hybrid charge bond atom_style hybrid charge body nparticle 2 5 -atom_style template myMols :pre +atom_style template myMols +atom_style tdpd 2 :pre [Description:] @@ -74,6 +77,9 @@ quantities. {charge} | charge | atomic system with charges | {dipole} | charge and dipole moment | system with dipolar particles | {dpd} | internal temperature and internal energies | DPD particles | +{edpd} | temperature and heat capacity | eDPD particles | +{mdpd} | density | mDPD particles | +{tdpd} | chemical concentration | tDPD particles | {electron} | charge and spin and eradius | electronic force field | {ellipsoid} | shape, quaternion, angular momentum | aspherical particles | {full} | molecular + charge | bio-molecules | @@ -145,6 +151,19 @@ properties with internal temperature (dpdTheta), internal conductive energy (uCond), internal mechanical energy (uMech), and internal chemical energy (uChem). +The {edpd} style is for energy-conserving dissipative particle +dynamics (eDPD) particles which store a temperature (edpd_temp), and +heat capacity(edpd_cv). + +The {mdpd} style is for many-body dissipative particle dynamics (mDPD) +particles which store a density (rho) for considering +density-dependent many-body interactions. + +The {tdpd} style is for transport dissipative particle dynamics (tDPD) +particles which store a set of chemical concentration. An integer +"cc_species" is required to specify the number of chemical species +involved in a tDPD system. + The {meso} style is for smoothed particle hydrodynamics (SPH) particles which store a density (rho), energy (e), and heat capacity (cv). @@ -284,6 +303,11 @@ force fields"_pair_eff.html. The {dpd} style is part of the USER-DPD package for dissipative particle dynamics (DPD). +The {edpd}, {mdpd}, and {tdpd} styles are part of the USER-MESO package +for energy-conserving dissipative particle dynamics (eDPD), many-body +dissipative particle dynamics (mDPD), and transport dissipative particle +dynamics (tDPD), respectively. + The {meso} style is part of the USER-SPH package for smoothed particle hydrodynamics (SPH). See "this PDF guide"_USER/sph/SPH_LAMMPS_userguide.pdf to using SPH in LAMMPS. diff --git a/doc/src/compute_edpd_temp_atom.txt b/doc/src/compute_edpd_temp_atom.txt new file mode 100644 index 0000000000..30f8c1043a --- /dev/null +++ b/doc/src/compute_edpd_temp_atom.txt @@ -0,0 +1,61 @@ +"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c + +:link(lws,http://lammps.sandia.gov) +:link(ld,Manual.html) +:link(lc,Section_commands.html#comm) + +:line + +compute edpd/temp/atom command :h3 + +[Syntax:] + +compute ID group-ID edpd/temp/atom :pre + +ID, group-ID are documented in "compute"_compute.html command +edpd/temp/atom = style name of this compute command :ul + +[Examples:] + +compute 1 all edpd/temp/atom :pre + +[Description:] + +Define a computation that calculates the per-atom temperature +for each eDPD particle in a group. + +The temperature is a local temperature derived from the internal energy +of each eDPD particle based on the local equilibrium hypothesis. +For more details please see "(Espanol1997)"_#Espanol1997 and "(Li2014)"_#Li2014. + +[Output info:] + +This compute calculates a per-atom vector, which can be accessed by +any command that uses per-atom values from a compute as input. See +"Section 6.15"_Section_howto.html#howto_15 for an overview of +LAMMPS output options. + +The per-atom vector values will be in temperature "units"_units.html. + +[Restrictions:] + +This compute is part of the USER-MESO package. It is only enabled if +LAMMPS was built with that package. See the "Making +LAMMPS"_Section_start.html#start_3 section for more info. + +[Related commands:] + +"pair_style edpd"_pair_meso.html + +[Default:] none + +:line + +:link(Espanol1997) +[(Espanol1997)] Espanol, Europhys Lett, 40(6): 631-636 (1997). DOI: +10.1209/epl/i1997-00515-8 + +:link(Li2014) +[(Li2014)] Li, Tang, Lei, Caswell, Karniadakis, J Comput Phys, 265: +113-127 (2014). DOI: 10.1016/j.jcp.2014.02.003. + diff --git a/doc/src/compute_tdpd_cc_atom.txt b/doc/src/compute_tdpd_cc_atom.txt new file mode 100644 index 0000000000..58a49fa59f --- /dev/null +++ b/doc/src/compute_tdpd_cc_atom.txt @@ -0,0 +1,60 @@ +"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c + +:link(lws,http://lammps.sandia.gov) +:link(ld,Manual.html) +:link(lc,Section_commands.html#comm) + +:line + +compute tdpd/cc/atom command :h3 + +[Syntax:] + +compute ID group-ID tdpd/cc/atom index :pre + +ID, group-ID are documented in "compute"_compute.html command +tdpd/cc/atom = style name of this compute command +index = index of chemical species (1 to Nspecies) :ul + +[Examples:] + +compute 1 all tdpd/cc/atom 2 :pre + +[Description:] + +Define a computation that calculates the per-atom chemical +concentration of a specified species for each tDPD particle in a +group. + +The chemical concentration of each species is defined as the number of +molecules carried by a tDPD particle for dilute solution. For more +details see "(Li2015)"_#Li2015. + +[Output info:] + +This compute calculates a per-atom vector, which can be accessed by +any command that uses per-atom values from a compute as input. See +"Section 6.15"_Section_howto.html#howto_15 for an overview of +LAMMPS output options. + +The per-atom vector values will be in the units of chemical species +per unit mass. + +[Restrictions:] + +This compute is part of the USER-MESO package. It is only enabled if +LAMMPS was built with that package. See the "Making +LAMMPS"_Section_start.html#start_3 section for more info. + +[Related commands:] + +"pair_style tdpd"_pair_meso.html + +[Default:] none + +:line + +:link(Li2015) +[(Li2015)] Li, Yazdani, Tartakovsky, Karniadakis, J Chem Phys, 143: +014101 (2015). DOI: 10.1063/1.4923254 + diff --git a/doc/src/fix_dpd_source.txt b/doc/src/fix_dpd_source.txt new file mode 100644 index 0000000000..de035a94b4 --- /dev/null +++ b/doc/src/fix_dpd_source.txt @@ -0,0 +1,101 @@ +"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c + +:link(lws,http://lammps.sandia.gov) +:link(ld,Manual.html) +:link(lc,Section_commands.html#comm) + +:line + +fix edpd/source command :h3 +fix tdpd/source command :h3 + +[Syntax:] + +fix ID group-ID edpd/source keyword values ... +fix ID group-ID tdpd/source cc_index keyword values ... :pre + +ID, group-ID are documented in "fix"_fix.html command :ulb,l +edpd/source or tdpd/source = style name of this fix command :l +index (only specified for tdpd/source) = index of chemical species (1 to Nspecies) :l +keyword = {sphere} or {cuboid} :l + {sphere} values = cx,cy,cz,radius,source + cx,cy,cz = x,y,z center of spherical domain (distance units) + radius = radius of a spherical domain (distance units) + source = heat source or concentration source (flux units, see below) + {cuboid} values = cx,cy,cz,dLx,dLy,dLz,source + cx,cy,cz = x,y,z lower left corner of a cuboid domain (distance units) + dLx,dLy,dLz = x,y,z side length of a cuboid domain (distance units) + source = heat source or concentration source (flux units, see below) :pre +:ule + +[Examples:] + +fix 1 all edpd/source sphere 0.0 0.0 0.0 5.0 0.01 +fix 1 all edpd/source cuboid 0.0 0.0 0.0 20.0 10.0 10.0 -0.01 +fix 1 all tdpd/source 1 sphere 5.0 0.0 0.0 5.0 0.01 +fix 1 all tdpd/source 2 cuboid 0.0 0.0 0.0 20.0 10.0 10.0 0.01 :pre + +[Description:] + +Fix {edpd/source} adds a heat source as an external heat flux to each +atom in a spherical or cuboid domain, where the {source} is in units +of energy/time. Fix {tdpd/source} adds an external concentration +source of the chemical species specified by {index} as an external +concentration flux for each atom in a spherical or cuboid domain, +where the {source} is in units of mole/volume/time. + +This command can be used to give an additional heat/concentration +source term to atoms in a simulation, such as for a simulation of a +heat conduction with a source term (see Fig.12 in "(Li2014)"_#Li2014) +or diffusion with a source term (see Fig.1 in "(Li2015)"_#Li2015), as +an analog of a periodic Poiseuille flow problem. + +If the {sphere} keyword is used, the {cx,cy,cz,radius} defines a +spherical domain to apply the source flux to. + +If the {cuboid} keyword is used, the {cx,cy,cz,dLx,dLy,dLz} defines a +cuboid domain to apply the source flux to. + +:line + +[Restart, fix_modify, output, run start/stop, minimize info:] + +No information about this fix is written to "binary restart +files"_restart.html. None of the "fix_modify"_fix_modify.html options +are relevant to this fix. No global or per-atom quantities are stored +by this fix for access by various "output +commands"_Section_howto.html#howto_15. No parameter of this fix can +be used with the {start/stop} keywords of the "run"_run.html command. +This fix is not invoked during "energy minimization"_minimize.html. + +[Restrictions:] + +This fix is part of the USER-MESO package. It is only enabled if +LAMMPS was built with that package. See the "Making +LAMMPS"_Section_start.html#start_3 section for more info. + +Fix {edpd/source} must be used with the "pair_style +edpd"_pair_meso.html command. Fix {tdpd/source} must be used with the +"pair_style tdpd"_pair_meso.html command. + +[Related commands:] + +"pair_style edpd"_pair_meso.html, "pair_style tdpd"_pair_meso.html, +"compute edpd/temp/atom"_compute_edpd_temp_atom.html, "compute +tdpd/cc/atom"_compute_tdpd_cc_atom.html + +[Default:] none + +:line + +:link(Li2014) +[(Li2014)] Z. Li, Y.-H. Tang, H. Lei, B. Caswell and G.E. Karniadakis, +"Energy-conserving dissipative particle dynamics with +temperature-dependent properties", J. Comput. Phys., 265: 113-127 +(2014). DOI: 10.1016/j.jcp.2014.02.003 + +:link(Li2015) +[(Li2015)] Z. Li, A. Yazdani, A. Tartakovsky and G.E. Karniadakis, +"Transport dissipative particle dynamics model for mesoscopic +advection-diffusion-reaction problems", J. Chem. Phys., 143: 014101 +(2015). DOI: 10.1063/1.4923254 diff --git a/doc/src/fix_mvv_dpd.txt b/doc/src/fix_mvv_dpd.txt new file mode 100644 index 0000000000..75e13744ea --- /dev/null +++ b/doc/src/fix_mvv_dpd.txt @@ -0,0 +1,97 @@ +"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c + +:link(lws,http://lammps.sandia.gov) +:link(ld,Manual.html) +:link(lc,Section_commands.html#comm) + +:line + +fix mvv/dpd command :h3 +fix mvv/edpd command :h3 +fix mvv/tdpd command :h3 + +[Syntax:] + +fix ID group-ID mvv/dpd lambda :pre +fix ID group-ID mvv/edpd lambda :pre +fix ID group-ID mvv/tdpd lambda :pre + +ID, group-ID are documented in "fix"_fix.html command +mvv/dpd, mvv/edpd, mvv/tdpd = style name of this fix command +lambda = (optional) relaxation parameter (unitless) :ul + +[Examples:] + +fix 1 all mvv/dpd +fix 1 all mvv/dpd 0.5 +fix 1 all mvv/edpd +fix 1 all mvv/edpd 0.5 +fix 1 all mvv/tdpd +fix 1 all mvv/tdpd 0.5 :pre + +[Description:] + +Perform time integration using the modified velocity-Verlet (MVV) +algorithm to update position and velocity (fix mvv/dpd), or position, +velocity and temperature (fix mvv/edpd), or position, velocity and +concentration (fix mvv/tdpd) for particles in the group each timestep. + +The modified velocity-Verlet (MVV) algorithm aims to improve the +stability of the time integrator by using an extrapolated version of +the velocity for the force evaluation: + +:c,image(Eqs/fix_mvv_dpd.jpg) + +where the parameter λ depends on the +specific choice of DPD parameters, and needs to be tuned on a +case-by-case basis. Specification of a {lambda} value is opttional. +If specified, the setting must be from 0.0 to 1.0. If not specified, +a default value of 0.5 is used, which effectively reproduces the +standard velocity-Verlet (VV) scheme. For more details, see +"Groot"_#Groot. + +Fix {mvv/dpd} updates the position and velocity of each atom. It can +be used with the "pair_style mdpd"_pair_meso.html command or other +pair styles such as "pair dpd"_pair_dpd.html. + +Fix {mvv/edpd} updates the per-atom temperature, in addition to +position and velocity, and must be used with the "pair_style +edpd"_pair_meso.html command. + +Fix {mvv/tdpd} updates the per-atom chemical concentration, in +addition to position and velocity, and must be used with the +"pair_style tdpd"_pair_meso.html command. + +:line + +[Restart, fix_modify, output, run start/stop, minimize info:] + +No information about this fix is written to "binary restart +files"_restart.html. None of the "fix_modify"_fix_modify.html options +are relevant to this fix. No global or per-atom quantities are stored +by this fix for access by various "output +commands"_Section_howto.html#howto_15. No parameter of this fix can +be used with the {start/stop} keywords of the "run"_run.html command. +This fix is not invoked during "energy minimization"_minimize.html. + +[Restrictions:] + +This fix is part of the USER-MESO package. It is only enabled if +LAMMPS was built with that package. See the "Making +LAMMPS"_Section_start.html#start_3 section for more info. + +[Related commands:] + +"pair_style mdpd"_pair_meso.html, "pair_style edpd"_pair_meso.html, +"pair_style tdpd"_pair_meso.html + +[Default:] + +The default value for the optional {lambda} parameter is 0.5. + +:line + +:link(Groot) +[(Groot)] Groot and Warren, J Chem Phys, 107: 4423-4435 (1997). DOI: +10.1063/1.474784 + diff --git a/doc/src/pair_meso.txt b/doc/src/pair_meso.txt new file mode 100644 index 0000000000..bcdf717d68 --- /dev/null +++ b/doc/src/pair_meso.txt @@ -0,0 +1,277 @@ +"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c + +:link(lws,http://lammps.sandia.gov) +:link(ld,Manual.html) +:link(lc,Section_commands.html#comm) + +:line + +pair_style edpd command :h3 +pair_style mdpd command :h3 +pair_style mdpd/rhosum command :h3 +pair_style tdpd command :h3 + +[Syntax:] + +pair_style style args :pre + +style = {edpd} or {mdpd} or {mdpd/rhosum} or {tdpd} :ulb,l +args = list of arguments for a particular style :l + {edpd} args = cutoff seed + cutoff = global cutoff for eDPD interactions (distance units) + seed = random # seed (integer) (if <= 0, eDPD will use current time as the seed) + {mdpd} args = T cutoff seed + T = temperature (temperature units) + cutoff = global cutoff for mDPD interactions (distance units) + seed = random # seed (integer) (if <= 0, mDPD will use current time as the seed) + {mdpd/rhosum} args = + {tdpd} args = T cutoff seed + T = temperature (temperature units) + cutoff = global cutoff for tDPD interactions (distance units) + seed = random # seed (integer) (if <= 0, tDPD will use current time as the seed) :pre +:ule + +[Examples:] + +pair_style edpd 1.58 9872598 +pair_coeff * * 18.75 4.5 0.41 1.58 1.42E-5 2.0 1.58 +pair_coeff 1 1 18.75 4.5 0.41 1.58 1.42E-5 2.0 1.58 power 10.54 -3.66 3.44 -4.10 +pair_coeff 1 1 18.75 4.5 0.41 1.58 1.42E-5 2.0 1.58 power 10.54 -3.66 3.44 -4.10 kappa -0.44 -3.21 5.04 0.00 :pre + +pair_style hybrid/overlay mdpd/rhosum mdpd 1.0 1.0 65689 +pair_coeff 1 1 mdpd/rhosum 0.75 +pair_coeff 1 1 mdpd -40.0 25.0 18.0 1.0 0.75 :pre + +pair_style tdpd 1.0 1.58 935662 +pair_coeff * * 18.75 4.5 0.41 1.58 1.58 1.0 1.0E-5 2.0 +pair_coeff 1 1 18.75 4.5 0.41 1.58 1.58 1.0 1.0E-5 2.0 3.0 1.0E-5 2.0 :pre + +[Description:] + +The {edpd} style computes the pairwise interactions and heat fluxes +for eDPD particles following the formulations in +"(Li2014_JCP)"_#Li2014_JCP and "Li2015_CC"_#Li2015_CC. The time +evolution of an eDPD particle is governed by the conservation of +momentum and energy given by + +:c,image(Eqs/pair_edpd_gov.jpg) + +where the three components of Fi +including the conservative force FijC, dissipative force FijD and random force FijR are expressed as + +:c,image(Eqs/pair_edpd_force.jpg) + +in which the exponent of the weighting function s can be defined as a temperature-dependent +variable. The heat flux between particles accounting for the +collisional heat flux qC, viscous +heat flux qV, and random heat flux +qR are given by + +:c,image(Eqs/pair_edpd_heat.jpg) + +where the mesoscopic heat friction κ is given by + +:c,image(Eqs/pair_edpd_kappa.jpg) + +with υ being the kinematic +viscosity. For more details, see Eq.(15) in "(Li2014_JCP)"_#Li2014_JCP. + +The following coefficients must be defined in eDPD system for each +pair of atom types via the "pair_coeff"_pair_coeff.html command as in +the examples above. + +A (force units) +gamma (force/velocity units) +power_f (positive real) +cutoff (distance units) +kappa (thermal conductivity units) +power_T (positive real) +cutoff_T (distance units) +optional keyword = power or kappa :ul + +The keyword {power} or {kappa} is optional. Both "power" and "kappa" +require 4 parameters c1, c2, +c4, c4 showing the temperature dependence +of the exponent

s(T) = +power_f*(1+c1*(T-1)+c2*(T-1)2 ++c3*(T-1)3+c4*(T-1)4)
+and of the mesoscopic heat friction
+sT(T) = +kappa*(1+c1*(T-1)+c2*(T-1)2 ++c3*(T-1)3+c4*(T-1)4)
+If the keyword {power} or {kappa} is not specified, the eDPD system +will use constant power_f and kappa, which is independent to +temperature changes. + +:line + +The {mdpd/rhosum} style computes the local particle mass density rho +for mDPD particles by kernel function interpolation. + +The following coefficients must be defined for each pair of atom types +via the "pair_coeff"_pair_coeff.html command as in the examples above. + +cutoff (distance units) :ul + +:line + +The {mdpd} style computes the many-body interactions between mDPD +particles following the formulations in +"(Li2013_POF)"_#Li2013_POF. The dissipative and random forces are in +the form same as the classical DPD, but the conservative force is +local density dependent, which are given by + +:c,image(Eqs/pair_mdpd_force.jpg) + +where the first term in FC with a +negative coefficient A < 0 stands for an attractive force within an +interaction range rc, and the second +term with B > 0 is the density-dependent repulsive force within an +interaction range rd. + +The following coefficients must be defined for each pair of atom types via the +"pair_coeff"_pair_coeff.html command as in the examples above. + +A (force units) +B (force units) +gamma (force/velocity units) +cutoff_c (distance units) +cutoff_d (distance units) :ul + +:line + +The {tdpd} style computes the pairwise interactions and chemical +concentration fluxes for tDPD particles following the formulations in +"(Li2015_JCP)"_#Li2015_JCP. The time evolution of a tDPD particle is +governed by the conservation of momentum and concentration given by + +:c,image(Eqs/pair_tdpd_gov.jpg) + +where the three components of Fi +including the conservative force FijC, dissipative force FijD and random force FijR are expressed as + +:c,image(Eqs/pair_tdpd_force.jpg) + +The concentration flux between two tDPD particles includes the Fickian +flux QijD and random flux +QijR, which are given by + +:c,image(Eqs/pair_tdpd_flux.jpg) + +where the parameters kappa and epsilon determine the strength of the +Fickian and random fluxes. ms +is the mass of a single solute molecule. In general, ms is much smaller than the mass of +a tDPD particle m. For more details, see +"(Li2015_JCP)"_#Li2015_JCP. + +The following coefficients must be defined for each pair of atom types via the +"pair_coeff"_pair_coeff.html command as in the examples above. + +A (force units) +gamma (force/velocity units) +power_f (positive real) +cutoff (distance units) +cutoff_CC (distance units) +kappa_i (diffusivity units) +epsilon_i (diffusivity units) +power_cc_i (positive real) :ul + +The last 3 values must be repeated Nspecies times, so that values for +each of the Nspecies chemical species are specified, as indicated by +the "I" suffix. In the first pair_coeff example above for pair_style +tdpd, Nspecies = 1. In the second example, Nspecies = 2, so 3 +additional coeffs are specified (for species 2). + +:line + +[Example scripts] + +There are example scripts for using all these pair styles in +examples/USER/meso. The example for an eDPD simulation models heat +conduction with source terms analog of periodic Poiseuille flow +problem. The setup follows Fig.12 in "(Li2014_JCP)"_#Li2014_JCP. The +output of the short eDPD simulation (about 2 minutes on a single core) +gives a temperature and density profiles as + +:c,image(JPG/examples_edpd.jpg) + +The example for a mDPD simulation models the oscillations of a liquid +droplet started from a liquid film. The mDPD parameters are adopted +from "(Li2013_POF)"_#Li2013_POF. The short mDPD run (about 2 minutes +on a single core) generates a particle trajectory which can +be visualized as follows. + +:c,image(JPG/examples_mdpd_first.jpg,JPG/examples_mdpd.gif) +:c,image(JPG/examples_mdpd_last.jpg) + +The first image is the initial state of the simulation. If you +click it a GIF movie should play in your browser. The second image +is the final state of the simulation. + +The example for a tDPD simulation computes the effective diffusion +coefficient of a tDPD system using a method analogous to the periodic +Poiseuille flow. The tDPD system is specified with two chemical +species, and the setup follows Fig.1 in +"(Li2015_JCP)"_#Li2015_JCP. The output of the short tDPD simulation +(about one and a half minutes on a single core) gives the +concentration profiles of the two chemical species as + +:c,image(JPG/examples_tdpd.jpg) + +:line + +[Mixing, shift, table, tail correction, restart, rRESPA info]: + +The styles {edpd}, {mdpd}, {mdpd/rhosum} and {tdpd} do not support +mixing. Thus, coefficients for all I,J pairs must be specified explicitly. + +The styles {edpd}, {mdpd}, {mdpd/rhosum} and {tdpd} do not support +the "pair_modify"_pair_modify.html shift, table, and tail options. + +The styles {edpd}, {mdpd}, {mdpd/rhosum} and {tdpd} do not write +information to "binary restart files"_restart.html. Thus, you need +to re-specify the pair_style and pair_coeff commands in an input script +that reads a restart file. + +[Restrictions:] + +The pair styles {edpd}, {mdpd}, {mdpd/rhosum} and {tdpd} are part of +the USER-MESO package. It is only enabled if LAMMPS was built with +that package. See the "Making LAMMPS"_Section_start.html#start_3 +section for more info. + +[Related commands:] + +"pair_coeff"_pair_coeff.html, "fix mvv/dpd"_fix_mvv_dpd.html, +"fix mvv/edpd"_fix_mvv_dpd.html, "fix mvv/tdpd"_fix_mvv_dpd.html, +"fix edpd/source"_fix_dpd_source.html, "fix tdpd/source"_fix_dpd_source.html, +"compute edpd/temp/atom"_compute_edpd_temp_atom.html, +"compute tdpd/cc/atom"_compute_tdpd_cc_atom.html + +[Default:] none + +:line + +:link(Li2014_JCP) +[(Li2014_JCP)] Li, Tang, Lei, Caswell, Karniadakis, J Comput Phys, +265: 113-127 (2014). DOI: 10.1016/j.jcp.2014.02.003. + +:link(Li2015_CC) +[(Li2015_CC)] Li, Tang, Li, Karniadakis, Chem Commun, 51: 11038-11040 +(2015). DOI: 10.1039/C5CC01684C. + +:link(Li2013_POF) +[(Li2013_POF)] Li, Hu, Wang, Ma, Zhou, Phys Fluids, 25: 072103 (2013). +DOI: 10.1063/1.4812366. + +:link(Li2015_JCP) +[(Li2015_JCP)] Li, Yazdani, Tartakovsky, Karniadakis, J Chem Phys, +143: 014101 (2015). DOI: 10.1063/1.4923254. diff --git a/doc/src/read_data.txt b/doc/src/read_data.txt index a8aca53693..747c3e752d 100644 --- a/doc/src/read_data.txt +++ b/doc/src/read_data.txt @@ -14,7 +14,7 @@ read_data file keyword args ... :pre file = name of data file to read in :ulb,l zero or more keyword/arg pairs may be appended :l -keyword = {add} or {offset} or {shift} or {extra/atom/types} or {extra/bond/types} or {extra/angle/types} or {extra/dihedral/types} or {extra/improper/types} or {extra/bond/per/atom} or {extra/angle/per/atom} or {extra/dihedral/per/atom} or {extra/improper/per/atom} or {group} or {nocoeff} or {fix} :l +keyword = {add} or {offset} or {shift} or {extra/atom/types} or {extra/bond/types} or {extra/angle/types} or {extra/dihedral/types} or {extra/improper/types} or {group} or {nocoeff} or {fix} :l {add} arg = {append} or {Nstart} or {merge} append = add new atoms with IDs appended to current IDs Nstart = add new atoms with IDs starting with Nstart @@ -32,11 +32,6 @@ keyword = {add} or {offset} or {shift} or {extra/atom/types} or {extra/bond/type {extra/angle/types} arg = # of extra angle types {extra/dihedral/types} arg = # of extra dihedral types {extra/improper/types} arg = # of extra improper types - {extra/bond/per/atom} arg = leave space for this many new bonds per atom - {extra/angle/per/atom} arg = leave space for this many new angles per atom - {extra/dihedral/per/atom} arg = leave space for this many new dihedrals per atom - {extra/improper/per/atom} arg = leave space for this many new impropers per atom - {extra/special/per/atom} arg = leave space for extra 1-2,1-3,1-4 interactions per atom {group} args = groupID groupID = add atoms in data file to this group {nocoeff} = ignore force field parameters @@ -62,7 +57,7 @@ simulation. The file can be ASCII text or a gzipped text file atom coordinates; see the "read_restart"_read_restart.html and "create_atoms"_create_atoms.html commands for alternative methods. Also see the explanation of the "-restart command-line -switch"_Section_start.html#start_6 which can convert a restart file to +switch"_Section_start.html#start_7 which can convert a restart file to a data file. This command can be used multiple times to add new atoms and their @@ -269,11 +264,11 @@ is different than the default. {angle types} = # of angle types in system {dihedral types} = # of dihedral types in system {improper types} = # of improper types in system -{extra bond per atom} = leave space for this many new bonds per atom (deprecated, use extra/bond/per/atom keyword) -{extra angle per atom} = leave space for this many new angles per atom (deprecated, use extra/angle/per/atom keyword) -{extra dihedral per atom} = leave space for this many new dihedrals per atom (deprecated, use extra/dihedral/per/atom keyword) -{extra improper per atom} = leave space for this many new impropers per atom (deprecated, use extra/improper/per/atom keyword) -{extra special per atom} = leave space for this many new special bonds per atom (deprecated, use extra/special/per/atom keyword) +{extra bond per atom} = leave space for this many new bonds per atom +{extra angle per atom} = leave space for this many new angles per atom +{extra dihedral per atom} = leave space for this many new dihedrals per atom +{extra improper per atom} = leave space for this many new impropers per atom +{extra special per atom} = leave space for this many new special bonds per atom {ellipsoids} = # of ellipsoids in system {lines} = # of line segments in system {triangles} = # of triangles in system @@ -372,32 +367,25 @@ read_data command will generate an error in this case. The "extra bond per atom" setting (angle, dihedral, improper) is only needed if new bonds (angles, dihedrals, impropers) will be added to the system when a simulation runs, e.g. by using the "fix -bond/create"_fix_bond_create.html command. Using this header flag -is deprecated; please use the {extra/bond/per/atom} keyword (and -correspondingly for angles, dihedrals and impropers) in the -read_data command instead. Either will pre-allocate space in LAMMPS - data structures for storing the new bonds (angles, +bond/create"_fix_bond_create.html command. This will pre-allocate +space in LAMMPS data structures for storing the new bonds (angles, dihedrals, impropers). The "extra special per atom" setting is typically only needed if new bonds/angles/etc will be added to the system, e.g. by using the "fix bond/create"_fix_bond_create.html command. Or if entire new molecules -will be added to the system, e.g. by using the -"fix deposit"_fix_deposit.html or "fix pour"_fix_pour.html commands, -which will have more special 1-2,1-3,1-4 neighbors than any other -molecules defined in the data file. Using this header flag is -deprecated; please use the {extra/special/per/atom} keyword instead. -Using this setting will pre-allocate space in the LAMMPS data -structures for storing these neighbors. See the +will be added to the system, e.g. by using the "fix +deposit"_fix_deposit.html or "fix pour"_fix_pour.html commands, which +will have more special 1-2,1-3,1-4 neighbors than any other molecules +defined in the data file. Using this setting will pre-allocate space +in the LAMMPS data structures for storing these neighbors. See the "special_bonds"_special_bonds.html and "molecule"_molecule.html doc pages for more discussion of 1-2,1-3,1-4 neighbors. -NOTE: All of the "extra" settings are only applied in the first data -file read and when no simulation box has yet been created; as soon as -the simulation box is created (and read_data implies that), these -settings are {locked} and cannot be changed anymore. Please see the -description of the {add} keyword above for reading multiple data files. -If they appear in later data files, they are ignored. +NOTE: All of the "extra" settings are only used if they appear in the +first data file read; see the description of the {add} keyword above +for reading multiple data files. If they appear in later data files, +they are ignored. The "ellipsoids" and "lines" and "triangles" and "bodies" settings are only used with "atom_style ellipsoid or line or tri or @@ -547,6 +535,9 @@ bond: atom-ID molecule-ID atom-type x y z charge: atom-ID atom-type q x y z dipole: atom-ID atom-type q x y z mux muy muz dpd: atom-ID atom-type theta x y z +edpd: atom-ID atom-type edpd_temp edpd_cv x y z +mdpd: atom-ID atom-type x y z +tdpd: atom-ID atom-type x y z cc1 cc2 ... ccNspecies electron: atom-ID atom-type q spin eradius x y z ellipsoid: atom-ID atom-type ellipsoidflag density x y z full: atom-ID molecule-ID atom-type q x y z @@ -566,12 +557,15 @@ The per-atom values have these meanings and units, listed alphabetically: atom-ID = integer ID of atom atom-type = type of atom (1-Ntype) bodyflag = 1 for body particles, 0 for point particles +cc = chemical concentration for tDPD particles for each species (mole/volume units) contact-radius = ??? (distance units) cs_re,cs_im = real/imaginary parts of wavepacket coefficients cv = heat capacity (need units) for SPH particles density = density of particle (mass/distance^3 or mass/distance^2 or mass/distance units, depending on dimensionality of particle) diameter = diameter of spherical atom (distance units) e = energy (need units) for SPH particles +edpd_temp = temperature for eDPD particles (temperature units) +edpd_cv = volumetric heat capacity for eDPD particles (energy/temperature/volume units) ellipsoidflag = 1 for ellipsoidal particles, 0 for point particles eradius = electron radius (or fixed-core radius) etag = integer ID of electron that each wavepacket belongs to diff --git a/doc/src/set.txt b/doc/src/set.txt index 14460c9741..4757d1c575 100644 --- a/doc/src/set.txt +++ b/doc/src/set.txt @@ -24,7 +24,7 @@ keyword = {type} or {type/fraction} or {mol} or {x} or {y} or {z} or \ {bond} or {angle} or {dihedral} or {improper} or \ {meso/e} or {meso/cv} or {meso/rho} or \ {smd/contact/radius} or {smd/mass/density} or {dpd/theta} or \ - {i_name} or {d_name} :l + {edpd/temp} or {edpd/cv} or {cc} or {i_name} or {d_name} :l {type} value = atom type value can be an atom-style variable (see below) {type/fraction} values = type fraction seed @@ -98,6 +98,13 @@ keyword = {type} or {type/fraction} or {mol} or {x} or {y} or {z} or \ {dpd/theta} value = internal temperature of DPD particles (temperature units) value can be an atom-style variable (see below) value can be NULL which sets internal temp of each particle to KE temp + {edpd/temp} value = temperature of eDPD particles (temperature units) + value can be an atom-style variable (see below) + {edpd/cv} value = volumetric heat capacity of eDPD particles (energy/temperature/volume units) + value can be an atom-style variable (see below) + {cc} values = index cc + index = index of a chemical species (1 to Nspecies) + cc = chemical concentration of tDPD particles for a species (mole/volume units) {i_name} value = value for custom integer vector with name {d_name} value = value for custom floating-point vector with name :pre :ule @@ -418,6 +425,19 @@ value >= 0.0, the internal temperature is set to that value. If it is < 0.0, the computation of Tkin is performed and the internal temperature is set to that value. +Keywords {edpd/temp} and {edpd/cv} set the temperature and volumetric +heat capacity of an eDPD particle as defined by the USER-MESO package. +Currently, only "atom_style edpd"_atom_style.html defines particles +with these attributes. The values for the temperature and heat +capacity must be positive. + +Keyword {cc} sets the chemical concentration of a tDPD particle for a +specified species as defined by the USER-MESO package. Currently, only +"atom_style tdpd"_atom_style.html defines particles with this +attribute. An integer for "index" selects a chemical species (1 to +Nspecies) where Nspecies is set by the atom_style command. The value +for the chemical concentration must be >= 0.0. + Keywords {i_name} and {d_name} refer to custom integer and floating-point properties that have been added to each atom via the "fix property/atom"_fix_property_atom.html command. When that command diff --git a/examples/USER/meso/README b/examples/USER/meso/README new file mode 100644 index 0000000000..4accc7ba01 --- /dev/null +++ b/examples/USER/meso/README @@ -0,0 +1,40 @@ +This directory contains input scripts for performing +simulations with these models: + +eDPD - energy-conserving dissipative particle dynamics +mDPD - many-body dissipative particle dynamics +tDPD - transport dissipative particle dynamics + +1) eDPD: The input script in.mdpd is an example simulation of +measuring the thermal conductivity by heat conduction analog of +periodic Poiseuille flow. The initial eDPD system is randomly filled +by many eDPD particles, and a set command "edpd/temp" gives the +initial temperature and a set command "edpd/cv" gives the heat +capacity of eDPD particles. A non-contact heat source/sink term is +applied by a fix command "edpd/source". A compute command +"edpd/temp/atom" obtain the temperature on each eDPD particle. The +simulation will generate a file named "temp.profile" showing the +temperature profile. For details please see online LAMMPS +documentation and Fig.12 in the paper Z. Li, et al. J Comput Phys, +2014, 265: 113-127. DOI: 10.1016/j.jcp.2014.02.003 + +2) mDPD: The input script "in.mdpd" is an example simulation of +oscillations of a free liquid droplet. The initial configuration is a +liquid film whose particles are in a fcc lattice created by the +command "create atoms". Then the liquid film has a tendency to form a +spherical droplet under the effect of surface tension. For details +please see online LAMMPS documentation and the paper Z. Li, et +al. Phys Fluids, 2013, 25: 072103. DOI: 10.1063/1.4812366 + +3) tDPD: The input script in.tdpd is an example simulation of +computing the effective diffusion coefficient of a tDPD system using a +method analogous to the periodic Poiseuille flow. Command "atom_style +tdpd 2" specifies the tDPD system with two chemical species. The +initial tDPD system is randomly filled by many tDPD particles, and a +set "cc" command gives initial concentration for each chemical +species. Fix commands "tdpd/source" add source terms and compute +commands "tdpd/cc/atom" obtain the chemical concentration on each tDPD +particle. The simulation will generate a file named "cc.profile" +showing the concentration profiles of the two chemical species. For +details please see online LAMMPS documentation and Fig.1 in the paper +Z. Li, et al. J Chem Phys, 2015, 143: 014101. DOI: 10.1063/1.4923254 diff --git a/examples/USER/meso/edpd/in.edpd b/examples/USER/meso/edpd/in.edpd new file mode 100644 index 0000000000..316099bce3 --- /dev/null +++ b/examples/USER/meso/edpd/in.edpd @@ -0,0 +1,54 @@ +######################################################################## +### Heat conduction analog of periodic Poiseuille flow problem ### +### using energy-conserving DPD (eDPD) simulation ### +### ### +### Created : Zhen Li (zhen_li@brown.edu) ### +### Division of Applied Mathematics, Brown University. ### +### ### +### mDPD system setup follows Fig.12 in the publication: ### +### Z. Li, Y.-H. Tang, H. Lei, B. Caswell and G.E. Karniadakis. ### +### "Energy-conserving dissipative particle dynamics with ### +### temperature-dependent properties". J. Comput. Phys., ### +### 2014, 265: 113-127. DOI: 10.1016/j.jcp.2014.02.003 ### +######################################################################## +units lj +dimension 3 +boundary p p p +neighbor 0.2 bin +neigh_modify every 1 delay 0 check yes + +atom_style edpd + +region edpd block -10 10 -10 10 -5 5 units box +create_box 1 edpd +create_atoms 1 random 16000 276438 NULL +mass 1 1.0 +set atom * edpd/temp 1.0 +set atom * edpd/cv 1.0E5 + +pair_style edpd 1.58 9872598 +#pair_coeff 1 1 18.75 4.5 0.41 1.58 1.45E-5 2.0 1.58 +pair_coeff 1 1 18.75 4.5 0.41 1.58 1.41E-5 2.0 1.58 & + power 10.54 -3.66 3.44 -4.10 & + kappa -0.44 -3.21 5.04 0.00 + +compute mythermo all temp +thermo 100 +thermo_modify temp mythermo +thermo_modify flush yes + +velocity all create 1.0 432982 loop local dist gaussian + +fix mvv all mvv/edpd 0.5 +fix upper all edpd/source cuboid 0.0 5.0 0.0 20.0 10.0 10.0 0.01 +fix lower all edpd/source cuboid 0.0 -5.0 0.0 20.0 10.0 10.0 -0.01 + +timestep 0.01 +run 500 +reset_timestep 0 + +compute temp all edpd/temp/atom +compute ccT all chunk/atom bin/1d y 0.0 1.0 +fix stat all ave/chunk 1 500 500 ccT c_temp density/number norm sample file temp.profile + +run 500 diff --git a/examples/USER/meso/edpd/log.16Aug17.edpd.g++.1 b/examples/USER/meso/edpd/log.16Aug17.edpd.g++.1 new file mode 100644 index 0000000000..af975f877c --- /dev/null +++ b/examples/USER/meso/edpd/log.16Aug17.edpd.g++.1 @@ -0,0 +1,142 @@ +LAMMPS (11 Aug 2017) +######################################################################## +### Heat conduction analog of periodic Poiseuille flow problem ### +### using energy-conserving DPD (eDPD) simulation ### +### ### +### Created : Zhen Li (zhen_li@brown.edu) ### +### Division of Applied Mathematics, Brown University. ### +### ### +### mDPD system setup follows Fig.12 in the publication: ### +### Z. Li, Y.-H. Tang, H. Lei, B. Caswell and G.E. Karniadakis. ### +### "Energy-conserving dissipative particle dynamics with ### +### temperature-dependent properties". J. Comput. Phys., ### +### 2014, 265: 113-127. DOI: 10.1016/j.jcp.2014.02.003 ### +######################################################################## +units lj +dimension 3 +boundary p p p +neighbor 0.2 bin +neigh_modify every 1 delay 0 check yes + +atom_style edpd + +region edpd block -10 10 -10 10 -5 5 units box +create_box 1 edpd +Created orthogonal box = (-10 -10 -5) to (10 10 5) + 1 by 1 by 1 MPI processor grid +create_atoms 1 random 16000 276438 NULL +Created 16000 atoms +mass 1 1.0 +set atom * edpd/temp 1.0 + 16000 settings made for edpd/temp +set atom * edpd/cv 1.0E5 + 16000 settings made for edpd/cv + +pair_style edpd 1.58 9872598 +#pair_coeff 1 1 18.75 4.5 0.41 1.58 1.45E-5 2.0 1.58 +pair_coeff 1 1 18.75 4.5 0.41 1.58 1.41E-5 2.0 1.58 power 10.54 -3.66 3.44 -4.10 kappa -0.44 -3.21 5.04 0.00 + +compute mythermo all temp +thermo 100 +thermo_modify temp mythermo +thermo_modify flush yes + +velocity all create 1.0 432982 loop local dist gaussian + +fix mvv all mvv/edpd 0.5 +fix upper all edpd/source cuboid 0.0 5.0 0.0 20.0 10.0 10.0 0.01 +fix lower all edpd/source cuboid 0.0 -5.0 0.0 20.0 10.0 10.0 -0.01 + +timestep 0.01 +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 = 1.78 + ghost atom cutoff = 1.78 + binsize = 0.89, bins = 23 23 12 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair edpd, 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) = 11.64 | 11.64 | 11.64 Mbytes +Step Temp E_pair E_mol TotEng Press + 0 1 48.948932 0 50.448838 201.73366 + 100 1.0069712 43.754293 0 45.264656 199.5369 + 200 0.98667561 43.716052 0 45.195973 196.72854 + 300 1.0036944 43.706299 0 45.211746 195.35714 + 400 1.0024228 43.697014 0 45.200554 197.0062 + 500 0.99968161 43.687445 0 45.186873 193.80596 +Loop time of 80.7995 on 1 procs for 500 steps with 16000 atoms + +Performance: 5346.567 tau/day, 6.188 timesteps/s +99.9% CPU use with 1 MPI tasks x no OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 75.106 | 75.106 | 75.106 | 0.0 | 92.95 +Neigh | 4.9836 | 4.9836 | 4.9836 | 0.0 | 6.17 +Comm | 0.31199 | 0.31199 | 0.31199 | 0.0 | 0.39 +Output | 0.00048232 | 0.00048232 | 0.00048232 | 0.0 | 0.00 +Modify | 0.29985 | 0.29985 | 0.29985 | 0.0 | 0.37 +Other | | 0.09751 | | | 0.12 + +Nlocal: 16000 ave 16000 max 16000 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 14091 ave 14091 max 14091 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 749111 ave 749111 max 749111 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 749111 +Ave neighs/atom = 46.8194 +Neighbor list builds = 181 +Dangerous builds = 0 +reset_timestep 0 + +compute temp all edpd/temp/atom +compute ccT all chunk/atom bin/1d y 0.0 1.0 +fix stat all ave/chunk 1 500 500 ccT c_temp density/number norm sample file temp.profile + +run 500 +Per MPI rank memory allocation (min/avg/max) = 12.14 | 12.14 | 12.14 Mbytes +Step Temp E_pair E_mol TotEng Press + 0 0.99968161 43.687397 0 45.186825 196.38426 + 100 1.0041443 43.668196 0 45.174318 195.38066 + 200 0.99628392 43.666173 0 45.160505 197.84675 + 300 1.0029116 43.66224 0 45.166513 199.67414 + 400 0.99922193 43.64406 0 45.142799 196.94404 + 500 0.99355431 43.623266 0 45.113505 195.94136 +Loop time of 80.7742 on 1 procs for 500 steps with 16000 atoms + +Performance: 5348.242 tau/day, 6.190 timesteps/s +99.9% CPU use with 1 MPI tasks x no OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 75.073 | 75.073 | 75.073 | 0.0 | 92.94 +Neigh | 4.8786 | 4.8786 | 4.8786 | 0.0 | 6.04 +Comm | 0.31086 | 0.31086 | 0.31086 | 0.0 | 0.38 +Output | 0.00045919 | 0.00045919 | 0.00045919 | 0.0 | 0.00 +Modify | 0.4139 | 0.4139 | 0.4139 | 0.0 | 0.51 +Other | | 0.09731 | | | 0.12 + +Nlocal: 16000 ave 16000 max 16000 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 14091 ave 14091 max 14091 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 749667 ave 749667 max 749667 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 749667 +Ave neighs/atom = 46.8542 +Neighbor list builds = 178 +Dangerous builds = 0 + +Please see the log.cite file for references relevant to this simulation + +Total wall time: 0:02:41 diff --git a/examples/USER/meso/edpd/log.16Aug17.edpd.g++.4 b/examples/USER/meso/edpd/log.16Aug17.edpd.g++.4 new file mode 100644 index 0000000000..21206d38c6 --- /dev/null +++ b/examples/USER/meso/edpd/log.16Aug17.edpd.g++.4 @@ -0,0 +1,142 @@ +LAMMPS (11 Aug 2017) +######################################################################## +### Heat conduction analog of periodic Poiseuille flow problem ### +### using energy-conserving DPD (eDPD) simulation ### +### ### +### Created : Zhen Li (zhen_li@brown.edu) ### +### Division of Applied Mathematics, Brown University. ### +### ### +### mDPD system setup follows Fig.12 in the publication: ### +### Z. Li, Y.-H. Tang, H. Lei, B. Caswell and G.E. Karniadakis. ### +### "Energy-conserving dissipative particle dynamics with ### +### temperature-dependent properties". J. Comput. Phys., ### +### 2014, 265: 113-127. DOI: 10.1016/j.jcp.2014.02.003 ### +######################################################################## +units lj +dimension 3 +boundary p p p +neighbor 0.2 bin +neigh_modify every 1 delay 0 check yes + +atom_style edpd + +region edpd block -10 10 -10 10 -5 5 units box +create_box 1 edpd +Created orthogonal box = (-10 -10 -5) to (10 10 5) + 2 by 2 by 1 MPI processor grid +create_atoms 1 random 16000 276438 NULL +Created 16000 atoms +mass 1 1.0 +set atom * edpd/temp 1.0 + 16000 settings made for edpd/temp +set atom * edpd/cv 1.0E5 + 16000 settings made for edpd/cv + +pair_style edpd 1.58 9872598 +#pair_coeff 1 1 18.75 4.5 0.41 1.58 1.45E-5 2.0 1.58 +pair_coeff 1 1 18.75 4.5 0.41 1.58 1.41E-5 2.0 1.58 power 10.54 -3.66 3.44 -4.10 kappa -0.44 -3.21 5.04 0.00 + +compute mythermo all temp +thermo 100 +thermo_modify temp mythermo +thermo_modify flush yes + +velocity all create 1.0 432982 loop local dist gaussian + +fix mvv all mvv/edpd 0.5 +fix upper all edpd/source cuboid 0.0 5.0 0.0 20.0 10.0 10.0 0.01 +fix lower all edpd/source cuboid 0.0 -5.0 0.0 20.0 10.0 10.0 -0.01 + +timestep 0.01 +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 = 1.78 + ghost atom cutoff = 1.78 + binsize = 0.89, bins = 23 23 12 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair edpd, 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) = 4.969 | 4.979 | 4.985 Mbytes +Step Temp E_pair E_mol TotEng Press + 0 1 48.948932 0 50.448838 199.51547 + 100 1.0106415 43.744371 0 45.260239 196.39598 + 200 1.0053215 43.714413 0 45.222301 195.35298 + 300 0.99886399 43.713356 0 45.211559 196.74821 + 400 1.0035264 43.699086 0 45.204282 195.47446 + 500 1.0025285 43.698051 0 45.20175 197.27042 +Loop time of 21.165 on 4 procs for 500 steps with 16000 atoms + +Performance: 20411.046 tau/day, 23.624 timesteps/s +99.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 | 18.713 | 19.101 | 19.41 | 6.0 | 90.25 +Neigh | 1.2687 | 1.2925 | 1.3177 | 1.5 | 6.11 +Comm | 0.33013 | 0.66337 | 1.0747 | 34.3 | 3.13 +Output | 0.00023484 | 0.00028092 | 0.00036526 | 0.0 | 0.00 +Modify | 0.073931 | 0.075277 | 0.076306 | 0.3 | 0.36 +Other | | 0.03227 | | | 0.15 + +Nlocal: 4000 ave 4067 max 3930 min +Histogram: 1 1 0 0 0 0 0 0 0 2 +Nghost: 5997.5 ave 6052 max 5943 min +Histogram: 1 0 1 0 0 0 0 1 0 1 +Neighs: 187388 ave 193157 max 181221 min +Histogram: 1 1 0 0 0 0 0 0 0 2 + +Total # of neighbors = 749552 +Ave neighs/atom = 46.847 +Neighbor list builds = 181 +Dangerous builds = 0 +reset_timestep 0 + +compute temp all edpd/temp/atom +compute ccT all chunk/atom bin/1d y 0.0 1.0 +fix stat all ave/chunk 1 500 500 ccT c_temp density/number norm sample file temp.profile + +run 500 +Per MPI rank memory allocation (min/avg/max) = 5.221 | 5.23 | 5.236 Mbytes +Step Temp E_pair E_mol TotEng Press + 0 1.0025285 43.69801 0 45.201708 194.00452 + 100 0.9885969 43.679927 0 45.16273 196.28442 + 200 1.0028463 43.663067 0 45.167242 198.25592 + 300 1.0027516 43.648817 0 45.152851 198.82226 + 400 0.99695312 43.641469 0 45.136805 197.97499 + 500 0.98202292 43.627163 0 45.100105 199.16319 +Loop time of 21.576 on 4 procs for 500 steps with 16000 atoms + +Performance: 20022.203 tau/day, 23.174 timesteps/s +99.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 | 18.438 | 19.121 | 19.812 | 14.1 | 88.62 +Neigh | 1.2568 | 1.2885 | 1.325 | 2.5 | 5.97 +Comm | 0.29482 | 1.0219 | 1.7352 | 63.9 | 4.74 +Output | 0.00027728 | 0.00029719 | 0.0003531 | 0.0 | 0.00 +Modify | 0.11153 | 0.11265 | 0.1135 | 0.2 | 0.52 +Other | | 0.03194 | | | 0.15 + +Nlocal: 4000 ave 4092 max 3899 min +Histogram: 2 0 0 0 0 0 0 0 0 2 +Nghost: 5974 ave 6019 max 5915 min +Histogram: 1 0 0 1 0 0 0 0 0 2 +Neighs: 187414 ave 196149 max 178418 min +Histogram: 2 0 0 0 0 0 0 0 0 2 + +Total # of neighbors = 749658 +Ave neighs/atom = 46.8536 +Neighbor list builds = 181 +Dangerous builds = 0 + +Please see the log.cite file for references relevant to this simulation + +Total wall time: 0:00:42 diff --git a/examples/USER/meso/edpd/temp.profile.16Aug17.edpd.g++.1 b/examples/USER/meso/edpd/temp.profile.16Aug17.edpd.g++.1 new file mode 100644 index 0000000000..469b550258 --- /dev/null +++ b/examples/USER/meso/edpd/temp.profile.16Aug17.edpd.g++.1 @@ -0,0 +1,24 @@ +# Chunk-averaged data for fix stat and group density/number +# Timestep Number-of-chunks Total-count +# Chunk Coord1 Ncount c_temp density/number +500 20 16000 + 1 -9.5 801.636 0.986368 4.00818 + 2 -8.5 809.788 0.966281 4.04894 + 3 -7.5 819.754 0.952764 4.09877 + 4 -6.5 820.364 0.944592 4.10182 + 5 -5.5 826.146 0.940968 4.13073 + 6 -4.5 819.52 0.941415 4.0976 + 7 -3.5 815.182 0.945887 4.07591 + 8 -2.5 817.168 0.95487 4.08584 + 9 -1.5 817.282 0.969225 4.08641 + 10 -0.5 804.204 0.989552 4.02102 + 11 0.5 793.266 1.01015 3.96633 + 12 1.5 789.056 1.0308 3.94528 + 13 2.5 784.344 1.04568 3.92172 + 14 3.5 780.592 1.05508 3.90296 + 15 4.5 772.218 1.05968 3.86109 + 16 5.5 776.968 1.06003 3.88484 + 17 6.5 780.858 1.05612 3.90429 + 18 7.5 786.174 1.04752 3.93087 + 19 8.5 788.922 1.03347 3.94461 + 20 9.5 796.558 1.01278 3.98279 diff --git a/examples/USER/meso/edpd/temp.profile.16Aug17.edpd.g++.4 b/examples/USER/meso/edpd/temp.profile.16Aug17.edpd.g++.4 new file mode 100644 index 0000000000..1c50a9b6e5 --- /dev/null +++ b/examples/USER/meso/edpd/temp.profile.16Aug17.edpd.g++.4 @@ -0,0 +1,24 @@ +# Chunk-averaged data for fix stat and group density/number +# Timestep Number-of-chunks Total-count +# Chunk Coord1 Ncount c_temp density/number +500 20 16000 + 1 -9.5 801.642 0.986089 4.00821 + 2 -8.5 819.168 0.966072 4.09584 + 3 -7.5 817.382 0.952718 4.08691 + 4 -6.5 818 0.944633 4.09 + 5 -5.5 817.806 0.941105 4.08903 + 6 -4.5 826.11 0.941499 4.13055 + 7 -3.5 821.946 0.945922 4.10973 + 8 -2.5 816.202 0.954889 4.08101 + 9 -1.5 813.202 0.969281 4.06601 + 10 -0.5 798.904 0.989463 3.99452 + 11 0.5 798.056 1.01005 3.99028 + 12 1.5 793.114 1.03073 3.96557 + 13 2.5 782.812 1.04569 3.91406 + 14 3.5 775.69 1.05498 3.87845 + 15 4.5 778.094 1.05965 3.89047 + 16 5.5 778.856 1.06002 3.89428 + 17 6.5 780.51 1.05621 3.90255 + 18 7.5 780.518 1.04782 3.90259 + 19 8.5 789.698 1.03348 3.94849 + 20 9.5 792.29 1.01261 3.96145 diff --git a/examples/USER/meso/mdpd/in.mdpd b/examples/USER/meso/mdpd/in.mdpd new file mode 100644 index 0000000000..201b4a340e --- /dev/null +++ b/examples/USER/meso/mdpd/in.mdpd @@ -0,0 +1,52 @@ +######################################################################## +#### 3D droplet oscilation using many-body DPD simulation ### +#### ### +#### Created : Zhen Li (zhen_li@brown.edu) ### +#### Division of Applied Mathematics, Brown University. ### +#### ### +#### mDPD parameters follow the choice of the publication: ### +#### Z. Li et al. "Three dimensional flow structures in a moving ### +#### droplet on substrate: a dissipative particle dynamics study" ### +#### Physics of Fluids, 2013, 25: 072103. DOI: 10.1063/1.4812366 ### +######################################################################## +units lj +dimension 3 +boundary p p p +neighbor 0.3 bin +neigh_modify every 1 delay 0 check yes + +atom_style mdpd + +region mdpd block -25 25 -10 10 -10 10 units box +create_box 1 mdpd + +lattice fcc 6 +region film block -20 20 -7.5 7.5 -2.0 2.0 units box +create_atoms 1 region film + +pair_style hybrid/overlay mdpd/rhosum mdpd 1.0 1.0 9872598 +pair_coeff 1 1 mdpd/rhosum 0.75 +pair_coeff 1 1 mdpd -40 25 18.0 1.0 0.75 +mass 1 1.0 + +compute mythermo all temp +thermo 100 +thermo_modify temp mythermo +thermo_modify flush yes + +velocity all create 1.0 38497 loop local dist gaussian + +fix mvv all mvv/dpd + +#dump mydump all atom 100 atom.lammpstrj + +#dump jpg all image 200 image.*.jpg type type zoom 5 adiam 0.5 & +# view 90 90 box no 0 size 600 200 +#dump_modify jpg pad 4 + +#dump avi all movie 200 movie.avi type type zoom 5 adiam 0.5 & +# view 90 90 box no 0 size 600 200 +#dump_modify avi pad 4 + +timestep 0.01 +run 4000 diff --git a/examples/USER/meso/mdpd/log.16Aug17.mdpd.g++.1 b/examples/USER/meso/mdpd/log.16Aug17.mdpd.g++.1 new file mode 100644 index 0000000000..c3c14da559 --- /dev/null +++ b/examples/USER/meso/mdpd/log.16Aug17.mdpd.g++.1 @@ -0,0 +1,147 @@ +LAMMPS (11 Aug 2017) +######################################################################## +#### 3D droplet oscilation using many-body DPD simulation ### +#### ### +#### Created : Zhen Li (zhen_li@brown.edu) ### +#### Division of Applied Mathematics, Brown University. ### +#### ### +#### mDPD parameters follow the choice of the publication: ### +#### Z. Li et al. "Three dimensional flow structures in a moving ### +#### droplet on substrate: a dissipative particle dynamics study" ### +#### Physics of Fluids, 2013, 25: 072103. DOI: 10.1063/1.4812366 ### +######################################################################## +units lj +dimension 3 +boundary p p p +neighbor 0.3 bin +neigh_modify every 1 delay 0 check yes + +atom_style mdpd + +region mdpd block -25 25 -10 10 -10 10 units box +create_box 1 mdpd +Created orthogonal box = (-25 -10 -10) to (25 10 10) + 1 by 1 by 1 MPI processor grid + +lattice fcc 6 +Lattice spacing in x,y,z = 0.87358 0.87358 0.87358 +region film block -20 20 -7.5 7.5 -2.0 2.0 units box +create_atoms 1 region film +Created 14333 atoms + +pair_style hybrid/overlay mdpd/rhosum mdpd 1.0 1.0 9872598 +pair_coeff 1 1 mdpd/rhosum 0.75 +pair_coeff 1 1 mdpd -40 25 18.0 1.0 0.75 +mass 1 1.0 + +compute mythermo all temp +thermo 100 +thermo_modify temp mythermo +thermo_modify flush yes + +velocity all create 1.0 38497 loop local dist gaussian + +fix mvv all mvv/dpd + +dump mydump all atom 100 atom.lammpstrj + +#dump jpg all image 200 image.*.jpg type type zoom 5 adiam 0.5 # view 90 90 box no 0 size 600 200 +#dump_modify jpg pad 4 + +#dump avi all movie 200 movie.avi type type zoom 5 adiam 0.5 # view 90 90 box no 0 size 600 200 +#dump_modify avi pad 4 + +timestep 0.01 +run 4000 +Neighbor list info ... + update every 1 steps, delay 0 steps, check yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 1.3 + ghost atom cutoff = 1.3 + binsize = 0.65, bins = 77 31 31 + 2 neighbor lists, perpetual/occasional/extra = 2 0 0 + (1) pair mdpd/rhosum, perpetual + attributes: full, newton on + pair build: full/bin/atomonly + stencil: full/bin/3d + bin: standard + (2) pair mdpd, perpetual, half/full from (1) + attributes: half, newton on + pair build: halffull/newton + stencil: none + bin: none +Per MPI rank memory allocation (min/avg/max) = 9.931 | 9.931 | 9.931 Mbytes +Step Temp E_pair E_mol TotEng Press + 0 1 -13.346542 0 -11.846647 -6.8495478 + 100 1.0321029 -7.2846779 0 -5.7366316 -0.77640205 + 200 1.042287 -6.9534532 0 -5.3901317 -0.27750815 + 300 1.0583027 -6.8483105 0 -5.2609672 -0.30347708 + 400 1.0493719 -6.8648608 0 -5.2909127 -0.15312495 + 500 1.0723786 -6.8341085 0 -5.2256528 0.017227511 + 600 1.0545695 -6.8152957 0 -5.2335517 -0.024362439 + 700 1.0507193 -6.8076033 0 -5.2316344 -0.07101536 + 800 1.0531856 -6.9378568 0 -5.3581886 -0.053943939 + 900 1.0442995 -6.8501126 0 -5.2837726 -0.13347942 + 1000 1.0335049 -6.8883554 0 -5.3382062 -0.18420426 + 1100 1.0287276 -6.8298226 0 -5.2868389 -0.12081558 + 1200 1.0322527 -6.9462828 0 -5.3980117 -0.18047625 + 1300 1.0599443 -6.9449975 0 -5.355192 -0.011763589 + 1400 1.0560932 -6.845479 0 -5.2614498 0.032130055 + 1500 1.0432786 -6.9035877 0 -5.338779 -0.10268662 + 1600 1.064183 -6.9116836 0 -5.3155205 -0.060722129 + 1700 1.0586249 -6.8768278 0 -5.2890013 0.037005566 + 1800 1.0576064 -7.0060193 0 -5.4197204 -0.036211254 + 1900 1.0595141 -6.838741 0 -5.2495807 -0.12395681 + 2000 1.0650509 -6.897976 0 -5.3005111 0.003594807 + 2100 1.0768273 -6.8874245 0 -5.2722962 0.033283489 + 2200 1.0511606 -6.9823162 0 -5.4056854 0.015008427 + 2300 1.0461138 -6.8820601 0 -5.3129988 0.064646933 + 2400 1.0485369 -6.9437148 0 -5.3710191 -0.16534939 + 2500 1.0507221 -6.9394786 0 -5.3635054 -0.098289859 + 2600 1.0518352 -6.8947578 0 -5.3171152 -0.011666785 + 2700 1.0402369 -6.9273377 0 -5.3670913 0.035267073 + 2800 1.0426109 -6.912024 0 -5.3482168 0.049597305 + 2900 1.0358928 -6.9574778 0 -5.4037471 -0.063216561 + 3000 1.0351023 -6.9844192 0 -5.4318742 -0.10323465 + 3100 1.0255005 -6.9382486 0 -5.4001052 -0.073954735 + 3200 1.0150616 -6.9843183 0 -5.4618321 -0.095136405 + 3300 1.0118112 -6.9522082 0 -5.4345973 -0.12686179 + 3400 1.0071522 -6.970158 0 -5.4595351 -0.012487475 + 3500 1.0041758 -6.9773019 0 -5.4711433 -0.098027653 + 3600 1.0189298 -6.9393039 0 -5.4110158 0.061631719 + 3700 1.012442 -6.9341423 0 -5.4155852 0.10442772 + 3800 1.0021246 -6.9594374 0 -5.4563553 -0.081535223 + 3900 1.0165002 -6.9045321 0 -5.3798882 -0.0088283303 + 4000 1.0077099 -6.9145511 0 -5.4030918 0.048349691 +Loop time of 135.409 on 1 procs for 4000 steps with 14333 atoms + +Performance: 25522.736 tau/day, 29.540 timesteps/s +99.9% CPU use with 1 MPI tasks x no OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 93.074 | 93.074 | 93.074 | 0.0 | 68.74 +Neigh | 40.192 | 40.192 | 40.192 | 0.0 | 29.68 +Comm | 0.19625 | 0.19625 | 0.19625 | 0.0 | 0.14 +Output | 0.41756 | 0.41756 | 0.41756 | 0.0 | 0.31 +Modify | 1.0706 | 1.0706 | 1.0706 | 0.0 | 0.79 +Other | | 0.4581 | | | 0.34 + +Nlocal: 14333 ave 14333 max 14333 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 11 ave 11 max 11 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 401803 ave 401803 max 401803 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +FullNghs: 803606 ave 803606 max 803606 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 803606 +Ave neighs/atom = 56.0668 +Neighbor list builds = 1050 +Dangerous builds = 0 + +Please see the log.cite file for references relevant to this simulation + +Total wall time: 0:02:15 diff --git a/examples/USER/meso/mdpd/log.16Aug17.mdpd.g++.4 b/examples/USER/meso/mdpd/log.16Aug17.mdpd.g++.4 new file mode 100644 index 0000000000..ec3d8fbddc --- /dev/null +++ b/examples/USER/meso/mdpd/log.16Aug17.mdpd.g++.4 @@ -0,0 +1,147 @@ +LAMMPS (11 Aug 2017) +######################################################################## +#### 3D droplet oscilation using many-body DPD simulation ### +#### ### +#### Created : Zhen Li (zhen_li@brown.edu) ### +#### Division of Applied Mathematics, Brown University. ### +#### ### +#### mDPD parameters follow the choice of the publication: ### +#### Z. Li et al. "Three dimensional flow structures in a moving ### +#### droplet on substrate: a dissipative particle dynamics study" ### +#### Physics of Fluids, 2013, 25: 072103. DOI: 10.1063/1.4812366 ### +######################################################################## +units lj +dimension 3 +boundary p p p +neighbor 0.3 bin +neigh_modify every 1 delay 0 check yes + +atom_style mdpd + +region mdpd block -25 25 -10 10 -10 10 units box +create_box 1 mdpd +Created orthogonal box = (-25 -10 -10) to (25 10 10) + 4 by 1 by 1 MPI processor grid + +lattice fcc 6 +Lattice spacing in x,y,z = 0.87358 0.87358 0.87358 +region film block -20 20 -7.5 7.5 -2.0 2.0 units box +create_atoms 1 region film +Created 14333 atoms + +pair_style hybrid/overlay mdpd/rhosum mdpd 1.0 1.0 9872598 +pair_coeff 1 1 mdpd/rhosum 0.75 +pair_coeff 1 1 mdpd -40 25 18.0 1.0 0.75 +mass 1 1.0 + +compute mythermo all temp +thermo 100 +thermo_modify temp mythermo +thermo_modify flush yes + +velocity all create 1.0 38497 loop local dist gaussian + +fix mvv all mvv/dpd + +dump mydump all atom 100 atom.lammpstrj + +#dump jpg all image 200 image.*.jpg type type zoom 5 adiam 0.5 # view 90 90 box no 0 size 600 200 +#dump_modify jpg pad 4 + +#dump avi all movie 200 movie.avi type type zoom 5 adiam 0.5 # view 90 90 box no 0 size 600 200 +#dump_modify avi pad 4 + +timestep 0.01 +run 4000 +Neighbor list info ... + update every 1 steps, delay 0 steps, check yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 1.3 + ghost atom cutoff = 1.3 + binsize = 0.65, bins = 77 31 31 + 2 neighbor lists, perpetual/occasional/extra = 2 0 0 + (1) pair mdpd/rhosum, perpetual + attributes: full, newton on + pair build: full/bin/atomonly + stencil: full/bin/3d + bin: standard + (2) pair mdpd, perpetual, half/full from (1) + attributes: half, newton on + pair build: halffull/newton + stencil: none + bin: none +Per MPI rank memory allocation (min/avg/max) = 6.265 | 6.655 | 7.045 Mbytes +Step Temp E_pair E_mol TotEng Press + 0 1 -13.346542 0 -11.846647 -6.9757225 + 100 1.0406108 -7.2500697 0 -5.6892624 -0.80306477 + 200 1.0535506 -6.9452928 0 -5.3650772 -0.39911584 + 300 1.0644295 -6.8599907 0 -5.2634577 -0.2997968 + 400 1.0780123 -6.9471342 0 -5.3302286 -0.06274869 + 500 1.0672153 -6.8269984 0 -5.2262872 0.021251762 + 600 1.0634304 -6.8366569 0 -5.2416226 -0.021863333 + 700 1.0544807 -6.8272074 0 -5.2455967 -0.0064688066 + 800 1.0556172 -6.8859788 0 -5.3026634 0.023983333 + 900 1.0436201 -6.9246523 0 -5.3593313 -0.12409618 + 1000 1.0617016 -6.8632331 0 -5.2707919 -0.1145505 + 1100 1.0323831 -6.951554 0 -5.4030874 -0.030031884 + 1200 1.0407785 -6.931048 0 -5.3699892 -0.018362136 + 1300 1.0380953 -6.8785296 0 -5.3214953 -0.099308737 + 1400 1.0418898 -6.8998 0 -5.3370743 -0.14199421 + 1500 1.0487254 -6.9671212 0 -5.3941429 -0.12132644 + 1600 1.0561042 -6.8948881 0 -5.3108424 -0.09627292 + 1700 1.0524479 -6.9531441 0 -5.3745823 -0.11959782 + 1800 1.0541197 -6.9219819 0 -5.3409126 0.032964029 + 1900 1.0531221 -6.8805815 0 -5.3010085 0.030124685 + 2000 1.0531819 -6.8612868 0 -5.2816242 -0.076876781 + 2100 1.0757791 -6.919875 0 -5.3063189 -0.04060439 + 2200 1.069423 -6.9005754 0 -5.2965527 0.015347467 + 2300 1.0403109 -6.9015402 0 -5.3411827 0.0034687897 + 2400 1.0547448 -6.9325539 0 -5.3505471 -0.021202325 + 2500 1.0404195 -6.8494675 0 -5.2889472 0.086947847 + 2600 1.0499828 -6.9861392 0 -5.4112749 -0.018079308 + 2700 1.0294278 -6.8525151 0 -5.3084811 0.16911472 + 2800 1.0220652 -6.8993978 0 -5.366407 0.064820531 + 2900 1.0347904 -6.9322703 0 -5.3801929 -0.11384964 + 3000 1.0391372 -6.9519088 0 -5.3933117 0.003050577 + 3100 1.0335828 -7.0090074 0 -5.4587413 -0.17366664 + 3200 1.0211896 -6.9421289 0 -5.4104513 0.025299853 + 3300 1.0019232 -6.9426488 0 -5.4398688 -0.098334724 + 3400 1.0203541 -6.9310981 0 -5.4006737 -0.0015544982 + 3500 1.0076794 -6.9519932 0 -5.4405796 -0.056956902 + 3600 1.0086525 -6.9620979 0 -5.4492247 0.020014884 + 3700 1.0046112 -7.0011625 0 -5.4943508 -0.083936527 + 3800 1.0096867 -6.9470382 0 -5.4326138 -0.089521759 + 3900 1.0074482 -6.9959414 0 -5.4848745 -0.11873698 + 4000 1.01222 -6.9535694 0 -5.4353454 0.042191466 +Loop time of 63.0327 on 4 procs for 4000 steps with 14333 atoms + +Performance: 54828.695 tau/day, 63.459 timesteps/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 | 16.591 | 29.795 | 42.814 | 236.6 | 47.27 +Neigh | 2.0347 | 10.239 | 18.555 | 255.6 | 16.24 +Comm | 0.70099 | 6.0601 | 11.386 | 207.4 | 9.61 +Output | 0.20713 | 0.40902 | 0.61087 | 31.5 | 0.65 +Modify | 0.058089 | 0.27033 | 0.4851 | 40.7 | 0.43 +Other | | 16.26 | | | 25.79 + +Nlocal: 3583.25 ave 7207 max 0 min +Histogram: 2 0 0 0 0 0 0 0 0 2 +Nghost: 1055.75 ave 2131 max 0 min +Histogram: 2 0 0 0 0 0 0 0 0 2 +Neighs: 100549 ave 202192 max 0 min +Histogram: 2 0 0 0 0 0 0 0 0 2 +FullNghs: 201098 ave 404372 max 0 min +Histogram: 2 0 0 0 0 0 0 0 0 2 + +Total # of neighbors = 804390 +Ave neighs/atom = 56.1215 +Neighbor list builds = 1049 +Dangerous builds = 0 + +Please see the log.cite file for references relevant to this simulation + +Total wall time: 0:01:03 diff --git a/examples/USER/meso/tdpd/cc.profile.16Aug17.tdpd.g++.1 b/examples/USER/meso/tdpd/cc.profile.16Aug17.tdpd.g++.1 new file mode 100644 index 0000000000..a872600504 --- /dev/null +++ b/examples/USER/meso/tdpd/cc.profile.16Aug17.tdpd.g++.1 @@ -0,0 +1,24 @@ +# Chunk-averaged data for fix stat and group c_cc2 +# Timestep Number-of-chunks Total-count +# Chunk Coord1 Ncount c_cc1 c_cc2 +100 20 16000 + 1 -9.5 797.17 0.986661 1.0077 + 2 -8.5 802.61 0.967974 1.02003 + 3 -7.5 795.46 0.957045 1.02873 + 4 -6.5 806.46 0.951271 1.03428 + 5 -5.5 802.34 0.94898 1.03692 + 6 -4.5 799.84 0.949378 1.03673 + 7 -3.5 798.4 0.952505 1.03374 + 8 -2.5 800.36 0.959322 1.02778 + 9 -1.5 797.65 0.971516 1.01867 + 10 -0.5 808.88 0.990644 1.00626 + 11 0.5 786.29 1.00924 0.993828 + 12 1.5 807.16 1.02831 0.981436 + 13 2.5 797.54 1.04071 0.972184 + 14 3.5 799.67 1.04749 0.966258 + 15 4.5 799.61 1.05063 0.963256 + 16 5.5 806.11 1.05105 0.963052 + 17 6.5 803.67 1.04877 0.965688 + 18 7.5 797.39 1.04305 0.971187 + 19 8.5 801.85 1.03208 0.97993 + 20 9.5 791.54 1.01351 0.992209 diff --git a/examples/USER/meso/tdpd/cc.profile.16Aug17.tdpd.g++.4 b/examples/USER/meso/tdpd/cc.profile.16Aug17.tdpd.g++.4 new file mode 100644 index 0000000000..de34ef26c3 --- /dev/null +++ b/examples/USER/meso/tdpd/cc.profile.16Aug17.tdpd.g++.4 @@ -0,0 +1,24 @@ +# Chunk-averaged data for fix stat and group c_cc2 +# Timestep Number-of-chunks Total-count +# Chunk Coord1 Ncount c_cc1 c_cc2 +100 20 16000 + 1 -9.5 806.92 0.986675 1.00766 + 2 -8.5 798.01 0.96792 1.02003 + 3 -7.5 805.43 0.956909 1.02883 + 4 -6.5 800.54 0.951207 1.03432 + 5 -5.5 794.14 0.948967 1.03691 + 6 -4.5 799.75 0.949379 1.03672 + 7 -3.5 799.65 0.952492 1.03374 + 8 -2.5 799.94 0.959331 1.02778 + 9 -1.5 800.96 0.971664 1.01861 + 10 -0.5 803.97 0.99074 1.00622 + 11 0.5 800.66 1.00949 0.993673 + 12 1.5 779.22 1.02824 0.981461 + 13 2.5 809.13 1.04056 0.972274 + 14 3.5 805.23 1.04747 0.966272 + 15 4.5 795.95 1.05061 0.96327 + 16 5.5 796.4 1.05105 0.963035 + 17 6.5 806.1 1.04883 0.965621 + 18 7.5 806.41 1.04305 0.971224 + 19 8.5 792.2 1.03211 0.979955 + 20 9.5 799.39 1.01362 0.992156 diff --git a/examples/USER/meso/tdpd/in.tdpd b/examples/USER/meso/tdpd/in.tdpd new file mode 100644 index 0000000000..748a4f5077 --- /dev/null +++ b/examples/USER/meso/tdpd/in.tdpd @@ -0,0 +1,54 @@ +######################################################################## +### Pure diffusion with a reaction source term analog of a periodic ### +### Poiseuille flow problem using transport DPD (tDPD) simulation ### +### ### +### Created : Zhen Li (zhen_li@brown.edu) ### +### Division of Applied Mathematics, Brown University. ### +### ### +### tDPD system setup follows Fig.1 in the publication: ### +### Z. Li, A. Yazdani, A. Tartakovsky and G.E. Karniadakis. ### +### "Transport dissipative particle dynamics model for mesoscopic ### +### advection-diffusion-reaction problems. J. Chem. Phys., ### +### 2015, 143: 014101. DOI: 10.1063/1.4923254 ### +######################################################################## +units lj +dimension 3 +boundary p p p +neighbor 0.2 bin +neigh_modify every 1 delay 0 check yes + +atom_style tdpd 2 + +region tdpd block -10 10 -10 10 -5 5 units box +create_box 1 tdpd +create_atoms 1 random 16000 276438 NULL +mass 1 1.0 +set atom * cc 1 1.0 +set atom * cc 2 1.0 + +pair_style tdpd 1.0 1.58 9872598 +pair_coeff 1 1 18.75 4.5 0.41 1.58 1.58 1.0 1.0E-5 2.0 3.0 1.0E-5 2.0 + +compute mythermo all temp +thermo 50 +thermo_modify temp mythermo +thermo_modify flush yes + +velocity all create 1.0 432982 loop local dist gaussian + +fix mvv all mvv/tdpd 0.5 +fix upper1 all tdpd/source 1 cuboid 0.0 5.0 0.0 20.0 10.0 10.0 0.01 +fix lower1 all tdpd/source 1 cuboid 0.0 -5.0 0.0 20.0 10.0 10.0 -0.01 +fix upper2 all tdpd/source 2 cuboid 0.0 5.0 0.0 20.0 10.0 10.0 -0.01 +fix lower2 all tdpd/source 2 cuboid 0.0 -5.0 0.0 20.0 10.0 10.0 0.01 + +timestep 0.01 +run 500 +reset_timestep 0 + +compute cc1 all tdpd/cc/atom 1 +compute cc2 all tdpd/cc/atom 2 +compute bin all chunk/atom bin/1d y 0.0 1.0 +fix stat all ave/chunk 1 100 100 bin c_cc1 c_cc2 norm sample file cc.profile + +run 100 diff --git a/examples/USER/meso/tdpd/log.16Aug17.tdpd.g++.1 b/examples/USER/meso/tdpd/log.16Aug17.tdpd.g++.1 new file mode 100644 index 0000000000..21b618148c --- /dev/null +++ b/examples/USER/meso/tdpd/log.16Aug17.tdpd.g++.1 @@ -0,0 +1,146 @@ +LAMMPS (11 Aug 2017) +######################################################################## +### Pure diffusion with a reaction source term analog of a periodic ### +### Poiseuille flow problem using transport DPD (tDPD) simulation ### +### ### +### Created : Zhen Li (zhen_li@brown.edu) ### +### Division of Applied Mathematics, Brown University. ### +### ### +### tDPD system setup follows Fig.1 in the publication: ### +### Z. Li, A. Yazdani, A. Tartakovsky and G.E. Karniadakis. ### +### "Transport dissipative particle dynamics model for mesoscopic ### +### advection-diffusion-reaction problems. J. Chem. Phys., ### +### 2015, 143: 014101. DOI: 10.1063/1.4923254 ### +######################################################################## +units lj +dimension 3 +boundary p p p +neighbor 0.2 bin +neigh_modify every 1 delay 0 check yes + +atom_style tdpd 2 + +region tdpd block -10 10 -10 10 -5 5 units box +create_box 1 tdpd +Created orthogonal box = (-10 -10 -5) to (10 10 5) + 1 by 1 by 1 MPI processor grid +create_atoms 1 random 16000 276438 NULL +Created 16000 atoms +mass 1 1.0 +set atom * cc 1 1.0 + 16000 settings made for cc index 1 +set atom * cc 2 1.0 + 16000 settings made for cc index 2 + +pair_style tdpd 1.0 1.58 9872598 +pair_coeff 1 1 18.75 4.5 0.41 1.58 1.58 1.0 1.0E-5 2.0 3.0 1.0E-5 2.0 + +compute mythermo all temp +thermo 50 +thermo_modify temp mythermo +thermo_modify flush yes + +velocity all create 1.0 432982 loop local dist gaussian + +fix mvv all mvv/tdpd 0.5 +fix upper1 all tdpd/source 1 cuboid 0.0 5.0 0.0 20.0 10.0 10.0 0.01 +fix lower1 all tdpd/source 1 cuboid 0.0 -5.0 0.0 20.0 10.0 10.0 -0.01 +fix upper2 all tdpd/source 2 cuboid 0.0 5.0 0.0 20.0 10.0 10.0 -0.01 +fix lower2 all tdpd/source 2 cuboid 0.0 -5.0 0.0 20.0 10.0 10.0 0.01 + +timestep 0.01 +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 = 1.78 + ghost atom cutoff = 1.78 + binsize = 0.89, bins = 23 23 12 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair tdpd, 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) = 11.3 | 11.3 | 11.3 Mbytes +Step Temp E_pair E_mol TotEng Press + 0 1 48.948932 0 50.448838 202.19166 + 50 0.99837766 43.949877 0 45.447349 195.80936 + 100 0.99846831 43.756995 0 45.254604 198.22348 + 150 1.0026903 43.72408 0 45.228021 196.61676 + 200 1.0063144 43.722388 0 45.231765 194.17954 + 250 1.0032304 43.721864 0 45.226615 197.85829 + 300 0.9932656 43.703526 0 45.193331 196.57406 + 350 1.0002916 43.720498 0 45.220841 193.55346 + 400 0.99475486 43.722965 0 45.215004 196.81546 + 450 1.0011803 43.712447 0 45.214124 200.46118 + 500 1.0009006 43.708984 0 45.210241 197.38953 +Loop time of 96.0326 on 1 procs for 500 steps with 16000 atoms + +Performance: 4498.474 tau/day, 5.207 timesteps/s +99.9% CPU use with 1 MPI tasks x no OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 90.083 | 90.083 | 90.083 | 0.0 | 93.80 +Neigh | 5.049 | 5.049 | 5.049 | 0.0 | 5.26 +Comm | 0.34141 | 0.34141 | 0.34141 | 0.0 | 0.36 +Output | 0.00092816 | 0.00092816 | 0.00092816 | 0.0 | 0.00 +Modify | 0.45991 | 0.45991 | 0.45991 | 0.0 | 0.48 +Other | | 0.09865 | | | 0.10 + +Nlocal: 16000 ave 16000 max 16000 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 14091 ave 14091 max 14091 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 749379 ave 749379 max 749379 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 749379 +Ave neighs/atom = 46.8362 +Neighbor list builds = 183 +Dangerous builds = 0 +reset_timestep 0 + +compute cc1 all tdpd/cc/atom 1 +compute cc2 all tdpd/cc/atom 2 +compute bin all chunk/atom bin/1d y 0.0 1.0 +fix stat all ave/chunk 1 100 100 bin c_cc1 c_cc2 norm sample file cc.profile + +run 100 +Per MPI rank memory allocation (min/avg/max) = 11.8 | 11.8 | 11.8 Mbytes +Step Temp E_pair E_mol TotEng Press + 0 1.0009006 43.708984 0 45.210241 199.3205 + 50 1.0007276 43.704844 0 45.205842 197.77053 + 100 1.0039032 43.714201 0 45.219961 197.31118 +Loop time of 19.0326 on 1 procs for 100 steps with 16000 atoms + +Performance: 4539.577 tau/day, 5.254 timesteps/s +99.9% CPU use with 1 MPI tasks x no OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 17.842 | 17.842 | 17.842 | 0.0 | 93.74 +Neigh | 0.98674 | 0.98674 | 0.98674 | 0.0 | 5.18 +Comm | 0.066013 | 0.066013 | 0.066013 | 0.0 | 0.35 +Output | 0.00016284 | 0.00016284 | 0.00016284 | 0.0 | 0.00 +Modify | 0.11795 | 0.11795 | 0.11795 | 0.0 | 0.62 +Other | | 0.02012 | | | 0.11 + +Nlocal: 16000 ave 16000 max 16000 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 14126 ave 14126 max 14126 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 748927 ave 748927 max 748927 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 748927 +Ave neighs/atom = 46.8079 +Neighbor list builds = 37 +Dangerous builds = 0 + +Please see the log.cite file for references relevant to this simulation + +Total wall time: 0:01:55 diff --git a/examples/USER/meso/tdpd/log.16Aug17.tdpd.g++.4 b/examples/USER/meso/tdpd/log.16Aug17.tdpd.g++.4 new file mode 100644 index 0000000000..6cd99168f4 --- /dev/null +++ b/examples/USER/meso/tdpd/log.16Aug17.tdpd.g++.4 @@ -0,0 +1,146 @@ +LAMMPS (11 Aug 2017) +######################################################################## +### Pure diffusion with a reaction source term analog of a periodic ### +### Poiseuille flow problem using transport DPD (tDPD) simulation ### +### ### +### Created : Zhen Li (zhen_li@brown.edu) ### +### Division of Applied Mathematics, Brown University. ### +### ### +### tDPD system setup follows Fig.1 in the publication: ### +### Z. Li, A. Yazdani, A. Tartakovsky and G.E. Karniadakis. ### +### "Transport dissipative particle dynamics model for mesoscopic ### +### advection-diffusion-reaction problems. J. Chem. Phys., ### +### 2015, 143: 014101. DOI: 10.1063/1.4923254 ### +######################################################################## +units lj +dimension 3 +boundary p p p +neighbor 0.2 bin +neigh_modify every 1 delay 0 check yes + +atom_style tdpd 2 + +region tdpd block -10 10 -10 10 -5 5 units box +create_box 1 tdpd +Created orthogonal box = (-10 -10 -5) to (10 10 5) + 2 by 2 by 1 MPI processor grid +create_atoms 1 random 16000 276438 NULL +Created 16000 atoms +mass 1 1.0 +set atom * cc 1 1.0 + 16000 settings made for cc index 1 +set atom * cc 2 1.0 + 16000 settings made for cc index 2 + +pair_style tdpd 1.0 1.58 9872598 +pair_coeff 1 1 18.75 4.5 0.41 1.58 1.58 1.0 1.0E-5 2.0 3.0 1.0E-5 2.0 + +compute mythermo all temp +thermo 50 +thermo_modify temp mythermo +thermo_modify flush yes + +velocity all create 1.0 432982 loop local dist gaussian + +fix mvv all mvv/tdpd 0.5 +fix upper1 all tdpd/source 1 cuboid 0.0 5.0 0.0 20.0 10.0 10.0 0.01 +fix lower1 all tdpd/source 1 cuboid 0.0 -5.0 0.0 20.0 10.0 10.0 -0.01 +fix upper2 all tdpd/source 2 cuboid 0.0 5.0 0.0 20.0 10.0 10.0 -0.01 +fix lower2 all tdpd/source 2 cuboid 0.0 -5.0 0.0 20.0 10.0 10.0 0.01 + +timestep 0.01 +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 = 1.78 + ghost atom cutoff = 1.78 + binsize = 0.89, bins = 23 23 12 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair tdpd, 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) = 4.814 | 4.823 | 4.829 Mbytes +Step Temp E_pair E_mol TotEng Press + 0 1 48.948932 0 50.448838 199.65978 + 50 1.0153476 43.948796 0 45.471722 198.3346 + 100 1.0064284 43.754875 0 45.264424 197.5308 + 150 0.99609985 43.726751 0 45.220807 197.50623 + 200 1.0016604 43.720283 0 45.22268 197.81129 + 250 1.0054979 43.718568 0 45.22672 195.79405 + 300 0.9997618 43.716617 0 45.216166 197.84788 + 350 0.99170101 43.72093 0 45.208389 196.07711 + 400 1.0043692 43.71648 0 45.22294 199.55247 + 450 1.0086263 43.709988 0 45.222833 198.20516 + 500 1.0029076 43.717879 0 45.222146 197.26281 +Loop time of 24.5533 on 4 procs for 500 steps with 16000 atoms + +Performance: 17594.412 tau/day, 20.364 timesteps/s +99.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 | 22.236 | 22.418 | 22.736 | 4.0 | 91.30 +Neigh | 1.2759 | 1.2883 | 1.3077 | 1.1 | 5.25 +Comm | 0.35749 | 0.69526 | 0.88462 | 24.1 | 2.83 +Output | 0.00043321 | 0.00050318 | 0.00070691 | 0.0 | 0.00 +Modify | 0.11555 | 0.11648 | 0.11888 | 0.4 | 0.47 +Other | | 0.03473 | | | 0.14 + +Nlocal: 4000 ave 4012 max 3982 min +Histogram: 1 0 0 0 0 1 0 0 0 2 +Nghost: 5986.25 ave 6016 max 5956 min +Histogram: 1 0 0 0 1 0 1 0 0 1 +Neighs: 187309 ave 188264 max 186087 min +Histogram: 1 0 0 0 1 0 0 1 0 1 + +Total # of neighbors = 749235 +Ave neighs/atom = 46.8272 +Neighbor list builds = 180 +Dangerous builds = 0 +reset_timestep 0 + +compute cc1 all tdpd/cc/atom 1 +compute cc2 all tdpd/cc/atom 2 +compute bin all chunk/atom bin/1d y 0.0 1.0 +fix stat all ave/chunk 1 100 100 bin c_cc1 c_cc2 norm sample file cc.profile + +run 100 +Per MPI rank memory allocation (min/avg/max) = 5.065 | 5.074 | 5.082 Mbytes +Step Temp E_pair E_mol TotEng Press + 0 1.0029076 43.717879 0 45.222146 198.45789 + 50 1.0077982 43.713264 0 45.224867 196.56183 + 100 1.0036823 43.708022 0 45.213451 196.00815 +Loop time of 4.79577 on 4 procs for 100 steps with 16000 atoms + +Performance: 18015.870 tau/day, 20.852 timesteps/s +99.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 | 4.3481 | 4.39 | 4.4398 | 1.7 | 91.54 +Neigh | 0.25477 | 0.25675 | 0.25963 | 0.4 | 5.35 +Comm | 0.059327 | 0.11194 | 0.15608 | 11.0 | 2.33 +Output | 0.00011206 | 0.00011748 | 0.00011992 | 0.0 | 0.00 +Modify | 0.030417 | 0.030622 | 0.030739 | 0.1 | 0.64 +Other | | 0.006301 | | | 0.13 + +Nlocal: 4000 ave 4010 max 3987 min +Histogram: 1 0 0 0 0 1 1 0 0 1 +Nghost: 5985.25 ave 6025 max 5959 min +Histogram: 2 0 0 0 0 1 0 0 0 1 +Neighs: 187304 ave 188092 max 186449 min +Histogram: 1 0 0 0 0 2 0 0 0 1 + +Total # of neighbors = 749216 +Ave neighs/atom = 46.826 +Neighbor list builds = 38 +Dangerous builds = 0 + +Please see the log.cite file for references relevant to this simulation + +Total wall time: 0:00:29 diff --git a/src/Makefile b/src/Makefile index 3b67d2284f..91d65a11c5 100644 --- a/src/Makefile +++ b/src/Makefile @@ -59,7 +59,8 @@ PACKAGE = asphere body class2 colloid compress coreshell dipole gpu \ PACKUSER = user-atc user-awpmd user-cgdna user-cgsdk user-colvars \ user-diffraction user-dpd user-drude user-eff user-fep user-h5md \ - user-intel user-lb user-manifold user-meamc user-mgpt user-misc user-molfile \ + user-intel user-lb user-manifold user-meamc user-meso \ + user-mgpt user-misc user-molfile \ user-netcdf user-omp user-phonon user-qmmm user-qtb \ user-quip user-reaxc user-smd user-smtbq user-sph user-tally \ user-vtk diff --git a/src/USER-MESO/README b/src/USER-MESO/README new file mode 100644 index 0000000000..0119fdb9f8 --- /dev/null +++ b/src/USER-MESO/README @@ -0,0 +1,50 @@ +This package implements three extensions of the dissipative particle +dynamics (DPD) method, i.e., energy-conserving DPD (eDPD) that can +model non-isothermal processes, many-body DPD (mDPD) for simulating +vapor-liquid coexistence, and transport DPD (tDPD) for modeling +advection-diffuion-reaction systems. The equations of motion of these +DPD extensions are integrated through the modified velocity-Verlet +(MVV) algorithm. + +Currently, the package has the following features: + +* Three new atom styles (eDPD, mDPD, tDPD) for tracking the particles + with internal temperature, local mass density, and chemical + concentration. + +* Three set commands (edpd/temp, edpd/cv, cc) for setting internal + temperature (edpd/temp) and heat capacity (edpd/cv) for eDPD + particles and for setting chemical concentration (cc) for tDPD + particles. + +* Two compute commands (edpd/temp/atom, tdpd/cc/atom) for accessing + the internal temperature of eDPD particles and the chemical + concentration of tDPD particles. + +* Three fix commands (mvv/dpd, mvv/edpd, mvv/tdpd) for integrating the + shochastic ODEs using the modified velocity-Verlet (MVV) algorithm. + +* Two fix commands (edpd/source, tdpd/source) for adding additional + heat source/sink or chemical concentration source/sink to eDPD and + tDPD particles. + +* One pair style (edpd) for modeling a eDPD fluid. + +* Two pair styles (mdpd/rhosum, mdpd) for modeling a mDPD fluid. + +* One pair style (tdpd) for modeling a tDPD fluid. + +See the doc pages for "atom style edpd", "atom style mdpd", "atom +style tdpd", "set edpd/temp", "set edpd/cv", "set tdpd/cc", "compute +edpd/temp/atom", "compute tdpd/cc/atom", "fix mvv/dpd", "fix +mvv/edpd", "fix mvv/tdpd", "fix edpd/source", "fix tdpd/source", "pair +edpd", "pair mdpd/rhosum", "pair mdpd", "pair tdpd" commands to get +started. At the bottom of the doc pages are many links to additional +documentation contained in the doc/USER/meso directory. + +There are example scripts for using this package in +examples/USER/meso. + +The person who created this package is Zhen Li (zhen_li at brown.edu) +at Division of Applied Mathematics, Brown University, USA. Contact him +directly if you have questions. diff --git a/src/USER-MESO/atom_vec_edpd.cpp b/src/USER-MESO/atom_vec_edpd.cpp new file mode 100644 index 0000000000..635743cc9e --- /dev/null +++ b/src/USER-MESO/atom_vec_edpd.cpp @@ -0,0 +1,844 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ +#include +#include +#include "atom_vec_edpd.h" +#include "atom.h" +#include "comm.h" +#include "domain.h" +#include "modify.h" +#include "fix.h" +#include "update.h" +#include "memory.h" +#include "error.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +AtomVecEDPD::AtomVecEDPD(LAMMPS *lmp) : AtomVec(lmp) +{ + if(strcmp(update->unit_style,"lj") != 0) + error->all(FLERR,"Atom style edpd requires lj units"); + + molecular = 0; + mass_type = 1; + forceclearflag = 1; + + comm_x_only = comm_f_only = 0; + comm->ghost_velocity = 1; + + size_forward = 3 + 5; // edpd_temp + vest[4] + size_reverse = 3 + 1; // edpd_flux + size_border = 6 + 6; // edpd_temp + edpd_cv + vest[4] + size_velocity = 3; + size_data_atom = 5 + 2; // we read id + type + edpd_temp + edpd_cv + xyz[3] + size_data_vel = 4; + xcol_data = 5; + + atom->edpd_flag = 1; + atom->vest_flag = 1; +} + +/* ---------------------------------------------------------------------- + grow atom arrays + n = 0 grows arrays by a chunk + n > 0 allocates arrays to size n +------------------------------------------------------------------------- */ + +void AtomVecEDPD::grow(int n) +{ + if (n == 0) grow_nmax(); + else nmax = n; + atom->nmax = nmax; + if (nmax < 0 || nmax > MAXSMALLINT) + error->one(FLERR,"Per-processor system is too big"); + + tag = memory->grow(atom->tag,nmax,"atom:tag"); + type = memory->grow(atom->type,nmax,"atom:type"); + mask = memory->grow(atom->mask,nmax,"atom:mask"); + image = memory->grow(atom->image,nmax,"atom:image"); + x = memory->grow(atom->x,nmax,3,"atom:x"); + v = memory->grow(atom->v,nmax,3,"atom:v"); + f = memory->grow(atom->f,nmax*comm->nthreads,3,"atom:f"); + edpd_cv= memory->grow(atom->edpd_cv, nmax, "atom:edpd_cv"); + edpd_temp = memory->grow(atom->edpd_temp, nmax, "atom:edpd_temp"); + edpd_flux = memory->grow(atom->edpd_flux, nmax*comm->nthreads,"atom:edpd_flux"); + vest = memory->grow(atom->vest, nmax, 4, "atom:vest"); + + if (atom->nextra_grow) + for (int iextra = 0; iextra < atom->nextra_grow; iextra++) + modify->fix[atom->extra_grow[iextra]]->grow_arrays(nmax); +} + +/* ---------------------------------------------------------------------- + reset local array ptrs +------------------------------------------------------------------------- */ + +void AtomVecEDPD::grow_reset() +{ + tag = atom->tag; type = atom->type; + mask = atom->mask; image = atom->image; + x = atom->x; v = atom->v; f = atom->f; + edpd_cv = atom->cv; edpd_temp = atom->edpd_temp; edpd_flux = atom->edpd_flux; + vest = atom->vest; +} + +/* ---------------------------------------------------------------------- + copy atom I info to atom J +------------------------------------------------------------------------- */ + +void AtomVecEDPD::copy(int i, int j, int delflag) +{ + tag[j] = tag[i]; + type[j] = type[i]; + mask[j] = mask[i]; + image[j] = image[i]; + x[j][0] = x[i][0]; + x[j][1] = x[i][1]; + x[j][2] = x[i][2]; + v[j][0] = v[i][0]; + v[j][1] = v[i][1]; + v[j][2] = v[i][2]; + + edpd_temp[j] = edpd_temp[i]; + edpd_flux[j] = edpd_flux[i]; + edpd_cv[j] = edpd_cv[i]; + vest[j][0] = vest[i][0]; + vest[j][1] = vest[i][1]; + vest[j][2] = vest[i][2]; + vest[j][3] = vest[i][3]; + + if (atom->nextra_grow) + for (int iextra = 0; iextra < atom->nextra_grow; iextra++) + modify->fix[atom->extra_grow[iextra]]->copy_arrays(i,j,delflag); +} + + +void AtomVecEDPD::force_clear(int n, size_t nbytes) +{ + memset(&edpd_flux[n],0,nbytes); +} + + +/* ---------------------------------------------------------------------- */ + +int AtomVecEDPD::pack_comm(int n, int *list, double *buf, + int pbc_flag, int *pbc) +{ + int i,j,k,m; + double dx,dy,dz; + + m = 0; + if (pbc_flag == 0) { + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = x[j][0]; + buf[m++] = x[j][1]; + buf[m++] = x[j][2]; + buf[m++] = edpd_temp[j]; + buf[m++] = vest[j][0]; + buf[m++] = vest[j][1]; + buf[m++] = vest[j][2]; + buf[m++] = vest[j][3]; + } + } else { + if (domain->triclinic == 0) { + dx = pbc[0]*domain->xprd; + dy = pbc[1]*domain->yprd; + dz = pbc[2]*domain->zprd; + } else { + dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz; + dy = pbc[1]*domain->yprd + pbc[3]*domain->yz; + dz = pbc[2]*domain->zprd; + } + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = x[j][0] + dx; + buf[m++] = x[j][1] + dy; + buf[m++] = x[j][2] + dz; + buf[m++] = edpd_temp[j]; + buf[m++] = vest[j][0]; + buf[m++] = vest[j][1]; + buf[m++] = vest[j][2]; + buf[m++] = vest[j][3]; + } + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecEDPD::pack_comm_vel(int n, int *list, double *buf, + int pbc_flag, int *pbc) +{ + int i,j,k,m; + double dx,dy,dz,dvx,dvy,dvz; + + m = 0; + if (pbc_flag == 0) { + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = x[j][0]; + buf[m++] = x[j][1]; + buf[m++] = x[j][2]; + buf[m++] = v[j][0]; + buf[m++] = v[j][1]; + buf[m++] = v[j][2]; + buf[m++] = edpd_temp[j]; + buf[m++] = vest[j][0]; + buf[m++] = vest[j][1]; + buf[m++] = vest[j][2]; + buf[m++] = vest[j][3]; + } + } else { + if (domain->triclinic == 0) { + dx = pbc[0]*domain->xprd; + dy = pbc[1]*domain->yprd; + dz = pbc[2]*domain->zprd; + } else { + dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz; + dy = pbc[1]*domain->yprd + pbc[3]*domain->yz; + dz = pbc[2]*domain->zprd; + } + if (!deform_vremap) { + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = x[j][0] + dx; + buf[m++] = x[j][1] + dy; + buf[m++] = x[j][2] + dz; + buf[m++] = v[j][0]; + buf[m++] = v[j][1]; + buf[m++] = v[j][2]; + buf[m++] = edpd_temp[j]; + buf[m++] = vest[j][0]; + buf[m++] = vest[j][1]; + buf[m++] = vest[j][2]; + buf[m++] = vest[j][3]; + } + } else { + dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4]; + dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3]; + dvz = pbc[2]*h_rate[2]; + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = x[j][0] + dx; + buf[m++] = x[j][1] + dy; + buf[m++] = x[j][2] + dz; + if (mask[i] & deform_groupbit) { + buf[m++] = v[j][0] + dvx; + buf[m++] = v[j][1] + dvy; + buf[m++] = v[j][2] + dvz; + } else { + buf[m++] = v[j][0]; + buf[m++] = v[j][1]; + buf[m++] = v[j][2]; + } + buf[m++] = edpd_temp[j]; + buf[m++] = vest[j][0]; + buf[m++] = vest[j][1]; + buf[m++] = vest[j][2]; + buf[m++] = vest[j][3]; + } + } + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecEDPD::unpack_comm(int n, int first, double *buf) +{ + int i,m,last; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + x[i][0] = buf[m++]; + x[i][1] = buf[m++]; + x[i][2] = buf[m++]; + edpd_temp[i] = buf[m++]; + vest[i][0] = buf[m++]; + vest[i][1] = buf[m++]; + vest[i][2] = buf[m++]; + vest[i][3] = buf[m++]; + } +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecEDPD::unpack_comm_vel(int n, int first, double *buf) +{ + int i,m,last; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + x[i][0] = buf[m++]; + x[i][1] = buf[m++]; + x[i][2] = buf[m++]; + v[i][0] = buf[m++]; + v[i][1] = buf[m++]; + v[i][2] = buf[m++]; + edpd_temp[i] = buf[m++]; + vest[i][0] = buf[m++]; + vest[i][1] = buf[m++]; + vest[i][2] = buf[m++]; + vest[i][3] = buf[m++]; + } +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecEDPD::pack_reverse(int n, int first, double *buf) +{ + int i,m,last; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + buf[m++] = f[i][0]; + buf[m++] = f[i][1]; + buf[m++] = f[i][2]; + buf[m++] = edpd_flux[i]; + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecEDPD::unpack_reverse(int n, int *list, double *buf) +{ + int i,j,m; + + m = 0; + for (i = 0; i < n; i++) { + j = list[i]; + f[j][0] += buf[m++]; + f[j][1] += buf[m++]; + f[j][2] += buf[m++]; + edpd_flux[j] += buf[m++]; + } +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecEDPD::pack_border(int n, int *list, double *buf, + int pbc_flag, int *pbc) +{ + int i,j,m; + double dx,dy,dz; + + m = 0; + if (pbc_flag == 0) { + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = x[j][0]; + buf[m++] = x[j][1]; + buf[m++] = x[j][2]; + buf[m++] = ubuf(tag[j]).d; + buf[m++] = ubuf(type[j]).d; + buf[m++] = ubuf(mask[j]).d; + buf[m++] = edpd_temp[j]; + buf[m++] = edpd_cv[j]; + buf[m++] = vest[j][0]; + buf[m++] = vest[j][1]; + buf[m++] = vest[j][2]; + buf[m++] = vest[j][3]; + } + } else { + if (domain->triclinic == 0) { + dx = pbc[0]*domain->xprd; + dy = pbc[1]*domain->yprd; + dz = pbc[2]*domain->zprd; + } else { + dx = pbc[0]; + dy = pbc[1]; + dz = pbc[2]; + } + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = x[j][0] + dx; + buf[m++] = x[j][1] + dy; + buf[m++] = x[j][2] + dz; + buf[m++] = ubuf(tag[j]).d; + buf[m++] = ubuf(type[j]).d; + buf[m++] = ubuf(mask[j]).d; + buf[m++] = edpd_temp[j]; + buf[m++] = edpd_cv[j]; + buf[m++] = vest[j][0]; + buf[m++] = vest[j][1]; + buf[m++] = vest[j][2]; + buf[m++] = vest[j][3]; + } + } + + if (atom->nextra_border) + for (int iextra = 0; iextra < atom->nextra_border; iextra++) + m += modify->fix[atom->extra_border[iextra]]->pack_border(n,list,&buf[m]); + + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecEDPD::pack_border_vel(int n, int *list, double *buf, + int pbc_flag, int *pbc) +{ + int i,j,m; + double dx,dy,dz,dvx,dvy,dvz; + + m = 0; + if (pbc_flag == 0) { + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = x[j][0]; + buf[m++] = x[j][1]; + buf[m++] = x[j][2]; + buf[m++] = ubuf(tag[j]).d; + buf[m++] = ubuf(type[j]).d; + buf[m++] = ubuf(mask[j]).d; + buf[m++] = edpd_temp[j]; + buf[m++] = edpd_cv[j]; + buf[m++] = v[j][0]; + buf[m++] = v[j][1]; + buf[m++] = v[j][2]; + buf[m++] = vest[j][0]; + buf[m++] = vest[j][1]; + buf[m++] = vest[j][2]; + buf[m++] = vest[j][3]; + } + } else { + if (domain->triclinic == 0) { + dx = pbc[0]*domain->xprd; + dy = pbc[1]*domain->yprd; + dz = pbc[2]*domain->zprd; + } else { + dx = pbc[0]; + dy = pbc[1]; + dz = pbc[2]; + } + if (!deform_vremap) { + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = x[j][0] + dx; + buf[m++] = x[j][1] + dy; + buf[m++] = x[j][2] + dz; + buf[m++] = ubuf(tag[j]).d; + buf[m++] = ubuf(type[j]).d; + buf[m++] = ubuf(mask[j]).d; + buf[m++] = edpd_temp[j]; + buf[m++] = edpd_cv[j]; + buf[m++] = v[j][0]; + buf[m++] = v[j][1]; + buf[m++] = v[j][2]; + buf[m++] = vest[j][0]; + buf[m++] = vest[j][1]; + buf[m++] = vest[j][2]; + buf[m++] = vest[j][3]; + } + } else { + dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4]; + dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3]; + dvz = pbc[2]*h_rate[2]; + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = x[j][0] + dx; + buf[m++] = x[j][1] + dy; + buf[m++] = x[j][2] + dz; + buf[m++] = ubuf(tag[j]).d; + buf[m++] = ubuf(type[j]).d; + buf[m++] = ubuf(mask[j]).d; + buf[m++] = edpd_temp[j]; + buf[m++] = edpd_cv[j]; + if (mask[i] & deform_groupbit) { + buf[m++] = v[j][0] + dvx; + buf[m++] = v[j][1] + dvy; + buf[m++] = v[j][2] + dvz; + buf[m++] = vest[j][0] + dvx; + buf[m++] = vest[j][1] + dvy; + buf[m++] = vest[j][2] + dvz; + buf[m++] = vest[j][3]; + } else { + buf[m++] = v[j][0]; + buf[m++] = v[j][1]; + buf[m++] = v[j][2]; + buf[m++] = vest[j][0]; + buf[m++] = vest[j][1]; + buf[m++] = vest[j][2]; + buf[m++] = vest[j][3]; + } + } + } + } + + if (atom->nextra_border) + for (int iextra = 0; iextra < atom->nextra_border; iextra++) + m += modify->fix[atom->extra_border[iextra]]->pack_border(n,list,&buf[m]); + + return m; +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecEDPD::unpack_border(int n, int first, double *buf) +{ + int i,m,last; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + if (i == nmax) grow(0); + x[i][0] = buf[m++]; + x[i][1] = buf[m++]; + x[i][2] = buf[m++]; + tag[i] = (tagint) ubuf(buf[m++]).i; + type[i] = (int) ubuf(buf[m++]).i; + mask[i] = (int) ubuf(buf[m++]).i; + edpd_temp[i] = buf[m++]; + edpd_cv[i] = buf[m++]; + vest[i][0] = buf[m++]; + vest[i][1] = buf[m++]; + vest[i][2] = buf[m++]; + vest[i][3] = buf[m++]; + } + + if (atom->nextra_border) + for (int iextra = 0; iextra < atom->nextra_border; iextra++) + m += modify->fix[atom->extra_border[iextra]]-> + unpack_border(n,first,&buf[m]); +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecEDPD::unpack_border_vel(int n, int first, double *buf) +{ + int i,m,last; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + if (i == nmax) grow(0); + x[i][0] = buf[m++]; + x[i][1] = buf[m++]; + x[i][2] = buf[m++]; + tag[i] = (tagint) ubuf(buf[m++]).i; + type[i] = (int) ubuf(buf[m++]).i; + mask[i] = (int) ubuf(buf[m++]).i; + edpd_temp[i] = buf[m++]; + edpd_cv[i] = buf[m++]; + v[i][0] = buf[m++]; + v[i][1] = buf[m++]; + v[i][2] = buf[m++]; + vest[i][0] = buf[m++]; + vest[i][1] = buf[m++]; + vest[i][2] = buf[m++]; + vest[i][3] = buf[m++]; + } + + if (atom->nextra_border) + for (int iextra = 0; iextra < atom->nextra_border; iextra++) + m += modify->fix[atom->extra_border[iextra]]-> + unpack_border(n,first,&buf[m]); +} + +/* ---------------------------------------------------------------------- + pack data for atom I for sending to another proc + xyz must be 1st 3 values, so comm::exchange() can test on them +------------------------------------------------------------------------- */ + +int AtomVecEDPD::pack_exchange(int i, double *buf) +{ + int m = 1; + buf[m++] = x[i][0]; + buf[m++] = x[i][1]; + buf[m++] = x[i][2]; + buf[m++] = v[i][0]; + buf[m++] = v[i][1]; + buf[m++] = v[i][2]; + buf[m++] = ubuf(tag[i]).d; + buf[m++] = ubuf(type[i]).d; + buf[m++] = ubuf(mask[i]).d; + buf[m++] = ubuf(image[i]).d; + buf[m++] = edpd_temp[i]; + buf[m++] = edpd_cv[i]; + buf[m++] = vest[i][0]; + buf[m++] = vest[i][1]; + buf[m++] = vest[i][2]; + buf[m++] = vest[i][3]; + + if (atom->nextra_grow) + for (int iextra = 0; iextra < atom->nextra_grow; iextra++) + m += modify->fix[atom->extra_grow[iextra]]->pack_exchange(i,&buf[m]); + + buf[0] = m; + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecEDPD::unpack_exchange(double *buf) +{ + int nlocal = atom->nlocal; + if (nlocal == nmax) grow(0); + + int m = 1; + x[nlocal][0] = buf[m++]; + x[nlocal][1] = buf[m++]; + x[nlocal][2] = buf[m++]; + v[nlocal][0] = buf[m++]; + v[nlocal][1] = buf[m++]; + v[nlocal][2] = buf[m++]; + tag[nlocal] = (tagint) ubuf(buf[m++]).i; + type[nlocal] = (int) ubuf(buf[m++]).i; + mask[nlocal] = (int) ubuf(buf[m++]).i; + image[nlocal] = (imageint) ubuf(buf[m++]).i; + edpd_temp[nlocal] = buf[m++]; + edpd_cv[nlocal] = buf[m++]; + vest[nlocal][0] = buf[m++]; + vest[nlocal][1] = buf[m++]; + vest[nlocal][2] = buf[m++]; + vest[nlocal][3] = buf[m++]; + + if (atom->nextra_grow) + for (int iextra = 0; iextra < atom->nextra_grow; iextra++) + m += modify->fix[atom->extra_grow[iextra]]-> + unpack_exchange(nlocal,&buf[m]); + + atom->nlocal++; + return m; +} + +/* ---------------------------------------------------------------------- + size of restart data for all atoms owned by this proc + include extra data stored by fixes +------------------------------------------------------------------------- */ + +int AtomVecEDPD::size_restart() +{ + int i; + + int nlocal = atom->nlocal; + int n = (11 + 6) * nlocal; // 11 + edpd_temp + edpd_cv + vest[4] + + if (atom->nextra_restart) + for (int iextra = 0; iextra < atom->nextra_restart; iextra++) + for (i = 0; i < nlocal; i++) + n += modify->fix[atom->extra_restart[iextra]]->size_restart(i); + + return n; +} + +/* ---------------------------------------------------------------------- + pack atom I's data for restart file including extra quantities + xyz must be 1st 3 values, so that read_restart can test on them + molecular types may be negative, but write as positive +------------------------------------------------------------------------- */ + +int AtomVecEDPD::pack_restart(int i, double *buf) +{ + int m = 1; + buf[m++] = x[i][0]; + buf[m++] = x[i][1]; + buf[m++] = x[i][2]; + buf[m++] = ubuf(tag[i]).d; + buf[m++] = ubuf(type[i]).d; + buf[m++] = ubuf(mask[i]).d; + buf[m++] = ubuf(image[i]).d; + buf[m++] = v[i][0]; + buf[m++] = v[i][1]; + buf[m++] = v[i][2]; + buf[m++] = edpd_temp[i]; + buf[m++] = edpd_cv[i]; + buf[m++] = vest[i][0]; + buf[m++] = vest[i][1]; + buf[m++] = vest[i][2]; + buf[m++] = vest[i][3]; + + if (atom->nextra_restart) + for (int iextra = 0; iextra < atom->nextra_restart; iextra++) + m += modify->fix[atom->extra_restart[iextra]]->pack_restart(i,&buf[m]); + + buf[0] = m; + return m; +} + +/* ---------------------------------------------------------------------- + unpack data for one atom from restart file including extra quantities +------------------------------------------------------------------------- */ + +int AtomVecEDPD::unpack_restart(double *buf) +{ + int nlocal = atom->nlocal; + if (nlocal == nmax) { + grow(0); + if (atom->nextra_store) + memory->grow(atom->extra,nmax,atom->nextra_store,"atom:extra"); + } + + int m = 1; + x[nlocal][0] = buf[m++]; + x[nlocal][1] = buf[m++]; + x[nlocal][2] = buf[m++]; + tag[nlocal] = (tagint) ubuf(buf[m++]).i; + type[nlocal] = (int) ubuf(buf[m++]).i; + mask[nlocal] = (int) ubuf(buf[m++]).i; + image[nlocal] = (imageint) ubuf(buf[m++]).i; + v[nlocal][0] = buf[m++]; + v[nlocal][1] = buf[m++]; + v[nlocal][2] = buf[m++]; + + edpd_temp[nlocal] = buf[m++]; + edpd_cv[nlocal]= buf[m++]; + vest[nlocal][0] = buf[m++]; + vest[nlocal][1] = buf[m++]; + vest[nlocal][2] = buf[m++]; + vest[nlocal][3] = buf[m++]; + + double **extra = atom->extra; + if (atom->nextra_store) { + int size = static_cast (buf[0]) - m; + for (int i = 0; i < size; i++) extra[nlocal][i] = buf[m++]; + } + + atom->nlocal++; + return m; +} + +/* ---------------------------------------------------------------------- + create one atom of itype at coord + set other values to defaults +------------------------------------------------------------------------- */ + +void AtomVecEDPD::create_atom(int itype, double *coord) +{ + int nlocal = atom->nlocal; + if (nlocal == nmax) grow(0); + + tag[nlocal] = 0; + type[nlocal] = itype; + x[nlocal][0] = coord[0]; + x[nlocal][1] = coord[1]; + x[nlocal][2] = coord[2]; + mask[nlocal] = 1; + image[nlocal] = ((imageint) IMGMAX << IMG2BITS) | + ((imageint) IMGMAX << IMGBITS) | IMGMAX; + v[nlocal][0] = 0.0; + v[nlocal][1] = 0.0; + v[nlocal][2] = 0.0; + + edpd_temp[nlocal] = 1.0; + edpd_flux[nlocal] = 0.0; + edpd_cv[nlocal]= 1.0E5; + vest[nlocal][0] = 0.0; + vest[nlocal][1] = 0.0; + vest[nlocal][2] = 0.0; + vest[nlocal][3] = edpd_temp[nlocal]; + + atom->nlocal++; +} + +/* ---------------------------------------------------------------------- + unpack one line from Atoms section of data file + initialize other atom quantities +------------------------------------------------------------------------- */ + +void AtomVecEDPD::data_atom(double *coord, imageint imagetmp, char **values) +{ + int nlocal = atom->nlocal; + if (nlocal == nmax) grow(0); + + tag[nlocal] = ATOTAGINT(values[0]); + type[nlocal] = atoi(values[1]); + if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes) + error->one(FLERR,"Invalid atom type in Atoms section of data file"); + + edpd_temp[nlocal] = atof(values[2]); + edpd_cv[nlocal] = atof(values[3]); + + x[nlocal][0] = coord[0]; + x[nlocal][1] = coord[1]; + x[nlocal][2] = coord[2]; + + image[nlocal] = imagetmp; + + mask[nlocal] = 1; + v[nlocal][0] = 0.0; + v[nlocal][1] = 0.0; + v[nlocal][2] = 0.0; + + vest[nlocal][0] = 0.0; + vest[nlocal][1] = 0.0; + vest[nlocal][2] = 0.0; + vest[nlocal][3] = edpd_temp[nlocal]; + edpd_flux[nlocal] = 0.0; + + atom->nlocal++; +} + +/* ---------------------------------------------------------------------- + pack atom info for data file including 3 image flags +------------------------------------------------------------------------- */ + +void AtomVecEDPD::pack_data(double **buf) +{ + int nlocal = atom->nlocal; + for (int i = 0; i < nlocal; i++) { + buf[i][0] = ubuf(tag[i]).d; + buf[i][1] = ubuf(type[i]).d; + buf[i][2] = edpd_temp[i]; + buf[i][3] = edpd_cv[i]; + buf[i][4] = x[i][0]; + buf[i][5] = x[i][1]; + buf[i][6] = x[i][2]; + buf[i][7] = ubuf((image[i] & IMGMASK) - IMGMAX).d; + buf[i][8] = ubuf((image[i] >> IMGBITS & IMGMASK) - IMGMAX).d; + buf[i][9] = ubuf((image[i] >> IMG2BITS) - IMGMAX).d; + } +} + +/* ---------------------------------------------------------------------- + write atom info to data file including 3 image flags +------------------------------------------------------------------------- */ + +void AtomVecEDPD::write_data(FILE *fp, int n, double **buf) +{ + for (int i = 0; i < n; i++) + fprintf(fp,TAGINT_FORMAT " %d %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e %d %d %d\n", + (tagint) ubuf(buf[i][0]).i,(int) ubuf(buf[i][1]).i, + buf[i][2],buf[i][3],buf[i][4],buf[i][5],buf[i][6], + (int) ubuf(buf[i][7]).i,(int) ubuf(buf[i][8]).i,(int) ubuf(buf[i][9]).i); +} + +/* ---------------------------------------------------------------------- + return # of bytes of allocated memory +------------------------------------------------------------------------- */ + +bigint AtomVecEDPD::memory_usage() +{ + bigint bytes = 0; + + if (atom->memcheck("tag")) bytes += memory->usage(tag,nmax); + if (atom->memcheck("type")) bytes += memory->usage(type,nmax); + if (atom->memcheck("mask")) bytes += memory->usage(mask,nmax); + if (atom->memcheck("image")) bytes += memory->usage(image,nmax); + if (atom->memcheck("x")) bytes += memory->usage(x,nmax,3); + if (atom->memcheck("v")) bytes += memory->usage(v,nmax,3); + if (atom->memcheck("f")) bytes += memory->usage(f,nmax*comm->nthreads,3); + if (atom->memcheck("edpd_temp")) bytes += memory->usage(edpd_temp,nmax); + if (atom->memcheck("edpd_flux")) bytes += memory->usage(edpd_flux,nmax*comm->nthreads); + if (atom->memcheck("edpd_cv")) bytes += memory->usage(edpd_cv,nmax); + if (atom->memcheck("vest")) bytes += memory->usage(vest,nmax,4); + + return bytes; +} diff --git a/src/USER-MESO/atom_vec_edpd.h b/src/USER-MESO/atom_vec_edpd.h new file mode 100644 index 0000000000..36a4cae97b --- /dev/null +++ b/src/USER-MESO/atom_vec_edpd.h @@ -0,0 +1,68 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef ATOM_CLASS + +AtomStyle(edpd,AtomVecEDPD) + +#else + +#ifndef LMP_ATOM_VEC_EDPD_H +#define LMP_ATOM_VEC_EDPD_H + +#include "atom_vec.h" + +namespace LAMMPS_NS { + +class AtomVecEDPD : public AtomVec { + public: + AtomVecEDPD(class LAMMPS *); + virtual ~AtomVecEDPD() {} + void grow(int); + void grow_reset(); + void copy(int, int, int); + void force_clear(int, size_t); + virtual int pack_comm(int, int *, double *, int, int *); + virtual int pack_comm_vel(int, int *, double *, int, int *); + virtual void unpack_comm(int, int, double *); + virtual void unpack_comm_vel(int, int, double *); + int pack_reverse(int, int, double *); + void unpack_reverse(int, int *, double *); + virtual int pack_border(int, int *, double *, int, int *); + virtual int pack_border_vel(int, int *, double *, int, int *); + virtual void unpack_border(int, int, double *); + virtual void unpack_border_vel(int, int, double *); + virtual int pack_exchange(int, double *); + virtual int unpack_exchange(double *); + int size_restart(); + int pack_restart(int, double *); + int unpack_restart(double *); + void create_atom(int, double *); + void data_atom(double *, imageint, char **); + void pack_data(double **); + void write_data(FILE *, int, double **); + bigint memory_usage(); + + protected: + tagint *tag; + int *type,*mask; + imageint *image; + double **x,**v,**f; + double **vest; // store intermediate velocity for using mvv integrator + double *edpd_temp,*edpd_flux,*edpd_cv; // temperature, heat flux, and heat capacity +}; + +} + +#endif +#endif diff --git a/src/USER-MESO/atom_vec_mdpd.cpp b/src/USER-MESO/atom_vec_mdpd.cpp new file mode 100644 index 0000000000..0a4d302c36 --- /dev/null +++ b/src/USER-MESO/atom_vec_mdpd.cpp @@ -0,0 +1,951 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. + ------------------------------------------------------------------------- */ + +#include +#include +#include "atom_vec_mdpd.h" +#include "atom.h" +#include "comm.h" +#include "domain.h" +#include "modify.h" +#include "fix.h" +#include "update.h" +#include "memory.h" +#include "error.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +AtomVecMDPD::AtomVecMDPD(LAMMPS *lmp) : AtomVec(lmp) +{ + if(strcmp(update->unit_style,"lj") != 0) + error->all(FLERR,"Atom style mdpd requires lj units"); + + molecular = 0; + mass_type = 1; + forceclearflag = 1; + + comm_x_only = comm_f_only = 0; + comm->ghost_velocity = 1; + + size_forward = 3 + 4; // 3 + rho + vest[3], that means we may only communicate 4 in hybrid + size_reverse = 3 + 1; // 3 + drho + size_border = 6 + 4; // 6 + rho + vest[3] + size_velocity = 3; + size_data_atom = 5; + size_data_vel = 4; + xcol_data = 3; + + atom->rho_flag = 1; + atom->vest_flag = 1; +} + +/* ---------------------------------------------------------------------- + grow atom arrays + n = 0 grows arrays by a chunk + n > 0 allocates arrays to size n + ------------------------------------------------------------------------- */ + +void AtomVecMDPD::grow(int n) +{ + if (n == 0) grow_nmax(); + else nmax = n; + atom->nmax = nmax; + if (nmax < 0 || nmax > MAXSMALLINT) + error->one(FLERR,"Per-processor system is too big"); + + tag = memory->grow(atom->tag, nmax, "atom:tag"); + type = memory->grow(atom->type, nmax, "atom:type"); + mask = memory->grow(atom->mask, nmax, "atom:mask"); + image = memory->grow(atom->image, nmax, "atom:image"); + x = memory->grow(atom->x, nmax, 3, "atom:x"); + v = memory->grow(atom->v, nmax, 3, "atom:v"); + f = memory->grow(atom->f, nmax*comm->nthreads, 3, "atom:f"); + + rho = memory->grow(atom->rho, nmax, "atom:rho"); + drho = memory->grow(atom->drho, nmax*comm->nthreads, "atom:drho"); + vest = memory->grow(atom->vest, nmax, 3, "atom:vest"); + + if (atom->nextra_grow) + for (int iextra = 0; iextra < atom->nextra_grow; iextra++) + modify->fix[atom->extra_grow[iextra]]->grow_arrays(nmax); +} + +/* ---------------------------------------------------------------------- + reset local array ptrs + ------------------------------------------------------------------------- */ + +void AtomVecMDPD::grow_reset() { + tag = atom->tag; + type = atom->type; + mask = atom->mask; + image = atom->image; + x = atom->x; + v = atom->v; + f = atom->f; + rho = atom->rho; + drho = atom->drho; + vest = atom->vest; +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecMDPD::copy(int i, int j, int delflag) { + //printf("in AtomVecMDPD::copy\n"); + tag[j] = tag[i]; + type[j] = type[i]; + mask[j] = mask[i]; + image[j] = image[i]; + x[j][0] = x[i][0]; + x[j][1] = x[i][1]; + x[j][2] = x[i][2]; + v[j][0] = v[i][0]; + v[j][1] = v[i][1]; + v[j][2] = v[i][2]; + + rho[j] = rho[i]; + drho[j] = drho[i]; + vest[j][0] = vest[i][0]; + vest[j][1] = vest[i][1]; + vest[j][2] = vest[i][2]; + + if (atom->nextra_grow) + for (int iextra = 0; iextra < atom->nextra_grow; iextra++) + modify->fix[atom->extra_grow[iextra]]->copy_arrays(i, j,delflag); +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecMDPD::force_clear(int n, size_t nbytes) +{ + memset(&drho[n],0,nbytes); +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecMDPD::pack_comm_hybrid(int n, int *list, double *buf) { + //printf("in AtomVecMDPD::pack_comm_hybrid\n"); + int i, j, m; + + m = 0; + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = rho[j]; + buf[m++] = vest[j][0]; + buf[m++] = vest[j][1]; + buf[m++] = vest[j][2]; + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecMDPD::unpack_comm_hybrid(int n, int first, double *buf) { + //printf("in AtomVecMDPD::unpack_comm_hybrid\n"); + int i, m, last; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + rho[i] = buf[m++]; + vest[i][0] = buf[m++]; + vest[i][1] = buf[m++]; + vest[i][2] = buf[m++]; + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecMDPD::pack_border_hybrid(int n, int *list, double *buf) { + //printf("in AtomVecMDPD::pack_border_hybrid\n"); + int i, j, m; + + m = 0; + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = rho[j]; + buf[m++] = vest[j][0]; + buf[m++] = vest[j][1]; + buf[m++] = vest[j][2]; + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecMDPD::unpack_border_hybrid(int n, int first, double *buf) { + //printf("in AtomVecMDPD::unpack_border_hybrid\n"); + int i, m, last; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + rho[i] = buf[m++]; + vest[i][0] = buf[m++]; + vest[i][1] = buf[m++]; + vest[i][2] = buf[m++]; + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecMDPD::pack_reverse_hybrid(int n, int first, double *buf) { + //printf("in AtomVecMDPD::pack_reverse_hybrid\n"); + int i, m, last; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + buf[m++] = drho[i]; + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecMDPD::unpack_reverse_hybrid(int n, int *list, double *buf) { + //printf("in AtomVecMDPD::unpack_reverse_hybrid\n"); + int i, j, m; + + m = 0; + for (i = 0; i < n; i++) { + j = list[i]; + drho[j] += buf[m++]; + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecMDPD::pack_comm(int n, int *list, double *buf, int pbc_flag, + int *pbc) { + //printf("in AtomVecMDPD::pack_comm\n"); + int i, j, m; + double dx, dy, dz; + + m = 0; + if (pbc_flag == 0) { + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = x[j][0]; + buf[m++] = x[j][1]; + buf[m++] = x[j][2]; + buf[m++] = rho[j]; + buf[m++] = vest[j][0]; + buf[m++] = vest[j][1]; + buf[m++] = vest[j][2]; + } + } else { + if (domain->triclinic == 0) { + dx = pbc[0] * domain->xprd; + dy = pbc[1] * domain->yprd; + dz = pbc[2] * domain->zprd; + } else { + dx = pbc[0] * domain->xprd + pbc[5] * domain->xy + pbc[4] * domain->xz; + dy = pbc[1] * domain->yprd + pbc[3] * domain->yz; + dz = pbc[2] * domain->zprd; + } + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = x[j][0] + dx; + buf[m++] = x[j][1] + dy; + buf[m++] = x[j][2] + dz; + buf[m++] = rho[j]; + buf[m++] = vest[j][0]; + buf[m++] = vest[j][1]; + buf[m++] = vest[j][2]; + } + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecMDPD::pack_comm_vel(int n, int *list, double *buf, int pbc_flag, + int *pbc) { + //printf("in AtomVecMDPD::pack_comm_vel\n"); + int i, j, m; + double dx, dy, dz; + + m = 0; + if (pbc_flag == 0) { + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = x[j][0]; + buf[m++] = x[j][1]; + buf[m++] = x[j][2]; + buf[m++] = v[j][0]; + buf[m++] = v[j][1]; + buf[m++] = v[j][2]; + buf[m++] = rho[j]; + buf[m++] = vest[j][0]; + buf[m++] = vest[j][1]; + buf[m++] = vest[j][2]; + } + } else { + if (domain->triclinic == 0) { + dx = pbc[0] * domain->xprd; + dy = pbc[1] * domain->yprd; + dz = pbc[2] * domain->zprd; + } else { + dx = pbc[0] * domain->xprd + pbc[5] * domain->xy + pbc[4] * domain->xz; + dy = pbc[1] * domain->yprd + pbc[3] * domain->yz; + dz = pbc[2] * domain->zprd; + } + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = x[j][0] + dx; + buf[m++] = x[j][1] + dy; + buf[m++] = x[j][2] + dz; + buf[m++] = v[j][0]; + buf[m++] = v[j][1]; + buf[m++] = v[j][2]; + buf[m++] = rho[j]; + buf[m++] = vest[j][0]; + buf[m++] = vest[j][1]; + buf[m++] = vest[j][2]; + } + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecMDPD::unpack_comm(int n, int first, double *buf) { + //printf("in AtomVecMDPD::unpack_comm\n"); + int i, m, last; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + x[i][0] = buf[m++]; + x[i][1] = buf[m++]; + x[i][2] = buf[m++]; + rho[i] = buf[m++]; + vest[i][0] = buf[m++]; + vest[i][1] = buf[m++]; + vest[i][2] = buf[m++]; + } +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecMDPD::unpack_comm_vel(int n, int first, double *buf) { + //printf("in AtomVecMDPD::unpack_comm_vel\n"); + int i, m, last; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + x[i][0] = buf[m++]; + x[i][1] = buf[m++]; + x[i][2] = buf[m++]; + v[i][0] = buf[m++]; + v[i][1] = buf[m++]; + v[i][2] = buf[m++]; + rho[i] = buf[m++]; + vest[i][0] = buf[m++]; + vest[i][1] = buf[m++]; + vest[i][2] = buf[m++]; + } +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecMDPD::pack_reverse(int n, int first, double *buf) { + //printf("in AtomVecMDPD::pack_reverse\n"); + int i, m, last; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + buf[m++] = f[i][0]; + buf[m++] = f[i][1]; + buf[m++] = f[i][2]; + buf[m++] = drho[i]; + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecMDPD::unpack_reverse(int n, int *list, double *buf) { + //printf("in AtomVecMDPD::unpack_reverse\n"); + int i, j, m; + + m = 0; + for (i = 0; i < n; i++) { + j = list[i]; + f[j][0] += buf[m++]; + f[j][1] += buf[m++]; + f[j][2] += buf[m++]; + drho[j] += buf[m++]; + } +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecMDPD::pack_border(int n, int *list, double *buf, int pbc_flag, + int *pbc) { + //printf("in AtomVecMDPD::pack_border\n"); + int i, j, m; + double dx, dy, dz; + + m = 0; + if (pbc_flag == 0) { + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = x[j][0]; + buf[m++] = x[j][1]; + buf[m++] = x[j][2]; + buf[m++] = ubuf(tag[j]).d; + buf[m++] = ubuf(type[j]).d; + buf[m++] = ubuf(mask[j]).d; + buf[m++] = rho[j]; + buf[m++] = vest[j][0]; + buf[m++] = vest[j][1]; + buf[m++] = vest[j][2]; + } + } else { + if (domain->triclinic == 0) { + dx = pbc[0] * domain->xprd; + dy = pbc[1] * domain->yprd; + dz = pbc[2] * domain->zprd; + } else { + dx = pbc[0]; + dy = pbc[1]; + dz = pbc[2]; + } + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = x[j][0] + dx; + buf[m++] = x[j][1] + dy; + buf[m++] = x[j][2] + dz; + buf[m++] = ubuf(tag[j]).d; + buf[m++] = ubuf(type[j]).d; + buf[m++] = ubuf(mask[j]).d; + buf[m++] = rho[j]; + buf[m++] = vest[j][0]; + buf[m++] = vest[j][1]; + buf[m++] = vest[j][2]; + } + } + + if (atom->nextra_border) + for (int iextra = 0; iextra < atom->nextra_border; iextra++) + m += modify->fix[atom->extra_border[iextra]]->pack_border(n,list,&buf[m]); + + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecMDPD::pack_border_vel(int n, int *list, double *buf, int pbc_flag, + int *pbc) +{ + int i,j,m; + double dx,dy,dz,dvx,dvy,dvz; + + m = 0; + if (pbc_flag == 0) { + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = x[j][0]; + buf[m++] = x[j][1]; + buf[m++] = x[j][2]; + buf[m++] = ubuf(tag[j]).d; + buf[m++] = ubuf(type[j]).d; + buf[m++] = ubuf(mask[j]).d; + buf[m++] = v[j][0]; + buf[m++] = v[j][1]; + buf[m++] = v[j][2]; + buf[m++] = rho[j]; + buf[m++] = vest[j][0]; + buf[m++] = vest[j][1]; + buf[m++] = vest[j][2]; + } + } else { + if (domain->triclinic == 0) { + dx = pbc[0] * domain->xprd; + dy = pbc[1] * domain->yprd; + dz = pbc[2] * domain->zprd; + } else { + dx = pbc[0]; + dy = pbc[1]; + dz = pbc[2]; + } + if (!deform_vremap) { + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = x[j][0] + dx; + buf[m++] = x[j][1] + dy; + buf[m++] = x[j][2] + dz; + buf[m++] = ubuf(tag[j]).d; + buf[m++] = ubuf(type[j]).d; + buf[m++] = ubuf(mask[j]).d; + buf[m++] = v[j][0]; + buf[m++] = v[j][1]; + buf[m++] = v[j][2]; + buf[m++] = rho[j]; + buf[m++] = vest[j][0]; + buf[m++] = vest[j][1]; + buf[m++] = vest[j][2]; + } + } else { + dvx = pbc[0] * h_rate[0] + pbc[5] * h_rate[5] + pbc[4] * h_rate[4]; + dvy = pbc[1] * h_rate[1] + pbc[3] * h_rate[3]; + dvz = pbc[2] * h_rate[2]; + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = x[j][0] + dx; + buf[m++] = x[j][1] + dy; + buf[m++] = x[j][2] + dz; + buf[m++] = ubuf(tag[j]).d; + buf[m++] = ubuf(type[j]).d; + buf[m++] = ubuf(mask[j]).d; + if (mask[i] & deform_groupbit) { + buf[m++] = v[j][0] + dvx; + buf[m++] = v[j][1] + dvy; + buf[m++] = v[j][2] + dvz; + buf[m++] = rho[j]; + buf[m++] = vest[j][0] + dvx; + buf[m++] = vest[j][1] + dvy; + buf[m++] = vest[j][2] + dvz; + } else { + buf[m++] = v[j][0]; + buf[m++] = v[j][1]; + buf[m++] = v[j][2]; + buf[m++] = rho[j]; + buf[m++] = vest[j][0]; + buf[m++] = vest[j][1]; + buf[m++] = vest[j][2]; + } + } + } + } + + if (atom->nextra_border) + for (int iextra = 0; iextra < atom->nextra_border; iextra++) + m += modify->fix[atom->extra_border[iextra]]->pack_border(n,list,&buf[m]); + + return m; +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecMDPD::unpack_border(int n, int first, double *buf) { + //printf("in AtomVecMDPD::unpack_border\n"); + int i, m, last; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + if (i == nmax) + grow(0); + x[i][0] = buf[m++]; + x[i][1] = buf[m++]; + x[i][2] = buf[m++]; + tag[i] = (tagint) ubuf(buf[m++]).i; + type[i] = (int) ubuf(buf[m++]).i; + mask[i] = (int) ubuf(buf[m++]).i; + rho[i] = buf[m++]; + vest[i][0] = buf[m++]; + vest[i][1] = buf[m++]; + vest[i][2] = buf[m++]; + } + + if (atom->nextra_border) + for (int iextra = 0; iextra < atom->nextra_border; iextra++) + m += modify->fix[atom->extra_border[iextra]]-> + unpack_border(n,first,&buf[m]); +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecMDPD::unpack_border_vel(int n, int first, double *buf) { + //printf("in AtomVecMDPD::unpack_border_vel\n"); + int i, m, last; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + if (i == nmax) + grow(0); + x[i][0] = buf[m++]; + x[i][1] = buf[m++]; + x[i][2] = buf[m++]; + tag[i] = (tagint) ubuf(buf[m++]).i; + type[i] = (int) ubuf(buf[m++]).i; + mask[i] = (int) ubuf(buf[m++]).i; + v[i][0] = buf[m++]; + v[i][1] = buf[m++]; + v[i][2] = buf[m++]; + rho[i] = buf[m++]; + vest[i][0] = buf[m++]; + vest[i][1] = buf[m++]; + vest[i][2] = buf[m++]; + } + + if (atom->nextra_border) + for (int iextra = 0; iextra < atom->nextra_border; iextra++) + m += modify->fix[atom->extra_border[iextra]]-> + unpack_border(n,first,&buf[m]); +} + +/* ---------------------------------------------------------------------- + pack data for atom I for sending to another proc + xyz must be 1st 3 values, so comm::exchange() can test on them + ------------------------------------------------------------------------- */ + +int AtomVecMDPD::pack_exchange(int i, double *buf) { + //printf("in AtomVecMDPD::pack_exchange\n"); + int m = 1; + buf[m++] = x[i][0]; + buf[m++] = x[i][1]; + buf[m++] = x[i][2]; + buf[m++] = v[i][0]; + buf[m++] = v[i][1]; + buf[m++] = v[i][2]; + buf[m++] = ubuf(tag[i]).d; + buf[m++] = ubuf(type[i]).d; + buf[m++] = ubuf(mask[i]).d; + buf[m++] = ubuf(image[i]).d; + buf[m++] = rho[i]; + buf[m++] = vest[i][0]; + buf[m++] = vest[i][1]; + buf[m++] = vest[i][2]; + + if (atom->nextra_grow) + for (int iextra = 0; iextra < atom->nextra_grow; iextra++) + m += modify->fix[atom->extra_grow[iextra]]->pack_exchange(i, &buf[m]); + + buf[0] = m; + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecMDPD::unpack_exchange(double *buf) { + //printf("in AtomVecMDPD::unpack_exchange\n"); + int nlocal = atom->nlocal; + if (nlocal == nmax) + grow(0); + + int m = 1; + x[nlocal][0] = buf[m++]; + x[nlocal][1] = buf[m++]; + x[nlocal][2] = buf[m++]; + v[nlocal][0] = buf[m++]; + v[nlocal][1] = buf[m++]; + v[nlocal][2] = buf[m++]; + tag[nlocal] = (tagint) ubuf(buf[m++]).i; + type[nlocal] = (int) ubuf(buf[m++]).i; + mask[nlocal] = (int) ubuf(buf[m++]).i; + image[nlocal] = (imageint) ubuf(buf[m++]).i; + rho[nlocal] = buf[m++]; + vest[nlocal][0] = buf[m++]; + vest[nlocal][1] = buf[m++]; + vest[nlocal][2] = buf[m++]; + + if (atom->nextra_grow) + for (int iextra = 0; iextra < atom->nextra_grow; iextra++) + m += modify->fix[atom->extra_grow[iextra]]-> unpack_exchange(nlocal, + &buf[m]); + + atom->nlocal++; + return m; +} + +/* ---------------------------------------------------------------------- + size of restart data for all atoms owned by this proc + include extra data stored by fixes + ------------------------------------------------------------------------- */ + +int AtomVecMDPD::size_restart() { + int i; + + int nlocal = atom->nlocal; + int n = 15 * nlocal; // 11 + rho + vest[3] + + if (atom->nextra_restart) + for (int iextra = 0; iextra < atom->nextra_restart; iextra++) + for (i = 0; i < nlocal; i++) + n += modify->fix[atom->extra_restart[iextra]]->size_restart(i); + + return n; +} + +/* ---------------------------------------------------------------------- + pack atom I's data for restart file including extra quantities + xyz must be 1st 3 values, so that read_restart can test on them + molecular types may be negative, but write as positive + ------------------------------------------------------------------------- */ + +int AtomVecMDPD::pack_restart(int i, double *buf) { + int m = 1; + buf[m++] = x[i][0]; + buf[m++] = x[i][1]; + buf[m++] = x[i][2]; + buf[m++] = ubuf(tag[i]).d; + buf[m++] = ubuf(type[i]).d; + buf[m++] = ubuf(mask[i]).d; + buf[m++] = ubuf(image[i]).d; + buf[m++] = v[i][0]; + buf[m++] = v[i][1]; + buf[m++] = v[i][2]; + buf[m++] = rho[i]; + buf[m++] = vest[i][0]; + buf[m++] = vest[i][1]; + buf[m++] = vest[i][2]; + + if (atom->nextra_restart) + for (int iextra = 0; iextra < atom->nextra_restart; iextra++) + m += modify->fix[atom->extra_restart[iextra]]->pack_restart(i, &buf[m]); + + buf[0] = m; + return m; +} + +/* ---------------------------------------------------------------------- + unpack data for one atom from restart file including extra quantities + ------------------------------------------------------------------------- */ + +int AtomVecMDPD::unpack_restart(double *buf) { + int nlocal = atom->nlocal; + if (nlocal == nmax) { + grow(0); + if (atom->nextra_store) + memory->grow(atom->extra, nmax, atom->nextra_store, "atom:extra"); + } + + int m = 1; + x[nlocal][0] = buf[m++]; + x[nlocal][1] = buf[m++]; + x[nlocal][2] = buf[m++]; + tag[nlocal] = (tagint) ubuf(buf[m++]).i; + type[nlocal] = (int) ubuf(buf[m++]).i; + mask[nlocal] = (int) ubuf(buf[m++]).i; + image[nlocal] = (imageint) ubuf(buf[m++]).i; + v[nlocal][0] = buf[m++]; + v[nlocal][1] = buf[m++]; + v[nlocal][2] = buf[m++]; + rho[nlocal] = buf[m++]; + vest[nlocal][0] = buf[m++]; + vest[nlocal][1] = buf[m++]; + vest[nlocal][2] = buf[m++]; + + double **extra = atom->extra; + if (atom->nextra_store) { + int size = static_cast (buf[0]) - m; + for (int i = 0; i < size; i++) + extra[nlocal][i] = buf[m++]; + } + + atom->nlocal++; + return m; +} + +/* ---------------------------------------------------------------------- + create one atom of itype at coord + set other values to defaults + ------------------------------------------------------------------------- */ + +void AtomVecMDPD::create_atom(int itype, double *coord) { + int nlocal = atom->nlocal; + if (nlocal == nmax) + grow(0); + + tag[nlocal] = 0; + type[nlocal] = itype; + x[nlocal][0] = coord[0]; + x[nlocal][1] = coord[1]; + x[nlocal][2] = coord[2]; + mask[nlocal] = 1; + image[nlocal] = ((imageint) IMGMAX << IMG2BITS) | + ((imageint) IMGMAX << IMGBITS) | IMGMAX; + v[nlocal][0] = 0.0; + v[nlocal][1] = 0.0; + v[nlocal][2] = 0.0; + rho[nlocal] = 0.0; + vest[nlocal][0] = 0.0; + vest[nlocal][1] = 0.0; + vest[nlocal][2] = 0.0; + drho[nlocal] = 0.0; + + atom->nlocal++; +} + +/* ---------------------------------------------------------------------- + unpack one line from Atoms section of data file + initialize other atom quantities + ------------------------------------------------------------------------- */ + +void AtomVecMDPD::data_atom(double *coord, imageint imagetmp, char **values) { + int nlocal = atom->nlocal; + if (nlocal == nmax) grow(0); + + tag[nlocal] = ATOTAGINT(values[0]); + type[nlocal] = atoi(values[1]); + if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes) + error->one(FLERR,"Invalid atom type in Atoms section of data file"); + + x[nlocal][0] = coord[0]; + x[nlocal][1] = coord[1]; + x[nlocal][2] = coord[2]; + + image[nlocal] = imagetmp; + + mask[nlocal] = 1; + v[nlocal][0] = 0.0; + v[nlocal][1] = 0.0; + v[nlocal][2] = 0.0; + + vest[nlocal][0] = 0.0; + vest[nlocal][1] = 0.0; + vest[nlocal][2] = 0.0; + + rho[nlocal] = 0.0; + drho[nlocal] = 0.0; + + atom->nlocal++; +} + +/* ---------------------------------------------------------------------- + unpack hybrid quantities from one line in Atoms section of data file + initialize other atom quantities for this sub-style + ------------------------------------------------------------------------- */ + +int AtomVecMDPD::data_atom_hybrid(int nlocal, char **values) +{ + rho[nlocal] = atof(values[0]); + return 3; +} + +/* ---------------------------------------------------------------------- + pack atom info for data file including 3 image flags +------------------------------------------------------------------------- */ + +void AtomVecMDPD::pack_data(double **buf) +{ + int nlocal = atom->nlocal; + for (int i = 0; i < nlocal; i++) { + buf[i][0] = ubuf(tag[i]).d; + buf[i][1] = ubuf(type[i]).d; + buf[i][2] = rho[i]; + buf[i][3] = x[i][0]; + buf[i][4] = x[i][1]; + buf[i][5] = x[i][2]; + buf[i][6] = ubuf((image[i] & IMGMASK) - IMGMAX).d; + buf[i][7] = ubuf((image[i] >> IMGBITS & IMGMASK) - IMGMAX).d; + buf[i][8] = ubuf((image[i] >> IMG2BITS) - IMGMAX).d; + } +} + +/* ---------------------------------------------------------------------- + pack hybrid atom info for data file +------------------------------------------------------------------------- */ + +int AtomVecMDPD::pack_data_hybrid(int i, double *buf) +{ + buf[0] = rho[i]; + return 3; +} + +/* ---------------------------------------------------------------------- + write atom info to data file including 3 image flags +------------------------------------------------------------------------- */ + +void AtomVecMDPD::write_data(FILE *fp, int n, double **buf) +{ + for (int i = 0; i < n; i++) + fprintf(fp,TAGINT_FORMAT + " %d %-1.16e %-1.16e %-1.16e %-1.16e " + "%d %d %d\n", + (tagint) ubuf(buf[i][0]).i,(int) ubuf(buf[i][1]).i, + buf[i][2],buf[i][3],buf[i][4],buf[i][5], + (int) ubuf(buf[i][6]).i,(int) ubuf(buf[i][7]).i, + (int) ubuf(buf[i][8]).i); +} + +/* ---------------------------------------------------------------------- + write hybrid atom info to data file +------------------------------------------------------------------------- */ + +int AtomVecMDPD::write_data_hybrid(FILE *fp, double *buf) +{ + fprintf(fp," %-1.16e",buf[0]); + return 3; +} + +/* ---------------------------------------------------------------------- + assign an index to named atom property and return index + return -1 if name is unknown to this atom style +------------------------------------------------------------------------- */ + +int AtomVecMDPD::property_atom(char *name) +{ + if (strcmp(name,"rho") == 0) return 0; + if (strcmp(name,"drho") == 0) return 1; + return -1; +} + +/* ---------------------------------------------------------------------- + pack per-atom data into buf for ComputePropertyAtom + index maps to data specific to this atom style +------------------------------------------------------------------------- */ + +void AtomVecMDPD::pack_property_atom(int index, double *buf, + int nvalues, int groupbit) +{ + int *mask = atom->mask; + int nlocal = atom->nlocal; + int n = 0; + + if (index == 0) { + for (int i = 0; i < nlocal; i++) { + if (mask[i] & groupbit) buf[n] = rho[i]; + else buf[n] = 0.0; + n += nvalues; + } + } else if (index == 1) { + for (int i = 0; i < nlocal; i++) { + if (mask[i] & groupbit) buf[n] = drho[i]; + else buf[n] = 0.0; + n += nvalues; + } + } +} + +/* ---------------------------------------------------------------------- + return # of bytes of allocated memory + ------------------------------------------------------------------------- */ + +bigint AtomVecMDPD::memory_usage() { + bigint bytes = 0; + + if (atom->memcheck("tag")) bytes += memory->usage(tag, nmax); + if (atom->memcheck("type")) bytes += memory->usage(type, nmax); + if (atom->memcheck("mask")) bytes += memory->usage(mask, nmax); + if (atom->memcheck("image")) bytes += memory->usage(image, nmax); + if (atom->memcheck("x")) bytes += memory->usage(x, nmax, 3); + if (atom->memcheck("v")) bytes += memory->usage(v, nmax, 3); + if (atom->memcheck("f")) bytes += memory->usage(f, nmax*comm->nthreads, 3); + if (atom->memcheck("rho")) bytes += memory->usage(rho, nmax); + if (atom->memcheck("drho")) bytes += memory->usage(drho, nmax*comm->nthreads); + if (atom->memcheck("vest")) bytes += memory->usage(vest, nmax, 3); + + return bytes; +} diff --git a/src/USER-MESO/atom_vec_mdpd.h b/src/USER-MESO/atom_vec_mdpd.h new file mode 100644 index 0000000000..9e9ffcdcf2 --- /dev/null +++ b/src/USER-MESO/atom_vec_mdpd.h @@ -0,0 +1,79 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef ATOM_CLASS + +AtomStyle(mdpd,AtomVecMDPD) + +#else + +#ifndef LMP_ATOM_VEC_MDPD_H +#define LMP_ATOM_VEC_MDPD_H + +#include "atom_vec.h" + +namespace LAMMPS_NS { + +class AtomVecMDPD : public AtomVec { + public: + AtomVecMDPD(class LAMMPS *); + ~AtomVecMDPD() {} + void grow(int); + void grow_reset(); + void copy(int, int, int); + void force_clear(int, size_t); + int pack_comm(int, int *, double *, int, int *); + int pack_comm_vel(int, int *, double *, int, int *); + void unpack_comm(int, int, double *); + void unpack_comm_vel(int, int, double *); + int pack_reverse(int, int, double *); + void unpack_reverse(int, int *, double *); + int pack_comm_hybrid(int, int *, double *); + int unpack_comm_hybrid(int, int, double *); + int pack_border_hybrid(int, int *, double *); + int unpack_border_hybrid(int, int, double *); + int pack_reverse_hybrid(int, int, double *); + int unpack_reverse_hybrid(int, int *, double *); + int pack_border(int, int *, double *, int, int *); + int pack_border_vel(int, int *, double *, int, int *); + void unpack_border(int, int, double *); + void unpack_border_vel(int, int, double *); + int pack_exchange(int, double *); + int unpack_exchange(double *); + int size_restart(); + int pack_restart(int, double *); + int unpack_restart(double *); + void create_atom(int, double *); + void data_atom(double *, imageint, char **); + int data_atom_hybrid(int, char **); + void pack_data(double **); + int pack_data_hybrid(int, double *); + void write_data(FILE *, int, double **); + int write_data_hybrid(FILE *, double *); + int property_atom(char *); + void pack_property_atom(int, double *, int, int); + bigint memory_usage(); + + private: + tagint *tag; + int *type,*mask; + imageint *image; + double **x,**v,**f; + double *rho, *drho; + double **vest; // estimated velocity during force computation +}; + +} + +#endif +#endif diff --git a/src/USER-MESO/atom_vec_tdpd.cpp b/src/USER-MESO/atom_vec_tdpd.cpp new file mode 100644 index 0000000000..ce9e492029 --- /dev/null +++ b/src/USER-MESO/atom_vec_tdpd.cpp @@ -0,0 +1,879 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include +#include +#include "atom_vec_tdpd.h" +#include "atom.h" +#include "comm.h" +#include "force.h" +#include "domain.h" +#include "modify.h" +#include "fix.h" +#include "update.h" +#include "memory.h" +#include "error.h" +#include "input.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +AtomVecTDPD::AtomVecTDPD(LAMMPS *lmp) : AtomVec(lmp) +{ + if(strcmp(update->unit_style,"lj") != 0) + error->all(FLERR,"Atom style edpd requires lj units"); + + molecular = 0; + mass_type = 1; + forceclearflag = 1; + + comm_x_only = comm_f_only = 0; + comm->ghost_velocity = 1; + + cc_species = 0; // for now, reset in process_args() + + size_forward = 3 + cc_species + 3; //vest[3] + size_reverse = 3 + cc_species; + size_border = 6 + cc_species + 3; //vest[3] + size_velocity = 3; + // for data_atom, we read id + type + xyz[3] + cc[i] where i=1,cc_species + size_data_atom = 5 + cc_species; + size_data_vel = 4; + xcol_data = 3; + + atom->tdpd_flag = 1; + atom->vest_flag = 1; +} + +/* ---------------------------------------------------------------------- + process additional args + single arg = number of cc_species +------------------------------------------------------------------------- */ + +void AtomVecTDPD::process_args(int narg, char **arg) +{ + if (narg < 1) error->all(FLERR,"Invalid atom_style tdpd command"); + + atom->cc_species = force->inumeric(FLERR,arg[0]); + cc_species = atom->cc_species; + + // reset sizes that depend on cc_species + + size_forward = 3 + cc_species + 3; + size_reverse = 3 + cc_species; + size_border = 6 + cc_species + 3; + size_data_atom = 5 + cc_species; +} + +/* ---------------------------------------------------------------------- + grow atom arrays + n = 0 grows arrays by a chunk + n > 0 allocates arrays to size n +------------------------------------------------------------------------- */ + +void AtomVecTDPD::grow(int n) +{ + if (n == 0) grow_nmax(); + else nmax = n; + atom->nmax = nmax; + if (nmax < 0 || nmax > MAXSMALLINT) + error->one(FLERR,"Per-processor system is too big"); + + tag = memory->grow(atom->tag,nmax,"atom:tag"); + type = memory->grow(atom->type,nmax,"atom:type"); + mask = memory->grow(atom->mask,nmax,"atom:mask"); + image = memory->grow(atom->image,nmax,"atom:image"); + x = memory->grow(atom->x,nmax,3,"atom:x"); + v = memory->grow(atom->v,nmax,3,"atom:v"); + f = memory->grow(atom->f,nmax*comm->nthreads,3,"atom:f"); + cc = memory->grow(atom->cc,nmax*comm->nthreads,cc_species,"atom:cc"); + cc_flux = memory->grow(atom->cc_flux,nmax*comm->nthreads,cc_species, + "atom:cc_flux"); + vest = memory->grow(atom->vest, nmax, 3, "atom:vest"); + + if (atom->nextra_grow) + for (int iextra = 0; iextra < atom->nextra_grow; iextra++) + modify->fix[atom->extra_grow[iextra]]->grow_arrays(nmax); +} + +/* ---------------------------------------------------------------------- + reset local array ptrs +------------------------------------------------------------------------- */ + +void AtomVecTDPD::grow_reset() +{ + tag = atom->tag; type = atom->type; + mask = atom->mask; image = atom->image; + x = atom->x; v = atom->v; f = atom->f; + cc = atom->cc; cc_flux = atom->cc_flux; + vest = atom->vest; +} + +/* ---------------------------------------------------------------------- + copy atom I info to atom J +------------------------------------------------------------------------- */ + +void AtomVecTDPD::copy(int i, int j, int delflag) +{ + tag[j] = tag[i]; + type[j] = type[i]; + mask[j] = mask[i]; + image[j] = image[i]; + x[j][0] = x[i][0]; + x[j][1] = x[i][1]; + x[j][2] = x[i][2]; + v[j][0] = v[i][0]; + v[j][1] = v[i][1]; + v[j][2] = v[i][2]; + + for(int k = 0; k < cc_species; k++) + cc[j][k] = cc[i][k]; + + vest[j][0] = vest[i][0]; + vest[j][1] = vest[i][1]; + vest[j][2] = vest[i][2]; + + if (atom->nextra_grow) + for (int iextra = 0; iextra < atom->nextra_grow; iextra++) + modify->fix[atom->extra_grow[iextra]]->copy_arrays(i,j,delflag); +} + + +void AtomVecTDPD::force_clear(int n, size_t nbytes) +{ + memset(&cc_flux[n][0],0,cc_species*nbytes); +} + + +/* ---------------------------------------------------------------------- */ + +int AtomVecTDPD::pack_comm(int n, int *list, double *buf, + int pbc_flag, int *pbc) +{ + int i,j,k,m; + double dx,dy,dz; + + m = 0; + if (pbc_flag == 0) { + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = x[j][0]; + buf[m++] = x[j][1]; + buf[m++] = x[j][2]; + + for(k = 0; k < cc_species; k++) + buf[m++] = cc[j][k]; + + buf[m++] = vest[j][0]; + buf[m++] = vest[j][1]; + buf[m++] = vest[j][2]; + } + } else { + if (domain->triclinic == 0) { + dx = pbc[0]*domain->xprd; + dy = pbc[1]*domain->yprd; + dz = pbc[2]*domain->zprd; + } else { + dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz; + dy = pbc[1]*domain->yprd + pbc[3]*domain->yz; + dz = pbc[2]*domain->zprd; + } + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = x[j][0] + dx; + buf[m++] = x[j][1] + dy; + buf[m++] = x[j][2] + dz; + + for(k = 0; k < cc_species; k++) + buf[m++] = cc[j][k]; + + buf[m++] = vest[j][0]; + buf[m++] = vest[j][1]; + buf[m++] = vest[j][2]; + } + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecTDPD::pack_comm_vel(int n, int *list, double *buf, + int pbc_flag, int *pbc) +{ + int i,j,k,m; + double dx,dy,dz,dvx,dvy,dvz; + + m = 0; + if (pbc_flag == 0) { + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = x[j][0]; + buf[m++] = x[j][1]; + buf[m++] = x[j][2]; + buf[m++] = v[j][0]; + buf[m++] = v[j][1]; + buf[m++] = v[j][2]; + + for(k = 0; k < cc_species; k++) + buf[m++] = cc[j][k]; + + buf[m++] = vest[j][0]; + buf[m++] = vest[j][1]; + buf[m++] = vest[j][2]; + } + } else { + if (domain->triclinic == 0) { + dx = pbc[0]*domain->xprd; + dy = pbc[1]*domain->yprd; + dz = pbc[2]*domain->zprd; + } else { + dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz; + dy = pbc[1]*domain->yprd + pbc[3]*domain->yz; + dz = pbc[2]*domain->zprd; + } + if (!deform_vremap) { + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = x[j][0] + dx; + buf[m++] = x[j][1] + dy; + buf[m++] = x[j][2] + dz; + buf[m++] = v[j][0]; + buf[m++] = v[j][1]; + buf[m++] = v[j][2]; + + for(k = 0; k < cc_species; k++) + buf[m++] = cc[j][k]; + + buf[m++] = vest[j][0]; + buf[m++] = vest[j][1]; + buf[m++] = vest[j][2]; + } + } else { + dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4]; + dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3]; + dvz = pbc[2]*h_rate[2]; + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = x[j][0] + dx; + buf[m++] = x[j][1] + dy; + buf[m++] = x[j][2] + dz; + if (mask[i] & deform_groupbit) { + buf[m++] = v[j][0] + dvx; + buf[m++] = v[j][1] + dvy; + buf[m++] = v[j][2] + dvz; + } else { + buf[m++] = v[j][0]; + buf[m++] = v[j][1]; + buf[m++] = v[j][2]; + } + for(k = 0; k < cc_species; k++) + buf[m++] = cc[j][k]; + + buf[m++] = vest[j][0]; + buf[m++] = vest[j][1]; + buf[m++] = vest[j][2]; + } + } + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecTDPD::unpack_comm(int n, int first, double *buf) +{ + int i,m,last; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + x[i][0] = buf[m++]; + x[i][1] = buf[m++]; + x[i][2] = buf[m++]; + + for(int k = 0; k < cc_species; k++) + cc[i][k] = buf[m++]; + + vest[i][0] = buf[m++]; + vest[i][1] = buf[m++]; + vest[i][2] = buf[m++]; + } +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecTDPD::unpack_comm_vel(int n, int first, double *buf) +{ + int i,m,last; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + x[i][0] = buf[m++]; + x[i][1] = buf[m++]; + x[i][2] = buf[m++]; + v[i][0] = buf[m++]; + v[i][1] = buf[m++]; + v[i][2] = buf[m++]; + for(int k = 0; k < cc_species; k++) + cc[i][k] = buf[m++]; + + vest[i][0] = buf[m++]; + vest[i][1] = buf[m++]; + vest[i][2] = buf[m++]; + } +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecTDPD::pack_reverse(int n, int first, double *buf) +{ + int i,m,last; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + buf[m++] = f[i][0]; + buf[m++] = f[i][1]; + buf[m++] = f[i][2]; + for(int k = 0; k < cc_species; k++) + buf[m++] = cc_flux[i][k]; + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecTDPD::unpack_reverse(int n, int *list, double *buf) +{ + int i,j,m; + + m = 0; + for (i = 0; i < n; i++) { + j = list[i]; + f[j][0] += buf[m++]; + f[j][1] += buf[m++]; + f[j][2] += buf[m++]; + for(int k = 0; k < cc_species; k++) + cc_flux[j][k] += buf[m++]; + } +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecTDPD::pack_border(int n, int *list, double *buf, + int pbc_flag, int *pbc) +{ + int i,j,m; + double dx,dy,dz; + + m = 0; + if (pbc_flag == 0) { + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = x[j][0]; + buf[m++] = x[j][1]; + buf[m++] = x[j][2]; + buf[m++] = ubuf(tag[j]).d; + buf[m++] = ubuf(type[j]).d; + buf[m++] = ubuf(mask[j]).d; + for(int k = 0; k < cc_species; k++) + buf[m++] = cc[j][k]; + + buf[m++] = vest[j][0]; + buf[m++] = vest[j][1]; + buf[m++] = vest[j][2]; + } + } else { + if (domain->triclinic == 0) { + dx = pbc[0]*domain->xprd; + dy = pbc[1]*domain->yprd; + dz = pbc[2]*domain->zprd; + } else { + dx = pbc[0]; + dy = pbc[1]; + dz = pbc[2]; + } + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = x[j][0] + dx; + buf[m++] = x[j][1] + dy; + buf[m++] = x[j][2] + dz; + buf[m++] = ubuf(tag[j]).d; + buf[m++] = ubuf(type[j]).d; + buf[m++] = ubuf(mask[j]).d; + for(int k = 0; k < cc_species; k++) + buf[m++] = cc[j][k]; + + buf[m++] = vest[j][0]; + buf[m++] = vest[j][1]; + buf[m++] = vest[j][2]; + } + } + + if (atom->nextra_border) + for (int iextra = 0; iextra < atom->nextra_border; iextra++) + m += modify->fix[atom->extra_border[iextra]]->pack_border(n,list,&buf[m]); + + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecTDPD::pack_border_vel(int n, int *list, double *buf, + int pbc_flag, int *pbc) +{ + int i,j,m; + double dx,dy,dz,dvx,dvy,dvz; + + m = 0; + if (pbc_flag == 0) { + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = x[j][0]; + buf[m++] = x[j][1]; + buf[m++] = x[j][2]; + buf[m++] = ubuf(tag[j]).d; + buf[m++] = ubuf(type[j]).d; + buf[m++] = ubuf(mask[j]).d; + buf[m++] = v[j][0]; + buf[m++] = v[j][1]; + buf[m++] = v[j][2]; + for(int k = 0; k < cc_species; k++) + buf[m++] = cc[j][k]; + + buf[m++] = vest[j][0]; + buf[m++] = vest[j][1]; + buf[m++] = vest[j][2]; + } + } else { + if (domain->triclinic == 0) { + dx = pbc[0]*domain->xprd; + dy = pbc[1]*domain->yprd; + dz = pbc[2]*domain->zprd; + } else { + dx = pbc[0]; + dy = pbc[1]; + dz = pbc[2]; + } + if (!deform_vremap) { + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = x[j][0] + dx; + buf[m++] = x[j][1] + dy; + buf[m++] = x[j][2] + dz; + buf[m++] = ubuf(tag[j]).d; + buf[m++] = ubuf(type[j]).d; + buf[m++] = ubuf(mask[j]).d; + buf[m++] = v[j][0]; + buf[m++] = v[j][1]; + buf[m++] = v[j][2]; + for(int k = 0; k < cc_species; k++) + buf[m++] = cc[j][k]; + + buf[m++] = vest[j][0]; + buf[m++] = vest[j][1]; + buf[m++] = vest[j][2]; + } + } else { + dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4]; + dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3]; + dvz = pbc[2]*h_rate[2]; + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = x[j][0] + dx; + buf[m++] = x[j][1] + dy; + buf[m++] = x[j][2] + dz; + buf[m++] = ubuf(tag[j]).d; + buf[m++] = ubuf(type[j]).d; + buf[m++] = ubuf(mask[j]).d; + if (mask[i] & deform_groupbit) { + buf[m++] = v[j][0] + dvx; + buf[m++] = v[j][1] + dvy; + buf[m++] = v[j][2] + dvz; + } else { + buf[m++] = v[j][0]; + buf[m++] = v[j][1]; + buf[m++] = v[j][2]; + } + for(int k = 0; k < cc_species; k++) + buf[m++] = cc[j][k]; + + buf[m++] = vest[j][0]; + buf[m++] = vest[j][1]; + buf[m++] = vest[j][2]; + } + } + } + + if (atom->nextra_border) + for (int iextra = 0; iextra < atom->nextra_border; iextra++) + m += modify->fix[atom->extra_border[iextra]]->pack_border(n,list,&buf[m]); + + return m; +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecTDPD::unpack_border(int n, int first, double *buf) +{ + int i,m,last; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + if (i == nmax) grow(0); + x[i][0] = buf[m++]; + x[i][1] = buf[m++]; + x[i][2] = buf[m++]; + tag[i] = (tagint) ubuf(buf[m++]).i; + type[i] = (int) ubuf(buf[m++]).i; + mask[i] = (int) ubuf(buf[m++]).i; + for(int k = 0; k < cc_species; k++) + cc[i][k] = buf[m++]; + + vest[i][0] = buf[m++]; + vest[i][1] = buf[m++]; + vest[i][2] = buf[m++]; + } + + if (atom->nextra_border) + for (int iextra = 0; iextra < atom->nextra_border; iextra++) + m += modify->fix[atom->extra_border[iextra]]-> + unpack_border(n,first,&buf[m]); +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecTDPD::unpack_border_vel(int n, int first, double *buf) +{ + int i,m,last; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + if (i == nmax) grow(0); + x[i][0] = buf[m++]; + x[i][1] = buf[m++]; + x[i][2] = buf[m++]; + tag[i] = (tagint) ubuf(buf[m++]).i; + type[i] = (int) ubuf(buf[m++]).i; + mask[i] = (int) ubuf(buf[m++]).i; + v[i][0] = buf[m++]; + v[i][1] = buf[m++]; + v[i][2] = buf[m++]; + for(int k = 0; k < cc_species; k++) + cc[i][k] = buf[m++]; + + vest[i][0] = buf[m++]; + vest[i][1] = buf[m++]; + vest[i][2] = buf[m++]; + } + + if (atom->nextra_border) + for (int iextra = 0; iextra < atom->nextra_border; iextra++) + m += modify->fix[atom->extra_border[iextra]]-> + unpack_border(n,first,&buf[m]); +} + +/* ---------------------------------------------------------------------- + pack data for atom I for sending to another proc + xyz must be 1st 3 values, so comm::exchange() can test on them +------------------------------------------------------------------------- */ + +int AtomVecTDPD::pack_exchange(int i, double *buf) +{ + int m = 1; + buf[m++] = x[i][0]; + buf[m++] = x[i][1]; + buf[m++] = x[i][2]; + buf[m++] = v[i][0]; + buf[m++] = v[i][1]; + buf[m++] = v[i][2]; + buf[m++] = ubuf(tag[i]).d; + buf[m++] = ubuf(type[i]).d; + buf[m++] = ubuf(mask[i]).d; + buf[m++] = ubuf(image[i]).d; + for(int k = 0; k < cc_species; k++) + buf[m++] = cc[i][k]; + + buf[m++] = vest[i][0]; + buf[m++] = vest[i][1]; + buf[m++] = vest[i][2]; + + if (atom->nextra_grow) + for (int iextra = 0; iextra < atom->nextra_grow; iextra++) + m += modify->fix[atom->extra_grow[iextra]]->pack_exchange(i,&buf[m]); + + buf[0] = m; + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecTDPD::unpack_exchange(double *buf) +{ + int nlocal = atom->nlocal; + if (nlocal == nmax) grow(0); + + int m = 1; + x[nlocal][0] = buf[m++]; + x[nlocal][1] = buf[m++]; + x[nlocal][2] = buf[m++]; + v[nlocal][0] = buf[m++]; + v[nlocal][1] = buf[m++]; + v[nlocal][2] = buf[m++]; + tag[nlocal] = (tagint) ubuf(buf[m++]).i; + type[nlocal] = (int) ubuf(buf[m++]).i; + mask[nlocal] = (int) ubuf(buf[m++]).i; + image[nlocal] = (imageint) ubuf(buf[m++]).i; + for(int k = 0; k < cc_species; k++) + cc[nlocal][k] = buf[m++]; + + vest[nlocal][0] = buf[m++]; + vest[nlocal][1] = buf[m++]; + vest[nlocal][2] = buf[m++]; + + if (atom->nextra_grow) + for (int iextra = 0; iextra < atom->nextra_grow; iextra++) + m += modify->fix[atom->extra_grow[iextra]]-> + unpack_exchange(nlocal,&buf[m]); + + atom->nlocal++; + return m; +} + +/* ---------------------------------------------------------------------- + size of restart data for all atoms owned by this proc + include extra data stored by fixes +------------------------------------------------------------------------- */ + +int AtomVecTDPD::size_restart() +{ + int i; + + int nlocal = atom->nlocal; + int n = (11 + cc_species + 3) * nlocal; // 11 + cc[i] + vest[3] + + if (atom->nextra_restart) + for (int iextra = 0; iextra < atom->nextra_restart; iextra++) + for (i = 0; i < nlocal; i++) + n += modify->fix[atom->extra_restart[iextra]]->size_restart(i); + + return n; +} + +/* ---------------------------------------------------------------------- + pack atom I's data for restart file including extra quantities + xyz must be 1st 3 values, so that read_restart can test on them + molecular types may be negative, but write as positive +------------------------------------------------------------------------- */ + +int AtomVecTDPD::pack_restart(int i, double *buf) +{ + int m = 1; + buf[m++] = x[i][0]; + buf[m++] = x[i][1]; + buf[m++] = x[i][2]; + buf[m++] = ubuf(tag[i]).d; + buf[m++] = ubuf(type[i]).d; + buf[m++] = ubuf(mask[i]).d; + buf[m++] = ubuf(image[i]).d; + buf[m++] = v[i][0]; + buf[m++] = v[i][1]; + buf[m++] = v[i][2]; + for(int k = 0; k < cc_species; k++) + buf[m++] = cc[i][k]; + + buf[m++] = vest[i][0]; + buf[m++] = vest[i][1]; + buf[m++] = vest[i][2]; + + if (atom->nextra_restart) + for (int iextra = 0; iextra < atom->nextra_restart; iextra++) + m += modify->fix[atom->extra_restart[iextra]]->pack_restart(i,&buf[m]); + + buf[0] = m; + return m; +} + +/* ---------------------------------------------------------------------- + unpack data for one atom from restart file including extra quantities +------------------------------------------------------------------------- */ + +int AtomVecTDPD::unpack_restart(double *buf) +{ + int nlocal = atom->nlocal; + if (nlocal == nmax) { + grow(0); + if (atom->nextra_store) + memory->grow(atom->extra,nmax,atom->nextra_store,"atom:extra"); + } + + int m = 1; + x[nlocal][0] = buf[m++]; + x[nlocal][1] = buf[m++]; + x[nlocal][2] = buf[m++]; + tag[nlocal] = (tagint) ubuf(buf[m++]).i; + type[nlocal] = (int) ubuf(buf[m++]).i; + mask[nlocal] = (int) ubuf(buf[m++]).i; + image[nlocal] = (imageint) ubuf(buf[m++]).i; + v[nlocal][0] = buf[m++]; + v[nlocal][1] = buf[m++]; + v[nlocal][2] = buf[m++]; + for(int k = 0; k < cc_species; k++) + cc[nlocal][k] = buf[m++]; + + vest[nlocal][0] = buf[m++]; + vest[nlocal][1] = buf[m++]; + vest[nlocal][2] = buf[m++]; + + double **extra = atom->extra; + if (atom->nextra_store) { + int size = static_cast (buf[0]) - m; + for (int i = 0; i < size; i++) extra[nlocal][i] = buf[m++]; + } + + atom->nlocal++; + return m; +} + +/* ---------------------------------------------------------------------- + create one atom of itype at coord + set other values to defaults +------------------------------------------------------------------------- */ + +void AtomVecTDPD::create_atom(int itype, double *coord) +{ + int nlocal = atom->nlocal; + if (nlocal == nmax) grow(0); + + tag[nlocal] = 0; + type[nlocal] = itype; + x[nlocal][0] = coord[0]; + x[nlocal][1] = coord[1]; + x[nlocal][2] = coord[2]; + mask[nlocal] = 1; + image[nlocal] = ((imageint) IMGMAX << IMG2BITS) | + ((imageint) IMGMAX << IMGBITS) | IMGMAX; + v[nlocal][0] = 0.0; + v[nlocal][1] = 0.0; + v[nlocal][2] = 0.0; + + for(int k = 0; k < cc_species; k++) + cc[nlocal][k] = 0.0; + + vest[nlocal][0] = 0.0; + vest[nlocal][1] = 0.0; + vest[nlocal][2] = 0.0; + + atom->nlocal++; +} + +/* ---------------------------------------------------------------------- + unpack one line from Atoms section of data file + initialize other atom quantities +------------------------------------------------------------------------- */ + +void AtomVecTDPD::data_atom(double *coord, imageint imagetmp, char **values) +{ + int nlocal = atom->nlocal; + if (nlocal == nmax) grow(0); + + tag[nlocal] = ATOTAGINT(values[0]); + type[nlocal] = atoi(values[1]); + if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes) + error->one(FLERR,"Invalid atom type in Atoms section of data file"); + + x[nlocal][0] = coord[0]; + x[nlocal][1] = coord[1]; + x[nlocal][2] = coord[2]; + + for(int k = 0; k < cc_species; k++) + cc[nlocal][k] = atof( values[5+k] ); + + image[nlocal] = imagetmp; + + mask[nlocal] = 1; + v[nlocal][0] = 0.0; + v[nlocal][1] = 0.0; + v[nlocal][2] = 0.0; + + vest[nlocal][0] = 0.0; + vest[nlocal][1] = 0.0; + vest[nlocal][2] = 0.0; + + atom->nlocal++; +} + +/* ---------------------------------------------------------------------- + pack atom info for data file including 3 image flags +------------------------------------------------------------------------- */ + +void AtomVecTDPD::pack_data(double **buf) +{ + int nlocal = atom->nlocal; + for (int i = 0; i < nlocal; i++) { + buf[i][0] = ubuf(tag[i]).d; + buf[i][1] = ubuf(type[i]).d; + buf[i][2] = x[i][0]; + buf[i][3] = x[i][1]; + buf[i][4] = x[i][2]; + buf[i][5] = ubuf((image[i] & IMGMASK) - IMGMAX).d; + buf[i][6] = ubuf((image[i] >> IMGBITS & IMGMASK) - IMGMAX).d; + buf[i][7] = ubuf((image[i] >> IMG2BITS) - IMGMAX).d; + for(int k = 0; k < cc_species; k++) + buf[i][8+k] = cc[i][k]; + } +} + +/* ---------------------------------------------------------------------- + write atom info to data file including 3 image flags +------------------------------------------------------------------------- */ + +void AtomVecTDPD::write_data(FILE *fp, int n, double **buf) +{ + for (int i = 0; i < n; i++){ + fprintf(fp,TAGINT_FORMAT " %d %-1.16e %-1.16e %-1.16e %d %d %d", + (tagint) ubuf(buf[i][0]).i,(int) ubuf(buf[i][1]).i, + buf[i][2],buf[i][3],buf[i][4], + (int) ubuf(buf[i][5]).i,(int) ubuf(buf[i][6]).i, + (int) ubuf(buf[i][7]).i); + for(int k = 0; k < cc_species; k++) + fprintf(fp,TAGINT_FORMAT " %-1.16e",buf[i][8+k]); + fprintf(fp,TAGINT_FORMAT "\n"); + } +} + +/* ---------------------------------------------------------------------- + return # of bytes of allocated memory +------------------------------------------------------------------------- */ + +bigint AtomVecTDPD::memory_usage() +{ + bigint bytes = 0; + + if (atom->memcheck("tag")) bytes += memory->usage(tag,nmax); + if (atom->memcheck("type")) bytes += memory->usage(type,nmax); + if (atom->memcheck("mask")) bytes += memory->usage(mask,nmax); + if (atom->memcheck("image")) bytes += memory->usage(image,nmax); + if (atom->memcheck("x")) bytes += memory->usage(x,nmax,3); + if (atom->memcheck("v")) bytes += memory->usage(v,nmax,3); + if (atom->memcheck("f")) bytes += memory->usage(f,nmax*comm->nthreads,3); + if (atom->memcheck("cc")) bytes += memory->usage(cc,nmax*comm->nthreads,cc_species); + if (atom->memcheck("cc_flux")) bytes += memory->usage(cc_flux,nmax*comm->nthreads,cc_species); + if (atom->memcheck("vest")) bytes += memory->usage(vest, nmax); + + return bytes; +} diff --git a/src/USER-MESO/atom_vec_tdpd.h b/src/USER-MESO/atom_vec_tdpd.h new file mode 100644 index 0000000000..86e9ae4bb8 --- /dev/null +++ b/src/USER-MESO/atom_vec_tdpd.h @@ -0,0 +1,83 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef ATOM_CLASS + +AtomStyle(tdpd,AtomVecTDPD) + +#else + +#ifndef LMP_ATOM_VEC_TDPD_H +#define LMP_ATOM_VEC_TDPD_H + +#include "atom_vec.h" + +namespace LAMMPS_NS { + +class AtomVecTDPD : public AtomVec { + public: + AtomVecTDPD(class LAMMPS *); + virtual ~AtomVecTDPD() {} + void process_args(int, char **); + void grow(int); + void grow_reset(); + void copy(int, int, int); + void force_clear(int, size_t); + virtual int pack_comm(int, int *, double *, int, int *); + virtual int pack_comm_vel(int, int *, double *, int, int *); + virtual void unpack_comm(int, int, double *); + virtual void unpack_comm_vel(int, int, double *); + int pack_reverse(int, int, double *); + void unpack_reverse(int, int *, double *); + virtual int pack_border(int, int *, double *, int, int *); + virtual int pack_border_vel(int, int *, double *, int, int *); + virtual void unpack_border(int, int, double *); + virtual void unpack_border_vel(int, int, double *); + virtual int pack_exchange(int, double *); + virtual int unpack_exchange(double *); + int size_restart(); + int pack_restart(int, double *); + int unpack_restart(double *); + void create_atom(int, double *); + void data_atom(double *, imageint, char **); + void pack_data(double **); + void write_data(FILE *, int, double **); + bigint memory_usage(); + + protected: + tagint *tag; + int *type,*mask; + imageint *image; + double **x,**v,**f; + double **vest; // store intermediate velocity for using mvv integrator + double **cc,**cc_flux; + int cc_species; +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +E: Per-processor system is too big + +The number of owned atoms plus ghost atoms on a single +processor must fit in 32-bit integer. + +E: Invalid atom type in Atoms section of data file + +Atom types must range from 1 to specified # of types. + +*/ diff --git a/src/USER-MESO/compute_edpd_temp_atom.cpp b/src/USER-MESO/compute_edpd_temp_atom.cpp new file mode 100644 index 0000000000..15fdab2a69 --- /dev/null +++ b/src/USER-MESO/compute_edpd_temp_atom.cpp @@ -0,0 +1,97 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include +#include "compute_edpd_temp_atom.h" +#include "atom.h" +#include "update.h" +#include "modify.h" +#include "comm.h" +#include "force.h" +#include "memory.h" +#include "error.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +ComputeEDPDTempAtom::ComputeEDPDTempAtom(LAMMPS *lmp, int narg, char **arg) : + Compute(lmp, narg, arg) +{ + if (narg != 3) error->all(FLERR,"Number of arguments for compute edpd/temp/atom command != 3"); + if (atom->edpd_flag != 1) error->all(FLERR,"compute edpd/temp/atom command requires atom_style with temperature (e.g. edpd)"); + + peratom_flag = 1; + size_peratom_cols = 0; + + nmax = 0; + temp_vector = NULL; +} + +/* ---------------------------------------------------------------------- */ + +ComputeEDPDTempAtom::~ComputeEDPDTempAtom() +{ + memory->sfree(temp_vector); +} + +/* ---------------------------------------------------------------------- */ + +void ComputeEDPDTempAtom::init() +{ + + int count = 0; + for (int i = 0; i < modify->ncompute; i++) + if (strcmp(modify->compute[i]->style,"temp_vector/atom") == 0) count++; + if (count > 1 && comm->me == 0) + error->warning(FLERR,"More than one compute temp_vector/atom"); +} + +/* ---------------------------------------------------------------------- */ + +void ComputeEDPDTempAtom::compute_peratom() +{ + invoked_peratom = update->ntimestep; + + // grow temp_vector array if necessary + + if (atom->nmax > nmax) { + memory->sfree(temp_vector); + nmax = atom->nmax; + temp_vector = (double *) memory->smalloc(nmax*sizeof(double),"temp_vector/atom:temp_vector"); + vector_atom = temp_vector; + } + + double *edpd_temp = atom->edpd_temp; + int *mask = atom->mask; + int nlocal = atom->nlocal; + + for (int i = 0; i < nlocal; i++) { + if (mask[i] & groupbit) { + temp_vector[i] = edpd_temp[i]; + } + else { + temp_vector[i] = 0.0; + } + } +} + +/* ---------------------------------------------------------------------- + memory usage of local atom-based array +------------------------------------------------------------------------- */ + +double ComputeEDPDTempAtom::memory_usage() +{ + double bytes = nmax * sizeof(double); + return bytes; +} diff --git a/src/USER-MESO/compute_edpd_temp_atom.h b/src/USER-MESO/compute_edpd_temp_atom.h new file mode 100644 index 0000000000..4c61b664cc --- /dev/null +++ b/src/USER-MESO/compute_edpd_temp_atom.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef COMPUTE_CLASS + +ComputeStyle(edpd/temp/atom,ComputeEDPDTempAtom) + +#else + +#ifndef LMP_COMPUTE_EDPD_TEMP_ATOM_H +#define LMP_COMPUTE_EDPD_TEMP_ATOM_H + +#include "compute.h" + +namespace LAMMPS_NS { + +class ComputeEDPDTempAtom : public Compute { + public: + ComputeEDPDTempAtom(class LAMMPS *, int, char **); + ~ComputeEDPDTempAtom(); + void init(); + void compute_peratom(); + double memory_usage(); + + private: + int nmax; + double *temp_vector; +}; + +} + +#endif +#endif diff --git a/src/USER-MESO/compute_tdpd_cc_atom.cpp b/src/USER-MESO/compute_tdpd_cc_atom.cpp new file mode 100644 index 0000000000..b33550f5c1 --- /dev/null +++ b/src/USER-MESO/compute_tdpd_cc_atom.cpp @@ -0,0 +1,98 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include +#include "compute_tdpd_cc_atom.h" +#include "atom.h" +#include "update.h" +#include "modify.h" +#include "comm.h" +#include "force.h" +#include "memory.h" +#include "error.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +ComputeTDPDCCAtom::ComputeTDPDCCAtom(LAMMPS *lmp, int narg, char **arg) : + Compute(lmp, narg, arg) +{ + if (narg != 4) error->all(FLERR,"Number of arguments for compute tdpd/cc/atom command != 4"); + if (atom->tdpd_flag != 1) error->all(FLERR,"compute tdpd/cc/atom command requires atom_style with concentration (e.g. tdpd)"); + + index = force->inumeric(FLERR,arg[3]); + + peratom_flag = 1; + size_peratom_cols = 0; + + nmax = 0; + cc_vector = NULL; +} + +/* ---------------------------------------------------------------------- */ + +ComputeTDPDCCAtom::~ComputeTDPDCCAtom() +{ + memory->sfree(cc_vector); +} + +/* ---------------------------------------------------------------------- */ + +void ComputeTDPDCCAtom::init() +{ + + int count = 0; + for (int i = 0; i < modify->ncompute; i++) + if (strcmp(modify->compute[i]->style,"cc_vector/atom") == 0) count++; + if (count > 1 && comm->me == 0) + error->warning(FLERR,"More than one compute cc_vector/atom"); +} + +/* ---------------------------------------------------------------------- */ + +void ComputeTDPDCCAtom::compute_peratom() +{ + invoked_peratom = update->ntimestep; + + // grow cc_vector array if necessary + + if (atom->nmax > nmax) { + memory->sfree(cc_vector); + nmax = atom->nmax; + cc_vector = (double *) memory->smalloc(nmax*sizeof(double),"cc_vector/atom:cc_vector"); + vector_atom = cc_vector; + } + + double **cc = atom->cc; + int *mask = atom->mask; + int nlocal = atom->nlocal; + + for (int i = 0; i < nlocal; i++) { + if (mask[i] & groupbit) { + cc_vector[i] = cc[i][index-1]; + } + else + cc_vector[i] = 0.0; + } +} + +/* ---------------------------------------------------------------------- + memory usage of local atom-based array +------------------------------------------------------------------------- */ + +double ComputeTDPDCCAtom::memory_usage() +{ + double bytes = nmax * sizeof(double); + return bytes; +} diff --git a/src/USER-MESO/compute_tdpd_cc_atom.h b/src/USER-MESO/compute_tdpd_cc_atom.h new file mode 100644 index 0000000000..324cb779a4 --- /dev/null +++ b/src/USER-MESO/compute_tdpd_cc_atom.h @@ -0,0 +1,44 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef COMPUTE_CLASS + +ComputeStyle(tdpd/cc/atom,ComputeTDPDCCAtom) + +#else + +#ifndef LMP_COMPUTE_TDPD_CC_ATOM_H +#define LMP_COMPUTE_TDPD_CC_ATOM_H + +#include "compute.h" + +namespace LAMMPS_NS { + +class ComputeTDPDCCAtom : public Compute { + public: + ComputeTDPDCCAtom(class LAMMPS *, int, char **); + ~ComputeTDPDCCAtom(); + void init(); + void compute_peratom(); + double memory_usage(); + + private: + int nmax; + int index; + double *cc_vector; +}; + +} + +#endif +#endif diff --git a/src/USER-MESO/fix_edpd_source.cpp b/src/USER-MESO/fix_edpd_source.cpp new file mode 100644 index 0000000000..3ee7e8e291 --- /dev/null +++ b/src/USER-MESO/fix_edpd_source.cpp @@ -0,0 +1,120 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include +#include +#include "fix_edpd_source.h" +#include "atom.h" +#include "comm.h" +#include "update.h" +#include "modify.h" +#include "domain.h" +#include "lattice.h" +#include "input.h" +#include "variable.h" +#include "error.h" +#include "force.h" + +using namespace LAMMPS_NS; +using namespace FixConst; + +/* ---------------------------------------------------------------------- */ + +FixEDPDSource::FixEDPDSource(LAMMPS *lmp, int narg, char **arg) : + Fix(lmp, narg, arg) +{ + if (strcmp(style,"edpd/source") != 0 && narg < 4) + error->all(FLERR,"Illegal fix edpd/source command"); + + int iarg = 3; + + if (strcmp(arg[iarg],"sphere") == 0) option = 0; + else if (strcmp(arg[iarg],"cuboid") == 0) option = 1; + else error->all(FLERR,"Illegal fix edpd/source command"); + iarg++; + + if(option == 0){ + if (narg != 9 ) error->all(FLERR,"Illegal fix edpd/source command (5 args for sphere)"); + center[0] = force->numeric(FLERR,arg[iarg++]); + center[1] = force->numeric(FLERR,arg[iarg++]); + center[2] = force->numeric(FLERR,arg[iarg++]); + radius = force->numeric(FLERR,arg[iarg++]); + value = force->numeric(FLERR,arg[iarg++]); + } + else if(option == 1){ + if (narg != 11 ) error->all(FLERR,"Illegal fix edpd/edpd command (7 args for cuboid)"); + center[0] = force->numeric(FLERR,arg[iarg++]); + center[1] = force->numeric(FLERR,arg[iarg++]); + center[2] = force->numeric(FLERR,arg[iarg++]); + dLx = force->numeric(FLERR,arg[iarg++]); + dLy = force->numeric(FLERR,arg[iarg++]); + dLz = force->numeric(FLERR,arg[iarg++]); + value = force->numeric(FLERR,arg[iarg++]); + } + else error->all(FLERR,"Illegal fix edpd/source command"); +} + +/* ---------------------------------------------------------------------- */ + +FixEDPDSource::~FixEDPDSource() +{ +} + +/* ---------------------------------------------------------------------- */ + +int FixEDPDSource::setmask() +{ + int mask = 0; + mask |= POST_FORCE; + return mask; +} + +/* ---------------------------------------------------------------------- */ + +void FixEDPDSource::init() +{ +} + +/* ---------------------------------------------------------------------- */ + +void FixEDPDSource::post_force(int vflag) +{ + double **x = atom->x; + double *edpd_flux = atom->edpd_flux; + double *edpd_cv = atom->edpd_cv; + int *mask = atom->mask; + int nlocal = atom->nlocal; + + double drx, dry, drz, rsq; + double radius_sq = radius*radius*radius; + + for (int i = 0; i < nlocal; i++) { + if (mask[i] & groupbit) { + if(option == 0){ + drx = x[i][0] - center[0]; + dry = x[i][1] - center[1]; + drz = x[i][2] - center[2]; + rsq = drx*drx + dry*dry + drz*drz; + if(rsq < radius_sq) + edpd_flux[i] += value*edpd_cv[i]; + } + else if(option == 1){ + drx = x[i][0] - center[0]; + dry = x[i][1] - center[1]; + drz = x[i][2] - center[2]; + if(abs(drx) <= 0.5*dLx && abs(dry) <= 0.5*dLy && abs(drz) <= 0.5*dLz) + edpd_flux[i] += value*edpd_cv[i]; + } + } + } +} diff --git a/src/USER-MESO/fix_edpd_source.h b/src/USER-MESO/fix_edpd_source.h new file mode 100644 index 0000000000..1ea8610ce9 --- /dev/null +++ b/src/USER-MESO/fix_edpd_source.h @@ -0,0 +1,44 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef FIX_CLASS + +FixStyle(edpd/source,FixEDPDSource) + +#else + +#ifndef LMP_FIX_EDPDSOURCE_H +#define LMP_FIX_EDPDSOURCE_H + +#include "fix.h" + +namespace LAMMPS_NS { + +class FixEDPDSource : public Fix { + public: + FixEDPDSource(class LAMMPS *, int, char **); + ~FixEDPDSource(); + int setmask(); + void init(); + void post_force(int); + + protected: + int option; + double center[3], radius, dLx, dLy, dLz; + double value; +}; + +} + +#endif +#endif diff --git a/src/USER-MESO/fix_mvv_dpd.cpp b/src/USER-MESO/fix_mvv_dpd.cpp new file mode 100644 index 0000000000..77a67273f6 --- /dev/null +++ b/src/USER-MESO/fix_mvv_dpd.cpp @@ -0,0 +1,136 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + This is a time integrator for position and velocity (x and v) using the + modified velocity-Verlet (MVV) algorithm. + Setting verlet = 0.5 recovers the standard velocity-Verlet algorithm. + + Contributing author: Zhen Li (Brown University) + Email: zhen_li@brown.edu +------------------------------------------------------------------------- */ + +#include +#include +#include "fix_mvv_dpd.h" +#include "atom.h" +#include "force.h" +#include "update.h" +#include "respa.h" +#include "error.h" + +using namespace LAMMPS_NS; +using namespace FixConst; + +/* ---------------------------------------------------------------------- */ + +FixMvvDPD::FixMvvDPD(LAMMPS *lmp, int narg, char **arg) : + Fix(lmp, narg, arg) +{ + if (strcmp(style,"mvv/dpd") != 0 && narg < 3) + error->all(FLERR,"Illegal fix mvv/dpd command"); + + verlet = 0.5; + if(narg > 3) verlet = force->numeric(FLERR,arg[3]); + + dynamic_group_allow = 1; + time_integrate = 1; +} + +/* ---------------------------------------------------------------------- */ + +int FixMvvDPD::setmask() +{ + int mask = 0; + mask |= INITIAL_INTEGRATE; + mask |= FINAL_INTEGRATE; + return mask; +} + +/* ---------------------------------------------------------------------- */ + +void FixMvvDPD::init() +{ + dtv = update->dt; + dtf = 0.5 * update->dt * force->ftm2v; +} + +/* ---------------------------------------------------------------------- + allow for both per-type and per-atom mass +------------------------------------------------------------------------- */ + +void FixMvvDPD::initial_integrate(int vflag) +{ + double dtfm; + double **x = atom->x; + double **v = atom->v; + double **f = atom->f; + double **vest = atom->vest; + double *rmass = atom->rmass; + double *mass = atom->mass; + int *type = atom->type; + int *mask = atom->mask; + int nlocal = atom->nlocal; + if (igroup == atom->firstgroup) nlocal = atom->nfirst; + + for (int i = 0; i < nlocal; i++) + if (mask[i] & groupbit) { + if (rmass) dtfm = dtf / rmass[i]; + else dtfm = dtf / mass[type[i]]; + + vest[i][0] = v[i][0] + dtfm * f[i][0]; + vest[i][1] = v[i][1] + dtfm * f[i][1]; + vest[i][2] = v[i][2] + dtfm * f[i][2]; + + x[i][0] += dtv * vest[i][0]; + x[i][1] += dtv * vest[i][1]; + x[i][2] += dtv * vest[i][2]; + v[i][0] += 2.0 * verlet * dtfm * f[i][0]; + v[i][1] += 2.0 * verlet * dtfm * f[i][1]; + v[i][2] += 2.0 * verlet * dtfm * f[i][2]; + } +} + +/* ---------------------------------------------------------------------- */ + +void FixMvvDPD::final_integrate() +{ + double dtfm; + double **v = atom->v; + double **f = atom->f; + double **vest = atom->vest; + double *rmass = atom->rmass; + double *mass = atom->mass; + int *type = atom->type; + int *mask = atom->mask; + int nlocal = atom->nlocal; + if (igroup == atom->firstgroup) nlocal = atom->nfirst; + + for (int i = 0; i < nlocal; i++) + if (mask[i] & groupbit) { + if (rmass) dtfm = dtf / rmass[i]; + else dtfm = dtf / mass[type[i]]; + + v[i][0] = vest[i][0] + dtfm * f[i][0]; + v[i][1] = vest[i][1] + dtfm * f[i][1]; + v[i][2] = vest[i][2] + dtfm * f[i][2]; + } +} + +/* ---------------------------------------------------------------------- */ + +void FixMvvDPD::reset_dt() +{ + dtv = update->dt; + dtf = 0.5 * update->dt * force->ftm2v; +} diff --git a/src/USER-MESO/fix_mvv_dpd.h b/src/USER-MESO/fix_mvv_dpd.h new file mode 100644 index 0000000000..86cc79485f --- /dev/null +++ b/src/USER-MESO/fix_mvv_dpd.h @@ -0,0 +1,45 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef FIX_CLASS + +FixStyle(mvv/dpd,FixMvvDPD) + +#else + +#ifndef LMP_FIX_MVV_DPD_H +#define LMP_FIX_MVV_DPD_H + +#include "fix.h" + +namespace LAMMPS_NS { + +class FixMvvDPD : public Fix { + public: + FixMvvDPD(class LAMMPS *, int, char **); + virtual ~FixMvvDPD() {} + int setmask(); + virtual void init(); + virtual void initial_integrate(int); + virtual void final_integrate(); + virtual void reset_dt(); + + protected: + double dtv, dtf; + double verlet; +}; + +} + +#endif +#endif diff --git a/src/USER-MESO/fix_mvv_edpd.cpp b/src/USER-MESO/fix_mvv_edpd.cpp new file mode 100644 index 0000000000..fe801d6d36 --- /dev/null +++ b/src/USER-MESO/fix_mvv_edpd.cpp @@ -0,0 +1,163 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + This is a time integrator for position, velocity and temperature (x, + v and edpd_T) using the modified velocity-Verlet (MVV) algorithm. + Setting verlet = 0.5 recovers the standard velocity-Verlet algorithm. + + Contributing author: Zhen Li (Brown University) + Email: zhen_li@brown.edu + + Please cite the related publication: + Z. Li, Y.-H. Tang, H. Lei, B. Caswell and G.E. Karniadakis. "Energy- + conserving dissipative particle dynamics with temperature-dependent + properties". Journal of Computational Physics, 2014, 265: 113-127. + + Z. Li, Y.-H. Tang , X. Li and G.E. Karniadakis. "Mesoscale modeling of + phase transition dynamics of thermoresponsive polymers". Chemical + Communications, 2015, 51: 11038-11040. +------------------------------------------------------------------------- */ + +#include +#include +#include "fix_mvv_edpd.h" +#include "atom.h" +#include "force.h" +#include "update.h" +#include "respa.h" +#include "error.h" + +using namespace LAMMPS_NS; +using namespace FixConst; + +/* ---------------------------------------------------------------------- */ + +FixMvvEDPD::FixMvvEDPD(LAMMPS *lmp, int narg, char **arg) : + Fix(lmp, narg, arg) +{ + if (strcmp(style,"mvv/edpd") != 0 && narg < 3) + error->all(FLERR,"Illegal fix mvv/edpd command"); + + verlet = 0.5; + if(narg > 3) verlet = force->numeric(FLERR,arg[3]); + + dynamic_group_allow = 1; + time_integrate = 1; +} + +/* ---------------------------------------------------------------------- */ + +int FixMvvEDPD::setmask() +{ + int mask = 0; + mask |= INITIAL_INTEGRATE; + mask |= FINAL_INTEGRATE; + return mask; +} + +/* ---------------------------------------------------------------------- */ + +void FixMvvEDPD::init() +{ + dtv = update->dt; + dtf = 0.5 * update->dt * force->ftm2v; +} + +/* ---------------------------------------------------------------------- + allow for both per-type and per-atom mass +------------------------------------------------------------------------- */ + +void FixMvvEDPD::initial_integrate(int vflag) +{ + double dtfm,dtT; + // update v and x and cc of atoms in group + + double **x = atom->x; + double **v = atom->v; + double **f = atom->f; + double *edpd_temp = atom->edpd_temp; + double *edpd_flux = atom->edpd_flux; + double *edpd_cv = atom->edpd_cv; + double **vest = atom->vest; + double *rmass = atom->rmass; + double *mass = atom->mass; + int *type = atom->type; + int *mask = atom->mask; + int nlocal = atom->nlocal; + if (igroup == atom->firstgroup) nlocal = atom->nfirst; + + for (int i = 0; i < nlocal; i++) + if (mask[i] & groupbit) { + if (rmass) dtfm = dtf / rmass[i]; + else dtfm = dtf / mass[type[i]]; + + dtT = 0.5 * dtv / edpd_cv[i]; + + vest[i][0] = v[i][0] + dtfm * f[i][0]; + vest[i][1] = v[i][1] + dtfm * f[i][1]; + vest[i][2] = v[i][2] + dtfm * f[i][2]; + vest[i][3] = edpd_temp[i] + dtT * edpd_flux[i]; + + x[i][0] += dtv * vest[i][0]; + x[i][1] += dtv * vest[i][1]; + x[i][2] += dtv * vest[i][2]; + v[i][0] += 2.0 * verlet * dtfm * f[i][0]; + v[i][1] += 2.0 * verlet * dtfm * f[i][1]; + v[i][2] += 2.0 * verlet * dtfm * f[i][2]; + edpd_temp[i] += 2.0 * verlet * dtT * edpd_flux[i]; + } +} + +/* ---------------------------------------------------------------------- */ + +void FixMvvEDPD::final_integrate() +{ + double dtfm, dtT; + + // update v and edpd_temp of atoms in group + + double **v = atom->v; + double **f = atom->f; + double *edpd_temp = atom->edpd_temp; + double *edpd_flux = atom->edpd_flux; + double *edpd_cv = atom->edpd_cv; + double **vest = atom->vest; + double *rmass = atom->rmass; + double *mass = atom->mass; + int *type = atom->type; + int *mask = atom->mask; + int nlocal = atom->nlocal; + if (igroup == atom->firstgroup) nlocal = atom->nfirst; + + for (int i = 0; i < nlocal; i++) + if (mask[i] & groupbit) { + if (rmass) dtfm = dtf / rmass[i]; + else dtfm = dtf / mass[type[i]]; + + dtT = 0.5 * dtv / edpd_cv[i]; + + v[i][0] = vest[i][0] + dtfm * f[i][0]; + v[i][1] = vest[i][1] + dtfm * f[i][1]; + v[i][2] = vest[i][2] + dtfm * f[i][2]; + edpd_temp[i] = vest[i][3] + dtT * edpd_flux[i]; + } +} + +/* ---------------------------------------------------------------------- */ + +void FixMvvEDPD::reset_dt() +{ + dtv = update->dt; + dtf = 0.5 * update->dt * force->ftm2v; +} diff --git a/src/USER-MESO/fix_mvv_edpd.h b/src/USER-MESO/fix_mvv_edpd.h new file mode 100644 index 0000000000..0d9c5f195a --- /dev/null +++ b/src/USER-MESO/fix_mvv_edpd.h @@ -0,0 +1,45 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef FIX_CLASS + +FixStyle(mvv/edpd,FixMvvEDPD) + +#else + +#ifndef LMP_FIX_MVV_EDPD_H +#define LMP_FIX_MVV_EDPD_H + +#include "fix.h" + +namespace LAMMPS_NS { + +class FixMvvEDPD : public Fix { + public: + FixMvvEDPD(class LAMMPS *, int, char **); + virtual ~FixMvvEDPD() {} + int setmask(); + virtual void init(); + virtual void initial_integrate(int); + virtual void final_integrate(); + virtual void reset_dt(); + + protected: + double dtv, dtf; + double verlet; +}; + +} + +#endif +#endif diff --git a/src/USER-MESO/fix_mvv_tdpd.cpp b/src/USER-MESO/fix_mvv_tdpd.cpp new file mode 100644 index 0000000000..382ce9033a --- /dev/null +++ b/src/USER-MESO/fix_mvv_tdpd.cpp @@ -0,0 +1,156 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + This is a time integrator for position, velocity and concentration (x, + v and cc) using the modified velocity-Verlet (MVV) algorithm. + Setting verlet = 0.5 recovers the standard velocity-Verlet algorithm. + + Contributing author: Zhen Li (Brown University) + Email: zhen_li@brown.edu + + Please cite the related publication: + Z. Li, A. Yazdani, A. Tartakovsky and G.E. Karniadakis. "Transport + dissipative particle dynamics model for mesoscopic advection-diffusion + -reaction problems". The Journal of Chemical Physics, 2015, 143: 014101. +------------------------------------------------------------------------- */ + +#include +#include +#include "fix_mvv_tdpd.h" +#include "atom.h" +#include "force.h" +#include "update.h" +#include "respa.h" +#include "error.h" + +using namespace LAMMPS_NS; +using namespace FixConst; + +/* ---------------------------------------------------------------------- */ + +FixMvvTDPD::FixMvvTDPD(LAMMPS *lmp, int narg, char **arg) : + Fix(lmp, narg, arg) +{ + if (strcmp(style,"tdpd/verlet") != 0 && narg < 3) + error->all(FLERR,"Illegal fix mvv/tdpd command"); + + verlet = 0.5; + if(narg > 3) verlet = force->numeric(FLERR,arg[3]); + + cc_species = atom->cc_species; + + dynamic_group_allow = 1; + time_integrate = 1; +} + +/* ---------------------------------------------------------------------- */ + +int FixMvvTDPD::setmask() +{ + int mask = 0; + mask |= INITIAL_INTEGRATE; + mask |= FINAL_INTEGRATE; + return mask; +} + +/* ---------------------------------------------------------------------- */ + +void FixMvvTDPD::init() +{ + dtv = update->dt; + dtf = 0.5 * update->dt * force->ftm2v; +} + +/* ---------------------------------------------------------------------- + allow for both per-type and per-atom mass +------------------------------------------------------------------------- */ + +void FixMvvTDPD::initial_integrate(int vflag) +{ + double dtfm; + // update v and x and cc of atoms in group + + double **x = atom->x; + double **v = atom->v; + double **f = atom->f; + double **cc = atom->cc; + double **cc_flux = atom->cc_flux; + double **vest = atom->vest; + double *rmass = atom->rmass; + double *mass = atom->mass; + int *type = atom->type; + int *mask = atom->mask; + int nlocal = atom->nlocal; + if (igroup == atom->firstgroup) nlocal = atom->nfirst; + + for (int i = 0; i < nlocal; i++) + if (mask[i] & groupbit) { + if (rmass) dtfm = dtf / rmass[i]; + else dtfm = dtf / mass[type[i]]; + + vest[i][0] = v[i][0] + dtfm * f[i][0]; + vest[i][1] = v[i][1] + dtfm * f[i][1]; + vest[i][2] = v[i][2] + dtfm * f[i][2]; + + x[i][0] += dtv * vest[i][0]; + x[i][1] += dtv * vest[i][1]; + x[i][2] += dtv * vest[i][2]; + v[i][0] += 2.0 * verlet * dtfm * f[i][0]; + v[i][1] += 2.0 * verlet * dtfm * f[i][1]; + v[i][2] += 2.0 * verlet * dtfm * f[i][2]; + for(int k = 0; k < cc_species; k++) + cc[i][k] += 0.5 * dtv * cc_flux[i][k]; + } +} + +/* ---------------------------------------------------------------------- */ + +void FixMvvTDPD::final_integrate() +{ + double dtfm; + + // update v of atoms in group + + double **v = atom->v; + double **f = atom->f; + double **cc = atom->cc; + double **cc_flux = atom->cc_flux; + double **vest = atom->vest; + double *rmass = atom->rmass; + double *mass = atom->mass; + int *type = atom->type; + int *mask = atom->mask; + int nlocal = atom->nlocal; + if (igroup == atom->firstgroup) nlocal = atom->nfirst; + + for (int i = 0; i < nlocal; i++) + if (mask[i] & groupbit) { + if (rmass) dtfm = dtf / rmass[i]; + else dtfm = dtf / mass[type[i]]; + + v[i][0] = vest[i][0] + dtfm * f[i][0]; + v[i][1] = vest[i][1] + dtfm * f[i][1]; + v[i][2] = vest[i][2] + dtfm * f[i][2]; + for(int k = 0; k < cc_species; k++) + cc[i][k] += 0.5 * dtv * cc_flux[i][k]; + } +} + +/* ---------------------------------------------------------------------- */ + +void FixMvvTDPD::reset_dt() +{ + dtv = update->dt; + dtf = 0.5 * update->dt * force->ftm2v; +} diff --git a/src/USER-MESO/fix_mvv_tdpd.h b/src/USER-MESO/fix_mvv_tdpd.h new file mode 100644 index 0000000000..7adb23af69 --- /dev/null +++ b/src/USER-MESO/fix_mvv_tdpd.h @@ -0,0 +1,46 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef FIX_CLASS + +FixStyle(mvv/tdpd,FixMvvTDPD) + +#else + +#ifndef LMP_FIX_MVV_TDPD_H +#define LMP_FIX_MVV_TDPD_H + +#include "fix.h" + +namespace LAMMPS_NS { + +class FixMvvTDPD : public Fix { + public: + FixMvvTDPD(class LAMMPS *, int, char **); + virtual ~FixMvvTDPD() {} + int setmask(); + virtual void init(); + virtual void initial_integrate(int); + virtual void final_integrate(); + virtual void reset_dt(); + + protected: + double dtv, dtf; + double verlet; + int cc_species; +}; + +} + +#endif +#endif diff --git a/src/USER-MESO/fix_tdpd_source.cpp b/src/USER-MESO/fix_tdpd_source.cpp new file mode 100644 index 0000000000..3dfeba4787 --- /dev/null +++ b/src/USER-MESO/fix_tdpd_source.cpp @@ -0,0 +1,120 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include +#include +#include "fix_tdpd_source.h" +#include "atom.h" +#include "comm.h" +#include "update.h" +#include "modify.h" +#include "domain.h" +#include "lattice.h" +#include "input.h" +#include "variable.h" +#include "error.h" +#include "force.h" + +using namespace LAMMPS_NS; +using namespace FixConst; + +/* ---------------------------------------------------------------------- */ + +FixTDPDSource::FixTDPDSource(LAMMPS *lmp, int narg, char **arg) : + Fix(lmp, narg, arg) +{ + if (strcmp(style,"tdpd/source") != 0 && narg < 4) + error->all(FLERR,"Illegal fix tdpd/source command"); + + int iarg = 3; + cc_index = force->inumeric(FLERR,arg[iarg++]); + + if (strcmp(arg[iarg],"sphere") == 0) option = 0; + else if (strcmp(arg[iarg],"cuboid") == 0) option = 1; + else error->all(FLERR,"Illegal fix tdpd/source command"); + iarg++; + + if(option == 0){ + if (narg != 10 ) error->all(FLERR,"Illegal fix tdpd/source command (5 args for sphere)"); + center[0] = force->numeric(FLERR,arg[iarg++]); + center[1] = force->numeric(FLERR,arg[iarg++]); + center[2] = force->numeric(FLERR,arg[iarg++]); + radius = force->numeric(FLERR,arg[iarg++]); + value = force->numeric(FLERR,arg[iarg++]); + } + else if(option == 1){ + if (narg != 12 ) error->all(FLERR,"Illegal fix tdpd/edpd command (7 args for cuboid)"); + center[0] = force->numeric(FLERR,arg[iarg++]); + center[1] = force->numeric(FLERR,arg[iarg++]); + center[2] = force->numeric(FLERR,arg[iarg++]); + dLx = force->numeric(FLERR,arg[iarg++]); + dLy = force->numeric(FLERR,arg[iarg++]); + dLz = force->numeric(FLERR,arg[iarg++]); + value = force->numeric(FLERR,arg[iarg++]); + } + else error->all(FLERR,"Illegal fix tdpd/source command"); +} + +/* ---------------------------------------------------------------------- */ + +FixTDPDSource::~FixTDPDSource() +{ +} + +/* ---------------------------------------------------------------------- */ + +int FixTDPDSource::setmask() +{ + int mask = 0; + mask |= POST_FORCE; + return mask; +} + +/* ---------------------------------------------------------------------- */ + +void FixTDPDSource::init() +{ +} + +/* ---------------------------------------------------------------------- */ + +void FixTDPDSource::post_force(int vflag) +{ + double **x = atom->x; + double **cc_flux = atom->cc_flux; + int *mask = atom->mask; + int nlocal = atom->nlocal; + + double drx, dry, drz, rsq; + double radius_sq = radius*radius*radius; + + for (int i = 0; i < nlocal; i++) { + if (mask[i] & groupbit) { + if(option == 0){ + drx = x[i][0] - center[0]; + dry = x[i][1] - center[1]; + drz = x[i][2] - center[2]; + rsq = drx*drx + dry*dry + drz*drz; + if(rsq < radius_sq) + cc_flux[i][cc_index-1] += value; + } + else if(option == 1){ + drx = x[i][0] - center[0]; + dry = x[i][1] - center[1]; + drz = x[i][2] - center[2]; + if(abs(drx) <= 0.5*dLx && abs(dry) <= 0.5*dLy && abs(drz) <= 0.5*dLz) + cc_flux[i][cc_index-1] += value; + } + } + } +} diff --git a/src/USER-MESO/fix_tdpd_source.h b/src/USER-MESO/fix_tdpd_source.h new file mode 100644 index 0000000000..302fe82090 --- /dev/null +++ b/src/USER-MESO/fix_tdpd_source.h @@ -0,0 +1,45 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef FIX_CLASS + +FixStyle(tdpd/source,FixTDPDSource) + +#else + +#ifndef LMP_FIX_TDPDSOURCE_H +#define LMP_FIX_TDPDSOURCE_H + +#include "fix.h" + +namespace LAMMPS_NS { + +class FixTDPDSource : public Fix { + public: + FixTDPDSource(class LAMMPS *, int, char **); + ~FixTDPDSource(); + int setmask(); + void init(); + void post_force(int); + + protected: + int option; + int cc_index; + double center[3], radius, dLx, dLy, dLz; + double value; +}; + +} + +#endif +#endif diff --git a/src/USER-MESO/pair_edpd.cpp b/src/USER-MESO/pair_edpd.cpp new file mode 100644 index 0000000000..c1c100db43 --- /dev/null +++ b/src/USER-MESO/pair_edpd.cpp @@ -0,0 +1,551 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Zhen Li (Brown University) + Email: zhen_li@brown.edu +------------------------------------------------------------------------- */ + +#include +#include +#include +#include "pair_edpd.h" +#include "atom.h" +#include "atom_vec.h" +#include "comm.h" +#include "update.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "random_mars.h" +#include "citeme.h" +#include "memory.h" +#include "error.h" +#include +#include + +using namespace LAMMPS_NS; + +#define MIN(A,B) ((A) < (B) ? (A) : (B)) +#define MAX(A,B) ((A) > (B) ? (A) : (B)) + +#define EPSILON 1.0e-10 + +static const char cite_pair_edpd[] = + "pair edpd command:\n\n" + "@Article{ZLi2014_JCP,\n" + " author = {Li, Z. and Tang, Y.-H. and Lei, H. and Caswell, B. and Karniadakis, G.E.},\n" + " title = {Energy-conserving dissipative particle dynamics with temperature-dependent properties},\n" + " journal = {Journal of Computational Physics},\n" + " year = {2014},\n" + " volume = {265},\n" + " pages = {113--127}\n" + "}\n\n" + "@Article{ZLi2015_CC,\n" + " author = {Li, Z. and Tang, Y.-H. and Li, X. and Karniadakis, G.E.},\n" + " title = {Mesoscale modeling of phase transition dynamics of thermoresponsive polymers},\n" + " journal = {Chemical Communications},\n" + " year = {2015},\n" + " volume = {51},\n" + " pages = {11038--11040}\n" + "}\n\n"; +; + +/* ---------------------------------------------------------------------- */ + +PairEDPD::PairEDPD(LAMMPS *lmp) : Pair(lmp) +{ + if (lmp->citeme) lmp->citeme->add(cite_pair_edpd); + writedata = 1; + random = NULL; + randomT = NULL; +} + +/* ---------------------------------------------------------------------- */ + +PairEDPD::~PairEDPD() +{ + if (allocated) { + memory->destroy(setflag); + memory->destroy(cutsq); + + memory->destroy(cut); + memory->destroy(cutT); + + memory->destroy(a0); + memory->destroy(gamma); + memory->destroy(power); + memory->destroy(kappa); + memory->destroy(powerT); + } + if (power_flag) memory->destroy(sc); + if (kappa_flag) memory->destroy(kc); + + if (random) delete random; + if (randomT) delete randomT; +} + +/* ---------------------------------------------------------------------- */ + +void PairEDPD::compute(int eflag, int vflag) +{ + double evdwl = 0.0; + if (eflag || vflag) ev_setup(eflag,vflag); + else evflag = vflag_fdotr = 0; + + double **x = atom->x; + double **v = atom->v; + double **f = atom->f; + double *T = atom->edpd_temp; + double *Q = atom->edpd_flux; + double *cv = atom->edpd_cv; + int *type = atom->type; + double *mass = atom->mass; + int nlocal = atom->nlocal; + double *special_lj = force->special_lj; + int newton_pair = force->newton_pair; + double dtinvsqrt = 1.0/sqrt(update->dt); + double kboltz = 1.0; + + int inum = list->inum; + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + + // loop over neighbors of my atoms + for (int ii = 0; ii < inum; ii++) { + int i = ilist[ii]; + double xtmp = x[i][0]; + double ytmp = x[i][1]; + double ztmp = x[i][2]; + double vxtmp = v[i][0]; + double vytmp = v[i][1]; + double vztmp = v[i][2]; + int itype = type[i]; + int *jlist = firstneigh[i]; + int jnum = numneigh[i]; + + for (int jj = 0; jj < jnum; jj++) { + int j = jlist[jj]; + double factor_dpd = special_lj[sbmask(j)]; + j &= NEIGHMASK; + + double delx = xtmp - x[j][0]; + double dely = ytmp - x[j][1]; + double delz = ztmp - x[j][2]; + double rsq = delx*delx + dely*dely + delz*delz; + int jtype = type[j]; + + if (rsq < cutsq[itype][jtype]) { + double r = sqrt(rsq); + if (r < EPSILON) continue; + double rinv = 1.0/r; + double delvx = vxtmp - v[j][0]; + double delvy = vytmp - v[j][1]; + double delvz = vztmp - v[j][2]; + double dot = delx*delvx + dely*delvy + delz*delvz; + double vijeij = dot*rinv; + double randnum = random->gaussian(); + + double T_ij=0.5*(T[i]+T[j]); + double T_pow[4]; + T_pow[0] = T_ij - 1.0; + T_pow[1] = T_pow[0]*T_pow[0]; + T_pow[2] = T_pow[0]*T_pow[1]; + T_pow[3] = T_pow[0]*T_pow[2]; + + double power_d = power[itype][jtype]; + if(power_flag){ + double factor = 1.0; + for(int k = 0; k < 4; k++) + factor += sc[itype][jtype][k]*T_pow[k]; + power_d *= factor; + } + + power_d = MAX(0.01,power_d); + double wc = 1.0 - r/cut[itype][jtype]; + wc = MAX(0.0,MIN(1.0,wc)); + double wr = pow(wc, 0.5*power_d); + + double GammaIJ = gamma[itype][jtype]; + double SigmaIJ = 4.0*GammaIJ*kboltz*T[i]*T[j]/(T[i]+T[j]); + SigmaIJ = sqrt(SigmaIJ); + + double fpair = a0[itype][jtype]*T_ij*wc; + fpair -= GammaIJ *wr*wr *dot*rinv; + fpair += SigmaIJ * wr *randnum * dtinvsqrt; + fpair *= factor_dpd*rinv; + + f[i][0] += delx*fpair; + f[i][1] += dely*fpair; + f[i][2] += delz*fpair; + + // heat transfer + double dQc,dQd,dQr; + if( r < cutT[itype][jtype]) { + double wrT = 1.0 - r/cutT[itype][jtype]; + wrT = MAX(0.0,MIN(1.0,wrT)); + wrT = pow(wrT, 0.5*powerT[itype][jtype]); + double randnumT = randomT->gaussian(); + randnumT = MAX(-5.0,MIN(randnum,5.0)); + + double kappaT = kappa[itype][jtype]; + if(kappa_flag) { + double factor = 1.0; + for(int k = 0; k < 4; k++) + factor += kc[itype][jtype][k]*T_pow[k]; + kappaT *= factor; + } + + double kij = cv[i]*cv[j]*kappaT * T_ij*T_ij; + double alphaij = sqrt(2.0*kboltz*kij); + + dQc = kij * wrT*wrT * ( T[j] - T[i] )/(T[i]*T[j]); + dQd = wr*wr*( GammaIJ * vijeij*vijeij - SigmaIJ*SigmaIJ/mass[itype] ) - SigmaIJ * wr *vijeij *randnum; + dQd /= (cv[i]+cv[j]); + dQr = alphaij * wrT * dtinvsqrt * randnumT; + Q[i] += (dQc + dQd + dQr ); + } + //----------------------------------------------------------- + + if (newton_pair || j < nlocal) { + f[j][0] -= delx*fpair; + f[j][1] -= dely*fpair; + f[j][2] -= delz*fpair; + Q[j] -= ( dQc - dQd + dQr ); + } + + if (eflag) { + evdwl = 0.5*a0[itype][jtype]*T_ij*cut[itype][jtype] * wc*wc; + evdwl *= factor_dpd; + } + + if (evflag) ev_tally(i,j,nlocal,newton_pair,evdwl,0.0,fpair,delx,dely,delz); + } + } + } + + if (vflag_fdotr) virial_fdotr_compute(); +} + +/* ---------------------------------------------------------------------- + allocate all arrays +------------------------------------------------------------------------- */ + +void PairEDPD::allocate() +{ + int i,j; + allocated = 1; + int n = atom->ntypes; + + memory->create(setflag,n+1,n+1,"pair:setflag"); + for (i = 1; i <= n; i++) + for (j = i; j <= n; j++) + setflag[i][j] = 0; + + memory->create(cutsq,n+1,n+1,"pair:cutsq"); + + memory->create(cut,n+1,n+1,"pair:cut"); + memory->create(cutT,n+1,n+1,"pair:cutT"); + memory->create(a0,n+1,n+1,"pair:a0"); + memory->create(gamma,n+1,n+1,"pair:gamma"); + memory->create(power,n+1,n+1,"pair:power"); + memory->create(kappa,n+1,n+1,"pair:kappa"); + memory->create(powerT,n+1,n+1,"pair:powerT"); + +} + +/* ---------------------------------------------------------------------- + global settings +------------------------------------------------------------------------- */ + +void PairEDPD::settings(int narg, char **arg) +{ + if (narg != 2) error->all(FLERR,"Illegal pair_style command"); + + cut_global = force->numeric(FLERR,arg[0]); + seed = force->inumeric(FLERR,arg[1]); + + // initialize Marsaglia RNG with processor-unique seed + + if (seed <= 0 ) { + struct timespec time; + clock_gettime( CLOCK_REALTIME, &time ); + seed = time.tv_nsec; // if seed is non-positive, get the current time as the seed + } + delete random; + random = new RanMars(lmp,(seed + comm->me) % 900000000); + randomT = new RanMars(lmp,(2*seed + comm->me) % 900000000); + + // reset cutoffs that have been explicitly set + + if (allocated) { + int i,j; + for (i = 1; i <= atom->ntypes; i++) + for (j = i+1; j <= atom->ntypes; j++) + if (setflag[i][j]) + cut[i][j] = cut_global; + } +} + +/* ---------------------------------------------------------------------- + set coeffs for one or more type pairs +------------------------------------------------------------------------- */ + +void PairEDPD::coeff(int narg, char **arg) +{ + if (narg < 9) + error->all(FLERR,"Incorrect args for pair edpd coefficients"); + if (!allocated) allocate(); + + int ilo,ihi,jlo,jhi; + force->bounds(FLERR,arg[0],atom->ntypes,ilo,ihi); + force->bounds(FLERR,arg[1],atom->ntypes,jlo,jhi); + + double a0_one = force->numeric(FLERR,arg[2]); + double gamma_one = force->numeric(FLERR,arg[3]); + double power_one = force->numeric(FLERR,arg[4]); + double cut_one = force->numeric(FLERR,arg[5]); + double kappa_one = force->numeric(FLERR,arg[6]); + double powerT_one= force->numeric(FLERR,arg[7]); + double cutT_one = force->numeric(FLERR,arg[8]); + + int iarg = 9; + power_flag = kappa_flag = 0; + double sc_one[4], kc_one[4]; + int n = atom->ntypes; + while (iarg < narg) { + if (strcmp(arg[iarg],"power") == 0) { + if (iarg+5 > narg) error->all(FLERR,"Illegal pair edpd coefficients"); + for (int i = 0; i < 4; i++) + sc_one[i] = force->numeric(FLERR,arg[iarg+i+1]); + iarg += 5; + power_flag = 1; + memory->create(sc,n+1,n+1,4,"pair:sc"); + } else if (strcmp(arg[iarg],"kappa") == 0) { + if (iarg+5 > narg) error->all(FLERR,"Illegal pair edpd coefficients"); + for (int i = 0; i < 4; i++) + kc_one[i] = force->numeric(FLERR,arg[iarg+i+1]); + iarg += 5; + kappa_flag = 1; + memory->create(kc,n+1,n+1,4,"pair:kc"); + } else error->all(FLERR,"Illegal pair edpd coefficients"); + } + + int count = 0; + for (int i = ilo; i <= ihi; i++) + for (int j = MAX(jlo,i); j <= jhi; j++) { + a0[i][j] = a0_one; + gamma[i][j] = gamma_one; + power[i][j] = power_one; + cut[i][j] = cut_one; + kappa[i][j] = kappa_one; + powerT[i][j]= powerT_one; + cutT[i][j] = cutT_one; + + if(power_flag) + for (int k = 0; k < 4; k++) + sc[i][j][k] = sc_one[k]; + + if(kappa_flag) + for (int k = 0; k < 4; k++) + kc[i][j][k] = kc_one[k]; + + setflag[i][j] = 1; + count++; + } + + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); +} + +/* ---------------------------------------------------------------------- + init specific to this pair style +------------------------------------------------------------------------- */ + +void PairEDPD::init_style() +{ + if (comm->ghost_velocity == 0) + error->all(FLERR,"Pair edpd requires ghost atoms store velocity"); + + // if newton off, forces between atoms ij will be double computed + // using different random numbers + + if (force->newton_pair == 0 && comm->me == 0) error->warning(FLERR, + "Pair tdpd needs newton pair on for momentum conservation"); + + neighbor->request(this,instance_me); +} + +/* ---------------------------------------------------------------------- + init for one type pair i,j and corresponding j,i +------------------------------------------------------------------------- */ + +double PairEDPD::init_one(int i, int j) +{ + if (setflag[i][j] == 0) error->all(FLERR,"All pair coeffs are not set"); + + cut[j][i] = cut[i][j]; + cutT[j][i] = cutT[i][j]; + a0[j][i] = a0[i][j]; + gamma[j][i] = gamma[i][j]; + power[j][i] = power[i][j]; + kappa[j][i] = kappa[i][j]; + powerT[j][i]= powerT[i][j]; + + if(power_flag) + for (int k = 0; k < 4; k++) + sc[j][i][k] = sc[i][j][k]; + + if(kappa_flag) + for (int k = 0; k < 4; k++) + kc[j][i][k] = kc[i][j][k]; + + return cut[i][j]; +} + +/* ---------------------------------------------------------------------- + proc 0 writes to restart file +------------------------------------------------------------------------- */ + +void PairEDPD::write_restart(FILE *fp) +{ + write_restart_settings(fp); + + for (int i = 1; i <= atom->ntypes; i++) + for (int j = i; j <= atom->ntypes; j++) { + fwrite(&setflag[i][j],sizeof(int),1,fp); + if (setflag[i][j]) { + fwrite(&a0[i][j],sizeof(double),1,fp); + fwrite(&gamma[i][j],sizeof(double),1,fp); + fwrite(&power[i][j],sizeof(double),1,fp); + fwrite(&cut[i][j],sizeof(double),1,fp); + fwrite(&kappa[i][j],sizeof(double),1,fp); + fwrite(&powerT[i][j],sizeof(double),1,fp); + fwrite(&cutT[i][j],sizeof(double),1,fp); + if(power_flag) + for (int k = 0; k < 4; k++) + fwrite(&sc[i][j][k],sizeof(double),1,fp); + + if(kappa_flag) + for (int k = 0; k < 4; k++) + fwrite(&kc[i][j][k],sizeof(double),1,fp); + } + } +} + +/* ---------------------------------------------------------------------- + proc 0 reads from restart file, bcasts +------------------------------------------------------------------------- */ + +void PairEDPD::read_restart(FILE *fp) +{ + read_restart_settings(fp); + + allocate(); + + int me = comm->me; + for (int i = 1; i <= atom->ntypes; i++) + for (int j = i; j <= atom->ntypes; j++) { + if (me == 0) fread(&setflag[i][j],sizeof(int),1,fp); + MPI_Bcast(&setflag[i][j],1,MPI_INT,0,world); + if (setflag[i][j]) { + if (me == 0) { + fread(&a0[i][j],sizeof(double),1,fp); + fread(&gamma[i][j],sizeof(double),1,fp); + fread(&power[i][j],sizeof(double),1,fp); + fread(&cut[i][j],sizeof(double),1,fp); + fread(&kappa[i][j],sizeof(double),1,fp); + fread(&powerT[i][j],sizeof(double),1,fp); + fread(&cutT[i][j],sizeof(double),1,fp); + if(power_flag) + for (int k = 0; k < 4; k++) + fread(&sc[i][j][k],sizeof(double),1,fp); + + if(kappa_flag) + for (int k = 0; k < 4; k++) + fread(&kc[i][j][k],sizeof(double),1,fp); + } + MPI_Bcast(&a0[i][j],1,MPI_DOUBLE,0,world); + MPI_Bcast(&gamma[i][j],1,MPI_DOUBLE,0,world); + MPI_Bcast(&power[i][j],1,MPI_DOUBLE,0,world); + MPI_Bcast(&cut[i][j],1,MPI_DOUBLE,0,world); + MPI_Bcast(&kappa[i][j],1,MPI_DOUBLE,0,world); + MPI_Bcast(&powerT[i][j],1,MPI_DOUBLE,0,world); + MPI_Bcast(&cutT[i][j],1,MPI_DOUBLE,0,world); + if(power_flag) + for (int k = 0; k < 4; k++) + MPI_Bcast(&sc[i][j][k],1,MPI_DOUBLE,0,world); + + if(kappa_flag) + for (int k = 0; k < 4; k++) + MPI_Bcast(&kc[i][j][k],1,MPI_DOUBLE,0,world); + } + } +} + +/* ---------------------------------------------------------------------- + proc 0 writes to restart file +------------------------------------------------------------------------- */ + +void PairEDPD::write_restart_settings(FILE *fp) +{ + fwrite(&cut_global,sizeof(double),1,fp); + fwrite(&seed,sizeof(int),1,fp); + fwrite(&mix_flag,sizeof(int),1,fp); +} + +/* ---------------------------------------------------------------------- + proc 0 reads from restart file, bcasts +------------------------------------------------------------------------- */ + +void PairEDPD::read_restart_settings(FILE *fp) +{ + if (comm->me == 0) { + fread(&cut_global,sizeof(double),1,fp); + fread(&seed,sizeof(int),1,fp); + fread(&mix_flag,sizeof(int),1,fp); + } + MPI_Bcast(&cut_global,1,MPI_DOUBLE,0,world); + MPI_Bcast(&seed,1,MPI_INT,0,world); + MPI_Bcast(&mix_flag,1,MPI_INT,0,world); + + // initialize Marsaglia RNG with processor-unique seed + // same seed that pair_style command initially specified + + if (random) delete random; + random = new RanMars(lmp,seed + comm->me); + if (randomT) delete randomT; + randomT = new RanMars(lmp,seed + comm->me); +} + +/* ---------------------------------------------------------------------- */ + +double PairEDPD::single(int i, int j, int itype, int jtype, double rsq, + double factor_coul, double factor_dpd, double &fforce) +{ + double r,rinv,wc,phi; + double *T = atom->edpd_temp; + + r = sqrt(rsq); + if (r < EPSILON) { + fforce = 0.0; + return 0.0; + } + double T_ij = 0.5*(T[i]+T[j]); + rinv = 1.0/r; + wc = 1.0 - r/cut[itype][jtype]; + fforce = a0[itype][jtype]*T_ij*wc*factor_dpd*rinv; + + phi = 0.5*a0[itype][jtype]*T_ij*cut[itype][jtype]*wc*wc; + return factor_dpd*phi; +} diff --git a/src/USER-MESO/pair_edpd.h b/src/USER-MESO/pair_edpd.h new file mode 100644 index 0000000000..9ab0ad9670 --- /dev/null +++ b/src/USER-MESO/pair_edpd.h @@ -0,0 +1,85 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(edpd,PairEDPD) + +#else + +#ifndef LMP_PAIR_EDPD_H +#define LMP_PAIR_EDPD_H + +#include "pair.h" + +namespace LAMMPS_NS { + +class PairEDPD : public Pair { + public: + PairEDPD(class LAMMPS *); + virtual ~PairEDPD(); + virtual void compute(int, int); + virtual void settings(int, char **); + virtual void coeff(int, char **); + void init_style(); + double init_one(int, int); + virtual void write_restart(FILE *); + virtual void read_restart(FILE *); + virtual void write_restart_settings(FILE *); + virtual void read_restart_settings(FILE *); + double single(int, int, int, int, double, double, double, double &); + + protected: + double cut_global; + int seed; + double **cut,**cutT; + double **a0,**gamma; + double **power; + double **slope; + double **kappa; + double **powerT; + int power_flag, kappa_flag; + double ***sc,***kc; + class RanMars *random; + class RanMars *randomT; + + void allocate(); +}; + +} + +#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. + +W: Pair tdpd needs newton pair on for momentum conservation + +Self-explanatory. + +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/USER-MESO/pair_mdpd.cpp b/src/USER-MESO/pair_mdpd.cpp new file mode 100644 index 0000000000..bf78ea5af7 --- /dev/null +++ b/src/USER-MESO/pair_mdpd.cpp @@ -0,0 +1,425 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Zhen Li (Brown University) + Email: zhen_li@brown.edu +------------------------------------------------------------------------- */ + +#include +#include +#include +#include "pair_mdpd.h" +#include "atom.h" +#include "atom_vec.h" +#include "comm.h" +#include "update.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "random_mars.h" +#include "citeme.h" +#include "memory.h" +#include "error.h" +#include + +using namespace LAMMPS_NS; + +#define EPSILON 1.0e-10 + +static const char cite_pair_mdpd[] = + "pair mdpd command:\n\n" + "@Article{ZLi2013_POF,\n" + " author = {Li, Z. and Hu, G.H. and Wang, Z.L. and Ma Y.B. and Zhou, Z.W.},\n" + " title = {Three dimensional flow structures in a moving droplet on substrate: a dissipative particle dynamics study},\n" + " journal = {Physics of Fluids},\n" + " year = {2013},\n" + " volume = {25},\n" + " pages = {072103}\n" + "}\n\n"; + +/* ---------------------------------------------------------------------- */ + +PairMDPD::PairMDPD(LAMMPS *lmp) : Pair(lmp) +{ + if (lmp->citeme) lmp->citeme->add(cite_pair_mdpd); + + writedata = 1; + random = NULL; +} + +/* ---------------------------------------------------------------------- */ + +PairMDPD::~PairMDPD() +{ + if (allocated) { + memory->destroy(setflag); + memory->destroy(cutsq); + + memory->destroy(cut); + memory->destroy(cut_r); + memory->destroy(A_att); + memory->destroy(B_rep); + memory->destroy(gamma); + memory->destroy(sigma); + } + if (random) delete random; +} + +/* ---------------------------------------------------------------------- */ + +void PairMDPD::compute(int eflag, int vflag) +{ + int i,j,ii,jj,inum,jnum,itype,jtype; + double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair; + double vxtmp,vytmp,vztmp,delvx,delvy,delvz; + double rsq,r,rinv,dot,wc,wc_r, wr,randnum,factor_dpd; + int *ilist,*jlist,*numneigh,**firstneigh; + double rhoi, rhoj; + + evdwl = 0.0; + if (eflag || vflag) ev_setup(eflag,vflag); + else evflag = vflag_fdotr = 0; + + double **x = atom->x; + double **v = atom->v; + double **f = atom->f; + double *rho= atom->rho; + int *type = atom->type; + int nlocal = atom->nlocal; + double *special_lj = force->special_lj; + int newton_pair = force->newton_pair; + double dtinvsqrt = 1.0/sqrt(update->dt); + + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // loop over neighbors of my atoms + + for (ii = 0; ii < inum; ii++) { + i = ilist[ii]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + vxtmp = v[i][0]; + vytmp = v[i][1]; + vztmp = v[i][2]; + itype = type[i]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + rhoi = rho[i]; + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + factor_dpd = special_lj[sbmask(j)]; + j &= NEIGHMASK; + + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx*delx + dely*dely + delz*delz; + jtype = type[j]; + + if (rsq < cutsq[itype][jtype]) { + r = sqrt(rsq); + if (r < EPSILON) continue; // r can be 0.0 in MDPD systems + rinv = 1.0/r; + delvx = vxtmp - v[j][0]; + delvy = vytmp - v[j][1]; + delvz = vztmp - v[j][2]; + dot = delx*delvx + dely*delvy + delz*delvz; + + wc = 1.0 - r/cut[itype][jtype]; + wc_r = 1.0 - r/cut_r[itype][jtype]; + wc_r = MAX(wc_r,0.0); + wr = wc; + + rhoj = rho[j]; + randnum = random->gaussian(); + + // conservative force = A_att * wc + B_rep*(rhoi+rhoj)*wc_r + // drag force = -gamma * wr^2 * (delx dot delv) / r + // random force = sigma * wr * rnd * dtinvsqrt; + + fpair = A_att[itype][jtype]*wc + B_rep[itype][jtype]*(rhoi+rhoj)*wc_r; + fpair -= gamma[itype][jtype]*wr*wr*dot*rinv; + fpair += sigma[itype][jtype]*wr*randnum*dtinvsqrt; + fpair *= factor_dpd*rinv; + + f[i][0] += delx*fpair; + f[i][1] += dely*fpair; + f[i][2] += delz*fpair; + if (newton_pair || j < nlocal) { + f[j][0] -= delx*fpair; + f[j][1] -= dely*fpair; + f[j][2] -= delz*fpair; + } + + if (eflag) { + // unshifted eng of conservative term: + // eng shifted to 0.0 at cutoff + evdwl = 0.5*A_att[itype][jtype]*cut[itype][jtype] * wr*wr + 0.5*B_rep[itype][jtype]*cut_r[itype][jtype]*(rhoi+rhoj)*wc_r*wc_r; + evdwl *= factor_dpd; + } + + if (evflag) ev_tally(i,j,nlocal,newton_pair,evdwl,0.0,fpair,delx,dely,delz); + } + } + } + if (vflag_fdotr) virial_fdotr_compute(); +} + +/* ---------------------------------------------------------------------- + allocate all arrays +------------------------------------------------------------------------- */ + +void PairMDPD::allocate() +{ + int i,j; + allocated = 1; + int n = atom->ntypes; + + memory->create(setflag,n+1,n+1,"pair:setflag"); + for (i = 1; i <= n; i++) + for (j = i; j <= n; j++) + setflag[i][j] = 0; + + memory->create(cutsq,n+1,n+1,"pair:cutsq"); + + memory->create(cut,n+1,n+1,"pair:cut"); + memory->create(cut_r,n+1,n+1,"pair:cut_r"); + memory->create(A_att,n+1,n+1,"pair:A_att"); + memory->create(B_rep,n+1,n+1,"pair:B_rep"); + memory->create(gamma,n+1,n+1,"pair:gamma"); + memory->create(sigma,n+1,n+1,"pair:sigma"); +} + +/* ---------------------------------------------------------------------- + global settings +------------------------------------------------------------------------- */ + +void PairMDPD::settings(int narg, char **arg) +{ + if (narg != 3) error->all(FLERR,"Illegal pair_style command"); + + temperature = force->numeric(FLERR,arg[0]); + cut_global = force->numeric(FLERR,arg[1]); + seed = force->inumeric(FLERR,arg[2]); + + // initialize Marsaglia RNG with processor-unique seed + + if (seed <= 0 ) { + struct timespec time; + clock_gettime( CLOCK_REALTIME, &time ); + seed = time.tv_nsec; // if seed is non-positive, get the current time as the seed + } + delete random; + random = new RanMars(lmp,(seed + comm->me) % 900000000); + + // reset cutoffs that have been explicitly set + + if (allocated) { + int i,j; + for (i = 1; i <= atom->ntypes; i++) + for (j = i+1; j <= atom->ntypes; j++) + if (setflag[i][j]) cut[i][j] = cut_global; + } +} + +/* ---------------------------------------------------------------------- + set coeffs for one or more type pairs +------------------------------------------------------------------------- */ + +void PairMDPD::coeff(int narg, char **arg) +{ + if(narg != 7 ) error->all(FLERR,"Incorrect args for pair coefficients\n itype jtype A B gamma cutA cutB"); + if (!allocated) allocate(); + + int ilo,ihi,jlo,jhi; + force->bounds(FLERR,arg[0],atom->ntypes,ilo,ihi); + force->bounds(FLERR,arg[1],atom->ntypes,jlo,jhi); + + double A_one = force->numeric(FLERR,arg[2]); + double B_one = force->numeric(FLERR,arg[3]); + double gamma_one = force->numeric(FLERR,arg[4]); + double cut_one = force->numeric(FLERR,arg[5]); + double cut_two = force->numeric(FLERR,arg[6]); + + if(cut_one < cut_two) error->all(FLERR,"Incorrect args for pair coefficients\n cutA should be larger than cutB."); + + int count = 0; + for (int i = ilo; i <= ihi; i++) { + for (int j = MAX(jlo,i); j <= jhi; j++) { + A_att[i][j] = A_one; + B_rep[i][j] = B_one; + gamma[i][j] = gamma_one; + cut[i][j] = cut_one; + cut_r[i][j] = cut_two; + setflag[i][j] = 1; + count++; + } + } + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); +} + +/* ---------------------------------------------------------------------- + init specific to this pair style +------------------------------------------------------------------------- */ + +void PairMDPD::init_style() +{ + if (comm->ghost_velocity == 0) + error->all(FLERR,"Pair mdpd requires ghost atoms store velocity"); + + // if newton off, forces between atoms ij will be double computed + // using different random numbers + + if (force->newton_pair == 0 && comm->me == 0) error->warning(FLERR, + "Pair mdpd needs newton pair on for momentum conservation"); + + neighbor->request(this,instance_me); +} + +/* ---------------------------------------------------------------------- + init for one type pair i,j and corresponding j,i +------------------------------------------------------------------------- */ + +double PairMDPD::init_one(int i, int j) +{ + if (setflag[i][j] == 0) error->all(FLERR,"All pair coeffs are not set"); + + sigma[i][j] = sqrt(2.0*force->boltz*temperature*gamma[i][j]); + + cut[j][i] = cut[i][j]; + cut_r[j][i] = cut_r[i][j]; + A_att[j][i] = A_att[i][j]; + B_rep[j][i] = B_rep[i][j]; + gamma[j][i] = gamma[i][j]; + sigma[j][i] = sigma[i][j]; + + return cut[i][j]; +} + +/* ---------------------------------------------------------------------- + proc 0 writes to restart file +------------------------------------------------------------------------- */ + +void PairMDPD::write_restart(FILE *fp) +{ + write_restart_settings(fp); + + int i,j; + for (i = 1; i <= atom->ntypes; i++) + for (j = i; j <= atom->ntypes; j++) { + fwrite(&setflag[i][j],sizeof(int),1,fp); + if (setflag[i][j]) { + fwrite(&A_att[i][j],sizeof(double),1,fp); + fwrite(&B_rep[i][j],sizeof(double),1,fp); + fwrite(&gamma[i][j],sizeof(double),1,fp); + fwrite(&cut[i][j],sizeof(double),1,fp); + fwrite(&cut_r[i][j],sizeof(double),1,fp); + } + } +} + +/* ---------------------------------------------------------------------- + proc 0 reads from restart file, bcasts +------------------------------------------------------------------------- */ + +void PairMDPD::read_restart(FILE *fp) +{ + read_restart_settings(fp); + + allocate(); + + int i,j; + int me = comm->me; + for (i = 1; i <= atom->ntypes; i++) + for (j = i; j <= atom->ntypes; j++) { + if (me == 0) fread(&setflag[i][j],sizeof(int),1,fp); + MPI_Bcast(&setflag[i][j],1,MPI_INT,0,world); + if (setflag[i][j]) { + if (me == 0) { + fread(&A_att[i][j],sizeof(double),1,fp); + fread(&B_rep[i][j],sizeof(double),1,fp); + fread(&gamma[i][j],sizeof(double),1,fp); + fread(&cut[i][j],sizeof(double),1,fp); + fread(&cut_r[i][j],sizeof(double),1,fp); + } + MPI_Bcast(&A_att[i][j],1,MPI_DOUBLE,0,world); + MPI_Bcast(&B_rep[i][j],1,MPI_DOUBLE,0,world); + MPI_Bcast(&gamma[i][j],1,MPI_DOUBLE,0,world); + MPI_Bcast(&cut[i][j],1,MPI_DOUBLE,0,world); + MPI_Bcast(&cut_r[i][j],1,MPI_DOUBLE,0,world); + } + } +} + +/* ---------------------------------------------------------------------- + proc 0 writes to restart file +------------------------------------------------------------------------- */ + +void PairMDPD::write_restart_settings(FILE *fp) +{ + fwrite(&temperature,sizeof(double),1,fp); + fwrite(&cut_global,sizeof(double),1,fp); + fwrite(&seed,sizeof(int),1,fp); + fwrite(&mix_flag,sizeof(int),1,fp); +} + +/* ---------------------------------------------------------------------- + proc 0 reads from restart file, bcasts +------------------------------------------------------------------------- */ + +void PairMDPD::read_restart_settings(FILE *fp) +{ + if (comm->me == 0) { + fread(&temperature,sizeof(double),1,fp); + fread(&cut_global,sizeof(double),1,fp); + fread(&seed,sizeof(int),1,fp); + fread(&mix_flag,sizeof(int),1,fp); + } + MPI_Bcast(&temperature,1,MPI_DOUBLE,0,world); + MPI_Bcast(&cut_global,1,MPI_DOUBLE,0,world); + MPI_Bcast(&seed,1,MPI_INT,0,world); + MPI_Bcast(&mix_flag,1,MPI_INT,0,world); + + // initialize Marsaglia RNG with processor-unique seed + // same seed that pair_style command initially specified + + if (random) delete random; + random = new RanMars(lmp,seed + comm->me); +} + +/* ---------------------------------------------------------------------- + proc 0 writes to data file +------------------------------------------------------------------------- */ + +void PairMDPD::write_data(FILE *fp) +{ + for (int i = 1; i <= atom->ntypes; i++) + fprintf(fp,"%d %g %g %g\n",i,A_att[i][i],B_rep[i][i],gamma[i][i]); +} + +/* ---------------------------------------------------------------------- + proc 0 writes all pairs to data file +------------------------------------------------------------------------- */ + +void PairMDPD::write_data_all(FILE *fp) +{ + for (int i = 1; i <= atom->ntypes; i++) + for (int j = i; j <= atom->ntypes; j++) + fprintf(fp,"%d %d %g %g %g %g %g\n",i,j,A_att[i][j],B_rep[i][j],gamma[i][j],cut[i][j],cut_r[i][j]); +} + diff --git a/src/USER-MESO/pair_mdpd.h b/src/USER-MESO/pair_mdpd.h new file mode 100644 index 0000000000..ea0389c7fe --- /dev/null +++ b/src/USER-MESO/pair_mdpd.h @@ -0,0 +1,84 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(mdpd,PairMDPD) + +#else + +#ifndef LMP_PAIR_MDPD_H +#define LMP_PAIR_MDPD_H + +#include "pair.h" + +namespace LAMMPS_NS { + +class PairMDPD : public Pair { + public: + PairMDPD(class LAMMPS *); + virtual ~PairMDPD(); + virtual void compute(int, int); + virtual void settings(int, char **); + virtual void coeff(int, char **); + void init_style(); + double init_one(int, int); + virtual void write_restart(FILE *); + virtual void read_restart(FILE *); + virtual void write_restart_settings(FILE *); + virtual void read_restart_settings(FILE *); + virtual void write_data(FILE *); + virtual void write_data_all(FILE *); + + protected: + double cut_global,temperature; + int seed; + double **cut, **cut_r; + double **A_att,**B_rep; + double **gamma,**sigma; + class RanMars *random; + + void allocate(); +}; + +} + +#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: Pair dpd requires ghost atoms store velocity + +Use the comm_modify vel yes command to enable this. + +W: Pair dpd needs newton pair on for momentum conservation + +Self-explanatory. + +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/USER-MESO/pair_mdpd_rhosum.cpp b/src/USER-MESO/pair_mdpd_rhosum.cpp new file mode 100644 index 0000000000..9c4d6f804f --- /dev/null +++ b/src/USER-MESO/pair_mdpd_rhosum.cpp @@ -0,0 +1,267 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. + ------------------------------------------------------------------------- */ + +/*----------------------------------------------------------------------- + This is a Child Class PairMDPD for taking care of density summation + before the force calculation. + The code uses 3D Lucy kernel, it can be modified for other kernels. + + Contributing author: Zhen Li (Brown University) +------------------------------------------------------------------------- */ + +#include +#include +#include "pair_mdpd_rhosum.h" +#include "atom.h" +#include "force.h" +#include "comm.h" +#include "neigh_list.h" +#include "neigh_request.h" +#include "memory.h" +#include "error.h" +#include "neighbor.h" +#include "update.h" +#include "domain.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +PairMDPDRhoSum::PairMDPDRhoSum(LAMMPS *lmp) : Pair(lmp) +{ + restartinfo = 0; + + // set comm size needed by this Pair + + comm_forward = 1; + first = 1; +} + +/* ---------------------------------------------------------------------- */ + +PairMDPDRhoSum::~PairMDPDRhoSum() { + if (allocated) { + memory->destroy(setflag); + memory->destroy(cutsq); + + memory->destroy(cut); + } +} + +/* ---------------------------------------------------------------------- + init specific to this pair style + ------------------------------------------------------------------------- */ + +void PairMDPDRhoSum::init_style() { + // need a full neighbor list + int irequest = neighbor->request(this,instance_me); + neighbor->requests[irequest]->half = 0; + neighbor->requests[irequest]->full = 1; +} + +/* ---------------------------------------------------------------------- */ + +void PairMDPDRhoSum::compute(int eflag, int vflag) { + int i, j, ii, jj, jnum, itype, jtype; + double xtmp, ytmp, ztmp, delx, dely, delz; + double r, rsq, h, ih, ihsq; + int *jlist; + double wf; + // neighbor list variables + int inum, *ilist, *numneigh, **firstneigh; + + if (eflag || vflag) + ev_setup(eflag, vflag); + else + evflag = vflag_fdotr = 0; + + double **x = atom->x; + double *rho = atom->rho; + int *type = atom->type; + double *mass = atom->mass; + + // check consistency of pair coefficients + if (first) { + for (i = 1; i <= atom->ntypes; i++) + for (j = 1; i <= atom->ntypes; i++) + if (cutsq[i][j] > 0.0) + if (!setflag[i][i] || !setflag[j][j]) + if (comm->me == 0) + printf("mDPD particle types %d and %d interact, but not all of their single particle properties are set.\n", i, j); + + first = 0; + } + + + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // recompute density + // we use a full neighborlist here + + // initialize density with zero self-contribution, + for (ii = 0; ii < inum; ii++) { + i = ilist[ii]; + itype = type[i]; + + h = cut[itype][itype]; + // Lucy kernel, 3d + wf = 2.0889086280811262819e0 / (h * h * h); + rho[i] = 0; + } + + // add density at each atom via kernel function overlap + for (ii = 0; ii < inum; ii++) { + i = ilist[ii]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + itype = type[i]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + j &= NEIGHMASK; + + jtype = type[j]; + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx * delx + dely * dely + delz * delz; + + if (rsq < cutsq[itype][jtype]) { + h = cut[itype][jtype]; + ih = 1.0 / h; + ihsq = ih * ih; + + // Lucy kernel, 3d + r = sqrt(rsq); + wf = (h - r) * ihsq; + wf = 2.0889086280811262819e0 * (h + 3. * r) * wf * wf * wf * ih; + rho[i] += mass[jtype]*wf; + } + } + } + + // communicate densities + comm->forward_comm_pair(this); +} + +/* ---------------------------------------------------------------------- + allocate all arrays + ------------------------------------------------------------------------- */ + +void PairMDPDRhoSum::allocate() { + allocated = 1; + int n = atom->ntypes; + + memory->create(setflag, n + 1, n + 1, "pair:setflag"); + for (int i = 1; i <= n; i++) + for (int j = i; j <= n; j++) + setflag[i][j] = 0; + + memory->create(cutsq, n + 1, n + 1, "pair:cutsq"); + + memory->create(cut, n + 1, n + 1, "pair:cut"); +} + +/* ---------------------------------------------------------------------- + global settings + ------------------------------------------------------------------------- */ + +void PairMDPDRhoSum::settings(int narg, char **arg) { + if (narg != 0) + error->all(FLERR,"Illegal number of setting arguments for pair_style mdpd/rhosum"); +} + +/* ---------------------------------------------------------------------- + set coeffs for one or more type pairs + ------------------------------------------------------------------------- */ + +void PairMDPDRhoSum::coeff(int narg, char **arg) { + if (narg != 3) + error->all(FLERR,"Incorrect number of args for mdpd/rhosum coefficients"); + if (!allocated) + allocate(); + + int ilo, ihi, jlo, jhi; + force->bounds(FLERR,arg[0], atom->ntypes, ilo, ihi); + force->bounds(FLERR,arg[1], atom->ntypes, jlo, jhi); + + double cut_one = force->numeric(FLERR,arg[2]); + + int count = 0; + for (int i = ilo; i <= ihi; i++) { + for (int j = MAX(jlo,i); j <= jhi; j++) { + cut[i][j] = cut_one; + setflag[i][j] = 1; + count++; + } + } + + if (count == 0) + error->all(FLERR,"Incorrect args for pair coefficients"); +} + +/* ---------------------------------------------------------------------- + init for one type pair i,j and corresponding j,i + ------------------------------------------------------------------------- */ + +double PairMDPDRhoSum::init_one(int i, int j) { + if (setflag[i][j] == 0) { + error->all(FLERR,"All pair mdpd/rhosum coeffs are not set"); + } + + cut[j][i] = cut[i][j]; + + return cut[i][j]; +} + +/* ---------------------------------------------------------------------- */ + +double PairMDPDRhoSum::single(int i, int j, int itype, int jtype, double rsq, + double factor_coul, double factor_lj, double &fforce) { + fforce = 0.0; + + return 0.0; +} + +/* ---------------------------------------------------------------------- */ + +int PairMDPDRhoSum::pack_forward_comm(int n, int *list, double *buf, + int pbc_flag, int *pbc) { + int i, j, m; + double *rho = atom->rho; + + m = 0; + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = rho[j]; + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +void PairMDPDRhoSum::unpack_forward_comm(int n, int first, double *buf) { + int i, m, last; + double *rho = atom->rho; + + m = 0; + last = first + n; + for (i = first; i < last; i++) + rho[i] = buf[m++]; +} diff --git a/src/USER-MESO/pair_mdpd_rhosum.h b/src/USER-MESO/pair_mdpd_rhosum.h new file mode 100644 index 0000000000..a972ec7ccf --- /dev/null +++ b/src/USER-MESO/pair_mdpd_rhosum.h @@ -0,0 +1,50 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(mdpd/rhosum,PairMDPDRhoSum) + +#else + +#ifndef LMP_PAIR_MDPD_RHOSUM_H +#define LMP_PAIR_MDPD_RHOSUM_H + +#include "pair.h" + +namespace LAMMPS_NS { + +class PairMDPDRhoSum : public Pair { + public: + PairMDPDRhoSum(class LAMMPS *); + virtual ~PairMDPDRhoSum(); + void init_style(); + virtual void compute(int, int); + void settings(int, char **); + void coeff(int, char **); + virtual double init_one(int, int); + virtual double single(int, int, int, int, double, double, double, double &); + int pack_forward_comm(int, int *, double *, int, int *); + void unpack_forward_comm(int, int, double *); + + protected: + double **cut; + int first; + + void allocate(); +}; + +} + +#endif +#endif diff --git a/src/USER-MESO/pair_tdpd.cpp b/src/USER-MESO/pair_tdpd.cpp new file mode 100644 index 0000000000..22c856ee3f --- /dev/null +++ b/src/USER-MESO/pair_tdpd.cpp @@ -0,0 +1,477 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Zhen Li (Brown University) + Email: zhen_li@brown.edu +------------------------------------------------------------------------- */ + +#include +#include +#include +#include "pair_tdpd.h" +#include "atom.h" +#include "atom_vec.h" +#include "comm.h" +#include "update.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "random_mars.h" +#include "citeme.h" +#include "memory.h" +#include "error.h" +#include + +using namespace LAMMPS_NS; + +#define MIN(A,B) ((A) < (B) ? (A) : (B)) +#define MAX(A,B) ((A) > (B) ? (A) : (B)) + +#define EPSILON 1.0e-10 + +static const char cite_pair_tdpd[] = + "pair tdpd command:\n\n" + "@Article{ZLi2015_JCP,\n" + " author = {Li, Z. and Yazdani, A. and Tartakovsky, A. and Karniadakis, G.E.},\n" + " title = {Transport dissipative particle dynamics model for mesoscopic advection-diffusion-reaction problems},\n" + " journal = {The Journal of Chemical Physics},\n" + " year = {2015},\n" + " volume = {143},\n" + " pages = {014101}\n" + "}\n\n"; + +/* ---------------------------------------------------------------------- */ + +PairTDPD::PairTDPD(LAMMPS *lmp) : Pair(lmp) +{ + if (lmp->citeme) lmp->citeme->add(cite_pair_tdpd); + cc_species = atom->cc_species; + + writedata = 1; + random = NULL; +} + +/* ---------------------------------------------------------------------- */ + +PairTDPD::~PairTDPD() +{ + if (allocated) { + memory->destroy(setflag); + memory->destroy(cutsq); + + memory->destroy(cut); + memory->destroy(cutcc); + + memory->destroy(a0); + memory->destroy(gamma); + memory->destroy(sigma); + + memory->destroy(power); + memory->destroy(kappa); + memory->destroy(epsilon); + memory->destroy(powercc); + } + + if (random) delete random; +} + +/* ---------------------------------------------------------------------- */ + +void PairTDPD::compute(int eflag, int vflag) +{ + double evdwl = 0.0; + double fpair; + if (eflag || vflag) ev_setup(eflag,vflag); + else evflag = vflag_fdotr = 0; + + double **x = atom->x; + double **v = atom->v; + double **f = atom->f; + double **cc = atom->cc; + double **cc_flux = atom->cc_flux; + int *type = atom->type; + int nlocal = atom->nlocal; + double *special_lj = force->special_lj; + int newton_pair = force->newton_pair; + double dtinvsqrt = 1.0/sqrt(update->dt); + + int inum = list->inum; + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + + // loop over neighbors of my atoms + for (int ii = 0; ii < inum; ii++) { + int i = ilist[ii]; + double xtmp = x[i][0]; + double ytmp = x[i][1]; + double ztmp = x[i][2]; + double vxtmp = v[i][0]; + double vytmp = v[i][1]; + double vztmp = v[i][2]; + int itype = type[i]; + int *jlist = firstneigh[i]; + int jnum = numneigh[i]; + + for (int jj = 0; jj < jnum; jj++) { + int j = jlist[jj]; + double factor_dpd = special_lj[sbmask(j)]; + j &= NEIGHMASK; + + double delx = xtmp - x[j][0]; + double dely = ytmp - x[j][1]; + double delz = ztmp - x[j][2]; + double rsq = delx*delx + dely*dely + delz*delz; + int jtype = type[j]; + + if (rsq < cutsq[itype][jtype]) { + double r = sqrt(rsq); + if (r < EPSILON) continue; // r can be 0.0 in DPD systems + double rinv = 1.0/r; + double delvx = vxtmp - v[j][0]; + double delvy = vytmp - v[j][1]; + double delvz = vztmp - v[j][2]; + double dot = delx*delvx + dely*delvy + delz*delvz; + double wc = 1.0 - r/cut[itype][jtype]; + wc = MAX(0,MIN(1.0,wc)); + double wr = pow(wc, 0.5*power[itype][jtype]); + double randnum = random->gaussian(); + + // conservative force = a0 * wc + // drag force = -gamma * wr^2 * (delx dot delv) / r + // random force = sigma * wr^(power/2) * rnd * dtinvsqrt; + + double fpair = a0[itype][jtype]*wc; + fpair -= gamma[itype][jtype]*wr*wr*dot*rinv; + fpair += sigma[itype][jtype]*wr*randnum*dtinvsqrt; + fpair *= factor_dpd*rinv; + + f[i][0] += delx*fpair; + f[i][1] += dely*fpair; + f[i][2] += delz*fpair; + + // chemical concentration transport + if( r < cutcc[itype][jtype]) { + for(int k=0; kgaussian(); + randnum = MAX(-5.0,MIN(randnum,5.0)); + double dQc = -kappa[itype][jtype][k] * wcr*wcr *(cc[i][k]-cc[j][k]); + double dQr = epsilon[itype][jtype][k] *wcr* (cc[i][k]+cc[j][k]) *randnum*dtinvsqrt; + cc_flux[i][k] += (dQc + dQr); + if (newton_pair || j < nlocal) + cc_flux[j][k] -= ( dQc + dQr ); + } + } + //----------------------------------------------------------- + + if (newton_pair || j < nlocal) { + f[j][0] -= delx*fpair; + f[j][1] -= dely*fpair; + f[j][2] -= delz*fpair; + } + + if (eflag) { + evdwl = 0.5*a0[itype][jtype]*cut[itype][jtype] * wc*wc; + evdwl *= factor_dpd; + } + + if (evflag) ev_tally(i,j,nlocal,newton_pair,evdwl,0.0,fpair,delx,dely,delz); + } + } + } + + if (vflag_fdotr) virial_fdotr_compute(); +} + +/* ---------------------------------------------------------------------- + allocate all arrays +------------------------------------------------------------------------- */ + +void PairTDPD::allocate() +{ + int i,j; + allocated = 1; + int n = atom->ntypes; + + memory->create(setflag,n+1,n+1,"pair:setflag"); + for (i = 1; i <= n; i++) + for (j = i; j <= n; j++) + setflag[i][j] = 0; + + memory->create(cutsq,n+1,n+1,"pair:cutsq"); + + memory->create(cut,n+1,n+1,"pair:cut"); + memory->create(cutcc,n+1,n+1,"pair:cutcc"); + memory->create(a0,n+1,n+1,"pair:a0"); + memory->create(gamma,n+1,n+1,"pair:gamma"); + memory->create(sigma,n+1,n+1,"pair:sigma"); + memory->create(power,n+1,n+1,"pair:power"); + memory->create(kappa,n+1,n+1,cc_species,"pair:kappa"); + memory->create(epsilon,n+1,n+1,cc_species,"pair:epsilon"); + memory->create(powercc,n+1,n+1,cc_species,"pair:powercc"); + + for (i = 0; i <= atom->ntypes; i++) + for (j = 0; j <= atom->ntypes; j++) + sigma[i][j] = gamma[i][j] = 0.0; +} + +/* ---------------------------------------------------------------------- + global settings +------------------------------------------------------------------------- */ + +void PairTDPD::settings(int narg, char **arg) +{ + if (narg != 3) error->all(FLERR,"Illegal pair_style command"); + + temperature = force->numeric(FLERR,arg[0]); + cut_global = force->numeric(FLERR,arg[1]); + seed = force->inumeric(FLERR,arg[2]); + + // initialize Marsaglia RNG with processor-unique seed + + if (seed <= 0 ) { + struct timespec time; + clock_gettime( CLOCK_REALTIME, &time ); + seed = time.tv_nsec; // if seed is non-positive, get the current time as the seed + } + delete random; + random = new RanMars(lmp,(seed + comm->me) % 900000000); + + // reset cutoffs that have been explicitly set + + if (allocated) { + int i,j; + for (i = 1; i <= atom->ntypes; i++) + for (j = i+1; j <= atom->ntypes; j++) + if (setflag[i][j]) + cut[i][j] = cut_global; + } +} + +/* ---------------------------------------------------------------------- + set coeffs for one or more type pairs +------------------------------------------------------------------------- */ + +void PairTDPD::coeff(int narg, char **arg) +{ + if (narg != 7 + 3*cc_species) + error->all(FLERR,"Incorrect args for pair tdpd coefficients"); + if (!allocated) allocate(); + + int ilo,ihi,jlo,jhi; + force->bounds(FLERR,arg[0],atom->ntypes,ilo,ihi); + force->bounds(FLERR,arg[1],atom->ntypes,jlo,jhi); + + double a0_one = force->numeric(FLERR,arg[2]); + double gamma_one = force->numeric(FLERR,arg[3]); + double power_one = force->numeric(FLERR,arg[4]); + double cut_one = force->numeric(FLERR,arg[5]); + double cutcc_one = force->numeric(FLERR,arg[6]); + double kappa_one[cc_species],epsilon_one[cc_species],powercc_one[cc_species]; + for(int k=0; knumeric(FLERR,arg[7+3*k]); + epsilon_one[k] = force->numeric(FLERR,arg[8+3*k]); + powercc_one[k] = force->numeric(FLERR,arg[9+3*k]); + } + + int count = 0; + for (int i = ilo; i <= ihi; i++) + for (int j = MAX(jlo,i); j <= jhi; j++) { + a0[i][j] = a0_one; + gamma[i][j] = gamma_one; + power[i][j] = power_one; + cut[i][j] = cut_one; + cutcc[i][j] = cutcc_one; + for(int k=0; kall(FLERR,"Incorrect args for pair coefficients"); +} + +/* ---------------------------------------------------------------------- + init specific to this pair style +------------------------------------------------------------------------- */ + +void PairTDPD::init_style() +{ + if (comm->ghost_velocity == 0) + error->all(FLERR,"Pair tdpd requires ghost atoms store velocity"); + + // if newton off, forces between atoms ij will be double computed + // using different random numbers + + if (force->newton_pair == 0 && comm->me == 0) error->warning(FLERR, + "Pair tdpd needs newton pair on for momentum conservation"); + + neighbor->request(this,instance_me); +} + +/* ---------------------------------------------------------------------- + init for one type pair i,j and corresponding j,i +------------------------------------------------------------------------- */ + +double PairTDPD::init_one(int i, int j) +{ + if (setflag[i][j] == 0) error->all(FLERR,"All pair coeffs are not set"); + + sigma[i][j] = sqrt(2.0*force->boltz*temperature*gamma[i][j]); + + cut[j][i] = cut[i][j]; + cutcc[j][i] = cutcc[i][j]; + a0[j][i] = a0[i][j]; + gamma[j][i] = gamma[i][j]; + sigma[j][i] = sigma[i][j]; + power[j][i] = power[i][j]; + for(int k=0; kntypes; i++) + for (int j = i; j <= atom->ntypes; j++) { + fwrite(&setflag[i][j],sizeof(int),1,fp); + if (setflag[i][j]) { + fwrite(&a0[i][j],sizeof(double),1,fp); + fwrite(&gamma[i][j],sizeof(double),1,fp); + fwrite(&power[i][j],sizeof(double),1,fp); + fwrite(&cut[i][j],sizeof(double),1,fp); + fwrite(&cutcc[i][j],sizeof(double),1,fp); + for(int k=0; kme; + for (int i = 1; i <= atom->ntypes; i++) + for (int j = i; j <= atom->ntypes; j++) { + if (me == 0) fread(&setflag[i][j],sizeof(int),1,fp); + MPI_Bcast(&setflag[i][j],1,MPI_INT,0,world); + if (setflag[i][j]) { + if (me == 0) { + fread(&a0[i][j],sizeof(double),1,fp); + fread(&gamma[i][j],sizeof(double),1,fp); + fread(&power[i][j],sizeof(double),1,fp); + fread(&cut[i][j],sizeof(double),1,fp); + fread(&cutcc[i][j],sizeof(double),1,fp); + for(int k=0; kme == 0) { + fread(&temperature,sizeof(double),1,fp); + fread(&cut_global,sizeof(double),1,fp); + fread(&seed,sizeof(int),1,fp); + fread(&mix_flag,sizeof(int),1,fp); + } + MPI_Bcast(&temperature,1,MPI_DOUBLE,0,world); + MPI_Bcast(&cut_global,1,MPI_DOUBLE,0,world); + MPI_Bcast(&seed,1,MPI_INT,0,world); + MPI_Bcast(&mix_flag,1,MPI_INT,0,world); + + // initialize Marsaglia RNG with processor-unique seed + // same seed that pair_style command initially specified + + if (random) delete random; + random = new RanMars(lmp,seed + comm->me); +} + +/* ---------------------------------------------------------------------- */ + +double PairTDPD::single(int i, int j, int itype, int jtype, double rsq, + double factor_coul, double factor_dpd, double &fforce) +{ + double r,rinv,wc,phi; + + r = sqrt(rsq); + if (r < EPSILON) { + fforce = 0.0; + return 0.0; + } + + rinv = 1.0/r; + wc = 1.0 - r/cut[itype][jtype]; + fforce = a0[itype][jtype]*wc*factor_dpd*rinv; + + phi = 0.5*a0[itype][jtype]*cut[itype][jtype]*wc*wc; + return factor_dpd*phi; +} diff --git a/src/USER-MESO/pair_tdpd.h b/src/USER-MESO/pair_tdpd.h new file mode 100644 index 0000000000..9245308d38 --- /dev/null +++ b/src/USER-MESO/pair_tdpd.h @@ -0,0 +1,81 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(tdpd,PairTDPD) + +#else + +#ifndef LMP_PAIR_TDPD_H +#define LMP_PAIR_TDPD_H + +#include "pair.h" + +namespace LAMMPS_NS { + +class PairTDPD : public Pair { + public: + PairTDPD(class LAMMPS *); + virtual ~PairTDPD(); + virtual void compute(int, int); + virtual void settings(int, char **); + virtual void coeff(int, char **); + void init_style(); + double init_one(int, int); + virtual void write_restart(FILE *); + virtual void read_restart(FILE *); + virtual void write_restart_settings(FILE *); + virtual void read_restart_settings(FILE *); + double single(int, int, int, int, double, double, double, double &); + + protected: + double cut_global,temperature; + int seed,cc_species; + double **cut,**cutcc; + double **a0,**gamma,**sigma; + double **power; + double ***kappa,***epsilon; + double ***powercc; + class RanMars *random; + + void allocate(); +}; + +} + +#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. + +W: Pair tdpd needs newton pair on for momentum conservation + +Self-explanatory. + +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/atom.cpp b/src/atom.cpp index e46b1a7242..d4c00bc0a5 100644 --- a/src/atom.cpp +++ b/src/atom.cpp @@ -105,6 +105,11 @@ Atom::Atom(LAMMPS *lmp) : Pointers(lmp) dpdTheta = NULL; ssaAIR = NULL; + // USER-MESO + + cc = cc_flux = NULL; + edpd_temp = edpd_flux = edpd_cv = NULL; + // USER-SMD contact_radius = NULL; @@ -169,7 +174,7 @@ Atom::Atom(LAMMPS *lmp) : Pointers(lmp) cs_flag = csforce_flag = vforce_flag = etag_flag = 0; rho_flag = e_flag = cv_flag = vest_flag = 0; - dpd_flag = 0; + dpd_flag = edpd_flag = tdpd_flag = 0; // USER-SMD @@ -302,6 +307,12 @@ Atom::~Atom() memory->destroy(duChem); memory->destroy(ssaAIR); + memory->destroy(cc); + memory->destroy(cc_flux); + memory->destroy(edpd_temp); + memory->destroy(edpd_flux); + memory->destroy(edpd_cv); + memory->destroy(nspecial); memory->destroy(special); @@ -2194,6 +2205,7 @@ void *Atom::extract(char *name) if (strcmp(name, "damage") == 0) return (void *) damage; if (strcmp(name,"dpdTheta") == 0) return (void *) dpdTheta; + if (strcmp(name,"edpd_temp") == 0) return (void *) edpd_temp; return NULL; } diff --git a/src/atom.h b/src/atom.h index 0f84c8242f..29a1c5d69e 100644 --- a/src/atom.h +++ b/src/atom.h @@ -95,6 +95,13 @@ class Atom : protected Pointers { int nspecies_dpd; int *ssaAIR; // Shardlow Splitting Algorithm Active Interaction Region number + // USER-MESO package + + double **cc, **cc_flux; // cc = chemical concentration + double *edpd_temp,*edpd_flux; // temperature and heat flux + double *edpd_cv; // heat capacity + int cc_species; + // molecular info int **nspecial; // 0,1,2 = cumulative # of 1-2,1-3,1-4 neighs @@ -138,7 +145,7 @@ class Atom : protected Pointers { int vfrac_flag,spin_flag,eradius_flag,ervel_flag,erforce_flag; int cs_flag,csforce_flag,vforce_flag,ervelforce_flag,etag_flag; int rho_flag,e_flag,cv_flag,vest_flag; - int dpd_flag; + int dpd_flag,edpd_flag,tdpd_flag; // USER-SMD package diff --git a/src/set.cpp b/src/set.cpp index 59625b7e6c..2b1c0edee2 100644 --- a/src/set.cpp +++ b/src/set.cpp @@ -41,11 +41,12 @@ using namespace LAMMPS_NS; using namespace MathConst; enum{ATOM_SELECT,MOL_SELECT,TYPE_SELECT,GROUP_SELECT,REGION_SELECT}; + enum{TYPE,TYPE_FRACTION,MOLECULE,X,Y,Z,CHARGE,MASS,SHAPE,LENGTH,TRI, DIPOLE,DIPOLE_RANDOM,QUAT,QUAT_RANDOM,THETA,THETA_RANDOM,ANGMOM,OMEGA, DIAMETER,DENSITY,VOLUME,IMAGE,BOND,ANGLE,DIHEDRAL,IMPROPER, - MESO_E,MESO_CV,MESO_RHO,SMD_MASS_DENSITY,SMD_CONTACT_RADIUS,DPDTHETA, - INAME,DNAME}; + MESO_E,MESO_CV,MESO_RHO,EDPD_TEMP,EDPD_CV,CC,SMD_MASS_DENSITY, + SMD_CONTACT_RADIUS,DPDTHETA,INAME,DNAME}; #define BIG INT_MAX @@ -419,6 +420,46 @@ void Set::command(int narg, char **arg) set(MESO_RHO); iarg += 2; + } else if (strcmp(arg[iarg],"edpd/temp") == 0) { + if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (strcmp(arg[iarg+1],"NULL") == 0) dvalue = -1.0; + else if (strstr(arg[iarg+1],"v_") == arg[iarg+1]) varparse(arg[iarg+1],1); + else { + dvalue = force->numeric(FLERR,arg[iarg+1]); + if (dvalue < 0.0) error->all(FLERR,"Illegal set command"); + } + if (!atom->edpd_flag) + error->all(FLERR,"Cannot set edpd/temp for this atom style"); + set(EDPD_TEMP); + iarg += 2; + + } else if (strcmp(arg[iarg],"edpd/cv") == 0) { + if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (strcmp(arg[iarg+1],"NULL") == 0) dvalue = -1.0; + else if (strstr(arg[iarg+1],"v_") == arg[iarg+1]) varparse(arg[iarg+1],1); + else { + dvalue = force->numeric(FLERR,arg[iarg+1]); + if (dvalue < 0.0) error->all(FLERR,"Illegal set command"); + } + if (!atom->edpd_flag) + error->all(FLERR,"Cannot set edpd/cv for this atom style"); + set(EDPD_CV); + iarg += 2; + + } else if (strcmp(arg[iarg],"cc") == 0) { + if (iarg+3 > narg) error->all(FLERR,"Illegal set command"); + if (strcmp(arg[iarg+1],"NULL") == 0) dvalue = -1.0; + else if (strstr(arg[iarg+1],"v_") == arg[iarg+1]) varparse(arg[iarg+1],1); + else { + cc_index = force->inumeric(FLERR,arg[iarg+1]); + dvalue = force->numeric(FLERR,arg[iarg+2]); + if (cc_index < 1) error->all(FLERR,"Illegal set command"); + } + if (!atom->tdpd_flag) + error->all(FLERR,"Cannot set cc for this atom style"); + set(CC); + iarg += 3; + } else if (strcmp(arg[iarg],"smd/mass/density") == 0) { if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); if (strstr(arg[iarg+1],"v_") == arg[iarg+1]) varparse(arg[iarg+1],1); @@ -476,14 +517,28 @@ void Set::command(int narg, char **arg) } else error->all(FLERR,"Illegal set command"); // statistics + // for CC option, include species index MPI_Allreduce(&count,&allcount,1,MPI_INT,MPI_SUM,world); if (comm->me == 0) { - if (screen) fprintf(screen," %d settings made for %s\n", - allcount,arg[origarg]); - if (logfile) fprintf(logfile," %d settings made for %s\n", - allcount,arg[origarg]); + + if (screen) { + if (strcmp(arg[origarg],"cc") == 0) + fprintf(screen," %d settings made for %s index %s\n", + allcount,arg[origarg],arg[origarg+1]); + else + fprintf(screen," %d settings made for %s\n", + allcount,arg[origarg]); + } + if (logfile) { + if (strcmp(arg[origarg],"cc") == 0) + fprintf(logfile," %d settings made for %s index %s\n", + allcount,arg[origarg],arg[origarg+1]); + else + fprintf(logfile," %d settings made for %s\n", + allcount,arg[origarg]); + } } } @@ -663,6 +718,11 @@ void Set::set(int keyword) else if (keyword == MESO_E) atom->e[i] = dvalue; else if (keyword == MESO_CV) atom->cv[i] = dvalue; else if (keyword == MESO_RHO) atom->rho[i] = dvalue; + + else if (keyword == EDPD_TEMP) atom->edpd_temp[i] = dvalue; + else if (keyword == EDPD_CV) atom->edpd_cv[i] = dvalue; + else if (keyword == CC) atom->cc[i][cc_index-1] = dvalue; + else if (keyword == SMD_MASS_DENSITY) { // set mass from volume and supplied mass density atom->rmass[i] = atom->vfrac[i] * dvalue; diff --git a/src/set.h b/src/set.h index dfb06a2e12..5584e228ba 100644 --- a/src/set.h +++ b/src/set.h @@ -35,7 +35,8 @@ class Set : protected Pointers { int style,ivalue,newtype,count,index_custom; int ximage,yimage,zimage,ximageflag,yimageflag,zimageflag; double dvalue,xvalue,yvalue,zvalue,wvalue,fraction; - + int cc_index; + int varflag,varflag1,varflag2,varflag3,varflag4; int ivar1,ivar2,ivar3,ivar4; double *vec1,*vec2,*vec3,*vec4; From aa1ce09b126414f3292a00992420511a8777fde7 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 18 Aug 2017 20:03:47 -0400 Subject: [PATCH 374/439] more cleanup, checks and generalization of QEQ parameter file parsing --- src/QEQ/fix_qeq.cpp | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/src/QEQ/fix_qeq.cpp b/src/QEQ/fix_qeq.cpp index 38bfec8b96..757eae5dd2 100644 --- a/src/QEQ/fix_qeq.cpp +++ b/src/QEQ/fix_qeq.cpp @@ -692,11 +692,13 @@ void FixQEq::vector_add( double* dest, double c, double* v, int k ) void FixQEq::read_file(char *file) { - int itype,ntypes; + int i; int params_per_line = 6; char **words = new char*[params_per_line+1]; - ntypes = atom->ntypes; + int ntypes = atom->ntypes; + int *setflag = new int[ntypes+1]; + for (i=0; i < params_per_line; ++i) setflag[i] = 0; memory->create(chi,ntypes+1,"qeq:chi"); memory->create(eta,ntypes+1,"qeq:eta"); @@ -719,10 +721,10 @@ void FixQEq::read_file(char *file) // read each line out of file, skipping blank lines or leading '#' // store line of params if all 3 element tags are in element list - int n,nwords,ielement,eof; + int n,nwords,eof,nlo,nhi; char line[MAXLINE],*ptr; - eof = ielement = 0; + eof = 0; while (1) { if (comm->me == 0) { @@ -737,10 +739,6 @@ void FixQEq::read_file(char *file) MPI_Bcast(&n,1,MPI_INT,0,world); MPI_Bcast(line,n,MPI_CHAR,0,world); - ielement ++; - if (ielement > ntypes) - error->all(FLERR,"Invalid fix qeq parameter file"); - // strip comment, skip line if blank if ((ptr = strchr(line,'#'))) *ptr = '\0'; @@ -752,21 +750,28 @@ void FixQEq::read_file(char *file) if (nwords < 6) error->all(FLERR,"Invalid fix qeq parameter file"); - // words = ptrs to first 6 words in line for (n=0, words[n] = strtok(line," \t\n\r\f"); n < 6; words[++n] = strtok(NULL," \t\n\r\f")); - itype = force->inumeric(FLERR,words[0]); - if ((itype < 1) || (itype > atom->ntypes)) - error->all(FLERR,"Invalid fix qeq parameter file"); - chi[itype] = force->numeric(FLERR,words[1]); - eta[itype] = force->numeric(FLERR,words[2]); - gamma[itype] = force->numeric(FLERR,words[3]); - zeta[itype] = force->numeric(FLERR,words[4]); - zcore[itype] = force->numeric(FLERR,words[5]); + force->bounds(FLERR,words[0],ntypes,nlo,nhi); + for (n=nlo; n <=nhi; ++n) { + chi[n] = force->numeric(FLERR,words[1]); + eta[n] = force->numeric(FLERR,words[2]); + gamma[n] = force->numeric(FLERR,words[3]); + zeta[n] = force->numeric(FLERR,words[4]); + zcore[n] = force->numeric(FLERR,words[5]); + setflag[n] = 1; + } } + + // check if all types are set + for (n=1; n <= ntypes; ++n) + if (setflag[n] == 0) + error->all(FLERR,"Invalid fix qeq parameter file"); + delete [] words; + delete [] setflag; } From c5ce3ffe60e40f186cb8b63b4233ccfed7d229dd Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sun, 20 Aug 2017 09:18:04 -0400 Subject: [PATCH 375/439] use list of bonds per atom instead of bondlist, as that will work with shake as well --- src/compute_fragment_atom.cpp | 29 ++++++++++------------------- 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/src/compute_fragment_atom.cpp b/src/compute_fragment_atom.cpp index 02a0b8e7dc..5024ada4f4 100644 --- a/src/compute_fragment_atom.cpp +++ b/src/compute_fragment_atom.cpp @@ -90,9 +90,6 @@ void ComputeFragmentAtom::compute_peratom() vector_atom = fragmentID; } - int nbondlist = neighbor->nbondlist; - int **bondlist = neighbor->bondlist; - // if group is dynamic, insure ghost atom masks are current if (group->dynamic[igroup]) { @@ -100,21 +97,17 @@ void ComputeFragmentAtom::compute_peratom() comm->forward_comm_compute(this); } - // every bond starts in its own fragment, - // with fragmentID = MIN(b1atomID,b2atomID) - // only bonds wholly contained in the group are considered + // each atom starts in its own fragment, + int nlocal = atom->nlocal; tagint *tag = atom->tag; int *mask = atom->mask; + int *num_bond = atom->num_bond; + tagint **bond_atom = atom->bond_atom; - for (i = 0; i < nbondlist; i++) { - const int b1 = bondlist[i][0]; - const int b2 = bondlist[i][1]; - - if ((mask[b1] & groupbit) && (mask[b2] & groupbit)) - fragmentID[b1] = fragmentID[b2] = MIN(tag[b1],tag[b2]); - else fragmentID[b1] = fragmentID[b2] = 0; - } + for (i = 0; i < nlocal + atom->nghost; i++) + if (mask[i] & groupbit) fragmentID[i] = tag[i]; + else fragmentID[i] = 0; // loop until no more changes on any proc: // acquire fragmentIDs of ghost atoms @@ -124,9 +117,6 @@ void ComputeFragmentAtom::compute_peratom() // then check if any proc made changes commflag = 1; - int nlocal = atom->nlocal; - int *num_bond = atom->num_bond; - tagint **bond_atom = atom->bond_atom; int change,done,anychange; @@ -138,9 +128,10 @@ void ComputeFragmentAtom::compute_peratom() done = 1; for (i = 0; i < nlocal; i++) { if (!(mask[i] & groupbit)) continue; - + for (j = 0; j < num_bond[i]; j++) { - k = bond_atom[i][j]; + k = atom->map(bond_atom[i][j]); + if (k < 0) continue; if (!(mask[k] & groupbit)) continue; if (fragmentID[i] == fragmentID[k]) continue; From 35fd82b602828463dfa151325086b2e2d67309b2 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sun, 20 Aug 2017 09:19:04 -0400 Subject: [PATCH 376/439] trim unneeded includes --- src/compute_fragment_atom.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/compute_fragment_atom.cpp b/src/compute_fragment_atom.cpp index 5024ada4f4..7417c26831 100644 --- a/src/compute_fragment_atom.cpp +++ b/src/compute_fragment_atom.cpp @@ -21,9 +21,7 @@ #include "atom_vec.h" #include "update.h" #include "modify.h" -#include "neighbor.h" #include "force.h" -#include "pair.h" #include "comm.h" #include "memory.h" #include "error.h" From 4dc1195cd8511cb08b203eef1da0ac3c5a10fd49 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sun, 20 Aug 2017 09:41:49 -0400 Subject: [PATCH 377/439] add docs for compute fragment/atom --- doc/src/Section_commands.txt | 1 + doc/src/compute_cluster_atom.txt | 38 +++++++++++++++++++++----------- 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/doc/src/Section_commands.txt b/doc/src/Section_commands.txt index 571c6c4920..0211bbe055 100644 --- a/doc/src/Section_commands.txt +++ b/doc/src/Section_commands.txt @@ -775,6 +775,7 @@ KOKKOS, o = USER-OMP, t = OPT. "erotate/sphere"_compute_erotate_sphere.html, "erotate/sphere/atom"_compute_erotate_sphere_atom.html, "event/displace"_compute_event_displace.html, +"fragment/atom"_compute_cluster_atom.html, "global/atom"_compute_global_atom.html, "group/group"_compute_group_group.html, "gyration"_compute_gyration.html, diff --git a/doc/src/compute_cluster_atom.txt b/doc/src/compute_cluster_atom.txt index 147d06c2a8..c01c2010c5 100644 --- a/doc/src/compute_cluster_atom.txt +++ b/doc/src/compute_cluster_atom.txt @@ -7,37 +7,49 @@ :line compute cluster/atom command :h3 +compute fragment/atom command :h3 [Syntax:] -compute ID group-ID cluster/atom cutoff :pre +compute ID group-ID cluster/atom cutoff +compute ID group-ID fragment/atom :pre ID, group-ID are documented in "compute"_compute.html command -cluster/atom = style name of this compute command -cutoff = distance within which to label atoms as part of same cluster (distance units) :ul +{cluster/atom} or {fragment/atom} = style name of this compute command +cutoff = distance within which to label atoms as part of same cluster (distance units, cluster/atom only) :ul [Examples:] -compute 1 all cluster/atom 1.0 :pre +compute 1 all cluster/atom 3.5 +compute 1 all fragment/atom :pre [Description:] -Define a computation that assigns each atom a cluster ID. +Define a computation that assigns each atom a cluster ID or fragment ID. A cluster is defined as a set of atoms, each of which is within the cutoff distance from one or more other atoms in the cluster. If an atom has no neighbors within the cutoff distance, then it is a 1-atom -cluster. The ID of every atom in the cluster will be the smallest -atom ID of any atom in the cluster. +cluster. A fragment is similarly define as a set of atoms, each of +which has an explicit bond (i.e. defined via a "data file"_read_data.html, +the "create_bonds"_create_bonds.html command, or through fixes like +"fix bond/create"_fix_bond_create.html, "fix bond/swap"_fix_bond_swap.html, +or "fix bond/break"_fix_bond_break.html). The cluster ID or fragment ID +of every atom in the cluster will be set to the smallest atom ID of any atom +in the cluster or fragment, respectively. Only atoms in the compute group are clustered and assigned cluster -IDs. Atoms not in the compute group are assigned a cluster ID = 0. +IDs. Atoms not in the compute group are assigned a cluster ID = 0. +For fragments, only bonds where [both] atoms of the bond are included +in the compute group are assigned to fragments, so that only fragmets +are detected where [all] atoms are in the compute group. Thus atoms +may be included in the compute group, yes still have a fragment ID of 0. -The neighbor list needed to compute this quantity is constructed each -time the calculation is performed (i.e. each time a snapshot of atoms -is dumped). Thus it can be inefficient to compute/dump this quantity -too frequently or to have multiple compute/dump commands, each of a -{cluster/atom} style. +For compute {cluster/atom} the neighbor list needed to compute this quantity +is constructed each time the calculation is performed (i.e. each time a +snapshot of atoms is dumped). Thus it can be inefficient to compute/dump +this quantity too frequently or to have multiple compute/dump commands, +each of a {cluster/atom} style. NOTE: If you have a bonded system, then the settings of "special_bonds"_special_bonds.html command can remove pairwise From c895df73d624570703d2c56256c87abe92421ccf Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sun, 20 Aug 2017 09:47:51 -0400 Subject: [PATCH 378/439] skip over disabled bonds --- src/compute_fragment_atom.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/compute_fragment_atom.cpp b/src/compute_fragment_atom.cpp index 7417c26831..2dfb20a570 100644 --- a/src/compute_fragment_atom.cpp +++ b/src/compute_fragment_atom.cpp @@ -101,6 +101,7 @@ void ComputeFragmentAtom::compute_peratom() tagint *tag = atom->tag; int *mask = atom->mask; int *num_bond = atom->num_bond; + int **bond_type = atom->bond_type; tagint **bond_atom = atom->bond_atom; for (i = 0; i < nlocal + atom->nghost; i++) @@ -128,6 +129,7 @@ void ComputeFragmentAtom::compute_peratom() if (!(mask[i] & groupbit)) continue; for (j = 0; j < num_bond[i]; j++) { + if (bond_type[i][j] == 0) continue; k = atom->map(bond_atom[i][j]); if (k < 0) continue; if (!(mask[k] & groupbit)) continue; From 39e51df2c0045078591fc58d7ac6364ed06eaa6b Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sun, 20 Aug 2017 10:02:11 -0400 Subject: [PATCH 379/439] add missing entry in pdf manual --- doc/src/lammps.book | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/src/lammps.book b/doc/src/lammps.book index 76b6743657..c444a6bb69 100644 --- a/doc/src/lammps.book +++ b/doc/src/lammps.book @@ -21,6 +21,7 @@ Section_python.html Section_errors.html Section_history.html +tutorial_bash_on_windows.html tutorial_drude.html tutorial_github.html tutorial_pylammps.html From f5b8f722eee363909877e0120529520ace068e5d Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sun, 20 Aug 2017 10:09:21 -0400 Subject: [PATCH 380/439] remove non-portable non-ascii blanks from fix wall/ees docs --- doc/src/fix_wall_ees.txt | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/doc/src/fix_wall_ees.txt b/doc/src/fix_wall_ees.txt index a8688e8e41..f141a19405 100644 --- a/doc/src/fix_wall_ees.txt +++ b/doc/src/fix_wall_ees.txt @@ -50,17 +50,17 @@ fix ees_cube all wall/region/ees myCube 1.0 1.0 2.5 :pre Fix {wall/ees} bounds the simulation domain on one or more of its faces with a flat wall that interacts with the ellipsoidal atoms in the group by generating a force on the atom in a direction perpendicular to -the wall and a torque parallel with the wall.  The energy of +the wall and a torque parallel with the wall. The energy of wall-particle interactions E is given by: :c,image(Eqs/fix_wall_ees.jpg) Introduced by Babadi and Ejtehadi in "(Babadi)"_#BabadiEjtehadi. Here, {r} is the distance from the particle to the wall at position {coord}, -and Rc is the {cutoff} distance at which the  particle and wall no -longer interact. Also,  sigma_n is the distance between center of -ellipsoid and the nearest point of its surface to the wall  The energy -of the wall (see the image below). +and Rc is the {cutoff} distance at which the particle and wall no +longer interact. Also, sigma_n is the distance between center of +ellipsoid and the nearest point of its surface to the wall. The energy +of the wall is: :c,image(JPG/fix_wall_ees_image.jpg) @@ -68,21 +68,22 @@ Details of using this command and specifications are the same as fix/wall command. You can also find an example in USER/ees/ under examples/ directory. -The prefactor {epsilon} can be thought of as an -effective Hamaker constant with energy units for the strength of the -ellipsoid-wall interaction.  More specifically, the {epsilon} pre-factor -= 8 * pi^2 * rho_wall * rho_ellipsoid * epsilon -* sigma_a * sigma_b * sigma_c, where epsilon is the LJ parameters for -the constituent LJ particles and sigma_a, sigma_b, and sigma_c are radii -of ellipsoidal particles. Rho_wall and rho_ellipsoid are the number +The prefactor {epsilon} can be thought of as an +effective Hamaker constant with energy units for the strength of the +ellipsoid-wall interaction. More specifically, the {epsilon} pre-factor += 8 * pi^2 * rho_wall * rho_ellipsoid * epsilon +* sigma_a * sigma_b * sigma_c, where epsilon is the LJ parameters for +the constituent LJ particles and sigma_a, sigma_b, and sigma_c are radii +of ellipsoidal particles. Rho_wall and rho_ellipsoid are the number density of the constituent particles, in the wall and ellipsoid respectively, in units of 1/volume. NOTE: You must insure that r is always bigger than sigma_n for -all particles in the group, or LAMMPS will generate an error.  This +all particles in the group, or LAMMPS will generate an error. This means you cannot start your simulation with particles touching the wall -position {coord} (r = sigma_n) or with particles penetrating the wall (0 =< r < sigma_n) or with particles on the wrong side of the -wall (r < 0). +position {coord} (r = sigma_n) or with particles penetrating the wall +(0 =< r < sigma_n) or with particles on the wrong side of the +wall (r < 0). Fix {wall/region/ees} treats the surface of the geometric region defined @@ -93,7 +94,7 @@ Other details of this command are the same as for the "fix wall/region"_fix_wall_region.html command. One may also find an example of using this fix in the examples/USER/misc/ees/ directory. -[Restrictions:] +[Restrictions:] This fix is part of the USER-MISC package. It is only enabled if LAMMPS was built with that package. See the "Making From d1a0c040c9f8cb9da218cfe5ae11fea15ac9fcf5 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sun, 20 Aug 2017 23:28:13 -0400 Subject: [PATCH 381/439] add initializers for nmatch/nwant variables in molecule file parser --- src/molecule.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/molecule.cpp b/src/molecule.cpp index b0fec4bcbc..ff209fda21 100644 --- a/src/molecule.cpp +++ b/src/molecule.cpp @@ -1219,7 +1219,7 @@ void Molecule::shakeflag_read(char *line) void Molecule::shakeatom_read(char *line) { - int tmp, nmatch, nwant; + int tmp, nmatch=0, nwant=0; for (int i = 0; i < natoms; i++) { readline(line); if (shake_flag[i] == 1) { @@ -1262,7 +1262,7 @@ void Molecule::shakeatom_read(char *line) void Molecule::shaketype_read(char *line) { - int tmp,nmatch,nwant; + int tmp, nmatch=0, nwant=0; for (int i = 0; i < natoms; i++) { readline(line); if (shake_flag[i] == 1) { From 5a0c3aea8ac1413ae026e011171a70b37378ec28 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 21 Aug 2017 13:12:43 -0400 Subject: [PATCH 382/439] add a compute aggregate/atom, that combines the rules for compute cluster/atom and fragment/atom --- doc/src/compute_cluster_atom.txt | 33 ++-- src/compute_aggregate_atom.cpp | 270 +++++++++++++++++++++++++++++++ src/compute_aggregate_atom.h | 70 ++++++++ 3 files changed, 363 insertions(+), 10 deletions(-) create mode 100644 src/compute_aggregate_atom.cpp create mode 100644 src/compute_aggregate_atom.h diff --git a/doc/src/compute_cluster_atom.txt b/doc/src/compute_cluster_atom.txt index c01c2010c5..0aa38ae590 100644 --- a/doc/src/compute_cluster_atom.txt +++ b/doc/src/compute_cluster_atom.txt @@ -8,29 +8,35 @@ compute cluster/atom command :h3 compute fragment/atom command :h3 +compute aggregate/atom command :h3 [Syntax:] compute ID group-ID cluster/atom cutoff -compute ID group-ID fragment/atom :pre +compute ID group-ID fragment/atom +compute ID group-ID aggregate/atom cutoff :pre ID, group-ID are documented in "compute"_compute.html command -{cluster/atom} or {fragment/atom} = style name of this compute command -cutoff = distance within which to label atoms as part of same cluster (distance units, cluster/atom only) :ul +{cluster/atom} or {fragment/atom} or {aggregate/atom} = style name of this compute command +cutoff = distance within which to label atoms as part of same cluster (distance units) :ul [Examples:] compute 1 all cluster/atom 3.5 compute 1 all fragment/atom :pre +compute 1 all aggregate/atom 3.5 :pre [Description:] -Define a computation that assigns each atom a cluster ID or fragment ID. +Define a computation that assigns each atom a cluster, fragement, +or aggregate ID. A cluster is defined as a set of atoms, each of which is within the cutoff distance from one or more other atoms in the cluster. If an atom has no neighbors within the cutoff distance, then it is a 1-atom -cluster. A fragment is similarly define as a set of atoms, each of +cluster. + +A fragment is similarly defined as a set of atoms, each of which has an explicit bond (i.e. defined via a "data file"_read_data.html, the "create_bonds"_create_bonds.html command, or through fixes like "fix bond/create"_fix_bond_create.html, "fix bond/swap"_fix_bond_swap.html, @@ -38,6 +44,12 @@ or "fix bond/break"_fix_bond_break.html). The cluster ID or fragment ID of every atom in the cluster will be set to the smallest atom ID of any atom in the cluster or fragment, respectively. +An aggregate is defined by combining the rules for clusters and +fragments, i.e. a set of atoms, where each of it is within the cutoff +distance from one or more atoms within a fragment that is part of +the same cluster. This measure can be used to track molecular assemblies +like micelles. + Only atoms in the compute group are clustered and assigned cluster IDs. Atoms not in the compute group are assigned a cluster ID = 0. For fragments, only bonds where [both] atoms of the bond are included @@ -45,11 +57,12 @@ in the compute group are assigned to fragments, so that only fragmets are detected where [all] atoms are in the compute group. Thus atoms may be included in the compute group, yes still have a fragment ID of 0. -For compute {cluster/atom} the neighbor list needed to compute this quantity -is constructed each time the calculation is performed (i.e. each time a -snapshot of atoms is dumped). Thus it can be inefficient to compute/dump -this quantity too frequently or to have multiple compute/dump commands, -each of a {cluster/atom} style. +For computes {cluster/atom} and {aggregate/atom} the neighbor list needed +to compute this quantity is constructed each time the calculation is +performed (i.e. each time a snapshot of atoms is dumped). Thus it can be +inefficient to compute/dump this quantity too frequently or to have +multiple compute/dump commands, each of a {cluster/atom} or +{aggregate/atom} style. NOTE: If you have a bonded system, then the settings of "special_bonds"_special_bonds.html command can remove pairwise diff --git a/src/compute_aggregate_atom.cpp b/src/compute_aggregate_atom.cpp new file mode 100644 index 0000000000..1155ac437a --- /dev/null +++ b/src/compute_aggregate_atom.cpp @@ -0,0 +1,270 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Axel Kohlmeyer (Temple U) +------------------------------------------------------------------------- */ + +#include +#include "compute_aggregate_atom.h" +#include "atom.h" +#include "atom_vec.h" +#include "update.h" +#include "modify.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "neigh_request.h" +#include "pair.h" +#include "force.h" +#include "comm.h" +#include "memory.h" +#include "error.h" + +#include "group.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +ComputeAggregateAtom::ComputeAggregateAtom(LAMMPS *lmp, int narg, char **arg) : + Compute(lmp, narg, arg), + aggregateID(NULL) +{ + if (narg != 4) error->all(FLERR,"Illegal compute aggregate/atom command"); + + double cutoff = force->numeric(FLERR,arg[3]); + cutsq = cutoff*cutoff; + + if (atom->avec->bonds_allow == 0) + error->all(FLERR,"Compute aggregate/atom used when bonds are not allowed"); + + peratom_flag = 1; + size_peratom_cols = 0; + comm_forward = 1; + + nmax = 0; +} + +/* ---------------------------------------------------------------------- */ + +ComputeAggregateAtom::~ComputeAggregateAtom() +{ + memory->destroy(aggregateID); +} + +/* ---------------------------------------------------------------------- */ + +void ComputeAggregateAtom::init() +{ + if (atom->tag_enable == 0) + error->all(FLERR,"Cannot use compute aggregate/atom unless atoms have IDs"); + if (force->bond == NULL) + error->all(FLERR,"Compute aggregate/atom requires a bond style to be defined"); + + if (force->pair == NULL) + error->all(FLERR,"Compute cluster/atom requires a pair style to be defined"); + if (sqrt(cutsq) > force->pair->cutforce) + error->all(FLERR, + "Compute cluster/atom cutoff is longer than pairwise cutoff"); + + // need an occasional full neighbor list + // full required so that pair of atoms on 2 procs both set their clusterID + + int irequest = neighbor->request(this,instance_me); + neighbor->requests[irequest]->pair = 0; + neighbor->requests[irequest]->compute = 1; + neighbor->requests[irequest]->half = 0; + neighbor->requests[irequest]->full = 1; + neighbor->requests[irequest]->occasional = 1; + + int count = 0; + for (int i = 0; i < modify->ncompute; i++) + if (strcmp(modify->compute[i]->style,"aggregate/atom") == 0) count++; + if (count > 1 && comm->me == 0) + error->warning(FLERR,"More than one compute aggregate/atom"); +} + +/* ---------------------------------------------------------------------- */ + +void ComputeAggregateAtom::init_list(int id, NeighList *ptr) +{ + list = ptr; +} + +/* ---------------------------------------------------------------------- */ + +void ComputeAggregateAtom::compute_peratom() +{ + int i,j,k; + + invoked_peratom = update->ntimestep; + + // grow aggregateID array if necessary + + if (atom->nmax > nmax) { + memory->destroy(aggregateID); + nmax = atom->nmax; + memory->create(aggregateID,nmax,"aggregate/atom:aggregateID"); + vector_atom = aggregateID; + } + + // invoke full neighbor list (will copy or build if necessary) + + neighbor->build_one(list); + + // if group is dynamic, insure ghost atom masks are current + + if (group->dynamic[igroup]) { + commflag = 0; + comm->forward_comm_compute(this); + } + + // each atom starts in its own aggregate, + + int nlocal = atom->nlocal; + int inum = list->inum; + tagint *tag = atom->tag; + int *mask = atom->mask; + int *num_bond = atom->num_bond; + int **bond_type = atom->bond_type; + tagint **bond_atom = atom->bond_atom; + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + double **x = atom->x; + + for (i = 0; i < nlocal + atom->nghost; i++) + if (mask[i] & groupbit) aggregateID[i] = tag[i]; + else aggregateID[i] = 0; + + // loop until no more changes on any proc: + // acquire aggregateIDs of ghost atoms + // loop over my atoms, and check atoms bound to it + // if both atoms are in aggregate, assign lowest aggregateID to both + // then loop over my atoms, checking distance to neighbors + // if both atoms are in cluster, assign lowest clusterID to both + // iterate until no changes in my atoms + // then check if any proc made changes + + commflag = 1; + + int change,done,anychange; + + while (1) { + comm->forward_comm_compute(this); + + change = 0; + while (1) { + done = 1; + for (i = 0; i < nlocal; i++) { + if (!(mask[i] & groupbit)) continue; + + for (j = 0; j < num_bond[i]; j++) { + if (bond_type[i][j] == 0) continue; + k = atom->map(bond_atom[i][j]); + if (k < 0) continue; + if (!(mask[k] & groupbit)) continue; + if (aggregateID[i] == aggregateID[k]) continue; + + aggregateID[i] = aggregateID[k] = MIN(aggregateID[i],aggregateID[k]); + done = 0; + } + } + + for (int ii = 0; ii < inum; ii++) { + i = ilist[ii]; + if (!(mask[i] & groupbit)) continue; + + const double xtmp = x[i][0]; + const double ytmp = x[i][1]; + const double ztmp = x[i][2]; + int *jlist = firstneigh[i]; + const int jnum = numneigh[i]; + + for (int jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + j &= NEIGHMASK; + if (!(mask[j] & groupbit)) continue; + if (aggregateID[i] == aggregateID[j]) continue; + + const double delx = xtmp - x[j][0]; + const double dely = ytmp - x[j][1]; + const double delz = ztmp - x[j][2]; + const double rsq = delx*delx + dely*dely + delz*delz; + if (rsq < cutsq) { + aggregateID[i] = aggregateID[j] + = MIN(aggregateID[i],aggregateID[j]); + done = 0; + } + } + } + if (!done) change = 1; + if (done) break; + } + + // stop if all procs are done + + MPI_Allreduce(&change,&anychange,1,MPI_INT,MPI_MAX,world); + if (!anychange) break; + } +} + +/* ---------------------------------------------------------------------- */ + +int ComputeAggregateAtom::pack_forward_comm(int n, int *list, double *buf, + int pbc_flag, int *pbc) +{ + int i,j,m; + + m = 0; + if (commflag) { + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = aggregateID[j]; + } + } else { + int *mask = atom->mask; + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = ubuf(mask[j]).d; + } + } + + return m; +} + +/* ---------------------------------------------------------------------- */ + +void ComputeAggregateAtom::unpack_forward_comm(int n, int first, double *buf) +{ + int i,m,last; + + m = 0; + last = first + n; + if (commflag) + for (i = first; i < last; i++) aggregateID[i] = buf[m++]; + else { + int *mask = atom->mask; + for (i = first; i < last; i++) mask[i] = (int) ubuf(buf[m++]).i; + } +} + +/* ---------------------------------------------------------------------- + memory usage of local atom-based array +------------------------------------------------------------------------- */ + +double ComputeAggregateAtom::memory_usage() +{ + double bytes = nmax * sizeof(double); + return bytes; +} diff --git a/src/compute_aggregate_atom.h b/src/compute_aggregate_atom.h new file mode 100644 index 0000000000..8170aabc7f --- /dev/null +++ b/src/compute_aggregate_atom.h @@ -0,0 +1,70 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef COMPUTE_CLASS + +ComputeStyle(aggregate/atom,ComputeAggregateAtom) + +#else + +#ifndef LMP_COMPUTE_AGGREGATE_ATOM_H +#define LMP_COMPUTE_AGGREGATE_ATOM_H + +#include "compute.h" + +namespace LAMMPS_NS { + +class ComputeAggregateAtom : public Compute { + public: + ComputeAggregateAtom(class LAMMPS *, int, char **); + ~ComputeAggregateAtom(); + void init(); + void init_list(int, class NeighList *); + void compute_peratom(); + int pack_forward_comm(int, int *, double *, int, int *); + void unpack_forward_comm(int, int, double *); + double memory_usage(); + + private: + int nmax,commflag; + double cutsq; + class NeighList *list; + double *aggregateID; +}; + +} + +#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: Cannot use compute aggregate/atom unless atoms have IDs + +Atom IDs are used to identify aggregates. + +E: Compute aggregate/atom requires a bond style to be defined + +This is so that a bond list is generated which is used to find aggregates. + +W: More than one compute aggregate/atom + +It is not efficient to use compute aggregate/atom more than once. + +*/ From 24c00b1f7a202b45100eb59f94843b484bcc5c3a Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 21 Aug 2017 13:12:48 -0400 Subject: [PATCH 383/439] fix typo --- src/compute_cluster_atom.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compute_cluster_atom.cpp b/src/compute_cluster_atom.cpp index 80c002d39f..5ee6368504 100644 --- a/src/compute_cluster_atom.cpp +++ b/src/compute_cluster_atom.cpp @@ -63,7 +63,7 @@ void ComputeClusterAtom::init() if (atom->tag_enable == 0) error->all(FLERR,"Cannot use compute cluster/atom unless atoms have IDs"); if (force->pair == NULL) - error->all(FLERR,"Compute cluster/atom requires a pair style be defined"); + error->all(FLERR,"Compute cluster/atom requires a pair style to be defined"); if (sqrt(cutsq) > force->pair->cutforce) error->all(FLERR, "Compute cluster/atom cutoff is longer than pairwise cutoff"); From 090c792d9070f4687931131df26043f8f4a04d58 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 22 Aug 2017 13:42:02 -0600 Subject: [PATCH 384/439] Update Kokkos library to v2.04.00 --- lib/kokkos/CHANGELOG.md | 17 + lib/kokkos/Makefile.kokkos | 101 +- lib/kokkos/Makefile.targets | 11 + lib/kokkos/README | 22 + lib/kokkos/config/kokkos-promotion.txt | 140 ++ lib/kokkos/config/master_history.txt | 1 + lib/kokkos/config/test_all_sandia | 1 - lib/kokkos/core/cmake/KokkosCore_config.h.in | 22 +- lib/kokkos/core/src/CMakeLists.txt | 24 - lib/kokkos/core/src/Kokkos_Array.hpp | 12 +- lib/kokkos/core/src/Kokkos_Atomic.hpp | 18 + lib/kokkos/core/src/Kokkos_Complex.hpp | 19 +- lib/kokkos/core/src/Kokkos_Core.hpp | 4 + lib/kokkos/core/src/Kokkos_Core_fwd.hpp | 11 + lib/kokkos/core/src/Kokkos_Crs.hpp | 102 +- lib/kokkos/core/src/Kokkos_Macros.hpp | 61 +- lib/kokkos/core/src/Kokkos_MemoryPool.hpp | 14 +- .../core/src/Kokkos_Parallel_Reduce.hpp | 4 +- lib/kokkos/core/src/Kokkos_ROCm.hpp | 220 +++ lib/kokkos/core/src/Kokkos_ROCmSpace.hpp | 622 ++++++++ lib/kokkos/core/src/Kokkos_TaskScheduler.hpp | 61 + lib/kokkos/core/src/Kokkos_View.hpp | 1 + .../core/src/ROCm/Kokkos_ROCm_Atomic.hpp | 439 ++++++ .../core/src/ROCm/Kokkos_ROCm_Config.hpp | 51 + lib/kokkos/core/src/ROCm/Kokkos_ROCm_Exec.cpp | 133 ++ lib/kokkos/core/src/ROCm/Kokkos_ROCm_Exec.hpp | 137 ++ lib/kokkos/core/src/ROCm/Kokkos_ROCm_Impl.cpp | 753 ++++++++++ .../core/src/ROCm/Kokkos_ROCm_Invoke.hpp | 138 ++ lib/kokkos/core/src/ROCm/Kokkos_ROCm_Join.hpp | 72 + .../core/src/ROCm/Kokkos_ROCm_Parallel.hpp | 1265 +++++++++++++++++ .../core/src/ROCm/Kokkos_ROCm_Reduce.hpp | 193 +++ .../core/src/ROCm/Kokkos_ROCm_ReduceScan.hpp | 605 ++++++++ lib/kokkos/core/src/ROCm/Kokkos_ROCm_Scan.hpp | 157 ++ .../core/src/ROCm/Kokkos_ROCm_Space.cpp | 726 ++++++++++ lib/kokkos/core/src/ROCm/Kokkos_ROCm_Task.cpp | 174 +++ lib/kokkos/core/src/ROCm/Kokkos_ROCm_Task.hpp | 458 ++++++ lib/kokkos/core/src/ROCm/Kokkos_ROCm_Tile.hpp | 518 +++++++ .../src/ROCm/Kokkos_ROCm_Vectorization.hpp | 346 +++++ lib/kokkos/core/src/ROCm/hc_math_std.hpp | 367 +++++ .../Kokkos_Atomic_Compare_Exchange_Strong.hpp | 2 + .../core/src/impl/Kokkos_Atomic_Fetch_Add.hpp | 2 + .../core/src/impl/Kokkos_Atomic_Fetch_Sub.hpp | 3 + .../core/src/impl/Kokkos_Atomic_Generic.hpp | 4 +- lib/kokkos/core/src/impl/Kokkos_BitOps.hpp | 8 + lib/kokkos/core/src/impl/Kokkos_ClockTic.hpp | 4 + lib/kokkos/core/src/impl/Kokkos_Core.cpp | 27 +- lib/kokkos/core/src/impl/Kokkos_Error.hpp | 2 +- .../core/src/impl/Kokkos_HostThreadTeam.cpp | 4 +- .../core/src/impl/Kokkos_Memory_Fence.hpp | 2 + lib/kokkos/core/src/impl/Kokkos_OldMacros.hpp | 6 - .../core/src/impl/Kokkos_TaskQueue_impl.hpp | 4 +- .../core/src/impl/Kokkos_ViewMapping.hpp | 36 +- lib/kokkos/core/src/impl/Kokkos_ViewTile.hpp | 2 +- lib/kokkos/core/unit_test/CMakeLists.txt | 4 + lib/kokkos/core/unit_test/Makefile | 68 + .../core/unit_test/TestCompilerMacros.hpp | 13 + lib/kokkos/core/unit_test/TestComplex.hpp | 6 +- lib/kokkos/core/unit_test/TestCrs.hpp | 98 ++ lib/kokkos/core/unit_test/TestRange.hpp | 6 +- lib/kokkos/core/unit_test/TestScan.hpp | 4 +- .../core/unit_test/TestTaskScheduler.hpp | 36 +- lib/kokkos/core/unit_test/TestViewAPI.hpp | 20 +- .../unit_test/TestViewCtorPropEmbeddedDim.hpp | 1 + .../core/unit_test/TestViewMapping_a.hpp | 3 +- .../core/unit_test/TestViewMapping_b.hpp | 84 +- .../core/unit_test/cuda/TestCuda_Crs.cpp | 45 + .../default/TestDefaultDeviceType_c.cpp | 2 + .../core/unit_test/openmp/TestOpenMP_Crs.cpp | 45 + .../rocm/TestROCmHostPinned_Category.hpp | 65 + .../rocm/TestROCmHostPinned_SharedAlloc.cpp | 55 + .../rocm/TestROCmHostPinned_ViewAPI.cpp | 45 + .../rocm/TestROCmHostPinned_ViewMapping_a.cpp | 46 + .../rocm/TestROCmHostPinned_ViewMapping_b.cpp | 46 + ...TestROCmHostPinned_ViewMapping_subview.cpp | 46 + .../core/unit_test/rocm/TestROCm_All.cpp | 33 + .../rocm/TestROCm_AtomicOperations.cpp | 46 + .../unit_test/rocm/TestROCm_AtomicViews.cpp | 47 + .../core/unit_test/rocm/TestROCm_Atomics.cpp | 46 + .../core/unit_test/rocm/TestROCm_Category.hpp | 65 + .../core/unit_test/rocm/TestROCm_Complex.cpp | 47 + .../core/unit_test/rocm/TestROCm_Init.cpp | 50 + .../core/unit_test/rocm/TestROCm_Other.cpp | 52 + .../unit_test/rocm/TestROCm_RangePolicy.cpp | 47 + .../unit_test/rocm/TestROCm_Reductions.cpp | 48 + .../core/unit_test/rocm/TestROCm_Scan.cpp | 47 + .../unit_test/rocm/TestROCm_SharedAlloc.cpp | 55 + .../core/unit_test/rocm/TestROCm_Spaces.cpp | 196 +++ .../unit_test/rocm/TestROCm_SubView_a.cpp | 104 ++ .../unit_test/rocm/TestROCm_SubView_b.cpp | 63 + .../unit_test/rocm/TestROCm_SubView_c01.cpp | 54 + .../unit_test/rocm/TestROCm_SubView_c02.cpp | 54 + .../unit_test/rocm/TestROCm_SubView_c03.cpp | 54 + .../unit_test/rocm/TestROCm_SubView_c04.cpp | 54 + .../unit_test/rocm/TestROCm_SubView_c05.cpp | 54 + .../unit_test/rocm/TestROCm_SubView_c06.cpp | 54 + .../unit_test/rocm/TestROCm_SubView_c07.cpp | 54 + .../unit_test/rocm/TestROCm_SubView_c08.cpp | 54 + .../unit_test/rocm/TestROCm_SubView_c09.cpp | 54 + .../unit_test/rocm/TestROCm_SubView_c10.cpp | 54 + .../unit_test/rocm/TestROCm_SubView_c11.cpp | 54 + .../unit_test/rocm/TestROCm_SubView_c12.cpp | 54 + .../core/unit_test/rocm/TestROCm_Team.cpp | 75 + .../rocm/TestROCm_TeamReductionScan.cpp | 82 ++ .../unit_test/rocm/TestROCm_TeamScratch.cpp | 83 ++ .../unit_test/rocm/TestROCm_ViewAPI_b.cpp | 45 + .../unit_test/rocm/TestROCm_ViewMapping_a.cpp | 46 + .../unit_test/rocm/TestROCm_ViewMapping_b.cpp | 46 + .../rocm/TestROCm_ViewMapping_subview.cpp | 46 + .../unit_test/rocm/TestROCm_ViewOfClass.cpp | 46 + .../core/unit_test/serial/TestSerial_Crs.cpp | 45 + .../unit_test/threads/TestThreads_Crs.cpp | 45 + lib/kokkos/generate_makefile.bash | 22 +- 112 files changed, 10885 insertions(+), 154 deletions(-) create mode 100644 lib/kokkos/config/kokkos-promotion.txt create mode 100644 lib/kokkos/core/src/Kokkos_ROCm.hpp create mode 100644 lib/kokkos/core/src/Kokkos_ROCmSpace.hpp create mode 100644 lib/kokkos/core/src/ROCm/Kokkos_ROCm_Atomic.hpp create mode 100644 lib/kokkos/core/src/ROCm/Kokkos_ROCm_Config.hpp create mode 100644 lib/kokkos/core/src/ROCm/Kokkos_ROCm_Exec.cpp create mode 100644 lib/kokkos/core/src/ROCm/Kokkos_ROCm_Exec.hpp create mode 100644 lib/kokkos/core/src/ROCm/Kokkos_ROCm_Impl.cpp create mode 100644 lib/kokkos/core/src/ROCm/Kokkos_ROCm_Invoke.hpp create mode 100644 lib/kokkos/core/src/ROCm/Kokkos_ROCm_Join.hpp create mode 100644 lib/kokkos/core/src/ROCm/Kokkos_ROCm_Parallel.hpp create mode 100644 lib/kokkos/core/src/ROCm/Kokkos_ROCm_Reduce.hpp create mode 100644 lib/kokkos/core/src/ROCm/Kokkos_ROCm_ReduceScan.hpp create mode 100644 lib/kokkos/core/src/ROCm/Kokkos_ROCm_Scan.hpp create mode 100644 lib/kokkos/core/src/ROCm/Kokkos_ROCm_Space.cpp create mode 100644 lib/kokkos/core/src/ROCm/Kokkos_ROCm_Task.cpp create mode 100644 lib/kokkos/core/src/ROCm/Kokkos_ROCm_Task.hpp create mode 100644 lib/kokkos/core/src/ROCm/Kokkos_ROCm_Tile.hpp create mode 100644 lib/kokkos/core/src/ROCm/Kokkos_ROCm_Vectorization.hpp create mode 100644 lib/kokkos/core/src/ROCm/hc_math_std.hpp create mode 100644 lib/kokkos/core/unit_test/TestCrs.hpp create mode 100644 lib/kokkos/core/unit_test/cuda/TestCuda_Crs.cpp create mode 100644 lib/kokkos/core/unit_test/openmp/TestOpenMP_Crs.cpp create mode 100644 lib/kokkos/core/unit_test/rocm/TestROCmHostPinned_Category.hpp create mode 100644 lib/kokkos/core/unit_test/rocm/TestROCmHostPinned_SharedAlloc.cpp create mode 100644 lib/kokkos/core/unit_test/rocm/TestROCmHostPinned_ViewAPI.cpp create mode 100644 lib/kokkos/core/unit_test/rocm/TestROCmHostPinned_ViewMapping_a.cpp create mode 100644 lib/kokkos/core/unit_test/rocm/TestROCmHostPinned_ViewMapping_b.cpp create mode 100644 lib/kokkos/core/unit_test/rocm/TestROCmHostPinned_ViewMapping_subview.cpp create mode 100644 lib/kokkos/core/unit_test/rocm/TestROCm_All.cpp create mode 100644 lib/kokkos/core/unit_test/rocm/TestROCm_AtomicOperations.cpp create mode 100644 lib/kokkos/core/unit_test/rocm/TestROCm_AtomicViews.cpp create mode 100644 lib/kokkos/core/unit_test/rocm/TestROCm_Atomics.cpp create mode 100644 lib/kokkos/core/unit_test/rocm/TestROCm_Category.hpp create mode 100644 lib/kokkos/core/unit_test/rocm/TestROCm_Complex.cpp create mode 100644 lib/kokkos/core/unit_test/rocm/TestROCm_Init.cpp create mode 100644 lib/kokkos/core/unit_test/rocm/TestROCm_Other.cpp create mode 100644 lib/kokkos/core/unit_test/rocm/TestROCm_RangePolicy.cpp create mode 100644 lib/kokkos/core/unit_test/rocm/TestROCm_Reductions.cpp create mode 100644 lib/kokkos/core/unit_test/rocm/TestROCm_Scan.cpp create mode 100644 lib/kokkos/core/unit_test/rocm/TestROCm_SharedAlloc.cpp create mode 100644 lib/kokkos/core/unit_test/rocm/TestROCm_Spaces.cpp create mode 100644 lib/kokkos/core/unit_test/rocm/TestROCm_SubView_a.cpp create mode 100644 lib/kokkos/core/unit_test/rocm/TestROCm_SubView_b.cpp create mode 100644 lib/kokkos/core/unit_test/rocm/TestROCm_SubView_c01.cpp create mode 100644 lib/kokkos/core/unit_test/rocm/TestROCm_SubView_c02.cpp create mode 100644 lib/kokkos/core/unit_test/rocm/TestROCm_SubView_c03.cpp create mode 100644 lib/kokkos/core/unit_test/rocm/TestROCm_SubView_c04.cpp create mode 100644 lib/kokkos/core/unit_test/rocm/TestROCm_SubView_c05.cpp create mode 100644 lib/kokkos/core/unit_test/rocm/TestROCm_SubView_c06.cpp create mode 100644 lib/kokkos/core/unit_test/rocm/TestROCm_SubView_c07.cpp create mode 100644 lib/kokkos/core/unit_test/rocm/TestROCm_SubView_c08.cpp create mode 100644 lib/kokkos/core/unit_test/rocm/TestROCm_SubView_c09.cpp create mode 100644 lib/kokkos/core/unit_test/rocm/TestROCm_SubView_c10.cpp create mode 100644 lib/kokkos/core/unit_test/rocm/TestROCm_SubView_c11.cpp create mode 100644 lib/kokkos/core/unit_test/rocm/TestROCm_SubView_c12.cpp create mode 100644 lib/kokkos/core/unit_test/rocm/TestROCm_Team.cpp create mode 100644 lib/kokkos/core/unit_test/rocm/TestROCm_TeamReductionScan.cpp create mode 100644 lib/kokkos/core/unit_test/rocm/TestROCm_TeamScratch.cpp create mode 100644 lib/kokkos/core/unit_test/rocm/TestROCm_ViewAPI_b.cpp create mode 100644 lib/kokkos/core/unit_test/rocm/TestROCm_ViewMapping_a.cpp create mode 100644 lib/kokkos/core/unit_test/rocm/TestROCm_ViewMapping_b.cpp create mode 100644 lib/kokkos/core/unit_test/rocm/TestROCm_ViewMapping_subview.cpp create mode 100644 lib/kokkos/core/unit_test/rocm/TestROCm_ViewOfClass.cpp create mode 100644 lib/kokkos/core/unit_test/serial/TestSerial_Crs.cpp create mode 100644 lib/kokkos/core/unit_test/threads/TestThreads_Crs.cpp diff --git a/lib/kokkos/CHANGELOG.md b/lib/kokkos/CHANGELOG.md index 3fe9e46111..43d3f17d63 100644 --- a/lib/kokkos/CHANGELOG.md +++ b/lib/kokkos/CHANGELOG.md @@ -1,5 +1,22 @@ # Change Log +## [2.04.00](https://github.com/kokkos/kokkos/tree/2.04.00) (2017-08-16) +[Full Changelog](https://github.com/kokkos/kokkos/compare/2.03.13...2.04.00) + +**Implemented enhancements:** + +- Added ROCm backend to support AMD GPUs +- Kokkos::complex\ behaves slightly differently from std::complex\ [\#1011](https://github.com/kokkos/kokkos/issues/1011) +- Kokkos::Experimental::Crs constructor arguments were in the wrong order [\#992](https://github.com/kokkos/kokkos/issues/992) +- Work graph construction ease-of-use (one lambda for count and fill) [\#991](https://github.com/kokkos/kokkos/issues/991) +- when\_all returns pointer of futures (improved interface) [\#990](https://github.com/kokkos/kokkos/issues/990) +- Allow assignment of LayoutLeft to LayoutRight or vice versa for rank-0 Views [\#594](https://github.com/kokkos/kokkos/issues/594) +- Changed the meaning of Kokkos\_ENABLE\_CXX11\_DISPATCH\_LAMBDA [\#1035](https://github.com/kokkos/kokkos/issues/1035) + +**Fixed bugs:** + +- memory pool default constructor does not properly set member variables. [\#1007](https://github.com/kokkos/kokkos/issues/1007) + ## [2.03.13](https://github.com/kokkos/kokkos/tree/2.03.13) (2017-07-27) [Full Changelog](https://github.com/kokkos/kokkos/compare/2.03.05...2.03.13) diff --git a/lib/kokkos/Makefile.kokkos b/lib/kokkos/Makefile.kokkos index d2967cf9a3..b8236e8fd1 100644 --- a/lib/kokkos/Makefile.kokkos +++ b/lib/kokkos/Makefile.kokkos @@ -4,10 +4,16 @@ KOKKOS_PATH=../../lib/kokkos CXXFLAGS=$(CCFLAGS) -# Options: Cuda,OpenMP,Pthreads,Qthreads,Serial +# Options: Cuda,ROCm,OpenMP,Pthreads,Qthreads,Serial KOKKOS_DEVICES ?= "OpenMP" #KOKKOS_DEVICES ?= "Pthreads" -# Options: KNC,SNB,HSW,Kepler,Kepler30,Kepler32,Kepler35,Kepler37,Maxwell,Maxwell50,Maxwell52,Maxwell53,Pascal60,Pascal61,ARMv80,ARMv81,ARMv8-ThunderX,BGQ,Power7,Power8,Power9,KNL,BDW,SKX +# Options: +# Intel: KNC,KNL,SNB,HSW,BDW,SKX +# NVIDIA: Kepler,Kepler30,Kepler32,Kepler35,Kepler37,Maxwell,Maxwell50,Maxwell52,Maxwell53,Pascal60,Pascal61 +# ARM: ARMv80,ARMv81,ARMv8-ThunderX +# IBM: BGQ,Power7,Power8,Power9 +# AMD-GPUS: Kaveri,Carrizo,Fiji,Vega +# AMD-CPUS: AMDAVX,Ryzen,Epyc KOKKOS_ARCH ?= "" # Options: yes,no KOKKOS_DEBUG ?= "no" @@ -43,8 +49,8 @@ KOKKOS_INTERNAL_CUDA_USE_UVM := $(strip $(shell echo $(KOKKOS_CUDA_OPTIONS) | gr KOKKOS_INTERNAL_CUDA_USE_RELOC := $(strip $(shell echo $(KOKKOS_CUDA_OPTIONS) | grep "rdc" | wc -l)) KOKKOS_INTERNAL_CUDA_USE_LAMBDA := $(strip $(shell echo $(KOKKOS_CUDA_OPTIONS) | grep "enable_lambda" | wc -l)) + # Check for Kokkos Host Execution Spaces one of which must be on. -KOKKOS_INTERNAL_USE_OPENMPTARGET := $(strip $(shell echo $(KOKKOS_DEVICES) | grep OpenMPTarget | wc -l)) KOKKOS_INTERNAL_USE_OPENMP := $(strip $(shell echo $(subst OpenMPTarget,,$(KOKKOS_DEVICES)) | grep OpenMP | wc -l)) KOKKOS_INTERNAL_USE_PTHREADS := $(strip $(shell echo $(KOKKOS_DEVICES) | grep Pthread | wc -l)) KOKKOS_INTERNAL_USE_QTHREADS := $(strip $(shell echo $(KOKKOS_DEVICES) | grep Qthreads | wc -l)) @@ -60,6 +66,8 @@ endif # Check for other Execution Spaces. KOKKOS_INTERNAL_USE_CUDA := $(strip $(shell echo $(KOKKOS_DEVICES) | grep Cuda | wc -l)) +KOKKOS_INTERNAL_USE_ROCM := $(strip $(shell echo $(KOKKOS_DEVICES) | grep ROCm | wc -l)) +KOKKOS_INTERNAL_USE_OPENMPTARGET := $(strip $(shell echo $(KOKKOS_DEVICES) | grep OpenMPTarget | wc -l)) ifeq ($(KOKKOS_INTERNAL_USE_CUDA), 1) KOKKOS_INTERNAL_NVCC_PATH := $(shell which nvcc) @@ -87,6 +95,7 @@ ifneq ($(MPICH_CXX),) endif KOKKOS_INTERNAL_COMPILER_CLANG := $(strip $(shell $(CXX) --version 2>&1 | grep clang | wc -l)) KOKKOS_INTERNAL_COMPILER_APPLE_CLANG := $(strip $(shell $(CXX) --version 2>&1 | grep "apple-darwin" | wc -l)) +KOKKOS_INTERNAL_COMPILER_HCC := $(strip $(shell $(CXX) --version 2>&1 | grep HCC | wc -l)) ifeq ($(KOKKOS_INTERNAL_COMPILER_CLANG), 2) KOKKOS_INTERNAL_COMPILER_CLANG = 1 @@ -99,6 +108,10 @@ endif ifeq ($(KOKKOS_INTERNAL_COMPILER_APPLE_CLANG), 1) KOKKOS_INTERNAL_COMPILER_CLANG = 0 endif +# AMD HCC passes both clang and hcc test so turn off clang +ifeq ($(KOKKOS_INTERNAL_COMPILER_HCC), 1) + KOKKOS_INTENAL_COMPILER_CLANG = 0 +endif ifeq ($(KOKKOS_INTERNAL_COMPILER_CLANG), 1) KOKKOS_INTERNAL_COMPILER_CLANG_VERSION := $(shell clang --version | grep version | cut -d ' ' -f3 | tr -d '.') @@ -183,8 +196,12 @@ else ifeq ($(KOKKOS_INTERNAL_COMPILER_CRAY), 1) KOKKOS_INTERNAL_CXX11_FLAG := -hstd=c++11 else - KOKKOS_INTERNAL_CXX11_FLAG := --std=c++11 - KOKKOS_INTERNAL_CXX1Z_FLAG := --std=c++1z + ifeq ($(KOKKOS_INTERNAL_COMPILER_HCC), 1) + KOKKOS_INTERNAL_CXX11_FLAG := + else + KOKKOS_INTERNAL_CXX11_FLAG := --std=c++11 + KOKKOS_INTERNAL_CXX1Z_FLAG := --std=c++1z + endif endif endif endif @@ -259,6 +276,13 @@ KOKKOS_INTERNAL_USE_ARCH_IBM := $(strip $(shell echo $(KOKKOS_INTERNAL_USE_ARCH_ # AMD based. KOKKOS_INTERNAL_USE_ARCH_AMDAVX := $(strip $(shell echo $(KOKKOS_ARCH) | grep AMDAVX | wc -l)) +KOKKOS_INTERNAL_USE_ARCH_RYZEN := $(strip $(shell echo $(KOKKOS_ARCH) | grep Ryzen | wc -l)) +KOKKOS_INTERNAL_USE_ARCH_EPYC := $(strip $(shell echo $(KOKKOS_ARCH) | grep Epyc | wc -l)) +KOKKOS_INTERNAL_USE_ARCH_KAVERI := $(strip $(shell echo $(KOKKOS_ARCH) | grep Kaveri | wc -l)) +KOKKOS_INTERNAL_USE_ARCH_CARRIZO := $(strip $(shell echo $(KOKKOS_ARCH) | grep Carrizo | wc -l)) +KOKKOS_INTERNAL_USE_ARCH_FIJI := $(strip $(shell echo $(KOKKOS_ARCH) | grep Fiji | wc -l)) +KOKKOS_INTERNAL_USE_ARCH_VEGA := $(strip $(shell echo $(KOKKOS_ARCH) | grep Vega | wc -l)) +KOKKOS_INTERNAL_USE_ARCH_GFX901 := $(strip $(shell echo $(KOKKOS_ARCH) | grep gfx901 | wc -l)) # Any AVX? KOKKOS_INTERNAL_USE_ARCH_SSE42 := $(strip $(shell echo $(KOKKOS_INTERNAL_USE_ARCH_WSM) | bc )) @@ -271,6 +295,7 @@ KOKKOS_INTERNAL_USE_ARCH_AVX512XEON := $(strip $(shell echo $(KOKKOS_INTERNAL_US KOKKOS_INTERNAL_USE_ISA_X86_64 := $(strip $(shell echo $(KOKKOS_INTERNAL_USE_ARCH_WSM)+$(KOKKOS_INTERNAL_USE_ARCH_SNB)+$(KOKKOS_INTERNAL_USE_ARCH_HSW)+$(KOKKOS_INTERNAL_USE_ARCH_BDW)+$(KOKKOS_INTERNAL_USE_ARCH_KNL)+$(KOKKOS_INTERNAL_USE_ARCH_SKX) | bc )) KOKKOS_INTERNAL_USE_ISA_KNC := $(strip $(shell echo $(KOKKOS_INTERNAL_USE_ARCH_KNC) | bc )) KOKKOS_INTERNAL_USE_ISA_POWERPCLE := $(strip $(shell echo $(KOKKOS_INTERNAL_USE_ARCH_POWER8)+$(KOKKOS_INTERNAL_USE_ARCH_POWER9) | bc )) +KOKKOS_INTERNAL_USE_ISA_POWERPCBE := $(strip $(shell echo $(KOKKOS_INTERNAL_USE_ARCH_POWER7) | bc )) # Decide whether we can support transactional memory KOKKOS_INTERNAL_USE_TM := $(strip $(shell echo $(KOKKOS_INTERNAL_USE_ARCH_BDW)+$(KOKKOS_INTERNAL_USE_ARCH_SKX) | bc )) @@ -319,8 +344,12 @@ ifeq ($(KOKKOS_INTERNAL_USE_CUDA), 1) tmp := $(shell echo "\#define KOKKOS_HAVE_CUDA 1" >> KokkosCore_config.tmp ) endif +ifeq ($(KOKKOS_INTERNAL_USE_ROCM), 1) + tmp := $(shell echo '\#define KOKKOS_ENABLE_ROCM 1' >> KokkosCore_config.tmp) +endif + ifeq ($(KOKKOS_INTERNAL_USE_OPENMPTARGET), 1) - tmp := $(shell echo '\#define KOKKOS_ENABLE_OPENMPTARGET 1' >> KokkosCore_config.tmp) + tmp := $(shell echo '\#define KOKKOS_ENABLE_OPENMPTARGET 1' >> KokkosCore_config.tmp) endif ifeq ($(KOKKOS_INTERNAL_USE_OPENMP), 1) @@ -363,6 +392,12 @@ ifeq ($(KOKKOS_INTERNAL_USE_ISA_POWERPCLE), 1) tmp := $(shell echo "\#endif" >> KokkosCore_config.tmp ) endif +ifeq ($(KOKKOS_INTERNAL_USE_ISA_POWERPCBE), 1) + tmp := $(shell echo "\#ifndef __CUDA_ARCH__" >> KokkosCore_config.tmp ) + tmp := $(shell echo "\#define KOKKOS_USE_ISA_POWERPCBE" >> KokkosCore_config.tmp ) + tmp := $(shell echo "\#endif" >> KokkosCore_config.tmp ) +endif + tmp := $(shell echo "/* General Settings */" >> KokkosCore_config.tmp) ifeq ($(KOKKOS_INTERNAL_ENABLE_CXX11), 1) KOKKOS_CXXFLAGS += $(KOKKOS_INTERNAL_CXX11_FLAG) @@ -561,6 +596,18 @@ ifeq ($(KOKKOS_INTERNAL_USE_ARCH_AVX), 1) endif endif +ifeq ($(KOKKOS_INTERNAL_USE_ARCH_POWER7), 1) + tmp := $(shell echo "\#define KOKKOS_ARCH_POWER7 1" >> KokkosCore_config.tmp ) + + ifeq ($(KOKKOS_INTERNAL_COMPILER_PGI), 1) + + else + # Assume that this is a really a GNU compiler or it could be XL on P8. + KOKKOS_CXXFLAGS += -mcpu=power7 -mtune=power7 + KOKKOS_LDFLAGS += -mcpu=power7 -mtune=power7 + endif +endif + ifeq ($(KOKKOS_INTERNAL_USE_ARCH_POWER8), 1) tmp := $(shell echo "\#define KOKKOS_ARCH_POWER8 1" >> KokkosCore_config.tmp ) @@ -742,7 +789,49 @@ ifeq ($(KOKKOS_INTERNAL_USE_CUDA), 1) endif endif +# Figure out the architecture flag for ROCm. +ifeq ($(KOKKOS_INTERNAL_USE_ROCM), 1) + # Lets start with adding architecture defines + ifeq ($(KOKKOS_INTERNAL_USE_ARCH_KAVERI), 1) + tmp := $(shell echo "\#define KOKKOS_ARCH_ROCM 701" >> KokkosCore_config.tmp ) + tmp := $(shell echo "\#define KOKKOS_ARCH_KAVERI 1" >> KokkosCore_config.tmp ) + KOKKOS_INTERNAL_ROCM_ARCH_FLAG := --amdgpu-target=gfx701 + endif + ifeq ($(KOKKOS_INTERNAL_USE_ARCH_CARRIZO), 1) + tmp := $(shell echo "\#define KOKKOS_ARCH_ROCM 801" >> KokkosCore_config.tmp ) + tmp := $(shell echo "\#define KOKKOS_ARCH_CARRIZO 1" >> KokkosCore_config.tmp ) + KOKKOS_INTERNAL_ROCM_ARCH_FLAG := --amdgpu-target=gfx801 + endif + ifeq ($(KOKKOS_INTERNAL_USE_ARCH_FIJI), 1) + tmp := $(shell echo "\#define KOKKOS_ARCH_ROCM 803" >> KokkosCore_config.tmp ) + tmp := $(shell echo "\#define KOKKOS_ARCH_FIJI 1" >> KokkosCore_config.tmp ) + KOKKOS_INTERNAL_ROCM_ARCH_FLAG := --amdgpu-target=gfx803 + endif + ifeq ($(KOKKOS_INTERNAL_USE_ARCH_VEGA), 1) + tmp := $(shell echo "\#define KOKKOS_ARCH_ROCM 900" >> KokkosCore_config.tmp ) + tmp := $(shell echo "\#define KOKKOS_ARCH_VEGA 1" >> KokkosCore_config.tmp ) + KOKKOS_INTERNAL_ROCM_ARCH_FLAG := --amdgpu-target=gfx900 + endif + ifeq ($(KOKKOS_INTERNAL_USE_ARCH_GFX901), 1) + tmp := $(shell echo "\#define KOKKOS_ARCH_ROCM 901" >> KokkosCore_config.tmp ) + tmp := $(shell echo "\#define KOKKOS_ARCH_GFX901 1" >> KokkosCore_config.tmp ) + KOKKOS_INTERNAL_ROCM_ARCH_FLAG := --amdgpu-target=gfx901 + endif + + + KOKKOS_INTERNAL_HCC_PATH := $(shell which $(CXX)) + ROCM_HCC_PATH ?= $(KOKKOS_INTERNAL_HCC_PATH:/bin/clang++=) + + KOKKOS_CXXFLAGS += $(shell $(ROCM_HCC_PATH)/bin/hcc-config --cxxflags) + KOKKOS_LDFLAGS += $(shell $(ROCM_HCC_PATH)/bin/hcc-config --ldflags) -lhc_am -lm + KOKKOS_LDFLAGS += $(KOKKOS_INTERNAL_ROCM_ARCH_FLAG) + + KOKKOS_SRC += $(wildcard $(KOKKOS_PATH)/core/src/ROCm/*.cpp) + KOKKOS_HEADERS += $(wildcard $(KOKKOS_PATH)/core/src/ROCm/*.hpp) +endif + KOKKOS_INTERNAL_LS_CONFIG := $(shell ls KokkosCore_config.h 2>&1) + ifeq ($(KOKKOS_INTERNAL_LS_CONFIG), KokkosCore_config.h) KOKKOS_INTERNAL_NEW_CONFIG := $(strip $(shell diff KokkosCore_config.h KokkosCore_config.tmp | grep define | wc -l)) else diff --git a/lib/kokkos/Makefile.targets b/lib/kokkos/Makefile.targets index a9341a907c..964ec966d5 100644 --- a/lib/kokkos/Makefile.targets +++ b/lib/kokkos/Makefile.targets @@ -42,6 +42,17 @@ Kokkos_Cuda_Locks.o: $(KOKKOS_CPP_DEPENDS) $(KOKKOS_PATH)/core/src/Cuda/Kokkos_C $(CXX) $(KOKKOS_CPPFLAGS) $(KOKKOS_CXXFLAGS) $(CXXFLAGS) -c $(KOKKOS_PATH)/core/src/Cuda/Kokkos_Cuda_Locks.cpp endif +ifeq ($(KOKKOS_INTERNAL_USE_ROCM), 1) +Kokkos_ROCm_Exec.o: $(KOKKOS_CPP_DEPENDS) $(KOKKOS_PATH)/core/src/ROCm/Kokkos_ROCm_Exec.cpp + $(CXX) $(KOKKOS_CPPFLAGS) $(KOKKOS_CXXFLAGS) $(CXXFLAGS) -c $(KOKKOS_PATH)/core/src/ROCm/Kokkos_ROCm_Exec.cpp +Kokkos_ROCm_Space.o: $(KOKKOS_CPP_DEPENDS) $(KOKKOS_PATH)/core/src/ROCm/Kokkos_ROCm_Space.cpp + $(CXX) $(KOKKOS_CPPFLAGS) $(KOKKOS_CXXFLAGS) $(CXXFLAGS) -c $(KOKKOS_PATH)/core/src/ROCm/Kokkos_ROCm_Space.cpp +Kokkos_ROCm_Task.o: $(KOKKOS_CPP_DEPENDS) $(KOKKOS_PATH)/core/src/ROCm/Kokkos_ROCm_Task.cpp + $(CXX) $(KOKKOS_CPPFLAGS) $(KOKKOS_CXXFLAGS) $(CXXFLAGS) -c $(KOKKOS_PATH)/core/src/ROCm/Kokkos_ROCm_Task.cpp +Kokkos_ROCm_Impl.o: $(KOKKOS_CPP_DEPENDS) $(KOKKOS_PATH)/core/src/ROCm/Kokkos_ROCm_Impl.cpp + $(CXX) $(KOKKOS_CPPFLAGS) $(KOKKOS_CXXFLAGS) $(CXXFLAGS) -c $(KOKKOS_PATH)/core/src/ROCm/Kokkos_ROCm_Impl.cpp +endif + ifeq ($(KOKKOS_INTERNAL_USE_PTHREADS), 1) Kokkos_ThreadsExec_base.o: $(KOKKOS_CPP_DEPENDS) $(KOKKOS_PATH)/core/src/Threads/Kokkos_ThreadsExec_base.cpp $(CXX) $(KOKKOS_CPPFLAGS) $(KOKKOS_CXXFLAGS) $(CXXFLAGS) -c $(KOKKOS_PATH)/core/src/Threads/Kokkos_ThreadsExec_base.cpp diff --git a/lib/kokkos/README b/lib/kokkos/README index 257a2e5db4..e5ed39ef53 100644 --- a/lib/kokkos/README +++ b/lib/kokkos/README @@ -80,6 +80,9 @@ Other compilers working: X86: Cygwin 2.1.0 64bit with gcc 4.9.3 +Limited testing of the following compilers on POWER7+ systems: + GCC 4.8.5 (on RHEL7.1 POWER7+) + Known non-working combinations: Power8: Pthreads backend @@ -171,3 +174,22 @@ Contributions to Kokkos are welcome. In order to do so, please open an issue where a feature request or bug can be discussed. Then issue a pull request with your contribution. Pull requests must be issued against the develop branch. +=========================================================================== +====Citing Kokkos========================================================== +=========================================================================== + +If you publish work which mentions Kokkos, please cite the following paper: + +@article{CarterEdwards20143202, +title = "Kokkos: Enabling manycore performance portability through polymorphic memory access patterns ", +journal = "Journal of Parallel and Distributed Computing ", +volume = "74", +number = "12", +pages = "3202 - 3216", +year = "2014", +note = "Domain-Specific Languages and High-Level Frameworks for High-Performance Computing ", +issn = "0743-7315", +doi = "https://doi.org/10.1016/j.jpdc.2014.07.003", +url = "http://www.sciencedirect.com/science/article/pii/S0743731514001257", +author = "H. Carter Edwards and Christian R. Trott and Daniel Sunderland" +} diff --git a/lib/kokkos/config/kokkos-promotion.txt b/lib/kokkos/config/kokkos-promotion.txt new file mode 100644 index 0000000000..d56298b416 --- /dev/null +++ b/lib/kokkos/config/kokkos-promotion.txt @@ -0,0 +1,140 @@ +Summary: + +- Step 1: Testing Kokkos itself using test_all_sandia + +- Step 2: Testing of Kokkos integrated into Trilinos (config/trilinos-integration/*.sh) + +- Step 3: Locally update CHANGELOG, merge into master, edit config/master_history.txt + +- Step 4: Locally snapshot new master into corresponding Trilinos branch (develop or temporary), push with checking-test-sems.sh + +- Step 5: Push local Kokkos master to GitHub (need Owner approval) + +Steps 1, 2, and 4 include testing that may fail. These failures must be fixed either by pull requests to Kokkos develop, or by creating a new Trilinos branch for parts of Trilinos that must be updated. This is what usually takes the most time. + + +// -------------------------------------------------------------------------------- // + + +Step 1: The following should be repeated on enough machines to cover all +supported compilers. Those machines are: + + kokkos-dev + ??? <- TODO: identify other machines + + 1.1. Clone kokkos develop branch (or just switch to it) + + git clone -b develop git@github.com:kokkos/kokkos.git + cd kokkos + + 1.2. Create a testing directory + + mkdir testing + cd testing + + 1.3. Run the test_all_sandia script with no options to test all compilers + + nohup ../config/test_all_sandia & + tail -f nohup.out # to watch progress + +// -------------------------------------------------------------------------------- // + +Step 2: + 2.1. Build and test Trilinos with 4 different configurations; Run scripts for white and shepard that are provided in kokkos/config/trilinos-integration. These scripts load their own modules/environment, so don't require preparation. You can run all four at the same time, use separate directories for each. + + mkdir serial + cd serial + nohup KOKKOS_PATH/config/trilinos-integration/shepard_jenkins_run_script_serial_intel & + + 2.2. Compare the compile errors and test failures between updated and pristine versions. There may be compile failures that happen in both, tests that fail in both, and there may be tests that only fail some times (thus, rerun tests manually as needed). + +// -------------------------------------------------------------------------------- // + +Step 3: This step should be run on kokkos-dev + + 3.1. If you don't have a GitHub token already, generate one for yourself (this will give you TOKEN): + + https://github.com/settings/tokens + + 3.2. Get a clean copy of the Kokkos develop branch + + git clone -b develop git@github.com:kokkos/kokkos.git + cd kokkos + + 3.3. Generate the initial changelog. Use the most recent tag as OLDTAG (`git tag -l` can show you all tags). The NEWTAG is the new version number, e.g. "2.04.00". RUN THIS OUTSIDE THE KOKKOS SOURCE TREE! + + module load ruby/2.3.1/gcc/5.3.0 + gitthub_changelog_generator kokkos/kokkos --token TOKEN --no-pull-requests --include-labels 'InDevelop' --enhancement-labels 'enhancement,Feature Request' --future-release 'NEWTAG' --between-tags 'NEWTAG,OLDTAG' + cat CHANGELOG.md + + 3.4. Manually cleanup and commit the change log. Pushing to develop requires Owner permission. + (Copy the new section from the generated CHANGELOG.md to KOKKOS_PATH/CHANGELOG.md) + (Make desired changes to CHANGELOG.md to enhance clarity (remove issues not noteworthy)) + (Commit and push the CHANGELOG.md to develop) + + 3.5. Merge develop into master. DO NOT FAST-FORWARD THE MERGE!!!! + + (From kokkos directory): + git checkout master + git merge --no-ff origin/develop + + 3.6. Update the tag in kokkos/config/master_history.txt + + Tag description: MajorNumber.MinorNumber.WeeksSinceMinorNumberUpdate + Tag field widths: #.#.## + date description: month:day:year + date field widths: ##:##:#### + master description: SHA1 of previous master commit (use `git log`?) + develop description: SHA1 of merged develop branch + SHA1 field width: ######## (8 chars) + + # Append to config/master_history.txt: + + tag: 2.03.13 date: 07:27:2017 master: da314444 develop: 29ccb58a + + git commit --amend -a + + + 3.7. Create the new tag: + + git tag -a #.#.## + + (type the following into the tag message (same as for step 4.3)) + tag: #.#.## + date: mm/dd/yyyy + master: sha1 + develop: sha1 + + 3.8. DO NOT PUSH YET !!! + + +// -------------------------------------------------------------------------------- // + +Step 4: This step can be done on any SEMS machine (e.g. kokkos-dev). Actually, the checkin step requires lots of disk space and RAM. Use ceerws1113 if you have access to it. + + 4.1 Clone the Trilinos corresponding branch (or just switch to it) + + git clone -b develop git@github.com:trilinos/Trilinos.git + TRILINOS_PATH=$PWD/Trilinos + + 4.2 Snapshot Kokkos into Trilinos - this requires python/2.7.9 and that both Trilinos and Kokkos be clean - no untracked or modified files. Run the following outside of the Kokkos and Trilinos source trees. + + module load sems-python/2.7.9 + python KOKKOS_PATH/config/snapshot.py KOKKOS_PATH TRILINOS_PATH/packages + + 4.3. Run checkin-test to push to trilinos using the CI build modules (gcc/4.9.3) + + cd TRILINOS_PATH + mkdir CHECKIN + cd CHECKIN + nohup ../cmake/std/sems/checkin-test-sems.sh --do-all --push & + + 4.4. If there are failures, fix and backtrack. Otherwise, go to next step + +// -------------------------------------------------------------------------------- // + +Step 5: Push Kokkos master to GitHub (requires Owner permission). + + cd KOKKOS_PATH + git push --follow-tags origin master + diff --git a/lib/kokkos/config/master_history.txt b/lib/kokkos/config/master_history.txt index 0447db4b2b..96b05c02e1 100644 --- a/lib/kokkos/config/master_history.txt +++ b/lib/kokkos/config/master_history.txt @@ -8,3 +8,4 @@ tag: 2.02.15 date: 02:10:2017 master: 8c64cd93 develop: 28dea8b6 tag: 2.03.00 date: 04:25:2017 master: 120d9ce7 develop: 015ba641 tag: 2.03.05 date: 05:27:2017 master: 36b92f43 develop: 79073186 tag: 2.03.13 date: 07:27:2017 master: da314444 develop: 29ccb58a +tag: 2.04.00 date: 08:16:2017 master: 54eb75c0 develop: 32fb8ee1 diff --git a/lib/kokkos/config/test_all_sandia b/lib/kokkos/config/test_all_sandia index 005cd20721..e6fcaad261 100755 --- a/lib/kokkos/config/test_all_sandia +++ b/lib/kokkos/config/test_all_sandia @@ -167,7 +167,6 @@ if [ "$MACHINE" = "sems" ]; then "intel/15.0.2 $BASE_MODULE_LIST $INTEL_BUILD_LIST icpc $INTEL_WARNING_FLAGS" "intel/16.0.1 $BASE_MODULE_LIST $INTEL_BUILD_LIST icpc $INTEL_WARNING_FLAGS" "intel/16.0.3 $BASE_MODULE_LIST $INTEL_BUILD_LIST icpc $INTEL_WARNING_FLAGS" - "intel/17.0.1 $BASE_MODULE_LIST $INTEL_BUILD_LIST icpc $INTEL_WARNING_FLAGS" "clang/3.6.1 $BASE_MODULE_LIST $CLANG_BUILD_LIST clang++ $CLANG_WARNING_FLAGS" "clang/3.7.1 $BASE_MODULE_LIST $CLANG_BUILD_LIST clang++ $CLANG_WARNING_FLAGS" "clang/3.8.1 $BASE_MODULE_LIST $CLANG_BUILD_LIST clang++ $CLANG_WARNING_FLAGS" diff --git a/lib/kokkos/core/cmake/KokkosCore_config.h.in b/lib/kokkos/core/cmake/KokkosCore_config.h.in index 621cd54e1c..599c6b0224 100644 --- a/lib/kokkos/core/cmake/KokkosCore_config.h.in +++ b/lib/kokkos/core/cmake/KokkosCore_config.h.in @@ -1,15 +1,15 @@ -#if !defined(KOKKOS_MACROS_HPP) || defined(KOKKOS_CORE_CONFIG_H) -#error "Don't include KokkosCore_config.h directly; include Kokkos_Macros.hpp instead." -#else -#define KOKKOS_CORE_CONFIG_H -#endif - /* The trivial 'src/build_common.sh' creates a config * that must stay in sync with this file. */ #cmakedefine KOKKOS_FOR_SIERRA -#ifndef KOKKOS_FOR_SIERRA +#if !defined(KOKKOS_FOR_SIERRA) + +#if !defined(KOKKOS_MACROS_HPP) || defined(KOKKOS_CORE_CONFIG_H) +#error "Don't include KokkosCore_config.h directly; include Kokkos_Macros.hpp instead." +#else +#define KOKKOS_CORE_CONFIG_H +#endif #cmakedefine KOKKOS_HAVE_CUDA #cmakedefine KOKKOS_HAVE_OPENMP @@ -93,12 +93,6 @@ #cmakedefine KOKKOS_ARCH_PASCAL60 1 #cmakedefine KOKKOS_ARCH_PASCAL61 1 -// Don't forbid users from defining this macro on the command line, -// but still make sure that CMake logic can control its definition. -#ifndef KOKKOS_HAVE_CXX11_DISPATCH_LAMBDA -#cmakedefine KOKKOS_HAVE_CXX11_DISPATCH_LAMBDA 1 -#endif - // TODO: These are currently not used in Kokkos. Should they be removed? #cmakedefine KOKKOS_HAVE_MPI #cmakedefine KOKKOS_HAVE_CUSPARSE @@ -107,4 +101,4 @@ #cmakedefine KOKKOS_USING_DEPRECATED_VIEW #cmakedefine KOKKOS_HAVE_CXX11 -#endif // KOKKOS_FOR_SIERRA +#endif // !defined(KOKKOS_FOR_SIERRA) diff --git a/lib/kokkos/core/src/CMakeLists.txt b/lib/kokkos/core/src/CMakeLists.txt index 492470d05d..0d5d97a829 100644 --- a/lib/kokkos/core/src/CMakeLists.txt +++ b/lib/kokkos/core/src/CMakeLists.txt @@ -9,30 +9,6 @@ TRIBITS_ADD_OPTION_AND_DEFINE( ASSERT_DEFINED(${PROJECT_NAME}_ENABLE_CXX11) ASSERT_DEFINED(${PACKAGE_NAME}_ENABLE_CUDA) -# Kokkos_ENABLE_CXX11_DISPATCH_LAMBDA governs whether Kokkos allows -# use of lambdas at the outer level of parallel dispatch (that is, as -# the argument to an outer parallel_for, parallel_reduce, or -# parallel_scan). This works with non-CUDA execution spaces if C++11 -# is enabled. It does not currently work with public releases of -# CUDA. If that changes, please change the default here to ON if CUDA -# and C++11 are ON. -IF (${PROJECT_NAME}_ENABLE_CXX11) - IF (${PACKAGE_NAME}_ENABLE_CUDA) - SET(Kokkos_ENABLE_CXX11_DISPATCH_LAMBDA_DEFAULT OFF) - ELSE () - SET(Kokkos_ENABLE_CXX11_DISPATCH_LAMBDA_DEFAULT ON) - ENDIF () -ELSE () - SET(Kokkos_ENABLE_CXX11_DISPATCH_LAMBDA_DEFAULT OFF) -ENDIF () - -TRIBITS_ADD_OPTION_AND_DEFINE( - Kokkos_ENABLE_CXX11_DISPATCH_LAMBDA - KOKKOS_HAVE_CXX11_DISPATCH_LAMBDA - "Whether Kokkos allows use of lambdas at the outer level of parallel dispatch (that is, as the argument to an outer parallel_for, parallel_reduce, or parallel_scan). This requires C++11. It also does not currently work with public releases of CUDA. As a result, even if C++11 is enabled, this will be OFF by default if CUDA is enabled. If this option is ON, the macro KOKKOS_HAVE_CXX11_DISPATCH_LAMBDA will be defined. For compatibility with Kokkos' Makefile build system, it is also possible to define that macro on the command line." - ${Kokkos_ENABLE_CXX11_DISPATCH_LAMBDA_DEFAULT} - ) - TRIBITS_CONFIGURE_FILE(${PACKAGE_NAME}_config.h) INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}) diff --git a/lib/kokkos/core/src/Kokkos_Array.hpp b/lib/kokkos/core/src/Kokkos_Array.hpp index abb263b7cc..43e6386b54 100644 --- a/lib/kokkos/core/src/Kokkos_Array.hpp +++ b/lib/kokkos/core/src/Kokkos_Array.hpp @@ -152,10 +152,10 @@ public: KOKKOS_INLINE_FUNCTION pointer data() { return pointer(0) ; } KOKKOS_INLINE_FUNCTION const_pointer data() const { return const_pointer(0); } - ~Array() = default ; - Array() = default ; - Array( const Array & ) = default ; - Array & operator = ( const Array & ) = default ; + KOKKOS_FUNCTION_DEFAULTED ~Array() = default ; + KOKKOS_FUNCTION_DEFAULTED Array() = default ; + KOKKOS_FUNCTION_DEFAULTED Array( const Array & ) = default ; + KOKKOS_FUNCTION_DEFAULTED Array & operator = ( const Array & ) = default ; // Some supported compilers are not sufficiently C++11 compliant // for default move constructor and move assignment operator. @@ -209,7 +209,7 @@ public: KOKKOS_INLINE_FUNCTION pointer data() { return m_elem ; } KOKKOS_INLINE_FUNCTION const_pointer data() const { return m_elem ; } - ~Array() = default ; + KOKKOS_FUNCTION_DEFAULTED ~Array() = default ; Array() = delete ; Array( const Array & rhs ) = delete ; @@ -278,7 +278,7 @@ public: KOKKOS_INLINE_FUNCTION pointer data() { return m_elem ; } KOKKOS_INLINE_FUNCTION const_pointer data() const { return m_elem ; } - ~Array() = default ; + KOKKOS_FUNCTION_DEFAULTED ~Array() = default ; Array() = delete ; Array( const Array & ) = delete ; diff --git a/lib/kokkos/core/src/Kokkos_Atomic.hpp b/lib/kokkos/core/src/Kokkos_Atomic.hpp index 3c8673c66a..54a97a16c1 100644 --- a/lib/kokkos/core/src/Kokkos_Atomic.hpp +++ b/lib/kokkos/core/src/Kokkos_Atomic.hpp @@ -80,6 +80,11 @@ // Compiling NVIDIA device code, must use Cuda atomics: #define KOKKOS_ENABLE_CUDA_ATOMICS + +#elif defined(KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_ROCM_GPU) + +#define KOKKOS_ENABLE_ROCM_ATOMICS + #endif #if ! defined( KOKKOS_ENABLE_GNU_ATOMICS ) && \ @@ -154,6 +159,19 @@ const char * atomic_query_version() } // namespace Kokkos +#if defined( KOKKOS_ENABLE_ROCM ) +#include +namespace Kokkos { +namespace Impl { +extern KOKKOS_INLINE_FUNCTION +bool lock_address_rocm_space(void* ptr); + +extern KOKKOS_INLINE_FUNCTION +void unlock_address_rocm_space(void* ptr); +} +} +#endif + #ifdef _WIN32 #include "impl/Kokkos_Atomic_Windows.hpp" #else diff --git a/lib/kokkos/core/src/Kokkos_Complex.hpp b/lib/kokkos/core/src/Kokkos_Complex.hpp index 1fe964a6d2..26b47a8b74 100644 --- a/lib/kokkos/core/src/Kokkos_Complex.hpp +++ b/lib/kokkos/core/src/Kokkos_Complex.hpp @@ -107,6 +107,11 @@ public: re_ (val), im_ (0.0) {} + // BUG HCC WORKAROUND + KOKKOS_INLINE_FUNCTION complex( const RealType& re, const RealType& im): + re_ (re), im_ (im) + {} + //! Constructor that takes the real and imaginary parts. template KOKKOS_INLINE_FUNCTION complex (const RealType1& re, const RealType2& im) : @@ -227,6 +232,16 @@ public: return re_; } + //! Set the imaginary part of this complex number. + KOKKOS_INLINE_FUNCTION void imag (RealType v) { + im_ = v; + } + + //! Set the real part of this complex number. + KOKKOS_INLINE_FUNCTION void real (RealType v) { + re_ = v; + } + KOKKOS_INLINE_FUNCTION complex& operator += (const complex& src) { re_ += src.re_; @@ -299,7 +314,7 @@ public: // Scale (by the "1-norm" of y) to avoid unwarranted overflow. // If the real part is +/-Inf and the imaginary part is -/+Inf, // this won't change the result. - const RealType s = ::fabs (y.real ()) + ::fabs (y.imag ()); + const RealType s = std::fabs (y.real ()) + std::fabs (y.imag ()); // If s is 0, then y is zero, so x/y == real(x)/0 + i*imag(x)/0. // In that case, the relation x/y == (x/s) / (y/s) doesn't hold, @@ -537,7 +552,7 @@ operator / (const complex& x, const complex& y) { // Scale (by the "1-norm" of y) to avoid unwarranted overflow. // If the real part is +/-Inf and the imaginary part is -/+Inf, // this won't change the result. - const RealType s = ::fabs (real (y)) + ::fabs (imag (y)); + const RealType s = std::fabs (real (y)) + std::fabs (imag (y)); // If s is 0, then y is zero, so x/y == real(x)/0 + i*imag(x)/0. // In that case, the relation x/y == (x/s) / (y/s) doesn't hold, diff --git a/lib/kokkos/core/src/Kokkos_Core.hpp b/lib/kokkos/core/src/Kokkos_Core.hpp index ddb11d2894..3748c35eb0 100644 --- a/lib/kokkos/core/src/Kokkos_Core.hpp +++ b/lib/kokkos/core/src/Kokkos_Core.hpp @@ -74,6 +74,10 @@ #include #endif +#if defined( KOKKOS_ENABLE_ROCM ) +#include +#endif + #include #include #include diff --git a/lib/kokkos/core/src/Kokkos_Core_fwd.hpp b/lib/kokkos/core/src/Kokkos_Core_fwd.hpp index 8c080f7a8f..29001e19ed 100644 --- a/lib/kokkos/core/src/Kokkos_Core_fwd.hpp +++ b/lib/kokkos/core/src/Kokkos_Core_fwd.hpp @@ -122,6 +122,13 @@ class CudaHostPinnedSpace; ///< Memory space on Host accessible to Cuda GPU class Cuda; ///< Execution space for Cuda GPU #endif +#if defined( KOKKOS_ENABLE_ROCM ) +namespace Experimental { +class ROCmSpace ; ///< Memory space on ROCm GPU +class ROCm ; ///< Execution space for ROCm GPU +} +#endif + template struct Device; @@ -140,6 +147,8 @@ namespace Kokkos { typedef Cuda DefaultExecutionSpace; #elif defined ( KOKKOS_ENABLE_DEFAULT_DEVICE_TYPE_OPENMPTARGET ) typedef Experimental::OpenMPTarget DefaultExecutionSpace ; +#elif defined ( KOKKOS_ENABLE_DEFAULT_DEVICE_TYPE_ROCM ) + typedef Experimental::ROCm DefaultExecutionSpace ; #elif defined( KOKKOS_ENABLE_DEFAULT_DEVICE_TYPE_OPENMP ) typedef OpenMP DefaultExecutionSpace; #elif defined( KOKKOS_ENABLE_DEFAULT_DEVICE_TYPE_THREADS ) @@ -185,6 +194,8 @@ namespace Impl { #if defined( KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_CUDA ) && defined( KOKKOS_ENABLE_CUDA ) typedef Kokkos::CudaSpace ActiveExecutionMemorySpace; +#elif defined( KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_ROCM_GPU ) +typedef Kokkos::HostSpace ActiveExecutionMemorySpace ; #elif defined( KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_HOST ) typedef Kokkos::HostSpace ActiveExecutionMemorySpace; #else diff --git a/lib/kokkos/core/src/Kokkos_Crs.hpp b/lib/kokkos/core/src/Kokkos_Crs.hpp index 93b3fa5ca9..f089c16ad2 100644 --- a/lib/kokkos/core/src/Kokkos_Crs.hpp +++ b/lib/kokkos/core/src/Kokkos_Crs.hpp @@ -98,18 +98,18 @@ public: typedef View row_map_type; typedef View entries_type; - entries_type entries; row_map_type row_map; + entries_type entries; //! Construct an empty view. - Crs () : entries(), row_map() {} + Crs() : row_map(), entries() {} //! Copy constructor (shallow copy). - Crs (const Crs& rhs) : entries (rhs.entries), row_map (rhs.row_map) + Crs(const Crs& rhs) : row_map(rhs.row_map), entries(rhs.entries) {} template - Crs (const EntriesType& entries_,const RowMapType& row_map_) : entries (entries_), row_map (row_map_) + Crs(const RowMapType& row_map_, const EntriesType& entries_) : row_map(row_map_), entries(entries_) {} /** \brief Assign to a view of the rhs array. @@ -117,8 +117,8 @@ public: * then allocated memory is deallocated. */ Crs& operator= (const Crs& rhs) { - entries = rhs.entries; row_map = rhs.row_map; + entries = rhs.entries; return *this; } @@ -151,7 +151,7 @@ void get_crs_transpose_counts( template< class OutCounts, class InCrs> -void get_crs_row_map_from_counts( +typename OutCounts::value_type get_crs_row_map_from_counts( OutCounts& out, InCrs const& in, std::string const& name = "row_map"); @@ -204,18 +204,20 @@ class CrsRowMapFromCounts { using execution_space = typename InCounts::execution_space; using value_type = typename OutRowMap::value_type; using index_type = typename InCounts::size_type; + using last_value_type = Kokkos::View; private: - InCounts in; - OutRowMap out; + InCounts m_in; + OutRowMap m_out; + last_value_type m_last_value; public: KOKKOS_INLINE_FUNCTION void operator()(index_type i, value_type& update, bool final_pass) const { - update += in(i); - if (final_pass) { - out(i + 1) = update; - if (i == 0) { - out(0) = 0; - } + if (i < m_in.size()) { + update += m_in(i); + if (final_pass) m_out(i + 1) = update; + } else if (final_pass) { + m_out(0) = 0; + m_last_value() = update; } } KOKKOS_INLINE_FUNCTION @@ -226,12 +228,16 @@ class CrsRowMapFromCounts { } using self_type = CrsRowMapFromCounts; CrsRowMapFromCounts(InCounts const& arg_in, OutRowMap const& arg_out): - in(arg_in),out(arg_out) { + m_in(arg_in), m_out(arg_out), m_last_value("last_value") { + } + value_type execute() { using policy_type = RangePolicy; using closure_type = Kokkos::Impl::ParallelScan; - closure_type closure(*this, policy_type(0, in.size())); + closure_type closure(*this, policy_type(0, m_in.size() + 1)); closure.execute(); - execution_space::fence(); + auto last_value = Kokkos::create_mirror_view(m_last_value); + Kokkos::deep_copy(last_value, m_last_value); + return last_value(); } }; @@ -297,13 +303,14 @@ void get_crs_transpose_counts( template< class OutRowMap, class InCounts> -void get_crs_row_map_from_counts( +typename OutRowMap::value_type get_crs_row_map_from_counts( OutRowMap& out, InCounts const& in, std::string const& name) { out = OutRowMap(ViewAllocateWithoutInitializing(name), in.size() + 1); Kokkos::Impl::Experimental:: CrsRowMapFromCounts functor(in, out); + return functor.execute(); } template< class DataType, @@ -328,6 +335,65 @@ void transpose_crs( FillCrsTransposeEntries entries_functor(in, out); } +template< class CrsType, + class Functor> +struct CountAndFill { + using data_type = typename CrsType::size_type; + using size_type = typename CrsType::size_type; + using row_map_type = typename CrsType::row_map_type; + using entries_type = typename CrsType::entries_type; + using counts_type = row_map_type; + CrsType m_crs; + Functor m_functor; + counts_type m_counts; + struct Count {}; + KOKKOS_INLINE_FUNCTION void operator()(Count, size_type i) const { + m_counts(i) = m_functor(i, nullptr); + } + struct Fill {}; + KOKKOS_INLINE_FUNCTION void operator()(Fill, size_type i) const { + auto j = m_crs.row_map(i); + data_type* fill = &(m_crs.entries(j)); + m_functor(i, fill); + } + using self_type = CountAndFill; + CountAndFill(CrsType& crs, size_type nrows, Functor const& f): + m_crs(crs), + m_functor(f) + { + using execution_space = typename CrsType::execution_space; + m_counts = counts_type("counts", nrows); + { + using count_policy_type = RangePolicy; + using count_closure_type = + Kokkos::Impl::ParallelFor; + const count_closure_type closure(*this, count_policy_type(0, nrows)); + closure.execute(); + } + auto nentries = Kokkos::Experimental:: + get_crs_row_map_from_counts(m_crs.row_map, m_counts); + m_counts = counts_type(); + m_crs.entries = entries_type("entries", nentries); + { + using fill_policy_type = RangePolicy; + using fill_closure_type = + Kokkos::Impl::ParallelFor; + const fill_closure_type closure(*this, fill_policy_type(0, nrows)); + closure.execute(); + } + crs = m_crs; + } +}; + +template< class CrsType, + class Functor> +void count_and_fill_crs( + CrsType& crs, + typename CrsType::size_type nrows, + Functor const& f) { + Kokkos::Experimental::CountAndFill(crs, nrows, f); +} + }} // namespace Kokkos::Experimental #endif /* #define KOKKOS_CRS_HPP */ diff --git a/lib/kokkos/core/src/Kokkos_Macros.hpp b/lib/kokkos/core/src/Kokkos_Macros.hpp index 250ef6630a..7137eaae4b 100644 --- a/lib/kokkos/core/src/Kokkos_Macros.hpp +++ b/lib/kokkos/core/src/Kokkos_Macros.hpp @@ -96,6 +96,14 @@ //---------------------------------------------------------------------------- +#if defined(KOKKOS_ENABLE_SERIAL) || defined(KOKKOS_ENABLE_THREADS) || \ + defined(KOKKOS_ENABLE_OPENMP) || defined(KOKKOS_ENABLE_QTHREADS) || \ + defined(KOKKOS_ENABLE_ROCM) || defined(KOKKOS_ENABLE_OPENMPTARGET) + #define KOKKOS_INTERNAL_ENABLE_NON_CUDA_BACKEND +#endif + +#define KOKKOS_ENABLE_CXX11_DISPATCH_LAMBDA + #if defined( KOKKOS_ENABLE_CUDA ) && defined( __CUDACC__ ) // Compiling with a CUDA compiler. // @@ -133,6 +141,9 @@ #if ( CUDA_VERSION < 8000 ) && defined( __NVCC__ ) #define KOKKOS_LAMBDA [=]__device__ + #if defined( KOKKOS_INTERNAL_ENABLE_NON_CUDA_BACKEND ) + #undef KOKKOS_ENABLE_CXX11_DISPATCH_LAMBDA + #endif #else #define KOKKOS_LAMBDA [=]__host__ __device__ @@ -141,16 +152,13 @@ #endif #endif - #define KOKKOS_ENABLE_CXX11_DISPATCH_LAMBDA 1 - #endif -#endif // #if defined( KOKKOS_ENABLE_CUDA ) && defined( __CUDACC__ ) - -#if defined( KOKKOS_ENABLE_CXX11_DISPATCH_LAMBDA ) - // Cuda version 8.0 still needs the functor wrapper - #if /* ( CUDA_VERSION < 8000 ) && */ defined( __NVCC__ ) + #if defined( __NVCC__ ) #define KOKKOS_IMPL_NEED_FUNCTOR_WRAPPER - #endif -#endif + #endif + #else // !defined(KOKKOS_ENABLE_CUDA_LAMBDA) + #undef KOKKOS_ENABLE_CXX11_DISPATCH_LAMBDA + #endif // !defined(KOKKOS_ENABLE_CUDA_LAMBDA) +#endif // #if defined( KOKKOS_ENABLE_CUDA ) && defined( __CUDACC__ ) //---------------------------------------------------------------------------- // Language info: C++, CUDA, OPENMP @@ -161,8 +169,20 @@ #define KOKKOS_FORCEINLINE_FUNCTION __device__ __host__ __forceinline__ #define KOKKOS_INLINE_FUNCTION __device__ __host__ inline #define KOKKOS_FUNCTION __device__ __host__ + #ifdef KOKKOS_COMPILER_CLANG + #define KOKKOS_FUNCTION_DEFAULTED KOKKOS_FUNCTION + #endif #endif // #if defined( __CUDA_ARCH__ ) +#if defined( KOKKOS_ENABLE_ROCM ) && defined( __HCC__ ) + + #define KOKKOS_FORCEINLINE_FUNCTION __attribute__((amp,cpu)) inline + #define KOKKOS_INLINE_FUNCTION __attribute__((amp,cpu)) inline + #define KOKKOS_FUNCTION __attribute__((amp,cpu)) + #define KOKKOS_LAMBDA [=] __attribute__((amp,cpu)) + #define KOKKOS_FUNCTION_DEFAULTED KOKKOS_FUNCTION +#endif + #if defined( _OPENMP ) // Compiling with OpenMP. // The value of _OPENMP is an integer value YYYYMM @@ -179,15 +199,6 @@ // Host code is compiled again with another compiler. // Device code is compile to 'ptx'. #define KOKKOS_COMPILER_NVCC __NVCC__ -#else - #if !defined( KOKKOS_ENABLE_CXX11_DISPATCH_LAMBDA ) - #if !defined( KOKKOS_ENABLE_CUDA ) // Compiling with clang for Cuda does not work with LAMBDAs either - // CUDA (including version 6.5) does not support giving lambdas as - // arguments to global functions. Thus its not currently possible - // to dispatch lambdas from the host. - #define KOKKOS_ENABLE_CXX11_DISPATCH_LAMBDA 1 - #endif - #endif #endif // #if defined( __NVCC__ ) #if !defined( KOKKOS_LAMBDA ) @@ -321,6 +332,10 @@ //#define KOKKOS_ENABLE_PRAGMA_LOOPCOUNT 1 //#define KOKKOS_ENABLE_PRAGMA_VECTOR 1 //#define KOKKOS_ENABLE_PRAGMA_SIMD 1 + + #if ! defined( KOKKOS_ENABLE_ASM ) + #define KOKKOS_ENABLE_ASM 1 + #endif #endif //---------------------------------------------------------------------------- @@ -397,6 +412,10 @@ #define KOKKOS_FUNCTION /**/ #endif +#if !defined( KOKKOS_FUNCTION_DEFAULTED ) + #define KOKKOS_FUNCTION_DEFAULTED /**/ +#endif + //---------------------------------------------------------------------------- // Define empty macro for restrict if necessary: @@ -424,6 +443,7 @@ // There is zero or one default execution space specified. #if 1 < ( ( defined( KOKKOS_ENABLE_DEFAULT_DEVICE_TYPE_CUDA ) ? 1 : 0 ) + \ + ( defined( KOKKOS_ENABLE_DEFAULT_DEVICE_TYPE_ROCM ) ? 1 : 0 ) + \ ( defined( KOKKOS_ENABLE_DEFAULT_DEVICE_TYPE_OPENMPTARGET ) ? 1 : 0 ) + \ ( defined( KOKKOS_ENABLE_DEFAULT_DEVICE_TYPE_OPENMP ) ? 1 : 0 ) + \ ( defined( KOKKOS_ENABLE_DEFAULT_DEVICE_TYPE_THREADS ) ? 1 : 0 ) + \ @@ -435,6 +455,7 @@ // If default is not specified then chose from enabled execution spaces. // Priority: CUDA, OPENMP, THREADS, QTHREADS, SERIAL #if defined( KOKKOS_ENABLE_DEFAULT_DEVICE_TYPE_CUDA ) +#elif defined( KOKKOS_ENABLE_DEFAULT_DEVICE_TYPE_ROCM ) #elif defined( KOKKOS_ENABLE_DEFAULT_DEVICE_TYPE_OPENMPTARGET ) #elif defined( KOKKOS_ENABLE_DEFAULT_DEVICE_TYPE_OPENMP ) #elif defined( KOKKOS_ENABLE_DEFAULT_DEVICE_TYPE_THREADS ) @@ -442,6 +463,8 @@ #elif defined( KOKKOS_ENABLE_DEFAULT_DEVICE_TYPE_SERIAL ) #elif defined( KOKKOS_ENABLE_CUDA ) #define KOKKOS_ENABLE_DEFAULT_DEVICE_TYPE_CUDA +#elif defined( KOKKOS_ENABLE_ROCM ) + #define KOKKOS_ENABLE_DEFAULT_DEVICE_TYPE_ROCM #elif defined( KOKKOS_ENABLE_OPENMPTARGET ) #define KOKKOS_ENABLE_DEFAULT_DEVICE_TYPE_OPENMPTARGET #elif defined( KOKKOS_ENABLE_OPENMP ) @@ -459,6 +482,8 @@ #if defined( __CUDACC__ ) && defined( __CUDA_ARCH__ ) && defined( KOKKOS_ENABLE_CUDA ) #define KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_CUDA +#elif defined( __HCC__ ) && defined( __HCC_ACCELERATOR__ ) && defined( KOKKOS_ENABLE_ROCM ) + #define KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_ROCM_GPU #else #define KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_HOST #endif diff --git a/lib/kokkos/core/src/Kokkos_MemoryPool.hpp b/lib/kokkos/core/src/Kokkos_MemoryPool.hpp index 1da936067d..4ba5812f9e 100644 --- a/lib/kokkos/core/src/Kokkos_MemoryPool.hpp +++ b/lib/kokkos/core/src/Kokkos_MemoryPool.hpp @@ -233,12 +233,24 @@ public: //-------------------------------------------------------------------------- - MemoryPool() = default ; MemoryPool( MemoryPool && ) = default ; MemoryPool( const MemoryPool & ) = default ; MemoryPool & operator = ( MemoryPool && ) = default ; MemoryPool & operator = ( const MemoryPool & ) = default ; + MemoryPool() + : m_tracker() + , m_sb_state_array(0) + , m_sb_state_size(0) + , m_sb_size_lg2(0) + , m_max_block_size_lg2(0) + , m_min_block_size_lg2(0) + , m_sb_count(0) + , m_hint_offset(0) + , m_data_offset(0) + , m_unused_padding(0) + {} + /**\brief Allocate a memory pool from 'memspace'. * * The memory pool will have at least 'min_total_alloc_size' bytes diff --git a/lib/kokkos/core/src/Kokkos_Parallel_Reduce.hpp b/lib/kokkos/core/src/Kokkos_Parallel_Reduce.hpp index 9df6d4ba09..c392fc5b9a 100644 --- a/lib/kokkos/core/src/Kokkos_Parallel_Reduce.hpp +++ b/lib/kokkos/core/src/Kokkos_Parallel_Reduce.hpp @@ -1016,7 +1016,7 @@ parallel_reduce( std::string const & arg_label //------------------------------ - #if (KOKKOS_ENABLE_PROFILING) + #if defined(KOKKOS_ENABLE_PROFILING) uint64_t kpID = 0; if(Kokkos::Profiling::profileLibraryLoaded()) { Kokkos::Profiling::beginParallelReduce(arg_label, 0, &kpID); @@ -1042,7 +1042,7 @@ parallel_reduce( std::string const & arg_label //------------------------------ - #if (KOKKOS_ENABLE_PROFILING) + #if defined(KOKKOS_ENABLE_PROFILING) if(Kokkos::Profiling::profileLibraryLoaded()) { Kokkos::Profiling::endParallelReduce(kpID); } diff --git a/lib/kokkos/core/src/Kokkos_ROCm.hpp b/lib/kokkos/core/src/Kokkos_ROCm.hpp new file mode 100644 index 0000000000..b13b0b01de --- /dev/null +++ b/lib/kokkos/core/src/Kokkos_ROCm.hpp @@ -0,0 +1,220 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#ifndef KOKKOS_ROCM_HPP +#define KOKKOS_ROCM_HPP + +#include + +#if defined( KOKKOS_ENABLE_ROCM ) +#include +//---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*--------------------------------------------------------------------------*/ + +#include +#include +#include + +#if defined( __HCC_ACCELERATOR__ ) + +using namespace ::Concurrency::precise_math ; + +#endif + +/*--------------------------------------------------------------------------*/ + +namespace Kokkos { +namespace Impl { +class ROCmExec ; +} // namespace Impl +} // namespace Kokkos + +/*--------------------------------------------------------------------------*/ + +namespace Kokkos { +namespace Experimental { +/// \class ROCm +/// \brief Kokkos device for multicore processors in the host memory space. +class ROCm { +public: + //------------------------------------ + //! \name Type declarations that all Kokkos devices must provide. + //@{ + + //! Tag this class as a kokkos execution space + typedef ROCm execution_space ; + typedef ROCmSpace memory_space ; + typedef Kokkos::Device device_type; + + typedef LayoutLeft array_layout ; + typedef HostSpace::size_type size_type ; + + typedef ScratchMemorySpace< ROCm > scratch_memory_space ; + + ~ROCm() {} + ROCm(); +// explicit ROCm( const int instance_id ); + + ROCm( ROCm && ) = default ; + ROCm( const ROCm & ) = default ; + ROCm & operator = ( ROCm && ) = default ; + ROCm & operator = ( const ROCm & ) = default ; + + + //@} + //------------------------------------ + //! \name Functions that all Kokkos devices must implement. + //@{ + + KOKKOS_INLINE_FUNCTION static int in_parallel() { +#if defined( __HCC_ACCELERATOR__ ) + return true; +#else + return false; +#endif + } + + /** \brief Set the device in a "sleep" state. */ + static bool sleep() ; + + /** \brief Wake the device from the 'sleep' state. A noop for OpenMP. */ + static bool wake() ; + + /** \brief Wait until all dispatched functors complete. A noop for OpenMP. */ + static void fence() ; + + /// \brief Print configuration information to the given output stream. + static void print_configuration( std::ostream & , const bool detail = false ); + + /// \brief Free any resources being consumed by the device. + static void finalize() ; + + /** \brief Initialize the device. + * + */ + struct SelectDevice { + int rocm_device_id ; + SelectDevice() : rocm_device_id(1) {} + explicit SelectDevice( int id ) : rocm_device_id( id+1 ) {} + }; + + int rocm_device() const { return m_device ; } + bool isAPU(); + bool isAPU(int device); + + static void initialize( const SelectDevice = SelectDevice()); + + static int is_initialized(); + +// static size_type device_arch(); + +// static size_type detect_device_count(); + + + static int concurrency() ; + static const char* name(); +private: + int m_device ; + +}; +} +} // namespace Kokkos + +namespace Kokkos { +namespace Impl { + +template<> +struct MemorySpaceAccess + < Kokkos::Experimental::ROCmSpace + , Kokkos::Experimental::ROCm::scratch_memory_space + > +{ + enum { assignable = false }; + enum { accessible = true }; + enum { deepcopy = false }; +}; + +template<> +struct VerifyExecutionCanAccessMemorySpace + < Kokkos::Experimental::ROCm::memory_space + , Kokkos::Experimental::ROCm::scratch_memory_space + > +{ + enum { value = true }; + KOKKOS_INLINE_FUNCTION static void verify( void ) { } + KOKKOS_INLINE_FUNCTION static void verify( const void * ) { } +}; + +template<> +struct VerifyExecutionCanAccessMemorySpace + < Kokkos::HostSpace + , Kokkos::Experimental::ROCm::scratch_memory_space + > +{ + enum { value = false }; + inline static void verify( void ) { Experimental::ROCmSpace::access_error(); } + inline static void verify( const void * p ) { Experimental::ROCmSpace::access_error(p); } +}; +} // namespace Experimental +} // namespace Kokkos + + +#include +#include + +#endif +#endif + + diff --git a/lib/kokkos/core/src/Kokkos_ROCmSpace.hpp b/lib/kokkos/core/src/Kokkos_ROCmSpace.hpp new file mode 100644 index 0000000000..dce6a3cb3f --- /dev/null +++ b/lib/kokkos/core/src/Kokkos_ROCmSpace.hpp @@ -0,0 +1,622 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#ifndef KOKKOS_ROCMSPACE_HPP +#define KOKKOS_ROCMSPACE_HPP + +#include + +#if defined( KOKKOS_ENABLE_ROCM ) + +#include +#include +#include + +#include + + +/*--------------------------------------------------------------------------*/ + +namespace Kokkos { +namespace Experimental { +/** \brief ROCm on-device memory management */ + +class ROCmSpace { +public: + + //! Tag this class as a kokkos memory space + typedef ROCmSpace memory_space ; + typedef Kokkos::Experimental::ROCm execution_space ; + typedef Kokkos::Device device_type; + + typedef unsigned int size_type ; + + /*--------------------------------*/ + + ROCmSpace(); + ROCmSpace( ROCmSpace && rhs ) = default ; + ROCmSpace( const ROCmSpace & rhs ) = default ; + ROCmSpace & operator = ( ROCmSpace && rhs ) = default ; + ROCmSpace & operator = ( const ROCmSpace & rhs ) = default ; + ~ROCmSpace() = default ; + + /**\brief Allocate untracked memory in the rocm space */ + void * allocate( const size_t arg_alloc_size ) const ; + + /**\brief Deallocate untracked memory in the rocm space */ + void deallocate( void * const arg_alloc_ptr + , const size_t arg_alloc_size ) const ; + + /**\brief Return Name of the MemorySpace */ + static constexpr const char* name() { return m_name; }; + + /*--------------------------------*/ + /** \brief Error reporting for HostSpace attempt to access ROCmSpace */ + static void access_error(); + static void access_error( const void * const ); + +private: + + int m_device ; ///< Which ROCm device + + static constexpr const char* m_name = "ROCm"; + friend class Kokkos::Impl::SharedAllocationRecord< Kokkos::Experimental::ROCmSpace , void > ; +}; + +} // namespace Experimental + +namespace Impl { + +void * rocm_device_allocate(int); +void * rocm_hostpinned_allocate(int); +void rocm_device_free(void * ); + +/// \brief Initialize lock array for arbitrary size atomics. +/// +/// Arbitrary atomics are implemented using a hash table of locks +/// where the hash value is derived from the address of the +/// object for which an atomic operation is performed. +/// This function initializes the locks to zero (unset). +void init_lock_arrays_rocm_space(); + +/// \brief Retrieve the pointer to the lock array for arbitrary size atomics. +/// +/// Arbitrary atomics are implemented using a hash table of locks +/// where the hash value is derived from the address of the +/// object for which an atomic operation is performed. +/// This function retrieves the lock array pointer. +/// If the array is not yet allocated it will do so. +int* atomic_lock_array_rocm_space_ptr(bool deallocate = false); + +/// \brief Retrieve the pointer to the scratch array for team and thread private global memory. +/// +/// Team and Thread private scratch allocations in +/// global memory are aquired via locks. +/// This function retrieves the lock array pointer. +/// If the array is not yet allocated it will do so. +int* scratch_lock_array_rocm_space_ptr(bool deallocate = false); + +/// \brief Retrieve the pointer to the scratch array for unique identifiers. +/// +/// Unique identifiers in the range 0-ROCm::concurrency +/// are provided via locks. +/// This function retrieves the lock array pointer. +/// If the array is not yet allocated it will do so. +int* threadid_lock_array_rocm_space_ptr(bool deallocate = false); +} +} // namespace Kokkos + +/*--------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------*/ + + +namespace Kokkos { +namespace Experimental { +/** \brief Host memory that is accessible to ROCm execution space + * through ROCm's host-pinned memory allocation. + */ +class ROCmHostPinnedSpace { +public: + + //! Tag this class as a kokkos memory space + /** \brief Memory is in HostSpace so use the HostSpace::execution_space */ + typedef HostSpace::execution_space execution_space ; + typedef ROCmHostPinnedSpace memory_space ; + typedef Kokkos::Device device_type; + typedef unsigned int size_type ; + + /*--------------------------------*/ + + ROCmHostPinnedSpace(); + ROCmHostPinnedSpace( ROCmHostPinnedSpace && rhs ) = default ; + ROCmHostPinnedSpace( const ROCmHostPinnedSpace & rhs ) = default ; + ROCmHostPinnedSpace & operator = ( ROCmHostPinnedSpace && rhs ) = default ; + ROCmHostPinnedSpace & operator = ( const ROCmHostPinnedSpace & rhs ) = default ; + ~ROCmHostPinnedSpace() = default ; + + /**\brief Allocate untracked memory in the space */ + void * allocate( const size_t arg_alloc_size ) const ; + + /**\brief Deallocate untracked memory in the space */ + void deallocate( void * const arg_alloc_ptr + , const size_t arg_alloc_size ) const ; + + /**\brief Return Name of the MemorySpace */ + static constexpr const char* name() { return m_name; }; + +private: + + static constexpr const char* m_name = "ROCmHostPinned"; + + /*--------------------------------*/ +}; +} // namespace Experimental +} // namespace Kokkos + +/*--------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------*/ + +namespace Kokkos { +namespace Impl { + +static_assert( Kokkos::Impl::MemorySpaceAccess< Kokkos::Experimental::ROCmSpace , Kokkos::Experimental::ROCmSpace >::assignable , "" ); + +//---------------------------------------- + +template<> +struct MemorySpaceAccess< Kokkos::HostSpace , Kokkos::Experimental::ROCmSpace > { + enum { assignable = false }; + enum { accessible = false }; + enum { deepcopy = true }; +}; + +template<> +struct MemorySpaceAccess< Kokkos::HostSpace , Kokkos::Experimental::ROCmHostPinnedSpace > { + // HostSpace::execution_space == ROCmHostPinnedSpace::execution_space + enum { assignable = true }; + enum { accessible = true }; + enum { deepcopy = true }; +}; + +//---------------------------------------- + +template<> +struct MemorySpaceAccess< Kokkos::Experimental::ROCmSpace , Kokkos::HostSpace > { + enum { assignable = false }; + enum { accessible = false }; + enum { deepcopy = true }; +}; + +template<> +struct MemorySpaceAccess< Kokkos::Experimental::ROCmSpace , Kokkos::Experimental::ROCmHostPinnedSpace > { + // ROCmSpace::execution_space != ROCmHostPinnedSpace::execution_space + enum { assignable = false }; + enum { accessible = true }; // ROCmSpace::execution_space + enum { deepcopy = true }; +}; + + +//---------------------------------------- +// ROCmHostPinnedSpace::execution_space == HostSpace::execution_space +// ROCmHostPinnedSpace accessible to both ROCm and Host + +template<> +struct MemorySpaceAccess< Kokkos::Experimental::ROCmHostPinnedSpace , Kokkos::HostSpace > { + enum { assignable = false }; // Cannot access from ROCm + enum { accessible = true }; // ROCmHostPinnedSpace::execution_space + enum { deepcopy = true }; +}; + +template<> +struct MemorySpaceAccess< Kokkos::Experimental::ROCmHostPinnedSpace , Kokkos::Experimental::ROCmSpace > { + enum { assignable = false }; // Cannot access from Host + enum { accessible = false }; + enum { deepcopy = true }; +}; + +}; +//---------------------------------------- + +} // namespace Kokkos::Impl + +/*--------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------*/ + +namespace Kokkos { +namespace Impl { + +hc::completion_future DeepCopyAsyncROCm( void * dst , const void * src , size_t n); + +template<> struct DeepCopy< Kokkos::Experimental::ROCmSpace , Kokkos::Experimental::ROCmSpace , Kokkos::Experimental::ROCm> +{ + DeepCopy( void * dst , const void * src , size_t ); + DeepCopy( const Kokkos::Experimental::ROCm & , void * dst , const void * src , size_t ); +}; + +template<> struct DeepCopy< Kokkos::Experimental::ROCmSpace , HostSpace , Kokkos::Experimental::ROCm > +{ + DeepCopy( void * dst , const void * src , size_t ); + DeepCopy( const Kokkos::Experimental::ROCm & , void * dst , const void * src , size_t ); +}; + +template<> struct DeepCopy< HostSpace , Kokkos::Experimental::ROCmSpace , Kokkos::Experimental::ROCm > +{ + DeepCopy( void * dst , const void * src , size_t ); + DeepCopy( const Kokkos::Experimental::ROCm & , void * dst , const void * src , size_t ); +}; + +template struct DeepCopy< Kokkos::Experimental::ROCmSpace , Kokkos::Experimental::ROCmSpace , ExecutionSpace > +{ + inline + DeepCopy( void * dst , const void * src , size_t n ) + { (void) DeepCopy< Kokkos::Experimental::ROCmSpace , Kokkos::Experimental::ROCmSpace , Kokkos::Experimental::ROCm >( dst , src , n ); } + + inline + DeepCopy( const ExecutionSpace& exec, void * dst , const void * src , size_t n ) + { + exec.fence(); + hc::completion_future fut = DeepCopyAsyncROCm (dst,src,n); + fut.wait(); +// DeepCopy (dst,src,n); + } +}; + +template struct DeepCopy< Kokkos::Experimental::ROCmSpace , HostSpace , ExecutionSpace > +{ + inline + DeepCopy( void * dst , const void * src , size_t n ) + { (void) DeepCopy< Kokkos::Experimental::ROCmSpace , HostSpace , Kokkos::Experimental::ROCm>( dst , src , n ); } + + inline + DeepCopy( const ExecutionSpace& exec, void * dst , const void * src , size_t n ) + { + exec.fence(); + DeepCopy (dst,src,n); + } +}; + +template +struct DeepCopy< HostSpace , Kokkos::Experimental::ROCmSpace , ExecutionSpace > +{ + inline + DeepCopy( void * dst , const void * src , size_t n ) + { (void) DeepCopy< HostSpace , Kokkos::Experimental::ROCmSpace , Kokkos::Experimental::ROCm >( dst , src , n ); } + + inline + DeepCopy( const ExecutionSpace& exec, void * dst , const void * src , size_t n ) + { + exec.fence(); + DeepCopy (dst,src,n); + } +}; + +template<> struct DeepCopy< Kokkos::Experimental::ROCmHostPinnedSpace , Kokkos::Experimental::ROCmHostPinnedSpace , Kokkos::Experimental::ROCm> +{ + DeepCopy( void * dst , const void * src , size_t ); + DeepCopy( const Kokkos::Experimental::ROCm & , void * dst , const void * src , size_t ); +}; + +template<> struct DeepCopy< Kokkos::Experimental::ROCmHostPinnedSpace , HostSpace , Kokkos::Experimental::ROCm > +{ + DeepCopy( void * dst , const void * src , size_t ); + DeepCopy( const Kokkos::Experimental::ROCm & , void * dst , const void * src , size_t ); +}; + +template<> struct DeepCopy< HostSpace , Kokkos::Experimental::ROCmHostPinnedSpace , Kokkos::Experimental::ROCm > +{ + DeepCopy( void * dst , const void * src , size_t ); + DeepCopy( const Kokkos::Experimental::ROCm & , void * dst , const void * src , size_t ); +}; + +template +struct DeepCopy< Kokkos::Experimental::ROCmSpace , Kokkos::Experimental::ROCmHostPinnedSpace , ExecutionSpace> +{ + inline + DeepCopy( void * dst , const void * src , size_t n ) + { (void) DeepCopy< Kokkos::Experimental::ROCmSpace , HostSpace , Kokkos::Experimental::ROCm >( dst , src , n ); } + + inline + DeepCopy( const ExecutionSpace& exec, void * dst , const void * src , size_t n ) + { + exec.fence(); + hc::completion_future fut = DeepCopyAsyncROCm (dst,src,n); + fut.wait(); +// DeepCopyROCm (dst,src,n); + } +}; + +template struct DeepCopy< Kokkos::Experimental::ROCmHostPinnedSpace , Kokkos::Experimental::ROCmSpace , ExecutionSpace > +{ + inline + DeepCopy( void * dst , const void * src , size_t n ) + { (void) DeepCopy< HostSpace , Kokkos::Experimental::ROCmSpace , Kokkos::Experimental::ROCm >( dst , src , n ); } + + inline + DeepCopy( const ExecutionSpace& exec, void * dst , const void * src , size_t n ) + { + exec.fence(); + hc::completion_future fut = DeepCopyAsyncROCm (dst,src,n); + fut.wait(); +// DeepCopyROCm (dst,src,n); + } +}; + + + +template struct DeepCopy< Kokkos::Experimental::ROCmHostPinnedSpace , Kokkos::Experimental::ROCmHostPinnedSpace , ExecutionSpace > +{ + inline + DeepCopy( void * dst , const void * src , size_t n ) + { (void) DeepCopy< Kokkos::Experimental::ROCmHostPinnedSpace , Kokkos::Experimental::ROCmHostPinnedSpace , Kokkos::Experimental::ROCm >( dst , src , n ); } + + inline + DeepCopy( const ExecutionSpace& exec, void * dst , const void * src , size_t n ) + { + exec.fence(); +// hc::completion_future fut = DeepCopyAsyncROCm (dst,src,n); +// fut.wait(); +// DeepCopyAsyncROCm (dst,src,n); + DeepCopy (dst,src,n); + } +}; + +template struct DeepCopy< Kokkos::Experimental::ROCmHostPinnedSpace , HostSpace , ExecutionSpace > +{ + inline + DeepCopy( void * dst , const void * src , size_t n ) + { (void) DeepCopy< Kokkos::Experimental::ROCmHostPinnedSpace , HostSpace , Kokkos::Experimental::ROCm>( dst , src , n ); } + + inline + DeepCopy( const ExecutionSpace& exec, void * dst , const void * src , size_t n ) + { + exec.fence(); + DeepCopy (dst,src,n); + } +}; + +template +struct DeepCopy< HostSpace , Kokkos::Experimental::ROCmHostPinnedSpace , ExecutionSpace > +{ + inline + DeepCopy( void * dst , const void * src , size_t n ) + { (void) DeepCopy< HostSpace , Kokkos::Experimental::ROCmHostPinnedSpace , Kokkos::Experimental::ROCm >( dst , src , n ); } + + inline + DeepCopy( const ExecutionSpace& exec, void * dst , const void * src , size_t n ) + { + exec.fence(); + DeepCopy (dst,src,n); + } +}; +} // namespace Impl +} // namespace Kokkos + +//---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- + +namespace Kokkos { +namespace Impl { + +/** Running in ROCmSpace attempting to access HostSpace: error */ +template<> +struct VerifyExecutionCanAccessMemorySpace< Kokkos::Experimental::ROCmSpace , Kokkos::HostSpace > +{ + enum { value = false }; + KOKKOS_INLINE_FUNCTION static void verify( void ) + { Kokkos::abort("ROCm code attempted to access HostSpace memory"); } + + KOKKOS_INLINE_FUNCTION static void verify( const void * ) + { Kokkos::abort("ROCm code attempted to access HostSpace memory"); } +}; + +/** Running in ROCmSpace accessing ROCmHostPinnedSpace: ok */ +template<> +struct VerifyExecutionCanAccessMemorySpace< Kokkos::Experimental::ROCmSpace , Kokkos::Experimental::ROCmHostPinnedSpace > +{ + enum { value = true }; + KOKKOS_INLINE_FUNCTION static void verify( void ) { } + KOKKOS_INLINE_FUNCTION static void verify( const void * ) { } +}; + +/** Running in ROCmSpace attempting to access an unknown space: error */ +template< class OtherSpace > +struct VerifyExecutionCanAccessMemorySpace< + typename enable_if< ! is_same::value , Kokkos::Experimental::ROCmSpace >::type , + OtherSpace > +{ + enum { value = false }; + KOKKOS_INLINE_FUNCTION static void verify( void ) + { Kokkos::abort("ROCm code attempted to access unknown Space memory"); } + + KOKKOS_INLINE_FUNCTION static void verify( const void * ) + { Kokkos::abort("ROCm code attempted to access unknown Space memory"); } +}; + +//---------------------------------------------------------------------------- +/** Running in HostSpace attempting to access ROCmSpace */ +template<> +struct VerifyExecutionCanAccessMemorySpace< Kokkos::HostSpace , Kokkos::Experimental::ROCmSpace > +{ + enum { value = false }; + inline static void verify( void ) { Kokkos::Experimental::ROCmSpace::access_error(); } + inline static void verify( const void * p ) { Kokkos::Experimental::ROCmSpace::access_error(p); } +}; + +/** Running in HostSpace accessing ROCmHostPinnedSpace is OK */ +template<> +struct VerifyExecutionCanAccessMemorySpace< Kokkos::HostSpace , Kokkos::Experimental::ROCmHostPinnedSpace > +{ + enum { value = true }; + KOKKOS_INLINE_FUNCTION static void verify( void ) {} + KOKKOS_INLINE_FUNCTION static void verify( const void * ) {} +}; +} // namespace Impl +} // namespace Kokkos + +//---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- + +namespace Kokkos { +namespace Impl { + +template<> +class SharedAllocationRecord< Kokkos::Experimental::ROCmSpace , void > + : public SharedAllocationRecord< void , void > +{ +private: + + + typedef SharedAllocationRecord< void , void > RecordBase ; + + SharedAllocationRecord( const SharedAllocationRecord & ) = delete ; + SharedAllocationRecord & operator = ( const SharedAllocationRecord & ) = delete ; + + static void deallocate( RecordBase * ); + + static RecordBase s_root_record ; + + const Kokkos::Experimental::ROCmSpace m_space ; + +protected: + + ~SharedAllocationRecord(); + + SharedAllocationRecord( const Kokkos::Experimental::ROCmSpace & arg_space + , const std::string & arg_label + , const size_t arg_alloc_size + , const RecordBase::function_type arg_dealloc = & deallocate + ); + +public: + + std::string get_label() const ; + + static SharedAllocationRecord * allocate( const Kokkos::Experimental::ROCmSpace & arg_space + , const std::string & arg_label + , const size_t arg_alloc_size ); + + /**\brief Allocate tracked memory in the space */ + static + void * allocate_tracked( const Kokkos::Experimental::ROCmSpace & arg_space + , const std::string & arg_label + , const size_t arg_alloc_size ); + + /**\brief Reallocate tracked memory in the space */ + static + void * reallocate_tracked( void * const arg_alloc_ptr + , const size_t arg_alloc_size ); + + /**\brief Deallocate tracked memory in the space */ + static + void deallocate_tracked( void * const arg_alloc_ptr ); + + static SharedAllocationRecord * get_record( void * arg_alloc_ptr ); + + static void print_records( std::ostream & , const Kokkos::Experimental::ROCmSpace & , bool detail = false ); +}; + +template<> +class SharedAllocationRecord< Kokkos::Experimental::ROCmHostPinnedSpace , void > + : public SharedAllocationRecord< void , void > +{ +private: + + typedef SharedAllocationRecord< void , void > RecordBase ; + + SharedAllocationRecord( const SharedAllocationRecord & ) = delete ; + SharedAllocationRecord & operator = ( const SharedAllocationRecord & ) = delete ; + + static void deallocate( RecordBase * ); + + static RecordBase s_root_record ; + + const Kokkos::Experimental::ROCmHostPinnedSpace m_space ; + +protected: + + ~SharedAllocationRecord(); + SharedAllocationRecord() : RecordBase(), m_space() {} + + SharedAllocationRecord( const Kokkos::Experimental::ROCmHostPinnedSpace & arg_space + , const std::string & arg_label + , const size_t arg_alloc_size + , const RecordBase::function_type arg_dealloc = & deallocate + ); + +public: + + std::string get_label() const ; + + static SharedAllocationRecord * allocate( const Kokkos::Experimental::ROCmHostPinnedSpace & arg_space + , const std::string & arg_label + , const size_t arg_alloc_size + ); + /**\brief Allocate tracked memory in the space */ + static + void * allocate_tracked( const Kokkos::Experimental::ROCmHostPinnedSpace & arg_space + , const std::string & arg_label + , const size_t arg_alloc_size ); + + /**\brief Reallocate tracked memory in the space */ + static + void * reallocate_tracked( void * const arg_alloc_ptr + , const size_t arg_alloc_size ); + + /**\brief Deallocate tracked memory in the space */ + static + void deallocate_tracked( void * const arg_alloc_ptr ); + + + static SharedAllocationRecord * get_record( void * arg_alloc_ptr ); + + static void print_records( std::ostream & , const Kokkos::Experimental::ROCmHostPinnedSpace & , bool detail = false ); +}; +} // namespace Impl +} // namespace Kokkos + +//---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- + +#endif /* #if defined( KOKKOS_ENABLE_ROCM ) */ +#endif /* #define KOKKOS_ROCMSPACE_HPP */ + diff --git a/lib/kokkos/core/src/Kokkos_TaskScheduler.hpp b/lib/kokkos/core/src/Kokkos_TaskScheduler.hpp index fcfc91a4ee..079f80f556 100644 --- a/lib/kokkos/core/src/Kokkos_TaskScheduler.hpp +++ b/lib/kokkos/core/src/Kokkos_TaskScheduler.hpp @@ -681,6 +681,67 @@ public: return f ; } + template < class F > + KOKKOS_FUNCTION + Future< execution_space > + when_all( int narg , F const func ) + { + using input_type = decltype( func(0) ); + using future_type = Future< execution_space > ; + using task_base = Kokkos::Impl::TaskBase< void , void , void > ; + + static_assert( is_future< input_type >::value + , "Functor must return a Kokkos::Future" ); + + future_type f ; + + if ( 0 == narg ) return f ; + + size_t const alloc_size = m_queue->when_all_allocation_size( narg ); + + f.m_task = + reinterpret_cast< task_base * >( m_queue->allocate( alloc_size ) ); + + if ( f.m_task ) { + + // Reference count starts at two: + // +1 to match decrement when task completes + // +1 for the future + + new( f.m_task ) task_base(); + + f.m_task->m_queue = m_queue ; + f.m_task->m_ref_count = 2 ; + f.m_task->m_alloc_size = alloc_size ; + f.m_task->m_dep_count = narg ; + f.m_task->m_task_type = task_base::Aggregate ; + + // Assign dependences, reference counts were already incremented + + task_base * volatile * const dep = + f.m_task->aggregate_dependences(); + + for ( int i = 0 ; i < narg ; ++i ) { + const input_type arg_f = func(i); + if ( 0 != arg_f.m_task ) { + + if ( m_queue != static_cast< queue_type * >( arg_f.m_task->m_queue ) ) { + Kokkos::abort("Kokkos when_all Futures must be in the same scheduler" ); + } + // Increment reference count to track subsequent assignment. + Kokkos::atomic_increment( &(arg_f.m_task->m_ref_count) ); + dep[i] = arg_f.m_task ; + } + } + + Kokkos::memory_fence(); + + m_queue->schedule_aggregate( f.m_task ); + // this when_all may be processed at any moment + } + return f ; + } + //---------------------------------------- KOKKOS_INLINE_FUNCTION diff --git a/lib/kokkos/core/src/Kokkos_View.hpp b/lib/kokkos/core/src/Kokkos_View.hpp index 1754e4a8fb..47b105cfdc 100644 --- a/lib/kokkos/core/src/Kokkos_View.hpp +++ b/lib/kokkos/core/src/Kokkos_View.hpp @@ -2429,6 +2429,7 @@ template < class ValueType > struct CommonViewAllocProp< void, ValueType > { using value_type = ValueType; + using scalar_array_type = ValueType; template < class ... Views > CommonViewAllocProp( const Views & ... ) {} diff --git a/lib/kokkos/core/src/ROCm/Kokkos_ROCm_Atomic.hpp b/lib/kokkos/core/src/ROCm/Kokkos_ROCm_Atomic.hpp new file mode 100644 index 0000000000..a93f488203 --- /dev/null +++ b/lib/kokkos/core/src/ROCm/Kokkos_ROCm_Atomic.hpp @@ -0,0 +1,439 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include +//#include + +#ifdef KOKKOS_ENABLE_ROCM_ATOMICS +namespace Kokkos { + //ROCm can do: + //Types int/unsigned int + //variants: atomic_exchange/compare_exchange/fetch_add/fetch_sub/fetch_max/fetch_min/fetch_and/fetch_or/fetch_xor/fetch_inc/fetch_dec + + + KOKKOS_INLINE_FUNCTION + int atomic_exchange(int* dest, const int& val) { + return hc::atomic_exchange_int(dest, val); + } + + KOKKOS_INLINE_FUNCTION + unsigned int atomic_exchange(unsigned int* dest, const unsigned int& val) { + return hc::atomic_exchange_unsigned(dest, val); + } + + KOKKOS_INLINE_FUNCTION + int64_t atomic_exchange(int64_t* dest, const int64_t& val) { + return (int64_t)hc::atomic_exchange_uint64((uint64_t*)dest, (const uint64_t&)val); + } + + KOKKOS_INLINE_FUNCTION + uint64_t atomic_exchange(uint64_t* dest, const uint64_t& val) { + return hc::atomic_exchange_uint64(dest, val); + } + + KOKKOS_INLINE_FUNCTION + long long atomic_exchange(long long* dest, const long long& val) { + return (long long)hc::atomic_exchange_uint64((uint64_t*)dest, (const uint64_t&)val); + } + + KOKKOS_INLINE_FUNCTION + unsigned long long atomic_exchange(unsigned long long* dest, const unsigned long long& val) { + return (unsigned long long)hc::atomic_exchange_uint64((uint64_t*)dest, (const uint64_t&)val); + } + + KOKKOS_INLINE_FUNCTION + float atomic_exchange(float* dest, const float& val) { + union U { + int i ; + float f ; + KOKKOS_INLINE_FUNCTION U() {}; + } idest,ival; + idest.f = *dest; + ival.f = val; + idest.i = hc::atomic_exchange_int((int*)dest, ival.i); + return idest.f; + } + + KOKKOS_INLINE_FUNCTION + double atomic_exchange(double* dest, const double& val) { + union U { + uint64_t i ; + double d ; + KOKKOS_INLINE_FUNCTION U() {}; + } idest,ival; + idest.d = *dest; + ival.d = val; + idest.i = hc::atomic_exchange_uint64((uint64_t*)dest, ival.i); + return idest.d; + } + + KOKKOS_INLINE_FUNCTION + int atomic_compare_exchange(int* dest, int compare, const int& val); + + KOKKOS_INLINE_FUNCTION + int64_t atomic_compare_exchange(int64_t* dest, int64_t compare, const int64_t& val); + + template + KOKKOS_INLINE_FUNCTION + T atomic_exchange(T* dest, typename std::enable_if::type val) { + union U { + int i ; + T t ; + KOKKOS_INLINE_FUNCTION U() {}; + } assume , oldval , newval ; + + oldval.t = *dest ; + assume.i = oldval.i ; + newval.t = val ; + atomic_compare_exchange( reinterpret_cast(dest) , assume.i, newval.i ); + + return oldval.t ; + } + + template + KOKKOS_INLINE_FUNCTION + T atomic_exchange(T* dest, typename std::enable_if::type val) { + union U { + uint64_t i ; + T t ; + KOKKOS_INLINE_FUNCTION U() {}; + } assume , oldval , newval ; + + oldval.t = *dest ; + + assume.i = oldval.i ; + newval.t = val ; + atomic_compare_exchange( (int64_t*)(dest) , assume.i, newval.i ); + + return oldval.t ; + } + + template + KOKKOS_INLINE_FUNCTION + T atomic_exchange(T* dest, typename std::enable_if::type val) { + return val; + } + + KOKKOS_INLINE_FUNCTION + int atomic_compare_exchange(int* dest, int compare, const int& val) { + return hc::atomic_compare_exchange_int(dest, compare, val); + } + + KOKKOS_INLINE_FUNCTION + unsigned int atomic_compare_exchange(unsigned int* dest, unsigned int compare, const unsigned int& val) { + return hc::atomic_compare_exchange_unsigned(dest, compare, val); + } + + KOKKOS_INLINE_FUNCTION + int64_t atomic_compare_exchange(int64_t* dest, int64_t compare, const int64_t& val) { + return (int64_t) hc::atomic_compare_exchange_uint64((uint64_t*)dest, (uint64_t)compare, (const uint64_t&)val); + } + + KOKKOS_INLINE_FUNCTION + uint64_t atomic_compare_exchange(uint64_t* dest, uint64_t compare, const uint64_t& val) { + return hc::atomic_compare_exchange_uint64(dest, compare, val); + } + + KOKKOS_INLINE_FUNCTION + long long atomic_compare_exchange(long long* dest, long long compare, const long long& val) { + return (long long)hc::atomic_compare_exchange_uint64((uint64_t*)(dest), (uint64_t)(compare), (const uint64_t&)(val)); + } + + KOKKOS_INLINE_FUNCTION + float atomic_compare_exchange(float* dest, float compare, const float& val) { + union U { + int i ; + float f ; + KOKKOS_INLINE_FUNCTION U() {}; + } idest,icompare,ival; + idest.f = *dest; + icompare.f = compare; + ival.f = val; + idest.i = hc::atomic_compare_exchange_int(reinterpret_cast(dest), icompare.i, ival.i); + return idest.f; + } + + KOKKOS_INLINE_FUNCTION + double atomic_compare_exchange(double* dest, double compare, const double& val) { + union U { + uint64_t i ; + double d ; + KOKKOS_INLINE_FUNCTION U() {}; + } idest,icompare,ival; + idest.d = *dest; + icompare.d = compare; + ival.d = val; + idest.i = hc::atomic_compare_exchange_uint64(reinterpret_cast(dest), icompare.i, ival.i); + return idest.d; + } + + template + KOKKOS_INLINE_FUNCTION + T atomic_compare_exchange(volatile T* dest, T compare, typename std::enable_if::type val) { + union U { + int i ; + T f ; + KOKKOS_INLINE_FUNCTION U() {}; + } idest,icompare,ival; + idest.f = *dest; + icompare.f = compare; + ival.f = val; + idest.i = hc::atomic_compare_exchange_int((int*)(dest), icompare.i, ival.i); + return idest.f; + } + + template + KOKKOS_INLINE_FUNCTION + T atomic_compare_exchange(volatile T* dest, T compare, typename std::enable_if::type val) { + union U { + uint64_t i ; + T f ; + KOKKOS_INLINE_FUNCTION U() {}; + } idest,icompare,ival; + idest.f = *dest; + icompare.f = compare; + ival.f = val; + idest.i = hc::atomic_compare_exchange_uint64((uint64_t*)(dest), icompare.i, ival.i); + return idest.f; + } + + template + KOKKOS_INLINE_FUNCTION + T atomic_compare_exchange(volatile T* dest, T compare, typename std::enable_if<(sizeof(T) != sizeof(int32_t)) && (sizeof(T) != sizeof(int64_t)), const T&>::type val) { + return val; + } + + KOKKOS_INLINE_FUNCTION + int atomic_fetch_add (volatile int * dest, const int& val) { + return hc::atomic_fetch_add((int *)dest, val); + } + + KOKKOS_INLINE_FUNCTION + unsigned int atomic_fetch_add(unsigned int* dest, const unsigned int& val) { + return hc::atomic_fetch_add(dest, val); + } + + KOKKOS_INLINE_FUNCTION + unsigned long atomic_fetch_add(volatile unsigned long* dest, const unsigned long& val) { + return (unsigned long)hc::atomic_fetch_add((uint64_t *)dest, (const uint64_t)val); + } + + KOKKOS_INLINE_FUNCTION + int64_t atomic_fetch_add(volatile int64_t* dest, const int64_t& val) { + return (int64_t)hc::atomic_fetch_add((uint64_t *)dest, (const uint64_t&)val); + } + + KOKKOS_INLINE_FUNCTION + char atomic_fetch_add(volatile char * dest, const char& val) { + unsigned int oldval,newval,assume; + oldval = *(int *)dest ; + + do { + assume = oldval ; + newval = assume&0x7fffff00 + ((assume&0xff)+val)&0xff ; + oldval = hc::atomic_compare_exchange_unsigned((unsigned int*)dest, assume,newval); + } while ( assume != oldval ); + + return oldval ; + } + + + KOKKOS_INLINE_FUNCTION + short atomic_fetch_add(volatile short * dest, const short& val) { + unsigned int oldval,newval,assume; + oldval = *(int *)dest ; + + do { + assume = oldval ; + newval = assume&0x7fff0000 + ((assume&0xffff)+val)&0xffff ; + oldval = hc::atomic_compare_exchange_unsigned((unsigned int*)dest, assume,newval); + } while ( assume != oldval ); + + return oldval ; + } + + KOKKOS_INLINE_FUNCTION + long long atomic_fetch_add(volatile long long * dest, const long long& val) { + return (long long)hc::atomic_fetch_add((uint64_t*)dest, (const uint64_t&)val); + } + + + + KOKKOS_INLINE_FUNCTION + int atomic_fetch_sub (volatile int * dest, const int& val) { + return hc::atomic_fetch_sub((int *)dest, val); + } + + KOKKOS_INLINE_FUNCTION + unsigned int atomic_fetch_sub(volatile unsigned int* dest, const unsigned int& val) { + return hc::atomic_fetch_sub((unsigned int *)dest, val); + } + + KOKKOS_INLINE_FUNCTION + int64_t atomic_fetch_sub(int64_t* dest, const int64_t& val) { + return (int64_t)hc::atomic_fetch_add((uint64_t *)dest, -(const uint64_t&)val); +// return (int64_t)hc::atomic_fetch_sub_uint64((uint64_t*)dest, (const uint64_t&)val); + } + + KOKKOS_INLINE_FUNCTION + char atomic_fetch_sub(volatile char * dest, const char& val) { + unsigned int oldval,newval,assume; + oldval = *(int *)dest ; + + do { + assume = oldval ; + newval = assume&0x7fffff00 + ((assume&0xff)-val)&0xff ; + oldval = hc::atomic_compare_exchange_unsigned((unsigned int*)dest, assume,newval); + } while ( assume != oldval ); + + return oldval ; + } + + KOKKOS_INLINE_FUNCTION + short atomic_fetch_sub(volatile short * dest, const short& val) { + unsigned int oldval,newval,assume; + oldval = *(int *)dest ; + + do { + assume = oldval ; + newval = assume&0x7fff0000 + ((assume&0xffff)-val)&0xffff; + oldval = hc::atomic_compare_exchange_unsigned((unsigned int*)dest, assume,newval); + } while ( assume != oldval ); + + return oldval ; + } + + KOKKOS_INLINE_FUNCTION + long long atomic_fetch_sub(volatile long long * dest, const long long& val) { + return (long long)hc::atomic_fetch_add((uint64_t*)dest, -(const uint64_t&)val); + } + + template + KOKKOS_INLINE_FUNCTION + T atomic_fetch_add(volatile T* dest, typename std::enable_if::type val) { + union U { + unsigned int i ; + T t ; + KOKKOS_INLINE_FUNCTION U() {}; + } assume , oldval , newval ; + + oldval.t = *dest ; + + do { + assume.i = oldval.i ; + newval.t = assume.t + val ; + oldval.i = atomic_compare_exchange( (unsigned int*)(dest) , assume.i , newval.i ); + } while ( assume.i != oldval.i ); + + return oldval.t ; + } + + template + KOKKOS_INLINE_FUNCTION + T atomic_fetch_add(volatile T* dest, typename std::enable_if::type val) { + union U { + uint64_t i ; + T t ; + KOKKOS_INLINE_FUNCTION U() {}; + } assume , oldval , newval ; + + oldval.t = *dest ; + + do { + assume.i = oldval.i ; + newval.t = assume.t + val ; + oldval.i = atomic_compare_exchange( (uint64_t*)dest , assume.i , newval.i ); + } while ( assume.i != oldval.i ); + + return oldval.t ; + } + + + //WORKAROUND + template + KOKKOS_INLINE_FUNCTION + T atomic_fetch_add(volatile T* dest, typename std::enable_if::type val) { + return val ; + } + + template + KOKKOS_INLINE_FUNCTION + T atomic_fetch_sub(volatile T* dest, typename std::enable_if::type & val) { + union U { + int i ; + T t ; + KOKKOS_INLINE_FUNCTION U() {}; + } assume , oldval , newval ; + + oldval.t = *dest ; + + do { + assume.i = oldval.i ; + newval.t = assume.t - val ; + oldval.i = Kokkos::atomic_compare_exchange( (int*)dest , assume.i , newval.i ); + } while ( assume.i != oldval.i ); + + return oldval.t ; + } + + template + KOKKOS_INLINE_FUNCTION + T atomic_fetch_sub(volatile T* dest, typename std::enable_if::type val) { + union U { + int64_t i ; + T t ; + KOKKOS_INLINE_FUNCTION U() {}; + } assume , oldval , newval ; + + oldval.t = *dest ; + + do { + assume.i = oldval.i ; + newval.t = assume.t - val ; + oldval.i = atomic_compare_exchange( (int64_t*)dest , assume.i , newval.i ); + } while ( assume.i != oldval.i ); + + return oldval.t ; + } +} +#endif diff --git a/lib/kokkos/core/src/ROCm/Kokkos_ROCm_Config.hpp b/lib/kokkos/core/src/ROCm/Kokkos_ROCm_Config.hpp new file mode 100644 index 0000000000..83b5792a64 --- /dev/null +++ b/lib/kokkos/core/src/ROCm/Kokkos_ROCm_Config.hpp @@ -0,0 +1,51 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#ifndef GUARD_CORE_KOKKOS_ROCM_CONFIG_HPP +#define GUARD_CORE_KOKKOS_ROCM_CONFIG_HPP + +#ifndef KOKKOS_ROCM_HAS_WORKAROUNDS +#define KOKKOS_ROCM_HAS_WORKAROUNDS 1 +#endif + +#endif diff --git a/lib/kokkos/core/src/ROCm/Kokkos_ROCm_Exec.cpp b/lib/kokkos/core/src/ROCm/Kokkos_ROCm_Exec.cpp new file mode 100644 index 0000000000..e919d35903 --- /dev/null +++ b/lib/kokkos/core/src/ROCm/Kokkos_ROCm_Exec.cpp @@ -0,0 +1,133 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ +#ifndef KOKKOS_ROCMEXEC_HPP +#define KOKKOS_ROCMEXEC_HPP + +#include +#include +#include +//#include +#include + +#define ROCM_SPACE_ATOMIC_MASK 0x1FFFF +#define ROCM_SPACE_ATOMIC_XOR_MASK 0x15A39 +#define ROCM_CONCURRENCY 20480 +//#define ROCM_CONCURRENCY 81920 # for fiji + +namespace Kokkos { + static int rocm_space_atomic_locks[ROCM_SPACE_ATOMIC_MASK+1]; + static int rocm_space_scratch_locks[ROCM_CONCURRENCY]; + static int rocm_space_threadid_locks[ROCM_CONCURRENCY]; +namespace Impl { +// TODO: mimic cuda implemtation, add dgpu capability + + void init_rocm_atomic_lock_array() { + static int is_initialized = 0; + if(!is_initialized) + { + for(int i = 0; i < ROCM_SPACE_ATOMIC_MASK+1; i++) + rocm_space_atomic_locks[i] = 0; + is_initialized = 1; + } + } + + void init_rocm_scratch_lock_array() { + static int is_initialized = 0; + if(!is_initialized) + { + for(int i = 0; i < ROCM_CONCURRENCY; i++) + rocm_space_scratch_locks[i] = 0; + is_initialized = 1; + } + } + + void init_rocm_threadid_lock_array() { + static int is_initialized = 0; + if(!is_initialized) + { + for(int i = 0; i < ROCM_CONCURRENCY; i++) + rocm_space_threadid_locks[i] = 0; + is_initialized = 1; + } + } + + void init_lock_arrays_rocm_space() { + init_rocm_atomic_lock_array(); +// init_rocm_scratch_lock_array(); +// init_rocm_threadid_lock_array(); + } +} + +} // namespace Kokkos +#if 0 +namespace Kokkos { +namespace Impl { +KOKKOS_INLINE_FUNCTION +bool lock_address_rocm_space(void* ptr) { +#if 0 +return(Kokkos::Impl::lock_address_host_space(ptr)); +#else + size_t offset = size_t(ptr); + offset = offset >> 2; + offset = offset & ROCM_SPACE_ATOMIC_MASK; + return (0 == hc::atomic_compare_exchange(&rocm_space_atomic_locks[offset],0,1)); +#endif +} + +KOKKOS_INLINE_FUNCTION +void unlock_address_rocm_space(void* ptr) { +#if 0 +Kokkos::Impl::unlock_address_host_space(ptr) ; +#else + size_t offset = size_t(ptr); + offset = offset >> 2; + offset = offset & ROCM_SPACE_ATOMIC_MASK; + hc::atomic_exchange( &rocm_space_atomic_locks[ offset ], 0); +#endif +} + +} +} // namespace Kokkos +#endif + +#endif /* #ifndef KOKKOS_ROCMEXEC_HPP */ diff --git a/lib/kokkos/core/src/ROCm/Kokkos_ROCm_Exec.hpp b/lib/kokkos/core/src/ROCm/Kokkos_ROCm_Exec.hpp new file mode 100644 index 0000000000..48a27eb11d --- /dev/null +++ b/lib/kokkos/core/src/ROCm/Kokkos_ROCm_Exec.hpp @@ -0,0 +1,137 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ +#ifndef KOKKOS_ROCMEXEC_HPP +#define KOKKOS_ROCMEXEC_HPP + +#include +#include + +#if defined(__HCC_ACCELERATOR__) +#define printf(...) +#endif + +namespace Kokkos { +namespace Impl { +struct ROCmTraits { +// TODO: determine if needed + enum { WavefrontSize = 64 /* 64 */ }; + enum { WorkgroupSize = 64 /* 64 */ }; + enum { WavefrontIndexMask = 0x001f /* Mask for warpindex */ }; + enum { WavefrontIndexShift = 5 /* WarpSize == 1 << WarpShift */ }; + + enum { SharedMemoryBanks = 32 /* Compute device 2.0 */ }; + enum { SharedMemoryCapacity = 0x0C000 /* 48k shared / 16k L1 Cache */ }; + enum { SharedMemoryUsage = 0x04000 /* 16k shared / 48k L1 Cache */ }; + + enum { UpperBoundExtentCount = 65535 /* Hard upper bound */ }; +#if 0 + KOKKOS_INLINE_FUNCTION static + ROCmSpace::size_type wavefront_count( ROCmSpace::size_type i ) + { return ( i + WavefrontIndexMask ) >> WavefrontIndexShift ; } + + KOKKOS_INLINE_FUNCTION static + ROCmSpace::size_type wavefront_align( ROCmSpace::size_type i ) + { + enum { Mask = ~ROCmSpace::size_type( WavefrontIndexMask ) }; + return ( i + WavefrontIndexMask ) & Mask ; + } +#endif +}; +size_t rocm_internal_cu_count(); +size_t rocm_internal_maximum_workgroup_count(); + +size_t * rocm_internal_scratch_flags( const size_t size ); +size_t * rocm_internal_scratch_space( const size_t size ); + +} +} // namespace Kokkos +#define ROCM_SPACE_ATOMIC_MASK 0x1FFFF +#define ROCM_SPACE_ATOMIC_XOR_MASK 0x15A39 +//int rocm_space_atomic_locks[ROCM_SPACE_ATOMIC_MASK+1]; +extern int + *rocm_space_atomic_locks; + +namespace Kokkos { +namespace Impl { + void init_lock_arrays_rocm_space(); + + void* rocm_resize_scratch_space(size_t bytes, bool force_shrink = false); + +// TODO: determine if needed +KOKKOS_INLINE_FUNCTION +bool lock_address_rocm_space(void* ptr) { +#if 0 +return(Kokkos::Impl::lock_address_host_space(ptr)); +#else + size_t offset = size_t(ptr); + offset = offset >> 2; + offset = offset & ROCM_SPACE_ATOMIC_MASK; + return (0 == hc::atomic_compare_exchange(&rocm_space_atomic_locks[offset],0,1)); +#endif +} +KOKKOS_INLINE_FUNCTION +void unlock_address_rocm_space(void* ptr) { +#if 0 +Kokkos::Impl::unlock_address_host_space(ptr) ; +#else + size_t offset = size_t(ptr); + offset = offset >> 2; + offset = offset & ROCM_SPACE_ATOMIC_MASK; + hc::atomic_exchange( &rocm_space_atomic_locks[ offset ], 0); +#endif +} + +} +} // namespace Kokkos + +namespace Kokkos { +namespace Impl { +//extern +//KOKKOS_INLINE_FUNCTION +//void init_lock_arrays_rocm_space(); + + +} +} // namespace Kokkos + +#endif /* #ifndef KOKKOS_ROCMEXEC_HPP */ diff --git a/lib/kokkos/core/src/ROCm/Kokkos_ROCm_Impl.cpp b/lib/kokkos/core/src/ROCm/Kokkos_ROCm_Impl.cpp new file mode 100644 index 0000000000..1322391d92 --- /dev/null +++ b/lib/kokkos/core/src/ROCm/Kokkos_ROCm_Impl.cpp @@ -0,0 +1,753 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +/*--------------------------------------------------------------------------*/ +/* Kokkos interfaces */ + +#include + +/* only compile this file if ROCM is enabled for Kokkos */ +#ifdef KOKKOS_ENABLE_ROCM + +//#include +#include +#include +#include + +/*--------------------------------------------------------------------------*/ +/* Standard 'C' libraries */ +#include + +/* Standard 'C++' libraries */ +#include +#include +#include +#include + + + +//KOKKOS_INLINE_FUNCTION +// Kokkos::Impl::ROCmLockArraysStruct kokkos_impl_rocm_lock_arrays ; + + +/*--------------------------------------------------------------------------*/ +namespace Kokkos { +namespace Impl { + +#if 0 +namespace { +__global__ +void query_rocm_kernel_arch( int * d_arch ) +{ +#if defined( __HCC_ACCELERATOR__ ) + *d_arch = OCM_ARCH__ ; +#else + *d_arch = 0 ; +#endif +} + +/** Query what compute capability is actually launched to the device: */ +int rocm_kernel_arch() +{ + int * d_arch = 0 ; + rocmMalloc( (void **) & d_arch , sizeof(int) ); + query_rocm_kernel_arch<<<1,1>>>( d_arch ); + int arch = 0 ; + rocmMemcpy( & arch , d_arch , sizeof(int) , rocmMemcpyDefault ); + rocmFree( d_arch ); + return arch ; +} +bool rocm_launch_blocking() +{ + const char * env = getenv("ROCM_LAUNCH_BLOCKING"); + + if (env == 0) return false; + + return atoi(env); +} + +} +#endif + +// true device memory allocation, not visible from host +void * rocm_device_allocate(int size) +{ + void * ptr; + hc::accelerator acc; + ptr = hc::am_alloc(size,acc,0); + return ptr; +} + +// host pinned allocation +// flag = 1, non-coherent, host resident, but with gpu address space pointer +// flag = 2, coherent, host resident, but with host address space pointer +void * rocm_hostpinned_allocate(int size) +{ + void * ptr; + hc::accelerator acc; + ptr = hc::am_alloc(size,acc,2); + return ptr; +} +// same free used by all rocm memory allocations +void rocm_device_free(void * ptr) +{ + hc::am_free(ptr); +} + + +KOKKOS_INLINE_FUNCTION +void rocm_device_synchronize() +{ + hc::accelerator_view av = hc::accelerator().get_default_view(); + hc::completion_future fut = av.create_marker(); + fut.wait(); +} + +void rocm_internal_error_throw( const char * name, const char * file, const int line ) +{ +#if 0 + std::ostringstream out ; + out << name << " error( " << rocmGetErrorName(e) << "): " << rocmGetErrorString(e); + if (file) { + out << " " << file << ":" << line; + } + throw_runtime_exception( out.str() ); +#endif +} + +//---------------------------------------------------------------------------- +// Some significant rocm device properties: +// +// rocmDeviceProp::name : Text label for device +// rocmDeviceProp::major : Device major number +// rocmDeviceProp::minor : Device minor number +// rocmDeviceProp::workgroupSize : number of threads per workgroup +// rocmDeviceProp::multiProcessorCount : number of multiprocessors +// rocmDeviceProp::sharedMemPerBlock : capacity of shared memory per wavefront +// rocmDeviceProp::totalConstMem : capacity of constant memory +// rocmDeviceProp::totalGlobalMem : capacity of global memory +// rocmDeviceProp::maxGridSize[3] : maximum grid size + +// +// +// the data we have available from a ROCm accelerator +// std::wstring get_device_path() +// std::wstring get_description() +// unsigned int get_version() +// bool get_has_display() +// size_t get_dedicated_memory() +// bool get_supports_double_precision() +// bool get_supports_limited_double_precision() +// bool get_is_debug() +// bool get_supports_cpu_shared_memory() +// size_t get_max_tile_static_size() +// unsigned int get_cu_count() +// bool has_cpu_accessible_am() +struct rocmDeviceProp { + char name[256]; + char description[256]; + unsigned int version; + int device_type; + int device_ordinal; + int major; + int minor; + size_t totalGlobalMem; + size_t sharedMemPerWavefront; + int WavefrontSize; + int WorkgroupSize; + int MaxTileCount; + int maxThreadsPerWorkgroup; + int multiProcessorCount; + int canMapHostMemory; + bool APU; +}; + + + +void rocmGetDeviceProperties(struct rocmDeviceProp* devProp, int device) +{ + std::wstring s; + int i,n; + hc::accelerator acc; + std::vector accv = acc.get_all() ; + + hc::accelerator a = accv[device]; + + s=a.get_device_path(); + i = 0; + for(wchar_t c: s) + if((n=std::wctomb(&devProp->name[i],c))>0) + i+=n; + + /* assume a CPU */ + devProp->version = a.get_version(); + devProp->major = a.get_version()>>16; // for CPU, these are meaningless + devProp->minor = a.get_version()&0xff; + devProp->device_ordinal = 0; + + /* is this an AMD graphics card */ + if((devProp->name[0]=='g') && (devProp->name[1]=='f') + && (devProp->name[2]=='x')) { + /* for AMD cards, the name has the format gfxMmmO */ + + devProp->device_type = ((devProp->name[3]-0x30)<<16) + + ((devProp->name[4]-0x30)<<8) + + (devProp->name[5]-0x30); + devProp->device_ordinal = devProp->name[6]-0x30; + devProp->major = devProp->name[3]-0x30; + devProp->minor = devProp->name[5]-0x30; + } + + s=a.get_description(); + i = 0; + for(wchar_t c: s) + if((n=std::wctomb(&devProp->description[i],c))>0) + i+=n; + devProp->totalGlobalMem = a.get_dedicated_memory(); + devProp->sharedMemPerWavefront = a.get_max_tile_static_size(); + devProp->WavefrontSize = 64; + devProp->WorkgroupSize = 256; // preferred + devProp->MaxTileCount = 409600; // as defined in /opt/rocm/hcc-lc/include/hsa_new.h + devProp->maxThreadsPerWorkgroup = 1024; + devProp->multiProcessorCount = a.get_cu_count(); + devProp->canMapHostMemory = a.get_supports_cpu_shared_memory(); +// Kaveri has 64KB L2 per CU, 16KB L1, 64KB Vector Regs/SIMD, or 128 regs/thread +// GCN has 64KB LDS per CU + +//Kaveri APU is 7:0:0 +//Carrizo APU is 8:0:1 + devProp->APU = (((devProp->major==7)&&(devProp->minor==0))| + ((devProp->major==8)&&(devProp->minor==1)))?true:false; +} + +namespace { + + + +class ROCmInternalDevices { +public: + enum { MAXIMUM_DEVICE_COUNT = 64 }; + struct rocmDeviceProp m_rocmProp[ MAXIMUM_DEVICE_COUNT ] ; + int m_rocmDevCount ; + + ROCmInternalDevices(); + + static const ROCmInternalDevices & singleton(); +}; + +ROCmInternalDevices::ROCmInternalDevices() +{ + hc::accelerator acc; + std::vector accv = acc.get_all() ; + m_rocmDevCount = accv.size(); + + if(m_rocmDevCount > MAXIMUM_DEVICE_COUNT) { + Kokkos::abort("Sorry, you have more GPUs per node than we thought anybody would ever have. Please report this to github.com/kokkos/kokkos."); + } + for ( int i = 0 ; i < m_rocmDevCount ; ++i ) { + rocmGetDeviceProperties( m_rocmProp + i , i ); + } +} + +const ROCmInternalDevices & ROCmInternalDevices::singleton() +{ + static ROCmInternalDevices* self = nullptr; + if (!self) { + self = new ROCmInternalDevices(); + } + return *self; + +} + +} + +//---------------------------------------------------------------------------- + +class ROCmInternal { +private: + + ROCmInternal( const ROCmInternal & ); + ROCmInternal & operator = ( const ROCmInternal & ); + + +public: + + typedef Kokkos::Experimental::ROCm::size_type size_type ; + + int m_rocmDev ; + int m_rocmArch ; + unsigned m_multiProcCount ; + unsigned m_maxWorkgroup ; + unsigned m_maxSharedWords ; + size_type m_scratchSpaceCount ; + size_type m_scratchFlagsCount ; + size_type * m_scratchSpace ; + size_type * m_scratchFlags ; + + static int was_finalized; + + static ROCmInternal & singleton(); + + int verify_is_initialized( const char * const label ) const ; + + int is_initialized() const + { return 0 != m_scratchSpace && 0 != m_scratchFlags ; } + + void initialize( int rocm_device_id ); + void finalize(); + + void print_configuration( std::ostream & ) const ; + + + ~ROCmInternal(); + + ROCmInternal() + : m_rocmDev( -1 ) + , m_rocmArch( -1 ) + , m_multiProcCount( 0 ) + , m_maxWorkgroup( 0 ) + , m_maxSharedWords( 0 ) + , m_scratchSpaceCount( 0 ) + , m_scratchFlagsCount( 0 ) + , m_scratchSpace( 0 ) + , m_scratchFlags( 0 ) + {} + + size_type * scratch_space( const size_type size ); + size_type * scratch_flags( const size_type size ); +}; + +int ROCmInternal::was_finalized = 0; +//---------------------------------------------------------------------------- + + +void ROCmInternal::print_configuration( std::ostream & s ) const +{ + const ROCmInternalDevices & dev_info = ROCmInternalDevices::singleton(); + +#if defined( KOKKOS_ENABLE_ROCM ) + s << "macro KOKKOS_ENABLE_ROCM : defined" << std::endl ; +#endif +#if defined( __hcc_version__ ) + s << "macro __hcc_version__ = " << __hcc_version__ + << std::endl ; +#endif + + for ( int i = 0 ; i < dev_info.m_rocmDevCount ; ++i ) { + s << "Kokkos::Experimental::ROCm[ " << i << " ] " + << dev_info.m_rocmProp[i].name + << " version " << (dev_info.m_rocmProp[i].major) << "." << dev_info.m_rocmProp[i].minor + << ", Total Global Memory: " << human_memory_size(dev_info.m_rocmProp[i].totalGlobalMem) + << ", Shared Memory per Wavefront: " << human_memory_size(dev_info.m_rocmProp[i].sharedMemPerWavefront); + if ( m_rocmDev == i ) s << " : Selected" ; + s << std::endl ; + } +} + +//---------------------------------------------------------------------------- + +ROCmInternal::~ROCmInternal() +{ + if ( m_scratchSpace || + m_scratchFlags ) { + std::cerr << "Kokkos::Experimental::ROCm ERROR: Failed to call Kokkos::Experimental::ROCm::finalize()" + << std::endl ; + std::cerr.flush(); + } + + m_rocmDev = -1 ; + m_rocmArch = -1 ; + m_multiProcCount = 0 ; + m_maxWorkgroup = 0 ; + m_maxSharedWords = 0 ; + m_scratchSpaceCount = 0 ; + m_scratchFlagsCount = 0 ; + m_scratchSpace = 0 ; + m_scratchFlags = 0 ; +} + +int ROCmInternal::verify_is_initialized( const char * const label ) const +{ + if ( m_rocmDev < 0 ) { + std::cerr << "Kokkos::Experimental::ROCm::" << label << " : ERROR device not initialized" << std::endl ; + } + return 0 <= m_rocmDev ; +} + +ROCmInternal & ROCmInternal::singleton() +{ + static ROCmInternal* self = nullptr ; + if (!self) { + self = new ROCmInternal(); + } + return *self ; + +} + +void ROCmInternal::initialize( int rocm_device_id ) +{ + if ( was_finalized ) Kokkos::abort("Calling ROCm::initialize after ROCm::finalize is illegal\n"); + + if ( is_initialized() ) return; + + enum { WordSize = sizeof(size_type) }; + + if ( ! HostSpace::execution_space::is_initialized() ) { + const std::string msg("ROCm::initialize ERROR : HostSpace::execution_space is not initialized"); + throw_runtime_exception( msg ); + } + + const ROCmInternalDevices & dev_info = ROCmInternalDevices::singleton(); + + const bool ok_init = 0 == m_scratchSpace || 0 == m_scratchFlags ; + + const bool ok_id = 1 <= rocm_device_id && + rocm_device_id < dev_info.m_rocmDevCount ; + + // Need at least a GPU device + + const bool ok_dev = ok_id && + ( 1 <= dev_info.m_rocmProp[ rocm_device_id ].major && + 0 <= dev_info.m_rocmProp[ rocm_device_id ].minor ); + if ( ok_init && ok_dev ) { + + const struct rocmDeviceProp & rocmProp = + dev_info.m_rocmProp[ rocm_device_id ]; + + m_rocmDev = rocm_device_id ; + +// rocmSetDevice( m_rocmDev ) ); + Kokkos::Impl::rocm_device_synchronize(); + +/* + // Query what compute capability architecture a kernel executes: + m_rocmArch = rocm_kernel_arch(); + if ( m_rocmArch != rocmProp.major * 100 + rocmProp.minor * 10 ) { + std::cerr << "Kokkos::Experimental::ROCm::initialize WARNING: running kernels compiled for compute capability " + << ( m_rocmArch / 100 ) << "." << ( ( m_rocmArch % 100 ) / 10 ) + << " on device with compute capability " + << rocmProp.major << "." << rocmProp.minor + << " , this will likely reduce potential performance." + << std::endl ; + } +*/ + // number of multiprocessors + + m_multiProcCount = rocmProp.multiProcessorCount ; + + //---------------------------------- + // Maximum number of wavefronts, + // at most one workgroup per thread in a workgroup for reduction. + + + m_maxSharedWords = rocmProp.sharedMemPerWavefront/ WordSize ; + + //---------------------------------- + // Maximum number of Workgroups: + + m_maxWorkgroup = 5*rocmProp.multiProcessorCount; //TODO: confirm usage and value + + //---------------------------------- + // Multiblock reduction uses scratch flags for counters + // and scratch space for partial reduction values. + // Allocate some initial space. This will grow as needed. + + { + const unsigned reduce_block_count = m_maxWorkgroup * Impl::ROCmTraits::WorkgroupSize ; + + (void) scratch_flags( reduce_block_count * 2 * sizeof(size_type) ); + (void) scratch_space( reduce_block_count * 16 * sizeof(size_type) ); + } + //---------------------------------- + + } + else { + + std::ostringstream msg ; + msg << "Kokkos::Experimental::ROCm::initialize(" << rocm_device_id << ") FAILED" ; + + if ( ! ok_init ) { + msg << " : Already initialized" ; + } + if ( ! ok_id ) { + msg << " : Device identifier out of range " + << "[0.." << (dev_info.m_rocmDevCount-1) << "]" ; + } + else if ( ! ok_dev ) { + msg << " : Device " ; + msg << dev_info.m_rocmProp[ rocm_device_id ].major ; + msg << "." ; + msg << dev_info.m_rocmProp[ rocm_device_id ].minor ; + msg << " Need at least a GPU" ; + msg << std::endl; + } + Kokkos::Impl::throw_runtime_exception( msg.str() ); + } + + + // Init the array for used for arbitrarily sized atomics + Kokkos::Impl::init_lock_arrays_rocm_space(); + +// Kokkos::Impl::ROCmLockArraysStruct locks; +// locks.atomic = atomic_lock_array_rocm_space_ptr(false); +// locks.scratch = scratch_lock_array_rocm_space_ptr(false); +// locks.threadid = threadid_lock_array_rocm_space_ptr(false); +// rocmMemcpyToSymbol( kokkos_impl_rocm_lock_arrays , & locks , sizeof(ROCmLockArraysStruct) ); +} + +//---------------------------------------------------------------------------- + +typedef Kokkos::Experimental::ROCm::size_type ScratchGrain[ Impl::ROCmTraits::WorkgroupSize ] ; +enum { sizeScratchGrain = sizeof(ScratchGrain) }; + +void rocmMemset( Kokkos::Experimental::ROCm::size_type * ptr , Kokkos::Experimental::ROCm::size_type value , Kokkos::Experimental::ROCm::size_type size) +{ +char * mptr = (char * ) ptr; +#if 0 + parallel_for_each(hc::extent<1>(size), + [=, &ptr] + (hc::index<1> idx) __HC__ + { + int i = idx[0]; + ptr[i] = value; + }).wait(); +#else + for (int i= 0; i Record ; + + Record * const r = Record::allocate( Kokkos::HostSpace() + , "InternalScratchFlags" + , ( sizeScratchGrain * m_scratchFlagsCount ) ); + + Record::increment( r ); + + m_scratchFlags = reinterpret_cast( r->data() ); + + rocmMemset( m_scratchFlags , 0 , m_scratchFlagsCount * sizeScratchGrain ); + } + + return m_scratchFlags ; +} + +Kokkos::Experimental::ROCm::size_type * +ROCmInternal::scratch_space( const Kokkos::Experimental::ROCm::size_type size ) +{ + if ( verify_is_initialized("scratch_space") && m_scratchSpaceCount * sizeScratchGrain < size ) { + + m_scratchSpaceCount = ( size + sizeScratchGrain - 1 ) / sizeScratchGrain ; + + typedef Kokkos::Experimental::Impl::SharedAllocationRecord< Kokkos::HostSpace , void > Record ; + + Record * const r = Record::allocate( Kokkos::HostSpace() + , "InternalScratchSpace" + , ( sizeScratchGrain * m_scratchSpaceCount ) ); + + Record::increment( r ); + + m_scratchSpace = reinterpret_cast( r->data() ); + } + + return m_scratchSpace ; +} + +//---------------------------------------------------------------------------- + +void ROCmInternal::finalize() +{ + was_finalized = 1; + if ( 0 != m_scratchSpace || 0 != m_scratchFlags ) { + +// atomic_lock_array_rocm_space_ptr(false); +// scratch_lock_array_rocm_space_ptr(false); +// threadid_lock_array_rocm_space_ptr(false); + + typedef Kokkos::Experimental::Impl::SharedAllocationRecord< HostSpace > RecordROCm ; + typedef Kokkos::Experimental::Impl::SharedAllocationRecord< Kokkos::Experimental::ROCmHostPinnedSpace > RecordHost ; + + RecordROCm::decrement( RecordROCm::get_record( m_scratchFlags ) ); + RecordROCm::decrement( RecordROCm::get_record( m_scratchSpace ) ); + + m_rocmDev = -1 ; + m_multiProcCount = 0 ; + m_maxWorkgroup = 0 ; + m_maxSharedWords = 0 ; + m_scratchSpaceCount = 0 ; + m_scratchFlagsCount = 0 ; + m_scratchSpace = 0 ; + m_scratchFlags = 0 ; + } +} + +//---------------------------------------------------------------------------- + +Kokkos::Experimental::ROCm::size_type rocm_internal_cu_count() +{ return ROCmInternal::singleton().m_multiProcCount ; } + +Kokkos::Experimental::ROCm::size_type rocm_internal_maximum_extent_size() +{ return ROCmInternal::singleton().m_maxWorkgroup ; } + +Kokkos::Experimental::ROCm::size_type rocm_internal_maximum_shared_words() +{ return ROCmInternal::singleton().m_maxSharedWords ; } + +Kokkos::Experimental::ROCm::size_type * rocm_internal_scratch_space( const Kokkos::Experimental::ROCm::size_type size ) +{ return ROCmInternal::singleton().scratch_space( size ); } + +Kokkos::Experimental::ROCm::size_type * rocm_internal_scratch_flags( const Kokkos::Experimental::ROCm::size_type size ) +{ return ROCmInternal::singleton().scratch_flags( size ); } + + + +} // namespace Impl +} // namespace Kokkos + +//---------------------------------------------------------------------------- + +namespace Kokkos { +namespace Experimental { + +//ROCm::size_type ROCm::detect_device_count() +//{ return Impl::ROCmInternalDevices::singleton().m_rocmDevCount ; } + +int ROCm::concurrency() { +#if defined(KOKKOS_ARCH_KAVERI) + return 8*64*40; // 20480 kaveri +#else + return 32*8*40; // 81920 fiji and hawaii +#endif +} +int ROCm::is_initialized() +{ return Kokkos::Impl::ROCmInternal::singleton().is_initialized(); } + +void ROCm::initialize( const ROCm::SelectDevice config ) +{ + Kokkos::Impl::ROCmInternal::singleton().initialize( config.rocm_device_id ); + + #if defined(KOKKOS_ENABLE_PROFILING) + Kokkos::Profiling::initialize(); + #endif +} + +#if 0 +std::vector +ROCm::detect_device_arch() +{ + const Impl::ROCmInternalDevices & s = Impl::ROCmInternalDevices::singleton(); + + std::vector output( s.m_rocmDevCount ); + + for ( int i = 0 ; i < s.m_rocmDevCount ; ++i ) { + output[i] = s.m_rocmProp[i].major * 100 + s.m_rocmProp[i].minor ; + } + + return output ; +} + +ROCm::size_type ROCm::device_arch() +{ + return 1 ; +} +#endif + +void ROCm::finalize() +{ + Kokkos::Impl::ROCmInternal::singleton().finalize(); + + #if defined(KOKKOS_ENABLE_PROFILING) + Kokkos::Profiling::finalize(); + #endif +} + +ROCm::ROCm() + : m_device( Kokkos::Impl::ROCmInternal::singleton().m_rocmDev ) +{ + Kokkos::Impl::ROCmInternal::singleton().verify_is_initialized( "ROCm instance constructor" ); +} + +bool ROCm::isAPU(int device) { + const Kokkos::Impl::ROCmInternalDevices & dev_info = + Kokkos::Impl::ROCmInternalDevices::singleton(); + return (dev_info.m_rocmProp[device].APU); +} + +bool ROCm::isAPU() { + return ROCm::isAPU(rocm_device()); +} + +//ROCm::ROCm( const int instance_id ) +// : m_device( Impl::ROCmInternal::singleton().m_rocmDev ) +//{} + +void ROCm::print_configuration( std::ostream & s , const bool ) +{ Kokkos::Impl::ROCmInternal::singleton().print_configuration( s ); } + +bool ROCm::sleep() { return false ; } + +bool ROCm::wake() { return true ; } + +void ROCm::fence() +{ + Kokkos::Impl::rocm_device_synchronize(); +} + +const char* ROCm::name() { return "ROCm"; } + +} // namespace Experimental +} // namespace Kokkos + +#endif // KOKKOS_ENABLE_ROCM +//---------------------------------------------------------------------------- + diff --git a/lib/kokkos/core/src/ROCm/Kokkos_ROCm_Invoke.hpp b/lib/kokkos/core/src/ROCm/Kokkos_ROCm_Invoke.hpp new file mode 100644 index 0000000000..481e7df3a4 --- /dev/null +++ b/lib/kokkos/core/src/ROCm/Kokkos_ROCm_Invoke.hpp @@ -0,0 +1,138 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include +#include + +#if !defined( KOKKOS_ROCM_INVOKE_H ) +#define KOKKOS_ROCM_INVOKE_H + +namespace Kokkos { +namespace Impl { + +template()), int>::type = 0> +KOKKOS_INLINE_FUNCTION void rocm_invoke(F&& f, Ts&&... xs) +{ + f(Tag(), static_cast(xs)...); +} + +template()), int>::type = 0> +KOKKOS_INLINE_FUNCTION void rocm_invoke(F&& f, Ts&&... xs) +{ + f(static_cast(xs)...); +} + + +template +struct rocm_invoke_fn +{ + F* f; + rocm_invoke_fn(F& f_) : f(&f_) + {} + + template + KOKKOS_INLINE_FUNCTION void operator()(Ts&&... xs) const + { + rocm_invoke(*f, static_cast(xs)...); + } +}; + +template +KOKKOS_INLINE_FUNCTION rocm_invoke_fn make_rocm_invoke_fn(F& f) +{ + return {f}; +} + +template +KOKKOS_INLINE_FUNCTION T& rocm_unwrap(T& x) +{ + return x; +} + +template +KOKKOS_INLINE_FUNCTION T& rocm_unwrap(std::reference_wrapper x) +{ + return x; +} + +template +struct rocm_capture_fn +{ + F f; + T data; + + KOKKOS_INLINE_FUNCTION rocm_capture_fn(F f_, T x) + : f(f_), data(x) + {} + + template + KOKKOS_INLINE_FUNCTION void operator()(Ts&&... xs) const + { + f(rocm_unwrap(data), static_cast(xs)...); + } +}; + +template +KOKKOS_INLINE_FUNCTION rocm_capture_fn rocm_capture(F f, T x) +{ + return {f, x}; +} + +template +KOKKOS_INLINE_FUNCTION auto rocm_capture(F f, T x, U y, Ts... xs) -> decltype(rocm_capture(rocm_capture(f, x), y, xs...)) +{ + return rocm_capture(rocm_capture(f, x), y, xs...); +} + +struct rocm_apply_op +{ + template + KOKKOS_INLINE_FUNCTION void operator()(F&& f, Ts&&... xs) const + { + f(static_cast(xs)...); + } +}; + +}} + +#endif diff --git a/lib/kokkos/core/src/ROCm/Kokkos_ROCm_Join.hpp b/lib/kokkos/core/src/ROCm/Kokkos_ROCm_Join.hpp new file mode 100644 index 0000000000..d3d150703e --- /dev/null +++ b/lib/kokkos/core/src/ROCm/Kokkos_ROCm_Join.hpp @@ -0,0 +1,72 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#if !defined( KOKKOS_ROCM_JOIN_H ) +#define KOKKOS_ROCM_JOIN_H + +namespace Kokkos { +namespace Impl { + + +// Adaptor to use ValueJoin with standard algorithms +template +struct join_operator +{ + const F* fp; + template + T operator()(T x, const U& y) const + { + Joiner::join(*fp, &x, &y); + return x; + } +}; + +template +join_operator make_join_operator(const F& f) +{ + return join_operator{&f}; +} + +}} + +#endif diff --git a/lib/kokkos/core/src/ROCm/Kokkos_ROCm_Parallel.hpp b/lib/kokkos/core/src/ROCm/Kokkos_ROCm_Parallel.hpp new file mode 100644 index 0000000000..14ab52a1c2 --- /dev/null +++ b/lib/kokkos/core/src/ROCm/Kokkos_ROCm_Parallel.hpp @@ -0,0 +1,1265 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include +#include +#include +#include +#include + + +namespace Kokkos { +namespace Impl { + +struct ROCmTeamMember ; + +template< class ... Properties > +class TeamPolicyInternal< Kokkos::Experimental::ROCm, Properties ... >: public PolicyTraits { +private: + int m_league_size ; + int m_team_size ; + int m_vector_length ; + int m_team_scratch_size[2] ; + int m_thread_scratch_size[2] ; + int m_chunk_size ; + + +public: + + using execution_policy = TeamPolicyInternal ; + using execution_space = Kokkos::Experimental::ROCm ; + typedef PolicyTraits traits; + + TeamPolicyInternal& operator = (const TeamPolicyInternal& p) { + m_league_size = p.m_league_size; + m_team_size = p.m_team_size; + m_vector_length = p.m_vector_length; + m_team_scratch_size[0] = p.m_team_scratch_size[0]; + m_team_scratch_size[1] = p.m_team_scratch_size[1]; + m_thread_scratch_size[0] = p.m_thread_scratch_size[0]; + m_thread_scratch_size[1] = p.m_thread_scratch_size[1]; + m_chunk_size = p.m_chunk_size; + return *this; + } + + TeamPolicyInternal() + : m_league_size( 0 ) + , m_team_size( 0 ) + , m_vector_length( 0 ) + , m_team_scratch_size {0,0} + , m_thread_scratch_size {0,0} + , m_chunk_size ( 64 ) + {} + + TeamPolicyInternal( const int arg_league_size + , const int arg_team_size ) + : m_league_size( arg_league_size ), + m_team_size( arg_team_size ) + , m_team_scratch_size {0,0} + , m_thread_scratch_size {0,0} + , m_chunk_size ( 64 ) + {} + + TeamPolicyInternal( const int arg_league_size + , const int arg_team_size + , const int vector_length_request=1) + : m_league_size( arg_league_size ), + m_team_size( arg_team_size ), + m_vector_length (vector_length_request) + , m_team_scratch_size {0,0} + , m_thread_scratch_size {0,0} + , m_chunk_size ( 64 ) + {} + + TeamPolicyInternal( const int arg_league_size + , const Kokkos::AUTO_t ) + : m_league_size( arg_league_size ), m_team_size( -1 ) + , m_team_scratch_size {0,0} + , m_thread_scratch_size {0,0} + , m_chunk_size ( 64 ) + {} + + TeamPolicyInternal( const int arg_league_size + , const Kokkos::AUTO_t + , const int vector_length_request) + : m_league_size( arg_league_size ), + m_team_size( -1 ), + m_vector_length (vector_length_request) + , m_team_scratch_size {0,0} + , m_thread_scratch_size {0,0} + , m_chunk_size ( 64 ) + {} + + inline int chunk_size() const { return m_chunk_size ; } + + /** \brief set chunk_size to a discrete value*/ + KOKKOS_INLINE_FUNCTION TeamPolicyInternal set_chunk_size(typename traits::index_type chunk_size_) const { + TeamPolicyInternal p = *this; + p.m_chunk_size = chunk_size_; + return p; + } + + /** \brief set per team scratch size for a specific level of the scratch hierarchy */ + inline TeamPolicyInternal set_scratch_size(const int& level, const PerTeamValue& per_team) const { + TeamPolicyInternal p = *this; + p.m_team_scratch_size[level] = per_team.value; + return p; + }; + + /** \brief set per thread scratch size for a specific level of the scratch hierarchy */ + inline TeamPolicyInternal set_scratch_size(const int& level, const PerThreadValue& per_thread) const { + TeamPolicyInternal p = *this; + p.m_thread_scratch_size[level] = per_thread.value; + return p; + }; + + /** \brief set per thread and per team scratch size for a specific level of the scratch hierarchy */ + inline TeamPolicyInternal set_scratch_size(const int& level, const PerTeamValue& per_team, const PerThreadValue& per_thread) const { + TeamPolicyInternal p = *this; + p.m_team_scratch_size[level] = per_team.value; + p.m_thread_scratch_size[level] = per_thread.value; + return p; + }; + +// TODO: evaluate proper team_size_max requirements + template< class Functor_Type> + KOKKOS_INLINE_FUNCTION static + int team_size_max( const Functor_Type & functor) + { + typedef typename Kokkos::Impl::FunctorValueTraits::value_type value_type; + return team_size_recommended(functor); + // return std::min(Kokkos::Impl::get_max_tile_size() / sizeof(value_type), Kokkos::Impl::get_max_tile_thread()); + } + + template< class Functor_Type> + KOKKOS_INLINE_FUNCTION static int team_size_recommended(const Functor_Type & functor) + { return Kokkos::Impl::get_tile_size::value_type>(); } + + template< class Functor_Type > + KOKKOS_INLINE_FUNCTION static int team_size_recommended(const Functor_Type &functor, const int vector_length) + { + int max = team_size_recommended( functor )/vector_length; + if(max < 1) max = 1; + return(max); + } + + template + KOKKOS_INLINE_FUNCTION int team_size(const F& f) const { return (m_team_size > 0) ? m_team_size : team_size_recommended(f); } + KOKKOS_INLINE_FUNCTION int team_size() const { return (m_team_size > 0) ? m_team_size : Impl::get_max_tile_thread(); ; } + KOKKOS_INLINE_FUNCTION int league_size() const { return m_league_size ; } + + + inline int vector_length() const { return m_vector_length ; } + inline int scratch_size(int level, int team_size_ = -1) const { + if(team_size_<0) team_size_ = m_team_size; + return m_team_scratch_size[level] + team_size_*m_thread_scratch_size[level]; + } + inline size_t team_scratch_size(int level) const { + return m_team_scratch_size[level]; + } + inline size_t thread_scratch_size(int level) const { + return m_thread_scratch_size[level]; + } + + typedef Impl::ROCmTeamMember member_type; +}; + + struct ROCmTeamMember { + typedef Kokkos::Experimental::ROCm execution_space ; + typedef Kokkos::ScratchMemorySpace scratch_memory_space ; + + KOKKOS_INLINE_FUNCTION + const scratch_memory_space & team_shmem() const + { return m_team_shared.set_team_thread_mode(0,1,0); } + KOKKOS_INLINE_FUNCTION + const execution_space::scratch_memory_space & team_scratch(const int& level) const + { return m_team_shared.set_team_thread_mode(level,1,0) ; } + KOKKOS_INLINE_FUNCTION + const execution_space::scratch_memory_space & thread_scratch(const int& level) const + { return m_team_shared.set_team_thread_mode(level, + team_size(), + team_rank()) ; } + + + /* Rank of this team within the league of teams */ + KOKKOS_INLINE_FUNCTION int league_rank() const { return m_idx.tile[0]; } + /* Number of teams in the league */ + KOKKOS_INLINE_FUNCTION int league_size() const { return m_league_size; } + /* Rank of this thread within this team */ + KOKKOS_INLINE_FUNCTION int team_rank() const { return m_idx.local[0] / m_vector_length; } + /* Rank of this thread within this thread */ + KOKKOS_INLINE_FUNCTION int vector_rank() const { return m_idx.local[0] % m_vector_length; } + KOKKOS_INLINE_FUNCTION int lindex() const { return m_idx.local[0]; } + KOKKOS_INLINE_FUNCTION int gindex() const { return m_idx.global[0]; } + KOKKOS_INLINE_FUNCTION int tindex() const { return m_idx.tile[0]; } + KOKKOS_INLINE_FUNCTION int tile_dim() const { return m_idx.tile_dim[0]; } + KOKKOS_INLINE_FUNCTION int team_size() const { return m_team_size; } + KOKKOS_INLINE_FUNCTION int vector_length() const { return m_vector_length; } + + + KOKKOS_INLINE_FUNCTION + ROCmTeamMember( const hc::tiled_index< 1 > & arg_idx, int league_size_,int team_size_ ) + : m_league_size( league_size_ ) + , m_team_size( team_size_ ) + , m_team_shared( nullptr, 0 ) + , m_vector_length( 1 ) + , m_idx( arg_idx ) + {} + + KOKKOS_INLINE_FUNCTION + ROCmTeamMember( const hc::tiled_index< 1 > & arg_idx, int league_size_,int team_size_, char * shared, std::size_t shsize, std::size_t scratch_size0, char * scratch_ptr, std::size_t scratch_size1, std::size_t vector_length) + : m_league_size( league_size_ ) + , m_team_size( team_size_ ) + , m_team_shared( shared + + arg_idx.tile[0]*(shsize+scratch_size0), + (shsize+scratch_size0)*league_size_, + scratch_ptr + arg_idx.tile[0]*scratch_size1, + scratch_size1*league_size_) + , m_vector_length( vector_length ) + , m_idx( arg_idx ) + {} + + KOKKOS_INLINE_FUNCTION + void team_barrier() const { + m_idx.barrier.wait(); + } + + template + KOKKOS_INLINE_FUNCTION + void team_broadcast(const ValueType& value, const int& thread_id ) const + { + static_assert(std::is_trivially_default_constructible(), "Only trivial constructible types can be broadcasted"); + tile_static ValueType local_value; + zero_init(local_value); + if (this->team_rank() == thread_id) { + local_value = value; + } + this->team_barrier(); + value = local_value; + } +// Reduce accross a team of threads. +// +// Each thread has vector_length elements. +// This reduction is for TeamThreadRange operations, where the range +// is spread across threads. Effectively, there are vector_length +// independent reduction operations. +// This is different from a reduction across the elements of a thread, +// which reduces every vector element. + + template< class ValueType, class JoinOp > + KOKKOS_INLINE_FUNCTION + ValueType team_reduce( const ValueType & value , const JoinOp & op_in) const + { + typedef JoinLambdaAdapter JoinOpFunctor ; + const JoinOpFunctor op(op_in); + + tile_static ValueType buffer[512]; + const auto local = lindex(); + const auto team = team_rank(); + auto vector_rank = local%m_vector_length; + auto thread_base = team*m_vector_length; + + const std::size_t size = next_pow_2(m_team_size+1)/2; +#if defined(ROCM15) + buffer[local] = value; +#else + // ROCM 1.5 handles address spaces better, previous version didn't + lds_for(buffer[local], [&](ValueType& x) + { + x = value; + }); +#endif + m_idx.barrier.wait(); + + for(std::size_t s = 1; s < size; s *= 2) + { + const std::size_t index = 2 * s * team; + if (index < size) + { +#if defined(ROCM15) + op.join(buffer[vector_rank+index*m_vector_length], + buffer[vector_rank+(index+s)*m_vector_length]); +#else + lds_for(buffer[vector_rank+index*m_vector_length], [&](ValueType& x) + { + lds_for(buffer[vector_rank+(index+s)*m_vector_length], + [&](ValueType& y) + { + op.join(x, y); + }); + }); +#endif + } + m_idx.barrier.wait(); + } + + if (local == 0) + { + for(int i=size*m_vector_length; i + KOKKOS_INLINE_FUNCTION + ValueType thread_reduce( const ValueType & value , const JoinOp & op_in) const + { + typedef JoinLambdaAdapter JoinOpFunctor ; + const JoinOpFunctor op(op_in); + + const auto local = m_idx.local[0]; + tile_static ValueType buffer[512]; + const std::size_t size = m_vector_length; //vector length must be power of 2 + auto vector_rank = local%m_vector_length; + auto thread_base = team_rank()*m_vector_length; + lds_for(buffer[local], [&](ValueType& x) + { + x = value; + }); + m_idx.barrier.wait(); + for(std::size_t s = 1; s < size; s *= 2) + { + const std::size_t index = 2 * s * vector_rank; + if (index < size) + { +#if defined(ROCM15) + op.join(buffer[thread_base+index], buffer[thread_base+index+s]); +#else + + lds_for(buffer[thread_base+index], [&](ValueType& x) + { + lds_for(buffer[thread_base+index+s], [&](ValueType& y) + { + op.join(x, y); + }); + }); +#endif + } + m_idx.barrier.wait(); + } + + m_idx.barrier.wait(); + return buffer[thread_base]; + } + + /** \brief Intra-team exclusive prefix sum with team_rank() ordering + * with intra-team non-deterministic ordering accumulation. + * + * The global inter-team accumulation value will, at the end of the + * league's parallel execution, be the scan's total. + * Parallel execution ordering of the league's teams is non-deterministic. + * As such the base value for each team's scan operation is similarly + * non-deterministic. + */ + template< typename Type > + KOKKOS_INLINE_FUNCTION Type team_scan( const Type & value , Type * const global_accum = nullptr ) const + { + #if 0 + const auto local = m_idx.local[0]; + const auto last = m_team_size - 1; + const auto init = 0; + tile_static Type buffer[256]; + + if (local == last) buffer[0] = init; + else buffer[local] = value; + + m_idx.barrier.wait(); + + for(std::size_t s = 1; s < m_team_size; s *= 2) + { + if (local >= s) buffer[local] += buffer[local - s]; + m_idx.barrier.wait(); + } + + if ( global_accum ) + { + if(local == last) + { + atomic_fetch_add(global_accum, buffer[local] + value); + } + m_idx.barrier.wait(); + buffer[local] += *global_accum; + } + m_idx.barrier.wait(); + return buffer[local]; +#else + tile_static Type sarray[2][256+1]; + int lid = m_idx.local[0]; + int lp1 = lid+1; + + int toggle = 1; + int _toggle = 0; + m_idx.barrier.wait(); + + if(lid == 0) + { + sarray[1][0] = 0; + sarray[0][0] = 0; + } + sarray[1][lp1] = value; + + m_idx.barrier.wait(); + for(int stride = 1; stride < m_team_size; stride*=2) + { + if(lid >= stride) + { + sarray[_toggle][lp1] = + sarray[toggle][lp1]+sarray[toggle][lp1-stride]; + } + else + { + sarray[_toggle][lp1] = sarray[toggle][lp1]; + } + toggle = _toggle; + _toggle = 1-toggle; + m_idx.barrier.wait(); + } + + if ( global_accum ) + { + if(m_team_size == lp1) + { + sarray[toggle][m_team_size] = atomic_fetch_add(global_accum,sarray[toggle][m_team_size]); + } + m_idx.barrier.wait(); + sarray[toggle][lid] += sarray[toggle][m_team_size]; + } + m_idx.barrier.wait(); + return sarray[toggle][lid]; +#endif + } + + private: + int m_league_size ; + int m_team_size ; + const scratch_memory_space m_team_shared; + + public: + int m_vector_length; + hc::tiled_index<1> m_idx; + }; +} +} // namespace Kokkos +#include + +namespace Kokkos { +namespace Impl { + +//---------------------------------------------------------------------------- + +template< class FunctorType , class... Traits > +class ParallelFor< FunctorType + , Kokkos::RangePolicy< Traits... >, Kokkos::Experimental::ROCm > +{ +private: + + typedef Kokkos::RangePolicy< Traits... > Policy ; + +public: + + inline + ParallelFor( const FunctorType & f + , const Policy & policy ) + { + + + const auto len = policy.end()-policy.begin(); + const auto offset = policy.begin(); + if(len == 0) return; +// define a lambda to work around a compiler issue. The compiler does not +// properly dereference f inside the pfe. +auto foo = [=](size_t i){rocm_invoke(f, i);}; + +#if __hcc_workweek__ > 16600 + hc::parallel_for_each(hc::extent<1>(len) , [=](const hc::index<1> & idx) [[hc]] [[hc_max_workgroup_dim(1024,1,1)]] +#else + hc::parallel_for_each(hc::extent<1>(len).tile(256) , [=](const hc::index<1> & idx) [[hc]] +#endif + { + if(idx[0] +class ParallelFor< F + , Kokkos::TeamPolicy< Traits... > + , Kokkos::Experimental::ROCm > +{ + using Policy = Kokkos::Impl::TeamPolicyInternal< Kokkos::Experimental::ROCm, Traits... >; + typedef Kokkos::Impl::FunctorValueTraits ValueTraits; + +public: + inline + ParallelFor( const F & f + , const Policy & policy ) + { + const auto league_size = policy.league_size(); + const auto team_size = policy.team_size(); + const int vector_length = policy.vector_length(); + const auto total_size = league_size * team_size * vector_length; + const int scratch_size0 = policy.scratch_size(0,team_size); + const int scratch_size1 = policy.scratch_size(1,team_size); + + if(total_size == 0) return; + + const auto shared_size = FunctorTeamShmemSize< F >::value( f , team_size ); + char * scratch = NULL; + char * shared = (char *)rocm_device_allocate(shared_size * league_size + + scratch_size0*league_size); + if(0 flat_extent( total_size ); + + hc::tiled_extent< 1 > team_extent = flat_extent.tile(team_size*vector_length); + hc::parallel_for_each( team_extent , [=](hc::tiled_index<1> idx) [[hc]] + { + rocm_invoke(f, typename Policy::member_type(idx, league_size, team_size, shared, shared_size, scratch_size0, scratch, scratch_size1,vector_length)); + }).wait(); + + if(0 +class ParallelReduce< + FunctorType , Kokkos::RangePolicy< Traits... >, ReducerType, Kokkos::Experimental::ROCm > +{ +public: + + typedef Kokkos::RangePolicy< Traits... > Policy ; + + // TODO: Use generic lambdas instead + struct invoke_fn + { + template + KOKKOS_INLINE_FUNCTION void operator()(std::size_t size, F&& f, hc::tiled_index<1> idx, tile_desc td, Ts&&... xs) const + { + auto global = idx.global[0]; + if (global < size) f(idx.global[0], static_cast(xs)...); + } + }; + + template< class ViewType > + inline + ParallelReduce( const FunctorType & f, + const Policy & policy, + const ViewType & result_view, + typename std::enable_if< + Kokkos::is_view< ViewType >::value && + !Kokkos::is_reducer_type::value + ,void*>::type = NULL) + { + typedef typename Policy::work_tag Tag; + typedef Kokkos::Impl::FunctorValueTraits< FunctorType , Tag > ValueTraits; + typedef Kokkos::Impl::FunctorValueInit< FunctorType , Tag > ValueInit; + typedef typename ValueTraits::reference_type reference_type; + + const auto total_size = policy.end() - policy.begin(); + + if(total_size==0) { + if (result_view.data()) { + ValueInit::init( f , result_view.data() ); + } + return; + } + + Kokkos::Impl::reduce_enqueue< Tag > + ( total_size + , f + , InvalidType{} + , rocm_capture(invoke_fn{}, total_size) + , result_view.data() + , result_view.extent(0) + ); + } + + inline + ParallelReduce( const FunctorType & f, + Policy policy, + const ReducerType& reducer ) + { + typedef typename Policy::work_tag Tag; + + typedef Kokkos::Impl::if_c< std::is_same::value, FunctorType, ReducerType> ReducerConditional; + typedef typename ReducerConditional::type ReducerTypeFwd; + typedef Kokkos::Impl::FunctorValueTraits< FunctorType , Tag > ValueTraits; + typedef Kokkos::Impl::FunctorValueInit< ReducerType, Tag > ValueInit ; + + typedef typename ValueTraits::reference_type reference_type; + + const auto total_size = policy.end() - policy.begin(); + + if(total_size==0) { + if (reducer.view().data()) { + ValueInit::init( ReducerConditional::select(f,reducer), + reducer.view().data() ); + } + return; + } + + Kokkos::Impl::reduce_enqueue< Tag > + ( total_size + , f + , reducer + , rocm_capture(invoke_fn{}, total_size) + , reducer.view().data() + , reducer.view().extent(0) + ); + } + + KOKKOS_INLINE_FUNCTION + void execute() const {} + +}; + +template< class FunctorType, class ReducerType, class... Traits > +class ParallelReduce< + FunctorType , Kokkos::TeamPolicy< Traits... >, ReducerType, Kokkos::Experimental::ROCm > +{ + using Policy = Kokkos::Impl::TeamPolicyInternal< Kokkos::Experimental::ROCm, Traits... >; + typedef Kokkos::Impl::FunctorValueTraits ValueTraits; + +public: + + struct invoke_fn + { + template + KOKKOS_INLINE_FUNCTION void operator()(Create&& create, F&& f, hc::tiled_index<1> idx, tile_desc td, Ts&&... xs) const + { + f(create(idx, td), static_cast(xs)...); + } + }; + + template< class ViewType > + inline + ParallelReduce( const FunctorType & f, + const Policy & policy, + const ViewType & result_view, + typename std::enable_if< + Kokkos::is_view< ViewType >::value && + !Kokkos::is_reducer_type::value + ,void*>::type = NULL) + { + const int league_size = policy.league_size(); + const int team_size = policy.team_size(f); + const int vector_length = policy.vector_length(); + const int scratch_size0 = policy.scratch_size(0,team_size); + const int scratch_size1 = policy.scratch_size(1,team_size); + const int total_size = league_size * team_size ; + + if(total_size == 0) return; + + const int reduce_size = ValueTraits::value_size( f ); + const int shared_size = FunctorTeamShmemSize< FunctorType >::value( f , team_size ); + + char * shared; + char * scratch = NULL; + + shared = (char *)rocm_device_allocate(league_size * + (shared_size + scratch_size0)); + if(0 idx, tile_desc td) + { + + return typename Policy::member_type(idx, league_size, td.team_size, + shared, shared_size, scratch_size0, + scratch, scratch_size1, + vector_length); + }; + + Kokkos::Impl::reduce_enqueue< typename Policy::work_tag > + ( total_size*vector_length + , f + , InvalidType{} + , rocm_capture(invoke_fn{}, create_team_member) + , result_view.ptr_on_device() + , result_view.dimension_0() + , team_size + , vector_length + , shared_size + ); + + if(0::value( f , team_size ); + const int scratch_size0 = policy.scratch_size(0,team_size); + const int scratch_size1 = policy.scratch_size(1,team_size); + + char * shared; + char * scratch = NULL; + shared = (char *)rocm_device_allocate((shared_size + scratch_size0) * + league_size); + if(0 idx, tile_desc td) + { + return typename Policy::member_type(idx, league_size, td.tile_size, shared, shared_size, scratch_size0, scratch, scratch_size1, vector_length); + }; + + Kokkos::Impl::reduce_enqueue< typename Policy::work_tag > + ( league_size + , f + , reducer + , rocm_capture(invoke_fn{}, create_team_member) + , reducer.view().data() + , reducer.view().extent(0),team_size,vector_length + , shared_size + ); + + if(0 +class ParallelScan< FunctorType , Kokkos::RangePolicy< Traits... >, Kokkos::Experimental::ROCm > +{ +private: + + typedef Kokkos::RangePolicy< Traits... > Policy; + typedef typename Policy::work_tag Tag; + typedef Kokkos::Impl::FunctorValueTraits< FunctorType, Tag> ValueTraits; + +public: + + //---------------------------------------- + + inline + ParallelScan( const FunctorType & f + , const Policy & policy ) + { + const auto len = policy.end()-policy.begin(); + + + if(len==0) return; + + scan_enqueue(len, f, [](hc::tiled_index<1> idx, int, int) { return idx.global[0]; }); + } + + KOKKOS_INLINE_FUNCTION + void execute() const {} + + //---------------------------------------- +}; + +template< class FunctorType , class... Traits> +class ParallelScan< FunctorType , Kokkos::TeamPolicy< Traits... >, Kokkos::Experimental::ROCm > +{ +private: + + using Policy = Kokkos::Impl::TeamPolicyInternal< Kokkos::Experimental::ROCm, Traits... >; + typedef typename Policy::work_tag Tag; + typedef Kokkos::Impl::FunctorValueTraits< FunctorType, Tag> ValueTraits; + +public: + + //---------------------------------------- + + inline + ParallelScan( const FunctorType & f + , const Policy & policy ) + { + const auto league_size = policy.league_size(); + const auto team_size = policy.team_size(f); + const auto len = league_size * team_size; + + if(len == 0) return; + + scan_enqueue(len, f, [&](hc::tiled_index<1> idx, int n_teams, int n_leagues) { return typename Policy::member_type(idx,n_leagues,n_teams); }); + } + + KOKKOS_INLINE_FUNCTION + void execute() const {} + + //---------------------------------------- +}; + +} +} + +namespace Kokkos { +namespace Impl { + template + struct TeamThreadRangeBoundariesStruct { + typedef iType index_type; + const iType start; + const iType end; + const iType increment; + const ROCmTeamMember& thread; + +#if defined( __HCC_ACCELERATOR__ ) + KOKKOS_INLINE_FUNCTION + TeamThreadRangeBoundariesStruct (const ROCmTeamMember& thread_, const iType& count): + start( thread_.team_rank() ), + end( count ), + increment( thread_.team_size() ), + thread(thread_) + {} + KOKKOS_INLINE_FUNCTION + TeamThreadRangeBoundariesStruct (const ROCmTeamMember& thread_, const iType& begin_, const iType& end_): + start( begin_ + thread_.team_rank() ), + end( end_ ), + increment( thread_.team_size() ), + thread(thread_) + {} +#else + KOKKOS_INLINE_FUNCTION + TeamThreadRangeBoundariesStruct (const ROCmTeamMember& thread_, const iType& count): + start( 0 ), + end( count ), + increment( 1 ), + thread(thread_) + {} + KOKKOS_INLINE_FUNCTION + TeamThreadRangeBoundariesStruct (const ROCmTeamMember& thread_, const iType& begin_, const iType& end_): + start( begin_ ), + end( end_ ), + increment( 1 ), + thread(thread_) + {} +#endif + }; + template + struct ThreadVectorRangeBoundariesStruct { + typedef iType index_type; + const iType start; + const iType end; + const iType increment; + const ROCmTeamMember& thread; + +#if defined( __HCC_ACCELERATOR__ ) + KOKKOS_INLINE_FUNCTION + ThreadVectorRangeBoundariesStruct (const ROCmTeamMember& thread_, const iType& count): + start( thread_.lindex()%thread_.vector_length() ), + end( count ), + increment( thread_.vector_length() ), + thread(thread_) + {} + +// KOKKOS_INLINE_FUNCTION +// ThreadVectorRangeBoundariesStruct (const iType& count): +// start( 0 ), +// end( count ), +// increment( 1 ) +// {} +#else + KOKKOS_INLINE_FUNCTION + ThreadVectorRangeBoundariesStruct (const ROCmTeamMember& thread_, const iType& count): + start( 0 ), + end( count ), + increment( 1 ), + thread(thread_) + {} + KOKKOS_INLINE_FUNCTION + ThreadVectorRangeBoundariesStruct (const iType& count): + start( 0 ), + end( count ), + increment( 1 ) + {} +#endif + }; + +} +} + +namespace Kokkos { + +template +KOKKOS_INLINE_FUNCTION +Impl::TeamThreadRangeBoundariesStruct + TeamThreadRange(const Impl::ROCmTeamMember& thread, const iType& count) { + return Impl::TeamThreadRangeBoundariesStruct(thread,count); +} + +template +KOKKOS_INLINE_FUNCTION +Impl::TeamThreadRangeBoundariesStruct::type,Impl::ROCmTeamMember> + TeamThreadRange(const Impl::ROCmTeamMember& thread, const iType1& begin, const iType2& end) { + typedef typename std::common_type< iType1, iType2 >::type iType; + return Impl::TeamThreadRangeBoundariesStruct(thread,begin,end); +} + +template +KOKKOS_INLINE_FUNCTION +Impl::ThreadVectorRangeBoundariesStruct + ThreadVectorRange(const Impl::ROCmTeamMember& thread, const iType& count) { + return Impl::ThreadVectorRangeBoundariesStruct(thread,count); +} + +KOKKOS_INLINE_FUNCTION +Impl::ThreadSingleStruct PerTeam(const Impl::ROCmTeamMember& thread) { + return Impl::ThreadSingleStruct(thread); +} + +KOKKOS_INLINE_FUNCTION +Impl::VectorSingleStruct PerThread(const Impl::ROCmTeamMember& thread) { + return Impl::VectorSingleStruct(thread); +} + +template +KOKKOS_INLINE_FUNCTION +void single(const Impl::VectorSingleStruct& single_struct, const FunctorType& lambda) { + if(single_struct.team_member.vector_rank()==0) lambda(); +} + +template +KOKKOS_INLINE_FUNCTION +void single(const Impl::ThreadSingleStruct& single_struct, const FunctorType& lambda) { + if((single_struct.team_member.lindex()==0)) lambda(); +} + +template +KOKKOS_INLINE_FUNCTION +void single(const Impl::VectorSingleStruct& single_struct, const FunctorType& lambda, ValueType& val) { +#if defined(ROCM15) + // 1.5 needs this more proper restriction on which work units run + if( single_struct.team_member.vector_rank()==0) lambda(val); + val = shfl(val,0,single_struct.team_member.vector_length()); +#else + // but older compilers are fine with this (TestTeamVector::Test< Kokkos::Experimental::ROCm >(4)) + lambda(val); +#endif +} + +template +KOKKOS_INLINE_FUNCTION +void single(const Impl::ThreadSingleStruct& single_struct, const FunctorType& lambda, ValueType& val) { + if(single_struct.team_member.lindex()==0) lambda(val); + single_struct.team_member.team_broadcast(val,0); +} + +} + +namespace Kokkos { + + /** \brief Inter-thread parallel_for. Executes lambda(iType i) for each i=0..N-1. + * + * The range i=0..N-1 is mapped to all threads of the the calling thread team. + * This functionality requires C++11 support.*/ +template +KOKKOS_INLINE_FUNCTION +void parallel_for(const Impl::TeamThreadRangeBoundariesStruct& loop_boundaries, const Lambda& lambda) { + for( iType i = loop_boundaries.start; i < loop_boundaries.end; i+=loop_boundaries.increment) + lambda(i); +} + +/** \brief Inter-thread thread range parallel_reduce. Executes lambda(iType i, ValueType & val) for each i=0..N-1. + * + * The range i=0..N-1 is mapped to all threads of the the calling thread team and a summation of + * val is performed and put into result. This functionality requires C++11 support.*/ +template< typename iType, class Lambda, typename ValueType > +KOKKOS_INLINE_FUNCTION +void parallel_reduce(const Impl::TeamThreadRangeBoundariesStruct& loop_boundaries, + const Lambda & lambda, ValueType& result) { + + result = ValueType(); + + for( iType i = loop_boundaries.start; i < loop_boundaries.end; i+=loop_boundaries.increment) { + ValueType tmp = ValueType(); + lambda(i,tmp); + result+=tmp; + } + result = loop_boundaries.thread.team_reduce(result, + Impl::JoinAdd()); +// Impl::rocm_intra_workgroup_reduction( loop_boundaries.thread, result, +// Impl::JoinAdd()); +// Impl::rocm_inter_workgroup_reduction( loop_boundaries.thread, result, +// Impl::JoinAdd()); +} + +/** \brief Intra-thread thread range parallel_reduce. Executes lambda(iType i, ValueType & val) for each i=0..N-1. + * + * The range i=0..N-1 is mapped to all vector lanes of the the calling thread and a reduction of + * val is performed using JoinType(ValueType& val, const ValueType& update) and put into init_result. + * The input value of init_result is used as initializer for temporary variables of ValueType. Therefore + * the input value should be the neutral element with respect to the join operation (e.g. '0 for +-' or + * '1 for *'). This functionality requires C++11 support.*/ +template< typename iType, class Lambda, typename ValueType, class JoinType > +KOKKOS_INLINE_FUNCTION +void parallel_reduce(const Impl::TeamThreadRangeBoundariesStruct& loop_boundaries, + const Lambda & lambda, const JoinType& join, ValueType& result) { + +#if defined(ROCM15) + ValueType tmp = result; + // Simpler code works with ROCM1.5 + for( iType i = loop_boundaries.start; i < loop_boundaries.end; i+=loop_boundaries.increment) { + lambda(i,tmp); + } + result = loop_boundaries.thread.team_reduce(tmp,join); +#else + // this workaround freezes up with ROCM1.5, but needed for earlier compilers + for( iType i = loop_boundaries.start; i < loop_boundaries.end; i+=loop_boundaries.increment) { + ValueType tmp = ValueType(); + lambda(i,tmp); + join(result,tmp); + } + result = loop_boundaries.thread.team_reduce(result,join); +#endif +// Impl::rocm_intra_workgroup_reduction( loop_boundaries.thread, result,join); +// Impl::rocm_inter_workgroup_reduction( loop_boundaries.thread, result,join); +} + +} //namespace Kokkos + + +namespace Kokkos { +/** \brief Intra-thread vector parallel_for. Executes lambda(iType i) for each i=0..N-1. + * + * The range i=0..N-1 is mapped to all vector lanes of the the calling thread. + * This functionality requires C++11 support.*/ +template +KOKKOS_INLINE_FUNCTION +void parallel_for(const Impl::ThreadVectorRangeBoundariesStruct& + loop_boundaries, const Lambda& lambda) { + + for( iType i = loop_boundaries.start; i < loop_boundaries.end; i+=loop_boundaries.increment) + lambda(i); +} + +/** \brief Intra-thread vector parallel_reduce. Executes lambda(iType i, ValueType & val) for each i=0..N-1. + * + * The range i=0..N-1 is mapped to all vector lanes of the the calling thread and a summation of + * val is performed and put into result. This functionality requires C++11 support.*/ +template< typename iType, class Lambda, typename ValueType > +KOKKOS_INLINE_FUNCTION +void parallel_reduce(const Impl::ThreadVectorRangeBoundariesStruct& + loop_boundaries, const Lambda & lambda, ValueType& result) { + result = ValueType(); + + for( iType i = loop_boundaries.start; i < loop_boundaries.end; i+=loop_boundaries.increment) { + ValueType tmp = ValueType(); + lambda(i,tmp); + result+=tmp; + } + result = loop_boundaries.thread.thread_reduce(result,Impl::JoinAdd()); +} + +/** \brief Intra-thread vector parallel_reduce. Executes lambda(iType i, ValueType & val) for each i=0..N-1. + * + * The range i=0..N-1 is mapped to all vector lanes of the the calling thread and a reduction of + * val is performed using JoinType(ValueType& val, const ValueType& update) and put into init_result. + * The input value of init_result is used as initializer for temporary variables of ValueType. Therefore + * the input value should be the neutral element with respect to the join operation (e.g. '0 for +-' or + * '1 for *'). This functionality requires C++11 support.*/ +template< typename iType, class Lambda, typename ValueType, class JoinType > +KOKKOS_INLINE_FUNCTION +void parallel_reduce(const Impl::ThreadVectorRangeBoundariesStruct& + loop_boundaries, const Lambda & lambda, const JoinType& join, ValueType& result) { + + for( iType i = loop_boundaries.start; i < loop_boundaries.end; i+=loop_boundaries.increment) { + lambda(i,result); + loop_boundaries.thread.team_barrier(); + } + result = loop_boundaries.thread.thread_reduce(result,join); +} + +/** \brief Intra-thread vector parallel exclusive prefix sum. Executes lambda(iType i, ValueType & val, bool final) + * for each i=0..N-1. + * + * The range i=0..N-1 is mapped to all vector lanes in the thread and a scan operation is performed. + * Depending on the target execution space the operator might be called twice: once with final=false + * and once with final=true. When final==true val contains the prefix sum value. The contribution of this + * "i" needs to be added to val no matter whether final==true or not. In a serial execution + * (i.e. team_size==1) the operator is only called once with final==true. Scan_val will be set + * to the final sum value over all vector lanes. + * This functionality requires C++11 support.*/ +template< typename iType, class FunctorType > +KOKKOS_INLINE_FUNCTION +void parallel_scan(const Impl::ThreadVectorRangeBoundariesStruct& + loop_boundaries, const FunctorType & lambda) { + + typedef Kokkos::Impl::FunctorValueTraits< FunctorType , void > ValueTraits ; + typedef typename ValueTraits::value_type value_type ; + + value_type scan_val = value_type(); +#if (__ROCM_ARCH__ >= 800) +// adopt the cuda vector shuffle method + const int VectorLength = loop_boundaries.increment; + int lid = loop_boundaries.thread.lindex(); + int vector_rank = lid%VectorLength; + + iType loop_bound = ((loop_boundaries.end+VectorLength-1)/VectorLength) * VectorLength; + value_type val ; + for(int _i = vector_rank; _i < loop_bound; _i += VectorLength) { + val = value_type(); + if(_i 1) { + const value_type tmp2 = shfl_up(tmp, 1,VectorLength); + if(vector_rank > 0) + tmp+=tmp2; + } + if(vector_rank == 1) + result_i = tmp; + if (VectorLength > 3) { + const value_type tmp2 = shfl_up(tmp, 2,VectorLength); + if(vector_rank > 1) + tmp+=tmp2; + } + if ((vector_rank >= 2) && + (vector_rank < 4)) + result_i = tmp; + if (VectorLength > 7) { + const value_type tmp2 = shfl_up(tmp, 4,VectorLength); + if(vector_rank > 3) + tmp+=tmp2; + } + if ((vector_rank >= 4) && + (vector_rank < 8)) + result_i = tmp; + if (VectorLength > 15) { + const value_type tmp2 = shfl_up(tmp, 8,VectorLength); + if(vector_rank > 7) + tmp+=tmp2; + } + if ((vector_rank >= 8) && + (vector_rank < 16)) + result_i = tmp; + if (VectorLength > 31) { + const value_type tmp2 = shfl_up(tmp, 16,VectorLength); + if(vector_rank > 15) + tmp+=tmp2; + } + if ((vector_rank >=16) && + (vector_rank < 32)) + result_i = tmp; + if (VectorLength > 63) { + const value_type tmp2 = shfl_up(tmp, 32,VectorLength); + if(vector_rank > 31) + tmp+=tmp2; + } + + if (vector_rank >= 32) + result_i = tmp; + + val = scan_val + result_i - val; + scan_val += shfl(tmp,VectorLength-1,VectorLength); + if(_i + +#include +#include +#include +#include +#include +#include +#include + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +namespace Kokkos { +namespace Impl { + +template +T* reduce_value(T* x, std::true_type) [[hc]] +{ + return x; +} + +template +T& reduce_value(T* x, std::false_type) [[hc]] +{ + return *x; +} + +#if KOKKOS_ROCM_HAS_WORKAROUNDS +struct always_true +{ + template + bool operator()(Ts&&...) const + { + return true; + } +}; +#endif + +template< class Tag, class F, class ReducerType, class Invoker, class T > +void reduce_enqueue( + const int szElements, // size of the extent + const F & f, + const ReducerType& reducer, + Invoker invoke, + T * const output_result, + int const output_length, + const int team_size=64, + const int vector_size=1, + int const shared_size=0) +{ + using namespace hc ; + + typedef Kokkos::Impl::if_c< std::is_same::value, F, ReducerType> ReducerConditional; + typedef typename ReducerConditional::type ReducerTypeFwd; + + typedef Kokkos::Impl::FunctorValueTraits< ReducerTypeFwd , Tag > ValueTraits ; + typedef Kokkos::Impl::FunctorValueInit< ReducerTypeFwd , Tag > ValueInit ; + typedef Kokkos::Impl::FunctorValueJoin< ReducerTypeFwd , Tag > ValueJoin ; + typedef Kokkos::Impl::FunctorFinal< ReducerTypeFwd , Tag > ValueFinal ; + + typedef typename ValueTraits::pointer_type pointer_type ; + typedef typename ValueTraits::reference_type reference_type ; + + if (output_length < 1) return; + + assert(output_result != nullptr); + const auto td = get_tile_desc(szElements,output_length,team_size,vector_size, shared_size); + + // allocate host and device memory for the results from each team + std::vector result_cpu(td.num_tiles*output_length); + hc::array result(td.num_tiles*output_length); + + auto fut = tile_for(td, [=,&result](hc::tiled_index<1> t_idx, tile_buffer buffer) [[hc]] + { + const auto local = t_idx.local[0]; + const auto global = t_idx.global[0]; + const auto tile = t_idx.tile[0]; + + buffer.action_at(local, [&](T* state) + { + ValueInit::init(ReducerConditional::select(f, reducer), state); + invoke(make_rocm_invoke_fn(f), t_idx, td, reduce_value(state, std::is_pointer())); + }); + t_idx.barrier.wait(); + + // Reduce within a tile using multiple threads. +// even though buffer.size is always 64, the value 64 must be hard coded below +// due to a compiler bug +// for(std::size_t s = 1; s < buffer.size(); s *= 2) + for(std::size_t s = 1; s < 64; s *= 2) + { + const std::size_t index = 2 * s * local; +// if (index < buffer.size()) + if (index < 64) + { + buffer.action_at(index, index + s, [&](T* x, T* y) + { + ValueJoin::join(ReducerConditional::select(f, reducer), x, y); + }); + } + t_idx.barrier.wait(); + } + + // Store the tile result in the global memory. + if (local == 0) + { +#if KOKKOS_ROCM_HAS_WORKAROUNDS + // Workaround for assigning from LDS memory: std::copy should work + // directly + buffer.action_at(0, [&](T* x) + { +#if ROCM15 +// new ROCM 15 address space changes aren't implemented in std algorithms yet + auto * src = reinterpret_cast(x); + auto * dest = reinterpret_cast(result.data()+tile*output_length); + for(int i=0; i + +/* only compile this file if ROCM is enabled for Kokkos */ +#if defined( __HCC__ ) && defined( KOKKOS_ENABLE_ROCM ) + +//#include + +#include +#include +#include +#include + +//---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- + +namespace Kokkos { +namespace Impl { + +//---------------------------------------------------------------------------- + +template< typename T > +KOKKOS_INLINE_FUNCTION +void rocm_shfl( T & out , T const & in , int lane , + typename std::enable_if< sizeof(int) == sizeof(T) , int >::type width ) +{ + *reinterpret_cast(&out) = + __shfl( *reinterpret_cast(&in) , lane , width ); +} + +template< typename T > +KOKKOS_INLINE_FUNCTION +void rocm_shfl( T & out , T const & in , int lane , + typename std::enable_if + < ( sizeof(int) < sizeof(T) ) && ( 0 == ( sizeof(T) % sizeof(int) ) ) + , int >::type width ) +{ + enum : int { N = sizeof(T) / sizeof(int) }; + + for ( int i = 0 ; i < N ; ++i ) { + reinterpret_cast(&out)[i] = + __shfl( reinterpret_cast(&in)[i] , lane , width ); + } +} + +//---------------------------------------------------------------------------- + +template< typename T > +KOKKOS_INLINE_FUNCTION +void rocm_shfl_down( T & out , T const & in , int delta , + typename std::enable_if< sizeof(int) == sizeof(T) , int >::type width ) +{ + *reinterpret_cast(&out) = + __shfl_down( *reinterpret_cast(&in) , delta , width ); +} + +template< typename T > +KOKKOS_INLINE_FUNCTION +void rocm_shfl_down( T & out , T const & in , int delta , + typename std::enable_if + < ( sizeof(int) < sizeof(T) ) && ( 0 == ( sizeof(T) % sizeof(int) ) ) + , int >::type width ) +{ + enum : int { N = sizeof(T) / sizeof(int) }; + + for ( int i = 0 ; i < N ; ++i ) { + reinterpret_cast(&out)[i] = + __shfl_down( reinterpret_cast(&in)[i] , delta , width ); + } +} + +//---------------------------------------------------------------------------- + +template< typename T > +KOKKOS_INLINE_FUNCTION +void rocm_shfl_up( T & out , T const & in , int delta , + typename std::enable_if< sizeof(int) == sizeof(T) , int >::type width ) +{ + *reinterpret_cast(&out) = + __shfl_up( *reinterpret_cast(&in) , delta , width ); +} + +template< typename T > +KOKKOS_INLINE_FUNCTION +void rocm_shfl_up( T & out , T const & in , int delta , + typename std::enable_if + < ( sizeof(int) < sizeof(T) ) && ( 0 == ( sizeof(T) % sizeof(int) ) ) + , int >::type width ) +{ + enum : int { N = sizeof(T) / sizeof(int) }; + + for ( int i = 0 ; i < N ; ++i ) { + reinterpret_cast(&out)[i] = + __shfl_up( reinterpret_cast(&in)[i] , delta , width ); + } +} +#if 0 +//---------------------------------------------------------------------------- +/** \brief Reduce within a workgroup over team.vector_length(), the "vector" dimension. + * + * This will be called within a nested, intra-team parallel operation. + * Use shuffle operations to avoid conflicts with shared memory usage. + * + * Requires: + * team.vector_length() is power of 2 + * team.vector_length() <= 32 (one workgroup) + * + * Cannot use "butterfly" pattern because floating point + * addition is non-associative. Therefore, must broadcast + * the final result. + */ +template< class Reducer > +KOKKOS_INLINE_FUNCTION +void rocm_intra_workgroup_vector_reduce( Reducer const & reducer ) +{ + static_assert( + std::is_reference< typename Reducer::reference_type >::value , "" ); + + if ( 1 < team.vector_length() ) { + + typename Reducer::value_type tmp ; + + for ( int i = team.vector_length() ; ( i >>= 1 ) ; ) { + + rocm_shfl_down( tmp , reducer.reference() , i , team.vector_length() ); + + if ( team.vector_rank() < i ) { reducer.join( reducer.data() , & tmp ); } + } + + // Broadcast from root "lane" to all other "lanes" + + rocm_shfl( reducer.reference() , reducer.reference() , 0 , team.vector_length() ); + } +} + +/** \brief Inclusive scan over team.vector_length(), the "vector" dimension. + * + * This will be called within a nested, intra-team parallel operation. + * Use shuffle operations to avoid conflicts with shared memory usage. + * + * Algorithm is concurrent bottom-up reductions in triangular pattern + * where each ROCM thread is the root of a reduction tree from the + * zeroth ROCM thread to itself. + * + * Requires: + * team.vector_length() is power of 2 + * team.vector_length() <= 32 (one workgroup) + */ +template< typename ValueType > +KOKKOS_INLINE_FUNCTION +void rocm_intra_workgroup_vector_inclusive_scan( ValueType & local ) +{ + ValueType tmp ; + + // Bottom up: + // [t] += [t-1] if t >= 1 + // [t] += [t-2] if t >= 2 + // [t] += [t-4] if t >= 4 + // ... + + for ( int i = 1 ; i < team.vector_length() ; i <<= 1 ) { + + rocm_shfl_up( tmp , local , i , team.vector_length() ); + + if ( i <= team.vector_rank() ) { local += tmp ; } + } +} +#endif + +//---------------------------------------------------------------------------- +/* + * Algorithmic constraints: + * (a) threads with same team.team_rank() have same value + * (b) team.vector_length() == power of two + * (c) blockDim.z == 1 + */ + +template< class ValueType , class JoinOp> +KOKKOS_INLINE_FUNCTION +void rocm_intra_workgroup_reduction( const ROCmTeamMember& team, + ValueType& result, + const JoinOp& join) { + + unsigned int shift = 1; + int max_active_thread = team.team_size(); + + //Reduce over values from threads with different team.team_rank() + while(team.vector_length() * shift < 32 ) { + const ValueType tmp = shfl_down(result, team.vector_length()*shift,32u); + //Only join if upper thread is active (this allows non power of two for team.team_size() + if(team.team_rank() + shift < max_active_thread) + join(result , tmp); + shift*=2; + } + + result = shfl(result,0,32); +} + +template< class ValueType , class JoinOp> +KOKKOS_INLINE_FUNCTION +void rocm_inter_workgroup_reduction( const ROCmTeamMember& team, + ValueType& value, + const JoinOp& join) { + + #define STEP_WIDTH 4 + + tile_static ValueType sh_result[256]; + int max_active_thread = team.team_size(); + ValueType* result = (ValueType*) & sh_result; + const unsigned step = 256 / team.vector_length(); + unsigned shift = STEP_WIDTH; + const int id = team.team_rank()%step==0?team.team_rank()/step:65000; + if(id < STEP_WIDTH ) { + result[id] = value; + } + team.team_barrier(); + + while (shift<=max_active_thread/step) { + if(shift<=id && shift+STEP_WIDTH>id && team.vector_rank()==0) { + join(result[id%STEP_WIDTH],value); + } + team.team_barrier(); + shift+=STEP_WIDTH; + } + + + value = result[0]; + for(int i = 1; (i*step +KOKKOS_INLINE_FUNCTION +void rocm_intra_block_reduction( ROCmTeamMember& team, + ValueType& value, + const JoinOp& join, + const int max_active_thread) { + rocm_intra_workgroup_reduction(team,value,join,max_active_thread); + rocm_inter_workgroup_reduction(team,value,join,max_active_thread); +} + +template< class FunctorType , class JoinOp , class ArgTag = void > +KOKKOS_INLINE_FUNCTION +bool rocm_inter_block_reduction( ROCmTeamMember& team, + typename FunctorValueTraits< FunctorType , ArgTag >::reference_type value, + typename FunctorValueTraits< FunctorType , ArgTag >::reference_type neutral, + const JoinOp& join, + ROCm::size_type * const m_scratch_space, + typename FunctorValueTraits< FunctorType , ArgTag >::pointer_type const result, + ROCm::size_type * const m_scratch_flags, + const int max_active_thread) { +#ifdef __ROCM_ARCH__ + typedef typename FunctorValueTraits< FunctorType , ArgTag >::pointer_type pointer_type; + typedef typename FunctorValueTraits< FunctorType , ArgTag >::value_type value_type; + + //Do the intra-block reduction with shfl operations and static shared memory + rocm_intra_block_reduction(value,join,max_active_thread); + + const unsigned id = team.team_rank()*team.vector_length() + team.vector_rank(); + + //One thread in the block writes block result to global scratch_memory + if(id == 0 ) { + pointer_type global = ((pointer_type) m_scratch_space) + blockIdx.x; + *global = value; + } + + //One workgroup of last block performs inter block reduction through loading the block values from global scratch_memory + bool last_block = false; + + team.team_barrier(); + if ( id < 32 ) { + ROCm::size_type count; + + //Figure out whether this is the last block + if(id == 0) + count = Kokkos::atomic_fetch_add(m_scratch_flags,1); + count = Kokkos::shfl(count,0,32); + + //Last block does the inter block reduction + if( count == gridDim.x - 1) { + //set flag back to zero + if(id == 0) + *m_scratch_flags = 0; + last_block = true; + value = neutral; + + pointer_type const volatile global = (pointer_type) m_scratch_space ; + + //Reduce all global values with splitting work over threads in one workgroup + const int step_size = team.vector_length()*team.team_size() < 32 ? team.vector_length()*team.team_size() : 32; + for(int i=id; i 1) { + value_type tmp = Kokkos::shfl_down(value, 1,32); + if( id + 1 < gridDim.x ) + join(value, tmp); + } + if (team.vector_length()*team.team_size() > 2) { + value_type tmp = Kokkos::shfl_down(value, 2,32); + if( id + 2 < gridDim.x ) + join(value, tmp); + } + if (team.vector_length()*team.team_size() > 4) { + value_type tmp = Kokkos::shfl_down(value, 4,32); + if( id + 4 < gridDim.x ) + join(value, tmp); + } + if (team.vector_length()*team.team_size() > 8) { + value_type tmp = Kokkos::shfl_down(value, 8,32); + if( id + 8 < gridDim.x ) + join(value, tmp); + } + if (team.vector_length()*team.team_size() > 16) { + value_type tmp = Kokkos::shfl_down(value, 16,32); + if( id + 16 < gridDim.x ) + join(value, tmp); + } + } + } + + //The last block has in its thread=0 the global reduction value through "value" + return last_block; +#else + return true; +#endif +} +#endif +#if 0 + +//---------------------------------------------------------------------------- +// See section B.17 of ROCm C Programming Guide Version 3.2 +// for discussion of +// __launch_bounds__(maxThreadsPerBlock,minBlocksPerMultiprocessor) +// function qualifier which could be used to improve performance. +//---------------------------------------------------------------------------- +// Maximize shared memory and minimize L1 cache: +// rocmFuncSetCacheConfig(MyKernel, rocmFuncCachePreferShared ); +// For 2.0 capability: 48 KB shared and 16 KB L1 +//---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- +/* + * Algorithmic constraints: + * (a) team.team_size() is a power of two + * (b) team.team_size() <= 512 + * (c) team.vector_length() == blockDim.z == 1 + */ + +template< bool DoScan , class FunctorType , class ArgTag > +KOKKOS_INLINE_FUNCTION +void rocm_intra_block_reduce_scan( const FunctorType & functor , + const typename FunctorValueTraits< FunctorType , ArgTag >::pointer_type base_data ) +{ + typedef FunctorValueTraits< FunctorType , ArgTag > ValueTraits ; + typedef FunctorValueJoin< FunctorType , ArgTag > ValueJoin ; + + typedef typename ValueTraits::pointer_type pointer_type ; + + const unsigned value_count = ValueTraits::value_count( functor ); + const unsigned BlockSizeMask = team.team_size() - 1 ; + + // Must have power of two thread count + + if ( BlockSizeMask & team.team_size() ) { Kokkos::abort("ROCm::rocm_intra_block_scan requires power-of-two blockDim"); } + +#define BLOCK_REDUCE_STEP( R , TD , S ) \ + if ( ! ( R & ((1<<(S+1))-1) ) ) { ValueJoin::join( functor , TD , (TD - (value_count< +KOKKOS_INLINE_FUNCTION +bool rocm_single_inter_block_reduce_scan( const FunctorType & functor , + const ROCm::size_type block_id , + const ROCm::size_type block_count , + ROCm::size_type * const shared_data , + ROCm::size_type * const global_data , + ROCm::size_type * const global_flags ) +{ + typedef ROCm::size_type size_type ; + typedef FunctorValueTraits< FunctorType , ArgTag > ValueTraits ; + typedef FunctorValueJoin< FunctorType , ArgTag > ValueJoin ; + typedef FunctorValueInit< FunctorType , ArgTag > ValueInit ; + typedef FunctorValueOps< FunctorType , ArgTag > ValueOps ; + + typedef typename ValueTraits::pointer_type pointer_type ; + typedef typename ValueTraits::reference_type reference_type ; + typedef typename ValueTraits::value_type value_type ; + + // '__ffs' = position of the least significant bit set to 1. + // 'team.team_size()' is guaranteed to be a power of two so this + // is the integral shift value that can replace an integral divide. + const unsigned BlockSizeShift = __ffs( team.team_size() ) - 1 ; + const unsigned BlockSizeMask = team.team_size() - 1 ; + + // Must have power of two thread count + if ( BlockSizeMask & team.team_size() ) { Kokkos::abort("ROCm::rocm_single_inter_block_reduce_scan requires power-of-two blockDim"); } + + const integral_nonzero_constant< size_type , ValueTraits::StaticValueSize / sizeof(size_type) > + word_count( ValueTraits::value_size( functor ) / sizeof(size_type) ); + + // Reduce the accumulation for the entire block. + rocm_intra_block_reduce_scan( functor , pointer_type(shared_data) ); + + { + // Write accumulation total to global scratch space. + // Accumulation total is the last thread's data. + size_type * const shared = shared_data + word_count.value * BlockSizeMask ; + size_type * const global = global_data + word_count.value * block_id ; + +#if (__ROCM_ARCH__ < 500) + for ( size_type i = team.team_rank() ; i < word_count.value ; i += team.team_size() ) { global[i] = shared[i] ; } +#else + for ( size_type i = 0 ; i < word_count.value ; i += 1 ) { global[i] = shared[i] ; } +#endif + + } + + // Contributing blocks note that their contribution has been completed via an atomic-increment flag + // If this block is not the last block to contribute to this group then the block is done. + team.team_barrier(); + const bool is_last_block = + ! team.team_reduce( team.team_rank() ? 0 : ( 1 + atomicInc( global_flags , block_count - 1 ) < block_count ) ,Impl::JoinAdd()); + + if ( is_last_block ) { + + const size_type b = ( long(block_count) * long(team.team_rank()) ) >> BlockSizeShift ; + const size_type e = ( long(block_count) * long( team.team_rank() + 1 ) ) >> BlockSizeShift ; + + { + void * const shared_ptr = shared_data + word_count.value * team.team_rank() ; + reference_type shared_value = ValueInit::init( functor , shared_ptr ); + + for ( size_type i = b ; i < e ; ++i ) { + ValueJoin::join( functor , shared_ptr , global_data + word_count.value * i ); + } + } + + rocm_intra_block_reduce_scan( functor , pointer_type(shared_data) ); + + if ( DoScan ) { + + size_type * const shared_value = shared_data + word_count.value * ( team.team_rank() ? team.team_rank() - 1 : team.team_size() ); + + if ( ! team.team_rank() ) { ValueInit::init( functor , shared_value ); } + + // Join previous inclusive scan value to each member + for ( size_type i = b ; i < e ; ++i ) { + size_type * const global_value = global_data + word_count.value * i ; + ValueJoin::join( functor , shared_value , global_value ); + ValueOps ::copy( functor , global_value , shared_value ); + } + } + } + + return is_last_block ; +} + +// Size in bytes required for inter block reduce or scan +template< bool DoScan , class FunctorType , class ArgTag > +inline +unsigned rocm_single_inter_block_reduce_scan_shmem( const FunctorType & functor , const unsigned BlockSize ) +{ + return ( BlockSize + 2 ) * Impl::FunctorValueTraits< FunctorType , ArgTag >::value_size( functor ); +} +#endif + +} // namespace Impl +} // namespace Kokkos + +//---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- + +#endif /* #if defined( __ROCMCC__ ) */ +#endif /* KOKKOS_ROCM_REDUCESCAN_HPP */ + diff --git a/lib/kokkos/core/src/ROCm/Kokkos_ROCm_Scan.hpp b/lib/kokkos/core/src/ROCm/Kokkos_ROCm_Scan.hpp new file mode 100644 index 0000000000..acf75f6f13 --- /dev/null +++ b/lib/kokkos/core/src/ROCm/Kokkos_ROCm_Scan.hpp @@ -0,0 +1,157 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include +#include + +namespace Kokkos { +namespace Impl { + +template< class Tag, class F, class TransformIndex> +void scan_enqueue( + const int len, + const F & f, + TransformIndex transform_index) +{ + typedef Kokkos::Impl::FunctorValueTraits< F, Tag> ValueTraits; + typedef Kokkos::Impl::FunctorValueInit< F, Tag> ValueInit; + typedef Kokkos::Impl::FunctorValueJoin< F, Tag> ValueJoin; + typedef Kokkos::Impl::FunctorValueOps< F, Tag> ValueOps; + + typedef typename ValueTraits::value_type value_type; + typedef typename ValueTraits::pointer_type pointer_type; + typedef typename ValueTraits::reference_type reference_type; + + const auto td = get_tile_desc(len); + std::vector result_cpu(td.num_tiles); + hc::array result(td.num_tiles); + hc::array scratch(len); + + tile_for(td, [&,len,td](hc::tiled_index<1> t_idx, tile_buffer buffer) [[hc]] + { + const auto local = t_idx.local[0]; + const auto global = t_idx.global[0]; + const auto tile = t_idx.tile[0]; + + // Join tile buffer elements + const auto join = [&](std::size_t i, std::size_t j) + { + buffer.action_at(i, j, [&](value_type& x, const value_type& y) + { + ValueJoin::join(f, &x, &y); + }); + }; + + // Copy into tile + buffer.action_at(local, [&](value_type& state) + { + ValueInit::init(f, &state); + if (global < len) rocm_invoke(f, transform_index(t_idx, td.tile_size, td.num_tiles), state, false); + }); + t_idx.barrier.wait(); + // Up sweep phase + for(std::size_t d=1;d0;d/=2) + { + auto d2 = 2*d; + auto i = local*d2; + if(i1) +// std::partial_sum(result_cpu.data(), result_cpu.data()+(td.num_tiles-1)*sizeof(value_type), result_cpu.data(), make_join_operator(f)); +// use this implementation instead. + for(int i=1; i(len).tile(td.tile_size), [&,len,td](hc::tiled_index<1> t_idx) [[hc]] + { +// const auto local = t_idx.local[0]; + const auto global = t_idx.global[0]; + const auto tile = t_idx.tile[0]; + + if (global < len) + { + auto final_state = scratch[global]; + +// the join is locking up, at least with 1.6 + if (tile != 0) final_state += result[tile-1]; +// if (tile != 0) ValueJoin::join(f, &final_state, &result[tile-1]); + rocm_invoke(f, transform_index(t_idx, td.tile_size, td.num_tiles), final_state, true); + } + }).wait(); +} + +} // namespace Impl +} // namespace Kokkos diff --git a/lib/kokkos/core/src/ROCm/Kokkos_ROCm_Space.cpp b/lib/kokkos/core/src/ROCm/Kokkos_ROCm_Space.cpp new file mode 100644 index 0000000000..e2b6738076 --- /dev/null +++ b/lib/kokkos/core/src/ROCm/Kokkos_ROCm_Space.cpp @@ -0,0 +1,726 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include +#include +#include +#include +#include +#include +#include + +/* only compile this file if ROCM is enabled for Kokkos */ +#ifdef KOKKOS_ENABLE_ROCM + +#include +#include +#include + +#include + +#if defined(KOKKOS_ENABLE_PROFILING) +#include +#endif + + +/*--------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------*/ +#define ROCM_SAFE_CALL +namespace Kokkos { +namespace Impl { +using namespace hc; + +DeepCopy::DeepCopy( void * dst , const void * src , size_t n ) +{ + hc::accelerator acc; + hc::accelerator_view av = acc.get_default_view(); + av.copy( src , dst , n); +} + + +DeepCopy::DeepCopy( void * dst , const void * src , size_t n ) +{ + hc::accelerator acc; + hc::accelerator_view av = acc.get_default_view(); + av.copy( src , dst , n); +} + +DeepCopy::DeepCopy( void * dst , const void * src , size_t n ) +{ + hc::accelerator acc; + hc::accelerator_view av = acc.get_default_view(); + av.copy( src , dst , n); +} + +DeepCopy::DeepCopy( const Kokkos::Experimental::ROCm & instance , void * dst , const void * src , size_t n ) +{ + hc::accelerator acc; + hc::accelerator_view av = acc.get_default_view(); + av.copy( src , dst , n); +} + +DeepCopy::DeepCopy( const Kokkos::Experimental::ROCm & instance , void * dst , const void * src , size_t n ) +{ + hc::accelerator acc; + hc::accelerator_view av = acc.get_default_view(); + av.copy( src , dst , n); +} + +DeepCopy::DeepCopy( const Kokkos::Experimental::ROCm & instance , void * dst , const void * src , size_t n ) +{ + hc::accelerator acc; + hc::accelerator_view av = acc.get_default_view(); + av.copy( src , dst , n); +} + + + +DeepCopy::DeepCopy( void * dst , const void * src , size_t n ) +{ + hc::accelerator acc; + hc::accelerator_view av = acc.get_default_view(); + av.copy( src , dst , n); +} + + +DeepCopy::DeepCopy( void * dst , const void * src , size_t n ) +{ + hc::accelerator acc; + hc::accelerator_view av = acc.get_default_view(); + av.copy( src , dst , n); +} + +DeepCopy::DeepCopy( void * dst , const void * src , size_t n ) +{ + hc::accelerator acc; + hc::accelerator_view av = acc.get_default_view(); + av.copy( src , dst , n); +} + +DeepCopy::DeepCopy( const Kokkos::Experimental::ROCm & instance , void * dst , const void * src , size_t n ) +{ + hc::accelerator acc; + hc::accelerator_view av = acc.get_default_view(); + av.copy( src , dst , n); +} + +DeepCopy::DeepCopy( const Kokkos::Experimental::ROCm & instance , void * dst , const void * src , size_t n ) +{ + hc::accelerator acc; + hc::accelerator_view av = acc.get_default_view(); + av.copy( src , dst , n); +} + +DeepCopy::DeepCopy( const Kokkos::Experimental::ROCm & instance , void * dst , const void * src , size_t n ) +{ + hc::accelerator acc; + hc::accelerator_view av = acc.get_default_view(); + av.copy( src , dst , n); +} + + +hc::completion_future DeepCopyAsyncROCm( void * dst , const void * src , size_t n) { + hc::accelerator acc; + hc::accelerator_view av = acc.get_default_view(); + return(av.copy_async( src , dst , n)); +} + +} // namespace Impl +} // namespace Kokkos + +/*--------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------*/ + + +namespace Kokkos { + +void Experimental::ROCmSpace::access_error() +{ + const std::string msg("Kokkos::Experimental::ROCmSpace::access_error attempt to execute Experimental::ROCm function from non-ROCm space" ); + Kokkos::Impl::throw_runtime_exception( msg ); +} + +void Experimental::ROCmSpace::access_error( const void * const ) +{ + const std::string msg("Kokkos::Experimental::ROCmSpace::access_error attempt to execute Experimental::ROCm function from non-ROCm space" ); + Kokkos::Impl::throw_runtime_exception( msg ); +} + +} // namespace Kokkos + +/*--------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------*/ + +namespace Kokkos { +namespace Experimental { + +ROCmSpace::ROCmSpace() + : m_device( ROCm().rocm_device() ) +{ +} + +ROCmHostPinnedSpace::ROCmHostPinnedSpace() +{ +} + +void * ROCmSpace::allocate( const size_t arg_alloc_size ) const +{ + void * ptr = Kokkos::Impl::rocm_device_allocate( arg_alloc_size ); + return ptr ; +} + +void * Experimental::ROCmHostPinnedSpace::allocate( const size_t arg_alloc_size ) const +{ + void * ptr = Kokkos::Impl::rocm_hostpinned_allocate( arg_alloc_size ); + return ptr ; +} + +void ROCmSpace::deallocate( void * const arg_alloc_ptr , const size_t /* arg_alloc_size */ ) const +{ + Kokkos::Impl::rocm_device_free(arg_alloc_ptr); +} + +void Experimental::ROCmHostPinnedSpace::deallocate( void * const arg_alloc_ptr , const size_t /* arg_alloc_size */ ) const +{ + Kokkos::Impl::rocm_device_free(arg_alloc_ptr); +} + +} // namespace Experimental +} // namespace Kokkos + +//---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- + +namespace Kokkos { +namespace Impl { + +SharedAllocationRecord< void , void > +SharedAllocationRecord< Kokkos::Experimental::ROCmSpace , void >::s_root_record ; + +SharedAllocationRecord< void , void > +SharedAllocationRecord< Kokkos::Experimental::ROCmHostPinnedSpace , void >::s_root_record ; + + +std::string +SharedAllocationRecord< Kokkos::Experimental::ROCmSpace , void >::get_label() const +{ + SharedAllocationHeader header ; + + Kokkos::Impl::DeepCopy< Kokkos::HostSpace , Kokkos::Experimental::ROCmSpace >( & header , RecordBase::head() , sizeof(SharedAllocationHeader) ); + + return std::string( header.m_label ); +} + +std::string +SharedAllocationRecord< Kokkos::Experimental::ROCmHostPinnedSpace , void >::get_label() const +{ + return std::string( RecordBase::head()->m_label ); +} + +SharedAllocationRecord< Kokkos::Experimental::ROCmSpace , void > * +SharedAllocationRecord< Kokkos::Experimental::ROCmSpace , void >:: +allocate( const Kokkos::Experimental::ROCmSpace & arg_space + , const std::string & arg_label + , const size_t arg_alloc_size + ) +{ + return new SharedAllocationRecord( arg_space , arg_label , arg_alloc_size ); +} + +SharedAllocationRecord< Kokkos::Experimental::ROCmHostPinnedSpace , void > * +SharedAllocationRecord< Kokkos::Experimental::ROCmHostPinnedSpace , void >:: +allocate( const Kokkos::Experimental::ROCmHostPinnedSpace & arg_space + , const std::string & arg_label + , const size_t arg_alloc_size + ) +{ + return new SharedAllocationRecord( arg_space , arg_label , arg_alloc_size ); +} + +void +SharedAllocationRecord< Kokkos::Experimental::ROCmSpace , void >:: +deallocate( SharedAllocationRecord< void , void > * arg_rec ) +{ + delete static_cast(arg_rec); +} + +void +SharedAllocationRecord< Kokkos::Experimental::ROCmHostPinnedSpace , void >:: +deallocate( SharedAllocationRecord< void , void > * arg_rec ) +{ + delete static_cast(arg_rec); +} + +SharedAllocationRecord< Kokkos::Experimental::ROCmSpace , void >:: +~SharedAllocationRecord() +{ + #if defined(KOKKOS_ENABLE_PROFILING) + if(Kokkos::Profiling::profileLibraryLoaded()) { + + SharedAllocationHeader header ; + Kokkos::Impl::DeepCopy( & header , RecordBase::m_alloc_ptr , sizeof(SharedAllocationHeader) ); + + Kokkos::Profiling::deallocateData( + Kokkos::Profiling::SpaceHandle(Kokkos::Experimental::ROCmSpace::name()),header.m_label, + data(),size()); + } + #endif + + m_space.deallocate( SharedAllocationRecord< void , void >::m_alloc_ptr + , SharedAllocationRecord< void , void >::m_alloc_size + ); +} + +SharedAllocationRecord< Kokkos::Experimental::ROCmHostPinnedSpace , void >:: +~SharedAllocationRecord() +{ + #if defined(KOKKOS_ENABLE_PROFILING) + if(Kokkos::Profiling::profileLibraryLoaded()) { + Kokkos::Profiling::deallocateData( + Kokkos::Profiling::SpaceHandle(Kokkos::Experimental::ROCmHostPinnedSpace::name()),RecordBase::m_alloc_ptr->m_label, + data(),size()); + } + #endif + + m_space.deallocate( SharedAllocationRecord< void , void >::m_alloc_ptr + , SharedAllocationRecord< void , void >::m_alloc_size + ); +} + +SharedAllocationRecord< Kokkos::Experimental::ROCmSpace , void >:: +SharedAllocationRecord( const Kokkos::Experimental::ROCmSpace & arg_space + , const std::string & arg_label + , const size_t arg_alloc_size + , const SharedAllocationRecord< void , void >::function_type arg_dealloc + ) + // Pass through allocated [ SharedAllocationHeader , user_memory ] + // Pass through deallocation function + : SharedAllocationRecord< void , void > + ( & SharedAllocationRecord< Kokkos::Experimental::ROCmSpace , void >::s_root_record + , reinterpret_cast( arg_space.allocate( sizeof(SharedAllocationHeader) + arg_alloc_size ) ) + , sizeof(SharedAllocationHeader) + arg_alloc_size + , arg_dealloc + ) + , m_space( arg_space ) +{ + #if defined(KOKKOS_ENABLE_PROFILING) + if(Kokkos::Profiling::profileLibraryLoaded()) { + Kokkos::Profiling::allocateData(Kokkos::Profiling::SpaceHandle(arg_space.name()),arg_label,data(),arg_alloc_size); + } + #endif + + SharedAllocationHeader header ; + + // Fill in the Header information + header.m_record = static_cast< SharedAllocationRecord< void , void > * >( this ); + + strncpy( header.m_label + , arg_label.c_str() + , SharedAllocationHeader::maximum_label_length + ); + + // Copy to device memory + Kokkos::Impl::DeepCopy( RecordBase::m_alloc_ptr , & header , sizeof(SharedAllocationHeader) ); +} + +SharedAllocationRecord< Kokkos::Experimental::ROCmHostPinnedSpace , void >:: +SharedAllocationRecord( const Kokkos::Experimental::ROCmHostPinnedSpace & arg_space + , const std::string & arg_label + , const size_t arg_alloc_size + , const SharedAllocationRecord< void , void >::function_type arg_dealloc + ) + // Pass through allocated [ SharedAllocationHeader , user_memory ] + // Pass through deallocation function + : SharedAllocationRecord< void , void > + ( & SharedAllocationRecord< Kokkos::Experimental::ROCmHostPinnedSpace , void >::s_root_record + , reinterpret_cast( arg_space.allocate( sizeof(SharedAllocationHeader) + arg_alloc_size ) ) + , sizeof(SharedAllocationHeader) + arg_alloc_size + , arg_dealloc + ) + , m_space( arg_space ) +{ + #if defined(KOKKOS_ENABLE_PROFILING) + if(Kokkos::Profiling::profileLibraryLoaded()) { + Kokkos::Profiling::allocateData(Kokkos::Profiling::SpaceHandle(arg_space.name()),arg_label,data(),arg_alloc_size); + } + #endif + // Fill in the Header information, directly accessible via host pinned memory + + RecordBase::m_alloc_ptr->m_record = this ; + + strncpy( RecordBase::m_alloc_ptr->m_label + , arg_label.c_str() + , SharedAllocationHeader::maximum_label_length + ); +} + +//---------------------------------------------------------------------------- + +void * SharedAllocationRecord< Kokkos::Experimental::ROCmSpace , void >:: +allocate_tracked( const Kokkos::Experimental::ROCmSpace & arg_space + , const std::string & arg_alloc_label + , const size_t arg_alloc_size ) +{ + if ( ! arg_alloc_size ) return (void *) 0 ; + + SharedAllocationRecord * const r = + allocate( arg_space , arg_alloc_label , arg_alloc_size ); + + RecordBase::increment( r ); + + return r->data(); +} + +void SharedAllocationRecord< Kokkos::Experimental::ROCmSpace , void >:: +deallocate_tracked( void * const arg_alloc_ptr ) +{ + if ( arg_alloc_ptr != 0 ) { + SharedAllocationRecord * const r = get_record( arg_alloc_ptr ); + + RecordBase::decrement( r ); + } +} + +void * SharedAllocationRecord< Kokkos::Experimental::ROCmSpace , void >:: +reallocate_tracked( void * const arg_alloc_ptr + , const size_t arg_alloc_size ) +{ + SharedAllocationRecord * const r_old = get_record( arg_alloc_ptr ); + SharedAllocationRecord * const r_new = allocate( r_old->m_space , r_old->get_label() , arg_alloc_size ); + + Kokkos::Impl::DeepCopy( r_new->data() , r_old->data() + , std::min( r_old->size() , r_new->size() ) ); + + RecordBase::increment( r_new ); + RecordBase::decrement( r_old ); + + return r_new->data(); +} + +#if 0 +void * SharedAllocationRecord< Kokkos::Experimental::ROCmHostPinnedSpace , void >:: +allocate_tracked( const Kokkos::Experimental::ROCmHostPinnedSpace & arg_space + , const std::string & arg_alloc_label + , const size_t arg_alloc_size ) +{ + if ( ! arg_alloc_size ) return (void *) 0 ; + + SharedAllocationRecord * const r = + allocate( arg_space , arg_alloc_label , arg_alloc_size ); + + RecordBase::increment( r ); + + return r->data(); +} + +void SharedAllocationRecord< Kokkos::Experimental::ROCmHostPinnedSpace , void >:: +deallocate_tracked( void * const arg_alloc_ptr ) +{ + if ( arg_alloc_ptr != 0 ) { + SharedAllocationRecord * const r = get_record( arg_alloc_ptr ); + + RecordBase::decrement( r ); + } +} + +void * SharedAllocationRecord< Kokkos::Experimental::ROCmHostPinnedSpace , void >:: +reallocate_tracked( void * const arg_alloc_ptr + , const size_t arg_alloc_size ) +{ + SharedAllocationRecord * const r_old = get_record( arg_alloc_ptr ); + SharedAllocationRecord * const r_new = allocate( r_old->m_space , r_old->get_label() , arg_alloc_size ); + + Kokkos::Impl::DeepCopy( r_new->data() , r_old->data() + , std::min( r_old->size() , r_new->size() ) ); + + RecordBase::increment( r_new ); + RecordBase::decrement( r_old ); + + return r_new->data(); +} +#endif + +//---------------------------------------------------------------------------- + +SharedAllocationRecord< Kokkos::Experimental::ROCmSpace , void > * +SharedAllocationRecord< Kokkos::Experimental::ROCmSpace , void >::get_record( void * alloc_ptr ) +{ + using Header = SharedAllocationHeader ; + using RecordBase = SharedAllocationRecord< void , void > ; + using RecordROCm = SharedAllocationRecord< Kokkos::Experimental::ROCmSpace , void > ; + +#if 0 + // Copy the header from the allocation + Header head ; + + Header const * const head_rocm = alloc_ptr ? Header::get_header( alloc_ptr ) : (Header*) 0 ; + + if ( alloc_ptr ) { + Kokkos::Impl::DeepCopy( & head , head_rocm , sizeof(SharedAllocationHeader) ); + } + + RecordROCm * const record = alloc_ptr ? static_cast< RecordROCm * >( head.m_record ) : (RecordROCm *) 0 ; + + if ( ! alloc_ptr || record->m_alloc_ptr != head_rocm ) { + Kokkos::Impl::throw_runtime_exception( std::string("Kokkos::Impl::SharedAllocationRecord< Kokkos::Experimental::ROCmSpace , void >::get_record ERROR" ) ); + } + +#else + + // Iterate the list to search for the record among all allocations + // requires obtaining the root of the list and then locking the list. + + RecordROCm * const record = static_cast< RecordROCm * >( RecordBase::find( & s_root_record , alloc_ptr ) ); + + if ( record == 0 ) { + Kokkos::Impl::throw_runtime_exception( std::string("Kokkos::Impl::SharedAllocationRecord< Kokkos::Experimental::ROCmSpace , void >::get_record ERROR" ) ); + } + +#endif + + return record ; +} + +#if 0 +SharedAllocationRecord< Kokkos::Experimental::ROCmHostPinnedSpace , void > * +SharedAllocationRecord< Kokkos::Experimental::ROCmHostPinnedSpace , void >::get_record( void * alloc_ptr ) +{ + using Header = SharedAllocationHeader ; + using RecordROCm = SharedAllocationRecord< Kokkos::Experimental::ROCmHostPinnedSpace , void > ; + + Header * const h = alloc_ptr ? reinterpret_cast< Header * >( alloc_ptr ) - 1 : (Header *) 0 ; + + if ( ! alloc_ptr || h->m_record->m_alloc_ptr != h ) { + Kokkos::Impl::throw_runtime_exception( std::string("Kokkos::Impl::SharedAllocationRecord< Kokkos::Experimental::ROCmHostPinnedSpace , void >::get_record ERROR" ) ); + } + + return static_cast< RecordROCm * >( h->m_record ); +} +#endif + +// Iterate records to print orphaned memory ... +void +SharedAllocationRecord< Kokkos::Experimental::ROCmSpace , void >:: +print_records( std::ostream & s , const Kokkos::Experimental::ROCmSpace & space , bool detail ) +{ + SharedAllocationRecord< void , void > * r = & s_root_record ; + + char buffer[256] ; + + SharedAllocationHeader head ; + + if ( detail ) { + do { + if ( r->m_alloc_ptr ) { + Kokkos::Impl::DeepCopy( & head , r->m_alloc_ptr , sizeof(SharedAllocationHeader) ); + } + else { + head.m_label[0] = 0 ; + } + + //Formatting dependent on sizeof(uintptr_t) + const char * format_string; + + if (sizeof(uintptr_t) == sizeof(unsigned long)) { + format_string = "ROCm addr( 0x%.12lx ) list( 0x%.12lx 0x%.12lx ) extent[ 0x%.12lx + %.8ld ] count(%d) dealloc(0x%.12lx) %s\n"; + } + else if (sizeof(uintptr_t) == sizeof(unsigned long long)) { + format_string = "ROCm addr( 0x%.12llx ) list( 0x%.12llx 0x%.12llx ) extent[ 0x%.12llx + %.8ld ] count(%d) dealloc(0x%.12llx) %s\n"; + } + + snprintf( buffer , 256 + , format_string + , reinterpret_cast( r ) + , reinterpret_cast( r->m_prev ) + , reinterpret_cast( r->m_next ) + , reinterpret_cast( r->m_alloc_ptr ) + , r->m_alloc_size + , r->m_count + , reinterpret_cast( r->m_dealloc ) + , head.m_label + ); + std::cout << buffer ; + r = r->m_next ; + } while ( r != & s_root_record ); + } + else { + do { + if ( r->m_alloc_ptr ) { + + Kokkos::Impl::DeepCopy( & head , r->m_alloc_ptr , sizeof(SharedAllocationHeader) ); + + //Formatting dependent on sizeof(uintptr_t) + const char * format_string; + + if (sizeof(uintptr_t) == sizeof(unsigned long)) { + format_string = "ROCm [ 0x%.12lx + %ld ] %s\n"; + } + else if (sizeof(uintptr_t) == sizeof(unsigned long long)) { + format_string = "ROCm [ 0x%.12llx + %ld ] %s\n"; + } + + snprintf( buffer , 256 + , format_string + , reinterpret_cast< uintptr_t >( r->data() ) + , r->size() + , head.m_label + ); + } + else { + snprintf( buffer , 256 , "ROCm [ 0 + 0 ]\n" ); + } + std::cout << buffer ; + r = r->m_next ; + } while ( r != & s_root_record ); + } +} +#if 0 +void +SharedAllocationRecord< Kokkos::Experimental::ROCmHostPinnedSpace , void >:: +print_records( std::ostream & s , const Kokkos::Experimental::ROCmHostPinnedSpace & space , bool detail ) +{ + SharedAllocationRecord< void , void >::print_host_accessible_records( s , "ROCmHostPinned" , & s_root_record , detail ); +} +#endif + +} // namespace Impl +} // namespace Kokkos + +/*--------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------*/ +namespace Kokkos { +namespace { +#if 0 + KOKKOS_INLINE_FUNCTION void init_lock_array_kernel_atomic() { + unsigned i = tindex()*team_size() + lindex(); + + if(i>>(); + init_lock_array_kernel_scratch_threadid<<<(Kokkos::Experimental::ROCm::concurrency()+255)/256,256>>>(Kokkos::Experimental::ROCm::concurrency()); + } +} +#endif + +void* rocm_resize_scratch_space(size_t bytes, bool force_shrink) { + static void* ptr = NULL; + static size_t current_size = 0; + if(current_size == 0) { + current_size = bytes; + ptr = Kokkos::kokkos_malloc("ROCmSpace::ScratchMemory",current_size); + } + if(bytes > current_size) { + current_size = bytes; + ptr = Kokkos::kokkos_realloc(ptr,current_size); + } + if((bytes < current_size) && (force_shrink)) { + current_size = bytes; + Kokkos::kokkos_free(ptr); + ptr = Kokkos::kokkos_malloc("ROCmSpace::ScratchMemory",current_size); + } + return ptr; +} + +} +} + +#endif // KOKKOS_ENABLE_ROCM + diff --git a/lib/kokkos/core/src/ROCm/Kokkos_ROCm_Task.cpp b/lib/kokkos/core/src/ROCm/Kokkos_ROCm_Task.cpp new file mode 100644 index 0000000000..317995c4f4 --- /dev/null +++ b/lib/kokkos/core/src/ROCm/Kokkos_ROCm_Task.cpp @@ -0,0 +1,174 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include + +#if defined( KOKKOS_ENABLE_ROCM ) && defined( KOKKOS_ENABLE_TASKDAG ) + +#include + +//---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- + +namespace Kokkos { +namespace Impl { + +template class TaskQueue< Kokkos::Experimental::ROCm > ; + + +//---------------------------------------------------------------------------- +KOKKOS_INLINE_FUNCTION +void TaskQueueSpecialization< Kokkos::Experimental::ROCm >::driver + ( TaskQueueSpecialization< Kokkos::Experimental::ROCm >::queue_type * const queue, + hc::tiled_index<3> threadIdx ) +{ + using Member = TaskExec< Kokkos::Experimental::ROCm > ; + using Queue = TaskQueue< Kokkos::Experimental::ROCm > ; + using task_root_type = TaskBase< void , void , void > ; + + task_root_type * const end = (task_root_type *) task_root_type::EndTag ; + + Member single_exec( 1, threadIdx ); + Member team_exec( threadIdx.tile_dim[0], threadIdx ); + + const int wavefront_lane = threadIdx.local[0] + threadIdx.local[1]* threadIdx.tile_dim[0] ; + + union { + task_root_type * ptr ; + int raw[2] ; + } task ; + + // Loop until all queues are empty and no tasks in flight + + do { + + // Each team lead attempts to acquire either a thread team task + // or collection of single thread tasks for the team. + + if ( 0 == wavefront_lane ) { + + task.ptr = 0 < *((volatile int *) & queue->m_ready_count) ? end : 0 ; + + // Loop by priority and then type + for ( int i = 0 ; i < Queue::NumQueue && end == task.ptr ; ++i ) { + for ( int j = 0 ; j < 2 && end == task.ptr ; ++j ) { + task.ptr = Queue::pop_ready_task( & queue->m_ready[i][j] ); + } + } + +#if 0 +printf("TaskQueue::driver(%d,%d) task(%lx)\n",threadIdx.z,blockIdx.x + , uintptr_t(task.ptr)); +#endif + + } + + // shuffle broadcast + + task.raw[0] = hc::__shfl( task.raw[0] , 0 ); + task.raw[1] = hc::__shfl( task.raw[1] , 0 ); + + if ( 0 == task.ptr ) break ; // 0 == queue->m_ready_count + + if ( end != task.ptr ) { + if ( task_root_type::TaskTeam == task.ptr->m_task_type ) { + // Thread Team Task + (*task.ptr->m_apply)( task.ptr , & team_exec ); + } + else if ( 0 == threadIdx.local[1] ) { + // Single Thread Task + (*task.ptr->m_apply)( task.ptr , & single_exec ); + } + + if ( 0 == wavefront_lane ) { + queue->complete( task.ptr ); + } + } + } while(1); +} +#if 0 +namespace { +KOKKOS_INLINE_FUNCTION +void rocm_task_queue_execute( TaskQueue< Kokkos::Experimental::ROCm > * queue, + hc::tiled_index<3> threadIdx ) +{ TaskQueueSpecialization< Kokkos::Experimental::ROCm >::driver( queue, threadIdx ); } + +} +#endif +void TaskQueueSpecialization< Kokkos::Experimental::ROCm >::execute + ( TaskQueue< Kokkos::Experimental::ROCm > * const queue ) +{ + const int workgroups_per_wavefront = 4 ; + const int wavefront_size = Kokkos::Impl::ROCmTraits::WavefrontSize ; + const int cu_count = Kokkos::Impl::rocm_internal_cu_count(); +// const dim3 grid( Kokkos::Impl::rocm_internal_cu_count() , 1 , 1 ); +// const dim3 block( 1 , Kokkos::Impl::ROCmTraits::WorkGroupSize , workgroups_per_wavefront ); + + + + // Query the stack size, in bytes: + // If not large enough then set the stack size, in bytes: + +// adapted from the cuda code. TODO: Not at all sure that this is the proper +// to map the cuda grid/blocks/3D tiling to HCC +#if 0 + hc::extent< 3 > flat_extent( cu_count, + wavefront_size, workgroups_per_wavefront ); + hc::tiled_extent< 3 > team_extent = flat_extent.tile(1, + wavefront_size,workgroups_per_wavefront); + + hc::parallel_for_each( team_extent , [&](hc::tiled_index<3> idx) [[hc]] + { + TaskQueueSpecialization< Kokkos::Experimental::ROCm >::driver( queue,idx ); + }).wait(); +#endif +} + + +}} /* namespace Kokkos::Impl */ + +//---------------------------------------------------------------------------- + +#endif /* #if defined( KOKKOS_ENABLE_ROCM ) && defined( KOKKOS_ENABLE_TASKDAG ) */ + + diff --git a/lib/kokkos/core/src/ROCm/Kokkos_ROCm_Task.hpp b/lib/kokkos/core/src/ROCm/Kokkos_ROCm_Task.hpp new file mode 100644 index 0000000000..16badcc1d4 --- /dev/null +++ b/lib/kokkos/core/src/ROCm/Kokkos_ROCm_Task.hpp @@ -0,0 +1,458 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#ifndef KOKKOS_IMPL_ROCM_TASK_HPP +#define KOKKOS_IMPL_ROCM_TASK_HPP + +#if defined( KOKKOS_ENABLE_TASKDAG ) + +#include + +//---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- + +namespace Kokkos { +namespace Impl { + +template< class > class TaskExec ; + +template<> +class TaskQueueSpecialization< Kokkos::Experimental::ROCm > +{ +public: + + using execution_space = Kokkos::Experimental::ROCm ; + using queue_type = Kokkos::Impl::TaskQueue< execution_space > ; + using task_base_type = Kokkos::Impl::TaskBase< execution_space , void , void > ; + using member_type = TaskExec< execution_space > ; + + // Must specify memory space + using memory_space = Kokkos::HostSpace ; + + static + void iff_single_thread_recursive_execute( queue_type * const ) {} + + KOKKOS_INLINE_FUNCTION + static void driver( queue_type * const, hc::tiled_index<3> ); + + // Must provide task queue execution function + static void execute( queue_type * const ); + + // Must provide mechanism to set function pointer in + // execution space from the host process. + template< typename FunctorType > + static + void proc_set_apply( typename TaskBase< Kokkos::Experimental::ROCm + , typename FunctorType::value_type + , FunctorType + >::function_type * ptr ) + { + using TaskType = TaskBase< Kokkos::Experimental::ROCm + , typename FunctorType::value_type + , FunctorType + > ; + hc::extent< 1 > flat_extent( 1 ); + hc::tiled_extent< 1 > team_extent = flat_extent.tile( 1); + + hc::parallel_for_each( team_extent , [&](hc::tiled_index<1> idx) [[hc]] + { + *ptr = TaskType::apply ; + }).wait(); + } +}; + +/*template<> +KOKKOS_FUNCTION +void TaskQueue::decrement( typename TaskQueue::task_root_type * +) {} +*/ +extern template class TaskQueue< Kokkos::Experimental::ROCm > ; + +//---------------------------------------------------------------------------- +/**\brief Impl::TaskExec is the TaskScheduler::member_type + * passed to tasks running in a ROCm space. + * + * ROCm thread blocks for tasking are dimensioned: + * idx.tile_dim[0] == vector length + * idx.tile_dim[1] == team size + * idx.tile_dim[2] == number of teams + * where + * idx.tile_dim[0] * idx.tile_dim[1] == WavefrontSize + * + * Both single thread and thread team tasks are run by a full ROCm warp. + * A single thread task is called by warp lane #0 and the remaining + * lanes of the warp are idle. + */ +template<> +class TaskExec< Kokkos::Experimental::ROCm > +{ +private: + + TaskExec( TaskExec && ) = delete ; + TaskExec( TaskExec const & ) = delete ; + TaskExec & operator = ( TaskExec && ) = delete ; + TaskExec & operator = ( TaskExec const & ) = delete ; + + + friend class Kokkos::Impl::TaskQueue< Kokkos::Experimental::ROCm > ; + friend class Kokkos::Impl::TaskQueueSpecialization< Kokkos::Experimental::ROCm > ; + + int m_team_size ; + hc::tiled_index<3> m_idx; + +// KOKKOS_INLINE_FUNCTION TaskExec( int arg_team_size ) //TODO: tile_dim[0] +// : m_team_size( arg_team_size ) {} + + KOKKOS_INLINE_FUNCTION TaskExec( int arg_team_size, + hc::tiled_index<3> tidx) + : m_team_size( arg_team_size), + m_idx( tidx ) {} + +public: +// const auto local = t_idx.local[0]; +// const auto global = t_idx.global[0]; +// const auto tile = t_idx.tile[0]; + + hc::tiled_index<3> idx() const { return m_idx;} + +#if defined( __HCC_ACCELERATOR__ ) + KOKKOS_INLINE_FUNCTION void team_barrier() { /* __threadfence_block(); */ } + KOKKOS_INLINE_FUNCTION int team_rank() const { return m_idx.local[1] ; } // t_idx.tile[0]; + KOKKOS_INLINE_FUNCTION int team_size() const { return m_team_size ; } +#else + KOKKOS_INLINE_FUNCTION void team_barrier() {} + KOKKOS_INLINE_FUNCTION int team_rank() const { return 0 ; } + KOKKOS_INLINE_FUNCTION int team_size() const { return 0 ; } +#endif +}; + +}} /* namespace Kokkos::Impl */ + +//---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- +namespace Kokkos { + +template +KOKKOS_INLINE_FUNCTION +Impl::TeamThreadRangeBoundariesStruct > +TeamThreadRange + ( Impl::TaskExec< Kokkos::Experimental::ROCm > & thread, const iType & count ) +{ + return Impl::TeamThreadRangeBoundariesStruct >(thread,count); +} + +template +KOKKOS_INLINE_FUNCTION +Impl::TeamThreadRangeBoundariesStruct< typename std::common_type< iType1, iType2 >::type, + Impl::TaskExec< Kokkos::Experimental::ROCm > > +TeamThreadRange + ( Impl:: TaskExec< Kokkos::Experimental::ROCm > & thread, const iType1 & begin, const iType2 & end ) +{ + typedef typename std::common_type::type iType; + return Impl::TeamThreadRangeBoundariesStruct >(thread, begin, end); +} + +template +KOKKOS_INLINE_FUNCTION +Impl::ThreadVectorRangeBoundariesStruct > +ThreadVectorRange + ( Impl::TaskExec< Kokkos::Experimental::ROCm > & thread + , const iType & count ) +{ + return Impl::ThreadVectorRangeBoundariesStruct >(thread,count); +} + +/** \brief Inter-thread parallel_for. Executes lambda(iType i) for each i=0..N-1. + * + * The range i=0..N-1 is mapped to all threads of the the calling thread team. + * This functionality requires C++11 support. +*/ +template +KOKKOS_INLINE_FUNCTION +void parallel_for + ( const Impl::TeamThreadRangeBoundariesStruct >& loop_boundaries + , const Lambda& lambda + ) +{ + for( iType i = loop_boundaries.start; i < loop_boundaries.end; i+=loop_boundaries.increment) { + lambda(i); + } +} + +// reduce across corresponding lanes between team members within workgroup +// assume stride*team_size == workgroup_size +template< typename ValueType > +KOKKOS_INLINE_FUNCTION +void strided_shfl_workgroup_reduction + (const ValueType& f(), + ValueType& val, + int team_size, + int stride) +{ + for (int lane_delta=(team_size*stride)>>1; lane_delta>=stride; lane_delta>>=1) { + f(val, Kokkos::shfl_down(val, lane_delta, team_size*stride)); + } +} + +template< typename ValueType, class JoinType > +KOKKOS_INLINE_FUNCTION +void strided_shfl_workgroup_reduction + (const JoinType& join, + ValueType& val, + int team_size, + int stride) +{ + for (int lane_delta=(team_size*stride)>>1; lane_delta>=stride; lane_delta>>=1) { + join(val, shfl_down(val, lane_delta, team_size*stride)); + } +} + +// multiple within-workgroup non-strided reductions +template< typename ValueType, class JoinType > +KOKKOS_INLINE_FUNCTION +void multi_shfl_workgroup_reduction + (const JoinType& join, + ValueType& val, + int vec_length) +{ + for (int lane_delta=vec_length>>1; lane_delta; lane_delta>>=1) { + join(val, shfl_down(val, lane_delta, vec_length)); + } +} + +// broadcast within workgroup +template< class ValueType > +KOKKOS_INLINE_FUNCTION +ValueType shfl_workgroup_broadcast + (ValueType& val, + int src_lane, + int width) +{ + return shfl(val, src_lane, width); +} + +// all-reduce across corresponding vector lanes between team members within workgroup +// assume vec_length*team_size == workgroup_size +// blockDim.x == vec_length == stride +// blockDim.y == team_size +// threadIdx.x == position in vec +// threadIdx.y == member number + +template +KOKKOS_INLINE_FUNCTION +void parallel_reduce + ( const Impl::TeamThreadRangeBoundariesStruct >& loop_boundaries + , const Lambda& lambda + , ValueType& initialized_result) +{ + int team_rank = loop_boundaries.thread.team_rank(); // member num within the team + ValueType result = initialized_result; + hc::tiled_index<3> idx = loop_boundaries.thread.idx(); + + for( iType i = loop_boundaries.start; i < loop_boundaries.end; i+=loop_boundaries.increment) { + lambda(i, result); + } + initialized_result = result; + + strided_shfl_workgroup_reduction( + [&] (ValueType& val1, const ValueType& val2) { val1 += val2; }, + initialized_result, + loop_boundaries.thread.team_size(), + idx.tile_dim[0]); + initialized_result = shfl_workgroup_broadcast( initialized_result, idx.local[0], Impl::ROCmTraits::WavefrontSize ); + +} + +template< typename iType, class Lambda, typename ValueType, class JoinType > +KOKKOS_INLINE_FUNCTION +void parallel_reduce + (const Impl::TeamThreadRangeBoundariesStruct >& loop_boundaries, + const Lambda & lambda, + const JoinType & join, + ValueType& initialized_result) +{ + hc::tiled_index<3> idx = loop_boundaries.thread.idx(); + int team_rank = loop_boundaries.thread.team_rank(); // member num within the team + ValueType result = initialized_result; + + for( iType i = loop_boundaries.start; i < loop_boundaries.end; i+=loop_boundaries.increment) { + lambda(i, result); + } + + strided_shfl_workgroup_reduction( + join, + initialized_result, + loop_boundaries.thread.team_size(), + idx.tile_dim[0]); + initialized_result = shfl_workgroup_broadcast( initialized_result, idx.local[0], Impl::ROCmTraits::WavefrontSize ); +} + +// placeholder for future function +template< typename iType, class Lambda, typename ValueType > +KOKKOS_INLINE_FUNCTION +void parallel_reduce + (const Impl::ThreadVectorRangeBoundariesStruct >& loop_boundaries, + const Lambda & lambda, + ValueType& initialized_result) +{ + ValueType result = initialized_result; + hc::tiled_index<3> idx = loop_boundaries.thread.idx(); + + for( iType i = loop_boundaries.start; i < loop_boundaries.end; i+=loop_boundaries.increment) { + lambda(i,result); + } + + initialized_result = result; + + //initialized_result = multi_shfl_workgroup_reduction( + multi_shfl_workgroup_reduction( + [&] (ValueType& val1, const ValueType& val2) { val1 += val2; }, + initialized_result, + idx.tile_dim[0]); + initialized_result = shfl_workgroup_broadcast( initialized_result, 0, idx.tile_dim[0] ); +} + +// placeholder for future function +template< typename iType, class Lambda, typename ValueType, class JoinType > +KOKKOS_INLINE_FUNCTION +void parallel_reduce + (const Impl::ThreadVectorRangeBoundariesStruct >& loop_boundaries, + const Lambda & lambda, + const JoinType & join, + ValueType& initialized_result) +{ + hc::tiled_index<3> idx = loop_boundaries.thread.idx(); + ValueType result = initialized_result; + for( iType i = loop_boundaries.start; i < loop_boundaries.end; i+=loop_boundaries.increment) { + lambda(i,result); + } + initialized_result = result; + + multi_shfl_workgroup_reduction(join, initialized_result, idx.tile_dim[0]); + initialized_result = shfl_workgroup_broadcast( initialized_result, 0, idx.tile_dim[0] ); +} + +template< typename ValueType, typename iType, class Lambda > +KOKKOS_INLINE_FUNCTION +void parallel_scan + (const Impl::TeamThreadRangeBoundariesStruct >& loop_boundaries, + const Lambda & lambda) +{ + hc::tiled_index<3> idx = loop_boundaries.thread.idx(); + ValueType accum = 0 ; + ValueType val, y, local_total; + + for( iType i = loop_boundaries.start; i < loop_boundaries.end; i+=loop_boundaries.increment) { + val = 0; + lambda(i,val,false); + + // intra-idx.tile_dim[0] exclusive scan on 'val' + // accum = accumulated, sum in total for this iteration + + // INCLUSIVE scan + for( int offset = idx.tile_dim[0] ; offset < Impl::ROCmTraits::WavefrontSize ; offset <<= 1 ) { + y = shfl_up(val, offset, Impl::ROCmTraits::WavefrontSize); + if(idx.local[1]*idx.tile_dim[0] >= offset) { val += y; } + } + + // pass accum to all threads + local_total = shfl_workgroup_broadcast(val, + idx.local[0]+Impl::ROCmTraits::WavefrontSize-idx.tile_dim[0], + Impl::ROCmTraits::WavefrontSize); + + // make EXCLUSIVE scan by shifting values over one + val = shfl_up(val, idx.tile_dim[0], Impl::ROCmTraits::WavefrontSize); + if ( idx.local[1] == 0 ) { val = 0 ; } + + val += accum; + lambda(i,val,true); + accum += local_total; + } +} + +// placeholder for future function +template< typename iType, class Lambda, typename ValueType > +KOKKOS_INLINE_FUNCTION +void parallel_scan + (const Impl::ThreadVectorRangeBoundariesStruct >& loop_boundaries, + const Lambda & lambda) +{ + hc::tiled_index<3> idx = loop_boundaries.thread.idx(); + ValueType accum = 0 ; + ValueType val, y, local_total; + + for( iType i = loop_boundaries.start; i < loop_boundaries.end; i+=loop_boundaries.increment) { + val = 0; + lambda(i,val,false); + + // intra-idx.tile_dim[0] exclusive scan on 'val' + // accum = accumulated, sum in total for this iteration + + // INCLUSIVE scan + for( int offset = 1 ; offset < idx.tile_dim[0] ; offset <<= 1 ) { + y = shfl_up(val, offset, idx.tile_dim[0]); + if(idx.local[0] >= offset) { val += y; } + } + + // pass accum to all threads + local_total = shfl_workgroup_broadcast(val, idx.tile_dim[0]-1, + idx.tile_dim[0]); + + // make EXCLUSIVE scan by shifting values over one + val = shfl_up(val, 1, idx.tile_dim[0]); + if ( idx.local[0] == 0 ) { val = 0 ; } + + val += accum; + lambda(i,val,true); + accum += local_total; + } +} + + +} /* namespace Kokkos */ +//---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- + +#endif /* #if defined( KOKKOS_ENABLE_TASKDAG ) */ +#endif /* #ifndef KOKKOS_IMPL_ROCM_TASK_HPP */ + diff --git a/lib/kokkos/core/src/ROCm/Kokkos_ROCm_Tile.hpp b/lib/kokkos/core/src/ROCm/Kokkos_ROCm_Tile.hpp new file mode 100644 index 0000000000..e1a89e3794 --- /dev/null +++ b/lib/kokkos/core/src/ROCm/Kokkos_ROCm_Tile.hpp @@ -0,0 +1,518 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include +#include +#include +#include +#include + +#if !defined( KOKKOS_ROCM_TILE_H ) +#define KOKKOS_ROCM_TILE_H + +// Macro to abstract out the enable_if craziness +#define KOKKOS_ROCM_REQUIRES(...) \ + bool KokkosROCmRequiresBool ## __LINE__ = true, typename std::enable_if::type = 0 + +// This number uniquely identifies the 1.5 release build. +#if __hcc_workweek__ > 17160 +#define ROCM15 1 +#endif + +namespace Kokkos { +namespace Impl { + +template + +#if defined(ROCM15) +using lds_t = T; +#else +// prior to 1.5, needed to decorate LDS addresses +using lds_t = __attribute__((address_space(3))) T; +#endif + +#define KOKKOS_ROCM_TILE_RESTRIC_CPU restrict(cpu, amp) + +// a set of routines to the replace the std::routines +// that will operate on address space 3 types + +#if defined(ROCM15) +// 1.5 can't use std::copy et al for LDS access, so we define our own +// set of routines +template +void rcopy(I first, I last, O out) [[hc]] +{ + while (first != last) *out++ = *first++; +} +template +void rfor_each(I first, I last, F f) [[hc]] +{ + for(;first!=last;++first) f(*first); +} + +template +void rtransform(I first, I last, O out, F f) [[hc]] +{ + while(first!=last) *out++ = f(*first++); +} +#endif + + +inline std::size_t get_max_tile_size() KOKKOS_ROCM_TILE_RESTRIC_CPU +{ + return hc::accelerator().get_max_tile_static_size() - 1024; +} + +inline std::size_t get_max_tile_thread() KOKKOS_ROCM_TILE_RESTRIC_CPU +{ + return 64; +} + +inline int next_pow_2(int x) restrict(cpu, amp) +{ + --x; + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + x |= x >> 8; + x |= x >> 16; + return x+1; +} + +template +inline std::size_t get_tile_size(std::size_t n = 1, + std::size_t team = 64, + std::size_t vector = 1) + KOKKOS_ROCM_TILE_RESTRIC_CPU +{ + const auto size = sizeof(T) * n; + const auto group_size = get_max_tile_size(); + if (size == 0 || size > group_size) return 0; + // Assume that thread size is a power of 2 + auto thread_size = std::min(team*vector,4*get_max_tile_thread()); + // ensure that we have enough tile static memory to keep + // threadsize * size elements for reductions + while(size > (group_size / thread_size) && thread_size > 2) +{ thread_size /= 2; +} + return thread_size; +} + +template +struct array_view +{ + T* x; + std::size_t n; + + array_view(T* xp, std::size_t np) [[hc]] [[cpu]] + : x(xp), n(np) + {} + + array_view(T* xp, T* yp) [[hc]] [[cpu]] + : x(xp), n(yp-xp) + {} + + T& operator[](std::size_t i) const [[hc]] [[cpu]] + { + return x[i]; + } + + std::size_t size() const [[hc]] [[cpu]] + { + return this->n; + } + + T* data() const [[hc]] [[cpu]] + { + return x; + } + + T* begin() const [[hc]] [[cpu]] + { + return x; + } + + T* end() const [[hc]] [[cpu]] + { + return x+this->size(); + } +}; + +template +struct rocm_char +{ using type=char; }; + +template +struct rocm_char +: std::add_const::type> +{}; +#if !defined(ROCM15) +// earlier compilers required explicit address space decorations +template +struct rocm_char<__attribute__((address_space(3))) T> +{ using type = __attribute__((address_space(3))) typename rocm_char::type; }; + +template +struct rocm_char +{ using type = const __attribute__((address_space(3))) typename rocm_char::type; }; +#endif + +template::type> +Char* rocm_byte_cast(T& x) restrict(cpu, amp) +{ + return reinterpret_cast(&x); +} + +template +void rocm_raw_assign(T& x, const U& y) restrict(cpu, amp) +{ + auto * src = rocm_byte_cast(y); + auto * dest = rocm_byte_cast(x); +#if defined (ROCM15) + rcopy(src, src+sizeof(T), dest); +#else + std::copy(src, src+sizeof(T), dest); +#endif +} + +template +void rocm_assign_impl(T& x, const U& y, std::true_type) restrict(cpu, amp) +{ + rocm_raw_assign(x, y); +} + +template +void rocm_assign_impl(T& x, const U& y, std::false_type) restrict(cpu, amp) +{ + x = y; +} + +// Workaround for assigning in and out of LDS memory +template +void rocm_assign(T& x, const U& y) restrict(cpu, amp) +{ + rocm_assign_impl(x, y, std::integral_constant()); +} + +// Compute the address space of tile +template +struct tile_type +{ +#if defined (ROCM15) + typedef T type; +#else + typedef __attribute__((address_space(3))) T type; +#endif +}; + +#if !defined (ROCM15) +template +void lds_for(__attribute__((address_space(3))) T& value, Body b) [[hc]] +{ + T state = value; + b(state); + value = state; +} +#endif + +template +void lds_for(T& value, Body b) [[hc]] +{ + b(value); +} + + +constexpr std::size_t get_max_tile_array_size() +{ + return 24; +} + +template +struct single_action +{ + template + void action_at(std::size_t i, Action a) [[hc]] + { + auto& value = static_cast(*this)[i]; +#if KOKKOS_ROCM_HAS_WORKAROUNDS + T state = value; + a(state); + value = state; +#else + a(value); +#endif + } + + template + void action_at(std::size_t i, std::size_t j, Action a) [[hc]] + { + static_cast(*this).action_at(i, [&](T& x) + { + static_cast(*this).action_at(j, [&](T& y) + { + a(x, y); + }); + }); + } +}; + +template +struct tile_buffer +: array_view::type>, single_action, T> +{ + typedef typename tile_type::type element_type; + typedef array_view base; + + using base::base; + + tile_buffer(element_type* xp, std::size_t np, std::size_t) [[hc]] [[cpu]] + : base(xp, np) + {} + + tile_buffer(T* xp, T* yp, std::size_t) [[hc]] [[cpu]] + : base(xp, yp) + {} +}; + +template +struct tile_buffer +{ + typedef typename tile_type::type element_type; + typedef typename tile_type::type tchar_type; + element_type* element_data; + std::size_t n, m; + + tile_buffer(element_type* xp, std::size_t np, std::size_t mp) [[hc]] [[cpu]] + : element_data(xp), n(np), m(mp) + {} + + tile_buffer(element_type* xp, element_type* yp, std::size_t mp) [[hc]] [[cpu]] + : element_data(xp), n(yp-xp), m(mp) + {} + + element_type* operator[](std::size_t i) const [[hc]] [[cpu]] + { + return element_data+i*m; + } + + template + typename Impl::enable_if< (sizeof(Q) <= 8) , void >::type + action_at(std::size_t i, Action a) [[hc]] + { + element_type* value = (*this)[i]; +#if defined (ROCM15) + a(value); +#else +#if KOKKOS_ROCM_HAS_WORKAROUNDS + if (m > get_max_tile_array_size()) return; + T state[get_max_tile_array_size()]; + // std::copy(value, value+m, state); + // Workaround for assigning from LDS memory + std::transform(value, value+m, state, [](element_type& x) + { + T result; + rocm_assign(result, x); + return result; + }); + a(state); + std::copy(state, state+m, value); +#endif +#endif + } + + template + typename Impl::enable_if< !(sizeof(Q) <= 8) , void >::type + action_at(std::size_t i, Action a) [[hc]] + { + element_type* value = (*this)[i]; +#if defined (ROCM15) + a(value); +#else +//#if KOKKOS_ROCM_HAS_WORKAROUNDS + if (m > get_max_tile_array_size()) return; + T state[get_max_tile_array_size()]; + // std::copy(value, value+m, state); + // Workaround for assigning from LDS memory + std::transform(value, value+m, state, [](element_type& x) + { + T result; + rocm_assign(result, x); + return result; + }); + a(state); + // this workaround required when T is greater than 8 bytes + tile_static char tv[64*sizeof(T)]; + size_t sT = sizeof(T); + for (int j = 0; j + void action_at(std::size_t i, std::size_t j, Action a) [[hc]] + { + this->action_at(i, [&](T* x) + { + this->action_at(j, [&](T* y) + { + a(x, y); + }); + }); + } + + std::size_t size() const [[hc]] [[cpu]] + { + return this->n; + } + + element_type* data() const [[hc]] [[cpu]] + { + return element_data; + } +}; + +// Zero initialize LDS memory +struct zero_init_f +{ + template +#if defined (ROCM15) + void operator()(T& x, std::size_t=1) const [[hc]] + { + auto * start = reinterpret_cast(&x); + for(int i=0; i(&x); + std::fill(start, start+sizeof(T), 0); + rocm_raw_assign(x, T()); + } +#endif + + template +#if defined (ROCM15) + void operator()(T* x, std::size_t size) const [[hc]] + { + rfor_each(x, x+size, *this); + } +#else + void operator()(__attribute__((address_space(3))) T* x, std::size_t size) const [[hc]] + { + std::for_each(x, x+size, *this); + } +#endif +}; + +static constexpr zero_init_f zero_init = {}; + +struct tile_desc +{ + // Number of work items, or size of extent + std::size_t elements; + // number of threads in team + std::size_t team_size; + // vector length of team + std::size_t vector_length; + // Size of tile + std::size_t tile_size; + // Size of array + std::size_t array_size; + // Number of tiles + std::size_t num_tiles; + // Per team reserved LDS memory, used for reduction + std::size_t reduce_size; + // Per team shared memory in LDS, this in addition to reduce shared mem + std::size_t shared_size; + std::size_t size; +}; + +template +tile_desc get_tile_desc(std::size_t size, + std::size_t array_size=1, + std::size_t team_size=64, + std::size_t vector_size=1, + std::size_t shared_size=0) +{ + tile_desc result; + result.elements = size; + result.array_size = array_size; + result.vector_length = vector_size; + result.team_size = team_size; + result.tile_size = get_tile_size(array_size,team_size,vector_size); + result.num_tiles = std::ceil(1.0 * size / result.tile_size); + result.reduce_size = result.tile_size * sizeof(T) * array_size; + result.shared_size = shared_size; + result.size = result.tile_size * result.num_tiles; + + return result; +} + +template::type> +hc::completion_future tile_for(tile_desc td, F f) +{ + assert(td.array_size <= get_max_tile_array_size() && "Exceed max array size"); + assert(((td.size % td.tile_size) == 0) && "Tile size must be divisible by extent"); + auto grid = hc::extent<1>(td.size).tile_with_dynamic( + td.tile_size, td.reduce_size + td.shared_size); + // grid.set_dynamic_group_segment_size(td.reduce_size + td.shared_size); + return parallel_for_each(grid, [=](hc::tiled_index<1> t_idx) [[hc]] + { +#if defined (ROCM15) + typedef T group_t; +#else + typedef __attribute__((address_space(3))) T group_t; +#endif + group_t * buffer = (group_t *)hc::get_dynamic_group_segment_base_pointer(); + tile_buffer tb(buffer, td.tile_size, td.array_size); + zero_init(tb[t_idx.local[0]], td.array_size); + f(t_idx, tb); + }); +} + +}} + +#endif diff --git a/lib/kokkos/core/src/ROCm/Kokkos_ROCm_Vectorization.hpp b/lib/kokkos/core/src/ROCm/Kokkos_ROCm_Vectorization.hpp new file mode 100644 index 0000000000..ac166f9ad8 --- /dev/null +++ b/lib/kokkos/core/src/ROCm/Kokkos_ROCm_Vectorization.hpp @@ -0,0 +1,346 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ +#ifndef KOKKOS_ROCM_VECTORIZATION_HPP +#define KOKKOS_ROCM_VECTORIZATION_HPP + +#include + +/* only compile this file if ROCM is enabled for Kokkos */ +#ifdef KOKKOS_ENABLE_ROCM + +#include + +namespace Kokkos { +using namespace hc; + +// Shuffle only makes sense on >= Fiji GPUs; it doesn't work on CPUs +// or other GPUs. We provide a generic definition (which is trivial +// and doesn't do what it claims to do) because we don't actually use +// this function unless we are on a suitable GPU, with a suitable +// Scalar type. (For example, in the mat-vec, the "ThreadsPerRow" +// internal parameter depends both on the ExecutionSpace and the Scalar type, +// and it controls whether shfl_down() gets called.) +namespace Impl { + + template< typename Scalar > + struct shfl_union { + enum {n = sizeof(Scalar)/4}; + float fval[n]; + KOKKOS_INLINE_FUNCTION + Scalar value() { + return *(Scalar*) fval; + } + KOKKOS_INLINE_FUNCTION + void operator= (Scalar& value_) { + float* const val_ptr = (float*) &value_; + for(int i=0; i + KOKKOS_INLINE_FUNCTION + Scalar shfl(const Scalar &val, const int& srcLane, const typename Impl::enable_if< (sizeof(Scalar) == 4) , int >::type& width + ) { + Scalar tmp1 = val; + float tmp = *reinterpret_cast(&tmp1); + tmp = __shfl(tmp,srcLane,width); + return *reinterpret_cast(&tmp); + } + + KOKKOS_INLINE_FUNCTION + double shfl(const double &val, const int& srcLane, const int& width) { + int lo = __double2loint(val); + int hi = __double2hiint(val); + lo = __shfl(lo,srcLane,width); + hi = __shfl(hi,srcLane,width); + return __hiloint2double(hi,lo); + } + + template + KOKKOS_INLINE_FUNCTION + Scalar shfl(const Scalar &val, const int& srcLane, const typename Impl::enable_if< (sizeof(Scalar) == 8) ,int>::type& width) { + int lo = __double2loint(*reinterpret_cast(&val)); + int hi = __double2hiint(*reinterpret_cast(&val)); + lo = __shfl(lo,srcLane,width); + hi = __shfl(hi,srcLane,width); + const double tmp = __hiloint2double(hi,lo); + return *(reinterpret_cast(&tmp)); + } + + template + KOKKOS_INLINE_FUNCTION + Scalar shfl(const Scalar &val, const int& srcLane, const typename Impl::enable_if< (sizeof(Scalar) > 8) ,int>::type& width) { + Impl::shfl_union s_val; + Impl::shfl_union r_val; + s_val = val; + + for(int i = 0; i + KOKKOS_INLINE_FUNCTION + Scalar shfl_down(const Scalar &val, const int& delta, const typename Impl::enable_if< (sizeof(Scalar) == 4) , int >::type & width) { + Scalar tmp1 = val; + float tmp = *reinterpret_cast(&tmp1); + tmp = __shfl_down(tmp,delta,width); + return *reinterpret_cast(&tmp); + } + + KOKKOS_INLINE_FUNCTION + long shfl_down(const long &val, const int& delta, const int& width) { + int lo = __long2loint(val); + int hi = __long2hiint(val); + lo = __shfl_down(lo,delta,width); + hi = __shfl_down(hi,delta,width); + return __hiloint2long(hi,lo); + } + + KOKKOS_INLINE_FUNCTION + double shfl_down(const double &val, const int& delta, const int& width) { + int lo = __double2loint(val); + int hi = __double2hiint(val); + lo = __shfl_down(lo,delta,width); + hi = __shfl_down(hi,delta,width); + return __hiloint2double(hi,lo); + } + + template + KOKKOS_INLINE_FUNCTION + Scalar shfl_down(const Scalar &val, const int& delta, const typename Impl::enable_if< (sizeof(Scalar) == 8) , int >::type & width) { + int lo = __double2loint(*reinterpret_cast(&val)); + int hi = __double2hiint(*reinterpret_cast(&val)); + lo = __shfl_down(lo,delta,width); + hi = __shfl_down(hi,delta,width); + const double tmp = __hiloint2double(hi,lo); + return *(reinterpret_cast(&tmp)); + } + + template + KOKKOS_INLINE_FUNCTION + Scalar shfl_down(const Scalar &val, const int& delta, const typename Impl::enable_if< (sizeof(Scalar) > 8) , int >::type & width) { + Impl::shfl_union s_val; + Impl::shfl_union r_val; + s_val = val; + + for(int i = 0; i + KOKKOS_INLINE_FUNCTION + Scalar shfl_up(const Scalar &val, const int& delta, const typename Impl::enable_if< (sizeof(Scalar) == 4) , int >::type & width) { + Scalar tmp1 = val; + float tmp = *reinterpret_cast(&tmp1); + tmp = __shfl_up(tmp,delta,width); + return *reinterpret_cast(&tmp); + } + + KOKKOS_INLINE_FUNCTION + double shfl_up(const double &val, const int& delta, const int& width ) { + int lo = __double2loint(val); + int hi = __double2hiint(val); + lo = __shfl_up(lo,delta,width); + hi = __shfl_up(hi,delta,width); + return __hiloint2double(hi,lo); + } + + template + KOKKOS_INLINE_FUNCTION + Scalar shfl_up(const Scalar &val, const int& delta, const typename Impl::enable_if< (sizeof(Scalar) == 8) , int >::type & width) { + int lo = __double2loint(*reinterpret_cast(&val)); + int hi = __double2hiint(*reinterpret_cast(&val)); + lo = __shfl_up(lo,delta,width); + hi = __shfl_up(hi,delta,width); + const double tmp = __hiloint2double(hi,lo); + return *(reinterpret_cast(&tmp)); + } + + template + KOKKOS_INLINE_FUNCTION + Scalar shfl_up(const Scalar &val, const int& delta, const typename Impl::enable_if< (sizeof(Scalar) > 8) , int >::type & width) { + Impl::shfl_union s_val; + Impl::shfl_union r_val; + s_val = val; + + for(int i = 0; i + inline + Scalar shfl(const Scalar &val, const int& srcLane, const int& width) { + if(width > 1) Kokkos::abort("Error: calling shfl from a device with CC<8.0."); + return val; + } + + template + inline + Scalar shfl_down(const Scalar &val, const int& delta, const int& width) { + if(width > 1) Kokkos::abort("Error: calling shfl_down from a device with CC<8.0."); + return val; + } + + template + inline + Scalar shfl_up(const Scalar &val, const int& delta, const int& width) { + if(width > 1) Kokkos::abort("Error: calling shfl_down from a device with CC<8.0."); + return val; + } +#endif + + + +} + +#endif // KOKKOS_ENABLE_ROCM +#endif diff --git a/lib/kokkos/core/src/ROCm/hc_math_std.hpp b/lib/kokkos/core/src/ROCm/hc_math_std.hpp new file mode 100644 index 0000000000..56c2e634e4 --- /dev/null +++ b/lib/kokkos/core/src/ROCm/hc_math_std.hpp @@ -0,0 +1,367 @@ +#pragma once + +#include "hc.hpp" +#include + +// Math functions with integer overloads will be converted to +// this floating point type. +#define HC_IMPLICIT_FLOAT_CONV double + +#ifdef __KALMAR_ACCELERATOR__ + +#define HC_MATH_WRAPPER_1(function, arg1) \ +template \ +inline T function(T arg1) __attribute__((hc,cpu)) { \ + return hc::precise_math::function(arg1); \ +} + +#define KALMAR_MATH_WRAPPER_1(function, arg1) HC_MATH_WRAPPER_1(function, arg1) + +#define HC_MATH_WRAPPER_FP_OVERLOAD_1(function, arg1) \ +template \ +inline \ +typename std::enable_if::value,HC_IMPLICIT_FLOAT_CONV>::type \ + function(T arg1) __attribute__((hc,cpu)) { \ + return hc::precise_math::function(static_cast(arg1)); \ +} \ +template \ +inline \ +typename std::enable_if::value,T>::type \ + function(T arg1) __attribute__((hc,cpu)) { \ + return hc::precise_math::function(arg1); \ +} + +#define KALMAR_MATH_WRAPPER_FP_OVERLOAD_1(function, arg1) HC_MATH_WRAPPER_FP_OVERLOAD_1(function, arg1) + +#define HC_MATH_WRAPPER_2(function, arg1, arg2) \ +template \ +inline T function(T arg1, T arg2) __attribute__((hc,cpu)) { \ + return hc::precise_math::function(arg1, arg2); \ +} + +#define HC_MATH_ALIAS_2(alias, function, arg1, arg2) \ +template \ +inline T alias(T arg1, T arg2) __attribute__((hc,cpu)) { \ + return hc::precise_math::function(arg1, arg2); \ +} + +#define HC_MATH_WRAPPER_3(function, arg1, arg2, arg3) \ +template \ +inline T function(T arg1, T arg2, T arg3) __attribute__((hc,cpu)) { \ + return hc::precise_math::function(arg1, arg2, arg3); \ +} + +#define HC_MATH_WRAPPER_TQ(function, arg1) \ +template \ +inline T function(Q arg1) __attribute__((hc,cpu)) { \ + return hc::precise_math::function(arg1); \ +} + +#define HC_MATH_WRAPPER_FP_OVERLOAD_TQ(function, T, arg1) \ +template \ +inline \ +typename std::enable_if::value,T>::type \ +function(Q arg1) __attribute__((hc,cpu)) { \ + return hc::precise_math::function(static_cast(arg1)); \ +}\ +template \ +inline \ +typename std::enable_if::value,T>::type \ +function(Q arg1) __attribute__((hc,cpu)) { \ + return hc::precise_math::function(arg1); \ +} + +#define HC_MATH_WRAPPER_TTQ(function, arg1, arg2) \ +template \ +inline T function(T arg1, Q arg2) __attribute__((hc,cpu)) { \ + return hc::precise_math::function(arg1, arg2); \ +} + +#define HC_MATH_WRAPPER_FP_OVERLOAD_TTQ(function, arg1, arg2) \ +template \ +inline \ +typename std::enable_if::value||std::is_integral::value,HC_IMPLICIT_FLOAT_CONV>::type \ +function(T arg1, Q arg2) __attribute__((hc,cpu)) { \ + return hc::precise_math::function(static_cast(arg1),static_cast(arg2)); \ +}\ +template \ +inline \ +typename std::enable_if::value&&std::is_floating_point::value,T>::type \ +function(T arg1, Q arg2) __attribute__((hc,cpu)) { \ + return hc::precise_math::function(arg1,arg2); \ +} + +#define HC_MATH_WRAPPER_TTTQ(function, arg1, arg2, arg3) \ +template \ +inline T function(T arg1, T arg2, Q arg3) __attribute__((hc,cpu)) { \ + return hc::precise_math::function(arg1, arg2, arg3); \ +} + +#define HC_MATH_WRAPPER_VTQQ(function, arg1, arg2, arg3) \ +template \ +inline void function(T arg1, Q arg2, Q arg3) __attribute__((hc,cpu)) { \ + hc::precise_math::function(arg1, arg2, arg3); \ +} + +#else + +#define HC_MATH_WRAPPER_1(function, arg1) \ +template \ +inline T function(T arg1) __attribute__((hc,cpu)) { \ + return std::function(arg1); \ +} + +#define KALMAR_MATH_WRAPPER_1(function, arg1) \ +template \ +inline T function(T arg1) __attribute__((hc,cpu)) { \ + return hc::precise_math::function(arg1); \ +} + +#define HC_MATH_WRAPPER_FP_OVERLOAD_1(function, arg1) \ +template \ +inline \ +typename std::enable_if::value,HC_IMPLICIT_FLOAT_CONV>::type \ + function(T arg1) __attribute__((hc,cpu)) { \ + return ::function(static_cast(arg1)); \ +} \ +template \ +inline \ +typename std::enable_if::value,T>::type \ + function(T arg1) __attribute__((hc,cpu)) { \ + return std::function(arg1); \ +} + +#define KALMAR_MATH_WRAPPER_FP_OVERLOAD_1(function, arg1) \ +template \ +inline \ +typename std::enable_if::value,HC_IMPLICIT_FLOAT_CONV>::type \ + function(T arg1) __attribute__((hc,cpu)) { \ + return hc::precise_math::function(static_cast(arg1)); \ +} \ +template \ +inline \ +typename std::enable_if::value,T>::type \ + function(T arg1) __attribute__((hc,cpu)) { \ + return hc::precise_math::function(arg1); \ +} + +#define HC_MATH_WRAPPER_2(function, arg1, arg2) \ +template \ +inline T function(T arg1, T arg2) __attribute__((hc,cpu)) { \ + return std::function(arg1, arg2); \ +} + +#define HC_MATH_ALIAS_2(alias, function, arg1, arg2) \ +template \ +inline T alias(T arg1, T arg2) __attribute__((hc,cpu)) { \ + return std::function(arg1, arg2); \ +} + +#define HC_MATH_WRAPPER_3(function, arg1, arg2, arg3) \ +template \ +inline T function(T arg1, T arg2, T arg3) __attribute__((hc,cpu)) { \ + return std::function(arg1, arg2, arg3); \ +} + +#define HC_MATH_WRAPPER_TQ(function, arg1) \ +template \ +inline T function(Q arg1) __attribute__((hc,cpu)) { \ + return std::function(arg1); \ +} + +#define HC_MATH_WRAPPER_FP_OVERLOAD_TQ(function, T, arg1) \ +template \ +inline \ +typename std::enable_if::value,T>::type \ +function(Q arg1) __attribute__((hc)) { \ + return std::function(static_cast(arg1)); \ +}\ +template \ +inline \ +typename std::enable_if::value,T>::type \ +function(Q arg1) __attribute__((hc)) { \ + return std::function(arg1); \ +} + +#define HC_MATH_WRAPPER_TTQ(function, arg1, arg2) \ +template \ +inline T function(T arg1, Q arg2) __attribute__((hc,cpu)) { \ + return std::function(arg1, arg2); \ +} + +#define HC_MATH_WRAPPER_FP_OVERLOAD_TTQ(function, arg1, arg2) \ +template \ +inline \ +typename std::enable_if::value||std::is_integral::value,HC_IMPLICIT_FLOAT_CONV>::type \ +function(T arg1, Q arg2) __attribute__((hc,cpu)) { \ + return std::function(static_cast(arg1),static_cast(arg2)); \ +}\ +template \ +inline \ +typename std::enable_if::value&&std::is_floating_point::value,T>::type \ +function(T arg1, Q arg2) __attribute__((hc,cpu)) { \ + return std::function(arg1,arg2); \ +} + +#define HC_MATH_WRAPPER_TTTQ(function, arg1, arg2, arg3) \ +template \ +inline T function(T arg1, T arg2, Q arg3) __attribute__((hc,cpu)) { \ + return std::function(arg1, arg2, arg3); \ +} + +#define HC_MATH_WRAPPER_VTQQ(function, arg1, arg2, arg3) \ +template \ +inline void function(T arg1, Q arg2, Q arg3) __attribute__((hc,cpu)) { \ + std::function(arg1, arg2, arg3); \ +} + +#endif + + +// override global math functions +namespace std { + +// following math functions are NOT available because they don't have a GPU implementation +// +// erfinv +// erfcinv +// fpclassify +// +// following math functions are NOT available because they don't have a CPU implementation +// +// cospif +// cospi +// rsqrtf +// rsqrt +// sinpif +// sinpi +// tanpi +// + +HC_MATH_WRAPPER_TQ(ilogbf, x) +HC_MATH_WRAPPER_FP_OVERLOAD_TQ(ilogb, int, x) +HC_MATH_WRAPPER_FP_OVERLOAD_TQ(isfinite, bool, x) +HC_MATH_WRAPPER_FP_OVERLOAD_TQ(isinf, bool, x) +HC_MATH_WRAPPER_FP_OVERLOAD_TQ(isnan, bool, x) +HC_MATH_WRAPPER_FP_OVERLOAD_TQ(isnormal, bool, x) +HC_MATH_WRAPPER_TQ(nanf, tagp) +HC_MATH_WRAPPER_TQ(nan, tagp) +//HC_MATH_WRAPPER_TQ(signbitf, x) +HC_MATH_WRAPPER_TQ(signbit, x) +HC_MATH_WRAPPER_TTQ(frexpf, x, exp) +HC_MATH_WRAPPER_TTQ(frexp, x, exp) +HC_MATH_WRAPPER_TTQ(ldexpf, x, exp) +HC_MATH_WRAPPER_TTQ(ldexp, x, exp) +HC_MATH_WRAPPER_TTQ(lgammaf, x, exp) +HC_MATH_WRAPPER_TTQ(lgamma, x, exp) +HC_MATH_WRAPPER_TTQ(modff, x, exp) +HC_MATH_WRAPPER_TTQ(modf, x, exp) +HC_MATH_WRAPPER_TTQ(scalbnf, x, exp) +HC_MATH_WRAPPER_TTQ(scalbn, x, exp) +HC_MATH_WRAPPER_TTTQ(remquof, x, y, quo) +HC_MATH_WRAPPER_TTTQ(remquo, x, y, quo) +HC_MATH_WRAPPER_VTQQ(sincosf, x, s, c) +HC_MATH_WRAPPER_VTQQ(sincos, x, s, c) + +HC_MATH_WRAPPER_1(acosf, x) +HC_MATH_WRAPPER_FP_OVERLOAD_1(acos, x) +HC_MATH_WRAPPER_1(acoshf, x) +HC_MATH_WRAPPER_FP_OVERLOAD_1(acosh, x) +HC_MATH_WRAPPER_1(asinf, x) +HC_MATH_WRAPPER_FP_OVERLOAD_1(asin, x) +HC_MATH_WRAPPER_1(asinhf, x) +HC_MATH_WRAPPER_FP_OVERLOAD_1(asinh, x) +HC_MATH_WRAPPER_1(atanf, x) +HC_MATH_WRAPPER_FP_OVERLOAD_1(atan, x) +HC_MATH_WRAPPER_1(atanhf, x) +HC_MATH_WRAPPER_FP_OVERLOAD_1(atanh, x) +HC_MATH_WRAPPER_2(atan2f, x, y) +HC_MATH_WRAPPER_2(atan2, x, y) +HC_MATH_WRAPPER_1(cbrtf, x) +HC_MATH_WRAPPER_FP_OVERLOAD_1(cbrt, x) +HC_MATH_WRAPPER_1(ceilf, x) +HC_MATH_WRAPPER_FP_OVERLOAD_1(ceil, x) +HC_MATH_WRAPPER_2(copysignf, x, y) +HC_MATH_WRAPPER_2(copysign, x, y) +HC_MATH_WRAPPER_1(cosf, x) +HC_MATH_WRAPPER_FP_OVERLOAD_1(cos, x) +HC_MATH_WRAPPER_1(coshf, x) +HC_MATH_WRAPPER_FP_OVERLOAD_1(cosh, x) +KALMAR_MATH_WRAPPER_1(cospif, x) +KALMAR_MATH_WRAPPER_FP_OVERLOAD_1(cospi, x) +HC_MATH_WRAPPER_1(erff, x) +HC_MATH_WRAPPER_FP_OVERLOAD_1(erf, x) +HC_MATH_WRAPPER_1(erfcf, x) +HC_MATH_WRAPPER_FP_OVERLOAD_1(erfc, x) +HC_MATH_WRAPPER_1(expf, x) +HC_MATH_WRAPPER_FP_OVERLOAD_1(exp, x) +HC_MATH_WRAPPER_1(exp2f, x) +HC_MATH_WRAPPER_FP_OVERLOAD_1(exp2, x) +HC_MATH_WRAPPER_1(exp10f, x) +HC_MATH_WRAPPER_FP_OVERLOAD_1(exp10, x) +HC_MATH_WRAPPER_1(expm1f, x) +HC_MATH_WRAPPER_FP_OVERLOAD_1(expm1, x) +HC_MATH_WRAPPER_1(fabsf, x) +HC_MATH_WRAPPER_FP_OVERLOAD_1(fabs, x) +HC_MATH_WRAPPER_2(fdimf, x, y) +HC_MATH_WRAPPER_2(fdim, x, y) +HC_MATH_WRAPPER_1(floorf, x) +HC_MATH_WRAPPER_FP_OVERLOAD_1(floor, x) +HC_MATH_WRAPPER_3(fmaf, x, y, z) +HC_MATH_WRAPPER_3(fma, x, y, z) +HC_MATH_WRAPPER_2(fmaxf, x, y) +HC_MATH_WRAPPER_2(fmax, x, y) +HC_MATH_WRAPPER_2(fminf, x, y) +HC_MATH_WRAPPER_2(fmin, x, y) +HC_MATH_WRAPPER_2(fmodf, x, y) +HC_MATH_WRAPPER_2(fmod, x, y) +HC_MATH_WRAPPER_2(hypotf, x, y) +HC_MATH_WRAPPER_2(hypot, x, y) +HC_MATH_WRAPPER_1(logf, x) +HC_MATH_WRAPPER_FP_OVERLOAD_1(log, x) +HC_MATH_WRAPPER_1(log10f, x) +HC_MATH_WRAPPER_FP_OVERLOAD_1(log10, x) +HC_MATH_WRAPPER_1(log2f, x) +HC_MATH_WRAPPER_FP_OVERLOAD_1(log2, x) +HC_MATH_WRAPPER_1(log1pf, x) +HC_MATH_WRAPPER_FP_OVERLOAD_1(log1p, x) +HC_MATH_WRAPPER_1(logbf, x) +HC_MATH_WRAPPER_FP_OVERLOAD_1(logb, x) +HC_MATH_WRAPPER_1(nearbyintf, x) +HC_MATH_WRAPPER_FP_OVERLOAD_1(nearbyint, x) +HC_MATH_WRAPPER_2(nextafterf, x, y) +HC_MATH_WRAPPER_2(nextafter, x, y) +HC_MATH_WRAPPER_2(powf, x, y) +HC_MATH_WRAPPER_FP_OVERLOAD_TTQ(pow,x,y) +//HC_MATH_WRAPPER_1(rcbrtf, x) +//HC_MATH_WRAPPER_1(rcbrt, x) +HC_MATH_WRAPPER_2(remainderf, x, y) +HC_MATH_WRAPPER_2(remainder, x, y) +HC_MATH_WRAPPER_1(roundf, x) +HC_MATH_WRAPPER_FP_OVERLOAD_1(round, x) +KALMAR_MATH_WRAPPER_1(rsqrtf, x) +KALMAR_MATH_WRAPPER_FP_OVERLOAD_1(rsqrt, x) +HC_MATH_WRAPPER_2(scalbf, x, exp) +HC_MATH_WRAPPER_2(scalb, x, exp) +HC_MATH_WRAPPER_1(sinf, x) +HC_MATH_WRAPPER_FP_OVERLOAD_1(sin, x) +HC_MATH_WRAPPER_1(sinhf, x) +HC_MATH_WRAPPER_FP_OVERLOAD_1(sinh, x) +KALMAR_MATH_WRAPPER_1(sinpif, x) +KALMAR_MATH_WRAPPER_FP_OVERLOAD_1(sinpi, x) +HC_MATH_WRAPPER_1(sqrtf, x) +HC_MATH_WRAPPER_FP_OVERLOAD_1(sqrt, x) +HC_MATH_WRAPPER_1(tgammaf, x) +HC_MATH_WRAPPER_FP_OVERLOAD_1(tgamma, x) +HC_MATH_WRAPPER_1(tanf, x) +HC_MATH_WRAPPER_FP_OVERLOAD_1(tan, x) +HC_MATH_WRAPPER_1(tanhf, x) +HC_MATH_WRAPPER_FP_OVERLOAD_1(tanh, x) +HC_MATH_WRAPPER_1(truncf, x) +HC_MATH_WRAPPER_FP_OVERLOAD_1(trunc, x) + +//HC_MATH_ALIAS_2(min, fmin, x, y) +//HC_MATH_ALIAS_2(max, fmax, x, y) + +} // namespace + diff --git a/lib/kokkos/core/src/impl/Kokkos_Atomic_Compare_Exchange_Strong.hpp b/lib/kokkos/core/src/impl/Kokkos_Atomic_Compare_Exchange_Strong.hpp index 5b894b037b..49fca9c855 100644 --- a/lib/kokkos/core/src/impl/Kokkos_Atomic_Compare_Exchange_Strong.hpp +++ b/lib/kokkos/core/src/impl/Kokkos_Atomic_Compare_Exchange_Strong.hpp @@ -125,6 +125,7 @@ T atomic_compare_exchange( volatile T * const dest , const T & compare , //---------------------------------------------------------------------------- // GCC native CAS supports int, long, unsigned int, unsigned long. // Intel native CAS support int and long with the same interface as GCC. +#if !defined(KOKKOS_ENABLE_ROCM_ATOMICS) #if !defined(__CUDA_ARCH__) || defined(KOKKOS_IMPL_CUDA_CLANG_WORKAROUND) #if defined(KOKKOS_ENABLE_GNU_ATOMICS) || defined(KOKKOS_ENABLE_INTEL_ATOMICS) @@ -280,6 +281,7 @@ T atomic_compare_exchange( volatile T * const dest, const T compare, const T val #endif #endif +#endif // !defined ROCM_ATOMICS template KOKKOS_INLINE_FUNCTION diff --git a/lib/kokkos/core/src/impl/Kokkos_Atomic_Fetch_Add.hpp b/lib/kokkos/core/src/impl/Kokkos_Atomic_Fetch_Add.hpp index 084c55efed..2af1737c31 100644 --- a/lib/kokkos/core/src/impl/Kokkos_Atomic_Fetch_Add.hpp +++ b/lib/kokkos/core/src/impl/Kokkos_Atomic_Fetch_Add.hpp @@ -158,6 +158,7 @@ T atomic_fetch_add( volatile T * const dest , #endif #endif //---------------------------------------------------------------------------- +#if !defined(KOKKOS_ENABLE_ROCM_ATOMICS) #if !defined(__CUDA_ARCH__) || defined(KOKKOS_IMPL_CUDA_CLANG_WORKAROUND) #if defined(KOKKOS_ENABLE_GNU_ATOMICS) || defined(KOKKOS_ENABLE_INTEL_ATOMICS) @@ -355,6 +356,7 @@ T atomic_fetch_add( volatile T * const dest , const T val ) #endif #endif +#endif // !defined ROCM_ATOMICS //---------------------------------------------------------------------------- // Simpler version of atomic_fetch_add without the fetch diff --git a/lib/kokkos/core/src/impl/Kokkos_Atomic_Fetch_Sub.hpp b/lib/kokkos/core/src/impl/Kokkos_Atomic_Fetch_Sub.hpp index 038cc13e9a..b7c14052eb 100644 --- a/lib/kokkos/core/src/impl/Kokkos_Atomic_Fetch_Sub.hpp +++ b/lib/kokkos/core/src/impl/Kokkos_Atomic_Fetch_Sub.hpp @@ -135,6 +135,7 @@ T atomic_fetch_sub( volatile T * const dest , #endif #endif //---------------------------------------------------------------------------- +#if !defined(KOKKOS_ENABLE_ROCM_ATOMICS) #if !defined(__CUDA_ARCH__) || defined(KOKKOS_IMPL_CUDA_CLANG_WORKAROUND) #if defined(KOKKOS_ENABLE_GNU_ATOMICS) || defined(KOKKOS_ENABLE_INTEL_ATOMICS) @@ -263,6 +264,8 @@ T atomic_fetch_sub( volatile T * const dest , const T val ) #endif #endif +#endif // !defined ROCM_ATOMICS + // Simpler version of atomic_fetch_sub without the fetch template KOKKOS_INLINE_FUNCTION diff --git a/lib/kokkos/core/src/impl/Kokkos_Atomic_Generic.hpp b/lib/kokkos/core/src/impl/Kokkos_Atomic_Generic.hpp index 65578156d5..f47ba1a98a 100644 --- a/lib/kokkos/core/src/impl/Kokkos_Atomic_Generic.hpp +++ b/lib/kokkos/core/src/impl/Kokkos_Atomic_Generic.hpp @@ -238,7 +238,7 @@ T atomic_fetch_oper( const Oper& op, volatile T * const dest , *dest = Oper::apply(return_val, val); Impl::unlock_address_host_space( (void*) dest ); return return_val; -#else +#elif defined(KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_CUDA) // This is a way to (hopefully) avoid dead lock in a warp T return_val; int done = 0; @@ -277,7 +277,7 @@ T atomic_oper_fetch( const Oper& op, volatile T * const dest , *dest = return_val; Impl::unlock_address_host_space( (void*) dest ); return return_val; -#else +#elif defined(KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_CUDA) T return_val; // This is a way to (hopefully) avoid dead lock in a warp int done = 0; diff --git a/lib/kokkos/core/src/impl/Kokkos_BitOps.hpp b/lib/kokkos/core/src/impl/Kokkos_BitOps.hpp index df16b3738b..3d3029535e 100644 --- a/lib/kokkos/core/src/impl/Kokkos_BitOps.hpp +++ b/lib/kokkos/core/src/impl/Kokkos_BitOps.hpp @@ -62,6 +62,8 @@ int bit_first_zero( unsigned i ) noexcept #if defined( __CUDA_ARCH__ ) return full != i ? __ffs( ~i ) - 1 : -1 ; +#elif defined( __HCC_ACCELERATOR__ ) + return full != i ? (int)hc::__firstbit_u32_u32(~i) : -1 ; #elif defined( KOKKOS_COMPILER_INTEL ) return full != i ? _bit_scan_forward( ~i ) : -1 ; #elif defined( KOKKOS_COMPILER_IBM ) @@ -82,6 +84,8 @@ int bit_scan_forward( unsigned i ) { #if defined( __CUDA_ARCH__ ) return __ffs(i) - 1; +#elif defined( __HCC_ACCELERATOR__ ) + return (int)hc::__firstbit_u32_u32(i); #elif defined( KOKKOS_COMPILER_INTEL ) return _bit_scan_forward(i); #elif defined( KOKKOS_COMPILER_IBM ) @@ -106,6 +110,8 @@ int bit_scan_reverse( unsigned i ) enum { shift = static_cast( sizeof(unsigned) * CHAR_BIT - 1 ) }; #if defined( __CUDA_ARCH__ ) return shift - __clz(i); +#elif defined( __HCC_ACCELERATOR__ ) + return (int)hc::__firstbit_u32_u32(i); #elif defined( KOKKOS_COMPILER_INTEL ) return _bit_scan_reverse(i); #elif defined( KOKKOS_COMPILER_IBM ) @@ -130,6 +136,8 @@ int bit_count( unsigned i ) { #if defined( __CUDA_ARCH__ ) return __popc(i); +#elif defined( __HCC_ACCELERATOR__ ) + return (int)hc::__popcount_u32_b32(i); #elif defined ( __INTEL_COMPILER ) return _popcnt32(i); #elif defined( KOKKOS_COMPILER_IBM ) diff --git a/lib/kokkos/core/src/impl/Kokkos_ClockTic.hpp b/lib/kokkos/core/src/impl/Kokkos_ClockTic.hpp index 92111c3c59..c59c59d497 100644 --- a/lib/kokkos/core/src/impl/Kokkos_ClockTic.hpp +++ b/lib/kokkos/core/src/impl/Kokkos_ClockTic.hpp @@ -72,6 +72,10 @@ uint64_t clock_tic(void) noexcept return clock64(); +#elif defined(__HCC_ACCELERATOR__) + // Get clock register + return hc::__clock_u64(); + #elif defined( __i386__ ) || defined( __x86_64 ) // Return value of 64-bit hi-res clock register. diff --git a/lib/kokkos/core/src/impl/Kokkos_Core.cpp b/lib/kokkos/core/src/impl/Kokkos_Core.cpp index f52cc469ac..ab6cffc7c3 100644 --- a/lib/kokkos/core/src/impl/Kokkos_Core.cpp +++ b/lib/kokkos/core/src/impl/Kokkos_Core.cpp @@ -80,7 +80,7 @@ setenv("MEMKIND_HBW_NODES", "1", 0); const int num_threads = args.num_threads; const int use_numa = args.num_numa; #endif // defined( KOKKOS_ENABLE_OPENMP ) || defined( KOKKOS_ENABLE_THREADS ) -#if defined( KOKKOS_ENABLE_CUDA ) +#if defined( KOKKOS_ENABLE_CUDA ) || defined( KOKKOS_ENABLE_ROCM ) const int use_gpu = args.device_id; #endif // defined( KOKKOS_ENABLE_CUDA ) @@ -162,6 +162,18 @@ setenv("MEMKIND_HBW_NODES", "1", 0); } #endif +#if defined( KOKKOS_ENABLE_ROCM ) + if( std::is_same< Kokkos::Experimental::ROCm , Kokkos::DefaultExecutionSpace >::value || 0 < use_gpu ) { + if (use_gpu > -1) { + Kokkos::Experimental::ROCm::initialize( Kokkos::Experimental::ROCm::SelectDevice( use_gpu ) ); + } + else { + Kokkos::Experimental::ROCm::initialize(); + } + std::cout << "Kokkos::initialize() fyi: ROCm enabled and initialized" << std::endl ; + } +#endif + #if defined(KOKKOS_ENABLE_PROFILING) Kokkos::Profiling::initialize(); #endif @@ -181,6 +193,13 @@ void finalize_internal( const bool all_spaces = false ) } #endif +#if defined( KOKKOS_ENABLE_ROCM ) + if( std::is_same< Kokkos::Experimental::ROCm , Kokkos::DefaultExecutionSpace >::value || all_spaces ) { + if(Kokkos::Experimental::ROCm::is_initialized()) + Kokkos::Experimental::ROCm::finalize(); + } +#endif + #if defined( KOKKOS_ENABLE_OPENMPTARGET ) if( std::is_same< Kokkos::Experimental::OpenMPTarget , Kokkos::DefaultExecutionSpace >::value || all_spaces ) { if(Kokkos::Experimental::OpenMPTarget::is_initialized()) @@ -225,6 +244,12 @@ void fence_internal() } #endif +#if defined( KOKKOS_ENABLE_ROCM ) + if( std::is_same< Kokkos::Experimental::ROCm , Kokkos::DefaultExecutionSpace >::value ) { + Kokkos::Experimental::ROCm::fence(); + } +#endif + #if defined( KOKKOS_ENABLE_OPENMP ) if( std::is_same< Kokkos::OpenMP , Kokkos::DefaultExecutionSpace >::value || std::is_same< Kokkos::OpenMP , Kokkos::HostSpace::execution_space >::value ) { diff --git a/lib/kokkos/core/src/impl/Kokkos_Error.hpp b/lib/kokkos/core/src/impl/Kokkos_Error.hpp index 4bc2637c57..b4390f14a1 100644 --- a/lib/kokkos/core/src/impl/Kokkos_Error.hpp +++ b/lib/kokkos/core/src/impl/Kokkos_Error.hpp @@ -75,7 +75,7 @@ void abort( const char * const message ) { #ifdef __CUDA_ARCH__ Kokkos::Impl::cuda_abort(message); #else - #ifndef KOKKOS_ENABLE_OPENMPTARGET + #if !defined(KOKKOS_ENABLE_OPENMPTARGET) && !defined(__HCC_ACCELERATOR__) Kokkos::Impl::host_abort(message); #endif #endif diff --git a/lib/kokkos/core/src/impl/Kokkos_HostThreadTeam.cpp b/lib/kokkos/core/src/impl/Kokkos_HostThreadTeam.cpp index d2446bde09..047b262422 100644 --- a/lib/kokkos/core/src/impl/Kokkos_HostThreadTeam.cpp +++ b/lib/kokkos/core/src/impl/Kokkos_HostThreadTeam.cpp @@ -275,7 +275,9 @@ int HostThreadTeamData::rendezvous( int64_t * const buffer for ( int i = 0 ; i < end ; ++i ) { ((int8_t*) & value )[i] = int8_t( step ); } - + // Do not REMOVE this store fence!!! + // Makes stuff hang on GCC with more than 8 threads + store_fence(); spinwait_until_equal( buffer[ (rank << shift_mem_cycle) + sync_offset ] , value ); } diff --git a/lib/kokkos/core/src/impl/Kokkos_Memory_Fence.hpp b/lib/kokkos/core/src/impl/Kokkos_Memory_Fence.hpp index 7a887a9e29..eedf3d559e 100644 --- a/lib/kokkos/core/src/impl/Kokkos_Memory_Fence.hpp +++ b/lib/kokkos/core/src/impl/Kokkos_Memory_Fence.hpp @@ -53,6 +53,8 @@ void memory_fence() { #if defined( __CUDA_ARCH__ ) __threadfence(); +#elif defined( KOKKOS_ENABLE_ROCM_ATOMICS ) + amp_barrier(CLK_LOCAL_MEM_FENCE | CLK_GLOBAL_MEM_FENCE); #elif defined( KOKKOS_ENABLE_ASM ) && defined( KOKKOS_ENABLE_ISA_X86_64 ) asm volatile ( "mfence" ::: "memory" diff --git a/lib/kokkos/core/src/impl/Kokkos_OldMacros.hpp b/lib/kokkos/core/src/impl/Kokkos_OldMacros.hpp index 15ce6964a0..a408199088 100644 --- a/lib/kokkos/core/src/impl/Kokkos_OldMacros.hpp +++ b/lib/kokkos/core/src/impl/Kokkos_OldMacros.hpp @@ -140,12 +140,6 @@ #endif #endif -#ifdef KOKKOS_HAVE_CXX11_DISPATCH_LAMBDA -#ifndef KOKKOS_ENABLE_CXX11_DISPATCH_LAMBDA -#define KOKKOS_ENABLE_CXX11_DISPATCH_LAMBDA KOKKOS_HAVE_CXX11_DISPATCH_LAMBDA -#endif -#endif - #ifdef KOKKOS_HAVE_CXX1Z #ifndef KOKKOS_ENABLE_CXX1Z #define KOKKOS_ENABLE_CXX1Z KOKKOS_HAVE_CXX1Z diff --git a/lib/kokkos/core/src/impl/Kokkos_TaskQueue_impl.hpp b/lib/kokkos/core/src/impl/Kokkos_TaskQueue_impl.hpp index 1974f7e1ca..0cce45b2e7 100644 --- a/lib/kokkos/core/src/impl/Kokkos_TaskQueue_impl.hpp +++ b/lib/kokkos/core/src/impl/Kokkos_TaskQueue_impl.hpp @@ -456,10 +456,11 @@ void TaskQueue< ExecSpace >::schedule_aggregate // task->m_next == member of linked list (queue) #if KOKKOS_IMPL_DEBUG_TASKDAG_SCHEDULING - printf( "schedule_aggregate( 0x%lx { 0x%lx 0x%lx %d %d %d }\n" + printf( "schedule_aggregate( 0x%lx { 0x%lx 0x%lx %d %d %d %d }\n" , uintptr_t(task) , uintptr_t(task->m_wait) , uintptr_t(task->m_next) + , task->m_dep_count , task->m_task_type , task->m_priority , task->m_ref_count ); @@ -597,7 +598,6 @@ void TaskQueue< ExecSpace >::complete , task->m_task_type , task->m_priority , task->m_ref_count ); - fflush( stdout ); #endif task_root_type volatile & t = *task ; diff --git a/lib/kokkos/core/src/impl/Kokkos_ViewMapping.hpp b/lib/kokkos/core/src/impl/Kokkos_ViewMapping.hpp index d346f9e639..b2adcc9f06 100644 --- a/lib/kokkos/core/src/impl/Kokkos_ViewMapping.hpp +++ b/lib/kokkos/core/src/impl/Kokkos_ViewMapping.hpp @@ -1015,8 +1015,13 @@ struct ViewOffset< Dimension , Kokkos::LayoutLeft constexpr ViewOffset( const ViewOffset< DimRHS , Kokkos::LayoutRight , void > & rhs ) : m_dim( rhs.m_dim.N0, 0, 0, 0, 0, 0, 0, 0 ) { - static_assert( DimRHS::rank == 1 && dimension_type::rank == 1 && dimension_type::rank_dynamic == 1 - , "ViewOffset LayoutLeft and LayoutRight are only compatible when rank == 1" ); + static_assert( + ( DimRHS::rank == 0 && + dimension_type::rank == 0 ) || + ( DimRHS::rank == 1 && + dimension_type::rank == 1 && + dimension_type::rank_dynamic == 1 ) + , "ViewOffset LayoutLeft and LayoutRight are only compatible when rank <= 1" ); } template< class DimRHS > @@ -1024,8 +1029,13 @@ struct ViewOffset< Dimension , Kokkos::LayoutLeft ViewOffset( const ViewOffset< DimRHS , Kokkos::LayoutStride , void > & rhs ) : m_dim( rhs.m_dim.N0, 0, 0, 0, 0, 0, 0, 0 ) { - static_assert( DimRHS::rank == 1 && dimension_type::rank == 1 && dimension_type::rank_dynamic == 1 - , "ViewOffset LayoutLeft and LayoutStride are only compatible when rank == 1" ); + static_assert( + ( DimRHS::rank == 0 && + dimension_type::rank == 0 ) || + ( DimRHS::rank == 1 && + dimension_type::rank == 1 && + dimension_type::rank_dynamic == 1 ) + , "ViewOffset LayoutLeft and LayoutStride are only compatible when rank <= 1" ); if ( rhs.m_stride.S0 != 1 ) { Kokkos::abort("Kokkos::Impl::ViewOffset assignment of LayoutLeft from LayoutStride requires stride == 1" ); } @@ -1493,8 +1503,13 @@ struct ViewOffset< Dimension , Kokkos::LayoutRight constexpr ViewOffset( const ViewOffset< DimRHS , Kokkos::LayoutLeft , void > & rhs ) : m_dim( rhs.m_dim.N0, 0, 0, 0, 0, 0, 0, 0 ) { - static_assert( DimRHS::rank == 1 && dimension_type::rank == 1 && dimension_type::rank_dynamic == 1 - , "ViewOffset LayoutRight and LayoutLeft are only compatible when rank == 1" ); + static_assert( + ( DimRHS::rank == 0 && + dimension_type::rank == 0 ) || + ( DimRHS::rank == 1 && + dimension_type::rank == 1 && + dimension_type::rank_dynamic == 1 ) + , "ViewOffset LayoutRight and LayoutLeft are only compatible when rank <= 1" ); } template< class DimRHS > @@ -1502,8 +1517,13 @@ struct ViewOffset< Dimension , Kokkos::LayoutRight ViewOffset( const ViewOffset< DimRHS , Kokkos::LayoutStride , void > & rhs ) : m_dim( rhs.m_dim.N0, 0, 0, 0, 0, 0, 0, 0 ) { - static_assert( DimRHS::rank == 1 && dimension_type::rank == 1 && dimension_type::rank_dynamic == 1 - , "ViewOffset LayoutLeft/Right and LayoutStride are only compatible when rank == 1" ); + static_assert( + ( DimRHS::rank == 0 && + dimension_type::rank == 0 ) || + ( DimRHS::rank == 1 && + dimension_type::rank == 1 && + dimension_type::rank_dynamic == 1 ) + , "ViewOffset LayoutRight and LayoutString are only compatible when rank <= 1" ); if ( rhs.m_stride.S0 != 1 ) { Kokkos::abort("Kokkos::Impl::ViewOffset assignment of LayoutLeft/Right from LayoutStride requires stride == 1" ); } diff --git a/lib/kokkos/core/src/impl/Kokkos_ViewTile.hpp b/lib/kokkos/core/src/impl/Kokkos_ViewTile.hpp index 5a8600e0ae..37367f68e4 100644 --- a/lib/kokkos/core/src/impl/Kokkos_ViewTile.hpp +++ b/lib/kokkos/core/src/impl/Kokkos_ViewTile.hpp @@ -143,7 +143,7 @@ public: //---------------------------------------- - ~ViewOffset() = default ; + KOKKOS_FUNCTION_DEFAULTED ~ViewOffset() = default ; KOKKOS_INLINE_FUNCTION ViewOffset() = default ; KOKKOS_INLINE_FUNCTION ViewOffset( const ViewOffset & ) = default ; KOKKOS_INLINE_FUNCTION ViewOffset & operator = ( const ViewOffset & ) = default ; diff --git a/lib/kokkos/core/unit_test/CMakeLists.txt b/lib/kokkos/core/unit_test/CMakeLists.txt index 475b6bb48a..8aeae1199f 100644 --- a/lib/kokkos/core/unit_test/CMakeLists.txt +++ b/lib/kokkos/core/unit_test/CMakeLists.txt @@ -57,6 +57,7 @@ IF(Kokkos_ENABLE_Serial) serial/TestSerial_ViewMapping_b.cpp serial/TestSerial_ViewMapping_subview.cpp serial/TestSerial_ViewOfClass.cpp + serial/TestSerial_Crs.cpp serial/TestSerial_WorkGraph.cpp COMM serial mpi NUM_MPI_PROCS 1 @@ -103,6 +104,7 @@ IF(Kokkos_ENABLE_Pthread) threads/TestThreads_ViewMapping_b.cpp threads/TestThreads_ViewMapping_subview.cpp threads/TestThreads_ViewOfClass.cpp + threads/TestThreads_Crs.cpp threads/TestThreads_WorkGraph.cpp COMM serial mpi NUM_MPI_PROCS 1 @@ -149,6 +151,7 @@ IF(Kokkos_ENABLE_OpenMP) openmp/TestOpenMP_ViewMapping_b.cpp openmp/TestOpenMP_ViewMapping_subview.cpp openmp/TestOpenMP_ViewOfClass.cpp + openmp/TestOpenMP_Crs.cpp openmp/TestOpenMP_WorkGraph.cpp openmp/TestOpenMP_UniqueToken.cpp COMM serial mpi @@ -241,6 +244,7 @@ IF(Kokkos_ENABLE_Cuda) cuda/TestCuda_ViewMapping_b.cpp cuda/TestCuda_ViewMapping_subview.cpp cuda/TestCuda_ViewOfClass.cpp + cuda/TestCuda_Crs.cpp cuda/TestCuda_WorkGraph.cpp COMM serial mpi NUM_MPI_PROCS 1 diff --git a/lib/kokkos/core/unit_test/Makefile b/lib/kokkos/core/unit_test/Makefile index c877aa7dd2..07859f7ac3 100644 --- a/lib/kokkos/core/unit_test/Makefile +++ b/lib/kokkos/core/unit_test/Makefile @@ -10,6 +10,8 @@ vpath %.cpp ${KOKKOS_PATH}/core/unit_test/openmp vpath %.cpp ${KOKKOS_PATH}/core/unit_test/openmptarget vpath %.cpp ${KOKKOS_PATH}/core/unit_test/qthreads vpath %.cpp ${KOKKOS_PATH}/core/unit_test/cuda +vpath %.cpp ${KOKKOS_PATH}/core/unit_test/rocm + TEST_HEADERS = $(wildcard $(KOKKOS_PATH)/core/unit_test/*.hpp) TEST_HEADERS += $(wildcard $(KOKKOS_PATH)/core/unit_test/*/*.hpp) @@ -62,6 +64,7 @@ endif OBJ_CUDA += TestCuda_TeamReductionScan.o OBJ_CUDA += TestCuda_Other.o OBJ_CUDA += TestCuda_MDRange.o + OBJ_CUDA += TestCuda_Crs.o OBJ_CUDA += TestCuda_Task.o TestCuda_WorkGraph.o OBJ_CUDA += TestCuda_Spaces.o OBJ_CUDA += TestCuda_UniqueToken.o @@ -71,6 +74,58 @@ endif TEST_TARGETS += test-cuda endif +ifeq ($(KOKKOS_INTERNAL_USE_ROCM), 1) + OBJ_ROCM = UnitTestMainInit.o gtest-all.o + OBJ_ROCM += TestROCm_Init.o + OBJ_ROCM += TestROCm_Complex.o +# OBJ_ROCM += TestROCm_RangePolicy.o +# rocm.range_scan locking up + OBJ_ROCM += TestROCm_AtomicOperations.o + OBJ_ROCM += TestROCm_Atomics.o +# complex failing + OBJ_ROCM += TestROCm_AtomicViews.o + OBJ_ROCM += TestROCm_Other.o +# rocm.memory_pool + OBJ_ROCM += TestROCm_Scan.o + OBJ_ROCM += TestROCm_SharedAlloc.o + OBJ_ROCM += TestROCm_SubView_a.o +# OBJ_ROCM += TestROCm_SubView_b.o +# relies on host accessable device memory +# OBJ_ROCM += TestROCm_SubView_c01.o +# OBJ_ROCM += TestROCm_SubView_c02.o +# OBJ_ROCM += TestROCm_SubView_c03.o +# OBJ_ROCM += TestROCm_SubView_c04.o +# OBJ_ROCM += TestROCm_SubView_c05.o +# OBJ_ROCM += TestROCm_SubView_c06.o +# OBJ_ROCM += TestROCm_SubView_c07.o +# OBJ_ROCM += TestROCm_SubView_c08.o +# OBJ_ROCM += TestROCm_SubView_c09.o +# OBJ_ROCM += TestROCm_SubView_c10.o +# OBJ_ROCM += TestROCm_SubView_c11.o +# OBJ_ROCM += TestROCm_SubView_c12.o +# all of the above use UVM or Host accessable memory +# OBJ_ROCM += TestROCm_Team.o +# compile fails +# OBJ_ROCM += TestROCm_TeamReductionScan.o +# compile fails +# OBJ_ROCM += TestROCm_TeamScratch.o +# compile fails + OBJ_ROCM += TestROCm_ViewAPI_b.o +# test fail in view_api + OBJ_ROCM += TestROCm_ViewMapping_a.o + OBJ_ROCM += TestROCm_ViewMapping_b.o + OBJ_ROCM += TestROCm_ViewMapping_subview.o + OBJ_ROCM += TestROCmHostPinned_ViewAPI.o + OBJ_ROCM += TestROCmHostPinned_ViewMapping_a.o + OBJ_ROCM += TestROCmHostPinned_ViewMapping_b.o + OBJ_ROCM += TestROCmHostPinned_ViewMapping_subview.o + OBJ_ROCM += TestROCm_ViewOfClass.o + OBJ_ROCM += TestROCm_Spaces.o + + TARGETS += KokkosCore_UnitTest_ROCm + TEST_TARGETS += test-rocm +endif + ifeq ($(KOKKOS_INTERNAL_USE_PTHREADS), 1) OBJ_THREADS = UnitTestMainInit.o gtest-all.o @@ -122,6 +177,7 @@ endif OBJ_OPENMP += TestOpenMP_TeamReductionScan.o OBJ_OPENMP += TestOpenMP_Other.o OBJ_OPENMP += TestOpenMP_MDRange.o + OBJ_OPENMP += TestOpenMP_Crs.o OBJ_OPENMP += TestOpenMP_Task.o TestOpenMP_WorkGraph.o OBJ_OPENMP += TestOpenMP_UniqueToken.o @@ -209,7 +265,11 @@ endif OBJ_SERIAL += TestSerial_Team.o TestSerial_TeamScratch.o OBJ_SERIAL += TestSerial_TeamReductionScan.o OBJ_SERIAL += TestSerial_Other.o + #HCC_WORKAROUND + ifneq ($(KOKKOS_INTERNAL_COMPILER_HCC), 1) OBJ_SERIAL += TestSerial_MDRange.o + endif + OBJ_SERIAL += TestSerial_Crs.o OBJ_SERIAL += TestSerial_Task.o TestSerial_WorkGraph.o TARGETS += KokkosCore_UnitTest_Serial @@ -223,8 +283,10 @@ TEST_TARGETS += test-hwloc OBJ_DEFAULT = UnitTestMainInit.o gtest-all.o ifneq ($(KOKKOS_INTERNAL_USE_OPENMPTARGET), 1) +ifneq ($(KOKKOS_INTERNAL_COMPILER_HCC), 1) OBJ_DEFAULT += TestDefaultDeviceType.o TestDefaultDeviceType_a.o TestDefaultDeviceType_b.o TestDefaultDeviceType_c.o TestDefaultDeviceType_d.o endif +endif TARGETS += KokkosCore_UnitTest_Default TEST_TARGETS += test-default @@ -239,6 +301,9 @@ TEST_TARGETS += ${INITTESTS_TEST_TARGETS} KokkosCore_UnitTest_Cuda: $(OBJ_CUDA) $(KOKKOS_LINK_DEPENDS) $(LINK) $(EXTRA_PATH) $(OBJ_CUDA) $(KOKKOS_LIBS) $(LIB) $(KOKKOS_LDFLAGS) $(LDFLAGS) -o KokkosCore_UnitTest_Cuda +KokkosCore_UnitTest_ROCm: $(OBJ_ROCM) $(KOKKOS_LINK_DEPENDS) + $(LINK) $(EXTRA_PATH) $(OBJ_ROCM) $(KOKKOS_LIBS) $(LIB) $(KOKKOS_LDFLAGS) $(LDFLAGS) -o KokkosCore_UnitTest_ROCm + KokkosCore_UnitTest_Threads: $(OBJ_THREADS) $(KOKKOS_LINK_DEPENDS) $(LINK) $(EXTRA_PATH) $(OBJ_THREADS) $(KOKKOS_LIBS) $(LIB) $(KOKKOS_LDFLAGS) $(LDFLAGS) -o KokkosCore_UnitTest_Threads @@ -272,6 +337,9 @@ ${INITTESTS_TARGETS}: KokkosCore_UnitTest_DefaultDeviceTypeInit_%: TestDefaultDe test-cuda: KokkosCore_UnitTest_Cuda ./KokkosCore_UnitTest_Cuda +test-rocm: KokkosCore_UnitTest_ROCm + ./KokkosCore_UnitTest_ROCm + test-threads: KokkosCore_UnitTest_Threads ./KokkosCore_UnitTest_Threads diff --git a/lib/kokkos/core/unit_test/TestCompilerMacros.hpp b/lib/kokkos/core/unit_test/TestCompilerMacros.hpp index fddcc4a2e6..f0391134ba 100644 --- a/lib/kokkos/core/unit_test/TestCompilerMacros.hpp +++ b/lib/kokkos/core/unit_test/TestCompilerMacros.hpp @@ -43,6 +43,19 @@ #include +#if defined(KOKKOS_ENABLE_CUDA) && \ + ( !defined(KOKKOS_ENABLE_CUDA_LAMBDA) || \ + ( ( defined(KOKKOS_ENABLE_SERIAL) || defined(KOKKOS_ENABLE_OPENMP) ) && \ + ( (CUDA_VERSION < 8000) && defined( __NVCC__ )))) + #if defined(KOKKOS_ENABLE_CXX11_DISPATCH_LAMBDA) + #error "Macro bug: KOKKOS_ENABLE_CXX11_DISPATCH_LAMBDA shouldn't be defined" + #endif +#else + #if !defined(KOKKOS_ENABLE_CXX11_DISPATCH_LAMBDA) + #error "Macro bug: KOKKOS_ENABLE_CXX11_DISPATCH_LAMBDA should be defined" + #endif +#endif + #define KOKKOS_PRAGMA_UNROLL(a) namespace TestCompilerMacros { diff --git a/lib/kokkos/core/unit_test/TestComplex.hpp b/lib/kokkos/core/unit_test/TestComplex.hpp index 36f05612e0..ce5537fed3 100644 --- a/lib/kokkos/core/unit_test/TestComplex.hpp +++ b/lib/kokkos/core/unit_test/TestComplex.hpp @@ -158,7 +158,8 @@ struct TestComplexBasicMath { d_results(1) = a-b; d_results(2) = a*b; d_results(3) = a/b; - d_results(4) = Kokkos::complex(1.0,2.0); + d_results(4).real(1.0); + d_results(4).imag(2.0); d_results(4) += a; d_results(5) = Kokkos::complex(1.0,2.0); d_results(5) -= a; @@ -173,7 +174,8 @@ struct TestComplexBasicMath { d_results(9) = a-c; d_results(10) = a*c; d_results(11) = a/c; - d_results(12) = Kokkos::complex(1.0,2.0); + d_results(12).real(1.0); + d_results(12).imag(2.0); d_results(12) += c; d_results(13) = Kokkos::complex(1.0,2.0); d_results(13) -= c; diff --git a/lib/kokkos/core/unit_test/TestCrs.hpp b/lib/kokkos/core/unit_test/TestCrs.hpp new file mode 100644 index 0000000000..90f4036868 --- /dev/null +++ b/lib/kokkos/core/unit_test/TestCrs.hpp @@ -0,0 +1,98 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include + +#include + +namespace Test { + +namespace { + +template< class ExecSpace > +struct CountFillFunctor { + KOKKOS_INLINE_FUNCTION + std::int32_t operator()(std::int32_t row, std::int32_t* fill) const { + auto n = (row % 4) + 1; + if (fill) { + for (std::int32_t j = 0; j < n; ++j) { + fill[j] = j + 1; + } + } + return n; + } +}; + +template< class ExecSpace > +void test_count_fill(std::int32_t nrows) { + Kokkos::Experimental::Crs graph; + Kokkos::Experimental::count_and_fill_crs(graph, nrows, CountFillFunctor()); + ASSERT_EQ(graph.numRows(), nrows); + auto row_map = Kokkos::create_mirror_view(graph.row_map); + Kokkos::deep_copy(row_map, graph.row_map); + auto entries = Kokkos::create_mirror_view(graph.entries); + Kokkos::deep_copy(entries, graph.entries); + for (std::int32_t row = 0; row < nrows; ++row) { + auto n = (row % 4) + 1; + ASSERT_EQ(row_map(row + 1) - row_map(row), n); + for (std::int32_t j = 0; j < n; ++j) { + ASSERT_EQ(entries(row_map(row) + j), j + 1); + } + } +} + +} // anonymous namespace + +TEST_F( TEST_CATEGORY, crs_count_fill ) +{ + test_count_fill(0); + test_count_fill(1); + test_count_fill(2); + test_count_fill(3); + test_count_fill(13); + test_count_fill(100); + test_count_fill(1000); + test_count_fill(10000); +} + +} // namespace Test diff --git a/lib/kokkos/core/unit_test/TestRange.hpp b/lib/kokkos/core/unit_test/TestRange.hpp index 3cea1ad4a0..e6857a4d2f 100644 --- a/lib/kokkos/core/unit_test/TestRange.hpp +++ b/lib/kokkos/core/unit_test/TestRange.hpp @@ -301,19 +301,19 @@ TEST_F( TEST_CATEGORY, range_scan ) { { TestRange< TEST_EXECSPACE, Kokkos::Schedule >f(0); f.test_scan(); } { TestRange< TEST_EXECSPACE, Kokkos::Schedule >f(0); f.test_scan(); } -#ifndef KOKKOS_ENABLE_CUDA +#if !defined(KOKKOS_ENABLE_CUDA) && !defined(KOKKOS_ENABLE_ROCM) { TestRange< TEST_EXECSPACE, Kokkos::Schedule >f(0); f.test_dynamic_policy(); } #endif { TestRange< TEST_EXECSPACE, Kokkos::Schedule >f(2); f.test_scan(); } { TestRange< TEST_EXECSPACE, Kokkos::Schedule >f(3); f.test_scan(); } -#ifndef KOKKOS_ENABLE_CUDA +#if !defined(KOKKOS_ENABLE_CUDA) && !defined(KOKKOS_ENABLE_ROCM) { TestRange< TEST_EXECSPACE, Kokkos::Schedule >f(3); f.test_dynamic_policy(); } #endif { TestRange< TEST_EXECSPACE, Kokkos::Schedule >f(1000); f.test_scan(); } { TestRange< TEST_EXECSPACE, Kokkos::Schedule >f(1001); f.test_scan(); } -#ifndef KOKKOS_ENABLE_CUDA +#if !defined(KOKKOS_ENABLE_CUDA) && !defined(KOKKOS_ENABLE_ROCM) { TestRange< TEST_EXECSPACE, Kokkos::Schedule >f(1001); f.test_dynamic_policy(); } #endif } diff --git a/lib/kokkos/core/unit_test/TestScan.hpp b/lib/kokkos/core/unit_test/TestScan.hpp index fa7669c5ed..823f0c99a8 100644 --- a/lib/kokkos/core/unit_test/TestScan.hpp +++ b/lib/kokkos/core/unit_test/TestScan.hpp @@ -92,7 +92,7 @@ struct TestScan { Kokkos::deep_copy( errors_a, 0 ); errors = errors_a; - parallel_scan( N , *this ); + Kokkos::parallel_scan( N , *this ); } TestScan( const WorkSpec & Start , const WorkSpec & N ) @@ -103,7 +103,7 @@ struct TestScan { Kokkos::deep_copy( errors_a, 0 ); errors = errors_a; - parallel_scan( exec_policy( Start , N ) , *this ); + Kokkos::parallel_scan( exec_policy( Start , N ) , *this ); } static void test_range( const WorkSpec & begin, const WorkSpec & end ) diff --git a/lib/kokkos/core/unit_test/TestTaskScheduler.hpp b/lib/kokkos/core/unit_test/TestTaskScheduler.hpp index 4e66543857..a3f59a2b9e 100644 --- a/lib/kokkos/core/unit_test/TestTaskScheduler.hpp +++ b/lib/kokkos/core/unit_test/TestTaskScheduler.hpp @@ -250,34 +250,23 @@ struct TestTaskDependence { const int n = CHUNK < m_count ? CHUNK : m_count; if ( 1 < m_count ) { - // Test use of memory pool for temporary allocation: - // Raw allocation: - future_type * const f = - (future_type *) m_sched.memory()->allocate( sizeof(future_type) * n ); + const int increment = ( m_count + n - 1 ) / n; - // In-place construction: - for ( int i = 0; i < n; ++i ) new(f+i) future_type(); + future_type f = + m_sched.when_all( n , [this,increment]( int i ) { + const long inc = increment ; + const long begin = i * inc ; + const long count = begin + inc < m_count ? inc : m_count - begin ; - const int inc = ( m_count + n - 1 ) / n; - - for ( int i = 0; i < n; ++i ) { - long begin = i * inc; - long count = begin + inc < m_count ? inc : m_count - begin; - - f[i] = Kokkos::task_spawn( Kokkos::TaskSingle( m_sched ) - , TestTaskDependence( count, m_sched, m_accum ) ); - } + return Kokkos::task_spawn + ( Kokkos::TaskSingle( m_sched ) + , TestTaskDependence( count, m_sched, m_accum ) ); + }); m_count = 0; - Kokkos::respawn( this, Kokkos::when_all( f, n ) ); - - // In-place destruction to release future: - for ( int i = 0; i < n; ++i ) (f+i)->~future_type(); - - // Raw deallocation: - m_sched.memory()->deallocate( f , sizeof(future_type) * n ); + Kokkos::respawn( this, f ); } else if ( 1 == m_count ) { Kokkos::atomic_increment( & m_accum() ); @@ -372,7 +361,9 @@ struct TestTaskTeam { , begin - 1 ) ); + #ifndef __HCC_ACCELERATOR__ assert( !future.is_null() ); + #endif Kokkos::respawn( this, future ); } @@ -664,6 +655,7 @@ TEST_F( TEST_CATEGORY, task_fib ) TEST_F( TEST_CATEGORY, task_depend ) { for ( int i = 0; i < 25; ++i ) { +printf("\nTest::task_depend %d\n",i); TestTaskScheduler::TestTaskDependence< TEST_EXECSPACE >::run( i ); } } diff --git a/lib/kokkos/core/unit_test/TestViewAPI.hpp b/lib/kokkos/core/unit_test/TestViewAPI.hpp index 232163f11e..721ffd8378 100644 --- a/lib/kokkos/core/unit_test/TestViewAPI.hpp +++ b/lib/kokkos/core/unit_test/TestViewAPI.hpp @@ -1324,10 +1324,14 @@ TEST_F( TEST_CATEGORY, view_remap ) #ifdef KOKKOS_ENABLE_CUDA #define EXECSPACE std::conditional::value,Kokkos::CudaHostPinnedSpace,TEST_EXECSPACE>::type #else - #ifdef KOKKOS_ENABLE_OPENMPTARGET - #define EXECSPACE Kokkos::HostSpace + #ifdef KOKKOS_ENABLE_ROCM + #define EXECSPACE std::conditional::value,Kokkos::Experimental::ROCmHostPinnedSpace,TEST_EXECSPACE>::type #else - #define EXECSPACE TEST_EXECSPACE + #if defined(KOKKOS_ENABLE_OPENMPTARGET) + #define EXECSPACE Kokkos::HostSpace + #else + #define EXECSPACE TEST_EXECSPACE + #endif #endif #endif @@ -1375,4 +1379,14 @@ TEST_F( TEST_CATEGORY, view_remap ) } } +TEST_F( TEST_CATEGORY, view_mirror_nonconst ) +{ + Kokkos::View d_view("d_view", 10); + Kokkos::View d_view_const = d_view; + auto h_view = Kokkos::create_mirror(d_view_const); + Kokkos::deep_copy(h_view, d_view_const); + auto h_view2 = Kokkos::create_mirror(Kokkos::HostSpace(), d_view_const); + Kokkos::deep_copy(h_view2, d_view_const); +} + } // namespace Test diff --git a/lib/kokkos/core/unit_test/TestViewCtorPropEmbeddedDim.hpp b/lib/kokkos/core/unit_test/TestViewCtorPropEmbeddedDim.hpp index 305ddb2a1d..61b43a588a 100644 --- a/lib/kokkos/core/unit_test/TestViewCtorPropEmbeddedDim.hpp +++ b/lib/kokkos/core/unit_test/TestViewCtorPropEmbeddedDim.hpp @@ -107,6 +107,7 @@ struct TestViewCtorProp_EmbeddedDim { Kokkos::deep_copy( hcv1, cv1 ); ASSERT_EQ( (std::is_same< CommonViewValueType, double >::value) , true ) ; + ASSERT_EQ( (std::is_same< typename decltype(view_alloc_arg)::scalar_array_type, CommonViewValueType>::value) , true ) ; #if 0 // debug output for ( int i = 0; i < N0*N1; ++i ) { diff --git a/lib/kokkos/core/unit_test/TestViewMapping_a.hpp b/lib/kokkos/core/unit_test/TestViewMapping_a.hpp index 810ae72e73..f963875ae1 100644 --- a/lib/kokkos/core/unit_test/TestViewMapping_a.hpp +++ b/lib/kokkos/core/unit_test/TestViewMapping_a.hpp @@ -1012,7 +1012,7 @@ void test_view_mapping() ASSERT_EQ( a.use_count(), 1 ); ASSERT_EQ( b.use_count(), 0 ); -#if !defined( KOKKOS_ENABLE_CUDA_LAMBDA ) +#if !defined( KOKKOS_ENABLE_CUDA_LAMBDA ) && !defined( KOKKOS_ENABLE_ROCM ) // Cannot launch host lambda when CUDA lambda is enabled. typedef typename Kokkos::Impl::HostMirror< Space >::Space::execution_space host_exec_space; @@ -1021,6 +1021,7 @@ void test_view_mapping() // 'a' is captured by copy, and the capture mechanism converts 'a' to an // unmanaged copy. When the parallel dispatch accepts a move for the // lambda, this count should become 1. + ASSERT_EQ( a.use_count(), 2 ); V x = a; ASSERT_EQ( a.use_count(), 2 ); diff --git a/lib/kokkos/core/unit_test/TestViewMapping_b.hpp b/lib/kokkos/core/unit_test/TestViewMapping_b.hpp index ee1c96b423..d0cbfe9e7d 100644 --- a/lib/kokkos/core/unit_test/TestViewMapping_b.hpp +++ b/lib/kokkos/core/unit_test/TestViewMapping_b.hpp @@ -133,11 +133,15 @@ TEST_F( TEST_CATEGORY , view_mapping_atomic ) f.run(); } +} + /*--------------------------------------------------------------------------*/ + namespace Test { -struct ValueType { + +struct MappingClassValueType { KOKKOS_INLINE_FUNCTION - ValueType() + MappingClassValueType() { #if 0 #if defined( KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_CUDA ) @@ -150,7 +154,7 @@ struct ValueType { #endif } KOKKOS_INLINE_FUNCTION - ~ValueType() + ~MappingClassValueType() { #if 0 #if defined( KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_CUDA ) @@ -163,7 +167,6 @@ struct ValueType { #endif } }; -} template< class Space > void test_view_mapping_class_value() @@ -172,7 +175,7 @@ void test_view_mapping_class_value() ExecSpace::fence(); { - Kokkos::View< Test::ValueType, ExecSpace > a( "a" ); + Kokkos::View< MappingClassValueType, ExecSpace > a( "a" ); ExecSpace::fence(); } ExecSpace::fence(); @@ -184,3 +187,74 @@ TEST_F( TEST_CATEGORY , view_mapping_class_value ) } } + +/*--------------------------------------------------------------------------*/ + +namespace Test { + +TEST_F( TEST_CATEGORY , view_mapping_assignable ) +{ + typedef TEST_EXECSPACE exec_space ; + + { // Assignment of rank-0 Left = Right + typedef Kokkos::ViewTraits dst_traits ; + typedef Kokkos::ViewTraits src_traits ; + typedef Kokkos::Impl::ViewMapping mapping ; + static_assert( mapping::is_assignable , "" ); + + Kokkos::View src ; + Kokkos::View dst( src ); + dst = src ; + } + + { // Assignment of rank-0 Right = Left + typedef Kokkos::ViewTraits dst_traits ; + typedef Kokkos::ViewTraits src_traits ; + typedef Kokkos::Impl::ViewMapping mapping ; + static_assert( mapping::is_assignable , "" ); + + Kokkos::View src ; + Kokkos::View dst( src ); + dst = src ; + } + + { // Assignment of rank-1 Left = Right + typedef Kokkos::ViewTraits dst_traits ; + typedef Kokkos::ViewTraits src_traits ; + typedef Kokkos::Impl::ViewMapping mapping ; + static_assert( mapping::is_assignable , "" ); + + Kokkos::View src ; + Kokkos::View dst( src ); + dst = src ; + } + + { // Assignment of rank-1 Right = Left + typedef Kokkos::ViewTraits dst_traits ; + typedef Kokkos::ViewTraits src_traits ; + typedef Kokkos::Impl::ViewMapping mapping ; + static_assert( mapping::is_assignable , "" ); + + Kokkos::View src ; + Kokkos::View dst( src ); + dst = src ; + } + + { // Assignment of rank-2 Left = Right + typedef Kokkos::ViewTraits dst_traits ; + typedef Kokkos::ViewTraits src_traits ; + typedef Kokkos::Impl::ViewMapping mapping ; + static_assert( ! mapping::is_assignable , "" ); + } + + { // Assignment of rank-2 Right = Left + typedef Kokkos::ViewTraits dst_traits ; + typedef Kokkos::ViewTraits src_traits ; + typedef Kokkos::Impl::ViewMapping mapping ; + static_assert( ! mapping::is_assignable , "" ); + } + +} + +} + diff --git a/lib/kokkos/core/unit_test/cuda/TestCuda_Crs.cpp b/lib/kokkos/core/unit_test/cuda/TestCuda_Crs.cpp new file mode 100644 index 0000000000..a90e88933e --- /dev/null +++ b/lib/kokkos/core/unit_test/cuda/TestCuda_Crs.cpp @@ -0,0 +1,45 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include +#include diff --git a/lib/kokkos/core/unit_test/default/TestDefaultDeviceType_c.cpp b/lib/kokkos/core/unit_test/default/TestDefaultDeviceType_c.cpp index e11996e8f9..4500392b27 100644 --- a/lib/kokkos/core/unit_test/default/TestDefaultDeviceType_c.cpp +++ b/lib/kokkos/core/unit_test/default/TestDefaultDeviceType_c.cpp @@ -46,6 +46,7 @@ #include #if !defined( KOKKOS_ENABLE_CUDA ) || defined( __CUDACC__ ) +#if !defined( KOKKOS_ENABLE_ROCM ) #include #include @@ -60,3 +61,4 @@ TEST_F( defaultdevicetype, reduce_instantiation_c ) } // namespace Test #endif +#endif diff --git a/lib/kokkos/core/unit_test/openmp/TestOpenMP_Crs.cpp b/lib/kokkos/core/unit_test/openmp/TestOpenMP_Crs.cpp new file mode 100644 index 0000000000..54b283f539 --- /dev/null +++ b/lib/kokkos/core/unit_test/openmp/TestOpenMP_Crs.cpp @@ -0,0 +1,45 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include +#include diff --git a/lib/kokkos/core/unit_test/rocm/TestROCmHostPinned_Category.hpp b/lib/kokkos/core/unit_test/rocm/TestROCmHostPinned_Category.hpp new file mode 100644 index 0000000000..94e778b3bc --- /dev/null +++ b/lib/kokkos/core/unit_test/rocm/TestROCmHostPinned_Category.hpp @@ -0,0 +1,65 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#ifndef KOKKOS_TEST_THREADS_HPP +#define KOKKOS_TEST_THREADS_HPP + +#include + +namespace Test { + +class rocm_hostpinned : public ::testing::Test { +protected: + static void SetUpTestCase() { + } + + static void TearDownTestCase() { + } +}; + +} // namespace Test + +#define TEST_CATEGORY rocm_hostpinned +#define TEST_EXECSPACE Kokkos::Experimental::ROCmHostPinnedSpace + +#endif diff --git a/lib/kokkos/core/unit_test/rocm/TestROCmHostPinned_SharedAlloc.cpp b/lib/kokkos/core/unit_test/rocm/TestROCmHostPinned_SharedAlloc.cpp new file mode 100644 index 0000000000..2f8f379db0 --- /dev/null +++ b/lib/kokkos/core/unit_test/rocm/TestROCmHostPinned_SharedAlloc.cpp @@ -0,0 +1,55 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include +#include + +namespace Test { + + +TEST_F( TEST_CATEGORY, impl_shared_alloc ) +{ + test_shared_alloc< TEST_EXECSPACE, Kokkos::DefaultHostExecutionSpace >(); +} + +} // namespace Test diff --git a/lib/kokkos/core/unit_test/rocm/TestROCmHostPinned_ViewAPI.cpp b/lib/kokkos/core/unit_test/rocm/TestROCmHostPinned_ViewAPI.cpp new file mode 100644 index 0000000000..32ecbbb48f --- /dev/null +++ b/lib/kokkos/core/unit_test/rocm/TestROCmHostPinned_ViewAPI.cpp @@ -0,0 +1,45 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include +#include diff --git a/lib/kokkos/core/unit_test/rocm/TestROCmHostPinned_ViewMapping_a.cpp b/lib/kokkos/core/unit_test/rocm/TestROCmHostPinned_ViewMapping_a.cpp new file mode 100644 index 0000000000..5523fac7fc --- /dev/null +++ b/lib/kokkos/core/unit_test/rocm/TestROCmHostPinned_ViewMapping_a.cpp @@ -0,0 +1,46 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include +#include + diff --git a/lib/kokkos/core/unit_test/rocm/TestROCmHostPinned_ViewMapping_b.cpp b/lib/kokkos/core/unit_test/rocm/TestROCmHostPinned_ViewMapping_b.cpp new file mode 100644 index 0000000000..5e29612d72 --- /dev/null +++ b/lib/kokkos/core/unit_test/rocm/TestROCmHostPinned_ViewMapping_b.cpp @@ -0,0 +1,46 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include +#include + diff --git a/lib/kokkos/core/unit_test/rocm/TestROCmHostPinned_ViewMapping_subview.cpp b/lib/kokkos/core/unit_test/rocm/TestROCmHostPinned_ViewMapping_subview.cpp new file mode 100644 index 0000000000..6a6194b38f --- /dev/null +++ b/lib/kokkos/core/unit_test/rocm/TestROCmHostPinned_ViewMapping_subview.cpp @@ -0,0 +1,46 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include +#include + diff --git a/lib/kokkos/core/unit_test/rocm/TestROCm_All.cpp b/lib/kokkos/core/unit_test/rocm/TestROCm_All.cpp new file mode 100644 index 0000000000..a9c7e51b62 --- /dev/null +++ b/lib/kokkos/core/unit_test/rocm/TestROCm_All.cpp @@ -0,0 +1,33 @@ +#include "rocm/TestROCm_Init.cpp" + +//#include "rocm/TestROCm_Complex.cpp" +#include "rocm/TestROCm_Reductions.cpp" +//#include "rocm/TestROCm_RangePolicy.cpp" +//#include "rocm/TestROCm_AtomicOperations.cpp" +//#include "rocm/TestROCm_Atomics.cpp" +//#include "rocm/TestROCm_AtomicViews.cpp" +//#include "rocm/TestROCm_Other.cpp" +//#include "rocm/TestROCm_Scan.cpp" +//#include "rocm/TestROCm_SharedAlloc.cpp" +//#include "rocm/TestROCm_SubView_a.cpp" +//#include "rocm/TestROCm_SubView_b.cpp" +//#include "rocm/TestROCm_SubView_c01.cpp" +//#include "rocm/TestROCm_SubView_c02.cpp" +//#include "rocm/TestROCm_SubView_c03.cpp" +//#include "rocm/TestROCm_SubView_c04.cpp" +//#include "rocm/TestROCm_SubView_c05.cpp" +//#include "rocm/TestROCm_SubView_c06.cpp" +//#include "rocm/TestROCm_SubView_c07.cpp" +//#include "rocm/TestROCm_SubView_c08.cpp" +//#include "rocm/TestROCm_SubView_c09.cpp" +//#include "rocm/TestROCm_SubView_c10.cpp" +//#include "rocm/TestROCm_SubView_c11.cpp" +//#include "rocm/TestROCm_SubView_c12.cpp" +//#include "rocm/TestROCm_Team.cpp" +//#include "rocm/TestROCm_TeamReductionScan.cpp" +//#include "rocm/TestROCm_TeamScratch.cpp" +//#include "rocm/TestROCm_ViewAPI_b.cpp" +//#include "rocm/TestROCm_ViewMapping_a.cpp" +//#include "rocm/TestROCm_ViewMapping_b.cpp" +//#include "rocm/TestROCm_ViewMapping_subview.cpp" +//#include "rocm/TestROCm_ViewOfClass.cpp" diff --git a/lib/kokkos/core/unit_test/rocm/TestROCm_AtomicOperations.cpp b/lib/kokkos/core/unit_test/rocm/TestROCm_AtomicOperations.cpp new file mode 100644 index 0000000000..e6b7a25316 --- /dev/null +++ b/lib/kokkos/core/unit_test/rocm/TestROCm_AtomicOperations.cpp @@ -0,0 +1,46 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include +#include + diff --git a/lib/kokkos/core/unit_test/rocm/TestROCm_AtomicViews.cpp b/lib/kokkos/core/unit_test/rocm/TestROCm_AtomicViews.cpp new file mode 100644 index 0000000000..d5f82826b0 --- /dev/null +++ b/lib/kokkos/core/unit_test/rocm/TestROCm_AtomicViews.cpp @@ -0,0 +1,47 @@ + +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include +#include + diff --git a/lib/kokkos/core/unit_test/rocm/TestROCm_Atomics.cpp b/lib/kokkos/core/unit_test/rocm/TestROCm_Atomics.cpp new file mode 100644 index 0000000000..5944830c43 --- /dev/null +++ b/lib/kokkos/core/unit_test/rocm/TestROCm_Atomics.cpp @@ -0,0 +1,46 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include +#include + diff --git a/lib/kokkos/core/unit_test/rocm/TestROCm_Category.hpp b/lib/kokkos/core/unit_test/rocm/TestROCm_Category.hpp new file mode 100644 index 0000000000..a34068f533 --- /dev/null +++ b/lib/kokkos/core/unit_test/rocm/TestROCm_Category.hpp @@ -0,0 +1,65 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#ifndef KOKKOS_TEST_ROCM_HPP +#define KOKKOS_TEST_ROCM_HPP + +#include + +namespace Test { + +class rocm : public ::testing::Test { +protected: + static void SetUpTestCase() { + } + + static void TearDownTestCase() { + } +}; + +} // namespace Test + +#define TEST_CATEGORY rocm +#define TEST_EXECSPACE Kokkos::Experimental::ROCm + +#endif diff --git a/lib/kokkos/core/unit_test/rocm/TestROCm_Complex.cpp b/lib/kokkos/core/unit_test/rocm/TestROCm_Complex.cpp new file mode 100644 index 0000000000..2b72cdee88 --- /dev/null +++ b/lib/kokkos/core/unit_test/rocm/TestROCm_Complex.cpp @@ -0,0 +1,47 @@ + +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include +#include + diff --git a/lib/kokkos/core/unit_test/rocm/TestROCm_Init.cpp b/lib/kokkos/core/unit_test/rocm/TestROCm_Init.cpp new file mode 100644 index 0000000000..dafe9fb529 --- /dev/null +++ b/lib/kokkos/core/unit_test/rocm/TestROCm_Init.cpp @@ -0,0 +1,50 @@ + +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include +#include +#include +#include + + diff --git a/lib/kokkos/core/unit_test/rocm/TestROCm_Other.cpp b/lib/kokkos/core/unit_test/rocm/TestROCm_Other.cpp new file mode 100644 index 0000000000..3e182dacba --- /dev/null +++ b/lib/kokkos/core/unit_test/rocm/TestROCm_Other.cpp @@ -0,0 +1,52 @@ + +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include +#include +#include +//include +#include +#include + +#include diff --git a/lib/kokkos/core/unit_test/rocm/TestROCm_RangePolicy.cpp b/lib/kokkos/core/unit_test/rocm/TestROCm_RangePolicy.cpp new file mode 100644 index 0000000000..ef7dad95a3 --- /dev/null +++ b/lib/kokkos/core/unit_test/rocm/TestROCm_RangePolicy.cpp @@ -0,0 +1,47 @@ + +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include +#include + diff --git a/lib/kokkos/core/unit_test/rocm/TestROCm_Reductions.cpp b/lib/kokkos/core/unit_test/rocm/TestROCm_Reductions.cpp new file mode 100644 index 0000000000..33c4d960f8 --- /dev/null +++ b/lib/kokkos/core/unit_test/rocm/TestROCm_Reductions.cpp @@ -0,0 +1,48 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include +#include +#include +#include + diff --git a/lib/kokkos/core/unit_test/rocm/TestROCm_Scan.cpp b/lib/kokkos/core/unit_test/rocm/TestROCm_Scan.cpp new file mode 100644 index 0000000000..ae0a016af3 --- /dev/null +++ b/lib/kokkos/core/unit_test/rocm/TestROCm_Scan.cpp @@ -0,0 +1,47 @@ + +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include +#include + diff --git a/lib/kokkos/core/unit_test/rocm/TestROCm_SharedAlloc.cpp b/lib/kokkos/core/unit_test/rocm/TestROCm_SharedAlloc.cpp new file mode 100644 index 0000000000..7a038edf4b --- /dev/null +++ b/lib/kokkos/core/unit_test/rocm/TestROCm_SharedAlloc.cpp @@ -0,0 +1,55 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include +#include + +namespace Test { + + +TEST_F( TEST_CATEGORY, impl_shared_alloc ) +{ + test_shared_alloc< Kokkos::Experimental::ROCmSpace, Kokkos::DefaultHostExecutionSpace >(); +} + +} // namespace Test diff --git a/lib/kokkos/core/unit_test/rocm/TestROCm_Spaces.cpp b/lib/kokkos/core/unit_test/rocm/TestROCm_Spaces.cpp new file mode 100644 index 0000000000..d44e7afec3 --- /dev/null +++ b/lib/kokkos/core/unit_test/rocm/TestROCm_Spaces.cpp @@ -0,0 +1,196 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include +#include + +namespace Test { + +KOKKOS_INLINE_FUNCTION +void test_abort() +{ + Kokkos::abort( "test_abort" ); +} + +KOKKOS_INLINE_FUNCTION +void test_rocm_spaces_int_value( int * ptr ) +{ + if ( *ptr == 42 ) { *ptr = 2 * 42; } +} + +TEST_F( rocm, space_access ) +{ + static_assert( + Kokkos::Impl::MemorySpaceAccess< Kokkos::HostSpace, Kokkos::HostSpace >::assignable, "" ); + + static_assert( + Kokkos::Impl::MemorySpaceAccess< Kokkos::HostSpace, Kokkos::Experimental::ROCmHostPinnedSpace >::assignable, "" ); + + static_assert( + ! Kokkos::Impl::MemorySpaceAccess< Kokkos::HostSpace, Kokkos::Experimental::ROCmSpace >::assignable, "" ); + + static_assert( + ! Kokkos::Impl::MemorySpaceAccess< Kokkos::HostSpace, Kokkos::Experimental::ROCmSpace >::accessible, "" ); + + //-------------------------------------- + + static_assert( + Kokkos::Impl::MemorySpaceAccess< Kokkos::Experimental::ROCmSpace, Kokkos::Experimental::ROCmSpace >::assignable, "" ); + + static_assert( + ! Kokkos::Impl::MemorySpaceAccess< Kokkos::Experimental::ROCmSpace, Kokkos::Experimental::ROCmHostPinnedSpace >::assignable, "" ); + + static_assert( + Kokkos::Impl::MemorySpaceAccess< Kokkos::Experimental::ROCmSpace, Kokkos::Experimental::ROCmHostPinnedSpace >::accessible, "" ); + + static_assert( + ! Kokkos::Impl::MemorySpaceAccess< Kokkos::Experimental::ROCmSpace, Kokkos::HostSpace >::assignable, "" ); + + static_assert( + ! Kokkos::Impl::MemorySpaceAccess< Kokkos::Experimental::ROCmSpace, Kokkos::HostSpace >::accessible, "" ); + + //-------------------------------------- + + static_assert( + Kokkos::Impl::MemorySpaceAccess< Kokkos::Experimental::ROCmHostPinnedSpace, Kokkos::Experimental::ROCmHostPinnedSpace >::assignable, "" ); + + static_assert( + ! Kokkos::Impl::MemorySpaceAccess< Kokkos::Experimental::ROCmHostPinnedSpace, Kokkos::HostSpace >::assignable, "" ); + + static_assert( + Kokkos::Impl::MemorySpaceAccess< Kokkos::Experimental::ROCmHostPinnedSpace, Kokkos::HostSpace >::accessible, "" ); + + static_assert( + ! Kokkos::Impl::MemorySpaceAccess< Kokkos::Experimental::ROCmHostPinnedSpace, Kokkos::Experimental::ROCmSpace >::assignable, "" ); + + static_assert( + ! Kokkos::Impl::MemorySpaceAccess< Kokkos::Experimental::ROCmHostPinnedSpace, Kokkos::Experimental::ROCmSpace >::accessible, "" ); + + //-------------------------------------- + + static_assert( + ! Kokkos::Impl::SpaceAccessibility< Kokkos::Experimental::ROCm, Kokkos::HostSpace >::accessible, "" ); + + static_assert( + Kokkos::Impl::SpaceAccessibility< Kokkos::Experimental::ROCm, Kokkos::Experimental::ROCmSpace >::accessible, "" ); + + static_assert( + Kokkos::Impl::SpaceAccessibility< Kokkos::Experimental::ROCm, Kokkos::Experimental::ROCmHostPinnedSpace >::accessible, "" ); + + static_assert( + ! Kokkos::Impl::SpaceAccessibility< Kokkos::HostSpace, Kokkos::Experimental::ROCmSpace >::accessible, "" ); + + static_assert( + Kokkos::Impl::SpaceAccessibility< Kokkos::HostSpace, Kokkos::Experimental::ROCmHostPinnedSpace >::accessible, "" ); + + static_assert( + std::is_same< Kokkos::Impl::HostMirror< Kokkos::Experimental::ROCmSpace >::Space + , Kokkos::HostSpace >::value, "" ); + + static_assert( + std::is_same< Kokkos::Impl::HostMirror< Kokkos::Experimental::ROCmHostPinnedSpace >::Space + , Kokkos::Experimental::ROCmHostPinnedSpace >::value, "" ); + + static_assert( + Kokkos::Impl::SpaceAccessibility + < Kokkos::Impl::HostMirror< Kokkos::Experimental::ROCm >::Space + , Kokkos::HostSpace + >::accessible, "" ); + + static_assert( + Kokkos::Impl::SpaceAccessibility + < Kokkos::Impl::HostMirror< Kokkos::Experimental::ROCmSpace >::Space + , Kokkos::HostSpace + >::accessible, "" ); + + static_assert( + Kokkos::Impl::SpaceAccessibility + < Kokkos::Impl::HostMirror< Kokkos::Experimental::ROCmHostPinnedSpace >::Space + , Kokkos::HostSpace + >::accessible, "" ); +} + +template< class MemSpace, class ExecSpace > +struct TestViewROCmAccessible { + enum { N = 1000 }; + + using V = Kokkos::View< double*, MemSpace >; + + V m_base; + + struct TagInit {}; + struct TagTest {}; + + KOKKOS_INLINE_FUNCTION + void operator()( const TagInit &, const int i ) const { m_base[i] = i + 1; } + + KOKKOS_INLINE_FUNCTION + void operator()( const TagTest &, const int i, long & error_count ) const + { if ( m_base[i] != i + 1 ) ++error_count; } + + TestViewROCmAccessible() + : m_base( "base", N ) + {} + + static void run() + { + TestViewROCmAccessible self; + Kokkos::parallel_for( Kokkos::RangePolicy< typename MemSpace::execution_space, TagInit >( 0, N ), self ); + MemSpace::execution_space::fence(); + + // Next access is a different execution space, must complete prior kernel. + long error_count = -1; + Kokkos::parallel_reduce( Kokkos::RangePolicy< ExecSpace, TagTest >( 0, N ), self, error_count ); + EXPECT_EQ( error_count, 0 ); + } +}; + +TEST_F( rocm, impl_view_accessible ) +{ + TestViewROCmAccessible< Kokkos::Experimental::ROCmSpace, Kokkos::Experimental::ROCm >::run(); + + TestViewROCmAccessible< Kokkos::Experimental::ROCmHostPinnedSpace, Kokkos::Experimental::ROCm >::run(); + TestViewROCmAccessible< Kokkos::Experimental::ROCmHostPinnedSpace, Kokkos::HostSpace::execution_space >::run(); +} + +} // namespace Test diff --git a/lib/kokkos/core/unit_test/rocm/TestROCm_SubView_a.cpp b/lib/kokkos/core/unit_test/rocm/TestROCm_SubView_a.cpp new file mode 100644 index 0000000000..ea39a25b5c --- /dev/null +++ b/lib/kokkos/core/unit_test/rocm/TestROCm_SubView_a.cpp @@ -0,0 +1,104 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include +#include + +namespace Test { + +TEST_F( TEST_CATEGORY, view_subview_auto_1d_left ) +{ + TestViewSubview::test_auto_1d< Kokkos::LayoutLeft, TEST_EXECSPACE >(); +} + +TEST_F( TEST_CATEGORY, view_subview_auto_1d_right ) +{ + TestViewSubview::test_auto_1d< Kokkos::LayoutRight, TEST_EXECSPACE >(); +} + +TEST_F( TEST_CATEGORY, view_subview_auto_1d_stride ) +{ + TestViewSubview::test_auto_1d< Kokkos::LayoutStride, TEST_EXECSPACE >(); +} + +TEST_F( TEST_CATEGORY, view_subview_assign_strided ) +{ + TestViewSubview::test_1d_strided_assignment< TEST_EXECSPACE >(); +} + +TEST_F( TEST_CATEGORY, view_subview_left_0 ) +{ + TestViewSubview::test_left_0< TEST_EXECSPACE >(); +} + +TEST_F( TEST_CATEGORY, view_subview_left_1 ) +{ + TestViewSubview::test_left_1< TEST_EXECSPACE >(); +} + +TEST_F( TEST_CATEGORY, view_subview_left_2 ) +{ + TestViewSubview::test_left_2< TEST_EXECSPACE >(); +} + +TEST_F( TEST_CATEGORY, view_subview_left_3 ) +{ + TestViewSubview::test_left_3< TEST_EXECSPACE >(); +} + +TEST_F( TEST_CATEGORY, view_subview_right_0 ) +{ + TestViewSubview::test_right_0< TEST_EXECSPACE >(); +} + +TEST_F( TEST_CATEGORY, view_subview_right_1 ) +{ + TestViewSubview::test_right_1< TEST_EXECSPACE >(); +} + +TEST_F( TEST_CATEGORY, view_subview_right_3 ) +{ + TestViewSubview::test_right_3< TEST_EXECSPACE >(); +} + +} // namespace Test diff --git a/lib/kokkos/core/unit_test/rocm/TestROCm_SubView_b.cpp b/lib/kokkos/core/unit_test/rocm/TestROCm_SubView_b.cpp new file mode 100644 index 0000000000..00a3a341bb --- /dev/null +++ b/lib/kokkos/core/unit_test/rocm/TestROCm_SubView_b.cpp @@ -0,0 +1,63 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include +#include + +namespace Test { + +TEST_F( TEST_CATEGORY, view_subview_layoutleft_to_layoutleft ) +{ + TestViewSubview::test_layoutleft_to_layoutleft< TEST_EXECSPACE >(); + TestViewSubview::test_layoutleft_to_layoutleft< TEST_EXECSPACE, Kokkos::MemoryTraits >(); + TestViewSubview::test_layoutleft_to_layoutleft< TEST_EXECSPACE, Kokkos::MemoryTraits >(); +} + +TEST_F( TEST_CATEGORY, view_subview_layoutright_to_layoutright ) +{ + TestViewSubview::test_layoutright_to_layoutright< TEST_EXECSPACE >(); + TestViewSubview::test_layoutright_to_layoutright< TEST_EXECSPACE, Kokkos::MemoryTraits >(); + TestViewSubview::test_layoutright_to_layoutright< TEST_EXECSPACE, Kokkos::MemoryTraits >(); +} + +} // namespace Test diff --git a/lib/kokkos/core/unit_test/rocm/TestROCm_SubView_c01.cpp b/lib/kokkos/core/unit_test/rocm/TestROCm_SubView_c01.cpp new file mode 100644 index 0000000000..c17b0722e9 --- /dev/null +++ b/lib/kokkos/core/unit_test/rocm/TestROCm_SubView_c01.cpp @@ -0,0 +1,54 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include +#include + +namespace Test { + +TEST_F( TEST_CATEGORY, view_subview_1d_assign ) +{ + TestViewSubview::test_1d_assign< TEST_EXECSPACE >(); +} + +} // namespace Test diff --git a/lib/kokkos/core/unit_test/rocm/TestROCm_SubView_c02.cpp b/lib/kokkos/core/unit_test/rocm/TestROCm_SubView_c02.cpp new file mode 100644 index 0000000000..e723b43323 --- /dev/null +++ b/lib/kokkos/core/unit_test/rocm/TestROCm_SubView_c02.cpp @@ -0,0 +1,54 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include +#include + +namespace Test { + +TEST_F( TEST_CATEGORY, view_subview_1d_assign_atomic ) +{ + TestViewSubview::test_1d_assign< TEST_EXECSPACE, Kokkos::MemoryTraits >(); +} + +} // namespace Test diff --git a/lib/kokkos/core/unit_test/rocm/TestROCm_SubView_c03.cpp b/lib/kokkos/core/unit_test/rocm/TestROCm_SubView_c03.cpp new file mode 100644 index 0000000000..b1170a70f5 --- /dev/null +++ b/lib/kokkos/core/unit_test/rocm/TestROCm_SubView_c03.cpp @@ -0,0 +1,54 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include +#include + +namespace Test { + +TEST_F( TEST_CATEGORY, view_subview_1d_assign_randomaccess ) +{ + TestViewSubview::test_1d_assign< TEST_EXECSPACE, Kokkos::MemoryTraits >(); +} + +} // namespace Test diff --git a/lib/kokkos/core/unit_test/rocm/TestROCm_SubView_c04.cpp b/lib/kokkos/core/unit_test/rocm/TestROCm_SubView_c04.cpp new file mode 100644 index 0000000000..0788a82ba4 --- /dev/null +++ b/lib/kokkos/core/unit_test/rocm/TestROCm_SubView_c04.cpp @@ -0,0 +1,54 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include +#include + +namespace Test { + +TEST_F( TEST_CATEGORY, view_subview_2d_from_3d ) +{ + TestViewSubview::test_2d_subview_3d< TEST_EXECSPACE >(); +} + +} // namespace Test diff --git a/lib/kokkos/core/unit_test/rocm/TestROCm_SubView_c05.cpp b/lib/kokkos/core/unit_test/rocm/TestROCm_SubView_c05.cpp new file mode 100644 index 0000000000..8d075a37c0 --- /dev/null +++ b/lib/kokkos/core/unit_test/rocm/TestROCm_SubView_c05.cpp @@ -0,0 +1,54 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include +#include + +namespace Test { + +TEST_F( TEST_CATEGORY, view_subview_2d_from_3d_atomic ) +{ + TestViewSubview::test_2d_subview_3d< TEST_EXECSPACE, Kokkos::MemoryTraits >(); +} + +} // namespace Test diff --git a/lib/kokkos/core/unit_test/rocm/TestROCm_SubView_c06.cpp b/lib/kokkos/core/unit_test/rocm/TestROCm_SubView_c06.cpp new file mode 100644 index 0000000000..b9dc782571 --- /dev/null +++ b/lib/kokkos/core/unit_test/rocm/TestROCm_SubView_c06.cpp @@ -0,0 +1,54 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include +#include + +namespace Test { + +TEST_F( TEST_CATEGORY, view_subview_2d_from_3d_randomaccess ) +{ + TestViewSubview::test_2d_subview_3d< TEST_EXECSPACE, Kokkos::MemoryTraits >(); +} + +} // namespace Test diff --git a/lib/kokkos/core/unit_test/rocm/TestROCm_SubView_c07.cpp b/lib/kokkos/core/unit_test/rocm/TestROCm_SubView_c07.cpp new file mode 100644 index 0000000000..54c46095aa --- /dev/null +++ b/lib/kokkos/core/unit_test/rocm/TestROCm_SubView_c07.cpp @@ -0,0 +1,54 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include +#include + +namespace Test { + +TEST_F( TEST_CATEGORY, view_subview_3d_from_5d_left ) +{ + TestViewSubview::test_3d_subview_5d_left< TEST_EXECSPACE >(); +} + +} // namespace Test diff --git a/lib/kokkos/core/unit_test/rocm/TestROCm_SubView_c08.cpp b/lib/kokkos/core/unit_test/rocm/TestROCm_SubView_c08.cpp new file mode 100644 index 0000000000..369e16a795 --- /dev/null +++ b/lib/kokkos/core/unit_test/rocm/TestROCm_SubView_c08.cpp @@ -0,0 +1,54 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include +#include + +namespace Test { + +TEST_F( TEST_CATEGORY, view_subview_3d_from_5d_left_atomic ) +{ + TestViewSubview::test_3d_subview_5d_left< TEST_EXECSPACE, Kokkos::MemoryTraits >(); +} + +} // namespace Test diff --git a/lib/kokkos/core/unit_test/rocm/TestROCm_SubView_c09.cpp b/lib/kokkos/core/unit_test/rocm/TestROCm_SubView_c09.cpp new file mode 100644 index 0000000000..b97926f98e --- /dev/null +++ b/lib/kokkos/core/unit_test/rocm/TestROCm_SubView_c09.cpp @@ -0,0 +1,54 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include +#include + +namespace Test { + +TEST_F( TEST_CATEGORY, view_subview_3d_from_5d_left_randomaccess ) +{ + TestViewSubview::test_3d_subview_5d_left< TEST_EXECSPACE, Kokkos::MemoryTraits >(); +} + +} // namespace Test diff --git a/lib/kokkos/core/unit_test/rocm/TestROCm_SubView_c10.cpp b/lib/kokkos/core/unit_test/rocm/TestROCm_SubView_c10.cpp new file mode 100644 index 0000000000..a1d47e0fbd --- /dev/null +++ b/lib/kokkos/core/unit_test/rocm/TestROCm_SubView_c10.cpp @@ -0,0 +1,54 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include +#include + +namespace Test { + +TEST_F( TEST_CATEGORY, view_subview_3d_from_5d_right ) +{ + TestViewSubview::test_3d_subview_5d_right< TEST_EXECSPACE >(); +} + +} // namespace Test diff --git a/lib/kokkos/core/unit_test/rocm/TestROCm_SubView_c11.cpp b/lib/kokkos/core/unit_test/rocm/TestROCm_SubView_c11.cpp new file mode 100644 index 0000000000..5be70dc22e --- /dev/null +++ b/lib/kokkos/core/unit_test/rocm/TestROCm_SubView_c11.cpp @@ -0,0 +1,54 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include +#include + +namespace Test { + +TEST_F( TEST_CATEGORY, view_subview_3d_from_5d_right_atomic ) +{ + TestViewSubview::test_3d_subview_5d_right< TEST_EXECSPACE, Kokkos::MemoryTraits >(); +} + +} // namespace Test diff --git a/lib/kokkos/core/unit_test/rocm/TestROCm_SubView_c12.cpp b/lib/kokkos/core/unit_test/rocm/TestROCm_SubView_c12.cpp new file mode 100644 index 0000000000..8135476662 --- /dev/null +++ b/lib/kokkos/core/unit_test/rocm/TestROCm_SubView_c12.cpp @@ -0,0 +1,54 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include +#include + +namespace Test { + +TEST_F( TEST_CATEGORY, view_subview_3d_from_5d_right_randomaccess ) +{ + TestViewSubview::test_3d_subview_5d_right< TEST_EXECSPACE, Kokkos::MemoryTraits >(); +} + +} // namespace Test diff --git a/lib/kokkos/core/unit_test/rocm/TestROCm_Team.cpp b/lib/kokkos/core/unit_test/rocm/TestROCm_Team.cpp new file mode 100644 index 0000000000..054bbd83c8 --- /dev/null +++ b/lib/kokkos/core/unit_test/rocm/TestROCm_Team.cpp @@ -0,0 +1,75 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include +#include + +namespace Test { + +TEST_F( TEST_CATEGORY, team_for ) +{ + TestTeamPolicy< TEST_EXECSPACE, Kokkos::Schedule >::test_for( 0 ); + TestTeamPolicy< TEST_EXECSPACE, Kokkos::Schedule >::test_for( 0 ); + + TestTeamPolicy< TEST_EXECSPACE, Kokkos::Schedule >::test_for( 2 ); + TestTeamPolicy< TEST_EXECSPACE, Kokkos::Schedule >::test_for( 2 ); + + TestTeamPolicy< TEST_EXECSPACE, Kokkos::Schedule >::test_for( 1000 ); + TestTeamPolicy< TEST_EXECSPACE, Kokkos::Schedule >::test_for( 1000 ); +} + + +TEST_F( TEST_CATEGORY, team_reduce ) +{ + TestTeamPolicy< TEST_EXECSPACE, Kokkos::Schedule >::test_reduce( 0 ); + TestTeamPolicy< TEST_EXECSPACE, Kokkos::Schedule >::test_reduce( 0 ); + TestTeamPolicy< TEST_EXECSPACE, Kokkos::Schedule >::test_reduce( 2 ); + TestTeamPolicy< TEST_EXECSPACE, Kokkos::Schedule >::test_reduce( 2 ); + TestTeamPolicy< TEST_EXECSPACE, Kokkos::Schedule >::test_reduce( 1000 ); + TestTeamPolicy< TEST_EXECSPACE, Kokkos::Schedule >::test_reduce( 1000 ); +} +} + +#include + + diff --git a/lib/kokkos/core/unit_test/rocm/TestROCm_TeamReductionScan.cpp b/lib/kokkos/core/unit_test/rocm/TestROCm_TeamReductionScan.cpp new file mode 100644 index 0000000000..ba0eb0e1bd --- /dev/null +++ b/lib/kokkos/core/unit_test/rocm/TestROCm_TeamReductionScan.cpp @@ -0,0 +1,82 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include +#include + +namespace Test { + +#if !defined(KOKKOS_ROCM_CLANG_WORKAROUND) +TEST_F( TEST_CATEGORY, team_scan ) +{ + TestScanTeam< TEST_EXECSPACE, Kokkos::Schedule >( 0 ); + TestScanTeam< TEST_EXECSPACE, Kokkos::Schedule >( 0 ); + TestScanTeam< TEST_EXECSPACE, Kokkos::Schedule >( 10 ); + TestScanTeam< TEST_EXECSPACE, Kokkos::Schedule >( 10 ); + TestScanTeam< TEST_EXECSPACE, Kokkos::Schedule >( 10000 ); + TestScanTeam< TEST_EXECSPACE, Kokkos::Schedule >( 10000 ); +} +#endif + +TEST_F( TEST_CATEGORY, team_long_reduce ) +{ + TestReduceTeam< long, TEST_EXECSPACE, Kokkos::Schedule >( 0 ); + TestReduceTeam< long, TEST_EXECSPACE, Kokkos::Schedule >( 0 ); + TestReduceTeam< long, TEST_EXECSPACE, Kokkos::Schedule >( 3 ); + TestReduceTeam< long, TEST_EXECSPACE, Kokkos::Schedule >( 3 ); + TestReduceTeam< long, TEST_EXECSPACE, Kokkos::Schedule >( 100000 ); + TestReduceTeam< long, TEST_EXECSPACE, Kokkos::Schedule >( 100000 ); +} + +TEST_F( TEST_CATEGORY, team_double_reduce ) +{ + TestReduceTeam< double, TEST_EXECSPACE, Kokkos::Schedule >( 0 ); + TestReduceTeam< double, TEST_EXECSPACE, Kokkos::Schedule >( 0 ); + TestReduceTeam< double, TEST_EXECSPACE, Kokkos::Schedule >( 3 ); + TestReduceTeam< double, TEST_EXECSPACE, Kokkos::Schedule >( 3 ); + TestReduceTeam< double, TEST_EXECSPACE, Kokkos::Schedule >( 100000 ); + TestReduceTeam< double, TEST_EXECSPACE, Kokkos::Schedule >( 100000 ); +} + +} // namespace Test + diff --git a/lib/kokkos/core/unit_test/rocm/TestROCm_TeamScratch.cpp b/lib/kokkos/core/unit_test/rocm/TestROCm_TeamScratch.cpp new file mode 100644 index 0000000000..351dfee2b5 --- /dev/null +++ b/lib/kokkos/core/unit_test/rocm/TestROCm_TeamScratch.cpp @@ -0,0 +1,83 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include +#include + +namespace Test { + +TEST_F( TEST_CATEGORY, team_shared_request ) +{ + TestSharedTeam< TEST_EXECSPACE, Kokkos::Schedule >(); + TestSharedTeam< TEST_EXECSPACE, Kokkos::Schedule >(); +} + +TEST_F( TEST_CATEGORY, team_scratch_request ) +{ + TestScratchTeam< TEST_EXECSPACE, Kokkos::Schedule >(); + TestScratchTeam< TEST_EXECSPACE, Kokkos::Schedule >(); +} + +#if defined( KOKKOS_ENABLE_CXX11_DISPATCH_LAMBDA ) +#if !defined(KOKKOS_ENABLE_ROCM) || ( 8000 <= ROCM_VERSION ) +TEST_F( TEST_CATEGORY, team_lambda_shared_request ) +{ + TestLambdaSharedTeam< Kokkos::HostSpace, TEST_EXECSPACE, Kokkos::Schedule >(); + TestLambdaSharedTeam< Kokkos::HostSpace, TEST_EXECSPACE, Kokkos::Schedule >(); +} +#endif +#endif + +TEST_F( TEST_CATEGORY, shmem_size ) +{ + TestShmemSize< TEST_EXECSPACE >(); +} + +TEST_F( TEST_CATEGORY, multi_level_scratch ) +{ + TestMultiLevelScratchTeam< TEST_EXECSPACE, Kokkos::Schedule >(); + TestMultiLevelScratchTeam< TEST_EXECSPACE, Kokkos::Schedule >(); +} + +} // namespace Test + diff --git a/lib/kokkos/core/unit_test/rocm/TestROCm_ViewAPI_b.cpp b/lib/kokkos/core/unit_test/rocm/TestROCm_ViewAPI_b.cpp new file mode 100644 index 0000000000..3e6f559438 --- /dev/null +++ b/lib/kokkos/core/unit_test/rocm/TestROCm_ViewAPI_b.cpp @@ -0,0 +1,45 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include +#include diff --git a/lib/kokkos/core/unit_test/rocm/TestROCm_ViewMapping_a.cpp b/lib/kokkos/core/unit_test/rocm/TestROCm_ViewMapping_a.cpp new file mode 100644 index 0000000000..a7b2b9695d --- /dev/null +++ b/lib/kokkos/core/unit_test/rocm/TestROCm_ViewMapping_a.cpp @@ -0,0 +1,46 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include +#include + diff --git a/lib/kokkos/core/unit_test/rocm/TestROCm_ViewMapping_b.cpp b/lib/kokkos/core/unit_test/rocm/TestROCm_ViewMapping_b.cpp new file mode 100644 index 0000000000..fa5b209f1b --- /dev/null +++ b/lib/kokkos/core/unit_test/rocm/TestROCm_ViewMapping_b.cpp @@ -0,0 +1,46 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include +#include + diff --git a/lib/kokkos/core/unit_test/rocm/TestROCm_ViewMapping_subview.cpp b/lib/kokkos/core/unit_test/rocm/TestROCm_ViewMapping_subview.cpp new file mode 100644 index 0000000000..0af114c7ea --- /dev/null +++ b/lib/kokkos/core/unit_test/rocm/TestROCm_ViewMapping_subview.cpp @@ -0,0 +1,46 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include +#include + diff --git a/lib/kokkos/core/unit_test/rocm/TestROCm_ViewOfClass.cpp b/lib/kokkos/core/unit_test/rocm/TestROCm_ViewOfClass.cpp new file mode 100644 index 0000000000..f0b95c0e00 --- /dev/null +++ b/lib/kokkos/core/unit_test/rocm/TestROCm_ViewOfClass.cpp @@ -0,0 +1,46 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include +#include + diff --git a/lib/kokkos/core/unit_test/serial/TestSerial_Crs.cpp b/lib/kokkos/core/unit_test/serial/TestSerial_Crs.cpp new file mode 100644 index 0000000000..5799ab816c --- /dev/null +++ b/lib/kokkos/core/unit_test/serial/TestSerial_Crs.cpp @@ -0,0 +1,45 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include +#include diff --git a/lib/kokkos/core/unit_test/threads/TestThreads_Crs.cpp b/lib/kokkos/core/unit_test/threads/TestThreads_Crs.cpp new file mode 100644 index 0000000000..25243273fe --- /dev/null +++ b/lib/kokkos/core/unit_test/threads/TestThreads_Crs.cpp @@ -0,0 +1,45 @@ +/* +//@HEADER +// ************************************************************************ +// +// Kokkos v. 2.0 +// Copyright (2014) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) +// +// ************************************************************************ +//@HEADER +*/ + +#include +#include diff --git a/lib/kokkos/generate_makefile.bash b/lib/kokkos/generate_makefile.bash index 6d636dc7e4..b4a69d30fd 100755 --- a/lib/kokkos/generate_makefile.bash +++ b/lib/kokkos/generate_makefile.bash @@ -31,6 +31,9 @@ do KOKKOS_DEVICES="${KOKKOS_DEVICES},Cuda" CUDA_PATH="${key#*=}" ;; + --with-rocm) + KOKKOS_DEVICES="${KOKKOS_DEVICES},ROCm" + ;; --with-openmp) KOKKOS_DEVICES="${KOKKOS_DEVICES},OpenMP" ;; @@ -56,6 +59,9 @@ do --with-hwloc*) HWLOC_PATH="${key#*=}" ;; + --with-memkind*) + MEMKIND_PATH="${key#*=}" + ;; --arch*) KOKKOS_ARCH="${key#*=}" ;; @@ -117,6 +123,7 @@ do echo " ARMv81 = ARMv8.1 Compatible CPU" echo " ARMv8-ThunderX = ARMv8 Cavium ThunderX CPU" echo " [IBM]" + echo " Power7 = IBM POWER7 and POWER7+ CPUs" echo " Power8 = IBM POWER8 CPUs" echo " Power9 = IBM POWER9 CPUs" echo " [Intel]" @@ -151,7 +158,8 @@ do echo " -lpthread, etc.)." echo "--with-gtest=/Path/To/Gtest: Set path to gtest. (Used in unit and performance" echo " tests.)" - echo "--with-hwloc=/Path/To/Hwloc: Set path to hwloc." + echo "--with-hwloc=/Path/To/Hwloc: Set path to hwloc library." + echo "--with-memkind=/Path/To/MemKind: Set path to memkind library." echo "--with-options=[OPT]: Additional options to Kokkos:" echo " compiler_warnings" echo " aggressive_vectorization = add ivdep on loops" @@ -228,7 +236,17 @@ else fi if [ ${#HWLOC_PATH} -gt 0 ]; then - KOKKOS_SETTINGS="${KOKKOS_SETTINGS} HWLOC_PATH=${HWLOC_PATH} KOKKOS_USE_TPLS=hwloc" + KOKKOS_SETTINGS="${KOKKOS_SETTINGS} HWLOC_PATH=${HWLOC_PATH}" + KOKKOS_USE_TPLS="${KOKKOS_USE_TPLS},hwloc" +fi + +if [ ${#MEMKIND_PATH} -gt 0 ]; then + KOKKOS_SETTINGS="${KOKKOS_SETTINGS} MEMKIND_PATH=${MEMKIND_PATH}" + KOKKOS_USE_TPLS="${KOKKOS_USE_TPLS},experimental_memkind" +fi + +if [ ${#KOKKOS_USE_TPLS} -gt 0 ]; then + KOKKOS_SETTINGS="${KOKKOS_SETTINGS} KOKKOS_USE_TPLS=${KOKKOS_USE_TPLS}" fi if [ ${#QTHREADS_PATH} -gt 0 ]; then From 26c15140be2059151e57dda6e59b04b57a15cb1d Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 22 Aug 2017 23:46:09 -0400 Subject: [PATCH 385/439] add USER-MESO files to .gitignore --- src/.gitignore | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/.gitignore b/src/.gitignore index 80166e260e..ff589bc701 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -60,6 +60,35 @@ /intel_preprocess.h /intel_simd.h +/atom_vec_edpd.cpp +/atom_vec_edpd.h +/atom_vec_mdpd.cpp +/atom_vec_mdpd.h +/atom_vec_tdpd.cpp +/atom_vec_tdpd.h +/compute_edpd_temp_atom.cpp +/compute_edpd_temp_atom.h +/compute_tdpd_cc_atom.cpp +/compute_tdpd_cc_atom.h +/fix_edpd_source.cpp +/fix_edpd_source.h +/fix_mvv_dpd.cpp +/fix_mvv_dpd.h +/fix_mvv_edpd.cpp +/fix_mvv_edpd.h +/fix_mvv_tdpd.cpp +/fix_mvv_tdpd.h +/fix_tdpd_source.cpp +/fix_tdpd_source.h +/pair_edpd.cpp +/pair_edpd.h +/pair_mdpd.cpp +/pair_mdpd.h +/pair_mdpd_rhosum.cpp +/pair_mdpd_rhosum.h +/pair_tdpd.cpp +/pair_tdpd.h + /compute_sna_atom.cpp /compute_sna_atom.h /compute_snad_atom.cpp From 79d5ca669dcb22fc78108d97ff321045e2a54c43 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 22 Aug 2017 23:46:32 -0400 Subject: [PATCH 386/439] fix issues indicated by compiler warnings --- src/USER-MESO/atom_vec_edpd.cpp | 4 ++-- src/USER-MESO/atom_vec_tdpd.cpp | 4 ++-- src/USER-MESO/pair_tdpd.cpp | 1 - 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/USER-MESO/atom_vec_edpd.cpp b/src/USER-MESO/atom_vec_edpd.cpp index 635743cc9e..385e8fd426 100644 --- a/src/USER-MESO/atom_vec_edpd.cpp +++ b/src/USER-MESO/atom_vec_edpd.cpp @@ -136,7 +136,7 @@ void AtomVecEDPD::force_clear(int n, size_t nbytes) int AtomVecEDPD::pack_comm(int n, int *list, double *buf, int pbc_flag, int *pbc) { - int i,j,k,m; + int i,j,m; double dx,dy,dz; m = 0; @@ -182,7 +182,7 @@ int AtomVecEDPD::pack_comm(int n, int *list, double *buf, int AtomVecEDPD::pack_comm_vel(int n, int *list, double *buf, int pbc_flag, int *pbc) { - int i,j,k,m; + int i,j,m; double dx,dy,dz,dvx,dvy,dvz; m = 0; diff --git a/src/USER-MESO/atom_vec_tdpd.cpp b/src/USER-MESO/atom_vec_tdpd.cpp index ce9e492029..34f2b1a031 100644 --- a/src/USER-MESO/atom_vec_tdpd.cpp +++ b/src/USER-MESO/atom_vec_tdpd.cpp @@ -851,8 +851,8 @@ void AtomVecTDPD::write_data(FILE *fp, int n, double **buf) (int) ubuf(buf[i][5]).i,(int) ubuf(buf[i][6]).i, (int) ubuf(buf[i][7]).i); for(int k = 0; k < cc_species; k++) - fprintf(fp,TAGINT_FORMAT " %-1.16e",buf[i][8+k]); - fprintf(fp,TAGINT_FORMAT "\n"); + fprintf(fp," %-1.16e",buf[i][8+k]); + fprintf(fp,"\n"); } } diff --git a/src/USER-MESO/pair_tdpd.cpp b/src/USER-MESO/pair_tdpd.cpp index 22c856ee3f..1f2bd4eb6c 100644 --- a/src/USER-MESO/pair_tdpd.cpp +++ b/src/USER-MESO/pair_tdpd.cpp @@ -91,7 +91,6 @@ PairTDPD::~PairTDPD() void PairTDPD::compute(int eflag, int vflag) { double evdwl = 0.0; - double fpair; if (eflag || vflag) ev_setup(eflag,vflag); else evflag = vflag_fdotr = 0; From b80752a40c564e70c5b7b91f5ddb610a8376409d Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 23 Aug 2017 00:01:19 -0400 Subject: [PATCH 387/439] restore changes to read_data docs, that would have been lost due to merging an outdated version --- doc/src/read_data.txt | 48 +++++++++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/doc/src/read_data.txt b/doc/src/read_data.txt index 747c3e752d..6000a80976 100644 --- a/doc/src/read_data.txt +++ b/doc/src/read_data.txt @@ -14,7 +14,7 @@ read_data file keyword args ... :pre file = name of data file to read in :ulb,l zero or more keyword/arg pairs may be appended :l -keyword = {add} or {offset} or {shift} or {extra/atom/types} or {extra/bond/types} or {extra/angle/types} or {extra/dihedral/types} or {extra/improper/types} or {group} or {nocoeff} or {fix} :l +keyword = {add} or {offset} or {shift} or {extra/atom/types} or {extra/bond/types} or {extra/angle/types} or {extra/dihedral/types} or {extra/improper/types} or {extra/bond/per/atom} or {extra/angle/per/atom} or {extra/dihedral/per/atom} or {extra/improper/per/atom} or {group} or {nocoeff} or {fix} :l {add} arg = {append} or {Nstart} or {merge} append = add new atoms with IDs appended to current IDs Nstart = add new atoms with IDs starting with Nstart @@ -32,6 +32,11 @@ keyword = {add} or {offset} or {shift} or {extra/atom/types} or {extra/bond/type {extra/angle/types} arg = # of extra angle types {extra/dihedral/types} arg = # of extra dihedral types {extra/improper/types} arg = # of extra improper types + {extra/bond/per/atom} arg = leave space for this many new bonds per atom + {extra/angle/per/atom} arg = leave space for this many new angles per atom + {extra/dihedral/per/atom} arg = leave space for this many new dihedrals per atom + {extra/improper/per/atom} arg = leave space for this many new impropers per atom + {extra/special/per/atom} arg = leave space for extra 1-2,1-3,1-4 interactions per atom {group} args = groupID groupID = add atoms in data file to this group {nocoeff} = ignore force field parameters @@ -57,7 +62,7 @@ simulation. The file can be ASCII text or a gzipped text file atom coordinates; see the "read_restart"_read_restart.html and "create_atoms"_create_atoms.html commands for alternative methods. Also see the explanation of the "-restart command-line -switch"_Section_start.html#start_7 which can convert a restart file to +switch"_Section_start.html#start_6 which can convert a restart file to a data file. This command can be used multiple times to add new atoms and their @@ -264,11 +269,11 @@ is different than the default. {angle types} = # of angle types in system {dihedral types} = # of dihedral types in system {improper types} = # of improper types in system -{extra bond per atom} = leave space for this many new bonds per atom -{extra angle per atom} = leave space for this many new angles per atom -{extra dihedral per atom} = leave space for this many new dihedrals per atom -{extra improper per atom} = leave space for this many new impropers per atom -{extra special per atom} = leave space for this many new special bonds per atom +{extra bond per atom} = leave space for this many new bonds per atom (deprecated, use extra/bond/per/atom keyword) +{extra angle per atom} = leave space for this many new angles per atom (deprecated, use extra/angle/per/atom keyword) +{extra dihedral per atom} = leave space for this many new dihedrals per atom (deprecated, use extra/dihedral/per/atom keyword) +{extra improper per atom} = leave space for this many new impropers per atom (deprecated, use extra/improper/per/atom keyword) +{extra special per atom} = leave space for this many new special bonds per atom (deprecated, use extra/special/per/atom keyword) {ellipsoids} = # of ellipsoids in system {lines} = # of line segments in system {triangles} = # of triangles in system @@ -367,25 +372,32 @@ read_data command will generate an error in this case. The "extra bond per atom" setting (angle, dihedral, improper) is only needed if new bonds (angles, dihedrals, impropers) will be added to the system when a simulation runs, e.g. by using the "fix -bond/create"_fix_bond_create.html command. This will pre-allocate -space in LAMMPS data structures for storing the new bonds (angles, +bond/create"_fix_bond_create.html command. Using this header flag +is deprecated; please use the {extra/bond/per/atom} keyword (and +correspondingly for angles, dihedrals and impropers) in the +read_data command instead. Either will pre-allocate space in LAMMPS + data structures for storing the new bonds (angles, dihedrals, impropers). The "extra special per atom" setting is typically only needed if new bonds/angles/etc will be added to the system, e.g. by using the "fix bond/create"_fix_bond_create.html command. Or if entire new molecules -will be added to the system, e.g. by using the "fix -deposit"_fix_deposit.html or "fix pour"_fix_pour.html commands, which -will have more special 1-2,1-3,1-4 neighbors than any other molecules -defined in the data file. Using this setting will pre-allocate space -in the LAMMPS data structures for storing these neighbors. See the +will be added to the system, e.g. by using the +"fix deposit"_fix_deposit.html or "fix pour"_fix_pour.html commands, +which will have more special 1-2,1-3,1-4 neighbors than any other +molecules defined in the data file. Using this header flag is +deprecated; please use the {extra/special/per/atom} keyword instead. +Using this setting will pre-allocate space in the LAMMPS data +structures for storing these neighbors. See the "special_bonds"_special_bonds.html and "molecule"_molecule.html doc pages for more discussion of 1-2,1-3,1-4 neighbors. -NOTE: All of the "extra" settings are only used if they appear in the -first data file read; see the description of the {add} keyword above -for reading multiple data files. If they appear in later data files, -they are ignored. +NOTE: All of the "extra" settings are only applied in the first data +file read and when no simulation box has yet been created; as soon as +the simulation box is created (and read_data implies that), these +settings are {locked} and cannot be changed anymore. Please see the +description of the {add} keyword above for reading multiple data files. +If they appear in later data files, they are ignored. The "ellipsoids" and "lines" and "triangles" and "bodies" settings are only used with "atom_style ellipsoid or line or tri or From cdfb1aa0437591029e6c71bb802119a267fa9f2d Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 23 Aug 2017 00:39:52 -0400 Subject: [PATCH 388/439] make links unique, fix doc format warnings and add entries to administrative files --- doc/src/compute_edpd_temp_atom.txt | 5 +++-- doc/src/compute_tdpd_cc_atom.txt | 4 ++-- doc/src/computes.txt | 2 ++ doc/src/fix_dpd_source.txt | 8 ++++---- doc/src/fix_mvv_dpd.txt | 4 ++-- doc/src/fixes.txt | 2 ++ doc/src/lammps.book | 6 +++++- doc/src/pair_dpd.txt | 4 ++-- doc/src/pair_snap.txt | 14 ++++++-------- doc/src/pairs.txt | 1 + doc/src/read_data.txt | 7 +++---- 11 files changed, 32 insertions(+), 25 deletions(-) diff --git a/doc/src/compute_edpd_temp_atom.txt b/doc/src/compute_edpd_temp_atom.txt index 30f8c1043a..5b8c8ebd67 100644 --- a/doc/src/compute_edpd_temp_atom.txt +++ b/doc/src/compute_edpd_temp_atom.txt @@ -26,7 +26,8 @@ for each eDPD particle in a group. The temperature is a local temperature derived from the internal energy of each eDPD particle based on the local equilibrium hypothesis. -For more details please see "(Espanol1997)"_#Espanol1997 and "(Li2014)"_#Li2014. +For more details please see "(Espanol1997)"_#Espanol1997 and +"(Li2014)"_#Li2014a. [Output info:] @@ -55,7 +56,7 @@ LAMMPS"_Section_start.html#start_3 section for more info. [(Espanol1997)] Espanol, Europhys Lett, 40(6): 631-636 (1997). DOI: 10.1209/epl/i1997-00515-8 -:link(Li2014) +:link(Li2014a) [(Li2014)] Li, Tang, Lei, Caswell, Karniadakis, J Comput Phys, 265: 113-127 (2014). DOI: 10.1016/j.jcp.2014.02.003. diff --git a/doc/src/compute_tdpd_cc_atom.txt b/doc/src/compute_tdpd_cc_atom.txt index 58a49fa59f..a6a12dc52c 100644 --- a/doc/src/compute_tdpd_cc_atom.txt +++ b/doc/src/compute_tdpd_cc_atom.txt @@ -28,7 +28,7 @@ group. The chemical concentration of each species is defined as the number of molecules carried by a tDPD particle for dilute solution. For more -details see "(Li2015)"_#Li2015. +details see "(Li2015)"_#Li2015a. [Output info:] @@ -54,7 +54,7 @@ LAMMPS"_Section_start.html#start_3 section for more info. :line -:link(Li2015) +:link(Li2015a) [(Li2015)] Li, Yazdani, Tartakovsky, Karniadakis, J Chem Phys, 143: 014101 (2015). DOI: 10.1063/1.4923254 diff --git a/doc/src/computes.txt b/doc/src/computes.txt index 5a6ca66c46..c443bfaba2 100644 --- a/doc/src/computes.txt +++ b/doc/src/computes.txt @@ -30,6 +30,7 @@ Computes :h1 compute_displace_atom compute_dpd compute_dpd_atom + compute_edpd_temp_atom compute_erotate_asphere compute_erotate_rigid compute_erotate_sphere @@ -95,6 +96,7 @@ Computes :h1 compute_sna_atom compute_stress_atom compute_tally + compute_tdpd_cc_atom compute_temp compute_temp_asphere compute_temp_body diff --git a/doc/src/fix_dpd_source.txt b/doc/src/fix_dpd_source.txt index de035a94b4..b6decc657c 100644 --- a/doc/src/fix_dpd_source.txt +++ b/doc/src/fix_dpd_source.txt @@ -46,8 +46,8 @@ where the {source} is in units of mole/volume/time. This command can be used to give an additional heat/concentration source term to atoms in a simulation, such as for a simulation of a -heat conduction with a source term (see Fig.12 in "(Li2014)"_#Li2014) -or diffusion with a source term (see Fig.1 in "(Li2015)"_#Li2015), as +heat conduction with a source term (see Fig.12 in "(Li2014)"_#Li2014b) +or diffusion with a source term (see Fig.1 in "(Li2015)"_#Li2015b), as an analog of a periodic Poiseuille flow problem. If the {sphere} keyword is used, the {cx,cy,cz,radius} defines a @@ -88,13 +88,13 @@ tdpd/cc/atom"_compute_tdpd_cc_atom.html :line -:link(Li2014) +:link(Li2014b) [(Li2014)] Z. Li, Y.-H. Tang, H. Lei, B. Caswell and G.E. Karniadakis, "Energy-conserving dissipative particle dynamics with temperature-dependent properties", J. Comput. Phys., 265: 113-127 (2014). DOI: 10.1016/j.jcp.2014.02.003 -:link(Li2015) +:link(Li2015b) [(Li2015)] Z. Li, A. Yazdani, A. Tartakovsky and G.E. Karniadakis, "Transport dissipative particle dynamics model for mesoscopic advection-diffusion-reaction problems", J. Chem. Phys., 143: 014101 diff --git a/doc/src/fix_mvv_dpd.txt b/doc/src/fix_mvv_dpd.txt index 75e13744ea..3c1c1a7cba 100644 --- a/doc/src/fix_mvv_dpd.txt +++ b/doc/src/fix_mvv_dpd.txt @@ -48,7 +48,7 @@ case-by-case basis. Specification of a {lambda} value is opttional. If specified, the setting must be from 0.0 to 1.0. If not specified, a default value of 0.5 is used, which effectively reproduces the standard velocity-Verlet (VV) scheme. For more details, see -"Groot"_#Groot. +"Groot"_#Groot2. Fix {mvv/dpd} updates the position and velocity of each atom. It can be used with the "pair_style mdpd"_pair_meso.html command or other @@ -91,7 +91,7 @@ The default value for the optional {lambda} parameter is 0.5. :line -:link(Groot) +:link(Groot2) [(Groot)] Groot and Warren, J Chem Phys, 107: 4423-4435 (1997). DOI: 10.1063/1.474784 diff --git a/doc/src/fixes.txt b/doc/src/fixes.txt index 3dc5e77e14..7000a66c51 100644 --- a/doc/src/fixes.txt +++ b/doc/src/fixes.txt @@ -33,6 +33,7 @@ Fixes :h1 fix_drude fix_drude_transform fix_dpd_energy + fix_dpd_source fix_dt_reset fix_efield fix_ehex @@ -71,6 +72,7 @@ Fixes :h1 fix_move fix_mscg fix_msst + fix_mvv_dpd fix_neb fix_nh fix_nh_eff diff --git a/doc/src/lammps.book b/doc/src/lammps.book index 76b6743657..37587937e7 100644 --- a/doc/src/lammps.book +++ b/doc/src/lammps.book @@ -156,6 +156,7 @@ fix_controller.html fix_deform.html fix_deposit.html fix_dpd_energy.html +fix_dpd_source.html fix_drag.html fix_drude.html fix_drude_transform.html @@ -197,6 +198,7 @@ fix_momentum.html fix_move.html fix_mscg.html fix_msst.html +fix_mvv_dpd.html fix_neb.html fix_nh.html fix_nh_eff.html @@ -315,6 +317,7 @@ compute_dipole_chunk.html compute_displace_atom.html compute_dpd.html compute_dpd_atom.html +compute_edpd_temp_atom.html compute_erotate_asphere.html compute_erotate_rigid.html compute_erotate_sphere.html @@ -380,6 +383,7 @@ compute_smd_vol.html compute_sna_atom.html compute_stress_atom.html compute_tally.html +compute_tdpd_cc_atom.html compute_temp.html compute_temp_asphere.html compute_temp_body.html @@ -457,6 +461,7 @@ pair_mdf.html pair_meam.html pair_meam_spline.html pair_meam_sw_spline.html +pair_meso.html pair_mgpt.html pair_mie.html pair_momb.html @@ -644,4 +649,3 @@ USER/atc/man_unfix_flux.html USER/atc/man_unfix_nodes.html USER/atc/man_write_atom_weights.html USER/atc/man_write_restart.html - diff --git a/doc/src/pair_dpd.txt b/doc/src/pair_dpd.txt index 9dd204ad2d..8d194bb092 100644 --- a/doc/src/pair_dpd.txt +++ b/doc/src/pair_dpd.txt @@ -36,7 +36,7 @@ pair_coeff 1 1 1.0 1.0 :pre [Description:] Style {dpd} computes a force field for dissipative particle dynamics -(DPD) following the exposition in "(Groot)"_#Groot. +(DPD) following the exposition in "(Groot)"_#Groot1. Style {dpd/tstat} invokes a DPD thermostat on pairwise interactions, which is equivalent to the non-conservative portion of the DPD force @@ -196,7 +196,7 @@ langevin"_fix_langevin.html, "pair_style srp"_pair_srp.html :line -:link(Groot) +:link(Groot1) [(Groot)] Groot and Warren, J Chem Phys, 107, 4423-35 (1997). :link(Afshar) diff --git a/doc/src/pair_snap.txt b/doc/src/pair_snap.txt index fa90dc34e9..593765aa63 100644 --- a/doc/src/pair_snap.txt +++ b/doc/src/pair_snap.txt @@ -10,8 +10,7 @@ pair_style snap command :h3 [Syntax:] -pair_style snap -:pre +pair_style snap :pre [Examples:] @@ -20,17 +19,16 @@ pair_coeff * * InP.snapcoeff In P InP.snapparam In In P P :pre [Description:] -Pair style {snap} computes interactions -using the spectral neighbor analysis potential (SNAP) -"(Thompson)"_#Thompson20142. Like the GAP framework of Bartok et al. -"(Bartok2010)"_#Bartok20102, "(Bartok2013)"_#Bartok2013 -which uses bispectrum components +Pair style {snap} computes interactions using the spectral +neighbor analysis potential (SNAP) "(Thompson)"_#Thompson20142. +Like the GAP framework of Bartok et al. "(Bartok2010)"_#Bartok20102, +"(Bartok2013)"_#Bartok2013 which uses bispectrum components to characterize the local neighborhood of each atom in a very general way. The mathematical definition of the bispectrum calculation used by SNAP is identical to that used by "compute sna/atom"_compute_sna_atom.html. In SNAP, the total energy is decomposed into a sum over -atom energies. The energy of atom {i } is +atom energies. The energy of atom {i} is expressed as a weighted sum over bispectrum components. :c,image(Eqs/pair_snap.jpg) diff --git a/doc/src/pairs.txt b/doc/src/pairs.txt index 2c1b20f4d3..ec21b7a02e 100644 --- a/doc/src/pairs.txt +++ b/doc/src/pairs.txt @@ -58,6 +58,7 @@ Pair Styles :h1 pair_meam pair_meam_spline pair_meam_sw_spline + pair_meso pair_mgpt pair_mie pair_momb diff --git a/doc/src/read_data.txt b/doc/src/read_data.txt index 6000a80976..8c9aa02e22 100644 --- a/doc/src/read_data.txt +++ b/doc/src/read_data.txt @@ -374,10 +374,9 @@ needed if new bonds (angles, dihedrals, impropers) will be added to the system when a simulation runs, e.g. by using the "fix bond/create"_fix_bond_create.html command. Using this header flag is deprecated; please use the {extra/bond/per/atom} keyword (and -correspondingly for angles, dihedrals and impropers) in the -read_data command instead. Either will pre-allocate space in LAMMPS - data structures for storing the new bonds (angles, -dihedrals, impropers). +correspondingly for angles, dihedrals and impropers) in the read_data +command instead. Either will pre-allocate space in LAMMPS data +structures for storing the new bonds (angles, dihedrals, impropers). The "extra special per atom" setting is typically only needed if new bonds/angles/etc will be added to the system, e.g. by using the "fix From 57aafba7c3bdf188481634761b209b15d6c9d20e Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 23 Aug 2017 07:54:05 -0400 Subject: [PATCH 389/439] remove old moltemplate version --- tools/moltemplate/LICENSE.TXT | 28 - tools/moltemplate/README.TXT | 61 - tools/moltemplate/examples/README.TXT | 24 - .../README.TXT | 28 - .../README_run.sh | 31 - .../README_setup.sh | 25 - .../README_visualize.txt | 87 - .../images/cyclododecane+watMW_t=0ps_LR.jpg | Bin 51874 -> 0 bytes .../images/cyclododecane+watMW_t=400ps_LR.jpg | Bin 39434 -> 0 bytes .../images/cyclododecane+watMW_t=50ps_LR.jpg | Bin 39341 -> 0 bytes .../images/cyclopentane.jpg | Bin 12330 -> 0 bytes .../images/cyclopentane_unrelaxed.jpg | Bin 12835 -> 0 bytes .../images/watMW.jpg | Bin 3141 -> 0 bytes .../moltemplate_files/README.sh | 11 - .../moltemplate_files/cyclododecane.lt | 55 - .../moltemplate_files/system.lt | 62 - .../moltemplate_files/trappe1998.lt | 50 - .../version_more_comments/system.lt | 80 - .../moltemplate_files/watmw.lt | 54 - .../run.in.npt | 61 - .../run.in.nvt | 81 - .../DPPC_bilayer_formation_PACKMOL/README.TXT | 15 - .../README_run.sh | 21 - .../README_setup.sh | 28 - .../README_visualize.txt | 87 - .../images/DPPC_martini_LR.jpg | Bin 12907 -> 0 bytes .../images/t=0_after_minimization_LR.jpg | Bin 43653 -> 0 bytes .../images/t=13ns_450K_NVT_LR.jpg | Bin 45240 -> 0 bytes .../images/t=26ns_300K_NPT_LR.jpg | Bin 44951 -> 0 bytes .../images/t=6ns_300K_NPT_LR.jpg | Bin 46724 -> 0 bytes .../images/water_martini_LR.jpg | Bin 1660 -> 0 bytes .../moltemplate_files/lipid.lt | 78 - .../moltemplate_files/system.lt | 24 - .../moltemplate_files/water.lt | 17 - .../packmol_files/README.TXT | 8 - .../packmol_files/lipid.xyz | 14 - .../packmol_files/mix_lipids+water.inp | 34 - .../packmol_files/water.xyz | 3 - .../DPPC_bilayer_formation_PACKMOL/run.in.min | 31 - .../DPPC_bilayer_formation_PACKMOL/run.in.npt | 117 - .../DPPC_bilayer_formation_PACKMOL/run.in.nvt | 50 - .../DPPC_bilayer_preformed/README.TXT | 13 - .../DPPC_bilayer_preformed/README_run.sh | 21 - .../DPPC_bilayer_preformed/README_setup.sh | 23 - .../README_visualize.txt | 87 - .../images/DPPC_martini_LR.jpg | Bin 12907 -> 0 bytes .../images/t=0_bilayer_preformed_GL_LR.jpg | Bin 40709 -> 0 bytes .../images/t=4ns_bilayer_preformed_GL_LR.jpg | Bin 57230 -> 0 bytes .../images/water_martini_LR.jpg | Bin 1660 -> 0 bytes .../moltemplate_files/lipid.lt | 78 - .../moltemplate_files/system.lt | 27 - .../moltemplate_files/water.lt | 17 - .../DPPC_bilayer_preformed/run.in.min | 31 - .../DPPC_bilayer_preformed/run.in.npt | 66 - .../DPPC_bilayer_preformed/run.in.nvt | 47 - .../abstract_2bead_heteropolymer/README.TXT | 17 - .../README_run.sh | 20 - .../README_setup.sh | 23 - .../README_visualize.txt | 86 - .../images/polymer.png | Bin 53044 -> 0 bytes .../images/t=0ns.png | Bin 101303 -> 0 bytes .../images/t=40ns_occ.png | Bin 29838 -> 0 bytes .../images/t=4ns_occ.png | Bin 37734 -> 0 bytes .../moltemplate_files/README.sh | 6 - .../moltemplate_files/forcefield.lt | 139 - .../moltemplate_files/monomers.lt | 86 - .../moltemplate_files/polymer.lt | 64 - .../moltemplate_files/system.lt | 36 - .../abstract_2bead_heteropolymer/run.in.nvt | 32 - .../abstract_random_heteropolymer/README.TXT | 19 - .../README_run.sh | 14 - .../README_setup.sh | 23 - .../README_visualize.txt | 87 - .../images/2bead.jpg | Bin 2713 -> 0 bytes .../images/3bead.jpg | Bin 4410 -> 0 bytes .../images/random_heteropolymer_30_20_t=0.jpg | Bin 52135 -> 0 bytes .../random_heteropolymer_30_20_t=700ps.jpg | Bin 46460 -> 0 bytes .../moltemplate_files/forcefield.lt | 107 - .../moltemplate_files/monomers.lt | 62 - .../moltemplate_files/polymer.lt | 163 - .../moltemplate_files/system.lt | 11 - .../abstract_random_heteropolymer/run.in.nvt | 29 - .../abstract_translocation/README.TXT | 23 - .../abstract_translocation/README_run.sh | 28 - .../abstract_translocation/README_setup.sh | 23 - .../README_visualize.txt | 87 - .../images/polymer_LR.jpg | Bin 5568 -> 0 bytes .../images/solvent_LR.jpg | Bin 23407 -> 0 bytes .../images/walls+solvent+polymer_t=0.jpg | Bin 105467 -> 0 bytes .../images/walls_LR.jpg | Bin 13280 -> 0 bytes .../moltemplate_files/monomer.lt | 111 - .../moltemplate_files/polymer.lt | 32 - .../moltemplate_files/solvent.lt | 23 - .../moltemplate_files/solvent_single.lt | 22 - .../moltemplate_files/system.lt | 57 - .../moltemplate_files/wall_single.lt | 21 - .../moltemplate_files/walls.lt | 23 - .../abstract_translocation/run.in.npt | 120 - .../abstract_translocation/run.in.nvt | 53 - .../README_FIRST.txt | 48 - ...EADME_NUCLEAR_VOLUME_FRACTION_ESTIMATE.txt | 29 - .../README_run.sh | 7 - .../README_setup.sh | 58 - .../README_visualize.txt | 131 - .../images/stage2_interior.jpg | Bin 40803 -> 0 bytes .../images/stage2_interior_rotated.jpg | Bin 25429 -> 0 bytes .../images/t=0_before_minimizaion.jpg | Bin 79709 -> 0 bytes .../images/vmd_colorscale_jet.tcl | 87 - .../README_how_to_generate_system_lt.sh | 19 - .../README_length_flexibility_details.txt | 57 - .../moltemplate_files/calc_table.sh | 8 - .../moltemplate_files/condensin.lt | 47 - .../moltemplate_files/coords_orig.raw | 32768 ---------------- .../moltemplate_files/generate_system_lt.py | 301 - .../moltemplate_files/interpolate_coords.py | 74 - .../moltemplate_files/monomer.lt | 84 - .../moltemplate_files/table_bonds_stage2.dat | 4011 -- .../run.in.min | 41 - .../run.in.stage1 | 110 - .../run.in.stage2 | 90 - .../membrane+protein/README.TXT | 70 - .../membrane+protein/README_WARNING.TXT | 10 - .../membrane+protein/README_run.sh | 33 - .../membrane+protein/README_setup.sh | 28 - .../membrane+protein/README_visualize.txt | 87 - .../4HelixOrig+Lipid2005_t=1290ps_LR.jpg | Bin 85276 -> 0 bytes .../images/membrane+protein_t=0ps_LR.jpg | Bin 71073 -> 0 bytes .../membrane+protein_t=0ps_no_pbc_LR.jpg | Bin 51659 -> 0 bytes .../images/membrane+protein_t=0ps_top_LR.jpg | Bin 67085 -> 0 bytes .../images/membrane+protein_t=5000ps_LR.jpg | Bin 71011 -> 0 bytes .../moltemplate_files/1beadProtSci2010.lt | 233 - .../1beadProtSci2010_variations.lt | 225 - .../moltemplate_files/CGLipidBr2005.lt | 196 - .../calc_table/calc_CGLipidTableINTvsINT.py | 29 - .../version_charmm_cutoff/calc_table.py | 70 - .../moltemplate_files/system.lt | 178 - .../moltemplate_files/table_int.dat | 1139 - .../membrane+protein/run.in.min | 35 - .../membrane+protein/run.in.npt | 66 - .../membrane+protein/run.in.nvt | 71 - .../membrane_BranniganPRE2005/README.TXT | 33 - .../membrane_BranniganPRE2005/README_run.sh | 33 - .../membrane_BranniganPRE2005/README_setup.sh | 28 - .../README_visualize.txt | 87 - .../membrane_BranniganPRE2005/images/DLPC.jpg | Bin 4915 -> 0 bytes .../DPPC+DLPC_bilayer32x37_t=0ps_LR.jpg | Bin 58412 -> 0 bytes ...DPPC+DLPC_bilayer32x37_t=0ps_no_pbc_LR.jpg | Bin 36618 -> 0 bytes .../DPPC+DLPC_bilayer32x37_t=500ps_LR.jpg | Bin 62029 -> 0 bytes .../membrane_BranniganPRE2005/images/DPPC.jpg | Bin 5834 -> 0 bytes .../moltemplate_files/CGLipidBr2005Orig.lt | 208 - .../calc_table/calc_table.py | 29 - .../version_charmm_cutoff/calc_table.py | 70 - .../moltemplate_files/system.lt | 94 - .../moltemplate_files/table_int.dat | 1139 - .../membrane_BranniganPRE2005/run.in.min | 28 - .../membrane_BranniganPRE2005/run.in.npt | 57 - .../membrane_BranniganPRE2005/run.in.nvt | 45 - .../1bead+chaperone/README.TXT | 33 - .../frustrated+chaperonin/README.TXT | 32 - .../frustrated+chaperonin/README_run.sh | 31 - .../frustrated+chaperonin/README_setup.sh | 24 - .../README_visualize.txt | 87 - .../psf_file_created_by_topotools/system.psf | 86 - .../images/misfolded+chaperonin_t=0tau_LR.jpg | Bin 15784 -> 0 bytes .../unfolded+chaperonin_t=508750tau_LR.jpg | Bin 17080 -> 0 bytes .../moltemplate_files/1beadFrustrated.lt | 216 - .../1beadFrustrated_variants.lt | 85 - .../moltemplate_files/chaperonin.lt | 41 - .../generate_tables/calc_chaperone_table.py | 87 - .../generate_tables/calc_dihedral_table.py | 67 - .../moltemplate_files/system.lt | 45 - .../table_chaperonin_h=0.475.dat | 1188 - .../table_chaperonin_h=0.dat | 1187 - .../table_dihedral_frustrated.dat | 735 - .../frustrated+chaperonin/run.in.min | 25 - .../frustrated+chaperonin/run.in.nvt | 48 - .../frustrated+minichaperone/README.TXT | 38 - .../frustrated+minichaperone/README_run.sh | 31 - .../frustrated+minichaperone/README_setup.sh | 24 - .../README_visualize.txt | 87 - .../psf_file_created_by_topotools/system.psf | 476 - ...ein2x2x2+minichaperones2x2x2_t=0tau_LR.jpg | Bin 31162 -> 0 bytes ...x2x2+minichaperones2x2x2_t=67500tau_LR.jpg | Bin 26258 -> 0 bytes .../moltemplate_files/1beadFrustrated.lt | 216 - .../1beadFrustrated_variants.lt | 85 - .../generate_tables/calc_chaperone_table.py | 87 - .../generate_tables/calc_dihedral_table.py | 67 - .../moltemplate_files/minichaperone.lt | 41 - .../moltemplate_files/system.lt | 72 - .../table_dihedral_frustrated.dat | 735 - .../table_minichaperone_h=0.6.dat | 988 - .../table_minichaperone_h=0.dat | 989 - .../frustrated+minichaperone/run.in.min | 24 - .../frustrated+minichaperone/run.in.nvt | 46 - .../1bead+chaperone/frustrated/README.TXT | 29 - .../1bead+chaperone/frustrated/README_run.sh | 21 - .../frustrated/README_setup.sh | 24 - .../frustrated/README_visualize.txt | 87 - .../psf_file_created_by_topotools/system.psf | 85 - .../images/initial_conformation_t=0tau.jpg | Bin 23358 -> 0 bytes .../misfolded_conformation_t=1250tau.jpg | Bin 23090 -> 0 bytes .../moltemplate_files/1beadFrustrated.lt | 216 - .../1beadFrustrated_variants.lt | 85 - .../generate_tables/calc_dihedral_table.py | 67 - .../frustrated/moltemplate_files/system.lt | 20 - .../table_dihedral_frustrated.dat | 735 - .../1bead+chaperone/frustrated/run.in.min | 19 - .../frustrated/run_short_sim.in.nvt | 50 - .../unfrustrated+chaperonin/README.TXT | 32 - .../unfrustrated+chaperonin/README_run.sh | 31 - .../unfrustrated+chaperonin/README_setup.sh | 24 - .../README_visualize.txt | 87 - .../psf_file_created_by_topotools/system.psf | 98 - .../unfrustrated+chaperonin_t=0tau_LR.jpg | Bin 16267 -> 0 bytes .../unfrustrated+chaperonin_t=105tau_LR.jpg | Bin 14944 -> 0 bytes .../moltemplate_files/1beadUnfrustrated.lt | 255 - .../1beadUnfrustrated_variants.lt | 45 - .../moltemplate_files/chaperonin.lt | 41 - .../generate_tables/calc_chaperone_table.py | 87 - .../moltemplate_files/system.lt | 45 - .../table_chaperonin_h=0.475.dat | 1188 - .../table_chaperonin_h=0.dat | 1187 - .../unfrustrated+chaperonin/run.in.min | 19 - .../unfrustrated+chaperonin/run.in.nvt | 48 - .../1bead+chaperone/unfrustrated/README.TXT | 27 - .../unfrustrated/README_run.sh | 31 - .../unfrustrated/README_setup.sh | 23 - .../unfrustrated/README_visualize.txt | 87 - .../psf_file_created_by_topotools/system.psf | 97 - .../images/unfrustrated_t=0tau_LR.jpg | Bin 7690 -> 0 bytes .../images/unfrustrated_t=200tau_LR.jpg | Bin 7821 -> 0 bytes .../moltemplate_files/1beadUnfrustrated.lt | 255 - .../1beadUnfrustrated_variants.lt | 45 - .../unfrustrated/moltemplate_files/system.lt | 11 - .../1bead+chaperone/unfrustrated/run.in.min | 19 - .../1bead+chaperone/unfrustrated/run.in.nvt | 46 - .../1beadProtSci2010/README.TXT | 44 - .../1beadProtSci2010/README_run.sh | 31 - .../1beadProtSci2010/README_setup.sh | 23 - .../1beadProtSci2010/README_visualize.txt | 87 - .../images/4HelixBundle_t=0.jpg | Bin 38619 -> 0 bytes .../images/4SheetBundle_t=0.jpg | Bin 49905 -> 0 bytes .../psf_file_created_by_topotools/system.psf | 214 - .../moltemplate_files/1beadProtSci2010.lt | 274 - .../moltemplate_files/README.sh | 13 - .../other_implementations/README.TXT | 13 - .../charmm/1beadProtSci2010.lt | 411 - .../class2/1beadProtSci2010.lt | 385 - .../moltemplate_files/system.lt | 12 - .../1beadProtSci2010/run.in.min | 19 - .../1beadProtSci2010/run.in.nvt | 44 - .../README.TXT | 114 - .../README_WARNING.TXT | 20 - .../README_run.sh | 24 - .../README_setup.sh | 65 - .../README_visualize.txt | 87 - .../images/vesicle_membrane+protein_L.jpg | Bin 284201 -> 0 bytes .../moltemplate_files/1beadProtSci2010.lt | 233 - .../1beadProtSci2010_variations.lt | 225 - .../moltemplate_files/CGLipidBr2005.lt | 196 - .../moltemplate_files/README.sh | 22 - .../calc_table/calc_CGLipidTableINTvsINT.py | 29 - .../version_charmm_cutoff/calc_table.py | 70 - .../moltemplate_files/system.lt | 166 - .../moltemplate_files/table_int.dat | 1139 - .../packmol_files/README.sh | 33 - .../packmol_files/step1_proteins.inp | 49 - .../packmol_files/step2_innerlayer.inp | 70 - .../packmol_files/step3_outerlayer.inp | 70 - .../run.in.min | 50 - .../run.in.nvt | 63 - .../cnad-cnt/README_FIRST.TXT | 83 - .../cnad-cnt/README_step1_run_ltemplify.sh | 13 - .../cnad-cnt/README_step2_run_moltemplate.sh | 22 - .../cnad-cnt/README_step3_run_lammps.sh | 16 - .../cnad-cnt/README_visualize.txt | 50 - .../cnad-cnt/cnad-cnt.data | 1157 - .../cnad-cnt/cnad-cnt.in | 49 - .../images/cnad-cnt_after_rotate_copy.jpg | Bin 29386 -> 0 bytes .../cnad-cnt/images/cnad-cnt_orig.jpg | Bin 19144 -> 0 bytes .../cnad-cnt/images/cnad.jpg | Bin 18403 -> 0 bytes .../cnad-cnt/images/cnt.jpg | Bin 20633 -> 0 bytes .../cnad-cnt_after_rotate_and_copy.psf | 598 - .../cnad-cnt_orig.psf | 489 - .../cnad-cnt/run.in.nvt | 46 - .../cnad-cnt/system.lt | 29 - .../waterSPCE_from_PDBfile/README.TXT | 10 - .../waterSPCE_from_PDBfile/README_run.sh | 31 - .../waterSPCE_from_PDBfile/README_setup.sh | 32 - .../README_visualize.txt | 64 - .../moltemplate_files/.0 | 0 .../moltemplate_files/README.sh | 11 - .../moltemplate_files/solvate.pdb | 782 - .../moltemplate_files/spce.lt | 52 - .../moltemplate_files/system.lt | 16 - .../waterSPCE_from_PDBfile/run.in.npt | 48 - .../waterSPCE_from_PDBfile/run.in.nvt | 61 - .../examples/force_field_AMBER/WARNING.TXT | 54 - .../force_field_AMBER/benzene/README.TXT | 10 - .../force_field_AMBER/benzene/README_run.sh | 39 - .../force_field_AMBER/benzene/README_setup.sh | 26 - .../benzene/README_visualize.txt | 87 - .../benzene/moltemplate_files/benzene.lt | 51 - .../benzene/moltemplate_files/system.lt | 14 - .../README_remove_irrelevant_info.sh | 63 - .../force_field_AMBER/benzene/run.in.npt | 72 - .../force_field_AMBER/benzene/run.in.nvt | 51 - .../ethylene+benzene/README.TXT | 13 - .../ethylene+benzene/README_run.sh | 39 - .../ethylene+benzene/README_setup.sh | 25 - .../ethylene+benzene/README_visualize.txt | 87 - .../ethylene+benzene/images/benzene.jpg | Bin 15032 -> 0 bytes .../ethylene+benzene_box80x80x80_LR.jpg | Bin 130048 -> 0 bytes .../ethylene+benzene/images/ethylene.jpg | Bin 11657 -> 0 bytes .../moltemplate_files/benzene.lt | 47 - .../oplsaa_subset.prm | 94 - .../moltemplate_files/ethylene.lt | 38 - .../moltemplate_files/system.lt | 29 - .../README_remove_irrelevant_info.sh | 63 - .../ethylene+benzene/run.in.npt | 53 - .../ethylene+benzene/run.in.nvt | 46 - .../force_field_AMBER/hexadecane/README.TXT | 44 - .../hexadecane/README_run.sh | 39 - .../hexadecane/README_setup.sh | 26 - .../hexadecane/README_visualize.txt | 87 - .../force_field_AMBER/hexadecane/WARNING.TXT | 16 - .../images/hexadecane_12x12x2_t=0_LR.jpg | Bin 27017 -> 0 bytes .../hexadecane_12x12x2_t=10ps_npt_LR.jpg | Bin 36181 -> 0 bytes .../hexadecane/images/hexadecane_LR.jpg | Bin 5237 -> 0 bytes .../hexadecane/moltemplate_files/ch2group.lt | 59 - .../hexadecane/moltemplate_files/ch3group.lt | 65 - .../moltemplate_files/hexadecane.lt | 89 - .../hexadecane/moltemplate_files/system.lt | 18 - .../README_remove_irrelevant_info.sh | 63 - .../force_field_AMBER/hexadecane/run.in.npt | 86 - .../force_field_AMBER/hexadecane/run.in.nvt | 43 - .../waterTIP3P+isobutane/README.TXT | 41 - .../waterTIP3P+isobutane/README_run.sh | 39 - .../waterTIP3P+isobutane/README_setup.sh | 26 - .../waterTIP3P+isobutane/README_visualize.txt | 87 - .../waterTIP3P+isobutane/images/isobutane.jpg | Bin 24301 -> 0 bytes .../images/water+isobutane_t=0_LR.jpg | Bin 104035 -> 0 bytes .../images/water+isobutane_t=840ps_LR.jpg | Bin 73375 -> 0 bytes .../waterTIP3P+isobutane/images/water.jpg | Bin 10076 -> 0 bytes .../moltemplate_files/isobutane.lt | 56 - .../moltemplate_files/system.lt | 29 - .../README_remove_irrelevant_info.sh | 63 - .../waterTIP3P+isobutane/run.in.npt | 44 - .../waterTIP3P+isobutane/run.in.nvt | 52 - .../examples/force_field_OPLSAA/WARNING.TXT | 28 - .../alkane_chain_single/README.TXT | 40 - .../alkane_chain_single/README_run.sh | 34 - .../alkane_chain_single/README_setup.sh | 26 - .../alkane_chain_single/README_visualize.txt | 87 - .../alkane_chain_single/images/ch2_ry90.jpg | Bin 4680 -> 0 bytes .../alkane_chain_single/images/ch3_ry60.jpg | Bin 6951 -> 0 bytes .../alkane_chain_single/images/t=0.jpg | Bin 51583 -> 0 bytes .../alkane_chain_single/images/t=1ns.jpg | Bin 60111 -> 0 bytes .../moltemplate_files/alkane50.lt | 138 - .../moltemplate_files/ch2group.lt | 82 - .../moltemplate_files/ch3group.lt | 83 - .../oplsaa_lt_generator/AUTHOR.TXT | 3 - .../oplsaa_lt_generator/README.TXT | 109 - .../oplsaa_lt_generator/oplsaa_subset.prm | 151 - .../moltemplate_files/system.lt | 31 - .../alkane_chain_single/run.in.min | 37 - .../alkane_chain_single/run.in.nvt | 38 - .../ethylene+benzene/README.TXT | 12 - .../ethylene+benzene/README_run.sh | 34 - .../ethylene+benzene/README_setup.sh | 26 - .../ethylene+benzene/README_visualize.txt | 87 - .../ethylene+benzene/images/benzene.jpg | Bin 15032 -> 0 bytes .../ethylene+benzene_box80x80x80_LR.jpg | Bin 130048 -> 0 bytes .../ethylene+benzene/images/ethylene.jpg | Bin 11657 -> 0 bytes .../moltemplate_files/benzene.lt | 45 - .../moltemplate_files/ethylene.lt | 43 - .../oplsaa_lt_generator/AUTHOR.TXT | 3 - .../oplsaa_lt_generator/README.TXT | 110 - .../minimal_versions/README.TXT | 16 - .../oplsaa_subset_minimal.prm | 37 - .../oplsaa_subset_simplified.prm | 49 - .../oplsaa_lt_generator/oplsaa_subset.prm | 5129 --- .../moltemplate_files/system.lt | 28 - .../ethylene+benzene/run.in.npt | 58 - .../ethylene+benzene/run.in.nvt | 51 - .../ethylene+benzene_PACKMOL/README.TXT | 23 - .../ethylene+benzene_PACKMOL/README_run.sh | 34 - .../ethylene+benzene_PACKMOL/README_setup.sh | 37 - .../README_visualize.txt | 87 - .../images/benzene.jpg | Bin 15032 -> 0 bytes .../ethylene+benzene_box80x80x80_LR.jpg | Bin 130048 -> 0 bytes .../images/ethylene.jpg | Bin 11657 -> 0 bytes .../moltemplate_files/benzene.lt | 51 - .../moltemplate_files/ethylene.lt | 40 - .../oplsaa_lt_generator/AUTHOR.TXT | 3 - .../oplsaa_lt_generator/README.TXT | 110 - .../minimal_versions/README.TXT | 16 - .../oplsaa_subset_minimal.prm | 37 - .../oplsaa_subset_simplified.prm | 49 - .../oplsaa_lt_generator/oplsaa_subset.prm | 5129 --- .../moltemplate_files/system.lt | 21 - .../moltemplate_files/system.xyz | 12002 ------ .../packmol_files/README.TXT | 5 - .../packmol_files/benzene.xyz | 14 - .../packmol_files/ethylene.xyz | 8 - .../packmol_files/mix_ethylene+benzene.inp | 31 - .../ethylene+benzene_PACKMOL/run.in.npt | 58 - .../ethylene+benzene_PACKMOL/run.in.nvt | 51 - .../force_field_OPLSAA/hexadecane/README.TXT | 43 - .../hexadecane/README_run.sh | 34 - .../hexadecane/README_setup.sh | 29 - .../hexadecane/README_visualize.txt | 87 - .../force_field_OPLSAA/hexadecane/WARNING.TXT | 15 - .../images/hexadecane_12x12x2_t=0_LR.jpg | Bin 27017 -> 0 bytes .../hexadecane_12x12x2_t=10ps_npt_LR.jpg | Bin 36181 -> 0 bytes .../hexadecane/images/hexadecane_LR.jpg | Bin 5237 -> 0 bytes .../hexadecane/moltemplate_files/ch2group.lt | 82 - .../hexadecane/moltemplate_files/ch3group.lt | 83 - .../moltemplate_files/hexadecane.lt | 79 - .../oplsaa_lt_generator/AUTHOR.TXT | 3 - .../oplsaa_lt_generator/README.TXT | 108 - .../oplsaa_lt_generator/oplsaa_subset.prm | 151 - .../hexadecane/moltemplate_files/system.lt | 18 - .../force_field_OPLSAA/hexadecane/run.in.npt | 87 - .../force_field_OPLSAA/hexadecane/run.in.nvt | 44 - .../force_field_OPLSAA/methane/README.TXT | 24 - .../force_field_OPLSAA/methane/README_run.sh | 34 - .../methane/README_setup.sh | 28 - .../methane/README_visualize.txt | 87 - .../methane/moltemplate_files/methane.lt | 32 - .../oplsaa_lt_generator/AUTHOR.TXT | 3 - .../oplsaa_lt_generator/README.TXT | 108 - .../oplsaa_lt_generator/oplsaa_subset.prm | 115 - .../methane/moltemplate_files/system.lt | 15 - .../force_field_OPLSAA/methane/run.in.npt | 51 - .../force_field_OPLSAA/methane/run.in.nvt | 42 - .../waterSPCE+methane/README.TXT | 30 - .../waterSPCE+methane/README_run.sh | 34 - .../waterSPCE+methane/README_setup.sh | 28 - .../waterSPCE+methane/README_visualize.txt | 87 - .../moltemplate_files/methane.lt | 32 - .../oplsaa_lt_generator/AUTHOR.TXT | 3 - .../oplsaa_lt_generator/README.TXT | 111 - .../oplsaa_lt_generator/oplsaa_subset.prm | 126 - .../moltemplate_files/spce.lt | 52 - .../moltemplate_files/system.lt | 26 - .../waterSPCE+methane/run.in.npt | 52 - .../waterSPCE+methane/run.in.nvt | 42 - .../waterSPC_using_OPLSAA/README.TXT | 18 - .../waterSPC_using_OPLSAA/README_run.sh | 20 - .../waterSPC_using_OPLSAA/README_setup.sh | 28 - .../README_visualize.txt | 87 - .../TEST_density_estimate.txt | 20 - .../oplsaa_lt_generator/AUTHOR.TXT | 3 - .../oplsaa_lt_generator/README.TXT | 115 - .../oplsaa_lt_generator/oplsaa_subset.prm | 112 - .../moltemplate_files/spc.lt | 86 - .../moltemplate_files/system.lt | 16 - .../waterSPC_using_OPLSAA/run.in.npt | 52 - .../waterSPC_using_OPLSAA/run.in.nvt | 42 - .../propane/README.TXT | 21 - .../propane/README_run.sh | 34 - .../propane/README_setup.sh | 33 - .../propane/README_visualize.txt | 87 - .../propane/moltemplate_files/propane.lt | 31 - .../propane/moltemplate_files/system.lt | 37 - .../propane/run.in.npt | 43 - .../propane/run.in.nvt | 39 - .../aluminum_crystal_strain/README.TXT | 54 - .../aluminum_crystal_strain/README_setup.sh | 29 - .../README_visualize.txt | 87 - .../images/AlCell_LR.jpg | Bin 2364 -> 0 bytes .../images/AlCrystal10x10x10_t=0steps_LR.jpg | Bin 30158 -> 0 bytes .../AlCrystal10x10x10_t=20000steps_LR.jpg | Bin 29910 -> 0 bytes .../moltemplate_files/README.sh | 22 - .../moltemplate_files/al_cell.lt | 64 - .../moltemplate_files/system.lt | 35 - .../aluminum_crystal_strain/run.in | 76 - .../ice_crystal/README_run.sh | 33 - .../ice_crystal/README_setup.sh | 23 - .../ice_crystal/README_visualize.txt | 87 - .../images/ice_rect8_crystal_3x2x2_LR.jpg | Bin 25820 -> 0 bytes .../ice_crystal/images/ice_rect8_unitcell.png | Bin 21951 -> 0 bytes .../ice_crystal/moltemplate_files/spce.lt | 52 - .../moltemplate_files/spce_ice_rect16.lt | 81 - .../moltemplate_files/spce_ice_rect32.lt | 129 - .../moltemplate_files/spce_ice_rect8.lt | 57 - .../ice_crystal/moltemplate_files/system.lt | 11 - .../ice_crystal/run.in.npt | 48 - .../ice_crystal/run.in.nvt | 45 - .../nanotube+water/README.TXT | 51 - .../README_realistic_junctions.txt | 22 - .../nanotube+water/README_run.sh | 24 - .../nanotube+water/README_setup.sh | 23 - .../nanotube+water/README_visualize.txt | 77 - .../images/graphene_unit_cell.jpg | Bin 13144 -> 0 bytes ...nanotube+walls+water_side_pbc_t=0ps_LR.jpg | Bin 30772 -> 0 bytes ...notube+walls+water_side_pbc_t=108ps_LR.jpg | Bin 28367 -> 0 bytes ...notube+walls+water_side_pbc_t=305ps_LR.jpg | Bin 27305 -> 0 bytes .../nanotube+walls+water_top_nopbc_t=0_LR.jpg | Bin 33740 -> 0 bytes .../images/nanotube+walls_side_nopbc_LR.jpg | Bin 18748 -> 0 bytes .../images/water_side_nopbc_LR.jpg | Bin 26968 -> 0 bytes .../moltemplate_files/README.sh | 32 - .../moltemplate_files/graphene.lt | 55 - .../moltemplate_files/graphene_walls.lt | 57 - .../moltemplate_files/graphite.lt | 61 - .../moltemplate_files/nanotube.lt | 101 - .../nanotube+water/moltemplate_files/spce.lt | 52 - .../moltemplate_files/system.lt | 29 - .../moltemplate_files/water_box.lt | 20 - .../nanotube+water/moltemplate_files/watmw.lt | 54 - .../nanotube+water/run.in.npt | 147 - .../nanotube+water/run.in.nvt | 78 - .../waterSPCE+Na+Cl/README_run.sh | 33 - .../waterSPCE+Na+Cl/README_setup.sh | 23 - .../waterSPCE+Na+Cl/README_visualize.txt | 87 - .../waterSPCE+Na+Cl/images/Cl.jpg | Bin 1577 -> 0 bytes .../waterSPCE+Na+Cl/images/Na.jpg | Bin 1595 -> 0 bytes .../waterSPCE+Na+Cl/images/wat.jpg | Bin 5644 -> 0 bytes .../images/waterSPCE+Na+Cl_t=0.jpg | Bin 169027 -> 0 bytes .../images/waterSPCE+Na+Cl_t=100ps.jpg | Bin 144377 -> 0 bytes .../waterSPCE+Na+Cl/moltemplate_files/ions.lt | 67 - .../waterSPCE+Na+Cl/moltemplate_files/spce.lt | 52 - .../moltemplate_files/system.lt | 49 - .../waterSPCE+Na+Cl/run.in.npt | 48 - .../waterSPCE+Na+Cl/run.in.nvt | 58 - .../misc_examples/menger_sponge/README.TXT | 45 - .../menger_sponge/README_setup.sh | 29 - .../menger_sponge/README_visualize.txt | 87 - .../menger_sponge/images/AlCell_LR.jpg | Bin 2364 -> 0 bytes .../menger_sponge/images/lvl1_LR.jpg | Bin 2623 -> 0 bytes .../menger_sponge/images/lvl2_LR.jpg | Bin 7722 -> 0 bytes .../menger_sponge/images/lvl3_LR.jpg | Bin 16455 -> 0 bytes ...er_sponge_lattice_8cells_t=0_zoom1_LR2.jpg | Bin 82092 -> 0 bytes ...menger_sponge_lattice_8cells_t=7400_LR.jpg | Bin 21718 -> 0 bytes .../moltemplate_files/al_cell.lt | 64 - .../elegant_inefficient_version/al_cell.lt | 64 - .../menger_cubes.lt | 34 - .../elegant_inefficient_version/system.lt | 34 - .../moltemplate_files/menger_cubes.lt | 66 - .../menger_sponge/moltemplate_files/system.lt | 34 - .../misc_examples/menger_sponge/run.in | 38 - .../pyramids_vs_gravity/README.TXT | 23 - .../README_VMD_graphene.txt | 28 - .../pyramids_vs_gravity/README_setup.sh | 23 - .../pyramids_vs_gravity/README_visualize.txt | 76 - .../pyramids_vs_gravity_t=04800steps_LR.jpg | Bin 88094 -> 0 bytes .../pyramids_vs_gravity_t=12200steps_LR.jpg | Bin 91240 -> 0 bytes .../pyramids_vs_gravity_t=33000steps_LR.jpg | Bin 98828 -> 0 bytes .../moltemplate_files/README.sh | 15 - .../moltemplate_files/graphene.lt | 61 - .../moltemplate_files/graphene_wall.lt | 21 - .../moltemplate_files/pyramids.lt | 283 - .../moltemplate_files/system.lt | 80 - .../misc_examples/pyramids_vs_gravity/run.in | 68 - tools/moltemplate/moltemplate_manual.pdf | Bin 716411 -> 0 bytes tools/moltemplate/src/bonds_by_type.py | 370 - tools/moltemplate/src/chargepairs_by_type.py | 389 - tools/moltemplate/src/dump2data.py | 1290 - tools/moltemplate/src/extract_lammps_data.py | 119 - tools/moltemplate/src/ltemplify.py | 3361 -- tools/moltemplate/src/lttree.py | 744 - tools/moltemplate/src/lttree_check.py | 2222 -- tools/moltemplate/src/lttree_postprocess.py | 335 - tools/moltemplate/src/lttree_styles.py | 239 - tools/moltemplate/src/moltemplate.sh | 2110 - .../docs_dump2data.txt | 121 - .../docs_extract_lammps_data.txt | 60 - .../docs_raw2data.txt | 56 - .../moltemplate_force_fields/amber/README.TXT | 74 - .../amber/amberparm2lt.sh | 203 - .../amber/amberparm_angle_to_lt.py | 50 - .../amber/amberparm_bond_to_lt.py | 47 - .../amber/amberparm_dihedral_to_lt.py | 157 - .../amber/amberparm_improper_to_lt.py | 90 - .../amber/amberparm_mass_to_lt.py | 19 - .../amber/amberparm_pair_to_lt.py | 57 - .../src/moltemplate_force_fields/gaff.lt | 11789 ------ .../src/moltemplate_force_fields/graphene.lt | 55 - .../src/moltemplate_force_fields/graphite.lt | 61 - .../images/graphene_unit_cell.jpg | Bin 13144 -> 0 bytes .../images/ice_rect8_unitcell.png | Bin 21951 -> 0 bytes .../images/spce_ball_and_stick.jpg | Bin 5644 -> 0 bytes .../src/moltemplate_force_fields/loplsaa.lt | 153 - .../src/moltemplate_force_fields/oplsaa.lt | 8934 ----- .../oplsaa/AUTHOR.TXT | 3 - .../oplsaa/README.TXT | 125 - .../oplsaa/loplsaa_ext.prm | 87 - .../src/moltemplate_force_fields/spce.lt | 52 - .../spce_ice_rect16.lt | 81 - .../spce_ice_rect32.lt | 129 - .../spce_ice_rect8.lt | 57 - .../moltemplate_force_fields/tip3p_1983.lt | 119 - .../tip3p_1983_charmm.lt | 119 - .../moltemplate_force_fields/tip3p_2004.lt | 107 - .../moltemplate_force_fields/trappe1998.lt | 53 - .../src/moltemplate_force_fields/watmw.lt | 77 - .../oplsaa_moltemplate.py | 489 - tools/moltemplate/src/nbody_Angles.py | 52 - tools/moltemplate/src/nbody_Bonds.py | 31 - tools/moltemplate/src/nbody_Dihedrals.py | 53 - tools/moltemplate/src/nbody_Impropers.py | 62 - .../nbody_alternate_symmetry/class2_dih.py | 40 - .../nbody_alternate_symmetry/class2_imp.py | 41 - .../src/nbody_alternate_symmetry/gaff_imp.py | 74 - .../nbody_Dihedrals_nosym.py | 32 - .../nbody_Impropers_Icenter_swapJK.py | 49 - .../nbody_Impropers_Icenter_swapJKL.py | 43 - .../nbody_Impropers_Jcenter.py | 64 - .../nbody_Impropers_Jcenter_nosym.py | 33 - .../src/nbody_alternate_symmetry/opls_imp.py | 72 - tools/moltemplate/src/nbody_by_type.py | 665 - tools/moltemplate/src/nbody_by_type_lib.py | 394 - .../src/nbody_fix_ttree_assignments.py | 149 - tools/moltemplate/src/nbody_graph_search.py | 976 - tools/moltemplate/src/nbody_reorder_atoms.py | 74 - tools/moltemplate/src/ordereddict.py | 258 - tools/moltemplate/src/pdbsort.py | 138 - .../src/postprocess_input_script.py | 147 - tools/moltemplate/src/raw2data.py | 103 - .../moltemplate/src/remove_duplicate_atoms.py | 53 - .../src/remove_duplicates_nbody.py | 49 - .../src/renumber_DATA_first_column.py | 69 - tools/moltemplate/src/tinkerparm2lt.py | 581 - tools/moltemplate/src/ttree.py | 5383 --- tools/moltemplate/src/ttree_lex.py | 2088 - tools/moltemplate/src/ttree_matrix_stack.py | 710 - tools/moltemplate/src/ttree_render.py | 115 - 628 files changed, 146906 deletions(-) delete mode 100644 tools/moltemplate/LICENSE.TXT delete mode 100644 tools/moltemplate/README.TXT delete mode 100644 tools/moltemplate/examples/README.TXT delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/3bodyWater+hydrocarbons_MW+TraPPE/README.TXT delete mode 100755 tools/moltemplate/examples/coarse_grained_examples/3bodyWater+hydrocarbons_MW+TraPPE/README_run.sh delete mode 100755 tools/moltemplate/examples/coarse_grained_examples/3bodyWater+hydrocarbons_MW+TraPPE/README_setup.sh delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/3bodyWater+hydrocarbons_MW+TraPPE/README_visualize.txt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/3bodyWater+hydrocarbons_MW+TraPPE/images/cyclododecane+watMW_t=0ps_LR.jpg delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/3bodyWater+hydrocarbons_MW+TraPPE/images/cyclododecane+watMW_t=400ps_LR.jpg delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/3bodyWater+hydrocarbons_MW+TraPPE/images/cyclododecane+watMW_t=50ps_LR.jpg delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/3bodyWater+hydrocarbons_MW+TraPPE/images/cyclopentane.jpg delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/3bodyWater+hydrocarbons_MW+TraPPE/images/cyclopentane_unrelaxed.jpg delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/3bodyWater+hydrocarbons_MW+TraPPE/images/watMW.jpg delete mode 100755 tools/moltemplate/examples/coarse_grained_examples/3bodyWater+hydrocarbons_MW+TraPPE/moltemplate_files/README.sh delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/3bodyWater+hydrocarbons_MW+TraPPE/moltemplate_files/cyclododecane.lt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/3bodyWater+hydrocarbons_MW+TraPPE/moltemplate_files/system.lt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/3bodyWater+hydrocarbons_MW+TraPPE/moltemplate_files/trappe1998.lt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/3bodyWater+hydrocarbons_MW+TraPPE/moltemplate_files/version_more_comments/system.lt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/3bodyWater+hydrocarbons_MW+TraPPE/moltemplate_files/watmw.lt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/3bodyWater+hydrocarbons_MW+TraPPE/run.in.npt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/3bodyWater+hydrocarbons_MW+TraPPE/run.in.nvt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/MARTINI_examples/DPPC_bilayer_formation_PACKMOL/README.TXT delete mode 100755 tools/moltemplate/examples/coarse_grained_examples/MARTINI_examples/DPPC_bilayer_formation_PACKMOL/README_run.sh delete mode 100755 tools/moltemplate/examples/coarse_grained_examples/MARTINI_examples/DPPC_bilayer_formation_PACKMOL/README_setup.sh delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/MARTINI_examples/DPPC_bilayer_formation_PACKMOL/README_visualize.txt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/MARTINI_examples/DPPC_bilayer_formation_PACKMOL/images/DPPC_martini_LR.jpg delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/MARTINI_examples/DPPC_bilayer_formation_PACKMOL/images/t=0_after_minimization_LR.jpg delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/MARTINI_examples/DPPC_bilayer_formation_PACKMOL/images/t=13ns_450K_NVT_LR.jpg delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/MARTINI_examples/DPPC_bilayer_formation_PACKMOL/images/t=26ns_300K_NPT_LR.jpg delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/MARTINI_examples/DPPC_bilayer_formation_PACKMOL/images/t=6ns_300K_NPT_LR.jpg delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/MARTINI_examples/DPPC_bilayer_formation_PACKMOL/images/water_martini_LR.jpg delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/MARTINI_examples/DPPC_bilayer_formation_PACKMOL/moltemplate_files/lipid.lt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/MARTINI_examples/DPPC_bilayer_formation_PACKMOL/moltemplate_files/system.lt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/MARTINI_examples/DPPC_bilayer_formation_PACKMOL/moltemplate_files/water.lt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/MARTINI_examples/DPPC_bilayer_formation_PACKMOL/packmol_files/README.TXT delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/MARTINI_examples/DPPC_bilayer_formation_PACKMOL/packmol_files/lipid.xyz delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/MARTINI_examples/DPPC_bilayer_formation_PACKMOL/packmol_files/mix_lipids+water.inp delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/MARTINI_examples/DPPC_bilayer_formation_PACKMOL/packmol_files/water.xyz delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/MARTINI_examples/DPPC_bilayer_formation_PACKMOL/run.in.min delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/MARTINI_examples/DPPC_bilayer_formation_PACKMOL/run.in.npt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/MARTINI_examples/DPPC_bilayer_formation_PACKMOL/run.in.nvt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/MARTINI_examples/DPPC_bilayer_preformed/README.TXT delete mode 100755 tools/moltemplate/examples/coarse_grained_examples/MARTINI_examples/DPPC_bilayer_preformed/README_run.sh delete mode 100755 tools/moltemplate/examples/coarse_grained_examples/MARTINI_examples/DPPC_bilayer_preformed/README_setup.sh delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/MARTINI_examples/DPPC_bilayer_preformed/README_visualize.txt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/MARTINI_examples/DPPC_bilayer_preformed/images/DPPC_martini_LR.jpg delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/MARTINI_examples/DPPC_bilayer_preformed/images/t=0_bilayer_preformed_GL_LR.jpg delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/MARTINI_examples/DPPC_bilayer_preformed/images/t=4ns_bilayer_preformed_GL_LR.jpg delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/MARTINI_examples/DPPC_bilayer_preformed/images/water_martini_LR.jpg delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/MARTINI_examples/DPPC_bilayer_preformed/moltemplate_files/lipid.lt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/MARTINI_examples/DPPC_bilayer_preformed/moltemplate_files/system.lt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/MARTINI_examples/DPPC_bilayer_preformed/moltemplate_files/water.lt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/MARTINI_examples/DPPC_bilayer_preformed/run.in.min delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/MARTINI_examples/DPPC_bilayer_preformed/run.in.npt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/MARTINI_examples/DPPC_bilayer_preformed/run.in.nvt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/abstract_2bead_heteropolymer/README.TXT delete mode 100755 tools/moltemplate/examples/coarse_grained_examples/abstract_2bead_heteropolymer/README_run.sh delete mode 100755 tools/moltemplate/examples/coarse_grained_examples/abstract_2bead_heteropolymer/README_setup.sh delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/abstract_2bead_heteropolymer/README_visualize.txt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/abstract_2bead_heteropolymer/images/polymer.png delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/abstract_2bead_heteropolymer/images/t=0ns.png delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/abstract_2bead_heteropolymer/images/t=40ns_occ.png delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/abstract_2bead_heteropolymer/images/t=4ns_occ.png delete mode 100755 tools/moltemplate/examples/coarse_grained_examples/abstract_2bead_heteropolymer/moltemplate_files/README.sh delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/abstract_2bead_heteropolymer/moltemplate_files/forcefield.lt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/abstract_2bead_heteropolymer/moltemplate_files/monomers.lt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/abstract_2bead_heteropolymer/moltemplate_files/polymer.lt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/abstract_2bead_heteropolymer/moltemplate_files/system.lt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/abstract_2bead_heteropolymer/run.in.nvt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/abstract_random_heteropolymer/README.TXT delete mode 100755 tools/moltemplate/examples/coarse_grained_examples/abstract_random_heteropolymer/README_run.sh delete mode 100755 tools/moltemplate/examples/coarse_grained_examples/abstract_random_heteropolymer/README_setup.sh delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/abstract_random_heteropolymer/README_visualize.txt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/abstract_random_heteropolymer/images/2bead.jpg delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/abstract_random_heteropolymer/images/3bead.jpg delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/abstract_random_heteropolymer/images/random_heteropolymer_30_20_t=0.jpg delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/abstract_random_heteropolymer/images/random_heteropolymer_30_20_t=700ps.jpg delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/abstract_random_heteropolymer/moltemplate_files/forcefield.lt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/abstract_random_heteropolymer/moltemplate_files/monomers.lt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/abstract_random_heteropolymer/moltemplate_files/polymer.lt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/abstract_random_heteropolymer/moltemplate_files/system.lt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/abstract_random_heteropolymer/run.in.nvt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/abstract_translocation/README.TXT delete mode 100755 tools/moltemplate/examples/coarse_grained_examples/abstract_translocation/README_run.sh delete mode 100755 tools/moltemplate/examples/coarse_grained_examples/abstract_translocation/README_setup.sh delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/abstract_translocation/README_visualize.txt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/abstract_translocation/images/polymer_LR.jpg delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/abstract_translocation/images/solvent_LR.jpg delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/abstract_translocation/images/walls+solvent+polymer_t=0.jpg delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/abstract_translocation/images/walls_LR.jpg delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/abstract_translocation/moltemplate_files/monomer.lt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/abstract_translocation/moltemplate_files/polymer.lt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/abstract_translocation/moltemplate_files/solvent.lt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/abstract_translocation/moltemplate_files/solvent_single.lt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/abstract_translocation/moltemplate_files/system.lt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/abstract_translocation/moltemplate_files/wall_single.lt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/abstract_translocation/moltemplate_files/walls.lt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/abstract_translocation/run.in.npt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/abstract_translocation/run.in.nvt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/README_FIRST.txt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/README_NUCLEAR_VOLUME_FRACTION_ESTIMATE.txt delete mode 100755 tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/README_run.sh delete mode 100755 tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/README_setup.sh delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/README_visualize.txt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/images/stage2_interior.jpg delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/images/stage2_interior_rotated.jpg delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/images/t=0_before_minimizaion.jpg delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/images/vmd_colorscale_jet.tcl delete mode 100755 tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/moltemplate_files/README_how_to_generate_system_lt.sh delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/moltemplate_files/README_length_flexibility_details.txt delete mode 100755 tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/moltemplate_files/calc_table.sh delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/moltemplate_files/condensin.lt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/moltemplate_files/coords_orig.raw delete mode 100755 tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/moltemplate_files/generate_system_lt.py delete mode 100755 tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/moltemplate_files/interpolate_coords.py delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/moltemplate_files/monomer.lt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/moltemplate_files/table_bonds_stage2.dat delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/run.in.min delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/run.in.stage1 delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/run.in.stage2 delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/membrane+protein/README.TXT delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/membrane+protein/README_WARNING.TXT delete mode 100755 tools/moltemplate/examples/coarse_grained_examples/membrane+protein/README_run.sh delete mode 100755 tools/moltemplate/examples/coarse_grained_examples/membrane+protein/README_setup.sh delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/membrane+protein/README_visualize.txt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/membrane+protein/images/4HelixOrig+Lipid2005_t=1290ps_LR.jpg delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/membrane+protein/images/membrane+protein_t=0ps_LR.jpg delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/membrane+protein/images/membrane+protein_t=0ps_no_pbc_LR.jpg delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/membrane+protein/images/membrane+protein_t=0ps_top_LR.jpg delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/membrane+protein/images/membrane+protein_t=5000ps_LR.jpg delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/membrane+protein/moltemplate_files/1beadProtSci2010.lt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/membrane+protein/moltemplate_files/1beadProtSci2010_variations.lt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/membrane+protein/moltemplate_files/CGLipidBr2005.lt delete mode 100755 tools/moltemplate/examples/coarse_grained_examples/membrane+protein/moltemplate_files/calc_table/calc_CGLipidTableINTvsINT.py delete mode 100755 tools/moltemplate/examples/coarse_grained_examples/membrane+protein/moltemplate_files/calc_table/version_charmm_cutoff/calc_table.py delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/membrane+protein/moltemplate_files/system.lt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/membrane+protein/moltemplate_files/table_int.dat delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/membrane+protein/run.in.min delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/membrane+protein/run.in.npt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/membrane+protein/run.in.nvt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/README.TXT delete mode 100755 tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/README_run.sh delete mode 100755 tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/README_setup.sh delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/README_visualize.txt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/images/DLPC.jpg delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/images/DPPC+DLPC_bilayer32x37_t=0ps_LR.jpg delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/images/DPPC+DLPC_bilayer32x37_t=0ps_no_pbc_LR.jpg delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/images/DPPC+DLPC_bilayer32x37_t=500ps_LR.jpg delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/images/DPPC.jpg delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/moltemplate_files/CGLipidBr2005Orig.lt delete mode 100755 tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/moltemplate_files/calc_table/calc_table.py delete mode 100755 tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/moltemplate_files/calc_table/version_charmm_cutoff/calc_table.py delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/moltemplate_files/system.lt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/moltemplate_files/table_int.dat delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/run.in.min delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/run.in.npt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/run.in.nvt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/README.TXT delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+chaperonin/README.TXT delete mode 100755 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+chaperonin/README_run.sh delete mode 100755 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+chaperonin/README_setup.sh delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+chaperonin/README_visualize.txt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+chaperonin/images/for_visualization/psf_file_created_by_topotools/system.psf delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+chaperonin/images/misfolded+chaperonin_t=0tau_LR.jpg delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+chaperonin/images/unfolded+chaperonin_t=508750tau_LR.jpg delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+chaperonin/moltemplate_files/1beadFrustrated.lt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+chaperonin/moltemplate_files/1beadFrustrated_variants.lt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+chaperonin/moltemplate_files/chaperonin.lt delete mode 100755 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+chaperonin/moltemplate_files/generate_tables/calc_chaperone_table.py delete mode 100755 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+chaperonin/moltemplate_files/generate_tables/calc_dihedral_table.py delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+chaperonin/moltemplate_files/system.lt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+chaperonin/moltemplate_files/table_chaperonin_h=0.475.dat delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+chaperonin/moltemplate_files/table_chaperonin_h=0.dat delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+chaperonin/moltemplate_files/table_dihedral_frustrated.dat delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+chaperonin/run.in.min delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+chaperonin/run.in.nvt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+minichaperone/README.TXT delete mode 100755 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+minichaperone/README_run.sh delete mode 100755 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+minichaperone/README_setup.sh delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+minichaperone/README_visualize.txt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+minichaperone/images/for_visualization/psf_file_created_by_topotools/system.psf delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+minichaperone/images/protein2x2x2+minichaperones2x2x2_t=0tau_LR.jpg delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+minichaperone/images/protein2x2x2+minichaperones2x2x2_t=67500tau_LR.jpg delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+minichaperone/moltemplate_files/1beadFrustrated.lt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+minichaperone/moltemplate_files/1beadFrustrated_variants.lt delete mode 100755 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+minichaperone/moltemplate_files/generate_tables/calc_chaperone_table.py delete mode 100755 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+minichaperone/moltemplate_files/generate_tables/calc_dihedral_table.py delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+minichaperone/moltemplate_files/minichaperone.lt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+minichaperone/moltemplate_files/system.lt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+minichaperone/moltemplate_files/table_dihedral_frustrated.dat delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+minichaperone/moltemplate_files/table_minichaperone_h=0.6.dat delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+minichaperone/moltemplate_files/table_minichaperone_h=0.dat delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+minichaperone/run.in.min delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+minichaperone/run.in.nvt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated/README.TXT delete mode 100755 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated/README_run.sh delete mode 100755 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated/README_setup.sh delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated/README_visualize.txt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated/images/for_visualization/psf_file_created_by_topotools/system.psf delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated/images/initial_conformation_t=0tau.jpg delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated/images/misfolded_conformation_t=1250tau.jpg delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated/moltemplate_files/1beadFrustrated.lt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated/moltemplate_files/1beadFrustrated_variants.lt delete mode 100755 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated/moltemplate_files/generate_tables/calc_dihedral_table.py delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated/moltemplate_files/system.lt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated/moltemplate_files/table_dihedral_frustrated.dat delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated/run.in.min delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated/run_short_sim.in.nvt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated+chaperonin/README.TXT delete mode 100755 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated+chaperonin/README_run.sh delete mode 100755 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated+chaperonin/README_setup.sh delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated+chaperonin/README_visualize.txt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated+chaperonin/images/for_visualization/psf_file_created_by_topotools/system.psf delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated+chaperonin/images/unfrustrated+chaperonin_t=0tau_LR.jpg delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated+chaperonin/images/unfrustrated+chaperonin_t=105tau_LR.jpg delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated+chaperonin/moltemplate_files/1beadUnfrustrated.lt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated+chaperonin/moltemplate_files/1beadUnfrustrated_variants.lt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated+chaperonin/moltemplate_files/chaperonin.lt delete mode 100755 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated+chaperonin/moltemplate_files/generate_tables/calc_chaperone_table.py delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated+chaperonin/moltemplate_files/system.lt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated+chaperonin/moltemplate_files/table_chaperonin_h=0.475.dat delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated+chaperonin/moltemplate_files/table_chaperonin_h=0.dat delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated+chaperonin/run.in.min delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated+chaperonin/run.in.nvt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated/README.TXT delete mode 100755 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated/README_run.sh delete mode 100755 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated/README_setup.sh delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated/README_visualize.txt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated/images/for_visualization/psf_file_created_by_topotools/system.psf delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated/images/unfrustrated_t=0tau_LR.jpg delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated/images/unfrustrated_t=200tau_LR.jpg delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated/moltemplate_files/1beadUnfrustrated.lt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated/moltemplate_files/1beadUnfrustrated_variants.lt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated/moltemplate_files/system.lt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated/run.in.min delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated/run.in.nvt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1beadProtSci2010/README.TXT delete mode 100755 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1beadProtSci2010/README_run.sh delete mode 100755 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1beadProtSci2010/README_setup.sh delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1beadProtSci2010/README_visualize.txt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1beadProtSci2010/images/4HelixBundle_t=0.jpg delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1beadProtSci2010/images/4SheetBundle_t=0.jpg delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1beadProtSci2010/images/for_visualization/psf_file_created_by_topotools/system.psf delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1beadProtSci2010/moltemplate_files/1beadProtSci2010.lt delete mode 100755 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1beadProtSci2010/moltemplate_files/README.sh delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1beadProtSci2010/moltemplate_files/other_implementations/README.TXT delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1beadProtSci2010/moltemplate_files/other_implementations/charmm/1beadProtSci2010.lt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1beadProtSci2010/moltemplate_files/other_implementations/class2/1beadProtSci2010.lt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1beadProtSci2010/moltemplate_files/system.lt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1beadProtSci2010/run.in.min delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1beadProtSci2010/run.in.nvt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/README.TXT delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/README_WARNING.TXT delete mode 100755 tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/README_run.sh delete mode 100755 tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/README_setup.sh delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/README_visualize.txt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/images/vesicle_membrane+protein_L.jpg delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/moltemplate_files/1beadProtSci2010.lt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/moltemplate_files/1beadProtSci2010_variations.lt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/moltemplate_files/CGLipidBr2005.lt delete mode 100755 tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/moltemplate_files/README.sh delete mode 100755 tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/moltemplate_files/calc_table/calc_CGLipidTableINTvsINT.py delete mode 100755 tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/moltemplate_files/calc_table/version_charmm_cutoff/calc_table.py delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/moltemplate_files/system.lt delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/moltemplate_files/table_int.dat delete mode 100755 tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/packmol_files/README.sh delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/packmol_files/step1_proteins.inp delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/packmol_files/step2_innerlayer.inp delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/packmol_files/step3_outerlayer.inp delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/run.in.min delete mode 100644 tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/run.in.nvt delete mode 100644 tools/moltemplate/examples/file_conversion_examples/convert_LAMMPS_to_LT_examples/cnad-cnt/README_FIRST.TXT delete mode 100755 tools/moltemplate/examples/file_conversion_examples/convert_LAMMPS_to_LT_examples/cnad-cnt/README_step1_run_ltemplify.sh delete mode 100755 tools/moltemplate/examples/file_conversion_examples/convert_LAMMPS_to_LT_examples/cnad-cnt/README_step2_run_moltemplate.sh delete mode 100755 tools/moltemplate/examples/file_conversion_examples/convert_LAMMPS_to_LT_examples/cnad-cnt/README_step3_run_lammps.sh delete mode 100644 tools/moltemplate/examples/file_conversion_examples/convert_LAMMPS_to_LT_examples/cnad-cnt/README_visualize.txt delete mode 100644 tools/moltemplate/examples/file_conversion_examples/convert_LAMMPS_to_LT_examples/cnad-cnt/cnad-cnt.data delete mode 100644 tools/moltemplate/examples/file_conversion_examples/convert_LAMMPS_to_LT_examples/cnad-cnt/cnad-cnt.in delete mode 100644 tools/moltemplate/examples/file_conversion_examples/convert_LAMMPS_to_LT_examples/cnad-cnt/images/cnad-cnt_after_rotate_copy.jpg delete mode 100644 tools/moltemplate/examples/file_conversion_examples/convert_LAMMPS_to_LT_examples/cnad-cnt/images/cnad-cnt_orig.jpg delete mode 100644 tools/moltemplate/examples/file_conversion_examples/convert_LAMMPS_to_LT_examples/cnad-cnt/images/cnad.jpg delete mode 100644 tools/moltemplate/examples/file_conversion_examples/convert_LAMMPS_to_LT_examples/cnad-cnt/images/cnt.jpg delete mode 100644 tools/moltemplate/examples/file_conversion_examples/convert_LAMMPS_to_LT_examples/cnad-cnt/images/for_visualization/psf_file_created_by_topotools/cnad-cnt_after_rotate_and_copy.psf delete mode 100644 tools/moltemplate/examples/file_conversion_examples/convert_LAMMPS_to_LT_examples/cnad-cnt/images/for_visualization/psf_file_created_by_topotools/cnad-cnt_orig.psf delete mode 100644 tools/moltemplate/examples/file_conversion_examples/convert_LAMMPS_to_LT_examples/cnad-cnt/run.in.nvt delete mode 100644 tools/moltemplate/examples/file_conversion_examples/convert_LAMMPS_to_LT_examples/cnad-cnt/system.lt delete mode 100644 tools/moltemplate/examples/file_conversion_examples/read_PDB_file_examples/waterSPCE_from_PDBfile/README.TXT delete mode 100755 tools/moltemplate/examples/file_conversion_examples/read_PDB_file_examples/waterSPCE_from_PDBfile/README_run.sh delete mode 100755 tools/moltemplate/examples/file_conversion_examples/read_PDB_file_examples/waterSPCE_from_PDBfile/README_setup.sh delete mode 100644 tools/moltemplate/examples/file_conversion_examples/read_PDB_file_examples/waterSPCE_from_PDBfile/README_visualize.txt delete mode 100644 tools/moltemplate/examples/file_conversion_examples/read_PDB_file_examples/waterSPCE_from_PDBfile/moltemplate_files/.0 delete mode 100755 tools/moltemplate/examples/file_conversion_examples/read_PDB_file_examples/waterSPCE_from_PDBfile/moltemplate_files/README.sh delete mode 100644 tools/moltemplate/examples/file_conversion_examples/read_PDB_file_examples/waterSPCE_from_PDBfile/moltemplate_files/solvate.pdb delete mode 100644 tools/moltemplate/examples/file_conversion_examples/read_PDB_file_examples/waterSPCE_from_PDBfile/moltemplate_files/spce.lt delete mode 100644 tools/moltemplate/examples/file_conversion_examples/read_PDB_file_examples/waterSPCE_from_PDBfile/moltemplate_files/system.lt delete mode 100644 tools/moltemplate/examples/file_conversion_examples/read_PDB_file_examples/waterSPCE_from_PDBfile/run.in.npt delete mode 100644 tools/moltemplate/examples/file_conversion_examples/read_PDB_file_examples/waterSPCE_from_PDBfile/run.in.nvt delete mode 100644 tools/moltemplate/examples/force_field_AMBER/WARNING.TXT delete mode 100644 tools/moltemplate/examples/force_field_AMBER/benzene/README.TXT delete mode 100755 tools/moltemplate/examples/force_field_AMBER/benzene/README_run.sh delete mode 100755 tools/moltemplate/examples/force_field_AMBER/benzene/README_setup.sh delete mode 100644 tools/moltemplate/examples/force_field_AMBER/benzene/README_visualize.txt delete mode 100644 tools/moltemplate/examples/force_field_AMBER/benzene/moltemplate_files/benzene.lt delete mode 100644 tools/moltemplate/examples/force_field_AMBER/benzene/moltemplate_files/system.lt delete mode 100755 tools/moltemplate/examples/force_field_AMBER/benzene/optional_cleanup/README_remove_irrelevant_info.sh delete mode 100644 tools/moltemplate/examples/force_field_AMBER/benzene/run.in.npt delete mode 100644 tools/moltemplate/examples/force_field_AMBER/benzene/run.in.nvt delete mode 100644 tools/moltemplate/examples/force_field_AMBER/ethylene+benzene/README.TXT delete mode 100755 tools/moltemplate/examples/force_field_AMBER/ethylene+benzene/README_run.sh delete mode 100755 tools/moltemplate/examples/force_field_AMBER/ethylene+benzene/README_setup.sh delete mode 100644 tools/moltemplate/examples/force_field_AMBER/ethylene+benzene/README_visualize.txt delete mode 100644 tools/moltemplate/examples/force_field_AMBER/ethylene+benzene/images/benzene.jpg delete mode 100644 tools/moltemplate/examples/force_field_AMBER/ethylene+benzene/images/ethylene+benzene_box80x80x80_LR.jpg delete mode 100644 tools/moltemplate/examples/force_field_AMBER/ethylene+benzene/images/ethylene.jpg delete mode 100644 tools/moltemplate/examples/force_field_AMBER/ethylene+benzene/moltemplate_files/benzene.lt delete mode 100644 tools/moltemplate/examples/force_field_AMBER/ethylene+benzene/moltemplate_files/charges_come_from_OPLSAA/oplsaa_subset.prm delete mode 100644 tools/moltemplate/examples/force_field_AMBER/ethylene+benzene/moltemplate_files/ethylene.lt delete mode 100644 tools/moltemplate/examples/force_field_AMBER/ethylene+benzene/moltemplate_files/system.lt delete mode 100755 tools/moltemplate/examples/force_field_AMBER/ethylene+benzene/optional_cleanup/README_remove_irrelevant_info.sh delete mode 100644 tools/moltemplate/examples/force_field_AMBER/ethylene+benzene/run.in.npt delete mode 100644 tools/moltemplate/examples/force_field_AMBER/ethylene+benzene/run.in.nvt delete mode 100644 tools/moltemplate/examples/force_field_AMBER/hexadecane/README.TXT delete mode 100755 tools/moltemplate/examples/force_field_AMBER/hexadecane/README_run.sh delete mode 100755 tools/moltemplate/examples/force_field_AMBER/hexadecane/README_setup.sh delete mode 100644 tools/moltemplate/examples/force_field_AMBER/hexadecane/README_visualize.txt delete mode 100644 tools/moltemplate/examples/force_field_AMBER/hexadecane/WARNING.TXT delete mode 100644 tools/moltemplate/examples/force_field_AMBER/hexadecane/images/hexadecane_12x12x2_t=0_LR.jpg delete mode 100644 tools/moltemplate/examples/force_field_AMBER/hexadecane/images/hexadecane_12x12x2_t=10ps_npt_LR.jpg delete mode 100644 tools/moltemplate/examples/force_field_AMBER/hexadecane/images/hexadecane_LR.jpg delete mode 100644 tools/moltemplate/examples/force_field_AMBER/hexadecane/moltemplate_files/ch2group.lt delete mode 100644 tools/moltemplate/examples/force_field_AMBER/hexadecane/moltemplate_files/ch3group.lt delete mode 100644 tools/moltemplate/examples/force_field_AMBER/hexadecane/moltemplate_files/hexadecane.lt delete mode 100644 tools/moltemplate/examples/force_field_AMBER/hexadecane/moltemplate_files/system.lt delete mode 100755 tools/moltemplate/examples/force_field_AMBER/hexadecane/optional_cleanup/README_remove_irrelevant_info.sh delete mode 100644 tools/moltemplate/examples/force_field_AMBER/hexadecane/run.in.npt delete mode 100644 tools/moltemplate/examples/force_field_AMBER/hexadecane/run.in.nvt delete mode 100644 tools/moltemplate/examples/force_field_AMBER/waterTIP3P+isobutane/README.TXT delete mode 100755 tools/moltemplate/examples/force_field_AMBER/waterTIP3P+isobutane/README_run.sh delete mode 100755 tools/moltemplate/examples/force_field_AMBER/waterTIP3P+isobutane/README_setup.sh delete mode 100644 tools/moltemplate/examples/force_field_AMBER/waterTIP3P+isobutane/README_visualize.txt delete mode 100644 tools/moltemplate/examples/force_field_AMBER/waterTIP3P+isobutane/images/isobutane.jpg delete mode 100644 tools/moltemplate/examples/force_field_AMBER/waterTIP3P+isobutane/images/water+isobutane_t=0_LR.jpg delete mode 100644 tools/moltemplate/examples/force_field_AMBER/waterTIP3P+isobutane/images/water+isobutane_t=840ps_LR.jpg delete mode 100644 tools/moltemplate/examples/force_field_AMBER/waterTIP3P+isobutane/images/water.jpg delete mode 100644 tools/moltemplate/examples/force_field_AMBER/waterTIP3P+isobutane/moltemplate_files/isobutane.lt delete mode 100644 tools/moltemplate/examples/force_field_AMBER/waterTIP3P+isobutane/moltemplate_files/system.lt delete mode 100755 tools/moltemplate/examples/force_field_AMBER/waterTIP3P+isobutane/optional_cleanup/README_remove_irrelevant_info.sh delete mode 100644 tools/moltemplate/examples/force_field_AMBER/waterTIP3P+isobutane/run.in.npt delete mode 100644 tools/moltemplate/examples/force_field_AMBER/waterTIP3P+isobutane/run.in.nvt delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/WARNING.TXT delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/alkane_chain_single/README.TXT delete mode 100755 tools/moltemplate/examples/force_field_OPLSAA/alkane_chain_single/README_run.sh delete mode 100755 tools/moltemplate/examples/force_field_OPLSAA/alkane_chain_single/README_setup.sh delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/alkane_chain_single/README_visualize.txt delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/alkane_chain_single/images/ch2_ry90.jpg delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/alkane_chain_single/images/ch3_ry60.jpg delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/alkane_chain_single/images/t=0.jpg delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/alkane_chain_single/images/t=1ns.jpg delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/alkane_chain_single/moltemplate_files/alkane50.lt delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/alkane_chain_single/moltemplate_files/ch2group.lt delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/alkane_chain_single/moltemplate_files/ch3group.lt delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/alkane_chain_single/moltemplate_files/oplsaa_lt_generator/AUTHOR.TXT delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/alkane_chain_single/moltemplate_files/oplsaa_lt_generator/README.TXT delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/alkane_chain_single/moltemplate_files/oplsaa_lt_generator/oplsaa_subset.prm delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/alkane_chain_single/moltemplate_files/system.lt delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/alkane_chain_single/run.in.min delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/alkane_chain_single/run.in.nvt delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene/README.TXT delete mode 100755 tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene/README_run.sh delete mode 100755 tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene/README_setup.sh delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene/README_visualize.txt delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene/images/benzene.jpg delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene/images/ethylene+benzene_box80x80x80_LR.jpg delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene/images/ethylene.jpg delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene/moltemplate_files/benzene.lt delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene/moltemplate_files/ethylene.lt delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene/moltemplate_files/oplsaa_lt_generator/AUTHOR.TXT delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene/moltemplate_files/oplsaa_lt_generator/README.TXT delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene/moltemplate_files/oplsaa_lt_generator/minimal_versions/README.TXT delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene/moltemplate_files/oplsaa_lt_generator/minimal_versions/oplsaa_subset_minimal.prm delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene/moltemplate_files/oplsaa_lt_generator/minimal_versions/oplsaa_subset_simplified.prm delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene/moltemplate_files/oplsaa_lt_generator/oplsaa_subset.prm delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene/moltemplate_files/system.lt delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene/run.in.npt delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene/run.in.nvt delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/README.TXT delete mode 100755 tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/README_run.sh delete mode 100755 tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/README_setup.sh delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/README_visualize.txt delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/images/benzene.jpg delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/images/ethylene+benzene_box80x80x80_LR.jpg delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/images/ethylene.jpg delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/moltemplate_files/benzene.lt delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/moltemplate_files/ethylene.lt delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/moltemplate_files/oplsaa_lt_generator/AUTHOR.TXT delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/moltemplate_files/oplsaa_lt_generator/README.TXT delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/moltemplate_files/oplsaa_lt_generator/minimal_versions/README.TXT delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/moltemplate_files/oplsaa_lt_generator/minimal_versions/oplsaa_subset_minimal.prm delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/moltemplate_files/oplsaa_lt_generator/minimal_versions/oplsaa_subset_simplified.prm delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/moltemplate_files/oplsaa_lt_generator/oplsaa_subset.prm delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/moltemplate_files/system.lt delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/moltemplate_files/system.xyz delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/packmol_files/README.TXT delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/packmol_files/benzene.xyz delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/packmol_files/ethylene.xyz delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/packmol_files/mix_ethylene+benzene.inp delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/run.in.npt delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/run.in.nvt delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/hexadecane/README.TXT delete mode 100755 tools/moltemplate/examples/force_field_OPLSAA/hexadecane/README_run.sh delete mode 100755 tools/moltemplate/examples/force_field_OPLSAA/hexadecane/README_setup.sh delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/hexadecane/README_visualize.txt delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/hexadecane/WARNING.TXT delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/hexadecane/images/hexadecane_12x12x2_t=0_LR.jpg delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/hexadecane/images/hexadecane_12x12x2_t=10ps_npt_LR.jpg delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/hexadecane/images/hexadecane_LR.jpg delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/hexadecane/moltemplate_files/ch2group.lt delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/hexadecane/moltemplate_files/ch3group.lt delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/hexadecane/moltemplate_files/hexadecane.lt delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/hexadecane/moltemplate_files/oplsaa_lt_generator/AUTHOR.TXT delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/hexadecane/moltemplate_files/oplsaa_lt_generator/README.TXT delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/hexadecane/moltemplate_files/oplsaa_lt_generator/oplsaa_subset.prm delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/hexadecane/moltemplate_files/system.lt delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/hexadecane/run.in.npt delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/hexadecane/run.in.nvt delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/methane/README.TXT delete mode 100755 tools/moltemplate/examples/force_field_OPLSAA/methane/README_run.sh delete mode 100755 tools/moltemplate/examples/force_field_OPLSAA/methane/README_setup.sh delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/methane/README_visualize.txt delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/methane/moltemplate_files/methane.lt delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/methane/moltemplate_files/oplsaa_lt_generator/AUTHOR.TXT delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/methane/moltemplate_files/oplsaa_lt_generator/README.TXT delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/methane/moltemplate_files/oplsaa_lt_generator/oplsaa_subset.prm delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/methane/moltemplate_files/system.lt delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/methane/run.in.npt delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/methane/run.in.nvt delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/waterSPCE+methane/README.TXT delete mode 100755 tools/moltemplate/examples/force_field_OPLSAA/waterSPCE+methane/README_run.sh delete mode 100755 tools/moltemplate/examples/force_field_OPLSAA/waterSPCE+methane/README_setup.sh delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/waterSPCE+methane/README_visualize.txt delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/waterSPCE+methane/moltemplate_files/methane.lt delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/waterSPCE+methane/moltemplate_files/oplsaa_lt_generator/AUTHOR.TXT delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/waterSPCE+methane/moltemplate_files/oplsaa_lt_generator/README.TXT delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/waterSPCE+methane/moltemplate_files/oplsaa_lt_generator/oplsaa_subset.prm delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/waterSPCE+methane/moltemplate_files/spce.lt delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/waterSPCE+methane/moltemplate_files/system.lt delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/waterSPCE+methane/run.in.npt delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/waterSPCE+methane/run.in.nvt delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/waterSPC_using_OPLSAA/README.TXT delete mode 100755 tools/moltemplate/examples/force_field_OPLSAA/waterSPC_using_OPLSAA/README_run.sh delete mode 100755 tools/moltemplate/examples/force_field_OPLSAA/waterSPC_using_OPLSAA/README_setup.sh delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/waterSPC_using_OPLSAA/README_visualize.txt delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/waterSPC_using_OPLSAA/TEST_density_estimate.txt delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/waterSPC_using_OPLSAA/moltemplate_files/oplsaa_lt_generator/AUTHOR.TXT delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/waterSPC_using_OPLSAA/moltemplate_files/oplsaa_lt_generator/README.TXT delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/waterSPC_using_OPLSAA/moltemplate_files/oplsaa_lt_generator/oplsaa_subset.prm delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/waterSPC_using_OPLSAA/moltemplate_files/spc.lt delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/waterSPC_using_OPLSAA/moltemplate_files/system.lt delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/waterSPC_using_OPLSAA/run.in.npt delete mode 100644 tools/moltemplate/examples/force_field_OPLSAA/waterSPC_using_OPLSAA/run.in.nvt delete mode 100644 tools/moltemplate/examples/force_field_OPLSUA_united_atom/propane/README.TXT delete mode 100755 tools/moltemplate/examples/force_field_OPLSUA_united_atom/propane/README_run.sh delete mode 100755 tools/moltemplate/examples/force_field_OPLSUA_united_atom/propane/README_setup.sh delete mode 100644 tools/moltemplate/examples/force_field_OPLSUA_united_atom/propane/README_visualize.txt delete mode 100644 tools/moltemplate/examples/force_field_OPLSUA_united_atom/propane/moltemplate_files/propane.lt delete mode 100644 tools/moltemplate/examples/force_field_OPLSUA_united_atom/propane/moltemplate_files/system.lt delete mode 100644 tools/moltemplate/examples/force_field_OPLSUA_united_atom/propane/run.in.npt delete mode 100644 tools/moltemplate/examples/force_field_OPLSUA_united_atom/propane/run.in.nvt delete mode 100644 tools/moltemplate/examples/force_field_explicit_parameters/aluminum_crystal_strain/README.TXT delete mode 100755 tools/moltemplate/examples/force_field_explicit_parameters/aluminum_crystal_strain/README_setup.sh delete mode 100644 tools/moltemplate/examples/force_field_explicit_parameters/aluminum_crystal_strain/README_visualize.txt delete mode 100644 tools/moltemplate/examples/force_field_explicit_parameters/aluminum_crystal_strain/images/AlCell_LR.jpg delete mode 100644 tools/moltemplate/examples/force_field_explicit_parameters/aluminum_crystal_strain/images/AlCrystal10x10x10_t=0steps_LR.jpg delete mode 100644 tools/moltemplate/examples/force_field_explicit_parameters/aluminum_crystal_strain/images/AlCrystal10x10x10_t=20000steps_LR.jpg delete mode 100755 tools/moltemplate/examples/force_field_explicit_parameters/aluminum_crystal_strain/moltemplate_files/README.sh delete mode 100644 tools/moltemplate/examples/force_field_explicit_parameters/aluminum_crystal_strain/moltemplate_files/al_cell.lt delete mode 100644 tools/moltemplate/examples/force_field_explicit_parameters/aluminum_crystal_strain/moltemplate_files/system.lt delete mode 100644 tools/moltemplate/examples/force_field_explicit_parameters/aluminum_crystal_strain/run.in delete mode 100755 tools/moltemplate/examples/force_field_explicit_parameters/ice_crystal/README_run.sh delete mode 100755 tools/moltemplate/examples/force_field_explicit_parameters/ice_crystal/README_setup.sh delete mode 100644 tools/moltemplate/examples/force_field_explicit_parameters/ice_crystal/README_visualize.txt delete mode 100644 tools/moltemplate/examples/force_field_explicit_parameters/ice_crystal/images/ice_rect8_crystal_3x2x2_LR.jpg delete mode 100644 tools/moltemplate/examples/force_field_explicit_parameters/ice_crystal/images/ice_rect8_unitcell.png delete mode 100644 tools/moltemplate/examples/force_field_explicit_parameters/ice_crystal/moltemplate_files/spce.lt delete mode 100644 tools/moltemplate/examples/force_field_explicit_parameters/ice_crystal/moltemplate_files/spce_ice_rect16.lt delete mode 100644 tools/moltemplate/examples/force_field_explicit_parameters/ice_crystal/moltemplate_files/spce_ice_rect32.lt delete mode 100644 tools/moltemplate/examples/force_field_explicit_parameters/ice_crystal/moltemplate_files/spce_ice_rect8.lt delete mode 100644 tools/moltemplate/examples/force_field_explicit_parameters/ice_crystal/moltemplate_files/system.lt delete mode 100644 tools/moltemplate/examples/force_field_explicit_parameters/ice_crystal/run.in.npt delete mode 100644 tools/moltemplate/examples/force_field_explicit_parameters/ice_crystal/run.in.nvt delete mode 100644 tools/moltemplate/examples/force_field_explicit_parameters/nanotube+water/README.TXT delete mode 100644 tools/moltemplate/examples/force_field_explicit_parameters/nanotube+water/README_realistic_junctions.txt delete mode 100755 tools/moltemplate/examples/force_field_explicit_parameters/nanotube+water/README_run.sh delete mode 100755 tools/moltemplate/examples/force_field_explicit_parameters/nanotube+water/README_setup.sh delete mode 100644 tools/moltemplate/examples/force_field_explicit_parameters/nanotube+water/README_visualize.txt delete mode 100644 tools/moltemplate/examples/force_field_explicit_parameters/nanotube+water/images/graphene_unit_cell.jpg delete mode 100644 tools/moltemplate/examples/force_field_explicit_parameters/nanotube+water/images/nanotube+walls+water_side_pbc_t=0ps_LR.jpg delete mode 100644 tools/moltemplate/examples/force_field_explicit_parameters/nanotube+water/images/nanotube+walls+water_side_pbc_t=108ps_LR.jpg delete mode 100644 tools/moltemplate/examples/force_field_explicit_parameters/nanotube+water/images/nanotube+walls+water_side_pbc_t=305ps_LR.jpg delete mode 100644 tools/moltemplate/examples/force_field_explicit_parameters/nanotube+water/images/nanotube+walls+water_top_nopbc_t=0_LR.jpg delete mode 100644 tools/moltemplate/examples/force_field_explicit_parameters/nanotube+water/images/nanotube+walls_side_nopbc_LR.jpg delete mode 100644 tools/moltemplate/examples/force_field_explicit_parameters/nanotube+water/images/water_side_nopbc_LR.jpg delete mode 100755 tools/moltemplate/examples/force_field_explicit_parameters/nanotube+water/moltemplate_files/README.sh delete mode 100644 tools/moltemplate/examples/force_field_explicit_parameters/nanotube+water/moltemplate_files/graphene.lt delete mode 100644 tools/moltemplate/examples/force_field_explicit_parameters/nanotube+water/moltemplate_files/graphene_walls.lt delete mode 100644 tools/moltemplate/examples/force_field_explicit_parameters/nanotube+water/moltemplate_files/graphite.lt delete mode 100644 tools/moltemplate/examples/force_field_explicit_parameters/nanotube+water/moltemplate_files/nanotube.lt delete mode 100644 tools/moltemplate/examples/force_field_explicit_parameters/nanotube+water/moltemplate_files/spce.lt delete mode 100644 tools/moltemplate/examples/force_field_explicit_parameters/nanotube+water/moltemplate_files/system.lt delete mode 100644 tools/moltemplate/examples/force_field_explicit_parameters/nanotube+water/moltemplate_files/water_box.lt delete mode 100644 tools/moltemplate/examples/force_field_explicit_parameters/nanotube+water/moltemplate_files/watmw.lt delete mode 100644 tools/moltemplate/examples/force_field_explicit_parameters/nanotube+water/run.in.npt delete mode 100644 tools/moltemplate/examples/force_field_explicit_parameters/nanotube+water/run.in.nvt delete mode 100755 tools/moltemplate/examples/force_field_explicit_parameters/waterSPCE+Na+Cl/README_run.sh delete mode 100755 tools/moltemplate/examples/force_field_explicit_parameters/waterSPCE+Na+Cl/README_setup.sh delete mode 100644 tools/moltemplate/examples/force_field_explicit_parameters/waterSPCE+Na+Cl/README_visualize.txt delete mode 100644 tools/moltemplate/examples/force_field_explicit_parameters/waterSPCE+Na+Cl/images/Cl.jpg delete mode 100644 tools/moltemplate/examples/force_field_explicit_parameters/waterSPCE+Na+Cl/images/Na.jpg delete mode 100644 tools/moltemplate/examples/force_field_explicit_parameters/waterSPCE+Na+Cl/images/wat.jpg delete mode 100644 tools/moltemplate/examples/force_field_explicit_parameters/waterSPCE+Na+Cl/images/waterSPCE+Na+Cl_t=0.jpg delete mode 100644 tools/moltemplate/examples/force_field_explicit_parameters/waterSPCE+Na+Cl/images/waterSPCE+Na+Cl_t=100ps.jpg delete mode 100644 tools/moltemplate/examples/force_field_explicit_parameters/waterSPCE+Na+Cl/moltemplate_files/ions.lt delete mode 100644 tools/moltemplate/examples/force_field_explicit_parameters/waterSPCE+Na+Cl/moltemplate_files/spce.lt delete mode 100644 tools/moltemplate/examples/force_field_explicit_parameters/waterSPCE+Na+Cl/moltemplate_files/system.lt delete mode 100644 tools/moltemplate/examples/force_field_explicit_parameters/waterSPCE+Na+Cl/run.in.npt delete mode 100644 tools/moltemplate/examples/force_field_explicit_parameters/waterSPCE+Na+Cl/run.in.nvt delete mode 100644 tools/moltemplate/examples/misc_examples/menger_sponge/README.TXT delete mode 100755 tools/moltemplate/examples/misc_examples/menger_sponge/README_setup.sh delete mode 100644 tools/moltemplate/examples/misc_examples/menger_sponge/README_visualize.txt delete mode 100644 tools/moltemplate/examples/misc_examples/menger_sponge/images/AlCell_LR.jpg delete mode 100644 tools/moltemplate/examples/misc_examples/menger_sponge/images/lvl1_LR.jpg delete mode 100644 tools/moltemplate/examples/misc_examples/menger_sponge/images/lvl2_LR.jpg delete mode 100644 tools/moltemplate/examples/misc_examples/menger_sponge/images/lvl3_LR.jpg delete mode 100644 tools/moltemplate/examples/misc_examples/menger_sponge/images/menger_sponge_lattice_8cells_t=0_zoom1_LR2.jpg delete mode 100644 tools/moltemplate/examples/misc_examples/menger_sponge/images/menger_sponge_lattice_8cells_t=7400_LR.jpg delete mode 100644 tools/moltemplate/examples/misc_examples/menger_sponge/moltemplate_files/al_cell.lt delete mode 100644 tools/moltemplate/examples/misc_examples/menger_sponge/moltemplate_files/elegant_inefficient_version/al_cell.lt delete mode 100644 tools/moltemplate/examples/misc_examples/menger_sponge/moltemplate_files/elegant_inefficient_version/menger_cubes.lt delete mode 100644 tools/moltemplate/examples/misc_examples/menger_sponge/moltemplate_files/elegant_inefficient_version/system.lt delete mode 100644 tools/moltemplate/examples/misc_examples/menger_sponge/moltemplate_files/menger_cubes.lt delete mode 100644 tools/moltemplate/examples/misc_examples/menger_sponge/moltemplate_files/system.lt delete mode 100644 tools/moltemplate/examples/misc_examples/menger_sponge/run.in delete mode 100644 tools/moltemplate/examples/misc_examples/pyramids_vs_gravity/README.TXT delete mode 100644 tools/moltemplate/examples/misc_examples/pyramids_vs_gravity/README_VMD_graphene.txt delete mode 100755 tools/moltemplate/examples/misc_examples/pyramids_vs_gravity/README_setup.sh delete mode 100644 tools/moltemplate/examples/misc_examples/pyramids_vs_gravity/README_visualize.txt delete mode 100644 tools/moltemplate/examples/misc_examples/pyramids_vs_gravity/images/pyramids_vs_gravity_t=04800steps_LR.jpg delete mode 100644 tools/moltemplate/examples/misc_examples/pyramids_vs_gravity/images/pyramids_vs_gravity_t=12200steps_LR.jpg delete mode 100644 tools/moltemplate/examples/misc_examples/pyramids_vs_gravity/images/pyramids_vs_gravity_t=33000steps_LR.jpg delete mode 100755 tools/moltemplate/examples/misc_examples/pyramids_vs_gravity/moltemplate_files/README.sh delete mode 100644 tools/moltemplate/examples/misc_examples/pyramids_vs_gravity/moltemplate_files/graphene.lt delete mode 100644 tools/moltemplate/examples/misc_examples/pyramids_vs_gravity/moltemplate_files/graphene_wall.lt delete mode 100644 tools/moltemplate/examples/misc_examples/pyramids_vs_gravity/moltemplate_files/pyramids.lt delete mode 100644 tools/moltemplate/examples/misc_examples/pyramids_vs_gravity/moltemplate_files/system.lt delete mode 100644 tools/moltemplate/examples/misc_examples/pyramids_vs_gravity/run.in delete mode 100644 tools/moltemplate/moltemplate_manual.pdf delete mode 100644 tools/moltemplate/src/bonds_by_type.py delete mode 100644 tools/moltemplate/src/chargepairs_by_type.py delete mode 100644 tools/moltemplate/src/dump2data.py delete mode 100644 tools/moltemplate/src/extract_lammps_data.py delete mode 100644 tools/moltemplate/src/ltemplify.py delete mode 100644 tools/moltemplate/src/lttree.py delete mode 100644 tools/moltemplate/src/lttree_check.py delete mode 100644 tools/moltemplate/src/lttree_postprocess.py delete mode 100644 tools/moltemplate/src/lttree_styles.py delete mode 100755 tools/moltemplate/src/moltemplate.sh delete mode 100644 tools/moltemplate/src/moltemplate_docs_useful_scripts/docs_dump2data.txt delete mode 100644 tools/moltemplate/src/moltemplate_docs_useful_scripts/docs_extract_lammps_data.txt delete mode 100644 tools/moltemplate/src/moltemplate_docs_useful_scripts/docs_raw2data.txt delete mode 100644 tools/moltemplate/src/moltemplate_force_fields/amber/README.TXT delete mode 100755 tools/moltemplate/src/moltemplate_force_fields/amber/amberparm2lt.sh delete mode 100755 tools/moltemplate/src/moltemplate_force_fields/amber/amberparm_angle_to_lt.py delete mode 100755 tools/moltemplate/src/moltemplate_force_fields/amber/amberparm_bond_to_lt.py delete mode 100755 tools/moltemplate/src/moltemplate_force_fields/amber/amberparm_dihedral_to_lt.py delete mode 100755 tools/moltemplate/src/moltemplate_force_fields/amber/amberparm_improper_to_lt.py delete mode 100755 tools/moltemplate/src/moltemplate_force_fields/amber/amberparm_mass_to_lt.py delete mode 100755 tools/moltemplate/src/moltemplate_force_fields/amber/amberparm_pair_to_lt.py delete mode 100644 tools/moltemplate/src/moltemplate_force_fields/gaff.lt delete mode 100644 tools/moltemplate/src/moltemplate_force_fields/graphene.lt delete mode 100644 tools/moltemplate/src/moltemplate_force_fields/graphite.lt delete mode 100644 tools/moltemplate/src/moltemplate_force_fields/images/graphene_unit_cell.jpg delete mode 100644 tools/moltemplate/src/moltemplate_force_fields/images/ice_rect8_unitcell.png delete mode 100644 tools/moltemplate/src/moltemplate_force_fields/images/spce_ball_and_stick.jpg delete mode 100644 tools/moltemplate/src/moltemplate_force_fields/loplsaa.lt delete mode 100644 tools/moltemplate/src/moltemplate_force_fields/oplsaa.lt delete mode 100644 tools/moltemplate/src/moltemplate_force_fields/oplsaa/AUTHOR.TXT delete mode 100644 tools/moltemplate/src/moltemplate_force_fields/oplsaa/README.TXT delete mode 100644 tools/moltemplate/src/moltemplate_force_fields/oplsaa/loplsaa_ext.prm delete mode 100644 tools/moltemplate/src/moltemplate_force_fields/spce.lt delete mode 100644 tools/moltemplate/src/moltemplate_force_fields/spce_ice_rect16.lt delete mode 100644 tools/moltemplate/src/moltemplate_force_fields/spce_ice_rect32.lt delete mode 100644 tools/moltemplate/src/moltemplate_force_fields/spce_ice_rect8.lt delete mode 100644 tools/moltemplate/src/moltemplate_force_fields/tip3p_1983.lt delete mode 100644 tools/moltemplate/src/moltemplate_force_fields/tip3p_1983_charmm.lt delete mode 100644 tools/moltemplate/src/moltemplate_force_fields/tip3p_2004.lt delete mode 100644 tools/moltemplate/src/moltemplate_force_fields/trappe1998.lt delete mode 100644 tools/moltemplate/src/moltemplate_force_fields/watmw.lt delete mode 100755 tools/moltemplate/src/moltemplate_scripts_depreciated/oplsaa_moltemplate.py delete mode 100644 tools/moltemplate/src/nbody_Angles.py delete mode 100644 tools/moltemplate/src/nbody_Bonds.py delete mode 100644 tools/moltemplate/src/nbody_Dihedrals.py delete mode 100644 tools/moltemplate/src/nbody_Impropers.py delete mode 100644 tools/moltemplate/src/nbody_alternate_symmetry/class2_dih.py delete mode 100644 tools/moltemplate/src/nbody_alternate_symmetry/class2_imp.py delete mode 100644 tools/moltemplate/src/nbody_alternate_symmetry/gaff_imp.py delete mode 100644 tools/moltemplate/src/nbody_alternate_symmetry/nbody_Dihedrals_nosym.py delete mode 100644 tools/moltemplate/src/nbody_alternate_symmetry/nbody_Impropers_Icenter_swapJK.py delete mode 100644 tools/moltemplate/src/nbody_alternate_symmetry/nbody_Impropers_Icenter_swapJKL.py delete mode 100644 tools/moltemplate/src/nbody_alternate_symmetry/nbody_Impropers_Jcenter.py delete mode 100644 tools/moltemplate/src/nbody_alternate_symmetry/nbody_Impropers_Jcenter_nosym.py delete mode 100644 tools/moltemplate/src/nbody_alternate_symmetry/opls_imp.py delete mode 100644 tools/moltemplate/src/nbody_by_type.py delete mode 100644 tools/moltemplate/src/nbody_by_type_lib.py delete mode 100644 tools/moltemplate/src/nbody_fix_ttree_assignments.py delete mode 100644 tools/moltemplate/src/nbody_graph_search.py delete mode 100644 tools/moltemplate/src/nbody_reorder_atoms.py delete mode 100644 tools/moltemplate/src/ordereddict.py delete mode 100644 tools/moltemplate/src/pdbsort.py delete mode 100644 tools/moltemplate/src/postprocess_input_script.py delete mode 100644 tools/moltemplate/src/raw2data.py delete mode 100644 tools/moltemplate/src/remove_duplicate_atoms.py delete mode 100644 tools/moltemplate/src/remove_duplicates_nbody.py delete mode 100644 tools/moltemplate/src/renumber_DATA_first_column.py delete mode 100644 tools/moltemplate/src/tinkerparm2lt.py delete mode 100644 tools/moltemplate/src/ttree.py delete mode 100644 tools/moltemplate/src/ttree_lex.py delete mode 100644 tools/moltemplate/src/ttree_matrix_stack.py delete mode 100644 tools/moltemplate/src/ttree_render.py diff --git a/tools/moltemplate/LICENSE.TXT b/tools/moltemplate/LICENSE.TXT deleted file mode 100644 index 73eec32380..0000000000 --- a/tools/moltemplate/LICENSE.TXT +++ /dev/null @@ -1,28 +0,0 @@ - -Author: Andrew Jewett, Shea Group, http://www.chem.ucsb.edu/~sheagroup/ -Copyright (c) 2014, Regents of the University of California -All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of the University of California, Santa Barbara nor the - names of its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -THE POSSIBILITY OF SUCH DAMAGE. - diff --git a/tools/moltemplate/README.TXT b/tools/moltemplate/README.TXT deleted file mode 100644 index 773464d01b..0000000000 --- a/tools/moltemplate/README.TXT +++ /dev/null @@ -1,61 +0,0 @@ - -- Description: -- - -Moltemplate is a cross-platform text-based molecule builder for LAMMPS. - - -- Typical usage: -- - -moltemplate.sh [-atomstyle style] [-pdb/-xyz coord_file] [-vmd] system.lt - - -- Web page: -- - -Documentation, examples, and supporting code can be downloaded at: - - http://www.moltemplate.org -The most up-to-date version of moltemplate can be downloaded here. -(After download, you can unpack the archive using: - tar xzf moltemplate_2012-3-31.tar.gz -The date will vary from version to version.) - ----------------------------------------------------- ----------- INSTALLATION INSTRUCTIONS: ------------ ----------------------------------------------------- - -This directory should contain two folders: - src/ <-- location of all python and bash scripts - common/ <-- location of shared force fields and molecules - -The ``moltemplate.sh'' script and the python scripts that it invokes are -located in the ``src/'' subdirectory. You should update your PATH environment -variable to include this directory. - -If you do not know what a PATH environment variable is, read: - http://www.linfo.org/path_env_var.html -(I receive this question often.) - -It is also a good idea to set your MOLTEMPLATE_PATH environment variable to -point to the ``common/'' subdirectory. -(Force fields and commonly used molecules will eventually be located here.) - - -- Installation example --- - -Suppose the directory with this README.TXT file is located at ~/moltemplate. - -If you use the bash shell, typically you would edit your -~/.profile, ~/.bash_profile or ~/.bashrc files to contain the following lines: - export PATH="$PATH:$HOME/moltemplate/src" - export MOLTEMPLATE_PATH="$HOME/moltemplate/common" -If you use the tcsh shell, typically you would edit your -~/.login, ~/.cshrc, or ~/.tcshrc files to contain the following lines: - setenv PATH "$PATH:$HOME/moltemplate/src" - setenv MOLTEMPLATE_PATH "$HOME/moltemplate/common" - - -- Requirements: -- - -Moltemplate requires the Bourne-shell, and a recent version of python -(2.7, 3.0 or higher), and can run on OS X, linux, or windows (if a -suitable shell environment has been installed). - - -- License: -- - -Moltemplate is available under the terms of the open-source 3-clause BSD -license. (See LICENSE.TXT.) diff --git a/tools/moltemplate/examples/README.TXT b/tools/moltemplate/examples/README.TXT deleted file mode 100644 index e3602541c7..0000000000 --- a/tools/moltemplate/examples/README.TXT +++ /dev/null @@ -1,24 +0,0 @@ -These are examples for the "moltemplate" molecule builder for LAMMPS. -http://www.moltemplate.org - -Each directory contains one or more examples. - -Each example directory contains: - - images/ This folder has pictures of the molecules in the system - moltemplate_files/ This folder contains LT files and other auxiliary files - README_setup.sh Instructions for how to use moltemplate (executable) - README_visualize.txt Instructions for viewing in DATA/DUMP files in VMD - - ...and one or more LAMMPS input scripts with names like - - run.in.min - run.in.npt - run.in.nvt - -You can run these scripts using - lmp_linux -i run.in.npt -(The name of your lammps binary, "lmp_linux" in this example, may vary. - Sometimes, these scripts must be run in a certain order. For example - it may be necessary to run run.in.min to minimize the system before you can use run.in.npt, and later run.in.nvt. The README_run.sh file in each subdirectory - specifies indicates the order. These files have not been optimized.) diff --git a/tools/moltemplate/examples/coarse_grained_examples/3bodyWater+hydrocarbons_MW+TraPPE/README.TXT b/tools/moltemplate/examples/coarse_grained_examples/3bodyWater+hydrocarbons_MW+TraPPE/README.TXT deleted file mode 100644 index 33eeddda6e..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/3bodyWater+hydrocarbons_MW+TraPPE/README.TXT +++ /dev/null @@ -1,28 +0,0 @@ -# -------- REQUIREMENTS: --------- -# 1) This example requires the "MANYBODY" package. -# As of 2012-9, it is included by default, but this may change in the future. -# If lammps complains of a missing pair style enter "make yes-MANYBODY" -# into the shell before compiling lammps. For details see: -# http://lammps.sandia.gov/doc/Section_start.html#start_3 -This is a relatively complex example containing two different types of -molecules, and a hybrid of Lennard-Jones and 3-body SW "pair" styles. - -The cyclododecane molecule uses the -TraPPE force field for hydrocarbon chains. -The parameters for the TraPPE force field are -in a file named "trappe1998.lt" which should be -located in the MOLTEMPLATE_PATH. -(See moltemplate installation instructions.) - -The water solvent is implemented using the 3-body single-particle -coarse-grained "mW" water model: -Molinero, V. and Moore, E.B., J. Phys. Chem. B 2009, 113, 4008-4016 - -More detailed instructions on how to build LAMMPS input files and -run a short simulation are provided in other README files. - -step 1) -README_setup.sh - -step 2) -README_run.sh diff --git a/tools/moltemplate/examples/coarse_grained_examples/3bodyWater+hydrocarbons_MW+TraPPE/README_run.sh b/tools/moltemplate/examples/coarse_grained_examples/3bodyWater+hydrocarbons_MW+TraPPE/README_run.sh deleted file mode 100755 index 68acee49b9..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/3bodyWater+hydrocarbons_MW+TraPPE/README_run.sh +++ /dev/null @@ -1,31 +0,0 @@ -# --- Running LAMMPS --- -# -- Prerequisites: -- -# The 2 files "run.in.npt", and "run.in.nvt" are LAMMPS -# input scripts which link to the input scripts and data files -# you hopefully have created earlier with moltemplate.sh: -# system.in.init, system.in.settings, system.data, system.in.sw -# If not, carry out the instructions in "README_setup.sh". -# -# -- Instructions: -- -# If "lmp_mpi" is the name of the command you use to invoke lammps, -# then you would run lammps on these files this way: - - -lmp_mpi -i run.in.npt # minimization and simulation at constant pressure -lmp_mpi -i run.in.nvt # minimization and simulation at constant volume - -#(Note: The constant volume simulation lacks pressure equilibration. These are -# completely separate simulations. The results of the constant pressure -# simulation are ignored when beginning the simulation at constant volume. -# This can be fixed. Read "run.in.nvt" for equilibration instructions.) - - - - - - - -# If you have compiled the MPI version of lammps, you can run lammps in parallel -#mpirun -np 4 lmp_mpi -i run.in.npt -#mpirun -np 4 lmp_mpi -i run.in.nvt -# (assuming you have 4 processors available) diff --git a/tools/moltemplate/examples/coarse_grained_examples/3bodyWater+hydrocarbons_MW+TraPPE/README_setup.sh b/tools/moltemplate/examples/coarse_grained_examples/3bodyWater+hydrocarbons_MW+TraPPE/README_setup.sh deleted file mode 100755 index cb4d908984..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/3bodyWater+hydrocarbons_MW+TraPPE/README_setup.sh +++ /dev/null @@ -1,25 +0,0 @@ - - -# Create LAMMPS input files this way: -cd moltemplate_files - - # run moltemplate - - moltemplate.sh -a "@atom:/WatMW/mW 1" system.lt - - # Here we just want to make sure that the "mW" atom type is assigned to - # number "1". It should be by default, so usually you can leave out - # -a "@atom:/WatMW/mW 1". - - # This will generate various files with names ending in *.in* and *.data. - # These files are the input files directly read by LAMMPS. Move them to - # the parent directory (or wherever you plan to run the simulation). - - mv -f system.in* system.data ../ - - # Optional: - # The "./output_ttree/" directory is full of temporary files generated by - # moltemplate. They can be useful for debugging, but are usually thrown away. - rm -rf output_ttree/ - -cd ../ diff --git a/tools/moltemplate/examples/coarse_grained_examples/3bodyWater+hydrocarbons_MW+TraPPE/README_visualize.txt b/tools/moltemplate/examples/coarse_grained_examples/3bodyWater+hydrocarbons_MW+TraPPE/README_visualize.txt deleted file mode 100644 index 019afc1444..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/3bodyWater+hydrocarbons_MW+TraPPE/README_visualize.txt +++ /dev/null @@ -1,87 +0,0 @@ - - ------- To view a lammps trajectory in VMD -------- - - -1) Build a PSF file for use in viewing with VMD. - -This step works with VMD 1.9 and topotools 1.2. -(Older versions, like VMD 1.8.6, don't support this.) - - -a) Start VMD -b) Menu Extensions->Tk Console -c) Enter: - -(I assume that the the DATA file is called "system.data") - - topo readlammpsdata system.data full - animate write psf system.psf - -2) - -Later, to Load a trajectory in VMD: - - Start VMD - Select menu: File->New Molecule - -Browse to select the PSF file you created above, and load it. - (Don't close the window yet.) - -Browse to select the trajectory file. - If necessary, for "file type" select: "LAMMPS Trajectory" - Load it. - - ---- A note on trajectory format: ----- -If the trajectory is a DUMP file, then make sure the it contains the -information you need for pbctools (see below. I've been using this -command in my LAMMPS scripts to create the trajectories: - - dump 1 all custom 5000 DUMP_FILE.lammpstrj id mol type x y z ix iy iz - -It's a good idea to use an atom_style which supports molecule-ID numbers -so that you can assign a molecule-ID number to each atom. (I think this -is needed to wrap atom coordinates without breaking molecules in half.) - -Of course, you don't have to save your trajectories in DUMP format, -(other formats like DCD work fine) I just mention dump files -because these are the files I'm familiar with. - -3) ----- Wrap the coordinates to the unit cell - (without cutting the molecules in half) - -a) Start VMD -b) Load the trajectory in VMD (see above) -c) Menu Extensions->Tk Console -d) Try entering these commands: - - pbc wrap -compound res -all - pbc box - - ----- Optional ---- - Sometimes the solvent or membrane obscures the view of the solute. - It can help to shift the location of the periodic boundary box - To shift the box in the y direction (for example) do this: - - pbc wrap -compound res -all -shiftcenterrel {0.0 0.15 0.0} - pbc box -shiftcenterrel {0.0 0.15 0.0} - - Distances are measured in units of box-length fractions, not Angstroms. - - Alternately if you have a solute whose atoms are all of type 1, - then you can also try this to center the box around it: - - pbc wrap -sel type=1 -all -centersel type=2 -center com - -4) - You should check if your periodic boundary conditions are too small. - To do that: - select Graphics->Representations menu option - click on the "Periodic" tab, and - click on the "+x", "-x", "+y", "-y", "+z", "-z" checkboxes. - -5) Optional: If you like, change the atom types in the PSF file so - that VMD recognizes the atom types, use something like: - -sed -e 's/ 1 1 / C C /g' < system.psf > temp1.psf -sed -e 's/ 2 2 / H H /g' < temp1.psf > temp2.psf -sed -e 's/ 3 3 / P P /g' < temp2.psf > system.psf - -(If you do this, it might effect step 2 above.) diff --git a/tools/moltemplate/examples/coarse_grained_examples/3bodyWater+hydrocarbons_MW+TraPPE/images/cyclododecane+watMW_t=0ps_LR.jpg b/tools/moltemplate/examples/coarse_grained_examples/3bodyWater+hydrocarbons_MW+TraPPE/images/cyclododecane+watMW_t=0ps_LR.jpg deleted file mode 100644 index 5123dc7f60bec04fb5d42fab3e70027ed9516826..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 51874 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 F0su0K+4%qf diff --git a/tools/moltemplate/examples/coarse_grained_examples/3bodyWater+hydrocarbons_MW+TraPPE/images/cyclododecane+watMW_t=400ps_LR.jpg b/tools/moltemplate/examples/coarse_grained_examples/3bodyWater+hydrocarbons_MW+TraPPE/images/cyclododecane+watMW_t=400ps_LR.jpg deleted file mode 100644 index 4003ac5f0669fabc92c11f2f31de24c3ca37aa95..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 39434 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 diff --git a/tools/moltemplate/examples/coarse_grained_examples/3bodyWater+hydrocarbons_MW+TraPPE/images/cyclopentane.jpg b/tools/moltemplate/examples/coarse_grained_examples/3bodyWater+hydrocarbons_MW+TraPPE/images/cyclopentane.jpg deleted file mode 100644 index 6591b236a3c56bb6291df28dbd8d8c7bf80a7ee9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12330 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 NKNN}ouA)3l{~r!G!6yI! diff --git a/tools/moltemplate/examples/coarse_grained_examples/3bodyWater+hydrocarbons_MW+TraPPE/images/cyclopentane_unrelaxed.jpg b/tools/moltemplate/examples/coarse_grained_examples/3bodyWater+hydrocarbons_MW+TraPPE/images/cyclopentane_unrelaxed.jpg deleted file mode 100644 index 9b4ca06fb82ec74f7c099ceb6f864433e0004df4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12835 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 diff --git a/tools/moltemplate/examples/coarse_grained_examples/3bodyWater+hydrocarbons_MW+TraPPE/images/watMW.jpg b/tools/moltemplate/examples/coarse_grained_examples/3bodyWater+hydrocarbons_MW+TraPPE/images/watMW.jpg deleted file mode 100644 index 0ac8c2c01152e5bff958fd980a6a6f771d373835..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3141 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 S!XyHc5dRnOduQnGkNyWiTk Console -c) Enter: - -(I assume that the the DATA file is called "system.data") - - topo readlammpsdata system.data full - animate write psf system.psf - -2) - -Later, to Load a trajectory in VMD: - - Start VMD - Select menu: File->New Molecule - -Browse to select the PSF file you created above, and load it. - (Don't close the window yet.) - -Browse to select the trajectory file. - If necessary, for "file type" select: "LAMMPS Trajectory" - Load it. - - ---- A note on trajectory format: ----- -If the trajectory is a DUMP file, then make sure the it contains the -information you need for pbctools (see below. I've been using this -command in my LAMMPS scripts to create the trajectories: - - dump 1 all custom 5000 DUMP_FILE.lammpstrj id mol type x y z ix iy iz - -It's a good idea to use an atom_style which supports molecule-ID numbers -so that you can assign a molecule-ID number to each atom. (I think this -is needed to wrap atom coordinates without breaking molecules in half.) - -Of course, you don't have to save your trajectories in DUMP format, -(other formats like DCD work fine) I just mention dump files -because these are the files I'm familiar with. - -3) ----- Wrap the coordinates to the unit cell - (without cutting the molecules in half) - -a) Start VMD -b) Load the trajectory in VMD (see above) -c) Menu Extensions->Tk Console -d) Try entering these commands: - - pbc wrap -compound res -all - pbc box - - ----- Optional ---- - Sometimes the solvent or membrane obscures the view of the solute. - It can help to shift the location of the periodic boundary box - To shift the box in the y direction (for example) do this: - - pbc wrap -compound res -all -shiftcenterrel {0.0 0.0 -0.5} - pbc box -shiftcenterrel {0.0 0.0 -0.5} -style tubes -width 0.75 - - Distances are measured in units of box-length fractions, not Angstroms. - - Alternately if you have a solute whose atoms are all of type 1, - then you can also try this to center the box around it: - - pbc wrap -sel type=1 -all -centersel type=2 -center com - -4) - You should check if your periodic boundary conditions are too small. - To do that: - select Graphics->Representations menu option - click on the "Periodic" tab, and - click on the "+x", "-x", "+y", "-y", "+z", "-z" checkboxes. - -5) Optional: If you like, change the atom types in the PSF file so - that VMD recognizes the atom types, use something like: - -sed -e 's/ 1 1 / C C /g' < system.psf > temp1.psf -sed -e 's/ 2 2 / H H /g' < temp1.psf > temp2.psf -sed -e 's/ 3 3 / P P /g' < temp2.psf > system.psf - -(If you do this, it might effect step 2 above.) diff --git a/tools/moltemplate/examples/coarse_grained_examples/MARTINI_examples/DPPC_bilayer_formation_PACKMOL/images/DPPC_martini_LR.jpg b/tools/moltemplate/examples/coarse_grained_examples/MARTINI_examples/DPPC_bilayer_formation_PACKMOL/images/DPPC_martini_LR.jpg deleted file mode 100644 index cc85e79ff14717ece09368596bfdf3a60748935d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12907 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 C@u4sP diff --git a/tools/moltemplate/examples/coarse_grained_examples/MARTINI_examples/DPPC_bilayer_formation_PACKMOL/images/t=26ns_300K_NPT_LR.jpg b/tools/moltemplate/examples/coarse_grained_examples/MARTINI_examples/DPPC_bilayer_formation_PACKMOL/images/t=26ns_300K_NPT_LR.jpg deleted file mode 100644 index e38e81006ae1c4af465ce169fc5d8e6d6ee96bd4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 44951 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
7S_1 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
`HGbD(lb3VE5oB}R{nn=ANp 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 diff --git a/tools/moltemplate/examples/coarse_grained_examples/MARTINI_examples/DPPC_bilayer_preformed/images/t=4ns_bilayer_preformed_GL_LR.jpg b/tools/moltemplate/examples/coarse_grained_examples/MARTINI_examples/DPPC_bilayer_preformed/images/t=4ns_bilayer_preformed_GL_LR.jpg deleted file mode 100644 index 9d5b6b594223f9bb00061b321fd2fb394783f53c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 57230 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�YCo%zb0rgeMNZSJo^J1WuuVOI&Qn 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'r(+V@0ZV@$fLOY;<0$$gKE4Y+we&usx5x%TJ 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 Console -c) Enter: - -(I assume that the the DATA file is called "system.data") - - topo readlammpsdata system.data full - animate write psf system.psf - -2) - -Later, to Load a trajectory in VMD: - - Start VMD - Select menu: File->New Molecule - -Browse to select the PSF file you created above, and load it. - (Don't close the window yet.) - -Browse to select the trajectory file. - If necessary, for "file type" select: "LAMMPS Trajectory" - Load it. - - ---- A note on trajectory format: ----- -If the trajectory is a DUMP file, then make sure the it contains the -information you need for pbctools (see below. I've been using this -command in my LAMMPS scripts to create the trajectories: - - dump 1 all custom 5000 DUMP_FILE.lammpstrj id mol type x y z ix iy iz - -It's a good idea to use an atom_style which supports molecule-ID numbers -so that you can assign a molecule-ID number to each atom. (I think this -is needed to wrap atom coordinates without breaking molecules in half.) - -Of course, you don't have to save your trajectories in DUMP format, -(other formats like DCD work fine) I just mention dump files -because these are the files I'm familiar with. - -3) ----- Wrap the coordinates to the unit cell - (without cutting the molecules in half) - -a) Start VMD -b) Load the trajectory in VMD (see above) -c) Menu Extensions->Tk Console -d) Try entering these commands: - - pbc wrap -compound res -all - pbc box - - ----- Optional ---- - It can help to shift the location of the periodic boundary box - To shift the box in the y direction (for example) do this: - - pbc wrap -compound res -all -shiftcenterrel {0.0 0.15 0.0} - pbc box -shiftcenterrel {0.0 0.15 0.0} - - Distances are measured in units of box-length fractions, not Angstroms. - - Alternately if you have a solute whose atoms are all of type 1, - then you can also try this to center the box around it: - - pbc wrap -sel type=1 -all -centersel type=2 -center com - -4) - You should check if your periodic boundary conditions are too small. - To do that: - select Graphics->Representations menu option - click on the "Periodic" tab, and - click on the "+x", "-x", "+y", "-y", "+z", "-z" checkboxes. - -5) Optional: If you like, change the atom types in the PSF file so - that VMD recognizes the atom types, use something like: - -sed -e 's/ 1 1 / C C /g' < system.psf > temp1.psf -sed -e 's/ 2 2 / H H /g' < temp1.psf > temp2.psf -sed -e 's/ 3 3 / P P /g' < temp2.psf > system.psf - -(If you do this, it might effect step 2 above.) diff --git a/tools/moltemplate/examples/coarse_grained_examples/abstract_2bead_heteropolymer/images/polymer.png b/tools/moltemplate/examples/coarse_grained_examples/abstract_2bead_heteropolymer/images/polymer.png deleted file mode 100644 index 304dbdeb9dfeb449299bd1df6b3804075acdaa59..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 53044 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 XmAEzBt2gTe~DWM4fB%tiS diff --git a/tools/moltemplate/examples/coarse_grained_examples/abstract_2bead_heteropolymer/images/t=0ns.png b/tools/moltemplate/examples/coarse_grained_examples/abstract_2bead_heteropolymer/images/t=0ns.png deleted file mode 100644 index beadf7e1bb999c282e4bb87e63b51d810f889b20..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 101303 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 O0Xk)2WBvs7y8dsOd#3#W diff --git a/tools/moltemplate/examples/coarse_grained_examples/abstract_2bead_heteropolymer/moltemplate_files/README.sh b/tools/moltemplate/examples/coarse_grained_examples/abstract_2bead_heteropolymer/moltemplate_files/README.sh deleted file mode 100755 index a5157b7106..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/abstract_2bead_heteropolymer/moltemplate_files/README.sh +++ /dev/null @@ -1,6 +0,0 @@ -# Use these commands to generate the LAMMPS input script and data file -# (and other auxilliary files): -moltemplate.sh system.lt - -# This will generate various files with names ending in *.in* and *.data. - diff --git a/tools/moltemplate/examples/coarse_grained_examples/abstract_2bead_heteropolymer/moltemplate_files/forcefield.lt b/tools/moltemplate/examples/coarse_grained_examples/abstract_2bead_heteropolymer/moltemplate_files/forcefield.lt deleted file mode 100644 index c2c01a8eee..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/abstract_2bead_heteropolymer/moltemplate_files/forcefield.lt +++ /dev/null @@ -1,139 +0,0 @@ -# The "2beadFF" is a force-field environment object containing -# force-field data, atomic masses, and bond rules. -# Later, when we define molecules (such as "H" and "P"), we can inherit -# atom types and bond-rules from this force-field. This will automatically -# assign bonds and angular interactions according to atom (and bond) type. -# (You can also assign charge by atom type. However in this example I assigned -# charge to each atom manually (not by type). The OPLSAA examples in the -# "all_atoms" directory demonstrate how to assign charge by atom type.) - - - -2beadFF { - - # There are 3 atom types: - - write_once("Data Masses") { - @atom:CA 13.0 - @atom:HR 50.0 - @atom:PR 50.0 - } - - # 2-body (non-bonded) interactions: - # - # Uij(r) = 4*eps_ij * ( (sig_ij/r)^12 - (sig_ij/r)^6 ) - # - # Hydrophobic side-chain (R) atoms are attractive (large epsilon parameter). - # Polar side-chains and backbone atoms are not attractive (small epsilon). - # - # i j pairstylename eps sig - # - write_once("In Settings") { - pair_coeff @atom:CA @atom:CA lj/cut 0.10 2.0 - pair_coeff @atom:HR @atom:HR lj/cut 2.50 3.6 - pair_coeff @atom:PR @atom:PR lj/cut 0.10 3.6 - } - - # (By default, interactions between different AtomTypes use "arithmetic"rules: - # eps_ij=sqrt(eps_ii*eps_ij) and sig_ij=0.5*(sig_ii+sig_jj) - # Look for the line containing "pair_modify mix arithmetic" below...) - - # Optional: Assign bond types @bond:Backbone or @bond:Sidechain - # according to atom type. (This can be overridden.) - - write_once("Data Bonds By Type") { - @bond:Backbone @atom:CA @atom:CA - @bond:Sidechain @atom:CA @atom:HR - @bond:Sidechain @atom:CA @atom:PR - } - - # 2-body (bonded) interactions: - # - # Ubond(r) = (k/2)*(r-0)^2 - # - # The corresponding command is: - # - # bond_coeff bondType bondstylename k r0 - # - - write_once("In Settings") { - bond_coeff @bond:Sidechain harmonic 30.0 3.4 - bond_coeff @bond:Backbone harmonic 30.0 3.7 - } - - - # Rules for determining 3 and 4-body bonded interactions by type - - # angle-type atomType1 atomType2 atomType3 - - write_once("Data Angles By Type") { - @angle:Backbone @atom:CA @atom:CA @atom:CA - @angle:Sidechain @atom:CA @atom:CA @atom:*R # Note: "*R" <--> "HR" or "PR" - } - - # dihedral-type AtomType1 AtomType2 AtomType3 AtomType4 - - write_once("Data Dihedrals By Type") { - @dihedral:CCCC @atom:CA @atom:CA @atom:CA @atom:CA - @dihedral:RCCR @atom:*R @atom:CA @atom:CA @atom:*R #"*R" <--> "HR" or "PR" - } - - # 3-body interactions in this example are listed by atomType and bondType - # The atomIDs involved are determined automatically. The forumula used is: - # - # Uangle(theta) = (k/2)*(theta-theta0)^2 - # (k in kcal/mol/rad^2, theta0 in degrees) - # - # The corresponding command is: - # - # angle_coeff angleType anglestylename k theta0 - - write_once("In Settings") { - angle_coeff @angle:Backbone harmonic 30.00 114 - angle_coeff @angle:Sidechain harmonic 30.00 123 - } - - - # 4-body interactions in this example are listed by atomType and bondType - # The atomIDs involved are determined automatically. The forumula used is: - # - # Udihedral(phi) = K * (1 + cos(n*phi - d)) - # - # The d parameter is in degrees, K is in kcal/mol/rad^2. - # - # The corresponding command is - # dihedral_coeff dihedralType dihedralstylename K n d w (ignore "w") - - write_once("In Settings") { - dihedral_coeff @dihedral:CCCC charmm -0.5 1 -180 0.0 - dihedral_coeff @dihedral:RCCR charmm -1.5 1 -180 0.0 - } # write_once("In Settings") - - - # LAMMPS supports a large number of force-field styles. We must select - # which ones we need. This information belongs in the "In Init" section. - # (Hybrid styles used for portability. These choices can be overridden later.) - - write_once("In Init") { - # -- Default styles for "2bead" -- - # (Hybrid force fields were not necessary but are used for portability.) - units real - atom_style full - bond_style hybrid harmonic - angle_style hybrid harmonic - dihedral_style hybrid charmm - pair_style hybrid lj/cut 11.0 - - # If charges are needed, (assuming biopolymers), try one of: - #dielectric 80.0 - #pair_style hybrid lj/cut/coul/debye 0.1 11.0 - # or (for short distances, below a couple nm) - #pair_style hybrid lj/charmm/coul/charmm/implicit 9.0 11.0 - - pair_modify mix arithmetic - special_bonds lj 0.0 0.0 0.0 - } - - -} # 2beadFF - diff --git a/tools/moltemplate/examples/coarse_grained_examples/abstract_2bead_heteropolymer/moltemplate_files/monomers.lt b/tools/moltemplate/examples/coarse_grained_examples/abstract_2bead_heteropolymer/moltemplate_files/monomers.lt deleted file mode 100644 index 98aece5b8f..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/abstract_2bead_heteropolymer/moltemplate_files/monomers.lt +++ /dev/null @@ -1,86 +0,0 @@ -# In this example, we define two types of molecules: "H" and "P", -# both containing two atoms, whose ids (names) are "ca" and "r", -# and whose atom-types vary. -# -# "H" molecules: "P" molecules: -# -# @HR @PR -# | | -# @CA @CA -# -# Eventually, we will connect multiple "H" and "P" molecules -# together to form a polymer, as shown below: -# -# @HR @HR -# | | -# _@CA_ _@CA_ -# ... -.@CA-' `-@CA-' ` ... -# | | -# @PR @PR -# -# The "H" and "P" molecules both share the same type of -# backbone atom ("CA"), but have their own custom "r" -# sidechain atoms with different properties: -# The "HR" atoms belonging to "H" molecules are attracted to each other. -# The "PR" atoms in "P" molecules are not. - - - - - -import "forcefield.lt" # defines "2beadFF" - - - - - -# Define the "H" monomer type ("H" <--> "hydrophobic") - -H inherits 2beadFF { - # atom-id(name) mol-id atom-type charge x y z - write("Data Atoms") { - $atom:ca $mol:... @atom:CA 0.0 0.000 1.0000 0.0000000 - $atom:r $mol:... @atom:HR 0.0 0.000 4.4000 0.0000000 - } - - write("Data Bond List") { - $bond:cr $atom:ca $atom:r - } - - # This will look up the bond-parameters according to atom type. - # Use "Data Bonds" instead if you prefer to assign the bond type manually: - # write("Data Bonds") { - # $bond:cr @bond:Sidechain $atom:ca $atom:r - # } - -} - - - -# Define the "P" monomer type ("P" <--> "polar") - -P inherits 2beadFF { - - # atom-id(name) mol-id atom-type charge x y z - write("Data Atoms") { - $atom:ca $mol:... @atom:CA 0.0 0.000 1.0000 0.0000000 - $atom:r $mol:... @atom:PR 0.0 0.000 4.4000 0.0000000 - } - - write("Data Bond List") { - $bond:CR $atom:ca $atom:r - } - - # This will look up the bond-parameters according to atom type. - # Use "Data Bonds" instead if you prefer to assign the bond type manually: - # write("Data Bonds") { - # $bond:cr @bond:Sidechain $atom:ca $atom:r - # } - -} - - - -# Note: The "..." in "$mol:..." tells moltemplate that this molecule may -# be a part of a larger molecule, and (if so) to use the larger -# molecule's id number as it's own. diff --git a/tools/moltemplate/examples/coarse_grained_examples/abstract_2bead_heteropolymer/moltemplate_files/polymer.lt b/tools/moltemplate/examples/coarse_grained_examples/abstract_2bead_heteropolymer/moltemplate_files/polymer.lt deleted file mode 100644 index 5be93322d8..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/abstract_2bead_heteropolymer/moltemplate_files/polymer.lt +++ /dev/null @@ -1,64 +0,0 @@ - -import "monomers.lt" # This defines the monomer types named "H" and "P" - - - -Polymer { - - create_var {$mol} # optional:force all monomers to share the same molecule-ID - # (The "Data Atoms" in H and P must use "$mol:..." notation.) - - # This causes mon1,mon2,mon3,...,mon14 to share the same molecule counter - # because in the 2bead.lt file, the "..." in "$mol:..." preferentially looks - # for a counter of that type in a parent molecule or earlier ancestor. - - - # A polymer of alternating "H" and "P" monomers: - - mon1 = new P - mon2 = new P.rot(180.0, 1,0,0).move(3.2,0,0) - mon3 = new H.rot( 0.0, 1,0,0).move(6.4,0,0) - mon4 = new H.rot(180.0, 1,0,0).move(9.6,0,0) - mon5 = new H.rot( 0.0, 1,0,0).move(12.8,0,0) - mon6 = new H.rot(180.0, 1,0,0).move(16.0,0,0) - mon7 = new P.rot( 0.0, 1,0,0).move(19.2,0,0) - mon8 = new P.rot(180.0, 1,0,0).move(22.4,0,0) - mon9 = new P.rot( 0.0, 1,0,0).move(25.6,0,0) - mon10 = new H.rot(180.0, 1,0,0).move(28.8,0,0) - mon11 = new H.rot( 0.0, 1,0,0).move(32.0,0,0) - mon12 = new H.rot(180.0, 1,0,0).move(35.2,0,0) - mon13 = new P.rot( 0.0, 1,0,0).move(38.4,0,0) - mon14 = new P.rot(180.0, 1,0,0).move(41.6,0,0) - - - # Now, link the monomers together this way: - write("Data Bond List") { - $bond:backbone1 $atom:mon1/ca $atom:mon2/ca - $bond:backbone2 $atom:mon2/ca $atom:mon3/ca - $bond:backbone3 $atom:mon3/ca $atom:mon4/ca - $bond:backbone4 $atom:mon4/ca $atom:mon5/ca - $bond:backbone5 $atom:mon5/ca $atom:mon6/ca - $bond:backbone6 $atom:mon6/ca $atom:mon7/ca - $bond:backbone7 $atom:mon7/ca $atom:mon8/ca - $bond:backbone8 $atom:mon8/ca $atom:mon9/ca - $bond:backbone9 $atom:mon9/ca $atom:mon10/ca - $bond:backbone10 $atom:mon10/ca $atom:mon11/ca - $bond:backbone11 $atom:mon11/ca $atom:mon12/ca - $bond:backbone12 $atom:mon12/ca $atom:mon13/ca - $bond:backbone13 $atom:mon13/ca $atom:mon14/ca - } - - - # Use "Data Bonds" instead if you prefer to assign the bond types manually: - # write("Data Bonds") { - # $bond:backbone1 @bond:Backbone $atom:mon1/ca $atom:mon2/ca - # $bond:backbone2 @bond:Backbone $atom:mon2/ca $atom:mon3/ca - # : : : : - # } - -} # Polymer - - - -# Angle, dihedral and improper interactions between monomers will be generated -# automatically according to the instructions in the "force_field.lt" file. diff --git a/tools/moltemplate/examples/coarse_grained_examples/abstract_2bead_heteropolymer/moltemplate_files/system.lt b/tools/moltemplate/examples/coarse_grained_examples/abstract_2bead_heteropolymer/moltemplate_files/system.lt deleted file mode 100644 index e3d8317aa0..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/abstract_2bead_heteropolymer/moltemplate_files/system.lt +++ /dev/null @@ -1,36 +0,0 @@ -import "polymer.lt" - - -# Specify the periodic boundary conditions: -write_once("Data Boundary") { - 0 180.0 xlo xhi - 0 180.0 ylo yhi - 0 180.0 zlo zhi -} - - -# Create 27 polymers (=3x3x3) in a rectangular grid - -polymers = new Polymer [3].move(60.0, 0, 0) - [3].move(0, 60.0, 0) - [3].move(0, 0, 60.0) - - - - - - - - -# ----- everything below is optional: ----- -# Shift some of the polymers in the Z direction by a distance of 20.0 - -polymers[1][*][*].move(0,0,20) - -# We applied this move command to all the -# polymers in the middle slab (with constant X). -# More examples of applying the "move" command: - -polymers[*][1][*].move(20,0,0) -polymers[*][*][1].move(0,20,0) - diff --git a/tools/moltemplate/examples/coarse_grained_examples/abstract_2bead_heteropolymer/run.in.nvt b/tools/moltemplate/examples/coarse_grained_examples/abstract_2bead_heteropolymer/run.in.nvt deleted file mode 100644 index 35488d6590..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/abstract_2bead_heteropolymer/run.in.nvt +++ /dev/null @@ -1,32 +0,0 @@ -# -- Init Section -- - -include system.in.init - -# -- Atom Definition Section -- - -read_data system.data - -# -- Settings Section -- - -include system.in.settings - -# -- Run Section -- - - -timestep 2.0 -dump 1 all custom 2500 traj_nvt.lammpstrj id mol type x y z ix iy iz - -# To use Langevin dynamics in LAMMPS you need both "fix langevin" and "fix nve". -# (See http://lammps.sandia.gov/doc/fix_langevin.html for details.) - -fix fxlan all langevin 300.0 300.0 5000.0 48279 -fix fxnve all nve - - -thermo_style custom step temp pe etotal press vol epair ebond eangle edihed -thermo 2500 # time interval for printing out "thermo" data - -run 20000000 - -write_data system_after_nvt.data - diff --git a/tools/moltemplate/examples/coarse_grained_examples/abstract_random_heteropolymer/README.TXT b/tools/moltemplate/examples/coarse_grained_examples/abstract_random_heteropolymer/README.TXT deleted file mode 100644 index 15638c1536..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/abstract_random_heteropolymer/README.TXT +++ /dev/null @@ -1,19 +0,0 @@ -This is an example of how to build a polymer out of randomly-chosen monomers. -In this case, monomers will be chosen at random from two types -(denoted "2bead" and "3bead", although you can have as many types as you like). -You can also constrain the end-caps to be a particular type (eg "3bead"). - -The properties of the bonds connecting monomers (ie length, rigidity) will -be automatically determined, depending on the type of monomers at that location -in the polymer. The same is true for the 3-body angle, and 4-body dihedral -interactions. - - -Instructions on how to build LAMMPS input files and -run a short simulation are provided in other README files. - -step 1) -README_setup.sh - -step2) -README_run.sh diff --git a/tools/moltemplate/examples/coarse_grained_examples/abstract_random_heteropolymer/README_run.sh b/tools/moltemplate/examples/coarse_grained_examples/abstract_random_heteropolymer/README_run.sh deleted file mode 100755 index 9343d763f7..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/abstract_random_heteropolymer/README_run.sh +++ /dev/null @@ -1,14 +0,0 @@ -# --- Running LAMMPS --- -# -- Prerequisites: -- -# The "run.in.nvt" file is a LAMMPS input script containing -# references to the input scripts and data files -# you hopefully have created earlier with moltemplate.sh: -# system.in.init, system.in.settings, system.data -# If not, carry out the instructions in "README_setup.sh". -# -# -- Instructions: -- -# If "lmp_mpi" is the name of the command you use to invoke lammps, -# then you would run lammps on these files this way: - - -lmp_mpi -i run.in.nvt diff --git a/tools/moltemplate/examples/coarse_grained_examples/abstract_random_heteropolymer/README_setup.sh b/tools/moltemplate/examples/coarse_grained_examples/abstract_random_heteropolymer/README_setup.sh deleted file mode 100755 index acc5fbbaad..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/abstract_random_heteropolymer/README_setup.sh +++ /dev/null @@ -1,23 +0,0 @@ -# Use these commands to generate the LAMMPS input script and data file -# (and other auxilliary files): - - -# Create LAMMPS input files this way: -cd moltemplate_files - - # run moltemplate - - moltemplate.sh system.lt - - # This will generate various files with names ending in *.in* and *.data. - # These files are the input files directly read by LAMMPS. Move them to - # the parent directory (or wherever you plan to run the simulation). - - mv -f system.in* system.data ../ - - # Optional: - # The "./output_ttree/" directory is full of temporary files generated by - # moltemplate. They can be useful for debugging, but are usually thrown away. - rm -rf output_ttree/ - -cd ../ diff --git a/tools/moltemplate/examples/coarse_grained_examples/abstract_random_heteropolymer/README_visualize.txt b/tools/moltemplate/examples/coarse_grained_examples/abstract_random_heteropolymer/README_visualize.txt deleted file mode 100644 index 019afc1444..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/abstract_random_heteropolymer/README_visualize.txt +++ /dev/null @@ -1,87 +0,0 @@ - - ------- To view a lammps trajectory in VMD -------- - - -1) Build a PSF file for use in viewing with VMD. - -This step works with VMD 1.9 and topotools 1.2. -(Older versions, like VMD 1.8.6, don't support this.) - - -a) Start VMD -b) Menu Extensions->Tk Console -c) Enter: - -(I assume that the the DATA file is called "system.data") - - topo readlammpsdata system.data full - animate write psf system.psf - -2) - -Later, to Load a trajectory in VMD: - - Start VMD - Select menu: File->New Molecule - -Browse to select the PSF file you created above, and load it. - (Don't close the window yet.) - -Browse to select the trajectory file. - If necessary, for "file type" select: "LAMMPS Trajectory" - Load it. - - ---- A note on trajectory format: ----- -If the trajectory is a DUMP file, then make sure the it contains the -information you need for pbctools (see below. I've been using this -command in my LAMMPS scripts to create the trajectories: - - dump 1 all custom 5000 DUMP_FILE.lammpstrj id mol type x y z ix iy iz - -It's a good idea to use an atom_style which supports molecule-ID numbers -so that you can assign a molecule-ID number to each atom. (I think this -is needed to wrap atom coordinates without breaking molecules in half.) - -Of course, you don't have to save your trajectories in DUMP format, -(other formats like DCD work fine) I just mention dump files -because these are the files I'm familiar with. - -3) ----- Wrap the coordinates to the unit cell - (without cutting the molecules in half) - -a) Start VMD -b) Load the trajectory in VMD (see above) -c) Menu Extensions->Tk Console -d) Try entering these commands: - - pbc wrap -compound res -all - pbc box - - ----- Optional ---- - Sometimes the solvent or membrane obscures the view of the solute. - It can help to shift the location of the periodic boundary box - To shift the box in the y direction (for example) do this: - - pbc wrap -compound res -all -shiftcenterrel {0.0 0.15 0.0} - pbc box -shiftcenterrel {0.0 0.15 0.0} - - Distances are measured in units of box-length fractions, not Angstroms. - - Alternately if you have a solute whose atoms are all of type 1, - then you can also try this to center the box around it: - - pbc wrap -sel type=1 -all -centersel type=2 -center com - -4) - You should check if your periodic boundary conditions are too small. - To do that: - select Graphics->Representations menu option - click on the "Periodic" tab, and - click on the "+x", "-x", "+y", "-y", "+z", "-z" checkboxes. - -5) Optional: If you like, change the atom types in the PSF file so - that VMD recognizes the atom types, use something like: - -sed -e 's/ 1 1 / C C /g' < system.psf > temp1.psf -sed -e 's/ 2 2 / H H /g' < temp1.psf > temp2.psf -sed -e 's/ 3 3 / P P /g' < temp2.psf > system.psf - -(If you do this, it might effect step 2 above.) diff --git a/tools/moltemplate/examples/coarse_grained_examples/abstract_random_heteropolymer/images/2bead.jpg b/tools/moltemplate/examples/coarse_grained_examples/abstract_random_heteropolymer/images/2bead.jpg deleted file mode 100644 index f67da797f1f677383bad0885cc112812ddcbc182..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2713 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 dM<%L=h8dtBsdy*s@{RdOZtXu#9 diff --git a/tools/moltemplate/examples/coarse_grained_examples/abstract_random_heteropolymer/images/3bead.jpg b/tools/moltemplate/examples/coarse_grained_examples/abstract_random_heteropolymer/images/3bead.jpg deleted file mode 100644 index 15d7b296766de835005aa76d132274cb812628d3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4410 zcmb7{c|6qrx5qzYEMrM_$r2e2V<}R$Y*S=rFpM=zeWkL?V60JzEJ?_av6N*nw!(~I zB$Swvr_gUsw0>yN`SSy|4G<@qV21exLI^=l#d~k8?PFI0x{djFH9w2m}I5 zjuvn@1zZNeEPwTP2Oo)*o%OFE?CfmpoDeQ9P6#I_7te7XE^c0KPR?We$9RwP@$vI< z@dyYC@ChE-e19RJznNfG$WbC6Hz)Ve>HkxQ%>X|HFbDF$pwj>gKM2eZI&1|b01yB^ z>h`GL{}Bg-lbwwf%yo3D!v}y^*uX4cb}$>~e@B2=zyK>7J3ohj3`AA%v>~UEu$rZd z2qHxmYK_Yiy^OWG`7rf))zDw`5gA|s|1TH-*g3##EUb{fg;n^0zfU@%v;C(w=qQ+# zjh|gWM%7U8v?VT2&1IeAValhULi2}{0M8MKg&)ih=mW#zNsK%PA%!X8*HTq;(h%{i z=|{bC8Om|1ZRP`jnF=u5#73m(cNN=TZNrfE7q^9}3Y;ZxC!KP##O7V#Y)XZD$JHAB z^(;I8AhtI=zYVvm>&56NC|8PSmdR0Z=PhwENW^cZ`osx<5m4IMZ54NB1`m~iFkj?& zt{j-M4i4)0YNw2iOLb@EZ!IVr2;(beavyB%$Tt0WPax8%Qs1&2w-q&Cs>$N@`*?zptC*lgIu%SDCpC#%WoB7#6IfP!^t;{z%Jf6D>dU>Nb{V6 z>t*f2LeJYq4Jxa}w9E7aoB7(9Q$abCYOf(>X=P$MLda&QU>_{5>%gF_mN?s1^4uKN zi>7BR%x3u2GR&b-ggj&m>LC!N#cCWA*j098N-AZr5;>M>bJLfTUOchf8Qa|*6iL213{!De=fzadI{P5;yHgZG3y$mREj zCI~(m8Hho2v&@grgvO;vV=_spB!UVdE>G6!Gu{x~X`D|V%nI^IWZf&dVoqPY0sS+3zH!55G(X0;9w|k5Ztdr>=P3>NdgP50pf0?)eh{n)CM%LYUH2^m z&x>Nx;Kwjlp2s*yvv)PI;e3WnK0`JbE1x0oNGRO;b+=p(X7Z%>S&y~Ej*h{gnqGT{ zOof})MP0PY`V{#zg)2qZBSO$BP#_Y|O1TQ|BM3(O&yy}hpgprLI~}YBgE~rdtHYl~ z=GK`^zPx(*0;nEqG>`i1)H3jJ3|#f2g9XB5w~EgKr?s%BpDH7>Gs9+wEJ!_Pj*MvaO2DKMUtrHW5w#5eZ>rwVbV;f5egUo z*0dJ&tPgRW6Sj}Et8~pFji9;Eakh}fM*?Ldia9!uI{eE;;I*|mF|ltPHfn__7F_u{4^gLzfVzCpa?1^btLh0v#^SX81iH?an212PVit9yQI3YQ-Uuk4Hzn$M#(!kF$Q>1`R~TU^IfJg zOv|Htp=heIMJc@#K5a`t zE?SJ2PEk8v_SbzcPl`>5K-8#wG&F#g@M8Ggf1ErK&P-CT0rpWDU!6A4)W>e5GUL3=Rx|4p|MnvKMy7kD1-E;MFyZKeI=p{7RJY_y0of z8FE~2kpp$GSl2x8ODiNO*h|Ynb6IhDHM&C@?u&|Y?|-*9uPr7j)AwEF_Idgb67O$C zhwCjV?w`N0&i5o&a{28+`W`%EY{z6fCz3`U`hukm3);bkAN3vmEK_S6`)kfXm}Ek}Yb7bz-0!$HzOiH27@a1vq7)Z`FJy#kE6}6}qI0xY`uXC8V_Ekd5r-BwLe=jz@-0i}! z&+Z{m9!llfV8N_$tcd0|t%lNxj*mx|*^Pd6>WG(Ehz!Ppfr{g0mlkshB>Y^-L;bEZ znHX~ZecKCBW&YiA()-#3jL@(`s1|pqxi%GcVqT^u`QE3}Cz$%m1z)-0rvV||eGOd9 z9mPHr!+2;tc8$iQ4V@^2i7H{NB z`$me&%Ru9)q2VPnS+sJ|+9lamQiF6XF~S{?8$&-t;eW{M!Mn4ex5_THof&(1Cnjt* z$aiJweR=&ZhOgnbZT`Pfw>c5QIA?oqE&CKStC$^vGkKlgp7M;XN|27`Ec%R|Zfx~${w#gjsqblj#{KwK;%*gqIk+i4? z*9!u{az9A{Ic=+JA=ol+1e3n<46j&8Q)-E5NXI5mJ&0Vx6jQ`885~@Jn(spOH3GJp zg^2?Jk*6Zsv{w>7GoDyt(+j$wxk%Wk+=_dQkBk=oz;IaKPm6=9Zda+qp2)C6Ku+3o zc9{FXI_va{)=v|ecRO{OQmv_mV-CdJ8K%H$eIs&Ui@!B6(rr+o!Duk+ZSG#fQMq8lEgqRnj1n z&bn;SFFrf_c-0MD^mYB~&NREZ8c#uxS7r9nt%9^H7Nh#*1OY60N8lWDCJ!6X=xrHY z?IF91ug0zGg=OHlC1iX(Eg88WQ~kjM%Cp$Vj*AMF)!F*fQ)llwT=jUP)C@cCK~XSj zKBrfe|E~9Q+RDYf4y?m7Gk;tE0%(!XHO|MsDl*;tC33LV8gk~c-LrQmG;2C>n$P!w ze|fooPOuT9e_wty8H-bccuW>PHyc_QsS~Oj&YO*8*SlT!HrNFDBv?Evf}EBcjCar> z%x@RChHyd<8r&wy(b5P6-@_w^RldQI?mc+@l|p=4Q^h)*hqcI-DoZ6MmLh7X$9=R6 zyShb$o~df~K{_Ms-iVTjQvn{GuX}AKYm0{DTcnR2KDL5!Sis3_KpB`WP%R=GIm2M!&0XVpTZ z^W$(;-!Se^YzEqwXu9=MPx@^}$7l6+#Z$f&iMKqw8$;#>OV-D=*Z7yZK$Ux+6}f(R zyB*&XABv6Q7?hnPe12N0ceZ#`J*kF{jCY?`p|>u%sd)LFZ+0f+6s~TA%G8y${h49$ zXElp+iCH&qv^!A3TUn2O=^=T)gzR4qct zP|Xt)TkfP>KMh5Qxj;?_aO-P)xIR>>Q9C(^p409yQegVA;-AEjewS$I&*cnBy_c~2 zmy7v>Kc)Y?>gy4HuQfNEv8gzC2o(RSGW75WH~xar{rT^L4CHcH`2U?T_@W{I<0d>> zJGK;6P#$zEw`g35cIO9LmlT6O-@UBfuQu(X&~Cddy67X#{EnAaK$|OX$x3{>7<6KG zp!|Gu_lsUEFITgtWP8jjIn-p~y5ZcTt=7ObJ1dGy|3LfGZJE`j!GqhmS#Qe~hR1^g zyVEwmcca;c7H2LI^p&`R>I!B?JE3G0)=8D9Jyl3M1TfTu9DyIDmc?TzM^0R~S6{i3 zHZ3&@{Ip;{h8cFt_0l|7lWF7Y={`i}^j7%f#@Byhw)^a!Q&JbVlTcNDAKz~Jt8X=` zUQqjT&E>I$Eu&I?ULJK7ZV3fApf6JBkxTb&!m@DvEn~-MsPv3ul`h@SH$fhV*T8hN(HESIKG*`i@$`)+v65d>{s+g2_Ldr!tqD zbE;rlMWX(f8FPxBZS*vvyI(6?5Ih@ zHY?#E8)DJZOWQq7)?Wf(utDZtt&{E6UtDpJJCQ3YJWE6hn;au+tk|+}$4HB~)8)>T zLsRo$osYYdm(BI*Lf#$oD-105!>^ zpH+1W2@B`IvruL;n)pigs8;JefZAZ?X1YZzEK&}j#zxL)UvX7nOuYd@Y4M%F|K!%P zM>U`C0Tq$owOz;dQ=j-6=EvVNkyXFqn>dzaX8B8X-AZo4kUa&|@@DRT_NJQz5LlbW z1xgN6F8%`4S#p0j+-}F7Np;eqZ8Kmbwr1dd%r6)ZdY?F5sgDD24;NX}_9-OOcbNc8 zwB4ERhjs41A^_?E?~qV~FPDZafFihZl~;E2j45uuONDNv<{da zp>Eyc&P@G_f!9+@WP__HT%NX;8&j9qhfBXA*WBf(^Gj0Ls|19H3KJhrrijJ?+Kl@w z^Kl!ZmoES{EyD)$WBG|Y_#zJy02@^2Yf?*!hJFw5kh8)^8R*YhJ?RI4NcgCP_?B*E zBXb+>D*GeK5H&J19rU`J#?PseJKPF{I&o;rzWsT8UA@ zyxJqAVH~4}egwjMuervf33xu6jJ!lHQI|Jc?dv@HoFf<&KM=<(FSI>O7-VeXQ1*yF0Fal%g0_Aqu{Ho+qA>yNsx63~1+ba%Q~NUh$`dU$ zJgJUEDUN|(lXNYimzcIGXl0OmMqm_(ii=Q;Lv0MX#F zSn<1jiXNeV^j{;_HE9v+nYK7XRz)rUW&S7|g? zKEwbqCt4Rq(Mh3s_G0Zo>E%w?Rr_|H=yHRL;ENYV4~xv04)xw|w-#@Io-CyD%1@;% zH7pfr%-4n={CzCKN$ir(LRZX}PWFWaeFpwKsuiq!Zmlgf8%Y3SkKn?3NCog7TCl&t zsBiTU?3J{&=$y7dhh()4F%$B8jwdzOd)DU2QWoqRz}8^hM2DLA7w=Cd(J_qKA@62C zvDqHW8k{Z+?p7b=*lv!%k$c%3ichr2)zz*z#4L%_Ek#=+G%s@;^=z@>ub=b+)=Lq- zFi>_wYG)K(_YiYl0iBO87s-2O1f+)THe7-o0--^>;>npN!w`-V&RZd@PSzI$Bf`~< z;oU72-M;>PqhBle#xRmiG>a=xDdY17oSVBo7VbQ$a3}f^~I5kV0OL7anyJwpxj*=uOs-5P$;Np%C_Q#yWj4)(Daxqww)T3JE?>L!D75D)VU~cztElJahe z4PPaO&UrOxK%&1nD*X%7TBT992PfW*4N`5v={kBzD+@ZE*9K3 z$~V1iOgyHEVk*)0ljT#azEV36J0C?;zV{m%6)ddOwRlA4&50f^EsM!6kF04jE3q>T z%()w6the8b4`n4Mrw8u|zGxL&`zBvpZJMl@@eZ>bT}@9j&<#gss+^!qyN)c+WVY#9 zlLcQ8T~1x)%5)R6#6Arf+jwxDqPcHmGxn@2xRqzi59|2$J(SJyfwf&j@p@3a!0IVs}wtYbD9AE~&Gn$`s1PBBirVA`HhU$F6HZI19&Um>JDS>mAt)gX88c{^aq5}m-_ny7fKJ79YQ?2IMPZ31FVP9D zcDF4bh~A-J{x0}o#JYQ$xmD^Jv+hO}RbkIX&}WTvExUofTu5xLa9^q^Kh*0xdeJD+ zUdh=we59Lo&(*T@n$@HGTOp=RdVA<1>@B9ikS-z zEcsbPGM#|MmPHX*GXTMJc+W~TVN@=8|1_My5XWDab-Nhf)uzGWmoPcT9~t2+rf`H0%l;GnYDIzDw_^N7_mt*?^uOm zV}n&eH$c1lHnH23=GwhkL&hE;R2O4sTH}4?SSy5y-3O0sIz_$#Q=GO)qyQZ`czY0h zr|azj{jidM{uVE_aJ5<$?Fd76HK4H-qtv9(g9hEQ`lgO!U`gP&{JXiCuPje&4Ej|x zwIUB#OQ1;s7@WqJc4&+w{C)ZQg7*xtNoXGyX!0&HoSBRRpz3C6boDDfzdymRKiqd{ zkJd%S&(a+qkI(7{kHAhD0kGbr#ri7pd48dhO9J-+2sWu&Hqks&!-c@7^Hh#Ia;}qI zsk6D?fJq6cj8@Oe>ERkK6S92vP=A|lr&i<+215)0&}*yNuX9dcw-^9Hp|Z^FYewJ2 zF@WW4qT%Z^F+mN$d(5RJ8yVD<*apCc5;yBy*_}*@e!ZCA6^8lvnO~uT7mq3n7}0ua zlKos&^2i7}u+s(zPRG#W%KtcD?E`GB16TTjEjb>*`qdqUc`d!IeeCcf9&5jYCQQ=) zDYw&OXmBqZiq&u6o4V$g8eTl6av~I)q?4O-I3by>S%JUq0K9_%2poH(2DK}LANyvj zxJYFy0aP0ca%qj*7SC&#w8LX%r6+#J#X0mXYKyi)Ky>h;Yc3-+Xc>T`HN4f0&9xkT z1uZPaz#6B_#zsyP%a&&}lmhqngTEOvLm8V>uTff!*t!95>DE<-ug4n?fipHC$C0Cta_{rFL8&uF`5I(NoUtfHf+(qAI{<8 z&z8kcF90fpSef)*sMeIoC>s3b{@crfp^MGS9S}57ZDGKJ^#CwGyg$hkVM;Snp zJ{XR0&kM}S0UJyLBAz#iPTC7=1{~^3p8!H^w(Psyx(S^TyOIj#XO_|3C~JN@9Sv!K zu(@wG*2<%@M)M6Ygi%j3<-{mn%eO#tBZ@R%9Okj_eVR}lcTMXm+S^+o$pz-Zr1k=SrP zJJNCW`7;72p49@pp2qIm0Mej~OXBO_1*wer7*HpS9-dfu1D(GD0Fzi&zCV{DVXuL6 z6O997u_~`UVZCQ{Yyg=m0Kx_iRkJ8uHKToOhFytDl!Ns3ohpdnLWZP^KT{`d00@n}2jS z<-J$kVfcUi%m3X!=8mN8^|lQE{O`$GFe^{iPU4sS)%Jgnbb>F1EmB_Mp{oG+eG}_^ z8s&=5JpiAne~~Ho$`8PH98E^oCi{4%XZrq$A1P107{Nl zEg<1*QHId;|4S%Q>89;I&G)+iu8{t^z>^u&Rm2qXD|@`PbK2Mkz{sm@^R4%T(7K?6 z6Yck6V6V>;0Qf_lfBFwlYyg0H2m3#QgYw_O!@?oJ0EizbuyL_)F!7jKJ_=J(eWK=o zq5{Z32Q<^?ypV(5wjMSXa=F*`>W|l;0(-wK&>p$|iU!^QR=h;2K+68B^ zT`$|(=}SU1;iVBjcvU=W>s6Uo<11^+hkSyM-g78Uax^5ZO6Fc+V*2+6;4N8r?uBOy z=t*m-uXv=p2R&}atg>((o9Ek`?H-wkN!Tt3u!uL$6ubf9205>_h4{x29fbMu{*Qc- z{53Xnd`7Mpi~9N#JMqYgFajzP`4${C8x=2Te$f$=SsB%a;#>-x4PZk%8<7^>iG#wr z8q$LN0(&F5@6&j3u(5CmSM3Y>xrq>TqSC2$@{%_I-wjV!`H6IiqD2|)U){C)VQnqy z`DL^6VtwtyY4egNMS**)gjGQMrw2dOKY5smhcszKcU~CsTY=UqbcpJN5C=T{8mGM0DJ-4o@X!GFgg zcZ@l`yBKt$$ffI%j8-K5-iu9Bv#3>JZ!}3f7s_dE8zOWx(fjAfufHv17SM>xR)eQ_62q?K)j?piAH^{KJ<;wRkR9JIww zrp7mbNjUyn56)NP%fFae6JD0;25G)V{~8&Db;~sNnht*Au9Vx=+ON?ynS1xByA}Wf zQl+QbOSk1Wd(nF#pXP`!bR{ARQt2ZVCl?rC`cl6zoHXGP`X{N0-^@;siNWe>VidSo zhVn*@_y1Hm==fm~Cnsx?b?t5DmJgZmOd~U^uf9HQbBa4%oFK6AMTsz_DvbX0>katy zU?n@Km6BfP>T&v#S>QtVz}lE%LYiFgv>&!%q4o0ub*;dqWYf!UQey=1dUqJlQYKK= zIQk9fyKXO(DP8s_Im_6dF#Dy-^#)8rzIGCUy#zw2A$31BFqGi&KDwnUB=Nt}y%Jnf zOgtlAFZOXB^O*|uBwsBb+HK>?f9yW4n?tn>QMc3Q%+Xdi;hYPz)t7Bw{_F(u%lu)X z{NBg1jmt-TG}A_6GwrOvgZsJc#Pit^YM?YezX61(S>qYW5T|#orMpfIxU%NDh2x<) z4;x4qroI^ESbU^{)M;1CpKP-YWeW+&>^7EykNVYV;;0Ffh_VNe_bwT(m-_Im_&omE z)J&P&yQCs~C_R(kjORTms)L35nJyuCeagiAVw*szpFH03QL%1@Oc>e!i=SJ=yr2_O zPIuL+^xkTEXEml+dO63w01fvXvgdjj+vTR@3uj#LV$|9ja2}oi>Q9z@vQI!ln3gC3 z9X^hUeth)g`^RXuAGXmX)7Z1}MVo|i=Gx=}U3y>dzH(-n-J5J{3F={L7F!jh0uhaA zK5syI%2@R^cjGG(|B@;q$(M>gPLL#e)b4kpTaXU5&O&Ewvx4hct#L z;8%@@H$ac09r2*b@qWt7LAo$mGwdN3+PqXXsjGx5M8VXApuJ&|gH^Y&&{Ek8RC|Rz z$En0a>?_4AD)0OK=O!%~xBfLtUs^$@CKU2IrM*VfSMCrwndGfBp9r5yR=O^TOpv5a z)^1B-^E`8SaWoyUJC`&_dvnyNDRTcRNAL5Ot4zr25*b1YAN*YkEHw+CqC_!*m=zsx~` zS?XJ9PQLBl-`4`-c1r*LF7kiwxV%WW#hr<1 z#mR=qkdWT~(R>Bugu(-}%ye{y?-R*!`-juHpy-qLNG#^HGkgU{_nsk!j+`Tf>hzOL z%;5sA?>*mW$xB8 zJ`jN3Lz1edi=xrH?`7voaX9UeU6AJzb|3auT)I7G3_8m{a$jX@_0!k=;MgC~@Mj$r zdX9^~UIC6WxSt#w50c`to1IO$(`y9cc>SqXxG#3kr%jB@BH?4 zvm(=Y|L%}eeDqUunMv8lgpqZJKCs<8UJW|7e+=V(qz2i#>^io6_&H~9z%c65_m9-{ zam(3vq$2YjghU@CvP-^V6daxTy8Y3(409hZ31H_~_*VzYHbK*}+m)5b)ZJ$1cW&0O zIMd4B%Md&!AB{@E9c^-pwspZ^h)7_Ctj4|p%!f?h?nfs=sL|wFQ(klTu38wc!mtIl zvaVfqkZh(!leDqP-3)K4_8#3sl$A~62hHP4*u!a4^?dV|eENyb4$h7uO^8!C#N$&Q zpUyouk}_g9rw1Ogv({et7YMY(0v;0i(XNxpnf%51S{(+1tYg-o!M#aP686H#Y;~<_c1|_l-63 z?Z0c6rpQos*;mZXdL6dDKSOH+*PLlhJwZ;)W~o_++{W=Eg}WPwDmrn6L6z z2sp;O0_6^4>i3&--rpW6)0TZ&tv@+N_?x8o^?X<76We??*40EO`hYu6d`&AL!BA#B z6tkX;Cps2Nl>Oyk7ZkK-v=i>)mME!KOIlbXl!PHe=#L4n$TNLwgS#RzEK) z?a1tQ$=tLuM!9keUL34s0#U0dfv+l4%ZkTlMty_2~$sU_kNis|D0y-G7`S`ktZDf zGb)JVU$+Dugk|d}?hu0Y)fMh+Hisn`5XcfQ50y3tntNQ3N{u)@I4xkjloBXKJ9|_~ z1uUyY+xCB@{Eq)pEQ7;nR2cU|gt8>x`kRwzZtu2f)LC2$_ys)YtE%JJtY#<|gU;h4 zcFrW@Kk4>6_YDQ(nau5x99|aUd~a8S@Rc8KULSpb1h*C$QJz@O1vV?i*3GG@A=4d+ z#^LT^wI+t7pZk7w&9{EkuQU_A-k^v^bZkxgGbH%~zv4sRHZ=qxtUVk(sDH|w`cIT+ z=3?_OLt8P4<6*%ZzdygVQ$nb;OB3gwn4>^3bVW`4Z}5)9A_yVugl^PCKJb|O&M!2S zD3Y!Zt6#Qn3jB{KM+JY2zthFQ=$-i%_D#vS{;{5%u&s1z^~53lP)o-=3^J{-)c*!# zStO(UT`)3ePD=xMXVhQM7H=~!c1BMY)R$3myt)mT-`M42fAe+^8QR!Y+H`s^59eLD z_XgC+_lFGg-@%|wC5GTS@UWB5C4znO8E4j5=a!aglQI4Ci&zM6!;jq9GWoW# zS$`$T=EOp-GIjPEx%ygnO)jg!Ai5fxgHjoDaJ8D*f!2(wRmIp&Lb&()=fd+&Vfwvv zB8N5=(=hb0RmysnD+q~9Xp!V-&Cur-NysoZw{BYr-HA}(1CO*>jBLYL+s?`G(9)C1 zCf0eQffMtoZlzEjXN;~*vkzq z6y^*#K!NOAYQZ-pKAcv{fn;GeQSuS5elzC3q!H6m3TtbO3&Z1Y4>0X@y==>ZdG+Vy zS@rf05)~jT#h*=X8w9m4+6XZQtqo>aPzeT@((r16I>r)u!9H}KKafmofZvcHlQpOGJb1jYCEz4EW z7*4|TiBPEY?_S?_5Afeo4qu^<8_x@Z-&ylv!KW-vdHr^$!Mk1_WM@HqNuR3S1fvQr z@?VCI4GwLP+vo7_uYO-u4W`P7Q(zC{ut1m5(Ko<9Q(%H}JpPT!)Rze{9ISw>@`A@@c;SkQk?d+NX=_arDRpko+R+UBf2 zp*MK4Z5R9MPfn9A-MN6>MRj|yKcWPlo3bLT!=OVBwirzcn)2Is8}uw5qR1;e4S?EK zuxv^EY-Wpl)A|)tP3W|yJ)kijJ;eNr9pp(>j+x0noo5;kGm%z*wjtcGwdRWuv4dr< z1TL!|e!Ld1>7#%BalM!#{T(cvLcp$@Kj^|JP3*AZ8rim67g^cwB8|Cr<`WUS{*L}5zNudJHN^7e5Qk3EdwS(nO`Zh;iLS%A> z`_>+x6W7?Oy1so{v8e{KxSg~to;s3GB*zzo)+!Ti=QxWxX!E|2d|F}s8L6jWK~w@ zaz2aPH7PYryY>p9)6BA}n(``csVnlK~XJ;KGE07cg*euqN)p1sisBWrc03zJ=97`mRKIDkB-P8I}yvRHq#-Nx^ zD&$_M=3qvPcJ5P3uoYn>_YzpxHR!wFJn}J2^-|YIJq& z`8#eP%&PQ#sIM-H>f0Yud_!m17tox}sqyi`lMjF(M{2_PiqaKc-?x}+hP+>zI{J2| z8U*TBs9@tJ5Q=k=A<=eM4vcG=+we)$BFwF%b9>cRAwNDCp!BEPtqpdDcu&>WxtKk| z#^=rc%Hrbz%~+_#i!6vM_T=W+NUHCh@tKh3brv2w#gr{yA1sL*&K@W<3TbVBk8GfJ+M+J5+gC! zwWPJlwVglTxuIXPdVL%jB7yLOSI={E`Z&@3Pq7Gjv-|XcQ(H>jj&{~;pLr++hDrT@ zC8t_QYS?;238oU9Fv5!&ngl!VYHC$~8L2>he?4>@PKBkmXr2?=$OnBZDke8r4&&p> zl`zF=qWj06>;fOjxL%M;tum#LfE)%leDP-O7~Ffl;24pKEMU)}xzKLQ5R z70Q2hoaZm-o?{D$Cbr}#HyUap3q7fLwN(F0S}nYUO>!4f_g;4v*fY|vS+p{#p8y8G zSBMiWM`jbGXmu{Gz6TL3??128)$E5KqA%vK2B^(+wL!aNWig3(e-sDtsv`s4{U8V@yaO2M8W3P!5sAu2kETqC9 zatSueJ5P#3P#tea+>ddoWSo-Wx6kcs7W`VvJ|sRAg%+QP(nWN&VNh<%jL#3x&Q$(_ zyC3P9`{eIzl5;tiY~#{5*jKgNkifut zj4RmMzMoQXri^Hw)EXYH`$LW7hVF>X$+<~hn$Il<8y~bC-66*2t+o7HrzI__CT6G} z)k-l^2cFmE1-23dsCQdVRh+Iz+)w$Wa_{U~=woBE|ACbMz|0<}*N})yD$U0XaI|in zHRP{LN;BDpUhp%P-VW$QHjrqK)E2w&T)tA))D|c(I_f&z$?*V@F^d<`o-xnZ=hN^c1xliZN{kG<;rGlTvz}Tgh(#{0!N` zXLMq-#I8N~Zz6_$i&$2Ma)~*!XRGS$cX|bVLl`~DjzXdLdU_|Zqm(95u&%-7eTozj zk@edQF$bXdplkv@OHG%27ZRV3pUcTN+`z;i?Kyq^MI><|8e$KHDHDd2R7+fr8P0pE zNQIKAn&QE7uJ~7cFXZMWLth%}L@5x+8zbDai~l)PMse1lQoowvx$#fg3etGlOdqm80v1fn&>_Q&z2#me zlh@La#C`70vnZ}s->hL;oU)Z5087Hk=~wNhlM;A+uYBYF{stbtBIR8?q+g&j`edho0b?3s51CCBSxF{*NYStP;PDLdbo6-@O78bII}<~$Hofi z%m|Fmi*C46I$eUvRUSgpQ6N2yBU>PdN*G*TYXT`1WYFOAaY^FJ`e!#Q+D0)N%BS<3 z4s~%G41(u-6*o|1&$xzkwv4J1)fyIQVxYnOI>}Kz+h(>f(XU*)-_2g$)k8i+G z_N;MDh|GbWPkw|liW5aUA-;;(zRt@!;fOct5MlagtEoyi?L5pEu=YvM~lYM zQBA+-b(nnAXN2-)L;DczCtmMxfe55z+c8XUP>iNA_Fbj{Qbl|~QZClwQ;2;mhx z$bL`D#%Y)#TYz>v4xd0Pau<*E{v20|;91=8i*5n_ggxyV7S}xVRH{gH%0%}c5uq{? ziBqN8xtD7UimTtv4`-sAT}LdZr8AatuWPzPTDD2D6&n(6N8hFQk*VqD4+>yADyDFG zI%n)VU>5$1YoXhYQd>Ob|Khb!Mq}Pjc?1QJIxchC)O9UmoXgzamtYhbFhBWZE1eR8 zyn3tFzvQRHw+RY{k!8Otn@OY53*b^OEzh&>tq?^gC{|7~PrDb*=Ltxo&8gA0zrrX| zJh~YDdHkq%bNdGT8+Mdr?f+itW*%x8{ZROas(k1H+Ju^#TeZi8m~`w*!IC|jizDQI zMN=P%!EahsoJI1|q^uIP_+X7@?X3x$h=PHaNCLG7Njm!uWLMnKQHL7nQPmr&Mix274K-9%M13SyT8*6 z9A``JXa_#tc&d55{^H|o_4Pktz0uOki-T1wFC1uNxm1xkP8T6EEpd}i7aVZY@^V=s zevx~9{y6(33GoiMyg?h!9J@5(fPN)jx8VLuvu$+rZ2kcxiZW06p%~i_^ZF?mL;1V- zPCq>H&GjMr&>q)!} zZY_|Y$MPTmt39SU5Ts6O93jsSICogv*iB$|>Ip_fUu>W!9&Q(I*~(3>g=+n|=*nmN zuI4eUv;rwE`L@X0AB>6?+(-@!7lPb2DSCNJd&J)&srDCJl7Ki^C7+c{ztx99F>2ru z*DI(bu6W=vBYtD3K#uisa6^LFgn%58ncrw=l#G?1rfS4p=QtYyvLdQg^=yB=yFloW z=p3I-9jNBL`39iA0m#X+Z-CEFU=^`jGWAPOVzD-le8l%6_0z&EQ+-6C|1@Zs)S+OE zR8Z>Nw=TY0e8vagsy@0H-UvbZw2u?Dik3k5g7|*Y$SE%p-8OIth+QK#eI#W{fT^d# z&+kQZtZ83LB*?kd*RGnd#WvO-ODSgpzRFzcWV+eC7S1d|5Hw53cB%b?=bB{ zK*b13Az_Bv&kSAOJ~VSKG#2qIN1BI{&jp;Q|k`^`p<1c{d;{cQ#rZjszn( ztZJSt&p-cG_wT7Hj{}dYmuH%X!jC>qmb?x`c5cHG)c`_d$)EfnwWsp#Fa)tJNT0Q= z<27y8)P^V_6O5=_Y_vvSFZVIJPss}Z*R2~RLQpzoj2dIgTp-;u1)MmvYnJF-o7~8f zW?hb390FJR$}?5hh*tV%MBymxlYHI}bxaYg>(4OAF3c77A6p@i_4TsxVI|qGAI7E>xedLGLth2YYgb^a3O(tVjD~=>7=-X{!Q2WTq z<7{ddVbp;E8WoQ%q&4ghRxAI#?;M8EyR~H>M1RR&q8cO*TWWghu5enM&Xf2ezx`|$ zTpgtr)|E%F%&i9ElJt%N969yNu2?qORUR?aiZ2*`|FjZ{ef6Xv?{zJ962tzzy^$Mx zLCH_&i&(e_e)w|34(5S-m4uw@(G&=z%@epNw6A7M-G;75wCw*G=S}39XY3C+8^L@* zQah9&mBrvATd|wWt;m}PmBM6{wTb3wHv4yTse~1cm(Nr!G>3OjIlj4)WORxq%}uoRqi^3nw(4Yd zh4wt8&AoBY?q^HnkST*xpQ^-l#aq0)glHNgayFbjh4el>5rT_g*LFOUxIX!?HI3w}A2>!wLG~+)EgMH(DfH zf;ObvM-IIU)cT1fz23-1AyKIz9Qm9Az1Y9 z{DHlTor&N-l9M`Yk!dwgf~)j;6LkB(e}BdC0r|DeR>V|>v5ndUdJ%=jn5bw!OpWA- ziH@;KzRsd~(@ESj_Q#c7H^{^iY!_$#_3*Ok{UxKjHjoy5P(N+g_ctpzuH}0`XXn!7 zzQ_ANhkdDNK1PVmOwu$oLIfXO&rq%7N=k$Y`f0n+_Z(z$2GV==$T?6J$YWZf`qFEr zs*E20nyWeq;_b&6o*bx-h&FExwNIIoI=un41^gXjbFNDcU~jGdb78y)(g4$SkfQs? z;V2Cyn~W~A3``y#K9U{^28X!62eaAk4K>jl&HCxq7I&2966dleIhHohCmE&nsXs%c zzvtdaY;h6G$n?eJ9Jp`(C)>CL7f$sKbUfL;*_^-_o5?ElbBROCjtdhtCaXxm;3|Zz zKB4&yK;k?9OJZhFY(2O~apEss$97Zc=+921$(~+4k+S!oKLo0tCZZ-eMnnW5rE-s_ z?}zuP9r}N{h(MEA z&yeAsRDjx5K$NVQcbUu6j&VJISW(Z;A~BVpcbE|6p`LtRIhk8K%Z99B19l(FIA1`< zUO%KZaDh%UTh?8E_9DBw(r)ndru+5brTa5osbfrhRV$gQ^UiO0&BpQ3EPRr8eY{_U zofCu0_e`lcg{5s<(bbL&`*iAS<>N&1biT_ELG?EzTnAn75{Q6$Pz>T5^5?vxvYOK{ z-dWgrrqc&WSLw@l$-@^Qno7uY(N>$Ht33ryB%K_L^Y6S4J?Xvy>Wd1f{gbkm8UwM*l{IN9!vySk+1}154CpmB#FVZg>zZ;j{iEB8ftL!n^62kWNSp*OLBkabEhh1mW8=64pS1YqnX$KBGu)>rWQJUBz#2|<^;DL9DjE9D z?$>)EJH(Xo$Td+1Q`JqdB8e3r^(cw0rHQ(Nt$Pdz(U+!Hi4(6hNlMJ}RSIm(y~SbV zojhplzz9*ep|7XK`pJ&&Hv>E5(qp`@2Yz! z-o1S6*rhuL2uVEA>SWw~G6tbQy9ca5(HL7D-^ndklS@~P^qG;Ej+^7Ta1W|@noMN3 zL=;~G$mL{i5)wan6}?MWaH1`jTg zj74|<*D14&mD`kN+a|XWeynqODhh&c$t3Bee~#B_2KJzv?}`h$5Tr?-H=wPq zg8n?6Zf*MnTJ{>4U~Ge}vrmcV>WQ;$^gQiOXzUD%$#Fo>9zh{FC@cpH4?PV9jVXeG z#u)uyOzsoQf0!IIE2Xeg_BrlXBPzDQs@SfL{~>a){~>aZOTDW;a8&3HZc0bS( zZXVrZkTQp7eAC<0tV#;`FanPZ2{+4ZH`Fc(IlL_h^qem0hoFJHnKJ_EEsX5b6Srvv z2lI=4;zc|q;a~K8#L+N=f~prW**4k~Ya8eyIl%T5{^SM)CiZb)0T~Opa`w$!QDR)a zkI{{f)_j`mTXF_E^w4VS$7U&5dp=jt=Zx#K1U))QEZeHO*FQqFI!Qtp@)8>8B8WY= zVkjHhk}O#=g1di&;z7OIOJDJ0Q`&39^tXNdDT!=sRXNYC`cgXTG|>xRNP|*p8-8MZ zOlhx<7Kvl|&bc5$4CXE>%}(?rVDFLYTCl+ySarLtKW(JbV7{fIeRMC!Y^rGNEGc?Q zvukPA(Y%4i@#r-%?HiY#&Rz;`9@oau_7X=RH>EZ&;T#xR^E7Uj+xs}xPbwnNmOFy1 z_@Ybf-T*Dn)Nin*ye*>?VNPdzcCD)%)U&a&ZY0NbF(13iU*UB}SL_;Ij3xh%l^YB$5^a#htsfagD=J?(mCkV?~E7`7pI3r^-fdQ?odyzto0MgOo2|kCO%oz zJh|wVj3B%oWaVOk{yP<;wS9xjaZ8u$kn|b;ZoA>icgD={D zWggle^!4(}Tl0i)m!zhZr^icw{JNWar14dO#JJh_ygiz`ix{bMuw<-?xBb()hTLJu zK@02a*~`hVT23qT&XSg>y{Jw{7bRI14Sap>C5JD4wB@d0?$f>XI+FNdX9u`WOm0_D zpT0R#&&@mLJ~~j3tH^g(sgJg!0x0?40xdr^t;FmfTBhrA|pMy>k5a&&UV2ZL{btb^z0;UKSjsQv~i! zU5IK}i|5Q6z%ga0l}98HS^qo$IzWhs90({Vb_$`i`~8k&X7RwT?JEmWFeD zn1i=bQB8WAk{du<7TxRWYPk+_FL#nyUCqI3_|!gA6R6(YLRYdn_P0sf+uq0KZ{GwZ z+>zxNmspx=M~mIDC=D)k1HZ<%Uz=!|I!vF`LDrjSa(cXoGKqF2X-aqXOlpj7c47I5 z*4_nU>1|)(;{>fW)r^sI!fcd%)xt)S4qHB$j#J`tQJVgw(qmBSA#PH%KBOov&d-jK z4A?U@Ng0)88(93Ur0^ZOJ7OxjTcaH1Qhlaid05D>l{`R%^*;Y)mCtzd7fui2{}o=K zga0ZgMx^itAhg=e!wby@qOx*|^_r&{9*c~^^(sIp4RbFFx^(TD64>WWwhSDw(7cLg z#auh@=YvuZ3JAAt6T4|S-b*>hk=cA>=AwdPe$hqT+tbxWjl<+bmLClm)NBU^H>z2* zi;c#_dkNVKaG7GZOqfODl?K{&PoJlHU@wWXPHwxxXNQX6BNSzV7on+}yZ)%Z28T zwl0!aTJ5<)d(W@dQ^gWO5ouhvLVKG(el7<|d85dF$_d6@E}S>c_yE=hiNQ07e4VYN zHTc||xa?j@h|v*Nf5^OyE|2D6(pP$+-Vm!RZIW+D*CZ`MP!P0ZBkD(2dt89?cUMX( z{!U|_XSbqE4+k_;p_nqV@2By6^J@IJz2T1=^ytWLZetYnw4CO0zjJQ1ad?1@zD;i* z8uS2|IvTxy3KfjrP-GwN24X@P+I{ZNhUP|@c*kMdZH@VsfWGq5l~3Js-@?{MR0QEx z*k$W-C;OvaN8mla;2H%fAd!?=eM%AE3GlZX*osHQ`~1Bj$8C0q&p3F*(yT~ z(eGQ$8iH`on-Q|;U%vg@Y#zZ5Q6}zr1DYFZz}P8Icw!7<7PawBgu7+D|5Tiqe!WgJ z8W|PogoPLOP5lro`i*?5%-k!a^~*lxGl9Y=^-4=RXtUrD3A6i3X&@?aY69BC=Q*`Q zD+|yU-B(LDKDm!|GyQ7csYfi7*dYQ_hcR!!W=@rd0w`%PjxE1gtgd^-N@e3p4h2rH z08)IUKDnIL2=KH*8 z!K2{v9m*@&a2m=Lf;1oHY<57K6?NPv<*?!JESjNNI|#kX24roLJGJ_?sFY+T_;PHA zc&(Q$>{Rh%2pT_?-{OhTW^-a%T-WnwXjF!qh2_c740<|*{U@a!-SuHyvuK{6HD268 z-K+KL)G2>xvDkPv+fCcS%cLpEbR~=3r>qDW3Pl$6SrmMRo5mU`=wRtB{FW;5@b<&V zQJ)onP#%Vs`oi>5)xKw6#TiqWy_`D@?ND>EHXfR3srB!4P_r^t{Y89;gcE08qb!&L z%B$PT%m&V_kMc_*^5kq?a@ATm`p+Y^wS7C1Av3yR5~Iv$a-YAXy+F%MK$Bdw>U5u$ z5Ynve?G95PKDX z)nS*DT-5RQ(_m)#SYTzN~urmEj+H)8%$#Q)oMU7BIEXNf)?N?>Yh@)J` zvYBhYhj=7VEzeWZ!ni~}Dz3j4IA%TDtBFKBHxrT_)^>2%IvWyPSEi+t+Ev#0Jni%| zS^CAnR&-ZHS;wfcggXUX747C=8H4fg*#GlIxeiP1;pdU~7b)1Po(`?4gbcn!QP66ApP_JteuSsBFGyBkz7%H3+(?LA_LzZiHq z7wX%?+~o1frAaB@T+50?eSPQDNPm5W)BC)pYplLBy+vBXwAt**HuhnXPn7wm-%3yz zT8cY_*z2D$J8N{xfznG)j32zV?4+5FaT?K#?84GaK=`eO9CwW!Uhf)j4VFz7)3%WkXZ3(4e z9k??TC;hQ{Xl`_D7zcGo1;(7&fBzxV@WJ$&PH~nMOW~YkaOw>{yFs!w)Q1Mf>L!2c zbVk-;^s-^Ll-!WbGgFjsVM>!sh$RmNboS3~x-~=$Oeaq)>n10HON{gQ-EX3Dx*A0E z7}XjY)&12LmEG)u36sMTaBWH3%%7#brMYn@b|uZm-+80KGs$zy7M>3K5;LE~dp#6Cz~o71(V#-4ra#kxnqgY`V4X`7I!8dv*^_ z?Ht=>*GHCTzNWt=UHz4Atx6AWZwgkA^0Ve{L8aRM8B9(4-P76jrscrIW zr&$%0H{)y(v$)e&Fu!Vu#~T386%1`0T-54Sv$n<-W2&#>aqny~w2m=TK>eyCNx|7N zmW+W?+vL|yvMVTm#@iTM_f_JS=WY5IkBVzuTvtoAFaqD5ilvSPBxX3qYE&xR?X!h~ zmNj;yom+2EynIvJYT~+Gr(-R##-$>sw>r5MWnuhK+j@i~zG-Z`jm1QzPy@2g1_L#C zr1@>Mgu7<1E#J4s*kdv`6xQrwIHppE2V$?+Ylt?i)OB|wXLIboKhm7!tJtPE50#Ofz4cyWH{Q;M&~3_qNfYC7x3byVU6E!9&?KIvfP0D*1U?kBVhMYzl~h5 z(sy6gUkgU#1DbP|By6={IH5j~S56*G zjgU5%=8|j*zLZIg#w0xBY!VGMD}XuvX>J)tDdaEj^!-=dJ}H>7$^A8Aha!!`9m3(j z#WNPF000330|XHO z5)&XHF+ouU6e2QVaY9mok)hELBQtWb!SEz7Q)05=6+?oe@iaifRAZ8}B}8QZ+5iXv z0RRR+0{T_Z2C0fWa#~l(1gnI&*BJ&w0cYbJVqU zEX)^3{q!eS{5FO1Phe$~Z(jk9u-zp-opy+(V#?n9MOK3;ZH%6)asAx1T^}Pu1Z-10 zN3`U4^2Aaa$!jn6uv8r00&A$v9ijI-1QNe?pxANVIVwi(d2KFA9=czqh-)9QuJ~+;5C5AuYQ!!AZ z5%hf1nwVwT9IxLE$o~M?>B8rpL!*g*n%mAa)jc6qmy1N%K=uuoo{D)ivc@w`BNY^XM3wz@%5* za?a*#hkApsdJm+W-cA{4@}wJs zu(@v>Lr+za^t%>V`S|M3QtEUwknzdD?A?XU+J5K?H{y~B*DU7l>&TOPYDG~B7c{S# zz~GkJe+(L6ey@HixU;Wu4j?1 z$AYgDt0f&E8KXH~R_DlJB&uYVCf}F5xVY3wpc&08=VTko@xxPt^=B15BFa_;k3_6} zB2M4K|c9LA$Nkf@^Mo&y9@g@zmUS%urr5z|z% zyGh)UKRsGn=$AUumeK*iO}6|#IO^B>z4)x@2^6eyS}5=7b3cd2QnrpSwUIj);z79l zFyMV$oz_+xMk$&wbZ|JDSuLw0 zlM}<;sar^v&n!%eGPUPXT~Kr8060d_6pwbgQ%!+{0SOXvJEn2Q1710^D)YfmA5baOcNRyRbwX*^Pk3 zJd}4S5|P>#zT6JN#_?=@yK&Mp0ree(zc$^B(Hk9Mp# zQQDr?ziq9D!><_P3bTm_Kl#zm>2EQG4PW>^TSFsaFhk5=jfH-*w2q zZ4huptZ`3HsLL#}fP`?>lIwi3A@bXfjj#$kU;SrVp@NH<4mv0epR&dMBUYB`3iVOL z`I{Xkb_Fh$`0CXpsr8FH5~q&a-x5m{U<-FfD28C!VO1r0fn%#sasYIP9TquK#r-2v z8CPmUFlX=8(gqyp~qVIDo*Ph6)U=b@aGmDUj)- zjqWY8HVjUN8OGd=%fnVy$}U?S9GOKFdIVy0aZyonacZMAm) z0M4xfn`Y9JZJVuxvgHLBY}J|MWk|xD#kUL#D8H5GpcOlO|^0{7kO5|cpXy z@<5=d+hcY=ELSggw5Hmyc0m1{ZMOc?VKg!kBX@=?NBL_Yx1F~BT8!?&5k<=}uo#i@ z-!oqnRyVXLJ{pBs22-$u#}%=K5yG`DGOq!c<3|jairbDT<&yb|@!~JDQkJF|);6dN zUoWJ>+kQ9&T&+eclpDqZpKjesxg>CkB5kDGh8HSkJ_7)$%%^c0y(c7ON}0AWIk*fe zosFHY51yk(A_*g5W>yyjVxpEIqo-ES8sC@)7Yjlk^Aa3c*IqDA*&SP8y?tiN|t>n+wZjSk(Q@%Upa zMtlg|aRz+KwFfM}mZ2or4mh4^9Y``{jrauzWwF(RD`@vR;+kS^ABc3RU||{hp`S;xFh@HN1|ms?TA$qBZh4!GH<_9m!r}^bGCU@9$SI^aK@cvT>ae{ z#YH(bR~kXe{{XMUQmS1hj#7nU=bqazCXF+x9j`o7B|}zUWeK|9 zNq1m~yGt?HF0qxpBmj)XvoK#@R|L_M6+o2@Fe;BpFpl0rUu^t*4Gt=scht8h(ueuBUc?L4J6W zO1aHVWAVRt3O~bY`&&h$ICSYccY=9$7Z(|Mc;Y<~(nIQBXZla&jM{Wh2RTkNnU+iU zRx@&N-DUc9z(*qQn=hFM@;`F8%ivDPN&>V>3@uO@Z2&n@^8Q%RNhuOIJ#v)U;* zA4R@cWb5?V*Lc#5JvT)SgJV@b;pOwjiZdl;d$-zmiymG$(GHEM&9lqjyAsh?L}968 z^_oq`m$SzTyJt>UyALm00!eD(jZd!Dz|gwZ%-z`GYx~a(Y5H1j&h(^B!w*$QK{L`8 z?3MhuoIzh*Lo{^2+-B$F%iDuBJNCUH!2RL*jD2GWTn(X)&tb#2_=P#iyexp9b{#2i zLq+LM-R2*bBBki6cb;Y5M-j~O!>aUj*Fke~2mJdml!O>$k9cEan~A>zkFGh?dSGoH zW95(fsK5D)7$}#l&+88A{P5J~;7nFTl9k%C% z$l_Q%UzaRt9(9Cq5*rbXI#i`eI~FKf?0#6%SIN}qcvGjR=g$&J(KIa3ptD%pZ?}## z()4uVop!%Fd2hmKn?~SRTX-Ls$JdpQ{{V9Rlk&j^zML@NWB}oy=&)di(yD!%JUL^k z(j=AD%yVf5(oQsEqomFEmfri}=<6Xc)Hc}!oNxnPRQ~{Q`TjT`w8yu{8aiuLPIxKo zj2SvgPO&%eLD)W66*T=HDW{P3Exz7c?c<25`bLgO;q*=R1MJ<5(8vsDdL7@}7m`5% zJqB1`;mWOzT8I= zUKWqC2NC+@acPJj`tERk!VIG#wDRBlN1=ejL5HG_WgIS4w`+Z8^L!6Z}1i zJfvHGIFg#a6AeT6v+V?aV+yWxksdd>A3Q5dR~iG)^W}jR2mv_C7Y`QtRQ2u~*C<8Fx7U+s1$q2JCYhTQq5_&#BtG~9l_6zO8Mwfy}`yg&30ctH9 zdj600!A7l(SPS;HVWH@;)#=B2s!fO4%La;)CaSFj75) z;ySL7r70f*7%)@gZaDh6E}T)fe{5!wO%e55elsiS>V4q zrEc?&*9ewFDd&5ip){{WsBEe>$P`z2kT2W~(7g*!&gv0r+hBZcj0 zA@zBAVQ)AD`ZhPlN>SEo7;FP@^TC^?Ceq8o0C#+_)zp*$BXhDm!3psI@WNHrQV{~} zY^)mJdf2>DTKm-P2N~vl3HRU28N`}Gd#C}q#-6@Ttx4#>IQ;NG!svoS4aSj;f$+Z^ zJDNOaKISTyGd1 z7eNRU+qOa3Z&;pK6V3Z&Zv8Wji}yzlp`odXWsLA_H1tw+x-qrmZt{=M1;Dk2z)tKm ziyG+=VJmuGLa;c@wCa0IJWmg2!wC#AtWhS#MHU0->l92Vs_$|~b^Q5x;izjP(att8 z<}eF@CL2-5;fJN6MW%u;v}3t`c)VjxQhU`8-acH1(W0t|KdSzc`5b8j^}dh2vvFTM zO+5K!Urk$%8Y(C=8Q#!wVSh&gr=}QG%e+&L;`#dDhn_4p0gD}=;i~!}v=aXS>Gvt} z<$+5wXk|vq>*Iu*Mhxk-hpsWEG74^vQ?+uL zzKne(DvZwyw`dQ~@y7+Q*tlw#piS0g;18{VS<@^+8!}U?cZc(Qu(3lL#S-pB76a%r z(jKQ*zUn&-=07|?N7gP$M#f-wj3ALyPu`AE!@~^~HcBcun=7{kK3q;TbjjOp{H?X0 z=+V_hn%&nM8GMcdX6sZ8)(^xUN9TzvBr7If@NPI1{TEKXVxW*R>^rZ#?%jb?(hMtV z@0foLK7QYztEgo=!NIENX0hIBnZKm|M-fIyLBJi@6%oN1nlWhyqTV=)zoh0XPaqDE zA==BoZz1~Ggn|gxD3DoIczq2tf3ntp6*&Fj#|DP7!a}{}YxZy!aId88BQEtgdN>+7 zT6%j4TZf&vU|jy zGE}$Kk=`7|`C)2nh^(yNw`w8q=jZelU>Q!r4;(#TL_Ug6_g3^z-8?+Ed15G>g!AWs zq9~q7cOC~3*L1YRLf|?;hrGT#u(3fJ#S-pR79U2HTdP)!T5vCa0yyEQD)Q&Ic}@0X zEV)=Xx}GXTg{P*BMH28Fd{5Dqrasv2%9|a1 zxQ-blS>l%FIR?wye$E^4WS1m}+ZkI2qbS*7r$L#fw&CN?2Ss@&Zv4-@{D;ucR7A5x z+tr2|zKTrLV1Us#dOPg)i{YJ^DFco)R7#y89IRCA!ocP^M4g~`p}>-&aRmfTqsthvdvY8wA*F?4PYvhKpU@(zk2Sll zHZu7fM+uZo6t^+Ampn;3v~QcT(Z3uXjH7g?r2{)j$X|DkKA|rw4&2YRo9K8dB3Yts z=;H>ql55fCwvEqeZ_Aj$k>ps}1^Zah^md9FYR*%@18x2oTA9yVuKpu;RQ~`d{Qip_ zqZ9Ov1gl6RTCeehin`I>%-){Dkfc*7hok-DD-SUnMEqp>peYRlqZp+h*%EO2!Z^uw9 zCe<-Ec8v06>XsGIIE;a&m1mMSo!0t_YsBL z6!mH?q+8pO^pz4emSe*)8;6F?NvTU@X4;L( zhU`sF=-J|IuajuN>57YJfMkJA`|d6HjaHQ}B|SryjE?X;Mmma<5VmPu{T1Ww+k}Y) zkrXH%8iS;%?WLweq*Li8{{V*Hei1@R+St1>mR8SIG15wT8*Uz2j}hNIh>Ce_&Hn(7 z9bbLzhtmH5l#I}?^MAoQw}4)rq_e~q(dNG#bwErg269tRy+FEmaw#KV4GM+ZoBbhO1r#^MJ+n8C z@50y$tf<6*8MtB!NZUA!ZDZ*kCsInD(T*7k#~$pf`U3VZw$r>VQfqtNj9;KL!&K^2;9yKTr| zDvK!C2B-MNKYwCOg!i}tF;7PtWs+mCvDiFu6(TWwo80LGl*|!}WW<7x>-yNFeev>?#eHC9=^2JSDE#B?CUd#a3 zCve40RazKis>_x(-V}59>NONUXB?fWFWw`D01T&Pz!-vTg=nc9JIHrjZ40YX9qpPW zBX5Q}KqXvy)u>^4z*ysL`FWq$4PKB!_9CJC z!*27AjU#r1YDqM$k~A5Z;-;<(#Iwnm2HR{y)onbo9GO=Xly?kbj4LqWc%Oc!NEY3p zY;<`H8q%i2_qDoJ8O8LRF-v1{nos`5)#$v&*Ju9##}y@7=c_mMuCGa-{{Wg#={Tjc zT!$Mr^VOTSsL*|Kmff@aUm3IIX4~b4sCo05V#t7Q&9hgcv+*);`?#$L_xhXL{XhEZ%gyRgw2sM@#BP}j9AiuhsVcPrG{_+0A^3?IOzLs(ce~(H~yS%`^}D% zbz(s%KdVxrmG&&iP@Y%EQ>=!;t`bXKTyq%FnX)anoJfsfG+pa%K01{Z5Ww?LNKBcK zUq{Rz3|$*0V|xx5hJ~C-6Zaf%1n@e8r0An+jLT_bU92s{3^OvATy`04l-~`~6l6~m z*iTCP4Y`Aes$guVMM4N}M-oK#(#OPlL!PHZ+!Cb8yZtz*D}K#6-}jeVp=t(@q^ujx_ps0vv0Rkqoo(oD>!afHn-q#k%Y@2^s!M>9AiNgCo#6>BwF6%sKHH|+YSm;M{^k} z%6J?$TiEVgQAa4WsRAnl&f2ogMof|95$E8gi@)s~h_&plccjTiAg7^kYpOi;+B z%I_O-6=gGKicWjSfz*nUsBuh4sh~{~vGnXt-;O4rm@>Uv4IA*d;j2Sd0WrYLu6bs+%Nh)z z{{S}}R#e#NRdji|o&Nx@Jxbbme%45tRC6}njMl#bt%_(P8(Ki^Z$(Dat6U`(FEN=9 zHDhss*c+{7i+

g5^D^2ZqT+mIaBYp3)RjLC? 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 Console -c) Enter: - -(I assume that the the DATA file is called "system.data") - - topo readlammpsdata system.data full - animate write psf system.psf - -2) - -Later, to Load a trajectory in VMD: - - Start VMD - Select menu: File->New Molecule - -Browse to select the PSF file you created above, and load it. - (Don't close the window yet.) - -Browse to select the trajectory file. - If necessary, for "file type" select: "LAMMPS Trajectory" - Load it. - - ---- A note on trajectory format: ----- -If the trajectory is a DUMP file, then make sure the it contains the -information you need for pbctools (see below. I've been using this -command in my LAMMPS scripts to create the trajectories: - - dump 1 all custom 5000 DUMP_FILE.lammpstrj id mol type x y z ix iy iz - -It's a good idea to use an atom_style which supports molecule-ID numbers -so that you can assign a molecule-ID number to each atom. (I think this -is needed to wrap atom coordinates without breaking molecules in half.) - -Of course, you don't have to save your trajectories in DUMP format, -(other formats like DCD work fine) I just mention dump files -because these are the files I'm familiar with. - -3) ----- Wrap the coordinates to the unit cell - (without cutting the molecules in half) - -a) Start VMD -b) Load the trajectory in VMD (see above) -c) Menu Extensions->Tk Console -d) Try entering these commands: - - pbc wrap -compound res -all - pbc box - - ----- Optional ---- - Sometimes the solvent or membrane obscures the view of the solute. - It can help to shift the location of the periodic boundary box - To shift the box in the y direction (for example) do this: - - pbc wrap -compound res -all -shiftcenterrel {0.0 0.15 0.0} - pbc box -shiftcenterrel {0.0 0.15 0.0} - - Distances are measured in units of box-length fractions, not Angstroms. - - Alternately if you have a solute whose atoms are all of type 1, - then you can also try this to center the box around it: - - pbc wrap -sel type=1 -all -centersel type=2 -center com - -4) - You should check if your periodic boundary conditions are too small. - To do that: - select Graphics->Representations menu option - click on the "Periodic" tab, and - click on the "+x", "-x", "+y", "-y", "+z", "-z" checkboxes. - -5) Optional: If you like, change the atom types in the PSF file so - that VMD recognizes the atom types, use something like: - -sed -e 's/ 1 1 / C C /g' < system.psf > temp1.psf -sed -e 's/ 2 2 / H H /g' < temp1.psf > temp2.psf -sed -e 's/ 3 3 / P P /g' < temp2.psf > system.psf - -(If you do this, it might effect step 2 above.) diff --git a/tools/moltemplate/examples/coarse_grained_examples/abstract_translocation/images/polymer_LR.jpg b/tools/moltemplate/examples/coarse_grained_examples/abstract_translocation/images/polymer_LR.jpg deleted file mode 100644 index 5529fc74b9006e8f3e1e896a64f671c2ff902f40..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5568 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 bhjc-}i%2LwH+TM8lAE5RB+T#g`PBaaMdBB) diff --git a/tools/moltemplate/examples/coarse_grained_examples/abstract_translocation/images/solvent_LR.jpg b/tools/moltemplate/examples/coarse_grained_examples/abstract_translocation/images/solvent_LR.jpg deleted file mode 100644 index 304693e2acffe71b3c020b8a90f45ea58a59c22a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23407 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

v832UE!au!y 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

Y6mlk_ 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 diff --git a/tools/moltemplate/examples/coarse_grained_examples/abstract_translocation/images/walls_LR.jpg b/tools/moltemplate/examples/coarse_grained_examples/abstract_translocation/images/walls_LR.jpg deleted file mode 100644 index 319427ae61797777fb5b17a78d5a84c595aa7b86..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13280 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 AZU6uP diff --git a/tools/moltemplate/examples/coarse_grained_examples/abstract_translocation/moltemplate_files/monomer.lt b/tools/moltemplate/examples/coarse_grained_examples/abstract_translocation/moltemplate_files/monomer.lt deleted file mode 100644 index a8a35339f5..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/abstract_translocation/moltemplate_files/monomer.lt +++ /dev/null @@ -1,111 +0,0 @@ - # ---------------------------------------------------------------------- - # -- General comment: -- - # -- The write() and write_once() commands create and append text to -- - # -- files (replacing variables beginning with @ or $ with counters.) -- - # -- File names beginning with "In " or "Data " are special. -- - # -- They will be pasted into the LAMMPS input script and -- - # -- data files which are generated by moltemplate. The syntax -- - # -- of these files is exactly the same as the syntax from the -- - # -- corresponding sections of a LAMMPS input script or data file. -- - # ---------------------------------------------------------------------- - - -Monomer { - - # atom-id mol-id atom-type charge x y z - - write("Data Atoms") { - $atom:CA $mol:... @atom:CA 0.0 0.000 0.4000 0.00000 - $atom:R1 $mol:... @atom:R 0.0 0.000 1.000 1.000 - $atom:R2 $mol:... @atom:R 0.0 0.000 1.000 -1.000 - } - - # Note: The "..." in "$mol:..." tells moltemplate that this molecule may - # be a part of a larger molecule, and (if so) to use the larger - # parent object's molecule id number as it's own - - - # atom-type mass - - write_once("Data Masses") { - @atom:CA 13.0 - @atom:R 50.0 - } - - # atom-type atom-type epsilon sigma - - write_once("In Settings") { - pair_coeff @atom:CA @atom:CA 0.05 2.0 - pair_coeff @atom:R @atom:R 0.50 2.0 - } - - # bond-id bond-type atom-id1 atom-id2 - - write("Data Bonds") { - $bond:CR1 @bond:sidechain $atom:CA $atom:R1 - $bond:CR2 @bond:sidechain $atom:CA $atom:R2 - } - - write_once("In Settings") { - # bond-type k r0 - bond_coeff @bond:sidechain 30.0 1.2 - bond_coeff @bond:bb 30.0 2.0 # "bb" shorthand for "backbone" - } - - # For a compound molecule consisting of smaller building blocks (such as a - # polymer built from monomers), it is tedious to explicitly list all of the - # angles, dihedrals in the entire molecule. Instead, you can define rules - # for automatically generating all the angular interactions between bonded - # atoms according to their connectivity and the atom/bond type. - # Later, when you connect multiple monomers together to form a polymer, - # appropriate bond-angle forces will be applied to these atoms automatically - # (as well as dihedral and improper forces, if defined). - - # Rules for determining 3 and 4-body bonded interactions by type - - # angle-type atomType1 atomType2 atomType3 bondType1 bondType2 - - write_once("Data Angles By Type") { - @angle:backbone @atom:CA @atom:CA @atom:CA @bond:* @bond:* - @angle:sidechain @atom:CA @atom:CA @atom:R @bond:* @bond:* - @angle:RCR @atom:R @atom:CA @atom:R @bond:* @bond:* - } - - # ("@angle:RCR" defines the angle between the R-C-R atoms within a monomer. - # The other angular interactions are between atoms in neighboring monomers.) - - - # dihedral-type AtomType1 AtomType2 AtomType3 AtomType4 bondType1 btyp2 btyp3 - - write_once("Data Dihedrals By Type") { - @dihedral:backbn @atom:CA @atom:CA @atom:CA @atom:CA @bond:* @bond:* @bond:* - } - - # Parameters for these new angular interactions must be defined. (I recommend - # putting all force-field parameters (coeffs) in the "In Settings" section.) - - write_once("In Settings") { - # angle-type k theta0 - angle_coeff @angle:backbone 50.00 160 - angle_coeff @angle:sidechain 50.00 120 - angle_coeff @angle:RCR 50.00 120 - # dihedral-type K1 K2 K3 K4 - dihedral_coeff @dihedral:backbn 1.411036 -0.271016 3.145034 0.0 - } - -} # Monomer - - - - - - -# ------------------------------------------------------------------------- -# Heteropolymers: -# -# There is a similar example for heteropolymers which is distributed online -# bundled with the moltemplate software. It is named "2bead_heteropolymer", -# and it demonstrates how to share backbone (CA) atoms, bonds and angles -# (so that you don't have to define them seperately for each type of monomer). -# ------------------------------------------------------------------------- - diff --git a/tools/moltemplate/examples/coarse_grained_examples/abstract_translocation/moltemplate_files/polymer.lt b/tools/moltemplate/examples/coarse_grained_examples/abstract_translocation/moltemplate_files/polymer.lt deleted file mode 100644 index 31a36d07ce..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/abstract_translocation/moltemplate_files/polymer.lt +++ /dev/null @@ -1,32 +0,0 @@ -import "monomer.lt" - -Polymer { - - create_var {$mol} # optional:force all monomers to share the same molecule-ID - # (The "Data Atoms" in Monomer must use "$mol:..." notation.) - - # Make a chain of monomers - monomers = new Monomer [12].rot(180, 1,0,0).move(2.0, 0, 0) - - - # Now, link the monomers together this way: - write("Data Bonds") { - $bond:bb1 @bond:Monomer/bb $atom:monomers[0]/CA $atom:monomers[1]/CA - $bond:bb2 @bond:Monomer/bb $atom:monomers[1]/CA $atom:monomers[2]/CA - $bond:bb3 @bond:Monomer/bb $atom:monomers[2]/CA $atom:monomers[3]/CA - $bond:bb4 @bond:Monomer/bb $atom:monomers[3]/CA $atom:monomers[4]/CA - $bond:bb5 @bond:Monomer/bb $atom:monomers[4]/CA $atom:monomers[5]/CA - $bond:bb6 @bond:Monomer/bb $atom:monomers[5]/CA $atom:monomers[6]/CA - $bond:bb7 @bond:Monomer/bb $atom:monomers[6]/CA $atom:monomers[7]/CA - $bond:bb8 @bond:Monomer/bb $atom:monomers[7]/CA $atom:monomers[8]/CA - $bond:bb9 @bond:Monomer/bb $atom:monomers[8]/CA $atom:monomers[9]/CA - $bond:bb10 @bond:Monomer/bb $atom:monomers[9]/CA $atom:monomers[10]/CA - $bond:bb11 @bond:Monomer/bb $atom:monomers[10]/CA $atom:monomers[11]/CA - } - -} # Polymer - - - -# Angle, dihedral and improper interactions will be generated -# automatically according to the instructions in "monomer.lt" diff --git a/tools/moltemplate/examples/coarse_grained_examples/abstract_translocation/moltemplate_files/solvent.lt b/tools/moltemplate/examples/coarse_grained_examples/abstract_translocation/moltemplate_files/solvent.lt deleted file mode 100644 index 1073a58a14..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/abstract_translocation/moltemplate_files/solvent.lt +++ /dev/null @@ -1,23 +0,0 @@ -###################### SOLVENT ######################### - -import "solvent_single.lt" - -# Fill the simulation box with a solvent. -# In this example, the solvent is made of many -# copies of "MoleculeA" (which has only one atom). - -solvent = new MoleculeA [12].move(3.0,0,0) - [12].move(0,3.0,0) - [12].move(0,0,3.0) - -# To start with a reasonable conformation, it's a good idea to delete the -# solvent where the walls or the polymer is going to be. Here we do it manually: - -delete solvent[*][*][2] # <-- 1st wall will go here -delete solvent[*][*][8] # <-- 2nd wall will go here -delete solvent[6-7][0-8][5-6] # <-- polymer will go here - -# Alternate notation: -# [a:b] notation also works, however the "b" is a strict upper bound... -# ...hence the last line is equivalent to "delete solvent[6:8][0:9][5:7]" -# [a*b] notation also works, and is equivalent to [a-b] diff --git a/tools/moltemplate/examples/coarse_grained_examples/abstract_translocation/moltemplate_files/solvent_single.lt b/tools/moltemplate/examples/coarse_grained_examples/abstract_translocation/moltemplate_files/solvent_single.lt deleted file mode 100644 index 8057e3c6fc..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/abstract_translocation/moltemplate_files/solvent_single.lt +++ /dev/null @@ -1,22 +0,0 @@ -# The two files "solvent_single.lt" and "wall_single.lt" -# define two very simple molecules containing one atom each. -# Both atoms have a similar size (the have the same sigma parameter). - - -MoleculeA { - - # atomID molID atomType charge x y z - write("Data Atoms") { - $atom:a $mol:. @atom:a 0.0 0.0 0.0 0.0 - } - write_once("Data Masses") { - @atom:a 10.0 - } - write_once("In Settings") { - # i j epsilon sigma cutoff - pair_coeff @atom:a @atom:a 0.60 3.0 7.5 #<--attractive - group groupA type @atom:a #(Atoms of this type belong to the "A" group) - } - -} - diff --git a/tools/moltemplate/examples/coarse_grained_examples/abstract_translocation/moltemplate_files/system.lt b/tools/moltemplate/examples/coarse_grained_examples/abstract_translocation/moltemplate_files/system.lt deleted file mode 100644 index 0ed2727108..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/abstract_translocation/moltemplate_files/system.lt +++ /dev/null @@ -1,57 +0,0 @@ - -# LAMMPS supports a large number of force-field styles. We must select -# which ones we need. This information belongs in the "In Init" section (and -# (you can specify it anywhere in your LT files, multiple times if you like). -# If different molecules use different force-field styles, you can use hybrid -# styles. (In this example the molecules share the same pair_style.) - -write_once("In Init") { - units real - atom_style full - bond_style harmonic - angle_style harmonic - dihedral_style opls - pair_style lj/cut 9.0 - # If you have charged molecules immersed in a salty implicit - # solvent, you might try something like this this instead: - # pair_style lj/cut/coul/debye 0.1 9.0 - pair_modify mix arithmetic - dielectric 80.0 - special_bonds lj 0.0 0.0 0.0 -} - - -write_once("Data Boundary") { - 0.0 36.0 xlo xhi - 0.0 36.0 ylo yhi - -18.0 18.0 zlo zhi -} - - -import "solvent.lt" - -import "walls.lt" - -import "polymer.lt" - -polymer = new Polymer -polymer.rot(-90.0, 0,0,1) # rotate it -90 degrees around the Y axis -polymer.move(19.5,22.5,16.5) # move it near the openning of the hole - - - -####################### Notes: ######################### -# -# In this example we deleted solvent and wall molecule objects. -# You can also delete a monomer inside the polymer. To do that use: -# delete polymer/monomers[6] -# You can also delete individual atoms, bonds, angles, dihedrals, & impropers -# from existing molecules. For example to delete an atom in the middle -# of the polymer try this. (Bonds and other interactions will also be removed.) -# delete polymer/monomers[6]/CA -# To delete a bond, try this -# delete polymer/bb6 -# Note: This will not delete the angular interactions if they were explicitly -# defined (ie, using "Data Angles" instead of "Data Angles By Type"). -# Delete explicit angle, dihedral, and improper interactions manually. -# Note: In both cases the two molecule fragments will keep the same mol counter. diff --git a/tools/moltemplate/examples/coarse_grained_examples/abstract_translocation/moltemplate_files/wall_single.lt b/tools/moltemplate/examples/coarse_grained_examples/abstract_translocation/moltemplate_files/wall_single.lt deleted file mode 100644 index 79275a06b4..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/abstract_translocation/moltemplate_files/wall_single.lt +++ /dev/null @@ -1,21 +0,0 @@ -# The two files "solvent_single.lt" and "wall_single.lt" -# define two very simple molecules containing one atom each. -# Both atoms have a similar size (the have the same sigma parameter). - -MoleculeB { - - # atomID molID atomType charge x y z - write("Data Atoms") { - $atom:b $mol:. @atom:b 0.0 0.0 0.0 0.0 - } - write_once("Data Masses") { - @atom:b 10.0 - } - write_once("In Settings") { - # i j epsilon sigma cutoff - pair_coeff @atom:b @atom:b 0.05 3.0 7.5 #<--repulsive (approximately) - group groupB type @atom:b #(Atoms of this type belong to the "B" group) - } - -} - diff --git a/tools/moltemplate/examples/coarse_grained_examples/abstract_translocation/moltemplate_files/walls.lt b/tools/moltemplate/examples/coarse_grained_examples/abstract_translocation/moltemplate_files/walls.lt deleted file mode 100644 index dcccac941e..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/abstract_translocation/moltemplate_files/walls.lt +++ /dev/null @@ -1,23 +0,0 @@ -####################### WALLS ########################## - -import "wall_single.lt" - -# Create a wall at position z=6.0 (6.0 = 2*3.0) - -wall1 = new MoleculeB [12].move(3.0, 0, 0) - [12].move(0, 3.0, 0) - -wall1[*][*].move(0,0,6.0) - -# Create a second wall at position z=24.0 (24.0 = 8*3.0) - -wall2 = new MoleculeB [12].move(3.0, 0, 0) - [12].move(0, 3.0, 0) - -wall2[*][*].move(0,0,24.0) - -# Now delete some of the molecules in "wall2" to create a hole. - -delete wall2[6-7][6-9] -delete wall2[5-8][7-8] - diff --git a/tools/moltemplate/examples/coarse_grained_examples/abstract_translocation/run.in.npt b/tools/moltemplate/examples/coarse_grained_examples/abstract_translocation/run.in.npt deleted file mode 100644 index 0b58a8e1b0..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/abstract_translocation/run.in.npt +++ /dev/null @@ -1,120 +0,0 @@ -# THIS EXAMPLE HAS NOT BEEN RIGOROUSLY TESTED. -# (This simulation may fail. -# However the "run.in.nvt" example in this directory should work.) -# -# Requirements: -# To run this system at constant pressure, it might help to compile LAMMPS with -# the optional RIGID package, and use "fix rigid" on the carbon. (Optional.) -# The use of fix rigid is controversial. This method is demonstrated below. - -# ------------------------------- Initialization Section -------------------- - -include system.in.init - -# ------------------------------- Atom Definition Section ------------------- - -read_data system.data - -# ------------------------------- Settings Section -------------------------- - -include system.in.settings - -# ------------------------------- Run Section ------------------------------- - - -# Only the groupB atoms are immobile. -group mobile subtract all groupB - -# Unfortunately you can not use the LAMMPS "minimize" command on this system -# because there is no way to immobilize the wall atoms during minimization. -# Instead, we can use langevin dynamics with a fast -# damping parameter and a small timestep. - -print "--------- beginning minimization (using fix langevin) ---------" - -timestep 0.1 -fix fxlan mobile langevin 1.0 1.0 100.0 48279 -fix fxnve mobile nve # <-- needed by fix langevin (see lammps documentation) -thermo 100 -run 2500 - -unfix fxlan -unfix fxnve - -# -- simulation protocol -- - -print "--------- beginning simulation (using fix nvt) ---------" - -dump 1 all custom 1000 traj_npt.lammpstrj id mol type x y z ix iy iz - -thermo_style custom step temp pe etotal press vol epair ebond eangle edihed -thermo 200 # time interval for printing out "thermo" data - - -# ------------------------- NPT --------------------------- - - -# ------ QUESTIONABLE (see below): ------ - -fix Ffreezestuff groupB rigid single force * off off off torque * off off off - -# Comment: -# The use of "fix rigid" to immobilize an object is somewhat controversial. -# Feel free to omit it. -# (Neither Trung or Steve Plimpton use fix rigid for immobilizing -# molecules, but I noticed that at NPT, it does a better job of maintaining -# the correct volume. However "fix rigid" has changed since then (2011), -# so this may no longer be true. Please use this example with caution.) - - - -# Thermostat+Barostat -# Set temp=300K, pressure=200bar, and equilibrate volume only in the z direction - -fix fxMoveStuff mobile npt temp 300 300 100 z 200 200 1000.0 dilate mobile drag 2.0 - -# ---------------------------------------- - -# The next two lines recalculate the temperature using -# only the mobile degrees of freedom (ie. water atom velocities): - -compute tempMobile mobile temp -compute pressMobile all pressure tempMobile - -thermo_style custom step c_tempMobile c_pressMobile temp press vol - -fix_modify fxMoveStuff temp tempMobile - -reset_timestep 0 - -timestep 0.5 - -run 100000 - -timestep 1.0 - -run 100000 - - -write_data system_after_npt.data - -# (The "write_restart" and "read_restart" commands were buggy in 2012, -# but they should work also.) - - - - - - - -# ----- Comment: Avoid using fix rigid/npt on large single rigid objects ----- -# -# Use of the following is not recommended: -# -# fix Ffreezestuff groupB rigid/npt single temp 300 300 100 z 200 200 1000.0 force * off off off torque * off off off dilate mobile -# (temp=300K, pressure=200bar, and equilibrate volume only in the z direction) -# -# In my experience, the system becomes unstable when applying "fix rigid/npt" -# to the immobile atoms, while also applying "fix npt" on the solvent atoms. -# (It is probably a bad idea to use two barostats simultaneously.) -# ---------------------------------------------------------------------------- diff --git a/tools/moltemplate/examples/coarse_grained_examples/abstract_translocation/run.in.nvt b/tools/moltemplate/examples/coarse_grained_examples/abstract_translocation/run.in.nvt deleted file mode 100644 index c483d0b9ab..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/abstract_translocation/run.in.nvt +++ /dev/null @@ -1,53 +0,0 @@ -# PREREQUISITES: -# -# You must use moltemplate.sh to create 3 files: -# system.data system.in.init system.in.settings -# (See README_setup.sh for details) - -# -- Init Section -- - -include system.in.init - -# -- Atom Definition Section -- - -read_data system.data - -# -- Settings Section -- - -include system.in.settings - -# Use "neigh_modify" to turn off calculation of interactions between immobilized -# atoms. (Note: The "groupB" group was defined in the file "system.insettings") -neigh_modify exclude group groupB groupB - -# -- Run Section -- - - -timestep 1.0 -dump 1 all custom 500 traj_nvt.lammpstrj id mol type x y z ix iy iz - -thermo_style custom step temp pe etotal vol epair ebond eangle edihed -thermo 500 # time interval for printing out "thermo" data - - -# Optional: Improve efficiency by omitting the calcuation of interactions -# between immobile atoms. (Note: This is not optional under NPT conditions.) -neigh_modify exclude group groupB groupB - -# Only the groupB atoms are immobile. -group mobile subtract all groupB - -# The next two lines recalculate the temperature -# using only the mobile degrees of freedom: - -compute tempMobile mobile temp - -# Integrate the equations of motion: -fix fMoveStuff mobile nvt temp 300.0 300.0 100.0 -fix_modify fMoveStuff temp tempMobile - - -run 100000 - -write_data system_after_nvt.data - diff --git a/tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/README_FIRST.txt b/tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/README_FIRST.txt deleted file mode 100644 index 03fb40b167..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/README_FIRST.txt +++ /dev/null @@ -1,48 +0,0 @@ -This is an implementation of the "two-stage" model used by Maxim Imakaev -in the Naumova et Al 2013 Science paper on metaphase chromatin. -(Download the supplemental materials section and scroll down to the section: - "Two-stage process: linear compaction - axial compression") - ----- SMALL MODIFICATION ---- - -Unlike that study, I did not use "softened" Lennard-Jones potentials -(which allow the chains to pass through each other). - ---- Why use moltemplate? --- - -Honestly, you don't need to use moltemplate to build this polymer. -It is almost counter-productive to use moltemplate to build this kind of -polymer because it is so simple. (The polymer has only 1 bead per atom. -It just makes it more complicated to introduce all these extra -files including monomer.lt, condensin.lt and system.lt, especially considering -that system.lt is a complex file which is generated by a separate script.) - -However building the sytem using moltemplate may pay off if you -replace each point-like monomer with a multi-atom molecule later on. -(Right now, using moltemplate to build this system is sort of overkill. - I'll post an example of building more complex models of chromatin eventually.) - -Anyway, the two-stage model at the end of Naumova et al Science 2013 uses the "30nm-fiber" model, whose details are (somewhat vaguely) described in the supplemental materials section. - ----- 10-nm fiber model: ---- - -For the 10nm model, - n=128000, - L=200, - U(alpha)=5*(1 - cos(alpha)) - bond_length=1.0 (=10nm) - sigma=1.0 (particle radius = 10nm) - ----- 30-nm fiber model: ---- - -"The 30nm-like fiber was modeled by increasing the volume of each monomer and the amount of DNA represented by each monomer by a factor of 4.25, while keeping other parameters the same at the monomer level." - -I interpret this to mean that, for the 30nm model, - n=128000/4.25~=30117 (however I rounded up to 32768=2^15) - L=200/4.25~=47 (however I rounded up to 51) - U(alpha)=1.17647*(1 - cos(alpha)) (5/4.25=1.17647) - -To increase the volume by a factor o 4.25, I increase both the diameter of each -bead (the "sigma" parameter), and the bond-lengths connecting them from -1.0 (corresponding to 10nm) to 4.25^(1/3)~=1.6198 (corresponding to 16.198nm). - diff --git a/tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/README_NUCLEAR_VOLUME_FRACTION_ESTIMATE.txt b/tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/README_NUCLEAR_VOLUME_FRACTION_ESTIMATE.txt deleted file mode 100644 index 38ad9c1c06..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/README_NUCLEAR_VOLUME_FRACTION_ESTIMATE.txt +++ /dev/null @@ -1,29 +0,0 @@ ---------------- -The average diameter of a mammalian cell nucleus is is 6 micrometers (μm), -which occupies about 10% of the total cell volume. - -(See "Molecular Biology of the Cell, Chapter 4, pages 191–234 (4th ed.)", by - Bruce Alberts, Alexander Johnson, Julian Lewis, Martin Raff, Keith Roberts, Peter Walter, 2002) - -... of that, 25% of it is occupied by the nucleolus -http://en.wikipedia.org/wiki/Nucleolus -("citation needed") ---------------- - -From the supplemental material for the original HiC paper -(Lieberman-Aiden et al., Science 2009) - -Appendix 1. - Estimate of the Volume Fraction of Chromatin in Human Cells -In the simulations we sought to obtain an ensemble of structures that, in their statistical properties, resemble some of the features of chromatin arrangement in the cell. Below we demonstrate that chromatin occupies a significant fraction of cell volume, a property that we reproduced in simulations. Taking the nuclear diameter of a tissue culture cell to be 5-10um, and assuming close to a spherical shape we obtain the volume in the range 50-500 um^3, with a (geometric) mean of ~160 um^3. If we assume that the chromatin is built of DNA wrapped around nucleosomes, then we have 6x10^9bp/200bp=3x10^7 nucleosomes. Each may be approximated as a cylinder ~10nm in diameter and ~5nm in height, suggesting a volume of about 500nm3 each. The linker DNA after each nucleosome is about 50bps long, suggesting a volume of about 50*0.34nm*3.14*1nm^2=50nm^3. Thus the total volume of chromatin = 550x3x10^7 =16 um^3, or ~10% (3-23%) of the nuclear volume. This strikingly large volume fraction is itself a significant underestimate, since we ignored, among other things, all other DNA-bound proteins. Note that any further packing or localization of chromatin inside the nucleus will increase local density. ----- This next section mostly only justifies why they ---- ----- they did not stop the simulation when the globules ---- ----- were fully crumpled (ie with uniform density) ---- - In our simulations, the radius of the final crumpled globule was R≈12.5 and the volume V≈8000 cubic units. The total volume of the 4000 monomers, 1 unit in diameters each, is V≈2000. This implies a volume fraction of about 25%, which is consistent with the volume fraction estimated above. - ---- ---- - -Appendix 2. - Monomer length in base pairs -Each monomer of the chain corresponds to a fragment of chromatin that equals the Kuhn length of the chromatin fiber, i.e. approximately twice the persistence length of the fiber. Although the persistence length of the chromatin fiber is unknown it can be estimated using the following arguments. DNA is packed into nucleosomes, where 150 bps are wrapped around the histone core and do not contribute to flexibility of the fiber. The linker DNA of about 50 bps that connects consecutive nucleosomes is bendable, and is the source of flexibility in the fiber. Since the persistence length of double-stranded DNA is 150 bps, an equally flexible region of the nucleosomal DNA should contain 3 linkers, i.e. 3 consecutive nucleosomes packing about 600 bps of DNA. The excluded volume of the nucleosomes, nucleosome interactions, and other DNA-bound proteins can make the fiber less flexible or prohibit certain conformation and may tend to increase the persistence length of the fiber. Using this estimated lower bound estimate for the persistence length, we obtain the Kuhn length of the equivalent freely-jointed chain to be 6 nucleosomes, or ~ 1200bp. A simulated chain of 4000 monomers corresponds to 4.8Mb of packed DNA. The size of each monomer was chosen such that its volume is equal to (or slightly above) that of 6 nucleosomes (V=6 x 600 nm^3); thus the radius of the spherical monomer is R=10nm. The diameter of each globule shown in Figure 4 is about 200 nm. - - diff --git a/tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/README_run.sh b/tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/README_run.sh deleted file mode 100755 index 19674c88bd..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/README_run.sh +++ /dev/null @@ -1,7 +0,0 @@ -# Run lammps using the following 3 commands: -# (assuming "lmp_mpi" is the name of your LAMMPS binary) - -lmp_mpi -i run.in.min -lmp_mpi -i run.in.stage1 -lmp_mpi -i run.in.stage2 - diff --git a/tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/README_setup.sh b/tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/README_setup.sh deleted file mode 100755 index 14700a29cd..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/README_setup.sh +++ /dev/null @@ -1,58 +0,0 @@ -# Use these commands to generate the LAMMPS input script and data file -# (and other auxilliary files): - - -# Create LAMMPS input files this way: -cd moltemplate_files - - # First, rescale and interpolate the positions - # where the monomers will be located. (This step is - # not needed if the coords_orig.raw file already has correct coordinates.) - - ./interpolate_coords.py 32768 1.6198059 < coords_orig.raw > coords.raw - - # Then, build the "system.lt" file - - ./generate_system_lt.py 32768 51 < coords.raw > system.lt - - # 32768 is the number of monomers in the polymer - # (which may be different from the number of coordinates - # in the "coords_orig.raw" file) This number will vary - # depending on how long you want the polymer to be. - # The second argument "51" is the average interval between - # condensin anchors (IE the "loop size" in monomers.) - - - # Run moltemplate - - moltemplate.sh system.lt -a "@bond:stage1 1" \ - -a "@bond:stage2 2" \ - -a "@atom:Monomer/A 1" - - # This will generate various files with names ending in *.in* and *.data. - # These files are the input files directly read by LAMMPS. Move them to - # the parent directory (or wherever you plan to run the simulation). - # - # We used the "-a" command to set the variable @bond:condensin to "2" - # because we will refer to it later in the "run.in" LAMMPS input script. - # (Of coarse, LAMMPS knows nothing about moltemplate variables, - # so in that file we refer to it as dihedral type "1") - - mv -f system.in* system.data ../ - - # We also need the table of bond forces used during "stage 2". - # (Like the system.data and the various input scripts, this file is needed by - # LAMMPS, so we need to copy it to the directory where we will run the sim.) - cp -f table_bonds_stage2.dat ../ - - # Optional: - # The "./output_ttree/" directory is full of temporary files generated by - # moltemplate. They can be useful for debugging, but are usually thrown away. - rm -rf output_ttree/ - - # Optional: - # Remove the "system.lt" file created by "generate_system_lt.py" - #rm -f system.lt - -cd ../ - diff --git a/tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/README_visualize.txt b/tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/README_visualize.txt deleted file mode 100644 index a5b46dc8a5..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/README_visualize.txt +++ /dev/null @@ -1,131 +0,0 @@ -NOTE: VMD DOES NOT ALLOW YOU TO VISUALIZE SYSTEMS WITH MANY BONDS ATTACHED - TO EACH ATOM. (IF IT DID, THE RESULTS WOULD BE UGLY ANWAY.) - -HOWEVER THIS MODEL ATTACHES APPROXIMATELY 60 BONDS TO EACH CONDENSIN ATOM. -IN ORDER TO PULL THE CONDENSIN MONOMERS TOGETHER. YOU MUST DELETE THOSE -BONDS (of type "1" or "2") FROM THE "system.data" FILE BEFORE YOU CARRY -OUT THE COMMANDS BELOW. (...And backup your "system.data" file. You'll need -all the bonds when you run the simulations.) - --------------- COLORS --------------- -In order to show how the polymer is distributed along the length of the -cylinder, I recommend to select the -Graphics->Graphical Representations -menu option, and select "Index" from the "Coloring Method" pull-down menu. - -After doing this, you can switch from a red-white-blue scheme, to a -rainbow ("jet") scheme, by selecting the Extensions->Tk Console menu option -and loading the "vmd_colorscale_jet.tcl" file located in the "images" directory. -------------------------------------------- - -First, if you have not done so, download and install VMD: - -http://www.ks.uiuc.edu/Research/vmd/ -http://www.ks.uiuc.edu/Development/Download/download.cgi?PackageName=VMD - - - ------- To view a lammps trajectory in VMD -------- - -The system coordinates are initialy stored in a LAMMPS' ".data" file. -(If that file was built with moltemplate, it will be named "system.data".) - -The first step is to view that file. -Then you should create a ".psf" file -(The .psf file is necessary after you run the simulation - for viewing trajectories.) - -1) Build a PSF file for use in viewing with VMD - -a) Start VMD -b) Menu Extensions->Tk Console -c) Enter: - -(I assume that the the DATA file is called "system.data") - - topo readlammpsdata system.data full - animate write psf system.psf - -You will see a snapshot of the system on the screen. -(presumably the initial conformation at t=0) - -2) - -Later once you have run a simulation, -to Load a trajectory in VMD: - - Start VMD - Select menu: File->New Molecule - -Browse to select the PSF file you created above, and load it. - (Don't close the window yet.) - -Browse to select the trajectory file - (It usually has names like "traj.lammpstrj". It depends on how you saved it.) - If necessary, for "file type" select: "LAMMPS Trajectory". - (However VMD should recognize the file type by the file extension.) - Load it. - - - - - -##################### PERIODIC BOUNDARY CONDITIONS ##################### - If you are only simulating a single molecule and you are not - using periodic boundary conditions, then ignore everything below. -######################################################################## - - ---- A note on trajectory format: ----- -If the trajectory is the standard LAMMPS format, (aka a "DUMP" file with -a ".lammpstrj" extension), then it's a good idea when you run the simulation -to tell LAMMPS you want to store the information needed for showing periodic -boundary conditions. (Even if you are not using periodic boundaries. -It never hurts to include a tiny bit of extra information.) To do that, -I've been using this command in my LAMMPS scripts to create the trajectories: - - dump 1 all custom 5000 traj.lammpstrj id mol type x y z ix iy iz - -(Also: it's a good idea to use an atom_style which supports molecule-ID numbers -so that you can assign a molecule-ID number to each atom. I think this is needed -to wrap atom coordinates visually without breaking molecules in half. Again -you don't need to worry about this if you are not using periodic boundaries.) - - -3) ----- Wrap the coordinates to the unit cell - (without cutting the molecules in half) - -a) Start VMD -b) Load the trajectory in VMD (see above) -c) Menu Extensions->Tk Console -d) Try entering these commands: - - pbc wrap -compound res -all - pbc box - - ----- Optional ---- - Sometimes the solvent or membrane obscures the view of the solute. - It can help to shift the location of the periodic boundary box - To shift the box in the y direction (for example) do this: - - pbc wrap -compound res -all -shiftcenterrel {-0.5 -0.5 -0.5} - pbc box -shiftcenterrel {-0.5 -0.5 -0.5} - - Distances are measured in units of box-length fractions, not Angstroms. - - Alternately if you have a solute whose atoms are all of type 1, - then you can also try this to center the box around it: - - pbc wrap -sel type=1 -all -centersel type=2 -center com - -4) - You should check if your periodic boundary conditions are too small. - To do that: - select Graphics->Representations menu option - click on the "Periodic" tab, and - click on the "+x", "-x", "+y", "-y", "+z", "-z" checkboxes. - -5) Optional: If you like, change the atom types in the PSF file so - that VMD recognizes the atom types, use something like: - -sed -e 's/ 1 1 / C C /g' < system.psf > temp1.psf -sed -e 's/ 2 2 / H H /g' < temp1.psf > temp2.psf -sed -e 's/ 3 3 / P P /g' < temp2.psf > system.psf - -(If you do this, it might effect step 2 above.) diff --git a/tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/images/stage2_interior.jpg b/tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/images/stage2_interior.jpg deleted file mode 100644 index 8765cec85eef46e965adfeecadef653fe18458c4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40803 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

1sTFuJ$+{$7H`Nr#6Hz>Gncgu1kje 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 z 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 diff --git a/tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/images/stage2_interior_rotated.jpg b/tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/images/stage2_interior_rotated.jpg deleted file mode 100644 index 2d46cc6a439b266a63018f7a67def94d3dd1661c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25429 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ອtEqKATYYmWMQ6yNqfMe@&* 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¬ZZPop)5-CpZM7-W(fZ}p3eYenWd_cU4MB5*4F3QzA1@D1 zuLvV*sG8Q-#B#t#jW8SuMi_fJj*l$Q5K+hm_S_EzqF0grmRdDqC~`DzyYc6Us%p@<$Dc264I>4Z=K}W3O_=O}FBoL10tG0Y{Bdk% zY!X1y$>Zjn#M5m6;BM#C?||TBfWTA~$}jv-WA`d1k3n-Y8=ite&+7 zS;sglC?DAI5><=5Ki7TnpxD0f7;%m~Vj(ar6(>ioGsq$Ugh+4ueQ|XaVOV8|=YdW= iq=Z9*(dFXIF(}ThQ!X53<4n16K#PSE` coords.raw - - # Then, build the "system.lt" file - - ./generate_system_lt.py 32768 51 < coords.raw > system.lt - - # 32768 is the number of monomers in the polymer - # (which may be different from the number of coordinates - # in the "coords_orig.raw" file) This number will vary - # depending on how long you want the polymer to be. - # The second argument "51" is the average interval between - # condensin anchors (IE the "loop size" in monomers.) diff --git a/tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/moltemplate_files/README_length_flexibility_details.txt b/tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/moltemplate_files/README_length_flexibility_details.txt deleted file mode 100644 index 1d30ceb170..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/moltemplate_files/README_length_flexibility_details.txt +++ /dev/null @@ -1,57 +0,0 @@ ----- Andrew's comments ---- - -The two-stage model at the end of Naumova et al Science 2013 uses the "30nm-fiber" model, whose details are (somewhat vaguely) described in the supplemental materials section. - -For the 10nm model, - n=128000, - L=200, - U(alpha)=5*(1 - cos(alpha)) - bond_length=1.0 (=10nm) - sigma=1.0 (particle radius = 10nm) - -30nm-fiber model details: -"The 30nm-like fiber was modeled by increasing the volume of each monomer and the amount of DNA represented by each monomer by a factor of 4.25, while keeping other parameters the same at the monomer level." - -I interpret this to mean that, for the 30nm model, - n=128000/4.25~=30117 - L=200/4.25~=47 - U(alpha)=1.17647*(1 - cos(alpha)) (5/4.25=1.17647) -To increase the volume by a factor o 4.25, originally I thought I should increase the "sigma" parameter from 1.0 to 4.25^(1/3)~=1.6198. But I suspect that the bond-lengths between monomers should be fixed at 1.0. If that is the case, then, perhaps I should increase "sigma" from 1.0 to 4.25^(1/2)~=2.061552, and keep the bond-length fixed at 1.0 (which in the units used by thsi paper, corresponds to 10nm). (That would increase the volume of a cylinder of radius "sigma" and length="bond-length" by a factor of 4.25) - bond_length=1.0 (10nm again) - sigma=2.061552 (Yes, this is less than 3.0<-->30nm. See below.) - - - - ---- Excerpts from the Supplemental section of Naumova et al Science 2013 --- - -From p. 18 of the supplemental materials section of Naumova et al Science 2013. - - (This section was probably written by Maxim Imakaev.) - - In vivo, the structure of the chromatin fiber can be complicated and many details remain unknown, particularly in metaphase. Given this uncertainty, we simulated chromatin as a homogeneous “beads-on-a-string†polymer fiber. We consider a 10nm fiber, as the pervasiveness of the 30nm fiber in vivo has become increasingly contested. In our simulations, 77Mb is represented by a densely-packed 10nm fiber of 128,000 monomers. Each monomer represents a 10nm-sized DNA-histone complex containing 3 nucleosomes (around 600bp). The fiber has a persistence length of 4 monomers (~2.4Kb), which is based on earlier estimates of 5-10 nucleosomes for interphase (14). Those estimates arise from the assumption that 5-10 linker DNA fragments, each of 20-40bp, can collectively provide flexibility equal to that of the 150bp persistence length of DNA. Binding of proteins to the linker DNA (e.g. histone H1) and interactions between neighboring nucleosomes can further constrain dynamics, requiring more linkers to provide the persistence length. Due to the tight packing of nucleosomes in metaphase, we use the upper limit of this range, i.e. 12 nucleosomes. - For the consecutive loops on a scaffold model (the final folded state model with the best agreement with Hi-C data), we also performed simulations with a more flexible 10nm fiber, or with a 30nm fiber, and found similar results. The more flexible 10nm fiber was modeled by decreasing persistence length to 1.8 monomers. The 30nm-like fiber was modeled by increasing the volume of each monomer and the amount of DNA represented by each monomer by a factor of 4.25, while keeping other parameters the same at the monomer level. We note that a classic model of a 30nm fiber is much less dense than a compact metaphase chromosome. A textbook model of a 30nm fiber assumes packing of about 6 nucleosomes per 10nm of fiber length. This model predicts that only 28% of the volume of the fiber (a 30nm-diameter cylinder) is occupied by nucleosomes, assuming a nucleosome shell volume of 328 nm^3. This is much less than the estimated 30-50% density of nucleosomes in a metaphase chromosome, assuming a diameter of 600nm, a packing density of 50-70 Mb/um, and the same nucleosome volume. (See also (15), which gives an estimate of 0.14-0.18 pg/μm for DNA only, and would give about twice the density if DNA is counted with nucleosomes). As follows, these fibers would have to interdigitate, and fill in gaps within each other. We account for this overlap by assuming the effective diameter of the fiber to be less than 30nm. The effective diameter was chosen to make the volume of the fiber equal the total volume of all the nucleosomes. - - We accounted for topoisomerase II activity by allowing chromatin fibers to pass through each other, while still having excluded volume interactions. This was achieved by using a soft-core Lennard-Jones potential with 1kT energy cost for monomer overlap (see below). This allows for changes in the topological state of a chromosome that are known to occur during compaction in vivo. - -Our simulations of a two-step folding process show that Hi-C data for mitotic chromosomes is consistent with a linearly compressed array of consecutive chromatin loops. Whereas mechanisms for formation of consecutive chromatin loops have been proposed, the process of axial compression is less understood. Chromatid compression cannot be accomplished by increased chromatin-chromatin affinity alone, as this would lead to condensation into a globular geometry (14, 16, 17). However, mechanisms which locally compress the fiber of loop bases naturally allow for anisotropic compression into a shorter and thicker fiber, with the same width regardless of chromosome length (18). Differences in the duration or efficiency of the first and second stages of chromosomal condensation provide a natural mechanism for condensation-related proteins to separately affect mitotic chromosome length and width (19). We also note that the axis of loop-bases in our two-stage model does not necessarily form a continuous and rigid scaffold (Figure S26). As follows, we remain agnostic about the molecular details of the chromosomal scaffold, which might for example be formed by a network consisting of protein-protein and/or protein-DNA interactions (20). - - 1. Polymer simulations - - To perform Langevin dynamics polymer simulations we used OpenMM, a high-performance GPU-assisted molecular dynamics API (21, 22). To represent chromatin fibers as polymers, we used a sequence of spherical monomers of 1 unit of length in diameter. Here and below all distances are measured in monomer sizes, set to be 10nm unless specified otherwise. Neighboring monomers are connected by harmonic bonds, with a potential U = 100*(r - 1)^2 (here and below in units of kT). Polymer stiffness is modeled with a three point interaction term, with the potential U = 5*(1 - cos(alpha)), where alpha is the angle between neighboring bonds. All monomers interact via either a shifted Lennard-Jones (LJ) repulsive potential, or an attractive Lennard-Jones potential. At high densities in a confined volume, the details of the inter-monomer interactions become negligible due to screening (23), and we therefore used the computationally efficient shifted LJ potential. The shifted LJ potential allows for a short-range repulsion by truncating the LJ potential at its minimum and shifting the minimum to zero: U = 4 * (1/r^12 - 1/r^6) + 1, for r<2^(1/6); U=0 for r > 2^(1/6). The shifted LJ potential is one of the most computationally efficient repulsive potentials due to a very short cutoff radius. - - To allow chain passing, which represents activity of topoisomerase II, we softened the shifted LJ potential by truncating the interaction energy at Ecutoff = 1 kT. At energies more than 0.5 Ecutoff, the LJ potential was softened via: Usoftened = 0.5 * Ecutoff * (1 + tanh(2*U/Ecutoff - 1)). To avoid numerical 19instabilities in the calculation of U at r ~ 0, the interaction radius r was truncated at r=0.3 via: rtruncated = (r^10 + (0.3)^10)^0.1, which introduced negligible shift in a final softened potential. For an attractive LJ potential, we used: U = 4 * e * (1/r^12 - 1/r^6), with e = 0.46 kT, slightly below the theta-temperature. The attractive potential was similarly softened at 2 kT and cut off at r=2.5. Unless noted, we used a softened shifted LJ repulsive potential. - - Polymer models were visualized using Pymol and Rasmol. For images with loop bases highlighted, a base of each loop and 3 monomers surrounding it in each direction were labeled in red. - - SECTIONS 2-5 SKIPPED - -6. Two-stage process: linear compaction - axial compression - -To simulate the two-stage process of metaphase chromosome folding, we used the 30nm fiber representation described above for its computational efficiency. Simulations were initialized from 30000 monomer fractal globule conformations; fractal globule is a model for interphase chromatin organization. First, random consecutive loops with L=100 monomers (see above) were introduced, and anchors of neighboring loops were brought together using harmonic springs with a potential U = k * (r – r0)2; r0=0.5. To avoid abrupt motion of the loop anchors, the force was gradually turned on over the first -300000 timesteps, with k linearly increasing in time from 0 to 10 kT. We used softened shifted repulsive LJ potential for inter-monomer interaction. - -Upon completion of linear compaction, axial compression was initiated. This involves following changes: the repulsive LJ force is replaced with an attractive LJ force for all monomers, and the chromosomal core of loop anchors is homogeneously compressed. To achieve the latter, all anchor pairs separated by less than 30 anchors were attracted via a potential U = step(d-3) * abs(d-3) * 10 kT, which implements a constant attractive force between two anchors if they are separated by a distance larger than 3. The interactions between neighboring loop anchors were kept throughout this process. - -To obtain the contact map from this simulation, 50 independent runs of 1.5e7 timesteps were performed, and 250 conformations were collected from the second half of each run. The contact map was calculated from all conformations of all runs at a 30-monomer resolution, and was further averaged over three 10000-monomer blocks along the diagonal of the heatmap. The latter was done to show contact map at a relevant length scale (0 to 25 Mb), and to achieve a better averaging of the contact map. - diff --git a/tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/moltemplate_files/calc_table.sh b/tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/moltemplate_files/calc_table.sh deleted file mode 100755 index aed66719f0..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/moltemplate_files/calc_table.sh +++ /dev/null @@ -1,8 +0,0 @@ - - -for ((i=0; i<60; i++)); do echo "$((i+1)) " `echo "$i*0.05" | bc` 0 0; done - -echo 61 3.0 0 -5 - -for ((i=61; i<=4000; i++)); do echo "$((i+1)) " `echo "$i*0.05" | bc` `echo "($i-60)*0.5"|bc` -10; done - diff --git a/tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/moltemplate_files/condensin.lt b/tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/moltemplate_files/condensin.lt deleted file mode 100644 index f8dfea089b..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/moltemplate_files/condensin.lt +++ /dev/null @@ -1,47 +0,0 @@ -# This file contains the definition of a molecule named "CondensinMonomer". -# (This particular molecule contain only one atom, but that is up to you.) -# Later, multiple CondensinMonomers can be connected together to build a molecule. - - - -CondensinMonomer { - - # atom-id mol-id(ignore) atom-type q x y z - - write("Data Atoms") { - $atom:a $mol @atom:A 0.000 0.00000 0.00000 0.00000 - } - - # (The x y z positions will be changed later with move commands - # You can spedify charge and other properties by changing the atom_style.) - - - - # atom-type mass - - write_once("Data Masses") { - @atom:A 1.0 - } - - # pairwise interactions (between non-bonded atoms): - # - # U(r) = 4*eps*((r/sig)^12 - (r/sig)^6) - # - # Note: when sigma=0.8908987181403393=2^(1/6), the minimia is at r=1.0 - # - # atom-type atom-type pair_style epsilon sigma - - write_once("In Settings") { - # I usually use sigma = 2^(-(1/6)), with a cutoff of 1 - #pair_coeff @atom:A @atom:A lj/cut 1.0 0.8908987181403393 1.0 - # In the 2013 Science (metaphase) paper, Imakaev used sigma=1.0 - # with a cutoff of 2^(1/6). Here we are trying to reproduce his results. - # 10nm fiber - #pair_coeff @atom:A @atom:A lj/cut 1.0 1.0 1.122462048309373 - # 30nm fiber (4.25^(1/2)=2.0615528128088303) - #pair_coeff @atom:A @atom:A lj/cut 1.0 2.0615528128088303 2.314014792963349 - # 30nm fiber (4.25^(1/3)=1.6198059006387417) - pair_coeff @atom:A @atom:A lj/cut 1.0 1.6198059006387417 1.8181706490945708 - } - -} # CondensinMonomer diff --git a/tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/moltemplate_files/coords_orig.raw b/tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/moltemplate_files/coords_orig.raw deleted file mode 100644 index 9137c70616..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/moltemplate_files/coords_orig.raw +++ /dev/null @@ -1,32768 +0,0 @@ --25.8563 0.5868639 -10.5686 --26.7104 0.5123159 -10.988 --26.6472 -0.3489721 -10.3989 --27.477 0.09032793 -9.96323 --27.5656 0.5432849 -9.07679 --26.9532 1.30193 -9.02479 --27.7767 1.68179 -8.50491 --28.3972 2.40457 -8.91213 --28.6132 3.17136 -9.43966 --29.5915 2.93084 -9.73989 --29.9486 2.90331 -8.78678 --29.5668 3.82558 -8.58056 --29.4603 4.69627 -9.07626 --29.3895 5.66981 -9.03451 --30.1683 5.95262 -9.57885 --29.7252 6.82771 -9.62399 --29.3815 6.72967 -10.6049 --29.3359 7.11535 -11.5251 --28.6608 7.01853 -12.2411 --29.4269 7.23933 -12.8807 --28.8974 7.95352 -13.1355 --28.0615 8.41522 -13.369 --28.0899 7.83209 -14.2049 --28.9177 7.60378 -14.7609 --28.5783 7.72824 -15.6631 --28.8091 8.6176 -15.7699 --27.8292 8.72143 -15.4435 --27.0719 9.11061 -15.8328 --27.6533 9.78633 -16.3367 --27.7805 10.078 -15.4008 --27.4267 11.0102 -15.2806 --26.759 11.2425 -15.9727 --25.8124 10.7779 -16.0688 --25.9429 9.74176 -16.1052 --25.4567 8.84701 -16.0595 --25.0517 8.38721 -16.808 --24.4227 9.04521 -17.207 --23.8866 9.76185 -17.5133 --24.3909 10.0475 -16.6904 --25.0046 9.89792 -16.0027 --24.2884 10.043 -15.2759 --23.7492 10.8581 -14.9341 --23.4663 10.2023 -14.2305 --22.567 9.78524 -14.4336 --22.3801 10.3667 -13.6503 --22.207 11.2232 -14.0766 --22.1804 11.7239 -14.9411 --21.7644 12.6471 -14.7781 --20.9193 12.8327 -14.2212 --20.6343 13.0464 -15.1856 --20.0922 13.5451 -14.5286 --19.2983 13.914 -15.0082 --19.4023 13.0675 -15.5298 --18.5232 13.3107 -15.1504 --18.7586 12.7611 -14.334 --18.131 13.2514 -13.8647 --17.6729 12.5626 -13.1865 --16.7235 12.2766 -12.9417 --16.4151 12.9808 -12.2597 --16.515 12.6115 -11.3464 --17.2797 13.2961 -11.2699 --18.0935 13.8348 -11.2771 --19.1087 14.0856 -11.266 --20.0859 13.9469 -11.2803 --20.6702 13.1886 -11.171 --21.1132 13.6779 -10.4824 --20.7554 14.0923 -9.66475 --20.0092 13.3717 -9.46904 --20.2154 12.4286 -9.67692 --20.3212 12.0637 -10.6268 --20.6477 11.3656 -11.2997 --19.6829 11.205 -11.3344 --19.8476 11.8356 -12.123 --20.6059 11.9227 -12.7203 --19.6468 11.9213 -13.2611 --19.1986 11.5456 -14.0954 --19.4092 11.422 -15.1036 --18.97 10.6398 -15.5632 --19.2307 10.3891 -16.4246 --19.7998 9.63451 -16.5879 --19.0267 9.23752 -17.0947 --18.9718 8.51511 -16.4976 --18.5581 8.14381 -15.6756 --17.8601 8.72615 -16.1132 --16.8864 8.95457 -16.1283 --17.2573 8.65394 -17.0059 --16.8834 8.877 -17.9317 --16.9804 7.93611 -17.8517 --16.3517 7.18904 -18.1058 --15.44 7.46366 -18.4049 --14.6079 8.00931 -18.3901 --13.993 7.99908 -19.2032 --14.6716 7.33714 -19.1401 --15.2908 6.5047 -19.3095 --15.7928 5.64885 -19.0565 --14.9593 5.79763 -18.5547 --14.8818 5.10065 -19.2857 --14.9343 4.63209 -20.1751 --14.819 3.75787 -19.7859 --14.9014 2.77884 -19.7258 --15.8254 2.34137 -19.8546 --16.7518 2.11938 -19.9102 --17.2858 1.38873 -19.6316 --17.6051 2.23194 -19.3101 --17.4759 2.2122 -18.2935 --16.555 1.90863 -17.996 --16.3599 1.18543 -17.2873 --16.6597 0.2817609 -17.0068 --17.4192 -0.1762871 -16.5829 --17.5676 0.3030899 -15.6993 --18.4786 0.2816979 -16.1894 --19.3873 -0.03042487 -15.8965 --19.1305 -0.9198991 -16.3767 --18.8053 -1.89678 -16.5631 --17.8952 -2.29912 -16.367 --17.881 -1.7091 -15.4693 --18.034 -2.7152 -15.2978 --17.6676 -3.55164 -14.8756 --16.7023 -3.52134 -15.1619 --15.9315 -4.17398 -15.1337 --15.0123 -4.0393 -14.7833 --14.3289 -4.18259 -14.1178 --14.8199 -3.5703 -13.5025 --14.0673 -3.45279 -12.9118 --13.8652 -2.4677 -12.6746 --14.7013 -2.51433 -12.1349 --14.7591 -1.57501 -12.6047 --14.3849 -0.7913011 -12.8965 --15.0335 -0.6417921 -12.0814 --15.9264 -1.16147 -11.9717 --15.4966 -1.75734 -11.2786 --16.3186 -1.89513 -10.7004 --17.3447 -1.99074 -10.7706 --16.8078 -2.28381 -11.5947 --17.5234 -2.81286 -12.0644 --18.1535 -2.10741 -11.7565 --19.0461 -2.18436 -11.3109 --18.9286 -1.33458 -11.7392 --18.6673 -1.3773 -12.7462 --18.9847 -2.20517 -13.2055 --19.0146 -1.52805 -13.9914 --19.5602 -1.22894 -14.7766 --19.9174 -0.6614531 -13.9545 --19.3542 0.1054139 -14.1998 --20.0903 0.7562789 -14.2155 --20.2834 1.58939 -14.6348 --19.7527 2.45077 -14.9298 --20.7223 2.72193 -15.1458 --20.74 2.42061 -15.9961 --19.8152 2.19964 -16.3204 --18.971 2.3405 -15.7096 --18.6579 3.23116 -16.186 --17.7978 3.59352 -16.3547 --16.97 4.12994 -16.4791 --16.5011 3.5915 -15.7777 --16.0202 3.89081 -14.8962 --15.6429 3.25724 -14.3553 --14.7397 3.4752 -14.0485 --14.7642 3.81665 -13.1634 --14.4103 3.11518 -12.5644 --14.1883 3.73765 -11.7934 --14.3687 4.55216 -11.3856 --14.3268 4.88789 -12.3038 --15.1957 5.38065 -12.2756 --15.6408 5.01672 -13.0703 --15.754 4.13848 -12.5652 --16.3934 3.81218 -11.8968 --17.3731 3.98553 -11.5679 --17.384 4.61053 -12.3523 --17.0088 4.58629 -13.3268 --16.9114 5.16535 -14.0992 --16.9721 4.49621 -14.7963 --17.4023 3.56368 -14.6457 --18.2437 3.01085 -14.8456 --18.9477 3.16093 -14.2124 --19.6747 3.18298 -13.6077 --19.7802 2.66669 -12.7379 --20.4554 2.80231 -11.9906 --20.4431 2.28754 -11.1622 --21.1143 2.59765 -10.4807 --20.9793 1.72854 -10.0128 --21.0842 1.50483 -11.0246 --20.9463 1.76967 -12.0029 --21.5215 1.65595 -12.8724 --20.7484 1.53806 -13.5953 --21.5147 1.8493 -14.0826 --22.1459 1.33063 -14.7072 --22.9431 1.84812 -14.4744 --22.7432 1.55197 -13.5012 --22.5353 0.9422309 -12.7665 --23.4761 0.6851639 -12.5404 --23.8994 1.26011 -11.8804 --24.8117 1.00207 -12.25 --24.7453 0.6228869 -11.2856 --24.4099 1.46353 -10.7859 --24.2156 1.08345 -9.92118 --23.9937 2.01383 -9.72414 --23.8821 1.55967 -8.80694 --23.1616 1.83299 -8.1557 --22.9368 0.9799999 -7.79402 --22.7938 1.01153 -6.77103 --22.282 1.33482 -6.03303 --21.7229 1.39943 -6.76258 --21.5632 2.28103 -7.17858 --22.1153 2.04263 -7.95071 --21.1521 1.81223 -7.9383 --20.2267 1.89201 -7.51006 --20.4022 2.54211 -8.20325 --20.1076 3.39324 -7.89601 --19.5829 3.63982 -7.07314 --20.4682 4.13108 -7.05735 --21.4609 4.07088 -7.26429 --22.4326 4.22327 -6.95141 --22.893 4.43111 -6.15759 --23.7141 4.5535 -5.56708 --23.7779 5.31258 -6.18703 --23.8107 5.5558 -5.2089 --24.1892 5.16575 -4.31158 --24.2642 4.19842 -4.181 --24.2279 3.45123 -4.79567 --23.4687 2.77491 -4.99256 --23.0143 2.26585 -4.25556 --22.2432 2.16176 -4.87894 --21.7419 1.2533 -4.75704 --22.0968 1.21416 -3.8024 --22.7806 0.5350559 -4.01422 --23.6328 0.2559729 -4.35221 --24.0303 -0.3617141 -3.7317 --24.9241 -0.5948691 -3.83129 --25.6046 -1.01985 -4.47234 --26.5494 -0.6524121 -4.43946 --26.4332 -0.2285731 -3.51306 --26.922 0.4146309 -3.98824 --26.4263 0.8423219 -3.24398 --25.4875 0.9672159 -3.0102 --24.7855 0.3162459 -3.03382 --24.9032 -0.1652891 -2.20006 --24.1983 0.3436869 -1.65527 --24.2367 -0.1167971 -0.8324459 --23.3077 -0.04702097 -0.4668039 --23.1737 -0.7292341 0.2001991 --22.5559 -1.46595 0.4460061 --21.577 -1.35345 0.2161661 --20.8363 -1.9097 -0.1096419 --20.7858 -1.61539 -1.07873 --21.4913 -2.36956 -0.8332489 --22.0615 -1.61814 -1.21159 --22.6785 -1.58587 -2.02932 --22.7663 -2.63773 -2.08106 --23.7854 -2.85467 -2.09393 --24.4557 -2.43234 -2.47204 --25.0568 -1.88463 -3.05873 --25.9844 -1.50836 -2.92654 --26.2935 -2.2406 -3.56529 --25.8251 -2.26259 -4.43451 --26.2848 -2.88835 -5.07604 --25.5881 -2.8131 -5.77061 --25.9173 -1.98419 -5.91531 --25.277 -2.31206 -6.55531 --24.5189 -1.64248 -6.34188 --24.4214 -0.9918181 -7.13427 --24.1118 -0.7030901 -8.02954 --23.5344 -0.8902171 -8.84978 --22.9726 -1.68293 -8.90733 --22.2013 -1.96503 -9.50532 --21.3167 -2.39383 -9.55061 --20.3198 -2.15525 -9.52206 --19.4324 -2.51221 -9.13619 --19.1059 -2.8896 -10.0447 --19.506 -3.69665 -10.5051 --20.3179 -4.18677 -10.3733 --21.1743 -4.01533 -10.9126 --21.298 -4.49088 -11.774 --20.2387 -4.52844 -11.5665 --20.025 -5.19714 -12.1984 --20.0741 -5.31846 -13.2354 --20.1441 -4.34337 -13.4481 --20.4303 -4.25003 -14.3514 --21.0711 -3.57061 -14.0453 --21.8848 -3.75512 -13.5328 --22.8333 -3.96238 -13.6698 --23.0963 -4.29805 -12.7972 --23.897 -4.26723 -12.2585 --23.7472 -3.32062 -12.0912 --24.039 -2.43183 -11.8307 --24.1953 -1.43199 -11.9438 --23.5045 -1.71444 -12.517 --22.8381 -1.75465 -11.8201 --21.9794 -1.50973 -11.4719 --21.3081 -2.27073 -11.6703 --21.4259 -1.65348 -12.4337 --21.4072 -0.6430501 -12.7374 --21.2197 -1.15077 -13.5402 --21.4653 -1.61533 -14.3711 --21.678 -2.3134 -15.1053 --21.761 -1.80632 -15.8858 --22.3001 -2.39992 -16.4375 --21.8204 -3.30329 -16.4608 --22.7742 -3.17108 -16.1462 --23.0109 -4.12131 -16.396 --22.8974 -4.42068 -17.3218 --22.1833 -3.684 -17.5638 --22.0104 -2.63463 -17.5245 --22.3573 -1.72001 -17.4698 --22.6746 -1.38056 -18.3316 --21.701 -1.1273 -18.1019 --21.3841 -0.2681041 -17.7462 --20.8202 0.5212819 -17.5229 --20.7075 0.6440079 -16.5444 --20.3167 -0.3074361 -16.4489 --20.5917 -0.8066811 -15.6528 --20.3695 -1.45208 -16.4174 --20.322 -1.19686 -17.4115 --19.4338 -0.8807341 -17.9648 --18.7188 -1.56991 -17.9256 --18.0042 -2.10615 -18.4145 --17.217 -1.69111 -18.8235 --16.2306 -1.41386 -18.5311 --16.7092 -0.9373331 -17.9111 --16.4979 -1.22498 -16.9822 --15.8415 -0.7155781 -16.33 --16.0524 -1.64982 -16.0909 --16.0128 -1.34105 -15.1715 --15.6615 -2.09726 -14.6692 --15.7354 -1.26878 -14.055 --16.0778 -2.01875 -13.5013 --15.9748 -3.09989 -13.4163 --16.1937 -4.0262 -13.2199 --15.4769 -4.06166 -12.555 --15.7424 -4.9739 -12.405 --14.9714 -4.94772 -13.0002 --15.3565 -4.93115 -13.9477 --16.1099 -5.42589 -14.4363 --15.6769 -6.23915 -14.6239 --15.246 -5.98584 -13.7634 --14.6791 -5.83302 -14.4935 --14.4311 -5.99171 -15.4273 --13.591 -6.59059 -15.5913 --12.9453 -7.1745 -16.1371 --12.568 -6.26884 -16.5108 --11.6704 -6.64677 -16.5889 --11.2363 -6.5454 -15.7211 --10.6347 -5.81869 -15.9475 --10.0673 -5.08615 -15.5708 --9.45484 -4.91716 -14.7951 --8.75531 -4.93882 -14.1485 --8.40791 -4.1225 -14.7833 --9.14234 -3.81697 -14.2233 --9.77868 -4.5475 -13.8726 --10.0638 -4.62782 -12.9383 --10.4512 -3.63414 -12.8536 --11.0145 -3.87285 -11.9944 --10.0697 -3.81642 -11.6787 --9.31059 -4.30305 -11.26 --9.60032 -5.16846 -10.8412 --9.34082 -6.08307 -11.3031 --10.0144 -6.29671 -11.9917 --10.9442 -6.62142 -11.6513 --10.6611 -6.17844 -10.747 --11.6936 -6.10385 -10.6628 --11.5512 -6.26953 -9.73332 --12.0704 -7.02388 -9.51283 --11.4924 -7.47781 -10.1873 --11.1993 -7.43765 -11.1675 --12.1786 -7.27366 -10.9058 --13.1519 -7.2406 -10.5898 --13.6418 -7.28857 -11.4881 --13.5321 -8.25764 -11.6171 --14.2794 -8.84029 -11.7908 --13.6941 -8.99123 -12.5348 --14.1924 -9.78237 -12.7769 --14.6249 -10.3013 -13.5206 --14.3375 -11.2162 -13.6007 --13.5142 -11.1185 -14.1652 --12.5665 -11.3487 -14.1106 --11.8236 -11.9771 -14.3079 --11.394 -11.8163 -15.2164 --12.2585 -11.5803 -15.5423 --12.0044 -12.1814 -16.2783 --12.116 -11.7947 -17.174 --11.8405 -10.7974 -16.9867 --11.4812 -10.1428 -17.6056 --12.0887 -10.7471 -18.0865 --12.3105 -10.9978 -19.0697 --11.4504 -11.527 -18.9875 --10.5527 -11.2132 -19.4602 --10.5049 -10.2766 -19.2505 --10.4926 -10.2592 -18.2383 --9.96593 -9.93874 -17.4711 --8.98651 -10.233 -17.2828 --8.23076 -10.7276 -16.8663 --7.69255 -11.5365 -16.4764 --7.04511 -10.9534 -16.9666 --7.57158 -10.5399 -17.6979 --7.3741 -10.7509 -18.6718 --7.95722 -10.6033 -19.4512 --8.4977 -10.7575 -20.3146 --8.9983 -11.6007 -20.4842 --8.85562 -11.3792 -21.4364 --8.02492 -10.9297 -21.2218 --7.10975 -11.2055 -21.0615 --6.36105 -10.565 -20.9116 --7.07769 -9.84954 -20.876 --7.5931 -9.45155 -21.6635 --8.37761 -9.79051 -22.2354 --8.40777 -10.5986 -22.9075 --7.50114 -10.7609 -23.3428 --8.27201 -10.6911 -23.9728 --8.51983 -11.2028 -24.8071 --9.50126 -11.468 -25.0398 --9.8036 -10.5247 -25.2166 --9.80368 -11.1068 -26.0207 --9.06524 -11.337 -26.6722 --8.25793 -10.6206 -26.4318 --8.30776 -9.93345 -25.697 --8.54232 -9.00526 -25.8649 --8.68932 -8.4119 -25.0727 --9.11495 -7.70466 -25.6204 --8.89314 -6.76075 -25.8332 --9.63848 -6.21479 -25.4451 --9.90435 -5.35585 -25.9436 --10.286 -4.89325 -26.7268 --10.0949 -4.03774 -27.2203 --10.5785 -3.15085 -27.5332 --10.3264 -2.18899 -27.3749 --11.3071 -1.83547 -27.477 --11.0284 -2.1312 -28.4142 --10.5218 -2.40206 -29.2192 --11.4386 -2.85941 -29.2217 --11.7134 -2.42087 -30.0074 --12.5133 -2.94645 -30.3289 --13.3245 -3.45081 -30.1944 --12.6231 -3.87517 -29.6183 --13.2653 -4.14952 -28.9035 --13.5664 -3.70777 -28.0554 --14.3033 -3.36063 -27.4786 --14.5378 -3.87703 -26.5963 --15.5347 -3.94854 -27.021 --15.43 -2.90776 -26.9528 --15.0983 -2.34711 -27.7501 --15.8232 -2.5726 -28.3329 --16.691 -3.08293 -28.5635 --17.0077 -2.91261 -27.6673 --17.9846 -3.26305 -27.8179 --18.8816 -2.96541 -27.3956 --19.8258 -3.00054 -27.4892 --20.2731 -3.6932 -26.974 --21.0432 -3.71531 -26.4228 --22.0423 -3.58205 -26.3708 --22.2475 -4.41891 -26.9783 --22.7614 -3.68557 -27.1679 --23.3486 -2.99866 -26.6913 --23.3934 -3.3804 -25.8036 --24.3682 -3.6321 -25.579 --24.1188 -4.22707 -26.379 --25.0067 -3.70569 -26.4685 --24.3258 -3.06929 -26.4077 --24.7793 -2.28548 -26.1638 --23.8414 -1.85395 -26.3087 --24.1964 -1.43747 -25.4912 --24.2769 -1.18498 -24.5353 --24.4843 -0.2016161 -24.593 --23.5664 0.3086119 -24.5668 --23.2719 -0.3460051 -23.9883 --22.4987 -0.8680051 -23.4815 --22.1155 -1.4125 -22.7351 --22.784 -1.16018 -22.0382 --23.6298 -1.76748 -22.0793 --23.8022 -1.47638 -23.0535 --24.5079 -2.10188 -22.6156 --25.2085 -2.8521 -22.6358 --25.6327 -3.43621 -21.8898 --24.6709 -3.66382 -21.8703 --24.1058 -4.3945 -22.2365 --24.6879 -4.2968 -23.0118 --23.8328 -3.80287 -23.1386 --23.0237 -3.57034 -22.5497 --22.3468 -3.92298 -23.2242 --21.5371 -4.25193 -22.6711 --20.7385 -3.72843 -22.3017 --19.7313 -3.73469 -22.1907 --19.7719 -3.03947 -22.8797 --20.609 -2.94401 -23.3899 --21.5685 -2.7852 -23.3197 --21.9797 -2.04976 -23.7793 --21.1369 -1.83748 -24.2499 --20.3198 -1.39421 -23.8686 --19.9618 -0.4840651 -23.5973 --20.3029 -0.4283571 -22.7109 --19.3745 0.003753084 -22.7948 --18.5246 -0.06300757 -22.2009 --18.403 0.7198969 -22.7784 --19.0691 0.9318659 -23.5268 --19.9428 1.32639 -23.8487 --19.7276 1.94972 -24.6686 --19.4553 0.9763519 -24.8638 --19.6463 0.1258659 -25.2377 --19.7933 -0.1393001 -26.2108 --18.9664 -0.8306961 -26.3255 --19.0494 -0.9137051 -25.4034 --18.3153 -1.50045 -25.7667 --18.6257 -1.68272 -24.7786 --17.7605 -1.82306 -24.4216 --17.5338 -1.06268 -23.7354 --16.9073 -1.14972 -22.9642 --16.1363 -1.66513 -22.7661 --15.9561 -0.7064121 -22.7082 --15.1493 -0.1638731 -22.8609 --14.1708 0.1030579 -22.998 --13.5673 0.4471589 -23.6569 --13.1588 0.6514069 -24.5773 --13.8787 1.32222 -24.9563 --13.6371 1.7181 -25.8494 --13.4406 1.16625 -26.6492 --13.9156 1.4352 -27.4876 --14.3891 0.5685549 -27.7966 --14.412 0.1471539 -26.8736 --13.4903 -0.1858781 -26.9779 --13.7806 -0.3997161 -27.9497 --12.7852 -0.6466661 -28.164 --12.7712 0.2598879 -27.6997 --11.971 0.9045509 -27.9052 --11.4918 1.75427 -28.0334 --10.9562 1.77833 -28.9214 --11.2952 2.46877 -29.5439 --11.7232 3.33069 -29.3916 --12.5304 3.06653 -28.8165 --12.0592 3.28713 -28.0584 --12.7883 3.08135 -27.4393 --13.6429 2.6475 -27.1292 --14.2345 2.51575 -26.3703 --15.1804 2.17383 -26.4581 --15.9157 1.91143 -27.1101 --16.1481 0.9636179 -26.8481 --16.9105 0.7018659 -26.2791 --16.4335 0.2572729 -25.5955 --15.5872 0.3805739 -26.1178 --14.8654 1.01253 -25.9001 --14.5621 0.2318229 -25.3964 --14.0702 -0.4297191 -24.746 --13.0937 -0.8027531 -24.8256 --13.4949 -0.7447681 -25.7676 --14.4473 -0.9047931 -25.8069 --15.0988 -1.27633 -25.1426 --16.1185 -1.44734 -25.2172 --16.7215 -1.13494 -26.024 --17.0873 -0.6425631 -26.7745 --16.1534 -0.5712581 -27.136 --15.9354 -0.9912921 -28.0354 --16.2302 -1.0986 -28.9917 --15.3606 -0.7399631 -29.0913 --15.4607 0.1021469 -29.5757 --15.4081 1.0926 -29.7703 --15.683 1.97354 -29.3951 --16.7075 1.89867 -29.3432 --17.376 1.78135 -28.6269 --17.31 2.02941 -27.6077 --16.8212 2.83513 -27.1585 --16.8788 2.02027 -26.6443 --17.0923 2.50362 -25.7796 --17.6422 1.7203 -25.5951 --18.4417 1.81351 -25.0321 --17.8929 2.43164 -24.5866 --17.8667 3.29302 -24.8957 --17.069 3.68208 -24.5792 --16.1049 3.79114 -24.7344 --15.9806 4.48272 -25.4426 --15.5136 4.97326 -26.185 --15.2777 5.95951 -26.1206 --15.7975 6.47755 -25.3934 --14.9728 7.0361 -25.6069 --15.0511 7.9821 -25.3925 --14.7347 8.11099 -24.4858 --15.0234 8.28564 -23.62 --14.5984 7.62586 -23.0384 --13.8575 7.17583 -23.5805 --13.6437 6.5699 -24.3299 --14.3268 5.99542 -23.9076 --13.786 5.83896 -23.1077 --13.85 5.42903 -22.2 --13.5308 4.75701 -21.5152 --13.3157 5.44949 -20.8592 --12.7238 5.94298 -21.494 --12.3516 6.48505 -22.2703 --11.5198 6.70707 -22.6846 --11.8851 7.16386 -23.4582 --12.2304 7.38446 -24.3907 --11.65 8.13018 -24.1328 --11.4788 8.50117 -23.2482 --12.1581 9.21967 -23.3188 --13.0971 9.11135 -23.2279 --13.8029 8.97546 -22.5626 --14.1024 9.58313 -23.2839 --15.0245 9.44259 -23.7292 --15.1087 9.41592 -22.7526 --15.3262 8.96901 -21.8587 --15.0665 8.90728 -20.9134 --15.542 8.90633 -20.0151 --15.8199 8.48343 -19.0673 --15.5289 9.36219 -18.6891 --15.0782 10.1105 -18.2245 --14.4669 9.80677 -17.5089 --14.9014 9.06404 -17.0326 --15.1635 8.15976 -17.495 --14.9351 7.30085 -16.9297 --15.1475 6.98199 -16.0979 --14.7508 7.91614 -15.9661 --15.0764 7.46294 -15.1466 --14.3953 7.41372 -14.4446 --13.8092 6.65822 -14.8363 --13.292 6.4189 -13.9991 --13.2894 5.75966 -13.1682 --12.5019 5.29636 -12.9255 --11.5011 5.2434 -12.7439 --10.7536 4.70814 -13.0932 --10.4187 3.83934 -13.5491 --10.3923 2.95502 -13.2064 --10.7381 2.88137 -14.0818 --11.2661 3.43146 -14.7193 --11.6551 2.9874 -15.4448 --11.5854 3.91449 -15.7018 --11.5552 4.35131 -16.6595 --11.137 4.74654 -17.4655 --10.4221 5.02237 -16.9458 --9.71197 5.12683 -17.6277 --8.83725 4.83988 -17.2381 --8.88538 4.65888 -16.3297 --9.57604 5.35886 -16.1615 --9.13474 5.73116 -15.3628 --9.13042 6.21202 -14.5436 --9.94948 6.79624 -14.6417 --10.8865 6.48214 -14.7772 --11.9544 6.61477 -14.7121 --11.6597 7.00546 -15.5667 --12.4381 6.8123 -16.1907 --12.4057 6.03222 -15.5426 --11.5273 5.64895 -15.8117 --11.532 5.38656 -16.728 --11.591 5.66589 -17.6646 --12.5932 5.53358 -17.379 --12.6347 5.36413 -18.3777 --12.2989 5.81521 -19.1927 --11.6157 5.14812 -19.0257 --11.5948 5.45521 -20.0043 --11.3668 4.52142 -20.1566 --10.4705 4.69271 -19.83 --9.77194 5.40387 -19.7421 --9.77878 6.36477 -19.61 --9.40138 6.20925 -18.6334 --8.58776 6.4536 -18.0963 --7.74504 7.03884 -18.1918 --7.20188 7.76355 -18.6132 --7.7134 8.33719 -17.9293 --7.35443 7.69153 -17.2412 --6.48074 7.20294 -17.0333 --5.91669 6.64721 -17.5466 --5.20684 6.43124 -18.1012 --5.47036 7.30161 -18.5243 --5.54396 8.14056 -19.0888 --4.79284 8.67187 -18.9327 --4.38714 8.86877 -18.1019 --3.76949 9.70272 -18.1709 --4.48128 10.379 -18.5119 --4.79145 10.7156 -19.4329 --5.18038 9.99577 -20.2104 --5.61257 9.8526 -21.0794 --4.93884 9.52865 -21.7385 --5.20249 8.87644 -22.4878 --5.37311 8.60411 -21.4697 --5.7918 7.87792 -20.8753 --6.6202 7.36896 -20.6852 --7.15142 8.29436 -20.9982 --7.05435 9.33876 -21.2149 --7.96668 9.54404 -20.7737 --8.73077 9.70239 -20.0854 --8.47981 10.5871 -19.681 --8.19693 11.5536 -19.5107 --7.80598 11.9031 -20.3831 --7.56485 11.1827 -21.0652 --7.80432 11.8229 -21.7507 --8.03175 12.296 -22.5631 --7.34928 13.2119 -22.5716 --7.98101 13.34 -23.3127 --8.61221 13.7687 -23.9656 --9.54158 13.5263 -24.185 --9.77004 14.527 -24.1728 --9.43491 14.2821 -23.3086 --9.13346 14.3512 -22.3618 --9.36129 15.3342 -22.4936 --8.3367 15.2938 -22.7589 --7.41589 14.9901 -22.3982 --6.66353 14.3231 -22.4849 --6.49007 14.1959 -23.4769 --6.41634 14.2999 -24.4873 --5.6011 13.7938 -24.1463 --5.91981 12.8627 -23.8923 --6.16215 12.0831 -23.2633 --5.81201 12.4721 -22.3599 --5.5599 12.1475 -21.5351 --5.96835 12.2793 -20.6994 --5.00364 11.8383 -20.6168 --4.64198 12.6928 -20.3398 --4.05812 13.1228 -19.741 --3.60403 12.9907 -18.8149 --3.15329 12.2647 -18.2303 --2.30949 12.6965 -18.5033 --2.55074 12.8643 -19.4554 --1.63642 13.1478 -19.8705 --1.3597 13.6129 -19.06 --1.34937 14.3394 -18.3281 --1.35559 13.4486 -17.9689 --1.3002 12.706 -17.2235 --1.05004 13.1238 -16.3434 --1.49723 13.8118 -15.7247 --2.38258 14.3252 -15.9611 --2.99734 13.607 -16.3238 --2.84211 12.7632 -15.7478 --3.36914 12.0644 -16.1572 --3.9657 11.5672 -15.6938 --3.2478 11.832 -14.9438 --2.99585 10.8357 -15.1468 --2.56491 10.1104 -14.5974 --2.40933 9.13073 -14.3786 --3.36063 9.05637 -13.8779 --4.33247 9.27712 -13.7847 --4.99479 9.30484 -14.5985 --4.84807 8.35826 -15.0281 --5.77462 8.03437 -15.4531 --5.99319 8.74293 -14.8063 --6.31852 9.16294 -15.6597 --6.08742 10.0391 -15.8945 --5.91921 10.9666 -15.5192 --5.76961 11.4011 -16.4502 --5.41827 10.9374 -17.211 --4.81489 10.0796 -17.1079 --4.63718 10.9134 -16.5284 --3.82243 10.3758 -16.8657 --2.85741 10.4849 -16.7408 --2.30615 11.3129 -16.5077 --1.81277 11.2645 -17.3607 --0.840396 11.3652 -17.7354 --0.198197 11.9893 -17.2515 --0.01884423 11.3805 -16.4976 --0.752929 11.207 -15.8391 --1.0341 11.3315 -14.905 --0.714034 11.9221 -14.1348 --1.34841 11.8609 -13.3913 --1.63952 12.7005 -12.9051 --2.18417 12.5998 -13.7095 --2.24902 11.5828 -13.3987 --3.23614 11.4275 -13.7107 --3.74989 10.7502 -13.1799 --4.68411 10.8137 -12.7606 --4.92419 9.8593 -12.4386 --5.75549 9.2036 -12.3514 --6.16583 9.80532 -12.9615 --6.20426 10.475 -13.7062 --6.43772 11.0795 -14.4379 --7.20501 10.6198 -14.8933 --8.0165 10.1688 -14.8465 --8.63629 10.1431 -14.0581 --9.25197 10.5659 -14.7338 --8.81672 10.9947 -15.5471 --9.49481 10.3521 -15.8232 --10.2319 9.74245 -16.2206 --9.89958 10.4054 -16.8952 --10.4335 10.4479 -17.7681 --10.67 9.4728 -17.6017 --10.8786 8.53515 -17.8965 --11.7891 8.45758 -18.2489 --11.8777 7.53139 -18.3992 --12.1713 7.42677 -19.3116 --12.6844 7.29423 -20.1393 --11.7842 7.05778 -20.4534 --11.6284 7.96778 -20.7592 --12.5245 8.31246 -21.1789 --12.0089 9.1548 -21.3868 --11.1327 8.89798 -21.0663 --11.0813 9.88473 -20.9762 --11.6194 9.68921 -20.1269 --12.6093 9.71676 -20.2664 --13.6163 9.79655 -20.0931 --13.6504 10.1861 -21.0249 --13.0311 10.9462 -21.3592 --12.5307 10.5681 -22.1415 --11.991 11.4287 -22.2519 --11.2951 10.6241 -22.3841 --10.678 11.4285 -22.3333 --10.2719 11.149 -23.2077 --9.67635 10.4485 -23.6213 --10.4328 10.2984 -22.9904 --10.6665 9.88724 -23.8537 --11.0712 9.38184 -24.644 --10.9614 9.97458 -25.4246 --11.6713 10.5648 -25.7854 --11.4407 11.5036 -25.6859 --12.2005 12.1474 -25.6939 --11.6101 12.8345 -26.2027 --11.8256 13.7849 -26.1083 --10.8849 13.648 -25.8221 --10.3544 12.905 -25.4385 --9.83372 12.1079 -25.3286 --9.10863 11.9729 -24.5663 --8.24733 12.4259 -24.2467 --7.84933 12.8564 -25.0217 --7.59603 12.4778 -25.882 --6.83581 12.5847 -26.531 --7.30478 12.8352 -27.3951 --7.66747 12.0858 -27.8366 --7.89393 11.1603 -27.4827 --8.84208 10.797 -27.5523 --8.81668 11.7878 -27.7691 --9.54085 11.4194 -28.3533 --9.38809 11.4541 -29.336 --8.95109 11.7855 -30.1588 --8.86157 12.248 -31.1243 --8.84027 11.2373 -31.3378 --8.09185 10.9227 -31.9329 --7.68461 10.8415 -30.9864 --7.34468 9.94694 -30.8145 --7.59725 9.42885 -30.0005 --6.71674 9.43393 -29.4685 --5.81975 9.54084 -29.0788 --5.15482 8.81418 -29.1457 --5.13595 8.75231 -28.1364 --5.53545 9.13414 -27.2412 --5.88517 8.66464 -26.4563 --6.56028 8.22266 -25.8375 --6.46397 7.99074 -24.8309 --6.8106 7.06288 -25.0631 --5.88605 6.65292 -25.0386 --4.94506 6.42313 -25.0747 --4.03398 6.72634 -25.3896 --4.58623 6.2821 -26.0836 --5.2129 5.8494 -26.6915 --5.48835 5.1726 -27.3021 --6.00016 5.57662 -28.074 --5.56169 6.51913 -28.1246 --4.56557 6.6857 -28.1041 --4.89687 6.25895 -29.0359 --4.43688 5.56367 -29.568 --4.52641 4.59313 -29.8936 --5.39333 4.17028 -29.6387 --5.39954 4.90034 -28.9512 --6.33679 4.58825 -29.2605 --6.3002 3.77915 -29.8247 --6.71517 3.07819 -29.1702 --7.60913 3.56664 -29.0199 --8.44848 4.07393 -28.7565 --8.83271 5.01744 -28.4563 --9.11738 5.42913 -29.3571 --10.0974 5.24037 -29.3991 --11.0795 4.97349 -29.4387 --10.5449 5.16459 -28.5236 --11.2049 5.93098 -28.2954 --11.3447 6.43796 -29.1855 --11.067 6.50677 -30.1584 --11.9495 6.53043 -30.6313 --11.7867 5.83286 -29.9358 --12.6141 5.62445 -30.3733 --13.0057 6.50663 -30.5894 --13.6109 6.69925 -29.8516 --13.5891 7.64104 -29.6056 --14.1249 7.4484 -30.3611 --13.5283 7.96846 -30.9664 --12.7007 8.47657 -30.9103 --11.981 8.81888 -30.4023 --11.0093 8.69983 -30.4913 --11.1124 8.59187 -29.5845 --10.3085 8.94883 -29.0734 --10.7784 9.80614 -28.7684 --10.0983 9.64579 -28.0666 --9.70578 10.1412 -27.3079 --9.7016 9.15713 -27.1018 --8.90857 8.46981 -27.0382 --9.29676 8.66718 -26.143 --9.37678 8.1671 -25.2922 --8.93205 8.70872 -24.6296 --9.48431 9.36024 -24.0977 --8.74272 9.45467 -23.4648 --7.91199 9.42553 -22.857 --8.40639 8.93988 -22.0876 --8.53644 8.3689 -21.27 --8.82862 9.29892 -21.0899 --8.63285 9.92067 -21.8582 --9.28205 10.7495 -21.9625 --8.88327 11.1102 -21.0753 --9.65291 11.7436 -20.8835 --9.55643 12.5677 -21.4828 --9.52448 13.2032 -20.7014 --9.03444 13.9323 -20.2626 --8.96044 14.9127 -19.917 --8.22267 15.0851 -19.3193 --7.33625 14.912 -19.4895 --7.88342 14.1668 -19.8706 --7.01692 13.7403 -19.4629 --6.21268 13.3191 -19.9231 --5.5082 13.3579 -19.1838 --6.16723 13.6787 -18.4414 --5.47532 14.4207 -18.3353 --5.3065 13.5481 -17.8596 --5.69651 13.1246 -17.0973 --5.08776 13.1197 -16.3101 --4.38563 13.7633 -16.5989 --4.4488 14.4334 -15.8491 --5.37335 14.6601 -16.0628 --5.87564 13.8002 -15.8378 --6.65798 13.5142 -15.1775 --7.39787 13.3369 -15.8583 --8.11089 13.1368 -15.1876 --8.93282 13.0613 -14.6012 --8.75013 12.0903 -14.6497 --7.79478 12.2616 -14.9781 --7.5959 12.4452 -14.0723 --6.93719 12.1 -13.4016 --7.10599 12.2072 -12.388 --7.68004 11.6434 -11.8283 --7.87251 11.4613 -12.7593 --7.19433 10.7912 -12.5637 --6.33868 11.0757 -12.1074 --6.55863 10.8774 -11.1718 --6.62067 11.2632 -10.22 --6.68299 11.4522 -9.26033 --7.68457 11.3516 -9.34793 --7.55667 11.8853 -10.1947 --7.23066 12.4485 -9.44352 --6.40759 12.7699 -9.82458 --6.21356 12.9267 -8.86006 --5.46219 13.4195 -9.37219 --5.23186 13.7009 -10.294 --5.0249 14.6666 -10.6695 --5.5473 14.6341 -9.81682 --5.70543 15.4688 -10.3522 --5.42229 16.2507 -9.76258 --5.05268 16.6456 -8.89764 --6.01752 16.5732 -8.74238 --6.62911 16.1008 -8.07648 --6.31691 15.9218 -7.16945 --6.75727 16.2534 -6.38673 --7.44906 16.3476 -7.10622 --7.70191 16.6848 -8.02413 --7.36285 17.6295 -7.75691 --7.10702 18.2831 -8.46273 --8.10953 18.3411 -8.26804 --8.69371 19.1442 -8.04799 --8.73203 19.7411 -7.24909 --9.441 19.7927 -6.62153 --8.87665 19.5024 -5.82869 --8.12414 18.9269 -5.73722 --7.39845 18.3899 -6.22259 --7.32706 17.8955 -5.39713 --7.59885 16.9699 -5.83055 --8.32335 16.999 -6.40057 --8.60232 16.1344 -5.9744 --9.25312 15.7062 -6.55112 --9.93262 16.0946 -5.8609 --10.8348 16.2408 -5.32242 --10.7397 15.9873 -4.41068 --10.8483 15.0473 -4.61938 --11.2239 14.4467 -3.81256 --11.2737 14.276 -2.86954 --12.2358 14.1116 -2.89413 --12.252 14.5285 -3.79552 --13.1726 14.591 -3.35383 --12.4961 15.3694 -3.43879 --12.2439 15.7341 -2.58923 --11.3841 15.4578 -2.26473 --11.1036 16.3508 -2.53392 --11.1473 16.9843 -3.34181 --11.0943 17.3355 -4.25812 --10.5575 18.0285 -3.84859 --9.81164 18.5607 -3.76729 --9.02434 19.1694 -3.52172 --9.03875 20.2052 -3.35068 --9.03034 20.2821 -4.30302 --9.90998 20.72 -4.49403 --10.552 21.3906 -4.74543 --10.0491 22.0122 -5.44036 --9.43635 21.3099 -5.83062 --8.70144 20.7891 -6.22122 --8.50298 21.0931 -7.21871 --7.87161 21.7378 -6.8709 --7.66742 22.6654 -7.17604 --7.48931 23.2181 -8.02182 --7.46265 24.2408 -8.19642 --7.14917 23.992 -9.09705 --7.64431 23.5154 -9.85873 --8.35374 24.188 -9.6397 --9.26145 23.7371 -9.60265 --9.69329 24.021 -10.5353 --8.95878 24.6742 -10.6669 --8.92723 24.5451 -11.6794 --9.07898 24.8834 -12.5727 --8.74298 25.7791 -13.0569 --8.07377 25.8316 -13.8465 --7.71686 25.6117 -12.909 --7.40328 25.0727 -13.7173 --6.62004 24.6951 -14.2192 --7.16876 24.1326 -13.6555 --7.98595 23.7591 -13.4645 --7.38097 23.4834 -12.7017 --7.86497 22.7313 -12.2631 --8.06629 21.7182 -12.2309 --8.35686 22.2414 -11.396 --7.83597 22.9864 -11.0938 --6.80798 22.9684 -11.099 --5.84453 23.3532 -11.2588 --5.7992 22.6729 -11.9171 --6.37186 22.4792 -12.6627 --5.62042 22.4701 -13.3353 --5.16033 21.7262 -13.8134 --4.92312 20.9147 -14.3171 --4.34958 21.3089 -14.9457 --3.45974 21.0543 -14.5971 --3.08799 20.1124 -14.7643 --3.52132 19.8524 -15.6208 --4.10587 20.0696 -16.4248 --4.63929 19.2318 -16.3324 --5.56699 19.1843 -16.0752 --5.97637 18.3971 -16.6007 --6.4876 17.9563 -17.2823 --7.40066 18.1673 -16.9129 --7.92915 17.3285 -17.2336 --7.81041 16.321 -17.0412 --8.01089 15.4336 -16.615 --8.40725 16.2607 -16.3026 --8.30766 16.2342 -15.3339 --9.06053 16.0441 -14.5637 --9.94426 15.7435 -14.6289 --9.81075 15.4061 -15.6041 --10.6846 15.8754 -15.7046 --11.4879 15.7415 -16.3153 --11.938 15.6974 -17.211 --12.6911 15.4863 -17.7974 --12.9398 14.4902 -17.6318 --13.0998 14.2006 -16.6606 --13.7845 14.9 -16.4361 --14.5738 14.8816 -15.748 --15.1198 15.6918 -15.6931 --14.6609 16.2475 -14.9097 --14.5919 15.5283 -14.1889 --14.7879 16.277 -13.5707 --15.842 16.2262 -13.4623 --15.7049 15.3865 -13.8956 --15.9816 15.0608 -12.9823 --15.6369 15.5146 -12.1715 --15.7606 14.794 -11.4569 --16.6453 15.1755 -11.3082 --17.2218 15.6922 -12.0367 --17.5977 16.2447 -11.2573 --18.0732 16.8713 -12.0066 --18.2866 16.8079 -13.0375 --19.0086 17.0397 -12.3424 --18.903 17.944 -12.0537 --18.9825 18.2895 -12.9553 --19.6997 17.7232 -13.3911 --20.0717 18.4491 -14.0011 --20.8306 18.6387 -14.5282 --21.6854 18.0822 -14.7946 --22.1024 18.8436 -15.3247 --22.6787 18.0656 -15.3652 --23.034 17.2768 -14.8665 --23.6267 16.5183 -14.9407 --23.0007 15.81 -15.3062 --22.3673 15.8483 -14.5818 --21.5114 15.9443 -14.165 --21.4138 15.2544 -14.7364 --20.5514 15.1988 -15.2355 --20.683 14.5479 -14.4978 --21.3071 14.1725 -15.2447 --22.2635 14.3645 -15.1455 --22.9047 14.0905 -14.3697 --23.8364 14.1286 -14.5894 --23.9613 13.1312 -14.6961 --24.7271 12.5144 -14.9604 --24.8189 12.5871 -13.9736 --25.6619 12.3705 -14.4284 --26.483 12.494 -13.764 --27.3443 11.9703 -13.4754 --27.6551 11.4477 -12.7068 --27.7581 10.4714 -12.4545 --27.7287 10.0806 -13.4089 --28.3284 10.1659 -14.1943 --29.2365 10.1411 -13.9867 --30.0324 10.4924 -14.5021 --30.573 10.729 -13.6865 --31.0133 9.77099 -13.4948 --30.7233 8.86599 -13.8294 --31.1793 8.81603 -12.9566 --31.8783 8.1708 -12.6912 --32.5963 8.09343 -12.0373 --33.4971 8.23352 -12.4577 --33.9419 7.84661 -11.6561 --34.0181 6.87722 -11.7534 --34.6612 6.18256 -11.5629 --35.0742 6.66139 -12.3504 --34.2041 6.08759 -12.5931 --33.4019 6.07228 -13.1654 --32.7463 6.5219 -13.6608 --32.8809 6.31311 -14.6489 --33.618 5.62674 -14.7963 --34.5162 5.7196 -14.7244 --35.282 6.0968 -15.3304 --35.0515 5.45537 -16.1148 --34.2724 6.02933 -16.3637 --33.9339 5.23007 -16.974 --33.1552 5.16241 -17.5752 --33.7516 4.9817 -18.3 --33.6843 5.8228 -18.832 --33.6578 6.75957 -18.5393 --32.7787 6.31146 -18.3152 --31.9556 6.71907 -17.9816 --31.0576 6.42412 -18.096 --30.7205 7.15985 -18.7699 --29.7438 7.33477 -19.027 --29.2126 6.6401 -19.4965 --29.2256 6.42344 -18.4874 --28.3242 6.50571 -18.0186 --28.0767 5.55244 -18.3024 --28.5948 4.86554 -18.8725 --28.3001 5.62413 -19.4981 --27.5485 5.02038 -19.6554 --27.4502 5.72467 -20.4039 --26.8666 6.27561 -19.8473 --26.0651 6.57334 -19.3783 --26.3357 7.47622 -19.3197 --25.9304 8.1933 -18.6886 --26.2324 9.20527 -18.68 --26.2092 8.73711 -19.5578 --25.2089 8.8877 -19.344 --24.844 9.52151 -18.7197 --24.8006 10.5485 -19.0004 --23.9539 10.7528 -19.5711 --23.001 11.2007 -19.4998 --22.6704 12.0216 -18.9145 --23.2087 12.8536 -18.9075 --23.1836 13.0499 -19.8592 --22.3841 13.5373 -19.4646 --21.8722 14.1032 -20.1754 --22.2211 14.8263 -19.5295 --22.2988 15.0292 -20.4628 --21.4158 15.3003 -20.4314 --20.8401 15.8031 -19.8128 --20.2297 15.9837 -19.0716 --20.9956 15.613 -18.5868 --21.2568 14.6864 -18.3197 --21.5641 13.9022 -18.7076 --21.2678 13.3029 -19.441 --20.4719 12.7184 -19.5171 --20.0559 13.5055 -19.123 --20.0186 14.1618 -19.8662 --19.114 13.8345 -20.2094 --18.3413 13.4294 -20.7518 --17.9386 12.5128 -20.5193 --16.9701 12.6392 -20.36 --16.7362 11.7357 -20.6216 --17.3205 11.4166 -19.8312 --16.939 12.1733 -19.2894 --16.2936 11.6888 -18.7263 --15.3265 11.7955 -18.778 --14.8316 11.1882 -18.065 --15.7392 11.3087 -17.6247 --16.012 11.7 -16.7402 --16.3903 10.8736 -16.1296 --15.4026 11.0541 -15.9139 --14.7383 11.5492 -15.2862 --14.2846 12.2994 -15.7144 --14.8362 12.9226 -15.3 --15.4459 12.2681 -14.8004 --14.8314 12.176 -13.9867 --14.0515 11.6611 -14.2213 --13.4492 10.976 -13.718 --13.2327 10.221 -14.4192 --14.0626 10.2318 -15.0111 --13.3039 9.76234 -15.4871 --13.4072 9.14027 -16.2241 --12.7828 8.74219 -16.8863 --12.9779 8.28706 -17.761 --13.2658 7.31958 -17.6865 --13.5936 7.09838 -16.7683 --13.7201 6.34969 -16.1261 --14.6298 5.89118 -16.1166 --15.2543 5.43877 -16.715 --16.0091 4.96097 -17.3208 --16.6034 4.24669 -17.6394 --15.6374 4.0503 -18.0545 --16.0006 3.57473 -17.2105 --15.6712 2.72174 -16.8691 --14.7838 3.21309 -16.6815 --14.1712 3.53582 -17.42 --13.3023 3.16923 -17.0605 --13.3787 2.21152 -17.2254 --13.4559 1.36747 -17.7489 --14.3763 1.78208 -17.9943 --14.6492 2.13757 -17.1416 --14.5477 1.08883 -17.2835 --14.0675 0.6063239 -18.1056 --13.5537 -0.1024331 -17.6276 --12.5668 0.02020193 -17.4539 --11.8988 -0.2837721 -16.743 --10.888 -0.1374441 -16.9168 --10.6578 -0.1781361 -15.971 --10.8687 -0.7140171 -15.2035 --11.2238 -1.22669 -14.4592 --11.4322 -2.06389 -14.988 --12.008 -2.26883 -14.2612 --11.8021 -2.98359 -13.6022 --11.7427 -2.42911 -12.7723 --12.4759 -1.83269 -12.5987 --12.3301 -1.2894 -11.7748 --11.4409 -1.54055 -11.4622 --10.6389 -1.3974 -12.1779 --10.4376 -0.6918561 -12.8097 --9.55442 -0.2919981 -13.1729 --9.05818 -0.8190191 -12.448 --9.32121 -1.74202 -12.3299 --8.78283 -2.51179 -11.9168 --8.66779 -2.72829 -12.9149 --7.82722 -3.14845 -12.4986 --7.10964 -2.49019 -12.4076 --6.8233 -1.53771 -12.2442 --7.37608 -0.8277261 -12.6125 --7.39569 -0.3250271 -11.7675 --6.96381 -0.7737071 -10.9432 --7.75423 -1.45378 -11.1053 --7.92566 -2.36644 -10.8302 --7.25855 -3.06364 -11.2714 --7.00364 -3.87577 -10.7336 --6.15385 -3.99123 -10.2302 --6.46917 -4.33442 -9.35048 --6.85588 -4.28688 -8.45322 --6.92485 -4.22438 -7.43521 --7.84734 -3.73364 -7.31931 --8.4827 -4.499 -7.42994 --8.14458 -4.92797 -6.61065 --7.32791 -4.85503 -5.95261 --6.4179 -5.07963 -6.21829 --6.13383 -4.3385 -5.66193 --6.49289 -3.59732 -6.19215 --6.53558 -3.18173 -7.10875 --5.79542 -2.83778 -7.72254 --4.96306 -2.57088 -7.23495 --5.37551 -3.15559 -6.56679 --5.89014 -2.37465 -6.14468 --5.2015 -2.52328 -5.34671 --4.78255 -1.58928 -5.40413 --4.6808 -0.5926911 -5.26923 --4.17532 0.06954653 -5.79454 --5.13747 0.3046149 -6.00534 --4.77446 0.9149219 -6.78899 --4.93364 -0.05221067 -7.07768 --5.06036 -0.7942051 -6.56268 --5.99724 -0.6720131 -6.74385 --6.46051 -0.8794221 -7.63638 --6.08269 -0.5644811 -8.56686 --5.15936 -1.04869 -8.73595 --4.67341 -1.8987 -8.7444 --5.33618 -2.07015 -9.52868 --5.74312 -3.03071 -9.30882 --6.634 -2.83491 -9.03202 --6.84945 -3.16207 -8.07494 --7.11651 -2.20951 -7.92142 --8.08585 -2.22528 -7.98588 --8.26313 -1.8554 -8.93226 --7.41993 -1.72948 -9.16865 --7.98307 -0.9160551 -9.15461 --8.42946 -0.06280867 -8.87139 --8.68347 -0.3167871 -7.91411 --9.71594 -0.4411641 -7.89211 --10.6843 -0.3265851 -7.79444 --10.3599 0.08134713 -8.58346 --10.2697 0.3620349 -9.52579 --11.0472 -0.08321347 -9.87653 --11.6286 0.3745759 -10.5749 --11.0632 0.4728539 -11.405 --10.8408 0.4587639 -12.2921 --10.9879 0.6791979 -13.3067 --10.7682 0.9769439 -14.1626 --11.8021 0.5710499 -14.2618 --12.4178 1.14122 -14.6624 --11.7973 1.7291 -15.222 --11.1754 1.44258 -15.9362 --10.9324 1.76607 -16.8363 --10.6796 1.01038 -17.4414 --9.93239 1.57646 -17.4858 --9.52978 2.42551 -17.775 --9.81727 3.1704 -17.1129 --8.87173 2.96992 -16.6664 --8.83067 2.79788 -15.6615 --8.05345 3.38484 -15.3465 --7.35256 3.5749 -14.7127 --6.5733 3.55457 -15.3277 --6.44216 4.51285 -15.5744 --5.84389 4.14217 -16.2522 --6.552 4.00952 -16.883 --6.97634 3.32496 -17.4312 --7.39032 3.92426 -18.123 --6.94919 3.90841 -18.9773 --5.99748 3.74981 -18.8278 --6.40755 2.81061 -19.0601 --6.33415 3.43249 -19.9122 --5.37771 3.67652 -20.0107 --5.88406 3.01556 -20.605 --5.17999 2.3568 -20.9473 --5.06615 2.74155 -21.856 --5.26278 3.72677 -21.7879 --4.30002 3.77711 -21.3256 --3.77028 3.35203 -22.073 --3.8274 4.0454 -22.8465 --4.32612 4.81192 -23.2454 --3.9924 5.34391 -23.9519 --3.29951 5.86792 -24.4538 --3.55941 6.78079 -24.0667 --3.66199 7.82679 -23.9944 --3.09838 8.35195 -23.2393 --2.39708 8.93836 -23.7103 --2.81642 8.93499 -24.6212 --3.69678 9.27277 -24.9233 --3.15622 9.38475 -25.7644 --2.52736 10.1475 -25.4687 --2.02056 9.99594 -24.5703 --1.61619 10.6391 -25.1887 --0.575806 10.8752 -25.2638 --0.576208 10.4627 -26.1316 --1.29127 11.0811 -26.4169 --1.2238 11.1625 -27.4079 --2.21955 11.2466 -27.1557 --1.73153 12.1049 -27.1706 --2.23972 12.1476 -28.0146 --1.82364 11.6517 -28.8169 --2.03138 10.7405 -28.3526 --2.77193 10.8821 -29.0649 --2.96615 9.97512 -29.244 --2.76195 8.95002 -29.2814 --2.96837 7.97131 -29.2474 --2.60937 7.98571 -28.2672 --1.71548 7.65307 -27.8894 --2.41524 7.3917 -27.2827 --3.16824 6.96128 -27.7384 --3.58609 6.32467 -28.3408 --3.34451 5.35763 -28.6647 --4.21983 4.97551 -28.3601 --4.67631 4.09073 -28.3093 --4.82122 3.97579 -27.3407 --4.9865 3.04585 -27.69 --4.26534 2.60873 -27.1357 --4.258 3.06644 -26.2343 --5.15702 3.16347 -26.6778 --5.53555 3.49575 -25.8098 --6.47363 3.68964 -26.0133 --6.86433 2.78527 -26.2337 --7.75779 2.39119 -26.1441 --7.80699 2.77001 -27.0486 --7.85402 3.67113 -26.682 --8.72688 3.39714 -27.1076 --9.26433 3.87325 -27.8314 --10.177 3.51913 -27.9967 --10.4123 3.61317 -27.0662 --10.5974 4.05461 -26.1122 --11.1944 4.0148 -25.3849 --11.5127 3.21405 -25.782 --10.9009 2.46984 -26.1587 --11.1829 2.37769 -25.1362 --10.7587 2.135 -24.2284 --9.78555 1.89015 -24.3035 --8.80475 2.04858 -23.9656 --8.38017 2.41382 -23.1069 --9.1574 2.45508 -22.5479 --8.74408 2.10007 -21.6586 --7.78668 2.11055 -21.8428 --6.90519 1.6771 -21.6878 --7.13302 1.59103 -22.673 --7.5773 0.6808489 -22.7767 --7.30064 -0.3216401 -22.8127 --6.49088 0.1078649 -23.1054 --6.05547 -0.6811391 -22.6558 --6.05819 -0.1165251 -21.857 --6.76015 -0.8738481 -21.895 --7.33437 -1.22359 -21.1919 --7.49293 -1.84768 -20.4371 --8.33566 -2.03589 -20.8533 --8.90608 -2.88281 -20.6183 --9.87231 -2.91319 -20.565 --10.2809 -2.44858 -21.3845 --10.5511 -2.5355 -22.3564 --10.9761 -1.7575 -22.8234 --10.652 -1.01868 -22.2269 --10.8785 -0.09519287 -22.3564 --11.6903 0.01200223 -21.7633 --11.8575 -0.9300531 -21.6613 --12.7164 -0.6115241 -21.367 --13.1645 0.2191039 -21.2934 --13.5917 1.13022 -21.0378 --14.1623 0.3625649 -20.6559 --13.4339 -0.2555331 -20.4428 --12.7703 0.4748269 -20.093 --12.4124 1.35699 -20.032 --11.8843 1.54311 -19.1593 --11.4435 2.52362 -19.1964 --10.9504 2.50442 -20.0941 --11.4767 2.26812 -20.9243 --11.7643 1.39854 -21.2397 --12.486 1.86139 -21.7758 --13.0447 2.27963 -21.1384 --13.1638 3.17036 -20.6783 --13.2167 3.36464 -21.6626 --13.3539 3.54612 -22.5999 --12.945 2.9075 -23.3811 --12.6076 3.79019 -23.7185 --12.0983 3.92915 -22.8481 --11.6124 4.52723 -22.1423 --11.1738 4.67255 -23.046 --10.3863 4.06756 -22.9736 --9.81443 3.43132 -22.4432 --9.16133 4.17778 -22.3416 --8.97829 5.10355 -21.8623 --8.60786 4.92606 -20.9822 --8.18039 5.20445 -20.114 --7.42459 4.83994 -20.5671 --6.91487 5.74478 -20.3797 --6.20013 5.15217 -20.2238 --5.53283 5.34937 -19.505 --4.81529 5.64898 -20.1327 --4.98706 5.43502 -21.1138 --3.97241 5.297 -21.2637 --4.3351 5.6571 -22.1392 --4.99583 6.26634 -22.6912 --5.90669 6.05253 -22.8991 --6.38701 6.54929 -23.625 --7.40862 6.86096 -23.8639 --7.51483 5.90886 -23.8326 --8.20067 5.3345 -23.5321 --7.96882 5.37396 -24.5222 --7.46409 4.51346 -24.5182 --6.61179 4.43492 -23.8849 --5.60487 4.44428 -24.1623 --6.04978 3.62774 -24.5164 --6.04976 2.72126 -24.2235 --6.68577 2.89559 -23.5188 --6.13064 2.47416 -22.8191 --5.18717 2.72152 -22.8849 --4.19448 2.76292 -23.0143 --3.72448 2.43844 -23.8854 --3.23201 3.24142 -23.6028 --2.28648 3.43257 -23.3487 --1.47867 3.66174 -22.9332 --2.05349 3.77633 -22.1064 --1.47398 4.54761 -22.186 --0.696783 4.30719 -21.6137 --0.869483 3.4877 -21.1113 --0.377217 2.98478 -20.4102 --0.03700603 2.06934 -20.1661 --0.478077 1.35643 -19.6521 -0.01687707 2.07746 -19.1468 --0.292439 1.76001 -18.2615 --0.209767 0.7147319 -18.3969 -0.573791 0.07830143 -18.2353 -1.36078 -0.5653901 -18.3291 -1.94696 -0.004090036 -18.9971 -2.04215 0.7259949 -19.7355 -1.76368 1.02627 -20.6321 -1.10006 1.11696 -21.3711 -0.817453 2.04055 -21.6373 --0.127485 2.34312 -22.0351 --0.714268 2.20727 -22.8277 --1.55228 2.15886 -23.3863 --1.78083 2.0164 -22.3756 --2.4023 2.35637 -21.7102 --2.04666 2.30657 -20.8 --1.21113 1.75894 -20.5395 --1.03124 0.7672019 -20.473 --1.05343 0.1444739 -21.2389 --0.394021 -0.1776601 -20.6084 --0.07389953 -1.16787 -20.3768 --0.581944 -1.75538 -19.6514 --0.612364 -2.44681 -18.8666 --0.818362 -2.48909 -17.9078 --1.32781 -2.61062 -17.0437 --1.91101 -1.834 -17.3121 --2.57667 -2.03142 -18.0795 --2.04413 -2.23353 -18.8832 --1.66868 -1.438 -19.3491 --1.40644 -0.7900331 -20.1231 --1.57166 0.08864263 -19.7735 --2.19981 0.8604669 -19.9974 --2.78511 1.46902 -20.5377 --3.84372 1.38883 -20.6488 --3.60937 2.1154 -21.4133 --3.02445 1.34139 -21.8372 --3.68985 0.5358409 -21.9488 --4.62719 0.1831939 -22.1096 --5.12174 0.08343353 -22.9469 --4.76847 0.4569399 -23.7974 --5.46121 1.04685 -24.0535 --6.32379 1.2623 -24.4599 --6.21944 0.7822289 -25.3677 --6.44456 -0.1819901 -25.4816 --5.93951 0.1071569 -24.6414 --4.97678 -0.1679141 -24.7357 --4.9974 -0.6186531 -25.664 --5.10653 -1.39953 -26.2785 --4.51117 -1.27568 -27.0773 --4.04899 -1.51147 -26.1824 --4.12228 -0.4955011 -26.2991 --4.64729 -0.08107977 -27.0188 --5.10231 0.7600629 -26.652 --5.59718 1.28566 -27.4049 --6.12703 0.4853809 -27.3447 --6.83257 -0.2407291 -26.9615 --7.35038 0.4825689 -26.4065 --7.21778 1.24268 -25.7504 --7.3245 1.11634 -24.7668 --7.35347 0.1660959 -25.1407 --8.10791 -0.3383031 -24.759 --7.70239 -0.9878641 -25.3411 --8.32342 -1.59023 -25.8182 --7.98929 -2.53591 -25.9186 --8.07641 -3.29097 -25.2649 --7.69529 -3.24653 -24.4139 --8.31085 -2.39995 -24.5227 --7.38956 -2.08627 -24.5449 --7.67036 -1.82566 -23.5838 --8.1021 -1.02404 -23.2032 --8.68283 -1.77197 -22.8547 --8.59697 -2.48785 -22.0829 --9.30183 -3.2078 -22.1508 --9.92702 -3.966 -22.0304 --9.54116 -4.88923 -22.0502 --10.4925 -4.96119 -22.0387 --10.3489 -4.70919 -21.0558 --10.3913 -5.71849 -20.8323 --10.7373 -6.10992 -21.7276 --10.1801 -6.85244 -22.1536 --9.67696 -6.05531 -22.1201 --8.7006 -5.98369 -21.8982 --8.17849 -6.12328 -21.0164 --7.46489 -6.75182 -21.2613 --7.24324 -6.54976 -20.2785 --7.73322 -7.36698 -20.3708 --7.06279 -7.78003 -19.8739 --7.29648 -7.06145 -19.2442 --7.0135 -6.67343 -18.4623 --6.94854 -6.33181 -17.4562 --7.50806 -7.13097 -17.5389 --8.15759 -7.87191 -17.4535 --8.72937 -7.3384 -18.0777 --9.14056 -7.00787 -18.9276 --9.64995 -7.91043 -18.9225 --9.91199 -7.3631 -19.7273 --9.47142 -7.68154 -20.5482 --10.2662 -8.07851 -20.8394 --11.1582 -8.52953 -20.8715 --10.7212 -9.53891 -20.7684 --11.0239 -9.27681 -21.6406 --11.8956 -9.17928 -22.0293 --12.327 -8.29755 -22.2749 --13.0917 -7.68188 -21.9664 --13.3443 -8.56513 -22.4357 --12.7379 -8.89373 -23.1247 --13.3013 -8.15384 -23.4115 --13.2879 -7.19698 -23.0231 --14.1224 -6.91586 -23.6426 --13.3139 -6.79764 -24.145 --13.4842 -7.7032 -24.5346 --12.6531 -7.36776 -24.2552 --11.6524 -7.14151 -24.3772 --11.2488 -6.25811 -24.2657 --11.387 -6.09491 -23.2574 --11.6474 -6.20918 -22.3023 --11.9277 -6.71253 -21.5029 --11.7672 -6.40091 -20.573 --11.3743 -6.59285 -19.5797 --10.7207 -6.79961 -18.8091 --11.2763 -6.33703 -18.123 --10.7561 -5.68487 -18.6585 --10.5342 -4.78076 -19.0594 --9.95742 -4.13113 -18.5441 --10.4737 -3.31963 -18.9365 --10.6685 -2.68903 -18.2338 --10.887 -1.7365 -17.9972 --11.452 -1.01273 -18.1522 --11.1847 -1.25594 -19.1097 --12.0307 -1.77306 -19.1736 --12.8225 -1.49943 -18.7032 --13.8416 -1.65464 -18.5113 --13.4999 -2.09367 -17.709 --13.0667 -3.09287 -17.6842 --13.3936 -3.62376 -16.8355 --12.6112 -3.22349 -16.3307 --12.5986 -2.25392 -16.0001 --12.3355 -1.7792 -16.8464 --11.3812 -2.13978 -16.7547 --10.531 -2.60804 -16.5696 --10.3785 -1.66827 -16.861 --9.89684 -1.24609 -17.67 --9.52174 -0.3540031 -17.3059 --9.72908 0.5838319 -17.5796 --9.48023 0.3136609 -18.5243 --8.80644 0.4816039 -19.1793 --8.24908 0.2286959 -19.9682 --8.05902 1.10012 -19.5216 --7.1688 0.7314319 -19.8173 --6.54267 0.8675609 -20.6536 --5.62662 1.26323 -20.5238 --5.90205 1.57938 -19.7461 --5.46748 2.03302 -18.9582 --5.0562 1.91884 -18.0211 --5.91616 2.29666 -17.7967 --6.59968 1.76066 -17.2503 --7.39147 1.13801 -17.1898 --7.61184 0.1386269 -17.2255 --7.26343 -0.7531761 -17.0601 --6.50474 -0.1313381 -16.7553 --6.06607 0.7909319 -16.7587 --6.66957 1.22931 -16.2108 --7.20544 0.9500489 -15.4237 --7.20934 0.2764489 -14.7218 --7.73708 -0.4985331 -15.1934 --8.28774 -1.29515 -15.5841 --8.11202 -2.10331 -14.9913 --8.73927 -1.47665 -14.5385 --9.56872 -2.03782 -14.4168 --10.2425 -2.69415 -14.6572 --10.9558 -3.36471 -14.3407 --11.3094 -4.3678 -14.3872 --11.452 -5.17618 -13.8347 --10.589 -5.73436 -13.9296 --11.0839 -6.58628 -14.0863 --12.0543 -6.78724 -14.2446 --11.9776 -7.71024 -14.6125 --12.9249 -7.6348 -14.3614 --13.6528 -8.35528 -14.0165 --13.7415 -8.71996 -14.9387 --14.4453 -8.39914 -15.5505 --14.5019 -9.42314 -15.5186 --14.3219 -9.78924 -16.4429 --14.6684 -10.4865 -17.0748 --14.7497 -9.90494 -17.9074 --15.0881 -9.70623 -18.8198 --14.702 -10.6158 -18.8908 --15.4085 -11.1206 -18.3204 --15.2795 -12.0479 -18.1841 --15.1234 -13.0117 -18.174 --14.6872 -12.9087 -19.0886 --13.9387 -12.4371 -19.3726 --14.0753 -11.4575 -19.6138 --14.3704 -11.9884 -20.4366 --13.4589 -12.4222 -20.5071 --12.5297 -12.0092 -20.6385 --12.6467 -12.7968 -21.2149 --12.1287 -13.6137 -21.385 --11.637 -13.2803 -22.2616 --10.9352 -13.4481 -22.8486 --10.7778 -14.4313 -22.8161 --10.2828 -14.5939 -23.6909 --11.1189 -14.0112 -23.9474 --11.5471 -13.0313 -24.1451 --12.1349 -13.415 -24.83 --11.8194 -13.6157 -25.822 --11.3534 -12.8346 -25.5698 --11.6247 -11.9632 -25.2023 --12.5283 -11.8303 -25.0344 --13.124 -11.9309 -24.1865 --13.5736 -11.0282 -24.506 --13.1856 -10.4954 -25.2868 --12.6276 -10.6937 -24.4525 --12.4765 -9.72747 -24.4072 --12.5294 -9.17438 -25.2038 --11.5615 -9.32736 -25.3386 --10.9793 -9.06238 -24.5746 --10.7861 -8.52407 -23.712 --10.0703 -9.13524 -24.0782 --10.4641 -9.42067 -23.2308 --11.2604 -9.98327 -23.3849 --10.6337 -10.7409 -23.7521 --10.4782 -11.134 -22.8782 --10.1941 -11.959 -22.4728 --9.99278 -12.6765 -23.2274 --10.1488 -12.4593 -24.259 --9.16389 -12.3275 -24.4171 --8.8463 -13.3131 -24.4965 --8.08752 -13.6097 -25.0685 --7.40153 -12.9535 -24.705 --6.62501 -13.6417 -24.7005 --6.26886 -12.6923 -24.7874 --6.49263 -12.3014 -23.9173 --5.9661 -11.3841 -23.817 --5.0069 -11.4474 -23.596 --4.20432 -11.9681 -23.3049 --4.3098 -12.1121 -22.3226 --3.37255 -11.9931 -22.7151 --2.55201 -11.6202 -22.3169 --2.36016 -12.3245 -23.0359 --1.66432 -12.4937 -22.3212 --0.877678 -13.0437 -22.2393 --0.143644 -12.9921 -21.5963 --0.143266 -13.347 -20.6835 --0.456282 -12.4764 -20.3587 --1.25598 -12.7606 -19.8421 --0.824622 -12.0684 -19.3582 --0.483981 -12.0755 -18.3567 --0.936557 -12.4102 -17.468 --1.28092 -11.6395 -17.0039 --1.86067 -10.8449 -17.2355 --2.43344 -11.1541 -17.9991 --2.25004 -11.7552 -18.8705 --2.74585 -11.4793 -19.705 --2.409 -10.5562 -20.0025 --3.2061 -10.0308 -20.276 --2.60351 -9.15348 -20.2096 --1.82688 -8.76926 -19.7009 --1.23887 -9.17842 -20.3841 --0.80811 -9.76637 -19.6578 --0.61057 -9.92543 -18.6508 -0.249303 -10.2977 -18.8486 -0.947343 -10.84 -18.3738 -1.67424 -10.8665 -19.0461 -1.82808 -11.8291 -19.2771 -2.57676 -11.5885 -18.6974 -2.30704 -10.9078 -17.9631 -2.55259 -11.6755 -17.3141 -2.94101 -11.7524 -16.4726 -3.15902 -10.8097 -16.3725 -3.31583 -9.87306 -16.1581 -2.43309 -9.54103 -16.4568 -2.32595 -10.0829 -17.2724 -1.56159 -10.6308 -17.0705 -1.61828 -10.3207 -16.1431 -1.81629 -9.6351 -15.3422 -1.79685 -10.5947 -15.0251 -2.30098 -11.3474 -14.8 -2.36427 -11.6409 -15.702 -3.29344 -11.7135 -15.2915 -3.77695 -12.6143 -15.1328 -3.48812 -12.2182 -14.1901 -2.60778 -12.739 -14.158 -2.97343 -12.5772 -13.2364 -3.7935 -12.9617 -12.9564 -4.59724 -13.3579 -12.6276 -5.52603 -13.3726 -12.3469 -5.82441 -12.3813 -12.0898 -6.76253 -12.455 -12.3918 -7.30936 -12.0032 -11.6409 -7.67569 -11.2004 -12.1933 -7.82304 -11.2496 -11.1677 -8.5846 -11.7688 -11.5204 -8.84253 -12.0202 -12.4776 -8.81581 -11.1792 -13.0266 -8.8424 -10.4253 -13.6648 -8.43789 -10.864 -14.4582 -8.15855 -11.836 -14.2218 -7.40815 -11.1984 -14.39 -7.50815 -10.3493 -13.833 -7.73919 -9.78851 -13.0602 -8.69194 -9.5251 -12.6894 -8.8771 -9.51789 -11.6972 -8.4554 -9.15536 -10.8237 -8.87759 -10.052 -10.5062 -8.65496 -10.61 -9.72589 -8.62205 -11.5521 -9.44363 -8.2884 -12.3513 -9.05721 -7.68595 -12.8646 -8.47714 -6.93661 -12.8435 -9.22012 -6.55986 -13.6916 -9.54576 -6.70145 -13.7537 -10.5393 -7.39232 -14.4503 -10.3409 -7.76018 -14.8882 -9.4393 -7.56342 -14.7948 -8.53601 -8.38479 -14.2832 -8.25175 -7.91057 -14.1773 -7.39615 -6.93806 -14.0688 -7.4368 -7.09775 -15.0221 -7.45542 -7.5277 -15.7643 -7.03764 -7.10024 -16.2367 -7.8377 -6.39862 -16.5571 -7.24068 -6.45542 -16.6141 -6.27711 -6.9382 -15.7375 -6.08447 -7.54399 -16.4932 -5.85333 -8.38355 -16.6557 -6.5119 -8.98168 -15.8332 -6.4327 -9.59853 -15.0467 -6.53628 -10.4048 -15.5745 -6.16371 -10.3533 -14.7571 -5.60759 -9.40528 -14.7894 -5.30358 -9.78853 -14.4462 -4.4502 -9.22517 -15.1867 -4.28488 -8.46034 -15.8291 -4.64717 -7.97392 -15.9049 -3.84282 -7.23768 -16.4916 -4.00835 -7.14843 -17.3246 -3.62494 -6.26529 -16.9677 -3.20357 -6.9008 -16.3477 -2.72829 -6.29827 -16.9441 -2.11066 -6.56759 -16.2965 -1.39074 -6.45277 -15.3779 -1.73354 -6.18603 -14.8944 -0.8646459 -7.20886 -14.7399 -0.7031989 -7.20508 -15.4899 -0.03741148 -7.87081 -15.8131 -0.6274159 -8.56897 -15.4552 -1.26276 -8.08718 -16.2482 -1.64878 -8.01027 -16.9547 -2.34229 -8.6823 -16.2388 -2.55132 -9.53846 -16.6617 -2.1021 -10.4549 -16.948 -1.76569 -10.6094 -17.9503 -1.65629 -10.3003 -18.6244 -2.33813 -10.9283 -18.3665 -3.0082 -10.8666 -17.4326 -2.93123 -11.2107 -17.0107 -3.82966 -12.0806 -16.6559 -3.38857 -11.2798 -16.0391 -3.23827 -11.3702 -15.2834 -3.81482 -10.9111 -15.0232 -2.93437 -10.234 -15.7092 -2.69967 -9.54151 -15.2703 -2.16359 -8.62893 -15.0166 -2.59885 -7.91824 -14.6397 -2.01552 -8.41877 -13.7612 -1.61467 -7.86414 -12.9334 -1.35217 -6.86709 -12.918 -1.23862 -6.99661 -13.1055 -0.2396639 -6.37191 -12.6925 0.4544401 -7.21537 -12.155 0.6467831 -6.96755 -11.2098 0.6621711 -6.10012 -11.4678 1.09045 -5.18656 -11.7317 1.05229 -4.64201 -12.6029 0.9085221 -3.96073 -12.6907 0.1999071 -4.24115 -12.9963 -0.7029599 -4.14116 -12.1537 -1.30164 -4.41584 -11.3046 -0.7857039 -4.54614 -10.7535 -1.60206 -4.96966 -11.0075 -2.4678 -4.56578 -10.0279 -2.31058 -3.99097 -10.0968 -3.13683 -4.38046 -10.1602 -4.05287 -3.44935 -10.3088 -4.42954 -2.75922 -10.6561 -3.796 -3.15894 -11.4051 -4.3193 -3.86987 -11.3728 -4.95634 -4.73141 -11.604 -5.38043 -4.71704 -11.9217 -4.41599 -5.00136 -11.819 -3.44411 -5.93799 -12.0209 -3.2228 -6.53213 -11.2204 -3.08825 -6.91413 -10.56 -3.59847 -7.03893 -10.2475 -2.64763 -7.54125 -9.42891 -2.79159 -7.77987 -9.33016 -1.81889 -8.37191 -8.94872 -1.08869 -9.33152 -9.42079 -1.02123 -9.55304 -8.45991 -1.26295 -10.1561 -8.78401 -2.04645 -11.1472 -8.49093 -1.9784 -11.0882 -8.27614 -0.9747249 -11.6988 -8.06292 -0.2589369 -12.0617 -7.46132 0.4891011 -13.0565 -7.34464 0.5661621 -13.3426 -8.28816 0.7858061 -14.2119 -7.91538 0.8524281 -14.266 -8.02555 -0.1710859 -13.3694 -7.84711 -0.5781579 -13.4122 -7.13814 -1.357 -12.4209 -6.788 -1.50552 -11.9655 -7.01482 -2.42397 -12.0363 -6.08248 -2.70237 -11.5488 -5.65784 -3.53724 -10.6407 -5.83002 -3.09309 -10.0679 -5.53119 -3.79976 -9.53158 -6.28542 -3.78973 -8.59791 -5.90835 -3.61802 -7.79096 -5.42077 -3.51839 -7.60621 -4.9503 -2.66599 -7.78089 -4.73546 -1.68444 -6.86221 -5.18376 -1.74862 -6.09004 -5.74975 -1.38276 -5.13523 -5.83403 -1.73495 -4.29457 -6.01257 -1.21094 -4.31118 -5.17223 -0.7511719 -3.91306 -4.18338 -0.7061149 -3.70608 -3.54983 -0.01380658 -3.35511 -4.00323 0.8552491 -3.67106 -4.87979 1.17929 -3.57215 -5.48052 1.9717 -4.39092 -4.82273 2.03693 -5.05281 -4.20025 1.69458 -5.67759 -3.96331 0.9142551 -6.47147 -3.33585 1.02416 -7.27254 -3.50517 1.57748 -7.42827 -3.41891 0.6020611 -6.69442 -3.33049 -0.02872248 -6.53198 -4.00995 -0.7389029 -6.60142 -4.62446 0.04610632 -6.70687 -5.57994 0.01449072 -7.05457 -5.85488 -0.8878029 -7.66146 -6.314 -1.49332 -8.00027 -7.28499 -1.30876 -8.57763 -7.59813 -0.5547109 -8.86358 -8.53546 -0.3417539 -9.00317 -9.06635 0.5594771 -8.30789 -9.57841 1.15268 -7.38742 -9.70226 0.6961601 -6.86897 -9.86302 -0.1731819 -6.58268 -8.95046 -0.4952539 -6.44067 -8.51472 -1.37293 -5.59091 -8.89991 -1.08258 -5.23648 -8.26992 -1.81345 -5.1861 -8.51143 -2.78537 -6.09208 -8.10927 -2.67162 -7.03601 -7.98396 -2.62204 -6.77415 -7.30499 -3.36455 -7.82985 -7.38092 -3.39608 -8.73781 -7.07884 -3.11437 -8.97148 -7.85212 -2.6308 -9.58131 -8.08004 -3.34803 -8.6426 -8.44359 -3.58101 -9.08103 -9.17499 -4.07645 -8.55998 -10.0267 -4.15071 -9.0453 -10.4298 -4.96676 -8.51897 -9.57066 -5.25595 -7.69199 -9.72929 -5.82812 -7.57013 -10.2593 -6.68073 -8.08105 -10.8022 -7.25719 -8.32954 -10.416 -8.14212 -8.23525 -9.52461 -8.37869 -9.26845 -9.50178 -8.11719 -9.14069 -8.50732 -7.90363 -9.16327 -7.72532 -7.21815 -9.83255 -7.58466 -7.94662 -10.1991 -8.00796 -7.13177 -10.4307 -8.90692 -7.39468 -11.4014 -9.13696 -7.48312 -11.7537 -9.93861 -6.95195 -10.8615 -9.96528 -6.5613 -10.2662 -9.27542 -6.1077 -10.5123 -9.9064 -5.33012 -11.1876 -9.23873 -4.9554 -10.4814 -8.52063 -5.02168 -10.0601 -7.76095 -5.51943 -9.32095 -7.31692 -5.03026 -8.66063 -6.83595 -5.58032 -7.96648 -6.17924 -5.24486 -7.2028 -5.60568 -5.03075 -6.88888 -5.57903 -5.9449 -7.36905 -5.04168 -6.54782 -6.69727 -4.25686 -6.54668 -5.75908 -4.48956 -6.36231 -5.11415 -4.49833 -7.14939 -5.74159 -5.33049 -7.00516 -5.65625 -6.36623 -6.84081 -4.93005 -5.89934 -6.39083 -5.64791 -5.5818 -5.72945 -5.46573 -6.22026 -4.97413 -5.71861 -7.08522 -5.42383 -5.36125 -7.864 -4.90879 -5.35857 -8.76861 -5.35921 -4.4655 -9.2829 -5.13587 -4.90013 -9.4516 -6.07981 -4.86943 -10.2455 -5.66286 -3.84154 -10.3872 -5.65353 -4.03772 -11.1442 -6.38544 -3.0985 -10.998 -6.50588 -3.66772 -10.4807 -7.1692 -3.38625 -9.8332 -7.90543 -2.80248 -9.06254 -7.98907 -3.04307 -8.43376 -7.26475 -3.94868 -8.67012 -6.94741 -4.60957 -8.72689 -7.6913 -5.37152 -9.33758 -7.44218 -6.23932 -8.81815 -7.23745 -6.36899 -8.44352 -8.11641 -6.49601 -8.37431 -9.10603 -6.65328 -9.20643 -9.43752 -7.63537 -9.21536 -9.13509 -8.13671 -8.4072 -8.70674 -8.6593 -7.56868 -8.88272 -9.51259 -8.00875 -9.09746 -9.39162 -8.78782 -9.75098 -10.2894 -8.41411 -9.75635 -10.1519 -7.43656 -10.0205 -9.44544 -7.12849 -10.5546 -9.84334 -6.3273 -10.0665 -10.6508 -6.73696 -10.5416 -11.1715 -7.51566 -10.9749 -12.0509 -7.50892 -10.5664 -12.5633 -8.36977 -10.6608 -13.2917 -8.98368 -10.4919 -13.3217 -9.57413 -11.3705 -12.9205 -10.1612 -10.7109 -11.9945 -10.1179 -10.4775 -11.951 -10.7835 -9.66425 -11.1633 -10.1636 -9.62402 -10.449 -10.6962 -10.2006 -10.3419 -10.9033 -11.1582 -10.6211 -9.89502 -11.0539 -10.5029 -9.91881 -12.0405 -9.91344 -10.5871 -12.533 -10.1415 -11.431 -12.0927 -10.2006 -11.3678 -13.1303 -11.0206 -11.6942 -12.6199 -10.476 -12.4276 -12.3438 -11.3275 -12.4508 -11.7907 -10.9038 -13.29 -11.7643 -10.1675 -13.0616 -11.0871 -10.8015 -13.4942 -10.4659 -10.387 -12.7948 -9.83815 -10.1815 -13.1578 -8.89406 -11.1659 -13.3811 -8.89382 -12.1579 -13.3209 -9.0368 -12.9412 -13.6016 -9.68723 -13.8545 -13.6618 -10.0882 -13.5176 -14.4636 -10.5042 -13.5372 -15.3427 -11.0052 -14.2379 -15.4298 -10.2369 -14.343 -15.7325 -9.31888 -13.5825 -16.3571 -9.32601 -13.5393 -16.7316 -10.2558 -12.8635 -17.3462 -10.6065 -13.5094 -18.0626 -10.4759 -13.0771 -18.5991 -11.1994 -13.8581 -19.2286 -11.1324 -14.3682 -18.9506 -11.9642 -13.793 -19.3385 -12.7049 -13.1012 -19.8477 -13.1889 -13.6837 -19.6585 -13.9591 -14.2178 -18.757 -13.8423 -15.0028 -18.2931 -13.4463 -14.5492 -17.7808 -14.1968 -13.6744 -17.7347 -13.7443 -14.1039 -17.272 -13.0026 -13.9141 -16.288 -12.7834 -12.9323 -16.4217 -12.4142 -12.8443 -17.2553 -11.9513 -12.1043 -16.5585 -11.5892 -11.5025 -15.8723 -11.2345 -10.9528 -15.458 -11.9245 -11.8432 -14.9268 -12.0277 -12.0531 -13.9814 -12.2129 -12.7299 -14.2439 -11.5528 -11.9269 -14.2866 -10.9462 -12.3234 -13.3737 -10.8919 -13.0738 -13.202 -11.4229 -13.1983 -12.8561 -12.3366 -13.5634 -12.1887 -11.7304 -14.2314 -11.4556 -11.8367 -14.9035 -11.8938 -12.4331 -15.0642 -11.402 -13.3015 -15.9437 -11.3659 -12.8802 -16.9942 -11.1167 -12.7179 -16.5841 -10.3728 -12.1884 -16.2366 -10.1869 -11.2895 -15.8715 -10.601 -10.4364 -15.098 -10.8969 -9.89738 -15.162 -11.8246 -10.3704 -14.999 -12.5722 -9.72839 -14.2773 -12.0192 -9.40972 -14.2035 -12.2367 -8.47922 -15.1465 -11.9505 -8.69266 -16.1651 -11.8852 -8.58495 -17.0461 -11.9676 -8.01577 -17.1838 -11.7005 -8.96081 -17.7621 -12.3705 -9.31126 -17.8324 -12.6803 -8.43652 -17.4395 -13.5977 -8.2515 -17.371 -13.5056 -7.27658 -17.697 -13.2494 -6.3019 -18.0262 -12.3565 -6.01589 -18.4708 -12.2315 -6.89595 -19.4783 -12.0107 -7.01584 -19.4295 -12.1998 -7.95609 -19.3597 -13.1947 -7.88341 -18.5657 -13.5319 -8.43073 -18.805 -14.1393 -7.72182 -19.4479 -14.6613 -8.26357 -20.1238 -15.3463 -8.13733 -21.0212 -15.2858 -7.74005 -21.5275 -16.077 -7.32583 -20.7691 -16.7182 -7.60817 -20.0434 -16.9472 -8.32499 -20.1211 -16.2948 -9.09327 -19.2413 -16.1437 -9.54523 -19.2876 -15.1832 -9.61484 -18.6011 -14.907 -9.0201 -17.7281 -15.2275 -8.56614 -16.8923 -15.5855 -9.07284 -16.081 -15.2415 -9.53921 -15.9845 -16.1793 -9.7063 -16.8438 -16.6794 -9.84755 -17.3405 -15.8706 -10.2263 -18.0538 -15.7868 -9.62154 -18.6771 -15.5842 -10.4056 -19.4133 -15.5924 -11.1085 -19.4698 -16.237 -11.8988 -18.462 -16.4008 -12.1568 -17.5854 -16.0136 -12.3078 -16.7478 -15.4853 -12.4281 -16.995 -14.6227 -11.959 -17.1927 -13.9676 -11.2897 -17.0253 -13.5483 -10.4025 -16.9613 -12.9715 -9.60839 -16.6911 -12.1332 -10.163 -17.0967 -11.8812 -11.0523 -17.138 -12.2771 -11.9959 -17.0523 -12.9294 -12.8103 -16.513 -13.6018 -12.4003 -15.5347 -13.8245 -12.433 -15.1871 -14.6953 -12.1941 -14.7378 -15.6371 -12.0042 -15.1014 -15.5918 -11.0842 -15.1467 -16.4987 -11.4604 -16.0669 -16.775 -11.1168 -15.6836 -17.4002 -10.4479 -16.447 -18.1136 -10.1934 -17.3356 -17.7362 -10.373 -17.2965 -18.6071 -9.74915 -16.7959 -19.3415 -10.1203 -15.949 -19.8304 -10.3409 -15.2045 -19.1408 -10.3459 -15.2186 -18.6679 -11.2383 -15.3279 -19.405 -11.8706 -16.0409 -18.9153 -12.4059 -16.7905 -18.8284 -11.7772 -16.893 -17.9398 -12.2336 -17.4359 -17.9876 -11.4317 -18.1628 -18.6201 -11.5541 -18.3827 -17.8354 -12.1461 -19.1593 -18.4759 -12.1199 -19.506 -19.4437 -11.9901 -19.3985 -20.2181 -11.3532 -18.6832 -20.7344 -11.1277 -18.3844 -21.6171 -10.8795 -19.1305 -22.2833 -11.2086 -19.9494 -21.6721 -11.0535 -20.3045 -20.8299 -11.5303 -20.6344 -20.8836 -10.5866 -20.2441 -20.8023 -9.62064 -20.4938 -20.843 -8.67102 -21.3998 -20.417 -8.81347 -21.9043 -19.9425 -8.0207 -21.4972 -20.4296 -7.24466 -21.1938 -21.2682 -6.94792 -20.306 -21.521 -6.69856 -20.1968 -20.5726 -6.42844 -20.0923 -19.5479 -6.38618 -19.2874 -20.0845 -6.52706 -19.5102 -20.5403 -5.60411 -18.5223 -20.5964 -5.76013 -18.021 -20.3406 -4.94868 -18.5771 -20.3351 -4.27859 -18.3386 -19.3562 -4.02526 -17.6744 -19.7346 -3.25588 -17.9455 -20.6628 -3.05037 -17.1369 -20.3427 -2.47726 -17.1675 -21.2103 -2.88548 -16.5949 -20.8714 -3.55979 -16.5705 -21.0056 -4.5522 -15.6983 -21.2738 -4.88471 -15.1821 -20.6324 -5.44226 -15.2781 -20.8128 -6.40552 -16.1035 -21.4459 -6.35505 -15.6041 -21.8431 -7.17012 -15.8767 -21.6715 -8.17596 -16.0761 -22.4329 -8.79514 -16.7757 -22.347 -9.38504 -15.8505 -22.2669 -9.77472 -15.2229 -21.4232 -9.77967 -14.2716 -21.0862 -9.79212 -14.1804 -21.8975 -9.30797 -13.6295 -21.9072 -10.181 -13.2349 -21.6702 -11.0806 -12.6004 -21.2858 -11.7254 -13.2407 -21.123 -12.4796 -12.4252 -20.5434 -12.3969 -11.6538 -20.0156 -11.8447 -11.2837 -19.0747 -11.5967 -11.61 -18.3593 -10.9807 -11.1581 -17.7233 -11.6149 -10.7744 -17.1943 -12.3802 -10.0304 -16.664 -12.6816 -10.6052 -16.7103 -13.4848 -10.4967 -17.5918 -13.9574 -10.0227 -17.9619 -14.845 -10.9374 -17.6287 -15.0543 -11.8211 -17.5962 -14.6991 -12.3735 -18.3216 -15.0652 -12.953 -18.1758 -15.8707 -12.1676 -18.3893 -16.3975 -11.8537 -17.4328 -16.4338 -11.692 -16.7108 -17.146 -12.0428 -16.1004 -17.8951 -12.6691 -15.4202 -18.1985 -11.6907 -15.2116 -18.3959 -11.3697 -14.4137 -18.8619 -10.7552 -13.8704 -18.3441 -11.0367 -13.8112 -17.3748 -11.8756 -13.6262 -17.8578 -12.8288 -13.4857 -18.179 -13.6459 -13.0231 -18.4467 -12.9723 -12.2996 -18.2031 -12.4534 -12.5593 -19.0844 -11.6648 -12.8487 -19.6514 -11.2092 -12.6971 -20.5448 -10.7487 -11.8201 -20.1334 -10.8937 -11.3722 -21.0044 -10.7009 -10.4508 -21.2679 -9.69529 -10.4289 -21.4727 -9.05949 -9.76 -21.1737 -9.29175 -8.77412 -21.4394 -9.92717 -9.00838 -22.1707 -10.7098 -9.13546 -22.7047 -11.1274 -8.98838 -23.5885 -10.6282 -8.84405 -24.5231 -10.2736 -8.5995 -25.4573 -10.7571 -9.05496 -26.1894 -11.7235 -9.19945 -26.5783 -12.038 -8.96956 -25.689 -12.434 -9.42547 -24.9038 -12.3539 -10.4895 -24.999 -12.3068 -11.4339 -25.01 -11.4115 -11.2497 -25.4261 -10.4777 -11.3579 -25.6515 -10.3325 -10.3294 -25.3209 -9.9904 -10.2232 -24.3782 -9.0149 -10.1112 -24.204 -8.1923 -10.1255 -23.6275 -7.71534 -9.31333 -23.3709 -7.10703 -9.07895 -24.196 -6.36254 -9.52666 -23.6437 -5.48575 -9.94006 -23.5653 -4.4855 -10.0848 -23.6982 -4.55219 -9.8755 -24.7236 -5.03996 -10.6665 -25.1191 -5.71951 -9.88415 -25.2155 -6.38372 -10.5937 -25.0992 -6.04027 -10.7708 -24.1219 -6.52838 -11.2158 -23.3637 -5.84321 -11.9558 -23.4396 -4.82979 -12.1253 -23.7253 -4.18847 -12.7165 -23.2207 -3.36575 -12.8884 -23.6483 -3.53699 -13.8485 -23.5635 -2.57767 -13.3872 -23.6244 -2.82372 -14.0861 -24.3806 -2.29729 -13.9253 -25.2147 -1.70206 -13.5929 -25.9415 -0.679832 -13.6076 -26.0561 -0.624631 -12.6524 -25.8032 -0.363763 -12.7929 -24.8744 --0.553066 -13.1349 -24.9577 --1.08198 -12.5739 -24.318 --1.18515 -11.6178 -24.6602 --1.53364 -10.7374 -24.704 --1.44942 -10.1147 -25.5357 --1.89679 -10.5634 -26.3497 --2.77312 -10.6566 -26.0663 --2.58796 -11.4316 -26.6232 --3.45545 -11.7596 -26.9972 --4.49246 -11.8389 -27.1338 --4.73709 -11.9121 -26.1114 --5.26404 -11.1867 -25.6341 --4.82201 -10.3591 -25.2223 --4.59079 -9.45452 -25.6798 --4.30582 -8.57349 -26.0146 --4.13153 -8.63267 -27.0338 --4.93398 -8.20025 -27.4668 --5.40559 -8.62589 -26.6373 --5.97947 -8.217 -25.9441 --6.10227 -7.52326 -25.2308 --6.02459 -8.21388 -24.4846 --5.17923 -8.19067 -24.9265 --4.26758 -8.17787 -24.4326 --3.31304 -8.50231 -24.3601 --2.37386 -8.81591 -24.6847 --2.14763 -8.49457 -25.6232 --2.47493 -9.11257 -26.3064 --2.43499 -8.24223 -26.7642 --2.05686 -7.82373 -27.5694 --2.87996 -7.30278 -27.8501 --2.47467 -6.86599 -28.7091 --2.55547 -6.17227 -29.4823 --2.77028 -5.51532 -30.2266 --3.56456 -5.22332 -30.6832 --4.46566 -5.00346 -31.0947 --4.25684 -5.90501 -31.4851 --4.83914 -6.12385 -32.2307 --4.23706 -6.67659 -32.8404 --5.02763 -7.0392 -33.3756 --5.41441 -6.25851 -33.7622 --5.62017 -6.53651 -32.8166 --5.9776 -5.58788 -32.7651 --6.78577 -5.22067 -32.1989 --7.22698 -5.84146 -31.5705 --6.80498 -5.29561 -30.879 --7.08258 -4.40809 -31.1662 --6.25854 -3.98036 -31.5403 --6.20669 -3.9328 -30.541 --5.2917 -4.1839 -30.622 --5.44181 -5.17917 -30.6533 --5.36446 -5.58224 -29.8194 --5.44892 -5.74942 -28.8561 --5.52172 -5.69574 -27.8393 --5.34708 -4.78328 -27.4012 --4.98305 -4.04673 -27.8924 --4.00026 -3.84221 -27.7686 --3.34843 -3.10239 -27.3892 --3.95654 -3.45567 -26.6991 --4.58625 -3.92136 -26.1203 --5.23571 -4.67152 -26.0901 --4.60115 -4.62578 -25.2468 --5.13497 -5.08735 -24.6006 --4.9594 -5.95682 -25.0332 --4.58028 -6.17099 -24.1252 --3.66113 -6.13427 -23.6629 --3.00388 -5.51385 -24.1295 --2.9284 -4.97053 -24.9508 --2.31679 -4.57201 -25.5148 --1.481 -4.14728 -25.4206 --1.49622 -3.21439 -25.715 --1.91179 -3.4969 -24.8789 --2.89859 -3.54596 -24.7028 --3.4522 -2.81949 -25.1813 --3.41464 -2.37489 -24.2725 --2.87868 -2.44938 -23.3732 --1.97259 -2.46578 -23.6949 --2.32006 -2.19155 -24.5702 --1.92087 -2.19526 -25.4738 --1.96078 -1.38319 -26.0276 --2.36445 -1.75369 -26.8497 --2.82435 -1.60776 -27.6917 --3.40889 -1.8416 -28.5284 --2.65431 -2.33685 -28.9978 --3.37024 -3.08132 -28.852 --3.2166 -3.66471 -29.6552 --2.74331 -3.57402 -30.5587 --2.34027 -4.43414 -30.4157 --1.87892 -4.76276 -29.5656 --1.13367 -5.11015 -28.922 --1.42095 -5.911 -28.2546 --0.514804 -6.16766 -27.9123 -0.30984 -5.63255 -28.2645 -1.01312 -4.91042 -27.8106 -1.70366 -5.56329 -28.155 -1.67356 -6.40045 -28.7324 -1.07509 -7.10905 -28.3467 -0.378744 -7.16207 -27.6471 -0.59648 -7.99223 -27.1231 -1.21777 -8.80267 -27.0221 -1.33124 -9.73073 -27.1334 -1.32599 -9.79311 -28.1838 -2.06316 -10.3185 -28.4482 -1.54932 -10.875 -27.7093 -2.38797 -11.4755 -27.6945 -2.74992 -11.1643 -28.5808 -3.01294 -10.7741 -29.4268 -2.1235 -10.6966 -29.8688 -1.22844 -10.3557 -30.1457 -1.88245 -10.2032 -30.8499 -1.6241 -9.27519 -31.122 -1.25264 -9.24674 -30.1533 -0.662253 -8.93441 -29.4547 -1.07226 -8.29959 -30.185 -1.3483 -7.46237 -30.7181 -1.14107 -6.68209 -31.3539 -1.03811 -7.17039 -32.1842 -0.258963 -6.71685 -32.6243 --0.559825 -6.54549 -32.0764 -0.05563857 -6.68193 -31.3108 --0.491517 -6.35043 -30.5024 --1.27695 -6.42923 -29.9649 --1.05844 -6.97196 -29.2045 --0.907072 -7.67172 -28.4507 --1.7059 -8.01974 -28.9285 --2.52022 -8.66188 -28.9562 --3.4569 -8.62872 -28.6793 --3.2755 -9.32385 -28.0037 --3.23824 -10.2811 -28.0962 --2.63774 -11.1083 -28.1209 --1.76325 -10.6698 -28.2727 --0.926648 -11.1135 -28.2792 --0.154868 -11.7072 -28.5499 -0.779505 -11.7585 -28.2021 -0.577126 -12.5346 -28.722 -1.01173 -12.4228 -29.5983 -0.956487 -13.441 -29.481 -0.558534 -12.9939 -30.2834 -0.647323 -13.7062 -30.9684 -1.56628 -13.9829 -31.2527 -1.5012 -13.3128 -31.9465 -1.8158 -12.4835 -31.5019 -0.995354 -11.876 -31.4247 -0.567644 -12.081 -32.3021 -0.248048 -11.1892 -32.7198 --0.386714 -10.9423 -31.9891 --0.843948 -11.842 -32.0845 --1.57965 -11.9478 -32.8116 --2.59472 -11.9923 -32.9848 --2.23384 -11.1056 -33.1427 --2.36742 -10.1212 -33.3227 --2.71828 -10.5844 -34.1401 --3.63276 -10.7363 -34.379 --4.01873 -9.86801 -34.7167 --4.79302 -9.16045 -34.9905 --5.40267 -9.91529 -35.0408 --6.21782 -9.84282 -34.4419 --5.51295 -9.97518 -33.6518 --5.99287 -9.44515 -32.9445 --6.20132 -10.3098 -32.4232 --5.55665 -10.0832 -31.7506 --4.68075 -10.3109 -32.2513 --3.75314 -10.484 -32.0135 --2.977 -10.1863 -31.3713 --2.72698 -11.0117 -30.9056 --2.87056 -10.8709 -29.8934 --3.42946 -11.5711 -30.3072 --3.6314 -11.8413 -29.3711 --3.7448 -12.7933 -29.1269 --2.81304 -13.2143 -29 --2.59273 -13.7921 -28.1547 --1.78191 -14.0598 -28.7576 --2.59435 -14.2114 -29.3375 --2.84954 -14.9817 -28.7974 --2.02076 -15.1233 -29.3869 --2.22078 -14.5614 -30.2077 --2.50211 -15.3008 -30.8127 --2.62613 -15.8691 -31.6306 --2.70874 -15.407 -32.5239 --3.55662 -14.9703 -32.5077 --4.21798 -14.8696 -31.7745 --4.89102 -15.3784 -31.2167 --5.07004 -14.3746 -31.039 --4.56543 -13.6513 -31.5643 --5.19086 -12.9928 -31.207 --6.04407 -13.1054 -30.7424 --6.19457 -13.6507 -29.8998 --6.20547 -13.9823 -28.9992 --6.56648 -14.8268 -28.9209 --7.16823 -15.3557 -28.3393 --6.90997 -15.6028 -27.4893 --7.34242 -15.8744 -26.5528 --7.03234 -16.7688 -26.748 --7.2547 -17.6794 -27.2276 --6.29257 -17.5782 -27.5554 --6.48471 -16.6313 -27.9161 --5.53339 -16.3038 -28.063 --5.67459 -15.4596 -27.6032 --5.99193 -14.4656 -27.8063 --4.99545 -14.7378 -27.9567 --4.7748 -15.6384 -28.2976 --4.29305 -16.3411 -27.7602 --3.86194 -15.4139 -28.017 --2.98677 -15.3318 -27.5615 --2.22672 -15.8911 -28.0164 --1.41694 -15.6822 -28.5575 --0.646638 -16.074 -29.0383 --0.397092 -15.8012 -28.1403 --0.5841 -16.6033 -27.5392 --0.879644 -16.6255 -26.568 --0.521249 -15.7135 -26.4626 --1.23132 -14.9612 -26.6012 --0.518984 -14.251 -26.663 --0.523716 -13.9367 -27.6378 --0.20481 -13.1461 -28.1314 --0.861486 -12.9982 -28.9072 --0.412185 -13.473 -29.6124 --0.182832 -14.2224 -28.9765 -0.426702 -14.8163 -28.403 -1.3129 -15.3276 -28.6253 -1.66404 -16.1157 -28.1114 -1.62657 -15.7972 -27.1697 -0.903471 -15.7164 -26.5476 -0.765417 -16.6175 -26.3567 -0.880303 -17.5441 -26.0889 -1.89707 -17.5321 -26.061 -2.32855 -18.1382 -25.3644 -1.45077 -18.5868 -25.6523 -1.0479 -19.2023 -25.0304 -1.32267 -19.4127 -24.0621 -2.09783 -19.0854 -24.5272 -2.57571 -19.7754 -23.9653 -3.0414 -20.184 -23.1783 -2.33611 -20.5202 -22.5592 -2.83801 -20.5078 -21.701 -3.00188 -20.8071 -20.8034 -3.71325 -21.1516 -21.3781 -3.91205 -21.208 -20.3714 -4.54606 -21.7196 -20.9169 -4.77602 -20.7193 -21.0606 -4.80299 -19.8728 -21.5498 -4.51762 -20.7307 -22.0979 -4.57297 -19.8866 -22.6433 -5.54137 -19.9835 -22.4729 -5.42792 -19.2747 -23.1832 -5.44166 -19.711 -24.0137 -4.91236 -20.5227 -24.2816 -5.63499 -21.0103 -24.6572 -6.56576 -21.3033 -25.0408 -7.16424 -21.4814 -25.8898 -6.84638 -20.9699 -26.6879 -6.98027 -20.0933 -26.9815 -7.50737 -19.2946 -26.975 -7.80008 -18.3851 -26.8231 -7.32317 -18.3796 -27.6853 -6.44758 -17.899 -27.4004 -6.20873 -17.9321 -28.3638 -6.34007 -18.9078 -28.4514 -6.15166 -19.0913 -29.4464 -5.69385 -18.3789 -29.9725 -5.42198 -18.052 -29.0809 -4.80773 -17.3716 -29.606 -3.85093 -17.6359 -29.4383 -3.54324 -17.0621 -30.1318 -3.28077 -16.5677 -29.3487 -3.85116 -16.9316 -28.5991 -4.22929 -16.2715 -27.9874 -3.61482 -15.7801 -28.4694 -4.49909 -15.339 -28.6497 -4.69167 -15.2001 -27.6657 -5.68084 -15.0186 -27.4773 -5.66918 -15.8308 -26.7545 -6.05802 -16.2043 -27.6143 -6.69515 -16.2358 -28.3664 -7.43249 -15.7988 -27.9296 -8.04751 -16.6166 -28.0173 -8.95022 -16.5478 -27.5222 -8.7509 -16.6875 -26.5519 -8.66684 -16.9689 -25.6088 -7.93004 -16.3289 -25.9131 -7.52233 -16.9981 -25.1919 -8.16789 -17.1179 -24.4055 -8.51726 -18.0034 -24.5759 -7.76046 -18.5311 -24.9653 -8.26286 -19.0237 -25.6967 -9.11909 -19.5521 -25.5662 -9.6674 -19.9614 -24.8341 -9.36758 -19.5603 -24.0111 -9.71097 -18.8484 -23.4191 -9.91658 -18.4162 -22.5345 -10.7579 -18.5296 -22.0161 -10.7664 -19.3471 -21.4758 -11.5279 -19.9044 -21.3187 -11.8915 -20.1794 -22.2222 -12.6973 -19.7468 -21.9194 -12.7852 -20.3757 -22.7263 -13.3292 -20.632 -23.5514 -13.4752 -21.5047 -23.9737 -13.1537 -21.6533 -24.8679 -13.3275 -21.0276 -25.6407 -12.8764 -20.2171 -26.0973 -13.0388 -19.5873 -26.9026 -13.6184 -19.0849 -26.2738 -13.5587 -18.1361 -26.0939 -13.835 -18.3849 -25.1519 -13.1161 -18.4425 -24.3643 -12.4486 -18.4747 -23.7068 -12.7966 -19.3866 -23.5037 -12.8579 -18.8749 -22.6204 -13.0134 -17.9925 -22.2419 -12.588 -17.5563 -21.4621 -11.7095 -18.0384 -21.5748 -10.9247 -17.6441 -21.1799 -11.3474 -16.9299 -20.6619 -11.2398 -17.1269 -19.6472 -11.0711 -17.6729 -18.8322 -10.5879 -18.5693 -18.9895 -11.6483 -18.645 -18.9701 -11.9896 -19.5261 -19.4061 -12.1777 -20.4823 -19.2152 -12.7425 -21.1859 -19.5812 -13.534 -21.3841 -18.9716 -13.5533 -20.3777 -18.7243 -13.6597 -19.3756 -18.4117 -14.5079 -19.6058 -17.8605 -14.3696 -18.6726 -18.1917 -13.8902 -18.6813 -17.2889 -14.2964 -19.4534 -16.844 -13.8836 -18.8588 -16.1062 -14.1219 -17.9965 -15.7398 -15.021 -17.9166 -15.3536 -15.8157 -18.4727 -15.2823 -15.3523 -19.2932 -15.6161 -15.5973 -20.1148 -16.0267 -14.7908 -20.0871 -15.4163 -14.4999 -20.6217 -16.1994 -14.4935 -20.8031 -17.171 -13.7367 -21.211 -16.6155 -13.3535 -21.9859 -17.0621 -13.9134 -22.3007 -17.8359 -13.1086 -22.4337 -18.3733 -12.7485 -23.0859 -18.995 -13.7114 -23.0087 -19.1073 -14.4331 -23.0951 -19.7443 -14.6442 -23.1021 -20.731 -13.6472 -23.4078 -20.7863 -12.9265 -24.0757 -20.7849 -12.9137 -24.6385 -20.0039 -13.4248 -24.9077 -20.8176 -13.1772 -25.4239 -21.6317 -12.5213 -25.3094 -22.3177 -12.7114 -24.4921 -22.8817 -11.7947 -24.1747 -22.8288 -11.3222 -24.1469 -23.7954 -10.3858 -24.0424 -23.414 -10.4226 -24.9802 -23.0995 -9.72927 -24.8652 -22.3063 -9.83954 -23.9071 -22.0072 -9.56914 -24.0692 -21.0482 -9.90157 -24.4061 -20.2121 -9.14565 -24.6332 -19.5284 -9.65273 -23.9595 -18.9872 -10.518 -23.766 -18.4006 -10.6395 -22.7973 -18.0399 -10.8227 -21.9991 -17.4574 -11.5774 -21.5418 -17.0673 -11.0193 -21.6557 -16.294 -11.1189 -20.7757 -16.7343 -11.2056 -20.0747 -17.4413 -10.4645 -20.3758 -18.0466 -10.4713 -21.0458 -18.7275 -10.0723 -21.9686 -18.6107 -9.25549 -22.4879 -18.8545 -9.07569 -23.2173 -19.5635 -8.47135 -23.1156 -20.3332 -7.92134 -22.4266 -19.7771 -6.97099 -22.9323 -19.8422 -7.36124 -23.2402 -20.6742 -7.05892 -24.1907 -20.9196 -6.97074 -24.9608 -21.6174 -7.50667 -25.4617 -20.9658 -8.03961 -25.5878 -21.7907 -8.83553 -25.928 -21.222 -8.18798 -26.6192 -21.545 -7.44354 -26.6049 -20.9258 -7.16997 -26.9468 -20.0951 -8.03407 -27.2859 -20.412 -8.28212 -27.549 -19.4903 -7.75917 -27.0846 -18.7993 -7.23471 -26.228 -18.5828 -8.09615 -25.8278 -18.1313 -8.0119 -26.7454 -17.6509 -7.66004 -26.4889 -16.7077 -7.0012 -25.8358 -16.1749 -6.07736 -26.1412 -16.531 -5.19126 -25.9822 -16.9332 -5.30001 -25.4225 -17.6665 -4.99487 -24.542 -17.4581 -4.84378 -24.6103 -16.4763 -4.03099 -24.9792 -16.1006 -3.68288 -24.069 -16.0953 -4.5959 -23.605 -16.2331 -3.86345 -23.0581 -15.7277 -3.66842 -22.1019 -15.6366 -4.44255 -22.2054 -14.9581 -4.21291 -21.2708 -15.1999 -4.76323 -20.4773 -14.9393 -5.66103 -20.1248 -15.0223 -5.739 -19.9744 -16.018 -5.16279 -20.0965 -16.8303 -4.89575 -20.3109 -17.7972 -4.17046 -20.9811 -17.9269 -4.51684 -21.9014 -17.8269 -5.23199 -22.7013 -17.8388 -6.06518 -22.4194 -18.3384 -6.46958 -22.5766 -17.4627 -6.55573 -22.7228 -16.4735 -7.50401 -22.9115 -16.4373 -7.44964 -23.6301 -15.7202 -6.72281 -24.3062 -16.0531 -7.11046 -24.5414 -16.8984 -8 -24.4518 -17.2486 -8.1661 -24.7277 -16.2794 -8.80678 -25.0491 -15.5228 -9.75171 -25.0546 -15.3218 -10.6403 -24.6051 -15.2272 -10.8032 -23.6272 -15.245 -11.3153 -24.1974 -14.6185 -12.0515 -24.2957 -13.9372 -12.7912 -24.9006 -13.7944 -13.701 -25.3309 -13.8457 -14.1857 -24.4994 -14.0153 -14.6343 -23.6486 -14.4012 -15.6386 -23.7889 -14.3368 -16.2817 -24.1007 -14.9781 -17.2261 -23.8973 -15.148 -17.1019 -24.8721 -15.0619 -17.1599 -24.7516 -16.0014 -17.3539 -23.7965 -16.4071 -17.8914 -23.0954 -16.7842 -17.0729 -22.747 -17.2491 -16.9625 -21.8535 -16.8683 -16.4428 -22.6219 -16.403 -15.6334 -22.5211 -17.0605 -15.4402 -22.1734 -18.0255 -16.2596 -22.0516 -18.621 -16.281 -21.4801 -19.4674 -15.272 -21.45 -19.6547 -14.4919 -21.0218 -19.3708 -14.4827 -21.0699 -20.3203 -14.3937 -20.0891 -20.6419 -15.2591 -20.2013 -20.0479 -15.2322 -19.2317 -19.696 -15.3255 -18.4293 -19.1919 -16.3204 -18.4439 -19.1157 -16.4327 -17.9813 -18.2078 -16.7581 -18.8953 -17.873 -17.7688 -19.1172 -17.6779 -17.4339 -18.7452 -16.7992 -17.7999 -17.8916 -17.156 -17.4971 -16.9014 -17.0154 -16.987 -16.7673 -17.8442 -16.0071 -16.9277 -17.8095 -16.3357 -16.042 -18.0832 -15.8522 -15.2491 -17.7307 -15.0268 -15.3902 -17.2562 -14.2734 -14.6977 -17.4562 -13.3763 -15.0437 -17.412 -12.8254 -14.9499 -16.528 -12.139 -14.4217 -17.0652 -11.8915 -14.332 -16.0891 -11.8838 -13.7272 -15.3349 -12.4026 -14.0729 -14.5583 -12.0394 -14.4195 -13.678 -12.9144 -14.8831 -13.807 -13.1419 -14.8408 -12.8802 -13.7817 -14.1203 -12.6378 -14.2988 -14.5272 -13.4366 -15.2095 -14.9256 -13.7233 -16.0709 -14.886 -13.2813 -16.8565 -14.7059 -13.8844 -17.4549 -15.5032 -14.1596 -18.1093 -16.1326 -14.6099 -19.1191 -16.2713 -14.5576 -18.4838 -16.9854 -14.3561 -18.3764 -17.8012 -14.9375 -18.8833 -17.6984 -15.8364 -19.7245 -18.0248 -16.3655 -20.1495 -17.9916 -17.2058 -20.9699 -17.7827 -17.5859 -21.3857 -17.0593 -17.0054 -20.7868 -16.3499 -16.8 -20.6298 -15.3494 -17.1891 -19.8264 -16.0005 -17.3016 -19.2928 -16.1446 -18.1329 -18.6018 -16.7547 -17.8141 -18.6002 -16.3506 -16.9155 -18.1379 -15.6157 -17.4622 -17.7339 -15.6081 -18.4144 -17.1829 -16.2762 -18.8843 -16.297 -16.59 -19.3318 -16.5266 -15.7402 -19.8113 -15.5639 -15.6182 -19.5572 -15.699 -16.3879 -20.1923 -16.5975 -16.8251 -20.46 -16.6926 -17.1292 -21.3322 -17.2365 -16.2922 -21.7437 -17.0608 -16.9711 -22.4366 -16.6029 -17.6605 -22.9884 -15.7083 -17.2031 -22.9868 -15.7606 -16.5044 -22.2943 -14.8901 -16.0169 -22.2864 -14.8155 -15.0747 -22.5815 -15.7039 -15.2188 -22.2098 -15.8292 -14.4334 -21.5628 -16.5984 -14.8143 -21.107 -16.9572 -14.1128 -20.4506 -16.669 -13.1479 -20.4214 -15.8169 -12.8073 -20.0318 -14.8406 -12.6048 -20.2706 -13.8779 -12.827 -20.1218 -13.9749 -12.6475 -21.0685 -13.4412 -12.8735 -21.8637 -13.6789 -13.5508 -22.5351 -12.8481 -13.2971 -23.0953 -12.6076 -12.8744 -23.9928 -13.3394 -13.258 -24.5136 -13.6613 -13.9972 -25.1404 -14.1916 -14.3543 -24.3928 -15.149 -14.325 -24.0012 -15.6066 -13.4368 -23.9599 -14.7152 -13.2297 -24.3327 -14.2023 -12.9686 -25.1885 -15.1557 -12.5179 -25.2881 -15.343 -12.2639 -24.3119 -16.2864 -12.667 -24.5346 -17.0044 -11.9874 -24.2286 -17.5338 -12.4472 -23.4786 -16.6446 -12.5393 -22.9703 -16.5696 -11.6857 -22.4515 -17.3692 -11.9046 -21.9321 -17.8746 -11.0886 -21.707 -18.1737 -10.6253 -20.8764 -18.4803 -10.4366 -19.9717 -18.5569 -10.3192 -18.9542 -18.1234 -9.43081 -18.7172 -19.1582 -9.12823 -18.59 -19.7534 -9.87292 -18.3789 -20.4141 -10.1856 -19.1105 -20.9787 -9.62175 -18.4886 -21.0624 -10.3766 -17.8638 -21.4583 -9.85113 -17.0377 -20.722 -10.338 -16.6207 -20.7459 -9.59063 -15.9855 -20.8548 -8.95527 -15.1671 -19.9242 -8.703 -15.2473 -18.9201 -8.90411 -15.1719 -18.1238 -9.3561 -14.8699 -17.9836 -10.0041 -15.5943 -18.157 -11.0105 -15.6977 -18.6745 -11.5815 -15.1005 -18.6827 -10.9554 -14.3532 -18.5079 -11.6897 -13.6771 -18.159 -12.6452 -13.7128 -19.0323 -12.7534 -13.3496 -18.3701 -13.1307 -12.7089 -19.0798 -13.74 -13.0787 -19.6096 -14.2332 -12.4014 -19.8024 -14.9354 -13.1348 -19.8351 -15.8218 -13.5386 -20.7654 -16.2443 -13.3746 -21.1662 -16.203 -14.338 -22.1071 -15.9597 -14.491 -21.8826 -16.2741 -15.4213 -22.3855 -15.4327 -15.7371 -22.3595 -14.4144 -15.5923 -21.9658 -14.2895 -14.6841 -22.76 -13.8064 -14.3805 -23.7425 -13.9464 -14.7379 -24.3193 -13.9623 -15.5688 -24.8131 -13.1584 -15.2952 -25.6912 -13.5739 -15.4855 -25.6251 -14.4952 -15.2866 -26.3669 -15.1185 -15.078 -26.7458 -15.381 -14.1844 -27.7658 -15.4354 -14.3337 -27.8699 -14.6975 -15.0492 -28.7781 -15.208 -15.1462 -29.6164 -14.7923 -14.6655 -29.9572 -14.4356 -13.7453 -29.8541 -14.6583 -12.8038 -30.2491 -14.4595 -11.8887 -31.1175 -14.1393 -11.4102 -30.4487 -13.5883 -11.0262 -29.7189 -13.1534 -11.6149 -29.3205 -13.0365 -10.7325 -28.4554 -12.6286 -10.6393 -28.2075 -11.8614 -10.0456 -28.6695 -11.3561 -10.8066 -28.5348 -10.7129 -11.5541 -27.5467 -10.5919 -11.8849 -26.7544 -11.2417 -11.7694 -27.0448 -12.0857 -12.0829 -26.6559 -12.3735 -11.2575 -26.3066 -12.9885 -11.8995 -26.412 -13.0773 -12.8836 -25.7073 -13.7919 -12.8896 -25.8508 -13.8904 -13.9273 -25.772 -14.827 -13.6461 -25.2992 -15.6238 -13.279 -24.5212 -15.0165 -13.2247 -24.2121 -14.7299 -12.344 -24.9053 -15.254 -11.9832 -25.4244 -16.0721 -12.063 -25.6387 -17.0187 -12.1493 -24.6835 -17.0759 -12.4246 -23.775 -16.8107 -12.6708 -23.2459 -16.5785 -11.8284 -22.2539 -17.0322 -11.6962 -21.9275 -17.2061 -10.7655 -22.3346 -18.0584 -10.8395 -22.1421 -18.7998 -11.4673 -21.9957 -19.4888 -10.756 -22.2083 -20.3753 -10.3815 -23.2334 -20.2544 -10.1242 -24.1489 -19.9433 -9.93108 -23.7081 -19.8917 -9.07961 -24.1058 -20.3655 -8.27278 -24.3172 -21.2307 -7.89243 -24.1376 -20.516 -7.34119 -23.3707 -19.9827 -7.00076 -24.2276 -19.7348 -6.54321 -24.8567 -19.2319 -6.00323 -25.4487 -18.4073 -6.18263 -25.9119 -19.0874 -5.59996 -25.9277 -19.5393 -6.49261 -25.5308 -20.1325 -5.8481 -25.525 -21.1127 -5.91317 -25.3167 -21.9881 -5.48851 -26.2641 -21.8018 -5.05621 -26.4218 -21.5999 -4.06819 -26.2218 -22.4812 -3.68343 -26.1272 -23.3827 -3.95668 -26.3054 -23.9281 -3.0688 -27.2155 -24.1161 -3.50476 -26.8765 -24.9242 -3.78457 -27.5058 -25.6642 -4.2416 -27.1023 -26.527 -4.53879 -27.0619 -25.9043 -5.33441 -26.6871 -25.9842 -6.24525 -26.4865 -25.0119 -6.56307 -27.4421 -24.8808 -6.73176 -26.9309 -23.9615 -6.61002 -27.3001 -24.0946 -7.57501 -28.2015 -24.2194 -7.83352 -27.7642 -23.8312 -8.64523 -28.446 -24.0256 -9.39189 -27.5266 -23.8397 -9.74 -27.8445 -22.9525 -10.1512 -28.2282 -22.1332 -9.72605 -28.1529 -21.1953 -10.1234 -29.1037 -20.7761 -10.1733 -28.4622 -20.0265 -10.1448 -29.1432 -19.2432 -10.0976 -29.8741 -18.9771 -10.5654 -30.1066 -19.335 -9.69267 -29.9655 -19.0886 -8.71425 -30.1273 -18.0954 -8.94987 -30.0183 -17.9663 -9.97725 -29.6359 -17.1072 -9.59605 -29.0034 -16.8667 -8.85634 -28.2419 -16.9473 -8.19144 -27.8492 -17.1085 -9.0712 -27.5697 -16.108 -9.40298 -26.9925 -15.3652 -9.78794 -26.2743 -15.6365 -9.15202 -26.5107 -15.5092 -8.19827 -26.8303 -14.7332 -7.8175 -27.4228 -14.0303 -8.14973 -28.3852 -14.0894 -8.02409 -28.9399 -13.4063 -8.40876 -29.7726 -13.8112 -8.89635 -30.3518 -13.6393 -8.07892 -31.3164 -13.7703 -7.91874 -31.4135 -12.8393 -7.64175 -31.0896 -12.0376 -8.23817 -30.6434 -11.0984 -8.18926 -29.9714 -10.4298 -8.54088 -29.2192 -11.0595 -8.82531 -28.6715 -11.8448 -8.89409 -28.1345 -12.4835 -8.40983 -27.1843 -12.5256 -8.74668 -26.3993 -11.8476 -8.85674 -26.9703 -11.0674 -8.87206 -26.6709 -10.3475 -8.30911 -26.9508 -9.37132 -8.08685 -26.7855 -9.03903 -9.01802 -25.8574 -8.97002 -9.57433 -25.5988 -9.82136 -9.25645 -24.7619 -10.1389 -9.67106 -23.8746 -10.4125 -9.51316 -24.2453 -11.3345 -9.30173 -25.2589 -11.2778 -9.45013 -25.5803 -10.9257 -8.58106 -25.4702 -10.0831 -8.14629 -25.9919 -9.55072 -7.54039 -25.6746 -8.64846 -7.40779 -25.4433 -8.33951 -6.53427 -24.4989 -8.50595 -6.65493 -24.5153 -8.46665 -5.6737 -24.5739 -9.48034 -5.60575 -24.6297 -9.99906 -4.73285 -24.8183 -10.7433 -5.35782 -23.9116 -10.8019 -5.00426 -24.1648 -11.5341 -5.60111 -23.613 -12.3761 -5.33393 -22.6821 -12.3583 -5.29033 -22.8572 -12.652 -6.18695 -23.2679 -13.5634 -6.02049 -24.2666 -13.5665 -6.01619 -24.754 -14.2365 -5.55548 -24.7638 -14.1989 -4.50225 -25.0228 -15.1215 -4.21487 -24.1141 -15.333 -4.31866 -23.8079 -15.7368 -3.45891 -23.4561 -16.6754 -3.2757 -23.4303 -16.9574 -2.33522 -23.0118 -16.0143 -2.13419 -23.2693 -15.0072 -2.06275 -24.2651 -14.9787 -1.99105 -24.2919 -15.5924 -1.17515 -24.3155 -14.841 -0.4582359 -25.1283 -15.3465 -0.5036229 -25.2348 -14.4185 -0.06488168 -24.5136 -13.818 0.3570951 -25.2275 -13.1663 0.1421131 -24.9876 -13.2893 1.18684 -25.4414 -12.5948 1.77893 -25.4408 -13.2653 2.54706 -24.9729 -14.048 2.83926 -24.8891 -14.9278 3.4192 -25.372 -14.6094 4.14297 -26.0984 -15.3206 4.3032 -27.0125 -15.1236 4.00847 -27.62 -14.3943 4.23565 -28.6482 -14.582 4.03427 -29.0918 -15.1636 4.73254 -29.8524 -14.8481 5.19703 -30.1908 -15.7599 5.5041 -30.9153 -16.2851 5.18205 -30.3733 -16.7639 4.38364 -30.5791 -16.5679 3.50156 -29.5863 -16.8946 3.44013 -29.2717 -17.7348 3.96828 -28.8955 -17.6863 3.01384 -27.979 -17.3281 2.97434 -27.9624 -16.3674 2.77893 -28.3396 -15.4744 3.11057 -28.2026 -15.4439 2.1149 -27.2821 -15.1192 1.80134 -27.0399 -15.8175 1.08392 -26.6147 -16.5257 1.63729 -25.6737 -16.2316 1.37181 -25.6096 -16.7365 0.4545581 -26.5481 -17.1039 0.4675381 -26.2607 -16.4009 -0.1796899 -27.165 -16.0062 -0.2613949 -26.9674 -14.9999 -0.2270869 -27.4847 -14.2596 0.1759851 -27.0817 -13.3405 0.1084141 -26.8075 -12.5783 -0.4656639 -26.9694 -12.4699 -1.44124 -27.6937 -13.1783 -1.31868 -28.2051 -12.5574 -0.7864819 -29.1858 -12.3897 -0.8843409 -30.028 -11.8729 -0.6570859 -29.8736 -11.1222 -1.23453 -29.7886 -10.0779 -1.44002 -29.5036 -9.27114 -1.97535 -29.2124 -8.98143 -2.90251 -29.2178 -8.91597 -3.89201 -28.6765 -8.61849 -4.70993 -29.5922 -8.21236 -4.77392 -29.0873 -7.48039 -4.33529 -28.2973 -7.04118 -4.72241 -28.8451 -7.25546 -5.55126 -29.6016 -6.68431 -5.89783 -29.146 -5.79975 -6.06689 -28.4489 -6.38146 -6.47533 -27.7792 -6.5174 -7.19291 -28.4144 -7.30587 -7.19045 -27.5922 -7.66761 -6.82407 -28.0313 -8.41514 -7.26508 -27.6739 -8.3423 -8.24136 -27.7314 -8.66511 -9.23767 -27.272 -7.95581 -9.75733 -27.4269 -7.34492 -10.6114 -28.0425 -7.82302 -11.1699 -28.9176 -7.39337 -11.0902 -29.1076 -8.37356 -11.1194 -28.8413 -9.14644 -11.7364 -28.1088 -8.74703 -12.2712 -27.91 -7.75473 -12.6816 -28.5952 -7.8109 -13.4033 -28.448 -8.34285 -14.2751 -27.4154 -8.17272 -14.4191 -27.2249 -9.13546 -14.517 -26.403 -9.14191 -15.0485 -26.2999 -8.92309 -15.9905 -26.335 -7.95828 -16.1425 -26.1207 -7.8743 -17.2313 -25.7488 -6.93528 -17.2774 -25.0781 -7.511 -17.7133 -24.3484 -8.1919 -17.3384 -23.4965 -7.92555 -16.9085 -24.0928 -7.13886 -17.3378 -23.7939 -6.32786 -16.8285 -24.083 -6.34021 -17.7856 -25.0421 -6.4905 -18.0405 -25.6939 -6.59736 -18.812 -25.1952 -6.86743 -19.6415 -24.2383 -7.07014 -19.4521 -24.0692 -6.04984 -19.5603 -23.9515 -5.07739 -19.2637 -22.9602 -5.11552 -19.1409 -22.2975 -5.47456 -19.8141 -23.1025 -5.51085 -20.3748 -22.9175 -4.91009 -21.1221 -22.9449 -4.10277 -21.6805 -22.2681 -4.0511 -20.918 -22.7767 -3.23688 -21.1903 -23.669 -2.91219 -20.9701 -24.4482 -3.2365 -20.4153 -24.4829 -2.2752 -20.5939 -23.8886 -1.45106 -20.5562 -24.1081 -0.6395911 -21.1532 -23.9008 -0.8702291 -22.0768 -23.2073 -0.3687301 -22.5884 -23.443 -0.8388981 -23.4634 -22.6238 -1.49794 -23.4334 -22.933 -2.03632 -24.2382 -22.6485 -1.68762 -25.1797 -22.008 -1.04586 -25.5934 -22.795 -1.24581 -26.1267 -23.0418 -2.00049 -26.722 -23.7473 -2.7081 -26.854 -22.9626 -2.87833 -26.2518 -22.9877 -3.47937 -27.0963 -22.297 -2.88416 -27.3404 -21.6239 -2.39729 -28.0017 -20.6922 -2.69721 -27.8727 -20.1675 -3.16173 -27.1671 -20.3995 -4.12942 -26.9853 -20.803 -4.90785 -27.4347 -21.3814 -4.09716 -27.5813 -20.6819 -4.34135 -28.2495 -21.3811 -3.76857 -28.7777 -21.5944 -4.34063 -29.5771 -22.4986 -3.91032 -29.2903 -23.1906 -4.06023 -30.0174 -23.2526 -3.44768 -30.8714 -24.1149 -3.76465 -30.5387 -24.3467 -4.31427 -29.707 -24.4271 -4.98895 -28.9177 -24.9098 -5.04433 -28.0529 -24.4678 -5.82152 -27.7627 -23.6286 -5.67018 -27.2847 -23.9147 -4.7631 -26.974 -24.3337 -5.0812 -26.1947 -23.8891 -5.95304 -26.1686 -24.1818 -5.8353 -25.1993 -23.2958 -6.32126 -25.3782 -22.5389 -6.18362 -24.7652 -21.7665 -6.44275 -25.3246 -21.3527 -7.18337 -25.7122 -21.3011 -7.12181 -24.7215 -21.6829 -8.11301 -24.5958 -21.506 -8.92243 -25.2364 -22.311 -9.47341 -24.8775 -23.1141 -9.23952 -24.2518 -23.0592 -10.0614 -23.705 -23.3695 -9.70369 -22.8657 -23.8143 -9.34573 -22.0497 -24.5104 -8.88213 -21.4898 -25.2844 -9.42388 -21.0378 -25.9549 -10.0951 -21.3951 -25.2651 -10.7405 -21.0782 -25.218 -10.3991 -20.1564 -25.1875 -10.52 -19.1277 -24.4831 -10.1837 -18.5632 -23.6585 -9.94424 -19.1079 -23.9279 -11.0407 -19.0471 -23.801 -12.0576 -18.9863 -23.2658 -11.9927 -18.1027 -23.3301 -12.66 -17.3392 -23.1631 -12.8009 -16.3543 -22.6089 -12.2585 -15.8098 -23.4545 -11.9771 -15.401 -22.9035 -11.1408 -15.4111 -22.5068 -10.2177 -15.1901 -22.1747 -10.3074 -14.2348 -22.4918 -10.9561 -13.5444 -23.3821 -10.5623 -13.8674 -23.6899 -10.0789 -13.0289 -23.0102 -9.36278 -13.0826 -23.6127 -8.56719 -13.0767 -24.2071 -8.56377 -13.9308 -24.4373 -7.63862 -13.5312 -23.7957 -6.94776 -13.1547 -23.4686 -7.13899 -12.2649 -24.0515 -7.14962 -11.5233 -24.998 -6.93596 -11.1256 -24.7305 -6.24683 -10.5274 -25.0617 -6.00335 -9.65958 -24.8798 -5.13277 -10.0131 -24.5143 -4.39761 -9.4855 -25.1906 -3.71167 -9.43391 -25.5715 -3.50581 -8.52262 -24.9664 -3.22337 -7.7535 -23.9685 -2.94577 -8.07086 -23.2112 -2.43713 -8.50812 -23.6072 -2.41526 -9.44602 -23.0318 -2.94852 -10.0903 -22.1724 -2.68754 -10.5891 -21.5999 -3.26886 -9.89423 -22.1773 -3.71842 -9.24386 -21.2796 -3.81116 -9.00937 -21.6658 -4.66434 -9.31453 -21.7366 -4.84746 -10.3012 -22.1331 -5.34065 -11.1067 -22.7984 -5.94377 -10.6071 -21.8743 -6.48522 -10.7245 -20.9282 -6.62032 -10.4901 -20.6903 -5.64561 -10.658 -19.8887 -5.06712 -10.8806 -18.9299 -4.69647 -10.7343 -18.24 -4.35726 -11.3819 -17.3704 -4.24718 -11.9378 -17.5078 -5.2544 -12.2504 -17.2315 -4.76414 -13.1319 -16.45 -5.0031 -12.5275 -16.1456 -5.6531 -11.8936 -16.8412 -6.34056 -11.6283 -16.3256 -6.65243 -12.4293 -15.9479 -7.62838 -12.5761 -15.7642 -8.6454 -12.3845 -15.6314 -9.31242 -13.1746 -15.8787 -9.68678 -14.1503 -15.3911 -9.87962 -14.9556 -15.4817 -10.8665 -14.9273 -14.6932 -10.9133 -14.288 -14.4121 -11.4217 -15.1486 -13.3612 -11.4759 -15.2627 -13.6665 -10.9029 -15.9729 -13.7351 -11.7325 -16.5088 -13.6203 -12.0177 -17.4088 -13.7225 -11.2005 -18.0494 -12.9117 -10.6113 -18.2036 -12.7872 -9.58873 -18.3381 -12.4506 -9.61841 -19.3102 -12.1935 -8.83752 -18.8742 -12.0301 -7.95536 -19.146 -12.2501 -7.07887 -18.6758 -12.262 -7.04087 -19.6751 -11.7328 -6.58379 -20.4034 -12.0481 -5.74197 -19.9493 -12.2735 -5.4315 -19.0392 -11.9987 -4.53446 -19.4693 -11.3457 -4.38061 -18.6519 -11.8107 -4.77775 -17.795 -10.9612 -5.24133 -17.4803 -10.1627 -5.48166 -17.1198 -9.50442 -6.00443 -17.7127 -9.03355 -6.93538 -17.6181 -8.47608 -7.697 -17.2508 -7.67282 -8.08832 -17.6588 -7.44367 -7.09349 -17.3526 -8.01131 -6.32168 -17.6734 -8.52899 -5.5792 -17.267 -9.20995 -4.95803 -17.0931 -9.48674 -4.01858 -17.3245 -9.55304 -4.1095 -18.3254 -9.99739 -5.01114 -18.2295 -8.96042 -4.93942 -18.4538 -8.01403 -4.7303 -18.5468 -7.56015 -5.62165 -18.4576 -7.24437 -6.62524 -18.6136 -8.04479 -6.77965 -19.0786 -8.81672 -6.51161 -19.6569 -9.4934 -7.15882 -19.9466 -9.49722 -6.4162 -20.6217 -10.482 -6.34952 -20.7354 -10.5443 -6.49223 -21.6892 -11.016 -6.27755 -22.5506 -10.8751 -5.46711 -21.9762 -9.99186 -5.52541 -21.5626 -10.3452 -5.07223 -20.7521 -10.6289 -4.11602 -20.6422 -10.3005 -3.1362 -20.8727 -9.82521 -2.21148 -20.5974 -10.0545 -1.65698 -19.8201 -10.3975 -1.0747 -20.6657 -11.2907 -1.26083 -21.0455 -11.325 -0.2244581 -21.0545 -10.6341 -0.07507357 -21.7519 -10.5731 0.7147269 -22.3464 -10.1955 1.63406 -22.4924 -9.31664 1.82363 -22.9941 -8.59644 1.67396 -22.371 -8.42596 0.7606259 -21.9983 -7.52603 1.1453 -22.1477 -6.92562 1.22957 -21.2627 -6.41477 2.10737 -21.2184 -6.86134 2.85107 -21.7961 -7.28881 3.1331 -20.8803 -7.37179 3.98136 -20.404 -6.31289 4.05668 -20.3108 -5.89776 4.80545 -20.7904 -5.21834 5.55332 -20.7582 -4.65297 6.37954 -20.6603 -5.14382 6.33289 -19.7342 -5.98502 5.91106 -19.5562 -6.66824 5.35106 -19.1563 -7.06497 6.13764 -18.5724 -7.85859 6.0814 -19.1565 -8.48983 6.74274 -18.9131 -7.65529 7.25829 -19.2669 -7.80653 7.51277 -20.2417 -8.00427 7.82985 -21.2068 -7.70096 8.5143 -20.542 -7.19068 8.47607 -21.4967 -7.04273 8.28577 -22.4537 -6.15359 8.81529 -22.4977 -5.5929 8.32764 -23.0797 -5.62245 7.75697 -22.2752 -6.14285 7.00673 -22.7847 -7.03578 7.02336 -23.234 -7.86423 7.48317 -22.8901 -7.75152 6.63716 -22.3115 -8.05986 5.69336 -22.3032 -7.36735 5.06608 -22.1438 -7.33332 4.85268 -21.1945 -7.92832 5.01153 -20.3663 -8.84178 4.76354 -20.0779 -9.66964 4.10414 -20.0355 -9.23841 3.30958 -20.3508 -8.55118 3.46217 -19.6435 -8.16859 2.95729 -18.8266 -8.28443 3.73358 -18.1617 -7.72847 4.43352 -18.6847 -6.86605 4.03555 -18.6272 -5.98179 4.4017 -19.0393 -5.79104 3.5794 -18.5487 -5.20034 3.19953 -19.2469 -5.75031 2.43427 -18.9192 -6.13293 1.51064 -18.9893 -6.89337 1.67871 -18.2604 -6.10459 1.6592 -17.6439 -6.60068 2.5141 -17.483 -7.2963 3.02293 -16.9893 -8.16406 3.58456 -16.8183 -9.03713 3.16021 -16.8086 -9.36287 2.90658 -17.786 -10.2118 3.14535 -18.3026 -9.88897 2.20258 -18.4462 -10.164 1.66142 -17.5827 -10.3647 0.8572589 -17.129 -10.8485 0.8053339 -16.2602 -10.6953 0.09793843 -15.533 -10.8198 -0.4609421 -14.7428 -10.5965 0.1160509 -13.9522 -9.97413 -0.6918581 -13.8536 -9.87839 -1.63599 -13.4201 -10.3604 -1.01524 -12.7865 -11.1228 -1.66551 -12.9097 -11.301 -1.60182 -13.8775 -10.959 -2.54205 -13.4749 -11.8379 -2.22479 -13.0609 -11.8804 -3.20742 -13.2836 -12.017 -4.13863 -13.4871 -11.9104 -4.90725 -12.8167 -11.2375 -5.03063 -12.0366 -10.2937 -4.72942 -12.0508 -10.1573 -3.8177 -12.466 -9.62895 -4.09744 -13.3503 -9.79538 -3.06516 -13.4277 -8.85948 -2.88144 -13.6784 -8.9726 -2.59459 -12.7654 -9.56825 -2.32879 -12.0685 -9.23309 -1.36981 -12.2141 -9.38739 -0.4854961 -12.683 -9.94702 0.2010429 -12.3254 -10.5931 -0.3056611 -11.7696 -9.78948 0.09355763 -11.1951 -9.46303 -0.7424631 -10.7585 -9.05064 -0.6607541 -9.82044 -8.50449 -1.14242 -9.12951 -8.5666 -0.2787611 -8.69017 -7.89329 0.003295644 -9.41022 -6.91513 -0.1145211 -9.015 -6.81546 0.8590939 -8.67759 -5.87906 1.16888 -8.75542 -6.2072 1.95886 -9.32202 -6.49973 1.19249 -9.9543 -7.49017 1.24979 -10.1659 -6.89959 1.94796 -10.4711 -7.79777 2.22223 -10.2804 -8.68615 2.45645 -10.725 -9.47579 2.20275 -10.1316 -9.83387 1.64795 -10.8591 -10.0851 2.14067 -11.6578 -9.50146 2.79333 -11.3138 -9.73341 3.30789 -10.4883 -10.2841 4.08135 -10.3173 -10.3372 4.97512 -9.78593 -9.90736 5.66984 -9.13842 -9.83882 5.09525 -8.33365 -10.0946 5.46661 -7.3992 -9.93432 5.94395 -6.65128 -9.77468 6.85792 -6.73418 -9.05572 7.44037 -6.2922 -9.32653 6.60633 -5.7393 -8.48522 6.20226 -5.31691 -8.4886 6.82018 -4.57805 -7.52001 7.18109 -4.52401 -8.10647 8.00717 -4.49655 -8.72849 7.56266 -3.78362 -8.83162 7.11922 -2.87794 -8.34464 6.85635 -2.09231 -7.7579 6.31548 -2.71094 -7.53322 6.52506 -3.66986 -7.401 5.82748 -4.40383 -6.5936 5.2724 -4.66561 -5.62903 5.24096 -5.00128 -5.47037 4.33775 -5.35722 -5.98897 4.65013 -6.12624 -6.90924 4.79328 -6.17737 -7.24518 5.21535 -7.04011 -7.3467 5.88806 -6.26036 -6.49887 5.89597 -5.58445 -6.18269 6.82291 -5.87155 -6.51653 6.79875 -4.9112 -6.21958 6.38531 -4.04361 -5.65576 5.92132 -3.35793 -5.53134 5.78538 -2.39646 -5.51024 5.61904 -1.36 -5.46614 4.80102 -0.7213519 -5.56342 3.93131 -1.15315 -4.70782 3.7055 -0.5775349 -4.33792 2.9052 -1.04865 -3.6488 2.52788 -1.68681 -3.68136 3.35723 -2.28831 -4.60868 3.68362 -2.33755 -5.06392 4.54969 -2.43437 -5.97411 4.64432 -1.96572 -6.06719 4.45123 -2.90445 -6.56735 4.18022 -3.69939 -6.84709 3.2455 -3.96244 -6.25249 2.5304 -4.32443 -5.31744 2.59809 -4.01747 -4.78245 3.09539 -4.69412 -4.55181 3.69195 -3.85406 -4.02666 4.46481 -3.70274 -3.7753 3.97193 -4.53829 -3.37788 4.48498 -5.32139 -3.1311 4.87054 -4.50788 -2.40982 5.52329 -4.7372 -1.50144 5.96389 -4.57547 -0.837381 6.6891 -4.55061 -1.51242 7.32835 -4.95681 -1.2318 7.999 -5.61939 -2.07132 8.47597 -5.45056 -2.47597 9.43573 -5.56545 -3.38593 9.4684 -5.94584 -3.87668 8.98797 -5.14664 -4.13225 8.10067 -5.54933 -3.29302 7.48544 -5.5404 -3.62712 7.52176 -4.59314 -4.2146 6.65108 -4.54692 -3.25048 6.33987 -4.82225 -3.4754 6.20846 -5.80683 -4.15081 6.14521 -6.59411 -3.51736 6.85999 -6.77384 -4.01158 6.38712 -7.57539 -4.37193 7.21808 -7.16225 -4.07008 8.19652 -6.89853 -3.94993 8.14279 -7.86726 -4.57933 8.88804 -7.59343 -5.51764 8.86156 -7.81649 -5.46095 7.87323 -7.52744 -5.91795 7.21021 -6.8563 -5.79676 6.67497 -7.60364 -6.60302 6.01738 -7.65126 -6.19507 5.90688 -8.51202 -7.10244 5.72468 -8.87306 -6.57141 4.88027 -8.78316 -6.61732 4.09953 -9.38685 -6.43111 3.081 -9.42489 -5.7962 3 -10.1734 -6.07496 2.43715 -10.9647 -6.51881 3.11565 -11.5973 -6.57032 3.32356 -12.5609 -7.40635 3.93042 -12.6804 -8.03668 4.03978 -11.9065 -8.1488 4.75297 -11.1913 -9.01927 5.26095 -10.968 -9.71649 5.64889 -11.6276 -9.38183 6.33485 -12.2327 -8.37078 6.44808 -12.0336 -7.5173 6.87425 -12.2551 -6.80898 6.14408 -12.5147 -7.68864 5.93115 -13.0475 -8.28557 5.68163 -13.8402 -7.92576 6.23859 -14.6798 -6.93604 6.33008 -14.4608 -7.09488 6.97884 -15.1803 -7.06823 7.86142 -15.5981 -6.24323 7.7537 -16.0811 -5.29963 8.0926 -16.2411 -4.70596 7.25744 -16.1074 -4.15664 7.02818 -15.3362 -3.57626 6.32076 -14.9794 -3.32979 5.5224 -15.5376 -3.77655 4.59611 -15.4729 -3.87301 4.86542 -16.4355 -3.50081 4.19756 -17.0427 -2.70577 3.98901 -16.5369 -2.8612 3.34163 -15.7529 -3.19529 2.97499 -16.599 -2.66609 2.21388 -16.9912 -3.54406 1.95874 -17.3922 -3.95682 2.72012 -17.9704 -3.78366 3.62749 -18.2961 -4.0968 4.57844 -18.4011 -3.77522 5.47136 -18.6913 -4.0629 6.00749 -19.5107 -4.25354 7.02058 -19.2838 -3.43751 6.64512 -19.867 -3.00867 6.43205 -20.7848 -2.38617 6.84752 -21.3729 -2.0709 6.4896 -22.3222 -2.53383 6.62209 -23.2045 -2.18977 6.30646 -24.0833 -1.61252 6.60327 -24.8312 -2.65301 6.73655 -24.8664 -3.34414 6.00816 -25.0081 -3.08267 6.05736 -26.0135 -3.50899 5.1363 -26.1347 -3.28069 4.74597 -27.0133 -3.24162 4.88047 -28.0608 -4.1502 4.8764 -27.9491 -4.45513 4.52331 -28.8361 -4.8052 3.8377 -29.3994 -5.70892 4.07492 -29.9118 -4.97103 3.87697 -30.511 -3.98478 3.80747 -30.699 -3.41675 4.5233 -30.3938 -3.12763 4.51863 -29.418 -3.29134 3.55173 -29.8865 -2.83218 3.33207 -30.8075 -2.47378 3.03689 -29.9614 -2.47982 2.80388 -29.0118 -2.30081 2.63418 -28.0162 -1.77025 1.79528 -27.837 -0.880822 1.6327 -27.4569 -0.468344 1.17956 -28.1264 --0.473379 0.7629199 -28.1304 --0.817281 0.3713149 -29.0043 --0.251656 -0.4155941 -28.6204 -0.336359 -1.0061 -27.9357 -0.981935 -1.47798 -28.557 -1.89055 -1.33582 -29.1727 -2.16018 -2.12165 -29.7418 -2.18177 -3.10533 -29.7973 -1.34594 -3.5632 -29.6523 -0.519632 -3.40402 -29.1321 -0.210036 -3.33602 -28.1677 --0.320677 -4.0814 -28.4856 -0.01516317 -4.62418 -29.252 -0.904583 -5.02677 -29.078 -1.33119 -5.43753 -29.8197 -1.92359 -6.00717 -30.4431 -1.89713 -6.76985 -29.7707 -2.5093 -7.36453 -29.3099 -2.283 -7.99623 -30.01 -3.25254 -7.92979 -30.2839 -3.51203 -8.9136 -30.382 -3.86999 -9.67557 -30.9128 -4.81746 -9.76867 -31.3594 -5.33818 -10.5129 -31.9569 -5.21463 -11.1104 -32.7599 -5.01113 -10.6709 -33.6872 -5.08952 -9.92232 -34.3676 -4.42354 -9.19072 -34.1802 -4.53919 -8.2287 -34.4126 -4.37979 -7.83525 -33.4759 -4.72326 -8.09277 -32.5792 -4.53667 -7.18129 -32.2742 -5.34955 -6.96061 -31.753 -5.51886 -5.92376 -31.7724 -5.39783 -6.22247 -30.9379 -6.35566 -5.92 -30.6892 -6.80085 -6.80366 -30.4697 -7.16652 -6.13492 -29.8468 -7.26347 -6.76673 -29.0221 -7.49331 -6.97518 -28.1247 -7.37385 -7.91778 -27.7451 -7.90949 -8.09481 -26.8869 -7.76338 -7.18915 -27.1929 -8.82503 -7.00363 -27.0507 -9.63547 -6.75775 -26.6117 -10.5011 -6.59575 -26.051 -10.1762 -7.40917 -25.6643 -10.7883 -7.94803 -26.324 -10.8396 -7.61944 -27.2289 -11.5814 -7.44588 -27.869 -11.4657 -8.20921 -28.5149 -11.7499 -8.86654 -29.1529 -11.979 -9.06614 -28.2791 -12.1384 -9.75317 -29.0523 -11.1896 -9.90994 -28.8298 -11.3431 -10.8054 -28.4115 -12.1131 -11.5149 -28.2817 -12.7952 -12.0665 -28.7832 -13.033 -13.0071 -28.9071 -13.0271 -13.6799 -28.2579 -13.8044 -13.8836 -28.8353 -12.9849 -14.4784 -28.8907 -12.2553 -13.8761 -29.2943 -11.3957 -14.2002 -29.7687 -11.0492 -14.4429 -28.8352 -11.0377 -15.3459 -29.2215 -10.3889 -15.0386 -29.9342 -10.017 -14.3301 -29.25 -9.16488 -13.7682 -29.3931 -9.03591 -13.0454 -30.1113 -8.64722 -12.2141 -30.4057 -8.27525 -12.3187 -31.3987 -8.21517 -12.3909 -32.3636 -7.54178 -11.6982 -32.4379 -7.86355 -11.348 -31.5243 -8.21355 -10.5573 -30.9218 -7.47991 -10.5909 -30.2689 -6.60058 -11.0237 -30.4514 -6.81952 -11.2692 -29.5327 -6.09657 -10.8189 -29.0003 -6.12094 -11.647 -28.3699 -6.70404 -12.2366 -27.8746 -7.12831 -12.3254 -26.9666 -7.20566 -11.5409 -26.3733 -6.36072 -11.5111 -26.8736 -5.54071 -12.106 -26.867 -4.78478 -11.862 -27.355 -5.20832 -10.9339 -27.1806 -5.04158 -10.8174 -28.1766 -5.17188 -9.83069 -27.8874 -4.84483 -9.59129 -26.9573 -5.02834 -9.05155 -26.15 -5.27432 -8.0303 -26.071 -5.05258 -7.32274 -26.7556 -4.52852 -7.01088 -27.5214 -4.14285 -6.46836 -28.2113 -4.59063 -5.79881 -28.8525 -4.74921 -4.97668 -28.3892 -4.90164 -4.73063 -27.4656 -5.68624 -5.00372 -26.9419 -6.38839 -4.83949 -27.678 -7.26102 -4.72727 -27.2083 -8.08763 -4.35776 -27.4991 -8.53558 -4.28826 -28.4263 -8.44947 -3.3774 -28.4398 -9.16201 -3.14369 -27.7462 -9.97739 -2.66013 -27.5914 -9.44574 -2.06197 -28.1615 -9.84319 -1.62023 -27.3382 -9.50087 -0.8550741 -27.8355 -9.80294 -0.1625891 -28.4933 -9.38476 0.5225719 -29.0625 -10.1141 0.5461579 -29.6858 -10.5956 1.31519 -29.2146 -10.0214 1.78767 -29.7784 -10.0002 1.29642 -30.6815 -10.0139 1.56712 -31.6304 -10.8484 1.12109 -31.8816 -10.9408 1.59128 -30.9907 -11.2471 0.7206639 -31.0477 -11.8473 0.03473953 -30.5507 -11.3176 0.1451689 -29.695 -11.7833 -0.2547441 -28.9011 -12.3364 0.3334029 -29.4862 -13.3807 0.3132039 -29.8085 -14.0512 -0.4090351 -29.8629 -14.5112 -1.28344 -29.5757 -14.6965 -1.41305 -28.5115 -13.8841 -0.8553391 -28.1293 -14.0767 -0.1549331 -27.5044 -13.6415 -0.9264271 -26.9782 -12.9158 -1.59268 -26.829 -12.9712 -1.57771 -25.8562 -12.971 -0.6946841 -25.3781 -13.624 0.07821713 -25.6714 -14.2629 0.3773859 -24.925 -14.5004 1.09407 -24.2732 -13.9984 1.69374 -24.9613 -13.1313 1.3904 -24.6008 -12.5443 0.9985149 -23.8762 -11.9775 1.07109 -23.1062 -12.1191 2.01265 -23.1514 -11.5126 2.22838 -22.3617 -12.3777 2.29544 -21.8151 -12.656 1.49234 -21.389 -12.0212 1.01422 -20.7757 -11.6526 1.0851 -19.8941 -11.7524 1.35294 -18.9656 -12.6694 0.9086989 -18.6513 -12.4745 0.01534483 -18.188 -13.32 -0.4357571 -18.4767 -13.3612 -1.46712 -18.5708 -13.1586 -2.3857 -19.0798 -13.463 -3.10622 -19.7748 -13.3349 -3.31244 -20.8021 -13.8867 -2.49516 -20.8328 -14.1358 -1.53501 -20.7255 -13.8217 -1.82163 -21.6675 -14.8642 -1.99195 -21.7782 -14.9807 -2.42784 -20.9365 -14.7901 -3.31141 -20.4453 -14.4959 -4.03357 -19.9594 -14.9408 -4.53342 -20.6615 -14.2089 -4.48987 -21.4295 -13.6773 -4.07448 -22.1025 -12.623 -4.09084 -22.0604 -12.3007 -5.02232 -21.8798 -13.2635 -5.10807 -21.6987 -13.8206 -5.56189 -21.064 -14.6592 -5.5568 -21.643 -15.2531 -5.18259 -22.3581 -16.3165 -4.961 -22.3923 -16.8019 -4.07673 -22.5902 -16.8093 -3.37573 -21.8703 -17.424 -2.75211 -21.3873 -17.9847 -2.18889 -20.7834 -18.4649 -1.57189 -20.176 -17.6894 -0.9479571 -20.0145 -16.853 -1.37769 -20.3474 -16.0997 -2.00263 -20.1842 -16.4455 -3.02969 -20.045 -15.5347 -2.81767 -19.6446 -15.8433 -2.2678 -18.8755 -15.6744 -1.84415 -17.9564 -16.5063 -1.43461 -17.5864 -16.269 -2.05528 -16.8256 -16.1718 -2.78498 -16.1242 -16.1267 -3.56592 -16.7523 -15.5378 -3.29951 -17.5547 -14.9829 -3.77185 -18.1466 -14.3896 -4.18561 -18.8649 -13.709 -3.92916 -18.1487 -13.5992 -4.93767 -17.9699 -13.1482 -5.35263 -17.1672 -13.6469 -5.05812 -16.3533 -14.5416 -4.58744 -16.3815 -15.1709 -4.12822 -15.7046 -14.2655 -4.53703 -15.3925 -13.6372 -4.19944 -14.7103 -13.2391 -5.07265 -14.5407 -13.6046 -5.08525 -13.6437 -14.5714 -5.26758 -13.7577 -14.2504 -6.12994 -13.6185 -15.1579 -6.04909 -13.3687 -14.8702 -6.70207 -12.6884 -15.0434 -5.8083 -12.4633 -14.7221 -4.91122 -12.5502 -13.7831 -4.95453 -11.9906 -14.51 -4.17466 -11.9651 -15.2092 -3.48703 -12.0078 -15.9064 -3.97296 -11.5874 -15.5223 -4.54755 -10.8732 -15.7846 -3.7937 -10.276 -16.1344 -2.90733 -10.4124 -16.7336 -3.31813 -9.65908 -16.8902 -4.26469 -10.0278 -17.8043 -4.66825 -10.0433 -18.5684 -4.73736 -9.38081 -18.0771 -3.9785 -8.94334 -18.4763 -3.3055 -8.32634 -18.0568 -2.49929 -7.95927 -17.6372 -3.22325 -7.3535 -18.285 -3.2772 -6.50694 -17.9076 -3.00723 -5.62582 -17.5737 -2.29616 -4.96249 -16.9633 -3.03125 -4.81968 -16.5352 -2.46328 -4.07578 -15.7388 -2.82766 -4.4039 -15.6945 -3.09081 -5.36262 -15.6537 -2.13673 -5.48058 -14.9886 -1.47996 -5.47458 -14.0808 -1.39733 -5.06001 -14.0184 -2.29772 -4.58455 -13.3486 -2.9164 -5.02938 -13.2026 -2.67986 -5.9712 -12.3556 -2.62363 -6.40864 -11.7994 -2.01497 -5.9234 -11.5779 -1.2715 -6.63538 -10.7233 -1.7547 -6.91737 -10.0097 -1.53289 -6.25041 -10.2788 -2.5241 -6.24662 -10.6859 -2.94635 -5.5698 -10.1941 -3.61472 -5.07301 -9.63327 -3.64186 -4.21502 -9.97663 -3.23628 -3.45578 -10.6255 -2.77138 -4.11198 -11.0764 -2.07859 -4.54257 -10.3794 -1.34971 -4.56577 -10.9056 -0.7742611 -5.1712 -10.7601 -0.5988941 -6.14657 -10.0201 -0.3498951 -6.736 -9.56173 0.2448189 -7.40254 -8.96884 0.8625779 -7.98209 -9.4966 1.76613 -8.04602 -9.30732 2.02573 -9.01255 -10.0298 2.79604 -9.10807 -9.39083 3.51902 -9.38468 -8.46473 3.72907 -9.22976 -7.49022 3.69925 -9.21644 -7.50989 2.73105 -8.95594 -7.64278 2.54439 -8.02612 -7.22861 2.43876 -7.08136 -8.0505 2.51764 -6.50477 -7.92638 3.2774 -5.84715 -8.91942 3.25491 -5.50088 -9.2904 2.37904 -5.21342 -9.00911 2.52287 -4.24593 -9.81047 2.05468 -3.97039 -10.0272 1.05703 -4.14349 -10.9899 1.22085 -4.10578 -11.2696 2.25939 -4.04336 -12.2606 2.4352 -4.32165 -12.0142 1.71169 -3.60098 -12.4887 0.8528349 -3.86981 -13.3957 1.20839 -3.76264 -13.8089 0.3693879 -4.07088 -14.6663 0.1264769 -4.48157 -14.6317 1.08248 -4.11927 -15.424 1.19376 -3.50812 -14.6279 1.64701 -3.23632 -14.0894 1.06398 -2.64908 -13.1095 1.17704 -2.34409 -12.6362 0.9105889 -1.54403 -11.9342 0.3793159 -1.13185 -12.1283 -0.1130141 -1.97592 -12.9193 -0.3969411 -1.65496 -13.4266 -0.02087787 -0.8681569 -13.7364 -1.00562 -0.9260419 -14.5763 -1.55985 -0.9393549 -15.5517 -1.61777 -1.37552 -15.679 -1.34246 -0.4467289 -16.2365 -1.07266 0.3592451 -16.1184 -0.6931541 1.26246 -16.4701 0.1262039 1.696 -16.4787 -0.5821111 2.41261 -17.3634 -0.6170291 1.92125 -17.5149 0.09815803 1.2855 -17.8434 1.02557 1.75355 -18.0722 0.2895029 2.46331 -18.8874 0.2942659 3.13181 -18.3704 -0.4801701 3.33966 -17.7438 -1.17191 3.1344 -18.4039 -1.79234 2.66889 -19.0699 -1.97952 1.98051 -19.6118 -2.67478 2.39672 -20.467 -2.38723 2.00689 -21.3418 -2.02659 2.48542 -22.3014 -1.94209 2.24263 -21.7882 -2.55163 1.55026 -21.2197 -3.22487 2.03667 -21.0667 -3.80485 1.25485 -20.8853 -4.71653 0.8937581 -20.8842 -5.22049 0.01490852 -20.3767 -5.40465 -0.8845299 -20.1103 -5.08309 -1.83054 -20.3476 -4.95361 -2.7484 -19.522 -4.45129 -2.55985 -18.8294 -4.33835 -1.81075 -17.9996 -4.52407 -2.26376 -17.7458 -5.4506 -2.44964 -16.7254 -5.30448 -2.17788 -16.2565 -4.60719 -2.74364 -16.2151 -3.72685 -3.29333 -15.7262 -2.99153 -2.789 -15.6614 -3.43015 -1.90665 -16.1292 -2.85876 -1.2366 -15.7095 -2.35385 -0.4792149 -14.8126 -2.49056 -0.00487544 -14.0135 -2.31098 -0.5730929 -14.0405 -3.34851 -0.6600199 -13.9938 -3.29242 0.3207961 -14.2157 -3.20544 1.2619 -14.4434 -2.32031 1.04644 -14.5337 -1.81509 1.97571 -14.6316 -2.22372 2.84149 -14.9318 -1.73737 3.66671 -15.1967 -0.8580311 3.32 -14.7638 -0.6207671 2.48605 -14.859 0.3912219 2.70661 -15.2655 1.19274 2.19759 -16.1679 1.5958 2.39472 -16.9944 1.80276 1.78754 -17.0867 2.28562 0.9947541 -16.6612 2.40308 0.09233732 -16.1987 1.89342 0.8373681 -16.2368 1.39975 -0.04241388 -16.8675 1.13099 -0.6943039 -16.1921 1.07362 -1.3948 -16.1127 1.96421 -0.9369509 -15.4527 2.17524 -0.2510649 -14.9275 2.30896 -1.13687 -14.9215 3.15452 -1.76988 -15.1967 4.02254 -1.35802 -15.7645 4.51021 -1.92093 -15.5495 4.06478 -2.77171 -16.1881 4.08262 -3.54525 -16.4537 4.07465 -4.55948 -16.4725 3.28822 -5.31195 -16.0486 2.6653 -5.96255 -16.5763 2.91005 -6.74614 -17.0608 2.73276 -7.61758 -17.7823 2.66657 -8.32062 -17.5337 3.07272 -9.24231 -16.5839 2.8334 -9.19496 -15.9743 3.33937 -9.83763 -15.3707 2.59274 -9.4717 -14.8341 3.40546 -9.60853 -14.4539 3.51085 -8.61991 -14.8824 4.28413 -9.05905 -15.5919 4.78013 -9.47673 -15.4002 4.74092 -10.4498 -15.397 3.85587 -10.9188 -14.4842 3.413 -11.0031 -13.7385 2.88276 -10.5732 -13.3438 3.40957 -11.342 -13.2453 4.2327 -10.8042 -12.3601 4.66098 -10.7721 -11.4175 4.73637 -10.3491 -11.2748 3.98291 -10.972 -11.1334 3.36611 -10.2302 -11.3071 3.38037 -9.22031 -10.6439 3.83747 -8.71752 -9.94018 3.45408 -8.12362 -10.8207 3.02489 -8.23461 -11.6785 3.13409 -7.70041 -12.0286 3.05186 -6.73526 -12.9149 3.3104 -6.33065 -12.7985 3.68912 -5.41154 -11.955 3.96476 -5.01626 -11.1483 4.37331 -5.46209 -10.8613 3.67797 -6.06642 -10.49 4.11244 -6.85732 -11.0824 4.87668 -7.25349 -11.4962 5.09625 -8.17717 -12.1741 4.71646 -8.88149 -13.1384 4.74822 -8.9724 -12.9058 4.12982 -8.25632 -13.3133 3.26413 -7.9317 -14.0789 2.62308 -7.77368 -14.3067 1.68003 -7.80587 -14.7082 1.71386 -6.94262 -14.427 1.15472 -6.08468 -13.6346 0.8188369 -6.65335 -14.2709 0.3366099 -7.22479 -15.0986 0.8485969 -6.84214 -15.4315 0.9707859 -7.81995 -15.0741 0.1821259 -8.19281 -14.5054 0.4836509 -9.03958 -14.3164 1.09207 -9.83175 -15.3352 0.8281999 -10.0375 -15.8757 1.37215 -10.6568 -14.9125 1.5054 -10.8169 -14.3003 1.04402 -11.5438 -14.4834 1.50661 -12.3781 -15.1933 0.9679929 -12.0703 -15.2584 -0.01956057 -11.7424 -14.2208 0.08999403 -11.7888 -13.4065 -0.4224071 -12.1781 -13.3072 -1.43451 -12.1269 -13.3096 -1.25892 -11.1301 -12.6519 -1.11074 -10.4171 -12.2453 -1.91768 -10.9155 -12.0635 -1.75737 -9.93255 -11.4086 -2.33386 -10.415 -10.9822 -1.65571 -10.9463 -11.536 -1.07534 -11.5186 -12.0409 -1.04854 -12.3552 -11.7672 -0.2290091 -12.8485 -11.9172 0.7501209 -12.5936 -12.8457 1.04173 -12.459 -13.2488 1.41438 -11.6478 -12.6421 2.11717 -11.2751 -12.7883 2.37552 -10.2456 -13.4358 1.55399 -10.09 -12.8206 0.9532059 -10.6801 -11.8302 0.9513919 -10.9439 -11.8546 0.2022549 -10.216 -11.8789 0.6913819 -9.3284 -12.2733 1.54588 -9.83028 -12.9037 1.54605 -9.06158 -12.7228 0.6377969 -8.60459 -12.2693 1.1903 -7.82237 -11.5584 1.90742 -8.06845 -11.6047 2.07137 -7.01683 -11.8871 1.59742 -6.1281 -11.4559 0.9709069 -5.50432 -12.462 0.7939929 -5.15642 -13.2961 1.32215 -5.07588 -13.7728 2.22116 -5.04628 -13.682 2.57907 -5.96767 -14.5425 3.11385 -5.94712 -14.297 3.41929 -6.88027 -14.0468 4.38618 -7.27132 -13.313 5.04661 -7.25834 -13.9517 5.69365 -7.75479 -13.5285 6.38308 -7.1187 -14.4408 6.57511 -6.78867 -14.89 5.65569 -6.66026 -15.8404 5.53981 -7.14943 -16.0236 6.10396 -6.38402 -16.8893 6.27406 -6.94976 -17.8401 6.37384 -6.77608 -17.967 5.35583 -6.44632 -18.8145 5.18112 -7.07649 -19.3614 5.89209 -6.7676 -19.352 6.22546 -7.68148 -18.4306 6.3424 -7.91496 -18.7468 6.60585 -8.8932 -18.0056 6.03088 -9.30931 -17.1587 6.1912 -9.81189 -17.6331 6.74784 -10.4772 -18.3913 7.29002 -9.95377 -19.1994 7.86115 -10.0286 -19.2825 7.90464 -11.0507 -18.8465 8.80903 -11.2177 -18.4513 8.61911 -12.091 -19.4699 8.85533 -12.2342 -20.0552 9.33022 -12.9695 -20.2094 10.3249 -13.2205 -19.5037 10.2139 -14.0166 -20.3405 9.83968 -14.321 -20.5369 9.60326 -15.2446 -21.2095 9.81526 -16.0299 -21.9992 10.1368 -16.4565 -22.8761 10.4307 -16.7392 -23.1207 10.8313 -17.6041 -23.1943 11.103 -18.6315 -22.2539 10.8663 -18.8297 -21.9497 11.4539 -18.0287 -21.0268 11.6202 -18.2114 -20.2085 11.9662 -18.6379 -19.9476 11.9958 -19.5739 -19.7844 11.2751 -20.2549 -20.7522 10.8393 -20.2955 -20.4533 10.2647 -21.0871 -19.5554 9.92699 -21.2499 -19.2872 9.06925 -20.8881 -19.4157 8.31743 -21.4635 -19.0646 7.46462 -21.8705 -19.7216 7.57518 -22.6319 -20.3874 6.89598 -22.1875 -20.2323 6.28496 -21.4063 -20.7337 6.47099 -20.5818 -21.6751 6.36479 -20.431 -21.7101 7.04941 -21.1726 -21.7536 8.00527 -21.6462 -20.9606 7.8585 -21.0786 -21.6316 8.44915 -20.604 -22.5156 8.06367 -20.1653 -23.4009 8.23874 -20.5528 -23.5232 8.54244 -21.3975 -24.1643 8.55011 -22.2233 -24.9396 7.89034 -21.9929 -24.8108 8.12099 -22.9272 -25.5894 7.4792 -23.2 -26.0837 6.57346 -23.2886 -25.2616 6.13181 -23.4358 -25.6963 5.39455 -23.9849 -26.0398 4.70646 -23.3035 -25.2131 4.12607 -23.4105 -25.6536 3.52208 -24.0806 -26.3351 3.14621 -23.4477 -25.8045 2.93677 -22.575 -25.2402 3.32625 -21.8372 -24.3347 3.68805 -21.6606 -24.0049 4.30727 -22.3326 -24.4184 5.08319 -22.829 -23.841 5.71679 -22.2985 -23.9992 6.4057 -23.0256 -23.0648 6.44134 -23.2946 -23.7556 6.27281 -23.9554 -23.6338 5.91802 -24.9007 -23.4787 4.92199 -24.9718 -22.52 4.60056 -24.7475 -22.3884 4.25722 -25.6656 -22.1294 5.25041 -25.7193 -21.1695 5.43938 -25.6191 -20.6089 6.10657 -26.1601 -19.8986 6.61584 -25.739 -19.0042 6.61912 -25.3213 -18.339 5.98529 -24.9693 -18.6889 5.05501 -25.1489 -19.0657 4.34923 -25.7066 -18.1529 3.97515 -26.0929 -17.3753 4.04641 -26.7362 -17.407 3.03092 -26.534 -16.4778 2.85526 -26.9508 -15.9507 3.11916 -27.7328 -14.958 2.8364 -27.7433 -14.4377 3.6663 -28.1046 -13.9859 4.55076 -28.2773 -13.1932 4.62419 -28.8549 -13.2278 5.57931 -29.0656 -13.0516 6.44268 -28.5633 -13.8585 5.80314 -28.1583 -14.0863 5.99596 -27.2717 -14.55 6.72797 -27.7527 -15.5066 7.10238 -27.634 -15.8199 7.77549 -28.2789 -16.1101 6.93692 -28.7445 -16.2878 6.11166 -29.2676 -16.6098 6.14589 -28.2516 -17.3422 6.78692 -28.661 -17.2551 6.43241 -29.5149 -17.4395 5.60016 -30.0574 -17.249 4.98773 -29.3235 -16.3513 4.65396 -29.5521 -16.8069 4.08169 -30.2669 -16.7062 3.36094 -30.9375 -16.6263 2.79152 -31.7828 -15.6642 2.47479 -31.8849 -14.9214 3.0126 -31.4689 -15.057 4.01079 -31.6645 -14.1634 4.01343 -31.2288 -14.0513 4.59775 -30.4022 -13.1186 4.81774 -30.1855 -12.2397 4.93471 -30.6912 -11.2974 4.96817 -31.0692 -11.3244 4.35369 -30.3675 -10.8036 4.30037 -29.5046 -10.4577 4.9605 -30.1591 -10.0127 5.50159 -29.4315 -10.6399 6.21043 -29.1637 -10.4951 6.93043 -28.4048 -10.6603 7.92603 -28.2242 -9.89596 8.41012 -28.5374 -8.95556 8.22957 -28.5538 -8.16985 7.59181 -28.8416 -7.3461 8.04894 -28.4607 -6.97548 7.18695 -28.7287 -7.55345 6.39697 -28.4303 -7.64747 5.40236 -28.2908 -7.68609 4.95802 -29.1409 -7.27036 4.90015 -30.0199 -8.06286 4.41247 -30.5232 -8.71962 4.37611 -31.1994 -8.64164 3.36824 -31.0376 -8.45495 3.63326 -30.0409 -7.60238 3.40644 -29.5667 -6.58974 3.40478 -29.8311 -6.12144 2.6088 -29.5908 -6.89167 2.47347 -30.1813 -7.18708 1.89536 -29.4289 -6.48826 1.30716 -29.0725 -5.51923 1.17368 -28.8169 -5.94878 0.7978029 -28.0479 -5.74863 -0.1570281 -27.9844 -4.895 0.2963629 -27.8227 -4.79267 -0.5367211 -27.2497 -3.93744 -0.9663941 -27.5728 -4.56456 -1.73799 -27.4191 -5.21463 -1.19153 -27.9984 -6.06472 -1.49444 -27.8278 -6.35698 -2.01005 -27.0794 -7.21768 -1.879 -27.4199 -7.28432 -2.64582 -26.7796 -7.13094 -2.31367 -25.844 -6.92591 -2.04622 -24.866 -7.47935 -2.93922 -24.9071 -8.46587 -3.16137 -25.018 -9.30086 -2.67239 -25.0559 -10.2174 -2.94317 -24.7798 -10.6402 -3.79973 -24.9599 -11.1253 -3.54142 -24.1165 -11.8507 -3.14342 -24.6472 -12.924 -3.12016 -24.7422 -13.4687 -3.86899 -24.1543 -13.4261 -4.87918 -24.0701 -12.7203 -5.51014 -24.4726 -13.2377 -6.3597 -24.5313 -12.2869 -6.33369 -24.2292 -11.5403 -5.81104 -23.9835 -10.9147 -5.0318 -23.6821 -10.3711 -4.41761 -23.1248 -10.9705 -3.60087 -23.0866 -11.6636 -2.85731 -23.1448 -12.6433 -3.04284 -23.4059 -13.4645 -2.61364 -23.0394 -12.6994 -2.43511 -22.3385 -12.1979 -2.48017 -21.4694 -12.035 -1.49589 -21.6645 -11.8517 -0.9023341 -22.4657 -11.1045 -1.537 -22.7169 -11.1471 -0.6786171 -23.296 -11.5166 -0.07866817 -24.0171 -11.0773 -0.6396311 -24.6777 -10.4181 0.06312093 -24.3208 -10.4014 1.02761 -24.2941 -11.1328 1.7001 -24.2083 -11.0246 2.39041 -24.9028 -10.1146 2.80036 -25.0601 -10.8975 3.33309 -25.4118 -11.6985 3.27144 -24.8998 -12.6898 3.40995 -24.986 -13.4839 3.04446 -25.5493 -14.3707 3.3789 -25.2322 -13.9612 4.26067 -25.3843 -14.9567 4.5793 -25.1674 -14.9044 5.54991 -25.4008 -14.3251 6.1431 -25.9012 -13.7458 5.86441 -25.1751 -13.0883 6.13362 -25.9153 -12.876 5.16636 -26.0836 -12.4766 4.54109 -25.4068 -12.1844 4.88739 -24.5002 -11.8613 5.8248 -24.5759 -12.5216 6.30499 -24.069 -12.9059 7.0223 -24.7404 -12.0526 7.42872 -24.6595 -11.1499 7.15045 -24.7132 -10.739 7.16282 -23.7306 -10.1329 7.94379 -24.0149 -9.90671 7.98848 -23.0486 -9.50795 7.17317 -23.2863 -9.56063 6.29643 -22.6844 -10.3805 5.65452 -22.5087 -10.8667 4.82165 -22.148 -11.6282 4.22722 -21.686 -11.4162 3.58033 -21.0112 -10.9037 3.10337 -20.3008 -11.9149 3.20287 -20.0903 -12.382 3.25827 -19.1799 -11.5551 2.76777 -19.2999 -11.1669 3.5594 -18.8522 -11.7635 4.03749 -18.2174 -11.0243 4.75617 -18.2404 -10.0477 4.83393 -18.6581 -9.99544 5.21951 -17.7213 -10.6087 5.94995 -17.3615 -9.83696 5.821 -16.7878 -10.547 5.27953 -16.2631 -10.0616 5.83595 -15.6272 -10.9277 5.51573 -15.1778 -10.9266 5.4957 -14.1797 -11.2714 4.97513 -13.4157 -11.4724 4.13163 -13.9285 -11.9468 4.50216 -14.6903 -12.2711 3.5726 -14.4004 -11.6863 2.74258 -14.1987 -12.0507 1.84155 -14.1358 -12.761 1.83504 -14.7691 -12.1269 1.24347 -15.3429 -12.7785 1.37146 -16.083 -12.4003 0.5935119 -16.5393 -12.8943 1.14538 -17.2795 -12.9455 2.17544 -17.4142 -12.5365 3.0245 -17.3245 -11.4876 3.1543 -17.2938 -11.5017 3.94966 -16.7823 -12.4398 4.09095 -16.4007 -13.0319 4.84406 -16.1864 -13.9993 4.52609 -15.9298 -13.9051 4.85535 -14.9411 -14.7012 5.11444 -15.5092 -15.0051 5.38136 -16.4317 -14.628 6.21561 -16.912 -14.5374 7.213 -16.6225 -13.5585 7.08386 -16.5015 -12.7145 7.30605 -16.086 -12.0422 7.60603 -15.398 -11.4977 8.15367 -14.7384 -11.7297 8.05142 -13.7711 -12.6602 8.33642 -13.5453 -13.3493 8.72818 -13.029 -13.7053 8.94013 -13.9854 -14.3182 8.85112 -14.7438 -15.0917 9.45458 -15.0775 -15.7583 10.1965 -15.2939 -15.4278 11.0587 -15.6253 -14.6266 11.304 -16.2189 -15.1539 12.0237 -16.717 -15.0376 13.0011 -16.9547 -14.3545 12.9533 -16.1964 -13.8159 12.1484 -15.8521 -13.3894 11.6777 -16.6061 -12.7379 11.0481 -17.0469 -12.2009 11.8861 -17.169 -11.5491 11.8505 -17.9994 -10.8503 11.6896 -17.3548 -11.2965 10.8699 -17.0516 -11.5343 10.4073 -16.1823 -10.8307 9.73195 -16.3936 -10.6225 9.1503 -17.1523 -9.83779 9.31229 -16.5146 -8.96928 9.46025 -17.0296 -7.94626 9.49113 -17.165 -7.70431 8.592 -16.8308 -6.96636 8.00885 -17.2296 -6.12195 8.60937 -17.1311 -6.54256 9.48999 -17.3044 -6.1305 10.4079 -17.6435 -5.4043 9.74586 -17.5282 -4.45777 9.53636 -17.6369 -3.79193 10.2115 -17.314 -4.36685 10.2796 -16.4622 -3.96229 10.6455 -15.6046 -3.77777 10.3829 -14.7195 -4.39461 9.67209 -14.9967 -5.01537 9.25267 -15.73 -5.85486 9.48188 -15.2829 -5.72489 9.97266 -14.45 -6.03176 10.9377 -14.4703 -6.73038 10.3159 -14.6509 -6.25536 10.7591 -15.3238 -6.19581 11.6232 -15.7833 -7.12244 11.5937 -16.154 -7.30839 12.5423 -16.2213 -7.52548 12.7749 -15.1965 -6.58837 12.7291 -14.8853 -6.46676 13.0875 -15.7398 -6.02706 13.539 -16.495 -6.22456 14.5037 -16.6394 -6.94173 15.1697 -16.4213 -6.72264 16.1265 -16.797 -7.56562 16.6728 -16.8041 -8.54068 17.023 -16.7082 -8.49525 17.5181 -17.5024 -7.84517 17.9726 -18.0851 -7.22627 18.3612 -18.7731 -6.39976 18.9094 -18.6001 -6.24195 19.7306 -19.1118 -5.64446 20.5441 -19.0595 -6.24801 21.2389 -19.455 -6.3822 21.4693 -18.4279 -6.85795 20.5184 -18.2372 -6.57375 20.8758 -17.3276 -7.29466 21.4101 -17.0322 -7.48928 21.0578 -16.0412 -7.2348 20.982 -15.1145 -7.05519 21.839 -14.6871 -7.25552 22.5139 -15.3984 -7.11191 22.2885 -16.3341 -6.68449 23.1229 -16.7438 -7.13344 22.4979 -17.3773 -7.61477 22.4854 -18.2374 -8.56215 22.3866 -18.5549 -8.96347 21.7959 -19.2354 -9.28343 22.7467 -19.4352 -9.72549 23.6017 -19.8103 -8.97944 24.2216 -19.9478 -9.06487 24.3506 -18.9358 -8.31762 24.9166 -19.0705 -8.40817 25.8933 -18.9174 -8.4622 26.35 -18.0718 -8.11075 27.1083 -17.4803 -7.16186 27.1145 -17.181 -6.88919 27.1088 -16.2061 -7.6819 26.8554 -15.611 -7.54082 25.9019 -15.6306 -7.34015 24.9735 -15.6291 -6.86428 25.5163 -16.4031 -5.93127 25.3184 -16.1173 -5.34617 25.5586 -15.4061 -5.68436 26.0251 -14.6847 -5.94451 25.9567 -13.6574 -5.71832 25.2113 -13.0138 -6.60687 24.7982 -12.9155 -7.6378 24.8837 -12.9322 -8.00459 24.0925 -13.3408 -8.91954 23.7864 -13.6263 -9.44243 24.1165 -14.4233 -10.362 24.439 -14.7685 -10.9508 24.2002 -15.5118 -11.3023 24.3313 -16.431 -11.3047 24.2369 -17.4181 -11.0907 23.2682 -17.4978 -10.108 23.51 -17.5063 -9.31547 24.1793 -17.4631 -8.66281 23.6649 -18.0304 -8.253 23.2486 -17.2098 -8.20974 23.4924 -16.2698 -8.39411 23.2101 -15.2941 -9.30967 22.9182 -15.6066 -9.19444 21.9451 -15.2749 -9.49637 22.02 -14.326 -10.5144 22.1799 -14.2873 -10.7257 21.6149 -15.0555 -10.5359 20.6879 -14.6315 -10.4469 20.4042 -15.5954 -10.0922 21.0189 -16.3376 -9.76546 20.1052 -16.6814 -10.2403 19.33 -17.1467 -10.9707 18.8089 -16.7023 -11.9361 18.4811 -16.8391 -12.2588 17.9232 -16.1445 -13.0844 17.6464 -16.7097 -13.9919 18.1613 -16.7212 -14.5481 18.2884 -15.9529 -14.9734 18.7607 -15.1396 -15.2427 18.6741 -14.1858 -15.7545 17.8658 -14.39 -16.4135 18.3923 -13.7747 -16.9551 19.2089 -13.9954 -17.0557 20.1534 -14.2131 -17.0175 20.7993 -14.9973 -16.1989 20.4435 -15.2854 -16.0672 21.0087 -16.1413 -15.3604 20.271 -16.2835 -14.8687 19.442 -16.5284 -14.4453 20.1057 -17.1095 -15.0481 20.03 -17.8336 -15.0693 19.048 -18.1743 -15.8711 18.7313 -18.7611 -16.353 19.5938 -18.9192 -16.2256 19.7475 -19.893 -17.1968 20.1057 -20.1603 -18.0075 20.63 -19.8053 -18.9767 20.2902 -19.9312 -19.1793 19.3481 -20.0344 -19.1178 18.4319 -20.4064 -19.6056 18.1884 -19.5278 -19.4623 18.3383 -18.5315 -19.5226 17.5006 -17.9852 -18.5976 17.5361 -17.6356 -18.7136 16.7202 -17.1039 -18.7875 16.4042 -16.0877 -18.9348 17.3552 -16.2578 -17.9976 17.4034 -16.4586 -17.1551 17.5538 -16.9889 -16.6602 17.1548 -16.1143 -17.0861 17.8835 -15.6056 -17.7762 17.853 -14.7784 -18.2146 17.0581 -15.073 -19.1445 17.48 -14.8133 -19.5442 17.341 -13.8486 -19.9972 16.9601 -13.1137 -20.2867 17.2195 -12.2146 -19.4063 17.5039 -12.4881 -19.4469 18.401 -11.9701 -20.1871 19.0592 -12.0207 -19.8367 19.9239 -12.1445 -19.5077 20.6394 -11.4848 -18.9679 21.4699 -11.6713 -18.6218 22.3561 -11.4208 -18.0558 23.1732 -11.6052 -17.7543 22.4455 -12.1052 -16.8275 22.7525 -11.8334 -17.1364 22.0307 -11.2404 -16.5055 21.9508 -10.4829 -16.687 21.339 -9.65018 -16.778 20.4984 -9.06227 -15.8524 20.223 -8.81206 -16.3701 19.7201 -8.1183 -17.0657 19.1736 -8.55748 -17.9313 18.6239 -8.50018 -17.2556 17.9533 -8.7759 -16.8278 17.0255 -8.76074 -15.9975 16.6278 -9.06618 -16.1153 16.6972 -10.0841 -16.0932 15.8187 -10.6363 -15.1106 15.6149 -10.6299 -15.0613 16.2218 -9.81418 -14.3411 15.4615 -9.87215 -13.3956 14.9628 -10.0543 -13.3454 14.6405 -10.9855 -13.1781 14.9593 -11.9462 -12.9386 14.0266 -12.0406 -13.9135 13.9984 -11.8495 -14.4968 14.3503 -12.5705 -14.9512 14.6329 -13.4297 -15.9197 14.8069 -13.4046 -16.6787 15.4972 -13.5848 -17.5348 15.2519 -14.0467 -18.0477 14.7764 -13.2986 -18.8898 14.1592 -13.2414 -19.0103 14.6482 -12.4025 -18.7356 13.6721 -12.3037 -18.8811 13.9903 -11.3687 -18.348 14.1555 -10.5833 -18.492 15.0511 -10.174 -19.4596 15.215 -10.0875 -20.1302 14.4569 -9.82517 -19.9681 13.677 -10.4359 -19.5839 13.2001 -9.58381 -20.5171 12.9854 -9.80712 -21.418 12.5263 -9.63585 -20.7156 12.165 -10.2001 -21.1462 12.6588 -10.8175 -21.3834 12.2714 -11.6702 -20.7851 11.4043 -11.7096 -20.428 10.6145 -11.1905 -21.0094 9.84937 -11.44 -21.2737 9.23679 -10.6918 -21.5291 8.3386 -10.416 -22.3362 8.85812 -10.5397 -22.7228 8.32684 -9.76072 -21.9529 8.11323 -9.13114 -21.4662 7.173 -9.09736 -21.11 7.27901 -8.20189 -21.6947 7.87668 -7.55869 -20.7707 7.81212 -7.34495 -19.7721 8.00826 -7.12769 -19.1589 8.81244 -6.97117 -18.2298 8.94195 -7.27861 -18.5123 8.00917 -7.1891 -18.3365 7.48515 -6.36044 -17.6322 7.21992 -5.76041 -18.3278 7.39294 -4.99322 -19.2247 7.62398 -4.78057 -19.371 8.38911 -5.38194 -18.908 8.83791 -4.63457 -18.84 8.35908 -3.77882 -19.9219 8.39034 -3.61952 -20.5669 7.70602 -3.75604 -21.0433 7.0161 -3.22836 -21.8306 6.80903 -2.7185 -21.3759 7.75989 -2.44596 -20.6395 8.40864 -2.38696 -19.8178 7.79994 -2.49438 -18.9295 8.26735 -2.44505 -18.2609 9.00395 -2.5863 -18.7861 9.68774 -2.06646 -18.619 10.6205 -2.13955 -18.86 11.4498 -2.71273 -18.6529 12.1429 -2.0032 -18.1721 12.4332 -2.84281 -18.8267 12.7634 -3.49186 -18.7572 12.1165 -4.23371 -19.2853 11.5524 -4.87436 -18.447 11.0439 -4.72641 -19.0709 10.6271 -4.07885 -19.4073 9.72158 -4.33317 -18.4878 9.70429 -4.05581 -18.0011 10.0617 -3.25282 -17.3548 9.83665 -3.90324 -17.6833 10.3659 -4.63576 -17.0303 9.86674 -5.21106 -17.3928 9.02187 -4.95031 -17.5447 8.13559 -5.24682 -16.6215 8.05804 -5.61603 -16.4862 9.04068 -5.91381 -15.6982 9.56371 -6.19569 -15.2608 9.34576 -5.31796 -15.1302 10.2404 -4.82608 -15.579 11.0467 -4.26553 -15.8638 10.8278 -3.34027 -16.4578 10.8196 -2.48584 -15.842 10.9091 -1.81317 -16.4543 10.4353 -1.20483 -15.5857 9.98316 -1.30524 -14.8305 9.85216 -1.8877 -15.5436 9.26026 -2.16252 -15.3016 8.42722 -2.69323 -15.6347 7.5055 -2.48037 -15.7073 7.29898 -3.47914 -16.1791 7.88899 -4.11281 -16.8966 7.1664 -3.96643 -17.608 7.74413 -3.53316 -18.217 6.95787 -3.22208 -18.0893 6.31717 -2.44422 -17.8222 5.70586 -3.08831 -18.2239 5.80275 -3.97062 -19.0669 5.28414 -3.86991 -19.6129 4.84389 -3.16062 -20.506 4.46417 -3.20851 -20.3597 4.73015 -2.2306 -21.0321 4.06325 -2.00361 -20.8119 3.13989 -1.877 -20.6736 2.8869 -2.78462 -21.5031 2.95569 -3.3933 -20.7946 3.26598 -4.07778 -21.1137 4.00237 -4.61598 -21.0479 3.28134 -5.32973 -21.5771 2.85008 -6.01691 -21.5861 2.05693 -6.66966 -20.5476 2.04462 -6.72882 -20.1331 1.35231 -6.12933 -19.1501 1.42905 -6.4196 -19.0595 2.14387 -7.10515 -19.2086 2.86191 -7.77313 -18.67 3.2666 -8.54398 -18.501 4.25459 -8.69882 -17.5236 4.46066 -8.3767 -16.9583 4.37167 -7.50337 -16.2637 4.18151 -8.23837 -15.5513 4.77086 -7.77912 -15.1631 5.66903 -7.82917 -14.899 6.65631 -7.89716 -15.8712 6.73741 -8.08346 -15.4345 6.32387 -8.84744 -14.9919 5.98581 -9.6978 -14.3144 6.57254 -9.22159 -13.5693 7.16909 -9.59572 -14.4262 7.66021 -9.88752 -14.922 8.29743 -10.348 -14.8396 9.25757 -10.4275 -13.8799 9.07292 -10.1913 -13.869 9.25377 -11.1025 -13.5842 8.94569 -12.0451 -12.9397 9.48909 -11.5505 -12.9811 10.3503 -12.1215 -13.5511 11.1428 -12.0005 -13.78 10.6655 -12.8676 -14.3944 11.2144 -13.3368 -14.9567 10.7151 -12.7311 -15.8223 10.9531 -12.2912 -15.8207 11.9462 -12.4875 -14.9094 12.3267 -12.585 -14.4624 11.6488 -12.0608 -15.2633 11.8611 -11.4465 -15.5995 11.8844 -10.5375 -15.7709 10.8998 -10.4575 -16.426 10.4997 -9.815 -16.4865 11.2875 -9.14881 -15.5498 11.1694 -9.42018 -15.3622 10.3149 -8.85763 -15.6758 9.69785 -9.56039 -16.4577 9.89586 -8.86549 -17.3514 9.46538 -8.93185 -17.6881 8.98053 -9.70867 -16.9269 9.04361 -10.3452 -16.8436 8.32651 -11.085 -16.6496 7.4803 -10.6151 -15.8047 7.15594 -10.9996 -15.9711 6.79107 -11.9279 -15.3046 6.0854 -11.9506 -15.9193 5.22657 -12.0238 -16.4107 4.93096 -11.2323 -17.2982 4.98933 -11.5777 -17.3511 5.6335 -12.3398 -18.025 6.33448 -12.8078 -18.5748 5.72746 -12.2267 -18.8267 4.76551 -12.3093 -18.3879 4.31567 -11.576 -18.2394 5.05749 -10.9766 -19.0938 5.36848 -10.8709 -19.0562 6.30908 -10.525 -20.0047 6.102 -10.4457 -21.0051 5.96567 -10.6807 -21.0229 4.95876 -10.7628 -21.0944 4.90285 -9.81547 -22.0106 4.88153 -10.2105 -22.1935 3.90553 -10.3376 -22.3937 3.28058 -11.1559 -22.0226 2.47201 -10.6511 -22.7678 1.94034 -11.1119 -22.2323 1.29339 -11.6474 -22.5367 1.42399 -12.58 -22.3134 0.6362119 -13.2502 -21.8926 0.1761119 -13.9871 -22.0167 -0.4642921 -14.7513 -21.2738 -0.1583101 -15.3709 -21.9674 0.5183579 -15.4157 -22.6699 -0.07679747 -15.5963 -23.3949 0.01563563 -16.2397 -24.285 -0.1686401 -16.5968 -24.1751 0.2722289 -15.6652 -23.9184 0.9941319 -14.933 -24.1288 1.98162 -14.9103 -24.4133 2.28359 -15.8488 -24.9395 2.73825 -15.1116 -25.2638 3.68774 -14.9368 -25.4442 3.75317 -13.9659 -25.576 4.77353 -14.3072 -26.3302 5.43517 -14.5257 -26.8265 6.0853 -14.0699 -27.185 6.153 -13.1493 -27.2867 6.51982 -12.2147 -27.8165 6.02257 -11.5224 -27.8918 7.02305 -11.2949 -28.5166 6.86159 -10.5528 -29.3587 7.20959 -10.9219 -29.9596 7.10841 -10.1958 -30.6436 6.81524 -9.54489 -31.0908 7.33867 -10.2995 -31.9873 7.79418 -10.0958 -31.9308 8.75048 -10.3215 -32.2784 8.95106 -9.41175 -32.0011 9.22575 -8.46734 -32.3622 8.44395 -7.99346 -31.8404 8.34649 -7.11978 -32.3047 9.08517 -6.55709 -32.3695 9.52953 -7.39997 -33.1289 9.59008 -6.7845 -33.8143 10.3324 -6.83663 -34.0309 9.85493 -7.67641 -34.7392 10.4574 -7.5162 -34.3911 11.4258 -7.63397 -34.1657 12.4503 -7.66113 -33.9216 13.3265 -7.22838 -33.0816 13.8371 -7.35495 -32.309 14.444 -7.43441 -32.4185 13.9255 -8.27417 -31.4041 14.0788 -8.5274 -31.7463 13.361 -7.91886 -30.8278 13.0633 -7.7568 -30.8755 12.3657 -8.47761 -31.8121 11.9226 -8.35069 -31.4894 10.8898 -8.32981 -31.0978 11.4272 -7.67436 -30.6131 10.6033 -7.64181 -30.7669 10.6673 -6.67349 -30.5987 10.8135 -5.71865 -29.6547 10.52 -5.65265 -29.7008 9.65779 -5.17902 -29.153 9.69654 -4.33044 -29.2722 10.6494 -3.92249 -28.4151 11.1434 -3.97818 -28.9726 11.5119 -3.15849 -29.0512 12.4234 -3.50719 -29.0791 13.2287 -4.11671 -28.1894 13.754 -3.92879 -27.8672 14.7072 -3.69921 -28.2569 14.9208 -2.7798 -28.9004 15.3613 -3.39239 -29.2349 14.6318 -2.82715 -29.0162 14.743 -1.83593 -29.4492 15.4763 -1.41026 -28.9067 16.2127 -1.21968 -28.6672 17.1601 -0.9780169 -28.9202 17.6668 -1.77129 -29.0669 18.5962 -1.30718 -28.8163 19.4833 -1.80054 -27.952 19.8327 -2.26729 -27.2268 19.1922 -2.22403 -27.039 18.9945 -1.26824 -27.0613 18.2634 -0.5897429 -26.1291 17.8703 -0.3109609 -25.1741 17.5707 -0.1708109 -24.8449 17.9492 0.6618981 -23.9025 18.0263 0.2355831 -23.4161 18.7291 0.8071281 -23.3415 19.0187 1.76701 -23.4206 19.9901 2.03438 -23.9796 20.8252 1.95701 -24.777 21.3494 1.36142 -25.2659 22.1796 1.51834 -25.8949 22.5736 2.14248 -26.1065 22.6184 3.04125 -26.2244 23.5197 2.78385 -26.7053 24.1092 3.51156 -26.7619 23.3685 4.16286 -27.6294 22.9674 3.94186 -28.5653 23.1784 4.22708 -28.8198 23.1184 3.2341 -29.5797 23.4445 2.61091 -29.8448 22.951 3.41562 -30.0031 22.2019 4.03623 -29.8564 21.2629 4.37925 -29.3042 20.672 3.84968 -28.7389 21.1739 3.19383 -29.3765 20.7308 2.56725 -30.3902 21.0464 2.49829 -30.3655 20.663 1.56274 -30.9293 20.0866 1.09603 -31.8232 19.6795 1.39463 -31.2538 19.34 2.10587 -31.4523 18.3776 1.95067 -31.4423 18.3532 2.99926 -30.4292 18.3721 2.95097 -30.2973 17.8405 3.70433 -29.6767 17.8401 4.48641 -30.375 17.3791 4.93343 -30.862 16.5546 4.83223 -31.1137 15.5859 4.52099 -31.6566 16.1439 3.95939 -32.0499 15.2228 3.935 -32.6213 14.4597 3.63445 -31.8753 14.3085 3.0383 -32.0024 13.3662 3.30616 -31.1585 13.5231 2.77884 -30.3774 13.8652 3.16874 -30.2672 13.8074 2.1892 -29.6157 13.0683 2.17849 -29.1945 12.5863 1.47824 -29.4766 12.2237 0.6125161 -29.1546 11.4082 0.2683431 -29.2152 10.4593 0.2886111 -29.1893 9.83309 -0.4891869 -29.6806 10.2353 -1.27141 -30.5101 10.3703 -0.7005489 -31.2773 9.81061 -0.2708029 -32.1928 9.56648 -0.1940299 -32.4597 8.69408 -0.5499739 -31.7103 8.16181 -0.8916689 -30.8417 7.89042 -0.7676009 -29.9651 7.97487 -1.37012 -29.9232 7.12497 -1.87689 -28.973 6.86564 -2.13239 -28.6981 7.64486 -1.525 -27.785 7.66354 -1.41513 -28.0342 8.59993 -1.70576 -28.4719 8.64823 -2.55147 -28.9688 8.27357 -3.28523 -29.8242 8.78032 -3.33656 -30.2022 7.8818 -3.53644 -31.1807 7.69357 -3.78212 -32.102 7.51498 -4.00242 -33.0946 7.64337 -3.75284 -33.2179 6.59085 -3.80354 -33.0691 6.02562 -4.69687 -33.7749 5.41323 -4.4102 -34.5556 5.12284 -3.77529 -34.1295 5.41352 -2.96397 -35.0744 5.69271 -3.06696 -34.5017 6.48806 -3.17879 -33.922 6.36079 -2.30857 -33.9435 7.32551 -2.14791 -33.4422 7.71009 -2.84729 -32.6108 7.27091 -2.41327 -33.1821 6.94479 -1.67579 -32.1829 7.00372 -1.40962 -31.5093 6.78843 -0.6895609 -31.8295 5.84555 -0.6646149 -32.7918 5.64905 -0.3423019 -33.0281 5.19615 0.5371571 -32.8708 4.78669 1.44726 -32.408 4.11517 1.95064 -32.5666 4.53536 2.90889 -31.7809 5.12781 3.23294 -31.2355 5.33056 4.09749 -30.3568 5.02456 3.78098 -29.625 4.33788 3.80712 -29.4561 4.24268 2.84905 -28.7686 4.77182 3.48661 -29.325 5.55534 3.18995 -29.4276 6.53844 3.45937 -28.9711 7.40531 3.76797 -28.2668 7.94363 3.23297 -28.5339 8.66759 2.5749 -29.5014 8.40531 2.54839 -29.5581 8.40409 1.54916 -29.6106 9.41006 1.62235 -28.6814 9.82619 1.60512 -28.5633 10.7752 1.11565 -27.7148 10.2704 1.01276 -26.8367 9.89427 0.9383181 -26.9195 8.88093 1.23676 -27.3764 8.34439 1.92667 -26.9369 7.47258 1.90503 -27.0243 6.51808 2.07011 -27.6721 6.3996 2.79445 -27.2306 6.92899 3.45759 -26.9158 7.79333 3.98703 -27.4222 8.4339 4.61799 -28.1833 8.83955 5.03976 -28.7425 8.20736 5.57312 -29.0151 9.01907 6.07863 -28.3591 9.7807 5.98535 -27.6919 9.58611 6.70515 -26.8195 9.33081 6.4005 -26.678 8.51718 5.88803 -26.1002 7.96171 6.55168 -26.5678 8.59663 7.31395 -26.8593 9.29542 7.94104 -26.3277 9.57078 8.65548 -25.7843 8.8124 8.3693 -25.1002 9.59286 8.15685 -24.5025 10.3563 7.84443 -24.0074 10.6972 6.97141 -24.1494 9.74327 6.60072 -24.896 9.89485 7.15442 -25.22 10.7372 6.70905 -25.9907 10.6276 7.36759 -26.8371 11.1323 7.45888 -26.3867 11.3588 8.35758 -25.8505 12.0999 8.80348 -26.6498 11.9373 9.26901 -25.9635 11.8432 9.99395 -25.4158 12.1727 10.7899 -24.7099 11.7499 10.2391 -23.8861 11.2546 10.2053 -24.3432 10.3517 9.89805 -24.0143 10.8083 9.08159 -23.2115 11.2959 8.95451 -22.7503 11.127 8.03171 -22.4304 10.1974 7.99225 -23.1037 9.47721 7.7914 -22.7978 9.99134 6.9628 -22.7993 10.5235 6.07134 -22.1845 10.0877 5.48556 -22.1452 9.43522 6.24599 -21.3783 9.22796 5.645 -20.8868 8.42922 6.02841 -19.9659 8.66412 6.19113 -19.9288 8.0921 6.99119 -20.0065 7.88973 7.93284 -20.9726 8.0058 7.81478 -20.5017 8.71265 8.29558 -21.0229 9.53698 8.50741 -21.1344 10.515 8.61857 -21.5751 9.98519 9.32617 -22.1138 9.2292 9.7061 -22.1536 8.2534 9.88844 -23.042 7.78535 9.52109 -23.4288 7.62708 8.60124 -23.3825 7.55012 7.57232 -24.2556 7.07891 7.51446 -24.4985 7.83913 6.88906 -24.8195 8.67225 6.43386 -25.1389 7.86747 5.93166 -25.3519 6.95109 5.62193 -25.8137 6.44847 4.84606 -26.2048 5.5481 4.86404 -26.4966 5.17263 5.71017 -27.368 5.60353 5.78162 -28.2744 5.17561 5.61817 -28.613 5.85651 6.31427 -28.4117 5.55236 7.25116 -28.1222 5.22669 8.12204 -28.6875 6.00919 8.3315 -29.4891 6.2732 7.69515 -29.972 5.89009 6.92658 -30.4499 5.28117 7.626 -30.5096 4.31289 7.24126 -30.4639 3.72184 6.43432 -31.3295 4.17973 6.3924 -31.4837 4.15397 5.39084 -30.5827 3.73261 5.38215 -29.5942 3.74734 5.36237 -29.3046 2.81799 5.42902 -30.1367 2.35737 5.76398 -30.2747 1.40944 6.02275 -29.6353 0.8354259 5.43855 -29.6757 -0.1235141 5.43383 -30.1296 -0.9296761 5.70486 -29.4377 -0.7666061 6.43258 -29.8114 -1.46652 7.11235 -30.6535 -1.70345 6.5601 -31.3294 -2.19934 5.94895 -32.1077 -2.25895 5.28422 -31.1011 -2.23235 4.96089 -31.5781 -2.9411 4.39706 -32.336 -3.47501 4.51878 -32.7627 -3.42701 5.44725 -31.9182 -3.61387 5.88125 -31.3643 -4.42674 5.6449 -32.0591 -4.94729 5.19761 -32.4716 -5.13501 4.35264 -32.802 -5.96595 4.80388 -32.9234 -6.77303 5.32575 -32.7537 -6.24201 6.15925 -31.9175 -6.55432 5.59981 -31.4339 -6.82943 4.78112 -31.7569 -7.71781 4.39221 -32.0588 -8.53742 4.83295 -31.9399 -9.48303 4.36571 -32.9416 -9.322 4.30302 -33.6387 -8.65409 3.98824 -34.4058 -8.15607 4.32853 -35.0112 -8.65186 4.77959 -34.2 -8.65864 5.38416 -33.8706 -9.31907 6.06504 -33.4901 -9.05569 6.90085 -32.8852 -8.48285 7.29926 -33.6365 -8.57228 8.05406 -33.6922 -9.14675 8.91466 -33.1272 -8.84653 9.72047 -32.7169 -9.70445 10.0324 -33.3796 -10.289 10.4157 -33.5528 -10.2831 9.42283 -33.2557 -10.6933 8.53482 -32.2923 -10.8789 8.24253 -31.5824 -11.2466 8.8571 -30.6837 -11.6326 9.12681 -30.1057 -11.0622 9.63957 -30.2899 -10.164 9.4399 -30.5508 -9.93097 10.456 -30.0458 -10.33 11.2681 -29.3897 -10.2496 10.4601 -28.6116 -9.80107 9.99103 -29.1903 -9.10312 10.1896 -29.099 -8.83879 9.16082 -29.8993 -9.06249 8.57184 -30.6974 -8.43336 8.65562 -30.022 -8.20944 8.02871 -29.8279 -8.85202 7.3371 -29.1209 -9.35446 6.81811 -28.3278 -9.56415 7.41364 -27.608 -8.83841 7.63856 -27.5835 -7.85184 7.86513 -28.4599 -7.79346 7.37987 -28.9163 -7.01878 6.95048 -29.1053 -6.06529 6.73721 -28.1841 -5.65609 6.80171 -28.0847 -5.63993 5.84825 -28.0927 -5.36456 4.91129 -27.1236 -5.65872 4.69688 -26.39 -5.42837 5.27965 -25.6625 -5.74844 5.90028 -26.1591 -6.19242 6.59149 -26.3069 -6.87009 5.78763 -27.0737 -7.37034 6.07578 -27.3549 -8.30608 5.8906 -26.7767 -7.9596 5.15187 -27.2041 -7.71288 4.27471 -27.6301 -8.50493 3.9897 -27.5843 -9.26708 4.55891 -28.4436 -9.60925 4.18519 -28.9158 -9.68085 5.09456 -29.7055 -9.82117 5.58227 -29.5243 -10.6235 4.98537 -29.5809 -10.6481 3.99447 -29.2091 -11.4145 3.53328 -30.0176 -11.2699 2.96383 -29.8613 -10.5881 2.22583 -29.1063 -10.2153 1.66337 -28.092 -10.0684 1.47455 -27.6564 -10.0971 0.6689461 -27.1726 -10.7571 1.29938 -26.48 -10.0562 1.19402 -26.6476 -9.13461 1.01703 -25.6219 -9.33889 0.9885751 -25.3633 -9.52066 1.95745 -24.9068 -8.6322 2.20303 -23.9102 -8.67964 2.09835 -24.1284 -9.29728 1.44139 -23.8026 -10.1956 1.09527 -23.3007 -9.45246 0.8289771 -22.3915 -9.30147 0.5056851 -22.9022 -8.56307 0.06749312 -22.8223 -8.54835 -0.9401809 -23.0324 -9.46253 -1.20505 -22.3088 -8.98211 -1.74958 -23.0804 -8.71315 -2.24662 -23.4905 -8.17989 -3.06044 -23.5068 -8.09587 -4.02454 -22.7455 -8.69866 -4.43668 -22.209 -8.05275 -4.97762 -21.9579 -7.79956 -4.01848 -21.9218 -6.81984 -3.67232 -21.592 -6.81543 -4.59478 -20.8657 -6.85379 -5.1639 -19.9951 -6.37688 -5.44365 -19.2739 -5.71969 -5.69597 -18.918 -4.79987 -5.68608 -19.1696 -4.08604 -5.1188 -20.1213 -4.39055 -5.13912 -21.02 -4.02057 -4.9556 -21.9626 -4.3638 -4.83917 -22.3643 -3.47037 -4.56497 -22.7827 -3.67413 -5.4582 -23.0535 -4.119 -6.30472 -24.0037 -4.38655 -6.10592 -23.9948 -4.26808 -7.06435 -23.6191 -5.16226 -7.11237 -23.7493 -5.71375 -7.94788 -24.6784 -5.84114 -8.19411 -25.1583 -4.99548 -8.40189 -25.7388 -5.77589 -8.2629 -26.2099 -5.65823 -9.1549 -25.9823 -5.13969 -9.98033 -26.5526 -4.47074 -10.4406 -27.3034 -4.15758 -10.9512 -27.5832 -4.06609 -11.9612 -28.2319 -3.49281 -11.4783 -27.646 -2.67984 -11.2802 -26.8681 -2.63756 -11.9747 -26.2699 -3.41871 -12.2544 -25.4762 -3.0404 -11.8178 -25.1754 -3.44536 -12.707 -24.9606 -3.71319 -13.6296 -24.404 -3.86321 -14.4701 -24.31 -4.64046 -15.0155 -23.846 -5.15495 -14.346 -23.2558 -4.40976 -13.9488 -22.3011 -4.32868 -13.8905 -21.4468 -4.51793 -13.4359 -21.6716 -5.3551 -13.03 -21.9601 -5.5289 -13.8909 -22.7857 -6.13328 -13.9698 -22.6706 -6.12075 -14.9819 -23.4563 -6.76854 -14.8538 -23.4158 -7.73058 -15.1291 -23.0107 -7.76903 -14.2307 -21.9765 -7.68758 -14.279 -21.2185 -8.24973 -13.9614 -20.6141 -7.48282 -14.0717 -20.3311 -7.03145 -14.8709 -19.6488 -6.58002 -14.2463 -19.3831 -6.00318 -13.5513 -18.8521 -5.22884 -13.8288 -19.547 -4.93606 -14.5084 -18.8787 -4.48621 -15.0176 -19.5449 -4.83195 -15.7883 -19.9428 -3.9513 -15.7606 -19.2682 -4.15087 -16.587 -19.9738 -3.53139 -16.7844 -19.9848 -2.57785 -17.1127 -19.2808 -2.63557 -17.738 -18.2922 -2.75479 -17.5353 -18.1299 -3.78422 -17.5609 -17.1357 -3.87686 -17.7125 -17.4467 -3.3906 -16.9265 -17.5726 -4.4474 -16.9032 -16.724 -4.94851 -16.9165 -16.3324 -5.62491 -17.5655 -16.6222 -6.03115 -16.6336 -17.2588 -6.09487 -15.8541 -16.3358 -6.24695 -15.5686 -16.0012 -5.30621 -15.5685 -15.5615 -4.76364 -14.8485 -15.9007 -4.11701 -14.2041 -15.4552 -3.25284 -14.1182 -16.2838 -3.14296 -13.5633 -15.7478 -2.69394 -12.8261 -15.3896 -2.17242 -13.6447 -16.1142 -1.56656 -13.3594 -16.5132 -0.9405981 -14.0271 -15.9616 -0.6016441 -14.7666 -16.0197 -1.49783 -15.2834 -16.7919 -2.21733 -15.3315 -17.7683 -1.93402 -15.4326 -18.5295 -2.15149 -14.8577 -18.0183 -2.08847 -13.9347 -17.3 -2.22148 -13.3161 -18.0794 -2.91678 -13.2893 -18.4935 -2.54808 -12.5093 -19.2128 -3.04227 -13.1081 -20.0395 -2.49772 -13.4145 -19.4693 -1.73392 -13.8168 -19.9279 -1.17757 -13.1122 -20.0691 -1.02652 -12.0996 -20.6845 -0.3871451 -11.6442 -21.1924 0.4520519 -11.439 -21.4819 0.06560823 -10.6696 -21.4999 -0.9223161 -10.635 -21.2609 -1.23151 -9.75078 -20.3791 -0.8534071 -9.94125 -19.8645 -0.2292901 -10.5758 -19.3744 -1.08749 -10.5688 -18.6716 -1.79347 -10.8108 -18.1438 -1.89377 -9.95117 -17.3547 -1.56361 -9.43627 -17.8309 -0.7714351 -9.85097 -18.0802 0.03169223 -9.26769 -17.2843 -0.4091111 -8.8699 -16.3864 -0.3268651 -9.15058 -16.8109 0.1321019 -9.91565 -16.1958 -0.1311841 -10.7075 -16.2972 -1.04833 -10.3204 -15.5602 -1.28568 -10.9023 -14.9049 -1.96251 -10.8378 -14.9227 -2.54102 -10.0352 -15.6793 -2.57089 -9.37311 -14.8704 -2.33241 -8.89545 -14.6321 -1.51142 -9.50062 -13.8189 -1.757 -8.96638 -13.1587 -1.78485 -8.20451 -12.5752 -1.03694 -7.85536 -12.3793 -0.09291317 -7.378 -12.4442 -0.6874451 -6.61219 -13.2081 -1.40237 -6.60815 -13.5742 -2.09735 -7.26852 -14.1819 -2.69228 -7.72365 -14.8655 -2.47256 -7.15004 -15.6581 -2.41446 -7.83384 -15.7897 -1.54197 -8.2162 -16.5001 -1.19957 -7.5181 -17.4247 -1.64966 -7.64925 -17.1328 -2.2476 -8.47395 -16.7276 -2.92881 -7.9174 -16.0624 -3.53749 -7.41945 -16.6832 -3.88068 -6.67993 -16.9977 -4.85212 -7.00006 -16.3243 -5.08364 -6.28051 -15.65 -4.56183 -6.72452 -14.9936 -3.98435 -6.27175 -14.3269 -4.68876 -6.04197 -15.0228 -5.37707 -5.95485 -14.5918 -6.17246 -5.52147 -15.3543 -6.04947 -4.94286 -14.5787 -6.16895 -4.26887 -13.7782 -5.92649 -4.70998 -13.2587 -5.59046 -5.56648 -12.3938 -5.86675 -5.25926 -12.4697 -6.89185 -5.06957 -11.692 -6.5691 -5.51415 -12.0109 -6.635 -6.46841 -12.2923 -7.45526 -7.01414 -12.3603 -7.70137 -7.953 -11.6838 -7.44462 -8.7167 -12.2538 -6.63532 -8.84558 -12.0013 -6.48273 -9.78792 -12.0492 -5.58948 -10.3212 -12.9951 -5.25651 -10.0982 -13.3225 -5.54465 -11.0528 -12.9055 -6.03874 -11.817 -13.8524 -5.97071 -12.2858 -13.1702 -6.28361 -12.9938 -12.8454 -5.82946 -13.9232 -11.8798 -6.03599 -13.8645 -11.6044 -6.02081 -12.9172 -11.2648 -6.89406 -13.1481 -10.9064 -7.22434 -12.2548 -11.5503 -7.95828 -12.1246 -11.5305 -8.86314 -12.6355 -11.7806 -9.84761 -12.8511 -11.8736 -10.0204 -13.829 -11.7996 -9.06624 -13.728 -11.7472 -8.0858 -13.7264 -11.398 -8.23584 -14.6983 -11.914 -8.20178 -15.5426 -11.4008 -7.45577 -15.7854 -10.5143 -7.28124 -15.5486 -9.8521 -7.93458 -15.3434 -9.36255 -8.67757 -14.9835 -8.50705 -8.73542 -14.4627 -8.74567 -8.11551 -13.7601 -9.46239 -8.3822 -12.9762 -9.10679 -8.2364 -12.039 -9.54129 -7.33471 -12.1277 -9.85052 -6.42569 -12.0191 -8.88231 -6.30532 -11.6957 -8.0742 -6.43054 -11.2777 -7.14247 -6.5799 -10.9702 -6.65417 -5.7635 -11.1727 -6.54965 -6.09424 -12.1064 -5.72798 -5.48805 -12.0619 -5.95235 -4.49246 -11.9638 -4.96982 -4.28614 -12.0941 -4.1987 -4.92491 -11.9172 -4.47482 -4.73513 -10.9243 -4.83821 -5.58466 -10.5189 -4.24915 -5.7855 -11.3189 -5.01446 -6.2877 -11.6369 -4.23763 -6.89545 -11.3957 -4.59936 -7.628 -11.7485 -4.4181 -8.56698 -11.4572 -4.21018 -8.29685 -12.3052 -4.03851 -9.24292 -12.405 -3.88376 -10.16 -12.1114 -3.82946 -10.4131 -13.0426 -4.06767 -10.2056 -13.92 -3.99908 -9.27266 -13.7012 -3.13309 -9.16214 -14.1684 -3.05384 -8.1949 -14.4632 -3.40458 -7.94318 -13.612 -3.93945 -7.10694 -13.6529 -4.67749 -7.2189 -12.8922 -5.06677 -6.54218 -13.414 -4.65346 -5.85507 -13.9756 -4.45203 -6.24409 -14.8497 -3.88881 -5.74231 -15.5453 -3.53485 -6.64351 -15.62 -3.81052 -7.29601 -16.3239 -3.93557 -8.25138 -16.6774 -4.3958 -8.90868 -17.1947 -3.51655 -8.74846 -17.6336 -2.68294 -9.17626 -18.0319 -3.105 -8.78552 -18.8555 -3.57589 -9.11159 -19.6713 -3.27061 -9.9014 -19.2446 -2.74246 -10.7051 -19.544 -2.55407 -10.8384 -20.5086 -2.57787 -11.6623 -21.1944 -3.5566 -11.7755 -21.068 -3.22461 -12.319 -20.2125 -3.71994 -12.9002 -19.6476 -3.75334 -13.8808 -20.0069 -4.0149 -14.3175 -20.8718 -4.95558 -14.2144 -20.8585 -5.31318 -13.8578 -20.0161 -6.01763 -13.5645 -19.3683 -5.79027 -12.887 -18.6986 -6.54618 -12.4622 -19.1972 -6.88619 -12.3958 -18.2773 -6.29552 -12.0626 -17.5815 -6.59719 -13.0086 -17.4379 -6.09462 -13.8161 -17.19 -5.05742 -13.793 -16.9093 -5.11798 -12.8885 -17.314 -5.27766 -12.0362 -16.8541 -6.04158 -11.7761 -16.3381 -5.96897 -12.2592 -15.4999 -6.07507 -13.2007 -15.2062 -6.75712 -13.8651 -15.3598 -6.11522 -13.8122 -16.1398 -5.56459 -14.7116 -16.2412 -5.35923 -14.9018 -15.2885 -4.50331 -14.9562 -15.6741 -3.71125 -14.7151 -16.1995 -2.95745 -15.222 -16.4813 -3.38018 -14.7894 -17.2242 -4.01943 -15.6143 -17.1881 -3.3093 -15.4903 -17.8479 -4.16681 -14.9474 -17.9757 -4.45492 -14.9889 -18.9239 -5.18139 -15.1956 -19.6209 -6.07536 -15.6387 -19.5032 -6.39451 -16.0296 -18.6041 -6.47343 -16.1351 -17.5581 -6.5179 -16.159 -16.5955 -6.44267 -15.9677 -15.5609 -7.35688 -16.3575 -15.3142 -7.73983 -16.0645 -16.1738 -7.59766 -16.0659 -17.233 -8.44892 -16.6487 -17.2768 -9.18054 -16.5667 -16.6818 -9.16372 -15.8 -17.2891 -9.80738 -15.0865 -17.1276 -10.7426 -15.0994 -16.6843 -10.5728 -14.1018 -16.5193 -9.66996 -14.1386 -16.0461 -8.85921 -13.9676 -16.5411 -8.34369 -14.5648 -15.9615 -7.90081 -13.8079 -15.3772 -8.16195 -12.8751 -15.4896 -9.06065 -13.1209 -15.2211 -9.47578 -12.1989 -15.0843 -9.43857 -11.1932 -15.1136 -10.3264 -11.5877 -15.4293 -10.8599 -12.1161 -14.8104 -10.5214 -12.7539 -15.4422 -10.4893 -12.1692 -16.2028 -11.2655 -12.1519 -16.6831 -10.8799 -12.2761 -17.6134 -10.8519 -11.2898 -17.377 -9.96209 -11.5192 -17.5836 -9.38957 -12.089 -18.0777 -9.06266 -12.3141 -17.1683 -9.15303 -13.2732 -17.5232 -9.75613 -13.6566 -18.1925 -9.29802 -13.7399 -19.0927 -9.92087 -14.2631 -19.604 -9.87721 -15.1772 -20.0196 -8.92611 -15.3246 -20.3178 -8.14627 -15.7473 -20.9115 -8.60383 -14.9525 -21.1878 -8.31477 -14.4274 -22.0437 -7.43117 -14.0285 -21.711 -6.48527 -13.9725 -21.4907 -5.87564 -13.2406 -21.7622 -5.34181 -12.6697 -21.1047 -5.18015 -11.7172 -20.6699 -6.00814 -11.465 -20.2066 -5.31066 -11.3245 -19.5206 -4.75262 -10.6327 -19.0356 -5.29103 -9.80792 -18.9444 -4.86012 -9.49027 -19.7793 -5.00206 -8.89886 -20.5085 -4.31486 -8.16164 -20.8406 -3.76051 -7.41923 -21.1529 -3.35498 -8.21781 -21.6072 -2.40621 -7.81064 -21.4541 -1.69206 -8.31755 -21.987 -1.67204 -8.21179 -22.9949 -0.933643 -7.6586 -23.2668 -1.37687 -7.31341 -24.0375 -1.72107 -6.62773 -24.7177 -1.85173 -6.79856 -25.6954 -1.87749 -7.71862 -25.3034 -2.69426 -7.81314 -24.9247 -3.38983 -8.57092 -24.8521 -2.60494 -9.00279 -25.2271 -2.71021 -9.81704 -24.6492 -3.25392 -9.48564 -23.9264 -3.96275 -9.34345 -23.2226 -4.17688 -8.85005 -22.3598 -4.79146 -9.53039 -22.6683 -5.29316 -8.89936 -23.3685 -5.3619 -8.41291 -24.2144 -6.24216 -7.89562 -24.2551 -6.40015 -7.06308 -24.8517 -7.26197 -6.94339 -24.3876 -8.08437 -6.38125 -24.1393 -8.81509 -5.76924 -24.1109 -7.88297 -5.30797 -24.0827 -7.47347 -4.43912 -23.8489 -7.23621 -4.15531 -22.8953 -7.7792 -3.32538 -22.7887 -8.04141 -3.86582 -21.9637 -8.88505 -4.04521 -21.3959 -8.60925 -4.98005 -21.5848 -9.11142 -5.86783 -21.693 -9.54804 -6.50219 -22.2861 -9.18395 -7.02752 -21.512 -8.40021 -7.07126 -22.0499 -7.5598 -7.59429 -22.1259 -7.48781 -7.59681 -21.0884 -8.04822 -7.95729 -20.3484 -7.47347 -7.32285 -19.9293 -7.80925 -6.39547 -20.1817 -7.20787 -5.96589 -20.8944 -6.596 -6.65475 -21.3646 -6.28512 -6.25748 -22.2499 -5.71755 -5.71273 -22.8991 -5.16775 -4.94409 -23.0402 -4.58835 -5.39681 -22.4266 -4.68232 -4.4069 -22.2742 -5.50608 -4.07434 -22.0598 -5.16879 -3.8412 -21.1346 -5.46359 -4.26161 -20.2735 -4.91734 -4.90197 -19.7913 -5.54971 -4.6526 -19.0339 -6.24377 -5.39012 -19.1107 -6.83772 -5.16891 -19.8784 -6.93569 -4.17625 -19.5471 -6.72659 -4.28783 -18.5526 -6.52914 -4.16882 -17.6279 -6.82549 -4.25095 -16.6625 -7.0231 -3.94231 -15.6988 -7.94676 -4.07267 -15.4029 -8.33437 -4.85926 -14.8666 -8.3971 -5.76893 -14.5558 -7.52297 -6.20984 -14.3586 -8.08019 -6.55877 -13.5311 -8.99507 -6.26774 -13.1712 -9.75652 -5.6106 -13.4742 -10.6417 -5.90177 -13.7532 -10.57 -6.23204 -14.7105 -11.2211 -5.55426 -14.4786 -11.9457 -5.12367 -15.0225 -12.1852 -5.97619 -15.5284 -12.3604 -6.77529 -16.0528 -13.1118 -6.2103 -15.7193 -14.0003 -5.9677 -15.4423 -13.973 -6.81053 -14.9124 -13.604 -7.68192 -14.6828 -12.6722 -7.57804 -14.497 -12.5375 -8.56068 -14.6176 -12.7723 -9.22528 -15.3507 -13.6585 -9.49958 -15.5095 -13.967 -9.73231 -16.4749 -14.7339 -9.36324 -17.0519 -14.1738 -9.45675 -17.9398 -14.0685 -9.7012 -18.9063 -14.2721 -9.10496 -19.6467 -14.1081 -8.15977 -19.8521 -13.3831 -8.84652 -20.0493 -13.7039 -9.66948 -20.4803 -14.6751 -9.55269 -20.5059 -15.5333 -10.1198 -20.4703 -15.9035 -10.4838 -19.6071 -16.1499 -11.2763 -20.1485 -16.6713 -11.3476 -20.989 -16.178 -10.7906 -21.6836 -16.3294 -10.4079 -22.6152 -15.4199 -10.9505 -22.4815 -14.8428 -11.0046 -23.3739 -13.9904 -10.3675 -23.4553 -13.2857 -10.2653 -22.8059 -13.4007 -9.32155 -23.1393 -13.327 -9.2345 -24.1186 -13.9835 -8.61258 -23.6572 -14.3397 -8.34322 -24.5571 -14.952 -7.88276 -23.9108 -15.8867 -7.81423 -24.3205 -15.6916 -7.08621 -25.0171 -15.8933 -6.40276 -25.7624 -16.1602 -5.40715 -25.7702 -16.7393 -5.02075 -26.4824 -17.2442 -4.98768 -25.5935 -17.5296 -3.96997 -25.6782 -16.5698 -3.64645 -25.5806 -15.802 -4.22521 -25.1202 -15.7383 -3.46815 -24.4757 -14.9183 -3.02614 -24.0871 -14.3818 -2.51124 -24.7319 -13.8131 -3.30906 -25.0553 -13.0973 -3.58522 -25.7476 -13.9345 -3.88855 -26.2267 -13.558 -4.69868 -25.7517 -13.622 -4.89207 -26.6888 -13.8474 -4.96039 -27.6334 -14.8446 -4.81585 -27.6445 -15.0256 -5.39882 -26.8038 -15.6757 -6.1654 -27.0618 -15.4123 -5.88883 -27.9457 -15.362 -5.51275 -28.8626 -15.5804 -5.32557 -29.797 -16.3625 -5.92373 -29.7809 -16.3542 -6.64338 -30.4749 -15.5902 -7.18233 -30.2211 -15.0081 -7.74775 -30.7345 -14.5167 -8.4033 -30.0223 -15.4749 -8.23842 -29.7202 -15.8862 -7.70025 -28.9883 -15.5219 -6.90987 -28.5191 -15.0255 -7.16154 -27.6995 -15.6024 -7.92836 -27.5473 -14.7743 -7.98083 -26.9475 -15.5623 -8.34534 -26.3214 -14.9517 -9.1176 -26.1788 -15.485 -9.25324 -25.3534 -16.3537 -9.70271 -25.1853 -16.665 -9.91503 -24.2903 -17.6323 -10.1468 -24.3917 -18.3082 -9.43831 -24.5163 -19.109 -9.26375 -23.8507 -19.3495 -8.30183 -24.0907 -19.8314 -8.27773 -23.2275 -19.9587 -7.77677 -22.3474 -20.549 -7.04512 -21.8889 -21.1534 -6.35341 -22.2972 -20.9672 -6.07794 -21.3274 -20.6352 -6.50328 -20.3644 -21.2523 -7.26333 -20.4483 -20.8615 -7.11025 -19.5093 -19.8876 -7.17865 -19.1638 -19.3312 -6.36173 -19.2353 -20.0118 -6.08181 -18.5937 -19.202 -6.00994 -18.0225 -19.6197 -5.11386 -18.0133 -20.379 -4.61503 -18.3947 -20.9127 -4.61957 -17.5194 -20.9148 -3.69885 -17.9314 -21.5436 -3.24563 -18.6015 -21.8881 -3.25916 -19.5484 -22.0221 -2.34286 -20.0806 -22.0658 -1.62993 -19.4544 -22.7216 -1.00753 -19.2219 -22.2342 -0.8696961 -20.1535 -22.4419 -1.24312 -21.0358 -22.0501 -0.7951491 -21.8812 -21.8347 0.1317419 -21.4937 -21.0571 -0.1067441 -20.9489 -21.001 0.3465859 -19.9953 -21.8355 0.7861109 -19.6148 -21.5871 0.9436489 -18.6884 -22.0972 1.78834 -18.9148 -22.1263 2.8164 -19.0554 -21.9275 2.90986 -18.0475 -22.202 3.69677 -17.6129 -21.8649 4.55134 -17.3062 -22.512 4.08227 -16.7111 -23.0097 3.19879 -16.9191 -23.6456 3.85572 -17.2834 -24.4951 4.35555 -16.9988 -24.7661 4.54688 -16.0003 -24.1356 5.25866 -15.7565 -23.9589 6.12158 -16.2592 -24.1297 6.63728 -15.4253 -24.0164 7.48711 -14.9479 -24.4206 8.06712 -14.2153 -25.2387 8.12538 -14.8389 -24.9034 7.80166 -15.7242 -24.4987 8.05162 -16.6046 -23.8772 8.11679 -17.3886 -23.7129 7.6221 -18.2424 -23.4232 6.95134 -18.8176 -23.701 5.9467 -18.7974 -23.4847 5.35271 -17.9615 -22.786 5.37258 -17.258 -22.0103 5.79892 -17.7749 -21.3605 5.55046 -16.9071 -21.6403 5.66122 -15.936 -22.5319 6.28481 -16.0721 -22.0097 6.98071 -15.626 -22.4731 7.64317 -14.9904 -21.731 8.27225 -14.9306 -21.5685 8.90573 -15.7629 -22.5318 9.09689 -15.6777 -22.4554 9.68939 -14.8811 -23.3051 10.0631 -15.0712 -24.0742 10.3829 -14.5804 -24.2638 10.1997 -13.6274 -24.5833 9.35237 -13.163 -24.5575 10.1704 -12.4908 -24.4137 10.0169 -11.516 -25.1729 9.56208 -11.1656 -24.6237 9.69204 -10.329 -24.7246 8.72482 -10.5023 -24.3687 8.22521 -11.281 -25.1616 7.5844 -11.1103 -24.7375 7.24734 -11.9275 -23.9202 7.10187 -12.402 -23.1028 6.53721 -12.2588 -22.8602 5.59963 -12.1298 -21.9647 5.27957 -11.9871 -21.36 4.80487 -12.7033 -20.6123 5.3045 -13.0915 -19.7503 5.01882 -12.4957 -19.546 5.37484 -13.4154 -19.1566 4.49161 -13.351 -18.9008 3.81449 -13.9525 -19.1784 2.87603 -13.9014 -18.5617 2.26281 -13.6592 -18.4271 1.68139 -12.7868 -18.5002 2.5467 -12.3191 -18.6226 2.16832 -11.4478 -18.0421 2.52053 -10.6589 -17.4866 2.68864 -11.5467 -16.8739 2.52193 -12.3225 -16.1929 3.16652 -12.0273 -15.8184 4.06298 -12.2037 -14.8401 4.17653 -12.5276 -14.3545 4.8152 -13.1389 -13.4432 4.53628 -12.94 -12.905 4.64293 -12.0719 -12.4288 5.24999 -12.7346 -13.2952 5.56853 -13.0622 -13.4708 5.97749 -12.0903 -14.3368 6.10209 -12.4741 -14.2096 7.09977 -12.7956 -13.7808 7.03869 -13.6956 -14.5748 7.64674 -13.6422 -15.3196 7.43041 -14.2665 -16.0511 7.12142 -14.8729 -16.2657 6.19944 -14.5027 -15.9113 5.33651 -14.0867 -15.5493 4.48042 -13.7272 -16.441 4.0453 -13.7069 -17.285 3.51449 -13.4833 -17.7652 3.89235 -14.2955 -18.3069 3.35072 -14.9362 -18.3543 3.15344 -15.9176 -19.2302 3.1087 -16.4359 -20.1343 3.50171 -16.1713 -19.8162 3.34045 -15.2836 -20.8385 3.45826 -15.1842 -21.1403 3.08993 -16.0806 -20.5095 2.6288 -16.7744 -20.727 1.88922 -16.0658 -20.5002 1.06739 -16.5525 -20.6621 0.4656989 -15.7765 -21.0303 1.0927 -14.9463 -20.7314 1.89995 -14.4458 -20.5083 1.0493 -13.9128 -19.8168 0.4131059 -13.5225 -19.1657 -0.3945351 -13.5876 -19.9988 -0.6632901 -14.0608 -20.7868 -1.18704 -14.4985 -20.5566 -1.35438 -15.4337 -19.6062 -1.65251 -15.4343 -18.7237 -1.20534 -15.2125 -18.8385 -0.8306481 -16.1451 -18.3425 -0.08256157 -16.4229 -18.1511 -0.02739007 -17.4243 -17.8836 0.7306219 -16.8715 -17.5699 0.6075169 -15.9118 -17.1727 0.9836439 -15.089 -16.6693 0.1883479 -14.7214 -17.2052 0.5112789 -13.9844 -16.3087 0.8879749 -13.9837 -15.8487 0.8900969 -13.0091 -16.2043 1.45603 -12.2856 -17.1105 1.42141 -12.8317 -16.4205 1.71307 -13.4963 -15.6601 2.28462 -13.7098 -15.3733 2.99154 -13.0369 -14.5075 2.97832 -12.7225 -14.2083 2.43874 -13.5273 -13.7416 2.6357 -14.3347 -13.4547 3.49108 -14.615 -14.3435 3.44813 -14.1866 -15.2309 3.38236 -14.7119 -15.2003 3.13648 -15.734 -15.2061 2.19474 -15.9742 -15.8017 2.53744 -16.7472 -15.8073 2.98247 -17.7539 -15.9914 3.49149 -16.9164 -15.2764 4.13416 -17.2703 -14.9823 4.05711 -18.2289 -15.2098 3.76082 -19.1801 -15.6463 3.84523 -20.0011 -15.0384 4.1983 -20.5907 -14.6462 5.08659 -20.8417 -14.682 6.11948 -20.9262 -13.8006 5.93755 -20.5679 -13.758 5.48738 -19.6461 -13.1676 5.96195 -18.961 -13.4215 6.7856 -18.4382 -13.9051 7.34726 -19.0807 -14.8539 7.0614 -19.1461 -15.8229 7.02527 -18.7751 -16.7584 6.68764 -19.0279 -17.6767 6.6458 -18.4949 -16.8326 6.75542 -17.8868 -16.5382 7.54972 -17.3584 -17.3713 7.46073 -16.8415 -18.0453 8.02251 -17.3016 -18.2807 8.91538 -17.7771 -17.3094 8.9162 -17.4733 -17.0459 9.64554 -16.8612 -18.0431 9.67845 -16.769 -18.2496 10.173 -15.9098 -18.788 9.67459 -15.2328 -18.685 8.72001 -15.0023 -18.7521 9.11242 -14.0652 -18.4122 9.11093 -13.104 -17.6082 9.61161 -13.3981 -17.599 10.6152 -13.1763 -17.0548 10.9594 -12.3913 -17.778 11.1785 -11.655 -17.3216 10.7032 -10.8748 -18.2708 10.3293 -10.9745 -18.5967 10.6894 -10.0628 -19.3247 10.0592 -9.68923 -19.1846 9.53826 -8.81105 -18.6862 9.62056 -7.951 -19.1801 10.1324 -7.19787 -19.8705 10.9132 -6.95018 -20.4746 10.8162 -7.78612 -20.1748 11.7486 -7.80785 -20.0553 12.2995 -8.63065 -20.4068 13.2668 -8.56897 -21.1986 13.6842 -8.22209 -21.2348 14.158 -9.13418 -21.3778 15.1868 -9.04509 -22.0451 15.7931 -8.71462 -22.8369 15.1784 -8.8575 -23.4532 14.7692 -9.57795 -23.469 15.1264 -10.5077 -22.651 15.6826 -10.275 -23.0506 16.577 -10.0585 -23.3986 16.7369 -11.0145 -23.0291 17.2643 -11.8046 -23.8328 16.8482 -12.2766 -24.2225 16.658 -13.1784 -23.7005 15.9435 -13.5814 -22.9801 15.3448 -13.3387 -23.5692 15.6591 -12.6395 -23.2168 15.9469 -11.7898 -22.3843 16.1811 -12.1987 -21.6661 16.3355 -11.5978 -21.4383 15.4079 -11.717 -20.4956 15.1666 -11.5941 -20.5871 15.2429 -10.6389 -21.4817 15.0216 -10.647 -22.3145 14.8174 -10.1533 -22.9164 14.062 -10.3292 -23.5404 13.3073 -10.4417 -24.2839 12.7071 -10 -23.6723 12.05 -10.4299 -24.0734 12.3927 -11.3546 -23.2417 12.9191 -11.2407 -22.728 12.3516 -11.8591 -23.1634 11.5065 -12.0083 -23.5172 11.5848 -12.9267 -24.4227 11.6291 -12.522 -25.3388 11.3641 -12.2328 -25.8516 11.8918 -12.8846 -26.7296 11.7665 -12.3845 -26.146 12.4421 -11.8651 -25.8834 13.3005 -11.3766 -26.5233 13.8263 -11.9913 -26.4278 14.8324 -11.7555 -26.2343 15.0705 -12.7696 -25.3251 14.9869 -13.1457 -25.4275 14.2032 -13.8038 -24.8933 13.4193 -14.1199 -24.8765 12.4237 -14.365 -25.5023 11.9053 -14.9133 -26.1045 11.8456 -14.0035 -27.1154 12.0632 -14.1235 -27.643 11.3763 -14.4256 -28.1721 10.7726 -15.0011 -27.5851 10.0692 -15.3589 -28.3234 10.1685 -16.0189 -27.9105 10.517 -16.8656 -27.7188 9.76253 -17.4664 -27.1069 8.9916 -17.4102 -26.4127 9.72252 -17.6131 -25.6559 9.11338 -17.8128 -24.938 8.89472 -18.5096 -25.6656 8.47135 -19.036 -25.8833 9.00822 -19.7807 -24.8948 9.15421 -19.7174 -24.2256 9.86735 -19.7759 -24.8911 10.4345 -20.1413 -24.6279 11.4225 -19.9651 -25.5118 11.9213 -20.2515 -25.543 12.7259 -19.7605 -25.4722 13.674 -20.2315 -25.3492 14.0004 -21.1318 -25.0311 13.1076 -21.5105 -24.0643 12.9286 -21.5353 -23.0808 13.0603 -21.6328 -23.0174 13.473 -20.7649 -22.2017 14.0062 -20.7 -22.6885 14.5179 -20.0426 -21.9861 14.2418 -19.3913 -21.1688 13.7834 -19.6245 -20.2094 13.7266 -19.3926 -20.6585 12.8696 -19.5323 -20.0227 13.0007 -20.2545 -20.3059 13.3365 -21.1747 -19.88 12.5039 -21.476 -20.1246 12.8322 -22.3911 -19.9956 11.8383 -22.4373 -19.4304 12.149 -23.2166 -18.3874 12.2879 -23.2836 -18.836 12.6903 -24.0356 -18.544 13.5334 -24.5211 -19.28 13.1196 -25.0348 -19.451 12.4943 -25.7337 -19.1711 11.5378 -25.8066 -19.8754 11.6665 -26.6002 -18.9273 11.4798 -26.8863 -17.9509 11.8591 -26.9561 -17.1653 11.9057 -26.3041 -16.9298 10.9468 -25.9047 -16.1798 10.3937 -25.6191 -15.7214 11.1817 -25.2768 -15.0691 11.7965 -25.7414 -15.8541 12.3157 -25.6227 -16.4264 12.7976 -24.9389 -16.8514 13.7069 -25.2529 -16.1423 14.1096 -25.8364 -15.8446 13.6833 -26.6248 -15.3212 13.1112 -27.2488 -15.4995 12.4618 -28.034 -15.8181 11.5176 -28.0446 -15.4704 10.6005 -28.5186 -16.2791 10.0418 -28.8471 -17.0722 9.50835 -28.8125 -17.3787 8.54976 -28.6415 -17.5537 8.04115 -27.8371 -18.0134 8.70534 -27.2566 -18.4642 9.29112 -26.5261 -19.273 9.31689 -25.9521 -18.9961 8.69048 -25.2223 -19.4354 9.2031 -24.4783 -18.6634 8.79545 -24.0443 -18.1054 7.9731 -24.2469 -17.6262 8.36937 -23.5681 -17.772 7.5642 -22.9342 -16.9008 7.14537 -22.5655 -16.2611 7.3539 -21.8611 -16.464 7.929 -21.0222 -16.2511 7.21054 -20.3162 -15.7565 6.34318 -19.853 -16.3611 5.60833 -20.1039 -16.5355 4.95987 -20.8844 -17.2909 4.33639 -20.7946 -18.0782 4.4023 -20.1747 -18.8616 3.82131 -20.0437 -18.048 3.2115 -19.958 -18.1157 2.21961 -20.1939 -18.7516 2.1882 -21.0178 -18.2738 1.28973 -21.0759 -17.9424 0.4680959 -21.4121 -18.1781 0.7371489 -22.4025 -17.554 1.37244 -22.8311 -18.4839 1.75796 -23.211 -18.9172 1.11307 -23.7504 -18.3084 0.3227529 -24.0159 -17.6493 0.09907643 -24.7153 -17.182 0.9854059 -24.5369 -17.0764 1.82232 -24.1414 -16.8995 2.21772 -23.266 -16.3682 2.75825 -22.6806 -15.7133 2.66829 -21.9187 -15.3879 3.42867 -21.3953 -14.4938 3.72575 -21.439 -14.6611 4.28375 -22.2447 -14.7806 5.0938 -22.7755 -13.8479 5.04936 -22.4523 -13.5529 5.67915 -21.6679 -12.9635 5.06877 -21.1101 -11.9863 5.22109 -20.9742 -12.4739 5.99732 -21.2969 -12.2789 6.61992 -22.0782 -11.3912 7.1776 -22.1798 -10.7441 7.83774 -22.2478 -11.505 8.50641 -22.0251 -11.2175 9.18915 -21.4256 -10.434 9.36228 -22.0264 -9.59138 9.3029 -21.4929 -9.32598 8.82699 -20.7512 -10.1059 8.66098 -20.264 -9.62242 9.22907 -19.6188 -9.05116 9.82937 -19.0445 -9.74009 10.4646 -19.1627 -9.76277 10.8519 -20.1288 -8.9292 10.8271 -20.6798 -7.98828 10.6386 -20.7407 -7.36782 11.4145 -20.7371 -6.64428 11.6573 -21.2691 -5.8015 11.6845 -20.7717 -6.12922 10.7356 -20.596 -6.30537 9.77558 -20.7313 -5.54139 9.72569 -21.3173 -4.78474 9.73401 -20.644 -4.24336 8.97553 -20.2519 -3.58938 9.20199 -19.5216 -2.94432 9.84404 -19.0957 -2.46095 10.4039 -19.7728 -2.14812 9.82945 -20.5213 -1.23488 9.56824 -20.1147 -0.386588 10.1415 -20.0085 --0.114268 9.31126 -20.1356 --0.609684 9.05596 -19.3703 --0.116345 8.73692 -18.5828 --0.677295 7.92326 -18.9425 --1.10737 7.07699 -18.621 --0.722975 6.4533 -19.2629 -0.007454425 6.5362 -18.612 -0.889192 5.98482 -18.5399 -1.01098 6.69148 -19.1971 -0.315712 6.13783 -19.7249 --0.368301 6.04559 -20.508 --0.02902773 5.18845 -20.1413 -0.58151 4.73576 -20.7465 -1.14943 4.55425 -21.6008 -1.93437 4.87301 -21.1306 -2.56001 4.05136 -21.1822 -2.45869 3.31713 -20.5322 -2.15638 2.94102 -19.6569 -2.45861 2.28554 -18.9606 -3.23489 2.39758 -19.608 -4.16262 2.18734 -19.8642 -4.45832 1.56619 -19.2113 -3.59192 1.11422 -19.1185 -2.89981 0.5647699 -19.4139 -3.30319 0.05458743 -18.6298 -3.03065 -0.1652671 -17.7394 -3.0335 0.7232119 -17.2583 -2.66821 0.2951069 -16.3683 -1.68013 0.2443409 -16.5999 -1.25333 0.6596589 -17.3823 -1.36613 1.21442 -16.6067 -0.794429 0.7615669 -15.9346 -0.602888 -0.2033291 -16.1436 -0.599418 -1.07427 -15.664 -0.178556 -0.3583211 -15.2042 -1.0484 0.1927069 -14.9699 -1.78118 0.6384499 -15.2984 -1.8421 1.33798 -14.6278 -1.06419 1.89727 -14.7102 -0.958993 1.98874 -13.6961 -1.45246 1.40597 -12.9637 -2.03372 2.15697 -12.6613 -2.48666 2.82657 -12.1236 -2.71193 2.59742 -11.1166 -3.56496 2.44339 -10.626 -4.42282 2.93548 -10.9124 -4.79843 2.21888 -11.4794 -4.81019 2.72033 -12.3165 -5.60783 2.20502 -12.6142 -5.76531 2.01689 -13.6608 -5.17615 1.32959 -14.1888 -4.64882 0.9458489 -13.457 -4.54837 1.92587 -13.8506 -3.66949 1.52393 -13.8686 -3.70472 0.7257869 -13.1676 -3.21996 0.03931973 -13.5301 -2.32409 -0.06936657 -13.9561 -2.25509 -0.9077691 -13.5352 -1.28403 -0.9120921 -13.2686 -1.55962 -0.8053471 -12.2622 -2.07853 -0.8321221 -11.39 -2.96269 -0.6324651 -11.9394 -3.9171 -0.5864101 -11.6555 -4.90525 -0.4619421 -11.7578 -4.58383 0.4428069 -11.7171 -4.35171 0.1804629 -10.7637 -3.53606 0.08697703 -10.1219 -3.95773 -0.8467421 -10.178 -3.99775 -1.83428 -9.86372 -3.47865 -1.42612 -9.08215 -3.06046 -0.7558851 -8.44099 -2.16138 -0.4875691 -8.37484 -2.18024 -1.38548 -8.79845 -1.64328 -1.26561 -9.56028 -1.0998 -1.45241 -10.3984 -0.536515 -2.0378 -11.01 --0.252701 -1.77412 -11.519 -0.204412 -1.66229 -12.3586 -0.218641 -0.6711801 -12.2728 -0.517471 -0.09192697 -11.5376 -1.30077 0.009770654 -10.8925 -0.727763 0.4559529 -10.1998 -1.04943 0.1380059 -9.27933 -0.807864 0.1572499 -8.28873 -0.537264 -0.7919651 -8.48689 --0.07878473 -0.5555671 -7.82777 --0.193374 -1.40611 -8.35431 --1.07986 -1.45352 -7.8771 --0.637373 -1.75861 -7.04889 --1.68933 -1.77252 -6.9446 --2.48422 -1.15431 -6.85689 --2.82331 -0.4757271 -7.56819 --2.87203 0.1268349 -6.76894 --2.38534 0.7311229 -6.1294 --2.0138 -0.2102131 -5.92148 --2.5087 -1.09497 -5.63007 --1.57538 -1.31338 -5.39296 --1.08232 -1.93171 -4.84215 --1.2876 -1.11534 -4.28648 --2.13204 -1.4137 -3.88271 --1.33844 -1.82 -3.46019 --0.864781 -0.9946151 -3.18706 --1.34428 -0.09069667 -3.23954 --1.78152 -0.8644681 -2.73939 --2.53347 -0.8744561 -2.01978 --3.05288 -0.8049151 -1.21029 --3.40654 0.1859499 -1.2424 --3.30156 -0.06793007 -0.2662259 --4.2652 -0.07618187 -0.3892169 --4.72969 -0.05812407 0.4708821 --4.11701 -0.8759841 0.4016271 --4.78122 -1.24302 -0.2799089 --5.3325 -2.09282 -0.4551589 --5.72361 -1.57339 -1.24173 --6.69916 -1.40582 -1.37369 --6.78113 -0.4867981 -0.8820919 --5.9312 -0.1354211 -1.19415 --6.17728 -0.6373761 -2.06159 --6.91105 0.06091763 -2.08966 --6.14994 0.5722719 -2.37088 --6.12998 1.50968 -1.88311 --6.7306 2.33884 -1.86092 --6.46353 2.98736 -2.52695 --7.31111 3.56097 -2.44299 --7.68127 3.98651 -3.32391 --8.5968 3.5428 -3.66944 --9.41992 3.78404 -4.09519 --9.68608 2.93385 -4.52634 --9.96617 2.91389 -3.61911 --10.3852 3.55328 -3.13088 --9.9638 3.77818 -2.27026 --9.14686 4.35515 -2.59088 --8.40541 4.97466 -2.96442 --7.41739 4.97538 -3.13185 --7.3299 6.00454 -3.32601 --6.81714 6.46497 -4.02947 --7.07905 7.43123 -4.21016 --7.69203 6.72433 -4.45681 --7.74953 6.37344 -5.43257 --7.68011 6.65598 -6.37041 --8.20265 5.94554 -6.93059 --8.99725 6.19042 -7.4383 --8.55976 6.39527 -8.30373 --8.03402 6.31344 -9.16696 --7.67426 6.84898 -9.87227 --7.15398 7.36694 -10.453 --7.23584 8.37391 -10.5701 --8.1951 8.33129 -10.7679 --8.11674 7.73373 -11.4718 --7.84741 8.72686 -11.6569 --7.57609 9.02931 -12.4994 --7.95854 8.16365 -12.7825 --7.3952 7.4588 -13.3154 --6.71185 7.05574 -12.6166 --5.7682 6.78765 -12.3442 --5.05686 6.11042 -12.5055 --4.08918 6.28724 -12.5552 --3.84818 7.27498 -12.4602 --2.971 7.6659 -12.8094 --2.70561 6.76967 -13.1766 --2.90736 6.10524 -13.8567 --2.58189 5.45051 -13.1776 --2.32075 5.37246 -12.2159 --2.3559 4.72206 -11.503 --2.39597 3.66975 -11.1771 --1.73313 2.88029 -10.9578 --1.89163 3.2547 -10.0057 --0.959939 3.57536 -9.97183 --0.403854 3.00341 -10.5793 -0.173017 3.73846 -10.9698 --0.709485 3.58099 -11.4054 --1.40363 3.5623 -12.1598 --1.09327 3.3939 -13.1147 --0.576146 2.71041 -13.488 -0.358851 3.02293 -13.7638 -1.09813 3.59485 -13.4261 -2.01653 3.5502 -13.1749 -2.85557 3.71066 -13.6898 -3.31041 3.96829 -12.8413 -3.78721 3.32026 -13.4015 -3.76133 2.83033 -14.3185 -4.7063 2.74919 -14.6951 -5.0833 3.49301 -15.2532 -5.77606 3.70298 -14.6715 -6.70503 3.55938 -15.073 -6.40197 3.02803 -14.3157 -5.67386 2.52106 -14.6012 -5.04385 1.94818 -15.1646 -4.89611 1.15962 -15.814 -4.3312 0.5536319 -15.2571 -4.47495 -0.4515811 -15.2604 -5.38582 -0.4232491 -15.4591 -6.01099 -0.5750541 -14.7604 -5.99322 -1.04955 -13.8264 -6.41168 -1.60197 -13.2035 -7.30183 -1.37559 -13.5091 -7.80961 -1.43045 -12.6488 -7.98017 -0.7642221 -11.9277 -7.59944 -0.08110047 -12.4654 -6.75152 -0.1570411 -11.9121 -6.47895 0.2692999 -12.79 -6.19409 0.4683849 -13.722 -6.86937 1.17943 -13.7118 -7.09554 2.04824 -14.1124 -7.89975 2.3074 -14.6632 -8.45435 2.9208 -14.1 -7.7478 3.65644 -14.1445 -8.11149 4.05209 -15.0008 -7.86632 3.31738 -15.5607 -7.91586 2.42355 -16.1332 -7.58325 1.57773 -16.5912 -7.07434 0.8393939 -17.0237 -6.86367 -0.02400917 -17.463 -7.39397 -0.8501431 -17.2822 -7.02057 -1.18478 -16.4387 -6.40468 -0.5039211 -16.0014 -6.71946 -1.0128 -15.2451 -6.58252 -1.96687 -15.1954 -5.79003 -2.52636 -15.5518 -5.05796 -2.07332 -14.985 -4.68636 -1.94616 -14.0905 -4.22396 -2.59607 -13.4696 -4.77045 -3.00484 -14.1712 -5.71495 -3.16575 -14.2305 -6.62932 -3.4888 -14.235 -6.76596 -4.43269 -14.5537 -6.70533 -5.29637 -15.1463 -5.99685 -5.97891 -15.3356 -6.44775 -6.03187 -16.2043 -5.52284 -6.21395 -16.4676 -4.80351 -6.6693 -17.0347 -3.83873 -6.80935 -17.3588 -3.49684 -5.83226 -17.1479 -3.9838 -5.72784 -17.9998 -4.30139 -4.82225 -18.23 -4.58098 -3.97432 -18.608 -4.197 -3.77785 -17.7625 -3.54047 -3.08056 -17.3506 -3.51772 -3.34188 -16.415 -3.59249 -3.98642 -15.6008 -2.60172 -3.89766 -15.6753 -1.74083 -3.6099 -15.2596 -2.28536 -2.81783 -15.2544 -1.51479 -2.7454 -15.7778 -1.64239 -2.95682 -16.7478 -1.86556 -1.96615 -16.6619 -2.79507 -1.88612 -16.9573 -3.33286 -0.9583581 -16.8656 -3.83355 -1.8018 -16.6854 -4.24818 -0.9078041 -16.5357 -4.59806 -0.5400021 -17.3777 -5.23122 -0.9785461 -18.0612 -5.42352 -1.93557 -18.2492 -5.67411 -2.87496 -18.0313 -6.01116 -2.96445 -17.0113 -6.99499 -2.97878 -17.2395 -7.99266 -3.0955 -17.0294 -8.89674 -3.18417 -16.5848 -9.38641 -2.46012 -16.0401 -9.91873 -1.63274 -15.9261 -10.5554 -1.45965 -16.6276 -11.4792 -1.59501 -17.0061 -10.9965 -1.63509 -17.8897 -11.6093 -1.16565 -18.548 -10.8808 -0.4971311 -18.902 -10.1626 0.2036259 -18.7106 -9.23312 0.08656623 -18.2927 -8.49643 0.3760399 -18.9039 -8.16862 1.18128 -19.3453 -8.08025 1.97157 -19.9052 -8.8923 1.46368 -20.2602 -8.06599 1.39928 -20.8239 -7.32283 0.9059429 -20.3919 -6.29568 0.9345559 -20.2451 -5.52196 1.32724 -19.7498 -4.85224 0.5990429 -19.5069 -3.94809 0.2413829 -19.864 -4.02074 -0.7598761 -19.633 -4.22098 -1.25957 -20.4092 -4.48725 -1.10997 -21.3401 -5.4126 -1.27455 -21.153 -5.73149 -2.16087 -20.9346 -5.91549 -2.13553 -21.8565 -5.47474 -2.67334 -22.6208 -4.54644 -3.02773 -22.4434 -3.71418 -3.03889 -21.8559 -2.77794 -2.63371 -21.8094 -2.14814 -3.36566 -21.9087 -1.87587 -3.90962 -22.724 -1.76665 -3.51618 -23.6434 -2.65468 -3.20904 -23.8789 -3.16608 -2.4195 -23.4968 -3.79085 -3.0806 -23.9259 -4.4733 -2.82826 -24.7119 -4.62831 -2.2155 -25.4586 -4.94854 -1.38866 -25.1242 -4.89091 -0.6032211 -24.5314 -5.52947 -0.07740917 -25.0238 -6.36924 -0.5413291 -24.8533 -5.94139 -0.1985801 -24.0047 -5.54717 -0.3894441 -23.1294 -5.16864 -0.2479751 -22.2842 -4.21273 -0.2451801 -21.8848 -4.13751 -0.2606311 -22.886 -3.56769 0.5434939 -22.8118 -2.62091 0.5505289 -22.643 -2.29456 -0.1246861 -23.2065 -1.83482 -0.9639611 -23.4662 -0.870763 -0.8237791 -23.4226 -0.05824397 -1.09619 -22.8594 --0.09596513 -1.91503 -23.3923 --0.893162 -2.51962 -23.11 --0.443888 -3.1363 -23.791 --0.357939 -4.01827 -23.4049 --0.26196 -3.63156 -22.4974 --0.66908 -2.96259 -21.879 --1.14112 -3.75232 -21.6999 --1.7633 -3.12518 -21.2884 --0.911154 -2.90703 -20.838 --0.279171 -3.08851 -20.0089 -0.515672 -3.64556 -19.7536 -0.861919 -3.29979 -20.5465 -0.939159 -4.25935 -20.7412 -1.87581 -4.46622 -20.9353 -2.08842 -3.53606 -20.5193 -3.00993 -3.72533 -20.7491 -3.91547 -4.13362 -21.0197 -3.66182 -4.45965 -20.1483 -3.67298 -3.62314 -19.6142 -2.7817 -3.41588 -19.1308 -1.87457 -3.74881 -19.0285 -2.18877 -3.68153 -18.0874 -1.85159 -4.02353 -17.2573 -2.57887 -4.68092 -17.1073 -1.81968 -4.91478 -17.7766 -2.0247 -5.59035 -18.4669 -2.71776 -6.37425 -18.3483 -2.28048 -6.31639 -19.2725 -3.16819 -6.03407 -19.4463 -4.19029 -6.20895 -19.4782 -4.30605 -7.18056 -19.2901 -4.94117 -7.636 -19.8606 -5.24992 -6.72125 -20.1958 -5.40064 -5.72599 -20.4203 -4.55471 -5.87629 -21.0185 -3.82766 -6.27684 -21.5874 -3.06586 -6.11834 -22.1322 -2.36956 -5.70321 -21.6252 -2.43991 -4.92936 -22.2735 -1.79251 -5.59334 -22.5357 -1.64168 -5.02766 -23.4071 -0.883659 -5.13837 -22.6909 -0.677261 -5.17088 -21.5973 -0.212081 -6.06305 -21.5985 -0.945327 -6.43052 -22.2065 -0.418518 -7.26151 -21.9414 --0.352401 -7.02197 -21.369 --1.10166 -7.74563 -21.0996 --1.5619 -7.7791 -21.9618 --1.07152 -8.71809 -21.9745 --0.773015 -9.61908 -21.5851 --1.09088 -10.2083 -22.367 --1.66559 -9.39239 -22.5186 --2.28452 -9.11593 -21.7959 --2.87176 -8.47458 -21.2119 --2.76719 -7.54882 -21.6738 --3.34812 -7.55734 -20.9279 --4.03248 -6.98914 -21.0991 --4.48312 -6.57104 -21.8693 --4.90909 -7.46907 -22.0236 --4.83768 -6.9125 -22.8309 --5.51923 -6.23359 -22.5647 --5.8444 -6.39594 -21.6184 --6.65292 -5.90993 -21.3542 --6.6408 -5.93065 -22.3218 --7.59969 -5.67083 -22.1587 --8.0112 -5.95159 -23.0741 --8.64572 -6.33942 -23.6955 --8.87983 -7.36918 -23.8914 --9.43938 -8.23884 -23.9112 --8.73702 -8.48705 -23.1887 --7.87354 -8.56447 -23.628 --7.60561 -7.65096 -23.5873 --6.76914 -7.07101 -23.6279 --5.84476 -7.32266 -23.7817 --6.35786 -7.94603 -23.165 --5.74849 -8.70199 -22.8911 --5.0213 -8.06677 -23.1374 --4.47122 -8.74766 -22.6142 --4.266 -9.22298 -21.7225 --4.42068 -10.0248 -21.05 --5.3686 -10.0724 -21.033 --5.0239 -9.94946 -20.1035 --5.58651 -9.10356 -19.925 --6.4273 -9.62797 -19.9278 --7.13094 -9.08762 -19.4925 --8.1134 -8.92965 -19.3485 --7.916 -9.05963 -18.3574 --8.32807 -9.22799 -17.3952 --7.96327 -9.15292 -16.4711 --7.13791 -8.85642 -15.8785 --7.11588 -9.768 -15.415 --7.00063 -9.69721 -14.4271 --7.69845 -9.98535 -13.8907 --7.68748 -9.6762 -13.0239 --7.92961 -9.43329 -12.0699 --7.92671 -10.4868 -12.0024 --8.59261 -10.5495 -11.2957 --8.6775 -11.5486 -11.094 --8.68797 -12.5414 -11.0483 --7.74442 -12.6329 -11.0578 --6.84453 -12.6792 -11.441 --6.38557 -12.1747 -12.1616 --6.51119 -12.3173 -13.1843 --6.54708 -13.2856 -13.4907 --5.70466 -13.4285 -12.8443 --5.081 -12.8168 -13.2028 --4.99353 -12.4479 -14.1598 --4.42168 -11.7269 -14.0085 --4.96361 -11.2728 -13.3389 --4.22436 -10.6491 -12.9119 --4.2285 -11.445 -12.3429 --4.14669 -11.7679 -11.3998 --5.17283 -11.8312 -11.4054 --5.44877 -10.8909 -11.7008 --5.02747 -10.2352 -11.1263 --5.61826 -9.72656 -11.7156 --6.53522 -9.2399 -11.8866 --6.20838 -8.30565 -12.3231 --6.5974 -7.42004 -11.9507 --6.2782 -7.3376 -12.8363 --6.82824 -6.67825 -12.6193 --6.40804 -6.23731 -13.4021 --6.92363 -5.72766 -14.0733 --7.36604 -4.9041 -13.7561 --6.52811 -4.6796 -13.4552 --6.96038 -4.69884 -12.5758 --6.03845 -4.66012 -12.1088 --5.43265 -3.80772 -12.1736 --4.95956 -3.90071 -13.0694 --5.42097 -3.51349 -13.8473 --6.02588 -3.28 -14.5582 --5.71127 -2.30454 -14.6663 --6.1361 -2.34168 -15.5561 --5.44605 -1.8459 -15.9983 --5.34095 -1.08237 -15.3023 --5.19359 -0.1261761 -15.3249 --6.13756 -0.4014821 -15.1934 --6.33861 -1.37939 -14.8834 --7.02211 -2.00619 -14.583 --7.0916 -2.7308 -13.9025 --6.26102 -2.29211 -13.5131 --5.53755 -1.67579 -13.209 --5.78599 -0.9218561 -13.7908 --6.00814 -0.03279137 -13.3574 --5.16127 -0.2396111 -13.0186 --4.50241 -0.5017001 -13.6537 --4.0355 -1.10183 -12.9677 --4.40595 -2.00407 -12.7602 --3.99491 -2.40272 -11.9162 --3.90468 -1.68228 -11.1855 --2.98478 -2.09189 -11.348 --2.52795 -2.90611 -10.8733 --3.23748 -3.5952 -10.94 --4.10549 -3.33083 -10.4292 --4.46487 -3.9652 -11.0701 --4.7935 -4.53333 -10.2818 --4.51815 -4.32224 -9.38423 --3.88007 -4.85704 -8.81559 --3.05388 -5.43962 -8.76801 --2.95326 -5.25805 -7.79273 --3.11289 -5.62807 -6.80737 --3.84332 -5.93795 -6.16283 --3.41668 -5.31978 -5.54174 --3.99729 -5.60541 -4.71294 --3.10798 -5.80203 -4.26087 --2.92027 -4.8907 -4.64093 --2.9109 -3.89138 -4.90957 --3.00046 -3.42475 -5.73778 --2.46196 -2.79446 -6.20766 --2.52325 -3.30564 -7.09432 --2.47193 -4.24255 -6.96971 --1.85409 -4.01607 -7.76991 --1.46386 -3.05662 -7.86694 --1.45138 -3.16027 -6.84119 --1.27275 -3.55974 -5.93515 --0.463365 -3.85465 -6.44962 --0.345314 -4.73189 -6.97517 --0.316016 -5.61252 -6.57138 --1.16991 -6.01009 -6.8733 --0.825195 -6.34851 -6.01649 --0.124582 -6.39183 -5.22978 --0.265916 -7.37975 -5.40636 --0.547706 -7.25828 -4.46605 --1.13949 -8.05264 -4.53642 --0.804051 -8.2579 -5.40517 --0.36128 -8.95647 -4.89748 -0.351421 -9.25248 -4.27555 --0.143853 -8.63982 -3.62493 --1.08199 -8.98477 -3.45789 --2.03974 -8.74539 -3.42986 --2.20091 -7.90317 -4.06796 --1.71095 -7.06307 -4.06292 --2.22502 -6.44268 -3.54289 --1.604 -6.02683 -2.88179 --1.07807 -6.92464 -3.03152 --0.866132 -6.63614 -2.12428 --0.603271 -7.52007 -1.80791 --0.07262313 -7.24904 -1.03063 -0.758423 -7.42199 -1.53871 -1.30433 -6.61682 -1.65737 -1.44446 -6.21385 -0.7584299 -2.03235 -6.21094 0.00865578 -2.10326 -6.58847 0.8900701 -2.27107 -6.54141 1.90547 -1.7516 -5.90335 2.47217 -1.08524 -5.11922 2.40549 -1.98589 -4.64934 2.63138 -2.17226 -4.70741 1.64669 -1.39009 -4.40558 1.15427 -1.54194 -4.66615 0.2103631 -0.855158 -4.90969 -0.5290769 -1.19021 -4.68221 -1.40189 -0.353703 -4.93866 -1.79192 --0.206916 -4.28297 -2.32678 --1.08542 -4.66937 -2.00069 --1.55536 -4.35386 -1.13069 --2.09616 -3.85176 -1.74139 --2.43916 -2.8757 -1.71308 --2.87124 -2.40911 -2.50124 --3.46875 -1.70267 -2.81661 --4.21076 -1.15575 -2.98333 --4.96647 -0.7673731 -3.58126 --5.64395 -1.4383 -3.03941 --6.15349 -2.26748 -2.80886 --6.23738 -2.63336 -3.78964 --7.24683 -2.84992 -3.85762 --6.8888 -3.68234 -4.16646 --6.98638 -4.48584 -3.66969 --6.78895 -3.96426 -2.7724 --6.96153 -3.55093 -1.8643 --7.89252 -3.24965 -1.51386 --8.13237 -4.03718 -2.1182 --8.3258 -4.52643 -1.29865 --7.41958 -4.17537 -1.08487 --7.69389 -3.99519 -0.1256439 --8.67148 -4.16255 -0.3480079 --9.05717 -3.58548 0.3974381 --9.94841 -3.19194 0.6376861 --9.8016 -3.09686 -0.4328389 --9.52498 -3.42947 -1.34264 --9.97777 -4.0948 -0.7808479 --9.94466 -4.55156 -1.6741 --9.9391 -4.11148 -2.60107 --10.2974 -3.40417 -2.03144 --11.1278 -2.93425 -2.3189 --10.2757 -2.35405 -2.38378 --9.94859 -2.49202 -3.28057 --9.81715 -2.94866 -4.12036 --9.32171 -2.70645 -4.9605 --8.36991 -2.74414 -5.26466 --8.82681 -3.02598 -6.12466 --8.79048 -2.02417 -6.42963 --8.85879 -1.53105 -5.57262 --8.31079 -1.18524 -4.83394 --8.2718 -0.1908691 -4.7803 --7.34287 0.1754229 -4.82838 --7.02823 -0.7337681 -5.01594 --6.2372 -1.2643 -5.34531 --6.74877 -1.99315 -4.70819 --7.06329 -1.35354 -3.9178 --7.81427 -1.54819 -3.35142 --8.23527 -0.7291561 -3.7076 --8.84447 -0.05430937 -3.29866 --9.09337 0.9547759 -3.30868 --9.13432 1.70985 -2.72347 --9.0261 2.6643 -2.47088 --9.51312 2.20927 -1.75783 --10.4032 1.90431 -1.99285 --9.95978 1.10081 -1.68893 --9.1643 1.05799 -1.12714 --8.69944 0.4054269 -1.7158 --7.86045 0.6114229 -1.23901 --6.99697 1.29107 -1.26476 --6.15512 1.12304 -0.7985419 --6.29948 2.05812 -0.6360189 --6.33603 2.86782 -0.1275849 --5.56296 3.49514 -0.4207909 --5.49781 4.1652 -1.16401 --4.98307 3.4565 -1.68712 --4.40938 3.07408 -2.38223 --4.8681 2.81065 -3.29712 --4.40621 1.90201 -3.36053 --3.93417 1.14928 -3.745 --3.2121 0.5509129 -3.4248 --2.42866 1.16635 -3.71708 --2.09988 0.5772729 -4.44424 --1.58357 0.5419589 -5.30885 --0.895952 0.3726149 -4.61592 -0.02756167 0.2744969 -5.02169 -1.01955 0.3622549 -5.20791 -0.802494 -0.5858911 -5.19015 -0.349573 -0.1976221 -5.96161 --0.613025 -0.1925751 -6.21995 --0.694255 0.4109489 -6.9541 --0.149815 1.09887 -6.56885 -0.626835 1.01015 -7.12267 -1.4984 0.6952229 -7.50771 -2.45074 0.4011629 -7.36024 -3.08767 0.1352639 -6.67998 -4.06142 0.5546389 -6.83003 -4.84577 1.17428 -7.047 -5.0678 2.1399 -7.15738 -4.26218 2.27236 -7.73927 -4.30462 1.66895 -8.53619 -3.67205 2.48341 -8.47758 -2.68549 2.18537 -8.54579 -2.57971 1.56267 -9.22994 -1.84232 1.22941 -8.68837 -1.27527 2.01662 -8.87929 -1.47414 2.19956 -9.844 -0.762442 2.51611 -10.5738 -0.250464 1.79946 -10.0196 --0.579417 1.67947 -10.4897 --0.801419 0.6846579 -10.3158 --0.912124 0.08110523 -11.1268 --0.930345 -0.2629201 -12.0812 --0.74571 -0.9771571 -12.7995 --1.49629 -0.4676441 -13.1492 --1.79854 0.4533649 -13.0447 --2.62803 0.2749829 -13.6167 --3.55599 0.2698029 -13.1814 --4.2547 0.9220859 -12.772 --3.33735 1.34203 -12.9872 --2.65362 1.90314 -12.6489 --3.55278 2.33066 -12.7465 --2.97591 3.18317 -12.8309 --3.01702 4.12948 -12.787 --3.98402 3.98072 -12.6716 --4.77812 3.49191 -12.403 --4.80929 3.5695 -13.4311 --4.89889 2.78226 -13.9788 --5.86859 2.82125 -13.9387 --6.73754 2.76635 -13.321 --6.05149 3.47047 -13.1765 --6.40112 4.36987 -13.4364 --6.23791 4.65928 -12.5277 --5.32008 4.32601 -12.6549 --5.29807 5.24978 -12.1354 --5.06979 4.5528 -11.436 --4.40658 4.24212 -10.6849 --4.57676 3.85683 -9.74191 --5.41195 3.97853 -10.1086 --4.88217 3.15059 -10.4021 --4.68432 2.19791 -10.2646 --4.02476 2.74423 -9.70027 --3.15454 2.80347 -9.33334 --3.85362 2.74039 -8.69544 --4.80333 3.02416 -8.3438 --4.64385 2.61455 -7.44557 --4.23518 2.07805 -6.64823 --5.0828 2.12886 -6.08652 --5.23895 1.31703 -5.51485 --4.57522 1.15207 -4.74904 --5.01368 1.98996 -4.80621 --4.13814 2.40298 -4.54453 --3.69572 2.14483 -5.42338 --3.84685 3.03409 -5.80887 --4.54485 3.60115 -5.3329 --3.67068 3.97461 -5.52103 --4.11925 4.7917 -5.15779 --4.82915 4.31 -4.62082 --5.71781 4.66386 -4.74784 --6.09226 5.53817 -4.37762 --5.45495 5.10536 -3.75939 --4.54963 5.45408 -3.39488 --5.23275 5.06735 -2.66754 --6.20876 4.89161 -2.60265 --5.87884 5.41784 -1.84266 --6.11218 6.15333 -2.45302 --5.95471 6.22865 -3.47151 --5.14102 6.36951 -2.91876 --4.62875 7.04912 -2.34791 --3.9028 7.64291 -2.68309 --4.44253 7.89548 -3.43368 --3.60604 7.6648 -3.91977 --3.44799 8.35889 -4.65236 --2.4489 8.23255 -4.75901 --1.89284 7.41099 -4.73555 --2.84191 7.02008 -4.79042 --2.2544 6.78325 -4.06059 --1.99671 5.88807 -4.21869 --1.22627 6.50451 -4.06127 --1.32388 6.20685 -3.10699 --1.19027 6.68454 -2.1949 --1.36868 5.90268 -1.54748 --1.71709 6.34121 -0.7589899 --2.24791 6.993 -0.1341699 --1.55837 7.60087 -0.5103429 --1.71364 8.61883 -0.6459289 --1.92503 8.02603 -1.49621 --1.36584 8.28616 -2.32013 --0.469371 8.50639 -2.66028 --0.389903 9.51409 -2.83246 --0.932927 9.1598 -3.63519 --0.01538913 9.07359 -4.06747 --0.570229 9.50573 -4.76855 -0.501231 9.54764 -4.69888 -1.47342 9.41398 -4.3611 -1.90491 9.85217 -3.54705 -1.70574 10.578 -4.12179 -2.02861 11.5252 -4.2484 -2.88752 11.0441 -4.42756 -3.07362 10.9792 -5.40207 -3.65507 10.5635 -6.1475 -4.44175 11.1692 -5.77783 -3.80226 11.9353 -5.86663 -3.06246 12.645 -5.80953 -3.21886 12.9353 -4.86404 -2.7303 12.9759 -3.98377 -3.45267 13.586 -3.53664 -4.37612 13.1485 -3.49285 -5.28905 13.5067 -3.67933 -6.23187 13.8516 -3.79571 -7.13376 13.8381 -3.21335 -7.15953 13.6287 -4.18224 -7.89613 12.937 -4.33486 -8.87307 12.8448 -4.03485 -9.42333 12.7019 -4.83786 -9.30377 13.4994 -5.37256 -8.89822 13.3183 -6.30852 -8.26248 12.5276 -6.33688 -8.13985 12.7249 -5.35914 -7.20556 12.6925 -5.17868 -7.13576 11.593 -5.35668 -7.89255 11.6854 -4.67125 -7.97725 10.6975 -4.7808 -7.142 10.4684 -5.17582 -6.87516 10.5224 -6.10974 -6.81148 11.0464 -6.93643 -7.61276 11.7095 -7.06559 -7.6901 12.5885 -7.46278 -8.67873 12.2614 -7.66253 -9.49822 11.7825 -8.07718 -10.2592 12.2743 -8.37254 -11.2219 12.1791 -8.66147 -11.7049 11.5481 -9.23476 -12.276 10.85 -8.74365 -12.6937 10.2944 -9.43569 -11.9795 9.85845 -8.90769 -11.9077 9.55307 -9.8265 -10.9528 9.34678 -9.95759 -10.6987 9.41949 -10.9508 -9.84665 8.94284 -11.1483 -10.0574 9.55472 -11.9687 -9.35352 9.15466 -12.6435 -9.12864 8.82105 -13.5746 -9.28306 7.93822 -14.0808 -9.62439 7.00355 -13.7333 -10.292 7.27349 -14.4851 -9.85793 7.89216 -15.1232 -10.329 8.63096 -14.5616 -10.0366 9.54631 -14.317 -10.4768 9.90531 -13.4914 -11.2591 9.89226 -14.1183 -11.8132 9.6196 -13.2881 -11.5972 9.90145 -12.3769 -11.7815 10.7979 -12.711 -12.5626 11.1972 -13.2481 -12.8306 11.7822 -14.0052 -13.2561 10.843 -14.0273 -13.5055 11.0308 -14.958 -14.3194 10.6129 -15.3833 -13.8495 9.7615 -15.7448 -14.1158 10.1805 -16.6216 -14.7959 10.1257 -17.4176 -14.8012 9.17531 -17.0639 -15.1326 8.53956 -17.747 -14.9228 8.37836 -18.6951 -15.6765 8.77807 -19.1501 -15.2824 8.48899 -19.9861 -15.0038 9.40901 -20.2368 -14.5581 10.2349 -19.8392 -14.0731 11.062 -20.1652 -14.6966 11.1689 -20.9457 -13.8602 11.1454 -21.4195 -13.0127 11.3871 -21.9701 -12.3823 10.5443 -21.9469 -12.3287 9.90327 -22.7989 -12.9239 9.2563 -22.3523 -13.3691 9.36651 -23.2069 -14.1372 9.72629 -23.635 -15.0818 9.75429 -23.9467 -15.5432 9.40424 -23.0432 -16.1805 10.0659 -23.4634 -15.5481 10.8409 -23.3386 -15.3105 11.4134 -22.5788 -14.6277 11.9621 -22.1016 -14.6555 12.6288 -21.4249 -14.1885 13.518 -21.4853 -14.9268 13.8302 -20.9623 -15.5952 13.6941 -21.7113 -16.537 13.5729 -21.2263 -17.4456 13.4289 -20.7472 -17.4656 13.0834 -19.7515 -17.8618 13.9658 -19.7626 -17.743 14.8154 -20.1835 -17.954 15.7575 -20.0869 -18 16.082 -19.1772 -17.7964 16.9037 -18.6093 -17.7745 15.9803 -18.1877 -18.7561 15.7271 -18.3125 -19.7448 15.7344 -18.1692 -19.9358 14.994 -17.5599 -20.9115 14.861 -17.1964 -21.5982 14.1626 -17.0159 -21.7724 14.4989 -16.1179 -20.8412 14.5778 -15.7465 -20.4037 14.0713 -15.0434 -19.7733 14.5847 -15.7143 -20.2559 15.282 -16.1746 -20.5928 16.1851 -15.8508 -20.8559 16.6464 -16.8048 -20.8791 17.6508 -16.8689 -20.6958 18.2873 -17.5535 -20.5498 19.253 -17.6452 -19.7238 19.1999 -17.0191 -19.9331 19.1118 -16.0757 -19.8204 18.8982 -15.0849 -20.5062 18.6013 -14.4279 -21.5158 18.7857 -14.3431 -22.5219 18.6561 -14.3218 -22.9488 19.2829 -14.9953 -23.2302 20.2122 -15.4731 -23.7914 20.9023 -15.0822 -23.3591 21.5617 -14.4484 -22.8973 22.3975 -14.2705 -23.5967 22.004 -13.562 -23.4004 21.2423 -12.799 -22.769 20.9976 -12.0442 -22.6701 21.9257 -11.6787 -21.7569 22.0562 -11.3033 -22.2655 21.5979 -10.535 -22.369 22.5455 -10.1995 -21.5841 22.9618 -10.6889 -20.7981 22.4484 -10.4746 -20.3027 23.1357 -10.8419 -19.7519 23.1391 -10.0342 -20.612 23.1583 -9.58291 -20.2175 24.0101 -9.43085 -20.2787 24.7998 -8.94509 -20.6073 24.2397 -8.15532 -21.4702 24.7333 -8.06386 -22.1756 24.9759 -8.71907 -21.8178 25.9353 -8.75049 -22.3193 26.0166 -9.59677 -22.9444 25.2495 -9.46195 -23.0538 24.3077 -9.14437 -23.8502 23.803 -9.57359 -23.696 23.184 -8.79464 -22.946 22.5783 -8.93662 -22.6491 23.292 -8.39858 -22.4648 22.4932 -7.77161 -21.8304 22.1676 -7.16658 -22.276 21.2853 -6.95947 -22.6235 20.3964 -7.23688 -23.3242 19.9424 -6.64295 -23.8699 20.338 -7.33899 -24.8027 20.7814 -7.36785 -24.9781 20.9471 -6.35732 -24.416 21.3694 -5.62496 -25.3987 21.6157 -5.54971 -25.8548 22.4725 -5.25978 -25.1286 23.1553 -5.40724 -24.6996 23.4074 -6.30385 -24.1562 22.4813 -6.1663 -23.2913 22.6598 -6.58992 -23.21 22.1388 -5.78817 -22.9921 21.2991 -5.43969 -22.2032 20.7501 -5.36224 -21.4574 20.1406 -5.45169 -21.1786 21.0795 -5.73788 -20.9405 21.7418 -6.4652 -21.068 22.6182 -5.94466 -20.1234 22.3724 -5.73073 -19.381 22.123 -5.11288 -19.9965 21.3222 -5.29888 -19.7421 20.4514 -4.79087 -19.9191 19.7332 -4.11338 -18.911 19.6077 -3.88518 -18.6401 18.9671 -3.14416 -18.1281 18.1546 -2.99925 -17.2295 18.2984 -2.53715 -16.7525 19.2532 -2.49179 -16.2941 19.0627 -3.297 -15.8953 18.2967 -2.99894 -16.4589 17.9643 -3.88454 -17.1136 17.9903 -4.64744 -17.1219 18.6099 -5.36887 -17.6738 18.155 -6.08574 -16.9992 17.4609 -5.95279 -16.4554 17.0905 -5.17637 -15.5085 17.2708 -4.89742 -14.9733 16.7163 -5.60319 -14.179 17.3433 -5.52225 -13.9429 17.7403 -6.41906 -12.9797 17.5731 -6.13392 -12.3666 16.8942 -5.77685 -13.0554 16.3908 -5.26561 -12.4498 15.7294 -4.93922 -12.0411 16.3966 -4.21479 -11.0788 16.5176 -4.37169 -10.2914 16.8355 -3.79687 -10.1673 15.8038 -3.93616 -9.48957 15.3116 -4.34089 -9.23057 15.1582 -5.304 -9.70455 15.8831 -5.88603 -10.3118 15.1386 -6.15733 -9.74376 15.0314 -6.93332 -10.2339 15.8846 -6.85161 -9.42195 16.2896 -7.28168 -8.63444 16.0614 -7.85781 -8.36452 16.2222 -8.8114 -7.77551 16.8749 -8.40368 -6.79846 16.8037 -8.51123 -6.28079 17.6483 -8.42342 -5.91717 17.6472 -9.28894 -6.06678 18.2888 -10.0932 -6.6934 17.5772 -10.1842 -6.5743 17.0296 -11.0173 -6.22678 16.787 -11.9009 -5.19728 16.7875 -12.0919 -5.36403 16.2946 -12.9334 -5.95754 16.9881 -13.3701 -5.49456 17.5406 -12.6673 -5.84699 17.9914 -11.9142 -5.34813 18.3366 -11.1485 -4.40866 18.0427 -11.0844 -4.08886 18.1415 -12.0057 -3.58175 17.6674 -12.6223 -2.90584 17.0179 -12.3099 -2.70557 16.769 -11.3034 -2.23802 16.3041 -10.4741 -1.51773 16.6794 -9.97199 -0.761393 16.8625 -9.32005 -0.973168 17.8302 -9.25566 -0.02883217 17.8566 -8.73519 --0.233384 17.1524 -9.35682 --0.172867 16.2548 -9.62586 -0.340279 15.4837 -9.56239 -0.420925 15.189 -10.5088 -0.961298 15.8156 -11.1186 -0.70567 16.2333 -12.003 --0.08087933 15.6049 -12.2131 --0.04362113 15.7212 -13.2078 -0.905549 16.1802 -13.114 -1.77358 16.6768 -12.8404 -2.28061 16.6287 -13.7019 -1.81825 16.8399 -14.5908 -1.51865 17.3741 -13.8154 -0.521004 17.28 -13.6584 -0.456488 17.2116 -14.7161 -0.6284 17.988 -15.3116 --0.211574 18.4599 -15.4866 --0.968453 18.9841 -15.9116 --1.38388 18.048 -15.8354 --0.958659 18.0597 -16.7205 --0.942313 17.746 -17.6661 --0.818411 18.4675 -18.3569 --1.26246 17.7833 -18.7744 --0.394805 17.5386 -19.1721 -0.03533937 17.9239 -19.9201 -0.842764 18.526 -19.8644 -1.06417 17.6955 -20.3779 -1.25141 17.0985 -19.5543 -1.7251 16.8107 -20.4308 -2.37753 16.1867 -20.0914 -2.19223 15.4233 -19.5509 -2.55846 14.7271 -20.2489 -2.47185 13.9677 -20.8837 -2.45302 13.0526 -20.4848 -1.63452 12.4796 -20.09 -0.912101 11.8438 -20.4551 -1.50464 11.372 -21.1289 -0.934108 11.8689 -21.838 -0.196969 11.2393 -21.5279 --0.59868 11.7255 -21.7391 --1.22433 11.0538 -21.3272 --1.16585 10.7423 -20.3661 --0.967901 11.289 -19.5769 --1.82073 10.7145 -19.6206 --2.58568 10.0773 -19.5056 --2.89102 10.3011 -18.5423 --1.90169 10.4518 -18.2319 --1.02413 10.0571 -18.0216 --1.31302 9.14345 -17.571 --1.49496 8.95185 -18.5275 --2.27893 8.34608 -18.451 --2.03947 7.96612 -19.3583 --2.6306 8.62907 -19.936 --3.08149 7.88937 -20.4611 --2.06369 7.93715 -20.4711 --1.65711 7.22861 -19.9055 --1.99639 6.45304 -19.304 --2.45315 6.40952 -20.189 --2.76481 5.65712 -19.523 --2.83221 4.69706 -19.4962 --2.20596 3.89064 -19.5177 --1.43266 3.57919 -18.9379 --1.71534 3.38103 -18.0615 --1.91568 2.41652 -17.9787 --1.20713 2.25879 -17.3296 --1.40112 1.29451 -17.1931 --1.03241 1.30665 -16.2167 --1.17593 1.74616 -15.4731 --0.612505 2.24634 -14.8292 --0.254104 2.11985 -15.7551 -0.05736987 2.90517 -15.3844 -0.792961 3.59404 -15.3861 -0.442382 4.48415 -15.1791 -0.974746 4.94572 -14.4711 -1.97116 5.1202 -14.4163 -2.92118 4.97633 -14.024 -2.84624 5.41885 -13.1621 -3.67848 5.99561 -13.1608 -4.25016 6.66083 -12.6643 -5.21316 6.35302 -12.6055 -5.44033 6.03741 -13.5288 -5.35038 7.00095 -13.3322 -5.69806 7.78506 -12.8659 -5.97692 7.52173 -13.7225 -5.2282 8.10084 -13.9772 -4.22828 8.11713 -13.8854 -3.33431 8.01708 -13.4487 -2.99727 8.81706 -13.0311 -2.9266 9.40964 -13.7906 -2.12549 9.87909 -13.9045 -2.8046 10.2286 -13.3074 -3.31211 11.1454 -13.3782 -2.46894 11.6072 -13.156 -2.81746 12.5875 -12.9371 -3.45826 13.3775 -12.9887 -3.9002 12.5398 -13.3686 -3.56699 13.1643 -14.0151 -2.88092 12.8758 -14.6788 -3.08413 13.828 -14.6631 -2.59761 14.7007 -14.5059 -1.73472 14.8722 -14.0383 -2.00396 14.5622 -13.1451 -1.96664 13.7157 -13.6894 -1.76622 13.4637 -14.6086 -1.62327 14.3159 -15.0566 -0.732392 14.4526 -15.4359 -0.004660115 14.5101 -14.7126 -0.444011 15.3971 -14.5879 -0.01321817 15.4053 -15.4867 -0.549694 15.3386 -16.3381 -0.544683 14.8332 -17.2451 -1.0609 14.0618 -17.5362 -1.57956 13.173 -17.3005 -2.2521 13.3756 -16.482 -3.02798 12.7386 -16.265 -3.38567 12.6326 -17.1681 -4.12342 13.1906 -17.6051 -4.77539 12.8028 -18.2956 -4.89204 11.8461 -18.0228 -5.32339 11.1588 -18.5543 -5.18761 10.21 -18.9692 -5.82757 9.69084 -18.4305 -6.53218 10.2884 -18.6922 -6.96236 10.4813 -19.5614 -7.85951 10.674 -19.1448 -8.18617 11.4142 -18.6033 -7.24692 11.672 -18.8874 -7.32284 12.098 -19.7961 -6.3957 11.8581 -19.4337 -6.51541 12.82 -19.5093 -6.62493 13.7067 -19.0691 -6.11742 14.4056 -18.4406 -7.03871 14.4523 -18.0518 -7.51012 15.0344 -18.7772 -8.10708 15.7985 -18.5641 -7.98327 16.8238 -18.5036 -8.36296 16.5885 -19.3903 -8.01879 15.7696 -19.8366 -8.34193 15.3715 -20.6903 -9.06002 15.158 -21.4621 -10.0347 15.0605 -21.0782 -10.556 15.7905 -21.6021 -10.825 16.3212 -22.431 -11.7216 16.5915 -22.1015 -12.749 16.439 -21.9355 -13.5673 16.9191 -21.8055 -13.8462 17.0355 -20.8388 -13.5742 16.9637 -19.892 -12.8004 16.3867 -19.6042 -12.3466 15.5713 -19.2022 -12.5299 14.892 -19.9512 -13.2334 14.2452 -20.1818 -12.3842 13.8603 -20.5728 -11.4019 13.8238 -20.2394 -10.4812 13.8997 -19.7647 -10.3881 13.285 -18.9965 -10.9686 13.7391 -18.2831 -11.4887 13.0831 -18.8479 -12.4333 13.2963 -19.298 -12.4426 12.2735 -19.4855 -12.661 11.9126 -18.5725 -13.6113 11.9057 -18.8292 -14.2106 12.6911 -18.7507 -15.0519 12.1344 -18.7003 -15.7633 11.4541 -19.0207 -16.6493 11.1218 -19.1609 -17.3272 10.6835 -18.652 -17.3069 11.3992 -17.9004 -18.07 11.0095 -17.4068 -18.6808 11.7077 -17.3228 -18.6509 11.6807 -18.288 -18.3268 12.301 -19.0327 -17.7372 12.9866 -18.5743 -17.6208 12.3962 -17.7564 -16.996 11.9708 -17.1767 -17.6592 12.5926 -16.7475 -17.4626 12.0487 -15.9064 -17.3416 12.1755 -14.9304 -17.1767 13.1352 -14.5617 -16.4707 13.79 -14.5421 -16.8232 14.0457 -15.4673 -15.8682 13.7124 -15.555 -14.8914 13.7902 -15.85 -14.5954 14.1187 -16.8147 -15.305 14.6992 -16.4667 -14.4245 15.1954 -16.7272 -13.7875 15.5379 -15.9676 -12.9247 15.2304 -15.583 -12.3214 14.4928 -15.3838 -11.9968 14.1873 -16.2517 -12.7734 14.5196 -16.889 -12.6424 14.7588 -17.9234 -13.3964 15.0718 -17.4273 -13.945 15.0808 -18.2537 -14.5408 15.8646 -18.0856 -14.7092 15.5435 -18.9553 -15.4235 14.788 -18.9769 -16.0269 14.9202 -18.1924 -16.603 15.7166 -18.0505 -16.0783 16.6091 -17.9933 -15.6946 16.3597 -18.8668 -16.0256 16.0725 -19.7727 -15.2481 15.8208 -20.3971 -15.4735 16.1095 -21.2819 -15.2932 16.0628 -22.2601 -14.6872 16.5405 -23.0281 -14.5608 16.9628 -22.0462 -14.7339 17.9322 -22.2321 -13.9897 17.5989 -22.8664 -14.3816 17.5976 -23.7966 -15.3266 17.2802 -24.1049 -15.5446 16.2838 -24.3605 -16.1473 15.5392 -24.2308 -16.1795 15.8444 -23.2927 -17.1041 15.8413 -23.7098 -17.6784 16.5656 -23.2833 -17.9373 16.8533 -24.1401 -17.6429 17.6204 -24.7688 -16.9837 18.379 -24.9374 -17.6188 19.124 -25.0565 -18.15 19.4885 -25.8757 -17.8443 20.4366 -26.0593 -17.2649 20.9116 -26.6013 -16.6511 21.4618 -26.0514 -15.929 21.3044 -26.7225 -15.8248 22.1094 -26.1036 -15.3981 22.8733 -25.6317 -14.8321 22.182 -25.1629 -13.938 21.6828 -25.3953 -13.988 22.7252 -25.1901 -14.3041 22.9067 -24.2529 -13.5641 23.5446 -24.4516 -12.7064 23.0437 -24.4801 -12.4529 22.3782 -23.8387 -13.1888 21.8015 -24.1976 -12.6478 20.91 -24.2235 -12.6812 20.7215 -23.2548 -13.3273 20.9805 -22.5565 -13.5475 21.5888 -21.7326 -13.6231 20.687 -21.2046 -13.8844 20.0687 -20.5241 -14.2802 19.6969 -19.6714 -13.7328 19.1519 -18.9657 -13.7561 19.9801 -18.3075 -13.4732 20.1244 -19.2821 -12.6437 20.5001 -18.8632 -12.5161 20.4218 -19.8797 -11.7032 20.9481 -19.532 -10.8704 20.7421 -20.1724 -10.3795 20.0189 -20.0862 -10.8248 19.3661 -20.7747 -10.2347 18.6236 -20.3958 -9.40331 19.1192 -20.0863 -8.86563 19.9411 -20.1877 -8.88172 20.9413 -20.0059 -8.243 20.7562 -20.7465 -7.80643 19.8947 -20.5364 -8.23923 19.6364 -21.3819 -7.63805 18.965 -21.7959 -6.74786 18.9814 -21.4169 -6.41662 18.3899 -20.6693 -6.51645 17.5792 -21.2613 -5.94471 17.9433 -22.0252 -5.16815 17.4057 -22.4118 -4.93338 18.34 -22.8558 -5.59107 18.0366 -23.5864 -5.86867 17.0949 -23.8161 -5.49602 16.0959 -23.7815 -5.26456 15.6643 -22.8535 -4.79915 14.8121 -22.5953 -5.27807 15.3534 -21.93 -4.40891 15.7993 -22.0083 -4.27318 16.6612 -21.4284 -4.66208 16.0353 -20.755 -4.42349 15.6484 -19.8641 -5.03338 16.4016 -19.5376 -6.02724 16.0894 -19.2337 -6.09101 16.1327 -18.1992 -5.30528 16.0391 -17.5515 -5.32935 17.0038 -17.3556 -4.63675 17.7571 -17.1575 -3.76892 18.0335 -16.8583 -3.15662 17.4396 -16.2846 -2.9789 18.3341 -15.9575 -2.67547 18.7117 -16.9172 -3.00993 19.4997 -17.4155 -3.36451 20.4338 -16.9807 -3.62534 19.9611 -16.1279 -3.32957 20.6776 -15.564 -2.46079 21.1814 -15.7458 -2.03209 21.8759 -15.2188 -1.19695 21.8521 -14.7405 -0.560817 22.6699 -14.6862 -0.141169 23.2965 -15.3698 --0.188256 23.1787 -16.3455 -0.321665 23.5044 -17.1856 -0.746045 22.8207 -17.7158 -1.37788 22.1531 -17.3185 -1.84372 22.9842 -17.5454 -1.41344 23.3493 -16.6785 -1.55518 24.279 -16.3573 -1.42858 25.267 -16.5702 -1.44294 26.0978 -17.237 -0.573064 26.2886 -17.6566 -0.845541 25.9984 -18.4845 -0.654064 25.3078 -19.1028 -1.45756 25.4473 -19.6458 -1.84778 25.1991 -20.5169 -1.31549 24.293 -20.4925 -1.05049 23.4424 -20.038 -1.11965 23.4432 -19.0565 -0.206875 23.6857 -19.2664 --0.117766 24.4688 -19.7528 -0.05391727 25.0433 -20.4533 -0.01051257 24.5009 -21.3282 -0.571741 24.052 -21.9511 -1.53598 23.7635 -21.7367 -2.07681 23.7206 -22.5303 -2.42179 24.3425 -21.7963 -3.15967 23.9499 -21.2528 -3.76844 24.6376 -21.1725 -3.7064 25.0586 -20.2422 -3.85409 24.3941 -19.5048 -3.35314 23.6726 -19.9116 -2.87535 23.0967 -19.3109 -2.88062 22.0568 -19.1195 -3.67154 21.4955 -18.9368 -3.85968 21.706 -17.9899 -4.39 21.1729 -17.3281 -4.96026 20.3988 -17.6645 -5.494 19.7067 -17.1843 -5.76797 19.5865 -16.2124 -5.74006 18.8732 -15.5281 -5.054 18.2471 -15.1964 -5.7822 17.6227 -14.8907 -5.75198 17.8421 -13.9106 -5.39144 18.7358 -14.2006 -6.36382 19.0353 -14.0573 -5.64944 19.3795 -13.314 -6.22823 20.19 -13.4245 -6.73083 19.9162 -12.6005 -7.60979 19.7189 -12.9514 -7.88391 19.6625 -13.9516 -8.67744 20.3104 -13.7641 -8.72791 20.6557 -12.7844 -8.50114 21.0281 -11.8806 -7.9337 21.6515 -12.4461 -7.62764 22.5956 -12.1695 -6.74827 22.8687 -11.8329 -5.95212 23.4219 -11.7011 -6.67881 23.5156 -10.9349 -6.31494 23.0528 -10.1513 -5.53346 22.4241 -10.3884 -5.95613 21.862 -11.1008 -6.20965 21.6789 -12.0923 -6.65079 20.8476 -12.0588 -5.91666 20.6274 -11.4625 -5.26504 19.8216 -11.6441 -6.05097 19.3485 -12.1024 -6.83877 19.4783 -11.6079 -7.27441 18.9547 -10.8408 -6.89683 19.3561 -10.0877 -6.6556 20.2104 -10.5022 -5.90707 20.6628 -10.1306 -5.05625 20.7103 -9.72859 -5.31458 21.2766 -8.989 -4.66263 21.7812 -8.37282 -4.29321 20.8903 -8.69909 -3.46265 20.8539 -9.21665 -3.82882 19.9178 -9.39539 -4.08005 19.6659 -8.41598 -3.80246 18.7081 -8.74407 -3.88045 17.9479 -8.12136 -3.02581 18.2361 -7.63753 -3.14647 18.8868 -6.93194 -2.81188 19.6523 -7.53805 -1.79044 19.648 -7.54608 -1.37778 19.3149 -6.61703 -0.645455 19.2482 -7.26146 -0.592304 18.3995 -6.70043 -0.854256 18.7019 -5.83052 -0.891404 19.582 -5.42877 -1.09445 19.275 -4.5172 -1.50475 18.3719 -4.57627 -2.43207 18.7247 -4.4122 -2.71322 18.7888 -3.43824 -3.48124 18.2611 -3.95785 -2.9846 17.3948 -4.00337 -3.76583 16.804 -3.93487 -3.11237 16.1893 -3.45807 -2.13074 15.8949 -3.56521 -1.45509 15.2889 -3.27213 -1.58443 14.6107 -2.59288 -1.64869 14.8945 -1.61646 -0.951772 14.9845 -0.9528339 -1.32684 14.5565 -0.1561989 -1.62 13.6193 -0.3938899 -0.885968 12.921 -0.5149289 -1.25424 12.8348 0.3993221 -2.0439 12.3479 0.6504781 -2.21936 11.5269 0.09785092 -1.95808 10.5743 0.1906271 -1.7186 10.315 1.08706 -1.51795 9.35307 1.05931 -2.39794 9.34214 0.6322751 -3.18354 8.86587 1.04072 -4.02408 9.4348 1.07107 -4.90962 9.64208 1.55812 -4.80599 8.62645 1.65367 -4.15586 8.18657 2.27471 -4.10224 8.88304 2.97862 -3.39709 8.67072 3.69152 -2.50577 9.14585 3.43546 -2.1876 9.92792 2.84121 -2.81439 9.18167 2.41076 -2.33258 8.4889 2.01763 -1.69747 8.34599 2.76778 -0.654539 8.46318 2.60746 -0.08442597 7.67008 2.54188 --0.227728 7.14933 3.31389 --0.541569 6.31935 3.93167 -0.416 6.26939 4.03986 -1.08259 5.60174 4.35318 -0.951942 5.36666 3.4305 -1.53626 6.2032 3.31161 -1.667 7.0132 3.81567 -2.02707 7.5055 4.69835 -2.75021 8.056 4.8876 -2.802 9.02442 5.21735 -3.5701 9.4379 4.74466 -4.18961 9.29888 5.52626 -4.83387 9.85994 5.05007 -5.64085 10.4217 5.18971 -5.19528 10.9718 4.43747 -4.90551 10.9152 3.50258 -5.69702 10.2579 3.54314 -6.44433 10.8849 3.685 -6.81287 11.0511 4.56707 -7.77852 10.8081 4.79225 -7.95603 11.8021 4.79527 -8.63548 12.5386 4.76803 -8.57869 13.5564 4.71707 -7.65176 13.3643 4.3845 -7.93413 14.0158 3.57062 -7.19441 14.4023 3.10346 -6.91556 13.5009 2.78306 -6.5433 12.6028 2.99007 -5.75716 13.1909 2.9096 -5.0779 13.2893 2.09452 -4.6954 13.0921 3.04926 -4.7947 12.0972 3.16911 -5.74664 11.775 3.06696 -5.95922 11.3733 2.15595 -6.83792 10.8578 2.27601 -6.70782 10.1205 1.67241 -6.31252 9.27526 1.84543 -7.18423 8.98251 1.4777 -7.55446 8.29033 2.12255 -7.77537 7.57983 1.46305 -7.17956 7.5128 0.6328791 -6.24662 7.28719 0.2719401 -6.14074 6.47248 0.8404831 -5.3651 6.18267 0.3060021 -5.01046 6.92152 -0.3671499 -5.1457 7.81006 -0.8302409 -5.24953 7.64809 -1.79081 -4.79249 8.33963 -2.34034 -3.85427 8.18553 -2.14539 -4.13528 7.47473 -2.8255 -3.71816 6.67595 -3.1251 -3.44601 5.70117 -2.98438 -2.55118 6.02472 -2.93002 -2.16022 5.1266 -2.79723 -1.65473 4.31079 -2.99984 -0.952298 4.32211 -3.73708 -1.10694 3.43323 -3.35926 -0.919148 2.79079 -2.59664 -0.895758 1.79117 -2.45024 -1.55103 1.18479 -3.00102 -1.65527 2.08711 -3.48559 -1.86686 1.35166 -4.15246 -2.24996 0.4738339 -4.44401 -3.2099 0.4263879 -4.17739 -3.09158 0.6416359 -3.19053 -3.31057 1.42957 -3.69772 -4.27825 1.57069 -3.72168 -4.76124 1.10039 -2.94261 -5.68533 0.9280469 -3.19355 -5.51754 0.6143369 -2.15868 -4.94709 -0.1457431 -2.48033 -5.34326 -0.9856951 -2.37171 -5.88698 -0.3265351 -2.92082 -6.88688 -0.2646671 -3.12843 -6.84909 0.1637029 -2.26793 -7.48089 0.8234289 -2.63858 -8.01754 0.7140899 -1.84588 -8.07627 -0.2286211 -2.14237 -8.99982 0.04032343 -2.28034 -9.5303 -0.2184261 -3.11048 -8.84763 0.1277359 -3.80683 -7.8689 -0.1145761 -3.68075 -7.46557 0.3639299 -4.45536 -7.23782 1.00016 -5.22196 -7.20684 1.27098 -6.2458 -6.9153 2.24178 -6.0273 -6.15095 2.66566 -5.5281 -5.76981 1.85894 -5.85545 -5.53723 0.9454399 -5.49545 -5.89675 0.04483163 -5.25886 -5.2333 -0.09671177 -4.57217 -4.30388 -0.4705511 -4.40377 -4.38709 -1.00874 -5.21655 -4.51831 -0.5036551 -6.09942 -5.30486 -0.4877161 -6.6872 -6.13156 -0.2428091 -7.2215 -5.49906 -0.1429751 -7.96717 -4.8696 0.4305229 -8.2777 -4.82552 0.7992859 -9.14691 -4.92249 -0.09510617 -9.50695 -4.89369 -0.8720761 -8.85379 -5.34385 -1.4783 -9.5634 -4.8405 -1.17661 -10.3149 -4.88758 -2.15072 -10.5509 -5.8648 -2.35001 -10.5337 -5.88182 -3.12438 -10.0125 -6.61139 -3.07611 -10.6508 -6.8454 -3.94101 -10.1227 -7.7558 -3.77513 -9.69397 -8.68906 -3.9265 -9.50442 -8.73871 -4.45992 -10.4687 -8.79941 -3.60591 -10.9406 -8.10118 -3.83364 -11.6566 -7.71312 -2.97105 -11.2388 -7.26159 -2.07927 -11.4036 -6.97517 -1.61405 -10.5243 -7.88715 -1.97336 -10.3375 -8.32617 -2.89637 -10.2076 -7.43229 -2.7135 -9.72086 -7.29808 -3.08778 -8.76196 -7.82312 -2.29773 -8.57598 -7.00171 -1.85823 -8.44054 -7.26798 -1.81398 -7.47943 -7.5278 -2.74765 -7.15185 -8.52128 -2.76249 -7.17276 -8.93552 -3.48196 -6.64374 -9.07628 -4.45721 -6.66617 -9.54629 -4.91922 -7.41455 -10.1863 -4.92676 -8.1541 -9.65072 -5.07367 -8.93539 -10.0946 -4.93796 -9.81764 -10.852 -5.10831 -10.3887 -11.3168 -5.143 -9.54204 -11.6904 -4.96743 -8.63611 -11.9692 -5.20455 -7.69742 -12.2347 -4.98208 -6.75712 -11.7726 -4.17082 -7.12492 -11.7852 -4.04263 -8.09618 -11.3421 -3.26238 -8.57889 -11.5526 -2.49991 -7.9305 -10.6303 -2.05097 -7.94726 -9.71913 -1.69367 -8.11673 -9.08142 -1.11233 -7.61325 -8.56168 -1.68283 -6.97608 -7.80783 -1.09361 -6.76068 -8.54019 -0.5741641 -6.24067 -7.88821 -0.5239801 -5.5626 -8.43972 -1.37309 -5.32304 -8.41697 -2.40025 -5.46315 -7.79576 -2.66886 -4.67859 -8.37409 -3.44011 -4.32953 -8.67375 -3.05074 -3.46673 -8.75561 -2.22406 -2.91737 -7.99409 -1.63134 -2.70518 -8.29951 -1.33204 -1.77029 -9.10623 -1.87153 -1.45014 -8.66137 -1.99203 -0.5798359 -7.8042 -1.98493 -0.00531491 -7.58623 -1.10391 0.2153101 -6.71213 -0.9626921 0.6542721 -5.85165 -0.7189571 0.3044311 -5.55481 0.2336329 0.4656441 -5.19511 -0.002183446 -0.4153459 -4.29749 -0.005612676 -0.6659069 -4.49923 0.8848189 -0.2600919 -4.05102 1.11193 0.6023751 -3.54759 1.91897 0.7410661 -3.24482 1.90805 -0.2178339 -3.28843 1.16174 -0.9239759 -2.673 1.06579 -1.75853 -2.27938 0.3460909 -2.4053 -1.54216 0.08139473 -2.94996 -0.759619 0.2813749 -3.41022 -0.349188 1.16093 -3.29073 --0.197341 1.9922 -2.9163 --0.03381033 2.24399 -3.90572 -0.337535 3.01872 -4.46583 -0.774967 2.1179 -4.67321 -1.53706 2.63071 -5.11117 -1.83829 2.75522 -6.00504 -2.10855 1.76024 -6.13832 -3.01693 1.25743 -5.92352 -3.49698 2.07965 -5.61811 -3.96316 2.8592 -5.93829 -3.18467 2.58456 -6.60121 -2.58953 2.99027 -7.35475 -1.75606 3.3361 -7.72921 -2.31022 3.88336 -8.36488 -3.23011 3.6719 -8.42759 -3.47343 4.03569 -9.30507 -4.31799 4.26483 -8.76563 -5.30446 4.5102 -8.93585 -4.67806 5.12625 -9.29008 -4.71035 5.98155 -9.77667 -4.38273 6.93262 -10.0245 -5.29211 7.10436 -9.65067 -5.83922 7.90719 -9.67116 -6.43934 7.93731 -8.90773 -6.60915 8.71005 -9.53695 -7.33684 8.24717 -9.08791 -8.0079 8.70544 -9.40513 -8.8842 8.80871 -9.01643 -8.98029 7.83926 -9.20302 -8.7551 7.49946 -10.081 -8.00299 7.08156 -10.486 -7.28733 6.54179 -10.5819 -7.90416 5.72518 -10.7006 -7.47038 5.19312 -9.89793 -6.89924 5.37595 -10.7135 -6.20234 5.8157 -10.1612 -5.80241 4.8765 -10.2193 -4.88319 4.44226 -10.2773 -4.84625 5.05851 -11.0642 -3.95532 4.86805 -11.4507 -3.81276 4.17551 -10.8602 -4.17622 3.734 -11.6713 -3.17798 3.73189 -11.4819 -2.42231 4.14459 -10.8982 -1.90006 3.32859 -11.0177 -1.94188 3.36516 -10.0579 -1.13746 3.555 -9.55343 -0.656733 4.42048 -9.59994 -0.619125 5.31447 -9.98426 --0.287836 5.6256 -10.0207 --0.609718 6.40964 -10.4354 --0.584707 6.8216 -11.4066 -0.231641 6.97244 -11.9542 -0.328976 6.0063 -11.6648 --0.187154 5.12829 -11.6506 -0.338835 4.49639 -12.1384 -0.09657407 4.00266 -12.9278 -0.06612577 4.96236 -13.1562 --0.03349733 5.9666 -13.4004 -0.757068 6.32397 -13.8734 -0.99379 6.08001 -14.7789 -1.30503 5.28701 -15.2819 -0.86111 5.47528 -16.2655 -1.61666 6.11645 -15.8828 -0.811005 6.73492 -15.7847 -0.434271 7.69167 -15.6162 -0.658912 8.28428 -16.3708 -0.855978 9.03863 -15.7719 -1.61618 8.47162 -15.415 -2.13222 8.67324 -16.2198 -1.95677 8.01604 -17.0086 -1.41899 7.21073 -17.3346 -1.023 6.32948 -16.9838 -0.06145117 6.49555 -17.2024 --0.700607 6.10275 -17.7159 --1.05736 6.89338 -17.1548 --0.78377 7.16637 -16.2177 --1.74816 7.48778 -15.9623 --1.35439 8.02833 -15.1803 --1.23836 7.26591 -14.5295 --0.649503 6.52445 -14.8793 --0.1694 6.93929 -14.1362 -0.179076 7.81295 -14.4356 -0.188028 8.26269 -13.5308 -0.958948 8.71342 -13.0438 -1.85462 8.73557 -12.4983 -2.37915 9.06051 -11.7336 -2.5249 8.11289 -11.6623 -1.90927 7.5715 -11.0405 -0.932609 7.50928 -11.0003 -1.35102 7.10127 -10.1336 -2.35135 7.03283 -9.76803 -2.99695 6.96305 -9.07578 -2.93644 6.853 -8.10957 -2.74649 5.95463 -7.80327 -1.9903 6.59412 -7.42124 -1.7039 7.51101 -6.96787 -2.42169 8.093 -7.45374 -1.55061 8.56567 -7.7118 -0.779266 9.24653 -7.38535 -1.6028 9.88465 -7.38316 -1.89392 10.816 -7.10994 -1.02605 11.198 -7.33277 -1.45378 12.0139 -6.85985 -2.30769 12.4457 -7.11159 -2.0894 12.372 -8.13102 -2.54897 11.4674 -8.07754 -3.35926 10.9968 -8.45709 -3.58128 10.4314 -7.64082 -3.45768 9.73684 -8.38663 -4.38521 9.46595 -8.74776 -3.98568 9.40789 -9.69891 -4.28468 8.49673 -10.0534 -3.42832 8.68964 -10.5774 -3.9304 8.76364 -11.5382 -4.88788 8.78093 -11.2201 -5.2239 9.73519 -11.4177 -6.17893 9.43923 -11.5537 -6.00255 9.5609 -10.5418 -6.58128 10.3877 -10.6615 -6.05828 10.8839 -9.96707 -5.14855 10.705 -9.62396 -4.97676 10.5826 -10.5597 -4.47212 10.7957 -11.4218 -3.87246 11.4344 -11.8945 -4.17115 11.9543 -12.7019 -4.55945 11.0248 -12.9768 -5.43075 10.5605 -13.0526 -5.99136 10.8518 -12.3176 -6.58355 10.8837 -11.5214 -7.5595 10.6527 -11.3188 -7.23579 9.70395 -11.4157 -7.36942 9.73835 -10.44 -7.74141 9.68374 -9.52468 -7.78561 9.30742 -8.61714 -7.02795 9.90257 -8.42865 -7.5307 10.7497 -8.49515 -8.23009 10.332 -7.94386 -7.92502 10.741 -7.148 -8.8224 11.1928 -7.30666 -8.92981 10.5177 -6.61952 -8.54058 9.57255 -6.57997 -8.3421 9.15019 -5.70305 -7.63769 8.40928 -5.91253 -7.67456 8.87504 -6.81202 -8.48926 8.60449 -7.25146 -9.09994 9.36603 -7.37517 -9.80505 10.0311 -7.63928 -9.77764 10.4678 -8.55063 -9.83152 9.65675 -9.10794 -10.1016 10.2551 -9.80868 -10.5853 10.9422 -10.3831 -10.0013 10.6862 -11.1743 -10.047 11.5299 -11.5862 -9.09935 11.8939 -11.3745 -8.60599 12.1065 -12.246 -8.74817 11.1658 -12.6504 -9.55737 10.6668 -13.0164 -9.52769 11.2361 -13.8118 -10.3679 11.7337 -14.104 -10.9107 12.362 -13.666 -10.1379 12.7225 -14.1924 -11.0001 12.9842 -14.6521 -10.802 13.3479 -15.593 -10.3177 13.6335 -16.4352 -10.3075 13.2701 -17.3918 -9.30577 13.1588 -17.1409 -8.62053 13.8057 -17.6621 -7.89195 13.955 -17.0089 -7.5903 13.8624 -16.0474 -7.97996 14.7862 -15.8238 -7.46762 15.5407 -15.2879 -6.93009 16.3091 -15.5972 -7.24752 17.2725 -15.8193 -7.84535 18.114 -15.744 -8.81832 17.934 -16.0691 -9.75112 17.6432 -16.3895 -10.3798 16.8611 -16.1703 -10.7649 17.0096 -15.213 -11.2693 17.4792 -14.4558 -10.5392 17.9263 -14.8395 -9.77967 17.3908 -14.4724 -10.0343 16.8941 -13.6641 -10.9257 16.4499 -13.4883 -11.7741 15.881 -13.4694 -11.469 15.1648 -12.9408 -11.2022 14.3444 -13.3204 -11.9981 13.9564 -12.8762 -11.5684 13.7386 -11.9888 -10.7882 13.2865 -11.5902 -10.1997 13.575 -10.7992 -10.0661 14.3244 -11.3931 -9.22491 14.8776 -11.3663 -8.54596 14.9183 -10.6332 -8.60233 15.9071 -10.5789 -8.9268 16.8174 -10.9441 -8.07397 17.3834 -10.9989 -7.99375 17.4729 -12.0146 -7.99724 17.1942 -12.9784 -8.14918 16.3219 -13.4437 -7.84671 17.1141 -14.0508 -8.5959 16.8183 -14.6394 -8.64823 16.0972 -15.4077 -9.48286 15.575 -15.3852 -9.73747 14.7597 -14.7705 -9.25295 15.2857 -13.9637 -9.30261 14.9735 -13.0593 -8.57223 14.4008 -12.7355 -8.52941 13.3995 -12.9339 -8.07124 12.64 -13.3493 -7.54558 12.6824 -12.5528 -6.96393 13.169 -13.2407 -5.96161 12.9301 -13.3957 -5.12407 12.5838 -13.9002 -5.29018 12.517 -14.8868 -5.28793 11.6615 -15.0939 -4.24418 11.583 -14.9953 -3.51386 12.1287 -15.4354 -2.68599 11.5756 -15.2638 -2.77677 10.5592 -15.4833 -1.84928 10.4778 -14.9573 -1.2908 11.2879 -15.3071 -0.828311 10.5328 -15.727 -1.04976 10.0612 -16.5972 -1.28438 9.71185 -17.5674 -1.47065 10.7409 -17.4607 -2.15159 11.2842 -17.0167 -1.58909 12.097 -17.3 -1.07041 12.5946 -17.9757 -1.40124 12.2118 -18.7818 -1.51308 13.031 -19.3027 -0.548325 13.4575 -19.0612 -0.498589 13.4181 -20.0585 --0.08546563 13.0443 -20.8336 -0.90592 13.1584 -21.0872 -1.5457 13.9773 -21.2396 -2.053 13.6163 -22.0314 -2.94469 13.4048 -21.7845 -3.82507 13.5391 -21.4391 -4.6675 13.5757 -20.8088 -5.28976 13.6518 -19.9632 -4.37448 13.8287 -19.7599 -3.47705 13.6734 -19.4767 -3.53866 14.0334 -18.5955 -3.58654 14.6422 -17.7203 -4.34194 15.2529 -17.9563 -4.35289 15.2352 -16.9354 -4.03234 16.1352 -17.222 -4.01188 16.4518 -18.1778 -4.29335 17.3315 -18.6057 -3.85425 17.9268 -19.2735 -3.05045 18.4873 -19.2307 -2.77106 19.4118 -19.582 -2.94538 20.3354 -19.5031 -3.95129 20.3243 -19.5906 -4.58481 21.0101 -19.4539 -4.94679 20.8551 -20.3946 -4.50496 21.0365 -21.3168 -4.2565 20.6759 -22.3048 -4.01741 20.718 -23.2785 -4.76423 20.0858 -23.1 -5.43954 19.7351 -22.3863 -5.92696 20.1675 -23.1338 -5.99117 20.7837 -23.8625 -6.20596 21.5713 -23.2681 -6.5446 21.5381 -22.3289 -6.56435 22.5253 -22.0956 -6.26677 23.4417 -22.1202 -5.31612 23.4815 -22.4739 -4.69017 23.0301 -21.8752 -4.51015 22.5944 -22.7515 -4.60147 23.4507 -23.2148 -4.13097 24.0866 -23.794 -4.16381 25.0505 -23.5322 -4.91348 25.5412 -23.0056 -5.76132 25.4173 -23.4109 -6.6229 25.0838 -23.7543 -7.41578 24.5992 -23.524 -7.82011 23.714 -23.8135 -8.7246 23.3728 -23.9528 -8.59831 23.4553 -24.9985 -8.64676 22.5837 -25.5633 -8.35887 21.8693 -26.2537 -8.87107 22.0803 -27.1551 -9.09536 22.9523 -27.5108 -9.9562 23.4596 -27.2591 -9.83956 23.2209 -26.2944 -10.1607 23.0167 -25.2719 -9.88422 22.0372 -25.0978 -10.8574 21.666 -25.2671 -10.6573 20.7534 -24.916 -10.057 20.1339 -24.6049 -9.46292 19.3335 -24.3423 -9.30309 18.4422 -23.9435 -8.35456 18.5114 -23.5836 -8.20621 17.5116 -23.5926 -7.20986 17.3147 -23.512 -7.43438 16.7089 -22.725 -7.31946 16.0691 -23.4464 -7.89939 15.6615 -22.7273 -7.0066 15.458 -22.2372 -6.37657 14.9095 -22.8809 -7.23451 14.4226 -23.263 -6.37172 13.8994 -23.4023 -6.0981 13.0289 -23.1061 -5.71534 12.0548 -22.9809 -5.92871 11.4389 -22.2783 -5.82385 10.6797 -22.9282 -6.71269 10.5322 -22.5071 -7.70384 10.6801 -22.44 -7.89709 11.5951 -22.1002 -8.48712 12.4175 -22.0246 -9.24817 11.7249 -22.0379 -10.0897 11.5717 -22.4013 -10.8423 11.6425 -23.1309 -11.2173 12.2767 -22.5043 -11.0994 13.2326 -22.0771 -11.9754 13.5017 -21.8751 -12.3051 13.6429 -22.7634 -12.5247 13.668 -23.7787 -11.6207 13.3073 -23.8187 -11.992 13.6182 -24.6634 -12.7494 12.9374 -24.7602 -12.9194 13.0428 -25.7368 -13.4257 13.3713 -26.5496 -12.9321 13.9306 -27.2467 -13.723 14.2891 -27.8044 -14.6737 14.0669 -27.8233 -15.6031 14.3946 -27.6344 -15.2624 15.2568 -27.2553 -14.4436 15.7318 -26.9165 -13.8363 16.5131 -26.9391 -13.547 15.8052 -27.5502 -12.7789 16.3432 -27.8024 -12.266 16.632 -28.5855 -12.1587 17.3011 -27.8774 -13.0983 17.4977 -27.4851 -12.2995 17.4476 -26.8099 -11.7723 18.3075 -26.5215 -12.0036 19.1842 -26.0636 -11.152 19.6419 -25.6712 -10.4282 19.0769 -25.1688 -10.5257 18.2333 -24.6129 -10.719 17.6382 -23.7745 -10.0268 17.0332 -23.4161 -9.75422 16.2915 -24.0969 -10.1127 15.4789 -24.639 -10.2261 16.4171 -25.0867 -10.507 16.5046 -26.0434 -9.49607 16.7618 -26.095 -8.60391 16.7897 -25.6216 -8.39089 17.6024 -26.2816 -8.11573 17.7143 -27.255 -8.46906 17.0114 -27.8981 -8.61437 16.0536 -27.65 -8.87218 15.3196 -27.0138 -9.56094 14.6607 -27.3862 -9.12087 14.6414 -28.3038 -9.83778 15.2996 -28.4904 -8.89309 15.5258 -28.8489 -8.6687 14.9618 -29.7077 -7.84604 14.771 -30.2475 -8.48955 15.1097 -30.8893 -9.41758 14.7286 -30.7101 -8.85631 13.9234 -30.5271 -8.73094 13.5797 -31.4498 -9.08208 14.3495 -32.0321 -8.15684 14.7099 -32.1699 -7.33218 15.2801 -32.2498 -6.86531 16.0683 -32.59 -6.25186 15.4094 -32.1771 -6.19694 14.8124 -31.3885 -5.26713 14.9274 -31.357 -5.49612 14.042 -31.6144 -5.73309 13.5221 -30.8426 -4.77544 13.6122 -30.7904 -5.00053 12.6801 -31.1506 -5.58499 12.0327 -30.6133 -5.56724 12.8178 -30.0181 -6.26415 12.5016 -29.3831 -6.56597 11.6372 -29.0648 -7.06728 10.7659 -28.8874 -7.35521 10.0485 -28.2537 -7.75104 10.8911 -27.9957 -8.11352 11.2205 -27.0836 -8.38116 11.8367 -26.2419 -8.30772 11.2839 -25.432 -7.9699 11.8281 -24.6862 -7.62832 12.5694 -25.3033 -8.28467 13.3328 -25.3644 -8.9469 12.832 -24.7957 -8.53599 13.6648 -24.4811 -7.89569 14.4741 -24.4268 -7.00245 14.287 -24.836 -7.38435 15.1218 -25.1861 -7.94476 14.9936 -26.0176 -7.46389 14.6645 -26.8922 -6.61165 14.7375 -26.438 -5.61521 14.9305 -26.3091 -5.43048 14.7961 -25.3318 -4.74577 14.5239 -24.6567 -4.28644 14.6483 -23.7066 -4.4439 15.5932 -23.8665 -3.57722 15.2685 -24.2972 -2.95063 16.0257 -24.044 -1.96792 15.5847 -24.0343 -2.27712 15.7473 -23.0651 -2.4841 14.9922 -22.4372 -1.70225 15.1233 -21.875 -1.07691 15.0535 -21.0192 -0.09644807 15.3096 -21.0794 --0.733231 15.6413 -21.4898 --0.720415 15.1305 -22.3868 --1.13715 14.3067 -22.5707 --1.82767 13.5649 -22.6914 --1.33674 12.8586 -22.0684 --1.41134 12.2838 -21.2633 --2.1093 13.0274 -21.2717 --2.81425 12.257 -21.3232 --2.21706 11.5358 -20.9728 --2.86553 10.7144 -20.7569 --2.57811 9.89991 -21.2527 --2.02811 9.16619 -21.6167 --1.57861 8.52641 -22.2349 --1.39725 7.62037 -22.0322 --1.66046 7.22913 -22.8057 --1.26139 6.43844 -22.2386 --0.562543 6.37902 -21.5833 -0.202175 5.73179 -21.4508 -0.596481 5.84785 -22.3437 -0.253638 4.93769 -22.3335 --0.322354 4.74537 -23.1366 --0.668785 5.59046 -23.5397 --0.864057 5.85892 -24.4913 --0.847647 6.79761 -24.1304 --0.02430513 7.2697 -24.4141 -0.321397 7.22273 -25.3252 -0.274638 8.14565 -25.1189 -0.498555 9.15905 -25.0549 -0.06200237 8.88748 -24.1675 --0.119745 9.42912 -23.3893 -0.586874 9.95161 -22.9754 -1.44577 9.47078 -23.2085 -1.73965 8.62523 -23.6555 -1.266 8.20547 -24.4473 -1.45464 8.12637 -25.4299 -2.37393 8.01676 -24.9298 -2.93928 8.14052 -25.8021 -3.39689 9.01908 -25.5389 -4.41748 9.32078 -25.4499 -4.1681 10.0953 -25.8541 -3.98808 9.907 -26.8871 -4.96716 9.80165 -26.6031 -5.5036 10.3868 -25.9266 -5.91669 9.94512 -25.1816 -6.3735 9.25208 -24.6557 -5.69326 8.56234 -24.9 -4.72339 8.16983 -25.1234 -4.68593 8.8911 -24.4501 -3.85962 8.91633 -23.8216 -4.06727 8.28685 -23.0469 -4.16359 7.81281 -22.1381 -3.69914 7.08742 -21.5805 -2.94419 7.81493 -21.5168 -3.24435 8.74416 -21.9039 -2.6651 9.4043 -21.4385 -3.38777 10.0708 -21.5655 -2.9469 10.1818 -22.49 -3.17354 11.1537 -22.7959 -2.6618 11.6558 -22.1693 -2.40057 12.5706 -22.4076 -2.36448 12.6183 -23.4222 -3.14115 12.7003 -24.1049 -2.547 13.0741 -24.8587 -2.22456 13.217 -25.8025 -2.9689 13.8823 -25.6261 -2.77274 13.8094 -26.5774 -2.27817 13.4654 -27.3234 -1.77934 14.2602 -27.5964 -1.23405 14.8133 -26.9392 -0.496968 14.4879 -26.4377 --0.363298 14.5724 -26.9386 --0.512952 14.2118 -25.9421 --0.464064 13.3102 -26.26 --0.275882 13.205 -27.2543 --0.474141 13.3016 -28.1787 --0.666924 12.4098 -28.6512 --0.251921 12.0203 -29.4561 -0.457849 12.3226 -30.017 -1.1033 12.9191 -29.4608 -1.47471 13.2516 -28.5365 -1.07146 12.3524 -28.3201 -0.862399 11.5738 -27.7316 -1.57227 11.1073 -28.1445 -1.38506 10.1181 -28.5049 -0.456869 10.3102 -28.8431 --0.180783 10.4964 -29.5699 --1.04975 10.8413 -29.8611 --1.20452 9.89283 -29.628 --0.610685 9.34939 -28.9545 --1.2939 8.60294 -29.0802 --1.58257 7.62711 -29.3108 --2.11389 6.80211 -29.298 --1.73863 6.40596 -28.5621 --1.08752 6.49498 -27.7211 --0.638398 6.99597 -28.4876 -0.139514 7.00357 -27.8758 --0.182316 6.98504 -26.9746 --0.504715 7.37143 -26.1426 --1.54012 7.38314 -26.1947 --1.27205 6.60897 -25.6089 --1.96689 5.92514 -25.8999 --2.92518 5.9955 -26.2474 --2.51807 5.15759 -26.7189 --1.69496 4.92089 -26.237 --0.75054 5.20475 -26.1479 --0.04206013 5.79252 -26.5827 -0.486676 5.34271 -27.3562 -0.457965 4.55144 -26.7366 -1.26019 4.32844 -26.1072 -1.5751 5.21144 -25.7236 -2.33333 4.59717 -25.6174 -3.08038 4.17469 -25.0865 -2.60192 3.26019 -25.1243 -1.80879 3.87596 -24.8281 -2.28052 4.14247 -23.9347 -1.44241 3.63445 -23.6134 -1.70121 2.97154 -24.2892 -1.57373 1.98864 -24.5021 -1.49176 1.32533 -23.7612 -1.87967 2.04174 -23.172 -1.10915 2.58719 -23.4601 -0.660191 2.48196 -24.2808 -0.260046 2.06013 -25.0487 -0.681871 1.19137 -24.8379 -0.690071 0.2308509 -24.6167 --0.295743 0.06971143 -24.7824 --1.02188 -0.5675341 -24.854 --1.89648 -0.3650211 -24.3588 --1.45275 -0.1866831 -23.4678 --2.32084 0.07638903 -23.0907 --3.04749 0.6637529 -23.4406 --2.83756 0.8626429 -24.3293 --2.52692 0.4994849 -25.1703 --2.11826 1.2465 -25.84 --2.66226 1.32804 -26.7376 --1.62177 1.50977 -26.8275 --2.06532 1.87099 -27.5785 --2.65389 2.62856 -27.9507 --3.17346 3.31774 -27.4493 --2.70659 3.30593 -26.6187 --1.75585 3.68524 -26.5196 --1.48473 3.89647 -27.4023 --1.50865 3.54234 -28.3315 --0.83841 4.2299 -28.1574 --0.195271 3.52685 -28.333 --0.347874 3.3257 -27.3521 -0.03752477 2.46241 -26.9985 --0.355533 2.89389 -26.1709 --0.541212 1.96064 -25.8916 --0.627705 1.06694 -26.297 -0.336015 1.00327 -26.1882 -0.483003 0.09598443 -26.6128 -0.953445 -0.3320401 -25.8554 -0.880512 -1.30013 -25.9608 -1.69026 -1.84558 -26.386 -2.1436 -1.3634 -27.1329 -2.58451 -0.4721361 -27.1932 -1.94559 0.2900209 -27.4331 -2.11676 0.2778369 -26.4582 -2.17265 1.10497 -25.8207 -2.41515 1.29299 -24.7918 -3.26399 1.63506 -25.2027 -4.04534 1.32381 -24.5676 -4.50759 1.75062 -25.3541 -5.45263 2.13623 -25.2163 -5.02143 1.77245 -24.4146 -4.54651 2.32093 -23.7683 -3.64779 2.27721 -23.2838 -3.30195 1.29669 -23.3682 -2.88554 1.62947 -22.5125 -2.39212 2.14777 -21.9007 -3.23506 1.79184 -21.5294 -3.96825 2.23368 -21.8808 -4.6935 2.77618 -21.4558 -3.85267 3.29046 -21.7327 -3.62423 4.11607 -21.181 -4.10069 4.48167 -21.8825 -4.02574 5.44243 -22.0872 -5.02479 5.4745 -21.8984 -5.06615 5.56161 -22.8633 -5.50404 5.72501 -23.7668 -5.19181 5.93726 -24.7095 -4.85967 6.73875 -25.2497 -5.44458 6.93111 -26.0508 -4.78267 7.50633 -26.5919 -5.39195 7.70489 -27.3971 -6.30512 8.07784 -27.4475 -6.41118 7.81229 -26.42 -7.42512 7.70375 -26.4825 -7.51997 7.00883 -27.1491 -6.50293 6.93954 -27.2773 -5.53186 6.67179 -27.3194 -4.61153 6.20233 -27.4077 -3.70473 6.46937 -27.4582 -3.61698 7.32764 -28.0168 -2.64637 7.34907 -28.0805 -3.15201 7.4357 -28.9259 -2.56851 8.11354 -29.2642 -2.74158 8.22069 -30.2226 -2.96909 9.12645 -30.6927 -2.12471 9.22052 -30.282 -2.6632 10.075 -30.4533 -1.75169 10.1768 -30.7839 -1.54752 10.3676 -31.7986 -1.41242 11.3029 -32.177 -1.26459 11.8236 -32.9821 -0.34625 11.3633 -33.2473 -0.79724 11.0696 -34.032 -1.16116 11.4593 -34.9463 -1.17338 10.495 -35.139 -1.15969 9.65741 -35.7826 -2.08266 9.23938 -35.9002 -1.39078 8.54525 -35.7083 -0.727717 8.12311 -36.4127 -1.03108 7.51203 -35.6294 -1.30356 7.68455 -34.6568 -0.526146 7.0338 -34.7225 --0.106267 7.01043 -35.5228 --1.01403 6.65131 -35.6196 --1.87125 6.05959 -35.2991 --2.75286 5.89026 -35.7365 --2.57152 5.10837 -36.325 --2.95822 5.73858 -36.9589 --2.70093 4.70501 -37.1881 --2.50787 3.90194 -37.6649 --1.73026 3.29898 -37.6995 --1.48602 2.3891 -37.4237 --1.11411 2.03336 -38.2725 --1.53538 1.33428 -37.678 --0.758705 0.7834149 -37.8693 --0.883573 -0.1796411 -37.6088 --0.822324 -0.9170261 -36.9048 --0.974774 -1.21884 -35.9834 --1.60022 -0.4586911 -35.8389 --2.15423 -0.01821237 -35.1277 --2.12328 0.6581569 -34.3711 --3.16219 0.4695209 -34.1581 --2.90418 0.7912099 -33.2611 --3.12009 0.9217569 -32.2637 --3.09079 0.3767469 -31.3868 --3.40773 -0.5882951 -31.3802 --3.93796 -1.17872 -30.8289 --4.27653 -2.09142 -31.105 --3.46767 -2.3701 -31.6403 --2.5374 -1.99335 -31.9047 --2.69282 -1.17938 -32.5982 --2.06036 -0.5040521 -32.1974 --2.25199 -0.9130841 -31.3756 --1.95468 -0.9117171 -30.4306 --1.25861 -0.8059151 -29.6381 --0.884026 -0.1383871 -30.1998 --0.829636 0.8717129 -30.3735 --0.683854 1.55241 -29.711 --0.89942 2.42393 -29.3075 --0.660548 3.18659 -30.0011 --1.03523 3.74571 -30.8375 --1.81472 4.47271 -30.8498 --2.43476 3.69744 -31.0359 --3.33622 3.99324 -31.195 --2.99377 4.06997 -30.1796 --3.2984 5.00024 -30.2549 --3.12683 5.50868 -31.0984 --3.94652 6.10862 -30.9631 --4.57055 6.29754 -31.645 --4.24199 6.47066 -32.6092 --3.81558 5.91432 -33.3063 --3.36321 5.1061 -33.608 --2.46619 4.69947 -33.4626 --2.41413 4.58468 -34.4666 --1.93465 4.30442 -35.3095 --0.98336 4.15961 -34.9843 --0.06264113 4.40953 -34.6059 -0.604476 5.07033 -34.1369 -1.17856 4.64837 -33.4499 -1.35327 5.16973 -32.6481 -1.27782 4.57482 -31.8517 -1.68134 3.72528 -32.282 -2.50222 3.98682 -32.8362 -3.15798 3.22812 -32.8886 -3.85244 2.5266 -32.7983 -4.70164 2.68842 -33.0493 -5.61528 2.14801 -32.8711 -5.13755 1.60358 -33.6062 -4.84087 0.6499299 -33.7255 -3.86525 0.8590189 -33.5494 -3.78329 0.1748419 -32.9641 -3.47829 -0.5544681 -32.3202 -2.4846 -0.6331381 -32.3642 -2.47783 0.2608479 -32.0498 -3.21521 -0.01617147 -31.4217 -2.64331 -0.8255491 -31.0781 -3.26743 -0.6183491 -30.3185 -3.28219 -1.54696 -29.8601 -3.39081 -2.21722 -30.6384 -2.81375 -2.88647 -31.1132 -2.97762 -3.80137 -31.4792 -2.9151 -4.29679 -30.5622 -3.51634 -5.05018 -30.1898 -4.09451 -5.73684 -30.6425 -4.59109 -5.31731 -31.3582 -5.12317 -4.78977 -32.0186 -5.85032 -4.17073 -32.4552 -6.44168 -3.66102 -31.7853 -7.06181 -3.99714 -31.0713 -7.36353 -4.62473 -30.4018 -6.48066 -4.50012 -29.8791 -5.80303 -3.87234 -30.3481 -5.02893 -3.29468 -30.0103 -4.20107 -2.81206 -30.3194 -4.45602 -1.86615 -30.5768 -5.31821 -1.77449 -30.0135 -6.01144 -2.00241 -29.4308 -6.89167 -1.84161 -28.9878 -6.51989 -2.72947 -28.6871 -5.46667 -2.85478 -28.7089 -4.45556 -2.90291 -28.984 -3.85481 -2.99724 -28.2643 -3.66499 -3.86054 -27.8495 -2.82595 -4.34658 -27.6786 -2.4863 -3.93625 -26.7791 -2.21836 -3.22864 -26.1083 -1.40158 -3.06909 -25.6212 -0.903 -3.73141 -25.1079 -1.22634 -4.60132 -24.8272 -0.653023 -5.44234 -24.6618 --0.160986 -4.8231 -24.7918 --0.269395 -5.6949 -25.3363 -0.05704117 -6.58186 -25.4477 --0.159136 -6.49993 -24.4095 --0.857729 -6.10781 -23.8237 --1.15283 -5.23618 -23.3877 --0.780518 -5.38756 -22.4579 --1.70578 -5.38417 -22.2105 --1.9488 -4.50747 -22.5537 --2.91028 -4.63027 -22.5912 --3.01728 -4.88446 -21.6688 --2.75684 -5.3687 -20.8015 --2.54435 -5.81506 -21.6175 --1.89145 -6.5447 -21.591 --2.08829 -6.66567 -20.5803 --1.81574 -5.79628 -20.0219 --1.82102 -5.42378 -19.0604 --1.2689 -5.60858 -18.1634 --0.770561 -6.02679 -18.8785 --0.289029 -5.60646 -19.6353 -0.514337 -4.90788 -19.4129 -0.37276 -5.39792 -18.5328 -0.66816 -6.10188 -19.1778 -0.272598 -6.73431 -19.8238 --0.719039 -6.76961 -19.6878 --0.897399 -7.4579 -18.9959 --1.00272 -7.59598 -18.0128 --1.27954 -6.95171 -17.3999 --2.20022 -7.0167 -17.3897 --3.05787 -7.07177 -16.8432 --4.04502 -7.00159 -17.1699 --4.26571 -7.04744 -18.1258 --4.96733 -7.17055 -18.8142 --5.20161 -6.17335 -18.8211 --5.55296 -5.57061 -18.1452 --6.4346 -5.43705 -17.7595 --7.2455 -5.06905 -17.1775 --8.25983 -5.21312 -17.1249 --9.03118 -5.88105 -17.3461 --9.92562 -6.2324 -17.1682 --9.35198 -6.40303 -16.2836 --8.74679 -7.15155 -16.075 --7.94706 -7.15133 -15.5283 --6.96755 -7.36058 -15.4116 --6.58298 -6.44889 -15.5987 --6.76711 -6.66821 -14.6172 --7.60109 -6.641 -14.0067 --8.17761 -7.08727 -13.3328 --9.17093 -7.3539 -13.2646 --8.78032 -7.68504 -12.4857 --8.7577 -8.02221 -11.5458 --8.4713 -8.85108 -11.0294 --7.67461 -8.32841 -11.0302 --6.81236 -8.10652 -10.606 --6.25315 -7.34857 -10.2678 --5.99834 -6.97755 -11.136 --5.1091 -6.70698 -10.6663 --4.74698 -5.88905 -10.2017 --5.7435 -5.98781 -10.024 --5.2765 -6.44102 -9.26599 --5.7007 -6.49176 -8.38853 --6.42151 -5.83784 -8.39353 --5.98722 -5.82112 -7.52585 --5.87863 -6.65511 -7.06368 --6.86685 -6.76417 -7.33194 --6.26816 -7.50572 -7.00415 --7.18796 -7.74251 -6.57548 --7.73215 -8.60509 -6.53565 --8.01664 -9.53586 -6.81602 --7.53957 -9.88271 -7.62568 --6.68011 -9.82035 -7.14076 --6.82024 -9.29116 -6.25729 --7.03435 -9.7054 -5.36304 --6.82091 -10.2635 -4.52672 --6.64088 -11.1311 -4.18535 --6.48321 -11.7165 -4.87833 --7.41785 -11.6747 -5.31418 --7.83566 -11.0405 -5.98547 --8.80846 -11.4019 -5.9946 --9.27926 -11.4143 -6.84121 --9.62977 -11.2751 -7.76069 --10.0557 -11.6439 -8.56332 --10.5801 -11.2016 -9.29201 --9.8284 -10.4166 -9.53113 --9.68215 -10.8775 -10.4249 --10.0812 -11.7485 -10.7798 --10.9014 -12.124 -11.2353 --11.587 -11.459 -11.5422 --11.8842 -10.994 -12.3906 --11.2234 -11.5369 -12.9297 --10.4373 -12.0629 -13.4255 --10.568 -12.9252 -13.8908 --11.5093 -13.127 -13.8456 --12.5063 -13.1643 -14.1682 --12.7425 -12.6147 -13.4057 --11.9775 -12.7554 -12.7791 --12.5311 -11.9711 -12.5864 --12.9103 -11.2719 -11.9766 --13.5135 -11.1742 -11.1505 --12.7162 -11.3206 -10.5567 --12.3401 -12.1035 -10.1921 --11.8114 -12.5997 -9.52676 --11.413 -12.3667 -8.58639 --10.846 -12.2792 -9.42792 --10.8093 -13.2543 -9.12467 --10.0139 -13.3819 -9.71126 --9.38352 -13.0974 -8.95445 --8.43542 -13.0917 -8.98679 --8.46285 -12.1279 -8.95405 --9.03255 -12.0588 -8.1056 --8.38626 -11.9371 -7.25147 --8.95539 -12.7368 -7.20993 --9.12075 -13.3201 -7.98069 --9.60325 -13.4696 -7.16509 --9.55828 -14.4638 -7.09961 --8.84383 -15.1757 -6.8234 --8.96632 -16.136 -7.13759 --8.7145 -16.9587 -6.55084 --8.91511 -17.6258 -7.22367 --9.81447 -17.7911 -6.95577 --9.25484 -17.907 -6.17398 --10.014 -17.3553 -5.85668 --9.4338 -17.7684 -5.15659 --8.78124 -17.1607 -5.65917 --8.22721 -17.7454 -6.22189 --8.57182 -18.4332 -6.80508 --9.28467 -19.053 -6.56481 --8.60331 -19.5335 -7.04452 --7.9093 -20.2129 -6.76357 --7.41839 -19.3071 -6.57949 --7.17009 -18.7285 -5.8927 --6.35607 -18.9743 -5.38562 --6.54576 -19.7957 -4.79303 --7.25113 -20.3894 -4.47644 --7.52097 -19.5505 -4.16821 --6.7404 -19.4954 -3.44653 --5.92366 -20.136 -3.57317 --5.3195 -20.91 -3.80607 --4.77062 -20.9206 -4.55894 --3.88546 -21.1958 -4.86825 --4.32866 -20.6791 -5.66162 --4.48118 -19.7284 -5.5693 --4.60414 -19.4479 -4.56017 --5.28613 -18.7705 -4.16727 --5.38213 -19.0076 -3.15887 --5.0608 -18.7655 -2.2717 --4.75738 -18.066 -1.74256 --3.7727 -17.9464 -1.76098 --4.20641 -17.5291 -2.58044 --3.68721 -16.8005 -3.0234 --4.59659 -16.7904 -3.46188 --4.84089 -15.9837 -2.92204 --5.18732 -15.3723 -2.15002 --6.05217 -15.747 -2.14288 --6.84913 -16.2142 -1.69765 --7.02667 -15.4538 -2.31797 --7.63639 -15.1428 -2.98328 --7.35454 -16.029 -3.31322 --7.37949 -16.0976 -4.31404 --6.58075 -16.5676 -4.12009 --6.09184 -16.0045 -3.61716 --5.37915 -15.9687 -4.24186 --5.84387 -15.1287 -4.26464 --5.18177 -14.8722 -3.59869 --4.74039 -15.1568 -4.48305 --5.21582 -14.2601 -4.4001 --4.76843 -13.4053 -4.61087 --4.34539 -13.8743 -5.40542 --3.90371 -13.3536 -6.03698 --4.91741 -13.2406 -5.95675 --5.10467 -12.2751 -5.87934 --4.88368 -11.3748 -5.44635 --5.64655 -11.3383 -6.00722 --5.72654 -11.0168 -6.96623 --5.71261 -11.6248 -7.86676 --6.32923 -12.0919 -7.3103 --7.29097 -11.9572 -7.37802 --7.13488 -11.086 -7.81401 --6.56625 -10.319 -8.0394 --5.88362 -9.54781 -8.00801 --5.63742 -8.58983 -8.22042 --5.74823 -7.59259 -8.41535 --6.55913 -7.06421 -8.59 --6.82301 -7.97743 -8.85324 --6.60737 -8.88128 -9.2544 --7.38345 -9.39825 -9.4135 --7.94946 -10.1666 -9.88361 --7.39643 -10.867 -10.3702 --6.51568 -10.7891 -9.99249 --6.75633 -10.8229 -8.95899 --7.46417 -11.5089 -9.06017 --7.65487 -12.1342 -9.73089 --6.94194 -12.8154 -9.70476 --6.14181 -12.2851 -9.91887 --6.20778 -12.0358 -10.9246 --6.16299 -12.9827 -10.6618 --5.53175 -13.5799 -11.028 --4.88386 -14.4258 -11.0248 --5.45858 -14.4985 -11.8896 --5.91925 -15.3015 -12.2293 --5.22182 -15.9048 -12.5808 --5.34547 -16.6911 -13.236 --4.71358 -17.3129 -13.6918 --4.95197 -18.1281 -13.179 --5.61604 -18.7952 -12.9668 --6.29673 -18.3386 -12.5142 --6.95482 -18.9292 -12.2277 --7.30913 -19.7129 -12.7011 --8.05621 -20.1316 -13.2502 --8.65554 -19.3908 -13.421 --9.01887 -18.9328 -14.2019 --8.74727 -18.4263 -15.0468 --8.58135 -18.9197 -15.909 --7.64116 -18.6417 -16.0561 --7.39036 -17.6663 -16.1674 --7.03864 -16.7151 -16.0973 --7.64144 -16.6223 -15.2877 --6.96477 -16.54 -14.5494 --6.3318 -16.0761 -15.105 --5.71842 -15.4184 -15.56 --5.37442 -15.4341 -16.5456 --4.49626 -15.0227 -16.8982 --3.46307 -14.7782 -16.8057 --3.19329 -15.5299 -17.4027 --3.87594 -15.8643 -17.9897 --3.50012 -16.4888 -18.5835 --2.48163 -16.4498 -18.6951 --2.11284 -16.8789 -17.8485 --1.94189 -17.8685 -17.8858 --1.30994 -18.4443 -18.3398 --1.71892 -19.3166 -18.5465 --1.39523 -20.0478 -19.2904 --1.18377 -19.8349 -20.1737 --0.31773 -20.3309 -20.1356 --0.583887 -21.2562 -20.2585 --1.25095 -21.4576 -20.9912 --1.77466 -21.5487 -21.8716 --1.91482 -22.5126 -21.5652 --1.79049 -23.257 -20.8517 --1.15124 -22.6483 -20.4854 --1.96429 -22.4031 -19.8928 --1.17326 -22.0502 -19.424 --1.83103 -21.3803 -19.1909 --1.03728 -21.3587 -18.5792 --0.166861 -20.8752 -18.563 --0.37446 -20.6957 -17.5446 --1.18211 -20.2873 -17.1243 --1.10125 -19.8708 -16.1766 --1.6059 -19.6853 -15.3401 --1.92277 -19.1123 -14.5568 --1.92933 -18.8979 -13.5844 --2.01678 -17.9042 -13.3904 --2.83454 -18.389 -13.1796 --3.55845 -17.8541 -12.8531 --2.79447 -17.248 -13.0343 --2.91023 -16.2922 -12.828 --2.1594 -15.8966 -13.3527 --2.22603 -16.0631 -14.3293 --3.08597 -16.5142 -14.2251 --3.44511 -17.031 -14.9733 --3.27496 -17.9839 -15.4448 --2.78556 -18.0459 -14.5659 --1.84024 -18.0564 -14.9223 --1.37365 -17.3116 -15.3626 --1.52989 -16.7351 -16.2129 --1.06767 -17.5605 -16.616 --0.527187 -17.3444 -15.8241 --0.001998175 -16.5652 -15.488 -0.465988 -15.9455 -14.7871 -1.25102 -16.494 -15.075 -1.91999 -15.7924 -15.2334 -1.40966 -14.9108 -15.3083 -0.951005 -14.7266 -16.157 -1.19088 -15.6636 -16.5074 -1.74868 -14.8809 -16.7763 -2.07758 -15.3538 -17.6859 -2.62625 -14.6043 -18.0217 -2.98917 -14.8692 -18.9472 -3.31091 -15.5133 -19.697 -2.84453 -16.4013 -19.4922 -2.37459 -16.9138 -18.7919 -1.99256 -17.8758 -18.8293 -1.82265 -18.6755 -18.1602 -2.11543 -19.3264 -17.4844 -1.47852 -20.0955 -17.6318 -0.479087 -20.1434 -17.5933 -0.373331 -19.872 -16.6465 -0.756075 -19.8733 -15.7395 -1.48508 -19.3769 -16.1264 -2.47173 -19.0874 -16.3563 -3.20385 -18.5488 -15.9049 -3.35352 -18.3777 -14.9527 -4.10918 -17.7602 -14.6406 -5.1423 -17.5223 -14.4372 -5.9756 -17.7318 -14.9127 -5.71317 -18.1121 -15.7833 -5.23635 -17.2022 -15.6973 -4.41117 -17.6366 -16.0588 -4.50462 -18.5182 -16.6133 -3.73008 -18.3708 -17.1224 -4.21243 -18.2857 -18.0225 -4.58059 -19.0808 -18.5485 -4.10385 -18.5716 -19.253 -4.73184 -18.5737 -20.0558 -3.71626 -18.4188 -20.1508 -3.74715 -18.2395 -21.1181 -4.2229 -17.4542 -21.3906 -4.89473 -16.9971 -21.9136 -4.37399 -17.1372 -22.7552 -4.18208 -16.1531 -22.937 -3.31202 -16.294 -22.3387 -3.10328 -15.7276 -21.5823 -2.24796 -15.8643 -21.0515 -1.36023 -16.2356 -21.2358 -1.51942 -16.953 -21.8156 -0.894081 -17.8198 -21.5428 -1.38981 -18.443 -20.8275 -0.480549 -18.4035 -20.6661 --0.291023 -18.0314 -20.0729 --1.03756 -17.2966 -19.9607 --1.16107 -16.9806 -20.9383 --1.27512 -17.7144 -21.5536 --1.22166 -17.1441 -22.3628 --1.62164 -17.1525 -23.3287 --1.31036 -18.0593 -23.1896 --1.40262 -18.857 -22.591 --1.13995 -19.8142 -22.5239 --1.10531 -20.0062 -21.5197 --2.01263 -20.2981 -21.629 --2.4962 -19.3803 -21.7495 --3.53151 -19.4042 -21.6333 --4.33487 -18.9995 -21.2736 --5.25782 -18.6816 -21.0622 --5.29539 -17.8558 -20.5454 --6.18576 -17.305 -20.5554 --7.02772 -16.9101 -20.2624 --7.43195 -16.8439 -19.334 --7.99779 -16.0781 -18.9241 --8.90816 -16.543 -18.8383 --9.50165 -15.7784 -18.6664 --9.68402 -15.2267 -19.4932 --9.62593 -14.5504 -18.7914 --10.5185 -14.38 -18.3551 --10.9265 -13.5132 -18.2129 --9.98827 -13.3672 -17.8559 --9.02185 -13.3177 -17.9496 --8.77644 -13.7728 -17.1621 --8.02922 -14.3628 -17.0843 --7.25915 -13.9713 -17.6148 --7.34666 -13.0061 -17.8845 --7.18646 -12.3175 -18.5682 --6.30362 -12.3905 -18.0863 --6.26031 -12.6911 -17.1625 --5.96763 -13.4043 -17.8587 --5.11262 -13.3507 -18.2773 --4.41598 -14.0544 -18.5069 --5.10981 -14.6233 -17.9413 --5.47283 -15.5822 -18.2513 --5.76654 -16.542 -18.2694 --6.58185 -16.0525 -17.9552 --7.04224 -16.1026 -17.0989 --7.57988 -15.6697 -17.752 --8.41014 -16.1667 -17.6425 --8.27888 -17.1986 -17.6042 --9.01221 -17.7788 -17.9758 --9.28526 -18.7399 -17.8767 --9.36627 -18.9748 -18.8077 --9.05228 -18.2773 -19.5348 --9.89642 -17.7558 -19.5695 --9.5595 -17.0756 -20.2432 --9.20952 -16.4531 -20.9721 --8.71295 -15.6292 -20.8232 --9.67262 -15.4805 -20.9429 --10.2808 -14.8435 -21.3962 --9.59627 -14.1157 -21.2396 --9.49729 -13.2828 -20.6764 --8.77081 -12.6182 -20.9275 --8.03602 -13.0274 -21.4857 --7.96617 -13.933 -21.9882 --7.11028 -14.3045 -21.5513 --6.71808 -14.9945 -22.2176 --5.82272 -15.391 -22.0201 --5.69831 -15.2443 -22.9725 --5.05669 -14.9385 -23.6846 --4.79051 -15.7448 -23.093 --5.32918 -16.3177 -23.7688 --4.85978 -17.0974 -24.0967 --4.31805 -16.9881 -23.2805 --4.44804 -17.96 -23.5442 --4.88045 -18.7846 -23.9714 --4.55133 -19.6583 -23.8669 --3.81615 -19.8029 -23.2569 --3.84893 -20.6676 -22.9203 --3.30991 -21.0049 -22.1485 --3.41994 -21.1308 -21.1266 --3.45475 -21.0088 -20.112 --3.50698 -21.6974 -19.36 --2.88585 -22.1683 -18.7736 --2.83858 -22.7221 -17.9428 --3.26183 -23.4135 -18.5149 --3.81697 -24.2248 -18.2344 --3.11303 -23.9633 -17.5189 --2.73698 -24.8862 -17.3376 --1.70839 -25.0716 -17.3682 --1.26422 -24.3141 -17.9183 --1.89316 -23.9871 -17.2551 --1.91111 -23.3887 -16.5154 --2.27023 -22.4243 -16.3525 --1.98407 -22.3848 -15.3532 --1.9483 -21.3536 -15.4104 --2.76289 -21.7665 -14.8882 --2.47492 -20.9622 -14.3492 --3.37066 -20.4644 -14.3942 --3.65747 -19.938 -15.1782 --3.49428 -20.8626 -15.5975 --4.40961 -20.4881 -15.814 --4.48187 -21.4466 -15.9984 --5.40005 -21.3629 -16.3978 --6.14535 -21.7239 -15.8194 --6.39709 -22.6343 -16.2714 --6.63819 -23.2948 -15.6572 --6.72762 -24.2581 -15.8514 --7.62197 -24.1376 -15.4495 --7.42866 -24.5026 -14.5656 --7.69757 -25.442 -14.4721 --7.35526 -25.9669 -15.1326 --7.44411 -25.6473 -16.1025 --8.31662 -25.9073 -16.2933 --8.42397 -25.188 -17.0514 --7.55874 -25.3687 -17.5523 --6.77936 -25.8848 -17.7372 --6.83785 -26.5119 -18.542 --6.69998 -27.5215 -18.6313 --5.8416 -27.9807 -18.303 --5.19131 -28.6071 -18.7206 --4.46692 -28.0437 -18.9771 --5.2603 -27.6012 -19.2941 --4.6408 -27.3682 -20.0192 --4.21756 -26.4401 -20.0335 --4.74521 -25.7712 -19.5611 --4.93755 -25.099 -20.3559 --5.67226 -24.4395 -20.5325 --5.10075 -23.7716 -21.07 --6.02524 -23.4204 -21.2635 --6.38476 -22.5491 -20.9765 --6.29635 -22.3031 -19.9583 --6.83717 -22.1193 -19.1468 --7.41536 -21.4663 -18.6909 --7.14356 -20.9402 -19.4576 --6.20877 -20.7511 -19.7504 --5.45739 -20.7093 -19.1132 --4.60196 -20.2546 -19.4183 --4.91505 -19.3085 -19.2299 --5.59638 -19.1121 -18.5424 --6.21022 -18.4915 -18.0275 --5.65175 -17.6657 -18.0286 --5.45 -17.3813 -18.8819 --4.95153 -17.1244 -19.6846 --4.56715 -18.0854 -19.7491 --3.81521 -17.5001 -19.5181 --3.48371 -16.557 -19.5904 --2.52646 -16.3164 -19.8244 --2.78024 -15.3438 -20.0024 --1.99268 -14.7357 -19.775 --2.08163 -13.9206 -20.3811 --2.44668 -13.0491 -20.7612 --3.34904 -12.6396 -20.9325 --4.30265 -12.4518 -20.983 --4.44466 -11.7526 -20.2891 --4.90454 -11.0723 -19.713 --4.10909 -10.5215 -19.5993 --3.45822 -10.2479 -18.9088 --4.14851 -10.1545 -18.2028 --3.51174 -10.0192 -17.4358 --2.91964 -10.4058 -16.7487 --2.96628 -11.3527 -16.6183 --2.6278 -11.9476 -15.9037 --2.56235 -12.8289 -15.6282 --2.83054 -13.7289 -16.1225 --3.72549 -13.831 -15.5473 --4.30459 -13.8137 -14.7657 --4.86854 -14.3123 -14.1642 --5.76548 -14.8244 -14.0735 --6.1973 -15.6776 -14.045 --6.74584 -16.0216 -13.2243 --7.4979 -16.492 -12.7999 --7.47598 -16.0919 -11.8699 --7.0749 -15.1447 -11.7626 --6.86287 -15.2672 -10.8053 --6.02598 -14.9851 -11.1065 --5.87957 -15.9189 -10.6827 --6.04377 -16.6821 -10.025 --5.43878 -17.4583 -9.97095 --4.44818 -17.6035 -10.2133 --4.37283 -18.4595 -9.6067 --4.693 -18.7788 -8.70555 --3.68378 -18.6958 -8.64317 --3.04711 -19.4757 -8.44256 --3.31194 -20.3809 -8.15616 --3.28882 -21.2223 -7.67718 --4.21184 -21.0108 -7.3489 --4.78083 -20.1944 -7.25538 --5.17325 -19.4504 -6.72358 --5.26011 -18.4424 -6.57369 --4.78684 -18.3239 -5.70827 --4.51483 -17.4442 -6.18012 --4.15318 -16.7628 -5.5012 --4.21917 -16.1072 -4.87299 --3.74212 -15.6953 -5.62571 --4.3154 -15.2991 -6.30684 --5.0388 -15.3928 -6.98889 --4.3172 -15.3061 -7.65888 --4.64553 -15.8369 -8.50042 --3.78094 -15.9708 -9.04894 --4.03185 -15.0054 -9.2842 --3.34791 -14.2324 -9.2148 --2.74216 -13.4363 -9.5755 --2.26551 -13.0171 -8.72442 --2.28615 -12.3778 -9.48354 --1.46521 -12.4214 -8.90344 --1.13865 -11.5303 -8.6658 --0.562055 -11.4261 -7.87044 --0.465897 -10.8956 -7.08426 --1.04682 -10.5383 -6.46683 --1.48769 -10.168 -7.24678 --2.22638 -9.80931 -6.7286 --2.68035 -9.12281 -7.27984 --3.05932 -8.36928 -7.88992 --2.41224 -8.72277 -8.51117 --2.5887 -8.84828 -9.46352 --1.69787 -9.26633 -9.55887 --2.18797 -10.0778 -9.27299 --2.54116 -10.7042 -9.94804 --3.19873 -11.442 -9.80253 --4.08378 -11.1231 -10.2124 --3.42772 -10.8231 -10.9083 --2.55187 -10.6698 -11.3388 --1.87961 -9.95989 -11.2641 --2.6904 -9.77126 -11.8494 --2.75874 -8.7473 -11.7549 --2.18435 -8.94594 -11.0583 --2.25885 -8.13065 -10.5967 --2.53382 -7.4814 -9.94766 --2.42563 -6.53259 -9.52409 --1.95885 -5.97831 -10.1582 --2.82191 -5.62549 -10.4337 --3.58936 -6.11377 -10.8806 --3.31789 -6.55877 -11.7681 --3.48348 -5.80113 -12.382 --3.50306 -5.10191 -11.7269 --4.25672 -4.81569 -12.3724 --3.4176 -4.31535 -12.2849 --2.52515 -4.66291 -11.867 --1.55263 -4.83549 -11.6145 --1.52663 -5.73787 -11.2623 --0.846664 -5.11273 -10.823 -0.167458 -5.11345 -10.7391 -0.828566 -5.68561 -11.1075 -0.690266 -5.73108 -12.0457 -1.49824 -5.9098 -12.5929 -2.12951 -6.63934 -12.4501 -2.61485 -7.52896 -12.2873 -2.46522 -8.47283 -12.6014 -2.55514 -9.52912 -12.4159 -1.78268 -9.10386 -11.8581 -1.48624 -8.25327 -11.5174 -1.38335 -7.29099 -11.2995 -0.384445 -7.25558 -11.6067 -0.259597 -7.3452 -10.5911 --0.598338 -7.86755 -10.5066 --0.901415 -8.10627 -9.57526 --0.647332 -8.98062 -10.0315 --0.210731 -9.40171 -9.24363 -0.206064 -10.2175 -8.81559 -0.382995 -9.46033 -8.19315 --0.352407 -9.77948 -7.48105 --0.849142 -9.19522 -6.88633 --1.46886 -8.43508 -7.0752 --0.790682 -8.77626 -7.73203 --0.17667 -8.14825 -8.3453 -0.302823 -7.28767 -8.41897 -1.13414 -6.95559 -8.7791 -1.81336 -6.8577 -8.00251 -2.6783 -7.06952 -8.46684 -2.54861 -7.82863 -9.04406 -2.5473 -7.9718 -10.0163 -3.10979 -8.5685 -10.4775 -2.18273 -8.94439 -10.584 -2.03645 -9.53316 -9.74792 -2.47463 -10.0174 -8.97199 -2.7325 -10.9046 -8.76684 -2.98265 -11.2661 -7.89497 -2.2479 -11.8829 -8.01583 -3.14043 -12.3641 -7.86786 -2.72443 -13.1772 -7.43004 -3.42876 -13.3606 -6.68988 -4.0815 -12.7185 -6.52723 -4.33493 -13.5575 -6.02421 -4.72096 -14.4723 -5.84444 -5.03303 -14.926 -5.05136 -4.7974 -14.5494 -4.20406 -4.69782 -13.7394 -3.5656 -3.84025 -14.0909 -3.89419 -2.9067 -13.9376 -4.08523 -2.91625 -14.8429 -3.58604 -2.02576 -14.3418 -3.32978 -2.48267 -13.8801 -2.67692 -2.55361 -12.9271 -2.77267 -1.69982 -13.2544 -2.53238 -0.876923 -13.0072 -3.12945 -0.473609 -13.8419 -3.55156 -0.145605 -13.5135 -4.4195 --0.102888 -13.6135 -5.32303 --0.546808 -14.2368 -5.99965 --0.801334 -14.8125 -5.19511 --1.22663 -15.2386 -6.02797 --1.17143 -15.2872 -7.06485 --0.430845 -15.8261 -7.51477 --0.12752 -15.5456 -8.39823 -0.406398 -14.6877 -8.43538 --0.357962 -14.105 -8.29217 --1.36163 -13.7783 -8.17145 --1.63388 -12.8684 -7.82927 --2.07396 -12.0761 -7.39095 --2.27696 -11.5996 -6.54107 --2.15079 -11.3344 -5.61454 --2.58541 -11.7307 -4.803 --3.5223 -11.8309 -4.66908 --3.10611 -12.6511 -4.95856 --3.04545 -13.6382 -4.63361 --2.37001 -13.4045 -5.349 --1.93946 -12.4206 -5.39431 --1.13067 -11.94 -5.81236 --0.803068 -12.6255 -6.45777 --0.06733243 -12.0534 -6.55139 -0.631337 -12.6495 -6.83887 -1.38989 -12.0542 -7.15417 -2.20799 -11.525 -6.82157 -1.86633 -12.3237 -6.24185 -1.44788 -12.3905 -5.24862 -1.00325 -11.5266 -4.8867 -0.248417 -11.0087 -4.48163 -0.236091 -12.0138 -4.22242 --0.52344 -11.8078 -3.60658 --1.00831 -10.9962 -3.21496 --1.44165 -10.6322 -2.32399 --2.17818 -10.7441 -2.92818 --3.20127 -10.8409 -2.81987 --3.77399 -10.1364 -2.4904 --3.19204 -9.45773 -1.96594 --2.48629 -9.04385 -1.5538 --1.69402 -8.41213 -1.72794 --1.56365 -7.75567 -1.02557 --0.840817 -8.1178 -0.4772869 --0.484061 -8.31468 0.4821261 --0.714779 -7.31984 0.3963821 --1.7326 -7.21365 0.1272231 --2.36877 -6.50787 0.4035571 --2.95167 -5.95416 -0.2608069 --2.07454 -6.41282 -0.6269299 --2.13123 -6.98227 -1.52707 --2.61851 -7.58266 -2.23189 --3.1843 -8.38965 -2.43039 --3.4813 -7.58807 -3.05492 --3.73429 -7.29979 -3.98318 --3.50498 -6.56084 -3.34274 --4.27685 -6.59044 -2.66281 --4.25009 -7.43452 -2.14466 --4.75966 -7.09851 -1.3845 --4.80555 -6.08712 -1.422 --3.90915 -6.42064 -1.73763 --3.90024 -5.41456 -1.96875 --4.71564 -5.29546 -2.48182 --4.83503 -4.67136 -1.78708 --4.45282 -3.7949 -1.36873 --4.81239 -2.94477 -1.80802 --4.3522 -3.60372 -2.33377 --4.94596 -3.63285 -3.10788 --5.41409 -3.92354 -3.89604 --4.80246 -4.63892 -3.69175 --5.50902 -4.62768 -2.9498 --6.17786 -5.32257 -2.6825 --6.93382 -5.8789 -3.16858 --6.37226 -5.71111 -3.99547 --5.78218 -6.36825 -4.54537 --5.14827 -6.90338 -5.16303 --5.12429 -6.05287 -5.64607 --4.78405 -5.44961 -6.3362 --4.73495 -5.85295 -7.20148 --4.2643 -5.51843 -7.88169 --3.81437 -6.09051 -8.64934 --4.38284 -7.00592 -8.49771 --4.32204 -7.19172 -7.45033 --4.0745 -7.75582 -6.57974 --3.8081 -7.54234 -5.70427 --3.33842 -8.44116 -5.71774 --3.75776 -9.37796 -5.66772 --3.9632 -10.2366 -6.05129 --4.18261 -10.4498 -7.03028 --4.28352 -9.53792 -7.5662 --3.80751 -9.70603 -8.42783 --4.35924 -8.87388 -8.35086 --4.48108 -8.29318 -9.13253 --4.73544 -8.53484 -10.0086 --5.40972 -9.03748 -9.38197 --4.84938 -9.84372 -9.15587 --4.00868 -9.87191 -9.63705 --3.87679 -10.5456 -8.91476 --4.19548 -11.4296 -8.78262 --3.40597 -11.5916 -8.10372 --3.79738 -12.461 -8.10676 --4.16321 -11.7851 -7.50403 --4.612 -12.7045 -7.47935 --4.82732 -13.5771 -7.80756 --5.85016 -13.5647 -7.79969 --6.30038 -13.6408 -6.82029 --7.00699 -13.624 -6.13898 --6.38831 -12.9074 -6.05936 --6.79854 -12.9824 -5.07085 --6.19427 -12.6077 -4.46366 --6.17685 -12.8711 -3.51056 --6.74957 -13.7287 -3.62516 --7.17484 -12.9596 -3.1396 --8.11047 -12.8649 -2.95837 --8.15828 -12.8173 -3.99812 --8.62366 -12.7883 -4.76784 --9.06954 -12.679 -5.72139 --9.95253 -12.6184 -6.20569 --10.3295 -12.2217 -7.02937 --11.0087 -12.8892 -6.67695 --10.8754 -13.5411 -5.90165 --11.8237 -13.4338 -5.78308 --11.6956 -13.177 -4.79353 --12.4887 -13.3391 -4.23324 --12.1285 -14.007 -3.71961 --12.5932 -14.0942 -2.8327 --13.2627 -14.1653 -2.04208 --13.6735 -14.5153 -2.76445 --14.4285 -14.157 -3.28112 --14.5999 -13.7727 -4.21993 --15.343 -13.1277 -4.06144 --15.3151 -12.9449 -5.02863 --14.4429 -12.7526 -5.42388 --13.8139 -13.4438 -4.98612 --13.9427 -14.1343 -5.7207 --14.7152 -14.8065 -5.70206 --14.1603 -15.4635 -5.3592 --13.911 -15.4824 -4.35853 --13.1608 -14.8057 -4.18302 --12.6769 -15.5485 -4.64661 --12.8122 -16.5559 -4.54099 --12.9744 -17.2739 -5.16985 --12.2911 -17.9183 -5.47808 --11.6026 -18.2733 -5.95348 --11.5582 -17.3004 -6.1457 --10.7668 -16.8498 -6.62065 --10.4019 -16.327 -7.43013 --10.9995 -15.5663 -6.88618 --10.6001 -15.3291 -5.99296 --10.249 -14.9153 -5.11373 --9.40902 -15.446 -5.26245 --8.59879 -14.8581 -5.23257 --8.65781 -15.4868 -4.43245 --8.91835 -14.6258 -4.08379 --9.15449 -15.2262 -3.26378 --8.66991 -15.8566 -2.81344 --8.91184 -16.7423 -2.36227 --9.43281 -16.7243 -1.51427 --9.15261 -15.7837 -1.17602 --9.54112 -14.8639 -0.9906619 --9.17615 -14.8544 -0.05884918 --8.86366 -13.9628 -0.2897629 --8.21202 -14.4456 -0.8893569 --8.58293 -14.6136 -1.74923 --9.2116 -14.4326 -2.57776 --10.0406 -13.9385 -2.79395 --10.9746 -14.0581 -3.08897 --10.4617 -14.6775 -3.69861 --11.317 -14.7255 -4.21727 --11.2672 -15.3952 -3.48738 --10.7472 -15.3928 -2.64804 --10.4281 -16.3255 -2.66449 --10.7251 -16.0096 -1.79119 --11.5898 -16.5417 -1.62127 --11.9877 -16.9834 -0.8344099 --11.5492 -16.5618 -0.1304059 --12.4677 -16.2731 0.2235651 --12.1119 -17.1278 0.5649921 --11.2273 -17.5132 0.8381131 --10.6025 -16.7772 0.6695221 --9.92116 -16.0536 0.5327291 --10.4273 -15.6387 -0.1524589 --11.38 -15.508 -0.5184299 --12.1132 -15.0027 -0.1053899 --12.7113 -15.449 -0.7781149 --13.2541 -15.5573 0.06684782 --13.989 -15.0156 -0.08890958 --14.0873 -14.0273 -0.4405479 --14.2495 -13.097 -0.6504829 --15.0603 -13.2307 -0.06914208 --15.9876 -13.0614 -0.2852609 --16.2985 -13.9135 0.2438651 --16.2112 -14.0346 1.20577 --15.2448 -14.1395 1.11494 --15.2157 -14.8884 1.8775 --15.3307 -15.8167 1.43524 --15.9855 -16.1337 2.05662 --15.3799 -16.1626 2.86289 --14.4716 -15.6247 2.99175 --13.9951 -14.8561 2.49237 --13.3189 -15.1242 3.05099 --12.6841 -15.7566 2.9915 --12.1343 -16.5406 2.7664 --12.3457 -17.5583 2.61185 --13.3077 -17.6188 2.19687 --13.6715 -17.7274 3.08537 --13.3233 -18.5037 3.5885 --12.955 -18.7361 4.46727 --12.6278 -19.4875 3.90396 --12.3454 -19.893 3.04269 --12.4842 -19.2236 2.40699 --11.7988 -18.9572 1.84535 --11.5926 -19.8708 1.51474 --11.3765 -19.6077 0.5757821 --10.4883 -19.0764 0.6249351 --10.5374 -18.6956 1.56369 --10.734 -18.3992 2.51298 --9.79927 -18.222 2.56876 --9.28644 -18.8685 3.19013 --9.27977 -19.3349 2.29763 --8.85734 -19.0788 1.38835 --8.27708 -19.8551 1.41669 --9.01956 -20.4164 0.9560031 --9.6898 -20.6504 1.70992 --10.4328 -21.2157 1.32342 --10.6757 -20.9373 2.24398 --10.1583 -21.594 2.68841 --10.3961 -22.4347 2.27425 --10.4165 -22.6927 1.31698 --10.8006 -22.6702 0.3516861 --10.2883 -21.9945 -0.2298529 --10.4571 -21.4019 -0.9919809 --10.1012 -20.5105 -1.07526 --9.18049 -20.2911 -1.1013 --8.19223 -19.9301 -0.9283749 --7.44787 -20.6111 -1.05192 --6.4475 -20.6167 -0.9831219 --5.75958 -20.0208 -0.7579389 --4.83351 -20.4141 -1.03425 --4.25914 -19.7303 -0.4547009 --4.10593 -19.6191 -1.46373 --4.10061 -20.3867 -2.15923 --3.84737 -21.3741 -2.01031 --3.99985 -21.949 -2.81211 --3.95822 -21.202 -3.45018 --4.89557 -21.7006 -3.35904 --5.54065 -22.2838 -2.81 --6.53261 -22.2279 -2.75522 --7.04036 -21.3422 -2.68527 --7.53093 -21.3023 -3.5118 --8.20292 -20.7488 -4.03042 --8.59874 -21.503 -3.51647 --9.15945 -21.26 -2.75029 --9.61624 -20.3797 -2.59852 --9.16925 -19.5105 -2.621 --9.90965 -19.0756 -2.24725 --10.6294 -18.4214 -2.44332 --9.77153 -18.1259 -2.95762 --9.68216 -17.3094 -3.55915 --10.3639 -17.5631 -4.16538 --10.3232 -18.4979 -3.65905 --9.88846 -19.2663 -3.24487 --9.26034 -19.1199 -3.92483 --9.02877 -20.119 -4.00549 --9.31284 -20.9448 -4.55391 --9.53336 -21.9831 -4.46851 --10.0998 -22.3309 -5.2758 --10.6962 -21.7488 -5.83078 --9.87059 -21.2689 -6.09854 --9.83923 -20.9028 -7.00114 --9.00277 -20.7839 -7.55907 --9.63608 -21.5609 -7.56479 --9.29512 -22.3144 -8.14385 --9.5976 -22.6713 -7.29345 --9.5486 -22.5708 -6.30754 --8.68865 -22.6329 -5.85294 --9.22813 -22.7869 -5.11943 --8.92921 -23.5418 -4.44149 --8.73219 -22.8718 -3.75859 --9.63369 -22.9751 -4.02102 --10.2123 -23.4195 -3.28144 --11.1857 -23.68 -3.34844 --11.6308 -24.3155 -2.84416 --11.1608 -24.5261 -2.05627 --10.4501 -24.0877 -1.48022 --10.8999 -23.4881 -0.8462979 --11.6843 -22.8805 -1.16705 --11.7063 -22.8349 -2.17052 --12.5335 -23.4005 -2.21222 --13.3068 -23.9014 -2.53959 --13.8445 -23.8804 -3.34939 --13.9352 -24.3809 -4.29686 --13.4267 -25.1423 -3.90525 --12.8946 -24.293 -3.89244 --12.7719 -23.3343 -3.5034 --13.4219 -22.5406 -3.47346 --14.3499 -22.8141 -3.33856 --14.8799 -22.1327 -2.91774 --15.2801 -22.9994 -2.75792 --15.9474 -23.492 -2.13638 --15.9352 -24.5073 -2.07099 --15.0316 -24.5554 -1.62213 --15.1621 -24.9759 -2.48222 --15.8727 -24.7131 -3.11848 --15.2641 -25.1283 -3.77023 --14.8745 -25.4872 -4.65039 --14.7537 -26.1753 -5.39544 --15.3968 -25.5041 -5.91847 --15.6261 -25.7836 -6.87283 --16.2213 -26.6349 -6.97975 --16.5628 -26.972 -7.87227 --17.0446 -27.8317 -8.27311 --16.6908 -27.5158 -9.22237 --16.0486 -26.7232 -9.38605 --16.4272 -26.4956 -10.3105 --17.1352 -26.7392 -10.9121 --17.9323 -26.0622 -10.7437 --17.8361 -25.6051 -11.6363 --18.0748 -24.6706 -11.8486 --17.5106 -24.5762 -11.0623 --16.7434 -25.2513 -11.1087 --16.3069 -25.4355 -11.9865 --15.7988 -24.5379 -11.8407 --15.8997 -23.8037 -11.176 --15.596 -24.3695 -10.3998 --15.4789 -23.7638 -9.64523 --16.26 -23.1985 -9.75304 --16.1795 -22.4048 -9.2224 --17.1158 -22.5106 -8.70261 --17.0902 -21.5073 -8.40569 --17.0545 -21.9168 -7.47618 --17.2197 -22.0129 -6.54211 --16.4382 -22.5466 -6.25854 --15.8461 -23.1897 -5.78147 --15.5119 -23.6656 -6.50799 --16.4478 -23.951 -6.31296 --17.0974 -24.5028 -5.85036 --16.7606 -25.4586 -5.86018 --16.3179 -26.1437 -5.28684 --16.5406 -26.7135 -4.45647 --16.5346 -27.3105 -3.62636 --16.5939 -26.941 -2.70476 --16.2442 -26.035 -2.40775 --15.44 -26.2734 -1.88271 --14.8617 -25.9266 -1.22135 --14.3192 -25.9407 -0.4216239 --14.7628 -25.5161 0.4113921 --14.9897 -26.2988 1.03184 --15.7009 -26.475 1.8098 --16.0207 -25.7552 1.2052 --15.6262 -24.8989 0.8569101 --15.5754 -24.6363 -0.07352688 --15.4433 -23.9127 -0.7182949 --15.4008 -22.9975 -1.02725 --14.9319 -22.4404 -0.4009109 --14.5899 -21.5652 -0.6650349 --15.4709 -21.0535 -0.8124469 --15.5277 -21.3297 0.1434341 --16.1159 -20.5521 0.1259291 --16.6993 -20.5958 -0.6488479 --17.7244 -20.6078 -0.8686739 --18.3655 -19.9409 -1.31859 --19.2291 -20.3068 -1.06694 --18.9123 -20.4652 -0.1259429 --19.7315 -20.0995 0.2884271 --19.8084 -20.2325 1.28556 --20.2818 -20.2226 2.14711 --21.1577 -19.9108 2.1351 --21.7778 -20.2835 1.49821 --22.5102 -20.9019 1.80574 --23.0641 -20.2512 1.4101 --23.6131 -21.0372 1.18343 --23.8404 -21.7877 1.72333 --24.6404 -21.3875 2.15444 --25.4342 -21.1055 2.67174 --26.0425 -20.3199 2.57518 --25.2793 -19.8154 2.86549 --25.2282 -19.1625 3.63032 --25.8006 -18.9434 4.45133 --25.5865 -18.4805 5.40969 --25.433 -17.5236 5.25113 --24.9098 -18.1264 4.59982 --24.0421 -17.6195 4.48747 --23.9751 -16.9458 5.21951 --23.6191 -16.3365 4.53271 --23.1546 -16.523 3.66617 --22.9382 -17.3522 3.21668 --23.0536 -18.4145 3.10608 --23.2578 -19.0033 3.85866 --24.1294 -19.4143 3.64735 --24.4649 -18.8683 2.83483 --25.2497 -18.1708 2.62654 --24.7535 -17.622 1.88608 --24.0215 -17.3961 1.24974 --24.3138 -16.7102 1.90586 --24.315 -15.7003 1.72003 --25.1529 -15.2605 2.07131 --25.7038 -15.7144 2.74793 --25.9992 -14.7624 2.87699 --25.3576 -15.0975 3.67471 --24.5143 -14.8791 4.11524 --25.1382 -15.0403 4.858 --25.6389 -14.1996 4.56161 --26.2007 -14.3373 5.42019 --26.5707 -13.7682 6.09451 --26.1034 -12.909 6.19154 --25.702 -12.1043 5.71625 --26.0071 -11.3273 6.34874 --26.9974 -11.4344 6.27468 --27.5728 -11.2292 7.11139 --27.1517 -11.3361 7.97961 --26.3504 -11.547 8.60445 --25.9793 -10.8419 7.95929 --25.1374 -10.2913 7.8105 --25.8999 -9.61586 8.18436 --26.7531 -10.1965 8.17206 --27.2291 -10.3923 9.05196 --26.2725 -9.97099 9.19647 --26.5932 -8.99787 9.3671 --25.7672 -8.52431 9.67526 --25.8109 -8.33928 10.6489 --25.5332 -9.09613 11.3026 --24.9824 -9.50813 12.0718 --24.653 -10.3495 11.6212 --25.2394 -10.3694 10.8162 --26.0473 -10.8099 11.1584 --26.9029 -11.1846 10.7891 --27.6672 -10.8698 11.4231 --28.4823 -11.4371 11.5806 --28.8993 -10.9061 10.8502 --29.8385 -11.0488 10.7529 --29.6422 -11.9243 11.2191 --29.5238 -12.8779 11.0005 --30.5594 -12.9965 10.894 --31.2086 -13.2979 11.6018 --31.3946 -13.6777 10.6804 --32.0026 -14.3861 10.464 --32.2146 -13.6582 9.83058 --31.7114 -13.3655 9.0819 --31.6265 -12.4385 8.94563 --31.0071 -11.9883 8.29635 --30.6262 -12.8899 8.23274 --30.533 -12.4508 9.02015 --29.5844 -12.5537 8.94589 --28.9368 -12.3101 9.66539 --27.945 -11.9393 9.85732 --27.7795 -12.9381 9.84613 --27.9997 -12.8194 10.8369 --27.662 -13.7028 10.6211 --28.0586 -14.5832 11.0432 --29.0414 -14.3901 10.7143 --29.3759 -14.3166 11.652 --29.6072 -15.252 11.456 --28.9175 -15.8611 11.7262 --28.6188 -16.5135 10.9934 --28.8593 -15.8101 10.247 --29.7759 -15.6546 10.0184 --29.8077 -16.5582 9.67115 --28.9164 -16.3556 9.24566 --28.6269 -16.4326 8.29161 --29.1054 -15.8997 7.58653 --29.4252 -15.0586 7.02817 --29.3571 -15.8017 6.46294 --28.5601 -15.8371 5.90571 --28.4133 -16.4763 5.2086 --28.7791 -15.6729 4.83089 --29.7108 -15.9003 4.97143 --29.8533 -15.4132 4.12124 --29.4314 -15.3147 3.16338 --29.6236 -14.3518 3.08554 --28.953 -14.1115 3.8389 --28.1381 -14.0386 3.1966 --27.5004 -14.764 3.36394 --27.4799 -15.4626 4.06081 --27.5419 -15.8622 3.08447 --28.1904 -16.4162 3.58639 --28.7206 -16.8576 2.84338 --29.1514 -17.5247 2.14949 --29.7016 -16.6983 1.82078 --30.5267 -16.4129 2.37307 --31.1556 -15.665 2.37982 --31.9034 -16.2583 1.93547 --31.8687 -15.4744 1.3677 --32.2697 -15.0746 2.16541 --32.5149 -14.2259 2.50944 --32.0218 -13.5442 1.96798 --31.2199 -14.1366 2.23689 --30.2918 -13.9089 2.11207 --29.8776 -13.5407 1.27515 --29.8314 -12.6881 0.7281811 --29.8248 -13.022 -0.2428119 --29.0795 -12.3248 -0.2628429 --29.6427 -12.0382 -1.02777 --29.3795 -11.1295 -1.5376 --30.1799 -10.5148 -1.605 --31.0089 -10.1438 -1.45053 --30.3881 -9.73343 -2.12975 --30.2834 -8.92624 -1.5635 --29.5291 -9.29656 -1.01739 --29.0713 -9.94163 -1.51341 --28.349 -9.77612 -0.8048149 --28.2586 -8.8528 -0.3593109 --28.3219 -7.93846 -0.4750789 --27.6362 -7.44616 -1.0954 --27.6214 -6.68619 -1.81653 --27.5256 -6.66736 -2.81041 --28.325 -6.30654 -3.29322 --29.1787 -6.86134 -3.55906 --30.1271 -6.72461 -3.62124 --30.2215 -7.34116 -2.77154 --30.7692 -8.19409 -2.75922 --30.8918 -8.26476 -1.72008 --30.8545 -7.34657 -1.37889 --30.1588 -7.06606 -0.6849379 --30.7615 -6.96026 0.1223081 --30.515 -6.03601 0.2646411 --31.3668 -5.7821 -0.1432519 --30.8099 -5.32236 -0.7297359 --30.3989 -6.21286 -0.8100949 --29.5071 -6.01771 -0.5242219 --28.8509 -5.47707 -1.03726 --29.1968 -4.65662 -0.5421639 --29.7479 -3.97325 0.00390298 --29.7711 -3.46552 -0.7974169 --29.931 -2.51291 -0.7939619 --28.9664 -2.38214 -0.7090939 --29.1064 -1.65118 -0.07350588 --29.5628 -0.7682371 0.00802224 --29.5155 0.06386303 0.5531761 --29.1933 0.5350509 -0.2920219 --28.3896 1.06312 -0.5128269 --28.7585 1.17703 -1.55726 --29.1289 0.2024609 -1.58223 --29.9816 -0.2178351 -1.68734 --30.4698 -0.6354021 -0.9249599 --30.8782 -1.22377 -0.2671449 --30.894 -1.99012 0.3385521 --31.7949 -2.19791 0.7334211 --32.2138 -3.06815 0.9608151 --31.2937 -3.14525 1.22714 --31.2902 -3.56157 2.16568 --30.8086 -4.40609 2.51134 --30.5709 -5.19211 3.03957 --31.4211 -5.27342 3.50111 --31.0995 -4.43814 4.00308 --31.2521 -3.49512 3.70803 --30.7568 -2.68252 3.9067 --30.3417 -2.67146 3.08855 --30.0039 -1.72203 2.90904 --30.0512 -1.62629 3.89533 --30.9856 -1.77939 3.61479 --31.2721 -1.30445 4.46562 --30.658 -1.57862 5.24745 --30.3761 -0.6638401 4.89522 --30.6523 -0.3471301 5.847 --29.857 -0.8202281 5.91053 --29.7611 0.08377033 6.25046 --30.3996 0.8988479 6.36069 --29.4633 1.13948 6.62189 --28.662 0.8436169 6.08372 --27.8733 1.03403 6.73227 --27.3602 1.49167 7.38368 --28.0594 2.12466 7.40664 --28.4613 2.9642 6.95819 --28.4331 3.56506 7.66184 --28.4872 4.17833 6.87901 --28.9003 4.48958 5.96177 --29.6338 5.05487 6.3461 --30.4882 5.02277 5.73339 --31.092 4.2249 5.82261 --31.8246 4.19903 5.15207 --32.4528 4.04012 5.97196 --31.9261 3.14632 5.96912 --31.1066 3.02587 5.44422 --31.063 2.45841 4.55799 --30.8305 3.29639 4.14407 --29.951 3.34086 4.69168 --29.1624 2.68028 4.49473 --29.5515 1.85532 4.01351 --28.6988 2.27571 3.54866 --28.4755 1.50422 2.94599 --29.0426 1.82734 2.13299 --28.1272 1.93495 1.88761 --27.4481 1.68041 1.1838 --27.7405 0.9291299 0.6005541 --27.2577 0.08427333 0.9045761 --26.4184 -0.2851211 1.18588 --25.6625 -0.2233741 0.6132801 --25.4787 -0.2559861 -0.2883619 --26.409 0.1893689 -0.3968159 --26.6287 1.07329 -0.05366608 --26.6613 1.27036 -1.01643 --27.5318 0.8457059 -1.35992 --27.5558 -0.03318007 -0.9657839 --27.5521 -1.05283 -0.9672479 --27.3454 -1.94841 -1.37363 --26.7703 -1.82321 -0.4705729 --26.2493 -2.45756 -1.03878 --25.3738 -2.4678 -1.47035 --25.357 -1.50229 -1.07116 --25.2386 -1.59023 -0.1178459 --25.3074 -1.09918 0.8236221 --25.0866 -1.57426 1.64645 --25.1706 -2.34457 2.25706 --25.9509 -2.36606 2.87133 --26.0188 -1.58151 3.55735 --25.4249 -0.9150481 3.97254 --24.8318 -0.9475121 4.73922 --23.9156 -0.9986791 4.26439 --23.6341 -1.27303 3.40802 --24.3031 -1.97625 3.33408 --24.5996 -2.87035 3.26449 --25.05 -3.76655 3.29812 --24.3769 -4.42807 3.13499 --24.1661 -4.5239 4.14027 --24.9591 -5.07494 4.18127 --24.749 -5.27469 5.19018 --24.02 -5.48522 5.79527 --23.8142 -4.69705 5.18451 --22.8785 -4.66204 5.00561 --23.0942 -4.00753 4.28411 --23.6151 -3.19619 3.9755 --23.4866 -3.67127 3.12482 --22.9876 -4.27192 2.51077 --22.2 -4.75345 2.42018 --22.6843 -5.6025 2.67269 --23.6383 -5.2387 2.40044 --24.4916 -5.34048 1.94956 --25.377 -5.70905 1.54056 --26.2804 -6.17689 1.53887 --27.1241 -5.7095 1.80761 --26.8549 -4.81595 2.08773 --26.6854 -3.85051 1.9905 --27.3696 -3.36869 1.45945 --28.309 -3.26687 1.44077 --27.9088 -4.14171 1.01057 --26.9621 -4.31718 0.7441811 --27.182 -4.56497 -0.2147159 --26.2929 -5.02255 -0.3894559 --25.9775 -5.97234 -0.5933719 --25.4313 -6.49067 0.01223082 --25.1522 -6.90335 -0.8503829 --25.6515 -7.39857 -1.49961 --26.2871 -8.10652 -1.84514 --25.3726 -8.21781 -2.24252 --25.0525 -8.84455 -2.93077 --24.5548 -9.4021 -3.58789 --24.8337 -9.57013 -4.59893 --25.7736 -9.76335 -4.68072 --26.7672 -9.62468 -4.8666 --27.1906 -9.30579 -5.77186 --27.8985 -9.66443 -6.33573 --27.3717 -10.5647 -6.20375 --26.8545 -10.0763 -6.86043 --26.934 -10.9439 -7.29116 --27.9546 -10.8605 -7.33612 --28.8433 -11.0339 -6.9922 --28.9868 -10.7838 -7.94044 --29.0923 -11.783 -8.23123 --30.048 -11.7635 -7.84779 --30.9869 -11.7356 -7.58966 --31.4154 -11.3405 -6.80554 --31.3256 -12.1028 -6.16949 --30.824 -11.7417 -5.40567 --31.3847 -12.1949 -4.63727 --32.3314 -12.4778 -4.40528 --32.3971 -12.7676 -5.33096 --32.4856 -13.4947 -6.04092 --33.3995 -13.5752 -6.3308 --33.0489 -12.6673 -6.50486 --33.6577 -12.2096 -5.84394 --33.7011 -11.4583 -6.4566 --32.8244 -11.245 -6.97706 --32.1166 -11.5455 -7.52938 --31.9776 -10.7784 -8.27139 --32.2172 -10.2931 -7.41869 --31.4303 -9.67445 -7.31987 --31.4656 -8.63896 -7.36469 --30.8081 -7.96372 -6.881 --30.0461 -7.45755 -7.11506 --29.1542 -7.26022 -7.46534 --28.5011 -8.00002 -7.36582 --28.0116 -8.45689 -8.10759 --27.4542 -8.83888 -8.88506 --27.7659 -8.50368 -9.76429 --27.9604 -8.64531 -10.7496 --27.8128 -9.6302 -10.6551 --28.6778 -9.28622 -10.3464 --28.3216 -9.71855 -9.50077 --28.006 -10.6796 -9.44986 --28.0359 -11.6222 -9.51966 --28.1238 -12.4851 -8.98122 --27.1446 -12.7589 -8.71498 --26.8869 -13.3564 -7.93044 --26.0569 -13.3286 -7.41902 --26.0744 -12.4167 -7.68321 --25.1535 -12.1762 -7.31656 --24.9295 -12.1621 -8.25096 --25.3232 -11.2396 -8.46071 --25.7317 -11.1856 -7.54166 --25.1124 -10.4331 -7.64469 --24.768 -11.146 -6.92381 --24.2766 -10.5113 -6.33907 --23.5728 -10.6263 -7.05302 --23.8962 -11.3046 -7.58342 --23.0046 -11.5574 -7.25586 --23.2388 -12.2539 -6.57607 --23.5069 -12.8063 -5.72232 --22.6149 -12.4191 -5.54249 --21.8887 -11.7253 -5.60015 --21.8149 -11.766 -4.59949 --20.9085 -12.1535 -4.48421 --21.3988 -12.8645 -3.96208 --21.5868 -13.5412 -3.15454 --22.6011 -13.5586 -3.26399 --23.0568 -14.4146 -3.71873 --22.9487 -15.3497 -3.46057 --23.4105 -15.1787 -2.58188 --23.6123 -16.1829 -2.57414 --23.662 -17.1463 -2.44441 --24.3299 -17.3071 -3.19119 --24.4308 -18.3193 -3.48229 --24.6074 -18.1502 -4.43307 --23.8167 -18.3977 -4.92587 --22.8931 -17.991 -5.0565 --22.7148 -18.9847 -5.01766 --23.47 -19.2622 -5.63153 --23.1884 -19.0546 -6.56389 --22.4487 -18.3212 -6.5929 --21.7678 -17.7408 -6.13075 --21.2312 -17.0618 -5.57634 --21.7461 -16.2831 -5.97075 --22.7148 -16.0641 -5.97687 --22.7795 -15.1445 -6.26752 --21.9823 -14.4952 -6.29754 --21.4639 -14.6324 -7.15331 --21.3465 -15.5838 -7.2058 --21.3137 -15.4163 -8.20429 --22.2569 -15.6842 -8.04287 --22.4443 -16.6676 -8.22012 --21.6068 -16.9 -7.69914 --20.948 -17.5222 -8.10991 --19.9631 -17.701 -7.93945 --19.8039 -16.6786 -7.91739 --19.5448 -15.7656 -7.58659 --19.1022 -14.8241 -7.62245 --19.3859 -14.7652 -8.59994 --19.1218 -13.8056 -8.58245 --19.623 -13.8326 -9.43501 --20.4095 -13.4389 -9.99732 --20.0405 -13.6117 -10.9602 --20.9933 -13.7004 -11.2531 --21.4851 -13.549 -12.0461 --21.2994 -12.6479 -12.5347 --21.175 -12.2933 -11.6027 --20.2853 -12.6484 -11.2542 --19.7233 -11.8752 -11.3393 --19.5285 -12.2723 -10.421 --18.8272 -12.8946 -10.311 --18.1598 -13.3744 -10.8442 --18.2628 -12.4193 -11.2784 --17.3028 -12.6552 -11.104 --17.4972 -11.9453 -10.398 --18.3933 -11.5223 -10.0736 --17.7072 -11.4136 -9.34278 --18.6548 -11.3202 -9.1923 --18.7242 -11.8215 -8.33859 --18.0308 -11.2475 -7.99316 --17.3525 -11.4497 -7.33373 --16.3836 -11.5055 -7.36326 --16.2205 -10.5676 -7.1397 --15.9991 -10.8604 -8.04101 --15.0333 -10.6683 -7.78521 --15.1777 -11.4324 -8.44314 --14.8857 -12.4031 -8.67682 --15.711 -13.002 -8.50263 --15.3594 -13.8689 -8.21681 --14.6092 -14.0567 -8.86929 --14.7629 -13.3483 -9.58362 --15.0445 -14.2141 -9.94704 --15.0674 -14.4327 -10.9589 --15.7763 -15.079 -11.1975 --15.1977 -15.476 -10.6349 --16.1386 -15.571 -10.3602 --15.8148 -14.9078 -9.64515 --16.1011 -14.8463 -8.66348 --15.8332 -14.892 -7.72444 --15.9731 -14.6878 -6.715 --16.1808 -14.934 -5.76922 --16.8193 -14.9296 -5.09095 --15.9668 -14.485 -4.79662 --16.3296 -14.7002 -3.87623 --15.9705 -15.0862 -3.06033 --15.4432 -15.8742 -2.88952 --15.0575 -16.015 -1.85246 --14.5003 -16.4536 -2.58583 --13.8788 -16.7357 -3.29499 --14.3786 -17.3325 -3.9835 --14.7359 -18.2585 -3.83611 --14.7304 -18.2072 -4.84909 --15.6238 -17.7687 -4.58395 --16.1526 -18.4012 -4.1031 --17.0351 -18.9471 -4.1656 --17.2486 -18.3966 -4.86542 --17.4818 -17.5467 -4.42886 --18.497 -17.3997 -4.29158 --18.9273 -17.7165 -5.14716 --19.4041 -18.4866 -5.43493 --19.9146 -19.3054 -5.51828 --20.8201 -18.9569 -5.77788 --21.4777 -18.4787 -5.17628 --21.0725 -18.0428 -4.33419 --21.6861 -18.6364 -3.74198 --22.1742 -18.4869 -2.86736 --22.5271 -18.7054 -1.9394 --21.5085 -18.6989 -1.85862 --21.1278 -18.9942 -0.9415719 --20.1809 -18.7181 -1.3907 --19.5293 -18.2858 -2.08003 --18.6463 -18.7073 -1.89656 --17.7537 -18.8025 -1.57977 --17.9359 -19.2656 -0.7053519 --16.9949 -19.2952 -0.8236809 --16.1756 -19.5533 -0.2045599 --15.6039 -18.7442 -0.05060448 --14.8323 -19.0295 -0.5426879 --14.8383 -19.1837 -1.5106 --14.8268 -18.2113 -1.41878 --15.715 -18.4817 -1.84622 --16.5216 -18.3193 -1.23044 --16.8753 -18.5273 -2.06643 --17.3595 -18.9647 -2.85467 --17.4947 -19.5392 -3.65569 --18.1951 -19.7678 -2.95617 --17.8608 -20.7049 -3.13411 --17.7769 -21.7568 -3.00016 --18.0274 -22.7385 -2.88098 --18.1164 -22.2323 -1.98337 --18.6976 -22.971 -1.7219 --18.3922 -22.3965 -0.8787259 --18.6316 -22.1561 -0.01487328 --19.1724 -22.2513 0.7750871 --19.6243 -22.674 0.00962259 --19.7974 -22.6372 -0.9609369 --20.4904 -23.4349 -0.7582679 --20.8773 -23.1241 -1.6435 --20.6014 -23.5762 -2.50997 --21.0161 -24.1564 -3.18901 --21.3462 -24.7618 -3.93856 --21.1277 -24.0912 -4.76615 --20.3538 -23.4659 -4.74199 --19.892 -22.6769 -5.23613 --19.8156 -22.5254 -6.25192 --19.5351 -22.9795 -7.12728 --19.2711 -22.7492 -8.02902 --19.0257 -22.3495 -8.91883 --19.8895 -22.6588 -9.317 --20.7496 -22.3489 -8.87094 --20.9006 -21.4633 -9.33278 --21.2252 -20.5356 -9.71352 --21.309 -20.8216 -8.72685 --21.2523 -21.1804 -7.80573 --21.2564 -21.5361 -6.93202 --22.1931 -21.7126 -7.10912 --22.6633 -22.6247 -7.39364 --23.64 -22.6539 -7.38257 --24.3559 -22.0915 -7.86802 --24.9109 -22.6306 -7.20335 --25.2371 -22.3603 -6.21351 --26.0495 -21.9689 -6.67229 --26.4214 -21.0588 -6.54317 --26.4782 -20.0161 -6.3547 --26.9893 -19.4037 -5.75337 --27.7069 -20.1158 -5.82743 --27.6574 -20.6003 -4.98471 --27.0331 -20.695 -4.23207 --26.4469 -20.7485 -3.42809 --27.2163 -20.7026 -2.6656 --27.5987 -20.0814 -1.96346 --27.3423 -19.092 -1.86237 --27.0439 -19.0775 -2.80918 --26.3872 -18.4412 -2.46021 --25.5977 -18.7838 -1.98539 --25.5223 -19.2082 -1.06151 --25.1493 -18.7464 -0.2292469 --25.0966 -19.5113 0.4843211 --24.0903 -19.7892 0.3908011 --23.1972 -20.063 -0.09210218 --23.9996 -19.9896 -0.6815769 --24.8522 -20.3937 -0.9328289 --25.8116 -20.4419 -1.25787 --26.4411 -20.8219 -1.94218 --26.3505 -21.508 -2.71148 --26.106 -22.448 -2.76063 --27.0263 -22.6198 -3.17211 --26.4183 -23.0712 -3.89126 --25.4866 -22.7876 -4.0898 --24.7699 -22.2096 -4.5175 --24.9503 -21.2314 -4.72351 --24.9178 -20.6363 -3.91217 --24.7666 -20.1358 -3.07427 --25.2178 -19.5592 -3.73603 --26.083 -19.0427 -3.80122 --26.6542 -18.2209 -3.5667 --27.6271 -18.359 -3.22031 --28.4522 -17.7683 -3.3492 --28.7714 -17.9013 -4.29267 --29.7087 -17.9549 -3.97284 --30.4244 -18.5028 -4.5227 --31.3736 -18.4807 -4.62808 --31.7529 -17.831 -4.00141 --31.4749 -16.8945 -3.80916 --30.5209 -17.0765 -3.76165 --30.4881 -16.3811 -3.10029 --30.7015 -15.7919 -3.80869 --31.0457 -14.9745 -4.31396 --30.5098 -14.2774 -4.83538 --29.6104 -14.4931 -4.63153 --28.8529 -15.093 -4.36048 --28.1722 -15.3227 -4.98921 --27.2861 -15.4446 -5.45039 --27.0536 -16.1893 -6.1548 --26.9681 -17.2377 -6.36607 --26.3418 -16.611 -6.85056 --25.9976 -17.223 -6.16631 --25.8878 -18.0996 -6.55679 --25.1878 -18.4797 -7.22614 --26.0939 -18.4407 -7.5826 --25.756 -17.5128 -7.66674 --24.7403 -17.436 -7.95162 --24.3414 -16.9396 -8.74811 --23.9348 -15.9885 -8.71027 --23.2873 -15.8692 -7.97257 --24.1344 -15.3431 -7.62414 --23.4077 -14.8772 -8.07185 --23.0906 -14.8404 -9.01234 --22.5616 -15.3112 -9.78361 --21.6159 -15.1201 -9.65367 --21.4822 -15.9643 -10.1662 --21.8489 -16.9055 -9.91433 --22.251 -17.3912 -9.12553 --22.953 -17.6048 -9.71765 --22.2619 -18.0746 -10.2739 --22.4585 -18.4079 -11.2432 --22.655 -19.0555 -11.958 --23.3597 -19.055 -12.6614 --24.1245 -18.6977 -13.2357 --24.8015 -18.242 -13.7728 --25.1755 -17.7838 -12.9005 --25.3666 -16.8263 -13.1738 --24.777 -16.0876 -13.5263 --24.1724 -16.7288 -13.0435 --24.0038 -17.657 -12.9725 --23.14 -17.3476 -13.3573 --22.405 -17.4056 -14.114 --21.5227 -17.847 -14.1256 --20.9647 -18.5576 -13.826 --20.4456 -19.4147 -14.2127 --19.5979 -19.3032 -14.7406 --19.3598 -20.2359 -14.9621 --18.3814 -20.0485 -14.8549 --18.0673 -21.0307 -14.916 --18.7262 -21.1832 -14.164 --18.6001 -22.07 -14.6024 --19.0228 -21.9873 -15.5602 --18.143 -21.8541 -15.9679 --18.742 -22.0365 -16.6504 --18.6822 -22.4723 -17.57 --17.9694 -22.5221 -18.2066 --17.4622 -21.7283 -17.723 --16.736 -21.0673 -17.374 --15.7811 -21.3537 -17.0446 --15.1483 -21.84 -17.6034 --15.9652 -21.6118 -18.0431 --16.0738 -21.9368 -19.0579 --16.8466 -21.5645 -19.6197 --17.4188 -21.0485 -19.0389 --17.4608 -20.6828 -19.9781 --17.5284 -21.1167 -20.9018 --17.6335 -20.457 -21.7255 --18.2965 -21.1971 -21.6645 --18.7869 -21.8414 -22.2825 --18.4286 -22.7674 -22.4586 --18.8628 -22.5113 -23.3067 --18.0961 -22.2047 -23.8972 --18.1489 -21.406 -23.383 --17.8302 -20.4716 -23.4896 --16.888 -20.787 -23.6274 --16.2713 -20.396 -24.2248 --16.6193 -21.2464 -24.5242 --17.3313 -20.5438 -24.7774 --18.0859 -19.9731 -24.8012 --17.7132 -19.0655 -25.0533 --18.2605 -18.2507 -25.1965 --18.4239 -17.3207 -25.0954 --19.0954 -17.336 -24.3218 --19.9518 -17.3903 -23.8396 --20.35 -18.2355 -23.4973 --20.2752 -17.6068 -22.6349 --21.1872 -18.0495 -22.3404 --21.5524 -17.2089 -21.8648 --21.6549 -16.6718 -21.0519 --22.3831 -17.2386 -20.6115 --22.2511 -17.1216 -19.616 --21.4134 -16.8692 -19.1394 --20.9638 -16.3072 -18.397 --21.3668 -17.1941 -17.9489 --21.0504 -16.6631 -17.1335 --20.9522 -15.6075 -17.02 --21.6926 -15.4803 -17.6442 --22.0368 -15.3316 -18.583 --22.4198 -14.3945 -18.4102 --22.7983 -14.2821 -17.4946 --22.2433 -13.8623 -16.8117 --22.876 -14.5896 -16.5057 --21.9265 -14.6315 -16.1994 --20.9728 -14.6481 -16.6448 --20.8291 -14.2433 -15.6965 --20.7322 -14.1778 -14.647 --21.2115 -14.7648 -14.0244 --20.5173 -15.362 -13.7412 --19.7008 -15.9922 -13.7109 --19.2228 -15.6088 -12.9134 --18.3494 -15.3869 -13.3228 --18.292 -15.7808 -14.2429 --17.2846 -15.7232 -14.1711 --17.1446 -15.076 -13.4189 --17.2152 -14.0816 -13.3314 --17.2092 -13.4827 -14.1171 --17.9192 -13.8276 -14.696 --17.7443 -13.368 -15.5887 --17.9719 -12.4819 -15.8824 --17.3777 -12.3507 -15.101 --16.7844 -12.4855 -15.8953 --16.8472 -12.5896 -16.9266 --16.1674 -13.2187 -16.6429 --15.6761 -13.6632 -15.8651 --14.7166 -13.9623 -15.8691 --13.7702 -13.7494 -15.5837 --13.616 -13.99 -16.5844 --12.6024 -14.0587 -16.5821 --11.7043 -13.6872 -16.5305 --10.9146 -13.0325 -16.2587 --10.6057 -13.8974 -16.3649 --10.8372 -14.4831 -17.0462 --11.2188 -14.8348 -16.1724 --10.2172 -15.049 -16.3378 --10.8489 -15.8083 -16.2124 --9.85519 -16.0638 -16.0433 --10.2058 -16.397 -16.9697 --9.62492 -16.6674 -17.7259 --10.1849 -17.3305 -18.1245 --10.9986 -17.3823 -17.6896 --11.3662 -18.2407 -17.4881 --11.0273 -18.9244 -18.0492 --11.0603 -19.6772 -18.8003 --11.5854 -18.9175 -19.0661 --11.9465 -18.1179 -19.5735 --12.8502 -18.5852 -19.6673 --13.1274 -19.088 -20.494 --12.197 -19.0963 -20.8327 --12.2563 -19.1466 -21.7571 --13.2369 -19.3521 -21.5272 --13.8103 -18.5038 -21.3311 --14.5356 -18.2965 -20.5985 --15.1848 -17.6052 -20.0506 --14.8239 -16.6701 -20.3268 --14.1033 -16.2457 -20.9824 --13.2401 -16.7411 -20.657 --12.627 -17.4479 -21.0642 --11.8263 -16.9119 -21.0936 --11.5197 -16.4287 -20.288 --11.6535 -16.0086 -19.376 --11.7489 -15.2834 -18.7189 --12.1331 -15.2745 -17.8372 --12.2903 -16.2515 -17.9644 --12.9814 -16.7264 -17.514 --13.0333 -17.1588 -18.439 --14.0184 -17.1719 -18.5373 --14.7544 -16.908 -17.9016 --14.8533 -15.964 -18.184 --14.826 -15.8356 -19.1917 --15.7045 -15.5277 -18.6911 --16.3744 -16.1893 -19.0611 --16.776 -15.2847 -19.0082 --17.7545 -15.1423 -18.7838 --17.7277 -16.0312 -19.4009 --17.9042 -16.4322 -18.4703 --17.2116 -16.998 -18.9338 --17.6802 -17.6253 -18.1128 --16.9745 -18.1328 -18.5971 --16.4433 -18.6425 -19.2914 --15.4377 -18.6692 -19.4296 --14.7674 -18.4243 -18.8975 --14.5228 -19.0951 -18.1961 --14.7329 -19.9717 -17.8333 --14.0695 -20.7735 -17.9565 --13.3399 -20.6653 -18.6363 --12.629 -20.7882 -19.2631 --12.2893 -21.5956 -18.8069 --11.7562 -22.048 -19.4283 --10.8218 -21.8121 -19.2284 --11.2006 -22.3236 -18.4921 --10.8605 -23.2807 -18.4616 --11.0438 -23.2465 -17.5154 --10.1447 -23.7339 -17.2669 --10.1174 -24.6576 -17.7591 --10.1368 -25.3685 -17.0801 --9.80921 -25.948 -17.8341 --10.2857 -25.9039 -18.7991 --10.0383 -26.4361 -19.6339 --10.2149 -27.4079 -19.7616 --10.3183 -27.6561 -20.7083 --9.93609 -26.863 -21.3011 --10.5832 -26.7039 -21.9898 --10.1675 -27.4405 -22.5215 --9.42454 -27.2819 -23.128 --9.02843 -26.3164 -23.2329 --8.19959 -26.3195 -23.8604 --7.80053 -27.2687 -23.8743 --6.90713 -27.2434 -23.3877 --6.33111 -26.51 -23.1964 --5.91638 -26.6538 -24.095 --4.97258 -26.8027 -24.4736 --5.14478 -26.1154 -25.1026 --5.74796 -25.6135 -25.7404 --6.38135 -25.3884 -25.0036 --6.99438 -25.7777 -24.3663 --7.569 -25.1202 -23.8671 --7.50582 -25.0406 -22.8466 --7.06757 -24.3008 -22.4375 --7.7724 -23.6096 -22.846 --8.43662 -23.0827 -22.3599 --7.5651 -22.5206 -22.3276 --7.85807 -21.6609 -22.8034 --8.4573 -22.1271 -23.4982 --8.88454 -21.6314 -24.289 --8.63844 -21.6618 -25.219 --8.92629 -21.0921 -25.8417 --8.35122 -20.5166 -25.1893 --8.79993 -19.933 -25.9171 --9.7027 -20.0921 -26.2541 --9.15336 -19.3776 -26.7891 --10.0703 -18.8247 -26.704 --9.90905 -17.8347 -26.7587 --10.0786 -17.1013 -26.0738 --10.9556 -17.372 -26.46 --11.0137 -18.399 -26.4154 --11.6348 -17.9433 -25.8149 --11.3579 -18.3975 -24.9092 --11.6209 -18.0015 -24.0039 --11.4419 -17.0411 -23.8736 --11.6284 -16.8039 -22.9324 --12.4082 -16.2075 -23.0937 --13.0548 -15.4938 -23.3725 --13.2049 -15.0113 -24.2062 --13.6973 -15.0368 -25.014 --14.6789 -15.1566 -25.3352 --15.5415 -14.9525 -25.7997 --15.7751 -15.1291 -24.8546 --16.5565 -15.6308 -24.5283 --16.368 -14.8273 -24.1374 --16.4674 -14.2102 -24.9443 --16.8044 -13.4864 -25.5631 --16.0429 -13.1669 -26.1445 --15.2953 -13.3341 -26.7942 --15.9108 -13.9484 -27.1894 --15.6724 -14.4617 -27.9953 --15.7825 -15.3304 -28.5358 --15.6842 -16.3296 -28.5025 --15.1035 -17.1332 -28.6942 --14.1605 -16.9116 -28.6701 --14.4656 -16.6388 -27.7614 --14.689 -15.8426 -27.2342 --14.2976 -14.9757 -27.4534 --14.0842 -14.4756 -28.2207 --13.4945 -13.7708 -28.6459 --13.4735 -13.4505 -27.7187 --12.6599 -12.8717 -27.4407 --12.7948 -11.8468 -27.3905 --12.7848 -11.1497 -26.7065 --12.0595 -10.6263 -26.2617 --12.6869 -9.83537 -26.6699 --13.4122 -10.4094 -27.028 --14.1663 -9.81212 -26.579 --14.3536 -9.50697 -27.4693 --14.6716 -9.11668 -28.3042 --14.7923 -8.5039 -27.5599 --14.9051 -7.50686 -27.5441 --14.1482 -6.94791 -27.8635 --14.616 -6.27409 -27.2133 --14.1486 -6.89672 -26.565 --14.6569 -6.13766 -26.0899 --14.7654 -6.3968 -25.0808 --15.7628 -6.24432 -24.8097 --15.5878 -6.3935 -23.8356 --15.3178 -5.93791 -22.9421 --15.3656 -6.90606 -22.4681 --15.2553 -6.08715 -21.8972 --14.4223 -6.15862 -21.4061 --14.0994 -6.56181 -20.5334 --13.348 -6.93713 -20.0726 --13.5576 -6.61046 -19.1416 --13.1043 -7.27828 -18.5499 --12.1566 -7.03705 -18.8316 --11.395 -7.56029 -18.8414 --11.7928 -8.27816 -19.414 --12.2617 -8.50337 -20.3418 --13.1256 -9.02593 -20.1807 --13.0082 -9.94551 -19.8718 --13.219 -10.4832 -20.6645 --12.3434 -10.4363 -21.1408 --12.9622 -10.6597 -21.9447 --13.7835 -10.2182 -21.4535 --14.0922 -10.6224 -22.3488 --13.6663 -10.0081 -23.011 --14.2928 -9.28981 -22.7864 --14.622 -9.32766 -21.9654 --15.4609 -9.08563 -21.5394 --14.9906 -9.81174 -21.1056 --15.4468 -10.5336 -20.6228 --16.2313 -10.3123 -20.0868 --16.2319 -11.2729 -19.7649 --16.6859 -11.8916 -19.075 --16.927 -12.6145 -19.7155 --16.9531 -12.6272 -20.6408 --17.7344 -13.2578 -20.7883 --17.913 -12.7064 -21.6 --18.1478 -12.1159 -22.2931 --18.3638 -12.2596 -23.2903 --17.5398 -12.9241 -23.3422 --16.9219 -13.1488 -24.1986 --16.1453 -12.6816 -24.5282 --16.3012 -12.074 -25.3338 --17.1682 -11.5657 -25.2574 --16.7827 -11.3992 -24.2995 --16.805 -10.595 -23.7472 --16.979 -9.58756 -23.965 --17.9801 -9.79447 -23.9992 --18.737 -9.49676 -23.4689 --19.0239 -9.85684 -24.2792 --19.9232 -9.75607 -24.5774 --19.5831 -8.98415 -24.1508 --19.661 -8.17299 -23.6346 --19.6673 -7.59271 -22.7604 --18.8197 -8.17047 -22.5428 --19.6021 -8.47157 -21.9552 --20.0924 -8.69936 -21.1547 --20.9299 -8.69453 -21.7166 --21.9047 -8.83814 -21.4422 --22.3431 -9.27505 -22.3534 --21.7135 -9.63038 -23.0562 --21.8332 -10.2509 -23.8659 --22.1553 -10.8092 -23.0941 --22.8502 -10.6125 -22.494 --22.6154 -11.4535 -22.0124 --23.3619 -10.8822 -21.6113 --23.765 -11.3014 -20.8108 --24.6639 -11.7307 -20.813 --25.428 -11.6074 -21.4888 --26.3955 -11.5971 -21.8206 --26.1523 -11.7281 -22.7716 --27.0179 -11.3426 -23.0669 --26.9634 -10.5784 -22.413 --27.2861 -10.2866 -21.4654 --26.8363 -10.5299 -20.6647 --26.9097 -9.50756 -20.3791 --27.1278 -9.46589 -19.3715 --26.1943 -9.86101 -19.3362 --25.3057 -10.0108 -18.8345 --24.5033 -9.47037 -18.7209 --23.8669 -9.20356 -17.988 --24.7462 -8.80105 -17.6871 --25.5896 -9.22855 -17.351 --26.3723 -9.84887 -17.4124 --27.2702 -9.56371 -17.1608 --26.8104 -9.13884 -16.4298 --26.4391 -8.22466 -16.5798 --26.0149 -7.63125 -17.3873 --25.2429 -7.22345 -17.9171 --25.8362 -6.4754 -17.7596 --26.5077 -5.83769 -18.1638 --26.6268 -5.49826 -17.306 --25.9928 -4.83091 -17.7257 --25.1021 -4.45143 -17.7666 --25.5345 -4.48399 -16.7905 --24.7297 -3.9345 -16.8356 --24.7742 -3.82918 -15.8465 --24.6254 -2.93259 -16.1992 --24.7703 -2.64016 -15.2466 --24.6812 -2.11847 -14.4597 --24.0577 -1.35656 -14.6875 --23.7904 -0.4241431 -14.3231 --24.802 -0.5568621 -14.1906 --24.8938 0.4312349 -14.0624 --24.6982 0.7391499 -15.0138 --24.9986 1.6236 -14.944 --24.6976 2.40228 -15.4138 --23.8533 2.69883 -15.8672 --23.7851 3.32391 -16.6237 --23.3411 4.20477 -16.2493 --23.3219 5.18447 -15.9339 --22.608 4.99619 -15.3013 --21.6307 5.18695 -15.362 --21.1308 4.44205 -15.9118 --20.4701 4.49724 -16.6185 --19.769 3.9079 -16.1106 --20.1534 4.53928 -15.4809 --20.6205 4.81307 -14.5678 --21.4559 4.31778 -14.3558 --21.6635 3.67587 -13.6851 --22.2405 4.28041 -13.0975 --21.4879 4.08964 -12.4742 --21.1296 4.57688 -11.6783 --20.662 5.07129 -10.9763 --20.2084 5.91874 -11.1884 --19.9313 6.56748 -11.9144 --18.9791 6.35055 -12.1642 --19.4377 6.15448 -13.0086 --19.7982 6.70833 -13.7665 --19.5021 6.46394 -14.6596 --19.4139 5.94214 -15.4647 --20.178 6.35365 -15.928 --19.795 6.64048 -16.793 --20.5339 7.19839 -16.3763 --20.5668 8.23986 -16.2179 --21.0929 8.55873 -16.9661 --21.056 7.74213 -17.3765 --20.9171 6.99574 -18.0718 --20.3917 6.92095 -18.8965 --20.8656 6.54506 -19.7222 --20.7711 5.60833 -19.1868 --20.7956 4.66396 -19.3591 --19.9716 4.56344 -19.8737 --19.6444 3.92357 -20.6074 --20.5338 3.43975 -20.5846 --21.4432 3.0486 -20.9315 --21.9362 2.22176 -21.287 --22.7181 2.16909 -20.7533 --23.0335 2.12704 -21.7015 --22.7943 2.67014 -22.4827 --22.9792 2.8159 -23.5227 --22.6925 3.59502 -24.0588 --22.8564 3.99286 -23.1812 --23.726 3.97733 -22.7053 --23.9585 3.83454 -21.7641 --24.0741 4.63336 -21.1917 --23.4344 5.28648 -20.9849 --23.7612 5.58345 -20.0874 --23.7479 5.41741 -19.0851 --23.4083 6.37706 -18.8143 --22.7578 6.67618 -19.5322 --21.8896 7.08915 -19.2707 --20.9839 7.65923 -19.0314 --21.5056 8.22228 -18.3895 --21.8358 8.83121 -19.1545 --21.2657 8.81304 -20.0608 --20.3734 8.39484 -20.1079 --19.7451 8.80868 -20.787 --19.0078 9.34739 -20.8615 --18.7619 8.46071 -20.5085 --17.9873 8.51751 -21.1658 --17.9238 8.74931 -20.1631 --17.2434 9.17322 -20.8133 --17.1305 10.1747 -21.1052 --17.0711 10.7663 -21.929 --17.5075 9.98531 -22.3012 --17.918 9.26831 -22.7477 --18.7558 9.20298 -22.2065 --19.1259 8.47773 -22.8261 --19.0572 8.05679 -21.9958 --20.0142 7.83867 -21.8946 --20.6482 7.64938 -21.2025 --20.2936 6.82961 -21.1186 --19.5893 6.13442 -21.1855 --19.04 6.04146 -20.3806 --19.4064 5.40523 -19.7357 --18.9285 4.68237 -19.2603 --18.772 3.79084 -19.6315 --18.0238 4.43963 -19.8776 --17.4981 5.18689 -20.2765 --17.89 5.51775 -19.3983 --17.942 5.70685 -18.4713 --17.2388 6.3046 -18.0663 --17.1559 6.21823 -17.0456 --17.2415 6.62675 -16.1622 --16.65 6.24993 -15.4811 --15.8966 6.38638 -14.9041 --16.4956 7.26601 -14.838 --16.0754 8.17824 -14.8899 --16.1052 9.10075 -14.47 --15.2787 9.39428 -14.9988 --14.9405 9.86576 -14.1468 --15.1263 8.89361 -13.8579 --15.9627 8.79518 -13.2699 --16.6798 9.55212 -13.163 --17.1898 8.98911 -12.4809 --17.1412 9.8857 -12.0061 --18.0456 10.317 -12.2285 --18.6096 9.76251 -11.6178 --19.0585 9.07654 -12.1971 --18.278 8.73176 -12.724 --18.695 8.32951 -13.5667 --19.0279 7.75703 -14.2889 --19.7668 7.94318 -13.6453 --20.5726 7.8482 -13.129 --20.7747 7.83359 -12.1195 --21.5301 7.25414 -12.4182 --22.0507 6.63895 -11.8524 --22.0171 5.62346 -11.895 --22.8515 5.53636 -11.36 --23.1795 6.08835 -10.6236 --22.3673 6.622 -10.9429 --22.0987 7.50637 -10.4896 --22.4583 8.10702 -11.1537 --22.7733 7.4989 -11.8112 --23.7553 7.59364 -12.1028 --24.5385 7.1427 -11.673 --24.3001 7.24374 -10.7504 --24.3823 6.24303 -10.5902 --24.3256 5.28909 -10.4381 --24.6278 5.2566 -9.50308 --25.0899 4.5231 -9.00025 --26.1056 4.66216 -8.87191 --26.6834 4.23712 -9.61109 --27.0522 3.31012 -9.78979 --27.9259 3.47677 -10.1329 --28.8256 3.79478 -10.3104 --28.1853 4.58276 -10.4422 --29.0781 4.56081 -10.9264 --29.7343 4.09637 -11.6223 --29.8645 3.72661 -12.5412 --29.7336 3.17144 -13.3467 --28.8486 3.44988 -13.4144 --28.5823 2.96183 -14.2219 --27.7376 3.34989 -14.5927 --27.6846 4.39072 -14.5662 --26.8557 4.16152 -15.0154 --26.5218 3.40354 -15.4882 --26.9212 2.46093 -15.5852 --27.496 3.02821 -16.2372 --27.7631 3.9375 -16.4835 --28.3034 3.27866 -16.9815 --28.2603 2.34972 -16.6939 --27.8125 1.46746 -16.3593 --27.4149 1.39644 -15.3669 --27.6637 0.5254449 -15.8203 --27.4521 -0.2563051 -15.2981 --27.7041 -0.9512541 -15.9006 --27.6664 -0.9592731 -16.915 --27.2367 -0.3411821 -17.5441 --26.3403 0.03254033 -17.7512 --25.9827 -0.2765251 -18.6375 --25.9752 -0.06560697 -19.6272 --25.3768 -0.7243281 -19.9732 --25.8154 -0.3620421 -20.8284 --26.7138 -0.8464161 -20.6495 --26.7656 -1.71176 -21.1843 --26.5685 -2.16539 -20.322 --27.4715 -1.9368 -20.1124 --26.7582 -1.40019 -19.5209 --26.121 -1.39179 -18.7612 --26.7149 -1.95044 -18.142 --26.6465 -2.99615 -18.118 --26.5038 -3.00839 -17.0949 --26.0992 -2.25647 -16.57 --26.9217 -2.3942 -16.0472 --27.8172 -1.9629 -15.9825 --27.691 -2.67278 -15.3286 --28.5206 -2.98813 -14.9819 --28.3923 -3.03196 -13.9708 --29.0072 -2.29396 -14.0407 --29.1756 -2.43888 -13.0812 --29.652 -2.95745 -12.3988 --30.3465 -2.22577 -12.6085 --30.6343 -2.90817 -11.9464 --30.9873 -2.33286 -11.1772 --30.2171 -1.90371 -10.6774 --29.4698 -1.96255 -9.99046 --28.8714 -2.12037 -9.21182 --29.2458 -2.98706 -9.12135 --28.3165 -2.8964 -8.71837 --27.6719 -3.56916 -8.84936 --27.5315 -4.51781 -8.43869 --28.1978 -4.39197 -9.03523 --28.3224 -4.20856 -9.91141 --29.2247 -3.83851 -9.66929 --30.1615 -4.00294 -10.0349 --30.5792 -3.70021 -9.1717 --29.9744 -3.81461 -8.39494 --29.6471 -4.84823 -8.2906 --29.3276 -5.29837 -7.52392 --28.7411 -5.98852 -8.06335 --28.1203 -6.68548 -8.38002 --27.5502 -7.33137 -7.90733 --26.9833 -7.69181 -7.17488 --27.1692 -6.68796 -7.09935 --27.5463 -6.77892 -6.15545 --27.0843 -5.90896 -5.99587 --26.8035 -4.99696 -6.06111 --25.9209 -4.48508 -5.91199 --24.9408 -4.32956 -5.63025 --24.6067 -3.66141 -6.28557 --24.5375 -3.25885 -7.18129 --24.1135 -3.36204 -8.14449 --23.2281 -3.74447 -8.26723 --22.9438 -3.54474 -7.33406 --22.0956 -4.11682 -7.34574 --22.6368 -4.70593 -6.84575 --22.7251 -4.37976 -5.92943 --22.1072 -3.75443 -5.37541 --21.5451 -4.26216 -4.73994 --21.8676 -4.04217 -3.80814 --21.3239 -4.83183 -3.50418 --21.4021 -5.06487 -2.59724 --22.1271 -5.70024 -2.2488 --22.6547 -4.9874 -2.31272 --22.934 -5.67918 -2.94661 --23.6816 -5.95824 -3.5562 --23.784 -5.06972 -4.01338 --23.7705 -4.99249 -2.98449 --24.174 -5.50145 -2.22744 --24.5148 -6.23584 -2.78629 --23.6336 -6.63795 -2.80965 --23.7408 -7.18242 -1.97279 --23.5637 -8.16293 -1.6422 --23.1248 -8.71743 -0.9636129 --22.7494 -9.34704 -1.68109 --21.7475 -9.22428 -1.52062 --21.8432 -9.58775 -0.5700019 --21.0993 -10.2084 -0.4303749 --20.1693 -10.102 -0.4862069 --19.442 -10.1163 -1.1543 --19.5984 -9.30872 -1.72092 --19.78 -8.94724 -0.7901939 --19.219 -8.30481 -1.30817 --18.8594 -8.42836 -2.167 --19.8349 -8.32685 -2.29785 --20.0504 -9.20156 -2.72843 --20.5851 -10.0627 -2.44479 --20.5687 -10.9643 -2.03752 --21.5718 -10.9278 -1.89905 --21.518 -11.2736 -0.9153659 --21.4069 -11.7994 -1.71363 --21.969 -12.5137 -1.27429 --22.8333 -12.1605 -1.45836 --23.7243 -12.6779 -1.65155 --23.6564 -13.7049 -1.7039 --23.604 -13.7172 -0.7090639 --23.4119 -14.3982 0.02548502 --24.3577 -14.3871 0.03944372 --24.4985 -14.5549 -0.9035829 --24.8444 -15.431 -0.4577419 --25.6475 -14.8906 -0.7021109 --25.9562 -14.0475 -1.26335 --26.7976 -13.5948 -1.59723 --27.2995 -14.1695 -2.30216 --27.7743 -14.7383 -3.03548 --28.0544 -15.5547 -2.54447 --27.8334 -16.1241 -1.81521 --27.5888 -16.135 -0.8802419 --26.9404 -15.3167 -0.7427449 --26.8653 -15.9364 0.08066272 --26.0706 -15.4556 0.4948221 --25.6067 -14.7679 0.9731351 --25.4462 -13.9545 1.58306 --25.0399 -13.1577 1.15769 --25.2672 -12.3348 0.6995141 --25.7869 -12.5659 1.52162 --26.0478 -11.7249 2.06 --25.1009 -11.8928 2.09528 --25.3837 -11.3155 2.88302 --25.3943 -11.1769 3.89573 --24.4795 -10.9497 4.38772 --24.5039 -9.99064 4.14349 --25.3949 -10.0779 4.61474 --26.1865 -10.3106 5.23337 --26.0977 -9.61525 5.97599 --25.178 -9.67518 6.11553 --24.461 -9.7104 5.39108 --23.7357 -10.2595 5.78088 --23.9504 -11.1859 5.45311 --24.1436 -12.2091 5.45513 --24.1344 -13.1178 5.83205 --24.216 -13.3321 6.78767 --24.5114 -14.3347 6.60887 --23.565 -14.3017 6.33314 --23.4666 -14.9382 5.59089 --22.5205 -15.1254 5.69376 --21.9518 -15.2936 4.86378 --21.0152 -15.6423 4.63879 --20.8048 -14.8924 4.11101 --20.8347 -14.0539 4.67221 --20.7715 -14.5242 5.52782 --20.0098 -15.1266 5.34222 --19.4278 -16.0094 5.46612 --19.2671 -16.9669 5.72791 --18.8841 -16.6071 6.53155 --18.7367 -17.2537 7.29884 --18.4041 -17.4589 8.27543 --18.7058 -17.7103 9.19448 --19.2236 -18.1289 9.89915 --18.6684 -18.0592 10.7555 --18.3369 -17.5656 11.5327 --19.0581 -17.4156 12.2669 --18.7819 -18.0584 13.0634 --17.929 -18.373 13.5768 --17.3029 -17.7252 13.0988 --17.9428 -17.306 13.7603 --17.9521 -16.4526 14.2408 --17.2988 -16.143 13.6366 --16.3052 -15.8037 13.5681 --15.5476 -15.1807 13.5569 --15.9253 -14.9494 12.5818 --16.2534 -14.3944 11.8909 --16.8939 -13.6725 11.7425 --17.7469 -14.2887 11.7164 --18.7794 -14.1501 11.7972 --18.6372 -13.4653 12.5188 --19.3636 -13.1087 12.0196 --20.3571 -13.0839 11.9352 --21.1263 -13.6909 12.1855 --21.8292 -13.0317 12.0364 --21.8385 -13.6053 11.1961 --21.5903 -14.4481 10.715 --20.8676 -14.9772 10.9795 --21.1673 -15.4593 10.1499 --20.9148 -16.2147 9.59287 --20.8382 -16.6032 10.5589 --20.6283 -16.3808 11.4997 --21.3657 -16.1675 12.1776 --20.8605 -16.8955 12.6522 --21.0447 -17.8908 12.9839 --21.3973 -18.5855 12.2955 --20.6589 -18.279 11.6545 --19.8586 -18.8825 11.7498 --18.9661 -18.6813 11.4107 --18.7595 -19.2177 12.1729 --18.5484 -19.8531 12.905 --19.5634 -19.9964 13.0224 --20.3051 -20.6907 12.939 --19.7244 -21.5264 12.9207 --18.9719 -21.3214 13.5234 --18.4637 -21.9871 14.0377 --17.8017 -22.3104 13.5105 --17.3343 -21.4535 13.5202 --16.3115 -21.4311 13.3609 --16.6297 -21.852 12.5159 --15.9962 -21.0336 12.4124 --15.0484 -20.7638 12.5325 --14.0627 -20.6744 12.6968 --13.8441 -20.0664 13.4683 --13.104 -20.5765 13.0934 --12.1883 -20.3204 13.4098 --11.5591 -20.3789 14.1527 --11.2895 -21.3743 14.0379 --11.9626 -21.2837 14.7753 --11.4696 -22.1592 14.6469 --10.9447 -22.0515 15.4943 --10.5079 -22.9447 15.2828 --10.7278 -23.796 14.8563 --10.7421 -24.6517 14.3642 --11.1529 -24.0305 13.6006 --11.5962 -23.4798 14.2489 --12.299 -23.211 14.8693 --13.1839 -22.7269 15.0591 --13.2492 -22.8073 16.0282 --12.8923 -22.2384 16.7674 --13.012 -21.2766 16.393 --13.9915 -21.6347 16.2412 --13.6089 -21.1342 15.5023 --13.1324 -21.0067 14.5818 --12.7497 -20.4532 15.3168 --12.2761 -19.6925 14.8657 --12.0728 -19.1457 15.6102 --12.9825 -19.4205 15.4093 --13.9045 -19.4558 15.8422 --14.7193 -19.7738 16.4446 --14.2653 -19.4316 17.254 --15.1146 -18.9917 17.728 --15.5661 -19.5924 17.1626 --16.3288 -20.1362 17.5054 --16.994 -20.8572 17.4288 --17.4274 -20.8904 16.5199 --17.6577 -19.9385 16.5808 --18.6032 -19.6533 16.3646 --19.5205 -19.5256 15.9222 --18.8349 -19.2105 15.1948 --19.2482 -19.1882 14.3209 --20.1591 -18.7486 14.4798 --20.3373 -19.7321 14.5778 --20.6573 -19.7873 15.5689 --20.8237 -20.7689 15.5374 --21.5217 -21.3051 15.2584 --21.9278 -22.1577 14.8761 --22.6444 -21.4355 15.2531 --23.1584 -21.0337 16.0264 --23.0232 -20.8485 16.95 --23.6428 -20.0754 16.7791 --24.4553 -20.3345 16.2629 --24.9368 -19.5604 16.5357 --24.4211 -18.7356 16.6847 --25.2904 -18.2277 16.8456 --25.4538 -17.26 16.5058 --26.171 -16.9013 15.876 --25.7376 -15.9631 15.9395 --26.1431 -15.6236 15.1244 --26.0883 -15.0571 14.3439 --26.3336 -14.0926 14.1812 --26.2734 -14.1292 13.2455 --25.4074 -13.7129 13.3116 --26.1322 -13.1317 13.5918 --27.0469 -13.4303 13.2943 --27.9957 -13.191 13.6699 --28.0827 -12.9088 14.5878 --27.2764 -12.4171 15.0245 --27.3657 -11.5363 15.5231 --26.6972 -11.2559 16.2733 --26.6698 -12.2093 16.1537 --26.1697 -12.219 15.3311 --26.4021 -12.0994 14.3754 --26.1615 -11.679 13.436 --25.5072 -11.8015 12.7364 --24.6673 -12.06 12.2173 --23.7025 -11.6135 12.1575 --23.285 -10.9902 11.5062 --23.1126 -11.5867 10.7076 --23.5537 -12.5054 10.9306 --23.8663 -13.5064 10.8958 --24.5095 -14.303 10.9756 --23.9126 -14.7005 11.7059 --23.3533 -15.5691 11.7906 --22.7966 -15.6796 12.5884 --22 -15.4936 13.1441 --22.8068 -15.4745 13.7714 --22.5884 -15.9992 14.6084 --22.1379 -16.8288 14.7241 --21.5285 -16.7903 15.4752 --20.6366 -16.747 16.0173 --20.0355 -16.2817 16.634 --19.0982 -16.565 16.6498 --18.5463 -17.0372 17.2952 --18.2818 -18.0402 17.5299 --17.737 -17.8907 16.7918 --16.7876 -18.1121 16.7343 --16.4419 -18.964 17.2723 --16.2805 -18.551 18.1721 --16.8584 -19.2654 18.2119 --17.3122 -20.1372 18.3085 --18.2512 -19.9257 18.5022 --18.7986 -19.3183 19.1464 --19.5851 -19.0391 19.6614 --20.3504 -19.4437 20.1835 --20.5525 -18.6696 20.6966 --21.2067 -18.5027 20.0739 --20.797 -17.8698 19.3874 --21.5811 -18.0503 18.7517 --22.4921 -17.707 18.7149 --22.4027 -18.1117 19.5833 --22.6112 -17.3828 20.2676 --21.7865 -16.9157 20.3254 --21.5787 -17.4157 21.1869 --21.5131 -17.4152 22.1062 --22.3403 -16.8677 22.1879 --21.7466 -16.014 22.1118 --22.0557 -15.4338 22.8854 --21.994 -14.4361 23.1085 --21.4903 -13.9457 22.4406 --20.4903 -14.012 22.0919 --20.0846 -13.4732 21.3579 --19.4658 -13.2444 20.5956 --18.9733 -12.4195 20.5214 --18.6361 -11.7144 21.15 --18.6892 -10.8799 20.6117 --17.7894 -10.4831 20.4078 --17.6217 -10.3245 19.4129 --18.5027 -10.2979 18.8875 --17.9305 -11.0514 18.465 --17.6904 -11.5552 19.2858 --18.4133 -12.2878 19.4562 --17.8725 -12.7589 20.0785 --17.4596 -13.2801 20.9618 --18.1337 -13.6603 21.5942 --18.3444 -14.6398 21.6665 --18.2308 -15.501 21.2293 --17.3258 -15.1668 20.9423 --16.9849 -14.3486 20.596 --17.3797 -13.8064 19.8859 --16.6583 -13.2558 19.8958 --16.0322 -13.4125 19.1404 --15.3341 -12.6801 19.0193 --15.4397 -13.3465 18.1972 --14.5927 -13.7878 18.2811 --13.781 -14.3821 18.1964 --13.3763 -15.1586 17.7349 --14.0932 -15.6389 17.2564 --13.9407 -16.185 18.1581 --14.2897 -17.0431 17.9353 --14.8107 -17.1079 17.0567 --14.9836 -16.4462 16.384 --15.1414 -17.1592 15.7517 --15.8036 -17.2972 14.9962 --16.0969 -16.4274 14.6547 --15.514 -16.9957 14.0159 --14.8127 -17.4236 14.5469 --14.55 -18.3656 14.3801 --14.4733 -19.2259 14.7652 --15.4649 -19.064 14.6034 --15.6662 -18.8711 13.6296 --15.9454 -19.7936 14.0393 --15.6533 -20.5896 14.4661 --15.4067 -21.2956 15.1713 --15.6371 -22.186 15.6411 --15.2899 -23.0906 15.668 --15.0702 -22.9481 14.7001 --15.8364 -23.0486 14.0812 --16.8405 -22.729 14.0058 --17.3164 -23.213 13.2862 --18.142 -23.5531 12.9598 --19.063 -24.0638 12.819 --18.926 -24.9774 12.3338 --17.9582 -24.7229 12.0608 --16.9392 -24.7838 11.8896 --16.8896 -24.1334 12.6942 --16.9457 -23.6763 11.7814 --16.7802 -24.1677 10.9519 --16.553 -24.1677 9.96368 --16.867 -24.2428 9.03106 --15.9881 -23.8607 8.73761 --16.152 -24.4616 8.03724 --16.3945 -23.8817 7.24581 --16.7537 -24.1899 6.33066 --17.4032 -23.4182 6.5211 --17.406 -22.5961 7.12925 --16.5341 -22.4752 6.7605 --16.8892 -22.6667 5.87923 --17.3553 -22.4494 4.98818 --18.0102 -22.6108 4.21594 --17.2798 -23.1635 3.77436 --16.6265 -23.8049 4.17177 --16.505 -24.2144 5.04199 --15.9567 -24.8943 5.4971 --15.347 -25.3652 6.20004 --15.0025 -24.5023 6.52599 --14.2681 -24.1568 6.01331 --13.3886 -24.5329 6.25802 --13.2841 -25.3968 5.79701 --12.5842 -25.9677 5.29897 --11.9655 -26.1404 6.01336 --11.7533 -26.9817 6.44744 --11.5911 -27.9659 6.59363 --12.2713 -28.4011 7.19685 --13.0167 -28.2581 6.48996 --13.4544 -27.3787 6.65791 --14.3005 -26.8613 6.58845 --14.3922 -26.0477 7.06044 --14.0706 -25.6242 7.78914 --13.465 -26.3361 7.42795 --13.2916 -26.7711 8.32618 --13.2629 -27.4941 9.00212 --12.8385 -28.2732 9.32759 --12.0129 -28.0631 9.8657 --12.4833 -28.4626 10.6264 --12.4033 -29.2338 11.2593 --11.7663 -29.0647 12.0628 --11.0853 -28.3129 12.1202 --11.4432 -28.4734 13.0569 --11.8124 -27.7118 12.4426 --11.3759 -26.9726 13.0097 --10.7024 -26.2411 12.7046 --10.1676 -27.0021 12.3404 --9.33749 -26.8593 12.8543 --8.68249 -27.4808 12.3361 --7.72813 -27.4037 12.543 --7.70318 -26.5052 13.1014 --7.47899 -26.3807 12.0972 --7.94657 -25.5057 12.306 --7.99804 -24.7211 12.9444 --7.06884 -24.3353 13.0986 --7.52057 -23.5684 13.4719 --6.4991 -23.3537 13.4791 --5.67189 -23.5212 12.927 --5.41447 -24.1764 12.2397 --6.12909 -24.6829 11.9207 --6.73531 -25.0746 11.2408 --7.28631 -25.5997 10.5006 --7.61487 -26.1817 9.72923 --7.78173 -25.2934 9.26495 --6.99246 -24.8107 9.08603 --6.62649 -24.1273 9.64255 --5.68124 -24.193 9.48956 --4.83651 -24.0197 9.11793 --4.61761 -24.5427 8.33205 --4.11979 -24.9814 7.58152 --4.15021 -25.6946 6.91754 --5.03723 -26.1731 6.9267 --5.47597 -27.0965 6.88921 --4.99915 -27.4012 7.68266 --5.53606 -26.7236 8.19024 --6.54216 -26.9328 8.37616 --6.99211 -27.4364 7.71676 --7.38671 -28.3599 7.35999 --7.8555 -27.5988 6.95629 --8.35456 -26.8653 6.42789 --8.28665 -26.0962 5.80234 --9.23205 -26.4384 5.87059 --9.51788 -26.1555 6.81829 --9.07878 -26.6719 7.53198 --9.28952 -26.0168 8.26427 --9.65753 -25.2936 8.82026 --9.50596 -24.2894 8.49566 --8.83624 -24.4706 7.83024 --7.95976 -24.055 7.97713 --7.88607 -23.2767 7.33717 --7.42865 -22.7217 6.70699 --8.09596 -23.0572 6.00346 --8.95418 -23.473 6.39012 --9.3165 -24.2745 6.94998 --10.2881 -24.3344 6.97775 --10.7448 -25.1476 7.23885 --11.5631 -25.0172 6.8082 --12.2475 -24.3676 7.16706 --13.0819 -24.6389 7.5666 --14.0012 -24.3454 7.47721 --14.3827 -23.8045 8.26867 --14.0679 -24.0224 9.24947 --13.8202 -23.0809 9.06259 --13.4141 -22.1905 8.95065 --12.7452 -22.7677 8.52214 --11.8881 -22.2578 8.43814 --12.5483 -21.4479 8.46872 --12.851 -21.4677 7.49163 --12.9582 -20.536 7.69096 --13.825 -20.7836 7.25713 --14.2753 -20.2822 6.55418 --13.5163 -19.7728 6.68312 --12.7233 -19.3739 6.36414 --12.2661 -20.2379 6.45753 --11.5988 -19.9514 7.11634 --10.7939 -19.5645 7.50264 --10.1618 -20.1686 7.08363 --9.9247 -20.4212 6.18356 --10.2284 -19.5664 5.64438 --10.5442 -18.6805 5.09204 --10.1762 -18.2118 5.97434 --10.8134 -17.6876 6.54978 --11.2323 -16.7288 6.48077 --11.3677 -16.3823 7.35604 --11.1453 -16.7198 8.30394 --12.0877 -16.6145 7.9436 --12.9975 -16.6557 7.45222 --12.9982 -17.2788 8.20977 --13.5021 -17.6291 7.44686 --13.4891 -18.5064 7.05224 --14.1053 -17.9478 6.47906 --14.6324 -18.1926 5.67485 --15.5372 -18.696 5.69861 --15.6554 -17.7038 5.57472 --15.8988 -17.0734 6.30473 --15.2031 -16.5114 5.78592 --15.328 -16.5237 4.87456 --14.4384 -16.1358 4.979 --13.738 -16.281 5.7085 --13.1559 -15.553 5.9372 --14.107 -15.3993 6.05629 --14.5699 -15.0644 6.81135 --14.1732 -14.1299 6.98683 --13.9006 -14.8216 7.69782 --14.8362 -15.0377 7.73358 --15.2494 -15.8888 8.02317 --15.441 -16.023 7.08581 --16.2723 -16.1634 6.61066 --16.2955 -15.4056 5.97924 --16.152 -15.8768 5.0707 --17.1057 -15.7198 4.79409 --17.7617 -15.9428 5.45625 --18.0114 -16.286 4.60124 --17.1727 -16.8631 4.68151 --17.6949 -17.623 5.17391 --17.2023 -18.4895 5.26712 --17.047 -18.0075 6.11938 --17.9232 -18.2383 6.53618 --17.1476 -18.8953 6.88663 --17.9367 -18.8557 7.52722 --18.8318 -18.9422 7.14218 --19.7401 -19.3098 7.28826 --19.1996 -19.8847 7.9638 --18.5398 -20.3548 8.51733 --18.1975 -20.754 7.7049 --17.662 -21.0949 8.45369 --16.7077 -20.7471 8.66188 --16.2248 -21.3278 8.01383 --15.2823 -20.8271 8.07027 --14.8112 -19.9347 7.80203 --15.212 -18.994 8.21173 --15.3186 -18.6193 9.13512 --14.9647 -17.7391 9.35845 --15.2644 -18.0987 10.2124 --14.375 -18.3946 10.7023 --13.3405 -18.1941 10.8595 --12.6917 -18.8627 11.2491 --13.0693 -19.5194 10.5889 --13.2702 -20.422 10.9583 --12.5535 -20.6783 10.3192 --12.1998 -21.6036 10.7328 --12.5562 -22.3532 11.3133 --13.354 -22.4882 12.0326 --13.9429 -22.8689 12.7318 --13.0382 -23.2082 13.0815 --12.4436 -23.428 12.3464 --11.7385 -23.0571 11.6751 --11.4078 -22.9099 10.7626 --10.5413 -23.2801 11.1334 --10.2565 -24.2312 11.2577 --9.68239 -24.1788 12.0454 --10.3905 -23.4431 12.2075 --9.90236 -23.1593 13.028 --9.16788 -22.5631 13.2756 --9.15498 -21.6045 13.3775 --10.104 -21.3457 13.3369 --9.89748 -21.2044 14.3275 --9.23217 -20.4627 14.3614 --8.51968 -20.2167 15.0205 --7.68666 -20.3247 14.444 --7.92769 -20.3738 13.4745 --8.39157 -20.2988 12.5319 --8.83479 -19.4594 12.1655 --9.6842 -18.8926 11.9347 --10.2479 -19.4202 12.5913 --10.5801 -20.2817 12.907 --9.79529 -20.475 12.3211 --9.67152 -20.814 11.401 --9.00982 -20.3376 10.8706 --8.4768 -21.1685 10.6208 --7.67661 -21.0306 11.2776 --6.99726 -21.0987 11.9833 --6.53079 -21.9344 12.2905 --7.06129 -22.6589 11.8483 --7.50473 -23.1309 11.0706 --7.56649 -23.5013 10.1628 --8.16134 -22.7726 10.3414 --8.41355 -22.1358 9.63778 --7.63565 -22.068 9.02319 --7.02765 -21.8009 8.27645 --6.54382 -21.4861 7.44843 --6.56549 -20.6385 6.94967 --6.94432 -19.8355 7.3074 --7.21638 -19.9444 8.27236 --7.58838 -20.2023 9.16827 --8.4904 -20.4526 8.84445 --8.15222 -21.077 8.21029 --8.96232 -21.7121 8.00589 --9.52266 -22.4849 7.61783 --9.62458 -22.5674 6.63579 --10.018 -21.6277 6.55751 --10.616 -22.1384 7.2223 --11.2484 -22.0098 6.36159 --11.2696 -21.0791 5.91874 --12.1994 -21.4702 5.76509 --12.8321 -21.6355 4.97413 --13.1821 -21.5384 4.06886 --14.0043 -21.1221 3.71267 --13.7598 -20.6485 2.95362 --14.6706 -21.0981 2.80594 --15.3308 -21.0423 3.52278 --16.0334 -20.3948 3.16527 --15.6037 -20.7701 2.34816 --15.4398 -21.0736 1.37482 --14.5664 -20.7507 0.9463291 --14.2682 -20.8852 0.01858372 --13.5598 -21.3331 -0.5194279 --13.3889 -21.3806 -1.53008 --13.221 -20.4881 -1.12524 --13.3949 -19.7353 -1.7655 --12.4829 -20.0615 -2.02771 --12.6649 -19.8074 -2.93458 --12.7942 -20.3404 -3.8572 --12.9722 -19.3794 -3.84331 --13.776 -19.6413 -4.40887 --13.1151 -20.2232 -4.85247 --12.2432 -20.6669 -4.95343 --12.8731 -20.819 -5.68872 --12.8724 -20.5833 -6.65003 --12.1177 -20.7313 -7.23155 --11.9441 -19.7531 -7.05954 --11.224 -19.495 -7.71541 --10.856 -19.1028 -8.52595 --11.3479 -19.8051 -8.9675 --10.7873 -20.3108 -9.7458 --11.0878 -20.6928 -10.5823 --11.6754 -21.5731 -10.7885 --12.4922 -21.2441 -11.1545 --12.6379 -20.2787 -10.9958 --13.2944 -19.9427 -10.3066 --13.278 -19.0142 -10.4932 --12.8489 -18.325 -9.94689 --13.1326 -17.6801 -9.21585 --12.6 -16.8763 -9.5432 --12.5673 -16.5999 -10.4984 --12.3289 -16.7772 -11.4412 --11.6131 -16.0952 -11.3532 --11.9656 -15.3665 -10.8125 --12.2511 -14.9777 -9.96247 --13.0461 -15.0876 -9.38049 --13.8361 -15.1606 -8.79472 --14.1214 -14.8897 -7.90009 --14.5047 -15.2207 -7.13997 --14.8039 -16.0133 -6.65692 --13.8165 -16.0261 -6.58335 --13.7425 -16.9206 -6.17175 --13.8782 -17.721 -6.69159 --14.4253 -18.263 -7.3693 --14.7873 -19.2154 -7.64236 --14.4434 -19.1845 -6.64762 --15.3359 -18.5956 -6.70453 --16.1349 -19.0441 -7.17505 --16.7457 -18.9961 -7.89677 --16.503 -19.9239 -8.22841 --15.9415 -19.8744 -9.02668 --15.995 -20.8236 -9.17704 --15.5528 -21.0666 -10.0479 --14.7764 -21.6959 -10.0796 --14.0092 -22.3424 -10.0379 --14.7596 -22.7696 -9.46997 --14.4478 -23.6251 -9.09634 --13.909 -22.8932 -8.68726 --14.2586 -21.8985 -8.78402 --14.3306 -21.7199 -7.79238 --13.7608 -22.4404 -7.64928 --14.4073 -23.0971 -7.35915 --14.2086 -24.1782 -7.57188 --13.9273 -24.9503 -8.03676 --13.347 -24.4604 -8.61005 --13.0951 -23.6118 -9.09704 --12.5978 -22.8234 -9.49982 --12.1433 -22.1701 -8.9156 --12.5837 -21.4307 -9.39614 --13.4584 -21.1117 -9.06271 --12.8076 -20.6945 -8.41343 --12.5209 -21.6032 -8.07223 --12.0999 -22.0736 -7.26527 --12.0653 -23.0643 -7.17083 --11.101 -22.6429 -7.35272 --10.6343 -23.5125 -7.61482 --10.4575 -22.7285 -8.21005 --9.96988 -23.5058 -8.53786 --10.5366 -23.2984 -9.29094 --9.88833 -22.4993 -9.1612 --9.26189 -22.4335 -9.88935 --9.55457 -23.4853 -9.7156 --8.90766 -24.1433 -9.38025 --9.01619 -25.1001 -8.99852 --9.67157 -24.878 -9.71847 --9.82782 -24.8393 -10.6609 --9.44734 -24.0063 -11.1339 --10.3723 -23.7731 -11.5216 --11.2876 -23.3968 -11.4059 --11.531 -22.9328 -12.1825 --11.4163 -22.02 -12.5226 --10.4566 -22.3641 -12.6166 --10.6108 -21.3649 -12.8519 --11.1795 -20.8355 -13.5105 --10.9386 -20.3124 -12.7109 --11.1902 -19.4211 -13.0419 --10.9048 -18.526 -12.7767 --11.2434 -17.9221 -12.0505 --10.2955 -17.6203 -12.1797 --9.92415 -16.8283 -12.6878 --9.12948 -16.7316 -12.1084 --9.27972 -16.6311 -11.1319 --9.42417 -16.4717 -10.1605 --10.1302 -16.0325 -10.7755 --9.65797 -15.2152 -10.3101 --9.02813 -15.4776 -11.0147 --8.61998 -14.943 -11.8026 --8.14703 -14.9286 -10.914 --7.77494 -15.1843 -10.0007 --7.96588 -15.1283 -9.08874 --7.11457 -14.8896 -8.63949 --7.19579 -14.7987 -7.66504 --7.017 -14.6114 -6.74066 --6.35252 -15.3321 -6.56384 --5.61036 -15.9225 -6.27199 --5.99849 -16.353 -5.45015 --6.54826 -17.0565 -5.80272 --6.25956 -18.0303 -6.06956 --7.13261 -17.7163 -6.47061 --6.62804 -17.4804 -7.24971 --7.15244 -17.5008 -8.10202 --7.63518 -17.2121 -8.94411 --8.28479 -17.6428 -9.52161 --7.30211 -17.8117 -9.60037 --7.37105 -18.7661 -9.06496 --7.07755 -18.9179 -10.0825 --6.28563 -18.8405 -10.7027 --5.58628 -19.568 -11.0817 --5.79526 -20.4977 -10.8608 --6.27432 -20.409 -11.744 --7.24757 -20.6862 -12.018 --8.15805 -20.5775 -12.2194 --8.31647 -20.3899 -11.2231 --8.29053 -20.3758 -10.3001 --8.67418 -21.2769 -10.0863 --8.48523 -21.8136 -9.27615 --7.64932 -21.5046 -9.67972 --7.11744 -22.2369 -9.48083 --7.828 -22.848 -9.8071 --7.89367 -22.5407 -8.87451 --8.26425 -22.9456 -8.03499 --8.37579 -23.7695 -8.56829 --8.50131 -24.3071 -7.75776 --8.49888 -23.7913 -6.8924 --9.17588 -24.5362 -6.52647 --9.50766 -25.3503 -6.04282 --8.96764 -26.0578 -6.2432 --8.11769 -26.233 -6.75096 --7.10561 -26.2423 -6.81527 --6.76705 -25.4356 -7.14745 --7.40931 -24.844 -7.53426 --6.69106 -24.4561 -8.01994 --6.02256 -23.8157 -7.67025 --6.20572 -23.0797 -7.12119 --6.08308 -22.7013 -6.21072 --5.68986 -23.5723 -6.06144 --4.70475 -23.5465 -5.7099 --3.73891 -23.7694 -5.58015 --3.82096 -24.697 -5.15173 --3.18043 -25.1851 -5.79163 --3.22962 -26.014 -6.3186 --3.98791 -26.1603 -7.02967 --4.04843 -27.138 -7.27386 --3.73774 -27.3562 -8.26264 --2.93542 -27.4988 -7.53847 --2.15808 -27.4925 -6.85493 --1.43666 -27.2389 -7.52501 --1.13951 -26.643 -8.25546 --0.725724 -26.3944 -9.10349 --0.472588 -27.2314 -8.7066 -0.499898 -27.6188 -8.75347 -0.143184 -28.1725 -9.44328 -0.136604 -28.2008 -10.3848 --0.11103 -29.1345 -10.6821 --0.934206 -28.8613 -11.0161 --0.13751 -28.461 -11.4908 --0.981858 -28.3806 -12.0691 --1.13454 -27.3521 -12.084 --1.12787 -27.7758 -13.0637 --0.819436 -26.8047 -13.0455 --1.80558 -26.7112 -12.7577 --2.45577 -26.1518 -13.1337 --3.34388 -25.5549 -13.2242 --2.76254 -24.84 -13.6323 --3.24447 -24.0743 -14.0482 --3.79388 -23.4323 -13.5969 --4.59307 -22.9295 -13.2195 --3.94612 -22.1821 -13.0333 --3.36086 -21.5246 -12.4689 --3.86109 -21.0096 -13.2093 --4.74792 -20.6364 -13.1366 --5.74703 -20.6531 -13.24 --5.88603 -21.2075 -14.0374 --6.86543 -21.1261 -14.3301 --7.12213 -21.9691 -14.6901 --7.85535 -22.457 -15.211 --8.31898 -23.165 -14.7588 --8.9423 -23.5721 -14.0914 --9.42133 -22.7836 -13.924 --9.69196 -22.3709 -14.8085 --10.202 -21.5466 -14.5286 --10.0143 -20.8813 -15.2666 --10.3761 -20.4542 -16.1064 --10.9596 -20.2244 -15.3272 --10.3723 -19.401 -15.3935 --11.279 -19.1054 -15.2567 --11.936 -19.0337 -16.0444 --12.3857 -19.6689 -15.4527 --13.4088 -19.5879 -15.6301 --13.5709 -19.561 -14.6339 --12.8504 -20.2059 -14.2538 --12.3849 -21.0689 -14.5911 --12.9318 -21.8604 -14.2797 --13.533 -22.6388 -14.0402 --13.7299 -23.3735 -14.7526 --13.2148 -24.215 -14.7948 --14.1174 -24.6117 -14.9603 --14.6346 -24.4306 -14.1159 --14.7008 -23.5476 -13.7352 --15.36 -22.9131 -14.0506 --15.3866 -22.1889 -14.646 --15.3568 -21.2775 -14.9564 --16.0829 -20.8157 -14.4074 --16.9192 -20.6079 -13.8993 --16.7569 -20.3645 -12.9324 --16.8299 -19.282 -12.9742 --16.6276 -18.8496 -13.851 --15.9906 -19.6322 -13.869 --15.5251 -19.0013 -13.2945 --14.7471 -19.6809 -13.5244 --14.2373 -20.5787 -13.7725 --14.967 -21.0627 -13.3746 --15.5325 -20.5066 -12.7205 --15.2301 -20.545 -11.7359 --15.8551 -19.952 -11.1761 --16.0745 -19.6756 -10.2686 --16.5242 -18.7647 -10.1876 --16.5984 -17.723 -10.2773 --16.5008 -17.1923 -11.1768 --16.3464 -16.9284 -12.1925 --15.34 -17.0308 -12.0289 --15.1819 -16.0599 -12.12 --14.4238 -16.0075 -11.3475 --13.4576 -16.3736 -11.4686 --14.1803 -16.5862 -12.1421 --14.5338 -17.0523 -12.8609 --14.107 -17.0137 -13.7309 --13.2044 -16.7527 -14.1259 --13.3583 -15.8632 -14.5897 --12.5531 -15.6829 -15.0489 --12.4227 -14.6678 -15.1679 --11.5565 -14.9995 -14.803 --11.6983 -15.9886 -14.5967 --11.362 -16.1785 -13.6542 --11.0492 -15.9417 -12.7086 --10.6 -15.1744 -13.0968 --10.1666 -14.7475 -12.2688 --9.44794 -15.0493 -12.8736 --8.49653 -14.8824 -13.247 --8.81841 -14.1996 -12.5821 --7.96716 -14.0308 -13.0033 --8.43431 -13.7718 -13.7615 --7.65446 -13.1659 -13.5363 --8.34226 -12.5435 -13.2238 --8.52802 -11.5937 -13.1017 --9.30574 -11.2003 -13.6291 --9.80624 -10.3499 -13.4331 --10.0444 -9.69738 -14.1297 --10.0754 -9.81018 -15.1363 --9.8795 -9.16093 -15.8663 --10.5429 -9.83804 -16.2578 --11.5259 -9.68728 -15.8694 --11.6962 -9.94201 -14.951 --11.4894 -9.24164 -14.2768 --11.8353 -9.35848 -13.3738 --12.2148 -8.90278 -12.4119 --11.9745 -8.97873 -11.439 --11.8663 -8.98779 -10.4354 --12.3039 -9.67367 -9.9081 --12.9551 -10.3449 -9.65211 --13.8853 -9.87676 -9.56722 --14.3192 -10.3577 -10.2371 --14.7295 -11.0798 -10.6773 --15.579 -11.2043 -10.1358 --16.2706 -10.8584 -10.8387 --17.1044 -10.4235 -10.5238 --17.8584 -10.2669 -9.9036 --17.6818 -10.1205 -8.9502 --16.7673 -9.78922 -8.76368 --16.5064 -8.94285 -8.11516 --16.1621 -8.73573 -8.99555 --15.6864 -7.86448 -8.75967 --16.6297 -7.47522 -8.89807 --17.5751 -7.63204 -8.72659 --17.4796 -8.54748 -8.50572 --17.4467 -8.82631 -7.52997 --18.1386 -8.13692 -7.19666 --19.1017 -8.02345 -7.49203 --19.9528 -7.95476 -7.03812 --20.1486 -8.64701 -6.33458 --20.2513 -7.94858 -5.68077 --19.729 -7.45329 -4.92872 --20.2646 -7.01327 -4.22355 --19.3784 -6.46367 -4.30845 --19.6552 -6.43267 -3.30225 --20.3752 -6.4752 -2.61933 --20.776 -6.42029 -1.72763 --21.1992 -6.40713 -0.7997119 --20.391 -6.3823 -0.1923939 --19.8198 -5.55654 0.01164772 --19.1724 -4.82056 -0.1785469 --19.3771 -3.90495 -0.3838039 --19.3791 -3.87271 0.5837311 --18.6646 -4.46205 0.9876451 --17.9089 -3.84488 1.21453 --17.0382 -3.58044 0.7685451 --16.2756 -2.96242 1.00736 --15.7662 -3.22111 0.1551691 --14.8394 -2.91861 0.2195821 --14.1003 -2.99436 -0.4231549 --14.3107 -3.87486 -0.6035919 --14.812 -3.99221 0.1947461 --15.6618 -4.32746 0.5983531 --16.0432 -4.55389 1.54497 --15.3625 -5.18534 1.5587 --15.6738 -5.06168 2.49132 --15.9402 -4.59686 3.35144 --16.6698 -4.91667 3.90083 --17.3155 -4.72286 4.67708 --17.2938 -5.25495 5.53783 --17.0234 -4.6354 6.26558 --16.1578 -4.90776 5.81193 --15.2355 -4.47531 5.85946 --15.8973 -3.788 5.75904 --15.7798 -2.95246 6.2692 --15.7483 -2.50349 5.35126 --15.4331 -2.94906 4.50676 --16.0557 -2.58374 3.81593 --15.8787 -3.04676 2.96388 --15.9972 -2.29615 2.30121 --16.1267 -1.97578 1.42077 --16.8369 -1.3167 1.28679 --16.058 -0.7835421 1.49372 --15.6832 -0.7113371 2.41064 --15.0327 -1.15419 3.06755 --14.3452 -1.90395 3.34137 --13.4261 -1.52129 3.35235 --12.9898 -2.33326 3.07922 --12.4202 -2.98834 3.49489 --13.2636 -2.87704 4.07157 --13.6832 -2.86589 4.91188 --12.8038 -2.44596 5.31538 --12.7799 -3.32537 5.71349 --12.6386 -4.29337 5.58884 --11.9486 -4.84216 5.12124 --11.2765 -5.29368 4.52103 --11.1398 -4.35515 4.81135 --10.6339 -4.96699 5.42908 --9.79203 -4.62082 5.97331 --9.17254 -5.16942 5.43182 --8.78006 -4.42862 5.97138 --9.26452 -3.6096 5.56715 --9.93569 -3.25498 5.03078 --9.96967 -2.55754 5.70166 --10.5474 -3.33241 5.91895 --11.086 -4.09027 6.03541 --11.7119 -4.69089 6.46124 --10.8575 -4.95048 6.9115 --10.4807 -5.78502 7.28742 --9.58549 -5.34867 7.25215 --9.39893 -5.05111 8.2133 --10.0505 -4.36912 8.68728 --10.8147 -4.89375 8.33165 --11.0356 -5.73451 8.73633 --11.0966 -5.94194 9.75565 --10.5275 -6.41378 10.374 --9.87853 -6.01013 11.026 --10.4758 -5.15619 11.0545 --10.0132 -4.27231 11.3602 --9.08272 -4.01094 10.9746 --8.90522 -4.93951 11.3952 --8.33723 -5.72516 11.1234 --9.023 -5.77277 10.3776 --8.56447 -5.80485 9.44343 --8.3043 -6.42847 8.65353 --7.51808 -6.83428 9.20507 --6.70502 -6.78155 8.43065 --6.71977 -5.86244 8.04901 --6.62272 -4.8802 7.89203 --5.64226 -5.0111 7.99195 --5.08753 -4.07972 7.95821 --4.39494 -4.76425 7.64201 --3.83094 -3.90342 7.68716 --4.53908 -3.76438 7.02605 --4.38354 -3.58936 6.08466 --5.37858 -3.64986 6.20524 --6.01797 -2.99528 5.86675 --6.59123 -2.26971 6.31672 --5.81362 -2.16206 6.91571 --5.63513 -2.98077 7.51847 --4.82395 -2.43203 7.32438 --5.15097 -2.53927 6.38838 --4.26555 -2.00484 6.29065 --4.94455 -1.7315 5.56578 --4.75652 -0.7486931 5.22918 --4.46964 -0.7553121 6.15169 --5.18528 -0.7845931 6.84445 --6.01954 -0.4532861 7.17508 --6.62281 -0.5498241 6.35162 --6.00195 -0.9854971 5.74488 --5.71222 -1.11899 4.88937 --5.94191 -0.3045241 4.3211 --6.8678 -0.5669891 4.40275 --7.85919 -0.3573041 4.3583 --8.60722 -0.5088911 5.01202 --7.97803 -0.7016081 5.73115 --8.83773 -1.24123 5.70997 --8.24352 -1.51878 4.93922 --8.11763 -1.39559 3.9485 --8.11107 -0.9225461 3.04287 --9.01039 -1.25281 3.19073 --9.59776 -1.07874 3.9924 --9.81386 -0.3727041 3.23401 --10.7395 -0.3352581 2.79539 --11.0687 0.2903989 3.39023 --11.7957 -0.1601571 3.0549 --12.0852 -0.5209101 3.9749 --13.0459 -0.1670491 3.93156 --12.9527 0.4941859 4.63192 --13.531 1.25565 4.3018 --14.372 1.47667 3.78559 --14.9153 2.20225 3.46413 --14.7057 3.08711 3.85997 --14.8622 3.02498 2.84426 --14.2424 2.36166 2.28653 --13.9323 1.40603 2.23147 --14.5297 0.6203589 2.48261 --13.7906 -0.03764047 2.33515 --13.0222 -0.4058851 1.77962 --12.5057 0.4099019 2.12422 --12.6552 1.39709 2.25869 --11.8956 1.01694 2.86521 --11.1882 1.57688 3.28315 --10.7285 2.45735 3.19473 --11.3791 3.1841 3.16284 --11.1185 4.07796 3.58982 --11.2164 3.84546 4.57493 --11.5161 3.85476 5.60774 --11.1118 4.03025 6.52711 --10.4405 4.00961 7.24299 --10.7112 4.57037 8.05698 --10.4746 4.96883 7.13558 --10.5036 5.5026 6.26675 --11.1165 5.26008 5.48093 --11.9149 5.46017 6.08186 --12.8005 5.40061 6.4296 --13.0807 4.89487 5.63728 --13.621 4.50336 6.23903 --13.6097 3.6563 5.63557 --14.1386 2.78433 5.72102 --14.7738 3.25107 6.34383 --14.9097 2.79043 7.17578 --15.796 3.09873 7.54928 --15.9473 4.11107 7.73067 --15.0869 3.79916 8.22323 --14.3965 3.38305 8.80668 --13.8068 2.63716 8.42092 --13.7394 2.79194 7.41173 --12.7473 2.7407 7.54516 --13.0681 1.86228 7.7641 --13.4419 1.17769 7.02783 --13.7117 1.34211 6.10247 --13.6134 0.3240039 5.78509 --14.3406 -0.05361427 6.34564 --14.8288 -0.1119711 7.13977 --15.2968 0.1123499 8.04979 --14.5568 0.4393679 8.58934 --14.1493 1.12858 9.14711 --13.4485 0.5788939 8.78103 --12.4863 0.5617279 8.46262 --12.1899 1.36656 8.90693 --11.2493 1.21452 8.60203 --11.4785 1.46627 7.6622 --10.9225 2.22764 7.38696 --10.4154 1.34779 7.29626 --9.89205 2.16592 7.63292 --9.44254 2.85217 7.06337 --9.43421 1.95681 6.54825 --9.0842 2.46779 5.78483 --8.88354 3.48261 5.64114 --9.21494 4.25375 5.22915 --9.01866 4.60854 4.29529 --8.63661 3.87097 3.68728 --9.1384 3.64763 2.78767 --9.30456 2.7955 2.22956 --9.45433 1.80527 1.92864 --8.63877 2.0875 2.45126 --8.61315 2.19098 1.45455 --8.35515 1.38131 0.8427641 --8.25447 0.9756569 1.79137 --7.68088 0.2944719 1.42081 --6.84013 0.3388589 0.8719101 --6.01135 -0.06096017 1.28423 --5.93933 0.09975353 2.30953 --6.68531 -0.4572251 1.94505 --7.18932 -1.20412 2.41098 --7.5843 -1.8185 1.62495 --7.23387 -1.84713 0.6847041 --6.302 -2.28609 0.6344571 --5.52941 -2.13219 1.3005 --5.4779 -1.28709 1.87646 --6.20941 -1.93287 2.2536 --6.62967 -2.553 2.88679 --7.02854 -3.16343 3.54892 --7.99486 -3.3656 3.82128 --8.15122 -3.90975 2.99702 --7.29322 -4.33651 2.83366 --6.79101 -5.20174 3.05847 --6.09105 -4.98455 2.43387 --5.73687 -5.2648 3.34214 --5.34191 -4.65067 3.98402 --5.15339 -3.85842 4.57996 --4.23012 -3.72544 4.22188 --3.95078 -2.83416 3.80795 --3.07631 -3.20513 4.12576 --3.44236 -3.81631 3.46795 --3.9209 -4.05829 2.59333 --4.64418 -3.69999 2.02868 --5.49073 -3.30092 1.56871 --5.97373 -3.91878 0.9930761 --5.54785 -3.36368 0.3296711 --4.81969 -2.82203 0.2987471 --4.39013 -3.46394 0.9279961 --3.67425 -4.01 1.32668 --3.11742 -4.00121 0.4906761 --2.77258 -3.03472 0.7616961 --3.07109 -2.13407 1.08126 --2.95524 -2.16469 2.0659 --2.51045 -2.7833 2.65426 --1.85273 -2.76276 1.92425 --1.1358 -2.20054 2.33061 --0.366167 -2.86178 2.22672 -0.633552 -3.05299 1.95327 -1.1288 -3.83965 2.21643 -0.662937 -3.7429 3.10808 -0.473197 -4.13049 4.06621 -0.654465 -3.75697 5.01782 -1.1221 -4.65893 5.13865 -0.896134 -5.53483 5.57291 -0.483727 -5.76333 6.50213 -1.12115 -5.09921 6.83344 -0.593266 -4.80691 7.60844 -0.277929 -3.99256 8.08445 -1.13135 -4.35739 8.42962 -1.89057 -3.68144 8.29871 -2.59607 -3.03767 8.41704 -3.21142 -2.29975 8.81261 -3.47267 -1.57445 8.15014 -2.50681 -1.42939 8.52403 -2.84609 -0.4857551 8.32088 -1.93829 -0.5989861 7.85749 -1.41974 -1.31854 8.36879 -1.72793 -2.08971 7.79963 -2.63801 -2.02612 7.31876 -2.46893 -1.58131 6.4461 -2.74607 -1.24101 5.434 -3.1907 -1.98814 5.95285 -4.09294 -1.63902 6.14718 -3.54308 -1.19366 6.91668 -3.56461 -0.4227731 6.32065 -4.37606 -0.5360261 6.92264 -4.7352 0.3070499 6.57519 -5.63385 0.2156769 7.01996 -6.27301 0.2046649 7.83306 -6.08294 0.7716649 8.58319 -7.009 0.9642829 8.2369 -7.49024 1.59276 7.68432 -8.30228 0.9149609 7.50708 -9.23106 1.1346 7.8778 -9.56643 1.85424 8.46613 -9.76626 2.49356 9.12669 -8.87274 1.99895 9.21745 -8.10701 2.41902 9.6461 -7.35177 2.37358 10.3706 -6.37908 2.18189 10.438 -6.21197 2.8225 11.18 -5.84731 2.68578 12.1008 -5.36099 3.55247 12.1418 -4.3927 3.69174 12.3392 -3.80849 4.32964 12.8264 -3.04832 3.73059 13.2137 -2.72516 3.30629 12.3649 -2.09302 2.68404 12.6723 -1.79844 2.8601 13.602 -1.42253 3.76599 13.3941 -1.20906 3.54151 12.5298 -0.970957 3.4087 11.5393 -0.595423 4.32271 11.7162 -0.219806 4.59925 12.7051 -0.809837 4.61887 13.4693 -1.38114 5.03732 12.7619 -1.92504 5.70107 13.2511 -2.53096 5.12515 12.6977 -3.41258 5.56651 13.0841 -4.0666 6.23909 13.5515 -4.97236 6.05196 13.1235 -5.70102 5.80475 13.704 -5.28459 4.97046 14.1157 -4.50622 4.69412 14.6914 -3.83954 4.1091 15.2024 -3.20679 3.67907 14.546 -3.90875 3.56182 13.8259 -4.29333 2.72553 13.4554 -4.01999 2.4174 12.5527 -4.65703 1.74555 12.9832 -4.48842 1.16683 12.1662 -4.0233 1.17712 11.3182 -4.57331 0.7014139 10.6395 -4.76327 1.32938 9.80821 -4.09236 0.9524709 9.18616 -3.7033 1.75556 8.7608 -3.31665 1.82238 9.69643 -2.729 1.88933 10.4375 -1.91695 2.29596 9.92617 -1.65352 1.36968 10.4005 -2.11106 0.8764419 9.63451 -2.0477 -0.1410071 9.41005 -1.52265 -0.8366501 9.91129 -0.866427 -0.2511431 10.3604 -1.60448 -0.2624261 11.1544 -1.12919 -0.4921681 11.9841 -0.320563 -0.7395191 11.5289 --0.600753 -0.4297151 11.3303 --1.21529 0.3747819 11.5799 --2.04658 0.8537489 12.0587 --2.65876 0.1351749 12.3306 --2.43068 -0.3248401 11.4938 --2.74316 -0.7565651 10.6122 --2.77354 -1.16097 9.66108 --1.95194 -0.5651981 9.65568 --1.74844 -1.45491 9.27957 --0.928574 -1.87711 9.57963 --0.376641 -2.02537 8.73932 --0.400834 -2.85917 9.18213 --0.997686 -3.5221 9.5399 --1.87549 -3.86928 9.14902 --2.61842 -3.37529 8.7573 --3.05525 -3.99319 9.4712 --3.85304 -3.65661 9.04765 --4.39075 -3.15413 9.73712 --4.56047 -2.19627 9.92946 --4.59998 -2.45326 8.9555 --5.36616 -2.12234 8.51629 --6.39178 -2.18436 8.24923 --7.03093 -2.64704 8.71016 --7.07104 -3.63562 8.67191 --6.0969 -3.83194 8.97418 --5.12635 -3.67652 9.13748 --5.41792 -4.57363 9.48811 --6.07993 -5.25666 9.22146 --5.4221 -5.83894 9.63241 --5.15608 -5.73187 10.5974 --4.60991 -5.15527 9.92163 --3.7084 -5.00244 10.2968 --3.81329 -5.97925 10.6625 --4.09067 -5.38389 11.442 --3.09952 -5.4278 11.6103 --2.70696 -5.46075 12.5833 --3.188 -4.62138 12.6115 --3.89235 -4.86819 13.2257 --4.84442 -4.95947 12.806 --4.35443 -4.06582 12.9198 --4.60355 -3.19741 12.4094 --4.716 -3.0358 11.4843 --5.61119 -3.09122 11.9241 --5.74007 -3.74745 11.1754 --5.47902 -4.67854 11.5321 --6.29496 -4.85371 12.1286 --6.47295 -5.62984 11.4639 --7.20664 -5.09262 11.127 --7.34059 -5.88215 10.4676 --6.70306 -6.55672 10.7304 --6.4901 -7.22201 10.0191 --5.73654 -7.77985 10.086 --5.46698 -7.66029 9.13492 --5.80288 -7.96765 8.22902 --6.63893 -8.34481 8.51028 --6.93215 -9.13935 7.97534 --6.30451 -9.68645 7.39414 --5.33239 -9.53972 7.45388 --4.9275 -8.65434 7.33902 --5.10743 -8.22507 6.41156 --5.74315 -7.84767 5.75302 --6.38428 -7.13469 5.63763 --5.54554 -6.61665 5.9069 --5.68146 -5.64099 5.64069 --6.47578 -5.08109 5.71764 --5.97811 -5.05537 6.62084 --5.05463 -5.14179 6.31036 --4.08947 -5.05704 6.07715 --3.20147 -5.05986 5.65874 --2.41564 -5.22856 6.23798 --1.9229 -4.5232 6.64576 --2.24924 -3.60686 7.08261 --2.5358 -2.88518 7.73352 --3.26198 -2.2016 7.6499 --2.60479 -1.52835 7.16471 --1.97587 -0.7449971 6.90727 --2.45362 -0.08534777 6.45833 --3.17138 0.2400619 5.8316 --3.51843 0.7297609 5.05541 --4.49688 0.7098989 4.8951 --4.67415 0.5178749 3.88714 --4.57379 1.50449 3.79877 --4.14768 2.30098 4.15184 --3.75012 2.02783 3.28127 --3.17498 1.51291 2.71134 --3.78973 0.6232569 2.55865 --4.00147 1.11299 1.73416 --4.62995 0.4205699 2.13513 --5.26474 1.11388 1.74861 --5.79917 1.59967 2.42747 --6.2696 1.13419 3.16419 --6.68937 1.0034 2.23184 --7.26173 1.81072 2.47309 --7.25787 1.89294 1.46497 --7.22358 2.14206 0.4581781 --8.11307 2.65757 0.6079021 --7.99877 2.46623 -0.3295499 --7.63252 3.16964 -0.9127309 --8.63346 3.07989 -1.08383 --8.95821 3.95164 -0.7322679 --8.63462 4.55756 -0.1047279 --8.74383 3.57248 0.3517651 --9.62584 3.02324 0.4140021 --10.0984 2.33718 0.9737271 --10.023 1.71677 0.2404741 --10.5094 0.8561139 0.3646261 --10.5265 -0.05617297 0.7486331 --11.4443 0.09503133 0.9964271 --11.7724 1.0272 0.6063261 --11.544 0.7311279 -0.3558489 --11.6683 -0.03484157 -1.06428 --12.3918 -0.4956451 -0.4579529 --12.4451 -1.37571 -0.9921299 --11.8834 -1.41535 -0.1717999 --12.7262 -1.95901 -0.2578279 --12.4833 -2.86086 -0.4907509 --12.1713 -3.58101 0.05638162 --12.0247 -3.98957 -0.8409759 --11.6337 -4.54683 -0.1011889 --12.4777 -4.73459 0.3052491 --12.0413 -5.59536 -0.08172808 --12.4151 -6.43883 -0.2871959 --11.4598 -6.62172 -0.5648639 --10.9597 -6.83688 -1.42177 --11.6397 -7.30215 -2.06663 --12.5516 -7.73048 -2.05096 --11.6749 -8.1724 -1.74075 --11.3379 -8.78782 -1.04231 --12.2668 -8.90283 -1.44585 --12.0118 -9.79733 -1.90009 --11.127 -9.91044 -2.20727 --10.3919 -10.4536 -1.8023 --9.65474 -10.9681 -1.30434 --8.85423 -10.3731 -0.8564229 --8.10653 -10.9383 -0.6035629 --7.49222 -11.028 -1.36948 --7.92227 -10.2645 -1.83166 --7.80885 -9.89486 -2.74521 --7.42416 -9.61154 -3.60346 --8.08265 -8.95248 -3.9655 --8.01601 -7.91476 -3.86171 --9.05253 -7.93677 -3.67093 --8.61401 -6.99598 -3.66492 --7.82402 -6.96052 -4.26483 --8.11621 -6.33074 -4.93444 --8.25456 -5.50561 -4.33154 --9.09208 -5.58519 -3.71531 --9.25441 -5.2961 -4.63767 --9.81775 -6.01241 -4.31435 --10.211 -5.25636 -3.75548 --11.1161 -4.80349 -3.71971 --11.665 -4.3263 -2.99886 --11.5706 -4.18843 -2.0027 --12.5637 -4.21589 -2.08037 --12.4184 -3.36087 -2.55312 --12.9011 -3.31997 -3.37067 --12.2374 -2.86021 -3.94935 --12.0307 -1.92514 -4.33791 --11.2782 -1.38667 -4.03749 --11.0274 -0.7004761 -3.29497 --10.9486 0.2384219 -3.05939 --11.1894 1.13824 -2.62903 --12.1349 1.41909 -2.38198 --11.9785 2.4487 -2.38946 --12.9534 2.33991 -2.65296 --12.6176 2.58356 -3.58683 --12.9471 1.70652 -3.9759 --13.2205 0.9669039 -3.36603 --12.7887 0.2046829 -2.79401 --13.555 -0.2670331 -2.27709 --14.1726 -0.5278071 -1.51022 --13.497 -0.9104791 -0.8286219 --13.9409 -1.72725 -1.0967 --14.6595 -2.39206 -0.9559619 --14.9584 -2.62172 -1.99149 --15.5029 -3.34439 -2.4016 --15.3531 -4.02041 -1.68449 --16.3117 -3.95568 -1.3561 --17.1086 -4.44164 -1.70971 --16.2624 -4.86661 -1.99792 --15.7275 -4.94692 -2.95725 --14.7441 -4.84013 -3.15261 --13.7354 -4.96721 -3.06238 --13.593 -5.52453 -2.31146 --14.4343 -5.46568 -1.72535 --14.8381 -6.18332 -1.12468 --14.3268 -6.97007 -0.7348049 --14.149 -7.78793 -1.23205 --15.14 -7.55101 -1.36171 --14.5257 -7.04354 -1.99531 --14.3875 -6.82263 -2.95718 --14.6561 -6.42695 -3.80788 --14.8037 -7.37806 -3.70593 --14.3983 -8.27747 -3.7089 --13.6861 -8.10837 -4.4536 --12.6943 -8.25309 -4.61877 --12.6405 -7.61131 -3.84547 --13.3262 -6.99419 -4.28324 --12.6227 -6.26234 -4.13344 --11.82 -5.89599 -4.58189 --11.3373 -5.23122 -5.06118 --12.1118 -4.70271 -5.35801 --11.9654 -3.70223 -5.52617 --11.1317 -4.16834 -5.70268 --10.6465 -4.78322 -6.28252 --11.0873 -5.16682 -7.2105 --10.5362 -5.85525 -7.62173 --9.61645 -5.90448 -7.89322 --9.41133 -6.75942 -7.38465 --8.56814 -6.89831 -6.79595 --9.25464 -7.29852 -6.17061 --9.54162 -7.87354 -6.87657 --9.78035 -8.81054 -6.45399 --10.6263 -8.30558 -6.54045 --10.8198 -9.02387 -5.85961 --10.7523 -8.08213 -5.41178 --10.7706 -7.15981 -5.84873 --10.0102 -6.61641 -5.50105 --10.0354 -7.4499 -4.85743 --10.511 -7.97263 -4.17273 --9.85174 -8.67907 -3.90672 --9.66508 -9.59247 -3.59999 --8.74174 -9.91066 -3.33921 --8.53729 -10.894 -3.23376 --8.87506 -10.5449 -4.10908 --8.34708 -10.3854 -4.94813 --9.25048 -10.6561 -5.13119 --9.53285 -9.72373 -5.41933 --10.4581 -10.3004 -5.26642 --10.6097 -9.90344 -4.34837 --11.3131 -10.6235 -4.58162 --11.0431 -11.4121 -5.08748 --11.6613 -11.9826 -5.5197 --12.5449 -11.5435 -5.83732 --12.1605 -11.73 -6.81435 --12.3498 -12.1843 -7.62419 --13.2132 -11.6746 -7.53559 --13.1001 -10.7899 -7.19662 --12.7315 -10.4645 -8.08367 --11.965 -9.82525 -8.1356 --12.0164 -8.77165 -8.03003 --12.2637 -8.42133 -7.08691 --12.9145 -8.82415 -6.476 --13.317 -7.92674 -6.28543 --14.1423 -7.9482 -5.68036 --14.4301 -7.31803 -6.3945 --14.0829 -7.84228 -7.20335 --15.009 -8.19479 -7.34701 --14.7394 -8.57907 -8.23526 --14.2953 -7.7379 -8.53188 --13.3479 -8.14347 -8.30607 --13.174 -7.28402 -8.88594 --12.5747 -6.81889 -8.21562 --12.508 -6.07199 -7.5119 --13.3378 -5.80032 -6.99893 --13.2142 -6.11464 -6.01769 --12.6849 -5.28086 -5.82463 --13.5661 -4.99956 -5.41835 --13.8628 -4.04538 -5.51026 --13.1684 -3.78825 -6.16491 --12.341 -4.11062 -6.67275 --11.7655 -3.54592 -7.23734 --11.2354 -3.1351 -6.47186 --10.5788 -2.34921 -6.39004 --9.82708 -2.68936 -6.77462 --9.62904 -3.49573 -7.28435 --9.69816 -4.19761 -7.97637 --9.3843 -4.19862 -8.96501 --9.85721 -3.56001 -9.6175 --9.97765 -2.61289 -9.56544 --10.3289 -1.886 -8.9847 --10.1 -2.21283 -8.02851 --11.095 -1.88237 -8.13772 --11.3136 -1.02795 -8.68992 --12.2993 -1.25367 -8.79184 --12.6129 -0.6233441 -9.53425 --13.0562 -0.03035937 -10.3078 --12.7318 0.2344509 -11.1875 --13.2466 -0.5375771 -11.5319 --14.0514 -0.8971531 -11.0871 --13.9833 -0.7838071 -10.1171 --14.3809 -0.09130777 -9.58167 --14.1477 -0.4906821 -8.69967 --13.5512 0.3437499 -8.76938 --13.5553 0.9966759 -9.5043 --14.1998 1.76867 -9.61679 --13.9986 2.40339 -10.3797 --14.5903 2.07133 -11.0434 --15.0857 2.50633 -11.719 --15.2581 1.57856 -12.0867 --15.0642 1.42788 -13.0538 --15.9538 1.11445 -13.325 --16.2179 2.07593 -13.2281 --16.8938 1.52529 -13.5548 --17.5346 2.16555 -13.1101 --17.089 1.66247 -12.3519 --16.6234 1.51295 -11.5328 --17.1915 0.7017389 -11.3479 --17.8358 1.46398 -11.3279 --18.2543 0.5576179 -11.4101 --19.2347 0.2639029 -11.2233 --19.7289 1.08691 -11.4344 --19.4058 1.27529 -10.5064 --18.4292 1.50664 -10.5315 --18.5073 2.44616 -10.2254 --17.7797 3.05705 -10.553 --18.2485 3.81288 -10.1669 --17.4296 4.08972 -9.61581 --17.7197 4.9318 -10.0692 --17.6396 5.87938 -10.3505 --16.9243 5.59811 -11.0109 --16.6287 6.40365 -11.3814 --15.5816 6.20397 -11.1633 --15.1375 5.29983 -11.1544 --14.9024 5.94247 -10.4181 --14.051 5.68961 -10.8405 --13.4647 5.20526 -10.1634 --13.7081 5.98658 -9.56188 --14.0572 5.15964 -9.11807 --14.3643 4.22691 -9.3507 --14.8299 3.35653 -9.12718 --15.3076 3.05493 -8.3433 --15.1411 2.47169 -7.55063 --15.303 1.53488 -7.37628 --15.9606 1.01627 -7.94467 --15.3972 0.3691049 -7.5072 --15.0562 -0.5625001 -7.58182 --14.0689 -0.1570571 -7.38791 --13.151 -0.7142951 -7.37892 --13.3194 -1.33648 -6.57071 --14.283 -1.41196 -6.58087 --14.5888 -0.4891311 -6.53572 --15.5565 -0.7827201 -6.62669 --16.1163 -0.5370721 -5.74744 --17.1147 -0.4099491 -5.90578 --17.6024 -0.5411131 -5.10797 --17.811 -1.31315 -4.57258 --17.3561 -2.14514 -4.25402 --17.0919 -2.509 -5.15929 --16.1704 -2.48756 -4.75433 --15.1942 -2.07369 -4.7129 --14.5363 -1.96554 -3.98552 --14.1708 -1.78393 -3.05505 --13.7589 -1.31883 -3.83071 --14.0154 -0.7739061 -4.6073 --13.3712 -0.3731311 -5.26695 --12.3685 -0.3394061 -5.23494 --12.7016 0.4783669 -5.76347 --13.5256 0.5745729 -6.29798 --13.6408 1.21097 -7.04374 --13.4003 1.00328 -8.03495 --12.5074 0.7671339 -8.32876 --11.8825 1.3169 -7.67751 --11.2607 1.83796 -8.20394 --11.3131 1.78745 -9.26316 --10.3779 2.2007 -9.23384 --10.1736 2.95615 -8.5636 --11.0827 2.99323 -8.90905 --10.7056 3.30004 -9.76352 --10.1345 3.85159 -10.3867 --9.46633 4.53757 -10.2168 --9.86032 4.23879 -9.40325 --8.985 3.79773 -9.6384 --9.39263 3.00982 -9.98105 --9.89807 2.21641 -10.4061 --10.7994 2.08204 -10.8238 --11.2461 1.8779 -11.6636 --12.0658 2.01162 -10.996 --11.624 2.61569 -10.2866 --12.3315 3.18831 -9.76473 --12.0846 4.16772 -9.72973 --11.7664 4.13844 -10.7136 --11.4397 5.01966 -10.355 --11.6292 5.92514 -10.4956 --12.1423 5.80124 -11.326 --12.121 6.78778 -11.0987 --12.9143 6.93877 -11.697 --13.7314 6.65583 -12.1695 --13.8064 6.86468 -13.1514 --13.2637 7.62414 -12.8685 --12.2831 7.67504 -13.3531 --11.6904 8.43474 -13.7593 --12.0608 9.03903 -14.4133 --11.5834 9.73436 -15.0589 --12.1293 9.73247 -15.9326 --11.7453 10.6302 -15.642 --12.5464 11.047 -15.9865 --12.3475 10.8125 -16.9538 --13.1472 11.1476 -17.3175 --13.6442 11.9611 -17.0824 --12.8392 12.0561 -16.4647 --12.0166 12.393 -16.1229 --11.0605 12.3799 -16.6323 --10.9556 11.8423 -15.7424 --10.2583 11.8322 -15.0049 --11.224 11.6336 -14.7944 --11.5951 11.2502 -13.9739 --12.3023 11.45 -13.3081 --12.3345 11.6866 -12.3658 --13.1079 11.075 -12.2309 --13.4915 10.2274 -12.6637 --13.9188 10.0896 -11.8006 --14.0852 9.13709 -11.7264 --13.3136 8.6988 -11.2906 --13.6979 7.85792 -10.9444 --14.4628 7.33085 -10.5084 --14.3394 7.93284 -9.82093 --13.7403 8.63743 -9.39324 --13.6749 9.02866 -8.51969 --14.2466 9.85769 -8.09473 --15.0836 9.81678 -8.61682 --14.7824 9.02324 -8.08384 --14.9954 8.61194 -8.98459 --15.4318 8.67989 -9.83931 --15.6635 7.77898 -9.81967 --16.3547 8.28874 -10.3913 --16.9455 7.83206 -11.0389 --17.0301 7.92894 -12.0886 --16.2011 8.47434 -11.7819 --15.974 9.03886 -11.0466 --15.1708 9.64433 -11.4407 --14.8726 9.51973 -12.3924 --15.5324 10.233 -12.5667 --14.7328 10.7865 -12.4438 --14.69 11.5594 -13.078 --14.3531 12.1719 -12.3641 --13.9589 13.0281 -12.1023 --14.9837 12.9134 -11.8865 --15.4448 12.0428 -11.568 --15.4775 11.0169 -11.4223 --15.1675 11.535 -10.6669 --15.1375 10.9264 -9.7921 --14.5869 10.7295 -8.96828 --14.0051 11.4569 -8.65929 --13.5895 12.3339 -8.96034 --13.5141 13.3618 -8.746 --13.1248 13.5992 -9.63298 --12.9543 12.9999 -10.4035 --13.8496 13.2688 -10.8454 --14.1702 13.8267 -11.6444 --13.646 14.6446 -11.4633 --12.7604 14.3025 -11.8635 --12.7109 14.4936 -10.8549 --11.9455 14.708 -10.3541 --11.4454 14.3017 -11.0809 --10.9867 13.5549 -10.4297 --11.3193 12.6755 -10.2586 --10.8129 12.2093 -9.47412 --9.87492 11.9178 -9.40351 --9.50433 12.255 -8.51083 --9.41779 12.6206 -7.61336 --10.3854 12.869 -7.89155 --9.77932 13.4831 -8.34283 --9.34388 14.1003 -8.86351 --8.91205 14.9276 -9.10934 --8.34379 14.9026 -8.19351 --8.72096 15.6074 -7.55903 --9.23897 16.3911 -7.58802 --9.89541 17.0091 -7.14479 --10.1028 17.6491 -7.87931 --9.55659 17.1494 -8.55461 --9.88228 16.478 -9.24285 --10.3345 15.8526 -8.50764 --11.0622 16.312 -9.02452 --11.768 16.6231 -9.71404 --11.035 16.85 -10.2847 --11.0852 17.8233 -10.1868 --10.7931 18.2904 -11.017 --10.8778 18.6324 -11.977 --9.90642 18.8547 -12.0391 --9.3158 19.4724 -12.6368 --9.3935 20.0821 -11.6985 --8.96496 20.0166 -10.796 --8.10923 19.4685 -10.6281 --7.96916 18.4187 -10.5128 --7.66358 17.8827 -9.72894 --8.64395 18.0088 -9.77337 --8.42178 17.6101 -10.7238 --8.84358 17.7411 -11.5549 --8.09848 18.1395 -12.0981 --8.12608 17.1816 -12.1503 --7.73869 16.3987 -12.5357 --8.56562 16.2134 -11.9648 --9.20255 15.3641 -11.7726 --10.1144 14.9641 -11.8351 --10.8043 15.6149 -11.3459 --11.0416 16.6221 -11.5991 --11.9965 16.93 -11.9481 --11.7907 16.2391 -12.643 --11.019 16.1459 -13.2435 --11.3424 16.9234 -13.8054 --12.2293 16.6471 -13.4913 --12.8466 16.9463 -14.3352 --13.5462 17.582 -13.897 --12.9279 18.0186 -14.5581 --13.2302 18.6221 -13.857 --13.6477 19.3211 -13.3342 --13.076 19.8372 -12.6638 --12.2211 19.8471 -12.1552 --12.3387 20.7215 -12.5581 --13.1613 20.9466 -12.9803 --14.0885 20.6239 -12.8002 --14.8475 21.2154 -12.9402 --15.1789 21.2769 -13.8733 --14.5499 20.7825 -14.4527 --14.5058 20.3139 -15.3127 --13.7783 20.2632 -15.961 --13.0518 19.6639 -16.2813 --13.2409 20.496 -16.8483 --13.1642 21.4637 -16.8193 --12.5436 22.2172 -17.1356 --12.6471 23.2191 -16.9373 --12.4117 23.911 -17.6622 --12.0578 23.2736 -18.4592 --11.5811 23.9834 -19.141 --11.4354 24.1089 -20.0668 --10.7445 23.4248 -19.8052 --10.0787 24.0327 -20.1635 --9.6097 23.4547 -19.5119 --9.90029 22.5059 -19.2356 --10.0523 22.298 -20.113 --9.3344 21.7811 -20.5119 --9.07794 22.4998 -21.1212 --9.21124 21.8883 -21.876 --9.42316 21.2658 -22.6151 --9.73967 22.187 -22.7585 --10.1656 23.1774 -22.7186 --9.77654 24.1314 -22.4445 --8.9759 24.7109 -22.3077 --8.25412 24.6316 -21.6857 --7.27427 24.7619 -21.6247 --6.54359 25.2959 -21.1284 --6.65122 26.2115 -20.8181 --6.14855 26.905 -21.3859 --5.35633 26.6836 -21.8795 --4.72694 25.9405 -21.8735 --4.52641 26.8928 -21.5523 --4.02404 27.6726 -21.2319 --3.43662 27.6983 -20.4234 --3.49027 26.9503 -19.898 --4.45253 27.2177 -20.1739 --4.78603 26.6204 -19.3563 --4.79965 25.6812 -19.1674 --4.33611 25.7883 -20.0774 --3.97427 25.2573 -20.8591 --3.16291 25.6841 -20.4838 --2.70715 25.7557 -19.6281 --3.34466 25.334 -18.9918 --3.24672 24.5092 -19.5742 --3.14685 23.9516 -20.3831 --2.29345 24.436 -20.5106 --2.2565 24.0397 -21.4706 --3.24449 24.1482 -21.6721 --3.57164 24.0784 -22.6893 --2.95838 23.6687 -23.3418 --2.0237 23.5581 -23.6042 --2.15702 22.6904 -24.1579 --2.88044 22.2207 -23.6289 --3.33475 22.6366 -24.5129 --3.98398 22.8689 -23.7803 --4.91275 22.6509 -23.2302 --5.393 22.5389 -24.1259 --5.68906 23.5321 -24.088 --6.19553 24.3429 -24.5565 --7.0294 24.0385 -25.0881 --6.82001 23.5032 -24.2645 --7.56611 22.9496 -24.6594 --8.4883 22.877 -24.2504 --8.59055 22.0901 -24.7802 --8.3167 21.6662 -25.6681 --7.68023 21.1118 -26.1844 --7.8354 20.1774 -25.8419 --8.42681 20.0461 -26.664 --8.18065 19.0552 -26.6916 --7.51311 18.5187 -26.1717 --7.07185 19.4411 -26.1841 --6.50884 20.2265 -25.959 --5.84644 20.9367 -26.0056 --5.39991 20.0602 -25.7313 --4.89503 19.3826 -25.1075 --4.02356 19.6633 -24.7456 --4.51957 19.6615 -23.9052 --4.38959 20.619 -23.8046 --4.36685 21.2171 -24.5208 --4.49771 20.6147 -25.367 --4.05613 20.2195 -26.1561 --4.26248 20.6057 -27.0956 --3.31589 20.7395 -27.4278 --2.41163 20.7148 -27.7637 --1.92951 21.2675 -28.2867 --0.922388 21.2329 -28.2031 --0.08968983 20.8633 -27.8661 -0.579416 21.4294 -28.3143 -1.42354 21.8358 -27.9173 -2.23043 21.2793 -27.8389 -1.98013 20.284 -27.6042 -1.8996 19.3417 -27.2977 -2.36922 18.7285 -26.708 -3.17338 19.2594 -26.3534 -2.84205 18.4889 -25.8574 -2.88698 17.6027 -26.2286 -3.00777 17.4275 -25.2488 -3.63211 18.1352 -24.8896 -2.80852 18.7262 -24.7551 -2.14802 18.8269 -23.9294 -2.64452 19.5556 -23.3938 -1.99671 20.2875 -23.5477 -2.26555 19.8358 -22.6511 -2.19094 20.2373 -21.7118 -2.10536 20.9834 -21.0004 -1.90887 21.5993 -20.2119 -0.972559 21.8702 -20.3211 -0.279601 21.4791 -19.7057 --0.705841 21.6374 -19.7776 --0.438877 22.2127 -19.0309 --1.2557 22.7447 -19.1901 --1.60909 22.578 -18.2801 --1.71428 22.3257 -17.3105 --1.59912 23.2839 -17.1272 --2.48515 23.4746 -17.6534 --2.256 24.0985 -16.8998 --3.26995 24.2466 -16.8581 --4.06595 24.8947 -17.131 --5.04625 25.1263 -17.3091 --5.86078 25.068 -16.7632 --6.41083 25.7097 -16.3225 --6.93115 25.2073 -15.6727 --7.09152 24.8627 -16.5868 --7.66076 24.5221 -17.4461 --7.98287 25.3591 -16.912 --8.91029 25.0829 -17.1944 --9.54724 25.2852 -17.9858 --9.38031 24.7345 -18.7444 --8.45275 24.6249 -18.4158 --7.71621 24.2433 -19.058 --6.89109 24.6139 -18.7758 --6.06184 24.7097 -19.3217 --5.63641 24.0331 -18.6887 --4.87343 23.3651 -18.2794 --4.12726 22.7446 -18.3242 --3.87981 21.9268 -17.6624 --3.31338 21.3461 -17.136 --2.59596 21.7727 -16.6364 --1.74225 21.4149 -16.3054 --1.48782 22.223 -15.7457 --1.9112 22.6999 -14.9424 --1.69264 22.3421 -14.0948 --1.52592 21.284 -14.0444 --0.679564 20.6696 -14.1256 --0.743139 20.4553 -15.1513 -0.228292 20.1203 -14.8937 -0.384682 21.1527 -14.9868 -1.32462 20.7329 -14.7043 -2.02934 20.1062 -14.8325 -1.22964 19.9941 -15.4352 -1.74351 19.9673 -16.2447 -1.76725 20.7604 -16.8306 -1.83915 20.4504 -17.772 -1.09727 19.9095 -17.3408 -0.178765 20.3928 -17.525 --0.765846 20.2346 -17.8901 --1.40564 19.5188 -17.7863 --1.81134 18.8542 -18.4161 --2.76669 18.9306 -18.5772 --2.75645 18.3511 -19.3725 --3.24746 17.841 -20.1006 --2.86227 17.3824 -20.8545 --2.7866 17.2876 -21.9126 --3.70177 17.1064 -22.0908 --4.62685 17.3987 -21.909 --5.56296 17.7387 -22.2044 --6.13527 17.4277 -21.4118 --6.48379 16.6517 -20.9178 --6.21196 15.7736 -20.5809 --6.39129 16.5155 -19.9413 --5.69978 17.2098 -19.6148 --4.74718 17.4475 -19.9659 --5.08473 17.4052 -20.8509 --4.13209 17.7419 -21.0555 --4.38059 18.616 -21.4297 --4.84587 18.7286 -22.3187 --5.81624 18.7224 -22.5462 --6.30509 19.5408 -22.7177 --7.09012 19.6783 -23.2878 --7.65822 18.9128 -23.7005 --8.19639 18.8836 -24.5589 --8.94636 18.822 -23.9591 --9.1262 18.1071 -24.6472 --8.62223 17.6387 -25.2888 --8.879 16.6541 -25.4349 --9.84046 16.2638 -25.3929 --10.5389 16.6681 -24.7457 --11.3337 16.9714 -25.1467 --11.6457 17.6255 -24.4843 --11.2794 17.559 -23.5804 --10.475 16.9619 -23.1827 --10.255 17.0667 -22.2102 --10.4036 18.0419 -22.1949 --10.9966 17.8599 -21.4517 --11.2797 18.8102 -21.4447 --11.9142 19.0787 -20.7627 --12.5144 19.5275 -21.409 --12.2066 19.965 -22.2321 --12.5156 20.552 -23.001 --12.5045 21.187 -22.2053 --12.7417 21.7502 -21.4423 --12.8964 22.7084 -21.3866 --13.9131 22.681 -21.8258 --14.3758 22.2431 -21.0263 --14.8647 23.0525 -21.0359 --14.5584 22.8218 -20.1286 --14.7985 22.0132 -19.6184 --14.4688 22.6363 -18.8827 --14.0488 23.0163 -18.0261 --14.886 22.7135 -17.6643 --15.4933 22.7031 -16.8333 --16.4472 22.6861 -16.6845 --16.9297 23.4613 -17.0486 --17.4553 23.1975 -16.1974 --17.4384 22.1895 -16.1858 --17.7671 21.8853 -17.0631 --18.1505 22.7583 -17.3282 --19.1199 22.9503 -17.492 --18.9713 23.4582 -18.3745 --18.7788 24.0348 -17.5689 --18.8353 24.8945 -17.0022 --17.931 24.8506 -16.5234 --18.3413 25.4879 -15.8873 --18.9195 26.2724 -15.6417 --19.5567 26.0758 -14.9093 --20.2492 25.3409 -14.9651 --20.1547 24.3467 -14.8352 --20.3806 23.4084 -14.4959 --21.2508 23.0048 -14.1167 --20.608 23.3982 -13.4364 --21.135 24.224 -12.9775 --21.082 24.165 -11.9555 --21.078 25.0963 -12.2913 --20.4379 25.7596 -12.3275 --20.8087 25.6697 -11.4048 --21.2058 26.5472 -11.1733 --21.3568 27.4252 -11.5125 --21.6976 28.2583 -11.0988 --21.2907 29.0528 -11.3912 --21.3143 29.9547 -10.904 --21.1055 29.2174 -10.2362 --21.5275 29.0688 -9.38615 --21.4881 28.3554 -8.66938 --20.8954 27.9523 -7.94807 --20.7617 27.8161 -7.00101 --20.0983 28.0024 -6.21194 --19.8757 28.2517 -7.16327 --19.2405 28.8017 -6.59631 --18.9174 28.1814 -5.8509 --19.0103 27.216 -5.65812 --18.1281 26.8665 -5.3782 --17.8572 26.7595 -6.27854 --17.1569 26.0102 -6.12834 --17.4746 25.3195 -5.53645 --17.9898 24.5048 -5.77223 --18.6454 25.1992 -6.01774 --19.0855 25.2177 -6.90051 --18.682 24.3913 -7.28745 --18.0553 24.8679 -7.95185 --17.6638 24.8329 -8.8879 --18.3294 25.5536 -8.91988 --18.4088 24.8576 -9.68244 --18.586 24.026 -10.1039 --17.9249 23.6456 -10.7845 --17.0516 24.0411 -11.0483 --16.5017 23.3233 -10.6564 --16.3561 22.41 -11.0781 --17.0744 22.0984 -11.7084 --18.0378 22.3456 -11.6975 --18.6827 21.5415 -11.3946 --18.3013 21.6857 -10.4365 --18.5177 20.7327 -10.6681 --18.4506 20.191 -9.87382 --18.3471 21.0885 -9.4306 --18.9093 21.8011 -9.16562 --19.7787 21.7505 -9.6283 --20.6002 21.7779 -9.23764 --21.2625 21.3139 -9.87976 --22.0529 21.9663 -9.95112 --22.1166 22.6007 -9.17604 --22.5304 23.2615 -8.56953 --23.3 22.5608 -8.70092 --23.8527 21.702 -8.40181 --23.1102 21.3415 -8.91992 --22.3285 20.7602 -8.78978 --22.2323 19.857 -8.353 --21.9189 18.8744 -8.26196 --21.2515 18.1592 -8.406 --20.9144 18.3185 -9.26767 --20.2254 18.4852 -9.946 --19.5078 18.9801 -10.4429 --19.5167 18.8383 -11.4589 --18.8223 19.5437 -11.6419 --18.7482 19.5817 -12.6358 --18.0227 19.8982 -13.2685 --17.9326 19.7366 -14.218 --18.8692 20.0523 -14.2485 --18.6917 20.6717 -14.9964 --19.1649 21.4311 -15.4676 --19.2534 20.6509 -16.0826 --19.8237 19.9375 -16.4357 --19.1954 20.2994 -17.1942 --20.1831 20.3139 -17.5205 --20.9911 19.7129 -17.9003 --20.4916 18.7791 -17.922 --19.7263 18.3784 -18.3821 --19.7377 19.1666 -18.9322 --19.0996 18.4747 -19.3618 --18.1837 18.9355 -19.2861 --18.391 19.6242 -18.5737 --17.5957 19.9307 -17.9814 --16.8431 19.6886 -17.4423 --16.8194 20.3625 -16.7043 --16.3663 19.4509 -16.5989 --15.4786 18.9334 -16.7035 --15.3092 18.0174 -16.3338 --15.7429 17.1098 -16.1361 --16.5245 17.6533 -16.3658 --16.8815 17.0972 -17.1226 --17.583 16.4027 -16.8388 --17.2917 15.4887 -16.6956 --16.5927 16.1753 -16.368 --16.8966 15.5209 -15.6342 --17.6566 16.0222 -15.2716 --17.4462 16.9166 -15.5493 --16.473 17.0864 -15.3048 --16.2915 17.8754 -14.7387 --17.1547 17.5974 -14.3945 --17.3836 18.3211 -13.8207 --18.3659 18.255 -14.044 --18.9548 17.5688 -14.4273 --18.5931 16.6554 -14.6458 --18.763 16.2806 -15.5964 --18.2192 15.6625 -16.093 --18.6562 16.1156 -16.7741 --19.3915 15.6097 -17.1961 --19.1605 14.5608 -17.1772 --18.3917 13.8977 -17.1245 --17.7561 13.6735 -17.8765 --17.0842 13.5022 -17.198 --16.5036 12.7112 -17.4272 --15.9118 13.4112 -17.6533 --15.1072 13.3128 -17.0732 --14.511 12.5122 -17.1067 --14.1634 13.0431 -17.8051 --14.537 12.7238 -18.6061 --13.7921 13.4773 -18.6616 --13.327 14.2591 -19.0998 --13.1053 13.8357 -19.9241 --13.2167 12.9288 -20.3814 --13.5809 12.5038 -21.0877 --12.6369 12.4815 -21.2536 --13.2132 11.8524 -21.6836 --13.5629 12.3368 -22.5119 --13.3936 12.4595 -23.5634 --12.8153 13.3182 -23.622 --12.6197 14.1346 -22.9946 --12.5796 13.5425 -22.2309 --12.6147 13.7285 -21.2203 --11.8391 13.7961 -20.6729 --11.098 14.4858 -20.6641 --10.4501 15.1228 -20.2752 --10.8671 15.6371 -19.5243 --10.1616 16.2579 -19.1302 --10.4056 17.1487 -18.8327 --9.5936 17.2362 -18.1701 --9.15413 17.6697 -18.9167 --9.91365 18.2464 -19.0658 --9.91894 18.2469 -20.0817 --8.9767 17.9107 -20.2262 --8.62208 18.6668 -19.8859 --8.10516 19.0714 -19.1382 --8.4135 19.9056 -18.6176 --7.51944 20.1954 -18.2364 --7.73067 21.129 -18.5238 --7.89111 20.8226 -19.513 --7.09605 21.0392 -20.053 --6.32802 21.3295 -20.622 --6.17189 20.4461 -21.1387 --5.44292 20.5008 -21.7746 --5.72821 21.3836 -21.4194 --5.91619 22.3155 -21.1032 --5.32545 22.0619 -20.2886 --5.57911 21.7088 -19.4318 --6.64238 21.7151 -19.3333 --6.42805 22.1402 -18.5104 --6.39052 22.6156 -17.6179 --6.45965 22.9552 -16.6638 --6.85692 22.6823 -15.8675 --7.82127 22.5429 -16.0288 --7.72525 21.934 -16.831 --7.34732 21.2336 -16.157 --7.34853 20.6421 -15.3204 --8.34664 20.4928 -15.1199 --9.18492 20.4306 -15.5828 --9.78814 19.8163 -16.095 --9.57579 19.9918 -17.0262 --8.95784 20.6611 -17.5431 --8.95119 21.5849 -17.3349 --9.00486 21.3433 -16.4091 --9.92302 21.5234 -16.1066 --10.1711 22.2567 -16.7326 --10.5909 23.0654 -16.4196 --11.1981 22.9869 -15.7007 --11.4304 22.3251 -14.9874 --12.4792 22.5263 -14.9055 --12.1108 22.0145 -14.1324 --13.0069 21.4681 -14.0622 --13.3425 22.036 -13.2905 --14.1079 22.5278 -13.6366 --15.0095 22.7575 -13.2273 --15.3384 23.681 -13.1197 --15.959 23.6504 -12.3366 --15.8609 24.3801 -11.7011 --14.8786 24.4823 -11.5535 --14.2846 25.2791 -11.208 --13.4996 25.9202 -11.4407 --12.9262 26.7071 -11.5314 --12.3071 26.8692 -10.7963 --11.5622 27.5212 -11.0253 --10.9882 28.2486 -11.2888 --10.3941 27.5025 -11.6372 --10.5639 26.7779 -12.2363 --10.898 26.7859 -13.166 --9.95706 26.7578 -13.5291 --9.81758 26.0716 -14.3025 --9.71486 25.6984 -15.2364 --10.3761 25.055 -14.9765 --11.3496 25.129 -14.5475 --11.5316 24.289 -14.1536 --12.391 24.4356 -13.6826 --12.337 24.2292 -12.672 --13.1242 24.8186 -12.7432 --13.0318 25.5835 -13.2752 --13.904 25.1778 -13.4806 --14.897 25.2101 -13.4445 --14.809 25.0855 -12.4429 --15.2903 25.9466 -12.4582 --15.053 26.8761 -12.4189 --15.2812 27.2016 -11.4913 --15.3351 26.2812 -11.1775 --16.0617 25.616 -10.8492 --16.0032 25.1854 -9.99845 --16.1285 25.5489 -9.04365 --15.8078 26.3847 -9.44892 --16.1391 26.5524 -8.49049 --16.1832 27.0683 -7.69951 --15.4427 27.5391 -8.11986 --14.6918 28.2627 -7.97198 --14.2284 28.3085 -8.8646 --13.6451 29.0907 -9.13281 --12.9748 28.4782 -8.75857 --12.2486 28.0951 -9.4765 --11.5454 28.2528 -8.78302 --10.633 28.2504 -8.45806 --10.186 28.4538 -9.32573 --10.2765 27.6491 -9.92267 --9.40239 27.8343 -9.68725 --9.40993 26.8368 -9.65988 --8.42934 26.7872 -9.35304 --7.58915 26.7174 -9.8157 --8.3341 26.7774 -10.5435 --8.01295 27.6919 -10.735 --7.32195 28.3 -10.9202 --6.89106 28.3345 -11.8235 --7.00012 28.0228 -12.7399 --6.50072 28.9055 -12.7716 --6.38786 28.8971 -13.7371 --5.91539 29.0708 -14.5948 --5.34064 28.3723 -14.3382 --4.59722 28.6356 -13.6717 --5.11382 27.8475 -13.2373 --4.80814 26.9477 -13.1581 --4.04938 26.2223 -13.3405 --3.36292 25.4816 -13.1822 --3.58533 24.546 -12.9209 --3.49651 23.6117 -12.8316 --3.68158 23.511 -13.7937 --3.736 24.4278 -14.1601 --2.89986 24.087 -13.8382 --1.90157 24.12 -13.6564 --1.02048 24.6681 -13.6493 --0.618797 25.5464 -13.5999 -0.227835 25.6452 -14.1878 -0.993462 26.2216 -14.0015 -0.982784 27.1191 -14.4854 -1.26824 28.006 -14.9575 -0.931845 28.6786 -14.334 -1.79264 29.1347 -14.3002 -2.80076 29.3221 -14.5685 -2.83231 30.206 -15.0177 -2.86297 30.7271 -14.1903 -2.42485 31.0256 -13.3156 -2.36078 31.0829 -12.3558 -1.37177 30.6735 -12.2671 -0.514087 30.0633 -12.1655 -0.546746 29.165 -12.568 --0.08639763 28.6649 -11.9709 --1.02798 28.3833 -11.8806 --0.607485 27.6295 -12.3139 -0.05152617 27.5321 -13.0036 -0.771882 28.1804 -13.2704 -1.56261 28.6007 -12.8092 -1.817 27.818 -12.1854 -1.55247 27.2198 -11.4174 -0.652395 26.9853 -11.0497 -0.518275 25.9693 -10.8833 --0.02905953 25.1009 -10.7926 --0.449576 24.7718 -11.641 --1.29751 24.8414 -11.2169 --1.54881 24.0928 -11.8488 --2.46114 24.0608 -11.6715 --2.79427 23.1107 -11.6258 --2.93695 22.8085 -10.6563 --3.14385 23.638 -10.1544 --3.76922 23.8345 -9.47365 --3.47175 23.137 -8.86847 --2.84627 23.8544 -8.56338 --2.73572 23.7725 -7.61683 --2.39551 24.7604 -7.64407 --2.22387 25.52 -7.00309 --2.32173 26.3907 -6.5404 --1.61036 26.6172 -5.96735 --2.26756 26.3504 -5.18927 --2.78497 25.9674 -4.44158 --3.72655 26.1852 -4.60136 --4.07239 25.3857 -4.19268 --4.46312 26.322 -3.964 --4.59394 25.7484 -3.16226 --4.38522 24.7752 -3.04061 --5.08541 24.3265 -3.7155 --5.0262 24.1421 -4.68081 --5.95318 24.282 -5.01652 --5.76498 25.26 -4.99598 --6.72967 25.1512 -4.52696 --7.14742 24.8176 -5.36489 --7.59333 25.6694 -5.05452 --8.24176 25.1675 -5.58518 --8.35875 25.556 -6.50822 --8.55512 24.6626 -6.81904 --8.88901 24.4082 -5.86374 --9.79949 24.7059 -5.72231 --10.157 24.5206 -6.65131 --10.7042 25.3713 -6.64679 --9.94041 25.8535 -7.04461 --9.33635 25.8341 -6.22062 --9.26124 26.3752 -5.40983 --9.43016 27.1609 -4.79076 --8.40748 27.0483 -4.61062 --8.44901 27.3246 -3.66324 --7.40141 27.4138 -3.65667 --6.86415 27.9894 -4.21675 --6.57933 28.0353 -3.22844 --6.86289 27.6708 -2.32014 --6.63123 26.6647 -2.35695 --7.50026 26.2705 -2.22904 --6.80416 25.5621 -2.28186 --6.8485 25.5709 -1.33995 --7.40782 24.7808 -1.06255 --8.42413 24.7414 -0.7557619 --9.00158 25.5502 -0.6837289 --9.05794 26.4305 -0.2883169 --9.9976 26.2224 -0.1894149 --9.9276 27.0359 0.4121051 --10.7148 26.4639 0.6651241 --11.4159 26.2644 1.21016 --11.5337 25.2677 1.51979 --12.3684 24.9942 1.01142 --12.9266 24.1716 0.7160131 --13.1949 23.3046 0.2486961 --12.7128 22.3727 0.2580371 --12.9944 21.594 -0.1386649 --12.5942 20.7376 0.04480232 --12.1467 21.1022 -0.7755619 --11.6112 21.0742 -1.59928 --12.0619 21.8298 -2.00038 --11.3036 21.7713 -2.63458 --10.9871 22.6595 -2.40475 --10.0629 22.6028 -2.64965 --9.4831 22.5397 -3.50657 --8.60425 22.5618 -3.17175 --7.75394 22.9604 -3.28385 --7.67708 22.0517 -3.76677 --6.9395 21.361 -3.81976 --7.24653 20.5995 -3.28062 --6.53168 20.5713 -2.56719 --5.60198 20.8814 -2.48193 --5.97888 20.0964 -1.99376 --5.74671 19.9216 -1.01853 --6.33028 19.1381 -1.41105 --7.05727 19.8352 -1.25061 --7.45247 20.5159 -1.87352 --8.31444 20.0625 -1.83087 --9.31825 20.0491 -1.91194 --10.3203 20.0759 -1.74 --9.867 19.429 -2.4166 --10.4809 20.0657 -2.78223 --11.3258 19.9226 -2.23257 --11.6383 19.4476 -1.39513 --12.3968 18.8033 -1.05563 --12.2435 17.7914 -0.9772189 --12.4967 17.35 -0.1290289 --13.0849 16.8398 -0.7972539 --13.9668 17.3002 -0.9750299 --14.829 16.8964 -0.5425189 --15.5051 16.3379 -0.9757509 --16.0163 17.1366 -1.05127 --16.0248 18.0935 -0.6910139 --15.169 18.3382 -1.16318 --14.7944 18.9713 -1.79521 --14.701 19.9892 -2.18799 --13.7672 20.297 -2.0093 --13.5998 19.8725 -2.90031 --12.8092 20.4746 -2.78521 --13.4468 21.0603 -3.27559 --13.2875 22.0099 -3.13464 --13.2867 22.4821 -4.07998 --13.1075 21.6904 -4.76617 --12.632 21.6981 -5.67303 --11.7608 21.9768 -6.11895 --11.6352 22.8496 -6.45865 --11.2403 23.7859 -6.45098 --12.0597 23.996 -6.06343 --11.6674 23.3905 -5.36961 --10.734 23.1127 -5.22569 --10.1546 23.9623 -5.03411 --9.70812 23.2441 -4.55054 --8.86842 23.5807 -4.07795 --8.35516 24.4287 -4.01282 --8.46593 24.6916 -3.05857 --8.88929 25.2915 -2.34038 --9.68188 24.6697 -2.26132 --10.5765 25.1186 -2.2224 --10.9996 26.0825 -2.28861 --10.7139 27.0046 -2.02301 --10.7619 27.9468 -1.67302 --11.7349 28.0126 -1.47576 --11.4493 28.8837 -2.08002 --11.9556 29.2223 -2.9112 --11.9022 28.5577 -3.6642 --12.8697 28.5462 -3.6301 --13.7971 28.6232 -3.92375 --14.13 28.4966 -2.98685 --13.3368 28.0875 -2.57327 --13.9647 28.0662 -1.80142 --14.2893 28.8454 -1.23268 --14.3923 28.5564 -0.3124949 --14.3484 27.6115 -0.2961499 --14.4705 27.0422 0.5481081 --14.3481 26.376 1.30187 --14.5002 25.4276 1.11822 --14.0699 24.7213 0.6465191 --14.3993 24.7542 -0.2956739 --15.0262 24.0047 -0.4039019 --14.8595 23.4295 0.4349161 --14.2523 23.8298 1.18446 --15.1098 24.2484 1.11124 --15.4309 23.9022 2.00157 --15.9966 23.4999 1.25703 --16.7886 22.9665 1.25572 --17.1677 22.1289 0.8845051 --16.4092 21.5685 1.17879 --16.2491 20.5752 1.31363 --15.8362 20.2401 2.11894 --15.9536 21.0893 2.58863 --16.8857 20.7321 2.38378 --17.6349 20.2364 2.84403 --17.7201 19.7541 3.84054 --17.9795 18.8167 3.54854 --17.4485 18.0926 3.9157 --16.6928 18.5542 4.44577 --16.3243 17.6367 4.78648 --15.5163 17.3144 4.68146 --14.7939 16.7051 4.41267 --15.1713 16.5617 3.5159 --14.3761 16.9463 3.04978 --13.3997 17.0154 2.84784 --13.1107 17.9976 2.9204 --12.2514 17.6833 2.53412 --12.124 16.765 2.34532 --12.4115 16.0783 1.60561 --12.6731 16.8234 0.9824071 --12.3746 16.0283 0.4567341 --11.4884 16.4839 0.4543361 --11.1686 17.4527 0.4818031 --10.9695 17.9587 -0.4017159 --10.0807 18.3351 -0.5785599 --9.59265 17.9943 0.2143811 --8.95347 18.6159 0.6346391 --8.7249 17.9349 1.20472 --9.04812 17.6102 2.1561 --9.96379 17.2137 2.01083 --10.1869 16.2446 2.3471 --9.1699 16.2802 2.6654 --8.31943 15.8844 2.37684 --7.78271 15.0215 2.57593 --8.50082 14.8202 1.90673 --8.78066 14.4989 0.9468371 --8.86754 15.5442 0.9048101 --8.30696 16.2558 0.3159841 --8.04601 16.9612 0.9563871 --7.69183 17.4963 1.70479 --7.13855 18.1835 1.2749 --7.4281 18.3633 0.3808761 --7.00259 17.4979 0.06798982 --6.7232 17.803 -0.8083129 --6.19165 17.5697 -1.62483 --6.28592 16.8958 -2.25856 --6.67185 17.6004 -2.87322 --7.4868 17.2876 -3.28144 --7.51301 17.9413 -4.08848 --8.0112 17.4127 -4.7376 --8.74263 17.1766 -4.0921 --9.36036 16.3988 -3.78561 --9.70093 15.4757 -3.51676 --9.49753 15.5486 -4.53466 --9.19841 14.714 -4.11965 --8.36881 15.1722 -3.77303 --7.38705 15.258 -3.69663 --6.94743 15.8081 -2.98187 --5.9228 15.7434 -2.95574 --6.12196 14.8308 -3.31287 --6.7352 14.6883 -2.53791 --6.15258 15.0674 -1.74672 --5.56504 14.2638 -1.58806 --4.90893 14.8907 -1.19285 --4.01576 14.5625 -1.40581 --4.13094 13.6902 -1.7212 --4.00395 13.5656 -2.67316 --3.63922 12.6484 -2.97125 --3.90605 13.1123 -3.84034 --4.33045 13.8595 -4.31179 --3.53014 14.133 -4.79562 --2.96688 14.1699 -3.95276 --2.34956 13.4127 -4.21847 --1.9445 13.2196 -5.13027 --1.73125 13.0277 -6.09755 --2.31753 12.1487 -6.18908 --3.04616 11.7121 -6.70155 --3.38088 12.4201 -7.25242 --3.63451 12.653 -8.19642 --4.06455 13.4223 -7.67528 --3.67569 13.8755 -6.90435 --4.63842 13.6236 -6.62689 --4.16669 14.1612 -5.89694 --4.97391 14.0091 -5.26327 --5.75549 13.4699 -5.1642 --5.76082 13.2638 -6.08387 --5.25742 12.38 -6.48447 --4.49101 11.9739 -6.03591 --3.65751 11.8585 -5.63941 --4.27313 12.0383 -4.87845 --4.82404 11.1501 -5.12182 --5.33104 11.8989 -4.71756 --6.01499 11.1007 -4.67094 --6.56198 11.4859 -3.97679 --6.19297 11.0599 -3.11253 --6.19286 11.6618 -2.31901 --7.08648 11.8787 -1.91788 --7.27496 10.9286 -2.14475 --7.57549 10.6198 -1.18939 --8.40308 10.5346 -1.69016 --7.67286 9.90782 -2.13826 --6.83968 9.48635 -2.63757 --5.96889 9.64263 -2.20968 --5.2546 9.72186 -1.46231 --5.54801 9.44483 -0.5157079 --4.9479 8.64131 -0.7690009 --5.08498 7.94854 -1.40208 --4.66366 8.66612 -1.92837 --4.59865 9.38835 -2.55612 --3.6967 9.10581 -2.99902 --4.06092 9.61925 -3.7225 --3.27418 10.3177 -3.52223 --3.59235 11.2144 -3.83125 --4.57677 11.1786 -3.94186 --5.33152 10.5437 -3.80092 --5.13124 10.2729 -2.80878 --4.61791 10.7122 -2.10895 --3.76775 11.2416 -2.13944 --2.74771 11.0717 -2.06481 --2.50457 11.7525 -2.82554 --2.01723 11.2731 -3.55926 --1.91899 10.4028 -3.3217 --1.76519 9.64807 -3.96587 --1.3535 10.3545 -4.45657 --0.390397 10.6946 -4.17235 --0.355152 11.1812 -4.97259 --0.287418 12.2081 -5.27012 -0.531012 11.8584 -4.85601 -1.33026 12.2606 -5.3401 -1.29225 13.1862 -5.80974 -2.00121 13.1626 -6.49269 -2.69158 13.8873 -6.3547 -1.7968 14.4144 -6.21558 -0.863647 14.7099 -6.27182 -0.259662 15.1109 -7.03757 -0.289103 15.9579 -6.51088 --0.415133 16.1376 -7.18242 --0.419349 17.1618 -7.14214 --1.10525 16.9006 -7.8289 --1.66516 16.1055 -7.74411 --2.0667 15.7719 -8.66119 --2.94657 15.8772 -8.28159 --3.21487 15.9315 -7.32682 --3.99887 16.2272 -6.86744 --4.52851 15.633 -6.25469 --4.44251 15.328 -7.19392 --4.22855 15.3672 -8.18677 --4.62213 15.1531 -9.07548 --3.88642 15.7396 -9.29181 --3.25961 16.4842 -9.47357 --3.5545 17.4455 -9.61166 --4.01084 17.8092 -8.80678 --4.46403 18.5802 -8.38168 --4.85587 17.6472 -8.38634 --5.28183 17.7818 -7.46286 --5.60067 17.4537 -6.49386 --4.8209 18.0863 -6.63749 --4.98311 18.4147 -5.69404 --5.28415 19.2468 -6.08955 --4.5794 19.1643 -6.78392 --4.42917 19.9329 -7.42815 --5.06808 20.2583 -8.18302 --4.69449 20.1681 -9.07598 --3.96771 20.4893 -8.56137 --3.65166 21.5439 -8.53391 --4.30005 21.4194 -9.29377 --3.44383 21.4643 -9.72771 --3.02155 20.5957 -9.51807 --2.84679 19.9663 -10.2751 --3.26211 19.0727 -10.2317 --3.05739 18.8914 -11.1916 --3.88404 18.4152 -11.2376 --4.90936 18.6182 -11.0904 --5.53993 19.0963 -10.4939 --6.5366 19.059 -10.6481 --6.80076 20.0625 -10.4798 --7.60172 19.8863 -9.79531 --8.43092 19.9642 -9.18499 --8.25176 20.8935 -8.87036 --7.76198 21.2613 -8.08439 --7.39067 22.0731 -8.51964 --7.26226 21.7124 -9.45001 --6.40944 21.6815 -8.96149 --6.52191 22.5251 -9.53758 --5.98349 23.3807 -9.50507 --6.2184 23.7251 -8.64267 --5.35877 23.5766 -8.09541 --5.35856 22.9059 -7.35165 --5.10302 22.3702 -6.56531 --5.92263 21.8157 -6.19349 --5.72603 22.2477 -5.33475 --5.26709 22.302 -4.4414 --4.2781 22.4073 -4.24303 --4.40142 21.4096 -4.10673 --3.87639 21.3731 -4.92357 --3.09583 20.8076 -5.05922 --2.32437 21.3868 -5.10054 --1.81244 21.4566 -6.0185 --0.852445 21.3461 -5.84917 -0.01403387 20.8616 -5.93731 -0.497137 21.2607 -6.70716 --0.277966 21.0185 -7.26883 -0.611793 21.1124 -7.91477 -0.948975 20.3431 -8.46567 -1.22346 20.6265 -9.37459 -1.29313 21.6333 -9.23882 -1.11346 22.6149 -9.30655 -1.95525 22.5548 -9.87906 -2.01301 22.2365 -10.8663 -2.20081 22.03 -11.8715 -2.90779 21.9597 -12.6723 -2.23999 21.3174 -12.9892 -2.42604 20.3577 -12.7357 -2.01968 19.6332 -12.3708 -1.65707 19.114 -11.5947 -0.896686 18.5048 -11.4863 -0.762967 17.5382 -11.4146 -0.09350047 17.8047 -12.0922 --0.703807 17.5226 -11.6366 --0.973073 17.7839 -12.568 --1.76234 17.3315 -12.7391 --1.93242 18.1385 -13.2822 --2.73558 17.6078 -13.0671 --3.28527 17.9954 -13.7015 --3.83267 17.4656 -13.2572 --4.23554 18.1899 -13.8136 --4.77859 17.4249 -13.5492 --5.32182 16.5506 -13.7276 --5.16853 16.1862 -14.6876 --5.59383 15.2603 -14.8575 --5.76671 14.3906 -14.681 --5.22201 13.7431 -14.179 --4.35949 14.2349 -13.9368 --4.7864 14.4881 -13.0095 --5.02533 15.2118 -12.3172 --4.12931 14.8074 -11.946 --3.34373 15.1545 -11.4819 --3.55309 14.73 -10.6098 --2.60193 15.1252 -10.5447 --2.32246 15.322 -9.5903 --1.52283 15.8618 -9.94665 --1.13589 16.3217 -10.7674 --1.59582 17.233 -10.9072 --2.48615 16.7119 -10.8572 --3.26441 17.394 -11.0433 --3.33528 17.0033 -11.9705 --3.16339 16.3741 -12.7507 --2.73962 15.6785 -12.1446 --2.37969 14.7789 -12.5835 --2.26775 14.0894 -11.8401 --2.97231 14.2536 -11.169 --3.08335 13.3875 -11.4325 --4.06753 13.4923 -11.7207 --4.19157 12.7017 -12.2927 --4.08828 11.7107 -12.6622 --3.3268 11.2279 -12.2299 --3.86211 10.3457 -12.0529 --3.27857 10.2264 -11.2526 --3.14626 9.99729 -10.277 --3.46659 9.14845 -10.8192 --4.4038 9.53905 -10.6231 --4.33956 9.50306 -9.58421 --5.28329 9.73236 -9.19061 --5.84372 10.3504 -8.61994 --5.34746 11.2356 -8.8756 --4.7227 11.5892 -9.62785 --3.76336 11.3415 -9.75719 --4.06817 12.1895 -10.1867 --3.20752 12.2387 -10.6294 --2.41706 12.3025 -11.2187 --2.34656 11.3253 -10.9052 --1.84434 10.8353 -10.0826 --1.11819 11.4849 -10.1743 --0.76599 12.422 -10.5402 --0.551324 13.4151 -10.4299 --1.25956 13.2745 -9.75641 --1.933 12.5318 -9.83292 --2.02667 12.0519 -8.94831 --2.43133 11.5517 -8.12499 --1.94149 11.6148 -7.23882 --1.21497 11.1301 -7.79861 --0.615793 11.7121 -8.34671 --0.08581463 10.8716 -8.45062 -0.567703 10.1438 -8.40204 -0.762083 9.7094 -9.26543 -0.46003 9.5404 -10.2618 --0.377936 9.27577 -10.6489 --0.496771 8.87046 -9.80765 --0.906243 8.16166 -9.26814 --1.78581 7.91451 -9.62325 --1.67609 8.07027 -10.544 --2.06931 7.17125 -10.8292 --2.99579 7.17955 -11.1908 --3.88988 7.46934 -11.5089 --4.61256 6.95759 -11.1734 --4.67273 6.04005 -11.345 --3.69902 6.11349 -11.0277 --3.32484 5.93219 -10.1475 --3.24871 5.50527 -9.18841 --3.3437 4.65139 -8.57026 --3.57046 5.00437 -7.63426 --4.17362 5.7842 -7.83702 --4.61494 4.83575 -7.92231 --4.71294 4.9682 -6.95481 --4.80155 5.2848 -5.96035 --5.59108 5.86767 -5.61954 --5.68297 6.74112 -5.28063 --4.70028 6.7435 -5.64149 --4.58893 7.35633 -6.46836 --4.5073 7.94525 -7.23491 --5.18837 8.6192 -6.96901 --5.48383 7.70912 -7.50708 --5.43538 6.69158 -7.41726 --6.06478 6.64859 -6.69581 --6.58671 7.44297 -6.61669 --7.02309 8.25184 -7.06953 --7.56143 9.06633 -6.80492 --7.44444 9.02759 -7.82064 --7.12863 8.7977 -8.73415 --6.27837 8.30008 -8.95541 --6.56364 7.69307 -8.21319 --6.88015 7.39894 -9.1607 --6.01058 7.0083 -9.44681 --5.12674 6.74993 -9.16801 --4.93409 7.05933 -10.0641 --4.33663 7.83822 -10.2151 --4.54725 7.53602 -9.29842 --4.12896 7.08277 -8.52776 --3.56849 6.6009 -7.74393 --2.63792 6.11892 -7.8781 --2.95627 5.90923 -6.93389 --3.37386 5.00946 -6.60434 --2.83803 4.27737 -6.10877 --2.32326 3.5119 -6.39674 --1.54856 3.52375 -6.96717 --1.43064 3.96997 -7.86722 --1.12725 3.09882 -8.26499 --0.252824 2.656 -8.31311 --0.663174 1.87559 -8.87059 --1.60028 1.55443 -9.01272 --2.396 1.35454 -9.64133 --3.36983 1.57123 -9.70477 --3.43018 1.13041 -8.76877 --3.68363 1.10105 -7.81803 --2.63607 0.9607329 -7.76946 --1.75374 1.16921 -7.32227 --1.49169 1.99444 -6.81276 --1.39008 2.22432 -5.86815 --2.01341 2.3387 -5.12064 --2.24158 3.32375 -5.15132 --1.49862 3.66353 -4.4822 --0.864174 4.20874 -4.88409 -0.170589 4.14368 -4.97997 -0.953858 3.70259 -5.37518 -1.10106 4.51766 -5.87344 -1.1186 4.43987 -6.86728 -0.138193 4.70997 -6.86253 --0.26306 3.8155 -7.21113 -0.07826977 3.96414 -8.1794 --0.310053 4.88113 -8.54882 -0.575658 5.12903 -8.10954 --0.05582573 5.65266 -7.59286 --0.807636 6.06042 -7.24303 --0.769283 6.36135 -8.18495 --1.70359 6.30886 -8.65551 --1.4149 7.19253 -8.25863 --1.83125 8.05613 -7.88887 --2.627 7.55898 -7.86139 --3.18049 8.13962 -7.19263 --3.82262 8.57185 -7.7934 --3.24336 9.30747 -8.07919 --2.32235 9.31646 -7.67268 --2.40194 10.1918 -7.21213 --2.22063 9.66392 -6.37196 --1.45458 9.82944 -5.79745 --0.519792 9.55642 -5.97219 --0.05265373 8.85499 -6.43673 -0.08805297 7.91542 -6.03734 --0.279133 7.13915 -6.54593 -0.522977 6.89158 -7.04247 --0.009465155 7.45581 -7.70637 -0.140243 8.42911 -7.80688 -0.421607 8.83755 -8.69437 -1.13504 8.32393 -9.23863 -1.62792 9.13673 -9.66148 -2.26688 9.01052 -10.3716 -2.22123 9.97457 -10.2987 -1.52217 10.0099 -11.0302 -1.72557 10.9619 -11.3765 -1.82378 11.9245 -11.6844 -2.43868 12.6925 -11.2117 -3.34129 12.9784 -11.5234 -4.23704 13.2159 -10.9528 -4.80981 13.9278 -11.3958 -3.99378 14.3923 -11.0661 -3.29938 15.0486 -11.0586 -2.99814 15.2719 -10.1287 -3.37493 14.3676 -10.2233 -2.41158 14.2161 -9.91831 -2.36832 13.1892 -9.97264 -3.08774 13.4266 -9.31097 -3.61467 13.4807 -8.5132 -4.29333 13.6819 -9.12013 -5.22941 13.4419 -8.88934 -6.04312 14.024 -8.79124 -5.88228 14.3001 -9.76345 -6.89714 14.2304 -9.77705 -7.82777 14.2491 -9.3355 -8.15897 13.8023 -8.5357 -8.7193 14.4609 -8.04217 -7.93048 14.2436 -7.4424 -7.70804 13.4576 -6.98306 -6.78399 13.8244 -6.99249 -6.68794 14.4095 -6.21875 -5.9108 14.0147 -5.6566 -5.29016 14.4693 -6.39695 -4.98535 15.3956 -6.09166 -3.99824 15.2618 -6.38544 -4.16865 14.4398 -6.90525 -4.65507 14.7473 -7.72635 -4.79909 14.5031 -8.65832 -4.05581 14.7475 -9.25043 -3.09557 14.8895 -9.18646 -2.6021 15.2407 -8.38582 -2.9499 16.0791 -8.09489 -1.94716 15.9257 -7.77001 -2.44189 16.236 -6.97526 -2.89453 16.9621 -6.42342 -3.86088 17.1923 -6.7631 -4.16847 16.5527 -7.4516 -4.21119 16.211 -8.41952 -4.754 15.9436 -9.24413 -5.40764 15.5914 -8.57207 -6.27718 15.812 -8.96455 -6.95504 15.6928 -8.14494 -6.81919 15.6544 -7.12368 -6.7532 15.8392 -6.0939 -6.73759 16.8429 -5.88013 -6.44865 17.7603 -5.6252 -6.50422 17.2459 -4.80082 -6.08628 17.6762 -3.95245 -6.16534 16.9648 -3.31089 -5.36519 16.7929 -3.9663 -5.64957 15.947 -4.30342 -4.98074 15.5782 -4.96766 -3.96556 15.7417 -5.04029 -3.0203 15.7345 -5.34455 -2.24568 16.328 -5.33307 -1.33373 16.3362 -4.99447 -0.89807 15.9694 -4.20497 -0.871094 16.4777 -3.32951 -1.68744 17.0772 -3.43147 -0.891682 17.4931 -2.94578 -1.41952 18.1041 -2.24829 -1.85624 19.001 -2.35287 -2.19853 19.7552 -2.86864 -2.96189 20.4068 -2.53603 -3.89199 20.2634 -2.19075 -4.75771 20.1875 -2.47302 -4.27176 19.5536 -2.99405 -4.25385 20.4898 -3.38377 -4.15021 21.3938 -3.12109 -4.01892 22.3334 -3.35751 -3.24947 22.765 -2.89011 -2.52136 23.3772 -2.74757 -1.91848 23.8057 -2.15674 -1.65984 24.7739 -1.9307 -1.5365 25.0221 -0.9925239 -0.928666 25.5763 -1.55277 -0.451051 25.4977 -2.37548 -0.311332 26.11 -3.13363 -0.817934 25.5204 -3.75542 -0.09596857 24.8243 -3.76455 --0.80987 24.6976 -3.49872 --1.53429 25.4104 -3.13797 --1.66816 25.3927 -4.12101 --1.71159 24.8407 -4.93091 --2.60132 24.3786 -4.9334 --2.65342 23.3652 -4.93271 --2.55971 23.0874 -3.93072 --3.33572 22.4302 -3.67131 --3.78692 22.8343 -2.87941 --3.32065 23.0216 -2.04122 --4.06244 23.5135 -1.55054 --4.71269 23.3491 -2.29393 --5.33318 22.6329 -2.25105 --6.13258 22.5135 -1.59834 --6.55059 21.5951 -1.55957 --5.86997 21.1266 -0.9495489 --4.91375 20.782 -1.07176 --4.00883 21.0334 -0.9495269 --3.71371 21.3602 -0.06397288 --2.73975 21.6107 -0.1083809 --2.26901 21.5179 0.7389031 --1.62452 22.327 0.5147371 --0.644586 22.503 0.7338311 --0.720315 22.8806 1.63099 --1.27837 22.666 2.38874 --0.947893 22.3732 3.3303 --0.697055 23.0109 4.05814 --0.605812 22.1244 4.39344 -0.356578 22.0425 4.16815 -1.04668 21.8862 3.40027 -0.482136 22.2123 2.63641 -1.23547 22.95 2.47784 -1.28895 23.611 1.87263 -1.39146 23.0539 0.9915601 -2.34305 22.8046 0.8898661 -1.95098 22.5325 0.04237262 -2.36858 22.251 -0.7958209 -2.99912 22.484 0.03237322 -3.60146 21.6943 -0.01843678 -4.31093 21.5279 -0.7453979 -4.25768 21.599 -1.7834 -5.12928 21.5453 -2.36451 -5.60279 21.3112 -1.56921 -5.0394 20.6507 -1.08717 -5.31661 21.1948 -0.2830129 -5.73001 21.3217 0.5445531 -6.28771 20.698 -0.01795448 -6.69657 21.5994 0.08092132 -6.75972 22.335 -0.5728179 -7.62222 22.7907 -0.4807259 -7.72198 23.7646 -0.1220869 -8.57373 23.6703 -0.5601029 -8.65323 24.7176 -0.6790479 -8.22686 25.5574 -1.04391 -7.82044 25.4468 -1.96443 -6.98723 25.2044 -1.44203 -7.30708 24.2601 -1.5793 -6.74555 23.5474 -2.03873 -6.59245 22.776 -2.65391 -5.66871 23.0345 -2.40373 -5.75075 23.9883 -2.84634 -6.03581 24.7762 -3.34242 -5.45337 24.607 -4.07229 -4.65288 23.9385 -4.25361 -3.75862 24.2485 -3.81106 -4.23009 25.051 -3.67422 -3.18996 25.0749 -3.60349 -3.39988 25.0332 -4.60507 -3.08322 24.1764 -5.01847 -2.15461 23.6949 -5.18586 -1.63877 23.8361 -6.00564 -0.664562 23.9139 -6.20473 -0.300593 23.4875 -7.01266 --0.008696485 23.549 -7.96458 --0.904116 23.1508 -7.86543 --1.08318 22.6584 -6.97 --0.787271 23.4821 -6.45793 --0.802445 24.1392 -5.6749 --0.30261 23.2926 -5.58439 --0.641 22.9674 -4.61756 -0.07425147 23.1853 -3.88123 -0.25969 22.5073 -3.17052 -1.0585 22.1747 -3.76606 -1.31697 21.3092 -4.17933 -1.09366 20.3728 -4.56187 -2.04643 20.2179 -4.8628 -2.73057 19.6766 -5.27433 -2.82161 20.111 -6.20509 -3.6744 20.6233 -6.33793 -4.59344 20.6521 -6.01239 -5.54979 20.6811 -5.63083 -5.44818 20.1594 -4.79598 -4.66069 19.5664 -4.49942 -5.42603 18.9343 -4.83078 -6.38154 18.9486 -4.55479 -6.98249 18.4744 -3.84591 -7.95519 18.4287 -4.27892 -8.06795 19.3691 -4.19938 -7.7281 20.4004 -4.22761 -7.6335 21.341 -3.86768 -8.15394 22.1852 -4.20289 -7.70982 22.5248 -3.36263 -7.08488 22.6071 -4.21995 -6.55296 22.5494 -5.04952 -6.90602 22.0823 -5.86418 -6.82246 21.5876 -6.70959 -6.22109 20.8449 -6.73509 -6.79685 20.3417 -7.42453 -7.04992 19.4936 -6.96712 -7.15543 18.9042 -7.71533 -7.10361 18.7744 -8.72467 -6.22663 18.8922 -8.89419 -5.63404 19.4509 -8.33606 -5.60006 19.1654 -7.37726 -5.82561 18.2976 -6.91511 -6.64128 18.1387 -7.26594 -7.23167 17.3547 -7.11917 -7.78584 18.2244 -6.88069 -8.05382 17.5454 -6.30484 -8.26224 16.9596 -5.49146 -9.17239 17.0068 -4.96628 -9.95969 17.4072 -5.52512 -9.51318 18.0068 -4.77723 -10.3776 18.1853 -4.24964 -10.7905 19.1302 -4.38073 -11.2257 18.97 -3.46535 -10.2493 19.0913 -3.14504 -10.1524 20.0721 -2.96897 -9.39393 20.6662 -3.24734 -9.18158 21.1289 -2.31892 -10.1583 21.0961 -2.63321 -10.0288 21.287 -3.61231 -10.5323 22.1895 -3.53424 -9.72301 22.7089 -4.05475 -9.86747 21.9601 -4.67272 -10.3231 22.3901 -5.42428 -10.969 22.4517 -4.6546 -11.3645 21.8438 -4.02961 -12.1059 21.2371 -3.72295 -11.4823 20.9506 -4.47199 -11.6442 19.9258 -4.52042 -12.4713 19.635 -4.93355 -12.5895 19.9171 -5.80058 -11.8008 20.4773 -6.26592 -12.4308 20.2484 -6.99848 -11.9672 19.4016 -7.31364 -11.0057 19.2841 -7.72015 -11.1125 20.1129 -7.21388 -10.3894 19.8657 -6.51313 -9.5495 19.7367 -5.88387 -8.83673 19.4193 -5.22937 -8.84571 18.6346 -5.79685 -9.53661 18.5104 -6.43132 -9.78958 17.6108 -6.7335 -9.22222 17.9028 -7.55343 -9.79739 18.5709 -7.82612 -9.14663 19.3461 -7.65097 -9.50116 19.3242 -8.57275 -9.74094 20.2387 -8.71903 -9.15733 20.07 -9.529 -8.81512 19.4078 -10.1831 -8.37698 20.2684 -10.5026 -7.50149 20.5659 -10.9621 -7.73297 21.4701 -10.6515 -8.73793 21.7238 -10.7756 -9.51183 21.4953 -11.4931 -10.039 21.3112 -12.3512 -10.5709 21.2696 -13.2367 -11.5323 21.5543 -13.0648 -12.0694 22.3749 -12.8504 -12.5654 22.9607 -13.3807 -12.5943 23.6588 -14.1531 -12.9731 24.4455 -13.7208 -13.0794 25.4026 -13.8335 -13.7262 24.7729 -14.1565 -14.4711 24.3604 -14.6772 -15.2773 24.8913 -14.389 -14.8801 25.776 -14.7246 -15.3579 25.6069 -13.8379 -14.893 26.4603 -13.591 -13.9885 26.7006 -13.7326 -13.1671 27.1743 -13.8143 -12.1527 27.4983 -13.6783 -11.7594 28.1144 -12.9226 -11.7258 28.1383 -11.9316 -11.2597 27.8918 -11.0731 -10.9184 26.9757 -10.8902 -10.2936 27.5847 -11.2534 -9.78742 28.4354 -11.1872 -8.90065 28.8363 -10.8469 -7.95773 28.8008 -11.0309 -7.04889 29.0056 -10.8386 -6.04189 29.119 -11.0732 -6.21346 28.9231 -10.1246 -5.36977 28.3997 -10.0963 -5.9134 27.7239 -9.45844 -6.24381 28.2148 -8.767 -6.2609 28.0534 -7.75515 -5.68823 27.2541 -7.41854 -6.05103 26.8505 -6.57768 -6.51394 26.246 -5.86202 -6.62579 26.2984 -4.86149 -6.44976 27.2313 -4.4768 -6.75455 26.8005 -3.58975 -7.62028 26.4737 -3.52962 -8.56566 26.8827 -3.30285 -9.15274 26.8449 -4.17842 -8.66785 26.6798 -4.99836 -8.6646 25.9133 -4.42525 -7.6933 25.6379 -4.51931 -7.10942 24.8259 -4.87687 -6.38374 25.1659 -5.48653 -5.44338 24.9032 -5.43721 -5.55274 24.1526 -6.06719 -4.5932 24.5438 -6.30728 -3.74502 24.299 -6.72317 -4.18528 23.6963 -7.4653 -3.18484 23.5847 -7.48633 -3.24113 23.5693 -8.51857 -3.74751 24.2439 -9.02382 -4.8221 24.4431 -9.02092 -5.72776 24.8031 -8.73517 -5.70997 23.9461 -8.1799 -6.25984 24.388 -7.54069 -7.25215 24.1664 -7.37609 -6.99936 24.4758 -6.48472 -7.49826 23.7025 -6.05041 -8.41371 23.4077 -6.11004 -8.56539 22.6504 -5.55306 -8.00845 22.6018 -6.39794 -8.13534 23.1401 -7.16981 -8.89838 22.9871 -7.72494 -9.76832 22.9648 -8.25886 -10.4804 22.3968 -8.57274 -10.747 21.97 -9.42515 -10.7812 21.0167 -9.16509 -11.7203 20.8412 -9.23951 -12.4147 20.8803 -8.47215 -13.0625 21.4962 -8.05737 -13.6324 21.0065 -7.50408 -13.606 21.3647 -6.59838 -14.5719 21.0392 -6.63791 -15.3656 21.369 -7.24816 -16.0332 21.0667 -7.96801 -16.9461 21.0976 -8.20847 -17.7365 21.3174 -7.57975 -18.1781 21.1147 -8.53519 -18.5384 21.9897 -8.23926 -19.0852 21.8362 -9.022 -19.5645 22.0244 -9.87793 -20.0836 21.9293 -8.97643 -20.6478 21.806 -8.10983 -19.7174 21.514 -8.01464 -20.1371 21.2197 -7.13258 -19.4277 21.65 -6.59195 -18.6786 22.2733 -6.86489 -19.4305 23.018 -6.74225 -19.5306 23.5383 -5.83284 -18.6941 23.91 -5.32029 -18.1162 23.6695 -4.51359 -17.226 23.6483 -4.12138 -16.6246 23.9018 -4.92698 -16.4273 23.1365 -5.59114 -15.7917 23.7448 -6.06509 -15.2111 23.8068 -6.96437 -14.4749 23.2063 -6.48662 -14.5091 22.3279 -5.94994 -14.707 22.2552 -4.98425 -13.9344 21.9343 -4.50629 -14.4434 21.9004 -3.66605 -14.7103 21.0079 -4.03554 -15.283 20.2709 -3.66223 -14.6726 19.8007 -4.35546 -14.7275 19.8514 -5.31422 -13.7544 20.0303 -5.39702 -13.5081 19.8712 -6.33619 -13.3784 18.9153 -6.48659 -14.3327 18.99 -6.15063 -14.2679 19.1823 -7.16268 -13.4154 18.8974 -7.62108 -13.5387 18.1801 -8.28074 -13.3642 18.1504 -9.33908 -13.0971 17.5282 -10.0487 -12.2743 17.9105 -9.62359 -12.1932 17.2835 -8.84954 -11.9435 16.7172 -9.61688 -10.9979 16.4325 -9.50091 -10.0969 16.3463 -9.24521 -10.0151 15.9995 -10.1602 -10.4862 16.1738 -10.9545 -11.1468 15.4716 -10.6682 -11.3384 15.6605 -11.596 -12.0216 15.9106 -12.3559 -11.6988 16.7174 -11.8087 -12.1753 17.1135 -12.6534 -13.1759 16.9347 -12.5719 -13.6768 17.6277 -13.1898 -13.5688 17.2374 -14.057 -13.637 16.3208 -13.5486 -14.508 15.771 -13.2964 -14.8162 16.7044 -13.2046 -15.3524 17.2366 -12.551 -16.1803 17.6986 -12.6491 -17.0804 17.559 -13.0259 -17.2421 18.4326 -12.5335 -16.9948 18.9655 -11.7039 -16.3916 19.6687 -12.0315 -15.3959 19.6546 -11.6364 -14.3957 19.5743 -11.8479 -14.0831 20.4102 -12.3242 -13.0969 20.4895 -12.0045 -12.1831 20.0998 -12.1008 -12.0453 19.7116 -13.0391 -11.2325 20.2733 -13.0222 -10.2796 20.1078 -13.03 -10.0019 19.2006 -12.9489 -9.4024 19.3441 -12.1758 -10.1278 20.0082 -11.7542 -10.6698 19.8055 -10.9548 -11.3695 20.5161 -11.0709 -11.2881 21.4661 -11.4671 -10.5734 22.064 -11.2637 -10.5118 22.6833 -12.0703 -11.0323 23.543 -12.2069 -12.0194 23.9624 -12.328 -12.6516 24.5165 -11.7947 -13.1673 24.9652 -12.5182 -13.6395 24.141 -12.9377 -13.8473 23.2159 -12.6424 -14.606 23.406 -11.9968 -14.4926 24.3849 -11.6155 -14.3696 24.2664 -10.5972 -14.9827 23.4575 -10.5723 -15.8421 23.8515 -10.1579 -16.0073 22.8622 -10.1969 -16.3543 23.0504 -9.21741 -15.6617 23.3004 -8.55712 -15.1052 22.5601 -8.18463 -14.1724 22.5074 -8.56885 -14.2476 23.2957 -7.95459 -13.545 22.9425 -7.26034 -13.1453 23.4093 -6.48258 -13.2265 24.2409 -5.9314 -12.9033 24.8866 -5.26458 -13.5713 25.678 -5.24617 -14.5622 25.478 -5.23281 -14.7339 26.3458 -5.75123 -15.0871 26.5076 -6.70902 -16.0265 26.9003 -6.51219 -16.2431 26.0061 -6.25223 -16.721 26.717 -5.7955 -16.2939 26.313 -4.98231 -15.777 25.5586 -5.17912 -16.5662 24.9629 -5.37832 -17.57 24.9104 -5.5255 -18.2732 25.4955 -5.36408 -18.7257 26.2769 -5.89328 -18.1818 25.7294 -6.59827 -17.2892 26.2185 -6.75492 -16.7967 25.8381 -7.62388 -15.8253 25.8911 -7.39111 -15.0819 25.5405 -7.91782 -14.0736 25.6651 -7.80452 -14.3604 25.9781 -8.6561 -14.7018 25.6084 -9.58421 -14.0448 26.2744 -9.82791 -14.166 27.2723 -9.50991 -13.9557 28.245 -9.74165 -14.728 28.2199 -9.21169 -15.3289 28.2781 -10.0005 -15.9207 28.3904 -9.21882 -16.1906 29.0338 -8.48827 -16.751 28.4172 -7.95621 -16.2207 27.8831 -7.27445 -15.6513 28.3137 -6.53183 -15.5735 28.2666 -5.53042 -14.5908 28.2629 -5.60871 -13.7295 27.7991 -5.43938 -13.5694 28.7832 -5.60953 -13.8662 29.3116 -6.42651 -13.1821 29.4804 -7.19373 -12.5866 28.7276 -7.33631 -12.2656 27.7672 -7.18982 -11.4346 27.8821 -7.7284 -10.6266 27.3564 -7.37696 -11.3975 26.9146 -6.94486 -10.6885 26.3198 -7.17706 -10.5375 25.3607 -7.13979 -11.2532 25.6128 -7.83456 -10.2991 25.8997 -7.99193 -9.63582 26.6916 -7.80735 -9.01637 26.1347 -8.46866 -9.37671 25.4781 -9.14923 -9.8218 24.9525 -9.95094 -9.98969 25.918 -9.8552 -9.59725 25.8919 -10.7469 -9.11889 25.3989 -11.5072 -9.46699 24.57 -11.1197 -8.59478 24.0536 -10.9347 -8.25374 23.4349 -10.2701 -8.86608 23.7577 -9.48156 -9.013 24.1864 -8.60571 -8.48142 24.7874 -9.06821 -7.93175 24.7349 -8.25639 -7.13712 25.1487 -8.69492 -7.71438 25.7957 -9.17682 -7.32037 26.6791 -8.91042 -7.94653 27.2679 -8.46207 -8.87209 27.5539 -8.36606 -8.32694 28.2443 -7.83743 -8.15194 29.0435 -7.26842 -7.61838 28.5076 -6.61877 -7.48234 29.5162 -6.61383 -6.87221 29.8948 -5.88558 -6.15401 30.0804 -5.28336 -6.74088 29.4167 -4.74588 -5.77468 29.038 -4.59699 -5.21934 28.396 -3.93992 -5.08715 27.429 -4.24579 -4.86779 26.8163 -3.45672 -5.18055 26.2694 -4.23326 -4.30604 25.9029 -4.60901 -3.91467 26.803 -4.62717 -3.7318 27.0407 -5.62902 -3.1981 27.4953 -6.2832 -3.25582 27.1334 -7.25892 -3.97146 26.3796 -7.18424 -3.40154 25.6987 -6.80528 -2.42562 25.9043 -6.67165 -1.48112 25.6243 -6.79568 -1.36324 26.1226 -5.92393 -0.411239 26.1577 -6.33569 -0.394317 26.1069 -7.33472 -0.822625 26.1115 -8.18701 --0.09859133 26.2563 -8.60635 -0.243481 25.5779 -9.22187 --0.161013 24.7561 -9.02621 -0.384021 24.3588 -9.75857 -1.20783 24.0351 -9.25555 -1.32482 23.6395 -8.36517 -1.65722 24.4501 -8.01169 -2.32103 24.5351 -8.75534 -2.82155 25.1907 -9.34462 -3.67746 25.0886 -9.82397 -3.78998 25.9566 -9.30734 -3.16196 26.4416 -9.9292 -2.4277 26.8738 -10.31 -3.14009 27.5141 -10.35 -2.97418 27.6013 -11.2589 -2.82817 27.3174 -12.1978 -3.10174 26.3602 -11.8874 -4.05891 26.6418 -11.7222 -4.99718 26.6885 -11.3701 -4.72421 27.0337 -10.507 -4.00654 27.6431 -10.8737 -4.04614 28.5915 -10.5848 -3.60539 28.9501 -11.4479 -2.84956 29.5449 -11.1673 -3.53106 30.1741 -11.45 -3.84169 30.4477 -10.5768 -4.09051 29.8684 -9.7087 -4.53718 29.3767 -8.99031 -4.40157 29.4733 -7.97785 -4.16876 30.4267 -8.03256 -5.07346 30.8829 -8.10258 -5.21195 30.9422 -7.10271 -4.56212 31.7133 -7.10815 -5.44413 31.8855 -6.64243 -5.77791 32.7257 -6.8361 -5.75212 33.4131 -6.08342 -6.18387 34.2823 -6.28149 -6.06789 35.2031 -5.83171 -5.56354 35.9154 -5.32974 -5.74727 35.9389 -4.38795 -5.78499 36.2546 -3.43191 -6.28111 36.4023 -2.60965 -7.0699 35.8113 -2.47836 -6.4694 34.9664 -2.70033 -6.997 34.4109 -2.05829 -6.03462 34.0154 -2.11893 -5.36945 34.4736 -2.81166 -4.90076 33.7402 -2.39679 -4.88937 32.7938 -2.01421 -4.04709 32.2986 -1.58988 -3.99244 31.9571 -2.52856 -3.18357 32.2247 -2.99085 -2.24532 32.7152 -2.84897 -1.25491 32.5811 -3.0498 -0.793518 33.4665 -3.05057 -0.03558027 32.8175 -2.73247 --0.837785 32.349 -2.38845 --1.4373 32.7327 -1.78645 --2.03614 31.9171 -1.55322 --2.64205 31.7399 -0.7156659 --2.36406 32.559 -0.3595359 --2.89143 33.0653 -0.9856779 --3.49647 33.6956 -1.43307 --4.00635 33.3102 -2.20197 --4.79921 32.6951 -2.15696 --4.26601 31.757 -2.15662 --3.44145 31.1484 -2.36106 --4.04371 30.4539 -2.69241 --4.98946 30.2386 -2.38614 --4.66825 30.6799 -1.58221 --3.88421 31.072 -1.00006 --3.73429 32.042 -0.6553929 --3.55747 31.6976 0.2217321 --3.07338 31.3927 1.01787 --2.65202 31.1353 1.92554 --3.29957 30.8531 2.61722 --4.11254 30.3284 2.30378 --4.11964 29.5557 2.9238 --4.94517 28.9952 3.19731 --5.24214 28.707 2.25672 --6.14416 28.6769 2.40584 --6.53914 29.3688 3.00292 --7.43784 29.3054 2.56336 --8.24169 28.6526 2.59794 --8.88821 29.1778 1.97046 --8.42479 30.0898 1.91363 --9.19729 30.3555 1.42448 --10.0964 30.4538 1.03751 --10.702 29.838 1.51218 --11.5917 29.5718 2.00446 --12.3678 28.976 2.08915 --13.128 29.5293 1.92096 --13.4164 29.415 0.9413711 --14.3768 29.7233 0.9179961 --15.0251 30.4365 0.7104011 --15.4782 31.2714 0.3161891 --15.0088 32.0131 0.6320801 --14.7495 31.9926 -0.3134299 --13.7501 31.9685 -0.5969969 --13.1513 31.3128 -0.9320179 --12.4397 30.6947 -0.4256129 --12.0249 30.6958 -1.40449 --11.8647 31.4803 -1.94959 --10.9002 31.478 -1.72169 --10.373 31.5295 -0.9139339 --9.7965 32.0939 -1.54774 --8.75692 31.9585 -1.19774 --7.77427 32.3404 -1.22765 --7.87702 33.1625 -1.84391 --7.16611 33.7385 -1.77668 --7.55527 34.6425 -1.7363 --6.76853 35.1712 -1.28314 --5.94382 35.3885 -0.8633469 --6.33886 35.5142 0.08145962 --7.02974 34.8142 -0.1394109 --7.60879 35.4437 0.3690931 --7.90159 36.3626 0.5828591 --8.00082 36.2182 1.60105 --8.9555 36.3684 1.83033 --8.65038 35.4533 2.12037 --8.65281 35.2336 1.09613 --9.05811 34.3651 1.27529 --9.38013 34.7124 0.4015691 --10.1681 34.6614 -0.03629528 --11.1581 34.6728 0.2770401 --10.5232 35.3808 0.4492561 --10.5128 35.8002 -0.4176029 --11.5195 36.0247 -0.3566409 --11.7164 35.6577 -1.28217 --12.2895 35.2112 -1.93386 --12.1598 34.969 -2.84266 --12.7899 35.2519 -3.57748 --13.6664 35.7889 -3.52062 --14.5986 35.6237 -3.62834 --14.549 36.4889 -4.08186 --13.5811 36.7464 -4.15018 --13.3111 36.4101 -5.08034 --13.8498 36.1271 -5.89633 --13.2452 36.8637 -6.23324 --12.3628 37.1122 -6.13566 --11.5113 36.5219 -6.33313 --10.7025 36.0134 -6.02406 --9.79561 36.0085 -6.27028 --9.26793 35.1676 -6.62764 --10.075 34.7026 -6.50401 --9.94211 33.8696 -5.93646 --9.39054 33.0792 -5.85284 --8.72588 32.4357 -5.61659 --9.24534 32.1388 -4.75888 --9.6295 31.4265 -5.3126 --10.483 31.2822 -5.8151 --9.93805 30.6359 -6.44165 --10.1612 29.9241 -5.80772 --9.59946 29.3771 -5.29024 --8.76407 29.6499 -5.66905 --9.07322 28.9045 -6.23688 --8.2435 28.3569 -6.68556 --7.34344 28.1158 -6.45939 --7.6192 27.7867 -5.5644 --6.72882 27.8812 -5.43861 --6.6068 26.9726 -5.2444 --5.77749 27.3196 -4.87182 --5.62143 26.6083 -5.51526 --4.91028 26.2641 -6.11898 --5.27422 26.5982 -7.00966 --5.12325 26.6151 -8.00203 --4.19758 26.7887 -7.66085 --3.34978 26.4552 -8.14885 --2.92657 27.1567 -7.55578 --2.93921 27.3615 -8.53039 --2.18222 26.8012 -8.79302 --1.36673 27.0627 -8.29153 --1.99763 27.6738 -7.87468 --1.30842 27.9974 -8.58431 --1.23887 28.9795 -8.25522 --0.403265 29.3763 -7.84262 --0.28253 29.0488 -6.91868 --0.642839 30.0442 -6.94809 --1.14596 30.5863 -6.40865 --0.586428 31.2946 -5.88146 --1.04519 31.9821 -5.40463 --0.221327 32.2531 -4.96117 -0.115777 32.9057 -5.64915 --0.779199 33.335 -5.6079 --0.718813 34.2161 -5.28741 --1.08568 35.1238 -5.38603 --0.944038 35.7175 -6.23396 --1.25636 34.7639 -6.41798 --2.01362 34.3918 -6.96988 --2.72462 33.8541 -7.40201 --3.2829 33.063 -7.47193 --4.01673 32.6415 -6.89943 --4.16528 32.92 -5.92928 --5.20726 33.0174 -5.85081 --5.57561 33.9062 -5.90624 --6.58718 33.7711 -5.81647 --6.1676 32.929 -5.9218 --6.1158 32.8305 -4.89903 --5.89646 32.0335 -5.51982 --5.15893 32.2793 -4.78035 --4.28304 31.887 -4.41032 --4.8279 32.0147 -3.58512 --5.12399 31.1103 -3.55506 --6.07002 30.8315 -3.73675 --5.61405 29.9114 -3.6375 --5.29811 29.027 -3.36657 --4.46187 28.5703 -3.56907 --3.53347 28.8199 -3.38953 --3.1563 28.0579 -2.8795 --3.03774 27.6528 -1.96877 --3.56876 26.8851 -1.62935 --3.84142 26.1854 -0.9115909 --3.23823 26.9089 -0.6148229 --2.29375 27.1068 -0.2153419 --2.28849 26.6519 0.7219641 --1.58742 27.4168 0.7723061 --2.07682 28.2219 0.7629331 --2.58421 28.6502 1.55457 --3.42861 28.965 2.01409 --3.88025 28.9584 1.13364 --4.25316 28.1812 0.6223221 --4.39479 27.1252 0.6810341 --3.46576 26.7763 0.4864701 --3.62229 26.5869 1.41911 --3.84727 25.8376 0.7606571 --3.33141 24.9088 0.6629501 --2.3871 24.7265 0.5470561 --1.8722 24.5808 -0.2684759 --2.33996 24.9482 -1.09996 --1.94896 25.2123 -1.94291 --1.34704 24.4567 -2.16147 --0.881582 24.1452 -1.32727 -0.05731957 24.5258 -1.37871 -0.01081447 24.5799 -0.3821189 -0.06028677 24.9415 0.5447481 -0.720344 24.3663 1.1336 -0.389512 24.1846 2.05443 --0.12885 23.7598 2.76759 --0.373567 24.5903 3.20918 --0.399037 24.3651 4.15771 --1.20352 24.9251 3.88259 --1.32044 25.9029 3.72326 --1.39141 25.942 4.75342 --2.38591 26.1606 4.58754 --3.11655 26.7577 4.75753 --3.68771 25.9718 4.57151 --4.28328 26.5728 4.05436 --4.95466 26.8151 3.45734 --5.41849 26.4222 2.69783 --6.40864 26.1944 2.77823 --6.98668 25.5684 3.33821 --6.57949 24.9885 4.06287 --5.6542 25.3081 3.84591 --6.05908 25.6954 4.69874 --5.98463 24.9077 5.4115 --6.0568 24.1348 6.04231 --6.95235 24.6339 6.1841 --6.73519 25.5102 6.513 --7.01314 26.2261 5.83519 --7.44436 26.3449 4.99031 --8.20531 26.1139 4.42455 --8.72787 25.6559 5.02419 --8.1653 24.843 5.0002 --8.41207 23.9066 4.97985 --8.67069 24.0019 3.99131 --7.70083 24.2352 3.81193 --7.94957 24.2787 2.83801 --7.72664 23.3035 2.89557 --6.84576 23.7231 2.64432 --5.94032 23.9818 2.31573 --5.78547 24.5767 3.05555 --5.98115 25.2986 2.38576 --6.92079 24.9546 2.38556 --7.57061 25.1444 1.64447 --6.95319 25.3672 0.8867401 --6.09321 25.6381 0.3708411 --5.3592 26.2191 0.5892371 --4.9325 25.4517 0.00815367 --5.42193 24.6363 0.1828431 --5.10492 23.6875 0.2053401 --5.32426 23.131 0.9929951 --4.83646 22.4216 1.5426 --4.02062 22.8576 1.84647 --3.74661 22.293 2.60514 --4.21102 21.7749 3.3157 --3.58229 21.0404 3.5106 --4.17664 20.2092 3.34811 --4.54572 20.4387 4.24323 --4.08404 21.2659 4.56684 --4.98129 21.7001 4.63108 --5.5415 21.7172 5.3966 --5.54169 22.6447 5.06409 --5.84643 23.5924 4.83574 --5.30939 23.4956 5.65634 --5.35936 23.4691 6.6542 --6.07607 23.7546 7.25969 --6.01784 24.5863 7.84923 --5.58553 25.344 8.39298 --5.98508 25.5364 9.21597 --6.84137 25.2178 8.83013 --6.69244 24.2341 8.80802 --5.88883 24.0697 9.41446 --5.84233 23.0663 9.49857 --5.50628 22.3773 8.96647 --4.88463 22.9386 8.37951 --4.68049 23.8953 8.0961 --4.44779 24.8714 8.01635 --4.60973 25.5314 7.29506 --5.10913 25.1421 6.47988 --4.46363 25.0403 5.71182 --3.85496 24.3095 5.4336 --3.5544 24.8744 6.29658 --2.98237 25.285 5.67092 --1.98425 25.1829 5.86711 --1.94154 25.4879 6.87341 --2.20494 25.7029 7.74889 --1.43238 25.1368 7.87075 --1.72595 24.5375 8.60984 --1.04091 23.951 8.15911 --0.374104 23.1673 8.44135 -0.200434 23.3861 9.22563 -0.625364 24.0235 8.62792 -1.565 23.7492 8.91318 -1.56927 24.1007 7.97938 -1.9009 24.066 7.07811 -2.47254 24.7348 7.59463 -2.8728 25.4289 6.93957 -3.72549 25.7873 7.23667 -3.49076 25.6963 8.19929 -3.11532 26.2848 8.95176 -3.48422 26.334 9.91602 -4.34196 26.3147 10.4414 -4.16966 25.3585 10.5833 -3.98052 24.4027 10.8783 -4.34375 23.4995 11.0523 -3.6548 23.3615 11.7932 -4.64356 23.2432 12.0813 -4.95101 23.3855 12.9588 -5.76779 23.6052 13.6099 -6.32103 24.303 13.1245 -7.19917 24.1669 13.5383 -8.07128 24.5421 13.0713 -8.6735 25.2829 13.1728 -8.41718 26.2274 13.037 -7.74779 26.9557 13.2952 -7.41915 27.5339 14.0005 -7.03155 27.5085 14.9136 -7.64374 26.8023 15.29 -7.02049 26.1281 15.6659 -7.7618 25.4399 15.6979 -7.09938 24.7524 16.0272 -6.88241 24.2998 15.246 -6.01043 24.2046 15.7749 -5.92909 23.9256 16.739 -4.98639 23.5744 16.5254 -4.32475 24.2407 16.1846 -4.32958 25.1432 16.6547 -5.18068 25.424 16.21 -5.30387 25.976 15.306 -5.74838 26.48 16.0816 -5.33377 27.4117 16.1127 -4.71565 27.5516 16.9351 -3.87749 27.568 16.3776 -3.46667 27.2388 15.4699 -2.62861 27.0347 15.9497 -2.12911 26.9227 15.0447 -2.19746 26.9446 14.0543 -1.76275 27.6755 13.4142 -0.858209 27.2628 13.3545 -0.798871 28.0823 12.8046 -0.165199 28.7795 12.4367 --0.601192 28.3972 12.8524 --1.36019 28.1195 12.3627 --2.1282 28.0332 11.7677 --2.39566 27.2658 11.045 --3.25478 27.3655 10.541 --4.09646 26.8483 11.0105 --3.84542 26.4754 10.1214 --3.17747 25.6991 9.88881 --2.79756 24.9397 10.4629 --2.80823 23.9541 10.4612 --2.41126 23.4329 11.2486 --2.72616 23.3711 12.2099 --3.57313 23.0941 12.6526 --4.57359 23.3179 12.7047 --4.4732 24.2715 12.9772 --5.35121 24.5551 13.4249 --5.36753 25.2542 14.2046 --4.64914 24.877 14.7575 --4.60197 23.8989 15.0149 --4.45984 23.3608 15.8749 --4.24253 22.3549 15.8295 --4.23686 21.7892 14.9984 --4.61953 21.1999 14.2812 --4.83951 20.4333 13.7433 --4.41586 21.2761 13.3969 --3.79156 20.4977 13.5373 --2.9538 20.8898 13.7505 --2.26467 21.4726 14.0725 --2.31232 22.5126 14.2164 --2.28534 23.3248 14.7459 --2.74748 23.4274 15.5834 --2.61819 24.3016 15.1136 --2.81689 24.9856 15.8709 --3.5793 25.5041 15.4177 --4.12039 25.6056 16.2359 --4.11598 25.4946 17.2301 --4.40204 25.6311 18.165 --5.17168 25.4593 17.6076 --5.49244 25.9859 16.7389 --5.01978 26.7189 17.1655 --4.94943 27.3594 16.4315 --4.46305 28.1638 16.8332 --4.56374 29.1023 16.9777 --3.80231 29.2941 17.6132 --3.1089 29.1271 16.8993 --2.54083 29.9196 16.9993 --1.59066 30.3134 17.0923 --1.1229 29.4637 17.2553 --1.14312 28.9605 18.2044 --1.30184 28.0762 17.768 --1.05529 28.1404 16.8585 --1.68432 28.2153 16.1193 --2.42842 28.3236 15.4337 --1.92905 29.1171 15.1302 --2.54604 28.7882 14.4 --2.0673 28.2568 13.6843 --2.60336 28.0729 12.8254 --3.12155 27.1834 12.7914 --2.35718 26.8774 12.2586 --2.43114 25.8504 12.3694 --1.63722 25.254 12.2677 --1.5684 24.5114 12.9763 --1.48359 23.6657 12.4284 --1.96742 23.1762 13.1371 --1.18358 22.794 13.6898 --0.507825 22.8599 14.4092 --0.05433643 23.5241 14.8403 -0.668893 22.958 15.1637 -1.50856 22.6407 15.5632 -1.028 21.8296 15.4829 -0.07321817 21.9168 15.2226 --0.65852 21.4606 14.9177 --1.61644 21.6846 15.0972 --1.8735 20.7882 15.4069 --1.46234 21.1457 16.3133 --2.32776 20.6292 16.3941 --2.75861 20.0501 15.7049 --3.16543 19.569 16.5029 --2.43822 19.6946 17.1356 --1.61724 19.1937 16.8644 --1.15335 18.9746 17.7189 --1.68777 18.6003 18.4684 --2.25573 17.9106 18.0308 --2.87305 17.1668 17.8954 --3.77453 17.5305 17.9836 --3.52465 18.4716 17.7732 --2.82061 18.5605 18.4642 --3.00986 19.4183 19.0047 --3.23499 20.3556 19.2438 --3.79123 20.7477 20.019 --3.80244 21.4727 20.7766 --2.94677 21.5422 21.2447 --2.64418 21.0888 22.0964 --3.57737 20.8015 22.0233 --4.01319 21.5928 22.3278 --3.43601 22.4478 22.217 --2.88411 22.9589 21.5848 --2.12563 23.2235 21.0188 --2.61697 24.0469 21.2506 --2.03738 24.8801 21.1534 --2.0287 25.2974 20.2898 --2.23007 24.7035 19.4541 --1.46051 24.8875 18.8351 --2.10912 24.0858 18.4674 --1.19084 23.8358 18.1737 --0.740076 23.3516 17.3989 --0.265618 22.9754 16.603 -0.605279 23.2541 16.6948 -1.11872 22.7831 17.3811 -1.91475 22.4608 16.8281 -2.86022 22.713 16.6807 -2.88863 23.6636 17.0036 -2.86322 24.1841 16.1518 -2.10197 24.0707 15.5295 -2.84132 24.1226 14.82 -3.52462 24.817 15.1271 -3.8884 24.8706 14.1975 -4.0354 25.799 14.7331 -4.08933 26.7577 14.6183 -4.68638 27.4735 14.1669 -4.95238 27.7266 13.2267 -5.77237 28.3535 13.2546 -5.95079 27.8683 12.4157 -5.70663 27.3071 11.6404 -6.31632 26.5029 11.3883 -5.93388 26.0987 10.5981 -6.52741 26.109 9.80137 -7.30859 25.9932 9.24034 -8.10113 25.4722 9.39725 -7.95904 24.9823 10.2077 -8.1429 24.0128 10.4877 -7.42868 24.4346 10.9488 -6.44971 24.3737 10.674 -6.89257 23.6778 10.1628 -6.27228 23.0026 9.79615 -6.02409 22.128 9.48066 -5.12978 22.4611 9.0305 -4.53577 21.6145 8.9449 -3.71109 21.0241 8.90119 -2.85057 21.2636 9.35446 -1.9413 20.7537 9.44108 -2.65522 20.3665 8.74518 -3.15351 19.5544 8.35806 -3.15054 20.2241 7.60034 -3.98942 19.7089 7.8961 -3.70201 18.891 7.40375 -3.6261 18.9236 6.43456 -4.16954 19.3119 5.66922 -4.1138 19.2312 4.64166 -4.97744 18.8078 4.50366 -5.23305 17.8891 4.36048 -4.52341 17.182 4.11835 -3.68574 17.7747 3.91331 -2.96962 17.1117 3.90105 -2.14822 16.9828 4.40229 -2.68032 16.1602 4.36198 -3.17917 15.2834 4.52826 -3.66863 15.1609 3.63661 -2.86535 15.2134 2.99398 -3.0322 14.5755 2.27037 -3.60448 15.0631 1.62054 -3.94464 15.7259 2.23522 -3.46124 16.5334 2.49204 -4.38066 16.9094 2.74684 -5.24202 17.4352 2.54948 -6.06459 18.0134 2.57911 -5.80759 18.3402 1.64035 -5.34395 18.3589 0.6857281 -4.70443 19.0692 1.06119 -3.84141 19.4112 0.5961561 -3.62905 20.3411 0.1899651 -2.79543 20.1032 0.7393601 -3.33326 20.7304 1.29807 -3.00398 20.3368 2.1975 -2.96129 19.9202 3.16747 -2.84788 18.972 2.88304 -3.87748 19.0423 2.68859 -4.39104 19.8519 2.29307 -4.3144 20.0069 3.32605 -5.0928 20.6129 3.44193 -5.72143 21.441 3.63143 -5.32545 22.1055 3.05773 -4.49515 21.694 2.74134 -3.86052 21.0872 3.11457 -3.98154 21.411 4.06191 -3.3495 22.0227 3.59418 -3.46253 23.0207 3.52452 -4.37022 23.3338 3.17152 -5.31206 23.4749 2.76176 -5.65437 24.3527 2.35673 -5.61541 25.211 1.8534 -4.88303 25.88 1.96793 -4.36757 26.3118 1.23545 -3.72583 25.9778 0.6072841 -3.69551 26.3701 -0.3369459 -3.66503 25.465 -0.7755199 -2.97724 25.9493 -1.39636 -2.8005 26.6879 -2.16618 -2.06061 27.0988 -1.66501 -1.39155 27.487 -1.03251 -1.15039 28.4291 -0.6387749 -0.8435 27.7264 -0.00639932 -0.124248 27.394 -0.6469309 -0.269962 27.5182 -1.58935 --0.499252 27.2253 -2.03533 --0.952158 28.0261 -1.94637 --1.44845 28.4741 -2.72132 --0.485889 28.8051 -2.57439 -0.497312 28.8501 -2.58795 -0.523447 28.7435 -1.54201 --0.250615 29.3583 -1.54753 --0.362953 30.3365 -1.44712 --1.09124 30.7275 -0.8671219 --1.17616 31.383 -0.1576239 --0.428744 32.0069 -0.4520039 -0.175879 32.7988 -0.2103159 -0.411969 32.9642 0.7638831 -1.24031 32.2633 0.8783661 -1.0915 32.3433 1.8541 -0.114211 32.594 2.12278 --0.557941 33.228 2.48707 --1.34849 33.807 2.51853 --2.30215 33.5235 2.20824 --3.17343 33.0944 2.12705 --3.20241 34.0361 2.39952 --2.82042 34.5035 3.27026 --3.52549 33.8527 3.51665 --4.19088 33.8782 2.85603 --4.21389 34.8432 2.50092 --4.19283 34.1982 1.74094 --4.9787 34.3679 1.2182 --5.81559 33.7637 1.03629 --6.2667 33.286 1.68496 --6.52858 32.4562 1.09322 --7.03132 32.3765 1.9672 --6.51764 31.8131 2.56158 --6.15298 32.2851 3.42521 --6.04543 33.2621 3.05697 --5.13561 32.9053 3.15449 --5.04502 31.9013 3.00551 --5.17065 31.1069 3.69411 --5.03831 31.595 4.62143 --4.60065 31.4296 5.47344 --5.07482 31.0482 6.33279 --5.27723 30.08 6.35773 --4.36464 29.857 6.07885 --3.6201 29.3621 5.54776 --4.18881 28.954 4.83172 --4.09797 28.0199 4.47954 --3.32376 28.3566 3.93839 --2.42124 28.0405 3.88556 --1.63586 27.5052 3.61714 --1.71052 27.8762 2.68082 --0.807552 28.2881 2.56586 -0.146168 27.7659 2.62488 -0.315976 27.7058 3.57063 -0.546676 28.6977 3.46387 -0.942399 29.4421 2.99156 -1.44555 29.3176 3.88401 -2.02803 28.7137 4.46746 -2.81691 28.1783 4.1128 -1.939 27.6026 3.9745 -2.0084 26.9151 4.7554 -2.85507 27.114 5.24292 -3.53069 26.7457 5.85298 -4.43976 26.4595 5.50072 -5.03002 26.9691 4.87841 -5.83226 27.5268 4.98194 -6.06497 26.6018 5.30864 -6.07821 25.5863 5.47849 -7.03218 25.8635 5.35358 -7.85524 25.478 4.96221 -7.93833 26.1519 4.31092 -8.05976 26.8523 3.55811 -7.16932 27.335 3.49088 -6.68866 26.548 3.79262 -6.03497 25.79 4.00531 -6.53799 24.8537 4.25053 -7.44608 24.4964 3.86831 -7.90794 23.7124 4.11227 -6.93982 23.5557 4.04694 -7.21409 23.1614 4.95705 -7.75108 23.4831 5.68514 -7.69645 24.2714 6.40987 -7.2628 24.1207 7.313 -7.7915 24.0239 8.2387 -7.92137 23.2921 8.91856 -8.7018 22.7722 8.54838 -9.4142 22.1653 8.89383 -9.98993 22.8994 8.54634 -10.2311 22.0809 7.97985 -9.68705 22.8198 7.45578 -9.43208 23.4581 6.67319 -9.0154 23.1411 5.85197 -8.7367 22.533 6.61283 -8.94235 21.7355 6.02411 -8.32218 21.1218 5.71764 -7.9984 20.2439 6.03976 -7.61732 19.4144 5.62769 -7.07591 20.0448 6.09147 -6.33706 20.055 6.73041 -6.23779 19.1795 6.37574 -6.644 18.3062 6.65948 -5.92493 17.6155 6.9209 -4.99878 17.1892 6.8662 -5.49832 16.3343 6.84893 -6.46704 16.2524 6.7578 -6.65443 15.3157 6.43804 -6.94987 14.6058 5.79635 -7.25246 14.3374 4.81704 -6.43946 14.3159 4.23301 -5.69776 14.4861 4.92904 -4.83117 14.0286 5.00911 -4.60102 14.8782 4.67228 -5.2536 15.4778 4.97607 -5.44443 15.3849 3.99959 -6.39721 15.7481 3.97795 -6.32565 16.6633 4.40128 -7.10864 16.4954 4.99718 -7.73829 15.8141 5.3851 -7.89235 15.3377 4.52398 -8.82293 15.7205 4.59278 -9.54464 15.3688 4.05746 -9.93949 16.18 3.59235 -9.93216 15.9381 2.67776 -9.51695 16.8997 2.63979 -9.57154 16.3981 1.72875 -10.0494 17.1965 1.58638 -9.90552 18.0199 1.00076 -9.47369 18.8973 1.18179 -8.97956 19.8343 1.1964 -8.10062 19.6543 1.13398 -7.16282 20.0385 1.17565 -7.36561 19.1382 0.6912251 -8.22572 18.7182 0.3346041 -8.37583 18.4203 -0.5777199 -9.29366 18.575 -0.9219399 -10.1558 19.1108 -1.00503 -10.9718 18.5908 -0.7414219 -11.839 18.9717 -1.22374 -11.813 18.0853 -1.74475 -12.6926 17.5528 -1.60841 -13.5673 17.974 -1.46877 -13.8896 17.055 -1.65871 -14.4863 17.3373 -2.45847 -15.0416 18.0931 -2.33568 -15.0886 19.1627 -2.46906 -14.1922 19.5877 -2.53466 -13.4493 19.2966 -3.19849 -12.8693 19.9763 -2.80448 -13.0035 19.7243 -1.75751 -13.1265 20.7596 -1.6247 -13.5319 20.8761 -2.545 -14.0577 21.7411 -2.47959 -13.9735 22.5302 -2.02284 -14.7602 22.7733 -1.6355 -15.3077 22.7644 -0.7915359 -14.7104 23.5165 -0.6102559 -14.7461 24.4654 -0.2253649 -15.5156 24.1524 -0.8457779 -15.8875 24.6468 -1.60022 -15.0957 24.7596 -2.13767 -15.6688 24.6762 -2.88658 -15.2828 23.9765 -3.52221 -14.9026 23.2374 -3.01179 -14.2653 23.9559 -3.09328 -13.4748 23.86 -3.7925 -13.698 23.0489 -3.30347 -13.1687 22.239 -3.09649 -12.1471 22.3622 -2.95932 -11.8776 22.2872 -1.98131 -12.8142 22.1295 -1.89842 -13.5338 21.8997 -1.21585 -12.7897 21.7684 -0.4922629 -12.8331 22.7191 -0.3845369 -12.064 23.2825 -0.4727759 -11.6605 23.1312 0.4048221 -10.6663 23.1177 0.5041871 -10.2976 22.368 1.08864 -10.8156 22.9242 1.78291 -9.86011 22.9564 2.12804 -9.11579 22.3868 2.27044 -9.73866 21.6166 2.1906 -9.03895 21.5064 1.44306 -9.11104 20.7772 2.2187 -8.16959 20.7845 1.86257 -7.25693 20.9523 1.97105 -7.49479 20.1615 2.50412 -6.6675 19.7595 2.94218 -7.44523 19.266 3.35371 -8.09009 19.6624 4.03115 -8.99787 19.3679 3.95897 -9.56443 19.0439 4.75228 -9.77773 20.0443 4.85438 -10.2252 19.9924 4.05925 -10.9278 20.6135 3.85418 -10.8884 21.4608 3.35956 -10.8905 22.1475 4.05423 -11.6369 22.6835 3.8726 -12.5065 23.2284 3.93356 -12.9074 24.0919 3.62875 -12.2898 23.6195 2.97591 -12.9739 24.2228 2.43682 -13.296 24.9067 1.7144 -13.7063 24.5194 0.8808131 -12.9687 25.1205 0.7368901 -13.3997 25.8815 1.30133 -12.5026 26.4082 1.21489 -12.1595 25.8564 0.4625661 -11.3058 26.1744 0.04738462 -11.393 25.7427 -0.8495979 -11.4948 26.4753 -1.49648 -11.0466 25.5953 -1.73607 -10.313 26.2032 -2.10052 -9.55026 26.1847 -2.82557 -10.1739 26.7848 -3.42565 -10.3036 27.6282 -2.82269 -10.5738 27.6168 -1.79384 -10.9596 28.5324 -1.70759 -11.8823 28.1082 -1.55468 -12.5793 28.6498 -2.02127 -12.0909 28.4438 -2.94297 -11.7802 29.2415 -2.45601 -11.5093 29.5716 -1.63041 -11.86 30.3115 -1.03471 -10.882 30.3722 -0.6646099 -11.0941 30.8713 -1.48064 -10.1562 30.6159 -1.45389 -10.0288 29.6845 -1.64582 -9.43697 28.8951 -1.36703 -8.70411 29.5388 -1.50718 -8.60923 28.6628 -1.8336 -8.63965 27.7323 -1.46517 -7.70001 27.5717 -1.0987 -7.93171 28.1278 -0.2918329 -8.7645 27.5607 -0.3492799 -8.13413 26.8321 -0.5675659 -8.73651 26.609 0.1254721 -9.80152 26.6885 0.2134651 -10.4825 27.2239 -0.2206109 -9.87381 27.8921 0.2725441 -9.70034 27.5793 1.12252 -10.2035 27.8465 1.94505 -11.1995 27.7466 1.88984 -11.8976 28.3401 1.37983 -12.5198 29.0406 1.36317 -12.0743 29.6168 2.058 -11.6254 28.8641 2.47217 -11.0617 28.3056 3.06338 -11.6332 27.4704 3.25714 -11.5097 27.5955 4.31084 -10.63 27.0631 4.39976 -10.2915 26.7331 5.2787 -10.0677 25.7388 5.27005 -9.70714 24.8326 4.93369 -10.6416 24.5426 4.69713 -11.4605 24.8821 5.17973 -12.2802 25.4007 5.20537 -13.0286 25.3773 4.58096 -13.1566 24.7474 5.28129 -14.1173 24.9275 5.03533 -14.7214 25.3904 5.70022 -14.2466 26.0913 5.25757 -13.7672 26.0341 6.15128 -14.3597 26.4129 6.8815 -15.2269 26.8476 6.57488 -15.3682 27.2773 5.62638 -14.5438 27.7074 5.26788 -14.3193 28.5152 5.82116 -13.8109 29.2049 6.38563 -12.8644 28.8642 6.35611 -13.1591 28.229 7.05233 -13.9023 28.0856 7.71693 -14.1861 27.5614 8.58243 -13.9154 27.0207 9.30329 -13.9259 26.0025 9.11698 -14.1483 25.067 8.81214 -13.7537 24.3278 9.23465 -14.1216 23.4014 9.00749 -13.2737 23.2876 9.54717 -13.5151 22.4751 10.0644 -13.8382 21.6018 9.62541 -12.9227 21.5995 9.36597 -12.0301 21.7599 8.91004 -12.2291 21.2901 8.05426 -12.572 20.3633 8.00513 -13.0628 21.0783 7.41 -14.0126 21.1563 7.73254 -14.2919 20.97 8.64386 -13.415 20.4478 8.58495 -13.2952 19.5879 8.96383 -12.4693 19.0328 8.68721 -13.0903 18.5734 8.03401 -12.9506 17.919 8.74074 -12.12 17.7348 9.16984 -11.8414 18.0225 10.1043 -12.0218 18.7977 10.7517 -11.8285 19.7742 10.5481 -10.9928 19.6024 9.95195 -10.4441 19.2762 9.17212 -10.7759 19.9358 8.59161 -11.2698 19.3038 8.06628 -11.3234 18.2995 7.70314 -10.9891 18.9738 7.05285 -10.0413 19.0973 6.66177 -9.66829 18.969 7.64173 -8.87224 19.4916 7.4387 -8.76947 18.5977 7.9625 -8.07874 17.9429 7.88849 -8.72658 17.3 7.4641 -8.23209 17.5377 6.63707 -8.92981 17.8059 5.99973 -9.92866 17.6524 5.67887 -10.5569 16.8682 5.57014 -9.89864 16.4349 6.13436 -10.0414 15.5497 6.51405 -10.326 14.7074 7.00137 -10.2128 14.4757 7.98707 -9.58468 14.601 8.68692 -8.91282 13.9138 9.01112 -8.34139 13.2336 8.5331 -8.38531 12.4778 9.16798 -8.56698 11.6018 8.83985 -9.17235 11.2874 9.56349 -9.19877 11.6839 10.5131 -9.4579 12.5944 10.9226 -9.51126 13.4039 10.3234 -9.01631 14.2553 10.5615 -9.48126 13.9665 11.4027 -9.9907 13.4047 12.0905 -10.5335 14.0641 11.4901 -10.9877 14.631 12.1282 -10.7426 15.5872 12.2359 -11.4896 16.1712 12.5715 -10.7428 16.6568 12.1994 -9.9389 16.2712 12.5418 -9.23641 16.9906 12.8142 -8.68317 17.6602 12.4408 -7.71939 17.8138 12.234 -6.94815 17.3088 11.9326 -6.85313 16.3408 12.25 -7.1339 15.6198 12.9225 -7.73208 14.8532 13.0971 -7.64984 14.2199 12.348 -7.91316 14.8583 11.6094 -7.58864 14.1329 11.0289 -7.24921 14.529 10.1812 -6.49775 13.8647 10.104 -6.1021 14.7548 9.84989 -5.86363 15.7955 9.92081 -5.33295 15.1337 10.4708 -5.05287 14.1849 10.3256 -5.04332 13.3062 10.7999 -5.88357 13.5527 11.2881 -5.67894 13.4935 12.238 -6.21834 14.1601 12.7957 -5.94364 15.1106 13.1262 -5.30485 15.8455 13.3233 -6.07451 16.5521 13.5171 -6.70263 16.8099 14.1856 -7.46941 17.4003 14.1068 -6.58957 17.7658 13.8366 -6.12165 18.2173 14.5516 -6.5684 19.0412 14.2204 -6.80946 19.9326 13.8528 -7.13011 19.3534 13.1374 -6.13108 19.7967 13.0076 -5.94824 18.7944 13.0541 -5.0322 18.4747 12.8288 -4.44314 18.9986 12.1544 -4.68025 19.374 11.2539 -4.02685 19.5066 10.5372 -4.34358 19.7113 9.63453 -5.10272 20.3516 9.50812 -5.83014 19.6744 9.64821 -6.12097 20.5987 9.23448 -6.94707 21.1215 9.46936 -7.68818 20.9827 8.82092 -7.39587 20.6619 7.8612 -7.60686 19.6542 7.80271 -7.10098 19.3929 8.6685 -7.07763 18.9319 9.51898 -6.86072 18.8547 10.531 -5.97621 18.485 10.912 -5.90961 17.8507 11.6996 -4.94925 17.6047 11.4864 -4.54355 16.8197 11.9638 -3.71558 17.1667 12.4514 -2.8484 16.6904 12.4375 -2.28598 15.8717 12.1233 -2.47512 14.9907 12.4697 -3.3235 14.9183 11.9683 -3.7266 14.0149 12.2479 -3.02164 14.3748 12.7991 -2.70476 14.5763 13.7605 -2.06232 14.0725 14.343 -1.33524 14.5079 14.874 -1.64119 13.6201 15.1898 -1.28575 12.9829 14.4963 -0.372357 12.7643 14.2414 --0.570488 12.6148 14.2662 --0.422134 12.9211 15.1253 --0.524936 13.4218 15.9762 --1.07107 14.0473 16.626 --1.26566 14.921 16.2158 --1.40561 14.349 15.3917 --2.19336 14.2975 14.7449 --2.56719 14.6074 13.8832 --1.95531 14.8507 13.1059 --1.36694 15.1412 13.9086 --0.641526 15.7056 13.6039 --0.873023 15.8419 14.5554 --0.454374 16.6788 14.8086 --1.4164 17.0106 14.9861 --2.42202 17.0497 14.9785 --1.92985 17.9276 15.2725 --2.04999 18.3293 14.3678 --2.33283 19.1777 13.8217 --2.57383 19.5828 12.9627 --2.77892 19.004 12.188 --3.49935 19.0076 11.5021 --4.02549 19.5486 12.0985 --3.61947 18.8565 12.7721 --3.27377 17.9121 12.9943 --4.25655 17.9446 13.207 --5.2569 17.8635 13.2426 --5.31713 17.4825 12.3166 --6.06317 16.9463 12.1725 --7.00794 16.7023 11.7645 --6.25482 16.5944 11.0425 --5.28032 16.5848 10.8488 --5.50864 17.3181 10.2282 --4.77742 16.9068 9.91409 --4.01633 16.9922 9.21362 --4.00912 17.9576 9.06942 --3.25047 17.9201 9.66235 --2.6161 17.2094 9.96054 --1.66218 16.9889 10.0959 --1.28099 16.0662 9.86135 --0.730376 16.0793 9.03248 --1.58434 15.8198 8.46087 --1.62905 16.7738 8.13273 --1.70814 17.344 7.35144 --0.828279 17.8123 7.1089 --0.625571 16.9351 7.57498 -0.03675137 17.0226 6.83019 -0.288142 16.1884 7.26564 -0.173755 16.6089 8.18156 -0.477385 17.0826 9.01805 -1.01355 16.337 9.37735 -1.72967 16.9936 9.40559 -1.76414 17.834 9.95674 -1.55818 18.6677 10.5338 -1.7114 19.5605 11.0641 -1.53824 20.6047 11.1336 -2.25493 20.7903 11.8565 -2.84436 19.958 12.1183 -2.31016 19.5112 12.8249 -1.69856 19.3125 12.0757 -1.46413 18.4521 12.5639 -0.539015 18.6657 12.7728 -0.641699 17.7516 12.2847 -0.762594 17.8221 13.2788 -0.893094 18.6316 13.9789 -0.248856 18.4498 14.7624 -0.349679 19.4293 14.8412 -0.03856737 19.1865 13.9043 --0.714265 19.354 13.2995 --0.550001 19.5633 12.347 --0.459589 18.6013 12.2051 --1.30096 18.1393 12.3625 --0.627967 18.3689 13.1389 --0.396334 17.337 13.2278 --0.699587 16.407 12.9011 -0.100275 16.2545 12.2175 --0.702126 15.6068 12.1808 --0.391756 14.9697 11.5222 --1.17852 14.5233 11.9328 --1.35382 13.5176 11.829 --1.90816 13.4548 10.984 --2.89993 13.258 10.9468 --2.51056 12.9016 10.0425 --2.90396 12.209 10.6579 --3.74698 11.7955 10.1721 --4.08969 12.7458 10.5025 --4.4644 12.3694 11.418 --4.24788 11.5032 11.7971 --3.71926 10.5928 11.9768 --4.0911 10.1578 12.7592 --4.50259 9.3186 12.5044 --3.5523 9.17693 12.0684 --2.91319 9.35675 12.8224 --2.81576 10.3449 12.7251 --3.16771 11.2965 12.7187 --2.24024 11.3368 13.0166 --1.27192 11.5832 12.9692 --0.849444 12.2718 12.3524 --0.642816 12.647 11.4286 --0.146849 12.1184 10.7166 -0.702474 12.1679 11.3533 -1.10476 11.3088 11.2607 -1.73562 11.6143 10.5653 -1.7681 12.624 10.7642 -2.03514 12.3118 9.84224 -2.9633 12.6074 10.1113 -2.67106 13.5922 10.1516 -1.831 13.8798 9.77869 -2.15671 13.8025 8.88815 -3.0379 14.2889 8.76921 -4.02038 14.1137 8.70705 -4.08634 14.8572 9.30209 -3.35664 15.4542 9.51111 -3.8894 16.3063 9.49597 -3.18246 16.2392 8.85902 -2.78192 16.6922 9.61597 -2.59334 17.3952 10.2974 -3.59087 17.6622 10.2543 -4.61264 17.6259 10.3181 -5.20812 17.6742 9.59419 -5.43794 16.9196 8.94688 -4.72046 17.4591 8.60737 -4.00994 17.4685 7.84092 -3.2647 17.5378 8.49736 -2.74716 18.3854 8.5677 -1.99862 18.79 7.97817 -1.5164 19.1932 7.23904 -0.624325 19.6568 7.51545 --0.06048783 19.5806 8.35444 --0.52539 20.4709 8.33128 --1.36677 21.0827 8.49806 --1.2512 22.0951 8.42742 --1.41451 22.4664 7.50865 --2.05723 21.9586 6.9184 --1.8983 20.9876 6.90132 --0.996995 21.2622 6.87722 --0.733533 21.9082 6.17622 --1.61291 21.8025 5.88257 --1.89453 20.9557 5.45389 --1.13375 20.3186 5.64063 --0.946787 19.3182 5.84295 --1.7866 19.3859 5.2993 --2.54299 20.0131 5.3037 --2.9938 20.498 6.07214 --3.71919 20.2434 5.49413 --3.9281 19.3279 5.9686 --4.19202 18.3431 6.09192 --5.02676 18.4131 5.56337 --5.16027 18.877 6.41773 --5.2888 18.1382 7.08718 --4.73672 18.7081 7.62508 --3.74544 18.6487 7.63749 --3.5871 19.6834 7.55872 --2.55659 19.6981 7.57298 --2.23199 19.2637 6.74297 --2.02805 18.3281 6.53404 --2.26304 17.4023 6.32353 --1.7874 16.6838 5.75903 --1.42245 15.8191 6.07022 --1.15527 15.2126 6.76944 --1.67334 14.3673 6.44217 --2.59624 14.6765 6.48107 --2.25319 14.9696 5.53179 --1.24346 15.0899 5.50036 --1.24152 14.3561 4.77137 --1.01712 13.6194 5.43449 --0.165073 13.4877 5.90748 --0.344089 12.9885 6.72692 -0.170122 12.6919 7.5525 -0.856537 12.6687 8.30853 -1.19168 13.4238 7.78978 -0.843016 13.8562 6.9856 -0.497063 14.6782 6.43598 -0.987224 14.2537 5.66626 -0.97415 15.1545 5.15463 -0.754054 14.9442 4.20441 -1.25312 14.4422 3.42775 -1.98992 13.9128 3.35292 -2.64772 13.9833 4.19103 -3.15463 13.5335 4.93587 -3.23733 12.7239 5.4081 -2.40366 12.1578 5.62925 -1.72917 12.8371 5.36006 -1.34361 12.0461 5.84586 -0.439896 11.8431 5.51642 -0.653859 11.4607 4.63538 --0.365478 11.5811 4.60041 --0.582618 12.5703 4.82899 --1.50038 12.6282 5.22958 --1.77765 12.8064 6.23654 --2.46151 12.3094 5.73303 --3.26406 12.9173 5.54064 --4.19563 13.2809 5.92031 --3.7498 14.1176 5.70755 --3.38601 15.0786 5.81031 --3.46643 16.0532 5.55687 --3.55266 15.9249 4.60491 --3.42449 15.4783 3.76771 --4.35322 15.1399 4.13377 --3.72416 14.5024 3.68028 --3.94446 14.05 2.78798 --4.46877 13.2378 2.43268 --5.07211 13.9186 2.00011 --4.70697 14.4417 1.24035 --3.75031 14.2793 1.3437 --3.75385 14.6448 0.3652931 --3.68044 14.0747 -0.3757729 --2.7763 14.2921 -0.08460558 --2.08005 14.9841 0.2148171 --1.16099 15.1793 -0.02616548 --0.914376 15.1192 0.9394001 --0.842282 16.0243 0.4220811 -0.06495947 15.7628 0.1862331 -0.441015 16.4712 -0.4377529 -0.380865 17.0878 -1.21726 -1.23863 17.4652 -1.51679 -1.67899 16.6344 -1.28902 -2.66465 16.4733 -1.32675 -2.78594 17.4195 -1.29102 -2.77903 17.8583 -0.3950459 -3.23536 17.2737 0.2824581 -2.89888 17.7271 1.0711 -2.1202 17.7307 1.65862 -1.50747 17.5527 0.9664801 -1.14867 16.6395 1.13757 -1.34209 16.1387 1.93622 -0.384462 15.9773 1.56542 --0.641332 16.0509 1.586 --0.675315 15.6496 2.5297 --1.25586 16.4816 2.71904 --0.25321 16.5734 2.86834 -0.12381 17.4354 2.56546 -0.02889827 18.2421 3.13185 --0.08362913 18.6968 2.36022 -0.460568 19.4027 1.94047 --0.176184 20.1338 1.8605 --0.005404535 21.0883 1.68407 --0.923716 20.9229 1.25333 --1.18397 20.28 0.5181501 --0.50181 19.5299 0.6296351 --1.13942 19.0193 0.03415492 --1.99437 18.7508 0.5891121 --1.67405 17.973 1.12654 --2.02125 17.742 2.02912 --2.78851 18.271 2.4401 --3.04128 17.3312 2.51895 --3.47363 16.5652 2.03891 --3.32641 15.6433 1.59156 --2.31402 15.8681 1.63882 --1.98204 16.0918 0.7037461 --2.32094 16.9963 0.7324481 --2.56964 17.6899 0.05118072 --3.46455 17.2733 0.1348021 --3.92358 16.9164 0.9495841 --3.68374 17.7302 1.41665 --4.15213 18.5586 1.29552 --3.94066 18.6875 2.23518 --3.70992 18.3973 3.16562 --4.42848 17.7327 3.04279 --4.42269 16.8093 2.5853 --4.6135 17.5477 1.95493 --5.48583 17.3385 1.48943 --5.56177 17.8833 2.32269 --6.25062 17.2807 2.75285 --6.04636 16.3377 3.06366 --5.99379 15.3661 2.67272 --5.25129 14.9935 2.20611 --5.11506 14.7025 3.13457 --5.94825 14.742 3.70721 --6.76718 14.5218 4.17508 --7.64833 14.286 3.91217 --8.48066 13.6841 4.13956 --8.71028 12.7621 3.98458 --8.63706 11.8824 4.10091 --9.30519 11.9795 4.791 --9.60779 12.0998 5.71001 --9.9182 12.9455 5.97602 --10.4378 12.0748 6.27581 --11.3385 12.3258 6.58796 --11.9591 12.1253 7.34451 --11.1922 11.5639 7.31083 --10.7892 12.0831 8.01671 --10.8355 12.4553 9.00503 --10.7723 13.4059 9.3979 --9.99219 12.7641 9.51741 --9.7969 13.5445 9.03142 --9.21419 14.055 9.70512 --8.52356 14.1249 9.11537 --8.77146 14.3335 8.03152 --8.30906 13.442 8.13381 --7.65795 12.9101 7.5233 --7.77102 12.0284 7.06002 --8.54402 12.2986 6.58778 --8.00956 13.0284 6.1516 --8.32556 13.9354 5.98031 --9.26822 14.2408 5.7195 --10.2079 13.7981 5.6056 --11.1499 13.5043 5.94127 --11.4798 14.4963 6.07898 --11.2424 15.3901 5.61624 --12.1883 15.2412 5.31857 --12.9426 15.3517 5.96643 --13.257 14.9004 6.79878 --13.7201 15.7343 6.96362 --14.4846 16.1115 6.4297 --14.1576 17.0949 6.35454 --14.4024 18.0921 6.46292 --15.066 18.1074 7.21868 --14.7815 18.9005 7.73993 --14.3657 19.5818 7.08913 --14.3808 19.8247 6.07255 --13.4988 19.9126 6.4124 --12.8453 20.5526 6.94732 --12.8238 19.9155 7.66816 --12.7426 19.5732 8.57616 --12.3106 20.4421 8.54757 --11.7231 21.1386 8.19128 --11.1314 21.8719 8.50927 --11.0786 21.5382 9.40812 --11.1045 22.226 10.171 --11.224 23.1621 10.6017 --11.4934 23.8042 9.84163 --10.4935 23.8568 9.82033 --10.7217 23.1408 9.1468 --11.2725 23.8095 8.65374 --11.672 24.6458 8.92554 --12.0286 24.3617 8.05158 --11.3882 25.0955 7.76713 --11.5551 25.1529 6.75539 --11.2307 24.7723 5.85754 --10.998 25.4796 5.07811 --11.0224 24.9294 4.28228 --10.8878 24.7804 3.27606 --11.73 25.1761 3.60869 --11.8049 26.0698 3.97484 --12.4826 26.6494 3.57317 --12.6851 25.9648 2.8803 --12.2619 26.7898 2.38118 --11.2916 27.1111 2.37654 --10.3008 27.161 2.05817 --9.42947 27.0509 2.56853 --9.22768 26.2152 2.1585 --9.96686 25.8072 2.71565 --9.81155 26.4315 3.56138 --10.8184 26.6037 3.69458 --10.1974 27.3207 3.8354 --10.8469 27.9044 4.44608 --11.2456 28.4248 5.15947 --11.8924 28.6839 4.44442 --11.161 29.2096 3.88545 --10.5821 29.2773 4.70696 --10.0537 28.6776 5.33458 --10.1136 27.7222 5.62623 --9.16808 27.7237 5.37345 --8.32391 27.3597 4.94792 --8.50325 26.9036 5.84446 --8.39876 27.2097 6.82726 --9.08623 26.692 7.22173 --8.93361 25.7721 7.62513 --9.80909 25.5841 8.00477 --9.50356 25.4566 8.96193 --10.2822 24.7968 8.72291 --9.41941 24.5431 9.22336 --8.65687 25.1673 9.10779 --8.64887 26.0797 8.69144 --8.40991 26.9931 8.92713 --8.4163 27.9153 8.70296 --9.22486 27.5475 8.17626 --9.62621 27.2897 9.06818 --10.2576 28.03 9.10986 --9.41572 28.4272 8.71245 --10.0344 29.2053 8.72285 --10.3824 29.761 8.01683 --9.98536 30.5008 7.31604 --10.3977 30.4182 6.39354 --9.63828 30.9024 5.99087 --9.14583 31.6435 6.53671 --8.88123 30.6531 6.53538 --8.6163 30.6703 7.5364 --8.32974 30.1851 8.31819 --7.72426 29.9617 9.05667 --7.78054 29.5889 9.92911 --8.72622 29.5672 10.2577 --9.40472 28.8636 9.97381 --8.8878 28.0066 10.1673 --8.63503 27.0435 10.3864 --8.23552 26.8562 11.2144 --8.30371 25.9597 10.8453 --7.49626 25.4387 10.9248 --7.64323 25.9456 11.7435 --6.67118 25.8329 11.7934 --6.22392 25.4922 12.6391 --6.68724 25.2604 13.5174 --6.53063 24.2547 13.5146 --6.50803 24.1951 14.5109 --6.35159 23.1884 14.5512 --6.64698 22.3832 14.9289 --5.87524 22.0155 14.386 --6.46311 21.3609 13.8934 --5.8008 20.653 13.7103 --5.95663 20.8194 14.7108 --5.78892 20.0562 15.2081 --6.79034 20.1367 15.4707 --6.56838 19.4126 16.158 --6.33411 19.7905 17.1093 --5.69806 20.4256 17.5693 --6.38729 20.025 18.1749 --6.82747 20.8672 17.7611 --7.75607 20.5323 18.0544 --7.77128 21.4468 17.7469 --7.98902 21.4098 16.7648 --7.94715 21.6949 15.8156 --8.84359 21.9206 15.5293 --8.25721 22.4538 14.8739 --8.66028 21.5561 14.633 --7.73426 21.1808 14.4599 --7.7267 21.2213 13.4928 --7.91768 20.387 13.0664 --7.15212 19.9307 13.4764 --6.9748 20.0812 12.5389 --6.85838 19.0735 12.4001 --6.373 19.4113 11.5983 --5.53408 19.4063 11.096 --5.58046 18.3944 11.0819 --6.57878 18.2776 11.0732 --6.7716 19.1791 10.6589 --6.9496 18.8242 9.71626 --7.85146 18.7582 9.30556 --8.06712 17.9619 9.82626 --9.09339 18.0908 9.58696 --9.05845 18.5796 8.72757 --9.6113 19.286 9.18257 --9.10444 20.1718 9.28276 --8.43095 20.6762 9.80312 --8.15731 21.4969 9.38439 --7.38779 21.7312 8.8319 --7.06982 20.9082 8.39547 --7.07745 20.6091 7.42619 --6.75878 20.2437 6.46491 --7.16854 19.5161 7.03336 --7.28399 19.2871 6.06526 --8.16095 19.6872 6.26839 --8.55798 18.9445 5.70717 --7.79387 18.6912 5.21884 --8.15762 17.9344 5.56196 --8.32685 17.8129 6.57243 --8.09152 17.7756 7.59261 --7.13533 17.4485 7.56962 --7.19984 16.5419 7.06124 --6.37244 16.7261 7.59603 --5.53516 16.7906 7.10694 --6.0836 16.8038 6.33158 --5.36871 16.253 5.86744 --4.64863 15.7612 5.40358 --4.40184 16.0482 6.3464 --3.38989 15.9972 6.59618 --2.45828 15.6984 6.87665 --2.70979 15.0941 7.63502 --2.65614 14.4068 8.30152 --3.29823 13.8992 7.73664 --4.13357 13.314 7.63234 --3.93549 13.254 8.62703 --4.27471 13.7032 9.47636 --4.36827 14.2682 8.62852 --4.286 15.2722 8.68175 --5.16707 15.0771 8.20588 --5.71445 14.243 7.98784 --6.54056 14.6811 8.31724 --7.09888 14.4876 7.51583 --7.15116 14.4101 6.51772 --6.19464 14.1804 6.25818 --6.6048 14.7068 5.57449 --6.61881 15.7001 5.72489 --6.85365 16.0628 4.80607 --7.35745 16.4124 5.56792 --8.29022 16.015 5.61004 --8.95671 15.8277 6.27251 --9.85121 16.2713 5.94911 --9.28472 17.1194 5.97091 --9.91582 17.2196 5.2101 --10.7076 17.4083 5.87625 --11.3668 18.1029 5.93351 --11.3316 17.7913 6.86248 --11.9532 17.0945 6.55653 --12.0157 16.1564 6.19636 --11.1582 16.0164 6.71534 --10.636 16.5423 7.39594 --10.0846 16.3599 8.21242 --10.1966 15.6697 8.85723 --10.6821 16.5589 9.09104 --10.2897 17.4765 8.91214 --10.3983 18.4758 8.82049 --11.0062 18.1958 9.56373 --11.3912 18.9653 10.012 --11.9633 19.3029 10.6606 --12.6825 19.9727 10.2453 --13.001 19.2707 10.8808 --13.2225 18.4832 11.4649 --13.7364 17.9652 10.7489 --13.491 18.1487 9.8152 --13.6688 18.3196 8.90111 --14.0924 19.2215 9.15673 --14.8303 18.6162 9.01769 --15.546 18.5869 9.68826 --15.189 19.5417 9.94389 --15.3261 20.3852 9.54826 --16.0816 20.8648 10.0648 --16.0719 20.7038 11.0051 --15.392 21.2836 11.4137 --15.0814 21.6424 12.2386 --14.2255 22.0773 12.0597 --14.3175 21.5717 11.2119 --14.35 22.5412 10.9471 --15.1716 22.8083 10.4862 --14.6032 23.4951 10.9884 --15.0184 23.7336 11.8908 --15.6177 24.4219 11.4799 --14.9831 25.1431 11.806 --14.6591 25.9902 12.29 --14.0069 26.0659 11.5154 --13.7821 25.7609 10.5684 --14.0382 26.1255 9.65701 --14.6192 25.7191 9.07794 --14.1662 26.5375 8.57947 --13.4996 26.5519 7.78394 --13.0565 27.2796 7.28131 --12.3376 27.8084 7.70364 --12.5647 27.8163 8.73361 --12.3268 28.7715 8.73811 --11.6648 28.0278 8.98065 --12.1483 28.281 9.87824 --12.5058 29.0296 10.4544 --12.2797 29.8363 9.84363 --11.3144 29.8429 9.83197 --11.1412 30.8539 9.70813 --10.7327 31.2912 10.501 --9.95005 30.9185 10.9683 --9.51922 31.812 11.215 --8.61395 31.7393 11.5796 --7.62069 32.0891 11.4878 --6.98543 32.8509 11.6546 --6.65956 33.0836 10.7357 --5.76803 32.9386 11.1103 --5.03468 32.5617 10.5058 --4.18745 33.1165 10.898 --3.44285 33.7988 10.6909 --3.24273 33.6595 9.70195 --2.30534 33.5947 9.52734 --2.41434 32.8554 8.77001 --2.52222 33.5038 8.00066 --2.94476 33.217 7.12054 --3.27383 33.2976 6.1558 --3.81845 33.8591 6.73014 --3.46499 34.464 5.985 --4.19114 33.8307 5.53504 --4.40603 34.6095 6.07078 --5.27736 35.0532 6.11532 --5.26815 36.0484 6.0582 --4.70028 35.713 6.85318 --4.9557 35.9791 7.79962 --4.55111 35.1734 8.14245 --4.47178 34.4408 8.73101 --4.82932 33.5637 8.8421 --5.57064 33.2414 8.33791 --5.35456 32.2679 8.23034 --5.09874 31.3946 8.68109 --4.39697 30.7347 9.09035 --4.03461 29.8492 9.21395 --4.62377 30.043 9.99314 --5.02053 29.2529 10.446 --5.28538 28.4704 9.85525 --4.76731 29.2107 9.33744 --4.55711 29.5407 8.32919 --4.92283 28.6502 8.25345 --4.38789 27.7592 8.24648 --3.92974 28.2239 8.98901 --3.074 27.7321 8.62432 --2.1566 28.3162 8.49676 --2.64666 29.1577 8.89111 --2.84533 30.0454 8.53329 --2.20925 30.7923 8.63508 --2.21372 31.0146 9.62304 --2.55124 30.0652 9.43756 --2.70216 29.3833 10.1943 --3.12436 28.6663 10.7847 --4.067 28.8361 10.7292 --4.73832 28.6901 11.388 --4.14375 29.3822 11.8856 --4.43699 29.6376 12.8162 --5.17753 29.1313 12.3363 --5.88799 28.8099 12.81 --6.58178 28.043 12.5943 --6.31946 27.6086 13.401 --7.02774 26.9316 13.6603 --6.77608 27.0635 14.6372 --7.75785 27.2986 14.5927 --8.57901 27.8709 14.4942 --8.75431 27.1342 13.8436 --8.90921 27.4392 12.8929 --8.45285 28.2449 13.2187 --8.97362 29.0072 12.9034 --9.44538 29.1884 11.971 --10.1764 28.5595 11.8837 --10.7553 29.4404 11.9314 --10.9765 29.6709 12.84 --11.9793 29.4459 13.1197 --11.708 28.6105 13.4334 --12.4655 27.9558 13.4221 --12.6194 27.0188 13.5918 --12.5193 26.5194 14.4168 --12.7919 25.659 13.9317 --12.0326 25.7529 13.1727 --11.8423 24.8606 12.8716 --11.6441 23.9478 12.5819 --10.7338 24.3655 12.5403 --10.8929 24.3589 13.4936 --10.8971 24.919 14.3146 --10.0419 24.6402 14.7477 --10.4208 23.869 15.1769 --10.1459 23.2333 15.9657 --10.1997 22.281 15.869 --10.9178 21.7459 15.419 --10.4627 20.9052 15.2484 --9.45757 20.6309 15.045 --10.2096 20.7305 14.4045 --9.67737 19.9426 14.0449 --9.44708 20.0456 13.0371 --10.1636 20.3439 12.3764 --9.93726 21.2046 11.9582 --10.878 21.294 12.2193 --11.0462 20.4784 11.6643 --11.4437 20.3958 10.7256 --10.6169 19.9642 10.3173 --10.1121 20.7638 10.7503 --9.43844 20.1096 11.04 --8.42068 19.9867 11.2016 --8.13712 21.0161 11.011 --8.64852 21.8369 11.3814 --7.80182 22.2698 11.1089 --7.31843 22.9664 11.5622 --7.02471 23.8627 11.2141 --6.93736 23.6424 10.2278 --7.16013 23.413 9.31045 --6.88097 22.9832 8.49811 --7.31563 22.9877 7.5938 --7.49454 23.9111 7.78464 --8.24513 24.4824 7.5042 --8.64645 23.6841 8.02038 --9.45013 23.46 7.49977 --10.1766 22.7506 7.52309 --10.0913 21.7704 7.92333 --9.44326 21.0654 8.15634 --9.00747 20.5215 7.4962 --9.9194 20.3362 6.96614 --9.46075 20.8893 6.29151 --8.59556 20.6725 5.76904 --7.62193 20.9777 6.01872 --7.54378 21.6425 6.71835 --7.8336 22.3778 5.99442 --8.7014 22.0745 5.51478 --9.10231 22.8232 6.14775 --9.59108 23.7135 6.13938 --10.2764 22.9355 6.10374 --9.81053 22.7523 5.29022 --10.2986 22.1687 4.5773 --9.61676 22.6684 4.04598 --8.79499 22.8737 3.48155 --8.47979 21.9083 3.5764 --7.53564 21.9349 3.84552 --7.92729 21.6249 4.65492 --8.8892 21.3891 4.48529 --9.15564 20.4375 4.74056 --9.25875 19.9003 3.86467 --8.89102 20.0785 2.95756 --8.54433 20.2421 2.02005 --8.91626 19.354 1.83075 --9.83942 19.2573 2.38232 --10.6488 18.8306 1.94635 --11.324 18.8496 1.17435 --11.8358 19.2555 1.87561 --12.6039 19.1611 1.34553 --13.5834 18.8576 1.55826 --14.2076 18.4108 2.28143 --13.9109 19.2972 2.75964 --14.7489 19.3971 3.11732 --14.9109 19.8329 4.03503 --14.7385 20.196 5.06777 --15.4177 20.8694 5.08697 --14.8295 21.5392 4.62584 --14.5365 22.1167 3.89493 --14.7519 22.6375 4.82695 --15.0782 23.5123 4.38845 --14.4927 23.6345 3.49799 --14.4519 22.7284 3.10642 --13.5399 23.0164 3.06224 --12.7164 23.5819 2.77078 --12.4721 22.9288 3.51393 --13.2704 22.6873 4.05963 --13.2012 22.4541 5.0679 --12.5861 21.7299 5.41543 --12.3906 21.3418 4.56663 --12.1357 20.356 4.59511 --11.2186 20.7629 4.20567 --10.5819 21.3839 3.69541 --9.91111 21.3597 2.97195 --9.89914 20.3967 2.96763 --10.5884 20.3676 2.19941 --11.2271 20.5709 1.40792 --11.1249 21.4148 0.9303571 --10.9337 21.6488 0.0077598 --10.4352 21.933 -0.7746409 --10.2809 22.7056 -0.1415739 --10.1535 23.7122 -0.04546008 --9.6787 24.3731 -0.6079469 --10.2933 24.2237 -1.37613 --10.1628 23.2727 -1.43883 --9.588 22.4226 -1.41399 --8.82102 22.019 -1.84663 --7.87165 22.244 -1.65591 --8.20335 21.5092 -1.02498 --8.71766 22.0299 -0.2738599 --7.91513 22.2563 0.3206021 --8.01555 23.2288 0.2909331 --7.06753 22.9125 0.3337921 --6.75596 22.4776 1.15229 --6.09146 21.6744 1.39407 --6.35746 21.1275 2.1671 --6.23289 20.491 1.45777 --6.72771 19.7569 1.06988 --6.40541 20.4255 0.4028791 --5.87898 19.5314 0.4553071 --4.95733 19.2612 0.1149081 --4.68673 19.715 -0.7375399 --4.34603 18.8122 -0.9937629 --4.73714 18.0992 -1.57013 --4.61418 18.2579 -2.5283 --3.73969 18.0592 -2.178 --3.1983 17.5276 -2.76107 --3.45876 16.8411 -2.0271 --3.53714 16 -1.46206 --3.28982 15.1484 -1.81019 --3.77343 14.8653 -2.61369 --4.69259 14.6342 -2.88733 --4.64522 15.4693 -2.29562 --4.71563 16.432 -2.3915 --5.26857 16.6096 -3.22651 --4.81864 16.1617 -4.04931 --4.00198 16.5182 -4.40629 --4.00945 16.5454 -5.46276 --3.174 16.1126 -5.60349 --2.2981 16.5207 -5.37245 --1.62959 16.0833 -4.78494 --2.005 16.5212 -4.00926 --1.41827 17.2526 -4.24463 --0.737663 17.9472 -4.42708 --0.707975 18.6644 -3.77633 --0.477404 17.8623 -3.28177 --0.491491 17.0307 -2.61163 --1.18405 16.4317 -2.32401 --0.87908 15.4797 -2.57836 --1.05936 15.4036 -1.59522 --1.74512 14.74 -2.07016 --2.28566 13.9364 -1.86564 --2.56563 13.7466 -2.84878 --1.59764 13.5062 -2.74119 --1.39335 13.434 -1.81093 --0.789178 13.9324 -1.23541 --0.630491 14.4744 -0.5363729 --1.42254 14.0499 -0.2644969 --1.22407 13.2963 0.3092021 --1.20557 13.8385 1.10803 --0.310204 13.381 0.9451281 --0.208566 13.0277 1.85059 -0.112033 13.0655 2.77406 -0.855885 13.4166 2.21388 -1.71913 12.8561 2.36732 -2.14261 13.2269 1.53237 -2.37557 13.8036 0.7403961 -2.75784 12.9659 0.3603881 -2.98528 12.0948 0.8661851 -3.15158 12.5589 1.64824 -4.05116 12.0305 1.93617 -3.72786 11.3059 1.40974 -4.03358 10.4985 0.9882451 -3.85046 10.9665 0.1391871 -3.47699 11.7915 -0.1456819 -4.14219 12.5718 0.01946702 -4.49723 12.3617 -0.9354979 -4.21094 11.462 -0.9106189 -3.81845 10.8013 -1.61889 -4.01253 10.0446 -2.18509 -3.11203 9.79036 -1.89762 -2.4473 9.44114 -2.62352 -1.97905 8.66032 -3.00544 -2.69532 8.64203 -3.81414 -3.71184 8.55097 -3.8567 -4.68758 8.41798 -3.93152 -5.50505 8.79105 -4.21761 -5.96146 9.53224 -4.68463 -6.29175 9.78235 -3.81574 -5.64611 10.4331 -3.37308 -6.17562 11.2882 -3.38853 -5.74797 11.3421 -2.51246 -6.10933 12.2574 -2.18542 -6.82081 12.9787 -2.06302 -7.57666 12.7823 -2.74385 -8.36497 12.618 -2.18786 -8.55766 11.5582 -2.22107 -9.45918 11.9311 -1.9806 -9.22232 12.7989 -1.60563 -8.5771 13.5482 -1.669 -8.49815 13.7191 -0.6790829 -8.35238 12.7589 -0.6641639 -7.95902 12.3391 0.1353041 -8.69024 12.6054 0.6704431 -8.19971 13.1929 1.26449 -9.10818 13.4939 0.9835151 -9.99804 13.8734 1.11271 -10.9303 13.7171 1.41382 -11.5957 13.4228 0.6791311 -11.1877 13.1363 -0.1422079 -11.6841 13.159 -0.9918249 -11.4943 13.2115 -1.95847 -10.7377 12.873 -2.47347 -11.018 13.5171 -3.21163 -11.0337 14.4266 -2.86276 -11.4899 14.7399 -2.04813 -10.7689 14.4246 -1.47986 -9.86468 14.2214 -1.45498 -9.09521 14.3583 -2.09196 -8.65639 14.5014 -1.19074 -8.98694 15.442 -0.8362909 -9.60774 15.8074 -0.1475529 -10.4712 15.7554 -0.6797699 -11.0386 15.6113 0.1263181 -10.7982 16.5624 0.09936562 -11.6387 16.4219 -0.3550479 -11.5043 16.119 -1.38205 -11.6172 16.922 -1.87454 -10.6392 16.9768 -1.61227 -10.3031 16.407 -2.42379 -9.80221 15.5286 -2.7213 -8.82598 15.807 -2.71149 -8.05578 16.3202 -2.21496 -7.73755 16.0784 -1.30705 -7.93887 16.7972 -0.7168699 -8.56694 16.9059 -1.44657 -8.4034 17.6939 -2.00826 -8.96113 18.4796 -2.38433 -8.74021 19.2884 -1.80261 -8.17251 19.7736 -2.49853 -8.24505 18.9045 -3.11557 -7.35727 19.4067 -3.01368 -6.88504 20.2169 -3.15119 -6.20308 20.2572 -2.44057 -6.2362 19.2299 -2.4124 -5.83622 18.4712 -2.93075 -5.21585 17.9383 -2.36483 -5.78784 17.5026 -1.59939 -5.12781 16.7502 -1.39188 -5.15681 16.4737 -2.33079 -4.32675 16.1391 -1.82259 -4.17644 16.0286 -2.82715 -4.11268 15.0576 -3.10069 -3.29183 14.8842 -2.46566 -2.74901 14.4169 -1.74413 -3.28027 14.5921 -0.9052209 -3.49168 15.5102 -1.05106 -3.3233 15.7057 -0.1340779 -4.11217 16.2769 -0.4250849 -4.32086 17.2559 -0.5273339 -5.10273 16.9579 0.08164742 -6.02611 16.8587 -0.1992599 -6.38374 15.9488 -0.2033009 -6.60468 15.0956 -0.5556219 -6.5291 14.5377 0.2970341 -6.69914 14.996 1.21255 -7.72406 14.9528 1.20703 -7.42749 14.1166 1.65775 -6.75638 13.8339 1.01141 -6.79511 12.795 0.7808851 -7.08023 12.0138 1.28122 -6.16417 11.619 1.05231 -5.2585 11.225 0.6958311 -5.76247 10.4617 0.4003531 -6.67506 10.9513 0.4695601 -6.90862 10.2834 -0.2836099 -7.54889 10.3135 -1.03692 -7.3891 11.2927 -0.8302289 -7.21793 11.0366 -1.82547 -7.55349 10.3636 -2.53339 -7.50046 9.51802 -3.11044 -8.49499 9.84711 -3.29108 -8.93959 10.2307 -2.55318 -8.89762 9.22939 -2.4792 -8.19587 8.53608 -2.45481 -7.5322 8.26624 -3.11064 -7.50951 7.45174 -2.60161 -6.75295 6.97222 -2.18809 -6.53193 6.21022 -1.59906 -6.7557 5.61708 -0.8388259 -7.16309 4.75674 -0.3926339 -8.07893 4.94791 -0.7477459 -8.58175 5.7588 -1.05247 -8.73944 5.56041 -0.1008999 -9.54703 5.91384 -0.5783019 -9.97167 6.71359 -1.09357 -10.9405 6.40275 -1.28219 -10.3943 5.60603 -0.9161679 -10.0825 4.69832 -1.23265 -9.66028 4.13028 -1.88411 -9.65989 3.55074 -1.04513 -9.07837 3.42679 -0.2302949 -8.74043 3.27531 0.7284411 -7.81465 2.94594 0.4583241 -7.7536 3.52657 -0.4180499 -7.39119 2.90439 -1.18979 -6.68397 2.29199 -0.8793019 -5.90508 1.86245 -1.35326 -6.23148 1.17782 -0.7805209 -6.72145 0.7808919 -1.51598 -7.37464 1.56084 -1.38686 -8.15289 2.114 -1.65867 -8.69881 1.69563 -0.9196719 -8.28132 0.9221259 -0.4411449 -7.45072 0.3712899 -0.5519469 -6.91691 -0.1122661 0.08593922 -6.84169 0.7837989 0.4089251 -7.71565 0.5918129 0.8180451 -8.22613 0.04946713 1.43958 -7.53723 0.7260629 1.87917 -7.70068 -0.004851426 2.508 -7.58588 -0.2859261 3.49786 -8.43615 -0.1178131 3.93184 -9.30518 0.1615089 3.40811 -9.41425 -0.2380461 2.51344 -10.3668 -0.4206981 2.61784 -10.8675 -0.9923131 2.02712 -11.3451 -1.64252 2.64231 -12.2043 -1.46011 3.02585 -12.841 -1.87074 3.6303 -13.3574 -1.39065 2.9245 -13.5546 -2.2845 2.54438 -13.5102 -3.30738 2.37301 -12.7604 -2.66548 2.1235 -12.0165 -3.10839 1.67774 -12.2255 -4.0732 1.65731 -11.675 -4.8128 1.95446 -12.3006 -5.07039 1.21079 -13.011 -5.29115 1.84828 -13.5975 -4.65098 2.28432 -13.6996 -5.1071 3.17134 -13.7738 -4.12519 3.26611 -14.762 -4.24527 3.41213 -14.2947 -3.54054 3.96479 -13.7021 -3.4188 4.80785 -14.421 -3.28671 5.5005 -15.1368 -3.21102 6.22903 -14.3301 -3.35425 6.75972 -13.5779 -2.64388 6.87554 -13.27 -2.27044 6.01014 -13.3022 -1.68662 6.89504 -12.4448 -2.04498 7.14007 -12.6331 -1.20495 7.59656 -13.1109 -1.6579 8.36083 -12.5692 -2.48082 8.56547 -12.1509 -3.00983 7.76146 -11.4233 -2.93581 8.44748 -10.6631 -3.3112 8.81162 -10.5238 -3.25028 9.80773 -10.4913 -2.47696 10.4687 -11.3325 -2.31741 10.0882 -11.8408 -1.81155 9.44476 -10.8929 -1.58794 9.61731 -10.1958 -2.24498 9.25222 -10.0987 -1.47947 8.59929 -10.7279 -1.20426 7.81698 -10.6846 -0.2451991 7.72858 -11.5064 0.1691699 8.17696 -12.4384 0.3313159 8.51069 -12.5643 0.3041069 7.49128 -12.555 0.007186884 6.5112 -12.728 0.9916479 6.23156 -13.0607 0.4845149 5.47878 -13.9815 0.8915009 5.45317 -14.075 0.4423769 6.28157 -14.872 0.4634449 6.94033 -14.5894 1.22388 7.58249 -14.4178 2.18795 7.97053 -15.1728 2.73006 8.2562 -15.2277 3.70626 8.3748 -15.8279 4.13734 7.68136 -16.1859 4.73616 8.3207 -16.0565 5.73072 8.51748 -16.6513 5.78549 7.63295 -16.3539 5.86847 6.64533 -16.8915 6.71563 6.62988 -16.7622 7.44818 7.42743 -16.8473 8.32405 7.01063 -17.0889 7.62693 6.39962 -18.021 7.49991 6.72318 -18.4292 7.04308 7.48654 -17.8713 7.04445 8.21873 -18.635 7.68682 8.26433 -18.815 7.58923 9.25394 -17.8935 7.98852 9.33638 -16.9244 7.8215 9.14199 -17.0068 7.25191 9.95693 -16.6761 7.23133 10.8904 -15.7385 7.15514 11.1397 -15.4008 7.21476 10.2231 -15.51 7.3227 9.20804 -14.6631 7.75344 9.07828 -14.6732 8.64023 9.53167 -14.8314 8.4702 10.5628 -14.5486 9.33487 10.4142 -13.7421 9.19232 11.0178 -13.1292 9.52923 10.2803 -12.1379 9.79084 10.192 -11.7291 10.0686 9.33731 -10.9015 9.59628 9.19264 -9.94418 9.19328 9.27163 -9.33685 8.73662 10.0227 -8.72811 8.76409 10.8111 -9.00326 9.37491 11.496 -9.95992 9.13579 11.2984 -10.2547 8.82254 12.1378 -10.732 9.55905 12.6822 -10.8296 8.61703 13.025 -11.6086 8.96389 12.5149 -12.0063 8.84973 11.603 -12.278 7.88526 11.3846 -12.4442 8.27491 10.5251 -12.9224 7.39231 10.4808 -13.8273 7.36877 10.8131 -13.6138 6.46208 11.283 -12.7989 6.09145 10.9745 -11.9042 6.23218 11.3409 -11.1763 6.67507 10.8807 -11.1765 6.57947 9.90596 -11.9902 6.99378 9.57216 -12.6891 6.95776 8.82914 -12.9826 7.80939 8.22109 -12.4113 8.54069 8.52487 -11.9244 8.22093 9.38381 -11.5476 7.61846 8.70383 -10.8959 8.22863 8.18702 -11.1378 8.23449 7.25654 -11.0785 8.16453 6.21069 -11.8865 8.71826 5.85197 -12.4492 9.11254 5.11883 -12.7313 9.54381 5.9952 -12.5664 9.69487 6.94621 -13.0067 10.5938 6.6352 -13.1022 11.3145 7.29383 -12.2282 11.724 7.48144 -11.6862 11.34 6.73145 -11.269 10.9814 7.49731 -10.8097 11.8704 7.42777 -10.5706 11.9207 8.31134 -10.3168 10.9911 8.63375 -9.76887 10.8314 7.72261 -9.99179 10.9122 6.79248 -10.2282 10.5726 5.88075 -9.85812 9.65817 6.03139 -10.7254 9.68067 5.54246 -10.8023 8.91803 4.84564 -10.5696 7.9453 5.05633 -9.63451 7.50852 4.71216 -9.90456 7.20913 3.82767 -9.45848 7.85723 3.27292 -8.89371 8.27827 2.57729 -9.18967 7.46231 2.12529 -8.70528 6.62066 1.98016 -8.44303 6.25785 2.85104 -7.50815 6.27924 3.12641 -7.39668 6.16943 4.09527 -6.76839 5.52162 3.78903 -6.0568 6.21809 3.86504 -5.1453 6.51745 4.26151 -5.43925 6.41911 5.19551 -5.18374 5.59566 4.69413 -5.47873 4.70435 4.82979 -6.50764 4.92128 4.94454 -6.96915 5.75274 4.98227 -7.2877 6.47667 5.70282 -8.11741 6.98825 5.51793 -8.98853 7.23381 5.75365 -9.04127 6.82593 6.6848 -8.78215 5.90083 6.37736 -8.76819 5.29964 7.11776 -8.87037 4.36031 7.36714 -8.49169 4.11555 6.47144 -8.65188 3.31163 7.07085 -8.48953 2.64918 7.81 -8.34696 2.02278 7.07663 -9.07429 1.81492 6.41019 -9.57868 2.59177 6.55756 -10.4527 2.52802 7.09819 -11.3609 2.106 7.10637 -10.8296 1.23847 7.26659 -10.0883 0.5782899 7.1699 -9.53635 -0.1155801 6.58857 -10.0968 -0.9374221 6.49384 -9.96645 -1.87356 6.16512 -9.58884 -1.7883 5.23675 -8.76467 -2.29862 5.24379 -8.64212 -3.03635 4.68747 -8.02999 -3.20739 3.99563 -8.0305 -2.27266 3.89984 -8.95433 -2.47657 3.78262 -9.29519 -1.51841 3.76367 -9.87541 -2.16586 3.36412 -9.95747 -2.91339 4.08079 -9.96427 -3.7127 3.43046 -9.9699 -3.24692 2.49115 -10.7544 -3.87164 2.74204 -11.5959 -3.69565 3.29355 -11.7122 -3.14938 4.14449 -11.5251 -2.42222 4.82992 -10.8392 -2.05747 4.2071 -11.2214 -1.4553 4.92721 -10.8758 -0.6257981 5.35953 -10.1275 -0.02145137 5.49908 -10.6538 0.8276579 5.45356 -9.81455 1.14572 5.03653 -10.6187 1.56089 4.53396 -11.4712 1.24021 4.98142 -11.7335 2.10016 5.32959 -11.5341 3.02507 5.3824 -11.7029 3.98609 5.69936 -12.612 4.10068 5.92738 -12.9735 3.25123 5.56921 -13.6124 2.63766 5.95342 -13.5791 1.82761 6.39386 -12.7932 2.36169 6.61028 -13.1482 2.81972 7.38411 -13.9015 3.26104 6.86619 -14.5598 3.96807 6.76732 -14.1935 3.97889 7.61428 -14.11 3.90676 8.62166 -14.0887 4.86329 8.56245 -14.2906 5.60238 9.21296 -13.8053 5.02788 9.86693 -13.2461 4.1832 9.87214 -12.8723 3.62331 9.09127 -12.2644 2.91177 9.42284 -11.2917 3.10787 9.51225 -11.1608 4.01496 9.22662 -10.4305 4.55865 8.711 -10.1586 5.26305 9.24622 -9.30341 5.66718 8.97823 -9.29943 6.3281 8.23897 -9.70512 7.10018 7.63831 -9.73048 7.88821 8.1673 -9.59243 8.83932 7.87072 -8.755 8.3797 8.3726 -8.61592 8.63589 7.45117 -8.49761 9.4547 8.08504 -8.56647 10.1226 7.31396 -7.81455 10.5677 7.8192 -7.86778 10.9426 6.89985 -7.95043 11.8586 7.1114 -6.92459 11.8017 6.9327 -6.3144 11.3517 6.24735 -6.37731 11.9012 5.41155 -6.71531 12.7792 5.6894 -5.83416 12.9933 5.32591 -4.81598 12.9283 5.49469 -4.0039 13.3612 5.7969 -4.47033 13.7769 6.6448 -5.09838 13.0491 7.03844 -4.54928 12.5372 7.69909 -5.07214 13.2365 8.22331 -5.90627 13.5121 7.67464 -6.29105 13.9082 8.43086 -5.73768 13.5301 9.18587 -5.96596 12.594 9.58629 -6.24726 11.7194 9.12126 -6.68778 10.8423 9.42326 -5.71078 10.4726 9.41008 -5.25891 10.204 8.63882 -6.17029 10.1354 8.151 -6.12728 9.16653 8.55775 -6.93106 8.67587 8.15542 -7.58439 9.26826 8.78021 -7.50444 8.57049 9.54325 -7.543 8.15504 10.4356 -6.91775 8.28652 11.1795 -6.42502 7.8173 10.5433 -6.44103 6.86454 10.4839 -6.62567 5.91702 10.3706 -7.25231 5.61729 9.59289 -6.95888 5.48833 8.64111 -7.89566 5.34921 8.72082 -7.86305 4.64451 8.02328 -7.58976 4.41963 8.97726 -7.53403 3.45603 8.77384 -7.2993 3.294 7.81652 -6.41177 2.86823 7.41256 -6.06667 1.91557 7.29974 -5.40672 1.853 6.64803 -4.60063 1.45112 6.28887 -3.77401 1.90131 6.01014 -3.32667 2.3056 5.15108 -2.63769 1.9224 4.62053 -3.04115 1.69664 3.77278 -2.50651 1.50998 2.99811 -2.91487 0.6394779 3.32881 -3.35938 0.06876323 3.97456 -3.27614 -0.2537721 4.93971 -4.25331 -0.4119381 5.03025 -4.94791 0.3223009 5.06385 -5.66479 0.6247389 4.51652 -6.4876 0.1381029 4.48833 -5.91341 -0.7063281 4.50972 -5.43029 -1.22478 5.14824 -5.68313 -1.50504 6.11872 -5.74425 -1.86543 7.09258 -6.73269 -1.52398 6.89098 -6.96381 -0.5973121 6.7576 -7.31393 -0.1842651 5.91996 -7.58484 0.6498399 6.34968 -7.93242 1.3666 5.74199 -7.35831 0.8362679 5.03265 -6.79002 1.47976 4.51131 -6.51395 1.62009 5.42538 -5.56591 1.27624 5.4294 -4.78834 1.86218 5.38869 -4.15634 1.18582 4.9636 -4.14131 1.40317 4.01104 -4.2854 0.9713409 3.13571 -4.71509 1.26069 2.29323 -4.50979 2.19428 1.88235 -5.39935 2.31983 2.14757 -6.14324 1.94899 2.81674 -6.98179 1.44864 2.94964 -7.15928 2.27854 2.35352 -7.46322 2.36037 3.27287 -7.00074 3.25351 3.02025 -6.28394 3.94874 2.79746 -5.41412 3.46912 2.68764 -5.77743 3.41512 3.63014 -5.15391 3.63813 4.44365 -5.26245 3.20198 5.37986 -4.32837 3.07018 5.31769 -4.32015 3.89035 5.85056 -3.50091 3.39373 5.75461 -2.85566 2.83279 6.28036 -2.39678 1.98626 6.14504 -1.50053 2.33859 5.84863 -1.6515 2.73607 6.79769 -0.935418 3.22983 6.23621 -0.09677777 3.81523 5.93539 -0.150061 3.13394 5.14132 --0.352458 2.67763 5.84305 -0.04251107 1.8707 6.14099 --0.816214 1.63721 6.66419 --1.40341 2.42736 6.89144 --1.02708 3.30571 6.66649 --0.886295 3.92188 7.41185 --1.30985 3.37232 8.15562 --1.78353 4.26014 8.08779 --2.25253 3.72137 7.34142 --1.75043 4.10769 6.61635 --1.54221 4.9242 7.13061 --0.622868 5.22518 6.92903 --0.487221 5.09246 5.96747 --1.28462 4.53386 5.69083 --2.02439 4.24018 5.13132 --1.90325 4.78368 4.31437 --1.22861 4.21265 3.86225 --0.624816 4.25087 3.02885 --0.322037 3.3429 2.7779 -0.257098 2.7757 3.41322 -0.677632 3.60121 3.10115 -1.31083 4.32885 2.96231 -1.97258 3.71535 2.66625 -2.17222 2.78922 2.23691 -1.50454 2.03032 2.1361 -2.15186 1.89784 1.44207 -2.23975 2.5975 0.6830661 -1.34693 2.88244 0.4535731 -1.27154 2.86949 1.43984 -1.73013 3.76496 1.64161 -0.742335 3.69785 1.34974 -0.685522 4.62372 1.26494 -1.65019 5.07206 1.44203 -1.64907 5.37049 2.3947 -2.35313 4.80125 2.84316 -2.60079 5.46684 3.62135 -3.33216 5.32305 3.00297 -4.04849 4.59663 2.79864 -4.55605 4.98603 2.05158 -5.42603 5.00647 1.54599 -5.4981 4.02609 1.71817 -5.37985 3.08248 1.3436 -6.03692 3.68969 0.7913291 -5.12813 4.13008 0.8144591 -4.14999 4.44576 0.5977771 -3.78861 5.30065 1.04115 -2.77987 5.33707 1.18217 -2.52792 4.38834 1.08572 -2.52221 4.48135 0.07625182 -1.74136 4.90726 -0.3907509 -1.15378 4.15449 -0.2384429 -1.29891 4.43857 -1.18352 -0.720391 4.19659 -1.9906 -0.119397 4.41892 -2.82944 -0.355969 5.32116 -3.2686 -0.119142 6.14617 -2.61675 -1.0776 6.36578 -2.78959 -1.08351 7.37002 -2.62066 -1.89381 7.51691 -2.14115 -2.39781 6.67009 -2.08979 -1.92712 6.66463 -1.16088 -0.952985 6.57838 -0.9379809 -0.335133 6.18614 -0.1873869 --0.408738 6.02469 0.4817891 -0.161338 5.27121 0.4002171 --0.357776 4.4326 0.1813581 --1.11542 4.50658 -0.4005909 --1.33873 3.85648 -1.19216 --1.35514 3.39354 -0.3017899 --1.88108 4.03949 0.3296981 --2.74622 4.31873 -0.07881508 --3.16147 5.15216 -0.2641179 --3.61952 5.01746 -1.17093 --2.99378 5.80738 -1.08874 --2.63526 6.12156 -1.94933 --2.46585 5.2075 -2.3185 --3.05909 5.30334 -3.12737 --3.63342 4.77048 -2.55572 --2.9984 4.02644 -2.15977 --2.51806 3.61405 -1.36085 --3.08191 3.45852 -0.5606359 --2.81434 2.53669 -0.9791759 --3.18657 2.61399 -1.86622 --2.58598 1.91955 -2.18945 --1.771 1.62991 -1.77652 --1.75587 1.48537 -0.7645179 --2.52746 0.8348679 -0.5038549 --3.41253 1.28401 -0.4693799 --3.82664 1.61516 0.3136631 --4.82915 1.73375 0.2048101 --4.19266 2.38064 -0.06971028 --3.85204 3.06549 0.5472751 --3.90512 3.79267 1.19174 --3.71658 4.65297 1.6836 --2.78696 4.72082 1.5817 --2.00845 4.10395 1.67227 --2.66447 3.33254 1.82767 --2.87576 2.67591 2.48391 --3.96573 2.85553 2.36522 --4.39758 3.75163 2.73176 --4.83855 4.51525 3.07352 --4.44615 4.01932 3.82335 --3.41179 3.83744 3.84552 --3.46186 4.45895 4.55657 --3.87959 3.58864 4.66748 --3.53581 2.79344 5.26731 --2.66484 3.23567 5.48883 --2.31011 2.37025 5.58307 --2.38016 1.35614 5.7109 --2.51314 1.50853 4.73952 --2.32963 2.08639 3.91858 --1.58568 1.50737 4.1691 --1.60749 0.7205749 4.77454 --0.647669 0.6978599 5.03555 --1.02345 0.1129499 5.79445 --1.65835 -0.6447481 5.78678 --2.2469 -0.8098271 4.86316 --1.94465 -1.69471 5.22556 --1.28537 -2.49428 5.16242 --0.427581 -1.96023 5.4321 --0.07343573 -2.4145 4.54865 --0.249328 -1.63902 3.98728 -0.495824 -1.16224 3.58861 -1.17151 -1.00252 4.2819 -0.339323 -0.4276201 4.28618 -0.227604 0.3738969 3.7552 --0.788651 0.1428749 3.60997 --0.398516 -0.5032051 2.97498 -0.23665 -0.8023571 2.22986 -0.508659 0.1627429 2.37475 -1.52492 0.1617829 2.36736 -1.27505 -0.2583291 1.49604 -1.94536 -0.5105621 0.8059041 -1.0385 -1.10975 0.6737341 -0.810312 -0.2276581 0.2453301 --0.08427523 0.1091479 0.3778631 --0.03542283 0.9347269 -0.1749849 -0.549698 1.2176 0.5770521 -0.766198 1.56978 -0.3408409 -1.58905 1.10494 -0.09174428 -2.18712 0.4778809 0.2502351 -2.21572 0.2379469 -0.6691459 -2.31033 -0.7292861 -0.8492749 -2.07613 -0.7636741 -1.87084 -1.73746 -1.71781 -1.68463 -1.62301 -1.92054 -2.60437 -2.58455 -1.86011 -2.36472 -3.09457 -1.17838 -1.90937 -3.479 -0.6046521 -2.60987 -3.62787 -1.28175 -3.30585 -3.49963 -2.09659 -4.02103 -4.24097 -2.0651 -4.79105 -4.15292 -2.56072 -5.63722 -5.16148 -2.79038 -5.73761 -4.62029 -3.25337 -4.93592 -5.13256 -2.77161 -4.22008 -5.89057 -2.30981 -4.5706 -6.73467 -1.78357 -4.37016 -7.0064 -1.53287 -3.38629 -6.34693 -2.28013 -3.24014 -5.45604 -2.27039 -3.18103 -5.94481 -2.59441 -2.39293 -5.18166 -3.24032 -2.39112 -5.33132 -4.17287 -2.74671 -5.17692 -4.7135 -1.98619 -6.1434 -4.63064 -2.26518 -6.72507 -3.87146 -2.57421 -7.45233 -4.09939 -3.1823 -8.41544 -4.01231 -3.14291 -9.19784 -3.904 -2.38127 -9.68944 -4.42256 -1.7043 -10.1624 -5.23877 -1.87715 -10.9405 -4.58862 -2.03899 -11.4756 -4.09502 -1.3383 -12.0899 -3.33724 -1.25016 -11.2971 -3.07061 -1.76896 -11.9504 -2.28442 -1.77053 -11.561 -1.44676 -1.36545 -11.6869 -0.9526601 -0.5816709 -11.5545 -1.63259 0.2271001 -11.3094 -0.7113791 0.4969571 -11.1038 -0.0009610553 1.12714 -11.9758 0.2016329 1.52425 -13.0367 0.1456389 1.75732 -13.8432 -0.2918211 1.3492 -13.9608 -0.5700811 0.3900031 -14.2197 0.4132629 0.4028901 -13.3805 0.9203879 0.2183061 -13.634 1.51208 -0.6055679 -13.0307 2.27011 -0.2935779 -13.3878 2.86781 0.4366971 -13.7032 3.58168 1.032 -12.7162 3.92113 1.03355 -12.5718 4.26689 1.93234 -11.7654 4.47653 2.49794 -11.4905 4.89436 1.673 -11.3586 5.7591 1.21866 -11.87 6.09456 0.3945271 -12.4506 5.4095 -0.1781269 -11.6453 5.02416 -0.5884029 -11.7363 4.38291 0.2548391 -11.7859 3.43616 0.4347251 -11.8467 2.73849 -0.2412439 -11.4603 2.16438 0.4831941 -10.8618 2.55085 -0.1655909 -10.0169 2.36429 0.3975111 -10.3429 3.32787 0.4211181 -9.68509 3.2292 1.15537 -9.04397 2.52782 1.47956 -9.10369 1.7127 2.06474 -8.86298 1.83195 3.0676 -9.64551 2.40866 2.89042 -10.0227 1.76915 3.54817 -10.9605 1.514 3.44244 -11.7203 1.82513 2.74425 -11.8216 2.68006 2.21774 -11.8999 3.15525 1.38039 -12.6922 2.75437 1.71899 -13.3544 2.6309 2.52136 -13.2364 3.21914 3.32995 -12.5471 2.96214 3.95877 -11.924 3.4603 3.40125 -11.0869 3.74212 3.9882 -10.6158 4.00287 3.1832 -10.067 3.4233 3.846 -9.08884 3.25359 3.90837 -9.18083 2.89633 4.8168 -8.57798 2.31183 5.32938 -9.53887 2.23965 5.57435 -10.3859 2.63764 5.87846 -10.6534 3.11706 5.04889 -10.1206 3.82034 5.53207 -10.3562 3.88623 6.54812 -10.9014 3.73161 7.30832 -11.813 4.06043 7.73034 -12.7948 4.29059 7.70803 -12.8312 5.34056 7.77694 -12.9892 4.89134 6.875 -13.3649 5.80885 6.58426 -14.1611 5.79782 5.89521 -14.1792 5.13656 5.15771 -13.4249 5.06062 5.79258 -12.8859 5.81141 5.39577 -12.0267 5.974 4.88193 -12.7336 6.58105 4.5657 -13.0308 7.57981 4.44087 -12.3992 7.82918 3.68664 -11.9997 8.05868 2.7873 -11.2003 7.66415 2.25985 -11.3602 7.57197 1.26649 -12.3314 7.91526 1.10355 -12.3835 7.27114 0.3525751 -11.7989 7.84952 -0.2102939 -11.4836 7.24773 -0.9479959 -12.3677 6.95105 -1.31746 -11.5406 6.9548 -1.93099 -11.3548 7.90794 -2.05874 -10.7469 8.24058 -1.3493 -9.97563 8.92208 -1.16491 -10.1362 9.6571 -0.4645669 -10.7036 10.3749 -0.9442389 -10.2409 10.2062 -1.75469 -9.7781 10.9649 -1.16801 -8.95893 10.5021 -0.9002459 -8.39276 10.756 -0.1567279 -9.18188 10.5389 0.4307441 -8.86261 10.1073 1.23727 -9.23622 11.0468 1.57838 -9.70713 10.2401 1.78836 -9.75052 9.29924 1.49071 -10.2605 9.92318 0.8569741 -10.5312 9.03626 0.5007831 -11.4919 9.227 0.4091401 -12.2607 9.52758 -0.1987109 -13.1412 9.89836 -0.4819729 -13.2717 9.4176 0.4482491 -13.2133 8.90993 -0.3748119 -13.143 8.20372 -1.10799 -13.5677 7.77629 -1.86514 -14.4387 7.21728 -2.09122 -14.8573 6.36381 -2.23145 -14.6242 6.01313 -1.28466 -14.242 5.37283 -1.99802 -14.5326 5.10813 -2.98163 -13.736 4.59746 -2.82257 -12.8358 4.14015 -3.04215 -12.5304 3.65285 -3.88705 -13.3342 3.93411 -4.49398 -13.8808 4.25428 -5.30462 -13.6211 5.10961 -5.87127 -12.6268 5.28698 -6.08871 -12.0846 6.05245 -6.36784 -12.5761 6.64761 -5.77377 -12.5528 7.60973 -5.66901 -13.2621 7.30559 -4.93693 -14.014 7.02031 -5.63562 -13.6027 7.74678 -6.13336 -13.3582 8.69408 -5.89845 -12.4502 8.65624 -5.36835 -11.8737 8.70017 -4.6355 -10.9702 9.20871 -4.54582 -10.4319 9.37097 -3.67089 -9.80495 10.0067 -3.23053 -10.1628 10.9314 -3.39541 -10.745 10.8572 -4.1907 -11.6151 10.2858 -4.3534 -12.4153 10.2625 -4.83631 -12.8918 10.3424 -5.75427 -12.0243 10.7866 -5.77834 -11.3494 11.054 -6.39236 -10.7698 11.6566 -7.01647 -11.3219 12.4935 -7.07117 -11.4543 13.2094 -6.32582 -11.1368 13.6759 -5.5546 -10.2372 13.8693 -5.77727 -10.1114 12.9306 -5.98946 -10.0491 11.9694 -6.23893 -10.2446 11.0113 -6.31794 -10.4141 10.1265 -6.71774 -10.5308 10.0527 -5.68616 -10.9631 9.15594 -5.81776 -10.1491 8.70974 -6.24877 -10.066 8.58514 -7.19313 -10.6293 7.75794 -7.26905 -10.7216 8.39379 -7.97985 -9.95205 7.87571 -8.51143 -10.6769 8.04707 -9.1779 -10.7542 7.04785 -9.18808 -11.7684 7.11009 -9.10184 -12.5546 7.71725 -9.14555 -12.7841 7.52628 -8.15453 -13.7005 7.28925 -8.4548 -13.9073 8.2046 -8.22699 -13.9048 9.00581 -7.58129 -13.0124 8.89298 -7.20146 -13.5215 9.48838 -6.63231 -14.2368 9.91254 -7.18947 -14.8962 10.4286 -6.64753 -14.652 11.381 -6.28966 -13.8645 10.804 -6.3503 -13.0924 11.2864 -6.76033 -12.6918 11.8603 -7.4325 -13.3957 11.8833 -8.12249 -13.1571 12.848 -8.01007 -12.941 13.6433 -7.4132 -12.2585 14.1426 -6.87441 -12.4449 13.5248 -6.14689 -13.3912 13.6281 -6.55168 -14.1105 13.1585 -7.04279 -14.3872 12.7177 -6.23033 -14.0238 12.662 -5.30126 -13.7671 12.337 -4.42042 -12.7911 12.3586 -4.50646 -12.1607 12.6338 -3.72579 -12.0851 11.7455 -3.23039 -12.5383 12.2015 -2.4988 -12.8284 13.1604 -2.11959 -13.2449 13.9382 -1.75931 -13.2004 13.8435 -0.8049229 -13.8773 13.0525 -0.9332559 -13.9606 12.3213 -1.67166 -13.6639 11.6969 -0.8644749 -14.0061 10.8317 -0.8596129 -14.9247 10.9887 -0.5567709 -15.301 11.8237 -0.2332029 -14.7943 12.7345 -0.1543619 -14.4197 11.9998 0.4854721 -14.6336 11.1705 1.01152 -14.6458 10.1806 1.20597 -14.4818 9.19467 0.9801741 -15.0669 8.61486 1.58803 -14.939 7.68919 1.85346 -15.3209 7.43163 0.9584421 -14.8995 8.2189 0.4928101 -15.7483 8.14729 0.01010682 -16.0426 8.96273 0.4985981 -16.8957 9.4371 0.4532891 -17.4859 9.72082 -0.2774239 -18.0135 10.4887 -0.6411859 -17.7093 10.6761 0.3022391 -17.1673 11.2974 -0.1941559 -17.29 12.2979 0.01981182 -17.4236 12.9654 -0.7292299 -16.5363 13.0342 -0.3056389 -15.7564 13.4307 0.1229961 -16.139 13.432 1.02264 -16.2421 14.3328 1.35979 -16.7588 14.2944 0.4926041 -16.9099 14.3248 -0.4454059 -17.7807 14.4613 -0.09132518 -17.9004 15.2138 0.4969461 -17.1281 15.6581 0.9583371 -16.4562 15.4885 1.66357 -17.0688 16.0755 2.13761 -16.3925 16.1747 2.82331 -16.1871 17.1082 2.74948 -15.3501 16.8536 2.21423 -15.0065 17.8116 1.93589 -15.6403 18.5494 1.66703 -16.0667 19.2576 2.36423 -15.4224 18.9193 3.1201 -14.8076 19.1008 2.42134 -15.287 19.6894 1.78975 -14.6676 20.0458 1.1041 -13.9612 20.4142 1.6439 -13.7947 19.8789 2.51087 -13.286 20.3944 3.25837 -13.1444 21.3199 3.55329 -12.1778 21.4364 3.91596 -11.5719 21.5445 4.66238 -12.0566 21.1507 5.3855 -12.6925 21.5926 4.73618 -13.2567 20.7458 4.71401 -14.1671 20.5377 4.9157 -14.5248 21.3818 5.32655 -15.3326 21.4021 5.98379 -15.5768 22.1714 6.56529 -15.4879 22.6245 5.67089 -16.066 23.3434 5.47305 -16.8365 23.6625 5.96844 -16.8347 23.731 6.99962 -16.4203 24.6372 6.78255 -16.6363 25.2676 7.52447 -16.8357 26.1723 7.0361 -17.7275 25.8475 6.72239 -18.3549 26.0502 7.44647 -18.516 25.0817 7.62611 -19.3896 25.407 7.1193 -19.172 25.9659 6.33511 -19.0135 25.027 6.03299 -18.6653 24.0765 6.24996 -18.9004 23.113 6.10224 -18.6276 22.2849 5.54896 -18.8346 21.65 6.26011 -17.9965 21.2658 6.45281 -17.131 20.9284 6.69786 -16.3959 21.2514 6.10582 -17.1083 21.6768 5.48489 -16.7262 22.3826 4.83434 -16.6309 21.4924 4.55798 -16.586 20.9414 3.76192 -16.9968 20.5969 2.91863 -17.9611 20.5238 3.20098 -18.4161 21.1226 2.60313 -18.4414 20.469 1.8566 -17.6147 20.0143 1.53764 -17.5195 19.7033 0.6510101 -16.9634 18.8777 0.4092141 -17.9686 18.5953 0.6325491 -17.9047 18.5958 -0.3563799 -18.2487 18.2122 -1.23596 -19.1597 18.6137 -0.9929809 -19.2447 19.5806 -1.0401 -19.6589 20.2953 -0.5667299 -19.5355 19.976 0.3288441 -19.9285 19.9998 1.27098 -19.2261 19.3175 1.22847 -18.4661 18.8628 1.65547 -19.1564 18.1347 1.76409 -19.7641 18.1138 2.52907 -20.4793 17.3803 2.56344 -20.6492 17.3666 1.62757 -19.9459 17.7 0.8822991 -19.2816 16.9268 0.7300331 -19.0457 17.3468 -0.1744659 -18.4703 17.0291 -0.9208619 -18.954 16.2432 -0.4346939 -18.6366 15.5809 -1.17525 -17.778 16.0628 -1.37626 -17.0023 16.76 -1.28295 -16.5628 16.2459 -0.5189429 -15.6548 15.9756 -1.02082 -15.8088 15.7455 -1.96468 -15.4269 15.4439 -2.83078 -15.2446 15.2407 -3.79663 -15.6448 15.2573 -4.66529 -16.2325 14.786 -5.308 -16.6736 15.5988 -5.02026 -17.6542 15.2925 -4.96189 -18.2471 14.5893 -5.01974 -18.869 15.2777 -4.71836 -19.7518 14.9857 -4.57214 -20.6327 15.192 -4.20484 -20.2399 14.9371 -3.27653 -19.8756 14.0023 -3.45092 -20.5159 13.1785 -3.40428 -20.1024 12.7568 -4.27433 -20.493 12.4508 -5.19687 -20.989 13.05 -5.78981 -21.6279 12.9314 -6.5022 -21.591 12.5976 -7.42071 -22.5591 12.6362 -7.56365 -22.4015 13.6432 -7.50415 -23.089 14.4248 -7.4987 -24.0654 14.466 -7.24278 -23.7093 14.5574 -6.33657 -23.7838 15.0741 -5.56943 -23.1947 14.4676 -5.07484 -22.3996 14.2725 -5.58906 -22.5403 14.3865 -6.56904 -22.4174 15.3984 -6.40802 -23.2414 15.4966 -6.9889 -23.9887 16.0907 -7.06902 -23.7163 16.4085 -7.9255 -24.0761 17.2083 -8.48067 -23.8144 18.0186 -8.95579 -23.5627 19.0153 -8.87742 -24.2112 19.4028 -8.15933 -24.5388 18.7307 -7.41179 -23.9057 18.016 -7.10929 -24.6919 17.4977 -6.91617 -25.2517 17.7173 -6.12959 -25.8153 17.0638 -6.57593 -26.7042 16.6921 -6.44738 -26.908 15.7897 -6.78374 -26.5261 15.0025 -7.26032 -27.3098 14.4621 -6.9585 -28.0853 14.6888 -6.28878 -28.606 13.8891 -6.57696 -28.767 12.9085 -6.50483 -28.22 13.0918 -5.6804 -27.4064 13.4999 -5.29679 -26.991 12.6088 -5.2002 -26.6652 11.7188 -5.20021 -27.0652 11.255 -5.95453 -27.9306 11.6031 -6.33648 -27.2157 11.6014 -7.00453 -26.2631 11.1906 -6.98191 -26.1682 10.8557 -6.0517 -25.956 10.038 -5.48843 -26.0179 9.04095 -5.78616 -26.7247 8.59002 -6.25828 -26.6394 7.64874 -6.39522 -25.9785 8.26322 -6.85718 -25.2239 8.45957 -7.49011 -25.7945 8.73019 -8.18574 -26.038 7.78059 -8.32471 -26.8843 7.27732 -8.47072 -26.7651 6.36829 -8.76905 -27.5281 6.36404 -8.14051 -26.9992 5.57463 -8.32773 -27.1457 5.06478 -9.13724 -27.6887 4.27711 -9.51881 -26.7967 3.90346 -9.31259 -27.2208 3.23605 -10.0073 -26.998 2.34851 -10.531 -27.6273 1.56474 -10.4578 -27.6621 1.58461 -9.48161 -27.4067 1.72635 -8.48859 -27.6347 2.64149 -8.23717 -27.5229 3.29735 -7.53157 -27.4506 2.44691 -7.07983 -26.5522 2.05198 -7.27673 -26.2435 1.22456 -7.74694 -26.8845 0.5883139 -8.05487 -27.2925 -0.1204471 -7.46492 -27.8971 0.6740839 -7.39457 -27.4943 0.4424239 -6.55023 -27.0123 -0.1072741 -5.77207 -26.1263 0.3075229 -6.0482 -25.7517 1.04204 -5.55622 -25.0002 0.5158049 -5.95322 -24.7544 1.40551 -5.69841 -24.2025 1.82318 -6.40925 -23.3012 1.38142 -6.18988 -23.6509 1.44023 -7.15322 -22.7322 1.14357 -7.32776 -23.222 1.46947 -8.08629 -23.602 1.42015 -9.01133 -23.112 0.8639769 -9.72501 -22.7748 0.5776829 -8.81463 -23.1871 -0.2674801 -8.40605 -22.2714 -0.5491391 -8.64038 -21.4144 0.04958043 -8.6673 -21.431 0.6362769 -9.46642 -20.5395 1.02919 -9.63894 -20.0501 1.21944 -10.4745 -19.9034 1.93928 -11.2389 -19.5421 1.17204 -11.7558 -19.3278 0.1551019 -11.593 -18.716 -0.3584041 -12.2024 -18.3873 -1.20732 -11.8986 -17.7278 -1.87571 -11.7133 -17.3417 -1.20318 -11.0282 -17.8132 -0.3484381 -11.2352 -17.5139 0.2025309 -11.9667 -17.978 0.7816259 -11.387 -18.3625 0.8131549 -10.4617 -18.6682 1.34669 -9.67299 -18.27 2.10639 -9.19095 -17.991 1.22578 -8.94962 -18.4385 0.5701549 -8.36457 -19.0744 0.1515779 -7.80857 -19.2951 -0.5166431 -7.15144 -19.0283 -0.6788711 -6.2312 -18.1294 -0.1550071 -6.25102 -18.7758 -0.002729446 -5.50204 -18.8395 -0.5532041 -4.68536 -19.6157 -0.05053807 -4.41419 -20.2464 -0.6748601 -4.89527 -20.7625 0.1237319 -4.72104 -20.6059 0.9667829 -4.29473 -21.6155 1.06448 -4.43985 -22.4028 0.4266889 -4.64229 -23.0321 -0.1069801 -5.14129 -23.4378 -0.7973771 -4.51886 -23.3389 -1.62493 -5.08592 -23.9615 -0.9272101 -5.42478 -23.6628 -1.57815 -6.00981 -24.6585 -1.72078 -6.08848 -25.4623 -2.21768 -6.24301 -25.6137 -2.24626 -5.24264 -25.6409 -2.24353 -4.27033 -26.6122 -2.47512 -3.95941 -26.5074 -2.37914 -2.99967 -27.0262 -2.20609 -2.15222 -27.7028 -1.88532 -1.56778 -27.8765 -0.8658661 -1.67802 -28.5693 -0.3089911 -1.38992 -29.3008 0.2349359 -1.16132 -30.199 0.3805909 -1.46692 -30.5499 1.31555 -1.28025 -31.3961 1.13065 -0.7398609 -32.0769 0.6193469 -1.26139 -32.7453 0.6238219 -1.99164 -32.7672 1.55676 -2.44949 -31.8543 1.57149 -2.9274 -31.1745 1.36327 -3.65916 -31.3205 2.31915 -3.89621 -31.6167 3.18438 -3.62042 -32.4133 3.73318 -3.31432 -32.9895 3.19062 -2.69703 -33.4854 2.37074 -2.55594 -33.9627 3.15499 -2.9511 -34.1001 2.64709 -3.84491 -34.3334 1.75534 -3.40427 -34.215 0.7378809 -3.47185 -33.5024 0.2887179 -2.91048 -32.9214 -0.4978721 -2.72929 -32.5131 -0.9021571 -1.86992 -32.0589 -1.67648 -2.32599 -32.4095 -2.59771 -2.31093 -32.4582 -3.5919 -2.18342 -32.1009 -4.26535 -2.77233 -32.7504 -4.81135 -3.27747 -31.9983 -4.7072 -4.0253 -31.8621 -5.67267 -3.99359 -32.0148 -6.59491 -3.40146 -31.7165 -7.20811 -2.6255 -31.2994 -6.37546 -2.31289 -31.8353 -6.55155 -1.5252 -32.1147 -5.91748 -0.8506229 -32.819 -5.26174 -0.5450729 -33.5705 -4.75407 -1.02471 -34.1165 -4.94972 -0.2240299 -34.0729 -5.78081 -0.8163089 -33.4601 -6.53118 -1.14011 -33.2879 -6.56782 -2.12281 -32.876 -7.48352 -2.15261 -32.0882 -8.11932 -2.004 -31.1492 -8.04084 -1.62163 -30.9704 -8.88678 -1.077 -31.6185 -9.43117 -1.65863 -32.5444 -9.28376 -1.15292 -32.1055 -8.50657 -0.7925559 -32.6521 -8.41461 0.01364232 -33.4529 -8.52509 0.6079271 -33.7989 -8.14399 -0.3067549 -34.3899 -7.86339 -1.09724 -35.078 -7.47205 -0.5051759 -35.6266 -7.42593 0.2519761 -35.2999 -7.4015 1.29048 -34.9355 -8.24956 0.9149521 -35.3565 -9.11555 1.27441 -36.198 -9.08104 1.85578 -36.687 -8.49689 2.53472 -37.6789 -8.73475 2.40435 -37.392 -8.83703 1.45231 -37.0887 -9.32468 0.5973851 -37.4325 -8.94327 -0.2578119 -37.6539 -7.9877 -0.06869868 -37.0218 -7.23979 -0.1494659 -37.2901 -6.75983 -0.9317609 -36.432 -6.45951 -1.06319 -36.0511 -6.7162 -1.94775 -35.5862 -6.32214 -2.66077 -35.8379 -6.32094 -3.63559 -36.4795 -7.08425 -3.57282 -36.615 -6.90925 -4.5543 -36.8572 -7.01268 -5.49867 -36.6891 -6.86373 -6.49345 -36.0555 -6.66229 -7.31166 -36.3581 -5.72681 -7.60839 -35.4909 -5.84207 -7.1167 -34.5458 -5.94289 -7.33522 -33.784 -6.35761 -7.88957 -33.1362 -6.03209 -8.53042 -32.8098 -6.92856 -8.26421 -32.892 -7.0374 -9.23605 -32.0213 -6.48977 -9.15056 -31.5591 -6.80816 -9.99106 -31.1608 -7.02782 -9.14398 -30.9011 -6.24747 -8.74789 -30.679 -5.33466 -8.31746 -31.1154 -5.34561 -7.42058 -31.789 -4.93981 -6.82595 -32.7295 -4.82486 -7.39586 -32.4827 -4.44141 -8.30393 -32.0413 -3.76941 -7.65133 -31.6245 -2.88061 -7.57937 -31.3716 -3.43875 -8.30091 -30.7081 -3.0003 -8.90651 -29.9231 -2.74827 -8.38939 -29.4256 -3.06855 -7.57169 -29.0449 -2.11275 -7.60281 -28.7353 -2.41746 -8.5009 -28.9848 -2.45513 -9.41481 -29.4611 -1.83715 -9.95792 -30.4098 -2.16527 -10.244 -30.3085 -1.44922 -10.8665 -30.5826 -0.7761591 -10.1886 -30.343 0.1021519 -10.4285 -30.5548 0.4434849 -9.52092 -31.5171 0.7759869 -9.33066 -32.4185 0.9651259 -9.02966 -32.8869 0.1088819 -9.01102 -32.8222 0.1296589 -8.0145 -32.9334 -0.7668221 -7.60404 -33.6043 -0.9532401 -6.99619 -33.9053 -1.8817 -6.91952 -33.0173 -2.21705 -6.63705 -32.1358 -2.51773 -6.51011 -31.1187 -2.27061 -6.57006 -31.4909 -1.50795 -7.15872 -30.6265 -1.09123 -7.05311 -30.3568 -0.7474491 -7.91227 -29.5833 -0.1074381 -7.94849 -28.7658 -0.3190371 -8.59322 -28.5438 0.3300709 -9.27827 -28.8412 -0.2191671 -10.0891 -28.1076 -0.8036791 -9.61319 -27.8365 -0.4055351 -10.4566 -27.396 -1.28666 -10.7473 -26.6289 -1.85709 -10.9505 -26.7996 -1.515 -11.8449 -27.4342 -1.26696 -12.6613 -26.6199 -0.6665481 -12.8523 -25.6153 -0.6017801 -13.005 -25.6401 -0.4262301 -12.0515 -25.887 0.3688129 -11.5575 -26.4596 0.4011149 -10.8054 -25.6025 0.07164063 -10.3103 -25.1606 0.5351849 -9.50711 -25.0377 -0.4727051 -9.3532 -25.3382 -1.1144 -10.0898 -26.3007 -0.9136311 -10.4322 -26.0929 -1.45388 -9.63996 -26.2997 -0.6357161 -9.08193 -25.7314 -0.03961267 -8.47687 -24.8911 -0.4802131 -8.06567 -24.5538 0.1816999 -7.4842 -24.9471 1.061 -7.5712 -24.6802 1.72235 -8.2265 -24.5703 2.11915 -9.22276 -25.3802 2.64983 -9.42084 -25.8193 2.93333 -10.2692 -25.2135 3.67355 -10.3591 -25.0699 4.44441 -10.9631 -25.2153 4.07058 -11.91 -26.047 4.52826 -11.8539 -26.3513 5.42717 -11.8323 -27.1673 4.91617 -12.0224 -27.3107 4.49922 -12.9183 -27.687 3.96861 -13.6767 -28.4473 4.21044 -13.1492 -28.3392 3.38155 -12.5785 -28.8956 3.62921 -11.791 -28.8966 3.15545 -10.9392 -29.0951 2.55872 -11.734 -29.843 2.63031 -11.1939 -29.8547 2.8152 -10.1875 -29.5949 3.45269 -9.42848 -28.6314 3.43305 -9.7193 -28.4284 3.35955 -8.81683 -28.023 4.05999 -8.18582 -28.1264 4.47708 -7.28586 -27.4342 4.45374 -6.52467 -26.6706 4.81338 -5.90767 -26.6383 3.88146 -6.15685 -26.6373 3.05847 -6.63891 -26.4092 3.71027 -7.26681 -25.5271 4.06586 -7.24498 -24.6134 3.61532 -7.11949 -24.7195 2.92714 -7.87352 -24.4103 3.53385 -8.59212 -23.4874 3.72186 -8.29672 -23.3423 3.67059 -7.29521 -22.903 3.08045 -6.66395 -23.6587 3.26912 -6.07231 -24.6015 3.08123 -6.01093 -25.5064 3.35842 -5.59499 -25.7349 2.75437 -4.83136 -26.729 3.11159 -5.00161 -27.5883 3.68246 -5.20321 -27.4052 4.64336 -5.19307 -27.5466 5.01515 -4.16701 -26.5417 5.04773 -4.03648 -25.9672 5.84404 -4.24584 -25.0879 6.16534 -4.60365 -24.85 6.41511 -3.65925 -23.8013 6.50937 -3.52799 -23.3552 6.3415 -4.40398 -23.1874 6.84381 -5.24582 -22.4694 7.62969 -5.27708 -22.1313 8.52487 -4.85359 -22.5522 9.31307 -5.26893 -22.9449 10.134 -4.82952 -23.8389 9.75206 -5.11463 -24.3093 10.0451 -5.88698 -23.4782 9.61923 -6.23702 -22.977 10.1672 -6.86512 -22.8253 10.4871 -7.76667 -22.7851 11.3515 -8.33747 -23.0052 10.7083 -9.09152 -23.0158 11.6409 -9.42984 -23.0613 12.5339 -8.93692 -23.7206 13.226 -8.60102 -24.2911 12.6578 -8.01583 -25.2004 12.9288 -7.82151 -26.0773 13.0246 -7.29689 -26.3354 13.5441 -6.51761 -25.7874 12.6867 -6.22005 -25.2761 11.9488 -5.71705 -24.5572 12.3731 -6.14168 -23.6565 12.7759 -5.96189 -22.9248 13.0706 -6.5639 -22.4295 12.9578 -5.7014 -22.1408 12.7882 -4.7517 -21.5013 12.4092 -4.10777 -21.161 11.6335 -4.71278 -21.3967 11.4483 -3.74886 -20.8162 11.1433 -2.99594 -20.1814 10.7073 -2.39808 -21.1446 10.58 -2.23769 -22.0244 11.0778 -2.47454 -22.8558 11.4987 -2.0877 -22.5907 12.3736 -2.24774 -23.35 12.9125 -2.03304 -24.1181 13.4098 -1.6769 -25.0492 13.041 -1.66227 -25.7559 13.533 -2.11693 -25.9241 12.701 -2.74319 -25.1964 12.0545 -2.41924 -24.9999 11.3353 -1.7799 -24.7017 10.4736 -2.15812 -25.0673 10.5789 -3.07041 -25.3572 10.2 -3.97585 -26.1586 10.6441 -3.54716 -26.3507 10.7737 -2.58436 -26.9732 11.514 -2.72917 -27.2563 12.1724 -1.97272 -27.7664 13.0049 -1.92721 -27.6216 14.0113 -1.99521 -27.1136 14.7662 -2.2626 -26.4017 15.4639 -2.54486 -25.691 15.8819 -1.98842 -25.92 16.693 -2.50765 -25.6327 17.5021 -1.99368 -25.2252 16.9826 -1.22229 -24.4088 16.41 -0.9609739 -23.8496 16.7142 -1.69316 -23.8569 16.5583 -2.70281 -24.2982 16.2106 -3.60673 -24.6723 16.9807 -4.17119 -23.8908 16.6364 -4.70541 -23.0156 16.9597 -5.05832 -22.2056 16.886 -5.67052 -21.2919 16.9596 -6.00505 -20.9692 17.9037 -6.10941 -20.3966 18.2611 -6.79178 -19.8115 18.7992 -7.35801 -19.5168 17.9552 -6.98478 -18.5122 17.7215 -6.67459 -17.7921 16.9794 -6.67988 -17.1662 16.3195 -6.29573 -17.5189 15.359 -6.48448 -18.4642 15.1668 -6.80319 -18.4096 14.2421 -6.54617 -18.8062 13.7822 -7.28229 -18.747 13.2729 -8.11609 -18.6035 12.5322 -8.82229 -18.7337 11.5021 -9.11 -18.0158 11.0235 -8.73953 -18.7369 11.13 -8.03418 -17.9084 11.5975 -7.54947 -17.197 11.6036 -6.79947 -16.7747 11.9812 -5.99704 -16.2299 12.4345 -5.36654 -16.3359 13.4506 -5.20611 -15.527 13.9269 -5.69834 -14.7485 13.6763 -5.14358 -14.5094 14.4657 -4.56492 -14.1066 14.4826 -3.62557 -14.6087 14.1005 -2.83163 -15.1502 13.8813 -3.64618 -15.877 14.0856 -2.93892 -16.7653 13.8683 -2.655 -17.5665 14.0849 -2.20914 -18.5178 13.717 -2.22097 -19.2345 14.2714 -2.6577 -19.8531 14.2782 -1.79967 -19.3204 13.8132 -1.1493 -19.8821 13.1389 -0.7662349 -20.7648 13.0705 -1.16328 -21.0805 12.8353 -2.06428 -21.8628 12.6499 -1.5134 -21.6056 11.6493 -1.2685 -22.371 11.1609 -0.8089879 -22.0864 10.1147 -0.7042299 -21.4713 9.67908 -1.33246 -21.8564 8.88424 -0.8438029 -22.0217 8.12736 -0.3448949 -21.3336 8.72961 0.05552692 -21.3088 8.02625 0.8371771 -21.3244 7.25846 0.2658991 -20.8501 6.59385 0.8671261 -19.9672 7.03924 0.9680011 -19.1909 6.48206 1.3156 -19.7103 6.115 2.05301 -19.7354 5.12899 2.32421 -20.5681 4.79043 2.69903 -19.7692 4.21647 2.73318 -20.0988 3.32569 2.36043 -19.9007 2.3973 2.01311 -19.1986 1.94061 1.53645 -18.6927 2.16009 0.7239021 -18.3857 1.31595 0.9470151 -19.0388 0.6865949 1.2747 -19.7585 0.7810829 0.5643501 -20.304 0.3481559 -0.1642499 -20.332 1.05983 -0.8870599 -20.3579 1.95478 -1.38933 -21.2411 2.05659 -0.8813569 -20.7618 2.2217 -0.00160969 -21.4741 2.92935 0.2641491 -22.0028 3.81607 0.2507691 -21.7477 3.8532 1.20837 -21.9934 3.32401 2.01692 -22.8256 3.30105 2.65168 -22.3292 3.67891 3.47445 -21.9159 4.17081 4.27115 -21.9419 5.20785 4.53702 -21.4289 6.12136 4.40055 -21.721 6.81382 5.09559 -21.3967 6.80788 6.03464 -20.7749 6.75134 5.22999 -20.0959 7.54942 5.30082 -20.5175 7.38679 4.37273 -20.8128 7.72913 3.45933 -21.6462 7.32995 3.44421 -21.2525 7.44411 2.50148 -20.4136 7.02761 2.83067 -20.4273 6.4944 3.69789 -19.9901 6.0522 4.45463 -18.98 6.04004 4.44749 -19.0145 5.09029 4.5901 -19.4058 4.15161 4.61046 -20.0632 3.39302 4.57121 -19.2164 3.19854 5.14239 -19.1277 2.24578 4.72208 -19.6205 1.5134 4.16073 -19.8689 0.5387549 4.39897 -20.3239 -0.3684031 4.3997 -20.4135 -0.09945307 3.37295 -20.3881 -0.4768681 2.41504 -21.1361 0.1237799 2.74977 -21.7879 0.2456939 3.46715 -22.1456 0.9391379 4.06519 -23.0739 0.8777849 4.11954 -23.4242 0.3288149 3.3999 -23.8117 0.1083679 4.33017 -23.8159 0.3829339 5.28198 -24.4901 1.10225 5.43234 -23.7918 1.77536 5.63149 -23.4723 2.71904 5.72912 -23.7682 3.65166 5.36862 -22.9665 4.08164 5.76728 -23.3379 4.74276 6.43469 -24.2185 5.11071 6.80754 -25.048 5.65355 6.97118 -26.0049 5.56672 7.03285 -26.0963 4.76847 7.5229 -26.8708 4.18911 7.97899 -26.2886 4.63197 8.74785 -26.4104 3.72256 9.13065 -27.1418 3.66878 9.79438 -28.0751 3.83721 10.0607 -28.7675 3.62621 10.8324 -29.2472 4.36264 10.3656 -29.7753 3.87012 10.9791 -30.1955 2.94836 11.2164 -30.0572 2.06629 11.6749 -29.139 1.89699 11.3434 -29.7256 1.365 10.7451 -30.7142 1.43555 10.7594 -31.5536 1.40724 10.2246 -31.1736 1.95855 9.50557 -31.0103 2.51925 8.70455 -30.4341 2.66399 7.8713 -29.8259 3.03745 8.5384 -29.5654 2.91005 9.5135 -29.6179 1.96856 9.77554 -28.8155 1.58358 9.32203 -27.867 1.27337 9.03456 -28.0147 0.6239549 9.70849 -27.0466 0.4823889 9.98394 -26.9426 -0.09965557 10.8766 -26.7819 -0.5580731 10.0335 -26.7005 -0.5833211 9.12372 -27.3904 -1.26685 8.9211 -27.1056 -2.20014 8.68172 -27.5202 -2.14598 9.60536 -28.2439 -2.62018 10.0839 -28.9926 -3.09827 9.75647 -29.206 -3.34113 10.5686 -29.9799 -2.59864 10.4652 -30.855 -2.12727 10.2928 -30.7099 -2.97763 9.72211 -31.1388 -2.57159 8.94029 -30.5153 -3.12749 8.48102 -30.3577 -3.11424 7.46956 -31.2742 -3.05156 6.96587 -31.5845 -2.31295 7.65867 -32.0579 -3.15164 7.91483 -31.2866 -3.69542 7.92696 -30.8046 -4.28163 7.27895 -29.824 -4.21925 6.98443 -30.0454 -5.03738 6.45364 -29.4129 -4.95255 5.72211 -29.0474 -4.1598 5.23769 -28.0432 -4.10566 5.41371 -27.2261 -3.93984 5.99618 -27.1098 -3.10856 5.54064 -27.982 -2.9914 6.06159 -27.9553 -1.97183 5.91501 -28.3684 -1.18064 6.14697 -27.8305 -1.01282 5.37616 -27.0008 -0.5068821 5.50122 -26.7953 0.4859129 5.39103 -26.2844 -0.06405807 4.707 -26.022 -0.9745091 4.39482 -25.2414 -0.8666941 5.09208 -24.5704 -0.9777451 4.37098 -23.7916 -1.56604 4.52572 -23.4721 -1.68697 5.48271 -23.1282 -2.12808 6.30738 -23.6835 -1.81146 7.14622 -23.1072 -1.1642 6.68715 -23.0551 -0.3249691 7.26986 -22.3401 -0.8760271 7.65312 -22.7836 -0.2255491 8.24047 -22.978 -1.2076 8.45399 -23.4871 -1.02778 9.28189 -23.7353 -0.7388711 10.2037 -24.2044 -0.1886841 10.8909 -25.12 0.1166989 10.6127 -25.7734 -0.2338531 9.99157 -25.5338 0.5233129 9.26953 -25.8487 1.28992 9.82745 -25.8079 2.34301 9.59925 -25.7022 2.24057 8.6252 -25.3191 2.45179 7.8215 -26.0252 3.12815 7.5164 -26.3403 3.46191 6.60412 -25.7205 3.33372 5.8021 -25.4492 3.98317 5.06354 -25.6444 3.93867 4.06216 -26.3385 4.53524 3.79739 -26.1537 4.8443 2.83052 -25.8951 5.44773 2.00164 -25.7543 6.42372 1.86752 -25.6425 6.49181 0.8893701 -26.4688 5.86685 0.9155541 -27.0066 5.05997 0.8838441 -26.3031 4.3 0.9820631 -25.4898 4.43298 0.4192911 -25.0975 4.86804 -0.4508899 -25.0198 5.79006 -1.00449 -24.007 5.61127 -0.8491679 -23.3908 4.80863 -0.7841409 -23.148 4.84988 -1.76235 -23.8094 4.07117 -1.7771 -23.5438 3.69624 -0.9077349 -23.7494 2.87394 -0.3418099 -24.1163 2.03533 -0.7569189 -23.2868 1.44233 -0.5998649 -23.3752 1.60324 0.3601461 -23.3723 0.9235289 1.1082 -24.3579 1.12928 0.7468811 -25.1533 0.9175069 0.1941591 -24.8891 1.91784 0.04494502 -25.1038 1.3821 -0.7665529 -25.1431 1.69135 -1.72066 -25.1358 2.31535 -2.49818 -25.8654 2.46711 -3.15569 -26.4925 2.86806 -3.79567 -27.3234 3.29223 -3.53558 -26.7472 3.19831 -2.69516 -27.0479 2.25847 -2.36407 -27.8445 2.9146 -2.19973 -28.6829 2.75017 -2.58012 -29.4131 2.08193 -2.64811 -28.475 1.67392 -2.65869 -28.4096 1.11216 -1.87262 -28.1646 0.8850199 -0.9221629 -28.1624 1.73935 -0.3897119 -28.9231 2.30244 -0.1692429 -28.4229 2.0373 0.7066981 -28.2255 2.32599 1.61114 -29.1882 2.57984 1.68224 -29.2368 2.83034 2.62263 -28.7343 2.02197 2.90594 -29.5632 1.95923 3.36253 -30.0412 1.20689 3.65465 -30.2503 0.4325179 3.02396 -29.8852 -0.1469681 3.78201 -29.9306 -1.05595 4.21965 -30.838 -0.9556541 3.8964 -30.556 -1.25563 2.95583 -30.1142 -1.61754 2.1469 -30.8675 -2.04253 1.53979 -30.7368 -2.91533 1.96179 -30.9546 -3.02931 2.90265 -31.2724 -3.9821 2.83941 -30.4619 -4.50783 2.91379 -29.8963 -4.77396 2.11769 -30.0018 -3.89854 1.64314 -30.4565 -3.39242 0.8656431 -29.5646 -2.97503 0.8383791 -28.979 -2.4507 1.4835 -28.2024 -2.40125 2.13064 -29.018 -2.88473 2.47236 -29.2015 -1.98927 2.86685 -28.364 -1.63293 3.21712 -28.1 -0.8612181 2.70283 -27.4365 -0.9959161 1.91333 -26.4985 -1.30046 1.69259 -27.0288 -1.89379 1.18995 -27.0259 -2.20979 0.2209731 -27.0936 -1.50223 -0.4439029 -27.3106 -0.6244131 -0.1202729 -26.3606 -0.5866571 -0.5270169 -25.7744 -0.1369371 0.2819911 -24.9459 -0.5100441 0.6782821 -24.0855 -0.6414821 1.08641 -24.4237 -0.05681367 1.73589 -25.2436 0.01332063 2.47011 -24.669 0.8026359 2.8342 -24.2319 1.01221 1.95356 -24.5321 2.01222 2.0971 -24.9646 2.96723 2.0575 -24.1492 3.15068 2.72341 -24.6224 4.00879 2.84563 -24.1855 4.62183 2.1823 -23.6194 4.8242 2.93838 -23.2307 5.79023 3.03437 -23.1786 5.74947 1.99375 -22.4131 5.09058 1.79942 -23.0241 5.11568 0.9745161 -22.5573 4.88078 0.1262221 -22.2843 5.64026 -0.4677099 -22.7512 6.398 -0.02866758 -23.283 7.15775 0.3313241 -23.3566 7.84684 -0.3623069 -23.1868 8.81151 -0.06877338 -23.8136 9.44552 -0.4500529 -24.6011 8.8724 -0.4290269 -24.897 9.33906 0.4374631 -25.293 9.59628 1.19454 -25.469 9.52519 2.18133 -26.0754 8.82392 2.57996 -25.2862 8.40256 3.0027 -24.3392 8.39604 3.34683 -24.4188 8.7742 4.23284 -25.0218 9.08253 4.98159 -25.4965 9.96335 5.07956 -25.5492 10.8737 5.59237 -26.2219 10.7862 4.86591 -26.3779 11.4814 4.16047 -26.6844 10.6997 3.66664 -25.765 10.5099 3.84134 -25.127 11.0936 4.27854 -24.331 10.7743 3.69624 -23.7718 10.8683 2.90725 -23.5606 11.814 2.61285 -22.6723 12.2102 2.77787 -22.5949 11.6814 1.94051 -22.1303 10.8654 1.4938 -21.1173 10.6156 1.59132 -20.8542 11.2477 0.8829491 -20.2297 11.4895 1.65053 -19.4965 10.8208 1.79923 -18.6507 11.2438 1.4626 -18.8012 11.9211 0.8459591 -19.6841 12.1405 0.5081671 -20.1391 12.9553 0.6409621 -20.1188 13.7518 1.2459 -19.0931 13.7556 1.22308 -18.111 13.8652 1.54791 -18.2907 14.8398 1.94268 -19.0612 15.4278 1.8828 -19.542 15.6949 1.01623 -20.1833 14.9839 1.16266 -20.8278 14.8256 1.80946 -21.7042 15.0712 1.45151 -21.7518 15.0343 0.4573561 -21.2337 14.2312 0.4859511 -21.2235 13.2037 0.4695251 -21.9181 13.1492 1.23175 -22.4505 12.5571 0.6686281 -23.0104 11.769 0.4971351 -23.604 12.4656 0.9777411 -24.1728 12.9413 1.61808 -24.2309 13.6862 2.30331 -24.5871 13.9818 3.20195 -23.7474 13.6092 3.51391 -22.7911 13.8802 3.1566 -23.3086 14.5919 3.7603 -23.4456 14.8848 4.68362 -24.0134 15.7255 4.3986 -24.739 15.9593 5.09366 -25.6199 15.9586 5.59117 -26.4867 16.4701 5.69702 -25.9745 17.2253 6.10472 -25.052 17.495 6.33429 -24.42 17.5964 7.1942 -23.4809 17.5308 7.32158 -23.53 16.8682 8.05263 -22.5875 17.1398 7.76847 -22.5851 17.0679 6.74141 -22.4541 16.1239 7.00516 -22.5491 15.5554 6.16521 -23.2498 15.7127 5.40227 -22.6058 16.3792 4.92296 -22.2351 15.3963 4.87872 -21.4333 15.7741 4.34147 -20.6886 16.3486 4.7736 -21.0253 17.2513 4.94365 -21.8528 17.7489 4.74951 -21.8959 18.6769 4.69453 -21.5688 18.4512 3.7256 -20.9137 19.1892 3.61619 -21.7735 19.6694 3.6934 -22.6837 19.8258 3.62277 -22.836 20.3571 4.43613 -22.1342 20.9129 3.93374 -22.0524 21.0109 2.97994 -21.9712 21.1969 2.01137 -21.4378 20.7934 1.30135 -21.8945 20.6259 0.4796241 -21.6901 21.4712 -0.03427968 -21.4845 22.4161 -0.3104359 -22.3573 22.795 -0.1601949 -22.9756 22.1399 -0.6783019 -23.0999 22.8405 -1.34395 -22.1818 23.0551 -1.67556 -22.3831 23.8732 -2.11899 -23.1976 24.2478 -1.57673 -23.9153 24.9201 -1.33239 -24.8165 25.0377 -1.74666 -24.5308 25.7968 -1.144 -25.2196 25.398 -0.6070619 -24.4814 25.4123 0.02967192 -24.1316 26.3323 0.2203381 -23.2603 25.9454 0.5794341 -22.9093 25.6753 1.49694 -22.5593 25.2528 2.34468 -23.2298 24.7415 1.70307 -22.8648 23.8003 1.71589 -23.0556 22.8493 2.07886 -22.1803 22.4252 2.44282 -22.2505 23.1268 3.10623 -22.2829 24.1512 3.22282 -21.397 24.2978 2.87728 -20.4205 24.2204 2.73712 -20.1535 24.2774 3.73494 -19.9836 25.2513 4.03763 -20.1195 26.1773 3.71095 -19.5197 25.7365 3.02782 -19.1462 24.8994 2.90809 -18.7228 25.6479 2.3805 -18.0568 24.9101 2.69786 -17.9868 25.1812 1.71498 -17.7721 24.1912 1.45628 -18.361 23.4131 1.68515 -18.4044 22.4433 1.60029 -18.3353 21.8098 0.8154091 -17.326 22.0334 0.7732691 -16.6175 22.6318 1.0048 -16.4335 21.7112 1.42809 -16.0727 20.9185 0.9468671 -16.4107 19.9476 0.8346731 -15.7719 19.2268 0.4178701 -14.9263 19.3069 -0.1678999 -14.3415 18.5616 0.1150741 -13.605 18.304 -0.4823169 -13.8873 17.4744 -0.00738133 -13.6915 16.7923 0.6042921 -12.7731 17.0614 0.9932641 -12.2903 16.2417 0.6421881 -12.0927 15.2946 0.5951981 -12.49 15.1616 -0.3047689 -12.737 14.3118 0.05654222 -13.4308 14.308 0.7174301 -12.9143 14.2403 1.55483 -12.9107 14.0552 2.61777 -12.6939 15.0965 2.6158 -12.0773 14.467 2.07106 -11.5082 14.4411 2.93918 -11.6668 14.9643 3.75346 -11.6226 14.1867 4.39945 -10.8894 14.775 4.70646 -10.237 14.4359 5.34799 -10.218 13.5806 5.89129 -10.0359 12.7892 6.5403 -11.0033 12.4858 6.26353 -11.7166 12.2512 5.62873 -11.4339 12.4737 4.73781 -10.5895 12.9901 4.51369 -10.1087 12.3773 5.11815 -10.7193 11.8375 4.60009 -11.031 11.2296 3.843 -10.6157 10.3937 4.33302 -9.83171 9.75211 4.3179 -9.23529 10.494 3.98016 -8.55776 9.7713 3.92378 -8.73709 8.75911 4.07108 -8.01575 8.42624 4.69319 -7.1265 8.80792 4.41963 -6.90953 9.59377 5.01568 -7.57494 9.59416 5.77655 -7.94036 8.71396 6.0662 -8.05325 7.80121 6.60546 -7.13438 7.83476 6.95708 -6.63385 8.77241 6.8441 -6.27098 9.65062 7.13736 -6.13892 9.49476 6.14148 -5.99662 8.64951 5.59119 -6.84881 8.24707 5.88288 -6.16506 7.47521 5.97951 -5.53681 6.78887 6.26802 -4.76232 7.4738 6.45005 -3.98062 7.49872 6.99309 -3.31195 7.33958 7.70473 -2.51953 7.90087 7.99197 -3.26937 8.494 7.54402 -3.74833 9.36155 7.82883 -3.50817 10.3049 7.52921 -3.03606 11.247 7.3683 -2.42688 10.6312 6.88268 -2.75248 9.81497 6.3768 -2.60684 8.93079 6.8309 -2.0037 8.83472 7.64212 -1.78714 8.25119 6.87654 -0.868598 7.88535 6.68917 -1.27709 7.0139 6.99476 -1.00793 6.09727 7.34726 -1.93527 5.77782 7.57445 -2.6343 5.7293 6.80865 -3.53668 6.13661 6.78376 -4.50366 6.19913 6.4034 -4.45561 5.48432 5.66446 -3.96652 4.81407 6.17547 -4.37219 5.17733 7.02865 -4.47626 5.5977 7.91583 -5.06821 6.04476 8.60498 -5.491 6.52278 7.91347 -4.98385 7.00826 8.66891 -4.15387 7.52024 8.77767 -4.92482 8.04817 8.38084 -4.12989 8.65397 8.35699 -3.84828 9.43661 8.87552 -3.09814 8.8254 8.7384 -2.62569 9.45205 9.24425 -3.20201 9.38608 10.03 -3.1734 10.4537 9.75703 -3.98465 10.7421 9.29796 -4.6038 11.2824 9.8799 -4.12139 11.364 10.6734 -4.90659 10.7469 10.9407 -5.51135 9.98246 10.9756 -4.93442 9.77248 11.7305 -3.96954 9.55338 12.0828 -3.79898 9.29993 11.1576 -2.94973 8.9619 10.8708 -2.96023 8.20614 11.5469 -3.26781 7.26163 11.7039 -2.72268 7.05578 10.8985 -3.17516 6.28978 10.3613 -2.56804 6.62478 9.7415 -1.63236 6.61236 9.64541 -1.12226 6.56887 10.464 -0.797599 5.63455 10.403 -1.58022 4.95104 10.3403 -2.40044 5.39649 9.98301 -3.27995 4.83385 10.1986 -3.71256 5.50534 9.57017 -3.05566 4.96436 8.94244 -3.23572 5.27121 7.96491 -2.65096 4.63996 7.38074 -2.13756 3.80626 7.34608 -2.12614 3.04324 7.93941 -2.53576 2.87028 8.75503 -3.32842 3.41533 8.43991 -3.38598 3.66134 9.4431 -4.30666 3.31262 9.61981 -5.13849 3.54554 10.1357 -4.7992 4.41348 9.89789 -5.63447 4.85191 10.0789 -6.53464 4.6311 10.5021 -6.72275 4.37977 11.4288 -7.21665 5.0331 12.023 -8.11875 4.85646 11.594 -8.76973 5.43733 11.0629 -8.84879 6.22261 10.3385 -9.0282 6.9197 11.0575 -8.98307 6.39074 11.8125 -9.10851 6.21672 12.7943 -10.0203 6.64803 12.7032 -10.1379 7.13146 11.8328 -9.68193 7.91019 12.2115 -9.05234 8.53387 12.6933 -9.80147 9.00356 13.0332 -9.6778 9.0339 14.018 -9.86988 9.95808 14.2255 -10.7398 9.79937 13.9447 -11.5568 10.0001 14.5653 -11.1482 9.70825 15.4308 -10.9026 8.86274 14.9398 -11.1903 8.59917 15.9267 -10.7091 8.87605 16.6999 -11.2707 9.68064 16.7932 -12.1863 9.46684 16.9979 -11.9522 8.79867 17.6528 -12.8764 8.41306 17.5683 -13.6939 8.07634 17.9754 -14.3114 7.66873 18.6359 -15.2697 7.75782 18.9588 -15.4226 6.8317 18.5942 -15.7927 7.05579 19.4409 -15.8132 6.02053 19.1755 -15.6543 5.11758 18.6862 -16.4955 5.58254 18.5276 -16.5427 4.73557 17.9892 -16.2005 4.9327 17.0233 -16.1428 5.93273 16.7782 -16.75 6.24747 16.0114 -17.3069 6.36198 16.7632 -17.0843 7.19844 17.2178 -17.5655 7.96983 16.7573 -17.3143 8.85799 16.4044 -17.254 9.16149 17.3688 -16.9616 10.1083 17.7727 -16.7714 11.0837 17.9692 -16.1607 11.8667 18.1076 -15.3684 11.8568 18.7631 -15.9883 12.5998 18.991 -16.1234 12.8239 19.9086 -16.4647 12.8113 20.8372 -17.3061 12.4818 21.2563 -18.2083 12.454 20.9484 -19.2468 12.4562 21.1943 -19.7208 12.9756 21.9888 -20.2188 13.6788 22.5104 -20.4678 13.9971 21.6992 -19.9477 14.5595 21.0598 -20.3416 15.4935 20.9322 -19.9977 16.2078 20.364 -19.7911 16.313 21.3535 -18.9482 16.5552 20.7772 -18.1541 17.062 20.4941 -17.7495 17.3089 21.3314 -17.9593 18.101 21.9479 -18.1293 18.9222 22.481 -17.5945 19.808 22.3245 -18.0381 19.897 21.4452 -18.9293 19.4864 21.4794 -18.3059 19.3118 20.6875 -17.5189 19.4684 20.0598 -16.9257 19.501 19.2481 -16.3225 19.4035 18.4894 -16.5069 18.8443 17.687 -16.2796 17.8984 17.8835 -15.625 17.5118 17.1539 -15.5216 17.6829 16.1964 -15.3925 18.5954 15.8739 -15.0188 18.7318 16.8361 -14.3667 18.5062 16.099 -14.603 17.5967 15.7298 -13.6882 17.5014 15.492 -13.4781 17.2537 16.4252 -12.6576 17.8291 16.1227 -12.3499 17.3618 15.2685 -12.0101 16.5625 14.6911 -11.3373 15.9909 14.241 -11.186 15.0221 14.5238 -10.6156 14.2033 14.9464 -11.0084 13.3714 15.3326 -11.1171 12.5098 15.7421 -12.0899 12.6282 15.9472 -11.581 12.168 16.7489 -12.3511 11.8696 17.2488 -12.5318 12.3984 18.0429 -12.2291 12.6946 18.8684 -13.0153 13.2932 18.7989 -13.0916 13.5987 17.883 -12.8455 13.9076 16.9456 -12.0766 14.5127 17.0863 -11.8333 15.436 16.8775 -11.5649 16.0673 16.1249 -10.6416 15.9839 15.7936 -10.5534 16.6649 14.9875 -10.2334 16.4984 14.0952 -9.43961 15.9715 14.0547 -9.03355 15.8831 14.9381 -8.22201 15.4358 15.2748 -8.93338 14.954 15.7729 -8.97116 14.1353 15.2066 -9.4304 13.4775 15.7705 -8.90888 12.7052 15.5914 -8.30252 12.1169 15.1733 -7.35616 12.2006 15.4951 -6.58465 12.371 14.7728 -5.87971 11.6029 14.7993 -5.56158 10.6288 14.8947 -5.22668 11.0071 15.8069 -5.24141 9.98661 15.8459 -4.53885 9.37228 15.5816 -5.2051 9.13809 14.8058 -5.68299 9.20383 13.8818 -4.96363 8.68393 13.4792 -4.38355 7.89028 13.8245 -4.01211 7.13703 14.4879 -5.02717 7.11315 14.7406 -5.03486 6.57089 15.6559 -5.14786 5.71738 16.1433 -6.09961 6.03044 16.3463 -7.15589 6.05464 16.2717 -6.82647 6.81649 15.7113 -6.85893 7.46927 16.4647 -7.53272 7.97598 15.9967 -7.05816 7.87261 15.1254 -7.20985 8.47085 14.2821 -7.09502 9.14347 13.5156 -6.72613 8.48356 12.7501 -5.83874 8.42665 12.3118 -5.58601 8.74206 11.4499 -6.39839 9.35529 11.6589 -6.45003 10.3546 11.8319 -7.16795 11.0069 12.0758 -8.1168 11.2474 11.9593 -8.93326 10.6755 12.1198 -9.82558 11.2901 12.2002 -9.4204 11.7199 12.9774 -8.84002 10.8908 13.2842 -8.35334 10.3267 14.0109 -8.59387 10.4222 14.9361 -8.12856 9.59212 15.5564 -8.09146 9.06246 16.3807 -7.369 9.11843 17.1396 -6.72394 9.842 16.8317 -7.38222 10.2466 17.4243 -8.15515 10.3872 18.2317 -7.609 10.4469 18.9628 -7.58746 11.4051 19.1349 -8.53999 11.0589 19.3986 -8.53751 11.8972 18.8618 -8.86765 11.2472 18.2036 -9.04537 12.1824 17.9823 -9.89013 12.59 17.79 -10.7737 12.351 18.1789 -11.1201 11.6492 18.7466 -11.7487 11.2196 19.2693 -11.7661 10.2696 19.5344 -12.4996 9.66744 19.3187 -12.0537 9.77547 18.4128 -11.125 9.58933 18.2905 -10.2221 9.93494 17.891 -9.74631 10.1164 18.7655 -9.92477 11.1174 18.9535 -9.96832 12.029 19.3907 -9.48389 11.8199 20.1774 -8.57476 12.1316 20.0813 -8.51922 12.32 21.0354 -8.94754 11.6958 21.6863 -9.15156 11.786 22.6403 -8.16986 12.1177 22.7175 -7.89809 11.4373 23.3854 -8.0464 10.5132 23.2537 -7.97325 9.75229 22.4881 -8.19001 8.89031 21.9295 -9.13494 8.5262 21.8334 -10.0297 8.24878 21.9638 -10.2469 8.64931 22.8821 -9.37659 9.24143 23.101 -8.97993 8.561 23.6335 -9.05187 7.57281 23.5878 -8.14791 7.83222 23.9107 -7.4094 7.1732 24.0507 -6.45317 7.01045 24.0523 -6.10162 6.87344 24.9734 -6.58757 7.70149 25.3145 -7.4773 7.19742 25.4946 -7.12085 6.63329 26.2315 -7.4712 6.10311 26.9706 -8.42696 6.21189 27.0749 -8.48961 5.59768 26.3046 -9.38662 5.63683 25.8297 -9.12483 6.52001 25.4367 -9.37515 6.58717 26.3808 -9.57113 6.45104 27.3636 -8.87925 6.09017 28.0477 -9.13527 6.25604 28.9665 -9.45151 7.23862 28.9577 -9.65053 7.829 29.8291 -10.595 8.08736 29.6826 -10.677 8.93814 29.2567 -11.6349 9.11414 29.2177 -12.5069 8.83213 29.2888 -12.7623 8.0901 28.6803 -13.4103 8.00754 27.8694 -14.2206 7.83671 27.4408 -14.456 8.29833 26.6035 -14.7915 8.15743 25.6413 -15.8293 8.25021 25.7315 -16.8152 8.33383 25.8756 -16.4593 7.60074 25.2893 -17.3982 7.23634 25.0028 -16.8654 6.48573 25.3629 -17.1596 5.87812 26.077 -17.3661 6.01949 27.0451 -17.8031 6.48879 27.809 -17.414 5.59967 27.9816 -17.8242 4.71532 27.9694 -16.868 4.34483 28.0415 -15.8412 4.36508 27.9261 -16.0715 3.52071 27.4067 -17.0003 3.51808 27.09 -16.8018 2.6507 26.7018 -16.6122 2.72253 25.7225 -16.3459 1.72561 25.4962 -16.0574 1.65358 24.5383 -16.2094 1.18726 23.6466 -15.2165 1.54518 23.5883 -16.016 2.22306 23.5766 -16.2656 2.80695 24.3529 -16.3941 3.82275 24.4749 -17.395 3.7934 24.4429 -17.4663 4.60286 25.0086 -17.4792 5.37478 24.2957 -18.0445 4.98802 23.588 -17.6889 5.27339 22.7855 -16.7774 5.60914 22.5742 -16.3156 6.41509 22.1029 -15.6696 6.95068 22.6502 -14.8383 6.63766 23.1125 -14.4422 6.65109 22.1692 -14.0096 5.74515 22.0908 -14.7007 5.14436 22.511 -13.892 4.59396 22.5682 -13.9217 3.66508 23.0067 -14.5911 3.73498 22.333 -15.1773 2.88778 22.3476 -15.7804 3.45929 21.8987 -15.544 2.67591 21.2655 -14.5891 2.51601 21.4538 -14.8099 3.39992 21.1346 -14.0204 4.09352 21.0343 -13.4154 3.42779 20.5228 -13.5768 3.3206 19.4961 -12.7022 3.37282 18.9646 -12.129 3.80859 19.754 -11.5039 3.80211 20.545 -10.5177 3.64667 20.5645 -10.3122 4.53551 20.0988 -11.0821 4.80585 19.5938 -12.0461 5.00999 19.7545 -12.9282 5.18518 20.2402 -12.1678 5.46142 20.8857 -11.244 5.18679 20.845 -11.0927 5.59451 21.7601 -11.9424 5.47561 22.2453 -12.7584 4.85555 22.2154 -12.9189 5.47694 23.0419 -12.2022 5.75638 23.6755 -12.2494 6.7484 24.0122 -12.7527 5.91169 24.4317 -12.5469 6.04776 25.422 -12.9816 6.93404 25.513 -12.7535 7.87316 25.428 -12.0432 8.64806 25.4068 -12.4789 8.75815 26.2898 -12.297 9.60883 26.6852 -11.9193 10.5865 26.8473 -12.5767 11.0211 27.435 -13.3846 11.0468 26.7426 -14.0195 11.7814 27.1542 -13.5676 12.2683 26.4833 -13.6104 13.1202 27.0715 -13.5978 13.756 26.337 -14.098 13.6652 25.488 -13.2942 13.1782 25.1475 -14.1446 12.6096 25.1651 -14.9882 12.6501 24.7632 -15.5826 11.8557 24.993 -15.0319 10.9931 25.0832 -14.1952 11.2554 24.5913 -13.7741 11.8203 23.8935 -13.8677 12.5961 23.3038 -14.487 11.958 22.8525 -14.009 12.1503 21.9151 -13.1913 12.0692 21.3893 -12.337 11.8077 21.901 -12.3219 10.9203 22.4274 -11.4176 10.8934 22.064 -12.0967 10.7177 21.3677 -12.0724 9.67876 21.5099 -11.9971 9.19848 22.3516 -12.8148 9.71011 22.6171 -12.8217 9.00288 23.3219 -13.4273 8.7256 22.5672 -14.4067 8.55661 22.6469 -14.4981 9.38327 22.0038 -15.3802 8.82435 21.886 -15.8449 9.6161 22.1698 -16.4583 8.98237 21.6848 -17.1391 9.41266 21.0909 -17.4086 10.1934 20.5654 -18.039 10.7312 20.0625 -18.3232 9.85395 19.7043 -18.2668 9.79396 18.7341 -18.8318 8.97354 18.455 -19.2343 8.06916 18.5385 -19.0909 8.61904 19.3783 -18.9705 7.64701 19.7638 -19.5222 7.3597 20.4797 -19.0857 8.26074 20.8193 -18.3797 7.59697 20.5906 -18.4024 7.86092 21.5722 -17.4772 7.64416 21.875 -18.1031 7.82488 22.593 -18.6266 7.67745 23.4318 -19.4556 8.16978 23.6117 -19.7606 7.6273 22.8327 -20.5914 7.28695 22.3927 -21.0231 8.18287 22.4161 -21.7741 7.5324 22.3608 -22.5788 8.0147 22.7516 -23.2345 7.32933 22.4554 -23.0732 7.59519 21.4811 -22.872 8.59167 21.6301 -23.7645 8.60681 21.0869 -24.4555 8.8599 21.7555 -24.1773 8.55294 22.7151 -24.0106 9.5196 22.5149 -23.5124 10.4268 22.6033 -23.8256 10.5151 23.5158 -24.2026 10.0991 24.3368 -23.7821 10.5014 25.1331 -23.1286 11.2417 25.2881 -22.8646 12.1304 24.9832 -22.1333 11.3672 24.9137 -21.4922 10.9533 24.2037 -20.8837 11.499 24.7619 -20.9758 12.0946 23.9584 -20.068 11.839 23.6541 -19.5461 10.9213 23.5441 -19.5828 10.608 22.6493 -20.0219 9.78405 22.9331 -20.7304 10.1336 22.2888 -20.2343 10.1657 21.3704 -20.0963 10.6066 20.4646 -20.7865 10.3598 19.7267 -20.6465 11.3384 19.7834 -21.1554 11.6964 18.9409 -22.041 11.4814 18.5911 -22.1412 11.6938 17.649 -22.5117 12.5239 18.1617 -22.0768 13.2554 18.7114 -22.2944 13.9024 19.4316 -22.1322 14.4535 20.2681 -21.5315 14.13 21.0135 -22.1523 13.8908 21.7333 -21.4496 13.155 21.9829 -21.3336 12.8404 23.0148 -22.2509 12.8955 22.6433 -23.1985 12.9957 22.7062 -23.4671 13.7376 22.1221 -24.3535 14.2705 22.5377 -24.1679 14.2243 21.5137 -23.6853 14.7655 20.7878 -23.5707 15.4894 20.0898 -24.1752 14.8404 19.558 -25.1688 14.7719 19.6453 -25.9091 14.1186 19.79 -26.1756 14.7101 20.5274 -26.4611 15.2822 19.7668 -25.9608 16.2574 19.9325 -25.9955 17.2398 20.1182 -25.1035 17.6644 20.3808 -24.2423 17.1941 20.4092 -23.7836 18.093 20.1157 -24.617 18.6009 19.8733 -24.5662 18.1384 19.0541 -25.2501 18.7265 18.5122 -25.5338 18.5693 17.5808 -24.9974 18.0184 16.9055 -25.7868 18.5188 16.4714 -26.3464 18.2781 15.6333 -27.2651 18.5263 15.9035 -27.3488 17.5531 15.7293 -28.0729 16.9716 15.3887 -28.2321 16.5737 14.4459 -28.9311 15.8246 14.4899 -27.9883 15.4624 14.295 -27.8631 15.1389 13.3716 -27.7967 14.1754 13.3244 -28.2927 13.3183 13.4648 -27.597 13.2045 14.2161 -27.6843 13.9231 14.8043 -27.6693 13.8389 15.7308 -28.5107 13.3534 15.9867 -29.1415 12.7497 15.5877 -29.2829 12.0777 16.3218 -29.643 12.0472 17.2344 -30.4582 11.4762 17.0878 -30.5171 11.0142 16.182 -30.9061 11.7942 15.735 -31.5434 11.4124 15.0459 -31.6827 11.5566 14.074 -32.0381 12.3545 14.612 -32.1144 12.4546 13.6081 -31.7356 12.9726 12.888 -31.2845 13.003 12.0529 -32.1829 13.1169 11.887 -32.4745 13.69 11.1963 -32.6117 14.3796 11.9553 -31.7806 14.8741 12.2875 -30.9466 14.4826 12.0421 -30.0448 14.679 11.6203 -30.7218 14.7424 10.924 -30.6318 15.7587 10.7477 -29.8293 15.4833 10.145 -29.8937 16.2083 9.49561 -29.6214 15.5745 8.70904 -29.3426 15.5579 7.79061 -28.4281 15.3628 7.35388 -28.0886 16.1003 7.90098 -27.7108 15.4833 8.51819 -27.9589 15.1407 9.45728 -27.7753 14.4208 8.76483 -26.9919 13.8572 9.02829 -26.235 13.6961 9.73264 -25.3615 13.9616 10.1709 -25.3262 14.0501 11.1648 -24.786 13.7916 11.9375 -24.7626 14.8017 11.7839 -24.5079 15.4178 12.5428 -25.1695 15.1776 13.1945 -24.4849 14.4087 13.1682 -24.1061 14.1271 14.0861 -23.5057 13.4625 13.6537 -22.5554 13.689 13.4128 -22.4657 13.3749 12.4328 -22.9033 12.4873 12.8132 -22.9282 11.7236 13.5 -23.6789 11.1516 13.7968 -24.5005 11.0648 13.321 -23.8404 10.515 12.8319 -24.8031 10.2008 12.6798 -25.2833 10.8369 12.0532 -25.5789 11.7192 12.2712 -26.0547 11.6914 11.4636 -26.761 10.9773 11.2624 -26.6738 11.0808 12.2639 -27.1589 11.9669 12.2545 -28.0654 11.5692 12.1202 -28.0069 10.6684 12.4745 -27.7221 10.0971 11.6886 -27.2881 9.97827 12.5134 -27.0452 9.07285 12.055 -26.6665 9.20316 11.1773 -25.802 9.48018 10.8173 -25.0645 9.48338 10.2321 -24.9972 8.42864 10.2644 -25.0117 7.75715 11.0719 -25.7097 7.06637 10.7968 -25.776 7.46892 9.9335 -26.5535 8.14933 9.73523 -27.0069 8.17633 8.87412 -27.7869 7.585 9.02278 -27.9851 7.26817 9.98172 -28.3687 6.40915 10.3969 -28.598 6.23203 9.43955 -27.7752 5.63773 9.23617 -27.4015 6.08094 8.4251 -26.7117 5.60615 8.8303 -26.6316 5.21072 9.7514 -27.3464 4.64616 10.2678 -27.6676 4.36621 11.1734 -28.0981 4.4503 12.0524 -28.2838 5.29675 12.5024 -28.4826 5.85325 11.729 -28.8558 6.52358 12.3898 -29.8578 6.48325 12.4002 -29.9573 6.418 11.4378 -30.6093 5.96827 10.8221 -30.9723 5.48923 11.6814 -31.3339 5.13753 10.8228 -31.7401 4.8307 11.6634 -31.8002 4.51898 12.5284 -31.4082 3.66438 12.0931 -31.618 2.85125 11.5247 -31.4131 3.70272 10.9482 -31.106 3.60529 9.95626 -31.9102 3.32302 9.45034 -32.6225 2.74056 9.0702 -32.4429 1.80831 8.69111 -32.8304 1.52727 9.63894 -32.2509 0.7173809 9.73735 -32.2618 0.3755089 10.655 -32.4799 0.8727249 11.4647 -32.9921 1.32456 12.238 -32.7123 0.6962269 12.9227 -32.3654 -0.04575347 12.4784 -31.9311 -0.5688191 11.824 -32.4652 -0.5718451 10.9862 -32.7032 -1.22649 11.6997 -33.2921 -1.16322 12.4758 -32.5251 -1.55948 13.0232 -32.2727 -2.01543 13.8522 -31.5645 -2.50082 13.2842 -30.633 -2.63344 13.1256 -29.7153 -2.22651 12.9456 -29.3037 -3.01896 13.3582 -28.7665 -3.83535 13.7535 -28.9684 -3.13118 14.4203 -29.5225 -2.69218 15.1858 -30.0191 -1.88401 15.4541 -30.2574 -0.9183961 15.4671 -29.5799 -0.5191901 14.7901 -28.6234 -0.2231821 14.6062 -28.8819 -0.8168271 13.8588 -29.0384 -1.76169 14.183 -28.1278 -2.04136 13.7886 -27.2548 -2.15856 14.159 -27.6236 -1.42569 14.7849 -27.7361 -2.40069 15.178 -27.811 -1.88725 16.011 -27.7367 -1.28914 16.8692 -28.6775 -1.35889 17.003 -28.6251 -0.9200751 17.9543 -29.4162 -0.2614701 18.0738 -29.1151 0.7124329 18.1459 -29.8238 1.1205 18.7163 -30.7771 1.34721 18.5598 -30.591 0.6300639 17.9554 -31.0714 1.48413 17.6904 -30.8636 1.44601 16.6687 -30.5548 1.29915 15.6944 -29.8718 1.84738 15.1928 -29.6143 1.35819 14.3262 -29.0461 1.01151 13.5568 -28.5114 0.2082269 13.2592 -27.807 -0.3013751 13.8124 -27.7977 0.6368539 14.2126 -27.2785 0.5029049 15.1558 -27.0757 1.32665 14.5522 -26.8159 2.21731 15.0125 -26.0665 2.6268 14.443 -26.8088 3.17869 14.3151 -27.3168 3.78397 13.7 -27.0437 4.83091 13.7002 -26.4494 5.17594 14.3611 -25.8558 5.59864 15.1806 -25.5385 6.24294 15.8898 -24.9197 6.84144 16.4639 -24.0261 6.83301 16.0658 -24.8387 6.96379 15.4401 -25.091 7.84886 14.9146 -25.4984 8.66506 14.644 -24.9174 8.19028 14.0083 -24.9803 7.46032 13.3722 -24.9383 7.0548 12.4528 -25.1872 6.11485 12.1233 -24.6955 5.69751 12.9231 -24.974 5.10798 13.6718 -24.0912 4.84183 13.1106 -23.6736 5.66753 12.6751 -23.7903 6.66022 12.948 -23.1811 7.41961 13.0216 -22.8521 7.4029 13.9583 -22.9145 8.30941 14.357 -22.0128 8.21525 14.7906 -22.0767 8.59706 15.7661 -21.3705 8.88927 16.2644 -20.638 9.52502 16.5154 -19.9243 9.74341 15.8525 -19.9721 8.764 15.7418 -20.5039 8.31801 15.0143 -20.3204 7.46682 15.5035 -20.6502 7.29978 16.413 -20.1797 6.73823 17.0966 -19.9447 7.39575 17.8123 -20.7815 6.89556 17.8422 -20.5991 6.87648 18.8134 -20.3878 7.70939 19.2939 -20.3395 8.51042 18.6819 -21.3063 8.42672 18.6349 -22.0794 8.97078 18.3558 -22.7403 8.23112 18.2295 -22.5776 7.29831 17.8724 -21.8443 7.60736 17.2412 -22.6244 7.5743 16.6554 -22.6709 6.6474 16.2344 -21.8769 6.25624 16.6963 -21.6411 5.27534 16.4349 -21.4044 4.43869 16.7894 -20.6953 4.90482 17.1906 -19.7261 5.19132 17.0242 -19.125 4.52049 16.5856 -18.4615 4.23502 15.9183 -18.4663 3.29449 16.3488 -17.5473 3.46479 16.6625 -17.5518 2.43721 16.5451 -17.2551 1.99498 15.6895 -16.3002 2.00065 15.797 -16.0232 2.62167 16.4486 -16.7775 3.11226 15.995 -17.6517 3.14156 15.4493 -18.3489 2.42279 15.3454 -18.2752 1.83032 16.1651 -18.8708 1.45866 16.8591 -19.2578 0.5622509 17.0065 -19.1566 -0.4604981 16.6772 -19.9795 -0.7723401 16.145 -20.698 -1.43687 15.8937 -20.9733 -2.31359 16.4188 -20.4155 -2.40506 17.2711 -19.8343 -2.65031 18.0938 -19.0177 -2.09322 17.9989 -18.5928 -2.60087 18.7745 -18.7114 -2.48361 19.7239 -18.3091 -1.64334 19.4843 -18.3239 -1.08719 18.6601 -18.0202 -0.1604821 18.4309 -17.3496 -0.2581241 19.1829 -17.6878 0.6685109 19.084 -17.7321 1.58486 18.7388 -17.0236 1.7248 19.3724 -16.0115 1.63345 19.2339 -15.2573 2.15712 18.8643 -14.9131 2.75575 18.1013 -15.2803 3.66728 18.0768 -15.7718 3.2837 18.8639 -16.3993 3.31698 19.7336 -17.1839 2.98099 19.3106 -17.6599 3.48661 19.9631 -17.4067 3.26691 20.8806 -17.7646 2.82224 21.6513 -17.8814 2.12716 22.4321 -17.0173 2.1713 23.0445 -16.8144 2.83347 22.355 -16.0858 2.14421 22.3465 -16.5431 1.8218 21.6244 -16.7858 1.29133 22.4376 -16.6474 0.5232359 22.9767 -17.1979 -0.2060441 22.5871 -17.7818 -0.7755911 21.9754 -17.1633 -1.03579 21.2835 -16.9347 -1.91556 21.598 -17.6629 -2.55933 21.4431 -18.5033 -1.97609 21.4962 -19.3308 -1.4329 21.3108 -20.2602 -1.46698 21.5975 -21.0765 -1.09231 21.9634 -20.6068 -0.7352471 22.7681 -20.9554 -1.19296 23.5404 -21.1235 -1.79208 24.3595 -21.2277 -2.6375 23.8474 -21.4904 -3.51149 23.4063 -20.9532 -4.3649 23.6543 -19.9084 -4.28474 23.4854 -19.4574 -4.47401 22.5897 -18.5454 -4.07675 22.7384 -18.1012 -3.23911 23.0926 -17.2026 -2.89602 23.1774 -16.6113 -2.7612 22.4307 -16.2315 -3.03952 23.3451 -16.1863 -2.62778 24.2799 -15.6471 -1.85186 24.5237 -15.3467 -0.9407161 24.4315 -14.8039 -0.5984171 23.677 -13.9536 -1.10625 23.7479 -13.6612 -1.97233 24.0728 -12.8536 -1.30111 24.2574 -13.3289 -0.7748881 24.9697 -14.1542 -0.9713251 25.6229 -13.8667 -1.42687 26.4686 -13.1671 -0.7956861 26.4174 -12.9367 -0.4934561 27.3745 -13.6438 0.1397099 27.7149 -14.3599 -0.2063891 27.0974 -15.3496 -0.1084691 27.2634 -15.422 0.8396319 27.5963 -14.937 1.49949 27.0302 -15.3484 2.25432 26.4852 -15.0469 1.64273 25.7484 -14.5475 1.60717 24.7908 -13.6839 1.75413 24.3933 -12.7531 2.11225 24.3443 -12.0674 1.543 23.8684 -11.1555 1.8929 23.9129 -10.8903 0.9235539 24.0911 -10.5263 0.08736733 24.4069 -11.0392 -0.3241311 23.6567 -11.8945 -0.2473151 23.2749 -11.9724 0.01723833 22.3095 -12.4956 -0.8194661 22.1505 -13.3654 -0.5714861 21.7493 -13.8987 -0.08479677 20.9874 -13.992 0.2414319 20.0673 -13.5283 0.4633479 19.1494 -14.4096 0.03766453 19.0357 -14.1331 -0.7515811 19.4427 -13.3657 -1.40975 19.3156 -13.2367 -2.22755 18.746 -13.0963 -2.53942 19.689 -12.3388 -1.91823 19.6792 -12.1644 -2.84389 20.0062 -11.7658 -3.67595 20.0721 -12.5411 -4.19363 19.8568 -12.1506 -5.1891 19.8189 -12.9426 -5.45997 20.391 -12.5486 -6.3307 20.0521 -13.2952 -7.03782 19.7971 -13.0448 -7.53208 20.5997 -12.7839 -7.85449 21.5077 -12.4368 -8.77626 21.6179 -11.7645 -9.38857 21.8113 -11.466 -8.75665 22.5308 -11.2216 -7.90972 22.0624 -10.3419 -7.89423 22.5006 -9.40732 -8.1089 22.1225 -8.59823 -8.60052 21.9083 -8.13365 -8.9282 21.0817 -7.30919 -8.46582 20.8041 -6.68767 -7.82415 21.0558 -5.99098 -7.39027 20.5646 -6.14067 -8.25606 20.0501 -6.74806 -7.42881 19.9457 -7.5829 -7.65114 19.4379 -8.45775 -8.153 19.7189 -8.98295 -7.64388 20.3926 -8.17433 -7.013 20.4065 -8.09817 -7.3859 21.369 -7.49451 -6.6879 21.7915 -7.66291 -5.96774 21.0972 -6.83857 -5.40332 21.1161 -7.02275 -5.86384 20.2325 -6.4266 -6.25879 19.5523 -6.35386 -5.6544 18.782 -5.7076 -5.0502 18.9836 -6.17998 -4.30582 18.73 -7.14455 -4.39324 18.4456 -7.27459 -3.71899 17.7371 -6.9124 -3.36594 16.8486 -7.15069 -2.5768 16.2195 -7.50463 -1.66466 16.2182 -7.41679 -1.11303 15.3769 -7.68179 -0.1339621 15.32 -8.07345 0.6923019 15.7206 -7.23128 1.06244 15.4035 -7.14408 0.9192859 16.3659 -7.49396 1.80651 16.2209 -7.10564 2.44601 15.7041 -6.31987 3.06924 15.6758 -6.0303 3.10895 16.6279 -5.6705 3.94507 16.5099 -5.85497 4.88387 16.7838 -6.78068 4.99966 16.6716 -7.25452 4.15747 16.9231 -7.85243 3.45331 16.5704 -7.71253 3.39124 17.5538 -7.53709 2.61706 18.1913 -7.72496 3.00198 19.0683 -7.79887 2.02667 19.1714 -8.49208 1.4871 19.6708 -8.36159 1.55891 20.6034 -7.8145 0.7649859 20.9665 -6.8725 1.05723 21.2061 -6.20908 1.73362 21.0545 -5.8347 1.45265 21.9507 -5.43262 1.43983 22.8216 -6.08796 0.8774029 23.3744 -5.92931 0.3398649 22.5464 -5.36429 -0.2615721 23.0712 -5.17974 -1.20001 23.3508 -4.59644 -0.6913411 23.9877 -3.87627 -0.8958511 24.714 -3.57755 -0.1080181 25.1875 -3.49747 -0.8075501 25.9553 -4.21256 -1.15924 26.4847 -5.12075 -0.9898461 26.1085 -5.67654 -1.27851 26.9349 -6.23862 -1.99432 26.498 -6.73377 -2.83196 26.6388 -7.48094 -2.9473 26.0023 -7.65608 -1.98608 25.7287 -7.15773 -1.70592 24.8333 -7.62161 -1.27085 24.0622 -7.56162 -1.05121 23.1009 -6.69414 -0.5084451 23.1068 -6.35337 -1.26615 23.7342 -6.87885 -1.81663 22.9786 -6.40093 -2.44779 23.6367 -7.27132 -2.80054 23.2496 -8.02514 -3.41312 23.0356 -7.91844 -3.33761 21.9898 -8.63424 -2.86456 21.5824 -8.35811 -1.85594 21.6243 -7.59766 -1.39384 21.9681 -6.86067 -0.7537931 22.0281 -6.98259 -0.2116561 21.2268 -6.33134 -0.2871981 20.5128 -6.14301 -1.17461 20.0095 -7.20001 -1.05962 20.1519 -7.82257 -1.51866 19.5567 -8.28066 -2.21838 20.0863 -8.43099 -2.41182 19.1248 -9.06977 -1.6573 18.8504 -8.42653 -0.9714001 18.7296 -8.29426 -0.6263861 17.8424 -9.04591 -1.18407 17.3388 -9.61263 -1.20103 16.5206 -10.2753 -1.74154 16.0431 -10.4605 -2.57315 15.5817 -10.6931 -2.61225 16.5945 -9.77276 -2.61722 16.8742 -9.10664 -2.7243 16.1046 -9.08032 -3.52346 15.5337 -10.0451 -3.53114 15.8101 -10.5006 -4.47284 15.6442 -11.5081 -4.37182 15.887 -12.4714 -4.39639 15.7311 -13.013 -5.12665 15.2674 -13.9798 -4.78876 15.3651 -14.403 -5.4444 14.795 -14.24 -6.33479 14.3745 -13.3503 -6.00027 14.0778 -12.5142 -6.21892 14.5734 -11.8196 -6.24665 13.8257 -11.2182 -5.42189 14.103 -12.0959 -4.90054 14.4805 -12.4556 -4.21033 13.8387 -12.8554 -3.59554 13.1401 -12.4454 -4.10371 12.3643 -13.1547 -4.84287 12.5148 -13.8816 -5.49229 12.3638 -13.7241 -6.07333 11.5293 -14.2476 -6.79981 11.8653 -14.4677 -6.7284 12.856 -15.2978 -6.18664 13.1503 -14.8716 -5.27943 13.2733 -15.6174 -4.75357 13.6401 -16.2855 -4.69335 14.3652 -17.1399 -4.69725 13.7677 -18.0438 -4.37945 13.4832 -18.3097 -3.46467 13.8175 -17.6995 -3.13498 13.033 -17.5517 -2.60528 12.2349 -17.0227 -2.04485 11.6376 -17.3595 -1.39337 12.2906 -17.4574 -0.9459261 13.2247 -17.2028 -0.2270731 13.7886 -18.1047 -0.02609297 13.8543 -18.0745 0.02807103 12.8388 -17.5375 0.8129909 13.0154 -17.0034 1.46102 12.4577 -17.5091 2.20978 12.6914 -18.3821 2.57186 12.9633 -18.771 3.50686 13.2122 -17.8124 3.28661 13.5138 -17.8486 4.04853 14.1294 -16.8641 3.67118 13.8566 -16.2959 2.89223 13.4863 -15.7312 2.11705 13.8899 -14.9192 1.56163 13.9391 -15.0185 1.60425 12.9152 -15.0377 2.57532 12.594 -14.6755 2.70387 13.5171 -14.8917 2.76236 14.5173 -15.3862 3.64289 14.4759 -14.7822 4.19256 15.0068 -15.5881 4.80314 14.9911 -15.7974 5.44588 14.2167 -16.7475 5.5232 14.3016 -16.4874 6.12691 13.5056 -15.9885 6.77293 14.1419 -15.4059 6.75193 15.0102 -15.6756 7.71903 15.178 -15.4205 8.77725 15.0957 -16.1157 9.34749 14.6923 -15.6766 10.2323 14.3901 -16.4707 10.5344 13.7578 -16.3756 10.8009 14.7074 -15.9146 10.2444 15.3422 -15.5017 9.91119 16.1619 -14.5155 10.0219 15.9511 -13.7206 10.6986 15.7391 -13.8223 11.2264 16.6386 -14.0267 10.7513 17.5639 -14.625 11.5151 17.7013 -15.3403 12.1559 17.3043 -15.4529 13.073 16.8109 -15.5177 14.0727 16.7895 -16.5148 14.2177 17.1818 -16.0147 14.7441 17.8609 -16.139 15.5013 17.1051 -17.0689 15.7844 16.9837 -17.635 15.2034 17.6882 -18.4948 14.7407 17.4406 -18.8038 15.5021 16.8261 -18.757 15.0965 15.8578 -17.932 14.6551 15.5306 -17.6963 14.0688 14.7946 -17.9455 14.5387 13.9951 -17.9487 15.3255 13.4463 -17.8977 14.6258 12.733 -17.2275 14.1348 12.1206 -16.3371 14.5395 12.3725 -15.4296 14.8042 11.9226 -15.2533 13.982 12.502 -15.5794 13.309 13.1093 -14.5621 13.286 13.1529 -13.7999 12.8733 13.6859 -13.049 12.2501 13.7089 -13.7589 11.5623 13.544 -13.5874 11.9255 12.6375 -13.2762 11.0123 12.3992 -12.6149 11.6658 11.8082 -12.2432 10.7019 12.0759 -11.7083 10.9276 12.8226 -10.8924 11.2952 13.3041 -11.6 11.9095 13.6206 -11.6443 11.0788 14.2031 -10.9854 11.5259 14.7483 -11.0994 12.5012 14.5121 -11.9514 12.9509 14.261 -12.8162 13.4847 14.0428 -12.6957 13.3024 14.9871 -13.6854 13.0686 15.1369 -14.4244 13.3913 14.6769 -15.3142 13.8409 14.7357 -15.4861 14.5841 15.3272 -16.475 14.7416 15.2022 -16.4649 15.1616 16.1065 -16.2243 15.9974 15.6129 -15.3923 15.9487 15.1028 -14.483 15.5423 15.2387 -13.6661 15.5892 14.671 -14.0927 15.2353 13.9017 -13.6469 15.9604 13.3155 -12.9747 16.3915 12.7649 -12.8224 16.1547 11.8153 -12.8219 16.0218 10.815 -13.7252 16.1217 10.4299 -14.6619 16.5295 10.3567 -14.3581 17.463 10.2058 -13.8325 17.2023 11.0875 -14.4991 17.1258 11.8406 -15.2866 16.8565 11.295 -15.2864 15.9323 11.7371 -16.2452 16.3894 11.8105 -16.9695 17.022 12.0102 -16.1996 17.5726 12.2531 -16.1809 17.1405 13.1952 -16.4545 18.0939 13.438 -16.03 18.5861 12.7095 -16.6017 19.0399 12.1635 -16.7842 19.332 11.2239 -16.3131 18.8931 10.4369 -16.8223 18.2996 9.88084 -17.4382 18.4968 9.1722 -17.3506 19.4998 9.00489 -18.2344 19.8665 8.88494 -18.4288 19.6 9.80912 -19.1668 20.2736 9.89006 -19.3947 19.3696 10.3923 -19.0261 18.5265 10.7461 -19.3562 17.8099 10.1494 -18.7329 17.0313 10.1668 -18.5336 16.5454 11.0287 -18.8476 16.1584 11.8839 -18.9873 15.3766 12.4033 -19.9303 15.3134 12.8511 -20.1622 15.7924 13.7522 -20.3819 16.764 13.5707 -20.3135 17.7435 13.2203 -21.1554 17.3668 12.7187 -21.4773 16.8031 13.4755 -21.1308 17.2848 14.3137 -21.0082 17.6015 15.2691 -21.9898 17.6738 15.4 -22.6724 18.2169 14.9811 -23.0393 18.6042 15.9023 -22.2954 19.1662 16.2065 -21.3295 19.4301 15.986 -21.4754 20.3446 16.2555 -22.2826 20.9876 16.2465 -22.9901 21.6448 16.1999 -22.4186 22.409 16.3807 -22.3111 22.2065 17.3643 -21.3078 22.0635 17.3979 -20.7168 22.2917 16.5955 -20.0757 23.1393 16.5682 -20.6021 23.3766 15.6682 -21.2907 23.2212 15.0526 -21.4527 23.0494 14.0534 -21.2031 22.7479 13.114 -20.8891 22.0665 12.4673 -21.003 22.3934 11.4438 -21.9296 22.0218 11.271 -21.7755 22.8674 10.7622 -22.1979 23.6565 10.1577 -21.6368 23.132 9.56656 -21.6017 22.158 9.25279 -20.8751 21.5889 9.0248 -20.6723 21.1861 9.8886 -21.5199 20.8774 10.2643 -22.4274 20.5671 10.5172 -22.2045 19.8366 9.86317 -21.5171 20.2226 9.25974 -21.0336 19.5326 8.75793 -22.0063 19.4362 8.65897 -22.3621 18.901 7.87705 -22.5344 18.2411 7.1336 -22.4731 18.5512 6.20765 -23.0626 19.3795 6.4161 -23.8881 19.2019 5.93872 -24.5048 19.8065 6.50232 -23.8287 20.5659 6.71579 -24.6918 21.0254 6.81089 -24.9741 20.6742 7.69016 -24.6022 20.5034 8.58948 -25.4179 20.1546 9.04365 -25.3062 20.9639 9.69263 -24.8888 21.6591 10.192 -25.2749 21.1434 10.8889 -24.6428 20.4454 10.651 -23.8079 20.0391 10.4152 -24.0629 19.1429 9.98533 -23.9332 18.2254 10.4221 -23.1442 17.7659 9.9879 -22.3307 18.2146 10.2991 -22.987 19.0578 10.4323 -23.1028 18.385 11.1968 -22.2211 18.0042 11.5863 -21.9669 17.0815 11.2047 -21.1516 16.6669 10.8193 -20.4243 17.0261 10.1483 -20.8685 16.3287 9.59375 -20.6551 15.7767 8.78041 -21.0277 14.9284 9.12023 -20.2903 14.3195 9.37903 -20.3929 13.4785 8.88384 -20.7175 13.6374 7.98118 -20.1244 14.0164 7.29026 -19.559 13.5743 6.5547 -18.6524 14.1218 6.44803 -18.9867 14.8943 6.07582 -19.5157 15.8305 6.2228 -19.6263 15.8903 7.22584 -18.6753 16.0159 7.57949 -18.0633 16.0041 6.76496 -17.6519 16.4867 7.52317 -16.9538 15.731 7.30002 -17.4945 15.2585 8.00492 -18.3597 14.7803 8.04276 -17.7633 14.0963 8.53011 -17.5685 13.899 9.58825 -16.7208 13.3519 9.4178 -16.4625 14.3063 9.69108 -15.4673 14.3528 9.83254 -15.2014 13.8555 9.07364 -15.6845 13.8458 8.24886 -15.0611 14.1806 7.51169 -14.7588 14.9564 6.84024 -15.1624 15.7187 7.2821 -14.7554 16.4364 7.79303 -15.2197 17.081 7.15181 -15.4646 17.7063 6.57195 -15.3149 17.919 5.56208 -15.8698 18.6208 5.02944 -16.6744 18.0684 5.1697 -16.8531 19.0408 5.46118 -16.8749 19.9881 5.24392 -15.9892 19.7413 4.98988 -15.5017 20.105 5.77774 -16.2219 19.89 6.41284 -17.1742 19.6734 6.76123 -17.7305 18.8552 6.45816 -18.2116 19.0144 5.64258 -19.0091 18.4102 5.89256 -19.8839 18.5958 5.36507 -19.5244 19.2023 4.74854 -18.6165 18.8041 4.6644 -17.792 19.2578 4.31094 -17.3845 18.3862 4.53743 -18.2219 17.8254 4.70771 -17.5434 17.1645 4.32621 -17.5012 17.0215 5.38492 -16.5634 16.6562 5.33521 -15.6053 16.3395 5.58528 -15.6139 15.3633 5.18566 -15.398 14.442 5.45997 -15.5885 13.8729 4.66391 -16.2434 14.5676 4.27351 -15.3225 14.8393 4.0477 -14.4797 14.3061 4.14991 -14.1845 14.3993 5.11096 -13.6612 15.1935 4.72451 -13.5612 15.9442 4.15077 -14.0864 16.8226 4.12674 -14.6926 16.2967 4.69114 -14.2026 15.9611 5.50192 -14.0166 16.9146 5.44214 -13.9642 17.3213 6.31458 -13.0882 17.8092 6.18386 -13.7892 18.1904 5.50203 -13.0982 17.9219 4.92647 -13.3268 18.6126 4.16664 -12.3689 18.4193 3.88847 -12.6196 18.9107 3.05041 -12.5906 19.4076 2.10114 -12.0424 19.429 1.18129 -11.871 18.4713 1.32918 -12.4666 17.9943 2.05333 -12.0161 17.2156 2.57535 -11.3012 17.8107 2.2617 -10.4496 18.3013 2.35885 -10.3776 17.4481 2.88904 -10.9705 17.0402 3.58335 -11.5962 16.2452 3.489 -11.483 16.2669 4.45819 -11.931 15.6555 5.06229 -12.6526 14.9789 5.33079 -12.0799 15.1275 6.14705 -12.1439 14.1916 6.13907 -12.522 14.667 6.96599 -12.8841 14.5011 7.927 -12.6994 13.5457 7.80812 -12.3322 13.8284 8.68457 -12.7426 13.8183 9.59573 -12.0214 13.2756 10.0035 -11.2505 12.9329 9.55791 -10.8086 12.5733 10.3719 -10.7954 11.8271 11.1073 -11.0625 11.2346 10.3972 -11.2731 11.0786 9.47815 -12.1008 11.41 9.99709 -12.4027 12.1603 9.4229 -13.2517 11.7994 9.7734 -13.5428 12.6247 10.3084 -14.2323 12.0228 10.6596 -15.1582 11.7366 10.9492 -15.5228 11.3262 10.0169 -15.4211 10.3585 10.2133 -15.8885 10.0942 11.0542 -16.5886 10.5255 10.4911 -17.0373 10.0073 9.77018 -17.4404 10.6927 9.1359 -17.8692 9.8623 9.28847 -18.5763 10.2292 8.76274 -18.6042 10.1983 7.73707 -19.0461 11.0258 7.50965 -18.5637 11.905 7.30521 -17.907 11.5724 6.6345 -17.3787 12.4894 6.60868 -16.8263 12.809 5.78249 -15.9046 12.7628 5.96922 -15.5444 12.4975 6.90489 -15.7477 12.4495 7.91157 -14.8843 11.9721 8.21424 -15.3649 11.0636 7.92001 -14.5537 11.0266 8.38458 -13.911 10.3602 7.98426 -14.5215 10.3482 7.20926 -14.2855 10.7313 6.29749 -15.2111 10.3873 5.87935 -14.3701 9.97972 5.50932 -15.1289 9.27891 5.54982 -14.7949 9.18553 4.56881 -13.8455 9.05529 4.24786 -13.4861 9.93024 4.05556 -14.2074 10.5553 4.26958 -15.1695 10.8274 4.12061 -15.7573 10.9734 3.29737 -16.2898 10.3924 2.77087 -16.5215 11.4172 2.58414 -16.8779 12.3559 2.61478 -17.8423 12.3099 2.86551 -18.2308 11.5421 3.3763 -18.7711 11.2786 2.59253 -18.5241 10.5567 3.1778 -17.6402 10.1675 3.29857 -17.9899 9.6455 2.53635 -17.1171 9.31009 2.84637 -17.5084 8.67863 2.14551 -16.7521 8.11107 2.39058 -15.9163 7.8293 1.93882 -16.3946 7.1862 2.62267 -17.3404 6.97117 2.55458 -18.1118 7.4214 2.35014 -18.213 7.12739 3.32134 -17.8082 7.05824 4.17018 -17.0476 7.6385 4.07316 -16.1004 7.79027 4.09454 -15.1658 7.57064 4.13954 -14.506 8.23468 3.86142 -14.296 8.08077 4.81747 -14.5486 8.17906 5.81883 -14.9319 7.25425 5.82935 -15.4664 6.34456 6.02844 -16.1125 5.88293 5.49722 -16.3847 5.58273 4.57015 -15.5125 5.7189 4.13072 -15.7803 6.57176 3.80818 -16.0304 5.86663 3.09623 -16.354 5.36411 2.28634 -15.3338 5.20565 1.96928 -14.8448 6.07287 1.91484 -15.8129 6.33367 1.89842 -16.0444 5.79509 1.08776 -17.0472 5.62599 1.07818 -17.8956 6.01745 0.8630721 -18.6324 5.51386 0.3138321 -17.9136 5.47825 -0.4158689 -18.0723 6.43149 -0.7665279 -18.3554 7.24387 -0.2624609 -17.6132 6.80119 0.1294671 -17.2129 7.69613 0.1396261 -18.0252 8.2951 -0.07826198 -18.6186 8.4138 -0.8051169 -19.5116 8.19277 -0.7060639 -20.4521 8.05294 -0.6483929 -20.0597 7.84971 0.2284561 -19.8416 8.38334 1.05878 -19.2819 8.84825 1.68716 -19.5661 7.89978 1.9004 -19.7917 8.0439 2.86043 -19.6482 9.01398 3.21442 -18.8607 9.14185 3.85663 -18.1944 9.91212 3.94876 -19.0777 10.4014 4.05709 -19.1788 10.731 4.92496 -19.3436 11.51 4.25781 -19.7737 12.4187 4.55798 -19.3215 13.2369 4.95826 -19.8843 13.9997 4.6652 -20.7075 13.9872 4.08675 -20.8062 13.1298 4.51002 -21.5029 12.6408 3.94192 -22.4732 12.8027 4.00894 -22.7031 11.8094 4.18152 -23.5138 12.4212 4.28765 -23.2241 12.3101 5.23429 -23.9429 12.8917 5.61721 -24.5684 13.5807 6.07552 -24.3402 13.1322 6.92012 -23.4316 13.278 6.63948 -22.7182 13.4074 5.85343 -21.8295 13.4832 6.25584 -22.0436 12.6821 5.69023 -22.5927 12.5155 6.50435 -22.7927 12.2074 7.37066 -22.1695 12.546 8.1813 -22.2538 12.8024 9.17371 -21.9004 12.7497 10.0471 -22.3044 11.8989 10.3188 -22.8594 12.3801 11.0917 -22.0699 12.8487 11.156 -21.2527 13.0431 11.6782 -21.1154 13.9304 11.3386 -20.5372 14.0182 12.0985 -19.7068 14.5643 11.9648 -19.7369 15.3716 11.3794 -20.0015 14.5355 10.9069 -19.2966 13.8711 10.5771 -18.4842 14.2468 10.2931 -18.7478 14.2065 11.2661 -18.2032 13.4789 11.8513 -18.6599 13.0624 11.0545 -18.7346 12.57 11.9273 -18.0278 12.0408 12.43 -17.976 12.0392 13.4603 -18.0319 11.445 14.2467 -17.2463 12.049 14.4018 -17.5361 12.1362 15.3963 -17.8653 13.0733 15.4419 -18.5203 12.9425 16.2555 -18.4918 13.3793 17.2141 -19.3637 13.0471 17.4561 -19.9321 13.3232 18.2378 -20.8556 13.5538 18.1943 -20.6015 14.4633 18.4028 -19.6153 14.3467 18.5049 -19.8316 15.245 18.0828 -20.2601 15.7254 18.8136 -20.7808 15.2805 19.526 -21.4825 15.7305 18.9925 -22.2619 15.6653 18.3682 -22.5808 15.2287 17.5642 -21.7484 15.3141 16.9717 -22.273 16.1162 16.8026 -23.0704 16.0782 16.0775 -22.4949 15.6717 15.4303 -23.286 15.0081 15.1313 -23.1355 14.1893 14.5591 -22.256 14.5035 14.1009 -22.0556 15.5063 14.0068 -21.2226 15.0407 14.4041 -21.1227 14.0404 14.4003 -20.3752 14.5059 13.9666 -19.7695 14.755 14.7241 -19.8731 13.9544 15.2835 -19.5242 13.3947 14.672 -19.5863 12.5474 14.0739 -19.7546 11.698 13.6058 -18.969 11.3841 13.0597 -18.6996 10.6514 12.5387 -18.8622 9.67551 12.6989 -18.038 9.24133 12.5955 -18.6392 9.31473 11.7716 -18.6868 8.46287 11.227 -19.2948 8.16612 10.4259 -19.8464 7.77481 11.2132 -20.4819 7.67456 11.9589 -21.0561 7.19721 11.3141 -21.9664 7.0753 11.6683 -22.179 6.0818 11.5034 -21.4304 5.54067 11.1646 -20.7783 5.12166 10.5904 -20.398 4.24892 10.7955 -20.2335 4.10001 11.8253 -20.9272 4.39452 12.4451 -20.7076 5.33998 12.6506 -20.6335 5.06659 13.662 -19.8085 5.32309 14.1373 -19.9625 6.305 14.1019 -20.0946 7.27177 14.1489 -19.624 7.85267 13.4829 -19.6556 8.35495 14.3325 -19.18 7.49653 14.5767 -18.6673 7.35947 13.7655 -18.4031 6.40598 13.9952 -18.3237 6.61867 12.9918 -17.7766 5.70658 13.1411 -17.3905 5.85388 12.216 -17.1913 5.06922 11.6532 -16.9757 4.41974 10.9733 -17.8524 4.83796 10.897 -18.195 5.13896 11.7722 -18.2499 4.35244 12.3649 -18.7167 3.46935 12.1607 -18.2112 2.78193 11.4775 -18.8905 3.27675 10.988 -19.5001 3.19169 10.2264 -19.6799 3.37713 9.28296 -19.2264 3.02744 8.50412 -19.7514 2.41417 7.92111 -20.7727 2.60482 8.03476 -20.8462 2.56871 9.0693 -21.298 1.99271 9.77649 -20.4385 1.60842 9.39709 -21.2976 1.05709 9.21538 -21.0839 1.61691 8.47806 -21.5415 1.86407 7.57895 -22.26 1.27953 7.13544 -23.0025 1.8977 6.8 -22.8722 2.90277 6.94745 -22.5839 3.04646 7.84231 -22.8303 2.43921 8.67593 -22.8686 3.1503 9.40583 -22.1538 3.18751 10.1222 -22.2623 2.37394 10.6621 -21.9513 1.63877 11.2347 -21.3278 1.17209 10.701 -20.6982 0.6090099 11.1874 -20.3548 -0.3121531 10.8289 -20.9036 -0.4925011 9.90508 -20.9484 -0.3618771 8.94589 -21.0168 -1.21154 8.47818 -20.6711 -1.72528 9.27859 -20.4593 -2.68599 8.93689 -21.067 -2.17667 8.30623 -21.5186 -2.98181 8.20403 -22.4589 -2.78401 8.20534 -22.5358 -3.75406 8.29585 -23.364 -3.93231 7.6576 -24.191 -4.4657 7.44335 -24.8769 -3.92756 7.00437 -25.8787 -3.96985 6.93134 -25.7531 -3.29658 7.62221 -25.708 -2.77686 8.4424 -24.8569 -3.02408 8.9801 -25.2622 -3.94354 8.5561 -26.216 -4.24368 8.25607 -26.8575 -4.52807 8.89948 -27.7534 -4.66557 9.30924 -28.1603 -4.84839 10.168 -28.3655 -5.8327 10.0357 -28.7972 -5.90485 9.10794 -29.6565 -6.04956 8.6125 -29.0442 -6.73112 8.2771 -28.7084 -7.35311 9.0786 -27.8271 -7.71089 9.52029 -27.5205 -8.65644 9.4751 -27.9472 -8.93506 10.3241 -28.0913 -9.17991 11.3133 -27.1198 -9.32855 11.1122 -26.6809 -8.76551 11.7431 -26.9527 -8.07701 12.3728 -26.8916 -9.02596 12.8262 -26.0044 -9.44484 13.1125 -25.0083 -9.31367 13.0042 -25.0107 -9.83203 13.8678 -24.2459 -9.37602 14.3134 -23.9267 -10.0762 14.9168 -23.3046 -9.44817 15.3878 -23.9309 -8.65907 15.18 -24.7695 -8.55344 15.8514 -25.736 -8.79718 15.7891 -26.3092 -8.52656 15.049 -26.9609 -9.29796 15.153 -26.2762 -9.90922 15.5983 -26.5549 -10.7917 15.9141 -27.056 -11.2009 16.6682 -26.6309 -10.7269 17.4577 -27.1803 -11.3507 18.1629 -28.0937 -11.2992 18.3899 -28.4096 -10.3546 18.5428 -27.593 -9.73103 18.7169 -26.6303 -10.074 18.6181 -26.0576 -9.31439 18.7435 -25.1427 -9.60854 18.4491 -24.3498 -9.19665 18.824 -24.7083 -9.28456 19.7586 -23.7524 -8.99751 19.757 -23.0134 -9.29806 19.2283 -23.1569 -10.0777 18.6791 -22.5737 -10.4684 19.3813 -21.6931 -10.7288 18.9969 -21.6321 -10.5786 19.9505 -21.9458 -9.66164 20.1215 -20.8998 -9.48542 20.1672 -19.8548 -9.46035 19.8426 -19.1501 -8.79308 19.421 -18.7747 -9.62441 19.8162 -18.1871 -8.9833 20.2435 -18.0983 -7.97738 20.4616 -17.1559 -8.31898 20.6368 -16.3774 -7.97736 20.0721 -16.7115 -7.22429 19.3644 -16.7216 -7.50962 18.3581 -16.9351 -8.34218 18.7308 -17.9254 -8.32598 18.4371 -17.942 -7.33284 18.5897 -18.6277 -6.8125 19.0329 -18.9402 -7.31024 18.2833 -19.7965 -7.466 18.7433 -20.6677 -6.97225 18.4948 -21.4644 -7.30109 18.0263 -22.4525 -7.1368 18.0099 -22.735 -7.6898 18.7856 -23.4882 -7.05732 18.4721 -24.2051 -6.39175 18.8165 -23.6709 -5.83635 19.3963 -24.2576 -5.27224 18.911 -24.5146 -4.43242 18.4615 -25.0901 -4.36481 19.2324 -25.8861 -4.18578 19.7217 -26.756 -4.77062 19.8302 -26.5762 -4.59339 18.9026 -26.321 -3.65699 18.5097 -25.4675 -3.9851 18.1081 -26.003 -4.25226 17.2657 -25.914 -3.40622 16.7261 -25.3386 -2.74685 17.0598 -24.5083 -2.59869 17.628 -24.353 -1.6507 17.7183 -24.5477 -1.25116 16.8366 -24.2624 -0.3554061 17.0724 -24.6049 0.5765039 16.8174 -23.7579 1.18778 16.7854 -22.7308 1.04334 16.7444 -22.3534 0.5301389 17.4521 -22.2394 -0.3968491 17.3389 -21.2361 -0.3002691 17.3099 -21.0356 0.1000309 18.1664 -20.8863 1.09116 18.541 -20.1489 1.6226 18.1068 -20.8444 2.26317 18.3809 -21.8476 2.41441 18.5968 -22.8307 2.35382 18.9504 -23.4938 2.18501 18.2916 -24.0694 2.98942 18.5142 -23.7847 3.87563 18.0593 -24.1429 3.68633 17.1686 -23.3563 3.90903 16.6623 -23.9225 3.61649 15.9081 -23.6866 2.71283 15.6802 -23.9915 2.20917 14.8684 -24.2533 1.25463 14.6507 -24.2083 0.2856159 14.1855 -24.6972 -0.2828801 13.5044 -25.3323 -0.9143561 13.0177 -24.4435 -0.9556241 12.6494 -23.8093 -0.3761921 12.0588 -23.129 -0.09480627 12.7254 -22.3448 -0.03636327 12.2134 -21.8372 0.5727999 12.8023 -21.1964 -0.04394527 13.2661 -20.4183 0.5832549 13.5615 -19.7406 -0.1338651 13.7141 -19.9241 -0.4323101 14.6629 -20.4225 0.4351609 14.5612 -20.7314 0.5690049 15.5011 -20.6412 1.47518 15.93 -19.8008 1.98473 16.1373 -20.12 2.722 15.4771 -20.8411 2.67032 14.8827 -21.1521 2.62051 13.9107 -22.1759 2.75629 13.7956 -22.5263 3.72773 13.7558 -22.3387 4.57346 13.2673 -22.4909 4.81634 12.3019 -22.6659 4.19512 11.4962 -22.8384 3.48662 12.1904 -23.2497 2.58777 11.9972 -24.106 2.28111 12.3236 -24.4148 3.13376 12.7295 -24.6359 3.35353 13.7121 -25.3989 2.83401 13.281 -26.0857 2.99295 12.596 -26.0085 3.71373 11.9288 -26.0111 3.59452 10.9443 -25.4977 4.36156 10.5891 -24.7839 4.61631 11.2226 -24.4542 5.34458 10.5669 -24.5491 6.31787 10.2846 -24.6429 7.15676 9.71315 -24.1171 6.99247 8.87375 -24.5135 6.08176 9.1085 -24.1089 5.24644 8.63671 -24.126 5.01816 9.55213 -23.1783 4.65669 9.32927 -23.2772 4.37954 8.37432 -22.4755 4.69568 7.90092 -21.5543 4.26141 8.14256 -21.357 5.17534 7.67798 -21.9556 4.61231 7.11575 -21.5202 5.21756 6.4731 -21.1163 5.72286 5.65908 -20.7901 4.72159 5.52383 -20.0561 5.27122 5.96658 -19.5905 4.36422 5.98738 -18.8925 3.84776 6.55668 -18.9182 3.5126 7.50986 -18.6683 2.66586 7.0389 -18.4012 1.72606 6.83764 -19.2921 1.38547 7.10959 -18.6182 0.6295859 7.37568 -17.7381 0.3282519 7.53544 -16.9553 0.7679439 7.8646 -16.491 -0.1432011 7.92852 -16.529 0.03088953 6.88224 -17.1485 -0.6717561 6.4172 -16.2144 -0.4994131 6.10366 -16.4191 -0.9401671 5.27855 -16.7548 0.05541173 5.14545 -17.2969 0.6542919 5.78616 -16.6702 1.31775 6.06899 -16.7346 2.20423 5.71487 -17.118 2.84101 5.11831 -17.982 2.48739 5.07126 -18.168 1.68814 4.48709 -18.5423 2.17525 3.66616 -18.084 1.32794 3.38319 -18.0979 1.94762 2.6148 -17.4737 2.69719 2.92886 -17.0152 2.81961 3.79571 -17.5337 3.62875 3.63002 -16.8636 3.99115 2.94544 -16.2617 4.0202 3.7301 -15.9384 4.2905 4.70389 -16.5576 3.74767 5.176 -16.0472 3.0774 4.61321 -15.2447 3.34009 5.1408 -14.5646 3.18019 4.35178 -14.3574 3.87379 3.6505 -15.2052 4.34879 3.59691 -15.5249 3.5713 3.042 -15.1947 2.8446 2.49848 -15.181 3.61409 1.79882 -16.1282 3.80306 1.58571 -17.0061 3.87741 1.11396 -17.8004 4.30974 0.8464351 -18.0316 3.92305 -0.04146558 -17.5464 4.30734 -0.7790049 -17.6257 4.84049 -1.61252 -18.4279 4.68408 -1.02274 -18.8666 4.01016 -1.66149 -18.5236 4.4945 -2.36173 -17.9874 4.10445 -3.12617 -17.1884 4.55622 -3.41212 -17.1921 3.62219 -3.7827 -17.8373 3.14204 -4.45023 -18.6435 2.78035 -3.90193 -18.3533 2.59882 -2.99558 -18.2102 2.24571 -2.05646 -18.5831 1.39776 -1.58487 -18.6608 0.7311069 -2.22397 -19.5718 0.2995869 -2.03733 -19.7881 -0.5598691 -1.59136 -18.7718 -0.4852421 -1.63809 -18.2818 -1.29094 -1.24784 -18.5468 -2.03073 -1.83792 -17.6713 -1.65228 -1.9469 -16.9077 -1.4301 -2.57807 -16.1369 -1.66781 -3.09849 -15.8229 -0.8544261 -2.70826 -15.6489 -0.1632041 -1.96239 -14.8938 -0.2436231 -2.63166 -14.6191 -0.9791421 -3.24923 -14.0702 -0.6992321 -4.04612 -13.1882 -1.13551 -3.70727 -13.6023 -2.00409 -3.5806 -13.8631 -2.86247 -3.21928 -13.8704 -3.29267 -4.08488 -13.9131 -3.7108 -5.0374 -14.7521 -3.96765 -4.52881 -14.4687 -4.52005 -3.80194 -14.4677 -5.04383 -2.95204 -14.9267 -5.02814 -2.11171 -14.4403 -5.24038 -1.26444 -13.8341 -4.8443 -1.96436 -13.6093 -4.32059 -1.10751 -13.0657 -3.80346 -0.4171149 -12.4482 -3.58222 0.4058601 -11.6861 -3.83456 -0.1792279 -10.8145 -3.66754 0.2613781 -10.7913 -2.9544 0.9450551 -10.546 -2.00278 0.7589961 -9.92685 -2.1163 1.52118 -9.66215 -2.64755 0.6709331 -9.62183 -3.32867 -0.03365398 -8.94502 -3.86919 -0.4797269 -9.56917 -4.70117 -0.4249999 -10.0272 -4.64316 0.4623261 -10.1314 -4.44678 1.43843 -10.2863 -4.99697 2.26067 -9.61917 -5.69568 1.88521 -9.17893 -6.41581 1.30033 -8.52127 -5.65002 1.17264 -8.40721 -5.22422 2.12406 -7.72496 -4.48015 2.41244 -7.00819 -3.96508 2.72308 -6.4615 -3.38729 3.25413 -5.82997 -3.50201 4.01959 -5.2882 -4.18131 3.56289 -5.63704 -5.08939 3.59089 -6.60332 -5.07577 3.9497 -7.41771 -5.24707 3.44874 -7.09469 -6.06525 3.85836 -6.62923 -6.27142 2.91488 -7.45626 -6.65178 2.40383 -8.38859 -7.01954 2.8063 -9.37172 -6.77611 3.01545 -9.92293 -7.47324 2.63004 -10.5214 -8.28603 2.74904 -9.95689 -9.15912 2.79169 -9.35864 -8.38444 2.86694 -9.52663 -8.95596 3.6463 -9.76081 -8.13024 4.20131 -10.2249 -7.40606 4.61032 -10.9593 -7.29482 5.20935 -11.784 -7.81429 4.90053 -12.5144 -8.25436 4.3606 -12.3263 -8.25922 3.30985 -12.1841 -9.21251 3.60666 -12.1552 -9.67441 4.40139 -11.8877 -10.5227 4.80527 -10.9798 -10.0659 4.95835 -11.0864 -9.4642 5.7241 -11.0005 -8.90728 6.61091 -11.2028 -9.38213 7.44696 -11.4668 -10.3909 7.56265 -12.3829 -10.1545 7.78831 -13.3312 -10.0689 7.45692 -12.6401 -9.53514 6.94785 -12.5548 -8.58918 7.17798 -13.1472 -8.12698 7.81624 -13.1834 -8.75206 8.54831 -14.1576 -8.84908 8.58651 -14.0259 -8.63429 9.56395 -14.3016 -8.59096 10.5417 -14.1278 -8.24814 11.4399 -14.885 -8.84095 11.2531 -15.3957 -8.37564 11.9097 -15.2077 -7.416 11.8338 -15.5989 -6.47061 12.0808 -15.3447 -5.53915 12.0954 -16.1733 -5.10501 12.3195 -16.9419 -5.53537 11.8248 -16.9264 -5.3013 10.8234 -17.5556 -5.80347 10.2906 -18.4449 -5.63805 9.92614 -19.4134 -5.82195 9.91739 -19.3208 -5.74234 8.94243 -18.4716 -5.45484 8.39406 -17.5989 -5.11587 8.03072 -17.7781 -6.08958 8.19957 -17.6953 -6.54515 7.35146 -17.252 -7.27269 7.99022 -17.9202 -8.00877 8.27448 -17.9255 -7.92787 9.26857 -18.8737 -7.97413 8.94183 -19.2519 -8.75248 9.36519 -19.4456 -8.46752 10.3198 -19.7559 -7.8275 11.1423 -20.5286 -7.48481 10.5999 -21.16 -8.20521 10.7983 -21.8478 -8.79569 11.1651 -22.1881 -9.75642 11.0834 -22.551 -10.4307 11.7372 -22.2795 -9.63059 12.2746 -21.9497 -9.62905 13.2803 -22.1233 -10.5899 13.2647 -21.1064 -10.4795 13.3401 -20.1546 -10.2607 13.1135 -19.8611 -11.0319 12.5298 -19.0351 -10.684 12.6462 -18.7512 -9.69964 12.3803 -19.0136 -8.79802 12.6864 -18.2335 -8.86224 12.1572 -17.7059 -8.504 12.9065 -16.9944 -8.68519 12.1964 -16.479 -9.59142 12.1525 -17.1032 -10.1971 11.9705 -16.6993 -10.056 11.0008 -17.2036 -10.3425 10.1139 -16.747 -11.221 9.75749 -16.5855 -11.9522 10.3832 -15.7068 -11.4718 10.312 -14.7848 -11.1441 10.3235 -14.0254 -10.6993 10.7953 -13.8821 -10.901 9.79934 -13.5875 -9.96983 9.76498 -14.5338 -10.081 9.4904 -15.3268 -9.47475 9.7422 -15.5225 -9.10891 8.87092 -16.4547 -8.99993 9.20027 -16.5743 -8.72167 10.198 -15.6227 -8.47545 10.0529 -15.148 -7.66022 10.3072 -15.3591 -7.28015 9.41737 -14.9739 -6.63366 8.7506 -14.6867 -5.6557 8.84822 -15.205 -4.79315 9.00626 -16.0689 -4.38523 8.7097 -16.1528 -5.27022 9.13086 -16.8174 -5.81785 8.59818 -16.492 -5.61505 7.6852 -16.4994 -4.65978 7.2309 -15.7792 -3.95214 7.37348 -16.5103 -3.46907 6.82456 -16.3945 -2.49577 6.80721 -16.4337 -2.12198 7.75948 -17.1704 -1.7393 8.31958 -18.1169 -2.12737 8.35055 -18.8431 -1.98067 7.70293 -19.5573 -2.02583 8.40408 -19.7976 -1.02033 8.60876 -20.2648 -0.7406231 7.72927 -20.0765 -1.59683 7.21793 -20.2141 -2.21748 6.45899 -20.256 -3.19734 6.65182 -20.9306 -2.76241 6.00529 -21.3451 -3.32882 5.20678 -21.9035 -3.95014 5.80716 -21.2152 -4.29003 6.52598 -21.736 -4.95853 5.9 -21.3625 -5.89126 6.1946 -21.3074 -6.06394 5.20278 -20.9948 -6.78329 4.57963 -21.1179 -7.54728 3.87841 -20.7241 -7.69119 2.99596 -21.3608 -8.41895 2.71861 -21.1059 -8.20947 1.7246 -21.9665 -8.54209 1.37786 -21.6559 -7.61949 0.9286551 -21.7768 -6.7471 1.37315 -22.6046 -6.79882 0.8058411 -21.7672 -6.69171 0.2125821 -21.5544 -6.54088 -0.7577079 -22.3285 -6.97684 -1.24761 -23.0253 -7.40464 -1.91518 -22.3341 -7.44831 -2.61601 -22.9223 -6.95156 -3.24137 -23.4027 -6.25434 -2.64341 -23.391 -6.09644 -1.70283 -23.9508 -6.20615 -0.8761359 -24.9834 -6.1078 -0.8400219 -25.2547 -7.03295 -0.9136409 -24.786 -7.05092 -0.09198458 -25.149 -7.73203 0.5641071 -25.9877 -7.65417 1.00865 -26.871 -7.81512 1.40951 -26.7763 -6.88979 1.12459 -27.1336 -6.64432 0.1630551 -26.6866 -7.20391 -0.5158289 -26.7516 -6.69725 -1.41083 -27.4517 -6.1624 -0.9676279 -27.9289 -7.10297 -0.7146419 -28.1323 -7.56895 -1.46938 -27.8468 -6.66871 -1.79824 -28.0947 -6.69959 -2.7563 -27.2235 -6.26286 -2.91482 -26.8746 -7.15835 -3.12634 -26.0425 -7.24218 -3.69557 -26.1472 -6.74923 -4.51859 -26.0954 -6.22472 -5.34343 -25.3895 -5.5432 -4.90346 -24.6543 -4.81782 -4.98752 -24.2901 -4.70177 -4.05983 -24.6837 -3.82935 -3.82615 -25.6016 -3.48303 -3.53388 -25.0594 -2.70644 -3.09642 -24.7134 -1.96145 -2.7228 -24.7817 -2.66865 -1.98985 -24.5285 -1.6685 -1.83998 -24.6411 -0.6691721 -1.99527 -24.657 0.2563699 -2.33502 -23.792 -0.1863201 -2.15793 -23.6631 0.7617449 -2.48527 -23.393 -0.01082957 -3.06198 -22.3877 -0.2866181 -3.01994 -21.4797 -0.5305481 -3.25696 -21.6211 -0.1646271 -4.18978 -21.5455 -0.7555601 -5.01006 -21.7472 -1.75674 -5.155 -20.8955 -2.23818 -4.89781 -20.2315 -2.60419 -4.13322 -20.0959 -1.99518 -3.34606 -19.2674 -1.99787 -3.90795 -18.4911 -2.08374 -3.25869 -18.041 -2.45582 -4.01131 -18.6081 -2.31234 -4.74721 -18.957 -2.0569 -5.59225 -19.6966 -2.39009 -6.16052 -20.3034 -1.84614 -6.70041 -21.0889 -2.49747 -6.71425 -21.1995 -3.14856 -7.52388 -21.8802 -3.53745 -6.92579 -21.1251 -3.9284 -6.51005 -21.429 -4.7645 -6.09475 -20.4397 -5.05995 -6.38966 -20.8551 -5.99014 -6.57822 -21.759 -6.27665 -6.97959 -22.3508 -7.04059 -6.61973 -21.417 -7.48185 -6.82725 -21.3164 -8.42094 -6.8234 -21.3011 -8.95611 -7.67155 -21.8814 -8.30552 -8.01003 -22.7625 -7.97588 -7.67194 -22.9353 -7.4974 -8.49718 -22.4819 -8.12795 -9.13068 -23.3765 -8.60646 -9.26891 -23.479 -8.69273 -8.30887 -23.544 -9.32247 -7.45877 -23.428 -9.42892 -6.48115 -23.0874 -10.3439 -6.65846 -22.9987 -11.1129 -7.37403 -22.9768 -10.2864 -7.81775 -22.1775 -10.317 -8.37624 -22.2652 -9.52933 -9.02032 -21.7135 -9.68697 -9.81553 -20.7304 -9.48614 -9.84884 -19.7573 -9.37231 -9.8692 -18.796 -9.28359 -9.9117 -18.9861 -10.2115 -9.68353 -19.7753 -10.4255 -9.08492 -20.5701 -10.7339 -9.63454 -20.2053 -10.3334 -10.39 -19.3352 -10.8553 -10.6687 -18.7666 -11.0881 -11.5216 -18.3921 -10.25 -11.9594 -18.3739 -9.22883 -11.786 -17.7957 -9.1544 -10.9236 -17.6421 -8.20032 -10.6845 -17.3023 -8.74722 -9.88118 -18.1306 -8.85584 -9.29409 -18.5576 -9.16487 -8.4177 -17.6614 -8.78173 -8.29974 -16.8646 -8.16066 -8.44632 -15.8106 -8.14961 -8.47741 -14.9974 -8.25591 -9.076 -14.4029 -7.54262 -8.6765 -13.7685 -7.00973 -8.07132 -13.1662 -6.16968 -8.14931 -14.1549 -5.98558 -8.15327 -14.8697 -5.34745 -8.34599 -15.7605 -5.38786 -8.88319 -16.318 -5.10461 -8.16469 -15.7286 -5.65552 -7.58069 -16.3998 -6.28118 -7.80955 -17.1394 -7.00076 -7.87616 -17.9579 -7.48586 -7.54744 -18.4704 -6.5651 -7.77456 -18.3785 -6.58857 -8.76891 -18.2207 -6.89925 -9.6292 -17.9063 -7.13457 -10.5099 -17.1472 -7.5748 -10.0168 -16.8444 -6.96938 -10.7676 -16.6841 -7.93569 -11.2557 -15.9679 -7.4911 -10.7023 -15.6153 -8.17576 -11.36 -14.8939 -8.68783 -10.9075 -14.4088 -9.45212 -11.3885 -14.2227 -10.1108 -10.6925 -15.0685 -9.82006 -10.3297 -14.9774 -9.97402 -9.35027 -14.6915 -10.1326 -8.43559 -13.8304 -10.6282 -8.13017 -13.5442 -10.5907 -7.19171 -13.8728 -9.63076 -6.90914 -14.7125 -10.1243 -7.06792 -15.5954 -10.418 -7.45982 -16.3818 -9.76858 -7.46094 -15.8545 -9.79423 -6.60187 -15.7608 -9.25593 -5.75154 -16.0868 -8.49331 -5.30743 -16.1881 -7.46885 -5.35172 -16.9781 -8.01292 -5.14853 -16.7097 -7.13513 -4.68151 -16.5169 -6.43491 -3.98346 -17.3276 -5.92246 -4.20739 -18.1009 -6.22905 -3.64878 -18.6325 -6.84135 -4.17957 -18.6742 -7.82905 -4.0292 -17.7927 -8.04724 -3.56568 -18.0658 -7.46911 -2.83945 -18.9274 -6.91294 -2.60851 -18.7833 -7.6081 -1.90326 -18.5111 -8.23448 -1.14669 -18.9656 -8.24829 -0.2553509 -19.5093 -7.83134 0.4925901 -18.8313 -7.09243 0.5159011 -18.2227 -7.73146 0.6578981 -17.8239 -7.39928 1.51386 -18.6492 -7.92326 1.70251 -18.8199 -7.13032 2.28827 -19.1119 -6.74411 3.09778 -18.1124 -6.98182 3.21772 -18.093 -6.53972 4.07611 -17.8826 -5.55152 3.95393 -17.8578 -4.95806 4.69764 -17.7033 -4.1437 5.36405 -18.3869 -4.30892 6.06878 -19.0243 -3.48429 5.91544 -19.1784 -3.78783 4.95218 -18.6214 -3.77572 4.1725 -18.5924 -3.50396 3.1631 -19.3957 -4.05893 3.48256 -19.4797 -5.02794 3.39611 -19.4837 -5.42554 4.26888 -20.1759 -5.99255 4.72308 -19.6309 -5.34667 5.28917 -20.1929 -5.35215 6.14265 -19.2411 -5.30114 6.28298 -18.5848 -5.96902 6.86338 -18.7682 -6.91889 7.12674 -18.4297 -7.48482 6.35488 -17.4872 -7.93388 6.54116 -18.1375 -8.58743 5.98143 -18.938 -8.91742 6.46279 -19.4228 -9.79183 6.37346 -20.1544 -9.40485 6.91646 -19.7492 -8.5227 7.24438 -19.2252 -7.76647 7.69298 -19.5487 -6.84756 7.97032 -20.1464 -6.20261 7.48492 -21.0282 -6.8377 7.42242 -20.358 -7.21855 6.74877 -20.9892 -7.56282 6.06395 -21.1337 -8.05036 6.94745 -21.0823 -9.04436 6.85972 -21.1518 -9.89983 6.33971 -21.1151 -10.8283 6.66858 -20.5764 -11.0639 5.88796 -19.8294 -11.7305 5.81048 -19.0415 -11.8997 6.39853 -18.7603 -11.5521 5.49658 -18.0694 -12.0078 6.16271 -17.207 -12.1312 6.59847 -16.4614 -12.679 6.20835 -17.3544 -12.9821 5.82982 -17.5822 -13.8648 6.26362 -17.5711 -14.6216 5.70605 -17.5209 -15.224 6.48643 -17.8516 -15.2688 7.44001 -17.2653 -14.4567 7.34538 -16.5432 -13.7846 7.14224 -15.9017 -13.5177 6.41324 -15.4928 -13.3811 5.5374 -14.6698 -13.1157 5.93551 -13.9372 -12.3689 6.02749 -14.1677 -12.2197 5.08345 -14.7104 -11.509 5.6502 -14.6878 -10.7714 4.97807 -14.1547 -10.0261 5.04875 -14.8651 -9.86271 5.7042 -14.0632 -9.34538 6.09293 -14.3729 -10.021 6.78057 -15.1096 -9.99884 7.37646 -15.6746 -10.6568 7.02249 -15.9279 -10.6059 6.06132 -16.4079 -11.4074 5.76273 -16.2654 -10.8469 4.94958 -16.1915 -11.704 4.31425 -16.599 -12.5706 4.51392 -16.8274 -12.1792 3.61445 -15.9975 -12.7584 3.60671 -16.0301 -11.8758 3.07606 -15.6317 -11.8692 2.22853 -16.1856 -12.6577 1.93717 -15.796 -13.3021 1.19873 -15.3748 -13.706 2.02798 -14.4974 -13.4243 2.37818 -14.4269 -13.4892 1.36785 -13.6496 -14.1375 1.36854 -14.0615 -15.013 1.29953 -14.1317 -15.4005 0.3620601 -13.5855 -14.7535 -0.2217859 -13.6058 -13.7922 -0.1469439 -14.0415 -12.8525 -0.01262228 -13.2101 -12.3484 -0.1425779 -12.6013 -12.8521 0.5020671 -12.0452 -12.1303 0.1183821 -11.4829 -12.8778 0.4062601 -11.0044 -13.3143 1.17346 -10.3201 -13.7169 0.5586821 -10.547 -14.246 1.39172 -11.2095 -13.8894 2.0453 -11.9746 -13.313 2.27174 -12.0371 -13.0787 3.26039 -11.7533 -13.899 3.55016 -11.8535 -14.8504 3.44028 -11.9905 -14.7594 2.42351 -11.8866 -15.3083 1.54132 -12.2134 -15.0748 0.6195121 -11.2819 -14.8978 0.1642661 -12.0992 -15.1222 -0.4202699 -12.6321 -14.431 -0.9589949 -12.9544 -13.5229 -1.01692 -13.2658 -12.6284 -1.41594 -12.3869 -12.2775 -1.64752 -12.1595 -12.9521 -2.31651 -11.3085 -13.2876 -2.71296 -10.9376 -12.2956 -2.71275 -10.1703 -12.4505 -3.273 -10.3531 -13.3887 -3.66699 -9.55004 -13.0143 -4.16153 -9.37126 -12.613 -5.13707 -8.6012 -12.7021 -4.48669 -8.33501 -12.2441 -5.30837 -8.37652 -12.6021 -6.24236 -7.4953 -12.3575 -6.64132 -6.55296 -12.8129 -6.71304 -5.5858 -13.0912 -6.95755 -5.23333 -13.2836 -7.86611 -5.56932 -12.512 -8.40397 -5.73283 -11.9641 -9.24702 -4.97546 -11.5979 -9.70485 -4.17229 -11.1222 -9.34746 -4.51117 -10.8005 -8.42358 -5.08643 -10.2976 -7.81421 -4.80887 -11.0737 -7.22259 -5.80377 -11.1639 -7.36302 -6.65575 -11.512 -7.89543 -7.03968 -11.9291 -8.7375 -7.23371 -10.9511 -8.84002 -7.09943 -10.7708 -9.77572 -6.88196 -10.9962 -10.7237 -6.22254 -11.3629 -11.366 -5.67575 -10.906 -12.0324 -4.95089 -11.1826 -12.6584 -5.41955 -11.7045 -13.3724 -6.12384 -10.9987 -13.652 -5.98712 -10.396 -14.4148 -5.38659 -9.80669 -13.7759 -5.83754 -8.92129 -13.7728 -5.18476 -8.13768 -13.9299 -4.97499 -7.37939 -14.4223 -5.79436 -7.0227 -14.813 -6.09834 -7.79915 -14.3077 -6.57475 -8.38309 -14.9322 -6.83516 -8.26762 -15.8374 -6.61906 -9.23111 -15.543 -7.48016 -9.3018 -16.111 -8.10643 -9.66531 -16.7786 -8.60613 -9.92333 -17.6252 -7.84103 -9.72727 -18.3496 -7.33405 -10.4729 -18.8041 -7.54725 -10.9532 -19.6003 -7.04986 -11.7437 -20.1213 -7.73455 -12.3337 -20.4323 -7.95764 -12.7284 -19.5205 -8.84435 -12.7147 -20.0628 -9.60785 -13.2988 -20.1347 -9.80091 -13.8707 -20.9562 -9.40392 -13.1884 -21.5837 -9.64996 -12.5743 -22.3183 -10.1421 -11.7231 -22.5319 -10.5058 -12.3583 -23.1517 -10.3697 -13.2926 -22.6734 -10.3616 -13.9984 -23.4214 -10.0747 -14.5101 -22.6865 -10.4569 -15.376 -22.9754 -9.53122 -15.809 -23.1885 -9.31837 -16.5941 -22.6557 -8.46959 -16.224 -22.2594 -8.81906 -17.1011 -21.7078 -9.01358 -18.012 -22.0989 -8.24614 -17.9071 -21.4255 -8.78097 -18.7071 -21.1784 -8.18534 -19.3222 -20.6674 -8.80573 -19.4787 -19.9349 -7.92026 -19.964 -19.7659 -7.79673 -19.7267 -18.779 -7.22566 -19.7185 -17.9542 -7.54123 -18.8415 -17.5885 -7.65734 -18.1262 -16.9742 -7.38109 -18.5117 -16.1479 -8.15947 -18.1488 -15.7146 -8.09008 -17.1081 -15.4812 -8.81774 -17.5079 -14.9385 -8.37789 -17.2979 -14.1106 -8.25851 -18.1868 -13.6353 -8.32404 -18.5571 -12.6749 -9.27336 -18.472 -12.314 -9.43369 -19.4562 -12.3271 -8.60496 -19.9436 -12.4283 -8.44409 -20.1602 -11.4894 -9.34734 -20.3854 -11.1772 -10.2346 -20.9361 -11.3982 -10.0405 -21.6829 -11.978 -10.476 -22.6051 -12.3903 -9.76415 -22.0923 -12.9468 -9.15731 -22.8901 -12.8443 -8.49264 -23.1834 -12.1936 -7.99539 -23.0665 -11.3222 -7.58788 -23.6023 -10.6029 -6.69184 -23.6452 -11.046 -6.1688 -23.1681 -10.3445 -5.43497 -22.6592 -10.7588 -5.93334 -21.7625 -10.8329 -5.21747 -21.0562 -10.7185 -5.52593 -20.1326 -10.6937 -4.84134 -19.6647 -10.0695 -4.77899 -20.2433 -9.24482 -5.70293 -20.0972 -8.96647 -6.56166 -20.1493 -8.53731 -6.05573 -20.3935 -7.72566 -6.25481 -21.0444 -6.98909 -5.2718 -20.9297 -6.85422 -5.72649 -20.059 -6.56862 -6.15054 -19.1535 -6.5145 -5.21791 -19.0824 -6.17143 -5.11878 -18.9327 -7.13758 -4.38463 -18.4943 -6.6736 -4.55585 -17.7882 -7.36224 -4.33931 -18.5378 -7.9703 -3.51437 -18.1766 -8.38461 -3.31573 -17.1623 -8.5042 -2.64705 -16.5191 -8.07485 -2.09744 -16.0726 -7.45535 -1.49062 -16.6522 -8.03906 -1.23387 -17.3328 -8.73925 -0.30346 -17.6416 -8.7533 -0.630839 -17.5357 -7.83265 -0.210842 -16.8549 -7.28446 --0.765609 -17.266 -7.33179 --1.53015 -16.916 -7.9341 --2.29494 -17.4418 -8.33827 --1.94944 -17.1984 -9.2451 --1.22487 -17.5755 -8.78027 --0.714598 -17.7171 -9.60344 -0.06488177 -17.3654 -10.2273 -0.525294 -18.2407 -10.3922 -1.13476 -18.5559 -9.65827 -1.54671 -18.7541 -10.4597 -2.16486 -19.4978 -10.8324 -1.69621 -20.2077 -11.4016 -1.91181 -20.2654 -12.4186 -1.409 -19.7684 -13.1023 -1.54617 -20.7256 -13.4249 -2.34039 -20.8288 -14.0463 -3.02103 -20.6838 -14.7256 -2.37203 -21.1984 -15.4201 -2.14142 -20.9476 -16.3499 -1.10596 -21.078 -16.4609 -1.20952 -21.3057 -17.4668 -1.81886 -21.2546 -18.2423 -1.70381 -22.126 -17.8731 -2.64485 -21.9541 -17.8906 -3.0109 -22.71 -18.4294 -2.79627 -23.6582 -18.1087 -1.98309 -23.9377 -18.581 -1.0055 -23.9426 -18.6433 -1.15869 -23.558 -17.7189 -1.33041 -23.2878 -16.8962 -0.365032 -23.0308 -17.0969 --0.32087 -23.6106 -16.6645 --0.261421 -24.5238 -16.7546 --0.965106 -24.8404 -16.0651 --0.541065 -25.7111 -16.2759 --0.13045 -26.4429 -16.9291 -0.452407 -25.9393 -17.5352 -1.12468 -26.6343 -17.2503 -1.87334 -27.1562 -16.8338 -2.84869 -27.4653 -16.6884 -3.07772 -26.4928 -16.3248 -2.9076 -26.7115 -15.3852 -3.42252 -27.4111 -14.9066 -3.71078 -26.5849 -14.5453 -4.61808 -25.9529 -14.4735 -4.71975 -25.0222 -14.269 -5.18331 -24.3615 -13.6798 -4.54223 -23.7079 -14.0882 -3.85702 -23.5658 -13.3038 -4.60859 -23.0586 -13.0079 -4.24686 -22.321 -13.5225 -3.6305 -22.0557 -12.7291 -3.67121 -21.6047 -11.8541 -3.57334 -22.4138 -11.3345 -4.3978 -22.0328 -10.8776 -3.4967 -21.8318 -10.4978 -2.65757 -21.6443 -9.99944 -2.49867 -20.6314 -10.0876 -1.56033 -20.6741 -10.5921 -1.30445 -21.674 -10.5731 -0.699086 -21.0486 -10.0437 -0.09555337 -21.7721 -10.3895 --0.67992 -21.2678 -10.1384 --0.202553 -20.7224 -9.41979 --0.311098 -19.9992 -10.0689 --1.27705 -19.8724 -9.72904 --1.9763 -20.58 -9.45762 --2.82533 -21.0768 -9.558 --3.60508 -21.3714 -10.0813 --3.53135 -22.1902 -10.74 --2.59959 -21.9488 -10.3021 --2.67019 -21.1641 -10.8356 --2.51565 -20.5099 -11.5707 --1.81123 -20.8977 -12.2278 --1.44584 -21.3162 -13.0275 --0.73851 -21.579 -13.8188 -0.236861 -21.3814 -13.4472 --0.09628743 -20.4786 -13.4706 --0.887608 -19.9084 -13.3225 --0.579713 -19.1058 -12.8048 --0.06776103 -18.3438 -12.6442 --0.07017153 -17.3949 -12.881 -0.435471 -16.763 -12.3504 --0.426818 -16.5531 -11.9151 --0.870841 -15.7697 -11.509 --1.55085 -16.3677 -12.0503 --1.27065 -16.9211 -11.2321 --1.18798 -17.8167 -10.8812 --1.11851 -18.8133 -10.6261 --1.81577 -19.3954 -11.0657 --2.76171 -19.3865 -10.6881 --2.67028 -18.6328 -10.0883 --3.21577 -17.9983 -10.5421 --2.72929 -17.0884 -10.6989 --2.06918 -16.3772 -10.5869 --2.41188 -15.428 -10.9257 --2.61337 -14.6895 -11.5954 --3.37941 -14.9578 -12.1664 --3.499 -14.2555 -12.8225 --2.62909 -13.8393 -12.5668 --2.05287 -13.1233 -12.0971 --1.70181 -13.7434 -12.7353 --2.10006 -13.8884 -13.6604 --1.22756 -13.5752 -13.914 --1.10603 -13.6872 -14.9312 --1.21701 -14.0955 -15.8314 --0.855184 -14.9099 -15.4374 --0.418993 -15.2425 -14.6199 --0.421346 -14.5223 -13.9643 -0.0001792789 -13.7874 -13.3506 --0.03544683 -13.7805 -12.3673 -0.784476 -13.2783 -12.6815 -0.617006 -12.3794 -13.1352 --0.107018 -12.766 -12.5574 -0.395121 -12.239 -11.7953 -0.969215 -11.4478 -11.6446 -1.80403 -11.269 -12.014 -2.13606 -10.6996 -11.3237 -2.62238 -10.4303 -10.4696 -3.62027 -10.7194 -10.4867 -3.89445 -9.78872 -10.2689 -4.19952 -9.1349 -9.58573 -4.04027 -8.1288 -9.51668 -4.27428 -7.20865 -9.13025 -4.84118 -7.94261 -8.82737 -5.18071 -8.20168 -9.67821 -5.29692 -7.8281 -10.5448 -4.73542 -7.04117 -10.63 -5.4986 -6.57264 -10.1909 -5.7427 -6.92387 -9.31386 -6.6317 -7.31008 -9.57501 -7.32351 -6.76058 -9.03518 -7.35366 -5.80094 -8.76102 -7.51738 -5.74687 -7.80811 -7.25195 -6.72952 -7.75134 -6.95933 -7.59133 -8.08346 -6.38235 -7.37818 -7.2558 -5.44709 -7.17467 -7.47445 -5.80451 -6.54991 -8.16074 -5.90815 -5.96432 -8.97354 -5.60246 -5.18853 -8.42283 -4.6496 -5.12385 -8.59673 -5.18904 -4.2202 -8.63952 -5.62873 -3.26535 -8.56635 -4.62946 -3.09886 -8.58138 -4.14555 -3.37981 -9.37884 -4.52177 -3.9066 -10.0376 -3.77177 -4.48777 -9.69233 -3.48214 -5.44408 -10.018 -3.06511 -6.23814 -10.3596 -2.23593 -6.64603 -10.8246 -2.11271 -5.93336 -10.1643 -2.17686 -5.59376 -9.22687 -2.50086 -5.17389 -8.30703 -2.89124 -4.74398 -7.49698 -1.96821 -4.3552 -7.67211 -1.36323 -3.82094 -7.12431 -0.839738 -4.22401 -7.85054 --0.07656933 -4.43257 -8.04143 --0.591147 -4.26526 -8.90786 --0.591387 -3.52462 -9.5631 --1.45232 -3.7407 -9.91939 --1.59714 -4.69768 -10.0706 --1.37398 -5.45543 -9.54875 --0.570133 -5.85085 -9.09413 -0.429701 -5.97091 -9.17332 -1.00349 -5.37312 -9.67299 -1.18624 -4.40109 -9.90642 -1.97619 -3.87881 -9.57551 -1.49755 -2.96554 -9.51512 -0.670516 -2.52128 -9.83319 --0.277879 -2.26621 -9.63094 --0.981942 -1.53599 -9.5279 --0.612929 -0.6368001 -9.17189 --1.52626 -0.8659761 -8.86652 --2.57513 -0.8634281 -8.66677 --3.5389 -1.3613 -8.72864 --3.89156 -0.4996101 -8.57846 --3.44795 -0.03886937 -9.33565 --4.45175 0.03300163 -9.40652 --4.93609 0.8587609 -9.58454 --4.35682 0.8517059 -10.4249 --4.91839 0.1780219 -10.9585 --5.09428 0.9554969 -11.5736 --5.06958 1.63067 -12.2724 --5.61948 2.14972 -12.9432 --5.85327 2.75647 -12.2086 --5.48024 2.26439 -11.4456 --5.87602 3.09043 -10.9578 --6.52851 2.38961 -10.7783 --7.33528 2.59017 -11.2935 --7.91268 2.94337 -11.9365 --8.49477 2.50883 -12.604 --8.67009 1.73665 -13.2079 --8.76781 2.5201 -13.856 --8.72685 3.51251 -13.8082 --8.19841 4.38405 -13.8613 --8.18502 5.35668 -13.7548 --8.22738 6.23308 -14.2158 --8.61706 6.93495 -13.5972 --9.41944 7.50613 -13.7865 --9.86154 8.21908 -13.2261 --9.4693 8.90952 -13.8185 --8.53638 8.53803 -13.973 --8.02549 8.24011 -14.8875 --7.52903 8.42414 -15.7236 --8.16713 7.99571 -16.4205 --8.34328 6.99606 -16.4318 --7.59078 6.33473 -16.1529 --6.69203 6.47663 -15.7603 --6.59963 5.48516 -15.9628 --5.56738 5.43077 -15.8377 --4.73028 5.00961 -16.2535 --4.64951 4.79093 -15.2966 --4.03222 4.78332 -14.5027 --4.389 3.87693 -14.6961 --4.04127 3.0377 -14.9142 --3.21353 3.49836 -14.8334 --3.25573 2.92056 -15.6808 --2.64308 2.15048 -15.3501 --2.66563 1.14518 -15.4462 --2.88498 0.2590269 -15.7411 --3.33001 -0.4968361 -15.2667 --3.28519 -1.37007 -14.827 --3.31891 -1.31571 -15.8429 --3.08824 -1.7828 -16.6784 --4.08998 -1.69908 -16.7099 --4.5947 -0.8988301 -16.3526 --5.33281 -0.6653921 -16.9479 --5.28396 0.2840479 -17.139 --4.41405 0.2182769 -17.5638 --3.93527 -0.03800857 -18.4536 --3.13385 0.03247733 -17.9478 --3.08053 0.8461409 -18.4722 --2.89623 0.2154179 -19.2318 --3.43449 0.7468309 -19.8631 --4.17189 1.29877 -19.4631 --5.0241 1.01476 -19.0021 --5.21532 0.04330783 -18.9935 --5.23878 -0.02761457 -19.969 --5.82189 -0.6903471 -19.4982 --5.23445 -1.20978 -20.1803 --4.4694 -1.42132 -19.5122 --3.84957 -1.91205 -18.9204 --4.2518 -2.80902 -18.5978 --4.36849 -2.56776 -17.5937 --3.59843 -2.96523 -17.0867 --3.48938 -3.87131 -16.5303 --4.44361 -3.61948 -16.1718 --4.6991 -3.18533 -15.3519 --3.83822 -3.13673 -15.7049 --3.68376 -2.60623 -14.8079 --3.76689 -3.00443 -13.9125 --3.19118 -2.89826 -13.1088 --3.12892 -2.10077 -13.6839 --2.32274 -2.12277 -13.0078 --1.85964 -1.80365 -12.1678 --0.916772 -2.0697 -12.3468 --0.971444 -2.80952 -11.6705 --0.912032 -3.56639 -12.3072 --1.31291 -4.28642 -12.7692 --0.869967 -3.68049 -13.3329 --0.280933 -3.04328 -12.8938 -0.145615 -2.44028 -13.5893 -0.914475 -2.88547 -13.2336 -1.07139 -3.37413 -12.3384 -1.19318 -4.0603 -13.133 -2.03399 -4.46283 -13.5078 -2.63954 -4.68778 -14.1846 -1.7572 -4.87093 -14.656 -2.47576 -5.56088 -14.7849 -1.78657 -6.13526 -15.1822 -1.10469 -6.0257 -14.4925 -0.174578 -6.07243 -14.8754 -0.391988 -6.50658 -15.7378 --0.508114 -6.12165 -15.6432 -0.08153147 -5.63032 -16.2813 -0.220503 -5.28233 -15.3468 -0.03570347 -4.43878 -15.965 --0.104011 -4.43937 -16.9176 --0.641451 -4.34454 -17.7144 --1.42095 -3.93801 -18.154 --2.01159 -4.10451 -18.9461 --3.02921 -4.00917 -18.6123 --3.96391 -4.25978 -18.5035 --3.94214 -5.18315 -18.9722 --3.18083 -5.75725 -18.5155 --3.08104 -6.32807 -19.2923 --3.88924 -6.69755 -19.7769 --4.55959 -6.12842 -20.238 --4.89227 -5.29005 -20.7251 --5.82209 -5.50769 -20.3273 --6.17876 -4.49091 -20.3777 --6.98131 -3.9316 -20.5103 --6.94715 -3.12982 -19.8744 --7.65128 -2.77609 -19.2852 --7.89686 -1.8012 -19.0601 --6.86182 -1.86893 -19.0121 --6.10463 -1.78044 -18.3386 --6.36025 -2.80364 -18.1595 --6.69031 -3.37851 -17.3864 --5.9277 -3.98178 -17.7605 --5.71752 -3.50243 -16.9172 --5.53959 -4.42427 -16.4898 --4.9998 -4.91281 -15.8093 --5.88797 -5.25496 -15.5376 --5.17761 -5.43359 -14.8921 --4.4915 -5.41954 -14.1445 --4.15635 -5.47712 -15.079 --3.49325 -6.18058 -14.8004 --2.94532 -6.99019 -14.7242 --3.55593 -7.6204 -15.1602 --4.52074 -7.37278 -14.9695 --5.21687 -6.84787 -15.4385 --5.66519 -7.0381 -16.2502 --5.20698 -7.23071 -17.1713 --5.74133 -8.10952 -17.0496 --5.80442 -9.0973 -16.8729 --4.80255 -9.34265 -16.8055 --4.23824 -8.77637 -16.2485 --3.31661 -8.86548 -16.4986 --2.86784 -9.66271 -16.0148 --3.2209 -9.9424 -15.1731 --2.49329 -10.5103 -15.559 --1.59888 -10.0989 -15.5328 --0.712121 -10.5507 -15.7875 -0.03980327 -10.125 -16.3106 --0.39369 -9.8364 -17.1862 --0.320843 -10.6806 -17.7471 -0.553461 -11.2237 -17.4677 -0.393891 -11.4995 -16.4665 -0.965483 -11.3561 -15.6548 -1.09134 -12.2893 -15.1868 -0.522622 -12.5079 -14.3833 -0.17577 -11.8475 -15.084 -0.187091 -11.3937 -14.1999 --0.141519 -10.4381 -13.9956 -0.425746 -9.6049 -14.02 --0.237295 -8.97989 -13.5929 --0.847615 -8.20453 -13.7356 -0.03942217 -8.06333 -13.1925 --0.488034 -8.59983 -12.513 --0.812392 -9.01112 -11.7416 -0.05931477 -9.26492 -12.0287 -0.515404 -10.111 -12.0801 -0.5601 -9.74446 -11.224 --0.389113 -9.97651 -10.9753 -0.312737 -10.5257 -10.4426 -0.1831 -11.4647 -10.4448 -0.529094 -11.8167 -9.52893 -0.584328 -12.677 -10.0379 -1.34095 -12.5275 -10.6526 -2.12428 -13.1564 -10.7294 -2.34751 -14.1728 -10.9 -2.93189 -14.2253 -10.078 -3.42288 -13.4026 -9.7333 -4.43321 -13.2752 -9.49206 -4.37623 -13.3654 -10.4547 -3.70224 -13.1962 -11.1596 -4.34965 -13.842 -11.486 -5.2831 -14.1724 -11.5148 -5.55035 -14.9211 -12.1126 -4.6832 -15.4124 -12.3779 -4.34466 -14.5424 -12.711 -5.27795 -14.2931 -13.0261 -6.13573 -14.8011 -13.1491 -5.75136 -15.7596 -13.3706 -6.156 -16.4616 -12.7982 -6.11715 -17.3523 -12.385 -5.18196 -17.4978 -12.8892 -4.60885 -17.2212 -12.05 -3.85863 -16.7845 -11.5044 -3.68928 -16.5792 -12.4595 -3.46068 -17.5322 -12.8097 -2.95626 -18.246 -13.2383 -2.60664 -18.4075 -12.3147 -3.41465 -17.915 -11.9992 -2.43356 -17.7126 -11.7113 -1.75261 -17.0377 -11.6321 -1.05633 -16.3669 -11.424 -1.03603 -15.7975 -12.2832 -0.391981 -15.8443 -13.0295 -0.998052 -15.538 -13.8235 -1.304 -14.6266 -13.5697 -1.77931 -14.1385 -14.3655 -2.69796 -13.6797 -14.0684 -3.10556 -13.8763 -13.1216 -2.40889 -14.3343 -12.5379 -2.94881 -15.1419 -12.7965 -3.0579 -14.886 -11.8511 -2.71489 -15.6283 -11.3238 -2.51431 -16.1888 -10.4675 -2.00007 -15.3786 -10.1703 -1.96321 -14.678 -9.38318 -2.32467 -15.5381 -8.99671 -3.20075 -15.2126 -8.53457 -3.25067 -14.5382 -7.80628 -3.87748 -13.8694 -8.13017 -4.68305 -13.9065 -8.65782 -4.72087 -14.5395 -9.48952 -4.15216 -15.2782 -9.74921 -4.02083 -15.8004 -10.6065 -4.56679 -16.1884 -9.93498 -5.56624 -15.9277 -10.0405 -6.47393 -16.2625 -10.3235 -6.80235 -15.4439 -10.8171 -7.76964 -15.6897 -10.883 -8.27704 -14.8853 -10.4985 -8.86731 -14.3808 -9.92948 -9.87148 -14.293 -9.95183 -10.1524 -15.2727 -9.96079 -9.47708 -15.0865 -9.27986 -9.19798 -15.9588 -9.51214 -9.69013 -16.8098 -9.60213 -9.06761 -16.7727 -10.4252 -9.04486 -17.4539 -11.1215 -8.4801 -18.2262 -10.7955 -7.96671 -18.6462 -10.0317 -7.24417 -19.0736 -10.6924 -6.78412 -18.2643 -10.1923 -6.76373 -17.9372 -9.29114 -6.22469 -18.7284 -8.95612 -5.6394 -18.8284 -9.78786 -5.06021 -18.6246 -10.5643 -5.91596 -18.2086 -10.9006 -6.18851 -18.7226 -11.6609 -6.19306 -18.5577 -12.657 -6.18389 -19.1203 -13.5055 -6.95613 -19.7675 -13.4195 -6.6544 -19.7073 -12.458 -6.88927 -20.4801 -11.8838 -5.94273 -20.7176 -11.7871 -6.34081 -21.5896 -11.8257 -6.54438 -22.484 -12.0814 -7.3426 -21.9832 -12.2579 -7.72758 -21.7179 -13.1633 -8.64979 -21.5181 -13.475 -8.88078 -21.2746 -14.4486 -8.28622 -20.6415 -14.8601 -8.90286 -20.2846 -15.5776 -9.65783 -19.8036 -15.162 -10.2797 -20.5456 -14.7563 -11.0429 -20.7954 -14.1494 -11.4576 -21.2642 -13.3737 -11.7094 -21.5285 -12.4031 -11.4632 -21.9222 -11.4787 -11.2936 -21.9814 -10.5213 -11.8393 -22.2298 -9.66964 -12.7781 -22.5066 -9.65568 -12.3175 -23.273 -9.21618 -12.9336 -23.4435 -9.97529 -12.8517 -24.044 -10.7716 -13.752 -24.4493 -11.0761 -14.6586 -24.1736 -10.7948 -15.5674 -24.294 -11.0739 -15.6388 -24.4007 -12.0548 -16.3132 -23.8238 -11.8365 -16.6287 -22.9376 -12.0741 -16.5191 -22.536 -12.9881 -17.0353 -22.66 -13.8191 -17.7648 -22.0329 -13.4064 -18.7153 -22.24 -13.0745 -19.4052 -22.4632 -12.3556 -20.2186 -22.07 -12.747 -20.4088 -22.9838 -12.4087 -19.8052 -23.7186 -12.1429 -19.5685 -24.5197 -11.6114 -19.2494 -24.6848 -12.5419 -19.1164 -25.292 -13.3277 -19.8687 -25.4528 -13.9627 -20.7066 -25.4279 -14.5686 -21.5702 -25.8878 -14.5632 -21.2801 -25.6249 -13.5626 -20.8022 -26.2369 -12.8761 -19.8388 -26.0473 -13.1043 -19.5664 -26.8974 -12.6523 -18.9252 -27.332 -12.0953 -17.9957 -27.3829 -11.7841 -17.7926 -26.6807 -11.127 -17.1594 -26.357 -10.4534 -17.2826 -25.3684 -10.6811 -16.5226 -25.1001 -9.97244 -15.8778 -24.6599 -9.33559 -16.5834 -24.9422 -8.73405 -16.5817 -25.4004 -7.8214 -16.1121 -26.1859 -7.4172 -15.4392 -26.554 -7.99476 -15.5544 -25.7937 -8.64458 -14.5406 -25.8217 -8.68814 -14.0847 -25.5337 -7.82675 -13.1802 -25.2551 -8.19828 -12.8877 -24.9386 -9.13251 -13.9051 -24.7221 -9.05095 -13.9 -23.808 -8.6207 -14.2277 -24.0519 -7.70101 -14.2946 -23.3672 -6.97663 -14.2628 -23.3036 -5.97716 -14.0549 -22.5962 -5.21939 -13.9137 -22.0971 -6.08157 -13.1763 -21.6851 -6.60879 -13.1385 -20.6796 -6.55635 -12.7206 -20.5946 -7.39214 -12.2172 -21.4577 -7.43412 -12.7135 -22.372 -7.49352 -11.9784 -22.7894 -6.94834 -12.0051 -23.7408 -6.73848 -12.2223 -23.6557 -5.76564 -12.5236 -24.648 -5.8792 -12.263 -24.9119 -6.78395 -11.4867 -25.3055 -7.37392 -11.1775 -25.0846 -8.22175 -10.9894 -25.8074 -8.86226 -10.6162 -26.6485 -9.24989 -11.113 -27.4771 -9.59643 -10.2868 -27.9635 -9.29813 -9.60344 -27.5614 -9.86664 -9.55986 -27.2711 -8.94078 -9.80876 -27.5733 -8.0112 -9.41101 -26.8805 -7.41008 -9.41476 -25.9567 -7.64705 -9.11665 -25.3407 -8.39852 -9.30892 -25.66 -9.3589 -9.60851 -25.7372 -10.2836 -8.77694 -25.7761 -10.8226 -8.84179 -26.6426 -10.1506 -8.1882 -26.6834 -10.8975 -7.84339 -27.6071 -11.2533 -7.71186 -27.6055 -10.2978 -7.65695 -28.5584 -10.0213 -7.91996 -29.5465 -10.1175 -7.86381 -30.37 -10.7396 -8.165 -30.8988 -10.0244 -9.09725 -30.7788 -9.67797 -8.80002 -30.2411 -8.83131 -7.83837 -30.0236 -8.94351 -7.61592 -29.3506 -8.20535 -7.6928 -30.2533 -7.73117 -6.67548 -30.1758 -7.69912 -6.34363 -29.7085 -6.83994 -5.65522 -29.5246 -7.67432 -5.25661 -29.1654 -8.49673 -4.46443 -28.5988 -8.78929 -3.5096 -28.3103 -8.43011 -3.76869 -27.9115 -7.54398 -3.63149 -28.9383 -7.50885 -4.02796 -28.8981 -6.57905 -4.92432 -28.6333 -6.18797 -5.64113 -28.8968 -5.5739 -6.36915 -28.2153 -5.77219 -7.29798 -28.6117 -5.93242 -7.70151 -28.2185 -6.86025 -8.14484 -28.7565 -7.62219 -9.04841 -29.099 -7.99588 -9.48672 -28.9798 -7.11109 -9.97289 -29.7794 -6.81744 -10.9246 -29.9143 -6.61733 -11.2568 -29.5245 -5.73615 -11.403 -30.2531 -5.11609 -11.4618 -30.2351 -4.09913 -11.2242 -30.0663 -3.09526 -12.2046 -30.2475 -3.28527 -12.907 -30.5902 -3.93631 -13.3958 -31.3907 -4.02337 -14.3597 -31.6156 -4.03523 -14.8197 -30.9381 -4.60053 -14.3712 -30.1062 -5.06714 -13.4094 -29.9557 -4.73803 -12.7637 -29.2421 -4.74602 -12.766 -28.3572 -5.29818 -13.231 -27.4542 -5.23953 -13.3548 -27.2142 -6.21847 -14.286 -27.1345 -6.1173 -15.1158 -27.7286 -6.24973 -16.1196 -27.387 -6.3153 -16.7875 -26.8313 -5.71037 -17.5149 -26.8623 -4.9869 -18.2138 -27.1684 -4.24455 -18.9786 -26.9281 -3.61171 -19.5364 -27.5916 -4.16937 -19.5272 -28.6047 -4.08573 -18.6081 -28.6937 -3.62426 -18.0064 -28.4764 -2.86078 -17.898 -27.4597 -2.70205 -18.2718 -27.7191 -1.79111 -18.6048 -26.9908 -1.23899 -19.1368 -27.5926 -0.6512329 -19.6292 -27.852 0.1266841 -19.4255 -27.0775 0.7358001 -18.662 -27.68 1.05424 -18.5201 -26.8433 1.5077 -18.7068 -26.1967 0.7426251 -17.8464 -26.2925 0.2626851 -17.1823 -25.7248 -0.3716839 -16.6168 -24.9153 -0.1598689 -15.714 -24.4832 -0.3398989 -15.3714 -24.2237 -1.16885 -16.2798 -24.2422 -1.53983 -16.6255 -23.4418 -1.04091 -16.2032 -22.8808 -0.3071049 -15.8735 -21.9365 -0.2154859 -16.3879 -21.8682 0.6647901 -15.4176 -22.0333 0.8626841 -15.7005 -21.866 1.73248 -15.2056 -21.2999 2.32738 -15.709 -20.4909 2.26674 -15.4341 -20.1269 1.35991 -16.3787 -20.0142 1.12809 -17.1557 -19.9289 0.5492011 -16.8223 -19.1456 -0.07034078 -16.3106 -19.9615 -0.1057729 -16.9182 -20.6163 -0.5656899 -17.8819 -20.2127 -0.6676859 -18.3094 -20.7001 -1.43526 -19.0598 -21.2604 -1.61024 -19.9341 -20.7977 -1.38767 -20.0496 -21.7267 -1.74383 -20.4112 -21.7235 -2.66829 -20.4074 -20.8383 -2.90595 -21.3149 -20.5555 -3.00917 -20.6589 -19.8675 -3.37625 -20.1202 -19.1436 -3.75942 -20.3221 -18.4394 -4.48072 -20.684 -17.5754 -4.85178 -19.992 -16.8358 -4.72561 -19.9018 -15.9895 -5.21608 -20.1818 -15.7711 -4.26425 -20.6902 -15.8375 -3.41833 -20.797 -16.6764 -2.914 -19.855 -16.7946 -2.52979 -19.1886 -16.405 -3.1841 -19.0297 -15.4702 -2.78292 -19.221 -14.4994 -2.80888 -20.0677 -14.6829 -3.34164 -20.4434 -13.7763 -3.31472 -19.4643 -13.5166 -3.51252 -19.9689 -13.091 -4.306 -19.5062 -12.1831 -4.25078 -19.4054 -11.2169 -4.07694 -18.521 -11.5859 -3.79548 -17.5204 -11.497 -3.58986 -16.7453 -12.041 -3.2692 -16.963 -11.9835 -4.23123 -16.232 -11.4548 -4.68007 -15.4853 -11.0608 -5.25157 -15.1544 -11.6203 -4.49201 -15.1607 -12.6523 -4.65381 -14.4575 -12.1165 -5.10596 -13.9346 -11.3091 -5.26186 -13.9406 -10.3486 -5.09352 -14.0782 -9.84711 -4.27158 -14.5028 -9.14227 -4.81645 -15.4028 -8.84393 -4.46428 -15.7437 -8.22856 -3.76228 -16.2977 -8.42419 -2.93673 -16.8703 -9.11301 -2.59969 -17.4306 -8.37521 -2.16893 -17.2794 -8.99849 -1.42178 -17.6817 -9.86997 -1.07829 -17.1253 -10.1741 -1.80649 -16.2918 -9.66305 -1.49629 -15.8331 -9.22854 -0.6904129 -16.5122 -9.26005 0.04958052 -16.9919 -9.28842 0.9304581 -16.6047 -9.56284 1.83414 -15.9432 -9.03894 1.39695 -15.0127 -8.7172 1.06047 -14.37 -9.40521 0.9196971 -14.3933 -10.1805 1.62098 -13.5757 -9.70357 1.45689 -13.1295 -10.3944 0.7324251 -12.8419 -10.8999 1.44937 -12.5314 -9.99872 1.74929 -12.9838 -9.56833 2.55613 -13.7611 -8.98269 2.72421 -14.7273 -9.06167 2.46491 -15.2667 -9.80436 2.92219 -15.9593 -10.2613 2.42303 -16.3613 -10.7273 3.12756 -17.0951 -10.0654 3.36779 -17.2533 -9.09275 3.42199 -16.3912 -8.62641 3.12608 -15.9359 -7.70969 2.85661 -16.0285 -7.48963 3.82953 -15.7732 -8.3272 4.39432 -14.9122 -8.2129 3.80462 -13.9094 -8.11578 3.94545 -14.1486 -7.14878 4.03354 -13.5708 -6.96263 4.80262 -12.657 -7.07286 4.33386 -13.0568 -6.81138 3.50866 -13.6094 -6.57392 2.64743 -14.404 -5.95363 2.54102 -14.8734 -6.78139 2.22327 -15.824 -6.83437 2.40864 -15.9689 -5.90597 1.87672 -16.1855 -5.15403 2.4587 -16.2174 -4.23388 2.12209 -15.6596 -4.83354 1.53394 -15.5447 -4.34127 0.6148671 -16.2415 -3.8287 0.9948481 -16.9202 -3.5497 1.7019 -16.7058 -2.76477 2.32981 -16.6894 -2.01364 3.1022 -17.3213 -2.36224 3.78576 -17.1585 -2.93672 4.57473 -16.5527 -3.54641 3.97657 -15.8186 -4.19133 4.1524 -15.4241 -4.90067 4.75395 -15.5513 -5.57249 5.48577 -16.2664 -5.87635 6.1199 -16.5205 -6.71744 5.68303 -16.2458 -7.30416 6.46043 -16.2495 -8.23721 6.80561 -15.458 -8.11072 6.20612 -14.6222 -8.30134 5.63122 -14.7214 -7.38942 5.30952 -15.0877 -6.5723 4.97579 -15.2706 -6.60862 5.96359 -14.4349 -6.16136 6.26318 -14.3309 -7.07607 6.6816 -14.4833 -6.96358 7.62252 -14.6699 -5.98365 7.43966 -13.8659 -5.4496 7.05067 -13.0685 -4.96845 6.73721 -12.5242 -5.73505 6.36928 -12.5416 -6.21641 7.24197 -11.7849 -6.49409 7.81728 -11.4194 -7.02462 8.50158 -10.8248 -7.44324 7.83712 -10.3401 -6.66868 7.74805 -10.1159 -5.86779 7.11392 -10.7147 -5.12675 7.46192 -11.0287 -4.15252 7.56511 -11.0216 -3.97969 6.51305 -11.6352 -4.2773 5.81346 -12.5318 -4.54436 5.51507 -11.8249 -4.64516 4.75901 -11.4867 -5.57747 4.64073 -10.6342 -5.98434 4.55169 -9.82691 -5.45327 4.37626 -9.041 -5.78766 3.82623 -8.72476 -6.35542 4.63176 -8.9047 -6.0651 5.60462 -8.84308 -5.3633 6.2978 -8.81132 -4.36847 6.44201 -8.96536 -3.44143 6.16416 -7.93139 -3.15943 6.10483 -7.86794 -2.15857 6.25226 -8.62642 -2.30431 6.91569 -8.97559 -1.88807 7.77051 -8.29384 -1.22598 7.49074 -8.65738 -0.4279241 7.90068 -9.57068 -0.8063301 8.16903 -9.95977 -0.02060007 8.60467 -10.4041 -0.2824111 9.46776 -10.6536 0.6637999 9.29389 -9.97894 0.5659429 9.95862 -10.3222 0.5769729 10.9034 -11.0992 1.19235 10.6187 -11.1463 1.4923 11.5416 -11.95 1.70652 12.129 -11.9449 2.36608 12.7975 -12.0355 2.85016 11.8961 -12.1777 3.85226 11.9846 -12.1054 4.48535 11.0653 -12.7474 5.08237 11.4915 -13.5574 4.92995 11.994 -14.0985 5.6395 12.3409 -14.1473 6.61355 12.4175 -13.401 6.72036 12.9749 -12.8891 6.58013 13.8204 -13.4735 7.08363 14.591 -12.7062 7.11494 15.2203 -11.8894 7.51632 15.7422 -11.0025 7.17282 15.3211 -10.379 7.43746 14.6184 -9.59187 7.77115 15.1016 -9.07786 6.90905 15.2596 -8.85384 5.96241 14.8456 -9.0945 5.75556 15.8311 -8.92938 4.76267 15.9452 -9.37119 5.05681 16.8334 -8.94796 5.80009 17.3656 -8.81688 6.17271 18.3301 -8.36434 6.50203 19.0947 -8.60132 7.4322 18.9576 -7.65389 7.41121 18.5436 -7.12774 6.48494 18.2749 -6.51674 7.19216 18.6664 -5.97775 7.7071 19.2761 -6.56894 7.74764 20.0995 -7.49853 7.90588 19.6967 -7.47489 8.88353 19.6421 -8.39118 8.71202 19.536 -8.83773 9.31008 18.7803 -9.41321 9.104 18.0055 -9.65674 8.41865 17.3364 -9.54395 7.9262 16.4554 -9.97939 7.03988 16.6675 -10.9436 6.8876 16.2877 -10.6719 6.66071 17.1984 -10.4004 6.02327 17.8847 -11.2088 5.54344 17.5294 -11.9053 6.0561 17.1188 -12.2541 6.90489 16.7298 -11.9831 6.4564 15.8737 -12.5525 5.8063 15.2755 -13.4402 6.10114 15.0074 -14.4382 6.03826 15.0626 -14.5781 6.34669 15.9686 -14.3155 5.51283 16.5281 -14.5287 5.83497 17.4286 -13.9263 5.89642 18.2496 -13.0571 6.34586 17.988 -13.7898 7.06148 17.7608 -14.0733 7.59836 16.9563 -13.4545 8.23017 16.4437 -14.2941 8.02093 15.8863 -14.5664 8.02266 14.9176 -14.3767 7.67919 13.9822 -14.1412 8.60518 13.691 -14.3538 9.41434 14.1871 -14.9826 9.43962 13.4365 -15.4258 8.58844 13.1038 -15.3572 7.9171 12.3198 -15.8862 7.08662 12.3652 -15.3087 6.41512 11.9529 -15.7472 5.76358 11.2848 -14.8549 5.56618 10.8067 -15.1778 5.88579 9.97588 -15.7242 5.07879 9.84817 -16.6076 5.37026 9.91847 -17.4173 5.87078 9.86748 -17.3538 6.38671 9.0995 -17.5066 5.58474 8.57716 -18.0755 5.87276 7.78875 -18.2893 5.89856 6.7935 -18.8749 5.16928 7.21515 -17.9041 5.10296 7.11957 -16.9386 4.78744 7.17042 -17.0812 4.19571 7.94241 -17.2687 3.18868 8.12482 -17.1352 2.67696 9.02596 -17.802 1.95875 9.32616 -18.4263 1.49795 9.94625 -19.2834 1.0827 9.73296 -19.0554 0.1406569 9.51941 -18.3128 -0.2197141 8.90303 -17.619 -0.8765781 9.3324 -17.3936 -1.45024 10.057 -17.7665 -1.86501 10.8673 -17.7099 -2.51298 10.1143 -18.6269 -2.78882 10.2126 -18.697 -2.74814 11.2575 -19.3684 -2.7839 11.9727 -20.1243 -2.06216 12.1339 -20.6527 -2.86374 12.4943 -21.636 -2.92671 12.7574 -22.2984 -2.19964 12.8169 -22.9568 -2.75679 12.261 -23.318 -3.1258 11.3983 -22.7128 -3.90804 11.2894 -22.2833 -4.26496 12.1264 -21.7267 -4.85914 12.7967 -21.9962 -4.32145 13.6222 -22.6577 -5.03229 13.9177 -22.9939 -5.93473 14.1815 -22.7985 -5.78006 15.1706 -22.7169 -5.05894 15.8548 -21.9121 -4.51939 15.7096 -21.7082 -5.4078 16.1426 -21.2202 -5.97998 15.4968 -20.7784 -6.35243 16.3064 -20.5065 -6.63992 15.3302 -20.9009 -7.0022 14.4716 -21.6823 -7.62174 14.3301 -21.872 -7.16037 15.1283 -22.1678 -7.48601 16.0407 -22.9483 -6.98067 15.6747 -23.1571 -7.76722 15.1406 -23.8858 -7.27558 14.775 -23.203 -7.61476 14.1019 -23.2085 -7.47276 13.104 -23.9095 -6.6705 13.1887 -23.6291 -5.71274 13.2635 -22.8191 -5.4137 12.8207 -22.2023 -5.82429 12.1203 -22.0806 -6.18205 11.0969 -21.3687 -6.20311 10.5123 -22.176 -5.79743 10.0201 -22.7667 -6.4005 9.6221 -22.223 -7.21535 9.27225 -22.7251 -7.88873 9.76269 -23.1632 -8.61962 9.24829 -22.8 -8.93231 10.151 -23.3842 -9.41034 10.8522 -24.184 -10.066 10.879 -24.2762 -10.8776 10.2999 -23.8053 -11.6249 9.86764 -24.511 -11.7057 9.16762 -25.0467 -12.4958 8.90219 -24.4805 -13.0953 8.34078 -23.7506 -12.8875 7.68091 -23.9661 -13.6348 7.07137 -23.0749 -13.7484 7.54596 -22.9429 -13.2989 6.63268 -22.7615 -12.6929 5.91624 -21.9417 -12.1705 5.78191 -22.4758 -11.6283 6.44741 -21.9272 -10.9588 5.89172 -21.8484 -10.7697 4.97688 -22.4713 -9.9753 5.06657 -22.4586 -9.26658 5.77128 -22.7395 -8.28874 5.69888 -22.3764 -8.33839 6.67114 -22.5755 -9.15819 7.26246 -22.6471 -9.47181 8.20717 -22.0714 -9.78631 9.01932 -21.9807 -10.5103 8.28223 -21.8404 -11.4694 8.63798 -22.3142 -12.2313 8.19324 -22.8585 -12.8299 8.76967 -23.7405 -12.6873 9.24773 -22.9804 -12.504 9.80012 -22.5417 -13.1055 10.4242 -21.8922 -13.655 9.90561 -21.5795 -13.9686 10.8226 -21.4525 -13.082 11.3646 -20.5688 -12.6628 11.0302 -21.1336 -12.3322 10.2956 -20.4773 -12.3239 9.62265 -19.9534 -12.7354 8.91486 -19.2262 -13.2045 9.51281 -18.6117 -13.5735 8.75859 -18.4266 -13.6465 7.78123 -18.9481 -13.0302 7.13441 -18.3662 -13.0618 6.3277 -18.4626 -13.086 5.32065 -18.5379 -13.1755 4.38551 -18.3739 -13.987 3.89419 -17.8904 -14.7277 3.35126 -17.7449 -15.7086 3.20121 -18.5772 -16.1675 3.56706 -19.5369 -16.0634 3.36693 -20.1639 -16.2604 4.07859 -20.931 -16.6453 3.64817 -20.9029 -16.9337 4.65488 -21.2699 -17.7124 5.23889 -21.5644 -18.5322 4.80983 -22.4357 -18.672 4.38464 -22.4105 -19.3955 5.02393 -22.3951 -18.9854 5.89219 -22.0937 -18.0674 6.12719 -21.6908 -17.507 6.81298 -21.9967 -16.7226 6.20551 -22.6248 -16.3818 6.89664 -22.8768 -16.988 7.67205 -23.3519 -17.8265 7.76932 -22.948 -17.8551 6.92648 -23.7433 -18.1611 6.43531 -24.098 -17.3617 5.91617 -24.898 -17.9212 5.59474 -25.1052 -16.9385 5.42172 -25.6959 -16.3209 4.85236 -25.8646 -16.2331 5.87261 -25.9375 -16.2219 6.86151 -26.6472 -16.9061 6.63471 -27.0485 -16.1326 6.17069 -26.5753 -15.5156 5.63846 -26.6081 -14.7522 6.1464 -25.765 -14.1735 6.17857 -25.4108 -13.4789 6.79409 -25.8255 -12.5134 6.73959 -25.2139 -12.4105 5.88389 -25.4513 -11.6515 6.52552 -25.9741 -10.7884 6.80404 -26.0145 -10.1843 7.66896 -26.3895 -9.22012 7.4893 -25.4496 -8.99179 7.73924 -25.1047 -9.72733 8.26769 -25.1899 -9.50942 9.26378 -25.7508 -10.2374 9.63457 -25.449 -10.4907 10.5035 -25.5306 -9.67606 11.0968 -25.9743 -9.12671 10.4644 -26.0525 -8.50343 9.74042 -25.7639 -7.95211 9.01805 -24.9047 -7.68797 9.45478 -24.4199 -7.31759 8.66509 -23.5718 -7.00592 8.10151 -23.8396 -7.17455 7.18693 -23.4197 -6.69124 6.5033 -23.8527 -6.66005 5.62905 -24.6437 -6.02396 5.67921 -24.2716 -5.814 4.75032 -24.2857 -4.86256 4.4962 -24.3367 -3.84084 4.53306 -25.1963 -3.76486 4.01554 -25.7769 -3.73589 3.23515 -25.3298 -3.27805 2.5388 -24.6238 -3.41236 1.90017 -23.7704 -3.289 1.40685 -23.3189 -2.56931 0.9006861 -22.8563 -2.00246 1.54094 -23.671 -1.42405 1.43866 -24.2146 -2.03037 2.0274 -23.9868 -2.29407 2.91368 -23.5919 -2.85875 3.60956 -22.9219 -3.53628 3.99488 -22.2712 -3.48668 3.24178 -21.4312 -2.95212 3.37329 -20.8408 -3.64533 3.69231 -20.4882 -4.56132 3.97343 -21.174 -5.02143 3.47701 -21.2687 -5.36931 2.59335 -20.6016 -4.79924 2.07739 -19.9201 -5.4622 1.81586 -18.9169 -5.27244 1.59089 -18.4856 -6.0834 1.23759 -18.4992 -5.68287 0.3198581 -18.0328 -4.90369 -0.0002371105 -17.9903 -5.66781 -0.5296089 -17.7207 -6.32026 -1.16323 -17.1572 -6.72328 -0.4264609 -16.4022 -7.33798 -0.5941799 -16.0489 -8.21739 -0.9960719 -15.169 -8.18997 -1.55033 -14.2613 -8.41406 -1.52797 -13.9404 -8.83167 -2.37923 -13.1087 -9.32615 -2.72074 -12.8118 -9.31754 -3.66026 -12.7137 -9.44428 -4.61368 -12.0654 -10.2191 -4.6683 -12.0348 -10.9949 -5.28748 -11.1487 -11.3385 -4.98036 -10.9136 -11.7826 -5.91804 -10.1233 -12.199 -6.41392 -9.85359 -11.9526 -7.33453 -9.52216 -11.2977 -8.1012 -9.71179 -10.4665 -7.64903 -10.5895 -10.7288 -8.01466 -11.1896 -10.9134 -7.25395 -12.0127 -11.2889 -6.86793 -12.8761 -11.1883 -6.35022 -13.4474 -11.9843 -6.40001 -13.3245 -12.6362 -7.2466 -13.9815 -13.3262 -6.97898 -14.6392 -12.5497 -7.18479 -14.7758 -13.3666 -7.68799 -15.5086 -13.8065 -8.09691 -15.1671 -14.6069 -7.74576 -14.3781 -14.1043 -8.15545 -13.4782 -14.2095 -7.81202 -13.6183 -15.1467 -8.03272 -13.6293 -15.4459 -7.00727 -12.724 -15.2748 -6.57487 -12.1989 -15.9714 -7.17959 -11.3927 -15.787 -7.79897 -11.9407 -16.2269 -8.56645 -11.6582 -17.0673 -8.92143 -10.8685 -17.2934 -8.37399 -11.8169 -17.489 -7.8692 -10.9747 -17.9168 -7.47098 -11.8277 -18.4866 -7.46694 -12.3793 -18.7159 -8.27193 -12.9432 -19.551 -8.29712 -13.6831 -19.2585 -7.57827 -14.03 -18.2835 -7.4433 -14.3989 -17.5531 -6.79095 -14.2815 -17.398 -5.84746 -14.2441 -16.3989 -5.74756 -14.4939 -15.4307 -5.93769 -14.4939 -14.4107 -5.97564 -13.8382 -14.748 -5.29017 -13.2694 -13.8901 -5.49263 -13.5174 -12.9822 -5.24109 -13.95 -13.1603 -4.31216 -13.0054 -13.2909 -4.01268 -12.5361 -12.4377 -3.77818 -12.1657 -11.6022 -3.44724 -13.1376 -11.5189 -3.07526 -13.319 -11.1273 -2.23561 -14.1679 -10.7553 -2.67571 -14.9533 -11.436 -2.58784 -15.2463 -12.318 -3.06315 -15.805 -13.0243 -3.44214 -15.52 -13.6966 -4.16411 -15.9088 -14.391 -4.87885 -15.0652 -14.9595 -4.65043 -14.5786 -15.2411 -3.86827 -14.7996 -15.751 -3.01655 -14.238 -16.6205 -2.9248 -14.3571 -17.5721 -3.09843 -13.6489 -17.9674 -3.5618 -13.2584 -18.843 -3.87545 -12.256 -18.928 -4.08223 -11.6316 -19.6293 -3.92283 -11.4221 -20.5132 -4.45178 -10.3754 -20.3775 -4.48198 -10.6618 -21.29 -4.25986 -11.1136 -21.329 -5.17356 -11.9359 -21.7648 -5.27735 -12.0185 -22.6453 -4.86052 -12.9112 -22.9488 -4.64548 -12.6303 -22.6169 -3.80358 -12.7903 -22.8857 -2.8344 -12.948 -21.9046 -2.69529 -12.7035 -21.4789 -1.83664 -12.472 -22.4142 -1.47334 -12.8086 -22.4613 -0.5172219 -12.4123 -21.5785 -0.1126449 -11.9362 -21.3905 0.7057961 -12.5049 -20.6714 0.2728311 -11.9413 -19.8872 0.5675831 -10.9693 -19.5852 0.4354151 -10.1829 -19.8687 -0.03636138 -10.1461 -19.4058 -0.9523429 -9.34878 -20.0222 -1.03368 -10.1199 -20.5724 -0.7718269 -9.84713 -21.1037 -0.01500348 -10.2281 -22.0051 0.04838992 -10.9645 -22.2495 -0.4740939 -10.6169 -23.1803 -0.5300749 -10.2341 -22.7197 -1.27713 -9.6101 -22.4059 -1.95822 -9.89876 -23.2489 -2.45771 -8.88314 -23.4631 -2.49198 -8.08245 -22.8171 -2.56455 -8.6107 -21.9744 -2.39323 -8.06596 -21.1144 -2.60216 -7.20093 -20.7416 -3.00703 -7.405 -21.0637 -3.88839 -8.31898 -20.6165 -3.93657 -8.08626 -19.7973 -3.43918 -7.89754 -18.8205 -3.68937 -8.31267 -18.3429 -4.49714 -7.52249 -18.109 -5.00955 -6.89967 -18.7292 -5.65065 -6.66565 -19.5046 -5.00748 -6.22403 -18.6491 -4.69909 -5.59366 -17.9752 -5.07259 -6.5009 -17.5391 -5.16034 -6.64594 -16.6184 -5.17532 -5.8446 -15.9846 -5.05504 -5.18986 -16.3743 -5.73306 -4.84826 -16.383 -4.88159 -4.08539 -16.4703 -4.16379 -3.18031 -16.2624 -3.84994 -3.58387 -15.9901 -4.74481 -3.02966 -15.55 -5.49278 -2.34339 -16.1092 -5.08572 -1.3722 -15.8455 -4.84486 -0.470045 -16.2054 -5.0264 -0.255762 -17.1454 -4.60453 --0.7457 -17.1386 -4.76713 --1.30197 -17.455 -3.97378 --1.52378 -16.5188 -4.08672 --1.55326 -15.7165 -4.68847 --1.5074 -16.5421 -5.25506 --2.25809 -17.1844 -5.18451 --2.65504 -17.6438 -4.39342 --1.85033 -17.9663 -4.81681 --1.61445 -18.0469 -5.80734 --1.99538 -17.5296 -6.57295 --2.64806 -16.8477 -6.73968 --3.13295 -17.6934 -6.82695 --3.94558 -18.2439 -7.04354 --3.19658 -18.8099 -6.75384 --2.29282 -18.9331 -7.06731 --1.52388 -19.1338 -7.60263 --0.50016 -19.1715 -7.6631 -0.02893357 -20.0341 -7.86189 -0.879805 -19.7437 -7.36999 -1.39065 -20.6632 -7.29263 -2.00783 -20.2848 -6.57859 -1.98505 -20.2923 -5.51693 -1.93014 -20.1799 -4.50122 -1.66384 -19.2842 -4.26756 -1.33188 -18.7798 -5.07338 -0.924879 -18.215 -5.75437 -0.281352 -18.6205 -6.36045 --0.46197 -18.6194 -5.69552 --1.01354 -19.454 -5.85052 --1.06623 -20.0833 -5.09402 --1.79907 -19.4031 -4.99588 --1.95402 -20.0508 -5.78798 --2.78056 -20.5601 -6.07407 --2.87652 -21.5599 -5.96581 --3.08444 -22.5227 -5.79994 --2.51443 -23.2361 -5.54323 --2.62075 -24.1438 -5.74728 --3.14591 -23.7364 -6.4775 --2.60055 -22.921 -6.67483 --1.7608 -22.3635 -6.94795 --1.00759 -23.0302 -7.21135 --1.40602 -22.935 -8.15637 --0.383303 -23.1973 -8.3611 --0.904878 -24.0192 -8.54128 --1.93159 -24.1771 -8.53924 --1.54813 -25.0241 -8.90546 --2.48717 -25.507 -8.90731 --2.31961 -24.9429 -9.7433 --1.3139 -24.9982 -9.9403 --1.35077 -24.8193 -10.9172 --1.09828 -23.8617 -10.9013 --1.79857 -23.8327 -11.6283 --1.10098 -24.0251 -12.3463 --0.260163 -24.3476 -12.6669 -0.06457897 -23.7118 -11.9667 -0.481761 -23.8573 -11.1213 --0.08467393 -24.3736 -10.5204 -0.159555 -25.3618 -10.4359 -0.585903 -25.6852 -9.57399 -0.888645 -25.1924 -8.70516 -1.46047 -25.3578 -7.90827 -2.02115 -24.5741 -7.67996 -2.62366 -23.9961 -8.28341 -2.91563 -23.0574 -8.36998 -3.04013 -22.6278 -9.24963 -2.10019 -22.2723 -9.02423 -2.07836 -22.3093 -8.01571 -2.89073 -22.45 -7.3571 -3.60466 -22.9629 -6.82286 -3.35531 -23.5823 -6.01985 -2.58623 -23.9055 -5.47614 -1.65281 -24.1354 -5.4704 -2.05814 -25.0091 -5.61409 -1.88832 -25.9741 -5.70178 -1.33279 -25.9689 -6.45987 -0.755589 -25.8019 -5.60801 -0.36313 -24.8479 -5.45965 --0.08486583 -24.0306 -5.09963 --0.39639 -23.5281 -5.90698 --1.26208 -23.2841 -5.50261 --1.23603 -22.7466 -4.64023 --0.473321 -23.2066 -4.33011 --0.833291 -22.6354 -3.59845 --0.280257 -21.9963 -3.09667 --0.801465 -22.4105 -2.40293 --1.72251 -22.8406 -2.41875 --1.88699 -23.4735 -3.11239 --1.50577 -23.7868 -2.25046 --0.842954 -24.209 -1.55713 --1.68159 -24.7124 -1.46813 --2.61685 -24.5135 -1.12693 --3.26661 -25.1804 -0.6111219 --3.25878 -24.6679 0.2484741 --3.26593 -25.623 0.4409011 --3.403 -26.5583 0.07746672 --2.44786 -26.8456 0.3505171 --2.4426 -27.5194 -0.4223659 --2.53993 -26.7048 -0.9286269 --1.5061 -26.7195 -0.7734789 --0.488857 -26.5933 -0.7408599 --0.547752 -27.4631 -1.1149 --0.455211 -28.292 -1.6611 -0.147428 -27.8905 -2.35074 -0.865398 -28.5111 -2.14486 -0.764268 -27.8731 -1.32737 -1.56887 -28.4468 -1.15464 -2.48415 -28.3955 -0.8138859 -3.00143 -29.2492 -0.7289739 -2.4316 -29.2354 -1.56403 -2.05224 -30.0973 -1.10703 -1.65015 -30.6091 -0.3247229 -1.86513 -31.6054 -0.2183859 -0.961089 -31.7723 0.1733171 -0.189929 -32.4064 -0.1061039 -0.697018 -32.9814 0.5731091 -0.389864 -32.2173 1.25554 -0.06640627 -31.9852 2.19748 --0.339845 -31.052 2.14994 --0.736797 -31.4326 2.95926 --0.759485 -30.4705 2.88988 --1.00438 -29.5907 3.1827 --0.221612 -28.9321 3.44838 --0.350264 -28.4291 4.34094 --0.347768 -29.3287 4.465 -0.29616 -30.1327 4.73401 --0.388002 -30.7942 4.4101 --1.13064 -31.1238 3.81154 --0.977102 -32.1049 3.57194 --1.92608 -31.9271 3.85817 --2.34329 -31.0181 4.1372 --3.04194 -31.1308 4.83507 --3.09548 -30.2079 5.036 --3.83927 -30.1532 4.2797 --4.02441 -30.3427 3.33151 --4.77726 -30.7948 2.86894 --5.52583 -31.4254 2.88787 --6.21232 -30.9263 3.46972 --5.56351 -30.9227 4.31293 --6.49062 -30.4719 4.40573 --6.53955 -31.4086 4.73507 --6.37764 -32.346 4.45462 --5.9887 -33.0778 3.90489 --5.13975 -32.6779 3.69433 --4.59728 -32.3888 2.95105 --4.72449 -32.0716 2.04511 --3.94752 -31.5173 1.75863 --4.0073 -32.3249 1.2369 --4.46433 -33.1036 1.58011 --5.22205 -33.7399 1.22942 --5.27743 -32.9271 0.7599031 --5.59462 -31.9602 0.8182211 --6.23636 -31.2115 0.8920231 --5.50657 -30.5697 0.5680871 --4.7419 -30.3385 1.04092 --4.84283 -29.4106 1.35961 --4.96879 -28.5093 0.9464241 --4.68548 -28.3495 1.89226 --5.55883 -27.9145 1.64231 --6.51514 -27.93 1.77374 --7.20609 -27.7352 1.04279 --7.22647 -28.381 0.3038501 --7.20602 -27.8218 -0.5279949 --6.83696 -27.8503 -1.52527 --7.43494 -27.1215 -1.82155 --7.15331 -27.1002 -2.75658 --7.4386 -27.7524 -3.50886 --7.0072 -28.6554 -3.50201 --7.77704 -28.9357 -3.97869 --7.451 -29.8245 -4.36636 --6.865 -29.0939 -4.79434 --6.52124 -28.825 -5.66168 --7.48414 -28.9513 -5.90745 --7.26983 -28.0352 -6.21471 --7.27231 -27.7579 -7.09242 --7.59083 -27.2816 -7.86856 --8.10812 -26.9303 -8.72727 --7.33452 -26.4605 -8.47603 --7.11372 -26.2866 -9.43274 --7.57525 -25.9631 -10.1821 --7.2654 -26.5414 -10.8972 --7.45943 -25.9878 -11.6464 --7.57278 -25.0385 -11.2704 --6.74451 -25.3228 -11.7568 --6.22997 -25.4739 -10.9056 --6.41343 -24.4909 -10.9319 --5.57593 -24.2798 -10.3557 --5.41061 -23.4526 -10.9818 --5.14117 -22.6092 -10.6934 --5.76242 -22.6569 -11.3925 --6.7976 -22.6567 -11.3599 --6.71084 -22.8939 -12.3041 --6.33011 -23.6551 -12.8157 --6.50669 -24.4498 -12.2349 --7.26414 -24.7065 -12.8408 --8.20588 -25.0408 -12.6962 --8.35991 -25.9117 -12.9691 --8.84432 -26.0456 -12.117 --9.66475 -25.658 -11.706 --10.0149 -25.8595 -12.5939 --10.4889 -26.6596 -12.9548 --10.0398 -27.5057 -12.8818 --9.74446 -27.9801 -12.0077 --10.0395 -27.1028 -11.5774 --9.16283 -27.3536 -11.5016 --8.63258 -27.6493 -12.2357 --8.21989 -27.3571 -13.1375 --7.36546 -27.1035 -12.8035 --6.56165 -27.6909 -12.7739 --6.92779 -27.3224 -11.9192 --6.20789 -27.326 -11.2551 --5.38201 -27.6882 -11.6669 --5.09614 -28.3532 -10.9887 --4.33074 -27.8315 -11.297 --3.57087 -28.1019 -11.7589 --4.01677 -28.5286 -12.548 --4.13631 -28.412 -13.5274 --5.0833 -28.3213 -13.7567 --4.7085 -27.3942 -13.6301 --5.46409 -26.8569 -14.2117 --5.12717 -26.6317 -15.1242 --4.5427 -27.2581 -15.8088 --4.07003 -26.4511 -15.469 --3.22708 -26.1929 -15.1377 --2.76246 -27.1005 -14.9072 --2.26413 -26.1499 -14.9771 --1.7344 -26.9346 -15.2958 --1.7762 -26.3711 -16.0667 --1.225 -27.265 -16.127 --1.22796 -27.6978 -17.0324 --0.976136 -28.6228 -16.6486 --1.75632 -28.7759 -16.0345 --1.55244 -29.5721 -15.5572 --0.762712 -30.1146 -15.973 -0.147299 -29.815 -15.7262 -0.987057 -29.8055 -15.1261 -1.23451 -30.0418 -16.0479 -1.71649 -30.8914 -16.0712 -0.961962 -31.1365 -16.7152 -0.02418527 -30.7772 -16.7453 --0.511915 -31.6475 -16.7047 --0.667821 -31.4968 -15.6946 --1.63282 -31.5051 -15.4508 --2.04999 -31.6738 -14.5528 --2.73423 -32.3755 -14.2808 --2.92936 -32.8055 -13.3369 --3.46398 -32.9854 -12.4901 --4.01257 -33.3658 -11.6825 --4.7071 -34.0254 -11.8421 --5.01486 -33.6103 -10.9299 --5.83397 -33.8285 -10.4489 --6.30182 -32.9325 -10.3192 --6.55507 -32.5712 -9.42857 --7.27685 -32.2512 -8.7861 --7.61478 -31.5709 -9.3855 --6.66392 -31.2019 -9.37976 --5.85341 -31.6644 -9.04484 --5.30012 -30.879 -9.34453 --5.50362 -30.5804 -8.45666 --5.56171 -29.5825 -8.66459 --5.09959 -28.8928 -8.12323 --4.52943 -28.8629 -7.24156 --3.99179 -29.5537 -7.72675 --4.87345 -29.939 -7.39607 --4.3656 -30.7337 -7.28398 --4.07816 -31.6939 -7.06469 --4.76335 -31.4754 -7.86069 --4.63207 -32.4037 -8.18455 --4.99642 -33.3683 -8.11005 --5.83347 -33.7622 -7.67662 --6.04665 -34.7859 -7.66501 --5.33471 -34.7159 -8.40546 --4.46125 -34.8036 -7.85699 --3.57724 -34.5616 -7.54004 --3.20007 -34.9315 -6.66001 --2.21406 -34.9687 -6.50532 --1.32859 -34.6004 -6.78729 --0.880781 -33.7668 -6.58258 -0.122989 -33.7022 -6.40215 --0.170705 -33.8284 -5.39013 -0.542235 -33.6247 -4.743 -0.01403107 -33.2385 -4.03061 -0.416977 -32.4661 -3.47936 -0.02636687 -31.9669 -4.22353 --0.756313 -32.4901 -4.63028 --0.96685 -31.6725 -5.20239 --1.88555 -31.3385 -5.03985 --2.56933 -30.8344 -4.49313 --2.5664 -31.7667 -4.23766 --2.84033 -32.3345 -5.02727 --3.82574 -32.0247 -4.91663 --4.02821 -32.8633 -4.39882 --4.79357 -33.2158 -4.93567 --5.08113 -34.1408 -4.7498 --5.7345 -34.3773 -4.12364 --6.52846 -34.9989 -3.92108 --6.10273 -35.321 -3.15955 --5.84244 -35.0906 -2.22417 --6.3493 -35.9865 -2.04862 --5.94517 -36.6942 -1.41354 --5.97794 -35.858 -0.7871299 --6.74654 -35.7986 -0.1499369 --6.82672 -34.8082 -0.06300748 --6.56674 -33.8328 -0.1553539 --7.2328 -33.1857 0.1366111 --7.99515 -33.3835 0.7487401 --8.62549 -33.9901 1.22033 --9.34323 -33.9301 0.5744511 --9.94322 -33.3465 0.02430462 --9.74597 -32.4133 0.4133631 --10.1684 -31.5015 0.3464731 --11.151 -31.4641 0.5020301 --11.6215 -30.9123 -0.2030039 --11.1368 -30.2891 0.3854301 --11.548 -29.8592 1.21589 --12.6373 -30.1341 1.19904 --13.2867 -30.2812 0.4992201 --13.9817 -30.0981 1.19465 --14.8805 -30.5032 1.27396 --15.4314 -31.089 1.91721 --14.8335 -31.4838 2.54904 --15.5292 -31.7516 3.19795 --16.4036 -31.3275 3.34382 --17.2506 -30.7365 3.24162 --16.9426 -30.9081 2.33926 --16.7779 -30.0835 1.82785 --16.1553 -29.9589 2.57126 --15.0869 -29.9666 2.528 --14.9451 -28.977 2.59385 --15.7194 -28.3105 2.59017 --15.9543 -27.4525 2.96643 --15.8702 -26.5013 3.20489 --15.2618 -27.0535 3.67276 --14.4033 -27.3427 3.31707 --13.6357 -27.6426 2.78916 --13.4526 -27.6751 1.77864 --13.7893 -26.9904 1.23749 --13.6991 -27.1385 0.2960291 --14.104 -28.0058 -0.1130319 --13.4759 -27.8942 -0.9128399 --12.9239 -27.3973 -1.57342 --12.7445 -26.8662 -0.8346949 --12.0111 -26.2192 -1.10914 --11.8515 -26.866 -0.3267719 --11.3487 -27.6841 0.06945492 --11.0791 -27.9426 -0.8166949 --10.1005 -28.3251 -0.9231759 --9.36329 -28.7123 -1.5273 --9.77986 -29.1057 -2.27534 --9.61585 -30.0013 -1.91502 --9.75317 -31.1147 -1.83093 --9.68498 -30.9236 -0.8793729 --8.7357 -30.851 -0.7150829 --8.28037 -30.0321 -0.7729789 --9.15513 -29.8222 -0.3643189 --10.0262 -29.7061 0.1294911 --10.0606 -29.2671 1.07186 --9.52147 -28.458 0.7556741 --10.1087 -27.6025 0.8561291 --9.53179 -26.7529 0.6004121 --9.34078 -25.7901 0.3858071 --8.33267 -25.5675 0.3386031 --7.68459 -25.3726 0.9745741 --7.43072 -26.1455 1.60005 --7.34602 -26.9298 2.12404 --8.0018 -27.2911 2.81301 --7.7038 -28.2451 2.87921 --8.21383 -28.1989 3.69653 --8.54661 -29.1275 3.74865 --8.86498 -29.2846 2.83737 --8.87338 -30.1372 2.37586 --9.85997 -30.386 2.52784 --10.4924 -30.2201 3.17992 --11.1482 -30.6719 3.72177 --11.1193 -30.5311 4.78488 --11.0996 -31.3894 5.32681 --11.7457 -31.9448 4.97306 --11.3606 -32.8001 4.83623 --11.9832 -32.9243 5.6258 --12.7914 -33.5503 5.7888 --12.5611 -33.6306 6.78019 --12.2953 -34.4923 6.23625 --11.6441 -34.0194 5.63067 --11.0172 -33.3924 6.0716 --10.3559 -32.6466 5.868 --9.84982 -31.9281 5.52081 --9.3162 -31.6042 6.27711 --9.91195 -30.7939 6.44743 --9.4695 -30.2407 7.20479 --9.84419 -29.3959 6.87219 --9.52942 -28.4614 6.80415 --8.7354 -28.4048 7.42659 --8.11155 -28.9294 6.76135 --7.15942 -29.3692 6.84382 --7.17706 -28.9015 5.95513 --7.05746 -29.1112 4.97361 --6.29676 -28.4266 5.02954 --5.61739 -27.7924 5.35387 --5.16213 -26.9781 5.137 --5.51372 -26.4432 4.38017 --4.68885 -26.4479 3.82319 --5.05924 -26.391 2.91518 --4.76006 -27.3053 2.76286 --3.93485 -27.6365 3.21852 --3.18369 -27.7108 2.52604 --3.17204 -28.446 1.89714 --3.45552 -27.8842 1.12934 --2.81722 -28.5809 0.8344961 --2.7704 -29.4673 0.4301531 --2.17301 -30.1634 0.9266991 --2.66834 -30.9561 0.4182791 --2.54031 -31.9102 0.3959231 --1.94688 -32.4724 -0.2143409 --1.99011 -31.6136 -0.7083849 --1.90272 -32.474 -1.26499 --2.17053 -32.0833 -2.16425 --1.77033 -31.7624 -3.05559 --1.21428 -31.2006 -2.48993 --0.360399 -31.5813 -2.67904 --0.458845 -32.5009 -2.24463 -0.414483 -32.764 -1.9161 -0.958047 -32.929 -1.10683 -0.857245 -33.9309 -1.1363 --0.11235 -33.6957 -0.8697039 --0.587633 -34.4517 -1.22852 --0.456469 -34.7918 -0.3372039 --0.511243 -35.6396 0.3102441 --0.07963933 -36.4274 -0.06488348 --0.408271 -35.8679 -0.8275969 --1.04439 -35.2898 -1.34844 --1.74473 -36.0523 -1.19471 --2.59566 -35.78 -1.54295 --2.4239 -35.3803 -2.39169 --1.63869 -35.8082 -2.84282 --0.973177 -36.5427 -2.66819 --0.299181 -37.2599 -2.85176 -0.35901 -36.9402 -3.52274 -0.153375 -36.1217 -3.99497 -0.602714 -35.3732 -4.58523 -1.36403 -35.695 -4.11407 -1.13624 -36.4944 -4.75868 -1.95605 -35.9361 -5.01615 -2.08005 -35.6277 -5.91686 -1.98913 -36.5847 -5.80777 -2.88073 -36.5706 -6.21002 -2.86723 -35.7079 -6.72484 -2.53392 -34.7625 -6.75886 -2.99056 -33.8852 -6.72324 -3.13312 -32.9534 -7.03741 -3.82661 -33.0429 -7.78904 -3.05067 -32.473 -8.20499 -2.10805 -32.3276 -8.4991 -2.03354 -33.0898 -7.91915 -1.1762 -32.7337 -7.57395 -0.916799 -31.8761 -7.18013 -0.73491 -32.5249 -6.34246 -0.745324 -31.744 -5.67489 -1.33584 -31.0485 -5.28121 -2.25507 -31.5261 -5.23328 -2.80718 -30.7049 -5.04458 -3.33137 -30.1322 -4.47059 -3.97492 -30.7238 -5.03206 -4.54957 -29.8912 -4.81308 -4.28569 -28.9254 -4.92268 -3.73862 -28.3431 -4.26754 -3.09364 -27.929 -3.60119 -2.279 -27.6443 -3.14127 -1.55312 -26.9725 -2.8759 -1.19627 -26.1231 -2.52458 -1.03391 -25.8475 -3.48845 -1.83093 -25.2086 -3.34491 -1.21103 -24.3901 -3.18723 -0.410133 -23.6833 -3.28363 -0.724984 -23.6856 -4.19096 -0.709613 -22.7732 -3.82177 -0.529672 -22.2189 -4.63617 -1.03514 -21.5481 -5.19575 -1.97146 -21.5503 -4.70378 -2.88473 -21.2971 -4.72042 -3.31385 -21.825 -3.95996 -2.8572 -21.6083 -3.09096 -1.87242 -21.3224 -2.95046 -2.62274 -20.9591 -2.33327 -3.17574 -21.6194 -1.7722 -4.14737 -21.6816 -1.74102 -3.82457 -21.3974 -2.66535 -4.78828 -21.1266 -2.88471 -5.49353 -20.836 -3.57195 -4.61718 -20.2537 -3.55507 -4.82737 -20.0048 -2.59484 -5.48616 -19.2691 -2.75022 -5.07699 -19.1145 -1.87406 -4.99075 -18.1701 -1.61066 -4.03136 -18.5348 -1.63927 -4.15947 -17.585 -1.90669 -3.66141 -17.2229 -2.73579 -2.70217 -17.1157 -3.14992 -2.61133 -17.7758 -2.4429 -1.70015 -17.7168 -2.05843 -1.63764 -18.5066 -1.4912 -1.62861 -19.3919 -1.15111 -0.61747 -19.4552 -1.13758 -0.992767 -20.4298 -1.2495 -1.31512 -20.3418 -2.15929 -0.42165 -19.9891 -2.45045 --0.57002 -19.9023 -2.36026 --0.930017 -19.0558 -2.84128 --0.271876 -18.3675 -2.88757 -0.445859 -17.8202 -3.22805 -0.50654 -16.8849 -2.93476 --0.03413963 -16.9235 -2.14862 -0.843417 -16.6817 -1.80023 -0.196545 -15.9239 -1.84942 -0.06232547 -15.5097 -0.9087939 --0.23593 -14.5751 -1.20143 --0.167174 -13.7989 -1.85691 --0.487251 -12.8323 -1.92537 --1.29926 -12.2589 -1.87453 --0.911351 -11.8874 -1.05131 --0.384124 -12.3207 -0.3850729 -0.467525 -11.8433 -0.2822339 -0.63973 -12.6824 -0.8651389 -1.3566 -13.1636 -0.3727199 -2.35407 -13.0462 -0.09508098 -1.87928 -13.3691 0.6990161 -2.67565 -12.7658 1.05821 -1.93313 -12.9289 1.76265 -1.34931 -13.3911 2.43258 -0.794268 -12.5214 2.42501 -0.153415 -13.1004 2.07843 -0.178592 -13.0078 3.10963 -0.524956 -13.9704 3.11165 -1.53156 -14.0132 3.19736 -1.71359 -14.955 2.98557 -1.93256 -15.7897 2.7653 -2.06459 -15.4245 1.8613 -2.65987 -14.945 2.49717 -3.06078 -15.8514 2.20276 -2.58705 -16.5574 1.75196 -3.06309 -16.2656 0.9217101 -2.88813 -17.105 0.3392571 -3.64971 -17.4046 -0.2114959 -4.45519 -17.9561 -0.05997188 -4.29051 -17.2031 0.6092351 -4.13369 -17.8406 1.35575 -4.00324 -16.9198 1.70055 -4.9654 -16.7698 2.03593 -4.8595 -15.9876 2.65586 -4.88136 -15.73 3.67585 -5.80358 -15.3276 3.60176 -6.57166 -15.5924 2.98275 -7.17685 -14.9982 3.41853 -7.01784 -14.0136 3.71085 -7.72182 -13.2857 3.55628 -7.5624 -13.0178 2.56559 -8.14637 -13.488 1.93623 -7.92311 -14.1143 1.26338 -7.13224 -13.7527 1.70324 -6.17747 -13.6724 1.64618 -5.60247 -12.935 1.79794 -6.21141 -13.0311 2.5432 -6.3332 -12.4984 3.42267 -7.09366 -11.8126 3.40877 -7.14761 -12.1946 4.24342 -7.22227 -11.8649 5.16594 -6.28327 -11.9619 5.55196 -6.05591 -12.3594 6.48994 -6.96258 -12.2167 7.02597 -7.17089 -11.2613 6.72332 -7.96803 -10.7203 6.56381 -7.8604 -11.5484 6.07592 -8.27153 -12.3343 6.59897 -8.27736 -12.4939 5.59568 -8.11177 -13.2946 4.99201 -8.69217 -14.0784 5.21071 -8.98387 -15.0048 5.62814 -8.31661 -14.8626 6.277 -8.16536 -14.2274 7.04688 -8.78818 -14.9842 7.21579 -8.86161 -15.7153 7.92897 -9.34962 -15.0732 8.60808 -8.82617 -14.4165 9.06482 -7.86269 -14.3018 8.85571 -7.32975 -14.9175 8.27077 -6.93507 -14.8359 9.21417 -5.97861 -14.6327 9.361 -5.76179 -13.6579 9.51383 -5.83498 -14.3353 10.3086 -5.56235 -15.2154 10.1213 -4.97111 -15.5759 9.39779 -4.97547 -16.5043 9.51957 -5.93961 -16.5261 9.61539 -6.34754 -16.3269 10.5453 -6.81397 -16.5627 11.4128 -7.74164 -16.2191 11.3764 -7.95084 -16.0332 10.3927 -7.46729 -15.2378 10.7714 -7.11819 -14.4148 10.5322 -6.78388 -14.199 11.4343 -6.21586 -15.0746 11.3899 -5.51534 -15.7988 11.4302 -5.68739 -16.6118 11.942 -6.2412 -16.9314 12.7069 -5.90153 -17.6983 12.2225 -6.65548 -18.2471 12.0331 -6.68724 -18.933 11.4054 -6.61509 -19.2863 10.4868 -7.18091 -19.3185 9.63424 -7.05312 -18.3391 9.46843 -7.08122 -18.3595 8.45386 -8.04773 -18.3622 8.76092 -7.67101 -19.0151 8.09662 -8.28163 -19.4801 7.42341 -9.1589 -19.8519 6.99485 -9.29328 -20.1216 7.97268 -9.65087 -21.0568 7.84163 -9.55966 -20.8248 6.89521 -9.83833 -20.616 5.99148 -9.7105 -19.6579 5.56449 -10.073 -19.3215 4.72588 -10.8447 -18.6405 4.62493 -11.6387 -18.3455 5.12041 -11.4862 -18.0797 6.096 -11.0112 -18.5028 6.8993 -10.9989 -19.3437 6.29093 -10.9647 -20.0017 5.46091 -11.6915 -19.7313 4.91117 -12.3457 -20.2572 4.38944 -12.6286 -20.0153 3.44126 -13.0398 -20.873 3.40756 -13.103 -20.821 2.42337 -13.1089 -19.851 2.08783 -13.2204 -18.9466 2.62945 -13.1944 -17.9768 2.83552 -13.987 -17.3754 2.9129 -13.8976 -16.458 2.51572 -13.4982 -16.3481 3.39067 -13.3167 -15.3371 3.11086 -14.1239 -14.7813 2.87749 -14.0822 -14.9664 3.90174 -14.0952 -15.4366 4.74873 -14.0452 -14.6582 5.36334 -13.5111 -14.375 6.1075 -13.3858 -13.5418 5.65788 -12.5668 -12.9139 5.5024 -11.7001 -12.4814 5.37338 -11.3056 -13.4328 5.21158 -11.635 -14.3581 5.36317 -11.198 -15.2874 5.49238 -10.3311 -15.7221 5.24523 -9.8002 -15.7838 5.9913 -10.1546 -15.6022 6.97369 -10.8658 -15.0947 6.53863 -10.8438 -14.2298 7.10869 -11.723 -14.507 7.40902 -12.4421 -15.179 7.32751 -11.7519 -15.9846 7.14129 -11.0558 -15.6713 7.8654 -10.6811 -16.455 8.40375 -10.8155 -15.8519 9.24817 -10.9499 -15.9213 10.2237 -10.4383 -16.7658 10.5611 -10.1831 -15.9094 10.9761 -10.5314 -16.4741 11.7642 -11.4206 -16.3372 12.1379 -11.7636 -17.0324 11.5194 -12.3074 -17.1108 10.7061 -12.2612 -16.1566 10.634 -12.7345 -15.3075 10.4269 -13.2126 -15.6331 11.2934 -14.0802 -16.0132 11.5596 -14.7659 -16.7001 11.3479 -15.6853 -16.6358 10.8638 -16.0671 -16.7979 11.7476 -15.7609 -16.2544 12.5344 -15.0903 -16.2686 13.3113 -15.4613 -17.0945 12.8697 -16.1836 -17.7099 12.4822 -16.8091 -18.2433 11.9256 -17.1737 -18.5664 11.1026 -18.0477 -18.0673 11.3411 -18.7248 -18.4813 10.7993 -18.8594 -18.9269 9.87395 -19.5065 -18.3631 9.39073 -19.778 -18.2879 8.38091 -18.8583 -18.1224 8.09852 -17.9218 -17.94 8.38878 -17.8338 -17.1353 7.81957 -17.8263 -16.8713 6.87306 -17.9303 -16.5217 5.95954 -18.8579 -16.3036 6.22518 -18.9749 -17.2279 5.96216 -18.4448 -17.156 5.07423 -18.1502 -16.6044 4.28115 -18.3682 -17.3721 3.72192 -17.4752 -17.4938 3.36418 -17.3637 -16.8215 2.72243 -16.9707 -17.6037 2.21532 -16.0666 -17.4294 2.50703 -15.8446 -17.0045 3.35542 -16.1012 -17.2274 4.26125 -15.7743 -16.8361 5.16672 -15.2055 -16.0143 5.2018 -15.1814 -15.0103 5.14671 -15.3478 -14.5413 6.02271 -15.6293 -14.4512 6.98319 -15.133 -14.4495 7.88266 -14.6078 -14.3421 8.65998 -14.6309 -14.2505 9.61225 -14.9512 -14.8067 10.3418 -14.5821 -14.316 11.118 -13.957 -13.7111 11.6339 -13.0608 -13.4539 11.8512 -12.7158 -14.284 12.1503 -12.5365 -15.0984 12.6652 -13.0162 -15.6947 13.2954 -13.3721 -15.4126 14.1946 -12.7329 -16.2178 14.3753 -13.6254 -16.6406 14.7912 -14.53 -16.3142 15.0996 -14.3285 -17.2259 15.4076 -13.3263 -17.1892 15.7368 -12.3974 -17.0303 15.4481 -11.5135 -17.4388 15.5794 -10.9328 -17.7495 16.3625 -10.7748 -18.3411 17.0725 -10.6334 -18.8969 16.2728 -11.6419 -18.9209 16.0434 -11.7429 -19.8755 16.193 -12.1049 -19.5946 15.3793 -11.4963 -20.3817 15.0564 -10.6101 -20.0931 15.1305 -10.5206 -20.6486 14.2993 -10.7772 -19.8441 13.8223 -11.0142 -18.878 13.7167 -11.9871 -19.0792 13.7971 -12.618 -18.5345 14.3825 -12.4211 -18.1976 13.4555 -13.0555 -17.3804 13.3697 -13.3799 -18.0548 14.0328 -13.6604 -18.2793 13.1366 -13.1845 -18.1826 12.2842 -13.5287 -18.4204 11.3638 -13.7724 -18.0138 10.5001 -13.0649 -18.1861 9.78918 -13.156 -18.0834 8.73687 -12.9574 -18.1378 7.72102 -13.3069 -19.0813 7.4817 -13.7407 -19.5249 6.73852 -14.5287 -20.2277 6.74153 -15.1868 -20.9136 6.9128 -15.7649 -20.1707 6.63356 -16.3889 -20.9141 6.24113 -16.5886 -21.6155 5.55567 -16.1157 -22.3306 5.11836 -16.0531 -22.6098 4.18776 -16.2095 -22.6962 3.2344 -16.7256 -23.2651 2.60893 -17.5102 -23.7065 3.11611 -18.4703 -23.4053 3.36056 -19.0693 -22.9775 2.68477 -19.8192 -23.0195 1.95786 -20.3637 -22.8699 2.84435 -21.322 -22.4882 3.12053 -21.5567 -22.7301 4.04867 -21.549 -21.7481 3.97595 -21.0082 -20.9094 3.81826 -21.8826 -20.4569 3.7735 -22.0214 -20.8302 4.72657 -22.7386 -21.4975 5.09081 -21.7995 -21.7054 5.20251 -20.8566 -21.9048 4.93589 -20.6404 -22.8599 4.82119 -20.7561 -23.0472 5.71458 -21.0563 -23.8574 6.32326 -20.2487 -23.5412 6.7578 -20.9352 -23.0948 7.3379 -21.6897 -23.2367 7.89256 -22.4406 -22.9273 8.54203 -23.2685 -22.593 8.94899 -23.5834 -21.8985 9.61068 -23.0278 -21.1476 9.14305 -23.867 -20.7215 8.72788 -23.8374 -20.787 7.69991 -24.4179 -20.077 7.24585 -23.6264 -19.5281 7.02086 -23.4435 -20.0672 6.21639 -23.1678 -21.088 6.16858 -23.1467 -21.8085 6.90456 -22.1506 -21.5094 6.69907 -21.1973 -21.4819 6.92606 -21.0171 -20.5428 6.7711 -21.487 -19.6936 6.75878 -20.5629 -19.4386 6.90618 -19.9985 -20.0258 6.17768 -20.1115 -21.0785 6.18236 -19.3248 -21.623 6.28505 -18.4337 -21.3014 6.62267 -17.8302 -21.5718 7.36741 -17.0878 -21.2281 7.94202 -18.0028 -20.9761 8.23412 -18.9927 -20.701 8.4125 -18.7137 -21.6375 8.73744 -19.2524 -22.0995 9.49334 -18.7086 -22.2619 10.3831 -17.8389 -22.0463 9.93282 -18.0998 -21.3577 10.502 -18.6046 -20.4705 10.6095 -18.3064 -20.7582 11.5391 -17.2499 -20.6234 11.5099 -16.7733 -20.5792 12.3159 -16.1025 -20.3095 11.5627 -15.3817 -19.8425 12.2067 -14.7469 -19.8778 12.8762 -14.6994 -20.1232 13.8701 -14.1051 -19.8191 14.6205 -13.4749 -19.2103 14.2382 -12.9895 -19.5755 13.3715 -13.0599 -20.1447 12.5218 -13.6879 -20.8666 12.1303 -13.6325 -21.6477 12.7415 -13.9034 -22.0996 11.8569 -14.0614 -22.0642 10.8381 -14.6849 -22.5583 10.2732 -14.5732 -22.9638 11.1215 -15.1017 -22.3891 11.8122 -15.9051 -22.7113 12.2754 -16.2753 -22.1337 11.5461 -16.5115 -22.5365 10.6879 -17.3168 -23.0861 11.0035 -17.4645 -22.2728 11.5115 -17.2379 -21.6492 12.1977 -17.2829 -22.4796 12.7562 -18.1832 -22.7439 13.0811 -17.596 -22.9665 13.7818 -16.9791 -23.5318 13.3022 -16.2667 -24.1316 13.7055 -15.2491 -23.9898 13.7683 -14.3598 -23.9543 13.9836 -14.5485 -23.0442 14.1794 -13.7892 -22.4389 14.2708 -13.4683 -22.5891 13.3201 -12.8258 -23.358 13.4779 -13.5089 -23.7435 12.8382 -13.8857 -24.6013 12.5539 -13.773 -25.3558 11.8657 -14.0552 -24.9295 10.9401 -14.5626 -25.6878 10.4627 -15.4461 -25.3208 10.1989 -14.8627 -24.6992 9.83406 -14.534 -24.9829 8.88792 -14.7117 -25.4011 8.02876 -14.4857 -24.4755 7.67402 -14.1342 -24.1674 6.74341 -13.4078 -23.9976 7.42437 -12.6555 -23.5599 7.73617 -12.3974 -24.2314 7.04237 -12.9702 -24.6645 6.32612 -13.6842 -25.2158 6.74853 -13.0235 -25.7514 7.24851 -12.2514 -26.3636 7.26753 -12.8314 -27.0606 7.81207 -12.6038 -27.8513 7.30983 -12.5735 -28.8431 7.33749 -12.2396 -29.4098 6.44482 -12.0508 -29.6759 5.49806 -11.1502 -29.3207 5.49548 -10.3558 -30.0383 5.46283 -10.4545 -29.5513 4.58895 -10.8345 -30.4871 4.40751 -11.1571 -30.5707 3.37287 -10.9448 -31.4042 2.91588 -11.1107 -31.21 1.93477 -11.8684 -31.6677 2.23084 -11.6723 -32.6405 2.36172 -12.2804 -32.985 1.5789 -13.0345 -33.188 2.21018 -13.4776 -32.3313 2.48776 -13.2799 -32.4183 3.54032 -12.38 -32.4992 3.93767 -11.7363 -33.0756 4.53455 -11.9752 -32.2608 5.10807 -12.3484 -31.8398 5.90166 -12.7273 -31.1033 6.55477 -13.5625 -30.7935 6.85635 -14.5374 -30.4824 6.92466 -14.0327 -29.6682 6.60034 -14.7562 -29.8488 5.87278 -15.5812 -29.4135 6.22909 -16.351 -28.7498 5.90148 -17.286 -28.7827 5.5711 -17.2101 -29.4979 4.86066 -18.2142 -29.3376 5.0335 -18.9499 -28.9752 5.62912 -18.8247 -29.505 6.46314 -19.3614 -28.6635 6.69959 -18.6793 -28.0041 6.5193 -17.9241 -27.8167 7.09957 -17.2506 -28.3906 7.42499 -17.2351 -27.6137 8.06259 -16.4655 -26.9911 8.11316 -16.3136 -26.0986 8.46319 -16.5576 -26.6716 9.24722 -15.9936 -27.4849 8.98096 -15.9024 -28.325 9.56145 -15.9493 -28.6549 8.59266 -15.0119 -28.8377 8.54455 -14.7886 -29.4459 9.29907 -13.9723 -29.4755 8.70547 -13.2021 -29.772 8.06898 -12.4609 -29.198 8.44785 -12.1864 -28.6542 9.21665 -12.5754 -27.8736 9.69171 -11.5337 -27.8182 9.72062 -11.1293 -27.2653 10.4702 -10.7706 -26.8435 9.61684 -10.4119 -27.5741 9.09648 -9.67231 -27.2997 9.7162 -9.24948 -26.9685 8.88765 -9.44275 -25.9831 8.70913 -9.68421 -25.7123 9.65043 -8.80783 -25.1966 9.79139 -8.55095 -24.237 9.62744 -8.56783 -23.4044 10.2054 -9.54485 -23.1074 10.0716 -9.24252 -22.6319 10.9331 -9.00656 -22.4687 11.8783 -8.52612 -21.788 12.5188 -7.58063 -21.5398 12.7332 -8.03518 -20.8632 12.1035 -7.37243 -20.1195 12.0151 -7.68539 -20.5901 11.1883 -7.1647 -21.3924 11.4196 -7.17981 -21.4898 10.4483 -7.90993 -21.8043 9.78448 -8.92344 -21.8076 9.74444 -9.00628 -21.1035 10.5018 -9.57446 -21.4648 11.2466 -10.4096 -21.203 10.8521 -10.803 -21.0681 11.7954 -11.0162 -20.0604 11.6974 -11.8033 -20.6984 11.6767 -12.3131 -21.5249 11.4426 -12.7873 -21.0998 10.6249 -13.5182 -20.619 10.1947 -13.6747 -20.0911 9.36468 -12.7577 -19.983 9.17493 -12.0384 -19.4029 9.54754 -11.979 -19.5386 8.63212 -11.749 -20.435 8.21792 -11.1703 -20.6209 7.38999 -11.8332 -20.7135 6.63279 -12.2643 -19.8192 6.92832 -13.0222 -20.3327 6.69309 -13.418 -20.4819 7.68552 -13.3705 -21.3375 7.29635 -12.5075 -21.6061 6.7935 -12.1022 -21.945 5.96311 -11.1334 -22.0081 6.27865 -11.0344 -23.0421 6.27601 -10.7902 -23.6714 5.45677 -10.415 -24.1962 6.27434 -10.3495 -24.7104 7.12187 -10.3194 -25.6248 7.51287 -11.1758 -25.1171 7.57312 -11.5482 -25.6893 6.78744 -10.7329 -25.8882 6.32479 -9.78489 -25.8366 5.79944 -9.07751 -25.1952 5.52148 -8.22989 -24.9789 5.82999 -8.1592 -24.329 6.49966 -7.58826 -24.9065 7.06586 -7.56061 -25.7614 6.59574 -6.56482 -25.8701 6.2969 -6.14562 -26.6806 6.23979 -6.67179 -26.4506 5.41113 -7.19327 -27.1934 5.77093 -6.81251 -28.016 6.11493 -5.9142 -27.7554 5.82514 -5.32528 -27.906 5.04563 -5.70637 -26.995 5.07576 -6.47645 -27.5915 4.67971 -6.6919 -26.9524 3.98946 -5.98767 -26.6966 3.26532 -5.0725 -26.3003 3.58836 -5.38928 -25.4908 4.10018 -5.68945 -25.1374 4.90183 -6.67885 -24.8368 4.6686 -7.49044 -24.3131 4.36011 -6.84268 -23.5632 4.54226 -6.04767 -23.6115 5.10118 -5.32773 -23.8456 5.81054 -4.42231 -24.1312 5.57109 -3.83804 -23.8855 4.74021 -3.50793 -23.1873 4.12267 -3.72672 -23.4429 3.2153 -3.9351 -23.201 2.29834 -3.8863 -24.0834 1.93382 -4.80595 -23.5955 1.99305 -5.68653 -23.6604 1.66909 -6.03855 -24.5161 1.83158 -6.52102 -24.1112 2.55885 -6.95061 -23.6561 1.7993 -7.72034 -23.001 1.72749 -8.0176 -23.9464 1.96953 -8.64399 -23.456 1.39549 -9.41492 -23.1898 0.7758301 -9.18482 -22.8796 -0.1361699 -8.8823 -21.9178 -0.1691859 -7.95912 -22.2034 -0.04778818 -6.9871 -22.1418 -0.05680968 -6.32169 -22.928 0.05137812 -6.0944 -22.4103 -0.7216199 -5.58956 -23.2502 -0.4723959 -5.7931 -23.07 -1.4354 -4.82376 -23.2824 -1.43017 -3.88781 -23.4134 -1.4872 -3.22408 -23.4939 -0.7584419 -3.0267 -22.8048 -1.43799 -2.72904 -22.949 -2.31533 -2.0127 -23.1897 -3.01016 -2.96822 -23.1114 -3.39036 -3.64681 -22.7031 -2.73805 -4.53529 -23.2184 -2.88132 -5.15892 -22.7239 -3.38909 -5.93296 -23.2106 -3.76128 -5.78365 -24.1386 -4.12915 -6.19308 -24.1198 -3.20019 -6.80716 -23.6869 -3.86208 -6.73302 -24.5277 -4.29842 -7.61487 -24.2158 -4.68194 -7.74897 -23.3994 -5.1772 -7.82792 -22.6044 -5.69422 -8.29955 -21.7287 -5.40162 -9.20053 -21.7269 -4.95995 -9.61559 -21.3885 -5.82532 -9.40583 -22.2208 -6.30772 -8.84144 -21.5762 -6.93228 -9.45234 -22.3414 -7.29506 -9.29291 -23.1579 -7.94219 -8.7587 -22.4997 -8.51473 -9.21281 -21.7891 -9.12996 -8.4158 -21.1957 -8.97225 -7.70424 -21.2533 -9.64591 -7.53949 -22.0066 -10.3182 -7.0867 -22.4891 -9.51153 -6.42001 -22.5181 -8.70625 -5.73364 -23.131 -8.42925 -5.62286 -24.1254 -8.42003 -5.55654 -24.4012 -7.47736 -5.36575 -25.3531 -7.76003 -4.62712 -25.3239 -7.0576 -5.39373 -25.3294 -6.46031 -6.14548 -26.0025 -6.24019 -7.18077 -26.0112 -6.3566 -7.94806 -26.4781 -5.88337 -8.10677 -27.4499 -5.63721 -7.76294 -27.598 -4.65677 -8.04801 -27.7039 -3.66361 -7.55408 -26.8703 -3.49585 -8.36756 -26.3047 -3.64368 -9.3362 -26.5334 -3.76371 -10.2722 -26.3511 -3.5213 -11.1084 -26.7874 -3.18128 -11.2072 -27.4833 -2.421 -11.1454 -26.8236 -1.75476 -12.1061 -26.7984 -1.88993 -12.9958 -26.9171 -1.54549 -12.9284 -26.4632 -0.6782079 -12.3161 -25.7011 -0.5467779 -12.6028 -24.7218 -0.4264899 -12.6556 -25.3131 0.4292701 -13.4288 -25.5913 0.9645151 -14.2518 -25.0061 1.05274 -14.5052 -24.275 0.4051651 -14.0582 -24.4402 -0.4720799 -13.8082 -23.9312 -1.28918 -14.2319 -24.0508 -2.21962 -13.4274 -23.7871 -2.77572 -13.0865 -23.6087 -3.76133 -13.2707 -24.2856 -4.44047 -14.1406 -24.545 -4.14306 -13.7023 -25.292 -3.68761 -14.0386 -25.6951 -4.66843 -15.0433 -25.7142 -4.36276 -14.8269 -24.9302 -4.96897 -15.3868 -24.4189 -4.24 -15.2946 -23.4547 -4.27703 -16.2167 -23.2461 -4.50542 -16.9491 -23.7255 -4.28437 -17.4923 -22.9456 -3.88588 -16.6641 -22.621 -3.47284 -15.8232 -22.1554 -3.25514 -15.6458 -22.133 -2.29331 -14.9361 -21.7056 -1.77192 -14.2524 -21.8726 -2.49504 -14.81 -21.3205 -3.14853 -15.6495 -20.8727 -2.93704 -15.1703 -20.1984 -2.37891 -15.7081 -19.5312 -2.90227 -16.0183 -19.6339 -3.86371 -15.5461 -19.3737 -4.71793 -15.9658 -18.67 -5.29029 -15.8786 -18.2356 -4.38833 -14.9764 -18.2639 -4.73806 -15.3978 -17.4961 -5.15639 -16.3737 -17.0602 -5.34423 -16.3689 -16.5067 -4.53316 -16.9765 -16.3062 -3.72958 -17.7718 -15.7647 -3.83099 -18.1128 -14.8512 -3.57039 -17.2757 -14.4584 -3.25934 -16.6488 -13.8294 -2.72542 -15.6954 -14.1938 -2.6246 -15.408 -13.264 -2.36075 -15.1016 -14.0209 -1.82528 -14.6206 -14.0133 -0.9356809 -14.7685 -14.3374 -0.08821208 -15.6028 -14.7019 -0.5401639 -15.8735 -15.6247 -0.7069929 -16.1094 -16.6051 -0.5554309 -15.4691 -17.2226 -0.8694259 -15.6121 -17.9579 -0.1142679 -14.7342 -18.2186 0.1428551 -13.8853 -18.4837 0.5881911 -13.6303 -19.3868 0.3846621 -12.7315 -19.1541 0.1002611 -12.2785 -18.781 -0.7333489 -13.2788 -18.8959 -1.11139 -13.7198 -18.0232 -1.15812 -13.9843 -17.0465 -1.53942 -13.1229 -17.0146 -1.23949 -12.8273 -16.4642 -0.5199449 -13.0084 -15.8096 0.2088021 -13.1112 -16.4642 0.9113921 -13.6966 -17.2736 0.7385281 -14.6203 -17.2241 1.11258 -15.6273 -17.3534 1.23108 -15.9301 -16.3926 1.19328 -16.167 -15.4405 1.36317 -17.0425 -15.7469 0.9498541 -17.8629 -15.2182 0.8358491 -18.7588 -15.1483 0.3855941 -17.9444 -15.4757 -0.09787118 -17.9279 -15.6607 -1.11502 -18.9461 -15.5739 -1.04662 -18.43 -15.157 -1.78923 -17.8474 -14.5127 -1.43214 -18.6678 -13.8918 -1.53267 -19.3434 -14.5593 -1.22441 -19.9448 -13.9165 -1.67982 -20.3016 -13.2105 -1.06688 -19.544 -12.9206 -1.65768 -19.2227 -12.0052 -1.47468 -18.5778 -11.2056 -1.52814 -17.6521 -11.3824 -1.15417 -17.5059 -12.1155 -1.77241 -17.082 -12.3496 -0.8819149 -17.3913 -13.3242 -0.7079829 -16.5312 -13.8821 -0.6354939 -17.1352 -14.3784 -0.01819998 -18.0565 -13.9894 0.2101861 -18.8109 -13.3898 0.03182242 -19.7025 -13.5728 0.4303421 -19.4416 -13.3448 1.3898 -19.946 -13.9508 1.96492 -19.8015 -14.8146 2.48534 -19.207 -15.5789 2.27357 -19.587 -15.3801 1.33213 -19.9004 -14.9826 0.5038281 -20.5887 -14.5659 -0.1245599 -21.2919 -15.195 0.0079754 -21.8268 -16.021 -0.3667259 -21.0726 -16.6018 -0.2237009 -20.4022 -17.0561 0.3494221 -21.2696 -17.5183 0.6261871 -21.8865 -18.2366 0.2751361 -21.2799 -17.9099 -0.4315259 -21.9362 -17.6462 -1.23282 -21.6757 -16.8263 -1.53378 -21.7622 -15.8724 -1.85993 -22.3624 -15.0185 -1.81897 -22.3082 -14.0162 -1.81103 -22.6686 -13.6309 -2.63702 -21.9987 -12.9822 -2.25182 -21.1804 -13.2642 -1.7815 -21.6413 -12.8372 -0.9601729 -20.9596 -13.1269 -0.3035129 -21.3879 -12.6589 0.4356981 -21.4897 -11.9542 1.10496 -22.1817 -11.1654 1.00499 -22.5099 -11.821 0.2279191 -23.3536 -12.1516 0.6512961 -24.0348 -11.966 -0.1504829 -24.9269 -12.0707 -0.5337359 -25.6982 -11.4738 -0.05943088 -25.8534 -10.546 -0.3807949 -26.2806 -9.88787 -0.9417309 -26.5293 -9.23632 -1.67777 -26.0299 -9.47149 -2.56934 -26.6688 -10.1435 -2.90728 -26.6893 -10.3968 -3.94174 -27.2918 -10.5794 -4.72848 -27.3172 -10.5785 -5.7645 -27.8453 -11.4316 -6.02445 -27.3012 -12.2626 -5.75543 -27.961 -12.6693 -6.26681 -27.6374 -13.5663 -5.88558 -27.8772 -13.9462 -5.04422 -26.9319 -13.8126 -4.72627 -26.8369 -13.7678 -3.71823 -26.3681 -13.2233 -2.93366 -25.8073 -13.6273 -3.65242 -25.8385 -12.6274 -3.95244 -25.648 -12.1548 -3.07618 -24.6706 -11.8553 -2.97191 -23.7876 -11.4843 -2.94817 -22.8611 -11.8332 -3.13811 -22.5856 -11.2757 -3.9022 -22.2007 -10.4323 -3.64756 -21.2205 -10.1217 -3.53511 -20.7558 -10.3695 -2.65387 -21.0698 -9.534 -2.21001 -21.3796 -9.66503 -1.25807 -20.6337 -9.00032 -1.33058 -20.6194 -9.60706 -0.5632739 -19.6303 -9.61935 -0.4039059 -18.6638 -9.65056 -0.03480318 -17.9419 -10.1328 0.4292331 -18.3419 -9.8927 1.29877 -18.4619 -8.84966 1.2952 -18.8807 -8.79515 2.22778 -19.2998 -8.65813 3.09498 -19.1228 -9.57009 3.49961 -19.6879 -10.4124 3.83382 -20.1997 -10.8605 3.14083 -20.3136 -11.802 3.40431 -21.2096 -12.1021 3.03575 -22.0085 -12.1099 2.45198 -22.3444 -12.4324 1.57153 -22.1328 -13.336 1.24382 -22.187 -13.9264 0.4201471 -22.4608 -14.7866 0.07742082 -23.1895 -15.372 0.3312191 -23.1407 -15.7333 1.25453 -23.985 -15.3002 1.0789 -23.4603 -14.9585 1.89027 -22.4195 -14.9481 2.03992 -22.0306 -14.384 2.71218 -21.2537 -14.5147 3.27402 -20.962 -15.1406 2.48127 -21.1459 -16.0674 2.14959 -22.0446 -16.4505 2.1469 -22.3591 -17.1086 2.91305 -21.7114 -17.8626 2.95936 -20.8878 -18.1721 2.53366 -21.0181 -18.5609 3.42006 -21.4609 -19.3297 2.86831 -22.2704 -19.7644 2.33214 -22.7516 -20.4003 1.66228 -22.6713 -21.1695 2.3898 -23.3634 -21.931 2.29419 -23.9988 -21.8873 3.07666 -24.4284 -22.7043 2.67701 -25.3956 -22.5596 2.27951 -25.384 -22.1825 1.35644 -25.15 -22.2411 0.3211971 -25.2705 -21.6658 -0.5292969 -24.3142 -21.3541 -0.5466199 -23.588 -22.0542 -0.3334429 -23.5415 -23.0198 -0.4940779 -22.8746 -23.0371 0.2345871 -22.0312 -23.5227 -0.1970019 -21.8002 -24.3502 0.2218071 -21.2913 -25.0181 0.8299931 -22.1779 -25.3834 1.14798 -21.7446 -25.8786 0.3867981 -21.2067 -26.6895 0.6205601 -21.4681 -27.2797 1.40048 -22.2178 -27.8615 0.9611791 -22.2405 -28.5416 0.1671061 -22.0253 -29.1803 0.8594391 -21.1766 -28.7372 0.4869451 -20.7841 -28.9568 1.43094 -19.951 -28.4595 1.77823 -19.7445 -28.4781 2.8397 -19.0263 -28.9197 2.36393 -18.4804 -29.6721 2.79756 -17.9276 -28.8742 2.76709 -17.1634 -28.8814 3.35395 -16.4301 -28.6025 2.79021 -16.2542 -28.1459 3.61319 -15.4133 -28.4568 3.21062 -14.8826 -27.6954 2.93173 -15.42 -26.9724 2.6197 -15.3368 -26.6487 1.63176 -15.9499 -26.3703 0.8685331 -16.7825 -26.099 1.39732 -16.7679 -25.0995 1.27961 -17.4103 -24.4104 1.00427 -17.6339 -23.4168 0.6795921 -18.2092 -23.3152 -0.1660229 -18.7116 -22.4843 -0.05645268 -19.2455 -22.4944 0.6821191 -19.0494 -23.3193 1.14776 -18.8271 -24.0673 1.8293 -19.3946 -24.673 1.28536 -19.8999 -25.122 1.94779 -19.59 -25.8438 2.594 -20.438 -26.1358 3.04804 -20.492 -27.0984 2.87652 -21.006 -27.171 3.74725 -21.9065 -27.6414 3.91769 -21.3803 -27.6646 4.77227 -20.4668 -27.7852 5.20785 -19.4809 -27.8458 5.0824 -18.7737 -27.1688 4.96253 -18.5002 -26.7234 5.81214 -18.791 -25.9188 5.32324 -18.1779 -25.2414 5.05507 -17.2552 -25.4908 5.22652 -16.755 -24.6588 5.05159 -15.9359 -24.1429 5.46816 -16.0255 -23.6971 6.33737 -16.0763 -24.0009 7.22411 -16.2665 -23.7036 8.15069 -17.0089 -23.8093 8.8043 -17.9867 -23.6233 8.58075 -18.2505 -24.6264 8.59636 -19.1316 -25.0869 8.72933 -19.8966 -25.288 8.23042 -19.8349 -26.0441 8.86524 -20.3411 -25.2849 9.25834 -20.6439 -24.9364 10.1343 -20.551 -24.525 11.0441 -21.4969 -24.0495 10.9478 -22.174 -24.7832 10.6338 -22.15 -25.4921 11.3486 -21.2967 -25.4958 11.8533 -20.8683 -24.6807 12.1247 -21.2876 -24.2208 12.9058 -20.8946 -24.7068 13.7719 -20.3843 -24.826 14.6094 -20.0756 -25.0142 15.6003 -19.1647 -25.2685 15.4871 -19.1507 -25.9252 16.2526 -18.46 -26.4217 15.7307 -17.5974 -26.796 15.3835 -17.7285 -27.8052 15.1261 -16.6898 -27.6529 15.0499 -16.1205 -27.5356 15.8298 -15.4223 -27.898 16.416 -14.7248 -27.6752 15.7718 -14.7949 -26.7462 15.4272 -14.0963 -26.0387 15.4734 -13.3727 -26.642 15.1974 -12.577 -26.0112 15.1393 -12.4976 -26.1096 14.1154 -12.0212 -26.6609 13.447 -11.4641 -27.3502 12.9791 -11.1732 -26.5746 12.3464 -11.9641 -25.9724 12.0095 -12.5887 -25.3388 11.522 -11.891 -25.0539 10.8173 -11.1595 -24.7442 11.4336 -10.9504 -24.7667 12.4247 -10.2758 -25.0442 13.1675 -10.0852 -25.8759 13.7777 -9.73414 -25.8163 14.7002 -10.3942 -25.3477 15.1344 -10.4079 -24.3536 15.3628 -10.2915 -23.6999 14.6116 -9.616 -24.4156 14.2288 -8.8367 -25.0383 14.3016 -8.28542 -25.8505 14.5016 -8.54928 -26.7754 14.3833 -8.27389 -27.5484 14.9277 -8.77136 -27.3185 15.7689 -9.43977 -26.7603 15.3167 -9.95525 -27.5982 15.527 -9.83695 -26.9751 16.2811 -9.74588 -26.1794 16.7955 -9.16064 -25.3577 16.6046 -8.87783 -24.9774 17.4617 -9.38927 -24.4671 16.7778 -8.9587 -23.8486 17.3993 -8.34596 -23.5415 18.0924 -8.28692 -22.5797 18.3628 -8.82571 -21.7861 18.018 -8.83679 -20.8225 17.711 -9.13341 -20.6885 16.8397 -8.6825 -21.0573 16.0707 -7.75779 -21.4619 16.1724 -8.25928 -21.7776 15.3313 -8.00777 -21.4888 14.4278 -8.66338 -22.0989 13.9832 -8.59699 -22.8368 14.7242 -7.9489 -23.5298 14.9684 -7.9474 -23.7496 13.9386 -7.75646 -23.5032 12.9596 -7.3013 -23.1784 12.1014 -6.73028 -22.5745 11.5324 -6.09088 -22.1739 12.2073 -5.0975 -22.4724 12.0615 -5.4502 -21.5785 11.7142 -5.55647 -20.5279 11.7076 -4.64705 -20.6812 11.997 -3.81497 -20.2358 12.2813 -4.22566 -20.4078 13.1806 -3.63643 -20.014 13.9276 -3.76402 -19.5365 13.0476 -4.54926 -19.0236 13.4242 -4.01852 -18.3885 13.8635 -3.009 -18.3203 13.5332 -3.32447 -17.3593 13.8897 -3.64607 -17.0395 12.9544 -3.48975 -16.1523 12.6316 -3.24271 -15.7212 13.4922 -3.5622 -15.4342 14.4223 -3.45251 -15.7886 15.3171 -2.94998 -16.566 15.2095 -2.68328 -16.7032 16.215 -1.86329 -16.4068 16.6187 -1.01774 -16.7657 16.708 -1.31893 -16.5403 17.5676 -1.40879 -17.5514 17.5515 -1.49144 -18.5287 17.7754 -2.47682 -18.3334 17.9194 -3.35142 -18.2491 18.3514 -4.05306 -17.9338 18.8816 -4.28017 -16.925 18.9857 -5.14649 -16.6523 18.4404 -5.51375 -16.4576 19.4107 -6.26039 -16.1245 18.7398 -6.7835 -15.7449 19.5853 -6.73335 -14.8933 19.113 -7.44086 -14.3328 18.7276 -8.38266 -14.1805 18.3052 -8.92402 -13.3616 18.5627 -9.91936 -13.0741 18.5753 -9.51039 -13.0645 19.4945 -10.2088 -12.9559 20.2583 -10.6256 -13.6315 20.8839 -9.84254 -13.585 21.4074 -8.84855 -13.5125 21.4069 -7.90687 -13.2061 21.6585 -7.49944 -12.3354 21.9113 -8.48718 -12.0032 21.9556 -9.0501 -11.9312 21.1528 -8.72866 -11.0953 20.6901 -8.13003 -11.7184 20.2547 -7.53979 -12.4457 20.5002 -7.31046 -12.4291 19.5357 -6.28096 -12.2807 19.4151 -6.68411 -11.4193 19.6906 -7.22942 -10.9159 19.0336 -7.43427 -11.0755 18.0475 -7.24588 -10.3235 17.4425 -8.08474 -9.99685 17.799 -8.74957 -10.375 17.1267 -8.44614 -11.0217 16.4659 -8.5643 -12.0533 16.5326 -7.82108 -12.2382 15.8899 -7.86719 -13.1358 15.4483 -8.11702 -13.2102 14.4599 -7.3126 -13.523 14.0102 -7.54363 -14.4589 13.6775 -8.40102 -14.3665 13.097 -8.97345 -13.7431 12.5149 -8.22489 -13.1769 12.8112 -8.00734 -12.3399 12.4024 -7.45971 -12.5357 11.55 -7.45708 -11.533 11.3592 -8.34365 -11.2467 11.748 -8.50544 -10.5063 11.0988 -9.22485 -10.8844 10.6334 -10.1115 -11.4336 10.3926 -10.9116 -10.9354 10.06 -10.8677 -10.6725 9.11123 -10.4092 -9.78053 9.28422 -11.1568 -9.14266 9.61878 -10.8724 -9.14005 10.5646 -10.1444 -8.68249 9.99815 -10.6345 -8.02527 9.36645 -9.73417 -8.31715 9.05193 -8.97903 -8.71486 8.37146 -8.61166 -9.3655 8.99798 -8.38508 -10.1196 8.37292 -8.50095 -10.9778 8.60855 -8.57785 -11.2776 9.54937 -7.92689 -10.4292 9.64216 -7.10824 -10.5464 9.11218 -6.32802 -11.2054 8.97182 -5.46552 -11.466 9.22452 -4.87134 -11.8631 8.56787 -3.99609 -11.2656 8.45961 -3.01342 -11.3284 8.57613 -2.87867 -12.2882 8.29066 -3.14948 -12.89 9.05516 -2.94406 -13.0203 10.0044 -2.92683 -12.0918 9.69697 -3.12245 -11.9106 10.6366 -2.57815 -11.3921 11.3485 -3.47328 -11.9014 11.707 -3.84817 -10.9472 11.612 -4.49184 -11.0334 10.8553 -5.00703 -11.319 11.6533 -5.19056 -12.2663 11.3344 -5.22574 -12.5839 12.2506 -4.37922 -13.1056 12.3643 -3.62585 -13.7446 12.5707 -4.05736 -14.5955 12.7784 -4.12227 -15.1531 11.9105 -3.42155 -15.6174 11.332 -3.04971 -15.281 10.5032 -2.75834 -14.3372 10.8391 -2.52366 -14.1306 11.7973 -1.78895 -14.5328 11.2112 -0.983698 -14.1231 11.4176 -0.349877 -14.8904 11.1176 -0.182532 -14.3915 10.2139 --0.487721 -15.1765 10.2578 --0.02521483 -15.9842 10.2623 -0.426329 -16.9043 10.0091 -0.510958 -17.524 9.24528 -0.289357 -17.4452 8.33545 --0.62125 -17.9137 8.34531 --0.92016 -18.8785 8.41346 --0.157073 -19.3749 8.80904 -0.12156 -19.8885 8.00061 -0.926731 -20.0638 7.41023 -1.56109 -20.3813 6.76297 -1.59479 -21.4031 6.7881 -2.11737 -21.5066 7.621 -2.71854 -20.7215 7.36752 -2.69648 -20.4448 6.37988 -2.97059 -19.5034 6.1049 -3.19111 -20.1283 5.40746 -2.72582 -19.8394 4.51249 -3.35648 -20.2533 3.80942 -3.91846 -20.8786 4.34885 -4.73567 -21.4057 4.41744 -4.94295 -22.1461 5.15118 -5.36638 -22.6877 5.8905 -5.36057 -22.283 6.85552 -6.14272 -22.6075 7.29 -5.49014 -22.0743 7.9857 -4.77355 -22.2507 8.64712 -4.59929 -21.3244 8.18087 -4.4128 -20.9343 9.05105 -4.00931 -20.271 9.68311 -4.18636 -20.8606 10.4832 -3.52748 -20.6795 11.1372 -3.67775 -21.4143 11.8605 -2.72411 -21.6661 11.6562 -2.23315 -21.4211 12.5282 -1.30569 -21.6984 12.2697 -0.511651 -21.2135 11.8628 -0.727752 -20.2274 12.01 -0.203149 -19.3972 12.0728 -0.09454317 -19.0587 11.156 --0.731489 -18.8116 10.5601 --1.13355 -19.7471 10.8956 --1.13625 -19.7973 12.0258 --2.13004 -19.8529 12.1228 --2.35248 -19.9447 13.1017 --2.56359 -20.3278 13.9229 --3.52899 -20.5741 13.9039 --3.20592 -20.7879 14.8715 --3.03317 -21.2225 15.7798 --2.04115 -20.8163 15.8413 --2.51995 -19.9016 15.9421 --2.25386 -20.4716 16.7763 --2.58126 -19.502 16.9599 --2.99606 -18.9402 17.6544 --3.75142 -19.1427 18.1774 --3.89274 -19.7418 17.3956 --3.83718 -20.4726 16.7726 --3.59694 -20.1886 15.8734 --3.53188 -19.3401 15.3232 --3.42116 -18.5874 14.6788 --3.47818 -17.8908 15.3681 --3.69962 -17.0456 15.7799 --3.60226 -17.1214 16.803 --4.52915 -16.8144 17.0444 --5.17232 -17.4951 17.432 --6.02679 -17.0775 17.0122 --5.91278 -16.1131 17.1455 --5.58183 -15.5235 16.3872 --4.87733 -14.8155 16.6282 --3.88667 -14.7306 16.7006 --2.95585 -14.8324 16.4812 --2.07532 -14.5498 16.1837 --1.74039 -13.7238 15.7688 --2.3876 -13.0543 15.5766 --2.48842 -12.1104 15.8763 --2.99133 -12.5475 16.5964 --2.07439 -12.449 16.798 --1.48698 -11.7053 17.1485 --1.3772 -11.2062 18.03 --1.44161 -11.5151 18.9582 --0.883796 -10.8524 19.4217 --0.04533693 -10.3877 19.2196 -0.722677 -10.3485 19.9142 --0.275641 -10.3497 20.2333 --0.120381 -9.88502 21.1354 --0.155147 -8.86607 21.1694 --0.398836 -8.6596 20.1953 --1.31348 -9.09144 20.526 --1.0724 -8.79301 21.5162 --1.67865 -7.9615 21.816 --2.24717 -8.0331 20.935 --2.57366 -8.536 20.2063 --2.45118 -9.23311 19.5752 --2.11305 -9.69347 20.4748 --3.07362 -9.84566 20.16 --3.11701 -9.61546 21.0986 --3.07627 -10.5968 21.1165 --2.73372 -11.5206 20.8974 --3.66424 -11.3411 20.6028 --3.6691 -11.3585 21.5878 --3.56405 -12.3497 21.7751 --3.76211 -11.7651 22.5837 --4.16287 -11.6593 23.5212 --3.9422 -10.9827 24.1632 --3.12398 -11.4467 24.4711 --2.49831 -10.6606 24.4244 --2.17372 -11.3971 23.7481 --2.28378 -11.9994 22.9053 --1.3459 -12.0527 22.7396 --1.73202 -11.1746 22.6219 --2.28385 -11.6767 21.9318 --1.87691 -12.1095 21.0784 --1.66537 -12.8039 20.3592 --0.919531 -13.2308 20.995 --0.238483 -12.8648 21.6475 --0.887125 -13.1498 22.3188 --1.56417 -13.8354 22.1026 --1.73772 -14.7922 22.0992 --1.3094 -15.6271 22.3542 --0.563854 -16.2563 22.1296 --0.314718 -16.3338 21.2568 --0.726518 -17.1734 20.8897 --0.687158 -17.2034 21.8433 --0.283559 -18.0268 21.5059 -0.644767 -17.9099 21.1192 -1.07629 -17.9749 20.2271 -1.20677 -17.3517 19.4042 -1.63976 -16.4553 19.4062 -2.05572 -17.1223 20.0042 -2.08222 -17.9053 20.6089 -1.96049 -18.9481 20.6965 -1.86238 -19.1541 21.6246 -2.57664 -19.7236 21.9544 -2.02057 -20.1147 21.2286 -1.99923 -21.1137 21.0176 -2.92451 -21.3165 20.667 -3.43831 -20.5578 20.8268 -3.92248 -21.1316 21.525 -3.95029 -21.7969 20.7599 -4.68446 -22.5021 21.0377 -5.1662 -22.5768 20.1116 -6.05858 -22.7796 20.1429 -5.95602 -22.3573 19.1769 -5.55935 -21.5817 18.6324 -6.19474 -20.6881 18.7728 -5.82104 -20.0473 18.0594 -4.9587 -20.2672 17.7887 -5.13317 -20.3295 16.8372 -5.74665 -19.5629 16.5781 -6.17084 -18.7745 17.0635 -7.02757 -19.2467 17.1907 -7.57209 -19.7236 17.8469 -7.20697 -18.7506 18.0984 -6.49636 -18.0252 18.2162 -6.08127 -18.3514 19.0421 -5.88614 -17.5378 19.5884 -6.43055 -17.9569 20.3623 -7.13409 -18.07 19.6695 -7.15509 -18.9528 19.2737 -7.36426 -19.0645 20.2216 -7.68241 -18.1859 20.6268 -8.45819 -17.5782 20.811 -8.82659 -16.6844 20.5851 -9.58608 -16.5182 19.9648 -10.0536 -17.0076 19.2215 -9.38029 -17.6977 19.4582 -9.12926 -18.5815 19.7412 -9.36154 -18.1427 20.6198 -9.08495 -18.6725 21.3944 -9.20592 -19.6284 21.8638 -8.94908 -19.4346 22.7851 -9.10099 -19.8638 23.6582 -9.83014 -20.5643 24.0045 -10.4017 -20.0854 23.3843 -10.665 -20.9564 23.0464 -11.2765 -21.3427 23.7143 -11.9089 -20.4571 23.46 -12.1299 -19.8461 24.2137 -11.406 -20.0737 24.8813 -11.4048 -21.0335 25.2286 -10.484 -21.3096 24.8976 -10.8939 -22.0786 24.47 -11.8479 -22.1191 24.682 -12.6113 -22.747 24.8006 -13.4038 -22.6446 24.1272 -13.9955 -22.3636 24.9536 -14.3499 -21.5832 24.5166 -13.3456 -21.6076 24.1277 -13.0979 -21.9365 23.1578 -12.7753 -21.2379 22.561 -11.8386 -21.522 22.7025 -11.1832 -22.086 22.1349 -11.2033 -23.0387 22.0842 -11.6319 -22.8839 21.2018 -12.3931 -22.3136 20.8151 -12.6838 -21.342 20.6859 -12.4753 -20.7889 19.9208 -12.358 -19.8292 20.2162 -12.608 -19.8608 21.2324 -12.7573 -20.7668 21.4824 -13.5349 -21.3071 21.9571 -14.2206 -21.4669 21.2327 -14.6844 -20.5766 21.4973 -15.5451 -21.1126 21.5673 -16.3331 -20.8771 22.0152 -16.4887 -20.7115 21.0798 -16.4753 -19.6943 20.8239 -17.017 -18.9361 20.7536 -17.0839 -18.1424 20.0516 -16.6196 -17.8908 19.271 -17.3481 -17.2856 19.5987 -17.6015 -16.3245 19.3892 -18.2637 -16.515 18.6093 -18.8972 -16.7152 19.3532 -19.149 -16.9126 20.2679 -19.1213 -15.8599 20.3028 -19.1691 -15.2992 19.4411 -20.0077 -15.2174 18.9398 -20.7334 -15.3558 18.1614 -21.3918 -14.9189 18.8316 -21.7751 -15.1778 19.6513 -22.5664 -14.6626 19.3996 -23.1363 -13.8811 19.4779 -23.8363 -13.7466 20.1906 -24.6831 -13.6351 20.716 -25.1917 -13.5184 19.799 -24.8857 -12.5526 19.4906 -24.0378 -12.9664 19.2276 -23.9718 -12.1718 18.6839 -24.7984 -12.3131 18.1317 -24.5179 -12.7572 17.219 -23.6641 -13.0256 16.7891 -22.8601 -13.2596 16.3115 -22.1463 -12.8607 16.8845 -21.9545 -13.8343 17.0275 -21.3383 -13.5781 17.7667 -20.8421 -12.8318 18.1114 -21.1646 -12.7559 19.0344 -20.2453 -12.753 19.5639 -20.392 -13.5071 20.1391 -19.3867 -13.4921 20.1104 -18.8311 -12.9179 20.7251 -18.5822 -12.533 21.6275 -17.9009 -12.7794 22.347 -18.3535 -12.3008 23.0647 -18.1534 -12.8587 23.8886 -17.8768 -11.888 23.9256 -17.2454 -11.1537 24.2782 -16.9861 -10.3368 23.7688 -16.2263 -10.1692 23.166 -16.9364 -9.64589 22.5587 -17.8934 -9.98029 22.7825 -18.5073 -10.7437 22.5333 -18.6662 -10.8285 21.55 -18.1385 -11.0337 20.7673 -17.2119 -10.8653 20.6867 -17.5411 -11.8113 20.7835 -17.8319 -12.4988 20.0736 -16.9891 -12.4385 19.6311 -16.949 -13.0697 20.4184 -17.2994 -13.9314 20.47 -17.013 -14.7956 20.0668 -16.5245 -15.5763 19.6975 -16.8172 -16.4343 20.0732 -16.9008 -16.9131 20.9123 -17.1395 -17.1486 21.8485 -16.2155 -17.446 21.766 -15.84 -17.3172 20.8946 -15.7544 -16.3353 20.9507 -15.084 -16.9566 20.6236 -15.0563 -17.0351 21.6557 -14.2611 -16.56 21.267 -13.7119 -17.3341 21.0813 -14.0032 -18.2219 20.7918 -14.1827 -17.7155 19.9801 -14.8071 -18.0006 19.3217 -13.9015 -17.9622 18.9251 -13.8647 -18.8302 19.3034 -13.9886 -19.8378 19.2192 -13.6881 -20.8305 19.0936 -14.2408 -21.5953 19.1167 -14.1795 -21.2806 18.2367 -13.961 -20.9777 17.2919 -12.9984 -21.1419 17.3934 -12.9449 -22.1265 17.5642 -12.1897 -22.1434 16.9328 -12.1466 -21.8726 15.9481 -12.2631 -20.9671 15.5316 -13.0767 -21.1027 16.0921 -14.0103 -21.58 15.929 -14.7488 -20.9708 15.7604 -15.7524 -20.8953 16.0837 -16.5955 -20.4021 15.9606 -16.6673 -19.7381 15.1495 -16.6776 -19.8394 14.1602 -16.9467 -18.8654 14.1286 -17.3126 -18.0408 13.7169 -18.163 -17.8 13.3223 -17.6048 -17.0148 13.3057 -16.7001 -17.2743 13.3981 -15.9934 -17.4642 14.0808 -16.0506 -16.5445 13.671 -16.6927 -15.7958 13.5902 -16.7102 -14.8682 13.0852 -17.3312 -14.904 12.2556 -16.892 -15.4251 11.4074 -16.4407 -14.9629 10.64 -16.5951 -13.97 10.2789 -16.2226 -14.2067 9.36569 -16.0579 -13.259 9.61267 -15.4941 -12.5795 9.24718 -15.0405 -12.3893 8.37385 -14.8678 -11.9637 7.49552 -15.8046 -12.0011 7.82147 -15.7344 -12.4509 6.98807 -16.2573 -11.5495 7.02433 -16.8516 -11.7195 7.85075 -17.4926 -11.2114 7.2006 -17.3796 -10.9185 8.1573 -17.3381 -9.96655 8.08764 -18.1638 -9.70784 8.626 -18.6871 -9.62755 7.74275 -19.2636 -9.78113 8.59048 -19.1916 -10.5655 9.18979 -19.3419 -9.84208 9.9307 -19.5212 -10.4772 10.5838 -19.3432 -11.3814 10.3235 -19.2035 -11.7701 11.2988 -20.0921 -11.9469 11.5627 -20.3036 -12.4272 12.4377 -20.759 -12.5489 13.4215 -21.4393 -12.7268 14.1906 -22.2976 -12.2942 14.3001 -22.1225 -12.9654 14.9431 -22.9193 -13.5844 14.6886 -23.2896 -13.3093 13.8467 -23.5904 -12.4174 13.447 -23.8179 -11.7742 12.6955 -24.3107 -12.5087 12.2077 -25.0717 -13.0803 11.9282 -25.0339 -14.0096 12.4347 -24.6784 -13.4501 13.2196 -25.3362 -14.1002 13.7278 -24.6905 -14.7766 14.0832 -23.8287 -15.2453 13.8774 -23.2197 -16.0523 14.0253 -23.4218 -16.9241 13.5838 -23.944 -17.4614 12.9731 -23.2524 -16.9649 12.52 -23.6196 -16.7557 11.6996 -23.6712 -16.901 10.6909 -23.4716 -17.6184 9.9473 -22.651 -17.2921 10.3637 -22.2779 -17.2728 11.2573 -21.5749 -17.5074 11.9836 -22.3203 -17.9341 12.5139 -22.9683 -18.4001 11.7951 -22.2801 -19.1681 11.7142 -21.4053 -19.5119 11.3777 -20.3853 -19.7087 11.2918 -19.7 -18.9576 11.2215 -19.9345 -18.3873 12.0063 -19.126 -18.6082 12.6463 -18.4042 -19.2117 12.7478 -18.4064 -19.537 13.7406 -18.9951 -18.7281 13.7091 -19.9867 -18.6716 13.7247 -20.3909 -19.4955 13.3431 -19.8536 -20.3243 13.2528 -20.0922 -20.3937 14.1656 -20.8351 -21.021 13.8194 -21.8029 -20.7591 13.7759 -22.1945 -19.8114 14.0123 -21.3909 -19.3841 13.6528 -21.4389 -18.6875 14.4882 -21.2089 -17.6722 14.6267 -21.0576 -17.0236 15.435 -20.9377 -16.9582 16.4135 -20.0306 -17.2898 16.3151 -19.9979 -17.9765 15.6103 -19.0703 -18.3448 15.218 -18.9522 -17.9068 16.0775 -18.4495 -17.2381 15.6299 -18.5126 -16.6148 16.4152 -18.9441 -15.9439 17.0217 -18.9546 -14.9959 16.8168 -19.8685 -15.4745 17.0768 -20.4988 -15.0382 16.4345 -21.2408 -15.2863 15.8088 -20.3418 -15.4428 15.4217 -19.3418 -15.5429 15.2366 -18.5666 -15.3721 15.7669 -18.6128 -14.5689 15.1505 -17.6924 -14.7383 15.3969 -17.6759 -14.2959 14.4667 -18.017 -13.4109 14.7782 -17.3507 -12.6884 14.9489 -17.6567 -12.599 13.998 -18.055 -11.7295 13.8002 -18.0592 -11.1975 14.7344 -18.0324 -10.5216 14.0607 -17.0804 -10.8654 14.1813 -16.5297 -10.7453 15.0037 -15.8667 -11.3827 14.5954 -15.2078 -11.8968 13.9977 -16.0661 -12.1083 13.5856 -16.9583 -11.992 13.0238 -17.3693 -12.7447 12.6157 -18.3004 -13.0276 12.3623 -19.228 -13.2511 12.3478 -20.0066 -13.863 12.5413 -19.8407 -13.0829 13.1521 -19.6586 -13.8112 13.8225 -19.5386 -13.6666 14.7871 -19.371 -12.9435 15.3981 -19.8265 -12.0696 15.4102 -19.6467 -11.1406 15.4782 -19.8935 -10.5029 16.1671 -19.8266 -9.59691 16.7205 -18.973 -10.1647 17.0347 -18.9617 -9.82738 15.9814 -18.1814 -10.0477 15.4821 -17.7759 -10.8876 15.7384 -17.239 -10.7221 16.5414 -16.283 -10.4647 16.2948 -16.0111 -11.2631 16.8735 -15.6391 -10.6704 17.6561 -14.8049 -10.9685 17.141 -13.9673 -10.7704 16.6961 -14.1578 -9.88572 17.1298 -14.8519 -9.48887 16.5275 -14.809 -9.99201 15.6258 -15.4492 -9.86722 14.8889 -15.1049 -8.91151 14.9435 -15.2064 -8.76762 13.9486 -14.2364 -8.49475 13.7716 -13.4154 -8.41747 14.3545 -12.6618 -9.01112 14.7628 -13.4119 -9.69315 15.0531 -12.789 -10.0758 14.302 -13.0901 -11.0416 14.05 -13.6467 -10.5281 13.4598 -14.448 -10.1921 13.0633 -15.2656 -9.63232 13.2552 -15.1947 -9.39696 12.3088 -15.0809 -10.3276 12.1609 -15.5845 -11.1246 11.6976 -15.5366 -11.9679 12.2144 -15.4046 -12.7256 12.8154 -15.0312 -13.5068 13.3091 -14.9211 -14.4679 12.846 -15.4172 -15.0429 13.4713 -15.3059 -15.2083 14.4182 -15.0825 -15.1953 15.3606 -14.8733 -15.1789 16.3378 -14.0172 -15.4629 15.892 -14.0328 -15.7429 16.8752 -14.0154 -16.6565 17.4312 -13.6074 -17.526 17.7289 -13.4315 -16.7809 18.4251 -12.6991 -17.1439 18.9118 -11.7846 -17.6336 19.1287 -11.2129 -18.3364 19.171 -11.6321 -18.445 18.2921 -11.2596 -19.1415 17.7841 -10.1679 -19.0529 17.7276 -9.36545 -18.9156 17.2041 -9.11291 -18.8502 16.3785 -8.56703 -18.1747 15.871 -7.67693 -18.4741 15.6254 -6.82792 -18.5693 15.0797 -7.13856 -19.5326 15.0178 -6.81154 -20.4277 15.261 -5.85982 -20.2459 14.8552 -6.31378 -19.7093 14.1526 -6.75981 -19.8836 13.3496 -7.50936 -19.2474 13.2306 -7.8768 -18.3566 13.5514 -8.58354 -18.2965 14.2789 -8.17163 -17.3733 14.5608 -8.99199 -16.7854 14.8231 -9.89586 -16.346 14.5029 -10.0455 -15.3727 14.5434 -10.6426 -15.7623 15.2176 -11.4251 -15.5659 14.6038 -10.7794 -15.4679 13.855 -11.092 -14.5143 13.7338 -11.7003 -13.6937 13.7896 -11.6803 -13.1079 12.9605 -11.3886 -12.2086 12.7621 -11.4904 -11.9169 11.8261 -11.0048 -12.684 11.425 -11.2882 -13.6325 11.2094 -11.3929 -13.6703 10.2234 -10.549 -14.0549 9.93925 -9.53525 -14.08 10.0611 -9.40973 -14.7187 10.7889 -8.67742 -14.5854 10.1567 -8.6079 -13.673 10.7156 -8.83867 -13.2266 9.82935 -9.36943 -12.459 9.61909 -9.83852 -11.946 8.86 -9.90208 -11.8822 7.87916 -10.333 -12.3184 7.07397 -10.5024 -11.9338 6.19152 -10.7005 -11.0583 6.32286 -9.94586 -10.3408 6.31861 -9.61294 -9.51184 5.89239 -8.80395 -9.4756 5.36395 -9.07378 -9.71021 4.36965 -9.12608 -10.5007 3.72301 -10.0084 -10.4745 3.30404 -10.3092 -11.3538 3.68395 -10.9156 -12.105 3.27582 -10.5321 -12.9242 2.97742 -9.98694 -13.8338 2.90952 -9.89586 -14.7708 3.20697 -10.223 -15.3217 2.46526 -9.97844 -15.6924 1.56889 -9.82954 -15.655 0.5727841 -8.81993 -15.5104 0.4303571 -8.12205 -15.8642 1.16059 -7.65754 -16.3617 1.86615 -8.05168 -15.6867 2.56303 -8.96663 -15.6841 2.97414 -8.38208 -15.6266 3.7878 -8.38646 -16.3482 4.48296 -8.34792 -16.3616 5.46223 -7.42414 -16.1066 5.66418 -7.18402 -17.0657 5.41715 -6.62461 -17.4258 4.63916 -5.72735 -17.7633 4.91671 -6.04854 -18.4171 5.53724 -6.92644 -18.7474 5.87321 -7.83783 -18.4838 5.71531 -8.63633 -19.0707 5.3145 -8.55091 -18.3936 4.51782 -8.55368 -17.8895 3.73108 -8.53316 -16.9447 3.4305 -8.58464 -17.2938 2.53332 -8.26622 -18.2862 2.72688 -8.69252 -18.9669 2.09442 -9.58921 -18.6614 2.38267 -10.015 -19.3036 2.97027 -9.41062 -20.1496 2.79166 -8.57742 -20.661 2.49731 -7.67804 -20.8562 2.99244 -8.46565 -20.3121 3.36645 -7.66677 -20.1688 3.88434 -7.11442 -19.8842 3.09391 -6.16439 -20.1766 3.25063 -5.57399 -20.219 2.50907 -5.78972 -19.9494 1.49832 -5.88044 -20.8214 0.9294851 -6.79247 -20.5141 0.6326911 -6.90932 -20.929 1.57167 -7.02635 -19.8802 1.67481 -6.44519 -19.1283 1.26306 -6.07805 -18.2226 1.63827 -6.93756 -17.8568 1.37767 -7.52422 -17.9504 0.6069281 -8.05136 -17.3317 1.18247 -9.01215 -17.5457 1.31852 -8.76324 -17.9482 0.4874391 -9.34989 -17.1743 0.02438652 -9.53369 -17.7135 -0.8989129 -9.11113 -18.5564 -1.18454 -9.12063 -18.5801 -2.12252 -8.19189 -18.6962 -2.49704 -7.72058 -18.3817 -1.70593 -6.88454 -17.9556 -1.25368 -6.39212 -18.8045 -0.9549159 -5.40056 -18.6443 -0.6043179 -5.76756 -17.8181 -0.2791149 -6.45936 -17.0981 -0.3282179 -6.24922 -16.5816 0.4280381 -5.86086 -15.6625 0.4950001 -5.34167 -14.8808 0.1436271 -4.4163 -14.9781 0.5095771 -3.52097 -14.8934 0.9120841 -2.56613 -15.0007 0.5170031 -2.69676 -14.5501 -0.3931389 -3.61927 -14.2219 -0.6819869 -3.49604 -14.4886 -1.70499 -4.44689 -14.569 -1.85275 -5.46509 -14.261 -1.75316 -5.30193 -13.4384 -1.17463 -4.94002 -12.6662 -1.62725 -4.4606 -11.8436 -2.0563 -3.58696 -11.7742 -2.47962 -3.04633 -10.9882 -2.06609 -2.16696 -10.3849 -2.01831 -2.77371 -9.81974 -1.44902 -2.72412 -8.79897 -1.29942 -3.04439 -7.87375 -1.35128 -3.37105 -8.10331 -0.4720199 -3.52928 -7.29553 0.06062072 -4.43624 -7.81644 0.1750971 -5.3716 -7.99339 -0.1238339 -4.86472 -8.51695 0.6218711 -4.75794 -8.92904 1.522 -4.45678 -9.73844 1.15905 -3.58662 -9.74819 0.7958001 -2.63399 -9.70525 0.4238561 -2.72948 -8.82313 1.02986 -2.68862 -8.46011 1.95835 -2.18554 -8.77372 2.78064 -2.68466 -8.23363 3.47681 -2.77345 -9.16168 3.89821 -1.84386 -9.18165 4.36558 -1.39328 -8.28059 4.51542 -0.968436 -8.81984 3.91246 -0.802599 -9.82113 4.1676 --0.02486293 -10.1202 4.67014 --0.651518 -10.7537 4.68958 --0.956516 -10.4936 3.77723 --0.825304 -9.55982 3.42885 --1.02781 -9.3845 4.36568 --0.806224 -8.97987 5.22866 --1.79465 -8.77246 4.90286 --2.11381 -7.86269 4.62875 --1.22366 -7.47424 4.36551 --0.74966 -6.64657 4.08254 --0.949338 -6.35999 4.95726 --1.70868 -5.73927 4.7297 --2.283 -6.5991 4.55773 --3.09428 -6.06446 4.35293 --3.09335 -5.74098 3.43666 --3.44008 -4.9789 2.90646 --2.62854 -5.27466 2.42413 --2.31504 -6.05232 1.97806 --2.92725 -6.84625 2.09162 --2.49054 -7.03937 2.95113 --2.92687 -7.98405 3.16055 --3.66632 -7.73651 2.505 --3.21562 -8.07139 1.64681 --2.56948 -8.88732 1.5952 --2.90609 -8.53022 0.6664551 --3.6014 -7.85205 0.5155561 --4.09777 -8.37627 -0.1241289 --3.39339 -8.66398 -0.7305609 --2.85558 -9.48611 -0.4090389 --3.39205 -10.3435 -0.3048929 --3.84741 -10.2002 0.5347171 --3.83694 -10.4713 1.49354 --4.3124 -11.2275 1.89103 --3.62379 -11.5485 1.24503 --4.06218 -11.8028 0.4132911 --4.53541 -12.1938 -0.3112359 --5.22387 -12.3154 0.4226701 --5.90488 -12.9413 0.3303431 --5.98504 -12.5189 -0.5238559 --6.52169 -11.7291 -0.5247459 --6.0407 -10.9634 -0.4622349 --6.85452 -10.8095 0.01692222 --6.95415 -9.94634 0.5340851 --6.78644 -10.2546 1.47959 --7.11856 -10.9133 2.20646 --7.07923 -10.2242 2.91758 --6.48974 -9.6592 3.56758 --5.89954 -9.60204 2.79483 --5.42269 -9.76789 1.94793 --5.82685 -8.9612 1.55245 --6.78315 -8.98944 1.77369 --7.44912 -8.73456 1.12132 --7.33977 -7.75091 0.9030411 --6.83556 -6.87448 0.9853161 --7.83568 -6.79408 1.05395 --8.33363 -7.27487 0.2438741 --9.14178 -6.72569 0.4610531 --9.32293 -6.21423 1.28966 --9.95009 -6.33195 2.04751 --10.9632 -6.49091 1.73494 --10.6126 -7.40076 2.05154 --9.8087 -7.82985 2.54267 --9.58993 -7.71068 3.50286 --8.86256 -7.62766 2.83804 --8.31545 -8.19324 2.32049 --7.85709 -8.23699 3.24886 --7.54141 -7.32521 3.12105 --7.58713 -7.27306 2.1036 --8.33422 -6.61655 2.36262 --8.23622 -5.62875 2.38001 --8.92724 -5.26198 1.74788 --8.57077 -4.40053 2.05091 --7.68166 -4.82536 1.79214 --7.56074 -3.94514 1.2962 --7.02902 -4.63888 0.6917681 --6.89635 -5.60447 0.3935881 --6.93835 -6.37077 -0.2811859 --6.57045 -6.18362 -1.16533 --5.94403 -6.93639 -1.0336 --5.50206 -6.3275 -0.3962679 --5.81484 -6.80342 0.4559041 --5.1477 -6.71311 1.15813 --5.17986 -6.98153 2.13128 --5.47799 -6.99445 3.0306 --6.06193 -6.88907 3.82961 --5.7292 -7.81512 4.09145 --6.06185 -8.67253 4.5227 --5.32488 -9.30201 4.37926 --4.84095 -8.86603 3.64501 --4.1442 -9.10766 2.90698 --3.54038 -9.78693 2.51664 --2.80982 -9.22292 2.90278 --2.76838 -10.0224 3.53774 --3.29812 -10.6565 2.92661 --2.52994 -11.1735 2.94338 --2.5766 -11.8505 3.63434 --2.26721 -11.5252 4.47654 --1.33307 -11.9829 4.42335 --0.604949 -11.9485 3.79041 --0.008740175 -11.16 4.05818 -0.784221 -11.6463 4.34085 -1.20967 -11.4257 3.39496 -0.60522 -11.1084 2.61976 -0.953801 -10.1846 2.71746 -1.88379 -10.5568 2.57629 -2.32579 -11.4941 2.59775 -2.41332 -11.5368 3.61758 -3.15108 -10.8303 3.37661 -3.23791 -10.4003 2.5418 -3.58369 -9.78406 1.89461 -2.67428 -10.1386 1.78762 -2.76005 -10.8251 1.06218 -2.39452 -11.2342 0.2038461 -1.62523 -10.5995 -0.02234418 -1.09516 -10.3402 -0.8112679 -0.310965 -10.7151 -1.28205 --0.668973 -10.3773 -1.26038 --0.448411 -10.9059 -2.11342 --0.202195 -10.0445 -2.57396 -0.179368 -10.0229 -3.41043 -1.0614 -10.2078 -3.77937 -1.06291 -9.59588 -2.92962 -1.27462 -8.65588 -3.09743 -2.22469 -8.78504 -3.56648 -2.0404 -8.19573 -4.2823 -2.33269 -7.53773 -4.9925 -3.20344 -8.01731 -5.11762 -4.01833 -7.93433 -5.6313 -4.05205 -7.44407 -6.49468 -4.13812 -6.74665 -5.89565 -3.50021 -6.297 -6.52848 -2.68425 -6.41716 -6.97116 -2.15217 -6.08391 -6.13965 -2.15548 -5.15873 -5.82287 -1.63476 -4.24018 -5.77109 -2.07633 -4.18104 -4.79978 -1.57298 -4.65904 -4.06422 -1.30034 -5.47744 -4.58232 -0.332169 -5.7058 -4.77863 --0.07058293 -5.01856 -4.14365 --0.05865913 -5.0647 -3.17646 -0.369245 -5.8602 -2.75756 -0.689674 -6.20752 -3.60056 -1.39506 -6.66806 -3.1438 -2.01419 -5.91681 -3.24544 -2.44815 -6.47211 -2.56876 -2.89941 -7.32893 -2.83356 -3.88571 -7.40189 -2.8306 -4.01406 -6.75963 -3.51751 -3.05184 -6.6754 -3.6425 -3.21524 -5.89241 -2.94354 -3.65139 -5.199 -2.30594 -4.0877 -4.43393 -1.82111 -3.059 -4.20825 -1.78038 -3.0879 -3.26638 -1.38515 -2.41525 -3.83137 -0.8495179 -1.81672 -3.62336 -1.6425 -1.04267 -3.50899 -2.17002 -0.441666 -2.6975 -1.9169 -0.869322 -2.93023 -1.09212 -0.879904 -3.45249 -0.2173289 -0.09999727 -4.00713 -0.3587009 --0.07822283 -3.23549 -1.05643 --0.428106 -2.37988 -0.7775749 --0.883838 -1.50207 -0.5620249 --1.18272 -2.24607 0.1411291 --0.722347 -2.18612 1.05283 -0.128696 -2.08644 0.5852701 -1.12233 -2.09671 0.6109281 -1.91318 -2.26381 0.07968072 -2.68129 -1.65855 0.3573331 -3.37601 -1.64886 1.00098 -2.63449 -1.91881 1.61951 -1.90728 -2.6326 1.63034 -2.24899 -3.23308 2.31808 -2.9137 -3.93897 2.41619 -3.0301 -3.53573 3.44249 -3.67235 -3.86698 4.08904 -3.48488 -4.50229 4.84306 -3.97706 -4.60086 5.79375 -4.06978 -5.5768 5.71723 -4.58661 -5.61048 6.62018 -4.09475 -5.0552 7.27425 -3.26925 -4.5776 6.95182 -2.39386 -4.4273 6.49079 -2.32123 -3.55287 6.79206 -1.63267 -3.11959 6.33452 -0.911761 -3.19061 7.10449 -0.07613857 -3.59656 6.74473 --0.136795 -2.57486 6.57032 --0.788555 -2.28166 7.15267 --0.584493 -1.46936 6.57502 --0.15887 -0.5883061 6.28814 -0.714452 -0.6004271 5.99473 -1.26103 -1.10396 6.72533 -0.357338 -1.15578 7.22655 --0.02966983 -0.2250141 7.28448 --0.180034 -0.04484897 8.26217 --0.711168 0.8334549 8.38534 --1.57076 0.5482409 8.72195 --1.16663 1.23719 9.34863 --1.99713 1.57378 8.8652 --2.5053 1.35477 8.01614 --2.93512 1.74288 7.19111 --3.37891 2.3733 6.57435 --3.67903 1.4562 6.20588 --3.66256 0.8233679 7.04884 --3.72016 1.17107 7.98768 --3.7146 1.85782 8.77204 --3.7232 2.35397 9.64058 --4.0995 3.2967 9.51425 --4.70535 3.60286 8.85224 --5.1693 2.99983 9.49489 --6.08956 3.05233 8.99466 --6.36721 3.97462 8.99291 --7.07708 4.19029 8.38901 --7.58076 4.4913 9.20248 --8.26433 4.16024 9.89639 --7.67349 4.55512 10.647 --8.05597 3.62925 10.7198 --7.9435 2.66495 11.1024 --7.58396 2.10884 10.3881 --7.79608 2.5195 9.52343 --7.82724 1.80054 8.87151 --8.66111 1.63352 8.38357 --9.07222 0.6767219 8.13744 --9.04338 -0.07914377 8.74978 --8.35766 -0.8584791 8.69146 --8.94506 -1.06356 7.89374 --8.25392 -0.4423921 7.50055 --8.06382 0.4155509 7.96232 --7.10606 0.2042439 7.84407 --6.31425 0.7975399 7.76879 --6.05446 1.74309 7.63503 --5.88319 1.3502 6.77837 --6.73816 1.09281 6.31818 --6.94238 0.6198309 5.42342 --7.76214 0.6800769 6.04483 --8.47298 0.8085199 5.22459 --9.01502 0.5352019 4.47289 --9.54604 0.2382199 5.29358 --8.80023 0.2170779 5.92721 --9.58948 0.4590359 6.37502 --10.5543 0.6497139 6.48332 --11.07 0.04291493 7.1491 --11.3052 -0.8343971 6.71035 --11.3939 -1.77962 6.97069 --11.9776 -2.4537 6.57936 --12.6991 -2.16566 7.24874 --13.1025 -2.59641 8.06675 --13.416 -1.74848 8.59796 --14.3265 -2.33733 8.5582 --14.9986 -1.57715 8.33084 --14.6866 -1.9283 7.43078 --15.6436 -2.31022 7.38312 --15.7321 -3.23239 7.6272 --14.9336 -3.24806 7.04557 --14.7495 -3.49552 7.99958 --15.1343 -3.90888 8.87761 --15.0341 -4.52608 9.69246 --14.1579 -4.5706 9.19657 --13.4306 -3.86419 8.91343 --12.6615 -3.45573 9.32579 --12.7748 -2.48016 8.95163 --11.8583 -2.23176 9.22924 --11.2258 -2.41529 9.93093 --12.1409 -2.283 10.2977 --12.7554 -1.4789 10.0736 --12.5042 -1.79145 11.0162 --13.1771 -2.50625 11.3292 --13.2945 -1.49843 11.5007 --13.8119 -1.28833 10.6254 --14.3558 -0.8961241 11.3476 --14.9573 -0.7719121 10.5391 --15.3671 -0.5158381 9.75632 --15.6554 0.4962639 9.71188 --16.4669 1.02757 9.69735 --16.9239 0.2878619 10.1884 --16.795 -0.5119051 10.833 --17.3233 -0.9286371 10.1169 --17.9003 -1.53496 9.59746 --18.8312 -1.53839 9.24783 --18.419 -2.41963 8.77454 --18.9629 -3.1781 8.42458 --18.3853 -3.57825 7.78315 --18.0551 -2.74294 7.45256 --17.3498 -2.17615 7.16022 --17.9443 -1.29666 7.13002 --17.8122 -1.16842 6.13755 --18.5356 -0.4191131 6.33706 --19.1599 -1.11058 5.94373 --19.6043 -0.3455701 5.54964 --19.753 -1.29959 5.1581 --20.0812 -0.5405311 4.59497 --20.9892 -0.1161791 4.72888 --20.5949 0.6532929 5.30865 --20.718 -0.1808591 5.82477 --21.3009 -0.9740661 5.85079 --20.4957 -1.54793 6.01556 --20.851 -1.83954 6.86934 --19.8886 -2.15355 6.953 --19.1618 -2.76549 7.18901 --19.5949 -3.17614 6.35648 --20.4163 -3.36997 5.7407 --20.7456 -2.74841 5.04995 --21.7135 -3.0382 4.87326 --22.0084 -3.79759 5.43515 --22.5455 -3.69963 6.21678 --21.5322 -3.55069 6.33498 --20.9944 -4.30631 5.91357 --21.6653 -5.02454 5.56417 --21.8906 -5.22584 4.6327 --22.236 -6.19439 4.60642 --22.136 -7.13678 4.37829 --22.5563 -7.68685 3.61776 --23.2376 -7.29286 3.00613 --22.8 -6.5743 3.37931 --23.443 -6.03809 3.91882 --23.79 -6.76359 4.49515 --23.8292 -7.61084 3.90571 --24.8033 -7.54284 3.94811 --25.0724 -6.64289 4.3289 --25.7831 -7.17918 4.80852 --25.0391 -7.57836 5.31641 --24.4711 -8.39308 5.50226 --24.7625 -8.5808 6.40293 --23.7002 -8.4737 6.38614 --23.6306 -7.47349 6.48781 --23.9674 -7.37908 7.43753 --24.8728 -7.60503 7.81357 --25.7772 -8.03633 7.47732 --26.7986 -8.21379 7.60739 --27.5229 -7.9706 7.0419 --27.8471 -8.89817 7.26341 --28.1121 -8.6893 8.21224 --28.9728 -9.02268 8.17426 --28.8008 -9.47214 7.25817 --28.8903 -10.3333 7.79188 --29.746 -10.5798 8.25109 --30.2959 -10.401 9.12726 --30.7124 -9.47618 8.9877 --30.8798 -8.49928 8.77141 --30.4961 -8.20407 7.89625 --30.9602 -7.89842 7.10152 --31.4638 -7.77651 6.30762 --31.6427 -8.74012 6.23402 --31.6774 -9.67418 5.91967 --31.0421 -10.2497 5.35899 --30.434 -9.95114 4.64196 --30.2946 -9.93402 3.684 --29.688 -9.6531 2.94686 --29.5911 -8.959 2.21303 --29.9523 -8.91761 1.21904 --29.1395 -9.26679 0.7553351 --28.503 -10.0408 0.5690901 --28.6741 -10.4062 1.53046 --27.7655 -10.5537 1.55209 --27.6485 -9.52329 1.54315 --26.8908 -9.45588 2.13679 --25.9656 -9.59319 2.21339 --24.9448 -9.70667 2.01664 --25.1802 -8.9631 1.35016 --24.5921 -9.64305 0.8507291 --24.3806 -8.67904 0.7143361 --23.5636 -8.75185 1.26997 --23.0839 -9.58895 0.8988761 --23.4821 -10.5274 0.7296581 --22.7368 -10.5616 1.41766 --23.604 -10.7885 1.85289 --23.9343 -11.7354 1.83459 --23.7885 -12.4241 2.53541 --23.0343 -12.3539 3.11046 --22.594 -11.5382 2.91653 --22.1069 -10.9557 3.73236 --22.6658 -10.1148 3.76703 --22.2654 -10.191 4.69965 --21.3227 -9.79043 4.83072 --21.4849 -8.89094 5.24785 --21.1539 -8.59825 4.32443 --22.0821 -8.75689 4.13776 --22.9614 -8.57513 4.54538 --23.5514 -8.69337 3.75768 --23.6217 -8.64355 2.69243 --22.5522 -8.49205 2.53009 --21.5255 -8.20206 2.42071 --20.8184 -7.44592 2.7268 --21.2732 -6.99189 1.93919 --20.5244 -6.55127 2.43428 --19.5055 -6.60945 2.38919 --19.6376 -6.25765 3.34364 --20.1163 -6.40019 4.20926 --20.0477 -6.18986 5.18335 --20.4173 -6.08217 6.08258 --20.1527 -6.84352 6.6312 --20.2438 -6.84642 7.62796 --20.1151 -6.02152 8.18266 --19.5463 -5.29809 7.79836 --18.5407 -5.2194 7.80755 --18.5422 -5.15157 8.78069 --17.6793 -5.34803 9.24246 --17.1312 -5.73615 8.47341 --16.5052 -6.51722 8.28069 --15.6275 -6.87766 8.45374 --14.859 -6.1837 8.17454 --14.3886 -6.80816 7.5019 --13.5538 -7.12615 7.12711 --12.9374 -7.98799 7.23576 --13.065 -8.48872 6.42189 --12.6729 -9.02608 5.55513 --12.6995 -9.95237 5.12177 --13.0213 -10.882 5.42496 --12.2789 -10.7597 6.13712 --11.5385 -10.4565 6.72089 --11.4599 -11.4333 6.58586 --10.9839 -12.0721 7.16727 --11.3923 -12.9527 6.85925 --10.4544 -13.2842 6.57464 --10.3448 -13.5834 7.55042 --9.36605 -13.4526 7.56272 --9.13512 -14.1902 6.88959 --9.05221 -14.9759 6.308 --8.09812 -14.8128 6.25897 --8.34814 -14.8619 5.2853 --8.28847 -14.0104 4.74117 --9.26922 -14.2976 4.5517 --9.56161 -13.3339 4.71015 --9.09019 -12.6176 4.36058 --9.69881 -11.7685 4.27918 --10.1788 -10.8784 4.21103 --10.2803 -10.4842 5.08128 --9.42287 -9.9416 5.21628 --8.69397 -9.26695 5.47643 --9.55931 -8.84293 5.67031 --9.62325 -7.89428 5.42089 --9.78625 -7.6749 6.34588 --10.5881 -7.49276 6.89485 --10.7426 -7.43651 7.86997 --10.5225 -8.37894 7.56393 --9.5659 -8.30768 7.45785 --8.60888 -8.25004 7.23432 --8.10368 -8.53678 6.46875 --8.16843 -7.77673 5.91658 --7.98731 -8.18694 5.10034 --8.56159 -8.64916 4.41937 --9.47951 -8.8574 4.10219 --10.2839 -9.4285 3.89998 --11.3399 -9.57069 4.26419 --11.4181 -8.69596 3.79048 --12.4444 -8.73447 3.54697 --13.1544 -9.02972 4.24557 --13.1293 -8.14467 4.70069 --12.214 -7.97171 4.52973 --12.5264 -7.60213 5.44221 --13.2552 -6.94897 5.48903 --12.8803 -6.52341 4.67416 --12.2577 -6.9935 4.04542 --12.23 -6.94654 3.07282 --13.1814 -7.23969 3.278 --13.6149 -6.90467 2.47307 --13.4081 -6.45824 1.56555 --14.3161 -5.93179 1.41258 --14.0942 -5.345 2.16926 --13.093 -5.33255 2.06693 --13.3614 -5.96065 2.69728 --13.3455 -6.10453 3.70964 --13.291 -5.08153 3.73874 --13.5227 -4.08192 3.60732 --12.8318 -3.84538 2.88551 --12.2017 -4.47169 2.30971 --13.0649 -4.20864 1.91403 --12.3919 -3.46652 1.86509 --12.2097 -2.51721 1.87325 --12.0268 -1.50788 2.05332 --11.182 -1.20994 1.5109 --10.2539 -1.41675 1.8266 --10.2083 -1.0579 0.8957651 --9.23047 -0.8263741 0.8760581 --9.50883 -0.9359691 -0.08010118 --9.76948 -1.7394 -0.5646889 --8.73503 -1.93784 -0.2816079 --8.57486 -2.13745 0.7269531 --8.47035 -2.34422 1.65492 --9.01899 -2.43475 2.42116 --9.93013 -2.3205 2.78805 --10.0115 -3.32079 2.96323 --9.53198 -4.00714 2.4232 --9.90379 -4.69911 3.07948 --10.2124 -5.53136 3.58917 --9.32789 -5.21775 3.92169 --8.78577 -5.6123 3.24836 --8.2262 -6.39516 3.64534 --9.07472 -6.55511 4.15219 --9.95873 -6.76745 3.65097 --10.9601 -6.59397 3.84586 --10.528 -6.35217 4.81108 --11.1546 -6.12326 5.52947 --11.9662 -6.65645 5.65621 --11.5739 -7.37179 6.14975 --10.895 -7.99238 5.81369 --10.6494 -8.39647 4.99536 --10.6841 -7.59934 4.36684 --10.8011 -7.90372 3.43788 --11.5797 -7.90165 2.80754 --11.8738 -8.40201 1.99107 --12.3779 -8.8358 1.32324 --12.1949 -9.81591 1.06708 --11.7486 -10.6639 0.6752741 --11.4646 -10.6223 -0.2737539 --10.5722 -10.2134 -0.4441349 --9.74434 -10.6118 0.08877352 --9.41957 -9.70531 -0.1728289 --8.7107 -9.2652 -0.6094719 --8.48307 -8.70124 0.1721361 --9.32538 -8.24195 0.1610261 --9.81965 -7.62159 -0.4705099 --10.5853 -8.12014 -0.8857959 --9.79943 -8.28606 -1.45246 --9.9958 -7.40668 -1.92818 --9.03246 -7.00161 -1.75905 --8.41029 -7.43586 -1.00455 --7.88792 -8.18547 -0.6848129 --6.95254 -7.9172 -0.3502299 --6.51523 -8.57556 -0.9225159 --6.20996 -8.03278 -1.7017 --5.79324 -7.56806 -2.44666 --5.09654 -8.20497 -2.81053 --5.69394 -7.85312 -3.62041 --6.28493 -8.69572 -3.8482 --5.62196 -9.35362 -4.13606 --5.05595 -9.86458 -4.80535 --4.8463 -10.3696 -3.92742 --4.00834 -10.9421 -3.75403 --3.0147 -11.0427 -4.04114 --3.07436 -11.9539 -3.57949 --2.08063 -12.2464 -3.64869 --1.89176 -13.1716 -3.31735 --1.63678 -14.0276 -3.82369 --1.76657 -15.0393 -3.85377 --2.66128 -14.714 -3.60785 --3.40214 -14.1579 -3.21253 --3.15056 -14.7785 -2.43178 --3.90951 -14.6443 -1.81137 --4.42118 -13.8541 -1.82912 --4.00248 -13.824 -0.9943129 --4.72723 -13.9457 -0.3147079 --4.22101 -14.1328 0.4992931 --3.33089 -14.3674 0.1724631 --3.25142 -13.5138 -0.3833709 --2.42272 -13.0636 -0.3962309 --1.62059 -12.8028 0.03944742 --1.57508 -11.7708 -0.1718979 --1.67002 -10.774 -0.2343349 --1.62652 -10.3737 0.5974801 --1.11186 -9.60659 1.02011 --0.336853 -9.48398 0.3556071 -0.432066 -9.15993 0.9872611 -0.08077057 -9.33408 1.95711 -0.672739 -8.69878 2.38883 -0.909954 -7.77095 2.51119 -1.45528 -7.41416 3.35335 -2.41493 -7.15281 3.14864 -2.83638 -6.24356 3.5237 -3.08094 -6.54208 4.51597 -3.948 -6.56963 4.19237 -4.89748 -6.64691 4.2155 -4.59642 -6.70164 5.17332 -5.14828 -5.97505 5.64504 -5.23701 -6.88507 6.00631 -4.95753 -6.72924 6.97154 -4.7598 -7.64717 7.12428 -4.65204 -8.29601 7.84901 -3.82519 -8.74655 8.21496 -4.4953 -9.49388 8.02825 -5.04671 -9.46476 8.87931 -5.23522 -10.3971 8.43525 -6.12849 -10.3272 7.97872 -6.30115 -10.9495 7.14048 -5.67761 -10.4938 6.52576 -5.77502 -9.6163 5.99313 -5.41567 -8.88076 5.6377 -4.50628 -9.08393 5.21407 -5.038 -9.0742 4.3738 -5.79647 -8.42463 4.61976 -5.91618 -7.52148 4.41029 -5.0718 -7.58135 3.81229 -4.33099 -8.18745 4.09156 -4.56226 -8.73472 3.2743 -3.71178 -8.99162 2.78355 -3.98714 -8.32947 2.06322 -4.84558 -7.93126 2.62387 -5.57227 -7.74836 1.97118 -6.58354 -7.65636 2.19929 -6.3115 -8.68952 2.33013 -6.99898 -8.20951 2.90278 -7.30997 -9.15742 2.90309 -7.55762 -10.0051 2.43757 -7.97548 -10.7502 2.92323 -7.60417 -10.4541 3.76985 -7.07053 -10.387 4.62572 -6.69373 -9.75756 3.99018 -6.73742 -8.96194 4.70256 -7.18747 -8.11495 4.75792 -7.26797 -8.61822 5.59198 -6.67993 -9.4375 5.54108 -7.11418 -9.82905 6.32256 -7.70887 -9.20054 6.84463 -8.3969 -9.22973 7.59042 -7.93399 -8.35582 7.73638 -8.33891 -7.45251 7.41603 -7.907 -7.35248 8.39137 -8.05037 -6.43259 7.93478 -7.88318 -6.19632 8.92142 -8.80584 -6.09829 9.19357 -8.7957 -5.09305 9.1631 -9.06011 -4.68811 8.25584 -9.10664 -5.68326 7.89006 -9.95487 -5.63963 8.40052 -10.5617 -5.01073 8.91856 -11.2659 -5.21506 9.5241 -11.7312 -5.78802 10.2017 -11.9783 -5.58917 11.1457 -11.1968 -5.46798 11.7961 -10.521 -6.14165 12.0489 -10.1598 -6.73281 12.7502 -10.0509 -7.75274 12.755 -10.4214 -7.42335 11.9464 -11.179 -7.1991 11.3393 -11.5893 -7.35188 12.2063 -12.312 -6.87068 12.6281 -12.6831 -7.85429 12.569 -12.132 -8.55427 12.1788 -12.4208 -8.62453 13.148 -12.117 -7.92937 13.7809 -11.9941 -7.80083 14.814 -11.1956 -7.98021 15.2516 -10.2209 -7.84038 15.1375 -10.499 -7.20543 14.3926 -10.338 -8.17589 14.1404 -11.0599 -8.80375 14.4674 -10.2212 -9.27043 14.6364 -10.0317 -10.2286 14.8203 -9.27894 -10.0622 14.1543 -9.28348 -10.2237 13.1694 -8.3882 -9.88387 12.7372 -9.12077 -10.2231 12.1365 -9.84451 -10.9652 12.071 -10.2218 -10.3904 11.3941 -10.8749 -10.2237 12.1753 -10.9662 -10.5272 13.0751 -10.2356 -10.7522 13.6997 -10.097 -11.6126 13.2576 -9.7299 -11.6733 14.1353 -9.72061 -12.6372 13.9723 -9.95925 -12.6577 14.986 -10.6026 -11.9496 14.7323 -11.0771 -11.4066 15.4231 -11.568 -11.3582 16.2924 -11.836 -12.1332 16.9063 -12.4842 -12.1259 16.1551 -12.3887 -13.0385 15.7703 -11.5151 -13.3255 16.1246 -11.6945 -13.1965 17.0686 -12.1283 -13.3922 18.0062 -12.9073 -12.835 17.8343 -12.9377 -12.737 18.8467 -13.7886 -12.5446 18.37 -14.5484 -12.7001 17.8034 -14.6223 -13.6912 17.5474 -15.1482 -13.0638 16.8972 -15.4914 -12.098 17.0241 -15.3908 -12.0734 18.0553 -16.2857 -12.2579 18.4674 -15.837 -11.9502 19.4511 -15.0682 -11.3599 19.2191 -14.1151 -11.0734 19.236 -13.7463 -11.6337 20.0014 -13.464 -10.693 20.0342 -13.3875 -10.2778 20.8855 -12.8586 -9.57002 20.4024 -12.3171 -10.1753 19.7942 -11.6184 -10.2722 19.0898 -11.0216 -11.1185 19.2511 -10.6646 -11.1746 18.3268 -10.0072 -11.8448 17.8362 -10.6281 -12.2214 17.1054 -9.70475 -12.6013 17.2345 -9.54628 -13.3623 16.629 -9.03207 -14.0296 16.0862 -9.15908 -15.0596 16.2307 -9.97682 -15.589 16.5196 -9.64289 -15.0507 17.2821 -9.29262 -15.8812 17.7548 -9.70394 -16.7703 17.5603 -10.4463 -16.1508 17.7905 -11.1285 -15.388 17.9942 -12.1672 -15.2387 18.1737 -12.2818 -14.5877 18.9012 -12.5207 -14.2603 19.7641 -13.2142 -13.5657 19.5923 -14.0689 -13.7234 20.098 -13.3768 -14.3737 20.3532 -14.1037 -14.8915 20.8492 -15.0753 -15.067 20.7612 -15.5458 -14.1786 20.9295 -16.1044 -14.7987 21.4944 -16.5785 -14.1033 22.1712 -16.3962 -14.7314 22.8081 -15.5339 -15.2002 22.563 -14.8567 -14.7534 23.1389 -14.9203 -13.7776 23.2839 -14.1287 -13.9812 23.9652 -13.5534 -13.2898 24.4116 -12.9358 -12.6489 24.7571 -13.6792 -12.7236 25.4095 -12.8047 -13.0673 25.8156 -12.3128 -13.786 26.0631 -12.1828 -14.7107 25.7874 -11.9604 -15.7245 25.5152 -11.9557 -14.9466 24.8212 -12.1404 -14.3119 24.0808 -11.2077 -14.6287 24.0369 -11.5552 -14.1281 23.2436 -11.9346 -15.0942 23.1616 -11.5949 -14.8565 22.1977 -10.694 -15.2886 22.1302 -9.88386 -15.5283 22.6895 -9.99171 -16.1353 23.5583 -9.98111 -15.2847 24.2282 -9.12663 -15.8338 24.1335 -8.72211 -16.4585 23.4502 -7.92623 -17.0423 23.7967 -8.43447 -17.9295 23.5176 -7.70158 -18.4094 23.9847 -7.14815 -17.7081 24.4458 -6.67664 -18.5331 24.7911 -5.68821 -18.6968 24.4916 -4.90188 -19.3676 24.5507 -4.95213 -19.6661 23.6052 -3.96198 -19.4151 23.3217 -3.32503 -18.6214 23.0502 -3.44208 -17.924 23.7381 -4.20431 -17.278 23.7983 -3.78635 -16.4847 23.2939 -3.36994 -16.0585 22.4795 -2.39729 -15.7667 22.3306 -1.3923 -15.7672 22.447 -1.0172 -15.9977 21.605 -0.725339 -15.5067 20.799 -1.1464 -14.6508 20.5897 -1.13883 -13.9521 21.238 -0.431807 -13.9369 20.5156 --0.03169973 -13.4196 19.7529 --0.199314 -12.4593 19.4866 -0.01266417 -12.2618 20.4542 -0.290117 -11.8129 21.3103 --0.682834 -11.4939 21.2808 -0.07871707 -10.9362 21.7149 --0.27504 -10.0752 22.2741 --0.03392763 -10.1927 23.2752 -0.292354 -10.9387 22.797 -1.09712 -11.3906 22.3685 -0.728895 -11.718 23.305 --0.268841 -11.773 23.4099 --1.17271 -11.9957 23.7204 --0.647067 -11.5344 24.3714 --0.249529 -10.8341 24.998 -0.654183 -10.6325 25.4435 -0.965977 -9.82209 24.9564 -1.38526 -9.1748 25.5864 -1.05991 -8.78347 26.4863 -1.29989 -9.28799 27.3017 -1.83867 -8.79225 27.9833 -2.53922 -8.32349 27.4377 -2.45067 -8.11709 26.466 -3.30334 -8.17723 26.8565 -3.76545 -7.42818 27.3832 -4.20815 -7.30239 28.3438 -3.47749 -7.61795 28.8443 -3.75542 -6.93913 29.4925 -3.49527 -7.40704 30.3288 -2.59322 -8.02761 30.3854 -2.53578 -8.82534 29.7945 -2.5859 -8.97016 28.788 -2.77692 -9.98062 28.7493 -2.26536 -10.6663 29.25 -1.92433 -11.6165 29.3157 -1.67925 -11.5422 30.2424 -2.64987 -11.5834 30.4728 -3.2702 -11.3923 31.2342 -3.53337 -11.6183 32.178 -2.73506 -12.2551 31.9717 -1.86343 -12.7123 32.0377 -1.97009 -13.3576 31.3318 -1.27986 -13.5194 30.711 -1.30898 -13.2514 29.727 -1.54466 -14.2101 29.652 -0.519134 -14.4606 29.7116 --0.174577 -14.6752 30.3083 --0.149983 -15.3387 29.5832 --0.08527413 -16.2852 29.9599 -0.816636 -16.0088 30.4331 -1.5182 -15.2693 30.5339 -2.53831 -15.4312 30.4409 -2.56591 -15.0899 29.4367 -3.49535 -15.321 29.6702 -3.95118 -15.2959 28.7779 -4.76522 -14.7016 28.9266 -5.01779 -13.7387 28.669 -5.27605 -13.6048 27.7787 -4.74446 -12.9493 27.2891 -4.09996 -13.1977 28.0048 -3.47253 -13.8934 28.3046 -3.6815 -14.7329 27.7457 -3.98234 -15.1186 26.8569 -4.31935 -16.0299 26.8799 -5.10366 -15.4362 27.1509 -5.61577 -15.2916 28.0265 -5.98613 -15.9959 28.6391 -6.72397 -16.2773 28.0296 -6.0561 -16.1552 27.2418 -5.40599 -16.7146 26.7141 -5.48422 -16.2691 25.8193 -4.48032 -16.1774 25.7227 -4.32304 -15.1964 25.6078 -3.63423 -15.7527 25.1602 -2.80507 -15.3075 25.3725 -2.38962 -14.8054 26.1547 -1.65822 -15.1476 26.7986 -1.6929 -16.0912 27.1249 -2.33599 -16.9379 27.3601 -1.77605 -17.7042 27.3306 -2.12298 -18.5888 27.0257 -1.3978 -18.8995 26.4103 -2.11015 -19.5033 26.0965 -2.48352 -18.6382 25.7075 -2.89624 -19.2934 25.0888 -1.97937 -19.0535 24.7623 -1.83954 -18.4934 24.0073 -1.4574 -17.5344 23.876 -0.688629 -17.6855 23.2747 -1.34595 -18.3463 22.9697 -0.707629 -19.0883 23.158 --0.108001 -18.8305 23.7196 --0.462673 -19.6956 23.4572 --0.876909 -20.5862 23.2193 --1.54809 -20.6632 22.5176 --1.97861 -20.3421 23.3592 --2.84115 -19.7889 23.3744 --2.19498 -19.0301 23.6581 --1.89968 -19.4248 24.5108 --2.2922 -19.4154 25.4431 --1.41913 -19.3257 26.0188 --1.36056 -20.178 26.5309 --1.27834 -21.1745 26.4197 --1.24742 -22.2056 26.2937 --0.535256 -22.7409 25.7781 -0.2824 -22.2026 26.1188 -0.807009 -22.3173 25.2541 -1.74429 -22.0295 25.2949 -2.54869 -21.4617 25.4179 -2.95405 -21.2111 24.5657 -2.44994 -21.0632 23.7664 -2.53639 -21.9808 23.4023 -3.08859 -22.7716 23.6821 -3.52303 -23.3115 24.4472 -4.02005 -23.9697 25.0146 -4.89749 -23.5002 24.8581 -5.06867 -23.2381 23.8369 -5.60881 -22.448 23.7529 -5.79652 -22.1132 22.8345 -6.2619 -22.4822 22.0153 -6.62932 -23.408 22.115 -5.92652 -23.6284 22.8216 -6.25707 -24.4767 23.0366 -5.73137 -25.0699 22.4835 -6.56579 -25.6581 22.3257 -7.00724 -26.523 22.7207 -7.15678 -26.7409 21.7357 -6.93846 -26.829 20.7076 -6.43078 -26.5557 19.892 -6.0891 -27.121 19.1746 -5.36694 -27.7347 19.3371 -4.99255 -28.6367 19.1846 -5.0596 -28.6368 20.1468 -4.46459 -28.4094 20.9074 -3.86487 -29.23 20.8405 -3.91483 -28.9199 19.8418 -3.21227 -29.5983 19.7592 -2.73599 -29.5096 18.934 -3.5609 -29.1522 18.4077 -3.37913 -29.3521 17.4118 -3.69959 -30.2931 17.2895 -3.06128 -30.8917 16.8109 -2.1127 -30.8282 16.4966 -2.61277 -30.9872 15.6386 -2.97332 -30.7242 14.7375 -3.50087 -30.4775 13.9507 -4.42087 -30.1839 14.3241 -5.16096 -29.9129 14.9925 -5.26521 -29.2888 15.733 -4.26871 -29.0336 16.036 -4.20427 -28.7056 15.0965 -4.4272 -28.875 14.1493 -5.10462 -28.719 13.3732 -5.44286 -29.1241 12.5427 -5.15537 -29.5327 11.6438 -4.87956 -30.0046 10.8106 -4.7889 -30.91 10.4992 -4.06691 -31.0006 9.75587 -4.31936 -31.8397 9.25919 -4.94265 -31.7022 8.51658 -5.69201 -31.591 9.21544 -6.05245 -32.2578 8.55484 -7.01854 -32.5895 8.53958 -7.25508 -32.5468 7.567 -7.01894 -32.8624 6.61589 -6.41158 -32.1169 6.5313 -6.02511 -31.5674 5.76293 -5.46756 -31.2046 6.48122 -6.00498 -31.3533 7.35979 -6.57477 -30.7834 6.79277 -7.4564 -31.2102 7.04994 -7.50028 -30.3391 6.55868 -6.77008 -30.0039 6.02851 -6.14042 -29.2632 6.26375 -5.37542 -29.5274 5.81603 -5.16051 -30.3033 5.25944 -5.63311 -30.5625 4.38306 -6.33821 -29.9407 4.16891 -6.94997 -30.5923 3.77024 -6.60244 -30.2052 2.96887 -6.75446 -30.1783 2.03276 -7.088 -31.0786 2.17532 -6.28471 -31.3804 1.65422 -6.06878 -31.9897 0.7806721 -5.09407 -32.0449 0.3878521 -4.41302 -31.9268 1.14882 -4.27991 -32.4016 2.00379 -3.92176 -33.2783 1.76938 -4.23981 -34.2466 2.06049 -5.08944 -33.7855 2.09426 -5.90305 -33.2952 2.49566 -6.69152 -32.8372 2.92915 -7.10439 -32.6909 3.78489 -6.75413 -31.7586 3.71431 -7.61967 -31.4689 4.19098 -7.46374 -30.9786 5.08755 -8.20464 -30.4909 4.69328 -8.78869 -30.4725 3.94162 -9.55189 -30.4844 3.2895 -9.94315 -30.7957 2.45022 -9.86763 -31.7499 2.42608 -10.4961 -32.1932 1.84059 -9.65242 -31.9568 1.36016 -10.0294 -31.1282 0.9094231 -9.66795 -30.1425 0.9582691 -10.449 -29.5794 1.08684 -10.2411 -28.592 0.7743931 -11.1735 -28.6603 1.25335 -10.8277 -28.0337 1.92742 -10.339 -27.4794 2.59028 -9.306 -27.3339 2.81054 -8.53278 -27.6322 2.24473 -7.67185 -27.1785 2.56715 -7.20193 -26.259 2.30337 -8.10617 -26.2789 1.95761 -8.64807 -26.5757 1.24665 -8.53029 -27.5536 1.09649 -8.77867 -27.847 0.1648101 -8.97438 -27.0583 -0.4114099 -9.67526 -26.3842 -0.05133288 -10.5479 -25.9287 -0.03319518 -10.5607 -25.1347 -0.7400499 -9.60357 -25.1824 -0.9198149 -8.80356 -25.7505 -0.8872829 -8.02858 -26.1273 -1.44816 -7.7948 -25.1505 -1.54965 -7.46366 -24.959 -2.46012 -7.13635 -25.8907 -2.38113 -6.84258 -26.7744 -2.81514 -6.59198 -26.3773 -3.71811 -5.82379 -25.7037 -3.72308 -5.71126 -25.7539 -2.70447 -4.92815 -26.4689 -2.69205 -4.1097 -26.9138 -3.12939 -3.54376 -26.391 -2.51984 -3.7106 -25.6569 -1.80025 -4.52964 -26.2343 -1.55838 -4.55375 -26.8973 -0.7863659 -3.88718 -26.3333 -0.1962089 -3.01699 -26.2429 0.2913851 -3.61306 -25.6401 0.8360921 -4.19151 -24.8604 1.0508 -3.49137 -24.1774 0.8038601 -3.18427 -23.2902 1.23812 -2.43248 -23.9323 1.36908 -2.37176 -23.5649 2.34107 -1.36405 -23.5402 2.63652 -1.95831 -22.8877 3.19233 -2.40156 -22.0312 2.88845 -3.12641 -21.3777 2.7191 -3.84184 -20.7329 2.5338 -3.35147 -20.7703 1.6574 -4.1301 -20.0916 1.5808 -3.12667 -19.713 1.70466 -3.09079 -18.9287 2.30945 -2.34069 -18.5274 2.91442 -2.51281 -17.5483 3.08418 -2.08626 -16.7421 3.42472 -3.01169 -16.897 3.73091 -3.81953 -17.2272 4.25209 -4.34185 -17.361 5.08157 -3.342 -17.5525 5.07987 -2.6273 -18.2467 4.95602 -2.18612 -17.8911 5.74418 -2.39674 -17.8796 6.63488 -3.39198 -18.0747 6.78539 -3.34136 -17.9617 7.8115 -2.83865 -18.0238 8.69303 -3.73414 -18.2459 9.05234 -4.60729 -18.1067 9.5404 -5.34405 -17.7884 8.99116 -4.61571 -17.5964 8.36354 -4.71512 -16.6839 8.09093 -3.85546 -16.3119 8.43661 -3.54957 -15.3833 8.86311 -2.60937 -15.746 8.51148 -1.71982 -15.6868 9.0269 -1.57991 -15.5125 8.09272 -0.794504 -14.9549 8.18173 -0.166124 -14.1728 8.09784 -0.436231 -14.1736 7.13912 -0.778462 -13.2149 7.06021 --0.08411993 -13.1487 7.58119 --0.770971 -12.5211 7.08491 --1.31601 -12.3584 7.94635 --1.06838 -13.1397 8.43886 --0.958268 -12.7637 9.3415 --1.8792 -12.3874 9.59024 --2.3114 -13.1585 9.28982 --2.87657 -13.9504 8.97557 --2.66081 -14.7454 9.55889 --1.83837 -15.1645 9.7555 --2.10956 -15.8522 10.4864 --2.20354 -16.727 10.0684 --2.19288 -17.5164 9.41281 --2.80917 -18.2756 9.184 --2.6144 -18.8812 10.0036 --3.31415 -19.5641 10.0232 --3.51747 -19.8565 9.13854 --4.38988 -19.6461 9.63977 --4.06872 -20.5848 9.77979 --4.63817 -21.345 9.44221 --4.34385 -22.2107 9.08414 --3.33298 -22.0798 8.92704 --3.72614 -22.3781 8.07962 --2.99287 -21.7021 7.87074 --2.10456 -21.256 7.88261 --1.81144 -21.3777 8.84327 --2.15753 -20.754 9.56648 --2.42406 -20.7831 10.4757 --3.13826 -21.5109 10.5491 --3.05383 -21.3537 11.5143 --3.9174 -21.1297 11.9879 --4.02796 -20.4916 11.2382 --5.00291 -20.3972 11.1148 --5.17723 -19.7483 10.4044 --5.1926 -19.0445 11.1526 --5.31865 -19.5651 11.9568 --6.07963 -20.19 12.2252 --6.63524 -19.6753 12.7716 --6.36725 -19.2462 11.865 --6.19625 -18.4947 11.2311 --6.33071 -17.5618 10.8432 --6.74884 -17.8079 10.0244 --7.07065 -17.2916 9.25436 --7.8367 -17.4916 9.92358 --7.98473 -18.4803 9.86211 --7.08634 -18.8819 10.2249 --6.31155 -19.4265 9.86869 --5.56577 -18.8609 9.54426 --4.95549 -18.1097 9.31955 --4.14308 -18.744 9.11453 --4.66193 -18.9386 8.27486 --4.25268 -18.0536 8.07225 --4.12011 -18.3423 7.08113 --4.37857 -18.4467 6.12653 --3.4432 -18.0029 6.1649 --3.08436 -18.8696 6.42886 --2.3448 -19.4761 6.68824 --2.43923 -19.7932 7.60801 --3.00117 -18.9215 7.63017 --2.0121 -18.7304 7.67984 --1.65559 -18.0215 7.12076 --1.32377 -18.1171 6.14431 --0.589749 -17.4005 6.01699 --1.52826 -16.9539 6.08019 --2.27802 -17.4812 5.75332 --2.76673 -16.8203 6.30379 --3.67332 -16.7793 6.01003 --3.76494 -15.795 6.23469 --3.70776 -14.9935 5.58204 --3.46638 -14.5391 6.44044 --2.82092 -15.3574 6.61286 --1.88157 -15.403 6.46462 --1.42555 -14.5775 6.20287 --2.21204 -14.1701 5.5946 --3.19711 -13.8797 5.32895 --4.10084 -13.8998 4.96984 --4.30015 -14.6775 4.29614 --4.81359 -14.3979 3.50498 --5.03346 -13.4187 3.30984 --5.0091 -12.3744 3.37242 --4.28706 -11.6514 3.42177 --3.84528 -12.5351 3.42797 --3.395 -13.3572 3.88394 --2.55321 -12.9156 3.85573 --2.46949 -13.8245 3.41844 --1.83466 -13.888 4.16778 --1.07269 -14.3704 4.65028 --0.204381 -14.0622 5.07115 -0.604582 -14.7705 5.28947 -0.04996767 -15.5978 5.02013 --0.167659 -16.5286 5.22067 --0.761388 -16.5196 4.4443 --0.07502663 -16.7822 3.73273 -0.531513 -17.104 4.44652 -1.23369 -17.8473 4.29427 -2.13424 -17.5952 4.28589 -2.12737 -16.7452 4.93626 -2.22306 -15.8372 4.99855 -2.16645 -14.8806 4.86766 -2.98479 -14.3478 4.9732 -3.77318 -14.5619 5.52073 -4.55577 -14.6465 6.24447 -5.16692 -14.2527 6.86266 -5.0017 -13.4425 6.22649 -3.98909 -13.4933 6.02705 -3.89183 -12.4989 6.23804 -3.08419 -12.9966 5.96056 -3.35128 -12.6337 5.02006 -2.76839 -12.016 4.57669 -2.60178 -12.5342 3.68564 -2.17268 -12.9641 4.48567 -1.98284 -13.4455 5.30958 -1.23317 -13.9545 4.84272 -0.852034 -13.0821 4.69283 -0.218634 -12.7286 5.42728 -0.04598387 -11.7534 5.41253 --0.858053 -12.0784 5.77539 --1.35532 -11.381 6.2955 --0.741542 -11.0492 7.01377 -0.222019 -11.2074 6.82516 -0.644275 -11.7889 7.55778 -1.10859 -12.2843 8.27182 -1.57917 -11.3455 8.54345 -1.82791 -10.5394 8.0276 -1.48096 -9.72162 8.55164 -1.23803 -9.52806 7.59175 -2.18086 -9.17617 7.4343 -2.95304 -9.33066 6.88949 -3.55401 -10.0112 6.38102 -4.10665 -10.7839 6.26092 -3.86506 -10.1015 5.60869 -3.06497 -9.81245 5.12774 -3.24052 -8.84732 5.09376 -3.87724 -8.13332 5.14488 -3.05207 -7.56565 4.83897 -2.35379 -7.85068 5.52982 -1.72768 -7.14177 5.21044 -2.47821 -6.50118 5.39008 -2.1846 -5.85607 4.61829 -2.55993 -5.40375 5.42054 -2.19381 -5.4894 6.37177 -2.72036 -6.28649 6.74202 -2.14555 -6.10452 7.45072 -1.92842 -6.58579 8.2491 -2.77021 -6.06855 8.68678 -3.68443 -6.34615 9.04043 -4.61243 -6.55482 8.85427 -5.23878 -7.33384 8.92016 -5.71794 -8.11888 8.73715 -6.46797 -8.20633 9.3932 -7.19502 -7.57988 9.44107 -6.98279 -6.56206 9.40688 -6.33106 -6.06809 8.80385 -6.94728 -5.53913 8.20479 -7.02893 -4.54694 7.92184 -7.2901 -5.23104 7.22779 -6.7799 -4.84429 6.44579 -7.23038 -3.98781 6.18673 -6.25066 -3.98663 5.89311 -6.42988 -3.2669 5.20572 -5.87521 -2.44693 5.35534 -6.08657 -2.61301 6.3555 -5.93349 -3.46375 6.94639 -5.17192 -3.13405 7.53098 -4.60964 -3.51306 8.36184 -3.69706 -3.96352 8.49253 -3.26228 -3.6165 9.30574 -3.35026 -4.22518 10.0215 -4.09151 -4.94097 10.0338 -3.31965 -5.17435 10.7026 -3.9591 -5.52151 11.3416 -4.08907 -6.42336 10.8501 -4.97599 -5.95218 10.8875 -5.61309 -5.11238 11.0406 -5.60291 -4.31445 10.5124 -5.0333 -3.62238 10.2114 -4.84778 -2.8316 10.9084 -3.98949 -2.3663 11.151 -3.7653 -1.99442 10.2379 -3.47019 -1.32741 9.52049 -3.91333 -0.5187531 8.99508 -4.65039 -1.19749 8.77088 -5.37174 -1.66994 9.29078 -6.14833 -2.24294 9.64288 -7.02875 -1.91319 9.3368 -7.83577 -1.68445 8.69591 -8.57591 -2.34071 8.96902 -7.99773 -3.09338 8.69459 -7.4737 -2.83836 9.54882 -6.96497 -3.16523 10.3481 -7.96687 -3.3058 10.4128 -7.49334 -3.77973 11.2084 -6.77729 -3.74953 11.8964 -7.4131 -3.9005 12.5595 -6.49517 -4.00731 12.798 -5.76858 -3.89104 13.5446 -5.09561 -4.70182 13.7053 -4.2207 -4.9355 14.1136 -3.38476 -5.19204 13.6223 -3.24404 -5.55199 14.5565 -3.03688 -5.34152 15.5333 -3.68541 -6.12894 15.5208 -4.41917 -5.6839 16.0052 -4.34889 -6.67442 16.0366 -3.43891 -7.05232 15.8659 -2.62956 -7.20852 16.4767 -2.69145 -8.16487 16.093 -1.82258 -8.43695 15.8278 -1.3441 -7.79057 16.4579 -0.765754 -7.53005 17.1835 -0.430452 -8.20105 17.9422 --0.283059 -8.82487 18.0717 --0.515426 -9.82416 18.1682 -0.29211 -10.258 17.8496 -0.716902 -10.9073 18.4042 --0.144323 -11.2171 18.0334 --0.04546883 -12.158 18.3781 --0.356866 -12.7668 17.6711 --0.397227 -12.6639 16.6379 --0.416311 -11.8646 16.0312 --0.437444 -12.5074 15.371 -0.01688057 -13.1286 14.8799 --0.839018 -13.6232 14.5571 --0.785639 -12.6251 14.4972 -0.104365 -12.3285 14.2708 --0.326164 -11.5524 13.7637 --0.727061 -11.4947 12.7973 --1.24766 -10.9375 12.1169 --1.94669 -11.6568 12.4027 --2.78175 -11.5407 12.9042 --2.93037 -10.7327 13.4738 --2.41091 -11.1105 14.1991 --3.01687 -11.7739 14.6727 --3.89672 -11.4316 15.1552 --4.08293 -11.6943 14.2084 --4.43063 -10.7329 14.215 --5.29387 -10.7757 14.6505 --5.80107 -11.6381 14.4818 --6.59529 -11.8214 15.0542 --6.52944 -12.0841 15.9654 --6.47184 -11.1418 16.2919 --6.53021 -10.4308 15.5987 --6.48563 -9.46429 15.3587 --6.08227 -9.60663 14.5085 --6.17465 -8.98245 13.6768 --5.9508 -9.43023 12.8248 --4.89801 -9.08165 13.1164 --4.24492 -8.63113 13.6741 --4.36523 -7.67977 13.901 --5.17175 -7.91564 14.4657 --4.5743 -7.60823 15.2618 --4.97982 -6.89268 15.791 --5.04334 -6.80031 14.7903 --4.51849 -6.26651 14.0927 --4.53205 -6.01778 13.1458 --3.87954 -6.38432 12.4241 --4.17788 -6.53155 11.4705 --4.08115 -7.29424 12.1032 --3.81988 -7.49885 13.0662 --3.33415 -7.92279 13.8139 --2.71877 -7.1352 13.4899 --2.07088 -6.58695 14.0558 --1.9521 -5.92766 13.3529 --1.32448 -6.24247 12.5983 --0.357629 -6.46229 12.2664 --0.702131 -7.44426 12.3254 --1.2584 -7.56773 13.0912 --1.09988 -8.49418 12.6978 --0.216402 -8.13992 12.943 -0.02028247 -8.16046 13.9718 -0.786567 -8.11308 14.6252 -0.323498 -8.96345 14.5137 -1.21826 -9.36684 14.557 -2.13336 -8.8914 14.7562 -2.54018 -9.38078 13.9712 -2.05172 -9.09142 13.1385 -2.38962 -8.21144 12.9051 -2.55431 -7.26994 12.668 -2.6999 -6.38666 13.1432 -1.966 -5.86241 13.5014 -2.05987 -4.83111 13.6853 -2.69225 -4.16291 14.0689 -2.56678 -3.22258 13.8626 -3.36013 -3.51893 14.4634 -3.68308 -3.23998 15.3344 -3.62392 -3.78492 16.2008 -3.3422 -3.72052 17.183 -3.52107 -2.70814 17.2113 -3.07702 -2.94488 18.0722 -4.09383 -3.19575 17.9566 -4.91496 -2.86808 18.4672 -5.12912 -1.97668 18.8763 -4.62362 -1.84807 19.7417 -4.39368 -2.44496 20.484 -4.40131 -3.35288 20.0482 -4.53543 -3.67441 20.9995 -4.45316 -2.79253 21.437 -3.46288 -2.83708 21.7154 -2.81372 -2.31656 21.1796 -3.46503 -1.73192 21.683 -2.66096 -1.15928 21.4143 -2.6485 -0.7028631 20.5356 -2.12429 -0.2663201 19.777 -3.06664 0.05919313 19.9468 -3.85488 0.3177169 19.4501 -4.33606 1.20229 19.4487 -5.0291 1.74488 18.9759 -5.48394 1.62962 18.0449 -5.9931 2.11609 17.3565 -6.37403 1.77953 16.4263 -5.51985 1.17202 16.6704 -5.00785 0.3111489 16.5561 -4.16592 -0.2699511 16.7416 -3.92832 -1.23754 16.4783 -3.06472 -0.8148631 16.3995 -2.66105 -0.9033481 17.3546 -1.76597 -0.6670981 16.9414 -1.17155 0.04145303 16.5867 -1.27731 -0.04189287 15.5874 -1.38275 -0.01368457 14.5944 -1.80543 0.8325329 14.603 -2.27593 0.5375979 13.8068 -3.17183 0.3607529 13.2837 -2.69916 0.1099769 12.4164 -3.4684 -0.4760131 12.4491 -3.30701 -0.8636271 11.5095 -2.59701 -1.54083 11.8007 -1.55811 -1.55701 11.823 -1.08775 -1.89783 11.0172 -0.201415 -2.42139 11.0824 --0.31046 -3.20176 10.8383 --1.08673 -3.6115 11.2771 --1.96286 -3.175 11.3155 --2.36532 -2.56449 10.7426 --1.78186 -2.15825 11.3982 --2.55721 -1.55925 11.6222 --3.48048 -1.80568 11.6969 --4.26734 -1.502 11.1485 --4.38318 -1.88096 12.0259 --5.31622 -1.6945 12.3863 --5.81347 -1.31165 11.6474 --6.57582 -1.62228 12.241 --6.67339 -2.54324 11.8885 --7.14547 -3.19361 12.4623 --6.2835 -3.0541 12.9902 --7.01693 -3.74057 13.2794 --6.51933 -4.46214 13.6805 --5.59484 -4.42649 14.1102 --4.98107 -5.11707 14.3852 --4.99679 -5.80987 15.0447 --4.75859 -5.8398 16.0042 --4.41752 -5.08356 15.4812 --5.34609 -4.59699 15.4305 --6.25967 -4.48022 15.0236 --6.86339 -5.17119 15.5447 --7.61267 -4.6245 15.2369 --7.76317 -4.97882 14.3007 --8.17076 -4.11313 14.5715 --9.06604 -3.9654 15.1836 --9.9874 -4.31267 15.1241 --10.7519 -4.74422 14.6497 --10.2125 -5.58494 14.5989 --11.0049 -6.24681 14.6806 --11.9153 -6.1098 14.5788 --11.6426 -5.56417 13.7195 --11.9427 -5.01632 14.5179 --12.3533 -4.34539 13.8568 --11.4068 -3.99973 13.6988 --11.1456 -4.79498 13.2304 --10.4258 -4.48666 12.7825 --9.75879 -5.30265 12.9364 --9.26915 -6.15436 12.9441 --8.25579 -6.37472 12.8387 --7.93373 -5.52437 13.2511 --7.6288 -4.78464 12.5702 --7.95103 -3.83464 12.553 --8.6281 -3.30244 11.9897 --9.11928 -2.63023 12.503 --9.55589 -1.91505 11.8893 --9.88033 -2.28109 10.9434 --10.2263 -1.29291 11.0682 --10.3243 -0.3518891 10.6634 --9.46919 -0.7696521 10.7087 --8.77558 -1.07513 10.0204 --7.98919 -0.9010871 10.5287 --7.56678 -0.4289851 11.3262 --7.98073 -0.6038271 12.1817 --7.10857 -0.3790811 12.7083 --6.22826 -0.2657351 13.2311 --5.45704 -0.8869851 13.4521 --4.47777 -1.00322 13.1363 --3.68001 -0.9675711 12.5266 --3.75388 0.05887803 12.7101 --3.49299 -0.3281581 11.8339 --4.07029 -0.08476177 11.0325 --4.2986 0.8120999 10.6537 --3.46415 1.1876 11.1414 --3.08395 1.87231 11.7315 --2.13524 2.09825 11.8641 --2.38496 2.39053 10.9266 --1.49337 2.1048 10.5673 --0.521907 1.77636 10.6294 --0.435242 2.76544 10.984 --0.687999 3.58377 10.5102 --1.16898 3.73031 9.59166 --2.02277 3.14273 9.80519 --2.45887 4.10897 9.98994 --2.7961 3.77995 10.9186 --3.67594 3.44272 10.8472 --4.48219 3.4942 11.4632 --4.89968 3.08074 12.3513 --4.49068 3.37885 13.2037 --4.05352 4.25809 13.1394 --3.94307 4.81927 12.2588 --3.38518 3.99847 12.2677 --2.5382 4.46164 12.7445 --2.46159 4.16418 13.6911 --2.5648 4.80279 14.4812 --3.52272 5.00023 14.5712 --2.81483 5.35908 15.2352 --3.31535 4.79501 15.9251 --2.6123 5.24337 16.4454 --3.19615 5.70898 17.0755 --3.86599 6.38646 17.3141 --3.79796 6.18136 16.3679 --4.39236 6.84587 15.8972 --5.17015 7.29948 16.2787 --5.84197 7.54013 15.608 --6.01217 6.57423 15.5502 --5.51044 6.06141 14.8673 --4.58584 6.25247 14.6593 --4.66033 6.03996 13.6564 --3.89407 6.41103 13.034 --3.71748 6.22819 12.0787 --4.16699 6.91125 11.4762 --3.94628 7.89989 11.693 --3.28022 7.29523 12.0774 --2.72851 7.85606 11.43 --2.13459 8.50736 11.1061 --1.23353 8.36916 10.8326 --0.527177 7.71125 10.5514 --0.349383 7.03771 11.314 --0.314746 8.01542 11.5593 -0.591904 8.4892 11.5448 -1.4389 8.57948 12.0841 -1.33297 9.46995 12.5998 -0.851472 9.78219 13.4219 --0.177644 9.87428 13.7594 --0.427083 9.74756 12.7678 --1.3353 9.35121 12.9537 --1.70024 10.2721 12.9008 --2.0931 10.032 11.9578 --1.92929 10.1051 11.0302 --1.0527 10.528 11.2508 --0.334725 10.4059 10.5211 --1.09095 10.0234 10.0642 --1.60538 9.21796 9.96238 --2.62858 9.21152 9.82606 --3.43167 9.23115 10.4479 --3.22991 10.2541 9.99223 --3.55133 9.85172 9.11907 --3.54485 10.8632 8.95226 --3.89975 11.2833 8.09805 --4.76235 11.4185 7.70406 --4.62139 12.2467 7.08888 --4.67567 11.5898 6.34321 --5.3691 10.8657 6.38637 --4.44004 10.4611 6.55982 --3.45934 10.2287 6.61719 --4.04349 9.42249 6.44824 --4.55902 8.63555 6.92527 --4.01416 8.36923 7.70348 --3.05104 7.99184 7.63369 --2.13766 8.30584 7.60096 --1.81268 9.14375 7.17488 --1.66329 10.1056 6.95987 --1.76072 9.74184 6.03042 --1.44697 10.6545 5.80372 --1.02043 11.6261 5.86735 --0.347541 11.2177 6.4096 -0.258269 12.0513 6.59011 --0.10767 11.7881 7.49317 -0.893676 11.7674 7.55022 -1.09597 10.841 7.58973 -0.34784 10.6952 8.26225 --0.474442 10.0596 8.18613 --0.446257 10.8234 8.85446 -0.154289 10.0281 9.08933 -0.257695 9.22195 8.57897 -1.25171 8.9118 8.4777 -0.736533 8.53479 7.74322 --0.149708 7.99524 7.80566 -0.522899 7.33793 8.12932 --0.326996 6.97648 8.4417 -0.08116177 6.28844 9.07703 --0.747868 6.66108 9.4683 --0.839754 7.63454 9.22486 --1.432 7.43562 8.43939 --1.6246 6.57431 7.98528 --0.953214 6.94702 7.25577 --1.72726 6.72931 6.63524 --1.3209 7.16476 5.89604 --1.99405 6.87298 5.12553 --2.44381 7.57684 4.63766 --2.82326 8.04941 5.44157 --3.30461 7.44274 6.03957 --3.69629 7.23254 6.90383 --3.6088 6.39884 6.41614 --3.94607 6.23195 5.51548 --4.90221 6.48635 5.6415 --5.45531 5.95674 5.03023 --6.4002 6.10951 5.19897 --6.04406 6.91052 4.68128 --5.32295 6.76913 3.88619 --6.28906 7.06921 3.68998 --6.82914 6.31462 3.39299 --6.61596 5.37988 3.03909 --7.3079 5.00114 3.6307 --6.91151 4.66733 4.39263 --6.87273 4.92055 5.40103 --6.56384 4.03523 5.58065 --6.14801 3.77822 6.391 --5.98561 4.34983 7.15874 --5.6288 4.59255 8.10602 --4.8601 5.21066 7.89073 --4.40017 6.03088 7.67945 --4.23645 6.55095 8.54546 --3.32219 6.20531 8.3474 --2.68214 6.07936 9.12878 --1.97887 5.50561 8.65302 --1.87406 4.75613 9.31545 --1.14324 5.00448 9.9003 --0.869637 5.42802 10.693 --0.54364 4.58634 10.9918 --1.53977 4.4375 11.1283 --2.28043 4.73818 11.8244 --1.89965 5.63832 12.1339 --2.26837 6.41493 11.6423 --1.70387 6.92853 12.2248 --1.7907 6.53942 13.1453 --0.994715 6.15224 13.6917 --1.38114 5.87656 14.5962 --2.32418 6.08959 14.4726 --2.69008 6.98905 14.5035 --2.90216 7.89765 14.274 --2.82982 8.22728 13.3217 --3.81647 8.3475 13.2422 --4.20021 8.94536 14.0087 --4.38557 7.98575 14.2251 --4.55239 8.29604 15.1019 --5.39764 8.56019 14.6008 --6.27325 8.94769 14.9773 --6.80551 8.7503 15.8325 --7.79511 8.5195 15.943 --7.68748 8.87793 14.9678 --8.52514 9.41219 14.9546 --9.17728 10.1236 15.1858 --9.20804 11.125 15.0151 --9.84193 10.5516 14.4456 --10.2261 10.5041 13.596 --10.3534 9.55721 13.8659 --9.9089 8.75648 14.3288 --9.59659 8.13428 13.6277 --9.43179 7.7906 12.6733 --10.3678 7.58929 12.6974 --9.67188 6.79784 12.9465 --8.92323 6.65916 13.6417 --8.94491 5.74159 13.799 --9.81286 5.87387 14.1247 --10.7117 5.91548 14.5639 --11.0074 5.5899 15.412 --11.2619 4.91773 16.118 --11.2675 5.74598 16.7119 --12.2139 6.14628 16.5112 --13.081 5.63259 16.3911 --13.3993 5.0809 17.0905 --12.541 4.60097 16.955 --12.0568 3.94054 16.4125 --11.4901 3.49721 15.6613 --10.6168 3.13161 15.7515 --10.0492 3.79341 15.1847 --9.21478 4.00485 15.7191 --9.06616 3.04213 15.8331 --9.55061 2.22841 15.5237 --9.96275 1.34043 15.206 --9.81048 0.6915399 14.5041 --9.13119 0.06653543 14.8625 --8.66643 0.07178103 15.7017 --9.07906 0.8022029 16.2011 --8.47326 0.9682909 15.3753 --7.74446 1.61575 14.9932 --7.14814 0.7939719 15.1816 --7.13582 0.1740409 15.9863 --7.22022 0.5054089 16.8598 --6.64208 0.8622849 17.6311 --7.05831 1.46514 18.344 --6.30095 0.9823999 18.7832 --6.45359 0.1881929 19.3683 --6.27281 0.9946179 20.0133 --6.5212 1.80965 19.3878 --7.55521 1.56817 19.4224 --7.89385 2.07691 18.5435 --8.85226 2.27199 18.2555 --9.08515 1.44169 18.8415 --8.91947 0.4828319 19.1229 --8.08843 0.3127129 19.5711 --7.69407 -0.3244541 18.9996 --7.27086 -1.0763 19.3933 --7.05641 -1.41415 20.3437 --7.82329 -1.38555 20.9946 --7.29391 -0.9320491 21.7121 --6.67076 -0.7502901 22.4474 --7.23388 -0.5022371 23.3413 --7.50842 -0.5256911 24.3238 --7.63703 -1.50683 24.6253 --8.21939 -2.18865 24.2094 --8.22691 -1.62573 23.3819 --7.91253 -2.22182 22.6522 --7.09197 -2.15326 23.1464 --6.95474 -3.09519 22.8865 --6.93542 -4.02553 23.3071 --6.88006 -3.33281 24.0833 --6.67724 -4.02408 24.7692 --6.49662 -4.5802 25.5943 --5.73096 -3.98693 26.013 --6.50824 -3.2626 25.9869 --7.29116 -3.75803 25.8734 --8.03204 -3.52123 26.5657 --8.53601 -4.32659 26.5969 --9.4934 -4.52432 26.7511 --9.19591 -5.15098 27.5242 --10.2157 -5.26457 27.356 --10.4582 -5.29809 28.2956 --10.8022 -4.5565 28.9102 --10.8178 -3.76798 29.5732 --11.5312 -3.88711 28.966 --10.8459 -3.13255 28.7077 --10.1623 -2.41776 28.651 --10.9445 -2.42123 27.9418 --11.4935 -1.7409 28.4434 --10.972 -1.04424 28.9034 --10.1436 -1.47161 29.2654 --9.34568 -1.82636 29.7777 --9.81818 -1.92695 30.7014 --10.6304 -2.21054 31.225 --11.3369 -1.56574 31.297 --11.6165 -2.04865 32.0672 --12.0948 -2.94435 31.6494 --11.8791 -2.46847 30.7249 --12.1532 -3.45362 30.4995 --12.1272 -4.45112 30.8605 --11.7169 -5.24954 31.0187 --11.1793 -4.46529 30.7829 --10.5961 -4.06153 31.4418 --9.94057 -3.56386 30.9229 --9.26757 -3.70083 30.2425 --8.25234 -3.4932 29.9969 --7.68623 -3.01594 30.7236 --6.88053 -2.62972 30.397 --5.88347 -2.56345 30.715 --5.01156 -2.11087 30.8838 --4.48271 -2.97004 30.9932 --3.77305 -2.62339 31.5378 --3.71318 -1.65077 31.1442 --2.92682 -1.10004 30.9526 --2.33131 -0.3124831 31.2791 --1.64065 -1.12122 31.3048 --1.10939 -0.8661781 30.5027 --1.08712 -1.3632 29.586 --0.24091 -1.96752 29.4656 --0.429319 -1.75874 28.4853 --0.783835 -2.15648 27.5835 --1.6561 -1.98449 27.7426 --1.69679 -2.98727 27.9991 --2.37261 -3.03852 27.296 --3.2781 -2.8864 26.8666 --3.21352 -2.12205 26.2981 --2.59796 -2.40522 25.5345 --1.73365 -1.95194 25.5726 --1.64609 -1.32461 24.7223 --2.4568 -1.02371 25.3029 --2.96442 -0.2594071 24.6979 --3.57426 -1.04627 24.8369 --4.5425 -0.6538601 24.6278 --5.44121 -0.9810181 24.8567 --4.90843 -1.41591 25.6075 --5.12613 -2.3005 25.2039 --4.64385 -2.64852 24.3723 --3.78141 -2.57055 24.804 --2.86772 -2.90469 24.6501 --2.15604 -3.45435 24.1998 --2.47706 -4.2908 23.7343 --3.44741 -4.09293 23.946 --3.19349 -3.76077 23.0241 --3.52078 -3.38444 22.2145 --3.86066 -2.62264 21.8457 --2.85942 -2.8387 21.7735 --1.93879 -2.41375 21.9507 --1.77573 -2.28829 20.9488 --1.31199 -1.36995 21.123 --0.802421 -1.95324 20.4106 --1.1651 -2.52156 19.8437 --2.14068 -2.19427 19.8958 --2.75939 -2.60443 19.3321 --1.84206 -2.40191 18.8747 --1.06792 -2.75147 18.3181 --1.35313 -3.70872 18.6384 --1.15728 -4.24904 17.7849 --1.98613 -4.88198 17.531 --1.64816 -4.79613 18.4637 --2.18902 -5.08388 19.2484 --3.1157 -5.47209 19.1725 --4.00392 -4.94444 19.2225 --3.92378 -5.2015 18.2462 --3.69565 -4.67564 17.4142 --2.9967 -4.46789 16.7217 --2.6737 -5.38769 16.9716 --2.03776 -6.15211 16.7494 --2.70852 -6.51883 17.3921 --3.70212 -6.4088 17.2801 --3.4814 -7.10076 16.6073 --4.32392 -7.50704 16.9362 --4.31912 -8.30834 17.4777 --5.27928 -8.10106 17.7386 --6.30521 -8.41238 17.7195 --5.95601 -8.27572 16.8171 --5.59574 -8.43346 15.9225 --5.80591 -7.58254 15.4705 --6.24395 -7.00943 14.8071 --6.58093 -6.1752 14.4879 --7.33803 -6.63504 15.0727 --7.35287 -7.26471 15.9336 --6.83367 -6.39506 15.9244 --7.2978 -6.76241 16.7244 --6.5587 -7.35353 16.4628 --6.94321 -8.24447 16.1485 --6.72081 -9.07574 16.8284 --5.80016 -9.48924 16.6334 --5.35016 -10.2833 16.8487 --5.78981 -11.1168 17.0087 --6.62125 -11.2196 17.5397 --7.10156 -10.5272 17.1386 --7.37522 -9.71971 17.5889 --7.07531 -9.85534 18.529 --8.01196 -10.3285 18.4998 --7.98373 -9.61958 19.1575 --8.61213 -8.96609 18.6798 --8.84074 -9.12058 17.7213 --8.77405 -9.80681 16.8979 --9.13785 -10.3994 16.1503 --10.124 -10.6844 16.0407 --11.1375 -10.6023 15.86 --11.0375 -10.5126 16.8605 --10.6826 -10.8534 17.6821 --9.6329 -10.8626 17.7922 --9.67044 -11.1272 18.7127 --8.95365 -11.461 19.3005 --9.34314 -11.461 20.1984 --9.42022 -11.955 21.076 --8.77519 -12.586 20.6106 --7.95002 -12.7926 20.0492 --6.98403 -13.1237 19.986 --7.02688 -13.8101 20.6748 --6.83362 -13.3739 21.5413 --6.32111 -12.6212 21.8621 --6.54723 -12.4777 20.8939 --6.95839 -11.7282 21.4445 --7.1198 -10.8358 21.7547 --6.12733 -10.9464 21.9014 --5.76075 -10.9846 20.931 --5.48358 -10.2446 20.2315 --5.02342 -9.53439 20.7755 --4.94829 -8.84202 20.024 --4.22582 -9.02331 19.407 --3.91009 -8.51404 18.607 --3.06391 -8.56756 19.0534 --2.23907 -8.75966 18.5815 --2.32046 -8.74538 17.5747 --2.90261 -8.90824 16.7905 --3.11086 -8.56597 15.8316 --3.62599 -8.74579 14.9704 --4.2833 -9.40074 15.2515 --4.43787 -9.67338 14.2448 --3.83644 -9.95462 13.4035 --4.24018 -10.6613 12.8104 --3.59824 -10.0719 12.2166 --3.86213 -10.0443 11.2367 --3.60415 -9.27304 10.7547 --2.93779 -9.66163 10.1537 --2.56607 -8.95812 10.7162 --1.75285 -8.77549 11.3065 --1.25895 -9.53537 11.8097 --0.392311 -9.94437 11.5503 --1.02561 -9.9082 10.8417 --0.274919 -9.42106 10.3838 -0.149082 -8.57021 10.3815 --0.12514 -8.72708 11.2997 -0.605462 -8.06588 11.406 -0.486002 -7.64826 12.3685 -1.38987 -7.09402 12.6473 -1.54931 -6.83413 11.6812 -2.17167 -6.29376 12.2161 -1.8855 -5.35329 12.0156 -1.99903 -5.81926 11.1326 -1.04462 -5.6966 10.7749 -0.256095 -6.12228 10.2572 --0.310421 -5.59981 10.8494 -0.468424 -5.35838 11.451 -0.681269 -4.46656 11.0998 -1.65952 -4.35086 11.18 -2.24714 -3.75328 11.5912 -1.75759 -4.20899 12.1983 -1.06196 -3.58475 12.5059 -0.336286 -4.19673 12.4228 --0.03167633 -4.96928 12.9654 --0.452136 -4.30665 13.4969 --0.599502 -5.07432 14.0854 --0.08005263 -5.84849 14.1312 -0.790041 -5.27308 14.1979 -1.17571 -4.71181 14.9512 -2.02791 -4.73739 15.4269 -1.24608 -4.625 16.0875 -1.08559 -3.93566 16.8071 -1.64291 -3.45855 17.6014 -1.23463 -4.33852 18.0695 -1.13245 -5.03726 17.3642 -1.43692 -5.71395 18.0108 -0.862523 -6.35186 17.5004 --0.06090333 -6.71719 17.5568 --0.311585 -6.28907 16.6344 --0.563513 -7.0607 16.1976 --0.872112 -6.29358 15.6758 --0.46517 -5.48299 15.1916 --1.10867 -4.75024 15.0563 --2.01375 -4.35534 15.0505 --2.72631 -4.5263 14.348 --2.67638 -3.70669 13.6913 --3.00621 -2.82511 14.1227 --2.21063 -2.62621 14.6233 --2.45501 -1.96208 13.793 --2.84394 -2.46605 12.9868 --2.06715 -3.03915 12.738 --1.14589 -3.4519 13.0479 --1.19278 -3.18115 14.0265 --0.548949 -2.35636 14.2431 --0.358188 -1.93434 15.1926 --1.29288 -1.74581 15.5282 --1.79159 -1.70995 16.4533 --2.08949 -2.60781 16.2329 --1.36415 -3.0747 16.7165 --1.34129 -3.59945 15.9775 --0.493915 -3.33835 15.6348 -0.381722 -2.89778 15.4777 -1.34917 -2.73743 15.3064 -1.05328 -1.92416 15.6699 -0.53346 -1.45169 16.3717 -0.710963 -1.54428 17.2761 -0.485846 -1.12302 18.0722 --0.175816 -0.4101681 18.1205 -0.522107 0.01083293 17.5461 --0.183227 0.7050479 17.5736 --0.09816243 1.09841 16.5934 --0.882653 1.41526 16.1129 --1.76628 0.8978589 15.8006 --1.09268 0.1896959 15.6147 --1.79488 -0.3547611 15.0799 --2.33796 -0.1611101 15.8618 --2.5377 0.4531059 15.1295 --2.64039 0.4649719 14.1403 --3.35878 0.5101699 13.4452 --4.23745 0.9225439 13.3935 --4.76698 0.2835549 12.9055 --4.85113 0.3164519 11.8754 --5.6994 0.6042979 12.2902 --6.00093 0.8590669 11.3323 --6.06907 1.81673 11.0426 --6.67463 1.26325 10.5502 --7.31623 0.6363999 10.1247 --8.2455 0.5818589 10.0451 --8.88437 1.2162 9.51508 --9.31783 2.06746 9.70156 --10.1044 2.73036 9.48264 --10.5632 1.82053 9.39042 --10.2028 1.97337 10.2713 --10.4588 1.69637 11.171 --11.4505 1.95156 11.1066 --11.8244 1.40418 10.3259 --12.589 1.45814 10.9687 --12.5297 2.08772 11.7639 --11.951 2.76806 11.4434 --12.8439 2.75987 10.9884 --12.3644 3.57143 10.6289 --12.9402 3.75365 11.4237 --13.5825 4.27895 10.8917 --13.4086 5.13209 11.3238 --12.5889 5.65374 11.3923 --13.1343 6.1937 11.9381 --12.3227 6.84616 11.9491 --13.0663 7.43543 11.5406 --13.2373 7.57946 10.5686 --14.2485 7.47404 10.5257 --14.8986 7.86916 9.85107 --15.856 7.42691 9.71315 --15.8452 7.54053 8.6943 --15.307 7.45361 7.85508 --16.0107 6.72168 7.82421 --15.8389 6.17202 7.04386 --15.9353 5.25408 6.67924 --15.9432 4.48542 6.0295 --16.9013 4.3364 6.29861 --17.5701 3.64247 6.55703 --17.1462 2.85743 7.04756 --18.133 2.68737 6.87938 --18.899 2.95836 7.52941 --18.8691 2.11515 8.08872 --18.7004 1.16265 7.81354 --18.19 0.3010649 7.66665 --18.8371 -0.3056651 8.07971 --19.0493 0.2309129 8.91455 --18.576 1.13695 9.05767 --18.573 1.88912 9.68494 --19.3754 2.1555 9.16054 --19.979 2.71011 9.78031 --20.6344 3.49517 9.78648 --20.3889 3.43901 10.782 --19.6876 4.15156 10.9233 --19.9252 5.00812 11.3467 --19.6186 5.83298 10.7654 --20.1573 6.58012 10.42 --19.6918 7.44918 10.0712 --18.9742 7.49434 10.7154 --17.931 7.47347 10.6981 --17.8508 7.72414 9.71155 --18.5615 7.95478 9.04417 --17.7006 8.14471 8.60276 --16.6642 8.24952 8.57516 --15.9058 8.59178 7.9672 --15.3552 8.34372 8.81139 --14.6084 8.75239 9.40578 --14.2244 9.04614 8.52393 --14.4015 8.68682 7.60671 --14.1742 9.19992 6.79667 --13.8524 8.25601 6.62931 --14.5706 8.05865 5.96413 --14.5233 8.99312 5.55202 --14.4294 9.96627 5.46254 --13.4951 9.81921 5.64735 --12.8862 9.50485 6.41514 --11.9925 9.8182 6.76104 --11.5511 9.56146 7.63152 --10.8186 9.9835 8.23854 --10.2462 9.22586 8.64381 --9.88788 9.77025 9.37055 --9.62609 9.68278 10.3025 --8.90211 10.4222 10.4391 --8.32482 10.6296 9.70637 --7.59984 10.8031 10.3587 --6.84556 10.1265 10.431 --6.10837 10.5092 11.0591 --6.02022 11.3494 10.4642 --5.21203 11.5956 9.88522 --4.85507 10.8236 10.5581 --4.85994 9.84128 10.697 --4.39634 9.47594 9.91131 --4.33216 8.51271 9.80911 --5.20243 8.54133 9.31447 --6.03103 8.12546 8.9545 --5.85982 8.10103 7.91277 --5.51729 7.19683 8.01301 --6.10864 6.98984 7.24208 --6.86437 6.50129 7.44652 --7.56231 6.86398 6.87495 --6.99548 7.58646 6.56137 --7.11816 8.46963 6.94121 --6.50016 9.06276 7.42661 --6.51745 10.0346 7.34926 --7.27642 10.1134 8.01784 --7.70651 10.7867 7.33845 --8.00549 9.95435 6.96353 --8.21929 9.04247 7.24914 --8.68047 8.82474 8.15967 --7.85611 8.25914 8.08098 --8.23501 8.1751 9.05778 --7.53581 8.91789 8.90755 --7.33967 8.48725 9.74887 --7.14959 8.85293 10.7401 --8.0018 8.47298 10.7505 --8.61432 8.70168 9.96665 --9.26014 7.86009 9.78408 --9.90223 7.33489 10.3644 --9.65105 7.97972 11.0722 --8.8714 8.63809 11.07 --9.203 9.00601 11.8991 --9.80544 9.55419 12.3783 --9.28456 10.3352 12.8621 --9.69225 11.1767 12.5662 --9.03911 11.6404 12.0258 --8.69329 11.924 11.12 --8.96591 12.9182 11.1665 --8.10278 12.8059 10.5753 --7.99085 13.2565 9.77194 --7.08784 13.3365 9.38313 --7.22932 12.7954 8.49965 --8.07834 12.2391 8.59635 --9.00125 12.2408 9.02422 --9.87248 11.7442 9.12226 --10.2701 10.8446 9.13956 --10.6811 10.7863 10.0386 --10.4239 11.2996 10.8185 --11.3231 10.7404 10.8041 --12.1982 10.9808 11.2628 --11.992 11.624 10.6102 --12.9867 11.8279 10.4976 --13.1912 12.4494 9.83758 --12.8578 12.1833 8.91052 --11.9216 12.0799 9.1765 --11.9463 11.097 9.14009 --12.5984 10.4129 9.49229 --12.8375 10.0412 10.4131 --11.8179 9.98614 10.1741 --11.1639 9.65139 9.41039 --10.837 8.71439 9.36759 --11.1589 7.74809 9.0863 --12.1579 7.96713 9.22428 --11.8695 7.88005 8.28571 --11.1597 7.28984 7.79508 --10.5411 7.89865 7.35078 --10.1158 7.64266 8.29519 --9.97184 6.99227 9.01332 --9.06727 6.68901 9.32356 --8.5644 6.96219 10.1706 --8.5637 5.92967 10.1221 --8.46588 5.65961 11.0521 --8.98366 4.95696 10.5783 --9.79828 4.52449 10.297 --10.6292 4.92354 10.6273 --10.2768 5.75586 10.0816 --10.5825 5.43513 9.17456 --11.4547 4.97996 9.29558 --11.3104 4.03905 9.01654 --11.6262 4.48819 8.17471 --12.6485 4.31601 8.31302 --13.045 4.84579 7.59517 --13.3186 5.76796 7.78117 --13.9159 5.23765 8.4153 --14.5389 4.58841 8.88079 --15.0265 5.43951 8.83734 --14.5364 6.17146 8.338 --14.3918 6.21084 7.31039 --14.1634 6.36404 6.39368 --14.6739 5.73099 5.80543 --15.2847 5.14738 5.22985 --15.6926 4.34405 4.90062 --15.7585 5.0093 4.18366 --15.5031 4.01591 3.89373 --16.1272 3.77777 3.1988 --16.4634 2.82813 3.1113 --17.3157 3.01116 2.64126 --17.6723 3.86891 2.33719 --18.0409 3.3833 1.53222 --18.2165 2.88017 0.7361461 --17.7357 2.0963 0.2453051 --16.7372 1.83455 0.2045991 --16.913 2.81088 -0.1856809 --16.7582 3.12696 -1.1201 --15.9276 3.37958 -0.6253209 --15.6897 3.02213 0.2853951 --15.3035 2.07581 0.4431411 --14.3681 2.28554 0.1505561 --14.2132 1.65168 -0.6012719 --14.1456 0.6139589 -0.7033069 --14.9476 0.3851959 -0.2966519 --14.9304 0.9993829 0.4873221 --15.8009 1.01347 0.9975961 --14.9195 0.9405769 1.40845 --15.5823 0.9411189 2.21365 --15.9164 1.19222 3.20517 --15.5115 0.8742359 3.95977 --15.8877 1.40779 4.74973 --16.4428 1.36976 5.63769 --16.4298 0.5734729 6.16709 --16.184 -0.3402871 6.18573 --16.1932 0.1013339 5.26551 --16.7967 0.2425449 4.45964 --17.1429 -0.7417671 4.54086 --17.4037 -1.02883 3.61758 --17.492 -1.94334 3.24891 --17.9636 -2.31334 2.41669 --18.8062 -1.96075 2.70663 --19.677 -1.41924 2.57433 --18.8454 -0.8433801 2.72582 --19.542 -0.1429751 2.9508 --18.6644 0.1049059 3.41709 --17.8275 0.6973629 3.72347 --18.0774 1.67127 3.58641 --18.8037 1.66641 4.32622 --18.1919 1.99438 5.03676 --18.8035 1.28023 5.42442 --19.795 1.5297 5.50707 --20.4929 1.43578 6.11578 --21.1094 2.12254 5.77178 --21.7258 2.03652 6.58769 --21.1802 1.4012 7.0708 --20.7785 1.63918 7.92788 --20.3834 0.7471979 8.00737 --21.3151 0.3441479 7.92243 --20.9722 0.1772349 8.83804 --20.8551 0.8378309 9.57737 --21.7451 0.6685049 9.91822 --22.2344 1.00464 9.14864 --22.0374 1.98432 9.12114 --22.7204 2.14435 8.45576 --23.1886 2.2542 7.46494 --23.9576 1.70007 7.8585 --24.1455 2.59411 8.28077 --24.7304 2.15813 8.86213 --25.1769 2.2918 9.80419 --24.4549 1.85282 10.3922 --24.3285 2.69548 10.7831 --23.3499 2.51133 11.0813 --22.5664 3.10964 10.78 --22.3368 3.38533 9.87491 --23.2836 3.88289 9.82612 --24.1449 4.07483 9.38539 --24.9055 4.61902 8.98251 --25.5013 5.42584 8.98782 --25.631 5.19946 8.01619 --24.6605 4.86676 7.70353 --23.8525 4.31714 7.4083 --22.9661 4.24454 7.07742 --22.7094 4.43687 8.05281 --22.9206 4.94653 8.89688 --23.8284 4.93664 8.59372 --24.3819 5.7347 8.9128 --23.6262 6.18228 9.39338 --24.1193 6.98848 9.33498 --24.2053 7.94083 9.05715 --23.5087 7.46045 8.43986 --23.2834 8.42186 8.63737 --22.4341 8.89123 8.41329 --22.2178 9.82719 8.46512 --21.8106 9.43343 7.69509 --20.894 9.55573 7.30492 --20.0654 8.93305 7.34534 --19.265 9.2212 7.67301 --18.3816 9.44673 8.08812 --17.731 9.01057 7.45689 --17.0426 9.6192 7.17253 --17.8298 9.79194 6.55086 --17.7975 10.4472 7.3119 --17.5255 10.7146 8.25237 --17.5148 10.6378 9.17237 --18.0964 10.7002 9.99016 --18.3907 10.025 9.30533 --17.8138 9.57765 9.97503 --18.1396 8.75761 10.448 --19.0531 8.78066 10.2435 --20.0016 9.12187 10.0988 --20.9569 8.94695 10.1869 --21.2294 8.0352 9.98872 --21.2522 7.04759 10.3436 --21.9704 6.9235 9.67152 --21.424 6.12567 9.42417 --20.6913 5.48032 9.16043 --20.1316 6.24326 9.07872 --19.1846 5.76322 9.07801 --18.3793 6.30126 8.81004 --18.3877 6.48004 7.85202 --17.624 7.14808 7.66342 --17.3135 7.04684 8.60807 --16.791 6.77513 9.38353 --16.7177 5.82704 9.14941 --15.8721 5.61947 9.71921 --16.3782 5.68636 10.6139 --17.092 6.38617 10.4225 --17.5443 6.01977 11.3014 --17.4926 7.01393 11.5026 --16.7948 7.54734 11.9959 --16.1046 8.08924 11.4435 --15.7626 8.46777 12.2784 --15.451 9.34608 12.7352 --14.5988 8.9751 12.4451 --13.7541 9.33552 12.8393 --12.8093 9.43466 12.7085 --11.8455 9.60099 12.9044 --12.151 10.3416 13.5544 --12.6952 11.1258 13.6531 --13.3494 10.9226 12.9499 --14.1793 10.2769 12.8838 --14.9149 10.6537 13.535 --15.7255 11.0605 13.8447 --16.011 10.7479 14.704 --16.5302 10.193 15.3665 --16.7084 9.57036 14.6131 --16.3208 9.14181 13.7861 --16.183 9.93505 13.1251 --16.1441 9.83574 12.0746 --16.4508 10.7008 12.4501 --15.6069 11.0145 12.0189 --14.8987 11.5184 11.6545 --15.7185 12.006 11.3271 --15.938 11.8136 10.3686 --16.8683 12.104 10.5214 --16.8324 11.951 11.529 --17.5017 12.5844 11.9231 --17.2066 13.284 12.6174 --17.7894 13.3066 13.4123 --18.4096 13.2529 12.5747 --18.7857 12.799 11.7594 --19.4022 12.9778 11.0081 --19.256 13.0572 9.98591 --18.9843 13.9964 10.1475 --19.424 14.5778 10.7953 --18.6411 13.9838 11.1966 --17.8826 13.4844 10.7573 --17.4838 14.1388 10.0833 --17.8797 14.9957 9.87011 --18.4656 14.8126 9.0389 --17.708 14.89 8.34478 --17.0876 14.5853 7.58974 --16.9398 13.7786 6.90326 --17.7986 13.4707 6.46897 --17.984 14.0686 5.6947 --18.8587 13.7561 6.15374 --19.7151 13.525 6.58214 --20.549 13.998 6.78496 --20.128 14.6763 6.09772 --20.6034 14.3541 5.36744 --20.6517 14.9447 4.59836 --20.8325 13.989 4.30592 --20.6443 13.286 3.54381 --20.6099 12.2927 3.83175 --20.3392 11.3376 3.95222 --20.8127 11.4973 3.06679 --21.1908 10.5753 2.98861 --20.6391 10.3568 2.25131 --19.9263 10.1488 1.51188 --19.9415 9.25403 1.85054 --20.1778 8.32909 2.31379 --19.1781 8.5781 2.44287 --18.2118 8.89288 2.19981 --18.189 8.18421 1.54535 --17.2635 7.73017 1.58547 --16.2463 7.6142 1.91922 --15.5176 7.76538 2.56686 --15.3397 8.59926 3.15022 --15.8387 8.99711 2.40566 --16.4118 9.66885 2.10903 --17.1142 10.3377 2.45246 --17.3022 10.7597 3.34678 --16.5022 10.774 3.88684 --17.1771 10.3029 4.53561 --18.0962 9.89471 4.39263 --18.486 9.33381 5.04918 --18.5809 8.28918 5.03958 --19.5188 8.6987 4.76335 --19.4279 9.28357 5.59085 --20.2121 8.82827 6.06637 --20.379 9.78455 6.03393 --21.3931 10.0218 5.82224 --21.5361 9.80027 4.87176 --22.1762 8.96009 4.77926 --22.8106 8.64893 5.44921 --23.0546 7.9394 4.70827 --23.9556 8.14012 5.03945 --24.019 7.36455 4.30359 --23.5155 6.69216 4.80071 --22.5853 6.72563 5.16006 --22.0262 6.14553 5.73502 --22.3174 5.1675 5.73996 --22.7515 4.86146 4.85073 --23.1434 5.34025 4.09166 --22.1286 5.32383 4.17827 --22.1876 4.40554 3.74044 --22.8822 3.74534 3.47025 --23.4825 3.07868 3.14208 --22.6275 2.6008 3.21842 --21.7224 2.17732 3.08397 --21.5842 2.70189 2.29208 --22.165 1.92888 2.03428 --22.4924 1.50822 2.84415 --21.8621 1.0041 3.45336 --21.1759 0.2799409 3.28811 --21.0304 0.2124569 2.27987 --21.3837 1.16093 1.96968 --22.2112 0.5795699 1.80891 --23.0982 0.1978249 2.00713 --24.1497 0.3661199 1.93656 --23.6551 1.1789 2.34114 --24.555 1.43592 2.12021 --23.9178 2.04451 2.5067 --24.8894 2.4385 2.52078 --25.8899 2.73038 2.58456 --26.6693 2.16676 2.80186 --27.073 2.81954 2.13128 --26.9129 3.3228 2.99943 --27.3178 3.50801 3.92297 --27.2207 2.63251 4.37337 --26.229 2.35594 4.22659 --26.3975 2.64501 5.29685 --26.8708 3.21998 5.94523 --25.9895 3.55013 5.96744 --25.5536 3.71375 6.84865 --24.6839 4.2482 6.75215 --23.8419 3.83795 6.39327 --23.7753 2.98498 6.97288 --24.6835 2.61338 6.88265 --25.4888 2.26979 7.40431 --25.2094 1.36746 7.67867 --25.6337 0.4587559 7.83589 --26.1738 -0.2643041 7.44691 --26.661 -0.002927916 6.62758 --27.0067 -0.4739781 5.929 --26.4206 -1.19371 6.24662 --26.8951 -1.65527 5.47457 --27.2878 -2.57816 5.19238 --26.9049 -2.91502 4.4399 --27.5745 -3.65088 4.63716 --27.7888 -4.4724 5.2032 --27.622 -5.39409 5.63329 --27.3587 -6.17373 6.09738 --26.5949 -6.13382 6.70862 --25.913 -6.51277 7.31244 --25.8241 -5.54823 7.14249 --25.3221 -5.19484 7.95659 --24.8095 -4.78294 7.19599 --24.7227 -3.80322 7.55181 --25.1905 -2.95663 7.43491 --25.0433 -1.91334 7.35149 --25.1718 -1.71685 8.40801 --25.7352 -1.68866 9.12552 --26.7156 -1.52124 9.39455 --26.6334 -1.50479 8.44095 --27.3795 -1.96952 8.09198 --28.3869 -2.14528 8.23809 --28.9592 -2.93868 8.14789 --28.6778 -3.58252 7.4632 --28.6849 -4.54608 7.63074 --28.2698 -4.49694 8.54397 --28.7294 -5.39869 8.29093 --27.815 -5.46194 8.71017 --28.4464 -5.74467 9.44507 --28.5756 -6.39893 10.2765 --27.695 -6.56968 10.7968 --26.9222 -6.74896 10.2126 --26.0672 -6.18078 10.3836 --25.5458 -5.71525 11.1128 --26.3116 -5.00214 11.0959 --26.9211 -4.47307 10.5559 --27.8409 -4.66015 10.9436 --28.7333 -4.47199 10.3964 --29.6235 -4.09016 10.6213 --29.6489 -3.60498 11.4264 --29.2607 -4.07263 12.1852 --29.6919 -4.89626 12.5819 --29.5036 -5.93351 12.346 --29.5514 -5.89086 13.4324 --30.5406 -5.89542 13.4369 --30.6046 -6.88492 13.2592 --30.5874 -7.81331 12.8694 --29.8998 -7.59022 13.552 --29.5483 -7.04016 14.3898 --29.0501 -6.68898 15.1997 --28.6048 -6.07493 15.852 --27.9426 -5.2967 16.0139 --27.6255 -6.03937 16.5874 --26.932 -5.99301 15.8604 --26.2152 -6.50559 16.2546 --25.8946 -5.56365 16.1367 --26.1557 -4.94182 16.8582 --26.6813 -5.17347 17.6412 --26.3552 -4.87469 18.5749 --26.4466 -4.87485 19.5439 --26.426 -3.99058 20.1414 --25.3924 -3.78557 20.095 --25.737 -3.56701 19.1945 --26.4127 -2.88894 19.1771 --25.8383 -2.3688 19.9157 --25.6628 -1.96139 19.0106 --26.1634 -1.26354 19.3518 --25.7259 -0.9780581 18.467 --25.4726 -1.36614 17.549 --25.5181 -1.03141 16.6284 --26.0615 -1.18691 15.8425 --26.7691 -0.6453001 15.3685 --27.1294 0.3092749 15.3441 --26.175 0.1346859 15.0941 --25.9244 0.8306779 14.4312 --26.2439 1.76041 14.5625 --25.2909 1.88427 14.7343 --25.7226 2.79308 14.4321 --26.7024 3.07729 14.3015 --27.1107 2.78929 15.1246 --26.8287 3.42657 15.8962 --26.7458 3.89007 16.7561 --27.5244 3.34692 17.0329 --27.3048 2.7958 17.7646 --27.8155 2.04417 17.4256 --28.0311 1.24354 16.9189 --27.8608 0.3248159 17.381 --26.9659 0.6720039 17.1127 --26.0145 0.3812559 17.295 --25.4984 1.0873 17.8029 --25.9629 0.7850579 18.6848 --25.5012 1.66542 18.6498 --25.5098 1.96987 19.5741 --26.3406 2.40596 20.0832 --26.4778 3.08405 20.715 --27.3261 3.33753 21.1002 --27.6467 3.30042 20.1082 --28.6334 3.23709 20.3253 --28.9656 2.75438 19.5715 --28.6018 1.94368 19.0667 --28.5901 1.37771 19.8464 --29.3769 1.28387 20.4473 --29.9444 0.6443659 20.087 --30.5315 0.6079549 19.2905 --30.7536 1.37473 18.6587 --30.7115 0.5954319 18.0366 --31.032 0.2717729 17.1549 --30.585 1.18309 16.9244 --29.7137 1.3711 17.1544 --30.0091 1.18551 16.2038 --29.5971 1.66975 15.4238 --29.8192 1.83544 14.4535 --29.6197 1.14179 13.7434 --29.9036 0.3976679 13.2225 --30.6415 1.03978 13.1375 --30.4247 0.6434279 12.3539 --29.8227 0.9300449 11.5827 --29.6146 1.18524 10.6353 --29.2406 0.4148709 10.0241 --29.1917 -0.5860941 9.85622 --29.5733 -0.9123691 8.98424 --30.2338 -0.1837881 9.1785 --31.2422 -0.1645041 9.33978 --32.0625 0.2955899 9.09603 --32.3144 0.02087193 10.0355 --32.6589 0.05482133 11.0179 --33.5811 -0.2577951 10.9777 --33.5369 -1.20973 11.0289 --34.3822 -0.8621801 10.6339 --34.4271 -0.1483141 9.92666 --34.5935 -1.11388 9.75276 --35.5686 -0.7767251 9.61908 --35.9287 -0.7006961 10.5651 --36.0204 -1.07848 11.4621 --35.6144 -0.5265201 12.2236 --35.1228 0.2258789 12.5105 --34.6471 0.8125789 13.1486 --33.6877 1.10518 13.3468 --33.4504 0.3123529 12.8487 --32.9189 -0.1629371 12.1558 --32.3695 -0.8340281 12.6936 --31.9384 -1.2792 13.5926 --32.2016 -2.1487 13.0573 --31.8808 -3.05301 13.3475 --32.088 -3.34308 14.1983 --32.2819 -4.19825 14.6467 --32.2157 -4.9378 15.3663 --32.1769 -4.2263 16.0915 --31.4863 -4.78034 16.5957 --31.0919 -5.67472 16.9641 --31.7465 -6.39528 17.3529 --30.8769 -6.64758 17.8482 --30.3276 -7.45781 17.6335 --29.3745 -7.41106 17.2507 --28.7972 -7.77078 17.9453 --29.4418 -7.11485 18.2928 --29.2917 -6.61958 19.1649 --28.5758 -7.27643 19.1616 --28.0044 -8.10029 19.3007 --27.2758 -8.75037 19.2871 --26.6174 -8.04401 19.1936 --26.1801 -8.95255 19.39 --25.7653 -9.37365 18.6135 --25.1379 -9.1714 17.907 --25.1235 -8.42584 17.3577 --24.7928 -9.06175 16.7351 --24.9504 -10.0159 16.54 --24.8699 -9.77813 15.6412 --25.0956 -9.07198 14.9029 --24.8203 -9.88053 14.3753 --25.3639 -9.45066 13.6468 --25.7938 -10.3574 13.7914 --26.181 -9.60109 14.344 --26.6214 -9.08793 15.0733 --27.2731 -9.1365 15.8825 --26.8726 -8.31058 15.6607 --25.9779 -7.94232 15.4374 --25.2731 -7.62731 14.7613 --24.4756 -7.18516 14.487 --24.4357 -6.45831 13.8776 --25.2016 -6.7355 13.2178 --25.4334 -5.90063 12.588 --25.6407 -5.70514 13.643 --25.5877 -5.43469 14.5828 --25.3086 -4.56376 14.3085 --24.9828 -4.45121 13.3622 --25.5608 -3.85998 12.7932 --26.4282 -4.13316 12.5627 --26.5913 -3.22701 12.2309 --26.594 -2.57208 12.9443 --26.7012 -1.65764 13.3035 --26.5448 -0.9621601 12.4862 --26.318 -1.31883 11.5684 --25.9956 -1.33097 10.5858 --25.1867 -1.47943 11.1941 --24.4411 -1.30972 11.9535 --24.1108 -1.91808 11.2221 --24.7178 -2.5368 10.7569 --25.1267 -2.81965 11.5721 --24.5432 -3.39903 12.2095 --24.1356 -4.10669 11.6764 --23.3814 -4.69434 11.4393 --23.2924 -5.46786 10.8707 --23.0496 -5.89221 9.97981 --23.0862 -5.15294 9.27277 --22.5623 -5.65117 8.5702 --23.3728 -5.21873 8.18617 --23.0198 -4.37009 7.6553 --22.8381 -4.76251 6.71531 --22.4025 -5.6544 6.88766 --21.8221 -6.45513 7.243 --21.4399 -6.59555 8.18776 --22.1237 -7.14151 8.58826 --21.8435 -6.77451 9.50511 --21.2562 -7.56791 9.7564 --20.5894 -6.89216 9.59344 --20.3391 -6.22386 10.2844 --21.0593 -6.43292 10.9253 --20.9335 -5.79832 11.6809 --20.8546 -4.91165 11.3315 --21.1234 -4.60186 12.2539 --21.0476 -3.60482 11.9846 --22.0568 -3.72156 12.0656 --22.4229 -2.82583 11.736 --23.0751 -2.32674 12.3562 --23.0196 -1.62668 11.6531 --22.5608 -1.46798 10.7824 --21.6715 -1.09373 10.4522 --21.9586 -1.86487 9.92097 --22.1036 -1.50299 8.96405 --23.008 -1.81229 8.835 --23.7661 -2.40563 8.67985 --24.1793 -3.41455 8.76174 --23.5123 -3.5909 9.4388 --23.0986 -3.65306 10.3602 --22.4397 -3.07975 9.9437 --21.5916 -2.8296 9.34811 --20.6621 -3.15761 9.29913 --19.9371 -2.50022 9.01235 --20.0823 -2.05663 9.89497 --19.9478 -1.2457 9.36902 --20.3781 -0.3988081 9.59321 --20.669 -0.5058181 10.6278 --20.7362 -1.21023 11.3537 --20.9524 -1.95235 12.0299 --20.917 -2.31427 11.0806 --20.2164 -3.12942 11.0688 --19.333 -2.81914 10.6488 --18.3306 -2.4761 10.8219 --18.5234 -3.33856 11.3669 --18.0789 -4.18241 11.7876 --18.2974 -5.13544 11.6135 --18.9086 -5.65157 12.2542 --19.7744 -5.88956 12.7234 --20.214 -5.43267 13.4804 --21.1858 -5.07583 13.5286 --21.9615 -4.97327 14.2053 --21.2514 -4.36003 14.6096 --20.8825 -3.51733 14.24 --21.5032 -2.73668 14.1229 --21.3228 -1.75946 14.0414 --22.2305 -1.71753 14.0759 --22.1674 -0.7294791 14.37 --22.0211 -1.13287 15.2912 --22.3259 -0.1691421 15.1527 --22.0435 0.7877679 15.4526 --22.3099 1.59379 14.923 --22.9086 2.14088 15.5381 --23.4327 2.19119 14.7137 --22.7349 1.81394 14.0991 --22.6901 1.57563 13.0961 --23.4556 1.34372 12.395 --23.3723 1.18505 11.4991 --24.0724 0.5088469 11.8057 --25.0408 0.4713649 11.4617 --25.1557 -0.09699677 10.6388 --25.02 -0.1401261 9.68332 --25.6469 0.6376149 9.80482 --26.5643 0.4899109 9.95259 --26.7515 1.48182 10.0958 --26.9032 1.8316 9.17495 --26.5597 2.40939 8.51712 --26.8924 3.35555 8.42586 --27.7733 3.52738 8.79957 --28.3822 4.28917 9.00815 --28.6496 5.2499 8.82537 --29.6425 4.95198 8.8216 --30.4606 5.61892 8.98038 --30.1607 6.49139 9.39425 --30.4715 7.38861 9.15895 --29.4783 7.2489 9.21563 --29.839 7.62772 8.36497 --29.5285 8.60337 8.43811 --29.1279 8.85688 7.47968 --28.8618 8.38022 6.66563 --29.4202 7.62422 6.4091 --29.9015 7.98832 7.17886 --30.5979 8.20259 6.56177 --30.0707 8.87246 5.94509 --30.2015 9.1251 4.99271 --30.7867 8.36685 5.0261 --31.2618 7.47672 4.78821 --30.5924 6.9089 5.31942 --29.9046 7.19666 4.60303 --29.449 7.11285 3.73079 --28.5334 6.73935 3.78008 --27.6569 6.55922 3.17472 --27.3774 7.52569 2.93154 --27.5228 8.2953 3.62326 --27.6777 8.93256 4.31182 --27.1814 9.84019 4.38613 --27.0152 9.60859 3.44533 --26.3463 8.95344 3.11016 --25.6799 8.27405 2.90184 --25.7444 7.55789 3.56676 --26.3772 6.86647 3.51086 --26.3306 6.46957 2.56274 --26.0678 7.10853 1.85843 --25.3259 6.60063 1.42614 --24.674 6.87871 2.18589 --24.354 6.083 1.6884 --23.5238 5.64476 1.49169 --23.1774 6.50247 1.9926 --23.2332 5.91862 2.80852 --22.3693 5.68014 3.01948 --22.5636 6.50465 3.49103 --22.291 7.30925 2.90422 --21.6475 7.14927 3.67409 --21.0724 7.29506 2.86575 --20.8297 6.32276 2.94965 --20.4663 6.84285 3.74954 --20.0391 7.61978 3.45209 --19.2188 7.04228 3.30296 --18.7128 7.40049 2.52101 --19.2925 7.05546 1.86764 --20.017 7.28315 1.12108 --19.5185 6.9241 0.3487671 --19.3133 6.15189 0.9070231 --19.12 5.12737 0.8892201 --18.3041 5.34847 0.5083491 --17.6825 6.1404 0.2806821 --17.0173 6.88321 0.3004321 --16.0731 6.93146 0.3805461 --15.2503 6.97544 -0.09340078 --14.2809 7.28241 -0.1451879 --14.387 8.00765 -0.8039309 --13.7467 8.73298 -0.8390829 --13.9077 9.42991 -1.53027 --12.9481 9.31915 -1.16294 --12.7976 8.69424 -2.00782 --12.6919 7.82858 -1.48348 --11.8145 7.60694 -1.95208 --12.1959 7.58755 -2.93171 --12.2179 6.78221 -3.49398 --12.1477 5.75598 -3.39928 --11.5753 5.39412 -4.13109 --11.026 5.04966 -3.31778 --10.3764 4.99756 -2.62078 --9.99884 4.72605 -1.81986 --10.1489 4.85244 -0.8291499 --10.8322 5.5111 -0.5173629 --10.4136 6.04495 -1.2101 --10.8189 5.96071 -2.10283 --9.99905 6.37485 -2.52359 --10.2281 7.32643 -2.3023 --10.8462 8.05843 -2.0083 --10.4431 8.86394 -2.46212 --10.5238 9.85859 -2.67218 --10.573 10.2239 -3.58413 --11.1936 9.44463 -3.68638 --11.8969 8.8309 -4.03931 --11.5148 8.57704 -4.95341 --10.7034 8.39303 -4.4113 --11.1362 7.59297 -4.70944 --11.4201 6.65187 -5.10396 --11.5737 7.43668 -5.68176 --11.7163 7.71046 -6.58638 --11.9643 6.9971 -7.19448 --11.6017 6.08987 -7.32509 --12.0146 6.09939 -8.23126 --12.1436 5.76275 -9.24258 --11.2345 6.24773 -9.19245 --10.7806 6.60431 -9.98494 --10.7353 7.31581 -9.29093 --10.682 8.01087 -8.6196 --9.91061 8.16822 -9.17815 --9.4224 7.82109 -8.36584 --8.97017 8.65965 -8.0773 --9.17949 9.32574 -7.448 --9.41558 9.5921 -6.50229 --8.45853 9.65419 -6.22249 --8.21816 9.30679 -5.33379 --9.12762 9.82034 -5.30476 --8.9603 9.46731 -4.39415 --9.30718 9.92934 -3.55473 --9.07754 9.45559 -2.70166 --8.33858 8.83144 -2.84237 --8.99419 8.19712 -3.29516 --9.5087 7.95641 -4.12814 --10.0324 7.43393 -4.83318 --10.1041 6.72933 -5.50667 --9.72162 5.75797 -5.44711 --10.3026 5.33063 -6.06774 --10.9271 5.05992 -5.25096 --10.572 4.6707 -4.45718 --11.232 4.05549 -3.81071 --11.523 3.15866 -3.57359 --11.7099 3.48213 -2.64392 --12.6717 3.65958 -2.88172 --12.8725 4.47958 -2.30565 --12.4899 5.38334 -1.95287 --13.0053 5.73168 -1.09357 --13.9061 5.21626 -1.34658 --14.8517 5.19284 -0.9763229 --15.4197 5.8456 -0.5109169 --14.6106 6.31987 -0.8499519 --15.0447 6.24913 -1.72514 --15.4784 6.89131 -2.3545 --15.3086 7.83123 -2.7843 --15.6989 7.37366 -3.53719 --15.5233 6.48981 -3.96339 --14.9225 6.60173 -4.74889 --13.9844 6.616 -4.59388 --13.1216 6.86571 -5.13909 --13.4635 7.81867 -5.1507 --13.3419 7.40184 -4.31827 --13.4263 6.67262 -3.61472 --13.4004 5.62871 -3.86149 --14.1281 5.40602 -4.4228 --14.1154 4.8013 -5.19037 --15.0817 4.84439 -5.41049 --15.2717 5.73521 -5.79179 --16.1499 6.05564 -6.16595 --16.4682 7.04597 -6.32428 --16.9302 7.60502 -5.6828 --16.7302 8.48559 -5.46507 --16.6885 9.4595 -5.64372 --17.6839 9.73689 -5.42704 --18.5986 9.95378 -5.85043 --19.0719 9.57111 -5.00026 --18.8877 9.83801 -4.0256 --19.513 10.6138 -3.80188 --20.5051 10.6743 -4.01591 --21.1561 9.86307 -4.00896 --21.1519 8.81741 -3.94878 --20.2235 9.21195 -3.89795 --19.3659 8.88726 -3.47903 --18.8006 8.23273 -4.00827 --19.3687 7.9456 -4.731 --19.2728 6.95202 -4.7615 --19.5983 6.10917 -4.32602 --20.2171 5.8745 -5.006 --19.6539 5.08108 -4.9063 --18.9857 4.38213 -5.23773 --18.1075 4.75558 -4.92255 --18.4641 4.84977 -3.98064 --18.6762 3.87172 -3.79692 --18.6936 3.19802 -3.04861 --19.5227 3.79903 -2.98037 --19.5678 4.41394 -3.80523 --20.3094 4.35352 -4.41732 --20.0781 3.53678 -4.98257 --19.6286 2.67122 -5.3583 --19.1439 2.1681 -4.5849 --18.2724 1.59576 -4.7822 --18.6027 1.32736 -3.92941 --19.1592 1.24493 -3.06267 --19.3896 0.3918949 -3.52466 --20.197 -0.1223351 -3.90723 --20.7291 0.3309289 -4.60034 --19.8374 0.4542819 -5.07212 --19.8426 -0.5311451 -4.83943 --20.8073 -0.7432431 -5.10712 --20.8311 -0.1517291 -5.91389 --21.7451 -0.5019971 -6.32989 --21.5395 -1.47848 -6.30417 --22.46 -1.31902 -5.96875 --23.3597 -1.07899 -6.26087 --23.5589 -1.99185 -6.35131 --23.8154 -2.08836 -5.43432 --23.0947 -2.77464 -5.67373 --22.1498 -2.45761 -5.83004 --21.2261 -2.9042 -5.63276 --20.3115 -2.98593 -5.85292 --20.3545 -3.7125 -6.56958 --19.452 -3.26868 -6.45938 --18.6563 -2.81125 -6.20628 --18.7165 -1.89256 -6.66738 --17.9805 -1.21646 -6.75457 --17.4952 -0.3717351 -6.9934 --18.1942 0.2106499 -7.45817 --18.8957 0.8307839 -7.09259 --18.2028 1.30242 -7.58214 --18.3339 2.14608 -7.11048 --17.9077 1.32662 -6.60519 --17.3929 2.21233 -6.65665 --17.2748 2.77727 -7.44567 --16.9876 3.53021 -8.02394 --16.1106 3.72551 -7.73011 --15.5881 4.04524 -8.519 --15.7128 4.76379 -9.20817 --15.4165 5.51476 -8.63714 --15.5077 5.88234 -7.73269 --16.407 5.60722 -8.10002 --17.2045 5.95662 -7.62466 --17.9496 6.11831 -8.29189 --18.6815 5.41541 -8.49745 --19.2042 5.66753 -7.74727 --19.7477 4.95403 -7.50318 --19.8178 4.41262 -8.25808 --20.0241 3.80419 -9.03675 --20.4819 4.63743 -9.00464 --19.9207 5.45914 -9.25423 --19.7921 6.37978 -8.85907 --20.3507 7.14918 -8.73126 --20.3127 8.10657 -8.52184 --21.1233 8.20438 -7.89168 --20.8153 8.87648 -7.21366 --20.4778 7.99613 -6.94637 --20.4482 7.49316 -6.10296 --21.058 7.89083 -5.44367 --21.5354 8.44194 -6.14296 --22.4881 8.47635 -5.92487 --22.7136 9.20825 -6.58032 --23.0945 9.95473 -7.12956 --23.7045 9.14438 -7.23641 --23.6321 9.31128 -8.29303 --24.4334 9.87863 -8.43637 --24.3875 10.4852 -7.62894 --24.805 11.1656 -8.1772 --25.7983 11.3854 -8.00778 --25.4015 12.2749 -8.1789 --24.8728 12.1863 -9.04184 --25.174 12.6379 -9.863 --25.929 12.1036 -10.3058 --26.6911 11.4667 -10.2268 --26.2995 10.5914 -10.5764 --25.9527 10.5517 -9.60666 --25.0238 10.7722 -9.78144 --24.5026 10.6294 -10.6642 --24.907 11.2179 -11.3722 --24.8136 12.1902 -11.2656 --24.318 12.8448 -10.7686 --23.2926 12.9205 -10.7046 --23.5386 12.5011 -9.85447 --23.3961 11.6934 -10.4083 --22.5949 11.7602 -9.75761 --23.3465 11.1792 -9.39475 --22.6368 10.4139 -9.17901 --23.0775 9.5903 -9.40562 --22.3863 9.23677 -8.76261 --22.084 8.27614 -8.83622 --21.3969 8.96469 -9.25081 --20.4875 9.30637 -9.28358 --19.8938 9.44747 -10.0615 --18.9414 9.34533 -9.6246 --18.4628 10.2351 -9.55128 --17.7164 10.9549 -9.60271 --16.9629 11.347 -9.09945 --17.5345 12.2014 -9.2866 --17.4949 12.4905 -8.33908 --16.6387 12.4656 -7.77493 --15.9646 12.0387 -7.23904 --15.9506 11.1949 -6.65031 --16.3122 10.4972 -7.25315 --16.8471 9.73084 -6.93524 --17.5557 10.25 -6.61611 --17.9021 10.9991 -7.16127 --18.7917 11.1719 -6.67434 --18.6056 11.7968 -5.88554 --17.8028 12.2446 -5.49451 --17.0098 12.7118 -5.0387 --16.107 12.2979 -4.95444 --15.6959 11.9438 -4.10595 --16.4418 12.3408 -3.53487 --15.6307 12.9079 -3.50283 --15.8986 13.6975 -4.02855 --15.067 14.1614 -4.48553 --15.2637 13.6706 -5.38181 --14.829 13.2131 -6.20256 --15.3153 12.4525 -5.88979 --14.7749 11.6948 -5.40584 --15.2776 10.9008 -5.06106 --15.0973 10.0995 -5.56591 --14.9843 10.5632 -6.41795 --14.179 10.3675 -7.02502 --13.3261 10.5878 -6.63335 --12.6441 11.1266 -6.32804 --12.8244 11.679 -5.50818 --13.4707 12.3861 -5.07084 --12.7579 12.3411 -4.42671 --12.7696 11.5541 -3.80566 --13.2534 10.9773 -4.45564 --13.9531 10.7666 -5.06869 --13.6843 9.96968 -5.61857 --13.6596 9.00316 -5.91481 --14.6007 8.80708 -5.83626 --15.5779 8.71023 -6.06432 --15.2 9.33495 -6.80079 --15.462 8.3841 -7.10268 --14.8532 7.9097 -7.79004 --14.3834 7.69091 -6.86761 --15.0428 6.93855 -6.85699 --14.3667 6.37514 -7.23178 --14.2355 5.42794 -7.12098 --13.3347 4.95422 -7.26355 --13.3137 4.34339 -8.14099 --13.1848 4.01897 -9.10932 --13.2269 3.04417 -8.93466 --13.176 2.08737 -8.58898 --12.7201 2.7952 -8.01062 --12.9957 1.94764 -7.60114 --12.6957 1.34224 -6.80831 --13.0986 1.86618 -6.14069 --12.7098 2.82953 -6.48367 --11.8794 2.94885 -6.04148 --11.1762 3.3857 -6.62258 --10.4282 4.03399 -6.41549 --9.49174 4.21107 -6.71154 --9.0332 4.23622 -7.55147 --8.86703 4.85123 -8.30278 --7.90794 5.25144 -8.33654 --7.24138 4.82035 -8.94138 --7.81053 4.02614 -8.89511 --8.18457 3.08894 -9.15466 --7.42925 3.3879 -9.77915 --6.89185 3.38358 -8.93517 --5.94623 3.5893 -8.74905 --5.78587 4.23851 -7.97279 --6.26167 3.5626 -7.44097 --6.19006 3.27009 -6.42184 --6.76573 2.4857 -6.04426 --7.06767 3.08365 -5.36044 --6.46502 2.81042 -4.59868 --6.72946 2.46806 -3.73044 --6.81441 1.50719 -4.11158 --7.41403 1.55898 -4.95001 --7.60858 1.1741 -5.81483 --8.15298 2.01416 -5.65738 --8.32222 2.35061 -4.81961 --7.78286 3.19303 -4.63598 --7.41137 4.07246 -4.86739 --7.96127 4.73726 -4.54939 --8.72482 4.73233 -5.17417 --9.55905 4.28055 -4.92535 --9.41737 5.00148 -4.28272 --8.66152 5.61794 -4.03895 --8.65811 6.61591 -3.82767 --8.16763 7.27356 -3.21333 --8.49703 7.29976 -2.33935 --7.56766 7.28921 -2.07419 --7.24899 8.10509 -1.49993 --7.29901 8.82218 -0.8172299 --7.22757 9.58276 -0.2351349 --7.75972 10.2704 0.3407071 --8.39822 9.8774 1.02347 --7.77825 9.43214 1.67385 --7.63851 8.55739 1.2645 --8.55409 8.40194 1.49906 --9.54712 8.29805 1.27062 --9.48876 8.30276 0.2935551 --9.54763 7.32849 0.1585261 --9.15259 6.72385 -0.5299689 --9.12374 5.68915 -0.5333089 --8.09509 5.87984 -0.6329369 --7.16409 6.14663 -0.8649879 --7.14394 5.9342 0.1448351 --7.30989 5.50204 0.9595921 --7.30882 5.40363 1.96032 --7.83346 4.75494 1.41691 --8.31249 4.63033 2.26168 --8.70018 5.45677 1.88069 --9.39198 4.82683 1.5159 --10.2497 4.40521 1.48668 --10.2421 3.60649 0.9856751 --10.1543 3.35928 1.8981 --10.9459 2.79278 1.76277 --11.7209 2.84382 1.17626 --11.3249 3.23014 0.2801721 --11.3316 3.8874 -0.4748329 --10.6441 4.18692 0.1500721 --11.43 4.27712 0.8062941 --12.0001 4.59456 -0.03282558 --12.4536 4.36807 -0.8914329 --12.9656 3.52097 -1.2395 --13.6665 3.77073 -1.95519 --14.4875 4.00539 -2.39507 --14.4788 3.12328 -2.81467 --14.3877 3.63809 -3.71945 --15.1304 4.19263 -4.03044 --15.682 5.05209 -4.08885 --16.3302 4.40658 -4.46787 --16.4883 5.17977 -5.12836 --17.3295 5.18545 -5.77468 --17.8902 4.72852 -6.43217 --17.4978 3.78816 -6.54906 --17.5214 4.3233 -7.38828 --18.3023 3.76164 -7.73416 --18.8648 3.01798 -8.16287 --19.1935 2.13466 -8.25581 --19.0216 2.45282 -9.17873 --18.3109 1.78565 -9.29458 --17.5879 1.07993 -9.50118 --17.1957 0.4337719 -10.1499 --17.4094 -0.2813301 -9.49481 --17.12 0.1725629 -8.69921 --17.8142 -0.5341421 -8.44098 --16.948 -0.7491441 -8.08392 --16.726 -1.59539 -8.54765 --16.3894 -2.43117 -8.11806 --16.4664 -2.68833 -9.07415 --17.161 -3.37969 -9.37019 --17.2573 -3.63693 -10.2407 --17.5699 -4.48494 -10.7465 --18.0462 -5.24585 -10.2972 --17.046 -5.36345 -10.1238 --16.7919 -6.11464 -10.7784 --15.768 -5.89248 -10.8483 --14.8823 -5.45584 -10.6175 --14.002 -5.85806 -10.778 --14.6287 -6.6302 -10.9128 --15.5864 -7.01671 -10.9074 --15.6101 -6.77318 -11.8627 --15.1765 -7.60365 -12.2757 --16.0408 -8.00621 -12.2907 --17.1017 -7.90177 -12.1747 --17.237 -7.3157 -12.9705 --17.3192 -6.8145 -12.1483 --18.2605 -6.82124 -12.0673 --18.1814 -7.70392 -12.5244 --18.0131 -7.93409 -13.4833 --18.1246 -7.9925 -14.3695 --17.7641 -7.63038 -15.2641 --18.416 -6.81336 -15.1016 --18.793 -5.96586 -14.6921 --18.8685 -5.31119 -15.4316 --19.5514 -5.76792 -15.9477 --19.617 -4.86232 -16.1876 --20.2038 -4.38558 -16.9137 --19.7246 -3.58536 -16.662 --19.1114 -3.23296 -17.4619 --18.3767 -3.85677 -17.7577 --19.0424 -4.08823 -18.4836 --19.0869 -4.32678 -19.4445 --19.0292 -4.38935 -20.4728 --19.6078 -4.51076 -21.3364 --18.992 -4.9738 -21.9051 --18.6579 -4.11071 -21.9686 --17.9432 -4.45063 -22.6153 --17.599 -4.74409 -23.5639 --17.2532 -3.97686 -23.0387 --16.7655 -3.12116 -23.0206 --16.9809 -2.59668 -22.2243 --16.2563 -2.51724 -21.5019 --15.6278 -3.04796 -21.0019 --15.9348 -3.03495 -20.0513 --15.8446 -4.10863 -19.9915 --14.9598 -3.84776 -19.7083 --14.6766 -2.95459 -19.2593 --14.7783 -2.15762 -19.7842 --15.5933 -1.64263 -19.9579 --15.651 -0.7080521 -20.0752 --16.2167 -1.18483 -20.7433 --16.5569 -0.3364211 -21.0875 --17.1472 0.4057409 -21.2424 --17.9906 0.1318169 -20.8425 --18.6775 -0.4637851 -21.0886 --18.7367 -1.44185 -20.9611 --18.4745 -0.8322611 -20.2082 --18.624 -0.1363201 -19.4956 --19.248 0.7037379 -19.5028 --18.7388 1.50873 -19.328 --19.4803 1.68564 -18.7561 --20.5044 1.59286 -18.7326 --21.0812 0.8775759 -18.4469 --20.5804 0.1627119 -18.9419 --20.6042 -0.5437181 -19.6138 --20.4984 -1.60833 -19.5088 --19.8959 -1.34725 -20.3103 --19.2489 -1.86451 -19.8101 --19.8442 -2.68179 -19.9903 --20.2627 -3.24886 -20.657 --20.8206 -4.02545 -20.3054 --21.5284 -4.34913 -20.9234 --21.744 -5.30256 -21.2814 --21.2637 -5.49298 -22.1912 --20.9915 -6.22891 -21.6213 --21.2326 -6.62476 -20.7031 --20.4457 -6.48843 -20.1067 --21.3012 -6.19876 -19.5073 --20.7945 -6.82727 -18.9251 --20.1509 -6.07596 -18.816 --19.1103 -5.81893 -18.852 --18.9732 -6.8106 -18.9741 --19.3705 -6.80477 -19.8954 --19.0736 -7.5246 -20.585 --18.2613 -6.99293 -20.5625 --17.6523 -6.42853 -20.0983 --16.6682 -6.14715 -19.8434 --16.2363 -5.27509 -20.1385 --15.4526 -5.95183 -20.1411 --15.6922 -6.92491 -20.3256 --16.2187 -7.5523 -19.7738 --16.3353 -8.45429 -20.1194 --15.8048 -8.60722 -19.3075 --16.0203 -8.95795 -18.4104 --16.8407 -8.51878 -17.9814 --17.5036 -7.9811 -18.462 --17.496 -8.0029 -17.4706 --17.4311 -7.07083 -17.9247 --18.4112 -7.3029 -17.8965 --19.3189 -7.63071 -18.0912 --19.6758 -8.14119 -18.8633 --20.1928 -8.83599 -19.2276 --20.5362 -9.20437 -18.4003 --20.1805 -9.13986 -17.4574 --19.6885 -8.58674 -16.7814 --18.8646 -9.23245 -16.8201 --19.4287 -9.88693 -17.2959 --19.9701 -10.1985 -18.1452 --19.2643 -10.2044 -18.8829 --18.2471 -10.3698 -18.7306 --18.2607 -10.8714 -19.5212 --17.349 -10.9621 -19.0757 --17.1728 -10.5634 -18.2374 --16.6719 -11.1398 -17.6331 --15.8123 -11.2429 -17.1 --15.7415 -10.9853 -16.1459 --15.484 -11.6851 -15.438 --14.8397 -11.2007 -14.8804 --14.5464 -12.1573 -14.7748 --14.0417 -12.7586 -14.1692 --14.8255 -13.3139 -13.8861 --15.0649 -13.0726 -12.9215 --14.855 -12.0544 -13.0681 --15.4749 -11.8212 -13.777 --16.0516 -11.4088 -14.4742 --15.7481 -10.627 -13.913 --15.5705 -9.68453 -14.126 --16.1726 -8.89964 -14.4031 --16.2877 -9.02743 -13.4751 --17.1869 -9.52963 -13.2164 --17.9365 -10.1629 -12.9775 --18.4047 -9.6677 -13.7014 --18.9411 -9.50943 -12.9037 --19.519 -9.88829 -12.166 --19.7399 -10.7148 -12.7402 --18.7289 -11.0874 -12.7754 --18.6871 -11.3638 -13.72 --19.3376 -12.1078 -13.5416 --19.273 -12.7159 -12.8039 --19.3146 -13.4692 -12.1574 --19.6442 -14.2849 -12.7201 --19.1709 -13.6961 -13.4347 --19.4704 -13.5126 -14.3045 --18.7866 -12.7799 -14.2901 --18.9128 -12.538 -15.2347 --19.7194 -11.9218 -15.5499 --19.9831 -11.4333 -14.6918 --20.613 -10.7654 -14.3199 --21.154 -11.5483 -14.4957 --21.6933 -11.096 -15.1568 --22.5262 -10.5591 -15.0268 --23.4114 -10.887 -15.4288 --23.2281 -9.91541 -15.4572 --22.6999 -9.16141 -15.8944 --21.8371 -8.81149 -16.3126 --21.5408 -8.08511 -15.6972 --20.7441 -7.47828 -15.9343 --19.8581 -7.46703 -15.4813 --20.6733 -7.19067 -14.9009 --20.7967 -6.22852 -14.7009 --20.7077 -5.90648 -15.6517 --21.4205 -6.09353 -16.361 --21.8981 -6.54667 -15.7191 --22.8655 -6.34797 -15.5698 --22.6583 -6.70301 -14.6793 --21.9507 -6.98463 -13.9696 --21.9822 -7.96415 -14.3465 --21.329 -8.16353 -13.6978 --21.5021 -8.49353 -12.7555 --21.3996 -8.9939 -11.9011 --22.2397 -9.63093 -11.9988 --21.4169 -10.1236 -11.7952 --21.9706 -10.4008 -12.5368 --22.704 -10.7317 -11.9997 --22.6154 -10.889 -10.9681 --22.7963 -11.4315 -10.0462 --21.8905 -11.1696 -10.1984 --21.4624 -10.6179 -9.50345 --21.8774 -9.85874 -9.03791 --21.5885 -10.1511 -8.1827 --20.6214 -9.94133 -8.52348 --19.7331 -9.66824 -8.24706 --19.6182 -9.73862 -7.21172 --20.6276 -9.68963 -6.88797 --21.5595 -9.44883 -6.98547 --22.321 -9.46369 -6.37868 --22.0547 -9.14463 -5.43934 --21.3056 -8.4327 -5.28123 --21.2383 -7.67902 -4.65624 --22.2536 -7.81655 -4.78297 --22.6313 -7.02882 -5.30861 --23.5355 -6.67441 -5.47654 --23.0509 -6.39894 -6.3581 --22.3575 -6.95432 -6.78931 --23.1048 -6.82569 -7.40569 --23.2714 -6.84595 -8.35925 --22.4942 -7.42973 -8.40523 --22.3994 -8.44993 -8.43815 --21.4312 -8.85421 -8.50906 --20.614 -8.47026 -8.87779 --20.5102 -8.30614 -7.90502 --20.737 -7.40812 -8.28047 --20.6615 -7.2783 -9.26135 --21.1854 -7.4988 -10.0818 --22.1749 -7.44367 -10.1385 --23.1307 -7.16925 -10.4427 --23.3337 -8.15553 -10.3792 --23.3214 -9.06716 -10.0132 --22.9874 -9.00068 -9.09937 --23.6518 -8.46115 -8.56621 --24.6083 -8.33062 -8.71314 --24.5775 -7.91479 -9.68922 --25.5722 -7.97489 -9.72691 --25.2321 -8.79316 -10.1483 --25.3648 -8.14991 -10.93 --25.5658 -7.31133 -11.4628 --25.5347 -6.48646 -10.8568 --26.3106 -7.05684 -10.5244 --27.1367 -6.95092 -10.9095 --28.1496 -6.81726 -10.6646 --28.0746 -6.81552 -11.6432 --28.9204 -6.85949 -12.2347 --29.5158 -7.2523 -12.8443 --28.9312 -7.97094 -13.0851 --28.1701 -8.52727 -13.4394 --28.5058 -8.79837 -14.3177 --27.8614 -9.45037 -14.5719 --27.3165 -8.70347 -14.7457 --26.4687 -9.19666 -14.9029 --25.7113 -9.8013 -14.9567 --25.0643 -10.0408 -15.6758 --25.9843 -10.3556 -16.0932 --26.5471 -11.0352 -15.6051 --27.021 -11.9086 -15.5411 --26.4241 -11.7843 -14.7318 --26.3814 -12.5812 -15.1366 --26.3795 -12.964 -15.9997 --27.2844 -13.4095 -15.7998 --26.9271 -14.3325 -15.7698 --26.8113 -15.2286 -15.3016 --27.2849 -16.0883 -15.543 --28.2021 -16.4883 -15.6375 --28.9118 -15.8527 -15.9496 --29.4905 -15.2836 -15.3033 --30.1107 -15.2602 -14.5336 --29.4673 -15.4286 -13.7832 --30.1651 -16.0709 -13.5739 --30.3851 -16.3978 -12.6314 --31.1881 -15.853 -12.8245 --30.7387 -15.434 -12.0495 --30.337 -15.4006 -11.1233 --29.3268 -15.5851 -11.1554 --28.7961 -15.1826 -11.9621 --29.2135 -14.4098 -12.5822 --28.7026 -14.049 -11.7903 --29.4718 -13.48 -12.1127 --30.3263 -14.0433 -12.2379 --31.0087 -13.3105 -12.562 --31.6191 -13.3637 -11.8237 --31.2445 -12.8141 -11.0915 --31.5801 -11.8785 -11.3345 --30.854 -11.3279 -11.0837 --29.9775 -10.9221 -11.2704 --29.6001 -10.0102 -11.1846 --30.2067 -9.21227 -11.0269 --29.6461 -8.63992 -11.5282 --29.6166 -7.73654 -11.0927 --29.7743 -6.80952 -10.7688 --30.6488 -6.25998 -10.778 --30.0154 -5.45339 -10.6363 --29.3968 -5.19754 -9.86278 --29.0682 -5.79428 -10.6034 --28.5322 -4.99089 -11.0523 --28.0498 -5.41028 -11.9037 --28.1254 -4.4165 -11.9805 --27.5696 -4.33426 -11.134 --26.6569 -4.53009 -10.6749 --26.7596 -3.51603 -10.5138 --26.5177 -2.56203 -10.3385 --26.2748 -2.24011 -9.46086 --26.7587 -2.48875 -8.58775 --26.8949 -1.6167 -8.91524 --27.1001 -0.8727731 -8.26105 --28.1074 -0.9495181 -8.52323 --28.2406 -1.86336 -8.14695 --29.1279 -1.81261 -7.73355 --30.0412 -1.87763 -7.39229 --30.0373 -1.7388 -6.4421 --30.3653 -1.61133 -5.57153 --30.0071 -1.9172 -4.68311 --29.0639 -1.58439 -4.84869 --29.1542 -0.6287571 -5.20699 --29.2945 -1.31735 -5.92125 --28.6951 -0.5709951 -6.29527 --27.7625 -0.6045741 -5.95797 --27.413 -1.32677 -5.32575 --27.3992 -2.23503 -5.52083 --28.2173 -2.67215 -4.96722 --28.1936 -2.80461 -3.98196 --28.1394 -2.86364 -2.98111 --28.998 -2.21684 -3.113 --28.9801 -1.242 -3.07789 --29.2173 -0.3706141 -3.23703 --29.8633 0.3819099 -3.15063 --29.9937 1.08532 -3.89204 --30.9831 0.8294419 -4.2029 --31.265 1.46323 -3.45368 --30.7796 1.99087 -2.73087 --31.2593 2.55891 -3.41221 --31.4322 2.98219 -4.3087 --30.7454 2.85519 -4.96846 --30.6785 1.85998 -5.16275 --30.9227 1.4169 -6.02006 --31.6726 1.76526 -6.55666 --31.2014 1.66531 -7.40743 --30.4989 2.27539 -7.55355 --30.0193 2.82024 -6.87711 --30.4914 2.96861 -6.00159 --30.0943 3.84834 -5.80823 --30.6935 4.0374 -6.61104 --30.7213 4.58755 -7.46554 --31.5334 5.04326 -7.2008 --31.1986 5.99822 -6.85385 --30.3724 6.58032 -7.15795 --29.3241 6.71562 -7.03353 --29.408 5.85247 -6.44407 --30.3863 5.90785 -6.15416 --30.6005 5.27053 -5.28232 --29.6812 5.30733 -4.97177 --29.0914 4.54776 -5.4126 --29.0042 4.16937 -6.32179 --28.1731 3.87765 -5.90747 --27.7317 4.31836 -6.68478 --27.1357 3.83249 -6.05319 --27.1404 4.576 -5.42171 --26.9549 5.35894 -4.83619 --27.1806 5.66493 -3.87852 --27.6136 6.5081 -4.13241 --28.0098 7.12844 -3.52965 --28.9461 6.82156 -3.27433 --29.8856 6.99889 -3.12897 --30.1669 6.13522 -3.59491 --29.5307 5.33017 -3.27734 --29.6611 5.03957 -2.37958 --29.6776 4.34286 -1.72301 --30.4161 4.74929 -1.17822 --30.2437 4.5608 -0.2020719 --30.4996 3.67256 0.2289931 --31.4015 3.32453 -0.1085739 --30.9705 2.40719 -0.2701209 --31.0933 1.89655 0.5632351 --30.9248 2.7794 0.9543811 --30.2854 3.33134 1.45602 --31.2458 3.30808 1.80708 --31.7923 4.19225 1.65734 --31.6637 3.99849 2.6438 --32.4203 4.55891 2.36126 --33.0296 5.21834 2.84718 --33.7203 5.31557 2.09953 --34.082 6.23692 2.01545 --34.0994 6.96242 2.64027 --34.4457 7.61008 1.90678 --34.7105 8.57714 1.82871 --34.0877 8.57656 2.65179 --33.1361 8.84915 2.76592 --32.6935 9.81024 2.84905 --32.0533 9.89021 2.10025 --31.2653 10.2474 1.46962 --30.4456 10.7164 1.50993 --30.2051 11.1495 0.6525131 --29.3704 11.5622 0.3392291 --29.0961 10.8239 1.00084 --28.3957 11.1394 1.64397 --28.0562 10.3644 1.16143 --28.3535 9.57279 0.7101611 --28.0068 9.21822 -0.07460388 --27.4338 10.0198 -0.1065269 --26.5419 9.91777 -0.5325629 --25.691 9.62774 -0.9747849 --26.2127 8.83648 -0.7282919 --25.4684 8.13927 -0.9196469 --26.0544 7.41042 -0.5711419 --26.827 7.32799 -1.18345 --27.3038 8.16727 -0.9387929 --27.8678 7.84512 -1.68295 --27.1304 7.59791 -2.31056 --27.2293 6.70011 -1.90829 --26.8836 6.26997 -1.16938 --27.3018 6.18946 -0.2832759 --28.037 5.51473 -0.5245249 --28.6713 5.05802 0.01936942 --28.0733 4.30539 -0.1666699 --27.1442 4.61702 -0.3198909 --26.636 3.80858 -0.6461129 --25.8913 4.17893 -1.24135 --25.0973 3.59859 -1.56521 --24.1104 3.5199 -1.7993 --23.2448 3.36908 -1.21603 --22.8379 4.22902 -0.9817719 --22.6878 3.69788 -0.1510819 --22.8014 2.73863 -0.4565029 --22.1681 2.19973 -1.03789 --21.6676 1.98279 -1.87826 --20.9072 2.27907 -2.36655 --20.1649 1.88298 -1.77811 --19.8448 2.704 -1.19085 --19.7198 2.22191 -0.2348379 --19.796 1.22464 -0.2212119 --20.2013 0.6173169 -0.8109259 --20.6323 -0.1289691 -1.30149 --21.0184 -0.4701381 -2.13347 --21.9924 -0.8434491 -2.1511 --22.1048 -0.2135791 -2.91264 --22.1701 -1.21145 -3.15308 --21.7026 -2.02938 -2.82892 --21.3088 -1.56701 -3.57607 --21.0296 -2.52795 -3.42786 --20.2286 -2.21479 -2.95583 --19.556 -2.37035 -2.22653 --19.0579 -3.23614 -2.21581 --19.0841 -4.16074 -1.71935 --19.9574 -4.28446 -2.17821 --20.3215 -4.22641 -1.26593 --21.1023 -3.69402 -0.8745999 --21.8834 -3.45944 -0.3635359 --22.5017 -3.22909 0.3661381 --22.4834 -4.09257 0.8167011 --21.5981 -4.01555 0.4854791 --20.9798 -3.4286 1.06973 --20.9027 -3.77549 1.94949 --20.3769 -3.58769 2.72147 --20.1407 -3.17675 3.57266 --21.1653 -3.16098 3.57952 --20.9782 -2.27462 3.1002 --20.3876 -2.62354 2.36148 --19.9176 -2.36989 1.4723 --20.1849 -1.55414 0.9620751 --19.302 -1.78172 0.5458511 --18.925 -1.26163 -0.1415559 --18.9466 -1.24642 -1.08482 --19.0094 -0.2684201 -0.8252439 --19.1629 0.6642769 -1.21335 --18.2093 0.5788819 -1.6319 --17.3051 0.2144849 -1.50494 --17.2411 -0.7821791 -1.29343 --16.7012 -1.1842 -2.05998 --17.5821 -1.80669 -1.90968 --18.4715 -1.3398 -2.19486 --17.7284 -0.9058841 -2.68097 --17.6384 -0.2451301 -3.46826 --16.7318 -0.6941181 -3.14707 --16.4766 0.2915919 -3.27827 --15.7853 0.6780629 -3.82778 --15.8603 1.50818 -3.23086 --15.7459 2.07613 -4.00552 --15.2129 2.88055 -4.0293 --16.0441 3.42008 -3.83803 --16.772 3.26847 -3.2713 --17.0481 3.3034 -2.42299 --17.0217 4.29937 -2.69255 --17.16 5.08265 -3.21892 --16.9064 6.04569 -3.04884 --17.1141 6.52947 -2.23896 --17.9371 6.11381 -2.4441 --18.5396 6.10409 -1.67245 --18.7904 5.13153 -1.43602 --19.742 4.70114 -1.26851 --20.8105 4.81562 -1.37206 --20.279 5.0724 -0.5808339 --20.5637 6.05837 -0.7662359 --21.3611 5.42848 -0.5774549 --21.8805 6.24901 -0.2935159 --21.5627 6.91469 -0.8801249 --21.5593 7.85506 -1.19665 --20.6389 7.51594 -1.36899 --20.6276 8.18319 -2.11801 --19.6517 7.99789 -2.04951 --19.0489 8.05402 -1.33813 --19.2651 8.92334 -0.8753659 --18.5154 8.54232 -0.3257789 --17.6089 8.69884 0.03967842 --17.1403 9.08983 -0.7550079 --16.9603 10.056 -0.5056299 --17.9172 9.68384 -0.5207209 --18.6496 9.94074 -1.12208 --18.4394 10.9176 -0.8580399 --19.0533 10.9664 -1.68637 --19.8101 11.004 -2.38598 --20.7845 10.8062 -2.26362 --21.1219 11.3299 -1.47701 --20.9482 11.3215 -0.4693609 --20.71 10.4062 -0.1801799 --21.0843 10.8111 0.6727461 --21.2236 11.8224 0.7412651 --21.1444 12.7528 1.06079 --20.4231 12.792 1.73867 --20.1444 11.7771 1.78825 --19.2816 11.2987 1.84473 --18.534 11.8831 1.86232 --18.3155 12.4794 1.07325 --18.0288 11.9086 0.2957631 --17.2602 12.0692 -0.3634309 --16.6704 11.4872 -0.9307299 --15.8787 11.5024 -0.3678059 --15.716 11.9939 -1.22029 --16.5647 12.2562 -1.61285 --17.4659 12.5964 -1.28113 --17.1926 13.4919 -1.53298 --18.1052 13.6124 -1.11044 --18.1941 14.6358 -1.13917 --18.2533 15.5634 -1.53841 --18.0922 16.0379 -2.43636 --17.2652 15.9983 -1.85595 --17.0449 16.2069 -0.9480219 --16.7956 15.3813 -0.3285369 --16.9527 15.5094 0.6097181 --17.8223 15.4493 0.1317881 --17.4999 16.3532 0.04342042 --17.6824 17.3436 0.2827471 --16.7608 17.234 0.01388132 --16.0495 16.9437 0.6636041 --15.682 16.9122 1.58698 --16.3201 16.2658 1.97051 --15.4319 16.0201 2.37906 --14.4113 15.856 2.2497 --14.8501 14.9799 1.88701 --14.82 14.3542 1.10958 --15.8331 14.2965 1.22881 --16.2445 14.6604 0.3874261 --15.7014 14.0032 -0.1797499 --15.9365 14.4009 -1.06157 --15.3602 15.0854 -1.49592 --15.1333 14.4738 -2.23859 --15.5205 13.5288 -2.42807 --14.6305 13.1686 -2.75663 --13.9132 13.7144 -2.3277 --13.6816 13.8455 -1.37311 --14.4415 14.2573 -0.8110849 --14.3554 13.5372 -0.1144269 --13.7907 14.1178 0.4429241 --12.7852 14.5064 0.5747421 --12.1441 13.7682 0.3527431 --11.688 14.3426 0.9270441 --10.7748 13.8259 1.12115 --10.5129 13.1552 0.4652031 --9.58483 13.3521 0.6175021 --9.22793 12.95 -0.1874239 --9.7248 12.5731 -0.8963849 --10.2519 13.4463 -1.19285 --10.0482 14.4197 -1.05956 --9.67124 15.204 -1.48424 --8.81303 15.3445 -0.9836239 --8.47364 14.3015 -1.05084 --7.9609 13.7315 -0.4515009 --8.26246 13.3183 -1.25289 --8.69615 12.4512 -1.26109 --9.17819 11.8925 -1.87343 --8.83367 12.6726 -2.30815 --8.9503 11.911 -2.96 --8.6432 11.1689 -2.48141 --8.12989 10.6492 -3.11618 --7.94359 11.6142 -2.99665 --7.97105 12.3899 -3.58071 --6.9739 12.3943 -3.4197 --7.26801 13.2369 -3.23288 --6.97999 13.8113 -4.02231 --6.92008 14.6376 -4.63393 --7.53537 14.9196 -5.27154 --7.96711 14.778 -6.17542 --7.5502 14.2287 -6.80799 --7.33518 13.4245 -7.32246 --7.72637 12.4931 -7.47226 --7.55834 11.5023 -7.51813 --6.70259 11.6085 -7.13863 --6.43262 11.2629 -7.99468 --5.54268 11.481 -7.84943 --4.63687 11.0848 -7.74788 --5.08443 11.2419 -6.86425 --5.66808 10.9941 -6.13455 --6.08059 10.1061 -5.85343 --6.97294 10.5134 -6.19523 --7.94161 10.6136 -6.33629 --8.15188 10.3585 -5.36927 --8.0922 11.3303 -5.52918 --8.99209 11.5979 -5.87808 --9.92692 11.4512 -5.55554 --10.0826 10.6945 -4.95855 --10.7765 11.4011 -4.90368 --11.0336 11.9935 -4.16836 --10.5407 12.0206 -3.33543 --10.6531 12.8807 -2.8566 --11.5429 13.1202 -2.39561 --10.9235 12.5665 -1.85422 --10.5163 11.7391 -1.40956 --9.90543 11.6102 -0.6683979 --10.4072 11.2504 0.1456631 --9.52574 11.5282 0.5662861 --8.64568 11.8081 1.00293 --7.88446 11.1769 1.1497 --8.08232 11.3108 0.1626221 --7.18421 11.8266 0.2426351 --7.24949 11.9894 -0.7513159 --6.23237 11.9241 -0.8250039 --6.07268 12.3117 0.1014301 --6.04794 12.3869 1.09335 --5.96504 12.096 2.09355 --5.07852 11.6742 2.45208 --4.28603 11.9515 1.80456 --3.70267 12.4549 2.32543 --2.9301 12.3577 2.87326 --3.44473 13.1004 3.40741 --3.3138 12.1803 3.79436 --2.49269 12.6558 4.13073 --2.41089 13.5245 3.73553 --2.11934 13.8182 2.85582 --2.52019 13.2114 2.11124 --3.41986 13.4062 1.87485 --3.06329 13.1585 0.8697611 --3.9995 13.127 0.9693941 --4.01159 12.9922 -0.01687538 --4.22385 12.125 -0.4425529 --4.97685 11.5549 -0.1999029 --5.58967 10.8626 0.07890422 --6.32567 10.1799 0.3687851 --5.62422 9.84683 0.9763101 --4.81629 9.39697 0.9220071 --4.34857 8.75712 1.45231 --4.49018 8.25065 2.30054 --5.17739 7.53342 2.19485 --5.09667 6.56227 2.37434 --4.43315 5.95 2.87397 --3.66142 5.39437 2.5951 --3.35113 6.23413 3.18002 --3.78233 6.9097 2.63368 --3.16112 7.67651 2.33602 --3.17266 7.12838 1.49074 --2.25199 6.82092 1.68701 --1.63599 7.4975 2.0485 --1.14057 8.06816 2.66717 --0.943707 8.9445 3.19157 --0.523393 9.35895 3.95422 -0.138476 9.32388 3.25424 --0.05106053 10.2376 3.15861 --0.467388 10.297 2.28472 --1.42604 9.9836 2.64822 --1.39225 9.2125 2.03716 --1.23256 9.89802 1.34827 --0.630075 9.0384 1.38951 --0.197621 9.19934 0.5481991 -0.500995 9.9097 0.3311831 --0.397804 10.3138 0.5555881 --0.675505 9.67825 -0.1702709 --0.16712 9.78222 -1.01045 --0.998259 10.3881 -1.11482 --0.920501 9.51418 -1.60061 --1.94264 9.80166 -1.74254 --1.53469 10.3641 -2.44212 --0.638988 10.7543 -2.23828 -0.201844 10.516 -1.68564 -0.920025 10.2319 -2.38864 -0.455667 10.9991 -2.72112 -0.713161 11.6499 -2.10046 -0.20238 11.9739 -1.28766 -0.104399 12.4805 -2.11503 --0.966686 12.3141 -2.17912 --1.30656 12.0716 -1.26156 --2.21253 11.7856 -1.00077 --2.9335 11.6857 -0.3863279 --3.42189 10.8942 0.01735252 --3.58319 10.5459 0.9069221 --3.7044 9.81174 1.57709 --3.77973 9.82443 2.53497 --2.851 10.0689 2.76759 --3.45555 10.2612 3.58823 --3.80881 10.677 4.36824 --4.72178 10.941 4.78482 --5.47869 11.5377 4.47239 --6.27348 10.9534 4.1462 --6.48655 11.9178 3.99542 --6.68245 11.3893 4.86824 --6.87899 10.4046 5.04178 --5.95811 10.1154 5.02666 --5.40197 9.78294 4.21071 --6.23872 9.27706 4.1427 --6.47454 8.90191 5.08216 --7.33146 9.46059 4.90457 --8.01468 9.64651 4.15873 --8.71902 9.77885 3.50136 --8.55013 10.6763 2.98853 --9.22218 10.0502 2.72389 --9.76576 10.0101 3.54905 --9.97286 9.81187 4.45313 --10.0048 8.82189 4.53382 --9.57051 8.84071 5.37917 --10.1784 8.84496 6.16289 --10.9031 8.34496 5.79803 --10.6291 7.73698 4.9934 --11.1001 8.62124 4.84391 --11.3462 9.59761 4.85225 --12.3006 9.4094 4.76371 --12.368 10.3994 4.47912 --12.9045 11.0341 5.04143 --13.8185 10.9916 4.74271 --14.3137 11.8216 4.57588 --13.684 12.3941 5.18215 --12.8348 12.7914 5.1748 --12.9865 13.0324 4.18706 --12.0703 13.0901 3.76773 --11.2235 13.4361 3.3739 --11.4317 12.8314 2.6787 --10.725 12.2958 3.06964 --9.73611 12.1754 2.92224 --9.01346 12.4598 2.34894 --8.02159 12.4875 2.18395 --8.3084 13.3929 1.79439 --9.24621 13.4545 2.06868 --9.6104 13.817 2.84323 --10.0444 14.681 2.5691 --10.9408 14.9928 2.54087 --11.5731 14.4263 3.05553 --11.9768 13.7978 2.45794 --12.4719 13.2176 1.90662 --13.3796 12.8951 1.70326 --12.6242 12.3082 1.4323 --12.1726 12.4424 0.5583481 --12.3234 11.748 -0.1147959 --12.1942 11.1321 0.6867151 --11.9975 10.255 0.3832561 --12.1673 9.48752 -0.1296799 --13.0863 9.48525 0.3646551 --13.9329 9.72229 0.8873411 --14.1335 10.2679 1.66849 --14.2663 9.93174 2.56269 --13.6847 10.5604 3.00298 --12.7353 10.6814 2.72734 --12.0841 9.79055 2.91298 --11.3355 9.1549 3.10306 --10.7172 8.46235 3.25931 --9.90185 8.15034 2.906 --8.90559 7.98822 2.96448 --7.96794 7.53812 2.77102 --7.30097 7.35341 2.03517 --7.57113 7.58127 1.05269 --6.74494 8.11031 1.31677 --6.57104 8.04585 0.3078651 --6.37077 7.04694 0.5089971 --5.86905 6.21928 0.1842841 --5.30755 6.53274 0.9329481 --4.61563 5.98095 0.4786811 --4.55691 5.57784 1.30031 --5.31523 5.45697 1.92796 --5.09862 4.56844 1.45552 --6.0706 4.85085 1.45983 --6.24581 4.26475 2.12015 --7.14755 4.03691 2.60903 --7.1344 3.34806 3.36118 --6.56381 2.53526 3.52535 --6.21593 2.84172 4.4143 --7.18956 3.08622 4.39527 --6.88186 2.7388 5.30143 --7.73512 2.74521 5.7571 --7.81345 2.09734 6.42784 --7.86885 2.61475 7.29455 --7.21275 3.03907 6.75808 --8.02079 3.65558 6.48527 --8.32819 4.38637 7.05048 --7.75026 5.17371 7.37131 --8.53449 5.56414 6.86893 --9.0705 6.18399 6.29359 --9.18547 6.43868 5.37004 --10.1309 6.48984 4.95711 --10.075 5.90596 4.10914 --10.6033 5.77477 3.25684 --11.4915 5.55095 2.86298 --11.4826 6.45165 2.88619 --12.2541 6.34856 2.26058 --12.2754 7.03374 1.60909 --13.2132 7.28498 1.75081 --13.3072 6.29687 1.88416 --14.0779 6.51246 1.24737 --14.5756 5.70484 1.49237 --15.3501 6.2173 1.3197 --14.995 5.94206 0.4915031 --14.9704 4.97506 0.2475571 --14.8867 4.56571 1.12685 --14.2057 3.94815 1.39534 --13.5976 4.61955 1.78343 --13.2819 5.16665 2.51034 --14.2472 5.23537 2.79707 --14.5276 5.70771 3.56346 --13.9732 6.28778 2.90681 --13.0992 6.37031 3.40807 --13.0369 7.09092 4.03209 --13.9625 7.06634 4.32548 --14.5867 7.38594 3.6435 --14.5972 8.02436 4.4101 --15.0789 7.18608 4.62539 --15.5561 6.9159 5.49025 --15.8378 7.82428 5.45924 --16.6706 8.33384 5.64102 --17.2497 8.3269 6.36882 --17.1027 7.29181 6.47553 --17.7013 6.74951 5.9415 --18.2728 5.92549 6.08992 --19.2061 5.69527 5.75225 --19.6374 6.25774 5.06496 --20.5171 5.82204 5.06144 --20.8216 4.94617 5.40425 --20.5654 3.93048 5.26953 --20.0435 3.55313 4.5116 --19.3611 3.88696 3.78356 --20.2026 3.96436 3.1476 --20.2079 4.27207 2.14607 --19.1955 4.02096 2.10907 --19.7393 3.77259 1.3072 --20.7043 3.54772 1.53513 --21.217 4.03306 2.22869 --22.1289 4.3414 2.40394 --21.9778 4.90727 1.56706 --22.188 5.94708 1.6234 --21.5108 5.90785 0.9634941 --21.4206 6.92175 0.7647941 --21.8534 7.82194 0.6919021 --21.4815 8.44541 1.34703 --22.1249 9.13216 1.70433 --22.7184 8.39449 1.3292 --23.5615 8.67741 1.67106 --23.3613 8.92225 0.7785541 --23.4343 9.47534 0.00611501 --24.1533 10.0249 -0.4309919 --24.6745 9.84649 -1.23417 --24.0765 10.5448 -1.45637 --24.4249 11.1656 -2.01152 --25.2414 10.9792 -1.40261 --25.264 10.9464 -2.40865 --25.9243 11.0546 -3.19418 --25.9954 12.0134 -3.6847 --25.7067 11.7566 -4.58168 --25.1907 12.5228 -4.92813 --25.7522 12.8548 -5.57639 --26.0894 13.7857 -5.23268 --26.5051 14.687 -5.24813 --27.1509 14.7527 -4.50099 --27.7902 14.0271 -4.71781 --28.4303 13.3382 -4.33287 --28.0604 12.425 -4.41673 --28.4449 11.5527 -4.20893 --29.0154 10.7519 -4.1762 --29.7423 10.3848 -3.62626 --29.0771 9.75529 -3.25114 --28.4636 9.27589 -3.7982 --28.4591 9.67989 -4.72995 --27.4414 9.93293 -4.63921 --26.7807 9.54115 -3.95225 --27.0007 10.2308 -3.35417 --26.376 9.9653 -2.60018 --25.4792 9.49245 -2.891 --25.7081 8.57828 -2.63242 --25.4127 7.63445 -2.56097 --24.9193 6.77252 -2.79835 --25.4321 6.87424 -3.62368 --24.9536 6.91598 -4.53667 --25.0949 7.85999 -4.18235 --24.2061 8.35185 -4.33653 --24.0745 8.13365 -3.37724 --23.7429 9.05495 -3.05611 --23.1248 9.58027 -2.4885 --23.0958 9.76121 -3.53426 --23.8494 10.2686 -3.91943 --24.7529 10.0975 -4.39213 --24.8167 9.38584 -5.07081 --24.698 9.24554 -6.08325 --23.6644 9.51425 -5.94048 --23.0072 10.2645 -6.1597 --23.2065 10.8913 -5.3995 --22.9179 11.8494 -5.22899 --22.3579 12.1402 -4.40142 --21.4823 11.9736 -4.64223 --21.6031 11.268 -3.95098 --22.1912 11.307 -3.09905 --21.5912 11.8038 -2.47285 --20.8983 12.4775 -2.24333 --20.7455 13.487 -2.37434 --20.4978 13.1116 -1.3607 --19.4836 13.0475 -1.3608 --20.0161 12.7365 -0.5693919 --20.6945 13.2766 0.1004561 --19.9245 13.9454 0.2604961 --19.7888 14.8249 0.6497151 --20.4989 15.3962 1.09294 --20.0252 15.9409 0.4255741 --20.2931 16.2695 -0.4628899 --20.5303 17.1873 -0.3129499 --21.2132 17.3517 -0.9993989 --21.635 17.9579 -1.60284 --22.345 17.2457 -1.3793 --22.4363 17.5096 -2.34842 --22.9029 18.0194 -3.03752 --22.9782 18.6477 -2.34791 --23.9264 18.5152 -2.34204 --24.8799 18.1686 -2.28032 --25.1159 18.438 -1.36889 --25.6816 17.6265 -1.35756 --26.686 17.5441 -1.22327 --27.6022 17.3711 -1.52778 --28.2623 16.8536 -1.01294 --28.8707 17.6311 -1.08455 --29.0186 17.534 -2.06428 --28.7005 17.1163 -2.93395 --28.341 18.0369 -2.89251 --27.5369 18.6453 -3.01391 --26.7437 19.1256 -3.33699 --27.0187 20.0332 -3.47797 --26.7939 20.9147 -3.97372 --26.0383 20.5862 -4.57897 --26.8681 19.9342 -4.52514 --27.51 20.4963 -5.08118 --27.4115 21.4944 -4.88639 --27.7067 21.5405 -5.86996 --26.8684 21.4281 -6.42509 --26.7811 22.3653 -6.87811 --26.2189 22.7569 -6.2405 --25.3222 22.2456 -6.40021 --25.515 21.9115 -5.45219 --25.9744 21.1455 -5.87659 --26.3903 20.289 -5.39732 --27.0644 19.5572 -5.69625 --27.2876 20.3711 -6.25585 --27.7232 19.5245 -6.62455 --27.7964 18.5628 -6.37271 --28.3471 17.6687 -6.37751 --29.303 17.357 -6.44679 --30.1309 16.9536 -6.76217 --30.1254 17.9 -6.42401 --30.7841 17.9221 -7.20002 --29.9551 17.6989 -7.75358 --29.7982 17.8458 -8.741 --29.5214 18.8017 -9.10434 --29.4123 19.7589 -8.8559 --28.8884 20.1688 -8.06704 --28.736 19.3068 -7.59176 --27.9653 19.0667 -8.15494 --27.3462 18.3032 -8.3921 --27.8302 17.4797 -8.01376 --26.9467 17.3914 -7.60317 --26.2098 16.9931 -8.22539 --26.6651 16.121 -8.0663 --26.7417 15.4237 -7.38068 --26.722 14.55 -6.91892 --27.7368 14.6145 -7.08392 --27.6104 14.1286 -7.8877 --28.1844 14.396 -8.62136 --27.3314 13.9342 -8.99711 --27.5018 14.8597 -9.38141 --28.3075 15.4985 -9.42071 --28.0202 16.4543 -9.64596 --28.023 17.3171 -10.0645 --27.3961 17.3127 -10.8207 --26.8957 16.5055 -10.3832 --26.5178 15.6131 -10.1191 --25.6128 15.376 -10.296 --25.821 15.4928 -11.2368 --25.8867 15.3031 -12.2493 --26.4143 14.5556 -12.7675 --27.1197 13.8768 -12.4997 --26.8881 13.941 -11.5509 --27.6134 14.571 -11.3278 --27.5728 15.5615 -11.3652 --28.1417 15.4807 -12.1459 --27.2196 15.3352 -12.4232 --27.166 16.1074 -13.0977 --27.0001 15.6534 -13.9297 --26.0174 15.5751 -13.7829 --25.4125 16.0702 -13.1154 --24.4883 16.3813 -12.8174 --24.979 16.9082 -13.4551 --25.1786 17.3334 -12.5648 --24.5872 18.1127 -12.3256 --24.7345 17.5935 -11.4842 --25.1916 18.3315 -10.9061 --24.2546 18.1091 -10.6206 --23.9746 17.166 -10.1873 --23.5969 16.2928 -10.4534 --23.2238 15.6065 -9.86313 --23.9213 15.1287 -9.38353 --23.5008 15.4741 -8.52616 --24.0574 16.047 -7.88749 --24.5925 15.2674 -7.78446 --24.467 14.2615 -7.53027 --23.6026 13.9358 -7.11613 --23.9574 13.0749 -7.59301 --23.0137 13.2333 -7.47244 --22.5732 12.6268 -8.17045 --21.908 12.4193 -7.50595 --21.9517 13.3393 -7.13227 --21.0207 13.0488 -7.33482 --21.0543 13.6763 -6.55256 --21.3229 14.1302 -5.70845 --21.2057 15.0624 -5.64534 --20.5999 14.8946 -4.87888 --19.8768 14.3607 -5.32014 --19.4179 14.9342 -6.00833 --18.9145 14.9028 -6.83603 --17.8739 14.9603 -6.99184 --17.0261 14.6461 -7.38891 --16.3469 14.168 -6.74876 --16.8644 13.9676 -5.93651 --17.7358 14.5059 -6.02316 --17.241 15.2846 -5.66113 --17.8274 15.4273 -4.91201 --17.2299 16.1751 -4.79841 --16.5514 16.8753 -5.12565 --15.6381 16.7989 -5.55577 --15.2454 17.646 -5.95612 --15.7655 18.472 -5.62926 --16.0848 17.8171 -4.96095 --16.6722 18.2557 -4.21249 --15.8172 18.8644 -4.02979 --15.7053 19.2636 -3.11082 --16.4607 19.6336 -2.54308 --16.6843 19.2845 -1.61709 --17.5188 19.2527 -1.11674 --17.1611 19.6001 -0.2062059 --16.4673 20.2052 0.01248912 --16.0251 20.6163 -0.8306439 --16.7016 21.3305 -0.5482349 --16.0445 21.7821 0.01715102 --15.9532 22.8407 -0.1033119 --15.3756 23.1929 -0.8594319 --15.7502 23.4709 -1.73059 --14.9266 23.5486 -2.25361 --15.1675 23.8165 -3.14253 --15.3971 24.3701 -3.8841 --16.3762 24.4987 -3.86461 --16.9741 24.3455 -3.03916 --17.0251 23.4715 -2.47501 --17.3392 22.5895 -2.69669 --16.5629 22.1377 -3.12897 --16.5372 21.213 -3.1029 --16.3689 20.98 -4.02925 --16.7142 20.6673 -4.92059 --16.2397 19.7774 -5.27578 --16.9679 20.0878 -5.97046 --17.5778 20.8576 -5.74077 --17.8773 19.9557 -5.3316 --18.2429 20.572 -4.61467 --19.0427 20.3617 -5.08644 --19.1487 19.5967 -5.78266 --19.8825 19.5655 -5.11237 --20.4516 18.9214 -4.46369 --21.0092 18.6274 -3.707 --20.7478 19.6016 -3.81768 --21.3001 20.43 -3.74292 --21.5369 21.2207 -4.33797 --21.2397 22.0744 -3.89597 --21.3034 22.1076 -2.89636 --20.6904 21.391 -2.55568 --20.9453 21.1632 -1.68586 --21.403 20.4856 -1.13059 --20.7789 20.9561 -0.5809199 --20.0703 21.0208 0.1376621 --20.1104 21.8118 0.6710611 --20.7752 22.5307 0.7884611 --20.6672 22.9081 -0.1135699 --19.668 22.9947 -0.2081149 --19.7263 23.8208 -0.7670739 --18.8289 23.6473 -1.25644 --18.5119 22.7366 -1.20805 --18.9605 21.9497 -1.55782 --19.6015 22.6866 -1.28634 --18.9762 22.7279 -2.07258 --19.2685 23.5262 -2.60457 --18.298 23.4183 -2.70705 --17.9895 24.3855 -2.41585 --17.8728 24.577 -1.42913 --18.6013 24.9962 -1.8703 --18.0303 25.6088 -2.42637 --18.2884 26.1646 -1.66489 --18.4338 26.4762 -0.7297489 --18.7918 27.1729 -0.1346639 --19.6605 26.7341 -0.1613239 --19.3557 27.0029 0.7704401 --20.21 26.6679 1.18685 --21.15 26.7924 1.48169 --21.7172 27.1796 0.6030421 --22.1836 26.9732 -0.3066439 --22.8798 26.3874 -0.5714109 --22.7718 26.815 -1.49837 --23.026 26.4193 -2.43276 --22.6467 25.5935 -2.85048 --23.1096 25.418 -3.68799 --22.2579 25.5119 -4.32435 --21.8873 24.6409 -4.08363 --21.0859 25.0882 -4.4901 --20.6818 24.5285 -5.23986 --20.9811 23.8705 -4.53334 --21.4337 23.0242 -4.46447 --22.2123 22.4424 -4.48595 --22.8078 22.4809 -5.31991 --23.7937 22.3538 -5.47556 --23.722 23.1272 -4.85262 --23.6754 22.8204 -3.92155 --24.6307 22.6493 -4.1455 --24.4383 21.6185 -4.31251 --23.7152 21.6416 -3.68451 --23.2661 20.8856 -4.11076 --22.7141 20.4717 -4.86332 --22.4343 19.9218 -5.62493 --22.9901 19.1984 -5.9858 --23.9717 19.2426 -5.53193 --24.9155 19.2299 -5.23056 --25.0507 18.7312 -6.11858 --24.579 18.4944 -6.97285 --24.5991 18.0484 -7.83112 --23.8067 17.5434 -8.10522 --23.5594 17.1253 -8.98751 --22.5861 17.1319 -8.91695 --21.8963 17.0707 -9.6787 --21.7816 16.3642 -8.97446 --20.9871 16.1606 -8.38401 --21.1544 16.0508 -7.41429 --21.6133 16.7622 -6.8895 --22.0408 16.3322 -6.05358 --22.048 16.0566 -5.13699 --21.746 16.6427 -4.39104 --21.6479 17.3945 -4.97827 --20.7598 17.4419 -5.3567 --19.7022 17.6338 -5.4915 --19.358 16.7486 -5.20092 --19.0001 17.3722 -4.4464 --18.5239 16.9971 -3.64144 --18.3371 17.6953 -2.96645 --18.1286 18.6031 -2.54258 --17.6263 18.2391 -3.30854 --16.7564 17.992 -2.97297 --16.6435 17.1642 -3.34224 --15.7174 17.1278 -3.65505 --15.0994 17.0504 -2.98033 --14.7041 16.1081 -2.85636 --14.3438 16.1251 -3.78035 --14.1199 15.2154 -3.69995 --13.7826 15.7556 -4.51511 --13.9673 15.1114 -5.24786 --14.6043 14.9931 -5.94873 --14.2982 14.5801 -6.84063 --13.2676 14.6621 -6.79775 --12.9044 15.3863 -6.10743 --12.8412 15.7652 -7.03848 --13.8179 15.8575 -7.30687 --14.6254 15.3766 -7.49181 --14.0515 15.7506 -8.26604 --13.1913 15.2587 -7.93743 --13.0704 14.2871 -7.83145 --13.4616 13.5505 -7.36322 --14.4263 13.5978 -7.71193 --15.2117 12.9592 -7.53646 --15.2397 13.0261 -8.54244 --16.0182 13.1075 -9.2427 --16.1446 14.0665 -9.00893 --16.9791 14.482 -9.39612 --16.8226 15.5094 -9.50108 --15.8756 15.0612 -9.68899 --15.0489 15.0452 -9.02557 --15.5042 15.9341 -8.90758 --16.3871 16.5033 -8.84363 --16.003 17.2138 -8.26638 --15.6224 16.3936 -7.92268 --16.1133 16.8876 -7.26187 --15.2117 16.7569 -6.78134 --15.1319 17.7027 -7.0536 --14.6081 18.31 -7.79186 --14.4354 18.6365 -8.72435 --14.8117 19.4652 -9.13069 --14.2434 19.6458 -9.92601 --14.3219 20.6575 -9.82757 --14.0835 20.7993 -8.88724 --13.9327 21.5816 -8.16964 --14.5541 22.3568 -8.0369 --14.658 21.8784 -7.19371 --13.8476 22.4947 -7.28846 --13.1293 22.6959 -7.94246 --13.057 22.746 -8.9288 --12.5474 22.2119 -9.64743 --11.9517 21.4312 -9.92479 --11.8358 20.5409 -10.4811 --11.1943 20.6219 -9.7497 --11.0011 19.6637 -9.68605 --10.8798 19.5162 -8.71657 --9.95039 19.7176 -9.1393 --10.2293 18.7665 -8.912 --10.8756 18.312 -8.23975 --10.1583 18.5922 -7.59052 --10.8745 19.199 -7.70335 --11.6061 19.0235 -7.09627 --12.6042 18.9966 -7.07194 --13.2068 19.7329 -6.76609 --13.8319 19.9756 -6.00731 --13.0161 20.5032 -5.88355 --12.162 20.6556 -5.40298 --11.762 20.438 -4.4417 --12.5221 19.7955 -4.65782 --11.8664 18.9985 -4.80993 --12.6669 18.587 -4.27297 --12.8672 17.6193 -4.18833 --12.5956 17.1176 -5.08277 --12.203 16.6142 -5.82685 --11.8658 16.0125 -6.47415 --11.5753 15.1731 -6.92645 --11.7731 14.2235 -6.50198 --10.8166 14.0033 -6.66395 --11.0973 13.0481 -6.76632 --11.5704 12.8444 -7.62293 --12.4405 12.5718 -8.08819 --13.0043 11.7803 -8.32459 --12.2821 11.4216 -7.85587 --11.7687 10.8394 -7.25353 --12.0237 9.86803 -7.11939 --11.4147 9.07688 -7.09721 --10.7838 8.42444 -7.56457 --10.4151 9.33783 -7.81213 --10.2323 9.55048 -8.70194 --10.2827 9.72087 -9.69325 --10.1096 9.08885 -10.4169 --10.4883 8.16055 -10.8184 --11.1526 8.5869 -11.4837 --11.4697 9.437 -11.9319 --10.5088 9.46296 -12.2137 --10.3767 10.3581 -12.4279 --10.717 10.4237 -11.4621 --9.92347 9.8409 -11.3087 --9.55691 10.5271 -10.6603 --9.10839 10.4323 -11.559 --9.51822 11.2099 -12.0698 --9.14634 12.0132 -12.5399 --9.54934 12.9027 -12.539 --9.66126 13.6804 -11.8361 --10.0432 13.9192 -10.9677 --9.175 14.2558 -10.7876 --8.59333 13.7615 -11.4713 --8.20658 14.0092 -12.3009 --8.06564 14.7557 -12.9799 --7.11117 14.9362 -13.1302 --7.11484 15.1668 -14.1267 --6.97525 16.1983 -14.0874 --7.0651 16.5686 -13.1717 --6.69712 17.3523 -13.6148 --7.50508 17.6674 -14.117 --7.74932 18.1271 -14.976 --8.35414 18.2974 -14.1387 --8.25858 19.2334 -14.2412 --9.07242 19.338 -14.8047 --8.58525 19.2552 -15.6633 --8.26629 18.9956 -16.4798 --8.567 18.3031 -15.8747 --8.80339 17.4338 -15.4985 --9.75833 17.4694 -15.3841 --9.36128 18.038 -14.7831 --9.38421 17.9274 -13.7571 --10.2788 18.3979 -13.5484 --10.4713 19.1978 -14.0332 --10.7922 19.6961 -13.2183 --10.4323 20.5686 -12.7662 --9.98238 21.4728 -12.8408 --10.8427 21.9415 -12.5412 --10.7064 22.2364 -11.5734 --11.1324 22.7032 -10.7209 --11.2107 22.602 -9.79223 --10.8261 22.5659 -8.82583 --10.7865 23.448 -9.26818 --10.9828 24.2413 -8.69829 --10.7695 24.751 -9.53057 --11.1639 25.5935 -9.87693 --12.0084 25.2794 -9.45695 --12.4676 26.1394 -9.47454 --11.9253 26.9795 -9.62965 --11.524 26.9126 -8.74322 --11.8592 27.2985 -7.83905 --11.9028 26.5259 -7.26944 --12.252 27.0343 -6.54635 --11.925 26.5711 -5.6401 --12.2735 25.8123 -5.0876 --13.333 25.7755 -5.06785 --13.7338 26.607 -5.48742 --14.7046 26.7939 -5.22075 --14.3441 27.562 -5.71306 --13.6199 28.1988 -6.09958 --13.3856 28.7841 -6.96125 --14.2819 29.133 -6.5449 --14.7881 29.652 -5.83118 --15.6172 30.0653 -6.4153 --16.2761 29.4167 -6.45287 --16.6825 28.7275 -7.11752 --16.2966 29.3663 -7.89281 --16.2354 30.347 -8.08221 --16.162 31.3416 -7.96722 --16.496 32.2945 -7.83379 --17.3264 32.7154 -7.49502 --17.376 33.5557 -6.93961 --16.8113 33.4386 -6.131 --16.6423 34.0835 -5.41732 --17.1078 33.7308 -4.60787 --17.2842 33.2345 -3.73526 --17.389 32.3048 -3.30006 --17.2397 31.3122 -3.03504 --17.2413 30.3907 -2.64011 --16.5926 30.5672 -1.84714 --17.1896 29.7607 -1.8157 --18.014 29.7614 -1.14562 --18.681 29.249 -0.6840529 --18.3695 28.7979 0.06311092 --17.6367 28.4164 0.6559691 --16.908 27.8562 0.5002321 --16.2512 27.201 0.1392141 --16.6372 26.3252 -0.06420178 --16.652 25.368 0.02058682 --17.3823 24.8261 0.5051641 --17.3577 25.0698 1.51502 --16.5441 25.6434 1.39153 --17.3571 26.1716 1.52671 --17.7062 26.103 2.48346 --18.6487 25.8187 2.64534 --18.5521 26.5653 3.28568 --18.7105 27.0455 4.20171 --19.0466 27.1345 5.1465 --18.4477 26.9204 5.96335 --19.0226 26.1491 6.07822 --18.1793 25.661 5.89391 --17.7542 24.9286 5.33894 --18.1528 24.0702 4.99122 --18.3483 23.5145 5.7748 --18.8345 23.3947 4.87795 --19.5237 23.134 4.29889 --20.4269 23.453 4.74846 --20.1462 22.6607 5.24028 --19.4624 21.9384 5.24599 --19.0344 21.2359 4.61044 --20.0438 21.0211 4.55822 --20.1742 20.0749 4.17666 --20.4124 19.7532 3.18938 --20.3512 19.3684 2.24161 --21.3262 18.9831 2.05396 --21.6577 18.307 2.78903 --21.5432 17.4068 2.42242 --21.2031 16.6442 1.86931 --20.5953 16.1426 2.47472 --20.1128 15.504 3.10221 --20.3034 15.197 2.206 --21.0868 14.629 1.82692 --21.0724 13.6413 2.02561 --21.9421 13.0763 1.78881 --22.791 12.7266 1.42813 --22.5489 13.4204 0.6979761 --22.5506 14.2707 0.1187931 --22.1294 13.7172 -0.6949629 --22.9919 13.9234 -1.19015 --22.9355 13.2158 -1.9869 --22.2086 13.4632 -2.70325 --21.7641 12.721 -3.21914 --20.7798 12.7595 -3.30013 --20.0417 12.1756 -3.70404 --19.1801 12.2047 -4.16001 --19.3397 12.8714 -4.84206 --19.2116 13.3472 -3.97008 --19.5105 13.0772 -3.08555 --19.0718 13.7675 -2.67992 --18.5089 14.467 -2.08895 --17.8783 13.8531 -2.57886 --18.3345 14.5452 -3.08744 --18.7348 15.4627 -3.22581 --18.7648 15.7871 -4.15544 --19.5971 15.9225 -3.62038 --20.2367 15.5349 -2.94867 --21.0424 15.6029 -3.49934 --21.6068 14.8602 -3.78628 --22.3289 15.1333 -4.47335 --23.1823 15.2826 -4.89144 --23.6153 14.5158 -4.47327 --23.8314 14.3534 -3.56048 --23.9375 15.2556 -3.09432 --24.3321 15.1762 -2.18371 --24.3672 14.3527 -1.58666 --25.3829 14.2879 -1.74964 --25.4659 14.88 -0.8951009 --26.4019 15.0424 -1.02345 --26.9868 14.4858 -0.4004199 --26.8645 15.1911 0.2493721 --26.3235 16.1093 0.05859842 --25.8803 16.7781 0.6393861 --24.9563 16.7921 0.1940701 --25.0996 16.336 -0.6739559 --24.3119 15.9334 -1.15031 --23.8007 15.2316 -0.6280479 --23.9731 15.457 0.4097101 --24.8664 15.4716 0.8796181 --24.4259 15.0229 1.67603 --23.4921 15.1887 1.42569 --23.7305 14.4782 0.7219131 --23.3165 13.9112 1.47808 --23.0257 13.2915 2.2304 --23.7803 12.689 2.12232 --24.4119 12.0659 2.53427 --24.4182 12.6209 3.34293 --24.929 13.3691 3.80775 --25.4502 12.7318 4.36143 --25.8512 12.1795 3.5829 --25.4181 11.5205 4.12192 --25.9251 10.6986 4.04321 --25.5372 9.77124 4.11009 --26.2067 9.07982 4.1542 --25.8902 8.35485 4.69446 --25.8821 8.37883 5.70717 --25.8623 7.53283 6.09484 --25.4361 6.86883 6.53671 --24.6974 6.41979 7.02067 --23.87 6.99475 6.91026 --24.5923 7.64689 6.62208 --24.1649 8.35164 6.10246 --24.6057 9.09881 6.64412 --24.9698 8.72895 7.5009 --25.7037 8.18324 7.88089 --26.3136 7.59813 7.27027 --26.3394 7.03508 8.04692 --26.3881 6.98992 9.08835 --25.9138 6.30267 9.57715 --25.8675 6.16545 10.5967 --26.8063 6.26047 11.0099 --26.5931 6.72695 11.8751 --26.2179 6.90624 12.7936 --25.2465 7.30104 13.047 --25.3453 8.31153 13.0389 --24.4232 7.91459 13.0303 --23.5092 7.90253 13.441 --22.9538 7.01711 13.4548 --22.5872 7.50755 12.74 --22.2369 6.61735 12.8477 --22.0503 6.73493 11.8281 --21.1634 6.85252 12.1497 --20.7454 7.38964 12.8935 --21.2391 7.74877 13.665 --20.7657 8.39357 14.2468 --20.1741 9.05597 13.7239 --19.2922 8.84092 13.4098 --18.2613 8.61245 13.4545 --17.3313 8.55324 13.5982 --16.6771 8.09225 14.1734 --16.8749 7.73011 15.0722 --16.5035 8.40804 15.7052 --17.056 7.85696 16.3241 --17.6971 7.29309 15.6975 --17.7149 6.31407 16.0366 --16.7403 6.38689 15.7 --15.9321 6.98927 15.6124 --16.0061 7.2112 16.6014 --15.8823 8.17923 16.8116 --15.4259 8.92929 17.3787 --14.8292 8.17444 17.7032 --14.2908 8.94322 17.4345 --14.6731 9.68795 18.0248 --15.5522 10.0785 17.6068 --15.6188 10.6859 18.4356 --16.6778 10.5182 18.1317 --17.4791 10.0612 17.7321 --17.8909 10.0258 16.8248 --17.921 8.96961 16.7033 --18.555 8.81343 17.3734 --19.2952 8.17621 17.3342 --19.7527 8.20408 16.4947 --20.3705 7.45076 16.1219 --21.2392 7.09885 15.9159 --21.7878 6.86279 15.1013 --21.2726 6.03072 14.8494 --20.919 5.1416 14.4963 --20.5809 4.2791 14.1208 --19.6913 4.65939 13.9702 --19.9715 5.59716 13.9264 --19.9639 6.43817 13.368 --19.2771 6.75974 13.9822 --18.9022 7.18996 13.1897 --19.5178 6.95863 12.452 --19.8683 7.78218 11.9343 --19.8172 8.63613 11.4069 --20.1734 9.56271 11.4286 --19.5866 10.4284 11.5639 --18.8471 10.3077 10.854 --19.6518 10.3152 10.3084 --20.2489 11.0885 9.95757 --19.8349 11.1896 9.1057 --19.648 11.9471 8.55018 --18.784 11.6062 8.86745 --18.3999 12.4673 8.40962 --18.4576 13.2196 8.9674 --17.482 13.2973 9.19661 --17.3843 12.3167 9.09221 --17.0247 12.2152 8.23006 --16.5096 12.9649 8.39694 --16.0057 13.0896 9.24742 --15.47 13.386 8.45323 --14.5254 13.2475 8.13213 --14.5648 12.2852 7.97273 --14.248 11.3098 8.32196 --14.136 10.5755 9.05648 --13.5737 10.3379 8.28268 --13.4713 10.507 7.31698 --12.5268 11.0092 7.42202 --12.8953 11.1881 6.46385 --13.8749 11.0223 6.13864 --14.156 11.5154 6.87835 --15.087 11.7657 6.87356 --16.0105 11.4358 6.56211 --16.887 11.166 6.2063 --17.7985 11.4229 5.8213 --18.6831 11.1254 5.36312 --18.7592 12.0543 5.62443 --19.2681 12.7588 5.11956 --19.8938 11.9562 5.15318 --19.9173 12.4085 6.09814 --20.735 11.8197 6.16165 --20.9851 11.0521 5.59494 --21.605 11.6003 6.01024 --22.1693 11.3284 6.80579 --21.9585 12.1164 7.27986 --21.8408 12.9514 7.87306 --21.4309 13.6178 8.55351 --22.2791 14.1324 8.41686 --22.9403 14.095 7.61227 --23.0426 13.4 6.9402 --23.8973 13.3357 7.43953 --23.6753 13.1139 8.36916 --24.5475 13.5451 8.42096 --24.2539 14.3101 8.93708 --23.5541 14.6482 8.27878 --23.4007 15.3319 7.53493 --23.3954 15.6122 8.4527 --22.739 15.3695 9.11169 --21.8491 15.5739 8.60609 --22.0091 15.272 7.63976 --21.585 16.0737 7.29546 --20.7148 16.5114 7.05836 --19.9115 16.9825 7.38713 --19.2248 17.1676 8.00019 --18.6335 16.3387 8.01078 --19.5078 16.3171 8.63004 --19.0149 16.9145 9.22063 --18.1045 17.3256 9.20764 --17.7458 17.2574 8.23598 --17.3275 16.4184 7.80737 --17.9038 16.6816 7.02377 --16.8832 16.6372 6.79607 --16.2193 16.0582 7.018 --15.6133 15.7253 7.79258 --15.6229 15.1301 8.6298 --15.0039 14.7373 9.31337 --14.0242 14.3474 9.4133 --13.6635 13.4528 9.65456 --12.9142 14.0499 9.30707 --12.6699 14.0819 10.3109 --13.1564 14.062 11.1319 --13.45 14.0443 12.1246 --12.9146 14.81 12.5125 --12.7008 13.8253 12.7662 --12.1545 14.2783 13.5278 --11.2733 14.1245 13.2201 --10.5426 14.812 13.0884 --11.1482 15.245 13.7764 --11.0641 15.9947 14.4443 --10.4815 16.8227 14.3761 --9.98879 17.0668 13.5391 --9.05994 17.3959 13.6144 --8.19289 17.4039 13.181 --7.65756 17.2894 12.3649 --7.16487 16.5748 12.9074 --6.98068 15.603 13.1991 --7.67139 15.5444 13.8697 --8.28259 16.1781 13.3888 --8.33855 15.4953 12.7495 --8.89007 14.7235 13.0004 --9.60722 14.8262 13.6606 --8.77268 14.8758 14.1918 --8.03127 14.1437 14.0803 --7.20942 13.5155 13.8929 --6.2819 13.9041 13.8605 --6.83052 14.1727 14.6781 --5.92842 14.657 14.598 --5.77372 13.6693 14.7089 --5.75952 12.8729 14.0547 --5.58857 12.9468 13.0404 --5.10265 12.0979 12.9197 --5.88789 11.8027 12.3595 --5.92109 12.7766 12.1148 --6.57022 13.4384 12.2217 --6.97838 14.2192 11.7786 --7.95746 14.2366 11.6211 --8.626 14.7911 11.1321 --8.96517 15.0432 10.2731 --8.57396 15.5019 9.44626 --7.96744 16.0681 8.78005 --8.20721 17.0102 9.00009 --7.42603 17.6826 8.87803 --6.74053 16.9046 8.90941 --6.14497 16.2155 9.00159 --6.85879 16.1485 9.75054 --7.55159 16.822 10.003 --8.31841 16.9826 10.6294 --9.12416 16.3801 10.2891 --10.0102 16.0504 10.0585 --9.93582 15.6495 10.968 --10.8388 15.4002 11.4115 --11.4594 16.1693 11.5813 --11.2778 15.574 12.3644 --12.1019 16.1606 12.5878 --12.6767 16.6684 11.9149 --13.5802 16.9518 11.4864 --14.0161 16.8458 10.6048 --13.6635 16.4451 9.75534 --14.077 16.6095 8.9101 --14.7558 16.9514 9.4831 --15.0319 17.4544 10.28 --15.9202 17.087 10.5756 --15.4991 16.2211 10.3806 --15.2889 16.548 11.2732 --15.194 16.4643 12.3621 --15.6553 15.9154 13.0805 --15.2944 16.243 13.8931 --14.4844 16.2308 13.39 --14.0201 16.9981 14.0054 --13.6357 17.8312 13.7303 --12.9477 18.5798 13.6604 --13.8287 18.8912 14.1531 --14.3676 18.6614 14.9535 --13.7809 18.5327 15.7608 --13.5159 19.4704 15.5759 --13.4606 20.2137 16.1982 --13.4157 21.049 16.6962 --12.4002 20.8872 16.5409 --12.0948 20.7366 15.4981 --12.7483 20.8652 14.7679 --12.2798 20.1365 14.344 --12.2062 19.2142 14.7405 --11.3736 19.4835 15.1831 --10.4242 19.4571 15.5601 --11.0002 18.6398 15.4126 --10.4488 18.0537 15.8184 --10.1777 17.0319 15.7714 --10.6429 16.1411 15.8823 --10.5366 15.1479 15.9519 --10.8437 14.6083 16.7023 --9.90431 14.7944 17.078 --9.85153 13.9508 17.5722 --9.56544 12.9779 17.7015 --10.3984 12.7535 17.2475 --10.4571 13.4697 16.5361 --9.52556 13.4076 16.6856 --9.26236 14.2916 16.1494 --9.37813 15.2612 16.3747 --8.38562 15.4282 16.711 --8.48184 15.6856 17.6591 --9.04587 16.5333 17.8117 --8.72542 17.4947 17.5006 --9.13356 17.9715 16.7171 --8.40605 18.5871 16.3313 --7.66544 18.4304 15.6566 --7.12335 18.4769 16.4799 --6.29528 18.4865 15.9011 --5.39158 18.6192 16.3981 --4.58314 18.2498 15.9979 --3.71007 17.7153 15.9009 --3.46745 17.7477 14.898 --4.28655 17.0509 14.6446 --3.99694 16.1035 14.5151 --4.31983 15.8808 15.4774 --3.49901 15.3249 15.5872 --2.95548 14.7453 16.1881 --2.85346 13.981 15.5902 --2.98141 13.2149 15.0277 --2.8911 12.3545 14.5577 --3.44351 13.0338 13.9651 --2.9431 13.0783 13.076 --2.55568 13.7207 12.4316 --3.45137 14.125 12.6074 --4.22841 14.3716 13.1864 --5.1837 14.7054 13.0432 --5.2242 15.7048 12.9008 --5.84823 15.3585 12.2435 --6.24252 15.3934 11.2625 --5.23606 15.3105 11.2369 --4.94791 16.1198 11.7909 --4.06508 15.9562 11.3657 --3.29488 16.0104 10.73 --2.79668 16.7057 11.3276 --1.90597 16.2979 11.074 --1.17183 16.9147 11.2801 --0.528299 16.6144 10.6304 -0.386695 16.8347 10.5259 -1.24483 16.7373 11.1079 -0.807577 15.824 11.2417 -1.00112 15.0994 10.5336 -0.827965 14.2257 10.9292 -1.04077 14.2725 11.8933 -0.82922 14.3329 12.8334 -0.265262 13.7264 13.4105 --0.145116 14.4998 13.8882 -0.234522 15.2684 13.3393 -0.838451 15.9264 12.999 -1.61164 16.198 13.5262 -2.58748 16.3696 13.8902 -2.53291 16.9452 14.7124 -1.91124 16.1443 14.8088 -2.48864 15.6801 15.4017 -2.85488 15.0965 16.1046 -3.19848 15.4336 16.9883 -3.37567 15.7194 17.9336 -3.68576 15.6472 18.9038 -3.73133 16.4755 19.5336 -2.97927 16.6775 18.8444 -2.3151 16.0307 19.2025 -1.42982 15.4404 18.99 -0.686562 14.7958 19.1064 -0.185258 14.1025 18.4768 --0.02865873 13.7737 17.5867 -0.549877 13.2132 17.0376 -0.35408 12.9203 16.0825 -1.23961 12.8438 16.4375 -2.22795 12.5609 16.3193 -2.8305 12.452 15.6038 -3.05241 12.2764 14.6807 -2.75195 12.9566 14.021 -3.66967 13.1078 13.6776 -4.23362 12.4455 13.3202 -5.19663 12.2563 13.0821 -4.69977 11.3401 13.1315 -5.5189 10.774 13.3025 -6.45332 10.6969 12.8958 -7.04664 10.6529 13.6536 -6.65558 11.5059 14.0257 -6.69998 12.1839 13.3709 -6.71824 13.0966 13.7324 -7.05121 14.088 13.582 -7.86337 13.6618 13.9823 -7.6852 14.3234 14.7008 -8.23142 14.8411 14.1352 -7.68516 15.5874 14.4377 -6.99505 15.7995 15.1716 -6.60596 16.4343 15.7577 -7.01105 17.0814 16.3325 -6.27136 17.6878 16.7447 -6.20135 17.8799 15.7463 -5.31077 17.447 15.6763 -4.94453 17.4954 14.7145 -4.97427 18.378 15.2491 -4.73987 18.0723 16.1844 -3.77326 17.6909 16.0876 -2.7631 17.3667 15.8566 -3.26067 17.0428 16.7168 -2.41126 16.4844 16.4742 -1.43 16.5098 16.6895 -0.726538 16.1897 17.3227 -0.338607 16.2627 16.3811 --0.340568 16.7954 15.871 --0.07459183 17.5418 16.475 --0.59678 17.3296 17.299 --0.50361 17.9657 18.0093 --1.11964 17.7331 18.7979 --1.84589 17.0462 18.8015 --2.50168 17.2567 19.4967 --3.23881 16.8432 19.0173 --3.77709 16.0569 18.7703 --3.64453 16.1423 17.7281 --3.90108 16.2293 16.7888 --4.85859 16.2068 16.6398 --4.32727 15.3166 16.5973 --4.54688 15.2931 17.6156 --4.30761 14.4432 17.0892 --4.89151 13.9237 16.3779 --4.85531 13.0398 16.8944 --4.59658 12.1778 17.3483 --4.57442 11.3451 17.9624 --4.35027 11.9708 18.7095 --4.86944 12.6624 19.2308 --5.70099 13.0731 19.5085 --5.59782 12.6426 20.3648 --4.60837 12.6136 20.685 --3.85789 12.7689 21.3312 --2.93737 12.6661 21.1216 --2.81741 13.2868 20.3856 --3.10154 14.1308 20.8294 --3.87658 14.3672 20.1952 --3.18628 15.0192 20.0057 --3.05176 15.8248 19.4832 --2.35921 15.6286 18.9129 --2.13738 15.2307 18.0519 --1.20429 14.9701 18.3182 --1.55634 14.7108 19.1984 --0.805312 14.3251 19.6892 --1.14344 15.2517 20.0725 --0.119287 15.5422 19.9042 --0.36607 16.3919 19.4238 -0.218311 17.2113 19.5215 -0.346517 17.6086 18.5822 -0.762423 18.5307 18.3856 -1.00527 18.7467 19.3784 -1.69244 18.815 20.0727 -1.61412 18.082 20.702 -1.07048 17.2656 20.4804 -0.824042 16.9264 21.4494 -0.08582117 16.3527 21.3355 --0.688262 16.5827 20.7341 --0.780652 17.3891 20.1664 --1.4795 17.9024 20.6411 --2.27095 18.1667 20.0808 --2.72659 17.764 20.9109 --3.66608 17.4102 21.1872 --3.80204 16.4528 20.8775 --4.66378 16.0681 20.5835 --4.8135 17.0747 20.4427 --5.13339 16.9208 21.3677 --6.11843 16.622 21.2725 --6.94947 16.0064 21.2379 --7.51166 16.0827 22.0957 --8.35459 16.5282 21.7075 --8.50244 15.5476 21.901 --8.46655 14.6384 21.4204 --7.86248 15.1912 20.8568 --7.90182 15.0691 19.8211 --8.37037 14.2333 19.4651 --8.29704 13.4427 20.0026 --7.43897 13.4211 20.6086 --8.23265 13.6654 21.1192 --7.31675 13.7893 21.5215 --7.25485 14.7595 21.762 --6.79238 14.1726 22.5461 --7.23238 14.0376 23.4248 --7.24069 14.8912 23.9504 --6.54127 14.5151 24.5538 --5.88258 15.2255 24.7757 --4.94877 15.2131 24.4247 --5.37139 15.5978 23.5777 --5.37452 16.1942 24.3427 --5.51242 16.6954 25.2287 --5.04655 17.2975 24.5667 --5.14016 18.1517 24.2719 --5.81691 18.6789 23.7819 --6.73069 19.2107 24.0555 --7.41599 19.26 24.7329 --7.87022 19.1669 25.5419 --8.27463 19.823 26.1166 --8.30631 20.8405 26.111 --9.31349 20.6029 25.8025 --10.2905 20.4134 25.7888 --10.2037 19.8813 24.9397 --9.87627 18.8644 24.9883 --9.67419 18.7185 24.0558 --10.2779 17.914 23.837 --9.86146 17.5132 23.019 --10.0957 16.5405 23.0317 --10.7712 15.8827 23.2531 --10.1436 15.5172 23.9845 --10.2324 14.558 24.1485 --9.58726 14.5299 24.9397 --9.37194 14.6121 25.9783 --9.62032 14.2507 26.8247 --10.3952 13.6669 27.1437 --10.6463 12.8703 27.763 --11.2845 12.2594 27.375 --10.5351 11.6409 27.4895 --10.017 10.9889 26.9377 --10.5975 10.529 27.5968 --11.2831 9.7591 27.4231 --10.7157 9.15571 26.942 --10.0847 8.38955 27.0552 --9.73312 8.43277 26.0879 --10.2059 8.28163 25.2074 --10.6597 7.67908 25.7945 --9.9097 7.13266 26.0911 --10.0345 6.9663 27.0687 --9.03112 6.88526 27.2665 --8.82971 7.3601 26.4405 --8.12374 7.46326 25.7888 --8.89146 7.64394 25.1789 --9.12288 8.2631 24.4524 --8.59247 9.01232 24.0349 --7.65658 8.77161 24.1142 --7.4076 7.89838 23.7247 --8.27022 7.81844 23.2961 --8.48534 7.44544 24.1641 --9.35665 7.68762 23.5703 --10.1939 7.11957 23.7268 --9.50617 6.48509 23.8388 --10.1321 5.93411 24.422 --10.9152 5.5422 23.812 --11.3791 5.83057 24.6021 --11.5888 4.86936 24.4333 --11.3926 4.98143 25.4291 --11.1943 4.63544 26.3195 --11.5296 4.94264 27.2556 --10.6465 4.71999 27.7355 --9.64945 4.72284 27.8732 --9.58739 5.74216 27.6969 --9.15043 6.22818 28.4825 --9.91748 6.74908 28.3092 --9.25988 7.33337 28.6391 --8.45 7.50959 29.2634 --8.26468 7.00572 30.022 --8.58737 6.11286 29.7657 --7.90935 5.37691 29.6679 --7.92276 4.45147 29.3318 --8.41873 5.1656 28.7733 --8.27556 5.52567 27.8693 --7.35548 5.90001 28.1699 --6.56946 6.50166 28.1443 --6.30949 6.86527 27.2232 --5.73822 7.62067 26.8621 --6.10448 8.53336 26.8803 --6.49722 9.3667 27.1806 --7.40786 9.72059 26.9601 --7.45054 8.81854 27.3262 --7.94959 9.5869 27.7374 --8.47139 10.365 27.7188 --8.90216 10.6466 26.8866 --9.2844 10.3427 26.0088 --8.78512 10.6915 25.252 --9.11905 11.4863 25.8133 --8.46718 12.1411 26.1402 --7.88891 12.2382 26.9795 --7.89813 12.7563 27.8246 --7.68476 12.3442 28.7757 --8.14219 12.9307 29.4364 --7.44078 13.4392 28.9339 --6.47496 13.2427 28.7759 --6.36921 14.1393 28.2426 --6.95787 14.8775 28.5838 --6.82252 15.0671 27.5782 --7.21055 14.3391 27.1057 --7.07835 14.8096 26.2124 --7.38949 14.3575 25.4073 --7.78507 13.502 24.9861 --7.21225 12.7466 25.0678 --7.85074 12.5767 24.2857 --7.67553 12.6739 23.3704 --8.69544 12.8511 23.3331 --9.29841 13.1462 22.5553 --9.32475 14.0062 22.0615 --10.1832 13.6839 22.5201 --10.775 12.853 22.5391 --11.7399 13.0367 22.7952 --11.0081 13.4303 23.4196 --11.752 13.7055 24.0221 --11.877 14.3786 23.3001 --11.8261 14.7629 22.3423 --11.0113 14.3669 21.907 --11.1206 13.5911 21.3335 --10.9593 14.0013 20.4239 --11.749 14.5106 20.1334 --11.5972 15.5032 19.9772 --10.8026 16.04 20.3984 --10.4304 16.7902 21.0268 --9.62272 17.3794 21.2207 --9.08679 18.1847 21.4167 --8.71931 19.037 21.6905 --9.15964 19.9298 21.7145 --9.22379 19.8998 20.69 --9.58439 20.5615 19.9389 --10.4929 20.1667 19.8993 --11.3644 20.656 19.6432 --10.7333 20.9026 18.8673 --10.8593 20.4903 17.9141 --11.3916 19.7509 17.4479 --10.5613 19.2566 17.6988 --10.7844 19.106 18.7282 --10.4148 18.2184 18.3312 --10.8064 17.273 18.4647 --11.4186 16.5512 18.6024 --12.0162 15.9261 18.0243 --12.5256 15.2488 18.5891 --13.4478 15.472 19.0047 --14.1135 15.2872 18.1791 --15.0066 15.1557 17.7208 --14.7781 14.1801 17.6872 --15.2625 13.3551 17.5449 --14.8851 12.8353 16.8242 --13.9499 12.362 16.9257 --13.5383 13.0428 16.3611 --13.6088 12.7353 15.4402 --12.8933 12.8591 14.727 --12.4887 12.3143 15.5195 --11.6162 12.3067 15.1164 --11.1751 12.6006 15.9511 --11.4776 12.4802 16.8523 --12.4121 12.3243 16.7223 --12.7809 12.7162 17.4788 --12.7912 13.5059 16.8618 --12.1356 13.7076 17.5817 --12.7888 14.4745 17.3984 --13.6732 14.6349 16.873 --13.179 14.8563 16.06 --12.6793 15.6412 15.6744 --12.2449 14.8953 15.0648 --12.3185 13.9296 15.1516 --13.2074 14.1845 14.7177 --14.2425 14.1984 14.9103 --14.5828 14.8819 15.5581 --14.316 15.8535 15.2641 --15.1631 16.4316 15.0817 --16.0766 16.3278 15.3044 --16.6604 15.5164 15.4091 --17.3376 14.8604 14.9808 --18.1667 14.475 14.5652 --19.0187 14.7234 14.9343 --19.583 14.1536 15.5205 --19.8463 13.4387 16.0107 --18.9629 12.8297 16.1806 --19.1386 11.8046 16.1918 --18.2131 11.5093 15.9648 --17.7369 12.2524 15.5134 --16.7936 11.9571 15.5616 --16.3299 12.7826 15.2521 --15.7132 13.5462 15.5829 --16.5108 13.3054 16.1483 --15.6732 13.6171 16.6448 --16.3137 14.3486 16.6398 --15.8638 15.2298 16.6701 --15.6635 16.2157 16.6935 --15.3727 17.0416 16.2747 --15.0865 17.5259 15.4751 --15.7871 18.2198 15.3505 --15.3271 19.1155 15.3146 --16.2434 19.2611 14.9797 --16.7097 18.9534 15.7695 --17.5659 18.5002 15.8649 --17.5395 19.487 15.7356 --17.6871 20.1054 16.5296 --17.6724 19.2189 16.9308 --17.5602 18.4719 17.5933 --17.7957 18.4445 18.5929 --18.305 17.6112 18.6374 --18.1872 16.673 18.8222 --18.2193 16.4391 17.8813 --18.9028 17.16 17.8339 --19.2283 16.7168 16.9826 --18.9506 15.9568 16.4447 --18.5746 15.1322 16.2332 --18.8276 14.8532 17.1804 --18.7575 15.0307 18.1254 --17.8326 15.14 18.3704 --16.9473 14.6204 18.1047 --16.2059 14.884 18.6507 --16.2432 14.5058 19.5919 --15.6099 13.9464 18.9756 --14.6 13.8912 18.9512 --13.9923 13.0595 18.8172 --13.5292 13.425 19.5613 --13.993 13.1978 20.3636 --14.6867 12.6162 20.7416 --15.6073 12.3189 20.9675 --15.0435 11.5698 21.0191 --15.9571 11.3637 21.1133 --15.4662 10.5029 21.4542 --15.9484 10.3951 20.5226 --16.3642 10.0661 21.358 --16.1419 10.185 22.3113 --16.0294 11.1358 22.6692 --16.9598 10.8475 22.5855 --16.6693 11.3827 23.3619 --16.4477 10.7754 24.1139 --17.1124 10.8549 24.7868 --17.7863 11.1782 24.0938 --18.7602 10.816 23.9367 --18.5658 10.0266 23.3521 --19.1886 9.47953 23.9322 --19.8598 10.1438 23.6414 --19.5933 10.6886 22.8562 --19.6146 10.1273 22.0806 --18.706 10.3396 21.7782 --18.6018 10.0445 20.8997 --18.9033 9.17041 20.6803 --18.1376 8.5393 20.4996 --18.9054 8.00844 20.1879 --18.1587 7.74695 19.532 --17.1859 7.75635 19.8588 --17.1805 7.76995 18.8747 --17.1921 7.58457 17.9073 --16.9178 8.50808 18.1169 --17.1231 9.06721 18.8469 --18.0986 9.21289 18.5359 --18.7347 9.6992 18.0076 --19.1564 10.2727 18.8313 --18.7465 10.9604 18.2588 --18.8217 11.7192 18.9407 --18.8928 11.5145 19.9152 --18.4903 12.2012 20.4674 --17.6254 12.7732 20.6308 --17.4326 13.5587 20.1046 --16.4533 13.6925 20.2607 --16.4676 13.3188 21.1241 --16.5107 13.8741 21.9462 --15.6627 14.4111 21.752 --14.8775 13.7723 21.4931 --14.2863 14.3221 20.7981 --13.3127 14.178 20.7393 --13.3767 15.1493 20.3617 --12.5997 15.7726 20.2586 --12.155 16.693 20.3165 --11.8306 17.6467 20.4318 --11.8732 18.5882 20.6413 --12.7358 18.2127 20.7232 --13.1773 17.3858 20.2496 --13.9549 17.0154 19.7743 --13.8654 17.8525 19.2735 --14.0577 17.6219 18.3307 --13.7845 17.4361 17.3413 --14.3983 18.2368 17.258 --15.1951 18.3822 16.6477 --16.0136 17.9061 16.7761 --16.6729 17.2911 16.4149 --17.5746 17.208 15.93 --18.4328 17.4644 15.4581 --18.3357 16.7684 14.7144 --18.045 17.6165 14.1574 --18.1341 18.3125 13.4303 --18.3734 17.6653 12.6935 --17.6663 17.8491 11.9878 --16.8991 17.2766 11.6611 --17.4872 16.7457 11.0615 --17.1805 17.0327 10.1114 --17.7324 17.8299 10.3488 --18.6746 18.0004 10.3405 --19.0055 18.5259 9.58436 --18.5974 19.4175 9.55676 --18.7359 20.4072 9.37613 --19.0353 21.2985 9.78009 --18.3791 21.2753 10.5014 --18.5936 22.0402 11.1632 --18.917 22.9438 11.4671 --18.1151 22.4043 11.9458 --17.6567 22.4105 12.7858 --17.1338 23.2648 12.6985 --16.8677 23.311 13.6922 --16.3439 22.8639 14.5396 --16.171 21.8763 14.4748 --16.2591 22.3087 13.5273 --15.632 22.5935 12.8258 --15.4894 23.4592 13.1395 --15.3173 22.6868 13.778 --14.7481 22.7939 14.5766 --14.9006 22.827 15.5538 --14.8145 23.835 15.3272 --14.0736 24.1743 15.953 --13.9518 25.1392 15.7091 --13.2104 25.7307 16.1456 --12.4487 26.1901 16.4891 --11.9071 25.5218 16.0092 --11.4205 25.4112 16.9006 --11.9475 25.8285 17.6469 --11.277 26.5033 17.9087 --10.7053 27.3219 17.8562 --9.76829 27.2794 18.1556 --10.3519 26.9594 18.9083 --9.94576 26.261 18.4027 --9.38996 25.6628 19.0171 --9.28986 24.8435 19.6535 --8.55894 24.1343 19.5846 --8.27845 23.5274 20.2925 --9.25769 23.3377 20.5657 --10.202 23.2442 21.0384 --11.1574 23.3491 20.7525 --12.1588 23.3874 20.9074 --12.4513 22.6004 21.3801 --12.9049 22.4265 20.5409 --13.6599 22.6359 19.959 --13.9145 23.0959 20.8372 --14.7721 22.6526 20.8068 --14.9544 22.2173 19.9097 --14.7328 22.6622 19.0809 --14.9607 23.3032 18.2774 --14.5427 22.6814 17.6736 --15.4136 22.7159 17.2668 --16.4153 22.7397 17.1208 --16.5893 22.4149 18.1155 --15.9289 22.7518 18.7312 --15.9244 21.7882 18.958 --15.5509 21.1278 18.217 --14.7189 20.9664 17.5766 --14.6613 21.0822 18.5472 --15.0285 20.2393 19.0311 --15.3518 19.3254 18.6501 --15.9325 18.7599 19.2964 --15.7713 18.2651 18.4171 --15.6912 17.6564 19.1452 --15.2923 16.7898 19.2253 --15.4367 16.6545 20.151 --15.9839 15.9609 20.6077 --16.6227 16.7121 20.7775 --17.4859 17.1689 20.5891 --18.4602 16.743 20.7645 --18.3479 16.8156 21.7094 --19.0509 17.5038 21.5016 --19.7257 16.977 22.1125 --19.7439 16.8085 23.1147 --20.6924 16.5805 23.3813 --21.4412 16.4257 22.8399 --20.7082 15.7547 22.641 --20.6844 14.829 22.283 --19.9474 14.961 22.9103 --19.7388 14.0187 22.9859 --19.8466 13.1608 22.4646 --19.4046 13.1681 23.4718 --19.1536 13.9338 23.962 --18.5485 13.2238 24.0471 --18.0648 13.8546 23.4377 --17.5799 14.5686 22.9081 --17.6619 14.8168 23.8613 --18.2578 15.4619 24.2781 --17.9582 16.4469 24.109 --17.6755 16.9236 24.8957 --18.5215 16.9373 25.4714 --19.4183 17.338 25.1469 --18.8808 17.9821 25.637 --18.6362 18.6545 24.9821 --19.5073 18.3459 24.7167 --20.1164 18.8315 23.9816 --19.4923 18.3585 23.3881 --18.8849 17.6557 22.9788 --18.2202 17.8708 22.2271 --17.5589 17.1464 22.1975 --17.2932 17.5585 23.0651 --16.5432 17.7389 22.3837 --15.7144 17.9381 22.9173 --16.3513 17.6815 23.6964 --16.0213 16.7027 23.7297 --15.2124 16.1975 23.5581 --15.2011 15.7188 22.7401 --14.8047 14.8412 22.9806 --14.1778 14.1342 23.2934 --13.1686 14.0071 23.3134 --12.6884 13.2599 23.8103 --13.2402 13.1828 24.7196 --12.9157 12.7744 25.5448 --12.1142 12.5019 26.0817 --12.4625 11.8811 26.7922 --13.317 12.4758 26.6899 --13.7725 11.7677 27.2093 --13.4431 11.0788 26.6688 --13.0654 10.2098 26.3977 --12.7548 10.4749 25.5205 --12.8074 11.4701 25.6319 --13.1337 11.6686 24.729 --12.5095 11.0255 24.1895 --11.5039 10.9275 24.3846 --10.7034 11.2197 24.9484 --10.4626 10.3553 25.4186 --9.9755 10.3003 24.5521 --9.91432 9.29653 24.4089 --10.857 8.89677 24.5524 --11.3036 9.26059 23.7477 --11.8072 9.51852 22.9215 --11.7967 8.56454 23.2307 --11.3209 7.79167 22.9254 --10.7523 7.40492 22.248 --11.5007 6.99869 21.7899 --12.0769 7.31457 20.9871 --11.5715 7.9607 20.44 --11.4073 8.98442 20.5984 --11.3918 9.94881 20.897 --12.2319 10.4451 21.1892 --13.0199 11.055 20.982 --13.3564 11.2534 19.9807 --13.7865 10.5222 19.5117 --13.4502 10.5107 18.5976 --13.043 10.4438 17.749 --12.2273 10.0108 17.4723 --12.5577 9.08826 17.5507 --11.6459 8.66923 17.4206 --11.6707 9.36542 18.1345 --11.117 10.0741 18.4398 --10.8395 9.95574 19.3871 --9.90197 9.49041 19.2377 --9.11125 9.28621 19.9098 --8.4818 9.57175 19.2234 --8.42459 10.3954 18.6877 --8.57474 11.3183 19.1904 --8.74988 12.2759 19.056 --9.40394 12.3205 19.7482 --10.4485 12.3756 19.5622 --10.7964 12.7804 20.4525 --10.5762 12.0403 21.0676 --10.3543 11.1889 20.529 --9.38529 11.3239 20.5157 --8.46428 10.9455 20.5807 --7.50961 11.1828 20.2997 --6.83598 11.6451 20.7898 --6.79848 12.1087 19.9114 --7.01947 12.3553 18.8988 --6.57618 12.6541 18.0601 --6.68889 11.9181 17.3753 --6.43095 12.5005 16.6678 --6.09319 11.6329 16.3833 --5.70758 11.1032 15.6192 --5.4642 10.1379 15.5568 --5.73957 10.029 14.6754 --5.83837 10.6101 13.8236 --6.0324 9.76151 13.3437 --6.5066 8.92616 13.7816 --6.12758 8.49811 12.9124 --5.58692 7.70963 12.5082 --5.65621 7.29758 13.4577 --6.23639 6.82122 12.8195 --6.52923 6.18239 13.4826 --7.12281 6.47546 14.2025 --7.51973 6.02518 13.4423 --7.62218 5.09288 13.2347 --7.0392 4.28759 13.3086 --6.41266 3.61001 12.9435 --6.82261 4.09686 12.1687 --7.80549 4.20824 11.9885 --8.30621 3.41747 12.1095 --9.2627 3.54989 12.316 --10.023 4.08509 12.4124 --9.72938 3.90804 13.3742 --10.0912 2.96597 13.2832 --9.15341 2.98966 13.5886 --8.59627 2.24224 13.5587 --7.60002 2.23444 13.4752 --6.63667 2.17544 13.41 --6.98481 1.4074 13.9763 --6.9083 0.5065679 13.4237 --6.9112 0.9622379 12.596 --7.53448 0.7725789 11.9144 --7.60953 1.6602 11.4576 --8.36788 1.93418 12.1355 --9.34165 1.94978 12.4718 --10.1182 1.22617 12.4151 --9.66928 0.3470699 12.4145 --10.0608 -0.3770331 13.0348 --10.8053 0.04534363 13.5136 --10.9185 -0.2201981 14.4826 --10.0884 -0.8247281 14.357 --9.89581 -1.72135 13.9119 --10.3052 -2.20956 14.6204 --9.43827 -1.7697 14.6702 --9.29361 -2.75503 14.7466 --8.7679 -2.93523 13.9322 --8.77967 -1.97943 13.6263 --8.00721 -1.71124 14.2108 --7.20527 -2.39233 14.3776 --6.28708 -2.46018 14.7517 --5.50978 -2.99763 15.0035 --4.87456 -3.32088 15.7476 --5.09218 -2.82564 16.6017 --5.67044 -3.31431 17.1573 --4.84077 -3.5213 17.587 --4.12491 -2.92833 17.0893 --3.70147 -2.38648 17.8064 --4.15076 -2.14764 18.6848 --5.00106 -2.15323 19.223 --5.76624 -1.47259 19.4341 --6.11242 -1.90146 18.5689 --6.56273 -2.51765 19.1764 --7.39541 -3.01351 19.5393 --8.09007 -2.91378 20.1831 --8.2729 -3.61092 20.8907 --8.15377 -4.62146 20.8853 --7.568 -4.93991 21.6478 --6.63677 -4.55956 21.5797 --5.85004 -3.95808 21.6858 --6.18667 -3.33517 20.9813 --6.18737 -3.78658 20.091 --5.53664 -3.81778 19.2804 --4.74382 -3.39137 19.5492 --4.48988 -4.11556 20.1403 --3.96259 -3.8037 20.977 --4.41188 -4.54418 21.4637 --4.04224 -5.35216 21.9567 --4.40963 -5.44066 22.9089 --5.38588 -5.64926 23.2517 --6.13691 -6.27672 23.4865 --5.57736 -7.13338 23.6287 --5.26086 -7.74733 24.3534 --4.76193 -8.5053 23.9714 --5.01191 -9.00159 23.1045 --5.48674 -9.15889 23.9406 --5.71304 -10.015 24.4442 --5.4502 -11.0022 24.3822 --6.33849 -11.3386 23.9728 --7.02374 -10.8667 23.4476 --7.53232 -11.2014 24.1847 --7.49145 -10.6107 25.0168 --6.9053 -11.4621 25.2611 --6.38879 -12.1357 25.8535 --6.36445 -11.198 26.0922 --5.92291 -10.3555 25.8464 --5.17424 -10.0078 26.3332 --4.17552 -10.1896 26.3951 --4.27346 -11.1812 26.4777 --4.42498 -11.7999 27.2648 --4.90142 -10.9772 27.4722 --5.30733 -11.2148 28.3398 --6.20028 -10.7248 28.3176 --6.33272 -10.5286 29.3213 --6.43742 -9.55612 29.1571 --7.29997 -9.20025 29.2828 --7.58897 -9.9788 29.8861 --6.93379 -10.0995 30.58 --6.14338 -9.92119 31.1486 --6.1572 -10.7217 31.7428 --5.82427 -11.5901 31.4013 --5.30131 -11.6555 30.5361 --4.93664 -10.7189 30.6573 --4.19201 -11.3324 30.9709 --3.68283 -10.5157 31.2255 --3.73708 -9.71466 30.5821 --4.44 -9.83453 31.3634 --3.94838 -9.294 32.0201 --3.18098 -9.11628 31.345 --2.39008 -8.55957 31.2029 --2.05082 -8.53588 32.1061 --2.26029 -8.27083 33.0851 --2.07005 -7.81418 33.9578 --2.96949 -8.29667 34.1874 --2.87032 -9.29739 34.5377 --3.18066 -8.5738 35.1983 --3.65129 -7.86996 35.7071 --4.32729 -7.48876 35.096 --5.23578 -7.74284 34.741 --5.35578 -6.726 34.8471 --6.05153 -6.76102 35.5926 --6.54671 -5.89182 35.2567 --6.68215 -5.98972 34.2487 --6.52886 -5.29829 33.5225 --6.88663 -4.53885 33.0493 --7.16786 -5.23523 32.4089 --8.06323 -5.48035 31.9662 --8.29513 -6.48819 31.8019 --8.82276 -6.89359 31.0891 --9.27165 -6.00209 30.9584 --9.80357 -5.40461 31.6331 --10.405 -5.39372 32.4776 --11.415 -5.11379 32.3357 --11.1509 -5.96425 32.7861 --11.5918 -6.63834 33.4712 --12.4635 -6.42018 33.8848 --13.1562 -6.45987 33.2074 --14.0476 -6.77484 32.8405 --14.3378 -7.0149 31.9364 --14.5929 -6.07239 31.7581 --15.4385 -6.07943 31.1631 --14.6744 -5.57146 30.7134 --15.2822 -4.82025 30.9771 --14.7682 -4.04592 31.1709 --15.084 -3.21782 30.6917 --14.112 -3.10347 30.7817 --13.9216 -3.18426 29.8556 --13.1466 -2.87235 29.3618 --12.5682 -2.92074 28.6379 --12.5167 -2.33895 27.8458 --11.7169 -2.29985 27.2916 --12.0668 -1.42706 27.0851 --11.1609 -1.30288 26.6055 --10.5427 -1.99737 26.7869 --9.74331 -2.47059 27.1014 --9.41825 -3.032 26.2967 --9.80622 -2.55707 25.5282 --9.44122 -1.90508 24.8764 --8.83089 -1.39274 25.4942 --8.6453 -0.8265411 26.2531 --9.56127 -1.1234 26.155 --9.71968 -0.2689041 26.6388 --8.83494 -0.1100241 27.0623 --8.1758 -0.8948181 27.1743 --7.27594 -0.7465051 27.6738 --6.7384 -1.54388 27.2822 --5.96771 -0.9817801 27.0766 --5.40222 -0.5206561 26.3983 --4.97203 -0.09070167 27.2626 --4.24461 0.4979579 26.7936 --3.38887 0.04514773 26.6222 --2.9279 0.9747779 26.6634 --3.2322 1.92719 26.5999 --3.84125 2.3788 27.2713 --3.39326 3.28384 27.4414 --4.11535 3.67397 27.983 --4.75974 4.08214 28.5839 --5.08527 4.21383 27.6826 --5.8542 4.41118 26.9439 --6.01378 3.82445 27.7835 --5.67777 2.99541 27.7152 --5.52844 2.80348 28.68 --5.03618 3.08359 29.472 --4.3058 2.43601 29.6745 --4.42237 1.52481 29.2594 --5.11775 1.03787 28.7661 --5.88508 1.18043 29.402 --6.06451 1.42617 30.3362 --6.70212 1.76528 29.6544 --6.24947 2.67021 29.7726 --6.03974 3.49465 30.1951 --6.7946 4.07921 29.7849 --6.05298 4.8147 29.7259 --5.20269 5.12236 29.349 --5.21677 5.85871 29.9603 --5.41315 6.78781 29.8875 --4.79568 6.81262 29.0268 --3.99514 6.66947 28.3858 --3.03944 6.46079 28.3659 --2.73542 7.34365 27.9838 --1.75812 7.2557 28.2258 --2.25347 7.04342 29.0599 --1.61236 6.25496 28.986 --1.02287 6.91168 29.4939 --0.451451 7.1928 28.7106 -0.365517 7.16305 29.3096 -0.730573 6.38164 29.7813 -0.227381 5.60288 30.2386 -1.17522 5.2819 30.0144 -0.527798 4.85559 29.3264 -1.30285 4.54081 28.7769 -1.77442 5.03089 28.0603 -2.00437 4.99447 27.117 -2.53116 4.7549 26.2939 -3.29996 4.29444 26.6396 -3.29535 3.46968 26.056 -3.30932 3.2663 25.0624 -3.16526 2.49723 24.4967 -3.78679 2.08986 25.2208 -3.4458 1.47527 24.4779 -2.48671 1.31702 24.7223 -1.95008 2.09493 24.3169 -1.35608 2.75267 23.8601 -2.0616 2.64606 23.1265 -2.00713 1.63868 23.3914 -2.00937 1.14744 22.5003 -2.59985 0.6195839 21.9239 -1.80939 0.8462109 21.3958 -1.85162 -0.1277821 21.6161 -1.02254 -0.7200291 21.9197 -0.690945 -0.7312221 22.9215 -0.403874 -0.8673551 23.8584 -0.434681 -1.50882 24.6346 --0.274303 -1.89818 25.2585 --0.639269 -2.74045 25.6398 --0.04237533 -3.49552 25.4272 -0.514925 -4.27574 24.9553 -1.15316 -3.50431 24.9077 -1.60065 -2.75995 25.3418 -1.99883 -2.9098 24.4127 -2.05443 -3.16592 23.4693 -1.33345 -3.77129 23.6844 -1.29112 -4.43999 22.9496 -0.322235 -4.35958 22.7196 -0.105746 -3.45459 23.1529 --0.362931 -2.87389 23.7947 -0.146905 -2.02739 23.5413 -0.44663 -2.24749 22.6242 --0.526826 -2.14007 22.4105 --0.622878 -3.00554 21.9627 --1.08994 -3.85938 21.9486 --1.12968 -4.37923 21.1123 --1.01048 -5.38815 21.1541 --1.76751 -5.03038 20.6074 --1.94746 -5.96863 20.2533 --2.26909 -6.36072 19.3439 --2.0392 -7.05389 18.658 --2.28634 -7.32747 19.5801 --1.62751 -7.22985 20.2615 --1.09849 -7.78448 20.9566 --0.218492 -7.36891 20.9073 --0.419421 -6.39214 20.514 -0.304016 -6.48977 21.2594 --0.28069 -6.40402 22.0212 --0.210638 -5.9323 22.9262 --0.716771 -5.1326 22.6556 --1.68668 -5.40062 22.5905 --2.61417 -5.76572 22.6832 --2.14844 -6.67534 22.4849 --1.75015 -6.63236 23.3474 --2.49746 -6.51173 24.0638 --3.3793 -6.60586 24.5469 --4.36157 -6.31374 24.9615 --4.47375 -5.64805 25.6552 --3.69084 -5.24956 26.2145 --3.89047 -4.7364 27.1186 --4.37352 -4.23448 27.8074 --4.29441 -5.18286 28.1244 --5.17571 -4.87955 28.1981 --4.7282 -4.52529 29.0677 --5.72619 -4.5132 29.0892 --5.54859 -5.22415 29.7358 --4.82587 -4.74857 30.2636 --5.42183 -5.28575 30.8639 --5.76328 -6.18681 31.2043 --5.75381 -7.1412 31.5102 --5.66724 -8.12792 31.6831 --4.91815 -7.36239 31.8159 --4.1578 -6.84564 32.1882 --3.47264 -6.3744 31.6824 --2.87729 -5.71147 31.2161 --2.12123 -6.21802 30.8012 --1.49863 -6.99656 30.7192 --0.845301 -7.36273 29.9408 --0.497765 -8.08031 30.5426 --0.524816 -8.764 31.3038 -0.208163 -9.21771 31.8504 -1.01749 -8.8485 31.4359 -1.17272 -7.85719 31.4748 -1.93303 -7.613 32.1547 -2.86436 -7.56703 32.507 -2.51494 -6.87016 33.0712 -2.85106 -6.25975 33.8482 -2.30752 -6.41459 34.6217 -1.51016 -5.96997 34.3861 -1.43944 -5.28215 35.0192 -2.33784 -5.01546 34.5743 -2.33009 -4.74999 33.6209 -2.73395 -5.14368 32.8468 -2.63126 -5.17544 31.8521 -2.88054 -4.79449 31.0063 -1.8996 -5.00915 30.982 -1.25565 -4.33824 30.5591 -0.58151 -3.69609 30.2306 --0.362328 -3.85429 30.4364 --0.35023 -4.60746 31.1467 -0.330081 -5.18736 30.6682 --0.18175 -5.73773 30.0651 -0.185889 -6.67063 29.8782 -0.811363 -7.14157 29.2376 -1.12166 -6.41543 29.9564 -1.40391 -5.9569 29.1649 -1.46552 -5.33913 28.3903 -2.32138 -5.27667 27.8152 -3.01919 -5.02694 28.4559 -3.4678 -5.92059 28.1798 -3.90833 -5.59594 28.975 -4.82014 -5.35005 29.3698 -4.93707 -4.75136 30.215 -4.41362 -4.10462 30.7744 -4.27884 -4.19642 31.7609 -3.56153 -3.59741 31.8484 -3.7201 -2.60856 32.1932 -4.04701 -1.94419 31.4713 -3.37178 -1.30375 31.511 -3.57398 -0.2698791 31.5979 -3.56605 -0.4208131 30.5606 -4.31313 0.01836233 31.008 -4.83208 0.7215209 30.5145 -5.34699 1.5726 30.4245 -4.85389 2.24517 29.9415 -4.52996 3.18367 29.7697 -4.32128 2.72043 30.6236 -3.51084 2.38909 31.0544 -2.75497 2.84588 31.5962 -1.90812 3.47994 31.7825 -0.929293 3.38519 31.7505 -0.196676 3.09466 32.3419 --0.316065 2.3669 31.8835 -0.200461 1.5933 31.7226 --0.608195 1.03412 31.6335 --0.395155 0.8490619 30.6816 --0.949291 1.29104 29.9099 --1.30035 2.05812 29.3079 --1.95375 1.93891 28.5546 --1.24183 2.22192 27.9019 --1.07515 3.01533 27.2496 --1.07866 3.57916 28.0733 --0.964031 3.73296 29.0427 --0.337105 3.35158 29.6822 -0.271269 3.51284 29.018 -0.736709 2.74606 28.4829 -0.446781 1.99857 27.8718 -0.108797 1.89724 26.9177 -0.777923 1.21703 26.7383 -0.924952 1.71474 25.8795 -0.618567 1.14264 25.0979 -0.378764 0.7466329 24.1631 -0.93713 1.23846 23.4462 -0.855474 1.63827 22.4858 -0.009510075 1.86773 21.9857 --0.710412 1.28226 22.3759 --0.276635 0.9320909 21.4944 --1.20145 0.7377259 21.1138 --1.83873 0.5309719 21.8034 --2.32477 1.28549 22.1568 --2.27728 0.9553069 23.1345 --3.26512 1.22654 23.3708 --3.03484 2.09794 23.8566 --3.60286 2.89649 23.6691 --3.33235 2.93765 24.6656 --3.41956 3.95703 24.7783 --4.40116 3.79314 24.9308 --5.37141 3.73399 24.9075 --5.89451 3.82524 24.0423 --6.48751 3.02895 24.2291 --7.38622 2.73971 24.2945 --8.15523 2.51628 23.7183 --8.74059 2.72597 24.4821 --8.28493 1.90851 24.9018 --8.08307 1.97452 25.9377 --8.18537 1.78968 26.8694 --7.93235 2.06713 27.8024 --6.94646 2.11559 27.3285 --6.75307 2.72775 26.6202 --5.91853 2.25696 26.6893 --6.51786 1.55874 26.2707 --5.97372 1.83486 25.4904 --6.14115 1.52343 24.5476 --6.2118 0.8391489 23.8398 --5.47006 1.14165 23.3156 --5.95577 1.1052 22.4598 --5.17949 1.36423 21.9619 --4.46204 0.9758969 22.5612 --3.79432 1.67466 22.464 --3.72159 2.50009 21.9158 --4.49495 3.10369 21.9539 --5.3014 3.28906 22.5334 --5.0138 4.19 22.7672 --5.45061 4.916 22.2848 --5.48488 5.16796 21.2641 --5.94861 5.2914 20.3308 --5.62445 5.36652 19.3903 --5.22768 6.29182 19.1841 --6.14341 6.26712 18.8145 --5.61719 6.39452 17.9652 --6.10534 5.55273 17.8517 --6.98833 5.62487 17.5105 --7.34195 4.86915 16.8934 --6.48641 4.60352 17.3568 --5.51965 4.48477 17.8496 --4.6781 4.1692 17.2818 --4.99704 4.98921 16.8027 --4.66352 4.23928 16.2949 --4.7597 3.24288 16.4605 --5.02135 3.37023 15.5684 --5.9268 3.40904 15.8462 --5.93066 2.69033 15.1967 --6.46015 1.89183 15.4298 --5.97087 1.25547 16.0639 --5.48825 0.9569169 15.2301 --5.01502 0.6202689 16.016 --5.40873 -0.2522141 16.1655 --5.84557 -0.001250536 17.073 --5.66956 -0.7742791 17.6143 --4.73681 -0.6064961 17.6853 --3.94726 -0.1405641 17.3354 --3.42055 0.3823579 17.9432 --2.43536 0.6982449 18.1111 --1.67294 1.06096 17.5337 --1.92632 1.94263 17.3153 --1.66695 2.4393 16.5278 --2.33579 2.66821 15.8142 --2.26839 3.23438 15.0128 --1.72216 2.55147 14.455 --0.792499 2.39492 13.963 --1.01595 1.47049 13.6366 --0.435737 1.55502 14.4676 -0.281482 2.09536 14.0451 -0.452657 3.02221 13.9832 --0.03647023 3.9488 13.9494 -0.295026 4.51042 14.6784 -0.39807 5.24785 15.291 -1.1862 5.4817 15.9281 -1.30632 6.31889 15.4169 -0.956525 7.22962 15.7198 -0.717265 8.17721 15.9127 -1.48833 8.58118 15.4004 -1.35629 9.61416 15.1757 -0.756229 9.41195 14.4451 -0.233297 8.55392 14.4531 --0.657418 8.36828 14.8184 --1.27213 7.79572 15.3577 --1.56239 6.88016 15.6475 --1.69537 7.17001 16.7054 --1.16217 7.32904 17.5741 --0.519996 6.93806 18.21 -0.001502085 6.94523 19.0375 -0.319531 7.63463 18.4952 -1.08252 7.9272 17.9665 -1.92018 8.48213 17.906 -2.37683 9.36327 17.5847 -3.01797 9.26593 16.8635 -3.05938 9.92907 16.1827 -2.71254 10.8397 15.9111 -1.95224 11.2068 15.419 -1.39757 11.897 15.9257 -0.440535 11.5693 16.0728 --0.431982 11.1584 16.2884 --0.823348 11.7711 16.9477 --1.79572 12.0241 17.0228 --2.44767 11.2706 17.0925 --3.27913 11.5439 17.435 --3.98258 11.1465 16.9052 --4.52637 11.0621 16.0153 --3.96333 11.8639 16.1102 --3.31606 11.4527 15.4064 --3.3598 10.5127 15.1708 --3.07717 9.90199 15.9513 --2.84445 9.41486 15.0957 --1.90804 9.55034 15.0367 --1.95755 9.40783 15.9949 --2.3107 9.64181 16.9336 --1.91241 8.88985 17.5614 --2.3557 7.99968 17.3585 --3.29489 7.82852 17.2924 --4.35085 7.64661 17.2769 --4.52483 8.59425 17.5392 --5.52312 8.61525 17.4682 --6.43929 8.67011 17.9125 --6.62915 8.44699 16.9832 --7.48997 8.93207 17.1254 --8.35121 8.67164 17.4766 --8.73507 7.79997 17.9218 --9.17031 6.96659 18.1828 --9.46145 6.55346 19.0879 --9.99601 6.35177 18.1984 --10.8072 6.10779 17.6038 --10.1708 5.88915 16.8632 --9.32302 5.5957 17.2592 --9.79567 4.85061 17.7652 --9.84323 3.97941 18.1793 --10.3379 3.77281 17.3482 --11.0041 3.11954 17.6233 --11.1846 2.34166 18.2699 --11.3077 2.15845 17.3224 --11.2598 1.68814 16.4474 --10.3608 1.68617 16.956 --10.4009 0.8290709 16.3585 --9.97106 0.4625279 17.1954 --9.72376 0.7649709 18.1487 --9.42196 -0.1227481 17.9359 --9.93362 -1.03028 17.7878 --10.7726 -1.39647 17.2498 --10.1325 -2.14979 16.8517 --10.2503 -3.10051 17.2427 --9.77458 -3.39673 16.3668 --9.07681 -3.00125 15.836 --8.68544 -2.13801 15.6461 --8.46047 -1.29713 15.1198 --7.52676 -0.9147031 15.25 --7.78187 -0.5061731 16.174 --7.61409 -1.22045 16.7775 --8.47026 -1.64882 17.1196 --8.23695 -1.10643 18.0179 --8.87871 -1.79948 18.3726 --9.47966 -2.27646 19.0046 --10.3828 -1.99695 19.4502 --11.3457 -2.32622 19.2508 --11.4249 -1.91662 18.3106 --11.4643 -1.27815 19.057 --12.145 -1.05747 18.3592 --12.3441 -1.8133 18.9196 --12.3564 -2.67689 18.5365 --11.7751 -2.94705 17.7541 --12.7356 -2.60118 17.5336 --12.8955 -2.83162 16.6069 --13.8152 -3.11445 16.8873 --13.2377 -3.9447 16.8912 --13.2704 -4.63087 16.1736 --12.5908 -4.6114 15.4655 --12.364 -4.00137 16.2124 --11.5665 -3.33246 16.1004 --11.1276 -2.91386 15.3262 --12.1046 -2.70158 15.325 --12.3588 -2.89598 14.3428 --12.7441 -3.7051 14.7497 --13.3798 -3.46943 15.4666 --14.2902 -3.85219 15.8335 --15.2945 -3.54731 15.9353 --14.6511 -3.02693 15.3534 --15.2812 -2.305 15.1662 --14.9897 -1.71937 15.9627 --15.9162 -1.74234 15.9776 --16.1593 -0.9150431 15.5164 --16.7863 -1.09016 14.795 --16.9673 -1.87161 14.142 --16.8965 -2.2246 14.9936 --17.6086 -2.91009 14.8043 --17.4582 -3.91199 14.4678 --17.5109 -4.5784 15.2454 --17.3387 -3.67502 15.6705 --17.5511 -3.53909 16.6148 --17.0708 -3.19278 17.4277 --16.7491 -2.56466 18.1019 --16.2673 -1.65735 17.9786 --15.7559 -0.7729371 18.3099 --15.5531 -1.02127 17.3238 --14.9254 -1.44104 17.8584 --14.8566 -2.31879 17.3559 --15.2033 -2.51268 18.296 --14.5085 -2.28098 18.9709 --14.2126 -1.6524 19.6825 --13.8885 -0.8455291 20.2602 --14.0771 0.1001789 20.3876 --14.132 1.08998 20.3361 --14.0657 1.67083 19.5364 --13.561 0.9319009 19.2784 --12.6583 1.18574 18.7263 --12.376 1.57846 19.6251 --12.3124 1.4091 20.6053 --12.2302 0.4217849 20.6174 --12.1371 -0.6572291 20.5515 --11.1698 -0.3581631 20.7003 --10.8272 0.5140509 21.0789 --10.979 1.45377 20.7236 --11.172 2.23599 21.2647 --10.7487 1.78645 22.0483 --10.0083 1.80938 22.7537 --9.81458 1.3421 23.6951 --10.1977 2.0792 24.1954 --11.0591 1.94857 23.6274 --11.946 2.1409 23.8964 --12.8461 1.86973 24.2515 --13.5169 1.02771 24.2243 --13.6795 0.6323989 25.19 --14.5057 1.03741 24.7954 --14.464 1.45838 25.7284 --14.3281 0.8274849 26.5187 --15.2384 1.29468 26.4223 --15.9738 1.91644 26.6419 --16.6474 2.43745 26.1147 --16.4351 3.35893 26.251 --17.1533 3.69354 26.7755 --17.0724 4.67839 26.6334 --16.6069 5.46636 26.807 --15.6239 5.66349 26.9223 --14.7689 5.31954 27.0369 --15.3619 4.64461 27.3967 --14.8233 3.97708 27.823 --14.4789 3.07267 27.7415 --14.0386 3.29948 28.5975 --13.0364 3.38173 28.3586 --12.2707 3.88933 27.8666 --11.9399 4.05107 28.812 --12.5444 4.89123 28.7826 --12.1118 5.57835 29.3341 --11.3539 6.31362 29.3602 --11.2644 6.38652 30.3147 --10.4343 6.39975 29.8653 --10.8 7.30987 30.1272 --10.3176 8.0031 29.5132 --9.83753 8.90007 29.3571 --9.66591 9.70606 28.7058 --8.80694 9.96169 29.1745 --8.72459 10.9123 29.6128 --7.95256 11.4525 29.3908 --7.46787 10.582 29.3119 --7.1167 9.59736 29.1131 --6.38114 10.1605 29.3588 --6.11763 10.2431 28.4125 --5.10435 10.0179 28.2777 --4.6689 10.9536 28.3371 --4.04731 10.2733 27.929 --3.56455 9.77776 27.3134 --4.25147 9.49787 26.5559 --3.41422 9.30634 25.9967 --3.11605 8.40876 25.9881 --2.75844 8.61951 25.0464 --2.77269 7.57708 25.3082 --3.33558 6.76937 25.2797 --3.27294 6.35714 26.1728 --3.49942 5.45805 25.7926 --3.70976 5.52042 24.7639 --3.95999 5.19512 23.8186 --3.76067 4.89075 22.86 --3.18962 5.60944 22.51 --3.36531 6.29943 21.8091 --4.20933 6.31208 21.3261 --3.76648 7.15583 21.6139 --4.23427 6.9834 22.5762 --5.15967 7.42483 22.5685 --5.45973 7.69452 23.4668 --6.18652 7.08279 23.7398 --6.14138 7.36286 24.6649 --6.86478 6.75831 25.0105 --6.43099 5.86369 24.9167 --6.15543 5.16122 24.2012 --6.78254 5.01731 23.3778 --7.29719 4.44378 22.7711 --7.47646 5.22517 22.1777 --7.97357 5.7412 22.9103 --8.48787 5.06287 22.4028 --8.49454 4.26179 21.7851 --8.14959 4.7407 20.9451 --8.62406 4.04348 20.312 --9.33584 4.74227 20.2345 --9.85887 4.74565 21.0707 --10.6094 4.20086 21.2982 --10.4969 3.42628 20.6048 --10.1057 2.49366 20.4265 --9.37048 2.22283 21.0553 --8.83847 1.72776 20.4262 --8.6225 1.48771 21.3957 --8.06066 1.04873 20.6955 --7.13799 1.46432 20.8415 --6.47869 1.54816 21.5671 --5.73978 1.87458 21.2111 --5.06796 1.63251 20.4382 --4.22272 1.0339 20.2933 --3.5307 1.40266 20.8684 --2.71778 1.23901 20.4073 --2.96053 0.3081989 20.4421 --3.78127 -0.01714367 20.8348 --3.72428 -0.7656301 20.1231 --2.76204 -0.7804141 20.0242 --1.86907 -0.4687881 19.6155 --1.16157 0.07829463 19.0897 --0.436628 0.5155719 19.4964 -0.03167987 1.17807 18.9355 --0.129245 2.1454 19.0315 --1.15818 1.96742 19.1921 --1.1119 1.58037 20.0905 --0.263751 2.10266 20.1601 --0.443674 2.60316 21.0204 --1.10246 3.39687 20.7365 --1.56616 3.95572 21.3721 --2.43138 3.45957 21.4434 --2.63951 2.84926 22.1802 --1.67232 2.94211 22.2395 --1.23175 2.31914 22.9423 --0.898716 1.59364 23.641 --0.849194 2.43031 24.2867 --0.739508 3.29586 24.9016 --0.2869 3.80642 25.6161 -0.382319 4.43077 26.0251 --0.333737 4.99124 25.749 --1.12413 4.36119 25.9818 --0.990136 4.78225 25.0796 --1.88272 5.17638 24.8547 --2.55426 5.35055 24.1026 --2.3602 6.14073 23.5913 --2.2866 6.74255 24.3889 --1.79421 7.37781 23.8535 --2.79383 7.52572 23.85 --2.42566 7.3134 22.9673 --1.82791 8.11642 23.0738 --1.61817 8.15036 22.0384 --2.28356 7.40483 21.9268 --2.74413 8.00422 21.212 --1.82105 7.73237 20.9685 --0.857884 7.85424 21.0725 --0.452438 8.3524 20.277 --1.2691 8.80815 20.3247 --1.65149 8.17832 19.6802 --2.02312 7.85721 18.8287 --2.17635 6.85522 18.7187 --1.48834 6.97156 19.3413 --1.61762 5.96273 19.5437 --1.03759 5.47769 18.8034 --0.241701 5.62291 19.4102 --0.75936 4.82325 19.7137 --1.54036 5.05784 20.4184 --2.15771 5.81791 20.7536 --1.43818 6.51241 20.9279 --1.1543 5.63139 21.2759 --0.368647 6.11537 21.6567 -0.374717 6.69013 21.2831 -0.696121 7.41715 20.701 -1.07549 6.46229 20.4345 -1.31146 5.53953 20.0625 -0.556378 5.14609 20.4766 -0.328547 4.22771 20.7173 -0.539241 3.26422 20.7252 -0.776523 3.36445 19.7335 -1.48603 3.03193 20.432 -2.40116 2.7974 20.1711 -3.17091 2.5932 19.6627 -3.06762 2.72151 18.6879 -2.70799 3.43746 18.0576 -2.23343 4.24034 17.7069 -1.35904 4.24038 18.3211 -0.97544 4.48125 17.5101 -1.42054 3.67879 17.1654 -1.34919 2.81517 16.8282 -0.474079 2.82814 16.4032 --0.490896 3.08253 16.1635 --0.555686 2.6366 15.2565 -0.350867 2.97499 15.2968 -1.34414 3.10165 15.0029 -1.04434 2.11463 15.009 -1.75337 1.72056 15.5334 -2.18154 2.34409 16.1841 -2.70576 3.13702 16.0116 -2.91837 3.49003 16.9114 -3.68883 4.09484 16.8241 -4.61692 3.90823 16.6394 -4.33343 3.09237 17.2112 -4.53191 2.12044 17.3156 -4.39102 1.19616 17.041 -3.35443 1.36223 17.262 -2.50747 1.10441 16.8571 -1.73581 0.7118349 16.3518 -0.965049 1.31485 16.5103 -1.3411 0.9003579 17.3351 -1.27293 1.75257 17.9252 -0.739971 2.54536 17.7007 --0.258172 2.64237 17.5495 --0.350157 3.5073 18.1163 --1.32713 3.07561 18.0399 --2.24884 2.67137 18.1282 --3.06663 3.1052 18.6492 --2.92911 2.76705 19.5906 --3.12354 3.3917 20.3402 --2.70003 4.27346 20.2754 --3.33379 4.86894 20.7886 --2.56856 4.89235 21.4081 --2.15486 5.35642 22.2041 --1.41339 5.8773 22.6134 --0.43116 5.73971 22.9834 --0.129524 5.00308 22.368 --0.241375 4.29839 21.693 --0.003512875 3.43022 21.9456 -0.717606 3.14719 22.6411 -0.227399 3.72732 23.3243 -0.340758 3.64375 24.3295 -0.763954 4.28826 24.964 -1.58353 3.77099 25.2489 -2.32893 4.38341 24.9709 -1.85703 5.27578 24.9063 -1.20565 5.9386 24.5953 -1.96457 6.59727 24.4432 -2.87749 6.97947 24.6976 -2.187 7.20575 25.3032 -2.01651 7.87504 26.086 -1.23468 8.419 25.9756 -0.833214 9.03684 26.6049 -0.226623 8.24739 26.9123 -0.128653 8.50486 27.9073 -1.00834 8.63921 28.1557 -1.42311 8.83476 28.9471 -1.26653 9.85496 29.0708 -1.87353 10.5133 28.502 -1.40795 11.0028 29.1941 -0.756412 11.5488 28.7964 -0.142976 12.307 29.0997 -0.925243 12.891 28.7958 -1.25841 12.3249 27.9889 -1.42472 13.1732 27.5042 -0.617704 13.7005 27.2997 --0.270467 13.3004 27.2187 --0.757277 14.1908 27.1943 --0.56207 14.9415 27.7447 --0.240886 15.3555 26.9476 -0.229181 16.0181 26.3045 --0.532917 15.7778 25.7283 --0.959145 15.5875 24.8121 --0.615544 15.8656 23.945 -0.141355 16.0089 23.2849 -0.611625 15.2467 22.8725 -1.05582 15.4761 23.6938 -0.83154 16.1086 24.387 -1.33632 15.9539 25.2726 -1.80584 15.3969 25.9736 -2.3371 14.5656 25.7281 -2.10599 14.366 26.6934 -2.11803 13.3646 26.6438 -1.15599 13.0709 26.5428 -1.67481 12.8631 25.743 -2.5154 12.444 25.2497 -2.61927 11.493 25.4907 -2.16088 10.6256 25.1818 -1.82656 10.6273 24.3044 -2.08344 11.591 24.482 -1.23242 12.1235 24.2612 -1.40502 12.706 23.4598 -1.48481 12.7294 22.4484 -1.79703 11.9219 21.9126 -2.17305 11.4043 22.6274 -1.70389 10.5727 22.8207 -1.56933 9.66225 23.2736 -1.42951 8.77509 22.8014 -1.70107 8.78999 23.6827 -0.742673 8.63485 23.6347 --0.257419 8.61138 23.5598 --0.774801 9.50415 23.5392 --1.56579 9.98542 23.2583 --1.62114 10.9991 23.2331 --1.82707 11.331 22.2793 --1.73312 11.3004 21.2518 --0.776017 10.9841 21.0314 -0.09542387 10.8025 20.5483 -0.273923 9.79455 20.6568 --0.005826175 9.20497 19.9338 --0.835264 9.61603 19.4875 --0.703451 9.83437 18.5096 --0.387791 10.7553 18.5097 --1.05126 11.132 19.231 --0.396326 11.9487 19.1533 --0.06319823 12.9725 19.307 -0.360388 12.877 20.2414 -1.33045 12.5664 20.4017 -1.24448 13.5474 20.5848 -0.906824 13.4818 21.5328 -0.710028 14.4649 21.3322 -0.452694 14.8508 20.4626 -1.43237 15.1947 20.7094 -2.19565 15.4112 21.3972 -1.78387 16.3378 21.6194 -2.73019 16.3739 21.3692 -3.61439 15.917 21.222 -3.71144 15.3155 21.9306 -4.39425 14.9263 22.5009 -4.58766 15.6884 21.8812 -4.3378 16.7289 21.6719 -4.53804 16.6389 20.7162 -4.74376 15.6451 20.7504 -5.58622 15.2612 20.2791 -6.38089 15.4745 20.8395 -6.76335 15.2998 19.9139 -7.68337 15.7348 20.0025 -7.84459 15.6741 19.015 -8.05188 16.5339 18.5067 -7.87005 17.5245 18.6452 -7.96272 17.3367 19.6141 -8.7142 17.5652 19.0509 -8.87512 17.7599 18.0945 -9.13599 17.3845 17.1687 -8.60628 17.115 16.2897 -8.45493 18.1287 16.2216 -9.38024 18.5574 15.999 -9.8873 17.8435 16.53 -10.5558 18.4526 16.891 -10.9788 18.1191 15.9944 -10.4884 18.656 15.2742 -10.4957 18.8953 14.3092 -9.78366 19.4612 13.9734 -10.1385 19.2933 13.0079 -10.2397 19.1707 12.0179 -9.43036 19.8608 12.1311 -9.49623 20.7143 11.6048 -9.17555 20.5718 10.6449 -8.31674 21.0706 10.7115 -7.62043 20.3937 10.3181 -7.13265 20.1675 11.159 -6.27119 19.7206 11.1814 -5.58143 20.315 10.6359 -4.95111 20.3477 11.4885 -4.33249 20.5227 12.2422 -4.75272 20.8967 13.054 -4.83822 20.3194 13.8353 -4.63983 20.0021 14.7333 -5.44803 20.551 14.586 -5.83484 19.7153 15.0081 -6.17688 19.6865 15.9467 -7.14496 19.9828 15.7359 -8.17051 19.8215 15.6566 -8.37111 19.7238 14.6272 -8.78426 20.2588 13.9852 -9.0216 21.0871 14.5141 -9.14634 21.8919 13.8438 -9.85216 22.4885 13.6002 -10.5431 21.9547 13.0239 -11.2586 22.0187 12.3613 -10.448 22.6421 12.2407 -9.61113 22.9564 11.8133 -9.85765 23.8815 11.7619 -10.8456 23.5995 11.9117 -11.2111 23.3075 10.9663 -10.8479 23.7235 10.1872 -10.3052 23.5936 9.35201 -10.0347 24.5599 9.45751 -10.2488 25.3273 8.85273 -10.6829 25.6429 8.03424 -9.98082 26.0372 7.45786 -10.0444 27.0599 7.68847 -9.22008 27.3074 7.16099 -8.18262 27.413 7.12684 -7.26741 27.7889 7.25135 -7.26072 27.3574 8.20461 -6.69415 26.9008 8.8913 -7.07222 27.6872 9.34017 -6.36359 28.4273 9.3997 -5.6665 29.0602 9.14495 -5.13342 28.3867 9.63661 -4.20877 28.8443 9.71646 -4.2066 29.152 8.78141 -3.51107 29.8606 9.17189 -3.69047 30.8214 9.45793 -2.98676 31.5025 9.49575 -2.61374 31.0195 8.65157 -1.67148 31.2851 9.07 -1.45144 30.4914 8.5727 -1.9075 29.5978 8.4442 -1.82205 28.8099 7.84556 -2.41353 29.318 7.18035 -3.26713 29.8141 7.30542 -4.02738 30.4499 7.07925 -3.84851 29.9639 6.2554 -4.17281 29.1139 5.88277 -4.23296 28.6811 6.77184 -5.16005 28.1805 6.66483 -5.71884 28.8467 6.06089 -6.56009 29.1088 6.49345 -5.9674 29.8775 6.30643 -6.93372 30.3073 6.25337 -7.87293 30.4865 6.63735 -7.46155 31.199 6.11149 -6.79772 31.8972 5.97055 -6.72641 31.5436 5.09056 -7.04412 31.1131 4.29 -6.98245 31.294 3.30664 -7.86596 31.3847 3.5672 -8.43131 32.2295 3.57472 -9.23136 32.4987 3.02404 -9.10023 31.8208 2.26017 -9.27437 30.8122 2.66731 -10.0842 31.3261 2.99451 -10.8804 31.8908 2.84736 -11.0166 32.8628 2.99338 -10.8361 33.7017 2.40896 -10.7663 34.6429 2.36308 -10.8494 35.5788 2.76096 -10.486 35.264 3.61417 -9.95462 34.447 3.79743 -10.4208 33.7321 4.41909 -10.1404 33.0102 5.06734 -10.5721 33.5536 5.77781 -10.9896 32.6734 5.90381 -11.6919 33.3885 5.74387 -12.1791 32.4873 5.60959 -11.6444 32.6707 4.80301 -12.4034 32.0118 4.64617 -13.2293 31.3686 4.53846 -14.0298 31.2693 5.1431 -14.3922 32.2408 5.21706 -14.0664 31.8149 6.03783 -14.0815 32.5104 6.77022 -14.1551 31.5761 7.18846 -14.9233 31.029 7.68894 -14.6752 30.1794 7.0545 -15.074 29.8114 7.9879 -14.6787 29.1323 8.57811 -15.0969 29.733 9.22704 -15.0909 30.4303 9.92428 -15.6755 30.4683 10.6793 -14.7357 30.5975 11.1088 -14.0013 31.0192 11.6719 -13.4256 31.5027 11.0397 -13.748 32.18 10.2478 -13.2192 31.6028 9.68953 -13.0599 31.3434 8.76032 -12.2714 31.7216 8.20789 -12.5533 31.7874 7.28819 -12.9348 31.1316 6.69495 -13.1129 30.2759 6.9146 -12.2574 29.8665 6.94601 -11.3421 29.9242 6.43449 -10.8762 30.7971 6.20642 -10.4565 29.9761 5.78691 -10.4885 30.5959 5.02232 -9.72807 30.6918 5.70396 -9.41621 31.1412 6.49475 -9.61332 31.7066 7.20241 -8.81374 31.8004 7.87065 -8.83128 32.3566 8.71559 -9.47481 32.6005 9.35427 -9.67192 31.714 8.9787 -10.6834 31.8763 8.99656 -11.0793 31.0478 8.52058 -11.0229 30.31 9.21281 -10.5755 29.4357 9.44143 -9.61622 29.1784 9.27372 -9.5662 28.372 9.92423 -9.3376 27.7866 10.6299 -9.70266 26.9281 11.0359 -10.3604 27.058 11.772 -11.2929 26.7539 11.5715 -12.157 26.6439 11.0394 -13.0801 26.3636 11.2414 -12.5931 25.787 11.823 -12.5282 26.2747 12.6775 -12.1461 26.9447 13.3184 -11.179 27.0971 13.6292 -10.6438 26.2818 13.6149 -11.077 26.1526 14.4865 -12.0321 25.9221 14.1312 -12.3828 24.9016 13.9001 -12.5856 24.9888 12.88 -12.1197 24.5077 12.0823 -11.7748 23.5764 12.0654 -12.6625 22.9886 12.2 -12.6006 23.596 11.3794 -13.3273 23.9627 10.8952 -14.1563 23.944 11.5735 -13.7962 23.0416 11.8159 -14.3659 22.4795 12.3967 -15.2265 22.8635 12.778 -16.0806 22.7584 13.3002 -15.3114 22.661 13.9793 -15.1206 21.729 14.2311 -14.1192 21.7147 14.6532 -13.3143 21.1658 14.9458 -13.0042 20.9101 14.0569 -13.8295 20.735 13.4289 -13.8301 19.7911 13.8128 -14.5073 19.1431 13.3365 -13.9771 19.1618 12.4972 -13.8217 18.8399 11.4701 -13.3685 19.5642 10.8858 -12.7452 19.295 11.574 -12.8498 20.2966 11.6854 -13.8015 20.5411 11.5048 -14.7299 20.3369 11.1592 -15.5037 20.2446 10.4598 -16.1679 21.0429 10.562 -17.072 21.2172 11.0693 -17.4452 20.6359 11.8201 -18.3124 20.6169 11.3784 -19.1787 20.8812 10.9912 -18.8708 21.2824 10.118 -18.7887 21.9613 10.8269 -18.77 22.7691 10.1705 -19.5865 23.3336 9.92965 -20.047 23.9898 9.38812 -20.7304 24.5113 8.90637 -20.8597 25.4686 8.95764 -20.0115 25.8573 8.61215 -19.2508 26.4674 8.83629 -18.2497 26.3368 9.03043 -17.8216 25.821 9.78176 -17.4105 24.9419 9.85263 -18.0648 24.8341 10.5244 -18.5899 25.0776 11.3178 -17.8312 25.3003 11.9591 -17.5132 24.4242 12.3542 -16.9352 23.9629 11.7169 -16.59 24.7561 11.2072 -16.225 25.6657 11.1164 -16.3976 26.6015 11.3168 -16.0837 26.783 12.1821 -16.1554 25.8557 12.4867 -16.2969 25.9708 13.465 -17.2458 26.1884 13.695 -18.075 25.6158 14.0262 -17.1653 25.2234 14.0932 -16.8765 24.4535 14.5688 -17.0529 23.486 14.7915 -16.2266 23.6471 15.2795 -15.4378 23.5375 15.8422 -15.0973 24.2127 15.3306 -15.3297 24.702 14.5321 -15.083 25.6001 14.8539 -14.8071 26.1133 15.604 -15.0478 25.7755 16.4797 -15.4168 25.172 17.2125 -14.827 24.4044 17.4669 -14.8107 23.752 18.2633 -14.9055 22.7441 18.4027 -14.8851 23.1519 19.3414 -14.1334 22.4733 19.0626 -13.4919 22.8963 18.4085 -12.6986 22.5425 17.8622 -12.0652 22.1757 17.1642 -11.671 22.9959 16.7596 -11.348 23.7736 17.328 -10.5187 23.8904 17.7988 -10.0241 24.688 17.5267 -10.1689 24.9539 18.5082 -10.2349 25.7942 19.1143 -10.0481 25.1283 19.8082 -10.2896 24.37 20.3001 -9.7145 23.6122 20.1175 -10.0751 23.2358 21.0331 -9.8934 23.4121 21.9878 -9.2328 23.1209 22.7419 -9.5182 22.2849 22.2417 -10.3112 22.3718 22.7989 -11.1268 22.5881 22.2292 -11.5483 21.6471 22.4219 -12.0071 21.1386 23.2249 -11.9375 20.5329 24.0381 -12.2235 19.7857 23.4639 -11.4158 19.3232 23.0516 -10.5006 19.02 23.0349 -10.3633 18.0752 23.1254 -11.1725 17.7387 23.6125 -11.7715 17.1881 24.2441 -11.3384 17.3945 25.1652 -11.4943 16.7158 25.9148 -11.812 16.5331 26.8137 -12.4427 15.897 26.3566 -11.8324 15.1732 26.7629 -10.8442 15.4231 27.0729 -10.6878 14.9132 27.9124 -11.2174 14.2899 27.3407 -10.5364 13.6192 26.9137 -9.78373 13.0316 26.4913 -10.4367 12.5377 25.8935 -9.7265 11.8443 25.9003 -9.2275 10.9825 25.7945 -9.07816 11.3501 24.8561 -8.63833 12.0217 24.2689 -8.53077 12.8619 24.7417 -7.78698 12.8511 25.463 -6.98246 12.4768 24.9661 -6.84058 12.0888 25.8546 -6.77492 12.9021 26.2877 -5.99308 13.0142 25.6129 -5.99506 12.43 24.835 -5.30167 13.1794 24.766 -5.79976 13.8332 24.2231 -5.89589 14.6664 23.7055 -5.2393 15.2605 23.9603 -5.68312 15.6559 23.1649 -5.47411 16.5985 23.0154 -5.74914 17.2512 23.6932 -6.49155 16.5699 23.7354 -6.80229 17.2071 24.3655 -7.38697 17.7632 24.9109 -7.92244 17.1467 25.5154 -8.08342 16.2268 25.7783 -8.40244 15.7525 26.5445 -8.46503 14.7762 26.3262 -8.98402 14.0911 25.9222 -9.40273 13.7477 25.1217 -9.16909 13.7073 24.1306 -9.71616 14.4636 24.4038 -10.5092 14.3349 25.0334 -10.8769 13.4162 25.2291 -10.6772 13.0207 24.281 -10.541 12.1187 23.8799 -10.7067 12.4188 22.9558 -11.1978 13.1747 22.5535 -11.7828 13.9926 22.4403 -12.6507 14.3767 22.7017 -13.4796 14.214 22.3097 -14.3599 14.6168 22.6458 -14.381 15.3989 22.0781 -14.4782 14.6835 21.3918 -15.4083 14.5248 21.3374 -16.1136 15.1905 21.5533 -15.7117 16.0728 21.2385 -15.1002 15.6604 20.5305 -14.2479 15.7855 20.0208 -13.3288 15.8352 20.2615 -13.2092 15.375 19.4074 -12.3277 15.3223 19.9857 -11.904 14.3491 20.0366 -11.6727 14.5485 19.0667 -11.7532 15.1607 18.2615 -11.8302 16.0297 17.7796 -12.0537 16.8023 18.2977 -11.1973 17.1412 17.8104 -10.2785 17.1253 17.487 -9.94878 16.2338 17.2609 -10.0638 15.3269 17.4453 -9.81221 14.4831 17.9106 -10.4752 14.215 18.6322 -10.149 13.6965 19.4527 -10.6714 14.3559 19.9304 -10.2748 14.5745 20.7843 -10.2575 15.6136 20.8212 -10.3386 16.5823 20.8847 -10.0445 16.2233 21.8288 -9.4007 16.148 22.5944 -8.94161 16.69 23.3756 -8.03636 16.8379 23.6793 -7.73322 16.0059 23.2497 -7.55178 15.3288 22.5436 -7.58923 14.6598 21.8272 -7.17785 13.8445 22.2071 -6.16185 14.0959 22.3406 -5.61312 14.1045 21.5167 -4.80066 13.5033 21.6329 -4.39877 14.1715 21.0015 -5.0702 14.0124 20.2845 -6.11567 14.1393 20.4838 -6.64264 13.8411 19.6749 -7.3106 13.4 19.0825 -7.14846 14.2448 18.5467 -7.75723 14.5439 19.2515 -7.82049 14.936 18.2848 -8.3778 14.1251 17.9829 -8.24315 13.2509 17.7134 -7.64481 13.1689 16.9582 -7.2356 12.7637 17.6637 -6.35038 12.4289 17.8969 -5.38057 12.0977 17.8386 -4.94692 11.259 17.5019 -5.10903 10.737 18.3533 -5.05627 11.6457 18.8295 -5.86968 12.146 19.0777 -5.93064 12.6497 19.9711 -5.9562 12.7313 20.9984 -6.73811 12.6869 21.6152 -7.13979 11.7413 21.4644 -6.91214 11.049 20.7659 -5.97127 11.088 20.4041 -5.30284 11.6808 20.9141 -4.31643 11.5921 21.0998 -3.8686 11.013 21.7232 -3.64857 10.1019 21.9853 -3.03751 9.59302 21.3178 -2.75026 10.3692 20.7132 -3.4621 10.2988 19.9846 -2.71198 9.96935 19.3434 -1.79661 9.97789 19.7307 -1.58902 9.92466 18.7596 -1.06091 10.1656 17.8914 -1.8455 10.8255 18.1189 -2.82133 10.6043 17.9325 -3.00277 11.4644 17.4601 -3.37622 11.6023 16.6212 -3.2405 12.3594 17.2945 -3.60379 13.0061 16.6469 -3.07322 13.6242 17.261 -3.95514 13.6509 17.8213 -4.4186 14.4831 18.0627 -4.90865 14.873 17.2508 -4.98359 13.9119 16.877 -5.82558 13.8999 16.2672 -6.51645 14.3458 16.8699 -6.66938 15.1998 17.3801 -6.21068 16.0344 17.2566 -5.45392 16.2158 17.8528 -6.19443 16.6439 18.4787 -6.20313 17.6604 18.685 -6.37458 18.3672 19.2102 -6.41231 18.8617 18.3044 -6.42563 18.8582 17.3428 -5.72958 19.5497 17.0827 -5.77572 20.5642 16.8777 -6.21953 21.0864 16.1538 -6.86863 21.8132 16.3163 -6.05717 22.2626 16.7261 -5.18854 21.9938 16.9603 -4.66797 21.4398 17.5349 -4.2928 20.6379 18.0066 -4.92757 20.373 18.7224 -4.63358 20.217 19.6439 -3.70648 20.4738 19.797 -3.89606 19.7361 19.1519 -3.47613 18.8165 18.9535 -3.61423 18.9099 19.9454 -3.66033 18.3081 20.6718 -3.93145 17.9559 21.51 -3.14501 17.5259 21.9473 -3.74516 16.9755 22.5695 -3.1169 17.4008 23.2479 -3.52037 18.0968 23.8657 -3.40116 17.9086 24.8153 -3.22092 18.8038 25.2311 -3.3023 18.0767 25.9406 -3.67426 17.5491 26.7974 -4.27153 18.2495 27.1184 -5.2539 18.1326 27.2486 -4.81265 17.2694 27.7161 -4.11262 17.5534 28.387 -3.81158 16.6628 28.404 -3.46734 16.2581 29.2664 -4.33899 16.3849 29.7207 -4.97567 15.664 29.7689 -5.92271 15.8015 29.4248 -6.084 14.8739 29.773 -5.93299 14.6037 30.7483 -6.81388 14.8247 31.2398 -7.17747 14.4835 30.3646 -7.44496 13.6027 29.8667 -7.39203 14.4106 29.2151 -8.0244 15.0319 28.7407 -8.98983 14.7923 28.6913 -9.52146 14.1448 29.0741 -9.1562 13.2955 29.501 -10.1473 13.2792 29.6592 -11.1708 13.2211 29.6536 -12.0244 12.7961 29.5174 -12.2859 12.6554 28.4883 -11.4104 12.2653 28.224 -11.8973 11.7198 28.8035 -11.7694 10.9414 29.3836 -11.6474 10.2548 28.5984 -10.8349 10.806 28.4936 -9.9169 11.1794 28.3218 -9.4649 11.788 27.6549 -8.72195 12.2037 27.0761 -8.06782 11.4389 27.1509 -7.09883 11.1017 27.2139 -6.83647 10.7229 26.2768 -6.19663 9.9921 26.6075 -5.2019 9.95132 26.3525 -4.35487 9.39658 26.2686 -4.43745 10.0841 27.0775 -3.67501 10.6699 26.8501 -3.76266 10.8304 27.8738 -4.53866 11.0879 28.4944 -4.3801 11.6155 29.361 -5.30423 11.1764 29.3084 -6.15691 10.7022 29.0359 -6.17047 9.86717 28.5594 -6.49364 9.03109 29.0423 -5.89402 8.29601 29.3114 -6.85399 8.16149 29.7211 -7.79699 8.04617 29.788 -7.63673 8.35694 30.734 -6.96324 8.70819 31.3681 -6.01158 8.90959 31.5562 -5.80026 8.7009 30.6512 -5.77275 9.72164 30.6364 -5.33458 10.2781 31.3703 -4.95336 10.9439 30.8161 -4.1037 10.7513 31.2732 -3.62842 10.5475 32.152 -3.08687 10.3253 32.9841 -3.1527 11.326 32.9572 -3.95797 11.7852 32.403 -3.75525 12.399 31.7145 -3.17388 12.8207 30.9924 -3.24947 12.7123 30.0189 -2.26276 13.0476 29.9154 -2.97267 13.182 29.2231 -2.60031 12.2582 29.1089 -2.20285 11.86 28.3406 -2.13847 11.0742 27.7767 -2.45746 10.6357 27.0069 -2.34249 9.70255 26.6191 -2.91316 8.85196 26.773 -3.54106 8.42075 26.1226 -4.06339 7.83031 25.5095 -4.66787 8.5007 24.9348 -4.40158 7.70442 24.4395 -4.36608 7.86712 23.4306 -4.27657 8.32036 22.5546 -4.19186 8.25011 21.578 -4.486 8.80145 20.8238 -5.11857 9.39305 21.3134 -5.48588 8.52843 20.9492 -6.09228 9.26168 20.7977 -6.72213 9.49793 21.5202 -6.94051 9.22803 22.4674 -7.5584 8.36442 22.3992 -6.64869 7.87943 22.6052 -6.75478 7.13995 21.9385 -7.42495 7.17168 22.6934 -8.06266 7.10432 21.9347 -8.78813 6.5464 21.765 -9.49763 5.89254 21.3206 -8.96839 5.08261 21.6855 -8.13699 5.2072 21.029 -7.25405 5.38528 20.4861 -7.13164 4.64201 19.8285 -7.81366 4.32258 19.1134 -7.11194 4.15977 18.4212 -6.34287 4.71205 18.1971 -5.45159 4.51355 17.9012 -4.74387 5.06407 17.4374 -4.08305 5.67654 17.805 -4.3706 5.5881 18.7239 -3.38461 5.59909 18.8178 -2.33206 5.52283 18.894 -2.35443 6.33722 18.2594 -1.44366 6.00948 18.4344 -1.58797 6.61738 17.6868 -1.77572 7.22474 16.9483 -2.68533 7.64907 16.859 -3.02578 6.67946 16.8036 -2.62176 6.96221 15.9011 -2.81326 7.64854 15.1511 -1.79998 7.69857 14.9272 -2.07419 7.82366 13.9377 -1.70714 8.76308 13.8124 -2.25939 9.16749 14.6053 -2.90504 8.72859 15.2783 -3.66132 8.32567 15.8402 -4.17419 8.09563 16.6691 -3.99549 7.7211 17.5638 -3.50258 8.05203 18.3565 -4.31441 8.62916 18.0987 -4.96493 7.82081 18.2689 -5.1183 6.87635 18.2153 -5.17178 6.89134 19.2375 -5.15518 6.628 20.2703 -5.54241 5.97579 20.9506 -5.11574 5.54916 21.7207 -4.28973 5.7359 21.2298 -4.44788 4.90858 20.7328 -4.15657 3.93211 20.9412 -4.03097 3.6763 21.9263 -4.71772 3.64708 22.5632 -4.70452 3.01125 23.4021 -4.03494 3.67241 23.7415 -4.5555 4.55799 23.7131 -5.06738 4.80971 24.4474 -5.385 3.89037 24.4405 -5.71737 3.23981 23.7206 -6.27241 3.15452 22.9025 -6.83909 3.4176 23.7004 -7.53289 2.75636 23.4826 -6.93562 2.02137 23.5891 -7.66254 1.70929 22.9323 -7.60368 0.7879119 23.3328 -8.34709 0.1960579 23.2344 -9.19516 0.1462779 23.7769 -8.55125 -0.01097937 24.4814 -7.82877 -0.2292221 25.1968 -8.01547 0.6502919 25.6395 -7.14262 0.6265179 25.0991 -6.15159 0.6755779 25.1246 -6.3408 0.1507719 25.939 -5.4636 0.08107533 26.3536 -6.17452 -0.1008751 27.0281 -5.43235 0.4709029 27.358 -5.78533 1.23388 26.9711 -5.64912 1.74791 27.8191 -4.76613 1.63876 27.3604 -4.72962 1.16696 26.52 -3.87763 1.13636 27.0719 -4.11712 0.7627909 27.97 -3.3538 0.2300269 27.7944 -2.6415 -0.2687261 28.2678 -1.80274 -0.1115071 28.772 -2.06811 -1.0332 29.0761 -2.80884 -1.03385 29.7229 -3.13887 -1.93097 29.9609 -3.59354 -2.81243 29.6527 -3.06096 -3.50027 29.0532 -2.8939 -2.62539 28.7147 -3.32566 -2.75122 27.8683 -4.25248 -2.66775 27.5028 -5.13384 -3.1324 27.8722 -5.70906 -3.97261 27.5377 -5.67334 -3.75598 26.5732 -6.53417 -4.18608 26.5549 -6.74668 -4.55305 27.4826 -6.41604 -5.33576 28.0654 -6.53964 -5.73901 27.2106 -6.92942 -6.58858 26.8949 -6.62765 -7.02312 26.0217 -6.59777 -8.05148 25.7563 -5.89667 -8.46373 25.1942 -6.24888 -9.41075 24.8693 -7.0431 -9.10277 24.4654 -7.90844 -9.08314 25.0605 -7.56327 -8.17633 25.4744 -7.37966 -8.67747 26.3091 -6.93668 -9.54041 26.3098 -7.74371 -10.0842 26.0233 -8.669 -10.0152 25.6563 -9.25345 -10.2653 26.3994 -10.0859 -10.6764 26.8445 -10.0248 -11.6348 27.009 -9.82829 -11.6095 28.0004 -10.1305 -10.6303 27.9113 -10.4076 -10.4078 28.8585 -10.8215 -9.82706 28.1551 -11.2965 -10.0494 27.2895 -10.9906 -10.4322 26.3962 -11.2453 -9.90729 25.5644 -11.5115 -9.46594 24.6828 -12.0599 -9.35044 23.8577 -12.4506 -10.1989 23.6662 -13.2319 -10.6538 23.2063 -14.0192 -10.0608 23.0569 -14.3234 -9.87886 22.1544 -13.2621 -9.93587 22.1171 -13.2482 -9.29856 22.8548 -13.8894 -8.89802 23.4765 -13.1307 -8.2646 23.5006 -13.5097 -7.48339 22.9268 -13.0098 -6.84747 22.3524 -12.0478 -6.89717 22.0691 -11.8979 -6.95152 23.0482 -12.4151 -6.21283 23.4581 -13.4141 -6.14223 23.7435 -13.2652 -5.54623 22.9691 -14.1843 -5.227 23.0287 -14.6178 -4.96441 23.8616 -14.3678 -4.08116 23.398 -14.4964 -4.27772 22.449 -15.3889 -4.53248 22.5092 -15.1919 -3.78081 21.8119 -16.0753 -3.76027 21.4212 -16.9256 -4.3013 21.4558 -16.5942 -3.89536 22.2921 -16.8359 -4.14391 23.2042 -17.0576 -4.4813 24.1293 -17.2843 -5.45216 24.1441 -16.7426 -6.16347 24.6898 -15.9923 -5.52055 24.812 -15.517 -6.32954 24.597 -15.7361 -7.00867 23.9283 -15.1724 -7.75875 23.8794 -14.8788 -7.17601 23.0878 -15.4073 -7.48229 22.3386 -15.4079 -7.83015 21.4445 -14.8586 -8.04783 20.6712 -14.4437 -7.72601 19.8892 -15.1299 -8.2832 19.6482 -14.8062 -7.63021 18.9998 -14.6148 -6.74048 18.9028 -14.2714 -6.13987 18.2141 -13.8871 -5.30856 18.4728 -14.0805 -4.34682 18.8855 -14.9198 -3.87766 19.2074 -15.4108 -4.06909 18.3904 -16.2627 -4.09087 17.8448 -15.6379 -4.16395 17.0492 -14.9897 -3.71304 16.4427 -14.9306 -2.72037 16.1074 -14.9572 -3.29554 15.2881 -14.6791 -3.59497 14.3911 -14.1764 -2.80789 14.011 -13.6652 -2.16715 13.6322 -13.251 -1.55345 13.0246 -13.4706 -0.7146921 12.5843 -13.9814 0.04938563 12.1996 -13.9307 0.8130229 11.6357 -13.4414 0.4504269 10.868 -12.4467 0.5425829 10.8432 -12.486 1.48008 10.6742 -13.4049 1.78494 10.3533 -13.9047 0.9934809 9.98834 -13.9411 -0.05474867 9.78133 -14.1803 -1.03485 9.48234 -14.7784 -1.34443 10.2225 -13.8835 -1.46052 10.7235 -13.9518 -2.31155 10.3214 -13.613 -2.90334 9.68777 -13.2296 -3.36057 10.4842 -12.9176 -4.31824 10.6244 -13.7059 -4.6044 11.2969 -13.757 -4.80376 10.2754 -14.3824 -4.22222 9.75408 -13.6863 -4.60029 9.16339 -14.3466 -4.0723 8.69729 -13.7447 -3.35285 8.47338 -13.6996 -2.52823 7.91387 -14.1962 -1.71481 8.38885 -14.9682 -1.10501 8.17248 -15.2871 -1.01043 9.10444 -16.1268 -0.4999501 9.31572 -15.7794 0.1632959 8.63851 -16.0393 0.9525639 9.19816 -15.68 1.927 9.32495 -15.6757 2.2787 10.2615 -15.7966 2.89705 11.0662 -16.7529 3.10876 11.1791 -16.4655 3.22631 12.1279 -16.0967 3.91034 12.7495 -15.8919 4.61002 12.1337 -16.0366 4.91532 13.0202 -15.1417 4.50705 13.3845 -14.7688 4.72655 14.2144 -14.1368 5.12329 13.5832 -13.1444 4.88784 13.4299 -12.9502 5.65377 12.7662 -12.1951 6.18554 12.9641 -11.446 6.78359 13.1083 -10.8868 6.06088 13.2966 -11.3182 5.49575 12.5963 -11.5103 4.61306 12.1641 -11.3794 3.83613 12.8266 -10.8849 3.07006 12.5058 -10.1027 3.71495 12.5519 -9.87151 3.2199 13.4096 -9.00304 3.1379 13.9776 -8.16053 2.56427 14.2357 -8.20198 3.23262 14.9202 -8.10338 3.91768 14.2731 -8.34986 3.90585 13.2734 -7.5945 3.33275 12.8575 -6.60976 3.55827 12.8089 -5.96274 3.98748 13.5143 -6.00076 3.68643 14.49 -6.40417 2.77441 14.5 -6.48775 1.84045 14.673 -5.81856 1.15471 14.4001 -5.7111 0.5908089 13.6081 -5.19288 -0.3071891 13.4822 -5.167 -0.5099661 12.5665 -6.07795 -0.7171511 12.2685 -6.86779 -1.34185 12.5276 -7.60599 -1.22059 11.9222 -7.76014 -0.8555171 10.9896 -8.23318 -0.1770331 10.5144 -8.52851 -0.5071431 9.54936 -7.86104 0.09938203 9.09165 -7.61109 1.03826 9.47082 -6.61581 1.37236 9.51416 -6.57228 1.04714 10.5053 -7.08009 1.53682 11.2303 -7.46249 1.66948 12.1627 -7.75646 1.17323 12.9802 -8.70197 1.3379 12.7974 -9.62682 1.45664 12.873 -10.0843 1.69849 12.0566 -10.5484 1.28525 12.8226 -10.1589 0.4427179 13.3111 -9.41138 -0.2212881 13.241 -9.59321 -1.03497 13.8784 -9.10637 -1.78241 14.2204 -8.70874 -2.31484 13.4754 -9.69507 -2.15197 13.5429 -9.43707 -2.70695 12.7621 -10.2278 -2.45007 12.1752 -10.9912 -2.74363 12.7618 -11.7846 -3.24963 12.4902 -11.9593 -2.66412 13.2806 -12.3837 -2.76762 14.1813 -12.7288 -2.2054 14.9489 -12.7979 -1.54393 14.1709 -13.2274 -0.9802271 14.7689 -13.59 -0.8055091 15.6665 -14.2092 -1.38015 16.1953 -13.3278 -1.59949 16.5575 -13.7343 -1.19357 17.4026 -14.5516 -0.8031841 17.0419 -15.4511 -1.24661 17.1641 -16.3481 -1.46505 16.8155 -16.3932 -2.48753 16.7994 -16.9541 -2.06209 17.5595 -17.4292 -2.77426 18.1052 -16.4865 -2.93345 18.5016 -15.5066 -2.77684 18.6182 -14.6339 -2.13776 18.5876 -14.0476 -2.30273 17.7193 -13.6734 -3.2085 17.4798 -12.686 -2.986 17.6083 -12.618 -3.42429 18.5318 -11.9578 -4.08473 18.2815 -11.8053 -4.00621 17.329 -11.5548 -3.09533 17.1543 -10.8127 -3.70869 16.8652 -10.2885 -4.5823 16.8784 -10.3007 -5.50636 16.8819 -9.84575 -5.77082 17.7078 -8.96114 -6.29061 17.5076 -8.20881 -6.39839 18.1928 -7.97408 -5.66667 18.7272 -8.94219 -5.50771 18.7807 -9.33586 -4.66109 18.3976 -9.58334 -3.74524 18.169 -10.0558 -2.99654 18.5721 -10.3261 -2.17994 19.052 -9.87826 -1.87852 19.9582 -10.3915 -1.1466 20.3723 -9.91799 -1.47197 21.248 -10.4979 -1.78229 22.0685 -11.1285 -2.26067 21.4805 -12.0667 -1.93487 21.6289 -11.5094 -1.09751 21.7772 -11.8324 -1.48511 22.6063 -11.5898 -2.22028 23.153 -11.1425 -3.06814 23.1788 -11.1393 -3.26573 24.1209 -10.3468 -3.69427 24.3994 -9.78458 -2.9825 24.1548 -8.77558 -2.80029 24.412 -8.98645 -2.30571 25.18 -9.17642 -3.11509 25.7512 -10.0537 -3.29154 26.3479 -10.113 -3.98426 25.586 -11.0341 -4.57612 25.6194 -11.459 -3.89638 25.0592 -11.8782 -4.77921 24.8377 -12.1817 -5.67274 24.8694 -11.8553 -6.55028 24.7432 -10.8807 -6.37412 24.6808 -10.3183 -6.84417 24.0472 -9.70865 -7.23213 24.7356 -9.02726 -7.04168 25.4255 -9.53376 -7.7919 25.837 -10.2576 -8.25773 26.3056 -10.7327 -8.54283 25.4576 -11.1553 -7.69795 25.4991 -11.7942 -7.6417 26.2663 -11.183 -6.92657 26.4557 -11.3368 -6.88643 27.4363 -10.5413 -7.42872 27.5689 -10.2789 -6.56315 28.063 -9.6465 -6.00439 28.6281 -9.65643 -5.04917 28.336 -10.129 -4.58773 29.0517 -10.479 -4.89578 29.8513 -9.53986 -4.78092 30.2757 -8.61026 -4.58552 30.7869 -8.66983 -4.64549 31.8052 -7.69753 -4.39888 31.9216 -7.22706 -3.49279 32.0981 -7.72875 -2.68339 31.8765 -8.52831 -3.10826 32.1425 -9.34558 -3.7333 32.2147 -9.73542 -3.00303 31.6795 -10.5476 -2.61035 32.0392 -10.8089 -1.82797 31.5166 -10.394 -1.62277 30.632 -10.2663 -2.02692 29.7972 -9.40174 -1.60961 29.3877 -9.6856 -1.65649 28.4208 -8.82929 -1.22927 28.1469 -8.91014 -0.2863901 28.4898 -8.26707 0.4336719 28.7769 -8.27715 1.11368 27.9907 -9.15313 1.13908 27.6027 -9.65913 1.34412 26.8252 -10.688 1.43576 26.744 -11.2138 0.8368559 27.3607 -11.9458 1.01359 28.011 -12.9451 1.28594 27.8279 -12.685 0.6458979 27.0878 -12.1137 0.04405823 26.4796 -12.2049 0.8889659 25.955 -11.5692 1.72429 26.1229 -11.1495 1.28377 25.2722 -10.2178 1.46377 25.1716 -9.35449 1.3909 25.5493 -8.61412 2.12505 25.6995 -9.16634 2.79496 25.2318 -9.29508 3.24273 24.3861 -10.084 3.70113 23.9425 -10.2336 2.95235 23.3514 -9.46786 2.4155 23.0402 -9.99157 1.538 22.9076 -10.8664 1.62851 22.5424 -10.8125 2.59707 22.3027 -11.237 2.16684 21.482 -11.3193 2.54684 20.5291 -10.7011 2.29663 19.759 -11.5994 1.82019 19.5986 -12.0236 0.8752639 19.8116 -11.4219 0.2110019 19.3663 -11.3451 -0.5150101 18.6454 -11.2283 -1.13147 17.8607 -11.9879 -1.07397 17.1963 -11.4515 -0.9004621 16.4308 -11.8985 -0.1433131 16.7667 -11.6799 0.2870219 15.8704 -11.1761 1.13096 15.9139 -10.9186 1.77537 15.2057 -10.7785 1.29961 14.3642 -11.6151 1.18444 13.7393 -12.2366 1.44217 14.4751 -13.0447 1.92905 14.0729 -12.8892 2.97146 13.893 -11.9511 3.09433 13.4421 -11.3192 3.23568 14.2748 -11.7929 2.84565 15.1046 -11.2698 3.41564 15.6706 -11.1384 3.01946 16.5802 -10.6589 2.49655 17.2539 -11.2522 2.86435 18.0497 -11.2427 3.36534 18.8726 -11.1062 3.95548 18.0465 -12.0571 4.02108 17.8523 -12.4592 3.27076 17.3534 -12.1802 2.34927 17.6254 -12.2781 1.6518 18.3534 -12.2089 0.9344209 17.6923 -13.1974 0.9692519 18.0457 -13.1196 1.14103 17.0289 -13.3661 1.10824 16.0462 -14.2005 1.24791 15.5089 -14.0919 1.91489 16.3058 -14.9936 1.39919 16.3196 -15.4992 1.00876 17.052 -16.3741 0.5508839 17.3422 -15.9202 0.1642279 16.5317 -16.673 0.6565399 16.1588 -17.5071 0.3758769 16.6387 -17.9465 -0.1131991 15.9464 -17.5937 -1.02034 15.518 -18.5633 -1.38513 15.5445 -18.2419 -2.31757 15.4582 -18.5526 -3.12031 16.1493 -18.4903 -3.53774 17.041 -18.4009 -4.12716 17.8169 -18.6403 -4.08016 18.8088 -19.5521 -4.4028 18.9664 -19.7684 -3.69501 18.3907 -20.7113 -3.35071 18.5856 -21.2562 -4.23978 18.6343 -21.2725 -5.02789 19.235 -21.0628 -5.18564 20.1572 -21.0755 -6.05535 20.6042 -21.238 -5.51159 21.4119 -22.11 -5.56672 20.8921 -22.1462 -4.58225 20.6628 -22.6379 -3.75533 20.6644 -22.9279 -4.3441 19.9213 -23.3375 -3.45441 19.9475 -24.0123 -3.84834 20.547 -24.9976 -3.61375 20.6044 -25.3775 -3.4625 21.5036 -25.4171 -4.00249 22.3013 -25.9213 -3.44605 22.9095 -25.384 -2.957 23.6738 -25.5104 -2.23344 23.0119 -24.6118 -1.81156 23.0914 -23.7394 -1.33897 22.9139 -23.7749 -0.4516421 22.6126 -23.7934 0.3108499 22.0091 -23.1378 0.7515379 22.5913 -22.9673 0.1470669 23.4084 -22.2618 0.1154579 24.0446 -22.1833 0.7096699 24.819 -21.4625 0.07802103 24.9742 -21.3201 -0.9315631 24.966 -21.5547 -1.34541 25.894 -21.157 -1.21627 26.754 -20.3737 -0.8004481 27.2723 -20.4621 -0.3510251 26.3469 -19.9952 0.4088479 25.9898 -20.2401 0.9407229 26.7606 -20.6526 0.8001589 27.6774 -21.5244 0.7892129 28.2144 -20.9618 1.1824 28.9294 -20.7957 0.2847939 28.7416 -20.2962 -0.3471191 29.3111 -19.3019 -0.3835591 29.5466 -19.1044 -0.07999017 28.5865 -18.6553 -0.5826331 27.8584 -18.0058 -0.9659451 28.6202 -18.3797 -1.81818 29.0703 -17.3658 -1.74673 29.292 -16.7437 -1.20529 28.6812 -16.696 -0.6326311 27.8879 -16.7478 0.04635923 28.6641 -15.781 -0.2604031 28.4639 -15.1599 0.4281279 28.8535 -14.2284 0.5908989 28.8654 -14.3075 -0.2904611 29.3442 -14.4573 0.001689104 30.2382 -13.7239 0.1361979 30.9237 -12.9272 0.5672949 31.4148 -12.7486 -0.1933981 32.0451 -13.1864 -0.8986591 31.503 -13.7647 -1.63492 31.6215 -14.5801 -1.49559 31.0742 -15.4559 -1.7169 31.4208 -14.9315 -1.38825 32.2183 -15.4397 -1.79638 33.0355 -14.573 -1.22908 33.3272 -14.3777 -1.94975 33.9461 -13.8537 -2.64104 33.4781 -12.9718 -2.9522 33.1792 -12.5867 -2.00675 33.5023 -11.8773 -1.91914 32.6735 -11.0842 -1.25841 32.9303 -10.4035 -0.7576341 33.4396 -10.0371 -0.8152961 32.5088 -9.15791 -0.3263291 32.3486 -8.62221 -0.2834061 31.5334 -9.16311 -0.4640701 30.6786 -9.8489 0.1951219 30.3072 -10.6335 0.7299999 29.9953 -10.1671 1.28634 30.7392 -9.90994 1.727 29.8593 -10.2143 2.30198 29.1265 -10.305 3.288 29.2888 -9.809 4.21565 29.3885 -10.5271 4.27244 28.6783 -10.2038 3.44909 28.2022 -10.9709 2.80958 28.3122 -11.3269 3.54162 27.7484 -11.4199 3.90209 26.8356 -11.4511 3.565 25.863 -10.4817 3.71934 25.5981 -10.5265 4.63526 26.0987 -10.3726 5.17692 26.9072 -9.91341 4.64487 27.5389 -9.13626 4.16276 27.8837 -8.37625 3.51115 27.5416 -7.58766 3.49862 26.8869 -6.95528 2.9456 26.3842 -5.97325 3.15709 26.3611 -4.99867 2.99623 26.0442 -4.99613 3.92113 26.2843 -5.00119 4.87825 26.6897 -4.23583 5.16614 27.3246 -4.30855 4.79378 28.2519 -4.04788 5.74211 28.3073 -4.95801 6.22906 28.4354 -5.59581 5.41982 28.5028 -4.76738 5.38686 29.0148 -5.47954 5.52196 29.7948 -5.09839 4.56593 29.8502 -4.12676 4.60173 29.9187 -3.18381 4.75357 30.1689 -2.71193 5.50878 30.703 -2.06905 5.9324 30.1795 -1.76248 5.82305 31.0608 -0.789086 6.11515 31.0101 -1.03261 6.47333 31.8987 -0.762365 6.40693 32.8685 -0.790483 7.39789 33.2033 -0.809175 8.23667 33.7979 -0.547769 7.34979 34.2299 --0.320565 7.50619 34.6679 --1.13294 7.62519 34.0777 --1.80305 8.18581 34.5538 --2.46556 8.40657 33.8674 --2.81454 8.804 32.9615 --3.16984 9.77009 32.8533 --3.50138 10.0469 31.985 --4.51022 10.2717 31.9634 --5.4374 10.0014 31.7056 --5.66918 10.5822 30.8296 --5.27053 10.9557 29.9762 --4.30525 11.01 30.0811 --3.59771 11.6917 30.1106 --4.06496 12.4745 30.6189 --4.30454 13.3517 30.1327 --4.7354 13.146 29.2417 --4.43759 13.8247 28.5367 --4.44589 13.2246 27.6776 --3.54471 12.8259 27.4431 --2.97426 11.9721 27.7024 --2.63082 11.8427 26.7701 --1.79132 11.478 26.4223 --2.04564 11.1707 25.5062 --1.69896 10.2715 25.6491 --2.54514 10.2078 26.0737 --2.92259 10.3012 25.1281 --3.89321 10.1545 25.0886 --4.69932 10.5023 25.4382 --5.44236 10.7704 26.0223 --5.92612 10.8491 25.1167 --5.94666 11.3521 24.2954 --5.98103 10.6516 23.7341 --5.79544 10.9259 22.7268 --6.03681 10.4138 21.8686 --5.02499 10.3981 21.6933 --5.3175 9.76208 20.978 --4.95117 9.22439 20.3478 --4.50195 8.48961 20.7825 --5.14891 7.64304 20.9614 --5.50693 6.71433 21.0533 --6.39082 7.16387 21.3137 --6.15971 7.96535 20.6806 --5.97209 8.60679 21.3932 --6.88254 8.96117 21.3908 --7.5414 8.35542 21.777 --7.96573 9.11367 22.3164 --8.20687 9.93344 21.8859 --9.11952 9.75923 21.4376 --9.37911 8.78747 21.275 --8.92006 8.18755 21.8607 --9.74585 7.6449 21.675 --9.4214 6.74282 21.319 --9.78391 6.42066 20.425 --10.3614 7.0081 19.8029 --10.9148 7.34918 19.0422 --11.4588 7.86553 18.3409 --12.2094 8.21997 18.9922 --12.6787 7.97777 19.7537 --12.5555 7.10324 20.1042 --12.9064 6.45121 19.4266 --13.1518 6.44791 18.4829 --13.7867 5.87947 17.9239 --14.4616 5.30524 17.4434 --15.1579 5.24338 16.7547 --15.8657 5.72659 17.3279 --16.3316 5.04445 17.8508 --17.0806 4.83549 18.3979 --17.6606 5.33174 17.7499 --18.5623 4.85001 17.7364 --19.2185 4.69888 16.9889 --19.6732 3.8089 17.2818 --20.3651 4.52437 17.2226 --20.3227 5.51888 17.5012 --21.1094 6.06236 17.4214 --21.5878 5.23942 17.5871 --21.8801 5.38857 18.5018 --21.2377 6.0622 18.8767 --20.475 5.72109 19.2422 --19.6627 5.69619 18.7191 --18.987 6.17167 19.2432 --19.1327 6.56931 20.1538 --18.5137 5.91762 20.6247 --17.6884 6.37321 20.9763 --17.7948 6.11681 21.9682 --18.2732 5.5893 22.6585 --17.5667 4.89982 22.8932 --16.9097 4.39922 22.5233 --17.2295 3.98463 23.4291 --16.3819 3.36921 23.2535 --16.5822 3.15409 24.2063 --16.9198 3.47553 25.0464 --15.9589 3.19106 24.9607 --15.1913 2.67156 24.5982 --14.6271 3.44168 24.4893 --13.702 3.2744 24.9376 --13.3353 3.43365 24.0285 --13.2848 4.0862 23.2894 --13.1972 3.81034 22.3193 --13.7756 2.99899 22.2779 --14.3248 3.75364 22.6128 --14.5164 3.98136 21.6338 --15.3875 4.31297 21.9605 --15.4825 3.98837 22.8994 --14.8565 4.62548 23.3565 --15.5014 5.18696 22.7354 --16.3159 5.52307 22.2651 --16.3509 6.23878 21.6301 --15.8843 6.24583 22.5212 --16.2967 7.11448 22.3753 --15.4056 7.47757 22.1632 --14.7867 7.79749 22.877 --14.9281 8.57886 23.5063 --14.2384 8.78297 22.75 --14.1538 9.67032 22.3508 --13.4932 9.61191 23.1463 --14.3558 10.0762 23.2016 --14.6818 10.6731 22.4813 --14.1785 10.694 21.6536 --14.067 9.93799 20.9663 --14.6433 9.93238 20.1828 --13.7416 9.56059 20.0677 --13.7089 8.79542 19.3993 --14.7065 8.71758 19.3935 --14.52 8.04798 20.1101 --13.8356 7.39021 20.4236 --14.0701 7.14491 19.4882 --14.5609 6.74878 18.7875 --15.0772 5.91119 19.0819 --14.5916 5.26851 19.6679 --14.383 4.45901 20.1809 --14.6783 3.62418 19.6494 --15.0126 3.5617 20.5823 --15.5845 2.83548 21.047 --14.6093 2.73084 21.4115 --14.7656 1.83973 21.6722 --14.8885 0.9385479 22.1 --15.0353 0.1008669 22.7377 --15.5127 0.3108749 23.6096 --16.2659 0.1665499 23.003 --17.2289 -0.1924341 22.9495 --18.187 -0.4523701 23.2256 --17.827 -0.5251921 24.1657 --18.5091 0.1946159 24.0059 --18.3242 0.6734629 24.8986 --17.5131 0.9857489 24.3253 --16.887 1.66044 24.8039 --17.2923 1.50815 25.6913 --16.9746 0.9162689 26.3324 --16.7503 0.2726529 27.0097 --17.6748 0.5326559 26.7803 --18.2759 -0.3542361 26.7608 --17.9529 -1.32186 26.7978 --18.5836 -1.4212 27.6086 --18.6726 -1.23734 28.6199 --18.8478 -1.38532 29.5823 --18.4953 -0.4692981 29.3457 --18.3006 0.3741809 28.9452 --17.9279 1.13785 28.4125 --17.9008 2.07153 27.968 --18.6189 1.41648 27.6179 --19.1111 0.6868579 28.1118 --19.2358 -0.3026581 28.3022 --19.7716 -0.9590701 27.6981 --20.6998 -1.07101 27.4757 --21.3647 -1.03349 28.1435 --21.0213 -0.1422501 28.4678 --21.1997 -0.09121377 29.5062 --20.8746 0.6891999 28.9494 --21.6105 1.10457 29.4108 --22.0436 0.7902849 28.5038 --23.0433 0.7767919 28.2355 --22.5049 -0.09148827 28.2411 --23.3058 -0.3401701 27.6968 --23.6874 -0.3061921 26.7915 --23.4645 -0.8401271 25.9568 --22.9186 -1.11428 25.0957 --22.5432 -2.06446 25.0774 --23.0421 -2.91505 24.6293 --23.1389 -3.66669 23.9348 --23.1328 -2.78367 23.5223 --23.9242 -2.17944 23.4265 --24.6522 -2.87911 23.3929 --24.9237 -2.18173 22.7169 --25.7609 -2.60663 22.722 --25.8535 -1.64407 22.6945 --24.9753 -1.07581 22.8646 --25.6662 -0.5610121 22.3817 --24.9302 -0.1339661 21.9277 --24.4414 -0.06187377 21.0273 --25.1635 -0.6854571 20.8387 --25.0061 -0.04801927 20.1002 --24.4987 0.6623519 19.7567 --23.6091 0.9984749 20.1518 --23.1415 1.00536 20.9724 --22.3655 0.4108719 21.2204 --22.1078 -0.04754077 20.4028 --21.135 -0.3402271 20.3023 --21.375 -0.8269201 21.1243 --20.4018 -0.6765591 21.2813 --19.8768 -1.42046 20.8733 --20.1698 -1.28786 19.9457 --19.5924 -0.4982951 19.721 --18.876 -0.4377271 18.9896 --18.4751 0.04940623 19.7843 --17.485 0.09339073 19.5815 --17.2054 -0.8796381 19.5343 --17.0477 -1.51909 20.2887 --16.4202 -2.16723 20.7375 --16.8472 -3.02566 20.2944 --17.4558 -3.72183 19.9951 --17.3843 -2.83138 19.4716 --18.217 -2.63031 19.0868 --18.2203 -3.47036 18.5185 --18.2298 -2.99064 17.6879 --19.0302 -2.42943 17.6569 --19.5831 -1.67385 18.1481 --19.1171 -0.8631901 17.8222 --18.6735 -0.002140926 17.8457 --18.3604 -0.7143201 17.2014 --17.6891 -0.7642781 16.444 --17.2961 0.1484479 16.4754 --17.3642 1.06322 16.0277 --17.819 0.9107539 15.2332 --18.7358 1.12058 15.4803 --19.492 0.4399269 15.275 --19.7423 0.9311009 14.4676 --19.1859 0.5498339 13.6909 --18.7957 -0.1102041 14.3288 --17.9028 0.1782979 14.1812 --17.0647 0.4568279 13.8636 --16.9756 1.02058 13.0128 --17.1094 1.68858 13.7578 --17.6488 2.17114 14.4762 --17.7305 2.97121 15.1112 --18.3347 2.89887 15.8646 --18.417 2.94332 16.8662 --17.7097 3.42381 17.3961 --17.3964 3.79071 18.1895 --17.4759 2.98301 18.7294 --18.4235 3.15251 19.1381 --18.7122 3.8279 19.9054 --17.9672 4.27111 20.4602 --17.6016 4.1241 21.2569 --18.586 4.29568 21.2717 --18.5869 3.27437 21.2148 --18.9814 3.11216 22.1666 --18.8782 2.32694 22.7118 --19.6415 2.3604 23.3047 --20.171 1.5208 23.2643 --20.4765 0.6036149 23.3414 --20.772 -0.2996321 22.9523 --21.7501 -0.6225901 23.0502 --22.1293 -0.4463941 23.98 --22.9202 0.1508989 23.8526 --23.784 0.6846109 23.7916 --23.7461 0.7440459 24.7518 --22.7576 0.9736189 25.0705 --22.0851 1.69822 24.889 --22.677 2.25563 24.2488 --22.5912 3.22156 24.5038 --22.5096 4.14021 24.7509 --23.3451 4.72148 24.8352 --23.5204 5.61384 24.8606 --23.1995 5.4771 23.8936 --24.1696 5.25899 24.0561 --25.1103 5.35062 23.7679 --24.5585 6.06632 23.3036 --25.3713 5.97427 22.6805 --25.6226 6.84513 22.1932 --26.4593 6.44698 22.3166 --27.1419 6.05425 21.6622 --26.2487 5.61692 21.8215 --25.292 5.4875 21.5434 --24.6662 5.33119 20.7531 --24.8024 6.28559 20.6408 --24.1696 6.0273 19.8554 --23.3697 5.35595 19.8139 --23.169 4.40361 20.0098 --24.1013 4.20402 19.9151 --24.2843 3.66161 19.0574 --25.0243 3.75273 18.3058 --25.9239 3.7334 18.0207 --25.5343 4.56337 18.4349 --25.8316 5.19426 17.8066 --25.6949 6.17609 18.1529 --24.9472 6.4964 17.4398 --24.1164 7.05103 17.6821 --23.8077 7.66947 18.4121 --23.3644 7.72344 19.3241 --22.4556 7.26196 19.0668 --22.062 8.1736 19.1313 --22.7414 8.69509 18.7794 --22.5631 9.54953 18.2858 --23.1351 10.4148 18.3445 --22.6109 10.7452 19.0418 --22.7223 11.706 18.7633 --23.2833 12.3945 19.3447 --22.6369 11.8544 19.9075 --23.3586 11.3006 20.3522 --23.095 10.6678 21.0036 --23.4794 9.87139 20.5985 --22.5339 9.69464 20.3483 --21.6549 10.0544 20.6277 --20.8194 10.4701 20.1893 --21.0914 11.4228 20.0725 --20.5795 11.5807 19.1729 --20.8305 12.4212 19.6876 --20.8346 12.706 18.7376 --21.7635 12.2962 18.5502 --22.4295 13.0798 18.4389 --21.8848 13.8665 18.1076 --22.7587 14.1077 18.3949 --22.6501 14.9562 18.9063 --23.6685 15.0673 19.0213 --23.7942 14.1084 18.7776 --24.642 13.6849 18.363 --24.8586 13.7307 17.4818 --24.179 13.0176 17.3696 --24.3911 12.0283 17.3361 --24.7808 11.1869 17.1098 --25.7773 10.8549 17.1482 --26.3579 10.7844 16.3098 --26.0516 11.6282 16.05 --25.4175 12.2595 15.4909 --24.9002 11.4044 15.7678 --24.0854 11.5598 15.2399 --24.8667 11.3335 14.6596 --24.3341 12.207 14.4296 --25.2852 12.5713 14.2966 --25.6353 12.8046 13.3467 --24.6491 12.6971 13.2806 --23.7816 12.2378 12.9397 --24.1335 11.6613 12.1639 --23.5195 11.0872 12.6337 --23.1104 10.8908 13.5469 --22.5324 10.0805 13.5635 --22.0808 9.27491 13.1962 --21.8137 9.13135 12.2911 --21.2631 9.10459 11.4543 --21.2817 9.98759 11.0646 --22.1565 10.162 10.6345 --22.5652 10.9669 11.0457 --23.2005 11.5551 11.5629 --23.6474 11.4888 10.6656 --23.9356 10.5341 10.5563 --24.8606 10.1712 10.3967 --25.8043 10.3689 10.0093 --26.3324 11.1998 9.68461 --25.6072 11.5576 9.0225 --25.8804 10.7354 8.56323 --26.6143 10.6941 7.88041 --26.1792 11.0693 7.07356 --26.5145 11.5714 6.23982 --27.2654 11.7498 5.56775 --27.7374 12.1084 6.37974 --28.4716 12.806 6.67095 --29.3842 12.4335 7.00184 --29.7947 11.6028 6.70223 --30.31 10.781 6.71252 --31.0686 11.2663 6.25234 --32.0348 11.5843 6.28058 --31.6137 12.0296 7.01392 --32.3661 12.2151 7.75306 --31.7357 12.9675 8.10269 --31.0297 13.6469 8.12657 --31.5147 13.7893 7.25154 --32.0401 13.1777 6.66333 --31.3428 13.2869 5.98396 --30.8962 13.0869 5.08818 --30.5843 12.1392 5.1499 --29.6671 12.5074 4.92466 --29.1215 13.2127 4.44513 --28.6476 13.6821 5.18371 --27.6386 13.7717 4.97338 --27.022 14.4491 5.29122 --27.2057 14.6123 6.25409 --26.805 15.5738 6.39628 --25.8825 15.4069 6.11553 --24.9938 15.3025 6.59875 --24.279 15.6334 6.00895 --23.9109 16.1239 5.23267 --23.7267 17.0443 4.91467 --22.7246 17.3931 5.04679 --22.4811 17.104 4.09164 --21.6916 16.631 3.70478 --21.0977 16.1224 4.23216 --21.0794 15.683 5.12673 --20.0854 15.518 5.16461 --19.739 16.4343 5.25751 --19.2131 16.6617 6.12038 --18.8459 15.7934 5.83032 --18.1789 15.0831 5.81031 --17.1661 15.1198 5.98822 --17.4644 16.1376 5.85744 --17.6513 16.1619 4.84522 --18.4936 16.7053 4.85462 --18.5345 17.5423 5.41013 --18.2709 18.2763 6.06027 --17.894 19.1554 6.36879 --17.4666 19.4769 7.30791 --17.4344 20.4177 7.12227 --17.9044 21.02 7.83779 --17.6188 21.6705 8.48269 --18.2492 22.3563 8.68685 --19.0491 21.7112 8.33057 --19.883 21.7093 7.91159 --19.4908 22.0909 7.01876 --19.2065 22.9475 6.53505 --19.5051 23.1516 7.43552 --19.8127 23.9034 8.01308 --20.4853 24.4388 8.51202 --20.724 25.3547 8.95203 --21.2292 26.0688 9.45084 --21.1646 26.014 10.4375 --22.1422 25.831 10.1633 --22.5471 26.2039 10.9396 --23.0646 26.3172 11.7763 --22.1152 26.1027 12.0249 --21.7604 26.9981 12.4579 --21.1577 27.7658 12.6511 --21.648 27.6858 11.8031 --20.679 27.9025 11.5702 --20.0775 27.378 12.2064 --19.1424 27.0219 12.4217 --19.0808 26.6068 11.5361 --18.9778 25.6653 11.918 --18.9056 24.7452 12.2398 --18.6698 24.4249 13.1544 --19.5193 24.5188 13.6219 --20.5115 24.6694 13.3884 --20.4561 23.6492 13.3375 --20.7069 23.1358 12.5338 --20.0188 22.7979 11.8716 --20.1708 23.7303 11.4051 --20.7842 23.3466 10.7554 --21.6192 22.8548 10.8845 --21.6499 22.9888 9.86657 --22.0685 22.0659 9.79239 --22.1637 21.7139 10.7249 --21.3694 21.643 11.4308 --21.4744 20.7723 12.0477 --22.1068 20.4377 12.7222 --21.6536 21.1993 13.3045 --21.3793 20.7101 14.1314 --20.6809 21.2881 14.5455 --20.6798 21.4975 15.475 --21.3182 21.4736 16.1669 --22.2474 21.8894 16.0612 --22.5953 21.5518 16.9836 --21.9156 21.9263 17.5473 --22.4599 21.4552 18.255 --23.1808 20.8412 18.05 --22.4578 20.3071 18.258 --22.202 19.4807 17.6634 --21.3894 20.1193 17.7696 --20.6776 20.7987 17.873 --20.3446 21.1227 17.0654 --19.6232 20.3901 16.8719 --19.0894 20.4375 16.0204 --19.1272 19.4581 15.8261 --19.0966 19.217 14.7902 --19.6694 18.7072 14.1803 --20.4552 18.6888 14.8226 --20.6674 18.4306 15.7422 --20.3408 17.5103 15.5035 --20.0707 16.6032 15.1799 --20.8879 16.3217 15.6853 --21.4775 15.8705 16.2557 --22.3568 15.4909 16.382 --22.1894 15.8427 15.5012 --22.3371 16.6869 15.1445 --22.0333 16.0297 14.4469 --22.4082 16.0744 13.5085 --23.3656 16.2672 13.5158 --23.2192 17.1578 12.9702 --23.916 16.9904 12.2647 --24.5851 17.213 11.6874 --24.146 17.2091 10.772 --23.8156 17.4951 9.82253 --23.691 16.5761 9.65023 --24.235 15.861 10.1599 --25.0708 15.571 10.635 --24.3581 15.2828 11.3218 --23.907 14.4246 10.9911 --23.1818 14.3431 10.2233 --22.1994 14.4153 10.3133 --21.3913 13.8928 10.2759 --21.4987 13.5508 11.2282 --20.7441 13.7107 11.7399 --20.2721 14.3938 12.3467 --20.925 14.0418 12.9704 --20.3734 13.3743 13.6485 --20.1928 13.1362 14.5835 --21.0726 12.619 14.8008 --21.907 12.6852 15.3948 --22.6271 12.3618 15.9153 --22.6921 11.4694 16.2772 --23.5591 11.8821 16.8167 --23.5735 10.8329 16.8661 --23.6823 9.95208 16.3182 --23.1899 9.25396 16.9063 --23.6422 8.68967 16.2652 --23.2204 7.80625 16.0122 --23.1589 8.21481 15.0417 --23.6382 7.33632 14.6345 --23.8257 6.44376 15.1577 --23.3361 5.7585 14.6132 --22.541 5.15062 14.3652 --22.4227 4.30402 14.8777 --23.4149 4.40223 14.7731 --24.1127 3.93343 15.271 --24.4207 3.13992 14.8008 --24.4093 2.67677 13.8488 --24.3873 3.18045 13.0363 --24.6592 3.93111 13.6143 --23.979 4.54525 13.1312 --23.3618 3.84353 12.7459 --22.364 3.62566 12.8998 --21.6034 4.25903 12.669 --21.3495 4.03056 11.7903 --21.6773 3.0411 11.8116 --21.0703 2.72507 12.535 --20.2631 3.20918 12.1574 --20.2497 2.23959 11.987 --19.3155 2.55164 11.9415 --18.6353 3.24762 11.9546 --18.0776 3.05433 12.767 --17.7847 3.93117 12.3158 --16.8872 3.99144 11.9943 --17.1921 3.01748 12.3963 --17.2927 2.07128 12.7641 --16.4518 2.48771 13.1928 --16.157 2.64031 12.2582 --16.0055 2.44711 11.2432 --15.144 2.83982 11.4457 --14.5094 2.21121 12.024 --14.3463 1.40988 12.6389 --13.4321 0.9371269 12.7704 --13.4447 -0.04806037 12.5063 --12.5911 -0.1811881 12.9986 --12.0812 0.6491789 12.9888 --11.3775 1.40001 12.7907 --11.7397 1.64666 13.6832 --11.4468 2.254 14.3736 --11.7889 2.98437 13.7965 --11.2182 3.69827 13.9589 --11.7046 4.57666 14.3271 --12.0426 3.98731 13.5007 --12.5908 4.80649 13.5827 --12.6416 4.66244 12.5739 --11.8579 4.12006 12.0974 --11.1874 4.80016 11.8683 --11.3776 5.23437 12.759 --11.4915 6.2562 12.9629 --11.5046 6.70273 13.8868 --12.3315 7.25776 13.9563 --12.7117 6.72575 14.6714 --12.5316 6.85418 15.6202 --11.8064 7.36243 15.1744 --11.8451 8.36513 14.9547 --12.7174 7.92712 14.8537 --13.5642 7.70128 15.2866 --13.8657 8.29963 14.6168 --13.9564 7.79027 13.8161 --14.4094 7.15712 14.3501 --14.3468 6.58089 15.1467 --14.4884 5.90523 14.4795 --14.7155 5.06278 14.9991 --14.0505 4.66439 14.3347 --14.5294 3.93128 13.8956 --14.2364 2.97003 13.9428 --14.6069 2.13064 14.2792 --14.688 1.18424 14.5292 --14.5071 0.1902699 14.7433 --14.2823 -0.5606821 15.3974 --13.524 -1.20811 15.1652 --13.5942 -1.13658 14.2053 --14.0867 -1.97968 14.258 --14.5769 -2.56252 13.5928 --15.4902 -3.04816 13.7549 --15.7385 -2.59165 12.9073 --15.8357 -2.01715 12.0372 --16.445 -2.81988 12.097 --17.0792 -2.68862 12.8949 --17.9881 -2.75599 13.2879 --18.8346 -2.99186 12.9635 --19.4988 -3.02283 12.1673 --20.1976 -3.4139 12.8359 --19.7532 -4.32533 12.5259 --18.839 -4.56991 12.7099 --18.3951 -4.17272 13.4829 --17.4917 -4.52357 13.5213 --17.0641 -4.60136 12.6009 --16.2549 -4.68362 13.1621 --15.4939 -4.12084 13.4292 --14.6691 -4.4765 12.9728 --14.6656 -3.65752 12.4391 --14.6476 -4.32313 11.753 --13.6776 -4.66283 11.7215 --13.7301 -5.69202 11.6376 --13.1448 -6.35061 11.2179 --12.7574 -5.52365 11.584 --12.1736 -4.94371 12.1848 --12.842 -5.2083 12.9384 --13.5783 -5.27939 13.644 --13.4902 -6.17651 13.1994 --14.4057 -6.52402 13.2866 --14.3562 -6.97354 12.3591 --14.615 -7.62887 11.6458 --14.8069 -8.36125 10.8896 --14.5856 -9.17328 11.5389 --13.8087 -9.39008 10.9573 --13.8174 -8.65073 10.2559 --14.0519 -9.47135 9.66708 --14.7789 -9.66902 8.96843 --15.0803 -10.4636 8.54218 --15.0374 -11.4846 8.78984 --14.4105 -11.9962 9.33588 --13.7812 -12.0743 10.1845 --13.1962 -12.9 10.0741 --13.0538 -13.5696 9.34185 --12.2246 -13.1869 9.76267 --12.4798 -12.2357 9.69031 --12.0714 -11.6186 10.3804 --12.1794 -10.6208 10.0733 --12.5165 -10.1044 10.8808 --12.4184 -9.44783 10.1353 --12.1539 -8.6806 10.76 --12.1976 -8.27962 11.7027 --11.4265 -7.86601 11.1753 --10.9556 -7.92769 11.9986 --11.1915 -8.30279 12.8651 --11.8023 -9.12923 13.0127 --11.828 -9.07229 14.0063 --11.2001 -9.0135 14.7836 --11.5952 -9.84168 15.1764 --10.6904 -10.0223 14.9038 --10.1302 -10.8396 14.7605 --10.5029 -11.4179 14.1174 --11.1416 -11.5842 14.9066 --11.2242 -12.5605 15.1777 --11.5317 -13.4836 15.0639 --11.725 -14.4905 15.3132 --12.3741 -13.7678 15.5667 --12.435 -13.9258 14.5695 --11.9904 -14.289 13.7641 --12.6238 -15.1122 14.1629 --13.04 -15.782 14.771 --13.9029 -15.5369 15.2656 --13.7377 -14.5597 15.1611 --14.1663 -13.6683 15.224 --14.217 -12.7216 15.1278 --13.6967 -11.942 14.8575 --14.499 -11.2963 14.8886 --13.7169 -10.6717 15.0105 --14.1385 -9.8111 15.3582 --14.056 -8.81631 15.2429 --14.4813 -8.57581 14.3953 --15.1847 -8.71191 15.0675 --15.0514 -7.71003 14.9407 --15.3321 -7.51251 15.8825 --14.908 -6.58921 15.9068 --14.6714 -5.67807 15.6459 --15.5342 -5.24074 15.5652 --16.2389 -5.21051 14.8716 --17.1144 -5.6317 14.9657 --18.0109 -5.24926 14.7811 --18.3465 -4.32793 14.7115 --19.0306 -5.16055 14.7123 --19.3714 -4.30282 15.1305 --18.8486 -4.78579 15.7512 --19.2384 -5.2351 16.5672 --19.8194 -4.53081 16.9817 --19.7381 -3.62079 16.601 --20.5704 -3.84518 16.0759 --21.5085 -4.2948 15.9969 --21.9579 -3.45094 15.764 --21.2816 -3.02928 15.1384 --21.2253 -2.10826 15.3897 --21.7034 -2.24058 16.2761 --21.0459 -2.78734 16.7232 --20.626 -3.60996 17.2528 --19.8026 -3.20319 17.6697 --20.1867 -2.53149 18.2412 --21.1643 -2.39693 18.3186 --22.1375 -2.51574 18.6108 --22.4368 -3.37668 18.9218 --22.8845 -3.80557 18.125 --22.565 -4.75155 18.0827 --22.6369 -5.53053 17.3699 --22.2214 -6.45394 17.5042 --21.2175 -6.59485 17.2436 --20.6093 -6.59152 16.4205 --21.2274 -6.13979 15.765 --21.007 -6.29038 14.8 --20.1658 -5.87802 14.393 --20.4347 -6.50318 13.659 --20.1294 -7.3614 13.3379 --20.2815 -8.31904 13.6495 --21.1411 -7.81407 13.6691 --21.2453 -8.77627 13.4552 --20.4355 -9.31786 13.6686 --20.464 -10.0844 13.0139 --21.3752 -10.5898 13.1139 --21.8539 -11.4582 12.8058 --22.3566 -10.6054 12.7918 --23.2847 -10.4304 13.1392 --22.8335 -9.86882 13.7944 --22.9326 -9.0004 13.265 --22.8225 -8.2001 12.7304 --22.2137 -7.76809 12.1041 --22.5538 -8.06583 11.2631 --23.4181 -8.13162 10.7142 --23.5371 -9.01777 10.1883 --22.8542 -9.48906 9.59995 --21.9935 -9.85428 10.0257 --21.2578 -10.1448 9.40457 --20.3342 -9.78064 9.55296 --19.8757 -10.0564 10.4057 --20.2877 -10.8476 10.8672 --21.2219 -10.9051 10.7232 --21.232 -11.285 9.76872 --20.976 -11.7902 8.91172 --20.1906 -12.2223 9.4151 --20.1321 -12.2628 10.3815 --19.4145 -11.5355 10.6352 --18.8021 -11.0408 11.2093 --18.0605 -10.9506 11.8919 --18.0788 -10.845 12.8903 --17.2406 -10.3265 12.3753 --17.5709 -9.4526 12.6933 --17.0711 -8.58167 12.3955 --16.1007 -8.82916 12.0808 --15.7548 -8.87283 13.0025 --15.2406 -9.65447 12.7039 --14.4041 -9.93805 13.1609 --13.8399 -9.72105 13.9656 --12.9552 -9.29287 14.2124 --12.3149 -10.0254 14.0559 --11.6958 -10.6328 13.5311 --11.2286 -10.4575 12.616 --11.1151 -11.3363 12.1987 --12.1197 -11.344 11.8726 --12.3337 -11.6469 12.7798 --13.07 -12.2801 13.0694 --13.7741 -12.9705 12.9666 --12.913 -13.4556 13.2667 --12.7811 -13.1876 12.2675 --13.4142 -13.7861 11.7717 --14.1294 -13.6347 11.0755 --13.7435 -14.5436 11.2214 --13.2462 -15.2746 11.6231 --13.619 -15.7563 10.8342 --13.4032 -16.6958 10.5545 --14.1442 -17.177 11.0633 --14.3038 -17.0154 12.0063 --14.2937 -18.0898 12.1521 --13.3573 -18.0653 11.9491 --13.008 -17.1619 12.0144 --12.569 -16.5856 11.3765 --12.0342 -16.2705 12.175 --11.29 -15.682 11.7911 --11.3462 -14.9688 12.5186 --11.3175 -14.3164 11.7542 --11.6705 -13.8169 12.5716 --11.6079 -13.0055 11.9091 --11.0558 -12.5212 11.3573 --11.1217 -12.8611 10.3926 --11.1717 -12.9499 9.44344 --11.4883 -13.4336 8.65279 --11.3911 -14.0536 9.45605 --11.0154 -14.8942 9.90665 --10.9107 -15.7418 9.31658 --10.1674 -15.1091 9.31277 --9.25543 -14.7441 9.48574 --9.35603 -14.8184 8.48217 --9.01679 -15.7862 8.38727 --8.42185 -16.5203 8.69078 --7.71336 -15.9321 8.1799 --7.5319 -15.7941 9.18166 --8.15522 -15.7054 9.99015 --7.27699 -15.5965 10.3733 --6.39986 -15.2661 10.8049 --6.99323 -14.98 11.575 --7.21043 -15.3354 12.513 --7.61294 -16.2207 12.2547 --8.52252 -15.7352 12.159 --8.89485 -16.5281 12.712 --9.44335 -16.5552 13.5329 --9.97968 -15.8482 12.9906 --10.1016 -15.1833 13.7344 --9.76662 -14.3857 13.2031 --10.4265 -13.5756 13.275 --10.1803 -13.1596 14.098 --9.38299 -12.8067 13.616 --9.35298 -12.1008 12.8896 --8.71844 -11.3585 13.0916 --8.48646 -11.9451 13.8439 --8.17243 -12.7794 14.3115 --7.47383 -12.8095 14.9691 --6.70691 -12.5244 14.3243 --6.29636 -12.0625 13.5451 --5.77251 -12.1324 12.7276 --4.96963 -11.957 13.3266 --4.37885 -12.6061 12.8797 --3.4751 -12.7535 13.1224 --2.46644 -12.5955 13.2734 --2.29336 -13.5335 13.3964 --2.28724 -14.2212 14.0714 --3.01944 -13.9878 14.7322 --3.64286 -13.378 15.0489 --4.07825 -14.2475 14.6776 --4.00845 -15.222 14.9321 --3.50938 -15.5669 14.0639 --2.64177 -15.9914 14.1924 --1.78684 -15.6144 14.575 --1.03774 -14.8316 14.5595 --0.257539 -15.0141 13.9101 --0.814122 -14.5346 13.3128 --0.279798 -14.2109 12.5227 --1.13092 -14.0016 11.9281 --1.68929 -14.8867 12.1271 --2.2502 -15.1814 11.3779 --3.22441 -15.4114 11.3595 --3.95495 -15.7002 10.8825 --4.93527 -15.3058 10.6727 --4.52089 -14.4495 10.5088 --5.03661 -13.7371 11.1481 --5.2316 -13.384 10.2465 --4.91356 -13.611 9.38488 --5.13142 -14.5975 9.17386 --4.28 -15.02 8.91954 --3.42342 -15.3088 8.55623 --4.00123 -16.0499 8.4121 --4.26571 -16.1461 9.37968 --5.11562 -15.9241 8.96915 --4.97638 -15.9521 7.98776 --4.82796 -15.4948 7.0453 --4.98525 -16.0406 6.16289 --5.93043 -16.3144 6.1374 --5.8433 -16.0465 5.14941 --6.80047 -16.0544 5.55214 --6.71995 -16.9712 5.07558 --7.29431 -17.7093 5.45684 --8.08481 -17.7934 4.88759 --8.83237 -17.7277 4.31484 --9.29485 -17.406 5.10454 --9.50908 -16.8318 4.2715 --10.0262 -16.4766 3.50252 --9.76806 -15.741 2.95711 --10.4393 -14.9967 2.73803 --10.6939 -13.9773 2.837 --9.86313 -13.4496 3.10292 --9.4669 -12.5588 3.2127 --9.32951 -11.5627 3.1926 --9.49092 -11.8666 2.24387 --8.51063 -12.0104 2.2545 --7.647 -11.7223 2.52399 --7.16154 -11.4849 3.32388 --7.58521 -11.7138 4.1843 --8.08859 -11.2034 3.49062 --8.43055 -10.3051 3.80534 --8.36071 -10.9378 4.66446 --8.52729 -11.7573 5.22929 --8.12353 -12.0899 6.05005 --7.6002 -11.1451 6.04934 --8.22611 -11.223 6.86227 --8.17027 -10.2027 6.81395 --7.66758 -9.85711 6.08457 --6.70709 -9.80032 5.72645 --5.73627 -10.0756 5.73279 --5.90122 -10.6519 4.95043 --6.19392 -11.3805 5.67116 --5.19158 -11.3663 5.79466 --4.21011 -11.3152 5.3763 --3.42291 -11.6358 5.91709 --2.47573 -11.9692 6.03712 --2.82688 -11.7363 6.84839 --3.46379 -11.3149 7.4446 --3.82628 -11.0748 6.58181 --4.14163 -11.9973 6.82995 --5.02245 -11.5529 6.97695 --4.96484 -11.8054 7.93043 --4.97512 -11.9889 8.90666 --5.80108 -12.3064 9.25755 --6.18154 -12.2917 8.31973 --6.86248 -12.9804 8.76474 --7.60562 -13.5297 8.95671 --8.47612 -13.359 9.19352 --8.97273 -12.599 8.88789 --8.88602 -11.7999 8.27398 --8.83056 -10.8708 8.56809 --8.01839 -10.3895 8.4692 --7.56872 -10.0371 9.38398 --8.48196 -9.64187 9.26905 --9.25637 -9.73074 8.65801 --8.94671 -8.73462 8.73173 --8.68501 -7.84965 8.63449 --9.67852 -7.89738 8.57039 --10.5474 -8.17671 9.05984 --10.9916 -8.7796 9.61118 --10.5077 -9.49113 10.1048 --10.9201 -9.65617 10.9771 --11.0191 -9.16513 11.8401 --10.056 -8.98558 11.8441 --9.48656 -9.83375 11.8815 --8.52771 -9.40361 11.9027 --7.65701 -9.19628 11.5324 --7.28913 -8.98857 10.6557 --6.85527 -9.25242 9.75601 --5.8838 -9.45995 9.73748 --6.17547 -10.3458 10.1679 --6.38789 -11.3313 10.4024 --5.60911 -10.9228 10.7947 --5.26977 -11.7576 11.1855 --4.31387 -11.9952 10.8125 --3.81708 -11.2754 10.4831 --3.63662 -10.5949 9.80697 --3.83197 -9.66397 9.35883 --3.23304 -9.97363 8.67636 --4.05337 -9.99381 8.05107 --4.00879 -9.60027 7.20057 --3.24219 -10.2628 7.46003 --2.21937 -10.0085 7.54237 --1.5086 -9.3663 7.61932 --2.03755 -8.64762 7.22902 --2.60656 -7.91609 7.52817 --3.07442 -7.78088 6.71161 --3.90213 -7.30732 6.52288 --4.46595 -6.69211 7.1664 --5.32853 -6.27249 7.12371 --4.85495 -6.14359 8.00402 --4.60717 -6.93374 8.54844 --3.68486 -7.14225 8.26117 --2.76403 -6.97013 8.74928 --2.83071 -5.96947 8.8676 --2.32492 -5.91072 9.68941 --1.43914 -5.59526 9.46368 --0.718796 -5.09829 8.94702 --1.68619 -5.01923 8.72194 --1.86715 -5.94074 8.46423 --1.24196 -5.34578 7.92916 --1.15171 -5.94459 7.08821 --0.978512 -5.92971 6.07717 --1.35606 -6.8707 6.0425 --0.767922 -7.64702 6.42272 --0.865564 -7.45187 7.38743 --0.896027 -6.76326 7.98738 --0.812824 -7.50732 8.60398 --0.9275 -7.38563 9.56079 -0.03925537 -7.66421 9.74743 -0.979635 -8.01612 9.50727 -1.37164 -7.13546 9.24982 -2.22756 -7.59726 8.86003 -2.13468 -8.45454 9.2289 -3.02987 -8.1633 9.69418 -2.89406 -9.09685 9.3726 -3.91906 -9.48224 9.38328 -3.54115 -9.60345 10.25 -2.81453 -10.3028 10.5753 -1.82304 -10.141 10.4085 -1.87521 -10.5727 9.56157 -1.10952 -11.242 9.50076 -0.480168 -11.276 10.2902 --0.181517 -11.7603 10.8565 --0.654144 -12.4303 11.4198 -0.169415 -12.3388 12.0215 -1.11456 -11.87 12.2915 -1.4029 -11.0693 11.6927 -1.96894 -10.3992 12.2367 -2.59011 -11.1355 12.3341 -2.85567 -11.8283 13.0112 -2.89577 -11.3065 13.8757 -3.29015 -10.6659 13.2455 -3.76112 -9.99368 13.9789 -3.70739 -9.27913 13.3061 -3.61942 -8.64505 12.4664 -4.31742 -8.05681 13.0009 -4.67152 -7.25635 12.4987 -4.02476 -7.19478 11.7987 -4.65541 -7.95778 11.5507 -4.26264 -8.4686 10.7116 -5.12178 -8.893 10.6796 -5.9996 -8.6933 11.1762 -6.6614 -8.06781 10.7916 -6.84345 -7.13375 10.7941 -7.11938 -6.21555 11.1719 -6.94666 -5.38361 10.7529 -7.0666 -4.91156 11.6361 -6.12999 -5.16393 11.9884 -5.70367 -5.96256 12.4204 -6.32633 -6.35782 13.1015 -6.16522 -6.99838 13.842 -5.23511 -7.24871 13.7518 -4.67898 -7.53724 14.5081 -3.84233 -7.12629 14.7783 -4.33898 -6.23568 14.6018 -4.92888 -5.54235 15.0331 -4.66588 -4.61073 15.4541 -4.77967 -3.74714 15.8524 -4.56712 -3.11922 16.5592 -5.13401 -2.2673 16.653 -5.7262 -1.72388 17.2534 -5.70437 -1.19063 16.3647 -6.36443 -1.59586 15.742 -6.00244 -2.47326 15.3074 -6.61123 -3.26395 15.342 -7.52945 -3.69607 15.5365 -7.83861 -4.54128 16.0288 -8.05658 -5.10122 15.2442 -8.19459 -5.95882 14.7299 -8.00076 -5.13946 14.1373 -8.01104 -6.00924 13.6213 -8.01555 -6.98035 13.5843 -8.92536 -6.82341 13.2842 -9.37941 -7.38898 13.9703 -9.30533 -7.71918 14.8557 -8.77157 -8.05922 15.6348 -8.06582 -8.34086 16.2745 -7.49695 -8.98885 15.7348 -7.30155 -8.39651 14.956 -6.37858 -8.08252 14.9308 -5.99767 -7.35344 15.4904 -5.89821 -7.57671 16.465 -5.48744 -7.99633 17.2791 -4.94498 -8.65608 17.8231 -4.5791 -8.36726 16.9378 -4.34638 -7.58715 17.5114 -3.58903 -8.31376 17.5636 -2.86878 -7.85887 18.0733 -3.53982 -7.40044 18.7233 -3.63229 -8.24255 19.1673 -4.29521 -8.97527 19.1768 -5.2283 -8.99934 19.471 -4.74273 -9.82793 19.8541 -3.97734 -10.2775 20.4163 -4.38304 -9.43663 20.9001 -5.20799 -8.81106 20.8057 -5.29995 -8.25845 21.666 -5.55068 -9.08412 22.2561 -5.62191 -8.38517 22.9529 -5.45372 -8.9074 23.8446 -4.97544 -9.68615 23.4533 -4.04899 -9.7301 23.2144 -3.02538 -9.72771 23.4248 -2.27777 -9.25773 23.9092 -2.60637 -9.83146 24.642 -2.06834 -10.4691 25.1648 -2.98501 -10.1383 25.4648 -3.77338 -10.2511 24.8341 -3.21226 -11.0752 24.7921 -3.81998 -11.5338 24.1775 -4.53746 -11.2246 24.7592 -5.36673 -11.1681 24.2911 -6.15237 -11.1392 24.9052 -6.94253 -11.2748 25.5101 -7.97556 -11.3918 25.3732 -8.75444 -11.9416 25.4657 -9.3552 -11.9684 26.202 -9.11418 -12.9378 26.0338 -8.35194 -12.4012 26.3399 -7.50797 -12.8752 25.9981 -7.214 -13.4463 26.7573 -7.14874 -12.4359 27.0891 -7.18785 -12.0551 27.9787 -7.87135 -12.7175 27.8276 -8.54403 -13.3965 28.3346 -8.35464 -13.6686 29.2886 -7.86525 -12.8595 29.6467 -7.2894 -12.1995 30.0984 -6.79961 -13.0791 30.1172 -7.02606 -13.1285 31.0434 -6.31541 -13.7693 31.2378 -6.10469 -12.8383 31.2878 -6.11202 -11.9027 31.7524 -6.46447 -11.3053 31.0766 -6.3598 -10.9629 32.1249 -5.8407 -10.3956 32.7331 -5.83679 -9.91114 33.5202 -6.07137 -9.0802 33.0629 -6.69946 -9.23483 32.288 -6.36154 -8.79899 31.4863 -7.27654 -8.85419 30.9645 -7.6829 -9.77268 31.2079 -7.54825 -9.84001 30.2531 -6.598 -9.43911 30.1988 -6.49573 -9.5202 29.2163 -5.53968 -9.42432 28.9313 -5.94915 -10.1031 28.2712 -6.29367 -11.0101 28.1898 -5.53763 -11.4606 28.6116 -4.52598 -11.5743 28.4887 -3.70031 -11.4006 27.9888 -3.19174 -10.6939 27.4435 -3.84825 -10.055 27.8068 -3.86567 -10.0267 26.7991 -4.66197 -9.59274 26.3796 -5.13621 -9.30312 27.2442 -5.95765 -8.82314 27.4399 -6.40266 -7.97045 27.824 -5.78161 -7.2181 27.5977 -5.4157 -7.21001 26.6746 -4.71439 -6.53827 26.4159 -5.47709 -5.87549 26.5892 -5.61399 -5.20001 25.8277 -4.82491 -4.52466 25.7468 -5.5258 -4.10131 25.233 -4.84514 -3.58442 24.6757 -4.60258 -4.39775 24.1562 -5.557 -4.66739 23.9532 -5.76883 -4.56943 22.9462 -6.29055 -5.41666 23.0317 -7.11247 -6.00398 23.0017 -7.44245 -6.40499 23.8456 -6.61126 -6.88402 24.0272 -6.03003 -7.22985 23.3833 -5.08666 -7.44441 23.6712 -5.34654 -7.46644 24.6686 -4.42012 -7.52421 25.0908 -3.49831 -7.76408 24.7625 -3.2266 -7.48022 23.8415 -3.09361 -8.39691 23.3111 -3.55439 -8.59053 22.3858 -4.50134 -8.86873 22.1562 -4.54472 -9.79042 22.3521 -4.038 -10.6354 22.5732 -4.4668 -10.7835 21.6308 -3.43415 -10.7293 21.5707 -3.11937 -10.0331 22.2064 -2.48592 -9.31354 21.8216 -2.29327 -8.36005 21.5487 -2.90525 -7.81561 21.0357 -2.38229 -6.89796 21.1302 -2.28918 -6.84803 22.1209 -2.32682 -5.86216 22.102 -2.12691 -4.88976 21.8634 -2.75841 -4.49507 21.1587 -2.50697 -4.18478 20.2633 -3.4496 -4.52819 20.4 -4.24096 -4.50968 19.7959 -3.68327 -5.37819 19.5996 -3.2398 -6.29003 19.1856 -2.53684 -5.67732 19.0411 -1.56961 -5.66583 19.3355 -0.75988 -6.22473 19.1661 -0.899623 -6.78818 20.0683 -0.547214 -7.46286 19.3833 -0.539714 -8.45438 19.1922 -1.29024 -9.06026 18.9854 -1.75441 -8.73908 18.1814 -1.29721 -9.53868 17.8494 -1.44704 -10.4418 17.3257 -2.02234 -11.1657 17.6451 -2.14466 -11.7531 16.8161 -2.20677 -12.5496 16.0737 -2.36647 -13.1666 16.7384 -3.20061 -13.6084 16.8535 -3.36759 -13.6251 17.8097 -2.54772 -14.2206 17.6785 -2.93428 -15.1225 17.9585 -2.68993 -15.9992 17.5035 -2.96992 -16.9176 17.6857 -3.33369 -17.0413 18.5591 -3.75125 -16.1181 18.6302 -4.07882 -15.6929 17.7624 -5.08229 -15.5845 17.9423 -5.48164 -14.6386 17.8755 -5.08629 -13.7728 18.0506 -4.52667 -14.3918 17.5179 -4.62921 -14.4708 16.5588 -4.72844 -13.5453 16.8963 -4.38939 -12.5043 16.7113 -5.18137 -12.4336 17.3367 -5.52813 -11.6578 17.861 -5.09541 -12.0291 18.7351 -4.72197 -11.1619 18.9894 -4.43964 -10.3012 18.5124 -5.24734 -10.0637 17.9748 -6.08457 -9.81781 17.5114 -6.33838 -10.0576 16.5731 -6.92908 -10.1424 15.7837 -7.28932 -10.7841 15.1079 -7.73375 -10.3466 14.2749 -6.9195 -9.70849 14.2136 -6.00936 -9.61275 13.8606 -5.10514 -9.99442 13.7461 -5.74621 -10.4437 13.1082 -5.74301 -11.2844 12.6527 -4.7558 -11.1957 12.745 -4.64641 -10.9471 13.7978 -5.15186 -11.5766 14.4118 -4.31326 -11.9893 14.6519 -5.13747 -12.1385 15.2478 -4.78688 -13.0588 15.3474 -4.53673 -13.955 14.9734 -3.9135 -14.2002 14.2446 -2.95308 -13.927 14.379 -1.98967 -13.7772 14.7668 -1.93373 -13.5548 15.7345 -0.854417 -13.4668 15.8371 --0.04808563 -13.906 15.9709 --0.150293 -14.829 16.1935 -0.747902 -15.3103 16.517 -0.168313 -14.9827 17.2821 --0.853329 -14.7993 17.2382 --1.49334 -15.1939 17.8202 --1.40807 -16.1634 18.0911 --2.17774 -15.853 17.4891 --1.61044 -15.5683 16.6913 --1.49388 -16.5236 16.4705 --1.56856 -17.5317 16.2759 --1.96747 -18.4769 16.0926 --1.23597 -19.0759 16.4865 --1.25095 -20.0519 16.4228 --0.460609 -19.7369 15.8707 --0.212572 -20.3149 15.0629 --0.997494 -19.7894 14.6618 --1.71278 -19.1639 14.4626 --1.96649 -18.8815 13.5788 --2.73364 -18.9626 12.9202 --3.70405 -19.0521 13.3274 --4.55143 -18.9073 12.8728 --4.31902 -18.4176 12.0317 --3.90402 -18.1546 11.2265 --2.97252 -17.6808 11.2193 --2.26266 -18.0985 11.6979 --1.48453 -18.7856 11.9061 --0.964144 -18.9424 12.7245 --0.415193 -18.1213 13.0718 -0.444879 -18.1274 12.506 -0.974169 -17.4012 12.0582 -0.974092 -17.5739 11.007 -1.84417 -17.9929 10.7105 -1.73225 -18.4558 9.89079 -1.47171 -19.4244 9.74956 -0.974402 -20.2209 9.33611 -0.384932 -20.8911 9.86883 --0.389727 -21.1677 10.4797 -0.01521957 -21.8945 10.9896 -0.05871707 -22.8632 11.345 -0.691047 -22.8057 12.1327 -1.08135 -23.0875 11.2858 -1.83637 -22.9028 10.6416 -1.48242 -22.7551 9.6827 -1.9636 -22.274 8.94491 -1.64352 -22.6525 8.04482 -1.61614 -23.325 7.2721 -0.707763 -23.7478 7.30919 --0.252318 -23.8926 7.35222 --1.01616 -24.2206 6.88791 --1.84438 -23.7502 7.08328 --1.87519 -23.5444 6.10386 --2.13448 -22.6512 6.4576 --1.66074 -21.8049 6.19198 --1.15654 -20.9285 6.44426 --0.718475 -20.1147 6.03695 -0.164708 -20.674 5.78579 --0.01589773 -20.0681 4.97102 -0.885024 -20.4885 4.7685 -0.09926327 -21.1905 4.84691 --0.808385 -21.0182 4.59495 --1.55568 -20.5635 4.18723 --2.18709 -21.3035 4.00798 --3.00055 -20.9676 3.64674 --3.64173 -20.5375 4.2391 --3.31896 -19.8914 4.86656 --2.85119 -20.7578 5.2288 --3.7707 -20.9565 5.39289 --3.54129 -21.611 6.11262 --3.97816 -20.9457 6.67117 --4.61667 -21.1458 6.03375 --5.25223 -20.6076 5.487 --5.94805 -21.2153 5.10035 --5.70048 -22.0811 5.67156 --6.33136 -22.1884 6.45026 --6.91692 -21.5898 5.91666 --7.08882 -20.721 5.48752 --8.10577 -20.9242 5.31144 --8.4604 -21.5184 4.53969 --8.96983 -22.1018 3.89692 --8.65451 -21.5178 3.14012 --9.12891 -22.0878 2.42662 --8.53697 -22.3703 1.75747 --7.92905 -21.9405 2.30111 --7.38358 -22.2354 1.46058 --7.21531 -23.2116 1.03767 --6.93468 -22.6684 0.2045471 --6.83464 -23.6305 -0.02034028 --6.34601 -24.4529 -0.1137839 --5.57126 -25.0974 -0.2584989 --5.76164 -24.7563 -1.2226 --4.82731 -24.6024 -1.53167 --4.07329 -23.9697 -1.66746 --4.4549 -23.4143 -0.9210209 --5.17098 -23.1646 -0.2840259 --4.72227 -23.1454 0.6649081 --4.89059 -23.8285 1.37573 --4.3018 -23.9364 2.23492 --3.73559 -23.9816 1.3695 --3.49921 -23.3683 2.11781 --3.2218 -22.5715 2.60663 --3.02093 -21.5526 2.62711 --3.27769 -21.1495 1.74452 --4.19353 -21.5198 1.80137 --4.98661 -21.3389 1.2447 --5.07125 -21.662 2.17646 --4.9736 -22.0679 3.13657 --4.69462 -21.168 3.57214 --5.4142 -20.4649 3.27682 --6.36537 -20.2916 3.5088 --6.52459 -21.1085 3.05845 --7.14308 -21.8327 2.96512 --6.74055 -22.7726 2.96186 --6.86088 -23.7463 3.01942 --7.68546 -24.3396 3.12521 --8.09746 -23.7225 3.78533 --9.05604 -23.7312 4.04863 --8.95118 -23.1503 4.82985 --8.10779 -22.7169 4.87095 --7.44445 -22.0167 4.83097 --7.00109 -21.9933 3.90778 --6.20854 -22.0169 4.48577 --5.33882 -22.4997 4.69913 --5.11932 -23.3828 4.47648 --5.30212 -24.1704 5.05825 --5.85597 -23.6783 5.70885 --5.46185 -23.5175 6.58709 --4.90568 -23.8177 7.39632 --3.91829 -23.6624 7.22205 --4.06289 -23.1849 6.3398 --4.50825 -23.8857 5.86248 --3.54578 -24.1423 6.19555 --3.07496 -24.3642 7.07094 --2.75904 -25.2549 7.13063 --1.90983 -24.7458 7.32603 --2.04389 -24.413 8.2905 --1.17183 -23.8594 8.16639 --1.09149 -24.292 9.09553 --1.09729 -25.1514 8.53163 --0.284908 -25.6728 8.23479 --0.859386 -26.1114 7.53383 --0.349544 -26.0197 6.60742 --0.152157 -26.3561 5.75123 -0.305957 -25.5013 5.44341 -0.639955 -24.6453 5.0958 -1.45373 -24.1497 5.34998 -1.64969 -25.0663 5.63504 -2.41328 -25.2337 6.32573 -2.55264 -26.158 6.60078 -2.05596 -26.8893 6.99865 -1.12335 -27.1869 7.23222 -0.23524 -27.2218 7.58881 --0.48757 -27.5351 8.20561 --0.006572685 -26.6311 8.53369 -0.716113 -26.635 9.18025 -0.77614 -27.1397 10.0469 -1.05652 -26.4782 10.7392 -0.656988 -25.9826 11.4098 --0.216678 -25.4904 11.557 --0.481458 -25.4373 12.4948 -0.03084727 -25.2949 13.2875 --0.573587 -25.9575 13.6867 --0.200951 -26.6732 14.2632 --0.733612 -27.5667 14.4088 --0.233464 -27.5595 15.2468 --1.1828 -27.4525 15.6123 --1.12796 -27.4415 16.5979 --0.502434 -27.7334 17.3217 --0.700554 -27.3487 18.2064 --1.00912 -26.6588 17.539 --0.987297 -26.1222 18.3746 --1.59682 -25.3207 18.0438 --1.62191 -25.0287 17.0786 --2.10594 -25.2279 16.2842 --1.60907 -24.6897 15.639 --0.876122 -24.1887 15.2298 --1.44249 -24.1263 14.4007 --0.56479 -23.7399 14.1555 -0.110963 -23.5695 14.8308 -1.06158 -23.272 14.5201 -1.4566 -24.1711 14.4872 -2.37447 -24.4431 14.1512 -2.63715 -23.891 14.9731 -3.46508 -23.3658 14.543 -2.96624 -22.7441 13.9468 -3.76553 -23.334 13.6281 -3.79808 -24.2525 13.2187 -3.52321 -24.0009 12.2259 -2.584 -23.6272 12.4786 -1.67907 -23.4555 12.6389 -1.1521 -23.494 13.4485 -1.11797 -24.3445 12.8297 -1.54844 -24.463 11.9369 -1.61891 -24.8841 11.0267 -2.53561 -25.2605 11.344 -2.78562 -25.5501 10.427 -3.76353 -25.6907 10.5259 -3.55617 -25.2277 9.58969 -3.36987 -24.8313 8.67574 -4.14012 -25.1806 8.07 -5.14181 -24.8987 7.87121 -5.9522 -25.4974 8.04003 -6.85831 -25.3212 8.53151 -6.86585 -26.2808 8.60469 -6.44395 -27.1857 8.3371 -6.33149 -27.9985 8.89513 -6.85272 -28.7764 9.26474 -6.62253 -28.1513 10.0319 -5.75778 -28.4818 9.90541 -5.38957 -27.8654 10.5222 -4.62468 -27.7613 9.78821 -3.94717 -27.963 9.12652 -3.93444 -26.9711 9.13797 -3.5934 -27.0736 8.20688 -3.42462 -26.7948 7.2389 -4.06156 -27.0662 6.50515 -3.28864 -27.1677 5.90157 -2.46353 -27.8413 6.17879 -1.93009 -27.5067 5.43119 -1.59997 -28.276 5.90894 -0.83552 -28.9152 6.26924 -1.24913 -29.5007 6.99391 -1.29642 -30.4602 7.08401 -1.49843 -30.114 7.99986 -2.30709 -29.6166 8.27328 -1.57615 -29.3501 8.9327 -1.61161 -28.7752 9.73419 -2.12376 -28.071 10.167 -1.63044 -28.0531 11.0027 -0.734307 -27.9152 10.6489 -0.807459 -28.3035 11.5567 -0.461584 -27.6263 12.2163 -1.35438 -27.8603 12.5701 -1.28963 -26.8496 12.3417 -2.01349 -27.1638 11.7205 -2.46607 -26.4398 12.1324 -1.93959 -25.8992 12.7972 -2.3566 -26.2365 13.6592 -3.33544 -26.2754 13.6219 -4.08726 -26.0701 14.2603 -4.20604 -26.9552 14.7261 -4.70396 -26.2083 15.3324 -5.65204 -26.0619 15.6366 -5.54673 -25.6003 16.5173 -5.54423 -24.614 16.6007 -5.83167 -24.7577 15.6306 -5.20853 -24.082 15.1549 -6.1222 -24.058 14.9134 -6.66397 -23.5562 14.1941 -6.68759 -23.04 15.116 -6.32235 -23.0095 16.0716 -6.13542 -22.0236 16.323 -6.78645 -22.0278 17.049 -6.33427 -22.6708 17.7244 -6.06887 -23.3432 18.4467 -5.32258 -23.4648 19.1422 -4.37887 -23.7634 19.4548 -3.8784 -24.5617 19.2538 -4.27229 -24.7232 20.1783 -3.42339 -24.3393 20.5526 -3.36913 -25.3153 20.3022 -2.87804 -25.5863 21.1708 -2.09713 -25.8004 21.7505 -2.43605 -26.3985 20.9227 -3.1334 -26.8931 20.4288 -4.10975 -26.6882 20.3058 -3.85087 -26.2267 19.4088 -2.90517 -26.5396 19.2663 -2.29152 -25.7341 19.1811 -2.92481 -24.9178 19.0206 -2.38267 -24.1762 19.4055 -2.94325 -23.7052 18.8028 -3.24194 -22.8151 18.4434 -3.82621 -22.7165 17.5647 -3.41857 -22.1278 16.8592 -2.54716 -21.846 16.4648 -2.09006 -22.536 15.859 -1.45522 -22.2497 16.5675 -1.68968 -23.1552 16.8379 -0.887876 -23.7107 16.6331 -0.399985 -22.9812 17.0319 --0.31213 -22.3248 16.8222 -0.163992 -22.7612 16.0343 -0.174185 -22.1584 15.2372 --0.810391 -21.8673 15.1964 --0.48581 -22.0679 14.3025 --1.3678 -22.4179 13.7687 --1.1562 -21.6924 13.147 --0.78409 -20.8726 13.575 -0.09470097 -21.3602 13.5353 -0.777126 -21.9583 13.7832 -0.44622 -22.7062 13.2566 --0.03000863 -23.3829 12.7188 --0.610865 -23.7343 12.0372 --1.55232 -24.1415 12.1249 --2.30107 -24.3469 11.5733 --2.523 -24.5548 12.5104 --2.58265 -24.3953 13.4867 --2.83629 -23.497 13.3208 --2.25993 -23.4314 14.1756 --2.13969 -22.7912 14.9809 --2.15603 -23.3361 15.8462 --2.79124 -23.2592 16.6183 --3.59935 -23.6207 17.0977 --3.89708 -23.5245 18.059 --3.3101 -22.747 17.9856 --2.44118 -22.3407 18.0574 --2.15803 -21.4529 18.0049 --1.90881 -21.0118 18.8369 --1.13707 -21.5799 18.9824 --0.484177 -21.4616 19.7388 -0.01251117 -21.727 20.5728 -0.161859 -22.6651 20.8715 --0.03410003 -23.6637 20.9497 -0.52687 -24.5226 21.0192 -0.532925 -25.442 21.5028 --0.472655 -25.446 21.4809 --1.37446 -25.7227 21.1811 --1.46507 -25.8269 22.1564 --1.2881 -24.8042 22.0565 --1.62893 -24.4157 21.1819 --1.85474 -25.0453 20.3475 --2.36318 -25.8979 20.1873 --3.16894 -25.2585 20.4277 --3.57156 -24.4207 20.4528 --4.54503 -24.4209 20.2405 --5.52895 -24.3369 20.3074 --6.37144 -24.9365 19.9056 --6.9838 -24.5353 19.2033 --7.24008 -23.5232 19.2774 --7.07351 -22.6728 18.7672 --8.02285 -22.4234 18.8033 --8.23905 -23.3358 19.0896 --9.14556 -23.6939 19.0285 --8.73742 -24.5376 18.6243 --9.51019 -25.2223 18.718 --9.70246 -26.1939 18.6072 --10.708 -26.3182 18.7596 --11.6716 -26.4342 18.3661 --12.4937 -27.081 18.4881 --11.9714 -27.8286 18.9425 --11.5439 -28.6414 19.2627 --11.4074 -29.1572 20.089 --10.4892 -29.3092 20.3638 --10.5159 -29.0347 19.4368 --10.5257 -30.02 19.3037 --10.6489 -29.6384 18.3807 --11.0138 -28.9419 17.7084 --10.1331 -28.7683 18.3149 --9.3416 -28.5523 17.6763 --9.6858 -28.0625 16.9398 --9.24671 -27.7551 16.14 --9.54019 -27.8586 15.2271 --10.1879 -27.2647 15.7918 --10.0849 -26.8799 16.7249 --9.31915 -26.5037 16.2415 --8.97102 -26.6635 15.2804 --9.14834 -26.2854 14.3889 --8.23188 -26.3753 14.4552 --7.84262 -27.2627 14.7027 --8.06001 -27.8947 14.0239 --7.45887 -28.5814 14.3882 --7.00771 -28.6853 13.5042 --6.53022 -28.1486 12.8046 --5.62054 -28.2274 13.3704 --5.06215 -27.7064 12.6767 --5.81477 -26.9588 12.6801 --5.14186 -26.7293 11.8991 --5.03935 -26.3616 12.8136 --4.9154 -26.3598 13.7381 --4.08197 -26.0099 14.2226 --3.46725 -25.4384 14.8404 --4.27884 -24.9136 14.7485 --5.10321 -24.8342 15.27 --4.42001 -24.4131 15.8104 --4.79508 -24.4356 16.7017 --5.53575 -23.7539 17.033 --5.7501 -23.6396 18.0262 --5.94048 -22.6733 17.98 --6.52284 -22.9874 17.2244 --6.44533 -22.2642 16.5577 --7.15121 -21.8054 16.0598 --6.72604 -20.9542 16.5032 --7.46794 -20.5757 15.9841 --7.19369 -19.8468 16.5603 --7.88099 -20.1815 17.2086 --7.60257 -19.6976 17.9871 --6.74804 -19.4884 18.4008 --6.03555 -19.7087 18.9722 --5.38873 -19.1204 19.3274 --5.78765 -18.318 18.8767 --5.06561 -17.8807 19.4545 --4.25904 -17.2328 19.2205 --3.92603 -16.5096 19.8651 --3.1054 -15.8943 19.6587 --2.64585 -16.6987 20.12 --3.28847 -16.8075 20.826 --3.7815 -17.6139 21.1534 --4.44437 -17.1303 20.6506 --5.13194 -16.4811 21.0998 --5.70077 -16.4709 20.3017 --6.51383 -15.8338 20.1565 --7.46278 -15.5791 20.0643 --7.27834 -15.6984 19.0724 --6.78736 -16.4565 18.6168 --6.44325 -15.6733 18.1997 --5.93119 -14.8477 18.4148 --5.39244 -13.9372 18.3976 --5.71618 -13.5547 19.2177 --5.50961 -12.5173 19.1616 --5.25301 -12.0544 18.3319 --4.53676 -11.6754 17.8329 --4.85151 -11.9309 16.9261 --5.03605 -12.6697 16.2686 --5.87721 -13.2378 16.0872 --6.41311 -13.2366 16.8715 --7.23485 -12.6469 17.2036 --7.42276 -13.2718 17.858 --7.8791 -14.2312 17.8216 --8.79398 -13.8059 17.6695 --9.30439 -14.4913 17.084 --9.09481 -13.635 16.5333 --9.72135 -13.9192 15.7891 --10.4781 -13.3417 15.5439 --10.6267 -13.9545 16.2763 --11.5079 -14.2793 16.7263 --11.1142 -14.6404 17.5589 --10.528 -14.7966 18.3273 --9.70582 -15.2743 18.5442 --10.1866 -16.2123 18.4838 --10.165 -17.0995 19.0494 --11.0962 -17.4082 19.3316 --10.4385 -18.0636 19.2244 --11.298 -18.6121 19.2929 --11.2919 -18.3803 20.3298 --10.6828 -18.4118 21.1192 --10.7422 -17.4101 21.0978 --11.2026 -17.4099 21.9795 --12.1396 -17.1143 21.7081 --12.4634 -16.5833 22.473 --12.5368 -15.5895 22.6296 --11.5426 -15.7873 22.5737 --11.8052 -15.9041 21.6364 --11.2329 -16.1212 20.8557 --10.7455 -16.132 20.041 --11.6815 -16.2169 19.7123 --12.0337 -16.1453 18.7399 --12.6742 -16.5683 18.1314 --12.0149 -16.8951 17.393 --12.438 -16.3624 16.7644 --11.5579 -16.6103 16.3077 --10.6908 -16.2303 16.5427 --10.0058 -15.6926 16.8669 --9.19448 -15.968 16.2911 --9.44073 -15.7699 15.3374 --9.67662 -16.6259 14.8305 --10.3851 -16.3487 14.2622 --10.8591 -16.4952 13.3854 --11.5681 -17.2469 13.6592 --11.9074 -18.1433 13.8545 --11.8994 -18.381 12.9376 --11.4135 -18.4116 12.1058 --10.8809 -17.9966 12.81 --10.2183 -18.6004 13.3459 --9.86835 -19.1208 14.1503 --8.87507 -19.144 13.9304 --8.05983 -18.578 13.9249 --8.09784 -17.7121 14.4711 --8.60621 -16.807 14.6001 --8.4019 -17.1634 15.4354 --7.62568 -16.4589 15.5323 --7.66705 -15.8741 16.3795 --7.60255 -16.1253 17.365 --7.76913 -17.1362 17.3297 --7.54774 -17.6674 18.131 --7.98511 -17.1014 18.8467 --7.28034 -17.1813 19.5231 --7.96595 -17.9258 19.5959 --8.26694 -17.7012 20.5269 --8.05197 -18.1396 21.4358 --7.30349 -17.5781 21.1136 --7.28509 -17.449 22.091 --7.58323 -16.9566 22.892 --7.5624 -16.3028 22.0871 --7.07354 -15.7103 22.6975 --7.76889 -15.4759 23.4416 --8.2801 -15.6595 24.3045 --8.19737 -16.0739 25.2486 --8.04954 -17.0596 25.3942 --8.51606 -17.8368 25.7287 --8.62742 -18.4899 26.5581 --9.38812 -18.2545 27.1518 --8.75255 -18.8434 27.599 --8.66947 -19.7066 27.1025 --8.35385 -20.7039 27.2569 --8.5254 -20.6776 26.3212 --9.16916 -21.3531 26.0486 --9.68347 -20.5781 25.6684 --9.93035 -20.9536 24.7293 --9.31292 -21.4752 24.0775 --9.11485 -20.781 23.3248 --8.65679 -20.2238 24.0518 --7.66083 -20.016 23.9571 --7.91193 -19.0385 23.8127 --7.6372 -18.5029 24.5857 --8.27473 -19.0409 25.1389 --7.68575 -19.7244 25.6739 --6.68931 -19.6899 25.4424 --6.8236 -20.6117 25.9194 --5.86874 -20.1621 26.0383 --5.47412 -20.5625 26.8344 --4.71573 -20.7621 26.1404 --4.56754 -19.7668 26.3823 --3.98006 -20.2297 27.0652 --3.92964 -19.2061 26.9898 --4.89529 -18.9113 27.0637 --5.10632 -17.9097 27.1824 --5.5715 -17.2045 26.6137 --4.84944 -16.7634 26.1001 --3.94242 -16.6438 25.7508 --3.14103 -16.4021 25.2192 --3.35132 -15.7486 25.9304 --2.76775 -15.3024 25.2748 --2.17604 -14.5139 25.1945 --1.70435 -13.895 24.5228 --1.26579 -14.5957 23.966 --0.48509 -14.7577 23.431 --0.272772 -15.4431 24.1348 -0.103813 -15.5876 25.0554 --0.369081 -14.7419 25.2415 --1.07511 -14.5062 25.8214 --1.08398 -15.5327 26.0883 --2.05371 -15.324 26.3184 --2.45094 -15.1741 27.2699 --2.61954 -15.0977 28.2162 --2.97413 -15.4522 29.1344 --3.06894 -15.9939 29.931 --2.61721 -16.776 29.5453 --3.23666 -16.4799 28.8108 --2.73721 -16.3844 27.944 --3.59764 -15.9838 27.7563 --3.83091 -15.3349 26.9642 --3.68725 -14.3879 26.6733 --3.57378 -13.4284 26.3879 --3.74693 -12.4219 26.273 --3.99801 -12.4045 25.2997 --4.73538 -13.138 25.0926 --5.04249 -13.6616 25.9451 --5.08535 -14.4448 26.5524 --5.75517 -14.0775 27.0102 --5.59186 -13.617 27.8681 --5.20866 -14.6125 27.9267 --6.11328 -14.9814 28.073 --6.39469 -14.2661 28.7306 --7.0818 -13.5561 28.4887 --6.44385 -13.2595 27.8282 --7.42289 -13.2061 27.5456 --7.94154 -14.0528 27.4468 --7.64038 -13.9516 26.5447 --8.18159 -14.0816 25.6834 --8.63178 -14.5505 24.9002 --9.43736 -14.7685 24.396 --9.76875 -15.5633 23.9243 --10.1182 -16.3703 23.4132 --10.6146 -17.2777 23.4551 --11.2882 -17.9909 23.3277 --11.995 -18.2389 22.6706 --11.4503 -19.0615 22.5932 --11.232 -19.647 23.3482 --11.7662 -20.1125 22.6946 --10.9726 -20.7058 22.2877 --10.5666 -20.7442 21.365 --11.4259 -20.5239 21.4039 --11.9979 -19.6795 21.652 --12.7592 -18.9781 21.6011 --13.2415 -19.7656 21.3758 --13.1434 -19.2594 20.4534 --12.1236 -19.2168 20.44 --11.8405 -19.8443 19.7302 --12.5574 -20.0584 19.0178 --13.2557 -20.7334 19.3396 --14.2063 -20.8814 19.2499 --14.6876 -20.0991 19.6854 --14.2323 -20.0109 20.5348 --14.689 -19.8672 21.4413 --14.309 -19.1562 22.0289 --14.4431 -18.5881 22.9321 --14.3278 -19.5094 23.3333 --14.1228 -19.3539 24.3298 --14.5235 -20.0491 25.0076 --14.3519 -19.1686 25.3429 --14.2934 -19.5688 26.2989 --15.2791 -19.6515 26.4714 --15.2584 -19.3511 27.4474 --15.5372 -18.4223 27.1582 --15.513 -17.4517 27.2419 --14.9016 -16.7657 27.5097 --14.176 -16.3833 28.0416 --13.8883 -16.2869 28.8918 --14.6883 -16.8679 28.8448 --15.1372 -17.7551 29.122 --15.8524 -17.2092 28.5187 --16.3952 -16.5583 27.9363 --16.5391 -16.6507 26.9058 --16.7358 -15.7097 26.6077 --16.1617 -15.961 25.8889 --15.6037 -15.2783 26.2909 --15.3217 -14.9598 27.2333 --14.8587 -14.9614 28.1458 --15.0774 -14.1763 28.7593 --15.2979 -13.2778 29.0163 --16.0244 -12.7038 29.3932 --16.9587 -12.9738 28.9447 --16.7835 -12.0703 28.6068 --17.4411 -11.9027 29.4084 --17.8886 -11.5403 28.6411 --17.3513 -10.8472 28.2815 --16.8358 -10.4771 27.5794 --16.7526 -9.47209 27.6357 --16.6165 -8.46407 27.6533 --17.1518 -7.5669 27.811 --17.1646 -6.70497 27.3267 --16.4303 -6.02934 27.308 --16.4266 -6.54797 26.4411 --16.0054 -6.89585 25.6954 --15.0374 -6.84129 25.4815 --15.0911 -6.06164 26.0504 --14.4521 -5.40231 25.703 --13.9652 -4.55283 25.2846 --14.9797 -4.31418 25.4686 --14.9092 -4.07382 24.5592 --14.7151 -3.21017 24.9593 --14.5621 -2.4174 25.5106 --14.973 -1.89718 26.3119 --15.9683 -1.71531 26.3502 --16.9596 -1.47679 26.1897 --16.7071 -0.5897181 25.8218 --16.0002 -0.4847961 25.1537 --16.6024 -1.28446 24.9286 --17.0393 -1.74433 24.1344 --17.0457 -2.69663 23.863 --17.1312 -3.58911 24.3428 --16.6889 -4.00914 23.5284 --15.8246 -3.46588 23.6833 --15.67 -3.50121 22.7003 --16.427 -2.95036 22.3833 --17.0308 -3.49368 21.8502 --17.7311 -2.89337 21.4696 --18.737 -2.61047 21.2764 --18.275 -2.79591 20.3799 --18.8206 -3.64982 20.5265 --19.6051 -3.75862 19.8246 --20.3738 -3.61352 19.2042 --20.6824 -2.66151 19.3487 --21.4669 -3.03126 19.8227 --22.0037 -3.58308 20.534 --21.3179 -4.28817 20.583 --20.4879 -4.59355 21.0812 --20.6328 -4.30987 22.0609 --20.6024 -3.90417 22.9094 --21.2951 -4.02918 23.5881 --21.584 -4.67228 24.3601 --21.3234 -4.40695 25.2496 --20.375 -4.69147 25.1209 --19.7256 -5.4119 25.037 --19.1675 -5.1292 24.2648 --19.7328 -4.3966 23.9174 --19.7064 -4.95229 23.097 --19.7359 -5.09788 22.1259 --19.391 -4.75572 21.2171 --18.8103 -5.5442 21.2532 --18.4147 -6.30364 20.7949 --18.8577 -7.01715 20.2805 --18.5467 -7.50618 19.5048 --17.9568 -7.65583 20.2486 --17.487 -8.54174 20.4205 --16.7588 -8.98013 19.8326 --16.5758 -8.00815 19.5956 --16.2571 -7.0243 19.6966 --16.0143 -6.31483 18.9925 --15.2344 -6.00696 18.3795 --14.4323 -6.05816 17.8213 --15.2716 -6.30961 17.2729 --15.9724 -6.95308 17.2688 --16.8955 -6.59841 17.1697 --17.7682 -7.30675 17.2205 --18.5367 -7.49246 17.8403 --18.2989 -8.34145 17.3868 --17.337 -8.57548 17.1086 --16.5474 -8.93688 16.7022 --16.6185 -9.15321 17.662 --16.5483 -10.0871 17.2301 --17.1672 -10.7683 17.6011 --16.3082 -11.1802 17.7183 --15.9479 -11.6197 16.8738 --15.1189 -11.0084 17.0329 --14.7565 -11.9251 16.7229 --13.7592 -12.1883 16.905 --14.2061 -13.0513 16.5453 --14.9642 -13.0271 17.0654 --15.2854 -13.5587 16.3513 --15.8904 -14.0551 16.9848 --16.0984 -14.8679 16.4998 --16.8958 -15.3377 16.8462 --17.4431 -14.6573 17.3816 --17.8947 -13.835 17.1725 --18.8192 -13.9604 16.7034 --19.613 -13.5918 16.3105 --20.3084 -13.6606 16.9341 --20.2769 -14.6266 16.6566 --21.2026 -14.9576 16.8346 --21.3421 -15.259 15.9106 --21.8675 -14.5042 15.4322 --21.2252 -14.3667 14.6204 --20.2483 -14.3586 14.2852 --20.1064 -13.3779 14.3925 --20.1835 -13.0456 15.2669 --20.515 -12.3431 15.9907 --20.2812 -11.5879 15.462 --21.2773 -11.3453 15.0964 --21.7985 -10.6008 15.445 --21.4939 -10.7128 16.3995 --20.692 -10.2363 16.9441 --20.654 -9.77944 17.8815 --21.5376 -10.1128 18.1064 --22.0979 -10.9348 18.1857 --22.6792 -11.6444 18.6224 --22.5154 -12.2933 19.4096 --22.5723 -11.7236 20.2381 --23.2694 -12.1977 20.8684 --22.4455 -12.7398 20.9281 --23.1573 -13.1984 20.4309 --23.3559 -13.9609 19.7631 --23.2379 -13.2547 19.1031 --23.4759 -13.8726 18.3867 --24.4327 -13.8269 18.656 --25.4578 -13.6325 18.8294 --25.5707 -13.6451 19.8314 --24.9504 -12.9648 20.2063 --25.1186 -12.0285 20.4371 --25.9551 -11.5178 20.3335 --25.876 -10.9292 21.0863 --25.2456 -10.4434 21.6051 --24.9783 -11.4033 21.5771 --24.4422 -12.192 21.7103 --23.6387 -11.5575 21.7145 --23.4415 -10.8955 20.9646 --23.0785 -10.461 21.8559 --23.1605 -9.87577 22.6797 --23.0962 -10.4397 23.4798 --22.6508 -11.1436 22.9126 --21.876 -11.4645 23.4086 --21.7159 -11.6546 24.3664 --21.2289 -12.3501 24.8992 --20.9433 -11.468 25.3777 --21.4905 -10.7767 25.8702 --21.303 -10.5342 26.7716 --20.433 -10.9788 26.8105 --20.1955 -10.2023 26.1829 --19.4408 -10.3201 26.8463 --19.0637 -9.44911 27.1705 --19.5797 -8.90732 26.4761 --20.497 -8.6222 26.6891 --20.7885 -7.82599 26.2452 --21.4229 -7.92819 25.425 --21.7291 -7.05132 25.0931 --22.4997 -7.40124 25.683 --22.6616 -7.59947 24.7542 --22.5917 -7.12027 23.9675 --22.4931 -7.4293 22.9852 --23.2204 -7.22561 22.3092 --22.7929 -6.70239 21.5699 --22.7681 -6.3387 20.6226 --23.4158 -6.76184 19.9514 --23.3657 -5.80011 19.8908 --23.8214 -5.03201 19.5487 --24.2249 -5.57196 18.8657 --24.8174 -5.87683 19.675 --25.5617 -5.95881 20.2926 --24.9291 -5.93948 21.0136 --24.0678 -5.71726 21.4522 --23.7052 -5.66963 22.3666 --23.071 -5.13882 21.9123 --22.9869 -5.02625 22.9209 --22.3019 -5.75401 22.8445 --21.5147 -6.27022 23.0202 --20.8394 -6.72651 23.6688 --20.303 -7.46143 24.0319 --19.3662 -7.30051 24.4012 --19.4187 -7.23002 25.3772 --18.6602 -7.79517 25.0335 --18.1273 -8.58633 25.0186 --17.3517 -8.9683 24.5408 --17.0837 -9.64125 23.7853 --16.1265 -9.96092 24.0671 --15.3586 -9.4639 23.7846 --15.624 -9.09088 24.6663 --15.8706 -8.26117 24.1895 --16.2806 -7.55833 24.6397 --16.2503 -7.04426 23.8273 --16.1328 -6.62698 22.8536 --16.8318 -6.23575 22.2791 --16.8299 -5.34595 21.8877 --15.9808 -4.87865 21.863 --15.4175 -5.65394 22.0081 --15.0505 -6.44001 22.4856 --14.84 -5.72865 23.0758 --13.8677 -6.15882 23.0146 --13.1397 -5.98502 22.282 --13.0941 -5.12391 21.793 --13.5292 -5.67529 21.044 --13.7913 -6.60061 21.0412 --13.6184 -7.23404 20.2868 --13.1319 -7.88142 20.9542 --12.3106 -7.98622 21.4035 --12.1476 -7.80767 22.3451 --12.3106 -8.33743 23.1602 --11.3976 -8.19743 23.4937 --10.6271 -7.77336 23.0571 --11.2756 -6.9686 22.9895 --12.3022 -6.74315 22.9404 --12.8889 -7.44288 23.2993 --12.1911 -6.94348 23.9019 --11.522 -7.4256 24.4598 --10.8649 -7.58938 25.1334 --10.8823 -8.45499 24.7193 --9.92946 -8.64666 24.8669 --10.0608 -9.18774 25.7178 --9.26556 -9.6382 25.3365 --8.475 -9.34272 25.8805 --8.87636 -8.43431 25.9445 --8.54313 -8.44303 25.0122 --8.68253 -7.54128 25.3381 --8.5132 -7.146 24.3579 --9.35516 -6.59228 24.4788 --8.84671 -6.39116 23.6097 --7.99895 -6.35855 23.0846 --7.88448 -6.88183 22.19 --6.89793 -6.75182 21.8784 --6.26864 -6.99816 22.6544 --6.68149 -7.77815 22.9729 --7.3633 -8.06454 23.6666 --7.97337 -7.39204 23.2191 --8.63881 -7.92766 23.661 --8.99322 -8.76848 24.095 --9.76219 -9.4128 24.0899 --9.72335 -10.2925 23.6721 --10.5807 -10.7911 23.7854 --10.9255 -10.7031 24.7423 --10.5605 -10.4276 25.6299 --10.6524 -10.427 26.6021 --10.7348 -11.4241 26.3535 --11.1754 -12.3096 26.5236 --11.3409 -12.2899 25.4973 --11.0069 -13.0497 24.8685 --9.99027 -13.0507 25.0812 --9.43625 -12.2813 24.7316 --8.64563 -12.4617 25.2939 --8.55912 -13.1647 24.568 --8.56346 -13.3295 23.5321 --8.07098 -13.5159 22.661 --7.75684 -12.5524 22.8464 --7.78074 -11.5666 22.7628 --8.6118 -11.2963 22.3509 --7.96638 -10.4891 22.3557 --8.72854 -10.157 22.8887 --9.58592 -9.99251 22.368 --9.54366 -9.85945 21.3744 --8.62648 -9.41592 21.0322 --8.72938 -10.3802 21.3882 --7.84309 -10.6841 21.1092 --7.89715 -10.112 20.3013 --7.01173 -9.67758 20.638 --6.25085 -9.31552 21.1516 --6.77076 -8.44659 21.2927 --6.58973 -8.54534 20.3003 --6.52735 -7.98891 19.4617 --6.77199 -7.62752 18.5687 --6.95144 -7.00528 19.3177 --6.69129 -6.03699 19.4183 --5.9621 -5.98704 20.2022 --5.25744 -5.3858 19.6458 --5.87893 -5.20311 18.8712 --6.47162 -4.47113 18.5365 --6.88199 -3.91654 17.8393 --7.23761 -4.80785 17.5495 --8.12624 -4.51024 17.9324 --9.07345 -4.75816 18.1272 --9.66788 -5.51897 17.7675 --10.5639 -5.08309 17.5697 --10.0731 -4.76253 18.4181 --10.1913 -4.7029 19.4439 --10.6915 -5.51886 19.416 --10.0917 -6.15035 19.8272 --9.50178 -6.88919 20.1233 --8.52426 -7.14324 19.7996 --8.45161 -6.97396 18.7867 --8.81078 -7.07562 17.8277 --8.38704 -7.76464 17.2272 --8.80422 -7.62946 16.3327 --8.39979 -7.93653 15.4825 --8.05114 -8.82905 15.4812 --8.28114 -9.75574 15.1497 --8.97959 -9.36762 14.5247 --9.89542 -9.34574 14.871 --9.73039 -8.91341 15.7845 --10.3752 -8.87255 16.5613 --10.3599 -7.86416 16.3597 --11.3265 -7.84972 15.8942 --12.3186 -7.72608 16.2106 --12.9499 -6.92321 16.2028 --12.7351 -7.15484 17.186 --12.8097 -7.89174 17.9096 --12.7746 -7.91037 18.9275 --13.5501 -8.56062 18.8628 --14.3495 -8.80163 19.2871 --14.9009 -9.14188 20.0401 --14.5734 -9.85185 20.7145 --13.8939 -10.048 20.0459 --13.3633 -10.4018 19.1655 --12.4734 -10.7407 18.7963 --12.0398 -11.6115 18.8743 --12.4961 -11.6901 19.7345 --13.1879 -12.2574 20.2301 --13.9948 -12.1687 19.8259 --14.539 -12.1786 20.6512 --15.2155 -12.105 21.3049 --14.4407 -11.4568 21.5728 --14.9724 -10.6056 21.3467 --15.055 -10.6173 22.3641 --14.9821 -11.4167 22.8041 --15.94 -11.372 23.1827 --15.974 -12.2738 22.7926 --16.2737 -13.1435 23.1906 --17.1505 -13.0583 22.8491 --17.023 -14.018 22.7491 --16.9612 -14.9577 22.3334 --16.6308 -15.6678 22.8782 --16.543 -15.4906 23.8701 --15.6579 -15.2354 23.6288 --15.3509 -14.233 23.7797 --14.5266 -13.8087 24.1113 --13.619 -13.6441 23.6613 --13.4555 -12.7003 23.7173 --14.0966 -11.9588 23.7972 --14.4793 -12.2022 24.6443 --15.4839 -12.3055 24.9095 --15.8294 -11.3123 24.9249 --15.4906 -10.4806 25.4167 --14.7888 -9.90048 25.1738 --14.8462 -10.4824 24.3447 --13.8945 -10.2966 24.6139 --13.3354 -10.6145 25.4171 --13.5112 -9.60895 25.2843 --12.6915 -9.31112 24.8737 --12.0937 -9.68026 25.633 --12.1601 -10.2951 26.3733 --11.8913 -10.5554 27.3399 --12.6401 -11.2411 27.111 --12.7128 -11.8584 26.3429 --13.0572 -12.6683 25.8101 --12.7667 -13.07 26.7037 --13.7584 -13.1668 26.9926 --13.3018 -13.2807 27.85 --13.7195 -12.7147 28.4569 --14.1759 -12.2872 29.2316 --13.6923 -11.4739 28.8769 --14.4353 -11.3904 28.1861 --14.6913 -10.4763 27.9851 --13.9752 -9.90171 28.2723 --12.9442 -9.9411 28.1352 --12.776 -9.98031 29.0935 --12.7506 -10.1391 30.0842 --12.592 -10.8268 30.7909 --12.4352 -10.5791 31.729 --12.706 -9.72422 31.2908 --12.4446 -8.84752 31.7444 --12.4602 -7.89314 31.4568 --11.8107 -7.82755 30.6483 --11.4676 -6.85624 30.7978 --11.2739 -6.17709 30.1011 --10.3384 -6.47646 29.9639 --10.8872 -7.25832 29.5934 --10.7392 -7.92567 30.3007 --10.9245 -8.52177 29.5084 --10.4337 -8.11911 28.7592 --10.5782 -8.1771 27.7933 --11.3223 -8.11876 27.1622 --11.1668 -7.47903 26.4067 --11.8484 -6.97418 25.9909 --12.7121 -6.95536 26.4379 --12.2262 -6.11749 26.6943 --12.7724 -5.32829 27.0418 --13.0548 -4.65336 26.3032 --13.1012 -4.18886 25.3584 --12.4986 -4.75048 24.8162 --11.7017 -4.53946 24.2716 --12.0264 -3.64389 24.055 --12.0688 -3.92831 23.0334 --12.0435 -3.14987 22.4682 --11.3999 -2.6444 23.0745 --11.4227 -2.59358 24.0787 --11.3753 -2.4753 25.0866 --12.2667 -2.06435 24.8185 --12.5848 -1.81631 23.8717 --12.0096 -1.68228 23.1234 --11.9091 -1.86169 22.1114 --11.0285 -2.25799 22.1598 --10.559 -1.57914 21.5817 --10.8128 -2.06642 20.7531 --10.4803 -3.02095 20.5875 --10.401 -3.59043 19.7656 --11.1343 -4.26348 20.0563 --12.0449 -4.4754 20.3364 --11.8838 -3.45458 20.6074 --12.4225 -2.91007 21.2617 --13.019 -2.74261 22.0016 --13.1923 -3.26322 22.7933 --14.2001 -3.46362 22.7229 --14.4232 -2.94191 21.9151 --14.9467 -3.18348 21.0548 --14.8441 -4.09531 20.7972 --15.5072 -3.69947 20.1486 --15.7368 -4.23401 19.3423 --16.1448 -4.05363 18.4323 --15.8052 -4.80459 17.8201 --16.3903 -5.46796 17.4357 --17.2901 -5.38252 17.1133 --18.0764 -5.23962 17.7126 --18.6074 -6.03023 17.9997 --19.2671 -6.6645 18.0932 --19.9199 -7.38276 17.883 --20.2001 -7.98733 18.6157 --19.8692 -8.67504 18.0391 --19.5243 -8.7733 19.0198 --20.3166 -9.23116 19.4277 --20.0842 -10.2228 19.5742 --19.4385 -10.2009 18.8354 --19.3343 -10.2716 17.8946 --19.1319 -11.0613 17.2941 --18.4564 -11.164 16.5692 --17.4024 -11.1156 16.6734 --17.3879 -11.131 15.6775 --17.9397 -10.4549 15.2394 --17.8559 -10.5041 14.2974 --17.9709 -11.3806 13.9071 --17.3818 -11.961 13.2727 --16.5816 -12.5189 13.7007 --15.7899 -12.0165 14.0791 --14.8625 -12.0951 13.8824 --14.8263 -11.153 13.702 --15.4132 -10.6632 12.9975 --15.9967 -11.3467 12.5275 --16.2252 -11.0667 11.5492 --15.4034 -10.4851 11.2336 --15.7317 -9.8602 10.4954 --16.3598 -9.79076 9.69623 --16.6558 -9.47758 8.86158 --16.9034 -8.51422 9.16669 --17.1514 -8.18166 10.0722 --17.9136 -7.65713 9.7389 --18.4221 -7.54334 8.89693 --18.9739 -7.35429 8.04365 --19.5353 -7.78264 7.34318 --18.5828 -7.98184 7.05121 --17.5422 -8.01225 6.88422 --17.4067 -7.04716 6.9567 --17.7364 -6.22406 6.40823 --17.6647 -7.15582 5.95328 --18.0995 -7.3024 5.15454 --19.123 -7.40957 5.258 --19.3571 -8.4383 5.1358 --18.4206 -8.69245 5.04938 --18.8868 -9.18479 4.36119 --19.5662 -9.84982 4.68354 --18.928 -9.86664 5.36154 --18.1402 -10.3628 5.82505 --17.8677 -10.9856 6.57123 --17.2168 -11.2934 7.26523 --17.5769 -10.6648 7.99151 --18.2202 -10.5203 8.62465 --18.8863 -10.9446 7.97711 --18.6643 -11.6209 8.69037 --17.6858 -11.5833 9.06897 --18.169 -12.3931 9.43196 --17.2372 -12.8759 9.35416 --16.3767 -12.327 9.34308 --15.8093 -12.878 9.89257 --15.7391 -13.695 9.41949 --16.2584 -14.5249 9.02677 --16.4353 -13.7727 8.36688 --16.708 -13.2385 7.56292 --15.9808 -12.6088 7.33496 --14.93 -12.4963 7.4124 --14.0421 -12.7034 7.09583 --13.4657 -12.8725 7.81163 --13.2073 -13.4659 7.03725 --13.6635 -13.6677 6.10394 --14.5061 -14.1862 5.85012 --14.0589 -13.7359 5.13811 --14.3586 -13.5461 4.20289 --13.7307 -14.0883 3.65636 --14.2577 -13.3186 3.12609 --15.0485 -12.8493 2.95356 --14.815 -11.8899 3.16312 --15.5913 -11.3731 3.30834 --16.284 -10.6567 3.01516 --16.4799 -10.0128 3.72987 --17.4047 -10.3474 3.60083 --17.7145 -11.3193 3.40233 --17.8889 -11.2387 2.38898 --18.8365 -10.9893 2.35673 --19.2202 -10.0996 2.55681 --19.4736 -9.87045 3.48042 --19.5157 -8.9874 2.92432 --19.3594 -8.35047 3.72188 --18.479 -7.74866 3.74324 --18.0082 -7.04627 3.14702 --18.1096 -6.77018 4.10902 --18.4375 -5.89883 4.39956 --17.6916 -5.85959 3.76617 --16.8817 -6.07979 3.30263 --15.8755 -6.31547 3.34363 --15.3912 -5.6536 3.87336 --15.7007 -5.58853 4.81143 --16.0415 -6.30549 5.55861 --15.9028 -7.01093 6.18353 --15.2602 -7.67732 5.79662 --15.0215 -7.64629 4.79729 --14.8575 -7.63943 3.80743 --14.595 -8.07339 2.9713 --15.0289 -7.20545 2.80891 --15.5401 -7.64142 2.01924 --15.8021 -8.05141 1.16597 --14.953 -8.50671 1.52955 --15.6337 -8.84338 2.26251 --15.5121 -9.72314 2.86245 --14.924 -10.1041 2.13461 --15.6794 -10.7311 2.02913 --15.23 -11.6146 2.0006 --16.1379 -11.8946 2.00282 --16.7927 -12.3432 2.66807 --17.0449 -13.0291 2.02622 --17.262 -13.3969 1.08434 --17.7444 -13.7664 1.84922 --18.5771 -14.2984 1.54221 --19.2692 -13.788 2.00877 --18.8916 -14.1964 2.80971 --19.2573 -13.3565 3.25119 --18.8947 -12.5911 2.87434 --19.0372 -12.7262 1.92061 --19.078 -12.4863 0.9606911 --19.1666 -12.8393 0.01094332 --19.9425 -13.4201 0.02750622 --20.2017 -12.9685 -0.7489729 --20.5391 -12.0617 -1.12257 --19.5228 -12.2508 -1.02169 --18.878 -11.5984 -0.7495329 --18.4902 -11.0235 -0.1191279 --17.5753 -10.5778 -0.4269879 --16.6481 -10.484 -0.08099628 --15.9208 -11.115 -0.1107389 --14.9639 -11.0593 0.2473411 --15.2254 -10.352 0.9017971 --15.0128 -9.4141 0.5678031 --15.2243 -8.91337 -0.2213079 --14.4357 -8.41789 0.05288872 --14.9062 -7.61987 0.3556751 --15.3704 -6.75526 0.5436391 --16.1359 -6.4294 1.02381 --16.2401 -5.67312 1.58794 --16.8932 -6.14203 2.09978 --16.8832 -7.14329 2.07646 --17.0415 -8.13897 1.9131 --16.727 -8.93318 1.37605 --16.2795 -9.00624 0.4360171 --17.261 -8.83958 0.2443261 --17.9771 -8.35304 -0.2831419 --17.6254 -7.4618 -0.5650039 --17.058 -6.62278 -0.8506389 --17.2646 -5.65965 -0.6844559 --17.9705 -6.1158 -1.24358 --18.5333 -6.44615 -1.97525 --17.8681 -6.49678 -2.74695 --17.802 -6.795 -3.70499 --18.6053 -6.25349 -3.42826 --18.6125 -5.24346 -3.27733 --18.066 -4.79734 -4.01595 --18.8342 -4.17637 -3.85408 --18.9706 -4.51385 -4.79125 --19.3243 -5.21392 -5.4699 --19.8725 -5.99635 -5.39059 --19.1327 -6.65718 -5.3248 --18.3803 -7.34925 -5.48122 --18.3687 -8.37562 -5.30182 --17.5574 -8.11834 -5.78981 --17.2588 -7.27937 -6.20958 --18.0258 -6.83771 -6.68384 --18.0607 -5.93849 -6.21315 --17.1578 -6.29659 -6.45402 --17.7706 -5.60213 -6.99269 --17.6282 -5.12089 -7.88915 --16.6785 -5.10921 -7.94746 --16.2191 -5.84324 -7.60147 --15.6737 -5.69921 -8.49004 --14.9898 -5.07629 -8.69215 --14.2561 -5.69313 -8.94822 --13.3916 -5.14971 -9.01518 --12.55 -4.62941 -8.67044 --11.9107 -4.65164 -9.45559 --11.9755 -3.70739 -9.53065 --12.1684 -2.79261 -9.06541 --13.072 -2.85207 -9.46023 --13.0864 -3.44881 -8.60713 --13.9591 -3.26053 -9.14504 --14.1503 -3.92701 -8.36496 --14.9291 -3.70891 -8.95277 --15.2839 -3.53075 -8.05999 --16.2271 -3.41963 -7.76014 --17.1745 -3.52467 -7.36912 --17.462 -3.36917 -6.4266 --16.4947 -3.26251 -6.20248 --16.0781 -4.25785 -6.38463 --15.1869 -4.56692 -6.75814 --14.4118 -4.20819 -7.22915 --14.4164 -5.16593 -7.47513 --14.1406 -6.05357 -7.50263 --14.3648 -6.22788 -6.52053 --15.1773 -5.83078 -6.15556 --15.4744 -5.06855 -5.5926 --16.3414 -4.69841 -5.18431 --16.4251 -5.5353 -4.62981 --16.518 -6.33316 -3.97281 --16.7132 -6.95145 -3.20446 --16.3473 -7.44269 -3.98513 --17.0442 -8.10241 -3.82256 --17.4463 -9.03437 -3.97039 --17.182 -9.74464 -3.40873 --16.2472 -9.46887 -3.11862 --15.9342 -10.1372 -3.77919 --16.1449 -11.1775 -3.91878 --15.9684 -11.1982 -4.96147 --16.4456 -11.7821 -5.57034 --17.412 -11.5047 -5.65659 --17.877 -11.1857 -6.47036 --18.5086 -10.8761 -7.18474 --19.518 -10.9205 -7.05448 --20.2377 -11.3981 -7.41556 --20.8019 -12.0096 -8.03957 --20.5975 -12.9392 -7.72241 --20.3029 -13.1653 -6.74794 --20.7535 -12.897 -5.88058 --20.7381 -13.8678 -5.49862 --20.0035 -13.255 -5.40206 --19.6195 -12.3737 -5.44454 --19.3345 -12.1513 -4.53613 --18.5603 -12.6606 -4.17183 --18.751 -12.0942 -3.32654 --17.8015 -11.8378 -3.62336 --17.7644 -11.1347 -2.92758 --17.5999 -11.3204 -1.97151 --16.9838 -11.5329 -1.25655 --16.4929 -12.3701 -1.22113 --16.3407 -13.0503 -1.94762 --16.9218 -13.6103 -1.26664 --17.2174 -14.2967 -1.87939 --16.7642 -14.6161 -1.02679 --17.5262 -14.6179 -0.2676219 --18.524 -14.5808 -0.01440028 --18.3591 -13.6411 -0.1706759 --18.8882 -13.517 -1.00386 --19.4842 -13.8192 -1.77767 --19.2044 -12.9459 -2.19962 --18.4029 -12.2898 -2.16865 --18.0908 -13.2077 -2.36105 --18.2333 -14.1323 -2.08134 --18.8586 -13.9902 -2.80542 --19.0883 -14.7135 -3.50955 --18.2839 -15.256 -3.32026 --18.3209 -15.8923 -2.47859 --17.6021 -15.8769 -1.82759 --16.7083 -15.6773 -2.32738 --16.7014 -16.0352 -1.44363 --16.4211 -16.2315 -0.4430339 --17.1477 -16.8488 -0.1877479 --17.167 -17.6278 0.4337811 --16.861 -18.0754 1.2904 --17.6047 -17.788 1.80629 --17.6229 -17.0618 2.45654 --18.6084 -17.3201 2.47297 --19.2016 -16.9174 1.70555 --18.8674 -16.8098 0.8007271 --18.8294 -15.8853 0.4150321 --19.5529 -15.266 0.5794591 --19.7042 -14.9409 1.55854 --20.536 -14.6914 1.06234 --21.1002 -15.3471 1.62685 --22.0746 -15.765 1.80648 --22.4927 -14.9835 2.27899 --22.6096 -14.006 1.95844 --22.5236 -13.0623 1.98658 --22.6799 -12.8275 1.02312 --22.1896 -12.2068 1.60314 --21.6665 -11.3148 1.79851 --21.2978 -10.7213 1.16423 --20.7986 -10.272 1.9968 --20.9159 -10.5977 2.97381 --20.1285 -10.982 3.54118 --20.8203 -11.3228 4.13951 --20.2017 -10.6704 4.49365 --20.6835 -11.0611 5.34768 --20.8511 -11.9998 5.57333 --21.8526 -11.8397 5.41481 --21.9526 -12.5821 6.08797 --22.8295 -12.2875 6.52534 --23.1368 -11.3705 6.34837 --22.2961 -11.3946 6.87562 --21.844 -10.9842 7.56685 --21.9915 -11.4163 8.46386 --22.827 -12.0585 8.3727 --22.2571 -12.5046 9.05202 --21.9944 -13.3021 9.51221 --22.9378 -13.517 9.14622 --23.9079 -13.8427 9.2615 --24.3702 -13.0761 8.6829 --24.9555 -13.5982 8.10246 --25.4204 -14.3529 7.54206 --25.8092 -15.1807 7.13748 --26.5197 -15.901 7.27795 --27.0284 -16.0673 8.10792 --26.6683 -15.1575 8.33945 --26.0209 -14.4598 8.66714 --25.7611 -13.7258 9.31001 --25.4286 -13.9632 10.2178 --25.6033 -14.7569 9.7819 --24.7775 -15.0775 9.2928 --24.7076 -15.8936 8.8172 --24.1289 -16.5151 9.42323 --24.3925 -17.1213 10.1547 --23.5673 -17.6156 10.0587 --22.6976 -18.1315 10.0034 --22.2642 -17.9675 9.12324 --22.8581 -18.5158 8.59345 --22.1849 -19.2428 8.42504 --23.0899 -19.243 7.95142 --24.0782 -19.3861 7.72719 --24.0992 -20.1718 7.02174 --24.4663 -20.899 7.61354 --24.1845 -21.9016 7.82978 --23.1899 -21.7722 7.61118 --22.8199 -21.9008 6.75469 --22.4817 -20.9476 6.61434 --23.2397 -20.8565 5.96029 --24.1189 -21.3763 5.81774 --24.1471 -22.2542 5.33011 --23.2495 -22.5661 5.07807 --22.2767 -22.3499 5.1588 --22.236 -21.603 4.43457 --22.1575 -21.1807 5.42874 --21.2758 -20.7228 5.74039 --21.7909 -19.892 5.69952 --21.662 -19.6551 4.71008 --21.8475 -19.0744 3.97977 --21.9095 -18.4841 4.80406 --20.8704 -18.7249 4.85504 --20.6593 -17.7463 4.69751 --20.7583 -17.6991 5.72459 --20.2781 -17.7523 6.64265 --19.6909 -17.8401 7.45255 --19.6183 -16.8502 7.55147 --20.0272 -16.1811 6.85039 --20.7177 -15.4989 6.70258 --20.0271 -14.868 7.0509 --20.0891 -13.8671 6.75451 --20.3426 -13.8064 7.7883 --20.2222 -14.5718 8.44451 --19.5391 -14.3686 9.11965 --18.6989 -14.6208 8.60513 --18.1485 -14.1603 7.96201 --18.7457 -13.3924 7.93491 --18.604 -13.0846 6.97472 --18.926 -13.6583 6.23641 --18.2356 -14.1621 5.62244 --17.8578 -13.2786 5.51122 --17.2634 -12.5949 5.02639 --16.4796 -12.1079 4.67754 --15.5677 -11.7076 4.50541 --14.6414 -11.2841 4.58037 --15.0051 -10.6528 5.18583 --14.2951 -11.0756 5.70686 --14.0702 -11.9169 5.21958 --13.6892 -12.3722 4.42763 --13.1195 -11.6957 3.81921 --12.5624 -12.1939 3.15205 --12.322 -13.1602 3.23067 --11.6648 -13.2714 4.00083 --11.7563 -12.4 4.53912 --11.7976 -11.482 4.15239 --11.1524 -11.1616 3.47078 --11.7528 -10.6017 2.8644 --12.7139 -10.913 2.9438 --12.5803 -10.3437 2.10094 --11.6701 -10.6091 1.70348 --11.3316 -11.5911 1.73756 --10.749 -11.898 0.9526371 --10.5551 -12.7077 1.548 --10.9885 -13.2144 0.8109861 --11.3604 -12.5737 0.1236011 --10.7736 -11.8306 -0.1829209 --10.1609 -12.4889 0.02782242 --9.44033 -12.9272 0.5497491 --9.08814 -12.1416 0.1162441 --8.3989 -12.1433 -0.6025449 --8.3176 -12.9172 -0.06511018 --8.50949 -12.8249 0.9439171 --8.47264 -13.7168 1.42527 --8.3198 -13.9101 2.36208 --8.7295 -14.6818 2.65583 --8.37203 -15.619 2.55081 --8.68207 -16.1834 1.72766 --8.18224 -16.7351 1.00774 --8.57297 -16.7215 0.1399021 --7.97885 -16.744 -0.6450729 --7.43054 -17.217 -1.34063 --6.71517 -17.7187 -1.63362 --6.62189 -17.8027 -0.6146229 --6.50536 -17.2932 0.2981031 --6.02331 -16.8521 1.09006 --5.35079 -16.3477 0.4553941 --6.11783 -16.2396 -0.2509479 --6.54796 -15.6138 0.4008321 --6.48742 -15.6361 1.42974 --7.13988 -15.2444 2.17204 --7.3448 -15.2186 3.1547 --6.9691 -15.2354 4.06684 --6.69408 -16.1796 3.88808 --6.26311 -16.7761 3.28375 --5.7262 -17.6232 3.67206 --5.53528 -18.5636 3.38286 --6.14371 -18.2428 2.69458 --5.18081 -18.4872 2.38342 --4.42132 -18.1866 1.86216 --3.96041 -17.5998 1.17445 --3.63592 -16.6552 1.07837 --3.80473 -16.7126 0.09609402 --3.1401 -16.3779 -0.5458699 --2.51979 -16.9387 -0.06550528 --2.44478 -17.912 0.1262581 --1.58416 -17.8928 0.6103961 --1.02168 -17.1028 0.8116451 --0.698401 -17.2784 1.66179 --1.29405 -16.4718 1.7535 --1.20491 -16.6565 2.70536 --1.83627 -17.3383 2.51024 --2.41765 -16.9109 1.83713 --2.93634 -16.0722 1.92531 --3.30215 -15.1277 1.85612 --2.68966 -14.6529 1.19532 --2.09517 -13.8614 0.8158601 --1.59787 -14.6848 0.9300581 --0.979176 -14.633 0.2424121 --1.43266 -15.3157 -0.3772699 --1.38441 -15.8767 -1.15919 --1.63294 -16.6299 -1.84423 --0.979846 -17.3623 -1.62137 --0.26691 -16.8839 -1.05171 --0.01836083 -17.7326 -0.5577269 -0.311614 -18.6345 -0.2386659 --0.300772 -19.1707 0.3533641 --0.45909 -18.9769 1.33908 --0.765792 -18.7706 2.27261 --0.267866 -17.9749 2.66323 --0.476554 -17.9033 3.65093 --0.04862893 -18.6448 4.1154 -0.160754 -19.1816 3.32306 -0.432145 -20.0162 2.86337 -1.35828 -19.9421 3.20509 -0.918236 -20.851 3.25794 -1.00792 -21.6939 3.71865 -0.01846787 -21.9635 3.63551 --0.03478893 -22.8796 3.965 --0.44018 -23.3375 4.74781 --1.29316 -23.6069 5.09817 --1.4422 -23.8758 4.1608 --2.18571 -24.2742 3.69094 --2.84799 -23.7683 4.21335 --2.42618 -22.9348 3.90019 --2.46041 -23.2094 2.95356 --2.39758 -23.2739 1.94176 --2.98297 -22.9221 1.19968 --2.92175 -22.2346 0.5027861 --2.61479 -21.406 0.08836602 --1.72104 -21.5423 0.5203291 --1.36492 -20.7139 0.2088941 --0.681441 -21.3719 0.3890411 -0.221378 -21.737 -0.08934318 --0.01296833 -21.8795 0.8959241 -0.596142 -22.5959 0.6715991 -1.40294 -23.0858 0.4111251 -1.38058 -23.6248 -0.4516429 -1.35347 -24.6271 -0.3329969 -0.476824 -24.7115 0.2140341 --0.118841 -23.9082 0.1092351 -0.162551 -23.5464 0.9382481 --0.528495 -22.8752 0.7937701 --1.22243 -22.4509 0.1072601 --1.94009 -22.2481 -0.5394919 --2.14375 -23.1794 -0.9199809 --2.68979 -23.5751 -1.67526 --3.13772 -24.1382 -2.39865 --3.03463 -25.1308 -2.13476 --3.52823 -25.2435 -2.97538 --4.11751 -24.541 -2.92176 --4.98222 -25.145 -2.96032 --5.28442 -25.6283 -3.73908 --6.24526 -25.5695 -3.52539 --5.69793 -26.1943 -2.89561 --6.10714 -26.8499 -2.29479 --5.51818 -27.2647 -2.97214 --5.18347 -27.0796 -3.90706 --4.28836 -27.3998 -4.09418 --3.36446 -27.6429 -4.18591 --2.82066 -26.8267 -4.15093 --2.53327 -26.1742 -3.36111 --2.53883 -25.7304 -4.16075 --1.83245 -25.1139 -4.50631 --0.970865 -25.526 -4.44269 --1.28663 -26.2739 -3.85732 --1.59705 -27.0396 -4.42883 --1.52632 -27.7935 -5.0979 --0.800441 -28.4785 -5.12727 --0.744699 -28.3136 -6.13472 --0.720131 -29.1246 -6.65237 --0.629731 -28.78 -7.55645 --0.377451 -29.4107 -8.29517 --0.996488 -29.4598 -8.99045 --0.599697 -30.4016 -9.05727 --1.05784 -30.574 -9.88977 --0.277431 -31.1161 -10.1052 -0.408644 -30.4338 -10.2678 -0.978395 -29.7866 -9.76467 -1.29804 -30.5431 -9.27597 -1.76449 -30.7711 -10.1503 -2.72658 -30.573 -10.0078 -3.25293 -30.1211 -9.28215 -3.51152 -30.303 -8.42115 -3.31075 -29.2896 -8.29259 -2.46667 -29.6373 -8.74994 -2.01793 -29.7625 -9.58242 -1.81954 -28.8668 -9.90537 -2.65316 -28.6716 -9.44185 -2.33536 -27.7881 -9.76625 -3.34896 -27.4633 -10.0527 -3.97128 -27.7919 -10.8043 -4.30927 -26.8921 -11.1651 -4.7887 -26.0184 -11.3504 -5.70995 -26.1383 -11.3205 -6.10342 -26.3904 -12.1577 -5.41486 -27.146 -12.2684 -5.54559 -27.9474 -11.7159 -5.04998 -28.5559 -12.2761 -4.11678 -29.0272 -12.3376 -3.28746 -28.39 -12.1586 -2.77907 -28.9011 -12.8448 -2.71111 -28.2776 -13.6278 -2.54822 -28.9496 -14.3251 -3.32498 -28.3929 -14.7103 -4.30863 -28.4893 -14.4465 -5.15146 -27.9711 -14.1983 -5.91513 -27.4989 -13.7535 -6.60183 -27.5979 -14.4791 -7.30611 -28.0657 -15.0896 -7.61482 -28.5404 -15.9428 -6.72906 -29.0013 -16.1311 -6.57845 -29.3164 -17.1116 -5.7474 -29.6489 -17.5644 -5.21519 -30.3931 -17.9417 -4.76158 -29.5123 -17.877 -5.11433 -28.5404 -18.0793 -4.61588 -27.7529 -17.694 -4.30396 -27.9973 -16.7823 -4.87471 -28.7588 -17.0524 -4.37257 -29.4196 -16.515 -4.34907 -30.36 -16.7674 -3.71661 -31.1385 -16.8334 -3.18788 -31.4624 -17.6259 -3.09708 -30.8725 -18.4167 -2.63163 -30.0338 -18.7512 -1.81601 -29.8788 -19.3065 -1.39484 -28.9596 -19.4089 -1.64554 -27.9775 -19.4681 -2.59088 -27.7061 -19.6773 -3.53325 -27.469 -19.8316 -3.70637 -27.0416 -20.7882 -3.97953 -26.526 -21.6369 -4.00849 -25.6369 -22.0054 -4.67819 -24.9864 -22.411 -5.00228 -24.615 -23.2314 -5.30182 -25.4954 -23.6215 -5.18228 -25.8779 -24.57 -4.65137 -26.3726 -25.2504 -5.00133 -27.2703 -24.9781 -5.68137 -27.0381 -25.6138 -5.54698 -26.2542 -26.1818 -4.80806 -26.1418 -26.771 -4.78139 -25.1744 -27.0733 -5.18275 -25.2179 -28.0197 -5.64785 -26.1033 -28.3246 -5.11108 -26.9582 -28.3317 diff --git a/tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/moltemplate_files/generate_system_lt.py b/tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/moltemplate_files/generate_system_lt.py deleted file mode 100755 index 796347bb0b..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/moltemplate_files/generate_system_lt.py +++ /dev/null @@ -1,301 +0,0 @@ -#!/usr/bin/env python - -err_msg = """ -Usage: - - generate_system_lt.py n < monomer_coords.raw > system.lt - -Example: - - generate_system_lt.py 30118 47 < coords.raw > system.lt - -Explanation: - ARGUMENTS: - n = total length of the polymer (in monomers) - L = the (average) length of each condensin interval (Poisson- - distributed) This is also 1/probability that each monomer - is a "condensin monomer". - - (Note: 30117 ~= 128000/4.25, but using 30118 makes interpolation cleaner, - and 47 = 200/4.25. Note that 128000 and 200 are for the 10nm model. - See the supplemental section of Naumova et al Science 2013, p 18.) - -""" - - -import sys -import random -from math import * - -# Parse the argument list: -if len(sys.argv) <= 2: - sys.stderr.write("Error:\n\nTypical Usage:\n\n"+err_msg+"\n") - exit(1) -N=int(sys.argv[1]) -L=float(sys.argv[2]) -if len(sys.argv) > 3: - delta_x = float(sys.argv[3]) -else: - delta_x = 2.0 -if len(sys.argv) > 4: - x_offset = float(sys.argv[4]) -else: - x_offset = -((N-1.0)/2) * delta_x - - -coords = [[0.0, 0.0, 0.0] for i in range(0,N)] -lines = sys.stdin.readlines() -if len(lines) != N: - sys.stderr.write("Error: Number of lines in input file ("+str(len(lines))+")\n" - " does not match first argument ("+str(N)+")\n") - exit(1) -for i in range(0, N): - coords[i] = map(float, lines[i].split()) - -# Now calculate the box_boundaries: -box_bounds_min = [0.0, 0.0, 0.0] -box_bounds_max = [0.0, 0.0, 0.0] -for i in range(0, N): - for d in range(0, 3): - if i == 0: - box_bounds_min[d] = coords[i][d] - box_bounds_max[d] = coords[i][d] - else: - if coords[i][d] > box_bounds_max[d]: - box_bounds_max[d] = coords[i][d] - if coords[i][d] < box_bounds_min[d]: - box_bounds_min[d] = coords[i][d] - -# Now scale the box boundaries outward by 50% -box_scale = 1.5 -for d in range(0,3): - box_bounds_cen = 0.5*(box_bounds_max[d] + box_bounds_min[d]) - box_bounds_width = box_bounds_max[d] - box_bounds_min[d] - box_bounds_min[d] = box_bounds_cen - 0.5*box_scale*box_bounds_width - box_bounds_max[d] = box_bounds_cen + 0.5*box_scale*box_bounds_width - -# Now calculate the direction each molecule should be pointing at: -direction_vects = [[0.0, 0.0, 0.0] for i in range(0,N)] -for d in range(0, 3): - direction_vects[0][d] = coords[1][d] - coords[0][d] - direction_vects[N-1][d] = coords[N-1][d] - coords[N-2][d] -for i in range(1, N-1): - for d in range(0, 3): - direction_vects[i][d] = coords[i+1][d] - coords[i-1][d] - -# Optional: normalize the direction vectors -for i in range(1, N-1): - direction_len = 0.0 - for d in range(0, 3): - direction_len += (direction_vects[i][d])**2 - direction_len = sqrt(direction_len) - for d in range(0, 3): - direction_vects[i][d] /= direction_len - -# Now, begin writing the text for the system.lt file: - -sys.stdout.write( -""" -import "monomer.lt" # <-- defines "Monomer" -import "condensin.lt" # <-- defines "CondensinMonomer" - - -""" -) - - - -# Figure out which monomers are "Monomers" and which monomers are -# "CondensinMonomers" - -ic = 0 # count the number of condensins added so far -condensin_is_here = [False for i in range(0, N)] -for i in range(0, N): - #add_condensin_here = random.random() < (1.0 / L) - add_condensin_here = random.random() < (1.0 / (L-2.0)) - - # We do not allow condensin at successive sites separated by less than 2 - # subunits (the "L-2.0" above is to compensate for this) - if (((i > 0) and condensin_is_here[i-1]) or - ((i > 1) and condensin_is_here[i-2])): - add_condensin_here = False - - if add_condensin_here: - condensin_is_here[i] = True - ic += 1 -Nc = ic - - -ic = 0 -for i in range(0, N): - if condensin_is_here[i]: - sys.stdout.write("condensins["+str(ic)+"] = new CondensinMonomer.scale(0.5,0.8,0.8).rotvv(1,0,0,") - ic+=1 - else: - sys.stdout.write("monomers["+str(i)+"] = new Monomer.scale(0.5,0.8,0.8).rotvv(1,0,0,") - sys.stdout.write(str(direction_vects[i][0])+"," - +str(direction_vects[i][1])+"," - +str(direction_vects[i][2])+ - ").move(" - +str(coords[i][0])+"," - +str(coords[i][1])+"," - +str(coords[i][2])+")\n") - - #if condensin_is_here[i]: - # if i < N-1: - # sys.stdout.write("\n" - # "#(override the dihedral angle for this monomer)\n" - # "write(\"Data Dihedrals\") {\n" - # " $dihedral:twistor"+str(i+1)+" @dihedral:CondensinMonomer/TWISTOR $atom:monomers["+str(i)+"]/t $atom:monomers["+str(i)+"]/c $atom:monomers["+str(i+1)+"]/c $atom:monomers["+str(i+1)+"]/t\n" - # "}\n" - # "\n") - - - -sys.stdout.write( -""" - -# ---------------- simulation box ----------------- - -# Now define a box big enough to hold a polymer with this (initial) shape - -""" -) - - -sys.stdout.write("write_once(\"Data Boundary\") {\n" - +str(box_bounds_min[0])+" "+str(box_bounds_max[0])+" xlo xhi\n" - +str(box_bounds_min[1])+" "+str(box_bounds_max[1])+" ylo yhi\n" - +str(box_bounds_min[2])+" "+str(box_bounds_max[2])+" zlo zhi\n" - "}\n\n\n") - - -sys.stdout.write( -""" -# What kind of boundary conditions are we using? - -write_once("In Init") { - boundary s s s # <-- boundary conditions in x y z directions - #boundary p p p # <-- boundary conditions in x y z directions -} -# "p" stands for "periodic" -# "s" stands for "shrink-wrapped" (non-periodic) - - -# ---- Bonds ---- - - -write_once("In Settings") { - # 10nm model: - #bond_coeff @bond:backbone harmonic 100.0 1.0 - # 30nm fiber (4.25^(1/3)=1.6198059006387417) - bond_coeff @bond:backbone harmonic 100.0 1.6198059006387417 -} - - -""" -) - - -sys.stdout.write("write(\"Data Bonds\") {\n") - -# Old bond-loop was simple: -#for i in range(0, N-1): -# sys.stdout.write(" $bond:b"+str(i+1)+" @bond:backbone $atom:monomers["+str(i)+"]/a $atom:monomers["+str(i+1)+"]/a\n") - -ic = 0 -for i in range(0, N-1): - #sys.stderr.write("i="+str(i)+", ic="+str(ic)+", Nc="+str(Nc)+"\n") - - # Figure out if the first atom in the bond pair - # belongs to a regular Monomer or a CondensinMonomer - if condensin_is_here[i]: - sys.stdout.write(" $bond:b"+str(i+1)+" @bond:backbone $atom:condensins["+str(ic)+"]/a") - ic+=1 - else: - sys.stdout.write(" $bond:b"+str(i+1)+" @bond:backbone $atom:monomers["+str(i)+"]/a") - - # Do the same thing for the second atom in the bond pair - if condensin_is_here[i+1]: - assert(ic coords.raw - -Example: - - interpolate_coords.py 30118 3.0 < coords_orig.raw > coords.raw - - # (Note: 30117 ~= 128000/4.25, but using 30118 makes interpolation cleaner. - # See the supplemental section of Naumova et al Science 2013, p 18.) - -""" - - -import sys -from math import * - -# Parse the argument list: -if len(sys.argv) <= 1: - sys.stderr.write("Error:\n\nTypical Usage:\n\n"+err_msg+"\n") - exit(1) - -n_new = int(sys.argv[1]) - -if len(sys.argv) > 2: - scale = float(sys.argv[2]) -else: - scale = 1.0 - -coords_orig = [] - -lines = sys.stdin.readlines() - -for line in lines: - tokens = line.split() - if (len(tokens) > 0): - coords_orig.append(map(float, tokens)) - g_dim = len(tokens) - -n_orig = len(coords_orig) - -if n_orig < 2: - sys.stderr.write("Error:\n\nInput file contains less than two lines of coordinates\n") - exit(1) - -if n_new < 2: - sys.stderr.write("Error:\n\nOutput file will contain less than two lines of coordinates\n") - exit(1) - -coords_new = [[0.0 for d in range(0, g_dim)] for i in range(0, n_new)] - -for i_new in range(0, n_new): - I_orig = (i_new) * (float(n_orig-1) / float(n_new-1)) - i_orig = int(floor(I_orig)) - i_remainder = I_orig - i_orig - - if (i_new < n_new-1): - for d in range(0, g_dim): - coords_new[i_new][d] = scale*(coords_orig[i_orig][d] - + - i_remainder*(coords_orig[i_orig+1][d]- - coords_orig[i_orig][d])) - else: - for d in range(0, g_dim): - coords_new[i_new][d] = scale*coords_orig[n_orig-1][d] - - # print the coordates - for d in range(0, g_dim-1): - sys.stdout.write(str(coords_new[i_new][d]) + ' ') - sys.stdout.write(str(coords_new[i_new][g_dim-1]) + "\n") diff --git a/tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/moltemplate_files/monomer.lt b/tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/moltemplate_files/monomer.lt deleted file mode 100644 index 9ef2b03984..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/moltemplate_files/monomer.lt +++ /dev/null @@ -1,84 +0,0 @@ -# This file contains the definition of a molecule named "Monomer". -# (This particular molecule contain only one atom, but that is up to you.) -# Later, multiple monomers can be connected together to build a molecule. - - - -Monomer { - - # atom-id mol-id(ignore) atom-type q x y z - - write("Data Atoms") { - $atom:a $mol @atom:A 0.000 0.00000 0.00000 0.00000 - } - - # (The x y z positions will be changed later with move commands - # You can spedify charge and other properties by changing the atom_style.) - - - - # atom-type mass - - write_once("Data Masses") { - @atom:A 1.0 - } - - # pairwise interactions (between non-bonded atoms): - # - # U(r) = 4*eps*((r/sig)^12 - (r/sig)^6) - # - # Note: when sigma=0.8908987181403393=2^(1/6), the minimia is at r=1.0 - # - # atom-type atom-type pair_style epsilon sigma rcutoff - - write_once("In Settings") { - # I usually use sigma = 2^(-(1/6)), with a cutoff of 1 - #pair_coeff @atom:A @atom:A lj/cut 1.0 0.8908987181403393 1.0 - # In the 2013 Science (metaphase) paper, Imakaev used sigma=1.0 - # with a cutoff of 2^(1/6). Here we are trying to reproduce his results. - # 10nm fiber - #pair_coeff @atom:A @atom:A lj/cut 1.0 1.0 1.122462048309373 - # 30nm fiber (4.25^(1/2)=2.0615528128088303) - #pair_coeff @atom:A @atom:A lj/cut 1.0 2.0615528128088303 2.314014792963349 - # 30nm fiber (4.25^(1/3)=1.6198059006387417) - pair_coeff @atom:A @atom:A lj/cut 1.0 1.6198059006387417 1.8181706490945708 - } - -} # Monomer - - - - -# -------------------------------------------------------------------- -# -# At some point we need to specify which force-field styles we want. -# LAMMPS also allows you to customize the kinds of properties you want -# each atom to have (the "atom_style"), such as charge, molecule-id, dipole etc. -# I typically specify this here. Doing it this way means that all systems built -# from "Monomers" (ie which import "monomer.lt") share these atom-styles -# and force-field styles by default. You can override these settings later. - - -write_once("In Init") { - # Default styles for molecules built out of "Monomers" - units lj - atom_style full - - bond_style hybrid harmonic table linear 4001 - angle_style hybrid cosine - dihedral_style none - - # If you need angles, dihedrals and impropers, uncomment or replace: - # angle_style hybrid harmonic - # dihedral_style hybrid fourier - - pair_style hybrid lj/cut 2.5 - - # If you are using gpu acceleration uncomment these lines: - # package gpu force/neigh 0 0 1.0 - # pair_style hybrid lj/cut/gpu 4.0 - - pair_modify mix arithmetic - special_bonds lj/coul 1 1 1 -} - diff --git a/tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/moltemplate_files/table_bonds_stage2.dat b/tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/moltemplate_files/table_bonds_stage2.dat deleted file mode 100644 index 1bfb911c09..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/moltemplate_files/table_bonds_stage2.dat +++ /dev/null @@ -1,4011 +0,0 @@ -# This table contains the bond potential between condensin-anchors -# used by Imakaev in the Science 2013 (metaphase chromatin HiC) paper, -# two-stage model, during stage 2. -# -# i r_i U(r_i) -dU/dr|r_i -# where U(r) = step(d-3) * abs(d-3) * 10 - -STAGE2 -N 4001 FP 0 0 EQ 0 - -1 0 0 0 -2 .05 0 0 -3 .10 0 0 -4 .15 0 0 -5 .20 0 0 -6 .25 0 0 -7 .30 0 0 -8 .35 0 0 -9 .40 0 0 -10 .45 0 0 -11 .50 0 0 -12 .55 0 0 -13 .60 0 0 -14 .65 0 0 -15 .70 0 0 -16 .75 0 0 -17 .80 0 0 -18 .85 0 0 -19 .90 0 0 -20 .95 0 0 -21 1.00 0 0 -22 1.05 0 0 -23 1.10 0 0 -24 1.15 0 0 -25 1.20 0 0 -26 1.25 0 0 -27 1.30 0 0 -28 1.35 0 0 -29 1.40 0 0 -30 1.45 0 0 -31 1.50 0 0 -32 1.55 0 0 -33 1.60 0 0 -34 1.65 0 0 -35 1.70 0 0 -36 1.75 0 0 -37 1.80 0 0 -38 1.85 0 0 -39 1.90 0 0 -40 1.95 0 0 -41 2.00 0 0 -42 2.05 0 0 -43 2.10 0 0 -44 2.15 0 0 -45 2.20 0 0 -46 2.25 0 0 -47 2.30 0 0 -48 2.35 0 0 -49 2.40 0 0 -50 2.45 0 0 -51 2.50 0 0 -52 2.55 0 0 -53 2.60 0 0 -54 2.65 0 0 -55 2.70 0 0 -56 2.75 0 0 -57 2.80 0 0 -58 2.85 0 0 -59 2.90 0 0 -60 2.95 0 0 -61 3.0 0 -5 -62 3.05 .5 -10 -63 3.10 1.0 -10 -64 3.15 1.5 -10 -65 3.20 2.0 -10 -66 3.25 2.5 -10 -67 3.30 3.0 -10 -68 3.35 3.5 -10 -69 3.40 4.0 -10 -70 3.45 4.5 -10 -71 3.50 5.0 -10 -72 3.55 5.5 -10 -73 3.60 6.0 -10 -74 3.65 6.5 -10 -75 3.70 7.0 -10 -76 3.75 7.5 -10 -77 3.80 8.0 -10 -78 3.85 8.5 -10 -79 3.90 9.0 -10 -80 3.95 9.5 -10 -81 4.00 10.0 -10 -82 4.05 10.5 -10 -83 4.10 11.0 -10 -84 4.15 11.5 -10 -85 4.20 12.0 -10 -86 4.25 12.5 -10 -87 4.30 13.0 -10 -88 4.35 13.5 -10 -89 4.40 14.0 -10 -90 4.45 14.5 -10 -91 4.50 15.0 -10 -92 4.55 15.5 -10 -93 4.60 16.0 -10 -94 4.65 16.5 -10 -95 4.70 17.0 -10 -96 4.75 17.5 -10 -97 4.80 18.0 -10 -98 4.85 18.5 -10 -99 4.90 19.0 -10 -100 4.95 19.5 -10 -101 5.00 20.0 -10 -102 5.05 20.5 -10 -103 5.10 21.0 -10 -104 5.15 21.5 -10 -105 5.20 22.0 -10 -106 5.25 22.5 -10 -107 5.30 23.0 -10 -108 5.35 23.5 -10 -109 5.40 24.0 -10 -110 5.45 24.5 -10 -111 5.50 25.0 -10 -112 5.55 25.5 -10 -113 5.60 26.0 -10 -114 5.65 26.5 -10 -115 5.70 27.0 -10 -116 5.75 27.5 -10 -117 5.80 28.0 -10 -118 5.85 28.5 -10 -119 5.90 29.0 -10 -120 5.95 29.5 -10 -121 6.00 30.0 -10 -122 6.05 30.5 -10 -123 6.10 31.0 -10 -124 6.15 31.5 -10 -125 6.20 32.0 -10 -126 6.25 32.5 -10 -127 6.30 33.0 -10 -128 6.35 33.5 -10 -129 6.40 34.0 -10 -130 6.45 34.5 -10 -131 6.50 35.0 -10 -132 6.55 35.5 -10 -133 6.60 36.0 -10 -134 6.65 36.5 -10 -135 6.70 37.0 -10 -136 6.75 37.5 -10 -137 6.80 38.0 -10 -138 6.85 38.5 -10 -139 6.90 39.0 -10 -140 6.95 39.5 -10 -141 7.00 40.0 -10 -142 7.05 40.5 -10 -143 7.10 41.0 -10 -144 7.15 41.5 -10 -145 7.20 42.0 -10 -146 7.25 42.5 -10 -147 7.30 43.0 -10 -148 7.35 43.5 -10 -149 7.40 44.0 -10 -150 7.45 44.5 -10 -151 7.50 45.0 -10 -152 7.55 45.5 -10 -153 7.60 46.0 -10 -154 7.65 46.5 -10 -155 7.70 47.0 -10 -156 7.75 47.5 -10 -157 7.80 48.0 -10 -158 7.85 48.5 -10 -159 7.90 49.0 -10 -160 7.95 49.5 -10 -161 8.00 50.0 -10 -162 8.05 50.5 -10 -163 8.10 51.0 -10 -164 8.15 51.5 -10 -165 8.20 52.0 -10 -166 8.25 52.5 -10 -167 8.30 53.0 -10 -168 8.35 53.5 -10 -169 8.40 54.0 -10 -170 8.45 54.5 -10 -171 8.50 55.0 -10 -172 8.55 55.5 -10 -173 8.60 56.0 -10 -174 8.65 56.5 -10 -175 8.70 57.0 -10 -176 8.75 57.5 -10 -177 8.80 58.0 -10 -178 8.85 58.5 -10 -179 8.90 59.0 -10 -180 8.95 59.5 -10 -181 9.00 60.0 -10 -182 9.05 60.5 -10 -183 9.10 61.0 -10 -184 9.15 61.5 -10 -185 9.20 62.0 -10 -186 9.25 62.5 -10 -187 9.30 63.0 -10 -188 9.35 63.5 -10 -189 9.40 64.0 -10 -190 9.45 64.5 -10 -191 9.50 65.0 -10 -192 9.55 65.5 -10 -193 9.60 66.0 -10 -194 9.65 66.5 -10 -195 9.70 67.0 -10 -196 9.75 67.5 -10 -197 9.80 68.0 -10 -198 9.85 68.5 -10 -199 9.90 69.0 -10 -200 9.95 69.5 -10 -201 10.00 70.0 -10 -202 10.05 70.5 -10 -203 10.10 71.0 -10 -204 10.15 71.5 -10 -205 10.20 72.0 -10 -206 10.25 72.5 -10 -207 10.30 73.0 -10 -208 10.35 73.5 -10 -209 10.40 74.0 -10 -210 10.45 74.5 -10 -211 10.50 75.0 -10 -212 10.55 75.5 -10 -213 10.60 76.0 -10 -214 10.65 76.5 -10 -215 10.70 77.0 -10 -216 10.75 77.5 -10 -217 10.80 78.0 -10 -218 10.85 78.5 -10 -219 10.90 79.0 -10 -220 10.95 79.5 -10 -221 11.00 80.0 -10 -222 11.05 80.5 -10 -223 11.10 81.0 -10 -224 11.15 81.5 -10 -225 11.20 82.0 -10 -226 11.25 82.5 -10 -227 11.30 83.0 -10 -228 11.35 83.5 -10 -229 11.40 84.0 -10 -230 11.45 84.5 -10 -231 11.50 85.0 -10 -232 11.55 85.5 -10 -233 11.60 86.0 -10 -234 11.65 86.5 -10 -235 11.70 87.0 -10 -236 11.75 87.5 -10 -237 11.80 88.0 -10 -238 11.85 88.5 -10 -239 11.90 89.0 -10 -240 11.95 89.5 -10 -241 12.00 90.0 -10 -242 12.05 90.5 -10 -243 12.10 91.0 -10 -244 12.15 91.5 -10 -245 12.20 92.0 -10 -246 12.25 92.5 -10 -247 12.30 93.0 -10 -248 12.35 93.5 -10 -249 12.40 94.0 -10 -250 12.45 94.5 -10 -251 12.50 95.0 -10 -252 12.55 95.5 -10 -253 12.60 96.0 -10 -254 12.65 96.5 -10 -255 12.70 97.0 -10 -256 12.75 97.5 -10 -257 12.80 98.0 -10 -258 12.85 98.5 -10 -259 12.90 99.0 -10 -260 12.95 99.5 -10 -261 13.00 100.0 -10 -262 13.05 100.5 -10 -263 13.10 101.0 -10 -264 13.15 101.5 -10 -265 13.20 102.0 -10 -266 13.25 102.5 -10 -267 13.30 103.0 -10 -268 13.35 103.5 -10 -269 13.40 104.0 -10 -270 13.45 104.5 -10 -271 13.50 105.0 -10 -272 13.55 105.5 -10 -273 13.60 106.0 -10 -274 13.65 106.5 -10 -275 13.70 107.0 -10 -276 13.75 107.5 -10 -277 13.80 108.0 -10 -278 13.85 108.5 -10 -279 13.90 109.0 -10 -280 13.95 109.5 -10 -281 14.00 110.0 -10 -282 14.05 110.5 -10 -283 14.10 111.0 -10 -284 14.15 111.5 -10 -285 14.20 112.0 -10 -286 14.25 112.5 -10 -287 14.30 113.0 -10 -288 14.35 113.5 -10 -289 14.40 114.0 -10 -290 14.45 114.5 -10 -291 14.50 115.0 -10 -292 14.55 115.5 -10 -293 14.60 116.0 -10 -294 14.65 116.5 -10 -295 14.70 117.0 -10 -296 14.75 117.5 -10 -297 14.80 118.0 -10 -298 14.85 118.5 -10 -299 14.90 119.0 -10 -300 14.95 119.5 -10 -301 15.00 120.0 -10 -302 15.05 120.5 -10 -303 15.10 121.0 -10 -304 15.15 121.5 -10 -305 15.20 122.0 -10 -306 15.25 122.5 -10 -307 15.30 123.0 -10 -308 15.35 123.5 -10 -309 15.40 124.0 -10 -310 15.45 124.5 -10 -311 15.50 125.0 -10 -312 15.55 125.5 -10 -313 15.60 126.0 -10 -314 15.65 126.5 -10 -315 15.70 127.0 -10 -316 15.75 127.5 -10 -317 15.80 128.0 -10 -318 15.85 128.5 -10 -319 15.90 129.0 -10 -320 15.95 129.5 -10 -321 16.00 130.0 -10 -322 16.05 130.5 -10 -323 16.10 131.0 -10 -324 16.15 131.5 -10 -325 16.20 132.0 -10 -326 16.25 132.5 -10 -327 16.30 133.0 -10 -328 16.35 133.5 -10 -329 16.40 134.0 -10 -330 16.45 134.5 -10 -331 16.50 135.0 -10 -332 16.55 135.5 -10 -333 16.60 136.0 -10 -334 16.65 136.5 -10 -335 16.70 137.0 -10 -336 16.75 137.5 -10 -337 16.80 138.0 -10 -338 16.85 138.5 -10 -339 16.90 139.0 -10 -340 16.95 139.5 -10 -341 17.00 140.0 -10 -342 17.05 140.5 -10 -343 17.10 141.0 -10 -344 17.15 141.5 -10 -345 17.20 142.0 -10 -346 17.25 142.5 -10 -347 17.30 143.0 -10 -348 17.35 143.5 -10 -349 17.40 144.0 -10 -350 17.45 144.5 -10 -351 17.50 145.0 -10 -352 17.55 145.5 -10 -353 17.60 146.0 -10 -354 17.65 146.5 -10 -355 17.70 147.0 -10 -356 17.75 147.5 -10 -357 17.80 148.0 -10 -358 17.85 148.5 -10 -359 17.90 149.0 -10 -360 17.95 149.5 -10 -361 18.00 150.0 -10 -362 18.05 150.5 -10 -363 18.10 151.0 -10 -364 18.15 151.5 -10 -365 18.20 152.0 -10 -366 18.25 152.5 -10 -367 18.30 153.0 -10 -368 18.35 153.5 -10 -369 18.40 154.0 -10 -370 18.45 154.5 -10 -371 18.50 155.0 -10 -372 18.55 155.5 -10 -373 18.60 156.0 -10 -374 18.65 156.5 -10 -375 18.70 157.0 -10 -376 18.75 157.5 -10 -377 18.80 158.0 -10 -378 18.85 158.5 -10 -379 18.90 159.0 -10 -380 18.95 159.5 -10 -381 19.00 160.0 -10 -382 19.05 160.5 -10 -383 19.10 161.0 -10 -384 19.15 161.5 -10 -385 19.20 162.0 -10 -386 19.25 162.5 -10 -387 19.30 163.0 -10 -388 19.35 163.5 -10 -389 19.40 164.0 -10 -390 19.45 164.5 -10 -391 19.50 165.0 -10 -392 19.55 165.5 -10 -393 19.60 166.0 -10 -394 19.65 166.5 -10 -395 19.70 167.0 -10 -396 19.75 167.5 -10 -397 19.80 168.0 -10 -398 19.85 168.5 -10 -399 19.90 169.0 -10 -400 19.95 169.5 -10 -401 20.00 170.0 -10 -402 20.05 170.5 -10 -403 20.10 171.0 -10 -404 20.15 171.5 -10 -405 20.20 172.0 -10 -406 20.25 172.5 -10 -407 20.30 173.0 -10 -408 20.35 173.5 -10 -409 20.40 174.0 -10 -410 20.45 174.5 -10 -411 20.50 175.0 -10 -412 20.55 175.5 -10 -413 20.60 176.0 -10 -414 20.65 176.5 -10 -415 20.70 177.0 -10 -416 20.75 177.5 -10 -417 20.80 178.0 -10 -418 20.85 178.5 -10 -419 20.90 179.0 -10 -420 20.95 179.5 -10 -421 21.00 180.0 -10 -422 21.05 180.5 -10 -423 21.10 181.0 -10 -424 21.15 181.5 -10 -425 21.20 182.0 -10 -426 21.25 182.5 -10 -427 21.30 183.0 -10 -428 21.35 183.5 -10 -429 21.40 184.0 -10 -430 21.45 184.5 -10 -431 21.50 185.0 -10 -432 21.55 185.5 -10 -433 21.60 186.0 -10 -434 21.65 186.5 -10 -435 21.70 187.0 -10 -436 21.75 187.5 -10 -437 21.80 188.0 -10 -438 21.85 188.5 -10 -439 21.90 189.0 -10 -440 21.95 189.5 -10 -441 22.00 190.0 -10 -442 22.05 190.5 -10 -443 22.10 191.0 -10 -444 22.15 191.5 -10 -445 22.20 192.0 -10 -446 22.25 192.5 -10 -447 22.30 193.0 -10 -448 22.35 193.5 -10 -449 22.40 194.0 -10 -450 22.45 194.5 -10 -451 22.50 195.0 -10 -452 22.55 195.5 -10 -453 22.60 196.0 -10 -454 22.65 196.5 -10 -455 22.70 197.0 -10 -456 22.75 197.5 -10 -457 22.80 198.0 -10 -458 22.85 198.5 -10 -459 22.90 199.0 -10 -460 22.95 199.5 -10 -461 23.00 200.0 -10 -462 23.05 200.5 -10 -463 23.10 201.0 -10 -464 23.15 201.5 -10 -465 23.20 202.0 -10 -466 23.25 202.5 -10 -467 23.30 203.0 -10 -468 23.35 203.5 -10 -469 23.40 204.0 -10 -470 23.45 204.5 -10 -471 23.50 205.0 -10 -472 23.55 205.5 -10 -473 23.60 206.0 -10 -474 23.65 206.5 -10 -475 23.70 207.0 -10 -476 23.75 207.5 -10 -477 23.80 208.0 -10 -478 23.85 208.5 -10 -479 23.90 209.0 -10 -480 23.95 209.5 -10 -481 24.00 210.0 -10 -482 24.05 210.5 -10 -483 24.10 211.0 -10 -484 24.15 211.5 -10 -485 24.20 212.0 -10 -486 24.25 212.5 -10 -487 24.30 213.0 -10 -488 24.35 213.5 -10 -489 24.40 214.0 -10 -490 24.45 214.5 -10 -491 24.50 215.0 -10 -492 24.55 215.5 -10 -493 24.60 216.0 -10 -494 24.65 216.5 -10 -495 24.70 217.0 -10 -496 24.75 217.5 -10 -497 24.80 218.0 -10 -498 24.85 218.5 -10 -499 24.90 219.0 -10 -500 24.95 219.5 -10 -501 25.00 220.0 -10 -502 25.05 220.5 -10 -503 25.10 221.0 -10 -504 25.15 221.5 -10 -505 25.20 222.0 -10 -506 25.25 222.5 -10 -507 25.30 223.0 -10 -508 25.35 223.5 -10 -509 25.40 224.0 -10 -510 25.45 224.5 -10 -511 25.50 225.0 -10 -512 25.55 225.5 -10 -513 25.60 226.0 -10 -514 25.65 226.5 -10 -515 25.70 227.0 -10 -516 25.75 227.5 -10 -517 25.80 228.0 -10 -518 25.85 228.5 -10 -519 25.90 229.0 -10 -520 25.95 229.5 -10 -521 26.00 230.0 -10 -522 26.05 230.5 -10 -523 26.10 231.0 -10 -524 26.15 231.5 -10 -525 26.20 232.0 -10 -526 26.25 232.5 -10 -527 26.30 233.0 -10 -528 26.35 233.5 -10 -529 26.40 234.0 -10 -530 26.45 234.5 -10 -531 26.50 235.0 -10 -532 26.55 235.5 -10 -533 26.60 236.0 -10 -534 26.65 236.5 -10 -535 26.70 237.0 -10 -536 26.75 237.5 -10 -537 26.80 238.0 -10 -538 26.85 238.5 -10 -539 26.90 239.0 -10 -540 26.95 239.5 -10 -541 27.00 240.0 -10 -542 27.05 240.5 -10 -543 27.10 241.0 -10 -544 27.15 241.5 -10 -545 27.20 242.0 -10 -546 27.25 242.5 -10 -547 27.30 243.0 -10 -548 27.35 243.5 -10 -549 27.40 244.0 -10 -550 27.45 244.5 -10 -551 27.50 245.0 -10 -552 27.55 245.5 -10 -553 27.60 246.0 -10 -554 27.65 246.5 -10 -555 27.70 247.0 -10 -556 27.75 247.5 -10 -557 27.80 248.0 -10 -558 27.85 248.5 -10 -559 27.90 249.0 -10 -560 27.95 249.5 -10 -561 28.00 250.0 -10 -562 28.05 250.5 -10 -563 28.10 251.0 -10 -564 28.15 251.5 -10 -565 28.20 252.0 -10 -566 28.25 252.5 -10 -567 28.30 253.0 -10 -568 28.35 253.5 -10 -569 28.40 254.0 -10 -570 28.45 254.5 -10 -571 28.50 255.0 -10 -572 28.55 255.5 -10 -573 28.60 256.0 -10 -574 28.65 256.5 -10 -575 28.70 257.0 -10 -576 28.75 257.5 -10 -577 28.80 258.0 -10 -578 28.85 258.5 -10 -579 28.90 259.0 -10 -580 28.95 259.5 -10 -581 29.00 260.0 -10 -582 29.05 260.5 -10 -583 29.10 261.0 -10 -584 29.15 261.5 -10 -585 29.20 262.0 -10 -586 29.25 262.5 -10 -587 29.30 263.0 -10 -588 29.35 263.5 -10 -589 29.40 264.0 -10 -590 29.45 264.5 -10 -591 29.50 265.0 -10 -592 29.55 265.5 -10 -593 29.60 266.0 -10 -594 29.65 266.5 -10 -595 29.70 267.0 -10 -596 29.75 267.5 -10 -597 29.80 268.0 -10 -598 29.85 268.5 -10 -599 29.90 269.0 -10 -600 29.95 269.5 -10 -601 30.00 270.0 -10 -602 30.05 270.5 -10 -603 30.10 271.0 -10 -604 30.15 271.5 -10 -605 30.20 272.0 -10 -606 30.25 272.5 -10 -607 30.30 273.0 -10 -608 30.35 273.5 -10 -609 30.40 274.0 -10 -610 30.45 274.5 -10 -611 30.50 275.0 -10 -612 30.55 275.5 -10 -613 30.60 276.0 -10 -614 30.65 276.5 -10 -615 30.70 277.0 -10 -616 30.75 277.5 -10 -617 30.80 278.0 -10 -618 30.85 278.5 -10 -619 30.90 279.0 -10 -620 30.95 279.5 -10 -621 31.00 280.0 -10 -622 31.05 280.5 -10 -623 31.10 281.0 -10 -624 31.15 281.5 -10 -625 31.20 282.0 -10 -626 31.25 282.5 -10 -627 31.30 283.0 -10 -628 31.35 283.5 -10 -629 31.40 284.0 -10 -630 31.45 284.5 -10 -631 31.50 285.0 -10 -632 31.55 285.5 -10 -633 31.60 286.0 -10 -634 31.65 286.5 -10 -635 31.70 287.0 -10 -636 31.75 287.5 -10 -637 31.80 288.0 -10 -638 31.85 288.5 -10 -639 31.90 289.0 -10 -640 31.95 289.5 -10 -641 32.00 290.0 -10 -642 32.05 290.5 -10 -643 32.10 291.0 -10 -644 32.15 291.5 -10 -645 32.20 292.0 -10 -646 32.25 292.5 -10 -647 32.30 293.0 -10 -648 32.35 293.5 -10 -649 32.40 294.0 -10 -650 32.45 294.5 -10 -651 32.50 295.0 -10 -652 32.55 295.5 -10 -653 32.60 296.0 -10 -654 32.65 296.5 -10 -655 32.70 297.0 -10 -656 32.75 297.5 -10 -657 32.80 298.0 -10 -658 32.85 298.5 -10 -659 32.90 299.0 -10 -660 32.95 299.5 -10 -661 33.00 300.0 -10 -662 33.05 300.5 -10 -663 33.10 301.0 -10 -664 33.15 301.5 -10 -665 33.20 302.0 -10 -666 33.25 302.5 -10 -667 33.30 303.0 -10 -668 33.35 303.5 -10 -669 33.40 304.0 -10 -670 33.45 304.5 -10 -671 33.50 305.0 -10 -672 33.55 305.5 -10 -673 33.60 306.0 -10 -674 33.65 306.5 -10 -675 33.70 307.0 -10 -676 33.75 307.5 -10 -677 33.80 308.0 -10 -678 33.85 308.5 -10 -679 33.90 309.0 -10 -680 33.95 309.5 -10 -681 34.00 310.0 -10 -682 34.05 310.5 -10 -683 34.10 311.0 -10 -684 34.15 311.5 -10 -685 34.20 312.0 -10 -686 34.25 312.5 -10 -687 34.30 313.0 -10 -688 34.35 313.5 -10 -689 34.40 314.0 -10 -690 34.45 314.5 -10 -691 34.50 315.0 -10 -692 34.55 315.5 -10 -693 34.60 316.0 -10 -694 34.65 316.5 -10 -695 34.70 317.0 -10 -696 34.75 317.5 -10 -697 34.80 318.0 -10 -698 34.85 318.5 -10 -699 34.90 319.0 -10 -700 34.95 319.5 -10 -701 35.00 320.0 -10 -702 35.05 320.5 -10 -703 35.10 321.0 -10 -704 35.15 321.5 -10 -705 35.20 322.0 -10 -706 35.25 322.5 -10 -707 35.30 323.0 -10 -708 35.35 323.5 -10 -709 35.40 324.0 -10 -710 35.45 324.5 -10 -711 35.50 325.0 -10 -712 35.55 325.5 -10 -713 35.60 326.0 -10 -714 35.65 326.5 -10 -715 35.70 327.0 -10 -716 35.75 327.5 -10 -717 35.80 328.0 -10 -718 35.85 328.5 -10 -719 35.90 329.0 -10 -720 35.95 329.5 -10 -721 36.00 330.0 -10 -722 36.05 330.5 -10 -723 36.10 331.0 -10 -724 36.15 331.5 -10 -725 36.20 332.0 -10 -726 36.25 332.5 -10 -727 36.30 333.0 -10 -728 36.35 333.5 -10 -729 36.40 334.0 -10 -730 36.45 334.5 -10 -731 36.50 335.0 -10 -732 36.55 335.5 -10 -733 36.60 336.0 -10 -734 36.65 336.5 -10 -735 36.70 337.0 -10 -736 36.75 337.5 -10 -737 36.80 338.0 -10 -738 36.85 338.5 -10 -739 36.90 339.0 -10 -740 36.95 339.5 -10 -741 37.00 340.0 -10 -742 37.05 340.5 -10 -743 37.10 341.0 -10 -744 37.15 341.5 -10 -745 37.20 342.0 -10 -746 37.25 342.5 -10 -747 37.30 343.0 -10 -748 37.35 343.5 -10 -749 37.40 344.0 -10 -750 37.45 344.5 -10 -751 37.50 345.0 -10 -752 37.55 345.5 -10 -753 37.60 346.0 -10 -754 37.65 346.5 -10 -755 37.70 347.0 -10 -756 37.75 347.5 -10 -757 37.80 348.0 -10 -758 37.85 348.5 -10 -759 37.90 349.0 -10 -760 37.95 349.5 -10 -761 38.00 350.0 -10 -762 38.05 350.5 -10 -763 38.10 351.0 -10 -764 38.15 351.5 -10 -765 38.20 352.0 -10 -766 38.25 352.5 -10 -767 38.30 353.0 -10 -768 38.35 353.5 -10 -769 38.40 354.0 -10 -770 38.45 354.5 -10 -771 38.50 355.0 -10 -772 38.55 355.5 -10 -773 38.60 356.0 -10 -774 38.65 356.5 -10 -775 38.70 357.0 -10 -776 38.75 357.5 -10 -777 38.80 358.0 -10 -778 38.85 358.5 -10 -779 38.90 359.0 -10 -780 38.95 359.5 -10 -781 39.00 360.0 -10 -782 39.05 360.5 -10 -783 39.10 361.0 -10 -784 39.15 361.5 -10 -785 39.20 362.0 -10 -786 39.25 362.5 -10 -787 39.30 363.0 -10 -788 39.35 363.5 -10 -789 39.40 364.0 -10 -790 39.45 364.5 -10 -791 39.50 365.0 -10 -792 39.55 365.5 -10 -793 39.60 366.0 -10 -794 39.65 366.5 -10 -795 39.70 367.0 -10 -796 39.75 367.5 -10 -797 39.80 368.0 -10 -798 39.85 368.5 -10 -799 39.90 369.0 -10 -800 39.95 369.5 -10 -801 40.00 370.0 -10 -802 40.05 370.5 -10 -803 40.10 371.0 -10 -804 40.15 371.5 -10 -805 40.20 372.0 -10 -806 40.25 372.5 -10 -807 40.30 373.0 -10 -808 40.35 373.5 -10 -809 40.40 374.0 -10 -810 40.45 374.5 -10 -811 40.50 375.0 -10 -812 40.55 375.5 -10 -813 40.60 376.0 -10 -814 40.65 376.5 -10 -815 40.70 377.0 -10 -816 40.75 377.5 -10 -817 40.80 378.0 -10 -818 40.85 378.5 -10 -819 40.90 379.0 -10 -820 40.95 379.5 -10 -821 41.00 380.0 -10 -822 41.05 380.5 -10 -823 41.10 381.0 -10 -824 41.15 381.5 -10 -825 41.20 382.0 -10 -826 41.25 382.5 -10 -827 41.30 383.0 -10 -828 41.35 383.5 -10 -829 41.40 384.0 -10 -830 41.45 384.5 -10 -831 41.50 385.0 -10 -832 41.55 385.5 -10 -833 41.60 386.0 -10 -834 41.65 386.5 -10 -835 41.70 387.0 -10 -836 41.75 387.5 -10 -837 41.80 388.0 -10 -838 41.85 388.5 -10 -839 41.90 389.0 -10 -840 41.95 389.5 -10 -841 42.00 390.0 -10 -842 42.05 390.5 -10 -843 42.10 391.0 -10 -844 42.15 391.5 -10 -845 42.20 392.0 -10 -846 42.25 392.5 -10 -847 42.30 393.0 -10 -848 42.35 393.5 -10 -849 42.40 394.0 -10 -850 42.45 394.5 -10 -851 42.50 395.0 -10 -852 42.55 395.5 -10 -853 42.60 396.0 -10 -854 42.65 396.5 -10 -855 42.70 397.0 -10 -856 42.75 397.5 -10 -857 42.80 398.0 -10 -858 42.85 398.5 -10 -859 42.90 399.0 -10 -860 42.95 399.5 -10 -861 43.00 400.0 -10 -862 43.05 400.5 -10 -863 43.10 401.0 -10 -864 43.15 401.5 -10 -865 43.20 402.0 -10 -866 43.25 402.5 -10 -867 43.30 403.0 -10 -868 43.35 403.5 -10 -869 43.40 404.0 -10 -870 43.45 404.5 -10 -871 43.50 405.0 -10 -872 43.55 405.5 -10 -873 43.60 406.0 -10 -874 43.65 406.5 -10 -875 43.70 407.0 -10 -876 43.75 407.5 -10 -877 43.80 408.0 -10 -878 43.85 408.5 -10 -879 43.90 409.0 -10 -880 43.95 409.5 -10 -881 44.00 410.0 -10 -882 44.05 410.5 -10 -883 44.10 411.0 -10 -884 44.15 411.5 -10 -885 44.20 412.0 -10 -886 44.25 412.5 -10 -887 44.30 413.0 -10 -888 44.35 413.5 -10 -889 44.40 414.0 -10 -890 44.45 414.5 -10 -891 44.50 415.0 -10 -892 44.55 415.5 -10 -893 44.60 416.0 -10 -894 44.65 416.5 -10 -895 44.70 417.0 -10 -896 44.75 417.5 -10 -897 44.80 418.0 -10 -898 44.85 418.5 -10 -899 44.90 419.0 -10 -900 44.95 419.5 -10 -901 45.00 420.0 -10 -902 45.05 420.5 -10 -903 45.10 421.0 -10 -904 45.15 421.5 -10 -905 45.20 422.0 -10 -906 45.25 422.5 -10 -907 45.30 423.0 -10 -908 45.35 423.5 -10 -909 45.40 424.0 -10 -910 45.45 424.5 -10 -911 45.50 425.0 -10 -912 45.55 425.5 -10 -913 45.60 426.0 -10 -914 45.65 426.5 -10 -915 45.70 427.0 -10 -916 45.75 427.5 -10 -917 45.80 428.0 -10 -918 45.85 428.5 -10 -919 45.90 429.0 -10 -920 45.95 429.5 -10 -921 46.00 430.0 -10 -922 46.05 430.5 -10 -923 46.10 431.0 -10 -924 46.15 431.5 -10 -925 46.20 432.0 -10 -926 46.25 432.5 -10 -927 46.30 433.0 -10 -928 46.35 433.5 -10 -929 46.40 434.0 -10 -930 46.45 434.5 -10 -931 46.50 435.0 -10 -932 46.55 435.5 -10 -933 46.60 436.0 -10 -934 46.65 436.5 -10 -935 46.70 437.0 -10 -936 46.75 437.5 -10 -937 46.80 438.0 -10 -938 46.85 438.5 -10 -939 46.90 439.0 -10 -940 46.95 439.5 -10 -941 47.00 440.0 -10 -942 47.05 440.5 -10 -943 47.10 441.0 -10 -944 47.15 441.5 -10 -945 47.20 442.0 -10 -946 47.25 442.5 -10 -947 47.30 443.0 -10 -948 47.35 443.5 -10 -949 47.40 444.0 -10 -950 47.45 444.5 -10 -951 47.50 445.0 -10 -952 47.55 445.5 -10 -953 47.60 446.0 -10 -954 47.65 446.5 -10 -955 47.70 447.0 -10 -956 47.75 447.5 -10 -957 47.80 448.0 -10 -958 47.85 448.5 -10 -959 47.90 449.0 -10 -960 47.95 449.5 -10 -961 48.00 450.0 -10 -962 48.05 450.5 -10 -963 48.10 451.0 -10 -964 48.15 451.5 -10 -965 48.20 452.0 -10 -966 48.25 452.5 -10 -967 48.30 453.0 -10 -968 48.35 453.5 -10 -969 48.40 454.0 -10 -970 48.45 454.5 -10 -971 48.50 455.0 -10 -972 48.55 455.5 -10 -973 48.60 456.0 -10 -974 48.65 456.5 -10 -975 48.70 457.0 -10 -976 48.75 457.5 -10 -977 48.80 458.0 -10 -978 48.85 458.5 -10 -979 48.90 459.0 -10 -980 48.95 459.5 -10 -981 49.00 460.0 -10 -982 49.05 460.5 -10 -983 49.10 461.0 -10 -984 49.15 461.5 -10 -985 49.20 462.0 -10 -986 49.25 462.5 -10 -987 49.30 463.0 -10 -988 49.35 463.5 -10 -989 49.40 464.0 -10 -990 49.45 464.5 -10 -991 49.50 465.0 -10 -992 49.55 465.5 -10 -993 49.60 466.0 -10 -994 49.65 466.5 -10 -995 49.70 467.0 -10 -996 49.75 467.5 -10 -997 49.80 468.0 -10 -998 49.85 468.5 -10 -999 49.90 469.0 -10 -1000 49.95 469.5 -10 -1001 50.00 470.0 -10 -1002 50.05 470.5 -10 -1003 50.10 471.0 -10 -1004 50.15 471.5 -10 -1005 50.20 472.0 -10 -1006 50.25 472.5 -10 -1007 50.30 473.0 -10 -1008 50.35 473.5 -10 -1009 50.40 474.0 -10 -1010 50.45 474.5 -10 -1011 50.50 475.0 -10 -1012 50.55 475.5 -10 -1013 50.60 476.0 -10 -1014 50.65 476.5 -10 -1015 50.70 477.0 -10 -1016 50.75 477.5 -10 -1017 50.80 478.0 -10 -1018 50.85 478.5 -10 -1019 50.90 479.0 -10 -1020 50.95 479.5 -10 -1021 51.00 480.0 -10 -1022 51.05 480.5 -10 -1023 51.10 481.0 -10 -1024 51.15 481.5 -10 -1025 51.20 482.0 -10 -1026 51.25 482.5 -10 -1027 51.30 483.0 -10 -1028 51.35 483.5 -10 -1029 51.40 484.0 -10 -1030 51.45 484.5 -10 -1031 51.50 485.0 -10 -1032 51.55 485.5 -10 -1033 51.60 486.0 -10 -1034 51.65 486.5 -10 -1035 51.70 487.0 -10 -1036 51.75 487.5 -10 -1037 51.80 488.0 -10 -1038 51.85 488.5 -10 -1039 51.90 489.0 -10 -1040 51.95 489.5 -10 -1041 52.00 490.0 -10 -1042 52.05 490.5 -10 -1043 52.10 491.0 -10 -1044 52.15 491.5 -10 -1045 52.20 492.0 -10 -1046 52.25 492.5 -10 -1047 52.30 493.0 -10 -1048 52.35 493.5 -10 -1049 52.40 494.0 -10 -1050 52.45 494.5 -10 -1051 52.50 495.0 -10 -1052 52.55 495.5 -10 -1053 52.60 496.0 -10 -1054 52.65 496.5 -10 -1055 52.70 497.0 -10 -1056 52.75 497.5 -10 -1057 52.80 498.0 -10 -1058 52.85 498.5 -10 -1059 52.90 499.0 -10 -1060 52.95 499.5 -10 -1061 53.00 500.0 -10 -1062 53.05 500.5 -10 -1063 53.10 501.0 -10 -1064 53.15 501.5 -10 -1065 53.20 502.0 -10 -1066 53.25 502.5 -10 -1067 53.30 503.0 -10 -1068 53.35 503.5 -10 -1069 53.40 504.0 -10 -1070 53.45 504.5 -10 -1071 53.50 505.0 -10 -1072 53.55 505.5 -10 -1073 53.60 506.0 -10 -1074 53.65 506.5 -10 -1075 53.70 507.0 -10 -1076 53.75 507.5 -10 -1077 53.80 508.0 -10 -1078 53.85 508.5 -10 -1079 53.90 509.0 -10 -1080 53.95 509.5 -10 -1081 54.00 510.0 -10 -1082 54.05 510.5 -10 -1083 54.10 511.0 -10 -1084 54.15 511.5 -10 -1085 54.20 512.0 -10 -1086 54.25 512.5 -10 -1087 54.30 513.0 -10 -1088 54.35 513.5 -10 -1089 54.40 514.0 -10 -1090 54.45 514.5 -10 -1091 54.50 515.0 -10 -1092 54.55 515.5 -10 -1093 54.60 516.0 -10 -1094 54.65 516.5 -10 -1095 54.70 517.0 -10 -1096 54.75 517.5 -10 -1097 54.80 518.0 -10 -1098 54.85 518.5 -10 -1099 54.90 519.0 -10 -1100 54.95 519.5 -10 -1101 55.00 520.0 -10 -1102 55.05 520.5 -10 -1103 55.10 521.0 -10 -1104 55.15 521.5 -10 -1105 55.20 522.0 -10 -1106 55.25 522.5 -10 -1107 55.30 523.0 -10 -1108 55.35 523.5 -10 -1109 55.40 524.0 -10 -1110 55.45 524.5 -10 -1111 55.50 525.0 -10 -1112 55.55 525.5 -10 -1113 55.60 526.0 -10 -1114 55.65 526.5 -10 -1115 55.70 527.0 -10 -1116 55.75 527.5 -10 -1117 55.80 528.0 -10 -1118 55.85 528.5 -10 -1119 55.90 529.0 -10 -1120 55.95 529.5 -10 -1121 56.00 530.0 -10 -1122 56.05 530.5 -10 -1123 56.10 531.0 -10 -1124 56.15 531.5 -10 -1125 56.20 532.0 -10 -1126 56.25 532.5 -10 -1127 56.30 533.0 -10 -1128 56.35 533.5 -10 -1129 56.40 534.0 -10 -1130 56.45 534.5 -10 -1131 56.50 535.0 -10 -1132 56.55 535.5 -10 -1133 56.60 536.0 -10 -1134 56.65 536.5 -10 -1135 56.70 537.0 -10 -1136 56.75 537.5 -10 -1137 56.80 538.0 -10 -1138 56.85 538.5 -10 -1139 56.90 539.0 -10 -1140 56.95 539.5 -10 -1141 57.00 540.0 -10 -1142 57.05 540.5 -10 -1143 57.10 541.0 -10 -1144 57.15 541.5 -10 -1145 57.20 542.0 -10 -1146 57.25 542.5 -10 -1147 57.30 543.0 -10 -1148 57.35 543.5 -10 -1149 57.40 544.0 -10 -1150 57.45 544.5 -10 -1151 57.50 545.0 -10 -1152 57.55 545.5 -10 -1153 57.60 546.0 -10 -1154 57.65 546.5 -10 -1155 57.70 547.0 -10 -1156 57.75 547.5 -10 -1157 57.80 548.0 -10 -1158 57.85 548.5 -10 -1159 57.90 549.0 -10 -1160 57.95 549.5 -10 -1161 58.00 550.0 -10 -1162 58.05 550.5 -10 -1163 58.10 551.0 -10 -1164 58.15 551.5 -10 -1165 58.20 552.0 -10 -1166 58.25 552.5 -10 -1167 58.30 553.0 -10 -1168 58.35 553.5 -10 -1169 58.40 554.0 -10 -1170 58.45 554.5 -10 -1171 58.50 555.0 -10 -1172 58.55 555.5 -10 -1173 58.60 556.0 -10 -1174 58.65 556.5 -10 -1175 58.70 557.0 -10 -1176 58.75 557.5 -10 -1177 58.80 558.0 -10 -1178 58.85 558.5 -10 -1179 58.90 559.0 -10 -1180 58.95 559.5 -10 -1181 59.00 560.0 -10 -1182 59.05 560.5 -10 -1183 59.10 561.0 -10 -1184 59.15 561.5 -10 -1185 59.20 562.0 -10 -1186 59.25 562.5 -10 -1187 59.30 563.0 -10 -1188 59.35 563.5 -10 -1189 59.40 564.0 -10 -1190 59.45 564.5 -10 -1191 59.50 565.0 -10 -1192 59.55 565.5 -10 -1193 59.60 566.0 -10 -1194 59.65 566.5 -10 -1195 59.70 567.0 -10 -1196 59.75 567.5 -10 -1197 59.80 568.0 -10 -1198 59.85 568.5 -10 -1199 59.90 569.0 -10 -1200 59.95 569.5 -10 -1201 60.00 570.0 -10 -1202 60.05 570.5 -10 -1203 60.10 571.0 -10 -1204 60.15 571.5 -10 -1205 60.20 572.0 -10 -1206 60.25 572.5 -10 -1207 60.30 573.0 -10 -1208 60.35 573.5 -10 -1209 60.40 574.0 -10 -1210 60.45 574.5 -10 -1211 60.50 575.0 -10 -1212 60.55 575.5 -10 -1213 60.60 576.0 -10 -1214 60.65 576.5 -10 -1215 60.70 577.0 -10 -1216 60.75 577.5 -10 -1217 60.80 578.0 -10 -1218 60.85 578.5 -10 -1219 60.90 579.0 -10 -1220 60.95 579.5 -10 -1221 61.00 580.0 -10 -1222 61.05 580.5 -10 -1223 61.10 581.0 -10 -1224 61.15 581.5 -10 -1225 61.20 582.0 -10 -1226 61.25 582.5 -10 -1227 61.30 583.0 -10 -1228 61.35 583.5 -10 -1229 61.40 584.0 -10 -1230 61.45 584.5 -10 -1231 61.50 585.0 -10 -1232 61.55 585.5 -10 -1233 61.60 586.0 -10 -1234 61.65 586.5 -10 -1235 61.70 587.0 -10 -1236 61.75 587.5 -10 -1237 61.80 588.0 -10 -1238 61.85 588.5 -10 -1239 61.90 589.0 -10 -1240 61.95 589.5 -10 -1241 62.00 590.0 -10 -1242 62.05 590.5 -10 -1243 62.10 591.0 -10 -1244 62.15 591.5 -10 -1245 62.20 592.0 -10 -1246 62.25 592.5 -10 -1247 62.30 593.0 -10 -1248 62.35 593.5 -10 -1249 62.40 594.0 -10 -1250 62.45 594.5 -10 -1251 62.50 595.0 -10 -1252 62.55 595.5 -10 -1253 62.60 596.0 -10 -1254 62.65 596.5 -10 -1255 62.70 597.0 -10 -1256 62.75 597.5 -10 -1257 62.80 598.0 -10 -1258 62.85 598.5 -10 -1259 62.90 599.0 -10 -1260 62.95 599.5 -10 -1261 63.00 600.0 -10 -1262 63.05 600.5 -10 -1263 63.10 601.0 -10 -1264 63.15 601.5 -10 -1265 63.20 602.0 -10 -1266 63.25 602.5 -10 -1267 63.30 603.0 -10 -1268 63.35 603.5 -10 -1269 63.40 604.0 -10 -1270 63.45 604.5 -10 -1271 63.50 605.0 -10 -1272 63.55 605.5 -10 -1273 63.60 606.0 -10 -1274 63.65 606.5 -10 -1275 63.70 607.0 -10 -1276 63.75 607.5 -10 -1277 63.80 608.0 -10 -1278 63.85 608.5 -10 -1279 63.90 609.0 -10 -1280 63.95 609.5 -10 -1281 64.00 610.0 -10 -1282 64.05 610.5 -10 -1283 64.10 611.0 -10 -1284 64.15 611.5 -10 -1285 64.20 612.0 -10 -1286 64.25 612.5 -10 -1287 64.30 613.0 -10 -1288 64.35 613.5 -10 -1289 64.40 614.0 -10 -1290 64.45 614.5 -10 -1291 64.50 615.0 -10 -1292 64.55 615.5 -10 -1293 64.60 616.0 -10 -1294 64.65 616.5 -10 -1295 64.70 617.0 -10 -1296 64.75 617.5 -10 -1297 64.80 618.0 -10 -1298 64.85 618.5 -10 -1299 64.90 619.0 -10 -1300 64.95 619.5 -10 -1301 65.00 620.0 -10 -1302 65.05 620.5 -10 -1303 65.10 621.0 -10 -1304 65.15 621.5 -10 -1305 65.20 622.0 -10 -1306 65.25 622.5 -10 -1307 65.30 623.0 -10 -1308 65.35 623.5 -10 -1309 65.40 624.0 -10 -1310 65.45 624.5 -10 -1311 65.50 625.0 -10 -1312 65.55 625.5 -10 -1313 65.60 626.0 -10 -1314 65.65 626.5 -10 -1315 65.70 627.0 -10 -1316 65.75 627.5 -10 -1317 65.80 628.0 -10 -1318 65.85 628.5 -10 -1319 65.90 629.0 -10 -1320 65.95 629.5 -10 -1321 66.00 630.0 -10 -1322 66.05 630.5 -10 -1323 66.10 631.0 -10 -1324 66.15 631.5 -10 -1325 66.20 632.0 -10 -1326 66.25 632.5 -10 -1327 66.30 633.0 -10 -1328 66.35 633.5 -10 -1329 66.40 634.0 -10 -1330 66.45 634.5 -10 -1331 66.50 635.0 -10 -1332 66.55 635.5 -10 -1333 66.60 636.0 -10 -1334 66.65 636.5 -10 -1335 66.70 637.0 -10 -1336 66.75 637.5 -10 -1337 66.80 638.0 -10 -1338 66.85 638.5 -10 -1339 66.90 639.0 -10 -1340 66.95 639.5 -10 -1341 67.00 640.0 -10 -1342 67.05 640.5 -10 -1343 67.10 641.0 -10 -1344 67.15 641.5 -10 -1345 67.20 642.0 -10 -1346 67.25 642.5 -10 -1347 67.30 643.0 -10 -1348 67.35 643.5 -10 -1349 67.40 644.0 -10 -1350 67.45 644.5 -10 -1351 67.50 645.0 -10 -1352 67.55 645.5 -10 -1353 67.60 646.0 -10 -1354 67.65 646.5 -10 -1355 67.70 647.0 -10 -1356 67.75 647.5 -10 -1357 67.80 648.0 -10 -1358 67.85 648.5 -10 -1359 67.90 649.0 -10 -1360 67.95 649.5 -10 -1361 68.00 650.0 -10 -1362 68.05 650.5 -10 -1363 68.10 651.0 -10 -1364 68.15 651.5 -10 -1365 68.20 652.0 -10 -1366 68.25 652.5 -10 -1367 68.30 653.0 -10 -1368 68.35 653.5 -10 -1369 68.40 654.0 -10 -1370 68.45 654.5 -10 -1371 68.50 655.0 -10 -1372 68.55 655.5 -10 -1373 68.60 656.0 -10 -1374 68.65 656.5 -10 -1375 68.70 657.0 -10 -1376 68.75 657.5 -10 -1377 68.80 658.0 -10 -1378 68.85 658.5 -10 -1379 68.90 659.0 -10 -1380 68.95 659.5 -10 -1381 69.00 660.0 -10 -1382 69.05 660.5 -10 -1383 69.10 661.0 -10 -1384 69.15 661.5 -10 -1385 69.20 662.0 -10 -1386 69.25 662.5 -10 -1387 69.30 663.0 -10 -1388 69.35 663.5 -10 -1389 69.40 664.0 -10 -1390 69.45 664.5 -10 -1391 69.50 665.0 -10 -1392 69.55 665.5 -10 -1393 69.60 666.0 -10 -1394 69.65 666.5 -10 -1395 69.70 667.0 -10 -1396 69.75 667.5 -10 -1397 69.80 668.0 -10 -1398 69.85 668.5 -10 -1399 69.90 669.0 -10 -1400 69.95 669.5 -10 -1401 70.00 670.0 -10 -1402 70.05 670.5 -10 -1403 70.10 671.0 -10 -1404 70.15 671.5 -10 -1405 70.20 672.0 -10 -1406 70.25 672.5 -10 -1407 70.30 673.0 -10 -1408 70.35 673.5 -10 -1409 70.40 674.0 -10 -1410 70.45 674.5 -10 -1411 70.50 675.0 -10 -1412 70.55 675.5 -10 -1413 70.60 676.0 -10 -1414 70.65 676.5 -10 -1415 70.70 677.0 -10 -1416 70.75 677.5 -10 -1417 70.80 678.0 -10 -1418 70.85 678.5 -10 -1419 70.90 679.0 -10 -1420 70.95 679.5 -10 -1421 71.00 680.0 -10 -1422 71.05 680.5 -10 -1423 71.10 681.0 -10 -1424 71.15 681.5 -10 -1425 71.20 682.0 -10 -1426 71.25 682.5 -10 -1427 71.30 683.0 -10 -1428 71.35 683.5 -10 -1429 71.40 684.0 -10 -1430 71.45 684.5 -10 -1431 71.50 685.0 -10 -1432 71.55 685.5 -10 -1433 71.60 686.0 -10 -1434 71.65 686.5 -10 -1435 71.70 687.0 -10 -1436 71.75 687.5 -10 -1437 71.80 688.0 -10 -1438 71.85 688.5 -10 -1439 71.90 689.0 -10 -1440 71.95 689.5 -10 -1441 72.00 690.0 -10 -1442 72.05 690.5 -10 -1443 72.10 691.0 -10 -1444 72.15 691.5 -10 -1445 72.20 692.0 -10 -1446 72.25 692.5 -10 -1447 72.30 693.0 -10 -1448 72.35 693.5 -10 -1449 72.40 694.0 -10 -1450 72.45 694.5 -10 -1451 72.50 695.0 -10 -1452 72.55 695.5 -10 -1453 72.60 696.0 -10 -1454 72.65 696.5 -10 -1455 72.70 697.0 -10 -1456 72.75 697.5 -10 -1457 72.80 698.0 -10 -1458 72.85 698.5 -10 -1459 72.90 699.0 -10 -1460 72.95 699.5 -10 -1461 73.00 700.0 -10 -1462 73.05 700.5 -10 -1463 73.10 701.0 -10 -1464 73.15 701.5 -10 -1465 73.20 702.0 -10 -1466 73.25 702.5 -10 -1467 73.30 703.0 -10 -1468 73.35 703.5 -10 -1469 73.40 704.0 -10 -1470 73.45 704.5 -10 -1471 73.50 705.0 -10 -1472 73.55 705.5 -10 -1473 73.60 706.0 -10 -1474 73.65 706.5 -10 -1475 73.70 707.0 -10 -1476 73.75 707.5 -10 -1477 73.80 708.0 -10 -1478 73.85 708.5 -10 -1479 73.90 709.0 -10 -1480 73.95 709.5 -10 -1481 74.00 710.0 -10 -1482 74.05 710.5 -10 -1483 74.10 711.0 -10 -1484 74.15 711.5 -10 -1485 74.20 712.0 -10 -1486 74.25 712.5 -10 -1487 74.30 713.0 -10 -1488 74.35 713.5 -10 -1489 74.40 714.0 -10 -1490 74.45 714.5 -10 -1491 74.50 715.0 -10 -1492 74.55 715.5 -10 -1493 74.60 716.0 -10 -1494 74.65 716.5 -10 -1495 74.70 717.0 -10 -1496 74.75 717.5 -10 -1497 74.80 718.0 -10 -1498 74.85 718.5 -10 -1499 74.90 719.0 -10 -1500 74.95 719.5 -10 -1501 75.00 720.0 -10 -1502 75.05 720.5 -10 -1503 75.10 721.0 -10 -1504 75.15 721.5 -10 -1505 75.20 722.0 -10 -1506 75.25 722.5 -10 -1507 75.30 723.0 -10 -1508 75.35 723.5 -10 -1509 75.40 724.0 -10 -1510 75.45 724.5 -10 -1511 75.50 725.0 -10 -1512 75.55 725.5 -10 -1513 75.60 726.0 -10 -1514 75.65 726.5 -10 -1515 75.70 727.0 -10 -1516 75.75 727.5 -10 -1517 75.80 728.0 -10 -1518 75.85 728.5 -10 -1519 75.90 729.0 -10 -1520 75.95 729.5 -10 -1521 76.00 730.0 -10 -1522 76.05 730.5 -10 -1523 76.10 731.0 -10 -1524 76.15 731.5 -10 -1525 76.20 732.0 -10 -1526 76.25 732.5 -10 -1527 76.30 733.0 -10 -1528 76.35 733.5 -10 -1529 76.40 734.0 -10 -1530 76.45 734.5 -10 -1531 76.50 735.0 -10 -1532 76.55 735.5 -10 -1533 76.60 736.0 -10 -1534 76.65 736.5 -10 -1535 76.70 737.0 -10 -1536 76.75 737.5 -10 -1537 76.80 738.0 -10 -1538 76.85 738.5 -10 -1539 76.90 739.0 -10 -1540 76.95 739.5 -10 -1541 77.00 740.0 -10 -1542 77.05 740.5 -10 -1543 77.10 741.0 -10 -1544 77.15 741.5 -10 -1545 77.20 742.0 -10 -1546 77.25 742.5 -10 -1547 77.30 743.0 -10 -1548 77.35 743.5 -10 -1549 77.40 744.0 -10 -1550 77.45 744.5 -10 -1551 77.50 745.0 -10 -1552 77.55 745.5 -10 -1553 77.60 746.0 -10 -1554 77.65 746.5 -10 -1555 77.70 747.0 -10 -1556 77.75 747.5 -10 -1557 77.80 748.0 -10 -1558 77.85 748.5 -10 -1559 77.90 749.0 -10 -1560 77.95 749.5 -10 -1561 78.00 750.0 -10 -1562 78.05 750.5 -10 -1563 78.10 751.0 -10 -1564 78.15 751.5 -10 -1565 78.20 752.0 -10 -1566 78.25 752.5 -10 -1567 78.30 753.0 -10 -1568 78.35 753.5 -10 -1569 78.40 754.0 -10 -1570 78.45 754.5 -10 -1571 78.50 755.0 -10 -1572 78.55 755.5 -10 -1573 78.60 756.0 -10 -1574 78.65 756.5 -10 -1575 78.70 757.0 -10 -1576 78.75 757.5 -10 -1577 78.80 758.0 -10 -1578 78.85 758.5 -10 -1579 78.90 759.0 -10 -1580 78.95 759.5 -10 -1581 79.00 760.0 -10 -1582 79.05 760.5 -10 -1583 79.10 761.0 -10 -1584 79.15 761.5 -10 -1585 79.20 762.0 -10 -1586 79.25 762.5 -10 -1587 79.30 763.0 -10 -1588 79.35 763.5 -10 -1589 79.40 764.0 -10 -1590 79.45 764.5 -10 -1591 79.50 765.0 -10 -1592 79.55 765.5 -10 -1593 79.60 766.0 -10 -1594 79.65 766.5 -10 -1595 79.70 767.0 -10 -1596 79.75 767.5 -10 -1597 79.80 768.0 -10 -1598 79.85 768.5 -10 -1599 79.90 769.0 -10 -1600 79.95 769.5 -10 -1601 80.00 770.0 -10 -1602 80.05 770.5 -10 -1603 80.10 771.0 -10 -1604 80.15 771.5 -10 -1605 80.20 772.0 -10 -1606 80.25 772.5 -10 -1607 80.30 773.0 -10 -1608 80.35 773.5 -10 -1609 80.40 774.0 -10 -1610 80.45 774.5 -10 -1611 80.50 775.0 -10 -1612 80.55 775.5 -10 -1613 80.60 776.0 -10 -1614 80.65 776.5 -10 -1615 80.70 777.0 -10 -1616 80.75 777.5 -10 -1617 80.80 778.0 -10 -1618 80.85 778.5 -10 -1619 80.90 779.0 -10 -1620 80.95 779.5 -10 -1621 81.00 780.0 -10 -1622 81.05 780.5 -10 -1623 81.10 781.0 -10 -1624 81.15 781.5 -10 -1625 81.20 782.0 -10 -1626 81.25 782.5 -10 -1627 81.30 783.0 -10 -1628 81.35 783.5 -10 -1629 81.40 784.0 -10 -1630 81.45 784.5 -10 -1631 81.50 785.0 -10 -1632 81.55 785.5 -10 -1633 81.60 786.0 -10 -1634 81.65 786.5 -10 -1635 81.70 787.0 -10 -1636 81.75 787.5 -10 -1637 81.80 788.0 -10 -1638 81.85 788.5 -10 -1639 81.90 789.0 -10 -1640 81.95 789.5 -10 -1641 82.00 790.0 -10 -1642 82.05 790.5 -10 -1643 82.10 791.0 -10 -1644 82.15 791.5 -10 -1645 82.20 792.0 -10 -1646 82.25 792.5 -10 -1647 82.30 793.0 -10 -1648 82.35 793.5 -10 -1649 82.40 794.0 -10 -1650 82.45 794.5 -10 -1651 82.50 795.0 -10 -1652 82.55 795.5 -10 -1653 82.60 796.0 -10 -1654 82.65 796.5 -10 -1655 82.70 797.0 -10 -1656 82.75 797.5 -10 -1657 82.80 798.0 -10 -1658 82.85 798.5 -10 -1659 82.90 799.0 -10 -1660 82.95 799.5 -10 -1661 83.00 800.0 -10 -1662 83.05 800.5 -10 -1663 83.10 801.0 -10 -1664 83.15 801.5 -10 -1665 83.20 802.0 -10 -1666 83.25 802.5 -10 -1667 83.30 803.0 -10 -1668 83.35 803.5 -10 -1669 83.40 804.0 -10 -1670 83.45 804.5 -10 -1671 83.50 805.0 -10 -1672 83.55 805.5 -10 -1673 83.60 806.0 -10 -1674 83.65 806.5 -10 -1675 83.70 807.0 -10 -1676 83.75 807.5 -10 -1677 83.80 808.0 -10 -1678 83.85 808.5 -10 -1679 83.90 809.0 -10 -1680 83.95 809.5 -10 -1681 84.00 810.0 -10 -1682 84.05 810.5 -10 -1683 84.10 811.0 -10 -1684 84.15 811.5 -10 -1685 84.20 812.0 -10 -1686 84.25 812.5 -10 -1687 84.30 813.0 -10 -1688 84.35 813.5 -10 -1689 84.40 814.0 -10 -1690 84.45 814.5 -10 -1691 84.50 815.0 -10 -1692 84.55 815.5 -10 -1693 84.60 816.0 -10 -1694 84.65 816.5 -10 -1695 84.70 817.0 -10 -1696 84.75 817.5 -10 -1697 84.80 818.0 -10 -1698 84.85 818.5 -10 -1699 84.90 819.0 -10 -1700 84.95 819.5 -10 -1701 85.00 820.0 -10 -1702 85.05 820.5 -10 -1703 85.10 821.0 -10 -1704 85.15 821.5 -10 -1705 85.20 822.0 -10 -1706 85.25 822.5 -10 -1707 85.30 823.0 -10 -1708 85.35 823.5 -10 -1709 85.40 824.0 -10 -1710 85.45 824.5 -10 -1711 85.50 825.0 -10 -1712 85.55 825.5 -10 -1713 85.60 826.0 -10 -1714 85.65 826.5 -10 -1715 85.70 827.0 -10 -1716 85.75 827.5 -10 -1717 85.80 828.0 -10 -1718 85.85 828.5 -10 -1719 85.90 829.0 -10 -1720 85.95 829.5 -10 -1721 86.00 830.0 -10 -1722 86.05 830.5 -10 -1723 86.10 831.0 -10 -1724 86.15 831.5 -10 -1725 86.20 832.0 -10 -1726 86.25 832.5 -10 -1727 86.30 833.0 -10 -1728 86.35 833.5 -10 -1729 86.40 834.0 -10 -1730 86.45 834.5 -10 -1731 86.50 835.0 -10 -1732 86.55 835.5 -10 -1733 86.60 836.0 -10 -1734 86.65 836.5 -10 -1735 86.70 837.0 -10 -1736 86.75 837.5 -10 -1737 86.80 838.0 -10 -1738 86.85 838.5 -10 -1739 86.90 839.0 -10 -1740 86.95 839.5 -10 -1741 87.00 840.0 -10 -1742 87.05 840.5 -10 -1743 87.10 841.0 -10 -1744 87.15 841.5 -10 -1745 87.20 842.0 -10 -1746 87.25 842.5 -10 -1747 87.30 843.0 -10 -1748 87.35 843.5 -10 -1749 87.40 844.0 -10 -1750 87.45 844.5 -10 -1751 87.50 845.0 -10 -1752 87.55 845.5 -10 -1753 87.60 846.0 -10 -1754 87.65 846.5 -10 -1755 87.70 847.0 -10 -1756 87.75 847.5 -10 -1757 87.80 848.0 -10 -1758 87.85 848.5 -10 -1759 87.90 849.0 -10 -1760 87.95 849.5 -10 -1761 88.00 850.0 -10 -1762 88.05 850.5 -10 -1763 88.10 851.0 -10 -1764 88.15 851.5 -10 -1765 88.20 852.0 -10 -1766 88.25 852.5 -10 -1767 88.30 853.0 -10 -1768 88.35 853.5 -10 -1769 88.40 854.0 -10 -1770 88.45 854.5 -10 -1771 88.50 855.0 -10 -1772 88.55 855.5 -10 -1773 88.60 856.0 -10 -1774 88.65 856.5 -10 -1775 88.70 857.0 -10 -1776 88.75 857.5 -10 -1777 88.80 858.0 -10 -1778 88.85 858.5 -10 -1779 88.90 859.0 -10 -1780 88.95 859.5 -10 -1781 89.00 860.0 -10 -1782 89.05 860.5 -10 -1783 89.10 861.0 -10 -1784 89.15 861.5 -10 -1785 89.20 862.0 -10 -1786 89.25 862.5 -10 -1787 89.30 863.0 -10 -1788 89.35 863.5 -10 -1789 89.40 864.0 -10 -1790 89.45 864.5 -10 -1791 89.50 865.0 -10 -1792 89.55 865.5 -10 -1793 89.60 866.0 -10 -1794 89.65 866.5 -10 -1795 89.70 867.0 -10 -1796 89.75 867.5 -10 -1797 89.80 868.0 -10 -1798 89.85 868.5 -10 -1799 89.90 869.0 -10 -1800 89.95 869.5 -10 -1801 90.00 870.0 -10 -1802 90.05 870.5 -10 -1803 90.10 871.0 -10 -1804 90.15 871.5 -10 -1805 90.20 872.0 -10 -1806 90.25 872.5 -10 -1807 90.30 873.0 -10 -1808 90.35 873.5 -10 -1809 90.40 874.0 -10 -1810 90.45 874.5 -10 -1811 90.50 875.0 -10 -1812 90.55 875.5 -10 -1813 90.60 876.0 -10 -1814 90.65 876.5 -10 -1815 90.70 877.0 -10 -1816 90.75 877.5 -10 -1817 90.80 878.0 -10 -1818 90.85 878.5 -10 -1819 90.90 879.0 -10 -1820 90.95 879.5 -10 -1821 91.00 880.0 -10 -1822 91.05 880.5 -10 -1823 91.10 881.0 -10 -1824 91.15 881.5 -10 -1825 91.20 882.0 -10 -1826 91.25 882.5 -10 -1827 91.30 883.0 -10 -1828 91.35 883.5 -10 -1829 91.40 884.0 -10 -1830 91.45 884.5 -10 -1831 91.50 885.0 -10 -1832 91.55 885.5 -10 -1833 91.60 886.0 -10 -1834 91.65 886.5 -10 -1835 91.70 887.0 -10 -1836 91.75 887.5 -10 -1837 91.80 888.0 -10 -1838 91.85 888.5 -10 -1839 91.90 889.0 -10 -1840 91.95 889.5 -10 -1841 92.00 890.0 -10 -1842 92.05 890.5 -10 -1843 92.10 891.0 -10 -1844 92.15 891.5 -10 -1845 92.20 892.0 -10 -1846 92.25 892.5 -10 -1847 92.30 893.0 -10 -1848 92.35 893.5 -10 -1849 92.40 894.0 -10 -1850 92.45 894.5 -10 -1851 92.50 895.0 -10 -1852 92.55 895.5 -10 -1853 92.60 896.0 -10 -1854 92.65 896.5 -10 -1855 92.70 897.0 -10 -1856 92.75 897.5 -10 -1857 92.80 898.0 -10 -1858 92.85 898.5 -10 -1859 92.90 899.0 -10 -1860 92.95 899.5 -10 -1861 93.00 900.0 -10 -1862 93.05 900.5 -10 -1863 93.10 901.0 -10 -1864 93.15 901.5 -10 -1865 93.20 902.0 -10 -1866 93.25 902.5 -10 -1867 93.30 903.0 -10 -1868 93.35 903.5 -10 -1869 93.40 904.0 -10 -1870 93.45 904.5 -10 -1871 93.50 905.0 -10 -1872 93.55 905.5 -10 -1873 93.60 906.0 -10 -1874 93.65 906.5 -10 -1875 93.70 907.0 -10 -1876 93.75 907.5 -10 -1877 93.80 908.0 -10 -1878 93.85 908.5 -10 -1879 93.90 909.0 -10 -1880 93.95 909.5 -10 -1881 94.00 910.0 -10 -1882 94.05 910.5 -10 -1883 94.10 911.0 -10 -1884 94.15 911.5 -10 -1885 94.20 912.0 -10 -1886 94.25 912.5 -10 -1887 94.30 913.0 -10 -1888 94.35 913.5 -10 -1889 94.40 914.0 -10 -1890 94.45 914.5 -10 -1891 94.50 915.0 -10 -1892 94.55 915.5 -10 -1893 94.60 916.0 -10 -1894 94.65 916.5 -10 -1895 94.70 917.0 -10 -1896 94.75 917.5 -10 -1897 94.80 918.0 -10 -1898 94.85 918.5 -10 -1899 94.90 919.0 -10 -1900 94.95 919.5 -10 -1901 95.00 920.0 -10 -1902 95.05 920.5 -10 -1903 95.10 921.0 -10 -1904 95.15 921.5 -10 -1905 95.20 922.0 -10 -1906 95.25 922.5 -10 -1907 95.30 923.0 -10 -1908 95.35 923.5 -10 -1909 95.40 924.0 -10 -1910 95.45 924.5 -10 -1911 95.50 925.0 -10 -1912 95.55 925.5 -10 -1913 95.60 926.0 -10 -1914 95.65 926.5 -10 -1915 95.70 927.0 -10 -1916 95.75 927.5 -10 -1917 95.80 928.0 -10 -1918 95.85 928.5 -10 -1919 95.90 929.0 -10 -1920 95.95 929.5 -10 -1921 96.00 930.0 -10 -1922 96.05 930.5 -10 -1923 96.10 931.0 -10 -1924 96.15 931.5 -10 -1925 96.20 932.0 -10 -1926 96.25 932.5 -10 -1927 96.30 933.0 -10 -1928 96.35 933.5 -10 -1929 96.40 934.0 -10 -1930 96.45 934.5 -10 -1931 96.50 935.0 -10 -1932 96.55 935.5 -10 -1933 96.60 936.0 -10 -1934 96.65 936.5 -10 -1935 96.70 937.0 -10 -1936 96.75 937.5 -10 -1937 96.80 938.0 -10 -1938 96.85 938.5 -10 -1939 96.90 939.0 -10 -1940 96.95 939.5 -10 -1941 97.00 940.0 -10 -1942 97.05 940.5 -10 -1943 97.10 941.0 -10 -1944 97.15 941.5 -10 -1945 97.20 942.0 -10 -1946 97.25 942.5 -10 -1947 97.30 943.0 -10 -1948 97.35 943.5 -10 -1949 97.40 944.0 -10 -1950 97.45 944.5 -10 -1951 97.50 945.0 -10 -1952 97.55 945.5 -10 -1953 97.60 946.0 -10 -1954 97.65 946.5 -10 -1955 97.70 947.0 -10 -1956 97.75 947.5 -10 -1957 97.80 948.0 -10 -1958 97.85 948.5 -10 -1959 97.90 949.0 -10 -1960 97.95 949.5 -10 -1961 98.00 950.0 -10 -1962 98.05 950.5 -10 -1963 98.10 951.0 -10 -1964 98.15 951.5 -10 -1965 98.20 952.0 -10 -1966 98.25 952.5 -10 -1967 98.30 953.0 -10 -1968 98.35 953.5 -10 -1969 98.40 954.0 -10 -1970 98.45 954.5 -10 -1971 98.50 955.0 -10 -1972 98.55 955.5 -10 -1973 98.60 956.0 -10 -1974 98.65 956.5 -10 -1975 98.70 957.0 -10 -1976 98.75 957.5 -10 -1977 98.80 958.0 -10 -1978 98.85 958.5 -10 -1979 98.90 959.0 -10 -1980 98.95 959.5 -10 -1981 99.00 960.0 -10 -1982 99.05 960.5 -10 -1983 99.10 961.0 -10 -1984 99.15 961.5 -10 -1985 99.20 962.0 -10 -1986 99.25 962.5 -10 -1987 99.30 963.0 -10 -1988 99.35 963.5 -10 -1989 99.40 964.0 -10 -1990 99.45 964.5 -10 -1991 99.50 965.0 -10 -1992 99.55 965.5 -10 -1993 99.60 966.0 -10 -1994 99.65 966.5 -10 -1995 99.70 967.0 -10 -1996 99.75 967.5 -10 -1997 99.80 968.0 -10 -1998 99.85 968.5 -10 -1999 99.90 969.0 -10 -2000 99.95 969.5 -10 -2001 100.00 970.0 -10 -2002 100.05 970.5 -10 -2003 100.10 971.0 -10 -2004 100.15 971.5 -10 -2005 100.20 972.0 -10 -2006 100.25 972.5 -10 -2007 100.30 973.0 -10 -2008 100.35 973.5 -10 -2009 100.40 974.0 -10 -2010 100.45 974.5 -10 -2011 100.50 975.0 -10 -2012 100.55 975.5 -10 -2013 100.60 976.0 -10 -2014 100.65 976.5 -10 -2015 100.70 977.0 -10 -2016 100.75 977.5 -10 -2017 100.80 978.0 -10 -2018 100.85 978.5 -10 -2019 100.90 979.0 -10 -2020 100.95 979.5 -10 -2021 101.00 980.0 -10 -2022 101.05 980.5 -10 -2023 101.10 981.0 -10 -2024 101.15 981.5 -10 -2025 101.20 982.0 -10 -2026 101.25 982.5 -10 -2027 101.30 983.0 -10 -2028 101.35 983.5 -10 -2029 101.40 984.0 -10 -2030 101.45 984.5 -10 -2031 101.50 985.0 -10 -2032 101.55 985.5 -10 -2033 101.60 986.0 -10 -2034 101.65 986.5 -10 -2035 101.70 987.0 -10 -2036 101.75 987.5 -10 -2037 101.80 988.0 -10 -2038 101.85 988.5 -10 -2039 101.90 989.0 -10 -2040 101.95 989.5 -10 -2041 102.00 990.0 -10 -2042 102.05 990.5 -10 -2043 102.10 991.0 -10 -2044 102.15 991.5 -10 -2045 102.20 992.0 -10 -2046 102.25 992.5 -10 -2047 102.30 993.0 -10 -2048 102.35 993.5 -10 -2049 102.40 994.0 -10 -2050 102.45 994.5 -10 -2051 102.50 995.0 -10 -2052 102.55 995.5 -10 -2053 102.60 996.0 -10 -2054 102.65 996.5 -10 -2055 102.70 997.0 -10 -2056 102.75 997.5 -10 -2057 102.80 998.0 -10 -2058 102.85 998.5 -10 -2059 102.90 999.0 -10 -2060 102.95 999.5 -10 -2061 103.00 1000.0 -10 -2062 103.05 1000.5 -10 -2063 103.10 1001.0 -10 -2064 103.15 1001.5 -10 -2065 103.20 1002.0 -10 -2066 103.25 1002.5 -10 -2067 103.30 1003.0 -10 -2068 103.35 1003.5 -10 -2069 103.40 1004.0 -10 -2070 103.45 1004.5 -10 -2071 103.50 1005.0 -10 -2072 103.55 1005.5 -10 -2073 103.60 1006.0 -10 -2074 103.65 1006.5 -10 -2075 103.70 1007.0 -10 -2076 103.75 1007.5 -10 -2077 103.80 1008.0 -10 -2078 103.85 1008.5 -10 -2079 103.90 1009.0 -10 -2080 103.95 1009.5 -10 -2081 104.00 1010.0 -10 -2082 104.05 1010.5 -10 -2083 104.10 1011.0 -10 -2084 104.15 1011.5 -10 -2085 104.20 1012.0 -10 -2086 104.25 1012.5 -10 -2087 104.30 1013.0 -10 -2088 104.35 1013.5 -10 -2089 104.40 1014.0 -10 -2090 104.45 1014.5 -10 -2091 104.50 1015.0 -10 -2092 104.55 1015.5 -10 -2093 104.60 1016.0 -10 -2094 104.65 1016.5 -10 -2095 104.70 1017.0 -10 -2096 104.75 1017.5 -10 -2097 104.80 1018.0 -10 -2098 104.85 1018.5 -10 -2099 104.90 1019.0 -10 -2100 104.95 1019.5 -10 -2101 105.00 1020.0 -10 -2102 105.05 1020.5 -10 -2103 105.10 1021.0 -10 -2104 105.15 1021.5 -10 -2105 105.20 1022.0 -10 -2106 105.25 1022.5 -10 -2107 105.30 1023.0 -10 -2108 105.35 1023.5 -10 -2109 105.40 1024.0 -10 -2110 105.45 1024.5 -10 -2111 105.50 1025.0 -10 -2112 105.55 1025.5 -10 -2113 105.60 1026.0 -10 -2114 105.65 1026.5 -10 -2115 105.70 1027.0 -10 -2116 105.75 1027.5 -10 -2117 105.80 1028.0 -10 -2118 105.85 1028.5 -10 -2119 105.90 1029.0 -10 -2120 105.95 1029.5 -10 -2121 106.00 1030.0 -10 -2122 106.05 1030.5 -10 -2123 106.10 1031.0 -10 -2124 106.15 1031.5 -10 -2125 106.20 1032.0 -10 -2126 106.25 1032.5 -10 -2127 106.30 1033.0 -10 -2128 106.35 1033.5 -10 -2129 106.40 1034.0 -10 -2130 106.45 1034.5 -10 -2131 106.50 1035.0 -10 -2132 106.55 1035.5 -10 -2133 106.60 1036.0 -10 -2134 106.65 1036.5 -10 -2135 106.70 1037.0 -10 -2136 106.75 1037.5 -10 -2137 106.80 1038.0 -10 -2138 106.85 1038.5 -10 -2139 106.90 1039.0 -10 -2140 106.95 1039.5 -10 -2141 107.00 1040.0 -10 -2142 107.05 1040.5 -10 -2143 107.10 1041.0 -10 -2144 107.15 1041.5 -10 -2145 107.20 1042.0 -10 -2146 107.25 1042.5 -10 -2147 107.30 1043.0 -10 -2148 107.35 1043.5 -10 -2149 107.40 1044.0 -10 -2150 107.45 1044.5 -10 -2151 107.50 1045.0 -10 -2152 107.55 1045.5 -10 -2153 107.60 1046.0 -10 -2154 107.65 1046.5 -10 -2155 107.70 1047.0 -10 -2156 107.75 1047.5 -10 -2157 107.80 1048.0 -10 -2158 107.85 1048.5 -10 -2159 107.90 1049.0 -10 -2160 107.95 1049.5 -10 -2161 108.00 1050.0 -10 -2162 108.05 1050.5 -10 -2163 108.10 1051.0 -10 -2164 108.15 1051.5 -10 -2165 108.20 1052.0 -10 -2166 108.25 1052.5 -10 -2167 108.30 1053.0 -10 -2168 108.35 1053.5 -10 -2169 108.40 1054.0 -10 -2170 108.45 1054.5 -10 -2171 108.50 1055.0 -10 -2172 108.55 1055.5 -10 -2173 108.60 1056.0 -10 -2174 108.65 1056.5 -10 -2175 108.70 1057.0 -10 -2176 108.75 1057.5 -10 -2177 108.80 1058.0 -10 -2178 108.85 1058.5 -10 -2179 108.90 1059.0 -10 -2180 108.95 1059.5 -10 -2181 109.00 1060.0 -10 -2182 109.05 1060.5 -10 -2183 109.10 1061.0 -10 -2184 109.15 1061.5 -10 -2185 109.20 1062.0 -10 -2186 109.25 1062.5 -10 -2187 109.30 1063.0 -10 -2188 109.35 1063.5 -10 -2189 109.40 1064.0 -10 -2190 109.45 1064.5 -10 -2191 109.50 1065.0 -10 -2192 109.55 1065.5 -10 -2193 109.60 1066.0 -10 -2194 109.65 1066.5 -10 -2195 109.70 1067.0 -10 -2196 109.75 1067.5 -10 -2197 109.80 1068.0 -10 -2198 109.85 1068.5 -10 -2199 109.90 1069.0 -10 -2200 109.95 1069.5 -10 -2201 110.00 1070.0 -10 -2202 110.05 1070.5 -10 -2203 110.10 1071.0 -10 -2204 110.15 1071.5 -10 -2205 110.20 1072.0 -10 -2206 110.25 1072.5 -10 -2207 110.30 1073.0 -10 -2208 110.35 1073.5 -10 -2209 110.40 1074.0 -10 -2210 110.45 1074.5 -10 -2211 110.50 1075.0 -10 -2212 110.55 1075.5 -10 -2213 110.60 1076.0 -10 -2214 110.65 1076.5 -10 -2215 110.70 1077.0 -10 -2216 110.75 1077.5 -10 -2217 110.80 1078.0 -10 -2218 110.85 1078.5 -10 -2219 110.90 1079.0 -10 -2220 110.95 1079.5 -10 -2221 111.00 1080.0 -10 -2222 111.05 1080.5 -10 -2223 111.10 1081.0 -10 -2224 111.15 1081.5 -10 -2225 111.20 1082.0 -10 -2226 111.25 1082.5 -10 -2227 111.30 1083.0 -10 -2228 111.35 1083.5 -10 -2229 111.40 1084.0 -10 -2230 111.45 1084.5 -10 -2231 111.50 1085.0 -10 -2232 111.55 1085.5 -10 -2233 111.60 1086.0 -10 -2234 111.65 1086.5 -10 -2235 111.70 1087.0 -10 -2236 111.75 1087.5 -10 -2237 111.80 1088.0 -10 -2238 111.85 1088.5 -10 -2239 111.90 1089.0 -10 -2240 111.95 1089.5 -10 -2241 112.00 1090.0 -10 -2242 112.05 1090.5 -10 -2243 112.10 1091.0 -10 -2244 112.15 1091.5 -10 -2245 112.20 1092.0 -10 -2246 112.25 1092.5 -10 -2247 112.30 1093.0 -10 -2248 112.35 1093.5 -10 -2249 112.40 1094.0 -10 -2250 112.45 1094.5 -10 -2251 112.50 1095.0 -10 -2252 112.55 1095.5 -10 -2253 112.60 1096.0 -10 -2254 112.65 1096.5 -10 -2255 112.70 1097.0 -10 -2256 112.75 1097.5 -10 -2257 112.80 1098.0 -10 -2258 112.85 1098.5 -10 -2259 112.90 1099.0 -10 -2260 112.95 1099.5 -10 -2261 113.00 1100.0 -10 -2262 113.05 1100.5 -10 -2263 113.10 1101.0 -10 -2264 113.15 1101.5 -10 -2265 113.20 1102.0 -10 -2266 113.25 1102.5 -10 -2267 113.30 1103.0 -10 -2268 113.35 1103.5 -10 -2269 113.40 1104.0 -10 -2270 113.45 1104.5 -10 -2271 113.50 1105.0 -10 -2272 113.55 1105.5 -10 -2273 113.60 1106.0 -10 -2274 113.65 1106.5 -10 -2275 113.70 1107.0 -10 -2276 113.75 1107.5 -10 -2277 113.80 1108.0 -10 -2278 113.85 1108.5 -10 -2279 113.90 1109.0 -10 -2280 113.95 1109.5 -10 -2281 114.00 1110.0 -10 -2282 114.05 1110.5 -10 -2283 114.10 1111.0 -10 -2284 114.15 1111.5 -10 -2285 114.20 1112.0 -10 -2286 114.25 1112.5 -10 -2287 114.30 1113.0 -10 -2288 114.35 1113.5 -10 -2289 114.40 1114.0 -10 -2290 114.45 1114.5 -10 -2291 114.50 1115.0 -10 -2292 114.55 1115.5 -10 -2293 114.60 1116.0 -10 -2294 114.65 1116.5 -10 -2295 114.70 1117.0 -10 -2296 114.75 1117.5 -10 -2297 114.80 1118.0 -10 -2298 114.85 1118.5 -10 -2299 114.90 1119.0 -10 -2300 114.95 1119.5 -10 -2301 115.00 1120.0 -10 -2302 115.05 1120.5 -10 -2303 115.10 1121.0 -10 -2304 115.15 1121.5 -10 -2305 115.20 1122.0 -10 -2306 115.25 1122.5 -10 -2307 115.30 1123.0 -10 -2308 115.35 1123.5 -10 -2309 115.40 1124.0 -10 -2310 115.45 1124.5 -10 -2311 115.50 1125.0 -10 -2312 115.55 1125.5 -10 -2313 115.60 1126.0 -10 -2314 115.65 1126.5 -10 -2315 115.70 1127.0 -10 -2316 115.75 1127.5 -10 -2317 115.80 1128.0 -10 -2318 115.85 1128.5 -10 -2319 115.90 1129.0 -10 -2320 115.95 1129.5 -10 -2321 116.00 1130.0 -10 -2322 116.05 1130.5 -10 -2323 116.10 1131.0 -10 -2324 116.15 1131.5 -10 -2325 116.20 1132.0 -10 -2326 116.25 1132.5 -10 -2327 116.30 1133.0 -10 -2328 116.35 1133.5 -10 -2329 116.40 1134.0 -10 -2330 116.45 1134.5 -10 -2331 116.50 1135.0 -10 -2332 116.55 1135.5 -10 -2333 116.60 1136.0 -10 -2334 116.65 1136.5 -10 -2335 116.70 1137.0 -10 -2336 116.75 1137.5 -10 -2337 116.80 1138.0 -10 -2338 116.85 1138.5 -10 -2339 116.90 1139.0 -10 -2340 116.95 1139.5 -10 -2341 117.00 1140.0 -10 -2342 117.05 1140.5 -10 -2343 117.10 1141.0 -10 -2344 117.15 1141.5 -10 -2345 117.20 1142.0 -10 -2346 117.25 1142.5 -10 -2347 117.30 1143.0 -10 -2348 117.35 1143.5 -10 -2349 117.40 1144.0 -10 -2350 117.45 1144.5 -10 -2351 117.50 1145.0 -10 -2352 117.55 1145.5 -10 -2353 117.60 1146.0 -10 -2354 117.65 1146.5 -10 -2355 117.70 1147.0 -10 -2356 117.75 1147.5 -10 -2357 117.80 1148.0 -10 -2358 117.85 1148.5 -10 -2359 117.90 1149.0 -10 -2360 117.95 1149.5 -10 -2361 118.00 1150.0 -10 -2362 118.05 1150.5 -10 -2363 118.10 1151.0 -10 -2364 118.15 1151.5 -10 -2365 118.20 1152.0 -10 -2366 118.25 1152.5 -10 -2367 118.30 1153.0 -10 -2368 118.35 1153.5 -10 -2369 118.40 1154.0 -10 -2370 118.45 1154.5 -10 -2371 118.50 1155.0 -10 -2372 118.55 1155.5 -10 -2373 118.60 1156.0 -10 -2374 118.65 1156.5 -10 -2375 118.70 1157.0 -10 -2376 118.75 1157.5 -10 -2377 118.80 1158.0 -10 -2378 118.85 1158.5 -10 -2379 118.90 1159.0 -10 -2380 118.95 1159.5 -10 -2381 119.00 1160.0 -10 -2382 119.05 1160.5 -10 -2383 119.10 1161.0 -10 -2384 119.15 1161.5 -10 -2385 119.20 1162.0 -10 -2386 119.25 1162.5 -10 -2387 119.30 1163.0 -10 -2388 119.35 1163.5 -10 -2389 119.40 1164.0 -10 -2390 119.45 1164.5 -10 -2391 119.50 1165.0 -10 -2392 119.55 1165.5 -10 -2393 119.60 1166.0 -10 -2394 119.65 1166.5 -10 -2395 119.70 1167.0 -10 -2396 119.75 1167.5 -10 -2397 119.80 1168.0 -10 -2398 119.85 1168.5 -10 -2399 119.90 1169.0 -10 -2400 119.95 1169.5 -10 -2401 120.00 1170.0 -10 -2402 120.05 1170.5 -10 -2403 120.10 1171.0 -10 -2404 120.15 1171.5 -10 -2405 120.20 1172.0 -10 -2406 120.25 1172.5 -10 -2407 120.30 1173.0 -10 -2408 120.35 1173.5 -10 -2409 120.40 1174.0 -10 -2410 120.45 1174.5 -10 -2411 120.50 1175.0 -10 -2412 120.55 1175.5 -10 -2413 120.60 1176.0 -10 -2414 120.65 1176.5 -10 -2415 120.70 1177.0 -10 -2416 120.75 1177.5 -10 -2417 120.80 1178.0 -10 -2418 120.85 1178.5 -10 -2419 120.90 1179.0 -10 -2420 120.95 1179.5 -10 -2421 121.00 1180.0 -10 -2422 121.05 1180.5 -10 -2423 121.10 1181.0 -10 -2424 121.15 1181.5 -10 -2425 121.20 1182.0 -10 -2426 121.25 1182.5 -10 -2427 121.30 1183.0 -10 -2428 121.35 1183.5 -10 -2429 121.40 1184.0 -10 -2430 121.45 1184.5 -10 -2431 121.50 1185.0 -10 -2432 121.55 1185.5 -10 -2433 121.60 1186.0 -10 -2434 121.65 1186.5 -10 -2435 121.70 1187.0 -10 -2436 121.75 1187.5 -10 -2437 121.80 1188.0 -10 -2438 121.85 1188.5 -10 -2439 121.90 1189.0 -10 -2440 121.95 1189.5 -10 -2441 122.00 1190.0 -10 -2442 122.05 1190.5 -10 -2443 122.10 1191.0 -10 -2444 122.15 1191.5 -10 -2445 122.20 1192.0 -10 -2446 122.25 1192.5 -10 -2447 122.30 1193.0 -10 -2448 122.35 1193.5 -10 -2449 122.40 1194.0 -10 -2450 122.45 1194.5 -10 -2451 122.50 1195.0 -10 -2452 122.55 1195.5 -10 -2453 122.60 1196.0 -10 -2454 122.65 1196.5 -10 -2455 122.70 1197.0 -10 -2456 122.75 1197.5 -10 -2457 122.80 1198.0 -10 -2458 122.85 1198.5 -10 -2459 122.90 1199.0 -10 -2460 122.95 1199.5 -10 -2461 123.00 1200.0 -10 -2462 123.05 1200.5 -10 -2463 123.10 1201.0 -10 -2464 123.15 1201.5 -10 -2465 123.20 1202.0 -10 -2466 123.25 1202.5 -10 -2467 123.30 1203.0 -10 -2468 123.35 1203.5 -10 -2469 123.40 1204.0 -10 -2470 123.45 1204.5 -10 -2471 123.50 1205.0 -10 -2472 123.55 1205.5 -10 -2473 123.60 1206.0 -10 -2474 123.65 1206.5 -10 -2475 123.70 1207.0 -10 -2476 123.75 1207.5 -10 -2477 123.80 1208.0 -10 -2478 123.85 1208.5 -10 -2479 123.90 1209.0 -10 -2480 123.95 1209.5 -10 -2481 124.00 1210.0 -10 -2482 124.05 1210.5 -10 -2483 124.10 1211.0 -10 -2484 124.15 1211.5 -10 -2485 124.20 1212.0 -10 -2486 124.25 1212.5 -10 -2487 124.30 1213.0 -10 -2488 124.35 1213.5 -10 -2489 124.40 1214.0 -10 -2490 124.45 1214.5 -10 -2491 124.50 1215.0 -10 -2492 124.55 1215.5 -10 -2493 124.60 1216.0 -10 -2494 124.65 1216.5 -10 -2495 124.70 1217.0 -10 -2496 124.75 1217.5 -10 -2497 124.80 1218.0 -10 -2498 124.85 1218.5 -10 -2499 124.90 1219.0 -10 -2500 124.95 1219.5 -10 -2501 125.00 1220.0 -10 -2502 125.05 1220.5 -10 -2503 125.10 1221.0 -10 -2504 125.15 1221.5 -10 -2505 125.20 1222.0 -10 -2506 125.25 1222.5 -10 -2507 125.30 1223.0 -10 -2508 125.35 1223.5 -10 -2509 125.40 1224.0 -10 -2510 125.45 1224.5 -10 -2511 125.50 1225.0 -10 -2512 125.55 1225.5 -10 -2513 125.60 1226.0 -10 -2514 125.65 1226.5 -10 -2515 125.70 1227.0 -10 -2516 125.75 1227.5 -10 -2517 125.80 1228.0 -10 -2518 125.85 1228.5 -10 -2519 125.90 1229.0 -10 -2520 125.95 1229.5 -10 -2521 126.00 1230.0 -10 -2522 126.05 1230.5 -10 -2523 126.10 1231.0 -10 -2524 126.15 1231.5 -10 -2525 126.20 1232.0 -10 -2526 126.25 1232.5 -10 -2527 126.30 1233.0 -10 -2528 126.35 1233.5 -10 -2529 126.40 1234.0 -10 -2530 126.45 1234.5 -10 -2531 126.50 1235.0 -10 -2532 126.55 1235.5 -10 -2533 126.60 1236.0 -10 -2534 126.65 1236.5 -10 -2535 126.70 1237.0 -10 -2536 126.75 1237.5 -10 -2537 126.80 1238.0 -10 -2538 126.85 1238.5 -10 -2539 126.90 1239.0 -10 -2540 126.95 1239.5 -10 -2541 127.00 1240.0 -10 -2542 127.05 1240.5 -10 -2543 127.10 1241.0 -10 -2544 127.15 1241.5 -10 -2545 127.20 1242.0 -10 -2546 127.25 1242.5 -10 -2547 127.30 1243.0 -10 -2548 127.35 1243.5 -10 -2549 127.40 1244.0 -10 -2550 127.45 1244.5 -10 -2551 127.50 1245.0 -10 -2552 127.55 1245.5 -10 -2553 127.60 1246.0 -10 -2554 127.65 1246.5 -10 -2555 127.70 1247.0 -10 -2556 127.75 1247.5 -10 -2557 127.80 1248.0 -10 -2558 127.85 1248.5 -10 -2559 127.90 1249.0 -10 -2560 127.95 1249.5 -10 -2561 128.00 1250.0 -10 -2562 128.05 1250.5 -10 -2563 128.10 1251.0 -10 -2564 128.15 1251.5 -10 -2565 128.20 1252.0 -10 -2566 128.25 1252.5 -10 -2567 128.30 1253.0 -10 -2568 128.35 1253.5 -10 -2569 128.40 1254.0 -10 -2570 128.45 1254.5 -10 -2571 128.50 1255.0 -10 -2572 128.55 1255.5 -10 -2573 128.60 1256.0 -10 -2574 128.65 1256.5 -10 -2575 128.70 1257.0 -10 -2576 128.75 1257.5 -10 -2577 128.80 1258.0 -10 -2578 128.85 1258.5 -10 -2579 128.90 1259.0 -10 -2580 128.95 1259.5 -10 -2581 129.00 1260.0 -10 -2582 129.05 1260.5 -10 -2583 129.10 1261.0 -10 -2584 129.15 1261.5 -10 -2585 129.20 1262.0 -10 -2586 129.25 1262.5 -10 -2587 129.30 1263.0 -10 -2588 129.35 1263.5 -10 -2589 129.40 1264.0 -10 -2590 129.45 1264.5 -10 -2591 129.50 1265.0 -10 -2592 129.55 1265.5 -10 -2593 129.60 1266.0 -10 -2594 129.65 1266.5 -10 -2595 129.70 1267.0 -10 -2596 129.75 1267.5 -10 -2597 129.80 1268.0 -10 -2598 129.85 1268.5 -10 -2599 129.90 1269.0 -10 -2600 129.95 1269.5 -10 -2601 130.00 1270.0 -10 -2602 130.05 1270.5 -10 -2603 130.10 1271.0 -10 -2604 130.15 1271.5 -10 -2605 130.20 1272.0 -10 -2606 130.25 1272.5 -10 -2607 130.30 1273.0 -10 -2608 130.35 1273.5 -10 -2609 130.40 1274.0 -10 -2610 130.45 1274.5 -10 -2611 130.50 1275.0 -10 -2612 130.55 1275.5 -10 -2613 130.60 1276.0 -10 -2614 130.65 1276.5 -10 -2615 130.70 1277.0 -10 -2616 130.75 1277.5 -10 -2617 130.80 1278.0 -10 -2618 130.85 1278.5 -10 -2619 130.90 1279.0 -10 -2620 130.95 1279.5 -10 -2621 131.00 1280.0 -10 -2622 131.05 1280.5 -10 -2623 131.10 1281.0 -10 -2624 131.15 1281.5 -10 -2625 131.20 1282.0 -10 -2626 131.25 1282.5 -10 -2627 131.30 1283.0 -10 -2628 131.35 1283.5 -10 -2629 131.40 1284.0 -10 -2630 131.45 1284.5 -10 -2631 131.50 1285.0 -10 -2632 131.55 1285.5 -10 -2633 131.60 1286.0 -10 -2634 131.65 1286.5 -10 -2635 131.70 1287.0 -10 -2636 131.75 1287.5 -10 -2637 131.80 1288.0 -10 -2638 131.85 1288.5 -10 -2639 131.90 1289.0 -10 -2640 131.95 1289.5 -10 -2641 132.00 1290.0 -10 -2642 132.05 1290.5 -10 -2643 132.10 1291.0 -10 -2644 132.15 1291.5 -10 -2645 132.20 1292.0 -10 -2646 132.25 1292.5 -10 -2647 132.30 1293.0 -10 -2648 132.35 1293.5 -10 -2649 132.40 1294.0 -10 -2650 132.45 1294.5 -10 -2651 132.50 1295.0 -10 -2652 132.55 1295.5 -10 -2653 132.60 1296.0 -10 -2654 132.65 1296.5 -10 -2655 132.70 1297.0 -10 -2656 132.75 1297.5 -10 -2657 132.80 1298.0 -10 -2658 132.85 1298.5 -10 -2659 132.90 1299.0 -10 -2660 132.95 1299.5 -10 -2661 133.00 1300.0 -10 -2662 133.05 1300.5 -10 -2663 133.10 1301.0 -10 -2664 133.15 1301.5 -10 -2665 133.20 1302.0 -10 -2666 133.25 1302.5 -10 -2667 133.30 1303.0 -10 -2668 133.35 1303.5 -10 -2669 133.40 1304.0 -10 -2670 133.45 1304.5 -10 -2671 133.50 1305.0 -10 -2672 133.55 1305.5 -10 -2673 133.60 1306.0 -10 -2674 133.65 1306.5 -10 -2675 133.70 1307.0 -10 -2676 133.75 1307.5 -10 -2677 133.80 1308.0 -10 -2678 133.85 1308.5 -10 -2679 133.90 1309.0 -10 -2680 133.95 1309.5 -10 -2681 134.00 1310.0 -10 -2682 134.05 1310.5 -10 -2683 134.10 1311.0 -10 -2684 134.15 1311.5 -10 -2685 134.20 1312.0 -10 -2686 134.25 1312.5 -10 -2687 134.30 1313.0 -10 -2688 134.35 1313.5 -10 -2689 134.40 1314.0 -10 -2690 134.45 1314.5 -10 -2691 134.50 1315.0 -10 -2692 134.55 1315.5 -10 -2693 134.60 1316.0 -10 -2694 134.65 1316.5 -10 -2695 134.70 1317.0 -10 -2696 134.75 1317.5 -10 -2697 134.80 1318.0 -10 -2698 134.85 1318.5 -10 -2699 134.90 1319.0 -10 -2700 134.95 1319.5 -10 -2701 135.00 1320.0 -10 -2702 135.05 1320.5 -10 -2703 135.10 1321.0 -10 -2704 135.15 1321.5 -10 -2705 135.20 1322.0 -10 -2706 135.25 1322.5 -10 -2707 135.30 1323.0 -10 -2708 135.35 1323.5 -10 -2709 135.40 1324.0 -10 -2710 135.45 1324.5 -10 -2711 135.50 1325.0 -10 -2712 135.55 1325.5 -10 -2713 135.60 1326.0 -10 -2714 135.65 1326.5 -10 -2715 135.70 1327.0 -10 -2716 135.75 1327.5 -10 -2717 135.80 1328.0 -10 -2718 135.85 1328.5 -10 -2719 135.90 1329.0 -10 -2720 135.95 1329.5 -10 -2721 136.00 1330.0 -10 -2722 136.05 1330.5 -10 -2723 136.10 1331.0 -10 -2724 136.15 1331.5 -10 -2725 136.20 1332.0 -10 -2726 136.25 1332.5 -10 -2727 136.30 1333.0 -10 -2728 136.35 1333.5 -10 -2729 136.40 1334.0 -10 -2730 136.45 1334.5 -10 -2731 136.50 1335.0 -10 -2732 136.55 1335.5 -10 -2733 136.60 1336.0 -10 -2734 136.65 1336.5 -10 -2735 136.70 1337.0 -10 -2736 136.75 1337.5 -10 -2737 136.80 1338.0 -10 -2738 136.85 1338.5 -10 -2739 136.90 1339.0 -10 -2740 136.95 1339.5 -10 -2741 137.00 1340.0 -10 -2742 137.05 1340.5 -10 -2743 137.10 1341.0 -10 -2744 137.15 1341.5 -10 -2745 137.20 1342.0 -10 -2746 137.25 1342.5 -10 -2747 137.30 1343.0 -10 -2748 137.35 1343.5 -10 -2749 137.40 1344.0 -10 -2750 137.45 1344.5 -10 -2751 137.50 1345.0 -10 -2752 137.55 1345.5 -10 -2753 137.60 1346.0 -10 -2754 137.65 1346.5 -10 -2755 137.70 1347.0 -10 -2756 137.75 1347.5 -10 -2757 137.80 1348.0 -10 -2758 137.85 1348.5 -10 -2759 137.90 1349.0 -10 -2760 137.95 1349.5 -10 -2761 138.00 1350.0 -10 -2762 138.05 1350.5 -10 -2763 138.10 1351.0 -10 -2764 138.15 1351.5 -10 -2765 138.20 1352.0 -10 -2766 138.25 1352.5 -10 -2767 138.30 1353.0 -10 -2768 138.35 1353.5 -10 -2769 138.40 1354.0 -10 -2770 138.45 1354.5 -10 -2771 138.50 1355.0 -10 -2772 138.55 1355.5 -10 -2773 138.60 1356.0 -10 -2774 138.65 1356.5 -10 -2775 138.70 1357.0 -10 -2776 138.75 1357.5 -10 -2777 138.80 1358.0 -10 -2778 138.85 1358.5 -10 -2779 138.90 1359.0 -10 -2780 138.95 1359.5 -10 -2781 139.00 1360.0 -10 -2782 139.05 1360.5 -10 -2783 139.10 1361.0 -10 -2784 139.15 1361.5 -10 -2785 139.20 1362.0 -10 -2786 139.25 1362.5 -10 -2787 139.30 1363.0 -10 -2788 139.35 1363.5 -10 -2789 139.40 1364.0 -10 -2790 139.45 1364.5 -10 -2791 139.50 1365.0 -10 -2792 139.55 1365.5 -10 -2793 139.60 1366.0 -10 -2794 139.65 1366.5 -10 -2795 139.70 1367.0 -10 -2796 139.75 1367.5 -10 -2797 139.80 1368.0 -10 -2798 139.85 1368.5 -10 -2799 139.90 1369.0 -10 -2800 139.95 1369.5 -10 -2801 140.00 1370.0 -10 -2802 140.05 1370.5 -10 -2803 140.10 1371.0 -10 -2804 140.15 1371.5 -10 -2805 140.20 1372.0 -10 -2806 140.25 1372.5 -10 -2807 140.30 1373.0 -10 -2808 140.35 1373.5 -10 -2809 140.40 1374.0 -10 -2810 140.45 1374.5 -10 -2811 140.50 1375.0 -10 -2812 140.55 1375.5 -10 -2813 140.60 1376.0 -10 -2814 140.65 1376.5 -10 -2815 140.70 1377.0 -10 -2816 140.75 1377.5 -10 -2817 140.80 1378.0 -10 -2818 140.85 1378.5 -10 -2819 140.90 1379.0 -10 -2820 140.95 1379.5 -10 -2821 141.00 1380.0 -10 -2822 141.05 1380.5 -10 -2823 141.10 1381.0 -10 -2824 141.15 1381.5 -10 -2825 141.20 1382.0 -10 -2826 141.25 1382.5 -10 -2827 141.30 1383.0 -10 -2828 141.35 1383.5 -10 -2829 141.40 1384.0 -10 -2830 141.45 1384.5 -10 -2831 141.50 1385.0 -10 -2832 141.55 1385.5 -10 -2833 141.60 1386.0 -10 -2834 141.65 1386.5 -10 -2835 141.70 1387.0 -10 -2836 141.75 1387.5 -10 -2837 141.80 1388.0 -10 -2838 141.85 1388.5 -10 -2839 141.90 1389.0 -10 -2840 141.95 1389.5 -10 -2841 142.00 1390.0 -10 -2842 142.05 1390.5 -10 -2843 142.10 1391.0 -10 -2844 142.15 1391.5 -10 -2845 142.20 1392.0 -10 -2846 142.25 1392.5 -10 -2847 142.30 1393.0 -10 -2848 142.35 1393.5 -10 -2849 142.40 1394.0 -10 -2850 142.45 1394.5 -10 -2851 142.50 1395.0 -10 -2852 142.55 1395.5 -10 -2853 142.60 1396.0 -10 -2854 142.65 1396.5 -10 -2855 142.70 1397.0 -10 -2856 142.75 1397.5 -10 -2857 142.80 1398.0 -10 -2858 142.85 1398.5 -10 -2859 142.90 1399.0 -10 -2860 142.95 1399.5 -10 -2861 143.00 1400.0 -10 -2862 143.05 1400.5 -10 -2863 143.10 1401.0 -10 -2864 143.15 1401.5 -10 -2865 143.20 1402.0 -10 -2866 143.25 1402.5 -10 -2867 143.30 1403.0 -10 -2868 143.35 1403.5 -10 -2869 143.40 1404.0 -10 -2870 143.45 1404.5 -10 -2871 143.50 1405.0 -10 -2872 143.55 1405.5 -10 -2873 143.60 1406.0 -10 -2874 143.65 1406.5 -10 -2875 143.70 1407.0 -10 -2876 143.75 1407.5 -10 -2877 143.80 1408.0 -10 -2878 143.85 1408.5 -10 -2879 143.90 1409.0 -10 -2880 143.95 1409.5 -10 -2881 144.00 1410.0 -10 -2882 144.05 1410.5 -10 -2883 144.10 1411.0 -10 -2884 144.15 1411.5 -10 -2885 144.20 1412.0 -10 -2886 144.25 1412.5 -10 -2887 144.30 1413.0 -10 -2888 144.35 1413.5 -10 -2889 144.40 1414.0 -10 -2890 144.45 1414.5 -10 -2891 144.50 1415.0 -10 -2892 144.55 1415.5 -10 -2893 144.60 1416.0 -10 -2894 144.65 1416.5 -10 -2895 144.70 1417.0 -10 -2896 144.75 1417.5 -10 -2897 144.80 1418.0 -10 -2898 144.85 1418.5 -10 -2899 144.90 1419.0 -10 -2900 144.95 1419.5 -10 -2901 145.00 1420.0 -10 -2902 145.05 1420.5 -10 -2903 145.10 1421.0 -10 -2904 145.15 1421.5 -10 -2905 145.20 1422.0 -10 -2906 145.25 1422.5 -10 -2907 145.30 1423.0 -10 -2908 145.35 1423.5 -10 -2909 145.40 1424.0 -10 -2910 145.45 1424.5 -10 -2911 145.50 1425.0 -10 -2912 145.55 1425.5 -10 -2913 145.60 1426.0 -10 -2914 145.65 1426.5 -10 -2915 145.70 1427.0 -10 -2916 145.75 1427.5 -10 -2917 145.80 1428.0 -10 -2918 145.85 1428.5 -10 -2919 145.90 1429.0 -10 -2920 145.95 1429.5 -10 -2921 146.00 1430.0 -10 -2922 146.05 1430.5 -10 -2923 146.10 1431.0 -10 -2924 146.15 1431.5 -10 -2925 146.20 1432.0 -10 -2926 146.25 1432.5 -10 -2927 146.30 1433.0 -10 -2928 146.35 1433.5 -10 -2929 146.40 1434.0 -10 -2930 146.45 1434.5 -10 -2931 146.50 1435.0 -10 -2932 146.55 1435.5 -10 -2933 146.60 1436.0 -10 -2934 146.65 1436.5 -10 -2935 146.70 1437.0 -10 -2936 146.75 1437.5 -10 -2937 146.80 1438.0 -10 -2938 146.85 1438.5 -10 -2939 146.90 1439.0 -10 -2940 146.95 1439.5 -10 -2941 147.00 1440.0 -10 -2942 147.05 1440.5 -10 -2943 147.10 1441.0 -10 -2944 147.15 1441.5 -10 -2945 147.20 1442.0 -10 -2946 147.25 1442.5 -10 -2947 147.30 1443.0 -10 -2948 147.35 1443.5 -10 -2949 147.40 1444.0 -10 -2950 147.45 1444.5 -10 -2951 147.50 1445.0 -10 -2952 147.55 1445.5 -10 -2953 147.60 1446.0 -10 -2954 147.65 1446.5 -10 -2955 147.70 1447.0 -10 -2956 147.75 1447.5 -10 -2957 147.80 1448.0 -10 -2958 147.85 1448.5 -10 -2959 147.90 1449.0 -10 -2960 147.95 1449.5 -10 -2961 148.00 1450.0 -10 -2962 148.05 1450.5 -10 -2963 148.10 1451.0 -10 -2964 148.15 1451.5 -10 -2965 148.20 1452.0 -10 -2966 148.25 1452.5 -10 -2967 148.30 1453.0 -10 -2968 148.35 1453.5 -10 -2969 148.40 1454.0 -10 -2970 148.45 1454.5 -10 -2971 148.50 1455.0 -10 -2972 148.55 1455.5 -10 -2973 148.60 1456.0 -10 -2974 148.65 1456.5 -10 -2975 148.70 1457.0 -10 -2976 148.75 1457.5 -10 -2977 148.80 1458.0 -10 -2978 148.85 1458.5 -10 -2979 148.90 1459.0 -10 -2980 148.95 1459.5 -10 -2981 149.00 1460.0 -10 -2982 149.05 1460.5 -10 -2983 149.10 1461.0 -10 -2984 149.15 1461.5 -10 -2985 149.20 1462.0 -10 -2986 149.25 1462.5 -10 -2987 149.30 1463.0 -10 -2988 149.35 1463.5 -10 -2989 149.40 1464.0 -10 -2990 149.45 1464.5 -10 -2991 149.50 1465.0 -10 -2992 149.55 1465.5 -10 -2993 149.60 1466.0 -10 -2994 149.65 1466.5 -10 -2995 149.70 1467.0 -10 -2996 149.75 1467.5 -10 -2997 149.80 1468.0 -10 -2998 149.85 1468.5 -10 -2999 149.90 1469.0 -10 -3000 149.95 1469.5 -10 -3001 150.00 1470.0 -10 -3002 150.05 1470.5 -10 -3003 150.10 1471.0 -10 -3004 150.15 1471.5 -10 -3005 150.20 1472.0 -10 -3006 150.25 1472.5 -10 -3007 150.30 1473.0 -10 -3008 150.35 1473.5 -10 -3009 150.40 1474.0 -10 -3010 150.45 1474.5 -10 -3011 150.50 1475.0 -10 -3012 150.55 1475.5 -10 -3013 150.60 1476.0 -10 -3014 150.65 1476.5 -10 -3015 150.70 1477.0 -10 -3016 150.75 1477.5 -10 -3017 150.80 1478.0 -10 -3018 150.85 1478.5 -10 -3019 150.90 1479.0 -10 -3020 150.95 1479.5 -10 -3021 151.00 1480.0 -10 -3022 151.05 1480.5 -10 -3023 151.10 1481.0 -10 -3024 151.15 1481.5 -10 -3025 151.20 1482.0 -10 -3026 151.25 1482.5 -10 -3027 151.30 1483.0 -10 -3028 151.35 1483.5 -10 -3029 151.40 1484.0 -10 -3030 151.45 1484.5 -10 -3031 151.50 1485.0 -10 -3032 151.55 1485.5 -10 -3033 151.60 1486.0 -10 -3034 151.65 1486.5 -10 -3035 151.70 1487.0 -10 -3036 151.75 1487.5 -10 -3037 151.80 1488.0 -10 -3038 151.85 1488.5 -10 -3039 151.90 1489.0 -10 -3040 151.95 1489.5 -10 -3041 152.00 1490.0 -10 -3042 152.05 1490.5 -10 -3043 152.10 1491.0 -10 -3044 152.15 1491.5 -10 -3045 152.20 1492.0 -10 -3046 152.25 1492.5 -10 -3047 152.30 1493.0 -10 -3048 152.35 1493.5 -10 -3049 152.40 1494.0 -10 -3050 152.45 1494.5 -10 -3051 152.50 1495.0 -10 -3052 152.55 1495.5 -10 -3053 152.60 1496.0 -10 -3054 152.65 1496.5 -10 -3055 152.70 1497.0 -10 -3056 152.75 1497.5 -10 -3057 152.80 1498.0 -10 -3058 152.85 1498.5 -10 -3059 152.90 1499.0 -10 -3060 152.95 1499.5 -10 -3061 153.00 1500.0 -10 -3062 153.05 1500.5 -10 -3063 153.10 1501.0 -10 -3064 153.15 1501.5 -10 -3065 153.20 1502.0 -10 -3066 153.25 1502.5 -10 -3067 153.30 1503.0 -10 -3068 153.35 1503.5 -10 -3069 153.40 1504.0 -10 -3070 153.45 1504.5 -10 -3071 153.50 1505.0 -10 -3072 153.55 1505.5 -10 -3073 153.60 1506.0 -10 -3074 153.65 1506.5 -10 -3075 153.70 1507.0 -10 -3076 153.75 1507.5 -10 -3077 153.80 1508.0 -10 -3078 153.85 1508.5 -10 -3079 153.90 1509.0 -10 -3080 153.95 1509.5 -10 -3081 154.00 1510.0 -10 -3082 154.05 1510.5 -10 -3083 154.10 1511.0 -10 -3084 154.15 1511.5 -10 -3085 154.20 1512.0 -10 -3086 154.25 1512.5 -10 -3087 154.30 1513.0 -10 -3088 154.35 1513.5 -10 -3089 154.40 1514.0 -10 -3090 154.45 1514.5 -10 -3091 154.50 1515.0 -10 -3092 154.55 1515.5 -10 -3093 154.60 1516.0 -10 -3094 154.65 1516.5 -10 -3095 154.70 1517.0 -10 -3096 154.75 1517.5 -10 -3097 154.80 1518.0 -10 -3098 154.85 1518.5 -10 -3099 154.90 1519.0 -10 -3100 154.95 1519.5 -10 -3101 155.00 1520.0 -10 -3102 155.05 1520.5 -10 -3103 155.10 1521.0 -10 -3104 155.15 1521.5 -10 -3105 155.20 1522.0 -10 -3106 155.25 1522.5 -10 -3107 155.30 1523.0 -10 -3108 155.35 1523.5 -10 -3109 155.40 1524.0 -10 -3110 155.45 1524.5 -10 -3111 155.50 1525.0 -10 -3112 155.55 1525.5 -10 -3113 155.60 1526.0 -10 -3114 155.65 1526.5 -10 -3115 155.70 1527.0 -10 -3116 155.75 1527.5 -10 -3117 155.80 1528.0 -10 -3118 155.85 1528.5 -10 -3119 155.90 1529.0 -10 -3120 155.95 1529.5 -10 -3121 156.00 1530.0 -10 -3122 156.05 1530.5 -10 -3123 156.10 1531.0 -10 -3124 156.15 1531.5 -10 -3125 156.20 1532.0 -10 -3126 156.25 1532.5 -10 -3127 156.30 1533.0 -10 -3128 156.35 1533.5 -10 -3129 156.40 1534.0 -10 -3130 156.45 1534.5 -10 -3131 156.50 1535.0 -10 -3132 156.55 1535.5 -10 -3133 156.60 1536.0 -10 -3134 156.65 1536.5 -10 -3135 156.70 1537.0 -10 -3136 156.75 1537.5 -10 -3137 156.80 1538.0 -10 -3138 156.85 1538.5 -10 -3139 156.90 1539.0 -10 -3140 156.95 1539.5 -10 -3141 157.00 1540.0 -10 -3142 157.05 1540.5 -10 -3143 157.10 1541.0 -10 -3144 157.15 1541.5 -10 -3145 157.20 1542.0 -10 -3146 157.25 1542.5 -10 -3147 157.30 1543.0 -10 -3148 157.35 1543.5 -10 -3149 157.40 1544.0 -10 -3150 157.45 1544.5 -10 -3151 157.50 1545.0 -10 -3152 157.55 1545.5 -10 -3153 157.60 1546.0 -10 -3154 157.65 1546.5 -10 -3155 157.70 1547.0 -10 -3156 157.75 1547.5 -10 -3157 157.80 1548.0 -10 -3158 157.85 1548.5 -10 -3159 157.90 1549.0 -10 -3160 157.95 1549.5 -10 -3161 158.00 1550.0 -10 -3162 158.05 1550.5 -10 -3163 158.10 1551.0 -10 -3164 158.15 1551.5 -10 -3165 158.20 1552.0 -10 -3166 158.25 1552.5 -10 -3167 158.30 1553.0 -10 -3168 158.35 1553.5 -10 -3169 158.40 1554.0 -10 -3170 158.45 1554.5 -10 -3171 158.50 1555.0 -10 -3172 158.55 1555.5 -10 -3173 158.60 1556.0 -10 -3174 158.65 1556.5 -10 -3175 158.70 1557.0 -10 -3176 158.75 1557.5 -10 -3177 158.80 1558.0 -10 -3178 158.85 1558.5 -10 -3179 158.90 1559.0 -10 -3180 158.95 1559.5 -10 -3181 159.00 1560.0 -10 -3182 159.05 1560.5 -10 -3183 159.10 1561.0 -10 -3184 159.15 1561.5 -10 -3185 159.20 1562.0 -10 -3186 159.25 1562.5 -10 -3187 159.30 1563.0 -10 -3188 159.35 1563.5 -10 -3189 159.40 1564.0 -10 -3190 159.45 1564.5 -10 -3191 159.50 1565.0 -10 -3192 159.55 1565.5 -10 -3193 159.60 1566.0 -10 -3194 159.65 1566.5 -10 -3195 159.70 1567.0 -10 -3196 159.75 1567.5 -10 -3197 159.80 1568.0 -10 -3198 159.85 1568.5 -10 -3199 159.90 1569.0 -10 -3200 159.95 1569.5 -10 -3201 160.00 1570.0 -10 -3202 160.05 1570.5 -10 -3203 160.10 1571.0 -10 -3204 160.15 1571.5 -10 -3205 160.20 1572.0 -10 -3206 160.25 1572.5 -10 -3207 160.30 1573.0 -10 -3208 160.35 1573.5 -10 -3209 160.40 1574.0 -10 -3210 160.45 1574.5 -10 -3211 160.50 1575.0 -10 -3212 160.55 1575.5 -10 -3213 160.60 1576.0 -10 -3214 160.65 1576.5 -10 -3215 160.70 1577.0 -10 -3216 160.75 1577.5 -10 -3217 160.80 1578.0 -10 -3218 160.85 1578.5 -10 -3219 160.90 1579.0 -10 -3220 160.95 1579.5 -10 -3221 161.00 1580.0 -10 -3222 161.05 1580.5 -10 -3223 161.10 1581.0 -10 -3224 161.15 1581.5 -10 -3225 161.20 1582.0 -10 -3226 161.25 1582.5 -10 -3227 161.30 1583.0 -10 -3228 161.35 1583.5 -10 -3229 161.40 1584.0 -10 -3230 161.45 1584.5 -10 -3231 161.50 1585.0 -10 -3232 161.55 1585.5 -10 -3233 161.60 1586.0 -10 -3234 161.65 1586.5 -10 -3235 161.70 1587.0 -10 -3236 161.75 1587.5 -10 -3237 161.80 1588.0 -10 -3238 161.85 1588.5 -10 -3239 161.90 1589.0 -10 -3240 161.95 1589.5 -10 -3241 162.00 1590.0 -10 -3242 162.05 1590.5 -10 -3243 162.10 1591.0 -10 -3244 162.15 1591.5 -10 -3245 162.20 1592.0 -10 -3246 162.25 1592.5 -10 -3247 162.30 1593.0 -10 -3248 162.35 1593.5 -10 -3249 162.40 1594.0 -10 -3250 162.45 1594.5 -10 -3251 162.50 1595.0 -10 -3252 162.55 1595.5 -10 -3253 162.60 1596.0 -10 -3254 162.65 1596.5 -10 -3255 162.70 1597.0 -10 -3256 162.75 1597.5 -10 -3257 162.80 1598.0 -10 -3258 162.85 1598.5 -10 -3259 162.90 1599.0 -10 -3260 162.95 1599.5 -10 -3261 163.00 1600.0 -10 -3262 163.05 1600.5 -10 -3263 163.10 1601.0 -10 -3264 163.15 1601.5 -10 -3265 163.20 1602.0 -10 -3266 163.25 1602.5 -10 -3267 163.30 1603.0 -10 -3268 163.35 1603.5 -10 -3269 163.40 1604.0 -10 -3270 163.45 1604.5 -10 -3271 163.50 1605.0 -10 -3272 163.55 1605.5 -10 -3273 163.60 1606.0 -10 -3274 163.65 1606.5 -10 -3275 163.70 1607.0 -10 -3276 163.75 1607.5 -10 -3277 163.80 1608.0 -10 -3278 163.85 1608.5 -10 -3279 163.90 1609.0 -10 -3280 163.95 1609.5 -10 -3281 164.00 1610.0 -10 -3282 164.05 1610.5 -10 -3283 164.10 1611.0 -10 -3284 164.15 1611.5 -10 -3285 164.20 1612.0 -10 -3286 164.25 1612.5 -10 -3287 164.30 1613.0 -10 -3288 164.35 1613.5 -10 -3289 164.40 1614.0 -10 -3290 164.45 1614.5 -10 -3291 164.50 1615.0 -10 -3292 164.55 1615.5 -10 -3293 164.60 1616.0 -10 -3294 164.65 1616.5 -10 -3295 164.70 1617.0 -10 -3296 164.75 1617.5 -10 -3297 164.80 1618.0 -10 -3298 164.85 1618.5 -10 -3299 164.90 1619.0 -10 -3300 164.95 1619.5 -10 -3301 165.00 1620.0 -10 -3302 165.05 1620.5 -10 -3303 165.10 1621.0 -10 -3304 165.15 1621.5 -10 -3305 165.20 1622.0 -10 -3306 165.25 1622.5 -10 -3307 165.30 1623.0 -10 -3308 165.35 1623.5 -10 -3309 165.40 1624.0 -10 -3310 165.45 1624.5 -10 -3311 165.50 1625.0 -10 -3312 165.55 1625.5 -10 -3313 165.60 1626.0 -10 -3314 165.65 1626.5 -10 -3315 165.70 1627.0 -10 -3316 165.75 1627.5 -10 -3317 165.80 1628.0 -10 -3318 165.85 1628.5 -10 -3319 165.90 1629.0 -10 -3320 165.95 1629.5 -10 -3321 166.00 1630.0 -10 -3322 166.05 1630.5 -10 -3323 166.10 1631.0 -10 -3324 166.15 1631.5 -10 -3325 166.20 1632.0 -10 -3326 166.25 1632.5 -10 -3327 166.30 1633.0 -10 -3328 166.35 1633.5 -10 -3329 166.40 1634.0 -10 -3330 166.45 1634.5 -10 -3331 166.50 1635.0 -10 -3332 166.55 1635.5 -10 -3333 166.60 1636.0 -10 -3334 166.65 1636.5 -10 -3335 166.70 1637.0 -10 -3336 166.75 1637.5 -10 -3337 166.80 1638.0 -10 -3338 166.85 1638.5 -10 -3339 166.90 1639.0 -10 -3340 166.95 1639.5 -10 -3341 167.00 1640.0 -10 -3342 167.05 1640.5 -10 -3343 167.10 1641.0 -10 -3344 167.15 1641.5 -10 -3345 167.20 1642.0 -10 -3346 167.25 1642.5 -10 -3347 167.30 1643.0 -10 -3348 167.35 1643.5 -10 -3349 167.40 1644.0 -10 -3350 167.45 1644.5 -10 -3351 167.50 1645.0 -10 -3352 167.55 1645.5 -10 -3353 167.60 1646.0 -10 -3354 167.65 1646.5 -10 -3355 167.70 1647.0 -10 -3356 167.75 1647.5 -10 -3357 167.80 1648.0 -10 -3358 167.85 1648.5 -10 -3359 167.90 1649.0 -10 -3360 167.95 1649.5 -10 -3361 168.00 1650.0 -10 -3362 168.05 1650.5 -10 -3363 168.10 1651.0 -10 -3364 168.15 1651.5 -10 -3365 168.20 1652.0 -10 -3366 168.25 1652.5 -10 -3367 168.30 1653.0 -10 -3368 168.35 1653.5 -10 -3369 168.40 1654.0 -10 -3370 168.45 1654.5 -10 -3371 168.50 1655.0 -10 -3372 168.55 1655.5 -10 -3373 168.60 1656.0 -10 -3374 168.65 1656.5 -10 -3375 168.70 1657.0 -10 -3376 168.75 1657.5 -10 -3377 168.80 1658.0 -10 -3378 168.85 1658.5 -10 -3379 168.90 1659.0 -10 -3380 168.95 1659.5 -10 -3381 169.00 1660.0 -10 -3382 169.05 1660.5 -10 -3383 169.10 1661.0 -10 -3384 169.15 1661.5 -10 -3385 169.20 1662.0 -10 -3386 169.25 1662.5 -10 -3387 169.30 1663.0 -10 -3388 169.35 1663.5 -10 -3389 169.40 1664.0 -10 -3390 169.45 1664.5 -10 -3391 169.50 1665.0 -10 -3392 169.55 1665.5 -10 -3393 169.60 1666.0 -10 -3394 169.65 1666.5 -10 -3395 169.70 1667.0 -10 -3396 169.75 1667.5 -10 -3397 169.80 1668.0 -10 -3398 169.85 1668.5 -10 -3399 169.90 1669.0 -10 -3400 169.95 1669.5 -10 -3401 170.00 1670.0 -10 -3402 170.05 1670.5 -10 -3403 170.10 1671.0 -10 -3404 170.15 1671.5 -10 -3405 170.20 1672.0 -10 -3406 170.25 1672.5 -10 -3407 170.30 1673.0 -10 -3408 170.35 1673.5 -10 -3409 170.40 1674.0 -10 -3410 170.45 1674.5 -10 -3411 170.50 1675.0 -10 -3412 170.55 1675.5 -10 -3413 170.60 1676.0 -10 -3414 170.65 1676.5 -10 -3415 170.70 1677.0 -10 -3416 170.75 1677.5 -10 -3417 170.80 1678.0 -10 -3418 170.85 1678.5 -10 -3419 170.90 1679.0 -10 -3420 170.95 1679.5 -10 -3421 171.00 1680.0 -10 -3422 171.05 1680.5 -10 -3423 171.10 1681.0 -10 -3424 171.15 1681.5 -10 -3425 171.20 1682.0 -10 -3426 171.25 1682.5 -10 -3427 171.30 1683.0 -10 -3428 171.35 1683.5 -10 -3429 171.40 1684.0 -10 -3430 171.45 1684.5 -10 -3431 171.50 1685.0 -10 -3432 171.55 1685.5 -10 -3433 171.60 1686.0 -10 -3434 171.65 1686.5 -10 -3435 171.70 1687.0 -10 -3436 171.75 1687.5 -10 -3437 171.80 1688.0 -10 -3438 171.85 1688.5 -10 -3439 171.90 1689.0 -10 -3440 171.95 1689.5 -10 -3441 172.00 1690.0 -10 -3442 172.05 1690.5 -10 -3443 172.10 1691.0 -10 -3444 172.15 1691.5 -10 -3445 172.20 1692.0 -10 -3446 172.25 1692.5 -10 -3447 172.30 1693.0 -10 -3448 172.35 1693.5 -10 -3449 172.40 1694.0 -10 -3450 172.45 1694.5 -10 -3451 172.50 1695.0 -10 -3452 172.55 1695.5 -10 -3453 172.60 1696.0 -10 -3454 172.65 1696.5 -10 -3455 172.70 1697.0 -10 -3456 172.75 1697.5 -10 -3457 172.80 1698.0 -10 -3458 172.85 1698.5 -10 -3459 172.90 1699.0 -10 -3460 172.95 1699.5 -10 -3461 173.00 1700.0 -10 -3462 173.05 1700.5 -10 -3463 173.10 1701.0 -10 -3464 173.15 1701.5 -10 -3465 173.20 1702.0 -10 -3466 173.25 1702.5 -10 -3467 173.30 1703.0 -10 -3468 173.35 1703.5 -10 -3469 173.40 1704.0 -10 -3470 173.45 1704.5 -10 -3471 173.50 1705.0 -10 -3472 173.55 1705.5 -10 -3473 173.60 1706.0 -10 -3474 173.65 1706.5 -10 -3475 173.70 1707.0 -10 -3476 173.75 1707.5 -10 -3477 173.80 1708.0 -10 -3478 173.85 1708.5 -10 -3479 173.90 1709.0 -10 -3480 173.95 1709.5 -10 -3481 174.00 1710.0 -10 -3482 174.05 1710.5 -10 -3483 174.10 1711.0 -10 -3484 174.15 1711.5 -10 -3485 174.20 1712.0 -10 -3486 174.25 1712.5 -10 -3487 174.30 1713.0 -10 -3488 174.35 1713.5 -10 -3489 174.40 1714.0 -10 -3490 174.45 1714.5 -10 -3491 174.50 1715.0 -10 -3492 174.55 1715.5 -10 -3493 174.60 1716.0 -10 -3494 174.65 1716.5 -10 -3495 174.70 1717.0 -10 -3496 174.75 1717.5 -10 -3497 174.80 1718.0 -10 -3498 174.85 1718.5 -10 -3499 174.90 1719.0 -10 -3500 174.95 1719.5 -10 -3501 175.00 1720.0 -10 -3502 175.05 1720.5 -10 -3503 175.10 1721.0 -10 -3504 175.15 1721.5 -10 -3505 175.20 1722.0 -10 -3506 175.25 1722.5 -10 -3507 175.30 1723.0 -10 -3508 175.35 1723.5 -10 -3509 175.40 1724.0 -10 -3510 175.45 1724.5 -10 -3511 175.50 1725.0 -10 -3512 175.55 1725.5 -10 -3513 175.60 1726.0 -10 -3514 175.65 1726.5 -10 -3515 175.70 1727.0 -10 -3516 175.75 1727.5 -10 -3517 175.80 1728.0 -10 -3518 175.85 1728.5 -10 -3519 175.90 1729.0 -10 -3520 175.95 1729.5 -10 -3521 176.00 1730.0 -10 -3522 176.05 1730.5 -10 -3523 176.10 1731.0 -10 -3524 176.15 1731.5 -10 -3525 176.20 1732.0 -10 -3526 176.25 1732.5 -10 -3527 176.30 1733.0 -10 -3528 176.35 1733.5 -10 -3529 176.40 1734.0 -10 -3530 176.45 1734.5 -10 -3531 176.50 1735.0 -10 -3532 176.55 1735.5 -10 -3533 176.60 1736.0 -10 -3534 176.65 1736.5 -10 -3535 176.70 1737.0 -10 -3536 176.75 1737.5 -10 -3537 176.80 1738.0 -10 -3538 176.85 1738.5 -10 -3539 176.90 1739.0 -10 -3540 176.95 1739.5 -10 -3541 177.00 1740.0 -10 -3542 177.05 1740.5 -10 -3543 177.10 1741.0 -10 -3544 177.15 1741.5 -10 -3545 177.20 1742.0 -10 -3546 177.25 1742.5 -10 -3547 177.30 1743.0 -10 -3548 177.35 1743.5 -10 -3549 177.40 1744.0 -10 -3550 177.45 1744.5 -10 -3551 177.50 1745.0 -10 -3552 177.55 1745.5 -10 -3553 177.60 1746.0 -10 -3554 177.65 1746.5 -10 -3555 177.70 1747.0 -10 -3556 177.75 1747.5 -10 -3557 177.80 1748.0 -10 -3558 177.85 1748.5 -10 -3559 177.90 1749.0 -10 -3560 177.95 1749.5 -10 -3561 178.00 1750.0 -10 -3562 178.05 1750.5 -10 -3563 178.10 1751.0 -10 -3564 178.15 1751.5 -10 -3565 178.20 1752.0 -10 -3566 178.25 1752.5 -10 -3567 178.30 1753.0 -10 -3568 178.35 1753.5 -10 -3569 178.40 1754.0 -10 -3570 178.45 1754.5 -10 -3571 178.50 1755.0 -10 -3572 178.55 1755.5 -10 -3573 178.60 1756.0 -10 -3574 178.65 1756.5 -10 -3575 178.70 1757.0 -10 -3576 178.75 1757.5 -10 -3577 178.80 1758.0 -10 -3578 178.85 1758.5 -10 -3579 178.90 1759.0 -10 -3580 178.95 1759.5 -10 -3581 179.00 1760.0 -10 -3582 179.05 1760.5 -10 -3583 179.10 1761.0 -10 -3584 179.15 1761.5 -10 -3585 179.20 1762.0 -10 -3586 179.25 1762.5 -10 -3587 179.30 1763.0 -10 -3588 179.35 1763.5 -10 -3589 179.40 1764.0 -10 -3590 179.45 1764.5 -10 -3591 179.50 1765.0 -10 -3592 179.55 1765.5 -10 -3593 179.60 1766.0 -10 -3594 179.65 1766.5 -10 -3595 179.70 1767.0 -10 -3596 179.75 1767.5 -10 -3597 179.80 1768.0 -10 -3598 179.85 1768.5 -10 -3599 179.90 1769.0 -10 -3600 179.95 1769.5 -10 -3601 180.00 1770.0 -10 -3602 180.05 1770.5 -10 -3603 180.10 1771.0 -10 -3604 180.15 1771.5 -10 -3605 180.20 1772.0 -10 -3606 180.25 1772.5 -10 -3607 180.30 1773.0 -10 -3608 180.35 1773.5 -10 -3609 180.40 1774.0 -10 -3610 180.45 1774.5 -10 -3611 180.50 1775.0 -10 -3612 180.55 1775.5 -10 -3613 180.60 1776.0 -10 -3614 180.65 1776.5 -10 -3615 180.70 1777.0 -10 -3616 180.75 1777.5 -10 -3617 180.80 1778.0 -10 -3618 180.85 1778.5 -10 -3619 180.90 1779.0 -10 -3620 180.95 1779.5 -10 -3621 181.00 1780.0 -10 -3622 181.05 1780.5 -10 -3623 181.10 1781.0 -10 -3624 181.15 1781.5 -10 -3625 181.20 1782.0 -10 -3626 181.25 1782.5 -10 -3627 181.30 1783.0 -10 -3628 181.35 1783.5 -10 -3629 181.40 1784.0 -10 -3630 181.45 1784.5 -10 -3631 181.50 1785.0 -10 -3632 181.55 1785.5 -10 -3633 181.60 1786.0 -10 -3634 181.65 1786.5 -10 -3635 181.70 1787.0 -10 -3636 181.75 1787.5 -10 -3637 181.80 1788.0 -10 -3638 181.85 1788.5 -10 -3639 181.90 1789.0 -10 -3640 181.95 1789.5 -10 -3641 182.00 1790.0 -10 -3642 182.05 1790.5 -10 -3643 182.10 1791.0 -10 -3644 182.15 1791.5 -10 -3645 182.20 1792.0 -10 -3646 182.25 1792.5 -10 -3647 182.30 1793.0 -10 -3648 182.35 1793.5 -10 -3649 182.40 1794.0 -10 -3650 182.45 1794.5 -10 -3651 182.50 1795.0 -10 -3652 182.55 1795.5 -10 -3653 182.60 1796.0 -10 -3654 182.65 1796.5 -10 -3655 182.70 1797.0 -10 -3656 182.75 1797.5 -10 -3657 182.80 1798.0 -10 -3658 182.85 1798.5 -10 -3659 182.90 1799.0 -10 -3660 182.95 1799.5 -10 -3661 183.00 1800.0 -10 -3662 183.05 1800.5 -10 -3663 183.10 1801.0 -10 -3664 183.15 1801.5 -10 -3665 183.20 1802.0 -10 -3666 183.25 1802.5 -10 -3667 183.30 1803.0 -10 -3668 183.35 1803.5 -10 -3669 183.40 1804.0 -10 -3670 183.45 1804.5 -10 -3671 183.50 1805.0 -10 -3672 183.55 1805.5 -10 -3673 183.60 1806.0 -10 -3674 183.65 1806.5 -10 -3675 183.70 1807.0 -10 -3676 183.75 1807.5 -10 -3677 183.80 1808.0 -10 -3678 183.85 1808.5 -10 -3679 183.90 1809.0 -10 -3680 183.95 1809.5 -10 -3681 184.00 1810.0 -10 -3682 184.05 1810.5 -10 -3683 184.10 1811.0 -10 -3684 184.15 1811.5 -10 -3685 184.20 1812.0 -10 -3686 184.25 1812.5 -10 -3687 184.30 1813.0 -10 -3688 184.35 1813.5 -10 -3689 184.40 1814.0 -10 -3690 184.45 1814.5 -10 -3691 184.50 1815.0 -10 -3692 184.55 1815.5 -10 -3693 184.60 1816.0 -10 -3694 184.65 1816.5 -10 -3695 184.70 1817.0 -10 -3696 184.75 1817.5 -10 -3697 184.80 1818.0 -10 -3698 184.85 1818.5 -10 -3699 184.90 1819.0 -10 -3700 184.95 1819.5 -10 -3701 185.00 1820.0 -10 -3702 185.05 1820.5 -10 -3703 185.10 1821.0 -10 -3704 185.15 1821.5 -10 -3705 185.20 1822.0 -10 -3706 185.25 1822.5 -10 -3707 185.30 1823.0 -10 -3708 185.35 1823.5 -10 -3709 185.40 1824.0 -10 -3710 185.45 1824.5 -10 -3711 185.50 1825.0 -10 -3712 185.55 1825.5 -10 -3713 185.60 1826.0 -10 -3714 185.65 1826.5 -10 -3715 185.70 1827.0 -10 -3716 185.75 1827.5 -10 -3717 185.80 1828.0 -10 -3718 185.85 1828.5 -10 -3719 185.90 1829.0 -10 -3720 185.95 1829.5 -10 -3721 186.00 1830.0 -10 -3722 186.05 1830.5 -10 -3723 186.10 1831.0 -10 -3724 186.15 1831.5 -10 -3725 186.20 1832.0 -10 -3726 186.25 1832.5 -10 -3727 186.30 1833.0 -10 -3728 186.35 1833.5 -10 -3729 186.40 1834.0 -10 -3730 186.45 1834.5 -10 -3731 186.50 1835.0 -10 -3732 186.55 1835.5 -10 -3733 186.60 1836.0 -10 -3734 186.65 1836.5 -10 -3735 186.70 1837.0 -10 -3736 186.75 1837.5 -10 -3737 186.80 1838.0 -10 -3738 186.85 1838.5 -10 -3739 186.90 1839.0 -10 -3740 186.95 1839.5 -10 -3741 187.00 1840.0 -10 -3742 187.05 1840.5 -10 -3743 187.10 1841.0 -10 -3744 187.15 1841.5 -10 -3745 187.20 1842.0 -10 -3746 187.25 1842.5 -10 -3747 187.30 1843.0 -10 -3748 187.35 1843.5 -10 -3749 187.40 1844.0 -10 -3750 187.45 1844.5 -10 -3751 187.50 1845.0 -10 -3752 187.55 1845.5 -10 -3753 187.60 1846.0 -10 -3754 187.65 1846.5 -10 -3755 187.70 1847.0 -10 -3756 187.75 1847.5 -10 -3757 187.80 1848.0 -10 -3758 187.85 1848.5 -10 -3759 187.90 1849.0 -10 -3760 187.95 1849.5 -10 -3761 188.00 1850.0 -10 -3762 188.05 1850.5 -10 -3763 188.10 1851.0 -10 -3764 188.15 1851.5 -10 -3765 188.20 1852.0 -10 -3766 188.25 1852.5 -10 -3767 188.30 1853.0 -10 -3768 188.35 1853.5 -10 -3769 188.40 1854.0 -10 -3770 188.45 1854.5 -10 -3771 188.50 1855.0 -10 -3772 188.55 1855.5 -10 -3773 188.60 1856.0 -10 -3774 188.65 1856.5 -10 -3775 188.70 1857.0 -10 -3776 188.75 1857.5 -10 -3777 188.80 1858.0 -10 -3778 188.85 1858.5 -10 -3779 188.90 1859.0 -10 -3780 188.95 1859.5 -10 -3781 189.00 1860.0 -10 -3782 189.05 1860.5 -10 -3783 189.10 1861.0 -10 -3784 189.15 1861.5 -10 -3785 189.20 1862.0 -10 -3786 189.25 1862.5 -10 -3787 189.30 1863.0 -10 -3788 189.35 1863.5 -10 -3789 189.40 1864.0 -10 -3790 189.45 1864.5 -10 -3791 189.50 1865.0 -10 -3792 189.55 1865.5 -10 -3793 189.60 1866.0 -10 -3794 189.65 1866.5 -10 -3795 189.70 1867.0 -10 -3796 189.75 1867.5 -10 -3797 189.80 1868.0 -10 -3798 189.85 1868.5 -10 -3799 189.90 1869.0 -10 -3800 189.95 1869.5 -10 -3801 190.00 1870.0 -10 -3802 190.05 1870.5 -10 -3803 190.10 1871.0 -10 -3804 190.15 1871.5 -10 -3805 190.20 1872.0 -10 -3806 190.25 1872.5 -10 -3807 190.30 1873.0 -10 -3808 190.35 1873.5 -10 -3809 190.40 1874.0 -10 -3810 190.45 1874.5 -10 -3811 190.50 1875.0 -10 -3812 190.55 1875.5 -10 -3813 190.60 1876.0 -10 -3814 190.65 1876.5 -10 -3815 190.70 1877.0 -10 -3816 190.75 1877.5 -10 -3817 190.80 1878.0 -10 -3818 190.85 1878.5 -10 -3819 190.90 1879.0 -10 -3820 190.95 1879.5 -10 -3821 191.00 1880.0 -10 -3822 191.05 1880.5 -10 -3823 191.10 1881.0 -10 -3824 191.15 1881.5 -10 -3825 191.20 1882.0 -10 -3826 191.25 1882.5 -10 -3827 191.30 1883.0 -10 -3828 191.35 1883.5 -10 -3829 191.40 1884.0 -10 -3830 191.45 1884.5 -10 -3831 191.50 1885.0 -10 -3832 191.55 1885.5 -10 -3833 191.60 1886.0 -10 -3834 191.65 1886.5 -10 -3835 191.70 1887.0 -10 -3836 191.75 1887.5 -10 -3837 191.80 1888.0 -10 -3838 191.85 1888.5 -10 -3839 191.90 1889.0 -10 -3840 191.95 1889.5 -10 -3841 192.00 1890.0 -10 -3842 192.05 1890.5 -10 -3843 192.10 1891.0 -10 -3844 192.15 1891.5 -10 -3845 192.20 1892.0 -10 -3846 192.25 1892.5 -10 -3847 192.30 1893.0 -10 -3848 192.35 1893.5 -10 -3849 192.40 1894.0 -10 -3850 192.45 1894.5 -10 -3851 192.50 1895.0 -10 -3852 192.55 1895.5 -10 -3853 192.60 1896.0 -10 -3854 192.65 1896.5 -10 -3855 192.70 1897.0 -10 -3856 192.75 1897.5 -10 -3857 192.80 1898.0 -10 -3858 192.85 1898.5 -10 -3859 192.90 1899.0 -10 -3860 192.95 1899.5 -10 -3861 193.00 1900.0 -10 -3862 193.05 1900.5 -10 -3863 193.10 1901.0 -10 -3864 193.15 1901.5 -10 -3865 193.20 1902.0 -10 -3866 193.25 1902.5 -10 -3867 193.30 1903.0 -10 -3868 193.35 1903.5 -10 -3869 193.40 1904.0 -10 -3870 193.45 1904.5 -10 -3871 193.50 1905.0 -10 -3872 193.55 1905.5 -10 -3873 193.60 1906.0 -10 -3874 193.65 1906.5 -10 -3875 193.70 1907.0 -10 -3876 193.75 1907.5 -10 -3877 193.80 1908.0 -10 -3878 193.85 1908.5 -10 -3879 193.90 1909.0 -10 -3880 193.95 1909.5 -10 -3881 194.00 1910.0 -10 -3882 194.05 1910.5 -10 -3883 194.10 1911.0 -10 -3884 194.15 1911.5 -10 -3885 194.20 1912.0 -10 -3886 194.25 1912.5 -10 -3887 194.30 1913.0 -10 -3888 194.35 1913.5 -10 -3889 194.40 1914.0 -10 -3890 194.45 1914.5 -10 -3891 194.50 1915.0 -10 -3892 194.55 1915.5 -10 -3893 194.60 1916.0 -10 -3894 194.65 1916.5 -10 -3895 194.70 1917.0 -10 -3896 194.75 1917.5 -10 -3897 194.80 1918.0 -10 -3898 194.85 1918.5 -10 -3899 194.90 1919.0 -10 -3900 194.95 1919.5 -10 -3901 195.00 1920.0 -10 -3902 195.05 1920.5 -10 -3903 195.10 1921.0 -10 -3904 195.15 1921.5 -10 -3905 195.20 1922.0 -10 -3906 195.25 1922.5 -10 -3907 195.30 1923.0 -10 -3908 195.35 1923.5 -10 -3909 195.40 1924.0 -10 -3910 195.45 1924.5 -10 -3911 195.50 1925.0 -10 -3912 195.55 1925.5 -10 -3913 195.60 1926.0 -10 -3914 195.65 1926.5 -10 -3915 195.70 1927.0 -10 -3916 195.75 1927.5 -10 -3917 195.80 1928.0 -10 -3918 195.85 1928.5 -10 -3919 195.90 1929.0 -10 -3920 195.95 1929.5 -10 -3921 196.00 1930.0 -10 -3922 196.05 1930.5 -10 -3923 196.10 1931.0 -10 -3924 196.15 1931.5 -10 -3925 196.20 1932.0 -10 -3926 196.25 1932.5 -10 -3927 196.30 1933.0 -10 -3928 196.35 1933.5 -10 -3929 196.40 1934.0 -10 -3930 196.45 1934.5 -10 -3931 196.50 1935.0 -10 -3932 196.55 1935.5 -10 -3933 196.60 1936.0 -10 -3934 196.65 1936.5 -10 -3935 196.70 1937.0 -10 -3936 196.75 1937.5 -10 -3937 196.80 1938.0 -10 -3938 196.85 1938.5 -10 -3939 196.90 1939.0 -10 -3940 196.95 1939.5 -10 -3941 197.00 1940.0 -10 -3942 197.05 1940.5 -10 -3943 197.10 1941.0 -10 -3944 197.15 1941.5 -10 -3945 197.20 1942.0 -10 -3946 197.25 1942.5 -10 -3947 197.30 1943.0 -10 -3948 197.35 1943.5 -10 -3949 197.40 1944.0 -10 -3950 197.45 1944.5 -10 -3951 197.50 1945.0 -10 -3952 197.55 1945.5 -10 -3953 197.60 1946.0 -10 -3954 197.65 1946.5 -10 -3955 197.70 1947.0 -10 -3956 197.75 1947.5 -10 -3957 197.80 1948.0 -10 -3958 197.85 1948.5 -10 -3959 197.90 1949.0 -10 -3960 197.95 1949.5 -10 -3961 198.00 1950.0 -10 -3962 198.05 1950.5 -10 -3963 198.10 1951.0 -10 -3964 198.15 1951.5 -10 -3965 198.20 1952.0 -10 -3966 198.25 1952.5 -10 -3967 198.30 1953.0 -10 -3968 198.35 1953.5 -10 -3969 198.40 1954.0 -10 -3970 198.45 1954.5 -10 -3971 198.50 1955.0 -10 -3972 198.55 1955.5 -10 -3973 198.60 1956.0 -10 -3974 198.65 1956.5 -10 -3975 198.70 1957.0 -10 -3976 198.75 1957.5 -10 -3977 198.80 1958.0 -10 -3978 198.85 1958.5 -10 -3979 198.90 1959.0 -10 -3980 198.95 1959.5 -10 -3981 199.00 1960.0 -10 -3982 199.05 1960.5 -10 -3983 199.10 1961.0 -10 -3984 199.15 1961.5 -10 -3985 199.20 1962.0 -10 -3986 199.25 1962.5 -10 -3987 199.30 1963.0 -10 -3988 199.35 1963.5 -10 -3989 199.40 1964.0 -10 -3990 199.45 1964.5 -10 -3991 199.50 1965.0 -10 -3992 199.55 1965.5 -10 -3993 199.60 1966.0 -10 -3994 199.65 1966.5 -10 -3995 199.70 1967.0 -10 -3996 199.75 1967.5 -10 -3997 199.80 1968.0 -10 -3998 199.85 1968.5 -10 -3999 199.90 1969.0 -10 -4000 199.95 1969.5 -10 -4001 200.00 1970.0 -10 diff --git a/tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/run.in.min b/tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/run.in.min deleted file mode 100644 index c8c28cd7a1..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/run.in.min +++ /dev/null @@ -1,41 +0,0 @@ -######################################################### -# Example how to run this file: -# -# 1) Choose a ransom seed (in this case 141203) -# (or use `bash -c 'echo $RANDOM'`) -# -# 2) Then, from the shell, invoke LAMMPS to collapse the polymer: -# -# lmp_ubuntu_parallel -i run.in -var seed 141203 -# -######################################################### -# eg: -# time mpirun -np 2 lmp_ubuntu_parallel -i run.in.min -######################################################### - -# -- Init Section -- - -include system.in.init - -# -- Atom Definition Section -- - -read_data system.data - -# -- Settings Section -- - -include system.in.settings - -# -- Run Section -- - -dump 1 all custom 10000 traj_min.lammpstrj id mol type x y z ix iy iz -thermo_style custom step pe etotal vol epair ebond eangle edihed -thermo_modify norm no #(report total energy not energy / num_atoms) -thermo 100 #(time interval for printing out "thermo" data) - -# Now minimize the system: - -min_style quickmin -min_modify dmax 0.05 -minimize 1.0e-7 1.0e-8 30000 100000000 - -write_data system_after_min.data diff --git a/tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/run.in.stage1 b/tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/run.in.stage1 deleted file mode 100644 index bf129df04f..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/run.in.stage1 +++ /dev/null @@ -1,110 +0,0 @@ -# PREREQUISITES: You must run LAMMPS using "run.in.min" beforehand. -# (This will create the "system_after_min0.data" file needed below.) -######################################################### -# Run using: -# -# lmp_ubuntu_parallel -i run.in.stage1 -# -######################################################### -# GPUs: -# To enable gpu acceleration, make sure settings.in.init includes this line: -# package gpu force/neigh 0 0 1.0 (make sure it is not commented out.) -# ...and replace "lj/cut" in the "settings.in.init" and "settings.in.settings" -# files with "lj/cut/gpu" - - -# -- Init Section -- - -include system.in.init - -# -- Atom Definition Section -- - -#read_data system.data -read_data system_after_min.data - -# -- Settings Section -- - -include system.in.settings - -# -- Run Section -- - -# DON'T MINIMIZE FIRST UNLESS YOU CHOOSE THE CORRECT INITIAL KbondC FORMULA -#thermo_style custom step pe etotal vol epair ebond eangle edihed -#thermo_modify norm no #(report total energy not energy / num_atoms) -#thermo 20 #(time interval for printing out "thermo" data) -#min_style sd -#min_modify dmax 0.05 -#minimize 1.0e-7 1.0e-8 20000 1000000 -#write_data system_after_min_t=0.data - - -mass * 1.0 -timestep 0.005 # "dt" -dump 1 all custom 25000 traj_stage1.lammpstrj id mol type x y z ix iy iz -reset_timestep 0 - - -# --- run the simulation --- - - -# set the velocity to zero -velocity all create 0.0 123456 - -# To use Langevin dynamics in LAMMPS you need both "fix langevin" and "fix nve" -# (See http://lammps.sandia.gov/doc/fix_langevin.html for details.) - -# Tstart Tstop tdamp randomseed - -fix fxlan all langevin 1.0 1.0 10.0 123456 - -# pstart pstop pdamp(time-units, 2000 iters usually) -#fix fxnph all nph x -0.000 -0.000 1.0 -fix fxnve all nve -# (See http://lammps.sandia.gov/doc/fix_langevin.html) - -fix fxcenter all recenter 0.0 0.0 0.0 - -thermo_style custom step temp pe etotal press vol epair ebond eangle edihed -thermo_modify norm no #(report total energy not energy / num_atoms) -thermo 1000 #(time interval for printing out "thermo" data) - -#balance dynamic x 20 1.0 -out tmp.balance -#balance x uniform - - -variable nloop1 loop 300 - - label loop1 - - print "############### LOOP ${nloop1} ###############" - - # Now, change the bond-strength between condensin monomers. - # From the Naumova et al Science 2013 paper (supp materials) - # "Two-stage model: linear compaction + axial compression" - # "First, random consecutive loops with L=100 monomers (see above) were - # introduced, and anchors of neighboring loops were brought together - # using harmonic springs with a potential U = k * (r – r0)2; r0=0.5. - # To avoid abrupt motion of the loop anchors, the force was gradually - # turned on over the first 300000 timesteps, with k linearly increasing - # in time from 0 to 10 kT." - # Do this by changing the parameters in the force-field for these - # bonds. - # - # Formula used for "bond_style harmonic": - # Ubond(r) = k*(r-r0)^2 - # bondType style - #bond_coeff 1 harmonic 0.1 0.5 - - variable time equal step - variable KbondC equal $((v_time+1)*(10.0/300000.0)) - print "timestep = ${time}, KbondC = ${KbondC}" file KbondC_vs_time.dat - - #bond_coeff 1 harmonic ${KbondC} 0.5 - bond_coeff 1 harmonic ${KbondC} 0.5 - run 1000 - - next nloop1 - jump SELF loop1 - -write_data system_after_stage1.data - diff --git a/tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/run.in.stage2 b/tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/run.in.stage2 deleted file mode 100644 index e429fc8825..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/chromosome_metaphase_Naumova2013/run.in.stage2 +++ /dev/null @@ -1,90 +0,0 @@ -# PREREQUISITES: You must run LAMMPS using "run.in.stage1" beforehand. -# (This will create the "system_after_stage1.data" file.) -######################################################### -# Run using: -# -# lmp_ubuntu_parallel -i run.in.stage2 -# -######################################################### -# eg: -# time mpirun -np 2 lmp_ubuntu_parallel -i run.in -var seed 1 -######################################################### -# GPUs: -# To enable gpu acceleration, make sure settings.in.init includes this line: -# package gpu force/neigh 0 0 1.0 (make sure it is not commented out.) -# ...and replace "lj/cut" in the "settings.in.init" and "settings.in.settings" -# files with "lj/cut/gpu" - - -# -- Init Section -- - -include system.in.init - -# -- Atom Definition Section -- - -#read_data system.data -read_data system_after_stage1.data - -# -- Settings Section -- - -include system.in.settings - -# -- Run Section -- - - -mass * 1.0 -timestep 0.005 # "dt" -dump 1 all custom 50000 traj_stage2.lammpstrj id mol type x y z ix iy iz -reset_timestep 300000 - - -# --- run the simulation --- - -# set the velocity to zero -velocity all create 0.0 123456 - -# To use Langevin dynamics in LAMMPS you need both "fix langevin" and "fix nve" -# (See http://lammps.sandia.gov/doc/fix_langevin.html for details.) - -# Tstart Tstop tdamp randomseed - -fix fxlan all langevin 1.0 1.0 10.0 123456 - -# pstart pstop pdamp(time-units, 2000 iters usually) -fix fxnve all nve -# (See http://lammps.sandia.gov/doc/fix_langevin.html) - -fix fxcenter all recenter 0.0 0.0 0.0 - -thermo_style custom step temp pe etotal press vol epair ebond eangle edihed -thermo_modify norm no #(report total energy not energy / num_atoms) -thermo 1000 #(time interval for printing out "thermo" data) - -#balance dynamic x 20 1.0 -out tmp.balance -#balance x uniform - -# atomTypes pairStyle epsilon sigma rcutoff -# 10nm-fiber -#pair_coeff 1 1 lj/cut 1.0 1.0 2.5 -#pair_coeff 2 2 lj/cut 1.0 1.0 2.5 -# 30nm fiber (4.25^(1/3)=1.6198059006387417) -pair_coeff 1 1 lj/cut 1.0 1.6198059006387417 4.049514751596854 -pair_coeff 2 2 lj/cut 1.0 1.6198059006387417 4.049514751596854 - - -# During stage 2, add attractive forces between all pairs of non-consecutive -# condensin anchors. These forces are stored in the table file below: -# bondType bondStyle filename label -bond_coeff 2 table table_bonds_stage2.dat STAGE2 - -# During stage 2, I assume the stage-1 bonds remain in place -# (They have length 0.5. -# After 300000 timesteps during stage 1, the "k" value should be 10.0.) - -# bondType bondStyle k r0 -bond_coeff 1 harmonic 10.0 0.5 - -timestep 0.005 -run 1700000 - -write_data system_after_stage2.data diff --git a/tools/moltemplate/examples/coarse_grained_examples/membrane+protein/README.TXT b/tools/moltemplate/examples/coarse_grained_examples/membrane+protein/README.TXT deleted file mode 100644 index 09abbc4b2a..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/membrane+protein/README.TXT +++ /dev/null @@ -1,70 +0,0 @@ - This example shows how to put a protein (inclusion) in a - lipid bilayer mixture composed of two different lipids (DPPC and DLPC). - The DPPC lipid model is described here: - G. Brannigan, P.F. Philips, and F.L.H. Brown, - Physical Review E, Vol 72, 011915 (2005) - (The DLPC model is a truncated version of DPPC. Modifications discussed below.) - The protein model is described here: - G. Bellesia, AI Jewett, and J-E Shea, - Protein Science, Vol19 141-154 (2010) - ---- PREREQUISITES: --- - -1) This example requires the "dihedral_style fourier", which is currently -in the USER-MISC package. Build LAMMPS with this package enabled using - make yes-user-misc -before compiling LAMMPS. -(See http://lammps.sandia.gov/doc/Section_start.html#start_3 for details.) - -2) This example may require additional features to be added to LAMMPS. -If LAMMPS complains about an "Invalid pair_style", then - a) download the "additional_lammps_code" from - http://moltemplate.org (upper-left corner menu) - b) unpack it - c) copy the .cpp and .h files to the src folding of your lammps installation. - d) (re)compile LAMMPS. - - ------ Details -------- - -This example contains a coarse-grained model of a 4-helix bundle protein -inserted into a lipid bilayer (made from a mixture of DPPC and DLPC). - - -- Protein Model: -- - -The coarse-grained protein is described in: - G. Bellesia, AI Jewett, and J-E Shea, Protein Science, Vol19 141-154 (2010) -Here we use the "AUF2" model described in that paper. -(The hydrophobic beads face outwards.) - - -- Memebrane Model: -- - -The DPPC lipid bilayer described in: - G. Brannigan, P.F. Philips, and F.L.H. Brown, - Physical Review E, Vol 72, 011915 (2005) -and: - M.C. Watson, E.S. Penev, P.M. Welch, and F.L.H. Brown - J. Chem. Phys. 135, 244701 (2011) - -As in Watson(JCP 2011), rigid bond-length constraints -have been replaced by harmonic bonds. - -A truncated version of this lipid (named "DLPC") has also been added. -The bending stiffness of each lipid has been increased to compensate -for the additional disorder resulting from mixing two different types -of lipids together. (Otherwise pores appear.) -Unlike the original "DPPC" molecule model, the new "DPPC" and "DLPC" models -have not been carefully parameterized to reproduce the correct behavior in -a lipid bilayer mixture. - - -------------- - -Instructions on how to build LAMMPS input files and -run a short simulation are provided in other README files. - -step 1) -README_setup.sh - -step2) -README_run.sh diff --git a/tools/moltemplate/examples/coarse_grained_examples/membrane+protein/README_WARNING.TXT b/tools/moltemplate/examples/coarse_grained_examples/membrane+protein/README_WARNING.TXT deleted file mode 100644 index 8864c3e047..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/membrane+protein/README_WARNING.TXT +++ /dev/null @@ -1,10 +0,0 @@ -WARNING: - - This is not a realistic simulation of proteins in a lipid membrane. This -example was only intented to be a technical demonstration to show how to -combine totally different kinds of coarse-grained molecules (with different -kinds of force-fields) together in the same simulation in LAMMPS. Tuning the -force-field parameters to get realistic results was not the goal. I did -not take the extra time to do this. If you have suggestions for changes, -please email me (jewett.aij at gmail dot com). - diff --git a/tools/moltemplate/examples/coarse_grained_examples/membrane+protein/README_run.sh b/tools/moltemplate/examples/coarse_grained_examples/membrane+protein/README_run.sh deleted file mode 100755 index d7ea305695..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/membrane+protein/README_run.sh +++ /dev/null @@ -1,33 +0,0 @@ -# --- Running LAMMPS --- -# -- Prerequisites: -- -# The "run.in.nvt" file is a LAMMPS input script containing -# references to the input scripts and data files -# you hopefully have created earlier with moltemplate.sh: -# system.in.init, system.in.settings, system.data, and table_int.dat -# If not, carry out the instructions in "README_setup.sh". -# -# -- Instructions: -- -# If "lmp_mpi" is the name of the command you use to invoke lammps, -# then you would run lammps on these files this way: - - -lmp_mpi -i run.in.npt # Run a simulation at constant pressure (tension) - -#or - -lmp_mpi -i run.in.nvt # Run a simulation at constant volume - -#(Note: The constant volume simulation lacks pressure equilibration. These are -# completely separate simulations. The results of the constant pressure -# simulation are ignored when beginning the simulation at constant volume. -# This can be fixed. Read "run.in.nvt" for equilibration instructions.) - - - - - -# If you have compiled the MPI version of lammps, you can run lammps in parallel -#mpirun -np 4 lmp_mpi -i run.in.npt -#or -#mpirun -np 4 lmp_mpi -i run.in.nvt -# (assuming you have 4 processors available) diff --git a/tools/moltemplate/examples/coarse_grained_examples/membrane+protein/README_setup.sh b/tools/moltemplate/examples/coarse_grained_examples/membrane+protein/README_setup.sh deleted file mode 100755 index abf2fce64b..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/membrane+protein/README_setup.sh +++ /dev/null @@ -1,28 +0,0 @@ -# Use these commands to generate the LAMMPS input script and data file -# (and other auxilliary files): - - -# Create LAMMPS input files this way: -cd moltemplate_files - - # run moltemplate - - moltemplate.sh system.lt - - # This will generate various files with names ending in *.in* and *.data. - # These files are the input files directly read by LAMMPS. Move them to - # the parent directory (or wherever you plan to run the simulation). - - mv -f system.in* system.data ../ - - # The "table_int.dat" file contains tabular data for the lipid INT-INT atom - # 1/r^2 interaction. We need it too. (This slows down the simulation by x2, - # so I might look for a way to get rid of it later.) - cp -f table_int.dat ../ - - # Optional: - # The "./output_ttree/" directory is full of temporary files generated by - # moltemplate. They can be useful for debugging, but are usually thrown away. - rm -rf output_ttree/ - -cd ../ diff --git a/tools/moltemplate/examples/coarse_grained_examples/membrane+protein/README_visualize.txt b/tools/moltemplate/examples/coarse_grained_examples/membrane+protein/README_visualize.txt deleted file mode 100644 index 019afc1444..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/membrane+protein/README_visualize.txt +++ /dev/null @@ -1,87 +0,0 @@ - - ------- To view a lammps trajectory in VMD -------- - - -1) Build a PSF file for use in viewing with VMD. - -This step works with VMD 1.9 and topotools 1.2. -(Older versions, like VMD 1.8.6, don't support this.) - - -a) Start VMD -b) Menu Extensions->Tk Console -c) Enter: - -(I assume that the the DATA file is called "system.data") - - topo readlammpsdata system.data full - animate write psf system.psf - -2) - -Later, to Load a trajectory in VMD: - - Start VMD - Select menu: File->New Molecule - -Browse to select the PSF file you created above, and load it. - (Don't close the window yet.) - -Browse to select the trajectory file. - If necessary, for "file type" select: "LAMMPS Trajectory" - Load it. - - ---- A note on trajectory format: ----- -If the trajectory is a DUMP file, then make sure the it contains the -information you need for pbctools (see below. I've been using this -command in my LAMMPS scripts to create the trajectories: - - dump 1 all custom 5000 DUMP_FILE.lammpstrj id mol type x y z ix iy iz - -It's a good idea to use an atom_style which supports molecule-ID numbers -so that you can assign a molecule-ID number to each atom. (I think this -is needed to wrap atom coordinates without breaking molecules in half.) - -Of course, you don't have to save your trajectories in DUMP format, -(other formats like DCD work fine) I just mention dump files -because these are the files I'm familiar with. - -3) ----- Wrap the coordinates to the unit cell - (without cutting the molecules in half) - -a) Start VMD -b) Load the trajectory in VMD (see above) -c) Menu Extensions->Tk Console -d) Try entering these commands: - - pbc wrap -compound res -all - pbc box - - ----- Optional ---- - Sometimes the solvent or membrane obscures the view of the solute. - It can help to shift the location of the periodic boundary box - To shift the box in the y direction (for example) do this: - - pbc wrap -compound res -all -shiftcenterrel {0.0 0.15 0.0} - pbc box -shiftcenterrel {0.0 0.15 0.0} - - Distances are measured in units of box-length fractions, not Angstroms. - - Alternately if you have a solute whose atoms are all of type 1, - then you can also try this to center the box around it: - - pbc wrap -sel type=1 -all -centersel type=2 -center com - -4) - You should check if your periodic boundary conditions are too small. - To do that: - select Graphics->Representations menu option - click on the "Periodic" tab, and - click on the "+x", "-x", "+y", "-y", "+z", "-z" checkboxes. - -5) Optional: If you like, change the atom types in the PSF file so - that VMD recognizes the atom types, use something like: - -sed -e 's/ 1 1 / C C /g' < system.psf > temp1.psf -sed -e 's/ 2 2 / H H /g' < temp1.psf > temp2.psf -sed -e 's/ 3 3 / P P /g' < temp2.psf > system.psf - -(If you do this, it might effect step 2 above.) diff --git a/tools/moltemplate/examples/coarse_grained_examples/membrane+protein/images/4HelixOrig+Lipid2005_t=1290ps_LR.jpg b/tools/moltemplate/examples/coarse_grained_examples/membrane+protein/images/4HelixOrig+Lipid2005_t=1290ps_LR.jpg deleted file mode 100644 index 246ee5462527237be5bf22d1e13febf7624317fb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 85276 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

s#DTdz)ZurbwJ$Q&K&BZ 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%0D9MP@*)QXcRnjgu^%fU0RbA1#sBWrB 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≧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%0A*Wivi-|YgLstDm@A#L%74sj>i-RA5 z-e=1hiV9*hW-B6PB)0!mwkGMRzj@vr!u91-P>Wx5yC3}cv4oRFKGvI{4*Hpfd$vw~ z)}^M$3G)o-rKfT|H2fduv&)ltOGGc`TBCQhCq&$9Ni3!mT{=@3D-+gv=2_ZU$$2Nt_Kbi8D=kp z#?g1m@}_+Om}L5TL1u7|NF76c&BWj$=1XWp1z|ZPoA;gI+qXbuov}%l@eMC`0sw~3 zI0!K)nAh~QyFI#mUhc|HdVR57Ubf+H#jT^t3UAH%D{AyDxF1j7x8YYFV05metjAV2ByT=o^`P!(TegDSlu zy>XpYVIcqHvhIZ%F@*tim$`)86jl;-hWyB#V zo0)U#F94Sx$EpUH;iESI7P~~&JDx*m7UZ-GTGZQ(izag!4;oatZM!{cOXk(3Y(+>G zTm+m48>=Z_YHO2c+He^Ry3jDVO~O@DlQ(h;_E`%(1Rw+(%neQo+Z76pJdK5# zZ51P3ryghaVj77dbv?VLY<&DvH0+{*G?o_j&;;|cGo-SI{nr4&5$f7uVI@0GOMV1fKcR8#GtaJdXcOJAdl{#A350pLf zpkd|RtMo}TAB-3-ul2F=E;3i|BYFb#b*$P>?+{0gSfs9!3L;}$n(V`b;0|JtlO*8& z(T>P=4!ZDajL`U@3sZ?(-ks|LGIt+Oc7GSNX1asht*xTR8!={%VlKs+zI=11>SA%i zP=d6Zw5wy@@;c>Urro0bupi3}C8`tpSu`h=Czmg6qx8(lgPdZ*rNU1tWWI@|b*v@AV}IBT}N z{?U<(Z&T^WsmZy|UBCDE@w?xWU~yEHEv-+#E*~d-iwux_tT$2fiAqBb zD>^=1VV$3I*L&ubIp-Legk1+7S4!V@QG%;-oNuZ=-c*yFbxUoWdZ`k5 S+I979?Q8!(8-erJ>%RfXm|lAT diff --git a/tools/moltemplate/examples/coarse_grained_examples/membrane+protein/images/membrane+protein_t=0ps_top_LR.jpg b/tools/moltemplate/examples/coarse_grained_examples/membrane+protein/images/membrane+protein_t=0ps_top_LR.jpg deleted file mode 100644 index 5d4b15b2915334c23729930bd2680b5a817a2413..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 67085 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�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 diff --git a/tools/moltemplate/examples/coarse_grained_examples/membrane+protein/moltemplate_files/1beadProtSci2010.lt b/tools/moltemplate/examples/coarse_grained_examples/membrane+protein/moltemplate_files/1beadProtSci2010.lt deleted file mode 100644 index 2e510ebd9e..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/membrane+protein/moltemplate_files/1beadProtSci2010.lt +++ /dev/null @@ -1,233 +0,0 @@ -# This file defines a 4-helix bundle coarse-grained protein model (AUF2) used in -# G. Bellesia, AI Jewett, and J-E Shea, -# Protein Science, Vol19 141-154 (2010) -# -# Strategy: -# -#1) First I'll define some building blocks (A16, B16, T3) -# which are helices, sheets and turns of a predetermined length) -# -#2) Then I'll copy and paste them together to build -# a 4-helix bundle (or a 4-strand beta-barrel). -# This approach is optional. If your protein has helices which are not -# identical, you should probably just include all 4 helices in a single -# "Data Atoms" section and don't try to subdivide the protein into pieces.) - - - -1beadProtSci2010 { # <-- enclose definitions in a namespace for portability - - # A16 is a coarse-grained alpha-helix containing 16 residues (one "atom" each) - - A16 { - - # AtomID MoleculeID AtomType Charge X Y Z - - write('Data Atoms') { - $atom:a1 $mol:... @atom:../sL 0.0 -2.4 -2.4 0.0 - $atom:a2 $mol:... @atom:../sL 0.0 2.4 -2.4 3.6 - $atom:a3 $mol:... @atom:../sH 0.0 2.4 2.4 7.2 - $atom:a4 $mol:... @atom:../sH 0.0 -2.4 2.4 10.8 - $atom:a5 $mol:... @atom:../sL 0.0 -2.4 -2.4 14.4 - $atom:a6 $mol:... @atom:../sL 0.0 2.4 -2.4 18.0 - $atom:a7 $mol:... @atom:../sH 0.0 2.4 2.4 21.6 - $atom:a8 $mol:... @atom:../sH 0.0 -2.4 2.4 25.2 - $atom:a9 $mol:... @atom:../sL 0.0 -2.4 -2.4 28.8 - $atom:a10 $mol:... @atom:../sL 0.0 2.4 -2.4 32.4 - $atom:a11 $mol:... @atom:../sH 0.0 2.4 2.4 36.0 - $atom:a12 $mol:... @atom:../sH 0.0 -2.4 2.4 39.6 - $atom:a13 $mol:... @atom:../sL 0.0 -2.4 -2.4 43.2 - $atom:a14 $mol:... @atom:../sL 0.0 2.4 -2.4 46.8 - $atom:a15 $mol:... @atom:../sH 0.0 2.4 2.4 50.4 - $atom:a16 $mol:... @atom:../sH 0.0 -2.4 2.4 54.0 - } - - write('Data Bonds') { - $bond:b1 @bond:../backbone $atom:a1 $atom:a2 - $bond:b2 @bond:../backbone $atom:a2 $atom:a3 - $bond:b3 @bond:../backbone $atom:a3 $atom:a4 - $bond:b4 @bond:../backbone $atom:a4 $atom:a5 - $bond:b5 @bond:../backbone $atom:a5 $atom:a6 - $bond:b6 @bond:../backbone $atom:a6 $atom:a7 - $bond:b7 @bond:../backbone $atom:a7 $atom:a8 - $bond:b8 @bond:../backbone $atom:a8 $atom:a9 - $bond:b9 @bond:../backbone $atom:a9 $atom:a10 - $bond:b10 @bond:../backbone $atom:a10 $atom:a11 - $bond:b11 @bond:../backbone $atom:a11 $atom:a12 - $bond:b12 @bond:../backbone $atom:a12 $atom:a13 - $bond:b13 @bond:../backbone $atom:a13 $atom:a14 - $bond:b14 @bond:../backbone $atom:a14 $atom:a15 - $bond:b15 @bond:../backbone $atom:a15 $atom:a16 - } - - } # A16 - - - T3 { # T3 is a "turn" region consisting of 3 beads - - # AtomID MoleculeID AtomType Charge X Y Z - - write('Data Atoms') { - $atom:a1 $mol:... @atom:../tN 0.0 -4.8 0.0 0.0 - $atom:a2 $mol:... @atom:../tN 0.0 0.0 3.3 -1.44 - $atom:a3 $mol:... @atom:../tN 0.0 4.8 0.0 0.0 - } - - write('Data Bonds') { - $bond:b1 @bond:../backbone $atom:a1 $atom:a2 - $bond:b2 @bond:../backbone $atom:a2 $atom:a3 - } - - } # T3 - - - # ----- Now build a larger molecule using A16 and T3 ------- - - # Create a 4-Helix bundle. - # In this version, the hydrophobic beads are poing outward. - # I oriented them this way because I want to place this protein in a membrane. - # (There is another file in this directory containing alternate version - # of this same molecule with the hydrophobic beads pointing inward.) - - 4HelixInsideOut { - helix1 = new A16.rot(-225, 0,0,1).move(-5.70,-5.70,-32.4) - helix2 = new A16.rot(-135, 0,0,1).move( 5.70,-5.70,-28.8) - helix3 = new A16.rot( -45, 0,0,1).move( 5.70, 5.70,-25.2) - helix4 = new A16.rot( 45, 0,0,1).move(-5.70, 5.70,-21.6) - - turn1 = new T3.rot(180,1,0,0).rot(-20,0,1,0).rot( 10,0,0,1).move(0.78,-4.2, 27.9) - turn2 = new T3.rot(-10,1,0,0).rot( 20,0,1,0).rot(-70,0,0,1).move(4.55, 2.4,-33.0) - turn3 = new T3.rot(180,1,0,0).rot(-20,0,1,0).rot(190,0,0,1).move(-0.78,4.2, 34.2) - - write('Data Bonds') { - $bond:turn1a @bond:../backbone $atom:turn1/a1 $atom:helix1/a16 - $bond:turn1b @bond:../backbone $atom:turn1/a3 $atom:helix2/a16 - $bond:turn2a @bond:../backbone $atom:turn2/a1 $atom:helix3/a1 - $bond:turn2b @bond:../backbone $atom:turn2/a3 $atom:helix2/a1 - $bond:turn3a @bond:../backbone $atom:turn3/a1 $atom:helix3/a16 - $bond:turn3b @bond:../backbone $atom:turn3/a3 $atom:helix4/a16 - } - create_var { $mol } # molecule ID number shared by all atoms in this protein - - } # 4HelixInsideOut - - - # -------- Minor coordinates adjustment: ----------- - - # Those coordinates in the commands above are a little too large. - # To make it easier to type them in, I was using sigma=6.0 Angstroms. - # Instead, here I'll try using sigma=4.8 Angstroms. 4.8/6 = 0.8) - - 4HelixInsideOut.scale(0.8) - - # Note: "scale()" only effects the initial coordinates of - # the molecule, not the force field parameters. - # (If you plan to minimize the molecule, you don't need to - # be so careful about the initial coordinates. In that case, - # you don't have worry about "scale()". Feel free to remove.) - - - - # -------------- Force-Field Parameters ------------ - - # Units and force-field styles for this protein model - # (These can be overridden later.) - - write_once("In Init") { - units real - atom_style full - bond_style hybrid harmonic - angle_style hybrid harmonic - dihedral_style hybrid fourier - pair_style hybrid lj/charmm/coul/charmm/inter es4k4l maxmax 21.0 24.0 - pair_modify mix arithmetic - special_bonds lj 0.0 0.0 1.0 #(turn on "1-4" interactions) - } - - # --- Distance Units --- - # In this version of the model, sigma (the bond-length - # and particle diameter) is rounded to 4.8 Angstroms. - # - # --- Energy & Temperature Units --- - # In this protein model, "epsilon" represents the free energy - # bonus for bringing two hydrophobic amino acids together. - # Here I choose to set epsilon to 1.806551818181818 kCal/mole. - # This value was chosen so that a temperature of 300 Kelvin lies at - # 0.33 epsilon, which is the unfolding temperature of the marginally stable - # "ASF1" protein model from the Bellesia et al 2010 paper. - # This choice insures that both the "ASF1" model from that paper, - # as well as the much more stable "AUF2" protein we use here (which - # unfolds at 0.42*eps) should definitely remain stable at 300 degrees Kelvin, - # in the bulk at least. (However it's not clear that these energy - # parameters will work well for a protein in membrane. Perhaps I'll - # run some tests and fine tune these parameters for this scenario.) - - - # 2-body (non-bonded) interactions: - # - # Uij(r) = 4*eps_ij * (K*(sig_ij/r)^12 + L*(sig_ij/r)^6) - # - # i j pairstylename eps sig K L - # - write_once("In Settings") { - pair_coeff @atom:sH @atom:sH lj/charmm/coul/charmm/inter 1.8065518 4.8 1 -1 - pair_coeff @atom:sL @atom:sL lj/charmm/coul/charmm/inter 1.8065518 4.8 1 0 - pair_coeff @atom:tN @atom:tN lj/charmm/coul/charmm/inter 1.8065518 4.8 1 0 - } - - # The exact value of the bond_coeff does not matter too much as long as - # it is "stiff enough". Here I use a softer bond spring than the one - # used in the paper so that I can increase the time step. - # I also use a relatively soft spring to constrain the bond angles. - - # bond_coeff bondType bondstylename k r0 - - write_once("In Settings") { - bond_coeff @bond:1beadProtSci2010/backbone harmonic 10.0 4.8 - } - - - # angleType atomtypes1 2 3 bondtypes1 2 - - write_once("Data Angles By Type") { - @angle:backbone @atom:* @atom:* @atom:* @bond:* @bond:* - } - - # angle_coeff angleType anglestylename k theta0 - write_once("In Settings") { - angle_coeff @angle:backbone harmonic 100.0 105.0 - } - - - # dihedralType atomtypes1 2 3 4 bondtypes1 2 3 - - write_once("Data Dihedrals By Type") { - # For a chain of sH and sL atoms, use the @dihedral:delta65_0 - # parameters. (This corresponds to the "AUF2" model from the - # Bellesia et. al 2010 paper.) - - @dihedral:delta65_0 @atom:s* @atom:s* @atom:s* @atom:s* * * * - - # If "tN" (turn) atoms are present, use the @dihedral:turn parameters - - @dihedral:turn @atom:tN @atom:* @atom:* @atom:* * * * - } - - write_once("In Settings") { - dihedral_coeff @dihedral:delta60_0 fourier 2 2.167862 3 0 2.167862 1 -60.0 - dihedral_coeff @dihedral:delta65_0 fourier 2 2.167862 3 0 2.167862 1 -65.0 - dihedral_coeff @dihedral:turn fourier 1 0.361310 3 0 - # Note: 2.167862=1.2*epsilon and 0.361310=0.2*epsilon. - } - - - # --- Mass Units --- - # Typical amino acids weigh approximately 110.0 grams/mole. (Rounding down): - write_once("Data Masses") { - @atom:1beadProtSci2010/sH 100.0 - @atom:1beadProtSci2010/sL 100.0 - @atom:1beadProtSci2010/tN 100.0 - } - -} # 1beadProtSci2010 (namespace) - diff --git a/tools/moltemplate/examples/coarse_grained_examples/membrane+protein/moltemplate_files/1beadProtSci2010_variations.lt b/tools/moltemplate/examples/coarse_grained_examples/membrane+protein/moltemplate_files/1beadProtSci2010_variations.lt deleted file mode 100644 index 38b1b48f88..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/membrane+protein/moltemplate_files/1beadProtSci2010_variations.lt +++ /dev/null @@ -1,225 +0,0 @@ -### THIS FILE IS OPTIONAL AND IS NOT NECESSARY. IN THIS FILE, I DEFINED SOME ## -### ADDITIONAL PROTEIN TYPES FROM THE PAPER THAT I DID NOT USE IN THIS EXAMPLE## -# -# This file defines a family of coarse-grained protein models used in: -# G. Bellesia, AI Jewett, and J-E Shea, -# Protein Science, Vol19 141-154 (2010) -# -# Strategy: -# -#1) First I'll define some building blocks (A16, B16, T3) -# which are helices, sheets and turns of a predetermined length) - -import "1beadProtSci2010.lt" - -# We defined A16 and T3 earlier in "1beadPRotSci2010.lt" Will define B16 below -# -#2) Then I'll copy and paste them together to build -# a 4-helix bundle or a 4-strand beta-barrel. - - -1beadProtSci2010 { #<-- Add new molecules to existing namespace defined earlier - # This way we don't have to start from scratch. We can - # use all the atom types and angle settings defined earlier - - # B16 is a coarse-grained beta-strand containing 16 residues (one "atom" each) - - B16 { - - # AtomID MoleculeID AtomType Charge X Y Z - - write('Data Atoms') { - $atom:a1 $mol:... @atom:../sL 0.0 -1.8 0.0 0.0 - $atom:a2 $mol:... @atom:../sH 0.0 1.8 0.0 4.8 - $atom:a3 $mol:... @atom:../sL 0.0 -1.8 0.0 9.6 - $atom:a4 $mol:... @atom:../sH 0.0 1.8 0.0 14.4 - $atom:a5 $mol:... @atom:../sL 0.0 -1.8 0.0 19.2 - $atom:a6 $mol:... @atom:../sH 0.0 1.8 0.0 24.0 - $atom:a7 $mol:... @atom:../sL 0.0 -1.8 0.0 28.8 - $atom:a8 $mol:... @atom:../sH 0.0 1.8 0.0 33.6 - $atom:a9 $mol:... @atom:../sL 0.0 -1.8 0.0 38.4 - $atom:a10 $mol:... @atom:../sH 0.0 1.8 0.0 43.2 - $atom:a11 $mol:... @atom:../sL 0.0 -1.8 0.0 48.0 - $atom:a12 $mol:... @atom:../sH 0.0 1.8 0.0 52.8 - $atom:a13 $mol:... @atom:../sL 0.0 -1.8 0.0 57.6 - $atom:a14 $mol:... @atom:../sH 0.0 1.8 0.0 62.4 - $atom:a15 $mol:... @atom:../sL 0.0 -1.8 0.0 67.2 - $atom:a16 $mol:... @atom:../sH 0.0 1.8 0.0 72.0 - } - - write('Data Bonds') { - $bond:b1 @bond:../backbone $atom:a1 $atom:a2 - $bond:b2 @bond:../backbone $atom:a2 $atom:a3 - $bond:b3 @bond:../backbone $atom:a3 $atom:a4 - $bond:b4 @bond:../backbone $atom:a4 $atom:a5 - $bond:b5 @bond:../backbone $atom:a5 $atom:a6 - $bond:b6 @bond:../backbone $atom:a6 $atom:a7 - $bond:b7 @bond:../backbone $atom:a7 $atom:a8 - $bond:b8 @bond:../backbone $atom:a8 $atom:a9 - $bond:b9 @bond:../backbone $atom:a9 $atom:a10 - $bond:b10 @bond:../backbone $atom:a10 $atom:a11 - $bond:b11 @bond:../backbone $atom:a11 $atom:a12 - $bond:b12 @bond:../backbone $atom:a12 $atom:a13 - $bond:b13 @bond:../backbone $atom:a13 $atom:a14 - $bond:b14 @bond:../backbone $atom:a14 $atom:a15 - $bond:b15 @bond:../backbone $atom:a15 $atom:a16 - } - - } # B16 - - # ----- Now build larger molecules using B16 and T3 ------- - - - 4SheetBarrel { - sheet1 = new B16.rot( 45, 0,0,1).move(-4.762203156,-4.762203156, -36.0) - sheet2 = new B16.rot( 135, 0,0,1).move( 4.762203156,-4.762203156, -36.0) - sheet3 = new B16.rot( 225, 0,0,1).move( 4.762203156, 4.762203156, -36.0) - sheet4 = new B16.rot( 315, 0,0,1).move(-4.762203156, 4.762203156, -36.0) - - turn1 = new T3.rot(180,1,0,0).rot( 0, 0,0,1).move( 0, -7.8, 39.6) - turn2 = new T3.rot( 0,1,0,0).rot(-90,0,0,1).move(4.2, 0.0,-41.4) - turn3 = new T3.rot(180,1,0,0).rot(-180,0,0,1).move( 0, 7.8, 39.6) - - write('Data Bonds') { - $bond:turn1a @bond:../backbone $atom:turn1/a1 $atom:sheet1/a16 - $bond:turn1b @bond:../backbone $atom:turn1/a3 $atom:sheet2/a16 - $bond:turn2a @bond:../backbone $atom:turn2/a1 $atom:sheet3/a1 - $bond:turn2b @bond:../backbone $atom:turn2/a3 $atom:sheet2/a1 - $bond:turn3a @bond:../backbone $atom:turn3/a1 $atom:sheet3/a16 - $bond:turn3b @bond:../backbone $atom:turn3/a3 $atom:sheet4/a16 - } - create_var { $mol } # molecule ID number shared by all atoms in this protein - } - - - # Below I define several alternate conformations of the"4HelixBundleInsideOut" - # molecule I defined earlier in "1beadProtSci2010.lt". Same molecule however. - - 4HelixBundle { - helix1 = new A16.rot( -45, 0,0,1).move(-5.70,-5.70,-32.4) - helix2 = new A16.rot( 45, 0,0,1).move( 5.70,-5.70,-28.8) - helix3 = new A16.rot( 135, 0,0,1).move( 5.70, 5.70,-25.2) - helix4 = new A16.rot( 225, 0,0,1).move(-5.70, 5.70,-21.6) - - write('Data Bonds') { - $bond:turn1a @bond:../backbone $atom:turn1/a1 $atom:helix1/a16 - $bond:turn1b @bond:../backbone $atom:turn1/a3 $atom:helix2/a16 - $bond:turn2a @bond:../backbone $atom:turn2/a1 $atom:helix3/a1 - $bond:turn2b @bond:../backbone $atom:turn2/a3 $atom:helix2/a1 - $bond:turn3a @bond:../backbone $atom:turn3/a1 $atom:helix3/a16 - $bond:turn3b @bond:../backbone $atom:turn3/a3 $atom:helix4/a16 - } - - turn1 = new T3.rot(150,1,0,0).rot(-23,0,1,0).rot( 8,0,0,1).move(-3.6,-4.8,28.2) - turn2 = new T3.rot(-5,1,0,0).rot( 21,0,1,0).rot(-100,0,0,1).move(4.2,-0.66,-30.9) - turn3 = new T3.rot(150,1,0,0).rot(-23,0,1,0).rot(188,0,0,1).move(3.6,4.8,35.4) - - create_var { $mol } # molecule ID number shared by all atoms in this protein - - } # 4HelixBundle - - - - - # --- alternate conformations (same molecule) ---- - - # In the following version, the helices are oriented in a similar way, - # but they are separated a little further away from eachother. - - 4HelixBundleLoose { - - helix1 = new A16.rot( -45, 0,0,1).move(-6.7347723,-6.7347723, -27.0) - helix2 = new A16.rot( 45, 0,0,1).move( 6.7347723,-6.7347723, -27.0) - helix3 = new A16.rot( 135, 0,0,1).move( 6.7347723, 6.7347723, -27.0) - helix4 = new A16.rot( 225, 0,0,1).move(-6.7347723, 6.7347723, -27.0) - - turn1 = new T3.rot(180,1,0,0).rot(-17,0,0,1).move(-1.2,-4.2,32.4) - turn2 = new T3.rot( 0,1,0,0).rot(-100,0,0,1).move(4.2,-0.9,-28.8) - turn3 = new T3.rot(180,1,0,0).rot(163,0,0,1).move(1.2,4.2,32.4) - - write('Data Bonds') { - $bond:turn1a @bond:../backbone $atom:turn1/a1 $atom:helix1/a16 - $bond:turn1b @bond:../backbone $atom:turn1/a3 $atom:helix2/a16 - $bond:turn2a @bond:../backbone $atom:turn2/a1 $atom:helix3/a1 - $bond:turn2b @bond:../backbone $atom:turn2/a3 $atom:helix2/a1 - $bond:turn3a @bond:../backbone $atom:turn3/a1 $atom:helix3/a16 - $bond:turn3b @bond:../backbone $atom:turn3/a3 $atom:helix4/a16 - } - create_var { $mol } # molecule ID number shared by all atoms in this protein - } - - - # In following version, the helices are oriented in a similar way, - # but they are separated a little further away from eachother. - - 4HelixInsideOutLoose { - helix1 = new A16.rot(-225, 0,0,1).move(-6.7347723,-6.7347723, -27.0) - helix2 = new A16.rot(-135, 0,0,1).move( 6.7347723,-6.7347723, -27.0) - helix3 = new A16.rot( -45, 0,0,1).move( 6.7347723, 6.7347723, -27.0) - helix4 = new A16.rot( 45, 0,0,1).move(-6.7347723, 6.7347723, -27.0) - - turn1 = new T3.rot(180,1,0,0).rot( 10,0,0,1).move( 0.78,-4.2,28.8) - turn2 = new T3.rot( 70,1,0,0).rot(-70,0,0,1).move( 10.8,2.4,-28.2) - turn3 = new T3.rot(180,1,0,0).rot(190,0,0,1).move(-0.78,4.2,28.8) - - write('Data Bonds') { - $bond:turn1a @bond:../backbone $atom:turn1/a1 $atom:helix1/a16 - $bond:turn1b @bond:../backbone $atom:turn1/a3 $atom:helix2/a16 - $bond:turn2a @bond:../backbone $atom:turn2/a1 $atom:helix3/a1 - $bond:turn2b @bond:../backbone $atom:turn2/a3 $atom:helix2/a1 - $bond:turn3a @bond:../backbone $atom:turn3/a1 $atom:helix3/a16 - $bond:turn3b @bond:../backbone $atom:turn3/a3 $atom:helix4/a16 - } - create_var { $mol } # molecule ID number shared by all atoms in this protein - - } # 4HelixInsideOutLoose - - - - - # In the following version, the 4 helices are arranged next to each other, - # side-by-side, in a planar conformation (instead of a compact bundle). - - 4HelixPlanar { - helix1 = new A16.rot(-00, 0,0,1).move(0, 0, -27.0) - helix2 = new A16.rot( 00, 0,0,1).move(14.4, 0, -27.0) - helix3 = new A16.rot(-00, 0,0,1).move(28.8, 0, -27.0) - helix4 = new A16.rot( 00, 0,0,1).move(43.2, 0, -27.0) - - turn1 = new T3.rot(180,1,0,0).rot( 0,0,0,1).move( 4.8, 0, 31.8) - turn2 = new T3.rot( 0,1,0,0).rot(180,0,0,1).move(19.2, 0,-31.8) - turn3 = new T3.rot(180,1,0,0).rot( 0,0,0,1).move(34.6, 0, 31.8) - - write('Data Bonds') { - $bond:turn1a @bond:../backbone $atom:turn1/a1 $atom:helix1/a16 - $bond:turn1b @bond:../backbone $atom:turn1/a3 $atom:helix2/a16 - $bond:turn2a @bond:../backbone $atom:turn2/a1 $atom:helix3/a1 - $bond:turn2b @bond:../backbone $atom:turn2/a3 $atom:helix2/a1 - $bond:turn3a @bond:../backbone $atom:turn3/a1 $atom:helix3/a16 - $bond:turn3b @bond:../backbone $atom:turn3/a3 $atom:helix4/a16 - } - create_var { $mol } # molecule ID number shared by all atoms in this protein - - } # 4HelixPlanar - - - # -------- Minor coordinates adjustment: ----------- - # Those coordinates in the commands above are a little too large. - # To make it easier to type them in, I was using sigma=6.0 Angstroms. - # Instead, here I'll try using sigma=4.8 Angstroms. 4.8/6.0 = 0.8) - - 4SheetBarrel.scale(0.8) - 4HelixBundle.scale(0.8) - 4HelixBundleLoose.scale(0.8) - 4HelixInsideOutLoose.scale(0.8) - 4HelixPlanar.scale(0.8) - - # Note: "scale()" only effects the initial coordinates of - # the molecule, not the force field parameters. - # (If you plan to minimize the molecule, you don't need to - # be so careful about the initial coordinates. In that case, - # you don't have worry about "scale()". Feel free to remove.) - - -} # 1beadProtSci2010 (namespace) - diff --git a/tools/moltemplate/examples/coarse_grained_examples/membrane+protein/moltemplate_files/CGLipidBr2005.lt b/tools/moltemplate/examples/coarse_grained_examples/membrane+protein/moltemplate_files/CGLipidBr2005.lt deleted file mode 100644 index 24be50aced..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/membrane+protein/moltemplate_files/CGLipidBr2005.lt +++ /dev/null @@ -1,196 +0,0 @@ -# Note: -# -# This example may require additional features to be added to LAMMPS. If -# LAMMPS complains about an "Invalid pair_style", then download copy the -# "additional_lammps_code" from moltemplate.org, unpack it into your LAMMPS -# "src" directory and recompile LAMMPS. -# -# -------- Description -------- -# -# This example contains an implementation of the DPPC lipid bilayer described in -# G. Brannigan, P.F. Philips, and F.L.H. Brown, -# Physical Review E, Vol 72, 011915 (2005) -# and: -# M.C. Watson, E.S. Penev, P.M. Welch, and F.L.H. Brown -# J. Chem. Phys. 135, 244701 (2011) -# -# As in Watson(JCP 2011), rigid bond-length constraints have been replaced -# by harmonic bonds. -# -# A truncated version of this lipid (named "DLPC") has also been added. -# Unlike the original "DPPC" molecule model, "DLPC" has not been carefully -# parameterized to reproduce the correct behavior in a lipid bilayer mixture. -# -# Units: -# -# The "epsilon" parameter in their model is approximately 2.75 kJ/mole -# ( = 0.657265774378585 kCal/mole, using 1kCal=4.184kJ) -# The "sigma" parameter corresponds to 7.5 angstroms. - - -CGLipidBr2005 { - - - write_once("In Init") { - # -- Default styles for "CGLipidBr2005" -- - units real - atom_style full - # (Hybrid force field styles were used for portability.) - bond_style hybrid harmonic - - #angle_style hybrid cosine/delta # <- used in the original article - angle_style hybrid harmonic # <- prevents unphysical acute angle turns - # Explanation: - # angle_style cosine/delta: U(theta) = k*(1-cos(theta-theta0)) - # angle_style harmonic: U(theta) = k*(theta-theta0)^2 - - dihedral_style none - improper_style none - - pair_style hybrid table linear 1130 & - lj/charmm/coul/charmm/inter es4k4l 14.5 15 - - pair_modify mix arithmetic - special_bonds lj 0.0 0.0 1.0 # turn off pairs if "less than 3 bonds" - } - - - DPPC { - write("Data Atoms") { - $atom:h $mol:. @atom:head 0.0 0.00 0.00 33.75 # DPPC head atom - $atom:i $mol:. @atom:../int 0.0 -1.00 0.00 26.25 - $atom:t1 $mol:. @atom:../tail 0.0 1.00 0.00 18.75 - $atom:t2 $mol:. @atom:../tail 0.0 -1.00 0.00 11.25 - $atom:t3 $mol:. @atom:../tail 0.0 1.00 0.00 3.75 - } - write("Data Bonds") { - $bond:b1 @bond:../backbone $atom:h $atom:i - $bond:b2 @bond:../backbone $atom:i $atom:t1 - $bond:b3 @bond:../backbone $atom:t1 $atom:t2 - $bond:b4 @bond:../backbone $atom:t2 $atom:t3 - } - write("Data Angles") { - $angle:a1 @angle:../backbone $atom:h $atom:i $atom:t1 - $angle:a2 @angle:../backbone $atom:i $atom:t1 $atom:t2 - $angle:a3 @angle:../backbone $atom:t1 $atom:t2 $atom:t3 - } - - # Define properties of the local (lipid-specific) atom:head type atom: - write_once("Data Masses") { - @atom:head 200.0 - } - write_once("In Settings") { - pair_coeff @atom:head @atom:head lj/charmm/coul/charmm/inter 0.1643 7.5 0.4 0 - pair_coeff @atom:../int @atom:head lj/charmm/coul/charmm/inter 0.1643 7.5 0.4 0 - pair_coeff @atom:../tail @atom:head lj/charmm/coul/charmm/inter 0.1643 7.5 0.4 0 - } - - } #DPPC - - - DLPC { - write("Data Atoms") { - $atom:h $mol:. @atom:head 0.0 0.00 0.00 30.00 # DLPC head atom - $atom:i $mol:. @atom:../int 0.0 -1.00 0.00 22.50 - $atom:t1 $mol:. @atom:../tail 0.0 1.00 0.00 15.00 - $atom:t2 $mol:. @atom:../tail 0.0 -1.00 0.00 7.50 - } - write("Data Bonds") { - $bond:b1 @bond:../backbone $atom:h $atom:i - $bond:b2 @bond:../backbone $atom:i $atom:t1 - $bond:b3 @bond:../backbone $atom:t1 $atom:t2 - } - write("Data Angles") { - $angle:a1 @angle:../backbone $atom:h $atom:i $atom:t1 - $angle:a2 @angle:../backbone $atom:i $atom:t1 $atom:t2 - } - # Define properties of the local (lipid-specific) atom:head type atom: - write_once("Data Masses") { - @atom:head 200.0 - } - write_once("In Settings") { - pair_coeff @atom:head @atom:head lj/charmm/coul/charmm/inter 0.1643 7.5 0.4 0 - pair_coeff @atom:../int @atom:head lj/charmm/coul/charmm/inter 0.1643 7.5 0.4 0 - pair_coeff @atom:../tail @atom:head lj/charmm/coul/charmm/inter 0.1643 7.5 0.4 0 - } - } #DLPC - - - # Particles and properties shared by all lipid types: - - write_once("Data Masses") { - @atom:int 200.0 - @atom:tail 200.0 - } - - write_once("In Settings") { - # -- Default settings/parameters for "CGLipidBr2005" -- - # (Hybrid bond & angle styles were used for portability.) - - # As in Watson(JCP 2011), rigid bond-length constraints - # have been replaced by harmonic bonds. - # The k_theta parameter should lie in between 5*epsilon and 10*epsilon. - bond_coeff @bond:backbone harmonic 116.847 7.5 #<--2*5000*eps/sig^2 - } - - write_once("In Settings") { - # cosine/delta: U(theta) = k*(1-cos(theta-theta0)) - #angle_coeff @angle:backbone cosine/delta 4.60086042 180 #<-- 7*eps - # harmonic: U(theta) = k*(theta-theta0)^2 not (k/2)*(theta-theta0)^2 - angle_coeff @angle:backbone harmonic 9.85898661 180 #<-->30*eps - } - # I use a stiffer bond-angle than the original Brannigan & Brown 2005 paper - # to attempt to compensate for the fact that here we are using a lipid - # mixture of DPPC and DLPC. (The mixture of lipids introduces a great deal - # of disorder into the bilayer which would not be present in a DPPC bilayer. - # This causes pores to form. Increasing the angle stiffness prevents this.) - - write_once("In Settings") { - - # The interaction of "atom:int" with other "atom:int" atoms is given by - # epsilon*(0.4*(sigma/r)^12 - 3.0*(sigma/r)^2), shifted and cutoff at - # r=3*sigma. This was implemented using pair_style table. - # Unfortunately, mixing lj/charmm and "table" pair styles in the same - # simulation is very inneficient. - - pair_coeff @atom:int @atom:int table table_int.dat INT - - # The interaction of tail beads with eachother is given by the formula below - # and with other atoms ...using Lorenz-Berthelot and "repulsive wins" rules: - # epsilon*(0.4*(sigma/r)^12 - 1.0*(sigma/r)^6), - pair_coeff @atom:tail @atom:tail lj/charmm/coul/charmm/inter 0.1643 7.5 0.4 -1 - pair_coeff @atom:int @atom:tail lj/charmm/coul/charmm/inter 0.1643 7.5 0.4 -1 - - # The interaction between head beads from different types of lipids - # is (currently) repulsive: - pair_coeff @atom:DPPC/head @atom:DLPC/head lj/charmm/coul/charmm/inter 0.1643 7.5 0.4 0 - - } # write_once("In Settings") - - - # Note: I divided epsilon by 4 to get "0.1643" because we are using the - # "es4k4l" coeffstyle, corresponding to U(r)=eps(4*K*(s/r)^12 + 4*L*(s/r)^6) - # (The "es4k4l" coeffstyle is the default.) Using this convention makes it - # easier to mix this coarse-grained lipid model with other molecular models. - - - -} # CGLipidBr2005 - - - - - - - - -# Note: This example has not been optimized for speed. -# -# Unfortunately, using both lj/charmm and "table" pair styles in the same -# simulation seems to be very inneficient. (The simulation is twice as slow -# as using only the "lj/charmm" pair styles for every pairwise interaction, -# ...and about 25% slower than using "table" for every pairwise interaction. -# However the lennard-jones pair styles support mixing, so we use them to -# make it easier to run these molecules with other molecules which don't use -# pair_table. I felt that portability was worth the extra 25% slow down.) - diff --git a/tools/moltemplate/examples/coarse_grained_examples/membrane+protein/moltemplate_files/calc_table/calc_CGLipidTableINTvsINT.py b/tools/moltemplate/examples/coarse_grained_examples/membrane+protein/moltemplate_files/calc_table/calc_CGLipidTableINTvsINT.py deleted file mode 100755 index 0d09e4d02e..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/membrane+protein/moltemplate_files/calc_table/calc_CGLipidTableINTvsINT.py +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env python - -# Calculate a table of pairwise energies and forces between "INT" atoms -# in the lipid membrane model described in -# Brannigan et al, Phys Rev E, 72, 011915 (2005) -# The energy of this interaction U(r) = eps*(0.4*(sigma/r)^12 - 3.0*(sigma/r)^2) -# However it is truncated at rc2 = 22.5 (shifted upwards to maintain continuity) - -def U(r, eps, sigma): - return eps* (0.4*pow((sigma/r),12) - 3.0*sigma*sigma/(r*r)) -def F(r, eps, sigma): - return eps*(12*0.4*pow((sigma/r),13)/sigma - 2*3.0*sigma*sigma/(r*r*r)) - -epsilon = 2.75/4.184 # kCal/mole -sigma = 7.5 -Rmin = 0.02 -Rmax = 22.6 -rcut = 22.5 -N = 1130 - -for i in range(0,N): - r = Rmin + i*(Rmax-Rmin)/(N-1) - U_r = U(r, epsilon, sigma) - U(rcut, epsilon, sigma) - F_r = F(r, epsilon, sigma) - if r > rcut: - U_r = 0.0 - F_r = 0.0 - print(str(i+1)+' '+str(r)+' '+str(U_r)+' '+str(F_r)) - diff --git a/tools/moltemplate/examples/coarse_grained_examples/membrane+protein/moltemplate_files/calc_table/version_charmm_cutoff/calc_table.py b/tools/moltemplate/examples/coarse_grained_examples/membrane+protein/moltemplate_files/calc_table/version_charmm_cutoff/calc_table.py deleted file mode 100755 index 32147e444a..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/membrane+protein/moltemplate_files/calc_table/version_charmm_cutoff/calc_table.py +++ /dev/null @@ -1,70 +0,0 @@ -#!/usr/bin/env python - -# Calculate a table of pairwise energies and forces between "INT" atoms -# in the lipid membrane model described in -# Brannigan et al, Phys Rev E, 72, 011915 (2005) -# The energy of this interaction U(r) = eps*(0.4*(sigma/r)^12 - 3.0*(sigma/r)^2) -# I realized later this is not what we want because although energy is conserved -# all enrgies are shifted with respect to energies used in the Brannigan paper -# (by 0.27 kCal/mole) and the later Watson JCP 2011 paper (by 0.224 kCal/mole). -# (So don't use this.) - -# Calculate and print a - -def S(r, rc1, rc2, derivative=False): - """ - Calculate the switching function S(r) which decays continuously - between 1 and 0 in the range from rc1 to rc2 (rc2>rc1): - S(r) = (rc2^2 - r^2)^2 * (rc2^2 + 2*r^2 - 3*rc1^2) / (rc2^2-rc1^2)^3 - I'm using the same smoothing/switching cutoff function used by the CHARMM - force-fields. (I'm even using the same code to implement it, taken - from lammps charmm/coul/charmm pair style, rewritten in python.) - - """ - assert(rc2>rc1) - rsq = r*r - rc1sq = rc1*rc1 - rc2sq = rc2*rc2 - denom_lj_inv = (1.0 / ((rc2sq-rc1sq)* - (rc2sq-rc1sq)* - (rc2sq-rc1sq))) - if rsq > rc2sq: - return 0.0 - elif rsq < rc1sq: - if derivative: - return 0.0 - else: - return 1.0 - else: - rc2sq_minus_rsq = (rc2sq - rsq) - rc2sq_minus_rsq_sq = rc2sq_minus_rsq * rc2sq_minus_rsq - if derivative: - return (12.0 * rsq * rc2sq_minus_rsq * (rsq-rc1sq) * denom_lj_inv) - else: - return (rc2sq_minus_rsq_sq * - (rc2sq + 2.0*rsq - 3.0*rc1sq) * denom_lj_inv) - - -def U(r, eps, sigma): - return eps* (0.4*pow((sigma/r),12) - 3.0*sigma*sigma/(r*r)) - -def F(r, eps, sigma): - return eps*(12*0.4*pow((sigma/r),13)/sigma - 2*3.0*sigma*sigma/(r*r*r)) - -epsilon = 2.75/4.184 # kCal/mole -sigma = 7.5 -Rmin = 0.02 -Rmax = 22.6 -Rc1 = 22.0 -Rc2 = 22.5 -N = 1130 - -for i in range(0,N): - r = Rmin + i*(Rmax-Rmin)/(N-1) - U_r = U(r, epsilon, sigma) - F_r = F(r, epsilon, sigma) - # Multiply U(r) & F(r) by the smoothing/switch function - U_r = U_r * S(r, Rc1, Rc2) - F_r = U_r * S(r, Rc1, Rc2, True) + F_r * S(r, Rc1, Rc2, False) - print(str(i+1)+' '+str(r)+' '+str(U_r)+' '+str(F_r)) - diff --git a/tools/moltemplate/examples/coarse_grained_examples/membrane+protein/moltemplate_files/system.lt b/tools/moltemplate/examples/coarse_grained_examples/membrane+protein/moltemplate_files/system.lt deleted file mode 100644 index 3e521b0f90..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/membrane+protein/moltemplate_files/system.lt +++ /dev/null @@ -1,178 +0,0 @@ -# Description: - -# This example shows how to put a protein (inclusion) in a -# lipid bilayer mixture composed of two different lipids (DPPC and DLPC). -# The DPPC lipid model is described here: -# G. Brannigan, P.F. Philips, and F.L.H. Brown, -# Physical Review E, Vol 72, 011915 (2005) -# The protein model is described here: -# G. Bellesia, AI Jewett, and J-E Shea, -# Protein Science, Vol19 141-154 (2010) -# The new DLPC model is a truncated version of DPPC, -# (Its behaviour has not been rigorously tested.) -# Note that 50%/50% mixtures of DPPC & DLPC are commonly used to -# build liposomes http://www.ncbi.nlm.nih.gov/pubmed/10620293 - -# Note: -# This example may require additional features to be added to LAMMPS. -# If LAMMPS complains about an "Invalid pair_style", then copy the code -# in the "additional_lammps_code" directory into your LAMMPS "src" directory -# and recompile LAMMPS. - - - -import "CGLipidBr2005.lt" - -using namespace CGLipidBr2005 - -# The "= new random" syntax chooses one of several molecules at random - -lipids = new random([DPPC, DLPC], [0.5,0.5], 1234) #"1234"=random_seed - [13].move(7.5, 0, 0) - [15].move(3.75, 6.49519, 0) # <-- hexagonal lattice - [2].rot(180, 1, 0, 0) # <-- 2 monolayers - -# Move all the lipds up to the center of the box - -lipids[*][*][*].move(0,0,75.0) - - - - -# Although this patch of lipids is not square or rectangular, (it looks -# like a parallelogram), this is no longer the case after rectangular -# periodic boundary conditions are applied. (Check by visualising in VMD.) - - -write_once("Data Boundary") { - 0 97.5 xlo xhi - 0 97.42785792 ylo yhi - 0 150.0 zlo zhi -} - - -# A note on geometry: -# We want to create a bilayer arranged in a hexagonal lattice consisting of -# 15 rows (each row is aligned with the x-axis) -# 13 columns (aligned at a 60 degree angle from the x axis) -# The lattice spacing is 7.5 Angstroms. -# When wrapped onto a rectangular box, the dimensions of the system are: -# 13 * 7.5 Angstroms in the X direction -# 15 * 7.5*sqrt(3)/2 Angstroms in the Y direction - - - - - - - -# ------------------- protein inclusion --------------------- - -import "1beadProtSci2010.lt" - -using namespace 1beadProtSci2010 - -protein = new 4HelixInsideOut - -protein.move(45.0, 25.98076211, 75.0) - - -# Delete a hole in the membrane to create space for the protein. -# (In the future moltemplate will be able to avoid occlusion automatically.) - - -delete lipids[4][2][*] -delete lipids[6][2][*] -delete lipids[3-6][3][*] -delete lipids[3-5][4][*] -delete lipids[2-5][5][*] -delete lipids[2][6][*] -delete lipids[4][6][*] - - -# -------- interactions between protein and lipids ---------- - -# Note: All atom types must include the full path (the name of -# the namespace which defined them as well as the atom type name). -# (This is because we are no longer inside that namespace.) - - -write_once("In Settings") { - - # Interactions between the protein and lipid atoms are usually - # determined by mixing rules. However this is not possible some - # for atoms (such as the "int" atoms in the lipid model which - # interact using -1/r^2 attraction). Lorentz-Berthelot mixing - # rules do not make sense for these atoms so we must explicitly - # define their interaction with all other atoms. - - # i j pairstylename eps sig K L - - pair_coeff @atom:CGLipidBr2005/int @atom:1beadProtSci2010/sH lj/charmm/coul/charmm/inter 1.8065518 7.5 1 -1 - pair_coeff @atom:CGLipidBr2005/int @atom:1beadProtSci2010/sL lj/charmm/coul/charmm/inter 1.8065518 7.5 1 0 - pair_coeff @atom:CGLipidBr2005/int @atom:1beadProtSci2010/tN lj/charmm/coul/charmm/inter 1.8065518 7.5 1 0 - - # We want the interactions between hydrophobic residues and atoms in - # the interior of the lipid to be energetically similar to the attractive - # interactions between hydrophobic residues. (See 1beadProtSci2010.) - - pair_coeff @atom:CGLipidBr2005/tail @atom:1beadProtSci2010/sH lj/charmm/coul/charmm/inter 1.8065518 7.5 1 -1 - - # All other interactions between proteins and lipids are steric. - pair_coeff @atom:CGLipidBr2005/tail @atom:1beadProtSci2010/sL lj/charmm/coul/charmm/inter 1.8065518 7.5 1 0 - pair_coeff @atom:CGLipidBr2005/tail @atom:1beadProtSci2010/tN lj/charmm/coul/charmm/inter 1.8065518 7.5 1 0 - pair_coeff @atom:CGLipidBr2005/DPPC/head @atom:1beadProtSci2010/sH lj/charmm/coul/charmm/inter 1.8065518 7.5 1 0 - pair_coeff @atom:CGLipidBr2005/DPPC/head @atom:1beadProtSci2010/sL lj/charmm/coul/charmm/inter 1.8065518 7.5 1 0 - pair_coeff @atom:CGLipidBr2005/DLPC/head @atom:1beadProtSci2010/sH lj/charmm/coul/charmm/inter 1.8065518 7.5 1 0 - pair_coeff @atom:CGLipidBr2005/DLPC/head @atom:1beadProtSci2010/sL lj/charmm/coul/charmm/inter 1.8065518 7.5 1 0 - - - # We also add an artificial attractive interaction between the - # turn residues of the protein and the lipid head groups in - # order to keep the protein upright. This might not be necessary - - pair_coeff @atom:CGLipidBr2005/DPPC/head @atom:1beadProtSci2010/tN lj/charmm/coul/charmm/inter 1.8065518 6.0 1 -1 - pair_coeff @atom:CGLipidBr2005/DLPC/head @atom:1beadProtSci2010/tN lj/charmm/coul/charmm/inter 1.8065518 6.0 1 -1 - - # Add a weak attractive interaction between hydrophilic "sL" beads - # (Whose strength mimics the strength of interaction between tail beads - # in the lipid. This was absent from the original protein model. - # However without some kind of weak attraction between residues, - # the negative pressure in the interior of the bilayer membrane - # allways pulls the protein apart. Recall that in the membrane, - # the hydrophobic beads in the protein will face outwards towards the lipid - # tails leaving the hydrophilic amino acids of the protein in the interior. - # In reality, these polar groups form hydrogen bonds with each other.) - - pair_coeff @atom:1beadProtSci2010/sL @atom:1beadProtSci2010/sL lj/charmm/coul/charmm/inter 0.3286 6.0 0.4 -1 - - # However these hydrophilic amino acids are not attrected to - # the bilayer interior. - - pair_coeff @atom:CGLipidBr2005/int @atom:1beadProtSci2010/sL lj/charmm/coul/charmm/inter 0.1643 7.5 0.4 0 - pair_coeff @atom:CGLipidBr2005/tail @atom:1beadProtSci2010/sL lj/charmm/coul/charmm/inter 0.1643 7.5 0.4 0 - -} - - - - -# Finally, we must combine the two force-field styles which were used for -# the coarse-grained lipid and protein. To do that, we write one last time -# to the "In Init" section. When reading the "Init" section LAMMPS will -# read these commands last and this will override any earlier settings. - -write_once("In Init") { - # -- These styles override earlier settings -- - units real - atom_style full - # (Hybrid force field styles were used for portability.) - bond_style hybrid harmonic - angle_style hybrid cosine/delta harmonic - dihedral_style hybrid fourier - improper_style none - pair_style hybrid table linear 1001 lj/charmm/coul/charmm/inter es4k4l 14.5 15 - pair_modify mix arithmetic - special_bonds lj 0.0 0.0 1.0 # turn off pairs if "less than 3 bonds" -} - diff --git a/tools/moltemplate/examples/coarse_grained_examples/membrane+protein/moltemplate_files/table_int.dat b/tools/moltemplate/examples/coarse_grained_examples/membrane+protein/moltemplate_files/table_int.dat deleted file mode 100644 index b0d651d67f..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/membrane+protein/moltemplate_files/table_int.dat +++ /dev/null @@ -1,1139 +0,0 @@ -# Table for the INT-INT interaction from -# Brannigan et al, Phys Rev E, 72, 011915 (2005) -# This table contains -# i r_i U(r_i) -dU/dr|r_i -# where U(r) = eps*(0.4*(sigma/r)^12 - 3.0*(sigma/r)^2) - -INT -N 1130 - -1 0.02 2.0331818401e+30 1.21990910406e+33 -2 0.04 4.9638228518e+26 1.48914685554e+29 -3 0.06 3.82579033251e+24 7.65158066501e+26 -4 0.08 1.21187081343e+23 1.81780622014e+25 -5 0.1 8.32791281704e+21 9.99349538045e+23 -6 0.12 9.34030842897e+20 9.34030842897e+22 -7 0.14 1.46892540453e+20 1.25907891817e+22 -8 0.16 2.95866897809e+19 2.21900173357e+21 -9 0.18 7.19889946863e+18 4.79926631242e+20 -10 0.2 2.0331818401e+18 1.21990910406e+20 -11 0.22 6.47834392264e+17 3.53364213962e+19 -12 0.24 2.28034873754e+17 1.14017436877e+19 -13 0.26 8.72681951932e+16 4.02776285507e+18 -14 0.28 3.58624366341e+16 1.53696157003e+18 -15 0.3 1.56704372019e+16 6.26817488078e+17 -16 0.32 7.2233129348e+15 2.70874235055e+17 -17 0.34 3.48970861422e+15 1.23166186384e+17 -18 0.36 1.75754381558e+15 5.85847938527e+16 -19 0.38 9.18613895646e+14 2.90088598625e+16 -20 0.4 4.96382285179e+14 1.48914685554e+16 -21 0.42 2.76404230108e+14 7.89726371739e+15 -22 0.44 1.58162693423e+14 4.31352800247e+15 -23 0.46 9.27773983256e+13 2.42027995633e+15 -24 0.48 5.56725765996e+13 1.391814415e+15 -25 0.5 3.41111308981e+13 8.18667141564e+14 -26 0.52 2.13057117167e+13 4.91670270393e+14 -27 0.54 1.35459994024e+13 3.0102220895e+14 -28 0.56 8.75547769351e+12 1.87617379153e+14 -29 0.58 5.74645813711e+12 1.18892237325e+14 -30 0.6 3.8257903322e+12 7.65158066491e+13 -31 0.62 2.58128463312e+12 4.99603477424e+13 -32 0.64 1.7635041342e+12 3.30657025205e+13 -33 0.66 1.21901470178e+12 2.21639036726e+13 -34 0.68 8.51979641904e+11 1.50349348607e+13 -35 0.7 6.0167184547e+11 1.0314374497e+13 -36 0.72 4.29087845387e+11 7.15146409276e+12 -37 0.74 3.08855637556e+11 5.00846980094e+12 -38 0.76 2.24270970425e+11 3.54112058818e+12 -39 0.78 1.64210505205e+11 2.52631546702e+12 -40 0.8 1.2118708117e+11 1.81780621971e+12 -41 0.82 90109367359.1 1.31867367068e+12 -42 0.84 67481501334.4 9.64021449503e+11 -43 0.86 50880896383.4 7.09965997788e+11 -44 0.88 38613938681.2 5.26553710913e+11 -45 0.9 29486692086.8 3.93155896009e+11 -46 0.92 22650731882.4 2.95444330322e+11 -47 0.94 17498544395.3 2.23385674464e+11 -48 0.96 13591937526.4 1.69899220331e+11 -49 0.98 10612635712.6 1.29950642555e+11 -50 1.0 8327912706.34 99934953582.6 -51 1.02 6566502316.69 77252969474.2 -52 1.04 5201589672.36 60018343356.8 -53 1.06 4138717434.11 46853405843.3 -54 1.08 3307128665.58 36745874940.0 -55 1.1 2653529579.27 28947596241.1 -56 1.12 2137567708.15 22902511945.9 -57 1.14 1728534024.3 18195095739.0 -58 1.16 1402943799.0 14513212422.1 -59 1.18 1142752163.37 11621209113.9 -60 1.2 934030766.093 9340308300.6 -61 1.22 765981286.774 7534242773.65 -62 1.24 630196371.787 6098675145.29 -63 1.26 520103253.414 4953364870.6 -64 1.28 430542934.103 4036340534.04 -65 1.3 357450462.101 3299543229.91 -66 1.32 297610947.802 2705554551.18 -67 1.34 248472587.186 2225128105.44 -68 1.36 208002782.573 1835319108.76 -69 1.38 174576985.011 1518061159.35 -70 1.4 146892484.084 1259078837.33 -71 1.42 123901294.937 1047053582.16 -72 1.44 104757721.536 872981382.419 -73 1.46 88777241.639 729676313.267 -74 1.48 75404158.02 611385405.387 -75 1.5 64186061.7033 513488820.507 -76 1.52 54753607.1486 432265633.695 -77 1.54 46804443.7318 364710253.134 -78 1.56 40090410.0598 308388060.159 -79 1.58 34407297.9713 261321529.95 -80 1.6 29586646.6744 221900119.2 -81 1.62 25489145.661 188808745.634 -82 1.64 21999316.2868 160970856.824 -83 1.66 19021212.5921 137502982.517 -84 1.68 16474936.8715 117678352.86 -85 1.7 14293808.3245 100897694.735 -86 1.72 12422056.6082 86665727.6626 -87 1.74 10812938.3788 74572197.8496 -88 1.76 9427195.57103 64276535.39 -89 1.78 8231790.46096 55495411.7777 -90 1.8 7198865.45512 47992625.088 -91 1.82 6304885.77339 41570857.9644 -92 1.84 5529931.32911 36064946.1544 -93 1.86 4857110.59557 31336368.341 -94 1.88 4272074.43377 27268725.7382 -95 1.9 3762612.01167 23764025.6584 -96 1.92 3318314.28383 20739619.609 -97 1.94 2930293.18879 18125675.4316 -98 1.96 2590946.89128 15863086.114 -99 1.98 2293763.15199 13901736.4186 -100 2.0 2033154.33079 12199063.3122 -101 2.02 1804318.68586 10718858.1296 -102 2.04 1603123.57305 9430268.02169 -103 2.06 1426006.91783 8306962.01537 -104 2.08 1269893.96121 7326433.30293 -105 2.1 1132126.79514 6469414.48445 -106 2.12 1010404.62602 5719386.63441 -107 2.14 902733.052344 5062166.44376 -108 2.16 807380.928986 4485558.44681 -109 2.18 722843.627253 3979061.59742 -110 2.2 647811.695319 3533621.30686 -111 2.22 581144.085827 3141419.57242 -112 2.24 521845.251959 2795697.07302 -113 2.26 469045.525153 2490602.13576 -114 2.28 421984.280794 2221062.32522 -115 2.3 379995.475978 1982675.10836 -116 2.32 342495.208369 1771614.62868 -117 2.34 308970.999537 1584552.10475 -118 2.36 278972.551763 1418587.76828 -119 2.38 252103.765513 1271192.59046 -120 2.4 228015.837009 1140158.32224 -121 2.42 206401.282366 1023554.60663 -122 2.44 186988.75765 919692.114521 -123 2.46 169538.563484 827090.818108 -124 2.48 153838.739168 744452.651831 -125 2.5 139701.665073 670637.92543 -126 2.52 126961.103835 604644.949624 -127 2.54 115469.620781 545592.416037 -128 2.56 105096.332511 492704.141327 -129 2.58 95724.9397832 445295.843157 -130 2.6 87252.0069441 402763.664479 -131 2.62 79585.4554502 364574.203947 -132 2.64 72643.2434671 330255.845328 -133 2.66 66352.2073932 299391.208536 -134 2.68 60647.0444312 271610.570248 -135 2.7 55469.4181565 246586.123584 -136 2.72 50767.1714483 224026.964698 -137 2.74 46493.633237 203674.709811 -138 2.76 42607.0073083 185299.659567 -139 2.78 39069.8329526 168697.439095 -140 2.8 35848.5085794 153686.051901 -141 2.82 32912.8705664 140103.294183 -142 2.84 30235.8206098 127804.483324 -143 2.86 27792.9956998 116660.460548 -144 2.88 25562.4755962 106555.833042 -145 2.9 23524.5233195 97387.4254387 -146 2.92 21661.3547409 89062.9145204 -147 2.94 19956.9338374 81499.6244039 -148 2.96 18396.7906059 74623.4624292 -149 2.98 16967.8589974 68367.9785194 -150 3.0 15658.3325568 62673.5329856 -151 3.02 14457.5357325 57486.5596649 -152 3.04 13355.809067 52758.912937 -153 3.06 12344.4066925 48447.2886046 -154 3.08 11415.4047444 44512.7098736 -155 3.1 10561.6194689 40920.0707567 -156 3.12 9776.5339459 37637.7301715 -157 3.14 9054.23247117 34637.1508274 -158 3.16 8389.34175838 31892.5777179 -159 3.18 7776.97821258 29380.7516608 -160 3.2 7212.7006167 27080.6538766 -161 3.22 6692.4676457 24973.2780793 -162 3.24 6212.59969004 23041.4269669 -163 3.26 5769.74452856 21269.5303734 -164 3.28 5360.84644195 19643.4826615 -165 3.3 4983.1184041 18150.4972204 -166 3.32 4634.01702836 16778.97618 -167 3.34 4311.21998136 15518.393672 -168 3.36 4012.60560869 14359.191159 -169 3.38 3736.23454428 13292.6835236 -170 3.4 3480.33310029 12310.9747549 -171 3.42 3243.27825585 11406.8822043 -172 3.44 3023.58408279 10573.8684961 -173 3.46 2819.88946345 9805.98028003 -174 3.48 2630.94697101 9097.79310596 -175 3.5 2455.61279669 8444.36177626 -176 3.52 2292.83761972 7841.17560602 -177 3.54 2141.65832756 7284.11808108 -178 3.56 2001.19050257 6769.43046025 -179 3.58 1870.62160083 6293.67891689 -180 3.6 1749.20475558 5853.72485855 -181 3.62 1636.25314534 5446.69810179 -182 3.64 1531.13487237 5069.97261409 -183 3.66 1433.26830277 4721.1445646 -184 3.68 1342.11782445 4398.01245332 -185 3.7 1257.18998347 4098.55911171 -186 3.72 1178.02996319 3820.93539003 -187 3.74 1104.21837425 3563.44536511 -188 3.76 1035.36832639 3324.53291993 -189 3.78 971.122756088 3102.76956138 -190 3.8 911.151986554 2896.84335615 -191 3.82 855.151498616 2705.54887715 -192 3.84 802.83989347 2527.77806329 -193 3.86 753.957029799 2362.51190574 -194 3.88 708.262319576 2208.81288195 -195 3.9 665.533168297 2065.81806693 -196 3.92 625.563546756 1932.73285812 -197 3.94 588.162682667 1808.82525631 -198 3.96 553.153861545 1693.42065104 -199 3.98 520.373327227 1585.89706361 -200 4.0 489.669273313 1485.68080556 -201 4.02 460.900917596 1392.24251449 -202 4.04 433.937652306 1305.09353282 -203 4.06 408.6582636 1223.78259822 -204 4.08 384.950214367 1147.89281764 -205 4.1 362.708984933 1077.03889938 -206 4.12 341.837466738 1010.86461999 -207 4.14 322.245404503 949.040505266 -208 4.16 303.848882793 891.261706073 -209 4.18 286.569853265 837.246052066 -210 4.2 270.33569919 786.732267446 -211 4.22 255.078834164 739.47833469 -212 4.24 240.736332164 695.259993326 -213 4.26 227.249586386 653.869362042 -214 4.28 214.563994495 615.113673492 -215 4.3 202.628668126 578.814112106 -216 4.32 191.396164684 544.804746089 -217 4.34 180.822239621 512.931545605 -218 4.36 170.865617553 483.051479815 -219 4.38 161.487780703 455.031686127 -220 4.4 152.652773286 428.748705595 -221 4.42 144.327020575 404.087778912 -222 4.44 136.479161479 380.942197972 -223 4.46 129.07989358 359.212708377 -224 4.48 122.101829632 338.806958688 -225 4.5 115.519364658 319.638992577 -226 4.52 109.308552789 301.628780369 -227 4.54 103.446993117 284.701786758 -228 4.56 97.9137238447 268.788571763 -229 4.58 92.6891241175 253.824422244 -230 4.6 87.7548229339 239.749011508 -231 4.62 83.0936146036 226.506084761 -232 4.64 78.6893802546 214.043168343 -233 4.66 74.5270149351 202.31130085 -234 4.68 70.5923598871 191.264784422 -235 4.7 66.8721396072 180.860954593 -236 4.72 63.353903336 171.05996726 -237 4.74 60.0259706488 161.824601429 -238 4.76 56.8773808439 153.120076496 -239 4.78 53.8978458491 144.913882966 -240 4.8 51.0777063884 137.175625538 -241 4.82 48.4078911713 129.876877635 -242 4.84 45.8798788842 122.991046476 -243 4.86 43.485662782 116.493247913 -244 4.88 41.2177176913 110.360190267 -245 4.9 39.0689692529 104.570066494 -246 4.92 37.0327652428 99.1024540566 -247 4.94 35.102848823 93.9382219092 -248 4.96 33.2733335874 89.05944408 -249 4.98 31.5386802724 84.4493193479 -250 5.0 29.8936750183 80.0920965658 -251 5.02 28.3334090704 75.9730052143 -252 5.04 26.8532598202 72.0781907976 -253 5.06 25.4488730938 68.3946547294 -254 5.08 24.116146599 64.9101983786 -255 5.1 22.8512144543 61.6133709734 -256 5.12 21.650432722 58.4934210835 -257 5.14 20.5103658787 55.5402514226 -258 5.16 19.4277741591 52.7443767307 -259 5.18 18.3996017121 50.0968845179 -260 5.2 17.4229655155 47.5893984632 -261 5.22 16.4951449988 45.2140442802 -262 5.24 15.6135723236 42.9634178757 -263 5.26 14.775823281 40.8305556374 -264 5.28 13.979608762 38.808906703 -265 5.3 13.2227667648 36.8923070701 -266 5.32 12.5032549016 35.0749554196 -267 5.34 11.8191433738 33.3513905323 -268 5.36 11.1686083831 31.7164701895 -269 5.38 10.5499259512 30.1653514539 -270 5.4 9.96146612005 28.693472236 -271 5.42 9.40168750976 27.2965340593 -272 5.44 8.86913220892 25.9704859397 -273 5.46 8.36242097742 24.7115093061 -274 5.48 7.88024874079 23.5160038893 -275 5.5 7.4213803577 22.3805745153 -276 5.52 6.98464664308 21.3020187412 -277 5.54 6.56894063048 20.2773152771 -278 5.56 6.1732140587 19.3036131423 -279 5.58 5.79647406826 18.3782215059 -280 5.6 5.43778009463 17.4986001669 -281 5.62 5.09624094585 16.6623506308 -282 5.64 4.77101205293 15.867207745 -283 5.66 4.46129288233 15.1110318537 -284 5.68 4.16632450031 14.3918014404 -285 5.7 3.88538727999 13.7076062261 -286 5.72 3.61779874199 13.0566406912 -287 5.74 3.36291152072 12.4371979973 -288 5.76 3.12011144838 11.8476642796 -289 5.78 2.8888157497 11.2865132882 -290 5.8 2.66847134042 10.7523013555 -291 5.82 2.45855322349 10.2436626676 -292 5.84 2.25856297681 9.7593048226 -293 5.86 2.06802732724 9.2980046552 -294 5.88 1.88649680546 8.85860431242 -295 5.9 1.71354447704 8.44000756375 -296 5.92 1.548764745 8.04117633127 -297 5.94 1.39177221978 7.66112742597 -298 5.96 1.24220065245 7.29892947717 -299 5.98 1.09970192753 6.9537000433 -300 6.0 0.963945111861 6.62460289254 -301 6.02 0.83461555631 6.31084544295 -302 6.04 0.711414047074 6.01167635216 -303 6.06 0.594056003831 5.72638324756 -304 6.08 0.482270721937 5.45429058822 -305 6.1 0.375800656137 5.19475765055 -306 6.12 0.274400743381 4.94717663025 -307 6.14 0.177837762511 4.71097085338 -308 6.16 0.0858897286772 4.48559308998 -309 6.18 -0.00165467948361 4.27052396409 -310 6.2 -0.0849966617872 4.06527045435 -311 6.22 -0.164327809314 3.8693644797 -312 6.24 -0.239830589745 3.68236156522 -313 6.26 -0.311678806773 3.50383958321 -314 6.28 -0.380038035049 3.33339756513 -315 6.3 -0.445066032049 3.17065458013 -316 6.32 -0.506913128135 3.0152486763 -317 6.34 -0.56572259604 2.866835881 -318 6.36 -0.621631000928 2.72508925658 -319 6.38 -0.674768532081 2.58969800863 -320 6.4 -0.725259317268 2.46036664323 -321 6.42 -0.773221720709 2.33681417085 -322 6.44 -0.818768625574 2.21877335375 -323 6.46 -0.862007701832 2.10598999469 -324 6.48 -0.90304166028 1.99822226439 -325 6.5 -0.941968493479 1.8952400656 -326 6.52 -0.978881704324 1.79682443166 -327 6.54 -1.01387052292 1.70276695755 -328 6.56 -1.04702011237 1.61286926168 -329 6.58 -1.07841176412 1.52694247655 -330 6.6 -1.10812308336 1.44480676668 -331 6.62 -1.13622816508 1.36629087245 -332 6.64 -1.1627977612 1.29123167801 -333 6.66 -1.18789943936 1.21947380239 -334 6.68 -1.21159773365 1.15086921208 -335 6.7 -1.23395428792 1.08527685416 -336 6.72 -1.25502799183 1.02256230873 -337 6.74 -1.27487511024 0.962597459596 -338 6.76 -1.2935494061 0.90526018218 -339 6.78 -1.31110225728 0.850434047748 -340 6.8 -1.32758276773 0.798008043011 -341 6.82 -1.34303787302 0.747876304295 -342 6.84 -1.35751244086 0.699937865467 -343 6.86 -1.3710493666 0.654096418865 -344 6.88 -1.38368966412 0.610260088543 -345 6.9 -1.3954725523 0.568341215144 -346 6.92 -1.40643553728 0.528256151786 -347 6.94 -1.41661449078 0.489925070364 -348 6.96 -1.42604372459 0.453271777711 -349 6.98 -1.43475606153 0.418223541087 -350 7.0 -1.44278290299 0.384710922497 -351 7.02 -1.45015429321 0.352667621378 -352 7.04 -1.45689898057 0.322030325194 -353 7.06 -1.46304447588 0.292738567537 -354 7.08 -1.46861710792 0.264734593325 -355 7.1 -1.47364207647 0.237963230734 -356 7.12 -1.47814350264 0.2123717695 -357 7.14 -1.482144477 0.187909845266 -358 7.16 -1.48566710537 0.16452932965 -359 7.18 -1.48873255248 0.142184225751 -360 7.2 -1.49136108362 0.120830568787 -361 7.22 -1.49357210429 0.100426331626 -362 7.24 -1.49538419809 0.0809313349308 -363 7.26 -1.4968151628 0.0623071617066 -364 7.28 -1.49788204479 0.044517076001 -365 7.3 -1.49860117187 0.0275259455594 -366 7.32 -1.49898818464 0.0113001682279 -367 7.34 -1.49905806636 -0.00419239808778 -368 7.36 -1.4988251715 -0.0189825020854 -369 7.38 -1.49830325295 -0.0330995625254 -370 7.4 -1.49750548803 -0.0465717286462 -371 7.42 -1.49644450327 -0.0594259376903 -372 7.44 -1.49513239812 -0.0716879696855 -373 7.46 -1.49358076759 -0.0833824996199 -374 7.48 -1.4918007238 -0.0945331471409 -375 7.5 -1.48980291663 -0.105162523901 -376 7.52 -1.48759755345 -0.115292278666 -377 7.54 -1.48519441791 -0.124943140307 -378 7.56 -1.48260288794 -0.13413495876 -379 7.58 -1.47983195293 -0.142886744076 -380 7.6 -1.47689023018 -0.151216703644 -381 7.62 -1.47378598053 -0.159142277674 -382 7.64 -1.47052712344 -0.166680173038 -383 7.66 -1.46712125128 -0.173846395532 -384 7.68 -1.46357564306 -0.180656280652 -385 7.7 -1.45989727753 -0.187124522948 -386 7.72 -1.45609284575 -0.193265204023 -387 7.74 -1.45216876302 -0.199091819249 -388 7.76 -1.4481311804 -0.204617303261 -389 7.78 -1.44398599566 -0.20985405428 -390 7.8 -1.43973886378 -0.214813957332 -391 7.82 -1.43539520696 -0.21950840641 -392 7.84 -1.43096022428 -0.223948325627 -393 7.86 -1.42643890087 -0.228144189416 -394 7.88 -1.42183601669 -0.232106041819 -395 7.9 -1.41715615498 -0.235843514899 -396 7.92 -1.41240371029 -0.239365846333 -397 7.94 -1.40758289625 -0.242681896213 -398 7.96 -1.40269775292 -0.245800163096 -399 7.98 -1.39775215386 -0.248728799339 -400 8.0 -1.39274981294 -0.251475625745 -401 8.02 -1.38769429081 -0.254048145572 -402 8.04 -1.3825890011 -0.256453557906 -403 8.06 -1.37743721643 -0.258698770453 -404 8.08 -1.37224207403 -0.260790411767 -405 8.1 -1.3670065813 -0.262734842931 -406 8.12 -1.36173362096 -0.264538168734 -407 8.14 -1.35642595614 -0.26620624836 -408 8.16 -1.35108623513 -0.267744705599 -409 8.18 -1.34571699603 -0.269158938625 -410 8.2 -1.34032067115 -0.270454129338 -411 8.22 -1.33489959126 -0.271635252315 -412 8.24 -1.32945598963 -0.272707083354 -413 8.26 -1.32399200593 -0.273674207668 -414 8.28 -1.31850968998 -0.274541027712 -415 8.3 -1.3130110053 -0.275311770682 -416 8.32 -1.30749783257 -0.275990495686 -417 8.34 -1.30197197291 -0.276581100614 -418 8.36 -1.29643515102 -0.277087328708 -419 8.38 -1.29088901827 -0.277512774857 -420 8.4 -1.28533515553 -0.277860891625 -421 8.42 -1.279775076 -0.278134995017 -422 8.44 -1.27421022789 -0.278338270004 -423 8.46 -1.26864199697 -0.27847377582 -424 8.48 -1.26307170904 -0.278544451025 -425 8.5 -1.25750063229 -0.278553118366 -426 8.52 -1.25192997959 -0.278502489422 -427 8.54 -1.24636091063 -0.27839516907 -428 8.56 -1.24079453406 -0.278233659745 -429 8.58 -1.23523190945 -0.27802036554 -430 8.6 -1.22967404925 -0.277757596126 -431 8.62 -1.22412192063 -0.277447570509 -432 8.64 -1.21857644724 -0.277092420635 -433 8.66 -1.21303851096 -0.276694194842 -434 8.68 -1.20750895348 -0.276254861174 -435 8.7 -1.20198857794 -0.275776310556 -436 8.72 -1.19647815038 -0.275260359835 -437 8.74 -1.19097840123 -0.274708754702 -438 8.76 -1.18549002669 -0.274123172492 -439 8.78 -1.18001369009 -0.273505224869 -440 8.8 -1.17455002313 -0.272856460401 -441 8.82 -1.16909962718 -0.272178367032 -442 8.84 -1.16366307443 -0.271472374453 -443 8.86 -1.15824090903 -0.270739856375 -444 8.88 -1.1528336482 -0.269982132713 -445 8.9 -1.14744178329 -0.269200471678 -446 8.92 -1.14206578078 -0.26839609179 -447 8.94 -1.13670608326 -0.267570163805 -448 8.96 -1.13136311038 -0.266723812565 -449 8.98 -1.1260372597 -0.26585811878 -450 9.0 -1.12072890764 -0.264974120729 -451 9.02 -1.11543841024 -0.2640728159 -452 9.04 -1.11016610399 -0.263155162565 -453 9.06 -1.10491230659 -0.262222081284 -454 9.08 -1.09967731769 -0.261274456364 -455 9.1 -1.09446141962 -0.260313137244 -456 9.12 -1.08926487805 -0.259338939836 -457 9.14 -1.08408794265 -0.258352647809 -458 9.16 -1.07893084774 -0.257355013824 -459 9.18 -1.07379381288 -0.256346760718 -460 9.2 -1.06867704347 -0.255328582644 -461 9.22 -1.06358073129 -0.254301146164 -462 9.24 -1.05850505508 -0.253265091305 -463 9.26 -1.053450181 -0.252221032561 -464 9.28 -1.04841626319 -0.251169559871 -465 9.3 -1.04340344425 -0.25011123955 -466 9.32 -1.03841185563 -0.249046615186 -467 9.34 -1.03344161818 -0.2479762085 -468 9.36 -1.0284928425 -0.246900520178 -469 9.38 -1.02356562938 -0.245820030663 -470 9.4 -1.0186600702 -0.244735200927 -471 9.42 -1.01377624733 -0.243646473201 -472 9.44 -1.00891423443 -0.242554271687 -473 9.46 -1.0040740969 -0.241459003238 -474 9.48 -0.999255892143 -0.240361058009 -475 9.5 -0.994459669928 -0.239260810093 -476 9.52 -0.989685472697 -0.238158618121 -477 9.54 -0.984933335869 -0.237054825845 -478 9.56 -0.980203288132 -0.235949762702 -479 9.58 -0.975495351726 -0.234843744346 -480 9.6 -0.970809542708 -0.233737073173 -481 9.62 -0.966145871217 -0.232630038816 -482 9.64 -0.961504341725 -0.231522918625 -483 9.66 -0.956884953272 -0.230415978128 -484 9.68 -0.952287699705 -0.229309471477 -485 9.7 -0.947712569897 -0.228203641873 -486 9.72 -0.943159547963 -0.22709872198 -487 9.74 -0.938628613467 -0.225994934317 -488 9.76 -0.934119741622 -0.224892491642 -489 9.78 -0.929632903477 -0.223791597316 -490 9.8 -0.925168066109 -0.222692445658 -491 9.82 -0.920725192794 -0.221595222284 -492 9.84 -0.916304243179 -0.220500104432 -493 9.86 -0.91190517345 -0.219407261278 -494 9.88 -0.907527936486 -0.218316854241 -495 9.9 -0.903172482012 -0.217229037271 -496 9.92 -0.898838756748 -0.216143957132 -497 9.94 -0.894526704547 -0.215061753669 -498 9.96 -0.890236266534 -0.213982560076 -499 9.98 -0.885967381232 -0.212906503136 -500 10.0 -0.881719984692 -0.211833703472 -501 10.02 -0.877494010612 -0.210764275774 -502 10.04 -0.873289390453 -0.209698329022 -503 10.06 -0.869106053554 -0.208635966708 -504 10.08 -0.864943927233 -0.207577287034 -505 10.1 -0.860802936899 -0.206522383122 -506 10.12 -0.856683006147 -0.205471343199 -507 10.14 -0.852584056854 -0.204424250786 -508 10.16 -0.848506009271 -0.203381184875 -509 10.18 -0.844448782117 -0.202342220105 -510 10.2 -0.840412292656 -0.201307426921 -511 10.22 -0.836396456786 -0.20027687174 -512 10.24 -0.832401189115 -0.199250617102 -513 10.26 -0.828426403039 -0.19822872182 -514 10.28 -0.824472010811 -0.197211241119 -515 10.3 -0.820537923617 -0.196198226777 -516 10.32 -0.81662405164 -0.195189727259 -517 10.34 -0.812730304126 -0.19418578784 -518 10.36 -0.808856589444 -0.193186450732 -519 10.38 -0.805002815152 -0.1921917552 -520 10.4 -0.801168888049 -0.191201737679 -521 10.42 -0.797354714233 -0.190216431881 -522 10.44 -0.793560199154 -0.189235868906 -523 10.46 -0.789785247667 -0.188260077336 -524 10.48 -0.786029764076 -0.187289083343 -525 10.5 -0.782293652189 -0.186322910778 -526 10.52 -0.778576815358 -0.185361581264 -527 10.54 -0.774879156522 -0.184405114284 -528 10.56 -0.771200578253 -0.183453527268 -529 10.58 -0.767540982794 -0.182506835671 -530 10.6 -0.763900272099 -0.181565053055 -531 10.62 -0.760278347867 -0.180628191165 -532 10.64 -0.75667511158 -0.179696260001 -533 10.66 -0.753090464539 -0.17876926789 -534 10.68 -0.749524307893 -0.177847221551 -535 10.7 -0.745976542671 -0.176930126167 -536 10.72 -0.742447069815 -0.176017985441 -537 10.74 -0.738935790206 -0.175110801662 -538 10.76 -0.735442604695 -0.174208575761 -539 10.78 -0.731967414126 -0.173311307369 -540 10.8 -0.728510119361 -0.172418994873 -541 10.82 -0.72507062131 -0.171531635464 -542 10.84 -0.721648820948 -0.170649225192 -543 10.86 -0.718244619341 -0.169771759015 -544 10.88 -0.714857917667 -0.168899230842 -545 10.9 -0.711488617235 -0.168031633581 -546 10.92 -0.708136619505 -0.167168959186 -547 10.94 -0.704801826108 -0.166311198692 -548 10.96 -0.701484138863 -0.165458342262 -549 10.98 -0.698183459794 -0.164610379221 -550 11.0 -0.694899691148 -0.1637672981 -551 11.02 -0.691632735406 -0.162929086665 -552 11.04 -0.688382495303 -0.162095731957 -553 11.06 -0.68514887384 -0.161267220326 -554 11.08 -0.681931774298 -0.160443537459 -555 11.1 -0.678731100249 -0.159624668416 -556 11.12 -0.675546755573 -0.15881059766 -557 11.14 -0.672378644462 -0.15800130908 -558 11.16 -0.669226671439 -0.157196786028 -559 11.18 -0.666090741365 -0.156397011339 -560 11.2 -0.662970759447 -0.155601967361 -561 11.22 -0.659866631253 -0.154811635976 -562 11.24 -0.656778262715 -0.154025998629 -563 11.26 -0.653705560141 -0.153245036348 -564 11.28 -0.650648430223 -0.152468729768 -565 11.3 -0.647606780043 -0.15169705915 -566 11.32 -0.644580517084 -0.150930004405 -567 11.34 -0.641569549231 -0.150167545112 -568 11.36 -0.638573784781 -0.149409660536 -569 11.38 -0.635593132451 -0.148656329652 -570 11.4 -0.632627501379 -0.147907531156 -571 11.42 -0.629676801133 -0.147163243484 -572 11.44 -0.626740941713 -0.146423444834 -573 11.46 -0.62381983356 -0.145688113174 -574 11.48 -0.620913387554 -0.144957226261 -575 11.5 -0.618021515027 -0.144230761656 -576 11.52 -0.615144127757 -0.143508696739 -577 11.54 -0.612281137978 -0.14279100872 -578 11.56 -0.609432458382 -0.142077674653 -579 11.58 -0.606598002119 -0.141368671449 -580 11.6 -0.603777682806 -0.140663975889 -581 11.62 -0.600971414522 -0.139963564633 -582 11.64 -0.598179111815 -0.139267414235 -583 11.66 -0.595400689704 -0.138575501149 -584 11.68 -0.592636063678 -0.137887801745 -585 11.7 -0.589885149701 -0.137204292313 -586 11.72 -0.587147864211 -0.136524949077 -587 11.74 -0.584424124122 -0.135849748201 -588 11.76 -0.581713846826 -0.135178665802 -589 11.78 -0.579016950193 -0.134511677954 -590 11.8 -0.576333352571 -0.133848760697 -591 11.82 -0.573662972788 -0.133189890048 -592 11.84 -0.571005730151 -0.132535042004 -593 11.86 -0.56836154445 -0.131884192552 -594 11.88 -0.565730335952 -0.131237317677 -595 11.9 -0.563112025406 -0.130594393364 -596 11.92 -0.560506534041 -0.129955395608 -597 11.94 -0.557913783565 -0.129320300421 -598 11.96 -0.555333696166 -0.128689083832 -599 11.98 -0.552766194514 -0.1280617219 -600 12.0 -0.550211201752 -0.127438190715 -601 12.02 -0.547668641506 -0.126818466403 -602 12.04 -0.545138437876 -0.126202525133 -603 12.06 -0.542620515439 -0.125590343118 -604 12.08 -0.540114799247 -0.124981896625 -605 12.1 -0.537621214828 -0.124377161973 -606 12.12 -0.53513968818 -0.123776115544 -607 12.14 -0.532670145775 -0.123178733779 -608 12.16 -0.530212514555 -0.122584993188 -609 12.18 -0.52776672193 -0.121994870352 -610 12.2 -0.525332695778 -0.121408341923 -611 12.22 -0.522910364445 -0.120825384632 -612 12.24 -0.52049965674 -0.120245975289 -613 12.26 -0.518100501935 -0.119670090788 -614 12.28 -0.515712829763 -0.119097708107 -615 12.3 -0.513336570418 -0.118528804313 -616 12.32 -0.51097165455 -0.117963356563 -617 12.34 -0.508618013267 -0.11740134211 -618 12.36 -0.506275578128 -0.116842738298 -619 12.38 -0.503944281147 -0.116287522571 -620 12.4 -0.501624054788 -0.115735672472 -621 12.42 -0.49931483196 -0.115187165645 -622 12.44 -0.497016546022 -0.114641979838 -623 12.46 -0.494729130774 -0.114100092904 -624 12.48 -0.49245252046 -0.1135614828 -625 12.5 -0.490186649763 -0.113026127594 -626 12.52 -0.487931453803 -0.112494005462 -627 12.54 -0.485686868135 -0.11196509469 -628 12.56 -0.48345282875 -0.111439373678 -629 12.58 -0.481229272066 -0.110916820936 -630 12.6 -0.479016134933 -0.110397415091 -631 12.62 -0.476813354625 -0.109881134884 -632 12.64 -0.474620868841 -0.109367959171 -633 12.66 -0.472438615702 -0.108857866928 -634 12.68 -0.470266533747 -0.108350837244 -635 12.7 -0.468104561934 -0.107846849332 -636 12.72 -0.465952639633 -0.107345882519 -637 12.74 -0.463810706629 -0.106847916255 -638 12.76 -0.461678703116 -0.106352930108 -639 12.78 -0.459556569693 -0.105860903769 -640 12.8 -0.457444247367 -0.105371817049 -641 12.82 -0.455341677547 -0.10488564988 -642 12.84 -0.453248802042 -0.104402382317 -643 12.86 -0.451165563056 -0.103921994536 -644 12.88 -0.449091903193 -0.103444466836 -645 12.9 -0.447027765446 -0.102969779639 -646 12.92 -0.4449730932 -0.102497913489 -647 12.94 -0.442927830229 -0.102028849053 -648 12.96 -0.440891920688 -0.101562567122 -649 12.98 -0.438865309121 -0.101099048608 -650 13.0 -0.436847940448 -0.100638274548 -651 13.02 -0.434839759968 -0.100180226101 -652 13.04 -0.432840713358 -0.0997248845489 -653 13.06 -0.430850746664 -0.0992722312959 -654 13.08 -0.428869806307 -0.0988222478696 -655 13.1 -0.426897839073 -0.0983749159199 -656 13.12 -0.424934792115 -0.0979302172191 -657 13.14 -0.42298061295 -0.0974881336614 -658 13.16 -0.421035249454 -0.097048647263 -659 13.18 -0.419098649864 -0.0966117401617 -660 13.2 -0.417170762771 -0.0961773946166 -661 13.22 -0.41525153712 -0.0957455930079 -662 13.24 -0.413340922208 -0.0953163178365 -663 13.26 -0.411438867679 -0.0948895517235 -664 13.28 -0.409545323527 -0.0944652774101 -665 13.3 -0.407660240085 -0.0940434777572 -666 13.32 -0.405783568032 -0.0936241357448 -667 13.34 -0.403915258384 -0.0932072344716 -668 13.36 -0.402055262494 -0.0927927571548 -669 13.38 -0.400203532049 -0.0923806871294 -670 13.4 -0.39836001907 -0.091971007848 -671 13.42 -0.396524675907 -0.0915637028799 -672 13.44 -0.394697455235 -0.0911587559112 -673 13.46 -0.392878310058 -0.0907561507435 -674 13.48 -0.391067193701 -0.0903558712944 -675 13.5 -0.389264059808 -0.0899579015961 -676 13.52 -0.387468862344 -0.0895622257951 -677 13.54 -0.385681555589 -0.089168828152 -678 13.56 -0.383902094135 -0.0887776930406 -679 13.58 -0.382130432887 -0.0883888049474 -680 13.6 -0.380366527059 -0.088002148471 -681 13.62 -0.378610332173 -0.0876177083216 -682 13.64 -0.376861804052 -0.0872354693205 -683 13.66 -0.375120898826 -0.0868554163993 -684 13.68 -0.373387572922 -0.0864775345994 -685 13.7 -0.371661783067 -0.0861018090713 -686 13.72 -0.369943486282 -0.0857282250742 -687 13.74 -0.368232639885 -0.0853567679751 -688 13.76 -0.366529201481 -0.0849874232486 -689 13.78 -0.364833128968 -0.0846201764757 -690 13.8 -0.363144380531 -0.0842550133436 -691 13.82 -0.361462914638 -0.083891919645 -692 13.84 -0.359788690043 -0.0835308812773 -693 13.86 -0.358121665778 -0.0831718842421 -694 13.88 -0.356461801157 -0.0828149146446 -695 13.9 -0.354809055768 -0.0824599586927 -696 13.92 -0.353163389476 -0.0821070026966 -697 13.94 -0.351524762418 -0.0817560330682 -698 13.96 -0.349893135001 -0.0814070363201 -699 13.98 -0.348268467902 -0.0810599990654 -700 14.0 -0.346650722064 -0.0807149080166 -701 14.02 -0.345039858694 -0.0803717499853 -702 14.04 -0.343435839265 -0.0800305118814 -703 14.06 -0.341838625506 -0.0796911807123 -704 14.08 -0.340248179409 -0.0793537435825 -705 14.1 -0.338664463221 -0.079018187693 -706 14.12 -0.337087439445 -0.0786845003402 -707 14.14 -0.335517070835 -0.0783526689157 -708 14.16 -0.333953320399 -0.0780226809053 -709 14.18 -0.332396151392 -0.0776945238888 -710 14.2 -0.330845527319 -0.0773681855387 -711 14.22 -0.329301411928 -0.0770436536203 -712 14.24 -0.327763769212 -0.0767209159903 -713 14.26 -0.326232563407 -0.0763999605967 -714 14.28 -0.324707758986 -0.076080775478 -715 14.3 -0.323189320665 -0.0757633487623 -716 14.32 -0.321677213392 -0.075447668667 -717 14.34 -0.320171402352 -0.0751337234981 -718 14.36 -0.318671852963 -0.0748215016493 -719 14.38 -0.317178530874 -0.0745109916017 -720 14.4 -0.315691401963 -0.0742021819228 -721 14.42 -0.314210432337 -0.0738950612663 -722 14.44 -0.312735588328 -0.073589618371 -723 14.46 -0.311266836492 -0.0732858420606 -724 14.48 -0.309804143609 -0.0729837212427 -725 14.5 -0.308347476679 -0.0726832449085 -726 14.52 -0.306896802922 -0.0723844021319 -727 14.54 -0.305452089775 -0.072087182069 -728 14.56 -0.304013304893 -0.0717915739575 -729 14.58 -0.302580416142 -0.0714975671162 -730 14.6 -0.301153391604 -0.071205150944 -731 14.62 -0.29973219957 -0.0709143149198 -732 14.64 -0.298316808542 -0.0706250486013 -733 14.66 -0.29690718723 -0.0703373416252 -734 14.68 -0.29550330455 -0.0700511837056 -735 14.7 -0.294105129623 -0.0697665646344 -736 14.72 -0.292712631773 -0.06948347428 -737 14.74 -0.291325780527 -0.069201902587 -738 14.76 -0.289944545612 -0.0689218395755 -739 14.78 -0.288568896953 -0.0686432753407 -740 14.8 -0.287198804672 -0.068366200052 -741 14.82 -0.285834239089 -0.0680906039529 -742 14.84 -0.284475170717 -0.0678164773599 -743 14.86 -0.283121570262 -0.0675438106623 -744 14.88 -0.281773408622 -0.0672725943215 -745 14.9 -0.280430656883 -0.0670028188703 -746 14.92 -0.279093286324 -0.0667344749127 -747 14.94 -0.277761268406 -0.066467553123 -748 14.96 -0.276434574779 -0.0662020442454 -749 14.98 -0.275113177278 -0.0659379390934 -750 15.0 -0.273797047918 -0.0656752285492 -751 15.02 -0.272486158899 -0.0654139035635 -752 15.04 -0.271180482599 -0.0651539551544 -753 15.06 -0.269879991575 -0.0648953744073 -754 15.08 -0.268584658563 -0.0646381524742 -755 15.1 -0.267294456476 -0.0643822805732 -756 15.12 -0.266009358398 -0.064127749988 -757 15.14 -0.264729337592 -0.0638745520673 -758 15.16 -0.263454367489 -0.0636226782243 -759 15.18 -0.262184421693 -0.0633721199364 -760 15.2 -0.260919473977 -0.0631228687444 -761 15.22 -0.259659498285 -0.062874916252 -762 15.24 -0.258404468725 -0.0626282541256 -763 15.26 -0.257154359572 -0.0623828740934 -764 15.28 -0.255909145268 -0.0621387679452 -765 15.3 -0.254668800416 -0.061895927532 -766 15.32 -0.253433299783 -0.061654344765 -767 15.34 -0.252202618295 -0.0614140116156 -768 15.36 -0.250976731041 -0.0611749201148 -769 15.38 -0.249755613266 -0.0609370623526 -770 15.4 -0.248539240374 -0.0607004304776 -771 15.42 -0.247327587926 -0.0604650166966 -772 15.44 -0.246120631637 -0.0602308132741 -773 15.46 -0.244918347377 -0.0599978125317 -774 15.48 -0.243720711169 -0.0597660068478 -775 15.5 -0.242527699187 -0.0595353886571 -776 15.52 -0.241339287756 -0.05930595045 -777 15.54 -0.240155453352 -0.0590776847726 -778 15.56 -0.238976172597 -0.0588505842256 -779 15.58 -0.237801422264 -0.0586246414643 -780 15.6 -0.236631179269 -0.0583998491983 -781 15.62 -0.235465420674 -0.0581762001905 -782 15.64 -0.234304123687 -0.057953687257 -783 15.66 -0.233147265658 -0.057732303267 -784 15.68 -0.231994824078 -0.0575120411416 -785 15.7 -0.23084677658 -0.0572928938542 -786 15.72 -0.229703100938 -0.0570748544293 -787 15.74 -0.228563775063 -0.0568579159429 -788 15.76 -0.227428777006 -0.0566420715213 -789 15.78 -0.226298084954 -0.0564273143414 -790 15.8 -0.22517167723 -0.0562136376296 -791 15.82 -0.224049532291 -0.0560010346619 -792 15.84 -0.222931628729 -0.0557894987635 -793 15.86 -0.22181794527 -0.0555790233081 -794 15.88 -0.220708460771 -0.0553696017175 -795 15.9 -0.21960315422 -0.0551612274618 -796 15.92 -0.218502004734 -0.0549538940582 -797 15.94 -0.217404991561 -0.0547475950712 -798 15.96 -0.216312094077 -0.0545423241119 -799 15.98 -0.215223291785 -0.0543380748379 -800 16.0 -0.214138564315 -0.0541348409526 -801 16.02 -0.21305789142 -0.0539326162051 -802 16.04 -0.21198125298 -0.0537313943897 -803 16.06 -0.210908628999 -0.0535311693457 -804 16.08 -0.209839999602 -0.0533319349567 -805 16.1 -0.208775345037 -0.0531336851505 -806 16.12 -0.207714645672 -0.0529364138987 -807 16.14 -0.206657881997 -0.0527401152166 -808 16.16 -0.205605034619 -0.0525447831621 -809 16.18 -0.204556084266 -0.0523504118362 -810 16.2 -0.20351101178 -0.0521569953823 -811 16.22 -0.202469798123 -0.0519645279856 -812 16.24 -0.201432424372 -0.0517730038733 -813 16.26 -0.200398871718 -0.0515824173138 -814 16.28 -0.199369121467 -0.0513927626166 -815 16.3 -0.198343155039 -0.051204034132 -816 16.32 -0.197320953965 -0.0510162262506 -817 16.34 -0.196302499889 -0.050829333403 -818 16.36 -0.195287774565 -0.0506433500599 -819 16.38 -0.194276759859 -0.0504582707309 -820 16.4 -0.193269437746 -0.0502740899651 -821 16.42 -0.192265790306 -0.0500908023503 -822 16.44 -0.191265799733 -0.0499084025129 -823 16.46 -0.190269448323 -0.0497268851171 -824 16.48 -0.189276718481 -0.0495462448654 -825 16.5 -0.188287592716 -0.0493664764977 -826 16.52 -0.187302053643 -0.0491875747911 -827 16.54 -0.186320083981 -0.0490095345599 -828 16.56 -0.185341666552 -0.0488323506547 -829 16.58 -0.18436678428 -0.0486560179629 -830 16.6 -0.183395420192 -0.0484805314077 -831 16.62 -0.182427557417 -0.0483058859483 -832 16.64 -0.181463179181 -0.0481320765793 -833 16.66 -0.180502268813 -0.0479590983305 -834 16.68 -0.179544809739 -0.0477869462668 -835 16.7 -0.178590785487 -0.0476156154877 -836 16.72 -0.177640179677 -0.0474451011271 -837 16.74 -0.176692976031 -0.0472753983531 -838 16.76 -0.175749158364 -0.0471065023674 -839 16.78 -0.174808710589 -0.0469384084057 -840 16.8 -0.173871616713 -0.0467711117367 -841 16.82 -0.172937860836 -0.0466046076623 -842 16.84 -0.172007427154 -0.0464388915171 -843 16.86 -0.171080299953 -0.0462739586683 -844 16.88 -0.170156463616 -0.0461098045155 -845 16.9 -0.169235902612 -0.04594642449 -846 16.92 -0.168318601505 -0.0457838140552 -847 16.94 -0.167404544949 -0.0456219687059 -848 16.96 -0.166493717686 -0.0454608839681 -849 16.98 -0.165586104549 -0.0453005553988 -850 17.0 -0.164681690459 -0.045140978586 -851 17.02 -0.163780460423 -0.044982149148 -852 17.04 -0.162882399539 -0.0448240627335 -853 17.06 -0.161987492989 -0.0446667150213 -854 17.08 -0.161095726042 -0.0445101017198 -855 17.1 -0.160207084053 -0.0443542185673 -856 17.12 -0.15932155246 -0.0441990613312 -857 17.14 -0.158439116788 -0.0440446258081 -858 17.16 -0.157559762644 -0.0438909078236 -859 17.18 -0.156683475719 -0.0437379032318 -860 17.2 -0.155810241787 -0.0435856079154 -861 17.22 -0.154940046702 -0.0434340177851 -862 17.24 -0.154072876401 -0.0432831287799 -863 17.26 -0.153208716903 -0.0431329368663 -864 17.28 -0.152347554306 -0.0429834380385 -865 17.3 -0.151489374787 -0.0428346283181 -866 17.32 -0.150634164605 -0.0426865037537 -867 17.34 -0.149781910096 -0.0425390604208 -868 17.36 -0.148932597673 -0.0423922944219 -869 17.38 -0.148086213829 -0.0422462018856 -870 17.4 -0.147242745133 -0.0421007789672 -871 17.42 -0.146402178232 -0.0419560218477 -872 17.44 -0.145564499846 -0.0418119267343 -873 17.46 -0.144729696774 -0.0416684898597 -874 17.48 -0.143897755889 -0.0415257074823 -875 17.5 -0.143068664136 -0.0413835758856 -876 17.52 -0.142242408539 -0.0412420913782 -877 17.54 -0.141418976192 -0.0411012502937 -878 17.56 -0.140598354262 -0.0409610489904 -879 17.58 -0.139780529991 -0.0408214838511 -880 17.6 -0.138965490691 -0.040682551283 -881 17.62 -0.138153223746 -0.0405442477172 -882 17.64 -0.137343716613 -0.0404065696091 -883 17.66 -0.136536956816 -0.0402695134376 -884 17.68 -0.135732931952 -0.0401330757054 -885 17.7 -0.134931629688 -0.0399972529384 -886 17.72 -0.134133037758 -0.0398620416858 -887 17.74 -0.133337143966 -0.0397274385201 -888 17.76 -0.132543936186 -0.0395934400363 -889 17.78 -0.131753402356 -0.0394600428522 -890 17.8 -0.130965530486 -0.0393272436083 -891 17.82 -0.130180308648 -0.0391950389674 -892 17.84 -0.129397724985 -0.0390634256142 -893 17.86 -0.128617767704 -0.0389324002559 -894 17.88 -0.127840425077 -0.0388019596211 -895 17.9 -0.127065685442 -0.0386721004602 -896 17.92 -0.126293537203 -0.0385428195454 -897 17.94 -0.125523968827 -0.0384141136698 -898 17.96 -0.124756968844 -0.038285979648 -899 17.98 -0.12399252585 -0.0381584143155 -900 18.0 -0.123230628501 -0.0380314145287 -901 18.02 -0.122471265519 -0.0379049771648 -902 18.04 -0.121714425686 -0.0377790991214 -903 18.06 -0.120960097846 -0.0376537773164 -904 18.08 -0.120208270905 -0.0375290086883 -905 18.1 -0.119458933831 -0.0374047901954 -906 18.12 -0.11871207565 -0.0372811188161 -907 18.14 -0.117967685451 -0.0371579915483 -908 18.16 -0.117225752381 -0.0370354054099 -909 18.18 -0.116486265647 -0.0369133574381 -910 18.2 -0.115749214515 -0.0367918446895 -911 18.22 -0.11501458831 -0.0366708642398 -912 18.24 -0.114282376416 -0.0365504131839 -913 18.26 -0.113552568273 -0.0364304886354 -914 18.28 -0.11282515338 -0.0363110877269 -915 18.3 -0.112100121292 -0.0361922076096 -916 18.32 -0.111377461622 -0.0360738454529 -917 18.34 -0.110657164039 -0.0359559984449 -918 18.36 -0.109939218269 -0.0358386637917 -919 18.38 -0.109223614091 -0.0357218387177 -920 18.4 -0.108510341341 -0.0356055204649 -921 18.42 -0.107799389911 -0.0354897062933 -922 18.44 -0.107090749747 -0.0353743934808 -923 18.46 -0.106384410848 -0.0352595793223 -924 18.48 -0.105680363268 -0.0351452611307 -925 18.5 -0.104978597114 -0.0350314362357 -926 18.52 -0.104279102547 -0.0349181019845 -927 18.54 -0.103581869781 -0.0348052557411 -928 18.56 -0.102886889082 -0.0346928948865 -929 18.58 -0.102194150767 -0.0345810168186 -930 18.6 -0.101503645208 -0.0344696189517 -931 18.62 -0.100815362825 -0.0343586987167 -932 18.64 -0.100129294092 -0.0342482535611 -933 18.66 -0.0994454295322 -0.0341382809484 -934 18.68 -0.0987637597204 -0.0340287783585 -935 18.7 -0.0980842752811 -0.0339197432873 -936 18.72 -0.0974069668887 -0.0338111732465 -937 18.74 -0.0967318252675 -0.0337030657637 -938 18.76 -0.0960588411908 -0.0335954183822 -939 18.78 -0.0953880054812 -0.0334882286609 -940 18.8 -0.0947193090095 -0.0333814941741 -941 18.82 -0.0940527426954 -0.0332752125115 -942 18.84 -0.0933882975062 -0.0331693812782 -943 18.86 -0.0927259644573 -0.033063998094 -944 18.88 -0.0920657346112 -0.0329590605941 -945 18.9 -0.0914075990779 -0.0328545664286 -946 18.92 -0.0907515490141 -0.0327505132621 -947 18.94 -0.0900975756229 -0.0326468987742 -948 18.96 -0.089445670154 -0.032543720659 -949 18.98 -0.0887958239027 -0.0324409766249 -950 19.0 -0.0881480282103 -0.032338664395 -951 19.02 -0.0875022744633 -0.0322367817064 -952 19.04 -0.0868585540934 -0.0321353263106 -953 19.06 -0.0862168585771 -0.0320342959728 -954 19.08 -0.0855771794356 -0.0319336884725 -955 19.1 -0.084939508234 -0.0318335016031 -956 19.12 -0.0843038365819 -0.0317337331714 -957 19.14 -0.0836701561321 -0.0316343809981 -958 19.16 -0.0830384585813 -0.0315354429176 -959 19.18 -0.0824087356692 -0.0314369167774 -960 19.2 -0.0817809791782 -0.0313388004388 -961 19.22 -0.0811551809338 -0.031241091776 -962 19.24 -0.0805313328034 -0.0311437886765 -963 19.26 -0.079909426697 -0.031046889041 -964 19.28 -0.079289454566 -0.030950390783 -965 19.3 -0.0786714084036 -0.0308542918291 -966 19.32 -0.0780552802445 -0.0307585901186 -967 19.34 -0.0774410621642 -0.0306632836034 -968 19.36 -0.0768287462793 -0.0305683702482 -969 19.38 -0.0762183247467 -0.0304738480301 -970 19.4 -0.0756097897639 -0.0303797149388 -971 19.42 -0.0750031335683 -0.0302859689762 -972 19.44 -0.0743983484373 -0.0301926081566 -973 19.46 -0.0737954266876 -0.0300996305063 -974 19.48 -0.0731943606756 -0.0300070340638 -975 19.5 -0.0725951427967 -0.0299148168796 -976 19.52 -0.071997765485 -0.0298229770161 -977 19.54 -0.0714022212134 -0.0297315125477 -978 19.56 -0.0708085024932 -0.0296404215602 -979 19.58 -0.0702166018738 -0.0295497021514 -980 19.6 -0.0696265119425 -0.0294593524306 -981 19.62 -0.0690382253245 -0.0293693705184 -982 19.64 -0.0684517346822 -0.0292797545471 -983 19.66 -0.0678670327154 -0.0291905026603 -984 19.68 -0.0672841121609 -0.0291016130126 -985 19.7 -0.0667029657922 -0.0290130837702 -986 19.72 -0.0661235864195 -0.02892491311 -987 19.74 -0.0655459668893 -0.0288370992202 -988 19.76 -0.0649701000843 -0.0287496402998 -989 19.78 -0.0643959789228 -0.0286625345588 -990 19.8 -0.0638235963592 -0.028575780218 -991 19.82 -0.0632529453832 -0.0284893755087 -992 19.84 -0.0626840190197 -0.0284033186731 -993 19.86 -0.0621168103288 -0.0283176079638 -994 19.88 -0.0615513124053 -0.0282322416441 -995 19.9 -0.0609875183786 -0.0281472179874 -996 19.92 -0.0604254214128 -0.0280625352778 -997 19.94 -0.0598650147059 -0.0279781918096 -998 19.96 -0.0593062914901 -0.027894185887 -999 19.98 -0.0587492450313 -0.0278105158248 -1000 20.0 -0.0581938686292 -0.0277271799475 -1001 20.02 -0.0576401556166 -0.0276441765898 -1002 20.04 -0.0570880993599 -0.0275615040963 -1003 20.06 -0.056537693258 -0.0274791608214 -1004 20.08 -0.0559889307431 -0.0273971451294 -1005 20.1 -0.0554418052798 -0.0273154553941 -1006 20.12 -0.0548963103651 -0.0272340899992 -1007 20.14 -0.0543524395283 -0.0271530473379 -1008 20.16 -0.0538101863307 -0.027072325813 -1009 20.18 -0.0532695443654 -0.0269919238365 -1010 20.2 -0.0527305072574 -0.0269118398301 -1011 20.22 -0.0521930686629 -0.0268320722247 -1012 20.24 -0.0516572222695 -0.0267526194605 -1013 20.26 -0.0511229617959 -0.0266734799867 -1014 20.28 -0.0505902809917 -0.0265946522621 -1015 20.3 -0.0500591736373 -0.026516134754 -1016 20.32 -0.0495296335436 -0.0264379259393 -1017 20.34 -0.0490016545518 -0.0263600243033 -1018 20.36 -0.0484752305336 -0.0262824283405 -1019 20.38 -0.0479503553904 -0.0262051365543 -1020 20.4 -0.0474270230535 -0.0261281474567 -1021 20.42 -0.0469052274841 -0.0260514595684 -1022 20.44 -0.0463849626725 -0.0259750714189 -1023 20.46 -0.0458662226388 -0.0258989815462 -1024 20.48 -0.0453490014319 -0.0258231884968 -1025 20.5 -0.0448332931297 -0.0257476908257 -1026 20.52 -0.0443190918392 -0.0256724870964 -1027 20.54 -0.0438063916958 -0.0255975758806 -1028 20.56 -0.0432951868634 -0.0255229557586 -1029 20.58 -0.0427854715342 -0.0254486253186 -1030 20.6 -0.0422772399288 -0.0253745831572 -1031 20.62 -0.0417704862954 -0.0253008278792 -1032 20.64 -0.0412652049103 -0.0252273580972 -1033 20.66 -0.0407613900774 -0.0251541724321 -1034 20.68 -0.040259036128 -0.0250812695126 -1035 20.7 -0.039758137421 -0.0250086479756 -1036 20.72 -0.0392586883422 -0.0249363064654 -1037 20.74 -0.0387606833045 -0.0248642436347 -1038 20.76 -0.0382641167479 -0.0247924581434 -1039 20.78 -0.0377689831387 -0.0247209486595 -1040 20.8 -0.0372752769703 -0.0246497138585 -1041 20.82 -0.036782992762 -0.0245787524235 -1042 20.84 -0.0362921250596 -0.0245080630453 -1043 20.86 -0.0358026684351 -0.0244376444219 -1044 20.88 -0.0353146174863 -0.0243674952592 -1045 20.9 -0.0348279668369 -0.0242976142701 -1046 20.92 -0.0343427111362 -0.0242280001751 -1047 20.94 -0.0338588450591 -0.0241586517019 -1048 20.96 -0.0333763633058 -0.0240895675856 -1049 20.98 -0.0328952606017 -0.0240207465683 -1050 21.0 -0.0324155316974 -0.0239521873994 -1051 21.02 -0.0319371713684 -0.0238838888354 -1052 21.04 -0.0314601744149 -0.0238158496399 -1053 21.06 -0.0309845356618 -0.0237480685835 -1054 21.08 -0.0305102499587 -0.0236805444437 -1055 21.1 -0.0300373121794 -0.0236132760051 -1056 21.12 -0.0295657172219 -0.023546262059 -1057 21.14 -0.0290954600085 -0.0234795014037 -1058 21.16 -0.0286265354851 -0.0234129928442 -1059 21.18 -0.028158938622 -0.0233467351922 -1060 21.2 -0.0276926644126 -0.0232807272662 -1061 21.22 -0.0272277078743 -0.0232149678915 -1062 21.24 -0.0267640640477 -0.0231494558997 -1063 21.26 -0.0263017279969 -0.0230841901292 -1064 21.28 -0.0258406948088 -0.0230191694249 -1065 21.3 -0.0253809595937 -0.0229543926381 -1066 21.32 -0.0249225174848 -0.0228898586266 -1067 21.34 -0.0244653636377 -0.0228255662547 -1068 21.36 -0.0240094932312 -0.0227615143929 -1069 21.38 -0.0235549014661 -0.0226977019182 -1070 21.4 -0.023101583566 -0.0226341277136 -1071 21.42 -0.0226495347765 -0.0225707906687 -1072 21.44 -0.0221987503655 -0.0225076896791 -1073 21.46 -0.021749225623 -0.0224448236465 -1074 21.48 -0.0213009558606 -0.0223821914788 -1075 21.5 -0.020853936412 -0.02231979209 -1076 21.52 -0.0204081626323 -0.0222576244002 -1077 21.54 -0.0199636298985 -0.0221956873354 -1078 21.56 -0.0195203336085 -0.0221339798275 -1079 21.58 -0.0190782691821 -0.0220725008144 -1080 21.6 -0.0186374320597 -0.02201124924 -1081 21.62 -0.0181978177032 -0.0219502240539 -1082 21.64 -0.0177594215953 -0.0218894242115 -1083 21.66 -0.0173222392394 -0.0218288486741 -1084 21.68 -0.0168862661598 -0.0217684964086 -1085 21.7 -0.0164514979014 -0.0217083663878 -1086 21.72 -0.0160179300295 -0.0216484575898 -1087 21.74 -0.0155855581298 -0.0215887689986 -1088 21.76 -0.0151543778082 -0.0215292996039 -1089 21.78 -0.014724384691 -0.0214700484006 -1090 21.8 -0.0142955744243 -0.0214110143895 -1091 21.82 -0.0138679426741 -0.0213521965765 -1092 21.84 -0.0134414851265 -0.0212935939733 -1093 21.86 -0.013016197487 -0.0212352055967 -1094 21.88 -0.0125920754809 -0.0211770304692 -1095 21.9 -0.012169114853 -0.0211190676184 -1096 21.92 -0.0117473113675 -0.0210613160772 -1097 21.94 -0.0113266608076 -0.021003774884 -1098 21.96 -0.0109071589762 -0.0209464430823 -1099 21.98 -0.0104888016947 -0.0208893197208 -1100 22.0 -0.010071584804 -0.0208324038534 -1101 22.02 -0.00965550416359 -0.0207756945391 -1102 22.04 -0.0092405556517 -0.020719190842 -1103 22.06 -0.00882673516534 -0.0206628918315 -1104 22.08 -0.00841403862003 -0.0206067965819 -1105 22.1 -0.0080024619498 -0.0205509041723 -1106 22.12 -0.00759200110698 -0.0204952136871 -1107 22.14 -0.00718265206222 -0.0204397242155 -1108 22.16 -0.00677441080431 -0.0203844348517 -1109 22.18 -0.00636727334011 -0.0203293446947 -1110 22.2 -0.00596123569445 -0.0202744528484 -1111 22.22 -0.00555629391005 -0.0202197584216 -1112 22.24 -0.00515244404737 -0.0201652605278 -1113 22.26 -0.00474968218459 -0.0201109582853 -1114 22.28 -0.00434800441746 -0.0200568508172 -1115 22.3 -0.00394740685922 -0.0200029372512 -1116 22.32 -0.00354788564052 -0.0199492167196 -1117 22.34 -0.0031494369093 -0.0198956883597 -1118 22.36 -0.00275205683071 -0.0198423513132 -1119 22.38 -0.00235574158704 -0.0197892047262 -1120 22.4 -0.00196048737759 -0.0197362477497 -1121 22.42 -0.00156629041861 -0.0196834795391 -1122 22.44 -0.00117314694319 -0.0196308992543 -1123 22.46 -0.000781053201174 -0.0195785060596 -1124 22.48 -0.000390005459079 -0.019526299124 -1125 22.5 0.0 -0.0194742776206 -1126 22.52 0.0 0.0 -1127 22.54 0.0 0.0 -1128 22.56 0.0 0.0 -1129 22.58 0.0 0.0 -1130 22.6 0.0 0.0 diff --git a/tools/moltemplate/examples/coarse_grained_examples/membrane+protein/run.in.min b/tools/moltemplate/examples/coarse_grained_examples/membrane+protein/run.in.min deleted file mode 100644 index 2fc8fbba75..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/membrane+protein/run.in.min +++ /dev/null @@ -1,35 +0,0 @@ -# -------- REQUIREMENTS: --------- -# 1) This example requires the "USER-MISC" package. (Use "make yes-USER-MISC") -# http://lammps.sandia.gov/doc/Section_start.html#start_3 -# 2) It also may require additional features and bug fixes for LAMMPS. -# So, after typing "make yes-user-misc" in to the shell, ... -# be sure to download and copy the "additional_lammps_code" from -# http://moltemplate.org (upper-left corner menu) -# 3) Unpack it -# 4) copy the .cpp and .h files to the src folding of your lammps installation. -# 5) Compile LAMMPS. -# -# If LAMMPS complains about an "Invalid pair_style", or "Invalid dihedral_style" -# then you made a mistake in the instructions above. - - - -# -- Init section -- - -include system.in.init - -# -- Atom definition section -- - -read_data system.data - -# -- Settings Section -- - -include system.in.settings - -# -- Run section -- - -dump 1 all custom 50 traj_min.lammpstrj id mol type x y z ix iy iz - -minimize 1.0e-5 1.0e-7 500 2000 - -write_data system_after_min.data diff --git a/tools/moltemplate/examples/coarse_grained_examples/membrane+protein/run.in.npt b/tools/moltemplate/examples/coarse_grained_examples/membrane+protein/run.in.npt deleted file mode 100644 index cbf76ac2db..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/membrane+protein/run.in.npt +++ /dev/null @@ -1,66 +0,0 @@ -# PREREQUISITES: -# -# You must use moltemplate.sh to create 3 files: -# system.data system.in.init system.in.settings -# (Follow the instructions in README_setup.sh, or run it using ./README_sh.) -# -# -------- REQUIREMENTS: --------- -# 1) This example requires the "USER-MISC" package. (Use "make yes-USER-MISC") -# http://lammps.sandia.gov/doc/Section_start.html#start_3 -# 2) It also may require additional features and bug fixes for LAMMPS. -# So, after typing "make yes-user-misc" in to the shell, ... -# be sure to download and copy the "additional_lammps_code" from -# http://moltemplate.org (upper-left corner menu) -# 3) Unpack it -# 4) copy the .cpp and .h files to the src folding of your lammps installation. -# 5) Compile LAMMPS. -# -# If LAMMPS complains about an "Invalid pair_style", or "Invalid dihedral_style" -# then you made a mistake in the instructions above. -# - -# -- Init Section -- - -include system.in.init - -# -- Atom Definition Section -- - -#read_data system.data -read_data system_after_min.data - -# -- Settings Section -- - -include system.in.settings - -# -- Run Section -- - -#minimize 1.0e-5 1.0e-7 500 2000 - -timestep 10.0 # The time-step in Watson et. al 2011 was 0.002*3ps = 6fs -dump 1 all custom 10000 traj_npt.lammpstrj id mol type x y z ix iy iz - - -thermo_style custom step temp pe etotal vol epair ebond eangle -thermo 1000 # time interval for printing out "thermo" data - - -fix fxlan all langevin 300.0 300.0 120 48279 -fix fxnph all nph x 0 0 1000 y 0 0 1000 couple xy - - -# Note: The temperature 300.0 K corresponds to 0.907033536873*epsilon -# (for the "epsilon" used by the coarse-grained lipid), and -# to 0.33*epsilon (for the "epsilon" used in the coarse-grained protein) -# Note: The langevin damping parameter "120" corresponds to -# the 0.12ps damping time used in Watson et. al JCP 2011. -# Note: We maintain the system system at constant (zero) tention -# using a barostat damping parameter Pdamp=1000 ("0 0 1000") - - -# optional (not sure if this helps): -# balance x uniform y uniform - - -run 100000 - -write_data system_after_npt.data diff --git a/tools/moltemplate/examples/coarse_grained_examples/membrane+protein/run.in.nvt b/tools/moltemplate/examples/coarse_grained_examples/membrane+protein/run.in.nvt deleted file mode 100644 index 05f533339f..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/membrane+protein/run.in.nvt +++ /dev/null @@ -1,71 +0,0 @@ -# PREREQUISITES: -# -# 1) You must use moltemplate.sh to create 3 files: -# system.data system.in.init system.in.settings -# (Follow the instructions in README_setup.sh, or run it using ./README_sh.) -# 2) You must equilibrate the system beforehand using "run.in.npt". -# This will create the file "system_after_npt.data" which this file reads. -# (Note: I have not verified that this equilibration protocol works well.) -# -# -------- LAMMPS REQUIREMENTS: --------- -# 1) This example requires the "USER-MISC" package. (Use "make yes-USER-MISC") -# http://lammps.sandia.gov/doc/Section_start.html#start_3 -# 2) It also may require additional features and bug fixes for LAMMPS. -# So, after typing "make yes-user-misc" in to the shell, ... -# be sure to download and copy the "additional_lammps_code" from -# http://moltemplate.org (upper-left corner menu) -# 3) Unpack it -# 4) copy the .cpp and .h files to the src folding of your lammps installation. -# 5) Compile LAMMPS. -# -# If LAMMPS complains about an "Invalid pair_style", or "Invalid dihedral_style" -# then you made a mistake in the instructions above. -# -# ------------------------------- Initialization Section -------------------- - -include system.in.init - -# ------------------------------- Atom Definition Section ------------------- - - -# Read the coordinates generated by an earlier NPT simulation - -read_data system_after_npt.data - -# (The "write_restart" and "read_restart" commands were buggy in 2012, -# but they should work also. I prefer "write_data" and "read_data".) - - -# ------------------------------- Settings Section -------------------------- - -include system.in.settings - -# ------------------------------- Run Section ------------------------------- - - -timestep 10.0 # The time-step in Watson et. al 2011 was 0.002*3ps = 6fs -dump 1 all custom 10000 traj_nvt.lammpstrj id mol type x y z ix iy iz - - -thermo_style custom step temp pe etotal vol epair ebond eangle -thermo 1000 # time interval for printing out "thermo" data - - -fix fxlan all langevin 300.0 300.0 120 48279 -fix fxnve all nve - -# Note: The energy scale "epsilon" = 2.75kJ/mole = 330.7485200981 Kelvin*kB. -# So a temperature of 300.0 Kelvin corresponds to 0.907033536873*epsilon. -# Note: The langevin damping parameter "120" corresponds to -# the 0.12ps damping time used in Watson et. al JCP 2011. - -#restart 500000 - -run 50000000 - - -write_data system_after_nvt.data - -# (The "write_restart" and "read_restart" commands were buggy in 2012, -# but they should work also.) - diff --git a/tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/README.TXT b/tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/README.TXT deleted file mode 100644 index 1bf9d00b99..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/README.TXT +++ /dev/null @@ -1,33 +0,0 @@ -Note: - This example may require additional features to be added to LAMMPS. -If LAMMPS complains about an "Invalid pair_style", then copy the code -in the "additional_lammps_code" directory into your LAMMPS "src" directory -and recompile LAMMPS. - ------ Description -------- - -This example contains an implementation of the DPPC lipid bilayer described in: - G. Brannigan, P.F. Philips, and F.L.H. Brown, - Physical Review E, Vol 72, 011915 (2005) -and: - M.C. Watson, E.S. Penev, P.M. Welch, and F.L.H. Brown - J. Chem. Phys. 135, 244701 (2011) - -As in Watson(JCP 2011), rigid bond-length constraints -have been replaced by harmonic bonds. - -A truncated version of this lipid (named "DLPC") has also been added. -Unlike the original "DPPC" molecule model, "DLPC" has not been carefully -parameterized to reproduce the correct behavior in a lipid bilayer. - - -------------- - -Instructions on how to build LAMMPS input files and -run a short simulation are provided in other README files. - -step 1) -README_setup.sh - -step2) -README_run.sh diff --git a/tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/README_run.sh b/tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/README_run.sh deleted file mode 100755 index d7ea305695..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/README_run.sh +++ /dev/null @@ -1,33 +0,0 @@ -# --- Running LAMMPS --- -# -- Prerequisites: -- -# The "run.in.nvt" file is a LAMMPS input script containing -# references to the input scripts and data files -# you hopefully have created earlier with moltemplate.sh: -# system.in.init, system.in.settings, system.data, and table_int.dat -# If not, carry out the instructions in "README_setup.sh". -# -# -- Instructions: -- -# If "lmp_mpi" is the name of the command you use to invoke lammps, -# then you would run lammps on these files this way: - - -lmp_mpi -i run.in.npt # Run a simulation at constant pressure (tension) - -#or - -lmp_mpi -i run.in.nvt # Run a simulation at constant volume - -#(Note: The constant volume simulation lacks pressure equilibration. These are -# completely separate simulations. The results of the constant pressure -# simulation are ignored when beginning the simulation at constant volume. -# This can be fixed. Read "run.in.nvt" for equilibration instructions.) - - - - - -# If you have compiled the MPI version of lammps, you can run lammps in parallel -#mpirun -np 4 lmp_mpi -i run.in.npt -#or -#mpirun -np 4 lmp_mpi -i run.in.nvt -# (assuming you have 4 processors available) diff --git a/tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/README_setup.sh b/tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/README_setup.sh deleted file mode 100755 index abf2fce64b..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/README_setup.sh +++ /dev/null @@ -1,28 +0,0 @@ -# Use these commands to generate the LAMMPS input script and data file -# (and other auxilliary files): - - -# Create LAMMPS input files this way: -cd moltemplate_files - - # run moltemplate - - moltemplate.sh system.lt - - # This will generate various files with names ending in *.in* and *.data. - # These files are the input files directly read by LAMMPS. Move them to - # the parent directory (or wherever you plan to run the simulation). - - mv -f system.in* system.data ../ - - # The "table_int.dat" file contains tabular data for the lipid INT-INT atom - # 1/r^2 interaction. We need it too. (This slows down the simulation by x2, - # so I might look for a way to get rid of it later.) - cp -f table_int.dat ../ - - # Optional: - # The "./output_ttree/" directory is full of temporary files generated by - # moltemplate. They can be useful for debugging, but are usually thrown away. - rm -rf output_ttree/ - -cd ../ diff --git a/tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/README_visualize.txt b/tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/README_visualize.txt deleted file mode 100644 index 019afc1444..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/README_visualize.txt +++ /dev/null @@ -1,87 +0,0 @@ - - ------- To view a lammps trajectory in VMD -------- - - -1) Build a PSF file for use in viewing with VMD. - -This step works with VMD 1.9 and topotools 1.2. -(Older versions, like VMD 1.8.6, don't support this.) - - -a) Start VMD -b) Menu Extensions->Tk Console -c) Enter: - -(I assume that the the DATA file is called "system.data") - - topo readlammpsdata system.data full - animate write psf system.psf - -2) - -Later, to Load a trajectory in VMD: - - Start VMD - Select menu: File->New Molecule - -Browse to select the PSF file you created above, and load it. - (Don't close the window yet.) - -Browse to select the trajectory file. - If necessary, for "file type" select: "LAMMPS Trajectory" - Load it. - - ---- A note on trajectory format: ----- -If the trajectory is a DUMP file, then make sure the it contains the -information you need for pbctools (see below. I've been using this -command in my LAMMPS scripts to create the trajectories: - - dump 1 all custom 5000 DUMP_FILE.lammpstrj id mol type x y z ix iy iz - -It's a good idea to use an atom_style which supports molecule-ID numbers -so that you can assign a molecule-ID number to each atom. (I think this -is needed to wrap atom coordinates without breaking molecules in half.) - -Of course, you don't have to save your trajectories in DUMP format, -(other formats like DCD work fine) I just mention dump files -because these are the files I'm familiar with. - -3) ----- Wrap the coordinates to the unit cell - (without cutting the molecules in half) - -a) Start VMD -b) Load the trajectory in VMD (see above) -c) Menu Extensions->Tk Console -d) Try entering these commands: - - pbc wrap -compound res -all - pbc box - - ----- Optional ---- - Sometimes the solvent or membrane obscures the view of the solute. - It can help to shift the location of the periodic boundary box - To shift the box in the y direction (for example) do this: - - pbc wrap -compound res -all -shiftcenterrel {0.0 0.15 0.0} - pbc box -shiftcenterrel {0.0 0.15 0.0} - - Distances are measured in units of box-length fractions, not Angstroms. - - Alternately if you have a solute whose atoms are all of type 1, - then you can also try this to center the box around it: - - pbc wrap -sel type=1 -all -centersel type=2 -center com - -4) - You should check if your periodic boundary conditions are too small. - To do that: - select Graphics->Representations menu option - click on the "Periodic" tab, and - click on the "+x", "-x", "+y", "-y", "+z", "-z" checkboxes. - -5) Optional: If you like, change the atom types in the PSF file so - that VMD recognizes the atom types, use something like: - -sed -e 's/ 1 1 / C C /g' < system.psf > temp1.psf -sed -e 's/ 2 2 / H H /g' < temp1.psf > temp2.psf -sed -e 's/ 3 3 / P P /g' < temp2.psf > system.psf - -(If you do this, it might effect step 2 above.) diff --git a/tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/images/DLPC.jpg b/tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/images/DLPC.jpg deleted file mode 100644 index 637f2f1c7a634d4585c1186247fc28c339acd25b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4915 zcmb7Hc{J2v_y3NujzQKI*l zjh%y&iw@b6(3HV`|Qo#USghy~0Fu<^5V2uPjf6g+jw+D%AU4fF81v_YZF zIh(+mw<7AcHv@`h4xL30Sr5toM|`NTA9}NK{9{()2Uu7@ENoyFj{mbbq~>R3V?QLm zBxwCm2qSz-&FyAk&Dy~@00n~%V+QjBdccUbTXf^z&$wULs60xgEy}#dhHpnBk zkn2yGk@Q@pC33w!(}`A6lpB%i>w5pzXOTD;b*1_<-*4rx9=-1P%h@8Jcx-dUU!lb( zg})`u{vv9K%c7tueH!x)dz4z{bj;GP7ffbE6!BPB`Q;YBy4J>EyHWK;L=7RAI2tCU z$FL;JP})dbCdax0Ne4iJYJX*XzeJQ0ZO^)^C36zx6wp0+Kk6a}$CO5RZXq>eimpsC zCefcd(ev)>+3t?nw?nfPc%5k`iL-%mYK+t?n0(w{j^*o_v`2~ezs{Wh4GJL&sSYz# z{@&FKeBoF&!l>#d{#;Gl=x#aDYN~vJpt3BiMSH*DDtmF?Z7YRfb1_4GQTbDY@95~n zHLDe+q*ktZ-jD-8!1AXob9sf`=<<#)SpG)Yv1RM|DV;_-x-XjfoOY(V@ujzm-FW;> z&Ltnqrgh$#MpSvb%UYyFRQv&O%ClkJf?oIiM1$IvVx%Z@Z7-trs9K^MT4cW1eLLiB;BiXwna*HEdX0cv_eP&-6?BM-q-LW@#F&Zqi6SZRAjcW}Qe{I$JC1B!5c%>rL%DmaO>mI}JKL(Fz)k+NcjYwm(gKO{;KnyJLzI@&V{P z+j~P~_!lWup=Jr&G==6k@z@w+8W#3-sK#0M?0d(-T{eCS67$)Cu;}HYYd0V<(`bLa zN(9r>QTCykxNB?hTU}*=Lwz8C>>qSVfu3XV0z>0_Rg>FDS8?ZWt->zc9Gzss7GHj- zw?vL+SG8x?+2o}*x=6`N23=1!?}Pl_jG8kE zLfq|#*o-3+xc09Rni_&E_-aip6$(5@9=xoICKXTyUj&=0|D15H=$w*EY`7aqPG;D} zDeS_Q6x+p|{KelDakOIcL=Wl@mgl3H*;&aS$or*PX_<`8 z)fZ_iSrfNryG#Rw^Z0VqMP}6H@vsbcJya};OafDiuZg!PyM{_kHEaw8DxDyEpUhHy zI0@fbP&UqLgCSdaWk<~8D_>azM3G`aO-f_G4ktu3@<^g+M0-6`E$Gz-T4Bk*Uk55<*cp$vDIrQo1yp13a*Fv zGC3 zGMQ9BSZeuxyld#|!HaEr;!sf+g!tv$Bszkpahl6o-#|+lIg1OEm9Tb9bH8xb8~yz5 zaw?_#Ls8JN;ALg5A7AA`CbxN?;qvx~k7CRb_ndt?)0WKO%Y|;{+nNs)mmqM*D+)$* zxj_5t*myrb7RzrGc55+Re*?7u;~>Ea*5U6)!tDrHECP#gV^h${3eHv5=JaIL-?Ky2!W3 z7u6sSUm2(hHmJ{_p#{ju}EQ(m_-bUXA9m(y3sM+&{oDQGEF{>I;tOzPvh(VaHq z$CSH*dDu*$T04qegxuhn5CT|NC%EkBtvj}5Vi4{2e$bS2`ym@1-Q22w9A7u1AcHT_^(>Be~@8!k^`e5=)4mzKe{{|Fv(!k{)_cH|yl$#Xt|RE;crE{oOS(c#ge7 zGpbT5OW00HTYr$>Dtn9V`=5uas}hI_OhQ}*Z-RxKC*@{sd;?4NYK+K1FkLPFzzL-D z@!m28-u$dPo~n3-W5-KHMqP^=)C*-wpgZbret%*{?_7Up8#=S(>nnC4o>FMIecm1T26HqQkc}g6l3F)kuqMRDg`WI28zsiNi=e=oa9s8B{c7=rp^1 z%~5$*ZEYkR?QrW;!prkNlE0IX<8Ps^Q|5iz&2yU zYwufLt_vJOD=!s(5DIhb@hrM*;YgsbFZq*}>u(d4$Oy zqC?Jz` z<}m-;n+i?8qSwOxCd#T9JS=}5Yw~G%zNT`n&S0L*b5!3@RRI~ zWi}nlB(6X2DMYBeZlA=S0X~Ffcu6<848^F7q3%_r(t@XgXZQ!r`yxV7BD@Azc0h7l z(&I+>Q2fmx2uV9rBd7YYj2k!W&H$n{1^=z#+9>ljZTR_sf;0j3$&p^}>fm%mrk}qF zMbf4kq3!|)fQT(%ax!E+RQ72!U$VEu#cTphzx~A4iBo;8^j>bH>8ss)`cc`_QlIrC zMKuqAp1t8M)Z?KD?uSM~j?sr*1e8pg5@r}AJ^#ANal_9m)}!xwta_vjkMDIyQPPRH zb4aMxxT?*^de`_Y|Jsi(_iMhELAs?j(vlvnaF!b@)0pP1@&0$>I`}~<54MT%@6(;_ zNIT7~1Q?tipvc0={PR0dFuhC*EHR0%*pkgs+H8WzRBQ`h;!WIZFN#>g%BOxm`X{MO|Gue_V$0nPM(l2)-osbEj zYtEim>0^~=DVg$FZSd~9qDB=n@4fH#gmtO*dUMeTA}6eo`fqz>0Ns5#=+F9Vc-Km7 zrK6YKW`9y#PwI@8BF0C-`fqQUvvJ8p34F-wRkDIm^+hb@OvEe1m$3L1?`7Tm1TCD> z1GE&p>+a>zJ}fY3B>BCG*W(G}8H|F{zLE2nyqb1SiA68S45 z!>6B%byAlqG{?IQGQg?EOh*k<-(yXG&)sghfa}kagCd;WAX01}I-mSK=d>O*j4r%JxaKks;U8y#upQDIt2u ziBG2_Ze0@#f}U>@w=zVRl=)b{F%j#I)!>Edl2okk#NOxF6wi!bHpfsM4xCJV&kc#STn0^l-rY4mFBWY2{66MM!KN%}Uoo4gyi3dz+Sj@cXI_^DZyOyCj| z%zxB=UFg5%by-|Ks5QsX2jA87y3r4nK%*ARvwF%o*lo1yZ&2!K!HVXlTZjwBjG4-& zxJ9ce6>5E5l-nH;efQFZ0%?YDSKYoNLx298uGr4NhV+G~*l%o6sf6SMz$aY~W8R`r z{a$7b2&P-O5*js%H_diwC9%!*{`{(y(096kP~ITK@sKD)xq*pQ#1~RSXyg{5&$$Kf|sz)?<{+R|uwFTo4;Z z;7(I3_ZcL!_1(O>n@=q9P@FdXxL$&fMAi-Yr?;r=1$iF&h6yU#E|~i0OER>%x$pGr z+$YGau}QVtuM+FQBAk|gD!TE!wGm)#B*bbuTf4Me;1*;s_mdk- z>Ce}^KVc?CW4{(=<=bF627n(e3^w61Sf}xVS%gujGOl?jju##(<*g|%O_ZdZ zZ?o=)nKFM?{EBAEfR_QGDl? z1O_`MIPZ3nHOF&n-b7q*6l;jd6357RD%w~ICB+ChriMaIsOM$^^>3SumhXiJ?u1k3 m;Jbk;gYo^`R^0u!0eA*DNiju|Ba(0~?q3P~YZHlsZ~p<(7Z8~M diff --git a/tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/images/DPPC+DLPC_bilayer32x37_t=0ps_LR.jpg b/tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/images/DPPC+DLPC_bilayer32x37_t=0ps_LR.jpg deleted file mode 100644 index 14f1a1ed2c5ff40707bf823b522455d4e064e2ee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 58412 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 diff --git a/tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/images/DPPC+DLPC_bilayer32x37_t=0ps_no_pbc_LR.jpg b/tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/images/DPPC+DLPC_bilayer32x37_t=0ps_no_pbc_LR.jpg deleted file mode 100644 index 757abe26849bf62e3e752fc42737a5f3b6fe63d2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 36618 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 MiYU>eMv5!{*?q4mh5!Hn diff --git a/tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/images/DPPC+DLPC_bilayer32x37_t=500ps_LR.jpg b/tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/images/DPPC+DLPC_bilayer32x37_t=500ps_LR.jpg deleted file mode 100644 index 2322449c1dcb8b54dc3a01ab3bd9dfdcee8e9795..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 62029 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 K4PN)(_x}YJQU+N7 diff --git a/tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/images/DPPC.jpg b/tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/images/DPPC.jpg deleted file mode 100644 index 57e093023d5f47f382fcb38514d18a64c2d6e593..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5834 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 Scd*HGm1L%c0xbAq=6?XmcDmaD diff --git a/tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/moltemplate_files/CGLipidBr2005Orig.lt b/tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/moltemplate_files/CGLipidBr2005Orig.lt deleted file mode 100644 index aabf2bcc8f..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/moltemplate_files/CGLipidBr2005Orig.lt +++ /dev/null @@ -1,208 +0,0 @@ -# Note: -# -# This example may require additional features to be added to LAMMPS. If -# LAMMPS complains about an "Invalid pair_style", then download copy the -# "additional_lammps_code" from moltemplate.org, unpack it into your LAMMPS -# "src" directory and recompile LAMMPS. -# -# -------- Description -------- -# -# This example contains an implementation of the DPPC lipid bilayer described in -# G. Brannigan, P.F. Philips, and F.L.H. Brown, -# Physical Review E, Vol 72, 011915 (2005) -# and: -# M.C. Watson, E.S. Penev, P.M. Welch, and F.L.H. Brown -# J. Chem. Phys. 135, 244701 (2011) -# -# As in Watson(JCP 2011), rigid bond-length constraints have been replaced -# by harmonic bonds. -# -# --- DLPC lipids --- -# A truncated version of the DPPC lipid (named "DLPC") has also been added. -# Unlike the original "DPPC" molecule model, "DLPC" has not been carefully -# parameterized to reproduce the correct behavior in a lipid bilayer/mixture. -# (You may need to stiffen the bond-angle forces to make it behave correctly, -# but I did not do this here.) -# -# Units: -# -# The "epsilon" parameter in their model is approximately 2.75 kJ/mole -# ( = 0.657265774378585 kCal/mole, using 1kCal=4.184kJ) -# The "sigma" parameter corresponds to 7.5 angstroms. -# -# -# The new DLPC model is a truncated version of DPPC, -# (Its behaviour has not been rigorously tested.) - - - -CGLipidBr2005 { - - - write_once("In Init") { - # -- Default styles for "CGLipidBr2005" -- - units real - atom_style full - # (Hybrid force field styles were used for portability.) - bond_style hybrid harmonic - - angle_style hybrid cosine/delta # <- used in the original article - #angle_style hybrid harmonic # <- prevents unphysical acute angle turns - # Explanation: - # angle_style cosine/delta: U(theta) = k*(1-cos(theta-theta0)) - # angle_style harmonic: U(theta) = k*(theta-theta0)^2 - - dihedral_style none - improper_style none - - pair_style hybrid table linear 1130 & - lj/charmm/coul/charmm/inter es4k4l 14.5 15 - - pair_modify mix arithmetic - special_bonds lj 0.0 0.0 1.0 # turn off pairs if "less than 3 bonds" - } - - - DPPC { - write("Data Atoms") { - $atom:h $mol:. @atom:head 0.0 0.00 0.00 33.75 # DPPC head atom - $atom:i $mol:. @atom:../int 0.0 -1.00 0.00 26.25 - $atom:t1 $mol:. @atom:../tail 0.0 1.00 0.00 18.75 - $atom:t2 $mol:. @atom:../tail 0.0 -1.00 0.00 11.25 - $atom:t3 $mol:. @atom:../tail 0.0 1.00 0.00 3.75 - } - write("Data Bonds") { - $bond:b1 @bond:../backbone $atom:h $atom:i - $bond:b2 @bond:../backbone $atom:i $atom:t1 - $bond:b3 @bond:../backbone $atom:t1 $atom:t2 - $bond:b4 @bond:../backbone $atom:t2 $atom:t3 - } - write("Data Angles") { - $angle:a1 @angle:../backbone $atom:h $atom:i $atom:t1 - $angle:a2 @angle:../backbone $atom:i $atom:t1 $atom:t2 - $angle:a3 @angle:../backbone $atom:t1 $atom:t2 $atom:t3 - } - - # Define properties of the local (lipid-specific) atom:head type atom: - write_once("Data Masses") { - @atom:head 200.0 - } - write_once("In Settings") { - pair_coeff @atom:head @atom:head lj/charmm/coul/charmm/inter 0.1643 7.5 0.4 0 - pair_coeff @atom:../int @atom:head lj/charmm/coul/charmm/inter 0.1643 7.5 0.4 0 - pair_coeff @atom:../tail @atom:head lj/charmm/coul/charmm/inter 0.1643 7.5 0.4 0 - } - - } #DPPC - - - DLPC { - write("Data Atoms") { - $atom:h $mol:. @atom:head 0.0 0.00 0.00 30.00 # DLPC head atom - $atom:i $mol:. @atom:../int 0.0 -1.00 0.00 22.50 - $atom:t1 $mol:. @atom:../tail 0.0 1.00 0.00 15.00 - $atom:t2 $mol:. @atom:../tail 0.0 -1.00 0.00 7.50 - } - write("Data Bonds") { - $bond:b1 @bond:../backbone $atom:h $atom:i - $bond:b2 @bond:../backbone $atom:i $atom:t1 - $bond:b3 @bond:../backbone $atom:t1 $atom:t2 - } - write("Data Angles") { - $angle:a1 @angle:../backbone $atom:h $atom:i $atom:t1 - $angle:a2 @angle:../backbone $atom:i $atom:t1 $atom:t2 - } - # Define properties of the local (lipid-specific) atom:head type atom: - write_once("Data Masses") { - @atom:head 200.0 - } - write_once("In Settings") { - pair_coeff @atom:head @atom:head lj/charmm/coul/charmm/inter 0.1643 7.5 0.4 0 - pair_coeff @atom:../int @atom:head lj/charmm/coul/charmm/inter 0.1643 7.5 0.4 0 - pair_coeff @atom:../tail @atom:head lj/charmm/coul/charmm/inter 0.1643 7.5 0.4 0 - } - } #DLPC - - - # Particles and properties shared by all lipid types: - - write_once("Data Masses") { - @atom:int 200.0 - @atom:tail 200.0 - } - - write_once("In Settings") { - # -- Default settings/parameters for "CGLipidBr2005" -- - # (Hybrid bond & angle styles were used for portability.) - - # As in Watson(JCP 2011), rigid bond-length constraints - # have been replaced by harmonic bonds. - # The k_theta parameter should lie in between 5*epsilon and 10*epsilon. - bond_coeff @bond:backbone harmonic 116.847 7.5 #<--2*5000*eps/sig^2 - } - - write_once("In Settings") { - - # cosine/delta: U(theta) = k*(1-cos(theta-theta0)) - angle_coeff @angle:backbone cosine/delta 4.60086042 180 #<-- 7*eps - - ## Alternately, to stiffen the bond-angles, try this: - ##angle_coeff @angle:backbone cosine/delta 6.57265774 180 #<-- 10*eps - ## harmonic: U(theta) = k*(theta-theta0)^2 not (k/2)*(theta-theta0)^2 - ##angle_coeff @angle:backbone harmonic 9.85898661 180 #<-->30*eps - } - # Note: You may want to use a stiffer bond-angle than the original - # Brannigan&Brown 2005 paper if you want to mix two different lipids together. - # (The mixture of lipids introduces a great deal of disorder into the bilayer - # which would not be present in a DPPC bilayer. This caused pores to form - # in my simulations. But increasing the angle stiffness prevents this.) - - write_once("In Settings") { - - # The interaction of "atom:int" with other "atom:int" atoms is given by - # epsilon*(0.4*(sigma/r)^12 - 3.0*(sigma/r)^2), shifted and cutoff at - # r=3*sigma. This was implemented using pair_style table. - # Unfortunately, mixing lj/charmm and "table" pair styles in the same - # simulation is very inneficient. - - pair_coeff @atom:int @atom:int table table_int.dat INT - - # The interaction of tail beads with eachother is given by the formula below - # and with other atoms ...using Lorenz-Berthelot and "repulsive wins" rules: - # epsilon*(0.4*(sigma/r)^12 - 1.0*(sigma/r)^6), - pair_coeff @atom:tail @atom:tail lj/charmm/coul/charmm/inter 0.1643 7.5 0.4 -1 - pair_coeff @atom:int @atom:tail lj/charmm/coul/charmm/inter 0.1643 7.5 0.4 -1 - - # The interaction between head beads from different types of lipids - # is (currently) repulsive: - pair_coeff @atom:DPPC/head @atom:DLPC/head lj/charmm/coul/charmm/inter 0.1643 7.5 0.4 0 - - } # write_once("In Settings") - - - # Note: I divided epsilon by 4 to get "0.1643" because we are using the - # "es4k4l" coeffstyle, corresponding to U(r)=eps(4*K*(s/r)^12 + 4*L*(s/r)^6) - # (The "es4k4l" coeffstyle is the default.) Using this convention makes it - # easier to mix this coarse-grained lipid model with other molecular models. - - - -} # CGLipidBr2005 - - - - - - - - -# Note: This example has not been optimized for speed. -# -# Unfortunately, using both lj/charmm and "table" pair styles in the same -# simulation seems to be very inneficient. (The simulation is twice as slow -# as using only the "lj/charmm" pair styles for every pairwise interaction, -# ...and about 25% slower than using "table" for every pairwise interaction. -# However the lennard-jones pair styles support mixing, so we use them to -# make it easier to run these molecules with other molecules which don't use -# pair_table. I felt that portability was worth the extra 25% slow down.) - diff --git a/tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/moltemplate_files/calc_table/calc_table.py b/tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/moltemplate_files/calc_table/calc_table.py deleted file mode 100755 index 0d09e4d02e..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/moltemplate_files/calc_table/calc_table.py +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env python - -# Calculate a table of pairwise energies and forces between "INT" atoms -# in the lipid membrane model described in -# Brannigan et al, Phys Rev E, 72, 011915 (2005) -# The energy of this interaction U(r) = eps*(0.4*(sigma/r)^12 - 3.0*(sigma/r)^2) -# However it is truncated at rc2 = 22.5 (shifted upwards to maintain continuity) - -def U(r, eps, sigma): - return eps* (0.4*pow((sigma/r),12) - 3.0*sigma*sigma/(r*r)) -def F(r, eps, sigma): - return eps*(12*0.4*pow((sigma/r),13)/sigma - 2*3.0*sigma*sigma/(r*r*r)) - -epsilon = 2.75/4.184 # kCal/mole -sigma = 7.5 -Rmin = 0.02 -Rmax = 22.6 -rcut = 22.5 -N = 1130 - -for i in range(0,N): - r = Rmin + i*(Rmax-Rmin)/(N-1) - U_r = U(r, epsilon, sigma) - U(rcut, epsilon, sigma) - F_r = F(r, epsilon, sigma) - if r > rcut: - U_r = 0.0 - F_r = 0.0 - print(str(i+1)+' '+str(r)+' '+str(U_r)+' '+str(F_r)) - diff --git a/tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/moltemplate_files/calc_table/version_charmm_cutoff/calc_table.py b/tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/moltemplate_files/calc_table/version_charmm_cutoff/calc_table.py deleted file mode 100755 index 32147e444a..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/moltemplate_files/calc_table/version_charmm_cutoff/calc_table.py +++ /dev/null @@ -1,70 +0,0 @@ -#!/usr/bin/env python - -# Calculate a table of pairwise energies and forces between "INT" atoms -# in the lipid membrane model described in -# Brannigan et al, Phys Rev E, 72, 011915 (2005) -# The energy of this interaction U(r) = eps*(0.4*(sigma/r)^12 - 3.0*(sigma/r)^2) -# I realized later this is not what we want because although energy is conserved -# all enrgies are shifted with respect to energies used in the Brannigan paper -# (by 0.27 kCal/mole) and the later Watson JCP 2011 paper (by 0.224 kCal/mole). -# (So don't use this.) - -# Calculate and print a - -def S(r, rc1, rc2, derivative=False): - """ - Calculate the switching function S(r) which decays continuously - between 1 and 0 in the range from rc1 to rc2 (rc2>rc1): - S(r) = (rc2^2 - r^2)^2 * (rc2^2 + 2*r^2 - 3*rc1^2) / (rc2^2-rc1^2)^3 - I'm using the same smoothing/switching cutoff function used by the CHARMM - force-fields. (I'm even using the same code to implement it, taken - from lammps charmm/coul/charmm pair style, rewritten in python.) - - """ - assert(rc2>rc1) - rsq = r*r - rc1sq = rc1*rc1 - rc2sq = rc2*rc2 - denom_lj_inv = (1.0 / ((rc2sq-rc1sq)* - (rc2sq-rc1sq)* - (rc2sq-rc1sq))) - if rsq > rc2sq: - return 0.0 - elif rsq < rc1sq: - if derivative: - return 0.0 - else: - return 1.0 - else: - rc2sq_minus_rsq = (rc2sq - rsq) - rc2sq_minus_rsq_sq = rc2sq_minus_rsq * rc2sq_minus_rsq - if derivative: - return (12.0 * rsq * rc2sq_minus_rsq * (rsq-rc1sq) * denom_lj_inv) - else: - return (rc2sq_minus_rsq_sq * - (rc2sq + 2.0*rsq - 3.0*rc1sq) * denom_lj_inv) - - -def U(r, eps, sigma): - return eps* (0.4*pow((sigma/r),12) - 3.0*sigma*sigma/(r*r)) - -def F(r, eps, sigma): - return eps*(12*0.4*pow((sigma/r),13)/sigma - 2*3.0*sigma*sigma/(r*r*r)) - -epsilon = 2.75/4.184 # kCal/mole -sigma = 7.5 -Rmin = 0.02 -Rmax = 22.6 -Rc1 = 22.0 -Rc2 = 22.5 -N = 1130 - -for i in range(0,N): - r = Rmin + i*(Rmax-Rmin)/(N-1) - U_r = U(r, epsilon, sigma) - F_r = F(r, epsilon, sigma) - # Multiply U(r) & F(r) by the smoothing/switch function - U_r = U_r * S(r, Rc1, Rc2) - F_r = U_r * S(r, Rc1, Rc2, True) + F_r * S(r, Rc1, Rc2, False) - print(str(i+1)+' '+str(r)+' '+str(U_r)+' '+str(F_r)) - diff --git a/tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/moltemplate_files/system.lt b/tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/moltemplate_files/system.lt deleted file mode 100644 index c556233c0d..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/moltemplate_files/system.lt +++ /dev/null @@ -1,94 +0,0 @@ -# Description: - -# This constructs a bilayer constructed from coarse-grained DPPC lipids -# (implicit solvent). The DPPC lipid model is described here: -# G. Brannigan, P.F. Philips, and F.L.H. Brown, -# Physical Review E, Vol 72, 011915 (2005) -# -# NOTE: There is an example of a 50%/50% DPPC & DLPC mixture -# in the "membrane+protein" and "vesicle" examples. - - - - - - -import "CGLipidBr2005Orig.lt" - -using namespace CGLipidBr2005 - -lipids = new DPPC [32].move(7.5, 0, 0) - [37].move(3.75, 6.49519, 0) - [2].rot(180, 1, 0, 0) - - -# Move the lipds up to the center of the box -lipids[*][*][*].move(0,0,75.0) - - -# Although this patch of lipids is not square or rectangular, (it looks -# like a parallelogram), this is no longer the case after rectangular -# periodic boundary conditions are applied. We apply them below: -# width: 240 = 32*7.5 -# height: 240.322 = 37*6.49519 - -write_once("Data Boundary") { - 0 240 xlo xhi - 0 240.322 ylo yhi - 0 150.0 zlo zhi -} - - - - - - - - -# -------------- File ends here. Only comments below.------------------- - -# ------------------------------------ -# ------------- COMMENTS: ------------ -# ------------------------------------ -# -# A note on geometry: -# We want to create a bilayer arranged in a hexagonal lattice consisting of -# 32 rows (each row is aligned with the x-axis) -# 37 columns (aligned at a 60 degree angle from the x axis) -# The lattice spacing is 8.0 Angstroms ( ~= 0.95*sigma*2^(1/6), where sigma=7.5) -# When wrapped onto a rectangular box, the dimensions of the system are: -# 32 * 7.5 Angstroms in the X direction -# 37 * 7.5*sqrt(3)/2 Angstroms in the Y direction -# ------------------------------------ -# -# Below I show simple ways to create a lipid bilayer: -# -# 1) If you just want to make lipid bilayer out of DPPC, -# without specifying the location of each lipid, you could use this syntax: -# lipids = new DPPC [32][37][2] # 3-D array -# Later you can load in the coordinates of the lipds from a PDB file. -# Alternately you could also use a 1-dimensional array: -# lipids = new DPPC [2368] # 1-D array. Note: 2368 = 32 x 37 x 2 -# It does not matter as long as the number of lipids is correct. -# Multidimensional arrays are only useful if you plan to apply independent -# coordinate transformations to each row and column and monolayer. See below: -# -# 2) Instead of loading a PDB file later, we can directly specify the location -# of each DPPC lipid in the LT file itself. For lipid bilayers, this is -# easy, because the bilayer structure resembles 2 planar lattices. -# We can use "move" commands to place each lipid, and the "rot" command -# to turn the lipids in one of the monolayers upside down. -# -# lipids = new DPPC [32].move(7.5, 0, 0) -# [37].move(3.75, 6.49519, 0) -# [2].rot(180, 1, 0, 0) -# -# 3) If you want to create a bilayer from a mixture of DPPC and DLPC, you must -# replace "DPPC" in the command above with random([DPPC,DLPC],[0.5,0.5],12345) -# Here "0.5,0.5" are the probabilities for each molecule type, and "12345" -# is an optional random seed. -# lipids = new random([DPPC,DLPC], [0.5,0.5], 12345) -# [32].move(7.5, 0, 0) -# [37].move(3.75, 6.49519, 0) -# [2].rot(180, 1, 0, 0) -# diff --git a/tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/moltemplate_files/table_int.dat b/tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/moltemplate_files/table_int.dat deleted file mode 100644 index b0d651d67f..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/moltemplate_files/table_int.dat +++ /dev/null @@ -1,1139 +0,0 @@ -# Table for the INT-INT interaction from -# Brannigan et al, Phys Rev E, 72, 011915 (2005) -# This table contains -# i r_i U(r_i) -dU/dr|r_i -# where U(r) = eps*(0.4*(sigma/r)^12 - 3.0*(sigma/r)^2) - -INT -N 1130 - -1 0.02 2.0331818401e+30 1.21990910406e+33 -2 0.04 4.9638228518e+26 1.48914685554e+29 -3 0.06 3.82579033251e+24 7.65158066501e+26 -4 0.08 1.21187081343e+23 1.81780622014e+25 -5 0.1 8.32791281704e+21 9.99349538045e+23 -6 0.12 9.34030842897e+20 9.34030842897e+22 -7 0.14 1.46892540453e+20 1.25907891817e+22 -8 0.16 2.95866897809e+19 2.21900173357e+21 -9 0.18 7.19889946863e+18 4.79926631242e+20 -10 0.2 2.0331818401e+18 1.21990910406e+20 -11 0.22 6.47834392264e+17 3.53364213962e+19 -12 0.24 2.28034873754e+17 1.14017436877e+19 -13 0.26 8.72681951932e+16 4.02776285507e+18 -14 0.28 3.58624366341e+16 1.53696157003e+18 -15 0.3 1.56704372019e+16 6.26817488078e+17 -16 0.32 7.2233129348e+15 2.70874235055e+17 -17 0.34 3.48970861422e+15 1.23166186384e+17 -18 0.36 1.75754381558e+15 5.85847938527e+16 -19 0.38 9.18613895646e+14 2.90088598625e+16 -20 0.4 4.96382285179e+14 1.48914685554e+16 -21 0.42 2.76404230108e+14 7.89726371739e+15 -22 0.44 1.58162693423e+14 4.31352800247e+15 -23 0.46 9.27773983256e+13 2.42027995633e+15 -24 0.48 5.56725765996e+13 1.391814415e+15 -25 0.5 3.41111308981e+13 8.18667141564e+14 -26 0.52 2.13057117167e+13 4.91670270393e+14 -27 0.54 1.35459994024e+13 3.0102220895e+14 -28 0.56 8.75547769351e+12 1.87617379153e+14 -29 0.58 5.74645813711e+12 1.18892237325e+14 -30 0.6 3.8257903322e+12 7.65158066491e+13 -31 0.62 2.58128463312e+12 4.99603477424e+13 -32 0.64 1.7635041342e+12 3.30657025205e+13 -33 0.66 1.21901470178e+12 2.21639036726e+13 -34 0.68 8.51979641904e+11 1.50349348607e+13 -35 0.7 6.0167184547e+11 1.0314374497e+13 -36 0.72 4.29087845387e+11 7.15146409276e+12 -37 0.74 3.08855637556e+11 5.00846980094e+12 -38 0.76 2.24270970425e+11 3.54112058818e+12 -39 0.78 1.64210505205e+11 2.52631546702e+12 -40 0.8 1.2118708117e+11 1.81780621971e+12 -41 0.82 90109367359.1 1.31867367068e+12 -42 0.84 67481501334.4 9.64021449503e+11 -43 0.86 50880896383.4 7.09965997788e+11 -44 0.88 38613938681.2 5.26553710913e+11 -45 0.9 29486692086.8 3.93155896009e+11 -46 0.92 22650731882.4 2.95444330322e+11 -47 0.94 17498544395.3 2.23385674464e+11 -48 0.96 13591937526.4 1.69899220331e+11 -49 0.98 10612635712.6 1.29950642555e+11 -50 1.0 8327912706.34 99934953582.6 -51 1.02 6566502316.69 77252969474.2 -52 1.04 5201589672.36 60018343356.8 -53 1.06 4138717434.11 46853405843.3 -54 1.08 3307128665.58 36745874940.0 -55 1.1 2653529579.27 28947596241.1 -56 1.12 2137567708.15 22902511945.9 -57 1.14 1728534024.3 18195095739.0 -58 1.16 1402943799.0 14513212422.1 -59 1.18 1142752163.37 11621209113.9 -60 1.2 934030766.093 9340308300.6 -61 1.22 765981286.774 7534242773.65 -62 1.24 630196371.787 6098675145.29 -63 1.26 520103253.414 4953364870.6 -64 1.28 430542934.103 4036340534.04 -65 1.3 357450462.101 3299543229.91 -66 1.32 297610947.802 2705554551.18 -67 1.34 248472587.186 2225128105.44 -68 1.36 208002782.573 1835319108.76 -69 1.38 174576985.011 1518061159.35 -70 1.4 146892484.084 1259078837.33 -71 1.42 123901294.937 1047053582.16 -72 1.44 104757721.536 872981382.419 -73 1.46 88777241.639 729676313.267 -74 1.48 75404158.02 611385405.387 -75 1.5 64186061.7033 513488820.507 -76 1.52 54753607.1486 432265633.695 -77 1.54 46804443.7318 364710253.134 -78 1.56 40090410.0598 308388060.159 -79 1.58 34407297.9713 261321529.95 -80 1.6 29586646.6744 221900119.2 -81 1.62 25489145.661 188808745.634 -82 1.64 21999316.2868 160970856.824 -83 1.66 19021212.5921 137502982.517 -84 1.68 16474936.8715 117678352.86 -85 1.7 14293808.3245 100897694.735 -86 1.72 12422056.6082 86665727.6626 -87 1.74 10812938.3788 74572197.8496 -88 1.76 9427195.57103 64276535.39 -89 1.78 8231790.46096 55495411.7777 -90 1.8 7198865.45512 47992625.088 -91 1.82 6304885.77339 41570857.9644 -92 1.84 5529931.32911 36064946.1544 -93 1.86 4857110.59557 31336368.341 -94 1.88 4272074.43377 27268725.7382 -95 1.9 3762612.01167 23764025.6584 -96 1.92 3318314.28383 20739619.609 -97 1.94 2930293.18879 18125675.4316 -98 1.96 2590946.89128 15863086.114 -99 1.98 2293763.15199 13901736.4186 -100 2.0 2033154.33079 12199063.3122 -101 2.02 1804318.68586 10718858.1296 -102 2.04 1603123.57305 9430268.02169 -103 2.06 1426006.91783 8306962.01537 -104 2.08 1269893.96121 7326433.30293 -105 2.1 1132126.79514 6469414.48445 -106 2.12 1010404.62602 5719386.63441 -107 2.14 902733.052344 5062166.44376 -108 2.16 807380.928986 4485558.44681 -109 2.18 722843.627253 3979061.59742 -110 2.2 647811.695319 3533621.30686 -111 2.22 581144.085827 3141419.57242 -112 2.24 521845.251959 2795697.07302 -113 2.26 469045.525153 2490602.13576 -114 2.28 421984.280794 2221062.32522 -115 2.3 379995.475978 1982675.10836 -116 2.32 342495.208369 1771614.62868 -117 2.34 308970.999537 1584552.10475 -118 2.36 278972.551763 1418587.76828 -119 2.38 252103.765513 1271192.59046 -120 2.4 228015.837009 1140158.32224 -121 2.42 206401.282366 1023554.60663 -122 2.44 186988.75765 919692.114521 -123 2.46 169538.563484 827090.818108 -124 2.48 153838.739168 744452.651831 -125 2.5 139701.665073 670637.92543 -126 2.52 126961.103835 604644.949624 -127 2.54 115469.620781 545592.416037 -128 2.56 105096.332511 492704.141327 -129 2.58 95724.9397832 445295.843157 -130 2.6 87252.0069441 402763.664479 -131 2.62 79585.4554502 364574.203947 -132 2.64 72643.2434671 330255.845328 -133 2.66 66352.2073932 299391.208536 -134 2.68 60647.0444312 271610.570248 -135 2.7 55469.4181565 246586.123584 -136 2.72 50767.1714483 224026.964698 -137 2.74 46493.633237 203674.709811 -138 2.76 42607.0073083 185299.659567 -139 2.78 39069.8329526 168697.439095 -140 2.8 35848.5085794 153686.051901 -141 2.82 32912.8705664 140103.294183 -142 2.84 30235.8206098 127804.483324 -143 2.86 27792.9956998 116660.460548 -144 2.88 25562.4755962 106555.833042 -145 2.9 23524.5233195 97387.4254387 -146 2.92 21661.3547409 89062.9145204 -147 2.94 19956.9338374 81499.6244039 -148 2.96 18396.7906059 74623.4624292 -149 2.98 16967.8589974 68367.9785194 -150 3.0 15658.3325568 62673.5329856 -151 3.02 14457.5357325 57486.5596649 -152 3.04 13355.809067 52758.912937 -153 3.06 12344.4066925 48447.2886046 -154 3.08 11415.4047444 44512.7098736 -155 3.1 10561.6194689 40920.0707567 -156 3.12 9776.5339459 37637.7301715 -157 3.14 9054.23247117 34637.1508274 -158 3.16 8389.34175838 31892.5777179 -159 3.18 7776.97821258 29380.7516608 -160 3.2 7212.7006167 27080.6538766 -161 3.22 6692.4676457 24973.2780793 -162 3.24 6212.59969004 23041.4269669 -163 3.26 5769.74452856 21269.5303734 -164 3.28 5360.84644195 19643.4826615 -165 3.3 4983.1184041 18150.4972204 -166 3.32 4634.01702836 16778.97618 -167 3.34 4311.21998136 15518.393672 -168 3.36 4012.60560869 14359.191159 -169 3.38 3736.23454428 13292.6835236 -170 3.4 3480.33310029 12310.9747549 -171 3.42 3243.27825585 11406.8822043 -172 3.44 3023.58408279 10573.8684961 -173 3.46 2819.88946345 9805.98028003 -174 3.48 2630.94697101 9097.79310596 -175 3.5 2455.61279669 8444.36177626 -176 3.52 2292.83761972 7841.17560602 -177 3.54 2141.65832756 7284.11808108 -178 3.56 2001.19050257 6769.43046025 -179 3.58 1870.62160083 6293.67891689 -180 3.6 1749.20475558 5853.72485855 -181 3.62 1636.25314534 5446.69810179 -182 3.64 1531.13487237 5069.97261409 -183 3.66 1433.26830277 4721.1445646 -184 3.68 1342.11782445 4398.01245332 -185 3.7 1257.18998347 4098.55911171 -186 3.72 1178.02996319 3820.93539003 -187 3.74 1104.21837425 3563.44536511 -188 3.76 1035.36832639 3324.53291993 -189 3.78 971.122756088 3102.76956138 -190 3.8 911.151986554 2896.84335615 -191 3.82 855.151498616 2705.54887715 -192 3.84 802.83989347 2527.77806329 -193 3.86 753.957029799 2362.51190574 -194 3.88 708.262319576 2208.81288195 -195 3.9 665.533168297 2065.81806693 -196 3.92 625.563546756 1932.73285812 -197 3.94 588.162682667 1808.82525631 -198 3.96 553.153861545 1693.42065104 -199 3.98 520.373327227 1585.89706361 -200 4.0 489.669273313 1485.68080556 -201 4.02 460.900917596 1392.24251449 -202 4.04 433.937652306 1305.09353282 -203 4.06 408.6582636 1223.78259822 -204 4.08 384.950214367 1147.89281764 -205 4.1 362.708984933 1077.03889938 -206 4.12 341.837466738 1010.86461999 -207 4.14 322.245404503 949.040505266 -208 4.16 303.848882793 891.261706073 -209 4.18 286.569853265 837.246052066 -210 4.2 270.33569919 786.732267446 -211 4.22 255.078834164 739.47833469 -212 4.24 240.736332164 695.259993326 -213 4.26 227.249586386 653.869362042 -214 4.28 214.563994495 615.113673492 -215 4.3 202.628668126 578.814112106 -216 4.32 191.396164684 544.804746089 -217 4.34 180.822239621 512.931545605 -218 4.36 170.865617553 483.051479815 -219 4.38 161.487780703 455.031686127 -220 4.4 152.652773286 428.748705595 -221 4.42 144.327020575 404.087778912 -222 4.44 136.479161479 380.942197972 -223 4.46 129.07989358 359.212708377 -224 4.48 122.101829632 338.806958688 -225 4.5 115.519364658 319.638992577 -226 4.52 109.308552789 301.628780369 -227 4.54 103.446993117 284.701786758 -228 4.56 97.9137238447 268.788571763 -229 4.58 92.6891241175 253.824422244 -230 4.6 87.7548229339 239.749011508 -231 4.62 83.0936146036 226.506084761 -232 4.64 78.6893802546 214.043168343 -233 4.66 74.5270149351 202.31130085 -234 4.68 70.5923598871 191.264784422 -235 4.7 66.8721396072 180.860954593 -236 4.72 63.353903336 171.05996726 -237 4.74 60.0259706488 161.824601429 -238 4.76 56.8773808439 153.120076496 -239 4.78 53.8978458491 144.913882966 -240 4.8 51.0777063884 137.175625538 -241 4.82 48.4078911713 129.876877635 -242 4.84 45.8798788842 122.991046476 -243 4.86 43.485662782 116.493247913 -244 4.88 41.2177176913 110.360190267 -245 4.9 39.0689692529 104.570066494 -246 4.92 37.0327652428 99.1024540566 -247 4.94 35.102848823 93.9382219092 -248 4.96 33.2733335874 89.05944408 -249 4.98 31.5386802724 84.4493193479 -250 5.0 29.8936750183 80.0920965658 -251 5.02 28.3334090704 75.9730052143 -252 5.04 26.8532598202 72.0781907976 -253 5.06 25.4488730938 68.3946547294 -254 5.08 24.116146599 64.9101983786 -255 5.1 22.8512144543 61.6133709734 -256 5.12 21.650432722 58.4934210835 -257 5.14 20.5103658787 55.5402514226 -258 5.16 19.4277741591 52.7443767307 -259 5.18 18.3996017121 50.0968845179 -260 5.2 17.4229655155 47.5893984632 -261 5.22 16.4951449988 45.2140442802 -262 5.24 15.6135723236 42.9634178757 -263 5.26 14.775823281 40.8305556374 -264 5.28 13.979608762 38.808906703 -265 5.3 13.2227667648 36.8923070701 -266 5.32 12.5032549016 35.0749554196 -267 5.34 11.8191433738 33.3513905323 -268 5.36 11.1686083831 31.7164701895 -269 5.38 10.5499259512 30.1653514539 -270 5.4 9.96146612005 28.693472236 -271 5.42 9.40168750976 27.2965340593 -272 5.44 8.86913220892 25.9704859397 -273 5.46 8.36242097742 24.7115093061 -274 5.48 7.88024874079 23.5160038893 -275 5.5 7.4213803577 22.3805745153 -276 5.52 6.98464664308 21.3020187412 -277 5.54 6.56894063048 20.2773152771 -278 5.56 6.1732140587 19.3036131423 -279 5.58 5.79647406826 18.3782215059 -280 5.6 5.43778009463 17.4986001669 -281 5.62 5.09624094585 16.6623506308 -282 5.64 4.77101205293 15.867207745 -283 5.66 4.46129288233 15.1110318537 -284 5.68 4.16632450031 14.3918014404 -285 5.7 3.88538727999 13.7076062261 -286 5.72 3.61779874199 13.0566406912 -287 5.74 3.36291152072 12.4371979973 -288 5.76 3.12011144838 11.8476642796 -289 5.78 2.8888157497 11.2865132882 -290 5.8 2.66847134042 10.7523013555 -291 5.82 2.45855322349 10.2436626676 -292 5.84 2.25856297681 9.7593048226 -293 5.86 2.06802732724 9.2980046552 -294 5.88 1.88649680546 8.85860431242 -295 5.9 1.71354447704 8.44000756375 -296 5.92 1.548764745 8.04117633127 -297 5.94 1.39177221978 7.66112742597 -298 5.96 1.24220065245 7.29892947717 -299 5.98 1.09970192753 6.9537000433 -300 6.0 0.963945111861 6.62460289254 -301 6.02 0.83461555631 6.31084544295 -302 6.04 0.711414047074 6.01167635216 -303 6.06 0.594056003831 5.72638324756 -304 6.08 0.482270721937 5.45429058822 -305 6.1 0.375800656137 5.19475765055 -306 6.12 0.274400743381 4.94717663025 -307 6.14 0.177837762511 4.71097085338 -308 6.16 0.0858897286772 4.48559308998 -309 6.18 -0.00165467948361 4.27052396409 -310 6.2 -0.0849966617872 4.06527045435 -311 6.22 -0.164327809314 3.8693644797 -312 6.24 -0.239830589745 3.68236156522 -313 6.26 -0.311678806773 3.50383958321 -314 6.28 -0.380038035049 3.33339756513 -315 6.3 -0.445066032049 3.17065458013 -316 6.32 -0.506913128135 3.0152486763 -317 6.34 -0.56572259604 2.866835881 -318 6.36 -0.621631000928 2.72508925658 -319 6.38 -0.674768532081 2.58969800863 -320 6.4 -0.725259317268 2.46036664323 -321 6.42 -0.773221720709 2.33681417085 -322 6.44 -0.818768625574 2.21877335375 -323 6.46 -0.862007701832 2.10598999469 -324 6.48 -0.90304166028 1.99822226439 -325 6.5 -0.941968493479 1.8952400656 -326 6.52 -0.978881704324 1.79682443166 -327 6.54 -1.01387052292 1.70276695755 -328 6.56 -1.04702011237 1.61286926168 -329 6.58 -1.07841176412 1.52694247655 -330 6.6 -1.10812308336 1.44480676668 -331 6.62 -1.13622816508 1.36629087245 -332 6.64 -1.1627977612 1.29123167801 -333 6.66 -1.18789943936 1.21947380239 -334 6.68 -1.21159773365 1.15086921208 -335 6.7 -1.23395428792 1.08527685416 -336 6.72 -1.25502799183 1.02256230873 -337 6.74 -1.27487511024 0.962597459596 -338 6.76 -1.2935494061 0.90526018218 -339 6.78 -1.31110225728 0.850434047748 -340 6.8 -1.32758276773 0.798008043011 -341 6.82 -1.34303787302 0.747876304295 -342 6.84 -1.35751244086 0.699937865467 -343 6.86 -1.3710493666 0.654096418865 -344 6.88 -1.38368966412 0.610260088543 -345 6.9 -1.3954725523 0.568341215144 -346 6.92 -1.40643553728 0.528256151786 -347 6.94 -1.41661449078 0.489925070364 -348 6.96 -1.42604372459 0.453271777711 -349 6.98 -1.43475606153 0.418223541087 -350 7.0 -1.44278290299 0.384710922497 -351 7.02 -1.45015429321 0.352667621378 -352 7.04 -1.45689898057 0.322030325194 -353 7.06 -1.46304447588 0.292738567537 -354 7.08 -1.46861710792 0.264734593325 -355 7.1 -1.47364207647 0.237963230734 -356 7.12 -1.47814350264 0.2123717695 -357 7.14 -1.482144477 0.187909845266 -358 7.16 -1.48566710537 0.16452932965 -359 7.18 -1.48873255248 0.142184225751 -360 7.2 -1.49136108362 0.120830568787 -361 7.22 -1.49357210429 0.100426331626 -362 7.24 -1.49538419809 0.0809313349308 -363 7.26 -1.4968151628 0.0623071617066 -364 7.28 -1.49788204479 0.044517076001 -365 7.3 -1.49860117187 0.0275259455594 -366 7.32 -1.49898818464 0.0113001682279 -367 7.34 -1.49905806636 -0.00419239808778 -368 7.36 -1.4988251715 -0.0189825020854 -369 7.38 -1.49830325295 -0.0330995625254 -370 7.4 -1.49750548803 -0.0465717286462 -371 7.42 -1.49644450327 -0.0594259376903 -372 7.44 -1.49513239812 -0.0716879696855 -373 7.46 -1.49358076759 -0.0833824996199 -374 7.48 -1.4918007238 -0.0945331471409 -375 7.5 -1.48980291663 -0.105162523901 -376 7.52 -1.48759755345 -0.115292278666 -377 7.54 -1.48519441791 -0.124943140307 -378 7.56 -1.48260288794 -0.13413495876 -379 7.58 -1.47983195293 -0.142886744076 -380 7.6 -1.47689023018 -0.151216703644 -381 7.62 -1.47378598053 -0.159142277674 -382 7.64 -1.47052712344 -0.166680173038 -383 7.66 -1.46712125128 -0.173846395532 -384 7.68 -1.46357564306 -0.180656280652 -385 7.7 -1.45989727753 -0.187124522948 -386 7.72 -1.45609284575 -0.193265204023 -387 7.74 -1.45216876302 -0.199091819249 -388 7.76 -1.4481311804 -0.204617303261 -389 7.78 -1.44398599566 -0.20985405428 -390 7.8 -1.43973886378 -0.214813957332 -391 7.82 -1.43539520696 -0.21950840641 -392 7.84 -1.43096022428 -0.223948325627 -393 7.86 -1.42643890087 -0.228144189416 -394 7.88 -1.42183601669 -0.232106041819 -395 7.9 -1.41715615498 -0.235843514899 -396 7.92 -1.41240371029 -0.239365846333 -397 7.94 -1.40758289625 -0.242681896213 -398 7.96 -1.40269775292 -0.245800163096 -399 7.98 -1.39775215386 -0.248728799339 -400 8.0 -1.39274981294 -0.251475625745 -401 8.02 -1.38769429081 -0.254048145572 -402 8.04 -1.3825890011 -0.256453557906 -403 8.06 -1.37743721643 -0.258698770453 -404 8.08 -1.37224207403 -0.260790411767 -405 8.1 -1.3670065813 -0.262734842931 -406 8.12 -1.36173362096 -0.264538168734 -407 8.14 -1.35642595614 -0.26620624836 -408 8.16 -1.35108623513 -0.267744705599 -409 8.18 -1.34571699603 -0.269158938625 -410 8.2 -1.34032067115 -0.270454129338 -411 8.22 -1.33489959126 -0.271635252315 -412 8.24 -1.32945598963 -0.272707083354 -413 8.26 -1.32399200593 -0.273674207668 -414 8.28 -1.31850968998 -0.274541027712 -415 8.3 -1.3130110053 -0.275311770682 -416 8.32 -1.30749783257 -0.275990495686 -417 8.34 -1.30197197291 -0.276581100614 -418 8.36 -1.29643515102 -0.277087328708 -419 8.38 -1.29088901827 -0.277512774857 -420 8.4 -1.28533515553 -0.277860891625 -421 8.42 -1.279775076 -0.278134995017 -422 8.44 -1.27421022789 -0.278338270004 -423 8.46 -1.26864199697 -0.27847377582 -424 8.48 -1.26307170904 -0.278544451025 -425 8.5 -1.25750063229 -0.278553118366 -426 8.52 -1.25192997959 -0.278502489422 -427 8.54 -1.24636091063 -0.27839516907 -428 8.56 -1.24079453406 -0.278233659745 -429 8.58 -1.23523190945 -0.27802036554 -430 8.6 -1.22967404925 -0.277757596126 -431 8.62 -1.22412192063 -0.277447570509 -432 8.64 -1.21857644724 -0.277092420635 -433 8.66 -1.21303851096 -0.276694194842 -434 8.68 -1.20750895348 -0.276254861174 -435 8.7 -1.20198857794 -0.275776310556 -436 8.72 -1.19647815038 -0.275260359835 -437 8.74 -1.19097840123 -0.274708754702 -438 8.76 -1.18549002669 -0.274123172492 -439 8.78 -1.18001369009 -0.273505224869 -440 8.8 -1.17455002313 -0.272856460401 -441 8.82 -1.16909962718 -0.272178367032 -442 8.84 -1.16366307443 -0.271472374453 -443 8.86 -1.15824090903 -0.270739856375 -444 8.88 -1.1528336482 -0.269982132713 -445 8.9 -1.14744178329 -0.269200471678 -446 8.92 -1.14206578078 -0.26839609179 -447 8.94 -1.13670608326 -0.267570163805 -448 8.96 -1.13136311038 -0.266723812565 -449 8.98 -1.1260372597 -0.26585811878 -450 9.0 -1.12072890764 -0.264974120729 -451 9.02 -1.11543841024 -0.2640728159 -452 9.04 -1.11016610399 -0.263155162565 -453 9.06 -1.10491230659 -0.262222081284 -454 9.08 -1.09967731769 -0.261274456364 -455 9.1 -1.09446141962 -0.260313137244 -456 9.12 -1.08926487805 -0.259338939836 -457 9.14 -1.08408794265 -0.258352647809 -458 9.16 -1.07893084774 -0.257355013824 -459 9.18 -1.07379381288 -0.256346760718 -460 9.2 -1.06867704347 -0.255328582644 -461 9.22 -1.06358073129 -0.254301146164 -462 9.24 -1.05850505508 -0.253265091305 -463 9.26 -1.053450181 -0.252221032561 -464 9.28 -1.04841626319 -0.251169559871 -465 9.3 -1.04340344425 -0.25011123955 -466 9.32 -1.03841185563 -0.249046615186 -467 9.34 -1.03344161818 -0.2479762085 -468 9.36 -1.0284928425 -0.246900520178 -469 9.38 -1.02356562938 -0.245820030663 -470 9.4 -1.0186600702 -0.244735200927 -471 9.42 -1.01377624733 -0.243646473201 -472 9.44 -1.00891423443 -0.242554271687 -473 9.46 -1.0040740969 -0.241459003238 -474 9.48 -0.999255892143 -0.240361058009 -475 9.5 -0.994459669928 -0.239260810093 -476 9.52 -0.989685472697 -0.238158618121 -477 9.54 -0.984933335869 -0.237054825845 -478 9.56 -0.980203288132 -0.235949762702 -479 9.58 -0.975495351726 -0.234843744346 -480 9.6 -0.970809542708 -0.233737073173 -481 9.62 -0.966145871217 -0.232630038816 -482 9.64 -0.961504341725 -0.231522918625 -483 9.66 -0.956884953272 -0.230415978128 -484 9.68 -0.952287699705 -0.229309471477 -485 9.7 -0.947712569897 -0.228203641873 -486 9.72 -0.943159547963 -0.22709872198 -487 9.74 -0.938628613467 -0.225994934317 -488 9.76 -0.934119741622 -0.224892491642 -489 9.78 -0.929632903477 -0.223791597316 -490 9.8 -0.925168066109 -0.222692445658 -491 9.82 -0.920725192794 -0.221595222284 -492 9.84 -0.916304243179 -0.220500104432 -493 9.86 -0.91190517345 -0.219407261278 -494 9.88 -0.907527936486 -0.218316854241 -495 9.9 -0.903172482012 -0.217229037271 -496 9.92 -0.898838756748 -0.216143957132 -497 9.94 -0.894526704547 -0.215061753669 -498 9.96 -0.890236266534 -0.213982560076 -499 9.98 -0.885967381232 -0.212906503136 -500 10.0 -0.881719984692 -0.211833703472 -501 10.02 -0.877494010612 -0.210764275774 -502 10.04 -0.873289390453 -0.209698329022 -503 10.06 -0.869106053554 -0.208635966708 -504 10.08 -0.864943927233 -0.207577287034 -505 10.1 -0.860802936899 -0.206522383122 -506 10.12 -0.856683006147 -0.205471343199 -507 10.14 -0.852584056854 -0.204424250786 -508 10.16 -0.848506009271 -0.203381184875 -509 10.18 -0.844448782117 -0.202342220105 -510 10.2 -0.840412292656 -0.201307426921 -511 10.22 -0.836396456786 -0.20027687174 -512 10.24 -0.832401189115 -0.199250617102 -513 10.26 -0.828426403039 -0.19822872182 -514 10.28 -0.824472010811 -0.197211241119 -515 10.3 -0.820537923617 -0.196198226777 -516 10.32 -0.81662405164 -0.195189727259 -517 10.34 -0.812730304126 -0.19418578784 -518 10.36 -0.808856589444 -0.193186450732 -519 10.38 -0.805002815152 -0.1921917552 -520 10.4 -0.801168888049 -0.191201737679 -521 10.42 -0.797354714233 -0.190216431881 -522 10.44 -0.793560199154 -0.189235868906 -523 10.46 -0.789785247667 -0.188260077336 -524 10.48 -0.786029764076 -0.187289083343 -525 10.5 -0.782293652189 -0.186322910778 -526 10.52 -0.778576815358 -0.185361581264 -527 10.54 -0.774879156522 -0.184405114284 -528 10.56 -0.771200578253 -0.183453527268 -529 10.58 -0.767540982794 -0.182506835671 -530 10.6 -0.763900272099 -0.181565053055 -531 10.62 -0.760278347867 -0.180628191165 -532 10.64 -0.75667511158 -0.179696260001 -533 10.66 -0.753090464539 -0.17876926789 -534 10.68 -0.749524307893 -0.177847221551 -535 10.7 -0.745976542671 -0.176930126167 -536 10.72 -0.742447069815 -0.176017985441 -537 10.74 -0.738935790206 -0.175110801662 -538 10.76 -0.735442604695 -0.174208575761 -539 10.78 -0.731967414126 -0.173311307369 -540 10.8 -0.728510119361 -0.172418994873 -541 10.82 -0.72507062131 -0.171531635464 -542 10.84 -0.721648820948 -0.170649225192 -543 10.86 -0.718244619341 -0.169771759015 -544 10.88 -0.714857917667 -0.168899230842 -545 10.9 -0.711488617235 -0.168031633581 -546 10.92 -0.708136619505 -0.167168959186 -547 10.94 -0.704801826108 -0.166311198692 -548 10.96 -0.701484138863 -0.165458342262 -549 10.98 -0.698183459794 -0.164610379221 -550 11.0 -0.694899691148 -0.1637672981 -551 11.02 -0.691632735406 -0.162929086665 -552 11.04 -0.688382495303 -0.162095731957 -553 11.06 -0.68514887384 -0.161267220326 -554 11.08 -0.681931774298 -0.160443537459 -555 11.1 -0.678731100249 -0.159624668416 -556 11.12 -0.675546755573 -0.15881059766 -557 11.14 -0.672378644462 -0.15800130908 -558 11.16 -0.669226671439 -0.157196786028 -559 11.18 -0.666090741365 -0.156397011339 -560 11.2 -0.662970759447 -0.155601967361 -561 11.22 -0.659866631253 -0.154811635976 -562 11.24 -0.656778262715 -0.154025998629 -563 11.26 -0.653705560141 -0.153245036348 -564 11.28 -0.650648430223 -0.152468729768 -565 11.3 -0.647606780043 -0.15169705915 -566 11.32 -0.644580517084 -0.150930004405 -567 11.34 -0.641569549231 -0.150167545112 -568 11.36 -0.638573784781 -0.149409660536 -569 11.38 -0.635593132451 -0.148656329652 -570 11.4 -0.632627501379 -0.147907531156 -571 11.42 -0.629676801133 -0.147163243484 -572 11.44 -0.626740941713 -0.146423444834 -573 11.46 -0.62381983356 -0.145688113174 -574 11.48 -0.620913387554 -0.144957226261 -575 11.5 -0.618021515027 -0.144230761656 -576 11.52 -0.615144127757 -0.143508696739 -577 11.54 -0.612281137978 -0.14279100872 -578 11.56 -0.609432458382 -0.142077674653 -579 11.58 -0.606598002119 -0.141368671449 -580 11.6 -0.603777682806 -0.140663975889 -581 11.62 -0.600971414522 -0.139963564633 -582 11.64 -0.598179111815 -0.139267414235 -583 11.66 -0.595400689704 -0.138575501149 -584 11.68 -0.592636063678 -0.137887801745 -585 11.7 -0.589885149701 -0.137204292313 -586 11.72 -0.587147864211 -0.136524949077 -587 11.74 -0.584424124122 -0.135849748201 -588 11.76 -0.581713846826 -0.135178665802 -589 11.78 -0.579016950193 -0.134511677954 -590 11.8 -0.576333352571 -0.133848760697 -591 11.82 -0.573662972788 -0.133189890048 -592 11.84 -0.571005730151 -0.132535042004 -593 11.86 -0.56836154445 -0.131884192552 -594 11.88 -0.565730335952 -0.131237317677 -595 11.9 -0.563112025406 -0.130594393364 -596 11.92 -0.560506534041 -0.129955395608 -597 11.94 -0.557913783565 -0.129320300421 -598 11.96 -0.555333696166 -0.128689083832 -599 11.98 -0.552766194514 -0.1280617219 -600 12.0 -0.550211201752 -0.127438190715 -601 12.02 -0.547668641506 -0.126818466403 -602 12.04 -0.545138437876 -0.126202525133 -603 12.06 -0.542620515439 -0.125590343118 -604 12.08 -0.540114799247 -0.124981896625 -605 12.1 -0.537621214828 -0.124377161973 -606 12.12 -0.53513968818 -0.123776115544 -607 12.14 -0.532670145775 -0.123178733779 -608 12.16 -0.530212514555 -0.122584993188 -609 12.18 -0.52776672193 -0.121994870352 -610 12.2 -0.525332695778 -0.121408341923 -611 12.22 -0.522910364445 -0.120825384632 -612 12.24 -0.52049965674 -0.120245975289 -613 12.26 -0.518100501935 -0.119670090788 -614 12.28 -0.515712829763 -0.119097708107 -615 12.3 -0.513336570418 -0.118528804313 -616 12.32 -0.51097165455 -0.117963356563 -617 12.34 -0.508618013267 -0.11740134211 -618 12.36 -0.506275578128 -0.116842738298 -619 12.38 -0.503944281147 -0.116287522571 -620 12.4 -0.501624054788 -0.115735672472 -621 12.42 -0.49931483196 -0.115187165645 -622 12.44 -0.497016546022 -0.114641979838 -623 12.46 -0.494729130774 -0.114100092904 -624 12.48 -0.49245252046 -0.1135614828 -625 12.5 -0.490186649763 -0.113026127594 -626 12.52 -0.487931453803 -0.112494005462 -627 12.54 -0.485686868135 -0.11196509469 -628 12.56 -0.48345282875 -0.111439373678 -629 12.58 -0.481229272066 -0.110916820936 -630 12.6 -0.479016134933 -0.110397415091 -631 12.62 -0.476813354625 -0.109881134884 -632 12.64 -0.474620868841 -0.109367959171 -633 12.66 -0.472438615702 -0.108857866928 -634 12.68 -0.470266533747 -0.108350837244 -635 12.7 -0.468104561934 -0.107846849332 -636 12.72 -0.465952639633 -0.107345882519 -637 12.74 -0.463810706629 -0.106847916255 -638 12.76 -0.461678703116 -0.106352930108 -639 12.78 -0.459556569693 -0.105860903769 -640 12.8 -0.457444247367 -0.105371817049 -641 12.82 -0.455341677547 -0.10488564988 -642 12.84 -0.453248802042 -0.104402382317 -643 12.86 -0.451165563056 -0.103921994536 -644 12.88 -0.449091903193 -0.103444466836 -645 12.9 -0.447027765446 -0.102969779639 -646 12.92 -0.4449730932 -0.102497913489 -647 12.94 -0.442927830229 -0.102028849053 -648 12.96 -0.440891920688 -0.101562567122 -649 12.98 -0.438865309121 -0.101099048608 -650 13.0 -0.436847940448 -0.100638274548 -651 13.02 -0.434839759968 -0.100180226101 -652 13.04 -0.432840713358 -0.0997248845489 -653 13.06 -0.430850746664 -0.0992722312959 -654 13.08 -0.428869806307 -0.0988222478696 -655 13.1 -0.426897839073 -0.0983749159199 -656 13.12 -0.424934792115 -0.0979302172191 -657 13.14 -0.42298061295 -0.0974881336614 -658 13.16 -0.421035249454 -0.097048647263 -659 13.18 -0.419098649864 -0.0966117401617 -660 13.2 -0.417170762771 -0.0961773946166 -661 13.22 -0.41525153712 -0.0957455930079 -662 13.24 -0.413340922208 -0.0953163178365 -663 13.26 -0.411438867679 -0.0948895517235 -664 13.28 -0.409545323527 -0.0944652774101 -665 13.3 -0.407660240085 -0.0940434777572 -666 13.32 -0.405783568032 -0.0936241357448 -667 13.34 -0.403915258384 -0.0932072344716 -668 13.36 -0.402055262494 -0.0927927571548 -669 13.38 -0.400203532049 -0.0923806871294 -670 13.4 -0.39836001907 -0.091971007848 -671 13.42 -0.396524675907 -0.0915637028799 -672 13.44 -0.394697455235 -0.0911587559112 -673 13.46 -0.392878310058 -0.0907561507435 -674 13.48 -0.391067193701 -0.0903558712944 -675 13.5 -0.389264059808 -0.0899579015961 -676 13.52 -0.387468862344 -0.0895622257951 -677 13.54 -0.385681555589 -0.089168828152 -678 13.56 -0.383902094135 -0.0887776930406 -679 13.58 -0.382130432887 -0.0883888049474 -680 13.6 -0.380366527059 -0.088002148471 -681 13.62 -0.378610332173 -0.0876177083216 -682 13.64 -0.376861804052 -0.0872354693205 -683 13.66 -0.375120898826 -0.0868554163993 -684 13.68 -0.373387572922 -0.0864775345994 -685 13.7 -0.371661783067 -0.0861018090713 -686 13.72 -0.369943486282 -0.0857282250742 -687 13.74 -0.368232639885 -0.0853567679751 -688 13.76 -0.366529201481 -0.0849874232486 -689 13.78 -0.364833128968 -0.0846201764757 -690 13.8 -0.363144380531 -0.0842550133436 -691 13.82 -0.361462914638 -0.083891919645 -692 13.84 -0.359788690043 -0.0835308812773 -693 13.86 -0.358121665778 -0.0831718842421 -694 13.88 -0.356461801157 -0.0828149146446 -695 13.9 -0.354809055768 -0.0824599586927 -696 13.92 -0.353163389476 -0.0821070026966 -697 13.94 -0.351524762418 -0.0817560330682 -698 13.96 -0.349893135001 -0.0814070363201 -699 13.98 -0.348268467902 -0.0810599990654 -700 14.0 -0.346650722064 -0.0807149080166 -701 14.02 -0.345039858694 -0.0803717499853 -702 14.04 -0.343435839265 -0.0800305118814 -703 14.06 -0.341838625506 -0.0796911807123 -704 14.08 -0.340248179409 -0.0793537435825 -705 14.1 -0.338664463221 -0.079018187693 -706 14.12 -0.337087439445 -0.0786845003402 -707 14.14 -0.335517070835 -0.0783526689157 -708 14.16 -0.333953320399 -0.0780226809053 -709 14.18 -0.332396151392 -0.0776945238888 -710 14.2 -0.330845527319 -0.0773681855387 -711 14.22 -0.329301411928 -0.0770436536203 -712 14.24 -0.327763769212 -0.0767209159903 -713 14.26 -0.326232563407 -0.0763999605967 -714 14.28 -0.324707758986 -0.076080775478 -715 14.3 -0.323189320665 -0.0757633487623 -716 14.32 -0.321677213392 -0.075447668667 -717 14.34 -0.320171402352 -0.0751337234981 -718 14.36 -0.318671852963 -0.0748215016493 -719 14.38 -0.317178530874 -0.0745109916017 -720 14.4 -0.315691401963 -0.0742021819228 -721 14.42 -0.314210432337 -0.0738950612663 -722 14.44 -0.312735588328 -0.073589618371 -723 14.46 -0.311266836492 -0.0732858420606 -724 14.48 -0.309804143609 -0.0729837212427 -725 14.5 -0.308347476679 -0.0726832449085 -726 14.52 -0.306896802922 -0.0723844021319 -727 14.54 -0.305452089775 -0.072087182069 -728 14.56 -0.304013304893 -0.0717915739575 -729 14.58 -0.302580416142 -0.0714975671162 -730 14.6 -0.301153391604 -0.071205150944 -731 14.62 -0.29973219957 -0.0709143149198 -732 14.64 -0.298316808542 -0.0706250486013 -733 14.66 -0.29690718723 -0.0703373416252 -734 14.68 -0.29550330455 -0.0700511837056 -735 14.7 -0.294105129623 -0.0697665646344 -736 14.72 -0.292712631773 -0.06948347428 -737 14.74 -0.291325780527 -0.069201902587 -738 14.76 -0.289944545612 -0.0689218395755 -739 14.78 -0.288568896953 -0.0686432753407 -740 14.8 -0.287198804672 -0.068366200052 -741 14.82 -0.285834239089 -0.0680906039529 -742 14.84 -0.284475170717 -0.0678164773599 -743 14.86 -0.283121570262 -0.0675438106623 -744 14.88 -0.281773408622 -0.0672725943215 -745 14.9 -0.280430656883 -0.0670028188703 -746 14.92 -0.279093286324 -0.0667344749127 -747 14.94 -0.277761268406 -0.066467553123 -748 14.96 -0.276434574779 -0.0662020442454 -749 14.98 -0.275113177278 -0.0659379390934 -750 15.0 -0.273797047918 -0.0656752285492 -751 15.02 -0.272486158899 -0.0654139035635 -752 15.04 -0.271180482599 -0.0651539551544 -753 15.06 -0.269879991575 -0.0648953744073 -754 15.08 -0.268584658563 -0.0646381524742 -755 15.1 -0.267294456476 -0.0643822805732 -756 15.12 -0.266009358398 -0.064127749988 -757 15.14 -0.264729337592 -0.0638745520673 -758 15.16 -0.263454367489 -0.0636226782243 -759 15.18 -0.262184421693 -0.0633721199364 -760 15.2 -0.260919473977 -0.0631228687444 -761 15.22 -0.259659498285 -0.062874916252 -762 15.24 -0.258404468725 -0.0626282541256 -763 15.26 -0.257154359572 -0.0623828740934 -764 15.28 -0.255909145268 -0.0621387679452 -765 15.3 -0.254668800416 -0.061895927532 -766 15.32 -0.253433299783 -0.061654344765 -767 15.34 -0.252202618295 -0.0614140116156 -768 15.36 -0.250976731041 -0.0611749201148 -769 15.38 -0.249755613266 -0.0609370623526 -770 15.4 -0.248539240374 -0.0607004304776 -771 15.42 -0.247327587926 -0.0604650166966 -772 15.44 -0.246120631637 -0.0602308132741 -773 15.46 -0.244918347377 -0.0599978125317 -774 15.48 -0.243720711169 -0.0597660068478 -775 15.5 -0.242527699187 -0.0595353886571 -776 15.52 -0.241339287756 -0.05930595045 -777 15.54 -0.240155453352 -0.0590776847726 -778 15.56 -0.238976172597 -0.0588505842256 -779 15.58 -0.237801422264 -0.0586246414643 -780 15.6 -0.236631179269 -0.0583998491983 -781 15.62 -0.235465420674 -0.0581762001905 -782 15.64 -0.234304123687 -0.057953687257 -783 15.66 -0.233147265658 -0.057732303267 -784 15.68 -0.231994824078 -0.0575120411416 -785 15.7 -0.23084677658 -0.0572928938542 -786 15.72 -0.229703100938 -0.0570748544293 -787 15.74 -0.228563775063 -0.0568579159429 -788 15.76 -0.227428777006 -0.0566420715213 -789 15.78 -0.226298084954 -0.0564273143414 -790 15.8 -0.22517167723 -0.0562136376296 -791 15.82 -0.224049532291 -0.0560010346619 -792 15.84 -0.222931628729 -0.0557894987635 -793 15.86 -0.22181794527 -0.0555790233081 -794 15.88 -0.220708460771 -0.0553696017175 -795 15.9 -0.21960315422 -0.0551612274618 -796 15.92 -0.218502004734 -0.0549538940582 -797 15.94 -0.217404991561 -0.0547475950712 -798 15.96 -0.216312094077 -0.0545423241119 -799 15.98 -0.215223291785 -0.0543380748379 -800 16.0 -0.214138564315 -0.0541348409526 -801 16.02 -0.21305789142 -0.0539326162051 -802 16.04 -0.21198125298 -0.0537313943897 -803 16.06 -0.210908628999 -0.0535311693457 -804 16.08 -0.209839999602 -0.0533319349567 -805 16.1 -0.208775345037 -0.0531336851505 -806 16.12 -0.207714645672 -0.0529364138987 -807 16.14 -0.206657881997 -0.0527401152166 -808 16.16 -0.205605034619 -0.0525447831621 -809 16.18 -0.204556084266 -0.0523504118362 -810 16.2 -0.20351101178 -0.0521569953823 -811 16.22 -0.202469798123 -0.0519645279856 -812 16.24 -0.201432424372 -0.0517730038733 -813 16.26 -0.200398871718 -0.0515824173138 -814 16.28 -0.199369121467 -0.0513927626166 -815 16.3 -0.198343155039 -0.051204034132 -816 16.32 -0.197320953965 -0.0510162262506 -817 16.34 -0.196302499889 -0.050829333403 -818 16.36 -0.195287774565 -0.0506433500599 -819 16.38 -0.194276759859 -0.0504582707309 -820 16.4 -0.193269437746 -0.0502740899651 -821 16.42 -0.192265790306 -0.0500908023503 -822 16.44 -0.191265799733 -0.0499084025129 -823 16.46 -0.190269448323 -0.0497268851171 -824 16.48 -0.189276718481 -0.0495462448654 -825 16.5 -0.188287592716 -0.0493664764977 -826 16.52 -0.187302053643 -0.0491875747911 -827 16.54 -0.186320083981 -0.0490095345599 -828 16.56 -0.185341666552 -0.0488323506547 -829 16.58 -0.18436678428 -0.0486560179629 -830 16.6 -0.183395420192 -0.0484805314077 -831 16.62 -0.182427557417 -0.0483058859483 -832 16.64 -0.181463179181 -0.0481320765793 -833 16.66 -0.180502268813 -0.0479590983305 -834 16.68 -0.179544809739 -0.0477869462668 -835 16.7 -0.178590785487 -0.0476156154877 -836 16.72 -0.177640179677 -0.0474451011271 -837 16.74 -0.176692976031 -0.0472753983531 -838 16.76 -0.175749158364 -0.0471065023674 -839 16.78 -0.174808710589 -0.0469384084057 -840 16.8 -0.173871616713 -0.0467711117367 -841 16.82 -0.172937860836 -0.0466046076623 -842 16.84 -0.172007427154 -0.0464388915171 -843 16.86 -0.171080299953 -0.0462739586683 -844 16.88 -0.170156463616 -0.0461098045155 -845 16.9 -0.169235902612 -0.04594642449 -846 16.92 -0.168318601505 -0.0457838140552 -847 16.94 -0.167404544949 -0.0456219687059 -848 16.96 -0.166493717686 -0.0454608839681 -849 16.98 -0.165586104549 -0.0453005553988 -850 17.0 -0.164681690459 -0.045140978586 -851 17.02 -0.163780460423 -0.044982149148 -852 17.04 -0.162882399539 -0.0448240627335 -853 17.06 -0.161987492989 -0.0446667150213 -854 17.08 -0.161095726042 -0.0445101017198 -855 17.1 -0.160207084053 -0.0443542185673 -856 17.12 -0.15932155246 -0.0441990613312 -857 17.14 -0.158439116788 -0.0440446258081 -858 17.16 -0.157559762644 -0.0438909078236 -859 17.18 -0.156683475719 -0.0437379032318 -860 17.2 -0.155810241787 -0.0435856079154 -861 17.22 -0.154940046702 -0.0434340177851 -862 17.24 -0.154072876401 -0.0432831287799 -863 17.26 -0.153208716903 -0.0431329368663 -864 17.28 -0.152347554306 -0.0429834380385 -865 17.3 -0.151489374787 -0.0428346283181 -866 17.32 -0.150634164605 -0.0426865037537 -867 17.34 -0.149781910096 -0.0425390604208 -868 17.36 -0.148932597673 -0.0423922944219 -869 17.38 -0.148086213829 -0.0422462018856 -870 17.4 -0.147242745133 -0.0421007789672 -871 17.42 -0.146402178232 -0.0419560218477 -872 17.44 -0.145564499846 -0.0418119267343 -873 17.46 -0.144729696774 -0.0416684898597 -874 17.48 -0.143897755889 -0.0415257074823 -875 17.5 -0.143068664136 -0.0413835758856 -876 17.52 -0.142242408539 -0.0412420913782 -877 17.54 -0.141418976192 -0.0411012502937 -878 17.56 -0.140598354262 -0.0409610489904 -879 17.58 -0.139780529991 -0.0408214838511 -880 17.6 -0.138965490691 -0.040682551283 -881 17.62 -0.138153223746 -0.0405442477172 -882 17.64 -0.137343716613 -0.0404065696091 -883 17.66 -0.136536956816 -0.0402695134376 -884 17.68 -0.135732931952 -0.0401330757054 -885 17.7 -0.134931629688 -0.0399972529384 -886 17.72 -0.134133037758 -0.0398620416858 -887 17.74 -0.133337143966 -0.0397274385201 -888 17.76 -0.132543936186 -0.0395934400363 -889 17.78 -0.131753402356 -0.0394600428522 -890 17.8 -0.130965530486 -0.0393272436083 -891 17.82 -0.130180308648 -0.0391950389674 -892 17.84 -0.129397724985 -0.0390634256142 -893 17.86 -0.128617767704 -0.0389324002559 -894 17.88 -0.127840425077 -0.0388019596211 -895 17.9 -0.127065685442 -0.0386721004602 -896 17.92 -0.126293537203 -0.0385428195454 -897 17.94 -0.125523968827 -0.0384141136698 -898 17.96 -0.124756968844 -0.038285979648 -899 17.98 -0.12399252585 -0.0381584143155 -900 18.0 -0.123230628501 -0.0380314145287 -901 18.02 -0.122471265519 -0.0379049771648 -902 18.04 -0.121714425686 -0.0377790991214 -903 18.06 -0.120960097846 -0.0376537773164 -904 18.08 -0.120208270905 -0.0375290086883 -905 18.1 -0.119458933831 -0.0374047901954 -906 18.12 -0.11871207565 -0.0372811188161 -907 18.14 -0.117967685451 -0.0371579915483 -908 18.16 -0.117225752381 -0.0370354054099 -909 18.18 -0.116486265647 -0.0369133574381 -910 18.2 -0.115749214515 -0.0367918446895 -911 18.22 -0.11501458831 -0.0366708642398 -912 18.24 -0.114282376416 -0.0365504131839 -913 18.26 -0.113552568273 -0.0364304886354 -914 18.28 -0.11282515338 -0.0363110877269 -915 18.3 -0.112100121292 -0.0361922076096 -916 18.32 -0.111377461622 -0.0360738454529 -917 18.34 -0.110657164039 -0.0359559984449 -918 18.36 -0.109939218269 -0.0358386637917 -919 18.38 -0.109223614091 -0.0357218387177 -920 18.4 -0.108510341341 -0.0356055204649 -921 18.42 -0.107799389911 -0.0354897062933 -922 18.44 -0.107090749747 -0.0353743934808 -923 18.46 -0.106384410848 -0.0352595793223 -924 18.48 -0.105680363268 -0.0351452611307 -925 18.5 -0.104978597114 -0.0350314362357 -926 18.52 -0.104279102547 -0.0349181019845 -927 18.54 -0.103581869781 -0.0348052557411 -928 18.56 -0.102886889082 -0.0346928948865 -929 18.58 -0.102194150767 -0.0345810168186 -930 18.6 -0.101503645208 -0.0344696189517 -931 18.62 -0.100815362825 -0.0343586987167 -932 18.64 -0.100129294092 -0.0342482535611 -933 18.66 -0.0994454295322 -0.0341382809484 -934 18.68 -0.0987637597204 -0.0340287783585 -935 18.7 -0.0980842752811 -0.0339197432873 -936 18.72 -0.0974069668887 -0.0338111732465 -937 18.74 -0.0967318252675 -0.0337030657637 -938 18.76 -0.0960588411908 -0.0335954183822 -939 18.78 -0.0953880054812 -0.0334882286609 -940 18.8 -0.0947193090095 -0.0333814941741 -941 18.82 -0.0940527426954 -0.0332752125115 -942 18.84 -0.0933882975062 -0.0331693812782 -943 18.86 -0.0927259644573 -0.033063998094 -944 18.88 -0.0920657346112 -0.0329590605941 -945 18.9 -0.0914075990779 -0.0328545664286 -946 18.92 -0.0907515490141 -0.0327505132621 -947 18.94 -0.0900975756229 -0.0326468987742 -948 18.96 -0.089445670154 -0.032543720659 -949 18.98 -0.0887958239027 -0.0324409766249 -950 19.0 -0.0881480282103 -0.032338664395 -951 19.02 -0.0875022744633 -0.0322367817064 -952 19.04 -0.0868585540934 -0.0321353263106 -953 19.06 -0.0862168585771 -0.0320342959728 -954 19.08 -0.0855771794356 -0.0319336884725 -955 19.1 -0.084939508234 -0.0318335016031 -956 19.12 -0.0843038365819 -0.0317337331714 -957 19.14 -0.0836701561321 -0.0316343809981 -958 19.16 -0.0830384585813 -0.0315354429176 -959 19.18 -0.0824087356692 -0.0314369167774 -960 19.2 -0.0817809791782 -0.0313388004388 -961 19.22 -0.0811551809338 -0.031241091776 -962 19.24 -0.0805313328034 -0.0311437886765 -963 19.26 -0.079909426697 -0.031046889041 -964 19.28 -0.079289454566 -0.030950390783 -965 19.3 -0.0786714084036 -0.0308542918291 -966 19.32 -0.0780552802445 -0.0307585901186 -967 19.34 -0.0774410621642 -0.0306632836034 -968 19.36 -0.0768287462793 -0.0305683702482 -969 19.38 -0.0762183247467 -0.0304738480301 -970 19.4 -0.0756097897639 -0.0303797149388 -971 19.42 -0.0750031335683 -0.0302859689762 -972 19.44 -0.0743983484373 -0.0301926081566 -973 19.46 -0.0737954266876 -0.0300996305063 -974 19.48 -0.0731943606756 -0.0300070340638 -975 19.5 -0.0725951427967 -0.0299148168796 -976 19.52 -0.071997765485 -0.0298229770161 -977 19.54 -0.0714022212134 -0.0297315125477 -978 19.56 -0.0708085024932 -0.0296404215602 -979 19.58 -0.0702166018738 -0.0295497021514 -980 19.6 -0.0696265119425 -0.0294593524306 -981 19.62 -0.0690382253245 -0.0293693705184 -982 19.64 -0.0684517346822 -0.0292797545471 -983 19.66 -0.0678670327154 -0.0291905026603 -984 19.68 -0.0672841121609 -0.0291016130126 -985 19.7 -0.0667029657922 -0.0290130837702 -986 19.72 -0.0661235864195 -0.02892491311 -987 19.74 -0.0655459668893 -0.0288370992202 -988 19.76 -0.0649701000843 -0.0287496402998 -989 19.78 -0.0643959789228 -0.0286625345588 -990 19.8 -0.0638235963592 -0.028575780218 -991 19.82 -0.0632529453832 -0.0284893755087 -992 19.84 -0.0626840190197 -0.0284033186731 -993 19.86 -0.0621168103288 -0.0283176079638 -994 19.88 -0.0615513124053 -0.0282322416441 -995 19.9 -0.0609875183786 -0.0281472179874 -996 19.92 -0.0604254214128 -0.0280625352778 -997 19.94 -0.0598650147059 -0.0279781918096 -998 19.96 -0.0593062914901 -0.027894185887 -999 19.98 -0.0587492450313 -0.0278105158248 -1000 20.0 -0.0581938686292 -0.0277271799475 -1001 20.02 -0.0576401556166 -0.0276441765898 -1002 20.04 -0.0570880993599 -0.0275615040963 -1003 20.06 -0.056537693258 -0.0274791608214 -1004 20.08 -0.0559889307431 -0.0273971451294 -1005 20.1 -0.0554418052798 -0.0273154553941 -1006 20.12 -0.0548963103651 -0.0272340899992 -1007 20.14 -0.0543524395283 -0.0271530473379 -1008 20.16 -0.0538101863307 -0.027072325813 -1009 20.18 -0.0532695443654 -0.0269919238365 -1010 20.2 -0.0527305072574 -0.0269118398301 -1011 20.22 -0.0521930686629 -0.0268320722247 -1012 20.24 -0.0516572222695 -0.0267526194605 -1013 20.26 -0.0511229617959 -0.0266734799867 -1014 20.28 -0.0505902809917 -0.0265946522621 -1015 20.3 -0.0500591736373 -0.026516134754 -1016 20.32 -0.0495296335436 -0.0264379259393 -1017 20.34 -0.0490016545518 -0.0263600243033 -1018 20.36 -0.0484752305336 -0.0262824283405 -1019 20.38 -0.0479503553904 -0.0262051365543 -1020 20.4 -0.0474270230535 -0.0261281474567 -1021 20.42 -0.0469052274841 -0.0260514595684 -1022 20.44 -0.0463849626725 -0.0259750714189 -1023 20.46 -0.0458662226388 -0.0258989815462 -1024 20.48 -0.0453490014319 -0.0258231884968 -1025 20.5 -0.0448332931297 -0.0257476908257 -1026 20.52 -0.0443190918392 -0.0256724870964 -1027 20.54 -0.0438063916958 -0.0255975758806 -1028 20.56 -0.0432951868634 -0.0255229557586 -1029 20.58 -0.0427854715342 -0.0254486253186 -1030 20.6 -0.0422772399288 -0.0253745831572 -1031 20.62 -0.0417704862954 -0.0253008278792 -1032 20.64 -0.0412652049103 -0.0252273580972 -1033 20.66 -0.0407613900774 -0.0251541724321 -1034 20.68 -0.040259036128 -0.0250812695126 -1035 20.7 -0.039758137421 -0.0250086479756 -1036 20.72 -0.0392586883422 -0.0249363064654 -1037 20.74 -0.0387606833045 -0.0248642436347 -1038 20.76 -0.0382641167479 -0.0247924581434 -1039 20.78 -0.0377689831387 -0.0247209486595 -1040 20.8 -0.0372752769703 -0.0246497138585 -1041 20.82 -0.036782992762 -0.0245787524235 -1042 20.84 -0.0362921250596 -0.0245080630453 -1043 20.86 -0.0358026684351 -0.0244376444219 -1044 20.88 -0.0353146174863 -0.0243674952592 -1045 20.9 -0.0348279668369 -0.0242976142701 -1046 20.92 -0.0343427111362 -0.0242280001751 -1047 20.94 -0.0338588450591 -0.0241586517019 -1048 20.96 -0.0333763633058 -0.0240895675856 -1049 20.98 -0.0328952606017 -0.0240207465683 -1050 21.0 -0.0324155316974 -0.0239521873994 -1051 21.02 -0.0319371713684 -0.0238838888354 -1052 21.04 -0.0314601744149 -0.0238158496399 -1053 21.06 -0.0309845356618 -0.0237480685835 -1054 21.08 -0.0305102499587 -0.0236805444437 -1055 21.1 -0.0300373121794 -0.0236132760051 -1056 21.12 -0.0295657172219 -0.023546262059 -1057 21.14 -0.0290954600085 -0.0234795014037 -1058 21.16 -0.0286265354851 -0.0234129928442 -1059 21.18 -0.028158938622 -0.0233467351922 -1060 21.2 -0.0276926644126 -0.0232807272662 -1061 21.22 -0.0272277078743 -0.0232149678915 -1062 21.24 -0.0267640640477 -0.0231494558997 -1063 21.26 -0.0263017279969 -0.0230841901292 -1064 21.28 -0.0258406948088 -0.0230191694249 -1065 21.3 -0.0253809595937 -0.0229543926381 -1066 21.32 -0.0249225174848 -0.0228898586266 -1067 21.34 -0.0244653636377 -0.0228255662547 -1068 21.36 -0.0240094932312 -0.0227615143929 -1069 21.38 -0.0235549014661 -0.0226977019182 -1070 21.4 -0.023101583566 -0.0226341277136 -1071 21.42 -0.0226495347765 -0.0225707906687 -1072 21.44 -0.0221987503655 -0.0225076896791 -1073 21.46 -0.021749225623 -0.0224448236465 -1074 21.48 -0.0213009558606 -0.0223821914788 -1075 21.5 -0.020853936412 -0.02231979209 -1076 21.52 -0.0204081626323 -0.0222576244002 -1077 21.54 -0.0199636298985 -0.0221956873354 -1078 21.56 -0.0195203336085 -0.0221339798275 -1079 21.58 -0.0190782691821 -0.0220725008144 -1080 21.6 -0.0186374320597 -0.02201124924 -1081 21.62 -0.0181978177032 -0.0219502240539 -1082 21.64 -0.0177594215953 -0.0218894242115 -1083 21.66 -0.0173222392394 -0.0218288486741 -1084 21.68 -0.0168862661598 -0.0217684964086 -1085 21.7 -0.0164514979014 -0.0217083663878 -1086 21.72 -0.0160179300295 -0.0216484575898 -1087 21.74 -0.0155855581298 -0.0215887689986 -1088 21.76 -0.0151543778082 -0.0215292996039 -1089 21.78 -0.014724384691 -0.0214700484006 -1090 21.8 -0.0142955744243 -0.0214110143895 -1091 21.82 -0.0138679426741 -0.0213521965765 -1092 21.84 -0.0134414851265 -0.0212935939733 -1093 21.86 -0.013016197487 -0.0212352055967 -1094 21.88 -0.0125920754809 -0.0211770304692 -1095 21.9 -0.012169114853 -0.0211190676184 -1096 21.92 -0.0117473113675 -0.0210613160772 -1097 21.94 -0.0113266608076 -0.021003774884 -1098 21.96 -0.0109071589762 -0.0209464430823 -1099 21.98 -0.0104888016947 -0.0208893197208 -1100 22.0 -0.010071584804 -0.0208324038534 -1101 22.02 -0.00965550416359 -0.0207756945391 -1102 22.04 -0.0092405556517 -0.020719190842 -1103 22.06 -0.00882673516534 -0.0206628918315 -1104 22.08 -0.00841403862003 -0.0206067965819 -1105 22.1 -0.0080024619498 -0.0205509041723 -1106 22.12 -0.00759200110698 -0.0204952136871 -1107 22.14 -0.00718265206222 -0.0204397242155 -1108 22.16 -0.00677441080431 -0.0203844348517 -1109 22.18 -0.00636727334011 -0.0203293446947 -1110 22.2 -0.00596123569445 -0.0202744528484 -1111 22.22 -0.00555629391005 -0.0202197584216 -1112 22.24 -0.00515244404737 -0.0201652605278 -1113 22.26 -0.00474968218459 -0.0201109582853 -1114 22.28 -0.00434800441746 -0.0200568508172 -1115 22.3 -0.00394740685922 -0.0200029372512 -1116 22.32 -0.00354788564052 -0.0199492167196 -1117 22.34 -0.0031494369093 -0.0198956883597 -1118 22.36 -0.00275205683071 -0.0198423513132 -1119 22.38 -0.00235574158704 -0.0197892047262 -1120 22.4 -0.00196048737759 -0.0197362477497 -1121 22.42 -0.00156629041861 -0.0196834795391 -1122 22.44 -0.00117314694319 -0.0196308992543 -1123 22.46 -0.000781053201174 -0.0195785060596 -1124 22.48 -0.000390005459079 -0.019526299124 -1125 22.5 0.0 -0.0194742776206 -1126 22.52 0.0 0.0 -1127 22.54 0.0 0.0 -1128 22.56 0.0 0.0 -1129 22.58 0.0 0.0 -1130 22.6 0.0 0.0 diff --git a/tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/run.in.min b/tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/run.in.min deleted file mode 100644 index 6cbb92ad86..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/run.in.min +++ /dev/null @@ -1,28 +0,0 @@ -# -- Init section -- - -include system.in.init - -# -- Atom definition section -- - -read_data system.data - -# -- Settings Section -- - -include system.in.settings - -# Optional: Make sure the pairwise energies look reasonable: -#pair_write 2 2 1001 r 2.6 16.0 test_tail-tail.dat t-t 0 0 -#pair_write 2 3 1001 r 2.6 16.0 test_tail-head.dat t-h 0 0 -#pair_write 1 2 1001 r 2.6 16.0 test_int-tail.dat i-t 0 0 -#pair_write 1 1 2573 r 2.6 16.0 test_int-int.dat i-i 0 0 -#pair_write 1 3 1001 r 2.6 16.0 test_int-head.dat i-h 0 0 -#pair_write 3 3 1001 r 2.6 16.0 test_head-head.dat h-h 0 0 - - -# -- Run section -- - -dump 1 all custom 50 traj_min.lammpstrj id mol type x y z ix iy iz - -minimize 1.0e-5 1.0e-7 500 2000 - -write_data system_after_min.data diff --git a/tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/run.in.npt b/tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/run.in.npt deleted file mode 100644 index ab37d34b39..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/run.in.npt +++ /dev/null @@ -1,57 +0,0 @@ -# -------- REQUIREMENTS: --------- -# 1) This example may require additional features and bug fixes for LAMMPS. -# Be sure to download and copy the "additional_lammps_code" from -# http://moltemplate.org (upper-left corner menu) -# 2) Unpack it -# 3) copy the .cpp and .h files to the src folding of your lammps installation. -# 4) Compile LAMMPS. -# -# (If LAMMPS complains about an "Invalid pair_style" -# then you made a mistake in the instructions above.) -# - -# -- Init Section -- - -include system.in.init - -# -- Atom Definition Section -- - -read_data system.data - -# -- Settings Section -- - -include system.in.settings - -# -- Run Section -- - - -timestep 6.0 # The time-step in Watson et. al 2011 was 0.002*3ps = 6fs -dump 1 all custom 5000 traj_npt.lammpstrj id mol type x y z ix iy iz - - -thermo_style custom step temp pe etotal vol epair ebond eangle -thermo 1000 # time interval for printing out "thermo" data - - -fix fxlan all langevin 300.0 300.0 120 48279 -fix fxnph all nph x 0 0 1000 y 0 0 1000 couple xy - - -# Note: The temperature 300.0 K corresponds to 0.907033536873*epsilon -# for the "epsilon" used by the coarse-grained lipid. -# Note: The langevin damping parameter "120" corresponds to -# the 0.12ps damping time used in Watson et. al JCP 2011. -# Note: We maintain the system system at constant (zero) tention -# using a barostat damping parameter Pdamp=1000 ("0 0 1000") - - -# optional (not sure if this helps): -# balance x uniform y uniform - - -#restart 1000000 - -run 2000000 - -write_data system_after_npt.data - diff --git a/tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/run.in.nvt b/tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/run.in.nvt deleted file mode 100644 index 63d4cde4a1..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/membrane_BranniganPRE2005/run.in.nvt +++ /dev/null @@ -1,45 +0,0 @@ -# ------------------------------- Initialization Section -------------------- - -include system.in.init - -# ------------------------------- Atom Definition Section ------------------- - - -# Normally, I would minimize the system and equilibrate the system at constant -# pressure and temperature beforehand. If you run lammps with "run.in.npt", -# it will generate a data file "system_after_npt.data" with reasonable -# coordinates at that temperature and pressure. Then we could load it now: -# -#read_data system_after_npt.data - -read_data system.data - -# ------------------------------- Settings Section -------------------------- - -include system.in.settings - -# ------------------------------- Run Section ------------------------------- - - -timestep 6.0 # The time-step in Watson et. al 2011 was 0.002*3ps = 6fs -dump 1 all custom 5000 traj_nvt.lammpstrj id mol type x y z ix iy iz - - -thermo_style custom step temp pe etotal vol epair ebond eangle -thermo 1000 # time interval for printing out "thermo" data - - -fix fxlan all langevin 300.0 300.0 120 48279 -fix fxnve all nve - -# Note: The energy scale "epsilon" = 2.75kJ/mole = 330.7485200981 Kelvin*kB. -# So a temperature of 300.0 Kelvin corresponds to 0.907033536873*epsilon. -# Note: The langevin damping parameter "120" corresponds to -# the 0.12ps damping time used in Watson et. al JCP 2011. - -#restart 1000000 - -run 1000000 - -write_data system_after_nvt.data - diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/README.TXT b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/README.TXT deleted file mode 100644 index 31abcd66ef..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/README.TXT +++ /dev/null @@ -1,33 +0,0 @@ -# This directory contains examples of how to run a short simulation of a -# coarse-grained protein-like polymer, folding in the presence and absence of -# a chaperone (modeled as an attractive or repulsie spherical shell). -# -# The protein models and the chaperone models are described and used here: -# AI Jewett, A Baumketner and J-E Shea, PNAS, 101 (36), 13192-13197, (2004) -# (http://www.pnas.org/content/101/36/13192) -# ...and also here: -# AI Jewett and J-E Shea, J. Mol. Biol, Vol 363(5), (2006) -# -# (In the "frustrated+minichaperone" directory, the protein is -# placed outside the chaperone sphere, as opposed to inside.) -# -# -------- REQUIREMENTS: --------- -# 1) These examples require the "USER-MISC" package. (Use "make yes-USER-MISC") -# http://lammps.sandia.gov/doc/Section_start.html#start_3 -# 2) They also may require additional features and bug fixes for LAMMPS. -# be sure to download and copy the "additional_lammps_code" from -# http://moltemplate.org (upper-left corner menu) -# 3) Unpack it -# 4) copy the .cpp and .h files to the src folding of your lammps installation. -# 5) Compile LAMMPS. -# - -------------- -Instructions on how to build LAMMPS input files and -run a short simulation are provided in other README files in each directory. - -step 1) -README_setup.sh - -step2) -README_run.sh diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+chaperonin/README.TXT b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+chaperonin/README.TXT deleted file mode 100644 index a52f73ff7b..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+chaperonin/README.TXT +++ /dev/null @@ -1,32 +0,0 @@ -# This directory demonstrates how to run a long simulation of -# the "frustrated" coarse-grained protein confined in a frustrated -# coarse-grained chaperonin (R=6, h=0.475) as described in: -# AI Jewett, A Baumketner and J-E Shea, PNAS, 101 (36), 13192-13197, (2004) -# (http://www.pnas.org/content/101/36/13192) -# -# Note: If you want to use a "hydrophilic" chaperone (with h=0.0 -# instead of h=0.475), then replace the word "CHAP_INTERIOR_H0.475" -# (at the end of "system.lt") with "CHAP_INTERIOR_H0" -# -# Because this process takes a long time (even with the help of the chaperone) -# I save the data relatively infrequently. -# -# -------- REQUIREMENTS: --------- -# 1) This example requires the "USER-MISC" package. (Use "make yes-USER-MISC") -# http://lammps.sandia.gov/doc/Section_start.html#start_3 -# 2) It also may require additional features and bug fixes for LAMMPS. -# be sure to download and copy the "additional_lammps_code" from -# http://moltemplate.org (upper-left corner menu) -# 3) Unpack it -# 4) copy the .cpp and .h files to the src folding of your lammps installation. -# 5) Compile LAMMPS. - -------------- -Instructions on how to build LAMMPS input files and -run a short simulation are provided in other README files. - -step 1) -README_setup.sh - -step2) -README_run.sh diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+chaperonin/README_run.sh b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+chaperonin/README_run.sh deleted file mode 100755 index d5ae1fe5a3..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+chaperonin/README_run.sh +++ /dev/null @@ -1,31 +0,0 @@ -# You would probably run lammps this way: -# -# lmp_ubuntu -i run.in.nvt - -# The files "run.in.min", and "run.in.nvt" are LAMMPS input scripts which refer -# to the input scripts & data files you created earlier when you ran moltemplate -# system.in.init, system.in.settings, system.data - - - - -# ----------------------------------- - - - -LAMMPS_COMMAND="lmp_mpi" - -# Here "$LAMMPS_BINARY" is the name of the command you use to invoke lammps -# (such as lmp_ubuntu, lmp_mac_mpi, lmp_cygwin etc...). Change if necessary. - -# Run lammps using the following 3 commands: - -"$LAMMPS_COMMAND" -i run.in.min # minimize (OPTIONAL) -"$LAMMPS_COMMAND" -i run.in.nvt # production run - -# Alternately, if you have MPI installed, try something like this: - -#NUMPROCS=4 -#mpirun -np $NUMPROCS "$LAMMPS_COMMAND" -i run.in.min # minimize (OPTIONAL) -#mpirun -np $NUMPROCS "$LAMMPS_COMMAND" -i run.in.nvt # production run - diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+chaperonin/README_setup.sh b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+chaperonin/README_setup.sh deleted file mode 100755 index df49f4384f..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+chaperonin/README_setup.sh +++ /dev/null @@ -1,24 +0,0 @@ -# Use these commands to generate the LAMMPS input script and data file -# (and other auxilliary files): - - -# Create LAMMPS input files this way: -cd moltemplate_files - - # run moltemplate - - moltemplate.sh -overlay-dihedrals system.lt - - # This will generate various files with names ending in *.in* and *.data. - # These files are the input files directly read by LAMMPS. Move them to - # the parent directory (or wherever you plan to run the simulation). - - mv -f system.in* system.data ../ - cp -r table*.dat ../ - - # Optional: - # The "./output_ttree/" directory is full of temporary files generated by - # moltemplate. They can be useful for debugging, but are usually thrown away. - rm -rf output_ttree/ - -cd ../ diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+chaperonin/README_visualize.txt b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+chaperonin/README_visualize.txt deleted file mode 100644 index 019afc1444..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+chaperonin/README_visualize.txt +++ /dev/null @@ -1,87 +0,0 @@ - - ------- To view a lammps trajectory in VMD -------- - - -1) Build a PSF file for use in viewing with VMD. - -This step works with VMD 1.9 and topotools 1.2. -(Older versions, like VMD 1.8.6, don't support this.) - - -a) Start VMD -b) Menu Extensions->Tk Console -c) Enter: - -(I assume that the the DATA file is called "system.data") - - topo readlammpsdata system.data full - animate write psf system.psf - -2) - -Later, to Load a trajectory in VMD: - - Start VMD - Select menu: File->New Molecule - -Browse to select the PSF file you created above, and load it. - (Don't close the window yet.) - -Browse to select the trajectory file. - If necessary, for "file type" select: "LAMMPS Trajectory" - Load it. - - ---- A note on trajectory format: ----- -If the trajectory is a DUMP file, then make sure the it contains the -information you need for pbctools (see below. I've been using this -command in my LAMMPS scripts to create the trajectories: - - dump 1 all custom 5000 DUMP_FILE.lammpstrj id mol type x y z ix iy iz - -It's a good idea to use an atom_style which supports molecule-ID numbers -so that you can assign a molecule-ID number to each atom. (I think this -is needed to wrap atom coordinates without breaking molecules in half.) - -Of course, you don't have to save your trajectories in DUMP format, -(other formats like DCD work fine) I just mention dump files -because these are the files I'm familiar with. - -3) ----- Wrap the coordinates to the unit cell - (without cutting the molecules in half) - -a) Start VMD -b) Load the trajectory in VMD (see above) -c) Menu Extensions->Tk Console -d) Try entering these commands: - - pbc wrap -compound res -all - pbc box - - ----- Optional ---- - Sometimes the solvent or membrane obscures the view of the solute. - It can help to shift the location of the periodic boundary box - To shift the box in the y direction (for example) do this: - - pbc wrap -compound res -all -shiftcenterrel {0.0 0.15 0.0} - pbc box -shiftcenterrel {0.0 0.15 0.0} - - Distances are measured in units of box-length fractions, not Angstroms. - - Alternately if you have a solute whose atoms are all of type 1, - then you can also try this to center the box around it: - - pbc wrap -sel type=1 -all -centersel type=2 -center com - -4) - You should check if your periodic boundary conditions are too small. - To do that: - select Graphics->Representations menu option - click on the "Periodic" tab, and - click on the "+x", "-x", "+y", "-y", "+z", "-z" checkboxes. - -5) Optional: If you like, change the atom types in the PSF file so - that VMD recognizes the atom types, use something like: - -sed -e 's/ 1 1 / C C /g' < system.psf > temp1.psf -sed -e 's/ 2 2 / H H /g' < temp1.psf > temp2.psf -sed -e 's/ 3 3 / P P /g' < temp2.psf > system.psf - -(If you do this, it might effect step 2 above.) diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+chaperonin/images/for_visualization/psf_file_created_by_topotools/system.psf b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+chaperonin/images/for_visualization/psf_file_created_by_topotools/system.psf deleted file mode 100644 index 9e34246f8e..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+chaperonin/images/for_visualization/psf_file_created_by_topotools/system.psf +++ /dev/null @@ -1,86 +0,0 @@ -PSF - - 1 !NTITLE - REMARKS VMD generated structure x-plor psf file - - 28 !NATOM - 1 1 2 2 0.000000 1.0000 0 - 2 1 1 1 0.000000 1.0000 0 - 3 1 2 2 0.000000 1.0000 0 - 4 1 1 1 0.000000 1.0000 0 - 5 1 2 2 0.000000 1.0000 0 - 6 1 1 1 0.000000 1.0000 0 - 7 1 3 3 0.000000 1.0000 0 - 8 1 3 3 0.000000 1.0000 0 - 9 1 1 1 0.000000 1.0000 0 - 10 1 2 2 0.000000 1.0000 0 - 11 1 1 1 0.000000 1.0000 0 - 12 1 2 2 0.000000 1.0000 0 - 13 1 1 1 0.000000 1.0000 0 - 14 1 2 2 0.000000 1.0000 0 - 15 1 3 3 0.000000 1.0000 0 - 16 1 3 3 0.000000 1.0000 0 - 17 1 3 3 0.000000 1.0000 0 - 18 1 1 1 0.000000 1.0000 0 - 19 1 1 1 0.000000 1.0000 0 - 20 1 2 2 0.000000 1.0000 0 - 21 1 2 2 0.000000 1.0000 0 - 22 1 1 1 0.000000 1.0000 0 - 23 1 1 1 0.000000 1.0000 0 - 24 1 2 2 0.000000 1.0000 0 - 25 1 2 2 0.000000 1.0000 0 - 26 1 1 1 0.000000 1.0000 0 - 27 1 2 2 0.000000 1.0000 0 - 28 2 4 4 0.000000 100.0000 0 - - 26 !NBOND: bonds - 1 2 2 3 3 4 4 5 - 5 6 6 7 7 8 8 9 - 9 10 10 11 11 12 12 13 - 13 14 14 15 15 16 16 17 - 17 18 18 19 19 20 20 21 - 21 22 22 23 23 24 24 25 - 25 26 26 27 - - 25 !NTHETA: angles - 13 14 15 7 8 9 6 7 8 - 16 17 18 15 16 17 2 3 4 - 4 5 6 9 10 11 11 12 13 - 14 15 16 1 2 3 3 4 5 - 10 11 12 12 13 14 25 26 27 - 5 6 7 8 9 10 17 18 19 - 18 19 20 22 23 24 21 22 23 - 19 20 21 20 21 22 23 24 25 - 24 25 26 - - 19 !NPHI: dihedrals - 1 2 3 4 2 3 4 5 - 3 4 5 6 4 5 6 7 - 8 9 10 11 9 10 11 12 - 10 11 12 13 11 12 13 14 - 12 13 14 15 15 16 17 18 - 16 17 18 19 17 18 19 20 - 18 19 20 21 19 20 21 22 - 20 21 22 23 21 22 23 24 - 22 23 24 25 23 24 25 26 - 24 25 26 27 - - 0 !NIMPHI: impropers - - - 0 !NDON: donors - - - 0 !NACC: acceptors - - - 0 !NNB - - 0 0 0 0 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 !NGRP - 0 0 0 - diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+chaperonin/images/misfolded+chaperonin_t=0tau_LR.jpg b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+chaperonin/images/misfolded+chaperonin_t=0tau_LR.jpg deleted file mode 100644 index 31853cd5ad4b73c6abc2ea24708765e41cb7b68b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15784 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 diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+chaperonin/images/unfolded+chaperonin_t=508750tau_LR.jpg b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+chaperonin/images/unfolded+chaperonin_t=508750tau_LR.jpg deleted file mode 100644 index fdc5c890b18ec41eee143a4584dfe8195d833ed0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17080 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 Console -c) Enter: - -(I assume that the the DATA file is called "system.data") - - topo readlammpsdata system.data full - animate write psf system.psf - -2) - -Later, to Load a trajectory in VMD: - - Start VMD - Select menu: File->New Molecule - -Browse to select the PSF file you created above, and load it. - (Don't close the window yet.) - -Browse to select the trajectory file. - If necessary, for "file type" select: "LAMMPS Trajectory" - Load it. - - ---- A note on trajectory format: ----- -If the trajectory is a DUMP file, then make sure the it contains the -information you need for pbctools (see below. I've been using this -command in my LAMMPS scripts to create the trajectories: - - dump 1 all custom 5000 DUMP_FILE.lammpstrj id mol type x y z ix iy iz - -It's a good idea to use an atom_style which supports molecule-ID numbers -so that you can assign a molecule-ID number to each atom. (I think this -is needed to wrap atom coordinates without breaking molecules in half.) - -Of course, you don't have to save your trajectories in DUMP format, -(other formats like DCD work fine) I just mention dump files -because these are the files I'm familiar with. - -3) ----- Wrap the coordinates to the unit cell - (without cutting the molecules in half) - -a) Start VMD -b) Load the trajectory in VMD (see above) -c) Menu Extensions->Tk Console -d) Try entering these commands: - - pbc wrap -compound res -all - pbc box - - ----- Optional ---- - Sometimes the solvent or membrane obscures the view of the solute. - It can help to shift the location of the periodic boundary box - To shift the box in the y direction (for example) do this: - - pbc wrap -compound res -all -shiftcenterrel {0.0 0.15 0.0} - pbc box -shiftcenterrel {0.0 0.15 0.0} - - Distances are measured in units of box-length fractions, not Angstroms. - - Alternately if you have a solute whose atoms are all of type 1, - then you can also try this to center the box around it: - - pbc wrap -sel type=1 -all -centersel type=2 -center com - -4) - You should check if your periodic boundary conditions are too small. - To do that: - select Graphics->Representations menu option - click on the "Periodic" tab, and - click on the "+x", "-x", "+y", "-y", "+z", "-z" checkboxes. - -5) Optional: If you like, change the atom types in the PSF file so - that VMD recognizes the atom types, use something like: - -sed -e 's/ 1 1 / C C /g' < system.psf > temp1.psf -sed -e 's/ 2 2 / H H /g' < temp1.psf > temp2.psf -sed -e 's/ 3 3 / P P /g' < temp2.psf > system.psf - -(If you do this, it might effect step 2 above.) diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+minichaperone/images/for_visualization/psf_file_created_by_topotools/system.psf b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+minichaperone/images/for_visualization/psf_file_created_by_topotools/system.psf deleted file mode 100644 index b0013ccc62..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+minichaperone/images/for_visualization/psf_file_created_by_topotools/system.psf +++ /dev/null @@ -1,476 +0,0 @@ -PSF - - 1 !NTITLE - REMARKS VMD generated structure x-plor psf file - - 224 !NATOM - 1 1 2 2 0.000000 1.0000 0 - 2 1 1 1 0.000000 1.0000 0 - 3 1 2 2 0.000000 1.0000 0 - 4 1 1 1 0.000000 1.0000 0 - 5 1 2 2 0.000000 1.0000 0 - 6 1 1 1 0.000000 1.0000 0 - 7 1 3 3 0.000000 1.0000 0 - 8 1 3 3 0.000000 1.0000 0 - 9 1 1 1 0.000000 1.0000 0 - 10 1 2 2 0.000000 1.0000 0 - 11 1 1 1 0.000000 1.0000 0 - 12 1 2 2 0.000000 1.0000 0 - 13 1 1 1 0.000000 1.0000 0 - 14 1 2 2 0.000000 1.0000 0 - 15 1 3 3 0.000000 1.0000 0 - 16 1 3 3 0.000000 1.0000 0 - 17 1 3 3 0.000000 1.0000 0 - 18 1 1 1 0.000000 1.0000 0 - 19 1 1 1 0.000000 1.0000 0 - 20 1 2 2 0.000000 1.0000 0 - 21 1 2 2 0.000000 1.0000 0 - 22 1 1 1 0.000000 1.0000 0 - 23 1 1 1 0.000000 1.0000 0 - 24 1 2 2 0.000000 1.0000 0 - 25 1 2 2 0.000000 1.0000 0 - 26 1 1 1 0.000000 1.0000 0 - 27 1 2 2 0.000000 1.0000 0 - 28 2 2 2 0.000000 1.0000 0 - 29 2 1 1 0.000000 1.0000 0 - 30 2 2 2 0.000000 1.0000 0 - 31 2 1 1 0.000000 1.0000 0 - 32 2 2 2 0.000000 1.0000 0 - 33 2 1 1 0.000000 1.0000 0 - 34 2 3 3 0.000000 1.0000 0 - 35 2 3 3 0.000000 1.0000 0 - 36 2 1 1 0.000000 1.0000 0 - 37 2 2 2 0.000000 1.0000 0 - 38 2 1 1 0.000000 1.0000 0 - 39 2 2 2 0.000000 1.0000 0 - 40 2 1 1 0.000000 1.0000 0 - 41 2 2 2 0.000000 1.0000 0 - 42 2 3 3 0.000000 1.0000 0 - 43 2 3 3 0.000000 1.0000 0 - 44 2 3 3 0.000000 1.0000 0 - 45 2 1 1 0.000000 1.0000 0 - 46 2 1 1 0.000000 1.0000 0 - 47 2 2 2 0.000000 1.0000 0 - 48 2 2 2 0.000000 1.0000 0 - 49 2 1 1 0.000000 1.0000 0 - 50 2 1 1 0.000000 1.0000 0 - 51 2 2 2 0.000000 1.0000 0 - 52 2 2 2 0.000000 1.0000 0 - 53 2 1 1 0.000000 1.0000 0 - 54 2 2 2 0.000000 1.0000 0 - 55 3 2 2 0.000000 1.0000 0 - 56 3 1 1 0.000000 1.0000 0 - 57 3 2 2 0.000000 1.0000 0 - 58 3 1 1 0.000000 1.0000 0 - 59 3 2 2 0.000000 1.0000 0 - 60 3 1 1 0.000000 1.0000 0 - 61 3 3 3 0.000000 1.0000 0 - 62 3 3 3 0.000000 1.0000 0 - 63 3 1 1 0.000000 1.0000 0 - 64 3 2 2 0.000000 1.0000 0 - 65 3 1 1 0.000000 1.0000 0 - 66 3 2 2 0.000000 1.0000 0 - 67 3 1 1 0.000000 1.0000 0 - 68 3 2 2 0.000000 1.0000 0 - 69 3 3 3 0.000000 1.0000 0 - 70 3 3 3 0.000000 1.0000 0 - 71 3 3 3 0.000000 1.0000 0 - 72 3 1 1 0.000000 1.0000 0 - 73 3 1 1 0.000000 1.0000 0 - 74 3 2 2 0.000000 1.0000 0 - 75 3 2 2 0.000000 1.0000 0 - 76 3 1 1 0.000000 1.0000 0 - 77 3 1 1 0.000000 1.0000 0 - 78 3 2 2 0.000000 1.0000 0 - 79 3 2 2 0.000000 1.0000 0 - 80 3 1 1 0.000000 1.0000 0 - 81 3 2 2 0.000000 1.0000 0 - 82 4 2 2 0.000000 1.0000 0 - 83 4 1 1 0.000000 1.0000 0 - 84 4 2 2 0.000000 1.0000 0 - 85 4 1 1 0.000000 1.0000 0 - 86 4 2 2 0.000000 1.0000 0 - 87 4 1 1 0.000000 1.0000 0 - 88 4 3 3 0.000000 1.0000 0 - 89 4 3 3 0.000000 1.0000 0 - 90 4 1 1 0.000000 1.0000 0 - 91 4 2 2 0.000000 1.0000 0 - 92 4 1 1 0.000000 1.0000 0 - 93 4 2 2 0.000000 1.0000 0 - 94 4 1 1 0.000000 1.0000 0 - 95 4 2 2 0.000000 1.0000 0 - 96 4 3 3 0.000000 1.0000 0 - 97 4 3 3 0.000000 1.0000 0 - 98 4 3 3 0.000000 1.0000 0 - 99 4 1 1 0.000000 1.0000 0 - 100 4 1 1 0.000000 1.0000 0 - 101 4 2 2 0.000000 1.0000 0 - 102 4 2 2 0.000000 1.0000 0 - 103 4 1 1 0.000000 1.0000 0 - 104 4 1 1 0.000000 1.0000 0 - 105 4 2 2 0.000000 1.0000 0 - 106 4 2 2 0.000000 1.0000 0 - 107 4 1 1 0.000000 1.0000 0 - 108 4 2 2 0.000000 1.0000 0 - 109 5 2 2 0.000000 1.0000 0 - 110 5 1 1 0.000000 1.0000 0 - 111 5 2 2 0.000000 1.0000 0 - 112 5 1 1 0.000000 1.0000 0 - 113 5 2 2 0.000000 1.0000 0 - 114 5 1 1 0.000000 1.0000 0 - 115 5 3 3 0.000000 1.0000 0 - 116 5 3 3 0.000000 1.0000 0 - 117 5 1 1 0.000000 1.0000 0 - 118 5 2 2 0.000000 1.0000 0 - 119 5 1 1 0.000000 1.0000 0 - 120 5 2 2 0.000000 1.0000 0 - 121 5 1 1 0.000000 1.0000 0 - 122 5 2 2 0.000000 1.0000 0 - 123 5 3 3 0.000000 1.0000 0 - 124 5 3 3 0.000000 1.0000 0 - 125 5 3 3 0.000000 1.0000 0 - 126 5 1 1 0.000000 1.0000 0 - 127 5 1 1 0.000000 1.0000 0 - 128 5 2 2 0.000000 1.0000 0 - 129 5 2 2 0.000000 1.0000 0 - 130 5 1 1 0.000000 1.0000 0 - 131 5 1 1 0.000000 1.0000 0 - 132 5 2 2 0.000000 1.0000 0 - 133 5 2 2 0.000000 1.0000 0 - 134 5 1 1 0.000000 1.0000 0 - 135 5 2 2 0.000000 1.0000 0 - 136 6 2 2 0.000000 1.0000 0 - 137 6 1 1 0.000000 1.0000 0 - 138 6 2 2 0.000000 1.0000 0 - 139 6 1 1 0.000000 1.0000 0 - 140 6 2 2 0.000000 1.0000 0 - 141 6 1 1 0.000000 1.0000 0 - 142 6 3 3 0.000000 1.0000 0 - 143 6 3 3 0.000000 1.0000 0 - 144 6 1 1 0.000000 1.0000 0 - 145 6 2 2 0.000000 1.0000 0 - 146 6 1 1 0.000000 1.0000 0 - 147 6 2 2 0.000000 1.0000 0 - 148 6 1 1 0.000000 1.0000 0 - 149 6 2 2 0.000000 1.0000 0 - 150 6 3 3 0.000000 1.0000 0 - 151 6 3 3 0.000000 1.0000 0 - 152 6 3 3 0.000000 1.0000 0 - 153 6 1 1 0.000000 1.0000 0 - 154 6 1 1 0.000000 1.0000 0 - 155 6 2 2 0.000000 1.0000 0 - 156 6 2 2 0.000000 1.0000 0 - 157 6 1 1 0.000000 1.0000 0 - 158 6 1 1 0.000000 1.0000 0 - 159 6 2 2 0.000000 1.0000 0 - 160 6 2 2 0.000000 1.0000 0 - 161 6 1 1 0.000000 1.0000 0 - 162 6 2 2 0.000000 1.0000 0 - 163 7 2 2 0.000000 1.0000 0 - 164 7 1 1 0.000000 1.0000 0 - 165 7 2 2 0.000000 1.0000 0 - 166 7 1 1 0.000000 1.0000 0 - 167 7 2 2 0.000000 1.0000 0 - 168 7 1 1 0.000000 1.0000 0 - 169 7 3 3 0.000000 1.0000 0 - 170 7 3 3 0.000000 1.0000 0 - 171 7 1 1 0.000000 1.0000 0 - 172 7 2 2 0.000000 1.0000 0 - 173 7 1 1 0.000000 1.0000 0 - 174 7 2 2 0.000000 1.0000 0 - 175 7 1 1 0.000000 1.0000 0 - 176 7 2 2 0.000000 1.0000 0 - 177 7 3 3 0.000000 1.0000 0 - 178 7 3 3 0.000000 1.0000 0 - 179 7 3 3 0.000000 1.0000 0 - 180 7 1 1 0.000000 1.0000 0 - 181 7 1 1 0.000000 1.0000 0 - 182 7 2 2 0.000000 1.0000 0 - 183 7 2 2 0.000000 1.0000 0 - 184 7 1 1 0.000000 1.0000 0 - 185 7 1 1 0.000000 1.0000 0 - 186 7 2 2 0.000000 1.0000 0 - 187 7 2 2 0.000000 1.0000 0 - 188 7 1 1 0.000000 1.0000 0 - 189 7 2 2 0.000000 1.0000 0 - 190 8 2 2 0.000000 1.0000 0 - 191 8 1 1 0.000000 1.0000 0 - 192 8 2 2 0.000000 1.0000 0 - 193 8 1 1 0.000000 1.0000 0 - 194 8 2 2 0.000000 1.0000 0 - 195 8 1 1 0.000000 1.0000 0 - 196 8 3 3 0.000000 1.0000 0 - 197 8 3 3 0.000000 1.0000 0 - 198 8 1 1 0.000000 1.0000 0 - 199 8 2 2 0.000000 1.0000 0 - 200 8 1 1 0.000000 1.0000 0 - 201 8 2 2 0.000000 1.0000 0 - 202 8 1 1 0.000000 1.0000 0 - 203 8 2 2 0.000000 1.0000 0 - 204 8 3 3 0.000000 1.0000 0 - 205 8 3 3 0.000000 1.0000 0 - 206 8 3 3 0.000000 1.0000 0 - 207 8 1 1 0.000000 1.0000 0 - 208 8 1 1 0.000000 1.0000 0 - 209 8 2 2 0.000000 1.0000 0 - 210 8 2 2 0.000000 1.0000 0 - 211 8 1 1 0.000000 1.0000 0 - 212 8 1 1 0.000000 1.0000 0 - 213 8 2 2 0.000000 1.0000 0 - 214 8 2 2 0.000000 1.0000 0 - 215 8 1 1 0.000000 1.0000 0 - 216 8 2 2 0.000000 1.0000 0 - 217 9 4 4 0.000000 100.0000 0 - 218 10 4 4 0.000000 100.0000 0 - 219 11 4 4 0.000000 100.0000 0 - 220 12 4 4 0.000000 100.0000 0 - 221 13 4 4 0.000000 100.0000 0 - 222 14 4 4 0.000000 100.0000 0 - 223 15 4 4 0.000000 100.0000 0 - 224 16 4 4 0.000000 100.0000 0 - - 208 !NBOND: bonds - 1 2 2 3 3 4 4 5 - 5 6 6 7 7 8 8 9 - 9 10 10 11 11 12 12 13 - 13 14 14 15 15 16 16 17 - 17 18 18 19 19 20 20 21 - 21 22 22 23 23 24 24 25 - 25 26 26 27 28 29 29 30 - 30 31 31 32 32 33 33 34 - 34 35 35 36 36 37 37 38 - 38 39 39 40 40 41 41 42 - 42 43 43 44 44 45 45 46 - 46 47 47 48 48 49 49 50 - 50 51 51 52 52 53 53 54 - 55 56 56 57 57 58 58 59 - 59 60 60 61 61 62 62 63 - 63 64 64 65 65 66 66 67 - 67 68 68 69 69 70 70 71 - 71 72 72 73 73 74 74 75 - 75 76 76 77 77 78 78 79 - 79 80 80 81 82 83 83 84 - 84 85 85 86 86 87 87 88 - 88 89 89 90 90 91 91 92 - 92 93 93 94 94 95 95 96 - 96 97 97 98 98 99 99 100 - 100 101 101 102 102 103 103 104 - 104 105 105 106 106 107 107 108 - 109 110 110 111 111 112 112 113 - 113 114 114 115 115 116 116 117 - 117 118 118 119 119 120 120 121 - 121 122 122 123 123 124 124 125 - 125 126 126 127 127 128 128 129 - 129 130 130 131 131 132 132 133 - 133 134 134 135 136 137 137 138 - 138 139 139 140 140 141 141 142 - 142 143 143 144 144 145 145 146 - 146 147 147 148 148 149 149 150 - 150 151 151 152 152 153 153 154 - 154 155 155 156 156 157 157 158 - 158 159 159 160 160 161 161 162 - 163 164 164 165 165 166 166 167 - 167 168 168 169 169 170 170 171 - 171 172 172 173 173 174 174 175 - 175 176 176 177 177 178 178 179 - 179 180 180 181 181 182 182 183 - 183 184 184 185 185 186 186 187 - 187 188 188 189 190 191 191 192 - 192 193 193 194 194 195 195 196 - 196 197 197 198 198 199 199 200 - 200 201 201 202 202 203 203 204 - 204 205 205 206 206 207 207 208 - 208 209 209 210 210 211 211 212 - 212 213 213 214 214 215 215 216 - - 200 !NTHETA: angles - 13 14 15 40 41 42 67 68 69 - 94 95 96 121 122 123 148 149 150 - 175 176 177 202 203 204 7 8 9 - 6 7 8 16 17 18 34 35 36 - 33 34 35 43 44 45 61 62 63 - 60 61 62 70 71 72 88 89 90 - 87 88 89 97 98 99 115 116 117 - 114 115 116 124 125 126 142 143 144 - 141 142 143 151 152 153 169 170 171 - 168 169 170 178 179 180 196 197 198 - 195 196 197 205 206 207 15 16 17 - 42 43 44 69 70 71 96 97 98 - 123 124 125 150 151 152 177 178 179 - 204 205 206 2 3 4 4 5 6 - 9 10 11 11 12 13 29 30 31 - 31 32 33 36 37 38 38 39 40 - 56 57 58 58 59 60 63 64 65 - 65 66 67 83 84 85 85 86 87 - 90 91 92 92 93 94 110 111 112 - 112 113 114 117 118 119 119 120 121 - 137 138 139 139 140 141 144 145 146 - 146 147 148 164 165 166 166 167 168 - 171 172 173 173 174 175 191 192 193 - 193 194 195 198 199 200 200 201 202 - 14 15 16 41 42 43 68 69 70 - 95 96 97 122 123 124 149 150 151 - 176 177 178 203 204 205 1 2 3 - 3 4 5 10 11 12 12 13 14 - 25 26 27 28 29 30 30 31 32 - 37 38 39 39 40 41 52 53 54 - 55 56 57 57 58 59 64 65 66 - 66 67 68 79 80 81 82 83 84 - 84 85 86 91 92 93 93 94 95 - 106 107 108 109 110 111 111 112 113 - 118 119 120 120 121 122 133 134 135 - 136 137 138 138 139 140 145 146 147 - 147 148 149 160 161 162 163 164 165 - 165 166 167 172 173 174 174 175 176 - 187 188 189 190 191 192 192 193 194 - 199 200 201 201 202 203 214 215 216 - 5 6 7 8 9 10 32 33 34 - 35 36 37 59 60 61 62 63 64 - 86 87 88 89 90 91 113 114 115 - 116 117 118 140 141 142 143 144 145 - 167 168 169 170 171 172 194 195 196 - 197 198 199 17 18 19 44 45 46 - 71 72 73 98 99 100 125 126 127 - 152 153 154 179 180 181 206 207 208 - 18 19 20 22 23 24 21 22 23 - 45 46 47 49 50 51 48 49 50 - 72 73 74 76 77 78 75 76 77 - 99 100 101 103 104 105 102 103 104 - 126 127 128 130 131 132 129 130 131 - 153 154 155 157 158 159 156 157 158 - 180 181 182 184 185 186 183 184 185 - 207 208 209 211 212 213 210 211 212 - 19 20 21 20 21 22 23 24 25 - 24 25 26 46 47 48 47 48 49 - 50 51 52 51 52 53 73 74 75 - 74 75 76 77 78 79 78 79 80 - 100 101 102 101 102 103 104 105 106 - 105 106 107 127 128 129 128 129 130 - 131 132 133 132 133 134 154 155 156 - 155 156 157 158 159 160 159 160 161 - 181 182 183 182 183 184 185 186 187 - 186 187 188 208 209 210 209 210 211 - 212 213 214 213 214 215 - - 152 !NPHI: dihedrals - 1 2 3 4 2 3 4 5 - 3 4 5 6 4 5 6 7 - 8 9 10 11 9 10 11 12 - 10 11 12 13 11 12 13 14 - 12 13 14 15 15 16 17 18 - 16 17 18 19 17 18 19 20 - 18 19 20 21 19 20 21 22 - 20 21 22 23 21 22 23 24 - 22 23 24 25 23 24 25 26 - 24 25 26 27 28 29 30 31 - 29 30 31 32 30 31 32 33 - 31 32 33 34 35 36 37 38 - 36 37 38 39 37 38 39 40 - 38 39 40 41 39 40 41 42 - 42 43 44 45 43 44 45 46 - 44 45 46 47 45 46 47 48 - 46 47 48 49 47 48 49 50 - 48 49 50 51 49 50 51 52 - 50 51 52 53 51 52 53 54 - 55 56 57 58 56 57 58 59 - 57 58 59 60 58 59 60 61 - 62 63 64 65 63 64 65 66 - 64 65 66 67 65 66 67 68 - 66 67 68 69 69 70 71 72 - 70 71 72 73 71 72 73 74 - 72 73 74 75 73 74 75 76 - 74 75 76 77 75 76 77 78 - 76 77 78 79 77 78 79 80 - 78 79 80 81 82 83 84 85 - 83 84 85 86 84 85 86 87 - 85 86 87 88 89 90 91 92 - 90 91 92 93 91 92 93 94 - 92 93 94 95 93 94 95 96 - 96 97 98 99 97 98 99 100 - 98 99 100 101 99 100 101 102 - 100 101 102 103 101 102 103 104 - 102 103 104 105 103 104 105 106 - 104 105 106 107 105 106 107 108 - 109 110 111 112 110 111 112 113 - 111 112 113 114 112 113 114 115 - 116 117 118 119 117 118 119 120 - 118 119 120 121 119 120 121 122 - 120 121 122 123 123 124 125 126 - 124 125 126 127 125 126 127 128 - 126 127 128 129 127 128 129 130 - 128 129 130 131 129 130 131 132 - 130 131 132 133 131 132 133 134 - 132 133 134 135 136 137 138 139 - 137 138 139 140 138 139 140 141 - 139 140 141 142 143 144 145 146 - 144 145 146 147 145 146 147 148 - 146 147 148 149 147 148 149 150 - 150 151 152 153 151 152 153 154 - 152 153 154 155 153 154 155 156 - 154 155 156 157 155 156 157 158 - 156 157 158 159 157 158 159 160 - 158 159 160 161 159 160 161 162 - 163 164 165 166 164 165 166 167 - 165 166 167 168 166 167 168 169 - 170 171 172 173 171 172 173 174 - 172 173 174 175 173 174 175 176 - 174 175 176 177 177 178 179 180 - 178 179 180 181 179 180 181 182 - 180 181 182 183 181 182 183 184 - 182 183 184 185 183 184 185 186 - 184 185 186 187 185 186 187 188 - 186 187 188 189 190 191 192 193 - 191 192 193 194 192 193 194 195 - 193 194 195 196 197 198 199 200 - 198 199 200 201 199 200 201 202 - 200 201 202 203 201 202 203 204 - 204 205 206 207 205 206 207 208 - 206 207 208 209 207 208 209 210 - 208 209 210 211 209 210 211 212 - 210 211 212 213 211 212 213 214 - 212 213 214 215 213 214 215 216 - - 0 !NIMPHI: impropers - - - 0 !NDON: donors - - - 0 !NACC: acceptors - - - 0 !NNB - - 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 - 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 !NGRP - 0 0 0 - diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+minichaperone/images/protein2x2x2+minichaperones2x2x2_t=0tau_LR.jpg b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+minichaperone/images/protein2x2x2+minichaperones2x2x2_t=0tau_LR.jpg deleted file mode 100644 index c62a881b2a63a86d0c0ccd58dbfd47f523c57fdf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 31162 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 diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+minichaperone/images/protein2x2x2+minichaperones2x2x2_t=67500tau_LR.jpg b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+minichaperone/images/protein2x2x2+minichaperones2x2x2_t=67500tau_LR.jpg deleted file mode 100644 index 38ef54396ee4d0e362d584e99efa28e346fef6a9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26258 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 N_7Q)NwrBi3{a-Y*B@_Sv diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+minichaperone/moltemplate_files/1beadFrustrated.lt b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+minichaperone/moltemplate_files/1beadFrustrated.lt deleted file mode 100644 index e43026ba9f..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+minichaperone/moltemplate_files/1beadFrustrated.lt +++ /dev/null @@ -1,216 +0,0 @@ -# This file defines the "frustrated" coarse-grained protein model used in: -# AI Jewett, A Baumketner and J-E Shea, PNAS, 101 (36), 13192-13197, (2004) -# (http://www.pnas.org/content/101/36/13192) - - -1beadFrustrated { - - # There are 3 atom types (referred to above as B, L, and N) - # Define their masses: - - write_once("Data Masses") { - @atom:B 1.0 - @atom:L 1.0 - @atom:N 1.0 - } - - # AtomID MoleculeID AtomType Charge X Y Z - - write('Data Atoms') { - $atom:a1 $mol @atom:L 0.0 -0.92636654 -1.8409904 -2.1482679 - $atom:a2 $mol @atom:B 0.0 -0.57313354 -1.0670787 -1.6182341 - $atom:a3 $mol @atom:L 0.0 -0.85707399 -1.2358703 -0.69350966 - $atom:a4 $mol @atom:B 0.0 -0.44231274 -0.4584993 -0.23418709 - $atom:a5 $mol @atom:L 0.0 -0.75081182 -0.62868078 0.69786737 - $atom:a6 $mol @atom:B 0.0 -0.36201977 0.11619615 1.2249098 - $atom:a7 $mol @atom:N 0.0 -0.63708237 -0.15973084 2.1723919 - $atom:a8 $mol @atom:N 0.0 0.20516047 0.10417157 2.624901 - $atom:a9 $mol @atom:B 0.0 0.57223743 0.44728103 1.7695617 - $atom:a10 $mol @atom:L 0.0 0.77646279 -0.40630393 1.3168043 - $atom:a11 $mol @atom:B 0.0 0.45475664 -0.2077937 0.40045721 - $atom:a12 $mol @atom:L 0.0 0.72712495 -1.0397637 -0.087614951 - $atom:a13 $mol @atom:B 0.0 0.36971183 -0.85840501 -0.9933019 - $atom:a14 $mol @atom:L 0.0 0.74784336 -1.5700415 -1.5859217 - $atom:a15 $mol @atom:N 0.0 0.43423905 -1.2758917 -2.4853429 - $atom:a16 $mol @atom:N 0.0 0.70583191 -0.30726921 -2.4987711 - $atom:a17 $mol @atom:N 0.0 -0.091688915 0.23323014 -2.2051358 - $atom:a18 $mol @atom:B 0.0 -0.34243283 -0.035822049 -1.2644719 - $atom:a19 $mol @atom:B 0.0 0.41961247 0.18475451 -0.65971014 - $atom:a20 $mol @atom:L 0.0 0.51968465 1.1546791 -0.77877053 - $atom:a21 $mol @atom:L 0.0 -0.40827985 1.2765273 -0.52550748 - $atom:a22 $mol @atom:B 0.0 -0.368141 0.58090904 0.19152224 - $atom:a23 $mol @atom:B 0.0 0.40327249 0.86101769 0.7336255 - $atom:a24 $mol @atom:L 0.0 0.22707289 1.8326235 0.89673346 - $atom:a25 $mol @atom:L 0.0 -0.66500182 1.7285809 1.2783166 - $atom:a26 $mol @atom:B 0.0 -0.39205603 1.0475436 1.9328097 - $atom:a27 $mol @atom:L 0.0 0.25339027 1.5246265 2.5388463 - } - - # bond-ID bond-Type atom-ID atom-ID - - write('Data Bonds') { - $bond:b1 @bond:backbone $atom:a1 $atom:a2 - $bond:b2 @bond:backbone $atom:a2 $atom:a3 - $bond:b3 @bond:backbone $atom:a3 $atom:a4 - $bond:b4 @bond:backbone $atom:a4 $atom:a5 - $bond:b5 @bond:backbone $atom:a5 $atom:a6 - $bond:b6 @bond:backbone $atom:a6 $atom:a7 - $bond:b7 @bond:backbone $atom:a7 $atom:a8 - $bond:b8 @bond:backbone $atom:a8 $atom:a9 - $bond:b9 @bond:backbone $atom:a9 $atom:a10 - $bond:b10 @bond:backbone $atom:a10 $atom:a11 - $bond:b11 @bond:backbone $atom:a11 $atom:a12 - $bond:b12 @bond:backbone $atom:a12 $atom:a13 - $bond:b13 @bond:backbone $atom:a13 $atom:a14 - $bond:b14 @bond:backbone $atom:a14 $atom:a15 - $bond:b15 @bond:backbone $atom:a15 $atom:a16 - $bond:b16 @bond:backbone $atom:a16 $atom:a17 - $bond:b17 @bond:backbone $atom:a17 $atom:a18 - $bond:b18 @bond:backbone $atom:a18 $atom:a19 - $bond:b19 @bond:backbone $atom:a19 $atom:a20 - $bond:b20 @bond:backbone $atom:a20 $atom:a21 - $bond:b21 @bond:backbone $atom:a21 $atom:a22 - $bond:b22 @bond:backbone $atom:a22 $atom:a23 - $bond:b23 @bond:backbone $atom:a23 $atom:a24 - $bond:b24 @bond:backbone $atom:a24 $atom:a25 - $bond:b25 @bond:backbone $atom:a25 $atom:a26 - $bond:b26 @bond:backbone $atom:a26 $atom:a27 - } - - # (3-body) Angles are specified below - - # (4-body) Dihedrals must be defined explicitly for every quartet of atoms. - # (These interactions are not determined by atom type.) - - # dihedral-ID dihedral-Type atom-ID atom-ID atom-ID atom-ID - - write('Data Dihedrals') { - - $dihedral:d1 @dihedral:beta $atom:a1 $atom:a2 $atom:a3 $atom:a4 - $dihedral:d2 @dihedral:beta $atom:a2 $atom:a3 $atom:a4 $atom:a5 - $dihedral:d3 @dihedral:beta $atom:a3 $atom:a4 $atom:a5 $atom:a6 - $dihedral:d4 @dihedral:beta $atom:a4 $atom:a5 $atom:a6 $atom:a7 - - # Dihedral angle forces in the turn regions were switched off - # (in this model) so just I comment them out (and \ the variable names). - # \$dihedral:d5 \@dihedral:turn $atom:a5 $atom:a6 $atom:a7 $atom:a8 - # \$dihedral:d6 \@dihedral:turn $atom:a6 $atom:a7 $atom:a8 $atom:a9 - # \$dihedral:d7 \@dihedral:turn $atom:a7 $atom:a8 $atom:a9 $atom:a10 - - $dihedral:d8 @dihedral:beta $atom:a8 $atom:a9 $atom:a10 $atom:a11 - $dihedral:d9 @dihedral:beta $atom:a9 $atom:a10 $atom:a11 $atom:a12 - $dihedral:d10 @dihedral:beta $atom:a10 $atom:a11 $atom:a12 $atom:a13 - $dihedral:d11 @dihedral:beta $atom:a11 $atom:a12 $atom:a13 $atom:a14 - $dihedral:d12 @dihedral:beta $atom:a12 $atom:a13 $atom:a14 $atom:a15 - - # Dihedral angle forces in the turn regions were switched off - # (in this model) so just I comment them out (and \ the variable names). - # \$dihedral:d13 \@dihedral:turn $atom:a13 $atom:a14 $atom:a15 $atom:a16 - # \$dihedral:d14 \@dihedral:turn $atom:a14 $atom:a15 $atom:a16 $atom:a17 - - $dihedral:d15 @dihedral:alpha $atom:a15 $atom:a16 $atom:a17 $atom:a18 - $dihedral:d16 @dihedral:alpha $atom:a16 $atom:a17 $atom:a18 $atom:a19 - $dihedral:d17 @dihedral:alpha $atom:a17 $atom:a18 $atom:a19 $atom:a20 - $dihedral:d18 @dihedral:alpha $atom:a18 $atom:a19 $atom:a20 $atom:a21 - $dihedral:d19 @dihedral:alpha $atom:a19 $atom:a20 $atom:a21 $atom:a22 - $dihedral:d20 @dihedral:alpha $atom:a20 $atom:a21 $atom:a22 $atom:a23 - $dihedral:d21 @dihedral:alpha $atom:a21 $atom:a22 $atom:a23 $atom:a24 - $dihedral:d22 @dihedral:alpha $atom:a22 $atom:a23 $atom:a24 $atom:a25 - $dihedral:d23 @dihedral:alpha $atom:a23 $atom:a24 $atom:a25 $atom:a26 - $dihedral:d24 @dihedral:alpha $atom:a24 $atom:a25 $atom:a26 $atom:a27 - } - - # All consecutively bonded triplets of atoms same 3-body bond-angle - # interaction parameters. Of coarse, we could specify them all explicitly - # (as we did for the dihedrals above), but I wanted to show how to specify - # angles by atom type instead. (You can do this for dihedrals & impropers - # also.) - - # angle-Type atom-Type atom-Type atom-Type bond-Type bond-Type - - write_once('Data Angles By Type') { - @angle:backbone @atom:* @atom:* @atom:* @bond:* @bond:* - } - - # (The "*" is a wildcard character. I use "*" to denote any atom-type or - # bond-type which is defined within the current namespace: 1beadFrustrated) - - - # 2-body (non-bonded) interactions: - # - # Uij(r) = 4*eps_ij * (K*(sig_ij/r)^12 + L*(sig_ij/r)^6) - # - # i j pairstylename eps sig K L - # - write_once("In Settings") { - pair_coeff @atom:B @atom:B lj/charmm/coul/charmm/inter 1.0 1.0 1 -1 - pair_coeff @atom:B @atom:L lj/charmm/coul/charmm/inter 0.5833333333 1.0 1 0 - pair_coeff @atom:B @atom:N lj/charmm/coul/charmm/inter 0.6666666667 1.0 1 0 - pair_coeff @atom:L @atom:L lj/charmm/coul/charmm/inter 0.1666666667 1.0 1 1 - pair_coeff @atom:L @atom:N lj/charmm/coul/charmm/inter 0.25 1.0 1 0 - pair_coeff @atom:N @atom:N lj/charmm/coul/charmm/inter 0.3333333333 1.0 1 0 - } - - - # 2-body (bonded) interactions: - # - # Ubond(r) = (k/2)*(r-0)^2 - # - # The corresponding command is: - # - # bond-Type bondstylename k r0 - - write_once("In Settings") { - bond_coeff @bond:backbone harmonic 100.0 1.0 - } - - # 3-body interactions in this example are listed by atomType and bondType - # The atomIDs involved are determined automatically. The forumula used is: - # - # Uangle(theta) = (k/2)*(theta-theta0)^2 - # (k in kcal/mol/rad^2, theta0 in degrees) - # - # angle-Type anglestylename k theta0 - - write_once("In Settings") { - angle_coeff @angle:backbone harmonic 13.3333333333 105.0 - } - - - # We use tabular dihedral potentials to implement the dihedral forces. - # (Actually there is a way to use Fourier series, using multiple charmm - # style dihedral interactions, but it's slower and messier.) - - write_once("In Settings") { - # style file keyword - dihedral_coeff @dihedral:alpha table table_dihedral_frustrated.dat FRUSTRATED_ALPHA - dihedral_coeff @dihedral:beta table table_dihedral_frustrated.dat FRUSTRATED_BETA - # No need to specify dihedral interactions in the turn regions. (none exist) - } - - write_once("In Settings") { - # Optional: define the atoms in the "proteins" group - group proteins type @atom:B - group proteins type @atom:L - group proteins type @atom:N - } - - # LAMMPS has many available force field styles (and atom styles). - # Here, we pick the ones which work well for this molecular model: - - write_once("In Init") { - # --- Default options for the "1BeadFrustrated" protein model --- - # --- (These can be overridden later.) --- - units lj - atom_style full - bond_style hybrid harmonic - angle_style hybrid harmonic - dihedral_style hybrid table spline 360 - pair_style hybrid lj/charmm/coul/charmm/inter es4k4l maxmax 3.5 4.0 - pair_modify mix arithmetic - special_bonds lj 0.0 0.0 1.0 #(turn on "1-4" interactions) - } - -} # 1beadFrustrated - - diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+minichaperone/moltemplate_files/1beadFrustrated_variants.lt b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+minichaperone/moltemplate_files/1beadFrustrated_variants.lt deleted file mode 100644 index 54e2de4376..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+minichaperone/moltemplate_files/1beadFrustrated_variants.lt +++ /dev/null @@ -1,85 +0,0 @@ -import "1beadFrustrated.lt" - - -# Alternate starting conformation (same molecule): - - -1beadMisfolded inherits 1beadFrustrated { - - # This molecule "inherits" all of its features from "1beadFrustrated". - # Here we override the atomic positions with new coordinates: - - # AtomID MoleculeID AtomType Charge X Y Z - - write("Data Atoms") { - $atom:a1 $mol @atom:L 0.0 -0.69801399 -0.22114168 -1.9464876 - $atom:a2 $mol @atom:B 0.0 -0.40921658 -0.027063664 -1.0033251 - $atom:a3 $mol @atom:L 0.0 0.10259348 0.80836418 -1.0737085 - $atom:a4 $mol @atom:B 0.0 0.25857916 1.0054984 -0.11621451 - $atom:a5 $mol @atom:L 0.0 0.8258629 1.8325549 -0.18529135 - $atom:a6 $mol @atom:B 0.0 0.91366257 2.1950317 0.74175977 - $atom:a7 $mol @atom:N 0.0 1.4399539 1.554238 1.2994409 - $atom:a8 $mol @atom:N 0.0 0.73372573 1.0161012 1.7397275 - $atom:a9 $mol @atom:B 0.0 0.26608782 0.65302497 0.94353938 - $atom:a10 $mol @atom:L 0.0 0.97442305 0.13574211 0.50586398 - $atom:a11 $mol @atom:B 0.0 0.35889617 -0.18247555 -0.1764186 - $atom:a12 $mol @atom:L 0.0 0.87151735 -0.77260824 -0.75240916 - $atom:a13 $mol @atom:B 0.0 0.047726486 -1.0530682 -1.1902704 - $atom:a14 $mol @atom:L 0.0 0.34530697 -1.7476773 -1.8393331 - $atom:a15 $mol @atom:N 0.0 0.65865186 -2.45948 -1.2167056 - $atom:a16 $mol @atom:N 0.0 -0.16534524 -2.6219442 -0.67112167 - $atom:a17 $mol @atom:N 0.0 -0.010590421 -2.2445242 0.24748633 - $atom:a18 $mol @atom:B 0.0 0.18135771 -1.2564919 0.1767523 - $atom:a19 $mol @atom:B 0.0 -0.57472665 -0.82852797 -0.27027791 - $atom:a20 $mol @atom:L 0.0 -1.3967448 -1.0516787 0.24247346 - $atom:a21 $mol @atom:L 0.0 -1.003428 -0.85642681 1.1107555 - $atom:a22 $mol @atom:B 0.0 -0.25156735 -0.3182346 0.74262946 - $atom:a23 $mol @atom:B 0.0 -0.61751956 0.30115562 0.070426493 - $atom:a24 $mol @atom:L 0.0 -1.3347934 0.83310182 0.52625934 - $atom:a25 $mol @atom:L 0.0 -0.83315257 1.270904 1.2564086 - $atom:a26 $mol @atom:B 0.0 -0.10469759 1.6988523 0.72597181 - $atom:a27 $mol @atom:L 0.0 -0.57854905 2.3367737 0.11206868 - } - -} # 1beadMisfolded - - -1beadUnfolded inherits 1beadFrustrated { - - # This molecule "inherits" all of its features from "1beadFrustrated" - # Here we override the atomic positions with new coordinates: - - # AtomID MoleculeID AtomType Charge X Y Z - - write('Data Atoms') { - $atom:a1 $mol @atom:L 0.0 -2.4 1.7 -0.0 - $atom:a2 $mol @atom:B 0.0 -1.8 1.7 0.8 - $atom:a3 $mol @atom:L 0.0 -1.2 2.5 0.8 - $atom:a4 $mol @atom:B 0.0 -0.6 2.5 -0.0 - $atom:a5 $mol @atom:L 0.0 0.0 1.7 -0.0 - $atom:a6 $mol @atom:B 0.0 0.6 1.7 0.8 - $atom:a7 $mol @atom:N 0.0 1.2 2.5 0.8 - $atom:a8 $mol @atom:N 0.0 1.8 2.5 -0.0 - $atom:a9 $mol @atom:B 0.0 2.4 1.7 -0.0 - $atom:a10 $mol @atom:L 0.0 3.0 1.7 -0.8 - $atom:a11 $mol @atom:B 0.0 3.0 0.7 -0.8 - $atom:a12 $mol @atom:L 0.0 3.0 0.1 -0.0 - $atom:a13 $mol @atom:B 0.0 3.8 -0.5 -0.0 - $atom:a14 $mol @atom:L 0.0 3.8 -1.1 -0.8 - $atom:a15 $mol @atom:N 0.0 3.0 -1.7 -0.8 - $atom:a16 $mol @atom:N 0.0 3.0 -1.7 0.2 - $atom:a17 $mol @atom:N 0.0 2.4 -2.5 0.2 - $atom:a18 $mol @atom:B 0.0 1.8 -2.5 -0.6 - $atom:a19 $mol @atom:B 0.0 1.2 -1.7 -0.6 - $atom:a20 $mol @atom:L 0.0 0.6 -1.7 0.2 - $atom:a21 $mol @atom:L 0.0 -0.0 -2.5 0.2 - $atom:a22 $mol @atom:B 0.0 -0.6 -2.5 -0.6 - $atom:a23 $mol @atom:B 0.0 -1.2 -1.7 -0.6 - $atom:a24 $mol @atom:L 0.0 -1.8 -1.7 0.2 - $atom:a25 $mol @atom:L 0.0 -2.4 -2.5 0.2 - $atom:a26 $mol @atom:B 0.0 -3.0 -2.5 -0.6 - $atom:a27 $mol @atom:L 0.0 -3.6 -1.7 -0.6 - } - -} # 1beadUnfolded - diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+minichaperone/moltemplate_files/generate_tables/calc_chaperone_table.py b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+minichaperone/moltemplate_files/generate_tables/calc_chaperone_table.py deleted file mode 100755 index 9b86809cc3..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+minichaperone/moltemplate_files/generate_tables/calc_chaperone_table.py +++ /dev/null @@ -1,87 +0,0 @@ -#!/usr/bin/env python - -# Calculate a table of pairwise energies and forces between atoms in the -# protein and a chaperone provided in the supplemental materials section of: -# AI Jewett, A Baumketner and J-E Shea, PNAS, 101 (36), 13192-13197, (2004) -# This is stored in a tabulated force field with a singularity at a distance R. -# -# To calculate the table for interaction between -# ...the chaperone and a hydrophobic bead (2004 PNAS paper), use this table: -# ./calc_chaperone_table.py 1.0 1.0 6.0 0.475 0.0 5.9 1181 -# ...the chaperone and a hydrophilic bead (2004 PNAS paper), use this table: -# ./calc_chaperone_table.py 1.0 1.0 6.0 0.0 0.0 5.9 1181 -# ...the chaperone and a hydrophobic bead (2006 JMB paper), use this table: -# ./calc_chaperone_table.py 1.0 1.0 3.0 0.60 3.1 8.0 981 True -# ...the chaperone and a hydrophilic bead (2006 JMB paper), use this table: -# ./calc_chaperone_table.py 1.0 1.0 3.0 0.0 3.1 8.0 981 True - -from math import * -import sys - -def U(r, eps, sigma, R, h): - #print('r='+str(r)+' eps='+str(eps)+' s='+str(sigma)+' R='+str(R)+' h='+str(h)) - # Formula is undefined at r=0, but you can take the limit: - if r <= 0: - return 4.0*pi*R*R*4.0*eps*(pow((sigma/R), 12.0) - - h*pow((sigma/R), 6.0)) - xp = sigma/(r+R) - xm = sigma/(r-R) - term10 = pow(xm, 10.0) - pow(xp, 10.0) - term4 = pow(xm, 4.0) - pow(xp, 4.0) - return 4.0*pi*eps*(R/r) * (0.2*term10 - 0.5*h*term4) - -def F(r, eps, sigma, R, h): - # Formula is undefined at r=0, but you can take the limit: - if r <= 0: - return 0.0 - product_term_a = U(r, eps, sigma, R, h) / r - ixp = (r+R)/sigma - ixm = (r-R)/sigma - dix_dr = 1.0/sigma - term10 = (10.0/sigma)*(pow(ixm, -11.0) - pow(ixp, -11.0)) - term4 = (4.0/sigma)*(pow(ixm, -5.0) - pow(ixp, -5.0)) - product_term_b = 4.0*eps*pi*(R/r) * (0.2*term10 - 0.5*h*term4) - return product_term_a + product_term_b - - -class InputError(Exception): - """ A generic exception object containing a string for error reporting. - - """ - def __init__(self, err_msg): - self.err_msg = err_msg - def __str__(self): - return self.err_msg - def __repr__(self): - return str(self) - -if len(sys.argv) < 8: - sys.stderr.write("Error: expected 7 arguments:\n" - "\n" - "Usage: "+sys.argv[0]+" epsilon sigma R h rmin rmax N\n\n") - sys.exit(-1) - -epsilon = float(sys.argv[1]) -sigma = float(sys.argv[2]) -R = float(sys.argv[3]) -h = float(sys.argv[4]) -rmin = float(sys.argv[5]) -rmax = float(sys.argv[6]) -N = int(sys.argv[7]) - -subtract_Urcut = False -if len(sys.argv) == 9: - subtract_Urcut = True -rcut = rmax - -for i in range(0,N): - r = rmin + i*(rmax-rmin)/(N-1) - U_r = U(r, epsilon, sigma, R, h) - F_r = F(r, epsilon, sigma, R, h) - if subtract_Urcut: - U_r -= U(rcut, epsilon, sigma, R, h) - if (r >= rcut) or (i==N-1): - U_r = 0.0 - F_r = 0.0 - print(str(i+1)+' '+str(r)+' '+str(U_r)+' '+str(F_r)) - diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+minichaperone/moltemplate_files/generate_tables/calc_dihedral_table.py b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+minichaperone/moltemplate_files/generate_tables/calc_dihedral_table.py deleted file mode 100755 index 34c66418a8..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+minichaperone/moltemplate_files/generate_tables/calc_dihedral_table.py +++ /dev/null @@ -1,67 +0,0 @@ -#!/usr/bin/env python - -# Calculate a table of dihedral angle interactions used in the alpha-helix -# and beta-sheet regions of the frustrated protein model described in -# provided in figure 8 of the supplemental materials section of: -# AI Jewett, A Baumketner and J-E Shea, PNAS, 101 (36), 13192-13197, (2004) -# Note that the "A" and "B" parameters were incorrectly reported to be -# 5.4*epsilon and 6.0*epsilon. The values used were 5.6 and 6.0 epsilon. -# The phiA and phiB values were 57.29577951308232 degrees (1 rad) -# and 180 degrees, respectively. Both expA and expB were 6.0. -# -# To generate the table used for the alpha-helix (1 degree resolution) use this: -# ./calc_dihedral_table.py 6.0 57.29577951308232 6 5.6 180 6 0.0 359 360 -# To generate the table used for the beta-sheets (1 degree resolution) use this: -# ./calc_dihedral_table.py 5.6 57.29577951308232 6 6.0 180 6 0.0 359 360 -# -# (If you're curious as to why I set the location of the minima at phi_alpha -# to 1.0 radians (57.2957795 degrees), there was no particularly good reason. -# I think the correct value turns out to be something closer to 50 degrees.) - - -from math import * -import sys - - -# The previous version included the repulsive core term -def U(phi, A, phiA, expA, B, phiB, expB, use_radians=False): - conv_units = pi/180.0 - if use_radians: - conv_units = 1.0 - termA = pow(cos(0.5*(phi-phiA)*conv_units), expA) - termB = pow(cos(0.5*(phi-phiB)*conv_units), expB) - return -A*termA - B*termB - -# The previous version included the repulsive core term -def F(phi, A, phiA, expA, B, phiB, expB, use_radians=False): - conv_units = pi/180.0 - if use_radians: - conv_units = 1.0 - termA = (0.5*sin(0.5*(phi-phiA)*conv_units) * - expA * pow(cos(0.5*(phi-phiA)*conv_units), expA-1.0)) - termB = (0.5*sin(0.5*(phi-phiB)*conv_units) * - expB * pow(cos(0.5*(phi-phiB)*conv_units), expB-1.0)) - return -conv_units*(A*termA + B*termB) - -if len(sys.argv) != 10: - sys.stderr.write("Error: expected 9 arguments:\n" - "\n" - "Usage: "+sys.argv[0]+" A phiA expA B phiB expB phiMin phiMax N\n\n") - sys.exit(-1) - -A = float(sys.argv[1]) -phiA = float(sys.argv[2]) -expA = float(sys.argv[3]) -B = float(sys.argv[4]) -phiB = float(sys.argv[5]) -expB = float(sys.argv[6]) -phi_min = float(sys.argv[7]) -phi_max = float(sys.argv[8]) -N = int(sys.argv[9]) - -for i in range(0,N): - phi = phi_min + i*(phi_max - phi_min)/(N-1) - U_phi = U(phi, A, phiA, expA, B, phiB, expB, use_radians=False) - F_phi = F(phi, A, phiA, expA, B, phiB, expB, use_radians=False) - print(str(i+1)+' '+str(phi)+' '+str(U_phi)+' '+str(F_phi)) - diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+minichaperone/moltemplate_files/minichaperone.lt b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+minichaperone/moltemplate_files/minichaperone.lt deleted file mode 100644 index 1d37823b7a..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+minichaperone/moltemplate_files/minichaperone.lt +++ /dev/null @@ -1,41 +0,0 @@ -# Here we define a trivial molecule containing only one particle. - -Minichaperone { - - # atomID molID atomType charge x y z - - write("Data Atoms") { - $atom:C $mol @atom:C 0.0 0.0 0.0 0.0 - } - - write_once("Data Masses") { - @atom:C 100.0 - } - - write_once("In Settings") { - # If for some reason there are multiple chaperones present, - # I assume that they interact repulsively (hence, L=0) - - # i j pairStyle eps sig K L - - pair_coeff @atom:C @atom:C lj/charmm/coul/charmm/inter 1.0 3.0 1 0 - - # Optional: define the atoms in the "chaperonins" group: - # (Defining a group for the chaperone makes it easy to immobilize it later.) - - group chaperones type @atom:C - } - - # Specify which pair_styles, and atom styles work well with - # this model. (Again this can be overridden later.) - - write_once("In Init") { - units lj - atom_style full - pair_style hybrid lj/charmm/coul/charmm/inter es4k4l maxmax 8.0 9.0 - } - -} # Minichaperone - -# We have not specified how this particle interacts with other particles -# besides itself. Later on you must do this. diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+minichaperone/moltemplate_files/system.lt b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+minichaperone/moltemplate_files/system.lt deleted file mode 100644 index 8f8c37d08b..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+minichaperone/moltemplate_files/system.lt +++ /dev/null @@ -1,72 +0,0 @@ -write_once("Data Boundary") { - 0.0 80.0 xlo xhi - 0.0 80.0 ylo yhi - 0.0 80.0 zlo zhi -} - - -import "1beadFrustrated_variants.lt" -import "minichaperone.lt" - - -# Create 8 proteins and 8 chaperones (2x2x2 array): -# NOTE: Below I create multiple proteins and multiple chaperones -# to see what would happen. (I suspect nothing good. In the -# 2006 paper, only 1 protein and 1 chaperone were present.) - - -proteins = new 1beadUnfolded [2].move(40,0,0) - [2].move(0,40,0) - [2].move(0,0,40) - -chaperones = new Minichaperone [2].move(40,0,0) - [2].move(0,40,0) - [2].move(0,0,40) - -proteins[*][*][*].move(20,20,20) # to avoid overlap with the chaperones - - - -# If you only want 1 protein and 1 chaperone -# then replace the lines above with: -# -# protein = new 1beadMisfolded -# chaperone = new Minichaperone - - - - - -# ---- Now define interactions between the atoms in the protein ---- -# ---- (named "B", "L", "N") and the atom which represents the ---- -# ---- chaperone ("c"). These interactions are tabulated. ---- - -write_once("In Settings") { - pair_coeff @atom:Minichaperone/C @atom:1beadFrustrated/B table table_minichaperone_h=0.6.dat CH_H0.6 - pair_coeff @atom:Minichaperone/C @atom:1beadFrustrated/L table table_minichaperone_h=0.dat CH_H0 - pair_coeff @atom:Minichaperone/C @atom:1beadFrustrated/N table table_minichaperone_h=0.dat CH_H0 -} - -# Note: If you want purely repulsive spheres (crowding, h=0.0) -# instead of an attractive "hydrophobic" chaperone (h=0.6) -# then replace "table_minichaperone_h=0_6.dat CH_H0_6" -# with "table_minichaperone_h=0.dat CH_H0" -# (... or just use an ordinary Lennard-Jones interaction -# with sigma = 6.0 and epsilon near 0.0) - - -# LAMMPS has many available force field styles (and atom styles). Here we -# select the ones which work well for the full combine system. (This should -# override any settings made in "1beadFrustrated.lt" or "minichaperone.lt") - - -write_once("In Init") { - units lj - atom_style full - bond_style hybrid harmonic - angle_style hybrid harmonic - dihedral_style hybrid table spline 360 - pair_style hybrid lj/charmm/coul/charmm/inter es4k4l maxmax 3.5 4.0 table spline 981 - pair_modify mix arithmetic - special_bonds lj 0.0 0.0 1.0 #(turn on "1-4" interactions) -} diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+minichaperone/moltemplate_files/table_dihedral_frustrated.dat b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+minichaperone/moltemplate_files/table_dihedral_frustrated.dat deleted file mode 100644 index d660fee308..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+minichaperone/moltemplate_files/table_dihedral_frustrated.dat +++ /dev/null @@ -1,735 +0,0 @@ -# Table of the potential and its negative derivative for frustrated alpha helix -# (Note: Derivatives are in units of energy/radians, not energy/degrees.) -# ./calc_dihedral_table.py 6.0 57.29577951308232 6 5.6 180 6 0.0 359 360 - -FRUSTRATED_ALPHA -N 360 DEGREES - -1 0.0 -2.74081145103 0.0783990792662 -2 1.0 -2.81950869101 0.0789852583442 -3 2.0 -2.89876136749 0.0795096391909 -4 3.0 -2.97850675562 0.0799703813963 -5 4.0 -3.05868032959 0.0803657243943 -6 5.0 -3.13921584545 0.0806939935737 -7 6.0 -3.22004543014 0.0809536062381 -8 7.0 -3.30109967628 0.0811430773977 -9 8.0 -3.38230774267 0.0812610253741 -10 9.0 -3.46359746038 0.0813061772009 -11 10.0 -3.54489544401 0.0812773738039 -12 11.0 -3.62612720812 0.0811735749433 -13 12.0 -3.70721728841 0.0809938639029 -14 13.0 -3.78808936748 0.080737451911 -15 14.0 -3.86866640485 0.0804036822781 -16 15.0 -3.94887077101 0.0799920342374 -17 16.0 -4.02862438516 0.0795021264757 -18 17.0 -4.10784885622 0.0789337203415 -19 18.0 -4.18646562704 0.0782867227197 -20 19.0 -4.26439612115 0.0775611885609 -21 20.0 -4.34156189202 0.0767573230567 -22 21.0 -4.41788477419 0.0758754834523 -23 22.0 -4.49328703609 0.0749161804868 -24 23.0 -4.56769153408 0.0738800794563 -25 24.0 -4.64102186743 0.0727680008923 -26 25.0 -4.71320253365 0.0715809208518 -27 26.0 -4.78415908407 0.0703199708131 -28 27.0 -4.85381827903 0.0689864371778 -29 28.0 -4.92210824234 0.067581760373 -30 29.0 -4.98895861476 0.0661075335571 -31 30.0 -5.05430070586 0.0645655009259 -32 31.0 -5.11806764409 0.0629575556235 -33 32.0 -5.18019452449 0.061285737258 -34 33.0 -5.24061855376 0.0595522290273 -35 34.0 -5.29927919225 0.0577593544584 -36 35.0 -5.3561182925 0.0559095737673 -37 36.0 -5.41108023395 0.0540054798439 -38 37.0 -5.46411205346 0.0520497938726 -39 38.0 -5.51516357127 0.0500453605949 -40 39.0 -5.56418751203 0.0479951432253 -41 40.0 -5.61113962059 0.0459022180302 -42 41.0 -5.65597877221 0.0437697685824 -43 42.0 -5.69866707689 0.0416010797029 -44 43.0 -5.7391699774 0.0393995311046 -45 44.0 -5.77745634094 0.0371685907508 -46 45.0 -5.81349854393 0.034911807945 -47 46.0 -5.84727254977 0.0326328061676 -48 47.0 -5.87875797937 0.030335275675 -49 48.0 -5.90793817411 0.0280229658805 -50 49.0 -5.93480025113 0.0256996775336 -51 50.0 -5.95933515063 0.0233692547166 -52 51.0 -5.98153767519 0.0210355766777 -53 52.0 -6.00140652074 0.0187025495211 -54 53.0 -6.01894429926 0.016374097773 -55 54.0 -6.03415755288 0.0140541558448 -56 55.0 -6.04705675953 0.0117466594146 -57 56.0 -6.05765632981 0.00945553674764 -58 57.0 -6.06597459526 0.00718469997761 -59 58.0 -6.07203378786 0.00493803637051 -60 59.0 -6.07586001075 0.00271939959245 -61 60.0 -6.07748320034 0.000532601003776 -62 61.0 -6.07693707962 -0.00161859899905 -63 62.0 -6.07425910291 -0.00373049957158 -64 63.0 -6.06949039207 -0.00579946791801 -65 64.0 -6.06267566421 -0.00782194767468 -66 65.0 -6.05386315117 -0.00979446715893 -67 66.0 -6.04310451074 -0.0117136474624 -68 67.0 -6.03045472992 -0.0135762103679 -69 68.0 -6.01597202036 -0.0153789860691 -70 69.0 -5.99971770618 -0.0171189206741 -71 70.0 -5.98175610439 -0.0187930834719 -72 71.0 -5.9621543982 -0.0203986739443 -73 72.0 -5.9409825034 -0.0219330285036 -74 73.0 -5.91831292823 -0.0233936269399 -75 74.0 -5.89422062685 -0.0247780985587 -76 75.0 -5.86878284696 -0.0260842279959 -77 76.0 -5.84207897162 -0.0273099606906 -78 77.0 -5.81419035593 -0.0284534080045 -79 78.0 -5.78520015867 -0.0295128519729 -80 79.0 -5.7551931694 -0.0304867496727 -81 80.0 -5.72425563141 -0.0313737371989 -82 81.0 -5.6924750609 -0.0321726332348 -83 82.0 -5.65994006273 -0.0328824422092 -84 83.0 -5.62674014332 -0.0335023570292 -85 84.0 -5.59296552097 -0.0340317613814 -86 85.0 -5.55870693409 -0.0344702315961 -87 86.0 -5.52405544786 -0.0348175380654 -88 87.0 -5.48910225957 -0.0350736462148 -89 88.0 -5.45393850338 -0.0352387170203 -90 89.0 -5.41865505462 -0.0353131070729 -91 90.0 -5.38334233438 -0.0352973681855 -92 91.0 -5.34809011465 -0.0351922465446 -93 92.0 -5.31298732458 -0.0349986814067 -94 93.0 -5.27812185824 -0.034717803342 -95 94.0 -5.24358038438 -0.0343509320285 -96 95.0 -5.2094481586 -0.0338995736008 -97 96.0 -5.17580883839 -0.0333654175598 -98 97.0 -5.14274430152 -0.0327503332496 -99 98.0 -5.11033446814 -0.0320563659092 -100 99.0 -5.07865712698 -0.0312857323082 -101 100.0 -5.04778776623 -0.0304408159764 -102 101.0 -5.01779940929 -0.0295241620384 -103 102.0 -4.98876245596 -0.0285384716647 -104 103.0 -4.96074452928 -0.0274865961525 -105 104.0 -4.93381032851 -0.0263715306507 -106 105.0 -4.90802148862 -0.0251964075427 -107 106.0 -4.88343644644 -0.0239644895038 -108 107.0 -4.86011031397 -0.0226791622487 -109 108.0 -4.83809475914 -0.0213439269874 -110 109.0 -4.81743789414 -0.0199623926068 -111 110.0 -4.79818417182 -0.0185382675969 -112 111.0 -4.78037429015 -0.0170753517415 -113 112.0 -4.76404510526 -0.0155775275918 -114 113.0 -4.74922955293 -0.0140487517461 -115 114.0 -4.73595657904 -0.0124930459538 -116 115.0 -4.7242510789 -0.0109144880672 -117 116.0 -4.71413384576 -0.00931720286182 -118 117.0 -4.70562152846 -0.00770535274772 -119 118.0 -4.69872659855 -0.00608312839491 -120 119.0 -4.69345732669 -0.00445473929448 -121 120.0 -4.6898177686 -0.00282440427898 -122 121.0 -4.68780776044 -0.00119634202478 -123 122.0 -4.68742292374 0.000425238440527 -124 123.0 -4.68865467977 0.0020361472029 -125 124.0 -4.69149027336 0.00363222287571 -126 125.0 -4.69591280613 0.00520934194008 -127 126.0 -4.70190127895 0.0067634279891 -128 127.0 -4.70943064365 0.00829046085365 -129 128.0 -4.71847186379 0.00978648558781 -130 129.0 -4.72899198423 0.0112476212922 -131 130.0 -4.74095420961 0.0126700697544 -132 131.0 -4.7543179912 0.0140501238848 -133 132.0 -4.76903912216 0.0153841759291 -134 133.0 -4.78506984093 0.0166687254364 -135 134.0 -4.80235894235 0.0179003869651 -136 135.0 -4.82085189642 0.0190758975074 -137 136.0 -4.84049097437 0.0201921236154 -138 137.0 -4.86121538156 0.0212460682116 -139 138.0 -4.88296139722 0.0222348770682 -140 139.0 -4.90566252032 0.0231558449399 -141 140.0 -4.9292496215 0.0240064213355 -142 141.0 -4.95365110055 0.0247842159162 -143 142.0 -4.97879304911 0.0254870035063 -144 143.0 -5.00459941816 0.0261127287073 -145 144.0 -5.03099218995 0.0266595101027 -146 145.0 -5.05789155387 0.0271256440463 -147 146.0 -5.08521608601 0.0275096080241 -148 147.0 -5.11288293171 0.0278100635833 -149 148.0 -5.14080799097 0.0280258588231 -150 149.0 -5.16890610603 0.0281560304409 -151 150.0 -5.19709125082 0.0281998053314 -152 151.0 -5.22527672173 0.0281566017347 -153 152.0 -5.25337532941 0.0280260299338 -154 153.0 -5.28129959092 0.0278078924984 -155 154.0 -5.30896192196 0.0275021840788 -156 155.0 -5.33627482866 0.0271090907491 -157 156.0 -5.36315109852 0.0266289889046 -158 157.0 -5.38950398994 0.026062443717 -159 158.0 -5.41524742011 0.0254102071518 -160 159.0 -5.44029615055 0.0246732155563 -161 160.0 -5.46456597019 0.0238525868232 -162 161.0 -5.48797387528 0.0229496171403 -163 162.0 -5.51043824587 0.0219657773349 -164 163.0 -5.53187901853 0.0209027088232 -165 164.0 -5.55221785468 0.0197622191769 -166 165.0 -5.57137830441 0.0185462773191 -167 166.0 -5.58928596528 0.0172570083629 -168 167.0 -5.60586863576 0.0158966881068 -169 168.0 -5.62105646307 0.0144677372016 -170 169.0 -5.63478208493 0.0129727150063 -171 170.0 -5.64698076513 0.0114143131467 -172 171.0 -5.65759052241 0.00979534879707 -173 172.0 -5.66655225257 0.00811875770075 -174 173.0 -5.67380984344 0.00638758694863 -175 174.0 -5.67931028251 0.00460498753534 -176 175.0 -5.68300375706 0.00277420671195 -177 176.0 -5.68484374646 0.000898580155594 -178 177.0 -5.68478710669 -0.00101847602368 -179 178.0 -5.68279414663 -0.00297347341791 -180 179.0 -5.67882869631 -0.00496285957718 -181 180.0 -5.67285816674 -0.00698302636509 -182 181.0 -5.6648536014 -0.00903031839234 -183 182.0 -5.65478971926 -0.0111010415069 -184 183.0 -5.64264494925 -0.0131914713189 -185 184.0 -5.62840145627 -0.0152978617389 -186 185.0 -5.6120451586 -0.017416453508 -187 186.0 -5.59356573683 -0.0195434826976 -188 187.0 -5.57295663425 -0.0216751891584 -189 188.0 -5.55021504898 -0.0238078248974 -190 189.0 -5.52534191754 -0.0259376623617 -191 190.0 -5.4983418904 -0.0280610026087 -192 191.0 -5.46922329932 -0.0301741833429 -193 192.0 -5.43799811672 -0.0322735868002 -194 193.0 -5.40468190731 -0.0343556474589 -195 194.0 -5.36929377207 -0.0364168595607 -196 195.0 -5.33185628476 -0.0384537844225 -197 196.0 -5.29239542138 -0.0404630575223 -198 197.0 -5.25094048245 -0.0424413953416 -199 198.0 -5.20752400881 -0.0443856019501 -200 199.0 -5.16218169074 -0.0462925753151 -201 200.0 -5.11495227114 -0.0481593133234 -202 201.0 -5.06587744261 -0.0499829195012 -203 202.0 -5.01500173918 -0.0517606084187 -204 203.0 -4.96237242264 -0.0534897107689 -205 204.0 -4.90803936404 -0.055167678109 -206 205.0 -4.85205492059 -0.0567920872546 -207 206.0 -4.79447380837 -0.0583606443179 -208 207.0 -4.73535297113 -0.0598711883816 -209 208.0 -4.6747514457 -0.0613216948024 -210 209.0 -4.61273022413 -0.0627102781377 -211 210.0 -4.54935211328 -0.0640351946902 -212 211.0 -4.4846815919 -0.0652948446678 -213 212.0 -4.41878466581 -0.0664877739558 -214 213.0 -4.35172872155 -0.0676126754981 -215 214.0 -4.28358237872 -0.0686683902899 -216 215.0 -4.21441534165 -0.0696539079796 -217 216.0 -4.14429825061 -0.070568367083 -218 217.0 -4.07330253293 -0.0714110548116 -219 218.0 -4.00150025463 -0.0721814065199 -220 219.0 -3.92896397266 -0.072879004774 -221 220.0 -3.85576658834 -0.0735035780505 -222 221.0 -3.78198120223 -0.0740549990687 -223 222.0 -3.70768097086 -0.0745332827669 -224 223.0 -3.63293896573 -0.0749385839297 -225 224.0 -3.5578280347 -0.0752711944755 -226 225.0 -3.48242066643 -0.075531540416 -227 226.0 -3.4067888579 -0.0757201784978 -228 227.0 -3.33100398548 -0.0758377925383 -229 228.0 -3.25513667985 -0.0758851894693 -230 229.0 -3.17925670492 -0.0758632951011 -231 230.0 -3.10343284123 -0.0757731496217 -232 231.0 -3.02773277394 -0.0756159028468 -233 232.0 -2.95222298559 -0.0753928092342 -234 233.0 -2.87696865416 -0.0751052226812 -235 234.0 -2.80203355622 -0.0747545911191 -236 235.0 -2.72747997572 -0.0743424509249 -237 236.0 -2.65336861841 -0.073870421164 -238 237.0 -2.57975853208 -0.0733401976859 -239 238.0 -2.50670703279 -0.0727535470871 -240 239.0 -2.4342696372 -0.0721123005638 -241 240.0 -2.36250000104 -0.0714183476691 -242 241.0 -2.29144986396 -0.0706736299971 -243 242.0 -2.22116900065 -0.0698801348102 -244 243.0 -2.15170517837 -0.0690398886302 -245 244.0 -2.0831041209 -0.0681549508121 -246 245.0 -2.01540947892 -0.067227407119 -247 246.0 -1.94866280684 -0.0662593633171 -248 247.0 -1.88290354594 -0.0652529388105 -249 248.0 -1.81816901389 -0.0642102603325 -250 249.0 -1.7544944006 -0.0631334557138 -251 250.0 -1.69191277013 -0.0620246477436 -252 251.0 -1.6304550688 -0.0608859481423 -253 252.0 -1.57015013921 -0.059719451663 -254 253.0 -1.51102474011 -0.0585272303374 -255 254.0 -1.45310357187 -0.0573113278834 -256 255.0 -1.39640930762 -0.0560737542899 -257 256.0 -1.34096262951 -0.054816480593 -258 257.0 -1.28678227024 -0.0535414338587 -259 258.0 -1.23388505944 -0.0522504923856 -260 259.0 -1.18228597475 -0.0509454811405 -261 260.0 -1.13199819729 -0.0496281674395 -262 261.0 -1.08303317143 -0.0483002568854 -263 262.0 -1.03540066834 -0.046963389572 -264 263.0 -0.989108853377 -0.0456191365664 -265 264.0 -0.944164356669 -0.0442689966762 -266 265.0 -0.900572346917 -0.0429143935113 -267 266.0 -0.858336607922 -0.0415566728462 -268 267.0 -0.817459617608 -0.0401971002897 -269 268.0 -0.777942629232 -0.0388368592669 -270 269.0 -0.739785754436 -0.0374770493178 -271 270.0 -0.702988047855 -0.0361186847156 -272 271.0 -0.667547592939 -0.0347626934072 -273 272.0 -0.633461588675 -0.0334099162773 -274 273.0 -0.600726436882 -0.0320611067354 -275 274.0 -0.569337829756 -0.0307169306269 -276 275.0 -0.539290837348 -0.0293779664649 -277 276.0 -0.510579994645 -0.0280447059807 -278 277.0 -0.483199387947 -0.0267175549897 -279 278.0 -0.457142740217 -0.0253968345674 -280 279.0 -0.432403495111 -0.0240827825309 -281 280.0 -0.408974899365 -0.0227755552188 -282 281.0 -0.386850083265 -0.0214752295619 -283 282.0 -0.366022138902 -0.020181805438 -284 283.0 -0.346484195932 -0.0188952082997 -285 284.0 -0.328229494574 -0.0176152920667 -286 285.0 -0.311251455597 -0.0163418422722 -287 286.0 -0.295543747024 -0.0150745794496 -288 287.0 -0.28110034735 -0.0138131627512 -289 288.0 -0.267915605017 -0.0125571937823 -290 289.0 -0.255984293962 -0.011306220639 -291 290.0 -0.245301665026 -0.0100597421363 -292 291.0 -0.235863493049 -0.00881721220956 -293 292.0 -0.22766611948 -0.00757804447631 -294 293.0 -0.220706490355 -0.00634161694135 -295 294.0 -0.214982189503 -0.00510727682957 -296 295.0 -0.210491466861 -0.00387434552992 -297 296.0 -0.207233261801 -0.00264212363344 -298 297.0 -0.205207221373 -0.00140989604849 -299 298.0 -0.204413713408 -0.00017693717569 -300 299.0 -0.204853834414 0.0010574838751 -301 300.0 -0.206529412255 0.00229409804323 -302 301.0 -0.209443003569 0.00353363106913 -303 302.0 -0.213597885954 0.00477679825726 -304 303.0 -0.218998044922 0.00602429926791 -305 304.0 -0.22564815567 0.00727681295572 -306 305.0 -0.23355355972 0.00853499227222 -307 306.0 -0.2427202365 0.00979945924997 -308 307.0 -0.253154769958 0.0110708000854 -309 308.0 -0.264864310313 0.0123495603372 -310 309.0 -0.277856531075 0.0136362402565 -311 310.0 -0.292139581459 0.0149312902659 -312 311.0 -0.307722034364 0.0162351066015 -313 312.0 -0.324612830087 0.0175480271349 -314 313.0 -0.342821215943 0.0188703273888 -315 314.0 -0.362356682012 0.0202022167596 -316 315.0 -0.383228893218 0.0215438349636 -317 316.0 -0.405447617967 0.0228952487148 -318 317.0 -0.429022653586 0.0242564486517 -319 318.0 -0.45396374882 0.0256273465206 -320 319.0 -0.480280523637 0.0270077726275 -321 320.0 -0.507982386639 0.0283974735696 -322 321.0 -0.537078450328 0.029796110253 -323 322.0 -0.567577444555 0.0312032562068 -324 323.0 -0.59948762842 0.0326183962009 -325 324.0 -0.632816700956 0.0340409251716 -326 325.0 -0.667571710883 0.0354701474639 -327 326.0 -0.703758965776 0.0369052763923 -328 327.0 -0.741383940946 0.038345434125 -329 328.0 -0.780451188376 0.0397896518935 -330 329.0 -0.820964246018 0.0412368705304 -331 330.0 -0.862925547807 0.042685941334 -332 331.0 -0.906336334692 0.0441356272615 -333 332.0 -0.951196567028 0.045584604448 -334 333.0 -0.997504838648 0.0470314640498 -335 334.0 -1.04525829294 0.048474714408 -336 335.0 -1.09445254125 0.0499127835288 -337 336.0 -1.1450815839 0.0513440218749 -338 337.0 -1.1971377342 0.0527667054614 -339 338.0 -1.25061154564 0.0541790392498 -340 339.0 -1.30549174267 0.0555791608316 -341 340.0 -1.36176515529 0.0569651443923 -342 341.0 -1.41941665773 0.0583350049463 -343 342.0 -1.47842911151 0.0596867028317 -344 343.0 -1.53878331313 0.061018148454 -345 344.0 -1.60045794659 0.0623272072653 -346 345.0 -1.66342954101 0.0636117049668 -347 346.0 -1.72767243359 0.0648694329207 -348 347.0 -1.79315873807 0.0660981537565 -349 348.0 -1.85985831882 0.0672956071568 -350 349.0 -1.92773877092 0.0684595158069 -351 350.0 -1.99676540616 0.0695875914917 -352 351.0 -2.06690124527 0.0706775413231 -353 352.0 -2.13810701636 0.0717270740805 -354 353.0 -2.21034115987 0.0727339066469 -355 354.0 -2.28355983986 0.0736957705223 -356 355.0 -2.35771696194 0.0746104183955 -357 356.0 -2.43276419776 0.0754756307561 -358 357.0 -2.50865101613 0.0762892225281 -359 358.0 -2.58532472075 0.0770490497051 -360 359.0 -2.66273049463 0.0777530159679 - -# Table of the potential and its negative derivative for frustrated beta sheet -# (Note: Derivatives are in units of energy/radians, not energy/degrees.) -# ./calc_dihedral_table.py 5.6 57.29577951308232 6 6.0 180 6 0.0 359 360 - -FRUSTRATED_BETA -N 360 DEGREES - -1 0.0 -2.55809068762 0.0731724739818 -2 1.0 -2.63154144494 0.0737195744566 -3 2.0 -2.70551060968 0.0742089966437 -4 3.0 -2.77993963883 0.074639023134 -5 4.0 -2.85476830901 0.0750080115297 -6 5.0 -2.92993479441 0.0753144003899 -7 6.0 -3.00537575069 0.0755567150326 -8 7.0 -3.08102640456 0.0757335731758 -9 8.0 -3.15682064892 0.0758436903983 -10 9.0 -3.23269114341 0.075885885404 -11 10.0 -3.30856942003 0.0758590850738 -12 11.0 -3.38438599377 0.0757623292865 -13 12.0 -3.46007047791 0.0755947754951 -14 13.0 -3.53555170381 0.0753557030426 -15 14.0 -3.61075784476 0.0750445172025 -16 15.0 -3.68561654392 0.0746607529305 -17 16.0 -3.76005504566 0.0742040783151 -18 17.0 -3.83400033034 0.0736742977129 -19 18.0 -3.907379252 0.0730713545594 -20 19.0 -3.98011867868 0.0723953338429 -21 20.0 -4.0521456351 0.0716464642332 -22 21.0 -4.12338744726 0.0708251198546 -23 22.0 -4.19377188857 0.0699318216967 -24 23.0 -4.26322732737 0.0689672386556 -25 24.0 -4.33168287509 0.0679321881993 -26 25.0 -4.39906853508 0.0668276366524 -27 26.0 -4.46531535141 0.0656546990963 -28 27.0 -4.53035555742 0.0644146388823 -29 28.0 -4.59412272358 0.0631088667546 -30 29.0 -4.65655190431 0.061738939584 -31 30.0 -4.71757978327 0.0603065587109 -32 31.0 -4.77714481686 0.0588135679005 -33 32.0 -4.83518737548 0.057261950911 -34 33.0 -4.89164988211 0.0556538286799 -35 34.0 -4.94647694795 0.0539914561312 -36 35.0 -4.99961550465 0.0522772186102 -37 36.0 -5.05101493277 0.0505136279528 -38 37.0 -5.10062718621 0.048703318195 -39 38.0 -5.14840691207 0.0468490409338 -40 39.0 -5.19431156578 0.0449536603471 -41 40.0 -5.23830152101 0.0430201478838 -42 41.0 -5.28034017422 0.0410515766363 -43 42.0 -5.3203940433 0.0390511154063 -44 43.0 -5.35843286021 0.0370220224793 -45 44.0 -5.39442965726 0.0349676391193 -46 45.0 -5.4283608467 0.0328913828015 -47 46.0 -5.46020629342 0.0307967401964 -48 47.0 -5.48994938059 0.028687259923 -49 48.0 -5.51757706789 0.0265665450883 -50 49.0 -5.54307994213 0.0244382456298 -51 50.0 -5.56645226024 0.0223060504811 -52 51.0 -5.58769198425 0.0201736795783 -53 52.0 -5.60680080825 0.0180448757265 -54 53.0 -5.62378417713 0.0159233963481 -55 54.0 -5.63865129702 0.0138130051308 -56 55.0 -5.6514151374 0.0117174635982 -57 56.0 -5.66209242462 0.00964052262251 -58 57.0 -5.67070362704 0.00758591390103 -59 58.0 -5.67727293157 0.00555734141841 -60 59.0 -5.6818282117 0.00355847291538 -61 60.0 -5.68440098698 0.00159293138608 -62 61.0 -5.68502637408 -0.000335713374531 -63 62.0 -5.68374302934 -0.00222395315148 -64 63.0 -5.68059308309 -0.0040683495974 -65 64.0 -5.67562206565 -0.00586554240548 -66 65.0 -5.66887882528 -0.00761225734683 -67 66.0 -5.66041543813 -0.00930531415106 -68 67.0 -5.65028711044 -0.0109416342099 -69 68.0 -5.63855207307 -0.0125182480831 -70 69.0 -5.6252714687 -0.0140323027883 -71 70.0 -5.61050923182 -0.0154810688529 -72 71.0 -5.59433196178 -0.0168619471125 -73 72.0 -5.57680878923 -0.0181724752358 -74 73.0 -5.5580112361 -0.019410333958 -75 74.0 -5.53801306959 -0.0205733530082 -76 75.0 -5.51689015031 -0.0216595167121 -77 76.0 -5.49472027505 -0.0226669692568 -78 77.0 -5.47158301441 -0.0235940196022 -79 78.0 -5.44755954575 -0.0244391460249 -80 79.0 -5.42273248172 -0.0252010002837 -81 80.0 -5.3971856949 -0.0258784113929 -82 81.0 -5.37100413881 -0.0264703889936 -83 82.0 -5.34427366574 -0.0269761263135 -84 83.0 -5.31708084192 -0.0273950027051 -85 84.0 -5.28951276022 -0.0277265857564 -86 85.0 -5.26165685114 -0.0279706329651 -87 86.0 -5.23360069216 -0.0281270929735 -88 87.0 -5.20543181621 -0.0281961063563 -89 88.0 -5.17723751951 -0.0281780059613 -90 89.0 -5.14910466934 -0.0280733167983 -91 90.0 -5.12111951208 -0.0278827554757 -92 91.0 -5.09336748214 -0.0276072291861 -93 92.0 -5.06593301201 -0.0272478342399 -94 93.0 -5.0388993441 -0.026805854151 -95 94.0 -5.01234834466 -0.0262827572773 -96 95.0 -4.98636032033 -0.0256801940208 -97 96.0 -4.96101383762 -0.0249999935924 -98 97.0 -4.93638554598 -0.0242441603499 -99 98.0 -4.91255000457 -0.0234148697145 -100 99.0 -4.88957951348 -0.0225144636776 -101 100.0 -4.86754394953 -0.0215454459053 -102 101.0 -4.84651060724 -0.0205104764546 -103 102.0 -4.8265440452 -0.01941236611 -104 103.0 -4.80770593836 -0.0182540703564 -105 104.0 -4.79005493648 -0.0170386830008 -106 105.0 -4.77364652914 -0.0157694294583 -107 106.0 -4.7585329176 -0.0144496597171 -108 107.0 -4.74476289391 -0.0130828410011 -109 108.0 -4.73238172744 -0.0116725501446 -110 109.0 -4.72143105919 -0.0102224657007 -111 110.0 -4.71194880414 -0.00873635979846 -112 111.0 -4.70396906182 -0.0072180897712 -113 112.0 -4.69752203541 -0.00567158957449 -114 113.0 -4.69263395945 -0.00410086101469 -115 114.0 -4.68932703648 -0.00250996480925 -116 115.0 -4.68761938265 -0.000903011500147 -117 116.0 -4.68752498248 0.00071584775762 -118 117.0 -4.68905365291 0.00234243051027 -119 118.0 -4.69221101668 0.00397253239976 -120 119.0 -4.69699848518 0.00560193661579 -121 120.0 -4.70341325069 0.00722642338265 -122 121.0 -4.71144828821 0.00884177945771 -123 122.0 -4.72109236669 0.0104438076188 -124 123.0 -4.73233006984 0.0120283361174 -125 124.0 -4.74514182625 0.0135912280748 -126 125.0 -4.75950394898 0.0151283907985 -127 126.0 -4.77538868431 0.0166357849963 -128 127.0 -4.79276426974 0.0181094338658 -129 128.0 -4.81159500092 0.0195454320375 -130 129.0 -4.83184130754 0.0209399543498 -131 130.0 -4.8534598378 0.0222892644342 -132 131.0 -4.87640355143 0.0235897230915 -133 132.0 -4.90062182095 0.0248377964369 -134 133.0 -4.92606054096 0.0260300637961 -135 134.0 -4.95266224518 0.0271632253326 -136 135.0 -4.98036623096 0.028234109388 -137 136.0 -5.00910869107 0.0292396795182 -138 137.0 -5.03882285221 0.0301770412082 -139 138.0 -5.06943912022 0.0310434482505 -140 139.0 -5.10088523142 0.0318363087705 -141 140.0 -5.13308640979 0.0325531908865 -142 141.0 -5.16596552963 0.0331918279898 -143 142.0 -5.19944328334 0.0337501236332 -144 143.0 -5.23343835383 0.0342261560164 -145 144.0 -5.26786759123 0.0346181820585 -146 145.0 -5.30264619353 0.0349246410472 -147 146.0 -5.33768789051 0.0351441578585 -148 147.0 -5.37290513082 0.0352755457383 -149 148.0 -5.40820927152 0.0353178086401 -150 149.0 -5.4435107698 0.0352701431151 -151 150.0 -5.4787193763 0.0351319397498 -152 151.0 -5.51374432971 0.0349027841491 -153 152.0 -5.54849455206 0.0345824574643 -154 153.0 -5.58287884436 0.0341709364636 -155 154.0 -5.61680608206 0.0336683931487 -156 155.0 -5.65018540988 0.0330751939177 -157 156.0 -5.68292643563 0.0323918982779 -158 157.0 -5.71493942249 0.0316192571138 -159 158.0 -5.74613547931 0.0307582105139 -160 159.0 -5.77642674856 0.029809885165 -161 160.0 -5.80572659147 0.0287755913197 -162 161.0 -5.83394976986 0.0276568193473 -163 162.0 -5.86101262442 0.0264552358763 -164 163.0 -5.8868332488 0.025172679541 -165 164.0 -5.91133165941 0.0238111563427 -166 165.0 -5.93442996024 0.0223728346376 -167 166.0 -5.95605250261 0.0208600397671 -168 167.0 -5.97612603931 0.0192752483425 -169 168.0 -5.99457987285 0.0176210822011 -170 169.0 -6.01134599757 0.015900302049 -171 170.0 -6.02635923519 0.014115800807 -172 171.0 -6.03955736358 0.0122705966784 -173 172.0 -6.05088123845 0.0103678259555 -174 173.0 -6.0602749078 0.00841073558436 -175 174.0 -6.06768571866 0.00640267550713 -176 175.0 -6.0730644163 0.00434709080102 -177 176.0 -6.07636523524 0.00224751363529 -178 177.0 -6.07754598232 0.000107555066143 -179 178.0 -6.07656811141 -0.00206910330914 -180 179.0 -6.07339678973 -0.00427871781763 -181 180.0 -6.06800095563 -0.00651749127408 -182 181.0 -6.06035336781 -0.00878158162059 -183 182.0 -6.05043064586 -0.0110671106207 -184 183.0 -6.03821330204 -0.0133701725859 -185 184.0 -6.02368576439 -0.0156868431131 -186 185.0 -6.00683639108 -0.0180131878107 -187 186.0 -5.98765747603 -0.0203452709919 -188 187.0 -5.96614524589 -0.0226791643135 -189 188.0 -5.94229984843 -0.025010955339 -190 189.0 -5.91612533236 -0.0273367560054 -191 190.0 -5.88762961878 -0.0296527109716 -192 191.0 -5.85682446433 -0.0319550058299 -193 192.0 -5.82372541626 -0.0342398751598 -194 193.0 -5.78835175943 -0.0365036104045 -195 194.0 -5.75072645562 -0.0387425675516 -196 195.0 -5.71087607524 -0.0409531746008 -197 196.0 -5.66883072166 -0.0431319387984 -198 197.0 -5.62462394846 -0.0452754536249 -199 198.0 -5.57829266983 -0.0473804055171 -200 199.0 -5.5298770643 -0.0494435803104 -201 200.0 -5.47942047235 -0.0514618693867 -202 201.0 -5.42696928781 -0.0534322755136 -203 202.0 -5.37257284377 -0.055351918363 -204 203.0 -5.316283293 -0.0572180396955 -205 204.0 -5.25815548345 -0.059028008202 -206 205.0 -5.19824682901 -0.0607793239895 -207 206.0 -5.13661717604 -0.0624696227052 -208 207.0 -5.0733286659 -0.0640966792879 -209 208.0 -5.00844559393 -0.0656584113417 -210 209.0 -4.94203426529 -0.0671528821253 -211 210.0 -4.87416284794 -0.0685783031513 -212 211.0 -4.80490122327 -0.0699330363936 -213 212.0 -4.7343208347 -0.0712155960973 -214 213.0 -4.66249453466 -0.0724246501921 -215 214.0 -4.58949643037 -0.0735590213066 -216 215.0 -4.51540172879 -0.0746176873849 -217 216.0 -4.44028658118 -0.0755997819067 -218 217.0 -4.3642279276 -0.0765045937139 -219 218.0 -4.28730334182 -0.0773315664459 -220 219.0 -4.20959087694 -0.0780802975905 -221 220.0 -4.13116891218 -0.0787505371538 -222 221.0 -4.0521160012 -0.0793421859574 -223 222.0 -3.97251072229 -0.0798552935693 -224 223.0 -3.89243153076 -0.0802900558785 -225 224.0 -3.81195661404 -0.0806468123209 -226 225.0 -3.73116374964 -0.0809260427693 -227 226.0 -3.65013016636 -0.0811283640964 -228 227.0 -3.56893240921 -0.0812545264246 -229 228.0 -3.48764620813 -0.0813054090744 -230 229.0 -3.4063463509 -0.0812820162266 -231 230.0 -3.32510656064 -0.0811854723104 -232 231.0 -3.24399937793 -0.081017017134 -233 232.0 -3.16309604794 -0.0807780007742 -234 233.0 -3.08246641287 -0.0804698782381 -235 234.0 -3.00217880976 -0.0800942039176 -236 235.0 -2.92229997393 -0.079652625851 -237 236.0 -2.84289494829 -0.0791468798106 -238 237.0 -2.76402699866 -0.0785787832348 -239 238.0 -2.68575753514 -0.0779502290223 -240 239.0 -2.60814603984 -0.077263179207 -241 240.0 -2.53125000097 -0.0765196585342 -242 241.0 -2.4551248533 -0.0757217479546 -243 242.0 -2.37982392531 -0.0748715780578 -244 243.0 -2.30539839282 -0.073971322463 -245 244.0 -2.23189723927 -0.0730231911866 -246 245.0 -2.15936722267 -0.072029424007 -247 246.0 -2.0878528491 -0.0709922838436 -248 247.0 -2.01739635293 -0.0699140501714 -249 248.0 -1.94803768347 -0.0687970124882 -250 249.0 -1.87981449824 -0.0676434638537 -251 250.0 -1.81276216256 -0.0664556945194 -252 251.0 -1.74691375554 -0.0652359856651 -253 252.0 -1.68230008218 -0.0639866032624 -254 253.0 -1.61894969164 -0.0627097920793 -255 254.0 -1.55688890134 -0.0614077698443 -256 255.0 -1.49614182687 -0.0600827215855 -257 256.0 -1.43673041741 -0.05873679416 -258 257.0 -1.37867449659 -0.0573720909874 -259 258.0 -1.32199180845 -0.0559906670036 -260 259.0 -1.26669806833 -0.0545945238457 -261 260.0 -1.21280701853 -0.0531856052829 -262 261.0 -1.1603304883 -0.0517657929031 -263 262.0 -1.1092784581 -0.0503369020679 -264 263.0 -1.05965912771 -0.0489006781451 -265 264.0 -1.01147898802 -0.0474587930279 -266 265.0 -0.964742896092 -0.0460128419505 -267 266.0 -0.919454153297 -0.0445643406057 -268 267.0 -0.875614586172 -0.0431147225719 -269 268.0 -0.833224629688 -0.0416653370554 -270 269.0 -0.792283412613 -0.0402174469521 -271 270.0 -0.752788844664 -0.038772227232 -272 271.0 -0.714737705101 -0.0373307636499 -273 272.0 -0.67812573245 -0.0358940517831 -274 273.0 -0.642947715028 -0.0344629963972 -275 274.0 -0.609197581934 -0.0330384111393 -276 275.0 -0.576868494182 -0.0316210185584 -277 276.0 -0.545952935658 -0.0302114504483 -278 277.0 -0.51644280357 -0.0288102485125 -279 278.0 -0.488329498068 -0.0274178653447 -280 279.0 -0.461604010741 -0.0260346657211 -281 280.0 -0.436257011655 -0.0246609281969 -282 281.0 -0.412278934657 -0.023296847002 -283 282.0 -0.389660060626 -0.0219425342253 -284 283.0 -0.368390598407 -0.0205980222818 -285 284.0 -0.348460763137 -0.01926326665 -286 285.0 -0.329860851704 -0.0179381488715 -287 286.0 -0.312581315078 -0.0166224797996 -288 287.0 -0.296612827279 -0.015316003087 -289 288.0 -0.281946350734 -0.0140183988977 -290 289.0 -0.268573197826 -0.0127292878319 -291 290.0 -0.256485088408 -0.0114482350481 -292 291.0 -0.245674203109 -0.0101747545698 -293 292.0 -0.236133232246 -0.00890831375923 -294 293.0 -0.227855420178 -0.00764833794542 -295 294.0 -0.220834604976 -0.00639421518813 -296 295.0 -0.215065253253 -0.00514530116277 -297 296.0 -0.210542490065 -0.00390092414876 -298 297.0 -0.207262123775 -0.00266039010467 -299 298.0 -0.205220665805 -0.00142298781263 -300 299.0 -0.204415345223 -0.000187994074493 -301 300.0 -0.204844118104 0.00104532105779 -302 301.0 -0.206505671662 0.00227768903543 -303 302.0 -0.209399423126 0.0035098375675 -304 303.0 -0.213525513386 0.00474248539479 -305 304.0 -0.218884795423 0.00597633710062 -306 305.0 -0.225478817581 0.00721207797616 -307 306.0 -0.233309801737 0.00845036895769 -308 307.0 -0.242380616448 0.00969184165314 -309 308.0 -0.252694745185 0.0109370934746 -310 309.0 -0.264256249747 0.0121866828936 -311 310.0 -0.277069729013 0.0134411248358 -312 311.0 -0.291140273151 0.0147008862297 -313 312.0 -0.306473413467 0.0159663817261 -314 313.0 -0.323075068066 0.0172379696031 -315 314.0 -0.340951483513 0.018515947869 -316 315.0 -0.360109172702 0.0198005505798 -317 316.0 -0.380554849155 0.0210919443819 -318 317.0 -0.402295357987 0.0223902252933 -319 318.0 -0.425337603767 0.0236954157356 -320 319.0 -0.449688475549 0.0250074618263 -321 320.0 -0.475354769327 0.0263262309427 -322 321.0 -0.50234310819 0.0276515095659 -323 322.0 -0.530659860472 0.0289830014145 -324 323.0 -0.560311056174 0.0303203258736 -325 324.0 -0.59130230198 0.0316630167284 -326 325.0 -0.623638695141 0.0330105212056 -327 326.0 -0.657324736579 0.0343621993296 -328 327.0 -0.692364243488 0.0357173235955 -329 328.0 -0.728760261774 0.0370750789637 -330 329.0 -0.766514978659 0.0384345631765 -331 330.0 -0.805629635748 0.0397947873984 -332 331.0 -0.846104442913 0.04115467718 -333 332.0 -0.887938493289 0.042513073745 -334 333.0 -0.93112967973 0.0438687355968 -335 334.0 -0.975674613021 0.0452203404434 -336 335.0 -1.02156854218 0.0465664874361 -337 336.0 -1.06880527714 0.0479056997168 -338 337.0 -1.11737711415 0.0492364272675 -339 338.0 -1.16727476416 0.0505570500574 -340 339.0 -1.2184872845 0.051865881477 -341 340.0 -1.27100201415 0.0531611720525 -342 341.0 -1.32480451282 0.0544411134304 -343 342.0 -1.37987850417 0.055703842622 -344 343.0 -1.43620582346 0.0569474464963 -345 344.0 -1.49376636966 0.0581699665097 -346 345.0 -1.55253806258 0.05936940366 -347 346.0 -1.61249680493 0.0605437236497 -348 347.0 -1.67361644969 0.0616908622471 -349 348.0 -1.73586877296 0.0628087308273 -350 349.0 -1.79922345238 0.0638952220804 -351 350.0 -1.86364805137 0.0649482158688 -352 351.0 -1.92910800931 0.0659655852184 -353 352.0 -1.9955666377 0.066945202426 -354 353.0 -2.06298512258 0.0678849452658 -355 354.0 -2.13132253309 0.0687827032771 -356 355.0 -2.20053583647 0.0696363841147 -357 356.0 -2.27057991931 0.0704439199439 -358 357.0 -2.3414076153 0.0712032738621 -359 358.0 -2.41296973939 0.0719124463259 -360 359.0 -2.48521512832 0.072569481568 diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+minichaperone/moltemplate_files/table_minichaperone_h=0.6.dat b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+minichaperone/moltemplate_files/table_minichaperone_h=0.6.dat deleted file mode 100644 index d2b1ed3aaf..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+minichaperone/moltemplate_files/table_minichaperone_h=0.6.dat +++ /dev/null @@ -1,988 +0,0 @@ -# Interaction between a chaperone wall and hydrophobic ("B") beads (h=0.6) -# Generated using: -# generate_tables/calc_chaperone_table.py 1.0 1.0 3.0 0.60 3.1 8.0 981 True - -CH_H0.6 -N 981 R 3.1 8.0 - -1 3.1 24321971157.7 2.4400451019e+12 -2 3.105 14907528428.0 1.42456746092e+12 -3 3.11 9347010266.92 8.52735030437e+11 -4 3.115 5983057175.03 5.22187648991e+11 -5 3.12 3902942155.05 3.26496996649e+11 -6 3.125 2590648415.38 2.0808159227e+11 -7 3.13 1747350825.1 1.34970444886e+11 -8 3.135 1196139798.89 88984974583.5 -9 3.14 830130182.341 59559787515.6 -10 3.145 583518174.975 40428507749.3 -11 3.15 415078797.287 27803974550.9 -12 3.155 298562827.719 19356989964.4 -13 3.16 217001769.743 13631486848.5 -14 3.165 159270305.159 9703243449.66 -15 3.17 117976881.962 6977184032.49 -16 3.175 88149161.6455 5064988683.98 -17 3.18 66402860.1298 3710042118.5 -18 3.185 50409022.6215 2740737360.59 -19 3.19 38548170.6708 2041021063.98 -20 3.195 29683036.1074 1531572773.33 -21 3.2 23007502.8905 1157631256.92 -22 3.205 17945109.6836 881028781.898 -23 3.21 14080149.2893 674921399.554 -24 3.215 11110438.2418 520266326.167 -25 3.22 8814639.75879 403443800.764 -26 3.225 7029455.47123 314636408.027 -27 3.23 5633571.16439 246714657.082 -28 3.235 4536265.59262 194464091.949 -29 3.24 3669265.83647 154044868.616 -30 3.245 2980881.1453 122610915.077 -31 3.25 2431748.15466 98039536.8272 -32 3.255 1991724.07297 78738058.3506 -33 3.26 1637603.46485 63504600.2322 -34 3.265 1351429.90872 51427172.534 -35 3.27 1119240.11293 41810074.9071 -36 3.275 930124.378436 34119886.2947 -37 3.28 775519.857832 27945597.578 -38 3.285 648676.115123 22969017.4933 -39 3.29 544248.919174 18942684.9889 -40 3.295 457989.984944 15673297.5619 -41 3.3 386508.875651 13009215.1485 -42 3.305 327089.446276 10830991.226 -43 3.31 277547.709074 9044163.93118 -44 3.315 236121.303553 7573742.76366 -45 3.32 201383.18845 6359973.47163 -46 3.325 172173.978278 5355070.91875 -47 3.33 147548.691578 4520688.28477 -48 3.335 126734.684289 3825948.80978 -49 3.34 109098.298235 3245909.11014 -50 3.345 94118.3261235 2760354.93052 -51 3.35 81364.827777 2352853.97713 -52 3.355 70482.1624146 2010008.31682 -53 3.36 61175.3541703 1720862.26897 -54 3.365 53199.1018261 1476431.88582 -55 3.37 46348.8930587 1269329.84244 -56 3.375 40453.7990113 1093465.44786 -57 3.38 35370.6146686 943803.998782 -58 3.385 30979.0803706 816173.162054 -59 3.39 27177.9744013 707106.743488 -60 3.395 23881.9094124 613718.268337 -61 3.4 21018.6991377 533598.403624 -62 3.405 18527.1884441 464731.50307 -63 3.41 16355.4608211 405427.532611 -64 3.415 14459.3541284 354266.400629 -65 3.42 12801.228731 310052.319542 -66 3.425 11348.9427887 271776.300627 -67 3.43 10074.9979765 238585.259865 -68 3.435 8955.82575185 209756.510836 -69 3.44 7971.18978782 184676.657916 -70 3.445 7103.68463562 162824.092297 -71 3.45 6338.31427303 143754.444665 -72 3.455 5662.13711315 127088.469763 -73 3.46 5063.9664184 112501.9356 -74 3.465 4534.11699728 99717.1686967 -75 3.47 4064.19064042 88495.970274 -76 3.475 3646.89404446 78633.6696895 -77 3.48 3275.88403311 69954.1231906 -78 3.485 2945.63575657 62305.4999784 -79 3.49 2651.33026883 55556.7252625 -80 3.495 2388.75847582 49594.4725913 -81 3.5 2154.23893796 44320.6162531 -82 3.505 1944.54741747 39650.0697323 -83 3.51 1756.8563988 35508.9486835 -84 3.515 1588.68309151 31833.0071751 -85 3.52 1437.84465949 28566.3044359 -86 3.525 1302.41961585 25660.0663588 -87 3.53 1180.71448694 23071.7118275 -88 3.535 1071.23498579 20764.0187577 -89 3.54 972.661050857 18704.4087568 -90 3.545 883.825202407 16864.3326446 -91 3.55 803.693750954 15218.7418698 -92 3.555 731.350460573 13745.6331832 -93 3.56 665.982328363 12425.6558809 -94 3.565 606.867190408 11241.7725673 -95 3.57 553.362906393 10178.9657593 -96 3.575 504.897910387 9223.98381086 -97 3.58 460.962945446 8365.12060921 -98 3.585 421.103825306 7592.02431669 -99 3.59 384.915088285 6895.53112553 -100 3.595 352.034427161 6267.5205811 -101 3.6 322.137794751 5700.78952663 -102 3.605 294.935098544 5188.94214534 -103 3.61 270.166409464 4726.29393494 -104 3.615 247.598619855 4307.78775517 -105 3.62 227.022494431 3928.92034957 -106 3.625 208.250065337 3585.67796495 -107 3.63 191.112328875 3274.47988201 -108 3.635 175.457206974 2992.12883298 -109 3.64 161.147741205 2735.76742147 -110 3.645 148.060491326 2502.83977901 -111 3.65 136.084113848 2291.05779528 -112 3.655 125.118099223 2098.37134728 -113 3.66 115.071648949 1922.94202847 -114 3.665 105.862676198 1763.11994431 -115 3.67 97.4169155884 1617.42319704 -116 3.675 89.6671295106 1484.51973131 -117 3.68 82.5523999227 1363.21125435 -118 3.685 76.0174958886 1252.41898087 -119 3.69 70.0123082899 1151.17098442 -120 3.695 64.4913441675 1058.59096449 -121 3.7 59.4132740402 973.88826227 -122 3.705 54.7405263329 896.348978842 -123 3.71 50.438923727 825.328067481 -124 3.715 46.4773568526 760.242287449 -125 3.72 42.8274912666 700.563920374 -126 3.725 39.4635041252 645.815162231 -127 3.73 36.3618473701 595.563114331 -128 3.735 33.5010346035 549.415305905 -129 3.74 30.8614491473 507.015688796 -130 3.745 28.425171059 468.041051794 -131 3.75 26.1758211241 432.197808262 -132 3.755 24.0984200646 399.21911609 -133 3.76 22.179261392 368.86229374 -134 3.765 20.4057965086 340.906500282 -135 3.77 18.7665308078 315.150650994 -136 3.775 17.2509296613 291.411543325 -137 3.78 15.8493332971 269.522170811 -138 3.785 14.5528796804 249.330205101 -139 3.79 13.3534346012 230.696628411 -140 3.795 12.2435282565 213.494500686 -141 3.8 11.2162976896 197.607847495 -142 3.805 10.2654345142 182.930656184 -143 3.81 9.38513741093 169.365969178 -144 3.815 8.57006893443 156.825064535 -145 3.82 7.81531621929 145.226714879 -146 3.825 7.1163552113 134.496516825 -147 3.83 6.46901809043 124.566283826 -148 3.835 5.86946358438 115.373496111 -149 3.84 5.3141499016 106.860802062 -150 3.845 4.79981003946 98.9755659598 -151 3.85 4.32342924744 91.6694575494 -152 3.855 3.88222444642 84.8980793495 -153 3.86 3.47362542484 78.6206280516 -154 3.865 3.09525764949 72.7995867184 -155 3.87 2.74492654463 67.4004448293 -156 3.875 2.42060310675 62.3914435192 -157 3.88 2.12041073521 57.7433436194 -158 3.885 1.84261317026 53.4292143513 -159 3.89 1.58560343996 49.424240734 -160 3.895 1.34789372698 45.7055479593 -161 3.9 1.12810607442 42.2520411601 -162 3.905 0.92496385733 39.0442591487 -163 3.91 0.737283953249 36.0642408427 -164 3.915 0.563969551396 33.2954032193 -165 3.92 0.404003545437 30.7224297483 -166 3.925 0.2564424599 28.3311683573 -167 3.93 0.120410864734 26.1085380703 -168 3.935 -0.00490376337106 24.0424435434 -169 3.94 -0.120255770611 22.1216967943 -170 3.945 -0.226345680979 20.3359454863 -171 3.95 -0.323824207772 18.6756071913 -172 3.955 -0.413295950251 17.1318091041 -173 3.96 -0.495322801504 15.6963327338 -174 3.965 -0.570427091298 14.3615631388 -175 3.97 -0.639094485635 13.1204423129 -176 3.975 -0.701776662868 11.9664263642 -177 3.98 -0.75889378451 10.8934461632 -178 3.985 -0.810836777335 9.89587116294 -179 3.99 -0.857969441941 8.96847612349 -180 3.995 -0.900630401683 8.10641049364 -181 4.0 -0.939134904689 7.30517022808 -182 4.005 -0.973776490618 6.56057183534 -183 4.01 -1.00482853285 5.86872847094 -184 4.015 -1.03254566588 5.22602790624 -185 4.02 -1.05716510696 4.62911221801 -186 4.025 -1.07890788015 4.07485905752 -187 4.03 -1.09797995042 3.56036436994 -188 4.035 -1.11457327471 3.08292644583 -189 4.04 -1.12886677634 2.64003119688 -190 4.045 -1.14102724873 2.22933855711 -191 4.05 -1.1512101936 1.84866991901 -192 4.055 -1.15956059893 1.49599652185 -193 4.06 -1.16621366096 1.16942871644 -194 4.065 -1.17129545464 0.867206036674 -195 4.07 -1.17492355624 0.587688014256 -196 4.075 -1.17720762184 0.329345678162 -197 4.08 -1.17824992491 0.0907536851962 -198 4.085 -1.17814585595 -0.129416967536 -199 4.09 -1.17698438715 -0.332405693416 -200 4.095 -1.17484850446 -0.519368571864 -201 4.1 -1.1718156096 -0.691384146782 -202 4.105 -1.16795789413 -0.84945880294 -203 4.11 -1.16334268761 -0.994531752529 -204 4.115 -1.15803278177 -1.12747966154 -205 4.12 -1.15208673236 -1.24912094323 -206 4.125 -1.14555914033 -1.36021974383 -207 4.13 -1.1385009138 -1.46148964359 -208 4.135 -1.1309595122 -1.55359709446 -209 4.14 -1.1229791738 -1.63716461409 -210 4.145 -1.11460112791 -1.71277375416 -211 4.15 -1.10586379267 -1.78096785987 -212 4.155 -1.09680295968 -1.84225463583 -213 4.16 -1.08745196606 -1.89710853265 -214 4.165 -1.07784185518 -1.94597296735 -215 4.17 -1.06800152657 -1.98926238963 -216 4.175 -1.05795787589 -2.02736420527 -217 4.18 -1.04773592563 -2.06064056692 -218 4.185 -1.03735894714 -2.0894300419 -219 4.19 -1.02684857465 -2.11404916577 -220 4.195 -1.01622491175 -2.13479388991 -221 4.2 -1.0055066309 -2.15194093062 -222 4.205 -0.994711066419 -2.16574902671 -223 4.21 -0.983854301441 -2.17646011217 -224 4.215 -0.972951249128 -2.18430040971 -225 4.22 -0.962015728675 -2.18948145101 -226 4.225 -0.951060536345 -2.19220102845 -227 4.23 -0.940097511927 -2.19264408348 -228 4.235 -0.92913760089 -2.19098353577 -229 4.24 -0.918190912536 -2.18738105733 -230 4.245 -0.907266774409 -2.18198779544 -231 4.25 -0.896373783212 -2.17494504784 -232 4.255 -0.885519852462 -2.16638489351 -233 4.26 -0.87471225709 -2.15643078212 -234 4.265 -0.863957675198 -2.14519808475 -235 4.27 -0.853262227147 -2.13279460887 -236 4.275 -0.842631512163 -2.11932107965 -237 4.28 -0.832070642606 -2.1048715901 -238 4.285 -0.82158427607 -2.08953402203 -239 4.29 -0.81117664544 -2.07339043986 -240 4.295 -0.800851587053 -2.056517459 -241 4.3 -0.790612567064 -2.0389865906 -242 4.305 -0.780462706161 -2.02086456422 -243 4.31 -0.770404802702 -2.00221362974 -244 4.315 -0.760441354404 -1.98309184017 -245 4.32 -0.750574578653 -1.96355331629 -246 4.325 -0.740806431546 -1.94364849462 -247 4.33 -0.731138625717 -1.92342435953 -248 4.335 -0.721572647055 -1.90292466077 -249 4.34 -0.712109770359 -1.8821901172 -250 4.345 -0.702751074011 -1.86125860773 -251 4.35 -0.693497453724 -1.84016535019 -252 4.355 -0.684349635419 -1.81894306902 -253 4.36 -0.675308187304 -1.79762215246 -254 4.365 -0.666373531174 -1.77623079981 -255 4.37 -0.657545953012 -1.75479515963 -256 4.375 -0.648825612912 -1.73333945922 -257 4.38 -0.640212554381 -1.71188612608 -258 4.385 -0.631706713048 -1.6904559018 -259 4.39 -0.623307924828 -1.66906794891 -260 4.395 -0.615015933557 -1.64773995108 -261 4.4 -0.606830398156 -1.6264882071 -262 4.405 -0.598750899326 -1.60532771911 -263 4.41 -0.590776945828 -1.58427227531 -264 4.415 -0.582907980353 -1.5633345276 -265 4.42 -0.575143385022 -1.54252606445 -266 4.425 -0.567482486527 -1.52185747923 -267 4.43 -0.559924560948 -1.5013384344 -268 4.435 -0.552468838251 -1.48097772171 -269 4.44 -0.545114506505 -1.46078331869 -270 4.445 -0.537860715815 -1.44076244171 -271 4.45 -0.530706582 -1.42092159576 -272 4.455 -0.523651190037 -1.40126662118 -273 4.46 -0.516693597271 -1.38180273752 -274 4.465 -0.509832836414 -1.36253458471 -275 4.47 -0.503067918346 -1.34346626168 -276 4.475 -0.496397834731 -1.32460136271 -277 4.48 -0.489821560449 -1.30594301139 -278 4.485 -0.483338055873 -1.28749389264 -279 4.49 -0.476946268986 -1.26925628268 -280 4.495 -0.470645137352 -1.2512320772 -281 4.5 -0.464433589953 -1.23342281778 -282 4.505 -0.458310548894 -1.21582971671 -283 4.51 -0.452274930995 -1.19845368022 -284 4.515 -0.446325649266 -1.18129533036 -285 4.52 -0.44046161427 -1.16435502548 -286 4.525 -0.4346817354 -1.14763287946 -287 4.53 -0.428984922053 -1.13112877974 -288 4.535 -0.423370084719 -1.11484240423 -289 4.54 -0.417836135987 -1.09877323723 -290 4.545 -0.41238199148 -1.08292058423 -291 4.55 -0.407006570712 -1.06728358594 -292 4.555 -0.401708797874 -1.05186123133 -293 4.56 -0.396487602569 -1.03665236991 -294 4.565 -0.391341920477 -1.02165572322 -295 4.57 -0.386270693966 -1.00686989558 -296 4.575 -0.381272872655 -0.992293384203 -297 4.58 -0.376347413926 -0.977924588641 -298 4.585 -0.371493283387 -0.963761819613 -299 4.59 -0.366709455298 -0.949803307297 -300 4.595 -0.361994912953 -0.936047209078 -301 4.6 -0.357348649027 -0.922491616798 -302 4.605 -0.352769665884 -0.909134563531 -303 4.61 -0.348256975857 -0.895974029926 -304 4.615 -0.343809601493 -0.883007950126 -305 4.62 -0.339426575775 -0.870234217299 -306 4.625 -0.335106942311 -0.857650688807 -307 4.63 -0.330849755501 -0.845255191024 -308 4.635 -0.326654080682 -0.833045523832 -309 4.64 -0.322518994248 -0.821019464813 -310 4.645 -0.318443583754 -0.809174773153 -311 4.65 -0.314426947996 -0.797509193282 -312 4.655 -0.310468197079 -0.786020458251 -313 4.66 -0.306566452464 -0.774706292883 -314 4.665 -0.302720847002 -0.763564416693 -315 4.67 -0.298930524954 -0.752592546601 -316 4.675 -0.295194641998 -0.741788399447 -317 4.68 -0.291512365223 -0.731149694325 -318 4.685 -0.287882873112 -0.720674154735 -319 4.69 -0.284305355517 -0.710359510583 -320 4.695 -0.280779013618 -0.700203500014 -321 4.7 -0.277303059881 -0.690203871119 -322 4.705 -0.273876718005 -0.680358383489 -323 4.71 -0.270499222857 -0.670664809654 -324 4.715 -0.267169820408 -0.6611209364 -325 4.72 -0.263887767656 -0.651724565975 -326 4.725 -0.260652332547 -0.64247351719 -327 4.73 -0.257462793889 -0.633365626422 -328 4.735 -0.254318441262 -0.624398748527 -329 4.74 -0.251218574926 -0.615570757662 -330 4.745 -0.248162505718 -0.606879548039 -331 4.75 -0.245149554953 -0.598323034585 -332 4.755 -0.242179054319 -0.58989915355 -333 4.76 -0.239250345768 -0.581605863034 -334 4.765 -0.236362781405 -0.573441143467 -335 4.77 -0.233515723378 -0.565402998016 -336 4.775 -0.230708543759 -0.557489452949 -337 4.78 -0.227940624433 -0.549698557946 -338 4.785 -0.225211356975 -0.542028386363 -339 4.79 -0.222520142536 -0.534477035451 -340 4.795 -0.219866391719 -0.527042626532 -341 4.8 -0.21724952446 -0.519723305146 -342 4.805 -0.214668969906 -0.512517241154 -343 4.81 -0.212124166297 -0.505422628808 -344 4.815 -0.209614560836 -0.498437686799 -345 4.82 -0.207139609574 -0.491560658268 -346 4.825 -0.204698777286 -0.484789810792 -347 4.83 -0.202291537346 -0.478123436352 -348 4.835 -0.199917371608 -0.471559851267 -349 4.84 -0.197575770285 -0.465097396123 -350 4.845 -0.195266231824 -0.458734435665 -351 4.85 -0.19298826279 -0.452469358686 -352 4.855 -0.190741377745 -0.446300577889 -353 4.86 -0.188525099125 -0.440226529743 -354 4.865 -0.186338957127 -0.434245674319 -355 4.87 -0.184182489589 -0.428356495114 -356 4.875 -0.182055241873 -0.422557498867 -357 4.88 -0.179956766747 -0.416847215362 -358 4.885 -0.177886624278 -0.41122419722 -359 4.89 -0.175844381709 -0.405687019689 -360 4.895 -0.173829613352 -0.400234280415 -361 4.9 -0.171841900476 -0.394864599219 -362 4.905 -0.169880831195 -0.389576617857 -363 4.91 -0.16794600036 -0.384368999782 -364 4.915 -0.166037009451 -0.379240429897 -365 4.92 -0.164153466471 -0.374189614305 -366 4.925 -0.16229498584 -0.369215280054 -367 4.93 -0.16046118829 -0.364316174883 -368 4.935 -0.158651700764 -0.359491066961 -369 4.94 -0.156866156312 -0.354738744625 -370 4.945 -0.155104193995 -0.350058016116 -371 4.95 -0.153365458783 -0.345447709317 -372 4.955 -0.151649601455 -0.340906671484 -373 4.96 -0.14995627851 -0.336433768983 -374 4.965 -0.148285152065 -0.33202788702 -375 4.97 -0.146635889767 -0.327687929376 -376 4.975 -0.145008164695 -0.323412818142 -377 4.98 -0.143401655276 -0.319201493452 -378 4.985 -0.141816045188 -0.315052913217 -379 4.99 -0.140251023278 -0.310966052862 -380 4.995 -0.138706283472 -0.306939905064 -381 5.0 -0.137181524691 -0.30297347949 -382 5.005 -0.135676450764 -0.299065802536 -383 5.01 -0.134190770348 -0.295215917071 -384 5.015 -0.132724196843 -0.291422882179 -385 5.02 -0.131276448317 -0.287685772906 -386 5.025 -0.129847247421 -0.284003680008 -387 5.03 -0.128436321314 -0.280375709698 -388 5.035 -0.127043401585 -0.276800983406 -389 5.04 -0.12566822418 -0.273278637523 -390 5.045 -0.124310529325 -0.269807823169 -391 5.05 -0.122970061454 -0.266387705946 -392 5.055 -0.121646569138 -0.263017465704 -393 5.06 -0.120339805013 -0.259696296304 -394 5.065 -0.119049525711 -0.256423405389 -395 5.07 -0.117775491793 -0.253198014152 -396 5.075 -0.11651746768 -0.25001935711 -397 5.08 -0.115275221587 -0.246886681885 -398 5.085 -0.114048525458 -0.243799248974 -399 5.09 -0.112837154905 -0.240756331544 -400 5.095 -0.111640889142 -0.237757215204 -401 5.1 -0.110459510922 -0.234801197803 -402 5.105 -0.109292806483 -0.231887589219 -403 5.11 -0.10814056548 -0.229015711147 -404 5.115 -0.107002580932 -0.226184896906 -405 5.12 -0.105878649164 -0.223394491231 -406 5.125 -0.104768569746 -0.220643850079 -407 5.13 -0.103672145444 -0.217932340436 -408 5.135 -0.10258918216 -0.215259340122 -409 5.14 -0.101519488881 -0.212624237608 -410 5.145 -0.100462877624 -0.210026431825 -411 5.15 -0.0994191633865 -0.207465331988 -412 5.155 -0.0983881640955 -0.204940357408 -413 5.16 -0.0973697005554 -0.202450937324 -414 5.165 -0.0963635964003 -0.199996510721 -415 5.17 -0.0953696780453 -0.197576526166 -416 5.175 -0.0943877746391 -0.195190441635 -417 5.18 -0.0934177180174 -0.192837724349 -418 5.185 -0.0924593426569 -0.190517850609 -419 5.19 -0.0915124856305 -0.188230305639 -420 5.195 -0.0905769865631 -0.185974583427 -421 5.2 -0.0896526875878 -0.18375018657 -422 5.205 -0.0887394333038 -0.18155662612 -423 5.21 -0.0878370707341 -0.179393421439 -424 5.215 -0.0869454492844 -0.177260100045 -425 5.22 -0.0860644207027 -0.175156197473 -426 5.225 -0.0851938390397 -0.173081257131 -427 5.23 -0.0843335606096 -0.17103483016 -428 5.235 -0.0834834439517 -0.169016475296 -429 5.24 -0.0826433497932 -0.167025758735 -430 5.245 -0.0818131410117 -0.165062254002 -431 5.25 -0.0809926825993 -0.163125541821 -432 5.255 -0.0801818416266 -0.161215209984 -433 5.26 -0.079380487208 -0.159330853228 -434 5.265 -0.078588490467 -0.157472073109 -435 5.27 -0.0778057245025 -0.155638477884 -436 5.275 -0.0770320643556 -0.15382968239 -437 5.28 -0.0762673869772 -0.152045307925 -438 5.285 -0.0755115711956 -0.150284982136 -439 5.29 -0.0747644976853 -0.148548338906 -440 5.295 -0.0740260489359 -0.146835018241 -441 5.3 -0.0732961092222 -0.145144666161 -442 5.305 -0.0725745645738 -0.143476934597 -443 5.31 -0.0718613027461 -0.14183148128 -444 5.315 -0.0711562131918 -0.140207969643 -445 5.32 -0.0704591870322 -0.138606068717 -446 5.325 -0.0697701170295 -0.137025453033 -447 5.33 -0.0690888975602 -0.135465802523 -448 5.335 -0.0684154245873 -0.133926802424 -449 5.34 -0.0677495956348 -0.132408143187 -450 5.345 -0.0670913097616 -0.130909520379 -451 5.35 -0.0664404675362 -0.129430634599 -452 5.355 -0.0657969710116 -0.127971191381 -453 5.36 -0.0651607237011 -0.126530901116 -454 5.365 -0.0645316305539 -0.125109478958 -455 5.37 -0.0639095979318 -0.123706644743 -456 5.375 -0.0632945335861 -0.122322122907 -457 5.38 -0.0626863466341 -0.120955642402 -458 5.385 -0.0620849475378 -0.119606936622 -459 5.39 -0.0614902480807 -0.118275743316 -460 5.395 -0.0609021613473 -0.11696180452 -461 5.4 -0.0603206017011 -0.115664866475 -462 5.405 -0.0597454847642 -0.114384679556 -463 5.41 -0.0591767273965 -0.113120998201 -464 5.415 -0.0586142476758 -0.111873580833 -465 5.42 -0.0580579648779 -0.110642189799 -466 5.425 -0.0575077994571 -0.109426591294 -467 5.43 -0.0569636730276 -0.108226555298 -468 5.435 -0.056425508344 -0.107041855505 -469 5.44 -0.0558932292835 -0.105872269263 -470 5.445 -0.0553667608274 -0.104717577509 -471 5.45 -0.0548460290437 -0.103577564704 -472 5.455 -0.0543309610691 -0.102452018771 -473 5.46 -0.0538214850925 -0.101340731041 -474 5.465 -0.0533175303375 -0.100243496185 -475 5.47 -0.0528190270461 -0.0991601121616 -476 5.475 -0.0523259064626 -0.0980903801592 -477 5.48 -0.0518381008174 -0.0970341045378 -478 5.485 -0.051355543311 -0.0959910927755 -479 5.49 -0.0508781680991 -0.0949611554144 -480 5.495 -0.0504059102771 -0.093944106007 -481 5.5 -0.0499387058651 -0.0929397610647 -482 5.505 -0.0494764917935 -0.0919479400065 -483 5.51 -0.0490192058883 -0.0909684651086 -484 5.515 -0.0485667868571 -0.0900011614554 -485 5.52 -0.0481191742754 -0.089045856891 -486 5.525 -0.0476763085723 -0.0881023819721 -487 5.53 -0.0472381310177 -0.0871705699209 -488 5.535 -0.0468045837087 -0.0862502565794 -489 5.54 -0.0463756095568 -0.0853412803652 -490 5.545 -0.0459511522751 -0.0844434822262 -491 5.55 -0.0455311563655 -0.0835567055986 -492 5.555 -0.0451155671069 -0.0826807963635 -493 5.56 -0.0447043305426 -0.0818156028054 -494 5.565 -0.0442973934684 -0.0809609755715 -495 5.57 -0.0438947034215 -0.0801167676313 -496 5.575 -0.043496208668 -0.0792828342371 -497 5.58 -0.0431018581925 -0.0784590328851 -498 5.585 -0.0427116016864 -0.0776452232778 -499 5.59 -0.0423253895371 -0.0768412672861 -500 5.595 -0.0419431728176 -0.0760470289129 -501 5.6 -0.0415649032753 -0.075262374257 -502 5.605 -0.041190533322 -0.0744871714779 -503 5.61 -0.0408200160238 -0.0737212907608 -504 5.615 -0.0404533050908 -0.0729646042826 -505 5.62 -0.0400903548671 -0.0722169861784 -506 5.625 -0.0397311203217 -0.0714783125087 -507 5.63 -0.0393755570382 -0.0707484612271 -508 5.635 -0.0390236212059 -0.0700273121483 -509 5.64 -0.0386752696104 -0.0693147469176 -510 5.645 -0.0383304596246 -0.0686106489795 -511 5.65 -0.0379891491998 -0.0679149035485 -512 5.655 -0.0376512968568 -0.0672273975789 -513 5.66 -0.0373168616773 -0.0665480197363 -514 5.665 -0.0369858032954 -0.065876660369 -515 5.67 -0.0366580818895 -0.0652132114801 -516 5.675 -0.0363336581739 -0.0645575667 -517 5.68 -0.0360124933904 -0.0639096212595 -518 5.685 -0.0356945493011 -0.0632692719635 -519 5.69 -0.03537978818 -0.0626364171647 -520 5.695 -0.0350681728056 -0.0620109567384 -521 5.7 -0.0347596664531 -0.061392792057 -522 5.705 -0.0344542328874 -0.0607818259659 -523 5.71 -0.0341518363554 -0.060177962759 -524 5.715 -0.0338524415789 -0.059581108155 -525 5.72 -0.0335560137477 -0.0589911692739 -526 5.725 -0.0332625185126 -0.0584080546145 -527 5.73 -0.0329719219782 -0.0578316740315 -528 5.735 -0.0326841906969 -0.0572619387135 -529 5.74 -0.0323992916615 -0.0566987611612 -530 5.745 -0.0321171922994 -0.0561420551663 -531 5.75 -0.0318378604656 -0.0555917357902 -532 5.755 -0.0315612644367 -0.0550477193436 -533 5.76 -0.0312873729048 -0.0545099233662 -534 5.765 -0.0310161549711 -0.0539782666069 -535 5.77 -0.0307475801402 -0.0534526690041 -536 5.775 -0.030481618314 -0.0529330516667 -537 5.78 -0.030218239786 -0.0524193368549 -538 5.785 -0.0299574152356 -0.0519114479623 -539 5.79 -0.0296991157224 -0.051409309497 -540 5.795 -0.0294433126807 -0.050912847064 -541 5.8 -0.029189977914 -0.0504219873478 -542 5.805 -0.0289390835898 -0.049936658095 -543 5.81 -0.0286906022343 -0.0494567880971 -544 5.815 -0.0284445067271 -0.0489823071741 -545 5.82 -0.0282007702961 -0.0485131461582 -546 5.825 -0.0279593665127 -0.0480492368772 -547 5.83 -0.0277202692865 -0.0475905121394 -548 5.835 -0.0274834528608 -0.0471369057172 -549 5.84 -0.0272488918076 -0.0466883523327 -550 5.845 -0.027016561023 -0.0462447876419 -551 5.85 -0.0267864357225 -0.0458061482206 -552 5.855 -0.0265584914363 -0.0453723715492 -553 5.86 -0.0263327040052 -0.0449433959991 -554 5.865 -0.0261090495757 -0.0445191608184 -555 5.87 -0.0258875045962 -0.0440996061179 -556 5.875 -0.0256680458122 -0.043684672858 -557 5.88 -0.0254506502623 -0.043274302835 -558 5.885 -0.0252352952741 -0.0428684386684 -559 5.89 -0.0250219584602 -0.0424670237876 -560 5.895 -0.0248106177138 -0.0420700024197 -561 5.9 -0.0246012512052 -0.0416773195766 -562 5.905 -0.0243938373776 -0.0412889210434 -563 5.91 -0.0241883549434 -0.0409047533657 -564 5.915 -0.0239847828804 -0.0405247638384 -565 5.92 -0.023783100428 -0.0401489004937 -566 5.925 -0.0235832870839 -0.0397771120898 -567 5.93 -0.0233853225998 -0.0394093480998 -568 5.935 -0.0231891869786 -0.0390455587005 -569 5.94 -0.0229948604704 -0.0386856947618 -570 5.945 -0.0228023235693 -0.0383297078356 -571 5.95 -0.02261155701 -0.0379775501459 -572 5.955 -0.0224225417644 -0.0376291745779 -573 5.96 -0.0222352590382 -0.0372845346683 -574 5.965 -0.022049690268 -0.0369435845953 -575 5.97 -0.0218658171179 -0.0366062791685 -576 5.975 -0.0216836214762 -0.0362725738196 -577 5.98 -0.0215030854528 -0.0359424245927 -578 5.985 -0.0213241913757 -0.0356157881351 -579 5.99 -0.0211469217882 -0.0352926216881 -580 5.995 -0.0209712594458 -0.0349728830781 -581 6.0 -0.0207971873137 -0.0346565307074 -582 6.005 -0.0206246885634 -0.034343523546 -583 6.01 -0.0204537465704 -0.0340338211226 -584 6.015 -0.0202843449109 -0.0337273835164 -585 6.02 -0.0201164673595 -0.0334241713486 -586 6.025 -0.0199500978864 -0.0331241457746 -587 6.03 -0.0197852206547 -0.0328272684755 -588 6.035 -0.0196218200176 -0.0325335016508 -589 6.04 -0.0194598805162 -0.0322428080099 -590 6.045 -0.0192993868768 -0.0319551507653 -591 6.05 -0.0191403240084 -0.0316704936245 -592 6.055 -0.0189826770001 -0.0313888007827 -593 6.06 -0.018826431119 -0.0311100369157 -594 6.065 -0.0186715718074 -0.0308341671728 -595 6.07 -0.018518084681 -0.0305611571696 -596 6.075 -0.0183659555261 -0.0302909729809 -597 6.08 -0.0182151702974 -0.0300235811346 -598 6.085 -0.0180657151159 -0.0297589486041 -599 6.09 -0.0179175762668 -0.0294970428023 -600 6.095 -0.0177707401969 -0.0292378315752 -601 6.1 -0.017625193513 -0.028981283195 -602 6.105 -0.0174809229791 -0.0287273663543 -603 6.11 -0.017337915515 -0.0284760501597 -604 6.115 -0.0171961581939 -0.0282273041259 -605 6.12 -0.0170556382404 -0.0279810981694 -606 6.125 -0.0169163430283 -0.0277374026031 -607 6.13 -0.0167782600792 -0.0274961881301 -608 6.135 -0.01664137706 -0.0272574258382 -609 6.14 -0.0165056817814 -0.0270210871943 -610 6.145 -0.0163711621956 -0.0267871440387 -611 6.15 -0.0162378063949 -0.0265555685802 -612 6.155 -0.0161056026094 -0.0263263333899 -613 6.16 -0.0159745392057 -0.0260994113969 -614 6.165 -0.0158446046847 -0.0258747758823 -615 6.17 -0.01571578768 -0.0256524004746 -616 6.175 -0.0155880769565 -0.0254322591449 -617 6.18 -0.015461461408 -0.0252143262011 -618 6.185 -0.0153359300561 -0.024998576284 -619 6.19 -0.0152114720485 -0.0247849843619 -620 6.195 -0.015088076657 -0.0245735257263 -621 6.2 -0.0149657332764 -0.024364175987 -622 6.205 -0.0148444314225 -0.0241569110676 -623 6.21 -0.0147241607307 -0.0239517072012 -624 6.215 -0.0146049109545 -0.0237485409258 -625 6.22 -0.014486671964 -0.0235473890799 -626 6.225 -0.0143694337444 -0.0233482287986 -627 6.23 -0.0142531863944 -0.0231510375089 -628 6.235 -0.0141379201248 -0.0229557929258 -629 6.24 -0.0140236252573 -0.0227624730484 -630 6.245 -0.0139102922227 -0.0225710561554 -631 6.25 -0.0137979115599 -0.0223815208018 -632 6.255 -0.0136864739141 -0.0221938458144 -633 6.26 -0.013575970036 -0.0220080102883 -634 6.265 -0.0134663907799 -0.021823993583 -635 6.27 -0.0133577271028 -0.0216417753188 -636 6.275 -0.0132499700628 -0.0214613353731 -637 6.28 -0.0131431108183 -0.0212826538767 -638 6.285 -0.013037140626 -0.0211057112104 -639 6.29 -0.0129320508404 -0.0209304880015 -640 6.295 -0.0128278329122 -0.0207569651202 -641 6.3 -0.0127244783869 -0.0205851236763 -642 6.305 -0.0126219789041 -0.020414945016 -643 6.31 -0.0125203261961 -0.0202464107184 -644 6.315 -0.0124195120866 -0.0200795025926 -645 6.32 -0.0123195284899 -0.0199142026739 -646 6.325 -0.0122203674091 -0.0197504932215 -647 6.33 -0.0121220209361 -0.0195883567147 -648 6.335 -0.0120244812493 -0.0194277758502 -649 6.34 -0.0119277406133 -0.0192687335389 -650 6.345 -0.0118317913778 -0.0191112129035 -651 6.35 -0.011736625976 -0.0189551972747 -652 6.355 -0.0116422369241 -0.0188006701892 -653 6.36 -0.0115486168203 -0.0186476153863 -654 6.365 -0.0114557583432 -0.0184960168053 -655 6.37 -0.0113636542516 -0.018345858583 -656 6.375 -0.0112722973829 -0.0181971250506 -657 6.38 -0.0111816806525 -0.0180498007315 -658 6.385 -0.0110917970524 -0.0179038703382 -659 6.39 -0.011002639651 -0.01775931877 -660 6.395 -0.0109142015915 -0.0176161311107 -661 6.4 -0.0108264760913 -0.0174742926254 -662 6.405 -0.0107394564409 -0.017333788759 -663 6.41 -0.0106531360033 -0.0171946051328 -664 6.415 -0.0105675082129 -0.0170567275427 -665 6.42 -0.0104825665746 -0.016920141957 -666 6.425 -0.0103983046631 -0.0167848345133 -667 6.43 -0.010314716122 -0.0166507915172 -668 6.435 -0.0102317946631 -0.0165179994391 -669 6.44 -0.0101495340651 -0.016386444913 -670 6.445 -0.0100679281734 -0.0162561147332 -671 6.45 -0.00998697089892 -0.0161269958531 -672 6.455 -0.0099066562175 -0.0159990753826 -673 6.46 -0.00982697816897 -0.0158723405861 -674 6.465 -0.0097479308565 -0.0157467788803 -675 6.47 -0.00966950844575 -0.0156223778326 -676 6.475 -0.00959170516422 -0.0154991251586 -677 6.48 -0.00951451530045 -0.0153770087205 -678 6.485 -0.00943793320329 -0.0152560165249 -679 6.49 -0.00936195328122 -0.0151361367211 -680 6.495 -0.00928657000161 -0.0150173575989 -681 6.5 -0.00921177789005 -0.0148996675874 -682 6.505 -0.00913757152962 -0.0147830552523 -683 6.51 -0.00906394556024 -0.0146675092947 -684 6.515 -0.00899089467799 -0.0145530185491 -685 6.52 -0.00891841363446 -0.0144395719819 -686 6.525 -0.00884649723606 -0.0143271586891 -687 6.53 -0.00877514034341 -0.0142157678952 -688 6.535 -0.0087043378707 -0.0141053889514 -689 6.54 -0.00863408478503 -0.0139960113337 -690 6.545 -0.00856437610582 -0.0138876246413 -691 6.55 -0.00849520690421 -0.0137802185952 -692 6.555 -0.0084265723024 -0.0136737830367 -693 6.56 -0.0083584674731 -0.0135683079253 -694 6.565 -0.00829088763895 -0.0134637833379 -695 6.57 -0.00822382807187 -0.0133601994666 -696 6.575 -0.00815728409258 -0.0132575466177 -697 6.58 -0.00809125106997 -0.01315581521 -698 6.585 -0.00802572442054 -0.0130549957733 -699 6.59 -0.00796069960789 -0.0129550789471 -700 6.595 -0.00789617214214 -0.0128560554792 -701 6.6 -0.00783213757941 -0.0127579162242 -702 6.605 -0.00776859152128 -0.0126606521422 -703 6.61 -0.00770552961427 -0.0125642542974 -704 6.615 -0.00764294754931 -0.0124687138569 -705 6.62 -0.00758084106125 -0.0123740220889 -706 6.625 -0.00751920592835 -0.0122801703624 -707 6.63 -0.00745803797178 -0.0121871501447 -708 6.635 -0.00739733305512 -0.0120949530012 -709 6.64 -0.00733708708388 -0.0120035705934 -710 6.645 -0.00727729600504 -0.0119129946781 -711 6.65 -0.00721795580654 -0.0118232171061 -712 6.655 -0.00715906251684 -0.0117342298209 -713 6.66 -0.00710061220446 -0.0116460248577 -714 6.665 -0.00704260097752 -0.011558594342 -715 6.67 -0.00698502498328 -0.0114719304888 -716 6.675 -0.0069278804077 -0.011386025601 -717 6.68 -0.00687116347501 -0.0113008720688 -718 6.685 -0.00681487044729 -0.0112164623683 -719 6.69 -0.00675899762401 -0.0111327890605 -720 6.695 -0.00670354134163 -0.0110498447902 -721 6.7 -0.00664849797317 -0.010967622285 -722 6.705 -0.00659386392783 -0.0108861143542 -723 6.71 -0.00653963565053 -0.0108053138879 -724 6.715 -0.00648580962156 -0.0107252138558 -725 6.72 -0.00643238235617 -0.0106458073064 -726 6.725 -0.00637935040415 -0.0105670873659 -727 6.73 -0.00632671034949 -0.0104890472373 -728 6.735 -0.00627445880997 -0.0104116801994 -729 6.74 -0.00622259243676 -0.0103349796058 -730 6.745 -0.00617110791413 -0.0102589388842 -731 6.75 -0.00612000195897 -0.0101835515351 -732 6.755 -0.00606927132054 -0.0101088111315 -733 6.76 -0.00601891278001 -0.0100347113173 -734 6.765 -0.00596892315019 -0.00996124580682 -735 6.77 -0.00591929927513 -0.00988840838405 -736 6.775 -0.00587003802979 -0.00981619290146 -737 6.78 -0.00582113631969 -0.00974459327937 -738 6.785 -0.00577259108059 -0.00967360350506 -739 6.79 -0.00572439927814 -0.00960321763197 -740 6.795 -0.00567655790757 -0.00953342977884 -741 6.8 -0.00562906399335 -0.009464234129 -742 6.805 -0.00558191458887 -0.00939562492948 -743 6.81 -0.00553510677612 -0.00932759649031 -744 6.815 -0.00548863766541 -0.00926014318374 -745 6.82 -0.00544250439501 -0.00919325944343 -746 6.825 -0.00539670413088 -0.00912693976378 -747 6.83 -0.00535123406635 -0.00906117869914 -748 6.835 -0.00530609142185 -0.0089959708631 -749 6.84 -0.00526127344456 -0.00893131092779 -750 6.845 -0.00521677740819 -0.00886719362314 -751 6.85 -0.00517260061263 -0.0088036137362 -752 6.855 -0.00512874038373 -0.00874056611047 -753 6.86 -0.00508519407293 -0.00867804564517 -754 6.865 -0.00504195905709 -0.00861604729463 -755 6.87 -0.00499903273812 -0.00855456606758 -756 6.875 -0.00495641254277 -0.00849359702652 -757 6.88 -0.00491409592235 -0.00843313528707 -758 6.885 -0.00487208035245 -0.00837317601735 -759 6.89 -0.0048303633327 -0.00831371443731 -760 6.895 -0.00478894238648 -0.00825474581818 -761 6.9 -0.00474781506071 -0.00819626548178 -762 6.905 -0.00470697892557 -0.00813826879998 -763 6.91 -0.00466643157426 -0.00808075119406 -764 6.915 -0.00462617062273 -0.00802370813416 -765 6.92 -0.00458619370948 -0.00796713513869 -766 6.925 -0.00454649849529 -0.00791102777373 -767 6.93 -0.004507082663 -0.0078553816525 -768 6.935 -0.00446794391726 -0.00780019243478 -769 6.94 -0.00442907998431 -0.00774545582638 -770 6.945 -0.00439048861173 -0.00769116757859 -771 6.95 -0.00435216756826 -0.00763732348763 -772 6.955 -0.00431411464353 -0.00758391939413 -773 6.96 -0.00427632764786 -0.00753095118263 -774 6.965 -0.00423880441202 -0.00747841478103 -775 6.97 -0.00420154278708 -0.0074263061601 -776 6.975 -0.0041645406441 -0.00737462133297 -777 6.98 -0.004127795874 -0.00732335635464 -778 6.985 -0.00409130638732 -0.0072725073215 -779 6.99 -0.00405507011399 -0.00722207037082 -780 6.995 -0.00401908500318 -0.00717204168032 -781 7.0 -0.00398334902306 -0.00712241746764 -782 7.005 -0.00394786016061 -0.00707319398991 -783 7.01 -0.00391261642144 -0.00702436754329 -784 7.015 -0.00387761582957 -0.00697593446253 -785 7.02 -0.00384285642725 -0.00692789112049 -786 7.025 -0.00380833627479 -0.00688023392772 -787 7.03 -0.00377405345032 -0.00683295933202 -788 7.035 -0.00374000604966 -0.006786063818 -789 7.04 -0.00370619218613 -0.00673954390668 -790 7.045 -0.00367260999033 -0.00669339615506 -791 7.05 -0.00363925761 -0.0066476171557 -792 7.055 -0.00360613320981 -0.00660220353629 -793 7.06 -0.00357323497123 -0.00655715195929 -794 7.065 -0.00354056109232 -0.00651245912153 -795 7.07 -0.00350810978757 -0.00646812175376 -796 7.075 -0.00347587928773 -0.00642413662034 -797 7.08 -0.00344386783965 -0.00638050051877 -798 7.085 -0.00341207370611 -0.0063372102794 -799 7.09 -0.00338049516565 -0.006294262765 -800 7.095 -0.00334913051243 -0.0062516548704 -801 7.1 -0.00331797805604 -0.00620938352214 -802 7.105 -0.00328703612137 -0.00616744567807 -803 7.11 -0.00325630304843 -0.00612583832708 -804 7.115 -0.00322577719224 -0.00608455848864 -805 7.12 -0.00319545692261 -0.00604360321253 -806 7.125 -0.00316534062405 -0.00600296957848 -807 7.13 -0.00313542669558 -0.00596265469582 -808 7.135 -0.00310571355061 -0.00592265570314 -809 7.14 -0.00307619961678 -0.005882969768 -810 7.145 -0.00304688333584 -0.00584359408654 -811 7.15 -0.00301776316346 -0.00580452588324 -812 7.155 -0.00298883756913 -0.00576576241051 -813 7.16 -0.002960105036 -0.00572730094846 -814 7.165 -0.00293156406078 -0.00568913880453 -815 7.17 -0.00290321315354 -0.00565127331323 -816 7.175 -0.00287505083762 -0.0056137018358 -817 7.18 -0.00284707564951 -0.00557642175992 -818 7.185 -0.00281928613867 -0.00553943049944 -819 7.19 -0.00279168086743 -0.00550272549407 -820 7.195 -0.00276425841086 -0.00546630420907 -821 7.2 -0.00273701735665 -0.00543016413502 -822 7.205 -0.00270995630497 -0.00539430278748 -823 7.21 -0.00268307386833 -0.00535871770676 -824 7.215 -0.00265636867152 -0.00532340645761 -825 7.22 -0.00262983935139 -0.00528836662899 -826 7.225 -0.00260348455684 -0.00525359583375 -827 7.23 -0.00257730294861 -0.00521909170842 -828 7.235 -0.00255129319921 -0.00518485191292 -829 7.24 -0.00252545399279 -0.00515087413029 -830 7.245 -0.00249978402504 -0.00511715606646 -831 7.25 -0.00247428200305 -0.00508369545 -832 7.255 -0.00244894664521 -0.00505049003185 -833 7.26 -0.00242377668111 -0.0050175375851 -834 7.265 -0.00239877085142 -0.00498483590472 -835 7.27 -0.00237392790776 -0.00495238280735 -836 7.275 -0.00234924661264 -0.00492017613103 -837 7.28 -0.00232472573932 -0.004888213735 -838 7.285 -0.00230036407169 -0.00485649349945 -839 7.29 -0.00227616040422 -0.00482501332528 -840 7.295 -0.0022521135418 -0.00479377113392 -841 7.3 -0.00222822229968 -0.00476276486705 -842 7.305 -0.00220448550332 -0.00473199248642 -843 7.31 -0.00218090198837 -0.00470145197362 -844 7.315 -0.00215747060047 -0.00467114132986 -845 7.32 -0.00213419019525 -0.00464105857576 -846 7.325 -0.00211105963817 -0.00461120175114 -847 7.33 -0.00208807780443 -0.00458156891484 -848 7.335 -0.00206524357891 -0.00455215814447 -849 7.34 -0.00204255585605 -0.00452296753622 -850 7.345 -0.00202001353975 -0.00449399520468 -851 7.35 -0.00199761554332 -0.00446523928264 -852 7.355 -0.00197536078933 -0.00443669792087 -853 7.36 -0.00195324820956 -0.00440836928794 -854 7.365 -0.00193127674492 -0.00438025157005 -855 7.37 -0.00190944534533 -0.00435234297081 -856 7.375 -0.00188775296965 -0.00432464171107 -857 7.38 -0.00186619858559 -0.00429714602873 -858 7.385 -0.00184478116965 -0.00426985417856 -859 7.39 -0.00182349970697 -0.00424276443203 -860 7.395 -0.00180235319134 -0.00421587507713 -861 7.4 -0.00178134062504 -0.00418918441815 -862 7.405 -0.0017604610188 -0.0041626907756 -863 7.41 -0.0017397133917 -0.00413639248593 -864 7.415 -0.0017190967711 -0.00411028790146 -865 7.42 -0.00169861019256 -0.00408437539014 -866 7.425 -0.00167825269977 -0.00405865333542 -867 7.43 -0.00165802334445 -0.00403312013606 -868 7.435 -0.00163792118629 -0.00400777420601 -869 7.44 -0.00161794529289 -0.00398261397421 -870 7.445 -0.00159809473965 -0.00395763788446 -871 7.45 -0.00157836860971 -0.00393284439525 -872 7.455 -0.00155876599391 -0.00390823197958 -873 7.46 -0.00153928599065 -0.00388379912488 -874 7.465 -0.00151992770589 -0.00385954433278 -875 7.47 -0.00150069025303 -0.00383546611901 -876 7.475 -0.00148157275285 -0.00381156301323 -877 7.48 -0.00146257433348 -0.0037878335589 -878 7.485 -0.00144369413025 -0.00376427631313 -879 7.49 -0.00142493128571 -0.00374088984652 -880 7.495 -0.00140628494952 -0.00371767274304 -881 7.5 -0.00138775427835 -0.00369462359991 -882 7.505 -0.0013693384359 -0.00367174102741 -883 7.51 -0.00135103659275 -0.00364902364878 -884 7.515 -0.00133284792636 -0.00362647010008 -885 7.52 -0.00131477162096 -0.00360407903007 -886 7.525 -0.0012968068675 -0.00358184910005 -887 7.53 -0.0012789528636 -0.00355977898374 -888 7.535 -0.00126120881349 -0.00353786736716 -889 7.54 -0.00124357392793 -0.00351611294851 -890 7.545 -0.00122604742416 -0.00349451443802 -891 7.55 -0.00120862852584 -0.00347307055786 -892 7.555 -0.00119131646298 -0.00345178004197 -893 7.56 -0.0011741104719 -0.00343064163599 -894 7.565 -0.00115700979517 -0.0034096540971 -895 7.57 -0.00114001368154 -0.00338881619393 -896 7.575 -0.00112312138587 -0.00336812670643 -897 7.58 -0.00110633216913 -0.00334758442575 -898 7.585 -0.00108964529827 -0.00332718815413 -899 7.59 -0.00107306004622 -0.00330693670479 -900 7.595 -0.00105657569181 -0.00328682890181 -901 7.6 -0.00104019151973 -0.00326686358005 -902 7.605 -0.00102390682047 -0.00324703958498 -903 7.61 -0.00100772089024 -0.00322735577263 -904 7.615 -0.000991633030992 -0.00320781100945 -905 7.62 -0.000975642550274 -0.00318840417222 -906 7.625 -0.000959748761248 -0.00316913414793 -907 7.63 -0.000943950982612 -0.00314999983371 -908 7.635 -0.00092824853855 -0.00313100013668 -909 7.64 -0.000912640758688 -0.00311213397388 -910 7.645 -0.000897126978043 -0.00309340027216 -911 7.65 -0.000881706536971 -0.0030747979681 -912 7.655 -0.000866378781123 -0.00305632600787 -913 7.66 -0.000851143061394 -0.00303798334719 -914 7.665 -0.000835998733877 -0.00301976895117 -915 7.67 -0.000820945159817 -0.00300168179428 -916 7.675 -0.000805981705564 -0.0029837208602 -917 7.68 -0.000791107742523 -0.00296588514177 -918 7.685 -0.000776322647117 -0.00294817364088 -919 7.69 -0.000761625800734 -0.00293058536838 -920 7.695 -0.000747016589687 -0.00291311934398 -921 7.7 -0.000732494405167 -0.00289577459618 -922 7.705 -0.000718058643203 -0.00287855016219 -923 7.71 -0.000703708704613 -0.0028614450878 -924 7.715 -0.000689443994968 -0.00284445842736 -925 7.72 -0.000675263924546 -0.00282758924361 -926 7.725 -0.000661167908286 -0.0028108366077 -927 7.73 -0.000647155365757 -0.002794199599 -928 7.735 -0.000633225721105 -0.00277767730511 -929 7.74 -0.000619378403022 -0.00276126882172 -930 7.745 -0.000605612844698 -0.00274497325255 -931 7.75 -0.000591928483787 -0.00272878970927 -932 7.755 -0.000578324762364 -0.00271271731143 -933 7.76 -0.000564801126885 -0.00269675518635 -934 7.765 -0.000551357028154 -0.00268090246909 -935 7.77 -0.000537991921277 -0.00266515830234 -936 7.775 -0.00052470526563 -0.00264952183636 -937 7.78 -0.000511496524817 -0.00263399222891 -938 7.785 -0.000498365166635 -0.00261856864514 -939 7.79 -0.000485310663039 -0.00260325025757 -940 7.795 -0.0004723324901 -0.00258803624599 -941 7.8 -0.000459430127974 -0.00257292579737 -942 7.805 -0.000446603060865 -0.00255791810586 -943 7.81 -0.000433850776986 -0.00254301237261 -944 7.815 -0.000421172768528 -0.00252820780582 -945 7.82 -0.000408568531625 -0.00251350362058 -946 7.825 -0.000396037566317 -0.00249889903884 -947 7.83 -0.000383579376517 -0.00248439328937 -948 7.835 -0.000371193469977 -0.00246998560763 -949 7.84 -0.000358879358258 -0.00245567523575 -950 7.845 -0.000346636556689 -0.00244146142247 -951 7.85 -0.000334464584344 -0.00242734342306 -952 7.855 -0.000322362964 -0.00241332049923 -953 7.86 -0.000310331222112 -0.00239939191913 -954 7.865 -0.000298368888779 -0.00238555695723 -955 7.87 -0.000286475497709 -0.00237181489431 -956 7.875 -0.000274650586192 -0.00235816501734 -957 7.88 -0.00026289369507 -0.00234460661948 -958 7.885 -0.000251204368701 -0.00233113899997 -959 7.89 -0.000239582154932 -0.00231776146411 -960 7.895 -0.000228026605069 -0.00230447332318 -961 7.9 -0.000216537273846 -0.0022912738944 -962 7.905 -0.000205113719399 -0.00227816250086 -963 7.91 -0.000193755503231 -0.00226513847144 -964 7.915 -0.000182462190187 -0.00225220114081 -965 7.92 -0.000171233348425 -0.00223934984935 -966 7.925 -0.000160068549386 -0.00222658394306 -967 7.93 -0.000148967367767 -0.00221390277357 -968 7.935 -0.000137929381494 -0.00220130569803 -969 7.94 -0.000126954171692 -0.00218879207909 -970 7.945 -0.000116041322662 -0.00217636128485 -971 7.95 -0.000105190421847 -0.00216401268878 -972 7.955 -9.44010598127e-05 -0.00215174566969 -973 7.96 -8.36728302154e-05 -0.0021395596117 -974 7.965 -7.30053297786e-05 -0.00212745390412 -975 7.97 -6.23981582662e-05 -0.00211542794149 -976 7.975 -5.18509184563e-05 -0.00210348112347 -977 7.98 -4.13632161162e-05 -0.0020916128548 -978 7.985 -3.09346599767e-05 -0.00207982254527 -979 7.99 -2.05648617073e-05 -0.00206810960966 -980 7.995 -1.0253435891e-05 -0.00205647346771 -981 8.0 0.0 0.0 diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+minichaperone/moltemplate_files/table_minichaperone_h=0.dat b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+minichaperone/moltemplate_files/table_minichaperone_h=0.dat deleted file mode 100644 index 82eaa7e158..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+minichaperone/moltemplate_files/table_minichaperone_h=0.dat +++ /dev/null @@ -1,989 +0,0 @@ -# Interaction between a chaperone wall and hydrophilic ("L", "N") beads (h=0.0) -# Generated using: -# generate_tables/calc_chaperone_table.py 1.0 1.0 3.0 0.00 3.1 8.0 981 True - -CH_H0 -N 981 R 3.1 8.0 - -1 3.1 24322007640.7 2.44004657299e+12 -2 3.105 14907558394.3 1.42456861215e+12 -3 3.11 9347035105.18 8.52735941633e+11 -4 3.115 5983077933.86 5.22188377701e+11 -5 3.12 3902959636.31 3.26497584961e+11 -6 3.125 2590663239.27 2.08082071378e+11 -7 3.13 1747363476.38 1.34970838198e+11 -8 3.135 1196150660.14 88985299862.7 -9 3.14 830139558.184 59560058382.9 -10 3.145 583526310.01 40428734750.9 -11 3.15 415085889.414 27804165925.8 -12 3.155 298569038.21 19357152203.7 -13 3.16 217007230.904 13631625105.8 -14 3.165 159275126.218 9703361847.17 -15 3.17 117981153.625 6977285889.84 -16 3.175 88152959.6539 5065076691.93 -17 3.18 66406248.0614 3710118471.36 -18 3.185 50412054.1061 2740803858.1 -19 3.19 38550891.1571 2041079190.29 -20 3.195 29685484.2812 1531623758.63 -21 3.2 23009711.8183 1157676125.86 -22 3.205 17947107.7408 881068391.885 -23 3.21 14081960.9175 674956471.214 -24 3.215 11112084.5698 520297467.685 -25 3.22 8816139.11379 403471527.483 -26 3.225 7030823.80219 314661158.279 -27 3.23 5634822.39381 246736805.049 -28 3.235 4537411.91017 194483958.161 -29 3.24 3670317.94503 154062728.557 -30 3.245 2981848.4679 122627006.268 -31 3.25 2432639.00923 98054064.6797 -32 3.255 1992545.82032 78751201.0309 -33 3.26 1638362.63452 63516512.707 -34 3.265 1352132.30623 51437989.9558 -35 3.27 1119890.91156 41819915.4536 -36 3.275 930728.197936 34128853.5593 -37 3.28 776080.832192 27953782.5881 -38 3.285 649197.950984 22976500.4202 -39 3.29 544734.946388 18949536.6006 -40 3.295 458443.200409 15679580.461 -41 3.3 386931.981432 13014984.83 -42 3.305 327484.882814 10836296.983 -43 3.31 277917.684205 9049049.63384 -44 3.315 236467.817902 7578247.52911 -45 3.32 201708.057716 6364132.2427 -46 3.325 172478.852825 5358914.96458 -47 3.33 147835.073691 4524245.63494 -48 3.335 127003.943407 3829244.63171 -49 3.34 109351.684422 3248966.03768 -50 3.345 94356.982001 2763193.35086 -51 3.35 81589.7991199 2355492.28163 -52 3.355 70694.4075656 2012463.12085 -53 3.36 61375.7524283 1723148.60489 -54 3.365 53388.4609277 1478563.37272 -55 3.37 46527.9558627 1271318.83571 -56 3.375 40623.2494805 1095323.17118 -57 3.38 35531.0832305 945540.660872 -58 3.385 31131.1487289 817798.059995 -59 3.39 27322.1798598 708628.354433 -60 3.395 24018.7487675 615144.330958 -61 3.4 21148.6321858 534935.990585 -62 3.405 18650.6411473 465987.08561 -63 3.41 16472.8281676 406607.038172 -64 3.415 14571.00272 355375.264352 -65 3.42 12907.4991276 311095.530355 -66 3.425 11450.1516342 272758.442538 -67 3.43 10171.439929 239510.549012 -68 3.435 9047.7752383 210628.82877 -69 3.44 8058.90260095 185499.581541 -70 3.445 7187.39938846 163600.920836 -71 3.45 6418.25372556 144488.223969 -72 3.455 5738.50938334 127782.014261 -73 3.46 5136.9660889 113157.848128 -74 3.465 4603.92612777 100337.85845 -75 3.47 4130.97969454 89083.6690543 -76 3.475 3710.8227393 79190.4466465 -77 3.48 3337.10211855 70481.8981958 -78 3.485 3004.28373073 62806.0557792 -79 3.49 2707.54003568 56031.718535 -80 3.495 2442.65394998 50045.4440029 -81 3.5 2205.93660145 44748.9996316 -82 3.505 1994.15683268 40057.2004294 -83 3.51 1804.48068152 35896.0712099 -84 3.515 1634.41934741 32201.2821773 -85 3.52 1481.78438725 28916.8150767 -86 3.525 1344.64907977 25993.8241582 -87 3.53 1221.31506159 23389.6620133 -88 3.535 1110.28347503 21067.0451721 -89 3.54 1010.22998333 18993.3383579 -90 3.545 919.9831055 17139.9396418 -91 3.55 838.505404885 15481.7515237 -92 3.555 764.877134293 13996.7253013 -93 3.56 698.281998657 12665.4680354 -94 3.565 637.994745566 11470.9030593 -95 3.57 583.370335637 10397.9763514 -96 3.575 533.834480178 9433.40224818 -97 3.58 488.875363677 8565.44294671 -98 3.585 448.036394307 7783.71706925 -99 3.59 410.909847488 7079.03325566 -100 3.595 377.131286207 6443.24533767 -101 3.6 346.374657747 5869.126147 -102 3.605 318.34798013 5350.25743201 -103 3.61 292.789543287 4880.93371692 -104 3.615 269.464560006 4456.07824337 -105 3.62 248.162210353 4071.16939457 -106 3.625 228.693030668 3722.17622503 -107 3.63 210.886604667 3405.5019084 -108 3.635 194.589519671 3117.93407879 -109 3.64 179.663555764 2856.60118023 -110 3.645 165.984079802 2618.93405823 -111 3.65 153.438619766 2402.63212994 -112 3.655 141.925598023 2205.6335579 -113 3.66 131.353204775 2026.08892777 -114 3.665 121.638395266 1862.33799643 -115 3.67 112.705996374 1712.88913275 -116 3.675 104.487909965 1576.40112248 -117 3.68 96.9224019089 1451.66705065 -118 3.685 89.9534670245 1337.6000114 -119 3.69 83.5302613658 1233.22042683 -120 3.695 77.6065942935 1137.6447839 -121 3.7 72.1404736708 1050.07562216 -122 3.705 67.0936983024 969.792625804 -123 3.71 62.431492423 896.144691745 -124 3.715 58.1221776441 828.54286083 -125 3.72 54.1368782948 766.454013201 -126 3.725 50.4492565603 709.395240693 -127 3.73 47.0352742263 656.928819585 -128 3.735 43.8729782026 608.65771617 -129 3.74 40.9423073113 564.221565572 -130 3.745 38.2249181088 523.293071279 -131 3.75 35.7040277571 485.57477893 -132 3.755 33.3642721761 450.796183363 -133 3.76 31.1915779041 418.711132572 -134 3.765 29.1730462649 389.095496464 -135 3.77 27.296848588 361.745071901 -136 3.775 25.5521313672 336.473698771 -137 3.78 23.9289303577 313.111564661 -138 3.785 22.4180927206 291.503678217 -139 3.79 21.0112064166 271.508493474 -140 3.795 19.7005361332 252.996669413 -141 3.8 18.4789651059 235.849950713 -142 3.805 17.3399422592 219.960157211 -143 3.81 16.2774341511 205.228270919 -144 3.815 15.2858812611 191.563610676 -145 3.82 14.3601582029 178.88308554 -146 3.825 13.4955374911 167.110519006 -147 3.83 12.6876565243 156.176036954 -148 3.835 11.9324874825 146.015512988 -149 3.84 11.2263098661 136.570065484 -150 3.845 10.5656854316 127.785601256 -151 3.85 9.94743530166 119.612401285 -152 3.855 9.36861904981 112.004744426 -153 3.86 8.82651557999 104.920565393 -154 3.865 8.31860563683 98.3211437563 -155 3.87 7.84255579999 92.1708209642 -156 3.875 7.39620382887 86.4367427306 -157 3.88 6.97754523696 81.0886243871 -158 3.885 6.58472098661 76.0985370389 -159 3.89 6.21600620515 71.4407125773 -160 3.895 5.86979983242 67.0913657925 -161 3.9 5.54461511838 63.0285320059 -162 3.905 5.23907089671 59.2319187891 -163 3.91 4.95188356739 55.6827704829 -164 3.915 4.68185972707 52.3637443466 -165 3.92 4.42788939186 49.2587972858 -166 3.925 4.18893976204 46.353082203 -167 3.93 3.96404948281 43.6328531095 -168 3.935 3.75232335915 41.0853782151 -169 3.94 3.55292748687 38.6988602882 -170 3.945 3.36508476491 36.4623636443 -171 3.95 3.18807075749 34.3657471793 -172 3.955 3.021209877 32.3996029206 -173 3.96 2.86387186138 30.5551996145 -174 3.965 2.71546852189 28.8244309147 -175 3.97 2.57545073925 27.1997677761 -176 3.975 2.44330568809 25.6742146917 -177 3.98 2.31855427126 24.2412694474 -178 3.985 2.20074874724 22.8948860937 -179 3.99 2.08947053515 21.6294408646 -180 3.995 1.98432818342 20.4397007945 -181 4.0 1.88495548901 19.3207948084 -182 4.005 1.79100975549 18.2681870794 -183 4.01 1.70217017901 17.2776524655 -184 4.015 1.61813635232 16.3452538542 -185 4.02 1.53862687753 15.467321259 -186 4.025 1.4633780794 14.6404325234 -187 4.03 1.3921428113 13.8613955037 -188 4.035 1.32468934683 13.1272316094 -189 4.04 1.26080035064 12.435160592 -190 4.045 1.20027192224 11.7825864834 -191 4.05 1.14291270762 11.1670845906 -192 4.055 1.08854307328 10.5863894642 -193 4.06 1.03699433825 10.0383837622 -194 4.065 0.988108059646 9.5210879405 -195 4.07 0.941735367837 9.03265070365 -196 4.075 0.897736347632 8.57134015767 -197 4.08 0.855979462015 8.13553560989 -198 4.085 0.816341015387 7.72371996598 -199 4.09 0.778704653425 7.33447267828 -200 4.095 0.74296089691 6.96646320305 -201 4.1 0.709006707075 6.61844492796 -202 4.105 0.676745080218 6.28924953404 -203 4.11 0.646084669489 5.97778175928 -204 4.115 0.616939431912 5.68301453361 -205 4.12 0.589228298872 5.40398445752 -206 4.125 0.562874868393 5.13978759855 -207 4.13 0.537807117698 4.88957558211 -208 4.135 0.513957134618 4.65255195486 -209 4.14 0.491260866548 4.42796880052 -210 4.145 0.469657885731 4.21512358966 -211 4.15 0.449091169745 4.01335624628 -212 4.155 0.429506896145 3.82204641559 -213 4.16 0.410854250299 3.64061091811 -214 4.165 0.393085245513 3.46850137704 -215 4.17 0.376154554607 3.30520200609 -216 4.175 0.360019352187 3.15022754657 -217 4.18 0.34463916687 3.00312134286 -218 4.185 0.329975742808 2.86345354671 -219 4.19 0.315992909894 2.730819441 -220 4.195 0.30265646206 2.60483787474 -221 4.2 0.289934043143 2.48514980144 -222 4.205 0.277795039817 2.37141691363 -223 4.21 0.26621048112 2.26332036686 -224 4.215 0.255152944156 2.160559587 -225 4.22 0.244596465565 2.06285115501 -226 4.225 0.234516458378 1.96992776403 -227 4.23 0.22488963393 1.88153724361 -228 4.235 0.215693928479 1.79744164671 -229 4.24 0.206908434252 1.71741639508 -230 4.245 0.198513334625 1.64124947915 -231 4.25 0.190489843169 1.56874070868 -232 4.255 0.182820146331 1.49970101084 -233 4.26 0.175487349508 1.43395177247 -234 4.265 0.168475426305 1.3713242237 -235 4.27 0.16176917078 1.31165886002 -236 4.275 0.155354152487 1.2548049004 -237 4.28 0.149216674142 1.20061977901 -238 4.285 0.143343731751 1.1489686684 -239 4.29 0.137722977049 1.09972403198 -240 4.295 0.13234268211 1.05276520399 -241 4.3 0.127191705983 1.00797799517 -242 4.305 0.122259463251 0.965254322417 -243 4.31 0.117535894375 0.924491860866 -244 4.315 0.113011437731 0.885593717092 -245 4.32 0.108677003225 0.848468121932 -246 4.325 0.104523947407 0.813028141752 -247 4.33 0.100544049971 0.779191406981 -248 4.335 0.0967294915884 0.746879856814 -249 4.34 0.0930728329625 0.716019499063 -250 4.345 0.0895669950612 0.686540184216 -251 4.35 0.0862052404384 0.658375392808 -252 4.355 0.08298115559 0.63146203527 -253 4.36 0.0798886342796 0.605740263498 -254 4.365 0.0769218617798 0.5811532934 -255 4.37 0.0740752999737 0.557647237752 -256 4.375 0.0713436732684 0.535170948731 -257 4.38 0.0687219552728 0.513675869532 -258 4.385 0.0662053561949 0.493115894506 -259 4.39 0.0637893109199 0.473447237321 -260 4.395 0.0614694677263 0.45462830664 -261 4.4 0.0592416776079 0.436619588871 -262 4.405 0.0571019841636 0.419383537567 -263 4.41 0.0550466140255 0.402884469071 -264 4.415 0.0530719677933 0.387088464035 -265 4.42 0.0511746114473 0.371963274467 -266 4.425 0.0493512682135 0.357478235973 -267 4.43 0.0475988108542 0.343604184887 -268 4.435 0.0459142543625 0.33031338001 -269 4.44 0.0442947490359 0.317579428671 -270 4.445 0.0427375739105 0.305377216875 -271 4.45 0.041240130534 0.293682843283 -272 4.455 0.0397999370598 0.282473556818 -273 4.46 0.0384146226445 0.271727697674 -274 4.465 0.0370819221326 0.261424641529 -275 4.47 0.035799671012 0.251544746799 -276 4.475 0.034565800626 0.242069304731 -277 4.48 0.0333783336288 0.232980492193 -278 4.485 0.0322353796696 0.224261326994 -279 4.49 0.0311351312947 0.215895625604 -280 4.495 0.0300758600554 0.207867963122 -281 4.5 0.0290559128103 0.200163635378 -282 4.505 0.0280737082121 0.192768623045 -283 4.51 0.0271277333693 0.185669557645 -284 4.515 0.0262165406731 0.178853689349 -285 4.52 0.0253387447812 0.172308856461 -286 4.525 0.0244930197498 0.166023456513 -287 4.53 0.023678096307 0.159986418851 -288 4.535 0.0228927592589 0.154187178661 -289 4.54 0.0221358450227 0.148615652333 -290 4.545 0.0214062392796 0.143262214105 -291 4.55 0.0207028747413 0.138117673905 -292 4.555 0.0200247290247 0.133173256332 -293 4.56 0.0193708226289 0.128420580717 -294 4.565 0.018740217009 0.123851642198 -295 4.57 0.0181320127424 0.119458793758 -296 4.575 0.017545347783 0.115234729179 -297 4.58 0.0169793957974 0.111172466848 -298 4.585 0.0164333645811 0.107265334394 -299 4.59 0.0159064945488 0.103506954082 -300 4.595 0.0153980572965 0.0998912289493 -301 4.6 0.0149073542304 0.0964123296321 -302 4.605 0.0144337152611 0.0930646818445 -303 4.61 0.0139764975575 0.0898429544837 -304 4.615 0.0135350843599 0.086742048322 -305 4.62 0.0131088838475 0.0837570852568 -306 4.625 0.0126973280587 0.0808833980908 -307 4.63 0.0122998718608 0.0781165208124 -308 4.635 0.0119159919677 0.0754521793521 -309 4.64 0.0115451860021 0.07288628279 -310 4.645 0.0111869716011 0.0704149149899 -311 4.65 0.010840885562 0.0680343266405 -312 4.655 0.0105064830275 0.0657409276799 -313 4.66 0.0101833367076 0.063531280086 -314 4.665 0.0098710361368 0.0614020910133 -315 4.67 0.00956918696433 0.0593502062585 -316 4.675 0.00927741027701 0.0573726040383 -317 4.68 0.00899534195191 0.0554663890638 -318 4.685 0.00872263203811 0.0536287868959 -319 4.69 0.00845894416602 0.0518571385691 -320 4.695 0.0082039549829 0.0501488954678 -321 4.7 0.00795735361347 0.0485016144454 -322 4.705 0.00771884114422 0.0469129531714 -323 4.71 0.00748813013054 0.045380665697 -324 4.715 0.00726494412547 0.0439025982277 -325 4.72 0.00704901722906 0.0424766850927 -326 4.725 0.00684009365745 0.0411009449015 -327 4.73 0.00663792733071 0.0397734768782 -328 4.735 0.00644228147858 0.0384924573653 -329 4.74 0.00625292826325 0.0372561364888 -330 4.745 0.00606964841851 0.0360628349754 -331 4.75 0.00589223090433 0.0349109411165 -332 4.755 0.00572047257643 0.0337989078704 -333 4.76 0.0055541778698 0.0327252500962 -334 4.765 0.00539315849596 0.0316885419138 -335 4.77 0.00523723315293 0.0306874141829 -336 4.775 0.00508622724762 0.0297205520964 -337 4.78 0.00493997262995 0.0287866928817 -338 4.785 0.00479830733822 0.0278846236056 -339 4.79 0.00466107535518 0.0270131790775 -340 4.795 0.00452812637438 0.0261712398457 -341 4.8 0.00439931557628 0.0253577302837 -342 4.805 0.00427450341372 0.0245716167613 -343 4.81 0.00415355540638 0.0238119058963 -344 4.815 0.00403634194372 0.0230776428841 -345 4.82 0.00392273809612 0.0223679099007 -346 4.825 0.00381262343384 0.0216818245753 -347 4.83 0.00370588185338 0.021018538531 -348 4.835 0.00360240141109 0.0203772359884 -349 4.84 0.00350207416352 0.0197571324301 -350 4.845 0.0034047960143 0.019157473324 -351 4.85 0.00331046656734 0.0185775329012 -352 4.855 0.00321898898591 0.0180166129873 -353 4.86 0.00313026985753 0.0174740418837 -354 4.865 0.00304421906424 0.0169491732974 -355 4.87 0.00296074965818 0.0164413853165 -356 4.875 0.00287977774216 0.0159500794299 -357 4.88 0.002801222355 0.0154746795881 -358 4.885 0.0027250053615 0.0150146313053 -359 4.89 0.00265105134676 0.0145694007979 -360 4.895 0.0025792875148 0.0141384741613 -361 4.9 0.00250964359108 0.0137213565802 -362 4.905 0.00244205172902 0.0133175715727 -363 4.91 0.00237644642012 0.0129266602662 -364 4.915 0.00231276440768 0.0125481807036 -365 4.92 0.00225094460389 0.0121817071786 -366 4.925 0.00219092801016 0.0118268295982 -367 4.93 0.00213265764061 0.011483152873 -368 4.935 0.00207607844856 0.011150296331 -369 4.94 0.00202113725576 0.0108278931578 -370 4.945 0.00196778268457 0.0105155898576 -371 4.95 0.00191596509257 0.0102130457388 -372 4.955 0.00186563650984 0.00991993241864 -373 4.96 0.0018167505786 0.00963593334953 -374 4.965 0.00176926249515 0.0093607433642 -375 4.97 0.0017231289541 0.00909406823946 -376 4.975 0.00167830809471 0.00883562427782 -377 4.98 0.00163475944922 0.00858513790595 -378 4.985 0.00159244389324 0.00834234528958 -379 4.99 0.001551323598 0.00810699196376 -380 4.995 0.00151136198435 0.00787883247819 -381 5.0 0.00147252367858 0.00765763005674 -382 5.005 0.00143477446984 0.00744315627058 -383 5.01 0.00139808126924 0.00723519072448 -384 5.015 0.00136241207038 0.00703352075553 -385 5.02 0.00132773591148 0.00683794114397 -386 5.025 0.00129402283882 0.00664825383541 -387 5.03 0.00126124387159 0.00646426767408 -388 5.035 0.00122937096804 0.00628579814667 -389 5.04 0.00119837699293 0.00611266713619 -390 5.045 0.00116823568608 0.00594470268561 -391 5.05 0.00113892163217 0.00578173877069 -392 5.055 0.00111041023163 0.00562361508175 -393 5.06 0.00108267767261 0.00547017681395 -394 5.065 0.00105570090391 0.00532127446577 -395 5.07 0.00102945760901 0.00517676364527 -396 5.075 0.00100392618096 0.00503650488393 -397 5.08 0.000979085698203 0.00490036345763 -398 5.085 0.000954915901321 0.00476820921459 -399 5.09 0.000931397170562 0.00463991640989 -400 5.095 0.000908510504214 0.00451536354643 -401 5.1 0.000886237497752 0.00439443322187 -402 5.105 0.000864560323733 0.00427701198153 -403 5.11 0.000843461712415 0.00416299017686 -404 5.115 0.000822924933066 0.00405226182927 -405 5.12 0.000802933775949 0.00394472449918 -406 5.125 0.000783472534939 0.00384027916001 -407 5.13 0.000764525990765 0.00373883007694 -408 5.135 0.000746079394846 0.00364028469024 -409 5.14 0.000728118453695 0.003544553503 -410 5.145 0.000710629313879 0.00345154997304 -411 5.15 0.000693598547507 0.00336119040893 -412 5.155 0.000677013138229 0.00327339386985 -413 5.16 0.00066086046772 0.00318808206921 -414 5.165 0.000645128302652 0.00310517928183 -415 5.17 0.000629804782101 0.00302461225459 -416 5.175 0.000614878405412 0.00294631012039 -417 5.18 0.000600338020472 0.00287020431528 -418 5.185 0.000586172812398 0.00279622849864 -419 5.19 0.00057237229261 0.00272431847632 -420 5.195 0.000558926288291 0.00265441212659 -421 5.2 0.000545824932198 0.00258644932878 -422 5.205 0.000533058652834 0.00252037189458 -423 5.21 0.00052061816495 0.0024561235018 -424 5.215 0.000508494460377 0.00239364963056 -425 5.22 0.000496678799167 0.00233289750178 -426 5.225 0.000485162701041 0.00227381601795 -427 5.23 0.000473937937122 0.00221635570597 -428 5.235 0.000462996521952 0.0021604686621 -429 5.24 0.000452330705781 0.00210610849886 -430 5.245 0.000441932967112 0.00205323029391 -431 5.25 0.000431796005499 0.00200179054064 -432 5.255 0.00042191273459 0.00195174710063 -433 5.26 0.000412276275402 0.00190305915777 -434 5.265 0.000402879949816 0.00185568717402 -435 5.27 0.0003937172743 0.00180959284671 -436 5.275 0.000384781953833 0.00176473906743 -437 5.28 0.000376067876031 0.00172108988228 -438 5.285 0.000367569105476 0.00167861045357 -439 5.29 0.000359279878223 0.00163726702293 -440 5.295 0.000351194596497 0.00159702687556 -441 5.3 0.000343307823559 0.00155785830593 -442 5.305 0.000335614278743 0.00151973058449 -443 5.31 0.00032810883266 0.0014826139257 -444 5.315 0.000320786502552 0.00144647945708 -445 5.32 0.000313642447802 0.00141129918936 -446 5.325 0.000306671965594 0.00137704598769 -447 5.33 0.000299870486707 0.00134369354382 -448 5.335 0.00029323357145 0.00131121634922 -449 5.34 0.000286756905732 0.00127958966922 -450 5.345 0.00028043629725 0.00124878951793 -451 5.35 0.000274267671812 0.00121879263406 -452 5.355 0.000268247069768 0.00118957645764 -453 5.36 0.000262370642562 0.00116111910739 -454 5.365 0.000256634649393 0.00113339935902 -455 5.37 0.000251035453984 0.00110639662416 -456 5.375 0.00024556952145 0.00108009093005 -457 5.38 0.000240233415275 0.0010544628999 -458 5.385 0.000235023794375 0.00102949373396 -459 5.39 0.000229937410261 0.00100516519115 -460 5.395 0.000224971104288 0.000981459571414 -461 5.4 0.000220121804997 0.000958359698545 -462 5.405 0.000215386525533 0.000935848903702 -463 5.41 0.000210762361152 0.000913911009406 -464 5.415 0.000206246486799 0.000892530314103 -465 5.42 0.000201836154771 0.000871691577231 -466 5.425 0.000197528692444 0.000851380004787 -467 5.43 0.000193321500075 0.000831581235376 -468 5.435 0.000189212048678 0.000812281326721 -469 5.44 0.000185197877955 0.000793466742621 -470 5.445 0.000181276594303 0.000775124340337 -471 5.45 0.000177445868872 0.000757241358398 -472 5.455 0.000173703435692 0.000739805404806 -473 5.46 0.000170047089853 0.000722804445631 -474 5.465 0.000166474685742 0.000706226793976 -475 5.47 0.000162984135336 0.000690061099303 -476 5.475 0.000159573406545 0.000674296337118 -477 5.48 0.000156240521608 0.000658921798975 -478 5.485 0.000152983555536 0.000643927082819 -479 5.49 0.000149800634601 0.000629302083639 -480 5.495 0.000146689934881 0.000615036984418 -481 5.5 0.000143649680835 0.000601122247385 -482 5.505 0.00014067814393 0.000587548605543 -483 5.51 0.000137773641309 0.000574307054471 -484 5.515 0.000134934534497 0.00056138884439 -485 5.52 0.000132159228148 0.000548785472487 -486 5.525 0.000129446168827 0.000536488675478 -487 5.53 0.000126793843833 0.000524490422414 -488 5.535 0.000124200780051 0.000512782907716 -489 5.54 0.000121665542848 0.000501358544429 -490 5.545 0.000119186734991 0.000490209957694 -491 5.55 0.000116762995603 0.000479329978423 -492 5.555 0.000114392999154 0.000468711637179 -493 5.56 0.000112075454472 0.000458348158245 -494 5.565 0.000109809103791 0.000448232953884 -495 5.57 0.000107592721827 0.000438359618774 -496 5.575 0.000105425114878 0.000428721924627 -497 5.58 0.000103305119949 0.000419313814967 -498 5.585 0.000101231603912 0.000410129400077 -499 5.59 9.92034626791e-05 0.000401162952103 -500 5.595 9.72196204062e-05 0.000392408900312 -501 5.6 9.5279028721e-05 0.00038386182649 -502 5.605 9.33806659696e-05 0.000375516460498 -503 5.61 9.1523536488e-05 0.000367367675949 -504 5.615 8.97066698933e-05 0.000359410486029 -505 5.62 8.79291203961e-05 0.000351640039446 -506 5.625 8.61899661332e-05 0.000344051616503 -507 5.63 8.44883085184e-05 0.000336640625287 -508 5.635 8.28232716138e-05 0.000329402597984 -509 5.64 8.11940015174e-05 0.000322333187302 -510 5.645 7.95996657698e-05 0.000315428163002 -511 5.65 7.80394527771e-05 0.000308683408537 -512 5.655 7.65125712508e-05 0.000302094917798 -513 5.66 7.50182496635e-05 0.000295658791947 -514 5.665 7.35557357199e-05 0.000289371236362 -515 5.67 7.21242958438e-05 0.000283228557659 -516 5.675 7.07232146788e-05 0.000277227160816 -517 5.68 6.93517946035e-05 0.000271363546381 -518 5.685 6.80093552604e-05 0.000265634307756 -519 5.69 6.66952330984e-05 0.000260036128578 -520 5.695 6.5408780928e-05 0.000254565780162 -521 5.7 6.41493674892e-05 0.000249220119037 -522 5.705 6.29163770311e-05 0.000243996084541 -523 5.71 6.17092089041e-05 0.000238890696497 -524 5.715 6.05272771628e-05 0.000233901052958 -525 5.72 5.93700101809e-05 0.000229024328015 -526 5.725 5.82368502757e-05 0.000224257769672 -527 5.73 5.7127253344e-05 0.000219598697784 -528 5.735 5.6040688508e-05 0.00021504450206 -529 5.74 5.49766377708e-05 0.000210592640118 -530 5.745 5.39345956813e-05 0.000206240635602 -531 5.75 5.29140690094e-05 0.000201986076352 -532 5.755 5.19145764286e-05 0.000197826612633 -533 5.76 5.09356482089e-05 0.000193759955407 -534 5.765 4.9976825917e-05 0.000189783874667 -535 5.77 4.90376621255e-05 0.000185896197809 -536 5.775 4.811772013e-05 0.000182094808056 -537 5.78 4.72165736735e-05 0.000178377642932 -538 5.785 4.63338066786e-05 0.000174742692774 -539 5.79 4.54690129874e-05 0.00017118799929 -540 5.795 4.46217961078e-05 0.000167711654157 -541 5.8 4.37917689674e-05 0.000164311797666 -542 5.805 4.29785536734e-05 0.000160986617396 -543 5.81 4.21817812796e-05 0.000157734346936 -544 5.815 4.14010915595e-05 0.000154553264637 -545 5.82 4.06361327855e-05 0.0001514416924 -546 5.825 3.98865615139e-05 0.000148397994509 -547 5.83 3.91520423762e-05 0.000145420576481 -548 5.835 3.84322478754e-05 0.000142507883961 -549 5.84 3.77268581883e-05 0.000139658401647 -550 5.845 3.70355609728e-05 0.000136870652241 -551 5.85 3.63580511802e-05 0.000134143195433 -552 5.855 3.56940308733e-05 0.000131474626912 -553 5.86 3.5043209048e-05 0.000128863577412 -554 5.865 3.44053014612e-05 0.000126308711771 -555 5.87 3.37800304622e-05 0.000123808728033 -556 5.875 3.31671248289e-05 0.000121362356562 -557 5.88 3.25663196081e-05 0.000118968359189 -558 5.885 3.1977355961e-05 0.000116625528379 -559 5.89 3.13999810112e-05 0.000114332686424 -560 5.895 3.0833947698e-05 0.000112088684656 -561 5.9 3.02790146332e-05 0.000109892402684 -562 5.905 2.97349459611e-05 0.000107742747652 -563 5.91 2.92015112233e-05 0.000105638653516 -564 5.915 2.86784852258e-05 0.000103579080344 -565 5.92 2.81656479105e-05 0.000101563013635 -566 5.925 2.76627842296e-05 9.95894636504e-05 -567 5.93 2.71696840234e-05 9.76574647761e-05 -568 5.935 2.66861419014e-05 9.57660748914e-05 -569 5.94 2.62119571261e-05 9.39143747606e-05 -570 5.945 2.57469335003e-05 9.21014674399e-05 -571 5.95 2.52908792569e-05 9.03264777011e-05 -572 5.955 2.4843606952e-05 8.85885514709e-05 -573 5.96 2.44049333599e-05 8.68868552854e-05 -574 5.965 2.39746793724e-05 8.522057576e-05 -575 5.97 2.35526698987e-05 8.35889190733e-05 -576 5.975 2.31387337693e-05 8.19911104654e-05 -577 5.98 2.27327036419e-05 8.04263937498e-05 -578 5.985 2.23344159097e-05 7.88940308385e-05 -579 5.99 2.19437106122e-05 7.739330128e-05 -580 5.995 2.15604313477e-05 7.59235018102e-05 -581 6.0 2.1184425189e-05 7.44839459145e-05 -582 6.005 2.08155426005e-05 7.3073963403e-05 -583 6.01 2.04536373574e-05 7.16928999962e-05 -584 6.015 2.00985664675e-05 7.03401169221e-05 -585 6.02 1.97501900945e-05 6.90149905246e-05 -586 6.025 1.94083714834e-05 6.77169118817e-05 -587 6.03 1.90729768878e-05 6.64452864341e-05 -588 6.035 1.87438754988e-05 6.51995336246e-05 -589 6.04 1.84209393761e-05 6.39790865457e-05 -590 6.045 1.81040433805e-05 6.27833915977e-05 -591 6.05 1.77930651083e-05 6.16119081557e-05 -592 6.055 1.74878848271e-05 6.04641082448e-05 -593 6.06 1.71883854134e-05 5.93394762249e-05 -594 6.065 1.68944522917e-05 5.82375084831e-05 -595 6.07 1.66059733752e-05 5.71577131349e-05 -596 6.075 1.63228390077e-05 5.60996097322e-05 -597 6.08 1.60449419074e-05 5.50627289806e-05 -598 6.085 1.57721771114e-05 5.40466124625e-05 -599 6.09 1.55044419226e-05 5.30508123689e-05 -600 6.095 1.52416358567e-05 5.20748912369e-05 -601 6.1 1.49836605915e-05 5.11184216954e-05 -602 6.105 1.47304199168e-05 5.01809862165e-05 -603 6.11 1.44818196863e-05 4.92621768737e-05 -604 6.115 1.42377677693e-05 4.83615951067e-05 -605 6.12 1.39981740054e-05 4.74788514917e-05 -606 6.125 1.37629501588e-05 4.66135655183e-05 -607 6.13 1.35320098744e-05 4.57653653718e-05 -608 6.135 1.33052686347e-05 4.49338877213e-05 -609 6.14 1.30826437185e-05 4.41187775132e-05 -610 6.145 1.28640541593e-05 4.33196877704e-05 -611 6.15 1.26494207056e-05 4.25362793959e-05 -612 6.155 1.24386657825e-05 4.17682209821e-05 -613 6.16 1.22317134528e-05 4.10151886251e-05 -614 6.165 1.20284893808e-05 4.02768657433e-05 -615 6.17 1.18289207957e-05 3.95529429009e-05 -616 6.175 1.16329364562e-05 3.88431176356e-05 -617 6.18 1.14404666165e-05 3.81470942917e-05 -618 6.185 1.12514429921e-05 3.74645838561e-05 -619 6.19 1.10657987276e-05 3.67953037992e-05 -620 6.195 1.08834683642e-05 3.61389779202e-05 -621 6.2 1.07043878085e-05 3.54953361956e-05 -622 6.205 1.05284943023e-05 3.48641146318e-05 -623 6.21 1.03557263924e-05 3.42450551216e-05 -624 6.215 1.01860239019e-05 3.36379053043e-05 -625 6.22 1.00193279015e-05 3.30424184292e-05 -626 6.225 9.8555806818e-06 3.24583532225e-05 -627 6.23 9.69472572662e-06 3.18854737577e-05 -628 6.235 9.53670768611e-06 3.13235493295e-05 -629 6.24 9.38147235122e-06 3.07723543299e-05 -630 6.245 9.22896662842e-06 3.02316681289e-05 -631 6.25 9.07913851515e-06 2.97012749568e-05 -632 6.255 8.93193707577e-06 2.918096379e-05 -633 6.26 8.78731241814e-06 2.86705282402e-05 -634 6.265 8.64521567069e-06 2.81697664451e-05 -635 6.27 8.50559896007e-06 2.76784809632e-05 -636 6.275 8.36841538931e-06 2.71964786701e-05 -637 6.28 8.23361901646e-06 2.6723570658e-05 -638 6.285 8.1011648338e-06 2.62595721375e-05 -639 6.29 7.97100874743e-06 2.58043023419e-05 -640 6.295 7.84310755745e-06 2.53575844336e-05 -641 6.3 7.71741893849e-06 2.49192454134e-05 -642 6.305 7.59390142079e-06 2.44891160312e-05 -643 6.31 7.47251437163e-06 2.40670306997e-05 -644 6.315 7.35321797725e-06 2.36528274098e-05 -645 6.32 7.23597322517e-06 2.32463476478e-05 -646 6.325 7.12074188691e-06 2.28474363155e-05 -647 6.33 7.00748650108e-06 2.24559416513e-05 -648 6.335 6.89617035696e-06 2.2071715154e-05 -649 6.34 6.7867574783e-06 2.16946115076e-05 -650 6.345 6.67921260764e-06 2.1324488509e-05 -651 6.35 6.5735011909e-06 2.09612069965e-05 -652 6.355 6.46958936234e-06 2.06046307805e-05 -653 6.36 6.3674439299e-06 2.02546265761e-05 -654 6.365 6.26703236079e-06 1.99110639364e-05 -655 6.37 6.16832276753e-06 1.95738151888e-05 -656 6.375 6.07128389417e-06 1.92427553714e-05 -657 6.38 5.97588510293e-06 1.89177621723e-05 -658 6.385 5.88209636109e-06 1.85987158689e-05 -659 6.39 5.7898882282e-06 1.828549927e-05 -660 6.395 5.69923184355e-06 1.79779976587e-05 -661 6.4 5.61009891393e-06 1.76760987363e-05 -662 6.405 5.52246170172e-06 1.73796925683e-05 -663 6.41 5.43629301316e-06 1.70886715312e-05 -664 6.415 5.35156618692e-06 1.68029302607e-05 -665 6.42 5.26825508299e-06 1.6522365601e-05 -666 6.425 5.18633407167e-06 1.62468765557e-05 -667 6.43 5.105778023e-06 1.59763642392e-05 -668 6.435 5.02656229621e-06 1.57107318301e-05 -669 6.44 4.94866272963e-06 1.54498845249e-05 -670 6.445 4.87205563062e-06 1.51937294934e-05 -671 6.45 4.79671776585e-06 1.49421758345e-05 -672 6.455 4.72262635178e-06 1.4695134534e-05 -673 6.46 4.64975904529e-06 1.44525184224e-05 -674 6.465 4.57809393461e-06 1.42142421344e-05 -675 6.47 4.50760953034e-06 1.39802220687e-05 -676 6.475 4.43828475677e-06 1.37503763495e-05 -677 6.48 4.37009894334e-06 1.35246247885e-05 -678 6.485 4.30303181628e-06 1.33028888476e-05 -679 6.49 4.23706349046e-06 1.30850916027e-05 -680 6.495 4.17217446142e-06 1.28711577084e-05 -681 6.5 4.10834559754e-06 1.26610133637e-05 -682 6.505 4.04555813243e-06 1.24545862778e-05 -683 6.51 3.98379365744e-06 1.22518056372e-05 -684 6.515 3.92303411434e-06 1.20526020738e-05 -685 6.52 3.86326178824e-06 1.18569076334e-05 -686 6.525 3.8044593005e-06 1.16646557444e-05 -687 6.53 3.74660960198e-06 1.14757811888e-05 -688 6.535 3.68969596629e-06 1.12902200718e-05 -689 6.54 3.63370198326e-06 1.11079097938e-05 -690 6.545 3.57861155257e-06 1.09287890224e-05 -691 6.55 3.52440887742e-06 1.07527976647e-05 -692 6.555 3.47107845843e-06 1.05798768409e-05 -693 6.56 3.41860508767e-06 1.04099688579e-05 -694 6.565 3.36697384274e-06 1.02430171842e-05 -695 6.57 3.31617008104e-06 1.00789664243e-05 -696 6.575 3.26617943417e-06 9.91776229528e-06 -697 6.58 3.21698780242e-06 9.75935160201e-06 -698 6.585 3.16858134936e-06 9.60368221456e-06 -699 6.59 3.12094649663e-06 9.45070304518e-06 -700 6.595 3.07406991872e-06 9.30036402612e-06 -701 6.6 3.02793853796e-06 9.15261608793e-06 -702 6.605 2.98253951958e-06 9.00741113824e-06 -703 6.61 2.93786026687e-06 8.86470204097e-06 -704 6.615 2.89388841646e-06 8.72444259607e-06 -705 6.62 2.85061183368e-06 8.58658751973e-06 -706 6.625 2.80801860801e-06 8.45109242494e-06 -707 6.63 2.76609704869e-06 8.31791380259e-06 -708 6.635 2.72483568033e-06 8.18700900294e-06 -709 6.64 2.68422323868e-06 8.05833621753e-06 -710 6.645 2.64424866648e-06 7.93185446144e-06 -711 6.65 2.60490110936e-06 7.80752355606e-06 -712 6.655 2.56616991186e-06 7.6853041121e-06 -713 6.66 2.52804461354e-06 7.56515751309e-06 -714 6.665 2.49051494513e-06 7.44704589922e-06 -715 6.67 2.45357082481e-06 7.33093215148e-06 -716 6.675 2.41720235453e-06 7.21677987627e-06 -717 6.68 2.38139981644e-06 7.10455339021e-06 -718 6.685 2.34615366934e-06 6.9942177054e-06 -719 6.69 2.31145454526e-06 6.88573851497e-06 -720 6.695 2.27729324613e-06 6.7790821789e-06 -721 6.7 2.2436607404e-06 6.67421571025e-06 -722 6.705 2.21054815986e-06 6.57110676157e-06 -723 6.71 2.17794679649e-06 6.46972361177e-06 -724 6.715 2.14584809929e-06 6.3700351531e-06 -725 6.72 2.11424367135e-06 6.27201087853e-06 -726 6.725 2.08312526676e-06 6.17562086942e-06 -727 6.73 2.05248478781e-06 6.08083578334e-06 -728 6.735 2.02231428205e-06 5.98762684229e-06 -729 6.74 1.99260593955e-06 5.89596582112e-06 -730 6.745 1.96335209014e-06 5.80582503618e-06 -731 6.75 1.93454520075e-06 5.71717733423e-06 -732 6.755 1.90617787275e-06 5.62999608165e-06 -733 6.76 1.87824283942e-06 5.54425515378e-06 -734 6.765 1.85073296341e-06 5.4599289246e-06 -735 6.77 1.82364123426e-06 5.37699225653e-06 -736 6.775 1.79696076603e-06 5.29542049053e-06 -737 6.78 1.77068479486e-06 5.21518943638e-06 -738 6.785 1.74480667672e-06 5.13627536317e-06 -739 6.79 1.71931988509e-06 5.05865498999e-06 -740 6.795 1.69421800875e-06 4.98230547687e-06 -741 6.8 1.66949474959e-06 4.90720441581e-06 -742 6.805 1.6451439205e-06 4.83332982211e-06 -743 6.81 1.62115944323e-06 4.76066012583e-06 -744 6.815 1.59753534637e-06 4.68917416347e-06 -745 6.82 1.57426576334e-06 4.61885116973e-06 -746 6.825 1.55134493038e-06 4.54967076962e-06 -747 6.83 1.52876718466e-06 4.48161297055e-06 -748 6.835 1.50652696239e-06 4.41465815471e-06 -749 6.84 1.48461879691e-06 4.3487870716e-06 -750 6.845 1.46303731695e-06 4.28398083065e-06 -751 6.85 1.44177724478e-06 4.22022089406e-06 -752 6.855 1.42083339451e-06 4.15748906981e-06 -753 6.86 1.40020067034e-06 4.09576750471e-06 -754 6.865 1.37987406492e-06 4.03503867774e-06 -755 6.87 1.35984865768e-06 3.97528539342e-06 -756 6.875 1.34011961322e-06 3.91649077535e-06 -757 6.88 1.32068217977e-06 3.85863825993e-06 -758 6.885 1.30153168756e-06 3.80171159016e-06 -759 6.89 1.2826635474e-06 3.74569480958e-06 -760 6.895 1.26407324911e-06 3.69057225636e-06 -761 6.9 1.2457563601e-06 3.63632855747e-06 -762 6.905 1.22770852394e-06 3.58294862303e-06 -763 6.91 1.20992545896e-06 3.53041764074e-06 -764 6.915 1.19240295686e-06 3.47872107044e-06 -765 6.92 1.17513688137e-06 3.42784463875e-06 -766 6.925 1.15812316694e-06 3.37777433388e-06 -767 6.93 1.14135781743e-06 3.32849640049e-06 -768 6.935 1.12483690484e-06 3.27999733473e-06 -769 6.94 1.10855656808e-06 3.23226387928e-06 -770 6.945 1.09251301173e-06 3.18528301858e-06 -771 6.95 1.07670250488e-06 3.13904197413e-06 -772 6.955 1.06112137989e-06 3.09352819987e-06 -773 6.96 1.0457660313e-06 3.0487293777e-06 -774 6.965 1.03063291469e-06 3.00463341302e-06 -775 6.97 1.01571854555e-06 2.96122843043e-06 -776 6.975 1.0010194982e-06 2.9185027695e-06 -777 6.98 9.86532404745e-07 2.87644498061e-06 -778 6.985 9.72253954022e-07 2.83504382088e-06 -779 6.99 9.58180890566e-07 2.79428825018e-06 -780 6.995 9.44310013618e-07 2.75416742728e-06 -781 7.0 9.30638176135e-07 2.71467070595e-06 -782 7.005 9.17162283824e-07 2.6757876313e-06 -783 7.01 9.03879294199e-07 2.63750793605e-06 -784 7.015 8.90786215647e-07 2.59982153697e-06 -785 7.02 8.77880106517e-07 2.56271853136e-06 -786 7.025 8.6515807423e-07 2.5261891936e-06 -787 7.03 8.52617274397e-07 2.49022397175e-06 -788 7.035 8.40254909964e-07 2.4548134843e-06 -789 7.04 8.28068230364e-07 2.41994851684e-06 -790 7.045 8.16054530689e-07 2.38562001899e-06 -791 7.05 8.04211150882e-07 2.35181910119e-06 -792 7.055 7.92535474938e-07 2.3185370317e-06 -793 7.06 7.81024930121e-07 2.28576523364e-06 -794 7.065 7.696769862e-07 2.25349528197e-06 -795 7.07 7.58489154692e-07 2.22171890072e-06 -796 7.075 7.47458988133e-07 2.19042796013e-06 -797 7.08 7.36584079342e-07 2.15961447389e-06 -798 7.085 7.2586206072e-07 2.12927059646e-06 -799 7.09 7.15290603549e-07 2.09938862041e-06 -800 7.095 7.04867417307e-07 2.06996097384e-06 -801 7.1 6.94590249e-07 2.04098021782e-06 -802 7.105 6.84456882499e-07 2.01243904392e-06 -803 7.11 6.74465137898e-07 1.98433027176e-06 -804 7.115 6.64612870877e-07 1.9566468466e-06 -805 7.12 6.5489797208e-07 1.92938183703e-06 -806 7.125 6.45318366505e-07 1.90252843264e-06 -807 7.13 6.35872012904e-07 1.87607994179e-06 -808 7.135 6.26556903196e-07 1.85002978938e-06 -809 7.14 6.17371061887e-07 1.8243715147e-06 -810 7.145 6.08312545506e-07 1.7990987693e-06 -811 7.15 5.99379442048e-07 1.77420531491e-06 -812 7.155 5.90569870428e-07 1.74968502142e-06 -813 7.16 5.81881979945e-07 1.72553186483e-06 -814 7.165 5.73313949757e-07 1.70173992537e-06 -815 7.17 5.64863988364e-07 1.67830338549e-06 -816 7.175 5.56530333103e-07 1.65521652804e-06 -817 7.18 5.4831124965e-07 1.63247373439e-06 -818 7.185 5.40205031528e-07 1.61006948263e-06 -819 7.19 5.32209999637e-07 1.58799834581e-06 -820 7.195 5.24324501773e-07 1.56625499017e-06 -821 7.2 5.16546912175e-07 1.54483417343e-06 -822 7.205 5.08875631066e-07 1.52373074317e-06 -823 7.21 5.01309084211e-07 1.50293963511e-06 -824 7.215 4.93845722479e-07 1.48245587157e-06 -825 7.22 4.86484021414e-07 1.46227455985e-06 -826 7.225 4.79222480814e-07 1.44239089069e-06 -827 7.23 4.72059624319e-07 1.42280013677e-06 -828 7.235 4.64993999004e-07 1.4034976512e-06 -829 7.24 4.58024174978e-07 1.38447886607e-06 -830 7.245 4.51148744997e-07 1.36573929102e-06 -831 7.25 4.44366324079e-07 1.34727451183e-06 -832 7.255 4.37675549122e-07 1.32908018904e-06 -833 7.26 4.31075078542e-07 1.31115205663e-06 -834 7.265 4.24563591899e-07 1.29348592063e-06 -835 7.27 4.1813978955e-07 1.2760776579e-06 -836 7.275 4.11802392291e-07 1.25892321479e-06 -837 7.28 4.05550141016e-07 1.24201860594e-06 -838 7.285 3.99381796376e-07 1.22535991301e-06 -839 7.29 3.9329613845e-07 1.20894328352e-06 -840 7.295 3.87291966418e-07 1.19276492962e-06 -841 7.3 3.81368098239e-07 1.17682112698e-06 -842 7.305 3.75523370336e-07 1.16110821364e-06 -843 7.31 3.69756637291e-07 1.14562258888e-06 -844 7.315 3.64066771537e-07 1.13036071214e-06 -845 7.32 3.58452663062e-07 1.11531910195e-06 -846 7.325 3.52913219116e-07 1.10049433488e-06 -847 7.33 3.47447363922e-07 1.0858830445e-06 -848 7.335 3.42054038397e-07 1.07148192036e-06 -849 7.34 3.3673219987e-07 1.05728770703e-06 -850 7.345 3.31480821814e-07 1.04329720308e-06 -851 7.35 3.26298893574e-07 1.02950726017e-06 -852 7.355 3.21185420107e-07 1.01591478207e-06 -853 7.36 3.16139421723e-07 1.00251672378e-06 -854 7.365 3.1115993383e-07 9.89310090577e-07 -855 7.37 3.06246006687e-07 9.76291937184e-07 -856 7.375 3.01396705156e-07 9.63459366859e-07 -857 7.38 2.96611108464e-07 9.50809530558e-07 -858 7.385 2.91888309966e-07 9.38339626099e-07 -859 7.39 2.87227416913e-07 9.26046897331e-07 -860 7.395 2.82627550221e-07 9.13928633336e-07 -861 7.4 2.78087844251e-07 9.01982167635e-07 -862 7.405 2.73607446588e-07 8.90204877406e-07 -863 7.41 2.6918551782e-07 8.78594182731e-07 -864 7.415 2.64821231333e-07 8.67147545837e-07 -865 7.42 2.60513773095e-07 8.55862470371e-07 -866 7.425 2.56262341455e-07 8.44736500673e-07 -867 7.43 2.5206614694e-07 8.33767221072e-07 -868 7.435 2.47924412057e-07 8.22952255188e-07 -869 7.44 2.43836371097e-07 8.12289265255e-07 -870 7.445 2.39801269946e-07 8.01775951447e-07 -871 7.45 2.35818365896e-07 7.91410051224e-07 -872 7.455 2.31886927457e-07 7.81189338689e-07 -873 7.46 2.28006234181e-07 7.7111162395e-07 -874 7.465 2.2417557648e-07 7.61174752504e-07 -875 7.47 2.20394255452e-07 7.51376604623e-07 -876 7.475 2.16661582706e-07 7.41715094759e-07 -877 7.48 2.12976880196e-07 7.32188170953e-07 -878 7.485 2.09339480053e-07 7.22793814262e-07 -879 7.49 2.05748724421e-07 7.13530038185e-07 -880 7.495 2.02203965296e-07 7.04394888118e-07 -881 7.5 1.9870456437e-07 6.95386440797e-07 -882 7.505 1.95249892873e-07 6.86502803769e-07 -883 7.51 1.91839331421e-07 6.77742114863e-07 -884 7.515 1.88472269866e-07 6.69102541673e-07 -885 7.52 1.85148107151e-07 6.60582281052e-07 -886 7.525 1.8186625116e-07 6.52179558612e-07 -887 7.53 1.7862611858e-07 6.43892628236e-07 -888 7.535 1.75427134757e-07 6.35719771598e-07 -889 7.54 1.72268733561e-07 6.27659297689e-07 -890 7.545 1.6915035725e-07 6.19709542357e-07 -891 7.55 1.66071456337e-07 6.11868867849e-07 -892 7.555 1.63031489458e-07 6.04135662368e-07 -893 7.56 1.60029923244e-07 5.96508339628e-07 -894 7.565 1.57066232194e-07 5.88985338432e-07 -895 7.57 1.54139898552e-07 5.81565122242e-07 -896 7.575 1.51250412185e-07 5.74246178766e-07 -897 7.58 1.48397270459e-07 5.6702701955e-07 -898 7.585 1.45579978125e-07 5.59906179576e-07 -899 7.59 1.42798047202e-07 5.52882216872e-07 -900 7.595 1.40050996861e-07 5.4595371212e-07 -901 7.6 1.37338353314e-07 5.39119268281e-07 -902 7.605 1.34659649703e-07 5.32377510221e-07 -903 7.61 1.32014425993e-07 5.25727084341e-07 -904 7.615 1.29402228861e-07 5.19166658223e-07 -905 7.62 1.26822611598e-07 5.12694920274e-07 -906 7.625 1.24275133998e-07 5.06310579376e-07 -907 7.63 1.21759362262e-07 5.0001236455e-07 -908 7.635 1.19274868896e-07 4.93799024619e-07 -909 7.64 1.16821232612e-07 4.87669327877e-07 -910 7.645 1.14398038233e-07 4.8162206177e-07 -911 7.65 1.120048766e-07 4.75656032572e-07 -912 7.655 1.09641344473e-07 4.69770065082e-07 -913 7.66 1.07307044442e-07 4.63963002309e-07 -914 7.665 1.05001584841e-07 4.58233705177e-07 -915 7.67 1.02724579651e-07 4.52581052224e-07 -916 7.675 1.0047564842e-07 4.47003939317e-07 -917 7.68 9.82544161708e-08 4.41501279361e-07 -918 7.685 9.60605133226e-08 4.36072002025e-07 -919 7.69 9.38935756035e-08 4.30715053459e-07 -920 7.695 9.17532439703e-08 4.25429396028e-07 -921 7.7 8.96391645283e-08 4.20214008047e-07 -922 7.705 8.75509884516e-08 4.15067883513e-07 -923 7.71 8.54883719059e-08 4.09990031857e-07 -924 7.715 8.34509759714e-08 4.04979477684e-07 -925 7.72 8.14384665682e-08 4.00035260529e-07 -926 7.725 7.94505143815e-08 3.95156434615e-07 -927 7.73 7.74867947896e-08 3.90342068606e-07 -928 7.735 7.55469877916e-08 3.85591245382e-07 -929 7.74 7.36307779372e-08 3.80903061797e-07 -930 7.745 7.17378542573e-08 3.76276628463e-07 -931 7.75 6.9867910196e-08 3.71711069515e-07 -932 7.755 6.80206435432e-08 3.67205522401e-07 -933 7.76 6.61957563687e-08 3.62759137662e-07 -934 7.765 6.43929549576e-08 3.5837107872e-07 -935 7.77 6.26119497457e-08 3.54040521671e-07 -936 7.775 6.08524552575e-08 3.49766655078e-07 -937 7.78 5.91141900435e-08 3.45548679773e-07 -938 7.785 5.73968766201e-08 3.41385808656e-07 -939 7.79 5.57002414093e-08 3.37277266505e-07 -940 7.795 5.402401468e-08 3.33222289779e-07 -941 7.8 5.23679304898e-08 3.29220126433e-07 -942 7.805 5.07317266285e-08 3.25270035737e-07 -943 7.81 4.91151445613e-08 3.21371288087e-07 -944 7.815 4.75179293742e-08 3.17523164833e-07 -945 7.82 4.59398297194e-08 3.13724958102e-07 -946 7.825 4.43805977617e-08 3.09975970624e-07 -947 7.83 4.28399891263e-08 3.06275515564e-07 -948 7.835 4.13177628469e-08 3.02622916355e-07 -949 7.84 3.98136813144e-08 2.99017506534e-07 -950 7.845 3.83275102273e-08 2.95458629582e-07 -951 7.85 3.68590185422e-08 2.91945638765e-07 -952 7.855 3.54079784251e-08 2.8847789698e-07 -953 7.86 3.39741652039e-08 2.85054776599e-07 -954 7.865 3.25573573211e-08 2.81675659322e-07 -955 7.87 3.11573362879e-08 2.78339936025e-07 -956 7.875 2.97738866382e-08 2.7504700662e-07 -957 7.88 2.84067958844e-08 2.71796279909e-07 -958 7.885 2.70558544725e-08 2.68587173443e-07 -959 7.89 2.57208557397e-08 2.65419113385e-07 -960 7.895 2.44015958707e-08 2.62291534374e-07 -961 7.9 2.30978738564e-08 2.59203879393e-07 -962 7.905 2.18094914519e-08 2.56155599635e-07 -963 7.91 2.05362531363e-08 2.53146154374e-07 -964 7.915 1.92779660724e-08 2.50175010842e-07 -965 7.92 1.8034440067e-08 2.47241644098e-07 -966 7.925 1.68054875325e-08 2.44345536912e-07 -967 7.93 1.55909234484e-08 2.41486179638e-07 -968 7.935 1.43905653237e-08 2.38663070101e-07 -969 7.94 1.32042331597e-08 2.35875713474e-07 -970 7.945 1.20317494138e-08 2.33123622171e-07 -971 7.95 1.08729389636e-08 2.30406315726e-07 -972 7.955 9.72762907123e-09 2.27723320689e-07 -973 7.96 8.59564934896e-09 2.2507417051e-07 -974 7.965 7.47683172465e-09 2.2245840544e-07 -975 7.97 6.37101040818e-09 2.19875572416e-07 -976 7.975 5.27802185823e-09 2.17325224966e-07 -977 7.98 4.19770474957e-09 2.148069231e-07 -978 7.985 3.12989994095e-09 2.12320233213e-07 -979 7.99 2.07445044336e-09 2.09864727985e-07 -980 7.995 1.03120138888e-09 2.07439986287e-07 -981 8.0 0.0 0.0 - diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+minichaperone/run.in.min b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+minichaperone/run.in.min deleted file mode 100644 index 0cde82b1f5..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+minichaperone/run.in.min +++ /dev/null @@ -1,24 +0,0 @@ -# -- Init section -- - -include system.in.init - -# -- Atom definition section -- - -read_data system.data - -# -- Settings Section -- - -include system.in.settings - -# Optional: Make sure the pairwise energies look reasonable: -pair_write 1 4 1001 r 4.05 8 test_chap-B.dat C-B 0 0 -pair_write 2 4 1001 r 4.05 8 test_chap-L.dat C-L 0 0 -pair_write 3 4 1001 r 4.05 8 test_chap-N.dat C-N 0 0 - -# -- Run section -- - -dump 1 all custom 50 traj_min.lammpstrj id mol type x y z ix iy iz - -minimize 1.0e-5 1.0e-7 500 2000 - -write_data system_after_min.data diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+minichaperone/run.in.nvt b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+minichaperone/run.in.nvt deleted file mode 100644 index d28f48dd88..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated+minichaperone/run.in.nvt +++ /dev/null @@ -1,46 +0,0 @@ -# -- Init Section -- - -include system.in.init - -# -- Atom Definition Section -- - -# I you want to be careful, you can minimize the system first. -# (Try using "run.in.min" and uncomment the line below.) -# read_data system_after_min.data - -read_data system.data - -# -- Settings Section -- - -include system.in.settings - -# -- Run Section -- - - -timestep 0.025 -dump 1 all custom 5000 traj_nvt.lammpstrj id mol type x y z ix iy iz - -# To use Langevin dynamics in LAMMPS you need both "fix langevin" and "fix nve". -# (See http://lammps.sandia.gov/doc/fix_langevin.html for details.) - -fix fxlan all langevin 0.25 0.25 1.0 48279 -fix fxnve all nve - -# Notes: -# The temperature is in reduced units and is set to 0.25 -# which is the folding temperature for the frustrated protein -# The inverse-damping-rate "damp" (which has units of time) is set to 1.0, -# as it was in the paper. (Hopefully folding times should be similar.) -# (See http://lammps.sandia.gov/doc/fix_langevin.html) - - -thermo_style custom step temp pe etotal press vol epair ebond eangle edihed -thermo_modify norm no #(report total energy not energy / num_atoms) -thermo 5000 #(time interval for printing out "thermo" data) - -#restart 100000000 restart_nvt - -run 1000000000 - -write_data system_after_nvt.data - diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated/README.TXT b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated/README.TXT deleted file mode 100644 index 77af3de15a..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated/README.TXT +++ /dev/null @@ -1,29 +0,0 @@ -# This directory demonstrates how to run a short simulation of -# the "frustrated" coarse-grained protein model used in: -# AI Jewett, A Baumketner and J-E Shea, PNAS, 101 (36), 13192-13197, (2004) -# (http://www.pnas.org/content/101/36/13192) -# -# During this short simulation (run_short_sim.nvt.in) the protein evolves -# from an unfolded initial conformation to a misfolded conformation. -# (Visualize using VMD. Note: It can take hundreds of millions of -# timesteps to escape from this conformation and reach the folded state.) -# -# -------- REQUIREMENTS: --------- -# 1) This example requires the "USER-MISC" package. (Use "make yes-USER-MISC") -# http://lammps.sandia.gov/doc/Section_start.html#start_3 -# 2) It also may require additional features and bug fixes for LAMMPS. -# be sure to download and copy the "additional_lammps_code" from -# http://moltemplate.org (upper-left corner menu) -# 3) Unpack it -# 4) copy the .cpp and .h files to the src folding of your lammps installation. -# 5) Compile LAMMPS. - -------------- -Instructions on how to build LAMMPS input files and -run a short simulation are provided in other README files. - -step 1) -README_setup.sh - -step2) -README_run.sh diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated/README_run.sh b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated/README_run.sh deleted file mode 100755 index 6c5417239b..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated/README_run.sh +++ /dev/null @@ -1,21 +0,0 @@ -# You would probably run lammps this way: -# -# lmp_ubuntu -i run.in.nvt - -# The files "run.in.min", and "run.in.nvt" are LAMMPS input scripts which refer -# to the input scripts & data files you created earlier when you ran moltemplate -# system.in.init, system.in.settings, system.data - - -# ----------------------------------- - -LAMMPS_COMMAND="lmp_mpi" - -# Here "$LAMMPS_BINARY" is the name of the command you use to invoke lammps -# (such as lmp_ubuntu, lmp_mac_mpi, lmp_cygwin etc...). Change if necessary. - -# Run lammps using the following 3 commands: - -"$LAMMPS_COMMAND" -i run.in.min # minimize (OPTIONAL) -"$LAMMPS_COMMAND" -i run_short_sim.in.nvt # production run - diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated/README_setup.sh b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated/README_setup.sh deleted file mode 100755 index df49f4384f..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated/README_setup.sh +++ /dev/null @@ -1,24 +0,0 @@ -# Use these commands to generate the LAMMPS input script and data file -# (and other auxilliary files): - - -# Create LAMMPS input files this way: -cd moltemplate_files - - # run moltemplate - - moltemplate.sh -overlay-dihedrals system.lt - - # This will generate various files with names ending in *.in* and *.data. - # These files are the input files directly read by LAMMPS. Move them to - # the parent directory (or wherever you plan to run the simulation). - - mv -f system.in* system.data ../ - cp -r table*.dat ../ - - # Optional: - # The "./output_ttree/" directory is full of temporary files generated by - # moltemplate. They can be useful for debugging, but are usually thrown away. - rm -rf output_ttree/ - -cd ../ diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated/README_visualize.txt b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated/README_visualize.txt deleted file mode 100644 index 019afc1444..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated/README_visualize.txt +++ /dev/null @@ -1,87 +0,0 @@ - - ------- To view a lammps trajectory in VMD -------- - - -1) Build a PSF file for use in viewing with VMD. - -This step works with VMD 1.9 and topotools 1.2. -(Older versions, like VMD 1.8.6, don't support this.) - - -a) Start VMD -b) Menu Extensions->Tk Console -c) Enter: - -(I assume that the the DATA file is called "system.data") - - topo readlammpsdata system.data full - animate write psf system.psf - -2) - -Later, to Load a trajectory in VMD: - - Start VMD - Select menu: File->New Molecule - -Browse to select the PSF file you created above, and load it. - (Don't close the window yet.) - -Browse to select the trajectory file. - If necessary, for "file type" select: "LAMMPS Trajectory" - Load it. - - ---- A note on trajectory format: ----- -If the trajectory is a DUMP file, then make sure the it contains the -information you need for pbctools (see below. I've been using this -command in my LAMMPS scripts to create the trajectories: - - dump 1 all custom 5000 DUMP_FILE.lammpstrj id mol type x y z ix iy iz - -It's a good idea to use an atom_style which supports molecule-ID numbers -so that you can assign a molecule-ID number to each atom. (I think this -is needed to wrap atom coordinates without breaking molecules in half.) - -Of course, you don't have to save your trajectories in DUMP format, -(other formats like DCD work fine) I just mention dump files -because these are the files I'm familiar with. - -3) ----- Wrap the coordinates to the unit cell - (without cutting the molecules in half) - -a) Start VMD -b) Load the trajectory in VMD (see above) -c) Menu Extensions->Tk Console -d) Try entering these commands: - - pbc wrap -compound res -all - pbc box - - ----- Optional ---- - Sometimes the solvent or membrane obscures the view of the solute. - It can help to shift the location of the periodic boundary box - To shift the box in the y direction (for example) do this: - - pbc wrap -compound res -all -shiftcenterrel {0.0 0.15 0.0} - pbc box -shiftcenterrel {0.0 0.15 0.0} - - Distances are measured in units of box-length fractions, not Angstroms. - - Alternately if you have a solute whose atoms are all of type 1, - then you can also try this to center the box around it: - - pbc wrap -sel type=1 -all -centersel type=2 -center com - -4) - You should check if your periodic boundary conditions are too small. - To do that: - select Graphics->Representations menu option - click on the "Periodic" tab, and - click on the "+x", "-x", "+y", "-y", "+z", "-z" checkboxes. - -5) Optional: If you like, change the atom types in the PSF file so - that VMD recognizes the atom types, use something like: - -sed -e 's/ 1 1 / C C /g' < system.psf > temp1.psf -sed -e 's/ 2 2 / H H /g' < temp1.psf > temp2.psf -sed -e 's/ 3 3 / P P /g' < temp2.psf > system.psf - -(If you do this, it might effect step 2 above.) diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated/images/for_visualization/psf_file_created_by_topotools/system.psf b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated/images/for_visualization/psf_file_created_by_topotools/system.psf deleted file mode 100644 index c7f8572b29..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated/images/for_visualization/psf_file_created_by_topotools/system.psf +++ /dev/null @@ -1,85 +0,0 @@ -PSF - - 1 !NTITLE - REMARKS VMD generated structure x-plor psf file - - 27 !NATOM - 1 1 2 2 0.000000 1.0000 0 - 2 1 1 1 0.000000 1.0000 0 - 3 1 2 2 0.000000 1.0000 0 - 4 1 1 1 0.000000 1.0000 0 - 5 1 2 2 0.000000 1.0000 0 - 6 1 1 1 0.000000 1.0000 0 - 7 1 3 3 0.000000 1.0000 0 - 8 1 3 3 0.000000 1.0000 0 - 9 1 1 1 0.000000 1.0000 0 - 10 1 2 2 0.000000 1.0000 0 - 11 1 1 1 0.000000 1.0000 0 - 12 1 2 2 0.000000 1.0000 0 - 13 1 1 1 0.000000 1.0000 0 - 14 1 2 2 0.000000 1.0000 0 - 15 1 3 3 0.000000 1.0000 0 - 16 1 3 3 0.000000 1.0000 0 - 17 1 3 3 0.000000 1.0000 0 - 18 1 1 1 0.000000 1.0000 0 - 19 1 1 1 0.000000 1.0000 0 - 20 1 2 2 0.000000 1.0000 0 - 21 1 2 2 0.000000 1.0000 0 - 22 1 1 1 0.000000 1.0000 0 - 23 1 1 1 0.000000 1.0000 0 - 24 1 2 2 0.000000 1.0000 0 - 25 1 2 2 0.000000 1.0000 0 - 26 1 1 1 0.000000 1.0000 0 - 27 1 2 2 0.000000 1.0000 0 - - 26 !NBOND: bonds - 1 2 2 3 3 4 4 5 - 5 6 6 7 7 8 8 9 - 9 10 10 11 11 12 12 13 - 13 14 14 15 15 16 16 17 - 17 18 18 19 19 20 20 21 - 21 22 22 23 23 24 24 25 - 25 26 26 27 - - 25 !NTHETA: angles - 13 14 15 7 8 9 6 7 8 - 16 17 18 15 16 17 2 3 4 - 4 5 6 9 10 11 11 12 13 - 14 15 16 1 2 3 3 4 5 - 10 11 12 12 13 14 25 26 27 - 5 6 7 8 9 10 17 18 19 - 18 19 20 22 23 24 21 22 23 - 19 20 21 20 21 22 23 24 25 - 24 25 26 - - 19 !NPHI: dihedrals - 1 2 3 4 2 3 4 5 - 3 4 5 6 4 5 6 7 - 8 9 10 11 9 10 11 12 - 10 11 12 13 11 12 13 14 - 12 13 14 15 15 16 17 18 - 16 17 18 19 17 18 19 20 - 18 19 20 21 19 20 21 22 - 20 21 22 23 21 22 23 24 - 22 23 24 25 23 24 25 26 - 24 25 26 27 - - 0 !NIMPHI: impropers - - - 0 !NDON: donors - - - 0 !NACC: acceptors - - - 0 !NNB - - 0 0 0 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 !NGRP - 0 0 0 - diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated/images/initial_conformation_t=0tau.jpg b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated/images/initial_conformation_t=0tau.jpg deleted file mode 100644 index 0869126bd018ee959e0e01d755f58361de02fc88..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23358 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 J`;Y$3{VxtS`Skz* diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated/moltemplate_files/1beadFrustrated.lt b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated/moltemplate_files/1beadFrustrated.lt deleted file mode 100644 index 074b55c735..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated/moltemplate_files/1beadFrustrated.lt +++ /dev/null @@ -1,216 +0,0 @@ -# This file defines the "frustrated" coarse-grained protein model used in: -# AI Jewett, A Baumketner and J-E Shea, PNAS, 101 (36), 13192-13197, (2004) -# (http://www.pnas.org/content/101/36/13192) - - -1beadFrustrated { - - # There are 3 atom types (referred to above as B, L, and N) - # Define their masses: - - write_once("Data Masses") { - @atom:B 1.0 - @atom:L 1.0 - @atom:N 1.0 - } - - # AtomID MoleculeID AtomType Charge X Y Z - - write("Data Atoms") { - $atom:a1 $mol @atom:L 0.0 -0.92636654 -1.8409904 -2.1482679 - $atom:a2 $mol @atom:B 0.0 -0.57313354 -1.0670787 -1.6182341 - $atom:a3 $mol @atom:L 0.0 -0.85707399 -1.2358703 -0.69350966 - $atom:a4 $mol @atom:B 0.0 -0.44231274 -0.4584993 -0.23418709 - $atom:a5 $mol @atom:L 0.0 -0.75081182 -0.62868078 0.69786737 - $atom:a6 $mol @atom:B 0.0 -0.36201977 0.11619615 1.2249098 - $atom:a7 $mol @atom:N 0.0 -0.63708237 -0.15973084 2.1723919 - $atom:a8 $mol @atom:N 0.0 0.20516047 0.10417157 2.624901 - $atom:a9 $mol @atom:B 0.0 0.57223743 0.44728103 1.7695617 - $atom:a10 $mol @atom:L 0.0 0.77646279 -0.40630393 1.3168043 - $atom:a11 $mol @atom:B 0.0 0.45475664 -0.2077937 0.40045721 - $atom:a12 $mol @atom:L 0.0 0.72712495 -1.0397637 -0.087614951 - $atom:a13 $mol @atom:B 0.0 0.36971183 -0.85840501 -0.9933019 - $atom:a14 $mol @atom:L 0.0 0.74784336 -1.5700415 -1.5859217 - $atom:a15 $mol @atom:N 0.0 0.43423905 -1.2758917 -2.4853429 - $atom:a16 $mol @atom:N 0.0 0.70583191 -0.30726921 -2.4987711 - $atom:a17 $mol @atom:N 0.0 -0.091688915 0.23323014 -2.2051358 - $atom:a18 $mol @atom:B 0.0 -0.34243283 -0.035822049 -1.2644719 - $atom:a19 $mol @atom:B 0.0 0.41961247 0.18475451 -0.65971014 - $atom:a20 $mol @atom:L 0.0 0.51968465 1.1546791 -0.77877053 - $atom:a21 $mol @atom:L 0.0 -0.40827985 1.2765273 -0.52550748 - $atom:a22 $mol @atom:B 0.0 -0.368141 0.58090904 0.19152224 - $atom:a23 $mol @atom:B 0.0 0.40327249 0.86101769 0.7336255 - $atom:a24 $mol @atom:L 0.0 0.22707289 1.8326235 0.89673346 - $atom:a25 $mol @atom:L 0.0 -0.66500182 1.7285809 1.2783166 - $atom:a26 $mol @atom:B 0.0 -0.39205603 1.0475436 1.9328097 - $atom:a27 $mol @atom:L 0.0 0.25339027 1.5246265 2.5388463 - } - - # bond-ID bond-Type atom-ID atom-ID - - write("Data Bonds") { - $bond:b1 @bond:backbone $atom:a1 $atom:a2 - $bond:b2 @bond:backbone $atom:a2 $atom:a3 - $bond:b3 @bond:backbone $atom:a3 $atom:a4 - $bond:b4 @bond:backbone $atom:a4 $atom:a5 - $bond:b5 @bond:backbone $atom:a5 $atom:a6 - $bond:b6 @bond:backbone $atom:a6 $atom:a7 - $bond:b7 @bond:backbone $atom:a7 $atom:a8 - $bond:b8 @bond:backbone $atom:a8 $atom:a9 - $bond:b9 @bond:backbone $atom:a9 $atom:a10 - $bond:b10 @bond:backbone $atom:a10 $atom:a11 - $bond:b11 @bond:backbone $atom:a11 $atom:a12 - $bond:b12 @bond:backbone $atom:a12 $atom:a13 - $bond:b13 @bond:backbone $atom:a13 $atom:a14 - $bond:b14 @bond:backbone $atom:a14 $atom:a15 - $bond:b15 @bond:backbone $atom:a15 $atom:a16 - $bond:b16 @bond:backbone $atom:a16 $atom:a17 - $bond:b17 @bond:backbone $atom:a17 $atom:a18 - $bond:b18 @bond:backbone $atom:a18 $atom:a19 - $bond:b19 @bond:backbone $atom:a19 $atom:a20 - $bond:b20 @bond:backbone $atom:a20 $atom:a21 - $bond:b21 @bond:backbone $atom:a21 $atom:a22 - $bond:b22 @bond:backbone $atom:a22 $atom:a23 - $bond:b23 @bond:backbone $atom:a23 $atom:a24 - $bond:b24 @bond:backbone $atom:a24 $atom:a25 - $bond:b25 @bond:backbone $atom:a25 $atom:a26 - $bond:b26 @bond:backbone $atom:a26 $atom:a27 - } - - # (3-body) Angles are specified below - - # (4-body) Dihedrals must be defined explicitly for every quartet of atoms. - # (These interactions are not determined by atom type.) - - # dihedral-ID dihedral-Type atom-ID atom-ID atom-ID atom-ID - - write("Data Dihedrals") { - - $dihedral:d1 @dihedral:beta $atom:a1 $atom:a2 $atom:a3 $atom:a4 - $dihedral:d2 @dihedral:beta $atom:a2 $atom:a3 $atom:a4 $atom:a5 - $dihedral:d3 @dihedral:beta $atom:a3 $atom:a4 $atom:a5 $atom:a6 - $dihedral:d4 @dihedral:beta $atom:a4 $atom:a5 $atom:a6 $atom:a7 - - # Dihedral angle forces in the turn regions were switched off - # (in this model) so just I comment them out (and \ the variable names). - # \$dihedral:d5 \@dihedral:turn $atom:a5 $atom:a6 $atom:a7 $atom:a8 - # \$dihedral:d6 \@dihedral:turn $atom:a6 $atom:a7 $atom:a8 $atom:a9 - # \$dihedral:d7 \@dihedral:turn $atom:a7 $atom:a8 $atom:a9 $atom:a10 - - $dihedral:d8 @dihedral:beta $atom:a8 $atom:a9 $atom:a10 $atom:a11 - $dihedral:d9 @dihedral:beta $atom:a9 $atom:a10 $atom:a11 $atom:a12 - $dihedral:d10 @dihedral:beta $atom:a10 $atom:a11 $atom:a12 $atom:a13 - $dihedral:d11 @dihedral:beta $atom:a11 $atom:a12 $atom:a13 $atom:a14 - $dihedral:d12 @dihedral:beta $atom:a12 $atom:a13 $atom:a14 $atom:a15 - - # Dihedral angle forces in the turn regions were switched off - # (in this model) so just I comment them out (and \ the variable names). - # \$dihedral:d13 \@dihedral:turn $atom:a13 $atom:a14 $atom:a15 $atom:a16 - # \$dihedral:d14 \@dihedral:turn $atom:a14 $atom:a15 $atom:a16 $atom:a17 - - $dihedral:d15 @dihedral:alpha $atom:a15 $atom:a16 $atom:a17 $atom:a18 - $dihedral:d16 @dihedral:alpha $atom:a16 $atom:a17 $atom:a18 $atom:a19 - $dihedral:d17 @dihedral:alpha $atom:a17 $atom:a18 $atom:a19 $atom:a20 - $dihedral:d18 @dihedral:alpha $atom:a18 $atom:a19 $atom:a20 $atom:a21 - $dihedral:d19 @dihedral:alpha $atom:a19 $atom:a20 $atom:a21 $atom:a22 - $dihedral:d20 @dihedral:alpha $atom:a20 $atom:a21 $atom:a22 $atom:a23 - $dihedral:d21 @dihedral:alpha $atom:a21 $atom:a22 $atom:a23 $atom:a24 - $dihedral:d22 @dihedral:alpha $atom:a22 $atom:a23 $atom:a24 $atom:a25 - $dihedral:d23 @dihedral:alpha $atom:a23 $atom:a24 $atom:a25 $atom:a26 - $dihedral:d24 @dihedral:alpha $atom:a24 $atom:a25 $atom:a26 $atom:a27 - } - - # All consecutively bonded triplets of atoms same 3-body bond-angle - # interaction parameters. Of coarse, we could specify them all explicitly - # (as we did for the dihedrals above), but I wanted to show how to specify - # angles by atom type instead. (You can do this for dihedrals & impropers - # also.) - - # angle-Type atom-Type atom-Type atom-Type bond-Type bond-Type - - write_once("Data Angles By Type") { - @angle:backbone @atom:* @atom:* @atom:* @bond:* @bond:* - } - - # (The "*" is a wildcard character. I use "*" to denote any atom-type or - # bond-type which is defined within the current namespace: 1beadFrustrated) - - - # 2-body (non-bonded) interactions: - # - # Uij(r) = 4*eps_ij * (K*(sig_ij/r)^12 + L*(sig_ij/r)^6) - # - # i j pairstylename eps sig K L - # - write_once("In Settings") { - pair_coeff @atom:B @atom:B lj/charmm/coul/charmm/inter 1.0 1.0 1 -1 - pair_coeff @atom:B @atom:L lj/charmm/coul/charmm/inter 0.5833333333 1.0 1 0 - pair_coeff @atom:B @atom:N lj/charmm/coul/charmm/inter 0.6666666667 1.0 1 0 - pair_coeff @atom:L @atom:L lj/charmm/coul/charmm/inter 0.1666666667 1.0 1 1 - pair_coeff @atom:L @atom:N lj/charmm/coul/charmm/inter 0.25 1.0 1 0 - pair_coeff @atom:N @atom:N lj/charmm/coul/charmm/inter 0.3333333333 1.0 1 0 - } - - - # 2-body (bonded) interactions: - # - # Ubond(r) = (k/2)*(r-0)^2 - # - # The corresponding command is: - # - # bond-Type bondstylename k r0 - - write_once("In Settings") { - bond_coeff @bond:backbone harmonic 100.0 1.0 - } - - # 3-body interactions in this example are listed by atomType and bondType - # The atomIDs involved are determined automatically. The forumula used is: - # - # Uangle(theta) = (k/2)*(theta-theta0)^2 - # (k in kcal/mol/rad^2, theta0 in degrees) - # - # angle-Type anglestylename k theta0 - - write_once("In Settings") { - angle_coeff @angle:backbone harmonic 13.3333333333 105.0 - } - - - # We use tabular dihedral potentials to implement the dihedral forces. - # (Actually there is a way to use Fourier series, using multiple charmm - # style dihedral interactions, but it's slower and messier.) - - write_once("In Settings") { - # style file keyword - dihedral_coeff @dihedral:alpha table table_dihedral_frustrated.dat FRUSTRATED_ALPHA - dihedral_coeff @dihedral:beta table table_dihedral_frustrated.dat FRUSTRATED_BETA - # No need to specify dihedral interactions in the turn regions. (none exist) - } - - write_once("In Settings") { - # Optional: define the atoms in the "proteins" group - group proteins type @atom:B - group proteins type @atom:L - group proteins type @atom:N - } - - # LAMMPS has many available force field styles (and atom styles). - # Here, we pick the ones which work well for this molecular model: - - write_once("In Init") { - # --- Default options for the "1BeadFrustrated" protein model --- - # --- (These can be overridden later.) --- - units lj - atom_style full - bond_style hybrid harmonic - angle_style hybrid harmonic - dihedral_style hybrid table spline 360 - pair_style hybrid lj/charmm/coul/charmm/inter es4k4l maxmax 3.5 4.0 - pair_modify mix arithmetic - special_bonds lj 0.0 0.0 1.0 #(turn on "1-4" interactions) - } - -} # 1beadFrustrated - - diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated/moltemplate_files/1beadFrustrated_variants.lt b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated/moltemplate_files/1beadFrustrated_variants.lt deleted file mode 100644 index 54e2de4376..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated/moltemplate_files/1beadFrustrated_variants.lt +++ /dev/null @@ -1,85 +0,0 @@ -import "1beadFrustrated.lt" - - -# Alternate starting conformation (same molecule): - - -1beadMisfolded inherits 1beadFrustrated { - - # This molecule "inherits" all of its features from "1beadFrustrated". - # Here we override the atomic positions with new coordinates: - - # AtomID MoleculeID AtomType Charge X Y Z - - write("Data Atoms") { - $atom:a1 $mol @atom:L 0.0 -0.69801399 -0.22114168 -1.9464876 - $atom:a2 $mol @atom:B 0.0 -0.40921658 -0.027063664 -1.0033251 - $atom:a3 $mol @atom:L 0.0 0.10259348 0.80836418 -1.0737085 - $atom:a4 $mol @atom:B 0.0 0.25857916 1.0054984 -0.11621451 - $atom:a5 $mol @atom:L 0.0 0.8258629 1.8325549 -0.18529135 - $atom:a6 $mol @atom:B 0.0 0.91366257 2.1950317 0.74175977 - $atom:a7 $mol @atom:N 0.0 1.4399539 1.554238 1.2994409 - $atom:a8 $mol @atom:N 0.0 0.73372573 1.0161012 1.7397275 - $atom:a9 $mol @atom:B 0.0 0.26608782 0.65302497 0.94353938 - $atom:a10 $mol @atom:L 0.0 0.97442305 0.13574211 0.50586398 - $atom:a11 $mol @atom:B 0.0 0.35889617 -0.18247555 -0.1764186 - $atom:a12 $mol @atom:L 0.0 0.87151735 -0.77260824 -0.75240916 - $atom:a13 $mol @atom:B 0.0 0.047726486 -1.0530682 -1.1902704 - $atom:a14 $mol @atom:L 0.0 0.34530697 -1.7476773 -1.8393331 - $atom:a15 $mol @atom:N 0.0 0.65865186 -2.45948 -1.2167056 - $atom:a16 $mol @atom:N 0.0 -0.16534524 -2.6219442 -0.67112167 - $atom:a17 $mol @atom:N 0.0 -0.010590421 -2.2445242 0.24748633 - $atom:a18 $mol @atom:B 0.0 0.18135771 -1.2564919 0.1767523 - $atom:a19 $mol @atom:B 0.0 -0.57472665 -0.82852797 -0.27027791 - $atom:a20 $mol @atom:L 0.0 -1.3967448 -1.0516787 0.24247346 - $atom:a21 $mol @atom:L 0.0 -1.003428 -0.85642681 1.1107555 - $atom:a22 $mol @atom:B 0.0 -0.25156735 -0.3182346 0.74262946 - $atom:a23 $mol @atom:B 0.0 -0.61751956 0.30115562 0.070426493 - $atom:a24 $mol @atom:L 0.0 -1.3347934 0.83310182 0.52625934 - $atom:a25 $mol @atom:L 0.0 -0.83315257 1.270904 1.2564086 - $atom:a26 $mol @atom:B 0.0 -0.10469759 1.6988523 0.72597181 - $atom:a27 $mol @atom:L 0.0 -0.57854905 2.3367737 0.11206868 - } - -} # 1beadMisfolded - - -1beadUnfolded inherits 1beadFrustrated { - - # This molecule "inherits" all of its features from "1beadFrustrated" - # Here we override the atomic positions with new coordinates: - - # AtomID MoleculeID AtomType Charge X Y Z - - write('Data Atoms') { - $atom:a1 $mol @atom:L 0.0 -2.4 1.7 -0.0 - $atom:a2 $mol @atom:B 0.0 -1.8 1.7 0.8 - $atom:a3 $mol @atom:L 0.0 -1.2 2.5 0.8 - $atom:a4 $mol @atom:B 0.0 -0.6 2.5 -0.0 - $atom:a5 $mol @atom:L 0.0 0.0 1.7 -0.0 - $atom:a6 $mol @atom:B 0.0 0.6 1.7 0.8 - $atom:a7 $mol @atom:N 0.0 1.2 2.5 0.8 - $atom:a8 $mol @atom:N 0.0 1.8 2.5 -0.0 - $atom:a9 $mol @atom:B 0.0 2.4 1.7 -0.0 - $atom:a10 $mol @atom:L 0.0 3.0 1.7 -0.8 - $atom:a11 $mol @atom:B 0.0 3.0 0.7 -0.8 - $atom:a12 $mol @atom:L 0.0 3.0 0.1 -0.0 - $atom:a13 $mol @atom:B 0.0 3.8 -0.5 -0.0 - $atom:a14 $mol @atom:L 0.0 3.8 -1.1 -0.8 - $atom:a15 $mol @atom:N 0.0 3.0 -1.7 -0.8 - $atom:a16 $mol @atom:N 0.0 3.0 -1.7 0.2 - $atom:a17 $mol @atom:N 0.0 2.4 -2.5 0.2 - $atom:a18 $mol @atom:B 0.0 1.8 -2.5 -0.6 - $atom:a19 $mol @atom:B 0.0 1.2 -1.7 -0.6 - $atom:a20 $mol @atom:L 0.0 0.6 -1.7 0.2 - $atom:a21 $mol @atom:L 0.0 -0.0 -2.5 0.2 - $atom:a22 $mol @atom:B 0.0 -0.6 -2.5 -0.6 - $atom:a23 $mol @atom:B 0.0 -1.2 -1.7 -0.6 - $atom:a24 $mol @atom:L 0.0 -1.8 -1.7 0.2 - $atom:a25 $mol @atom:L 0.0 -2.4 -2.5 0.2 - $atom:a26 $mol @atom:B 0.0 -3.0 -2.5 -0.6 - $atom:a27 $mol @atom:L 0.0 -3.6 -1.7 -0.6 - } - -} # 1beadUnfolded - diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated/moltemplate_files/generate_tables/calc_dihedral_table.py b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated/moltemplate_files/generate_tables/calc_dihedral_table.py deleted file mode 100755 index 34c66418a8..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated/moltemplate_files/generate_tables/calc_dihedral_table.py +++ /dev/null @@ -1,67 +0,0 @@ -#!/usr/bin/env python - -# Calculate a table of dihedral angle interactions used in the alpha-helix -# and beta-sheet regions of the frustrated protein model described in -# provided in figure 8 of the supplemental materials section of: -# AI Jewett, A Baumketner and J-E Shea, PNAS, 101 (36), 13192-13197, (2004) -# Note that the "A" and "B" parameters were incorrectly reported to be -# 5.4*epsilon and 6.0*epsilon. The values used were 5.6 and 6.0 epsilon. -# The phiA and phiB values were 57.29577951308232 degrees (1 rad) -# and 180 degrees, respectively. Both expA and expB were 6.0. -# -# To generate the table used for the alpha-helix (1 degree resolution) use this: -# ./calc_dihedral_table.py 6.0 57.29577951308232 6 5.6 180 6 0.0 359 360 -# To generate the table used for the beta-sheets (1 degree resolution) use this: -# ./calc_dihedral_table.py 5.6 57.29577951308232 6 6.0 180 6 0.0 359 360 -# -# (If you're curious as to why I set the location of the minima at phi_alpha -# to 1.0 radians (57.2957795 degrees), there was no particularly good reason. -# I think the correct value turns out to be something closer to 50 degrees.) - - -from math import * -import sys - - -# The previous version included the repulsive core term -def U(phi, A, phiA, expA, B, phiB, expB, use_radians=False): - conv_units = pi/180.0 - if use_radians: - conv_units = 1.0 - termA = pow(cos(0.5*(phi-phiA)*conv_units), expA) - termB = pow(cos(0.5*(phi-phiB)*conv_units), expB) - return -A*termA - B*termB - -# The previous version included the repulsive core term -def F(phi, A, phiA, expA, B, phiB, expB, use_radians=False): - conv_units = pi/180.0 - if use_radians: - conv_units = 1.0 - termA = (0.5*sin(0.5*(phi-phiA)*conv_units) * - expA * pow(cos(0.5*(phi-phiA)*conv_units), expA-1.0)) - termB = (0.5*sin(0.5*(phi-phiB)*conv_units) * - expB * pow(cos(0.5*(phi-phiB)*conv_units), expB-1.0)) - return -conv_units*(A*termA + B*termB) - -if len(sys.argv) != 10: - sys.stderr.write("Error: expected 9 arguments:\n" - "\n" - "Usage: "+sys.argv[0]+" A phiA expA B phiB expB phiMin phiMax N\n\n") - sys.exit(-1) - -A = float(sys.argv[1]) -phiA = float(sys.argv[2]) -expA = float(sys.argv[3]) -B = float(sys.argv[4]) -phiB = float(sys.argv[5]) -expB = float(sys.argv[6]) -phi_min = float(sys.argv[7]) -phi_max = float(sys.argv[8]) -N = int(sys.argv[9]) - -for i in range(0,N): - phi = phi_min + i*(phi_max - phi_min)/(N-1) - U_phi = U(phi, A, phiA, expA, B, phiB, expB, use_radians=False) - F_phi = F(phi, A, phiA, expA, B, phiB, expB, use_radians=False) - print(str(i+1)+' '+str(phi)+' '+str(U_phi)+' '+str(F_phi)) - diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated/moltemplate_files/system.lt b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated/moltemplate_files/system.lt deleted file mode 100644 index a27595559e..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated/moltemplate_files/system.lt +++ /dev/null @@ -1,20 +0,0 @@ -import "1beadFrustrated_variants.lt" - - -protein = new 1beadUnfolded - - - -# Note: The protein begins in an "Unfolded" conformation. If instead -# you want it to begin in the folded or misfolded conformations use: -# protein = new 1beadFrustrated # or -# protein = new 1beadMisfolded - - - -# ("27.0" is the length of the protein when maximally extended) -write_once("Data Boundary") { - 0.0 27.0 xlo xhi - 0.0 27.0 ylo yhi - 0.0 27.0 zlo zhi -} diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated/moltemplate_files/table_dihedral_frustrated.dat b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated/moltemplate_files/table_dihedral_frustrated.dat deleted file mode 100644 index d660fee308..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated/moltemplate_files/table_dihedral_frustrated.dat +++ /dev/null @@ -1,735 +0,0 @@ -# Table of the potential and its negative derivative for frustrated alpha helix -# (Note: Derivatives are in units of energy/radians, not energy/degrees.) -# ./calc_dihedral_table.py 6.0 57.29577951308232 6 5.6 180 6 0.0 359 360 - -FRUSTRATED_ALPHA -N 360 DEGREES - -1 0.0 -2.74081145103 0.0783990792662 -2 1.0 -2.81950869101 0.0789852583442 -3 2.0 -2.89876136749 0.0795096391909 -4 3.0 -2.97850675562 0.0799703813963 -5 4.0 -3.05868032959 0.0803657243943 -6 5.0 -3.13921584545 0.0806939935737 -7 6.0 -3.22004543014 0.0809536062381 -8 7.0 -3.30109967628 0.0811430773977 -9 8.0 -3.38230774267 0.0812610253741 -10 9.0 -3.46359746038 0.0813061772009 -11 10.0 -3.54489544401 0.0812773738039 -12 11.0 -3.62612720812 0.0811735749433 -13 12.0 -3.70721728841 0.0809938639029 -14 13.0 -3.78808936748 0.080737451911 -15 14.0 -3.86866640485 0.0804036822781 -16 15.0 -3.94887077101 0.0799920342374 -17 16.0 -4.02862438516 0.0795021264757 -18 17.0 -4.10784885622 0.0789337203415 -19 18.0 -4.18646562704 0.0782867227197 -20 19.0 -4.26439612115 0.0775611885609 -21 20.0 -4.34156189202 0.0767573230567 -22 21.0 -4.41788477419 0.0758754834523 -23 22.0 -4.49328703609 0.0749161804868 -24 23.0 -4.56769153408 0.0738800794563 -25 24.0 -4.64102186743 0.0727680008923 -26 25.0 -4.71320253365 0.0715809208518 -27 26.0 -4.78415908407 0.0703199708131 -28 27.0 -4.85381827903 0.0689864371778 -29 28.0 -4.92210824234 0.067581760373 -30 29.0 -4.98895861476 0.0661075335571 -31 30.0 -5.05430070586 0.0645655009259 -32 31.0 -5.11806764409 0.0629575556235 -33 32.0 -5.18019452449 0.061285737258 -34 33.0 -5.24061855376 0.0595522290273 -35 34.0 -5.29927919225 0.0577593544584 -36 35.0 -5.3561182925 0.0559095737673 -37 36.0 -5.41108023395 0.0540054798439 -38 37.0 -5.46411205346 0.0520497938726 -39 38.0 -5.51516357127 0.0500453605949 -40 39.0 -5.56418751203 0.0479951432253 -41 40.0 -5.61113962059 0.0459022180302 -42 41.0 -5.65597877221 0.0437697685824 -43 42.0 -5.69866707689 0.0416010797029 -44 43.0 -5.7391699774 0.0393995311046 -45 44.0 -5.77745634094 0.0371685907508 -46 45.0 -5.81349854393 0.034911807945 -47 46.0 -5.84727254977 0.0326328061676 -48 47.0 -5.87875797937 0.030335275675 -49 48.0 -5.90793817411 0.0280229658805 -50 49.0 -5.93480025113 0.0256996775336 -51 50.0 -5.95933515063 0.0233692547166 -52 51.0 -5.98153767519 0.0210355766777 -53 52.0 -6.00140652074 0.0187025495211 -54 53.0 -6.01894429926 0.016374097773 -55 54.0 -6.03415755288 0.0140541558448 -56 55.0 -6.04705675953 0.0117466594146 -57 56.0 -6.05765632981 0.00945553674764 -58 57.0 -6.06597459526 0.00718469997761 -59 58.0 -6.07203378786 0.00493803637051 -60 59.0 -6.07586001075 0.00271939959245 -61 60.0 -6.07748320034 0.000532601003776 -62 61.0 -6.07693707962 -0.00161859899905 -63 62.0 -6.07425910291 -0.00373049957158 -64 63.0 -6.06949039207 -0.00579946791801 -65 64.0 -6.06267566421 -0.00782194767468 -66 65.0 -6.05386315117 -0.00979446715893 -67 66.0 -6.04310451074 -0.0117136474624 -68 67.0 -6.03045472992 -0.0135762103679 -69 68.0 -6.01597202036 -0.0153789860691 -70 69.0 -5.99971770618 -0.0171189206741 -71 70.0 -5.98175610439 -0.0187930834719 -72 71.0 -5.9621543982 -0.0203986739443 -73 72.0 -5.9409825034 -0.0219330285036 -74 73.0 -5.91831292823 -0.0233936269399 -75 74.0 -5.89422062685 -0.0247780985587 -76 75.0 -5.86878284696 -0.0260842279959 -77 76.0 -5.84207897162 -0.0273099606906 -78 77.0 -5.81419035593 -0.0284534080045 -79 78.0 -5.78520015867 -0.0295128519729 -80 79.0 -5.7551931694 -0.0304867496727 -81 80.0 -5.72425563141 -0.0313737371989 -82 81.0 -5.6924750609 -0.0321726332348 -83 82.0 -5.65994006273 -0.0328824422092 -84 83.0 -5.62674014332 -0.0335023570292 -85 84.0 -5.59296552097 -0.0340317613814 -86 85.0 -5.55870693409 -0.0344702315961 -87 86.0 -5.52405544786 -0.0348175380654 -88 87.0 -5.48910225957 -0.0350736462148 -89 88.0 -5.45393850338 -0.0352387170203 -90 89.0 -5.41865505462 -0.0353131070729 -91 90.0 -5.38334233438 -0.0352973681855 -92 91.0 -5.34809011465 -0.0351922465446 -93 92.0 -5.31298732458 -0.0349986814067 -94 93.0 -5.27812185824 -0.034717803342 -95 94.0 -5.24358038438 -0.0343509320285 -96 95.0 -5.2094481586 -0.0338995736008 -97 96.0 -5.17580883839 -0.0333654175598 -98 97.0 -5.14274430152 -0.0327503332496 -99 98.0 -5.11033446814 -0.0320563659092 -100 99.0 -5.07865712698 -0.0312857323082 -101 100.0 -5.04778776623 -0.0304408159764 -102 101.0 -5.01779940929 -0.0295241620384 -103 102.0 -4.98876245596 -0.0285384716647 -104 103.0 -4.96074452928 -0.0274865961525 -105 104.0 -4.93381032851 -0.0263715306507 -106 105.0 -4.90802148862 -0.0251964075427 -107 106.0 -4.88343644644 -0.0239644895038 -108 107.0 -4.86011031397 -0.0226791622487 -109 108.0 -4.83809475914 -0.0213439269874 -110 109.0 -4.81743789414 -0.0199623926068 -111 110.0 -4.79818417182 -0.0185382675969 -112 111.0 -4.78037429015 -0.0170753517415 -113 112.0 -4.76404510526 -0.0155775275918 -114 113.0 -4.74922955293 -0.0140487517461 -115 114.0 -4.73595657904 -0.0124930459538 -116 115.0 -4.7242510789 -0.0109144880672 -117 116.0 -4.71413384576 -0.00931720286182 -118 117.0 -4.70562152846 -0.00770535274772 -119 118.0 -4.69872659855 -0.00608312839491 -120 119.0 -4.69345732669 -0.00445473929448 -121 120.0 -4.6898177686 -0.00282440427898 -122 121.0 -4.68780776044 -0.00119634202478 -123 122.0 -4.68742292374 0.000425238440527 -124 123.0 -4.68865467977 0.0020361472029 -125 124.0 -4.69149027336 0.00363222287571 -126 125.0 -4.69591280613 0.00520934194008 -127 126.0 -4.70190127895 0.0067634279891 -128 127.0 -4.70943064365 0.00829046085365 -129 128.0 -4.71847186379 0.00978648558781 -130 129.0 -4.72899198423 0.0112476212922 -131 130.0 -4.74095420961 0.0126700697544 -132 131.0 -4.7543179912 0.0140501238848 -133 132.0 -4.76903912216 0.0153841759291 -134 133.0 -4.78506984093 0.0166687254364 -135 134.0 -4.80235894235 0.0179003869651 -136 135.0 -4.82085189642 0.0190758975074 -137 136.0 -4.84049097437 0.0201921236154 -138 137.0 -4.86121538156 0.0212460682116 -139 138.0 -4.88296139722 0.0222348770682 -140 139.0 -4.90566252032 0.0231558449399 -141 140.0 -4.9292496215 0.0240064213355 -142 141.0 -4.95365110055 0.0247842159162 -143 142.0 -4.97879304911 0.0254870035063 -144 143.0 -5.00459941816 0.0261127287073 -145 144.0 -5.03099218995 0.0266595101027 -146 145.0 -5.05789155387 0.0271256440463 -147 146.0 -5.08521608601 0.0275096080241 -148 147.0 -5.11288293171 0.0278100635833 -149 148.0 -5.14080799097 0.0280258588231 -150 149.0 -5.16890610603 0.0281560304409 -151 150.0 -5.19709125082 0.0281998053314 -152 151.0 -5.22527672173 0.0281566017347 -153 152.0 -5.25337532941 0.0280260299338 -154 153.0 -5.28129959092 0.0278078924984 -155 154.0 -5.30896192196 0.0275021840788 -156 155.0 -5.33627482866 0.0271090907491 -157 156.0 -5.36315109852 0.0266289889046 -158 157.0 -5.38950398994 0.026062443717 -159 158.0 -5.41524742011 0.0254102071518 -160 159.0 -5.44029615055 0.0246732155563 -161 160.0 -5.46456597019 0.0238525868232 -162 161.0 -5.48797387528 0.0229496171403 -163 162.0 -5.51043824587 0.0219657773349 -164 163.0 -5.53187901853 0.0209027088232 -165 164.0 -5.55221785468 0.0197622191769 -166 165.0 -5.57137830441 0.0185462773191 -167 166.0 -5.58928596528 0.0172570083629 -168 167.0 -5.60586863576 0.0158966881068 -169 168.0 -5.62105646307 0.0144677372016 -170 169.0 -5.63478208493 0.0129727150063 -171 170.0 -5.64698076513 0.0114143131467 -172 171.0 -5.65759052241 0.00979534879707 -173 172.0 -5.66655225257 0.00811875770075 -174 173.0 -5.67380984344 0.00638758694863 -175 174.0 -5.67931028251 0.00460498753534 -176 175.0 -5.68300375706 0.00277420671195 -177 176.0 -5.68484374646 0.000898580155594 -178 177.0 -5.68478710669 -0.00101847602368 -179 178.0 -5.68279414663 -0.00297347341791 -180 179.0 -5.67882869631 -0.00496285957718 -181 180.0 -5.67285816674 -0.00698302636509 -182 181.0 -5.6648536014 -0.00903031839234 -183 182.0 -5.65478971926 -0.0111010415069 -184 183.0 -5.64264494925 -0.0131914713189 -185 184.0 -5.62840145627 -0.0152978617389 -186 185.0 -5.6120451586 -0.017416453508 -187 186.0 -5.59356573683 -0.0195434826976 -188 187.0 -5.57295663425 -0.0216751891584 -189 188.0 -5.55021504898 -0.0238078248974 -190 189.0 -5.52534191754 -0.0259376623617 -191 190.0 -5.4983418904 -0.0280610026087 -192 191.0 -5.46922329932 -0.0301741833429 -193 192.0 -5.43799811672 -0.0322735868002 -194 193.0 -5.40468190731 -0.0343556474589 -195 194.0 -5.36929377207 -0.0364168595607 -196 195.0 -5.33185628476 -0.0384537844225 -197 196.0 -5.29239542138 -0.0404630575223 -198 197.0 -5.25094048245 -0.0424413953416 -199 198.0 -5.20752400881 -0.0443856019501 -200 199.0 -5.16218169074 -0.0462925753151 -201 200.0 -5.11495227114 -0.0481593133234 -202 201.0 -5.06587744261 -0.0499829195012 -203 202.0 -5.01500173918 -0.0517606084187 -204 203.0 -4.96237242264 -0.0534897107689 -205 204.0 -4.90803936404 -0.055167678109 -206 205.0 -4.85205492059 -0.0567920872546 -207 206.0 -4.79447380837 -0.0583606443179 -208 207.0 -4.73535297113 -0.0598711883816 -209 208.0 -4.6747514457 -0.0613216948024 -210 209.0 -4.61273022413 -0.0627102781377 -211 210.0 -4.54935211328 -0.0640351946902 -212 211.0 -4.4846815919 -0.0652948446678 -213 212.0 -4.41878466581 -0.0664877739558 -214 213.0 -4.35172872155 -0.0676126754981 -215 214.0 -4.28358237872 -0.0686683902899 -216 215.0 -4.21441534165 -0.0696539079796 -217 216.0 -4.14429825061 -0.070568367083 -218 217.0 -4.07330253293 -0.0714110548116 -219 218.0 -4.00150025463 -0.0721814065199 -220 219.0 -3.92896397266 -0.072879004774 -221 220.0 -3.85576658834 -0.0735035780505 -222 221.0 -3.78198120223 -0.0740549990687 -223 222.0 -3.70768097086 -0.0745332827669 -224 223.0 -3.63293896573 -0.0749385839297 -225 224.0 -3.5578280347 -0.0752711944755 -226 225.0 -3.48242066643 -0.075531540416 -227 226.0 -3.4067888579 -0.0757201784978 -228 227.0 -3.33100398548 -0.0758377925383 -229 228.0 -3.25513667985 -0.0758851894693 -230 229.0 -3.17925670492 -0.0758632951011 -231 230.0 -3.10343284123 -0.0757731496217 -232 231.0 -3.02773277394 -0.0756159028468 -233 232.0 -2.95222298559 -0.0753928092342 -234 233.0 -2.87696865416 -0.0751052226812 -235 234.0 -2.80203355622 -0.0747545911191 -236 235.0 -2.72747997572 -0.0743424509249 -237 236.0 -2.65336861841 -0.073870421164 -238 237.0 -2.57975853208 -0.0733401976859 -239 238.0 -2.50670703279 -0.0727535470871 -240 239.0 -2.4342696372 -0.0721123005638 -241 240.0 -2.36250000104 -0.0714183476691 -242 241.0 -2.29144986396 -0.0706736299971 -243 242.0 -2.22116900065 -0.0698801348102 -244 243.0 -2.15170517837 -0.0690398886302 -245 244.0 -2.0831041209 -0.0681549508121 -246 245.0 -2.01540947892 -0.067227407119 -247 246.0 -1.94866280684 -0.0662593633171 -248 247.0 -1.88290354594 -0.0652529388105 -249 248.0 -1.81816901389 -0.0642102603325 -250 249.0 -1.7544944006 -0.0631334557138 -251 250.0 -1.69191277013 -0.0620246477436 -252 251.0 -1.6304550688 -0.0608859481423 -253 252.0 -1.57015013921 -0.059719451663 -254 253.0 -1.51102474011 -0.0585272303374 -255 254.0 -1.45310357187 -0.0573113278834 -256 255.0 -1.39640930762 -0.0560737542899 -257 256.0 -1.34096262951 -0.054816480593 -258 257.0 -1.28678227024 -0.0535414338587 -259 258.0 -1.23388505944 -0.0522504923856 -260 259.0 -1.18228597475 -0.0509454811405 -261 260.0 -1.13199819729 -0.0496281674395 -262 261.0 -1.08303317143 -0.0483002568854 -263 262.0 -1.03540066834 -0.046963389572 -264 263.0 -0.989108853377 -0.0456191365664 -265 264.0 -0.944164356669 -0.0442689966762 -266 265.0 -0.900572346917 -0.0429143935113 -267 266.0 -0.858336607922 -0.0415566728462 -268 267.0 -0.817459617608 -0.0401971002897 -269 268.0 -0.777942629232 -0.0388368592669 -270 269.0 -0.739785754436 -0.0374770493178 -271 270.0 -0.702988047855 -0.0361186847156 -272 271.0 -0.667547592939 -0.0347626934072 -273 272.0 -0.633461588675 -0.0334099162773 -274 273.0 -0.600726436882 -0.0320611067354 -275 274.0 -0.569337829756 -0.0307169306269 -276 275.0 -0.539290837348 -0.0293779664649 -277 276.0 -0.510579994645 -0.0280447059807 -278 277.0 -0.483199387947 -0.0267175549897 -279 278.0 -0.457142740217 -0.0253968345674 -280 279.0 -0.432403495111 -0.0240827825309 -281 280.0 -0.408974899365 -0.0227755552188 -282 281.0 -0.386850083265 -0.0214752295619 -283 282.0 -0.366022138902 -0.020181805438 -284 283.0 -0.346484195932 -0.0188952082997 -285 284.0 -0.328229494574 -0.0176152920667 -286 285.0 -0.311251455597 -0.0163418422722 -287 286.0 -0.295543747024 -0.0150745794496 -288 287.0 -0.28110034735 -0.0138131627512 -289 288.0 -0.267915605017 -0.0125571937823 -290 289.0 -0.255984293962 -0.011306220639 -291 290.0 -0.245301665026 -0.0100597421363 -292 291.0 -0.235863493049 -0.00881721220956 -293 292.0 -0.22766611948 -0.00757804447631 -294 293.0 -0.220706490355 -0.00634161694135 -295 294.0 -0.214982189503 -0.00510727682957 -296 295.0 -0.210491466861 -0.00387434552992 -297 296.0 -0.207233261801 -0.00264212363344 -298 297.0 -0.205207221373 -0.00140989604849 -299 298.0 -0.204413713408 -0.00017693717569 -300 299.0 -0.204853834414 0.0010574838751 -301 300.0 -0.206529412255 0.00229409804323 -302 301.0 -0.209443003569 0.00353363106913 -303 302.0 -0.213597885954 0.00477679825726 -304 303.0 -0.218998044922 0.00602429926791 -305 304.0 -0.22564815567 0.00727681295572 -306 305.0 -0.23355355972 0.00853499227222 -307 306.0 -0.2427202365 0.00979945924997 -308 307.0 -0.253154769958 0.0110708000854 -309 308.0 -0.264864310313 0.0123495603372 -310 309.0 -0.277856531075 0.0136362402565 -311 310.0 -0.292139581459 0.0149312902659 -312 311.0 -0.307722034364 0.0162351066015 -313 312.0 -0.324612830087 0.0175480271349 -314 313.0 -0.342821215943 0.0188703273888 -315 314.0 -0.362356682012 0.0202022167596 -316 315.0 -0.383228893218 0.0215438349636 -317 316.0 -0.405447617967 0.0228952487148 -318 317.0 -0.429022653586 0.0242564486517 -319 318.0 -0.45396374882 0.0256273465206 -320 319.0 -0.480280523637 0.0270077726275 -321 320.0 -0.507982386639 0.0283974735696 -322 321.0 -0.537078450328 0.029796110253 -323 322.0 -0.567577444555 0.0312032562068 -324 323.0 -0.59948762842 0.0326183962009 -325 324.0 -0.632816700956 0.0340409251716 -326 325.0 -0.667571710883 0.0354701474639 -327 326.0 -0.703758965776 0.0369052763923 -328 327.0 -0.741383940946 0.038345434125 -329 328.0 -0.780451188376 0.0397896518935 -330 329.0 -0.820964246018 0.0412368705304 -331 330.0 -0.862925547807 0.042685941334 -332 331.0 -0.906336334692 0.0441356272615 -333 332.0 -0.951196567028 0.045584604448 -334 333.0 -0.997504838648 0.0470314640498 -335 334.0 -1.04525829294 0.048474714408 -336 335.0 -1.09445254125 0.0499127835288 -337 336.0 -1.1450815839 0.0513440218749 -338 337.0 -1.1971377342 0.0527667054614 -339 338.0 -1.25061154564 0.0541790392498 -340 339.0 -1.30549174267 0.0555791608316 -341 340.0 -1.36176515529 0.0569651443923 -342 341.0 -1.41941665773 0.0583350049463 -343 342.0 -1.47842911151 0.0596867028317 -344 343.0 -1.53878331313 0.061018148454 -345 344.0 -1.60045794659 0.0623272072653 -346 345.0 -1.66342954101 0.0636117049668 -347 346.0 -1.72767243359 0.0648694329207 -348 347.0 -1.79315873807 0.0660981537565 -349 348.0 -1.85985831882 0.0672956071568 -350 349.0 -1.92773877092 0.0684595158069 -351 350.0 -1.99676540616 0.0695875914917 -352 351.0 -2.06690124527 0.0706775413231 -353 352.0 -2.13810701636 0.0717270740805 -354 353.0 -2.21034115987 0.0727339066469 -355 354.0 -2.28355983986 0.0736957705223 -356 355.0 -2.35771696194 0.0746104183955 -357 356.0 -2.43276419776 0.0754756307561 -358 357.0 -2.50865101613 0.0762892225281 -359 358.0 -2.58532472075 0.0770490497051 -360 359.0 -2.66273049463 0.0777530159679 - -# Table of the potential and its negative derivative for frustrated beta sheet -# (Note: Derivatives are in units of energy/radians, not energy/degrees.) -# ./calc_dihedral_table.py 5.6 57.29577951308232 6 6.0 180 6 0.0 359 360 - -FRUSTRATED_BETA -N 360 DEGREES - -1 0.0 -2.55809068762 0.0731724739818 -2 1.0 -2.63154144494 0.0737195744566 -3 2.0 -2.70551060968 0.0742089966437 -4 3.0 -2.77993963883 0.074639023134 -5 4.0 -2.85476830901 0.0750080115297 -6 5.0 -2.92993479441 0.0753144003899 -7 6.0 -3.00537575069 0.0755567150326 -8 7.0 -3.08102640456 0.0757335731758 -9 8.0 -3.15682064892 0.0758436903983 -10 9.0 -3.23269114341 0.075885885404 -11 10.0 -3.30856942003 0.0758590850738 -12 11.0 -3.38438599377 0.0757623292865 -13 12.0 -3.46007047791 0.0755947754951 -14 13.0 -3.53555170381 0.0753557030426 -15 14.0 -3.61075784476 0.0750445172025 -16 15.0 -3.68561654392 0.0746607529305 -17 16.0 -3.76005504566 0.0742040783151 -18 17.0 -3.83400033034 0.0736742977129 -19 18.0 -3.907379252 0.0730713545594 -20 19.0 -3.98011867868 0.0723953338429 -21 20.0 -4.0521456351 0.0716464642332 -22 21.0 -4.12338744726 0.0708251198546 -23 22.0 -4.19377188857 0.0699318216967 -24 23.0 -4.26322732737 0.0689672386556 -25 24.0 -4.33168287509 0.0679321881993 -26 25.0 -4.39906853508 0.0668276366524 -27 26.0 -4.46531535141 0.0656546990963 -28 27.0 -4.53035555742 0.0644146388823 -29 28.0 -4.59412272358 0.0631088667546 -30 29.0 -4.65655190431 0.061738939584 -31 30.0 -4.71757978327 0.0603065587109 -32 31.0 -4.77714481686 0.0588135679005 -33 32.0 -4.83518737548 0.057261950911 -34 33.0 -4.89164988211 0.0556538286799 -35 34.0 -4.94647694795 0.0539914561312 -36 35.0 -4.99961550465 0.0522772186102 -37 36.0 -5.05101493277 0.0505136279528 -38 37.0 -5.10062718621 0.048703318195 -39 38.0 -5.14840691207 0.0468490409338 -40 39.0 -5.19431156578 0.0449536603471 -41 40.0 -5.23830152101 0.0430201478838 -42 41.0 -5.28034017422 0.0410515766363 -43 42.0 -5.3203940433 0.0390511154063 -44 43.0 -5.35843286021 0.0370220224793 -45 44.0 -5.39442965726 0.0349676391193 -46 45.0 -5.4283608467 0.0328913828015 -47 46.0 -5.46020629342 0.0307967401964 -48 47.0 -5.48994938059 0.028687259923 -49 48.0 -5.51757706789 0.0265665450883 -50 49.0 -5.54307994213 0.0244382456298 -51 50.0 -5.56645226024 0.0223060504811 -52 51.0 -5.58769198425 0.0201736795783 -53 52.0 -5.60680080825 0.0180448757265 -54 53.0 -5.62378417713 0.0159233963481 -55 54.0 -5.63865129702 0.0138130051308 -56 55.0 -5.6514151374 0.0117174635982 -57 56.0 -5.66209242462 0.00964052262251 -58 57.0 -5.67070362704 0.00758591390103 -59 58.0 -5.67727293157 0.00555734141841 -60 59.0 -5.6818282117 0.00355847291538 -61 60.0 -5.68440098698 0.00159293138608 -62 61.0 -5.68502637408 -0.000335713374531 -63 62.0 -5.68374302934 -0.00222395315148 -64 63.0 -5.68059308309 -0.0040683495974 -65 64.0 -5.67562206565 -0.00586554240548 -66 65.0 -5.66887882528 -0.00761225734683 -67 66.0 -5.66041543813 -0.00930531415106 -68 67.0 -5.65028711044 -0.0109416342099 -69 68.0 -5.63855207307 -0.0125182480831 -70 69.0 -5.6252714687 -0.0140323027883 -71 70.0 -5.61050923182 -0.0154810688529 -72 71.0 -5.59433196178 -0.0168619471125 -73 72.0 -5.57680878923 -0.0181724752358 -74 73.0 -5.5580112361 -0.019410333958 -75 74.0 -5.53801306959 -0.0205733530082 -76 75.0 -5.51689015031 -0.0216595167121 -77 76.0 -5.49472027505 -0.0226669692568 -78 77.0 -5.47158301441 -0.0235940196022 -79 78.0 -5.44755954575 -0.0244391460249 -80 79.0 -5.42273248172 -0.0252010002837 -81 80.0 -5.3971856949 -0.0258784113929 -82 81.0 -5.37100413881 -0.0264703889936 -83 82.0 -5.34427366574 -0.0269761263135 -84 83.0 -5.31708084192 -0.0273950027051 -85 84.0 -5.28951276022 -0.0277265857564 -86 85.0 -5.26165685114 -0.0279706329651 -87 86.0 -5.23360069216 -0.0281270929735 -88 87.0 -5.20543181621 -0.0281961063563 -89 88.0 -5.17723751951 -0.0281780059613 -90 89.0 -5.14910466934 -0.0280733167983 -91 90.0 -5.12111951208 -0.0278827554757 -92 91.0 -5.09336748214 -0.0276072291861 -93 92.0 -5.06593301201 -0.0272478342399 -94 93.0 -5.0388993441 -0.026805854151 -95 94.0 -5.01234834466 -0.0262827572773 -96 95.0 -4.98636032033 -0.0256801940208 -97 96.0 -4.96101383762 -0.0249999935924 -98 97.0 -4.93638554598 -0.0242441603499 -99 98.0 -4.91255000457 -0.0234148697145 -100 99.0 -4.88957951348 -0.0225144636776 -101 100.0 -4.86754394953 -0.0215454459053 -102 101.0 -4.84651060724 -0.0205104764546 -103 102.0 -4.8265440452 -0.01941236611 -104 103.0 -4.80770593836 -0.0182540703564 -105 104.0 -4.79005493648 -0.0170386830008 -106 105.0 -4.77364652914 -0.0157694294583 -107 106.0 -4.7585329176 -0.0144496597171 -108 107.0 -4.74476289391 -0.0130828410011 -109 108.0 -4.73238172744 -0.0116725501446 -110 109.0 -4.72143105919 -0.0102224657007 -111 110.0 -4.71194880414 -0.00873635979846 -112 111.0 -4.70396906182 -0.0072180897712 -113 112.0 -4.69752203541 -0.00567158957449 -114 113.0 -4.69263395945 -0.00410086101469 -115 114.0 -4.68932703648 -0.00250996480925 -116 115.0 -4.68761938265 -0.000903011500147 -117 116.0 -4.68752498248 0.00071584775762 -118 117.0 -4.68905365291 0.00234243051027 -119 118.0 -4.69221101668 0.00397253239976 -120 119.0 -4.69699848518 0.00560193661579 -121 120.0 -4.70341325069 0.00722642338265 -122 121.0 -4.71144828821 0.00884177945771 -123 122.0 -4.72109236669 0.0104438076188 -124 123.0 -4.73233006984 0.0120283361174 -125 124.0 -4.74514182625 0.0135912280748 -126 125.0 -4.75950394898 0.0151283907985 -127 126.0 -4.77538868431 0.0166357849963 -128 127.0 -4.79276426974 0.0181094338658 -129 128.0 -4.81159500092 0.0195454320375 -130 129.0 -4.83184130754 0.0209399543498 -131 130.0 -4.8534598378 0.0222892644342 -132 131.0 -4.87640355143 0.0235897230915 -133 132.0 -4.90062182095 0.0248377964369 -134 133.0 -4.92606054096 0.0260300637961 -135 134.0 -4.95266224518 0.0271632253326 -136 135.0 -4.98036623096 0.028234109388 -137 136.0 -5.00910869107 0.0292396795182 -138 137.0 -5.03882285221 0.0301770412082 -139 138.0 -5.06943912022 0.0310434482505 -140 139.0 -5.10088523142 0.0318363087705 -141 140.0 -5.13308640979 0.0325531908865 -142 141.0 -5.16596552963 0.0331918279898 -143 142.0 -5.19944328334 0.0337501236332 -144 143.0 -5.23343835383 0.0342261560164 -145 144.0 -5.26786759123 0.0346181820585 -146 145.0 -5.30264619353 0.0349246410472 -147 146.0 -5.33768789051 0.0351441578585 -148 147.0 -5.37290513082 0.0352755457383 -149 148.0 -5.40820927152 0.0353178086401 -150 149.0 -5.4435107698 0.0352701431151 -151 150.0 -5.4787193763 0.0351319397498 -152 151.0 -5.51374432971 0.0349027841491 -153 152.0 -5.54849455206 0.0345824574643 -154 153.0 -5.58287884436 0.0341709364636 -155 154.0 -5.61680608206 0.0336683931487 -156 155.0 -5.65018540988 0.0330751939177 -157 156.0 -5.68292643563 0.0323918982779 -158 157.0 -5.71493942249 0.0316192571138 -159 158.0 -5.74613547931 0.0307582105139 -160 159.0 -5.77642674856 0.029809885165 -161 160.0 -5.80572659147 0.0287755913197 -162 161.0 -5.83394976986 0.0276568193473 -163 162.0 -5.86101262442 0.0264552358763 -164 163.0 -5.8868332488 0.025172679541 -165 164.0 -5.91133165941 0.0238111563427 -166 165.0 -5.93442996024 0.0223728346376 -167 166.0 -5.95605250261 0.0208600397671 -168 167.0 -5.97612603931 0.0192752483425 -169 168.0 -5.99457987285 0.0176210822011 -170 169.0 -6.01134599757 0.015900302049 -171 170.0 -6.02635923519 0.014115800807 -172 171.0 -6.03955736358 0.0122705966784 -173 172.0 -6.05088123845 0.0103678259555 -174 173.0 -6.0602749078 0.00841073558436 -175 174.0 -6.06768571866 0.00640267550713 -176 175.0 -6.0730644163 0.00434709080102 -177 176.0 -6.07636523524 0.00224751363529 -178 177.0 -6.07754598232 0.000107555066143 -179 178.0 -6.07656811141 -0.00206910330914 -180 179.0 -6.07339678973 -0.00427871781763 -181 180.0 -6.06800095563 -0.00651749127408 -182 181.0 -6.06035336781 -0.00878158162059 -183 182.0 -6.05043064586 -0.0110671106207 -184 183.0 -6.03821330204 -0.0133701725859 -185 184.0 -6.02368576439 -0.0156868431131 -186 185.0 -6.00683639108 -0.0180131878107 -187 186.0 -5.98765747603 -0.0203452709919 -188 187.0 -5.96614524589 -0.0226791643135 -189 188.0 -5.94229984843 -0.025010955339 -190 189.0 -5.91612533236 -0.0273367560054 -191 190.0 -5.88762961878 -0.0296527109716 -192 191.0 -5.85682446433 -0.0319550058299 -193 192.0 -5.82372541626 -0.0342398751598 -194 193.0 -5.78835175943 -0.0365036104045 -195 194.0 -5.75072645562 -0.0387425675516 -196 195.0 -5.71087607524 -0.0409531746008 -197 196.0 -5.66883072166 -0.0431319387984 -198 197.0 -5.62462394846 -0.0452754536249 -199 198.0 -5.57829266983 -0.0473804055171 -200 199.0 -5.5298770643 -0.0494435803104 -201 200.0 -5.47942047235 -0.0514618693867 -202 201.0 -5.42696928781 -0.0534322755136 -203 202.0 -5.37257284377 -0.055351918363 -204 203.0 -5.316283293 -0.0572180396955 -205 204.0 -5.25815548345 -0.059028008202 -206 205.0 -5.19824682901 -0.0607793239895 -207 206.0 -5.13661717604 -0.0624696227052 -208 207.0 -5.0733286659 -0.0640966792879 -209 208.0 -5.00844559393 -0.0656584113417 -210 209.0 -4.94203426529 -0.0671528821253 -211 210.0 -4.87416284794 -0.0685783031513 -212 211.0 -4.80490122327 -0.0699330363936 -213 212.0 -4.7343208347 -0.0712155960973 -214 213.0 -4.66249453466 -0.0724246501921 -215 214.0 -4.58949643037 -0.0735590213066 -216 215.0 -4.51540172879 -0.0746176873849 -217 216.0 -4.44028658118 -0.0755997819067 -218 217.0 -4.3642279276 -0.0765045937139 -219 218.0 -4.28730334182 -0.0773315664459 -220 219.0 -4.20959087694 -0.0780802975905 -221 220.0 -4.13116891218 -0.0787505371538 -222 221.0 -4.0521160012 -0.0793421859574 -223 222.0 -3.97251072229 -0.0798552935693 -224 223.0 -3.89243153076 -0.0802900558785 -225 224.0 -3.81195661404 -0.0806468123209 -226 225.0 -3.73116374964 -0.0809260427693 -227 226.0 -3.65013016636 -0.0811283640964 -228 227.0 -3.56893240921 -0.0812545264246 -229 228.0 -3.48764620813 -0.0813054090744 -230 229.0 -3.4063463509 -0.0812820162266 -231 230.0 -3.32510656064 -0.0811854723104 -232 231.0 -3.24399937793 -0.081017017134 -233 232.0 -3.16309604794 -0.0807780007742 -234 233.0 -3.08246641287 -0.0804698782381 -235 234.0 -3.00217880976 -0.0800942039176 -236 235.0 -2.92229997393 -0.079652625851 -237 236.0 -2.84289494829 -0.0791468798106 -238 237.0 -2.76402699866 -0.0785787832348 -239 238.0 -2.68575753514 -0.0779502290223 -240 239.0 -2.60814603984 -0.077263179207 -241 240.0 -2.53125000097 -0.0765196585342 -242 241.0 -2.4551248533 -0.0757217479546 -243 242.0 -2.37982392531 -0.0748715780578 -244 243.0 -2.30539839282 -0.073971322463 -245 244.0 -2.23189723927 -0.0730231911866 -246 245.0 -2.15936722267 -0.072029424007 -247 246.0 -2.0878528491 -0.0709922838436 -248 247.0 -2.01739635293 -0.0699140501714 -249 248.0 -1.94803768347 -0.0687970124882 -250 249.0 -1.87981449824 -0.0676434638537 -251 250.0 -1.81276216256 -0.0664556945194 -252 251.0 -1.74691375554 -0.0652359856651 -253 252.0 -1.68230008218 -0.0639866032624 -254 253.0 -1.61894969164 -0.0627097920793 -255 254.0 -1.55688890134 -0.0614077698443 -256 255.0 -1.49614182687 -0.0600827215855 -257 256.0 -1.43673041741 -0.05873679416 -258 257.0 -1.37867449659 -0.0573720909874 -259 258.0 -1.32199180845 -0.0559906670036 -260 259.0 -1.26669806833 -0.0545945238457 -261 260.0 -1.21280701853 -0.0531856052829 -262 261.0 -1.1603304883 -0.0517657929031 -263 262.0 -1.1092784581 -0.0503369020679 -264 263.0 -1.05965912771 -0.0489006781451 -265 264.0 -1.01147898802 -0.0474587930279 -266 265.0 -0.964742896092 -0.0460128419505 -267 266.0 -0.919454153297 -0.0445643406057 -268 267.0 -0.875614586172 -0.0431147225719 -269 268.0 -0.833224629688 -0.0416653370554 -270 269.0 -0.792283412613 -0.0402174469521 -271 270.0 -0.752788844664 -0.038772227232 -272 271.0 -0.714737705101 -0.0373307636499 -273 272.0 -0.67812573245 -0.0358940517831 -274 273.0 -0.642947715028 -0.0344629963972 -275 274.0 -0.609197581934 -0.0330384111393 -276 275.0 -0.576868494182 -0.0316210185584 -277 276.0 -0.545952935658 -0.0302114504483 -278 277.0 -0.51644280357 -0.0288102485125 -279 278.0 -0.488329498068 -0.0274178653447 -280 279.0 -0.461604010741 -0.0260346657211 -281 280.0 -0.436257011655 -0.0246609281969 -282 281.0 -0.412278934657 -0.023296847002 -283 282.0 -0.389660060626 -0.0219425342253 -284 283.0 -0.368390598407 -0.0205980222818 -285 284.0 -0.348460763137 -0.01926326665 -286 285.0 -0.329860851704 -0.0179381488715 -287 286.0 -0.312581315078 -0.0166224797996 -288 287.0 -0.296612827279 -0.015316003087 -289 288.0 -0.281946350734 -0.0140183988977 -290 289.0 -0.268573197826 -0.0127292878319 -291 290.0 -0.256485088408 -0.0114482350481 -292 291.0 -0.245674203109 -0.0101747545698 -293 292.0 -0.236133232246 -0.00890831375923 -294 293.0 -0.227855420178 -0.00764833794542 -295 294.0 -0.220834604976 -0.00639421518813 -296 295.0 -0.215065253253 -0.00514530116277 -297 296.0 -0.210542490065 -0.00390092414876 -298 297.0 -0.207262123775 -0.00266039010467 -299 298.0 -0.205220665805 -0.00142298781263 -300 299.0 -0.204415345223 -0.000187994074493 -301 300.0 -0.204844118104 0.00104532105779 -302 301.0 -0.206505671662 0.00227768903543 -303 302.0 -0.209399423126 0.0035098375675 -304 303.0 -0.213525513386 0.00474248539479 -305 304.0 -0.218884795423 0.00597633710062 -306 305.0 -0.225478817581 0.00721207797616 -307 306.0 -0.233309801737 0.00845036895769 -308 307.0 -0.242380616448 0.00969184165314 -309 308.0 -0.252694745185 0.0109370934746 -310 309.0 -0.264256249747 0.0121866828936 -311 310.0 -0.277069729013 0.0134411248358 -312 311.0 -0.291140273151 0.0147008862297 -313 312.0 -0.306473413467 0.0159663817261 -314 313.0 -0.323075068066 0.0172379696031 -315 314.0 -0.340951483513 0.018515947869 -316 315.0 -0.360109172702 0.0198005505798 -317 316.0 -0.380554849155 0.0210919443819 -318 317.0 -0.402295357987 0.0223902252933 -319 318.0 -0.425337603767 0.0236954157356 -320 319.0 -0.449688475549 0.0250074618263 -321 320.0 -0.475354769327 0.0263262309427 -322 321.0 -0.50234310819 0.0276515095659 -323 322.0 -0.530659860472 0.0289830014145 -324 323.0 -0.560311056174 0.0303203258736 -325 324.0 -0.59130230198 0.0316630167284 -326 325.0 -0.623638695141 0.0330105212056 -327 326.0 -0.657324736579 0.0343621993296 -328 327.0 -0.692364243488 0.0357173235955 -329 328.0 -0.728760261774 0.0370750789637 -330 329.0 -0.766514978659 0.0384345631765 -331 330.0 -0.805629635748 0.0397947873984 -332 331.0 -0.846104442913 0.04115467718 -333 332.0 -0.887938493289 0.042513073745 -334 333.0 -0.93112967973 0.0438687355968 -335 334.0 -0.975674613021 0.0452203404434 -336 335.0 -1.02156854218 0.0465664874361 -337 336.0 -1.06880527714 0.0479056997168 -338 337.0 -1.11737711415 0.0492364272675 -339 338.0 -1.16727476416 0.0505570500574 -340 339.0 -1.2184872845 0.051865881477 -341 340.0 -1.27100201415 0.0531611720525 -342 341.0 -1.32480451282 0.0544411134304 -343 342.0 -1.37987850417 0.055703842622 -344 343.0 -1.43620582346 0.0569474464963 -345 344.0 -1.49376636966 0.0581699665097 -346 345.0 -1.55253806258 0.05936940366 -347 346.0 -1.61249680493 0.0605437236497 -348 347.0 -1.67361644969 0.0616908622471 -349 348.0 -1.73586877296 0.0628087308273 -350 349.0 -1.79922345238 0.0638952220804 -351 350.0 -1.86364805137 0.0649482158688 -352 351.0 -1.92910800931 0.0659655852184 -353 352.0 -1.9955666377 0.066945202426 -354 353.0 -2.06298512258 0.0678849452658 -355 354.0 -2.13132253309 0.0687827032771 -356 355.0 -2.20053583647 0.0696363841147 -357 356.0 -2.27057991931 0.0704439199439 -358 357.0 -2.3414076153 0.0712032738621 -359 358.0 -2.41296973939 0.0719124463259 -360 359.0 -2.48521512832 0.072569481568 diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated/run.in.min b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated/run.in.min deleted file mode 100644 index 8eb3a03cbb..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated/run.in.min +++ /dev/null @@ -1,19 +0,0 @@ -# -- Init section -- - -include system.in.init - -# -- Atom definition section -- - -read_data system.data - -# -- Settings Section -- - -include system.in.settings - -# -- Run section -- - -dump 1 all custom 50 traj_min.lammpstrj id mol type x y z ix iy iz - -minimize 1.0e-5 1.0e-7 500 2000 - -write_data system_after_min.data diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated/run_short_sim.in.nvt b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated/run_short_sim.in.nvt deleted file mode 100644 index 185d03cf15..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/frustrated/run_short_sim.in.nvt +++ /dev/null @@ -1,50 +0,0 @@ -# -- Init Section -- - -include system.in.init - -# -- Atom Definition Section -- - -# I you want to be careful, you can minimize the system first. -# (Try using "run.in.min" and uncomment line below.) -# read_data system_after_min.data - -read_data system.data - -# -- Settings Section -- - -include system.in.settings - -# -- Run Section -- - - -timestep 0.025 -dump 1 all custom 50 traj_nvt.lammpstrj id mol type x y z ix iy iz - -# To use Langevin dynamics in LAMMPS you need both "fix langevin" and "fix nve". -# (See http://lammps.sandia.gov/doc/fix_langevin.html for details.) - -# Keep the chaperonin fixed. Only let the protein move. - -fix fxlan proteins langevin 0.25 0.25 1.0 48279 -fix fxnve proteins nve - -# Notes: -# The temperature is in reduced units and is set to 0.25 -# which is the folding temperature for the frustrated protein -# The inverse-damping-rate "damp" (which has units of time) is set to 1.0, -# as it was in the paper. (Hopefully folding times should be similar.) -# (See http://lammps.sandia.gov/doc/fix_langevin.html) - - -thermo_style custom step temp pe etotal press vol epair ebond eangle edihed -thermo_modify norm no #(report total energy not energy / num_atoms) -thermo 50 #(time interval for printing out "thermo" data) - -#restart 100000000 restart_nvt - -# Just run it long enough for it to collapse (not fold) -# (If you need to run it longer, then dump trajectory data less frequently.) -run 50000 - -write_data system_after_nvt.data - diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated+chaperonin/README.TXT b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated+chaperonin/README.TXT deleted file mode 100644 index 5da41b9a8b..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated+chaperonin/README.TXT +++ /dev/null @@ -1,32 +0,0 @@ -# This directory demonstrates how to run a short simulation of -# the "unfrustrated" coarse-grained protein model used in: -# AI Jewett, A Baumketner and J-E Shea, PNAS, 101 (36), 13192-13197, (2004) -# (http://www.pnas.org/content/101/36/13192) -# -# In this example, the protein is placed inside a repulsive sphere -# of radius 6.0 sigma which confines its motion. -# (This sphere is sometimes called the "chaperonin", because -# we were using it to model the crude behavior of a chaperonin cavity.) -# -# During this short simulation (run.in.nvt) the protein evolves -# from an unfolded initial conformation to the folded state. -# -# -------- REQUIREMENTS: --------- -# 1) This example requires the "USER-MISC" package. (Use "make yes-USER-MISC") -# http://lammps.sandia.gov/doc/Section_start.html#start_3 -# 2) It also may require additional features and bug fixes for LAMMPS. -# be sure to download and copy the "additional_lammps_code" from -# http://moltemplate.org (upper-left corner menu) -# 3) Unpack it -# 4) copy the .cpp and .h files to the src folding of your lammps installation. -# 5) Compile LAMMPS. - -------------- -Instructions on how to build LAMMPS input files and -run a short simulation are provided in other README files. - -step 1) -README_setup.sh - -step2) -README_run.sh diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated+chaperonin/README_run.sh b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated+chaperonin/README_run.sh deleted file mode 100755 index 45bd2d451d..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated+chaperonin/README_run.sh +++ /dev/null @@ -1,31 +0,0 @@ -# You would probably run lammps this way: -# -# lmp_ubuntu -i run.in.nvt - -# The files "run.in.min", and "run.in.nvt" are LAMMPS input scripts which refer -# to the input scripts & data files you created earlier when you ran moltemplate -# system.in.init, system.in.settings, system.data - - - - -# ----------------------------------- - - - -LAMMPS_COMMAND="lmp_ubuntu" - -# Here "$LAMMPS_BINARY" is the name of the command you use to invoke lammps -# (such as lmp_linux, lmp_g++, lmp_mac, lmp_cygwin, etc...) Change if necessary. - -# Run lammps using the following 3 commands: - -"$LAMMPS_COMMAND" -i run.in.min # minimize (OPTIONAL) -"$LAMMPS_COMMAND" -i run.in.nvt # production run - -# Alternately, if you have MPI installed, try something like this: - -#NUMPROCS=4 -#mpirun -np $NUMPROCS "$LAMMPS_COMMAND" -i run.in.min # minimize (OPTIONAL) -#mpirun -np $NUMPROCS "$LAMMPS_COMMAND" -i run.in.nvt # production run - diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated+chaperonin/README_setup.sh b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated+chaperonin/README_setup.sh deleted file mode 100755 index df49f4384f..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated+chaperonin/README_setup.sh +++ /dev/null @@ -1,24 +0,0 @@ -# Use these commands to generate the LAMMPS input script and data file -# (and other auxilliary files): - - -# Create LAMMPS input files this way: -cd moltemplate_files - - # run moltemplate - - moltemplate.sh -overlay-dihedrals system.lt - - # This will generate various files with names ending in *.in* and *.data. - # These files are the input files directly read by LAMMPS. Move them to - # the parent directory (or wherever you plan to run the simulation). - - mv -f system.in* system.data ../ - cp -r table*.dat ../ - - # Optional: - # The "./output_ttree/" directory is full of temporary files generated by - # moltemplate. They can be useful for debugging, but are usually thrown away. - rm -rf output_ttree/ - -cd ../ diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated+chaperonin/README_visualize.txt b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated+chaperonin/README_visualize.txt deleted file mode 100644 index 019afc1444..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated+chaperonin/README_visualize.txt +++ /dev/null @@ -1,87 +0,0 @@ - - ------- To view a lammps trajectory in VMD -------- - - -1) Build a PSF file for use in viewing with VMD. - -This step works with VMD 1.9 and topotools 1.2. -(Older versions, like VMD 1.8.6, don't support this.) - - -a) Start VMD -b) Menu Extensions->Tk Console -c) Enter: - -(I assume that the the DATA file is called "system.data") - - topo readlammpsdata system.data full - animate write psf system.psf - -2) - -Later, to Load a trajectory in VMD: - - Start VMD - Select menu: File->New Molecule - -Browse to select the PSF file you created above, and load it. - (Don't close the window yet.) - -Browse to select the trajectory file. - If necessary, for "file type" select: "LAMMPS Trajectory" - Load it. - - ---- A note on trajectory format: ----- -If the trajectory is a DUMP file, then make sure the it contains the -information you need for pbctools (see below. I've been using this -command in my LAMMPS scripts to create the trajectories: - - dump 1 all custom 5000 DUMP_FILE.lammpstrj id mol type x y z ix iy iz - -It's a good idea to use an atom_style which supports molecule-ID numbers -so that you can assign a molecule-ID number to each atom. (I think this -is needed to wrap atom coordinates without breaking molecules in half.) - -Of course, you don't have to save your trajectories in DUMP format, -(other formats like DCD work fine) I just mention dump files -because these are the files I'm familiar with. - -3) ----- Wrap the coordinates to the unit cell - (without cutting the molecules in half) - -a) Start VMD -b) Load the trajectory in VMD (see above) -c) Menu Extensions->Tk Console -d) Try entering these commands: - - pbc wrap -compound res -all - pbc box - - ----- Optional ---- - Sometimes the solvent or membrane obscures the view of the solute. - It can help to shift the location of the periodic boundary box - To shift the box in the y direction (for example) do this: - - pbc wrap -compound res -all -shiftcenterrel {0.0 0.15 0.0} - pbc box -shiftcenterrel {0.0 0.15 0.0} - - Distances are measured in units of box-length fractions, not Angstroms. - - Alternately if you have a solute whose atoms are all of type 1, - then you can also try this to center the box around it: - - pbc wrap -sel type=1 -all -centersel type=2 -center com - -4) - You should check if your periodic boundary conditions are too small. - To do that: - select Graphics->Representations menu option - click on the "Periodic" tab, and - click on the "+x", "-x", "+y", "-y", "+z", "-z" checkboxes. - -5) Optional: If you like, change the atom types in the PSF file so - that VMD recognizes the atom types, use something like: - -sed -e 's/ 1 1 / C C /g' < system.psf > temp1.psf -sed -e 's/ 2 2 / H H /g' < temp1.psf > temp2.psf -sed -e 's/ 3 3 / P P /g' < temp2.psf > system.psf - -(If you do this, it might effect step 2 above.) diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated+chaperonin/images/for_visualization/psf_file_created_by_topotools/system.psf b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated+chaperonin/images/for_visualization/psf_file_created_by_topotools/system.psf deleted file mode 100644 index 7763505c0d..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated+chaperonin/images/for_visualization/psf_file_created_by_topotools/system.psf +++ /dev/null @@ -1,98 +0,0 @@ -PSF - - 1 !NTITLE - REMARKS VMD generated structure x-plor psf file - - 28 !NATOM - 1 1 1 1 0.000000 100.0000 0 - 2 2 3 3 0.000000 1.0000 0 - 3 2 2 2 0.000000 1.0000 0 - 4 2 3 3 0.000000 1.0000 0 - 5 2 2 2 0.000000 1.0000 0 - 6 2 3 3 0.000000 1.0000 0 - 7 2 2 2 0.000000 1.0000 0 - 8 2 4 4 0.000000 1.0000 0 - 9 2 4 4 0.000000 1.0000 0 - 10 2 2 2 0.000000 1.0000 0 - 11 2 3 3 0.000000 1.0000 0 - 12 2 2 2 0.000000 1.0000 0 - 13 2 3 3 0.000000 1.0000 0 - 14 2 2 2 0.000000 1.0000 0 - 15 2 3 3 0.000000 1.0000 0 - 16 2 4 4 0.000000 1.0000 0 - 17 2 4 4 0.000000 1.0000 0 - 18 2 4 4 0.000000 1.0000 0 - 19 2 2 2 0.000000 1.0000 0 - 20 2 2 2 0.000000 1.0000 0 - 21 2 3 3 0.000000 1.0000 0 - 22 2 3 3 0.000000 1.0000 0 - 23 2 2 2 0.000000 1.0000 0 - 24 2 2 2 0.000000 1.0000 0 - 25 2 3 3 0.000000 1.0000 0 - 26 2 3 3 0.000000 1.0000 0 - 27 2 2 2 0.000000 1.0000 0 - 28 2 3 3 0.000000 1.0000 0 - - 26 !NBOND: bonds - 2 3 3 4 4 5 5 6 - 6 7 7 8 8 9 9 10 - 10 11 11 12 12 13 13 14 - 14 15 15 16 16 17 17 18 - 18 19 19 20 20 21 21 22 - 22 23 23 24 24 25 25 26 - 26 27 27 28 - - 25 !NTHETA: angles - 3 4 5 5 6 7 10 11 12 - 12 13 14 8 9 10 7 8 9 - 17 18 19 19 20 21 23 24 25 - 22 23 24 2 3 4 4 5 6 - 11 12 13 13 14 15 26 27 28 - 15 16 17 6 7 8 9 10 11 - 14 15 16 18 19 20 20 21 22 - 21 22 23 24 25 26 25 26 27 - 16 17 18 - - 43 !NPHI: dihedrals - 2 3 4 5 2 3 4 5 - 3 4 5 6 3 4 5 6 - 4 5 6 7 4 5 6 7 - 5 6 7 8 5 6 7 8 - 6 7 8 9 7 8 9 10 - 8 9 10 11 9 10 11 12 - 9 10 11 12 10 11 12 13 - 10 11 12 13 11 12 13 14 - 11 12 13 14 12 13 14 15 - 12 13 14 15 13 14 15 16 - 13 14 15 16 14 15 16 17 - 15 16 17 18 16 17 18 19 - 16 17 18 19 17 18 19 20 - 17 18 19 20 18 19 20 21 - 18 19 20 21 19 20 21 22 - 19 20 21 22 20 21 22 23 - 20 21 22 23 21 22 23 24 - 21 22 23 24 22 23 24 25 - 22 23 24 25 23 24 25 26 - 23 24 25 26 24 25 26 27 - 24 25 26 27 25 26 27 28 - 25 26 27 28 - - 0 !NIMPHI: impropers - - - 0 !NDON: donors - - - 0 !NACC: acceptors - - - 0 !NNB - - 0 0 0 0 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 !NGRP - 0 0 0 - diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated+chaperonin/images/unfrustrated+chaperonin_t=0tau_LR.jpg b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated+chaperonin/images/unfrustrated+chaperonin_t=0tau_LR.jpg deleted file mode 100644 index a0da344db5656fcce716e52eee2b1731a993f800..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16267 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 Console -c) Enter: - -(I assume that the the DATA file is called "system.data") - - topo readlammpsdata system.data full - animate write psf system.psf - -2) - -Later, to Load a trajectory in VMD: - - Start VMD - Select menu: File->New Molecule - -Browse to select the PSF file you created above, and load it. - (Don't close the window yet.) - -Browse to select the trajectory file. - If necessary, for "file type" select: "LAMMPS Trajectory" - Load it. - - ---- A note on trajectory format: ----- -If the trajectory is a DUMP file, then make sure the it contains the -information you need for pbctools (see below. I've been using this -command in my LAMMPS scripts to create the trajectories: - - dump 1 all custom 5000 DUMP_FILE.lammpstrj id mol type x y z ix iy iz - -It's a good idea to use an atom_style which supports molecule-ID numbers -so that you can assign a molecule-ID number to each atom. (I think this -is needed to wrap atom coordinates without breaking molecules in half.) - -Of course, you don't have to save your trajectories in DUMP format, -(other formats like DCD work fine) I just mention dump files -because these are the files I'm familiar with. - -3) ----- Wrap the coordinates to the unit cell - (without cutting the molecules in half) - -a) Start VMD -b) Load the trajectory in VMD (see above) -c) Menu Extensions->Tk Console -d) Try entering these commands: - - pbc wrap -compound res -all - pbc box - - ----- Optional ---- - Sometimes the solvent or membrane obscures the view of the solute. - It can help to shift the location of the periodic boundary box - To shift the box in the y direction (for example) do this: - - pbc wrap -compound res -all -shiftcenterrel {0.0 0.15 0.0} - pbc box -shiftcenterrel {0.0 0.15 0.0} - - Distances are measured in units of box-length fractions, not Angstroms. - - Alternately if you have a solute whose atoms are all of type 1, - then you can also try this to center the box around it: - - pbc wrap -sel type=1 -all -centersel type=2 -center com - -4) - You should check if your periodic boundary conditions are too small. - To do that: - select Graphics->Representations menu option - click on the "Periodic" tab, and - click on the "+x", "-x", "+y", "-y", "+z", "-z" checkboxes. - -5) Optional: If you like, change the atom types in the PSF file so - that VMD recognizes the atom types, use something like: - -sed -e 's/ 1 1 / C C /g' < system.psf > temp1.psf -sed -e 's/ 2 2 / H H /g' < temp1.psf > temp2.psf -sed -e 's/ 3 3 / P P /g' < temp2.psf > system.psf - -(If you do this, it might effect step 2 above.) diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated/images/for_visualization/psf_file_created_by_topotools/system.psf b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated/images/for_visualization/psf_file_created_by_topotools/system.psf deleted file mode 100644 index 1470af4bc1..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated/images/for_visualization/psf_file_created_by_topotools/system.psf +++ /dev/null @@ -1,97 +0,0 @@ -PSF - - 1 !NTITLE - REMARKS VMD generated structure x-plor psf file - - 27 !NATOM - 1 1 2 2 0.000000 1.0000 0 - 2 1 1 1 0.000000 1.0000 0 - 3 1 2 2 0.000000 1.0000 0 - 4 1 1 1 0.000000 1.0000 0 - 5 1 2 2 0.000000 1.0000 0 - 6 1 1 1 0.000000 1.0000 0 - 7 1 3 3 0.000000 1.0000 0 - 8 1 3 3 0.000000 1.0000 0 - 9 1 1 1 0.000000 1.0000 0 - 10 1 2 2 0.000000 1.0000 0 - 11 1 1 1 0.000000 1.0000 0 - 12 1 2 2 0.000000 1.0000 0 - 13 1 1 1 0.000000 1.0000 0 - 14 1 2 2 0.000000 1.0000 0 - 15 1 3 3 0.000000 1.0000 0 - 16 1 3 3 0.000000 1.0000 0 - 17 1 3 3 0.000000 1.0000 0 - 18 1 1 1 0.000000 1.0000 0 - 19 1 1 1 0.000000 1.0000 0 - 20 1 2 2 0.000000 1.0000 0 - 21 1 2 2 0.000000 1.0000 0 - 22 1 1 1 0.000000 1.0000 0 - 23 1 1 1 0.000000 1.0000 0 - 24 1 2 2 0.000000 1.0000 0 - 25 1 2 2 0.000000 1.0000 0 - 26 1 1 1 0.000000 1.0000 0 - 27 1 2 2 0.000000 1.0000 0 - - 26 !NBOND: bonds - 1 2 2 3 3 4 4 5 - 5 6 6 7 7 8 8 9 - 9 10 10 11 11 12 12 13 - 13 14 14 15 15 16 16 17 - 17 18 18 19 19 20 20 21 - 21 22 22 23 23 24 24 25 - 25 26 26 27 - - 25 !NTHETA: angles - 13 14 15 7 8 9 6 7 8 - 16 17 18 15 16 17 2 3 4 - 4 5 6 9 10 11 11 12 13 - 14 15 16 1 2 3 3 4 5 - 10 11 12 12 13 14 25 26 27 - 5 6 7 8 9 10 17 18 19 - 18 19 20 22 23 24 21 22 23 - 19 20 21 20 21 22 23 24 25 - 24 25 26 - - 43 !NPHI: dihedrals - 1 2 3 4 1 2 3 4 - 2 3 4 5 2 3 4 5 - 3 4 5 6 3 4 5 6 - 4 5 6 7 4 5 6 7 - 5 6 7 8 6 7 8 9 - 7 8 9 10 8 9 10 11 - 8 9 10 11 9 10 11 12 - 9 10 11 12 10 11 12 13 - 10 11 12 13 11 12 13 14 - 11 12 13 14 12 13 14 15 - 12 13 14 15 13 14 15 16 - 14 15 16 17 15 16 17 18 - 15 16 17 18 16 17 18 19 - 16 17 18 19 17 18 19 20 - 17 18 19 20 18 19 20 21 - 18 19 20 21 19 20 21 22 - 19 20 21 22 20 21 22 23 - 20 21 22 23 21 22 23 24 - 21 22 23 24 22 23 24 25 - 22 23 24 25 23 24 25 26 - 23 24 25 26 24 25 26 27 - 24 25 26 27 - - 0 !NIMPHI: impropers - - - 0 !NDON: donors - - - 0 !NACC: acceptors - - - 0 !NNB - - 0 0 0 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 !NGRP - 0 0 0 - diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated/images/unfrustrated_t=0tau_LR.jpg b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated/images/unfrustrated_t=0tau_LR.jpg deleted file mode 100644 index 152fa88ff927375764035bd9297b1dbf701a8027..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7690 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 diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated/images/unfrustrated_t=200tau_LR.jpg b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated/images/unfrustrated_t=200tau_LR.jpg deleted file mode 100644 index bb269f47f27f176fc64c2d9ee96ea51adc4595c6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7821 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 diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated/moltemplate_files/1beadUnfrustrated.lt b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated/moltemplate_files/1beadUnfrustrated.lt deleted file mode 100644 index 0dc1f5dd05..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated/moltemplate_files/1beadUnfrustrated.lt +++ /dev/null @@ -1,255 +0,0 @@ -# This file defines a pair of coarse-grained protein models used in: -# AI Jewett, A Baumketner and J-E Shea, PNAS, 101 (36), 13192-13197, (2004) -# (http://www.pnas.org/content/101/36/13192) - - -1beadUnfrustrated { - - # Note: the "unfrustrated" model is kind of funny looking. (My apologies.) - - # There are 3 atom types (referred to above as B, L, and N) - # Define their masses: - - write_once("Data Masses") { - @atom:B 1.0 - @atom:L 1.0 - @atom:N 1.0 - } - - # AtomID MoleculeID AtomType Charge X Y Z - - write("Data Atoms") { - $atom:a1 $mol @atom:L 0.0 -1.3969548 1.7525716 -0.28565118 - $atom:a2 $mol @atom:B 0.0 -0.66847917 1.0738923 -0.39651074 - $atom:a3 $mol @atom:L 0.0 -0.16610379 1.0893417 0.44519456 - $atom:a4 $mol @atom:B 0.0 0.42244126 0.35006314 0.15979926 - $atom:a5 $mol @atom:L 0.0 1.2844393 0.55103218 0.64505356 - $atom:a6 $mol @atom:N 0.0 1.9703715 0.37775946 -0.05267634 - $atom:a7 $mol @atom:N 0.0 2.574926 -0.30399114 0.34330503 - $atom:a8 $mol @atom:N 0.0 2.029546 -1.1256647 0.19829852 - $atom:a9 $mol @atom:B 0.0 1.0936146 -0.76054936 0.1043528 - $atom:a10 $mol @atom:L 0.0 0.74888247 -0.81165991 1.0334863 - $atom:a11 $mol @atom:B 0.0 -0.069536333 -0.26815389 0.94356636 - $atom:a12 $mol @atom:L 0.0 -0.65671052 -0.522532 1.7113065 - $atom:a13 $mol @atom:N 0.0 -1.5278507 -0.10774689 1.4611921 - $atom:a14 $mol @atom:L 0.0 -2.1958878 -0.8403146 1.5521738 - $atom:a15 $mol @atom:N 0.0 -2.6058074 -0.86553455 0.64397232 - $atom:a16 $mol @atom:N 0.0 -1.8447588 -1.1286421 0.042924693 - $atom:a17 $mol @atom:N 0.0 -1.5328721 -0.28576244 -0.40564841 - $atom:a18 $mol @atom:B 0.0 -0.69593879 0.027664412 0.064884008 - $atom:a19 $mol @atom:B 0.0 0.0026517494 -0.66355162 -0.11470678 - $atom:a20 $mol @atom:L 0.0 -0.35479285 -1.2282381 -0.86455878 - $atom:a21 $mol @atom:L 0.0 -0.60202976 -0.47829758 -1.4411001 - $atom:a22 $mol @atom:B 0.0 -0.14616501 0.20157397 -0.87098365 - $atom:a23 $mol @atom:B 0.0 0.7755198 -0.14153019 -0.76838748 - $atom:a24 $mol @atom:L 0.0 1.2465693 0.19738595 -1.5794731 - $atom:a25 $mol @atom:L 0.0 0.77604792 1.0612244 -1.637442 - $atom:a26 $mol @atom:B 0.0 0.44801303 1.1110219 -0.6900789 - $atom:a27 $mol @atom:L 0.0 1.0908651 1.7386382 -0.24229241 - } - - # bond-ID bond-Type atom-ID atom-ID - - write("Data Bonds") { - $bond:b1 @bond:backbone $atom:a1 $atom:a2 - $bond:b2 @bond:backbone $atom:a2 $atom:a3 - $bond:b3 @bond:backbone $atom:a3 $atom:a4 - $bond:b4 @bond:backbone $atom:a4 $atom:a5 - $bond:b5 @bond:backbone $atom:a5 $atom:a6 - $bond:b6 @bond:backbone $atom:a6 $atom:a7 - $bond:b7 @bond:backbone $atom:a7 $atom:a8 - $bond:b8 @bond:backbone $atom:a8 $atom:a9 - $bond:b9 @bond:backbone $atom:a9 $atom:a10 - $bond:b10 @bond:backbone $atom:a10 $atom:a11 - $bond:b11 @bond:backbone $atom:a11 $atom:a12 - $bond:b12 @bond:backbone $atom:a12 $atom:a13 - $bond:b13 @bond:backbone $atom:a13 $atom:a14 - $bond:b14 @bond:backbone $atom:a14 $atom:a15 - $bond:b15 @bond:backbone $atom:a15 $atom:a16 - $bond:b16 @bond:backbone $atom:a16 $atom:a17 - $bond:b17 @bond:backbone $atom:a17 $atom:a18 - $bond:b18 @bond:backbone $atom:a18 $atom:a19 - $bond:b19 @bond:backbone $atom:a19 $atom:a20 - $bond:b20 @bond:backbone $atom:a20 $atom:a21 - $bond:b21 @bond:backbone $atom:a21 $atom:a22 - $bond:b22 @bond:backbone $atom:a22 $atom:a23 - $bond:b23 @bond:backbone $atom:a23 $atom:a24 - $bond:b24 @bond:backbone $atom:a24 $atom:a25 - $bond:b25 @bond:backbone $atom:a25 $atom:a26 - $bond:b26 @bond:backbone $atom:a26 $atom:a27 - } - - # (3-body) Angles are specified below - - # (4-body) Dihedrals must be defined explicitly for every quartet of atoms. - # (These interactions are not determined by atom type.) - # - # Note that some quartets of atoms are listed because their - # potentials contain multiple terms in the Fourier expansion. - # (IE. multiple cosines... Be sure to use "-overlay-dihedrals"!) - # - # dihedral-ID dihedral-Type atom-ID atom-ID atom-ID atom-ID - - write("Data Dihedrals") { - $dihedral:d1a @dihedral:beta1 $atom:a1 $atom:a2 $atom:a3 $atom:a4 - $dihedral:d1b @dihedral:beta2 $atom:a1 $atom:a2 $atom:a3 $atom:a4 - $dihedral:d2a @dihedral:beta1 $atom:a2 $atom:a3 $atom:a4 $atom:a5 - $dihedral:d2b @dihedral:beta2 $atom:a2 $atom:a3 $atom:a4 $atom:a5 - $dihedral:d3a @dihedral:beta1 $atom:a3 $atom:a4 $atom:a5 $atom:a6 - $dihedral:d3b @dihedral:beta2 $atom:a3 $atom:a4 $atom:a5 $atom:a6 - $dihedral:d4a @dihedral:beta1 $atom:a4 $atom:a5 $atom:a6 $atom:a7 - $dihedral:d4b @dihedral:beta2 $atom:a4 $atom:a5 $atom:a6 $atom:a7 - $dihedral:d5 @dihedral:turn1 $atom:a5 $atom:a6 $atom:a7 $atom:a8 - $dihedral:d6 @dihedral:turn2 $atom:a6 $atom:a7 $atom:a8 $atom:a9 - $dihedral:d7 @dihedral:turn3 $atom:a7 $atom:a8 $atom:a9 $atom:a10 - $dihedral:d8a @dihedral:beta1 $atom:a8 $atom:a9 $atom:a10 $atom:a11 - $dihedral:d8b @dihedral:beta2 $atom:a8 $atom:a9 $atom:a10 $atom:a11 - $dihedral:d9a @dihedral:beta1 $atom:a9 $atom:a10 $atom:a11 $atom:a12 - $dihedral:d9b @dihedral:beta2 $atom:a9 $atom:a10 $atom:a11 $atom:a12 - $dihedral:d10a @dihedral:beta1 $atom:a10 $atom:a11 $atom:a12 $atom:a13 - $dihedral:d10b @dihedral:beta2 $atom:a10 $atom:a11 $atom:a12 $atom:a13 - $dihedral:d11a @dihedral:beta1 $atom:a11 $atom:a12 $atom:a13 $atom:a14 - $dihedral:d11b @dihedral:beta2 $atom:a11 $atom:a12 $atom:a13 $atom:a14 - $dihedral:d12a @dihedral:beta1 $atom:a12 $atom:a13 $atom:a14 $atom:a15 - $dihedral:d12b @dihedral:beta2 $atom:a12 $atom:a13 $atom:a14 $atom:a15 - $dihedral:d13 @dihedral:turn4 $atom:a13 $atom:a14 $atom:a15 $atom:a16 - $dihedral:d14 @dihedral:turn5 $atom:a14 $atom:a15 $atom:a16 $atom:a17 - $dihedral:d15a @dihedral:alpha1 $atom:a15 $atom:a16 $atom:a17 $atom:a18 - $dihedral:d15b @dihedral:alpha2 $atom:a15 $atom:a16 $atom:a17 $atom:a18 - $dihedral:d16a @dihedral:alpha1 $atom:a16 $atom:a17 $atom:a18 $atom:a19 - $dihedral:d16b @dihedral:alpha2 $atom:a16 $atom:a17 $atom:a18 $atom:a19 - $dihedral:d17a @dihedral:alpha1 $atom:a17 $atom:a18 $atom:a19 $atom:a20 - $dihedral:d17b @dihedral:alpha2 $atom:a17 $atom:a18 $atom:a19 $atom:a20 - $dihedral:d18a @dihedral:alpha1 $atom:a18 $atom:a19 $atom:a20 $atom:a21 - $dihedral:d18b @dihedral:alpha2 $atom:a18 $atom:a19 $atom:a20 $atom:a21 - $dihedral:d19a @dihedral:alpha1 $atom:a19 $atom:a20 $atom:a21 $atom:a22 - $dihedral:d19b @dihedral:alpha2 $atom:a19 $atom:a20 $atom:a21 $atom:a22 - $dihedral:d20a @dihedral:alpha1 $atom:a20 $atom:a21 $atom:a22 $atom:a23 - $dihedral:d20b @dihedral:alpha2 $atom:a20 $atom:a21 $atom:a22 $atom:a23 - $dihedral:d21a @dihedral:alpha1 $atom:a21 $atom:a22 $atom:a23 $atom:a24 - $dihedral:d21b @dihedral:alpha2 $atom:a21 $atom:a22 $atom:a23 $atom:a24 - $dihedral:d22a @dihedral:alpha1 $atom:a22 $atom:a23 $atom:a24 $atom:a25 - $dihedral:d22b @dihedral:alpha2 $atom:a22 $atom:a23 $atom:a24 $atom:a25 - $dihedral:d23a @dihedral:alpha1 $atom:a23 $atom:a24 $atom:a25 $atom:a26 - $dihedral:d23b @dihedral:alpha2 $atom:a23 $atom:a24 $atom:a25 $atom:a26 - $dihedral:d24a @dihedral:alpha1 $atom:a24 $atom:a25 $atom:a26 $atom:a27 - $dihedral:d24b @dihedral:alpha2 $atom:a24 $atom:a25 $atom:a26 $atom:a27 - } - - # All consecutively bonded triplets of atoms same 3-body bond-angle - # interaction parameters. Of coarse, we could specify them all explicitly - # (as we did for the dihedrals above), but I wanted to show how to specify - # angles by atom type instead. (You can do this for dihedrals & impropers - # also.) - - # angle-Type atom-Type atom-Type atom-Type bond-Type bond-Type - - write_once("Data Angles By Type") { - @angle:backbone @atom:* @atom:* @atom:* @bond:* @bond:* - } - - # (The "*" is a wildcard character. I use "*" to denote any atom-type or - # bond-type which is defined within the current namespace: 1beadUnfrustrated) - - - # 2-body (non-bonded) interactions: - # - # Uij(r) = 4*eps_ij * (K*(sig_ij/r)^12 + L*(sig_ij/r)^6) - # - # i j pairstylename eps sig K L - # - write_once("In Settings") { - pair_coeff @atom:B @atom:B lj/charmm/coul/charmm/inter 1.0 1.0 1 -1 - pair_coeff @atom:B @atom:L lj/charmm/coul/charmm/inter 0.5833333333 1.0 1 0 - pair_coeff @atom:B @atom:N lj/charmm/coul/charmm/inter 0.6666666667 1.0 1 0 - pair_coeff @atom:L @atom:L lj/charmm/coul/charmm/inter 0.1666666667 1.0 1 1 - pair_coeff @atom:L @atom:N lj/charmm/coul/charmm/inter 0.25 1.0 1 0 - pair_coeff @atom:N @atom:N lj/charmm/coul/charmm/inter 0.3333333333 1.0 1 0 - } - - - # 2-body (bonded) interactions: - # - # Ubond(r) = (k/2)*(r-0)^2 - # - # The corresponding command is: - # - # bond-Type bondstylename k r0 - - write_once("In Settings") { - bond_coeff @bond:backbone harmonic 100.0 1.0 - } - - # 3-body interactions in this example are listed by atomType and bondType - # The atomIDs involved are determined automatically. The forumula used is: - # - # Uangle(theta) = (k/2)*(theta-theta0)^2 - # (k in kcal/mol/rad^2, theta0 in degrees) - # - # angle-Type anglestylename k theta0 - - write_once("In Settings") { - angle_coeff @angle:backbone harmonic 13.3333333333 105.0 - } - - # 4-body interactions in this example are listed by atomType and bondType - # The atomIDs involved are determined automatically. The forumula used is: - # - # Udihedral(phi) = K * (1 + cos(n*phi - d)) - # - # The d parameter is in degrees, K is in kcal/mol/rad^2. - # - # The corresponding command is: - # - # dihedral_coeff dihedralType dihedralstylename K n d w - # ("w" is the weight for 1-4 pair interactions, which we set to 0) - - # NOTE: Currently, dihedral_coeff charmm does not allow non-integer d - # parameters. I'm hoping this will be fixed eventually. - - write_once("In Settings") { - # Correct version: - #dihedral_coeff @dihedral:alpha1 charmm -1.5 1 57.2957795 0.0 - # Replacing with - dihedral_coeff @dihedral:alpha1 charmm -1.5 1 57 0.0 - # Correct version: - #dihedral_coeff @dihedral:alpha2 charmm 0.375 2 114.591559 0.0 - # Replacing with - dihedral_coeff @dihedral:alpha2 charmm 0.375 2 115 0.0 - dihedral_coeff @dihedral:beta1 charmm -1.5 1 180 0.0 - dihedral_coeff @dihedral:beta2 charmm 0.375 2 360 0.0 - dihedral_coeff @dihedral:turn1 charmm -3.0 1 90 0.0 - # Correct version: - # dihedral_coeff @dihedral:turn2 charmm -3.0 1 11.4591559 0.0 - # Replacing with - dihedral_coeff @dihedral:turn2 charmm -3.0 1 11 0.0 - dihedral_coeff @dihedral:turn3 charmm -3.0 1 -90 0.0 - dihedral_coeff @dihedral:turn4 charmm 0.0 1 0 0.0 - dihedral_coeff @dihedral:turn5 charmm 0.0 1 0 0.0 - } - - write_once("In Settings") { - # Optional: define the atoms in the "proteins" group - group proteins type @atom:B - group proteins type @atom:L - group proteins type @atom:N - } - - # LAMMPS has many available force field styles (and atom styles). - # Here, we pick the ones which work well for this molecular model: - - write_once("In Init") { - # --- Default options for the "1BeadUnfrustrated" protein model --- - # --- (These can be overridden later.) --- - units lj - atom_style full - bond_style hybrid harmonic - angle_style hybrid harmonic - dihedral_style hybrid charmm - pair_style hybrid lj/charmm/coul/charmm/inter es4k4l maxmax 3.5 4.0 - pair_modify mix arithmetic - special_bonds lj 0.0 0.0 1.0 #(turn on "1-4" interactions) - } - -} # 1beadUnfrustrated - diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated/moltemplate_files/1beadUnfrustrated_variants.lt b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated/moltemplate_files/1beadUnfrustrated_variants.lt deleted file mode 100644 index cbc8fe217c..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated/moltemplate_files/1beadUnfrustrated_variants.lt +++ /dev/null @@ -1,45 +0,0 @@ -import "1beadUnfrustrated.lt" - - -# Alternate starting conformation (same molecule): - - -1beadUnfolded inherits 1beadUnfrustrated { - - # This molecule "inherits" all of its features from "1beadUnfrustrated" - # Here we override the atomic positions with new coordinates: - - # AtomID MoleculeID AtomType Charge X Y Z - - write("Data Atoms") { - $atom:a1 $mol @atom:L 0.0 -2.4 1.7 -0.0 - $atom:a2 $mol @atom:B 0.0 -1.8 1.7 0.8 - $atom:a3 $mol @atom:L 0.0 -1.2 2.5 0.8 - $atom:a4 $mol @atom:B 0.0 -0.6 2.5 -0.0 - $atom:a5 $mol @atom:L 0.0 0.0 1.7 -0.0 - $atom:a6 $mol @atom:B 0.0 0.6 1.7 0.8 - $atom:a7 $mol @atom:N 0.0 1.2 2.5 0.8 - $atom:a8 $mol @atom:N 0.0 1.8 2.5 -0.0 - $atom:a9 $mol @atom:B 0.0 2.4 1.7 -0.0 - $atom:a10 $mol @atom:L 0.0 3.0 1.7 -0.8 - $atom:a11 $mol @atom:B 0.0 3.0 0.7 -0.8 - $atom:a12 $mol @atom:L 0.0 3.0 0.1 -0.0 - $atom:a13 $mol @atom:B 0.0 3.8 -0.5 -0.0 - $atom:a14 $mol @atom:L 0.0 3.8 -1.1 -0.8 - $atom:a15 $mol @atom:N 0.0 3.0 -1.7 -0.8 - $atom:a16 $mol @atom:N 0.0 3.0 -1.7 0.2 - $atom:a17 $mol @atom:N 0.0 2.4 -2.5 0.2 - $atom:a18 $mol @atom:B 0.0 1.8 -2.5 -0.6 - $atom:a19 $mol @atom:B 0.0 1.2 -1.7 -0.6 - $atom:a20 $mol @atom:L 0.0 0.6 -1.7 0.2 - $atom:a21 $mol @atom:L 0.0 -0.0 -2.5 0.2 - $atom:a22 $mol @atom:B 0.0 -0.6 -2.5 -0.6 - $atom:a23 $mol @atom:B 0.0 -1.2 -1.7 -0.6 - $atom:a24 $mol @atom:L 0.0 -1.8 -1.7 0.2 - $atom:a25 $mol @atom:L 0.0 -2.4 -2.5 0.2 - $atom:a26 $mol @atom:B 0.0 -3.0 -2.5 -0.6 - $atom:a27 $mol @atom:L 0.0 -3.6 -1.7 -0.6 - } - -} # 1beadUnfolded - diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated/moltemplate_files/system.lt b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated/moltemplate_files/system.lt deleted file mode 100644 index 5ebe6efb88..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated/moltemplate_files/system.lt +++ /dev/null @@ -1,11 +0,0 @@ -import "1beadUnfrustrated_variants.lt" - - -protein = new 1beadUnfolded # (unfolded conformation, unfrustrated protein) - - -write_once("Data Boundary") { - 0.0 27.0 xlo xhi - 0.0 27.0 ylo yhi - 0.0 27.0 zlo zhi -} diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated/run.in.min b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated/run.in.min deleted file mode 100644 index 8eb3a03cbb..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated/run.in.min +++ /dev/null @@ -1,19 +0,0 @@ -# -- Init section -- - -include system.in.init - -# -- Atom definition section -- - -read_data system.data - -# -- Settings Section -- - -include system.in.settings - -# -- Run section -- - -dump 1 all custom 50 traj_min.lammpstrj id mol type x y z ix iy iz - -minimize 1.0e-5 1.0e-7 500 2000 - -write_data system_after_min.data diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated/run.in.nvt b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated/run.in.nvt deleted file mode 100644 index e49206ee3a..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1bead+chaperone/unfrustrated/run.in.nvt +++ /dev/null @@ -1,46 +0,0 @@ -# -- Init Section -- - -include system.in.init - -# -- Atom Definition Section -- - -# I you want to be careful, you can minimize the system first. -# (Try using "run.in.min" and uncomment the line below.) -# read_data system_after_min.data - -read_data system.data - -# -- Settings Section -- - -include system.in.settings - -# -- Run Section -- - - -timestep 0.025 -dump 1 all custom 50 traj_nvt.lammpstrj id mol type x y z ix iy iz - -# To use Langevin dynamics in LAMMPS you need both "fix langevin" and "fix nve". -# (See http://lammps.sandia.gov/doc/fix_langevin.html for details.) - -fix fxlan all langevin 0.39 0.39 1.0 48279 -fix fxnve all nve - -# Notes: -# The temperature is in reduced units and is set to 0.39 -# which is the folding temperature for the unfrustrated protein. -# The inverse-damping-rate "damp" (which has units of time) is set to 1.0, -# as it was in the paper. (Hopefully folding times should be similar.) -# (See http://lammps.sandia.gov/doc/fix_langevin.html) - - -thermo_style custom step temp pe etotal press vol epair ebond eangle edihed -thermo_modify norm no #(report total energy not energy / num_atoms) -thermo 50 #(time interval for printing out "thermo" data) - -#restart 100000000 restart_nvt - -run 8000 - -write_data system_after_nvt.data - diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1beadProtSci2010/README.TXT b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1beadProtSci2010/README.TXT deleted file mode 100644 index eda6a1ca22..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1beadProtSci2010/README.TXT +++ /dev/null @@ -1,44 +0,0 @@ -# -------- REQUIREMENTS: --------- -# 1) This example requires the "USER-MISC" package. (Use "make yes-USER-MISC") -# http://lammps.sandia.gov/doc/Section_start.html#start_3 -# 2) It also may require additional features and bug fixes for LAMMPS. -# be sure to download and copy the "additional_lammps_code" from -# http://moltemplate.org (upper-left corner menu) -# 3) Unpack it -# 4) copy the .cpp and .h files to the src folding of your lammps installation. -# 5) Compile LAMMPS. - -This is an example of a very simple coarse-grained protein. - -This example contains a 1-bead (C-alpha model) representation of the -"unfrustrated" 4-helix bundle model used in this paper: -G. Bellesia, AI Jewett, and J-E Shea, Protein Science, Vol19 141-154 (2010) - -In this model, there are three atom-types (bead-types), H, L, and N -representing one amino-acid each. The "H" beads represent the hydrophobic -amino acids, and are attracted to eachother with a strength of "1.0" -(in dimensionless units of "epsilon"). The "L" and "N" atoms are -hydrophilic and purely repulsive, and only differ in their secondary-structure -propensity (ie their dihedral parameters). - -The dihedral-interaction is bi-stable with two deep local minima (corresponding -to helix-like and sheet-like secondary structure). You can adjust the bias -in favor of one minima or another by modifying the angle-shift parameter in -the appropriate "dihedral_coeff" command in the other .lt file. - -A definition for the 4-sheet beta-barell protein model is also included. -If you want to simulate that molecule instead, then edit the "system.lt" -file (in the "moltemplate_files" subdirectory), and replace this line: -prot = new 4HelixBundle - with -prot = new 4SheetBundle - -------------- -Instructions on how to build LAMMPS input files and -run a short simulation are provided in other README files. - -step 1) -README_setup.sh - -step2) -README_run.sh diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1beadProtSci2010/README_run.sh b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1beadProtSci2010/README_run.sh deleted file mode 100755 index 4b0229453e..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1beadProtSci2010/README_run.sh +++ /dev/null @@ -1,31 +0,0 @@ -# You would probably run lammps this way: -# -# lmp_ubuntu -i run.in.nvt - -# The files "run.in.min", and "run.in.nvt" are LAMMPS input scripts which refer -# to the input scripts & data files you created earlier when you ran moltemplate -# system.in.init, system.in.settings, system.data - - - - -# ----------------------------------- - - - -LAMMPS_COMMAND="lmp_mpi" - -# Here "$LAMMPS_BINARY" is the name of the command you use to invoke lammps -# (such as lmp_ubuntu, lmp_mac_mpi, lmp_cygwin etc...) Change if necessary. - -# Run lammps using the following 3 commands: - -"$LAMMPS_COMMAND" -i run.in.min # minimize (OPTIONAL) -"$LAMMPS_COMMAND" -i run.in.nvt # production run - -# Alternately, if you have MPI installed, try something like this: - -#NUMPROCS=4 -#mpirun -np $NUMPROCS "$LAMMPS_COMMAND" -i run.in.min # minimize (OPTIONAL) -#mpirun -np $NUMPROCS "$LAMMPS_COMMAND" -i run.in.nvt # production run - diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1beadProtSci2010/README_setup.sh b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1beadProtSci2010/README_setup.sh deleted file mode 100755 index fa10f55724..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1beadProtSci2010/README_setup.sh +++ /dev/null @@ -1,23 +0,0 @@ -# Use these commands to generate the LAMMPS input script and data file -# (and other auxilliary files): - - -# Create LAMMPS input files this way: -cd moltemplate_files - - # run moltemplate - - moltemplate.sh -overlay-dihedrals system.lt - - # This will generate various files with names ending in *.in* and *.data. - # These files are the input files directly read by LAMMPS. Move them to - # the parent directory (or wherever you plan to run the simulation). - - mv -f system.in* system.data ../ - - # Optional: - # The "./output_ttree/" directory is full of temporary files generated by - # moltemplate. They can be useful for debugging, but are usually thrown away. - rm -rf output_ttree/ - -cd ../ diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1beadProtSci2010/README_visualize.txt b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1beadProtSci2010/README_visualize.txt deleted file mode 100644 index 019afc1444..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1beadProtSci2010/README_visualize.txt +++ /dev/null @@ -1,87 +0,0 @@ - - ------- To view a lammps trajectory in VMD -------- - - -1) Build a PSF file for use in viewing with VMD. - -This step works with VMD 1.9 and topotools 1.2. -(Older versions, like VMD 1.8.6, don't support this.) - - -a) Start VMD -b) Menu Extensions->Tk Console -c) Enter: - -(I assume that the the DATA file is called "system.data") - - topo readlammpsdata system.data full - animate write psf system.psf - -2) - -Later, to Load a trajectory in VMD: - - Start VMD - Select menu: File->New Molecule - -Browse to select the PSF file you created above, and load it. - (Don't close the window yet.) - -Browse to select the trajectory file. - If necessary, for "file type" select: "LAMMPS Trajectory" - Load it. - - ---- A note on trajectory format: ----- -If the trajectory is a DUMP file, then make sure the it contains the -information you need for pbctools (see below. I've been using this -command in my LAMMPS scripts to create the trajectories: - - dump 1 all custom 5000 DUMP_FILE.lammpstrj id mol type x y z ix iy iz - -It's a good idea to use an atom_style which supports molecule-ID numbers -so that you can assign a molecule-ID number to each atom. (I think this -is needed to wrap atom coordinates without breaking molecules in half.) - -Of course, you don't have to save your trajectories in DUMP format, -(other formats like DCD work fine) I just mention dump files -because these are the files I'm familiar with. - -3) ----- Wrap the coordinates to the unit cell - (without cutting the molecules in half) - -a) Start VMD -b) Load the trajectory in VMD (see above) -c) Menu Extensions->Tk Console -d) Try entering these commands: - - pbc wrap -compound res -all - pbc box - - ----- Optional ---- - Sometimes the solvent or membrane obscures the view of the solute. - It can help to shift the location of the periodic boundary box - To shift the box in the y direction (for example) do this: - - pbc wrap -compound res -all -shiftcenterrel {0.0 0.15 0.0} - pbc box -shiftcenterrel {0.0 0.15 0.0} - - Distances are measured in units of box-length fractions, not Angstroms. - - Alternately if you have a solute whose atoms are all of type 1, - then you can also try this to center the box around it: - - pbc wrap -sel type=1 -all -centersel type=2 -center com - -4) - You should check if your periodic boundary conditions are too small. - To do that: - select Graphics->Representations menu option - click on the "Periodic" tab, and - click on the "+x", "-x", "+y", "-y", "+z", "-z" checkboxes. - -5) Optional: If you like, change the atom types in the PSF file so - that VMD recognizes the atom types, use something like: - -sed -e 's/ 1 1 / C C /g' < system.psf > temp1.psf -sed -e 's/ 2 2 / H H /g' < temp1.psf > temp2.psf -sed -e 's/ 3 3 / P P /g' < temp2.psf > system.psf - -(If you do this, it might effect step 2 above.) diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1beadProtSci2010/images/4HelixBundle_t=0.jpg b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1beadProtSci2010/images/4HelixBundle_t=0.jpg deleted file mode 100644 index b4d919f9e692fa087f36eb561782ea9b15da95a2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 38619 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�W*3n4;-`?8DcTJ>@hM=Hi*1o)BP)~di0 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 diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1beadProtSci2010/images/4SheetBundle_t=0.jpg b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1beadProtSci2010/images/4SheetBundle_t=0.jpg deleted file mode 100644 index cd65146ffa2e88fa8014d3c73894fc8f60fd1cdf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49905 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 diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1beadProtSci2010/images/for_visualization/psf_file_created_by_topotools/system.psf b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1beadProtSci2010/images/for_visualization/psf_file_created_by_topotools/system.psf deleted file mode 100644 index de47509ed4..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1beadProtSci2010/images/for_visualization/psf_file_created_by_topotools/system.psf +++ /dev/null @@ -1,214 +0,0 @@ -PSF - - 1 !NTITLE - REMARKS VMD generated structure x-plor psf file - - 73 !NATOM - 1 1 1 1 0.000000 1.0000 0 - 2 1 1 1 0.000000 1.0000 0 - 3 1 2 2 0.000000 1.0000 0 - 4 1 2 2 0.000000 1.0000 0 - 5 1 1 1 0.000000 1.0000 0 - 6 1 1 1 0.000000 1.0000 0 - 7 1 2 2 0.000000 1.0000 0 - 8 1 2 2 0.000000 1.0000 0 - 9 1 1 1 0.000000 1.0000 0 - 10 1 1 1 0.000000 1.0000 0 - 11 1 2 2 0.000000 1.0000 0 - 12 1 2 2 0.000000 1.0000 0 - 13 1 1 1 0.000000 1.0000 0 - 14 1 1 1 0.000000 1.0000 0 - 15 1 2 2 0.000000 1.0000 0 - 16 1 2 2 0.000000 1.0000 0 - 17 1 1 1 0.000000 1.0000 0 - 18 1 1 1 0.000000 1.0000 0 - 19 1 2 2 0.000000 1.0000 0 - 20 1 2 2 0.000000 1.0000 0 - 21 1 1 1 0.000000 1.0000 0 - 22 1 1 1 0.000000 1.0000 0 - 23 1 2 2 0.000000 1.0000 0 - 24 1 2 2 0.000000 1.0000 0 - 25 1 1 1 0.000000 1.0000 0 - 26 1 1 1 0.000000 1.0000 0 - 27 1 2 2 0.000000 1.0000 0 - 28 1 2 2 0.000000 1.0000 0 - 29 1 1 1 0.000000 1.0000 0 - 30 1 1 1 0.000000 1.0000 0 - 31 1 2 2 0.000000 1.0000 0 - 32 1 2 2 0.000000 1.0000 0 - 33 1 1 1 0.000000 1.0000 0 - 34 1 1 1 0.000000 1.0000 0 - 35 1 2 2 0.000000 1.0000 0 - 36 1 2 2 0.000000 1.0000 0 - 37 1 1 1 0.000000 1.0000 0 - 38 1 1 1 0.000000 1.0000 0 - 39 1 2 2 0.000000 1.0000 0 - 40 1 2 2 0.000000 1.0000 0 - 41 1 1 1 0.000000 1.0000 0 - 42 1 1 1 0.000000 1.0000 0 - 43 1 2 2 0.000000 1.0000 0 - 44 1 2 2 0.000000 1.0000 0 - 45 1 1 1 0.000000 1.0000 0 - 46 1 1 1 0.000000 1.0000 0 - 47 1 2 2 0.000000 1.0000 0 - 48 1 2 2 0.000000 1.0000 0 - 49 1 1 1 0.000000 1.0000 0 - 50 1 1 1 0.000000 1.0000 0 - 51 1 2 2 0.000000 1.0000 0 - 52 1 2 2 0.000000 1.0000 0 - 53 1 1 1 0.000000 1.0000 0 - 54 1 1 1 0.000000 1.0000 0 - 55 1 2 2 0.000000 1.0000 0 - 56 1 2 2 0.000000 1.0000 0 - 57 1 1 1 0.000000 1.0000 0 - 58 1 1 1 0.000000 1.0000 0 - 59 1 2 2 0.000000 1.0000 0 - 60 1 2 2 0.000000 1.0000 0 - 61 1 1 1 0.000000 1.0000 0 - 62 1 1 1 0.000000 1.0000 0 - 63 1 2 2 0.000000 1.0000 0 - 64 1 2 2 0.000000 1.0000 0 - 65 1 3 3 0.000000 1.0000 0 - 66 1 3 3 0.000000 1.0000 0 - 67 1 3 3 0.000000 1.0000 0 - 68 1 3 3 0.000000 1.0000 0 - 69 1 3 3 0.000000 1.0000 0 - 70 1 3 3 0.000000 1.0000 0 - 71 1 3 3 0.000000 1.0000 0 - 72 1 3 3 0.000000 1.0000 0 - 73 1 3 3 0.000000 1.0000 0 - - 72 !NBOND: bonds - 1 2 2 3 3 4 4 5 - 5 6 6 7 7 8 8 9 - 9 10 10 11 11 12 12 13 - 13 14 14 15 15 16 16 65 - 17 18 17 70 18 19 19 20 - 20 21 21 22 22 23 23 24 - 24 25 25 26 26 27 27 28 - 28 29 29 30 30 31 31 32 - 32 67 33 34 33 68 34 35 - 35 36 36 37 37 38 38 39 - 39 40 40 41 41 42 42 43 - 43 44 44 45 45 46 46 47 - 47 48 48 71 49 50 50 51 - 51 52 52 53 53 54 54 55 - 55 56 56 57 57 58 58 59 - 59 60 60 61 61 62 62 63 - 63 64 64 73 65 66 66 67 - 68 69 69 70 71 72 72 73 - - 71 !NTHETA: angles - 16 65 66 32 67 66 48 71 72 - 64 73 72 2 3 4 3 4 5 - 6 7 8 7 8 9 10 11 12 - 11 12 13 14 15 16 18 19 20 - 19 20 21 22 23 24 23 24 25 - 26 27 28 27 28 29 30 31 32 - 34 35 36 35 36 37 38 39 40 - 39 40 41 42 43 44 43 44 45 - 46 47 48 50 51 52 51 52 53 - 54 55 56 55 56 57 58 59 60 - 59 60 61 62 63 64 15 16 65 - 31 32 67 47 48 71 63 64 73 - 34 33 68 18 17 70 1 2 3 - 4 5 6 5 6 7 8 9 10 - 9 10 11 12 13 14 13 14 15 - 17 18 19 20 21 22 21 22 23 - 24 25 26 25 26 27 28 29 30 - 29 30 31 33 34 35 36 37 38 - 37 38 39 40 41 42 41 42 43 - 44 45 46 45 46 47 49 50 51 - 52 53 54 53 54 55 56 57 58 - 57 58 59 60 61 62 61 62 63 - 17 70 69 33 68 69 65 66 67 - 68 69 70 71 72 73 - - 122 !NPHI: dihedrals - 4 5 6 7 8 9 10 11 - 12 13 14 15 20 21 22 23 - 24 25 26 27 28 29 30 31 - 36 37 38 39 40 41 42 43 - 44 45 46 47 52 53 54 55 - 56 57 58 59 60 61 62 63 - 2 3 4 5 6 7 8 9 - 10 11 12 13 18 19 20 21 - 22 23 24 25 26 27 28 29 - 34 35 36 37 38 39 40 41 - 42 43 44 45 50 51 52 53 - 54 55 56 57 58 59 60 61 - 3 4 5 6 1 2 3 4 - 7 8 9 10 5 6 7 8 - 11 12 13 14 9 10 11 12 - 13 14 15 16 19 20 21 22 - 17 18 19 20 23 24 25 26 - 21 22 23 24 27 28 29 30 - 25 26 27 28 29 30 31 32 - 35 36 37 38 33 34 35 36 - 39 40 41 42 37 38 39 40 - 43 44 45 46 41 42 43 44 - 45 46 47 48 51 52 53 54 - 49 50 51 52 55 56 57 58 - 53 54 55 56 59 60 61 62 - 57 58 59 60 61 62 63 64 - 4 5 6 7 8 9 10 11 - 12 13 14 15 20 21 22 23 - 24 25 26 27 28 29 30 31 - 36 37 38 39 40 41 42 43 - 44 45 46 47 52 53 54 55 - 56 57 58 59 60 61 62 63 - 2 3 4 5 6 7 8 9 - 10 11 12 13 18 19 20 21 - 22 23 24 25 26 27 28 29 - 34 35 36 37 38 39 40 41 - 42 43 44 45 50 51 52 53 - 54 55 56 57 58 59 60 61 - 3 4 5 6 1 2 3 4 - 7 8 9 10 5 6 7 8 - 11 12 13 14 9 10 11 12 - 13 14 15 16 19 20 21 22 - 17 18 19 20 23 24 25 26 - 21 22 23 24 27 28 29 30 - 25 26 27 28 29 30 31 32 - 35 36 37 38 33 34 35 36 - 39 40 41 42 37 38 39 40 - 43 44 45 46 41 42 43 44 - 45 46 47 48 51 52 53 54 - 49 50 51 52 55 56 57 58 - 53 54 55 56 59 60 61 62 - 57 58 59 60 61 62 63 64 - 68 69 70 17 33 68 69 70 - 65 66 67 32 16 65 66 67 - 71 72 73 64 48 71 72 73 - 34 33 68 69 18 17 70 69 - 68 33 34 35 70 17 18 19 - 15 16 65 66 31 32 67 66 - 47 48 71 72 63 64 73 72 - 14 15 16 65 30 31 32 67 - 46 47 48 71 62 63 64 73 - - 0 !NIMPHI: impropers - - - 0 !NDON: donors - - - 0 !NACC: acceptors - - - 0 !NNB - - 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 - 0 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 !NGRP - 0 0 0 - diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1beadProtSci2010/moltemplate_files/1beadProtSci2010.lt b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1beadProtSci2010/moltemplate_files/1beadProtSci2010.lt deleted file mode 100644 index 9b4ff25354..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1beadProtSci2010/moltemplate_files/1beadProtSci2010.lt +++ /dev/null @@ -1,274 +0,0 @@ -# This file defines a family of coarse-grained protein models used in: -# G. Bellesia, AI Jewett, and J-E Shea, Protein Science, Vol19 141-154 (2010) -# -# Strategy: -# -#1) First I'll define some building blocks (A16, B16, T3) -# which are helices, sheets and turns of a predetermined length) -# -#2) Then I'll copy and paste them together to build -# a 4-helix bundle or a 4-strand beta-barrel. -# This approach is optional. If your protein has helices which are not -# identical, you should probably just include all 4 helices in a single -# "Data Atoms" section and don't try to subdivide the protein into pieces.) - - -1beadProtSci2010 { # <-- enclose definitions in a namespace for portability - - write_once("In Init") { - units lj - atom_style full - bond_style hybrid harmonic - angle_style hybrid harmonic - dihedral_style hybrid fourier - pair_style hybrid lj/charmm/coul/charmm/inter es4k4l maxmax 3.5 4.0 - pair_modify mix arithmetic - special_bonds lj 0.0 0.0 1.0 #(turn on "1-4" interactions) - } - - - # A16 is a coarse-grained alpha-helix containing 16 residues (one "atom" each) - - A16 { - - # AtomID MoleculeID AtomType Charge X Y Z - - write('Data Atoms') { - $atom:a1 $mol:... @atom:../L 0.0 -0.4 -0.4 0.0 - $atom:a2 $mol:... @atom:../L 0.0 0.4 -0.4 0.6 - $atom:a3 $mol:... @atom:../H 0.0 0.4 0.4 1.2 - $atom:a4 $mol:... @atom:../H 0.0 -0.4 0.4 1.8 - $atom:a5 $mol:... @atom:../L 0.0 -0.4 -0.4 2.4 - $atom:a6 $mol:... @atom:../L 0.0 0.4 -0.4 3.0 - $atom:a7 $mol:... @atom:../H 0.0 0.4 0.4 3.6 - $atom:a8 $mol:... @atom:../H 0.0 -0.4 0.4 4.2 - $atom:a9 $mol:... @atom:../L 0.0 -0.4 -0.4 4.8 - $atom:a10 $mol:... @atom:../L 0.0 0.4 -0.4 5.4 - $atom:a11 $mol:... @atom:../H 0.0 0.4 0.4 6.0 - $atom:a12 $mol:... @atom:../H 0.0 -0.4 0.4 6.6 - $atom:a13 $mol:... @atom:../L 0.0 -0.4 -0.4 7.2 - $atom:a14 $mol:... @atom:../L 0.0 0.4 -0.4 7.8 - $atom:a15 $mol:... @atom:../H 0.0 0.4 0.4 8.4 - $atom:a16 $mol:... @atom:../H 0.0 -0.4 0.4 9.0 - } - - write('Data Bonds') { - $bond:b1 @bond:../backbone $atom:a1 $atom:a2 - $bond:b2 @bond:../backbone $atom:a2 $atom:a3 - $bond:b3 @bond:../backbone $atom:a3 $atom:a4 - $bond:b4 @bond:../backbone $atom:a4 $atom:a5 - $bond:b5 @bond:../backbone $atom:a5 $atom:a6 - $bond:b6 @bond:../backbone $atom:a6 $atom:a7 - $bond:b7 @bond:../backbone $atom:a7 $atom:a8 - $bond:b8 @bond:../backbone $atom:a8 $atom:a9 - $bond:b9 @bond:../backbone $atom:a9 $atom:a10 - $bond:b10 @bond:../backbone $atom:a10 $atom:a11 - $bond:b11 @bond:../backbone $atom:a11 $atom:a12 - $bond:b12 @bond:../backbone $atom:a12 $atom:a13 - $bond:b13 @bond:../backbone $atom:a13 $atom:a14 - $bond:b14 @bond:../backbone $atom:a14 $atom:a15 - $bond:b15 @bond:../backbone $atom:a15 $atom:a16 - } - - } # A16 - - - # B16 is a coarse-grained beta-strand containing 16 residues (one "atom" each) - - B16 { - - # AtomID MoleculeID AtomType Charge X Y Z - - write('Data Atoms') { - $atom:a1 $mol:... @atom:../L 0.0 -0.3 0.0 0.0 - $atom:a2 $mol:... @atom:../H 0.0 0.3 0.0 0.8 - $atom:a3 $mol:... @atom:../L 0.0 -0.3 0.0 1.6 - $atom:a4 $mol:... @atom:../H 0.0 0.3 0.0 2.4 - $atom:a5 $mol:... @atom:../L 0.0 -0.3 0.0 3.2 - $atom:a6 $mol:... @atom:../H 0.0 0.3 0.0 4.0 - $atom:a7 $mol:... @atom:../L 0.0 -0.3 0.0 4.8 - $atom:a8 $mol:... @atom:../H 0.0 0.3 0.0 5.6 - $atom:a9 $mol:... @atom:../L 0.0 -0.3 0.0 6.4 - $atom:a10 $mol:... @atom:../H 0.0 0.3 0.0 7.2 - $atom:a11 $mol:... @atom:../L 0.0 -0.3 0.0 8.0 - $atom:a12 $mol:... @atom:../H 0.0 0.3 0.0 8.8 - $atom:a13 $mol:... @atom:../L 0.0 -0.3 0.0 9.6 - $atom:a14 $mol:... @atom:../H 0.0 0.3 0.0 10.4 - $atom:a15 $mol:... @atom:../L 0.0 -0.3 0.0 11.2 - $atom:a16 $mol:... @atom:../H 0.0 0.3 0.0 12.0 - } - - write('Data Bonds') { - $bond:b1 @bond:../backbone $atom:a1 $atom:a2 - $bond:b2 @bond:../backbone $atom:a2 $atom:a3 - $bond:b3 @bond:../backbone $atom:a3 $atom:a4 - $bond:b4 @bond:../backbone $atom:a4 $atom:a5 - $bond:b5 @bond:../backbone $atom:a5 $atom:a6 - $bond:b6 @bond:../backbone $atom:a6 $atom:a7 - $bond:b7 @bond:../backbone $atom:a7 $atom:a8 - $bond:b8 @bond:../backbone $atom:a8 $atom:a9 - $bond:b9 @bond:../backbone $atom:a9 $atom:a10 - $bond:b10 @bond:../backbone $atom:a10 $atom:a11 - $bond:b11 @bond:../backbone $atom:a11 $atom:a12 - $bond:b12 @bond:../backbone $atom:a12 $atom:a13 - $bond:b13 @bond:../backbone $atom:a13 $atom:a14 - $bond:b14 @bond:../backbone $atom:a14 $atom:a15 - $bond:b15 @bond:../backbone $atom:a15 $atom:a16 - } - - } # B16 - - T3 { # T3 is a "turn" region consisting of 3 beads - - # AtomID MoleculeID AtomType Charge X Y Z - - write('Data Atoms') { - $atom:a1 $mol:... @atom:../N 0.0 -0.8 0.0 0.0 - $atom:a2 $mol:... @atom:../N 0.0 0.0 0.55 -0.24 - $atom:a3 $mol:... @atom:../N 0.0 0.8 0.0 0.0 - } - - write('Data Bonds') { - $bond:b1 @bond:../backbone $atom:a1 $atom:a2 - $bond:b2 @bond:../backbone $atom:a2 $atom:a3 - } - - } # T3 - - # ----- Now build larger molecules using A16, B16 and T3 ------- - - 4SheetBarrel { - - sheet1 = new B16.rot( 45, 0,0,1).move(-0.793700526,-0.793700526, -6) - sheet2 = new B16.rot( 135, 0,0,1).move( 0.793700526,-0.793700526, -6) - sheet3 = new B16.rot( 225, 0,0,1).move( 0.793700526, 0.793700526, -6) - sheet4 = new B16.rot( 315, 0,0,1).move(-0.793700526, 0.793700526, -6) - - turn1 = new T3.rot(180,1,0,0).rot(0,0,0,1).move(0,-1.3,6.6) - turn2 = new T3.rot( 0,1,0,0).rot(-90,0,0,1).move(0.7,-0.0,-6.9) - turn3 = new T3.rot(180,1,0,0).rot(-180,0,0,1).move(0,1.3,6.6) - - write('Data Bonds') { - $bond:turn1a @bond:../backbone $atom:turn1/a1 $atom:sheet1/a16 - $bond:turn1b @bond:../backbone $atom:turn1/a3 $atom:sheet2/a16 - $bond:turn2a @bond:../backbone $atom:turn2/a1 $atom:sheet3/a1 - $bond:turn2b @bond:../backbone $atom:turn2/a3 $atom:sheet2/a1 - $bond:turn3a @bond:../backbone $atom:turn3/a1 $atom:sheet3/a16 - $bond:turn3b @bond:../backbone $atom:turn3/a3 $atom:sheet4/a16 - } - create_var { $mol } # molecule ID number shared by all atoms in this protein - } - - - 4HelixBundle { - - helix1 = new A16.rot( -45, 0,0,1).move(-1.12691645,-1.12691645, -4.5) - helix2 = new A16.rot( 45, 0,0,1).move( 1.12691645,-1.12691645, -4.5) - helix3 = new A16.rot( 135, 0,0,1).move( 1.12691645, 1.12691645, -4.5) - helix4 = new A16.rot( 225, 0,0,1).move(-1.12691645, 1.12691645, -4.5) - - turn1 = new T3.rot(180,1,0,0).rot(-17,0,0,1).move(-0.2,-0.7,5.4) - turn2 = new T3.rot( 0,1,0,0).rot(-100,0,0,1).move(0.7,-0.15,-4.8) - turn3 = new T3.rot(180,1,0,0).rot(163,0,0,1).move(0.2,0.7,5.4) - - write('Data Bonds') { - $bond:turn1a @bond:../backbone $atom:turn1/a1 $atom:helix1/a16 - $bond:turn1b @bond:../backbone $atom:turn1/a3 $atom:helix2/a16 - $bond:turn2a @bond:../backbone $atom:turn2/a1 $atom:helix3/a1 - $bond:turn2b @bond:../backbone $atom:turn2/a3 $atom:helix2/a1 - $bond:turn3a @bond:../backbone $atom:turn3/a1 $atom:helix3/a16 - $bond:turn3b @bond:../backbone $atom:turn3/a3 $atom:helix4/a16 - } - create_var { $mol } # molecule ID number shared by all atoms in this protein - } - - - - # 2-body (non-bonded) interactions: - # - # Uij(r) = 4*eps_ij * (K*(sig_ij/r)^12 + L*(sig_ij/r)^6) - # - # i j pairstylename eps sig K L - # - write_once("In Settings") { - pair_coeff @atom:H @atom:H lj/charmm/coul/charmm/inter 1.0 1.0 1 -1 - pair_coeff @atom:L @atom:L lj/charmm/coul/charmm/inter 1.0 1.0 1 0 - pair_coeff @atom:N @atom:N lj/charmm/coul/charmm/inter 1.0 1.0 1 0 - } - # Interactions between different atoms use "repulsive wins" mixing rules - - - # bond_coeff bondType bondstylename k r0 - - write_once("In Settings") { - bond_coeff @bond:backbone harmonic 66.6 1.0 - } - - - # angle_coeff angleType anglestylename k theta0 - - write_once("In Settings") { - angle_coeff @angle:backbone harmonic 66.6 105.0 - } - - # We use the same bond-angle forces whenever - # there are 3 consecutively-bonded atoms: - # - # angleType atomtypes1 2 3 bondtypes1 2 - - write_once("Data Angles By Type") { - @angle:backbone @atom:* @atom:* @atom:* @bond:* @bond:* - } - - - - # From the Bellesia et al 2010 paper: - # for helices: U_{dih}(\phi) = 1.2*(cos(3\phi) + cos(\phi+\delta)) - # for turns: U_{dih}(\phi) = 0.2*cos(3\phi) - # - # General formula used for "dihedral_style fourier": - # U_{dih}(\phi) = \Sum_{i=1}^m K_i [ 1.0 + cos(n_i \phi - d_i) ] - # - # Syntax: - # dihedralType dihedralstyle m K_1 n_1 d_1 K2 n_2 d_2 ... - - write_once("In Settings") { - dihedral_coeff @dihedral:delta60_0 fourier 2 2.167862 3 0 2.167862 1 -60.0 - dihedral_coeff @dihedral:delta62_5 fourier 2 2.167862 3 0 2.167862 1 -62.5 - dihedral_coeff @dihedral:delta65_0 fourier 2 2.167862 3 0 2.167862 1 -65.0 - dihedral_coeff @dihedral:turn fourier 1 0.361310 3 0 - # Note: 2.167862=1.2*epsilon and 0.361310=0.2*epsilon. - } - - - # dihedralType atomtypes1 2 3 4 bondtypes1 2 3 - - write_once("Data Dihedrals By Type") { - @dihedral:delta60_0 @atom:H @atom:L @atom:H @atom:L * * * - @dihedral:delta60_0 @atom:H @atom:H @atom:L @atom:L * * * - @dihedral:delta60_0 @atom:H @atom:L @atom:L @atom:H * * * - @dihedral:delta60_0 @atom:L @atom:H @atom:H @atom:L * * * - @dihedral:turn @atom:N @atom:* @atom:* @atom:* * * * - } - # Note: This next rule is not needed: - # @dihedral:turn @atom:* @atom:* @atom:* @atom:N * * * - # (By reflection symmetry, it's equivalent to the rule above.) - # - # Note: The example in ../../membrane+protein/moltemplate_files/ - # demonstrates how to define dihedral angles for this model - # in an alternate way which might be easier to understand. - - - # --- Mass Units --- - # There are 3 atom types (referred to above as ../H, ../L, and ../N) - # Define their masses (in reduced units): - - write_once("Data Masses") { - @atom:H 1.0 - @atom:L 1.0 - @atom:N 1.0 - } - - -} # 1beadProtSci2010 (namespace) - diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1beadProtSci2010/moltemplate_files/README.sh b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1beadProtSci2010/moltemplate_files/README.sh deleted file mode 100755 index 852b9b76f2..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1beadProtSci2010/moltemplate_files/README.sh +++ /dev/null @@ -1,13 +0,0 @@ -# run moltemplate this way - -moltemplate.sh system.lt - -# This will generate various files with names ending in *.in* and *.data -# which are needed by LAMMPS. - -# ------ Other versions: -------- -# -# If you are using the "other_versions/charmm/1beadProtSci2010.lt" file, -# then you must run moltemplate this way: -# -# moltemplate.sh -overlay-dihdedrals system.lt diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1beadProtSci2010/moltemplate_files/other_implementations/README.TXT b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1beadProtSci2010/moltemplate_files/other_implementations/README.TXT deleted file mode 100644 index 82bc8c5c43..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1beadProtSci2010/moltemplate_files/other_implementations/README.TXT +++ /dev/null @@ -1,13 +0,0 @@ -This directory contains other versions of the same molecule -(with the same force-field), implemented in different ways. - -charmm/1beadProtSci2010.lt <-- This applies multiple "charmm" dihedral angle - forces to the same quartet of atoms to create - a Fourier series. (No packages needed.) - - NOTE: You must run moltemplate this way: - - moltemplate.sh -overlay-dihdedrals system.lt - -class2/1beadProtSci2010.lt <-- This uses the "class2" dihedral angles forces - (You must build LAMMPS with the CLASS2 package) diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1beadProtSci2010/moltemplate_files/other_implementations/charmm/1beadProtSci2010.lt b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1beadProtSci2010/moltemplate_files/other_implementations/charmm/1beadProtSci2010.lt deleted file mode 100644 index d57186bee7..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1beadProtSci2010/moltemplate_files/other_implementations/charmm/1beadProtSci2010.lt +++ /dev/null @@ -1,411 +0,0 @@ -# This file defines a family of coarse-grained protein models used in: -# G. Bellesia, AI Jewett, and J-E Shea, Protein Science, Vol19 141-154 (2010) -# -# -# For portability, all definitions in this file are enclosed within -# the "1beadProtSci2010" namespace. To access them, put -# "using namespace 1beadProtSci2010" in your LT file. - -# Strategy: -# -#1) First I'll define some building blocks -# (short helices, sheets and turns of a predetermined length) -# -#2) Then I'll cut and paste them together to build -# a 4-helix bundle or a 4-strand beta-barrel. -# -# Doing it this way is optional. It's simpler (but longer) to simply write -# out the entire sequence of all 73 atoms in a single "Data Atoms" section. -# (IE. Don't try to subdivide it.) It's also simpler to explicitly list the -# 72 bonds, 71 3-body angles and 70 4-body dihedral angle interactions -# manually (instead of inferring them from the atom type). If your protein -# has helices which are not identical, this would probably be easier. -# Use whichever style you prefer. -# -# -# Note that atom types, bond types, angle types, and dihedral types -# are shared between all molecules defined in the "1beadProtSci2010" family. -# (That's why there is a "../" in their path-names. Otherwise atom, bond, -# angle types, etc... are not shared between different molecules.) -# -# Confusing detail: -# Each molecule in LAMMPS can be assigned a unique molecule-ID (an integer). -# These are represented by the "$mol" variable written next to each atom. -# Our protein has multiple subunits (in this case: helices, sheets, turns). -# Because we want the subunits to share the same molecule-ID counter we use -# "$mol:..." instead of "$mol" which tells moltemplate to search for the -# parent molecule's ID. This is optional. If it bothers you, just use "$mol" - - - -1beadProtSci2010 { - - write_once("In Init") { - # -- Default styles for "1beadProtSci2010" -- - units lj - atom_style full - # (Hybrid force fields were not necessary but are used for portability.) - bond_style hybrid harmonic - angle_style hybrid harmonic - dihedral_style hybrid charmm - pair_style hybrid lj/charmm/coul/charmm/inter es4k4l maxmax 3.5 4.0 - - # If charges are needed, (assuming biopolymers), try one of: - #dielectric 80.0 - #pair_style hybrid lj/cut/coul/debye 0.1 4.0 - # or (for short distances, below a couple nm) - #pair_style hybrid lj/charmm/coul/charmm/implicit 3.5 4.0 - - pair_modify mix arithmetic - special_bonds lj 0.0 0.0 1.0 #(turn on "1-4" interactions) - } - - - # ---- Building blocks: A16, B16, Turn3 ---- - - # A16 is a coarse-grained alpha-helix containing 16 residues (one "atom" each) - - A16 { - - # AtomID MoleculeID AtomType Charge X Y Z - - write('Data Atoms') { - $atom:a1 $mol:... @atom:../L 0.0 -0.4 -0.4 0.0 - $atom:a2 $mol:... @atom:../L 0.0 0.4 -0.4 0.6 - $atom:a3 $mol:... @atom:../H 0.0 0.4 0.4 1.2 - $atom:a4 $mol:... @atom:../H 0.0 -0.4 0.4 1.8 - $atom:a5 $mol:... @atom:../L 0.0 -0.4 -0.4 2.4 - $atom:a6 $mol:... @atom:../L 0.0 0.4 -0.4 3.0 - $atom:a7 $mol:... @atom:../H 0.0 0.4 0.4 3.6 - $atom:a8 $mol:... @atom:../H 0.0 -0.4 0.4 4.2 - $atom:a9 $mol:... @atom:../L 0.0 -0.4 -0.4 4.8 - $atom:a10 $mol:... @atom:../L 0.0 0.4 -0.4 5.4 - $atom:a11 $mol:... @atom:../H 0.0 0.4 0.4 6.0 - $atom:a12 $mol:... @atom:../H 0.0 -0.4 0.4 6.6 - $atom:a13 $mol:... @atom:../L 0.0 -0.4 -0.4 7.2 - $atom:a14 $mol:... @atom:../L 0.0 0.4 -0.4 7.8 - $atom:a15 $mol:... @atom:../H 0.0 0.4 0.4 8.4 - $atom:a16 $mol:... @atom:../H 0.0 -0.4 0.4 9.0 - } - - write('Data Bonds') { - $bond:b1 @bond:../backbone $atom:a1 $atom:a2 - $bond:b2 @bond:../backbone $atom:a2 $atom:a3 - $bond:b3 @bond:../backbone $atom:a3 $atom:a4 - $bond:b4 @bond:../backbone $atom:a4 $atom:a5 - $bond:b5 @bond:../backbone $atom:a5 $atom:a6 - $bond:b6 @bond:../backbone $atom:a6 $atom:a7 - $bond:b7 @bond:../backbone $atom:a7 $atom:a8 - $bond:b8 @bond:../backbone $atom:a8 $atom:a9 - $bond:b9 @bond:../backbone $atom:a9 $atom:a10 - $bond:b10 @bond:../backbone $atom:a10 $atom:a11 - $bond:b11 @bond:../backbone $atom:a11 $atom:a12 - $bond:b12 @bond:../backbone $atom:a12 $atom:a13 - $bond:b13 @bond:../backbone $atom:a13 $atom:a14 - $bond:b14 @bond:../backbone $atom:a14 $atom:a15 - $bond:b15 @bond:../backbone $atom:a15 $atom:a16 - } - - } # A16 - - - # B16 is a coarse-grained beta-strand containing 16 residues (one "atom" each) - - B16 { - - # AtomID MoleculeID AtomType Charge X Y Z - - write('Data Atoms') { - $atom:a1 $mol:... @atom:../L 0.0 -0.3 0.0 0.0 - $atom:a2 $mol:... @atom:../H 0.0 0.3 0.0 0.8 - $atom:a3 $mol:... @atom:../L 0.0 -0.3 0.0 1.6 - $atom:a4 $mol:... @atom:../H 0.0 0.3 0.0 2.4 - $atom:a5 $mol:... @atom:../L 0.0 -0.3 0.0 3.2 - $atom:a6 $mol:... @atom:../H 0.0 0.3 0.0 4.0 - $atom:a7 $mol:... @atom:../L 0.0 -0.3 0.0 4.8 - $atom:a8 $mol:... @atom:../H 0.0 0.3 0.0 5.6 - $atom:a9 $mol:... @atom:../L 0.0 -0.3 0.0 6.4 - $atom:a10 $mol:... @atom:../H 0.0 0.3 0.0 7.2 - $atom:a11 $mol:... @atom:../L 0.0 -0.3 0.0 8.0 - $atom:a12 $mol:... @atom:../H 0.0 0.3 0.0 8.8 - $atom:a13 $mol:... @atom:../L 0.0 -0.3 0.0 9.6 - $atom:a14 $mol:... @atom:../H 0.0 0.3 0.0 10.4 - $atom:a15 $mol:... @atom:../L 0.0 -0.3 0.0 11.2 - $atom:a16 $mol:... @atom:../H 0.0 0.3 0.0 12.0 - } - - write('Data Bonds') { - $bond:b1 @bond:../backbone $atom:a1 $atom:a2 - $bond:b2 @bond:../backbone $atom:a2 $atom:a3 - $bond:b3 @bond:../backbone $atom:a3 $atom:a4 - $bond:b4 @bond:../backbone $atom:a4 $atom:a5 - $bond:b5 @bond:../backbone $atom:a5 $atom:a6 - $bond:b6 @bond:../backbone $atom:a6 $atom:a7 - $bond:b7 @bond:../backbone $atom:a7 $atom:a8 - $bond:b8 @bond:../backbone $atom:a8 $atom:a9 - $bond:b9 @bond:../backbone $atom:a9 $atom:a10 - $bond:b10 @bond:../backbone $atom:a10 $atom:a11 - $bond:b11 @bond:../backbone $atom:a11 $atom:a12 - $bond:b12 @bond:../backbone $atom:a12 $atom:a13 - $bond:b13 @bond:../backbone $atom:a13 $atom:a14 - $bond:b14 @bond:../backbone $atom:a14 $atom:a15 - $bond:b15 @bond:../backbone $atom:a15 $atom:a16 - } - - } # B16 - - T3 { # T3 is a "turn" region consisting of 3 beads - - # AtomID MoleculeID AtomType Charge X Y Z - - write('Data Atoms') { - $atom:a1 $mol:... @atom:../N 0.0 -0.8 0.0 0.0 - $atom:a2 $mol:... @atom:../N 0.0 0.0 0.55 -0.24 - $atom:a3 $mol:... @atom:../N 0.0 0.8 0.0 0.0 - } - - write('Data Bonds') { - $bond:b1 @bond:../backbone $atom:a1 $atom:a2 - $bond:b2 @bond:../backbone $atom:a2 $atom:a3 - } - - } # T3 - - # (Note: Again, atom types, bond-types, (dihedral-types, any variable, etc) - # can be shared. The ".." in "@atom:../CA" tells moltemplate that - # atom type CA is defined in the parent's environment. (We are - # sharing the CA atom type between both the H and P residues. - # The same is true of the ".." in "@bond:../sidechain". - # - # - # Note: The "..." in "$mol:..." tells moltemplate that this molecule may - # be a part of a larger molecule, and (if so) to use the larger - # molecule's id number as it's own. - - - - # ----- Now build larger molecules using A16, B16 and T3 ------- - - 4HelixBundle { - - helix1 = new A16.rot( -45, 0,0,1).move(-1.12691645,-1.12691645, 0) - helix2 = new A16.rot( 45, 0,0,1).move( 1.12691645,-1.12691645, 0) - helix3 = new A16.rot( 135, 0,0,1).move( 1.12691645, 1.12691645, 0) - helix4 = new A16.rot( 225, 0,0,1).move(-1.12691645, 1.12691645, 0) - # Note: 1.12691645 ~= 0.5*2^(1/6) + 0.4*sqrt(2) - - turn1 = new T3.rot(180,1,0,0).rot(-17,0,0,1).move(-0.2,-0.7,9.9) - turn2 = new T3.rot( 0,1,0,0).rot(-100,0,0,1).move(0.7,-0.15,-0.3) - turn3 = new T3.rot(180,1,0,0).rot(163,0,0,1).move(0.2,0.7,9.9) - - # Note: In the paper, this is described as the "UA2" conformation - # (I played around with the angles until it looked "okay". This is not - # the minimum energy conformation. Further minimization is necessary.) - - # Now bond the pieces together. - # (Note: angle & dihedral interactions will be generated automatically.) - write('Data Bonds') { - $bond:turn1a @bond:../backbone $atom:turn1/a1 $atom:helix1/a16 - $bond:turn1b @bond:../backbone $atom:turn1/a3 $atom:helix2/a16 - $bond:turn2a @bond:../backbone $atom:turn2/a1 $atom:helix3/a1 - $bond:turn2b @bond:../backbone $atom:turn2/a3 $atom:helix2/a1 - $bond:turn3a @bond:../backbone $atom:turn3/a1 $atom:helix3/a16 - $bond:turn3b @bond:../backbone $atom:turn3/a3 $atom:helix4/a16 - } - create_var { $mol } # <-- create a variable for the parent's Molecule-ID - } - - 4SheetBundle { - - sheet1 = new B16.rot( 45, 0,0,1).move(-0.793700526,-0.793700526, 0) - sheet2 = new B16.rot( 135, 0,0,1).move( 0.793700526,-0.793700526, 0) - sheet3 = new B16.rot( 225, 0,0,1).move( 0.793700526, 0.793700526, 0) - sheet4 = new B16.rot( 315, 0,0,1).move(-0.793700526, 0.793700526, 0) - # Note: 0.793700526 ~= 0.5*2^(1/6) * sqrt(1/2) - - turn1 = new T3.rot(180,1,0,0).rot(0,0,0,1).move(0,-1.3,12.6) - turn2 = new T3.rot( 0,1,0,0).rot(-90,0,0,1).move(0.7,-0.0,-0.9) - turn3 = new T3.rot(180,1,0,0).rot(-180,0,0,1).move(0,1.3,12.6) - - write('Data Bonds') { - $bond:turn1a @bond:../backbone $atom:turn1/a1 $atom:sheet1/a16 - $bond:turn1b @bond:../backbone $atom:turn1/a3 $atom:sheet2/a16 - $bond:turn2a @bond:../backbone $atom:turn2/a1 $atom:sheet3/a1 - $bond:turn2b @bond:../backbone $atom:turn2/a3 $atom:sheet2/a1 - $bond:turn3a @bond:../backbone $atom:turn3/a1 $atom:sheet3/a16 - $bond:turn3b @bond:../backbone $atom:turn3/a3 $atom:sheet4/a16 - } - create_var { $mol } # molecule ID number shared by all atoms in this protein - } - - - # There are 3 atom types (referred to above as ../H, ../L, and ../N) - # Define their masses: - - write_once("Data Masses") { - @atom:H 1.0 - @atom:L 1.0 - @atom:N 1.0 - - } - - - - # -------------------------------------------------------------------- - # -- In this example, all force field parameters are stored in the -- - # -- file named "In Settings". They can also go in sections like -- - # -- "Data Pair Coeffs", "Data Bond Coeffs", "Data Angle Coeffs"... -- - # -------------------------------------------------------------------- - - - - - # 2-body (non-bonded) interactions: - # - # Uij(r) = 4*eps_ij * (K*(sig_ij/r)^12 + L*(sig_ij/r)^6) - # - # i j pairstylename eps sig K L - # - write_once("In Settings") { - pair_coeff @atom:H @atom:H lj/charmm/coul/charmm/inter 1.0 1.0 1 -1 - pair_coeff @atom:L @atom:L lj/charmm/coul/charmm/inter 1.0 1.0 1 0 - pair_coeff @atom:N @atom:N lj/charmm/coul/charmm/inter 1.0 1.0 1 0 - } - # (Interactions between different atom types use "arithmetic" - # and "maxmax" ("repulsion-wins") mixing rules.) - - - # 2-body (bonded) interactions: - # - # Ubond(r) = (k/2)*(r-0)^2 - # - # The corresponding command is: - # - # bond_coeff bondType bondstylename k r0 - # - - write_once("In Settings") { - bond_coeff @bond:backbone harmonic 66.6 1.0 - } - - - - # 3-body interactions in this example are listed by atomType and bondType - # The atomIDs involved are determined automatically. The forumula used is: - # - # Uangle(theta) = (k/2)*(theta-theta0)^2 - # (k in kcal/mol/rad^2, theta0 in degrees) - # - # The corresponding command is: - # - # angle_coeff angleType anglestylename k theta0 - - write_once("In Settings") { - angle_coeff @angle:backbone harmonic 66.6 105.0 - } - - # Generate a "backbone" 3-body interaction whenever 3 atoms are bonded - # together. We do this by to asking moltemplate to generate this - # 3-body interaction whenever 3 consecutively bonded atoms satisfy - # the following type requirement: - # - # angleType atomtypes1 2 3 bondtypes1 2 - - write_once("Data Angles By Type") { - @angle:backbone * * * * * - } - - - - - - # 4-body interactions in this example are listed by atomType and bondType - # The atomIDs involved are determined automatically. The forumula used is: - # - # Udihedral(phi) = K * (1 + cos(n*phi - d)) - # - # The d parameter is in degrees, K is in kcal/mol/rad^2. - # - # The corresponding command is: - # - # dihedral_coeff dihedralType dihedralstylename K n d w - # ("w" is the weight for 1-4 pair interactions, which we set to 0) - - write_once("In Settings") { - dihedral_coeff @dihedral:turn charmm 0.2 3 0 0 - dihedral_coeff @dihedral:term3 charmm 1.2 3 0 0 - - dihedral_coeff @dihedral:delta65_0 charmm 1.2 1 -65 0 - dihedral_coeff @dihedral:delta62_5 charmm 1.2 1 -62 0 - dihedral_coeff @dihedral:delta60_0 charmm 1.2 1 -60 0 - dihedral_coeff @dihedral:delta57_5 charmm 1.2 1 -57 0 - dihedral_coeff @dihedral:delta55_0 charmm 1.2 1 -55 0 - } - - #write_once("In Settings") { - # dihedral_coeff @dihedral:turn charmm 0.2 3 0.0 0 - # dihedral_coeff @dihedral:term3 charmm 1.2 3 0.0 0 - # dihedral_coeff @dihedral:delta65_0 charmm 1.2 1 -65.0 0 - # dihedral_coeff @dihedral:delta62_5 charmm 1.2 1 -62.5 0 - # dihedral_coeff @dihedral:delta60_0 charmm 1.2 1 -60.0 0 - # dihedral_coeff @dihedral:delta57_5 charmm 1.2 1 -57.5 0 - # dihedral_coeff @dihedral:delta55_0 charmm 1.2 1 -55.5 0 - #} - - # Generate 4-body interactions whenever 4 consecutively bonded atoms satisfy - # the following type requirements: - - write_once("Data Dihedrals By Type") { - # The dihedral interaction between backbone atoms in the helix or sheet-like - # regions is proportional to the sum of two terms: cos(phi+delta)+cos(3*phi) - # where delta is a constant used to control the bias between helices/sheets. - # As of 2013-4-07, the "fourier", "table", "class2", and "charmm", - " dihedral_styles can implement this potential. - # However dihedral_style "charmm" can only handle one cosine term at a time. - # So we use two commands to create two dihedral interactions for the same - # set of of four atoms ("cos3" and "delta60_0"). (To allow the - # superposition of multiple dihedral interactions on the same atoms, - # be sure to run moltemplate with the "-overlay-dihdedrals" argument.) - # - # dihedralType atomtypes1 2 3 4 bondtypes1 2 3 - - @dihedral:term3 @atom:H @atom:L @atom:H @atom:L * * * - @dihedral:delta60_0 @atom:H @atom:L @atom:H @atom:L * * * - - @dihedral:term3 @atom:H @atom:L @atom:L @atom:H * * * - @dihedral:delta60_0 @atom:H @atom:L @atom:L @atom:H * * * - - @dihedral:term3 @atom:L @atom:H @atom:H @atom:L * * * - @dihedral:delta60_0 @atom:L @atom:H @atom:H @atom:L * * * - - @dihedral:term3 @atom:H @atom:H @atom:L @atom:L * * * - @dihedral:delta60_0 @atom:H @atom:H @atom:L @atom:L * * * - - # Comment out the next 4 lines: (They are redundant with the lines above) - #@dihedral:term3 @atom:L @atom:L @atom:H @atom:H * * * - #@dihedral:delta60_0 @atom:L @atom:L @atom:H @atom:H * * * - #@dihedral:term3 @atom:L @atom:H @atom:L @atom:H * * * - #@dihedral:delta60_0 @atom:L @atom:H @atom:L @atom:H * * * - # (Redundant: The LLHH pattern is identical to HHLL after order reversal) - # (Redundant: The LHLH pattern is identical to HLHL after order reversal) - - # Right now the dihedral-angle settings are "unfrustrated", meaning that the - # peptide backbone is equally happy to adopt helical or sheet-like secondary - # structure (See Table IV of Bellesia et. al, Prot Sci, 19, 141 (2010)). - # You can change that by changing "delta60_0" to one of the other choices. - - # Any dihedral interactions containing "N" atoms use the @dihedral:turn - # interaction (which is much weaker). - @dihedral:turn @atom:N @atom:* @atom:* @atom:* * * * - @dihedral:turn @atom:N @atom:N @atom:* @atom:* * * * - @dihedral:turn @atom:N @atom:N @atom:N @atom:* * * * - @dihedral:turn @atom:N @atom:N @atom:N @atom:N * * * - # Comment out the next 4 lines: (They are redundant with the lines above) - # @dihedral:turn @atom:N @atom:N @atom:N @atom:N * * * - # @dihedral:turn @atom:* @atom:N @atom:N @atom:N * * * - # @dihedral:turn @atom:* @atom:* @atom:N @atom:N * * * - # @dihedral:turn @atom:* @atom:* @atom:* @atom:N * * * - } - -} # 1beadProtSci2010 (namespace) - diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1beadProtSci2010/moltemplate_files/other_implementations/class2/1beadProtSci2010.lt b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1beadProtSci2010/moltemplate_files/other_implementations/class2/1beadProtSci2010.lt deleted file mode 100644 index a0e305f844..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1beadProtSci2010/moltemplate_files/other_implementations/class2/1beadProtSci2010.lt +++ /dev/null @@ -1,385 +0,0 @@ -# This file defines a family of coarse-grained protein models used in: -# G. Bellesia, AI Jewett, and J-E Shea, Protein Science, Vol19 141-154 (2010) -# -# -# For portability, all definitions in this file are enclosed within -# the "1beadProtSci2010" namespace. To access them, put -# "using namespace 1beadProtSci2010" in your LT file. - -# Strategy: -# -#1) First I'll define some building blocks -# (short helices, sheets and turns of a predetermined length) -# -#2) Then I'll cut and paste them together to build -# a 4-helix bundle or a 4-strand beta-barrel. -# -# Doing it this way is optional. It's simpler (but longer) to simply write -# out the entire sequence of all 73 atoms in a single "Data Atoms" section. -# (IE. Don't try to subdivide it.) It's also simpler to explicitly list the -# 72 bonds, 71 3-body angles and 70 4-body dihedral angle interactions -# manually (instead of inferring them from the atom type). If your protein -# has helices which are not identical, this would probably be easier. -# Use whichever style you prefer. -# -# -# Note that atom types, bond types, angle types, and dihedral types -# are shared between all molecules defined in the "1beadProtSci2010" family. -# (That's why there is a "../" in their path-names. Otherwise atom, bond, -# angle types, etc... are not shared between different molecules.) -# -# Confusing detail: -# Each molecule in LAMMPS can be assigned a unique molecule-ID (an integer). -# These are represented by the "$mol" variable written next to each atom. -# Our protein has multiple subunits (in this case: helices, sheets, turns). -# Because we want the subunits to share the same molecule-ID counter we use -# "$mol:..." instead of "$mol" which tells moltemplate to search for the -# parent molecule's ID. This is optional. If it bothers you, just use "$mol" - - - -1beadProtSci2010 { - - write_once("In Init") { - # -- Default styles for "1beadProtSci2010" -- - units lj - atom_style full - # (Hybrid force fields were not necessary but are used for portability.) - bond_style hybrid harmonic - angle_style hybrid harmonic - dihedral_style hybrid class2 - pair_style hybrid lj/charmm/coul/charmm/inter es4k4l maxmax 3.5 4.0 rsoftcore 1 - - # If charges are needed, (assuming biopolymers), try one of: - #dielectric 80.0 - #pair_style hybrid lj/cut/coul/debye 0.1 4.0 - # or (for short distances, below a couple nm) - #pair_style hybrid lj/charmm/coul/charmm/implicit 3.5 4.0 - - pair_modify mix arithmetic - special_bonds lj 0.0 0.0 1.0 #(turn on "1-4" interactions) - } - - - # ---- Building blocks: A16, B16, Turn3 ---- - - # A16 is a coarse-grained alpha-helix containing 16 residues (one "atom" each) - - A16 { - - # AtomID MoleculeID AtomType Charge X Y Z - - write('Data Atoms') { - $atom:a1 $mol:... @atom:../L 0.0 -0.4 -0.4 0.0 - $atom:a2 $mol:... @atom:../L 0.0 0.4 -0.4 0.6 - $atom:a3 $mol:... @atom:../H 0.0 0.4 0.4 1.2 - $atom:a4 $mol:... @atom:../H 0.0 -0.4 0.4 1.8 - $atom:a5 $mol:... @atom:../L 0.0 -0.4 -0.4 2.4 - $atom:a6 $mol:... @atom:../L 0.0 0.4 -0.4 3.0 - $atom:a7 $mol:... @atom:../H 0.0 0.4 0.4 3.6 - $atom:a8 $mol:... @atom:../H 0.0 -0.4 0.4 4.2 - $atom:a9 $mol:... @atom:../L 0.0 -0.4 -0.4 4.8 - $atom:a10 $mol:... @atom:../L 0.0 0.4 -0.4 5.4 - $atom:a11 $mol:... @atom:../H 0.0 0.4 0.4 6.0 - $atom:a12 $mol:... @atom:../H 0.0 -0.4 0.4 6.6 - $atom:a13 $mol:... @atom:../L 0.0 -0.4 -0.4 7.2 - $atom:a14 $mol:... @atom:../L 0.0 0.4 -0.4 7.8 - $atom:a15 $mol:... @atom:../H 0.0 0.4 0.4 8.4 - $atom:a16 $mol:... @atom:../H 0.0 -0.4 0.4 9.0 - } - - write('Data Bonds') { - $bond:b1 @bond:../backbone $atom:a1 $atom:a2 - $bond:b2 @bond:../backbone $atom:a2 $atom:a3 - $bond:b3 @bond:../backbone $atom:a3 $atom:a4 - $bond:b4 @bond:../backbone $atom:a4 $atom:a5 - $bond:b5 @bond:../backbone $atom:a5 $atom:a6 - $bond:b6 @bond:../backbone $atom:a6 $atom:a7 - $bond:b7 @bond:../backbone $atom:a7 $atom:a8 - $bond:b8 @bond:../backbone $atom:a8 $atom:a9 - $bond:b9 @bond:../backbone $atom:a9 $atom:a10 - $bond:b10 @bond:../backbone $atom:a10 $atom:a11 - $bond:b11 @bond:../backbone $atom:a11 $atom:a12 - $bond:b12 @bond:../backbone $atom:a12 $atom:a13 - $bond:b13 @bond:../backbone $atom:a13 $atom:a14 - $bond:b14 @bond:../backbone $atom:a14 $atom:a15 - $bond:b15 @bond:../backbone $atom:a15 $atom:a16 - } - - } # A16 - - - # B16 is a coarse-grained beta-strand containing 16 residues (one "atom" each) - - B16 { - - # AtomID MoleculeID AtomType Charge X Y Z - - write('Data Atoms') { - $atom:a1 $mol:... @atom:../L 0.0 -0.3 0.0 0.0 - $atom:a2 $mol:... @atom:../H 0.0 0.3 0.0 0.8 - $atom:a3 $mol:... @atom:../L 0.0 -0.3 0.0 1.6 - $atom:a4 $mol:... @atom:../H 0.0 0.3 0.0 2.4 - $atom:a5 $mol:... @atom:../L 0.0 -0.3 0.0 3.2 - $atom:a6 $mol:... @atom:../H 0.0 0.3 0.0 4.0 - $atom:a7 $mol:... @atom:../L 0.0 -0.3 0.0 4.8 - $atom:a8 $mol:... @atom:../H 0.0 0.3 0.0 5.6 - $atom:a9 $mol:... @atom:../L 0.0 -0.3 0.0 6.4 - $atom:a10 $mol:... @atom:../H 0.0 0.3 0.0 7.2 - $atom:a11 $mol:... @atom:../L 0.0 -0.3 0.0 8.0 - $atom:a12 $mol:... @atom:../H 0.0 0.3 0.0 8.8 - $atom:a13 $mol:... @atom:../L 0.0 -0.3 0.0 9.6 - $atom:a14 $mol:... @atom:../H 0.0 0.3 0.0 10.4 - $atom:a15 $mol:... @atom:../L 0.0 -0.3 0.0 11.2 - $atom:a16 $mol:... @atom:../H 0.0 0.3 0.0 12.0 - } - - write('Data Bonds') { - $bond:b1 @bond:../backbone $atom:a1 $atom:a2 - $bond:b2 @bond:../backbone $atom:a2 $atom:a3 - $bond:b3 @bond:../backbone $atom:a3 $atom:a4 - $bond:b4 @bond:../backbone $atom:a4 $atom:a5 - $bond:b5 @bond:../backbone $atom:a5 $atom:a6 - $bond:b6 @bond:../backbone $atom:a6 $atom:a7 - $bond:b7 @bond:../backbone $atom:a7 $atom:a8 - $bond:b8 @bond:../backbone $atom:a8 $atom:a9 - $bond:b9 @bond:../backbone $atom:a9 $atom:a10 - $bond:b10 @bond:../backbone $atom:a10 $atom:a11 - $bond:b11 @bond:../backbone $atom:a11 $atom:a12 - $bond:b12 @bond:../backbone $atom:a12 $atom:a13 - $bond:b13 @bond:../backbone $atom:a13 $atom:a14 - $bond:b14 @bond:../backbone $atom:a14 $atom:a15 - $bond:b15 @bond:../backbone $atom:a15 $atom:a16 - } - - } # B16 - - T3 { # T3 is a "turn" region consisting of 3 beads - - # AtomID MoleculeID AtomType Charge X Y Z - - write('Data Atoms') { - $atom:a1 $mol:... @atom:../N 0.0 -0.8 0.0 0.0 - $atom:a2 $mol:... @atom:../N 0.0 0.0 0.55 -0.24 - $atom:a3 $mol:... @atom:../N 0.0 0.8 0.0 0.0 - } - - write('Data Bonds') { - $bond:b1 @bond:../backbone $atom:a1 $atom:a2 - $bond:b2 @bond:../backbone $atom:a2 $atom:a3 - } - - } # T3 - - # (Note: Again, atom types, bond-types, (dihedral-types, any variable, etc) - # can be shared. The ".." in "@atom:../CA" tells moltemplate that - # atom type CA is defined in the parent's environment. (We are - # sharing the CA atom type between both the H and P residues. - # The same is true of the ".." in "@bond:../sidechain". - # - # - # Note: The "..." in "$mol:..." tells moltemplate that this molecule may - # be a part of a larger molecule, and (if so) to use the larger - # molecule's id number as it's own. - - - - # ----- Now build larger molecules using A16, B16 and T3 ------- - - 4HelixBundle { - - helix1 = new A16.rot( -45, 0,0,1).move(-1.12691645,-1.12691645, 0) - helix2 = new A16.rot( 45, 0,0,1).move( 1.12691645,-1.12691645, 0) - helix3 = new A16.rot( 135, 0,0,1).move( 1.12691645, 1.12691645, 0) - helix4 = new A16.rot( 225, 0,0,1).move(-1.12691645, 1.12691645, 0) - # Note: 1.12691645 ~= 0.5*2^(1/6) + 0.4*sqrt(2) - - turn1 = new T3.rot(180,1,0,0).rot(-17,0,0,1).move(-0.2,-0.7,9.9) - turn2 = new T3.rot( 0,1,0,0).rot(-100,0,0,1).move(0.7,-0.15,-0.3) - turn3 = new T3.rot(180,1,0,0).rot(163,0,0,1).move(0.2,0.7,9.9) - - # Note: In the paper, this is described as the "UA2" conformation - # (I played around with the angles until it looked "okay". This is not - # the minimum energy conformation. Further minimization is necessary.) - - # Now bond the pieces together. - # (Note: angle & dihedral interactions will be generated automatically.) - write('Data Bonds') { - $bond:turn1a @bond:../backbone $atom:turn1/a1 $atom:helix1/a16 - $bond:turn1b @bond:../backbone $atom:turn1/a3 $atom:helix2/a16 - $bond:turn2a @bond:../backbone $atom:turn2/a1 $atom:helix3/a1 - $bond:turn2b @bond:../backbone $atom:turn2/a3 $atom:helix2/a1 - $bond:turn3a @bond:../backbone $atom:turn3/a1 $atom:helix3/a16 - $bond:turn3b @bond:../backbone $atom:turn3/a3 $atom:helix4/a16 - } - create_var { $mol } # <-- create a variable for the parent's Molecule-ID - } - - 4SheetBundle { - - sheet1 = new B16.rot( 45, 0,0,1).move(-0.793700526,-0.793700526, 0) - sheet2 = new B16.rot( 135, 0,0,1).move( 0.793700526,-0.793700526, 0) - sheet3 = new B16.rot( 225, 0,0,1).move( 0.793700526, 0.793700526, 0) - sheet4 = new B16.rot( 315, 0,0,1).move(-0.793700526, 0.793700526, 0) - # Note: 0.793700526 ~= 0.5*2^(1/6) * sqrt(1/2) - - turn1 = new T3.rot(180,1,0,0).rot(0,0,0,1).move(0,-1.3,12.6) - turn2 = new T3.rot( 0,1,0,0).rot(-90,0,0,1).move(0.7,-0.0,-0.9) - turn3 = new T3.rot(180,1,0,0).rot(-180,0,0,1).move(0,1.3,12.6) - - write('Data Bonds') { - $bond:turn1a @bond:../backbone $atom:turn1/a1 $atom:sheet1/a16 - $bond:turn1b @bond:../backbone $atom:turn1/a3 $atom:sheet2/a16 - $bond:turn2a @bond:../backbone $atom:turn2/a1 $atom:sheet3/a1 - $bond:turn2b @bond:../backbone $atom:turn2/a3 $atom:sheet2/a1 - $bond:turn3a @bond:../backbone $atom:turn3/a1 $atom:sheet3/a16 - $bond:turn3b @bond:../backbone $atom:turn3/a3 $atom:sheet4/a16 - } - create_var { $mol } # molecule ID number shared by all atoms in this protein - } - - - # There are 3 atom types (referred to above as ../H, ../L, and ../N) - # Define their masses: - - write_once("Data Masses") { - @atom:H 1.0 - @atom:L 1.0 - @atom:N 1.0 - - } - - - - # -------------------------------------------------------------------- - # -- In this example, all force field parameters are stored in the -- - # -- file named "In Settings". They can also go in sections like -- - # -- "Data Pair Coeffs", "Data Bond Coeffs", "Data Angle Coeffs"... -- - # -------------------------------------------------------------------- - - - - - # 2-body (non-bonded) interactions: - # - # Uij(r) = 4*eps_ij * (K*(sig_ij/r)^12 + L*(sig_ij/r)^6) - # - # i j pairstylename eps sig K L - # - write_once("In Settings") { - pair_coeff @atom:H @atom:H lj/charmm/coul/charmm/inter 1.0 1.0 1 -1 0 0 0 0 - pair_coeff @atom:L @atom:L lj/charmm/coul/charmm/inter 1.0 1.0 1 0 0 0 0 0 - pair_coeff @atom:N @atom:N lj/charmm/coul/charmm/inter 1.0 1.0 1 0 0 0 0 0 - } - # (Interactions between different atom types use "arithmetic" - # and "maxmax" ("repulsion-wins") mixing rules.) - - - # 2-body (bonded) interactions: - # - # Ubond(r) = (k/2)*(r-0)^2 - # - # The corresponding command is: - # - # bond_coeff bondType bondstylename k r0 - # - - write_once("In Settings") { - bond_coeff @bond:backbone harmonic 66.6 1.0 - } - - - - # 3-body interactions in this example are listed by atomType and bondType - # The atomIDs involved are determined automatically. The forumula used is: - # - # Uangle(theta) = (k/2)*(theta-theta0)^2 - # (k in kcal/mol/rad^2, theta0 in degrees) - # - # The corresponding command is: - # - # angle_coeff angleType anglestylename k theta0 - - write_once("In Settings") { - angle_coeff @angle:backbone harmonic 66.6 105.0 - } - - # Generate a "backbone" 3-body interaction whenever 3 atoms are bonded - # together. We do this by to asking moltemplate to generate this - # 3-body interaction whenever 3 consecutively bonded atoms satisfy - # the following type requirement: - # - # angleType atomtypes1 2 3 bondtypes1 2 - - write_once("Data Angles By Type") { - @angle:backbone * * * * * - } - - - - - - # 4-body interactions in this example are listed by atomType and bondType - # The atomIDs involved are determined automatically. The forumula used is: - # - # Udihedral(phi) = K * (1 + cos(n*phi - d)) - # - # The d parameter is in degrees, K is in kcal/mol/rad^2. - # - # The corresponding command is: - # - - # From the Bellesia et al paper: Udihedral(x) = 1.2*(cos(x+delta) + cos(3x)) (delta=60) - # (scratchwork: 1.2*cos(x+60) = -1.2*cos(x+60-180) = -1.2*cos(x-120)) - # and 1.2*cos(3x) = -1.2*cos(3x-180) - # and 0.2*cos(x) = -0.2*cos(x - 180) - # This way, the energies match exactly with the implementation using charmm dihedrals.) - # - # dihedralType dihedralstylename K1 phi1 K2 phi2 K3 phi3 - - write_once("In Settings") { - dihedral_coeff @dihedral:delta60_0 class2 1.2 120.0 0 0 1.2 180.0 - dihedral_coeff @dihedral:turn class2 0 0 0 0 0.2 180.0 - - # All of the cross-terms (for the class2 force-field) are zero (see docs): - dihedral_coeff @dihedral:delta60_0 class2 mbt 0 0 0 0 - dihedral_coeff @dihedral:delta60_0 class2 ebt 0 0 0 0 0 0 0 0 - dihedral_coeff @dihedral:delta60_0 class2 at 0 0 0 0 0 0 0 0 - dihedral_coeff @dihedral:delta60_0 class2 aat 0 0 0 - dihedral_coeff @dihedral:delta60_0 class2 bb13 0 0 0 - dihedral_coeff @dihedral:turn class2 mbt 0 0 0 0 - dihedral_coeff @dihedral:turn class2 ebt 0 0 0 0 0 0 0 0 - dihedral_coeff @dihedral:turn class2 at 0 0 0 0 0 0 0 0 - dihedral_coeff @dihedral:turn class2 aat 0 0 0 - dihedral_coeff @dihedral:turn class2 bb13 0 0 0 - } - - # Generate 4-body interactions whenever 4 consecutively bonded atoms satisfy - # the following type requirements: - - write_once("Data Dihedrals By Type") { - # dihedralType atomtypes1 2 3 4 bondtypes1 2 3 - - @dihedral:delta60_0 @atom:H @atom:L @atom:H @atom:L * * * - @dihedral:delta60_0 @atom:H @atom:H @atom:L @atom:L * * * - @dihedral:delta60_0 @atom:H @atom:L @atom:L @atom:H * * * - @dihedral:delta60_0 @atom:L @atom:H @atom:H @atom:L * * * - - @dihedral:turn @atom:N @atom:* @atom:* @atom:* * * * - @dihedral:turn @atom:N @atom:N @atom:* @atom:* * * * - @dihedral:turn @atom:N @atom:N @atom:N @atom:* * * * - @dihedral:turn @atom:N @atom:N @atom:N @atom:N * * * - - #### Comment out the next 6 lines: (They are redundant with the lines above) - ## @dihedral:delta60_0 @atom:L @atom:H @atom:L @atom:H * * * - ## @dihedral:delta60_0 @atom:L @atom:L @atom:H @atom:H * * * - ## @dihedral:turn @atom:N @atom:N @atom:N @atom:N * * * - ## @dihedral:turn @atom:* @atom:N @atom:N @atom:N * * * - ## @dihedral:turn @atom:* @atom:* @atom:N @atom:N * * * - ## @dihedral:turn @atom:* @atom:* @atom:* @atom:N * * * - ################################################################### - } - - -} # 1beadProtSci2010 (namespace) - diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1beadProtSci2010/moltemplate_files/system.lt b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1beadProtSci2010/moltemplate_files/system.lt deleted file mode 100644 index 6300c4ce3f..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1beadProtSci2010/moltemplate_files/system.lt +++ /dev/null @@ -1,12 +0,0 @@ -import "1beadProtSci2010.lt" - -using namespace 1beadProtSci2010 - -prot = new 4HelixBundle - -write_once("Data Boundary") { - 0 100 xlo xhi - 0 100 ylo yhi - 0 100 zlo zhi -} - diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1beadProtSci2010/run.in.min b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1beadProtSci2010/run.in.min deleted file mode 100644 index 8eb3a03cbb..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1beadProtSci2010/run.in.min +++ /dev/null @@ -1,19 +0,0 @@ -# -- Init section -- - -include system.in.init - -# -- Atom definition section -- - -read_data system.data - -# -- Settings Section -- - -include system.in.settings - -# -- Run section -- - -dump 1 all custom 50 traj_min.lammpstrj id mol type x y z ix iy iz - -minimize 1.0e-5 1.0e-7 500 2000 - -write_data system_after_min.data diff --git a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1beadProtSci2010/run.in.nvt b/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1beadProtSci2010/run.in.nvt deleted file mode 100644 index a0f02dc738..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/protein_folding_examples/1beadProtSci2010/run.in.nvt +++ /dev/null @@ -1,44 +0,0 @@ -# -- Init Section -- - -include system.in.init - -# -- Atom Definition Section -- - -# I you want to be careful, you can minimize the system first. -# (Try using "run.in.min" and uncomment the line below) -# read_data system_after_min.data - -read_data system.data - -# -- Settings Section -- - -include system.in.settings - -# -- Run Section -- - - -timestep 0.008 -dump 1 all custom 500 traj_nvt.lammpstrj id mol type x y z ix iy iz - -# To use Langevin dynamics in LAMMPS you need both "fix langevin" and "fix nve". -# (See http://lammps.sandia.gov/doc/fix_langevin.html for details.) - -fix fxlan all langevin 0.4 0.4 1.0 48279 -fix fxnve all nve - -# Notes: -# The temperature is in reduced units and is set to 0.4. -# The inverse-damping-rate "damp" (which has units of time) is set to 1.0. -# (See http://lammps.sandia.gov/doc/fix_langevin.html) - - -thermo_style custom step temp pe etotal press vol epair ebond eangle edihed -thermo_modify norm no #(report total energy not energy / num_atoms) -thermo 500 #(time interval for printing out "thermo" data) - -restart 10000000 restart_nvt - -run 1000000 - -write_data system_after_nvt.data - diff --git a/tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/README.TXT b/tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/README.TXT deleted file mode 100644 index 305d00d636..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/README.TXT +++ /dev/null @@ -1,114 +0,0 @@ - This example shows how to build a multicomponent spherical vesicle. - The lipid bilayer is composed of two different lipids (DPPC and DLPC). - The vesicle also contains trans-membrane protein inclusions. - - The coordinates for the vesicle are constructed by PACKMOL (see below). - - The DPPC lipid model is described here: - G. Brannigan, P.F. Philips, and F.L.H. Brown, - Physical Review E, Vol 72, 011915 (2005) - (The DLPC model is a truncated version of DPPC. Modifications discussed below.) - The protein model is described here: - G. Bellesia, AI Jewett, and J-E Shea, - Protein Science, Vol19 141-154 (2010) - ---- PREREQUISITES: --- - -1) This example requires PACKMOL. You can download PACKMOL here: - - http://www.ime.unicamp.br/~martinez/packmol/ - - (Moltemplate does not come with an easy way to generate spherically-symmetric - structures, so I used the PACKMOL program to move the molecules into position.) - -2) This example requires the "dihedral_style fourier", which is currently -in the USER-MISC package. Build LAMMPS with this package enabled using - make yes-user-misc -before compiling LAMMPS. -(See http://lammps.sandia.gov/doc/Section_start.html#start_3 for details.) - -3) This example may require additional features to be added to LAMMPS. -If LAMMPS complains about an "Invalid pair_style", then - a) download the "additional_lammps_code" from - http://moltemplate.org (upper-left corner menu) - b) unpack it - c) copy the .cpp and .h files to the src folding of your lammps installation. - d) (re)compile LAMMPS. - ------- Details ------- - -This example contains a coarse-grained model of a 4-helix bundle protein -inserted into a lipid bilayer (made from a mixture of DPPC and DLPC). - - -- Protein Model: -- - -The coarse-grained protein is described in: - G. Bellesia, AI Jewett, and J-E Shea, Protein Science, Vol19 141-154 (2010) -Here we use the "AUF2" model described in that paper. -(The hydrophobic beads face outwards.) - - -- Memebrane Model: -- - -The DPPC lipid bilayer described in: - G. Brannigan, P.F. Philips, and F.L.H. Brown, - Physical Review E, Vol 72, 011915 (2005) -and: - M.C. Watson, E.S. Penev, P.M. Welch, and F.L.H. Brown - J. Chem. Phys. 135, 244701 (2011) - -As in Watson(JCP 2011), rigid bond-length constraints -have been replaced by harmonic bonds. - -A truncated version of this lipid (named "DLPC") has also been added. -The bending stiffness of each lipid has been increased to compensate -for the additional disorder resulting from mixing two different types -of lipids together. (Otherwise pores appear.) -Unlike the original "DPPC" molecule model, the new "DPPC" and "DLPC" models -have not been carefully parameterized to reproduce the correct behavior in -a lipid bilayer mixture. - - -- Interactions between the proteins and lipids -- - -This is discussed in the "system.lt" file. - ---- Building the files necessary to run a simulation in LAMMPS --- - -step 1) Run PACKMOL - - Type these commands into the shell. - (Each command could take several hours.) - -cd packmol_files - packmol < step1_proteins.inp # This step determines the protein's location - packmol < step2_innerlayer.inp # this step builds the inner monolayer - packmol < step3_outerlayer.inp # this step builds the outer monolayer -cd .. - -step 2) Run MOLTEMPLATE - Type these commands into the shell. - (This could take up to 10 minutes.) - -cd moltemplate_files - moltemplate.sh system.lt -xyz ../system.xyz - mv -f system.in* system.data ../ - cp -f table_int.dat ../ -cd .. - ---- Running LAMMPS --- - -step3) Run LAMMPS: - Type these commands into the shell. - (This could take days.) - -lmp_linux -i run.in.min # Minimize the system (important, and very slow) - -lmp_linux -i run.in.nvt # Run a simulation at constant volume - -If you have compiled the MPI version of lammps, you can run lammps in parallel: - -mpirun -np 4 lmp_linux -i run.in.min - or -mpirun -np 4 lmp_linux -i run.in.nvt - -(Assuming you have 4 cores, for example.) - diff --git a/tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/README_WARNING.TXT b/tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/README_WARNING.TXT deleted file mode 100644 index f11c438ad4..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/README_WARNING.TXT +++ /dev/null @@ -1,20 +0,0 @@ -WARNING: - - This is not a realistic simulation of proteins in a lipid membrane. This -example was only intented to be a technical demonstration to show how to -combine totally different kinds of coarse-grained molecules (with different -kinds of force-fields) together in the same simulation in LAMMPS. Tuning the -force-field parameters to get realistic results was not the goal. I did -not take the extra time to do this. If you have suggestions for changes, -please email me (jewett.aij at gmail dot com). - - In addition, I have noticed that newer versions of PACKMOL do not -always succeed at generating a spherical vesicle in a reasonable amount of time. -(You may have to play with the .inp files in the packmol_files directory - to get PACKMOL to produce any files at all. - -(NOTE: This example also demonstrantes how to use an external program - ("packmol") to generate the coordinates for the atoms in the system. - PLEASE USE "packmol", NOT "ppackmol". -the parallel version of "packmol". - This is because "ppackmol" is more likely to get caught in infinite loops.) - diff --git a/tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/README_run.sh b/tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/README_run.sh deleted file mode 100755 index ab62f6fb59..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/README_run.sh +++ /dev/null @@ -1,24 +0,0 @@ -# --- Running LAMMPS --- -# -- Prerequisites: -- -# The "run.in.nvt" file is a LAMMPS input script containing -# references to the input scripts and data files -# you hopefully have created earlier with MOLTEMPLATE and PACKMOL: -# system.in.init, system.in.settings, system.in.coords, system.data, -# and table_int.dat -# If not, carry out the instructions in "README_setup.sh". -# -# -- Instructions: -- -# If "lmp_mpi" is the name of the command you use to invoke lammps, -# then you would run lammps on these files this way: - -lmp_mpi -i run.in.min # Minimize the system (important, and very slow) - -lmp_mpi -i run.in.nvt # Run a simulation at constant volume - - - -# If you have compiled the MPI version of lammps, you can run lammps in parallel -#mpirun -np 4 lmp_mpi -i run.in.min -#or -#mpirun -np 4 lmp_mpi -i run.in.nvt -# (assuming you have 4 processors available) diff --git a/tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/README_setup.sh b/tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/README_setup.sh deleted file mode 100755 index f695f6d0ef..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/README_setup.sh +++ /dev/null @@ -1,65 +0,0 @@ -# Use these commands to generate the LAMMPS input script and data file -# (and other auxilliary files): - -# First, generate the coordinates (the "system.xyz" file). -# (This can be a very slow process.) - - - -cd packmol_files - - # You must run each packmol commend one after the other. - # NOTE: If PACKMOL gets stuck in an endless loop, then edit the corresponding - # "inp" file. This should not happen. You can also usually interrupt - # packmol after 30 minutes, and the solution at that point (an .xyz file) - # should be good enough for use. - packmol < step1_proteins.inp # This step determines the protein's location - # It takes ~20 minutes (on an intel i7) - packmol < step2_innerlayer.inp # this step builds the inner monolayer - # It takes ~90 minutes - packmol < step3_outerlayer.inp # this step builds the outer monolayer - # It takes ~4 hours - - - # NOTE: PLEASE USE "packmol", NOT "ppackmol". ("ppackmol" is the parallel - # version of packmol using OpemMP. This example has NOT been tested - # with "ppackmol". Our impression was that the "ppackmol" version - # is more likely to get stuck in an infinite loop. -Andrew 2015-8) - - - # Step3 creates a file named "step3_outerlayer.xyz" containing the coordinates - # in all the atoms of all the molecules. Later we will run moltemplate.sh - # using the "-xyz ../system.xyz" command line argument. That will instruct - # moltemplate to look for a file named "system.xyz" in the parent directory. - # So I rename the "step3_outerlayer.xyz" file to "system.xyz", and move it - # to this directory so that later moltemplate.sh can find it. - - mv -f step3_outerlayer.xyz ../system.xyz -cd .. - - - -# Create LAMMPS input files this way: -cd moltemplate_files - - # run moltemplate - - moltemplate.sh -xyz ../system.xyz system.lt - - # This will generate various files with names ending in *.in* and *.data. - # These files are the input files directly read by LAMMPS. Move them to - # the parent directory (or wherever you plan to run the simulation). - - mv -f system.in* system.data ../ - - # The "table_int.dat" file contains tabular data for the lipid INT-INT atom - # 1/r^2 interaction. We need it too. (This slows down the simulation by x2, - # so I might look for a way to get rid of it later.) - cp -f table_int.dat ../ - - # Optional: - # The "./output_ttree/" directory is full of temporary files generated by - # moltemplate. They can be useful for debugging, but are usually thrown away. - rm -rf output_ttree/ - -cd ../ diff --git a/tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/README_visualize.txt b/tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/README_visualize.txt deleted file mode 100644 index 019afc1444..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/README_visualize.txt +++ /dev/null @@ -1,87 +0,0 @@ - - ------- To view a lammps trajectory in VMD -------- - - -1) Build a PSF file for use in viewing with VMD. - -This step works with VMD 1.9 and topotools 1.2. -(Older versions, like VMD 1.8.6, don't support this.) - - -a) Start VMD -b) Menu Extensions->Tk Console -c) Enter: - -(I assume that the the DATA file is called "system.data") - - topo readlammpsdata system.data full - animate write psf system.psf - -2) - -Later, to Load a trajectory in VMD: - - Start VMD - Select menu: File->New Molecule - -Browse to select the PSF file you created above, and load it. - (Don't close the window yet.) - -Browse to select the trajectory file. - If necessary, for "file type" select: "LAMMPS Trajectory" - Load it. - - ---- A note on trajectory format: ----- -If the trajectory is a DUMP file, then make sure the it contains the -information you need for pbctools (see below. I've been using this -command in my LAMMPS scripts to create the trajectories: - - dump 1 all custom 5000 DUMP_FILE.lammpstrj id mol type x y z ix iy iz - -It's a good idea to use an atom_style which supports molecule-ID numbers -so that you can assign a molecule-ID number to each atom. (I think this -is needed to wrap atom coordinates without breaking molecules in half.) - -Of course, you don't have to save your trajectories in DUMP format, -(other formats like DCD work fine) I just mention dump files -because these are the files I'm familiar with. - -3) ----- Wrap the coordinates to the unit cell - (without cutting the molecules in half) - -a) Start VMD -b) Load the trajectory in VMD (see above) -c) Menu Extensions->Tk Console -d) Try entering these commands: - - pbc wrap -compound res -all - pbc box - - ----- Optional ---- - Sometimes the solvent or membrane obscures the view of the solute. - It can help to shift the location of the periodic boundary box - To shift the box in the y direction (for example) do this: - - pbc wrap -compound res -all -shiftcenterrel {0.0 0.15 0.0} - pbc box -shiftcenterrel {0.0 0.15 0.0} - - Distances are measured in units of box-length fractions, not Angstroms. - - Alternately if you have a solute whose atoms are all of type 1, - then you can also try this to center the box around it: - - pbc wrap -sel type=1 -all -centersel type=2 -center com - -4) - You should check if your periodic boundary conditions are too small. - To do that: - select Graphics->Representations menu option - click on the "Periodic" tab, and - click on the "+x", "-x", "+y", "-y", "+z", "-z" checkboxes. - -5) Optional: If you like, change the atom types in the PSF file so - that VMD recognizes the atom types, use something like: - -sed -e 's/ 1 1 / C C /g' < system.psf > temp1.psf -sed -e 's/ 2 2 / H H /g' < temp1.psf > temp2.psf -sed -e 's/ 3 3 / P P /g' < temp2.psf > system.psf - -(If you do this, it might effect step 2 above.) diff --git a/tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/images/vesicle_membrane+protein_L.jpg b/tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/images/vesicle_membrane+protein_L.jpg deleted file mode 100644 index c3ff5995601bc8b6ca882ad14d82454d896f642d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 284201 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

M*&FGb6!dVIzjDS%?H0+pY63YVk$0HQOB5 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 diff --git a/tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/moltemplate_files/1beadProtSci2010.lt b/tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/moltemplate_files/1beadProtSci2010.lt deleted file mode 100644 index 2e510ebd9e..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/moltemplate_files/1beadProtSci2010.lt +++ /dev/null @@ -1,233 +0,0 @@ -# This file defines a 4-helix bundle coarse-grained protein model (AUF2) used in -# G. Bellesia, AI Jewett, and J-E Shea, -# Protein Science, Vol19 141-154 (2010) -# -# Strategy: -# -#1) First I'll define some building blocks (A16, B16, T3) -# which are helices, sheets and turns of a predetermined length) -# -#2) Then I'll copy and paste them together to build -# a 4-helix bundle (or a 4-strand beta-barrel). -# This approach is optional. If your protein has helices which are not -# identical, you should probably just include all 4 helices in a single -# "Data Atoms" section and don't try to subdivide the protein into pieces.) - - - -1beadProtSci2010 { # <-- enclose definitions in a namespace for portability - - # A16 is a coarse-grained alpha-helix containing 16 residues (one "atom" each) - - A16 { - - # AtomID MoleculeID AtomType Charge X Y Z - - write('Data Atoms') { - $atom:a1 $mol:... @atom:../sL 0.0 -2.4 -2.4 0.0 - $atom:a2 $mol:... @atom:../sL 0.0 2.4 -2.4 3.6 - $atom:a3 $mol:... @atom:../sH 0.0 2.4 2.4 7.2 - $atom:a4 $mol:... @atom:../sH 0.0 -2.4 2.4 10.8 - $atom:a5 $mol:... @atom:../sL 0.0 -2.4 -2.4 14.4 - $atom:a6 $mol:... @atom:../sL 0.0 2.4 -2.4 18.0 - $atom:a7 $mol:... @atom:../sH 0.0 2.4 2.4 21.6 - $atom:a8 $mol:... @atom:../sH 0.0 -2.4 2.4 25.2 - $atom:a9 $mol:... @atom:../sL 0.0 -2.4 -2.4 28.8 - $atom:a10 $mol:... @atom:../sL 0.0 2.4 -2.4 32.4 - $atom:a11 $mol:... @atom:../sH 0.0 2.4 2.4 36.0 - $atom:a12 $mol:... @atom:../sH 0.0 -2.4 2.4 39.6 - $atom:a13 $mol:... @atom:../sL 0.0 -2.4 -2.4 43.2 - $atom:a14 $mol:... @atom:../sL 0.0 2.4 -2.4 46.8 - $atom:a15 $mol:... @atom:../sH 0.0 2.4 2.4 50.4 - $atom:a16 $mol:... @atom:../sH 0.0 -2.4 2.4 54.0 - } - - write('Data Bonds') { - $bond:b1 @bond:../backbone $atom:a1 $atom:a2 - $bond:b2 @bond:../backbone $atom:a2 $atom:a3 - $bond:b3 @bond:../backbone $atom:a3 $atom:a4 - $bond:b4 @bond:../backbone $atom:a4 $atom:a5 - $bond:b5 @bond:../backbone $atom:a5 $atom:a6 - $bond:b6 @bond:../backbone $atom:a6 $atom:a7 - $bond:b7 @bond:../backbone $atom:a7 $atom:a8 - $bond:b8 @bond:../backbone $atom:a8 $atom:a9 - $bond:b9 @bond:../backbone $atom:a9 $atom:a10 - $bond:b10 @bond:../backbone $atom:a10 $atom:a11 - $bond:b11 @bond:../backbone $atom:a11 $atom:a12 - $bond:b12 @bond:../backbone $atom:a12 $atom:a13 - $bond:b13 @bond:../backbone $atom:a13 $atom:a14 - $bond:b14 @bond:../backbone $atom:a14 $atom:a15 - $bond:b15 @bond:../backbone $atom:a15 $atom:a16 - } - - } # A16 - - - T3 { # T3 is a "turn" region consisting of 3 beads - - # AtomID MoleculeID AtomType Charge X Y Z - - write('Data Atoms') { - $atom:a1 $mol:... @atom:../tN 0.0 -4.8 0.0 0.0 - $atom:a2 $mol:... @atom:../tN 0.0 0.0 3.3 -1.44 - $atom:a3 $mol:... @atom:../tN 0.0 4.8 0.0 0.0 - } - - write('Data Bonds') { - $bond:b1 @bond:../backbone $atom:a1 $atom:a2 - $bond:b2 @bond:../backbone $atom:a2 $atom:a3 - } - - } # T3 - - - # ----- Now build a larger molecule using A16 and T3 ------- - - # Create a 4-Helix bundle. - # In this version, the hydrophobic beads are poing outward. - # I oriented them this way because I want to place this protein in a membrane. - # (There is another file in this directory containing alternate version - # of this same molecule with the hydrophobic beads pointing inward.) - - 4HelixInsideOut { - helix1 = new A16.rot(-225, 0,0,1).move(-5.70,-5.70,-32.4) - helix2 = new A16.rot(-135, 0,0,1).move( 5.70,-5.70,-28.8) - helix3 = new A16.rot( -45, 0,0,1).move( 5.70, 5.70,-25.2) - helix4 = new A16.rot( 45, 0,0,1).move(-5.70, 5.70,-21.6) - - turn1 = new T3.rot(180,1,0,0).rot(-20,0,1,0).rot( 10,0,0,1).move(0.78,-4.2, 27.9) - turn2 = new T3.rot(-10,1,0,0).rot( 20,0,1,0).rot(-70,0,0,1).move(4.55, 2.4,-33.0) - turn3 = new T3.rot(180,1,0,0).rot(-20,0,1,0).rot(190,0,0,1).move(-0.78,4.2, 34.2) - - write('Data Bonds') { - $bond:turn1a @bond:../backbone $atom:turn1/a1 $atom:helix1/a16 - $bond:turn1b @bond:../backbone $atom:turn1/a3 $atom:helix2/a16 - $bond:turn2a @bond:../backbone $atom:turn2/a1 $atom:helix3/a1 - $bond:turn2b @bond:../backbone $atom:turn2/a3 $atom:helix2/a1 - $bond:turn3a @bond:../backbone $atom:turn3/a1 $atom:helix3/a16 - $bond:turn3b @bond:../backbone $atom:turn3/a3 $atom:helix4/a16 - } - create_var { $mol } # molecule ID number shared by all atoms in this protein - - } # 4HelixInsideOut - - - # -------- Minor coordinates adjustment: ----------- - - # Those coordinates in the commands above are a little too large. - # To make it easier to type them in, I was using sigma=6.0 Angstroms. - # Instead, here I'll try using sigma=4.8 Angstroms. 4.8/6 = 0.8) - - 4HelixInsideOut.scale(0.8) - - # Note: "scale()" only effects the initial coordinates of - # the molecule, not the force field parameters. - # (If you plan to minimize the molecule, you don't need to - # be so careful about the initial coordinates. In that case, - # you don't have worry about "scale()". Feel free to remove.) - - - - # -------------- Force-Field Parameters ------------ - - # Units and force-field styles for this protein model - # (These can be overridden later.) - - write_once("In Init") { - units real - atom_style full - bond_style hybrid harmonic - angle_style hybrid harmonic - dihedral_style hybrid fourier - pair_style hybrid lj/charmm/coul/charmm/inter es4k4l maxmax 21.0 24.0 - pair_modify mix arithmetic - special_bonds lj 0.0 0.0 1.0 #(turn on "1-4" interactions) - } - - # --- Distance Units --- - # In this version of the model, sigma (the bond-length - # and particle diameter) is rounded to 4.8 Angstroms. - # - # --- Energy & Temperature Units --- - # In this protein model, "epsilon" represents the free energy - # bonus for bringing two hydrophobic amino acids together. - # Here I choose to set epsilon to 1.806551818181818 kCal/mole. - # This value was chosen so that a temperature of 300 Kelvin lies at - # 0.33 epsilon, which is the unfolding temperature of the marginally stable - # "ASF1" protein model from the Bellesia et al 2010 paper. - # This choice insures that both the "ASF1" model from that paper, - # as well as the much more stable "AUF2" protein we use here (which - # unfolds at 0.42*eps) should definitely remain stable at 300 degrees Kelvin, - # in the bulk at least. (However it's not clear that these energy - # parameters will work well for a protein in membrane. Perhaps I'll - # run some tests and fine tune these parameters for this scenario.) - - - # 2-body (non-bonded) interactions: - # - # Uij(r) = 4*eps_ij * (K*(sig_ij/r)^12 + L*(sig_ij/r)^6) - # - # i j pairstylename eps sig K L - # - write_once("In Settings") { - pair_coeff @atom:sH @atom:sH lj/charmm/coul/charmm/inter 1.8065518 4.8 1 -1 - pair_coeff @atom:sL @atom:sL lj/charmm/coul/charmm/inter 1.8065518 4.8 1 0 - pair_coeff @atom:tN @atom:tN lj/charmm/coul/charmm/inter 1.8065518 4.8 1 0 - } - - # The exact value of the bond_coeff does not matter too much as long as - # it is "stiff enough". Here I use a softer bond spring than the one - # used in the paper so that I can increase the time step. - # I also use a relatively soft spring to constrain the bond angles. - - # bond_coeff bondType bondstylename k r0 - - write_once("In Settings") { - bond_coeff @bond:1beadProtSci2010/backbone harmonic 10.0 4.8 - } - - - # angleType atomtypes1 2 3 bondtypes1 2 - - write_once("Data Angles By Type") { - @angle:backbone @atom:* @atom:* @atom:* @bond:* @bond:* - } - - # angle_coeff angleType anglestylename k theta0 - write_once("In Settings") { - angle_coeff @angle:backbone harmonic 100.0 105.0 - } - - - # dihedralType atomtypes1 2 3 4 bondtypes1 2 3 - - write_once("Data Dihedrals By Type") { - # For a chain of sH and sL atoms, use the @dihedral:delta65_0 - # parameters. (This corresponds to the "AUF2" model from the - # Bellesia et. al 2010 paper.) - - @dihedral:delta65_0 @atom:s* @atom:s* @atom:s* @atom:s* * * * - - # If "tN" (turn) atoms are present, use the @dihedral:turn parameters - - @dihedral:turn @atom:tN @atom:* @atom:* @atom:* * * * - } - - write_once("In Settings") { - dihedral_coeff @dihedral:delta60_0 fourier 2 2.167862 3 0 2.167862 1 -60.0 - dihedral_coeff @dihedral:delta65_0 fourier 2 2.167862 3 0 2.167862 1 -65.0 - dihedral_coeff @dihedral:turn fourier 1 0.361310 3 0 - # Note: 2.167862=1.2*epsilon and 0.361310=0.2*epsilon. - } - - - # --- Mass Units --- - # Typical amino acids weigh approximately 110.0 grams/mole. (Rounding down): - write_once("Data Masses") { - @atom:1beadProtSci2010/sH 100.0 - @atom:1beadProtSci2010/sL 100.0 - @atom:1beadProtSci2010/tN 100.0 - } - -} # 1beadProtSci2010 (namespace) - diff --git a/tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/moltemplate_files/1beadProtSci2010_variations.lt b/tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/moltemplate_files/1beadProtSci2010_variations.lt deleted file mode 100644 index 38b1b48f88..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/moltemplate_files/1beadProtSci2010_variations.lt +++ /dev/null @@ -1,225 +0,0 @@ -### THIS FILE IS OPTIONAL AND IS NOT NECESSARY. IN THIS FILE, I DEFINED SOME ## -### ADDITIONAL PROTEIN TYPES FROM THE PAPER THAT I DID NOT USE IN THIS EXAMPLE## -# -# This file defines a family of coarse-grained protein models used in: -# G. Bellesia, AI Jewett, and J-E Shea, -# Protein Science, Vol19 141-154 (2010) -# -# Strategy: -# -#1) First I'll define some building blocks (A16, B16, T3) -# which are helices, sheets and turns of a predetermined length) - -import "1beadProtSci2010.lt" - -# We defined A16 and T3 earlier in "1beadPRotSci2010.lt" Will define B16 below -# -#2) Then I'll copy and paste them together to build -# a 4-helix bundle or a 4-strand beta-barrel. - - -1beadProtSci2010 { #<-- Add new molecules to existing namespace defined earlier - # This way we don't have to start from scratch. We can - # use all the atom types and angle settings defined earlier - - # B16 is a coarse-grained beta-strand containing 16 residues (one "atom" each) - - B16 { - - # AtomID MoleculeID AtomType Charge X Y Z - - write('Data Atoms') { - $atom:a1 $mol:... @atom:../sL 0.0 -1.8 0.0 0.0 - $atom:a2 $mol:... @atom:../sH 0.0 1.8 0.0 4.8 - $atom:a3 $mol:... @atom:../sL 0.0 -1.8 0.0 9.6 - $atom:a4 $mol:... @atom:../sH 0.0 1.8 0.0 14.4 - $atom:a5 $mol:... @atom:../sL 0.0 -1.8 0.0 19.2 - $atom:a6 $mol:... @atom:../sH 0.0 1.8 0.0 24.0 - $atom:a7 $mol:... @atom:../sL 0.0 -1.8 0.0 28.8 - $atom:a8 $mol:... @atom:../sH 0.0 1.8 0.0 33.6 - $atom:a9 $mol:... @atom:../sL 0.0 -1.8 0.0 38.4 - $atom:a10 $mol:... @atom:../sH 0.0 1.8 0.0 43.2 - $atom:a11 $mol:... @atom:../sL 0.0 -1.8 0.0 48.0 - $atom:a12 $mol:... @atom:../sH 0.0 1.8 0.0 52.8 - $atom:a13 $mol:... @atom:../sL 0.0 -1.8 0.0 57.6 - $atom:a14 $mol:... @atom:../sH 0.0 1.8 0.0 62.4 - $atom:a15 $mol:... @atom:../sL 0.0 -1.8 0.0 67.2 - $atom:a16 $mol:... @atom:../sH 0.0 1.8 0.0 72.0 - } - - write('Data Bonds') { - $bond:b1 @bond:../backbone $atom:a1 $atom:a2 - $bond:b2 @bond:../backbone $atom:a2 $atom:a3 - $bond:b3 @bond:../backbone $atom:a3 $atom:a4 - $bond:b4 @bond:../backbone $atom:a4 $atom:a5 - $bond:b5 @bond:../backbone $atom:a5 $atom:a6 - $bond:b6 @bond:../backbone $atom:a6 $atom:a7 - $bond:b7 @bond:../backbone $atom:a7 $atom:a8 - $bond:b8 @bond:../backbone $atom:a8 $atom:a9 - $bond:b9 @bond:../backbone $atom:a9 $atom:a10 - $bond:b10 @bond:../backbone $atom:a10 $atom:a11 - $bond:b11 @bond:../backbone $atom:a11 $atom:a12 - $bond:b12 @bond:../backbone $atom:a12 $atom:a13 - $bond:b13 @bond:../backbone $atom:a13 $atom:a14 - $bond:b14 @bond:../backbone $atom:a14 $atom:a15 - $bond:b15 @bond:../backbone $atom:a15 $atom:a16 - } - - } # B16 - - # ----- Now build larger molecules using B16 and T3 ------- - - - 4SheetBarrel { - sheet1 = new B16.rot( 45, 0,0,1).move(-4.762203156,-4.762203156, -36.0) - sheet2 = new B16.rot( 135, 0,0,1).move( 4.762203156,-4.762203156, -36.0) - sheet3 = new B16.rot( 225, 0,0,1).move( 4.762203156, 4.762203156, -36.0) - sheet4 = new B16.rot( 315, 0,0,1).move(-4.762203156, 4.762203156, -36.0) - - turn1 = new T3.rot(180,1,0,0).rot( 0, 0,0,1).move( 0, -7.8, 39.6) - turn2 = new T3.rot( 0,1,0,0).rot(-90,0,0,1).move(4.2, 0.0,-41.4) - turn3 = new T3.rot(180,1,0,0).rot(-180,0,0,1).move( 0, 7.8, 39.6) - - write('Data Bonds') { - $bond:turn1a @bond:../backbone $atom:turn1/a1 $atom:sheet1/a16 - $bond:turn1b @bond:../backbone $atom:turn1/a3 $atom:sheet2/a16 - $bond:turn2a @bond:../backbone $atom:turn2/a1 $atom:sheet3/a1 - $bond:turn2b @bond:../backbone $atom:turn2/a3 $atom:sheet2/a1 - $bond:turn3a @bond:../backbone $atom:turn3/a1 $atom:sheet3/a16 - $bond:turn3b @bond:../backbone $atom:turn3/a3 $atom:sheet4/a16 - } - create_var { $mol } # molecule ID number shared by all atoms in this protein - } - - - # Below I define several alternate conformations of the"4HelixBundleInsideOut" - # molecule I defined earlier in "1beadProtSci2010.lt". Same molecule however. - - 4HelixBundle { - helix1 = new A16.rot( -45, 0,0,1).move(-5.70,-5.70,-32.4) - helix2 = new A16.rot( 45, 0,0,1).move( 5.70,-5.70,-28.8) - helix3 = new A16.rot( 135, 0,0,1).move( 5.70, 5.70,-25.2) - helix4 = new A16.rot( 225, 0,0,1).move(-5.70, 5.70,-21.6) - - write('Data Bonds') { - $bond:turn1a @bond:../backbone $atom:turn1/a1 $atom:helix1/a16 - $bond:turn1b @bond:../backbone $atom:turn1/a3 $atom:helix2/a16 - $bond:turn2a @bond:../backbone $atom:turn2/a1 $atom:helix3/a1 - $bond:turn2b @bond:../backbone $atom:turn2/a3 $atom:helix2/a1 - $bond:turn3a @bond:../backbone $atom:turn3/a1 $atom:helix3/a16 - $bond:turn3b @bond:../backbone $atom:turn3/a3 $atom:helix4/a16 - } - - turn1 = new T3.rot(150,1,0,0).rot(-23,0,1,0).rot( 8,0,0,1).move(-3.6,-4.8,28.2) - turn2 = new T3.rot(-5,1,0,0).rot( 21,0,1,0).rot(-100,0,0,1).move(4.2,-0.66,-30.9) - turn3 = new T3.rot(150,1,0,0).rot(-23,0,1,0).rot(188,0,0,1).move(3.6,4.8,35.4) - - create_var { $mol } # molecule ID number shared by all atoms in this protein - - } # 4HelixBundle - - - - - # --- alternate conformations (same molecule) ---- - - # In the following version, the helices are oriented in a similar way, - # but they are separated a little further away from eachother. - - 4HelixBundleLoose { - - helix1 = new A16.rot( -45, 0,0,1).move(-6.7347723,-6.7347723, -27.0) - helix2 = new A16.rot( 45, 0,0,1).move( 6.7347723,-6.7347723, -27.0) - helix3 = new A16.rot( 135, 0,0,1).move( 6.7347723, 6.7347723, -27.0) - helix4 = new A16.rot( 225, 0,0,1).move(-6.7347723, 6.7347723, -27.0) - - turn1 = new T3.rot(180,1,0,0).rot(-17,0,0,1).move(-1.2,-4.2,32.4) - turn2 = new T3.rot( 0,1,0,0).rot(-100,0,0,1).move(4.2,-0.9,-28.8) - turn3 = new T3.rot(180,1,0,0).rot(163,0,0,1).move(1.2,4.2,32.4) - - write('Data Bonds') { - $bond:turn1a @bond:../backbone $atom:turn1/a1 $atom:helix1/a16 - $bond:turn1b @bond:../backbone $atom:turn1/a3 $atom:helix2/a16 - $bond:turn2a @bond:../backbone $atom:turn2/a1 $atom:helix3/a1 - $bond:turn2b @bond:../backbone $atom:turn2/a3 $atom:helix2/a1 - $bond:turn3a @bond:../backbone $atom:turn3/a1 $atom:helix3/a16 - $bond:turn3b @bond:../backbone $atom:turn3/a3 $atom:helix4/a16 - } - create_var { $mol } # molecule ID number shared by all atoms in this protein - } - - - # In following version, the helices are oriented in a similar way, - # but they are separated a little further away from eachother. - - 4HelixInsideOutLoose { - helix1 = new A16.rot(-225, 0,0,1).move(-6.7347723,-6.7347723, -27.0) - helix2 = new A16.rot(-135, 0,0,1).move( 6.7347723,-6.7347723, -27.0) - helix3 = new A16.rot( -45, 0,0,1).move( 6.7347723, 6.7347723, -27.0) - helix4 = new A16.rot( 45, 0,0,1).move(-6.7347723, 6.7347723, -27.0) - - turn1 = new T3.rot(180,1,0,0).rot( 10,0,0,1).move( 0.78,-4.2,28.8) - turn2 = new T3.rot( 70,1,0,0).rot(-70,0,0,1).move( 10.8,2.4,-28.2) - turn3 = new T3.rot(180,1,0,0).rot(190,0,0,1).move(-0.78,4.2,28.8) - - write('Data Bonds') { - $bond:turn1a @bond:../backbone $atom:turn1/a1 $atom:helix1/a16 - $bond:turn1b @bond:../backbone $atom:turn1/a3 $atom:helix2/a16 - $bond:turn2a @bond:../backbone $atom:turn2/a1 $atom:helix3/a1 - $bond:turn2b @bond:../backbone $atom:turn2/a3 $atom:helix2/a1 - $bond:turn3a @bond:../backbone $atom:turn3/a1 $atom:helix3/a16 - $bond:turn3b @bond:../backbone $atom:turn3/a3 $atom:helix4/a16 - } - create_var { $mol } # molecule ID number shared by all atoms in this protein - - } # 4HelixInsideOutLoose - - - - - # In the following version, the 4 helices are arranged next to each other, - # side-by-side, in a planar conformation (instead of a compact bundle). - - 4HelixPlanar { - helix1 = new A16.rot(-00, 0,0,1).move(0, 0, -27.0) - helix2 = new A16.rot( 00, 0,0,1).move(14.4, 0, -27.0) - helix3 = new A16.rot(-00, 0,0,1).move(28.8, 0, -27.0) - helix4 = new A16.rot( 00, 0,0,1).move(43.2, 0, -27.0) - - turn1 = new T3.rot(180,1,0,0).rot( 0,0,0,1).move( 4.8, 0, 31.8) - turn2 = new T3.rot( 0,1,0,0).rot(180,0,0,1).move(19.2, 0,-31.8) - turn3 = new T3.rot(180,1,0,0).rot( 0,0,0,1).move(34.6, 0, 31.8) - - write('Data Bonds') { - $bond:turn1a @bond:../backbone $atom:turn1/a1 $atom:helix1/a16 - $bond:turn1b @bond:../backbone $atom:turn1/a3 $atom:helix2/a16 - $bond:turn2a @bond:../backbone $atom:turn2/a1 $atom:helix3/a1 - $bond:turn2b @bond:../backbone $atom:turn2/a3 $atom:helix2/a1 - $bond:turn3a @bond:../backbone $atom:turn3/a1 $atom:helix3/a16 - $bond:turn3b @bond:../backbone $atom:turn3/a3 $atom:helix4/a16 - } - create_var { $mol } # molecule ID number shared by all atoms in this protein - - } # 4HelixPlanar - - - # -------- Minor coordinates adjustment: ----------- - # Those coordinates in the commands above are a little too large. - # To make it easier to type them in, I was using sigma=6.0 Angstroms. - # Instead, here I'll try using sigma=4.8 Angstroms. 4.8/6.0 = 0.8) - - 4SheetBarrel.scale(0.8) - 4HelixBundle.scale(0.8) - 4HelixBundleLoose.scale(0.8) - 4HelixInsideOutLoose.scale(0.8) - 4HelixPlanar.scale(0.8) - - # Note: "scale()" only effects the initial coordinates of - # the molecule, not the force field parameters. - # (If you plan to minimize the molecule, you don't need to - # be so careful about the initial coordinates. In that case, - # you don't have worry about "scale()". Feel free to remove.) - - -} # 1beadProtSci2010 (namespace) - diff --git a/tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/moltemplate_files/CGLipidBr2005.lt b/tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/moltemplate_files/CGLipidBr2005.lt deleted file mode 100644 index 24be50aced..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/moltemplate_files/CGLipidBr2005.lt +++ /dev/null @@ -1,196 +0,0 @@ -# Note: -# -# This example may require additional features to be added to LAMMPS. If -# LAMMPS complains about an "Invalid pair_style", then download copy the -# "additional_lammps_code" from moltemplate.org, unpack it into your LAMMPS -# "src" directory and recompile LAMMPS. -# -# -------- Description -------- -# -# This example contains an implementation of the DPPC lipid bilayer described in -# G. Brannigan, P.F. Philips, and F.L.H. Brown, -# Physical Review E, Vol 72, 011915 (2005) -# and: -# M.C. Watson, E.S. Penev, P.M. Welch, and F.L.H. Brown -# J. Chem. Phys. 135, 244701 (2011) -# -# As in Watson(JCP 2011), rigid bond-length constraints have been replaced -# by harmonic bonds. -# -# A truncated version of this lipid (named "DLPC") has also been added. -# Unlike the original "DPPC" molecule model, "DLPC" has not been carefully -# parameterized to reproduce the correct behavior in a lipid bilayer mixture. -# -# Units: -# -# The "epsilon" parameter in their model is approximately 2.75 kJ/mole -# ( = 0.657265774378585 kCal/mole, using 1kCal=4.184kJ) -# The "sigma" parameter corresponds to 7.5 angstroms. - - -CGLipidBr2005 { - - - write_once("In Init") { - # -- Default styles for "CGLipidBr2005" -- - units real - atom_style full - # (Hybrid force field styles were used for portability.) - bond_style hybrid harmonic - - #angle_style hybrid cosine/delta # <- used in the original article - angle_style hybrid harmonic # <- prevents unphysical acute angle turns - # Explanation: - # angle_style cosine/delta: U(theta) = k*(1-cos(theta-theta0)) - # angle_style harmonic: U(theta) = k*(theta-theta0)^2 - - dihedral_style none - improper_style none - - pair_style hybrid table linear 1130 & - lj/charmm/coul/charmm/inter es4k4l 14.5 15 - - pair_modify mix arithmetic - special_bonds lj 0.0 0.0 1.0 # turn off pairs if "less than 3 bonds" - } - - - DPPC { - write("Data Atoms") { - $atom:h $mol:. @atom:head 0.0 0.00 0.00 33.75 # DPPC head atom - $atom:i $mol:. @atom:../int 0.0 -1.00 0.00 26.25 - $atom:t1 $mol:. @atom:../tail 0.0 1.00 0.00 18.75 - $atom:t2 $mol:. @atom:../tail 0.0 -1.00 0.00 11.25 - $atom:t3 $mol:. @atom:../tail 0.0 1.00 0.00 3.75 - } - write("Data Bonds") { - $bond:b1 @bond:../backbone $atom:h $atom:i - $bond:b2 @bond:../backbone $atom:i $atom:t1 - $bond:b3 @bond:../backbone $atom:t1 $atom:t2 - $bond:b4 @bond:../backbone $atom:t2 $atom:t3 - } - write("Data Angles") { - $angle:a1 @angle:../backbone $atom:h $atom:i $atom:t1 - $angle:a2 @angle:../backbone $atom:i $atom:t1 $atom:t2 - $angle:a3 @angle:../backbone $atom:t1 $atom:t2 $atom:t3 - } - - # Define properties of the local (lipid-specific) atom:head type atom: - write_once("Data Masses") { - @atom:head 200.0 - } - write_once("In Settings") { - pair_coeff @atom:head @atom:head lj/charmm/coul/charmm/inter 0.1643 7.5 0.4 0 - pair_coeff @atom:../int @atom:head lj/charmm/coul/charmm/inter 0.1643 7.5 0.4 0 - pair_coeff @atom:../tail @atom:head lj/charmm/coul/charmm/inter 0.1643 7.5 0.4 0 - } - - } #DPPC - - - DLPC { - write("Data Atoms") { - $atom:h $mol:. @atom:head 0.0 0.00 0.00 30.00 # DLPC head atom - $atom:i $mol:. @atom:../int 0.0 -1.00 0.00 22.50 - $atom:t1 $mol:. @atom:../tail 0.0 1.00 0.00 15.00 - $atom:t2 $mol:. @atom:../tail 0.0 -1.00 0.00 7.50 - } - write("Data Bonds") { - $bond:b1 @bond:../backbone $atom:h $atom:i - $bond:b2 @bond:../backbone $atom:i $atom:t1 - $bond:b3 @bond:../backbone $atom:t1 $atom:t2 - } - write("Data Angles") { - $angle:a1 @angle:../backbone $atom:h $atom:i $atom:t1 - $angle:a2 @angle:../backbone $atom:i $atom:t1 $atom:t2 - } - # Define properties of the local (lipid-specific) atom:head type atom: - write_once("Data Masses") { - @atom:head 200.0 - } - write_once("In Settings") { - pair_coeff @atom:head @atom:head lj/charmm/coul/charmm/inter 0.1643 7.5 0.4 0 - pair_coeff @atom:../int @atom:head lj/charmm/coul/charmm/inter 0.1643 7.5 0.4 0 - pair_coeff @atom:../tail @atom:head lj/charmm/coul/charmm/inter 0.1643 7.5 0.4 0 - } - } #DLPC - - - # Particles and properties shared by all lipid types: - - write_once("Data Masses") { - @atom:int 200.0 - @atom:tail 200.0 - } - - write_once("In Settings") { - # -- Default settings/parameters for "CGLipidBr2005" -- - # (Hybrid bond & angle styles were used for portability.) - - # As in Watson(JCP 2011), rigid bond-length constraints - # have been replaced by harmonic bonds. - # The k_theta parameter should lie in between 5*epsilon and 10*epsilon. - bond_coeff @bond:backbone harmonic 116.847 7.5 #<--2*5000*eps/sig^2 - } - - write_once("In Settings") { - # cosine/delta: U(theta) = k*(1-cos(theta-theta0)) - #angle_coeff @angle:backbone cosine/delta 4.60086042 180 #<-- 7*eps - # harmonic: U(theta) = k*(theta-theta0)^2 not (k/2)*(theta-theta0)^2 - angle_coeff @angle:backbone harmonic 9.85898661 180 #<-->30*eps - } - # I use a stiffer bond-angle than the original Brannigan & Brown 2005 paper - # to attempt to compensate for the fact that here we are using a lipid - # mixture of DPPC and DLPC. (The mixture of lipids introduces a great deal - # of disorder into the bilayer which would not be present in a DPPC bilayer. - # This causes pores to form. Increasing the angle stiffness prevents this.) - - write_once("In Settings") { - - # The interaction of "atom:int" with other "atom:int" atoms is given by - # epsilon*(0.4*(sigma/r)^12 - 3.0*(sigma/r)^2), shifted and cutoff at - # r=3*sigma. This was implemented using pair_style table. - # Unfortunately, mixing lj/charmm and "table" pair styles in the same - # simulation is very inneficient. - - pair_coeff @atom:int @atom:int table table_int.dat INT - - # The interaction of tail beads with eachother is given by the formula below - # and with other atoms ...using Lorenz-Berthelot and "repulsive wins" rules: - # epsilon*(0.4*(sigma/r)^12 - 1.0*(sigma/r)^6), - pair_coeff @atom:tail @atom:tail lj/charmm/coul/charmm/inter 0.1643 7.5 0.4 -1 - pair_coeff @atom:int @atom:tail lj/charmm/coul/charmm/inter 0.1643 7.5 0.4 -1 - - # The interaction between head beads from different types of lipids - # is (currently) repulsive: - pair_coeff @atom:DPPC/head @atom:DLPC/head lj/charmm/coul/charmm/inter 0.1643 7.5 0.4 0 - - } # write_once("In Settings") - - - # Note: I divided epsilon by 4 to get "0.1643" because we are using the - # "es4k4l" coeffstyle, corresponding to U(r)=eps(4*K*(s/r)^12 + 4*L*(s/r)^6) - # (The "es4k4l" coeffstyle is the default.) Using this convention makes it - # easier to mix this coarse-grained lipid model with other molecular models. - - - -} # CGLipidBr2005 - - - - - - - - -# Note: This example has not been optimized for speed. -# -# Unfortunately, using both lj/charmm and "table" pair styles in the same -# simulation seems to be very inneficient. (The simulation is twice as slow -# as using only the "lj/charmm" pair styles for every pairwise interaction, -# ...and about 25% slower than using "table" for every pairwise interaction. -# However the lennard-jones pair styles support mixing, so we use them to -# make it easier to run these molecules with other molecules which don't use -# pair_table. I felt that portability was worth the extra 25% slow down.) - diff --git a/tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/moltemplate_files/README.sh b/tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/moltemplate_files/README.sh deleted file mode 100755 index b0de637379..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/moltemplate_files/README.sh +++ /dev/null @@ -1,22 +0,0 @@ -# This example shows how to build a multicomponent spherical vesicle. -# The lipid bilayer is composed of two different lipids (DPPC and DLPC), -# The vesicle contains 120 trans-membrane protein inclusions. -# -# ---------------- Prerequisites: ------------------ -# You must run packmol to generate the coordinates beforehand. -# Afterwards, move and rename the final coordinate file to "../system.xyz" -# To do this, check the README.sh file in the ../packmol_files directory. -# (or follow these instructions below) -# -# cd ../packmol_files -# packmol < step1_proteins.inp -# packmol < step2_innerlayer.inp -# packmol < step3_outerlayer.inp -# cp step3_outerlayer.xyz ../system.xyz -# -# These steps could take a few hours. -# -# --- After you have done that, you can run moltemplate using this command: --- - -moltemplate.sh system.lt -xyz ../system.xyz - diff --git a/tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/moltemplate_files/calc_table/calc_CGLipidTableINTvsINT.py b/tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/moltemplate_files/calc_table/calc_CGLipidTableINTvsINT.py deleted file mode 100755 index 0d09e4d02e..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/moltemplate_files/calc_table/calc_CGLipidTableINTvsINT.py +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env python - -# Calculate a table of pairwise energies and forces between "INT" atoms -# in the lipid membrane model described in -# Brannigan et al, Phys Rev E, 72, 011915 (2005) -# The energy of this interaction U(r) = eps*(0.4*(sigma/r)^12 - 3.0*(sigma/r)^2) -# However it is truncated at rc2 = 22.5 (shifted upwards to maintain continuity) - -def U(r, eps, sigma): - return eps* (0.4*pow((sigma/r),12) - 3.0*sigma*sigma/(r*r)) -def F(r, eps, sigma): - return eps*(12*0.4*pow((sigma/r),13)/sigma - 2*3.0*sigma*sigma/(r*r*r)) - -epsilon = 2.75/4.184 # kCal/mole -sigma = 7.5 -Rmin = 0.02 -Rmax = 22.6 -rcut = 22.5 -N = 1130 - -for i in range(0,N): - r = Rmin + i*(Rmax-Rmin)/(N-1) - U_r = U(r, epsilon, sigma) - U(rcut, epsilon, sigma) - F_r = F(r, epsilon, sigma) - if r > rcut: - U_r = 0.0 - F_r = 0.0 - print(str(i+1)+' '+str(r)+' '+str(U_r)+' '+str(F_r)) - diff --git a/tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/moltemplate_files/calc_table/version_charmm_cutoff/calc_table.py b/tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/moltemplate_files/calc_table/version_charmm_cutoff/calc_table.py deleted file mode 100755 index 32147e444a..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/moltemplate_files/calc_table/version_charmm_cutoff/calc_table.py +++ /dev/null @@ -1,70 +0,0 @@ -#!/usr/bin/env python - -# Calculate a table of pairwise energies and forces between "INT" atoms -# in the lipid membrane model described in -# Brannigan et al, Phys Rev E, 72, 011915 (2005) -# The energy of this interaction U(r) = eps*(0.4*(sigma/r)^12 - 3.0*(sigma/r)^2) -# I realized later this is not what we want because although energy is conserved -# all enrgies are shifted with respect to energies used in the Brannigan paper -# (by 0.27 kCal/mole) and the later Watson JCP 2011 paper (by 0.224 kCal/mole). -# (So don't use this.) - -# Calculate and print a - -def S(r, rc1, rc2, derivative=False): - """ - Calculate the switching function S(r) which decays continuously - between 1 and 0 in the range from rc1 to rc2 (rc2>rc1): - S(r) = (rc2^2 - r^2)^2 * (rc2^2 + 2*r^2 - 3*rc1^2) / (rc2^2-rc1^2)^3 - I'm using the same smoothing/switching cutoff function used by the CHARMM - force-fields. (I'm even using the same code to implement it, taken - from lammps charmm/coul/charmm pair style, rewritten in python.) - - """ - assert(rc2>rc1) - rsq = r*r - rc1sq = rc1*rc1 - rc2sq = rc2*rc2 - denom_lj_inv = (1.0 / ((rc2sq-rc1sq)* - (rc2sq-rc1sq)* - (rc2sq-rc1sq))) - if rsq > rc2sq: - return 0.0 - elif rsq < rc1sq: - if derivative: - return 0.0 - else: - return 1.0 - else: - rc2sq_minus_rsq = (rc2sq - rsq) - rc2sq_minus_rsq_sq = rc2sq_minus_rsq * rc2sq_minus_rsq - if derivative: - return (12.0 * rsq * rc2sq_minus_rsq * (rsq-rc1sq) * denom_lj_inv) - else: - return (rc2sq_minus_rsq_sq * - (rc2sq + 2.0*rsq - 3.0*rc1sq) * denom_lj_inv) - - -def U(r, eps, sigma): - return eps* (0.4*pow((sigma/r),12) - 3.0*sigma*sigma/(r*r)) - -def F(r, eps, sigma): - return eps*(12*0.4*pow((sigma/r),13)/sigma - 2*3.0*sigma*sigma/(r*r*r)) - -epsilon = 2.75/4.184 # kCal/mole -sigma = 7.5 -Rmin = 0.02 -Rmax = 22.6 -Rc1 = 22.0 -Rc2 = 22.5 -N = 1130 - -for i in range(0,N): - r = Rmin + i*(Rmax-Rmin)/(N-1) - U_r = U(r, epsilon, sigma) - F_r = F(r, epsilon, sigma) - # Multiply U(r) & F(r) by the smoothing/switch function - U_r = U_r * S(r, Rc1, Rc2) - F_r = U_r * S(r, Rc1, Rc2, True) + F_r * S(r, Rc1, Rc2, False) - print(str(i+1)+' '+str(r)+' '+str(U_r)+' '+str(F_r)) - diff --git a/tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/moltemplate_files/system.lt b/tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/moltemplate_files/system.lt deleted file mode 100644 index f73c0d5f1d..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/moltemplate_files/system.lt +++ /dev/null @@ -1,166 +0,0 @@ -# Description: -# -# This example shows how to build a multicomponent spherical vesicle. -# The lipid bilayer is composed of two different lipids (DPPC and DLPC), -# The vesicle contains 120 trans-membrane protein inclusions. -# -# The DPPC lipid model is described here: -# G. Brannigan, P.F. Philips, and F.L.H. Brown, -# Physical Review E, Vol 72, 011915 (2005) -# The protein model is described here: -# G. Bellesia, AI Jewett, and J-E Shea, -# Protein Science, Vol19 141-154 (2010) -# The new DLPC model is a truncated version of DPPC, -# (Its behaviour has not been rigorously tested.) -# Note that 50%/50% mixtures of DPPC & DLPC are commonly used to -# build liposomes http://www.ncbi.nlm.nih.gov/pubmed/10620293 -# -# NOTE: THE COORDINATES FOR THESE MOLECULES ARE GENERATED BY PACKMOL (see below) -# -# NOTE: -# This example may require additional features to be added to LAMMPS. -# If LAMMPS complains about an "Invalid pair_style", then copy the code -# in the "additional_lammps_code" directory into your LAMMPS "src" directory -# and recompile LAMMPS. - -# First, load the definitions of the molecules we will need: - -import "CGLipidBr2005.lt" -using namespace CGLipidBr2005 - -import "1beadProtSci2010.lt" -using namespace 1beadProtSci2010 - -# PREREQUISITES: -# Coordinates for the molecules in this example are loaded from an .XYZ file -# created by PACKMOL. This must be done in advance. (See ../packmol_files/) -# -# The XYZ file was created by PACKMOL in 3 steps: -# (Add the proteins, then pack lipids in the inner & outer layers around them.) -# -# step1) Creae 120 proteins. Distribute them on the surface of the sphere. -# -# step2) Keeping the coordinates from step1 fixed, -# a) first we add 9500 DPPC lipids to the inner monolayer -# b) then we add 9500 DLPC lipids to the inner monolayer -# -# step3) Keeping the coordinates from steps 1 and 2 fixed, -# a) first we add 12500 DPPC lipids to the outer monolayer -# b) then we add 12500 DLPC lipids to the outer monolayer -# -# The order that molecules are created in moltemplate should match the order -# they appear in the final XYZ file created by PACKMOL. (See above.) -# Consequently I instantiate the molecules in the same order here: - - -# Step 1) ---- protein inclusions ---- - -proteins = new 4HelixInsideOut [120] - -# Step 2a) ---- inner monolayer ---- -dppc_in = new DPPC [9500] -# Step 2b) -dlpc_in = new DLPC [9500] - -# Step 3a) ---- outer monolayer ---- -dppc_out = new DPPC [12500] -# Step 3b) -dlpc_out = new DLPC [12500] - - - -# ------------------ boundary conditions -------------------- - -write_once("Data Boundary") { - -500.0 500.0 xlo xhi - -500.0 500.0 ylo yhi - -500.0 500.0 zlo zhi -} - - -# -------- interactions between protein and lipids ---------- - -# Note: All atom types must include the full path (the name of -# the namespace which defined them as well as the atom type name). -# (This is because we are no longer inside that namespace.) - - -write_once("In Settings") { - - # Interactions between the protein and lipid atoms are usually - # determined by mixing rules. However this is not possible some - # for atoms (such as the "int" atoms in the lipid model which - # interact using -1/r^2 attraction). Lorentz-Berthelot mixing - # rules do not make sense for these atoms so we must explicitly - # define their interaction with all other atoms. - - # i j pairstylename eps sig K L - - pair_coeff @atom:CGLipidBr2005/int @atom:1beadProtSci2010/sH lj/charmm/coul/charmm/inter 1.8065518 7.5 1 -1 - pair_coeff @atom:CGLipidBr2005/int @atom:1beadProtSci2010/sL lj/charmm/coul/charmm/inter 1.8065518 7.5 1 0 - pair_coeff @atom:CGLipidBr2005/int @atom:1beadProtSci2010/tN lj/charmm/coul/charmm/inter 1.8065518 7.5 1 0 - - # We want the interactions between hydrophobic residues and atoms in - # the interior of the lipid to be energetically similar to the attractive - # interactions between hydrophobic residues. (See 1beadProtSci2010.) - - pair_coeff @atom:CGLipidBr2005/tail @atom:1beadProtSci2010/sH lj/charmm/coul/charmm/inter 1.8065518 7.5 1 -1 - - # All other interactions between proteins and lipids are steric. - pair_coeff @atom:CGLipidBr2005/tail @atom:1beadProtSci2010/sL lj/charmm/coul/charmm/inter 1.8065518 7.5 1 0 - pair_coeff @atom:CGLipidBr2005/tail @atom:1beadProtSci2010/tN lj/charmm/coul/charmm/inter 1.8065518 7.5 1 0 - pair_coeff @atom:CGLipidBr2005/DPPC/head @atom:1beadProtSci2010/sH lj/charmm/coul/charmm/inter 1.8065518 7.5 1 0 - pair_coeff @atom:CGLipidBr2005/DPPC/head @atom:1beadProtSci2010/sL lj/charmm/coul/charmm/inter 1.8065518 7.5 1 0 - pair_coeff @atom:CGLipidBr2005/DLPC/head @atom:1beadProtSci2010/sH lj/charmm/coul/charmm/inter 1.8065518 7.5 1 0 - pair_coeff @atom:CGLipidBr2005/DLPC/head @atom:1beadProtSci2010/sL lj/charmm/coul/charmm/inter 1.8065518 7.5 1 0 - - - # We also add an artificial attractive interaction between the - # turn residues of the protein and the lipid head groups in - # order to keep the protein upright. This might not be necessary - - pair_coeff @atom:CGLipidBr2005/DPPC/head @atom:1beadProtSci2010/tN lj/charmm/coul/charmm/inter 1.8065518 6.0 1 -1 - pair_coeff @atom:CGLipidBr2005/DLPC/head @atom:1beadProtSci2010/tN lj/charmm/coul/charmm/inter 1.8065518 6.0 1 -1 - - # Add a weak attractive interaction between hydrophilic "sL" beads - # (Whose strength mimics the strength of interaction between tail beads - # in the lipid. This was absent from the original protein model. - # However without some kind of weak attraction between residues, - # the negative pressure in the interior of the bilayer membrane - # allways pulls the protein apart. Recall that in the membrane, - # the hydrophobic beads in the protein will face outwards towards the lipid - # tails leaving the hydrophilic amino acids of the protein in the interior. - # In reality, these polar groups form hydrogen bonds with each other.) - - pair_coeff @atom:1beadProtSci2010/sL @atom:1beadProtSci2010/sL lj/charmm/coul/charmm/inter 0.3286 6.0 0.4 -1 - - # However these hydrophilic amino acids are not attracted to - # the bilayer interior. - - pair_coeff @atom:CGLipidBr2005/int @atom:1beadProtSci2010/sL lj/charmm/coul/charmm/inter 0.1643 7.5 0.4 0 - pair_coeff @atom:CGLipidBr2005/tail @atom:1beadProtSci2010/sL lj/charmm/coul/charmm/inter 0.1643 7.5 0.4 0 - -} - - - - -# Finally, we must combine the two force-field styles which were used for -# the coarse-grained lipid and protein. To do that, we write one last time -# to the "In Init" section. When reading the "Init" section LAMMPS will -# read these commands last and this will override any earlier settings. - -write_once("In Init") { - # -- These styles override earlier settings -- - units real - atom_style full - # (Hybrid force field styles were used for portability.) - bond_style hybrid harmonic - angle_style hybrid cosine/delta harmonic - dihedral_style hybrid fourier - improper_style none - pair_style hybrid table linear 1001 lj/charmm/coul/charmm/inter es4k4l 14.5 15 - pair_modify mix arithmetic - special_bonds lj 0.0 0.0 1.0 # turn off pairs if "less than 3 bonds" -} - diff --git a/tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/moltemplate_files/table_int.dat b/tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/moltemplate_files/table_int.dat deleted file mode 100644 index b0d651d67f..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/moltemplate_files/table_int.dat +++ /dev/null @@ -1,1139 +0,0 @@ -# Table for the INT-INT interaction from -# Brannigan et al, Phys Rev E, 72, 011915 (2005) -# This table contains -# i r_i U(r_i) -dU/dr|r_i -# where U(r) = eps*(0.4*(sigma/r)^12 - 3.0*(sigma/r)^2) - -INT -N 1130 - -1 0.02 2.0331818401e+30 1.21990910406e+33 -2 0.04 4.9638228518e+26 1.48914685554e+29 -3 0.06 3.82579033251e+24 7.65158066501e+26 -4 0.08 1.21187081343e+23 1.81780622014e+25 -5 0.1 8.32791281704e+21 9.99349538045e+23 -6 0.12 9.34030842897e+20 9.34030842897e+22 -7 0.14 1.46892540453e+20 1.25907891817e+22 -8 0.16 2.95866897809e+19 2.21900173357e+21 -9 0.18 7.19889946863e+18 4.79926631242e+20 -10 0.2 2.0331818401e+18 1.21990910406e+20 -11 0.22 6.47834392264e+17 3.53364213962e+19 -12 0.24 2.28034873754e+17 1.14017436877e+19 -13 0.26 8.72681951932e+16 4.02776285507e+18 -14 0.28 3.58624366341e+16 1.53696157003e+18 -15 0.3 1.56704372019e+16 6.26817488078e+17 -16 0.32 7.2233129348e+15 2.70874235055e+17 -17 0.34 3.48970861422e+15 1.23166186384e+17 -18 0.36 1.75754381558e+15 5.85847938527e+16 -19 0.38 9.18613895646e+14 2.90088598625e+16 -20 0.4 4.96382285179e+14 1.48914685554e+16 -21 0.42 2.76404230108e+14 7.89726371739e+15 -22 0.44 1.58162693423e+14 4.31352800247e+15 -23 0.46 9.27773983256e+13 2.42027995633e+15 -24 0.48 5.56725765996e+13 1.391814415e+15 -25 0.5 3.41111308981e+13 8.18667141564e+14 -26 0.52 2.13057117167e+13 4.91670270393e+14 -27 0.54 1.35459994024e+13 3.0102220895e+14 -28 0.56 8.75547769351e+12 1.87617379153e+14 -29 0.58 5.74645813711e+12 1.18892237325e+14 -30 0.6 3.8257903322e+12 7.65158066491e+13 -31 0.62 2.58128463312e+12 4.99603477424e+13 -32 0.64 1.7635041342e+12 3.30657025205e+13 -33 0.66 1.21901470178e+12 2.21639036726e+13 -34 0.68 8.51979641904e+11 1.50349348607e+13 -35 0.7 6.0167184547e+11 1.0314374497e+13 -36 0.72 4.29087845387e+11 7.15146409276e+12 -37 0.74 3.08855637556e+11 5.00846980094e+12 -38 0.76 2.24270970425e+11 3.54112058818e+12 -39 0.78 1.64210505205e+11 2.52631546702e+12 -40 0.8 1.2118708117e+11 1.81780621971e+12 -41 0.82 90109367359.1 1.31867367068e+12 -42 0.84 67481501334.4 9.64021449503e+11 -43 0.86 50880896383.4 7.09965997788e+11 -44 0.88 38613938681.2 5.26553710913e+11 -45 0.9 29486692086.8 3.93155896009e+11 -46 0.92 22650731882.4 2.95444330322e+11 -47 0.94 17498544395.3 2.23385674464e+11 -48 0.96 13591937526.4 1.69899220331e+11 -49 0.98 10612635712.6 1.29950642555e+11 -50 1.0 8327912706.34 99934953582.6 -51 1.02 6566502316.69 77252969474.2 -52 1.04 5201589672.36 60018343356.8 -53 1.06 4138717434.11 46853405843.3 -54 1.08 3307128665.58 36745874940.0 -55 1.1 2653529579.27 28947596241.1 -56 1.12 2137567708.15 22902511945.9 -57 1.14 1728534024.3 18195095739.0 -58 1.16 1402943799.0 14513212422.1 -59 1.18 1142752163.37 11621209113.9 -60 1.2 934030766.093 9340308300.6 -61 1.22 765981286.774 7534242773.65 -62 1.24 630196371.787 6098675145.29 -63 1.26 520103253.414 4953364870.6 -64 1.28 430542934.103 4036340534.04 -65 1.3 357450462.101 3299543229.91 -66 1.32 297610947.802 2705554551.18 -67 1.34 248472587.186 2225128105.44 -68 1.36 208002782.573 1835319108.76 -69 1.38 174576985.011 1518061159.35 -70 1.4 146892484.084 1259078837.33 -71 1.42 123901294.937 1047053582.16 -72 1.44 104757721.536 872981382.419 -73 1.46 88777241.639 729676313.267 -74 1.48 75404158.02 611385405.387 -75 1.5 64186061.7033 513488820.507 -76 1.52 54753607.1486 432265633.695 -77 1.54 46804443.7318 364710253.134 -78 1.56 40090410.0598 308388060.159 -79 1.58 34407297.9713 261321529.95 -80 1.6 29586646.6744 221900119.2 -81 1.62 25489145.661 188808745.634 -82 1.64 21999316.2868 160970856.824 -83 1.66 19021212.5921 137502982.517 -84 1.68 16474936.8715 117678352.86 -85 1.7 14293808.3245 100897694.735 -86 1.72 12422056.6082 86665727.6626 -87 1.74 10812938.3788 74572197.8496 -88 1.76 9427195.57103 64276535.39 -89 1.78 8231790.46096 55495411.7777 -90 1.8 7198865.45512 47992625.088 -91 1.82 6304885.77339 41570857.9644 -92 1.84 5529931.32911 36064946.1544 -93 1.86 4857110.59557 31336368.341 -94 1.88 4272074.43377 27268725.7382 -95 1.9 3762612.01167 23764025.6584 -96 1.92 3318314.28383 20739619.609 -97 1.94 2930293.18879 18125675.4316 -98 1.96 2590946.89128 15863086.114 -99 1.98 2293763.15199 13901736.4186 -100 2.0 2033154.33079 12199063.3122 -101 2.02 1804318.68586 10718858.1296 -102 2.04 1603123.57305 9430268.02169 -103 2.06 1426006.91783 8306962.01537 -104 2.08 1269893.96121 7326433.30293 -105 2.1 1132126.79514 6469414.48445 -106 2.12 1010404.62602 5719386.63441 -107 2.14 902733.052344 5062166.44376 -108 2.16 807380.928986 4485558.44681 -109 2.18 722843.627253 3979061.59742 -110 2.2 647811.695319 3533621.30686 -111 2.22 581144.085827 3141419.57242 -112 2.24 521845.251959 2795697.07302 -113 2.26 469045.525153 2490602.13576 -114 2.28 421984.280794 2221062.32522 -115 2.3 379995.475978 1982675.10836 -116 2.32 342495.208369 1771614.62868 -117 2.34 308970.999537 1584552.10475 -118 2.36 278972.551763 1418587.76828 -119 2.38 252103.765513 1271192.59046 -120 2.4 228015.837009 1140158.32224 -121 2.42 206401.282366 1023554.60663 -122 2.44 186988.75765 919692.114521 -123 2.46 169538.563484 827090.818108 -124 2.48 153838.739168 744452.651831 -125 2.5 139701.665073 670637.92543 -126 2.52 126961.103835 604644.949624 -127 2.54 115469.620781 545592.416037 -128 2.56 105096.332511 492704.141327 -129 2.58 95724.9397832 445295.843157 -130 2.6 87252.0069441 402763.664479 -131 2.62 79585.4554502 364574.203947 -132 2.64 72643.2434671 330255.845328 -133 2.66 66352.2073932 299391.208536 -134 2.68 60647.0444312 271610.570248 -135 2.7 55469.4181565 246586.123584 -136 2.72 50767.1714483 224026.964698 -137 2.74 46493.633237 203674.709811 -138 2.76 42607.0073083 185299.659567 -139 2.78 39069.8329526 168697.439095 -140 2.8 35848.5085794 153686.051901 -141 2.82 32912.8705664 140103.294183 -142 2.84 30235.8206098 127804.483324 -143 2.86 27792.9956998 116660.460548 -144 2.88 25562.4755962 106555.833042 -145 2.9 23524.5233195 97387.4254387 -146 2.92 21661.3547409 89062.9145204 -147 2.94 19956.9338374 81499.6244039 -148 2.96 18396.7906059 74623.4624292 -149 2.98 16967.8589974 68367.9785194 -150 3.0 15658.3325568 62673.5329856 -151 3.02 14457.5357325 57486.5596649 -152 3.04 13355.809067 52758.912937 -153 3.06 12344.4066925 48447.2886046 -154 3.08 11415.4047444 44512.7098736 -155 3.1 10561.6194689 40920.0707567 -156 3.12 9776.5339459 37637.7301715 -157 3.14 9054.23247117 34637.1508274 -158 3.16 8389.34175838 31892.5777179 -159 3.18 7776.97821258 29380.7516608 -160 3.2 7212.7006167 27080.6538766 -161 3.22 6692.4676457 24973.2780793 -162 3.24 6212.59969004 23041.4269669 -163 3.26 5769.74452856 21269.5303734 -164 3.28 5360.84644195 19643.4826615 -165 3.3 4983.1184041 18150.4972204 -166 3.32 4634.01702836 16778.97618 -167 3.34 4311.21998136 15518.393672 -168 3.36 4012.60560869 14359.191159 -169 3.38 3736.23454428 13292.6835236 -170 3.4 3480.33310029 12310.9747549 -171 3.42 3243.27825585 11406.8822043 -172 3.44 3023.58408279 10573.8684961 -173 3.46 2819.88946345 9805.98028003 -174 3.48 2630.94697101 9097.79310596 -175 3.5 2455.61279669 8444.36177626 -176 3.52 2292.83761972 7841.17560602 -177 3.54 2141.65832756 7284.11808108 -178 3.56 2001.19050257 6769.43046025 -179 3.58 1870.62160083 6293.67891689 -180 3.6 1749.20475558 5853.72485855 -181 3.62 1636.25314534 5446.69810179 -182 3.64 1531.13487237 5069.97261409 -183 3.66 1433.26830277 4721.1445646 -184 3.68 1342.11782445 4398.01245332 -185 3.7 1257.18998347 4098.55911171 -186 3.72 1178.02996319 3820.93539003 -187 3.74 1104.21837425 3563.44536511 -188 3.76 1035.36832639 3324.53291993 -189 3.78 971.122756088 3102.76956138 -190 3.8 911.151986554 2896.84335615 -191 3.82 855.151498616 2705.54887715 -192 3.84 802.83989347 2527.77806329 -193 3.86 753.957029799 2362.51190574 -194 3.88 708.262319576 2208.81288195 -195 3.9 665.533168297 2065.81806693 -196 3.92 625.563546756 1932.73285812 -197 3.94 588.162682667 1808.82525631 -198 3.96 553.153861545 1693.42065104 -199 3.98 520.373327227 1585.89706361 -200 4.0 489.669273313 1485.68080556 -201 4.02 460.900917596 1392.24251449 -202 4.04 433.937652306 1305.09353282 -203 4.06 408.6582636 1223.78259822 -204 4.08 384.950214367 1147.89281764 -205 4.1 362.708984933 1077.03889938 -206 4.12 341.837466738 1010.86461999 -207 4.14 322.245404503 949.040505266 -208 4.16 303.848882793 891.261706073 -209 4.18 286.569853265 837.246052066 -210 4.2 270.33569919 786.732267446 -211 4.22 255.078834164 739.47833469 -212 4.24 240.736332164 695.259993326 -213 4.26 227.249586386 653.869362042 -214 4.28 214.563994495 615.113673492 -215 4.3 202.628668126 578.814112106 -216 4.32 191.396164684 544.804746089 -217 4.34 180.822239621 512.931545605 -218 4.36 170.865617553 483.051479815 -219 4.38 161.487780703 455.031686127 -220 4.4 152.652773286 428.748705595 -221 4.42 144.327020575 404.087778912 -222 4.44 136.479161479 380.942197972 -223 4.46 129.07989358 359.212708377 -224 4.48 122.101829632 338.806958688 -225 4.5 115.519364658 319.638992577 -226 4.52 109.308552789 301.628780369 -227 4.54 103.446993117 284.701786758 -228 4.56 97.9137238447 268.788571763 -229 4.58 92.6891241175 253.824422244 -230 4.6 87.7548229339 239.749011508 -231 4.62 83.0936146036 226.506084761 -232 4.64 78.6893802546 214.043168343 -233 4.66 74.5270149351 202.31130085 -234 4.68 70.5923598871 191.264784422 -235 4.7 66.8721396072 180.860954593 -236 4.72 63.353903336 171.05996726 -237 4.74 60.0259706488 161.824601429 -238 4.76 56.8773808439 153.120076496 -239 4.78 53.8978458491 144.913882966 -240 4.8 51.0777063884 137.175625538 -241 4.82 48.4078911713 129.876877635 -242 4.84 45.8798788842 122.991046476 -243 4.86 43.485662782 116.493247913 -244 4.88 41.2177176913 110.360190267 -245 4.9 39.0689692529 104.570066494 -246 4.92 37.0327652428 99.1024540566 -247 4.94 35.102848823 93.9382219092 -248 4.96 33.2733335874 89.05944408 -249 4.98 31.5386802724 84.4493193479 -250 5.0 29.8936750183 80.0920965658 -251 5.02 28.3334090704 75.9730052143 -252 5.04 26.8532598202 72.0781907976 -253 5.06 25.4488730938 68.3946547294 -254 5.08 24.116146599 64.9101983786 -255 5.1 22.8512144543 61.6133709734 -256 5.12 21.650432722 58.4934210835 -257 5.14 20.5103658787 55.5402514226 -258 5.16 19.4277741591 52.7443767307 -259 5.18 18.3996017121 50.0968845179 -260 5.2 17.4229655155 47.5893984632 -261 5.22 16.4951449988 45.2140442802 -262 5.24 15.6135723236 42.9634178757 -263 5.26 14.775823281 40.8305556374 -264 5.28 13.979608762 38.808906703 -265 5.3 13.2227667648 36.8923070701 -266 5.32 12.5032549016 35.0749554196 -267 5.34 11.8191433738 33.3513905323 -268 5.36 11.1686083831 31.7164701895 -269 5.38 10.5499259512 30.1653514539 -270 5.4 9.96146612005 28.693472236 -271 5.42 9.40168750976 27.2965340593 -272 5.44 8.86913220892 25.9704859397 -273 5.46 8.36242097742 24.7115093061 -274 5.48 7.88024874079 23.5160038893 -275 5.5 7.4213803577 22.3805745153 -276 5.52 6.98464664308 21.3020187412 -277 5.54 6.56894063048 20.2773152771 -278 5.56 6.1732140587 19.3036131423 -279 5.58 5.79647406826 18.3782215059 -280 5.6 5.43778009463 17.4986001669 -281 5.62 5.09624094585 16.6623506308 -282 5.64 4.77101205293 15.867207745 -283 5.66 4.46129288233 15.1110318537 -284 5.68 4.16632450031 14.3918014404 -285 5.7 3.88538727999 13.7076062261 -286 5.72 3.61779874199 13.0566406912 -287 5.74 3.36291152072 12.4371979973 -288 5.76 3.12011144838 11.8476642796 -289 5.78 2.8888157497 11.2865132882 -290 5.8 2.66847134042 10.7523013555 -291 5.82 2.45855322349 10.2436626676 -292 5.84 2.25856297681 9.7593048226 -293 5.86 2.06802732724 9.2980046552 -294 5.88 1.88649680546 8.85860431242 -295 5.9 1.71354447704 8.44000756375 -296 5.92 1.548764745 8.04117633127 -297 5.94 1.39177221978 7.66112742597 -298 5.96 1.24220065245 7.29892947717 -299 5.98 1.09970192753 6.9537000433 -300 6.0 0.963945111861 6.62460289254 -301 6.02 0.83461555631 6.31084544295 -302 6.04 0.711414047074 6.01167635216 -303 6.06 0.594056003831 5.72638324756 -304 6.08 0.482270721937 5.45429058822 -305 6.1 0.375800656137 5.19475765055 -306 6.12 0.274400743381 4.94717663025 -307 6.14 0.177837762511 4.71097085338 -308 6.16 0.0858897286772 4.48559308998 -309 6.18 -0.00165467948361 4.27052396409 -310 6.2 -0.0849966617872 4.06527045435 -311 6.22 -0.164327809314 3.8693644797 -312 6.24 -0.239830589745 3.68236156522 -313 6.26 -0.311678806773 3.50383958321 -314 6.28 -0.380038035049 3.33339756513 -315 6.3 -0.445066032049 3.17065458013 -316 6.32 -0.506913128135 3.0152486763 -317 6.34 -0.56572259604 2.866835881 -318 6.36 -0.621631000928 2.72508925658 -319 6.38 -0.674768532081 2.58969800863 -320 6.4 -0.725259317268 2.46036664323 -321 6.42 -0.773221720709 2.33681417085 -322 6.44 -0.818768625574 2.21877335375 -323 6.46 -0.862007701832 2.10598999469 -324 6.48 -0.90304166028 1.99822226439 -325 6.5 -0.941968493479 1.8952400656 -326 6.52 -0.978881704324 1.79682443166 -327 6.54 -1.01387052292 1.70276695755 -328 6.56 -1.04702011237 1.61286926168 -329 6.58 -1.07841176412 1.52694247655 -330 6.6 -1.10812308336 1.44480676668 -331 6.62 -1.13622816508 1.36629087245 -332 6.64 -1.1627977612 1.29123167801 -333 6.66 -1.18789943936 1.21947380239 -334 6.68 -1.21159773365 1.15086921208 -335 6.7 -1.23395428792 1.08527685416 -336 6.72 -1.25502799183 1.02256230873 -337 6.74 -1.27487511024 0.962597459596 -338 6.76 -1.2935494061 0.90526018218 -339 6.78 -1.31110225728 0.850434047748 -340 6.8 -1.32758276773 0.798008043011 -341 6.82 -1.34303787302 0.747876304295 -342 6.84 -1.35751244086 0.699937865467 -343 6.86 -1.3710493666 0.654096418865 -344 6.88 -1.38368966412 0.610260088543 -345 6.9 -1.3954725523 0.568341215144 -346 6.92 -1.40643553728 0.528256151786 -347 6.94 -1.41661449078 0.489925070364 -348 6.96 -1.42604372459 0.453271777711 -349 6.98 -1.43475606153 0.418223541087 -350 7.0 -1.44278290299 0.384710922497 -351 7.02 -1.45015429321 0.352667621378 -352 7.04 -1.45689898057 0.322030325194 -353 7.06 -1.46304447588 0.292738567537 -354 7.08 -1.46861710792 0.264734593325 -355 7.1 -1.47364207647 0.237963230734 -356 7.12 -1.47814350264 0.2123717695 -357 7.14 -1.482144477 0.187909845266 -358 7.16 -1.48566710537 0.16452932965 -359 7.18 -1.48873255248 0.142184225751 -360 7.2 -1.49136108362 0.120830568787 -361 7.22 -1.49357210429 0.100426331626 -362 7.24 -1.49538419809 0.0809313349308 -363 7.26 -1.4968151628 0.0623071617066 -364 7.28 -1.49788204479 0.044517076001 -365 7.3 -1.49860117187 0.0275259455594 -366 7.32 -1.49898818464 0.0113001682279 -367 7.34 -1.49905806636 -0.00419239808778 -368 7.36 -1.4988251715 -0.0189825020854 -369 7.38 -1.49830325295 -0.0330995625254 -370 7.4 -1.49750548803 -0.0465717286462 -371 7.42 -1.49644450327 -0.0594259376903 -372 7.44 -1.49513239812 -0.0716879696855 -373 7.46 -1.49358076759 -0.0833824996199 -374 7.48 -1.4918007238 -0.0945331471409 -375 7.5 -1.48980291663 -0.105162523901 -376 7.52 -1.48759755345 -0.115292278666 -377 7.54 -1.48519441791 -0.124943140307 -378 7.56 -1.48260288794 -0.13413495876 -379 7.58 -1.47983195293 -0.142886744076 -380 7.6 -1.47689023018 -0.151216703644 -381 7.62 -1.47378598053 -0.159142277674 -382 7.64 -1.47052712344 -0.166680173038 -383 7.66 -1.46712125128 -0.173846395532 -384 7.68 -1.46357564306 -0.180656280652 -385 7.7 -1.45989727753 -0.187124522948 -386 7.72 -1.45609284575 -0.193265204023 -387 7.74 -1.45216876302 -0.199091819249 -388 7.76 -1.4481311804 -0.204617303261 -389 7.78 -1.44398599566 -0.20985405428 -390 7.8 -1.43973886378 -0.214813957332 -391 7.82 -1.43539520696 -0.21950840641 -392 7.84 -1.43096022428 -0.223948325627 -393 7.86 -1.42643890087 -0.228144189416 -394 7.88 -1.42183601669 -0.232106041819 -395 7.9 -1.41715615498 -0.235843514899 -396 7.92 -1.41240371029 -0.239365846333 -397 7.94 -1.40758289625 -0.242681896213 -398 7.96 -1.40269775292 -0.245800163096 -399 7.98 -1.39775215386 -0.248728799339 -400 8.0 -1.39274981294 -0.251475625745 -401 8.02 -1.38769429081 -0.254048145572 -402 8.04 -1.3825890011 -0.256453557906 -403 8.06 -1.37743721643 -0.258698770453 -404 8.08 -1.37224207403 -0.260790411767 -405 8.1 -1.3670065813 -0.262734842931 -406 8.12 -1.36173362096 -0.264538168734 -407 8.14 -1.35642595614 -0.26620624836 -408 8.16 -1.35108623513 -0.267744705599 -409 8.18 -1.34571699603 -0.269158938625 -410 8.2 -1.34032067115 -0.270454129338 -411 8.22 -1.33489959126 -0.271635252315 -412 8.24 -1.32945598963 -0.272707083354 -413 8.26 -1.32399200593 -0.273674207668 -414 8.28 -1.31850968998 -0.274541027712 -415 8.3 -1.3130110053 -0.275311770682 -416 8.32 -1.30749783257 -0.275990495686 -417 8.34 -1.30197197291 -0.276581100614 -418 8.36 -1.29643515102 -0.277087328708 -419 8.38 -1.29088901827 -0.277512774857 -420 8.4 -1.28533515553 -0.277860891625 -421 8.42 -1.279775076 -0.278134995017 -422 8.44 -1.27421022789 -0.278338270004 -423 8.46 -1.26864199697 -0.27847377582 -424 8.48 -1.26307170904 -0.278544451025 -425 8.5 -1.25750063229 -0.278553118366 -426 8.52 -1.25192997959 -0.278502489422 -427 8.54 -1.24636091063 -0.27839516907 -428 8.56 -1.24079453406 -0.278233659745 -429 8.58 -1.23523190945 -0.27802036554 -430 8.6 -1.22967404925 -0.277757596126 -431 8.62 -1.22412192063 -0.277447570509 -432 8.64 -1.21857644724 -0.277092420635 -433 8.66 -1.21303851096 -0.276694194842 -434 8.68 -1.20750895348 -0.276254861174 -435 8.7 -1.20198857794 -0.275776310556 -436 8.72 -1.19647815038 -0.275260359835 -437 8.74 -1.19097840123 -0.274708754702 -438 8.76 -1.18549002669 -0.274123172492 -439 8.78 -1.18001369009 -0.273505224869 -440 8.8 -1.17455002313 -0.272856460401 -441 8.82 -1.16909962718 -0.272178367032 -442 8.84 -1.16366307443 -0.271472374453 -443 8.86 -1.15824090903 -0.270739856375 -444 8.88 -1.1528336482 -0.269982132713 -445 8.9 -1.14744178329 -0.269200471678 -446 8.92 -1.14206578078 -0.26839609179 -447 8.94 -1.13670608326 -0.267570163805 -448 8.96 -1.13136311038 -0.266723812565 -449 8.98 -1.1260372597 -0.26585811878 -450 9.0 -1.12072890764 -0.264974120729 -451 9.02 -1.11543841024 -0.2640728159 -452 9.04 -1.11016610399 -0.263155162565 -453 9.06 -1.10491230659 -0.262222081284 -454 9.08 -1.09967731769 -0.261274456364 -455 9.1 -1.09446141962 -0.260313137244 -456 9.12 -1.08926487805 -0.259338939836 -457 9.14 -1.08408794265 -0.258352647809 -458 9.16 -1.07893084774 -0.257355013824 -459 9.18 -1.07379381288 -0.256346760718 -460 9.2 -1.06867704347 -0.255328582644 -461 9.22 -1.06358073129 -0.254301146164 -462 9.24 -1.05850505508 -0.253265091305 -463 9.26 -1.053450181 -0.252221032561 -464 9.28 -1.04841626319 -0.251169559871 -465 9.3 -1.04340344425 -0.25011123955 -466 9.32 -1.03841185563 -0.249046615186 -467 9.34 -1.03344161818 -0.2479762085 -468 9.36 -1.0284928425 -0.246900520178 -469 9.38 -1.02356562938 -0.245820030663 -470 9.4 -1.0186600702 -0.244735200927 -471 9.42 -1.01377624733 -0.243646473201 -472 9.44 -1.00891423443 -0.242554271687 -473 9.46 -1.0040740969 -0.241459003238 -474 9.48 -0.999255892143 -0.240361058009 -475 9.5 -0.994459669928 -0.239260810093 -476 9.52 -0.989685472697 -0.238158618121 -477 9.54 -0.984933335869 -0.237054825845 -478 9.56 -0.980203288132 -0.235949762702 -479 9.58 -0.975495351726 -0.234843744346 -480 9.6 -0.970809542708 -0.233737073173 -481 9.62 -0.966145871217 -0.232630038816 -482 9.64 -0.961504341725 -0.231522918625 -483 9.66 -0.956884953272 -0.230415978128 -484 9.68 -0.952287699705 -0.229309471477 -485 9.7 -0.947712569897 -0.228203641873 -486 9.72 -0.943159547963 -0.22709872198 -487 9.74 -0.938628613467 -0.225994934317 -488 9.76 -0.934119741622 -0.224892491642 -489 9.78 -0.929632903477 -0.223791597316 -490 9.8 -0.925168066109 -0.222692445658 -491 9.82 -0.920725192794 -0.221595222284 -492 9.84 -0.916304243179 -0.220500104432 -493 9.86 -0.91190517345 -0.219407261278 -494 9.88 -0.907527936486 -0.218316854241 -495 9.9 -0.903172482012 -0.217229037271 -496 9.92 -0.898838756748 -0.216143957132 -497 9.94 -0.894526704547 -0.215061753669 -498 9.96 -0.890236266534 -0.213982560076 -499 9.98 -0.885967381232 -0.212906503136 -500 10.0 -0.881719984692 -0.211833703472 -501 10.02 -0.877494010612 -0.210764275774 -502 10.04 -0.873289390453 -0.209698329022 -503 10.06 -0.869106053554 -0.208635966708 -504 10.08 -0.864943927233 -0.207577287034 -505 10.1 -0.860802936899 -0.206522383122 -506 10.12 -0.856683006147 -0.205471343199 -507 10.14 -0.852584056854 -0.204424250786 -508 10.16 -0.848506009271 -0.203381184875 -509 10.18 -0.844448782117 -0.202342220105 -510 10.2 -0.840412292656 -0.201307426921 -511 10.22 -0.836396456786 -0.20027687174 -512 10.24 -0.832401189115 -0.199250617102 -513 10.26 -0.828426403039 -0.19822872182 -514 10.28 -0.824472010811 -0.197211241119 -515 10.3 -0.820537923617 -0.196198226777 -516 10.32 -0.81662405164 -0.195189727259 -517 10.34 -0.812730304126 -0.19418578784 -518 10.36 -0.808856589444 -0.193186450732 -519 10.38 -0.805002815152 -0.1921917552 -520 10.4 -0.801168888049 -0.191201737679 -521 10.42 -0.797354714233 -0.190216431881 -522 10.44 -0.793560199154 -0.189235868906 -523 10.46 -0.789785247667 -0.188260077336 -524 10.48 -0.786029764076 -0.187289083343 -525 10.5 -0.782293652189 -0.186322910778 -526 10.52 -0.778576815358 -0.185361581264 -527 10.54 -0.774879156522 -0.184405114284 -528 10.56 -0.771200578253 -0.183453527268 -529 10.58 -0.767540982794 -0.182506835671 -530 10.6 -0.763900272099 -0.181565053055 -531 10.62 -0.760278347867 -0.180628191165 -532 10.64 -0.75667511158 -0.179696260001 -533 10.66 -0.753090464539 -0.17876926789 -534 10.68 -0.749524307893 -0.177847221551 -535 10.7 -0.745976542671 -0.176930126167 -536 10.72 -0.742447069815 -0.176017985441 -537 10.74 -0.738935790206 -0.175110801662 -538 10.76 -0.735442604695 -0.174208575761 -539 10.78 -0.731967414126 -0.173311307369 -540 10.8 -0.728510119361 -0.172418994873 -541 10.82 -0.72507062131 -0.171531635464 -542 10.84 -0.721648820948 -0.170649225192 -543 10.86 -0.718244619341 -0.169771759015 -544 10.88 -0.714857917667 -0.168899230842 -545 10.9 -0.711488617235 -0.168031633581 -546 10.92 -0.708136619505 -0.167168959186 -547 10.94 -0.704801826108 -0.166311198692 -548 10.96 -0.701484138863 -0.165458342262 -549 10.98 -0.698183459794 -0.164610379221 -550 11.0 -0.694899691148 -0.1637672981 -551 11.02 -0.691632735406 -0.162929086665 -552 11.04 -0.688382495303 -0.162095731957 -553 11.06 -0.68514887384 -0.161267220326 -554 11.08 -0.681931774298 -0.160443537459 -555 11.1 -0.678731100249 -0.159624668416 -556 11.12 -0.675546755573 -0.15881059766 -557 11.14 -0.672378644462 -0.15800130908 -558 11.16 -0.669226671439 -0.157196786028 -559 11.18 -0.666090741365 -0.156397011339 -560 11.2 -0.662970759447 -0.155601967361 -561 11.22 -0.659866631253 -0.154811635976 -562 11.24 -0.656778262715 -0.154025998629 -563 11.26 -0.653705560141 -0.153245036348 -564 11.28 -0.650648430223 -0.152468729768 -565 11.3 -0.647606780043 -0.15169705915 -566 11.32 -0.644580517084 -0.150930004405 -567 11.34 -0.641569549231 -0.150167545112 -568 11.36 -0.638573784781 -0.149409660536 -569 11.38 -0.635593132451 -0.148656329652 -570 11.4 -0.632627501379 -0.147907531156 -571 11.42 -0.629676801133 -0.147163243484 -572 11.44 -0.626740941713 -0.146423444834 -573 11.46 -0.62381983356 -0.145688113174 -574 11.48 -0.620913387554 -0.144957226261 -575 11.5 -0.618021515027 -0.144230761656 -576 11.52 -0.615144127757 -0.143508696739 -577 11.54 -0.612281137978 -0.14279100872 -578 11.56 -0.609432458382 -0.142077674653 -579 11.58 -0.606598002119 -0.141368671449 -580 11.6 -0.603777682806 -0.140663975889 -581 11.62 -0.600971414522 -0.139963564633 -582 11.64 -0.598179111815 -0.139267414235 -583 11.66 -0.595400689704 -0.138575501149 -584 11.68 -0.592636063678 -0.137887801745 -585 11.7 -0.589885149701 -0.137204292313 -586 11.72 -0.587147864211 -0.136524949077 -587 11.74 -0.584424124122 -0.135849748201 -588 11.76 -0.581713846826 -0.135178665802 -589 11.78 -0.579016950193 -0.134511677954 -590 11.8 -0.576333352571 -0.133848760697 -591 11.82 -0.573662972788 -0.133189890048 -592 11.84 -0.571005730151 -0.132535042004 -593 11.86 -0.56836154445 -0.131884192552 -594 11.88 -0.565730335952 -0.131237317677 -595 11.9 -0.563112025406 -0.130594393364 -596 11.92 -0.560506534041 -0.129955395608 -597 11.94 -0.557913783565 -0.129320300421 -598 11.96 -0.555333696166 -0.128689083832 -599 11.98 -0.552766194514 -0.1280617219 -600 12.0 -0.550211201752 -0.127438190715 -601 12.02 -0.547668641506 -0.126818466403 -602 12.04 -0.545138437876 -0.126202525133 -603 12.06 -0.542620515439 -0.125590343118 -604 12.08 -0.540114799247 -0.124981896625 -605 12.1 -0.537621214828 -0.124377161973 -606 12.12 -0.53513968818 -0.123776115544 -607 12.14 -0.532670145775 -0.123178733779 -608 12.16 -0.530212514555 -0.122584993188 -609 12.18 -0.52776672193 -0.121994870352 -610 12.2 -0.525332695778 -0.121408341923 -611 12.22 -0.522910364445 -0.120825384632 -612 12.24 -0.52049965674 -0.120245975289 -613 12.26 -0.518100501935 -0.119670090788 -614 12.28 -0.515712829763 -0.119097708107 -615 12.3 -0.513336570418 -0.118528804313 -616 12.32 -0.51097165455 -0.117963356563 -617 12.34 -0.508618013267 -0.11740134211 -618 12.36 -0.506275578128 -0.116842738298 -619 12.38 -0.503944281147 -0.116287522571 -620 12.4 -0.501624054788 -0.115735672472 -621 12.42 -0.49931483196 -0.115187165645 -622 12.44 -0.497016546022 -0.114641979838 -623 12.46 -0.494729130774 -0.114100092904 -624 12.48 -0.49245252046 -0.1135614828 -625 12.5 -0.490186649763 -0.113026127594 -626 12.52 -0.487931453803 -0.112494005462 -627 12.54 -0.485686868135 -0.11196509469 -628 12.56 -0.48345282875 -0.111439373678 -629 12.58 -0.481229272066 -0.110916820936 -630 12.6 -0.479016134933 -0.110397415091 -631 12.62 -0.476813354625 -0.109881134884 -632 12.64 -0.474620868841 -0.109367959171 -633 12.66 -0.472438615702 -0.108857866928 -634 12.68 -0.470266533747 -0.108350837244 -635 12.7 -0.468104561934 -0.107846849332 -636 12.72 -0.465952639633 -0.107345882519 -637 12.74 -0.463810706629 -0.106847916255 -638 12.76 -0.461678703116 -0.106352930108 -639 12.78 -0.459556569693 -0.105860903769 -640 12.8 -0.457444247367 -0.105371817049 -641 12.82 -0.455341677547 -0.10488564988 -642 12.84 -0.453248802042 -0.104402382317 -643 12.86 -0.451165563056 -0.103921994536 -644 12.88 -0.449091903193 -0.103444466836 -645 12.9 -0.447027765446 -0.102969779639 -646 12.92 -0.4449730932 -0.102497913489 -647 12.94 -0.442927830229 -0.102028849053 -648 12.96 -0.440891920688 -0.101562567122 -649 12.98 -0.438865309121 -0.101099048608 -650 13.0 -0.436847940448 -0.100638274548 -651 13.02 -0.434839759968 -0.100180226101 -652 13.04 -0.432840713358 -0.0997248845489 -653 13.06 -0.430850746664 -0.0992722312959 -654 13.08 -0.428869806307 -0.0988222478696 -655 13.1 -0.426897839073 -0.0983749159199 -656 13.12 -0.424934792115 -0.0979302172191 -657 13.14 -0.42298061295 -0.0974881336614 -658 13.16 -0.421035249454 -0.097048647263 -659 13.18 -0.419098649864 -0.0966117401617 -660 13.2 -0.417170762771 -0.0961773946166 -661 13.22 -0.41525153712 -0.0957455930079 -662 13.24 -0.413340922208 -0.0953163178365 -663 13.26 -0.411438867679 -0.0948895517235 -664 13.28 -0.409545323527 -0.0944652774101 -665 13.3 -0.407660240085 -0.0940434777572 -666 13.32 -0.405783568032 -0.0936241357448 -667 13.34 -0.403915258384 -0.0932072344716 -668 13.36 -0.402055262494 -0.0927927571548 -669 13.38 -0.400203532049 -0.0923806871294 -670 13.4 -0.39836001907 -0.091971007848 -671 13.42 -0.396524675907 -0.0915637028799 -672 13.44 -0.394697455235 -0.0911587559112 -673 13.46 -0.392878310058 -0.0907561507435 -674 13.48 -0.391067193701 -0.0903558712944 -675 13.5 -0.389264059808 -0.0899579015961 -676 13.52 -0.387468862344 -0.0895622257951 -677 13.54 -0.385681555589 -0.089168828152 -678 13.56 -0.383902094135 -0.0887776930406 -679 13.58 -0.382130432887 -0.0883888049474 -680 13.6 -0.380366527059 -0.088002148471 -681 13.62 -0.378610332173 -0.0876177083216 -682 13.64 -0.376861804052 -0.0872354693205 -683 13.66 -0.375120898826 -0.0868554163993 -684 13.68 -0.373387572922 -0.0864775345994 -685 13.7 -0.371661783067 -0.0861018090713 -686 13.72 -0.369943486282 -0.0857282250742 -687 13.74 -0.368232639885 -0.0853567679751 -688 13.76 -0.366529201481 -0.0849874232486 -689 13.78 -0.364833128968 -0.0846201764757 -690 13.8 -0.363144380531 -0.0842550133436 -691 13.82 -0.361462914638 -0.083891919645 -692 13.84 -0.359788690043 -0.0835308812773 -693 13.86 -0.358121665778 -0.0831718842421 -694 13.88 -0.356461801157 -0.0828149146446 -695 13.9 -0.354809055768 -0.0824599586927 -696 13.92 -0.353163389476 -0.0821070026966 -697 13.94 -0.351524762418 -0.0817560330682 -698 13.96 -0.349893135001 -0.0814070363201 -699 13.98 -0.348268467902 -0.0810599990654 -700 14.0 -0.346650722064 -0.0807149080166 -701 14.02 -0.345039858694 -0.0803717499853 -702 14.04 -0.343435839265 -0.0800305118814 -703 14.06 -0.341838625506 -0.0796911807123 -704 14.08 -0.340248179409 -0.0793537435825 -705 14.1 -0.338664463221 -0.079018187693 -706 14.12 -0.337087439445 -0.0786845003402 -707 14.14 -0.335517070835 -0.0783526689157 -708 14.16 -0.333953320399 -0.0780226809053 -709 14.18 -0.332396151392 -0.0776945238888 -710 14.2 -0.330845527319 -0.0773681855387 -711 14.22 -0.329301411928 -0.0770436536203 -712 14.24 -0.327763769212 -0.0767209159903 -713 14.26 -0.326232563407 -0.0763999605967 -714 14.28 -0.324707758986 -0.076080775478 -715 14.3 -0.323189320665 -0.0757633487623 -716 14.32 -0.321677213392 -0.075447668667 -717 14.34 -0.320171402352 -0.0751337234981 -718 14.36 -0.318671852963 -0.0748215016493 -719 14.38 -0.317178530874 -0.0745109916017 -720 14.4 -0.315691401963 -0.0742021819228 -721 14.42 -0.314210432337 -0.0738950612663 -722 14.44 -0.312735588328 -0.073589618371 -723 14.46 -0.311266836492 -0.0732858420606 -724 14.48 -0.309804143609 -0.0729837212427 -725 14.5 -0.308347476679 -0.0726832449085 -726 14.52 -0.306896802922 -0.0723844021319 -727 14.54 -0.305452089775 -0.072087182069 -728 14.56 -0.304013304893 -0.0717915739575 -729 14.58 -0.302580416142 -0.0714975671162 -730 14.6 -0.301153391604 -0.071205150944 -731 14.62 -0.29973219957 -0.0709143149198 -732 14.64 -0.298316808542 -0.0706250486013 -733 14.66 -0.29690718723 -0.0703373416252 -734 14.68 -0.29550330455 -0.0700511837056 -735 14.7 -0.294105129623 -0.0697665646344 -736 14.72 -0.292712631773 -0.06948347428 -737 14.74 -0.291325780527 -0.069201902587 -738 14.76 -0.289944545612 -0.0689218395755 -739 14.78 -0.288568896953 -0.0686432753407 -740 14.8 -0.287198804672 -0.068366200052 -741 14.82 -0.285834239089 -0.0680906039529 -742 14.84 -0.284475170717 -0.0678164773599 -743 14.86 -0.283121570262 -0.0675438106623 -744 14.88 -0.281773408622 -0.0672725943215 -745 14.9 -0.280430656883 -0.0670028188703 -746 14.92 -0.279093286324 -0.0667344749127 -747 14.94 -0.277761268406 -0.066467553123 -748 14.96 -0.276434574779 -0.0662020442454 -749 14.98 -0.275113177278 -0.0659379390934 -750 15.0 -0.273797047918 -0.0656752285492 -751 15.02 -0.272486158899 -0.0654139035635 -752 15.04 -0.271180482599 -0.0651539551544 -753 15.06 -0.269879991575 -0.0648953744073 -754 15.08 -0.268584658563 -0.0646381524742 -755 15.1 -0.267294456476 -0.0643822805732 -756 15.12 -0.266009358398 -0.064127749988 -757 15.14 -0.264729337592 -0.0638745520673 -758 15.16 -0.263454367489 -0.0636226782243 -759 15.18 -0.262184421693 -0.0633721199364 -760 15.2 -0.260919473977 -0.0631228687444 -761 15.22 -0.259659498285 -0.062874916252 -762 15.24 -0.258404468725 -0.0626282541256 -763 15.26 -0.257154359572 -0.0623828740934 -764 15.28 -0.255909145268 -0.0621387679452 -765 15.3 -0.254668800416 -0.061895927532 -766 15.32 -0.253433299783 -0.061654344765 -767 15.34 -0.252202618295 -0.0614140116156 -768 15.36 -0.250976731041 -0.0611749201148 -769 15.38 -0.249755613266 -0.0609370623526 -770 15.4 -0.248539240374 -0.0607004304776 -771 15.42 -0.247327587926 -0.0604650166966 -772 15.44 -0.246120631637 -0.0602308132741 -773 15.46 -0.244918347377 -0.0599978125317 -774 15.48 -0.243720711169 -0.0597660068478 -775 15.5 -0.242527699187 -0.0595353886571 -776 15.52 -0.241339287756 -0.05930595045 -777 15.54 -0.240155453352 -0.0590776847726 -778 15.56 -0.238976172597 -0.0588505842256 -779 15.58 -0.237801422264 -0.0586246414643 -780 15.6 -0.236631179269 -0.0583998491983 -781 15.62 -0.235465420674 -0.0581762001905 -782 15.64 -0.234304123687 -0.057953687257 -783 15.66 -0.233147265658 -0.057732303267 -784 15.68 -0.231994824078 -0.0575120411416 -785 15.7 -0.23084677658 -0.0572928938542 -786 15.72 -0.229703100938 -0.0570748544293 -787 15.74 -0.228563775063 -0.0568579159429 -788 15.76 -0.227428777006 -0.0566420715213 -789 15.78 -0.226298084954 -0.0564273143414 -790 15.8 -0.22517167723 -0.0562136376296 -791 15.82 -0.224049532291 -0.0560010346619 -792 15.84 -0.222931628729 -0.0557894987635 -793 15.86 -0.22181794527 -0.0555790233081 -794 15.88 -0.220708460771 -0.0553696017175 -795 15.9 -0.21960315422 -0.0551612274618 -796 15.92 -0.218502004734 -0.0549538940582 -797 15.94 -0.217404991561 -0.0547475950712 -798 15.96 -0.216312094077 -0.0545423241119 -799 15.98 -0.215223291785 -0.0543380748379 -800 16.0 -0.214138564315 -0.0541348409526 -801 16.02 -0.21305789142 -0.0539326162051 -802 16.04 -0.21198125298 -0.0537313943897 -803 16.06 -0.210908628999 -0.0535311693457 -804 16.08 -0.209839999602 -0.0533319349567 -805 16.1 -0.208775345037 -0.0531336851505 -806 16.12 -0.207714645672 -0.0529364138987 -807 16.14 -0.206657881997 -0.0527401152166 -808 16.16 -0.205605034619 -0.0525447831621 -809 16.18 -0.204556084266 -0.0523504118362 -810 16.2 -0.20351101178 -0.0521569953823 -811 16.22 -0.202469798123 -0.0519645279856 -812 16.24 -0.201432424372 -0.0517730038733 -813 16.26 -0.200398871718 -0.0515824173138 -814 16.28 -0.199369121467 -0.0513927626166 -815 16.3 -0.198343155039 -0.051204034132 -816 16.32 -0.197320953965 -0.0510162262506 -817 16.34 -0.196302499889 -0.050829333403 -818 16.36 -0.195287774565 -0.0506433500599 -819 16.38 -0.194276759859 -0.0504582707309 -820 16.4 -0.193269437746 -0.0502740899651 -821 16.42 -0.192265790306 -0.0500908023503 -822 16.44 -0.191265799733 -0.0499084025129 -823 16.46 -0.190269448323 -0.0497268851171 -824 16.48 -0.189276718481 -0.0495462448654 -825 16.5 -0.188287592716 -0.0493664764977 -826 16.52 -0.187302053643 -0.0491875747911 -827 16.54 -0.186320083981 -0.0490095345599 -828 16.56 -0.185341666552 -0.0488323506547 -829 16.58 -0.18436678428 -0.0486560179629 -830 16.6 -0.183395420192 -0.0484805314077 -831 16.62 -0.182427557417 -0.0483058859483 -832 16.64 -0.181463179181 -0.0481320765793 -833 16.66 -0.180502268813 -0.0479590983305 -834 16.68 -0.179544809739 -0.0477869462668 -835 16.7 -0.178590785487 -0.0476156154877 -836 16.72 -0.177640179677 -0.0474451011271 -837 16.74 -0.176692976031 -0.0472753983531 -838 16.76 -0.175749158364 -0.0471065023674 -839 16.78 -0.174808710589 -0.0469384084057 -840 16.8 -0.173871616713 -0.0467711117367 -841 16.82 -0.172937860836 -0.0466046076623 -842 16.84 -0.172007427154 -0.0464388915171 -843 16.86 -0.171080299953 -0.0462739586683 -844 16.88 -0.170156463616 -0.0461098045155 -845 16.9 -0.169235902612 -0.04594642449 -846 16.92 -0.168318601505 -0.0457838140552 -847 16.94 -0.167404544949 -0.0456219687059 -848 16.96 -0.166493717686 -0.0454608839681 -849 16.98 -0.165586104549 -0.0453005553988 -850 17.0 -0.164681690459 -0.045140978586 -851 17.02 -0.163780460423 -0.044982149148 -852 17.04 -0.162882399539 -0.0448240627335 -853 17.06 -0.161987492989 -0.0446667150213 -854 17.08 -0.161095726042 -0.0445101017198 -855 17.1 -0.160207084053 -0.0443542185673 -856 17.12 -0.15932155246 -0.0441990613312 -857 17.14 -0.158439116788 -0.0440446258081 -858 17.16 -0.157559762644 -0.0438909078236 -859 17.18 -0.156683475719 -0.0437379032318 -860 17.2 -0.155810241787 -0.0435856079154 -861 17.22 -0.154940046702 -0.0434340177851 -862 17.24 -0.154072876401 -0.0432831287799 -863 17.26 -0.153208716903 -0.0431329368663 -864 17.28 -0.152347554306 -0.0429834380385 -865 17.3 -0.151489374787 -0.0428346283181 -866 17.32 -0.150634164605 -0.0426865037537 -867 17.34 -0.149781910096 -0.0425390604208 -868 17.36 -0.148932597673 -0.0423922944219 -869 17.38 -0.148086213829 -0.0422462018856 -870 17.4 -0.147242745133 -0.0421007789672 -871 17.42 -0.146402178232 -0.0419560218477 -872 17.44 -0.145564499846 -0.0418119267343 -873 17.46 -0.144729696774 -0.0416684898597 -874 17.48 -0.143897755889 -0.0415257074823 -875 17.5 -0.143068664136 -0.0413835758856 -876 17.52 -0.142242408539 -0.0412420913782 -877 17.54 -0.141418976192 -0.0411012502937 -878 17.56 -0.140598354262 -0.0409610489904 -879 17.58 -0.139780529991 -0.0408214838511 -880 17.6 -0.138965490691 -0.040682551283 -881 17.62 -0.138153223746 -0.0405442477172 -882 17.64 -0.137343716613 -0.0404065696091 -883 17.66 -0.136536956816 -0.0402695134376 -884 17.68 -0.135732931952 -0.0401330757054 -885 17.7 -0.134931629688 -0.0399972529384 -886 17.72 -0.134133037758 -0.0398620416858 -887 17.74 -0.133337143966 -0.0397274385201 -888 17.76 -0.132543936186 -0.0395934400363 -889 17.78 -0.131753402356 -0.0394600428522 -890 17.8 -0.130965530486 -0.0393272436083 -891 17.82 -0.130180308648 -0.0391950389674 -892 17.84 -0.129397724985 -0.0390634256142 -893 17.86 -0.128617767704 -0.0389324002559 -894 17.88 -0.127840425077 -0.0388019596211 -895 17.9 -0.127065685442 -0.0386721004602 -896 17.92 -0.126293537203 -0.0385428195454 -897 17.94 -0.125523968827 -0.0384141136698 -898 17.96 -0.124756968844 -0.038285979648 -899 17.98 -0.12399252585 -0.0381584143155 -900 18.0 -0.123230628501 -0.0380314145287 -901 18.02 -0.122471265519 -0.0379049771648 -902 18.04 -0.121714425686 -0.0377790991214 -903 18.06 -0.120960097846 -0.0376537773164 -904 18.08 -0.120208270905 -0.0375290086883 -905 18.1 -0.119458933831 -0.0374047901954 -906 18.12 -0.11871207565 -0.0372811188161 -907 18.14 -0.117967685451 -0.0371579915483 -908 18.16 -0.117225752381 -0.0370354054099 -909 18.18 -0.116486265647 -0.0369133574381 -910 18.2 -0.115749214515 -0.0367918446895 -911 18.22 -0.11501458831 -0.0366708642398 -912 18.24 -0.114282376416 -0.0365504131839 -913 18.26 -0.113552568273 -0.0364304886354 -914 18.28 -0.11282515338 -0.0363110877269 -915 18.3 -0.112100121292 -0.0361922076096 -916 18.32 -0.111377461622 -0.0360738454529 -917 18.34 -0.110657164039 -0.0359559984449 -918 18.36 -0.109939218269 -0.0358386637917 -919 18.38 -0.109223614091 -0.0357218387177 -920 18.4 -0.108510341341 -0.0356055204649 -921 18.42 -0.107799389911 -0.0354897062933 -922 18.44 -0.107090749747 -0.0353743934808 -923 18.46 -0.106384410848 -0.0352595793223 -924 18.48 -0.105680363268 -0.0351452611307 -925 18.5 -0.104978597114 -0.0350314362357 -926 18.52 -0.104279102547 -0.0349181019845 -927 18.54 -0.103581869781 -0.0348052557411 -928 18.56 -0.102886889082 -0.0346928948865 -929 18.58 -0.102194150767 -0.0345810168186 -930 18.6 -0.101503645208 -0.0344696189517 -931 18.62 -0.100815362825 -0.0343586987167 -932 18.64 -0.100129294092 -0.0342482535611 -933 18.66 -0.0994454295322 -0.0341382809484 -934 18.68 -0.0987637597204 -0.0340287783585 -935 18.7 -0.0980842752811 -0.0339197432873 -936 18.72 -0.0974069668887 -0.0338111732465 -937 18.74 -0.0967318252675 -0.0337030657637 -938 18.76 -0.0960588411908 -0.0335954183822 -939 18.78 -0.0953880054812 -0.0334882286609 -940 18.8 -0.0947193090095 -0.0333814941741 -941 18.82 -0.0940527426954 -0.0332752125115 -942 18.84 -0.0933882975062 -0.0331693812782 -943 18.86 -0.0927259644573 -0.033063998094 -944 18.88 -0.0920657346112 -0.0329590605941 -945 18.9 -0.0914075990779 -0.0328545664286 -946 18.92 -0.0907515490141 -0.0327505132621 -947 18.94 -0.0900975756229 -0.0326468987742 -948 18.96 -0.089445670154 -0.032543720659 -949 18.98 -0.0887958239027 -0.0324409766249 -950 19.0 -0.0881480282103 -0.032338664395 -951 19.02 -0.0875022744633 -0.0322367817064 -952 19.04 -0.0868585540934 -0.0321353263106 -953 19.06 -0.0862168585771 -0.0320342959728 -954 19.08 -0.0855771794356 -0.0319336884725 -955 19.1 -0.084939508234 -0.0318335016031 -956 19.12 -0.0843038365819 -0.0317337331714 -957 19.14 -0.0836701561321 -0.0316343809981 -958 19.16 -0.0830384585813 -0.0315354429176 -959 19.18 -0.0824087356692 -0.0314369167774 -960 19.2 -0.0817809791782 -0.0313388004388 -961 19.22 -0.0811551809338 -0.031241091776 -962 19.24 -0.0805313328034 -0.0311437886765 -963 19.26 -0.079909426697 -0.031046889041 -964 19.28 -0.079289454566 -0.030950390783 -965 19.3 -0.0786714084036 -0.0308542918291 -966 19.32 -0.0780552802445 -0.0307585901186 -967 19.34 -0.0774410621642 -0.0306632836034 -968 19.36 -0.0768287462793 -0.0305683702482 -969 19.38 -0.0762183247467 -0.0304738480301 -970 19.4 -0.0756097897639 -0.0303797149388 -971 19.42 -0.0750031335683 -0.0302859689762 -972 19.44 -0.0743983484373 -0.0301926081566 -973 19.46 -0.0737954266876 -0.0300996305063 -974 19.48 -0.0731943606756 -0.0300070340638 -975 19.5 -0.0725951427967 -0.0299148168796 -976 19.52 -0.071997765485 -0.0298229770161 -977 19.54 -0.0714022212134 -0.0297315125477 -978 19.56 -0.0708085024932 -0.0296404215602 -979 19.58 -0.0702166018738 -0.0295497021514 -980 19.6 -0.0696265119425 -0.0294593524306 -981 19.62 -0.0690382253245 -0.0293693705184 -982 19.64 -0.0684517346822 -0.0292797545471 -983 19.66 -0.0678670327154 -0.0291905026603 -984 19.68 -0.0672841121609 -0.0291016130126 -985 19.7 -0.0667029657922 -0.0290130837702 -986 19.72 -0.0661235864195 -0.02892491311 -987 19.74 -0.0655459668893 -0.0288370992202 -988 19.76 -0.0649701000843 -0.0287496402998 -989 19.78 -0.0643959789228 -0.0286625345588 -990 19.8 -0.0638235963592 -0.028575780218 -991 19.82 -0.0632529453832 -0.0284893755087 -992 19.84 -0.0626840190197 -0.0284033186731 -993 19.86 -0.0621168103288 -0.0283176079638 -994 19.88 -0.0615513124053 -0.0282322416441 -995 19.9 -0.0609875183786 -0.0281472179874 -996 19.92 -0.0604254214128 -0.0280625352778 -997 19.94 -0.0598650147059 -0.0279781918096 -998 19.96 -0.0593062914901 -0.027894185887 -999 19.98 -0.0587492450313 -0.0278105158248 -1000 20.0 -0.0581938686292 -0.0277271799475 -1001 20.02 -0.0576401556166 -0.0276441765898 -1002 20.04 -0.0570880993599 -0.0275615040963 -1003 20.06 -0.056537693258 -0.0274791608214 -1004 20.08 -0.0559889307431 -0.0273971451294 -1005 20.1 -0.0554418052798 -0.0273154553941 -1006 20.12 -0.0548963103651 -0.0272340899992 -1007 20.14 -0.0543524395283 -0.0271530473379 -1008 20.16 -0.0538101863307 -0.027072325813 -1009 20.18 -0.0532695443654 -0.0269919238365 -1010 20.2 -0.0527305072574 -0.0269118398301 -1011 20.22 -0.0521930686629 -0.0268320722247 -1012 20.24 -0.0516572222695 -0.0267526194605 -1013 20.26 -0.0511229617959 -0.0266734799867 -1014 20.28 -0.0505902809917 -0.0265946522621 -1015 20.3 -0.0500591736373 -0.026516134754 -1016 20.32 -0.0495296335436 -0.0264379259393 -1017 20.34 -0.0490016545518 -0.0263600243033 -1018 20.36 -0.0484752305336 -0.0262824283405 -1019 20.38 -0.0479503553904 -0.0262051365543 -1020 20.4 -0.0474270230535 -0.0261281474567 -1021 20.42 -0.0469052274841 -0.0260514595684 -1022 20.44 -0.0463849626725 -0.0259750714189 -1023 20.46 -0.0458662226388 -0.0258989815462 -1024 20.48 -0.0453490014319 -0.0258231884968 -1025 20.5 -0.0448332931297 -0.0257476908257 -1026 20.52 -0.0443190918392 -0.0256724870964 -1027 20.54 -0.0438063916958 -0.0255975758806 -1028 20.56 -0.0432951868634 -0.0255229557586 -1029 20.58 -0.0427854715342 -0.0254486253186 -1030 20.6 -0.0422772399288 -0.0253745831572 -1031 20.62 -0.0417704862954 -0.0253008278792 -1032 20.64 -0.0412652049103 -0.0252273580972 -1033 20.66 -0.0407613900774 -0.0251541724321 -1034 20.68 -0.040259036128 -0.0250812695126 -1035 20.7 -0.039758137421 -0.0250086479756 -1036 20.72 -0.0392586883422 -0.0249363064654 -1037 20.74 -0.0387606833045 -0.0248642436347 -1038 20.76 -0.0382641167479 -0.0247924581434 -1039 20.78 -0.0377689831387 -0.0247209486595 -1040 20.8 -0.0372752769703 -0.0246497138585 -1041 20.82 -0.036782992762 -0.0245787524235 -1042 20.84 -0.0362921250596 -0.0245080630453 -1043 20.86 -0.0358026684351 -0.0244376444219 -1044 20.88 -0.0353146174863 -0.0243674952592 -1045 20.9 -0.0348279668369 -0.0242976142701 -1046 20.92 -0.0343427111362 -0.0242280001751 -1047 20.94 -0.0338588450591 -0.0241586517019 -1048 20.96 -0.0333763633058 -0.0240895675856 -1049 20.98 -0.0328952606017 -0.0240207465683 -1050 21.0 -0.0324155316974 -0.0239521873994 -1051 21.02 -0.0319371713684 -0.0238838888354 -1052 21.04 -0.0314601744149 -0.0238158496399 -1053 21.06 -0.0309845356618 -0.0237480685835 -1054 21.08 -0.0305102499587 -0.0236805444437 -1055 21.1 -0.0300373121794 -0.0236132760051 -1056 21.12 -0.0295657172219 -0.023546262059 -1057 21.14 -0.0290954600085 -0.0234795014037 -1058 21.16 -0.0286265354851 -0.0234129928442 -1059 21.18 -0.028158938622 -0.0233467351922 -1060 21.2 -0.0276926644126 -0.0232807272662 -1061 21.22 -0.0272277078743 -0.0232149678915 -1062 21.24 -0.0267640640477 -0.0231494558997 -1063 21.26 -0.0263017279969 -0.0230841901292 -1064 21.28 -0.0258406948088 -0.0230191694249 -1065 21.3 -0.0253809595937 -0.0229543926381 -1066 21.32 -0.0249225174848 -0.0228898586266 -1067 21.34 -0.0244653636377 -0.0228255662547 -1068 21.36 -0.0240094932312 -0.0227615143929 -1069 21.38 -0.0235549014661 -0.0226977019182 -1070 21.4 -0.023101583566 -0.0226341277136 -1071 21.42 -0.0226495347765 -0.0225707906687 -1072 21.44 -0.0221987503655 -0.0225076896791 -1073 21.46 -0.021749225623 -0.0224448236465 -1074 21.48 -0.0213009558606 -0.0223821914788 -1075 21.5 -0.020853936412 -0.02231979209 -1076 21.52 -0.0204081626323 -0.0222576244002 -1077 21.54 -0.0199636298985 -0.0221956873354 -1078 21.56 -0.0195203336085 -0.0221339798275 -1079 21.58 -0.0190782691821 -0.0220725008144 -1080 21.6 -0.0186374320597 -0.02201124924 -1081 21.62 -0.0181978177032 -0.0219502240539 -1082 21.64 -0.0177594215953 -0.0218894242115 -1083 21.66 -0.0173222392394 -0.0218288486741 -1084 21.68 -0.0168862661598 -0.0217684964086 -1085 21.7 -0.0164514979014 -0.0217083663878 -1086 21.72 -0.0160179300295 -0.0216484575898 -1087 21.74 -0.0155855581298 -0.0215887689986 -1088 21.76 -0.0151543778082 -0.0215292996039 -1089 21.78 -0.014724384691 -0.0214700484006 -1090 21.8 -0.0142955744243 -0.0214110143895 -1091 21.82 -0.0138679426741 -0.0213521965765 -1092 21.84 -0.0134414851265 -0.0212935939733 -1093 21.86 -0.013016197487 -0.0212352055967 -1094 21.88 -0.0125920754809 -0.0211770304692 -1095 21.9 -0.012169114853 -0.0211190676184 -1096 21.92 -0.0117473113675 -0.0210613160772 -1097 21.94 -0.0113266608076 -0.021003774884 -1098 21.96 -0.0109071589762 -0.0209464430823 -1099 21.98 -0.0104888016947 -0.0208893197208 -1100 22.0 -0.010071584804 -0.0208324038534 -1101 22.02 -0.00965550416359 -0.0207756945391 -1102 22.04 -0.0092405556517 -0.020719190842 -1103 22.06 -0.00882673516534 -0.0206628918315 -1104 22.08 -0.00841403862003 -0.0206067965819 -1105 22.1 -0.0080024619498 -0.0205509041723 -1106 22.12 -0.00759200110698 -0.0204952136871 -1107 22.14 -0.00718265206222 -0.0204397242155 -1108 22.16 -0.00677441080431 -0.0203844348517 -1109 22.18 -0.00636727334011 -0.0203293446947 -1110 22.2 -0.00596123569445 -0.0202744528484 -1111 22.22 -0.00555629391005 -0.0202197584216 -1112 22.24 -0.00515244404737 -0.0201652605278 -1113 22.26 -0.00474968218459 -0.0201109582853 -1114 22.28 -0.00434800441746 -0.0200568508172 -1115 22.3 -0.00394740685922 -0.0200029372512 -1116 22.32 -0.00354788564052 -0.0199492167196 -1117 22.34 -0.0031494369093 -0.0198956883597 -1118 22.36 -0.00275205683071 -0.0198423513132 -1119 22.38 -0.00235574158704 -0.0197892047262 -1120 22.4 -0.00196048737759 -0.0197362477497 -1121 22.42 -0.00156629041861 -0.0196834795391 -1122 22.44 -0.00117314694319 -0.0196308992543 -1123 22.46 -0.000781053201174 -0.0195785060596 -1124 22.48 -0.000390005459079 -0.019526299124 -1125 22.5 0.0 -0.0194742776206 -1126 22.52 0.0 0.0 -1127 22.54 0.0 0.0 -1128 22.56 0.0 0.0 -1129 22.58 0.0 0.0 -1130 22.6 0.0 0.0 diff --git a/tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/packmol_files/README.sh b/tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/packmol_files/README.sh deleted file mode 100755 index 2fe282995a..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/packmol_files/README.sh +++ /dev/null @@ -1,33 +0,0 @@ -# Here we generate the starting coordinates of the simulation -# using PACKMOL. - - - -# You must run each packmol commend one after the other. -# NOTE: If PACKMOL gets stuck in an endless loop, then edit the corresponding -# "inp" file. This should not happen. You can also usually interrupt -# packmol after 30 minutes, and the solution at that point (an .xyz file) -# should be good enough for use. -packmol < step1_proteins.inp # This step determines the protein's location - # It takes ~20 minutes (on an intel i7) -packmol < step2_innerlayer.inp # this step builds the inner monolayer - # It takes ~90 minutes -packmol < step3_outerlayer.inp # this step builds the outer monolayer - # It takes ~4 hours - - -# NOTE: PLEASE USE "packmol", NOT "ppackmol". ("ppackmol" is the -# parallel-version of packmol using OpemMP. This example has NOT been -# tested with "ppackmol". Our impression was that the "ppackmol" -# version is more likely to get stuck in an infinite loop. -Andrew 2015-8) - - -# Step3 creates a file named "step3_outerlayer.xyz" containing the coordinates -# in all the atoms of all the molecules. Later we will run moltemplate.sh -# using the "-xyz ../system.xyz" command line argument. That will instruct -# moltemplate to look for a file named "system.xyz" in the parent directory. -# So I rename the "step3_outerlayer.xyz" file to "system.xyz", and move it -# to this directory so that later moltemplate.sh can find it. - -mv -f step3_outerlayer.xyz ../system.xyz - diff --git a/tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/packmol_files/step1_proteins.inp b/tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/packmol_files/step1_proteins.inp deleted file mode 100644 index abb48db7d6..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/packmol_files/step1_proteins.inp +++ /dev/null @@ -1,49 +0,0 @@ -# Step 1: Create a sphere of proteins lying -# (In step 2 we will pack lipids around these proteins -# -# ----- Run using: ----- -# packmol < step1_proteins.inp -# (This takes about 30 minutes on an Intel i7 processor) - - -# ----- Settings: ----- - -# All the atoms from diferent proteins will be at least 50.0 Angstrons apart. -tolerance 50.0 -# (Setting "discale" to 2.0 increases the typical separation -# distance to approximately 2.0*50.0 = 100.0 Angstroms.) -discale 2.0 -# The other parameters below are optional: -nloop 10000 -maxit 20 -seed 12345 -sidemax 3000.0 -# What fraction of the molecules are moved during "large moves"? (default 0.05) -movefrac 0.05 - - -# The output file name - -output step1_proteins.xyz - - -# File types are in xyz format - -filetype xyz - - - -# First, specify the protein inclusions -# We will pack the lipids around these later - -structure protein.xyz - number 120 - atoms 68 69 70 - inside sphere 0. 0. 0. 273.75 - end atoms - atoms 65 66 67 71 72 73 - outside sphere 0. 0. 0. 325.0 - end atoms -end structure - - diff --git a/tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/packmol_files/step2_innerlayer.inp b/tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/packmol_files/step2_innerlayer.inp deleted file mode 100644 index 9f61960f2e..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/packmol_files/step2_innerlayer.inp +++ /dev/null @@ -1,70 +0,0 @@ -# NOTE: YOU MUST COMPLETE STEP 1 BEFORE RUNNING PACKMOL ON THIS FILE - -# Step 2: Pack the lipids in the inner monolayer around the proteins from step1. -# -# ----- Run using: ----- -# packmol < step2_innerlayer.inp -# (This takes about 90 minutes on an Intel i7 processor) - - -# ----- Settings: ----- - -# All the atoms from diferent molecules will be at least 5.5 Angstrons apart -tolerance 5.5 -# (Setting "discale" to 1.4 increases the typical separation -# distance to approximately 1.4*5.5 = 7.7 Angstroms.) -discale 1.4 -# The other parameters below are optional: -nloop 10000 -maxit 20 -seed 12345 -sidemax 3000.0 -# What fraction of the molecules are moved during "large moves"? (default 0.05) -movefrac 0.05 - - -# The output file name - -output step2_innerlayer.xyz - -# File types are in xyz format - -filetype xyz - - -# The proteins whose position we determined earlier in step 1 -# will be frozen in place during this step. - -structure step1_proteins.xyz - number 1 - fixed 0. 0. 0. 0. 0. 0. -end structure - - -# 9500 DPPC lipids will be put in a shell with their hydrophilic heads -# (atom 1) pointing inwards, and their tails (atom 5) pointing outwards. - - -structure DPPC.xyz - number 9500 - atoms 1 - inside sphere 0. 0. 0. 270.0 - end atoms - atoms 5 - outside sphere 0. 0. 0. 295.0 - end atoms -end structure - -# 9500 DLPC lipids will be put in a shell with their hydrophilic heads -# (atom 1) pointing inwards, and their tails (atom 4) pointing outwards. - -structure DLPC.xyz - number 9500 - atoms 1 - inside sphere 0. 0. 0. 273.0 - end atoms - atoms 4 - outside sphere 0. 0. 0. 295.0 - end atoms -end structure - diff --git a/tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/packmol_files/step3_outerlayer.inp b/tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/packmol_files/step3_outerlayer.inp deleted file mode 100644 index bed1c04246..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/packmol_files/step3_outerlayer.inp +++ /dev/null @@ -1,70 +0,0 @@ -# NOTE: YOU MUST COMPLETE STEPS 1 AND 2 BEFORE RUNNING PACKMOL ON THIS FILE - -# Step 3: Pack the lipids in the outer monolayer around the proteins from step1. -# -# ----- Run using: ----- -# packmol < step3_outerlayer.inp -# (This takes about 4 hours on an Intel i7 processor) - - -# ----- Settings: ----- - -# All the atoms from diferent molecules will be at least 5.5 Angstrons apart -tolerance 5.5 -# (Setting "discale" to 1.4 increases the typical separation -# distance to approximately 1.4*5.5 = 7.7 Angstroms.) -discale 1.4 -# The other parameters below are optional: -nloop 10000 -maxit 20 -seed 12345 -sidemax 3000.0 -# What fraction of the molecules are moved during "large moves"? (default 0.05) -movefrac 0.05 - - -# The output file name - -output step3_outerlayer.xyz - -# File types are in xyz format - -filetype xyz - - -# The proteins and lipids whose position we determined earlier in steps 1-2 -# will be frozen in place during this step. - -structure step2_innerlayer.xyz - number 1 - fixed 0. 0. 0. 0. 0. 0. -end structure - - -# 12500 DPPC lipids will be put in a shell with their hydrophilic heads -# (atom 1) pointing outwards, and their tails (atom 5) pointing inwards. - - -structure DPPC.xyz - number 12500 - atoms 5 - inside sphere 0. 0. 0. 310.0 - end atoms - atoms 1 - outside sphere 0. 0. 0. 336.0 - end atoms -end structure - -# 12500 DLPC lipids will be put in a shell with their hydrophilic heads -# (atom 1) pointing outwards, and their tails (atom 4) pointing inwards. - -structure DLPC.xyz - number 12500 - atoms 4 - inside sphere 0. 0. 0. 313.0 - end atoms - atoms 1 - outside sphere 0. 0. 0. 332.0 - end atoms -end structure - diff --git a/tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/run.in.min b/tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/run.in.min deleted file mode 100644 index 25ed25ad77..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/run.in.min +++ /dev/null @@ -1,50 +0,0 @@ -# -------- REQUIREMENTS: --------- -# 1) This example requires the "USER-MISC" package. (Use "make yes-USER-MISC") -# http://lammps.sandia.gov/doc/Section_start.html#start_3 -# 2) It also may require additional features and bug fixes for LAMMPS. -# So, after typing "make yes-user-misc" in to the shell, ... -# be sure to download and copy the "additional_lammps_code" from -# http://moltemplate.org (upper-left corner menu) -# 3) Unpack it -# 4) copy the .cpp and .h files to the src folding of your lammps installation. -# 5) Compile LAMMPS. -# -# If LAMMPS complains about an "Invalid pair_style", or "Invalid dihedral_style" -# then you made a mistake in the instructions above. - - - -# -- Init section -- - -include system.in.init - -# -- Atom definition section -- - -read_data system.data - -# -- Settings Section -- - -include system.in.settings - -# -- Run section -- - -dump 1 all custom 250 traj_min.lammpstrj id mol type x y z ix iy iz - -# minimize - -#balance 1.3 rcb - -min_style quickmin -min_modify dmax 0.1 -minimize 1.0e-5 1.0e-7 5000 20000 - -# If minimization crashes, then instead try Langevin dynamics -# with a small timestep and a fast damping parameter. For example: -# -# timestep 0.05 -# fix fxlan all langevin 300.0 300.0 100.0 48279 -# fix fxnve all nve -# -# run 10000 - -write_data system_after_min.data diff --git a/tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/run.in.nvt b/tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/run.in.nvt deleted file mode 100644 index 253c042670..0000000000 --- a/tools/moltemplate/examples/coarse_grained_examples/vesicle_Brannigan2005+Bellesia2010/run.in.nvt +++ /dev/null @@ -1,63 +0,0 @@ -# -------- REQUIREMENTS: --------- -# 1) This example requires the "USER-MISC" package. (Use "make yes-USER-MISC") -# http://lammps.sandia.gov/doc/Section_start.html#start_3 -# 2) It also may require additional features and bug fixes for LAMMPS. -# So, after typing "make yes-user-misc" in to the shell, ... -# be sure to download and copy the "additional_lammps_code" from -# http://moltemplate.org (upper-left corner menu) -# 3) Unpack it -# 4) copy the .cpp and .h files to the src folding of your lammps installation. -# 5) Compile LAMMPS. -# -# If LAMMPS complains about an "Invalid pair_style", or "Invalid dihedral_style" -# then you made a mistake in the instructions above. -# -# ------------------------------- Initialization Section -------------------- - -include system.in.init - -# ------------------------------- Atom Definition Section ------------------- - -# Commenting out: -# -# read_data system.data -# -# Instead read the data file created by "run.in.min". - -read_data system_after_min.data - -# ------------------------------- Settings Section -------------------------- - -include system.in.settings - -# ------------------------------- Run Section ------------------------------- - -# Just in case the previous minimization failed, try again. -# (I don't know why this helps, but sometimes it does. Magic.) - -minimize 1.0e-5 1.0e-7 5000 20000 - -# Run main simulation - -timestep 10.0 # The time-step in Watson et. al 2011 was 0.002*3ps = 6fs -dump 1 all custom 2500 traj_nvt.lammpstrj id mol type x y z ix iy iz - - -thermo_style custom step temp pe etotal vol epair ebond eangle -thermo 100 # time interval for printing out "thermo" data - - - - -fix fxlan all langevin 300.0 300.0 120 48279 -fix fxnve all nve - -# Note: The energy scale "epsilon" = 2.75kJ/mole = 330.7485200981 Kelvin*kB. -# So a temperature of 300.0 Kelvin corresponds to 0.907033536873*epsilon. -# Note: The langevin damping parameter "120" corresponds to -# the 0.12ps damping time used in Watson et. al JCP 2011. - -run 1000000 - -write_data system_after_nvt.data - diff --git a/tools/moltemplate/examples/file_conversion_examples/convert_LAMMPS_to_LT_examples/cnad-cnt/README_FIRST.TXT b/tools/moltemplate/examples/file_conversion_examples/convert_LAMMPS_to_LT_examples/cnad-cnt/README_FIRST.TXT deleted file mode 100644 index d69f1d6ffa..0000000000 --- a/tools/moltemplate/examples/file_conversion_examples/convert_LAMMPS_to_LT_examples/cnad-cnt/README_FIRST.TXT +++ /dev/null @@ -1,83 +0,0 @@ -########################################################### -# Interaction of a carbon nanotube with a pair of "mystery -# molecules" (extracted from the cnat-cnt.data/in files). -########################################################### -# Author: Aysun Itai and Andrew Jewett - -This example uses "ltemplify.py" to create molecule templates out -of two different molecules in a pre-existing LAMMPS IN/DATA file. -Then I show how to use "moltemplate.sh" to make copies of these -molecules and to move and rotate them (creating new LAMMPS IN/DATA files). - - Disclaimer: -The molecules in this example are not physically realistic. -The purpose of this example is to demonstrate ltemplify usage. - - REQUIRED INPUT FILES - -cnad-cnt.data cnad-cnt.in system.lt - - cnad-cnt.data - This is a LAMMPS data file containing the coordinates and the topology - for a system combining the two molecules together. ltemplify will extract - molecules from this file, one at a time. - - cnad-cnt.in - This file contains force-field parameters and old run settings for the system. - (We ignore the run settings in this file.) The force-field parameters in - the "cnad-cnt.in" file are only necessary because we are going to build - a completely new set of simulation input files. (We are not only going to - rotate them and duplicate the molecules.) ltemplify.py will extract the - force field parameters from this file. This approach allows us to combine - these molecules with other types of molecules later on.) - - system.lt - The "system.lt" contains the instructions what we will do with these molecules - after ltemplify.py has converted them into .LT format. In this example - it contains instructions for rotating and copying the two molecules, - (It also defines the periodic boundary conditions.) - - OUTPUT FILES - -cnad.lt -cnt.lt - -These files are referenced in system.lt. -Running moltemplate.sh on system.lt (using "moltemplate.sh system.lt") -creates new LAMMPS data and input files: -system.data, system.in, system.in.init, system.in.settings -(These files are referenced in run.in.nvt.) - -You can run a simulation from the files created by moltemplate using - -lmp_linux -i run.in.nvt - -NOTE: BECAUSE ALL OF THE ORIGINAL FORCE FIELD PARAMETERS WERE INTENTIONALLY - ALTERED, THE SYSTEM WILL MOVE IN A VERY UNREALISTIC WAY WHEN SIMULATED. - (This was done to protect the original source of the files.) - The goal of this example is only to demonstrate how to use - "ltemplify.py" to convert lammps input and data files into - LT format and back again.) - - ----------- - -Instructions: -Run the commands (follow the instructions) in these files: - -step 1) -README_step1_run_ltemplify.sh - -and then - -step 2) -README_step2_run_moltemplate.sh - -step 3) OPTIONAL - -To run a short LAMMPS simulation, you can use the "in.nvt" file, for example: - -$LAMMPS_BINARY -i run.in.nvt - -where "$LAMMPS_BINARY" is the name of the command you use to invoke lammps -(such as lmp_linux, lmp_g++, lmp_mac, lmp_ubuntu, lmp_cygwin, etc...). - ----------- diff --git a/tools/moltemplate/examples/file_conversion_examples/convert_LAMMPS_to_LT_examples/cnad-cnt/README_step1_run_ltemplify.sh b/tools/moltemplate/examples/file_conversion_examples/convert_LAMMPS_to_LT_examples/cnad-cnt/README_step1_run_ltemplify.sh deleted file mode 100755 index 4bb42d7ea6..0000000000 --- a/tools/moltemplate/examples/file_conversion_examples/convert_LAMMPS_to_LT_examples/cnad-cnt/README_step1_run_ltemplify.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh - -# Aysun Itai's LAMMPS files contain two molecules: - -# The CNAD molecule has molecule-id 1 - -ltemplify.py -name CNAD -molid "1" cnad-cnt.in cnad-cnt.data > cnad.lt - -# The CNT (carbon nanotube) corresponds to molecule-id 2 -ltemplify.py -name CNT -molid "2" cnad-cnt.in cnad-cnt.data > cnt.lt - -# This will extract both molecules and save them as separate .LT files. -# (We can include these files later when preparing new simulations.) diff --git a/tools/moltemplate/examples/file_conversion_examples/convert_LAMMPS_to_LT_examples/cnad-cnt/README_step2_run_moltemplate.sh b/tools/moltemplate/examples/file_conversion_examples/convert_LAMMPS_to_LT_examples/cnad-cnt/README_step2_run_moltemplate.sh deleted file mode 100755 index 6903a855f9..0000000000 --- a/tools/moltemplate/examples/file_conversion_examples/convert_LAMMPS_to_LT_examples/cnad-cnt/README_step2_run_moltemplate.sh +++ /dev/null @@ -1,22 +0,0 @@ -# --- Running Moltemplate --- -# -- Prerequisites: -- -# The "system.lt" moltemplate file links to other ".lt" files -# files you hopefully have created earlier when you ran "ltemplify.py: -# cnad.lt and cnt.lt -# If not, carry out the instructions in "README_run_ltemplify.sh". - -moltemplate.sh system.lt - -# (Note: If you have VMD installed, try this instead:) -# moltemplate.sh system.lt -vmd - - -# Moltemplate will generate various files with names ending in *.in* and *.data. -# These files are the input files directly read by LAMMPS. - -# Optional: -# The "./output_ttree/" directory is full of temporary files generated by -# moltemplate. They can be useful for debugging, but are usually thrown away. - -rm -rf output_ttree/ - diff --git a/tools/moltemplate/examples/file_conversion_examples/convert_LAMMPS_to_LT_examples/cnad-cnt/README_step3_run_lammps.sh b/tools/moltemplate/examples/file_conversion_examples/convert_LAMMPS_to_LT_examples/cnad-cnt/README_step3_run_lammps.sh deleted file mode 100755 index ab9a7dc6e8..0000000000 --- a/tools/moltemplate/examples/file_conversion_examples/convert_LAMMPS_to_LT_examples/cnad-cnt/README_step3_run_lammps.sh +++ /dev/null @@ -1,16 +0,0 @@ -# --- Running LAMMPS --- -# -- Prerequisites: -- -# The "run.in.nvt" LAMMPS input script links to the input -# scripts and data files you hopefully have created earlier -# with moltemplate.sh: -# system.in.init, system.in.settings, system.data -# If not, carry out the instructions in "README_run_moltemplate.sh". -# -# -- Instructions: -- -# If "lmp_mpi" is the name of the command you use to invoke lammps, -# then you would run lammps this way: - -lmp_mpi -i run.in.nvt - -# NOTE: BECAUSE ALL OF THE ORIGINAL FORCE FIELD PARAMETERS WERE INTENTIONALLY -# REMOVED, THE SYSTEM WILL MOVE IN A VERY UNREALISTIC WAY. diff --git a/tools/moltemplate/examples/file_conversion_examples/convert_LAMMPS_to_LT_examples/cnad-cnt/README_visualize.txt b/tools/moltemplate/examples/file_conversion_examples/convert_LAMMPS_to_LT_examples/cnad-cnt/README_visualize.txt deleted file mode 100644 index 3b9be3e9c3..0000000000 --- a/tools/moltemplate/examples/file_conversion_examples/convert_LAMMPS_to_LT_examples/cnad-cnt/README_visualize.txt +++ /dev/null @@ -1,50 +0,0 @@ - - ------- To view the trajectory in VMD -------- - - -1) Build a PSF file for use in viewing with VMD. - -This step works with VMD 1.9 and topotools 1.2. -(Older versions, like VMD 1.8.6, don't support this.) - - -a) Start VMD -b) Menu Extensions->Tk Console -c) Enter: - -(I assume that the the DATA file is called "system.data") - - topo readlammpsdata system.data full - animate write psf system.psf - - -Later, to Load a trajectory in VMD: - Start VMD - Select menu: File->New Molecule - -Browse to select the PSF file you created above, and load it. - (Don't close the window yet.) - -Browse to select the trajectory file. - If necessary, for "file type" select: "LAMMPS Trajectory" - Load it - ------ Wrap the coordinates to the unit cell - -a) Start VMD -b) Load the trajectory in VMD (see above) -c) Menu Extensions->Tk Console -d) Enter: - - DISCLAIMER: I'M NOT SURE THESE COMMANDS ARE CORRECT. - LOOKUP "pbctools" FOR DETAILS. - - pbc wrap -compound res -all - pbc box - -3) Optional: If you like, change the atom types in the PSF file so - that VMD recognizes the atom types, use something like: - -sed -e 's/ 1 1 / C C /g' < system.psf > temp1.psf -sed -e 's/ 2 2 / H H /g' < temp1.psf > temp2.psf -sed -e 's/ 3 3 / P P /g' < temp2.psf > system.psf - -(If you do this, it might effect step 2 above.) diff --git a/tools/moltemplate/examples/file_conversion_examples/convert_LAMMPS_to_LT_examples/cnad-cnt/cnad-cnt.data b/tools/moltemplate/examples/file_conversion_examples/convert_LAMMPS_to_LT_examples/cnad-cnt/cnad-cnt.data deleted file mode 100644 index 1f18ff4aef..0000000000 --- a/tools/moltemplate/examples/file_conversion_examples/convert_LAMMPS_to_LT_examples/cnad-cnt/cnad-cnt.data +++ /dev/null @@ -1,1157 +0,0 @@ -Created by Aysun Itai and modified by Andrew Jewett -NOTE: This file has been extensively modified. -Only the bond connectivity and atomic positions are accurate. - - 101 atoms - 134 bonds - 252 angles - 457 dihedrals - 0 impropers - - 16 atom types - 24 bond types - 50 angle types - 78 dihedral types - 0 improper types - - 0 50 xlo xhi - 0 50 ylo yhi - 0 50 zlo zhi - -Masses - - 1 10.0 - 2 10.0 # atom type names often appear - 3 10.0 # in the comments follwing - 4 10.0 # each line in the Masses section - 5 10.0 - 6 10.0 - 7 10.0 - 8 10.0 - 9 10.0 - 10 10.0 - 11 10.0 - 12 10.0 - 13 10.0 - 14 10.0 - 15 10.0 - 16 10.0 - -Atoms - -1 2 1 0.000000 12.345 10.000 4.328 -2 2 1 0.000000 12.031 11.173 5.037 -3 2 1 0.000000 12.031 11.173 6.455 -4 2 1 0.000000 11.173 12.031 7.164 -5 2 1 0.000000 11.173 12.031 4.328 -6 2 1 0.000000 10.000 12.345 5.037 -7 2 1 0.000000 10.000 12.345 6.455 -8 2 1 0.000000 8.827 12.031 7.164 -9 2 1 0.000000 8.827 12.031 4.328 -10 2 1 0.000000 7.969 11.173 5.037 -11 2 1 0.000000 7.969 11.173 6.455 -12 2 1 0.000000 7.655 10.000 7.164 -13 2 1 0.000000 7.655 10.000 4.328 -14 2 1 0.000000 7.969 8.827 5.037 -15 2 1 0.000000 7.969 8.827 6.455 -16 2 1 0.000000 8.827 7.969 7.164 -17 2 1 0.000000 8.827 7.969 4.328 -18 2 1 0.000000 10.000 7.655 5.037 -19 2 1 0.000000 10.000 7.655 6.455 -20 2 1 0.000000 11.173 7.969 7.164 -21 2 1 0.000000 11.173 7.969 4.328 -22 2 1 0.000000 12.031 8.827 5.037 -23 2 1 0.000000 12.031 8.827 6.455 -24 2 1 0.000000 12.345 10.000 7.164 -25 2 1 0.000000 12.345 10.000 8.582 -26 2 1 0.000000 12.031 11.173 9.291 -27 2 1 0.000000 12.031 11.173 10.709 -28 2 1 0.000000 11.173 12.031 11.418 -29 2 1 0.000000 11.173 12.031 8.582 -30 2 1 0.000000 10.000 12.345 9.291 -31 2 1 0.000000 10.000 12.345 10.709 -32 2 1 0.000000 8.827 12.031 11.418 -33 2 1 0.000000 8.827 12.031 8.582 -34 2 1 0.000000 7.969 11.173 9.291 -35 2 1 0.000000 7.969 11.173 10.709 -36 2 1 0.000000 7.655 10.000 11.418 -37 2 1 0.000000 7.655 10.000 8.582 -38 2 1 0.000000 7.969 8.827 9.291 -39 2 1 0.000000 7.969 8.827 10.709 -40 2 1 0.000000 8.827 7.969 11.418 -41 2 1 0.000000 8.827 7.969 8.582 -42 2 1 0.000000 10.000 7.655 9.291 -43 2 1 0.000000 10.000 7.655 10.709 -44 2 1 0.000000 11.173 7.969 11.418 -45 2 1 0.000000 11.173 7.969 8.582 -46 2 1 0.000000 12.031 8.827 9.291 -47 2 1 0.000000 12.031 8.827 10.709 -48 2 1 0.000000 12.345 10.000 11.418 -49 2 1 0.000000 12.345 10.000 12.836 -50 2 1 0.000000 12.031 11.173 13.545 -51 2 1 0.000000 12.031 11.173 14.963 -52 2 1 0.000000 11.173 12.031 15.672 -53 2 1 0.000000 11.173 12.031 12.836 -54 2 1 0.000000 10.000 12.345 13.545 -55 2 1 0.000000 10.000 12.345 14.963 -56 2 1 0.000000 8.827 12.031 15.672 -57 2 1 0.000000 8.827 12.031 12.836 -58 2 1 0.000000 7.969 11.173 13.545 -59 2 1 0.000000 7.969 11.173 14.963 -60 2 1 0.000000 7.655 10.000 15.672 -61 2 1 0.000000 7.655 10.000 12.836 -62 2 1 0.000000 7.969 8.827 13.545 -63 2 1 0.000000 7.969 8.827 14.963 -64 2 1 0.000000 8.827 7.969 15.672 -65 2 1 0.000000 8.827 7.969 12.836 -66 2 1 0.000000 10.000 7.655 13.545 -67 2 1 0.000000 10.000 7.655 14.963 -68 2 1 0.000000 11.173 7.969 15.672 -69 2 1 0.000000 11.173 7.969 12.836 -70 2 1 0.000000 12.031 8.827 13.545 -71 2 1 0.000000 12.031 8.827 14.963 -72 2 1 0.000000 12.345 10.000 15.672 -73 1 9 -0.18 -3.365 0.678 1.133 -74 1 4 0.09 -2.854 1.624 1.417 -75 1 4 0.09 -4.302 0.58 1.719 -76 1 9 -0.09 -1.647 -0.716 0.047 -77 1 4 0.09 -1.451 -1.802 -0.11 -78 1 10 -0.18 -2.425 -0.518 1.369 -79 1 5 0.09 -1.756 -0.365 2.24 -80 1 5 0.09 -3.037 -1.427 1.561 -81 1 11 -0.09 -3.628 0.67 -0.366 -82 1 4 0.09 -3.892 1.592 -0.905 -83 1 10 -0.18 -4.015 -0.644 -0.985 -84 1 5 0.09 -4.264 -1.466 -0.292 -85 1 5 0.09 -4.56 -0.575 -1.945 -86 1 12 -0.09 -2.584 -0.196 -1.019 -87 1 4 0.09 -2.203 0.152 -1.987 -88 1 8 0.28 1.737 0.629 -0.049 -89 1 16 -0.71 1.009 1.811 -0.085 -90 1 7 0.34 -0.238 1.412 -0.066 -91 1 3 0.12 -1.102 2.079 -0.079 -92 1 14 -0.05 -0.385 0.043 -0.026 -93 1 15 -0.74 3.524 -0.923 0.002 -94 1 7 0.5 2.59 -1.876 0.037 -95 1 3 0.13 2.97 -2.901 0.072 -96 1 15 -0.75 1.258 -1.76 0.035 -97 1 8 0.43 0.895 -0.468 -0.01 -98 1 6 0.46 3.123 0.37 -0.042 -99 1 13 -0.77 4.058 1.336 -0.077 -100 1 2 0.38 5.012 1.052 -0.068 -101 1 2 0.38 3.805 2.299 -0.107 - - -Bond Coeffs - - 1 2.0 1.4 - 2 2.0 1.4 # comments can appear - 3 2.0 1.4 # at the end of lines - 4 2.0 1.4 # in each data file section - 5 2.0 1.1 - 6 2.0 1.4 - 7 2.0 1.4 - 8 2.0 1.4 - 9 2.0 1.4 - 10 2.0 1.4 - 11 2.0 1.4 - 12 2.0 1.4 - 13 2.0 1.4 - 14 2.0 1.4 - 15 2.0 1.4 - 16 2.0 1.1 - 17 2.0 1.4 - 18 2.0 1.4 - 19 2.0 1.1 - 20 2.0 1.4 - 21 2.0 1.4 - 22 2.0 1.1 - 23 2.0 1.1 - 24 2.0 1.1 - -Bonds - -1 1 1 2 # descriptive comments can -2 1 1 22 # appear at the end of lines -3 1 2 3 # in each data file section -4 1 2 5 # (removed from this file) -5 1 3 24 -6 1 3 4 -7 1 4 7 -8 1 4 29 -9 1 5 6 -10 1 6 7 -11 1 6 9 -12 1 7 8 -13 1 8 33 -14 1 8 11 -15 1 9 10 -16 1 10 13 -17 1 10 11 -18 1 11 12 -19 1 12 15 -20 1 12 37 -21 1 13 14 -22 1 14 17 -23 1 14 15 -24 1 15 16 -25 1 16 19 -26 1 16 41 -27 1 17 18 -28 1 18 21 -29 1 18 19 -30 1 19 20 -31 1 20 23 -32 1 20 45 -33 1 21 22 -34 1 22 23 -35 1 23 24 -36 1 24 25 -37 1 25 26 -38 1 25 46 -39 1 26 27 -40 1 26 29 -41 1 27 48 -42 1 27 28 -43 1 28 31 -44 1 28 53 -45 1 29 30 -46 1 30 31 -47 1 30 33 -48 1 31 32 -49 1 32 57 -50 1 32 35 -51 1 33 34 -52 1 34 37 -53 1 34 35 -54 1 35 36 -55 1 36 39 -56 1 36 61 -57 1 37 38 -58 1 38 41 -59 1 38 39 -60 1 39 40 -61 1 40 43 -62 1 40 65 -63 1 41 42 -64 1 42 45 -65 1 42 43 -66 1 43 44 -67 1 44 47 -68 1 44 69 -69 1 45 46 -70 1 46 47 -71 1 47 48 -72 1 48 49 -73 1 49 50 -74 1 49 70 -75 1 50 51 -76 1 50 53 -77 1 51 72 -78 1 51 52 -79 1 52 55 -80 1 53 54 -81 1 54 55 -82 1 54 57 -83 1 55 56 -84 1 56 59 -85 1 57 58 -86 1 58 61 -87 1 58 59 -88 1 59 60 -89 1 60 63 -90 1 61 62 -91 1 62 65 -92 1 62 63 -93 1 63 64 -94 1 64 67 -95 1 65 66 -96 1 66 69 -97 1 66 67 -98 1 67 68 -99 1 68 71 -100 1 69 70 -101 1 70 71 -102 1 71 72 -103 13 73 81 -104 19 73 74 -105 19 73 75 -106 18 76 78 -107 19 76 77 -108 20 76 92 -109 18 78 73 -110 23 78 79 -111 23 78 80 -112 14 81 86 -113 15 81 83 -114 16 81 82 -115 21 83 86 -116 23 83 84 -117 23 83 85 -118 17 86 76 -119 22 86 87 -120 12 88 89 -121 8 89 90 -122 5 90 91 -123 10 92 97 -124 6 92 90 -125 4 93 98 -126 7 94 93 -127 5 94 95 -128 7 94 96 -129 11 97 96 -130 9 97 88 -131 3 98 99 -132 2 98 88 -133 24 99 100 -134 24 99 101 - - -Angle Coeffs - - 1 0 120.0 0 2.0 - 2 0 120.0 0 2.0 # comments can appear - 3 0 120.0 0 2.0 # at the end of lines - 4 0 120.0 0 2.0 # in each data file section - 5 0 120.0 0 2.0 - 6 0 120.0 0 2.0 - 7 0 120.0 0 2.0 - 8 0 120.0 0 2.0 - 9 0 120.0 0 2.0 - 10 0 120.0 0 2.0 - 11 0 120.0 0 2.0 - 12 0 120.0 0 2.0 - 13 0 120.0 0 2.0 - 14 0 120.0 0 2.0 - 15 0 120.0 0 2.0 - 16 0 120.0 0 2.0 - 17 0 120.0 0 2.0 - 18 0 120.0 0 2.0 - 19 0 60.0 0 2.0 - 20 0 120.0 0 2.0 - 21 0 60.0 0 2.0 - 22 0 120.0 0 2.0 - 23 0 120.0 0 2.0 - 24 0 120.0 0 2.0 - 25 0 120.0 0 2.0 - 26 0 120.0 0 2.0 - 27 0 120.0 0 2.0 - 28 0 120.0 0 2.0 - 29 0 120.0 0 2.0 - 30 0 60.0 0 2.0 - 31 0 120.0 0 2.0 - 32 0 90.0 0 2.0 - 33 0 120.0 0 2.0 - 34 0 120.0 0 2.0 - 35 0 120.0 0 2.0 - 36 0 120.0 0 2.0 - 37 0 120.0 0 2.0 - 38 0 120.0 0 2.0 - 39 0 120.0 0 2.0 - 40 0 120.0 0 2.0 - 41 0 120.0 0 2.0 - 42 0 120.0 0 2.0 - 43 0 120.0 0 2.0 - 44 0 120.0 0 2.0 - 45 0 120.0 0 2.0 - 46 0 120.0 0 2.0 - 47 0 120.0 0 2.0 - 48 0 120.0 0 2.0 - 49 0 120.0 0 2.0 - 50 0 120.0 0 2.0 - -Angles - -1 1 2 1 22 -2 1 1 2 3 # comments can appear -3 1 1 2 5 # at the end of lines -4 1 3 2 5 # in each data file section -5 1 2 3 24 -6 1 2 3 4 -7 1 4 3 24 -8 1 3 4 7 -9 1 3 4 29 -10 1 7 4 29 -11 1 2 5 6 -12 1 5 6 7 -13 1 5 6 9 -14 1 7 6 9 -15 1 4 7 6 -16 1 4 7 8 -17 1 6 7 8 -18 1 7 8 33 -19 1 7 8 11 -20 1 11 8 33 -21 1 6 9 10 -22 1 9 10 13 -23 1 9 10 11 -24 1 11 10 13 -25 1 8 11 10 -26 1 8 11 12 -27 1 10 11 12 -28 1 11 12 15 -29 1 11 12 37 -30 1 15 12 37 -31 1 10 13 14 -32 1 13 14 17 -33 1 13 14 15 -34 1 15 14 17 -35 1 12 15 14 -36 1 12 15 16 -37 1 14 15 16 -38 1 15 16 19 -39 1 15 16 41 -40 1 19 16 41 -41 1 14 17 18 -42 1 17 18 21 -43 1 17 18 19 -44 1 19 18 21 -45 1 16 19 18 -46 1 16 19 20 -47 1 18 19 20 -48 1 19 20 23 -49 1 19 20 45 -50 1 23 20 45 -51 1 18 21 22 -52 1 1 22 21 -53 1 1 22 23 -54 1 21 22 23 -55 1 20 23 22 -56 1 20 23 24 -57 1 22 23 24 -58 1 3 24 23 -59 1 3 24 25 -60 1 23 24 25 -61 1 24 25 26 -62 1 24 25 46 -63 1 26 25 46 -64 1 25 26 27 -65 1 25 26 29 -66 1 27 26 29 -67 1 26 27 48 -68 1 26 27 28 -69 1 28 27 48 -70 1 27 28 31 -71 1 27 28 53 -72 1 31 28 53 -73 1 4 29 26 -74 1 4 29 30 -75 1 26 29 30 -76 1 29 30 31 -77 1 29 30 33 -78 1 31 30 33 -79 1 28 31 30 -80 1 28 31 32 -81 1 30 31 32 -82 1 31 32 57 -83 1 31 32 35 -84 1 35 32 57 -85 1 8 33 30 -86 1 8 33 34 -87 1 30 33 34 -88 1 33 34 37 -89 1 33 34 35 -90 1 35 34 37 -91 1 32 35 34 -92 1 32 35 36 -93 1 34 35 36 -94 1 35 36 39 -95 1 35 36 61 -96 1 39 36 61 -97 1 12 37 34 -98 1 12 37 38 -99 1 34 37 38 -100 1 37 38 41 -101 1 37 38 39 -102 1 39 38 41 -103 1 36 39 38 -104 1 36 39 40 -105 1 38 39 40 -106 1 39 40 43 -107 1 39 40 65 -108 1 43 40 65 -109 1 16 41 38 -110 1 16 41 42 -111 1 38 41 42 -112 1 41 42 45 -113 1 41 42 43 -114 1 43 42 45 -115 1 40 43 42 -116 1 40 43 44 -117 1 42 43 44 -118 1 43 44 47 -119 1 43 44 69 -120 1 47 44 69 -121 1 20 45 42 -122 1 20 45 46 -123 1 42 45 46 -124 1 25 46 45 -125 1 25 46 47 -126 1 45 46 47 -127 1 44 47 46 -128 1 44 47 48 -129 1 46 47 48 -130 1 27 48 47 -131 1 27 48 49 -132 1 47 48 49 -133 1 48 49 50 -134 1 48 49 70 -135 1 50 49 70 -136 1 49 50 51 -137 1 49 50 53 -138 1 51 50 53 -139 1 50 51 72 -140 1 50 51 52 -141 1 52 51 72 -142 1 51 52 55 -143 1 28 53 50 -144 1 28 53 54 -145 1 50 53 54 -146 1 53 54 55 -147 1 53 54 57 -148 1 55 54 57 -149 1 52 55 54 -150 1 52 55 56 -151 1 54 55 56 -152 1 55 56 59 -153 1 32 57 54 -154 1 32 57 58 -155 1 54 57 58 -156 1 57 58 61 -157 1 57 58 59 -158 1 59 58 61 -159 1 56 59 58 -160 1 56 59 60 -161 1 58 59 60 -162 1 59 60 63 -163 1 36 61 58 -164 1 36 61 62 -165 1 58 61 62 -166 1 61 62 65 -167 1 61 62 63 -168 1 63 62 65 -169 1 60 63 62 -170 1 60 63 64 -171 1 62 63 64 -172 1 63 64 67 -173 1 40 65 62 -174 1 40 65 66 -175 1 62 65 66 -176 1 65 66 69 -177 1 65 66 67 -178 1 67 66 69 -179 1 64 67 66 -180 1 64 67 68 -181 1 66 67 68 -182 1 67 68 71 -183 1 44 69 66 -184 1 44 69 70 -185 1 66 69 70 -186 1 49 70 69 -187 1 49 70 71 -188 1 69 70 71 -189 1 68 71 70 -190 1 68 71 72 -191 1 70 71 72 -192 1 51 72 71 -193 25 73 81 82 -194 24 73 81 83 -195 23 73 81 86 -196 29 73 78 80 -197 29 73 78 79 -198 44 74 73 75 -199 7 76 92 90 -200 15 76 92 97 -201 27 76 86 87 -202 26 76 86 83 -203 18 76 86 81 -204 29 76 78 80 -205 29 76 78 79 -206 28 76 78 73 -207 45 77 76 92 -208 38 78 76 92 -209 37 78 76 77 -210 37 78 73 75 -211 37 78 73 74 -212 16 78 73 81 -213 46 79 78 80 -214 20 81 86 87 -215 19 81 86 83 -216 22 81 83 85 -217 22 81 83 84 -218 21 81 83 86 -219 17 81 73 75 -220 17 81 73 74 -221 39 83 86 87 -222 36 83 81 82 -223 46 84 83 85 -224 35 86 83 85 -225 35 86 83 84 -226 31 86 81 82 -227 30 86 81 83 -228 34 86 76 92 -229 33 86 76 77 -230 32 86 76 78 -231 11 88 98 93 -232 9 88 89 90 -233 14 89 88 97 -234 43 91 90 89 -235 12 92 97 88 -236 49 92 97 96 -237 48 92 90 89 -238 41 92 90 91 -239 50 93 94 96 -240 42 93 94 95 -241 5 94 93 98 -242 42 95 94 96 -243 13 96 97 88 -244 8 97 96 94 -245 6 97 92 90 -246 4 98 99 101 -247 4 98 99 100 -248 2 98 88 97 -249 3 98 88 89 -250 47 99 98 93 -251 10 99 98 88 -252 40 100 99 101 - -Dihedral Coeffs - - 1 0.0 2 180 1 - 2 0.0 2 180 1 # comments can appear - 3 0.0 2 180 1 # at the end of lines - 4 0.0 2 180 1 # in each data file section - 5 0.0 2 180 1 - 6 0.0 2 180 1 - 7 0.0 2 180 1 - 8 0.0 2 180 1 - 9 0.0 1 180 1 - 10 0.0 1 180 1 - 11 0.0 3 180 1 - 12 0.0 2 180 1 - 13 0.0 2 180 1 - 14 0.0 2 180 1 - 15 0.0 2 180 1 - 16 0.0 2 180 1 - 17 0.0 2 180 1 - 18 0.0 2 180 1 - 19 0.0 2 180 1 - 20 0.0 2 180 1 - 21 0.0 2 180 1 - 22 0.0 2 180 1 - 23 0.0 1 180 1 - 24 0.0 1 180 1 - 25 0.0 3 180 1 - 26 0.0 2 180 1 - 27 0.0 2 180 1 - 28 0.0 2 180 1 - 29 0.0 2 180 1 - 30 0.0 6 180 1 - 31 0.0 3 180 1 - 32 0.0 3 180 1 - 33 0.0 3 180 1 - 34 0.0 3 180 1 - 35 0.0 3 180 1 - 36 0.0 3 180 1 - 37 0.0 3 180 1 - 38 0.0 3 180 1 - 39 0.0 3 180 1 - 40 0.0 3 180 1 - 41 0.0 3 180 1 - 42 0.0 3 180 1 - 43 0.0 3 180 1 - 44 0.0 3 180 1 - 45 0.0 3 180 1 - 46 0.0 3 180 1 - 47 0.0 3 180 1 - 48 0.0 3 180 1 - 49 0.0 2 180 1 - 50 0.0 2 180 1 - 51 0.0 2 180 1 - 52 0.0 3 180 1 - 53 0.0 3 180 1 - 54 0.0 3 180 1 - 55 0.0 3 180 1 - 56 0.0 3 180 1 - 57 0.0 3 180 1 - 58 0.0 3 180 1 - 59 0.0 3 180 1 - 60 0.0 3 180 1 - 61 0.0 3 180 1 - 62 0.0 3 180 1 - 63 0.0 3 180 1 - 64 0.0 3 180 1 - 65 0.0 3 180 1 - 66 0.0 2 180 1 - 67 0.0 3 180 1 - 68 0.0 3 180 1 - 69 0.0 3 180 1 - 70 0.0 3 180 1 - 71 0.0 3 180 1 - 72 0.0 3 180 1 - 73 0.0 3 180 1 - 74 0.0 3 180 1 - 75 0.0 2 180 1 - 76 0.0 2 180 1 - 77 0.0 2 180 1 - 78 0.0 2 180 1 - -Dihedrals - -1 1 22 1 2 3 -2 1 22 1 2 5 -3 1 2 1 22 21 -4 1 2 1 22 23 -5 1 1 2 3 24 -6 1 1 2 3 4 -7 1 5 2 3 24 -8 1 5 2 3 4 -9 1 1 2 5 6 -10 1 3 2 5 6 -11 1 2 3 24 23 -12 1 2 3 24 25 -13 1 4 3 24 23 -14 1 4 3 24 25 -15 1 2 3 4 7 -16 1 2 3 4 29 -17 1 24 3 4 7 -18 1 24 3 4 29 -19 1 3 4 7 6 -20 1 3 4 7 8 -21 1 29 4 7 6 -22 1 29 4 7 8 -23 1 3 4 29 26 -24 1 3 4 29 30 -25 1 7 4 29 26 -26 1 7 4 29 30 -27 1 2 5 6 7 -28 1 2 5 6 9 -29 1 5 6 7 4 -30 1 5 6 7 8 -31 1 9 6 7 4 -32 1 9 6 7 8 -33 1 5 6 9 10 -34 1 7 6 9 10 -35 1 4 7 8 33 -36 1 4 7 8 11 -37 1 6 7 8 33 -38 1 6 7 8 11 -39 1 7 8 33 30 -40 1 7 8 33 34 -41 1 11 8 33 30 -42 1 11 8 33 34 -43 1 7 8 11 10 -44 1 7 8 11 12 -45 1 33 8 11 10 -46 1 33 8 11 12 -47 1 6 9 10 13 -48 1 6 9 10 11 -49 1 9 10 13 14 -50 1 11 10 13 14 -51 1 9 10 11 8 -52 1 9 10 11 12 -53 1 13 10 11 8 -54 1 13 10 11 12 -55 1 8 11 12 15 -56 1 8 11 12 37 -57 1 10 11 12 15 -58 1 10 11 12 37 -59 1 11 12 15 14 -60 1 11 12 15 16 -61 1 37 12 15 14 -62 1 37 12 15 16 -63 1 11 12 37 34 -64 1 11 12 37 38 -65 1 15 12 37 34 -66 1 15 12 37 38 -67 1 10 13 14 17 -68 1 10 13 14 15 -69 1 13 14 17 18 -70 1 15 14 17 18 -71 1 13 14 15 12 -72 1 13 14 15 16 -73 1 17 14 15 12 -74 1 17 14 15 16 -75 1 12 15 16 19 -76 1 12 15 16 41 -77 1 14 15 16 19 -78 1 14 15 16 41 -79 1 15 16 19 18 -80 1 15 16 19 20 -81 1 41 16 19 18 -82 1 41 16 19 20 -83 1 15 16 41 38 -84 1 15 16 41 42 -85 1 19 16 41 38 -86 1 19 16 41 42 -87 1 14 17 18 21 -88 1 14 17 18 19 -89 1 17 18 21 22 -90 1 19 18 21 22 -91 1 17 18 19 16 -92 1 17 18 19 20 -93 1 21 18 19 16 -94 1 21 18 19 20 -95 1 16 19 20 23 -96 1 16 19 20 45 -97 1 18 19 20 23 -98 1 18 19 20 45 -99 1 19 20 23 22 -100 1 19 20 23 24 -101 1 45 20 23 22 -102 1 45 20 23 24 -103 1 19 20 45 42 -104 1 19 20 45 46 -105 1 23 20 45 42 -106 1 23 20 45 46 -107 1 18 21 22 1 -108 1 18 21 22 23 -109 1 1 22 23 20 -110 1 1 22 23 24 -111 1 21 22 23 20 -112 1 21 22 23 24 -113 1 20 23 24 3 -114 1 20 23 24 25 -115 1 22 23 24 3 -116 1 22 23 24 25 -117 1 3 24 25 26 -118 1 3 24 25 46 -119 1 23 24 25 26 -120 1 23 24 25 46 -121 1 24 25 26 27 -122 1 24 25 26 29 -123 1 46 25 26 27 -124 1 46 25 26 29 -125 1 24 25 46 45 -126 1 24 25 46 47 -127 1 26 25 46 45 -128 1 26 25 46 47 -129 1 25 26 27 48 -130 1 25 26 27 28 -131 1 29 26 27 48 -132 1 29 26 27 28 -133 1 25 26 29 4 -134 1 25 26 29 30 -135 1 27 26 29 4 -136 1 27 26 29 30 -137 1 26 27 48 47 -138 1 26 27 48 49 -139 1 28 27 48 47 -140 1 28 27 48 49 -141 1 26 27 28 31 -142 1 26 27 28 53 -143 1 48 27 28 31 -144 1 48 27 28 53 -145 1 27 28 31 30 -146 1 27 28 31 32 -147 1 53 28 31 30 -148 1 53 28 31 32 -149 1 27 28 53 50 -150 1 27 28 53 54 -151 1 31 28 53 50 -152 1 31 28 53 54 -153 1 4 29 30 31 -154 1 4 29 30 33 -155 1 26 29 30 31 -156 1 26 29 30 33 -157 1 29 30 31 28 -158 1 29 30 31 32 -159 1 33 30 31 28 -160 1 33 30 31 32 -161 1 29 30 33 8 -162 1 29 30 33 34 -163 1 31 30 33 8 -164 1 31 30 33 34 -165 1 28 31 32 57 -166 1 28 31 32 35 -167 1 30 31 32 57 -168 1 30 31 32 35 -169 1 31 32 57 54 -170 1 31 32 57 58 -171 1 35 32 57 54 -172 1 35 32 57 58 -173 1 31 32 35 34 -174 1 31 32 35 36 -175 1 57 32 35 34 -176 1 57 32 35 36 -177 1 8 33 34 37 -178 1 8 33 34 35 -179 1 30 33 34 37 -180 1 30 33 34 35 -181 1 33 34 37 12 -182 1 33 34 37 38 -183 1 35 34 37 12 -184 1 35 34 37 38 -185 1 33 34 35 32 -186 1 33 34 35 36 -187 1 37 34 35 32 -188 1 37 34 35 36 -189 1 32 35 36 39 -190 1 32 35 36 61 -191 1 34 35 36 39 -192 1 34 35 36 61 -193 1 35 36 39 38 -194 1 35 36 39 40 -195 1 61 36 39 38 -196 1 61 36 39 40 -197 1 35 36 61 58 -198 1 35 36 61 62 -199 1 39 36 61 58 -200 1 39 36 61 62 -201 1 12 37 38 41 -202 1 12 37 38 39 -203 1 34 37 38 41 -204 1 34 37 38 39 -205 1 37 38 41 16 -206 1 37 38 41 42 -207 1 39 38 41 16 -208 1 39 38 41 42 -209 1 37 38 39 36 -210 1 37 38 39 40 -211 1 41 38 39 36 -212 1 41 38 39 40 -213 1 36 39 40 43 -214 1 36 39 40 65 -215 1 38 39 40 43 -216 1 38 39 40 65 -217 1 39 40 43 42 -218 1 39 40 43 44 -219 1 65 40 43 42 -220 1 65 40 43 44 -221 1 39 40 65 62 -222 1 39 40 65 66 -223 1 43 40 65 62 -224 1 43 40 65 66 -225 1 16 41 42 45 -226 1 16 41 42 43 -227 1 38 41 42 45 -228 1 38 41 42 43 -229 1 41 42 45 20 -230 1 41 42 45 46 -231 1 43 42 45 20 -232 1 43 42 45 46 -233 1 41 42 43 40 -234 1 41 42 43 44 -235 1 45 42 43 40 -236 1 45 42 43 44 -237 1 40 43 44 47 -238 1 40 43 44 69 -239 1 42 43 44 47 -240 1 42 43 44 69 -241 1 43 44 47 46 -242 1 43 44 47 48 -243 1 69 44 47 46 -244 1 69 44 47 48 -245 1 43 44 69 66 -246 1 43 44 69 70 -247 1 47 44 69 66 -248 1 47 44 69 70 -249 1 20 45 46 25 -250 1 20 45 46 47 -251 1 42 45 46 25 -252 1 42 45 46 47 -253 1 25 46 47 44 -254 1 25 46 47 48 -255 1 45 46 47 44 -256 1 45 46 47 48 -257 1 44 47 48 27 -258 1 44 47 48 49 -259 1 46 47 48 27 -260 1 46 47 48 49 -261 1 27 48 49 50 -262 1 27 48 49 70 -263 1 47 48 49 50 -264 1 47 48 49 70 -265 1 48 49 50 51 -266 1 48 49 50 53 -267 1 70 49 50 51 -268 1 70 49 50 53 -269 1 48 49 70 69 -270 1 48 49 70 71 -271 1 50 49 70 69 -272 1 50 49 70 71 -273 1 49 50 51 72 -274 1 49 50 51 52 -275 1 53 50 51 72 -276 1 53 50 51 52 -277 1 49 50 53 28 -278 1 49 50 53 54 -279 1 51 50 53 28 -280 1 51 50 53 54 -281 1 50 51 72 71 -282 1 52 51 72 71 -283 1 50 51 52 55 -284 1 72 51 52 55 -285 1 51 52 55 54 -286 1 51 52 55 56 -287 1 28 53 54 55 -288 1 28 53 54 57 -289 1 50 53 54 55 -290 1 50 53 54 57 -291 1 53 54 55 52 -292 1 53 54 55 56 -293 1 57 54 55 52 -294 1 57 54 55 56 -295 1 53 54 57 32 -296 1 53 54 57 58 -297 1 55 54 57 32 -298 1 55 54 57 58 -299 1 52 55 56 59 -300 1 54 55 56 59 -301 1 55 56 59 58 -302 1 55 56 59 60 -303 1 32 57 58 61 -304 1 32 57 58 59 -305 1 54 57 58 61 -306 1 54 57 58 59 -307 1 57 58 61 36 -308 1 57 58 61 62 -309 1 59 58 61 36 -310 1 59 58 61 62 -311 1 57 58 59 56 -312 1 57 58 59 60 -313 1 61 58 59 56 -314 1 61 58 59 60 -315 1 56 59 60 63 -316 1 58 59 60 63 -317 1 59 60 63 62 -318 1 59 60 63 64 -319 1 36 61 62 65 -320 1 36 61 62 63 -321 1 58 61 62 65 -322 1 58 61 62 63 -323 1 61 62 65 40 -324 1 61 62 65 66 -325 1 63 62 65 40 -326 1 63 62 65 66 -327 1 61 62 63 60 -328 1 61 62 63 64 -329 1 65 62 63 60 -330 1 65 62 63 64 -331 1 60 63 64 67 -332 1 62 63 64 67 -333 1 63 64 67 66 -334 1 63 64 67 68 -335 1 40 65 66 69 -336 1 40 65 66 67 -337 1 62 65 66 69 -338 1 62 65 66 67 -339 1 65 66 69 44 -340 1 65 66 69 70 -341 1 67 66 69 44 -342 1 67 66 69 70 -343 1 65 66 67 64 -344 1 65 66 67 68 -345 1 69 66 67 64 -346 1 69 66 67 68 -347 1 64 67 68 71 -348 1 66 67 68 71 -349 1 67 68 71 70 -350 1 67 68 71 72 -351 1 44 69 70 49 -352 1 44 69 70 71 -353 1 66 69 70 49 -354 1 66 69 70 71 -355 1 49 70 71 68 -356 1 49 70 71 72 -357 1 69 70 71 68 -358 1 69 70 71 72 -359 1 68 71 72 51 -360 1 70 71 72 51 -361 38 73 81 86 76 -362 39 73 81 86 83 -363 40 73 81 86 87 -364 41 73 81 83 86 -365 42 73 81 83 84 -366 42 73 81 83 85 -367 46 73 78 76 86 -368 47 73 78 76 77 -369 48 73 78 76 92 -370 47 74 73 78 76 -371 71 74 73 78 79 -372 71 74 73 78 80 -373 53 74 73 81 86 -374 58 74 73 81 83 -375 67 74 73 81 82 -376 47 75 73 78 76 -377 71 75 73 78 79 -378 71 75 73 78 80 -379 53 75 73 81 86 -380 58 75 73 81 83 -381 67 75 73 81 82 -382 51 76 92 97 96 -383 20 76 92 97 88 -384 49 76 92 90 91 -385 50 76 92 90 89 -386 43 76 86 81 83 -387 44 76 86 81 82 -388 36 76 86 83 81 -389 45 76 86 83 84 -390 45 76 86 83 85 -391 30 76 78 73 81 -392 33 77 76 86 81 -393 64 77 76 86 83 -394 70 77 76 86 87 -395 71 77 76 78 79 -396 71 77 76 78 80 -397 25 77 76 92 97 -398 11 77 76 92 90 -399 32 78 76 86 81 -400 61 78 76 86 83 -401 62 78 76 86 87 -402 24 78 76 92 97 -403 10 78 76 92 90 -404 52 78 73 81 86 -405 57 78 73 81 83 -406 60 78 73 81 82 -407 55 79 78 76 86 -408 74 79 78 76 92 -409 31 79 78 73 81 -410 55 80 78 76 86 -411 74 80 78 76 92 -412 31 80 78 73 81 -413 34 81 86 76 92 -414 35 81 86 83 84 -415 35 81 86 83 85 -416 37 81 83 86 87 -417 63 82 81 86 83 -418 68 82 81 86 87 -419 56 82 81 83 86 -420 69 82 81 83 84 -421 69 82 81 83 85 -422 65 83 86 76 92 -423 59 83 81 86 87 -424 54 84 83 81 86 -425 73 84 83 86 87 -426 54 85 83 81 86 -427 73 85 83 86 87 -428 23 86 76 92 97 -429 9 86 76 92 90 -430 72 87 86 76 92 -431 17 88 98 99 100 -432 17 88 98 99 101 -433 12 88 98 93 94 -434 7 88 97 92 90 -435 14 88 97 96 94 -436 29 88 89 90 92 -437 28 88 89 90 91 -438 22 89 90 92 97 -439 75 89 88 98 99 -440 77 89 88 98 93 -441 76 89 88 97 92 -442 78 89 88 97 96 -443 8 90 92 97 96 -444 4 90 89 88 98 -445 16 90 89 88 97 -446 21 91 90 92 97 -447 15 92 97 96 94 -448 2 92 97 88 98 -449 66 93 98 99 100 -450 66 93 98 99 101 -451 19 93 98 88 97 -452 27 93 94 96 97 -453 13 94 93 98 99 -454 5 95 94 93 98 -455 26 95 94 96 97 -456 3 96 97 88 98 -457 6 96 94 93 98 diff --git a/tools/moltemplate/examples/file_conversion_examples/convert_LAMMPS_to_LT_examples/cnad-cnt/cnad-cnt.in b/tools/moltemplate/examples/file_conversion_examples/convert_LAMMPS_to_LT_examples/cnad-cnt/cnad-cnt.in deleted file mode 100644 index 1f403e2bd0..0000000000 --- a/tools/moltemplate/examples/file_conversion_examples/convert_LAMMPS_to_LT_examples/cnad-cnt/cnad-cnt.in +++ /dev/null @@ -1,49 +0,0 @@ -#Created by Aysun Itai and modified by Andrew Jewett -# NOTE: This file has been extensively modified. -# Only the bond connectivity and atomic positions are accurate. - -units real - -neigh_modify delay 2 every 1 - -atom_style full -bond_style harmonic -angle_style charmm -dihedral_style charmm -pair_style lj/charmm/coul/charmm 8.0 10.0 -pair_modify mix arithmetic - -read_data cnad-cnt.data - -pair_coeff 1 1 0.02 4.0 -pair_coeff 2 2 0.02 1.0 # atoms will not interact sterically -pair_coeff 3 3 0.02 2.0 # in this version of the file. -pair_coeff 4 4 0.02 2.0 # (All pair forces and atom names removed) -pair_coeff 5 5 0.02 2.0 -pair_coeff 6 6 0.02 3.0 -pair_coeff 7 7 0.02 3.0 -pair_coeff 8 8 0.02 3.0 -pair_coeff 9 9 0.02 4.0 -pair_coeff 10 10 0.02 4.0 -pair_coeff 11 11 0.02 4.0 -pair_coeff 12 12 0.02 4.0 -pair_coeff 13 13 0.02 3.0 -pair_coeff 14 14 0.02 3.0 -pair_coeff 15 15 0.02 3.0 -pair_coeff 16 16 0.02 3.0 - -group cnt type 1 -group cnad type 2:16 - -displace_atoms cnad move 0 -7 0 units box -special_bonds charmm - -velocity all create 0.0 54321 dist uniform - -thermo 1 -thermo_style multi -timestep 0.005 - -dump 1 all atom 10 cnad-cnt.dump - -run 20000 diff --git a/tools/moltemplate/examples/file_conversion_examples/convert_LAMMPS_to_LT_examples/cnad-cnt/images/cnad-cnt_after_rotate_copy.jpg b/tools/moltemplate/examples/file_conversion_examples/convert_LAMMPS_to_LT_examples/cnad-cnt/images/cnad-cnt_after_rotate_copy.jpg deleted file mode 100644 index 3b79b405ef778425d0007fc674e5b082a6200427..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29386 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

!fIecPV-Uk_O}Itgr-%( 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 NlKLiC6+8aF2>_J`#r6OI diff --git a/tools/moltemplate/examples/file_conversion_examples/convert_LAMMPS_to_LT_examples/cnad-cnt/images/cnad.jpg b/tools/moltemplate/examples/file_conversion_examples/convert_LAMMPS_to_LT_examples/cnad-cnt/images/cnad.jpg deleted file mode 100644 index 628371b0d71ce1c5b062d97fb13cd8b6bccca029..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18403 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 diff --git a/tools/moltemplate/examples/file_conversion_examples/convert_LAMMPS_to_LT_examples/cnad-cnt/images/cnt.jpg b/tools/moltemplate/examples/file_conversion_examples/convert_LAMMPS_to_LT_examples/cnad-cnt/images/cnt.jpg deleted file mode 100644 index 3489773adb004e02d7ebe141367143261fdda592..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20633 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 Solvation Box. -In this example, I made a box whose x,y,z dimensions were 16,24,24.) - diff --git a/tools/moltemplate/examples/file_conversion_examples/read_PDB_file_examples/waterSPCE_from_PDBfile/README_run.sh b/tools/moltemplate/examples/file_conversion_examples/read_PDB_file_examples/waterSPCE_from_PDBfile/README_run.sh deleted file mode 100755 index 2944f68403..0000000000 --- a/tools/moltemplate/examples/file_conversion_examples/read_PDB_file_examples/waterSPCE_from_PDBfile/README_run.sh +++ /dev/null @@ -1,31 +0,0 @@ -# --- Running LAMMPS --- -# -- Prerequisites: -- -# The 2 files "run.in.npt", and "run.in.nvt" are LAMMPS -# input scripts which link to the input scripts and data files -# you hopefully have created earlier with moltemplate.sh: -# system.in.init, system.in.settings, system.data -# If not, carry out the instructions in "README_setup.sh". -# -# -- Instructions: -- -# If "lmp_mpi" is the name of the command you use to invoke lammps, -# then you would run lammps on these files this way: - - -lmp_mpi -i run.in.npt # minimization and simulation at constant pressure -lmp_mpi -i run.in.nvt # minimization and simulation at constant volume - -#(Note: The constant volume simulation lacks pressure equilibration. These are -# completely separate simulations. The results of the constant pressure -# simulation are ignored when beginning the simulation at constant volume. -# This can be fixed. Read "run.in.nvt" for equilibration instructions.) - - - - - - - -# If you have compiled the MPI version of lammps, you can run lammps in parallel -#mpirun -np 4 lmp_mpi -i run.in.npt -#mpirun -np 4 lmp_mpi -i run.in.nvt -# (assuming you have 4 processors available) diff --git a/tools/moltemplate/examples/file_conversion_examples/read_PDB_file_examples/waterSPCE_from_PDBfile/README_setup.sh b/tools/moltemplate/examples/file_conversion_examples/read_PDB_file_examples/waterSPCE_from_PDBfile/README_setup.sh deleted file mode 100755 index 5d2be21331..0000000000 --- a/tools/moltemplate/examples/file_conversion_examples/read_PDB_file_examples/waterSPCE_from_PDBfile/README_setup.sh +++ /dev/null @@ -1,32 +0,0 @@ -# Use these commands to generate the LAMMPS input script and data file -# (and other auxilliary files): - -cd moltemplate_files/ # (The .lt input files are in this directory) - - moltemplate.sh -pdb solvate.pdb system.lt - - # This will generate various files with names ending in *.in* and *.data. - # These files are the input files directly read by LAMMPS. Move them to - # the parent directory (or wherever you plan to run the simulation). - - mv -f system.in* system.data ../ - - # Optional: - # The "./output_ttree/" directory is full of temporary files generated by - # moltemplate. They can be useful for debugging, but are usually thrown away. - rm -rf output_ttree/ - -cd ../ - - -# -#This will prepare LAMMPS input files for a box of water -#(In this example, we are using the "SPC/E" water model.) -#The number of water molecules in the "wat = new SPCE [260]" command -#must equal the number of water molecules in the PDB file. -# -#Coordinates and boundary-box information is read from the .pdb file. -# -#You can also specify this information directly in the ttree file. -#See the comments section in "system.lt" for details. -# diff --git a/tools/moltemplate/examples/file_conversion_examples/read_PDB_file_examples/waterSPCE_from_PDBfile/README_visualize.txt b/tools/moltemplate/examples/file_conversion_examples/read_PDB_file_examples/waterSPCE_from_PDBfile/README_visualize.txt deleted file mode 100644 index 8063d535f8..0000000000 --- a/tools/moltemplate/examples/file_conversion_examples/read_PDB_file_examples/waterSPCE_from_PDBfile/README_visualize.txt +++ /dev/null @@ -1,64 +0,0 @@ - ------- Instructions to view a trajectory in VMD -------- - - ------- Disclaimer ------- - -1) Build a PSF file for use in viewing with VMD. - -This step works with VMD 1.9 and topotools 1.2. -(Older versions, like VMD 1.8.6, don't support this.) - - -a) Start VMD -b) Menu Extensions->Tk Console -c) Enter: - -(I assume that the the DATA file is called "system.data") - - topo readlammpsdata system.data full - animate write psf system.psf - - (Note, at this point the image shown in the VMD graphics window may - not appear correct or incomplete. The coordinates of the atoms may - overlap if you asked moltemplate.sh to load your coordinates from - a PDB or XYZ file. - However, later after you have run a simulation, the trajectories - should appear reasonably correct when you load them in VMD using - the PSF file you just generated.) - - -Later, to Load a trajectory in VMD: - Start VMD - Select menu: File->New Molecule - -Browse to select the PSF file you created above, and load it. - (Don't close the window yet.) - -Browse to select the trajectory file. - If necessary, for "file type" select: "LAMMPS Trajectory" - Load it - ------ Wrap the coordinates to the unit cell - -a) Start VMD -b) Load the trajectory in VMD (see above) -c) Menu Extensions->Tk Console -d) Enter: - - DISCLAIMER: I'M NOT SURE THESE COMMANDS ARE CORRECT. - LOOKUP "pbctools" FOR DETAILS. - - pbc wrap -compound res -all - pbc box - - # If you have a solute of type 1, then use this: - #pbc wrap -sel type=1 -all -centersel type=2 -center com - -"1" corresponds to the "O" atom type -"2" corresponds to the "H" atom type - -3) Optional: If you like, change the atom types in the PSF file so - that VMD recognizes the atom types: - -sed -e 's/ 1 1 / O O /g' < system.psf > temp1.psf -sed -e 's/ 2 2 / H H /g' < temp1.psf > system.psf - -(If you do this, I guess that you might have to use - "type=O" and "type=H" in step 2 above.) diff --git a/tools/moltemplate/examples/file_conversion_examples/read_PDB_file_examples/waterSPCE_from_PDBfile/moltemplate_files/.0 b/tools/moltemplate/examples/file_conversion_examples/read_PDB_file_examples/waterSPCE_from_PDBfile/moltemplate_files/.0 deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tools/moltemplate/examples/file_conversion_examples/read_PDB_file_examples/waterSPCE_from_PDBfile/moltemplate_files/README.sh b/tools/moltemplate/examples/file_conversion_examples/read_PDB_file_examples/waterSPCE_from_PDBfile/moltemplate_files/README.sh deleted file mode 100755 index 4ebc7b17a3..0000000000 --- a/tools/moltemplate/examples/file_conversion_examples/read_PDB_file_examples/waterSPCE_from_PDBfile/moltemplate_files/README.sh +++ /dev/null @@ -1,11 +0,0 @@ - -# Run moltemplate this way: - -moltemplate.sh -pdb solvate.pdb system.lt - - -# The PDB file was generated by the "solvate" utility which comes with VMD. -# (To generate this file yourself, run VMD, click on the "Extensions" menu, -# and select Modeling-->Add Solvation Box. -# In this example, I made a box whose x,y,z dimensions were 16,24,24.) - diff --git a/tools/moltemplate/examples/file_conversion_examples/read_PDB_file_examples/waterSPCE_from_PDBfile/moltemplate_files/solvate.pdb b/tools/moltemplate/examples/file_conversion_examples/read_PDB_file_examples/waterSPCE_from_PDBfile/moltemplate_files/solvate.pdb deleted file mode 100644 index 0ed5103cbb..0000000000 --- a/tools/moltemplate/examples/file_conversion_examples/read_PDB_file_examples/waterSPCE_from_PDBfile/moltemplate_files/solvate.pdb +++ /dev/null @@ -1,782 +0,0 @@ -CRYST1 16.000 24.000 24.000 90.00 90.00 90.00 P 1 1 -ATOM 1 OH2 TIP3W 5 3.668 10.082 15.904 1.00 0.00 WT1 O -ATOM 2 H1 TIP3W 5 3.224 10.451 15.101 1.00 0.00 WT1 H -ATOM 3 H2 TIP3W 5 3.092 10.379 16.627 1.00 0.00 WT1 H -ATOM 4 OH2 TIP3W 7 6.033 4.876 20.891 1.00 0.00 WT1 O -ATOM 5 H1 TIP3W 7 6.078 5.224 21.798 1.00 0.00 WT1 H -ATOM 6 H2 TIP3W 7 6.592 4.088 20.961 1.00 0.00 WT1 H -ATOM 7 OH2 TIP3W 21 5.186 16.696 12.072 1.00 0.00 WT1 O -ATOM 8 H1 TIP3W 21 6.083 16.979 11.816 1.00 0.00 WT1 H -ATOM 9 H2 TIP3W 21 5.337 15.832 12.490 1.00 0.00 WT1 H -ATOM 10 OH2 TIP3W 29 8.324 13.811 21.332 1.00 0.00 WT1 O -ATOM 11 H1 TIP3W 29 8.633 13.348 22.112 1.00 0.00 WT1 H -ATOM 12 H2 TIP3W 29 8.506 13.116 20.645 1.00 0.00 WT1 H -ATOM 13 OH2 TIP3W 44 3.786 16.318 1.310 1.00 0.00 WT1 O -ATOM 14 H1 TIP3W 44 3.781 15.388 1.196 1.00 0.00 WT1 H -ATOM 15 H2 TIP3W 44 4.528 16.580 0.781 1.00 0.00 WT1 H -ATOM 16 OH2 TIP3W 46 6.205 6.991 18.442 1.00 0.00 WT1 O -ATOM 17 H1 TIP3W 46 6.782 7.347 19.152 1.00 0.00 WT1 H -ATOM 18 H2 TIP3W 46 5.309 7.062 18.800 1.00 0.00 WT1 H -ATOM 19 OH2 TIP3W 48 2.750 8.844 9.629 1.00 0.00 WT1 O -ATOM 20 H1 TIP3W 48 2.110 8.290 9.998 1.00 0.00 WT1 H -ATOM 21 H2 TIP3W 48 2.164 9.245 8.962 1.00 0.00 WT1 H -ATOM 22 OH2 TIP3W 52 3.935 16.195 22.109 1.00 0.00 WT1 O -ATOM 23 H1 TIP3W 52 4.870 16.034 21.985 1.00 0.00 WT1 H -ATOM 24 H2 TIP3W 52 3.655 15.367 22.581 1.00 0.00 WT1 H -ATOM 25 OH2 TIP3W 64 10.674 8.909 4.986 1.00 0.00 WT1 O -ATOM 26 H1 TIP3W 64 10.998 8.871 5.932 1.00 0.00 WT1 H -ATOM 27 H2 TIP3W 64 9.748 9.270 5.075 1.00 0.00 WT1 H -ATOM 28 OH2 TIP3W 67 0.002 5.667 14.591 1.00 0.00 WT1 O -ATOM 29 H1 TIP3W 67 0.483 5.990 13.830 1.00 0.00 WT1 H -ATOM 30 H2 TIP3W 67 0.608 5.781 15.347 1.00 0.00 WT1 H -ATOM 31 OH2 TIP3W 68 9.882 9.156 14.916 1.00 0.00 WT1 O -ATOM 32 H1 TIP3W 68 9.574 9.753 15.597 1.00 0.00 WT1 H -ATOM 33 H2 TIP3W 68 10.021 8.264 15.289 1.00 0.00 WT1 H -ATOM 34 OH2 TIP3W 87 1.661 6.681 1.943 1.00 0.00 WT1 O -ATOM 35 H1 TIP3W 87 1.943 5.739 1.981 1.00 0.00 WT1 H -ATOM 36 H2 TIP3W 87 0.778 6.599 1.483 1.00 0.00 WT1 H -ATOM 37 OH2 TIP3W 88 4.821 20.603 11.239 1.00 0.00 WT1 O -ATOM 38 H1 TIP3W 88 5.466 20.782 11.963 1.00 0.00 WT1 H -ATOM 39 H2 TIP3W 88 5.384 20.914 10.456 1.00 0.00 WT1 H -ATOM 40 OH2 TIP3W 90 15.022 20.855 12.831 1.00 0.00 WT1 O -ATOM 41 H1 TIP3W 90 14.222 20.809 13.292 1.00 0.00 WT1 H -ATOM 42 H2 TIP3W 90 14.673 21.057 11.918 1.00 0.00 WT1 H -ATOM 43 OH2 TIP3W 94 1.339 3.782 22.814 1.00 0.00 WT1 O -ATOM 44 H1 TIP3W 94 0.839 3.425 22.087 1.00 0.00 WT1 H -ATOM 45 H2 TIP3W 94 1.775 3.077 23.138 1.00 0.00 WT1 H -ATOM 46 OH2 TIP3W 95 0.485 15.137 22.476 1.00 0.00 WT1 O -ATOM 47 H1 TIP3W 95 0.644 15.425 23.349 1.00 0.00 WT1 H -ATOM 48 H2 TIP3W 95 0.312 15.961 21.975 1.00 0.00 WT1 H -ATOM 49 OH2 TIP3W 111 10.426 7.604 2.404 1.00 0.00 WT1 O -ATOM 50 H1 TIP3W 111 10.761 8.401 1.994 1.00 0.00 WT1 H -ATOM 51 H2 TIP3W 111 10.248 7.889 3.308 1.00 0.00 WT1 H -ATOM 52 OH2 TIP3W 113 4.269 22.752 16.265 1.00 0.00 WT1 O -ATOM 53 H1 TIP3W 113 4.149 23.680 15.888 1.00 0.00 WT1 H -ATOM 54 H2 TIP3W 113 5.061 22.796 16.776 1.00 0.00 WT1 H -ATOM 55 OH2 TIP3W 130 10.926 5.365 1.018 1.00 0.00 WT1 O -ATOM 56 H1 TIP3W 130 11.138 4.769 1.754 1.00 0.00 WT1 H -ATOM 57 H2 TIP3W 130 10.657 6.212 1.493 1.00 0.00 WT1 H -ATOM 58 OH2 TIP3W 133 8.647 4.314 19.278 1.00 0.00 WT1 O -ATOM 59 H1 TIP3W 133 7.964 3.611 19.326 1.00 0.00 WT1 H -ATOM 60 H2 TIP3W 133 8.043 5.064 19.153 1.00 0.00 WT1 H -ATOM 61 OH2 TIP3W 134 8.381 17.319 23.275 1.00 0.00 WT1 O -ATOM 62 H1 TIP3W 134 7.516 17.340 23.695 1.00 0.00 WT1 H -ATOM 63 H2 TIP3W 134 8.431 18.263 23.009 1.00 0.00 WT1 H -ATOM 64 OH2 TIP3W 150 4.299 17.774 7.169 1.00 0.00 WT1 O -ATOM 65 H1 TIP3W 150 3.303 17.803 7.322 1.00 0.00 WT1 H -ATOM 66 H2 TIP3W 150 4.533 18.755 6.924 1.00 0.00 WT1 H -ATOM 67 OH2 TIP3W 152 8.892 12.977 5.321 1.00 0.00 WT1 O -ATOM 68 H1 TIP3W 152 8.119 12.478 5.443 1.00 0.00 WT1 H -ATOM 69 H2 TIP3W 152 9.342 12.557 4.536 1.00 0.00 WT1 H -ATOM 70 OH2 TIP3W 167 2.174 18.468 2.212 1.00 0.00 WT1 O -ATOM 71 H1 TIP3W 167 2.632 17.628 2.203 1.00 0.00 WT1 H -ATOM 72 H2 TIP3W 167 2.931 19.120 2.281 1.00 0.00 WT1 H -ATOM 73 OH2 TIP3W 239 13.612 17.680 18.622 1.00 0.00 WT1 O -ATOM 74 H1 TIP3W 239 13.744 17.414 19.508 1.00 0.00 WT1 H -ATOM 75 H2 TIP3W 239 14.526 17.831 18.347 1.00 0.00 WT1 H -ATOM 76 OH2 TIP3W 443 9.935 12.876 10.191 1.00 0.00 WT1 O -ATOM 77 H1 TIP3W 443 9.709 12.098 9.634 1.00 0.00 WT1 H -ATOM 78 H2 TIP3W 443 9.472 12.766 11.018 1.00 0.00 WT1 H -ATOM 79 OH2 TIP3W 450 7.060 2.074 19.830 1.00 0.00 WT1 O -ATOM 80 H1 TIP3W 450 7.650 1.619 20.528 1.00 0.00 WT1 H -ATOM 81 H2 TIP3W 450 6.148 1.796 20.035 1.00 0.00 WT1 H -ATOM 82 OH2 TIP3W 465 13.891 1.919 2.992 1.00 0.00 WT1 O -ATOM 83 H1 TIP3W 465 14.198 2.681 3.422 1.00 0.00 WT1 H -ATOM 84 H2 TIP3W 465 13.212 1.577 3.578 1.00 0.00 WT1 H -ATOM 85 OH2 TIP3W 466 8.823 10.581 8.827 1.00 0.00 WT1 O -ATOM 86 H1 TIP3W 466 8.183 10.753 8.148 1.00 0.00 WT1 H -ATOM 87 H2 TIP3W 466 8.389 10.061 9.534 1.00 0.00 WT1 H -ATOM 88 OH2 TIP3W 469 9.078 11.967 12.734 1.00 0.00 WT1 O -ATOM 89 H1 TIP3W 469 8.228 11.561 12.993 1.00 0.00 WT1 H -ATOM 90 H2 TIP3W 469 9.512 12.194 13.560 1.00 0.00 WT1 H -ATOM 91 OH2 TIP3W 484 10.282 0.640 2.053 1.00 0.00 WT1 O -ATOM 92 H1 TIP3W 484 10.367 0.959 3.016 1.00 0.00 WT1 H -ATOM 93 H2 TIP3W 484 9.743 1.323 1.667 1.00 0.00 WT1 H -ATOM 94 OH2 TIP3W 485 4.618 8.125 7.777 1.00 0.00 WT1 O -ATOM 95 H1 TIP3W 485 5.405 7.919 8.314 1.00 0.00 WT1 H -ATOM 96 H2 TIP3W 485 4.002 8.458 8.422 1.00 0.00 WT1 H -ATOM 97 OH2 TIP3W 486 3.403 4.687 9.815 1.00 0.00 WT1 O -ATOM 98 H1 TIP3W 486 3.109 5.272 9.097 1.00 0.00 WT1 H -ATOM 99 H2 TIP3W 486 3.817 3.973 9.327 1.00 0.00 WT1 H -ATOM 100 OH2 TIP3W 489 3.276 7.465 19.325 1.00 0.00 WT1 O -ATOM 101 H1 TIP3W 489 2.772 6.991 19.964 1.00 0.00 WT1 H -ATOM 102 H2 TIP3W 489 3.604 8.288 19.753 1.00 0.00 WT1 H -ATOM 103 OH2 TIP3W 503 3.119 10.325 13.158 1.00 0.00 WT1 O -ATOM 104 H1 TIP3W 503 3.598 10.900 12.512 1.00 0.00 WT1 H -ATOM 105 H2 TIP3W 503 3.440 9.430 12.962 1.00 0.00 WT1 H -ATOM 106 OH2 TIP3W 506 2.378 5.806 16.253 1.00 0.00 WT1 O -ATOM 107 H1 TIP3W 506 2.157 6.161 17.099 1.00 0.00 WT1 H -ATOM 108 H2 TIP3W 506 3.301 6.032 16.126 1.00 0.00 WT1 H -ATOM 109 OH2 TIP3W 507 6.382 22.271 2.319 1.00 0.00 WT1 O -ATOM 110 H1 TIP3W 507 5.550 22.035 1.847 1.00 0.00 WT1 H -ATOM 111 H2 TIP3W 507 6.859 21.472 2.192 1.00 0.00 WT1 H -ATOM 112 OH2 TIP3W 509 4.017 3.905 19.418 1.00 0.00 WT1 O -ATOM 113 H1 TIP3W 509 3.142 4.042 19.132 1.00 0.00 WT1 H -ATOM 114 H2 TIP3W 509 4.582 4.727 19.295 1.00 0.00 WT1 H -ATOM 115 OH2 TIP3W 511 2.344 20.472 21.631 1.00 0.00 WT1 O -ATOM 116 H1 TIP3W 511 2.932 20.821 20.945 1.00 0.00 WT1 H -ATOM 117 H2 TIP3W 511 1.467 20.548 21.138 1.00 0.00 WT1 H -ATOM 118 OH2 TIP3W 517 14.526 10.532 20.137 1.00 0.00 WT1 O -ATOM 119 H1 TIP3W 517 14.162 9.733 20.503 1.00 0.00 WT1 H -ATOM 120 H2 TIP3W 517 14.466 10.420 19.194 1.00 0.00 WT1 H -ATOM 121 OH2 TIP3W 533 5.573 14.804 19.090 1.00 0.00 WT1 O -ATOM 122 H1 TIP3W 533 5.959 15.339 19.808 1.00 0.00 WT1 H -ATOM 123 H2 TIP3W 533 5.869 15.413 18.331 1.00 0.00 WT1 H -ATOM 124 OH2 TIP3W 543 5.458 13.097 4.589 1.00 0.00 WT1 O -ATOM 125 H1 TIP3W 543 5.673 13.019 3.612 1.00 0.00 WT1 H -ATOM 126 H2 TIP3W 543 4.899 13.894 4.657 1.00 0.00 WT1 H -ATOM 127 OH2 TIP3W 550 4.552 1.370 20.330 1.00 0.00 WT1 O -ATOM 128 H1 TIP3W 550 4.274 2.194 19.953 1.00 0.00 WT1 H -ATOM 129 H2 TIP3W 550 4.235 0.801 19.571 1.00 0.00 WT1 H -ATOM 130 OH2 TIP3W 554 5.160 13.744 7.954 1.00 0.00 WT1 O -ATOM 131 H1 TIP3W 554 6.048 13.422 8.207 1.00 0.00 WT1 H -ATOM 132 H2 TIP3W 554 5.008 14.493 8.528 1.00 0.00 WT1 H -ATOM 133 OH2 TIP3W 558 10.390 6.386 18.828 1.00 0.00 WT1 O -ATOM 134 H1 TIP3W 558 10.688 6.484 19.731 1.00 0.00 WT1 H -ATOM 135 H2 TIP3W 558 9.844 5.589 18.921 1.00 0.00 WT1 H -ATOM 136 OH2 TIP3W 562 1.678 21.942 1.035 1.00 0.00 WT1 O -ATOM 137 H1 TIP3W 562 1.272 21.280 1.592 1.00 0.00 WT1 H -ATOM 138 H2 TIP3W 562 1.498 22.809 1.493 1.00 0.00 WT1 H -ATOM 139 OH2 TIP3W 568 9.630 21.547 3.000 1.00 0.00 WT1 O -ATOM 140 H1 TIP3W 568 9.601 22.471 2.643 1.00 0.00 WT1 H -ATOM 141 H2 TIP3W 568 9.287 20.954 2.312 1.00 0.00 WT1 H -ATOM 142 OH2 TIP3W 575 2.344 10.571 2.624 1.00 0.00 WT1 O -ATOM 143 H1 TIP3W 575 2.122 10.753 3.553 1.00 0.00 WT1 H -ATOM 144 H2 TIP3W 575 2.947 9.791 2.617 1.00 0.00 WT1 H -ATOM 145 OH2 TIP3W 584 0.823 23.668 2.888 1.00 0.00 WT1 O -ATOM 146 H1 TIP3W 584 1.636 23.316 3.340 1.00 0.00 WT1 H -ATOM 147 H2 TIP3W 584 0.253 23.978 3.640 1.00 0.00 WT1 H -ATOM 148 OH2 TIP3W 594 2.710 6.185 7.540 1.00 0.00 WT1 O -ATOM 149 H1 TIP3W 594 2.467 6.236 6.561 1.00 0.00 WT1 H -ATOM 150 H2 TIP3W 594 3.410 6.855 7.580 1.00 0.00 WT1 H -ATOM 151 OH2 TIP3W 595 6.911 19.458 17.335 1.00 0.00 WT1 O -ATOM 152 H1 TIP3W 595 7.517 20.118 16.957 1.00 0.00 WT1 H -ATOM 153 H2 TIP3W 595 6.315 19.136 16.588 1.00 0.00 WT1 H -ATOM 154 OH2 TIP3W 613 13.540 22.220 2.748 1.00 0.00 WT1 O -ATOM 155 H1 TIP3W 613 12.965 22.475 3.462 1.00 0.00 WT1 H -ATOM 156 H2 TIP3W 613 14.428 22.404 3.074 1.00 0.00 WT1 H -ATOM 157 OH2 TIP3W 634 10.929 14.750 5.718 1.00 0.00 WT1 O -ATOM 158 H1 TIP3W 634 10.050 14.541 5.408 1.00 0.00 WT1 H -ATOM 159 H2 TIP3W 634 11.401 13.879 5.717 1.00 0.00 WT1 H -ATOM 160 OH2 TIP3W 822 0.747 4.469 10.579 1.00 0.00 WT1 O -ATOM 161 H1 TIP3W 822 0.426 3.568 10.339 1.00 0.00 WT1 H -ATOM 162 H2 TIP3W 822 1.505 4.585 9.990 1.00 0.00 WT1 H -ATOM 163 OH2 TIP3W 849 5.356 5.388 16.046 1.00 0.00 WT1 O -ATOM 164 H1 TIP3W 849 5.884 6.064 16.461 1.00 0.00 WT1 H -ATOM 165 H2 TIP3W 849 5.592 4.622 16.537 1.00 0.00 WT1 H -ATOM 166 OH2 TIP3W 867 10.704 6.721 15.883 1.00 0.00 WT1 O -ATOM 167 H1 TIP3W 867 10.901 6.912 16.836 1.00 0.00 WT1 H -ATOM 168 H2 TIP3W 867 10.127 5.972 15.998 1.00 0.00 WT1 H -ATOM 169 OH2 TIP3W 891 11.763 19.614 9.958 1.00 0.00 WT1 O -ATOM 170 H1 TIP3W 891 12.279 20.405 9.866 1.00 0.00 WT1 H -ATOM 171 H2 TIP3W 891 12.435 18.905 9.901 1.00 0.00 WT1 H -ATOM 172 OH2 TIP3W 906 7.027 2.224 13.411 1.00 0.00 WT1 O -ATOM 173 H1 TIP3W 906 6.185 2.801 13.535 1.00 0.00 WT1 H -ATOM 174 H2 TIP3W 906 6.692 1.403 13.742 1.00 0.00 WT1 H -ATOM 175 OH2 TIP3W 908 4.028 7.699 12.776 1.00 0.00 WT1 O -ATOM 176 H1 TIP3W 908 4.577 7.193 12.138 1.00 0.00 WT1 H -ATOM 177 H2 TIP3W 908 3.171 7.320 12.544 1.00 0.00 WT1 H -ATOM 178 OH2 TIP3W 924 12.493 9.451 2.215 1.00 0.00 WT1 O -ATOM 179 H1 TIP3W 924 12.908 9.840 2.987 1.00 0.00 WT1 H -ATOM 180 H2 TIP3W 924 12.982 8.641 2.039 1.00 0.00 WT1 H -ATOM 181 OH2 TIP3W 927 11.177 9.610 7.928 1.00 0.00 WT1 O -ATOM 182 H1 TIP3W 927 10.443 10.172 8.053 1.00 0.00 WT1 H -ATOM 183 H2 TIP3W 927 10.866 8.788 8.298 1.00 0.00 WT1 H -ATOM 184 OH2 TIP3W 928 1.838 3.206 15.398 1.00 0.00 WT1 O -ATOM 185 H1 TIP3W 928 2.201 4.081 15.545 1.00 0.00 WT1 H -ATOM 186 H2 TIP3W 928 2.117 2.999 14.422 1.00 0.00 WT1 H -ATOM 187 OH2 TIP3W 930 1.899 11.624 17.893 1.00 0.00 WT1 O -ATOM 188 H1 TIP3W 930 1.139 11.678 17.305 1.00 0.00 WT1 H -ATOM 189 H2 TIP3W 930 2.258 12.535 17.855 1.00 0.00 WT1 H -ATOM 190 OH2 TIP3W 932 9.220 13.904 17.340 1.00 0.00 WT1 O -ATOM 191 H1 TIP3W 932 10.062 14.198 17.738 1.00 0.00 WT1 H -ATOM 192 H2 TIP3W 932 9.394 12.999 17.102 1.00 0.00 WT1 H -ATOM 193 OH2 TIP3W 933 3.458 9.868 22.419 1.00 0.00 WT1 O -ATOM 194 H1 TIP3W 933 4.398 10.016 22.654 1.00 0.00 WT1 H -ATOM 195 H2 TIP3W 933 3.448 10.189 21.495 1.00 0.00 WT1 H -ATOM 196 OH2 TIP3W 947 15.430 3.274 7.407 1.00 0.00 WT1 O -ATOM 197 H1 TIP3W 947 15.458 2.741 8.157 1.00 0.00 WT1 H -ATOM 198 H2 TIP3W 947 15.933 2.740 6.770 1.00 0.00 WT1 H -ATOM 199 OH2 TIP3W 948 13.134 4.535 6.559 1.00 0.00 WT1 O -ATOM 200 H1 TIP3W 948 12.434 3.932 6.938 1.00 0.00 WT1 H -ATOM 201 H2 TIP3W 948 13.959 4.162 6.965 1.00 0.00 WT1 H -ATOM 202 OH2 TIP3W 951 10.295 14.066 14.320 1.00 0.00 WT1 O -ATOM 203 H1 TIP3W 951 10.592 14.067 15.226 1.00 0.00 WT1 H -ATOM 204 H2 TIP3W 951 9.322 14.226 14.350 1.00 0.00 WT1 H -ATOM 205 OH2 TIP3W 964 7.830 19.751 1.995 1.00 0.00 WT1 O -ATOM 206 H1 TIP3W 964 7.257 19.870 1.247 1.00 0.00 WT1 H -ATOM 207 H2 TIP3W 964 8.329 18.923 1.885 1.00 0.00 WT1 H -ATOM 208 OH2 TIP3W 972 15.027 11.249 9.806 1.00 0.00 WT1 O -ATOM 209 H1 TIP3W 972 15.636 10.953 9.104 1.00 0.00 WT1 H -ATOM 210 H2 TIP3W 972 14.929 12.194 9.545 1.00 0.00 WT1 H -ATOM 211 OH2 TIP3W 974 10.274 11.448 20.959 1.00 0.00 WT1 O -ATOM 212 H1 TIP3W 974 10.893 11.073 21.654 1.00 0.00 WT1 H -ATOM 213 H2 TIP3W 974 10.344 10.891 20.238 1.00 0.00 WT1 H -ATOM 214 OH2 TIP3W 975 11.473 6.075 21.702 1.00 0.00 WT1 O -ATOM 215 H1 TIP3W 975 12.046 5.667 22.431 1.00 0.00 WT1 H -ATOM 216 H2 TIP3W 975 10.554 5.939 22.100 1.00 0.00 WT1 H -ATOM 217 OH2 TIP3W 995 6.800 16.659 17.184 1.00 0.00 WT1 O -ATOM 218 H1 TIP3W 995 7.143 16.649 16.327 1.00 0.00 WT1 H -ATOM 219 H2 TIP3W 995 7.109 17.502 17.568 1.00 0.00 WT1 H -ATOM 220 OH2 TIP3W1007 14.603 18.110 3.213 1.00 0.00 WT1 O -ATOM 221 H1 TIP3W1007 14.275 17.655 3.963 1.00 0.00 WT1 H -ATOM 222 H2 TIP3W1007 13.842 18.606 2.878 1.00 0.00 WT1 H -ATOM 223 OH2 TIP3W1011 4.753 20.139 5.475 1.00 0.00 WT1 O -ATOM 224 H1 TIP3W1011 4.769 21.053 5.846 1.00 0.00 WT1 H -ATOM 225 H2 TIP3W1011 5.663 20.031 5.201 1.00 0.00 WT1 H -ATOM 226 OH2 TIP3W1013 1.615 17.355 14.355 1.00 0.00 WT1 O -ATOM 227 H1 TIP3W1013 1.225 16.480 14.420 1.00 0.00 WT1 H -ATOM 228 H2 TIP3W1013 0.859 17.984 14.051 1.00 0.00 WT1 H -ATOM 229 OH2 TIP3W1014 11.087 15.787 20.150 1.00 0.00 WT1 O -ATOM 230 H1 TIP3W1014 11.221 14.877 19.698 1.00 0.00 WT1 H -ATOM 231 H2 TIP3W1014 11.936 15.940 20.591 1.00 0.00 WT1 H -ATOM 232 OH2 TIP3W1017 9.784 18.060 16.439 1.00 0.00 WT1 O -ATOM 233 H1 TIP3W1017 10.576 18.166 15.922 1.00 0.00 WT1 H -ATOM 234 H2 TIP3W1017 9.941 18.584 17.234 1.00 0.00 WT1 H -ATOM 235 OH2 TIP3W1018 2.369 19.620 10.838 1.00 0.00 WT1 O -ATOM 236 H1 TIP3W1018 2.051 19.425 11.701 1.00 0.00 WT1 H -ATOM 237 H2 TIP3W1018 3.347 19.717 10.923 1.00 0.00 WT1 H -ATOM 238 OH2 TIP3W1027 15.158 15.218 1.453 1.00 0.00 WT1 O -ATOM 239 H1 TIP3W1027 15.286 16.123 1.160 1.00 0.00 WT1 H -ATOM 240 H2 TIP3W1027 14.175 15.219 1.587 1.00 0.00 WT1 H -ATOM 241 OH2 TIP3W1032 7.929 9.601 4.322 1.00 0.00 WT1 O -ATOM 242 H1 TIP3W1032 7.364 10.340 3.912 1.00 0.00 WT1 H -ATOM 243 H2 TIP3W1032 7.318 9.011 4.820 1.00 0.00 WT1 H -ATOM 244 OH2 TIP3W1053 11.585 23.121 19.455 1.00 0.00 WT1 O -ATOM 245 H1 TIP3W1053 12.413 23.205 19.982 1.00 0.00 WT1 H -ATOM 246 H2 TIP3W1053 10.816 23.266 20.095 1.00 0.00 WT1 H -ATOM 247 OH2 TIP3W1301 3.320 1.439 3.693 1.00 0.00 WT1 O -ATOM 248 H1 TIP3W1301 3.018 1.263 2.795 1.00 0.00 WT1 H -ATOM 249 H2 TIP3W1301 4.218 1.737 3.533 1.00 0.00 WT1 H -ATOM 250 OH2 TIP3W1308 8.378 22.836 14.074 1.00 0.00 WT1 O -ATOM 251 H1 TIP3W1308 9.127 23.085 13.478 1.00 0.00 WT1 H -ATOM 252 H2 TIP3W1308 7.806 23.652 14.112 1.00 0.00 WT1 H -ATOM 253 OH2 TIP3W1328 4.539 2.605 8.295 1.00 0.00 WT1 O -ATOM 254 H1 TIP3W1328 5.460 2.702 8.123 1.00 0.00 WT1 H -ATOM 255 H2 TIP3W1328 4.434 1.616 8.363 1.00 0.00 WT1 H -ATOM 256 OH2 TIP3W1344 8.883 21.581 5.760 1.00 0.00 WT1 O -ATOM 257 H1 TIP3W1344 8.705 22.232 6.446 1.00 0.00 WT1 H -ATOM 258 H2 TIP3W1344 9.357 22.008 5.077 1.00 0.00 WT1 H -ATOM 259 OH2 TIP3W1349 12.793 13.364 12.168 1.00 0.00 WT1 O -ATOM 260 H1 TIP3W1349 12.787 13.548 11.223 1.00 0.00 WT1 H -ATOM 261 H2 TIP3W1349 11.995 13.794 12.399 1.00 0.00 WT1 H -ATOM 262 OH2 TIP3W1352 6.667 7.547 9.646 1.00 0.00 WT1 O -ATOM 263 H1 TIP3W1352 6.103 6.975 10.296 1.00 0.00 WT1 H -ATOM 264 H2 TIP3W1352 7.558 7.292 10.046 1.00 0.00 WT1 H -ATOM 265 OH2 TIP3W1354 0.182 23.403 21.361 1.00 0.00 WT1 O -ATOM 266 H1 TIP3W1354 0.301 23.585 22.346 1.00 0.00 WT1 H -ATOM 267 H2 TIP3W1354 1.001 22.867 21.220 1.00 0.00 WT1 H -ATOM 268 OH2 TIP3W1355 11.347 16.007 23.148 1.00 0.00 WT1 O -ATOM 269 H1 TIP3W1355 11.779 15.126 23.087 1.00 0.00 WT1 H -ATOM 270 H2 TIP3W1355 10.586 15.923 22.581 1.00 0.00 WT1 H -ATOM 271 OH2 TIP3W1367 10.129 17.485 6.550 1.00 0.00 WT1 O -ATOM 272 H1 TIP3W1367 9.231 17.467 6.920 1.00 0.00 WT1 H -ATOM 273 H2 TIP3W1367 10.108 16.702 5.985 1.00 0.00 WT1 H -ATOM 274 OH2 TIP3W1370 4.654 5.717 5.023 1.00 0.00 WT1 O -ATOM 275 H1 TIP3W1370 5.059 5.126 4.395 1.00 0.00 WT1 H -ATOM 276 H2 TIP3W1370 5.409 5.785 5.634 1.00 0.00 WT1 H -ATOM 277 OH2 TIP3W1371 12.336 14.905 9.350 1.00 0.00 WT1 O -ATOM 278 H1 TIP3W1371 11.849 15.588 8.883 1.00 0.00 WT1 H -ATOM 279 H2 TIP3W1371 11.568 14.375 9.770 1.00 0.00 WT1 H -ATOM 280 OH2 TIP3W1374 5.488 14.255 13.212 1.00 0.00 WT1 O -ATOM 281 H1 TIP3W1374 6.279 14.126 13.709 1.00 0.00 WT1 H -ATOM 282 H2 TIP3W1374 4.864 13.991 13.878 1.00 0.00 WT1 H -ATOM 283 OH2 TIP3W1387 3.686 8.353 3.401 1.00 0.00 WT1 O -ATOM 284 H1 TIP3W1387 4.494 7.930 3.084 1.00 0.00 WT1 H -ATOM 285 H2 TIP3W1387 3.041 7.727 3.197 1.00 0.00 WT1 H -ATOM 286 OH2 TIP3W1388 15.005 14.526 19.133 1.00 0.00 WT1 O -ATOM 287 H1 TIP3W1388 15.742 13.941 19.238 1.00 0.00 WT1 H -ATOM 288 H2 TIP3W1388 14.746 14.453 18.188 1.00 0.00 WT1 H -ATOM 289 OH2 TIP3W1389 15.427 13.899 13.418 1.00 0.00 WT1 O -ATOM 290 H1 TIP3W1389 15.598 14.703 13.915 1.00 0.00 WT1 H -ATOM 291 H2 TIP3W1389 14.569 14.032 12.994 1.00 0.00 WT1 H -ATOM 292 OH2 TIP3W1392 15.117 16.342 15.320 1.00 0.00 WT1 O -ATOM 293 H1 TIP3W1392 14.190 16.658 15.235 1.00 0.00 WT1 H -ATOM 294 H2 TIP3W1392 15.725 17.080 14.950 1.00 0.00 WT1 H -ATOM 295 OH2 TIP3W1407 13.263 23.513 7.326 1.00 0.00 WT1 O -ATOM 296 H1 TIP3W1407 14.083 23.900 7.689 1.00 0.00 WT1 H -ATOM 297 H2 TIP3W1407 13.669 22.803 6.739 1.00 0.00 WT1 H -ATOM 298 OH2 TIP3W1411 10.030 11.441 3.434 1.00 0.00 WT1 O -ATOM 299 H1 TIP3W1411 9.274 10.827 3.422 1.00 0.00 WT1 H -ATOM 300 H2 TIP3W1411 10.533 11.362 2.661 1.00 0.00 WT1 H -ATOM 301 OH2 TIP3W1412 10.550 9.544 11.315 1.00 0.00 WT1 O -ATOM 302 H1 TIP3W1412 10.055 10.343 11.396 1.00 0.00 WT1 H -ATOM 303 H2 TIP3W1412 11.460 9.846 11.337 1.00 0.00 WT1 H -ATOM 304 OH2 TIP3W1414 2.005 17.796 21.122 1.00 0.00 WT1 O -ATOM 305 H1 TIP3W1414 2.773 17.325 21.598 1.00 0.00 WT1 H -ATOM 306 H2 TIP3W1414 2.173 18.758 21.265 1.00 0.00 WT1 H -ATOM 307 OH2 TIP3W1415 13.553 15.240 21.435 1.00 0.00 WT1 O -ATOM 308 H1 TIP3W1415 14.103 14.959 20.726 1.00 0.00 WT1 H -ATOM 309 H2 TIP3W1415 13.422 14.470 21.979 1.00 0.00 WT1 H -ATOM 310 OH2 TIP3W1418 11.456 2.350 19.585 1.00 0.00 WT1 O -ATOM 311 H1 TIP3W1418 10.731 2.931 19.730 1.00 0.00 WT1 H -ATOM 312 H2 TIP3W1418 11.546 1.862 20.401 1.00 0.00 WT1 H -ATOM 313 OH2 TIP3W1428 13.068 2.914 10.149 1.00 0.00 WT1 O -ATOM 314 H1 TIP3W1428 12.803 2.473 9.295 1.00 0.00 WT1 H -ATOM 315 H2 TIP3W1428 14.010 2.849 10.112 1.00 0.00 WT1 H -ATOM 316 OH2 TIP3W1429 5.450 9.067 5.337 1.00 0.00 WT1 O -ATOM 317 H1 TIP3W1429 4.722 8.840 4.711 1.00 0.00 WT1 H -ATOM 318 H2 TIP3W1429 4.939 8.770 6.117 1.00 0.00 WT1 H -ATOM 319 OH2 TIP3W1433 3.297 18.771 17.303 1.00 0.00 WT1 O -ATOM 320 H1 TIP3W1433 3.913 19.272 17.825 1.00 0.00 WT1 H -ATOM 321 H2 TIP3W1433 3.616 18.935 16.408 1.00 0.00 WT1 H -ATOM 322 OH2 TIP3W1435 6.597 15.954 21.463 1.00 0.00 WT1 O -ATOM 323 H1 TIP3W1435 7.157 15.160 21.200 1.00 0.00 WT1 H -ATOM 324 H2 TIP3W1435 7.205 16.451 22.021 1.00 0.00 WT1 H -ATOM 325 OH2 TIP3W1440 1.443 3.980 18.627 1.00 0.00 WT1 O -ATOM 326 H1 TIP3W1440 1.536 3.050 18.247 1.00 0.00 WT1 H -ATOM 327 H2 TIP3W1440 0.589 4.282 18.256 1.00 0.00 WT1 H -ATOM 328 OH2 TIP3W1451 3.248 22.876 3.701 1.00 0.00 WT1 O -ATOM 329 H1 TIP3W1451 2.662 22.334 4.248 1.00 0.00 WT1 H -ATOM 330 H2 TIP3W1451 4.106 22.410 3.781 1.00 0.00 WT1 H -ATOM 331 OH2 TIP3W1454 8.943 19.607 9.393 1.00 0.00 WT1 O -ATOM 332 H1 TIP3W1454 9.890 19.666 9.174 1.00 0.00 WT1 H -ATOM 333 H2 TIP3W1454 8.551 19.202 8.586 1.00 0.00 WT1 H -ATOM 334 OH2 TIP3W1455 7.534 23.313 22.010 1.00 0.00 WT1 O -ATOM 335 H1 TIP3W1455 7.309 22.777 22.738 1.00 0.00 WT1 H -ATOM 336 H2 TIP3W1455 6.697 23.403 21.532 1.00 0.00 WT1 H -ATOM 337 OH2 TIP3W1457 13.340 13.560 16.477 1.00 0.00 WT1 O -ATOM 338 H1 TIP3W1457 13.400 13.568 15.542 1.00 0.00 WT1 H -ATOM 339 H2 TIP3W1457 12.852 14.406 16.633 1.00 0.00 WT1 H -ATOM 340 OH2 TIP3W1458 8.344 7.845 20.429 1.00 0.00 WT1 O -ATOM 341 H1 TIP3W1458 8.479 8.292 21.236 1.00 0.00 WT1 H -ATOM 342 H2 TIP3W1458 9.102 8.059 19.900 1.00 0.00 WT1 H -ATOM 343 OH2 TIP3W1474 6.901 21.557 9.326 1.00 0.00 WT1 O -ATOM 344 H1 TIP3W1474 7.410 20.744 9.384 1.00 0.00 WT1 H -ATOM 345 H2 TIP3W1474 7.474 22.077 8.759 1.00 0.00 WT1 H -ATOM 346 OH2 TIP3W1494 14.403 7.815 15.212 1.00 0.00 WT1 O -ATOM 347 H1 TIP3W1494 13.532 8.206 14.911 1.00 0.00 WT1 H -ATOM 348 H2 TIP3W1494 14.885 7.681 14.373 1.00 0.00 WT1 H -ATOM 349 OH2 TIP3W1497 6.857 11.138 6.829 1.00 0.00 WT1 O -ATOM 350 H1 TIP3W1497 6.107 11.750 6.800 1.00 0.00 WT1 H -ATOM 351 H2 TIP3W1497 6.480 10.387 6.353 1.00 0.00 WT1 H -ATOM 352 OH2 TIP3W1512 10.309 21.500 11.481 1.00 0.00 WT1 O -ATOM 353 H1 TIP3W1512 11.014 20.928 11.185 1.00 0.00 WT1 H -ATOM 354 H2 TIP3W1512 9.595 20.961 11.183 1.00 0.00 WT1 H -ATOM 355 OH2 TIP3W1532 13.235 22.943 15.633 1.00 0.00 WT1 O -ATOM 356 H1 TIP3W1532 12.613 22.525 16.194 1.00 0.00 WT1 H -ATOM 357 H2 TIP3W1532 14.027 22.981 16.180 1.00 0.00 WT1 H -ATOM 358 OH2 TIP3W1559 6.818 20.066 20.150 1.00 0.00 WT1 O -ATOM 359 H1 TIP3W1559 7.686 20.067 20.626 1.00 0.00 WT1 H -ATOM 360 H2 TIP3W1559 6.969 19.869 19.212 1.00 0.00 WT1 H -ATOM 361 OH2 TIP3W1611 7.975 20.030 22.745 1.00 0.00 WT1 O -ATOM 362 H1 TIP3W1611 8.632 20.654 22.435 1.00 0.00 WT1 H -ATOM 363 H2 TIP3W1611 7.441 20.490 23.501 1.00 0.00 WT1 H -ATOM 364 OH2 TIP3W1707 12.113 0.921 4.942 1.00 0.00 WT1 O -ATOM 365 H1 TIP3W1707 12.819 0.635 5.562 1.00 0.00 WT1 H -ATOM 366 H2 TIP3W1707 11.814 1.896 5.223 1.00 0.00 WT1 H -ATOM 367 OH2 TIP3W1723 9.197 4.375 15.964 1.00 0.00 WT1 O -ATOM 368 H1 TIP3W1723 9.163 3.590 15.387 1.00 0.00 WT1 H -ATOM 369 H2 TIP3W1723 8.516 4.167 16.604 1.00 0.00 WT1 H -ATOM 370 OH2 TIP3W1725 2.421 3.775 5.058 1.00 0.00 WT1 O -ATOM 371 H1 TIP3W1725 2.684 2.934 4.652 1.00 0.00 WT1 H -ATOM 372 H2 TIP3W1725 3.219 4.340 5.048 1.00 0.00 WT1 H -ATOM 373 OH2 TIP3W1729 6.794 6.875 22.997 1.00 0.00 WT1 O -ATOM 374 H1 TIP3W1729 7.166 7.815 23.093 1.00 0.00 WT1 H -ATOM 375 H2 TIP3W1729 5.834 7.029 23.036 1.00 0.00 WT1 H -ATOM 376 OH2 TIP3W1730 11.518 2.141 14.835 1.00 0.00 WT1 O -ATOM 377 H1 TIP3W1730 11.356 2.769 14.101 1.00 0.00 WT1 H -ATOM 378 H2 TIP3W1730 12.345 1.727 14.583 1.00 0.00 WT1 H -ATOM 379 OH2 TIP3W1733 3.174 1.584 16.976 1.00 0.00 WT1 O -ATOM 380 H1 TIP3W1733 2.370 2.077 16.810 1.00 0.00 WT1 H -ATOM 381 H2 TIP3W1733 3.270 0.961 16.252 1.00 0.00 WT1 H -ATOM 382 OH2 TIP3W1746 10.848 10.071 18.631 1.00 0.00 WT1 O -ATOM 383 H1 TIP3W1746 10.345 10.477 17.907 1.00 0.00 WT1 H -ATOM 384 H2 TIP3W1746 11.663 10.551 18.638 1.00 0.00 WT1 H -ATOM 385 OH2 TIP3W1752 12.069 8.766 23.082 1.00 0.00 WT1 O -ATOM 386 H1 TIP3W1752 12.023 9.290 23.888 1.00 0.00 WT1 H -ATOM 387 H2 TIP3W1752 11.590 7.956 23.400 1.00 0.00 WT1 H -ATOM 388 OH2 TIP3W1764 5.141 1.611 0.499 1.00 0.00 WT1 O -ATOM 389 H1 TIP3W1764 4.697 1.110 1.234 1.00 0.00 WT1 H -ATOM 390 H2 TIP3W1764 6.031 1.302 0.586 1.00 0.00 WT1 H -ATOM 391 OH2 TIP3W1771 2.509 3.505 12.910 1.00 0.00 WT1 O -ATOM 392 H1 TIP3W1771 2.114 4.138 12.315 1.00 0.00 WT1 H -ATOM 393 H2 TIP3W1771 2.715 2.712 12.383 1.00 0.00 WT1 H -ATOM 394 OH2 TIP3W1773 14.354 1.352 14.004 1.00 0.00 WT1 O -ATOM 395 H1 TIP3W1773 14.694 0.623 14.565 1.00 0.00 WT1 H -ATOM 396 H2 TIP3W1773 14.573 2.195 14.426 1.00 0.00 WT1 H -ATOM 397 OH2 TIP3W1788 14.578 23.489 17.850 1.00 0.00 WT1 O -ATOM 398 H1 TIP3W1788 15.476 23.267 17.861 1.00 0.00 WT1 H -ATOM 399 H2 TIP3W1788 14.359 23.484 18.771 1.00 0.00 WT1 H -ATOM 400 OH2 TIP3W1789 5.461 6.754 1.943 1.00 0.00 WT1 O -ATOM 401 H1 TIP3W1789 6.412 6.627 2.018 1.00 0.00 WT1 H -ATOM 402 H2 TIP3W1789 5.209 5.956 1.434 1.00 0.00 WT1 H -ATOM 403 OH2 TIP3W1795 14.101 1.902 22.316 1.00 0.00 WT1 O -ATOM 404 H1 TIP3W1795 14.886 2.398 22.002 1.00 0.00 WT1 H -ATOM 405 H2 TIP3W1795 14.108 1.041 21.813 1.00 0.00 WT1 H -ATOM 406 OH2 TIP3W1813 6.142 11.858 16.052 1.00 0.00 WT1 O -ATOM 407 H1 TIP3W1813 5.762 12.642 15.675 1.00 0.00 WT1 H -ATOM 408 H2 TIP3W1813 5.566 11.146 15.661 1.00 0.00 WT1 H -ATOM 409 OH2 TIP3W1814 11.187 19.104 18.681 1.00 0.00 WT1 O -ATOM 410 H1 TIP3W1814 12.029 18.566 18.863 1.00 0.00 WT1 H -ATOM 411 H2 TIP3W1814 10.574 18.773 19.364 1.00 0.00 WT1 H -ATOM 412 OH2 TIP3W1829 11.780 13.509 0.983 1.00 0.00 WT1 O -ATOM 413 H1 TIP3W1829 12.311 13.422 1.794 1.00 0.00 WT1 H -ATOM 414 H2 TIP3W1829 12.379 13.816 0.300 1.00 0.00 WT1 H -ATOM 415 OH2 TIP3W1830 13.410 13.796 3.206 1.00 0.00 WT1 O -ATOM 416 H1 TIP3W1830 12.860 13.342 3.952 1.00 0.00 WT1 H -ATOM 417 H2 TIP3W1830 14.378 13.624 3.486 1.00 0.00 WT1 H -ATOM 418 OH2 TIP3W1831 7.314 0.228 9.152 1.00 0.00 WT1 O -ATOM 419 H1 TIP3W1831 7.447 0.196 8.157 1.00 0.00 WT1 H -ATOM 420 H2 TIP3W1831 8.219 0.336 9.426 1.00 0.00 WT1 H -ATOM 421 OH2 TIP3W1853 0.289 10.538 13.468 1.00 0.00 WT1 O -ATOM 422 H1 TIP3W1853 0.286 10.937 12.602 1.00 0.00 WT1 H -ATOM 423 H2 TIP3W1853 1.262 10.357 13.669 1.00 0.00 WT1 H -ATOM 424 OH2 TIP3W1856 12.440 12.407 5.370 1.00 0.00 WT1 O -ATOM 425 H1 TIP3W1856 11.652 11.887 5.105 1.00 0.00 WT1 H -ATOM 426 H2 TIP3W1856 12.893 11.867 5.977 1.00 0.00 WT1 H -ATOM 427 OH2 TIP3W1871 6.968 11.629 2.353 1.00 0.00 WT1 O -ATOM 428 H1 TIP3W1871 6.575 10.896 1.807 1.00 0.00 WT1 H -ATOM 429 H2 TIP3W1871 7.083 12.290 1.590 1.00 0.00 WT1 H -ATOM 430 OH2 TIP3W1873 13.533 10.550 7.160 1.00 0.00 WT1 O -ATOM 431 H1 TIP3W1873 12.608 10.309 7.490 1.00 0.00 WT1 H -ATOM 432 H2 TIP3W1873 14.008 10.940 7.925 1.00 0.00 WT1 H -ATOM 433 OH2 TIP3W1874 13.043 18.831 22.933 1.00 0.00 WT1 O -ATOM 434 H1 TIP3W1874 13.439 17.936 22.986 1.00 0.00 WT1 H -ATOM 435 H2 TIP3W1874 12.139 18.764 23.145 1.00 0.00 WT1 H -ATOM 436 OH2 TIP3W1894 11.706 15.811 16.829 1.00 0.00 WT1 O -ATOM 437 H1 TIP3W1894 10.892 16.347 16.590 1.00 0.00 WT1 H -ATOM 438 H2 TIP3W1894 12.344 16.466 17.162 1.00 0.00 WT1 H -ATOM 439 OH2 TIP3W1911 11.642 19.030 4.866 1.00 0.00 WT1 O -ATOM 440 H1 TIP3W1911 10.752 18.786 5.209 1.00 0.00 WT1 H -ATOM 441 H2 TIP3W1911 11.534 19.147 3.897 1.00 0.00 WT1 H -ATOM 442 OH2 TIP3W1912 13.550 21.522 9.565 1.00 0.00 WT1 O -ATOM 443 H1 TIP3W1912 13.279 21.744 8.655 1.00 0.00 WT1 H -ATOM 444 H2 TIP3W1912 13.859 22.419 9.914 1.00 0.00 WT1 H -ATOM 445 OH2 TIP3W1914 12.001 20.877 14.108 1.00 0.00 WT1 O -ATOM 446 H1 TIP3W1914 12.060 21.566 14.774 1.00 0.00 WT1 H -ATOM 447 H2 TIP3W1914 11.186 21.104 13.629 1.00 0.00 WT1 H -ATOM 448 OH2 TIP3W1915 12.814 17.906 7.383 1.00 0.00 WT1 O -ATOM 449 H1 TIP3W1915 13.379 17.410 6.688 1.00 0.00 WT1 H -ATOM 450 H2 TIP3W1915 11.963 17.994 6.954 1.00 0.00 WT1 H -ATOM 451 OH2 TIP3W1952 15.989 19.751 4.862 1.00 0.00 WT1 O -ATOM 452 H1 TIP3W1952 15.952 20.632 4.460 1.00 0.00 WT1 H -ATOM 453 H2 TIP3W1952 15.557 19.210 4.188 1.00 0.00 WT1 H -ATOM 454 OH2 TIP3W2123 10.963 1.737 11.790 1.00 0.00 WT1 O -ATOM 455 H1 TIP3W2123 10.319 2.240 11.334 1.00 0.00 WT1 H -ATOM 456 H2 TIP3W2123 11.709 2.167 11.210 1.00 0.00 WT1 H -ATOM 457 OH2 TIP3W2163 5.526 8.369 14.858 1.00 0.00 WT1 O -ATOM 458 H1 TIP3W2163 4.950 8.218 14.072 1.00 0.00 WT1 H -ATOM 459 H2 TIP3W2163 4.945 8.919 15.363 1.00 0.00 WT1 H -ATOM 460 OH2 TIP3W2165 14.776 4.939 12.443 1.00 0.00 WT1 O -ATOM 461 H1 TIP3W2165 14.636 5.952 12.252 1.00 0.00 WT1 H -ATOM 462 H2 TIP3W2165 13.865 4.712 12.604 1.00 0.00 WT1 H -ATOM 463 OH2 TIP3W2167 7.529 4.508 1.396 1.00 0.00 WT1 O -ATOM 464 H1 TIP3W2167 8.313 4.582 0.857 1.00 0.00 WT1 H -ATOM 465 H2 TIP3W2167 6.783 4.511 0.768 1.00 0.00 WT1 H -ATOM 466 OH2 TIP3W2172 11.435 0.836 22.059 1.00 0.00 WT1 O -ATOM 467 H1 TIP3W2172 11.858 0.103 21.657 1.00 0.00 WT1 H -ATOM 468 H2 TIP3W2172 12.219 1.281 22.508 1.00 0.00 WT1 H -ATOM 469 OH2 TIP3W2227 11.200 4.151 3.471 1.00 0.00 WT1 O -ATOM 470 H1 TIP3W2227 12.053 4.360 3.928 1.00 0.00 WT1 H -ATOM 471 H2 TIP3W2227 10.572 4.426 4.138 1.00 0.00 WT1 H -ATOM 472 OH2 TIP3W2231 4.884 4.081 13.713 1.00 0.00 WT1 O -ATOM 473 H1 TIP3W2231 4.970 4.746 14.373 1.00 0.00 WT1 H -ATOM 474 H2 TIP3W2231 3.932 3.975 13.593 1.00 0.00 WT1 H -ATOM 475 OH2 TIP3W2244 13.867 4.624 3.954 1.00 0.00 WT1 O -ATOM 476 H1 TIP3W2244 14.067 4.641 4.904 1.00 0.00 WT1 H -ATOM 477 H2 TIP3W2244 14.122 5.494 3.648 1.00 0.00 WT1 H -ATOM 478 OH2 TIP3W2270 3.174 11.159 5.954 1.00 0.00 WT1 O -ATOM 479 H1 TIP3W2270 3.904 11.073 5.352 1.00 0.00 WT1 H -ATOM 480 H2 TIP3W2270 3.204 12.104 6.129 1.00 0.00 WT1 H -ATOM 481 OH2 TIP3W2272 12.922 2.911 17.412 1.00 0.00 WT1 O -ATOM 482 H1 TIP3W2272 12.421 2.431 18.089 1.00 0.00 WT1 H -ATOM 483 H2 TIP3W2272 12.240 2.996 16.701 1.00 0.00 WT1 H -ATOM 484 OH2 TIP3W2277 13.644 7.961 20.946 1.00 0.00 WT1 O -ATOM 485 H1 TIP3W2277 13.183 7.158 20.680 1.00 0.00 WT1 H -ATOM 486 H2 TIP3W2277 13.018 8.315 21.687 1.00 0.00 WT1 H -ATOM 487 OH2 TIP3W2280 6.612 3.396 17.042 1.00 0.00 WT1 O -ATOM 488 H1 TIP3W2280 6.138 2.987 17.830 1.00 0.00 WT1 H -ATOM 489 H2 TIP3W2280 6.248 2.883 16.306 1.00 0.00 WT1 H -ATOM 490 OH2 TIP3W2288 3.628 15.453 9.684 1.00 0.00 WT1 O -ATOM 491 H1 TIP3W2288 3.604 16.368 9.365 1.00 0.00 WT1 H -ATOM 492 H2 TIP3W2288 3.266 15.478 10.592 1.00 0.00 WT1 H -ATOM 493 OH2 TIP3W2293 1.641 18.264 8.136 1.00 0.00 WT1 O -ATOM 494 H1 TIP3W2293 0.755 18.490 8.008 1.00 0.00 WT1 H -ATOM 495 H2 TIP3W2293 1.981 19.003 8.665 1.00 0.00 WT1 H -ATOM 496 OH2 TIP3W2295 8.716 0.819 21.571 1.00 0.00 WT1 O -ATOM 497 H1 TIP3W2295 8.359 0.399 22.460 1.00 0.00 WT1 H -ATOM 498 H2 TIP3W2295 9.622 1.046 21.690 1.00 0.00 WT1 H -ATOM 499 OH2 TIP3W2309 14.269 10.001 4.369 1.00 0.00 WT1 O -ATOM 500 H1 TIP3W2309 14.973 10.528 4.752 1.00 0.00 WT1 H -ATOM 501 H2 TIP3W2309 13.690 9.859 5.092 1.00 0.00 WT1 H -ATOM 502 OH2 TIP3W2311 14.691 13.817 9.050 1.00 0.00 WT1 O -ATOM 503 H1 TIP3W2311 15.162 14.372 8.385 1.00 0.00 WT1 H -ATOM 504 H2 TIP3W2311 13.821 14.250 9.113 1.00 0.00 WT1 H -ATOM 505 OH2 TIP3W2316 12.273 5.424 10.404 1.00 0.00 WT1 O -ATOM 506 H1 TIP3W2316 12.384 4.472 10.210 1.00 0.00 WT1 H -ATOM 507 H2 TIP3W2316 13.153 5.714 10.501 1.00 0.00 WT1 H -ATOM 508 OH2 TIP3W2317 3.759 13.253 15.143 1.00 0.00 WT1 O -ATOM 509 H1 TIP3W2317 3.552 13.546 16.059 1.00 0.00 WT1 H -ATOM 510 H2 TIP3W2317 2.862 13.321 14.740 1.00 0.00 WT1 H -ATOM 511 OH2 TIP3W2335 7.319 14.432 15.015 1.00 0.00 WT1 O -ATOM 512 H1 TIP3W2335 7.633 15.319 14.742 1.00 0.00 WT1 H -ATOM 513 H2 TIP3W2335 7.702 14.303 15.933 1.00 0.00 WT1 H -ATOM 514 OH2 TIP3W2357 3.117 11.819 10.070 1.00 0.00 WT1 O -ATOM 515 H1 TIP3W2357 3.490 12.496 9.523 1.00 0.00 WT1 H -ATOM 516 H2 TIP3W2357 3.937 11.583 10.539 1.00 0.00 WT1 H -ATOM 517 OH2 TIP3W2358 0.549 16.393 10.366 1.00 0.00 WT1 O -ATOM 518 H1 TIP3W2358 1.292 16.322 11.016 1.00 0.00 WT1 H -ATOM 519 H2 TIP3W2358 0.665 17.283 9.972 1.00 0.00 WT1 H -ATOM 520 OH2 TIP3W2607 10.050 5.605 5.758 1.00 0.00 WT1 O -ATOM 521 H1 TIP3W2607 10.155 6.554 5.556 1.00 0.00 WT1 H -ATOM 522 H2 TIP3W2607 10.797 5.389 6.309 1.00 0.00 WT1 H -ATOM 523 OH2 TIP3W2608 7.881 3.518 5.700 1.00 0.00 WT1 O -ATOM 524 H1 TIP3W2608 8.550 4.225 5.812 1.00 0.00 WT1 H -ATOM 525 H2 TIP3W2608 7.070 3.834 6.169 1.00 0.00 WT1 H -ATOM 526 OH2 TIP3W2634 8.559 3.515 11.535 1.00 0.00 WT1 O -ATOM 527 H1 TIP3W2634 8.435 4.298 12.155 1.00 0.00 WT1 H -ATOM 528 H2 TIP3W2634 7.955 2.899 11.952 1.00 0.00 WT1 H -ATOM 529 OH2 TIP3W2669 13.039 10.511 11.777 1.00 0.00 WT1 O -ATOM 530 H1 TIP3W2669 13.825 10.589 11.282 1.00 0.00 WT1 H -ATOM 531 H2 TIP3W2669 12.883 11.473 11.916 1.00 0.00 WT1 H -ATOM 532 OH2 TIP3W2691 15.316 3.976 15.033 1.00 0.00 WT1 O -ATOM 533 H1 TIP3W2691 15.353 4.265 14.065 1.00 0.00 WT1 H -ATOM 534 H2 TIP3W2691 14.585 4.533 15.460 1.00 0.00 WT1 H -ATOM 535 OH2 TIP3W2694 8.400 5.552 13.557 1.00 0.00 WT1 O -ATOM 536 H1 TIP3W2694 9.070 5.240 14.185 1.00 0.00 WT1 H -ATOM 537 H2 TIP3W2694 7.739 5.945 14.163 1.00 0.00 WT1 H -ATOM 538 OH2 TIP3W2714 4.281 21.161 19.066 1.00 0.00 WT1 O -ATOM 539 H1 TIP3W2714 5.157 21.058 19.381 1.00 0.00 WT1 H -ATOM 540 H2 TIP3W2714 4.169 22.110 18.904 1.00 0.00 WT1 H -ATOM 541 OH2 TIP3W2732 13.870 7.474 12.187 1.00 0.00 WT1 O -ATOM 542 H1 TIP3W2732 13.209 8.073 12.633 1.00 0.00 WT1 H -ATOM 543 H2 TIP3W2732 14.457 8.029 11.659 1.00 0.00 WT1 H -ATOM 544 OH2 TIP3W2735 13.600 17.247 9.998 1.00 0.00 WT1 O -ATOM 545 H1 TIP3W2735 13.256 16.385 10.107 1.00 0.00 WT1 H -ATOM 546 H2 TIP3W2735 13.616 17.337 9.047 1.00 0.00 WT1 H -ATOM 547 OH2 TIP3W2758 10.099 18.083 21.099 1.00 0.00 WT1 O -ATOM 548 H1 TIP3W2758 10.453 17.258 20.699 1.00 0.00 WT1 H -ATOM 549 H2 TIP3W2758 9.398 17.746 21.690 1.00 0.00 WT1 H -ATOM 550 OH2 TIP3W2778 15.465 7.955 17.814 1.00 0.00 WT1 O -ATOM 551 H1 TIP3W2778 15.150 7.979 16.932 1.00 0.00 WT1 H -ATOM 552 H2 TIP3W2778 14.706 7.563 18.306 1.00 0.00 WT1 H -ATOM 553 OH2 TIP3W3010 9.016 4.086 8.814 1.00 0.00 WT1 O -ATOM 554 H1 TIP3W3010 9.377 5.001 8.813 1.00 0.00 WT1 H -ATOM 555 H2 TIP3W3010 8.726 3.741 9.661 1.00 0.00 WT1 H -ATOM 556 OH2 TIP3W3072 6.439 5.144 7.455 1.00 0.00 WT1 O -ATOM 557 H1 TIP3W3072 7.310 4.836 7.837 1.00 0.00 WT1 H -ATOM 558 H2 TIP3W3072 6.121 5.819 8.116 1.00 0.00 WT1 H -ATOM 559 OH2 TIP3W3096 13.331 4.563 23.416 1.00 0.00 WT1 O -ATOM 560 H1 TIP3W3096 14.315 4.772 23.360 1.00 0.00 WT1 H -ATOM 561 H2 TIP3W3096 13.215 3.678 23.134 1.00 0.00 WT1 H -ATOM 562 OH2 TIP3W3134 11.401 21.480 17.136 1.00 0.00 WT1 O -ATOM 563 H1 TIP3W3134 11.522 22.112 17.856 1.00 0.00 WT1 H -ATOM 564 H2 TIP3W3134 11.255 20.672 17.636 1.00 0.00 WT1 H -ATOM 565 OH2 TIP3W3173 12.076 4.645 13.566 1.00 0.00 WT1 O -ATOM 566 H1 TIP3W3173 12.000 5.522 13.148 1.00 0.00 WT1 H -ATOM 567 H2 TIP3W3173 11.827 4.835 14.443 1.00 0.00 WT1 H -ATOM 568 OH2 TIP3W3177 9.131 1.075 15.841 1.00 0.00 WT1 O -ATOM 569 H1 TIP3W3177 9.948 1.463 15.412 1.00 0.00 WT1 H -ATOM 570 H2 TIP3W3177 9.113 0.161 15.464 1.00 0.00 WT1 H -ATOM 571 OH2 TIP3W3196 7.694 8.338 16.687 1.00 0.00 WT1 O -ATOM 572 H1 TIP3W3196 7.323 8.081 17.508 1.00 0.00 WT1 H -ATOM 573 H2 TIP3W3196 6.991 8.476 16.072 1.00 0.00 WT1 H -ATOM 574 OH2 TIP3W3218 11.912 13.212 19.726 1.00 0.00 WT1 O -ATOM 575 H1 TIP3W3218 12.854 13.225 19.881 1.00 0.00 WT1 H -ATOM 576 H2 TIP3W3218 11.504 12.764 20.555 1.00 0.00 WT1 H -ATOM 577 OH2 TIP3W3223 5.115 19.820 22.632 1.00 0.00 WT1 O -ATOM 578 H1 TIP3W3223 4.270 19.752 22.092 1.00 0.00 WT1 H -ATOM 579 H2 TIP3W3223 5.800 19.585 21.996 1.00 0.00 WT1 H -ATOM 580 OH2 TIP3W3303 14.170 23.047 20.478 1.00 0.00 WT1 O -ATOM 581 H1 TIP3W3303 15.015 22.883 20.902 1.00 0.00 WT1 H -ATOM 582 H2 TIP3W3303 13.757 22.177 20.579 1.00 0.00 WT1 H -ATOM 583 OH2 TIP3W3304 13.163 20.489 20.636 1.00 0.00 WT1 O -ATOM 584 H1 TIP3W3304 12.450 20.171 20.104 1.00 0.00 WT1 H -ATOM 585 H2 TIP3W3304 13.220 19.875 21.393 1.00 0.00 WT1 H -ATOM 586 OH2 TIP3W3447 11.316 2.273 7.956 1.00 0.00 WT1 O -ATOM 587 H1 TIP3W3447 11.391 1.358 8.151 1.00 0.00 WT1 H -ATOM 588 H2 TIP3W3447 10.423 2.479 8.181 1.00 0.00 WT1 H -ATOM 589 OH2 TIP3W3545 10.407 6.649 8.888 1.00 0.00 WT1 O -ATOM 590 H1 TIP3W3545 9.810 7.215 9.386 1.00 0.00 WT1 H -ATOM 591 H2 TIP3W3545 11.077 6.417 9.547 1.00 0.00 WT1 H -ATOM 592 OH2 TIP3W3596 7.574 19.420 4.717 1.00 0.00 WT1 O -ATOM 593 H1 TIP3W3596 7.704 19.335 3.679 1.00 0.00 WT1 H -ATOM 594 H2 TIP3W3596 7.970 20.255 4.957 1.00 0.00 WT1 H -ATOM 595 OH2 TIP3W3650 12.254 19.676 2.229 1.00 0.00 WT1 O -ATOM 596 H1 TIP3W3650 12.678 20.538 2.358 1.00 0.00 WT1 H -ATOM 597 H2 TIP3W3650 12.115 19.535 1.250 1.00 0.00 WT1 H -ATOM 598 OH2 TIP3W3660 14.036 7.730 6.644 1.00 0.00 WT1 O -ATOM 599 H1 TIP3W3660 14.358 7.138 7.346 1.00 0.00 WT1 H -ATOM 600 H2 TIP3W3660 13.886 8.589 7.123 1.00 0.00 WT1 H -ATOM 601 OH2 TIP3W3977 8.900 7.310 11.290 1.00 0.00 WT1 O -ATOM 602 H1 TIP3W3977 8.739 6.706 12.078 1.00 0.00 WT1 H -ATOM 603 H2 TIP3W3977 9.555 8.003 11.531 1.00 0.00 WT1 H -ATOM 604 OH2 TIP3W4012 9.495 14.416 1.979 1.00 0.00 WT1 O -ATOM 605 H1 TIP3W4012 10.354 14.203 1.548 1.00 0.00 WT1 H -ATOM 606 H2 TIP3W4012 9.165 13.566 2.099 1.00 0.00 WT1 H -ATOM 607 OH2 TIP3W4036 13.605 5.353 19.280 1.00 0.00 WT1 O -ATOM 608 H1 TIP3W4036 13.658 4.527 18.812 1.00 0.00 WT1 H -ATOM 609 H2 TIP3W4036 12.688 5.367 19.516 1.00 0.00 WT1 H -ATOM 610 OH2 TIP3W4074 7.334 17.973 7.090 1.00 0.00 WT1 O -ATOM 611 H1 TIP3W4074 7.571 18.390 6.200 1.00 0.00 WT1 H -ATOM 612 H2 TIP3W4074 6.533 17.444 6.885 1.00 0.00 WT1 H -ATOM 613 OH2 TIP3W4077 13.912 11.040 17.383 1.00 0.00 WT1 O -ATOM 614 H1 TIP3W4077 13.913 10.932 16.423 1.00 0.00 WT1 H -ATOM 615 H2 TIP3W4077 13.612 11.935 17.518 1.00 0.00 WT1 H -ATOM 616 OH2 TIP3W4501 14.682 11.334 14.388 1.00 0.00 WT1 O -ATOM 617 H1 TIP3W4501 15.236 11.941 13.876 1.00 0.00 WT1 H -ATOM 618 H2 TIP3W4501 14.266 10.683 13.763 1.00 0.00 WT1 H -ATOM 619 OH2 TIP3W4515 12.414 9.004 13.909 1.00 0.00 WT1 O -ATOM 620 H1 TIP3W4515 11.523 8.931 14.184 1.00 0.00 WT1 H -ATOM 621 H2 TIP3W4515 12.375 9.766 13.286 1.00 0.00 WT1 H -ATOM 622 OH2 TIP3W4809 15.898 3.293 1.648 1.00 0.00 WT1 O -ATOM 623 H1 TIP3W4809 15.837 3.977 2.359 1.00 0.00 WT1 H -ATOM 624 H2 TIP3W4809 15.065 2.796 1.789 1.00 0.00 WT1 H -ATOM 625 OH2 TIP3W6240 3.080 0.949 11.788 1.00 0.00 WT1 O -ATOM 626 H1 TIP3W6240 3.690 0.500 11.172 1.00 0.00 WT1 H -ATOM 627 H2 TIP3W6240 2.196 0.556 11.641 1.00 0.00 WT1 H -ATOM 628 OH2 TIP3W6671 0.897 12.813 20.940 1.00 0.00 WT1 O -ATOM 629 H1 TIP3W6671 1.234 13.577 21.489 1.00 0.00 WT1 H -ATOM 630 H2 TIP3W6671 1.110 12.083 21.442 1.00 0.00 WT1 H -ATOM 631 OH2 TIP3W7222 6.255 9.802 0.364 1.00 0.00 WT1 O -ATOM 632 H1 TIP3W7222 6.954 9.121 0.671 1.00 0.00 WT1 H -ATOM 633 H2 TIP3W7222 5.459 9.264 0.196 1.00 0.00 WT1 H -ATOM 634 OH2 TIP3W7479 6.140 3.669 3.704 1.00 0.00 WT1 O -ATOM 635 H1 TIP3W7479 6.732 3.837 2.949 1.00 0.00 WT1 H -ATOM 636 H2 TIP3W7479 6.807 3.408 4.378 1.00 0.00 WT1 H -ATOM 637 OH2 TIP3W7510 5.150 11.685 11.994 1.00 0.00 WT1 O -ATOM 638 H1 TIP3W7510 5.312 12.641 12.020 1.00 0.00 WT1 H -ATOM 639 H2 TIP3W7510 5.614 11.405 12.778 1.00 0.00 WT1 H -ATOM 640 OH2 TIP3W7563 5.196 19.304 15.315 1.00 0.00 WT1 O -ATOM 641 H1 TIP3W7563 5.227 20.213 14.942 1.00 0.00 WT1 H -ATOM 642 H2 TIP3W7563 5.252 18.720 14.569 1.00 0.00 WT1 H -ATOM 643 OH2 TIP3W7630 2.179 13.464 7.177 1.00 0.00 WT1 O -ATOM 644 H1 TIP3W7630 2.719 14.061 7.737 1.00 0.00 WT1 H -ATOM 645 H2 TIP3W7630 1.640 13.021 7.843 1.00 0.00 WT1 H -ATOM 646 OH2 TIP3W7631 1.926 21.439 17.027 1.00 0.00 WT1 O -ATOM 647 H1 TIP3W7631 2.672 21.817 16.545 1.00 0.00 WT1 H -ATOM 648 H2 TIP3W7631 2.398 20.912 17.662 1.00 0.00 WT1 H -ATOM 649 OH2 TIP3W7707 0.688 2.781 7.114 1.00 0.00 WT1 O -ATOM 650 H1 TIP3W7707 1.488 3.190 6.703 1.00 0.00 WT1 H -ATOM 651 H2 TIP3W7707 0.053 3.429 6.930 1.00 0.00 WT1 H -ATOM 652 OH2 TIP3W7985 0.449 7.366 9.140 1.00 0.00 WT1 O -ATOM 653 H1 TIP3W7985 0.202 6.479 9.095 1.00 0.00 WT1 H -ATOM 654 H2 TIP3W7985 0.796 7.563 8.256 1.00 0.00 WT1 H -ATOM 655 OH2 TIP3W8023 0.913 12.320 0.937 1.00 0.00 WT1 O -ATOM 656 H1 TIP3W8023 0.623 11.700 0.268 1.00 0.00 WT1 H -ATOM 657 H2 TIP3W8023 1.290 11.784 1.628 1.00 0.00 WT1 H -ATOM 658 OH2 TIP3W8029 7.889 16.997 14.360 1.00 0.00 WT1 O -ATOM 659 H1 TIP3W8029 7.935 17.181 13.358 1.00 0.00 WT1 H -ATOM 660 H2 TIP3W8029 8.602 17.562 14.734 1.00 0.00 WT1 H -ATOM 661 OH2 TIP3W8046 3.230 22.882 11.736 1.00 0.00 WT1 O -ATOM 662 H1 TIP3W8046 3.601 21.950 11.670 1.00 0.00 WT1 H -ATOM 663 H2 TIP3W8046 2.861 22.992 10.853 1.00 0.00 WT1 H -ATOM 664 OH2 TIP3W8064 4.620 22.335 7.130 1.00 0.00 WT1 O -ATOM 665 H1 TIP3W8064 3.754 22.591 7.590 1.00 0.00 WT1 H -ATOM 666 H2 TIP3W8064 5.178 22.349 7.907 1.00 0.00 WT1 H -ATOM 667 OH2 TIP3W8068 1.124 22.962 13.514 1.00 0.00 WT1 O -ATOM 668 H1 TIP3W8068 1.837 22.901 12.860 1.00 0.00 WT1 H -ATOM 669 H2 TIP3W8068 0.685 23.799 13.310 1.00 0.00 WT1 H -ATOM 670 OH2 TIP3W8364 8.561 10.924 16.881 1.00 0.00 WT1 O -ATOM 671 H1 TIP3W8364 7.916 11.188 16.202 1.00 0.00 WT1 H -ATOM 672 H2 TIP3W8364 8.309 10.008 17.123 1.00 0.00 WT1 H -ATOM 673 OH2 TIP3W8403 4.751 19.009 2.814 1.00 0.00 WT1 O -ATOM 674 H1 TIP3W8403 4.754 18.978 3.760 1.00 0.00 WT1 H -ATOM 675 H2 TIP3W8403 5.300 18.306 2.612 1.00 0.00 WT1 H -ATOM 676 OH2 TIP3W8411 3.406 0.117 14.493 1.00 0.00 WT1 O -ATOM 677 H1 TIP3W8411 3.348 0.244 13.546 1.00 0.00 WT1 H -ATOM 678 H2 TIP3W8411 4.378 0.190 14.724 1.00 0.00 WT1 H -ATOM 679 OH2 TIP3W8425 2.278 3.922 1.200 1.00 0.00 WT1 O -ATOM 680 H1 TIP3W8425 2.701 3.392 0.560 1.00 0.00 WT1 H -ATOM 681 H2 TIP3W8425 1.556 3.406 1.415 1.00 0.00 WT1 H -ATOM 682 OH2 TIP3W8441 6.246 21.216 13.564 1.00 0.00 WT1 O -ATOM 683 H1 TIP3W8441 7.127 21.533 13.794 1.00 0.00 WT1 H -ATOM 684 H2 TIP3W8441 5.802 22.075 13.455 1.00 0.00 WT1 H -ATOM 685 OH2 TIP3W8466 5.348 15.459 5.988 1.00 0.00 WT1 O -ATOM 686 H1 TIP3W8466 4.942 16.211 6.465 1.00 0.00 WT1 H -ATOM 687 H2 TIP3W8466 4.964 14.679 6.422 1.00 0.00 WT1 H -ATOM 688 OH2 TIP3W8468 1.312 13.577 13.829 1.00 0.00 WT1 O -ATOM 689 H1 TIP3W8468 1.594 13.350 12.963 1.00 0.00 WT1 H -ATOM 690 H2 TIP3W8468 0.905 14.443 13.634 1.00 0.00 WT1 H -ATOM 691 OH2 TIP3W8491 10.395 21.375 22.397 1.00 0.00 WT1 O -ATOM 692 H1 TIP3W8491 10.900 20.680 22.794 1.00 0.00 WT1 H -ATOM 693 H2 TIP3W8491 10.682 22.154 22.828 1.00 0.00 WT1 H -ATOM 694 OH2 TIP3W8528 6.013 16.085 3.326 1.00 0.00 WT1 O -ATOM 695 H1 TIP3W8528 6.016 16.035 4.292 1.00 0.00 WT1 H -ATOM 696 H2 TIP3W8528 5.249 15.516 3.046 1.00 0.00 WT1 H -ATOM 697 OH2 TIP3W8534 2.184 22.110 9.500 1.00 0.00 WT1 O -ATOM 698 H1 TIP3W8534 1.913 21.297 9.998 1.00 0.00 WT1 H -ATOM 699 H2 TIP3W8534 1.389 22.233 8.964 1.00 0.00 WT1 H -ATOM 700 OH2 TIP3W8536 3.207 13.979 17.772 1.00 0.00 WT1 O -ATOM 701 H1 TIP3W8536 3.947 14.082 18.373 1.00 0.00 WT1 H -ATOM 702 H2 TIP3W8536 2.585 14.685 17.921 1.00 0.00 WT1 H -ATOM 703 OH2 TIP3W8548 13.639 16.098 5.269 1.00 0.00 WT1 O -ATOM 704 H1 TIP3W8548 14.099 15.394 4.872 1.00 0.00 WT1 H -ATOM 705 H2 TIP3W8548 12.755 15.724 5.343 1.00 0.00 WT1 H -ATOM 706 OH2 TIP3W8556 1.981 16.635 18.663 1.00 0.00 WT1 O -ATOM 707 H1 TIP3W8556 1.921 17.181 19.529 1.00 0.00 WT1 H -ATOM 708 H2 TIP3W8556 2.656 17.117 18.156 1.00 0.00 WT1 H -ATOM 709 OH2 TIP3W8760 13.457 20.491 6.545 1.00 0.00 WT1 O -ATOM 710 H1 TIP3W8760 13.544 19.713 6.959 1.00 0.00 WT1 H -ATOM 711 H2 TIP3W8760 13.199 20.170 5.601 1.00 0.00 WT1 H -ATOM 712 OH2 TIP3W8780 3.438 8.099 0.316 1.00 0.00 WT1 O -ATOM 713 H1 TIP3W8780 2.547 7.847 0.577 1.00 0.00 WT1 H -ATOM 714 H2 TIP3W8780 3.889 7.775 1.093 1.00 0.00 WT1 H -ATOM 715 OH2 TIP3W8801 9.016 15.690 9.485 1.00 0.00 WT1 O -ATOM 716 H1 TIP3W8801 9.158 14.769 9.701 1.00 0.00 WT1 H -ATOM 717 H2 TIP3W8801 8.537 15.554 8.652 1.00 0.00 WT1 H -ATOM 718 OH2 TIP3W8822 1.562 6.536 12.239 1.00 0.00 WT1 O -ATOM 719 H1 TIP3W8822 0.960 7.250 12.049 1.00 0.00 WT1 H -ATOM 720 H2 TIP3W8822 1.197 5.827 11.553 1.00 0.00 WT1 H -ATOM 721 OH2 TIP3W8829 1.314 9.385 7.173 1.00 0.00 WT1 O -ATOM 722 H1 TIP3W8829 1.333 8.706 6.444 1.00 0.00 WT1 H -ATOM 723 H2 TIP3W8829 2.056 9.953 6.980 1.00 0.00 WT1 H -ATOM 724 OH2 TIP3W8843 7.572 0.420 3.478 1.00 0.00 WT1 O -ATOM 725 H1 TIP3W8843 7.636 0.339 2.503 1.00 0.00 WT1 H -ATOM 726 H2 TIP3W8843 6.628 0.234 3.530 1.00 0.00 WT1 H -ATOM 727 OH2 TIP3W8845 1.133 7.080 5.078 1.00 0.00 WT1 O -ATOM 728 H1 TIP3W8845 1.201 7.102 4.137 1.00 0.00 WT1 H -ATOM 729 H2 TIP3W8845 0.358 6.549 5.302 1.00 0.00 WT1 H -ATOM 730 OH2 TIP3W8865 11.515 22.342 4.827 1.00 0.00 WT1 O -ATOM 731 H1 TIP3W8865 10.875 21.911 4.185 1.00 0.00 WT1 H -ATOM 732 H2 TIP3W8865 11.205 21.919 5.694 1.00 0.00 WT1 H -ATOM 733 OH2 TIP3W8869 5.279 5.755 11.457 1.00 0.00 WT1 O -ATOM 734 H1 TIP3W8869 4.504 5.333 10.967 1.00 0.00 WT1 H -ATOM 735 H2 TIP3W8869 5.564 4.986 12.019 1.00 0.00 WT1 H -ATOM 736 OH2 TIP3W8887 8.890 21.041 16.070 1.00 0.00 WT1 O -ATOM 737 H1 TIP3W8887 8.698 21.572 15.300 1.00 0.00 WT1 H -ATOM 738 H2 TIP3W8887 9.800 21.340 16.244 1.00 0.00 WT1 H -ATOM 739 OH2 TIP3W8895 6.000 11.283 22.324 1.00 0.00 WT1 O -ATOM 740 H1 TIP3W8895 5.866 12.057 22.939 1.00 0.00 WT1 H -ATOM 741 H2 TIP3W8895 5.863 11.634 21.452 1.00 0.00 WT1 H -ATOM 742 OH2 TIP3W8905 7.834 14.408 7.527 1.00 0.00 WT1 O -ATOM 743 H1 TIP3W8905 7.105 14.717 6.993 1.00 0.00 WT1 H -ATOM 744 H2 TIP3W8905 8.194 13.714 6.926 1.00 0.00 WT1 H -ATOM 745 OH2 TIP3W8931 5.667 11.812 19.542 1.00 0.00 WT1 O -ATOM 746 H1 TIP3W8931 5.647 12.743 19.497 1.00 0.00 WT1 H -ATOM 747 H2 TIP3W8931 5.889 11.629 18.618 1.00 0.00 WT1 H -ATOM 748 OH2 TIP3W8932 12.997 18.576 15.207 1.00 0.00 WT1 O -ATOM 749 H1 TIP3W8932 12.617 19.193 14.493 1.00 0.00 WT1 H -ATOM 750 H2 TIP3W8932 13.582 19.163 15.737 1.00 0.00 WT1 H -ATOM 751 OH2 TIP3W8935 0.675 11.574 10.952 1.00 0.00 WT1 O -ATOM 752 H1 TIP3W8935 1.597 11.546 10.574 1.00 0.00 WT1 H -ATOM 753 H2 TIP3W8935 0.265 12.150 10.339 1.00 0.00 WT1 H -ATOM 754 OH2 TIP3W8949 8.782 17.187 2.362 1.00 0.00 WT1 O -ATOM 755 H1 TIP3W8949 8.004 16.786 2.797 1.00 0.00 WT1 H -ATOM 756 H2 TIP3W8949 9.140 16.422 1.970 1.00 0.00 WT1 H -ATOM 757 OH2 TIP3W8956 2.113 6.516 21.893 1.00 0.00 WT1 O -ATOM 758 H1 TIP3W8956 2.170 5.576 22.160 1.00 0.00 WT1 H -ATOM 759 H2 TIP3W8956 2.446 6.949 22.707 1.00 0.00 WT1 H -ATOM 760 OH2 TIP3W8977 2.583 16.123 12.046 1.00 0.00 WT1 O -ATOM 761 H1 TIP3W8977 3.491 16.508 12.059 1.00 0.00 WT1 H -ATOM 762 H2 TIP3W8977 2.312 16.312 12.887 1.00 0.00 WT1 H -ATOM 763 OH2 TIP3W8988 2.246 20.883 4.995 1.00 0.00 WT1 O -ATOM 764 H1 TIP3W8988 1.611 20.097 4.885 1.00 0.00 WT1 H -ATOM 765 H2 TIP3W8988 3.079 20.473 5.195 1.00 0.00 WT1 H -ATOM 766 OH2 TIP3W9082 8.156 17.564 11.520 1.00 0.00 WT1 O -ATOM 767 H1 TIP3W9082 8.355 18.345 10.921 1.00 0.00 WT1 H -ATOM 768 H2 TIP3W9082 8.334 16.820 10.874 1.00 0.00 WT1 H -ATOM 769 OH2 TIP3W9096 2.915 14.197 3.393 1.00 0.00 WT1 O -ATOM 770 H1 TIP3W9096 2.155 14.414 3.916 1.00 0.00 WT1 H -ATOM 771 H2 TIP3W9096 2.719 13.333 3.011 1.00 0.00 WT1 H -ATOM 772 OH2 TIP3W9226 8.578 0.832 6.351 1.00 0.00 WT1 O -ATOM 773 H1 TIP3W9226 7.928 0.530 5.693 1.00 0.00 WT1 H -ATOM 774 H2 TIP3W9226 8.563 1.801 6.335 1.00 0.00 WT1 H -ATOM 775 OH2 TIP3W9241 7.287 10.172 13.815 1.00 0.00 WT1 O -ATOM 776 H1 TIP3W9241 6.631 9.473 14.077 1.00 0.00 WT1 H -ATOM 777 H2 TIP3W9241 8.119 9.669 13.852 1.00 0.00 WT1 H -ATOM 778 OH2 TIP3W9250 3.347 10.487 19.814 1.00 0.00 WT1 O -ATOM 779 H1 TIP3W9250 2.792 10.955 19.188 1.00 0.00 WT1 H -ATOM 780 H2 TIP3W9250 4.264 10.639 19.456 1.00 0.00 WT1 H -END diff --git a/tools/moltemplate/examples/file_conversion_examples/read_PDB_file_examples/waterSPCE_from_PDBfile/moltemplate_files/spce.lt b/tools/moltemplate/examples/file_conversion_examples/read_PDB_file_examples/waterSPCE_from_PDBfile/moltemplate_files/spce.lt deleted file mode 100644 index 019911c19b..0000000000 --- a/tools/moltemplate/examples/file_conversion_examples/read_PDB_file_examples/waterSPCE_from_PDBfile/moltemplate_files/spce.lt +++ /dev/null @@ -1,52 +0,0 @@ -# file "spce.lt" -# -# H1 H2 -# \ / -# O - -SPCE { - - write_once("In Init") { - # -- Default styles (for solo "SPCE" water) -- - units real - atom_style full - # (Hybrid force fields were not necessary but are used for portability.) - pair_style hybrid lj/charmm/coul/long 9.0 10.0 10.0 - bond_style hybrid harmonic - angle_style hybrid harmonic - kspace_style pppm 0.0001 - pair_modify mix arithmetic - } - - write("Data Atoms") { - $atom:O $mol:. @atom:O -0.8476 0.0000000 0.00000 0.000000 - $atom:H1 $mol:. @atom:H 0.4238 0.8164904 0.00000 0.5773590 - $atom:H2 $mol:. @atom:H 0.4238 -0.8164904 0.00000 0.5773590 - } - - write_once("Data Masses") { - @atom:O 15.9994 - @atom:H 1.008 - } - - write("Data Bonds") { - $bond:OH1 @bond:OH $atom:O $atom:H1 - $bond:OH2 @bond:OH $atom:O $atom:H2 - } - - write("Data Angles") { - $angle:HOH @angle:HOH $atom:H1 $atom:O $atom:H2 - } - - write_once("In Settings") { - bond_coeff @bond:OH harmonic 1000.0 1.0 - angle_coeff @angle:HOH harmonic 1000.0 109.47 - pair_coeff @atom:O @atom:O lj/charmm/coul/long 0.1553 3.166 - pair_coeff @atom:H @atom:H lj/charmm/coul/long 0.0 2.058 - group spce type @atom:O @atom:H - fix fShakeSPCE spce shake 0.0001 10 100 b @bond:OH a @angle:HOH - # (Remember to "unfix" fShakeSPCE during minimization.) - } - -} # end of definition of "SPCE" water molecule type - diff --git a/tools/moltemplate/examples/file_conversion_examples/read_PDB_file_examples/waterSPCE_from_PDBfile/moltemplate_files/system.lt b/tools/moltemplate/examples/file_conversion_examples/read_PDB_file_examples/waterSPCE_from_PDBfile/moltemplate_files/system.lt deleted file mode 100644 index 274d8aeb11..0000000000 --- a/tools/moltemplate/examples/file_conversion_examples/read_PDB_file_examples/waterSPCE_from_PDBfile/moltemplate_files/system.lt +++ /dev/null @@ -1,16 +0,0 @@ -import "spce.lt" - -wat = new SPCE [260] - - - - - - - -# Open up the PDB file to count the number of water molecules inside. (Or just -# divide the number of atoms by 3). Put that in between the brackets ("[260]") -# -# The command above does not set the positions of the atoms. -# So they will have to be loaded later from a PDB or an XYZ file. -# (For example, using "moltemplate.sh -pdb solvate.pdb system.lt") diff --git a/tools/moltemplate/examples/file_conversion_examples/read_PDB_file_examples/waterSPCE_from_PDBfile/run.in.npt b/tools/moltemplate/examples/file_conversion_examples/read_PDB_file_examples/waterSPCE_from_PDBfile/run.in.npt deleted file mode 100644 index 4d8af42b5d..0000000000 --- a/tools/moltemplate/examples/file_conversion_examples/read_PDB_file_examples/waterSPCE_from_PDBfile/run.in.npt +++ /dev/null @@ -1,48 +0,0 @@ -# PREREQUISITES: -# -# You must use moltemplate.sh to create 3 files: -# system.data system.in.init system.in.settings -# (Follow the instructions in README_setup.sh, or run it using ./README_sh.) - -# ------------------------------- Initialization Section -------------------- - -include system.in.init - -# ------------------------------- Atom Definition Section ------------------- - -read_data system.data - -# ------------------------------- Settings Section -------------------------- - -include system.in.settings - -# ------------------------------- Run Section ------------------------------- - - -# -- minimization protocol -- - -# Note: The minimization step is not necessary in this example. However -# in general, it's always a good idea to minimize the system beforehand. -# fShakeSPCE was defined in system.in.settings. It is incompatible with "minimize". -unfix fShakeSPCE -minimize 1.0e-3 1.0e-5 100000 400000 -# Now read "system.in.settings" in order to redefine fShakeSPCE again: -include system.in.settings - -# -- simulation protocol -- - - -timestep 1.0 -dump 1 all custom 200 traj_npt.lammpstrj id mol type x y z ix iy iz -fix fxnpt all npt temp 300.0 300.0 100.0 iso 1.0 1.0 1000.0 drag 1.0 -thermo 100 - -run 10000 - -# Now that the system's temperature has become more equilibrated, -# we can increase the timestep: - -timestep 2.0 -run 50000 - -write_data system_after_npt.data diff --git a/tools/moltemplate/examples/file_conversion_examples/read_PDB_file_examples/waterSPCE_from_PDBfile/run.in.nvt b/tools/moltemplate/examples/file_conversion_examples/read_PDB_file_examples/waterSPCE_from_PDBfile/run.in.nvt deleted file mode 100644 index d039a5370f..0000000000 --- a/tools/moltemplate/examples/file_conversion_examples/read_PDB_file_examples/waterSPCE_from_PDBfile/run.in.nvt +++ /dev/null @@ -1,61 +0,0 @@ -# PREREQUISITES: -# -# 1) You must use moltemplate.sh to create 3 files: -# system.data system.in.init system.in.settings -# (Follow the instructions in README_setup.sh, or run it using ./README_sh.) -# 2) You must equilibrate the system beforehand using "run.in.npt". -# This will create the file "system_after_npt.data" which this file reads. -# (Note: I have not verified that this equilibration protocol works well.) - -# ------------------------------- Initialization Section -------------------- - -include system.in.init - -# ------------------------------- Atom Definition Section ------------------- - -# Read the coordinates generated by an earlier NPT simulation - -read_data system_after_npt.data - - -# (The "write_restart" and "read_restart" commands were buggy in 2012, -# but they should work also. I prefer "write_data" and "read_data".) - -# ------------------------------- Settings Section -------------------------- - -include system.in.settings - -# ------------------------------- Run Section ------------------------------- - - -# -- minimization protocol -- -# Note: If you are reading the data file created by run.in.npt, -# then you should not need to minimize the system beforehand. -# fShakeSPCE was defined in system.in.settings. -# (It is incompatible with "minimize".) - -unfix fShakeSPCE -minimize 1.0e-5 1.0e-7 100000 400000 - -# Now read "system.in.settings" in order to redefine fShakeSPCE again: - -include system.in.settings - - -# -- simulation protocol -- - - -timestep 1.0 -dump 1 all custom 500 traj_nvt.lammpstrj id mol type x y z ix iy iz -fix fxnvt all nvt temp 300.0 300.0 500.0 tchain 1 -thermo 500 - -run 10000 - -# Now that the system's temperature has become more equilibrated, -# we can increase the timestep: - -timestep 2.0 -run 50000 - -write_data system_after_nvt.data diff --git a/tools/moltemplate/examples/force_field_AMBER/WARNING.TXT b/tools/moltemplate/examples/force_field_AMBER/WARNING.TXT deleted file mode 100644 index 9d6d0e1b35..0000000000 --- a/tools/moltemplate/examples/force_field_AMBER/WARNING.TXT +++ /dev/null @@ -1,54 +0,0 @@ -# -------- WARNING: -------- - -This directory contains some examples of all-atom simulations using the GAFF -force field, prepared using moltemplate. - -This software is experimental, and the force-fields and equilbration protocols -have not been tested carefully by me. There is no gaurantee that simulations -prepared using moltemplate will reproduce the behavior of AmberTools/AMBER. - -# -------- REQUEST FOR HELP: -------- - -If you notice a problem with these examples, please report it. -Peer-review is the only way to improve this software (or any software). -Other suggestions are also welcome! - -(Contact jewett.aij@gmail.com, 2013-12-01) - - ---- Charge --- - -Some force-fields (such as OPLSAA) can assign charge based on atom type. -But AMBER simulations, charge is usually assigned using AmberTools which -typically estimates partial charges using quantum chemistry. - -You must assign partial charges to each atom or LAMMPS will crash -when it discovers your system has no charged particles. -(To disable this, change the pair_style to lj/cut or something similar.) - -You have to assign charge manually, just as you would for an ordinary molecule. - -(For example, charges are explicitly assigned to each atom in these files: - waterTIP3P+isobutane/moltemplate_files/isobutane.lt - hexadecane/moltemplate_files/ch2group.lt - hexadecane/moltemplate_files/ch3group.lt) - -(How you do this is up to you. In these examples, I obtained -partial charges from the OPLSAA parameter file located here: -http://dasher.wustl.edu/tinker/distribution/params/oplsaa.prm) - ---- Improper angles --- - -I am also uncertain whether the improper angle interactions generated by -moltemplate are equivalent to those generated by AmberTools. (I think they are, -but I am worried that I might have listed the atom types in the wrong order.) - ---- Bloated lammps input scripts --- - -LAMMPS input scripts prepared using moltemplate contain the entire contents -of the GAFF force-field, even when simulating small systems with just a few -atom types. - -This is harmless, but if you want to get rid of this extra information, -follow the README instructions in the "optional_cleanup" directories. - diff --git a/tools/moltemplate/examples/force_field_AMBER/benzene/README.TXT b/tools/moltemplate/examples/force_field_AMBER/benzene/README.TXT deleted file mode 100644 index ba0f5e6f45..0000000000 --- a/tools/moltemplate/examples/force_field_AMBER/benzene/README.TXT +++ /dev/null @@ -1,10 +0,0 @@ -This example shows how to build a box of benzene molecules using the -AMBER/GAFF force-field. - -step 1) -To build the files which LAMMPS needs, follow the instructions in: -README_setup.sh - -step 2) -To run LAMMPS with these files, follow these instructions: -README_run.sh diff --git a/tools/moltemplate/examples/force_field_AMBER/benzene/README_run.sh b/tools/moltemplate/examples/force_field_AMBER/benzene/README_run.sh deleted file mode 100755 index 9f923a6c7e..0000000000 --- a/tools/moltemplate/examples/force_field_AMBER/benzene/README_run.sh +++ /dev/null @@ -1,39 +0,0 @@ -# --- Running LAMMPS --- -# -------- REQUIREMENTS: --------- -# 1) This example requires building LAMMPS with the "USER-MISC" package. -# (because it makes use of "gaff.lt" which uses dihedral_style fourier) -# To do this, type "make yes-user-misc" before compiling LAMMPS. -# http://lammps.sandia.gov/doc/Section_start.html#start_3 -# -------- PREREQUISITES: -------- -# The 2 files "run.in.npt", and "run.in.nvt" are LAMMPS -# input scripts which link to the input scripts and data files -# you hopefully have created earlier with moltemplate.sh: -# system.in.init, system.in.settings, system.data -# If not, carry out the instructions in "README_setup.sh". -# -# -- Instructions: -- -# If "lmp_mpi" is the name of the command you use to invoke lammps, -# then you would run lammps on these files this way: - - -lmp_mpi -i run.in.npt # minimization and simulation at constant pressure -lmp_mpi -i run.in.nvt # minimization and simulation at constant volume - -#(Note: The constant volume simulation lacks pressure equilibration. These are -# completely separate simulations. The results of the constant pressure -# simulation might be ignored when beginning the simulation at constant -# volume. (This is because restart files in LAMMPS don't always work, -# and I was spending a lot of time trying to convince people it was a -# LAMMPS bug, instead of a moltemplate bug, so I disabled restart files.) -# Read the "run.in.nvt" file to find out how to use the "read_restart" -# command to load the results of the pressure-equilibration simulation, -# before beginning a constant-volume run. - - - - - -# If you have compiled the MPI version of lammps, you can run lammps in parallel -#mpirun -np 4 lmp_mpi -i run.in.npt -#mpirun -np 4 lmp_mpi -i run.in.nvt -# (assuming you have 4 processors available) diff --git a/tools/moltemplate/examples/force_field_AMBER/benzene/README_setup.sh b/tools/moltemplate/examples/force_field_AMBER/benzene/README_setup.sh deleted file mode 100755 index c2db73b457..0000000000 --- a/tools/moltemplate/examples/force_field_AMBER/benzene/README_setup.sh +++ /dev/null @@ -1,26 +0,0 @@ - -# Create LAMMPS input files this way: -cd moltemplate_files - - # run moltemplate - - moltemplate.sh system.lt - - # This will generate various files with names ending in *.in* and *.data. - # Move them to the directory where you plan to run LAMMPS (in this case "../") - mv -f system.data system.in* ../ - - # Optional: - # The "./output_ttree/" directory is full of temporary files generated by - # moltemplate. They can be useful for debugging, but are usually thrown away. - #rm -rf output_ttree/ - -cd ../ - - -# Optional: -# Note: The system.data and system.in.settings files contain extra information -# for atoms defined in GAFF which you are not using in this simulation. This -# is harmless, but if you to delete this information from your -# system.in.settings and system.in.data files, follow the instructions in -# this script: "optional_cleanup/README_remove_irrelevant_info.sh" diff --git a/tools/moltemplate/examples/force_field_AMBER/benzene/README_visualize.txt b/tools/moltemplate/examples/force_field_AMBER/benzene/README_visualize.txt deleted file mode 100644 index 019afc1444..0000000000 --- a/tools/moltemplate/examples/force_field_AMBER/benzene/README_visualize.txt +++ /dev/null @@ -1,87 +0,0 @@ - - ------- To view a lammps trajectory in VMD -------- - - -1) Build a PSF file for use in viewing with VMD. - -This step works with VMD 1.9 and topotools 1.2. -(Older versions, like VMD 1.8.6, don't support this.) - - -a) Start VMD -b) Menu Extensions->Tk Console -c) Enter: - -(I assume that the the DATA file is called "system.data") - - topo readlammpsdata system.data full - animate write psf system.psf - -2) - -Later, to Load a trajectory in VMD: - - Start VMD - Select menu: File->New Molecule - -Browse to select the PSF file you created above, and load it. - (Don't close the window yet.) - -Browse to select the trajectory file. - If necessary, for "file type" select: "LAMMPS Trajectory" - Load it. - - ---- A note on trajectory format: ----- -If the trajectory is a DUMP file, then make sure the it contains the -information you need for pbctools (see below. I've been using this -command in my LAMMPS scripts to create the trajectories: - - dump 1 all custom 5000 DUMP_FILE.lammpstrj id mol type x y z ix iy iz - -It's a good idea to use an atom_style which supports molecule-ID numbers -so that you can assign a molecule-ID number to each atom. (I think this -is needed to wrap atom coordinates without breaking molecules in half.) - -Of course, you don't have to save your trajectories in DUMP format, -(other formats like DCD work fine) I just mention dump files -because these are the files I'm familiar with. - -3) ----- Wrap the coordinates to the unit cell - (without cutting the molecules in half) - -a) Start VMD -b) Load the trajectory in VMD (see above) -c) Menu Extensions->Tk Console -d) Try entering these commands: - - pbc wrap -compound res -all - pbc box - - ----- Optional ---- - Sometimes the solvent or membrane obscures the view of the solute. - It can help to shift the location of the periodic boundary box - To shift the box in the y direction (for example) do this: - - pbc wrap -compound res -all -shiftcenterrel {0.0 0.15 0.0} - pbc box -shiftcenterrel {0.0 0.15 0.0} - - Distances are measured in units of box-length fractions, not Angstroms. - - Alternately if you have a solute whose atoms are all of type 1, - then you can also try this to center the box around it: - - pbc wrap -sel type=1 -all -centersel type=2 -center com - -4) - You should check if your periodic boundary conditions are too small. - To do that: - select Graphics->Representations menu option - click on the "Periodic" tab, and - click on the "+x", "-x", "+y", "-y", "+z", "-z" checkboxes. - -5) Optional: If you like, change the atom types in the PSF file so - that VMD recognizes the atom types, use something like: - -sed -e 's/ 1 1 / C C /g' < system.psf > temp1.psf -sed -e 's/ 2 2 / H H /g' < temp1.psf > temp2.psf -sed -e 's/ 3 3 / P P /g' < temp2.psf > system.psf - -(If you do this, it might effect step 2 above.) diff --git a/tools/moltemplate/examples/force_field_AMBER/benzene/moltemplate_files/benzene.lt b/tools/moltemplate/examples/force_field_AMBER/benzene/moltemplate_files/benzene.lt deleted file mode 100644 index 26ef1d5358..0000000000 --- a/tools/moltemplate/examples/force_field_AMBER/benzene/moltemplate_files/benzene.lt +++ /dev/null @@ -1,51 +0,0 @@ - -import "gaff.lt" - -# The "gaff.lt" file is usually located in "src/moltemplate_force_fields". -# Excerpt: -# -# @atom:ca # Sp2 C in pure aromatic systems -# @atom:ha # H bonded to aromatic carbon -# -# I looked up the charge of each atom using the OPLSAA parameters -# from the "oplsaa.prm" file distributed with TINKER -# http://dasher.wustl.edu/tinker/distribution/params/oplsaa.prm -# --------------------------------------------------------------- -# This is NOT how AmberTools assigns charge, and it will NOT -# reproduce the behavior of AMBER force-fields. - - -Benzene inherits GAFF { - - # atomID molID atomType charge X Y Z - write('Data Atoms') { - $atom:C1 $mol @atom:ca -0.115 5.274 1.999 -8.568 - $atom:C2 $mol @atom:ca -0.115 6.627 2.018 -8.209 - $atom:C3 $mol @atom:ca -0.115 7.366 0.829 -8.202 - $atom:C4 $mol @atom:ca -0.115 6.752 -0.379 -8.554 - $atom:C5 $mol @atom:ca -0.115 5.399 -0.398 -8.912 - $atom:C6 $mol @atom:ca -0.115 4.660 0.791 -8.919 - $atom:H11 $mol @atom:ha 0.115 4.704 2.916 -8.573 - $atom:H21 $mol @atom:ha 0.115 7.101 2.950 -7.938 - $atom:H31 $mol @atom:ha 0.115 8.410 0.844 -7.926 - $atom:H41 $mol @atom:ha 0.115 7.322 -1.296 -8.548 - $atom:H51 $mol @atom:ha 0.115 4.925 -1.330 -9.183 - $atom:H61 $mol @atom:ha 0.115 3.616 0.776 -9.196 - } - - write('Data Bond List') { - $bond:C12 $atom:C1 $atom:C2 - $bond:C23 $atom:C2 $atom:C3 - $bond:C34 $atom:C3 $atom:C4 - $bond:C45 $atom:C4 $atom:C5 - $bond:C56 $atom:C5 $atom:C6 - $bond:C61 $atom:C6 $atom:C1 - $bond:C1H1 $atom:C1 $atom:H11 - $bond:C2H2 $atom:C2 $atom:H21 - $bond:C3H3 $atom:C3 $atom:H31 - $bond:C4H4 $atom:C4 $atom:H41 - $bond:C5H5 $atom:C5 $atom:H51 - $bond:C6H6 $atom:C6 $atom:H61 - } - -} # Benzene diff --git a/tools/moltemplate/examples/force_field_AMBER/benzene/moltemplate_files/system.lt b/tools/moltemplate/examples/force_field_AMBER/benzene/moltemplate_files/system.lt deleted file mode 100644 index 002c538dad..0000000000 --- a/tools/moltemplate/examples/force_field_AMBER/benzene/moltemplate_files/system.lt +++ /dev/null @@ -1,14 +0,0 @@ -import "benzene.lt" # <- defines the "Benzene" molecule type. - - -# Periodic boundary conditions: -write_once("Data Boundary") { - 0.0 64.00 xlo xhi - 0.0 64.00 ylo yhi - 0.0 64.00 zlo zhi -} - -benzenes = new Benzene [8].move(8,0,0) - [8].move(0,8,0) - [8].move(0,0,8) - diff --git a/tools/moltemplate/examples/force_field_AMBER/benzene/optional_cleanup/README_remove_irrelevant_info.sh b/tools/moltemplate/examples/force_field_AMBER/benzene/optional_cleanup/README_remove_irrelevant_info.sh deleted file mode 100755 index 3251991775..0000000000 --- a/tools/moltemplate/examples/force_field_AMBER/benzene/optional_cleanup/README_remove_irrelevant_info.sh +++ /dev/null @@ -1,63 +0,0 @@ - # MOST USERS CAN IGNORE THIS FILE - # - # Unfortunately, as of 2014-4-19, the system.data and system.in.settings file - # which are created by moltemplate.sh contain a lot of irrelevant information, - # such as definition of parameters for atom types not present in the current - # system. This extra information takes up about 1 MB. - # - # This appears to be harmless. - # (Loading this extra information does not seem to slow down LAMMPS.) - # - # --------- OPTIONAL STEPS FOR STRIPPING OUT JUNK --------- - # - # However if you want to eliminate this junk from these files - # For now, we can strip this out using ltemplify.py to build a new .lt file. - # - # NOTE: If you decide to use this script, it was meant to be run it from - # the parent directory (../) (If you run it from somewhere else, be sure to - # modify the "PATH_TO_DATA_FILE" and "PATH_TO_OUTPUT_TTREE" variables below.) - # - # I suggest you do this in a temporary_directory - - PATH_TO_DATA_FILE="." - - pushd "$PATH_TO_DATA_FILE" - - mkdir new_lt_file - cd new_lt_file/ - - # now run ltemplify.py - - ltemplify.py ../system.in.init ../system.in.settings ../system.data > system.lt - - # This creates a new .LT file named "system.lt" in the local directory. - - # The ltemplify.py script also does not copy the boundary dimensions. - # We must do this manually. - # If you did NOT throw away the "Data Boundary" file usually located in - # "moltemplate_files/output_ttree/Data Boundary" - # then you can copy that information from this file into system.lt - - PATH_TO_OUTPUT_TTREE="../moltemplate_files/output_ttree" - - echo "write_once(\"Data Boundary\") {" >> system.lt - cat "$PATH_TO_OUTPUT_TTREE/Data Boundary" >> system.lt - echo "}" >> system.lt - echo "" >> system.lt - - # Now, run moltemplate on this new .LT file. - moltemplate.sh system.lt - # This will create: "system.data" "system.in.init" "system.in.settings." - - # That's it. The new "system.data" and system.in.* files should - # be ready to run in LAMMPS. - - # Now copy the system.data and system.in.* files to the place where - # you plan to run LAMMPS - mv -f system.data system.in.* ../ - cd ../ - - # Now delete all of the temporary files we generated - rm -rf new_lt_file/ - popd - diff --git a/tools/moltemplate/examples/force_field_AMBER/benzene/run.in.npt b/tools/moltemplate/examples/force_field_AMBER/benzene/run.in.npt deleted file mode 100644 index b2ee94440a..0000000000 --- a/tools/moltemplate/examples/force_field_AMBER/benzene/run.in.npt +++ /dev/null @@ -1,72 +0,0 @@ -# PREREQUISITES: -# -# You must use moltemplate.sh to create 3 files: -# system.data system.in.init system.in.settings -# (Follow the instructions in README_setup.sh, -# or run the file as a script using ./README_setup.sh) - -# ------------------------------- Initialization Section -------------------- - -include "system.in.init" - -# ------------------------------- Atom Definition Section ------------------- - -read_data "system.data" - -# ------------------------------- Settings Section -------------------------- - -include "system.in.settings" - -# ------------------------------- Run Section ------------------------------- - - -# -- minimization protocol -- - -minimize 1.0e-4 1.0e-6 100000 400000 - -# -- simulation protocol -- - -timestep 1.0 - -thermo 100 -dump 1 all custom 5000 traj_npt.lammpstrj id mol type x y z ix iy iz - -print "---------------------------------------------------------------------------" -print "First, use Langevin dynamics to randomize the initial shape of the molecules" -print "---------------------------------------------------------------------------" - - -fix 1 all momentum 100 linear 0 0 0 -fix fxlan all langevin 1000.0 1000.0 5000.0 123456 # temp: 1000 K -fix fxnve all nve - -run 20000 -unfix fxlan -unfix fxnve - - - -print "---------------------------------------------------------------------------" -print "Optional: use short high pressure run to get rid of small bubbles." -print " (In case there are any. I'm not certain there are." -print " Later we will restore ordinary pressure.)" -print "---------------------------------------------------------------------------" -fix fxlan all langevin 298.0 298.0 5000 123456 # temp: 298 K -fix fxnph all nph iso 500.0 500.0 1000.0 # pressure: 500 barr - -run 80000 -unfix fxlan -unfix fxnph - - - -print "---------------------------------------------------------------------------" -print "--- Now continue the simulation using a Nose-Hoover Thermostat/Barostat ---" -print "---------------------------------------------------------------------------" -# temperature: 298 K, pressure: 1 barr -fix fxnpt all npt temp 298.0 298.0 100.0 iso 1.0 1.0 1000.0 drag 1.0 -#thermo_modify flush yes - -run 5000000 - -write_data system_after_npt.data diff --git a/tools/moltemplate/examples/force_field_AMBER/benzene/run.in.nvt b/tools/moltemplate/examples/force_field_AMBER/benzene/run.in.nvt deleted file mode 100644 index 3901723ddd..0000000000 --- a/tools/moltemplate/examples/force_field_AMBER/benzene/run.in.nvt +++ /dev/null @@ -1,51 +0,0 @@ -# PREREQUISITES: -# -# 1) You must use moltemplate.sh to create 3 files: -# system.data system.in.init system.in.settings -# (Follow the instructions in README_setup.sh, -# or run the file as a script using ./README_setup.sh) -# 2) You must equilibrate the system beforehand using "run.in.npt". -# This will create the file "system_after_npt.data" which this file reads. -# (Note: I have not verified that this equilibration protocol works well.) - -# ------------------------------- Initialization Section -------------------- - -include "system.in.init" - -# ------------------------------- Atom Definition Section ------------------- - -# Read the coordinates generated by an earlier NPT simulation - -read_data "system_after_npt.data" - -# OPLSAA atom charges are stored in a separate file. -# Load that file now: - -include "system.in.charges" - -# ------------------------------- Settings Section -------------------------- - -include "system.in.settings" - - -# (The "write_restart" and "read_restart" commands were buggy in 2012, -# but they should work also. I prefer "write_data" and "read_data".) - -# ------------------------------- Settings Section -------------------------- - -include system.in.settings - -# ------------------------------- Run Section ------------------------------- - -# -- simulation protocol -- - - -timestep 1.0 -dump 1 all custom 5000 traj_nvt.lammpstrj id mol type x y z ix iy iz -fix fxnvt all nvt temp 300.0 300.0 500.0 tchain 1 -thermo 500 -#thermo_modify flush yes - -run 200000 - -write_restart system_after_nvt.data diff --git a/tools/moltemplate/examples/force_field_AMBER/ethylene+benzene/README.TXT b/tools/moltemplate/examples/force_field_AMBER/ethylene+benzene/README.TXT deleted file mode 100644 index b02f184dde..0000000000 --- a/tools/moltemplate/examples/force_field_AMBER/ethylene+benzene/README.TXT +++ /dev/null @@ -1,13 +0,0 @@ -This example shows how to simulate a mixture of ethylene and benzene -using the AMBER/GAFF force field. - -As of 2016-11-21, this code has not been tested for accuracy. -(See the WARNING.TXT file.) - -step 1) -To build the files which LAMMPS needs, follow the instructions in: -README_setup.sh - -step 2) -To run LAMMPS with these files, follow these instructions: -README_run.sh diff --git a/tools/moltemplate/examples/force_field_AMBER/ethylene+benzene/README_run.sh b/tools/moltemplate/examples/force_field_AMBER/ethylene+benzene/README_run.sh deleted file mode 100755 index 9f923a6c7e..0000000000 --- a/tools/moltemplate/examples/force_field_AMBER/ethylene+benzene/README_run.sh +++ /dev/null @@ -1,39 +0,0 @@ -# --- Running LAMMPS --- -# -------- REQUIREMENTS: --------- -# 1) This example requires building LAMMPS with the "USER-MISC" package. -# (because it makes use of "gaff.lt" which uses dihedral_style fourier) -# To do this, type "make yes-user-misc" before compiling LAMMPS. -# http://lammps.sandia.gov/doc/Section_start.html#start_3 -# -------- PREREQUISITES: -------- -# The 2 files "run.in.npt", and "run.in.nvt" are LAMMPS -# input scripts which link to the input scripts and data files -# you hopefully have created earlier with moltemplate.sh: -# system.in.init, system.in.settings, system.data -# If not, carry out the instructions in "README_setup.sh". -# -# -- Instructions: -- -# If "lmp_mpi" is the name of the command you use to invoke lammps, -# then you would run lammps on these files this way: - - -lmp_mpi -i run.in.npt # minimization and simulation at constant pressure -lmp_mpi -i run.in.nvt # minimization and simulation at constant volume - -#(Note: The constant volume simulation lacks pressure equilibration. These are -# completely separate simulations. The results of the constant pressure -# simulation might be ignored when beginning the simulation at constant -# volume. (This is because restart files in LAMMPS don't always work, -# and I was spending a lot of time trying to convince people it was a -# LAMMPS bug, instead of a moltemplate bug, so I disabled restart files.) -# Read the "run.in.nvt" file to find out how to use the "read_restart" -# command to load the results of the pressure-equilibration simulation, -# before beginning a constant-volume run. - - - - - -# If you have compiled the MPI version of lammps, you can run lammps in parallel -#mpirun -np 4 lmp_mpi -i run.in.npt -#mpirun -np 4 lmp_mpi -i run.in.nvt -# (assuming you have 4 processors available) diff --git a/tools/moltemplate/examples/force_field_AMBER/ethylene+benzene/README_setup.sh b/tools/moltemplate/examples/force_field_AMBER/ethylene+benzene/README_setup.sh deleted file mode 100755 index 0e2a17d9b9..0000000000 --- a/tools/moltemplate/examples/force_field_AMBER/ethylene+benzene/README_setup.sh +++ /dev/null @@ -1,25 +0,0 @@ -# Create LAMMPS input files this way: -cd moltemplate_files - - # run moltemplate - - moltemplate.sh system.lt - - # This will generate various files with names ending in *.in* and *.data. - # Move them to the directory where you plan to run LAMMPS (in this case "../") - mv -f system.data system.in* ../ - - # Optional: - # The "./output_ttree/" directory is full of temporary files generated by - # moltemplate. They can be useful for debugging, but are usually thrown away. - #rm -rf output_ttree/ - -cd ../ - - -# Optional: -# Note: The system.data and system.in.settings files contain extra information -# for atoms defined in GAFF which you are not using in this simulation. This -# is harmless, but if you to delete this information from your -# system.in.settings and system.in.data files, follow the instructions in -# this script: "optional_cleanup/README_remove_irrelevant_info.sh" diff --git a/tools/moltemplate/examples/force_field_AMBER/ethylene+benzene/README_visualize.txt b/tools/moltemplate/examples/force_field_AMBER/ethylene+benzene/README_visualize.txt deleted file mode 100644 index 019afc1444..0000000000 --- a/tools/moltemplate/examples/force_field_AMBER/ethylene+benzene/README_visualize.txt +++ /dev/null @@ -1,87 +0,0 @@ - - ------- To view a lammps trajectory in VMD -------- - - -1) Build a PSF file for use in viewing with VMD. - -This step works with VMD 1.9 and topotools 1.2. -(Older versions, like VMD 1.8.6, don't support this.) - - -a) Start VMD -b) Menu Extensions->Tk Console -c) Enter: - -(I assume that the the DATA file is called "system.data") - - topo readlammpsdata system.data full - animate write psf system.psf - -2) - -Later, to Load a trajectory in VMD: - - Start VMD - Select menu: File->New Molecule - -Browse to select the PSF file you created above, and load it. - (Don't close the window yet.) - -Browse to select the trajectory file. - If necessary, for "file type" select: "LAMMPS Trajectory" - Load it. - - ---- A note on trajectory format: ----- -If the trajectory is a DUMP file, then make sure the it contains the -information you need for pbctools (see below. I've been using this -command in my LAMMPS scripts to create the trajectories: - - dump 1 all custom 5000 DUMP_FILE.lammpstrj id mol type x y z ix iy iz - -It's a good idea to use an atom_style which supports molecule-ID numbers -so that you can assign a molecule-ID number to each atom. (I think this -is needed to wrap atom coordinates without breaking molecules in half.) - -Of course, you don't have to save your trajectories in DUMP format, -(other formats like DCD work fine) I just mention dump files -because these are the files I'm familiar with. - -3) ----- Wrap the coordinates to the unit cell - (without cutting the molecules in half) - -a) Start VMD -b) Load the trajectory in VMD (see above) -c) Menu Extensions->Tk Console -d) Try entering these commands: - - pbc wrap -compound res -all - pbc box - - ----- Optional ---- - Sometimes the solvent or membrane obscures the view of the solute. - It can help to shift the location of the periodic boundary box - To shift the box in the y direction (for example) do this: - - pbc wrap -compound res -all -shiftcenterrel {0.0 0.15 0.0} - pbc box -shiftcenterrel {0.0 0.15 0.0} - - Distances are measured in units of box-length fractions, not Angstroms. - - Alternately if you have a solute whose atoms are all of type 1, - then you can also try this to center the box around it: - - pbc wrap -sel type=1 -all -centersel type=2 -center com - -4) - You should check if your periodic boundary conditions are too small. - To do that: - select Graphics->Representations menu option - click on the "Periodic" tab, and - click on the "+x", "-x", "+y", "-y", "+z", "-z" checkboxes. - -5) Optional: If you like, change the atom types in the PSF file so - that VMD recognizes the atom types, use something like: - -sed -e 's/ 1 1 / C C /g' < system.psf > temp1.psf -sed -e 's/ 2 2 / H H /g' < temp1.psf > temp2.psf -sed -e 's/ 3 3 / P P /g' < temp2.psf > system.psf - -(If you do this, it might effect step 2 above.) diff --git a/tools/moltemplate/examples/force_field_AMBER/ethylene+benzene/images/benzene.jpg b/tools/moltemplate/examples/force_field_AMBER/ethylene+benzene/images/benzene.jpg deleted file mode 100644 index 356c78425644264fd39fa94cbe21122942871f7c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15032 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 M{%z+s@VWB;07Lw^g8%>k diff --git a/tools/moltemplate/examples/force_field_AMBER/ethylene+benzene/images/ethylene+benzene_box80x80x80_LR.jpg b/tools/moltemplate/examples/force_field_AMBER/ethylene+benzene/images/ethylene+benzene_box80x80x80_LR.jpg deleted file mode 100644 index 00c82d3d9f5f13a5dd36eaee35d982557be2b1b1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 130048 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%0AlqfP_f5(nxm?-97ZsjdXXHNH@dKEy&P0 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 diff --git a/tools/moltemplate/examples/force_field_AMBER/ethylene+benzene/images/ethylene.jpg b/tools/moltemplate/examples/force_field_AMBER/ethylene+benzene/images/ethylene.jpg deleted file mode 100644 index ab5bbbf49b35b63abfb7e5eb6a3e8ef8b7dac5bf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11657 zcmb7qWmsEH*X|BUaCdhJ?i45#cXuchch?puw79#wyE~LpiaQjywm1}b+Tw@ydEW1P zf1Pukm1OqZGxw~$=GwVt?ySk<;^P{CDK9N24S+x(K=$bcJbncv{-FOgI5;reAA^9w za9}6|3WY)-5GXtXJQRum4}riV!6P94F(^C|G7=*4AMnS?9|wO%J-rd1M*XGye-)2C z02U&!3c><|umCtL5Eu*e*awgUAOHmY;~e;pAv{Hchy;cMAwTuw{#VDpgvVt76$}F4 zFu|Ar06JOw&$z!=@ag@3uqUP*X&NXa)6&onz!ZZ|p_bs=s`#fogsnp97?r0b#i z!4Hj-_ppp51YRXn4rB5!fq2AvDu)^m;GfRFd;gRjWv~V(!lfC@9x4E6E~R$kM+nl zbz+-LpYQ(V1Wh;*$+=J$?p|;fRzoI0p`^8JKm08j5+?_dB)^~j;c#xI54@0tcefkH zOwlL`*#kh8R)P^5h754a(w2!S64ZRMyWu>30JU41WjvN#R%U`jcQ6)}ADILnZ5sg4 zY^Gb4Cnw2pE5gdy7=~>GJ3Oob8>HTbE=}^%dQuWp`#lc^jk3~306>)8?gkV0XyI9O zjYp-$Ab#6l|Gb^l`{l>Cd*+dVq8b|PxIB998&TSx%cr=UVN+Z?+R4Fs@7POVGW|`X z5dmXn#g`xOEL?VFET|;)(a*A(g}VUY<(F-sfO#}Oo>0wq6UcAsrEWwoSWq7Io$^(P|6PSLz;-tCLn-k~Dc2;8#K z7xAzgb}79}pB$NRd9{?y8;Bs~6A%4e7NW3<+2NfC26bEuj!Wl{@*UT%-^?l!mls0v z>VD(sKgdv?cp~V=8OJv9NO%bOmtMFX3t1&r4!6mniRkPYZdIT7DfO2ziW#_)7L3%HS@u-soQx< zJREjS*}z9{<`aHd1HcKh4d{Zz#Y)*x*FL3!Q8=k*-6g-Nf=IHum{h2LsuE(wl2vp0 zJ%t4zh(w!kZFJnRN+WuaH3;Ah+~>4Zg}BcY_bC5R0M#sEu5)n)QyyyU7te(( z^N5A)(vz`~@Ub`pNp74}|8mg9@C$jk63IAv(VrV=`-%M!Mvc4X+$842sWmV9%K+;t zd#9)C>PLc_>3;*DFBh*O3ci``>}GcU?FP_vc{&CZJ~Z#_k>>&LFp|MUU) zuKT`z|JMJxAUv%Ite5}*4+nySe_D;e|1^W(z<*XSENm)7OdMQF4m?qOY8q8~PM)Ww z0`X}90YTv&0q@P|hVLQHBbq-I9L+m6DQ!G5mHL=E2k@$#k_UXX0Fn9zI-Pp6Nrt-!Hm5aHcNbK_2*=S3U04iFKqD6ZeldTEi&3GK<3tUHpZ;9p2(PE_6G|aFPuSyBb4xLky)iso zfvmp#>fxO%vVJXpE`6V7QBS&9i5o<0rB}ug7Ee`cbI{U#%xax%$>IWPg1s7MZ2s7<@Ba zzZX8V@mvfZ5tA1B%Rv$q7LXvswS&^uuewZfV>xEpNmiWrOM4gzEzTw<|41U72P$YX z2o9ls1a?(u+H$|Nh>8WJnRMobeabN_dJ%)#9gKmoFjBbmS$Q?{kT(Ma2@yG_mhFkl zNe>d6LFQ=0gE83SK*39VY^GG0nAn)qgf>z$j8c6$f+?sl<5(s>x62dyq@R_d?DWZ9 z(KJO&Cho)U<2C}KV0{GlNS{+Uug!1{(H4i0AVhD9sI4HEHFDeMw(zKSJ9rE)Zd~_c zzibR2BHo3Iv7Mre1%Dh;_b-EWQ(ViLRSDMa1|mU>le?}I8GAYMOhgAm<+)pz-fM67 zzYnvAq;0thkV(YlnMeyf0*o*Z1f6>lRk;`$nm9{T7*TMUr&I4|Q1HDWwaenOw1DYL zD><_=SAlbmy!sm6yCZ)eLvls|b`0HLTpiCR1(1F1ZxkS9*r7DJY~oR{ekjU<%06i^ zXU0wA+tsbqR^4cA$$7EblU?=XnEatFqF};a=g5xZ1^6!Jx*JCRGe-4t@<^hP73ZI? z>!UNcon+i%l;lHI_u=#Gke$uiAABR?L1|+xhhZ_sdTw4?DpPgmJQ^Att8hH;ib>2z z^$gJztdCj*?34?15Ad|`7pCiS(Fjt|C(WADnw{d~iKt3mx?s_aCMK_Y&f9@mPkTMk zUjOE^6GfWN*u-`+uaJioWWZ5NImvxth&+)x!D$>XD)X> zSY%_#-BoNAjM0Jc#*_`559Zqn+ZfVFMWf|LjtP@_oPC$?SRm#O&0crml9$cO`+7`_ zY*$vC7sdp035qt#cy7Jg%kuFKO03$7YmXHyd4#LBXEy<-Q*b;yc8YF}OWgh+~2JR3<8OOJVgF447mScC}9F1I0)!T>LMURp?|zQ zZDRlgiiJ%{#VMv{0*{G9&E?`Bk4wWLDz0vtUr);|p%KtMg@Xy*ZGrcaU8d$JF z$0OBy`tLpmFY>g{3G3HXqw&OhFiLkJYG{^74(^eT<#d;z)Xr*-z8evZQokTwokrCO zYSk|-D!5)ry_DHcliYq`QC{xhE%#!x?s!y#>sf{3Ekasub8Ul=hUPrZhlY3bB4-B_ z4G*U&cDPsaWtnC+Iw~$9xzd!uMKGhWq|FFTha-m6MH6|6;B)4p2 zo!{@Ozjh4c{!9)r^^p2}IjFFKV2{|tduAO7&#)U?i(QP5yKuPR^F4_CE<80u8z~gg zq_Hmd5QFRpelvV8F%Oj*H8QeeHht^n>!nKHYp-Z><^2ZQYo%}7@po~QgkKQQ^1eoR z5DjStJOa@~xI}MrloUM7oj@Y9rl;&gN61Yk#EP!gyJ3|>!Jfs#=S5EP(+Fp|ochz~ z7j$~qY0a!+@(e4LucZm%G(KzEL~~9@b9z?Ku{iUx5gssWJpxy^=dd|Ye(CJgt;7Q+ ze^d8|U^16crE>MLo6h(ezE<8zp7v}#SV|so zj-smx^;1ZBi=BiP)2qHrbC5!jo0YVQ<{(TZ(4NT?^}MUGTTq>v<(0}C+|ujM1^XJ( z-s@)y#->o4mZ}&B8}qNo{;)p?55IiBRM{UF6FuE!xWfxTOfwMQ? z*;sBHPPJ_kE^J#ce@OL3j}mQICR|-pO{5yl^OjxhACQV}j3cBP1u z+ATO+Dhy~;#{#^f-pYTSL!V<#Mv92qzo*M4@tcHSk2~)(u;ifqaiSLwH#|_uA5(mA z6r-+g%&7f?uWD3AH!ufJJ5yGRPfE<#sN`qTPc-34ytKn}Ce+f0ivDjY&y|}zD5CT2 zg_4{0an+kDt$_}(?~46n`XvkkgT@#Fm~l&>7i z9+GqF1!rklUKV!Rcd0WUquJ^}h(Gf8<)OAXK&xk~+F=Lt1gY?B0;wG_o3Gv{~k|YU6y)QEF8l zgD!*h2%y%4-O|Dwp&V66NFP3&bGu#0ceC`$d-c{c5^!o%Dek0Yq`8`SUE(o40`HWg z;s-j%8sp{c(uY)9wgOXECzLv;v9{XGA1JfbEpk_>D8>`GGQ<`=S5@bJZ=v&=JM&)Z zGVUyq;hwR`m?b@TyL!0WF5#AWW?^+wEa?r;y!%dwz z>x=F8MJVW-IXcxd**CT?Y_5`*eY->zzgm2VV+oBDN8Kf#_VD5A z=Zl-mP>Sm7X~*6boLH%LVU;c|%1^q;axZdCWS%d6|1(mW(W>rPlg&h#u7{V_HWoXe z45R3o@;Z%NBRg}!+Lexj{*`$7+=%-em%TSz$>LyD;vR$NcuIQ3sN>ME4ce~Dd%s^j zbc;5qP4VW%G#oMNucQzRe}4?3FX@lx$nIQliZ@6^XE;wF?uH#5 zp}BsUp~CyhCiuK6JzVW_JTlU0X@J(cX=%A={mXFOlHM-~4IjRAC43344x(ge$IgZ~ z%uZ>Ust)V3l_nxb0TrL2l?_U8I3q+B_{U0q1Kd*0XSA(M78Vcn z-&T$|zV*zk&us2#3okft*Yw;0u~=R0#Mg@*ZU(JqtL<3qjBI^X?cOj4Dn_zEMqTx02DN~TLUcP&T(JOK&+v?U z)aik1LKUy370z@&BN+QATg0~OjhI6pV=K0OQM_qlW26Y#ER7^NhE}$IGk#)ts#fvN zPqIyVM=!b;xIX&8f%ES1#9Jz5{$l=(=-FbD1T#qkILZQJg5|G!i2MYeoD2%_qOJ~C z=hk=1yKzPG7?`~#!17{DGuhU+pV#jvh9R(~1{^_QjeO?Yk1bsrT{+&ZGO&F3Q`1~6 zD=gPnvmcBdqU@A@MTW^wJ0`Gk!PNcbyEjQyXWc=+es%d1G+_}CMOiflFej&Kc$GVc zkU-oy4S#%hyzex=s~WZTe$|)6%0!fes#$~`=${@+Oz<4fdO}{KPTWkBKde zU1|Lbe&%YHRaHzj4y)Q`?|1xx71kQ0Km;Bgs~Gd=JR}qrA{Q6L)A*5mw>kJrt%~eV zzj0nuEy1zlcaU_4+aS3o3tjj(EgC6uG7UAd=1~btQ1x>Jd{{CY<%3UlPhPz}+DPw1x=u*=X>1&1F<(sfs|I=`etC9{VJsnJ}Nyyl@~e82l$g{8u6aSbxQ_ z3nryMM|{3$efQL<>iXG#@;o9`k3jo+w<>GJZj=J2hE-Se<{N(47^!ssX?!zcFs{j=X6f%>iJ98$XTr=8>VGLaMk$+t81dLvK%N#qO# z&Kp|n{nM6O$PB##)7swT!yzG`L{bgTT{n`LEvdiWYqrqP&Ggzc((Rl%_gC`Eq+Sms z1p%c>&PQ-m_x{=o-nYTQ8{a0{3^uO=9FE8y0gSQvH0O1VFZJ(yHwiHK5fX+Rv3EUak*5I`sO7TimEOF` zBOrO#Whqt;-@qD!L$TSue{ah-Uwr-vowBXhNYnMW1HvCPMKl~X5s>hWJ5fW}$|3g~ z)LHfs05dP6TgdUXWC0T=uoO)dlftli>WApx;yHqD-vj!C29Rku z0cQanNhfr_sk;t~m@z1>)@%LMYu#BM@NQ4TG=x|w@v~q==Yo&1ZD8+5cbJp!zW@AO zWOU4^XW9XGAx4VMrLu|PtqldHAc9!*t9LKKCnAJLtdiN#j9nk@WviqLJ9P{A=h|Gd zqQr|k;JW^fg6a?$`t+y03Njx0o^sZg?W6O!N;S_+&q!InZRAgWGnKHQ^}4BklXEGU zOvA#S@J{BFc0QUiuLLiODe`%kh~~(#(%W>8K{#iZPVza1@b(GPnS$DyJrmxx!NT97 z5=d_aR1uD`Any7&W+bXZ4OS>Inm?txyza_a zMtI}k=Jup-S@4(n_FxA;_hl;jNCvL-qcS{HUuEawx08|;#*oUSzY3H&j6EY&C~;0$ z^^2o9jv~vtj{ZzyyHjt9VEyt1=Ve-H03lUu)`+3>K4^D!rajz{0o84K&Z>uST%k|r z{bHJC!6*7ncYh;!sb@Up?(Iz0T)58qP8MLszA56*1*>-SCpd>381SZ2Y3#%@xD6sG z5h#&E3T(_{Ejvr?Rt`BhrXu%Pvombv#{HwU>V@GY5_{ZaD$HU+BP#@ZuH8JH&wdcX zLYN}@$ENc?8V$;Z5=5w)_H_6Xh~Y=w2S8pud!2OWg}ap)P`e=p!lqN z_pdc%^G5rKEt%p7#+rS77qxRk@XRJ_%w%?)v&_ov82zHp^_~eRYb1%z+lFy9=CKb> zm!U85;Xbg`nAvak2)*zdpuV`I-5T{}J^S+fR{DT-p6P8`*gaZg8YKcJ^Ink$nG$lt z>sSMt&!saTK2=dg@goUJpi-vj`XazWSC!OG()3di3f`!|ZlHMH-P+ozz*|Q$A1ym>--30q1UZc4`3ghy^L-tk85y2kSRZzZ^wbyVcTfTS*x`wA0uKpmY;ylN ziz*6Ji~PvSuD)d`O@>l9{sM>@wT8mv&?PwBQLb2ZhR3$NV;vW8{vq-ykXX2(POsb*ThOgyi*eKx?w!|Hj1zM}UH!JHMNZinC;vdAz zGgJoIo}w~JxwBE4_PjANERAkS8=iFjm@OAiSvkdgRIgxY5nvQ829y`;QECQt*M{l7 zHfaz*mstcieHu>JX>9$aI1y%{enFrbBsGe_`SiuU{{a{*j({?`u6ob z%3-@ZSK#1?s$XAUR937zW*}5PovB^W@daG_cRZrgw@gBc^{9rf=)M4m#gV!pM&Am? z?!#N1Ct&8r>u}yNw|#>z=W{=sGJMXZjVD`YLKcPm&Aw4EiVD|XDpzmG8=mHkBkZ%| ziLU~0K4)q2ZkZH1*T{sa9gW`sf$4gitbv1yzMIw!TSm@3A<+%rHlE&R=Hi&*)g;os zRx}iiyNHD3d~kFoISy&&XrJJ0IX-|!zJ-M;TgO=KU5Ic@u6ytZkY0+UZy9jhaYbje zfj!}Vp)kMwJe>n)y&&u=5$pqfKlG$W{vJ^Se-5ag&a3|0DE}K^KAn30F-ROh3CKbI zrOMIz0T4gnuYoAz5P>+^e*l0fO9_A|{Y3vjIDirxpoRM<6A6M~KQ$o&34gjEm~u}g z5ckIqWdh<;2>@c0PfR}$fGzq2XfdDeg$ThErF{Z^PoJl{91!Z<9u%M+^i7b-VBn~BK2s(NM646dKV z2#kH^`KcwKuc~-Cr%ev4uJ3}=3zHHn%-7=x6^{E|VH$YQ(hUaT?g9TM#Q!ddfjjfF zn-=F2C5-j^Ec`JFHtV}mX@*^YnJCIiYmn9?(Q{9*a#c((d~}|lvdV!ViE!!IwbdbE zq{c#&=ID;8jX)}~0h->mrZh8DIzUBv<2e>tuHxl+uo{#&vM$S2Hi4AXussoRfp`TlWvf)4Uz?Uc2QlZOiAu~8nQFF2=&8~{w&{Ww z5hrquQ^w1e5{ud`q{hBzqU)mJG9agTf9S7|&f2BA-Qu28VTL}&*ldfqjCJ->6aYuB z^1$0JQ8?s4A*Wr$mhhoVBQz@n#&S&S5eIUdsE^HAsYDB?(X5XE|0UI#U+zZ-B65D8 z*g|^>-c3Uo(aOqcuArO0XHu6Uc}9O5biD`k2uxDwwj!c@P4=yJ^_IG{At`!V(=zX& zbpH)NE1XaKC?`T2OK1-Bn4##&sawx-70V`~$9~)Y@&TdUXV$Qvg&VAAc7- zW`AOa1RBgrgX20A6S{~9>U2rq*~}fFidp;B5`Zp%w-U{Kpgm@>u{4Ub+*^@zS{6Qy z=pMeXip?hW3SOMtm;kXvfoxLC%ZPtS#6VS0vWLe*VV~rdCXZ9SGu2|+n}PyW2A${f zo8rSUr!K1Hgqj~;Ro_*b1gr(kQEvSGXv7IH^$IC}QB4v_ewh=T#nM%6(uiP3g<7kXXsu zxRS*m-7aK0kJHP}}r15J$bhP=1z3lNr(U7T}R9q`j8|Cvb$v*b`2|?I0h#ad&+grGZE%m3+g&c;5FZOHAIUZAKFj3YwGDUm2vsJ(`~VULswVkMX1pHyro_YK+P7$l z2uS=e9FyJO@P4R>Lfe$)NoPUs=@>i)k}YR`Iv0hQ80BQxWlD^t!9z4u!hjIVA$2x8 ztv$HcBq)g$&~rTriFFj26v=JwzLW$3{(T5Y+Nb!kP==1;>zp zv27|vZ0$`K&%EtZs$KU7<$I+24Ipz|baNB`S#Veu$2PH-z<{cg0In4gxQ3%Li-#58 zOMcD|;Fn;SEP)G!hEj-_XJSr6d(-v~o;mSH@=%Fi67^U?Mr5dY^|~EAhY%BS@Hz}X7VVw_arR!A(s-$S>J4QmPAlnmW_3VXHOd4m-r8Azawye_}vd`gS+AM6d(CV5jSE2em z{m$9!)BX9nVz+zNkHFhU0LN=4?A1K}nEiL|h|>e!L9M$j0vg=U{Ah{LOgv-7>;iR? z)2MgTwZxFqtgSZmWI8(RoZm{wIPlU#IK))K2j;ZJGe zqLJckqGO}%lQBCWV)yi)=bj*S9>z54)G5y#AAPkz6anuf+k0O}KM!&3#SiaI`OQJp z5$fGPSqJ0$a)SQK0RESY!+_%T4+OUU5m73%fW_%sW6|_@Tqw(-g@cN%g|c(ZMeu`* z&o}p#dU{T?6kcaZT<9Ht@GC_cGEut^OQH2yY8>~ZJc{B=7jDbjPFbqo_|xc!6+Pa; z&5NqO-fYPG@)gRU2ttPGERssNsH=qug+BtZ^aNQ5Z;S-$J>EH!F@_zD8h);VpDiI{ z8I(nF3o27SYG|?#!-Boc>)*x5vQq4o#0{_5CqzbrGhpBtkeXo1}E8rB%`3;HI-Ed!v+Kh~T$E zX#bv{+$>s)c4|9x4a4hMD5xik6-jCK9K#AHJ0}h06zVV1`x9%UfLbWM0=G%(+pAFn z(w_cSg{`2i)kb1FDY16dux1nE(GdCXtXaFMK`Yd>ye?5~XsREPUIr=AtoKH}&CQ~& z)p24z?ZC1eb>-Xb?^_wVlB*2?!DWE4AV%EO@;+;3)Oa5mWI3ToDahk^AT=oS8qC+0 zZE(`?c(D_Xl}m$;Rg|CtAejWAnfXgL>6CT=aE|M9eo^CwwsRMWafS+|XR%yOR7IC0 zjOqQ`*ABfJUzzxv9d((1GGF52v>Y9GFtK+e(Xv+sE1+Vse#1vJ``ZTn?P1cK?81F zof)d6M~!f>sZw3wD`0?@Oa5sR8ydB#q8Js%WNh%gOOmyp1AJ0{PdhFcODK9Ej;IVl z;1#!CmG#@M#m!7!c6eTAq$>ppzY^`={(F*KoQJGJoAhay4|;G{qFO?rA0U}{)R~|) zx=*6-qTLu7ysO@Vu|yGu*aw5Y$LxMY&_xqlb6#0QOvnN;g~3&IUCX0k8n^}!(!`-= zg<`G&PZCm{-dwW4{6{@j0N1pkiKc6BFSTY$f>GB+QBY6gYB)no&-bB();T2X0Xa$% Z_8E$|x@U1kuTPi)sr*+0A7~zz{ttLQH(&q& diff --git a/tools/moltemplate/examples/force_field_AMBER/ethylene+benzene/moltemplate_files/benzene.lt b/tools/moltemplate/examples/force_field_AMBER/ethylene+benzene/moltemplate_files/benzene.lt deleted file mode 100644 index 47b1505c58..0000000000 --- a/tools/moltemplate/examples/force_field_AMBER/ethylene+benzene/moltemplate_files/benzene.lt +++ /dev/null @@ -1,47 +0,0 @@ - -import "gaff.lt" - -# The "gaff.lt" file is usually located in "src/moltemplate_force_fields". -# It contains definitions of the atoms "ca", "ha", as well as the bonded -# and non-bonded interactions between them (and many other atoms). -# -# Moltemplate is only a simple text manipulation tool. It cannot -# calculate atomic charge using quantom chemistry methods. -# Atom charges for this example were taken from the OPLSAA force field file: -# http://dasher.wustl.edu/tinker/distribution/params/oplsaa.prm -# However, normally simulations in AMBER are assigned charges using the -# "HF/6-31G* RESP2" or "AM1-BCC3" methods using AmberTools. - -Benzene inherits GAFF { - - write('Data Atoms') { - $atom:C1 $mol @atom:ca 0.115 5.274 1.999 -8.568 - $atom:C2 $mol @atom:ca 0.115 6.627 2.018 -8.209 - $atom:C3 $mol @atom:ca 0.115 7.366 0.829 -8.202 - $atom:C4 $mol @atom:ca 0.115 6.752 -0.379 -8.554 - $atom:C5 $mol @atom:ca 0.115 5.399 -0.398 -8.912 - $atom:C6 $mol @atom:ca 0.115 4.660 0.791 -8.919 - $atom:H11 $mol @atom:ha -0.115 4.704 2.916 -8.573 - $atom:H21 $mol @atom:ha -0.115 7.101 2.950 -7.938 - $atom:H31 $mol @atom:ha -0.115 8.410 0.844 -7.926 - $atom:H41 $mol @atom:ha -0.115 7.322 -1.296 -8.548 - $atom:H51 $mol @atom:ha -0.115 4.925 -1.330 -9.183 - $atom:H61 $mol @atom:ha -0.115 3.616 0.776 -9.196 - } - - write('Data Bond List') { - $bond:C12 $atom:C1 $atom:C2 - $bond:C23 $atom:C2 $atom:C3 - $bond:C34 $atom:C3 $atom:C4 - $bond:C45 $atom:C4 $atom:C5 - $bond:C56 $atom:C5 $atom:C6 - $bond:C61 $atom:C6 $atom:C1 - $bond:C1H1 $atom:C1 $atom:H11 - $bond:C2H2 $atom:C2 $atom:H21 - $bond:C3H3 $atom:C3 $atom:H31 - $bond:C4H4 $atom:C4 $atom:H41 - $bond:C5H5 $atom:C5 $atom:H51 - $bond:C6H6 $atom:C6 $atom:H61 - } - -} # Benzene diff --git a/tools/moltemplate/examples/force_field_AMBER/ethylene+benzene/moltemplate_files/charges_come_from_OPLSAA/oplsaa_subset.prm b/tools/moltemplate/examples/force_field_AMBER/ethylene+benzene/moltemplate_files/charges_come_from_OPLSAA/oplsaa_subset.prm deleted file mode 100644 index 8493a39f6c..0000000000 --- a/tools/moltemplate/examples/force_field_AMBER/ethylene+benzene/moltemplate_files/charges_come_from_OPLSAA/oplsaa_subset.prm +++ /dev/null @@ -1,94 +0,0 @@ -# This is a modified version of the file "oplsaa.prm" distributed with TINKER -# http://dasher.wustl.edu/tinker/distribution/params/oplsaa.prm -# In this version, all of the lines beginning with "atom" have been deleted -# except for the atom types we will be using in this simulation -# -# If you use this file, please also cite the software this file comes from: -# -# Ponder, J. W., and Richards, F. M. J. Comput. Chem. (1987) 8(7), 1016-1024 -# "An efficient newtonâ€like method for molecular mechanics energy -# minimization of large molecules." -# -# Ponder, J. W, (2004) -# "TINKER: Software tools for molecular design" -# http://dasher.wustl.edu/tinker/ - - ############################## - ## ## - ## Force Field Definition ## - ## ## - ############################## - - -forcefield OPLS-AA - -vdwindex TYPE -vdwtype LENNARD-JONES -radiusrule GEOMETRIC -radiustype SIGMA -radiussize DIAMETER -epsilonrule GEOMETRIC -vdw-14-scale 2.0 -chg-14-scale 2.0 -electric 332.06 -dielectric 1.0 - - - ############################# - ## ## - ## Literature References ## - ## ## - ############################# - - -The parameters supplied with TINKER are from "OPLS All-Atom Parameters -for Organic Molecules, Ions, Peptides & Nucleic Acids, July 2008" as -provided by W. L. Jorgensen, Yale University during June 2009. These -parameters are taken from those distributed with BOSS Version 4.8. - -Note that "atom type" numbers and not "atom class" numbers are used -to index van der Waals parameters, see the "vdwindex" keyword above - -The atom types with (UA) in the description are "united atom" values, -ie, OPLS-UA, where any nonpolar hydrogen atoms are combined onto their -attached atoms. All other parameters are "all-atom", OPLS-AA, including -explicit hydrogen atoms. - - - ############################# - ## ## - ## Atom Type Definitions ## - ## ## - ############################# - - -atom 88 47 CM "Alkene H2-C=" 6 12.011 3 -atom 89 46 HC "Alkene H-C=" 1 1.008 1 -atom 90 48 CA "Aromatic C" 6 12.011 3 -atom 91 49 HA "Aromatic H-C" 1 1.008 1 - - - ################################ - ## ## - ## Van der Waals Parameters ## - ## ## - ################################ - - -vdw 88 3.5500 0.0760 -vdw 89 2.4200 0.0300 -vdw 90 3.5500 0.0700 -vdw 91 2.4200 0.0300 - - - ######################################## - ## ## - ## Atomic Partial Charge Parameters ## - ## ## - ######################################## - - -charge 88 -0.2300 -charge 89 0.1150 -charge 90 -0.1150 -charge 91 0.1150 diff --git a/tools/moltemplate/examples/force_field_AMBER/ethylene+benzene/moltemplate_files/ethylene.lt b/tools/moltemplate/examples/force_field_AMBER/ethylene+benzene/moltemplate_files/ethylene.lt deleted file mode 100644 index cad6ea4a8d..0000000000 --- a/tools/moltemplate/examples/force_field_AMBER/ethylene+benzene/moltemplate_files/ethylene.lt +++ /dev/null @@ -1,38 +0,0 @@ - -import "gaff.lt" - -# The "gaff.lt" file is usually located in "src/moltemplate_force_fields". -# It contains definitions of the atoms "c2", "hc", as well as the bonded -# and non-bonded interactions between them (and many other atoms). -# -# Moltemplate is only a simple text manipulation tool. It cannot -# calculate atomic charge using quantom chemistry methods. -# Atom charges for this example were taken from the OPLSAA force field file: -# http://dasher.wustl.edu/tinker/distribution/params/oplsaa.prm -# However, normally simulations in AMBER are assigned charges using the -# "HF/6-31G* RESP2" or "AM1-BCC3" methods using AmberTools. - - -Ethylene inherits GAFF { - - # atom-id mol-id atom-type charge X Y Z - - write('Data Atoms') { - $atom:C1 $mol @atom:c2 -0.23 -0.6695 0.000000 0.000000 - $atom:C2 $mol @atom:c2 -0.23 0.6695 0.000000 0.000000 - $atom:H11 $mol @atom:hc 0.115 -1.234217 -0.854458 0.000000 - $atom:H12 $mol @atom:hc 0.115 -1.234217 0.854458 0.000000 - $atom:H21 $mol @atom:hc 0.115 1.234217 -0.854458 0.000000 - $atom:H22 $mol @atom:hc 0.115 1.234217 0.854458 0.000000 - } - - write('Data Bond List') { - $bond:C12 $atom:C1 $atom:C2 - $bond:C1H1 $atom:C1 $atom:H11 - $bond:C1H2 $atom:C1 $atom:H12 - $bond:C2H1 $atom:C2 $atom:H21 - $bond:C2H2 $atom:C2 $atom:H22 - } - -} # Ethylene - diff --git a/tools/moltemplate/examples/force_field_AMBER/ethylene+benzene/moltemplate_files/system.lt b/tools/moltemplate/examples/force_field_AMBER/ethylene+benzene/moltemplate_files/system.lt deleted file mode 100644 index f9984a1bb8..0000000000 --- a/tools/moltemplate/examples/force_field_AMBER/ethylene+benzene/moltemplate_files/system.lt +++ /dev/null @@ -1,29 +0,0 @@ -import "ethylene.lt" # <- defines the "Ethylene" molecule type. -import "benzene.lt" # <- defines the "Benzene" molecule type. - - -# Periodic boundary conditions: -write_once("Data Boundary") { - 0.0 80.00 xlo xhi - 0.0 80.00 ylo yhi - 0.0 80.00 zlo zhi -} - -# Create 1000 ethylenes and 500 benzenes - -ethylenes = new Ethylene[10].move(8.0, 0, 0) - [10].move(0, 8.0, 0) - [10].move(0, 0, 8.0) - -benzenes = new Benzene[10].move(8.0, 0, 0) - [10].move(0, 8.0, 0) - [5].move(0, 0, 16.0) - -# Now shift the positions of all of the benzene molecules, -# to reduce the chance that they overlap with the ethylene molecules. - -benzenes[*][*][*].move(4.0, 4.0, 4.0) - -# Note: There is also an example in the OPLSAA directory which shows how to -# generate the coordinates using PACKMOL. That allows us to omit all of -# the coordinates and .move() commands. (This works with AMBER/GAFF too.) diff --git a/tools/moltemplate/examples/force_field_AMBER/ethylene+benzene/optional_cleanup/README_remove_irrelevant_info.sh b/tools/moltemplate/examples/force_field_AMBER/ethylene+benzene/optional_cleanup/README_remove_irrelevant_info.sh deleted file mode 100755 index 3251991775..0000000000 --- a/tools/moltemplate/examples/force_field_AMBER/ethylene+benzene/optional_cleanup/README_remove_irrelevant_info.sh +++ /dev/null @@ -1,63 +0,0 @@ - # MOST USERS CAN IGNORE THIS FILE - # - # Unfortunately, as of 2014-4-19, the system.data and system.in.settings file - # which are created by moltemplate.sh contain a lot of irrelevant information, - # such as definition of parameters for atom types not present in the current - # system. This extra information takes up about 1 MB. - # - # This appears to be harmless. - # (Loading this extra information does not seem to slow down LAMMPS.) - # - # --------- OPTIONAL STEPS FOR STRIPPING OUT JUNK --------- - # - # However if you want to eliminate this junk from these files - # For now, we can strip this out using ltemplify.py to build a new .lt file. - # - # NOTE: If you decide to use this script, it was meant to be run it from - # the parent directory (../) (If you run it from somewhere else, be sure to - # modify the "PATH_TO_DATA_FILE" and "PATH_TO_OUTPUT_TTREE" variables below.) - # - # I suggest you do this in a temporary_directory - - PATH_TO_DATA_FILE="." - - pushd "$PATH_TO_DATA_FILE" - - mkdir new_lt_file - cd new_lt_file/ - - # now run ltemplify.py - - ltemplify.py ../system.in.init ../system.in.settings ../system.data > system.lt - - # This creates a new .LT file named "system.lt" in the local directory. - - # The ltemplify.py script also does not copy the boundary dimensions. - # We must do this manually. - # If you did NOT throw away the "Data Boundary" file usually located in - # "moltemplate_files/output_ttree/Data Boundary" - # then you can copy that information from this file into system.lt - - PATH_TO_OUTPUT_TTREE="../moltemplate_files/output_ttree" - - echo "write_once(\"Data Boundary\") {" >> system.lt - cat "$PATH_TO_OUTPUT_TTREE/Data Boundary" >> system.lt - echo "}" >> system.lt - echo "" >> system.lt - - # Now, run moltemplate on this new .LT file. - moltemplate.sh system.lt - # This will create: "system.data" "system.in.init" "system.in.settings." - - # That's it. The new "system.data" and system.in.* files should - # be ready to run in LAMMPS. - - # Now copy the system.data and system.in.* files to the place where - # you plan to run LAMMPS - mv -f system.data system.in.* ../ - cd ../ - - # Now delete all of the temporary files we generated - rm -rf new_lt_file/ - popd - diff --git a/tools/moltemplate/examples/force_field_AMBER/ethylene+benzene/run.in.npt b/tools/moltemplate/examples/force_field_AMBER/ethylene+benzene/run.in.npt deleted file mode 100644 index 9e529624d5..0000000000 --- a/tools/moltemplate/examples/force_field_AMBER/ethylene+benzene/run.in.npt +++ /dev/null @@ -1,53 +0,0 @@ -# PREREQUISITES: -# -# You must use moltemplate.sh to create 3 files: -# system.data system.in.init system.in.settings -# (Follow the instructions in README_setup.sh, -# or run the file as a script using ./README_setup.sh) - -# ------------------------------- Initialization Section -------------------- - -include "system.in.init" - -# ------------------------------- Atom Definition Section ------------------- - -read_data "system.data" - -# ------------------------------- Settings Section -------------------------- - -include "system.in.settings" - -# ------------------------------- Run Section ------------------------------- - - -# -- minimization protocol -- - -minimize 1.0e-4 1.0e-6 100000 400000 - -# -- simulation protocol -- - -timestep 1.0 - -print "---------------------------------------------------------------------------" -print "First, use Langevin dynamics to randomize the initial shape of the molecules" -print "(This is not really necessary, but it seems to speed up equilibration.)" -print "---------------------------------------------------------------------------" - -fix fxlan all langevin 300.0 300.0 120 123456 # temp: 300 K -fix fxnph all nph iso 50.0 50.0 1000.0 # pressure: 50 barr -run 2000 -unfix fxlan -unfix fxnph - -print "---------------------------------------------------------------------------" -print "--- Now continue the simulation using a Nose-Hoover Thermostat/Barostat ---" -print "---------------------------------------------------------------------------" -dump 1 all custom 1000 traj_npt.lammpstrj id mol type x y z ix iy iz -# temperature: 300 K, pressure: 50 barr -fix fxnpt all npt temp 300.0 300.0 100.0 iso 50.0 50.0 1000.0 drag 1.0 -thermo 100 -#thermo_modify flush yes - -run 100000 - -write_data system_after_npt.data diff --git a/tools/moltemplate/examples/force_field_AMBER/ethylene+benzene/run.in.nvt b/tools/moltemplate/examples/force_field_AMBER/ethylene+benzene/run.in.nvt deleted file mode 100644 index 15283ff82b..0000000000 --- a/tools/moltemplate/examples/force_field_AMBER/ethylene+benzene/run.in.nvt +++ /dev/null @@ -1,46 +0,0 @@ -# PREREQUISITES: -# -# 1) You must use moltemplate.sh to create 3 files: -# system.data system.in.init system.in.settings -# (Follow the instructions in README_setup.sh, -# or run the file as a script using ./README_setup.sh) -# 2) You must equilibrate the system beforehand using "run.in.npt". -# This will create the file "system_after_npt.data" which this file reads. -# (Note: I have not verified that this equilibration protocol works well.) - -# ------------------------------- Initialization Section -------------------- - -include "system.in.init" - -# ------------------------------- Atom Definition Section ------------------- - -# Read the coordinates generated by an earlier NPT simulation - -read_data "system_after_npt.data" - -# ------------------------------- Settings Section -------------------------- - -include "system.in.settings" - - -# (The "write_restart" and "read_restart" commands were buggy in 2012, -# but they should work also. I prefer "write_data" and "read_data".) - -# ------------------------------- Settings Section -------------------------- - -include system.in.settings - -# ------------------------------- Run Section ------------------------------- - -# -- simulation protocol -- - - -timestep 1.0 -dump 1 all custom 5000 traj_nvt.lammpstrj id mol type x y z ix iy iz -fix fxnvt all nvt temp 300.0 300.0 500.0 tchain 1 -thermo 500 -#thermo_modify flush yes - -run 200000 - -write_data system_after_nvt.data diff --git a/tools/moltemplate/examples/force_field_AMBER/hexadecane/README.TXT b/tools/moltemplate/examples/force_field_AMBER/hexadecane/README.TXT deleted file mode 100644 index a3f011167d..0000000000 --- a/tools/moltemplate/examples/force_field_AMBER/hexadecane/README.TXT +++ /dev/null @@ -1,44 +0,0 @@ -This example is a simple simulation of 288 hexadecane molecules in a box at -room temperature and atmospheric pressure. Please read the WARNING.TXT file. - --------- REQUIREMENTS: --------- -This example requires building LAMMPS with the "USER-MISC" package. -(because it uses dihedral_style fourier) -To do this, type "make yes-user-misc" before compiling LAMMPS. -http://lammps.sandia.gov/doc/Section_start.html#start_3 - -More detailed instructions on how to build LAMMPS input files and -run a short simulation are provided in other README files: - -step 1) to setup the LAMMPS input files, run this file: -README_setup.sh - - (Currently there is a bug which makes this step slow. - I'll fix it later -Andrew 2013-10-15.) - -step 2) to run LAMMPS, follow the instructions in this file: -README_run.sh - ------------- NOTE: There are two versions of this example. ---------------- - -Both examples use the same force-field parameters. - -1) -In this version, the force-field parameters are loaded from the "gaff.lt" file -(located in the "src/moltemplate_force_fields/" subdirectory). -This frees the user from the drudgery of manually specifying all of these -force-field details for every molecule. (However, the user must be careful -to choose @atom-type names which match AMBER GAFF conventions, -such as the "c3" and "h1" atoms, in this example.) - -2) -Alternately, there is another "hexadecane" example in the "all_atom_examples" -directory. In that example, force-field parameters are loaded from a file -named "alkanes.lt" (instead of "gaff.lt"). The "alkanes.lt" file contains -only the excerpts from "gaff.lt" which are relevant to the hydrocarbon -molcules used in that example. ("gaff.lt" contains parameters for most -small organic molecules, not just hydrocarbons.) -In this way, by editing "alkanes.lt", the user can manually control all of the -force-field details in the simulation. (Without feeling as though they are -relying on some kind of mysterious "black box" to do it for them.) - diff --git a/tools/moltemplate/examples/force_field_AMBER/hexadecane/README_run.sh b/tools/moltemplate/examples/force_field_AMBER/hexadecane/README_run.sh deleted file mode 100755 index 9f923a6c7e..0000000000 --- a/tools/moltemplate/examples/force_field_AMBER/hexadecane/README_run.sh +++ /dev/null @@ -1,39 +0,0 @@ -# --- Running LAMMPS --- -# -------- REQUIREMENTS: --------- -# 1) This example requires building LAMMPS with the "USER-MISC" package. -# (because it makes use of "gaff.lt" which uses dihedral_style fourier) -# To do this, type "make yes-user-misc" before compiling LAMMPS. -# http://lammps.sandia.gov/doc/Section_start.html#start_3 -# -------- PREREQUISITES: -------- -# The 2 files "run.in.npt", and "run.in.nvt" are LAMMPS -# input scripts which link to the input scripts and data files -# you hopefully have created earlier with moltemplate.sh: -# system.in.init, system.in.settings, system.data -# If not, carry out the instructions in "README_setup.sh". -# -# -- Instructions: -- -# If "lmp_mpi" is the name of the command you use to invoke lammps, -# then you would run lammps on these files this way: - - -lmp_mpi -i run.in.npt # minimization and simulation at constant pressure -lmp_mpi -i run.in.nvt # minimization and simulation at constant volume - -#(Note: The constant volume simulation lacks pressure equilibration. These are -# completely separate simulations. The results of the constant pressure -# simulation might be ignored when beginning the simulation at constant -# volume. (This is because restart files in LAMMPS don't always work, -# and I was spending a lot of time trying to convince people it was a -# LAMMPS bug, instead of a moltemplate bug, so I disabled restart files.) -# Read the "run.in.nvt" file to find out how to use the "read_restart" -# command to load the results of the pressure-equilibration simulation, -# before beginning a constant-volume run. - - - - - -# If you have compiled the MPI version of lammps, you can run lammps in parallel -#mpirun -np 4 lmp_mpi -i run.in.npt -#mpirun -np 4 lmp_mpi -i run.in.nvt -# (assuming you have 4 processors available) diff --git a/tools/moltemplate/examples/force_field_AMBER/hexadecane/README_setup.sh b/tools/moltemplate/examples/force_field_AMBER/hexadecane/README_setup.sh deleted file mode 100755 index c2db73b457..0000000000 --- a/tools/moltemplate/examples/force_field_AMBER/hexadecane/README_setup.sh +++ /dev/null @@ -1,26 +0,0 @@ - -# Create LAMMPS input files this way: -cd moltemplate_files - - # run moltemplate - - moltemplate.sh system.lt - - # This will generate various files with names ending in *.in* and *.data. - # Move them to the directory where you plan to run LAMMPS (in this case "../") - mv -f system.data system.in* ../ - - # Optional: - # The "./output_ttree/" directory is full of temporary files generated by - # moltemplate. They can be useful for debugging, but are usually thrown away. - #rm -rf output_ttree/ - -cd ../ - - -# Optional: -# Note: The system.data and system.in.settings files contain extra information -# for atoms defined in GAFF which you are not using in this simulation. This -# is harmless, but if you to delete this information from your -# system.in.settings and system.in.data files, follow the instructions in -# this script: "optional_cleanup/README_remove_irrelevant_info.sh" diff --git a/tools/moltemplate/examples/force_field_AMBER/hexadecane/README_visualize.txt b/tools/moltemplate/examples/force_field_AMBER/hexadecane/README_visualize.txt deleted file mode 100644 index 019afc1444..0000000000 --- a/tools/moltemplate/examples/force_field_AMBER/hexadecane/README_visualize.txt +++ /dev/null @@ -1,87 +0,0 @@ - - ------- To view a lammps trajectory in VMD -------- - - -1) Build a PSF file for use in viewing with VMD. - -This step works with VMD 1.9 and topotools 1.2. -(Older versions, like VMD 1.8.6, don't support this.) - - -a) Start VMD -b) Menu Extensions->Tk Console -c) Enter: - -(I assume that the the DATA file is called "system.data") - - topo readlammpsdata system.data full - animate write psf system.psf - -2) - -Later, to Load a trajectory in VMD: - - Start VMD - Select menu: File->New Molecule - -Browse to select the PSF file you created above, and load it. - (Don't close the window yet.) - -Browse to select the trajectory file. - If necessary, for "file type" select: "LAMMPS Trajectory" - Load it. - - ---- A note on trajectory format: ----- -If the trajectory is a DUMP file, then make sure the it contains the -information you need for pbctools (see below. I've been using this -command in my LAMMPS scripts to create the trajectories: - - dump 1 all custom 5000 DUMP_FILE.lammpstrj id mol type x y z ix iy iz - -It's a good idea to use an atom_style which supports molecule-ID numbers -so that you can assign a molecule-ID number to each atom. (I think this -is needed to wrap atom coordinates without breaking molecules in half.) - -Of course, you don't have to save your trajectories in DUMP format, -(other formats like DCD work fine) I just mention dump files -because these are the files I'm familiar with. - -3) ----- Wrap the coordinates to the unit cell - (without cutting the molecules in half) - -a) Start VMD -b) Load the trajectory in VMD (see above) -c) Menu Extensions->Tk Console -d) Try entering these commands: - - pbc wrap -compound res -all - pbc box - - ----- Optional ---- - Sometimes the solvent or membrane obscures the view of the solute. - It can help to shift the location of the periodic boundary box - To shift the box in the y direction (for example) do this: - - pbc wrap -compound res -all -shiftcenterrel {0.0 0.15 0.0} - pbc box -shiftcenterrel {0.0 0.15 0.0} - - Distances are measured in units of box-length fractions, not Angstroms. - - Alternately if you have a solute whose atoms are all of type 1, - then you can also try this to center the box around it: - - pbc wrap -sel type=1 -all -centersel type=2 -center com - -4) - You should check if your periodic boundary conditions are too small. - To do that: - select Graphics->Representations menu option - click on the "Periodic" tab, and - click on the "+x", "-x", "+y", "-y", "+z", "-z" checkboxes. - -5) Optional: If you like, change the atom types in the PSF file so - that VMD recognizes the atom types, use something like: - -sed -e 's/ 1 1 / C C /g' < system.psf > temp1.psf -sed -e 's/ 2 2 / H H /g' < temp1.psf > temp2.psf -sed -e 's/ 3 3 / P P /g' < temp2.psf > system.psf - -(If you do this, it might effect step 2 above.) diff --git a/tools/moltemplate/examples/force_field_AMBER/hexadecane/WARNING.TXT b/tools/moltemplate/examples/force_field_AMBER/hexadecane/WARNING.TXT deleted file mode 100644 index def26ba765..0000000000 --- a/tools/moltemplate/examples/force_field_AMBER/hexadecane/WARNING.TXT +++ /dev/null @@ -1,16 +0,0 @@ -# -------- WARNING: -------- - -This software is experimental, and the force-fields and equilbration protocols -have not been tested carefully by me. There is no gaurantee that the simulation -will reproduce the behavior of real hexadecane molecules, -(or even of hexadecane molecules simulated using AMBER, which should - be using the same force-field). - -# -------- REQUEST FOR HELP: -------- - -However, if you notice a problem with this example, please report it. -I confess I do not have a lot of experience running all-atom simulations. -Peer-review is the only way to improve this software (or any software). -Other suggestions are also welcome! - -(Contact jewett.aij@gmail.com, 2013-10-16) diff --git a/tools/moltemplate/examples/force_field_AMBER/hexadecane/images/hexadecane_12x12x2_t=0_LR.jpg b/tools/moltemplate/examples/force_field_AMBER/hexadecane/images/hexadecane_12x12x2_t=0_LR.jpg deleted file mode 100644 index b0d31f88453d4594681cc81791d66c5c1e8c0b99..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 27017 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\rwJO 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 Op_CsiKd1iyPygBZ$I|=& diff --git a/tools/moltemplate/examples/force_field_AMBER/hexadecane/images/hexadecane_LR.jpg b/tools/moltemplate/examples/force_field_AMBER/hexadecane/images/hexadecane_LR.jpg deleted file mode 100644 index 3ad353dbb4e083ccc07be687ea044170e86ec952..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5237 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 Ob8E+5TPj`WGyehPY6hJE diff --git a/tools/moltemplate/examples/force_field_AMBER/hexadecane/moltemplate_files/ch2group.lt b/tools/moltemplate/examples/force_field_AMBER/hexadecane/moltemplate_files/ch2group.lt deleted file mode 100644 index 69978eecae..0000000000 --- a/tools/moltemplate/examples/force_field_AMBER/hexadecane/moltemplate_files/ch2group.lt +++ /dev/null @@ -1,59 +0,0 @@ - -import "gaff.lt" # <-- defines the "GAFF" force field - - -# The "gaff.lt" file is usually located in $MOLTEMPLATE_PATH (and is -# distributed with moltemplate. See the "Installation" section in the manual.) -# It contains definitions of the atoms "c3", "hc", as well as the force-field -# parameters for bonded and non-bonded interactions between them -# (and many other atoms). - -# Atom charges were taken from the OPLSAA force field file: -# http://dasher.wustl.edu/tinker/distribution/params/oplsaa.prm - - -CH2 inherits GAFF { - - # atom-id mol-id atom-type charge x y z - - write("Data Atoms") { - $atom:C $mol:... @atom:c3 -0.120 0.000 0.000 0.000 - $atom:H1 $mol:... @atom:hc 0.060 0.000 0.63104384422426 0.892430762954 - $atom:H2 $mol:... @atom:hc 0.060 0.000 0.63104384422426 -0.892430762954 - } - - # Note: The "..." in "$mol:..." tells moltemplate that this molecule may - # be a part of a larger molecule, and (if so) to use the larger - # parent object's molecule id number as it's own. - # The CH2 group is part of the Hexadecane molecule. - - # Now specify which pairs of atoms are bonded: - write('Data Bond List') { - $bond:CH1 $atom:C $atom:H1 - $bond:CH2 $atom:C $atom:H2 - } - -} # CH2 - - -# Optional: Shift all the coordinates in the +Y direction by 0.4431163. -# This way, the carbon atom is no longer located at 0,0,0, but the -# axis of an alkane chain containing this monomer is at 0,0,0. -# (This makes it more convenient to construct a polymer later. -# If this is confusing, then simply add 0.4431163 to the Y -# coordinates in the "Data Atoms" section above.) - -CH2.move(0,0.4431163,0) - - - - -######### (scratchwork calculations for the atomic coordinates) ######### -# Lcc = 1.5350 # length of the C-C bond (Sp3) -# Lch = 1.0930 # length of the C-H bond -# theta=2*atan(sqrt(2)) # ~= 109.5 degrees = tetrahedronal angle (C-C-C angle) -# DeltaXc = Lcc*sin(theta/2) # = 1.2533222517240594 -# DeltaYc = Lcc*cos(theta/2) # = 0.8862326632060754 -# # 0.5*DeltaYc = 0.4431163316030377 -# DeltaZh = Lch*sin(theta/2) # = 0.8924307629540046 -# DeltaYh = Lch*cos(theta/2) # = 0.6310438442242609 diff --git a/tools/moltemplate/examples/force_field_AMBER/hexadecane/moltemplate_files/ch3group.lt b/tools/moltemplate/examples/force_field_AMBER/hexadecane/moltemplate_files/ch3group.lt deleted file mode 100644 index ef431f8d75..0000000000 --- a/tools/moltemplate/examples/force_field_AMBER/hexadecane/moltemplate_files/ch3group.lt +++ /dev/null @@ -1,65 +0,0 @@ -import "gaff.lt" # <-- defines the "GAFF" force field - - -# The "gaff.lt" file is usually located in $MOLTEMPLATE_PATH (and is -# distributed with moltemplate. See the "Installation" section in the manual.) -# It contains definitions of the atoms "c3", "hc", as well as the force-field -# parameters for bonded and non-bonded interactions between them -# (and many other atoms). -# -# Moltemplate is only a simple text manipulation tool. It cannot -# calculate atomic charge using quantom chemistry methods. -# Atom charges for this example were taken from the OPLSAA force field file: -# http://dasher.wustl.edu/tinker/distribution/params/oplsaa.prm -# However, normally simulations in AMBER are assigned charges using the -# "HF/6-31G* RESP2" or "AM1-BCC3" methods using AmberTools. - - -CH3 inherits GAFF { - - # atom-id mol-id atom-type charge x y z - - write("Data Atoms") { - $atom:C $mol:... @atom:c3 -0.180 0.000000 0.000000 0.000000 - $atom:H1 $mol:... @atom:hc 0.060 0.000000 0.6310438442242609 0.8924307629540046 - $atom:H2 $mol:... @atom:hc 0.060 0.000000 0.6310438442242609 -0.8924307629540046 - $atom:H3 $mol:... @atom:hc 0.060 -0.8924307629540046 -0.6310438442242609 0.000000 - } - - # Note: The "..." in "$mol:..." tells moltemplate that this molecule may - # be a part of a larger molecule, and (if so) to use the larger - # parent object's molecule id number as it's own. - # The CH3 group is part of the Hexadecane molecule. - - # Now specify which pairs of atoms are bonded: - write('Data Bond List') { - $bond:CH1 $atom:C $atom:H1 - $bond:CH2 $atom:C $atom:H2 - $bond:CH3 $atom:C $atom:H3 - } - -} # CH3 - - -# Optional: Shift all the coordinates in the +Y direction by 0.4431163. -# This way, the carbon atom is no longer located at 0,0,0, but the -# axis of an alkane chain containing this monomer is at 0,0,0. -# (This makes it more convenient to construct a polymer later. -# If this is confusing, then simply add 0.4431163 to the Y -# coordinates in the "Data Atoms" section above.) - -CH3.move(0,0.4431163,0) - - - - -######### (scratchwork calculations for the atomic coordinates) ######### -# Lcc = 1.5350 # length of the C-C bond (Sp3) -# Lch = 1.0930 # length of the C-H bond -# theta=2*atan(sqrt(2)) # ~= 109.5 degrees = tetrahedronal angle (C-C-C angle) -# DeltaXc = Lcc*sin(theta/2) # = 1.2533222517240594 -# DeltaYc = Lcc*cos(theta/2) # = 0.8862326632060754 -# # 0.5*DeltaYc = 0.4431163316030377 -# DeltaZh = Lch*sin(theta/2) # = 0.8924307629540046 -# DeltaYh = Lch*cos(theta/2) # = 0.6310438442242609 - diff --git a/tools/moltemplate/examples/force_field_AMBER/hexadecane/moltemplate_files/hexadecane.lt b/tools/moltemplate/examples/force_field_AMBER/hexadecane/moltemplate_files/hexadecane.lt deleted file mode 100644 index d28502f486..0000000000 --- a/tools/moltemplate/examples/force_field_AMBER/hexadecane/moltemplate_files/hexadecane.lt +++ /dev/null @@ -1,89 +0,0 @@ -# This example looks complicated because I split the -# hexadecane molecule into individual CH2 and CH3 monomers. -# -# I defined it this way so that you can easily modify -# it to change the length of the alkane chain. - - -import "gaff.lt" # load the "GAFF" force-field information -import "ch2group.lt" # load the definition of the "CH2" object -import "ch3group.lt" # load the definition of the "CH3" object - - - -Hexadecane inherits GAFF { - - - create_var {$mol} # optional:force all monomers to share the same molecule-ID - - - # Now create an array of 16 "CH2" objects distributed along the X axis - - monomers = new CH2 [16].rot(180,1,0,0).move(1.2533223,0,0) - - # Each monomer is rotated 180 degrees with respect to the previous - # monomer, and then moved 1.2533223 Angstroms down the X axis. - - # ---- Now, modify the ends: --- - # Delete the CH2 groups at the beginning and end, and replace them with CH3. - # (Note: Alternately, instead of deleting the CH2 groups at each end, you - # could modify them by adding an extra hydrogen atom to those carbons.) - - delete monomers[0] - delete monomers[15] - monomers[0] = new CH3 - monomers[15] = new CH3 - - # Move the CH3 groups to the correct location at either end of the chain: - - monomers[15].rot(180.0,0,0,1).move(18.7998345,0,0) - - # Note: 18.7998345 = (16-1) * 1.2533223 - - - # Now add a list of bonds connecting the carbon atoms together: - - write('Data Bond List') { - $bond:b1 $atom:monomers[0]/C $atom:monomers[1]/C - $bond:b2 $atom:monomers[1]/C $atom:monomers[2]/C - $bond:b3 $atom:monomers[2]/C $atom:monomers[3]/C - $bond:b4 $atom:monomers[3]/C $atom:monomers[4]/C - $bond:b5 $atom:monomers[4]/C $atom:monomers[5]/C - $bond:b6 $atom:monomers[5]/C $atom:monomers[6]/C - $bond:b7 $atom:monomers[6]/C $atom:monomers[7]/C - $bond:b8 $atom:monomers[7]/C $atom:monomers[8]/C - $bond:b9 $atom:monomers[8]/C $atom:monomers[9]/C - $bond:b10 $atom:monomers[9]/C $atom:monomers[10]/C - $bond:b11 $atom:monomers[10]/C $atom:monomers[11]/C - $bond:b12 $atom:monomers[11]/C $atom:monomers[12]/C - $bond:b13 $atom:monomers[12]/C $atom:monomers[13]/C - $bond:b14 $atom:monomers[13]/C $atom:monomers[14]/C - $bond:b15 $atom:monomers[14]/C $atom:monomers[15]/C - } - -} # Hexadecane - - - - - - - - - - -######### (scratchwork calculations for the atomic coordinates) ######### -# -# 1.2533223 = DeltaXc = how far each CH2 group is shifted along -# the X axis (in Angstoms). -# 0.4431163 = DeltaYc/2 = lateral displacement of carbons away -# from the central axis. (See below.) -# -# Lcc = 1.5350 # length of the C-C bond (Sp3) -# Lch = 1.0930 # length of the C-H bond -# theta=2*atan(sqrt(2)) # ~= 109.5 degrees = tetrahedronal angle (C-C-C angle) -# DeltaXc = Lcc*sin(theta/2) # = 1.2533222517240594 -# DeltaYc = Lcc*cos(theta/2) # = 0.8862326632060754 -# # 0.5*DeltaYc = 0.4431163316030377 -# DeltaZh = Lch*sin(theta/2) # = 0.8924307629540046 -# DeltaYh = Lch*cos(theta/2) # = 0.6310438442242609 diff --git a/tools/moltemplate/examples/force_field_AMBER/hexadecane/moltemplate_files/system.lt b/tools/moltemplate/examples/force_field_AMBER/hexadecane/moltemplate_files/system.lt deleted file mode 100644 index 4e0cfaec69..0000000000 --- a/tools/moltemplate/examples/force_field_AMBER/hexadecane/moltemplate_files/system.lt +++ /dev/null @@ -1,18 +0,0 @@ -import "hexadecane.lt" # <- defines the "Hexadecane" molecule type. - -# Periodic boundary conditions: -write_once("Data Boundary") { - 0.0 62.4 xlo xhi - 0.0 62.4 ylo yhi - 0.0 62.4 zlo zhi -} - -molecules = new Hexadecane [12].move(0, 0, 5.2) - [12].move(0, 5.2, 0) - [2].move(31.2, 0, 0) - - -# NOTE: The spacing between molecules is large. There should be extra room to -# move during the initial stages of equilibration. However, you will have to -# run the simulation at NPT conditions later to compress the system to a -# more realistic density. diff --git a/tools/moltemplate/examples/force_field_AMBER/hexadecane/optional_cleanup/README_remove_irrelevant_info.sh b/tools/moltemplate/examples/force_field_AMBER/hexadecane/optional_cleanup/README_remove_irrelevant_info.sh deleted file mode 100755 index 3251991775..0000000000 --- a/tools/moltemplate/examples/force_field_AMBER/hexadecane/optional_cleanup/README_remove_irrelevant_info.sh +++ /dev/null @@ -1,63 +0,0 @@ - # MOST USERS CAN IGNORE THIS FILE - # - # Unfortunately, as of 2014-4-19, the system.data and system.in.settings file - # which are created by moltemplate.sh contain a lot of irrelevant information, - # such as definition of parameters for atom types not present in the current - # system. This extra information takes up about 1 MB. - # - # This appears to be harmless. - # (Loading this extra information does not seem to slow down LAMMPS.) - # - # --------- OPTIONAL STEPS FOR STRIPPING OUT JUNK --------- - # - # However if you want to eliminate this junk from these files - # For now, we can strip this out using ltemplify.py to build a new .lt file. - # - # NOTE: If you decide to use this script, it was meant to be run it from - # the parent directory (../) (If you run it from somewhere else, be sure to - # modify the "PATH_TO_DATA_FILE" and "PATH_TO_OUTPUT_TTREE" variables below.) - # - # I suggest you do this in a temporary_directory - - PATH_TO_DATA_FILE="." - - pushd "$PATH_TO_DATA_FILE" - - mkdir new_lt_file - cd new_lt_file/ - - # now run ltemplify.py - - ltemplify.py ../system.in.init ../system.in.settings ../system.data > system.lt - - # This creates a new .LT file named "system.lt" in the local directory. - - # The ltemplify.py script also does not copy the boundary dimensions. - # We must do this manually. - # If you did NOT throw away the "Data Boundary" file usually located in - # "moltemplate_files/output_ttree/Data Boundary" - # then you can copy that information from this file into system.lt - - PATH_TO_OUTPUT_TTREE="../moltemplate_files/output_ttree" - - echo "write_once(\"Data Boundary\") {" >> system.lt - cat "$PATH_TO_OUTPUT_TTREE/Data Boundary" >> system.lt - echo "}" >> system.lt - echo "" >> system.lt - - # Now, run moltemplate on this new .LT file. - moltemplate.sh system.lt - # This will create: "system.data" "system.in.init" "system.in.settings." - - # That's it. The new "system.data" and system.in.* files should - # be ready to run in LAMMPS. - - # Now copy the system.data and system.in.* files to the place where - # you plan to run LAMMPS - mv -f system.data system.in.* ../ - cd ../ - - # Now delete all of the temporary files we generated - rm -rf new_lt_file/ - popd - diff --git a/tools/moltemplate/examples/force_field_AMBER/hexadecane/run.in.npt b/tools/moltemplate/examples/force_field_AMBER/hexadecane/run.in.npt deleted file mode 100644 index a1b9345229..0000000000 --- a/tools/moltemplate/examples/force_field_AMBER/hexadecane/run.in.npt +++ /dev/null @@ -1,86 +0,0 @@ -# PREREQUISITES: -# -# You must use moltemplate.sh to create 3 files: -# system.data system.in.init system.in.settings -# (Follow the instructions in README_setup.sh, -# or run the file as a script using ./README_setup.sh) - -# ------------------------------- Initialization Section -------------------- - -include system.in.init - -# ------------------------------- Atom Definition Section ------------------- - -read_data system.data - -# ------------------------------- Settings Section -------------------------- - -include system.in.settings - -# ------------------------------- Run Section ------------------------------- - -# To avvoid explosions, I have a 4-step equilibraion process (expand, minimize, -# reorient, compress). The system (as defined in the "system.data" file) -# is already expanded. That means there are 3 steps left: - -dump dumpeq1 all custom 50 traj_eq1_min.lammpstrj id mol type x y z ix iy iz -thermo 50 - -# -- Equilibration: part 1: initial minimization -- - -# Note: In general, it's always a good idea to minimize the system at first. - -minimize 1.0e-5 1.0e-7 100000 400000 -undump dumpeq1 - -write_data system_after_eq1_min.data - -# -- Equilibration part 2: reorienting the molecules (NVT) -- - -timestep 1.0 -dump dumpeq2 all custom 200 traj_eq2_reorient.lammpstrj id mol type x y z ix iy iz - -# Run the system at high temperature (at constant volume) to reorient the -# the molecules (which would otherwise be pointing in the same direction). - -# To speed it up, I randomize the atomic positions for a few thousand steps -# using fix langevin (and fix nve). Then I switch to fix nvt (Nose-Hoover). -# (If I start with fix nvt (Nose-Hoover), it seems to get "stuck" for a while.) - - -fix fxlan all langevin 900.0 900.0 120 48279 -fix fxnve all nve - -run 4000 - -unfix fxlan -unfix fxnve -# Now continue the simulation at high temperature using fix nvt (Nose-Hoover). -fix fxnvt all nvt temp 900.0 900.0 100.0 - -run 50000 -undump dumpeq2 - - -write_data system_after_eq2_reorient.data - -unfix fxnvt - -# -- equilibration part 3: Equilibrating the density (NPT) -- - -# Originally, the simulation box (in "system.data" and "system.lt") was -# unrealistically large. The spacing between the molecules was large also. -# I did this to enable the molecules to move freely and reorient themselves. -# After doing that, we should run the simulation under NPT conditions to -# allow the simulation box to contract to it's natural size. We do that here: -# We begin the simulation at 100 barr (a relatively low pressure), and -# slowly decrease it to 1 barr, maintianing the temperature at 300K. - -dump dumpeq3 all custom 200 traj_eq3_npt.lammpstrj id mol type x y z ix iy iz -fix fxnpt all npt temp 900.0 300.0 100.0 iso 100.0 1.0 1000.0 drag 2.0 - -timestep 1.0 -run 100000 - -write_data system_after_eq3_npt.data - diff --git a/tools/moltemplate/examples/force_field_AMBER/hexadecane/run.in.nvt b/tools/moltemplate/examples/force_field_AMBER/hexadecane/run.in.nvt deleted file mode 100644 index 0bb7699896..0000000000 --- a/tools/moltemplate/examples/force_field_AMBER/hexadecane/run.in.nvt +++ /dev/null @@ -1,43 +0,0 @@ -# PREREQUISITES: -# -# 1) You must use moltemplate.sh to create 3 files: -# system.data system.in.init system.in.settings -# (Follow the instructions in README_setup.sh, -# or run the file as a script using ./README_setup.sh) -# 2) You must equilibrate the system beforehand using "run.in.npt". -# This will create the file "system_after_npt.data" which this file reads. -# (Note: I have not verified that this equilibration protocol works well.) - -# ------------------------------- Initialization Section -------------------- - -include system.in.init - -# ------------------------------- Atom Definition Section ------------------- - - -# Read the coordinates generated by an earlier NPT simulation - -read_data system_after_eq3_npt.data - -# (The "write_restart" and "read_restart" commands were buggy in 2012, -# but they should work also. I prefer "write_data" and "read_data".) - - -# ------------------------------- Settings Section -------------------------- - -include system.in.settings - -# ------------------------------- Run Section ------------------------------- - -# -- simulation protocol -- - - -timestep 1.0 -dump 1 all custom 500 traj_nvt.lammpstrj id mol type x y z ix iy iz -fix fxnvt all nvt temp 350.0 350.0 500.0 tchain 1 -thermo 100 -#thermo_modify flush yes - -run 50000 - -write_data system_after_nvt.data diff --git a/tools/moltemplate/examples/force_field_AMBER/waterTIP3P+isobutane/README.TXT b/tools/moltemplate/examples/force_field_AMBER/waterTIP3P+isobutane/README.TXT deleted file mode 100644 index 6ec463efab..0000000000 --- a/tools/moltemplate/examples/force_field_AMBER/waterTIP3P+isobutane/README.TXT +++ /dev/null @@ -1,41 +0,0 @@ -The simulation consists of a mixture of isobutane and water. -Over time (less than 1 ns), the two molecules phase-separate. - -The GAFF parameters are applied only to the isobutane molecule. -(The water molecule parameters are defined explicitly in - src/moltemplate_force_fields/tip3p_2004.lt) - -WARNING: THIS IS A PRELIMINARY EXAMPLE WHICH USES AMBER'S GAFF FORCE FIELD. - AS OF 2014-4-19, these features have not been tested. - THE ABILITY TO DETECT AND ASSIGN GAFF FORCE FIELD PARAMETERS - MOLECULES ACCORDING TO ATOM TYPE IS AN EXPERIMENTAL FEATURE - AND CURRENTLY PROBABLY HAS BUGS (IN THE DIHEDRALS AND IMPROPERS). - PLEASE REPORT BUGS AND/OR SEND CORRECTIONS. -A 2014-4-19 - ------------------ CHARGE ---------------------- - -NOTE: The GAFF force-field DOES NOT ASSIGN ATOM CHARGE. - In this example, atom charges were taken from the OPLSAA force field file: - http://dasher.wustl.edu/tinker/distribution/params/oplsaa.prm - This is not the charge in AMBER simunlations is typically assigned. - (As of 2014, it is assigned using the "HF/6-31G* RESP2" or "AM1-BCC3" - methods using AmberTools (which are not available in moltemplate). - http://ambermd.org/doc6/html/AMBER-sh-19.4.html - http://ambermd.org/tutorials/basic/tutorial4b/) - - --------- REQUIREMENTS: --------- - - This example requires building LAMMPS with the "USER-MISC" package. - (because it makes use of "gaff.lt" which uses dihedral_style fourier) - To do this, type "make yes-user-misc" before compiling LAMMPS. - http://lammps.sandia.gov/doc/Section_start.html#start_3 - -More detailed instructions on how to build LAMMPS input files and -run a short simulation are provided in other README files. - -step 1) -README_setup.sh - -step 2) -README_run.sh diff --git a/tools/moltemplate/examples/force_field_AMBER/waterTIP3P+isobutane/README_run.sh b/tools/moltemplate/examples/force_field_AMBER/waterTIP3P+isobutane/README_run.sh deleted file mode 100755 index 9f923a6c7e..0000000000 --- a/tools/moltemplate/examples/force_field_AMBER/waterTIP3P+isobutane/README_run.sh +++ /dev/null @@ -1,39 +0,0 @@ -# --- Running LAMMPS --- -# -------- REQUIREMENTS: --------- -# 1) This example requires building LAMMPS with the "USER-MISC" package. -# (because it makes use of "gaff.lt" which uses dihedral_style fourier) -# To do this, type "make yes-user-misc" before compiling LAMMPS. -# http://lammps.sandia.gov/doc/Section_start.html#start_3 -# -------- PREREQUISITES: -------- -# The 2 files "run.in.npt", and "run.in.nvt" are LAMMPS -# input scripts which link to the input scripts and data files -# you hopefully have created earlier with moltemplate.sh: -# system.in.init, system.in.settings, system.data -# If not, carry out the instructions in "README_setup.sh". -# -# -- Instructions: -- -# If "lmp_mpi" is the name of the command you use to invoke lammps, -# then you would run lammps on these files this way: - - -lmp_mpi -i run.in.npt # minimization and simulation at constant pressure -lmp_mpi -i run.in.nvt # minimization and simulation at constant volume - -#(Note: The constant volume simulation lacks pressure equilibration. These are -# completely separate simulations. The results of the constant pressure -# simulation might be ignored when beginning the simulation at constant -# volume. (This is because restart files in LAMMPS don't always work, -# and I was spending a lot of time trying to convince people it was a -# LAMMPS bug, instead of a moltemplate bug, so I disabled restart files.) -# Read the "run.in.nvt" file to find out how to use the "read_restart" -# command to load the results of the pressure-equilibration simulation, -# before beginning a constant-volume run. - - - - - -# If you have compiled the MPI version of lammps, you can run lammps in parallel -#mpirun -np 4 lmp_mpi -i run.in.npt -#mpirun -np 4 lmp_mpi -i run.in.nvt -# (assuming you have 4 processors available) diff --git a/tools/moltemplate/examples/force_field_AMBER/waterTIP3P+isobutane/README_setup.sh b/tools/moltemplate/examples/force_field_AMBER/waterTIP3P+isobutane/README_setup.sh deleted file mode 100755 index c2db73b457..0000000000 --- a/tools/moltemplate/examples/force_field_AMBER/waterTIP3P+isobutane/README_setup.sh +++ /dev/null @@ -1,26 +0,0 @@ - -# Create LAMMPS input files this way: -cd moltemplate_files - - # run moltemplate - - moltemplate.sh system.lt - - # This will generate various files with names ending in *.in* and *.data. - # Move them to the directory where you plan to run LAMMPS (in this case "../") - mv -f system.data system.in* ../ - - # Optional: - # The "./output_ttree/" directory is full of temporary files generated by - # moltemplate. They can be useful for debugging, but are usually thrown away. - #rm -rf output_ttree/ - -cd ../ - - -# Optional: -# Note: The system.data and system.in.settings files contain extra information -# for atoms defined in GAFF which you are not using in this simulation. This -# is harmless, but if you to delete this information from your -# system.in.settings and system.in.data files, follow the instructions in -# this script: "optional_cleanup/README_remove_irrelevant_info.sh" diff --git a/tools/moltemplate/examples/force_field_AMBER/waterTIP3P+isobutane/README_visualize.txt b/tools/moltemplate/examples/force_field_AMBER/waterTIP3P+isobutane/README_visualize.txt deleted file mode 100644 index 019afc1444..0000000000 --- a/tools/moltemplate/examples/force_field_AMBER/waterTIP3P+isobutane/README_visualize.txt +++ /dev/null @@ -1,87 +0,0 @@ - - ------- To view a lammps trajectory in VMD -------- - - -1) Build a PSF file for use in viewing with VMD. - -This step works with VMD 1.9 and topotools 1.2. -(Older versions, like VMD 1.8.6, don't support this.) - - -a) Start VMD -b) Menu Extensions->Tk Console -c) Enter: - -(I assume that the the DATA file is called "system.data") - - topo readlammpsdata system.data full - animate write psf system.psf - -2) - -Later, to Load a trajectory in VMD: - - Start VMD - Select menu: File->New Molecule - -Browse to select the PSF file you created above, and load it. - (Don't close the window yet.) - -Browse to select the trajectory file. - If necessary, for "file type" select: "LAMMPS Trajectory" - Load it. - - ---- A note on trajectory format: ----- -If the trajectory is a DUMP file, then make sure the it contains the -information you need for pbctools (see below. I've been using this -command in my LAMMPS scripts to create the trajectories: - - dump 1 all custom 5000 DUMP_FILE.lammpstrj id mol type x y z ix iy iz - -It's a good idea to use an atom_style which supports molecule-ID numbers -so that you can assign a molecule-ID number to each atom. (I think this -is needed to wrap atom coordinates without breaking molecules in half.) - -Of course, you don't have to save your trajectories in DUMP format, -(other formats like DCD work fine) I just mention dump files -because these are the files I'm familiar with. - -3) ----- Wrap the coordinates to the unit cell - (without cutting the molecules in half) - -a) Start VMD -b) Load the trajectory in VMD (see above) -c) Menu Extensions->Tk Console -d) Try entering these commands: - - pbc wrap -compound res -all - pbc box - - ----- Optional ---- - Sometimes the solvent or membrane obscures the view of the solute. - It can help to shift the location of the periodic boundary box - To shift the box in the y direction (for example) do this: - - pbc wrap -compound res -all -shiftcenterrel {0.0 0.15 0.0} - pbc box -shiftcenterrel {0.0 0.15 0.0} - - Distances are measured in units of box-length fractions, not Angstroms. - - Alternately if you have a solute whose atoms are all of type 1, - then you can also try this to center the box around it: - - pbc wrap -sel type=1 -all -centersel type=2 -center com - -4) - You should check if your periodic boundary conditions are too small. - To do that: - select Graphics->Representations menu option - click on the "Periodic" tab, and - click on the "+x", "-x", "+y", "-y", "+z", "-z" checkboxes. - -5) Optional: If you like, change the atom types in the PSF file so - that VMD recognizes the atom types, use something like: - -sed -e 's/ 1 1 / C C /g' < system.psf > temp1.psf -sed -e 's/ 2 2 / H H /g' < temp1.psf > temp2.psf -sed -e 's/ 3 3 / P P /g' < temp2.psf > system.psf - -(If you do this, it might effect step 2 above.) diff --git a/tools/moltemplate/examples/force_field_AMBER/waterTIP3P+isobutane/images/isobutane.jpg b/tools/moltemplate/examples/force_field_AMBER/waterTIP3P+isobutane/images/isobutane.jpg deleted file mode 100644 index 8c548fba84514481bf2b0764122b452af8473274..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24301 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 diff --git a/tools/moltemplate/examples/force_field_AMBER/waterTIP3P+isobutane/images/water+isobutane_t=0_LR.jpg b/tools/moltemplate/examples/force_field_AMBER/waterTIP3P+isobutane/images/water+isobutane_t=0_LR.jpg deleted file mode 100644 index fab496aa20704bce235b39d8cc4a93109ecf87d9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 104035 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%0D{6H9b*iMAmPNgo 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Ξ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�-K?>w3_Um{ACF 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
pICe?`9KYP7!Vx8Nv}5)nnL5G=T9|dw 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

Ytb?Kc_6? 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�HRTrm&451f{otrKozE{FuXAS+JMyd7suI9 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 Ce(q-g diff --git a/tools/moltemplate/examples/force_field_AMBER/waterTIP3P+isobutane/images/water.jpg b/tools/moltemplate/examples/force_field_AMBER/waterTIP3P+isobutane/images/water.jpg deleted file mode 100644 index 9d578b4ef84277297deef50d851dd09614711d3e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10076 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 e633fT?UU_Fz7<^za-HCxC1|ieZ;6t system.lt - - # This creates a new .LT file named "system.lt" in the local directory. - - # The ltemplify.py script also does not copy the boundary dimensions. - # We must do this manually. - # If you did NOT throw away the "Data Boundary" file usually located in - # "moltemplate_files/output_ttree/Data Boundary" - # then you can copy that information from this file into system.lt - - PATH_TO_OUTPUT_TTREE="../moltemplate_files/output_ttree" - - echo "write_once(\"Data Boundary\") {" >> system.lt - cat "$PATH_TO_OUTPUT_TTREE/Data Boundary" >> system.lt - echo "}" >> system.lt - echo "" >> system.lt - - # Now, run moltemplate on this new .LT file. - moltemplate.sh system.lt - # This will create: "system.data" "system.in.init" "system.in.settings." - - # That's it. The new "system.data" and system.in.* files should - # be ready to run in LAMMPS. - - # Now copy the system.data and system.in.* files to the place where - # you plan to run LAMMPS - mv -f system.data system.in.* ../ - cd ../ - - # Now delete all of the temporary files we generated - rm -rf new_lt_file/ - popd - diff --git a/tools/moltemplate/examples/force_field_AMBER/waterTIP3P+isobutane/run.in.npt b/tools/moltemplate/examples/force_field_AMBER/waterTIP3P+isobutane/run.in.npt deleted file mode 100644 index b4e4078891..0000000000 --- a/tools/moltemplate/examples/force_field_AMBER/waterTIP3P+isobutane/run.in.npt +++ /dev/null @@ -1,44 +0,0 @@ -# PREREQUISITES: -# -# You must use moltemplate.sh to create 3 files: -# system.data system.in.init system.in.settings -# (Follow the instructions in README_setup.sh, -# or run the file as a script using ./README_setup.sh) -# -# ------------------------------- Initialization Section -------------------- - -include system.in.init - -# ------------------------------- Atom Definition Section ------------------- - -read_data system.data - -# ------------------------------- Settings Section -------------------------- - -include system.in.settings - -# ------------------------------- Run Section ------------------------------- - - -# -- minimization protocol -- - -# Note: The minimization step is not necessary in this example. However -# in general, it's always a good idea to minimize the system beforehand. -# fShakeTIP3P was defined in system.in.settings. It is incompatible with "minimize". -unfix fShakeTIP3P -minimize 1.0e-4 1.0e-6 100000 400000 -# Now read "system.in.settings" in order to redefine fShakeTIP3P again: -include system.in.settings - -# -- simulation protocol -- - - -timestep 1.0 -dump 1 all custom 500 traj_npt.lammpstrj id mol type x y z ix iy iz -fix fxnpt all npt temp 300.0 300.0 100.0 iso 1.0 1.0 1000.0 drag 1.0 -thermo 100 -#thermo_modify flush yes - -run 40000 - -write_data system_after_npt.data diff --git a/tools/moltemplate/examples/force_field_AMBER/waterTIP3P+isobutane/run.in.nvt b/tools/moltemplate/examples/force_field_AMBER/waterTIP3P+isobutane/run.in.nvt deleted file mode 100644 index 602b8c3295..0000000000 --- a/tools/moltemplate/examples/force_field_AMBER/waterTIP3P+isobutane/run.in.nvt +++ /dev/null @@ -1,52 +0,0 @@ -# PREREQUISITES: -# -# 1) You must use moltemplate.sh to create 3 files: -# system.data system.in.init system.in.settings -# (Follow the instructions in README_setup.sh, -# or run the file as a script using ./README_setup.sh) -# 2) You must equilibrate the system beforehand using "run.in.npt". -# This will create the file "system_after_npt.data" which this file reads. -# (Note: I have not verified that this equilibration protocol works well.) - -# ------------------------------- Initialization Section -------------------- - -include system.in.init - -# ------------------------------- Atom Definition Section ------------------- - - -# Read the coordinates generated by an earlier NPT simulation - -read_data system_after_npt.data - -# (The "write_restart" and "read_restart" commands were buggy in 2012, -# but they should work also. I prefer "write_data" and "read_data".) - -# ------------------------------- Settings Section -------------------------- - -include system.in.settings - -# ------------------------------- Run Section ------------------------------- - -# COMMENTING OUT MINIMIZATION STEPS: -# If you are reading the coordinates generated by the NPT run -# then you should not need to minimize the system beforehand. -# -- minimization protocol -- -## ("fix shake" is incompatible with "minimize".) -#unfix fShakeTIP3P -#minimize 1.0e-4 1.0e-6 100000 400000 -## Now read "system.in.settings" in order to redefine fShakeTIP3P again: -#include system.in.settings - -# -- simulation protocol -- - - -timestep 1.0 -dump 1 all custom 500 traj_nvt.lammpstrj id mol type x y z ix iy iz -fix fxnvt all nvt temp 300.0 300.0 500.0 tchain 1 -thermo 500 -#thermo_modify flush yes - -run 50000 - -write_data system_after_nvt.data diff --git a/tools/moltemplate/examples/force_field_OPLSAA/WARNING.TXT b/tools/moltemplate/examples/force_field_OPLSAA/WARNING.TXT deleted file mode 100644 index 0d8c8e0308..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/WARNING.TXT +++ /dev/null @@ -1,28 +0,0 @@ -# -------- WARNING: -------- - -This directory contains some examples of all-atom simulations using the OPLSAA -force field. - -This software is experimental, and the force-fields and equilbration protocols -have not been tested carefully by me. There is no gaurantee that simulations -prepared using moltemplate will reproduce the behavior of other MD codes. - -# -------- REQUEST FOR HELP: -------- - -If you notice a problem with these examples, please report it. -Peer-review is the only way to improve this software (or any software). -Other suggestions are also welcome! - -(Contact jewett.aij@gmail.com, 2014-4-19) - ---- Improper angles --- - -I am also uncertain whether the improper angle interactions generated by -moltemplate are equivalent to those generated by BOSS or other molecule -builders. (I think they are, but I am worried that we might have listed -the atom types in the wrong order. Let us know if you see discrepancies -between what moltemplate and other molecule builders generates.) - ------------ -For more details how to use the OPLSAA force-field, read the "README.TXT" -file located in "ethylene/moltemplate_files/oplsaa_lt_generator/README.TXT" diff --git a/tools/moltemplate/examples/force_field_OPLSAA/alkane_chain_single/README.TXT b/tools/moltemplate/examples/force_field_OPLSAA/alkane_chain_single/README.TXT deleted file mode 100644 index abef639d46..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/alkane_chain_single/README.TXT +++ /dev/null @@ -1,40 +0,0 @@ -This example is a simple simulation of a long alkane chain, -in a vacuum at room temperature using the OPLSAA force field. - -NOTE: This particular example uses the OPLSAA force-field - However, moltemplate is not limited to OPLSAA. - -1) Create the "system.data", "system.in.init", and "system.in.settings" -files which LAMMPS will read by running: - -moltemplate.sh system.lt - - -2) Run LAMMPS in this order: - -lmp_mpi -i run.in.min # minimize the energy (to avoid atom overlap) before... -lmp_mpi -i run.in.nvt # running the simulation at constant temperature - -(The name of the LAMMPS executable, eg "lmp_mpi", may vary.) - ----- Details ---- - -The "Alkane50" molecule, as well as the "CH2", and "CH3" monomers it contains -use the OPLSAA force-field. This means that when we define these molecules, -we only specify the atom names, bond list, and coordinates. -We do not have to list the atom charges, angles, dihedrals, or impropers. -The rules for creating atomic charge and angle topology are contained in -the "loplsaa.lt" file created by step 3) above. The "ch2group.lt", -"ch3group.lt", and "alkane50.lt" files all refer to "loplsaa.lt", -(as well as the "OPLSAA" force-field object which it defines). Excerpt: - -import "loplsaa.lt" -CH2 inherits OPLSAA { ... -CH3 inherits OPLSAA { ... -Alkane50 inherits OPLSAA { ... - -Alternatively, you can manually define a list of angles, dihedrals, and -improper interactions in these files, instead of asking the force-field -to generate them for you. You can also specify some of the angles and -dihedrals explicitly, and let the force-field handle the rest. -(Many of the examples which come with moltemplate do this.) diff --git a/tools/moltemplate/examples/force_field_OPLSAA/alkane_chain_single/README_run.sh b/tools/moltemplate/examples/force_field_OPLSAA/alkane_chain_single/README_run.sh deleted file mode 100755 index b31401f135..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/alkane_chain_single/README_run.sh +++ /dev/null @@ -1,34 +0,0 @@ -# --- Running LAMMPS --- -# -# The 2 files "run.in.npt", and "run.in.nvt" are LAMMPS -# input scripts which link to the input scripts and data files -# you hopefully have created earlier with moltemplate.sh: -# system.in.init, system.in.settings, system.data -# If not, carry out the instructions in "README_setup.sh". -# -# -- Instructions: -- -# If "lmp_mpi" is the name of the command you use to invoke lammps, -# then you would run lammps on these files this way: - - -lmp_mpi -i run.in.min # minimization -lmp_mpi -i run.in.nvt # minimization and simulation at constant volume - -#(Note: The constant volume simulation lacks pressure equilibration. These are -# completely separate simulations. The results of the constant pressure -# simulation might be ignored when beginning the simulation at constant -# volume. (This is because restart files in LAMMPS don't always work, -# and I was spending a lot of time trying to convince people it was a -# LAMMPS bug, instead of a moltemplate bug, so I disabled restart files.) -# Read the "run.in.nvt" file to find out how to use the "read_restart" -# command to load the results of the pressure-equilibration simulation, -# before beginning a constant-volume run. - - - - - -# If you have compiled the MPI version of lammps, you can run lammps in parallel -#mpirun -np 4 lmp_mpi -i run.in.npt -#mpirun -np 4 lmp_mpi -i run.in.nvt -# (assuming you have 4 processors available) diff --git a/tools/moltemplate/examples/force_field_OPLSAA/alkane_chain_single/README_setup.sh b/tools/moltemplate/examples/force_field_OPLSAA/alkane_chain_single/README_setup.sh deleted file mode 100755 index 54a6484dac..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/alkane_chain_single/README_setup.sh +++ /dev/null @@ -1,26 +0,0 @@ - -# Create LAMMPS input files this way: -cd moltemplate_files - - # run moltemplate - - moltemplate.sh system.lt - - # This will generate various files with names ending in *.in* and *.data. - # Move them to the directory where you plan to run LAMMPS (in this case "../") - mv -f system.data system.in* ../ - - # Optional: - # The "./output_ttree/" directory is full of temporary files generated by - # moltemplate. They can be useful for debugging, but are usually thrown away. - rm -rf output_ttree/ - -cd ../ - - -# Optional: -# Note: The system.data and system.in.settings files contain extra information -# for atoms defined in OPLSAA which you are not using in this simulation. This -# is harmless, but if you to delete this information from your -# system.in.settings and system.in.data files, follow the instructions in -# this script: "optional_cleanup/README_remove_irrelevant_info.sh" diff --git a/tools/moltemplate/examples/force_field_OPLSAA/alkane_chain_single/README_visualize.txt b/tools/moltemplate/examples/force_field_OPLSAA/alkane_chain_single/README_visualize.txt deleted file mode 100644 index 019afc1444..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/alkane_chain_single/README_visualize.txt +++ /dev/null @@ -1,87 +0,0 @@ - - ------- To view a lammps trajectory in VMD -------- - - -1) Build a PSF file for use in viewing with VMD. - -This step works with VMD 1.9 and topotools 1.2. -(Older versions, like VMD 1.8.6, don't support this.) - - -a) Start VMD -b) Menu Extensions->Tk Console -c) Enter: - -(I assume that the the DATA file is called "system.data") - - topo readlammpsdata system.data full - animate write psf system.psf - -2) - -Later, to Load a trajectory in VMD: - - Start VMD - Select menu: File->New Molecule - -Browse to select the PSF file you created above, and load it. - (Don't close the window yet.) - -Browse to select the trajectory file. - If necessary, for "file type" select: "LAMMPS Trajectory" - Load it. - - ---- A note on trajectory format: ----- -If the trajectory is a DUMP file, then make sure the it contains the -information you need for pbctools (see below. I've been using this -command in my LAMMPS scripts to create the trajectories: - - dump 1 all custom 5000 DUMP_FILE.lammpstrj id mol type x y z ix iy iz - -It's a good idea to use an atom_style which supports molecule-ID numbers -so that you can assign a molecule-ID number to each atom. (I think this -is needed to wrap atom coordinates without breaking molecules in half.) - -Of course, you don't have to save your trajectories in DUMP format, -(other formats like DCD work fine) I just mention dump files -because these are the files I'm familiar with. - -3) ----- Wrap the coordinates to the unit cell - (without cutting the molecules in half) - -a) Start VMD -b) Load the trajectory in VMD (see above) -c) Menu Extensions->Tk Console -d) Try entering these commands: - - pbc wrap -compound res -all - pbc box - - ----- Optional ---- - Sometimes the solvent or membrane obscures the view of the solute. - It can help to shift the location of the periodic boundary box - To shift the box in the y direction (for example) do this: - - pbc wrap -compound res -all -shiftcenterrel {0.0 0.15 0.0} - pbc box -shiftcenterrel {0.0 0.15 0.0} - - Distances are measured in units of box-length fractions, not Angstroms. - - Alternately if you have a solute whose atoms are all of type 1, - then you can also try this to center the box around it: - - pbc wrap -sel type=1 -all -centersel type=2 -center com - -4) - You should check if your periodic boundary conditions are too small. - To do that: - select Graphics->Representations menu option - click on the "Periodic" tab, and - click on the "+x", "-x", "+y", "-y", "+z", "-z" checkboxes. - -5) Optional: If you like, change the atom types in the PSF file so - that VMD recognizes the atom types, use something like: - -sed -e 's/ 1 1 / C C /g' < system.psf > temp1.psf -sed -e 's/ 2 2 / H H /g' < temp1.psf > temp2.psf -sed -e 's/ 3 3 / P P /g' < temp2.psf > system.psf - -(If you do this, it might effect step 2 above.) diff --git a/tools/moltemplate/examples/force_field_OPLSAA/alkane_chain_single/images/ch2_ry90.jpg b/tools/moltemplate/examples/force_field_OPLSAA/alkane_chain_single/images/ch2_ry90.jpg deleted file mode 100644 index 39a88795579f33345539451daac4815f999961a6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4680 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 diff --git a/tools/moltemplate/examples/force_field_OPLSAA/alkane_chain_single/images/t=0.jpg b/tools/moltemplate/examples/force_field_OPLSAA/alkane_chain_single/images/t=0.jpg deleted file mode 100644 index 39633edd5e6987b9b6f72e09ce493a1e3f3ff018..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 51583 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

Vq#DdArP8mhq%B;9kENP8V3Nk zTf z5DlDf*=r={N9s`@Op9m#03(S}_mgXPK4fn>&ojz-WXnSCdOI{h17xej`2KNWT_m2H z)y3`X5!{2Ae!xQah?YTMK>)7tMR~SDl%GOK@thyYy?OC*_|5<$piqJ&s;<3&Q|lmc z5yL~bk@B1XBujMHI5-hu6U_F+mB^H&_`4_Hu?`6lB{DFE^r=!&?Obi8j8c;9pA(he zsDJfg&eW=VPYs>^k5LO0tYcoLPmg$UXcS~q1QThn=Iq|GALeB*z-HZR_2lJT`Cnud zv8-gke3=q>6ix|4x5nNjtb^Mm;h!gY6sjchYsve+KF0>tEVHdfc77)`CX)EhQvI_M zxOi-ngm9b7x;-9peknmq)cnht-rqn}H5~>uz;J`7r~$wZGJj2Ees*%A^S=j|^@?=H znSx&8Epiplv5B=>Q2A(eJ(*@416I+HwDC~ufkViqL6c-aYSYG;@@oVVSo+Q4A0!6( zel`WD2*uSsHdQ8)d57y1Z1tGwI5SWr12F)j012w~V~++%;PB7$n||?GR$7GuOL+Nz zcwa+X^LR3Z^>L+6Y(5`f7Y-a|08bpMKVzQ{REaUy@e`6KP*-1!iFn|N)rpmt&t9?; zP18R?jTNimT672lfDEzw@h2@^pB$e4GP-o`F!?$_Vu5)k+~;#qo@3%jZjk zB&{$W8+UQ@n~v0>{CAdUTKotOu@p?v=n>X^0>6q+jAUn;J1TisAVR^LV4oI$IW%7b zlYTNF@?8yy&>$5{wd*7e%h?i}L&QwXfX3B_=LAaW-pY7)yoIvc3%r(0rIossgcgJ4 z^@1}+@)3I3Ty$~mf&1pyITF+V0F5{rKr-WqCQ^#5;ZiLhJ5`liRbO8d%63friRm~D z<-_r37}_#Tl%wY^U7Z$n!b=uaqQC?c9*8hZfi4&qw zF4}f2=4;gsa0b^zyyLqeWEj~ti`AZ?L1Z8uXE(Z#&~;66ETc zJj?88KtPR>Pt+4`GT#H_J~B0LY-yE1qDq1!gY$(fCX=`$WttWwqX|X=NXfYxamiSs zHiHo6b(T$xlqWrm)O<0fCVh>tu6`V+zZ54YHd7{&)A=_U!MfTPkU%04c92n#1`8w% zgZOe`A3R)gH;cW>WQsC0r}HHVfItu+hy(xu0Ao9#5)(FuAuEHt5V=|~l8HPxt!YVh zEy`qv%kXz6Q3vEOti3B307+jNuQ*{?B!Yq=i$F+TZBEsaA6D9Qm8_c*x9oB@*%LN> zVhl3=Rlrn{12UsiWaf#L=7QYa)L5nGfkWb9v*QY;5%K7~Bg|%j36WohTzt* z-q8*7h`o4cSvfU}g56UnG8+p-R*&7`Hi?Z>_KZ^Dw^&eR5f|P{Ubz<RA)T9+4XA@PEXK+FS-nO|7MGaPIYjv`tlrqa>$Ccm}yxG}DV8UZDIWjWmnO-HcJP@Ubgk2yiDjQDiAiyj4D=XM{F<^K*?|KXU<*&($01nQx{(T=-C^z# zmRW{wt>AYkGtHX$dWlJzstiS=C~}{eJs4qk`^j2?KjtE-^qRn;1h&Msh)zb%aO2GU z){Pl9L}2=3`aiZ2ggc2e3N3Y#E#!Jmu$c{Hw>T7-Aj)Pm-yR$&Ck#~OOFm^urYnpE zU61Ng&C9GE2%EVvM%2LeQl{g}Wa>@d9d&%*5=y=Oo{kbhM5mMB6WGQilU+^d4 zUHIb``@!XIfOh1nnOs?fh><50?Xoa`(Rgwf<51+Dn7mn=W(`5%wedMjjYVmb1l(%L zm152S6`N6I)PLB3{ROo0Nko4CSioGbH2QUVFmOhon5sVhl5 zg8XdBR(&`nN(&z@uq!m8Wu3@^BJClT^i%!iNhq=D$p$3HB8m|=mQd91vov=nR_ejX z37_vLwJIeRSr&E%stH?&Di!JYyM4^G2w2EfIWHNCW?CDg- z#-r_$(7S=sMiQ2!Xx1MlR8B!5Rml4?oMT3^%Z%*`&T2?kRf=@{fw3J*YgnxmA$rlY`Q zJuONO3yH}?8eA(JLX)8JieVK8`>4bsXxb7=_BNrKu~gXsDgkq8AG{LLXq03B05T$^ zC2VvPfV4`*<2c!LE;#kB(YA0X0$M;NsLCgLshrfPl_3d2bKdDBMa&#w0gm7o?U9)R@Eu8;n2!FkhL(R+$Hohq{#{k}qNSahaOff{{VPG+1;k6q=$c18>s9x2*EjN=&ZedEgoI2bN>LTG5REf_nQ|8 zr{o9QApn&SM5CxlB+QA~g&E*AQs3(&BO=y0T$z~~W3Twd6Nc@l@WMfj9?%2wiD2Gn z(VAe(bCh$bcz?6`$OzpL?DLfQ<_5n$GFeb?dJJg$ zozvWulL{=XeTd);=|C?lf~V#Zym=Q=o=))Hxu^mbHs=V~s{NR&lHn!r`^zlgO|Li& z^1{V3!63@p`HNK;wXzfq983*{V35e~2!|t)3bt51u?|EgCjtWTgi#Ms{bCmU(#1tc z2#HC_hZ5O?UXXKmnNj9r1K~qRw-T&#DLF6*LOCiemJ*E(;59iYa%lim&rUgF>vpnE zUn(MIV8$Vfb%4%piny}_%H$_3IwF>9CQLiL0HQhBP?|U z0S1Y>$>|0%djgNXL|#@gW&=+ROQhn5hX+K?362Mxxwv^eVe>}v@qoF!lZwQ>>v z0LiCGM}!%5EyCWTnAw!}_DXfPNp2Ct6ri*WK!EIyX zG!NT|KHQ={Fbc3to=iKuHv>64sJ1temiq~Lc);Kuh(Ekke?1flYOap((8?+&Oyc-& zFS?%>!EXg}=LDx~9t4{C#c1MX9`Q$A+=4~|JmXcGie?ixFoSG~_`@P0cHbhtW(F~S- z=O==2r8bBIl|uyo0Fan^e}FTcg)Z!kG8!W{6ATkVfN_G6-;7yC$*`smoQmJXF z;B4Lw#KR9&7UOuj_zVMrC(2Qk;V^=v>jB0ICI0{fS=JLq$#1?S^BYP~!bp(Y1j8FG zeZ?#ilhe5D!ACVWmR30|WpFvI$sNIpt0lp}CjPMnLZR9K+Rqq9=^)Zzr2InxPx&Ab zk_!o7G^1H;PR>_(C2m3OYX(1UCxfeDhS0cJ-rsG!?&RNz>G!d!bG zE3LzVu^`?~)6L)q7WTDOn^^GqY4(=1SE>#f4Dg(uRx>276C~f1A!qCT<0X`X&PjeI zhB0tIhH>czXJ(&@#@DSh-hZfg^tfd?BX&-9f^I81=WByl>b)mJyiw-E#uAO9lBy6L zAr*K50Rid$XAqzN04FkJq=%u;0WBl%b&ebAYG6uiB6P?JyeFZ?7V5JF2JKqx}! zy@Q6H(0fM^klqATK%|!tdhbmUsnUB95RfiS1VlkpI*JNXLfd)) zFIWD2dufnG*BC?!Me5_!$xFEfVyJXExCL_+3{2z@yBp8X1HphwmBF=&b2-KSqm=nd_iP!->+54%qP22yUV;p%Vj|^y@%MP|>FU!puDPb37+jXsnW03Fu|5=Q zp&A~zN8EQr#-Ua+jdPS3(wtj+gLf+N#UH`is8LDK3MKKC#^! zA}=yKcV#80db(FaT>InK*+q~T&$HrT`1 zrZgs9gKv&ViG>r~Wp05yY}NE4))z3-}I4{ zWzIG}m;-NClXFzp<_T2Ko0k6uq^{mJ8@ zCwI=ahfZ80j@wWazds)@*qy}0_(xtuC&{6RibUg&@|c~V>eN5>cQuM6KdXhFbf6tg zmqSijJz{wc%;rV(}T6pkDPPs4inOi5wwD;6_$J4ml| zjOBgj;c2Xu4Uk*14rs#ccb)T$ReU|zY4=EaU#cc_+9*RyI?oTt?x3?qK}gs z;JABjK(NV-TEU^`siS}j`K42#JL~(&YFcQgbaSd*CB}5nQbth?F6d}4J3p;nN04-T z1n^azq)QrK3|B3U(1PE2qxDq8K4tM0px5Uf+oQ_|D+BT!U$;K96mPR(a^QR@0d?&5 zvmCP1o_^LoKP{GmD`an^5Ozgfcbyp{?U*V)nP^R7+A5r`8V^gmB7Q#pIX7`w@{I12 z`R?Jnyk%h`&dr#qEQ9TJXzHB!444>Son(d9vyvd6;OwG^C5Mpxp#1SO4_atLF-5s_ z9|s@tKrR!6HRea^6JH(V zJ?IS&o*D}RNq5M(e;_MTrWR=rMnqB-{Stku!(Sqhs#C<(dQ=QDO1wcyw3iUPTYr4l z`32w7Z+sJ}OfUg^I=JR`V*u=+ z&fg|N5$+SAo|z>azK87}?HBqD^DQM*;&44nCCT_2VACY`QfL|4X0N{$4jqq!El>GhUOX0+i~a++}W2G;W<}# zS??xnMaXAJ`i8slu;&Uk6{=FGjQVSTV;0d`qcAT}=zaP6c>HmH@^537cD+u&zDh^! z(}|vm%P-mt+rU?xx-+!}o!=K=&-v;w1&EMtFdOJ=iC_9oJZTAz-SwvUjw4B5u07mP67p`|fa@5tG z(<^oOgkgZbx=6o4>ln8T2L5BB{e*6u7&6ui^)lHk)IbKWr2k27f=f>~eJU$E;r#a9 z?B1~{M|-=Xpc?s<1D`yq1Fp}|_1AKV1=>?CqoMSAzFe1MYz;paC(~Md;%0Dmlo$gA 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 LD4+iT41fRGaTSb& diff --git a/tools/moltemplate/examples/force_field_OPLSAA/alkane_chain_single/images/t=1ns.jpg b/tools/moltemplate/examples/force_field_OPLSAA/alkane_chain_single/images/t=1ns.jpg deleted file mode 100644 index da2fe1185e571b35f1199805a1f37645b2f5c787..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 60111 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 Console -c) Enter: - -(I assume that the the DATA file is called "system.data") - - topo readlammpsdata system.data full - animate write psf system.psf - -2) - -Later, to Load a trajectory in VMD: - - Start VMD - Select menu: File->New Molecule - -Browse to select the PSF file you created above, and load it. - (Don't close the window yet.) - -Browse to select the trajectory file. - If necessary, for "file type" select: "LAMMPS Trajectory" - Load it. - - ---- A note on trajectory format: ----- -If the trajectory is a DUMP file, then make sure the it contains the -information you need for pbctools (see below. I've been using this -command in my LAMMPS scripts to create the trajectories: - - dump 1 all custom 5000 DUMP_FILE.lammpstrj id mol type x y z ix iy iz - -It's a good idea to use an atom_style which supports molecule-ID numbers -so that you can assign a molecule-ID number to each atom. (I think this -is needed to wrap atom coordinates without breaking molecules in half.) - -Of course, you don't have to save your trajectories in DUMP format, -(other formats like DCD work fine) I just mention dump files -because these are the files I'm familiar with. - -3) ----- Wrap the coordinates to the unit cell - (without cutting the molecules in half) - -a) Start VMD -b) Load the trajectory in VMD (see above) -c) Menu Extensions->Tk Console -d) Try entering these commands: - - pbc wrap -compound res -all - pbc box - - ----- Optional ---- - Sometimes the solvent or membrane obscures the view of the solute. - It can help to shift the location of the periodic boundary box - To shift the box in the y direction (for example) do this: - - pbc wrap -compound res -all -shiftcenterrel {0.0 0.15 0.0} - pbc box -shiftcenterrel {0.0 0.15 0.0} - - Distances are measured in units of box-length fractions, not Angstroms. - - Alternately if you have a solute whose atoms are all of type 1, - then you can also try this to center the box around it: - - pbc wrap -sel type=1 -all -centersel type=2 -center com - -4) - You should check if your periodic boundary conditions are too small. - To do that: - select Graphics->Representations menu option - click on the "Periodic" tab, and - click on the "+x", "-x", "+y", "-y", "+z", "-z" checkboxes. - -5) Optional: If you like, change the atom types in the PSF file so - that VMD recognizes the atom types, use something like: - -sed -e 's/ 1 1 / C C /g' < system.psf > temp1.psf -sed -e 's/ 2 2 / H H /g' < temp1.psf > temp2.psf -sed -e 's/ 3 3 / P P /g' < temp2.psf > system.psf - -(If you do this, it might effect step 2 above.) diff --git a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene/images/benzene.jpg b/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene/images/benzene.jpg deleted file mode 100644 index 356c78425644264fd39fa94cbe21122942871f7c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15032 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 M{%z+s@VWB;07Lw^g8%>k diff --git a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene/images/ethylene+benzene_box80x80x80_LR.jpg b/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene/images/ethylene+benzene_box80x80x80_LR.jpg deleted file mode 100644 index 00c82d3d9f5f13a5dd36eaee35d982557be2b1b1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 130048 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%0AlqfP_f5(nxm?-97ZsjdXXHNH@dKEy&P0 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 diff --git a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene/images/ethylene.jpg b/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene/images/ethylene.jpg deleted file mode 100644 index ab5bbbf49b35b63abfb7e5eb6a3e8ef8b7dac5bf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11657 zcmb7qWmsEH*X|BUaCdhJ?i45#cXuchch?puw79#wyE~LpiaQjywm1}b+Tw@ydEW1P zf1Pukm1OqZGxw~$=GwVt?ySk<;^P{CDK9N24S+x(K=$bcJbncv{-FOgI5;reAA^9w za9}6|3WY)-5GXtXJQRum4}riV!6P94F(^C|G7=*4AMnS?9|wO%J-rd1M*XGye-)2C z02U&!3c><|umCtL5Eu*e*awgUAOHmY;~e;pAv{Hchy;cMAwTuw{#VDpgvVt76$}F4 zFu|Ar06JOw&$z!=@ag@3uqUP*X&NXa)6&onz!ZZ|p_bs=s`#fogsnp97?r0b#i z!4Hj-_ppp51YRXn4rB5!fq2AvDu)^m;GfRFd;gRjWv~V(!lfC@9x4E6E~R$kM+nl zbz+-LpYQ(V1Wh;*$+=J$?p|;fRzoI0p`^8JKm08j5+?_dB)^~j;c#xI54@0tcefkH zOwlL`*#kh8R)P^5h754a(w2!S64ZRMyWu>30JU41WjvN#R%U`jcQ6)}ADILnZ5sg4 zY^Gb4Cnw2pE5gdy7=~>GJ3Oob8>HTbE=}^%dQuWp`#lc^jk3~306>)8?gkV0XyI9O zjYp-$Ab#6l|Gb^l`{l>Cd*+dVq8b|PxIB998&TSx%cr=UVN+Z?+R4Fs@7POVGW|`X z5dmXn#g`xOEL?VFET|;)(a*A(g}VUY<(F-sfO#}Oo>0wq6UcAsrEWwoSWq7Io$^(P|6PSLz;-tCLn-k~Dc2;8#K z7xAzgb}79}pB$NRd9{?y8;Bs~6A%4e7NW3<+2NfC26bEuj!Wl{@*UT%-^?l!mls0v z>VD(sKgdv?cp~V=8OJv9NO%bOmtMFX3t1&r4!6mniRkPYZdIT7DfO2ziW#_)7L3%HS@u-soQx< zJREjS*}z9{<`aHd1HcKh4d{Zz#Y)*x*FL3!Q8=k*-6g-Nf=IHum{h2LsuE(wl2vp0 zJ%t4zh(w!kZFJnRN+WuaH3;Ah+~>4Zg}BcY_bC5R0M#sEu5)n)QyyyU7te(( z^N5A)(vz`~@Ub`pNp74}|8mg9@C$jk63IAv(VrV=`-%M!Mvc4X+$842sWmV9%K+;t zd#9)C>PLc_>3;*DFBh*O3ci``>}GcU?FP_vc{&CZJ~Z#_k>>&LFp|MUU) zuKT`z|JMJxAUv%Ite5}*4+nySe_D;e|1^W(z<*XSENm)7OdMQF4m?qOY8q8~PM)Ww z0`X}90YTv&0q@P|hVLQHBbq-I9L+m6DQ!G5mHL=E2k@$#k_UXX0Fn9zI-Pp6Nrt-!Hm5aHcNbK_2*=S3U04iFKqD6ZeldTEi&3GK<3tUHpZ;9p2(PE_6G|aFPuSyBb4xLky)iso zfvmp#>fxO%vVJXpE`6V7QBS&9i5o<0rB}ug7Ee`cbI{U#%xax%$>IWPg1s7MZ2s7<@Ba zzZX8V@mvfZ5tA1B%Rv$q7LXvswS&^uuewZfV>xEpNmiWrOM4gzEzTw<|41U72P$YX z2o9ls1a?(u+H$|Nh>8WJnRMobeabN_dJ%)#9gKmoFjBbmS$Q?{kT(Ma2@yG_mhFkl zNe>d6LFQ=0gE83SK*39VY^GG0nAn)qgf>z$j8c6$f+?sl<5(s>x62dyq@R_d?DWZ9 z(KJO&Cho)U<2C}KV0{GlNS{+Uug!1{(H4i0AVhD9sI4HEHFDeMw(zKSJ9rE)Zd~_c zzibR2BHo3Iv7Mre1%Dh;_b-EWQ(ViLRSDMa1|mU>le?}I8GAYMOhgAm<+)pz-fM67 zzYnvAq;0thkV(YlnMeyf0*o*Z1f6>lRk;`$nm9{T7*TMUr&I4|Q1HDWwaenOw1DYL zD><_=SAlbmy!sm6yCZ)eLvls|b`0HLTpiCR1(1F1ZxkS9*r7DJY~oR{ekjU<%06i^ zXU0wA+tsbqR^4cA$$7EblU?=XnEatFqF};a=g5xZ1^6!Jx*JCRGe-4t@<^hP73ZI? z>!UNcon+i%l;lHI_u=#Gke$uiAABR?L1|+xhhZ_sdTw4?DpPgmJQ^Att8hH;ib>2z z^$gJztdCj*?34?15Ad|`7pCiS(Fjt|C(WADnw{d~iKt3mx?s_aCMK_Y&f9@mPkTMk zUjOE^6GfWN*u-`+uaJioWWZ5NImvxth&+)x!D$>XD)X> zSY%_#-BoNAjM0Jc#*_`559Zqn+ZfVFMWf|LjtP@_oPC$?SRm#O&0crml9$cO`+7`_ zY*$vC7sdp035qt#cy7Jg%kuFKO03$7YmXHyd4#LBXEy<-Q*b;yc8YF}OWgh+~2JR3<8OOJVgF447mScC}9F1I0)!T>LMURp?|zQ zZDRlgiiJ%{#VMv{0*{G9&E?`Bk4wWLDz0vtUr);|p%KtMg@Xy*ZGrcaU8d$JF z$0OBy`tLpmFY>g{3G3HXqw&OhFiLkJYG{^74(^eT<#d;z)Xr*-z8evZQokTwokrCO zYSk|-D!5)ry_DHcliYq`QC{xhE%#!x?s!y#>sf{3Ekasub8Ul=hUPrZhlY3bB4-B_ z4G*U&cDPsaWtnC+Iw~$9xzd!uMKGhWq|FFTha-m6MH6|6;B)4p2 zo!{@Ozjh4c{!9)r^^p2}IjFFKV2{|tduAO7&#)U?i(QP5yKuPR^F4_CE<80u8z~gg zq_Hmd5QFRpelvV8F%Oj*H8QeeHht^n>!nKHYp-Z><^2ZQYo%}7@po~QgkKQQ^1eoR z5DjStJOa@~xI}MrloUM7oj@Y9rl;&gN61Yk#EP!gyJ3|>!Jfs#=S5EP(+Fp|ochz~ z7j$~qY0a!+@(e4LucZm%G(KzEL~~9@b9z?Ku{iUx5gssWJpxy^=dd|Ye(CJgt;7Q+ ze^d8|U^16crE>MLo6h(ezE<8zp7v}#SV|so zj-smx^;1ZBi=BiP)2qHrbC5!jo0YVQ<{(TZ(4NT?^}MUGTTq>v<(0}C+|ujM1^XJ( z-s@)y#->o4mZ}&B8}qNo{;)p?55IiBRM{UF6FuE!xWfxTOfwMQ? z*;sBHPPJ_kE^J#ce@OL3j}mQICR|-pO{5yl^OjxhACQV}j3cBP1u z+ATO+Dhy~;#{#^f-pYTSL!V<#Mv92qzo*M4@tcHSk2~)(u;ifqaiSLwH#|_uA5(mA z6r-+g%&7f?uWD3AH!ufJJ5yGRPfE<#sN`qTPc-34ytKn}Ce+f0ivDjY&y|}zD5CT2 zg_4{0an+kDt$_}(?~46n`XvkkgT@#Fm~l&>7i z9+GqF1!rklUKV!Rcd0WUquJ^}h(Gf8<)OAXK&xk~+F=Lt1gY?B0;wG_o3Gv{~k|YU6y)QEF8l zgD!*h2%y%4-O|Dwp&V66NFP3&bGu#0ceC`$d-c{c5^!o%Dek0Yq`8`SUE(o40`HWg z;s-j%8sp{c(uY)9wgOXECzLv;v9{XGA1JfbEpk_>D8>`GGQ<`=S5@bJZ=v&=JM&)Z zGVUyq;hwR`m?b@TyL!0WF5#AWW?^+wEa?r;y!%dwz z>x=F8MJVW-IXcxd**CT?Y_5`*eY->zzgm2VV+oBDN8Kf#_VD5A z=Zl-mP>Sm7X~*6boLH%LVU;c|%1^q;axZdCWS%d6|1(mW(W>rPlg&h#u7{V_HWoXe z45R3o@;Z%NBRg}!+Lexj{*`$7+=%-em%TSz$>LyD;vR$NcuIQ3sN>ME4ce~Dd%s^j zbc;5qP4VW%G#oMNucQzRe}4?3FX@lx$nIQliZ@6^XE;wF?uH#5 zp}BsUp~CyhCiuK6JzVW_JTlU0X@J(cX=%A={mXFOlHM-~4IjRAC43344x(ge$IgZ~ z%uZ>Ust)V3l_nxb0TrL2l?_U8I3q+B_{U0q1Kd*0XSA(M78Vcn z-&T$|zV*zk&us2#3okft*Yw;0u~=R0#Mg@*ZU(JqtL<3qjBI^X?cOj4Dn_zEMqTx02DN~TLUcP&T(JOK&+v?U z)aik1LKUy370z@&BN+QATg0~OjhI6pV=K0OQM_qlW26Y#ER7^NhE}$IGk#)ts#fvN zPqIyVM=!b;xIX&8f%ES1#9Jz5{$l=(=-FbD1T#qkILZQJg5|G!i2MYeoD2%_qOJ~C z=hk=1yKzPG7?`~#!17{DGuhU+pV#jvh9R(~1{^_QjeO?Yk1bsrT{+&ZGO&F3Q`1~6 zD=gPnvmcBdqU@A@MTW^wJ0`Gk!PNcbyEjQyXWc=+es%d1G+_}CMOiflFej&Kc$GVc zkU-oy4S#%hyzex=s~WZTe$|)6%0!fes#$~`=${@+Oz<4fdO}{KPTWkBKde zU1|Lbe&%YHRaHzj4y)Q`?|1xx71kQ0Km;Bgs~Gd=JR}qrA{Q6L)A*5mw>kJrt%~eV zzj0nuEy1zlcaU_4+aS3o3tjj(EgC6uG7UAd=1~btQ1x>Jd{{CY<%3UlPhPz}+DPw1x=u*=X>1&1F<(sfs|I=`etC9{VJsnJ}Nyyl@~e82l$g{8u6aSbxQ_ z3nryMM|{3$efQL<>iXG#@;o9`k3jo+w<>GJZj=J2hE-Se<{N(47^!ssX?!zcFs{j=X6f%>iJ98$XTr=8>VGLaMk$+t81dLvK%N#qO# z&Kp|n{nM6O$PB##)7swT!yzG`L{bgTT{n`LEvdiWYqrqP&Ggzc((Rl%_gC`Eq+Sms z1p%c>&PQ-m_x{=o-nYTQ8{a0{3^uO=9FE8y0gSQvH0O1VFZJ(yHwiHK5fX+Rv3EUak*5I`sO7TimEOF` zBOrO#Whqt;-@qD!L$TSue{ah-Uwr-vowBXhNYnMW1HvCPMKl~X5s>hWJ5fW}$|3g~ z)LHfs05dP6TgdUXWC0T=uoO)dlftli>WApx;yHqD-vj!C29Rku z0cQanNhfr_sk;t~m@z1>)@%LMYu#BM@NQ4TG=x|w@v~q==Yo&1ZD8+5cbJp!zW@AO zWOU4^XW9XGAx4VMrLu|PtqldHAc9!*t9LKKCnAJLtdiN#j9nk@WviqLJ9P{A=h|Gd zqQr|k;JW^fg6a?$`t+y03Njx0o^sZg?W6O!N;S_+&q!InZRAgWGnKHQ^}4BklXEGU zOvA#S@J{BFc0QUiuLLiODe`%kh~~(#(%W>8K{#iZPVza1@b(GPnS$DyJrmxx!NT97 z5=d_aR1uD`Any7&W+bXZ4OS>Inm?txyza_a zMtI}k=Jup-S@4(n_FxA;_hl;jNCvL-qcS{HUuEawx08|;#*oUSzY3H&j6EY&C~;0$ z^^2o9jv~vtj{ZzyyHjt9VEyt1=Ve-H03lUu)`+3>K4^D!rajz{0o84K&Z>uST%k|r z{bHJC!6*7ncYh;!sb@Up?(Iz0T)58qP8MLszA56*1*>-SCpd>381SZ2Y3#%@xD6sG z5h#&E3T(_{Ejvr?Rt`BhrXu%Pvombv#{HwU>V@GY5_{ZaD$HU+BP#@ZuH8JH&wdcX zLYN}@$ENc?8V$;Z5=5w)_H_6Xh~Y=w2S8pud!2OWg}ap)P`e=p!lqN z_pdc%^G5rKEt%p7#+rS77qxRk@XRJ_%w%?)v&_ov82zHp^_~eRYb1%z+lFy9=CKb> zm!U85;Xbg`nAvak2)*zdpuV`I-5T{}J^S+fR{DT-p6P8`*gaZg8YKcJ^Ink$nG$lt z>sSMt&!saTK2=dg@goUJpi-vj`XazWSC!OG()3di3f`!|ZlHMH-P+ozz*|Q$A1ym>--30q1UZc4`3ghy^L-tk85y2kSRZzZ^wbyVcTfTS*x`wA0uKpmY;ylN ziz*6Ji~PvSuD)d`O@>l9{sM>@wT8mv&?PwBQLb2ZhR3$NV;vW8{vq-ykXX2(POsb*ThOgyi*eKx?w!|Hj1zM}UH!JHMNZinC;vdAz zGgJoIo}w~JxwBE4_PjANERAkS8=iFjm@OAiSvkdgRIgxY5nvQ829y`;QECQt*M{l7 zHfaz*mstcieHu>JX>9$aI1y%{enFrbBsGe_`SiuU{{a{*j({?`u6ob z%3-@ZSK#1?s$XAUR937zW*}5PovB^W@daG_cRZrgw@gBc^{9rf=)M4m#gV!pM&Am? z?!#N1Ct&8r>u}yNw|#>z=W{=sGJMXZjVD`YLKcPm&Aw4EiVD|XDpzmG8=mHkBkZ%| ziLU~0K4)q2ZkZH1*T{sa9gW`sf$4gitbv1yzMIw!TSm@3A<+%rHlE&R=Hi&*)g;os zRx}iiyNHD3d~kFoISy&&XrJJ0IX-|!zJ-M;TgO=KU5Ic@u6ytZkY0+UZy9jhaYbje zfj!}Vp)kMwJe>n)y&&u=5$pqfKlG$W{vJ^Se-5ag&a3|0DE}K^KAn30F-ROh3CKbI zrOMIz0T4gnuYoAz5P>+^e*l0fO9_A|{Y3vjIDirxpoRM<6A6M~KQ$o&34gjEm~u}g z5ckIqWdh<;2>@c0PfR}$fGzq2XfdDeg$ThErF{Z^PoJl{91!Z<9u%M+^i7b-VBn~BK2s(NM646dKV z2#kH^`KcwKuc~-Cr%ev4uJ3}=3zHHn%-7=x6^{E|VH$YQ(hUaT?g9TM#Q!ddfjjfF zn-=F2C5-j^Ec`JFHtV}mX@*^YnJCIiYmn9?(Q{9*a#c((d~}|lvdV!ViE!!IwbdbE zq{c#&=ID;8jX)}~0h->mrZh8DIzUBv<2e>tuHxl+uo{#&vM$S2Hi4AXussoRfp`TlWvf)4Uz?Uc2QlZOiAu~8nQFF2=&8~{w&{Ww z5hrquQ^w1e5{ud`q{hBzqU)mJG9agTf9S7|&f2BA-Qu28VTL}&*ldfqjCJ->6aYuB z^1$0JQ8?s4A*Wr$mhhoVBQz@n#&S&S5eIUdsE^HAsYDB?(X5XE|0UI#U+zZ-B65D8 z*g|^>-c3Uo(aOqcuArO0XHu6Uc}9O5biD`k2uxDwwj!c@P4=yJ^_IG{At`!V(=zX& zbpH)NE1XaKC?`T2OK1-Bn4##&sawx-70V`~$9~)Y@&TdUXV$Qvg&VAAc7- zW`AOa1RBgrgX20A6S{~9>U2rq*~}fFidp;B5`Zp%w-U{Kpgm@>u{4Ub+*^@zS{6Qy z=pMeXip?hW3SOMtm;kXvfoxLC%ZPtS#6VS0vWLe*VV~rdCXZ9SGu2|+n}PyW2A${f zo8rSUr!K1Hgqj~;Ro_*b1gr(kQEvSGXv7IH^$IC}QB4v_ewh=T#nM%6(uiP3g<7kXXsu zxRS*m-7aK0kJHP}}r15J$bhP=1z3lNr(U7T}R9q`j8|Cvb$v*b`2|?I0h#ad&+grGZE%m3+g&c;5FZOHAIUZAKFj3YwGDUm2vsJ(`~VULswVkMX1pHyro_YK+P7$l z2uS=e9FyJO@P4R>Lfe$)NoPUs=@>i)k}YR`Iv0hQ80BQxWlD^t!9z4u!hjIVA$2x8 ztv$HcBq)g$&~rTriFFj26v=JwzLW$3{(T5Y+Nb!kP==1;>zp zv27|vZ0$`K&%EtZs$KU7<$I+24Ipz|baNB`S#Veu$2PH-z<{cg0In4gxQ3%Li-#58 zOMcD|;Fn;SEP)G!hEj-_XJSr6d(-v~o;mSH@=%Fi67^U?Mr5dY^|~EAhY%BS@Hz}X7VVw_arR!A(s-$S>J4QmPAlnmW_3VXHOd4m-r8Azawye_}vd`gS+AM6d(CV5jSE2em z{m$9!)BX9nVz+zNkHFhU0LN=4?A1K}nEiL|h|>e!L9M$j0vg=U{Ah{LOgv-7>;iR? z)2MgTwZxFqtgSZmWI8(RoZm{wIPlU#IK))K2j;ZJGe zqLJckqGO}%lQBCWV)yi)=bj*S9>z54)G5y#AAPkz6anuf+k0O}KM!&3#SiaI`OQJp z5$fGPSqJ0$a)SQK0RESY!+_%T4+OUU5m73%fW_%sW6|_@Tqw(-g@cN%g|c(ZMeu`* z&o}p#dU{T?6kcaZT<9Ht@GC_cGEut^OQH2yY8>~ZJc{B=7jDbjPFbqo_|xc!6+Pa; z&5NqO-fYPG@)gRU2ttPGERssNsH=qug+BtZ^aNQ5Z;S-$J>EH!F@_zD8h);VpDiI{ z8I(nF3o27SYG|?#!-Boc>)*x5vQq4o#0{_5CqzbrGhpBtkeXo1}E8rB%`3;HI-Ed!v+Kh~T$E zX#bv{+$>s)c4|9x4a4hMD5xik6-jCK9K#AHJ0}h06zVV1`x9%UfLbWM0=G%(+pAFn z(w_cSg{`2i)kb1FDY16dux1nE(GdCXtXaFMK`Yd>ye?5~XsREPUIr=AtoKH}&CQ~& z)p24z?ZC1eb>-Xb?^_wVlB*2?!DWE4AV%EO@;+;3)Oa5mWI3ToDahk^AT=oS8qC+0 zZE(`?c(D_Xl}m$;Rg|CtAejWAnfXgL>6CT=aE|M9eo^CwwsRMWafS+|XR%yOR7IC0 zjOqQ`*ABfJUzzxv9d((1GGF52v>Y9GFtK+e(Xv+sE1+Vse#1vJ``ZTn?P1cK?81F zof)d6M~!f>sZw3wD`0?@Oa5sR8ydB#q8Js%WNh%gOOmyp1AJ0{PdhFcODK9Ej;IVl z;1#!CmG#@M#m!7!c6eTAq$>ppzY^`={(F*KoQJGJoAhay4|;G{qFO?rA0U}{)R~|) zx=*6-qTLu7ysO@Vu|yGu*aw5Y$LxMY&_xqlb6#0QOvnN;g~3&IUCX0k8n^}!(!`-= zg<`G&PZCm{-dwW4{6{@j0N1pkiKc6BFSTY$f>GB+QBY6gYB)no&-bB();T2X0Xa$% Z_8E$|x@U1kuTPi)sr*+0A7~zz{ttLQH(&q& diff --git a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene/moltemplate_files/benzene.lt b/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene/moltemplate_files/benzene.lt deleted file mode 100644 index 1293cb1e4d..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene/moltemplate_files/benzene.lt +++ /dev/null @@ -1,45 +0,0 @@ -import "oplsaa.lt" - -# The "oplsaa.lt" file contains force-field definitions and masses for the -# atoms in your system. See oplsaa_lt_generator/README.TXT for details. - -# Note: -# Atom type @atom:90 corresponds to "Aromatic C" -# Atom type @atom:91 corresponds to "Aromatic H-C" - -Benzene inherits OPLSAA { - - write('Data Atoms') { - $atom:C1 $mol @atom:90 0.00 5.274 1.999 -8.568 # "Aromatic C" - $atom:C2 $mol @atom:90 0.00 6.627 2.018 -8.209 # "Aromatic C" - $atom:C3 $mol @atom:90 0.00 7.366 0.829 -8.202 # "Aromatic C" - $atom:C4 $mol @atom:90 0.00 6.752 -0.379 -8.554 # "Aromatic C" - $atom:C5 $mol @atom:90 0.00 5.399 -0.398 -8.912 # "Aromatic C" - $atom:C6 $mol @atom:90 0.00 4.660 0.791 -8.919 # "Aromatic C" - $atom:H11 $mol @atom:91 0.00 4.704 2.916 -8.573 # "Aromatic H-C" - $atom:H21 $mol @atom:91 0.00 7.101 2.950 -7.938 # "Aromatic H-C" - $atom:H31 $mol @atom:91 0.00 8.410 0.844 -7.926 # "Aromatic H-C" - $atom:H41 $mol @atom:91 0.00 7.322 -1.296 -8.548 # "Aromatic H-C" - $atom:H51 $mol @atom:91 0.00 4.925 -1.330 -9.183 # "Aromatic H-C" - $atom:H61 $mol @atom:91 0.00 3.616 0.776 -9.196 # "Aromatic H-C" - } - # Note: You don't have to specify the charge in this example because - # we are using the OPLSAA force-field assigns this by atom-type. - # Just leave these numbers as 0.00 for now. - - write('Data Bond List') { - $bond:C12 $atom:C1 $atom:C2 - $bond:C23 $atom:C2 $atom:C3 - $bond:C34 $atom:C3 $atom:C4 - $bond:C45 $atom:C4 $atom:C5 - $bond:C56 $atom:C5 $atom:C6 - $bond:C61 $atom:C6 $atom:C1 - $bond:C1H1 $atom:C1 $atom:H11 - $bond:C2H2 $atom:C2 $atom:H21 - $bond:C3H3 $atom:C3 $atom:H31 - $bond:C4H4 $atom:C4 $atom:H41 - $bond:C5H5 $atom:C5 $atom:H51 - $bond:C6H6 $atom:C6 $atom:H61 - } - -} # Benzene diff --git a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene/moltemplate_files/ethylene.lt b/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene/moltemplate_files/ethylene.lt deleted file mode 100644 index 626c731b02..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene/moltemplate_files/ethylene.lt +++ /dev/null @@ -1,43 +0,0 @@ -import "oplsaa.lt" - -# The "oplsaa.lt" file contains force-field definitions and masses for the -# atoms in your system. See oplsaa_lt_generator/README.TXT for details. - -# Note: -# Atom type 88 corresponds to "Alkene H2-C=" -# Atom type 89 corresponds to "Alkene H-C=" - - - -Ethylene inherits OPLSAA { - - # atom-id mol-id atom-type charge X Y Z - - write('Data Atoms') { - $atom:C1 $mol @atom:88 0.00 -0.6695 0.000000 0.000000 - $atom:C2 $mol @atom:88 0.00 0.6695 0.000000 0.000000 - $atom:H11 $mol @atom:89 0.00 -1.234217 -0.854458 0.000000 - $atom:H12 $mol @atom:89 0.00 -1.234217 0.854458 0.000000 - $atom:H21 $mol @atom:89 0.00 1.234217 -0.854458 0.000000 - $atom:H22 $mol @atom:89 0.00 1.234217 0.854458 0.000000 - } - # Note: You don't have to specify the charge in this example because - # we are using the OPLSAA force-field assigns this by atom-type. - # Just leave these numbers as 0.00 for now. - - write('Data Bond List') { - $bond:C12 $atom:C1 $atom:C2 - $bond:C1H1 $atom:C1 $atom:H11 - $bond:C1H2 $atom:C1 $atom:H12 - $bond:C2H1 $atom:C2 $atom:H21 - $bond:C2H2 $atom:C2 $atom:H22 - } - -} # Ethylene - - - -# Note: You don't need to supply the partial partial charges of the atoms. -# If you like, just fill the fourth column with zeros ("0.000"). -# Moltemplate and LAMMPS will automatically assign the charge later - diff --git a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene/moltemplate_files/oplsaa_lt_generator/AUTHOR.TXT b/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene/moltemplate_files/oplsaa_lt_generator/AUTHOR.TXT deleted file mode 100644 index d5e469af37..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene/moltemplate_files/oplsaa_lt_generator/AUTHOR.TXT +++ /dev/null @@ -1,3 +0,0 @@ - -OPLSAA force-field conversion tools provided by Jason Lambert. - diff --git a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene/moltemplate_files/oplsaa_lt_generator/README.TXT b/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene/moltemplate_files/oplsaa_lt_generator/README.TXT deleted file mode 100644 index 6da3456025..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene/moltemplate_files/oplsaa_lt_generator/README.TXT +++ /dev/null @@ -1,110 +0,0 @@ -This directory contains instructions for creating a a moltemplate file -("oplsaa.lt") containing force-field definitions relevant to the -"ethylene+benzene" example. (However, these instructions should work -for other molecules too.) - -First, check and see if there is an "oplsaa_subset.prm" file present. -If not, then download this file: - -http://dasher.wustl.edu/tinker/distribution/params/oplsaa.prm - This file is also available here: -http://dasher.wustl.edu/ffe/distribution/params/oplsaa.prm - -and save this file as "oplsaa_subset.prm". Then you must EDIT THIS FILE -so that it only contains atom types you plan to have in your simulation -(see below for details). Then run the opls_moltemplate.py script this way: - - -oplsaa_moltemplate.py oplsaa_subset.prm - - -This will create a file named "oplsaa.lt" -Look over the newly created "oplsaa.lt" file. -Then move this file to wherever you plan to run moltemplate. For example: - -mv -f oplsaa.lt .. - ------ DETAILS: Editing the "oplsaa_subset.prm" file ------- - -Again, before you run "oplsaa_moltemplate.py", you must edit the "oplsaa.prm" -file (or "oplsaa_subset.prm file) and eliminate atom types which do not -correspond to any of the atoms in your simulation. This means you must -look for lines near the beginning of this file which begin with the word "atom" -and refer to atom types which appear in the simulation you plan to run. All -other lines (beginning with the word "atom") must be deleted or commented out. -(Leave the rest of the file alone.) - -For example: -If you were working with ethylene and benzene you would delete every line -beginning with the word "atom", except for these four lines: - -# for ethylene: -atom 88 47 CM "Alkene H2-C=" 6 12.011 3 -atom 89 46 HC "Alkene H-C=" 1 1.008 1 -# for benzene: -atom 90 48 CA "Aromatic C" 6 12.011 3 -atom 91 49 HA "Aromatic H-C" 1 1.008 1 - -Then you are ready to run oplsaa_moltemplate.py on this file. - -(Note: Atom type numbers, like "88", "89", "47", etc... may vary depending on - when you downloaded "oplsaa.prm".) - - - ------ Using the "oplsaa.lt" file ----- - -Once you have created the "oplsaa.lt" file, you can create files (like -ethylene.lt) which define molecules that refer to these atom types. -Here is an excerpt from "ethyelene.lt": - -import "oplsaa.lt" -Ethylene inherits OPLSAA { - write('Data Atoms') { - list of atoms goes here ... - } - write('Data Bond List') { - list of bonds goes here ... - } -} - -And then run moltemplate. - - ------------ CHARGE: ----------- - -By default, the OPLSAA force-field assigns atom charge according to atom type. -When you run moltemplate, it will create a file named "system.in.charges", -containing commands like: - -set type 2 charge -0.42 -set type 3 charge 0.21 - -(This assumes your main moltemplate file is named "system.lt". If it was -named something else, eg "polymer.lt", then the file created by moltemplate -will be named "polymer.in.charges".) - -Include these commands somewhere in your LAMMPS input script -(or use the LAMMPS "include" command to load the commands in system.in.charges) - -Note that the atom numbers (eg "2", "3") in this file will not match the -OPLS atom numbers. (Check the output_ttree/ttree_assignments.txt file, -created by moltemplate, to see a table of "@atom" type numbers translated -from OPLSAA into LAMMPS.) - ------------ CREDIT ----------- - -If you use these tools and you publish a paper using OPLSAA, please also cite -the TINKER program. (Because these examples use the "oplsaa.prm" file which -is distributed with TINKER.) I think these are the relevant citations: - -1) Ponder, J. W., & Richards, F. M. (1987). "An efficient newtonâ€like method for molecular mechanics energy minimization of large molecules. Journal of Computational Chemistry", 8(7), 1016-1024. - -2) Ponder, J. W, (2004) "TINKER: Software tools for molecular design", http://dasher.wustl.edu/tinker/ - -------------------------------- - -Jason Lambert and Andrew Jewett -April, 2014 - -Please email bugs to jewett.aij@gmail.com and jlamber9@gmail.com diff --git a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene/moltemplate_files/oplsaa_lt_generator/minimal_versions/README.TXT b/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene/moltemplate_files/oplsaa_lt_generator/minimal_versions/README.TXT deleted file mode 100644 index 2fc1ea29ea..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene/moltemplate_files/oplsaa_lt_generator/minimal_versions/README.TXT +++ /dev/null @@ -1,16 +0,0 @@ -MOST USERS SHOULD IGNORE THIS DIRECTORY. - -This directory contains versions of the oplsaa_subset.prm file -which nearly all of the OPLSAA force-field information removed. -However for the "ethylene+benzene" example, all of the essential -parameters are contained in these files. You can use oplsaa_moltemplate.py -with either of these files and the physics should be the same. - -However there is no reason to do this. -When you download the "oplsaa.prm" file from: -http://dasher.wustl.edu/tinker/distribution/params/oplsaa.prm -(also http://dasher.wustl.edu/ffe/distribution/params/oplsaa.prm) -...just remove the lines beginning with "atom" for atoms you don't need. -You don't have to delete all the other irrelevant interactions. -(In fact, it is hard to do that without making a mistake. - I recommend that you leave the rest of the oplsaa.prm file alone.) diff --git a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene/moltemplate_files/oplsaa_lt_generator/minimal_versions/oplsaa_subset_minimal.prm b/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene/moltemplate_files/oplsaa_lt_generator/minimal_versions/oplsaa_subset_minimal.prm deleted file mode 100644 index b4078f1214..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene/moltemplate_files/oplsaa_lt_generator/minimal_versions/oplsaa_subset_minimal.prm +++ /dev/null @@ -1,37 +0,0 @@ - ############################# - ## Atom Type Definitions ## - ############################# - - -atom 88 47 CM "Alkene H2-C=" 6 12.011 3 -atom 89 46 HC "Alkene H-C=" 1 1.008 1 -atom 90 48 CA "Aromatic C" 6 12.011 3 -atom 91 49 HA "Aromatic H-C" 1 1.008 1 - -vdw 88 3.5500 0.0760 -vdw 89 2.4200 0.0300 -vdw 90 3.5500 0.0700 -vdw 91 2.4200 0.0300 - -bond 46 47 340.00 1.0800 -bond 47 47 549.00 1.3400 -bond 48 48 469.00 1.4000 -bond 48 49 367.00 1.0800 - -angle 46 47 46 35.00 117.00 -angle 46 47 47 35.00 120.00 -angle 48 48 48 63.00 120.00 -angle 48 48 49 35.00 120.00 - -torsion 46 47 47 46 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 48 48 48 48 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 49 48 48 49 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 48 48 48 49 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 - -imptors 0 0 47 0 30.000 180.0 2 -imptors 0 0 48 0 5.000 180.0 2 - -charge 88 -0.2300 -charge 89 0.1150 -charge 90 -0.1150 -charge 91 0.1150 diff --git a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene/moltemplate_files/oplsaa_lt_generator/minimal_versions/oplsaa_subset_simplified.prm b/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene/moltemplate_files/oplsaa_lt_generator/minimal_versions/oplsaa_subset_simplified.prm deleted file mode 100644 index 6dbc6861ac..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene/moltemplate_files/oplsaa_lt_generator/minimal_versions/oplsaa_subset_simplified.prm +++ /dev/null @@ -1,49 +0,0 @@ - ############################# - ## Atom Type Definitions ## - ############################# - -atom 88 47 CM "Alkene H2-C=" 6 12.011 3 -atom 89 46 HC "Alkene H-C=" 1 1.008 1 -atom 90 48 CA "Aromatic C" 6 12.011 3 -atom 91 49 HA "Aromatic H-C" 1 1.008 1 - -vdw 88 3.5500 0.0760 -vdw 89 2.4200 0.0300 -vdw 90 3.5500 0.0700 -vdw 91 2.4200 0.0300 - -bond 46 47 340.00 1.0800 -bond 47 47 549.00 1.3400 -bond 47 48 427.00 1.4330 -bond 48 48 469.00 1.4000 -bond 48 49 367.00 1.0800 - -angle 46 47 46 35.00 117.00 -angle 46 47 47 35.00 120.00 -angle 46 47 48 35.00 123.30 -angle 47 47 48 85.00 117.00 -angle 48 48 48 63.00 120.00 -angle 47 48 48 70.00 124.00 -angle 48 48 49 35.00 120.00 - -imptors 0 0 47 0 30.000 180.0 2 -imptors 0 0 48 0 5.000 180.0 2 - -torsion 47 46 47 46 0.000 0.0 1 -8.000 180.0 2 0.000 0.0 3 -torsion 0 47 47 0 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 46 47 47 46 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 46 47 47 48 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 46 47 48 48 0.000 0.0 1 0.000 180.0 2 -0.372 0.0 3 -torsion 47 47 48 48 1.241 0.0 1 3.353 180.0 2 -0.286 0.0 3 -torsion 0 48 48 0 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 0 48 48 48 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 0 48 48 49 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 47 48 48 49 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 48 48 48 48 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 48 48 48 49 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 49 48 48 49 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 - -charge 88 -0.2300 -charge 89 0.1150 -charge 90 -0.1150 -charge 91 0.1150 diff --git a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene/moltemplate_files/oplsaa_lt_generator/oplsaa_subset.prm b/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene/moltemplate_files/oplsaa_lt_generator/oplsaa_subset.prm deleted file mode 100644 index c802793ada..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene/moltemplate_files/oplsaa_lt_generator/oplsaa_subset.prm +++ /dev/null @@ -1,5129 +0,0 @@ -# This is a modified version of the file "oplsaa.prm" distributed with TINKER -# http://dasher.wustl.edu/tinker/distribution/params/oplsaa.prm -# In this version, all of the lines beginning with "atom" have been deleted -# except for the atom types we will be using in this simulation -# (I also deleted some other lines from that file data to reduce the file size, -# but doing that is not necessary.) -# -# If you use this file, please also cite the software this file comes from: -# -# Ponder, J. W., and Richards, F. M. J. Comput. Chem. (1987) 8(7), 1016-1024 -# "An efficient newtonâ€like method for molecular mechanics energy -# minimization of large molecules." -# -# Ponder, J. W, (2004) -# "TINKER: Software tools for molecular design" -# http://dasher.wustl.edu/tinker/ - - ############################## - ## ## - ## Force Field Definition ## - ## ## - ############################## - - -forcefield OPLS-AA - -vdwindex TYPE -vdwtype LENNARD-JONES -radiusrule GEOMETRIC -radiustype SIGMA -radiussize DIAMETER -epsilonrule GEOMETRIC -torsionunit 0.5 -imptorunit 0.5 -vdw-14-scale 2.0 -chg-14-scale 2.0 -electric 332.06 -dielectric 1.0 - - - ############################# - ## ## - ## Literature References ## - ## ## - ############################# - - -The parameters supplied with TINKER are from "OPLS All-Atom Parameters -for Organic Molecules, Ions, Peptides & Nucleic Acids, July 2008" as -provided by W. L. Jorgensen, Yale University during June 2009. These -parameters are taken from those distributed with BOSS Version 4.8. - -Note that "atom type" numbers and not "atom class" numbers are used -to index van der Waals parameters, see the "vdwindex" keyword above - -The atom types with (UA) in the description are "united atom" values, -ie, OPLS-UA, where any nonpolar hydrogen atoms are combined onto their -attached atoms. All other parameters are "all-atom", OPLS-AA, including -explicit hydrogen atoms. - - - ############################# - ## ## - ## Atom Type Definitions ## - ## ## - ############################# - - -atom 88 47 CM "Alkene H2-C=" 6 12.011 3 -atom 89 46 HC "Alkene H-C=" 1 1.008 1 -atom 90 48 CA "Aromatic C" 6 12.011 3 -atom 91 49 HA "Aromatic H-C" 1 1.008 1 - - - ################################ - ## ## - ## Van der Waals Parameters ## - ## ## - ################################ - - -vdw 1 2.9400 0.0610 -vdw 2 3.9050 0.1180 -vdw 3 3.7500 0.1050 -vdw 4 2.9600 0.2100 -vdw 5 3.0000 0.1700 -vdw 6 3.9100 0.1600 -vdw 7 0.0000 0.0000 -vdw 8 3.7300 0.2940 -vdw 9 3.7750 0.2070 -vdw 10 3.9050 0.1750 -vdw 11 3.9100 0.1600 -vdw 12 3.9600 0.1450 -vdw 13 3.9050 0.1180 -vdw 14 3.8500 0.1400 -vdw 15 3.8500 0.0800 -vdw 16 3.8000 0.1150 -vdw 17 3.7500 0.1100 -vdw 18 3.8000 0.0500 -vdw 19 3.7500 0.1050 -vdw 20 3.0700 0.1700 -vdw 21 0.0000 0.0000 -vdw 22 3.7750 0.2070 -vdw 23 3.9050 0.1180 -vdw 24 3.7000 0.2500 -vdw 25 3.5500 0.2500 -vdw 26 3.5500 0.2500 -vdw 27 3.5500 0.2500 -vdw 28 0.0000 0.0000 -vdw 29 0.0000 0.0000 -vdw 30 3.7750 0.2070 -vdw 31 3.9050 0.1180 -vdw 32 3.8000 0.1700 -vdw 33 3.8000 0.1180 -vdw 34 3.8000 0.1700 -vdw 35 3.8000 0.1180 -vdw 36 3.2000 0.1700 -vdw 37 3.6500 0.1500 -vdw 38 3.7750 0.2070 -vdw 39 3.8500 0.0800 -vdw 40 3.8000 0.0500 -vdw 41 3.0000 0.1700 -vdw 42 3.8000 0.1700 -vdw 43 3.8000 0.1180 -vdw 44 3.8000 0.1180 -vdw 45 3.4000 0.3000 -vdw 46 3.8000 0.0800 -vdw 47 3.4700 0.3000 -vdw 48 3.8000 0.0500 -vdw 49 3.4700 0.2660 -vdw 50 3.5600 0.3950 -vdw 51 2.9300 0.2800 -vdw 52 3.8100 0.1600 -vdw 53 2.9600 0.2100 -vdw 54 3.2500 0.1700 -vdw 55 3.8000 0.1150 -vdw 56 3.8000 0.1700 -vdw 57 0.0000 0.0000 -vdw 58 2.5560 0.0200 -vdw 59 2.7800 0.0690 -vdw 60 3.4010 0.2339 -vdw 61 3.6240 0.3170 -vdw 62 3.9350 0.4330 -vdw 63 3.15061 0.1521 -vdw 64 0.0000 0.0000 -vdw 65 3.15365 0.1550 -vdw 66 0.0000 0.0000 -vdw 67 0.0000 0.0000 -vdw 68 3.1760 0.1500 -vdw 69 0.0000 0.0000 -vdw 70 3.2700 0.1000 -vdw 71 0.0000 0.0000 -vdw 72 0.0000 0.0000 -vdw 73 3.1200 0.1600 -vdw 74 0.0000 0.0000 -vdw 75 0.0000 0.0000 -vdw 76 3.16557 0.1554 -vdw 77 0.0000 0.0000 -vdw 78 3.4200 0.1700 -vdw 79 0.0000 0.0000 -vdw 80 3.5000 0.0660 -vdw 81 3.5000 0.0660 -vdw 82 3.5000 0.0660 -vdw 83 3.5000 0.0660 -vdw 84 3.5000 0.0660 -vdw 85 2.5000 0.0300 -vdw 86 3.5500 0.0760 -vdw 87 3.5500 0.0760 -vdw 88 3.5500 0.0760 -vdw 89 2.4200 0.0300 -vdw 90 3.5500 0.0700 -vdw 91 2.4200 0.0300 -vdw 92 3.5500 0.0700 -vdw 93 3.5000 0.0660 -vdw 94 3.5000 0.0660 -vdw 95 3.5500 0.0760 -vdw 96 3.1200 0.1700 -vdw 97 0.0000 0.0000 -vdw 98 2.5000 0.0300 -vdw 99 3.5000 0.0660 -vdw 100 3.5000 0.0660 -vdw 101 3.5000 0.0660 -vdw 102 3.5000 0.0660 -vdw 103 3.2500 0.0620 -vdw 104 3.0700 0.1700 -vdw 105 0.0000 0.0000 -vdw 106 2.9400 0.0610 -vdw 107 2.5000 0.0300 -vdw 108 3.5500 0.0700 -vdw 109 3.0700 0.1700 -vdw 110 0.0000 0.0000 -vdw 111 3.0700 0.1700 -vdw 112 0.0000 0.0000 -vdw 113 3.0700 0.1700 -vdw 114 0.0000 0.0000 -vdw 115 3.5000 0.0660 -vdw 116 3.5000 0.0660 -vdw 117 3.5000 0.0660 -vdw 118 2.5000 0.0300 -vdw 119 2.9000 0.1400 -vdw 120 3.5500 0.0760 -vdw 121 2.9000 0.1400 -vdw 122 2.9000 0.1400 -vdw 123 3.5000 0.0660 -vdw 124 3.5000 0.0660 -vdw 125 3.5000 0.0660 -vdw 126 3.5000 0.0660 -vdw 127 2.5000 0.0300 -vdw 128 2.9000 0.1400 -vdw 129 3.0700 0.1700 -vdw 130 0.0000 0.0000 -vdw 131 3.5000 0.0660 -vdw 132 2.5000 0.0300 -vdw 133 3.5000 0.0660 -vdw 134 2.5000 0.0300 -vdw 135 3.5000 0.0660 -vdw 136 2.5000 0.0300 -vdw 137 3.5000 0.0660 -vdw 138 2.5000 0.0300 -vdw 139 3.5000 0.0660 -vdw 140 3.5000 0.0660 -vdw 141 3.5500 0.0700 -vdw 142 3.5500 0.2500 -vdw 143 3.7000 0.2500 -vdw 144 3.5500 0.2500 -vdw 145 3.5500 0.2500 -vdw 146 0.0000 0.0000 -vdw 147 0.0000 0.0000 -vdw 148 3.5000 0.0660 -vdw 149 3.5000 0.0660 -vdw 150 3.5000 0.0660 -vdw 151 3.5000 0.0660 -vdw 152 3.5000 0.0660 -vdw 153 3.5000 0.0660 -vdw 154 3.5000 0.0660 -vdw 155 3.5000 0.0660 -vdw 156 3.5000 0.0660 -vdw 157 3.5000 0.0660 -vdw 158 3.5000 0.0660 -vdw 159 3.5000 0.0660 -vdw 160 3.5000 0.0660 -vdw 161 3.5000 0.0660 -vdw 162 3.5000 0.0660 -vdw 163 3.5500 0.0700 -vdw 164 3.5500 0.2500 -vdw 165 3.5000 0.0660 -vdw 166 3.5000 0.0660 -vdw 167 3.5000 0.0660 -vdw 168 3.4000 0.3000 -vdw 169 3.5500 0.0760 -vdw 170 3.5500 0.0700 -vdw 171 3.5000 0.0660 -vdw 172 3.5000 0.0660 -vdw 173 3.7500 0.1050 -vdw 174 3.7500 0.1050 -vdw 175 3.7500 0.1050 -vdw 176 3.7500 0.1050 -vdw 177 3.7500 0.1050 -vdw 178 2.9600 0.2100 -vdw 179 3.2500 0.1700 -vdw 180 3.2500 0.1700 -vdw 181 3.2500 0.1700 -vdw 182 0.0000 0.0000 -vdw 183 0.0000 0.0000 -vdw 184 3.5000 0.0660 -vdw 185 3.5000 0.0660 -vdw 186 3.5000 0.0660 -vdw 187 3.5000 0.0660 -vdw 188 3.5000 0.0660 -vdw 189 3.7500 0.1050 -vdw 190 2.9600 0.2100 -vdw 191 3.2500 0.1700 -vdw 192 0.0000 0.0000 -vdw 193 3.2500 0.1700 -vdw 194 3.7500 0.1050 -vdw 195 2.9600 0.2100 -vdw 196 0.0000 0.0000 -vdw 197 2.5000 0.0200 -vdw 198 3.5000 0.0660 -vdw 199 3.5000 0.0660 -vdw 200 3.5000 0.0660 -vdw 201 3.5000 0.0660 -vdw 202 3.5500 0.0700 -vdw 203 3.6500 0.1500 -vdw 204 3.2000 0.1700 -vdw 205 3.5500 0.0700 -vdw 206 3.4000 0.3000 -vdw 207 3.2500 0.1700 -vdw 208 3.5500 0.0700 -vdw 209 3.7500 0.1050 -vdw 210 2.9600 0.2100 -vdw 211 3.0000 0.1700 -vdw 212 0.0000 0.0000 -vdw 213 3.7500 0.1050 -vdw 214 2.9600 0.2100 -vdw 215 3.5000 0.0660 -vdw 216 3.5000 0.0660 -vdw 217 3.5000 0.0660 -vdw 218 3.5000 0.0660 -vdw 219 3.7500 0.1050 -vdw 220 2.9600 0.2100 -vdw 221 2.4200 0.0150 -vdw 222 3.7500 0.1050 -vdw 223 2.9600 0.2100 -vdw 224 2.4200 0.0150 -vdw 225 3.5000 0.0660 -vdw 226 3.5000 0.0660 -vdw 227 3.5000 0.0660 -vdw 228 3.5000 0.0660 -vdw 229 3.2500 0.1700 -vdw 230 3.2500 0.1700 -vdw 231 3.2500 0.1700 -vdw 232 0.0000 0.0000 -vdw 233 0.0000 0.0000 -vdw 234 3.5000 0.0660 -vdw 235 3.5000 0.0660 -vdw 236 3.5000 0.0660 -vdw 237 3.5000 0.0660 -vdw 238 3.5000 0.0660 -vdw 239 3.5000 0.0660 -vdw 240 3.5000 0.0660 -vdw 241 3.5000 0.0660 -vdw 242 3.5000 0.0660 -vdw 243 3.2500 0.1700 -vdw 244 0.0000 0.0000 -vdw 245 3.5500 0.0500 -vdw 246 3.2500 0.1700 -vdw 247 0.0000 0.0000 -vdw 248 3.5000 0.0660 -vdw 249 3.5000 0.0660 -vdw 250 3.5000 0.0660 -vdw 251 3.5000 0.0660 -vdw 252 3.2500 0.1700 -vdw 253 0.0000 0.0000 -vdw 254 3.2500 0.1700 -vdw 255 3.5000 0.0800 -vdw 256 3.2500 0.1700 -vdw 257 0.0000 0.0000 -vdw 258 3.5000 0.0800 -vdw 259 2.5000 0.0500 -vdw 260 3.5000 0.0800 -vdw 261 2.5000 0.0500 -vdw 262 3.2500 0.1700 -vdw 263 3.7500 0.1050 -vdw 264 3.2500 0.1700 -vdw 265 3.7500 0.1050 -vdw 266 3.5000 0.0800 -vdw 267 3.5000 0.0800 -vdw 268 0.0000 0.0000 -vdw 269 2.9600 0.2100 -vdw 270 0.0000 0.0000 -vdw 271 2.9600 0.2100 -vdw 272 2.5000 0.0500 -vdw 273 2.5000 0.0500 -vdw 274 3.5000 0.0800 -vdw 275 2.5000 0.0500 -vdw 276 3.2500 0.1700 -vdw 277 3.7500 0.1050 -vdw 278 3.2500 0.1700 -vdw 279 3.5000 0.0800 -vdw 280 3.5000 0.0800 -vdw 281 3.5000 0.0800 -vdw 282 0.0000 0.0000 -vdw 283 2.9600 0.2100 -vdw 284 3.2500 0.1700 -vdw 285 0.0000 0.0000 -vdw 286 0.0000 0.0000 -vdw 287 2.5000 0.0500 -vdw 288 2.5000 0.0500 -vdw 289 3.2500 0.1700 -vdw 290 3.5000 0.0800 -vdw 291 3.2500 0.1700 -vdw 292 3.5000 0.0800 -vdw 293 3.5000 0.0800 -vdw 294 3.5000 0.0800 -vdw 295 3.2500 0.1700 -vdw 296 3.5000 0.0800 -vdw 297 3.2500 0.1700 -vdw 298 2.5000 0.0500 -vdw 299 3.2500 0.1700 -vdw 300 0.0000 0.0000 -vdw 301 0.0000 0.0000 -vdw 302 2.5000 0.0500 -vdw 303 0.0000 0.0000 -vdw 304 3.2500 0.1700 -vdw 305 3.5000 0.0800 -vdw 306 3.2500 0.1700 -vdw 307 3.5000 0.0800 -vdw 308 3.5000 0.0800 -vdw 309 3.7500 0.1050 -vdw 310 0.0000 0.0000 -vdw 311 3.2500 0.1700 -vdw 312 0.0000 0.0000 -vdw 313 2.9600 0.2100 -vdw 314 3.5000 0.0800 -vdw 315 2.5000 0.0500 -vdw 316 3.5000 0.0800 -vdw 317 2.5000 0.0500 -vdw 318 3.5000 0.0800 -vdw 319 2.5000 0.0500 -vdw 320 3.2500 0.1700 -vdw 321 3.7500 0.1050 -vdw 322 3.2500 0.1700 -vdw 323 3.5000 0.0800 -vdw 324 3.5000 0.0800 -vdw 325 3.5000 0.0800 -vdw 326 0.0000 0.0000 -vdw 327 2.9600 0.2100 -vdw 328 0.0000 0.0000 -vdw 329 3.2500 0.1700 -vdw 330 0.0000 0.0000 -vdw 331 0.0000 0.0000 -vdw 332 2.5000 0.0500 -vdw 333 2.5000 0.0500 -vdw 334 3.5000 0.0800 -vdw 335 2.5000 0.0500 -vdw 336 3.7400 0.2000 -vdw 337 2.9600 0.2100 -vdw 338 3.0000 0.1700 -vdw 339 3.5500 0.0660 -vdw 340 3.5000 0.0800 -vdw 341 3.4000 0.3000 -vdw 342 3.5500 0.0760 -vdw 343 3.0500 0.7100 -vdw 344 4.0200 0.7100 -vdw 345 4.2800 0.7100 -vdw 346 4.8100 0.7100 -vdw 347 5.3400 0.0005 -vdw 348 2.8700 0.0005 -vdw 349 4.0700 0.0005 -vdw 350 5.1700 0.0005 -vdw 351 5.6000 0.0005 -vdw 352 6.2000 0.0005 -vdw 353 1.644471 0.875044 -vdw 354 2.412031 0.449657 -vdw 355 3.102688 0.118226 -vdw 356 3.816610 0.047096 -vdw 357 4.2000 0.3000 -vdw 358 2.5000 0.0500 -vdw 359 4.2500 0.5000 -vdw 360 4.2000 0.3000 -vdw 361 2.5000 0.0500 -vdw 362 3.1500 0.2500 -vdw 363 4.2000 0.3000 -vdw 364 2.5000 0.0500 -vdw 365 3.6500 0.1500 -vdw 366 3.4000 0.2500 -vdw 367 4.2000 0.3000 -vdw 368 2.5000 0.0500 -vdw 369 3.4000 0.2500 -vdw 370 2.5000 0.0500 -vdw 371 4.2000 0.3000 -vdw 372 2.5000 0.0500 -vdw 373 4.2000 0.3000 -vdw 374 2.5000 0.0500 -vdw 375 0.0000 0.0000 -vdw 376 3.2000 0.2500 -vdw 377 0.0000 0.0000 -vdw 378 2.81524 0.4000 -vdw 379 3.11815 0.2000 -vdw 380 2.9000 0.1400 -vdw 381 3.7400 0.2000 -vdw 382 3.1500 0.2000 -vdw 383 2.9000 0.1400 -vdw 384 3.5000 0.0660 -vdw 385 2.5000 0.0300 -vdw 386 3.7400 0.2000 -vdw 387 3.1500 0.2000 -vdw 388 2.9000 0.1400 -vdw 389 3.5000 0.0660 -vdw 390 2.5000 0.0300 -vdw 391 3.7400 0.2000 -vdw 392 3.1500 0.2000 -vdw 393 2.9000 0.1400 -vdw 394 3.5000 0.0660 -vdw 395 2.5000 0.0300 -vdw 396 3.5000 0.0660 -vdw 397 2.5000 0.0300 -vdw 398 3.5500 0.0700 -vdw 399 3.5000 0.0660 -vdw 400 2.5000 0.0300 -vdw 401 3.5500 0.0700 -vdw 402 3.5000 0.0660 -vdw 403 2.5000 0.0300 -vdw 404 3.5500 0.0700 -vdw 405 3.5000 0.0660 -vdw 406 3.7500 0.1050 -vdw 407 2.9600 0.2100 -vdw 408 3.0000 0.1700 -vdw 409 3.5000 0.0660 -vdw 410 2.4200 0.0150 -vdw 411 3.7500 0.1050 -vdw 412 3.7500 0.1050 -vdw 413 3.5500 0.0700 -vdw 414 3.0000 0.1700 -vdw 415 3.5500 0.2500 -vdw 416 2.9600 0.1700 -vdw 417 3.5000 0.0660 -vdw 418 2.5000 0.0300 -vdw 419 3.2500 0.1700 -vdw 420 0.0000 0.0000 -vdw 421 3.2500 0.1700 -vdw 422 0.0000 0.0000 -vdw 423 3.5000 0.0660 -vdw 424 2.5000 0.0300 -vdw 425 3.5000 0.0660 -vdw 426 2.5000 0.0300 -vdw 427 3.5000 0.0660 -vdw 428 2.5000 0.0300 -vdw 429 3.5500 0.0700 -vdw 430 3.5500 0.0700 -vdw 431 3.5000 0.0660 -vdw 432 3.5000 0.0660 -vdw 433 3.5000 0.0660 -vdw 434 3.5500 0.2500 -vdw 435 2.9600 0.1700 -vdw 436 3.5600 0.3950 -vdw 437 3.5600 0.3950 -vdw 438 2.9300 0.2800 -vdw 439 3.5000 0.0660 -vdw 440 3.5000 0.0660 -vdw 441 3.5500 0.0700 -vdw 442 3.5500 0.0700 -vdw 443 3.5500 0.0700 -vdw 444 3.2500 0.1700 -vdw 445 0.0000 0.0000 -vdw 446 3.5000 0.0660 -vdw 447 3.5500 0.0700 -vdw 448 3.5500 0.0700 -vdw 449 3.5500 0.0700 -vdw 450 3.5500 0.0700 -vdw 451 3.5500 0.0700 -vdw 452 3.2500 0.1700 -vdw 453 3.2500 0.1700 -vdw 454 0.0000 0.0000 -vdw 455 3.5500 0.0700 -vdw 456 3.5000 0.0660 -vdw 457 3.5000 0.0660 -vdw 458 3.5500 0.0760 -vdw 459 3.5500 0.0760 -vdw 460 3.5500 0.0700 -vdw 461 3.2500 0.1700 -vdw 462 3.5500 0.0700 -vdw 463 3.5500 0.0700 -vdw 464 3.5500 0.0700 -vdw 465 2.4200 0.0300 -vdw 466 2.4200 0.0300 -vdw 467 2.4200 0.0300 -vdw 468 3.2500 0.1700 -vdw 469 3.5500 0.0700 -vdw 470 2.4200 0.0300 -vdw 471 3.2500 0.1700 -vdw 472 3.5500 0.0700 -vdw 473 3.5500 0.0700 -vdw 474 3.5500 0.0700 -vdw 475 2.4200 0.0300 -vdw 476 2.4200 0.0300 -vdw 477 2.4200 0.0300 -vdw 478 3.2500 0.1700 -vdw 479 3.5500 0.0700 -vdw 480 3.5500 0.0700 -vdw 481 2.4200 0.0300 -vdw 482 2.4200 0.0300 -vdw 483 3.2500 0.1700 -vdw 484 3.5500 0.0700 -vdw 485 3.5500 0.0700 -vdw 486 0.0000 0.0000 -vdw 487 2.4200 0.0300 -vdw 488 2.4200 0.0300 -vdw 489 3.2500 0.1700 -vdw 490 3.2500 0.1700 -vdw 491 3.5500 0.0700 -vdw 492 3.5500 0.0700 -vdw 493 3.5500 0.0700 -vdw 494 0.0000 0.0000 -vdw 495 2.4200 0.0300 -vdw 496 2.4200 0.0300 -vdw 497 2.4200 0.0300 -vdw 498 3.2500 0.1700 -vdw 499 3.5500 0.0700 -vdw 500 3.2500 0.1700 -vdw 501 3.5500 0.0700 -vdw 502 3.5500 0.0700 -vdw 503 0.0000 0.0000 -vdw 504 2.4200 0.0300 -vdw 505 2.4200 0.0300 -vdw 506 2.4200 0.0300 -vdw 507 2.9000 0.1400 -vdw 508 3.5500 0.0700 -vdw 509 3.5500 0.0760 -vdw 510 2.4200 0.0300 -vdw 511 2.4200 0.0300 -vdw 512 2.9000 0.1400 -vdw 513 3.5500 0.0700 -vdw 514 3.2500 0.1700 -vdw 515 3.5500 0.0700 -vdw 516 3.5500 0.0700 -vdw 517 2.4200 0.0300 -vdw 518 2.4200 0.0300 -vdw 519 2.4200 0.0300 -vdw 520 2.9000 0.1400 -vdw 521 3.2500 0.1700 -vdw 522 3.5500 0.0700 -vdw 523 3.5500 0.0700 -vdw 524 3.5500 0.0700 -vdw 525 2.4200 0.0300 -vdw 526 2.4200 0.0300 -vdw 527 2.4200 0.0300 -vdw 528 3.2500 0.1700 -vdw 529 3.5500 0.0700 -vdw 530 3.5500 0.0700 -vdw 531 3.5500 0.0700 -vdw 532 3.5500 0.0700 -vdw 533 3.5500 0.0700 -vdw 534 3.5500 0.0700 -vdw 535 3.5500 0.0700 -vdw 536 3.5500 0.0700 -vdw 537 0.0000 0.0000 -vdw 538 2.4200 0.0300 -vdw 539 2.4200 0.0300 -vdw 540 2.4200 0.0300 -vdw 541 2.4200 0.0300 -vdw 542 2.4200 0.0300 -vdw 543 2.4200 0.0300 -vdw 544 3.2500 0.1700 -vdw 545 3.5500 0.0700 -vdw 546 3.5500 0.0700 -vdw 547 3.5500 0.0700 -vdw 548 3.5500 0.0700 -vdw 549 3.5500 0.0700 -vdw 550 3.5500 0.0700 -vdw 551 3.5500 0.0700 -vdw 552 3.5500 0.0700 -vdw 553 3.5500 0.0700 -vdw 554 2.4200 0.0300 -vdw 555 2.4200 0.0300 -vdw 556 2.4200 0.0300 -vdw 557 2.4200 0.0300 -vdw 558 2.4200 0.0300 -vdw 559 2.4200 0.0300 -vdw 560 2.4200 0.0300 -vdw 561 3.2500 0.1700 -vdw 562 3.5500 0.0700 -vdw 563 3.2500 0.1700 -vdw 564 3.5500 0.0700 -vdw 565 3.5500 0.0700 -vdw 566 3.5500 0.0700 -vdw 567 3.2500 0.1700 -vdw 568 3.5500 0.0700 -vdw 569 3.2500 0.1700 -vdw 570 2.4200 0.0300 -vdw 571 2.4200 0.0300 -vdw 572 2.4200 0.0300 -vdw 573 0.0000 0.0000 -vdw 574 3.5500 0.2500 -vdw 575 3.5500 0.0700 -vdw 576 3.2500 0.1700 -vdw 577 3.5500 0.0700 -vdw 578 3.5500 0.0700 -vdw 579 2.4200 0.0300 -vdw 580 2.4200 0.0300 -vdw 581 2.4200 0.0300 -vdw 582 3.2500 0.1700 -vdw 583 3.5500 0.0700 -vdw 584 2.4200 0.0300 -vdw 585 3.5500 0.0700 -vdw 586 3.5000 0.0660 -vdw 587 3.2500 0.1700 -vdw 588 3.5500 0.0700 -vdw 589 3.5500 0.0700 -vdw 590 3.5500 0.0700 -vdw 591 3.5500 0.0700 -vdw 592 3.5500 0.0700 -vdw 593 3.5500 0.0700 -vdw 594 2.4200 0.0300 -vdw 595 2.4200 0.0300 -vdw 596 2.4200 0.0300 -vdw 597 2.4200 0.0300 -vdw 598 3.2500 0.1700 -vdw 599 3.5500 0.0700 -vdw 600 3.2500 0.1700 -vdw 601 3.5500 0.0700 -vdw 602 3.5500 0.0700 -vdw 603 3.5000 0.0660 -vdw 604 2.4200 0.0300 -vdw 605 2.4200 0.0300 -vdw 606 2.4200 0.0300 -vdw 607 2.5000 0.0300 -vdw 608 3.5000 0.0660 -vdw 609 3.5000 0.0660 -vdw 610 3.5000 0.0660 -vdw 611 3.5000 0.0660 -vdw 612 3.5000 0.0660 -vdw 613 3.5000 0.0660 -vdw 614 3.5000 0.0660 -vdw 615 3.5000 0.0660 -vdw 616 3.5000 0.0660 -vdw 617 3.5000 0.0660 -vdw 618 3.5000 0.0660 -vdw 619 3.5000 0.0660 -vdw 620 3.5000 0.0660 -vdw 621 3.5000 0.0660 -vdw 622 3.5000 0.0660 -vdw 623 3.5500 0.2500 -vdw 624 0.0000 0.0000 -vdw 625 3.5500 0.0700 -vdw 626 3.7500 0.1050 -vdw 627 3.2500 0.1700 -vdw 628 3.5000 0.0660 -vdw 629 3.5000 0.0660 -vdw 630 3.5000 0.0660 -vdw 631 3.5500 0.0700 -vdw 632 3.5500 0.0700 -vdw 633 3.5500 0.0700 -vdw 634 3.5500 0.0700 -vdw 635 3.5500 0.0700 -vdw 636 3.5500 0.0700 -vdw 637 3.5500 0.2500 -vdw 638 3.4730 0.0540 -vdw 639 3.3000 0.0500 -vdw 640 3.3000 0.0500 -vdw 641 3.5500 0.0760 -vdw 642 3.5000 0.0660 -vdw 643 2.5000 0.0300 -vdw 644 3.7500 0.0600 -vdw 645 3.4730 0.0540 -vdw 646 3.3000 0.0500 -vdw 647 3.3000 0.0500 -vdw 648 2.9500 0.0400 -vdw 649 3.5500 0.0760 -vdw 650 3.4000 0.3000 -vdw 651 2.4200 0.0300 -vdw 652 3.5000 0.0660 -vdw 653 3.5000 0.0660 -vdw 654 3.5000 0.0660 -vdw 655 3.5500 0.0700 -vdw 656 2.4200 0.0300 -vdw 657 3.5500 0.0700 -vdw 658 2.4200 0.0300 -vdw 659 3.5500 0.0700 -vdw 660 2.8500 0.0610 -vdw 661 3.5500 0.0700 -vdw 662 2.8500 0.0610 -vdw 663 3.4700 0.4700 -vdw 664 3.9050 0.1180 -vdw 665 3.5500 0.0700 -vdw 666 3.2500 0.0620 -vdw 667 2.9400 0.0610 -vdw 668 3.5500 0.0700 -vdw 669 2.8500 0.0610 -vdw 670 3.5500 0.0700 -vdw 671 3.4700 0.4700 -vdw 672 3.5500 0.0700 -vdw 673 3.7500 0.6000 -vdw 674 3.5000 0.0660 -vdw 675 3.5500 0.2500 -vdw 676 3.5500 0.0700 -vdw 677 3.5500 0.0700 -vdw 678 3.5500 0.0700 -vdw 679 3.5500 0.0700 -vdw 680 3.5500 0.0700 -vdw 681 2.4200 0.0300 -vdw 682 2.4200 0.0300 -vdw 683 3.5500 0.0500 -vdw 684 3.2500 0.1700 -vdw 685 0.0000 0.0000 -vdw 686 0.0000 0.0000 -vdw 687 2.4200 0.0300 -vdw 688 3.5000 0.0660 -vdw 689 3.5000 0.0660 -vdw 690 3.2500 0.1700 -vdw 691 3.2500 0.1700 -vdw 692 3.2500 0.1700 -vdw 693 3.5500 0.0500 -vdw 694 3.2000 0.1700 -vdw 695 3.3000 0.0660 -vdw 696 3.3000 0.0660 -vdw 697 3.3000 0.0660 -vdw 698 3.3000 0.0660 -vdw 699 3.3000 0.0660 -vdw 700 2.5000 0.0150 -vdw 701 3.2500 0.1200 -vdw 702 2.9600 0.1700 -vdw 703 3.5000 0.0660 -vdw 704 2.5000 0.0150 -vdw 705 3.5000 0.0660 -vdw 706 3.5000 0.0660 -vdw 707 3.5000 0.0660 -vdw 708 3.2500 0.1200 -vdw 709 3.5500 0.0700 -vdw 710 3.3000 0.0660 -vdw 711 3.2500 0.1700 -vdw 712 2.9600 0.2100 -vdw 713 3.7500 0.1050 -vdw 714 3.0000 0.1700 -vdw 715 3.5000 0.0660 -vdw 716 3.5000 0.0660 -vdw 717 3.5000 0.0660 -vdw 718 2.4200 0.0150 -vdw 719 2.4200 0.0150 -vdw 720 2.4200 0.0150 -vdw 721 2.9000 0.1400 -vdw 722 3.7400 0.2000 -vdw 723 3.5000 0.0660 -vdw 724 3.5000 0.0660 -vdw 725 2.5000 0.0300 -vdw 726 3.7400 0.2000 -vdw 727 3.1181 0.0610 -vdw 728 3.1500 0.1700 -vdw 729 2.8600 0.2100 -vdw 730 3.3000 0.1700 -vdw 731 3.3000 0.1700 -vdw 732 3.3000 0.1700 -vdw 733 3.5000 0.0660 -vdw 734 3.5000 0.0660 -vdw 735 3.5000 0.0660 -vdw 736 3.5000 0.0660 -vdw 737 3.5000 0.0660 -vdw 738 3.5000 0.0660 -vdw 739 0.0000 0.0000 -vdw 740 0.0000 0.0000 -vdw 741 2.5000 0.0150 -vdw 742 3.5000 0.0660 -vdw 743 3.5000 0.0660 -vdw 744 3.5000 0.0660 -vdw 745 3.5000 0.0660 -vdw 746 3.5500 0.0700 -vdw 747 3.5500 0.0700 -vdw 748 3.5500 0.0700 -vdw 749 3.5000 0.0660 -vdw 750 3.5000 0.0660 -vdw 751 3.5000 0.0660 -vdw 752 3.5000 0.0660 -vdw 753 3.5000 0.0660 -vdw 754 3.5000 0.0660 -vdw 755 3.3000 0.0860 -vdw 756 2.4200 0.0150 -vdw 757 3.3000 0.2100 -vdw 758 3.3000 0.1350 -vdw 759 3.3000 0.1000 -vdw 760 2.5000 0.0150 -vdw 761 3.5000 0.0660 -vdw 762 3.5000 0.0660 -vdw 763 3.5000 0.0660 -vdw 764 3.1200 0.1700 -vdw 765 0.0000 0.0000 -vdw 766 3.2500 0.1700 -vdw 767 3.2500 0.1700 -vdw 768 3.2500 0.1700 -vdw 769 3.3000 0.2100 -vdw 770 3.2500 0.1700 -vdw 771 0.0000 0.0000 -vdw 772 3.5000 0.0660 -vdw 773 3.5000 0.0660 -vdw 774 3.5000 0.0660 -vdw 775 3.5000 0.0660 -vdw 776 3.5500 0.0700 -vdw 777 3.5500 0.0760 -vdw 778 3.5500 0.0700 -vdw 779 3.5500 0.0700 -vdw 780 2.5000 0.0300 -vdw 781 3.5000 0.0660 -vdw 782 3.7500 0.1050 -vdw 783 3.2500 0.1700 -vdw 784 2.9600 0.2100 -vdw 785 0.0000 0.0000 -vdw 786 2.9400 0.0610 -vdw 787 3.5000 0.0660 -vdw 788 2.5000 0.0300 -vdw 789 3.5000 0.0660 -vdw 790 3.5000 0.0660 -vdw 791 3.5000 0.0660 -vdw 792 3.5000 0.0660 -vdw 793 3.5000 0.0660 -vdw 794 3.5000 0.0970 -vdw 795 2.9500 0.0530 -vdw 796 3.2500 0.0620 -vdw 797 2.5000 0.0300 -vdw 798 3.5000 0.0660 -vdw 799 3.5000 0.0660 -vdw 800 3.4000 0.3000 -vdw 801 3.5000 0.0660 -vdw 802 2.5000 0.0300 -vdw 803 3.5000 0.0660 -vdw 804 3.5000 0.0660 -vdw 805 3.4700 0.4700 -vdw 806 3.5000 0.0660 -vdw 807 2.5000 0.0300 -vdw 808 3.5000 0.0660 -vdw 809 3.5000 0.0660 -vdw 810 2.9400 0.0610 -vdw 811 3.4000 0.3000 -vdw 812 3.4700 0.4700 -vdw 813 3.5500 0.0700 -vdw 814 2.9000 0.1400 -vdw 815 3.5000 0.0660 -vdw 816 2.9000 0.0600 -vdw 817 3.2500 0.1700 -vdw 818 3.5500 0.0700 -vdw 819 3.5000 0.0660 -vdw 820 3.7500 0.1050 -vdw 821 3.7500 0.1050 -vdw 822 2.9600 0.2100 -vdw 823 3.2500 0.1700 -vdw 824 0.0000 0.0000 -vdw 825 3.1200 0.1700 -vdw 826 0.0000 0.0000 -vdw 827 3.5000 0.0660 -vdw 828 3.5000 0.0660 -vdw 829 3.5500 0.0700 -vdw 830 3.5500 0.0700 -vdw 831 3.5500 0.0700 -vdw 832 3.5500 0.0700 -vdw 833 3.5500 0.0700 -vdw 834 1.9600 0.0125 -vdw 835 3.5000 0.0660 -vdw 836 3.5000 0.0660 -vdw 837 3.5000 0.0660 -vdw 838 3.7500 0.6000 -vdw 839 2.5000 0.0300 -vdw 840 3.2500 0.1700 -vdw 841 3.5500 0.0700 -vdw 842 3.5500 0.0700 -vdw 843 3.2500 0.1700 -vdw 844 3.5500 0.0700 -vdw 845 3.7500 0.1050 -vdw 846 2.9600 0.2100 -vdw 847 3.2500 0.1700 -vdw 848 3.5000 0.0660 -vdw 849 3.5000 0.0660 -vdw 850 3.5000 0.0660 -vdw 851 3.5000 0.0660 -vdw 852 2.4200 0.0150 -vdw 853 3.7500 0.1050 -vdw 854 2.9600 0.2100 -vdw 855 2.4200 0.0150 -vdw 856 3.5000 0.0660 -vdw 857 3.5000 0.0660 -vdw 858 3.5000 0.0660 -vdw 859 3.5000 0.0660 -vdw 860 3.5000 0.0660 -vdw 861 3.5000 0.0660 -vdw 862 3.5000 0.0660 -vdw 863 3.5000 0.0660 -vdw 864 3.5000 0.0660 -vdw 865 3.5000 0.0660 -vdw 866 4.0000 0.1000 -vdw 867 4.0000 0.1000 -vdw 868 4.0000 0.1000 -vdw 869 4.0000 0.1000 -vdw 870 2.5000 0.0300 -vdw 871 3.5000 0.0660 -vdw 872 3.5000 0.0660 -vdw 873 3.5000 0.0660 -vdw 874 3.5000 0.0660 -vdw 875 3.0800 0.7200 -vdw 876 4.1800 0.11779 -vdw 877 4.5100 0.0900 -vdw 878 5.1500 0.0700 -vdw 879 2.7000 0.018279 -vdw 880 3.3500 0.002772 -vdw 881 4.0600 0.000328 -vdw 882 4.3200 0.000171 -vdw 883 4.8200 0.000081 -vdw 884 2.9100 0.875044 -vdw 885 3.4700 0.449657 -vdw 886 3.8200 0.118226 -vdw 887 4.1800 0.047096 -vdw 888 3.5000 0.0660 -vdw 889 3.5000 0.0660 -vdw 890 3.5000 0.0660 -vdw 891 3.5000 0.0660 -vdw 892 2.5000 0.0300 -vdw 893 3.2500 0.1700 -vdw 894 3.5500 0.0700 -vdw 895 3.2500 0.1700 -vdw 896 3.5500 0.0700 -vdw 897 3.5500 0.0760 -vdw 898 3.5500 0.0760 -vdw 899 2.4200 0.0300 -vdw 900 3.3000 0.0860 -vdw 901 3.3000 0.0860 -vdw 902 3.3000 0.0860 -vdw 903 3.3000 0.0860 -vdw 904 3.3000 0.0860 -vdw 905 2.9600 0.2100 -vdw 906 3.5000 0.0660 - - - ################################## - ## ## - ## Bond Stretching Parameters ## - ## ## - ################################## - - -bond 1 2 367.00 1.3800 -bond 1 3 420.00 1.3570 -bond 1 13 367.00 1.3600 -bond 1 19 450.00 1.2790 -bond 1 25 300.00 0.3000 -bond 1 47 420.00 1.3400 -bond 1 48 420.00 1.3540 -bond 1 82 420.00 1.3540 -bond 1 83 420.00 1.3540 -bond 1 84 420.00 1.3540 -bond 1 87 420.00 1.3540 -bond 1 88 420.00 1.3540 -bond 1 108 461.00 1.5700 -bond 2 2 260.00 1.5260 -bond 2 3 317.00 1.5220 -bond 2 5 386.00 1.4250 -bond 2 6 260.00 1.5260 -bond 2 10 260.00 1.5260 -bond 2 11 317.00 1.5000 -bond 2 12 317.00 1.5100 -bond 2 13 260.00 1.5260 -bond 2 14 317.00 1.5000 -bond 2 15 222.00 1.8100 -bond 2 16 222.00 1.8100 -bond 2 20 320.00 1.4250 -bond 2 24 337.00 1.4490 -bond 2 44 382.00 1.4480 -bond 2 48 317.00 1.5100 -bond 2 51 260.00 1.5260 -bond 2 53 367.00 1.4710 -bond 2 55 337.00 1.4630 -bond 2 80 317.00 1.4950 -bond 3 3 350.00 1.5100 -bond 3 4 570.00 1.2290 -bond 3 5 450.00 1.3640 -bond 3 6 317.00 1.5220 -bond 3 10 317.00 1.5220 -bond 3 12 469.00 1.4000 -bond 3 13 317.00 1.5220 -bond 3 19 400.00 1.4440 -bond 3 20 214.00 1.3270 -bond 3 21 300.00 1.7900 -bond 3 24 490.00 1.3350 -bond 3 44 317.00 1.5220 -bond 3 46 340.00 1.0900 -bond 3 47 410.00 1.4440 -bond 3 48 400.00 1.4900 -bond 3 50 385.00 1.4600 -bond 3 52 656.00 1.2500 -bond 3 56 457.00 1.3580 -bond 3 57 418.00 1.3880 -bond 3 60 447.00 1.4190 -bond 3 65 300.00 1.9800 -bond 3 84 400.00 1.4900 -bond 3 86 385.00 1.4600 -bond 3 105 424.00 1.3830 -bond 3 107 490.00 1.3350 -bond 4 25 553.00 0.3000 -bond 4 64 525.00 1.4800 -bond 4 89 570.00 1.2290 -bond 4 110 700.00 1.1710 -bond 5 6 386.00 1.4250 -bond 5 7 553.00 0.9450 -bond 5 10 386.00 1.4250 -bond 5 13 320.00 1.4100 -bond 5 20 250.00 1.4700 -bond 5 24 400.00 1.3800 -bond 5 25 340.00 0.3000 -bond 5 44 320.00 1.4500 -bond 5 47 450.00 1.3700 -bond 5 48 450.00 1.3640 -bond 5 51 320.00 1.3800 -bond 5 64 230.00 1.6100 -bond 5 79 450.00 1.6700 -bond 5 106 94.00 1.8000 -bond 5 108 374.00 1.6400 -bond 6 6 260.00 1.5260 -bond 6 10 260.00 1.5260 -bond 6 11 317.00 1.5000 -bond 6 13 260.00 1.5260 -bond 6 14 317.00 1.5000 -bond 6 15 222.00 1.8100 -bond 6 16 222.00 1.8100 -bond 6 20 320.00 1.4250 -bond 6 24 337.00 1.4490 -bond 6 44 382.00 1.4480 -bond 6 47 317.00 1.5100 -bond 6 51 260.00 1.5260 -bond 6 53 367.00 1.4710 -bond 6 55 337.00 1.4630 -bond 6 79 222.00 1.8100 -bond 6 105 337.00 1.4750 -bond 7 20 553.00 0.9450 -bond 7 25 340.00 0.1000 -bond 9 9 530.00 1.3400 -bond 9 11 530.00 1.3400 -bond 9 14 530.00 1.3400 -bond 10 10 260.00 1.5260 -bond 10 11 317.00 1.5000 -bond 10 14 317.00 1.5000 -bond 10 20 320.00 1.4250 -bond 10 24 337.00 1.4490 -bond 10 44 382.00 1.4480 -bond 10 105 337.00 1.4750 -bond 11 11 530.00 1.3400 -bond 11 13 317.00 1.5000 -bond 11 14 530.00 1.3400 -bond 11 79 222.00 1.7600 -bond 12 12 469.00 1.4000 -bond 12 48 469.00 1.4000 -bond 12 60 469.00 1.4000 -bond 12 81 469.00 1.4000 -bond 13 13 268.00 1.5290 -bond 13 14 317.00 1.5000 -bond 13 15 222.00 1.8100 -bond 13 16 222.00 1.8100 -bond 13 18 390.00 1.4300 -bond 13 19 390.00 1.4700 -bond 13 20 320.00 1.4100 -bond 13 21 245.00 1.7810 -bond 13 22 340.00 1.7900 -bond 13 24 337.00 1.4490 -bond 13 25 340.00 0.3000 -bond 13 44 382.00 1.4480 -bond 13 46 340.00 1.0900 -bond 13 47 317.00 1.5100 -bond 13 48 317.00 1.5100 -bond 13 50 317.00 1.5100 -bond 13 51 268.00 1.5290 -bond 13 53 367.00 1.4710 -bond 13 55 337.00 1.4630 -bond 13 56 337.00 1.4490 -bond 13 57 337.00 1.4750 -bond 13 60 317.00 1.5100 -bond 13 64 212.00 1.8430 -bond 13 65 245.00 1.9450 -bond 13 66 200.00 2.1900 -bond 13 79 340.00 1.7700 -bond 13 80 317.00 1.4950 -bond 13 83 317.00 1.5040 -bond 13 84 317.00 1.5040 -bond 13 85 317.00 1.5040 -bond 13 87 317.00 1.4950 -bond 13 90 337.00 1.4490 -bond 13 91 280.00 1.5100 -bond 13 95 532.80 1.4600 -bond 13 101 382.00 1.4480 -bond 13 102 375.00 1.4900 -bond 13 104 212.00 1.8200 -bond 13 105 337.00 1.4750 -bond 13 107 337.00 1.4490 -bond 13 108 187.00 1.8600 -bond 13 109 317.00 1.5100 -bond 14 14 530.00 1.3400 -bond 15 17 274.00 1.3360 -bond 15 48 250.00 1.7400 -bond 16 16 166.00 2.0380 -bond 16 19 300.00 1.6850 -bond 16 24 250.00 1.7300 -bond 16 25 340.00 0.5000 -bond 16 47 250.00 1.7600 -bond 16 48 250.00 1.7600 -bond 16 61 250.00 1.7300 -bond 16 82 250.00 1.7600 -bond 16 84 250.00 1.7400 -bond 16 91 222.00 1.8100 -bond 16 108 144.00 2.1500 -bond 17 25 340.00 0.1000 -bond 18 18 550.00 1.1200 -bond 18 19 650.00 1.1570 -bond 18 48 400.00 1.4100 -bond 18 56 550.00 1.2400 -bond 19 19 1150.00 1.2100 -bond 19 21 330.00 1.6370 -bond 19 46 420.00 1.0800 -bond 19 47 400.00 1.4260 -bond 19 48 400.00 1.4510 -bond 19 50 400.00 1.4260 -bond 19 65 330.00 1.7840 -bond 19 88 400.00 1.4510 -bond 19 91 400.00 1.4510 -bond 20 20 250.00 1.4700 -bond 20 21 200.00 1.6900 -bond 20 24 320.00 1.4500 -bond 20 25 340.00 0.3000 -bond 20 44 320.00 1.4500 -bond 20 47 450.00 1.3700 -bond 20 48 450.00 1.3640 -bond 20 51 320.00 1.3800 -bond 20 60 340.00 1.3600 -bond 20 61 462.00 1.3990 -bond 20 64 230.00 1.6100 -bond 20 82 462.00 1.3570 -bond 20 84 340.00 1.3600 -bond 20 108 374.00 1.6400 -bond 21 25 300.00 0.3000 -bond 21 47 300.00 1.7250 -bond 21 48 300.00 1.7250 -bond 21 82 300.00 1.7250 -bond 21 83 300.00 1.7250 -bond 21 84 300.00 1.7250 -bond 21 87 300.00 1.7250 -bond 21 88 300.00 1.7250 -bond 21 108 223.00 2.0200 -bond 22 23 700.00 1.5300 -bond 22 25 340.00 0.5000 -bond 23 25 340.00 0.3000 -bond 23 79 700.00 1.4400 -bond 24 25 367.00 0.3000 -bond 24 45 434.00 1.0100 -bond 24 48 427.00 1.3810 -bond 24 59 427.00 1.3810 -bond 24 79 434.00 1.6700 -bond 24 84 427.00 1.3810 -bond 24 88 427.00 1.3810 -bond 24 91 337.00 1.4490 -bond 24 103 500.00 1.2700 -bond 24 106 40.00 2.0500 -bond 25 25 340.00 0.3000 -bond 25 44 340.00 0.3000 -bond 25 45 340.00 0.1000 -bond 25 46 340.00 0.3000 -bond 25 47 340.00 0.3000 -bond 25 48 367.00 0.3000 -bond 25 49 340.00 0.3000 -bond 25 53 340.00 0.3000 -bond 25 56 367.00 0.3000 -bond 25 61 367.00 0.3000 -bond 25 65 300.00 0.3000 -bond 25 103 340.00 0.1000 -bond 31 32 600.00 0.9572 -bond 31 33 900.00 0.1500 -bond 31 106 40.00 2.0500 -bond 34 35 529.60 0.9572 -bond 36 37 600.00 0.9572 -bond 36 38 900.00 0.1750 -bond 39 40 600.00 0.9572 -bond 39 41 900.00 0.7000 -bond 42 43 600.00 1.0000 -bond 44 44 350.00 1.4450 -bond 44 45 434.00 1.0100 -bond 44 48 481.00 1.3400 -bond 44 79 340.00 1.7700 -bond 44 91 382.00 1.4480 -bond 44 108 266.00 1.7400 -bond 45 53 434.00 1.0100 -bond 45 55 434.00 1.0100 -bond 45 56 434.00 1.0100 -bond 45 57 434.00 1.0100 -bond 45 101 434.00 1.0100 -bond 45 105 434.00 1.0100 -bond 45 108 166.00 1.4800 -bond 46 47 340.00 1.0800 -bond 46 50 340.00 1.0800 -bond 46 51 340.00 1.0900 -bond 46 80 340.00 1.0800 -bond 46 91 340.00 1.0880 -bond 46 95 532.80 1.0840 -bond 46 108 166.00 1.4800 -bond 46 109 340.00 1.0800 -bond 47 47 549.00 1.3400 -bond 47 48 427.00 1.4330 -bond 47 50 549.00 1.3400 -bond 47 57 448.00 1.3650 -bond 47 58 367.00 1.0800 -bond 47 65 300.00 1.9000 -bond 47 66 250.00 2.0800 -bond 47 86 385.00 1.4600 -bond 47 91 317.00 1.5100 -bond 47 105 448.00 1.3650 -bond 47 110 700.00 1.3050 -bond 48 48 469.00 1.4000 -bond 48 49 367.00 1.0800 -bond 48 50 427.00 1.4330 -bond 48 53 400.00 1.4500 -bond 48 55 481.00 1.3400 -bond 48 56 483.00 1.3390 -bond 48 57 427.00 1.3810 -bond 48 60 469.00 1.4040 -bond 48 61 414.00 1.3910 -bond 48 64 220.00 1.7800 -bond 48 65 300.00 1.8700 -bond 48 66 250.00 2.0800 -bond 48 79 340.00 1.7700 -bond 48 81 469.00 1.4000 -bond 48 84 546.00 1.3670 -bond 48 86 469.00 1.4000 -bond 48 88 469.00 1.4210 -bond 48 91 317.00 1.4900 -bond 48 101 382.00 1.3850 -bond 48 102 400.00 1.4600 -bond 48 109 427.00 1.4330 -bond 49 59 367.00 1.0800 -bond 49 62 340.00 1.0800 -bond 49 82 367.00 1.0800 -bond 49 83 367.00 1.0800 -bond 49 84 367.00 1.0800 -bond 49 85 367.00 1.0800 -bond 49 87 367.00 1.0800 -bond 49 88 367.00 1.0800 -bond 50 50 385.00 1.4600 -bond 50 56 457.00 1.2900 -bond 50 84 549.00 1.3650 -bond 50 109 385.00 1.4600 -bond 51 105 337.00 1.4750 -bond 52 64 525.00 1.4800 -bond 53 54 434.00 1.0100 -bond 54 55 434.00 1.0100 -bond 55 59 481.00 1.3400 -bond 55 82 481.00 1.3400 -bond 56 56 500.00 1.3200 -bond 56 59 502.00 1.3240 -bond 56 60 461.00 1.3540 -bond 56 82 461.00 1.3540 -bond 56 86 483.00 1.3390 -bond 56 103 550.00 1.2100 -bond 56 109 457.00 1.2900 -bond 57 60 436.00 1.3740 -bond 57 61 400.00 1.3490 -bond 57 62 440.00 1.3710 -bond 57 81 428.00 1.3800 -bond 57 82 477.00 1.3430 -bond 57 84 427.00 1.3810 -bond 57 85 427.00 1.3810 -bond 57 86 385.00 1.4400 -bond 58 83 367.00 1.0800 -bond 58 84 367.00 1.0800 -bond 59 63 367.00 1.0800 -bond 60 60 520.00 1.3700 -bond 60 61 414.00 1.3910 -bond 60 80 388.00 1.4590 -bond 60 81 447.00 1.4190 -bond 60 87 469.00 1.4240 -bond 60 105 436.00 1.3740 -bond 61 61 400.00 1.2800 -bond 61 62 529.00 1.3040 -bond 61 82 488.00 1.3350 -bond 61 83 410.00 1.3940 -bond 61 84 410.00 1.3940 -bond 61 88 410.00 1.3200 -bond 62 63 367.00 1.0800 -bond 62 105 440.00 1.3710 -bond 63 82 367.00 1.0800 -bond 64 108 108.00 2.2500 -bond 65 82 300.00 1.8700 -bond 65 83 300.00 1.8700 -bond 65 84 300.00 1.8700 -bond 65 87 300.00 1.8700 -bond 65 88 300.00 1.8700 -bond 65 108 151.00 2.1900 -bond 66 82 250.00 2.0800 -bond 66 83 250.00 2.0800 -bond 66 84 250.00 2.0800 -bond 66 87 250.00 2.0800 -bond 66 88 250.00 2.0800 -bond 66 108 108.00 2.4400 -bond 77 78 500.00 1.8000 -bond 80 84 546.00 1.3520 -bond 82 86 385.00 1.4600 -bond 82 87 520.00 1.3700 -bond 83 84 520.00 1.3700 -bond 83 86 385.00 1.4600 -bond 84 84 512.00 1.3750 -bond 84 86 385.00 1.4600 -bond 84 87 546.00 1.3670 -bond 84 88 520.00 1.3700 -bond 85 85 520.00 1.3700 -bond 86 86 385.00 1.4600 -bond 86 87 385.00 1.4600 -bond 86 88 385.00 1.4600 -bond 87 87 469.00 1.4240 -bond 87 88 469.00 1.4240 -bond 89 90 490.00 1.3350 -bond 89 91 317.00 1.5220 -bond 90 91 337.00 1.4490 -bond 91 91 260.00 1.5200 -bond 102 103 550.00 1.2250 -bond 108 108 94.00 2.3200 -bond 109 109 549.00 1.3450 - - - ################################ - ## ## - ## Angle Bending Parameters ## - ## ## - ################################ - - -angle 25 1 25 33.00 109.47 -angle 1 2 2 50.00 109.50 -angle 2 2 2 63.00 112.40 -angle 2 2 3 63.00 112.40 -angle 2 2 5 80.00 109.50 -angle 2 2 6 63.00 112.40 -angle 6 2 6 63.00 112.40 -angle 5 2 6 80.00 109.50 -angle 2 2 10 63.00 112.40 -angle 3 2 10 63.00 112.40 -angle 6 2 10 63.00 112.40 -angle 10 2 10 63.00 112.40 -angle 5 2 10 80.00 109.50 -angle 10 2 12 63.00 114.00 -angle 6 2 13 63.00 112.40 -angle 10 2 15 50.00 108.60 -angle 2 2 16 50.00 114.70 -angle 10 2 16 50.00 114.70 -angle 2 2 20 80.00 109.50 -angle 6 2 20 80.00 109.50 -angle 10 2 20 80.00 109.50 -angle 3 2 24 80.00 110.30 -angle 2 2 24 80.00 111.20 -angle 2 2 44 56.20 109.47 -angle 6 2 44 56.20 109.47 -angle 10 2 44 56.20 109.47 -angle 13 2 44 56.20 109.47 -angle 3 2 44 80.00 111.20 -angle 2 2 48 63.00 112.40 -angle 10 2 48 63.00 114.00 -angle 2 2 51 63.00 112.40 -angle 6 2 51 63.00 112.40 -angle 2 2 53 80.00 111.20 -angle 2 2 55 80.00 111.20 -angle 10 2 80 63.00 115.60 -angle 2 3 4 80.00 120.40 -angle 1 3 4 80.00 121.00 -angle 3 3 4 80.00 121.40 -angle 4 3 4 80.00 126.00 -angle 4 3 5 80.00 121.00 -angle 4 3 6 80.00 120.40 -angle 5 3 10 70.00 115.00 -angle 4 3 10 80.00 120.40 -angle 5 3 12 70.00 120.00 -angle 12 3 12 85.00 120.00 -angle 5 3 13 70.00 108.00 -angle 13 3 13 70.00 116.00 -angle 1 3 13 80.00 111.00 -angle 3 3 13 80.00 117.20 -angle 4 3 13 80.00 120.40 -angle 10 3 20 81.00 111.40 -angle 13 3 20 81.00 111.40 -angle 4 3 20 83.00 123.40 -angle 13 3 21 75.00 109.00 -angle 4 3 21 75.00 119.00 -angle 24 3 24 70.00 114.20 -angle 2 3 24 70.00 116.60 -angle 3 3 24 70.00 116.60 -angle 6 3 24 70.00 116.60 -angle 10 3 24 70.00 116.60 -angle 13 3 24 70.00 116.60 -angle 4 3 24 80.00 122.90 -angle 20 3 24 81.00 111.40 -angle 13 3 44 70.00 116.00 -angle 4 3 44 80.00 120.40 -angle 13 3 46 35.00 115.00 -angle 46 3 46 35.00 115.00 -angle 4 3 46 35.00 123.00 -angle 24 3 46 40.00 114.00 -angle 5 3 46 40.00 115.00 -angle 20 3 46 40.00 115.00 -angle 24 3 47 70.00 115.50 -angle 4 3 47 80.00 125.30 -angle 46 3 48 35.00 115.00 -angle 24 3 48 70.00 115.50 -angle 13 3 48 70.00 116.00 -angle 5 3 48 70.00 120.00 -angle 4 3 48 80.00 120.40 -angle 20 3 48 81.00 111.40 -angle 48 3 48 85.00 120.00 -angle 13 3 50 70.00 116.00 -angle 46 3 50 80.00 116.00 -angle 4 3 50 80.00 124.00 -angle 10 3 52 65.00 117.00 -angle 2 3 52 70.00 117.00 -angle 6 3 52 70.00 117.00 -angle 13 3 52 70.00 117.00 -angle 48 3 52 70.00 117.00 -angle 4 3 52 80.00 126.00 -angle 52 3 52 80.00 126.00 -angle 46 3 56 35.00 116.00 -angle 46 3 56 35.00 122.00 -angle 4 3 56 80.00 122.50 -angle 47 3 57 70.00 114.10 -angle 56 3 57 70.00 118.60 -angle 57 3 57 70.00 118.60 -angle 4 3 57 80.00 120.60 -angle 24 3 60 70.00 111.30 -angle 57 3 60 70.00 111.30 -angle 4 3 60 80.00 128.80 -angle 13 3 65 75.00 109.00 -angle 4 3 65 75.00 119.00 -angle 44 3 84 70.00 116.00 -angle 4 3 84 80.00 120.40 -angle 4 3 87 80.00 128.20 -angle 57 3 105 70.00 115.40 -angle 56 3 105 70.00 118.60 -angle 4 3 105 80.00 120.90 -angle 13 3 107 70.00 116.60 -angle 4 3 107 80.00 122.90 -angle 25 4 25 10.00 117.00 -angle 3 4 25 35.00 113.00 -angle 3 5 7 35.00 113.00 -angle 2 5 7 55.00 108.50 -angle 6 5 7 55.00 108.50 -angle 7 5 10 55.00 108.50 -angle 7 5 13 55.00 108.50 -angle 7 5 24 49.00 105.40 -angle 25 5 25 5.00 109.47 -angle 7 5 25 10.00 109.47 -angle 13 5 25 10.00 109.47 -angle 7 5 47 35.00 109.00 -angle 25 5 48 10.00 109.47 -angle 7 5 48 35.00 113.00 -angle 7 5 51 55.00 108.50 -angle 7 5 64 55.00 108.50 -angle 13 5 64 100.00 120.50 -angle 7 5 79 74.00 110.00 -angle 7 5 106 100.00 126.00 -angle 5 7 25 10.00 109.47 -angle 25 7 25 33.00 109.47 -angle 2 10 2 63.00 112.40 -angle 2 10 3 63.00 111.10 -angle 2 10 5 80.00 109.50 -angle 3 10 6 63.00 111.10 -angle 6 10 6 63.00 111.50 -angle 2 10 6 63.00 112.40 -angle 5 10 6 80.00 109.50 -angle 3 10 10 63.00 111.10 -angle 2 10 10 63.00 111.50 -angle 6 10 10 63.00 111.50 -angle 10 10 10 63.00 111.50 -angle 5 10 10 80.00 109.50 -angle 2 10 20 80.00 109.50 -angle 6 10 20 80.00 109.50 -angle 10 10 20 80.00 109.50 -angle 3 10 24 63.00 110.10 -angle 6 10 24 80.00 109.50 -angle 2 10 24 80.00 109.70 -angle 10 10 24 80.00 109.70 -angle 2 10 44 56.20 109.47 -angle 6 10 44 56.20 109.47 -angle 10 10 44 56.20 109.47 -angle 13 10 44 56.20 109.47 -angle 3 10 44 80.00 109.70 -angle 2 10 48 63.00 112.40 -angle 20 10 48 80.00 109.50 -angle 2 10 105 80.00 109.50 -angle 10 10 105 80.00 109.50 -angle 20 10 105 80.00 109.50 -angle 2 11 2 70.00 124.00 -angle 2 11 6 70.00 124.00 -angle 6 11 6 70.00 124.00 -angle 2 11 9 70.00 118.00 -angle 6 11 9 70.00 118.00 -angle 9 11 10 70.00 118.00 -angle 2 11 10 70.00 124.00 -angle 6 11 10 70.00 124.00 -angle 10 11 10 70.00 124.00 -angle 2 11 11 70.00 118.00 -angle 6 11 11 70.00 118.00 -angle 9 11 11 70.00 118.00 -angle 10 11 11 70.00 118.00 -angle 11 11 11 70.00 118.00 -angle 9 11 13 70.00 118.00 -angle 11 11 13 70.00 118.00 -angle 2 11 13 70.00 124.00 -angle 6 11 13 70.00 124.00 -angle 10 11 13 70.00 124.00 -angle 13 11 13 70.00 124.00 -angle 9 11 14 70.00 118.00 -angle 11 11 14 70.00 118.00 -angle 9 11 79 70.00 118.00 -angle 2 12 12 70.00 120.00 -angle 3 12 12 85.00 120.00 -angle 12 12 12 85.00 120.00 -angle 12 12 48 85.00 120.00 -angle 12 12 60 85.00 120.00 -angle 12 12 81 85.00 120.00 -angle 1 13 1 77.00 109.10 -angle 2 13 2 40.00 109.50 -angle 1 13 3 50.00 109.50 -angle 2 13 3 63.00 111.10 -angle 3 13 3 63.00 111.10 -angle 2 13 6 40.00 109.50 -angle 6 13 6 40.00 109.50 -angle 3 13 6 63.00 109.50 -angle 1 13 13 50.00 109.50 -angle 5 13 13 50.00 109.50 -angle 13 13 13 58.35 112.70 -angle 3 13 13 63.00 111.10 -angle 13 13 15 50.00 108.60 -angle 13 13 16 50.00 114.70 -angle 13 13 19 58.35 112.70 -angle 3 13 20 50.00 109.50 -angle 13 13 20 50.00 109.50 -angle 3 13 21 69.00 109.80 -angle 13 13 21 69.00 109.80 -angle 21 13 21 78.00 111.70 -angle 13 13 22 50.00 108.60 -angle 20 13 24 50.00 109.50 -angle 3 13 24 63.00 110.10 -angle 2 13 24 80.00 109.70 -angle 13 13 24 80.00 109.70 -angle 16 13 44 50.00 114.70 -angle 2 13 44 56.20 109.47 -angle 6 13 44 56.20 109.47 -angle 10 13 44 56.20 109.47 -angle 13 13 44 56.20 109.47 -angle 3 13 44 80.00 111.20 -angle 46 13 46 33.00 107.80 -angle 18 13 46 35.00 108.50 -angle 19 13 46 35.00 108.50 -angle 2 13 46 35.00 109.50 -angle 3 13 46 35.00 109.50 -angle 5 13 46 35.00 109.50 -angle 15 13 46 35.00 109.50 -angle 16 13 46 35.00 109.50 -angle 20 13 46 35.00 109.50 -angle 22 13 46 35.00 109.50 -angle 24 13 46 35.00 109.50 -angle 44 13 46 35.00 109.50 -angle 13 13 46 37.50 110.70 -angle 1 13 46 40.00 107.00 -angle 21 13 46 51.00 107.60 -angle 46 13 47 35.00 109.50 -angle 1 13 47 50.00 109.50 -angle 13 13 47 63.00 111.10 -angle 47 13 47 63.00 112.40 -angle 46 13 48 35.00 109.50 -angle 47 13 48 40.00 109.50 -angle 48 13 48 40.00 109.50 -angle 1 13 48 50.00 109.50 -angle 5 13 48 50.00 109.50 -angle 20 13 48 50.00 109.50 -angle 16 13 48 50.00 114.70 -angle 3 13 48 63.00 112.00 -angle 2 13 48 63.00 114.00 -angle 13 13 48 63.00 114.00 -angle 44 13 48 80.00 111.20 -angle 46 13 50 35.00 109.50 -angle 46 13 51 37.50 110.70 -angle 5 13 51 50.00 109.50 -angle 13 13 51 58.35 112.70 -angle 46 13 53 35.00 109.50 -angle 3 13 53 80.00 111.20 -angle 13 13 53 80.00 111.20 -angle 46 13 55 35.00 109.50 -angle 13 13 55 80.00 111.20 -angle 46 13 56 35.00 109.50 -angle 3 13 56 63.00 110.10 -angle 13 13 56 65.00 109.00 -angle 46 13 57 35.00 109.50 -angle 48 13 57 80.00 111.20 -angle 46 13 60 35.00 109.50 -angle 13 13 60 63.00 114.00 -angle 46 13 64 41.00 109.50 -angle 13 13 64 43.00 109.50 -angle 48 13 64 43.00 109.50 -angle 46 13 65 51.00 107.60 -angle 3 13 65 69.00 109.80 -angle 13 13 65 69.00 110.00 -angle 48 13 65 69.00 110.00 -angle 65 13 65 78.00 111.70 -angle 46 13 66 75.00 111.00 -angle 13 13 66 75.00 112.00 -angle 46 13 79 35.00 109.50 -angle 13 13 79 50.00 108.60 -angle 1 13 79 50.00 109.50 -angle 46 13 80 35.00 109.50 -angle 13 13 80 63.00 115.60 -angle 46 13 83 35.00 109.50 -angle 13 13 83 63.00 114.00 -angle 46 13 84 35.00 109.50 -angle 16 13 84 50.00 114.70 -angle 13 13 84 63.00 114.00 -angle 46 13 85 35.00 109.50 -angle 13 13 85 63.00 114.00 -angle 46 13 87 35.00 109.50 -angle 13 13 87 63.00 115.60 -angle 46 13 90 35.00 109.50 -angle 13 13 90 80.00 110.00 -angle 3 13 90 80.00 113.00 -angle 46 13 91 37.50 110.70 -angle 46 13 95 35.00 105.00 -angle 13 13 95 63.00 105.00 -angle 46 13 101 35.00 109.50 -angle 13 13 101 80.00 111.20 -angle 46 13 102 35.00 105.00 -angle 13 13 102 63.00 111.10 -angle 46 13 104 41.00 109.50 -angle 13 13 104 43.00 109.50 -angle 46 13 105 35.00 109.50 -angle 13 13 105 50.00 109.50 -angle 20 13 105 50.00 109.50 -angle 46 13 107 35.00 109.50 -angle 13 13 107 80.00 109.70 -angle 46 13 108 35.00 109.50 -angle 13 13 108 60.00 112.00 -angle 2 14 2 70.00 124.00 -angle 2 14 6 70.00 124.00 -angle 6 14 6 70.00 124.00 -angle 2 14 9 70.00 118.00 -angle 6 14 9 70.00 118.00 -angle 9 14 10 70.00 118.00 -angle 2 14 10 70.00 124.00 -angle 6 14 10 70.00 124.00 -angle 10 14 10 70.00 124.00 -angle 2 14 11 70.00 118.00 -angle 6 14 11 70.00 118.00 -angle 9 14 11 70.00 118.00 -angle 10 14 11 70.00 118.00 -angle 11 14 11 70.00 118.00 -angle 9 14 13 70.00 118.00 -angle 11 14 13 70.00 118.00 -angle 2 14 13 70.00 124.00 -angle 6 14 13 70.00 124.00 -angle 10 14 13 70.00 124.00 -angle 13 14 13 70.00 124.00 -angle 2 14 14 70.00 118.00 -angle 6 14 14 70.00 118.00 -angle 9 14 14 70.00 118.00 -angle 10 14 14 70.00 118.00 -angle 11 14 14 70.00 118.00 -angle 13 14 14 70.00 118.00 -angle 14 14 14 70.00 118.00 -angle 17 15 17 35.00 92.07 -angle 2 15 17 44.00 96.00 -angle 6 15 17 44.00 96.00 -angle 13 15 17 44.00 96.00 -angle 25 15 25 5.00 109.47 -angle 13 15 25 10.00 109.47 -angle 33 15 33 10.00 160.00 -angle 2 15 33 150.00 96.70 -angle 6 15 33 150.00 96.70 -angle 13 15 33 150.00 96.70 -angle 17 15 33 150.00 96.70 -angle 17 15 48 50.00 96.00 -angle 2 16 6 62.00 98.90 -angle 13 16 13 62.00 98.90 -angle 2 16 16 68.00 103.70 -angle 6 16 16 68.00 103.70 -angle 13 16 16 68.00 103.70 -angle 13 16 19 65.00 100.00 -angle 25 16 25 5.00 109.47 -angle 13 16 25 10.00 109.47 -angle 33 16 33 10.00 160.00 -angle 2 16 33 150.00 96.70 -angle 6 16 33 150.00 96.70 -angle 13 16 33 150.00 96.70 -angle 16 16 33 150.00 96.70 -angle 13 16 48 62.00 104.20 -angle 47 16 48 62.00 104.20 -angle 24 16 60 74.00 92.40 -angle 25 16 61 10.00 130.00 -angle 25 16 82 10.00 130.00 -angle 60 16 82 74.00 97.00 -angle 25 16 84 10.00 130.00 -angle 82 16 84 74.00 90.00 -angle 60 16 84 74.00 97.00 -angle 84 16 84 74.00 97.00 -angle 13 16 91 62.00 94.00 -angle 15 17 25 10.00 109.47 -angle 25 17 25 33.00 109.47 -angle 13 18 19 150.00 180.00 -angle 19 18 48 170.00 180.00 -angle 18 18 56 100.00 180.00 -angle 13 19 18 150.00 180.00 -angle 16 19 19 140.00 180.00 -angle 13 19 19 150.00 180.00 -angle 18 19 25 10.00 90.00 -angle 19 19 46 112.00 180.00 -angle 18 19 47 150.00 180.00 -angle 19 19 47 160.00 180.00 -angle 18 19 48 150.00 180.00 -angle 19 19 48 160.00 180.00 -angle 19 19 50 160.00 180.00 -angle 18 19 55 150.00 180.00 -angle 18 19 88 150.00 180.00 -angle 2 20 2 100.00 111.80 -angle 2 20 3 83.00 116.90 -angle 3 20 6 83.00 116.90 -angle 2 20 6 100.00 111.80 -angle 2 20 7 55.00 108.50 -angle 7 20 10 55.00 108.50 -angle 3 20 10 83.00 116.90 -angle 10 20 10 100.00 111.80 -angle 13 20 13 60.00 109.50 -angle 3 20 13 83.00 116.90 -angle 25 20 25 5.00 109.47 -angle 13 20 25 10.00 109.47 -angle 13 20 47 75.00 111.00 -angle 25 20 48 10.00 109.47 -angle 13 20 48 75.00 111.00 -angle 47 20 48 75.00 111.00 -angle 48 20 48 75.00 111.00 -angle 3 20 48 83.00 116.90 -angle 2 20 48 100.00 111.80 -angle 13 20 51 60.00 109.50 -angle 2 20 51 100.00 113.00 -angle 6 20 51 100.00 113.00 -angle 10 20 51 100.00 113.00 -angle 24 20 60 70.00 104.50 -angle 25 20 61 10.00 125.00 -angle 2 20 64 100.00 120.50 -angle 6 20 64 100.00 120.50 -angle 10 20 64 100.00 120.50 -angle 13 20 64 100.00 120.50 -angle 48 20 64 100.00 120.50 -angle 64 20 64 100.00 120.50 -angle 25 20 82 10.00 125.00 -angle 60 20 82 70.00 106.50 -angle 82 20 82 70.00 107.00 -angle 25 20 84 10.00 125.00 -angle 82 20 84 70.00 104.00 -angle 60 20 84 70.00 106.50 -angle 84 20 84 70.00 106.50 -angle 61 20 84 70.00 108.90 -angle 108 20 108 20.00 145.00 -angle 13 20 108 40.00 130.00 -angle 25 21 25 33.00 109.47 -angle 13 22 13 62.00 96.00 -angle 13 22 23 74.00 107.00 -angle 23 22 25 10.00 90.00 -angle 2 24 3 50.00 121.90 -angle 3 24 3 70.00 126.40 -angle 3 24 5 46.00 115.70 -angle 2 24 6 50.00 121.90 -angle 3 24 6 50.00 121.90 -angle 2 24 10 50.00 118.00 -angle 3 24 10 50.00 121.90 -angle 13 24 13 50.00 118.00 -angle 3 24 13 50.00 121.90 -angle 3 24 16 70.00 112.00 -angle 3 24 20 70.00 108.60 -angle 3 24 25 10.00 109.50 -angle 25 24 45 10.00 100.00 -angle 5 24 45 35.00 110.20 -angle 3 24 45 35.00 119.80 -angle 45 24 45 35.00 120.00 -angle 2 24 45 38.00 118.40 -angle 6 24 45 38.00 118.40 -angle 10 24 45 38.00 118.40 -angle 13 24 45 38.00 118.40 -angle 45 24 48 35.00 119.80 -angle 13 24 48 50.00 118.00 -angle 3 24 48 50.00 121.90 -angle 48 24 48 70.00 118.00 -angle 54 24 54 35.00 120.00 -angle 45 24 59 35.00 118.00 -angle 3 24 59 70.00 125.20 -angle 13 24 79 50.00 120.00 -angle 45 24 79 100.00 111.00 -angle 45 24 84 35.00 119.80 -angle 48 24 84 70.00 118.00 -angle 16 24 86 70.00 117.00 -angle 45 24 87 35.00 119.80 -angle 48 24 87 70.00 118.00 -angle 45 24 88 35.00 119.80 -angle 48 24 88 70.00 118.00 -angle 45 24 91 40.00 113.00 -angle 3 24 91 55.00 128.00 -angle 48 24 103 70.00 121.00 -angle 3 24 106 20.00 126.00 -angle 25 25 25 33.00 109.47 -angle 32 31 32 75.00 104.52 -angle 32 31 33 50.00 52.26 -angle 35 34 35 34.05 104.52 -angle 37 36 37 75.00 109.50 -angle 37 36 38 50.00 54.75 -angle 40 39 40 75.00 104.52 -angle 41 39 41 50.00 109.47 -angle 40 39 41 50.00 110.6948 -angle 43 42 43 75.00 109.47 -angle 2 44 2 51.80 107.20 -angle 2 44 6 51.80 107.20 -angle 6 44 6 51.80 107.20 -angle 2 44 10 51.80 107.20 -angle 6 44 10 51.80 107.20 -angle 10 44 10 51.80 107.20 -angle 2 44 13 51.80 107.20 -angle 6 44 13 51.80 107.20 -angle 10 44 13 51.80 107.20 -angle 13 44 13 51.80 107.20 -angle 3 44 13 63.00 111.10 -angle 25 44 45 10.00 100.00 -angle 13 44 45 35.00 109.50 -angle 2 44 45 43.20 108.10 -angle 6 44 45 43.20 108.10 -angle 10 44 45 43.20 108.10 -angle 45 44 45 43.60 106.40 -angle 25 44 48 10.00 109.50 -angle 45 44 48 35.00 116.00 -angle 13 44 48 50.00 116.00 -angle 48 44 48 50.00 116.00 -angle 3 44 48 63.00 112.00 -angle 45 44 79 35.00 115.00 -angle 13 44 79 50.00 108.60 -angle 48 44 79 50.00 108.60 -angle 48 44 91 50.00 109.50 -angle 25 45 25 33.00 109.47 -angle 25 45 44 10.00 109.50 -angle 25 46 25 33.00 109.47 -angle 13 46 25 37.50 109.47 -angle 1 47 1 80.00 108.00 -angle 1 47 3 80.00 121.50 -angle 3 47 6 85.00 119.70 -angle 3 47 13 70.00 119.70 -angle 13 47 13 70.00 130.00 -angle 25 47 46 10.00 90.00 -angle 20 47 46 35.00 114.50 -angle 13 47 46 35.00 117.00 -angle 46 47 46 35.00 117.00 -angle 3 47 46 35.00 119.70 -angle 19 47 46 35.00 120.00 -angle 1 47 46 50.00 112.00 -angle 21 47 46 60.00 114.00 -angle 25 47 47 2.00 90.00 -angle 46 47 47 35.00 120.00 -angle 5 47 47 70.00 123.00 -angle 20 47 47 70.00 123.00 -angle 13 47 47 70.00 124.00 -angle 19 47 47 70.00 124.00 -angle 21 47 47 75.00 121.50 -angle 1 47 47 80.00 121.50 -angle 16 47 47 85.00 119.40 -angle 3 47 47 85.00 120.70 -angle 46 47 48 35.00 123.30 -angle 47 47 48 85.00 117.00 -angle 13 47 48 85.00 119.70 -angle 25 47 50 2.00 90.00 -angle 46 47 50 35.00 120.00 -angle 5 47 50 70.00 123.00 -angle 20 47 50 70.00 123.00 -angle 13 47 50 70.00 124.00 -angle 46 47 57 35.00 119.10 -angle 13 47 57 70.00 120.00 -angle 20 47 57 70.00 120.00 -angle 47 47 57 70.00 121.20 -angle 16 47 57 85.00 119.40 -angle 57 47 58 35.00 119.10 -angle 47 47 58 35.00 119.70 -angle 46 47 65 60.00 114.00 -angle 47 47 65 75.00 120.00 -angle 46 47 91 35.00 135.00 -angle 3 47 91 70.00 119.70 -angle 47 47 91 70.00 124.00 -angle 46 47 105 35.00 119.10 -angle 58 47 105 35.00 119.10 -angle 13 47 105 70.00 120.00 -angle 20 47 105 70.00 120.00 -angle 47 47 105 70.00 121.20 -angle 16 47 105 85.00 119.40 -angle 46 47 110 40.00 121.00 -angle 13 47 110 80.00 122.00 -angle 48 47 110 80.00 122.00 -angle 1 47 110 80.00 125.00 -angle 2 48 12 70.00 120.00 -angle 12 48 12 85.00 120.00 -angle 3 48 13 70.00 119.70 -angle 25 48 48 10.00 90.00 -angle 48 48 48 63.00 120.00 -angle 2 48 48 70.00 120.00 -angle 5 48 48 70.00 120.00 -angle 10 48 48 70.00 120.00 -angle 13 48 48 70.00 120.00 -angle 15 48 48 70.00 120.00 -angle 19 48 48 70.00 120.00 -angle 20 48 48 70.00 120.00 -angle 24 48 48 70.00 120.00 -angle 44 48 48 70.00 120.00 -angle 47 48 48 70.00 124.00 -angle 21 48 48 75.00 120.00 -angle 1 48 48 80.00 120.00 -angle 18 48 48 80.00 120.00 -angle 16 48 48 85.00 119.40 -angle 3 48 48 85.00 120.00 -angle 25 48 49 2.00 90.00 -angle 24 48 49 35.00 119.10 -angle 3 48 49 35.00 120.00 -angle 48 48 49 35.00 120.00 -angle 48 48 50 70.00 124.00 -angle 48 48 53 70.00 120.00 -angle 55 48 55 70.00 120.00 -angle 47 48 55 70.00 120.10 -angle 48 48 55 70.00 120.10 -angle 49 48 56 35.00 116.00 -angle 13 48 56 70.00 116.00 -angle 44 48 56 70.00 116.00 -angle 55 48 56 70.00 119.30 -angle 5 48 56 70.00 120.00 -angle 47 48 56 70.00 121.50 -angle 50 48 56 70.00 121.50 -angle 48 48 56 70.00 124.00 -angle 21 48 56 75.00 120.00 -angle 49 48 57 35.00 120.00 -angle 48 48 57 70.00 108.70 -angle 55 48 57 70.00 116.00 -angle 13 48 57 70.00 120.00 -angle 47 48 57 70.00 121.50 -angle 56 48 57 70.00 123.30 -angle 49 48 60 35.00 120.00 -angle 48 48 60 63.00 120.00 -angle 57 48 60 70.00 108.70 -angle 56 48 60 70.00 117.30 -angle 55 48 60 70.00 123.50 -angle 2 48 60 70.00 128.60 -angle 13 48 60 70.00 128.60 -angle 49 48 61 35.00 119.10 -angle 48 48 61 70.00 108.70 -angle 57 48 61 70.00 123.30 -angle 48 48 64 85.00 119.40 -angle 48 48 65 75.00 120.00 -angle 48 48 66 75.00 120.00 -angle 48 48 79 85.00 119.40 -angle 49 48 81 35.00 120.00 -angle 48 48 81 85.00 120.00 -angle 49 48 84 35.00 126.90 -angle 60 48 84 63.00 106.40 -angle 48 48 84 70.00 107.40 -angle 49 48 86 35.00 120.00 -angle 48 48 86 63.00 120.00 -angle 56 48 86 70.00 124.00 -angle 49 48 88 35.00 128.20 -angle 101 48 101 70.00 111.80 -angle 56 48 101 70.00 124.10 -angle 48 48 102 85.00 120.00 -angle 48 48 109 70.00 124.00 -angle 25 50 46 10.00 90.00 -angle 19 50 46 35.00 120.00 -angle 25 50 47 2.00 90.00 -angle 46 50 47 35.00 120.00 -angle 3 50 47 70.00 118.70 -angle 13 50 47 70.00 124.00 -angle 46 50 48 35.00 123.30 -angle 47 50 48 85.00 117.00 -angle 25 50 50 2.00 90.00 -angle 46 50 50 35.00 120.00 -angle 13 50 50 70.00 124.00 -angle 47 50 50 70.00 124.00 -angle 50 50 84 35.00 106.00 -angle 46 50 84 35.00 122.00 -angle 46 50 109 35.00 120.00 -angle 13 50 109 70.00 124.00 -angle 47 50 109 70.00 124.00 -angle 6 51 6 40.00 109.50 -angle 5 51 13 50.00 109.50 -angle 13 51 20 50.00 109.50 -angle 2 51 20 80.00 109.50 -angle 6 51 20 80.00 109.50 -angle 5 51 20 92.60 111.55 -angle 20 51 20 92.60 111.55 -angle 46 51 46 33.00 109.50 -angle 5 51 46 35.00 109.50 -angle 20 51 46 35.00 109.50 -angle 13 51 46 37.50 110.70 -angle 46 51 105 35.00 109.50 -angle 13 51 105 50.00 109.50 -angle 20 51 105 50.00 109.50 -angle 13 53 13 50.00 113.00 -angle 13 53 25 10.00 100.00 -angle 45 53 45 43.60 109.50 -angle 25 53 48 10.00 100.00 -angle 13 53 48 55.00 114.00 -angle 2 53 54 35.00 109.50 -angle 6 53 54 35.00 109.50 -angle 13 53 54 35.00 109.50 -angle 48 53 54 35.00 109.50 -angle 54 53 54 35.00 109.50 -angle 25 53 82 10.00 100.00 -angle 13 55 13 50.00 118.00 -angle 45 55 45 35.00 113.00 -angle 13 55 45 35.00 118.40 -angle 45 55 48 35.00 120.00 -angle 2 55 48 50.00 123.20 -angle 6 55 48 50.00 123.20 -angle 13 55 48 50.00 123.20 -angle 2 55 54 35.00 118.40 -angle 13 55 54 35.00 118.40 -angle 48 55 54 35.00 120.00 -angle 54 55 54 35.00 120.00 -angle 45 55 59 35.00 120.00 -angle 3 56 13 70.00 120.50 -angle 13 56 18 70.00 120.00 -angle 25 56 48 5.00 120.00 -angle 45 56 48 35.00 113.00 -angle 13 56 48 50.00 118.00 -angle 48 56 48 70.00 117.00 -angle 3 56 48 70.00 120.50 -angle 13 56 56 70.00 117.00 -angle 48 56 56 70.00 117.00 -angle 25 56 59 5.00 119.80 -angle 48 56 59 70.00 118.60 -angle 59 56 59 70.00 118.60 -angle 59 56 60 70.00 111.00 -angle 48 56 60 70.00 112.20 -angle 59 56 82 70.00 111.00 -angle 48 56 86 70.00 117.00 -angle 13 56 103 70.00 114.00 -angle 3 57 3 70.00 126.40 -angle 3 57 45 35.00 116.80 -angle 45 57 47 35.00 119.20 -angle 3 57 47 70.00 121.60 -angle 45 57 48 35.00 118.00 -angle 3 57 48 70.00 125.20 -angle 48 57 48 70.00 125.20 -angle 45 57 60 30.00 125.80 -angle 13 57 60 70.00 125.80 -angle 60 57 61 56.00 113.10 -angle 45 57 61 56.00 118.40 -angle 13 57 61 70.00 118.40 -angle 48 57 61 70.00 118.40 -angle 45 57 62 30.00 128.80 -angle 60 57 62 70.00 105.40 -angle 48 57 62 70.00 109.80 -angle 13 57 62 70.00 128.80 -angle 45 57 81 35.00 123.10 -angle 45 57 82 35.00 120.00 -angle 61 57 82 56.00 113.10 -angle 60 57 82 70.00 109.80 -angle 45 57 84 35.00 120.00 -angle 61 57 84 56.00 113.10 -angle 60 57 84 70.00 109.80 -angle 82 57 84 70.00 109.80 -angle 84 57 84 70.00 109.80 -angle 81 57 84 70.00 111.60 -angle 45 57 85 35.00 120.00 -angle 82 57 85 70.00 109.80 -angle 24 59 55 70.00 116.00 -angle 49 59 56 35.00 115.45 -angle 13 59 56 70.00 115.50 -angle 55 59 56 70.00 119.30 -angle 24 59 56 70.00 123.30 -angle 56 59 56 70.00 129.10 -angle 56 59 63 35.00 115.45 -angle 13 60 48 70.00 120.00 -angle 48 60 48 85.00 134.90 -angle 56 60 57 70.00 126.20 -angle 57 60 60 70.00 106.20 -angle 20 60 60 70.00 110.60 -angle 16 60 60 70.00 111.00 -angle 13 60 60 70.00 120.00 -angle 24 60 60 70.00 127.70 -angle 56 60 60 70.00 127.70 -angle 48 60 60 85.00 117.30 -angle 3 60 60 85.00 119.20 -angle 60 60 61 70.00 111.00 -angle 24 60 61 70.00 126.20 -angle 3 60 61 70.00 130.00 -angle 48 60 61 70.00 132.40 -angle 12 60 80 85.00 134.90 -angle 48 60 80 85.00 134.90 -angle 80 60 81 85.00 108.80 -angle 12 60 81 85.00 116.20 -angle 48 60 81 85.00 116.20 -angle 3 60 84 70.00 130.00 -angle 60 60 87 70.00 107.30 -angle 57 60 87 70.00 107.70 -angle 81 60 87 85.00 108.80 -angle 12 60 87 85.00 134.90 -angle 48 60 87 85.00 134.90 -angle 60 60 105 70.00 106.20 -angle 56 60 105 70.00 126.20 -angle 48 61 48 70.00 125.20 -angle 25 61 57 10.00 125.00 -angle 25 61 61 10.00 125.00 -angle 60 61 62 70.00 103.80 -angle 25 61 82 10.00 125.00 -angle 61 61 82 70.00 109.00 -angle 60 61 82 70.00 110.00 -angle 82 61 83 70.00 110.00 -angle 57 61 84 70.00 104.10 -angle 82 61 84 70.00 110.00 -angle 57 61 88 70.00 104.10 -angle 20 61 88 70.00 105.30 -angle 49 62 57 35.00 120.00 -angle 49 62 61 35.00 120.00 -angle 57 62 61 70.00 113.90 -angle 57 62 63 35.00 123.05 -angle 61 62 63 35.00 123.05 -angle 49 62 105 35.00 120.00 -angle 63 62 105 35.00 123.05 -angle 61 62 105 70.00 113.90 -angle 5 64 5 45.00 102.60 -angle 4 64 5 100.00 108.23 -angle 4 64 13 45.00 109.50 -angle 5 64 20 45.00 102.60 -angle 20 64 20 45.00 102.60 -angle 13 64 20 45.00 109.50 -angle 4 64 20 100.00 108.23 -angle 4 64 48 45.00 109.50 -angle 5 64 48 45.00 109.50 -angle 20 64 48 45.00 109.50 -angle 5 64 52 45.00 108.23 -angle 13 64 52 45.00 109.50 -angle 20 64 52 100.00 108.23 -angle 52 64 52 140.00 119.90 -angle 25 65 25 33.00 109.47 -angle 25 66 25 33.00 109.47 -angle 78 77 78 150.00 180.00 -angle 6 79 11 62.00 98.90 -angle 13 79 13 62.00 102.00 -angle 5 79 13 75.00 96.40 -angle 5 79 23 74.00 108.70 -angle 13 79 23 74.00 108.90 -angle 23 79 23 104.00 119.00 -angle 13 79 24 100.00 103.00 -angle 23 79 24 120.00 107.00 -angle 13 79 44 62.00 102.00 -angle 23 79 44 74.00 108.90 -angle 13 79 48 62.00 102.00 -angle 23 79 48 74.00 107.20 -angle 5 79 48 75.00 96.40 -angle 24 79 48 100.00 103.00 -angle 13 79 82 62.00 102.00 -angle 46 80 60 35.00 126.80 -angle 2 80 60 70.00 128.60 -angle 13 80 60 70.00 128.60 -angle 46 80 84 35.00 126.80 -angle 2 80 84 70.00 125.00 -angle 13 80 84 70.00 125.00 -angle 60 80 84 85.00 106.40 -angle 12 81 57 70.00 132.80 -angle 48 81 57 70.00 132.80 -angle 57 81 60 70.00 104.40 -angle 12 81 60 85.00 122.70 -angle 48 81 60 85.00 122.70 -angle 13 82 16 70.00 125.00 -angle 16 82 24 70.00 125.00 -angle 16 82 44 70.00 120.20 -angle 20 82 49 35.00 117.00 -angle 16 82 49 35.00 125.00 -angle 49 82 57 35.00 120.00 -angle 57 82 57 70.00 120.00 -angle 13 82 57 70.00 125.00 -angle 48 82 57 70.00 125.00 -angle 56 82 57 70.00 126.20 -angle 49 82 61 35.00 120.00 -angle 16 82 61 70.00 113.60 -angle 16 82 61 70.00 115.00 -angle 20 82 61 70.00 115.00 -angle 57 82 61 70.00 120.00 -angle 13 82 61 70.00 125.00 -angle 44 82 61 70.00 126.10 -angle 24 82 61 70.00 126.20 -angle 57 82 79 70.00 120.00 -angle 61 82 79 70.00 120.00 -angle 20 82 86 70.00 122.00 -angle 61 82 86 70.00 130.00 -angle 57 82 87 70.00 106.20 -angle 56 82 87 70.00 127.70 -angle 49 83 61 35.00 120.00 -angle 48 83 61 70.00 111.00 -angle 13 83 61 70.00 124.50 -angle 49 83 84 35.00 128.20 -angle 61 83 84 70.00 111.00 -angle 13 83 84 70.00 130.70 -angle 13 84 16 70.00 125.00 -angle 13 84 20 70.00 121.60 -angle 16 84 24 70.00 125.00 -angle 20 84 49 35.00 113.40 -angle 16 84 49 35.00 125.00 -angle 48 84 49 35.00 130.70 -angle 49 84 50 35.00 130.70 -angle 20 84 50 70.00 110.00 -angle 49 84 57 35.00 121.60 -angle 13 84 57 70.00 121.60 -angle 48 84 57 70.00 121.60 -angle 3 84 57 85.00 120.00 -angle 57 84 58 35.00 120.00 -angle 13 84 61 70.00 118.90 -angle 49 84 80 35.00 120.00 -angle 57 84 80 70.00 108.70 -angle 49 84 83 35.00 130.70 -angle 57 84 83 70.00 106.30 -angle 20 84 83 70.00 108.00 -angle 16 84 83 70.00 111.00 -angle 13 84 83 70.00 130.70 -angle 13 84 84 70.00 120.00 -angle 57 84 84 70.00 120.00 -angle 61 84 84 70.00 120.00 -angle 20 84 86 70.00 121.60 -angle 57 84 86 70.00 121.60 -angle 49 84 87 35.00 132.10 -angle 57 84 87 70.00 107.70 -angle 20 84 87 70.00 110.60 -angle 16 84 87 70.00 111.00 -angle 61 84 87 70.00 111.90 -angle 13 84 87 70.00 132.10 -angle 48 84 87 70.00 132.10 -angle 86 84 87 70.00 132.10 -angle 3 84 87 85.00 120.00 -angle 49 85 57 35.00 120.00 -angle 13 85 57 70.00 121.60 -angle 49 85 85 35.00 130.70 -angle 57 85 85 70.00 106.30 -angle 13 85 85 70.00 130.70 -angle 48 86 48 63.00 120.00 -angle 48 86 56 70.00 124.00 -angle 48 86 82 63.00 120.00 -angle 48 86 83 63.00 120.00 -angle 48 86 84 63.00 120.00 -angle 48 86 86 63.00 120.00 -angle 56 86 86 70.00 124.00 -angle 48 86 87 63.00 120.00 -angle 48 86 88 63.00 120.00 -angle 49 87 60 35.00 120.00 -angle 46 87 60 35.00 126.80 -angle 13 87 60 70.00 128.60 -angle 49 87 84 35.00 125.70 -angle 46 87 84 35.00 126.80 -angle 84 87 84 70.00 103.80 -angle 82 87 84 70.00 110.40 -angle 2 87 84 70.00 125.00 -angle 13 87 84 70.00 125.00 -angle 3 87 84 70.00 130.00 -angle 60 87 84 85.00 106.40 -angle 84 87 86 70.00 125.70 -angle 49 87 87 35.00 127.50 -angle 60 87 87 70.00 107.30 -angle 84 87 87 70.00 107.30 -angle 86 87 87 70.00 127.50 -angle 84 87 88 70.00 103.80 -angle 48 88 49 35.00 128.60 -angle 49 88 61 35.00 118.90 -angle 13 88 61 70.00 118.90 -angle 19 88 61 70.00 118.90 -angle 61 88 87 70.00 111.90 -angle 4 89 90 80.00 134.00 -angle 90 89 91 70.00 91.00 -angle 4 89 91 80.00 134.00 -angle 13 90 89 55.00 127.00 -angle 89 90 91 50.00 94.00 -angle 13 90 91 50.00 126.00 -angle 24 91 46 35.00 108.00 -angle 13 91 46 35.00 114.30 -angle 44 91 46 35.00 114.30 -angle 46 91 46 35.00 114.30 -angle 16 91 46 37.50 108.00 -angle 46 91 47 35.00 109.50 -angle 46 91 89 37.50 110.00 -angle 24 91 89 70.00 117.00 -angle 46 91 90 35.00 111.00 -angle 16 91 90 55.00 109.00 -angle 91 91 91 30.00 79.20 -angle 13 91 91 37.50 117.20 -angle 44 91 91 37.50 117.20 -angle 46 91 91 37.50 117.20 -angle 24 91 91 37.50 126.00 -angle 16 91 91 55.00 128.00 -angle 89 91 91 63.00 85.00 -angle 47 91 91 63.00 114.00 -angle 90 91 91 80.00 89.00 -angle 13 95 13 172.80 120.00 -angle 13 95 46 144.00 120.00 -angle 13 101 45 35.00 109.50 -angle 45 101 45 43.60 106.40 -angle 45 101 48 50.00 112.50 -angle 13 101 48 50.00 120.50 -angle 13 102 103 80.00 117.50 -angle 48 102 103 80.00 117.50 -angle 103 102 103 80.00 125.00 -angle 25 103 25 10.00 109.50 -angle 25 103 102 10.00 109.50 -angle 13 104 13 45.00 109.50 -angle 3 105 10 70.00 117.60 -angle 3 105 13 70.00 117.60 -angle 3 105 45 35.00 119.20 -angle 45 105 47 35.00 119.20 -angle 13 105 47 70.00 121.20 -angle 3 105 47 70.00 121.60 -angle 3 105 51 70.00 117.60 -angle 47 105 51 70.00 121.20 -angle 45 105 60 30.00 125.80 -angle 6 105 60 70.00 125.80 -angle 10 105 60 70.00 125.80 -angle 13 105 60 70.00 125.80 -angle 51 105 60 70.00 125.80 -angle 45 105 62 30.00 128.80 -angle 60 105 62 70.00 105.40 -angle 6 105 62 70.00 128.80 -angle 10 105 62 70.00 128.80 -angle 13 105 62 70.00 128.80 -angle 51 105 62 70.00 128.80 -angle 4 106 24 20.00 109.50 -angle 24 106 24 20.00 109.50 -angle 13 107 13 50.00 118.00 -angle 3 107 13 50.00 121.90 -angle 1 108 13 35.00 110.50 -angle 13 108 13 60.00 110.00 -angle 13 108 20 60.00 100.00 -angle 20 108 20 60.00 110.00 -angle 13 108 21 35.00 110.50 -angle 45 108 45 35.00 109.50 -angle 13 108 45 35.00 110.50 -angle 46 108 46 35.00 109.50 -angle 13 108 46 35.00 110.50 -angle 13 108 65 35.00 110.50 -angle 13 108 66 35.00 110.50 -angle 13 108 108 50.00 112.00 -angle 46 109 48 35.00 123.30 -angle 46 109 50 35.00 120.00 -angle 13 109 50 70.00 124.00 -angle 46 109 109 35.00 120.00 -angle 13 109 109 70.00 124.00 -angle 50 109 109 70.00 124.00 -angle 48 109 109 85.00 117.00 -angle 4 110 47 160.00 180.00 -angle 47 110 47 160.00 180.00 - - - ################################ - ## ## - ## Urey-Bradley Parameters ## - ## ## - ################################ - - -ureybrad 35 34 35 38.25 1.5537 - - - ##################################### - ## ## - ## Improper Torsional Parameters ## - ## ## - ##################################### - - -imptors 0 0 3 4 21.000 180.0 2 -imptors 0 0 3 52 21.000 180.0 2 -imptors 0 0 24 0 5.000 180.0 2 -imptors 0 0 47 0 30.000 180.0 2 -imptors 0 0 48 0 5.000 180.0 2 - - - ############################ - ## ## - ## Torsional Parameters ## - ## ## - ############################ - - - ################################################################### - ## ## - ## Alternative Torsional Parameter Values for Use with OPLS-AA ## - ## ## - ## For some torsions, OPLS-AA has multiple possible parameter ## - ## values; the list below shows functional groups for which ## - ## these alternate (commented) values should be preferred; the ## - ## values are in the same order as in the full parameter list ## - ## ## - ## 4 3 3 36 generic (default) ## - ## 4 3 3 36 dicarbonyls ## - ## 36 3 3 36 hydrocarbon (default) ## - ## 36 3 3 36 dicarbonyls ## - ## 13 3 5 7 carboxylic acid (default) ## - ## 13 3 5 7 1,2-diacid monoanion ## - ## 4 3 13 13 peptide (default) ## - ## 4 3 13 13 propanamide ## - ## 4 3 13 13 carboxylic acid ## - ## 4 3 13 13 dicarboxylic acid ## - ## 4 3 13 13 aldyhyde, ketone, acyl halide ## - ## 4 3 13 13 1,2-diacid monoanion ## - ## 5 3 13 13 carboxylic acid (default) ## - ## 5 3 13 13 dicarboxylic acid ## - ## 35 3 13 13 peptide psi' (default) ## - ## 35 3 13 13 propanamide ## - ## 35 3 13 13 beta-3-peptide, last psi ## - ## 4 3 29 13 esters (default) ## - ## 4 3 29 13 benzoic esters ## - ## 7 5 13 13 alcohols (default) ## - ## 7 5 13 13 trifluoroethanol ## - ## 7 5 13 13 hexopyranoses ## - ## 7 5 13 36 alcohols (default) ## - ## 7 5 13 36 axial cyclohexanol ## - ## 7 5 13 36 trifluoroethanol ## - ## 0 13 13 13 alcohols, ethers (default) ## - ## 0 13 13 13 hexopyranoses ## - ## 3 13 13 3 dicarboxylic acid (default) ## - ## 3 13 13 3 1,2-diacid monoanion ## - ## 3 13 13 13 butanamide (default) ## - ## 3 13 13 13 carboxylate ion ## - ## 3 13 13 13 aldyhyde, ketone, acyl halide ## - ## 3 13 13 36 all carbonyls (default) ## - ## 3 13 13 36 dicarboxylic acid ## - ## 3 13 13 36 aldehyde, ketone, acyl halide ## - ## 5 13 13 5 diols only (default) ## - ## 5 13 13 5 triols only ## - ## 5 13 13 5 hexopyranoses ## - ## 13 13 13 13 hydrocarbon (default) ## - ## 13 13 13 13 perfluoroalkane ## - ## 13 13 13 35 peptide chi-1 (default) ## - ## 13 13 13 35 N-propylformamide ## - ## 36 13 13 69 generic (default) ## - ## 36 13 13 69 sulfone ## - ## 13 13 33 13 amine (default) ## - ## 13 13 33 13 exocyclic amine ## - ## 13 13 33 13 exocyclic 1,4-diamine ## - ## 13 13 33 34 amine (default) ## - ## 13 13 33 34 azetidine, 4-ring ## - ## 13 13 33 34 pyrrolidine, 5-ring ## - ## 13 13 33 34 cyclic amine ## - ## 13 13 33 34 cyclic 1,4-diamine ## - ## 13 13 35 3 peptide phi' (default) ## - ## 13 13 35 3 N-ethylformamide ## - ## 13 13 35 3 beta-3-peptide, first theta tors ## - ## 13 13 35 13 proline, CD-N-CA-CB (default) ## - ## 13 13 35 13 proline, CG-CD-N-CA ## - ## 36 13 35 3 peptide phi'' (default) ## - ## 36 13 35 3 N-methylformamide ## - ## 13 13 47 0 imidazole, indole, purine (default) ## - ## 13 13 47 0 nucleoside chi ## - ## 13 13 47 52 nucleoside (default) ## - ## 13 13 47 52 imidazole, indole, purine ## - ## 29 13 47 0 imidazole, indole, purine (default) ## - ## 29 13 47 0 nucleoside chi ## - ## 29 13 95 52 nucleoside (default) ## - ## 29 13 95 52 imidazole, indole, purine ## - ## 13 13 97 13 generic (default) ## - ## 13 13 97 13 generic ## - ## 17 15 38 0 aromatic thiol (default) ## - ## 17 15 38 0 aromatic thiol, N-C-S-H ## - ## 13 29 54 42 phosphonates (default) ## - ## 13 29 54 42 dimethyl phosphate ## - ## 34 35 72 16 diaryl amine (default) ## - ## 34 35 72 16 aniline-like ## - ## 34 35 72 29 diaryl amine (default) ## - ## 34 35 72 29 aniline-like ## - ## 13 40 40 37 diene (default) ## - ## 13 40 40 37 2-methyl-1,3-butadiene ## - ## 0 46 72 0 generic (default) ## - ## 0 46 72 0 generic ## - ## 0 47 72 0 generic (default) ## - ## 0 47 72 0 generic ## - ## 0 47 74 0 generic (default) ## - ## 0 47 74 0 generic ## - ## 0 47 74 0 generic ## - ## 0 51 72 0 generic (default) ## - ## 0 51 72 0 HA-CR-NB-?? or N?-CR-NB-?? ## - ## 0 72 77 0 generic (default) ## - ## 0 72 77 0 biphenyl-like, N-C-C-C ## - ## ## - ################################################################### - - -torsion 0 2 2 2 -2.500 0.0 1 1.250 180.0 2 3.100 0.0 3 -torsion 0 2 2 6 -2.500 0.0 1 1.250 180.0 2 3.100 0.0 3 -torsion 1 2 2 2 -2.000 0.0 1 0.700 180.0 2 3.000 0.0 3 -torsion 1 2 2 6 -2.000 0.0 1 0.700 180.0 2 3.000 0.0 3 -torsion 2 2 2 2 -3.400 0.0 1 1.250 180.0 2 3.100 0.0 3 -torsion 2 2 2 6 -3.400 0.0 1 1.250 180.0 2 3.100 0.0 3 -torsion 2 2 2 10 -3.400 0.0 1 1.250 180.0 2 3.100 0.0 3 -torsion 2 2 2 13 -3.400 0.0 1 1.250 180.0 2 3.100 0.0 3 -torsion 2 2 2 65 -2.000 0.0 1 0.500 180.0 2 3.250 0.0 3 -torsion 6 2 2 6 -3.400 0.0 1 1.250 180.0 2 3.100 0.0 3 -torsion 6 2 2 65 -2.000 0.0 1 0.500 180.0 2 3.250 0.0 3 -torsion 10 2 2 10 -3.400 0.0 1 1.250 180.0 2 3.100 0.0 3 -torsion 2 2 5 7 0.300 0.0 1 0.000 180.0 2 1.300 0.0 3 -torsion 6 2 5 7 0.300 0.0 1 0.000 180.0 2 1.300 0.0 3 -torsion 10 2 5 7 0.300 0.0 1 0.000 180.0 2 1.300 0.0 3 -torsion 0 2 10 2 -2.500 0.0 1 1.250 180.0 2 3.100 0.0 3 -torsion 2 2 10 2 -3.400 0.0 1 1.250 180.0 2 3.100 0.0 3 -torsion 2 2 13 2 -3.400 0.0 1 1.250 180.0 2 3.100 0.0 3 -torsion 6 2 20 2 -7.400 0.0 1 3.000 180.0 2 1.800 0.0 3 -torsion 6 2 20 6 -8.400 0.0 1 3.000 180.0 2 1.800 0.0 3 -torsion 4 3 3 4 1.600 0.0 1 3.200 180.0 2 0.000 0.0 3 -torsion 4 3 3 13 0.000 0.0 1 0.500 180.0 2 0.000 0.0 3 -torsion 4 3 3 24 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 4 3 3 46 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -#torsion 4 3 3 36 0.000 0.0 1 0.200 180.0 2 0.000 0.0 3 -torsion 13 3 3 13 0.700 0.0 1 -1.500 180.0 2 0.000 0.0 3 -torsion 13 3 3 24 -0.500 0.0 1 0.200 180.0 2 0.000 0.0 3 -torsion 13 3 3 46 0.800 0.0 1 -0.760 180.0 2 0.000 0.0 3 -torsion 24 3 3 46 -0.900 0.0 1 0.300 180.0 2 0.000 0.0 3 -torsion 46 3 3 46 0.000 0.0 1 0.000 180.0 2 0.300 0.0 3 -#torsion 36 3 3 36 0.800 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 3 3 5 7 3.000 0.0 1 5.500 180.0 2 0.000 0.0 3 -torsion 4 3 5 7 0.000 0.0 1 5.000 180.0 2 0.000 0.0 3 -torsion 13 3 5 7 1.500 0.0 1 5.500 180.0 2 0.000 0.0 3 -#torsion 13 3 5 7 3.200 0.0 1 4.900 180.0 2 0.000 0.0 3 -torsion 24 3 5 7 -2.000 0.0 1 5.000 180.0 2 0.000 0.0 3 -torsion 46 3 5 7 1.500 0.0 1 5.500 180.0 2 0.000 0.0 3 -torsion 48 3 5 7 4.000 0.0 1 5.000 180.0 2 0.000 0.0 3 -torsion 1 3 13 13 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 1 3 13 46 0.000 0.0 1 0.000 180.0 2 0.360 0.0 3 -torsion 3 3 13 46 0.000 0.0 1 0.000 180.0 2 0.085 0.0 3 -torsion 4 3 13 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 4 3 13 13 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -#torsion 4 3 13 13 0.000 0.0 1 1.166 180.0 2 0.000 0.0 3 -#torsion 4 3 13 13 0.000 0.0 1 0.546 180.0 2 0.000 0.0 3 -#torsion 4 3 13 13 -0.750 0.0 1 -0.550 180.0 2 -0.250 0.0 3 -#torsion 4 3 13 13 -0.277 0.0 1 1.228 180.0 2 -0.694 0.0 3 -#torsion 4 3 13 13 -1.000 0.0 1 -1.900 180.0 2 -0.900 0.0 3 -torsion 4 3 13 21 -0.650 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 4 3 13 44 0.000 0.0 1 0.820 180.0 2 0.000 0.0 3 -torsion 4 3 13 24 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 4 3 13 46 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 4 3 13 48 0.000 0.0 1 0.546 180.0 2 0.000 0.0 3 -torsion 5 3 13 13 0.000 0.0 1 1.412 180.0 2 0.000 0.0 3 -#torsion 5 3 13 13 1.000 0.0 1 0.546 180.0 2 0.450 0.0 3 -torsion 5 3 13 44 5.260 0.0 1 0.820 180.0 2 0.000 0.0 3 -torsion 5 3 13 46 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 3 13 13 1.454 0.0 1 -0.144 180.0 2 -0.775 0.0 3 -torsion 13 3 13 46 0.000 0.0 1 0.000 180.0 2 0.275 0.0 3 -torsion 20 3 13 13 0.000 0.0 1 0.000 180.0 2 -0.553 0.0 3 -torsion 20 3 13 46 0.000 0.0 1 0.000 180.0 2 0.132 0.0 3 -torsion 21 3 13 13 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 21 3 13 46 0.000 0.0 1 0.000 180.0 2 0.360 0.0 3 -torsion 24 3 13 13 1.173 0.0 1 0.189 180.0 2 -1.200 0.0 3 -#torsion 35 3 13 13 3.250 0.0 1 -0.402 180.0 2 -0.136 0.0 3 -#torsion 35 3 13 13 3.260 0.0 1 0.440 180.0 2 0.600 0.0 3 -torsion 24 3 13 21 0.650 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 24 3 13 24 1.816 0.0 1 1.222 180.0 2 1.581 0.0 3 -torsion 24 3 13 46 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 46 3 13 13 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 46 3 13 46 0.000 0.0 1 0.000 180.0 2 0.360 0.0 3 -torsion 48 3 13 46 0.000 0.0 1 0.000 180.0 2 0.275 0.0 3 -torsion 52 3 13 13 0.000 0.0 1 0.820 180.0 2 0.000 0.0 3 -torsion 52 3 13 44 0.000 0.0 1 0.820 180.0 2 0.000 0.0 3 -torsion 52 3 13 46 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 65 3 13 13 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 65 3 13 46 0.000 0.0 1 0.000 180.0 2 0.360 0.0 3 -torsion 107 3 13 46 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 4 3 20 13 0.000 0.0 1 5.124 180.0 2 0.000 0.0 3 -#torsion 4 3 29 13 0.000 0.0 1 5.000 180.0 2 0.000 0.0 3 -torsion 4 3 20 48 0.000 0.0 1 5.000 180.0 2 0.000 0.0 3 -torsion 13 3 20 13 4.669 0.0 1 5.124 180.0 2 0.000 0.0 3 -torsion 13 3 20 48 1.500 0.0 1 5.000 180.0 2 0.000 0.0 3 -torsion 24 3 20 13 -2.000 0.0 1 5.000 180.0 2 0.000 0.0 3 -torsion 46 3 20 13 4.669 0.0 1 5.124 180.0 2 0.000 0.0 3 -torsion 48 3 20 13 4.000 0.0 1 5.000 180.0 2 0.000 0.0 3 -torsion 3 3 24 13 0.400 0.0 1 4.900 180.0 2 0.000 0.0 3 -torsion 3 3 24 45 0.000 0.0 1 4.900 180.0 2 0.000 0.0 3 -torsion 4 3 24 5 0.000 0.0 1 6.603 180.0 2 0.000 0.0 3 -torsion 4 3 24 13 0.000 0.0 1 6.089 180.0 2 0.000 0.0 3 -torsion 4 3 24 45 0.000 0.0 1 4.900 180.0 2 0.000 0.0 3 -torsion 4 3 24 47 0.000 0.0 1 6.089 180.0 2 0.000 0.0 3 -torsion 4 3 24 48 0.000 0.0 1 6.089 180.0 2 0.000 0.0 3 -torsion 4 3 24 91 0.000 0.0 1 6.089 180.0 2 0.000 0.0 3 -torsion 5 3 24 13 2.300 0.0 1 6.089 180.0 2 0.000 0.0 3 -torsion 5 3 24 45 0.000 0.0 1 4.900 180.0 2 0.000 0.0 3 -torsion 13 3 24 5 4.542 0.0 1 6.603 180.0 2 1.045 0.0 3 -torsion 13 3 24 13 2.300 0.0 1 6.089 180.0 2 0.000 0.0 3 -torsion 13 3 24 45 0.000 0.0 1 4.900 180.0 2 0.000 0.0 3 -torsion 13 3 24 48 2.300 0.0 1 6.089 180.0 2 0.000 0.0 3 -torsion 20 3 24 13 2.300 0.0 1 6.089 180.0 2 0.000 0.0 3 -torsion 20 3 24 45 0.000 0.0 1 4.900 180.0 2 0.000 0.0 3 -torsion 24 3 24 3 2.300 0.0 1 6.089 180.0 2 0.000 0.0 3 -torsion 24 3 24 13 4.600 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 24 3 24 45 0.000 0.0 1 4.900 180.0 2 0.000 0.0 3 -torsion 46 3 24 13 2.300 0.0 1 6.089 180.0 2 0.000 0.0 3 -torsion 46 3 24 45 0.000 0.0 1 4.900 180.0 2 0.000 0.0 3 -torsion 47 3 24 45 0.000 0.0 1 4.900 180.0 2 0.000 0.0 3 -torsion 48 3 24 45 0.000 0.0 1 4.900 180.0 2 0.000 0.0 3 -torsion 48 3 24 48 2.300 0.0 1 6.089 180.0 2 0.000 0.0 3 -torsion 48 3 24 84 2.300 0.0 1 6.089 180.0 2 0.000 0.0 3 -torsion 48 3 24 87 2.300 0.0 1 6.089 180.0 2 0.000 0.0 3 -torsion 84 3 24 48 2.300 0.0 1 6.089 180.0 2 0.000 0.0 3 -torsion 84 3 24 84 2.300 0.0 1 6.089 180.0 2 0.000 0.0 3 -torsion 84 3 24 87 2.300 0.0 1 6.089 180.0 2 0.000 0.0 3 -torsion 87 3 24 45 0.000 0.0 1 4.900 180.0 2 0.000 0.0 3 -torsion 87 3 24 48 2.300 0.0 1 6.089 180.0 2 0.000 0.0 3 -torsion 87 3 24 84 2.300 0.0 1 6.089 180.0 2 0.000 0.0 3 -torsion 87 3 24 87 2.300 0.0 1 6.089 180.0 2 0.000 0.0 3 -torsion 0 3 47 13 0.900 0.0 1 0.230 180.0 2 -0.505 0.0 3 -torsion 4 3 47 46 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 4 3 47 47 2.500 0.0 1 6.000 180.0 2 0.000 0.0 3 -torsion 5 3 47 47 3.200 0.0 1 -3.000 180.0 2 0.000 0.0 3 -torsion 24 3 47 46 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 24 3 47 47 2.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 107 3 47 46 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 107 3 47 47 2.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 4 3 48 48 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -torsion 5 3 48 48 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -torsion 13 3 48 48 0.000 0.0 1 0.200 180.0 2 0.000 0.0 3 -torsion 20 3 48 48 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -torsion 24 3 48 48 0.000 0.0 1 1.100 180.0 2 0.000 0.0 3 -torsion 46 3 48 48 0.000 0.0 1 0.200 180.0 2 0.000 0.0 3 -torsion 0 3 50 13 0.900 0.0 1 0.230 180.0 2 -0.505 0.0 3 -torsion 4 3 50 47 2.500 0.0 1 6.000 180.0 2 0.000 0.0 3 -torsion 5 3 50 47 3.200 0.0 1 -3.000 180.0 2 0.000 0.0 3 -torsion 13 3 50 47 0.800 0.0 1 -3.000 180.0 2 0.000 0.0 3 -torsion 13 3 56 0 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 13 3 56 13 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 46 3 56 0 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 46 3 56 45 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 0 3 60 0 0.000 0.0 1 7.000 180.0 2 0.000 0.0 3 -torsion 4 3 60 0 0.000 0.0 1 7.000 180.0 2 0.000 0.0 3 -torsion 4 3 82 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 4 3 82 57 2.000 0.0 1 1.000 180.0 2 0.000 0.0 3 -torsion 4 3 82 61 0.000 0.0 1 1.000 180.0 2 0.000 0.0 3 -torsion 82 3 82 57 -2.000 0.0 1 1.000 180.0 2 0.000 0.0 3 -torsion 82 3 82 61 0.000 0.0 1 1.000 180.0 2 0.000 0.0 3 -torsion 4 3 84 20 -0.750 0.0 1 1.500 180.0 2 0.000 0.0 3 -torsion 4 3 84 87 0.750 0.0 1 1.500 180.0 2 0.000 0.0 3 -torsion 84 3 84 20 0.000 0.0 1 1.500 180.0 2 0.000 0.0 3 -torsion 84 3 84 87 0.000 0.0 1 1.500 180.0 2 0.000 0.0 3 -torsion 48 3 86 48 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 0 3 87 0 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 4 3 87 84 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -torsion 4 3 87 87 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -torsion 24 3 87 84 0.000 0.0 1 1.100 180.0 2 0.000 0.0 3 -torsion 24 3 87 87 0.000 0.0 1 1.100 180.0 2 0.000 0.0 3 -torsion 4 3 107 13 0.000 0.0 1 4.900 180.0 2 0.000 0.0 3 -torsion 13 3 107 13 0.000 0.0 1 4.900 180.0 2 0.000 0.0 3 -torsion 4 3 109 109 2.500 0.0 1 6.000 180.0 2 0.000 0.0 3 -torsion 5 3 109 109 3.200 0.0 1 -3.000 180.0 2 0.000 0.0 3 -torsion 0 4 106 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 7 5 10 2 0.300 0.0 1 0.000 180.0 2 0.500 0.0 3 -torsion 7 5 10 6 0.300 0.0 1 0.000 180.0 2 0.500 0.0 3 -torsion 7 5 13 2 0.000 0.0 1 0.000 180.0 2 0.200 0.0 3 -torsion 7 5 13 6 0.000 0.0 1 0.000 180.0 2 0.200 0.0 3 -torsion 7 5 13 13 -0.356 0.0 1 -0.174 180.0 2 0.492 0.0 3 -#torsion 7 5 13 13 4.478 0.0 1 -2.175 180.0 2 0.000 0.0 3 -#torsion 7 5 13 13 2.674 0.0 1 -2.883 180.0 2 1.026 0.0 3 -torsion 7 5 13 46 0.000 0.0 1 0.000 180.0 2 0.352 0.0 3 -#torsion 7 5 13 36 -2.589 0.0 1 -1.123 180.0 2 0.270 0.0 3 -#torsion 7 5 13 36 0.000 0.0 1 0.000 180.0 2 0.476 0.0 3 -torsion 7 5 13 47 -0.900 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 7 5 13 48 -0.900 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 7 5 13 50 -0.900 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 7 5 44 13 0.000 0.0 1 0.000 180.0 2 0.300 0.0 3 -torsion 7 5 44 45 0.000 0.0 1 0.000 180.0 2 0.300 0.0 3 -torsion 7 5 24 3 5.519 0.0 1 -6.700 180.0 2 0.581 0.0 3 -torsion 7 5 24 45 2.722 0.0 1 -5.154 180.0 2 0.000 0.0 3 -torsion 7 5 47 47 0.000 0.0 1 1.682 180.0 2 0.000 0.0 3 -torsion 7 5 48 48 0.000 0.0 1 1.682 180.0 2 0.000 0.0 3 -torsion 7 5 51 20 -1.257 0.0 1 -1.806 180.0 2 0.003 0.0 3 -torsion 7 5 56 3 3.000 0.0 1 3.000 180.0 2 0.000 0.0 3 -torsion 7 5 64 4 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 7 5 64 5 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 7 5 79 13 -0.750 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 7 5 79 23 0.750 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 7 5 79 48 2.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 0 13 13 3 -4.344 0.0 1 -1.714 180.0 2 0.000 0.0 3 -torsion 0 13 13 13 1.711 0.0 1 -0.500 180.0 2 0.663 0.0 3 -#torsion 0 13 13 13 -1.336 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 0 13 13 24 1.428 0.0 1 0.086 180.0 2 0.029 0.0 3 -torsion 1 13 13 1 -2.500 0.0 1 0.000 180.0 2 0.250 0.0 3 -torsion 1 13 13 5 0.000 0.0 1 0.000 180.0 2 0.540 0.0 3 -torsion 1 13 13 13 0.300 0.0 1 -0.400 180.0 2 0.400 0.0 3 -torsion 1 13 13 46 0.000 0.0 1 0.000 180.0 2 0.400 0.0 3 -torsion 3 13 13 3 -0.550 0.0 1 0.000 180.0 2 1.000 0.0 3 -#torsion 3 13 13 3 0.800 0.0 1 0.000 180.0 2 0.900 0.0 3 -torsion 3 13 13 5 -6.180 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 3 13 13 13 -2.060 0.0 1 -0.313 180.0 2 0.315 0.0 3 -#torsion 3 13 13 13 -3.185 0.0 1 -0.825 180.0 2 0.493 0.0 3 -#torsion 3 13 13 13 -1.697 0.0 1 -0.456 180.0 2 0.585 0.0 3 -torsion 3 13 13 15 -4.344 0.0 1 -1.714 180.0 2 0.000 0.0 3 -torsion 3 13 13 16 -4.344 0.0 1 -1.714 180.0 2 0.000 0.0 3 -torsion 3 13 13 24 -9.000 0.0 1 2.000 180.0 2 0.800 0.0 3 -torsion 3 13 13 46 0.000 0.0 1 0.000 180.0 2 -0.100 0.0 3 -#torsion 3 13 13 36 0.000 0.0 1 0.000 180.0 2 0.074 0.0 3 -#torsion 3 13 13 36 0.000 0.0 1 0.000 180.0 2 -0.076 0.0 3 -torsion 3 13 13 48 -1.697 0.0 1 -0.456 180.0 2 0.585 0.0 3 -torsion 3 13 13 80 -1.697 0.0 1 -0.456 180.0 2 0.585 0.0 3 -torsion 5 13 13 5 9.508 0.0 1 0.000 180.0 2 0.000 0.0 3 -#torsion 5 13 13 5 12.234 0.0 1 0.000 180.0 2 0.000 0.0 3 -#torsion 5 13 13 5 9.066 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 5 13 13 13 -1.552 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 5 13 13 20 4.319 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 5 13 13 44 8.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 5 13 13 24 6.280 0.0 1 -1.467 180.0 2 2.030 0.0 3 -torsion 5 13 13 46 0.000 0.0 1 0.000 180.0 2 0.468 0.0 3 -torsion 13 13 13 13 1.300 0.0 1 -0.050 180.0 2 0.200 0.0 3 -#torsion 13 13 13 13 6.622 0. 1 0.948 180. 2 -1.388 0. 3 -2.118 180. 4 -torsion 13 13 13 15 1.262 0.0 1 -0.198 180.0 2 0.465 0.0 3 -torsion 13 13 13 16 2.619 0.0 1 -0.620 180.0 2 0.258 0.0 3 -torsion 13 13 13 19 0.000 0.0 1 -0.650 180.0 2 0.000 0.0 3 -torsion 13 13 13 21 0.000 0.0 1 0.000 180.0 2 0.400 0.0 3 -torsion 13 13 13 44 2.392 0.0 1 -0.674 180.0 2 0.550 0.0 3 -torsion 13 13 13 24 0.845 0.0 1 -0.962 180.0 2 0.713 0.0 3 -#torsion 13 13 13 35 1.964 0.0 1 0.000 180.0 2 0.659 0.0 3 -torsion 13 13 13 46 0.000 0.0 1 0.000 180.0 2 0.300 0.0 3 -torsion 13 13 13 51 1.300 0.0 1 -0.050 180.0 2 0.200 0.0 3 -torsion 13 13 13 53 2.732 0.0 1 -0.229 180.0 2 0.485 0.0 3 -torsion 13 13 13 65 0.000 0.0 1 0.000 180.0 2 0.400 0.0 3 -torsion 13 13 13 66 0.000 0.0 1 0.000 180.0 2 0.400 0.0 3 -torsion 13 13 13 79 1.262 0.0 1 -0.198 180.0 2 0.465 0.0 3 -torsion 13 13 13 107 1.964 0.0 1 0.000 180.0 2 0.659 0.0 3 -torsion 13 13 13 108 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 15 13 13 46 0.000 0.0 1 0.000 180.0 2 0.452 0.0 3 -torsion 16 13 13 46 0.000 0.0 1 0.000 180.0 2 0.452 0.0 3 -torsion 19 13 13 46 0.000 0.0 1 0.000 180.0 2 0.366 0.0 3 -torsion 20 13 13 20 -0.550 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 20 13 13 46 0.000 0.0 1 0.000 180.0 2 0.468 0.0 3 -torsion 21 13 13 21 -0.250 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 21 13 13 44 2.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 21 13 13 46 0.000 0.0 1 0.000 180.0 2 0.400 0.0 3 -torsion 44 13 13 44 11.035 0.0 1 -0.968 180.0 2 0.270 0.0 3 -torsion 44 13 13 46 -1.013 0.0 1 -0.709 180.0 2 0.473 0.0 3 -torsion 44 13 13 48 -0.800 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 24 13 13 46 0.000 0.0 1 0.000 180.0 2 0.464 0.0 3 -torsion 24 13 13 48 0.845 0.0 1 -0.962 180.0 2 0.713 0.0 3 -torsion 24 13 13 80 0.845 0.0 1 -0.962 180.0 2 0.713 0.0 3 -torsion 46 13 13 46 0.000 0.0 1 0.000 180.0 2 0.300 0.0 3 -torsion 46 13 13 47 0.000 0.0 1 0.000 180.0 2 0.366 0.0 3 -torsion 46 13 13 48 0.000 0.0 1 0.000 180.0 2 0.462 0.0 3 -torsion 46 13 13 51 0.000 0.0 1 0.000 180.0 2 0.300 0.0 3 -torsion 46 13 13 53 0.000 0.0 1 0.000 180.0 2 0.384 0.0 3 -torsion 46 13 13 55 0.000 0.0 1 0.000 180.0 2 -0.582 0.0 3 -torsion 46 13 13 59 0.000 0.0 1 0.000 180.0 2 0.462 0.0 3 -torsion 46 13 13 62 0.000 0.0 1 0.000 180.0 2 0.462 0.0 3 -torsion 46 13 13 65 0.000 0.0 1 0.000 180.0 2 0.400 0.0 3 -torsion 46 13 13 66 0.000 0.0 1 0.000 180.0 2 0.400 0.0 3 -torsion 46 13 13 79 0.000 0.0 1 0.000 180.0 2 0.452 0.0 3 -#torsion 36 13 13 69 0.000 0.0 1 0.000 180.0 2 0.350 0.0 3 -torsion 46 13 13 80 0.000 0.0 1 0.000 180.0 2 0.462 0.0 3 -torsion 46 13 13 82 0.000 0.0 1 0.000 180.0 2 0.462 0.0 3 -torsion 46 13 13 83 0.000 0.0 1 0.000 180.0 2 0.462 0.0 3 -torsion 46 13 13 84 0.000 0.0 1 0.000 180.0 2 0.462 0.0 3 -torsion 46 13 13 87 0.000 0.0 1 0.000 180.0 2 0.462 0.0 3 -torsion 46 13 13 88 0.000 0.0 1 0.000 180.0 2 0.462 0.0 3 -torsion 46 13 13 102 0.000 0.0 1 0.000 180.0 2 -0.225 0.0 3 -torsion 46 13 13 104 0.000 0.0 1 0.000 180.0 2 0.300 0.0 3 -torsion 46 13 13 107 0.000 0.0 1 0.000 180.0 2 0.464 0.0 3 -torsion 46 13 13 108 0.000 0.0 1 0.000 180.0 2 0.450 0.0 3 -torsion 46 13 13 109 0.000 0.0 1 0.000 180.0 2 0.366 0.0 3 -torsion 48 13 13 53 1.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 108 13 13 108 5.200 0.0 1 -0.500 180.0 2 0.000 0.0 3 -torsion 13 13 15 17 -0.759 0.0 1 -0.282 180.0 2 0.680 0.0 3 -torsion 46 13 15 17 0.000 0.0 1 0.000 180.0 2 0.480 0.0 3 -torsion 13 13 16 13 0.925 0.0 1 -0.576 180.0 2 0.677 0.0 3 -torsion 13 13 16 16 1.941 0.0 1 -0.836 180.0 2 0.935 0.0 3 -torsion 46 13 16 13 0.000 0.0 1 0.000 180.0 2 0.647 0.0 3 -torsion 46 13 16 16 0.000 0.0 1 0.000 180.0 2 0.558 0.0 3 -torsion 46 13 16 48 0.000 0.0 1 0.000 180.0 2 0.647 0.0 3 -torsion 0 13 18 19 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 46 13 18 19 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 0 13 19 18 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 0 13 19 19 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 13 19 19 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 46 13 19 19 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 0 13 20 13 -0.521 0.0 1 -2.018 180.0 2 1.996 0.0 3 -torsion 56 13 20 13 -0.500 0.0 1 -1.500 180.0 2 1.000 0.0 3 -torsion 57 13 20 13 -0.500 0.0 1 -1.500 180.0 2 1.000 0.0 3 -torsion 13 13 20 3 -1.220 0.0 1 -0.126 180.0 2 0.422 0.0 3 -torsion 13 13 20 13 0.650 0.0 1 -0.250 180.0 2 0.670 0.0 3 -torsion 13 13 20 64 -1.420 0.0 1 -0.620 180.0 2 0.100 0.0 3 -torsion 46 13 20 0 0.000 0.0 1 0.000 180.0 2 0.760 0.0 3 -torsion 46 13 20 3 0.000 0.0 1 0.000 180.0 2 0.198 0.0 3 -torsion 46 13 20 47 0.000 0.0 1 0.000 180.0 2 0.760 0.0 3 -torsion 46 13 20 48 0.000 0.0 1 0.000 180.0 2 0.760 0.0 3 -torsion 46 13 20 51 0.000 0.0 1 0.000 180.0 2 0.760 0.0 3 -torsion 46 13 20 64 0.000 0.0 1 0.000 180.0 2 0.300 0.0 3 -torsion 13 13 44 13 0.416 0.0 1 -0.128 180.0 2 0.695 0.0 3 -#torsion 13 13 33 13 1.536 0.0 1 -0.128 180.0 2 0.695 0.0 3 -#torsion 13 13 33 13 1.464 0.0 1 -0.128 180.0 2 0.695 0.0 3 -torsion 13 13 44 45 -0.190 0.0 1 -0.417 180.0 2 0.418 0.0 3 -#torsion 13 13 33 34 0.000 0.0 1 4.000 180.0 2 0.000 0.0 3 -#torsion 13 13 33 34 0.200 0.0 1 -0.417 180.0 2 0.418 0.0 3 -#torsion 13 13 33 34 0.819 0.0 1 -0.417 180.0 2 0.418 0.0 3 -#torsion 13 13 33 34 1.522 0.0 1 -0.417 180.0 2 0.418 0.0 3 -torsion 46 13 44 13 0.000 0.0 1 0.000 180.0 2 0.560 0.0 3 -torsion 46 13 44 45 0.000 0.0 1 0.000 180.0 2 0.400 0.0 3 -torsion 46 13 44 48 0.000 0.0 1 0.000 180.0 2 0.560 0.0 3 -torsion 0 13 24 45 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 3 13 24 3 -2.365 0.0 1 0.912 180.0 2 -0.850 0.0 3 -torsion 3 13 24 13 -1.737 0.0 1 1.251 180.0 2 -3.501 0.0 3 -torsion 3 13 24 45 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 13 24 3 0.000 0.0 1 0.462 180.0 2 0.000 0.0 3 -#torsion 13 13 35 3 -1.396 0.0 1 -0.427 180.0 2 0.000 0.0 3 -#torsion 13 13 35 3 1.130 0.0 1 -1.420 180.0 2 0.440 0.0 3 -torsion 13 13 24 13 4.753 0.0 1 -0.734 180.0 2 0.000 0.0 3 -#torsion 13 13 35 13 2.859 0.0 1 2.058 180.0 2 -11.266 0.0 3 -torsion 13 13 24 45 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 13 24 59 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 13 24 79 2.929 0.0 1 -2.533 180.0 2 0.497 0.0 3 -torsion 13 13 24 91 2.300 0.0 1 6.089 180.0 2 0.000 0.0 3 -torsion 46 13 24 3 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -#torsion 36 13 35 3 0.000 0.0 1 0.000 180.0 2 -0.139 0.0 3 -torsion 46 13 24 13 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 46 13 24 45 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 46 13 24 48 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 46 13 24 79 1.362 0.0 1 -1.457 180.0 2 0.149 0.0 3 -torsion 48 13 24 59 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 0 13 47 13 1.711 0.0 1 -0.500 180.0 2 0.663 0.0 3 -torsion 0 13 47 46 0.000 0.0 1 0.000 180.0 2 0.468 0.0 3 -torsion 0 13 47 47 0.500 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 0 13 47 50 0.500 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 1 13 47 47 0.500 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 13 47 13 2.817 0.0 1 -0.169 180.0 2 0.543 0.0 3 -torsion 13 13 47 47 0.346 0.0 1 0.405 180.0 2 -0.904 0.0 3 -torsion 13 13 47 50 0.346 0.0 1 0.405 180.0 2 -0.904 0.0 3 -torsion 46 13 47 13 0.000 0.0 1 0.000 180.0 2 0.300 0.0 3 -torsion 46 13 47 46 0.000 0.0 1 0.000 180.0 2 0.318 0.0 3 -torsion 46 13 47 47 0.000 0.0 1 0.000 180.0 2 -0.372 0.0 3 -torsion 46 13 47 50 0.000 0.0 1 0.000 180.0 2 -0.372 0.0 3 -torsion 46 13 47 110 0.000 0.0 1 0.000 180.0 2 -0.250 0.0 3 -torsion 47 13 47 13 0.000 0.0 1 -8.000 180.0 2 0.000 0.0 3 -torsion 47 13 47 46 0.000 0.0 1 -8.000 180.0 2 0.000 0.0 3 -torsion 0 13 48 48 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 1 13 48 48 0.000 0.0 1 0.450 180.0 2 0.000 0.0 3 -torsion 13 13 48 48 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 13 48 56 -0.500 0.0 1 0.500 180.0 2 -0.500 0.0 3 -torsion 21 13 48 48 0.000 0.0 1 -0.400 180.0 2 0.000 0.0 3 -torsion 46 13 48 48 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 64 13 48 48 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 65 13 48 48 0.000 0.0 1 0.000 180.0 2 0.400 0.0 3 -torsion 0 13 50 47 0.500 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 13 50 50 0.346 0.0 1 0.405 180.0 2 -0.904 0.0 3 -torsion 46 13 50 47 0.000 0.0 1 0.000 180.0 2 -0.372 0.0 3 -torsion 46 13 50 50 0.000 0.0 1 0.000 180.0 2 -0.372 0.0 3 -torsion 46 13 50 109 0.000 0.0 1 0.000 180.0 2 -0.372 0.0 3 -torsion 13 13 51 0 1.711 0.0 1 -0.500 180.0 2 0.663 0.0 3 -torsion 13 13 51 46 0.000 0.0 1 0.000 180.0 2 0.300 0.0 3 -torsion 46 13 51 20 0.000 0.0 1 0.000 180.0 2 0.468 0.0 3 -torsion 13 13 53 13 1.438 0.0 1 -0.124 180.0 2 0.264 0.0 3 -torsion 13 13 53 45 0.000 0.0 1 0.000 180.0 2 0.347 0.0 3 -torsion 46 13 53 13 0.000 0.0 1 0.000 180.0 2 0.302 0.0 3 -torsion 46 13 53 45 0.000 0.0 1 0.000 180.0 2 0.261 0.0 3 -torsion 46 13 53 48 0.000 0.0 1 0.000 180.0 2 0.462 0.0 3 -torsion 46 13 53 54 0.000 0.0 1 0.000 180.0 2 0.300 0.0 3 -torsion 13 13 55 45 -0.190 0.0 1 -0.417 180.0 2 0.418 0.0 3 -torsion 13 13 55 48 1.829 0.0 1 0.243 180.0 2 -0.498 0.0 3 -torsion 13 13 55 54 -0.190 0.0 1 -0.417 180.0 2 0.418 0.0 3 -torsion 46 13 55 13 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 46 13 55 45 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 46 13 55 48 0.000 0.0 1 0.000 180.0 2 0.177 0.0 3 -torsion 13 13 56 18 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 0 13 57 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 13 57 0 1.000 0.0 1 -0.350 180.0 2 0.000 0.0 3 -#torsion 13 13 47 0 0.000 0.0 1 -0.576 180.0 2 0.000 0.0 3 -torsion 13 13 57 62 2.756 0.0 1 -0.872 180.0 2 -3.680 0.0 3 -#torsion 13 13 47 52 -1.000 0.0 1 -0.350 180.0 2 0.000 0.0 3 -torsion 13 13 57 82 -1.000 0.0 1 -0.350 180.0 2 0.000 0.0 3 -torsion 20 13 57 0 1.500 0.0 1 -1.500 180.0 2 0.000 0.0 3 -#torsion 29 13 47 0 0.000 0.0 1 -1.876 180.0 2 0.000 0.0 3 -torsion 20 13 57 62 -1.500 0.0 1 -1.500 180.0 2 0.000 0.0 3 -torsion 20 13 57 82 -1.500 0.0 1 -1.500 180.0 2 0.000 0.0 3 -torsion 13 13 59 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 13 59 56 0.000 0.0 1 0.500 180.0 2 -0.500 0.0 3 -torsion 46 13 59 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 13 62 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 46 13 62 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 46 13 64 20 0.000 0.0 1 0.000 180.0 2 0.250 0.0 3 -torsion 46 13 64 52 0.000 0.0 1 0.000 180.0 2 0.250 0.0 3 -torsion 48 13 64 20 2.250 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 48 13 64 52 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 0 13 79 23 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 0 13 79 24 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 13 79 13 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 13 79 23 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 46 13 79 5 0.000 0.0 1 0.000 180.0 2 0.350 0.0 3 -torsion 46 13 79 13 0.000 0.0 1 0.000 180.0 2 0.350 0.0 3 -torsion 46 13 79 23 0.000 0.0 1 0.000 180.0 2 0.350 0.0 3 -torsion 46 13 79 48 0.000 0.0 1 0.000 180.0 2 0.350 0.0 3 -torsion 13 13 80 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 13 80 60 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 13 80 84 -0.714 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 46 13 80 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 46 13 80 60 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 46 13 80 84 0.000 0.0 1 0.000 180.0 2 -0.480 0.0 3 -torsion 13 13 82 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 46 13 82 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 13 83 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 46 13 83 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 1 13 84 0 0.000 0.0 1 0.450 180.0 2 0.000 0.0 3 -torsion 13 13 84 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 13 84 57 1.700 0.0 1 -0.600 180.0 2 0.000 0.0 3 -torsion 21 13 84 0 0.000 0.0 1 -0.400 180.0 2 0.000 0.0 3 -torsion 46 13 84 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 1 13 87 0 0.000 0.0 1 0.450 180.0 2 0.000 0.0 3 -torsion 13 13 87 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 21 13 87 0 0.000 0.0 1 -0.400 180.0 2 0.000 0.0 3 -torsion 46 13 87 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 13 88 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 46 13 88 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 0 13 90 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 46 13 90 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 46 13 91 91 0.000 0.0 1 0.000 180.0 2 0.300 0.0 3 -torsion 13 13 95 13 0.000 0.0 1 -1.000 180.0 2 0.000 0.0 3 -torsion 13 13 95 46 0.000 0.0 1 -1.000 180.0 2 0.000 0.0 3 -torsion 13 13 102 103 0.000 0.0 1 0.400 180.0 2 0.000 0.0 3 -torsion 46 13 102 103 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 13 104 13 1.000 0.0 1 -0.500 180.0 2 0.500 0.0 3 -torsion 46 13 104 13 0.000 0.0 1 0.000 180.0 2 0.300 0.0 3 -torsion 0 13 105 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 13 105 0 1.000 0.0 1 -0.350 180.0 2 0.000 0.0 3 -torsion 13 13 105 62 -1.000 0.0 1 -0.350 180.0 2 0.000 0.0 3 -torsion 13 13 105 82 -1.000 0.0 1 -0.350 180.0 2 0.000 0.0 3 -torsion 20 13 105 0 1.500 0.0 1 -1.500 180.0 2 0.000 0.0 3 -torsion 20 13 105 62 3.132 0.0 1 -1.491 180.0 2 2.744 0.0 3 -#torsion 29 13 95 52 -1.500 0.0 1 -1.500 180.0 2 0.000 0.0 3 -torsion 20 13 105 82 -1.500 0.0 1 -1.500 180.0 2 0.000 0.0 3 -torsion 3 13 107 13 -1.737 0.0 1 1.251 180.0 2 -3.501 0.0 3 -torsion 13 13 107 3 -1.396 0.0 1 -0.427 180.0 2 0.000 0.0 3 -torsion 13 13 107 13 4.753 0.0 1 -0.734 180.0 2 0.000 0.0 3 -#torsion 13 13 97 13 2.859 0.0 1 2.058 180.0 2 -11.266 0.0 3 -torsion 46 13 107 3 0.000 0.0 1 0.000 180.0 2 -0.139 0.0 3 -torsion 46 13 107 13 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 46 13 107 48 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 13 108 13 1.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 13 108 45 0.000 0.0 1 0.000 180.0 2 0.260 0.0 3 -torsion 46 13 108 13 0.000 0.0 1 0.000 180.0 2 0.180 0.0 3 -torsion 46 13 108 20 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 46 13 108 45 0.000 0.0 1 0.000 180.0 2 0.180 0.0 3 -torsion 13 13 109 109 0.346 0.0 1 0.405 180.0 2 -0.904 0.0 3 -torsion 46 13 109 13 0.000 0.0 1 0.000 180.0 2 0.300 0.0 3 -torsion 46 13 109 46 0.000 0.0 1 0.000 180.0 2 0.318 0.0 3 -torsion 46 13 109 109 0.000 0.0 1 0.000 180.0 2 -0.372 0.0 3 -torsion 17 15 48 0 0.000 0.0 1 1.100 180.0 2 0.000 0.0 3 -#torsion 17 15 38 0 -3.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 17 15 48 48 0.000 0.0 1 1.100 180.0 2 0.000 0.0 3 -torsion 13 16 16 13 0.000 0.0 1 -7.414 180.0 2 1.705 0.0 3 -torsion 13 16 48 48 0.000 0.0 1 0.600 180.0 2 0.000 0.0 3 -torsion 13 16 48 56 1.600 0.0 1 5.100 180.0 2 0.000 0.0 3 -torsion 13 16 59 56 0.000 0.0 1 4.800 180.0 2 0.000 0.0 3 -torsion 84 16 82 0 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 84 16 82 61 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 82 16 84 49 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 82 16 84 83 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 82 16 84 88 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 0 16 91 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 19 18 48 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 19 18 48 48 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 18 18 56 13 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 18 18 56 46 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 0 19 19 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 19 19 13 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 19 19 46 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 19 19 47 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 19 19 109 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 46 19 19 47 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 46 19 19 109 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 19 19 47 13 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 19 19 47 46 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 19 19 47 47 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 20 44 13 0.000 0.0 1 0.000 180.0 2 0.300 0.0 3 -torsion 13 20 44 45 0.000 0.0 1 0.000 180.0 2 0.300 0.0 3 -torsion 13 20 47 13 0.650 0.0 1 -0.250 180.0 2 0.670 0.0 3 -torsion 13 20 47 46 0.000 0.0 1 0.000 180.0 2 0.760 0.0 3 -torsion 13 20 47 47 -3.500 0.0 1 3.000 180.0 2 0.000 0.0 3 -torsion 13 20 47 50 -3.500 0.0 1 3.000 180.0 2 0.000 0.0 3 -torsion 3 20 48 48 0.000 0.0 1 2.500 180.0 2 0.000 0.0 3 -torsion 13 20 48 48 0.000 0.0 1 3.000 180.0 2 0.000 0.0 3 -torsion 13 20 48 56 0.400 0.0 1 5.500 180.0 2 0.000 0.0 3 -torsion 64 20 48 48 0.000 0.0 1 2.990 180.0 2 0.000 0.0 3 -torsion 13 20 51 5 -0.375 0.0 1 -1.358 180.0 2 0.004 0.0 3 -torsion 13 20 51 13 0.650 0.0 1 -0.250 180.0 2 0.670 0.0 3 -torsion 13 20 51 20 -0.375 0.0 1 -1.358 180.0 2 0.004 0.0 3 -torsion 13 20 51 46 0.000 0.0 1 0.000 180.0 2 0.760 0.0 3 -torsion 13 20 56 3 3.000 0.0 1 3.000 180.0 2 0.000 0.0 3 -torsion 13 20 59 56 0.000 0.0 1 5.200 180.0 2 0.000 0.0 3 -torsion 0 20 64 52 0.000 0.0 1 0.000 180.0 2 0.562 0.0 3 -torsion 13 20 64 13 3.500 0.0 1 -3.300 180.0 2 1.500 0.0 3 -torsion 13 20 64 52 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -#torsion 13 29 54 42 0.900 0.0 1 -2.930 180.0 2 2.640 0.0 3 -torsion 48 20 64 4 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 84 20 82 61 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 82 20 84 88 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 84 20 84 49 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 84 20 84 87 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 108 20 108 13 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 108 20 108 20 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 44 44 13 0.000 0.0 1 0.000 180.0 2 0.300 0.0 3 -torsion 13 44 44 45 0.000 0.0 1 0.000 180.0 2 0.300 0.0 3 -torsion 45 44 44 45 0.000 0.0 1 0.000 180.0 2 0.300 0.0 3 -torsion 13 44 48 48 -7.582 0.0 1 3.431 180.0 2 3.198 0.0 3 -torsion 45 44 48 48 0.000 0.0 1 2.030 180.0 2 0.000 0.0 3 -torsion 59 44 48 48 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -torsion 82 44 48 48 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -torsion 84 44 48 48 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -torsion 45 44 82 16 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -torsion 45 44 82 61 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -torsion 48 44 82 16 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -torsion 48 44 82 61 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -torsion 0 24 48 48 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -torsion 3 24 48 48 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -torsion 13 24 48 48 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -torsion 45 24 48 48 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -torsion 59 24 48 48 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -torsion 82 24 48 48 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -torsion 84 24 48 48 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -torsion 0 24 59 0 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 0 24 59 49 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 45 24 59 0 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 0 24 60 0 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 0 24 79 23 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 24 79 48 2.074 0.0 1 -2.966 180.0 2 2.473 0.0 3 -torsion 45 24 79 48 1.671 0.0 1 -4.901 180.0 2 0.669 0.0 3 -torsion 13 24 82 61 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -torsion 45 24 82 16 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -#torsion 34 35 72 16 0.000 0.0 1 2.030 180.0 2 0.000 0.0 3 -torsion 45 24 82 20 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -#torsion 34 35 72 29 0.000 0.0 1 2.030 180.0 2 0.000 0.0 3 -torsion 45 24 82 61 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -torsion 48 24 82 16 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -torsion 48 24 82 20 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -torsion 48 24 82 61 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -torsion 0 24 84 0 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 3 24 84 84 0.000 0.0 1 3.000 180.0 2 0.000 0.0 3 -torsion 45 24 84 16 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -torsion 45 24 84 20 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -torsion 48 24 84 16 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -torsion 48 24 84 20 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -torsion 3 24 86 48 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 3 24 86 56 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 3 24 86 86 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 47 24 86 48 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 47 24 86 56 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 0 24 87 0 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 0 24 88 0 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 3 24 91 46 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 3 24 91 89 -1.396 0.0 1 -0.427 180.0 2 0.000 0.0 3 -torsion 3 24 91 91 -1.396 0.0 1 -0.427 180.0 2 0.000 0.0 3 -torsion 45 24 91 46 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 45 24 91 89 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 45 24 91 91 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 0 24 106 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 47 46 47 13 0.000 0.0 1 -8.000 180.0 2 0.000 0.0 3 -torsion 47 46 47 46 0.000 0.0 1 -8.000 180.0 2 0.000 0.0 3 -torsion 0 47 47 0 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 0 47 47 19 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 3 47 47 24 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 3 47 47 46 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 5 47 47 13 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 5 47 47 46 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 13 47 47 13 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 13 47 47 19 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 13 47 47 20 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 13 47 47 46 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 19 47 47 46 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 20 47 47 46 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 21 47 47 21 -1.600 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 21 47 47 46 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 46 47 47 46 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 46 47 47 48 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 13 47 48 48 0.205 0.0 1 -0.531 180.0 2 0.000 0.0 3 -torsion 46 47 48 48 0.000 0.0 1 0.000 180.0 2 -0.372 0.0 3 -torsion 46 47 48 56 0.000 0.0 1 0.000 180.0 2 -0.372 0.0 3 -torsion 47 47 48 48 1.241 0.0 1 3.353 180.0 2 -0.286 0.0 3 -torsion 13 47 50 13 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 13 47 50 46 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 13 47 50 48 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 13 47 50 50 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 13 47 50 109 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 24 47 50 3 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 46 47 50 13 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 46 47 50 46 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 46 47 50 48 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 46 47 50 50 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 46 47 50 109 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 0 47 84 0 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 0 47 86 48 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 3 47 86 86 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 49 47 86 0 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 49 47 86 24 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 0 47 87 0 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 0 47 88 0 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 13 47 110 47 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 46 47 110 47 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 0 48 48 0 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 0 48 48 13 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 0 48 48 48 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 0 48 48 49 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 1 48 48 48 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 1 48 48 49 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 13 48 48 13 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 13 48 48 48 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 13 48 48 49 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 13 48 48 50 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 21 48 48 48 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 21 48 48 49 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 44 48 48 49 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 47 48 48 49 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 48 48 48 48 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 48 48 48 49 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 48 48 48 50 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 48 48 48 55 0.0 0. 1 1.62 180. 2 0.0 0. 3 -0.44 180. 4 -torsion 48 48 48 60 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 48 48 48 65 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 48 48 48 66 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 48 48 48 86 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 48 48 48 109 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 49 48 48 49 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 49 48 48 50 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 49 48 48 60 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 49 48 48 65 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 49 48 48 66 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 49 48 48 86 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 49 48 48 109 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 56 48 48 86 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 48 48 50 46 0.000 0.0 1 0.000 180.0 2 -0.372 0.0 3 -torsion 48 48 50 47 1.241 0.0 1 3.353 180.0 2 -0.286 0.0 3 -torsion 56 48 50 46 0.000 0.0 1 0.000 180.0 2 -0.372 0.0 3 -torsion 56 48 50 47 1.241 0.0 1 3.353 180.0 2 -0.286 0.0 3 -torsion 48 48 53 13 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 48 48 53 54 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 0 48 55 45 0.000 0.0 1 2.030 180.0 2 0.000 0.0 3 -torsion 48 48 55 45 0.000 0.0 1 3.900 180.0 2 0.000 0.0 3 -torsion 55 48 55 13 0.000 0.0 1 7.936 180.0 2 0.000 0.0 3 -torsion 55 48 55 45 0.000 0.0 1 3.900 180.0 2 0.000 0.0 3 -torsion 60 48 55 45 0.000 0.0 1 2.030 180.0 2 0.000 0.0 3 -torsion 0 48 56 0 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 48 48 56 48 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 49 48 56 48 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 0 48 60 0 0.000 0.0 1 7.000 180.0 2 0.000 0.0 3 -torsion 0 48 79 23 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 48 48 79 13 0.000 0.0 1 -0.900 180.0 2 0.000 0.0 3 -torsion 48 48 79 24 1.656 0.0 1 -0.768 180.0 2 -0.117 0.0 3 -torsion 48 48 86 48 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 48 48 86 56 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 48 48 86 86 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 49 48 86 48 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 49 48 86 56 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 49 48 86 86 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 56 48 86 48 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 56 48 86 86 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 49 48 88 49 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 56 48 101 13 0.000 0.0 1 3.651 180.0 2 0.000 0.0 3 -torsion 48 48 102 103 0.000 0.0 1 1.150 180.0 2 0.000 0.0 3 -torsion 48 48 109 13 0.205 0.0 1 -0.531 180.0 2 0.000 0.0 3 -torsion 48 48 109 46 0.000 0.0 1 0.000 180.0 2 -0.372 0.0 3 -torsion 48 48 109 109 1.241 0.0 1 3.353 180.0 2 -0.286 0.0 3 -torsion 0 50 50 49 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 3 50 50 3 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 13 50 50 13 0.000 0.0 1 0.000 180.0 2 0.300 0.0 3 -torsion 13 50 50 46 0.000 0.0 1 0.000 180.0 2 0.300 0.0 3 -torsion 13 50 50 47 0.000 0.0 1 0.000 180.0 2 -0.372 0.0 3 -#torsion 13 40 40 37 0.900 0.0 1 0.230 180.0 2 -0.505 0.0 3 -torsion 46 50 50 46 0.000 0.0 1 0.000 180.0 2 0.300 0.0 3 -torsion 46 50 50 47 0.000 0.0 1 0.000 180.0 2 -0.372 0.0 3 -torsion 47 50 50 47 1.423 0.0 1 4.055 180.0 2 0.858 0.0 3 -torsion 13 50 109 13 0.000 0.0 1 0.000 180.0 2 0.300 0.0 3 -torsion 13 50 109 109 0.000 0.0 1 0.000 180.0 2 -0.372 0.0 3 -torsion 46 50 109 13 0.000 0.0 1 0.000 180.0 2 0.300 0.0 3 -torsion 46 50 109 46 0.000 0.0 1 0.000 180.0 2 0.300 0.0 3 -torsion 46 50 109 109 0.000 0.0 1 0.000 180.0 2 -0.372 0.0 3 -torsion 47 50 109 13 0.000 0.0 1 0.000 180.0 2 -0.372 0.0 3 -torsion 47 50 109 46 0.000 0.0 1 0.000 180.0 2 -0.372 0.0 3 -torsion 47 50 109 109 1.423 0.0 1 4.055 180.0 2 0.858 0.0 3 -torsion 13 53 82 61 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -torsion 48 53 82 61 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -torsion 45 55 59 0 0.000 0.0 1 2.030 180.0 2 0.000 0.0 3 -torsion 13 56 56 13 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 13 56 56 48 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 48 56 56 48 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 0 56 59 0 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 0 56 59 49 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 0 56 60 0 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 0 56 62 0 0.000 0.0 1 10.000 180.0 2 0.000 0.0 3 -torsion 0 56 82 0 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -#torsion 0 46 72 0 0.000 0.0 1 10.000 180.0 2 0.000 0.0 3 -torsion 48 56 86 48 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 48 56 86 86 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 0 57 60 0 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 45 57 60 0 0.000 0.0 1 5.000 180.0 2 0.000 0.0 3 -torsion 0 57 61 0 0.000 0.0 1 10.000 180.0 2 0.000 0.0 3 -torsion 0 57 62 0 0.000 0.0 1 10.000 180.0 2 0.000 0.0 3 -torsion 0 57 81 0 0.000 0.0 1 3.050 180.0 2 0.000 0.0 3 -torsion 0 57 82 0 0.000 0.0 1 4.650 180.0 2 0.000 0.0 3 -#torsion 0 47 72 0 0.000 0.0 1 10.000 180.0 2 0.000 0.0 3 -torsion 0 57 82 49 0.000 0.0 1 10.000 180.0 2 0.000 0.0 3 -torsion 45 57 82 0 0.000 0.0 1 5.000 180.0 2 0.000 0.0 3 -torsion 0 57 84 0 0.000 0.0 1 2.800 180.0 2 0.000 0.0 3 -#torsion 0 47 74 0 0.000 0.0 1 5.000 180.0 2 0.000 0.0 3 -#torsion 0 47 74 0 0.000 0.0 1 3.000 180.0 2 0.000 0.0 3 -torsion 45 57 84 0 0.000 0.0 1 5.000 180.0 2 0.000 0.0 3 -torsion 61 57 86 48 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 84 57 86 48 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 0 60 60 0 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 0 60 61 0 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 0 60 80 0 0.000 0.0 1 3.350 180.0 2 0.000 0.0 3 -torsion 0 60 81 0 0.000 0.0 1 6.000 180.0 2 0.000 0.0 3 -torsion 0 60 87 0 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 48 60 87 84 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 60 60 87 84 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 0 61 61 0 0.000 0.0 1 10.000 180.0 2 0.000 0.0 3 -torsion 0 61 62 0 0.000 0.0 1 10.000 180.0 2 0.000 0.0 3 -torsion 0 61 82 0 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -#torsion 0 51 72 0 0.000 0.0 1 10.000 180.0 2 0.000 0.0 3 -torsion 0 61 82 49 0.000 0.0 1 10.000 180.0 2 0.000 0.0 3 -torsion 83 61 82 16 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 88 61 82 16 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 88 61 82 20 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 0 61 83 0 0.000 0.0 1 4.800 180.0 2 0.000 0.0 3 -torsion 82 61 83 49 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 82 61 83 84 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 0 61 84 0 0.000 0.0 1 10.000 180.0 2 0.000 0.0 3 -torsion 0 61 88 0 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 82 61 88 84 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 0 80 84 0 0.000 0.0 1 13.050 180.0 2 0.000 0.0 3 -torsion 0 82 84 0 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 16 82 86 48 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 20 82 86 48 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 57 82 86 48 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 61 82 86 48 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 0 82 87 0 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -#torsion 0 72 77 0 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 0 83 84 0 0.000 0.0 1 10.750 180.0 2 0.000 0.0 3 -torsion 0 83 84 49 0.000 0.0 1 10.750 180.0 2 0.000 0.0 3 -torsion 49 83 84 0 0.000 0.0 1 10.750 180.0 2 0.000 0.0 3 -torsion 49 83 84 16 0.000 0.0 1 10.750 180.0 2 0.000 0.0 3 -torsion 49 83 84 49 0.000 0.0 1 10.750 180.0 2 0.000 0.0 3 -torsion 61 83 84 16 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 61 83 84 20 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 61 83 84 49 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 0 83 86 48 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 61 83 86 48 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 61 83 87 0 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 84 83 87 0 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 0 84 84 0 0.000 0.0 1 10.750 180.0 2 0.000 0.0 3 -torsion 0 84 84 49 0.000 0.0 1 10.750 180.0 2 0.000 0.0 3 -torsion 16 84 84 49 0.000 0.0 1 10.750 180.0 2 0.000 0.0 3 -torsion 49 84 84 49 0.000 0.0 1 10.750 180.0 2 0.000 0.0 3 -torsion 0 84 86 48 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 16 84 86 48 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 20 84 86 48 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 57 84 86 48 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 0 84 87 0 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 0 84 87 49 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 49 84 87 49 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 0 84 88 49 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 16 84 88 49 0.000 0.0 1 10.750 180.0 2 0.000 0.0 3 -torsion 16 84 88 61 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 20 84 88 61 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 49 84 88 0 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 49 84 88 61 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 48 86 86 48 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 48 86 86 56 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 48 86 87 0 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 48 86 88 0 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 48 86 88 61 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 56 86 88 0 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 0 87 87 20 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 0 87 87 57 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 0 87 87 87 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 49 87 87 49 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 4 89 90 13 0.000 0.0 1 6.089 180.0 2 0.000 0.0 3 -torsion 4 89 90 45 0.000 0.0 1 4.900 180.0 2 0.000 0.0 3 -torsion 4 89 90 48 0.000 0.0 1 6.089 180.0 2 0.000 0.0 3 -torsion 4 89 90 91 0.000 0.0 1 20.000 180.0 2 0.000 0.0 3 -torsion 91 89 90 13 2.300 0.0 1 6.089 180.0 2 0.000 0.0 3 -torsion 91 89 90 45 0.000 0.0 1 4.900 180.0 2 0.000 0.0 3 -torsion 91 89 90 48 2.300 0.0 1 6.089 180.0 2 0.000 0.0 3 -torsion 91 89 90 91 2.300 0.0 1 6.089 180.0 2 0.000 0.0 3 -torsion 0 89 91 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 4 89 91 46 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 4 89 91 91 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 90 89 91 46 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 90 89 91 91 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 0 90 91 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 0 90 91 46 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 0 90 91 91 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 0 91 91 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 0 91 91 24 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 91 91 13 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 91 91 46 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 46 91 91 46 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 46 91 91 91 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 91 91 91 91 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 0 109 109 0 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 13 109 109 13 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 13 109 109 46 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 13 109 109 48 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 13 109 109 50 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 13 109 109 109 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 46 109 109 46 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 46 109 109 48 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 46 109 109 50 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 46 109 109 109 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 48 109 109 48 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 48 109 109 50 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 48 109 109 109 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 50 109 109 50 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 50 109 109 109 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 109 109 109 109 1.423 0.0 1 4.055 180.0 2 0.858 0.0 3 - - - ################################################################ - ## ## - ## Additional Torsional Parameter Values Used with OPLS-AA ## - ## ## - ## The torsions listed below were added to official OPLS-AA ## - ## to complete the set needed for proteins; the values were ## - ## obtained by analogy from the closest OPLS-AA torsions; ## - ## most of the added values are for HIP or N-terminal AAs; ## - ## ## - ################################################################ - - -torsion 24 3 13 53 1.816 0.0 1 1.222 180.0 2 1.581 0.0 3 -torsion 52 3 13 24 0.000 0.0 1 0.820 180.0 2 0.000 0.0 3 -torsion 3 13 13 53 1.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 3 13 13 83 -1.697 0.0 1 -0.456 180.0 2 0.585 0.0 3 -torsion 3 13 13 84 -1.697 0.0 1 -0.456 180.0 2 0.585 0.0 3 -torsion 3 13 13 85 -1.697 0.0 1 -0.456 180.0 2 0.585 0.0 3 -torsion 5 13 13 53 6.280 0.0 1 -1.467 180.0 2 2.030 0.0 3 -torsion 15 13 13 53 1.428 0.0 1 0.086 180.0 2 0.029 0.0 3 -torsion 16 13 13 53 1.428 0.0 1 0.086 180.0 2 0.029 0.0 3 -torsion 13 13 13 55 2.732 0.0 1 -0.229 180.0 2 0.485 0.0 3 -torsion 24 13 13 83 0.845 0.0 1 -0.962 180.0 2 0.713 0.0 3 -torsion 53 13 13 83 1.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 24 13 13 84 0.845 0.0 1 -0.962 180.0 2 0.713 0.0 3 -torsion 53 13 13 84 1.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 24 13 13 85 0.845 0.0 1 -0.962 180.0 2 0.713 0.0 3 -torsion 46 13 13 85 0.000 0.0 1 0.000 180.0 2 0.462 0.0 3 -torsion 53 13 13 85 1.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 3 13 53 13 1.438 0.0 1 -0.124 180.0 2 0.264 0.0 3 -torsion 3 13 53 54 0.000 0.0 1 0.000 180.0 2 0.347 0.0 3 -torsion 13 13 53 54 0.000 0.0 1 0.000 180.0 2 0.347 0.0 3 -torsion 46 13 55 54 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 13 85 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 13 85 57 1.700 0.0 1 -0.600 180.0 2 0.000 0.0 3 -torsion 46 13 85 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 55 48 55 54 0.000 0.0 1 3.900 180.0 2 0.000 0.0 3 -torsion 0 48 81 0 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 0 57 85 0 0.000 0.0 1 5.000 180.0 2 0.000 0.0 3 -torsion 0 85 85 0 0.000 0.0 1 10.750 180.0 2 0.000 0.0 3 - - - ################################################################ - ## ## - ## Additional Torsional Parameter Values Used with OPLS-AA ## - ## ## - ## The torsions listed below were added to official OPLS-AA ## - ## to complete the values needed for selected organics ## - ## ## - ################################################################ - - -torsion 13 13 13 20 1.300 0.0 1 -0.050 180.0 2 0.200 0.0 3 -torsion 13 13 13 47 1.300 0.0 1 -0.050 180.0 2 0.200 0.0 3 - - - ######################################## - ## ## - ## Atomic Partial Charge Parameters ## - ## ## - ######################################## - - -charge 1 -0.2200 -charge 2 0.2200 -charge 3 0.5500 -charge 4 -0.5000 -charge 5 -0.5800 -charge 6 0.0800 -charge 7 0.4500 -charge 8 0.0000 -charge 9 0.0000 -charge 10 0.0000 -charge 11 0.0000 -charge 12 0.0000 -charge 13 0.0000 -charge 14 0.0000 -charge 15 0.0000 -charge 16 0.0000 -charge 17 0.0000 -charge 18 0.0000 -charge 19 0.0000 -charge 20 -0.7000 -charge 21 0.4350 -charge 22 0.2650 -charge 23 0.2650 -charge 24 -0.4700 -charge 25 -0.4500 -charge 26 -0.4700 -charge 27 -0.3000 -charge 28 0.2350 -charge 29 0.2700 -charge 30 0.1800 -charge 31 0.1800 -charge 32 0.2350 -charge 33 0.2350 -charge 34 0.3000 -charge 35 0.3000 -charge 36 -0.4300 -charge 37 0.2800 -charge 38 0.1500 -charge 39 0.2650 -charge 40 0.2650 -charge 41 -0.5000 -charge 42 0.2500 -charge 43 0.2500 -charge 44 0.5000 -charge 45 -0.2500 -charge 46 0.4200 -charge 47 -0.1400 -charge 48 0.2480 -charge 49 -0.0620 -charge 50 0.1390 -charge 51 -0.4590 -charge 52 0.1600 -charge 53 -0.5000 -charge 54 -0.5700 -charge 55 0.5000 -charge 56 0.2850 -charge 57 0.0000 -charge 58 0.0000 -charge 59 0.0000 -charge 60 0.0000 -charge 61 0.0000 -charge 62 0.0000 -charge 63 -0.8340 -charge 64 0.4170 -charge 65 0.0000 -charge 66 0.5200 -charge 67 -1.0400 -charge 68 -0.8220 -charge 69 0.4110 -charge 70 0.0000 -charge 71 0.5110 -charge 72 -1.0220 -charge 73 0.0000 -charge 74 0.2410 -charge 75 -0.2410 -charge 76 -0.8200 -charge 77 0.4100 -charge 78 -1.0200 -charge 79 0.3400 -charge 80 -0.1800 -charge 81 -0.1200 -charge 82 -0.0600 -charge 83 -0.2400 -charge 84 0.0000 -charge 85 0.0600 -charge 86 0.0000 -charge 87 -0.1150 -charge 88 -0.2300 -charge 89 0.1150 -charge 90 -0.1150 -charge 91 0.1150 -charge 92 0.0000 -charge 93 -0.0650 -charge 94 -0.0050 -charge 95 -0.1150 -charge 96 -0.6830 -charge 97 0.4180 -charge 98 0.0400 -charge 99 0.1450 -charge 100 0.2050 -charge 101 0.2650 -charge 102 0.1263 -charge 103 0.5323 -charge 104 -0.6351 -charge 105 0.4286 -charge 106 -0.2057 -charge 107 0.0825 -charge 108 0.1500 -charge 109 -0.5850 -charge 110 0.4350 -charge 111 -0.7000 -charge 112 0.4350 -charge 113 -0.7300 -charge 114 0.4650 -charge 115 0.1450 -charge 116 0.2050 -charge 117 0.2650 -charge 118 0.0600 -charge 119 -0.1700 -charge 120 0.0000 -charge 121 -0.2850 -charge 122 -0.4000 -charge 123 0.1100 -charge 124 0.1400 -charge 125 0.1700 -charge 126 0.2000 -charge 127 0.0300 -charge 128 -0.4000 -charge 129 -0.7000 -charge 130 0.4350 -charge 131 0.2000 -charge 132 0.1000 -charge 133 0.2650 -charge 134 0.1000 -charge 135 0.3000 -charge 136 0.1000 -charge 137 0.3650 -charge 138 0.1000 -charge 139 0.4000 -charge 140 0.4650 -charge 141 0.0850 -charge 142 -0.3350 -charge 143 -0.4700 -charge 144 -0.4350 -charge 145 -0.2175 -charge 146 0.1550 -charge 147 0.2350 -charge 148 0.0600 -charge 149 0.1200 -charge 150 0.1800 -charge 151 0.0375 -charge 152 0.0975 -charge 153 0.1575 -charge 154 0.2175 -charge 155 0.0375 -charge 156 0.0975 -charge 157 0.1575 -charge 158 0.2175 -charge 159 0.0000 -charge 160 0.2000 -charge 161 0.2600 -charge 162 0.3200 -charge 163 -0.0550 -charge 164 -0.3200 -charge 165 0.0800 -charge 166 0.1400 -charge 167 0.2000 -charge 168 -0.1200 -charge 169 0.0050 -charge 170 0.1025 -charge 171 0.1400 -charge 172 0.2000 -charge 173 0.7000 -charge 174 0.5650 -charge 175 0.5850 -charge 176 0.6150 -charge 177 0.5000 -charge 178 -0.5000 -charge 179 -0.7600 -charge 180 -0.5000 -charge 181 -0.1400 -charge 182 0.3800 -charge 183 0.3000 -charge 184 0.0200 -charge 185 -0.1100 -charge 186 0.0800 -charge 187 -0.0500 -charge 188 0.0100 -charge 189 0.1420 -charge 190 -0.3900 -charge 191 -0.5420 -charge 192 0.3330 -charge 193 -0.4900 -charge 194 0.4200 -charge 195 -0.4200 -charge 196 0.3700 -charge 197 0.0600 -charge 198 -0.1200 -charge 199 -0.0600 -charge 200 0.0000 -charge 201 0.0600 -charge 202 0.0350 -charge 203 0.3950 -charge 204 -0.4300 -charge 205 0.1800 -charge 206 -0.1800 -charge 207 -0.3850 -charge 208 0.0850 -charge 209 0.5200 -charge 210 -0.4400 -charge 211 -0.5300 -charge 212 0.4500 -charge 213 0.7000 -charge 214 -0.8000 -charge 215 -0.2800 -charge 216 -0.2200 -charge 217 -0.1600 -charge 218 -0.1000 -charge 219 0.4500 -charge 220 -0.4500 -charge 221 0.0000 -charge 222 0.4700 -charge 223 -0.4700 -charge 224 0.0600 -charge 225 0.0400 -charge 226 -0.0200 -charge 227 0.1000 -charge 228 -0.0900 -charge 229 -0.4000 -charge 230 -0.3000 -charge 231 0.0000 -charge 232 0.3500 -charge 233 0.3300 -charge 234 0.1300 -charge 235 0.1900 -charge 236 0.2500 -charge 237 0.3100 -charge 238 0.2300 -charge 239 0.1700 -charge 240 0.1100 -charge 241 0.0900 -charge 242 0.1500 -charge 243 -0.8000 -charge 244 0.4600 -charge 245 0.6400 -charge 246 -0.7000 -charge 247 0.4400 -charge 248 0.2000 -charge 249 -0.1100 -charge 250 0.1900 -charge 251 -0.0500 -charge 252 -0.2000 -charge 253 0.3100 -charge 254 -0.4600 -charge 255 0.3600 -charge 256 -0.8500 -charge 257 0.3700 -charge 258 -0.1500 -charge 259 0.1000 -charge 260 -0.0400 -charge 261 0.1000 -charge 262 -0.6000 -charge 263 0.5000 -charge 264 -0.5100 -charge 265 0.4500 -charge 266 -0.0700 -charge 267 0.0800 -charge 268 0.4100 -charge 269 -0.4000 -charge 270 0.3600 -charge 271 -0.4200 -charge 272 0.1000 -charge 273 0.1000 -charge 274 -0.1400 -charge 275 0.0800 -charge 276 -0.5600 -charge 277 0.5500 -charge 278 -0.5400 -charge 279 0.4600 -charge 280 -0.0600 -charge 281 0.1000 -charge 282 0.3800 -charge 283 -0.4800 -charge 284 -0.7900 -charge 285 0.3850 -charge 286 0.3550 -charge 287 0.1000 -charge 288 0.1000 -charge 289 -0.5300 -charge 290 0.2200 -charge 291 -0.5500 -charge 292 0.3800 -charge 293 0.1500 -charge 294 0.4400 -charge 295 -0.4900 -charge 296 0.2000 -charge 297 -0.5000 -charge 298 0.2000 -charge 299 -0.8100 -charge 300 0.3850 -charge 301 0.3550 -charge 302 0.2000 -charge 303 0.3500 -charge 304 -0.5600 -charge 305 0.4600 -charge 306 -0.5100 -charge 307 0.3400 -charge 308 0.1200 -charge 309 0.5200 -charge 310 0.3800 -charge 311 -0.8000 -charge 312 0.4000 -charge 313 -0.5100 -charge 314 -0.0100 -charge 315 0.1200 -charge 316 -0.0100 -charge 317 0.1400 -charge 318 -0.0100 -charge 319 0.1300 -charge 320 -0.6400 -charge 321 0.6500 -charge 322 -0.7400 -charge 323 0.6600 -charge 324 -0.0600 -charge 325 0.1000 -charge 326 0.4900 -charge 327 -0.3000 -charge 328 0.4800 -charge 329 -0.8100 -charge 330 0.4600 -charge 331 0.4300 -charge 332 0.1400 -charge 333 0.1400 -charge 334 0.0100 -charge 335 0.1600 -charge 336 0.7800 -charge 337 -0.6600 -charge 338 -0.4300 -charge 339 0.2000 -charge 340 0.1800 -charge 341 -0.0600 -charge 342 0.1200 -charge 343 -1.0000 -charge 344 -1.0000 -charge 345 -1.0000 -charge 346 -1.0000 -charge 347 1.0000 -charge 348 1.0000 -charge 349 1.0000 -charge 350 1.0000 -charge 351 1.0000 -charge 352 1.0000 -charge 353 2.0000 -charge 354 2.0000 -charge 355 2.0000 -charge 356 2.0000 -charge 357 -0.4000 -charge 358 0.1000 -charge 359 -0.9000 -charge 360 -0.2000 -charge 361 0.0600 -charge 362 -0.9800 -charge 363 -1.0700 -charge 364 0.1900 -charge 365 0.5100 -charge 366 -0.8200 -charge 367 -0.3000 -charge 368 0.0700 -charge 369 -1.3100 -charge 370 0.4000 -charge 371 -0.4000 -charge 372 0.0800 -charge 373 0.0000 -charge 374 0.0700 -charge 375 -0.9800 -charge 376 -1.3000 -charge 377 0.3000 -charge 378 2.5000 -charge 379 -0.2500 -charge 380 -0.8650 -charge 381 1.6200 -charge 382 -0.9200 -charge 383 -0.6000 -charge 384 0.3000 -charge 385 -0.0300 -charge 386 1.9200 -charge 387 -1.1200 -charge 388 -0.7000 -charge 389 0.4400 -charge 390 -0.1000 -charge 391 1.6200 -charge 392 -0.9700 -charge 393 -0.6300 -charge 394 0.2800 -charge 395 -0.0200 -charge 396 -0.5100 -charge 397 0.0800 -charge 398 -0.1400 -charge 399 0.3200 -charge 400 0.0200 -charge 401 -0.0400 -charge 402 -0.4700 -charge 403 0.1200 -charge 404 0.1400 -charge 405 0.2400 -charge 406 0.5100 -charge 407 -0.4300 -charge 408 -0.3300 -charge 409 0.1600 -charge 410 0.0300 -charge 411 0.6350 -charge 412 0.6250 -charge 413 0.1350 -charge 414 -0.2150 -charge 415 1.4800 -charge 416 -0.6800 -charge 417 -0.5400 -charge 418 0.1800 -charge 419 -1.0000 -charge 420 0.4400 -charge 421 -0.8000 -charge 422 0.4100 -charge 423 0.1800 -charge 424 0.0300 -charge 425 0.3900 -charge 426 -0.0600 -charge 427 -0.1800 -charge 428 0.0600 -charge 429 0.0000 -charge 430 0.0300 -charge 431 0.1900 -charge 432 0.2200 -charge 433 0.2500 -charge 434 1.3740 -charge 435 -0.6870 -charge 436 0.2450 -charge 437 0.1300 -charge 438 -0.4200 -charge 439 -0.0350 -charge 440 0.0250 -charge 441 0.0750 -charge 442 -0.0550 -charge 443 0.1300 -charge 444 -0.5700 -charge 445 0.4200 -charge 446 -0.0050 -charge 447 0.2950 -charge 448 -0.0150 -charge 449 0.0150 -charge 450 0.3850 -charge 451 0.2150 -charge 452 -0.4900 -charge 453 -0.5400 -charge 454 0.4600 -charge 455 -0.1150 -charge 456 0.0550 -charge 457 0.1150 -charge 458 -0.0300 -charge 459 0.0850 -charge 460 0.0000 -charge 461 -0.6780 -charge 462 0.4730 -charge 463 -0.4470 -charge 464 0.2270 -charge 465 0.0120 -charge 466 0.1550 -charge 467 0.0650 -charge 468 -0.4680 -charge 469 0.1920 -charge 470 0.0420 -charge 471 -0.8390 -charge 472 0.8740 -charge 473 0.6530 -charge 474 -0.6890 -charge 475 -0.0320 -charge 476 0.0110 -charge 477 0.1970 -charge 478 -0.3310 -charge 479 0.3780 -charge 480 -0.1600 -charge 481 -0.0090 -charge 482 0.1220 -charge 483 -0.2390 -charge 484 -0.1630 -charge 485 -0.1490 -charge 486 0.3170 -charge 487 0.1550 -charge 488 0.1180 -charge 489 -0.0590 -charge 490 -0.4910 -charge 491 0.2460 -charge 492 -0.3200 -charge 493 -0.0340 -charge 494 0.3010 -charge 495 0.0720 -charge 496 0.1500 -charge 497 0.1350 -charge 498 -0.2570 -charge 499 0.2750 -charge 500 -0.5630 -charge 501 0.1850 -charge 502 -0.2860 -charge 503 0.3060 -charge 504 0.0780 -charge 505 0.0750 -charge 506 0.1870 -charge 507 -0.1900 -charge 508 -0.0190 -charge 509 -0.1540 -charge 510 0.1420 -charge 511 0.1260 -charge 512 -0.2570 -charge 513 0.5110 -charge 514 -0.5900 -charge 515 0.1690 -charge 516 -0.1480 -charge 517 0.0430 -charge 518 0.0910 -charge 519 0.1810 -charge 520 -0.1220 -charge 521 -0.4130 -charge 522 0.4050 -charge 523 -0.4550 -charge 524 0.2500 -charge 525 0.0530 -charge 526 0.1840 -charge 527 0.0980 -charge 528 -0.5000 -charge 529 0.0010 -charge 530 -0.3900 -charge 531 -0.2700 -charge 532 -0.1270 -charge 533 -0.1080 -charge 534 -0.2580 -charge 535 0.2200 -charge 536 0.2250 -charge 537 0.3760 -charge 538 0.1470 -charge 539 0.1720 -charge 540 0.1550 -charge 541 0.1070 -charge 542 0.1100 -charge 543 0.1400 -charge 544 -0.6940 -charge 545 0.4250 -charge 546 -0.3590 -charge 547 -0.0080 -charge 548 -0.1970 -charge 549 -0.1120 -charge 550 -0.0700 -charge 551 -0.3070 -charge 552 0.5630 -charge 553 -0.0510 -charge 554 0.0280 -charge 555 0.1460 -charge 556 0.1190 -charge 557 0.1330 -charge 558 0.1130 -charge 559 0.1140 -charge 560 0.1570 -charge 561 -0.7600 -charge 562 0.6790 -charge 563 -0.7880 -charge 564 0.7360 -charge 565 0.0380 -charge 566 0.3430 -charge 567 -0.6420 -charge 568 0.4520 -charge 569 -0.6820 -charge 570 0.0240 -charge 571 0.1010 -charge 572 0.0860 -charge 573 0.4130 -charge 574 -0.0300 -charge 575 0.2420 -charge 576 -0.5150 -charge 577 0.2280 -charge 578 -0.2990 -charge 579 0.1010 -charge 580 0.0680 -charge 581 0.2050 -charge 582 -0.9510 -charge 583 0.9650 -charge 584 -0.0140 -charge 585 0.1300 -charge 586 0.0520 -charge 587 -0.5990 -charge 588 0.3920 -charge 589 -0.3480 -charge 590 0.0200 -charge 591 -0.0420 -charge 592 0.3470 -charge 593 -0.1960 -charge 594 0.0320 -charge 595 0.1460 -charge 596 0.1080 -charge 597 0.1400 -charge 598 0.1220 -charge 599 0.1660 -charge 600 -0.5800 -charge 601 0.1730 -charge 602 -0.3950 -charge 603 -0.1990 -charge 604 0.1180 -charge 605 0.0930 -charge 606 0.2080 -charge 607 0.0980 -charge 608 -0.1390 -charge 609 -0.0790 -charge 610 0.0990 -charge 611 -0.1680 -charge 612 -0.1080 -charge 613 -0.1890 -charge 614 -0.1290 -charge 615 -0.1690 -charge 616 -0.1090 -charge 617 -0.1380 -charge 618 -0.0780 -charge 619 -0.0250 -charge 620 0.0350 -charge 621 -0.0380 -charge 622 0.0220 -charge 623 -0.3340 -charge 624 0.2550 -charge 625 0.5230 -charge 626 0.5000 -charge 627 -0.1400 -charge 628 0.2275 -charge 629 0.1400 -charge 630 -0.0080 -charge 631 0.5880 -charge 632 -0.1030 -charge 633 -0.3320 -charge 634 0.0400 -charge 635 0.3420 -charge 636 -0.0500 -charge 637 -0.2050 -charge 638 3.0000 -charge 639 4.0000 -charge 640 3.0000 -charge 641 0.6190 -charge 642 -0.3950 -charge 643 0.1740 -charge 644 3.0000 -charge 645 3.0000 -charge 646 3.0000 -charge 647 3.0000 -charge 648 3.0000 -charge 649 -0.3440 -charge 650 -0.6280 -charge 651 0.2000 -charge 652 -0.1200 -charge 653 -0.0600 -charge 654 0.0000 -charge 655 -0.2300 -charge 656 0.0300 -charge 657 -0.0990 -charge 658 0.0990 -charge 659 0.2200 -charge 660 -0.2200 -charge 661 0.1300 -charge 662 -0.1300 -charge 663 -0.2200 -charge 664 0.2200 -charge 665 0.1500 -charge 666 0.4500 -charge 667 -0.2000 -charge 668 0.2000 -charge 669 -0.2000 -charge 670 0.2000 -charge 671 -0.2000 -charge 672 0.1000 -charge 673 -0.1000 -charge 674 0.0550 -charge 675 -0.2200 -charge 676 0.0650 -charge 677 0.0130 -charge 678 -0.1060 -charge 679 -0.0900 -charge 680 -0.1190 -charge 681 0.1410 -charge 682 0.1290 -charge 683 0.8270 -charge 684 -0.8850 -charge 685 0.4260 -charge 686 0.4650 -charge 687 0.1190 -charge 688 -0.0200 -charge 689 0.0400 -charge 690 -0.6200 -charge 691 -0.7850 -charge 692 -0.7850 -charge 693 0.5500 -charge 694 -0.5600 -charge 695 0.4600 -charge 696 -0.0800 -charge 697 -0.0200 -charge 698 0.0400 -charge 699 0.1000 -charge 700 0.0600 -charge 701 0.5400 -charge 702 -0.3700 -charge 703 0.0200 -charge 704 0.0600 -charge 705 0.0800 -charge 706 0.1400 -charge 707 0.2000 -charge 708 0.6500 -charge 709 0.0900 -charge 710 0.0350 -charge 711 -0.9000 -charge 712 -0.5000 -charge 713 0.8600 -charge 714 -0.4500 -charge 715 0.2100 -charge 716 0.1600 -charge 717 -0.1000 -charge 718 0.0300 -charge 719 0.0300 -charge 720 0.0600 -charge 721 -0.7800 -charge 722 0.9684 -charge 723 -0.5081 -charge 724 -0.0080 -charge 725 0.1720 -charge 726 1.3400 -charge 727 -0.3900 -charge 728 0.7940 -charge 729 -0.5980 -charge 730 -0.9000 -charge 731 -0.7800 -charge 732 -0.6300 -charge 733 0.0000 -charge 734 0.0200 -charge 735 0.0300 -charge 736 0.0600 -charge 737 0.0800 -charge 738 0.0900 -charge 739 0.3600 -charge 740 0.3800 -charge 741 0.0600 -charge 742 0.1200 -charge 743 0.1800 -charge 744 0.1400 -charge 745 0.1500 -charge 746 0.1800 -charge 747 0.2000 -charge 748 0.2100 -charge 749 0.1150 -charge 750 0.1750 -charge 751 0.2350 -charge 752 0.1950 -charge 753 0.1525 -charge 754 0.1350 -charge 755 -0.2100 -charge 756 0.2000 -charge 757 0.0100 -charge 758 0.0100 -charge 759 0.0100 -charge 760 0.0600 -charge 761 0.4500 -charge 762 0.4800 -charge 763 0.5100 -charge 764 -0.6550 -charge 765 0.3900 -charge 766 -0.5000 -charge 767 -0.5600 -charge 768 -0.6000 -charge 769 0.0000 -charge 770 -0.1000 -charge 771 0.2900 -charge 772 0.0900 -charge 773 0.1500 -charge 774 0.2100 -charge 775 0.2700 -charge 776 0.0960 -charge 777 -0.0390 -charge 778 0.0270 -charge 779 0.0110 -charge 780 0.0740 -charge 781 -0.0290 -charge 782 0.7000 -charge 783 -0.3520 -charge 784 -0.7090 -charge 785 0.3170 -charge 786 -0.2200 -charge 787 0.0200 -charge 788 0.1000 -charge 789 0.1200 -charge 790 0.2200 -charge 791 0.3600 -charge 792 0.2400 -charge 793 0.1200 -charge 794 0.4800 -charge 795 -0.1200 -charge 796 0.2500 -charge 797 0.1500 -charge 798 -0.0800 -charge 799 -0.1060 -charge 800 -0.2000 -charge 801 -0.0060 -charge 802 0.1030 -charge 803 0.0970 -charge 804 0.2000 -charge 805 -0.2000 -charge 806 -0.0060 -charge 807 0.1030 -charge 808 0.0970 -charge 809 0.2000 -charge 810 -0.0800 -charge 811 -0.0800 -charge 812 -0.0800 -charge 813 0.1000 -charge 814 -0.2500 -charge 815 0.6000 -charge 816 -0.1500 -charge 817 -0.0250 -charge 818 -0.0450 -charge 819 0.1450 -charge 820 0.8880 -charge 821 1.0030 -charge 822 -0.6580 -charge 823 -0.6340 -charge 824 0.4110 -charge 825 -0.4420 -charge 826 0.4350 -charge 827 0.2250 -charge 828 0.2550 -charge 829 -0.0340 -charge 830 0.0030 -charge 831 0.3000 -charge 832 -0.0400 -charge 833 -0.0575 -charge 834 2.0000 -charge 835 -0.0700 -charge 836 0.0300 -charge 837 0.1300 -charge 838 -0.1300 -charge 839 0.1000 -charge 840 -0.6850 -charge 841 0.1550 -charge 842 -0.1000 -charge 843 -0.4270 -charge 844 0.2180 -charge 845 0.6000 -charge 846 -0.6000 -charge 847 -0.3600 -charge 848 0.0000 -charge 849 0.0600 -charge 850 0.1200 -charge 851 0.1800 -charge 852 0.0600 -charge 853 0.5700 -charge 854 -0.5700 -charge 855 0.0000 -charge 856 0.0200 -charge 857 -0.0400 -charge 858 0.0000 -charge 859 0.0600 -charge 860 -0.0700 -charge 861 -0.1400 -charge 862 0.1700 -charge 863 0.1100 -charge 864 0.1500 -charge 865 0.1700 -charge 866 1.0000 -charge 867 0.8500 -charge 868 0.7000 -charge 869 0.5500 -charge 870 -0.1000 -charge 871 -0.4300 -charge 872 -0.3700 -charge 873 -0.3100 -charge 874 -0.2500 -charge 875 -1.0000 -charge 876 -1.0000 -charge 877 -1.0000 -charge 878 -1.0000 -charge 879 1.0000 -charge 880 1.0000 -charge 881 1.0000 -charge 882 1.0000 -charge 883 1.0000 -charge 884 2.0000 -charge 885 2.0000 -charge 886 2.0000 -charge 887 2.0000 -charge 888 -0.0500 -charge 889 0.0500 -charge 890 0.1500 -charge 891 0.2500 -charge 892 0.1000 -charge 893 0.1150 -charge 894 0.1350 -charge 895 0.0150 -charge 896 0.1550 -charge 897 0.0000 -charge 898 -0.1150 -charge 899 0.1500 -charge 900 -0.2500 -charge 901 -0.1000 -charge 902 0.0500 -charge 903 -0.1000 -charge 904 0.2000 -charge 905 -0.2500 -charge 906 0.0880 - - - ######################################## - ## ## - ## Biopolymer Atom Type Conversions ## - ## ## - ######################################## - - -biotype 1 N "Glycine" 180 -biotype 2 CA "Glycine" 165 -biotype 3 C "Glycine" 177 -biotype 4 HN "Glycine" 183 -biotype 5 O "Glycine" 178 -biotype 6 HA "Glycine" 85 -biotype 7 N "Alanine" 180 -biotype 8 CA "Alanine" 166 -biotype 9 C "Alanine" 177 -biotype 10 HN "Alanine" 183 -biotype 11 O "Alanine" 178 -biotype 12 HA "Alanine" 85 -biotype 13 CB "Alanine" 80 -biotype 14 HB "Alanine" 85 -biotype 15 N "Valine" 180 -biotype 16 CA "Valine" 166 -biotype 17 C "Valine" 177 -biotype 18 HN "Valine" 183 -biotype 19 O "Valine" 178 -biotype 20 HA "Valine" 85 -biotype 21 CB "Valine" 82 -biotype 22 HB "Valine" 85 -biotype 23 CG1 "Valine" 80 -biotype 24 HG1 "Valine" 85 -biotype 25 CG2 "Valine" 80 -biotype 26 HG2 "Valine" 85 -biotype 27 N "Leucine" 180 -biotype 28 CA "Leucine" 166 -biotype 29 C "Leucine" 177 -biotype 30 HN "Leucine" 183 -biotype 31 O "Leucine" 178 -biotype 32 HA "Leucine" 85 -biotype 33 CB "Leucine" 81 -biotype 34 HB "Leucine" 85 -biotype 35 CG "Leucine" 82 -biotype 36 HG "Leucine" 85 -biotype 37 CD1 "Leucine" 80 -biotype 38 HD1 "Leucine" 85 -biotype 39 CD2 "Leucine" 80 -biotype 40 HD2 "Leucine" 85 -biotype 41 N "Isoleucine" 180 -biotype 42 CA "Isoleucine" 166 -biotype 43 C "Isoleucine" 177 -biotype 44 HN "Isoleucine" 183 -biotype 45 O "Isoleucine" 178 -biotype 46 HA "Isoleucine" 85 -biotype 47 CB "Isoleucine" 82 -biotype 48 HB "Isoleucine" 85 -biotype 49 CG1 "Isoleucine" 80 -biotype 50 HG1 "Isoleucine" 85 -biotype 51 CG2 "Isoleucine" 81 -biotype 52 HG2 "Isoleucine" 85 -biotype 53 CD "Isoleucine" 80 -biotype 54 HD "Isoleucine" 85 -biotype 55 N "Serine" 180 -biotype 56 CA "Serine" 166 -biotype 57 C "Serine" 177 -biotype 58 HN "Serine" 183 -biotype 59 O "Serine" 178 -biotype 60 HA "Serine" 85 -biotype 61 CB "Serine" 99 -biotype 62 HB "Serine" 85 -biotype 63 OG "Serine" 96 -biotype 64 HG "Serine" 97 -biotype 65 N "Threonine" 180 -biotype 66 CA "Threonine" 166 -biotype 67 C "Threonine" 177 -biotype 68 HN "Threonine" 183 -biotype 69 O "Threonine" 178 -biotype 70 HA "Threonine" 85 -biotype 71 CB "Threonine" 100 -biotype 72 HB "Threonine" 85 -biotype 73 OG1 "Threonine" 96 -biotype 74 HG1 "Threonine" 97 -biotype 75 CG2 "Threonine" 80 -biotype 76 HG2 "Threonine" 85 -biotype 77 N "Cysteine (SH)" 180 -biotype 78 CA "Cysteine (SH)" 166 -biotype 79 C "Cysteine (SH)" 177 -biotype 80 HN "Cysteine (SH)" 183 -biotype 81 O "Cysteine (SH)" 178 -biotype 82 HA "Cysteine (SH)" 85 -biotype 83 CB "Cysteine (SH)" 148 -biotype 84 HB "Cysteine (SH)" 85 -biotype 85 SG "Cysteine (SH)" 142 -biotype 86 HG "Cysteine (SH)" 146 -biotype 87 N "Cystine (SS)" 180 -biotype 88 CA "Cystine (SS)" 166 -biotype 89 C "Cystine (SS)" 177 -biotype 90 HN "Cystine (SS)" 183 -biotype 91 O "Cystine (SS)" 178 -biotype 92 HA "Cystine (SS)" 85 -biotype 93 CB "Cystine (SS)" 156 -biotype 94 HB "Cystine (SS)" 85 -biotype 95 SG "Cystine (SS)" 145 -biotype 96 N "Cysteine (S-)" -1 -biotype 97 CA "Cysteine (S-)" -1 -biotype 98 C "Cysteine (S-)" -1 -biotype 99 HN "Cysteine (S-)" -1 -biotype 100 O "Cysteine (S-)" -1 -biotype 101 HA "Cysteine (S-)" -1 -biotype 102 CB "Cysteine (S-)" -1 -biotype 103 HB "Cysteine (S-)" -1 -biotype 104 SG "Cysteine (S-)" -1 -biotype 105 N "Proline" 181 -biotype 106 CA "Proline" 188 -biotype 107 C "Proline" 177 -biotype 108 O "Proline" 178 -biotype 109 HA "Proline" 85 -biotype 110 CB "Proline" 81 -biotype 111 HB "Proline" 85 -biotype 112 CG "Proline" 81 -biotype 113 HG "Proline" 85 -biotype 114 CD "Proline" 187 -biotype 115 HD "Proline" 85 -biotype 116 N "Phenylalanine" 180 -biotype 117 CA "Phenylalanine" 166 -biotype 118 C "Phenylalanine" 177 -biotype 119 HN "Phenylalanine" 183 -biotype 120 O "Phenylalanine" 178 -biotype 121 HA "Phenylalanine" 85 -biotype 122 CB "Phenylalanine" 94 -biotype 123 HB "Phenylalanine" 85 -biotype 124 CG "Phenylalanine" 90 -biotype 125 CD "Phenylalanine" 90 -biotype 126 HD "Phenylalanine" 91 -biotype 127 CE "Phenylalanine" 90 -biotype 128 HE "Phenylalanine" 91 -biotype 129 CZ "Phenylalanine" 90 -biotype 130 HZ "Phenylalanine" 91 -biotype 131 N "Tyrosine" 180 -biotype 132 CA "Tyrosine" 166 -biotype 133 C "Tyrosine" 177 -biotype 134 HN "Tyrosine" 183 -biotype 135 O "Tyrosine" 178 -biotype 136 HA "Tyrosine" 85 -biotype 137 CB "Tyrosine" 94 -biotype 138 HB "Tyrosine" 85 -biotype 139 CG "Tyrosine" 90 -biotype 140 CD "Tyrosine" 90 -biotype 141 HD "Tyrosine" 91 -biotype 142 CE "Tyrosine" 90 -biotype 143 HE "Tyrosine" 91 -biotype 144 CZ "Tyrosine" 108 -biotype 145 OH "Tyrosine" 109 -biotype 146 HH "Tyrosine" 110 -biotype 147 N "Tyrosine (O-)" -1 -biotype 148 CA "Tyrosine (O-)" -1 -biotype 149 C "Tyrosine (O-)" -1 -biotype 150 HN "Tyrosine (O-)" -1 -biotype 151 O "Tyrosine (O-)" -1 -biotype 152 HA "Tyrosine (O-)" -1 -biotype 153 CB "Tyrosine (O-)" -1 -biotype 154 HB "Tyrosine (O-)" -1 -biotype 155 CG "Tyrosine (O-)" -1 -biotype 156 CD "Tyrosine (O-)" -1 -biotype 157 HD "Tyrosine (O-)" -1 -biotype 158 CE "Tyrosine (O-)" -1 -biotype 159 HE "Tyrosine (O-)" -1 -biotype 160 CZ "Tyrosine (O-)" -1 -biotype 161 OH "Tyrosine (O-)" -1 -biotype 162 N "Tryptophan" 180 -biotype 163 CA "Tryptophan" 166 -biotype 164 C "Tryptophan" 177 -biotype 165 HN "Tryptophan" 183 -biotype 166 O "Tryptophan" 178 -biotype 167 HA "Tryptophan" 85 -biotype 168 CB "Tryptophan" 81 -biotype 169 HB "Tryptophan" 85 -biotype 170 CG "Tryptophan" 441 -biotype 171 CD1 "Tryptophan" 455 -biotype 172 HD1 "Tryptophan" 91 -biotype 173 CD2 "Tryptophan" 442 -biotype 174 NE1 "Tryptophan" 444 -biotype 175 HE1 "Tryptophan" 445 -biotype 176 CE2 "Tryptophan" 443 -biotype 177 CE3 "Tryptophan" 90 -biotype 178 HE3 "Tryptophan" 91 -biotype 179 CZ2 "Tryptophan" 90 -biotype 180 HZ2 "Tryptophan" 91 -biotype 181 CZ3 "Tryptophan" 90 -biotype 182 HZ3 "Tryptophan" 91 -biotype 183 CH2 "Tryptophan" 90 -biotype 184 HH2 "Tryptophan" 91 -biotype 185 N "Histidine (+)" 180 -biotype 186 CA "Histidine (+)" 166 -biotype 187 C "Histidine (+)" 177 -biotype 188 HN "Histidine (+)" 183 -biotype 189 O "Histidine (+)" 178 -biotype 190 HA "Histidine (+)" 85 -biotype 191 CB "Histidine (+)" 446 -biotype 192 HB "Histidine (+)" 85 -biotype 193 CG "Histidine (+)" 451 -biotype 194 ND1 "Histidine (+)" 453 -biotype 195 HD1 "Histidine (+)" 454 -biotype 196 CD2 "Histidine (+)" 451 -biotype 197 HD2 "Histidine (+)" 91 -biotype 198 CE1 "Histidine (+)" 450 -biotype 199 HE1 "Histidine (+)" 91 -biotype 200 NE2 "Histidine (+)" 453 -biotype 201 HE2 "Histidine (+)" 454 -biotype 202 N "Histidine (HD)" 180 -biotype 203 CA "Histidine (HD)" 166 -biotype 204 C "Histidine (HD)" 177 -biotype 205 HN "Histidine (HD)" 183 -biotype 206 O "Histidine (HD)" 178 -biotype 207 HA "Histidine (HD)" 85 -biotype 208 CB "Histidine (HD)" 446 -biotype 209 HB "Histidine (HD)" 85 -biotype 210 CG "Histidine (HD)" 449 -biotype 211 ND1 "Histidine (HD)" 444 -biotype 212 HD1 "Histidine (HD)" 445 -biotype 213 CD2 "Histidine (HD)" 448 -biotype 214 HD2 "Histidine (HD)" 91 -biotype 215 CE1 "Histidine (HD)" 447 -biotype 216 HE1 "Histidine (HD)" 91 -biotype 217 NE2 "Histidine (HD)" 452 -biotype 218 N "Histidine (HE)" 180 -biotype 219 CA "Histidine (HE)" 166 -biotype 220 C "Histidine (HE)" 177 -biotype 221 HN "Histidine (HE)" 183 -biotype 222 O "Histidine (HE)" 178 -biotype 223 HA "Histidine (HE)" 85 -biotype 224 CB "Histidine (HE)" 446 -biotype 225 HB "Histidine (HE)" 85 -biotype 226 CG "Histidine (HE)" 448 -biotype 227 ND1 "Histidine (HE)" 452 -biotype 228 CD2 "Histidine (HE)" 449 -biotype 229 HD2 "Histidine (HE)" 91 -biotype 230 CE1 "Histidine (HE)" 447 -biotype 231 HE1 "Histidine (HE)" 91 -biotype 232 NE2 "Histidine (HE)" 444 -biotype 233 HE2 "Histidine (HE)" 445 -biotype 234 N "Aspartic Acid" 180 -biotype 235 CA "Aspartic Acid" 166 -biotype 236 C "Aspartic Acid" 177 -biotype 237 HN "Aspartic Acid" 183 -biotype 238 O "Aspartic Acid" 178 -biotype 239 HA "Aspartic Acid" 85 -biotype 240 CB "Aspartic Acid" 216 -biotype 241 HB "Aspartic Acid" 85 -biotype 242 CG "Aspartic Acid" 213 -biotype 243 OD "Aspartic Acid" 214 -biotype 244 N "Aspartic Acid (COOH)" -1 -biotype 245 CA "Aspartic Acid (COOH)" -1 -biotype 246 C "Aspartic Acid (COOH)" -1 -biotype 247 HN "Aspartic Acid (COOH)" -1 -biotype 248 O "Aspartic Acid (COOH)" -1 -biotype 249 HA "Aspartic Acid (COOH)" -1 -biotype 250 CB "Aspartic Acid (COOH)" -1 -biotype 251 HB "Aspartic Acid (COOH)" -1 -biotype 252 CG "Aspartic Acid (COOH)" -1 -biotype 253 OD1 "Aspartic Acid (COOH)" -1 -biotype 254 OD2 "Aspartic Acid (COOH)" -1 -biotype 255 HD2 "Aspartic Acid (COOH)" -1 -biotype 256 N "Asparagine" 180 -biotype 257 CA "Asparagine" 166 -biotype 258 C "Asparagine" 177 -biotype 259 HN "Asparagine" 183 -biotype 260 O "Asparagine" 178 -biotype 261 HA "Asparagine" 85 -biotype 262 CB "Asparagine" 81 -biotype 263 HB "Asparagine" 85 -biotype 264 CG "Asparagine" 177 -biotype 265 OD1 "Asparagine" 178 -biotype 266 ND2 "Asparagine" 179 -biotype 267 HD2 "Asparagine" 182 -biotype 268 N "Glutamic Acid" 180 -biotype 269 CA "Glutamic Acid" 166 -biotype 270 C "Glutamic Acid" 177 -biotype 271 HN "Glutamic Acid" 183 -biotype 272 O "Glutamic Acid" 178 -biotype 273 HA "Glutamic Acid" 85 -biotype 274 CB "Glutamic Acid" 81 -biotype 275 HB "Glutamic Acid" 85 -biotype 276 CG "Glutamic Acid" 216 -biotype 277 HG "Glutamic Acid" 85 -biotype 278 CD "Glutamic Acid" 213 -biotype 279 OE "Glutamic Acid" 214 -biotype 280 N "Glutamic Acid (COOH)" -1 -biotype 281 CA "Glutamic Acid (COOH)" -1 -biotype 282 C "Glutamic Acid (COOH)" -1 -biotype 283 HN "Glutamic Acid (COOH)" -1 -biotype 284 O "Glutamic Acid (COOH)" -1 -biotype 285 HA "Glutamic Acid (COOH)" -1 -biotype 286 CB "Glutamic Acid (COOH)" -1 -biotype 287 HB "Glutamic Acid (COOH)" -1 -biotype 288 CG "Glutamic Acid (COOH)" -1 -biotype 289 HG "Glutamic Acid (COOH)" -1 -biotype 290 CD "Glutamic Acid (COOH)" -1 -biotype 291 OE1 "Glutamic Acid (COOH)" -1 -biotype 292 OE2 "Glutamic Acid (COOH)" -1 -biotype 293 HE2 "Glutamic Acid (COOH)" -1 -biotype 294 N "Glutamine" 180 -biotype 295 CA "Glutamine" 166 -biotype 296 C "Glutamine" 177 -biotype 297 HN "Glutamine" 183 -biotype 298 O "Glutamine" 178 -biotype 299 HA "Glutamine" 85 -biotype 300 CB "Glutamine" 81 -biotype 301 HB "Glutamine" 85 -biotype 302 CG "Glutamine" 81 -biotype 303 HG "Glutamine" 85 -biotype 304 CD "Glutamine" 177 -biotype 305 OE1 "Glutamine" 178 -biotype 306 NE2 "Glutamine" 179 -biotype 307 HE2 "Glutamine" 182 -biotype 308 N "Methionine" 180 -biotype 309 CA "Methionine" 166 -biotype 310 C "Methionine" 177 -biotype 311 HN "Methionine" 183 -biotype 312 O "Methionine" 178 -biotype 313 HA "Methionine" 85 -biotype 314 CB "Methionine" 81 -biotype 315 HB "Methionine" 85 -biotype 316 CG "Methionine" 152 -biotype 317 HG "Methionine" 85 -biotype 318 SD "Methionine" 144 -biotype 319 CE "Methionine" 151 -biotype 320 HE "Methionine" 85 -biotype 321 N "Lysine" 180 -biotype 322 CA "Lysine" 166 -biotype 323 C "Lysine" 177 -biotype 324 HN "Lysine" 183 -biotype 325 O "Lysine" 178 -biotype 326 HA "Lysine" 85 -biotype 327 CB "Lysine" 81 -biotype 328 HB "Lysine" 85 -biotype 329 CG "Lysine" 81 -biotype 330 HG "Lysine" 85 -biotype 331 CD "Lysine" 81 -biotype 332 HD "Lysine" 85 -biotype 333 CE "Lysine" 235 -biotype 334 HE "Lysine" 85 -biotype 335 NZ "Lysine" 230 -biotype 336 HZ "Lysine" 233 -biotype 337 N "Lysine (NH2)" -1 -biotype 338 CA "Lysine (NH2)" -1 -biotype 339 C "Lysine (NH2)" -1 -biotype 340 HN "Lysine (NH2)" -1 -biotype 341 O "Lysine (NH2)" -1 -biotype 342 HA "Lysine (NH2)" -1 -biotype 343 CB "Lysine (NH2)" -1 -biotype 344 HB "Lysine (NH2)" -1 -biotype 345 CG "Lysine (NH2)" -1 -biotype 346 HG "Lysine (NH2)" -1 -biotype 347 CD "Lysine (NH2)" -1 -biotype 348 HD "Lysine (NH2)" -1 -biotype 349 CE "Lysine (NH2)" -1 -biotype 350 HE "Lysine (NH2)" -1 -biotype 351 NZ "Lysine (NH2)" -1 -biotype 352 HZ "Lysine (NH2)" -1 -biotype 353 N "Arginine" 180 -biotype 354 CA "Arginine" 166 -biotype 355 C "Arginine" 177 -biotype 356 HN "Arginine" 183 -biotype 357 O "Arginine" 178 -biotype 358 HA "Arginine" 85 -biotype 359 CB "Arginine" 81 -biotype 360 HB "Arginine" 85 -biotype 361 CG "Arginine" 251 -biotype 362 HG "Arginine" 85 -biotype 363 CD "Arginine" 250 -biotype 364 HD "Arginine" 85 -biotype 365 NE "Arginine" 246 -biotype 366 HE "Arginine" 247 -biotype 367 CZ "Arginine" 245 -biotype 368 NH "Arginine" 243 -biotype 369 HH "Arginine" 244 -biotype 370 N "Ornithine" 180 -biotype 371 CA "Ornithine" 166 -biotype 372 C "Ornithine" 177 -biotype 373 HN "Ornithine" 183 -biotype 374 O "Ornithine" 178 -biotype 375 HA "Ornithine" 85 -biotype 376 CB "Ornithine" 81 -biotype 377 HB "Ornithine" 85 -biotype 378 CG "Ornithine" 81 -biotype 379 HG "Ornithine" 85 -biotype 380 CD "Ornithine" 235 -biotype 381 HD "Ornithine" 85 -biotype 382 NE "Ornithine" 230 -biotype 383 HE "Ornithine" 233 -biotype 384 N "MethylAlanine (AIB)" 180 -biotype 385 CA "MethylAlanine (AIB)" 167 -biotype 386 C "MethylAlanine (AIB)" 177 -biotype 387 HN "MethylAlanine (AIB)" 183 -biotype 388 O "MethylAlanine (AIB)" 178 -biotype 389 CB "MethylAlanine (AIB)" 80 -biotype 390 HB "MethylAlanine (AIB)" 85 -biotype 391 N "Pyroglutamic Acid" 180 -biotype 392 CA "Pyroglutamic Acid" 166 -biotype 393 C "Pyroglutamic Acid" 177 -biotype 394 HN "Pyroglutamic Acid" 183 -biotype 395 O "Pyroglutamic Acid" 178 -biotype 396 HA "Pyroglutamic Acid" 85 -biotype 397 CB "Pyroglutamic Acid" 81 -biotype 398 HB "Pyroglutamic Acid" 85 -biotype 399 CG "Pyroglutamic Acid" 216 -biotype 400 HG "Pyroglutamic Acid" 85 -biotype 401 CD "Pyroglutamic Acid" 177 -biotype 402 OE "Pyroglutamic Acid" 178 -biotype 403 N "N-Terminal GLY" 230 -biotype 404 CA "N-Terminal GLY" 235 -biotype 405 C "N-Terminal GLY" 177 -biotype 406 HN "N-Terminal GLY" 233 -biotype 407 O "N-Terminal GLY" 178 -biotype 408 HA "N-Terminal GLY" 85 -biotype 409 N "N-Terminal ALA" 230 -biotype 410 CA "N-Terminal ALA" 236 -biotype 411 C "N-Terminal ALA" 177 -biotype 412 HN "N-Terminal ALA" 233 -biotype 413 O "N-Terminal ALA" 178 -biotype 414 HA "N-Terminal ALA" 85 -biotype 415 N "N-Terminal VAL" 230 -biotype 416 CA "N-Terminal VAL" 236 -biotype 417 C "N-Terminal VAL" 177 -biotype 418 HN "N-Terminal VAL" 233 -biotype 419 O "N-Terminal VAL" 178 -biotype 420 HA "N-Terminal VAL" 85 -biotype 421 N "N-Terminal LEU" 230 -biotype 422 CA "N-Terminal LEU" 236 -biotype 423 C "N-Terminal LEU" 177 -biotype 424 HN "N-Terminal LEU" 233 -biotype 425 O "N-Terminal LEU" 178 -biotype 426 HA "N-Terminal LEU" 85 -biotype 427 N "N-Terminal ILE" 230 -biotype 428 CA "N-Terminal ILE" 236 -biotype 429 C "N-Terminal ILE" 177 -biotype 430 HN "N-Terminal ILE" 233 -biotype 431 O "N-Terminal ILE" 178 -biotype 432 HA "N-Terminal ILE" 85 -biotype 433 N "N-Terminal SER" 230 -biotype 434 CA "N-Terminal SER" 236 -biotype 435 C "N-Terminal SER" 177 -biotype 436 HN "N-Terminal SER" 233 -biotype 437 O "N-Terminal SER" 178 -biotype 438 HA "N-Terminal SER" 85 -biotype 439 N "N-Terminal THR" 230 -biotype 440 CA "N-Terminal THR" 236 -biotype 441 C "N-Terminal THR" 177 -biotype 442 HN "N-Terminal THR" 233 -biotype 443 O "N-Terminal THR" 178 -biotype 444 HA "N-Terminal THR" 85 -biotype 445 N "N-Terminal CYS (SH)" 230 -biotype 446 CA "N-Terminal CYS (SH)" 236 -biotype 447 C "N-Terminal CYS (SH)" 177 -biotype 448 HN "N-Terminal CYS (SH)" 233 -biotype 449 O "N-Terminal CYS (SH)" 178 -biotype 450 HA "N-Terminal CYS (SH)" 85 -biotype 451 N "N-Terminal CYX (SS)" 230 -biotype 452 CA "N-Terminal CYX (SS)" 236 -biotype 453 C "N-Terminal CYX (SS)" 177 -biotype 454 HN "N-Terminal CYX (SS)" 233 -biotype 455 O "N-Terminal CYX (SS)" 178 -biotype 456 HA "N-Terminal CYX (SS)" 85 -biotype 457 N "N-Terminal CYD (S-)" -1 -biotype 458 CA "N-Terminal CYD (S-)" -1 -biotype 459 C "N-Terminal CYD (S-)" -1 -biotype 460 HN "N-Terminal CYD (S-)" -1 -biotype 461 O "N-Terminal CYD (S-)" -1 -biotype 462 HA "N-Terminal CYD (S-)" -1 -biotype 463 N "N-Terminal PRO" 252 -biotype 464 CA "N-Terminal PRO" 238 -biotype 465 C "N-Terminal PRO" 177 -biotype 466 HN "N-Terminal PRO" 253 -biotype 467 O "N-Terminal PRO" 178 -biotype 468 HA "N-Terminal PRO" 85 -biotype 469 CD "N-Terminal PRO" 239 -biotype 470 HD "N-Terminal PRO" 85 -biotype 471 N "N-Terminal PHE" 230 -biotype 472 CA "N-Terminal PHE" 236 -biotype 473 C "N-Terminal PHE" 177 -biotype 474 HN "N-Terminal PHE" 233 -biotype 475 O "N-Terminal PHE" 178 -biotype 476 HA "N-Terminal PHE" 85 -biotype 477 N "N-Terminal TYR" 230 -biotype 478 CA "N-Terminal TYR" 236 -biotype 479 C "N-Terminal TYR" 177 -biotype 480 HN "N-Terminal TYR" 233 -biotype 481 O "N-Terminal TYR" 178 -biotype 482 HA "N-Terminal TYR" 85 -biotype 483 N "N-Terminal TYD (O-)" -1 -biotype 484 CA "N-Terminal TYD (O-)" -1 -biotype 485 C "N-Terminal TYD (O-)" -1 -biotype 486 HN "N-Terminal TYD (O-)" -1 -biotype 487 O "N-Terminal TYD (O-)" -1 -biotype 488 HA "N-Terminal TYD (O-)" -1 -biotype 489 N "N-Terminal TRP" 230 -biotype 490 CA "N-Terminal TRP" 236 -biotype 491 C "N-Terminal TRP" 177 -biotype 492 HN "N-Terminal TRP" 233 -biotype 493 O "N-Terminal TRP" 178 -biotype 494 HA "N-Terminal TRP" 85 -biotype 495 N "N-Terminal HIS (+)" 230 -biotype 496 CA "N-Terminal HIS (+)" 236 -biotype 497 C "N-Terminal HIS (+)" 177 -biotype 498 HN "N-Terminal HIS (+)" 233 -biotype 499 O "N-Terminal HIS (+)" 178 -biotype 500 HA "N-Terminal HIS (+)" 85 -biotype 501 N "N-Terminal HIS (HD)" 230 -biotype 502 CA "N-Terminal HIS (HD)" 236 -biotype 503 C "N-Terminal HIS (HD)" 177 -biotype 504 HN "N-Terminal HIS (HD)" 233 -biotype 505 O "N-Terminal HIS (HD)" 178 -biotype 506 HA "N-Terminal HIS (HD)" 85 -biotype 507 N "N-Terminal HIS (HE)" 230 -biotype 508 CA "N-Terminal HIS (HE)" 236 -biotype 509 C "N-Terminal HIS (HE)" 177 -biotype 510 HN "N-Terminal HIS (HE)" 233 -biotype 511 O "N-Terminal HIS (HE)" 178 -biotype 512 HA "N-Terminal HIS (HE)" 85 -biotype 513 N "N-Terminal ASP" 230 -biotype 514 CA "N-Terminal ASP" 236 -biotype 515 C "N-Terminal ASP" 177 -biotype 516 HN "N-Terminal ASP" 233 -biotype 517 O "N-Terminal ASP" 178 -biotype 518 HA "N-Terminal ASP" 85 -biotype 519 N "N-Terminal ASH (COOH)" -1 -biotype 520 CA "N-Terminal ASH (COOH)" -1 -biotype 521 C "N-Terminal ASH (COOH)" -1 -biotype 522 HN "N-Terminal ASH (COOH)" -1 -biotype 523 O "N-Terminal ASH (COOH)" -1 -biotype 524 HA "N-Terminal ASH (COOH)" -1 -biotype 525 N "N-Terminal ASN" 230 -biotype 526 CA "N-Terminal ASN" 236 -biotype 527 C "N-Terminal ASN" 177 -biotype 528 HN "N-Terminal ASN" 233 -biotype 529 O "N-Terminal ASN" 178 -biotype 530 HA "N-Terminal ASN" 85 -biotype 531 N "N-Terminal GLU" 230 -biotype 532 CA "N-Terminal GLU" 236 -biotype 533 C "N-Terminal GLU" 177 -biotype 534 HN "N-Terminal GLU" 233 -biotype 535 O "N-Terminal GLU" 178 -biotype 536 HA "N-Terminal GLU" 85 -biotype 537 N "N-Terminal GLH (COOH)" -1 -biotype 538 CA "N-Terminal GLH (COOH)" -1 -biotype 539 C "N-Terminal GLH (COOH)" -1 -biotype 540 HN "N-Terminal GLH (COOH)" -1 -biotype 541 O "N-Terminal GLH (COOH)" -1 -biotype 542 HA "N-Terminal GLH (COOH)" -1 -biotype 543 N "N-Terminal GLN" 230 -biotype 544 CA "N-Terminal GLN" 236 -biotype 545 C "N-Terminal GLN" 177 -biotype 546 HN "N-Terminal GLN" 233 -biotype 547 O "N-Terminal GLN" 178 -biotype 548 HA "N-Terminal GLN" 85 -biotype 549 N "N-Terminal MET" 230 -biotype 550 CA "N-Terminal MET" 236 -biotype 551 C "N-Terminal MET" 177 -biotype 552 HN "N-Terminal MET" 233 -biotype 553 O "N-Terminal MET" 178 -biotype 554 HA "N-Terminal MET" 85 -biotype 555 N "N-Terminal LYS" 230 -biotype 556 CA "N-Terminal LYS" 236 -biotype 557 C "N-Terminal LYS" 177 -biotype 558 HN "N-Terminal LYS" 233 -biotype 559 O "N-Terminal LYS" 178 -biotype 560 HA "N-Terminal LYS" 85 -biotype 561 N "N-Terminal LYD (NH2)" -1 -biotype 562 CA "N-Terminal LYD (NH2)" -1 -biotype 563 C "N-Terminal LYD (NH2)" -1 -biotype 564 HN "N-Terminal LYD (NH2)" -1 -biotype 565 O "N-Terminal LYD (NH2)" -1 -biotype 566 HA "N-Terminal LYD (NH2)" -1 -biotype 567 N "N-Terminal ARG" 230 -biotype 568 CA "N-Terminal ARG" 236 -biotype 569 C "N-Terminal ARG" 177 -biotype 570 HN "N-Terminal ARG" 233 -biotype 571 O "N-Terminal ARG" 178 -biotype 572 HA "N-Terminal ARG" 85 -biotype 573 N "N-Terminal ORN" 230 -biotype 574 CA "N-Terminal ORN" 236 -biotype 575 C "N-Terminal ORN" 177 -biotype 576 HN "N-Terminal ORN" 233 -biotype 577 O "N-Terminal ORN" 178 -biotype 578 HA "N-Terminal ORN" 85 -biotype 579 N "N-Terminal AIB" 230 -biotype 580 CA "N-Terminal AIB" 237 -biotype 581 C "N-Terminal AIB" 177 -biotype 582 HN "N-Terminal AIB" 233 -biotype 583 O "N-Terminal AIB" 178 -biotype 584 N "C-Terminal GLY" 180 -biotype 585 CA "C-Terminal GLY" 226 -biotype 586 C "C-Terminal GLY" 213 -biotype 587 HN "C-Terminal GLY" 183 -biotype 588 OXT "C-Terminal GLY" 214 -biotype 589 HA "C-Terminal GLY" 85 -biotype 590 N "C-Terminal ALA" 180 -biotype 591 CA "C-Terminal ALA" 225 -biotype 592 C "C-Terminal ALA" 213 -biotype 593 HN "C-Terminal ALA" 183 -biotype 594 OXT "C-Terminal ALA" 214 -biotype 595 HA "C-Terminal ALA" 85 -biotype 596 N "C-Terminal VAL" 180 -biotype 597 CA "C-Terminal VAL" 225 -biotype 598 C "C-Terminal VAL" 213 -biotype 599 HN "C-Terminal VAL" 183 -biotype 600 OXT "C-Terminal VAL" 214 -biotype 601 HA "C-Terminal VAL" 85 -biotype 602 N "C-Terminal LEU" 180 -biotype 603 CA "C-Terminal LEU" 225 -biotype 604 C "C-Terminal LEU" 213 -biotype 605 HN "C-Terminal LEU" 183 -biotype 606 OXT "C-Terminal LEU" 214 -biotype 607 HA "C-Terminal LEU" 85 -biotype 608 N "C-Terminal ILE" 180 -biotype 609 CA "C-Terminal ILE" 225 -biotype 610 C "C-Terminal ILE" 213 -biotype 611 HN "C-Terminal ILE" 183 -biotype 612 OXT "C-Terminal ILE" 214 -biotype 613 HA "C-Terminal ILE" 85 -biotype 614 N "C-Terminal SER" 180 -biotype 615 CA "C-Terminal SER" 225 -biotype 616 C "C-Terminal SER" 213 -biotype 617 HN "C-Terminal SER" 183 -biotype 618 OXT "C-Terminal SER" 214 -biotype 619 HA "C-Terminal SER" 85 -biotype 620 N "C-Terminal THR" 180 -biotype 621 CA "C-Terminal THR" 225 -biotype 622 C "C-Terminal THR" 213 -biotype 623 HN "C-Terminal THR" 183 -biotype 624 OXT "C-Terminal THR" 214 -biotype 625 HA "C-Terminal THR" 85 -biotype 626 N "C-Terminal CYS (SH)" 180 -biotype 627 CA "C-Terminal CYS (SH)" 225 -biotype 628 C "C-Terminal CYS (SH)" 213 -biotype 629 HN "C-Terminal CYS (SH)" 183 -biotype 630 OXT "C-Terminal CYS (SH)" 214 -biotype 631 HA "C-Terminal CYS (SH)" 85 -biotype 632 N "C-Terminal CYX (SS)" 180 -biotype 633 CA "C-Terminal CYX (SS)" 225 -biotype 634 C "C-Terminal CYX (SS)" 213 -biotype 635 HN "C-Terminal CYX (SS)" 183 -biotype 636 OXT "C-Terminal CYX (SS)" 214 -biotype 637 HA "C-Terminal CYX (SS)" 85 -biotype 638 N "C-Terminal CYD (S-)" -1 -biotype 639 CA "C-Terminal CYD (S-)" -1 -biotype 640 C "C-Terminal CYD (S-)" -1 -biotype 641 HN "C-Terminal CYD (S-)" -1 -biotype 642 OXT "C-Terminal CYD (S-)" -1 -biotype 643 HA "C-Terminal CYD (S-)" -1 -biotype 644 N "C-Terminal PRO" 181 -biotype 645 CA "C-Terminal PRO" 228 -biotype 646 C "C-Terminal PRO" 213 -biotype 647 OXT "C-Terminal PRO" 214 -biotype 648 HA "C-Terminal PRO" 85 -biotype 649 N "C-Terminal PHE" 180 -biotype 650 CA "C-Terminal PHE" 225 -biotype 651 C "C-Terminal PHE" 213 -biotype 652 HN "C-Terminal PHE" 183 -biotype 653 OXT "C-Terminal PHE" 214 -biotype 654 HA "C-Terminal PHE" 85 -biotype 655 N "C-Terminal TYR" 180 -biotype 656 CA "C-Terminal TYR" 225 -biotype 657 C "C-Terminal TYR" 213 -biotype 658 HN "C-Terminal TYR" 183 -biotype 659 OXT "C-Terminal TYR" 214 -biotype 660 HA "C-Terminal TYR" 85 -biotype 661 N "C-Terminal TYD (O-)" -1 -biotype 662 CA "C-Terminal TYD (O-)" -1 -biotype 663 C "C-Terminal TYD (O-)" -1 -biotype 664 HN "C-Terminal TYD (O-)" -1 -biotype 665 OXT "C-Terminal TYD (O-)" -1 -biotype 666 HA "C-Terminal TYD (O-)" -1 -biotype 667 N "C-Terminal TRP" 180 -biotype 668 CA "C-Terminal TRP" 225 -biotype 669 C "C-Terminal TRP" 213 -biotype 670 HN "C-Terminal TRP" 183 -biotype 671 OXT "C-Terminal TRP" 214 -biotype 672 HA "C-Terminal TRP" 85 -biotype 673 N "C-Terminal HIS (+)" 180 -biotype 674 CA "C-Terminal HIS (+)" 225 -biotype 675 C "C-Terminal HIS (+)" 213 -biotype 676 HN "C-Terminal HIS (+)" 183 -biotype 677 OXT "C-Terminal HIS (+)" 214 -biotype 678 HA "C-Terminal HIS (+)" 85 -biotype 679 N "C-Terminal HIS (HD)" 180 -biotype 680 CA "C-Terminal HIS (HD)" 225 -biotype 681 C "C-Terminal HIS (HD)" 213 -biotype 682 HN "C-Terminal HIS (HD)" 183 -biotype 683 OXT "C-Terminal HIS (HD)" 214 -biotype 684 HA "C-Terminal HIS (HD)" 85 -biotype 685 N "C-Terminal HIS (HE)" 180 -biotype 686 CA "C-Terminal HIS (HE)" 225 -biotype 687 C "C-Terminal HIS (HE)" 213 -biotype 688 HN "C-Terminal HIS (HE)" 183 -biotype 689 OXT "C-Terminal HIS (HE)" 214 -biotype 690 HA "C-Terminal HIS (HE)" 85 -biotype 691 N "C-Terminal ASP" 180 -biotype 692 CA "C-Terminal ASP" 225 -biotype 693 C "C-Terminal ASP" 213 -biotype 694 HN "C-Terminal ASP" 183 -biotype 695 OXT "C-Terminal ASP" 214 -biotype 696 HA "C-Terminal ASP" 85 -biotype 697 N "C-Terminal ASH (COOH)" -1 -biotype 698 CA "C-Terminal ASH (COOH)" -1 -biotype 699 C "C-Terminal ASH (COOH)" -1 -biotype 700 HN "C-Terminal ASH (COOH)" -1 -biotype 701 OXT "C-Terminal ASH (COOH)" -1 -biotype 702 HA "C-Terminal ASH (COOH)" -1 -biotype 703 N "C-Terminal ASN" 180 -biotype 704 CA "C-Terminal ASN" 225 -biotype 705 C "C-Terminal ASN" 213 -biotype 706 HN "C-Terminal ASN" 183 -biotype 707 OXT "C-Terminal ASN" 214 -biotype 708 HA "C-Terminal ASN" 85 -biotype 709 N "C-Terminal GLU" 180 -biotype 710 CA "C-Terminal GLU" 225 -biotype 711 C "C-Terminal GLU" 213 -biotype 712 HN "C-Terminal GLU" 183 -biotype 713 OXT "C-Terminal GLU" 214 -biotype 714 HA "C-Terminal GLU" 85 -biotype 715 N "C-Terminal GLH (COOH)" -1 -biotype 716 CA "C-Terminal GLH (COOH)" -1 -biotype 717 C "C-Terminal GLH (COOH)" -1 -biotype 718 HN "C-Terminal GLH (COOH)" -1 -biotype 719 OXT "C-Terminal GLH (COOH)" -1 -biotype 720 HA "C-Terminal GLH (COOH)" -1 -biotype 721 N "C-Terminal GLN" 180 -biotype 722 CA "C-Terminal GLN" 225 -biotype 723 C "C-Terminal GLN" 213 -biotype 724 HN "C-Terminal GLN" 183 -biotype 725 OXT "C-Terminal GLN" 214 -biotype 726 HA "C-Terminal GLN" 85 -biotype 727 N "C-Terminal MET" 180 -biotype 728 CA "C-Terminal MET" 225 -biotype 729 C "C-Terminal MET" 213 -biotype 730 HN "C-Terminal MET" 183 -biotype 731 OXT "C-Terminal MET" 214 -biotype 732 HA "C-Terminal MET" 85 -biotype 733 N "C-Terminal LYS" 180 -biotype 734 CA "C-Terminal LYS" 225 -biotype 735 C "C-Terminal LYS" 213 -biotype 736 HN "C-Terminal LYS" 183 -biotype 737 OXT "C-Terminal LYS" 214 -biotype 738 HA "C-Terminal LYS" 85 -biotype 739 N "C-Terminal LYD (NH2)" -1 -biotype 740 CA "C-Terminal LYD (NH2)" -1 -biotype 741 C "C-Terminal LYD (NH2)" -1 -biotype 742 HN "C-Terminal LYD (NH2)" -1 -biotype 743 OXT "C-Terminal LYD (NH2)" -1 -biotype 744 HA "C-Terminal LYD (NH2)" -1 -biotype 745 N "C-Terminal ARG" 180 -biotype 746 CA "C-Terminal ARG" 225 -biotype 747 C "C-Terminal ARG" 213 -biotype 748 HN "C-Terminal ARG" 183 -biotype 749 OXT "C-Terminal ARG" 214 -biotype 750 HA "C-Terminal ARG" 85 -biotype 751 N "C-Terminal ORN" 180 -biotype 752 CA "C-Terminal ORN" 225 -biotype 753 C "C-Terminal ORN" 213 -biotype 754 HN "C-Terminal ORN" 183 -biotype 755 OXT "C-Terminal ORN" 214 -biotype 756 HA "C-Terminal ORN" 85 -biotype 757 N "C-Terminal AIB" 180 -biotype 758 CA "C-Terminal AIB" 227 -biotype 759 C "C-Terminal AIB" 213 -biotype 760 HN "C-Terminal AIB" 183 -biotype 761 OXT "C-Terminal AIB" 214 -biotype 762 N "Deprotonated N-Terminus" -1 -biotype 763 H "Deprotonated N-Terminus" -1 -biotype 764 C "Formyl N-Terminus" 177 -biotype 765 H "Formyl N-Terminus" 221 -biotype 766 O "Formyl N-Terminus" 178 -biotype 767 CH3 "Acetyl N-Terminus" 80 -biotype 768 H "Acetyl N-Terminus" 85 -biotype 769 C "Acetyl N-Terminus" 177 -biotype 770 O "Acetyl N-Terminus" 178 -biotype 771 C "Protonated C-Terminus" -1 -biotype 772 O "Protonated C-Terminus" -1 -biotype 773 OH "Protonated C-Terminus" -1 -biotype 774 HO "Protonated C-Terminus" -1 -biotype 775 N "Amide C-Terminus" 179 -biotype 776 HN "Amide C-Terminus" 182 -biotype 777 N "N-MeAmide C-Terminus" 180 -biotype 778 HN "N-MeAmide C-Terminus" 183 -biotype 779 CH3 "N-MeAmide C-Terminus" 184 -biotype 780 H "N-MeAmide C-Terminus" 85 -biotype 2001 O "Water" 63 -biotype 2002 H "Water" 64 -biotype 2003 NA "Sodium Ion" -1 -biotype 2004 K "Potassium Ion" -1 -biotype 2005 MG "Magnesium Ion" -1 -biotype 2006 CA "Calcium Ion" -1 -biotype 2007 CL "Chloride Ion" -1 diff --git a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene/moltemplate_files/system.lt b/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene/moltemplate_files/system.lt deleted file mode 100644 index 49458a5b42..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene/moltemplate_files/system.lt +++ /dev/null @@ -1,28 +0,0 @@ -import "ethylene.lt" # <- defines the "Ethylene" molecule type. -import "benzene.lt" # <- defines the "Benzene" molecule type. - - -# Periodic boundary conditions: -write_once("Data Boundary") { - 0.0 80.00 xlo xhi - 0.0 80.00 ylo yhi - 0.0 80.00 zlo zhi -} - -# Create 1000 ethylenes and 500 benzenes - -ethylenes = new Ethylene[10].move(8.0, 0, 0) - [10].move(0, 8.0, 0) - [10].move(0, 0, 8.0) - -benzenes = new Benzene[10].move(8.0, 0, 0) - [10].move(0, 8.0, 0) - [5].move(0, 0, 16.0) - -# Now shift the positions of all of the benzene molecules, -# to reduce the chance that they overlap with the ethylene molecules. - -benzenes[*][*][*].move(4.0, 4.0, 4.0) - -# Note: There is also an example which shows how to generate the coordinates -# using PACKMOL. (That allows us to omit the coordinates and .move() commands.) diff --git a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene/run.in.npt b/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene/run.in.npt deleted file mode 100644 index 527599ba88..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene/run.in.npt +++ /dev/null @@ -1,58 +0,0 @@ -# PREREQUISITES: -# -# You must use moltemplate.sh to create 3 files: -# system.data system.in.init system.in.settings -# (Follow the instructions in README_setup.sh, -# or run the file as a script using ./README_setup.sh) - -# ------------------------------- Initialization Section -------------------- - -include "system.in.init" - -# ------------------------------- Atom Definition Section ------------------- - -read_data "system.data" - -# OPLSAA atom charges are stored in a separate file. -# Load that file now: - -include "system.in.charges" - -# ------------------------------- Settings Section -------------------------- - -include "system.in.settings" - -# ------------------------------- Run Section ------------------------------- - - -# -- minimization protocol -- - -minimize 1.0e-4 1.0e-6 100000 400000 - -# -- simulation protocol -- - -timestep 1.0 - -print "---------------------------------------------------------------------------" -print "First, use Langevin dynamics to randomize the initial shape of the molecules" -print "(This is not really necessary, but it seems to speed up equilibration.)" -print "---------------------------------------------------------------------------" - -fix fxlan all langevin 300.0 300.0 120 123456 # temp: 300 K -fix fxnph all nph iso 50.0 50.0 1000.0 # pressure: 50 barr -run 2000 -unfix fxlan -unfix fxnph - -print "---------------------------------------------------------------------------" -print "--- Now continue the simulation using a Nose-Hoover Thermostat/Barostat ---" -print "---------------------------------------------------------------------------" -dump 1 all custom 1000 traj_npt.lammpstrj id mol type x y z ix iy iz -# temperature: 300 K, pressure: 50 barr -fix fxnpt all npt temp 300.0 300.0 100.0 iso 50.0 50.0 1000.0 drag 1.0 -thermo 100 -#thermo_modify flush yes - -run 100000 - -write_data system_after_npt.data diff --git a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene/run.in.nvt b/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene/run.in.nvt deleted file mode 100644 index 2f3b81c186..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene/run.in.nvt +++ /dev/null @@ -1,51 +0,0 @@ -# PREREQUISITES: -# -# 1) You must use moltemplate.sh to create 3 files: -# system.data system.in.init system.in.settings -# (Follow the instructions in README_setup.sh, -# or run the file as a script using ./README_setup.sh) -# 2) You must equilibrate the system beforehand using "run.in.npt". -# This will create the file "system_after_npt.data" which this file reads. -# (Note: I have not verified that this equilibration protocol works well.) - -# ------------------------------- Initialization Section -------------------- - -include "system.in.init" - -# ------------------------------- Atom Definition Section ------------------- - -# Read the coordinates generated by an earlier NPT simulation - -read_data "system_after_npt.data" - -# OPLSAA atom charges are stored in a separate file. -# Load that file now: - -include "system.in.charges" - -# ------------------------------- Settings Section -------------------------- - -include "system.in.settings" - - -# (The "write_restart" and "read_restart" commands were buggy in 2012, -# but they should work also. I prefer "write_data" and "read_data".) - -# ------------------------------- Settings Section -------------------------- - -include system.in.settings - -# ------------------------------- Run Section ------------------------------- - -# -- simulation protocol -- - - -timestep 1.0 -dump 1 all custom 5000 traj_nvt.lammpstrj id mol type x y z ix iy iz -fix fxnvt all nvt temp 300.0 300.0 500.0 tchain 1 -thermo 500 -#thermo_modify flush yes - -run 200000 - -write_data system_after_nvt.data diff --git a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/README.TXT b/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/README.TXT deleted file mode 100644 index af95dca522..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/README.TXT +++ /dev/null @@ -1,23 +0,0 @@ - -This is an example of how to use the OPLSAA force-field in LAMMPS - -This example also shows how to use moltemplate in combination with PACKMOL. -(PACKMOL is a useful program for generating atomic coordinates. In this example, - moltemplate.sh is only used to create the topology, force-field and charges, - and PACKMOL generates the coordinates, which moltemplate reads (in "step 1"). - Moltemplate can also be used for generating atomic coordinates, especially - for mixing many small molecules together, as we do in this example. However - I wanted to demonstrate how to combine PACKMOL with moltemplate.sh. - In some other scenarios, such as protein solvation, PACKMOL does a much - better job than moltemplate.) - -As of 2016-11-21, this code has not been tested for accuracy. -(See the WARNING.TXT file.) - -step 1) -To build the files which LAMMPS needs, follow the instructions in: -README_setup.sh - -step 2) -To run LAMMPS with these files, follow these instructions: -README_run.sh diff --git a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/README_run.sh b/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/README_run.sh deleted file mode 100755 index 5f82866644..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/README_run.sh +++ /dev/null @@ -1,34 +0,0 @@ -# --- Running LAMMPS --- -# -# The 2 files "run.in.npt", and "run.in.nvt" are LAMMPS -# input scripts which link to the input scripts and data files -# you hopefully have created earlier with moltemplate.sh: -# system.in.init, system.in.settings, system.data -# If not, carry out the instructions in "README_setup.sh". -# -# -- Instructions: -- -# If "lmp_mpi" is the name of the command you use to invoke lammps, -# then you would run lammps on these files this way: - - -lmp_mpi -i run.in.npt # minimization and simulation at constant pressure -lmp_mpi -i run.in.nvt # minimization and simulation at constant volume - -#(Note: The constant volume simulation lacks pressure equilibration. These are -# completely separate simulations. The results of the constant pressure -# simulation might be ignored when beginning the simulation at constant -# volume. (This is because restart files in LAMMPS don't always work, -# and I was spending a lot of time trying to convince people it was a -# LAMMPS bug, instead of a moltemplate bug, so I disabled restart files.) -# Read the "run.in.nvt" file to find out how to use the "read_restart" -# command to load the results of the pressure-equilibration simulation, -# before beginning a constant-volume run. - - - - - -# If you have compiled the MPI version of lammps, you can run lammps in parallel -#mpirun -np 4 lmp_mpi -i run.in.npt -#mpirun -np 4 lmp_mpi -i run.in.nvt -# (assuming you have 4 processors available) diff --git a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/README_setup.sh b/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/README_setup.sh deleted file mode 100755 index 60daffc2bf..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/README_setup.sh +++ /dev/null @@ -1,37 +0,0 @@ - -# Create the coordinates of the atoms using PACKMOL -cd packmol_files - - packmol < mix_ethylene+benzene.inp - mv -f system.xyz ../moltemplate_files/ - -cd .. - - - -# Create LAMMPS input files this way: -cd moltemplate_files - - # run moltemplate - - moltemplate.sh -xyz system.xyz system.lt - - # This will generate various files with names ending in *.in* and *.data. - # Move them to the directory where you plan to run LAMMPS (in this case "../") - mv -f system.data system.in* ../ - - # Optional: - # The "./output_ttree/" directory is full of temporary files generated by - # moltemplate. They can be useful for debugging, but are usually thrown away. - rm -rf output_ttree/ - -cd ../ - - - -# Optional: -# Note: The system.data and system.in.settings files contain extra information -# for atoms defined in OPLSAA which you are not using in this simulation. This -# is harmless, but if you to delete this information from your -# system.in.settings and system.in.data files, follow the instructions in -# this script: "optional_cleanup/README_remove_irrelevant_info.sh" diff --git a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/README_visualize.txt b/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/README_visualize.txt deleted file mode 100644 index 019afc1444..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/README_visualize.txt +++ /dev/null @@ -1,87 +0,0 @@ - - ------- To view a lammps trajectory in VMD -------- - - -1) Build a PSF file for use in viewing with VMD. - -This step works with VMD 1.9 and topotools 1.2. -(Older versions, like VMD 1.8.6, don't support this.) - - -a) Start VMD -b) Menu Extensions->Tk Console -c) Enter: - -(I assume that the the DATA file is called "system.data") - - topo readlammpsdata system.data full - animate write psf system.psf - -2) - -Later, to Load a trajectory in VMD: - - Start VMD - Select menu: File->New Molecule - -Browse to select the PSF file you created above, and load it. - (Don't close the window yet.) - -Browse to select the trajectory file. - If necessary, for "file type" select: "LAMMPS Trajectory" - Load it. - - ---- A note on trajectory format: ----- -If the trajectory is a DUMP file, then make sure the it contains the -information you need for pbctools (see below. I've been using this -command in my LAMMPS scripts to create the trajectories: - - dump 1 all custom 5000 DUMP_FILE.lammpstrj id mol type x y z ix iy iz - -It's a good idea to use an atom_style which supports molecule-ID numbers -so that you can assign a molecule-ID number to each atom. (I think this -is needed to wrap atom coordinates without breaking molecules in half.) - -Of course, you don't have to save your trajectories in DUMP format, -(other formats like DCD work fine) I just mention dump files -because these are the files I'm familiar with. - -3) ----- Wrap the coordinates to the unit cell - (without cutting the molecules in half) - -a) Start VMD -b) Load the trajectory in VMD (see above) -c) Menu Extensions->Tk Console -d) Try entering these commands: - - pbc wrap -compound res -all - pbc box - - ----- Optional ---- - Sometimes the solvent or membrane obscures the view of the solute. - It can help to shift the location of the periodic boundary box - To shift the box in the y direction (for example) do this: - - pbc wrap -compound res -all -shiftcenterrel {0.0 0.15 0.0} - pbc box -shiftcenterrel {0.0 0.15 0.0} - - Distances are measured in units of box-length fractions, not Angstroms. - - Alternately if you have a solute whose atoms are all of type 1, - then you can also try this to center the box around it: - - pbc wrap -sel type=1 -all -centersel type=2 -center com - -4) - You should check if your periodic boundary conditions are too small. - To do that: - select Graphics->Representations menu option - click on the "Periodic" tab, and - click on the "+x", "-x", "+y", "-y", "+z", "-z" checkboxes. - -5) Optional: If you like, change the atom types in the PSF file so - that VMD recognizes the atom types, use something like: - -sed -e 's/ 1 1 / C C /g' < system.psf > temp1.psf -sed -e 's/ 2 2 / H H /g' < temp1.psf > temp2.psf -sed -e 's/ 3 3 / P P /g' < temp2.psf > system.psf - -(If you do this, it might effect step 2 above.) diff --git a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/images/benzene.jpg b/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/images/benzene.jpg deleted file mode 100644 index 356c78425644264fd39fa94cbe21122942871f7c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15032 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 M{%z+s@VWB;07Lw^g8%>k diff --git a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/images/ethylene+benzene_box80x80x80_LR.jpg b/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/images/ethylene+benzene_box80x80x80_LR.jpg deleted file mode 100644 index 00c82d3d9f5f13a5dd36eaee35d982557be2b1b1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 130048 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%0AlqfP_f5(nxm?-97ZsjdXXHNH@dKEy&P0 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 diff --git a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/images/ethylene.jpg b/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/images/ethylene.jpg deleted file mode 100644 index ab5bbbf49b35b63abfb7e5eb6a3e8ef8b7dac5bf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11657 zcmb7qWmsEH*X|BUaCdhJ?i45#cXuchch?puw79#wyE~LpiaQjywm1}b+Tw@ydEW1P zf1Pukm1OqZGxw~$=GwVt?ySk<;^P{CDK9N24S+x(K=$bcJbncv{-FOgI5;reAA^9w za9}6|3WY)-5GXtXJQRum4}riV!6P94F(^C|G7=*4AMnS?9|wO%J-rd1M*XGye-)2C z02U&!3c><|umCtL5Eu*e*awgUAOHmY;~e;pAv{Hchy;cMAwTuw{#VDpgvVt76$}F4 zFu|Ar06JOw&$z!=@ag@3uqUP*X&NXa)6&onz!ZZ|p_bs=s`#fogsnp97?r0b#i z!4Hj-_ppp51YRXn4rB5!fq2AvDu)^m;GfRFd;gRjWv~V(!lfC@9x4E6E~R$kM+nl zbz+-LpYQ(V1Wh;*$+=J$?p|;fRzoI0p`^8JKm08j5+?_dB)^~j;c#xI54@0tcefkH zOwlL`*#kh8R)P^5h754a(w2!S64ZRMyWu>30JU41WjvN#R%U`jcQ6)}ADILnZ5sg4 zY^Gb4Cnw2pE5gdy7=~>GJ3Oob8>HTbE=}^%dQuWp`#lc^jk3~306>)8?gkV0XyI9O zjYp-$Ab#6l|Gb^l`{l>Cd*+dVq8b|PxIB998&TSx%cr=UVN+Z?+R4Fs@7POVGW|`X z5dmXn#g`xOEL?VFET|;)(a*A(g}VUY<(F-sfO#}Oo>0wq6UcAsrEWwoSWq7Io$^(P|6PSLz;-tCLn-k~Dc2;8#K z7xAzgb}79}pB$NRd9{?y8;Bs~6A%4e7NW3<+2NfC26bEuj!Wl{@*UT%-^?l!mls0v z>VD(sKgdv?cp~V=8OJv9NO%bOmtMFX3t1&r4!6mniRkPYZdIT7DfO2ziW#_)7L3%HS@u-soQx< zJREjS*}z9{<`aHd1HcKh4d{Zz#Y)*x*FL3!Q8=k*-6g-Nf=IHum{h2LsuE(wl2vp0 zJ%t4zh(w!kZFJnRN+WuaH3;Ah+~>4Zg}BcY_bC5R0M#sEu5)n)QyyyU7te(( z^N5A)(vz`~@Ub`pNp74}|8mg9@C$jk63IAv(VrV=`-%M!Mvc4X+$842sWmV9%K+;t zd#9)C>PLc_>3;*DFBh*O3ci``>}GcU?FP_vc{&CZJ~Z#_k>>&LFp|MUU) zuKT`z|JMJxAUv%Ite5}*4+nySe_D;e|1^W(z<*XSENm)7OdMQF4m?qOY8q8~PM)Ww z0`X}90YTv&0q@P|hVLQHBbq-I9L+m6DQ!G5mHL=E2k@$#k_UXX0Fn9zI-Pp6Nrt-!Hm5aHcNbK_2*=S3U04iFKqD6ZeldTEi&3GK<3tUHpZ;9p2(PE_6G|aFPuSyBb4xLky)iso zfvmp#>fxO%vVJXpE`6V7QBS&9i5o<0rB}ug7Ee`cbI{U#%xax%$>IWPg1s7MZ2s7<@Ba zzZX8V@mvfZ5tA1B%Rv$q7LXvswS&^uuewZfV>xEpNmiWrOM4gzEzTw<|41U72P$YX z2o9ls1a?(u+H$|Nh>8WJnRMobeabN_dJ%)#9gKmoFjBbmS$Q?{kT(Ma2@yG_mhFkl zNe>d6LFQ=0gE83SK*39VY^GG0nAn)qgf>z$j8c6$f+?sl<5(s>x62dyq@R_d?DWZ9 z(KJO&Cho)U<2C}KV0{GlNS{+Uug!1{(H4i0AVhD9sI4HEHFDeMw(zKSJ9rE)Zd~_c zzibR2BHo3Iv7Mre1%Dh;_b-EWQ(ViLRSDMa1|mU>le?}I8GAYMOhgAm<+)pz-fM67 zzYnvAq;0thkV(YlnMeyf0*o*Z1f6>lRk;`$nm9{T7*TMUr&I4|Q1HDWwaenOw1DYL zD><_=SAlbmy!sm6yCZ)eLvls|b`0HLTpiCR1(1F1ZxkS9*r7DJY~oR{ekjU<%06i^ zXU0wA+tsbqR^4cA$$7EblU?=XnEatFqF};a=g5xZ1^6!Jx*JCRGe-4t@<^hP73ZI? z>!UNcon+i%l;lHI_u=#Gke$uiAABR?L1|+xhhZ_sdTw4?DpPgmJQ^Att8hH;ib>2z z^$gJztdCj*?34?15Ad|`7pCiS(Fjt|C(WADnw{d~iKt3mx?s_aCMK_Y&f9@mPkTMk zUjOE^6GfWN*u-`+uaJioWWZ5NImvxth&+)x!D$>XD)X> zSY%_#-BoNAjM0Jc#*_`559Zqn+ZfVFMWf|LjtP@_oPC$?SRm#O&0crml9$cO`+7`_ zY*$vC7sdp035qt#cy7Jg%kuFKO03$7YmXHyd4#LBXEy<-Q*b;yc8YF}OWgh+~2JR3<8OOJVgF447mScC}9F1I0)!T>LMURp?|zQ zZDRlgiiJ%{#VMv{0*{G9&E?`Bk4wWLDz0vtUr);|p%KtMg@Xy*ZGrcaU8d$JF z$0OBy`tLpmFY>g{3G3HXqw&OhFiLkJYG{^74(^eT<#d;z)Xr*-z8evZQokTwokrCO zYSk|-D!5)ry_DHcliYq`QC{xhE%#!x?s!y#>sf{3Ekasub8Ul=hUPrZhlY3bB4-B_ z4G*U&cDPsaWtnC+Iw~$9xzd!uMKGhWq|FFTha-m6MH6|6;B)4p2 zo!{@Ozjh4c{!9)r^^p2}IjFFKV2{|tduAO7&#)U?i(QP5yKuPR^F4_CE<80u8z~gg zq_Hmd5QFRpelvV8F%Oj*H8QeeHht^n>!nKHYp-Z><^2ZQYo%}7@po~QgkKQQ^1eoR z5DjStJOa@~xI}MrloUM7oj@Y9rl;&gN61Yk#EP!gyJ3|>!Jfs#=S5EP(+Fp|ochz~ z7j$~qY0a!+@(e4LucZm%G(KzEL~~9@b9z?Ku{iUx5gssWJpxy^=dd|Ye(CJgt;7Q+ ze^d8|U^16crE>MLo6h(ezE<8zp7v}#SV|so zj-smx^;1ZBi=BiP)2qHrbC5!jo0YVQ<{(TZ(4NT?^}MUGTTq>v<(0}C+|ujM1^XJ( z-s@)y#->o4mZ}&B8}qNo{;)p?55IiBRM{UF6FuE!xWfxTOfwMQ? z*;sBHPPJ_kE^J#ce@OL3j}mQICR|-pO{5yl^OjxhACQV}j3cBP1u z+ATO+Dhy~;#{#^f-pYTSL!V<#Mv92qzo*M4@tcHSk2~)(u;ifqaiSLwH#|_uA5(mA z6r-+g%&7f?uWD3AH!ufJJ5yGRPfE<#sN`qTPc-34ytKn}Ce+f0ivDjY&y|}zD5CT2 zg_4{0an+kDt$_}(?~46n`XvkkgT@#Fm~l&>7i z9+GqF1!rklUKV!Rcd0WUquJ^}h(Gf8<)OAXK&xk~+F=Lt1gY?B0;wG_o3Gv{~k|YU6y)QEF8l zgD!*h2%y%4-O|Dwp&V66NFP3&bGu#0ceC`$d-c{c5^!o%Dek0Yq`8`SUE(o40`HWg z;s-j%8sp{c(uY)9wgOXECzLv;v9{XGA1JfbEpk_>D8>`GGQ<`=S5@bJZ=v&=JM&)Z zGVUyq;hwR`m?b@TyL!0WF5#AWW?^+wEa?r;y!%dwz z>x=F8MJVW-IXcxd**CT?Y_5`*eY->zzgm2VV+oBDN8Kf#_VD5A z=Zl-mP>Sm7X~*6boLH%LVU;c|%1^q;axZdCWS%d6|1(mW(W>rPlg&h#u7{V_HWoXe z45R3o@;Z%NBRg}!+Lexj{*`$7+=%-em%TSz$>LyD;vR$NcuIQ3sN>ME4ce~Dd%s^j zbc;5qP4VW%G#oMNucQzRe}4?3FX@lx$nIQliZ@6^XE;wF?uH#5 zp}BsUp~CyhCiuK6JzVW_JTlU0X@J(cX=%A={mXFOlHM-~4IjRAC43344x(ge$IgZ~ z%uZ>Ust)V3l_nxb0TrL2l?_U8I3q+B_{U0q1Kd*0XSA(M78Vcn z-&T$|zV*zk&us2#3okft*Yw;0u~=R0#Mg@*ZU(JqtL<3qjBI^X?cOj4Dn_zEMqTx02DN~TLUcP&T(JOK&+v?U z)aik1LKUy370z@&BN+QATg0~OjhI6pV=K0OQM_qlW26Y#ER7^NhE}$IGk#)ts#fvN zPqIyVM=!b;xIX&8f%ES1#9Jz5{$l=(=-FbD1T#qkILZQJg5|G!i2MYeoD2%_qOJ~C z=hk=1yKzPG7?`~#!17{DGuhU+pV#jvh9R(~1{^_QjeO?Yk1bsrT{+&ZGO&F3Q`1~6 zD=gPnvmcBdqU@A@MTW^wJ0`Gk!PNcbyEjQyXWc=+es%d1G+_}CMOiflFej&Kc$GVc zkU-oy4S#%hyzex=s~WZTe$|)6%0!fes#$~`=${@+Oz<4fdO}{KPTWkBKde zU1|Lbe&%YHRaHzj4y)Q`?|1xx71kQ0Km;Bgs~Gd=JR}qrA{Q6L)A*5mw>kJrt%~eV zzj0nuEy1zlcaU_4+aS3o3tjj(EgC6uG7UAd=1~btQ1x>Jd{{CY<%3UlPhPz}+DPw1x=u*=X>1&1F<(sfs|I=`etC9{VJsnJ}Nyyl@~e82l$g{8u6aSbxQ_ z3nryMM|{3$efQL<>iXG#@;o9`k3jo+w<>GJZj=J2hE-Se<{N(47^!ssX?!zcFs{j=X6f%>iJ98$XTr=8>VGLaMk$+t81dLvK%N#qO# z&Kp|n{nM6O$PB##)7swT!yzG`L{bgTT{n`LEvdiWYqrqP&Ggzc((Rl%_gC`Eq+Sms z1p%c>&PQ-m_x{=o-nYTQ8{a0{3^uO=9FE8y0gSQvH0O1VFZJ(yHwiHK5fX+Rv3EUak*5I`sO7TimEOF` zBOrO#Whqt;-@qD!L$TSue{ah-Uwr-vowBXhNYnMW1HvCPMKl~X5s>hWJ5fW}$|3g~ z)LHfs05dP6TgdUXWC0T=uoO)dlftli>WApx;yHqD-vj!C29Rku z0cQanNhfr_sk;t~m@z1>)@%LMYu#BM@NQ4TG=x|w@v~q==Yo&1ZD8+5cbJp!zW@AO zWOU4^XW9XGAx4VMrLu|PtqldHAc9!*t9LKKCnAJLtdiN#j9nk@WviqLJ9P{A=h|Gd zqQr|k;JW^fg6a?$`t+y03Njx0o^sZg?W6O!N;S_+&q!InZRAgWGnKHQ^}4BklXEGU zOvA#S@J{BFc0QUiuLLiODe`%kh~~(#(%W>8K{#iZPVza1@b(GPnS$DyJrmxx!NT97 z5=d_aR1uD`Any7&W+bXZ4OS>Inm?txyza_a zMtI}k=Jup-S@4(n_FxA;_hl;jNCvL-qcS{HUuEawx08|;#*oUSzY3H&j6EY&C~;0$ z^^2o9jv~vtj{ZzyyHjt9VEyt1=Ve-H03lUu)`+3>K4^D!rajz{0o84K&Z>uST%k|r z{bHJC!6*7ncYh;!sb@Up?(Iz0T)58qP8MLszA56*1*>-SCpd>381SZ2Y3#%@xD6sG z5h#&E3T(_{Ejvr?Rt`BhrXu%Pvombv#{HwU>V@GY5_{ZaD$HU+BP#@ZuH8JH&wdcX zLYN}@$ENc?8V$;Z5=5w)_H_6Xh~Y=w2S8pud!2OWg}ap)P`e=p!lqN z_pdc%^G5rKEt%p7#+rS77qxRk@XRJ_%w%?)v&_ov82zHp^_~eRYb1%z+lFy9=CKb> zm!U85;Xbg`nAvak2)*zdpuV`I-5T{}J^S+fR{DT-p6P8`*gaZg8YKcJ^Ink$nG$lt z>sSMt&!saTK2=dg@goUJpi-vj`XazWSC!OG()3di3f`!|ZlHMH-P+ozz*|Q$A1ym>--30q1UZc4`3ghy^L-tk85y2kSRZzZ^wbyVcTfTS*x`wA0uKpmY;ylN ziz*6Ji~PvSuD)d`O@>l9{sM>@wT8mv&?PwBQLb2ZhR3$NV;vW8{vq-ykXX2(POsb*ThOgyi*eKx?w!|Hj1zM}UH!JHMNZinC;vdAz zGgJoIo}w~JxwBE4_PjANERAkS8=iFjm@OAiSvkdgRIgxY5nvQ829y`;QECQt*M{l7 zHfaz*mstcieHu>JX>9$aI1y%{enFrbBsGe_`SiuU{{a{*j({?`u6ob z%3-@ZSK#1?s$XAUR937zW*}5PovB^W@daG_cRZrgw@gBc^{9rf=)M4m#gV!pM&Am? z?!#N1Ct&8r>u}yNw|#>z=W{=sGJMXZjVD`YLKcPm&Aw4EiVD|XDpzmG8=mHkBkZ%| ziLU~0K4)q2ZkZH1*T{sa9gW`sf$4gitbv1yzMIw!TSm@3A<+%rHlE&R=Hi&*)g;os zRx}iiyNHD3d~kFoISy&&XrJJ0IX-|!zJ-M;TgO=KU5Ic@u6ytZkY0+UZy9jhaYbje zfj!}Vp)kMwJe>n)y&&u=5$pqfKlG$W{vJ^Se-5ag&a3|0DE}K^KAn30F-ROh3CKbI zrOMIz0T4gnuYoAz5P>+^e*l0fO9_A|{Y3vjIDirxpoRM<6A6M~KQ$o&34gjEm~u}g z5ckIqWdh<;2>@c0PfR}$fGzq2XfdDeg$ThErF{Z^PoJl{91!Z<9u%M+^i7b-VBn~BK2s(NM646dKV z2#kH^`KcwKuc~-Cr%ev4uJ3}=3zHHn%-7=x6^{E|VH$YQ(hUaT?g9TM#Q!ddfjjfF zn-=F2C5-j^Ec`JFHtV}mX@*^YnJCIiYmn9?(Q{9*a#c((d~}|lvdV!ViE!!IwbdbE zq{c#&=ID;8jX)}~0h->mrZh8DIzUBv<2e>tuHxl+uo{#&vM$S2Hi4AXussoRfp`TlWvf)4Uz?Uc2QlZOiAu~8nQFF2=&8~{w&{Ww z5hrquQ^w1e5{ud`q{hBzqU)mJG9agTf9S7|&f2BA-Qu28VTL}&*ldfqjCJ->6aYuB z^1$0JQ8?s4A*Wr$mhhoVBQz@n#&S&S5eIUdsE^HAsYDB?(X5XE|0UI#U+zZ-B65D8 z*g|^>-c3Uo(aOqcuArO0XHu6Uc}9O5biD`k2uxDwwj!c@P4=yJ^_IG{At`!V(=zX& zbpH)NE1XaKC?`T2OK1-Bn4##&sawx-70V`~$9~)Y@&TdUXV$Qvg&VAAc7- zW`AOa1RBgrgX20A6S{~9>U2rq*~}fFidp;B5`Zp%w-U{Kpgm@>u{4Ub+*^@zS{6Qy z=pMeXip?hW3SOMtm;kXvfoxLC%ZPtS#6VS0vWLe*VV~rdCXZ9SGu2|+n}PyW2A${f zo8rSUr!K1Hgqj~;Ro_*b1gr(kQEvSGXv7IH^$IC}QB4v_ewh=T#nM%6(uiP3g<7kXXsu zxRS*m-7aK0kJHP}}r15J$bhP=1z3lNr(U7T}R9q`j8|Cvb$v*b`2|?I0h#ad&+grGZE%m3+g&c;5FZOHAIUZAKFj3YwGDUm2vsJ(`~VULswVkMX1pHyro_YK+P7$l z2uS=e9FyJO@P4R>Lfe$)NoPUs=@>i)k}YR`Iv0hQ80BQxWlD^t!9z4u!hjIVA$2x8 ztv$HcBq)g$&~rTriFFj26v=JwzLW$3{(T5Y+Nb!kP==1;>zp zv27|vZ0$`K&%EtZs$KU7<$I+24Ipz|baNB`S#Veu$2PH-z<{cg0In4gxQ3%Li-#58 zOMcD|;Fn;SEP)G!hEj-_XJSr6d(-v~o;mSH@=%Fi67^U?Mr5dY^|~EAhY%BS@Hz}X7VVw_arR!A(s-$S>J4QmPAlnmW_3VXHOd4m-r8Azawye_}vd`gS+AM6d(CV5jSE2em z{m$9!)BX9nVz+zNkHFhU0LN=4?A1K}nEiL|h|>e!L9M$j0vg=U{Ah{LOgv-7>;iR? z)2MgTwZxFqtgSZmWI8(RoZm{wIPlU#IK))K2j;ZJGe zqLJckqGO}%lQBCWV)yi)=bj*S9>z54)G5y#AAPkz6anuf+k0O}KM!&3#SiaI`OQJp z5$fGPSqJ0$a)SQK0RESY!+_%T4+OUU5m73%fW_%sW6|_@Tqw(-g@cN%g|c(ZMeu`* z&o}p#dU{T?6kcaZT<9Ht@GC_cGEut^OQH2yY8>~ZJc{B=7jDbjPFbqo_|xc!6+Pa; z&5NqO-fYPG@)gRU2ttPGERssNsH=qug+BtZ^aNQ5Z;S-$J>EH!F@_zD8h);VpDiI{ z8I(nF3o27SYG|?#!-Boc>)*x5vQq4o#0{_5CqzbrGhpBtkeXo1}E8rB%`3;HI-Ed!v+Kh~T$E zX#bv{+$>s)c4|9x4a4hMD5xik6-jCK9K#AHJ0}h06zVV1`x9%UfLbWM0=G%(+pAFn z(w_cSg{`2i)kb1FDY16dux1nE(GdCXtXaFMK`Yd>ye?5~XsREPUIr=AtoKH}&CQ~& z)p24z?ZC1eb>-Xb?^_wVlB*2?!DWE4AV%EO@;+;3)Oa5mWI3ToDahk^AT=oS8qC+0 zZE(`?c(D_Xl}m$;Rg|CtAejWAnfXgL>6CT=aE|M9eo^CwwsRMWafS+|XR%yOR7IC0 zjOqQ`*ABfJUzzxv9d((1GGF52v>Y9GFtK+e(Xv+sE1+Vse#1vJ``ZTn?P1cK?81F zof)d6M~!f>sZw3wD`0?@Oa5sR8ydB#q8Js%WNh%gOOmyp1AJ0{PdhFcODK9Ej;IVl z;1#!CmG#@M#m!7!c6eTAq$>ppzY^`={(F*KoQJGJoAhay4|;G{qFO?rA0U}{)R~|) zx=*6-qTLu7ysO@Vu|yGu*aw5Y$LxMY&_xqlb6#0QOvnN;g~3&IUCX0k8n^}!(!`-= zg<`G&PZCm{-dwW4{6{@j0N1pkiKc6BFSTY$f>GB+QBY6gYB)no&-bB();T2X0Xa$% Z_8E$|x@U1kuTPi)sr*+0A7~zz{ttLQH(&q& diff --git a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/moltemplate_files/benzene.lt b/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/moltemplate_files/benzene.lt deleted file mode 100644 index f240a091fe..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/moltemplate_files/benzene.lt +++ /dev/null @@ -1,51 +0,0 @@ -import "oplsaa.lt" - -# The "oplsaa.lt" file contains force-field definitions and masses for the -# atoms in your system. See oplsaa_lt_generator/README.TXT for details. - -# Note: -# Atom type @atom:90 corresponds to "Aromatic C" -# Atom type @atom:91 corresponds to "Aromatic H-C" - -Benzene inherits OPLSAA { - - # We just need a list of atom types and bonds. - # - # You don't have to specify the charge in this example because we are - # using the OPLSAA force-field assigns this by atom-type. - # - # You also don't have to specify the coordinates, because - # you are using PACKMOL to generate them for you. - # Just leave these numbers as 0.00 for now.. - - write('Data Atoms') { - $atom:C1 $mol @atom:90 0.00 0.00 0.00 0.00 # "Aromatic C" - $atom:C2 $mol @atom:90 0.00 0.00 0.00 0.00 # "Aromatic C" - $atom:C3 $mol @atom:90 0.00 0.00 0.00 0.00 # "Aromatic C" - $atom:C4 $mol @atom:90 0.00 0.00 0.00 0.00 # "Aromatic C" - $atom:C5 $mol @atom:90 0.00 0.00 0.00 0.00 # "Aromatic C" - $atom:C6 $mol @atom:90 0.00 0.00 0.00 0.00 # "Aromatic C" - $atom:H11 $mol @atom:91 0.00 0.00 0.00 0.00 # "Aromatic H-C" - $atom:H21 $mol @atom:91 0.00 0.00 0.00 0.00 # "Aromatic H-C" - $atom:H31 $mol @atom:91 0.00 0.00 0.00 0.00 # "Aromatic H-C" - $atom:H41 $mol @atom:91 0.00 0.00 0.00 0.00 # "Aromatic H-C" - $atom:H51 $mol @atom:91 0.00 0.00 0.00 0.00 # "Aromatic H-C" - $atom:H61 $mol @atom:91 0.00 0.00 0.00 0.00 # "Aromatic H-C" - } - - write('Data Bond List') { - $bond:C12 $atom:C1 $atom:C2 - $bond:C23 $atom:C2 $atom:C3 - $bond:C34 $atom:C3 $atom:C4 - $bond:C45 $atom:C4 $atom:C5 - $bond:C56 $atom:C5 $atom:C6 - $bond:C61 $atom:C6 $atom:C1 - $bond:C1H1 $atom:C1 $atom:H11 - $bond:C2H2 $atom:C2 $atom:H21 - $bond:C3H3 $atom:C3 $atom:H31 - $bond:C4H4 $atom:C4 $atom:H41 - $bond:C5H5 $atom:C5 $atom:H51 - $bond:C6H6 $atom:C6 $atom:H61 - } - -} # Benzene diff --git a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/moltemplate_files/ethylene.lt b/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/moltemplate_files/ethylene.lt deleted file mode 100644 index 45adb1faef..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/moltemplate_files/ethylene.lt +++ /dev/null @@ -1,40 +0,0 @@ -import "oplsaa.lt" - -# The "oplsaa.lt" file contains force-field definitions and masses for the -# atoms in your system. See oplsaa_lt_generator/README.TXT for details. - -# Note: -# Atom type 88 corresponds to "Alkene H2-C=" -# Atom type 89 corresponds to "Alkene H-C=" - - - -Ethylene inherits OPLSAA { - - # atom-id mol-id atom-type charge X Y Z - - write('Data Atoms') { - $atom:C1 $mol @atom:88 0.000 -0.6695 0.000000 0.000000 - $atom:C2 $mol @atom:88 0.000 0.6695 0.000000 0.000000 - $atom:H11 $mol @atom:89 0.000 -1.234217 -0.854458 0.000000 - $atom:H12 $mol @atom:89 0.000 -1.234217 0.854458 0.000000 - $atom:H21 $mol @atom:89 0.000 1.234217 -0.854458 0.000000 - $atom:H22 $mol @atom:89 0.000 1.234217 0.854458 0.000000 - } - - write('Data Bond List') { - $bond:C12 $atom:C1 $atom:C2 - $bond:C1H1 $atom:C1 $atom:H11 - $bond:C1H2 $atom:C1 $atom:H12 - $bond:C2H1 $atom:C2 $atom:H21 - $bond:C2H2 $atom:C2 $atom:H22 - } - -} # Ethylene - - - -# Note: You don't need to supply the partial partial charges of the atoms. -# If you like, just fill the fourth column with zeros ("0.000"). -# Moltemplate and LAMMPS will automatically assign the charge later - diff --git a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/moltemplate_files/oplsaa_lt_generator/AUTHOR.TXT b/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/moltemplate_files/oplsaa_lt_generator/AUTHOR.TXT deleted file mode 100644 index d5e469af37..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/moltemplate_files/oplsaa_lt_generator/AUTHOR.TXT +++ /dev/null @@ -1,3 +0,0 @@ - -OPLSAA force-field conversion tools provided by Jason Lambert. - diff --git a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/moltemplate_files/oplsaa_lt_generator/README.TXT b/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/moltemplate_files/oplsaa_lt_generator/README.TXT deleted file mode 100644 index 6da3456025..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/moltemplate_files/oplsaa_lt_generator/README.TXT +++ /dev/null @@ -1,110 +0,0 @@ -This directory contains instructions for creating a a moltemplate file -("oplsaa.lt") containing force-field definitions relevant to the -"ethylene+benzene" example. (However, these instructions should work -for other molecules too.) - -First, check and see if there is an "oplsaa_subset.prm" file present. -If not, then download this file: - -http://dasher.wustl.edu/tinker/distribution/params/oplsaa.prm - This file is also available here: -http://dasher.wustl.edu/ffe/distribution/params/oplsaa.prm - -and save this file as "oplsaa_subset.prm". Then you must EDIT THIS FILE -so that it only contains atom types you plan to have in your simulation -(see below for details). Then run the opls_moltemplate.py script this way: - - -oplsaa_moltemplate.py oplsaa_subset.prm - - -This will create a file named "oplsaa.lt" -Look over the newly created "oplsaa.lt" file. -Then move this file to wherever you plan to run moltemplate. For example: - -mv -f oplsaa.lt .. - ------ DETAILS: Editing the "oplsaa_subset.prm" file ------- - -Again, before you run "oplsaa_moltemplate.py", you must edit the "oplsaa.prm" -file (or "oplsaa_subset.prm file) and eliminate atom types which do not -correspond to any of the atoms in your simulation. This means you must -look for lines near the beginning of this file which begin with the word "atom" -and refer to atom types which appear in the simulation you plan to run. All -other lines (beginning with the word "atom") must be deleted or commented out. -(Leave the rest of the file alone.) - -For example: -If you were working with ethylene and benzene you would delete every line -beginning with the word "atom", except for these four lines: - -# for ethylene: -atom 88 47 CM "Alkene H2-C=" 6 12.011 3 -atom 89 46 HC "Alkene H-C=" 1 1.008 1 -# for benzene: -atom 90 48 CA "Aromatic C" 6 12.011 3 -atom 91 49 HA "Aromatic H-C" 1 1.008 1 - -Then you are ready to run oplsaa_moltemplate.py on this file. - -(Note: Atom type numbers, like "88", "89", "47", etc... may vary depending on - when you downloaded "oplsaa.prm".) - - - ------ Using the "oplsaa.lt" file ----- - -Once you have created the "oplsaa.lt" file, you can create files (like -ethylene.lt) which define molecules that refer to these atom types. -Here is an excerpt from "ethyelene.lt": - -import "oplsaa.lt" -Ethylene inherits OPLSAA { - write('Data Atoms') { - list of atoms goes here ... - } - write('Data Bond List') { - list of bonds goes here ... - } -} - -And then run moltemplate. - - ------------ CHARGE: ----------- - -By default, the OPLSAA force-field assigns atom charge according to atom type. -When you run moltemplate, it will create a file named "system.in.charges", -containing commands like: - -set type 2 charge -0.42 -set type 3 charge 0.21 - -(This assumes your main moltemplate file is named "system.lt". If it was -named something else, eg "polymer.lt", then the file created by moltemplate -will be named "polymer.in.charges".) - -Include these commands somewhere in your LAMMPS input script -(or use the LAMMPS "include" command to load the commands in system.in.charges) - -Note that the atom numbers (eg "2", "3") in this file will not match the -OPLS atom numbers. (Check the output_ttree/ttree_assignments.txt file, -created by moltemplate, to see a table of "@atom" type numbers translated -from OPLSAA into LAMMPS.) - ------------ CREDIT ----------- - -If you use these tools and you publish a paper using OPLSAA, please also cite -the TINKER program. (Because these examples use the "oplsaa.prm" file which -is distributed with TINKER.) I think these are the relevant citations: - -1) Ponder, J. W., & Richards, F. M. (1987). "An efficient newtonâ€like method for molecular mechanics energy minimization of large molecules. Journal of Computational Chemistry", 8(7), 1016-1024. - -2) Ponder, J. W, (2004) "TINKER: Software tools for molecular design", http://dasher.wustl.edu/tinker/ - -------------------------------- - -Jason Lambert and Andrew Jewett -April, 2014 - -Please email bugs to jewett.aij@gmail.com and jlamber9@gmail.com diff --git a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/moltemplate_files/oplsaa_lt_generator/minimal_versions/README.TXT b/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/moltemplate_files/oplsaa_lt_generator/minimal_versions/README.TXT deleted file mode 100644 index 2fc1ea29ea..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/moltemplate_files/oplsaa_lt_generator/minimal_versions/README.TXT +++ /dev/null @@ -1,16 +0,0 @@ -MOST USERS SHOULD IGNORE THIS DIRECTORY. - -This directory contains versions of the oplsaa_subset.prm file -which nearly all of the OPLSAA force-field information removed. -However for the "ethylene+benzene" example, all of the essential -parameters are contained in these files. You can use oplsaa_moltemplate.py -with either of these files and the physics should be the same. - -However there is no reason to do this. -When you download the "oplsaa.prm" file from: -http://dasher.wustl.edu/tinker/distribution/params/oplsaa.prm -(also http://dasher.wustl.edu/ffe/distribution/params/oplsaa.prm) -...just remove the lines beginning with "atom" for atoms you don't need. -You don't have to delete all the other irrelevant interactions. -(In fact, it is hard to do that without making a mistake. - I recommend that you leave the rest of the oplsaa.prm file alone.) diff --git a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/moltemplate_files/oplsaa_lt_generator/minimal_versions/oplsaa_subset_minimal.prm b/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/moltemplate_files/oplsaa_lt_generator/minimal_versions/oplsaa_subset_minimal.prm deleted file mode 100644 index b4078f1214..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/moltemplate_files/oplsaa_lt_generator/minimal_versions/oplsaa_subset_minimal.prm +++ /dev/null @@ -1,37 +0,0 @@ - ############################# - ## Atom Type Definitions ## - ############################# - - -atom 88 47 CM "Alkene H2-C=" 6 12.011 3 -atom 89 46 HC "Alkene H-C=" 1 1.008 1 -atom 90 48 CA "Aromatic C" 6 12.011 3 -atom 91 49 HA "Aromatic H-C" 1 1.008 1 - -vdw 88 3.5500 0.0760 -vdw 89 2.4200 0.0300 -vdw 90 3.5500 0.0700 -vdw 91 2.4200 0.0300 - -bond 46 47 340.00 1.0800 -bond 47 47 549.00 1.3400 -bond 48 48 469.00 1.4000 -bond 48 49 367.00 1.0800 - -angle 46 47 46 35.00 117.00 -angle 46 47 47 35.00 120.00 -angle 48 48 48 63.00 120.00 -angle 48 48 49 35.00 120.00 - -torsion 46 47 47 46 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 48 48 48 48 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 49 48 48 49 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 48 48 48 49 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 - -imptors 0 0 47 0 30.000 180.0 2 -imptors 0 0 48 0 5.000 180.0 2 - -charge 88 -0.2300 -charge 89 0.1150 -charge 90 -0.1150 -charge 91 0.1150 diff --git a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/moltemplate_files/oplsaa_lt_generator/minimal_versions/oplsaa_subset_simplified.prm b/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/moltemplate_files/oplsaa_lt_generator/minimal_versions/oplsaa_subset_simplified.prm deleted file mode 100644 index 6dbc6861ac..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/moltemplate_files/oplsaa_lt_generator/minimal_versions/oplsaa_subset_simplified.prm +++ /dev/null @@ -1,49 +0,0 @@ - ############################# - ## Atom Type Definitions ## - ############################# - -atom 88 47 CM "Alkene H2-C=" 6 12.011 3 -atom 89 46 HC "Alkene H-C=" 1 1.008 1 -atom 90 48 CA "Aromatic C" 6 12.011 3 -atom 91 49 HA "Aromatic H-C" 1 1.008 1 - -vdw 88 3.5500 0.0760 -vdw 89 2.4200 0.0300 -vdw 90 3.5500 0.0700 -vdw 91 2.4200 0.0300 - -bond 46 47 340.00 1.0800 -bond 47 47 549.00 1.3400 -bond 47 48 427.00 1.4330 -bond 48 48 469.00 1.4000 -bond 48 49 367.00 1.0800 - -angle 46 47 46 35.00 117.00 -angle 46 47 47 35.00 120.00 -angle 46 47 48 35.00 123.30 -angle 47 47 48 85.00 117.00 -angle 48 48 48 63.00 120.00 -angle 47 48 48 70.00 124.00 -angle 48 48 49 35.00 120.00 - -imptors 0 0 47 0 30.000 180.0 2 -imptors 0 0 48 0 5.000 180.0 2 - -torsion 47 46 47 46 0.000 0.0 1 -8.000 180.0 2 0.000 0.0 3 -torsion 0 47 47 0 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 46 47 47 46 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 46 47 47 48 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 46 47 48 48 0.000 0.0 1 0.000 180.0 2 -0.372 0.0 3 -torsion 47 47 48 48 1.241 0.0 1 3.353 180.0 2 -0.286 0.0 3 -torsion 0 48 48 0 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 0 48 48 48 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 0 48 48 49 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 47 48 48 49 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 48 48 48 48 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 48 48 48 49 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 49 48 48 49 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 - -charge 88 -0.2300 -charge 89 0.1150 -charge 90 -0.1150 -charge 91 0.1150 diff --git a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/moltemplate_files/oplsaa_lt_generator/oplsaa_subset.prm b/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/moltemplate_files/oplsaa_lt_generator/oplsaa_subset.prm deleted file mode 100644 index c802793ada..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/moltemplate_files/oplsaa_lt_generator/oplsaa_subset.prm +++ /dev/null @@ -1,5129 +0,0 @@ -# This is a modified version of the file "oplsaa.prm" distributed with TINKER -# http://dasher.wustl.edu/tinker/distribution/params/oplsaa.prm -# In this version, all of the lines beginning with "atom" have been deleted -# except for the atom types we will be using in this simulation -# (I also deleted some other lines from that file data to reduce the file size, -# but doing that is not necessary.) -# -# If you use this file, please also cite the software this file comes from: -# -# Ponder, J. W., and Richards, F. M. J. Comput. Chem. (1987) 8(7), 1016-1024 -# "An efficient newtonâ€like method for molecular mechanics energy -# minimization of large molecules." -# -# Ponder, J. W, (2004) -# "TINKER: Software tools for molecular design" -# http://dasher.wustl.edu/tinker/ - - ############################## - ## ## - ## Force Field Definition ## - ## ## - ############################## - - -forcefield OPLS-AA - -vdwindex TYPE -vdwtype LENNARD-JONES -radiusrule GEOMETRIC -radiustype SIGMA -radiussize DIAMETER -epsilonrule GEOMETRIC -torsionunit 0.5 -imptorunit 0.5 -vdw-14-scale 2.0 -chg-14-scale 2.0 -electric 332.06 -dielectric 1.0 - - - ############################# - ## ## - ## Literature References ## - ## ## - ############################# - - -The parameters supplied with TINKER are from "OPLS All-Atom Parameters -for Organic Molecules, Ions, Peptides & Nucleic Acids, July 2008" as -provided by W. L. Jorgensen, Yale University during June 2009. These -parameters are taken from those distributed with BOSS Version 4.8. - -Note that "atom type" numbers and not "atom class" numbers are used -to index van der Waals parameters, see the "vdwindex" keyword above - -The atom types with (UA) in the description are "united atom" values, -ie, OPLS-UA, where any nonpolar hydrogen atoms are combined onto their -attached atoms. All other parameters are "all-atom", OPLS-AA, including -explicit hydrogen atoms. - - - ############################# - ## ## - ## Atom Type Definitions ## - ## ## - ############################# - - -atom 88 47 CM "Alkene H2-C=" 6 12.011 3 -atom 89 46 HC "Alkene H-C=" 1 1.008 1 -atom 90 48 CA "Aromatic C" 6 12.011 3 -atom 91 49 HA "Aromatic H-C" 1 1.008 1 - - - ################################ - ## ## - ## Van der Waals Parameters ## - ## ## - ################################ - - -vdw 1 2.9400 0.0610 -vdw 2 3.9050 0.1180 -vdw 3 3.7500 0.1050 -vdw 4 2.9600 0.2100 -vdw 5 3.0000 0.1700 -vdw 6 3.9100 0.1600 -vdw 7 0.0000 0.0000 -vdw 8 3.7300 0.2940 -vdw 9 3.7750 0.2070 -vdw 10 3.9050 0.1750 -vdw 11 3.9100 0.1600 -vdw 12 3.9600 0.1450 -vdw 13 3.9050 0.1180 -vdw 14 3.8500 0.1400 -vdw 15 3.8500 0.0800 -vdw 16 3.8000 0.1150 -vdw 17 3.7500 0.1100 -vdw 18 3.8000 0.0500 -vdw 19 3.7500 0.1050 -vdw 20 3.0700 0.1700 -vdw 21 0.0000 0.0000 -vdw 22 3.7750 0.2070 -vdw 23 3.9050 0.1180 -vdw 24 3.7000 0.2500 -vdw 25 3.5500 0.2500 -vdw 26 3.5500 0.2500 -vdw 27 3.5500 0.2500 -vdw 28 0.0000 0.0000 -vdw 29 0.0000 0.0000 -vdw 30 3.7750 0.2070 -vdw 31 3.9050 0.1180 -vdw 32 3.8000 0.1700 -vdw 33 3.8000 0.1180 -vdw 34 3.8000 0.1700 -vdw 35 3.8000 0.1180 -vdw 36 3.2000 0.1700 -vdw 37 3.6500 0.1500 -vdw 38 3.7750 0.2070 -vdw 39 3.8500 0.0800 -vdw 40 3.8000 0.0500 -vdw 41 3.0000 0.1700 -vdw 42 3.8000 0.1700 -vdw 43 3.8000 0.1180 -vdw 44 3.8000 0.1180 -vdw 45 3.4000 0.3000 -vdw 46 3.8000 0.0800 -vdw 47 3.4700 0.3000 -vdw 48 3.8000 0.0500 -vdw 49 3.4700 0.2660 -vdw 50 3.5600 0.3950 -vdw 51 2.9300 0.2800 -vdw 52 3.8100 0.1600 -vdw 53 2.9600 0.2100 -vdw 54 3.2500 0.1700 -vdw 55 3.8000 0.1150 -vdw 56 3.8000 0.1700 -vdw 57 0.0000 0.0000 -vdw 58 2.5560 0.0200 -vdw 59 2.7800 0.0690 -vdw 60 3.4010 0.2339 -vdw 61 3.6240 0.3170 -vdw 62 3.9350 0.4330 -vdw 63 3.15061 0.1521 -vdw 64 0.0000 0.0000 -vdw 65 3.15365 0.1550 -vdw 66 0.0000 0.0000 -vdw 67 0.0000 0.0000 -vdw 68 3.1760 0.1500 -vdw 69 0.0000 0.0000 -vdw 70 3.2700 0.1000 -vdw 71 0.0000 0.0000 -vdw 72 0.0000 0.0000 -vdw 73 3.1200 0.1600 -vdw 74 0.0000 0.0000 -vdw 75 0.0000 0.0000 -vdw 76 3.16557 0.1554 -vdw 77 0.0000 0.0000 -vdw 78 3.4200 0.1700 -vdw 79 0.0000 0.0000 -vdw 80 3.5000 0.0660 -vdw 81 3.5000 0.0660 -vdw 82 3.5000 0.0660 -vdw 83 3.5000 0.0660 -vdw 84 3.5000 0.0660 -vdw 85 2.5000 0.0300 -vdw 86 3.5500 0.0760 -vdw 87 3.5500 0.0760 -vdw 88 3.5500 0.0760 -vdw 89 2.4200 0.0300 -vdw 90 3.5500 0.0700 -vdw 91 2.4200 0.0300 -vdw 92 3.5500 0.0700 -vdw 93 3.5000 0.0660 -vdw 94 3.5000 0.0660 -vdw 95 3.5500 0.0760 -vdw 96 3.1200 0.1700 -vdw 97 0.0000 0.0000 -vdw 98 2.5000 0.0300 -vdw 99 3.5000 0.0660 -vdw 100 3.5000 0.0660 -vdw 101 3.5000 0.0660 -vdw 102 3.5000 0.0660 -vdw 103 3.2500 0.0620 -vdw 104 3.0700 0.1700 -vdw 105 0.0000 0.0000 -vdw 106 2.9400 0.0610 -vdw 107 2.5000 0.0300 -vdw 108 3.5500 0.0700 -vdw 109 3.0700 0.1700 -vdw 110 0.0000 0.0000 -vdw 111 3.0700 0.1700 -vdw 112 0.0000 0.0000 -vdw 113 3.0700 0.1700 -vdw 114 0.0000 0.0000 -vdw 115 3.5000 0.0660 -vdw 116 3.5000 0.0660 -vdw 117 3.5000 0.0660 -vdw 118 2.5000 0.0300 -vdw 119 2.9000 0.1400 -vdw 120 3.5500 0.0760 -vdw 121 2.9000 0.1400 -vdw 122 2.9000 0.1400 -vdw 123 3.5000 0.0660 -vdw 124 3.5000 0.0660 -vdw 125 3.5000 0.0660 -vdw 126 3.5000 0.0660 -vdw 127 2.5000 0.0300 -vdw 128 2.9000 0.1400 -vdw 129 3.0700 0.1700 -vdw 130 0.0000 0.0000 -vdw 131 3.5000 0.0660 -vdw 132 2.5000 0.0300 -vdw 133 3.5000 0.0660 -vdw 134 2.5000 0.0300 -vdw 135 3.5000 0.0660 -vdw 136 2.5000 0.0300 -vdw 137 3.5000 0.0660 -vdw 138 2.5000 0.0300 -vdw 139 3.5000 0.0660 -vdw 140 3.5000 0.0660 -vdw 141 3.5500 0.0700 -vdw 142 3.5500 0.2500 -vdw 143 3.7000 0.2500 -vdw 144 3.5500 0.2500 -vdw 145 3.5500 0.2500 -vdw 146 0.0000 0.0000 -vdw 147 0.0000 0.0000 -vdw 148 3.5000 0.0660 -vdw 149 3.5000 0.0660 -vdw 150 3.5000 0.0660 -vdw 151 3.5000 0.0660 -vdw 152 3.5000 0.0660 -vdw 153 3.5000 0.0660 -vdw 154 3.5000 0.0660 -vdw 155 3.5000 0.0660 -vdw 156 3.5000 0.0660 -vdw 157 3.5000 0.0660 -vdw 158 3.5000 0.0660 -vdw 159 3.5000 0.0660 -vdw 160 3.5000 0.0660 -vdw 161 3.5000 0.0660 -vdw 162 3.5000 0.0660 -vdw 163 3.5500 0.0700 -vdw 164 3.5500 0.2500 -vdw 165 3.5000 0.0660 -vdw 166 3.5000 0.0660 -vdw 167 3.5000 0.0660 -vdw 168 3.4000 0.3000 -vdw 169 3.5500 0.0760 -vdw 170 3.5500 0.0700 -vdw 171 3.5000 0.0660 -vdw 172 3.5000 0.0660 -vdw 173 3.7500 0.1050 -vdw 174 3.7500 0.1050 -vdw 175 3.7500 0.1050 -vdw 176 3.7500 0.1050 -vdw 177 3.7500 0.1050 -vdw 178 2.9600 0.2100 -vdw 179 3.2500 0.1700 -vdw 180 3.2500 0.1700 -vdw 181 3.2500 0.1700 -vdw 182 0.0000 0.0000 -vdw 183 0.0000 0.0000 -vdw 184 3.5000 0.0660 -vdw 185 3.5000 0.0660 -vdw 186 3.5000 0.0660 -vdw 187 3.5000 0.0660 -vdw 188 3.5000 0.0660 -vdw 189 3.7500 0.1050 -vdw 190 2.9600 0.2100 -vdw 191 3.2500 0.1700 -vdw 192 0.0000 0.0000 -vdw 193 3.2500 0.1700 -vdw 194 3.7500 0.1050 -vdw 195 2.9600 0.2100 -vdw 196 0.0000 0.0000 -vdw 197 2.5000 0.0200 -vdw 198 3.5000 0.0660 -vdw 199 3.5000 0.0660 -vdw 200 3.5000 0.0660 -vdw 201 3.5000 0.0660 -vdw 202 3.5500 0.0700 -vdw 203 3.6500 0.1500 -vdw 204 3.2000 0.1700 -vdw 205 3.5500 0.0700 -vdw 206 3.4000 0.3000 -vdw 207 3.2500 0.1700 -vdw 208 3.5500 0.0700 -vdw 209 3.7500 0.1050 -vdw 210 2.9600 0.2100 -vdw 211 3.0000 0.1700 -vdw 212 0.0000 0.0000 -vdw 213 3.7500 0.1050 -vdw 214 2.9600 0.2100 -vdw 215 3.5000 0.0660 -vdw 216 3.5000 0.0660 -vdw 217 3.5000 0.0660 -vdw 218 3.5000 0.0660 -vdw 219 3.7500 0.1050 -vdw 220 2.9600 0.2100 -vdw 221 2.4200 0.0150 -vdw 222 3.7500 0.1050 -vdw 223 2.9600 0.2100 -vdw 224 2.4200 0.0150 -vdw 225 3.5000 0.0660 -vdw 226 3.5000 0.0660 -vdw 227 3.5000 0.0660 -vdw 228 3.5000 0.0660 -vdw 229 3.2500 0.1700 -vdw 230 3.2500 0.1700 -vdw 231 3.2500 0.1700 -vdw 232 0.0000 0.0000 -vdw 233 0.0000 0.0000 -vdw 234 3.5000 0.0660 -vdw 235 3.5000 0.0660 -vdw 236 3.5000 0.0660 -vdw 237 3.5000 0.0660 -vdw 238 3.5000 0.0660 -vdw 239 3.5000 0.0660 -vdw 240 3.5000 0.0660 -vdw 241 3.5000 0.0660 -vdw 242 3.5000 0.0660 -vdw 243 3.2500 0.1700 -vdw 244 0.0000 0.0000 -vdw 245 3.5500 0.0500 -vdw 246 3.2500 0.1700 -vdw 247 0.0000 0.0000 -vdw 248 3.5000 0.0660 -vdw 249 3.5000 0.0660 -vdw 250 3.5000 0.0660 -vdw 251 3.5000 0.0660 -vdw 252 3.2500 0.1700 -vdw 253 0.0000 0.0000 -vdw 254 3.2500 0.1700 -vdw 255 3.5000 0.0800 -vdw 256 3.2500 0.1700 -vdw 257 0.0000 0.0000 -vdw 258 3.5000 0.0800 -vdw 259 2.5000 0.0500 -vdw 260 3.5000 0.0800 -vdw 261 2.5000 0.0500 -vdw 262 3.2500 0.1700 -vdw 263 3.7500 0.1050 -vdw 264 3.2500 0.1700 -vdw 265 3.7500 0.1050 -vdw 266 3.5000 0.0800 -vdw 267 3.5000 0.0800 -vdw 268 0.0000 0.0000 -vdw 269 2.9600 0.2100 -vdw 270 0.0000 0.0000 -vdw 271 2.9600 0.2100 -vdw 272 2.5000 0.0500 -vdw 273 2.5000 0.0500 -vdw 274 3.5000 0.0800 -vdw 275 2.5000 0.0500 -vdw 276 3.2500 0.1700 -vdw 277 3.7500 0.1050 -vdw 278 3.2500 0.1700 -vdw 279 3.5000 0.0800 -vdw 280 3.5000 0.0800 -vdw 281 3.5000 0.0800 -vdw 282 0.0000 0.0000 -vdw 283 2.9600 0.2100 -vdw 284 3.2500 0.1700 -vdw 285 0.0000 0.0000 -vdw 286 0.0000 0.0000 -vdw 287 2.5000 0.0500 -vdw 288 2.5000 0.0500 -vdw 289 3.2500 0.1700 -vdw 290 3.5000 0.0800 -vdw 291 3.2500 0.1700 -vdw 292 3.5000 0.0800 -vdw 293 3.5000 0.0800 -vdw 294 3.5000 0.0800 -vdw 295 3.2500 0.1700 -vdw 296 3.5000 0.0800 -vdw 297 3.2500 0.1700 -vdw 298 2.5000 0.0500 -vdw 299 3.2500 0.1700 -vdw 300 0.0000 0.0000 -vdw 301 0.0000 0.0000 -vdw 302 2.5000 0.0500 -vdw 303 0.0000 0.0000 -vdw 304 3.2500 0.1700 -vdw 305 3.5000 0.0800 -vdw 306 3.2500 0.1700 -vdw 307 3.5000 0.0800 -vdw 308 3.5000 0.0800 -vdw 309 3.7500 0.1050 -vdw 310 0.0000 0.0000 -vdw 311 3.2500 0.1700 -vdw 312 0.0000 0.0000 -vdw 313 2.9600 0.2100 -vdw 314 3.5000 0.0800 -vdw 315 2.5000 0.0500 -vdw 316 3.5000 0.0800 -vdw 317 2.5000 0.0500 -vdw 318 3.5000 0.0800 -vdw 319 2.5000 0.0500 -vdw 320 3.2500 0.1700 -vdw 321 3.7500 0.1050 -vdw 322 3.2500 0.1700 -vdw 323 3.5000 0.0800 -vdw 324 3.5000 0.0800 -vdw 325 3.5000 0.0800 -vdw 326 0.0000 0.0000 -vdw 327 2.9600 0.2100 -vdw 328 0.0000 0.0000 -vdw 329 3.2500 0.1700 -vdw 330 0.0000 0.0000 -vdw 331 0.0000 0.0000 -vdw 332 2.5000 0.0500 -vdw 333 2.5000 0.0500 -vdw 334 3.5000 0.0800 -vdw 335 2.5000 0.0500 -vdw 336 3.7400 0.2000 -vdw 337 2.9600 0.2100 -vdw 338 3.0000 0.1700 -vdw 339 3.5500 0.0660 -vdw 340 3.5000 0.0800 -vdw 341 3.4000 0.3000 -vdw 342 3.5500 0.0760 -vdw 343 3.0500 0.7100 -vdw 344 4.0200 0.7100 -vdw 345 4.2800 0.7100 -vdw 346 4.8100 0.7100 -vdw 347 5.3400 0.0005 -vdw 348 2.8700 0.0005 -vdw 349 4.0700 0.0005 -vdw 350 5.1700 0.0005 -vdw 351 5.6000 0.0005 -vdw 352 6.2000 0.0005 -vdw 353 1.644471 0.875044 -vdw 354 2.412031 0.449657 -vdw 355 3.102688 0.118226 -vdw 356 3.816610 0.047096 -vdw 357 4.2000 0.3000 -vdw 358 2.5000 0.0500 -vdw 359 4.2500 0.5000 -vdw 360 4.2000 0.3000 -vdw 361 2.5000 0.0500 -vdw 362 3.1500 0.2500 -vdw 363 4.2000 0.3000 -vdw 364 2.5000 0.0500 -vdw 365 3.6500 0.1500 -vdw 366 3.4000 0.2500 -vdw 367 4.2000 0.3000 -vdw 368 2.5000 0.0500 -vdw 369 3.4000 0.2500 -vdw 370 2.5000 0.0500 -vdw 371 4.2000 0.3000 -vdw 372 2.5000 0.0500 -vdw 373 4.2000 0.3000 -vdw 374 2.5000 0.0500 -vdw 375 0.0000 0.0000 -vdw 376 3.2000 0.2500 -vdw 377 0.0000 0.0000 -vdw 378 2.81524 0.4000 -vdw 379 3.11815 0.2000 -vdw 380 2.9000 0.1400 -vdw 381 3.7400 0.2000 -vdw 382 3.1500 0.2000 -vdw 383 2.9000 0.1400 -vdw 384 3.5000 0.0660 -vdw 385 2.5000 0.0300 -vdw 386 3.7400 0.2000 -vdw 387 3.1500 0.2000 -vdw 388 2.9000 0.1400 -vdw 389 3.5000 0.0660 -vdw 390 2.5000 0.0300 -vdw 391 3.7400 0.2000 -vdw 392 3.1500 0.2000 -vdw 393 2.9000 0.1400 -vdw 394 3.5000 0.0660 -vdw 395 2.5000 0.0300 -vdw 396 3.5000 0.0660 -vdw 397 2.5000 0.0300 -vdw 398 3.5500 0.0700 -vdw 399 3.5000 0.0660 -vdw 400 2.5000 0.0300 -vdw 401 3.5500 0.0700 -vdw 402 3.5000 0.0660 -vdw 403 2.5000 0.0300 -vdw 404 3.5500 0.0700 -vdw 405 3.5000 0.0660 -vdw 406 3.7500 0.1050 -vdw 407 2.9600 0.2100 -vdw 408 3.0000 0.1700 -vdw 409 3.5000 0.0660 -vdw 410 2.4200 0.0150 -vdw 411 3.7500 0.1050 -vdw 412 3.7500 0.1050 -vdw 413 3.5500 0.0700 -vdw 414 3.0000 0.1700 -vdw 415 3.5500 0.2500 -vdw 416 2.9600 0.1700 -vdw 417 3.5000 0.0660 -vdw 418 2.5000 0.0300 -vdw 419 3.2500 0.1700 -vdw 420 0.0000 0.0000 -vdw 421 3.2500 0.1700 -vdw 422 0.0000 0.0000 -vdw 423 3.5000 0.0660 -vdw 424 2.5000 0.0300 -vdw 425 3.5000 0.0660 -vdw 426 2.5000 0.0300 -vdw 427 3.5000 0.0660 -vdw 428 2.5000 0.0300 -vdw 429 3.5500 0.0700 -vdw 430 3.5500 0.0700 -vdw 431 3.5000 0.0660 -vdw 432 3.5000 0.0660 -vdw 433 3.5000 0.0660 -vdw 434 3.5500 0.2500 -vdw 435 2.9600 0.1700 -vdw 436 3.5600 0.3950 -vdw 437 3.5600 0.3950 -vdw 438 2.9300 0.2800 -vdw 439 3.5000 0.0660 -vdw 440 3.5000 0.0660 -vdw 441 3.5500 0.0700 -vdw 442 3.5500 0.0700 -vdw 443 3.5500 0.0700 -vdw 444 3.2500 0.1700 -vdw 445 0.0000 0.0000 -vdw 446 3.5000 0.0660 -vdw 447 3.5500 0.0700 -vdw 448 3.5500 0.0700 -vdw 449 3.5500 0.0700 -vdw 450 3.5500 0.0700 -vdw 451 3.5500 0.0700 -vdw 452 3.2500 0.1700 -vdw 453 3.2500 0.1700 -vdw 454 0.0000 0.0000 -vdw 455 3.5500 0.0700 -vdw 456 3.5000 0.0660 -vdw 457 3.5000 0.0660 -vdw 458 3.5500 0.0760 -vdw 459 3.5500 0.0760 -vdw 460 3.5500 0.0700 -vdw 461 3.2500 0.1700 -vdw 462 3.5500 0.0700 -vdw 463 3.5500 0.0700 -vdw 464 3.5500 0.0700 -vdw 465 2.4200 0.0300 -vdw 466 2.4200 0.0300 -vdw 467 2.4200 0.0300 -vdw 468 3.2500 0.1700 -vdw 469 3.5500 0.0700 -vdw 470 2.4200 0.0300 -vdw 471 3.2500 0.1700 -vdw 472 3.5500 0.0700 -vdw 473 3.5500 0.0700 -vdw 474 3.5500 0.0700 -vdw 475 2.4200 0.0300 -vdw 476 2.4200 0.0300 -vdw 477 2.4200 0.0300 -vdw 478 3.2500 0.1700 -vdw 479 3.5500 0.0700 -vdw 480 3.5500 0.0700 -vdw 481 2.4200 0.0300 -vdw 482 2.4200 0.0300 -vdw 483 3.2500 0.1700 -vdw 484 3.5500 0.0700 -vdw 485 3.5500 0.0700 -vdw 486 0.0000 0.0000 -vdw 487 2.4200 0.0300 -vdw 488 2.4200 0.0300 -vdw 489 3.2500 0.1700 -vdw 490 3.2500 0.1700 -vdw 491 3.5500 0.0700 -vdw 492 3.5500 0.0700 -vdw 493 3.5500 0.0700 -vdw 494 0.0000 0.0000 -vdw 495 2.4200 0.0300 -vdw 496 2.4200 0.0300 -vdw 497 2.4200 0.0300 -vdw 498 3.2500 0.1700 -vdw 499 3.5500 0.0700 -vdw 500 3.2500 0.1700 -vdw 501 3.5500 0.0700 -vdw 502 3.5500 0.0700 -vdw 503 0.0000 0.0000 -vdw 504 2.4200 0.0300 -vdw 505 2.4200 0.0300 -vdw 506 2.4200 0.0300 -vdw 507 2.9000 0.1400 -vdw 508 3.5500 0.0700 -vdw 509 3.5500 0.0760 -vdw 510 2.4200 0.0300 -vdw 511 2.4200 0.0300 -vdw 512 2.9000 0.1400 -vdw 513 3.5500 0.0700 -vdw 514 3.2500 0.1700 -vdw 515 3.5500 0.0700 -vdw 516 3.5500 0.0700 -vdw 517 2.4200 0.0300 -vdw 518 2.4200 0.0300 -vdw 519 2.4200 0.0300 -vdw 520 2.9000 0.1400 -vdw 521 3.2500 0.1700 -vdw 522 3.5500 0.0700 -vdw 523 3.5500 0.0700 -vdw 524 3.5500 0.0700 -vdw 525 2.4200 0.0300 -vdw 526 2.4200 0.0300 -vdw 527 2.4200 0.0300 -vdw 528 3.2500 0.1700 -vdw 529 3.5500 0.0700 -vdw 530 3.5500 0.0700 -vdw 531 3.5500 0.0700 -vdw 532 3.5500 0.0700 -vdw 533 3.5500 0.0700 -vdw 534 3.5500 0.0700 -vdw 535 3.5500 0.0700 -vdw 536 3.5500 0.0700 -vdw 537 0.0000 0.0000 -vdw 538 2.4200 0.0300 -vdw 539 2.4200 0.0300 -vdw 540 2.4200 0.0300 -vdw 541 2.4200 0.0300 -vdw 542 2.4200 0.0300 -vdw 543 2.4200 0.0300 -vdw 544 3.2500 0.1700 -vdw 545 3.5500 0.0700 -vdw 546 3.5500 0.0700 -vdw 547 3.5500 0.0700 -vdw 548 3.5500 0.0700 -vdw 549 3.5500 0.0700 -vdw 550 3.5500 0.0700 -vdw 551 3.5500 0.0700 -vdw 552 3.5500 0.0700 -vdw 553 3.5500 0.0700 -vdw 554 2.4200 0.0300 -vdw 555 2.4200 0.0300 -vdw 556 2.4200 0.0300 -vdw 557 2.4200 0.0300 -vdw 558 2.4200 0.0300 -vdw 559 2.4200 0.0300 -vdw 560 2.4200 0.0300 -vdw 561 3.2500 0.1700 -vdw 562 3.5500 0.0700 -vdw 563 3.2500 0.1700 -vdw 564 3.5500 0.0700 -vdw 565 3.5500 0.0700 -vdw 566 3.5500 0.0700 -vdw 567 3.2500 0.1700 -vdw 568 3.5500 0.0700 -vdw 569 3.2500 0.1700 -vdw 570 2.4200 0.0300 -vdw 571 2.4200 0.0300 -vdw 572 2.4200 0.0300 -vdw 573 0.0000 0.0000 -vdw 574 3.5500 0.2500 -vdw 575 3.5500 0.0700 -vdw 576 3.2500 0.1700 -vdw 577 3.5500 0.0700 -vdw 578 3.5500 0.0700 -vdw 579 2.4200 0.0300 -vdw 580 2.4200 0.0300 -vdw 581 2.4200 0.0300 -vdw 582 3.2500 0.1700 -vdw 583 3.5500 0.0700 -vdw 584 2.4200 0.0300 -vdw 585 3.5500 0.0700 -vdw 586 3.5000 0.0660 -vdw 587 3.2500 0.1700 -vdw 588 3.5500 0.0700 -vdw 589 3.5500 0.0700 -vdw 590 3.5500 0.0700 -vdw 591 3.5500 0.0700 -vdw 592 3.5500 0.0700 -vdw 593 3.5500 0.0700 -vdw 594 2.4200 0.0300 -vdw 595 2.4200 0.0300 -vdw 596 2.4200 0.0300 -vdw 597 2.4200 0.0300 -vdw 598 3.2500 0.1700 -vdw 599 3.5500 0.0700 -vdw 600 3.2500 0.1700 -vdw 601 3.5500 0.0700 -vdw 602 3.5500 0.0700 -vdw 603 3.5000 0.0660 -vdw 604 2.4200 0.0300 -vdw 605 2.4200 0.0300 -vdw 606 2.4200 0.0300 -vdw 607 2.5000 0.0300 -vdw 608 3.5000 0.0660 -vdw 609 3.5000 0.0660 -vdw 610 3.5000 0.0660 -vdw 611 3.5000 0.0660 -vdw 612 3.5000 0.0660 -vdw 613 3.5000 0.0660 -vdw 614 3.5000 0.0660 -vdw 615 3.5000 0.0660 -vdw 616 3.5000 0.0660 -vdw 617 3.5000 0.0660 -vdw 618 3.5000 0.0660 -vdw 619 3.5000 0.0660 -vdw 620 3.5000 0.0660 -vdw 621 3.5000 0.0660 -vdw 622 3.5000 0.0660 -vdw 623 3.5500 0.2500 -vdw 624 0.0000 0.0000 -vdw 625 3.5500 0.0700 -vdw 626 3.7500 0.1050 -vdw 627 3.2500 0.1700 -vdw 628 3.5000 0.0660 -vdw 629 3.5000 0.0660 -vdw 630 3.5000 0.0660 -vdw 631 3.5500 0.0700 -vdw 632 3.5500 0.0700 -vdw 633 3.5500 0.0700 -vdw 634 3.5500 0.0700 -vdw 635 3.5500 0.0700 -vdw 636 3.5500 0.0700 -vdw 637 3.5500 0.2500 -vdw 638 3.4730 0.0540 -vdw 639 3.3000 0.0500 -vdw 640 3.3000 0.0500 -vdw 641 3.5500 0.0760 -vdw 642 3.5000 0.0660 -vdw 643 2.5000 0.0300 -vdw 644 3.7500 0.0600 -vdw 645 3.4730 0.0540 -vdw 646 3.3000 0.0500 -vdw 647 3.3000 0.0500 -vdw 648 2.9500 0.0400 -vdw 649 3.5500 0.0760 -vdw 650 3.4000 0.3000 -vdw 651 2.4200 0.0300 -vdw 652 3.5000 0.0660 -vdw 653 3.5000 0.0660 -vdw 654 3.5000 0.0660 -vdw 655 3.5500 0.0700 -vdw 656 2.4200 0.0300 -vdw 657 3.5500 0.0700 -vdw 658 2.4200 0.0300 -vdw 659 3.5500 0.0700 -vdw 660 2.8500 0.0610 -vdw 661 3.5500 0.0700 -vdw 662 2.8500 0.0610 -vdw 663 3.4700 0.4700 -vdw 664 3.9050 0.1180 -vdw 665 3.5500 0.0700 -vdw 666 3.2500 0.0620 -vdw 667 2.9400 0.0610 -vdw 668 3.5500 0.0700 -vdw 669 2.8500 0.0610 -vdw 670 3.5500 0.0700 -vdw 671 3.4700 0.4700 -vdw 672 3.5500 0.0700 -vdw 673 3.7500 0.6000 -vdw 674 3.5000 0.0660 -vdw 675 3.5500 0.2500 -vdw 676 3.5500 0.0700 -vdw 677 3.5500 0.0700 -vdw 678 3.5500 0.0700 -vdw 679 3.5500 0.0700 -vdw 680 3.5500 0.0700 -vdw 681 2.4200 0.0300 -vdw 682 2.4200 0.0300 -vdw 683 3.5500 0.0500 -vdw 684 3.2500 0.1700 -vdw 685 0.0000 0.0000 -vdw 686 0.0000 0.0000 -vdw 687 2.4200 0.0300 -vdw 688 3.5000 0.0660 -vdw 689 3.5000 0.0660 -vdw 690 3.2500 0.1700 -vdw 691 3.2500 0.1700 -vdw 692 3.2500 0.1700 -vdw 693 3.5500 0.0500 -vdw 694 3.2000 0.1700 -vdw 695 3.3000 0.0660 -vdw 696 3.3000 0.0660 -vdw 697 3.3000 0.0660 -vdw 698 3.3000 0.0660 -vdw 699 3.3000 0.0660 -vdw 700 2.5000 0.0150 -vdw 701 3.2500 0.1200 -vdw 702 2.9600 0.1700 -vdw 703 3.5000 0.0660 -vdw 704 2.5000 0.0150 -vdw 705 3.5000 0.0660 -vdw 706 3.5000 0.0660 -vdw 707 3.5000 0.0660 -vdw 708 3.2500 0.1200 -vdw 709 3.5500 0.0700 -vdw 710 3.3000 0.0660 -vdw 711 3.2500 0.1700 -vdw 712 2.9600 0.2100 -vdw 713 3.7500 0.1050 -vdw 714 3.0000 0.1700 -vdw 715 3.5000 0.0660 -vdw 716 3.5000 0.0660 -vdw 717 3.5000 0.0660 -vdw 718 2.4200 0.0150 -vdw 719 2.4200 0.0150 -vdw 720 2.4200 0.0150 -vdw 721 2.9000 0.1400 -vdw 722 3.7400 0.2000 -vdw 723 3.5000 0.0660 -vdw 724 3.5000 0.0660 -vdw 725 2.5000 0.0300 -vdw 726 3.7400 0.2000 -vdw 727 3.1181 0.0610 -vdw 728 3.1500 0.1700 -vdw 729 2.8600 0.2100 -vdw 730 3.3000 0.1700 -vdw 731 3.3000 0.1700 -vdw 732 3.3000 0.1700 -vdw 733 3.5000 0.0660 -vdw 734 3.5000 0.0660 -vdw 735 3.5000 0.0660 -vdw 736 3.5000 0.0660 -vdw 737 3.5000 0.0660 -vdw 738 3.5000 0.0660 -vdw 739 0.0000 0.0000 -vdw 740 0.0000 0.0000 -vdw 741 2.5000 0.0150 -vdw 742 3.5000 0.0660 -vdw 743 3.5000 0.0660 -vdw 744 3.5000 0.0660 -vdw 745 3.5000 0.0660 -vdw 746 3.5500 0.0700 -vdw 747 3.5500 0.0700 -vdw 748 3.5500 0.0700 -vdw 749 3.5000 0.0660 -vdw 750 3.5000 0.0660 -vdw 751 3.5000 0.0660 -vdw 752 3.5000 0.0660 -vdw 753 3.5000 0.0660 -vdw 754 3.5000 0.0660 -vdw 755 3.3000 0.0860 -vdw 756 2.4200 0.0150 -vdw 757 3.3000 0.2100 -vdw 758 3.3000 0.1350 -vdw 759 3.3000 0.1000 -vdw 760 2.5000 0.0150 -vdw 761 3.5000 0.0660 -vdw 762 3.5000 0.0660 -vdw 763 3.5000 0.0660 -vdw 764 3.1200 0.1700 -vdw 765 0.0000 0.0000 -vdw 766 3.2500 0.1700 -vdw 767 3.2500 0.1700 -vdw 768 3.2500 0.1700 -vdw 769 3.3000 0.2100 -vdw 770 3.2500 0.1700 -vdw 771 0.0000 0.0000 -vdw 772 3.5000 0.0660 -vdw 773 3.5000 0.0660 -vdw 774 3.5000 0.0660 -vdw 775 3.5000 0.0660 -vdw 776 3.5500 0.0700 -vdw 777 3.5500 0.0760 -vdw 778 3.5500 0.0700 -vdw 779 3.5500 0.0700 -vdw 780 2.5000 0.0300 -vdw 781 3.5000 0.0660 -vdw 782 3.7500 0.1050 -vdw 783 3.2500 0.1700 -vdw 784 2.9600 0.2100 -vdw 785 0.0000 0.0000 -vdw 786 2.9400 0.0610 -vdw 787 3.5000 0.0660 -vdw 788 2.5000 0.0300 -vdw 789 3.5000 0.0660 -vdw 790 3.5000 0.0660 -vdw 791 3.5000 0.0660 -vdw 792 3.5000 0.0660 -vdw 793 3.5000 0.0660 -vdw 794 3.5000 0.0970 -vdw 795 2.9500 0.0530 -vdw 796 3.2500 0.0620 -vdw 797 2.5000 0.0300 -vdw 798 3.5000 0.0660 -vdw 799 3.5000 0.0660 -vdw 800 3.4000 0.3000 -vdw 801 3.5000 0.0660 -vdw 802 2.5000 0.0300 -vdw 803 3.5000 0.0660 -vdw 804 3.5000 0.0660 -vdw 805 3.4700 0.4700 -vdw 806 3.5000 0.0660 -vdw 807 2.5000 0.0300 -vdw 808 3.5000 0.0660 -vdw 809 3.5000 0.0660 -vdw 810 2.9400 0.0610 -vdw 811 3.4000 0.3000 -vdw 812 3.4700 0.4700 -vdw 813 3.5500 0.0700 -vdw 814 2.9000 0.1400 -vdw 815 3.5000 0.0660 -vdw 816 2.9000 0.0600 -vdw 817 3.2500 0.1700 -vdw 818 3.5500 0.0700 -vdw 819 3.5000 0.0660 -vdw 820 3.7500 0.1050 -vdw 821 3.7500 0.1050 -vdw 822 2.9600 0.2100 -vdw 823 3.2500 0.1700 -vdw 824 0.0000 0.0000 -vdw 825 3.1200 0.1700 -vdw 826 0.0000 0.0000 -vdw 827 3.5000 0.0660 -vdw 828 3.5000 0.0660 -vdw 829 3.5500 0.0700 -vdw 830 3.5500 0.0700 -vdw 831 3.5500 0.0700 -vdw 832 3.5500 0.0700 -vdw 833 3.5500 0.0700 -vdw 834 1.9600 0.0125 -vdw 835 3.5000 0.0660 -vdw 836 3.5000 0.0660 -vdw 837 3.5000 0.0660 -vdw 838 3.7500 0.6000 -vdw 839 2.5000 0.0300 -vdw 840 3.2500 0.1700 -vdw 841 3.5500 0.0700 -vdw 842 3.5500 0.0700 -vdw 843 3.2500 0.1700 -vdw 844 3.5500 0.0700 -vdw 845 3.7500 0.1050 -vdw 846 2.9600 0.2100 -vdw 847 3.2500 0.1700 -vdw 848 3.5000 0.0660 -vdw 849 3.5000 0.0660 -vdw 850 3.5000 0.0660 -vdw 851 3.5000 0.0660 -vdw 852 2.4200 0.0150 -vdw 853 3.7500 0.1050 -vdw 854 2.9600 0.2100 -vdw 855 2.4200 0.0150 -vdw 856 3.5000 0.0660 -vdw 857 3.5000 0.0660 -vdw 858 3.5000 0.0660 -vdw 859 3.5000 0.0660 -vdw 860 3.5000 0.0660 -vdw 861 3.5000 0.0660 -vdw 862 3.5000 0.0660 -vdw 863 3.5000 0.0660 -vdw 864 3.5000 0.0660 -vdw 865 3.5000 0.0660 -vdw 866 4.0000 0.1000 -vdw 867 4.0000 0.1000 -vdw 868 4.0000 0.1000 -vdw 869 4.0000 0.1000 -vdw 870 2.5000 0.0300 -vdw 871 3.5000 0.0660 -vdw 872 3.5000 0.0660 -vdw 873 3.5000 0.0660 -vdw 874 3.5000 0.0660 -vdw 875 3.0800 0.7200 -vdw 876 4.1800 0.11779 -vdw 877 4.5100 0.0900 -vdw 878 5.1500 0.0700 -vdw 879 2.7000 0.018279 -vdw 880 3.3500 0.002772 -vdw 881 4.0600 0.000328 -vdw 882 4.3200 0.000171 -vdw 883 4.8200 0.000081 -vdw 884 2.9100 0.875044 -vdw 885 3.4700 0.449657 -vdw 886 3.8200 0.118226 -vdw 887 4.1800 0.047096 -vdw 888 3.5000 0.0660 -vdw 889 3.5000 0.0660 -vdw 890 3.5000 0.0660 -vdw 891 3.5000 0.0660 -vdw 892 2.5000 0.0300 -vdw 893 3.2500 0.1700 -vdw 894 3.5500 0.0700 -vdw 895 3.2500 0.1700 -vdw 896 3.5500 0.0700 -vdw 897 3.5500 0.0760 -vdw 898 3.5500 0.0760 -vdw 899 2.4200 0.0300 -vdw 900 3.3000 0.0860 -vdw 901 3.3000 0.0860 -vdw 902 3.3000 0.0860 -vdw 903 3.3000 0.0860 -vdw 904 3.3000 0.0860 -vdw 905 2.9600 0.2100 -vdw 906 3.5000 0.0660 - - - ################################## - ## ## - ## Bond Stretching Parameters ## - ## ## - ################################## - - -bond 1 2 367.00 1.3800 -bond 1 3 420.00 1.3570 -bond 1 13 367.00 1.3600 -bond 1 19 450.00 1.2790 -bond 1 25 300.00 0.3000 -bond 1 47 420.00 1.3400 -bond 1 48 420.00 1.3540 -bond 1 82 420.00 1.3540 -bond 1 83 420.00 1.3540 -bond 1 84 420.00 1.3540 -bond 1 87 420.00 1.3540 -bond 1 88 420.00 1.3540 -bond 1 108 461.00 1.5700 -bond 2 2 260.00 1.5260 -bond 2 3 317.00 1.5220 -bond 2 5 386.00 1.4250 -bond 2 6 260.00 1.5260 -bond 2 10 260.00 1.5260 -bond 2 11 317.00 1.5000 -bond 2 12 317.00 1.5100 -bond 2 13 260.00 1.5260 -bond 2 14 317.00 1.5000 -bond 2 15 222.00 1.8100 -bond 2 16 222.00 1.8100 -bond 2 20 320.00 1.4250 -bond 2 24 337.00 1.4490 -bond 2 44 382.00 1.4480 -bond 2 48 317.00 1.5100 -bond 2 51 260.00 1.5260 -bond 2 53 367.00 1.4710 -bond 2 55 337.00 1.4630 -bond 2 80 317.00 1.4950 -bond 3 3 350.00 1.5100 -bond 3 4 570.00 1.2290 -bond 3 5 450.00 1.3640 -bond 3 6 317.00 1.5220 -bond 3 10 317.00 1.5220 -bond 3 12 469.00 1.4000 -bond 3 13 317.00 1.5220 -bond 3 19 400.00 1.4440 -bond 3 20 214.00 1.3270 -bond 3 21 300.00 1.7900 -bond 3 24 490.00 1.3350 -bond 3 44 317.00 1.5220 -bond 3 46 340.00 1.0900 -bond 3 47 410.00 1.4440 -bond 3 48 400.00 1.4900 -bond 3 50 385.00 1.4600 -bond 3 52 656.00 1.2500 -bond 3 56 457.00 1.3580 -bond 3 57 418.00 1.3880 -bond 3 60 447.00 1.4190 -bond 3 65 300.00 1.9800 -bond 3 84 400.00 1.4900 -bond 3 86 385.00 1.4600 -bond 3 105 424.00 1.3830 -bond 3 107 490.00 1.3350 -bond 4 25 553.00 0.3000 -bond 4 64 525.00 1.4800 -bond 4 89 570.00 1.2290 -bond 4 110 700.00 1.1710 -bond 5 6 386.00 1.4250 -bond 5 7 553.00 0.9450 -bond 5 10 386.00 1.4250 -bond 5 13 320.00 1.4100 -bond 5 20 250.00 1.4700 -bond 5 24 400.00 1.3800 -bond 5 25 340.00 0.3000 -bond 5 44 320.00 1.4500 -bond 5 47 450.00 1.3700 -bond 5 48 450.00 1.3640 -bond 5 51 320.00 1.3800 -bond 5 64 230.00 1.6100 -bond 5 79 450.00 1.6700 -bond 5 106 94.00 1.8000 -bond 5 108 374.00 1.6400 -bond 6 6 260.00 1.5260 -bond 6 10 260.00 1.5260 -bond 6 11 317.00 1.5000 -bond 6 13 260.00 1.5260 -bond 6 14 317.00 1.5000 -bond 6 15 222.00 1.8100 -bond 6 16 222.00 1.8100 -bond 6 20 320.00 1.4250 -bond 6 24 337.00 1.4490 -bond 6 44 382.00 1.4480 -bond 6 47 317.00 1.5100 -bond 6 51 260.00 1.5260 -bond 6 53 367.00 1.4710 -bond 6 55 337.00 1.4630 -bond 6 79 222.00 1.8100 -bond 6 105 337.00 1.4750 -bond 7 20 553.00 0.9450 -bond 7 25 340.00 0.1000 -bond 9 9 530.00 1.3400 -bond 9 11 530.00 1.3400 -bond 9 14 530.00 1.3400 -bond 10 10 260.00 1.5260 -bond 10 11 317.00 1.5000 -bond 10 14 317.00 1.5000 -bond 10 20 320.00 1.4250 -bond 10 24 337.00 1.4490 -bond 10 44 382.00 1.4480 -bond 10 105 337.00 1.4750 -bond 11 11 530.00 1.3400 -bond 11 13 317.00 1.5000 -bond 11 14 530.00 1.3400 -bond 11 79 222.00 1.7600 -bond 12 12 469.00 1.4000 -bond 12 48 469.00 1.4000 -bond 12 60 469.00 1.4000 -bond 12 81 469.00 1.4000 -bond 13 13 268.00 1.5290 -bond 13 14 317.00 1.5000 -bond 13 15 222.00 1.8100 -bond 13 16 222.00 1.8100 -bond 13 18 390.00 1.4300 -bond 13 19 390.00 1.4700 -bond 13 20 320.00 1.4100 -bond 13 21 245.00 1.7810 -bond 13 22 340.00 1.7900 -bond 13 24 337.00 1.4490 -bond 13 25 340.00 0.3000 -bond 13 44 382.00 1.4480 -bond 13 46 340.00 1.0900 -bond 13 47 317.00 1.5100 -bond 13 48 317.00 1.5100 -bond 13 50 317.00 1.5100 -bond 13 51 268.00 1.5290 -bond 13 53 367.00 1.4710 -bond 13 55 337.00 1.4630 -bond 13 56 337.00 1.4490 -bond 13 57 337.00 1.4750 -bond 13 60 317.00 1.5100 -bond 13 64 212.00 1.8430 -bond 13 65 245.00 1.9450 -bond 13 66 200.00 2.1900 -bond 13 79 340.00 1.7700 -bond 13 80 317.00 1.4950 -bond 13 83 317.00 1.5040 -bond 13 84 317.00 1.5040 -bond 13 85 317.00 1.5040 -bond 13 87 317.00 1.4950 -bond 13 90 337.00 1.4490 -bond 13 91 280.00 1.5100 -bond 13 95 532.80 1.4600 -bond 13 101 382.00 1.4480 -bond 13 102 375.00 1.4900 -bond 13 104 212.00 1.8200 -bond 13 105 337.00 1.4750 -bond 13 107 337.00 1.4490 -bond 13 108 187.00 1.8600 -bond 13 109 317.00 1.5100 -bond 14 14 530.00 1.3400 -bond 15 17 274.00 1.3360 -bond 15 48 250.00 1.7400 -bond 16 16 166.00 2.0380 -bond 16 19 300.00 1.6850 -bond 16 24 250.00 1.7300 -bond 16 25 340.00 0.5000 -bond 16 47 250.00 1.7600 -bond 16 48 250.00 1.7600 -bond 16 61 250.00 1.7300 -bond 16 82 250.00 1.7600 -bond 16 84 250.00 1.7400 -bond 16 91 222.00 1.8100 -bond 16 108 144.00 2.1500 -bond 17 25 340.00 0.1000 -bond 18 18 550.00 1.1200 -bond 18 19 650.00 1.1570 -bond 18 48 400.00 1.4100 -bond 18 56 550.00 1.2400 -bond 19 19 1150.00 1.2100 -bond 19 21 330.00 1.6370 -bond 19 46 420.00 1.0800 -bond 19 47 400.00 1.4260 -bond 19 48 400.00 1.4510 -bond 19 50 400.00 1.4260 -bond 19 65 330.00 1.7840 -bond 19 88 400.00 1.4510 -bond 19 91 400.00 1.4510 -bond 20 20 250.00 1.4700 -bond 20 21 200.00 1.6900 -bond 20 24 320.00 1.4500 -bond 20 25 340.00 0.3000 -bond 20 44 320.00 1.4500 -bond 20 47 450.00 1.3700 -bond 20 48 450.00 1.3640 -bond 20 51 320.00 1.3800 -bond 20 60 340.00 1.3600 -bond 20 61 462.00 1.3990 -bond 20 64 230.00 1.6100 -bond 20 82 462.00 1.3570 -bond 20 84 340.00 1.3600 -bond 20 108 374.00 1.6400 -bond 21 25 300.00 0.3000 -bond 21 47 300.00 1.7250 -bond 21 48 300.00 1.7250 -bond 21 82 300.00 1.7250 -bond 21 83 300.00 1.7250 -bond 21 84 300.00 1.7250 -bond 21 87 300.00 1.7250 -bond 21 88 300.00 1.7250 -bond 21 108 223.00 2.0200 -bond 22 23 700.00 1.5300 -bond 22 25 340.00 0.5000 -bond 23 25 340.00 0.3000 -bond 23 79 700.00 1.4400 -bond 24 25 367.00 0.3000 -bond 24 45 434.00 1.0100 -bond 24 48 427.00 1.3810 -bond 24 59 427.00 1.3810 -bond 24 79 434.00 1.6700 -bond 24 84 427.00 1.3810 -bond 24 88 427.00 1.3810 -bond 24 91 337.00 1.4490 -bond 24 103 500.00 1.2700 -bond 24 106 40.00 2.0500 -bond 25 25 340.00 0.3000 -bond 25 44 340.00 0.3000 -bond 25 45 340.00 0.1000 -bond 25 46 340.00 0.3000 -bond 25 47 340.00 0.3000 -bond 25 48 367.00 0.3000 -bond 25 49 340.00 0.3000 -bond 25 53 340.00 0.3000 -bond 25 56 367.00 0.3000 -bond 25 61 367.00 0.3000 -bond 25 65 300.00 0.3000 -bond 25 103 340.00 0.1000 -bond 31 32 600.00 0.9572 -bond 31 33 900.00 0.1500 -bond 31 106 40.00 2.0500 -bond 34 35 529.60 0.9572 -bond 36 37 600.00 0.9572 -bond 36 38 900.00 0.1750 -bond 39 40 600.00 0.9572 -bond 39 41 900.00 0.7000 -bond 42 43 600.00 1.0000 -bond 44 44 350.00 1.4450 -bond 44 45 434.00 1.0100 -bond 44 48 481.00 1.3400 -bond 44 79 340.00 1.7700 -bond 44 91 382.00 1.4480 -bond 44 108 266.00 1.7400 -bond 45 53 434.00 1.0100 -bond 45 55 434.00 1.0100 -bond 45 56 434.00 1.0100 -bond 45 57 434.00 1.0100 -bond 45 101 434.00 1.0100 -bond 45 105 434.00 1.0100 -bond 45 108 166.00 1.4800 -bond 46 47 340.00 1.0800 -bond 46 50 340.00 1.0800 -bond 46 51 340.00 1.0900 -bond 46 80 340.00 1.0800 -bond 46 91 340.00 1.0880 -bond 46 95 532.80 1.0840 -bond 46 108 166.00 1.4800 -bond 46 109 340.00 1.0800 -bond 47 47 549.00 1.3400 -bond 47 48 427.00 1.4330 -bond 47 50 549.00 1.3400 -bond 47 57 448.00 1.3650 -bond 47 58 367.00 1.0800 -bond 47 65 300.00 1.9000 -bond 47 66 250.00 2.0800 -bond 47 86 385.00 1.4600 -bond 47 91 317.00 1.5100 -bond 47 105 448.00 1.3650 -bond 47 110 700.00 1.3050 -bond 48 48 469.00 1.4000 -bond 48 49 367.00 1.0800 -bond 48 50 427.00 1.4330 -bond 48 53 400.00 1.4500 -bond 48 55 481.00 1.3400 -bond 48 56 483.00 1.3390 -bond 48 57 427.00 1.3810 -bond 48 60 469.00 1.4040 -bond 48 61 414.00 1.3910 -bond 48 64 220.00 1.7800 -bond 48 65 300.00 1.8700 -bond 48 66 250.00 2.0800 -bond 48 79 340.00 1.7700 -bond 48 81 469.00 1.4000 -bond 48 84 546.00 1.3670 -bond 48 86 469.00 1.4000 -bond 48 88 469.00 1.4210 -bond 48 91 317.00 1.4900 -bond 48 101 382.00 1.3850 -bond 48 102 400.00 1.4600 -bond 48 109 427.00 1.4330 -bond 49 59 367.00 1.0800 -bond 49 62 340.00 1.0800 -bond 49 82 367.00 1.0800 -bond 49 83 367.00 1.0800 -bond 49 84 367.00 1.0800 -bond 49 85 367.00 1.0800 -bond 49 87 367.00 1.0800 -bond 49 88 367.00 1.0800 -bond 50 50 385.00 1.4600 -bond 50 56 457.00 1.2900 -bond 50 84 549.00 1.3650 -bond 50 109 385.00 1.4600 -bond 51 105 337.00 1.4750 -bond 52 64 525.00 1.4800 -bond 53 54 434.00 1.0100 -bond 54 55 434.00 1.0100 -bond 55 59 481.00 1.3400 -bond 55 82 481.00 1.3400 -bond 56 56 500.00 1.3200 -bond 56 59 502.00 1.3240 -bond 56 60 461.00 1.3540 -bond 56 82 461.00 1.3540 -bond 56 86 483.00 1.3390 -bond 56 103 550.00 1.2100 -bond 56 109 457.00 1.2900 -bond 57 60 436.00 1.3740 -bond 57 61 400.00 1.3490 -bond 57 62 440.00 1.3710 -bond 57 81 428.00 1.3800 -bond 57 82 477.00 1.3430 -bond 57 84 427.00 1.3810 -bond 57 85 427.00 1.3810 -bond 57 86 385.00 1.4400 -bond 58 83 367.00 1.0800 -bond 58 84 367.00 1.0800 -bond 59 63 367.00 1.0800 -bond 60 60 520.00 1.3700 -bond 60 61 414.00 1.3910 -bond 60 80 388.00 1.4590 -bond 60 81 447.00 1.4190 -bond 60 87 469.00 1.4240 -bond 60 105 436.00 1.3740 -bond 61 61 400.00 1.2800 -bond 61 62 529.00 1.3040 -bond 61 82 488.00 1.3350 -bond 61 83 410.00 1.3940 -bond 61 84 410.00 1.3940 -bond 61 88 410.00 1.3200 -bond 62 63 367.00 1.0800 -bond 62 105 440.00 1.3710 -bond 63 82 367.00 1.0800 -bond 64 108 108.00 2.2500 -bond 65 82 300.00 1.8700 -bond 65 83 300.00 1.8700 -bond 65 84 300.00 1.8700 -bond 65 87 300.00 1.8700 -bond 65 88 300.00 1.8700 -bond 65 108 151.00 2.1900 -bond 66 82 250.00 2.0800 -bond 66 83 250.00 2.0800 -bond 66 84 250.00 2.0800 -bond 66 87 250.00 2.0800 -bond 66 88 250.00 2.0800 -bond 66 108 108.00 2.4400 -bond 77 78 500.00 1.8000 -bond 80 84 546.00 1.3520 -bond 82 86 385.00 1.4600 -bond 82 87 520.00 1.3700 -bond 83 84 520.00 1.3700 -bond 83 86 385.00 1.4600 -bond 84 84 512.00 1.3750 -bond 84 86 385.00 1.4600 -bond 84 87 546.00 1.3670 -bond 84 88 520.00 1.3700 -bond 85 85 520.00 1.3700 -bond 86 86 385.00 1.4600 -bond 86 87 385.00 1.4600 -bond 86 88 385.00 1.4600 -bond 87 87 469.00 1.4240 -bond 87 88 469.00 1.4240 -bond 89 90 490.00 1.3350 -bond 89 91 317.00 1.5220 -bond 90 91 337.00 1.4490 -bond 91 91 260.00 1.5200 -bond 102 103 550.00 1.2250 -bond 108 108 94.00 2.3200 -bond 109 109 549.00 1.3450 - - - ################################ - ## ## - ## Angle Bending Parameters ## - ## ## - ################################ - - -angle 25 1 25 33.00 109.47 -angle 1 2 2 50.00 109.50 -angle 2 2 2 63.00 112.40 -angle 2 2 3 63.00 112.40 -angle 2 2 5 80.00 109.50 -angle 2 2 6 63.00 112.40 -angle 6 2 6 63.00 112.40 -angle 5 2 6 80.00 109.50 -angle 2 2 10 63.00 112.40 -angle 3 2 10 63.00 112.40 -angle 6 2 10 63.00 112.40 -angle 10 2 10 63.00 112.40 -angle 5 2 10 80.00 109.50 -angle 10 2 12 63.00 114.00 -angle 6 2 13 63.00 112.40 -angle 10 2 15 50.00 108.60 -angle 2 2 16 50.00 114.70 -angle 10 2 16 50.00 114.70 -angle 2 2 20 80.00 109.50 -angle 6 2 20 80.00 109.50 -angle 10 2 20 80.00 109.50 -angle 3 2 24 80.00 110.30 -angle 2 2 24 80.00 111.20 -angle 2 2 44 56.20 109.47 -angle 6 2 44 56.20 109.47 -angle 10 2 44 56.20 109.47 -angle 13 2 44 56.20 109.47 -angle 3 2 44 80.00 111.20 -angle 2 2 48 63.00 112.40 -angle 10 2 48 63.00 114.00 -angle 2 2 51 63.00 112.40 -angle 6 2 51 63.00 112.40 -angle 2 2 53 80.00 111.20 -angle 2 2 55 80.00 111.20 -angle 10 2 80 63.00 115.60 -angle 2 3 4 80.00 120.40 -angle 1 3 4 80.00 121.00 -angle 3 3 4 80.00 121.40 -angle 4 3 4 80.00 126.00 -angle 4 3 5 80.00 121.00 -angle 4 3 6 80.00 120.40 -angle 5 3 10 70.00 115.00 -angle 4 3 10 80.00 120.40 -angle 5 3 12 70.00 120.00 -angle 12 3 12 85.00 120.00 -angle 5 3 13 70.00 108.00 -angle 13 3 13 70.00 116.00 -angle 1 3 13 80.00 111.00 -angle 3 3 13 80.00 117.20 -angle 4 3 13 80.00 120.40 -angle 10 3 20 81.00 111.40 -angle 13 3 20 81.00 111.40 -angle 4 3 20 83.00 123.40 -angle 13 3 21 75.00 109.00 -angle 4 3 21 75.00 119.00 -angle 24 3 24 70.00 114.20 -angle 2 3 24 70.00 116.60 -angle 3 3 24 70.00 116.60 -angle 6 3 24 70.00 116.60 -angle 10 3 24 70.00 116.60 -angle 13 3 24 70.00 116.60 -angle 4 3 24 80.00 122.90 -angle 20 3 24 81.00 111.40 -angle 13 3 44 70.00 116.00 -angle 4 3 44 80.00 120.40 -angle 13 3 46 35.00 115.00 -angle 46 3 46 35.00 115.00 -angle 4 3 46 35.00 123.00 -angle 24 3 46 40.00 114.00 -angle 5 3 46 40.00 115.00 -angle 20 3 46 40.00 115.00 -angle 24 3 47 70.00 115.50 -angle 4 3 47 80.00 125.30 -angle 46 3 48 35.00 115.00 -angle 24 3 48 70.00 115.50 -angle 13 3 48 70.00 116.00 -angle 5 3 48 70.00 120.00 -angle 4 3 48 80.00 120.40 -angle 20 3 48 81.00 111.40 -angle 48 3 48 85.00 120.00 -angle 13 3 50 70.00 116.00 -angle 46 3 50 80.00 116.00 -angle 4 3 50 80.00 124.00 -angle 10 3 52 65.00 117.00 -angle 2 3 52 70.00 117.00 -angle 6 3 52 70.00 117.00 -angle 13 3 52 70.00 117.00 -angle 48 3 52 70.00 117.00 -angle 4 3 52 80.00 126.00 -angle 52 3 52 80.00 126.00 -angle 46 3 56 35.00 116.00 -angle 46 3 56 35.00 122.00 -angle 4 3 56 80.00 122.50 -angle 47 3 57 70.00 114.10 -angle 56 3 57 70.00 118.60 -angle 57 3 57 70.00 118.60 -angle 4 3 57 80.00 120.60 -angle 24 3 60 70.00 111.30 -angle 57 3 60 70.00 111.30 -angle 4 3 60 80.00 128.80 -angle 13 3 65 75.00 109.00 -angle 4 3 65 75.00 119.00 -angle 44 3 84 70.00 116.00 -angle 4 3 84 80.00 120.40 -angle 4 3 87 80.00 128.20 -angle 57 3 105 70.00 115.40 -angle 56 3 105 70.00 118.60 -angle 4 3 105 80.00 120.90 -angle 13 3 107 70.00 116.60 -angle 4 3 107 80.00 122.90 -angle 25 4 25 10.00 117.00 -angle 3 4 25 35.00 113.00 -angle 3 5 7 35.00 113.00 -angle 2 5 7 55.00 108.50 -angle 6 5 7 55.00 108.50 -angle 7 5 10 55.00 108.50 -angle 7 5 13 55.00 108.50 -angle 7 5 24 49.00 105.40 -angle 25 5 25 5.00 109.47 -angle 7 5 25 10.00 109.47 -angle 13 5 25 10.00 109.47 -angle 7 5 47 35.00 109.00 -angle 25 5 48 10.00 109.47 -angle 7 5 48 35.00 113.00 -angle 7 5 51 55.00 108.50 -angle 7 5 64 55.00 108.50 -angle 13 5 64 100.00 120.50 -angle 7 5 79 74.00 110.00 -angle 7 5 106 100.00 126.00 -angle 5 7 25 10.00 109.47 -angle 25 7 25 33.00 109.47 -angle 2 10 2 63.00 112.40 -angle 2 10 3 63.00 111.10 -angle 2 10 5 80.00 109.50 -angle 3 10 6 63.00 111.10 -angle 6 10 6 63.00 111.50 -angle 2 10 6 63.00 112.40 -angle 5 10 6 80.00 109.50 -angle 3 10 10 63.00 111.10 -angle 2 10 10 63.00 111.50 -angle 6 10 10 63.00 111.50 -angle 10 10 10 63.00 111.50 -angle 5 10 10 80.00 109.50 -angle 2 10 20 80.00 109.50 -angle 6 10 20 80.00 109.50 -angle 10 10 20 80.00 109.50 -angle 3 10 24 63.00 110.10 -angle 6 10 24 80.00 109.50 -angle 2 10 24 80.00 109.70 -angle 10 10 24 80.00 109.70 -angle 2 10 44 56.20 109.47 -angle 6 10 44 56.20 109.47 -angle 10 10 44 56.20 109.47 -angle 13 10 44 56.20 109.47 -angle 3 10 44 80.00 109.70 -angle 2 10 48 63.00 112.40 -angle 20 10 48 80.00 109.50 -angle 2 10 105 80.00 109.50 -angle 10 10 105 80.00 109.50 -angle 20 10 105 80.00 109.50 -angle 2 11 2 70.00 124.00 -angle 2 11 6 70.00 124.00 -angle 6 11 6 70.00 124.00 -angle 2 11 9 70.00 118.00 -angle 6 11 9 70.00 118.00 -angle 9 11 10 70.00 118.00 -angle 2 11 10 70.00 124.00 -angle 6 11 10 70.00 124.00 -angle 10 11 10 70.00 124.00 -angle 2 11 11 70.00 118.00 -angle 6 11 11 70.00 118.00 -angle 9 11 11 70.00 118.00 -angle 10 11 11 70.00 118.00 -angle 11 11 11 70.00 118.00 -angle 9 11 13 70.00 118.00 -angle 11 11 13 70.00 118.00 -angle 2 11 13 70.00 124.00 -angle 6 11 13 70.00 124.00 -angle 10 11 13 70.00 124.00 -angle 13 11 13 70.00 124.00 -angle 9 11 14 70.00 118.00 -angle 11 11 14 70.00 118.00 -angle 9 11 79 70.00 118.00 -angle 2 12 12 70.00 120.00 -angle 3 12 12 85.00 120.00 -angle 12 12 12 85.00 120.00 -angle 12 12 48 85.00 120.00 -angle 12 12 60 85.00 120.00 -angle 12 12 81 85.00 120.00 -angle 1 13 1 77.00 109.10 -angle 2 13 2 40.00 109.50 -angle 1 13 3 50.00 109.50 -angle 2 13 3 63.00 111.10 -angle 3 13 3 63.00 111.10 -angle 2 13 6 40.00 109.50 -angle 6 13 6 40.00 109.50 -angle 3 13 6 63.00 109.50 -angle 1 13 13 50.00 109.50 -angle 5 13 13 50.00 109.50 -angle 13 13 13 58.35 112.70 -angle 3 13 13 63.00 111.10 -angle 13 13 15 50.00 108.60 -angle 13 13 16 50.00 114.70 -angle 13 13 19 58.35 112.70 -angle 3 13 20 50.00 109.50 -angle 13 13 20 50.00 109.50 -angle 3 13 21 69.00 109.80 -angle 13 13 21 69.00 109.80 -angle 21 13 21 78.00 111.70 -angle 13 13 22 50.00 108.60 -angle 20 13 24 50.00 109.50 -angle 3 13 24 63.00 110.10 -angle 2 13 24 80.00 109.70 -angle 13 13 24 80.00 109.70 -angle 16 13 44 50.00 114.70 -angle 2 13 44 56.20 109.47 -angle 6 13 44 56.20 109.47 -angle 10 13 44 56.20 109.47 -angle 13 13 44 56.20 109.47 -angle 3 13 44 80.00 111.20 -angle 46 13 46 33.00 107.80 -angle 18 13 46 35.00 108.50 -angle 19 13 46 35.00 108.50 -angle 2 13 46 35.00 109.50 -angle 3 13 46 35.00 109.50 -angle 5 13 46 35.00 109.50 -angle 15 13 46 35.00 109.50 -angle 16 13 46 35.00 109.50 -angle 20 13 46 35.00 109.50 -angle 22 13 46 35.00 109.50 -angle 24 13 46 35.00 109.50 -angle 44 13 46 35.00 109.50 -angle 13 13 46 37.50 110.70 -angle 1 13 46 40.00 107.00 -angle 21 13 46 51.00 107.60 -angle 46 13 47 35.00 109.50 -angle 1 13 47 50.00 109.50 -angle 13 13 47 63.00 111.10 -angle 47 13 47 63.00 112.40 -angle 46 13 48 35.00 109.50 -angle 47 13 48 40.00 109.50 -angle 48 13 48 40.00 109.50 -angle 1 13 48 50.00 109.50 -angle 5 13 48 50.00 109.50 -angle 20 13 48 50.00 109.50 -angle 16 13 48 50.00 114.70 -angle 3 13 48 63.00 112.00 -angle 2 13 48 63.00 114.00 -angle 13 13 48 63.00 114.00 -angle 44 13 48 80.00 111.20 -angle 46 13 50 35.00 109.50 -angle 46 13 51 37.50 110.70 -angle 5 13 51 50.00 109.50 -angle 13 13 51 58.35 112.70 -angle 46 13 53 35.00 109.50 -angle 3 13 53 80.00 111.20 -angle 13 13 53 80.00 111.20 -angle 46 13 55 35.00 109.50 -angle 13 13 55 80.00 111.20 -angle 46 13 56 35.00 109.50 -angle 3 13 56 63.00 110.10 -angle 13 13 56 65.00 109.00 -angle 46 13 57 35.00 109.50 -angle 48 13 57 80.00 111.20 -angle 46 13 60 35.00 109.50 -angle 13 13 60 63.00 114.00 -angle 46 13 64 41.00 109.50 -angle 13 13 64 43.00 109.50 -angle 48 13 64 43.00 109.50 -angle 46 13 65 51.00 107.60 -angle 3 13 65 69.00 109.80 -angle 13 13 65 69.00 110.00 -angle 48 13 65 69.00 110.00 -angle 65 13 65 78.00 111.70 -angle 46 13 66 75.00 111.00 -angle 13 13 66 75.00 112.00 -angle 46 13 79 35.00 109.50 -angle 13 13 79 50.00 108.60 -angle 1 13 79 50.00 109.50 -angle 46 13 80 35.00 109.50 -angle 13 13 80 63.00 115.60 -angle 46 13 83 35.00 109.50 -angle 13 13 83 63.00 114.00 -angle 46 13 84 35.00 109.50 -angle 16 13 84 50.00 114.70 -angle 13 13 84 63.00 114.00 -angle 46 13 85 35.00 109.50 -angle 13 13 85 63.00 114.00 -angle 46 13 87 35.00 109.50 -angle 13 13 87 63.00 115.60 -angle 46 13 90 35.00 109.50 -angle 13 13 90 80.00 110.00 -angle 3 13 90 80.00 113.00 -angle 46 13 91 37.50 110.70 -angle 46 13 95 35.00 105.00 -angle 13 13 95 63.00 105.00 -angle 46 13 101 35.00 109.50 -angle 13 13 101 80.00 111.20 -angle 46 13 102 35.00 105.00 -angle 13 13 102 63.00 111.10 -angle 46 13 104 41.00 109.50 -angle 13 13 104 43.00 109.50 -angle 46 13 105 35.00 109.50 -angle 13 13 105 50.00 109.50 -angle 20 13 105 50.00 109.50 -angle 46 13 107 35.00 109.50 -angle 13 13 107 80.00 109.70 -angle 46 13 108 35.00 109.50 -angle 13 13 108 60.00 112.00 -angle 2 14 2 70.00 124.00 -angle 2 14 6 70.00 124.00 -angle 6 14 6 70.00 124.00 -angle 2 14 9 70.00 118.00 -angle 6 14 9 70.00 118.00 -angle 9 14 10 70.00 118.00 -angle 2 14 10 70.00 124.00 -angle 6 14 10 70.00 124.00 -angle 10 14 10 70.00 124.00 -angle 2 14 11 70.00 118.00 -angle 6 14 11 70.00 118.00 -angle 9 14 11 70.00 118.00 -angle 10 14 11 70.00 118.00 -angle 11 14 11 70.00 118.00 -angle 9 14 13 70.00 118.00 -angle 11 14 13 70.00 118.00 -angle 2 14 13 70.00 124.00 -angle 6 14 13 70.00 124.00 -angle 10 14 13 70.00 124.00 -angle 13 14 13 70.00 124.00 -angle 2 14 14 70.00 118.00 -angle 6 14 14 70.00 118.00 -angle 9 14 14 70.00 118.00 -angle 10 14 14 70.00 118.00 -angle 11 14 14 70.00 118.00 -angle 13 14 14 70.00 118.00 -angle 14 14 14 70.00 118.00 -angle 17 15 17 35.00 92.07 -angle 2 15 17 44.00 96.00 -angle 6 15 17 44.00 96.00 -angle 13 15 17 44.00 96.00 -angle 25 15 25 5.00 109.47 -angle 13 15 25 10.00 109.47 -angle 33 15 33 10.00 160.00 -angle 2 15 33 150.00 96.70 -angle 6 15 33 150.00 96.70 -angle 13 15 33 150.00 96.70 -angle 17 15 33 150.00 96.70 -angle 17 15 48 50.00 96.00 -angle 2 16 6 62.00 98.90 -angle 13 16 13 62.00 98.90 -angle 2 16 16 68.00 103.70 -angle 6 16 16 68.00 103.70 -angle 13 16 16 68.00 103.70 -angle 13 16 19 65.00 100.00 -angle 25 16 25 5.00 109.47 -angle 13 16 25 10.00 109.47 -angle 33 16 33 10.00 160.00 -angle 2 16 33 150.00 96.70 -angle 6 16 33 150.00 96.70 -angle 13 16 33 150.00 96.70 -angle 16 16 33 150.00 96.70 -angle 13 16 48 62.00 104.20 -angle 47 16 48 62.00 104.20 -angle 24 16 60 74.00 92.40 -angle 25 16 61 10.00 130.00 -angle 25 16 82 10.00 130.00 -angle 60 16 82 74.00 97.00 -angle 25 16 84 10.00 130.00 -angle 82 16 84 74.00 90.00 -angle 60 16 84 74.00 97.00 -angle 84 16 84 74.00 97.00 -angle 13 16 91 62.00 94.00 -angle 15 17 25 10.00 109.47 -angle 25 17 25 33.00 109.47 -angle 13 18 19 150.00 180.00 -angle 19 18 48 170.00 180.00 -angle 18 18 56 100.00 180.00 -angle 13 19 18 150.00 180.00 -angle 16 19 19 140.00 180.00 -angle 13 19 19 150.00 180.00 -angle 18 19 25 10.00 90.00 -angle 19 19 46 112.00 180.00 -angle 18 19 47 150.00 180.00 -angle 19 19 47 160.00 180.00 -angle 18 19 48 150.00 180.00 -angle 19 19 48 160.00 180.00 -angle 19 19 50 160.00 180.00 -angle 18 19 55 150.00 180.00 -angle 18 19 88 150.00 180.00 -angle 2 20 2 100.00 111.80 -angle 2 20 3 83.00 116.90 -angle 3 20 6 83.00 116.90 -angle 2 20 6 100.00 111.80 -angle 2 20 7 55.00 108.50 -angle 7 20 10 55.00 108.50 -angle 3 20 10 83.00 116.90 -angle 10 20 10 100.00 111.80 -angle 13 20 13 60.00 109.50 -angle 3 20 13 83.00 116.90 -angle 25 20 25 5.00 109.47 -angle 13 20 25 10.00 109.47 -angle 13 20 47 75.00 111.00 -angle 25 20 48 10.00 109.47 -angle 13 20 48 75.00 111.00 -angle 47 20 48 75.00 111.00 -angle 48 20 48 75.00 111.00 -angle 3 20 48 83.00 116.90 -angle 2 20 48 100.00 111.80 -angle 13 20 51 60.00 109.50 -angle 2 20 51 100.00 113.00 -angle 6 20 51 100.00 113.00 -angle 10 20 51 100.00 113.00 -angle 24 20 60 70.00 104.50 -angle 25 20 61 10.00 125.00 -angle 2 20 64 100.00 120.50 -angle 6 20 64 100.00 120.50 -angle 10 20 64 100.00 120.50 -angle 13 20 64 100.00 120.50 -angle 48 20 64 100.00 120.50 -angle 64 20 64 100.00 120.50 -angle 25 20 82 10.00 125.00 -angle 60 20 82 70.00 106.50 -angle 82 20 82 70.00 107.00 -angle 25 20 84 10.00 125.00 -angle 82 20 84 70.00 104.00 -angle 60 20 84 70.00 106.50 -angle 84 20 84 70.00 106.50 -angle 61 20 84 70.00 108.90 -angle 108 20 108 20.00 145.00 -angle 13 20 108 40.00 130.00 -angle 25 21 25 33.00 109.47 -angle 13 22 13 62.00 96.00 -angle 13 22 23 74.00 107.00 -angle 23 22 25 10.00 90.00 -angle 2 24 3 50.00 121.90 -angle 3 24 3 70.00 126.40 -angle 3 24 5 46.00 115.70 -angle 2 24 6 50.00 121.90 -angle 3 24 6 50.00 121.90 -angle 2 24 10 50.00 118.00 -angle 3 24 10 50.00 121.90 -angle 13 24 13 50.00 118.00 -angle 3 24 13 50.00 121.90 -angle 3 24 16 70.00 112.00 -angle 3 24 20 70.00 108.60 -angle 3 24 25 10.00 109.50 -angle 25 24 45 10.00 100.00 -angle 5 24 45 35.00 110.20 -angle 3 24 45 35.00 119.80 -angle 45 24 45 35.00 120.00 -angle 2 24 45 38.00 118.40 -angle 6 24 45 38.00 118.40 -angle 10 24 45 38.00 118.40 -angle 13 24 45 38.00 118.40 -angle 45 24 48 35.00 119.80 -angle 13 24 48 50.00 118.00 -angle 3 24 48 50.00 121.90 -angle 48 24 48 70.00 118.00 -angle 54 24 54 35.00 120.00 -angle 45 24 59 35.00 118.00 -angle 3 24 59 70.00 125.20 -angle 13 24 79 50.00 120.00 -angle 45 24 79 100.00 111.00 -angle 45 24 84 35.00 119.80 -angle 48 24 84 70.00 118.00 -angle 16 24 86 70.00 117.00 -angle 45 24 87 35.00 119.80 -angle 48 24 87 70.00 118.00 -angle 45 24 88 35.00 119.80 -angle 48 24 88 70.00 118.00 -angle 45 24 91 40.00 113.00 -angle 3 24 91 55.00 128.00 -angle 48 24 103 70.00 121.00 -angle 3 24 106 20.00 126.00 -angle 25 25 25 33.00 109.47 -angle 32 31 32 75.00 104.52 -angle 32 31 33 50.00 52.26 -angle 35 34 35 34.05 104.52 -angle 37 36 37 75.00 109.50 -angle 37 36 38 50.00 54.75 -angle 40 39 40 75.00 104.52 -angle 41 39 41 50.00 109.47 -angle 40 39 41 50.00 110.6948 -angle 43 42 43 75.00 109.47 -angle 2 44 2 51.80 107.20 -angle 2 44 6 51.80 107.20 -angle 6 44 6 51.80 107.20 -angle 2 44 10 51.80 107.20 -angle 6 44 10 51.80 107.20 -angle 10 44 10 51.80 107.20 -angle 2 44 13 51.80 107.20 -angle 6 44 13 51.80 107.20 -angle 10 44 13 51.80 107.20 -angle 13 44 13 51.80 107.20 -angle 3 44 13 63.00 111.10 -angle 25 44 45 10.00 100.00 -angle 13 44 45 35.00 109.50 -angle 2 44 45 43.20 108.10 -angle 6 44 45 43.20 108.10 -angle 10 44 45 43.20 108.10 -angle 45 44 45 43.60 106.40 -angle 25 44 48 10.00 109.50 -angle 45 44 48 35.00 116.00 -angle 13 44 48 50.00 116.00 -angle 48 44 48 50.00 116.00 -angle 3 44 48 63.00 112.00 -angle 45 44 79 35.00 115.00 -angle 13 44 79 50.00 108.60 -angle 48 44 79 50.00 108.60 -angle 48 44 91 50.00 109.50 -angle 25 45 25 33.00 109.47 -angle 25 45 44 10.00 109.50 -angle 25 46 25 33.00 109.47 -angle 13 46 25 37.50 109.47 -angle 1 47 1 80.00 108.00 -angle 1 47 3 80.00 121.50 -angle 3 47 6 85.00 119.70 -angle 3 47 13 70.00 119.70 -angle 13 47 13 70.00 130.00 -angle 25 47 46 10.00 90.00 -angle 20 47 46 35.00 114.50 -angle 13 47 46 35.00 117.00 -angle 46 47 46 35.00 117.00 -angle 3 47 46 35.00 119.70 -angle 19 47 46 35.00 120.00 -angle 1 47 46 50.00 112.00 -angle 21 47 46 60.00 114.00 -angle 25 47 47 2.00 90.00 -angle 46 47 47 35.00 120.00 -angle 5 47 47 70.00 123.00 -angle 20 47 47 70.00 123.00 -angle 13 47 47 70.00 124.00 -angle 19 47 47 70.00 124.00 -angle 21 47 47 75.00 121.50 -angle 1 47 47 80.00 121.50 -angle 16 47 47 85.00 119.40 -angle 3 47 47 85.00 120.70 -angle 46 47 48 35.00 123.30 -angle 47 47 48 85.00 117.00 -angle 13 47 48 85.00 119.70 -angle 25 47 50 2.00 90.00 -angle 46 47 50 35.00 120.00 -angle 5 47 50 70.00 123.00 -angle 20 47 50 70.00 123.00 -angle 13 47 50 70.00 124.00 -angle 46 47 57 35.00 119.10 -angle 13 47 57 70.00 120.00 -angle 20 47 57 70.00 120.00 -angle 47 47 57 70.00 121.20 -angle 16 47 57 85.00 119.40 -angle 57 47 58 35.00 119.10 -angle 47 47 58 35.00 119.70 -angle 46 47 65 60.00 114.00 -angle 47 47 65 75.00 120.00 -angle 46 47 91 35.00 135.00 -angle 3 47 91 70.00 119.70 -angle 47 47 91 70.00 124.00 -angle 46 47 105 35.00 119.10 -angle 58 47 105 35.00 119.10 -angle 13 47 105 70.00 120.00 -angle 20 47 105 70.00 120.00 -angle 47 47 105 70.00 121.20 -angle 16 47 105 85.00 119.40 -angle 46 47 110 40.00 121.00 -angle 13 47 110 80.00 122.00 -angle 48 47 110 80.00 122.00 -angle 1 47 110 80.00 125.00 -angle 2 48 12 70.00 120.00 -angle 12 48 12 85.00 120.00 -angle 3 48 13 70.00 119.70 -angle 25 48 48 10.00 90.00 -angle 48 48 48 63.00 120.00 -angle 2 48 48 70.00 120.00 -angle 5 48 48 70.00 120.00 -angle 10 48 48 70.00 120.00 -angle 13 48 48 70.00 120.00 -angle 15 48 48 70.00 120.00 -angle 19 48 48 70.00 120.00 -angle 20 48 48 70.00 120.00 -angle 24 48 48 70.00 120.00 -angle 44 48 48 70.00 120.00 -angle 47 48 48 70.00 124.00 -angle 21 48 48 75.00 120.00 -angle 1 48 48 80.00 120.00 -angle 18 48 48 80.00 120.00 -angle 16 48 48 85.00 119.40 -angle 3 48 48 85.00 120.00 -angle 25 48 49 2.00 90.00 -angle 24 48 49 35.00 119.10 -angle 3 48 49 35.00 120.00 -angle 48 48 49 35.00 120.00 -angle 48 48 50 70.00 124.00 -angle 48 48 53 70.00 120.00 -angle 55 48 55 70.00 120.00 -angle 47 48 55 70.00 120.10 -angle 48 48 55 70.00 120.10 -angle 49 48 56 35.00 116.00 -angle 13 48 56 70.00 116.00 -angle 44 48 56 70.00 116.00 -angle 55 48 56 70.00 119.30 -angle 5 48 56 70.00 120.00 -angle 47 48 56 70.00 121.50 -angle 50 48 56 70.00 121.50 -angle 48 48 56 70.00 124.00 -angle 21 48 56 75.00 120.00 -angle 49 48 57 35.00 120.00 -angle 48 48 57 70.00 108.70 -angle 55 48 57 70.00 116.00 -angle 13 48 57 70.00 120.00 -angle 47 48 57 70.00 121.50 -angle 56 48 57 70.00 123.30 -angle 49 48 60 35.00 120.00 -angle 48 48 60 63.00 120.00 -angle 57 48 60 70.00 108.70 -angle 56 48 60 70.00 117.30 -angle 55 48 60 70.00 123.50 -angle 2 48 60 70.00 128.60 -angle 13 48 60 70.00 128.60 -angle 49 48 61 35.00 119.10 -angle 48 48 61 70.00 108.70 -angle 57 48 61 70.00 123.30 -angle 48 48 64 85.00 119.40 -angle 48 48 65 75.00 120.00 -angle 48 48 66 75.00 120.00 -angle 48 48 79 85.00 119.40 -angle 49 48 81 35.00 120.00 -angle 48 48 81 85.00 120.00 -angle 49 48 84 35.00 126.90 -angle 60 48 84 63.00 106.40 -angle 48 48 84 70.00 107.40 -angle 49 48 86 35.00 120.00 -angle 48 48 86 63.00 120.00 -angle 56 48 86 70.00 124.00 -angle 49 48 88 35.00 128.20 -angle 101 48 101 70.00 111.80 -angle 56 48 101 70.00 124.10 -angle 48 48 102 85.00 120.00 -angle 48 48 109 70.00 124.00 -angle 25 50 46 10.00 90.00 -angle 19 50 46 35.00 120.00 -angle 25 50 47 2.00 90.00 -angle 46 50 47 35.00 120.00 -angle 3 50 47 70.00 118.70 -angle 13 50 47 70.00 124.00 -angle 46 50 48 35.00 123.30 -angle 47 50 48 85.00 117.00 -angle 25 50 50 2.00 90.00 -angle 46 50 50 35.00 120.00 -angle 13 50 50 70.00 124.00 -angle 47 50 50 70.00 124.00 -angle 50 50 84 35.00 106.00 -angle 46 50 84 35.00 122.00 -angle 46 50 109 35.00 120.00 -angle 13 50 109 70.00 124.00 -angle 47 50 109 70.00 124.00 -angle 6 51 6 40.00 109.50 -angle 5 51 13 50.00 109.50 -angle 13 51 20 50.00 109.50 -angle 2 51 20 80.00 109.50 -angle 6 51 20 80.00 109.50 -angle 5 51 20 92.60 111.55 -angle 20 51 20 92.60 111.55 -angle 46 51 46 33.00 109.50 -angle 5 51 46 35.00 109.50 -angle 20 51 46 35.00 109.50 -angle 13 51 46 37.50 110.70 -angle 46 51 105 35.00 109.50 -angle 13 51 105 50.00 109.50 -angle 20 51 105 50.00 109.50 -angle 13 53 13 50.00 113.00 -angle 13 53 25 10.00 100.00 -angle 45 53 45 43.60 109.50 -angle 25 53 48 10.00 100.00 -angle 13 53 48 55.00 114.00 -angle 2 53 54 35.00 109.50 -angle 6 53 54 35.00 109.50 -angle 13 53 54 35.00 109.50 -angle 48 53 54 35.00 109.50 -angle 54 53 54 35.00 109.50 -angle 25 53 82 10.00 100.00 -angle 13 55 13 50.00 118.00 -angle 45 55 45 35.00 113.00 -angle 13 55 45 35.00 118.40 -angle 45 55 48 35.00 120.00 -angle 2 55 48 50.00 123.20 -angle 6 55 48 50.00 123.20 -angle 13 55 48 50.00 123.20 -angle 2 55 54 35.00 118.40 -angle 13 55 54 35.00 118.40 -angle 48 55 54 35.00 120.00 -angle 54 55 54 35.00 120.00 -angle 45 55 59 35.00 120.00 -angle 3 56 13 70.00 120.50 -angle 13 56 18 70.00 120.00 -angle 25 56 48 5.00 120.00 -angle 45 56 48 35.00 113.00 -angle 13 56 48 50.00 118.00 -angle 48 56 48 70.00 117.00 -angle 3 56 48 70.00 120.50 -angle 13 56 56 70.00 117.00 -angle 48 56 56 70.00 117.00 -angle 25 56 59 5.00 119.80 -angle 48 56 59 70.00 118.60 -angle 59 56 59 70.00 118.60 -angle 59 56 60 70.00 111.00 -angle 48 56 60 70.00 112.20 -angle 59 56 82 70.00 111.00 -angle 48 56 86 70.00 117.00 -angle 13 56 103 70.00 114.00 -angle 3 57 3 70.00 126.40 -angle 3 57 45 35.00 116.80 -angle 45 57 47 35.00 119.20 -angle 3 57 47 70.00 121.60 -angle 45 57 48 35.00 118.00 -angle 3 57 48 70.00 125.20 -angle 48 57 48 70.00 125.20 -angle 45 57 60 30.00 125.80 -angle 13 57 60 70.00 125.80 -angle 60 57 61 56.00 113.10 -angle 45 57 61 56.00 118.40 -angle 13 57 61 70.00 118.40 -angle 48 57 61 70.00 118.40 -angle 45 57 62 30.00 128.80 -angle 60 57 62 70.00 105.40 -angle 48 57 62 70.00 109.80 -angle 13 57 62 70.00 128.80 -angle 45 57 81 35.00 123.10 -angle 45 57 82 35.00 120.00 -angle 61 57 82 56.00 113.10 -angle 60 57 82 70.00 109.80 -angle 45 57 84 35.00 120.00 -angle 61 57 84 56.00 113.10 -angle 60 57 84 70.00 109.80 -angle 82 57 84 70.00 109.80 -angle 84 57 84 70.00 109.80 -angle 81 57 84 70.00 111.60 -angle 45 57 85 35.00 120.00 -angle 82 57 85 70.00 109.80 -angle 24 59 55 70.00 116.00 -angle 49 59 56 35.00 115.45 -angle 13 59 56 70.00 115.50 -angle 55 59 56 70.00 119.30 -angle 24 59 56 70.00 123.30 -angle 56 59 56 70.00 129.10 -angle 56 59 63 35.00 115.45 -angle 13 60 48 70.00 120.00 -angle 48 60 48 85.00 134.90 -angle 56 60 57 70.00 126.20 -angle 57 60 60 70.00 106.20 -angle 20 60 60 70.00 110.60 -angle 16 60 60 70.00 111.00 -angle 13 60 60 70.00 120.00 -angle 24 60 60 70.00 127.70 -angle 56 60 60 70.00 127.70 -angle 48 60 60 85.00 117.30 -angle 3 60 60 85.00 119.20 -angle 60 60 61 70.00 111.00 -angle 24 60 61 70.00 126.20 -angle 3 60 61 70.00 130.00 -angle 48 60 61 70.00 132.40 -angle 12 60 80 85.00 134.90 -angle 48 60 80 85.00 134.90 -angle 80 60 81 85.00 108.80 -angle 12 60 81 85.00 116.20 -angle 48 60 81 85.00 116.20 -angle 3 60 84 70.00 130.00 -angle 60 60 87 70.00 107.30 -angle 57 60 87 70.00 107.70 -angle 81 60 87 85.00 108.80 -angle 12 60 87 85.00 134.90 -angle 48 60 87 85.00 134.90 -angle 60 60 105 70.00 106.20 -angle 56 60 105 70.00 126.20 -angle 48 61 48 70.00 125.20 -angle 25 61 57 10.00 125.00 -angle 25 61 61 10.00 125.00 -angle 60 61 62 70.00 103.80 -angle 25 61 82 10.00 125.00 -angle 61 61 82 70.00 109.00 -angle 60 61 82 70.00 110.00 -angle 82 61 83 70.00 110.00 -angle 57 61 84 70.00 104.10 -angle 82 61 84 70.00 110.00 -angle 57 61 88 70.00 104.10 -angle 20 61 88 70.00 105.30 -angle 49 62 57 35.00 120.00 -angle 49 62 61 35.00 120.00 -angle 57 62 61 70.00 113.90 -angle 57 62 63 35.00 123.05 -angle 61 62 63 35.00 123.05 -angle 49 62 105 35.00 120.00 -angle 63 62 105 35.00 123.05 -angle 61 62 105 70.00 113.90 -angle 5 64 5 45.00 102.60 -angle 4 64 5 100.00 108.23 -angle 4 64 13 45.00 109.50 -angle 5 64 20 45.00 102.60 -angle 20 64 20 45.00 102.60 -angle 13 64 20 45.00 109.50 -angle 4 64 20 100.00 108.23 -angle 4 64 48 45.00 109.50 -angle 5 64 48 45.00 109.50 -angle 20 64 48 45.00 109.50 -angle 5 64 52 45.00 108.23 -angle 13 64 52 45.00 109.50 -angle 20 64 52 100.00 108.23 -angle 52 64 52 140.00 119.90 -angle 25 65 25 33.00 109.47 -angle 25 66 25 33.00 109.47 -angle 78 77 78 150.00 180.00 -angle 6 79 11 62.00 98.90 -angle 13 79 13 62.00 102.00 -angle 5 79 13 75.00 96.40 -angle 5 79 23 74.00 108.70 -angle 13 79 23 74.00 108.90 -angle 23 79 23 104.00 119.00 -angle 13 79 24 100.00 103.00 -angle 23 79 24 120.00 107.00 -angle 13 79 44 62.00 102.00 -angle 23 79 44 74.00 108.90 -angle 13 79 48 62.00 102.00 -angle 23 79 48 74.00 107.20 -angle 5 79 48 75.00 96.40 -angle 24 79 48 100.00 103.00 -angle 13 79 82 62.00 102.00 -angle 46 80 60 35.00 126.80 -angle 2 80 60 70.00 128.60 -angle 13 80 60 70.00 128.60 -angle 46 80 84 35.00 126.80 -angle 2 80 84 70.00 125.00 -angle 13 80 84 70.00 125.00 -angle 60 80 84 85.00 106.40 -angle 12 81 57 70.00 132.80 -angle 48 81 57 70.00 132.80 -angle 57 81 60 70.00 104.40 -angle 12 81 60 85.00 122.70 -angle 48 81 60 85.00 122.70 -angle 13 82 16 70.00 125.00 -angle 16 82 24 70.00 125.00 -angle 16 82 44 70.00 120.20 -angle 20 82 49 35.00 117.00 -angle 16 82 49 35.00 125.00 -angle 49 82 57 35.00 120.00 -angle 57 82 57 70.00 120.00 -angle 13 82 57 70.00 125.00 -angle 48 82 57 70.00 125.00 -angle 56 82 57 70.00 126.20 -angle 49 82 61 35.00 120.00 -angle 16 82 61 70.00 113.60 -angle 16 82 61 70.00 115.00 -angle 20 82 61 70.00 115.00 -angle 57 82 61 70.00 120.00 -angle 13 82 61 70.00 125.00 -angle 44 82 61 70.00 126.10 -angle 24 82 61 70.00 126.20 -angle 57 82 79 70.00 120.00 -angle 61 82 79 70.00 120.00 -angle 20 82 86 70.00 122.00 -angle 61 82 86 70.00 130.00 -angle 57 82 87 70.00 106.20 -angle 56 82 87 70.00 127.70 -angle 49 83 61 35.00 120.00 -angle 48 83 61 70.00 111.00 -angle 13 83 61 70.00 124.50 -angle 49 83 84 35.00 128.20 -angle 61 83 84 70.00 111.00 -angle 13 83 84 70.00 130.70 -angle 13 84 16 70.00 125.00 -angle 13 84 20 70.00 121.60 -angle 16 84 24 70.00 125.00 -angle 20 84 49 35.00 113.40 -angle 16 84 49 35.00 125.00 -angle 48 84 49 35.00 130.70 -angle 49 84 50 35.00 130.70 -angle 20 84 50 70.00 110.00 -angle 49 84 57 35.00 121.60 -angle 13 84 57 70.00 121.60 -angle 48 84 57 70.00 121.60 -angle 3 84 57 85.00 120.00 -angle 57 84 58 35.00 120.00 -angle 13 84 61 70.00 118.90 -angle 49 84 80 35.00 120.00 -angle 57 84 80 70.00 108.70 -angle 49 84 83 35.00 130.70 -angle 57 84 83 70.00 106.30 -angle 20 84 83 70.00 108.00 -angle 16 84 83 70.00 111.00 -angle 13 84 83 70.00 130.70 -angle 13 84 84 70.00 120.00 -angle 57 84 84 70.00 120.00 -angle 61 84 84 70.00 120.00 -angle 20 84 86 70.00 121.60 -angle 57 84 86 70.00 121.60 -angle 49 84 87 35.00 132.10 -angle 57 84 87 70.00 107.70 -angle 20 84 87 70.00 110.60 -angle 16 84 87 70.00 111.00 -angle 61 84 87 70.00 111.90 -angle 13 84 87 70.00 132.10 -angle 48 84 87 70.00 132.10 -angle 86 84 87 70.00 132.10 -angle 3 84 87 85.00 120.00 -angle 49 85 57 35.00 120.00 -angle 13 85 57 70.00 121.60 -angle 49 85 85 35.00 130.70 -angle 57 85 85 70.00 106.30 -angle 13 85 85 70.00 130.70 -angle 48 86 48 63.00 120.00 -angle 48 86 56 70.00 124.00 -angle 48 86 82 63.00 120.00 -angle 48 86 83 63.00 120.00 -angle 48 86 84 63.00 120.00 -angle 48 86 86 63.00 120.00 -angle 56 86 86 70.00 124.00 -angle 48 86 87 63.00 120.00 -angle 48 86 88 63.00 120.00 -angle 49 87 60 35.00 120.00 -angle 46 87 60 35.00 126.80 -angle 13 87 60 70.00 128.60 -angle 49 87 84 35.00 125.70 -angle 46 87 84 35.00 126.80 -angle 84 87 84 70.00 103.80 -angle 82 87 84 70.00 110.40 -angle 2 87 84 70.00 125.00 -angle 13 87 84 70.00 125.00 -angle 3 87 84 70.00 130.00 -angle 60 87 84 85.00 106.40 -angle 84 87 86 70.00 125.70 -angle 49 87 87 35.00 127.50 -angle 60 87 87 70.00 107.30 -angle 84 87 87 70.00 107.30 -angle 86 87 87 70.00 127.50 -angle 84 87 88 70.00 103.80 -angle 48 88 49 35.00 128.60 -angle 49 88 61 35.00 118.90 -angle 13 88 61 70.00 118.90 -angle 19 88 61 70.00 118.90 -angle 61 88 87 70.00 111.90 -angle 4 89 90 80.00 134.00 -angle 90 89 91 70.00 91.00 -angle 4 89 91 80.00 134.00 -angle 13 90 89 55.00 127.00 -angle 89 90 91 50.00 94.00 -angle 13 90 91 50.00 126.00 -angle 24 91 46 35.00 108.00 -angle 13 91 46 35.00 114.30 -angle 44 91 46 35.00 114.30 -angle 46 91 46 35.00 114.30 -angle 16 91 46 37.50 108.00 -angle 46 91 47 35.00 109.50 -angle 46 91 89 37.50 110.00 -angle 24 91 89 70.00 117.00 -angle 46 91 90 35.00 111.00 -angle 16 91 90 55.00 109.00 -angle 91 91 91 30.00 79.20 -angle 13 91 91 37.50 117.20 -angle 44 91 91 37.50 117.20 -angle 46 91 91 37.50 117.20 -angle 24 91 91 37.50 126.00 -angle 16 91 91 55.00 128.00 -angle 89 91 91 63.00 85.00 -angle 47 91 91 63.00 114.00 -angle 90 91 91 80.00 89.00 -angle 13 95 13 172.80 120.00 -angle 13 95 46 144.00 120.00 -angle 13 101 45 35.00 109.50 -angle 45 101 45 43.60 106.40 -angle 45 101 48 50.00 112.50 -angle 13 101 48 50.00 120.50 -angle 13 102 103 80.00 117.50 -angle 48 102 103 80.00 117.50 -angle 103 102 103 80.00 125.00 -angle 25 103 25 10.00 109.50 -angle 25 103 102 10.00 109.50 -angle 13 104 13 45.00 109.50 -angle 3 105 10 70.00 117.60 -angle 3 105 13 70.00 117.60 -angle 3 105 45 35.00 119.20 -angle 45 105 47 35.00 119.20 -angle 13 105 47 70.00 121.20 -angle 3 105 47 70.00 121.60 -angle 3 105 51 70.00 117.60 -angle 47 105 51 70.00 121.20 -angle 45 105 60 30.00 125.80 -angle 6 105 60 70.00 125.80 -angle 10 105 60 70.00 125.80 -angle 13 105 60 70.00 125.80 -angle 51 105 60 70.00 125.80 -angle 45 105 62 30.00 128.80 -angle 60 105 62 70.00 105.40 -angle 6 105 62 70.00 128.80 -angle 10 105 62 70.00 128.80 -angle 13 105 62 70.00 128.80 -angle 51 105 62 70.00 128.80 -angle 4 106 24 20.00 109.50 -angle 24 106 24 20.00 109.50 -angle 13 107 13 50.00 118.00 -angle 3 107 13 50.00 121.90 -angle 1 108 13 35.00 110.50 -angle 13 108 13 60.00 110.00 -angle 13 108 20 60.00 100.00 -angle 20 108 20 60.00 110.00 -angle 13 108 21 35.00 110.50 -angle 45 108 45 35.00 109.50 -angle 13 108 45 35.00 110.50 -angle 46 108 46 35.00 109.50 -angle 13 108 46 35.00 110.50 -angle 13 108 65 35.00 110.50 -angle 13 108 66 35.00 110.50 -angle 13 108 108 50.00 112.00 -angle 46 109 48 35.00 123.30 -angle 46 109 50 35.00 120.00 -angle 13 109 50 70.00 124.00 -angle 46 109 109 35.00 120.00 -angle 13 109 109 70.00 124.00 -angle 50 109 109 70.00 124.00 -angle 48 109 109 85.00 117.00 -angle 4 110 47 160.00 180.00 -angle 47 110 47 160.00 180.00 - - - ################################ - ## ## - ## Urey-Bradley Parameters ## - ## ## - ################################ - - -ureybrad 35 34 35 38.25 1.5537 - - - ##################################### - ## ## - ## Improper Torsional Parameters ## - ## ## - ##################################### - - -imptors 0 0 3 4 21.000 180.0 2 -imptors 0 0 3 52 21.000 180.0 2 -imptors 0 0 24 0 5.000 180.0 2 -imptors 0 0 47 0 30.000 180.0 2 -imptors 0 0 48 0 5.000 180.0 2 - - - ############################ - ## ## - ## Torsional Parameters ## - ## ## - ############################ - - - ################################################################### - ## ## - ## Alternative Torsional Parameter Values for Use with OPLS-AA ## - ## ## - ## For some torsions, OPLS-AA has multiple possible parameter ## - ## values; the list below shows functional groups for which ## - ## these alternate (commented) values should be preferred; the ## - ## values are in the same order as in the full parameter list ## - ## ## - ## 4 3 3 36 generic (default) ## - ## 4 3 3 36 dicarbonyls ## - ## 36 3 3 36 hydrocarbon (default) ## - ## 36 3 3 36 dicarbonyls ## - ## 13 3 5 7 carboxylic acid (default) ## - ## 13 3 5 7 1,2-diacid monoanion ## - ## 4 3 13 13 peptide (default) ## - ## 4 3 13 13 propanamide ## - ## 4 3 13 13 carboxylic acid ## - ## 4 3 13 13 dicarboxylic acid ## - ## 4 3 13 13 aldyhyde, ketone, acyl halide ## - ## 4 3 13 13 1,2-diacid monoanion ## - ## 5 3 13 13 carboxylic acid (default) ## - ## 5 3 13 13 dicarboxylic acid ## - ## 35 3 13 13 peptide psi' (default) ## - ## 35 3 13 13 propanamide ## - ## 35 3 13 13 beta-3-peptide, last psi ## - ## 4 3 29 13 esters (default) ## - ## 4 3 29 13 benzoic esters ## - ## 7 5 13 13 alcohols (default) ## - ## 7 5 13 13 trifluoroethanol ## - ## 7 5 13 13 hexopyranoses ## - ## 7 5 13 36 alcohols (default) ## - ## 7 5 13 36 axial cyclohexanol ## - ## 7 5 13 36 trifluoroethanol ## - ## 0 13 13 13 alcohols, ethers (default) ## - ## 0 13 13 13 hexopyranoses ## - ## 3 13 13 3 dicarboxylic acid (default) ## - ## 3 13 13 3 1,2-diacid monoanion ## - ## 3 13 13 13 butanamide (default) ## - ## 3 13 13 13 carboxylate ion ## - ## 3 13 13 13 aldyhyde, ketone, acyl halide ## - ## 3 13 13 36 all carbonyls (default) ## - ## 3 13 13 36 dicarboxylic acid ## - ## 3 13 13 36 aldehyde, ketone, acyl halide ## - ## 5 13 13 5 diols only (default) ## - ## 5 13 13 5 triols only ## - ## 5 13 13 5 hexopyranoses ## - ## 13 13 13 13 hydrocarbon (default) ## - ## 13 13 13 13 perfluoroalkane ## - ## 13 13 13 35 peptide chi-1 (default) ## - ## 13 13 13 35 N-propylformamide ## - ## 36 13 13 69 generic (default) ## - ## 36 13 13 69 sulfone ## - ## 13 13 33 13 amine (default) ## - ## 13 13 33 13 exocyclic amine ## - ## 13 13 33 13 exocyclic 1,4-diamine ## - ## 13 13 33 34 amine (default) ## - ## 13 13 33 34 azetidine, 4-ring ## - ## 13 13 33 34 pyrrolidine, 5-ring ## - ## 13 13 33 34 cyclic amine ## - ## 13 13 33 34 cyclic 1,4-diamine ## - ## 13 13 35 3 peptide phi' (default) ## - ## 13 13 35 3 N-ethylformamide ## - ## 13 13 35 3 beta-3-peptide, first theta tors ## - ## 13 13 35 13 proline, CD-N-CA-CB (default) ## - ## 13 13 35 13 proline, CG-CD-N-CA ## - ## 36 13 35 3 peptide phi'' (default) ## - ## 36 13 35 3 N-methylformamide ## - ## 13 13 47 0 imidazole, indole, purine (default) ## - ## 13 13 47 0 nucleoside chi ## - ## 13 13 47 52 nucleoside (default) ## - ## 13 13 47 52 imidazole, indole, purine ## - ## 29 13 47 0 imidazole, indole, purine (default) ## - ## 29 13 47 0 nucleoside chi ## - ## 29 13 95 52 nucleoside (default) ## - ## 29 13 95 52 imidazole, indole, purine ## - ## 13 13 97 13 generic (default) ## - ## 13 13 97 13 generic ## - ## 17 15 38 0 aromatic thiol (default) ## - ## 17 15 38 0 aromatic thiol, N-C-S-H ## - ## 13 29 54 42 phosphonates (default) ## - ## 13 29 54 42 dimethyl phosphate ## - ## 34 35 72 16 diaryl amine (default) ## - ## 34 35 72 16 aniline-like ## - ## 34 35 72 29 diaryl amine (default) ## - ## 34 35 72 29 aniline-like ## - ## 13 40 40 37 diene (default) ## - ## 13 40 40 37 2-methyl-1,3-butadiene ## - ## 0 46 72 0 generic (default) ## - ## 0 46 72 0 generic ## - ## 0 47 72 0 generic (default) ## - ## 0 47 72 0 generic ## - ## 0 47 74 0 generic (default) ## - ## 0 47 74 0 generic ## - ## 0 47 74 0 generic ## - ## 0 51 72 0 generic (default) ## - ## 0 51 72 0 HA-CR-NB-?? or N?-CR-NB-?? ## - ## 0 72 77 0 generic (default) ## - ## 0 72 77 0 biphenyl-like, N-C-C-C ## - ## ## - ################################################################### - - -torsion 0 2 2 2 -2.500 0.0 1 1.250 180.0 2 3.100 0.0 3 -torsion 0 2 2 6 -2.500 0.0 1 1.250 180.0 2 3.100 0.0 3 -torsion 1 2 2 2 -2.000 0.0 1 0.700 180.0 2 3.000 0.0 3 -torsion 1 2 2 6 -2.000 0.0 1 0.700 180.0 2 3.000 0.0 3 -torsion 2 2 2 2 -3.400 0.0 1 1.250 180.0 2 3.100 0.0 3 -torsion 2 2 2 6 -3.400 0.0 1 1.250 180.0 2 3.100 0.0 3 -torsion 2 2 2 10 -3.400 0.0 1 1.250 180.0 2 3.100 0.0 3 -torsion 2 2 2 13 -3.400 0.0 1 1.250 180.0 2 3.100 0.0 3 -torsion 2 2 2 65 -2.000 0.0 1 0.500 180.0 2 3.250 0.0 3 -torsion 6 2 2 6 -3.400 0.0 1 1.250 180.0 2 3.100 0.0 3 -torsion 6 2 2 65 -2.000 0.0 1 0.500 180.0 2 3.250 0.0 3 -torsion 10 2 2 10 -3.400 0.0 1 1.250 180.0 2 3.100 0.0 3 -torsion 2 2 5 7 0.300 0.0 1 0.000 180.0 2 1.300 0.0 3 -torsion 6 2 5 7 0.300 0.0 1 0.000 180.0 2 1.300 0.0 3 -torsion 10 2 5 7 0.300 0.0 1 0.000 180.0 2 1.300 0.0 3 -torsion 0 2 10 2 -2.500 0.0 1 1.250 180.0 2 3.100 0.0 3 -torsion 2 2 10 2 -3.400 0.0 1 1.250 180.0 2 3.100 0.0 3 -torsion 2 2 13 2 -3.400 0.0 1 1.250 180.0 2 3.100 0.0 3 -torsion 6 2 20 2 -7.400 0.0 1 3.000 180.0 2 1.800 0.0 3 -torsion 6 2 20 6 -8.400 0.0 1 3.000 180.0 2 1.800 0.0 3 -torsion 4 3 3 4 1.600 0.0 1 3.200 180.0 2 0.000 0.0 3 -torsion 4 3 3 13 0.000 0.0 1 0.500 180.0 2 0.000 0.0 3 -torsion 4 3 3 24 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 4 3 3 46 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -#torsion 4 3 3 36 0.000 0.0 1 0.200 180.0 2 0.000 0.0 3 -torsion 13 3 3 13 0.700 0.0 1 -1.500 180.0 2 0.000 0.0 3 -torsion 13 3 3 24 -0.500 0.0 1 0.200 180.0 2 0.000 0.0 3 -torsion 13 3 3 46 0.800 0.0 1 -0.760 180.0 2 0.000 0.0 3 -torsion 24 3 3 46 -0.900 0.0 1 0.300 180.0 2 0.000 0.0 3 -torsion 46 3 3 46 0.000 0.0 1 0.000 180.0 2 0.300 0.0 3 -#torsion 36 3 3 36 0.800 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 3 3 5 7 3.000 0.0 1 5.500 180.0 2 0.000 0.0 3 -torsion 4 3 5 7 0.000 0.0 1 5.000 180.0 2 0.000 0.0 3 -torsion 13 3 5 7 1.500 0.0 1 5.500 180.0 2 0.000 0.0 3 -#torsion 13 3 5 7 3.200 0.0 1 4.900 180.0 2 0.000 0.0 3 -torsion 24 3 5 7 -2.000 0.0 1 5.000 180.0 2 0.000 0.0 3 -torsion 46 3 5 7 1.500 0.0 1 5.500 180.0 2 0.000 0.0 3 -torsion 48 3 5 7 4.000 0.0 1 5.000 180.0 2 0.000 0.0 3 -torsion 1 3 13 13 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 1 3 13 46 0.000 0.0 1 0.000 180.0 2 0.360 0.0 3 -torsion 3 3 13 46 0.000 0.0 1 0.000 180.0 2 0.085 0.0 3 -torsion 4 3 13 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 4 3 13 13 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -#torsion 4 3 13 13 0.000 0.0 1 1.166 180.0 2 0.000 0.0 3 -#torsion 4 3 13 13 0.000 0.0 1 0.546 180.0 2 0.000 0.0 3 -#torsion 4 3 13 13 -0.750 0.0 1 -0.550 180.0 2 -0.250 0.0 3 -#torsion 4 3 13 13 -0.277 0.0 1 1.228 180.0 2 -0.694 0.0 3 -#torsion 4 3 13 13 -1.000 0.0 1 -1.900 180.0 2 -0.900 0.0 3 -torsion 4 3 13 21 -0.650 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 4 3 13 44 0.000 0.0 1 0.820 180.0 2 0.000 0.0 3 -torsion 4 3 13 24 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 4 3 13 46 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 4 3 13 48 0.000 0.0 1 0.546 180.0 2 0.000 0.0 3 -torsion 5 3 13 13 0.000 0.0 1 1.412 180.0 2 0.000 0.0 3 -#torsion 5 3 13 13 1.000 0.0 1 0.546 180.0 2 0.450 0.0 3 -torsion 5 3 13 44 5.260 0.0 1 0.820 180.0 2 0.000 0.0 3 -torsion 5 3 13 46 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 3 13 13 1.454 0.0 1 -0.144 180.0 2 -0.775 0.0 3 -torsion 13 3 13 46 0.000 0.0 1 0.000 180.0 2 0.275 0.0 3 -torsion 20 3 13 13 0.000 0.0 1 0.000 180.0 2 -0.553 0.0 3 -torsion 20 3 13 46 0.000 0.0 1 0.000 180.0 2 0.132 0.0 3 -torsion 21 3 13 13 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 21 3 13 46 0.000 0.0 1 0.000 180.0 2 0.360 0.0 3 -torsion 24 3 13 13 1.173 0.0 1 0.189 180.0 2 -1.200 0.0 3 -#torsion 35 3 13 13 3.250 0.0 1 -0.402 180.0 2 -0.136 0.0 3 -#torsion 35 3 13 13 3.260 0.0 1 0.440 180.0 2 0.600 0.0 3 -torsion 24 3 13 21 0.650 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 24 3 13 24 1.816 0.0 1 1.222 180.0 2 1.581 0.0 3 -torsion 24 3 13 46 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 46 3 13 13 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 46 3 13 46 0.000 0.0 1 0.000 180.0 2 0.360 0.0 3 -torsion 48 3 13 46 0.000 0.0 1 0.000 180.0 2 0.275 0.0 3 -torsion 52 3 13 13 0.000 0.0 1 0.820 180.0 2 0.000 0.0 3 -torsion 52 3 13 44 0.000 0.0 1 0.820 180.0 2 0.000 0.0 3 -torsion 52 3 13 46 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 65 3 13 13 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 65 3 13 46 0.000 0.0 1 0.000 180.0 2 0.360 0.0 3 -torsion 107 3 13 46 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 4 3 20 13 0.000 0.0 1 5.124 180.0 2 0.000 0.0 3 -#torsion 4 3 29 13 0.000 0.0 1 5.000 180.0 2 0.000 0.0 3 -torsion 4 3 20 48 0.000 0.0 1 5.000 180.0 2 0.000 0.0 3 -torsion 13 3 20 13 4.669 0.0 1 5.124 180.0 2 0.000 0.0 3 -torsion 13 3 20 48 1.500 0.0 1 5.000 180.0 2 0.000 0.0 3 -torsion 24 3 20 13 -2.000 0.0 1 5.000 180.0 2 0.000 0.0 3 -torsion 46 3 20 13 4.669 0.0 1 5.124 180.0 2 0.000 0.0 3 -torsion 48 3 20 13 4.000 0.0 1 5.000 180.0 2 0.000 0.0 3 -torsion 3 3 24 13 0.400 0.0 1 4.900 180.0 2 0.000 0.0 3 -torsion 3 3 24 45 0.000 0.0 1 4.900 180.0 2 0.000 0.0 3 -torsion 4 3 24 5 0.000 0.0 1 6.603 180.0 2 0.000 0.0 3 -torsion 4 3 24 13 0.000 0.0 1 6.089 180.0 2 0.000 0.0 3 -torsion 4 3 24 45 0.000 0.0 1 4.900 180.0 2 0.000 0.0 3 -torsion 4 3 24 47 0.000 0.0 1 6.089 180.0 2 0.000 0.0 3 -torsion 4 3 24 48 0.000 0.0 1 6.089 180.0 2 0.000 0.0 3 -torsion 4 3 24 91 0.000 0.0 1 6.089 180.0 2 0.000 0.0 3 -torsion 5 3 24 13 2.300 0.0 1 6.089 180.0 2 0.000 0.0 3 -torsion 5 3 24 45 0.000 0.0 1 4.900 180.0 2 0.000 0.0 3 -torsion 13 3 24 5 4.542 0.0 1 6.603 180.0 2 1.045 0.0 3 -torsion 13 3 24 13 2.300 0.0 1 6.089 180.0 2 0.000 0.0 3 -torsion 13 3 24 45 0.000 0.0 1 4.900 180.0 2 0.000 0.0 3 -torsion 13 3 24 48 2.300 0.0 1 6.089 180.0 2 0.000 0.0 3 -torsion 20 3 24 13 2.300 0.0 1 6.089 180.0 2 0.000 0.0 3 -torsion 20 3 24 45 0.000 0.0 1 4.900 180.0 2 0.000 0.0 3 -torsion 24 3 24 3 2.300 0.0 1 6.089 180.0 2 0.000 0.0 3 -torsion 24 3 24 13 4.600 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 24 3 24 45 0.000 0.0 1 4.900 180.0 2 0.000 0.0 3 -torsion 46 3 24 13 2.300 0.0 1 6.089 180.0 2 0.000 0.0 3 -torsion 46 3 24 45 0.000 0.0 1 4.900 180.0 2 0.000 0.0 3 -torsion 47 3 24 45 0.000 0.0 1 4.900 180.0 2 0.000 0.0 3 -torsion 48 3 24 45 0.000 0.0 1 4.900 180.0 2 0.000 0.0 3 -torsion 48 3 24 48 2.300 0.0 1 6.089 180.0 2 0.000 0.0 3 -torsion 48 3 24 84 2.300 0.0 1 6.089 180.0 2 0.000 0.0 3 -torsion 48 3 24 87 2.300 0.0 1 6.089 180.0 2 0.000 0.0 3 -torsion 84 3 24 48 2.300 0.0 1 6.089 180.0 2 0.000 0.0 3 -torsion 84 3 24 84 2.300 0.0 1 6.089 180.0 2 0.000 0.0 3 -torsion 84 3 24 87 2.300 0.0 1 6.089 180.0 2 0.000 0.0 3 -torsion 87 3 24 45 0.000 0.0 1 4.900 180.0 2 0.000 0.0 3 -torsion 87 3 24 48 2.300 0.0 1 6.089 180.0 2 0.000 0.0 3 -torsion 87 3 24 84 2.300 0.0 1 6.089 180.0 2 0.000 0.0 3 -torsion 87 3 24 87 2.300 0.0 1 6.089 180.0 2 0.000 0.0 3 -torsion 0 3 47 13 0.900 0.0 1 0.230 180.0 2 -0.505 0.0 3 -torsion 4 3 47 46 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 4 3 47 47 2.500 0.0 1 6.000 180.0 2 0.000 0.0 3 -torsion 5 3 47 47 3.200 0.0 1 -3.000 180.0 2 0.000 0.0 3 -torsion 24 3 47 46 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 24 3 47 47 2.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 107 3 47 46 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 107 3 47 47 2.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 4 3 48 48 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -torsion 5 3 48 48 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -torsion 13 3 48 48 0.000 0.0 1 0.200 180.0 2 0.000 0.0 3 -torsion 20 3 48 48 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -torsion 24 3 48 48 0.000 0.0 1 1.100 180.0 2 0.000 0.0 3 -torsion 46 3 48 48 0.000 0.0 1 0.200 180.0 2 0.000 0.0 3 -torsion 0 3 50 13 0.900 0.0 1 0.230 180.0 2 -0.505 0.0 3 -torsion 4 3 50 47 2.500 0.0 1 6.000 180.0 2 0.000 0.0 3 -torsion 5 3 50 47 3.200 0.0 1 -3.000 180.0 2 0.000 0.0 3 -torsion 13 3 50 47 0.800 0.0 1 -3.000 180.0 2 0.000 0.0 3 -torsion 13 3 56 0 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 13 3 56 13 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 46 3 56 0 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 46 3 56 45 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 0 3 60 0 0.000 0.0 1 7.000 180.0 2 0.000 0.0 3 -torsion 4 3 60 0 0.000 0.0 1 7.000 180.0 2 0.000 0.0 3 -torsion 4 3 82 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 4 3 82 57 2.000 0.0 1 1.000 180.0 2 0.000 0.0 3 -torsion 4 3 82 61 0.000 0.0 1 1.000 180.0 2 0.000 0.0 3 -torsion 82 3 82 57 -2.000 0.0 1 1.000 180.0 2 0.000 0.0 3 -torsion 82 3 82 61 0.000 0.0 1 1.000 180.0 2 0.000 0.0 3 -torsion 4 3 84 20 -0.750 0.0 1 1.500 180.0 2 0.000 0.0 3 -torsion 4 3 84 87 0.750 0.0 1 1.500 180.0 2 0.000 0.0 3 -torsion 84 3 84 20 0.000 0.0 1 1.500 180.0 2 0.000 0.0 3 -torsion 84 3 84 87 0.000 0.0 1 1.500 180.0 2 0.000 0.0 3 -torsion 48 3 86 48 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 0 3 87 0 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 4 3 87 84 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -torsion 4 3 87 87 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -torsion 24 3 87 84 0.000 0.0 1 1.100 180.0 2 0.000 0.0 3 -torsion 24 3 87 87 0.000 0.0 1 1.100 180.0 2 0.000 0.0 3 -torsion 4 3 107 13 0.000 0.0 1 4.900 180.0 2 0.000 0.0 3 -torsion 13 3 107 13 0.000 0.0 1 4.900 180.0 2 0.000 0.0 3 -torsion 4 3 109 109 2.500 0.0 1 6.000 180.0 2 0.000 0.0 3 -torsion 5 3 109 109 3.200 0.0 1 -3.000 180.0 2 0.000 0.0 3 -torsion 0 4 106 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 7 5 10 2 0.300 0.0 1 0.000 180.0 2 0.500 0.0 3 -torsion 7 5 10 6 0.300 0.0 1 0.000 180.0 2 0.500 0.0 3 -torsion 7 5 13 2 0.000 0.0 1 0.000 180.0 2 0.200 0.0 3 -torsion 7 5 13 6 0.000 0.0 1 0.000 180.0 2 0.200 0.0 3 -torsion 7 5 13 13 -0.356 0.0 1 -0.174 180.0 2 0.492 0.0 3 -#torsion 7 5 13 13 4.478 0.0 1 -2.175 180.0 2 0.000 0.0 3 -#torsion 7 5 13 13 2.674 0.0 1 -2.883 180.0 2 1.026 0.0 3 -torsion 7 5 13 46 0.000 0.0 1 0.000 180.0 2 0.352 0.0 3 -#torsion 7 5 13 36 -2.589 0.0 1 -1.123 180.0 2 0.270 0.0 3 -#torsion 7 5 13 36 0.000 0.0 1 0.000 180.0 2 0.476 0.0 3 -torsion 7 5 13 47 -0.900 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 7 5 13 48 -0.900 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 7 5 13 50 -0.900 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 7 5 44 13 0.000 0.0 1 0.000 180.0 2 0.300 0.0 3 -torsion 7 5 44 45 0.000 0.0 1 0.000 180.0 2 0.300 0.0 3 -torsion 7 5 24 3 5.519 0.0 1 -6.700 180.0 2 0.581 0.0 3 -torsion 7 5 24 45 2.722 0.0 1 -5.154 180.0 2 0.000 0.0 3 -torsion 7 5 47 47 0.000 0.0 1 1.682 180.0 2 0.000 0.0 3 -torsion 7 5 48 48 0.000 0.0 1 1.682 180.0 2 0.000 0.0 3 -torsion 7 5 51 20 -1.257 0.0 1 -1.806 180.0 2 0.003 0.0 3 -torsion 7 5 56 3 3.000 0.0 1 3.000 180.0 2 0.000 0.0 3 -torsion 7 5 64 4 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 7 5 64 5 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 7 5 79 13 -0.750 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 7 5 79 23 0.750 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 7 5 79 48 2.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 0 13 13 3 -4.344 0.0 1 -1.714 180.0 2 0.000 0.0 3 -torsion 0 13 13 13 1.711 0.0 1 -0.500 180.0 2 0.663 0.0 3 -#torsion 0 13 13 13 -1.336 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 0 13 13 24 1.428 0.0 1 0.086 180.0 2 0.029 0.0 3 -torsion 1 13 13 1 -2.500 0.0 1 0.000 180.0 2 0.250 0.0 3 -torsion 1 13 13 5 0.000 0.0 1 0.000 180.0 2 0.540 0.0 3 -torsion 1 13 13 13 0.300 0.0 1 -0.400 180.0 2 0.400 0.0 3 -torsion 1 13 13 46 0.000 0.0 1 0.000 180.0 2 0.400 0.0 3 -torsion 3 13 13 3 -0.550 0.0 1 0.000 180.0 2 1.000 0.0 3 -#torsion 3 13 13 3 0.800 0.0 1 0.000 180.0 2 0.900 0.0 3 -torsion 3 13 13 5 -6.180 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 3 13 13 13 -2.060 0.0 1 -0.313 180.0 2 0.315 0.0 3 -#torsion 3 13 13 13 -3.185 0.0 1 -0.825 180.0 2 0.493 0.0 3 -#torsion 3 13 13 13 -1.697 0.0 1 -0.456 180.0 2 0.585 0.0 3 -torsion 3 13 13 15 -4.344 0.0 1 -1.714 180.0 2 0.000 0.0 3 -torsion 3 13 13 16 -4.344 0.0 1 -1.714 180.0 2 0.000 0.0 3 -torsion 3 13 13 24 -9.000 0.0 1 2.000 180.0 2 0.800 0.0 3 -torsion 3 13 13 46 0.000 0.0 1 0.000 180.0 2 -0.100 0.0 3 -#torsion 3 13 13 36 0.000 0.0 1 0.000 180.0 2 0.074 0.0 3 -#torsion 3 13 13 36 0.000 0.0 1 0.000 180.0 2 -0.076 0.0 3 -torsion 3 13 13 48 -1.697 0.0 1 -0.456 180.0 2 0.585 0.0 3 -torsion 3 13 13 80 -1.697 0.0 1 -0.456 180.0 2 0.585 0.0 3 -torsion 5 13 13 5 9.508 0.0 1 0.000 180.0 2 0.000 0.0 3 -#torsion 5 13 13 5 12.234 0.0 1 0.000 180.0 2 0.000 0.0 3 -#torsion 5 13 13 5 9.066 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 5 13 13 13 -1.552 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 5 13 13 20 4.319 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 5 13 13 44 8.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 5 13 13 24 6.280 0.0 1 -1.467 180.0 2 2.030 0.0 3 -torsion 5 13 13 46 0.000 0.0 1 0.000 180.0 2 0.468 0.0 3 -torsion 13 13 13 13 1.300 0.0 1 -0.050 180.0 2 0.200 0.0 3 -#torsion 13 13 13 13 6.622 0. 1 0.948 180. 2 -1.388 0. 3 -2.118 180. 4 -torsion 13 13 13 15 1.262 0.0 1 -0.198 180.0 2 0.465 0.0 3 -torsion 13 13 13 16 2.619 0.0 1 -0.620 180.0 2 0.258 0.0 3 -torsion 13 13 13 19 0.000 0.0 1 -0.650 180.0 2 0.000 0.0 3 -torsion 13 13 13 21 0.000 0.0 1 0.000 180.0 2 0.400 0.0 3 -torsion 13 13 13 44 2.392 0.0 1 -0.674 180.0 2 0.550 0.0 3 -torsion 13 13 13 24 0.845 0.0 1 -0.962 180.0 2 0.713 0.0 3 -#torsion 13 13 13 35 1.964 0.0 1 0.000 180.0 2 0.659 0.0 3 -torsion 13 13 13 46 0.000 0.0 1 0.000 180.0 2 0.300 0.0 3 -torsion 13 13 13 51 1.300 0.0 1 -0.050 180.0 2 0.200 0.0 3 -torsion 13 13 13 53 2.732 0.0 1 -0.229 180.0 2 0.485 0.0 3 -torsion 13 13 13 65 0.000 0.0 1 0.000 180.0 2 0.400 0.0 3 -torsion 13 13 13 66 0.000 0.0 1 0.000 180.0 2 0.400 0.0 3 -torsion 13 13 13 79 1.262 0.0 1 -0.198 180.0 2 0.465 0.0 3 -torsion 13 13 13 107 1.964 0.0 1 0.000 180.0 2 0.659 0.0 3 -torsion 13 13 13 108 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 15 13 13 46 0.000 0.0 1 0.000 180.0 2 0.452 0.0 3 -torsion 16 13 13 46 0.000 0.0 1 0.000 180.0 2 0.452 0.0 3 -torsion 19 13 13 46 0.000 0.0 1 0.000 180.0 2 0.366 0.0 3 -torsion 20 13 13 20 -0.550 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 20 13 13 46 0.000 0.0 1 0.000 180.0 2 0.468 0.0 3 -torsion 21 13 13 21 -0.250 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 21 13 13 44 2.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 21 13 13 46 0.000 0.0 1 0.000 180.0 2 0.400 0.0 3 -torsion 44 13 13 44 11.035 0.0 1 -0.968 180.0 2 0.270 0.0 3 -torsion 44 13 13 46 -1.013 0.0 1 -0.709 180.0 2 0.473 0.0 3 -torsion 44 13 13 48 -0.800 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 24 13 13 46 0.000 0.0 1 0.000 180.0 2 0.464 0.0 3 -torsion 24 13 13 48 0.845 0.0 1 -0.962 180.0 2 0.713 0.0 3 -torsion 24 13 13 80 0.845 0.0 1 -0.962 180.0 2 0.713 0.0 3 -torsion 46 13 13 46 0.000 0.0 1 0.000 180.0 2 0.300 0.0 3 -torsion 46 13 13 47 0.000 0.0 1 0.000 180.0 2 0.366 0.0 3 -torsion 46 13 13 48 0.000 0.0 1 0.000 180.0 2 0.462 0.0 3 -torsion 46 13 13 51 0.000 0.0 1 0.000 180.0 2 0.300 0.0 3 -torsion 46 13 13 53 0.000 0.0 1 0.000 180.0 2 0.384 0.0 3 -torsion 46 13 13 55 0.000 0.0 1 0.000 180.0 2 -0.582 0.0 3 -torsion 46 13 13 59 0.000 0.0 1 0.000 180.0 2 0.462 0.0 3 -torsion 46 13 13 62 0.000 0.0 1 0.000 180.0 2 0.462 0.0 3 -torsion 46 13 13 65 0.000 0.0 1 0.000 180.0 2 0.400 0.0 3 -torsion 46 13 13 66 0.000 0.0 1 0.000 180.0 2 0.400 0.0 3 -torsion 46 13 13 79 0.000 0.0 1 0.000 180.0 2 0.452 0.0 3 -#torsion 36 13 13 69 0.000 0.0 1 0.000 180.0 2 0.350 0.0 3 -torsion 46 13 13 80 0.000 0.0 1 0.000 180.0 2 0.462 0.0 3 -torsion 46 13 13 82 0.000 0.0 1 0.000 180.0 2 0.462 0.0 3 -torsion 46 13 13 83 0.000 0.0 1 0.000 180.0 2 0.462 0.0 3 -torsion 46 13 13 84 0.000 0.0 1 0.000 180.0 2 0.462 0.0 3 -torsion 46 13 13 87 0.000 0.0 1 0.000 180.0 2 0.462 0.0 3 -torsion 46 13 13 88 0.000 0.0 1 0.000 180.0 2 0.462 0.0 3 -torsion 46 13 13 102 0.000 0.0 1 0.000 180.0 2 -0.225 0.0 3 -torsion 46 13 13 104 0.000 0.0 1 0.000 180.0 2 0.300 0.0 3 -torsion 46 13 13 107 0.000 0.0 1 0.000 180.0 2 0.464 0.0 3 -torsion 46 13 13 108 0.000 0.0 1 0.000 180.0 2 0.450 0.0 3 -torsion 46 13 13 109 0.000 0.0 1 0.000 180.0 2 0.366 0.0 3 -torsion 48 13 13 53 1.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 108 13 13 108 5.200 0.0 1 -0.500 180.0 2 0.000 0.0 3 -torsion 13 13 15 17 -0.759 0.0 1 -0.282 180.0 2 0.680 0.0 3 -torsion 46 13 15 17 0.000 0.0 1 0.000 180.0 2 0.480 0.0 3 -torsion 13 13 16 13 0.925 0.0 1 -0.576 180.0 2 0.677 0.0 3 -torsion 13 13 16 16 1.941 0.0 1 -0.836 180.0 2 0.935 0.0 3 -torsion 46 13 16 13 0.000 0.0 1 0.000 180.0 2 0.647 0.0 3 -torsion 46 13 16 16 0.000 0.0 1 0.000 180.0 2 0.558 0.0 3 -torsion 46 13 16 48 0.000 0.0 1 0.000 180.0 2 0.647 0.0 3 -torsion 0 13 18 19 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 46 13 18 19 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 0 13 19 18 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 0 13 19 19 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 13 19 19 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 46 13 19 19 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 0 13 20 13 -0.521 0.0 1 -2.018 180.0 2 1.996 0.0 3 -torsion 56 13 20 13 -0.500 0.0 1 -1.500 180.0 2 1.000 0.0 3 -torsion 57 13 20 13 -0.500 0.0 1 -1.500 180.0 2 1.000 0.0 3 -torsion 13 13 20 3 -1.220 0.0 1 -0.126 180.0 2 0.422 0.0 3 -torsion 13 13 20 13 0.650 0.0 1 -0.250 180.0 2 0.670 0.0 3 -torsion 13 13 20 64 -1.420 0.0 1 -0.620 180.0 2 0.100 0.0 3 -torsion 46 13 20 0 0.000 0.0 1 0.000 180.0 2 0.760 0.0 3 -torsion 46 13 20 3 0.000 0.0 1 0.000 180.0 2 0.198 0.0 3 -torsion 46 13 20 47 0.000 0.0 1 0.000 180.0 2 0.760 0.0 3 -torsion 46 13 20 48 0.000 0.0 1 0.000 180.0 2 0.760 0.0 3 -torsion 46 13 20 51 0.000 0.0 1 0.000 180.0 2 0.760 0.0 3 -torsion 46 13 20 64 0.000 0.0 1 0.000 180.0 2 0.300 0.0 3 -torsion 13 13 44 13 0.416 0.0 1 -0.128 180.0 2 0.695 0.0 3 -#torsion 13 13 33 13 1.536 0.0 1 -0.128 180.0 2 0.695 0.0 3 -#torsion 13 13 33 13 1.464 0.0 1 -0.128 180.0 2 0.695 0.0 3 -torsion 13 13 44 45 -0.190 0.0 1 -0.417 180.0 2 0.418 0.0 3 -#torsion 13 13 33 34 0.000 0.0 1 4.000 180.0 2 0.000 0.0 3 -#torsion 13 13 33 34 0.200 0.0 1 -0.417 180.0 2 0.418 0.0 3 -#torsion 13 13 33 34 0.819 0.0 1 -0.417 180.0 2 0.418 0.0 3 -#torsion 13 13 33 34 1.522 0.0 1 -0.417 180.0 2 0.418 0.0 3 -torsion 46 13 44 13 0.000 0.0 1 0.000 180.0 2 0.560 0.0 3 -torsion 46 13 44 45 0.000 0.0 1 0.000 180.0 2 0.400 0.0 3 -torsion 46 13 44 48 0.000 0.0 1 0.000 180.0 2 0.560 0.0 3 -torsion 0 13 24 45 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 3 13 24 3 -2.365 0.0 1 0.912 180.0 2 -0.850 0.0 3 -torsion 3 13 24 13 -1.737 0.0 1 1.251 180.0 2 -3.501 0.0 3 -torsion 3 13 24 45 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 13 24 3 0.000 0.0 1 0.462 180.0 2 0.000 0.0 3 -#torsion 13 13 35 3 -1.396 0.0 1 -0.427 180.0 2 0.000 0.0 3 -#torsion 13 13 35 3 1.130 0.0 1 -1.420 180.0 2 0.440 0.0 3 -torsion 13 13 24 13 4.753 0.0 1 -0.734 180.0 2 0.000 0.0 3 -#torsion 13 13 35 13 2.859 0.0 1 2.058 180.0 2 -11.266 0.0 3 -torsion 13 13 24 45 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 13 24 59 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 13 24 79 2.929 0.0 1 -2.533 180.0 2 0.497 0.0 3 -torsion 13 13 24 91 2.300 0.0 1 6.089 180.0 2 0.000 0.0 3 -torsion 46 13 24 3 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -#torsion 36 13 35 3 0.000 0.0 1 0.000 180.0 2 -0.139 0.0 3 -torsion 46 13 24 13 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 46 13 24 45 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 46 13 24 48 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 46 13 24 79 1.362 0.0 1 -1.457 180.0 2 0.149 0.0 3 -torsion 48 13 24 59 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 0 13 47 13 1.711 0.0 1 -0.500 180.0 2 0.663 0.0 3 -torsion 0 13 47 46 0.000 0.0 1 0.000 180.0 2 0.468 0.0 3 -torsion 0 13 47 47 0.500 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 0 13 47 50 0.500 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 1 13 47 47 0.500 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 13 47 13 2.817 0.0 1 -0.169 180.0 2 0.543 0.0 3 -torsion 13 13 47 47 0.346 0.0 1 0.405 180.0 2 -0.904 0.0 3 -torsion 13 13 47 50 0.346 0.0 1 0.405 180.0 2 -0.904 0.0 3 -torsion 46 13 47 13 0.000 0.0 1 0.000 180.0 2 0.300 0.0 3 -torsion 46 13 47 46 0.000 0.0 1 0.000 180.0 2 0.318 0.0 3 -torsion 46 13 47 47 0.000 0.0 1 0.000 180.0 2 -0.372 0.0 3 -torsion 46 13 47 50 0.000 0.0 1 0.000 180.0 2 -0.372 0.0 3 -torsion 46 13 47 110 0.000 0.0 1 0.000 180.0 2 -0.250 0.0 3 -torsion 47 13 47 13 0.000 0.0 1 -8.000 180.0 2 0.000 0.0 3 -torsion 47 13 47 46 0.000 0.0 1 -8.000 180.0 2 0.000 0.0 3 -torsion 0 13 48 48 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 1 13 48 48 0.000 0.0 1 0.450 180.0 2 0.000 0.0 3 -torsion 13 13 48 48 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 13 48 56 -0.500 0.0 1 0.500 180.0 2 -0.500 0.0 3 -torsion 21 13 48 48 0.000 0.0 1 -0.400 180.0 2 0.000 0.0 3 -torsion 46 13 48 48 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 64 13 48 48 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 65 13 48 48 0.000 0.0 1 0.000 180.0 2 0.400 0.0 3 -torsion 0 13 50 47 0.500 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 13 50 50 0.346 0.0 1 0.405 180.0 2 -0.904 0.0 3 -torsion 46 13 50 47 0.000 0.0 1 0.000 180.0 2 -0.372 0.0 3 -torsion 46 13 50 50 0.000 0.0 1 0.000 180.0 2 -0.372 0.0 3 -torsion 46 13 50 109 0.000 0.0 1 0.000 180.0 2 -0.372 0.0 3 -torsion 13 13 51 0 1.711 0.0 1 -0.500 180.0 2 0.663 0.0 3 -torsion 13 13 51 46 0.000 0.0 1 0.000 180.0 2 0.300 0.0 3 -torsion 46 13 51 20 0.000 0.0 1 0.000 180.0 2 0.468 0.0 3 -torsion 13 13 53 13 1.438 0.0 1 -0.124 180.0 2 0.264 0.0 3 -torsion 13 13 53 45 0.000 0.0 1 0.000 180.0 2 0.347 0.0 3 -torsion 46 13 53 13 0.000 0.0 1 0.000 180.0 2 0.302 0.0 3 -torsion 46 13 53 45 0.000 0.0 1 0.000 180.0 2 0.261 0.0 3 -torsion 46 13 53 48 0.000 0.0 1 0.000 180.0 2 0.462 0.0 3 -torsion 46 13 53 54 0.000 0.0 1 0.000 180.0 2 0.300 0.0 3 -torsion 13 13 55 45 -0.190 0.0 1 -0.417 180.0 2 0.418 0.0 3 -torsion 13 13 55 48 1.829 0.0 1 0.243 180.0 2 -0.498 0.0 3 -torsion 13 13 55 54 -0.190 0.0 1 -0.417 180.0 2 0.418 0.0 3 -torsion 46 13 55 13 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 46 13 55 45 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 46 13 55 48 0.000 0.0 1 0.000 180.0 2 0.177 0.0 3 -torsion 13 13 56 18 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 0 13 57 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 13 57 0 1.000 0.0 1 -0.350 180.0 2 0.000 0.0 3 -#torsion 13 13 47 0 0.000 0.0 1 -0.576 180.0 2 0.000 0.0 3 -torsion 13 13 57 62 2.756 0.0 1 -0.872 180.0 2 -3.680 0.0 3 -#torsion 13 13 47 52 -1.000 0.0 1 -0.350 180.0 2 0.000 0.0 3 -torsion 13 13 57 82 -1.000 0.0 1 -0.350 180.0 2 0.000 0.0 3 -torsion 20 13 57 0 1.500 0.0 1 -1.500 180.0 2 0.000 0.0 3 -#torsion 29 13 47 0 0.000 0.0 1 -1.876 180.0 2 0.000 0.0 3 -torsion 20 13 57 62 -1.500 0.0 1 -1.500 180.0 2 0.000 0.0 3 -torsion 20 13 57 82 -1.500 0.0 1 -1.500 180.0 2 0.000 0.0 3 -torsion 13 13 59 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 13 59 56 0.000 0.0 1 0.500 180.0 2 -0.500 0.0 3 -torsion 46 13 59 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 13 62 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 46 13 62 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 46 13 64 20 0.000 0.0 1 0.000 180.0 2 0.250 0.0 3 -torsion 46 13 64 52 0.000 0.0 1 0.000 180.0 2 0.250 0.0 3 -torsion 48 13 64 20 2.250 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 48 13 64 52 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 0 13 79 23 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 0 13 79 24 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 13 79 13 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 13 79 23 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 46 13 79 5 0.000 0.0 1 0.000 180.0 2 0.350 0.0 3 -torsion 46 13 79 13 0.000 0.0 1 0.000 180.0 2 0.350 0.0 3 -torsion 46 13 79 23 0.000 0.0 1 0.000 180.0 2 0.350 0.0 3 -torsion 46 13 79 48 0.000 0.0 1 0.000 180.0 2 0.350 0.0 3 -torsion 13 13 80 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 13 80 60 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 13 80 84 -0.714 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 46 13 80 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 46 13 80 60 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 46 13 80 84 0.000 0.0 1 0.000 180.0 2 -0.480 0.0 3 -torsion 13 13 82 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 46 13 82 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 13 83 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 46 13 83 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 1 13 84 0 0.000 0.0 1 0.450 180.0 2 0.000 0.0 3 -torsion 13 13 84 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 13 84 57 1.700 0.0 1 -0.600 180.0 2 0.000 0.0 3 -torsion 21 13 84 0 0.000 0.0 1 -0.400 180.0 2 0.000 0.0 3 -torsion 46 13 84 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 1 13 87 0 0.000 0.0 1 0.450 180.0 2 0.000 0.0 3 -torsion 13 13 87 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 21 13 87 0 0.000 0.0 1 -0.400 180.0 2 0.000 0.0 3 -torsion 46 13 87 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 13 88 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 46 13 88 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 0 13 90 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 46 13 90 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 46 13 91 91 0.000 0.0 1 0.000 180.0 2 0.300 0.0 3 -torsion 13 13 95 13 0.000 0.0 1 -1.000 180.0 2 0.000 0.0 3 -torsion 13 13 95 46 0.000 0.0 1 -1.000 180.0 2 0.000 0.0 3 -torsion 13 13 102 103 0.000 0.0 1 0.400 180.0 2 0.000 0.0 3 -torsion 46 13 102 103 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 13 104 13 1.000 0.0 1 -0.500 180.0 2 0.500 0.0 3 -torsion 46 13 104 13 0.000 0.0 1 0.000 180.0 2 0.300 0.0 3 -torsion 0 13 105 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 13 105 0 1.000 0.0 1 -0.350 180.0 2 0.000 0.0 3 -torsion 13 13 105 62 -1.000 0.0 1 -0.350 180.0 2 0.000 0.0 3 -torsion 13 13 105 82 -1.000 0.0 1 -0.350 180.0 2 0.000 0.0 3 -torsion 20 13 105 0 1.500 0.0 1 -1.500 180.0 2 0.000 0.0 3 -torsion 20 13 105 62 3.132 0.0 1 -1.491 180.0 2 2.744 0.0 3 -#torsion 29 13 95 52 -1.500 0.0 1 -1.500 180.0 2 0.000 0.0 3 -torsion 20 13 105 82 -1.500 0.0 1 -1.500 180.0 2 0.000 0.0 3 -torsion 3 13 107 13 -1.737 0.0 1 1.251 180.0 2 -3.501 0.0 3 -torsion 13 13 107 3 -1.396 0.0 1 -0.427 180.0 2 0.000 0.0 3 -torsion 13 13 107 13 4.753 0.0 1 -0.734 180.0 2 0.000 0.0 3 -#torsion 13 13 97 13 2.859 0.0 1 2.058 180.0 2 -11.266 0.0 3 -torsion 46 13 107 3 0.000 0.0 1 0.000 180.0 2 -0.139 0.0 3 -torsion 46 13 107 13 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 46 13 107 48 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 13 108 13 1.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 13 108 45 0.000 0.0 1 0.000 180.0 2 0.260 0.0 3 -torsion 46 13 108 13 0.000 0.0 1 0.000 180.0 2 0.180 0.0 3 -torsion 46 13 108 20 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 46 13 108 45 0.000 0.0 1 0.000 180.0 2 0.180 0.0 3 -torsion 13 13 109 109 0.346 0.0 1 0.405 180.0 2 -0.904 0.0 3 -torsion 46 13 109 13 0.000 0.0 1 0.000 180.0 2 0.300 0.0 3 -torsion 46 13 109 46 0.000 0.0 1 0.000 180.0 2 0.318 0.0 3 -torsion 46 13 109 109 0.000 0.0 1 0.000 180.0 2 -0.372 0.0 3 -torsion 17 15 48 0 0.000 0.0 1 1.100 180.0 2 0.000 0.0 3 -#torsion 17 15 38 0 -3.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 17 15 48 48 0.000 0.0 1 1.100 180.0 2 0.000 0.0 3 -torsion 13 16 16 13 0.000 0.0 1 -7.414 180.0 2 1.705 0.0 3 -torsion 13 16 48 48 0.000 0.0 1 0.600 180.0 2 0.000 0.0 3 -torsion 13 16 48 56 1.600 0.0 1 5.100 180.0 2 0.000 0.0 3 -torsion 13 16 59 56 0.000 0.0 1 4.800 180.0 2 0.000 0.0 3 -torsion 84 16 82 0 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 84 16 82 61 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 82 16 84 49 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 82 16 84 83 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 82 16 84 88 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 0 16 91 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 19 18 48 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 19 18 48 48 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 18 18 56 13 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 18 18 56 46 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 0 19 19 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 19 19 13 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 19 19 46 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 19 19 47 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 19 19 109 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 46 19 19 47 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 46 19 19 109 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 19 19 47 13 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 19 19 47 46 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 19 19 47 47 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 20 44 13 0.000 0.0 1 0.000 180.0 2 0.300 0.0 3 -torsion 13 20 44 45 0.000 0.0 1 0.000 180.0 2 0.300 0.0 3 -torsion 13 20 47 13 0.650 0.0 1 -0.250 180.0 2 0.670 0.0 3 -torsion 13 20 47 46 0.000 0.0 1 0.000 180.0 2 0.760 0.0 3 -torsion 13 20 47 47 -3.500 0.0 1 3.000 180.0 2 0.000 0.0 3 -torsion 13 20 47 50 -3.500 0.0 1 3.000 180.0 2 0.000 0.0 3 -torsion 3 20 48 48 0.000 0.0 1 2.500 180.0 2 0.000 0.0 3 -torsion 13 20 48 48 0.000 0.0 1 3.000 180.0 2 0.000 0.0 3 -torsion 13 20 48 56 0.400 0.0 1 5.500 180.0 2 0.000 0.0 3 -torsion 64 20 48 48 0.000 0.0 1 2.990 180.0 2 0.000 0.0 3 -torsion 13 20 51 5 -0.375 0.0 1 -1.358 180.0 2 0.004 0.0 3 -torsion 13 20 51 13 0.650 0.0 1 -0.250 180.0 2 0.670 0.0 3 -torsion 13 20 51 20 -0.375 0.0 1 -1.358 180.0 2 0.004 0.0 3 -torsion 13 20 51 46 0.000 0.0 1 0.000 180.0 2 0.760 0.0 3 -torsion 13 20 56 3 3.000 0.0 1 3.000 180.0 2 0.000 0.0 3 -torsion 13 20 59 56 0.000 0.0 1 5.200 180.0 2 0.000 0.0 3 -torsion 0 20 64 52 0.000 0.0 1 0.000 180.0 2 0.562 0.0 3 -torsion 13 20 64 13 3.500 0.0 1 -3.300 180.0 2 1.500 0.0 3 -torsion 13 20 64 52 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -#torsion 13 29 54 42 0.900 0.0 1 -2.930 180.0 2 2.640 0.0 3 -torsion 48 20 64 4 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 84 20 82 61 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 82 20 84 88 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 84 20 84 49 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 84 20 84 87 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 108 20 108 13 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 108 20 108 20 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 44 44 13 0.000 0.0 1 0.000 180.0 2 0.300 0.0 3 -torsion 13 44 44 45 0.000 0.0 1 0.000 180.0 2 0.300 0.0 3 -torsion 45 44 44 45 0.000 0.0 1 0.000 180.0 2 0.300 0.0 3 -torsion 13 44 48 48 -7.582 0.0 1 3.431 180.0 2 3.198 0.0 3 -torsion 45 44 48 48 0.000 0.0 1 2.030 180.0 2 0.000 0.0 3 -torsion 59 44 48 48 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -torsion 82 44 48 48 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -torsion 84 44 48 48 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -torsion 45 44 82 16 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -torsion 45 44 82 61 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -torsion 48 44 82 16 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -torsion 48 44 82 61 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -torsion 0 24 48 48 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -torsion 3 24 48 48 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -torsion 13 24 48 48 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -torsion 45 24 48 48 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -torsion 59 24 48 48 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -torsion 82 24 48 48 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -torsion 84 24 48 48 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -torsion 0 24 59 0 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 0 24 59 49 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 45 24 59 0 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 0 24 60 0 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 0 24 79 23 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 24 79 48 2.074 0.0 1 -2.966 180.0 2 2.473 0.0 3 -torsion 45 24 79 48 1.671 0.0 1 -4.901 180.0 2 0.669 0.0 3 -torsion 13 24 82 61 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -torsion 45 24 82 16 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -#torsion 34 35 72 16 0.000 0.0 1 2.030 180.0 2 0.000 0.0 3 -torsion 45 24 82 20 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -#torsion 34 35 72 29 0.000 0.0 1 2.030 180.0 2 0.000 0.0 3 -torsion 45 24 82 61 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -torsion 48 24 82 16 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -torsion 48 24 82 20 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -torsion 48 24 82 61 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -torsion 0 24 84 0 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 3 24 84 84 0.000 0.0 1 3.000 180.0 2 0.000 0.0 3 -torsion 45 24 84 16 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -torsion 45 24 84 20 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -torsion 48 24 84 16 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -torsion 48 24 84 20 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -torsion 3 24 86 48 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 3 24 86 56 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 3 24 86 86 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 47 24 86 48 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 47 24 86 56 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 0 24 87 0 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 0 24 88 0 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 3 24 91 46 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 3 24 91 89 -1.396 0.0 1 -0.427 180.0 2 0.000 0.0 3 -torsion 3 24 91 91 -1.396 0.0 1 -0.427 180.0 2 0.000 0.0 3 -torsion 45 24 91 46 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 45 24 91 89 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 45 24 91 91 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 0 24 106 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 47 46 47 13 0.000 0.0 1 -8.000 180.0 2 0.000 0.0 3 -torsion 47 46 47 46 0.000 0.0 1 -8.000 180.0 2 0.000 0.0 3 -torsion 0 47 47 0 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 0 47 47 19 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 3 47 47 24 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 3 47 47 46 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 5 47 47 13 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 5 47 47 46 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 13 47 47 13 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 13 47 47 19 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 13 47 47 20 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 13 47 47 46 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 19 47 47 46 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 20 47 47 46 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 21 47 47 21 -1.600 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 21 47 47 46 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 46 47 47 46 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 46 47 47 48 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 13 47 48 48 0.205 0.0 1 -0.531 180.0 2 0.000 0.0 3 -torsion 46 47 48 48 0.000 0.0 1 0.000 180.0 2 -0.372 0.0 3 -torsion 46 47 48 56 0.000 0.0 1 0.000 180.0 2 -0.372 0.0 3 -torsion 47 47 48 48 1.241 0.0 1 3.353 180.0 2 -0.286 0.0 3 -torsion 13 47 50 13 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 13 47 50 46 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 13 47 50 48 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 13 47 50 50 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 13 47 50 109 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 24 47 50 3 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 46 47 50 13 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 46 47 50 46 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 46 47 50 48 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 46 47 50 50 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 46 47 50 109 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 0 47 84 0 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 0 47 86 48 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 3 47 86 86 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 49 47 86 0 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 49 47 86 24 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 0 47 87 0 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 0 47 88 0 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 13 47 110 47 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 46 47 110 47 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 0 48 48 0 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 0 48 48 13 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 0 48 48 48 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 0 48 48 49 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 1 48 48 48 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 1 48 48 49 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 13 48 48 13 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 13 48 48 48 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 13 48 48 49 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 13 48 48 50 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 21 48 48 48 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 21 48 48 49 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 44 48 48 49 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 47 48 48 49 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 48 48 48 48 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 48 48 48 49 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 48 48 48 50 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 48 48 48 55 0.0 0. 1 1.62 180. 2 0.0 0. 3 -0.44 180. 4 -torsion 48 48 48 60 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 48 48 48 65 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 48 48 48 66 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 48 48 48 86 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 48 48 48 109 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 49 48 48 49 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 49 48 48 50 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 49 48 48 60 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 49 48 48 65 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 49 48 48 66 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 49 48 48 86 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 49 48 48 109 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 56 48 48 86 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 48 48 50 46 0.000 0.0 1 0.000 180.0 2 -0.372 0.0 3 -torsion 48 48 50 47 1.241 0.0 1 3.353 180.0 2 -0.286 0.0 3 -torsion 56 48 50 46 0.000 0.0 1 0.000 180.0 2 -0.372 0.0 3 -torsion 56 48 50 47 1.241 0.0 1 3.353 180.0 2 -0.286 0.0 3 -torsion 48 48 53 13 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 48 48 53 54 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 0 48 55 45 0.000 0.0 1 2.030 180.0 2 0.000 0.0 3 -torsion 48 48 55 45 0.000 0.0 1 3.900 180.0 2 0.000 0.0 3 -torsion 55 48 55 13 0.000 0.0 1 7.936 180.0 2 0.000 0.0 3 -torsion 55 48 55 45 0.000 0.0 1 3.900 180.0 2 0.000 0.0 3 -torsion 60 48 55 45 0.000 0.0 1 2.030 180.0 2 0.000 0.0 3 -torsion 0 48 56 0 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 48 48 56 48 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 49 48 56 48 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 0 48 60 0 0.000 0.0 1 7.000 180.0 2 0.000 0.0 3 -torsion 0 48 79 23 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 48 48 79 13 0.000 0.0 1 -0.900 180.0 2 0.000 0.0 3 -torsion 48 48 79 24 1.656 0.0 1 -0.768 180.0 2 -0.117 0.0 3 -torsion 48 48 86 48 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 48 48 86 56 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 48 48 86 86 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 49 48 86 48 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 49 48 86 56 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 49 48 86 86 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 56 48 86 48 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 56 48 86 86 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 49 48 88 49 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 56 48 101 13 0.000 0.0 1 3.651 180.0 2 0.000 0.0 3 -torsion 48 48 102 103 0.000 0.0 1 1.150 180.0 2 0.000 0.0 3 -torsion 48 48 109 13 0.205 0.0 1 -0.531 180.0 2 0.000 0.0 3 -torsion 48 48 109 46 0.000 0.0 1 0.000 180.0 2 -0.372 0.0 3 -torsion 48 48 109 109 1.241 0.0 1 3.353 180.0 2 -0.286 0.0 3 -torsion 0 50 50 49 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 3 50 50 3 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 13 50 50 13 0.000 0.0 1 0.000 180.0 2 0.300 0.0 3 -torsion 13 50 50 46 0.000 0.0 1 0.000 180.0 2 0.300 0.0 3 -torsion 13 50 50 47 0.000 0.0 1 0.000 180.0 2 -0.372 0.0 3 -#torsion 13 40 40 37 0.900 0.0 1 0.230 180.0 2 -0.505 0.0 3 -torsion 46 50 50 46 0.000 0.0 1 0.000 180.0 2 0.300 0.0 3 -torsion 46 50 50 47 0.000 0.0 1 0.000 180.0 2 -0.372 0.0 3 -torsion 47 50 50 47 1.423 0.0 1 4.055 180.0 2 0.858 0.0 3 -torsion 13 50 109 13 0.000 0.0 1 0.000 180.0 2 0.300 0.0 3 -torsion 13 50 109 109 0.000 0.0 1 0.000 180.0 2 -0.372 0.0 3 -torsion 46 50 109 13 0.000 0.0 1 0.000 180.0 2 0.300 0.0 3 -torsion 46 50 109 46 0.000 0.0 1 0.000 180.0 2 0.300 0.0 3 -torsion 46 50 109 109 0.000 0.0 1 0.000 180.0 2 -0.372 0.0 3 -torsion 47 50 109 13 0.000 0.0 1 0.000 180.0 2 -0.372 0.0 3 -torsion 47 50 109 46 0.000 0.0 1 0.000 180.0 2 -0.372 0.0 3 -torsion 47 50 109 109 1.423 0.0 1 4.055 180.0 2 0.858 0.0 3 -torsion 13 53 82 61 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -torsion 48 53 82 61 0.000 0.0 1 2.100 180.0 2 0.000 0.0 3 -torsion 45 55 59 0 0.000 0.0 1 2.030 180.0 2 0.000 0.0 3 -torsion 13 56 56 13 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 13 56 56 48 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 48 56 56 48 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 0 56 59 0 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 0 56 59 49 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 0 56 60 0 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 0 56 62 0 0.000 0.0 1 10.000 180.0 2 0.000 0.0 3 -torsion 0 56 82 0 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -#torsion 0 46 72 0 0.000 0.0 1 10.000 180.0 2 0.000 0.0 3 -torsion 48 56 86 48 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 48 56 86 86 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 0 57 60 0 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 45 57 60 0 0.000 0.0 1 5.000 180.0 2 0.000 0.0 3 -torsion 0 57 61 0 0.000 0.0 1 10.000 180.0 2 0.000 0.0 3 -torsion 0 57 62 0 0.000 0.0 1 10.000 180.0 2 0.000 0.0 3 -torsion 0 57 81 0 0.000 0.0 1 3.050 180.0 2 0.000 0.0 3 -torsion 0 57 82 0 0.000 0.0 1 4.650 180.0 2 0.000 0.0 3 -#torsion 0 47 72 0 0.000 0.0 1 10.000 180.0 2 0.000 0.0 3 -torsion 0 57 82 49 0.000 0.0 1 10.000 180.0 2 0.000 0.0 3 -torsion 45 57 82 0 0.000 0.0 1 5.000 180.0 2 0.000 0.0 3 -torsion 0 57 84 0 0.000 0.0 1 2.800 180.0 2 0.000 0.0 3 -#torsion 0 47 74 0 0.000 0.0 1 5.000 180.0 2 0.000 0.0 3 -#torsion 0 47 74 0 0.000 0.0 1 3.000 180.0 2 0.000 0.0 3 -torsion 45 57 84 0 0.000 0.0 1 5.000 180.0 2 0.000 0.0 3 -torsion 61 57 86 48 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 84 57 86 48 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 0 60 60 0 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 0 60 61 0 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 0 60 80 0 0.000 0.0 1 3.350 180.0 2 0.000 0.0 3 -torsion 0 60 81 0 0.000 0.0 1 6.000 180.0 2 0.000 0.0 3 -torsion 0 60 87 0 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 48 60 87 84 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 60 60 87 84 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 0 61 61 0 0.000 0.0 1 10.000 180.0 2 0.000 0.0 3 -torsion 0 61 62 0 0.000 0.0 1 10.000 180.0 2 0.000 0.0 3 -torsion 0 61 82 0 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -#torsion 0 51 72 0 0.000 0.0 1 10.000 180.0 2 0.000 0.0 3 -torsion 0 61 82 49 0.000 0.0 1 10.000 180.0 2 0.000 0.0 3 -torsion 83 61 82 16 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 88 61 82 16 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 88 61 82 20 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 0 61 83 0 0.000 0.0 1 4.800 180.0 2 0.000 0.0 3 -torsion 82 61 83 49 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 82 61 83 84 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 0 61 84 0 0.000 0.0 1 10.000 180.0 2 0.000 0.0 3 -torsion 0 61 88 0 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 82 61 88 84 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 0 80 84 0 0.000 0.0 1 13.050 180.0 2 0.000 0.0 3 -torsion 0 82 84 0 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 16 82 86 48 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 20 82 86 48 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 57 82 86 48 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 61 82 86 48 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 0 82 87 0 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -#torsion 0 72 77 0 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 0 83 84 0 0.000 0.0 1 10.750 180.0 2 0.000 0.0 3 -torsion 0 83 84 49 0.000 0.0 1 10.750 180.0 2 0.000 0.0 3 -torsion 49 83 84 0 0.000 0.0 1 10.750 180.0 2 0.000 0.0 3 -torsion 49 83 84 16 0.000 0.0 1 10.750 180.0 2 0.000 0.0 3 -torsion 49 83 84 49 0.000 0.0 1 10.750 180.0 2 0.000 0.0 3 -torsion 61 83 84 16 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 61 83 84 20 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 61 83 84 49 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 0 83 86 48 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 61 83 86 48 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 61 83 87 0 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 84 83 87 0 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 0 84 84 0 0.000 0.0 1 10.750 180.0 2 0.000 0.0 3 -torsion 0 84 84 49 0.000 0.0 1 10.750 180.0 2 0.000 0.0 3 -torsion 16 84 84 49 0.000 0.0 1 10.750 180.0 2 0.000 0.0 3 -torsion 49 84 84 49 0.000 0.0 1 10.750 180.0 2 0.000 0.0 3 -torsion 0 84 86 48 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 16 84 86 48 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 20 84 86 48 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 57 84 86 48 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 0 84 87 0 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 0 84 87 49 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 49 84 87 49 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 0 84 88 49 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 16 84 88 49 0.000 0.0 1 10.750 180.0 2 0.000 0.0 3 -torsion 16 84 88 61 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 20 84 88 61 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 49 84 88 0 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 49 84 88 61 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 48 86 86 48 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 48 86 86 56 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 48 86 87 0 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 48 86 88 0 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 48 86 88 61 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 56 86 88 0 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 0 87 87 20 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 0 87 87 57 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 0 87 87 87 0.000 0.0 1 2.170 180.0 2 0.000 0.0 3 -torsion 49 87 87 49 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 4 89 90 13 0.000 0.0 1 6.089 180.0 2 0.000 0.0 3 -torsion 4 89 90 45 0.000 0.0 1 4.900 180.0 2 0.000 0.0 3 -torsion 4 89 90 48 0.000 0.0 1 6.089 180.0 2 0.000 0.0 3 -torsion 4 89 90 91 0.000 0.0 1 20.000 180.0 2 0.000 0.0 3 -torsion 91 89 90 13 2.300 0.0 1 6.089 180.0 2 0.000 0.0 3 -torsion 91 89 90 45 0.000 0.0 1 4.900 180.0 2 0.000 0.0 3 -torsion 91 89 90 48 2.300 0.0 1 6.089 180.0 2 0.000 0.0 3 -torsion 91 89 90 91 2.300 0.0 1 6.089 180.0 2 0.000 0.0 3 -torsion 0 89 91 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 4 89 91 46 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 4 89 91 91 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 90 89 91 46 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 90 89 91 91 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 0 90 91 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 0 90 91 46 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 0 90 91 91 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 0 91 91 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 0 91 91 24 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 91 91 13 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 91 91 46 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 46 91 91 46 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 46 91 91 91 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 91 91 91 91 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 0 109 109 0 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 13 109 109 13 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 13 109 109 46 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 13 109 109 48 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 13 109 109 50 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 13 109 109 109 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 46 109 109 46 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 46 109 109 48 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 46 109 109 50 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 46 109 109 109 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 48 109 109 48 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 48 109 109 50 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 48 109 109 109 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 50 109 109 50 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 50 109 109 109 0.000 0.0 1 14.000 180.0 2 0.000 0.0 3 -torsion 109 109 109 109 1.423 0.0 1 4.055 180.0 2 0.858 0.0 3 - - - ################################################################ - ## ## - ## Additional Torsional Parameter Values Used with OPLS-AA ## - ## ## - ## The torsions listed below were added to official OPLS-AA ## - ## to complete the set needed for proteins; the values were ## - ## obtained by analogy from the closest OPLS-AA torsions; ## - ## most of the added values are for HIP or N-terminal AAs; ## - ## ## - ################################################################ - - -torsion 24 3 13 53 1.816 0.0 1 1.222 180.0 2 1.581 0.0 3 -torsion 52 3 13 24 0.000 0.0 1 0.820 180.0 2 0.000 0.0 3 -torsion 3 13 13 53 1.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 3 13 13 83 -1.697 0.0 1 -0.456 180.0 2 0.585 0.0 3 -torsion 3 13 13 84 -1.697 0.0 1 -0.456 180.0 2 0.585 0.0 3 -torsion 3 13 13 85 -1.697 0.0 1 -0.456 180.0 2 0.585 0.0 3 -torsion 5 13 13 53 6.280 0.0 1 -1.467 180.0 2 2.030 0.0 3 -torsion 15 13 13 53 1.428 0.0 1 0.086 180.0 2 0.029 0.0 3 -torsion 16 13 13 53 1.428 0.0 1 0.086 180.0 2 0.029 0.0 3 -torsion 13 13 13 55 2.732 0.0 1 -0.229 180.0 2 0.485 0.0 3 -torsion 24 13 13 83 0.845 0.0 1 -0.962 180.0 2 0.713 0.0 3 -torsion 53 13 13 83 1.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 24 13 13 84 0.845 0.0 1 -0.962 180.0 2 0.713 0.0 3 -torsion 53 13 13 84 1.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 24 13 13 85 0.845 0.0 1 -0.962 180.0 2 0.713 0.0 3 -torsion 46 13 13 85 0.000 0.0 1 0.000 180.0 2 0.462 0.0 3 -torsion 53 13 13 85 1.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 3 13 53 13 1.438 0.0 1 -0.124 180.0 2 0.264 0.0 3 -torsion 3 13 53 54 0.000 0.0 1 0.000 180.0 2 0.347 0.0 3 -torsion 13 13 53 54 0.000 0.0 1 0.000 180.0 2 0.347 0.0 3 -torsion 46 13 55 54 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 13 85 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 13 85 57 1.700 0.0 1 -0.600 180.0 2 0.000 0.0 3 -torsion 46 13 85 0 0.000 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 55 48 55 54 0.000 0.0 1 3.900 180.0 2 0.000 0.0 3 -torsion 0 48 81 0 0.000 0.0 1 7.250 180.0 2 0.000 0.0 3 -torsion 0 57 85 0 0.000 0.0 1 5.000 180.0 2 0.000 0.0 3 -torsion 0 85 85 0 0.000 0.0 1 10.750 180.0 2 0.000 0.0 3 - - - ################################################################ - ## ## - ## Additional Torsional Parameter Values Used with OPLS-AA ## - ## ## - ## The torsions listed below were added to official OPLS-AA ## - ## to complete the values needed for selected organics ## - ## ## - ################################################################ - - -torsion 13 13 13 20 1.300 0.0 1 -0.050 180.0 2 0.200 0.0 3 -torsion 13 13 13 47 1.300 0.0 1 -0.050 180.0 2 0.200 0.0 3 - - - ######################################## - ## ## - ## Atomic Partial Charge Parameters ## - ## ## - ######################################## - - -charge 1 -0.2200 -charge 2 0.2200 -charge 3 0.5500 -charge 4 -0.5000 -charge 5 -0.5800 -charge 6 0.0800 -charge 7 0.4500 -charge 8 0.0000 -charge 9 0.0000 -charge 10 0.0000 -charge 11 0.0000 -charge 12 0.0000 -charge 13 0.0000 -charge 14 0.0000 -charge 15 0.0000 -charge 16 0.0000 -charge 17 0.0000 -charge 18 0.0000 -charge 19 0.0000 -charge 20 -0.7000 -charge 21 0.4350 -charge 22 0.2650 -charge 23 0.2650 -charge 24 -0.4700 -charge 25 -0.4500 -charge 26 -0.4700 -charge 27 -0.3000 -charge 28 0.2350 -charge 29 0.2700 -charge 30 0.1800 -charge 31 0.1800 -charge 32 0.2350 -charge 33 0.2350 -charge 34 0.3000 -charge 35 0.3000 -charge 36 -0.4300 -charge 37 0.2800 -charge 38 0.1500 -charge 39 0.2650 -charge 40 0.2650 -charge 41 -0.5000 -charge 42 0.2500 -charge 43 0.2500 -charge 44 0.5000 -charge 45 -0.2500 -charge 46 0.4200 -charge 47 -0.1400 -charge 48 0.2480 -charge 49 -0.0620 -charge 50 0.1390 -charge 51 -0.4590 -charge 52 0.1600 -charge 53 -0.5000 -charge 54 -0.5700 -charge 55 0.5000 -charge 56 0.2850 -charge 57 0.0000 -charge 58 0.0000 -charge 59 0.0000 -charge 60 0.0000 -charge 61 0.0000 -charge 62 0.0000 -charge 63 -0.8340 -charge 64 0.4170 -charge 65 0.0000 -charge 66 0.5200 -charge 67 -1.0400 -charge 68 -0.8220 -charge 69 0.4110 -charge 70 0.0000 -charge 71 0.5110 -charge 72 -1.0220 -charge 73 0.0000 -charge 74 0.2410 -charge 75 -0.2410 -charge 76 -0.8200 -charge 77 0.4100 -charge 78 -1.0200 -charge 79 0.3400 -charge 80 -0.1800 -charge 81 -0.1200 -charge 82 -0.0600 -charge 83 -0.2400 -charge 84 0.0000 -charge 85 0.0600 -charge 86 0.0000 -charge 87 -0.1150 -charge 88 -0.2300 -charge 89 0.1150 -charge 90 -0.1150 -charge 91 0.1150 -charge 92 0.0000 -charge 93 -0.0650 -charge 94 -0.0050 -charge 95 -0.1150 -charge 96 -0.6830 -charge 97 0.4180 -charge 98 0.0400 -charge 99 0.1450 -charge 100 0.2050 -charge 101 0.2650 -charge 102 0.1263 -charge 103 0.5323 -charge 104 -0.6351 -charge 105 0.4286 -charge 106 -0.2057 -charge 107 0.0825 -charge 108 0.1500 -charge 109 -0.5850 -charge 110 0.4350 -charge 111 -0.7000 -charge 112 0.4350 -charge 113 -0.7300 -charge 114 0.4650 -charge 115 0.1450 -charge 116 0.2050 -charge 117 0.2650 -charge 118 0.0600 -charge 119 -0.1700 -charge 120 0.0000 -charge 121 -0.2850 -charge 122 -0.4000 -charge 123 0.1100 -charge 124 0.1400 -charge 125 0.1700 -charge 126 0.2000 -charge 127 0.0300 -charge 128 -0.4000 -charge 129 -0.7000 -charge 130 0.4350 -charge 131 0.2000 -charge 132 0.1000 -charge 133 0.2650 -charge 134 0.1000 -charge 135 0.3000 -charge 136 0.1000 -charge 137 0.3650 -charge 138 0.1000 -charge 139 0.4000 -charge 140 0.4650 -charge 141 0.0850 -charge 142 -0.3350 -charge 143 -0.4700 -charge 144 -0.4350 -charge 145 -0.2175 -charge 146 0.1550 -charge 147 0.2350 -charge 148 0.0600 -charge 149 0.1200 -charge 150 0.1800 -charge 151 0.0375 -charge 152 0.0975 -charge 153 0.1575 -charge 154 0.2175 -charge 155 0.0375 -charge 156 0.0975 -charge 157 0.1575 -charge 158 0.2175 -charge 159 0.0000 -charge 160 0.2000 -charge 161 0.2600 -charge 162 0.3200 -charge 163 -0.0550 -charge 164 -0.3200 -charge 165 0.0800 -charge 166 0.1400 -charge 167 0.2000 -charge 168 -0.1200 -charge 169 0.0050 -charge 170 0.1025 -charge 171 0.1400 -charge 172 0.2000 -charge 173 0.7000 -charge 174 0.5650 -charge 175 0.5850 -charge 176 0.6150 -charge 177 0.5000 -charge 178 -0.5000 -charge 179 -0.7600 -charge 180 -0.5000 -charge 181 -0.1400 -charge 182 0.3800 -charge 183 0.3000 -charge 184 0.0200 -charge 185 -0.1100 -charge 186 0.0800 -charge 187 -0.0500 -charge 188 0.0100 -charge 189 0.1420 -charge 190 -0.3900 -charge 191 -0.5420 -charge 192 0.3330 -charge 193 -0.4900 -charge 194 0.4200 -charge 195 -0.4200 -charge 196 0.3700 -charge 197 0.0600 -charge 198 -0.1200 -charge 199 -0.0600 -charge 200 0.0000 -charge 201 0.0600 -charge 202 0.0350 -charge 203 0.3950 -charge 204 -0.4300 -charge 205 0.1800 -charge 206 -0.1800 -charge 207 -0.3850 -charge 208 0.0850 -charge 209 0.5200 -charge 210 -0.4400 -charge 211 -0.5300 -charge 212 0.4500 -charge 213 0.7000 -charge 214 -0.8000 -charge 215 -0.2800 -charge 216 -0.2200 -charge 217 -0.1600 -charge 218 -0.1000 -charge 219 0.4500 -charge 220 -0.4500 -charge 221 0.0000 -charge 222 0.4700 -charge 223 -0.4700 -charge 224 0.0600 -charge 225 0.0400 -charge 226 -0.0200 -charge 227 0.1000 -charge 228 -0.0900 -charge 229 -0.4000 -charge 230 -0.3000 -charge 231 0.0000 -charge 232 0.3500 -charge 233 0.3300 -charge 234 0.1300 -charge 235 0.1900 -charge 236 0.2500 -charge 237 0.3100 -charge 238 0.2300 -charge 239 0.1700 -charge 240 0.1100 -charge 241 0.0900 -charge 242 0.1500 -charge 243 -0.8000 -charge 244 0.4600 -charge 245 0.6400 -charge 246 -0.7000 -charge 247 0.4400 -charge 248 0.2000 -charge 249 -0.1100 -charge 250 0.1900 -charge 251 -0.0500 -charge 252 -0.2000 -charge 253 0.3100 -charge 254 -0.4600 -charge 255 0.3600 -charge 256 -0.8500 -charge 257 0.3700 -charge 258 -0.1500 -charge 259 0.1000 -charge 260 -0.0400 -charge 261 0.1000 -charge 262 -0.6000 -charge 263 0.5000 -charge 264 -0.5100 -charge 265 0.4500 -charge 266 -0.0700 -charge 267 0.0800 -charge 268 0.4100 -charge 269 -0.4000 -charge 270 0.3600 -charge 271 -0.4200 -charge 272 0.1000 -charge 273 0.1000 -charge 274 -0.1400 -charge 275 0.0800 -charge 276 -0.5600 -charge 277 0.5500 -charge 278 -0.5400 -charge 279 0.4600 -charge 280 -0.0600 -charge 281 0.1000 -charge 282 0.3800 -charge 283 -0.4800 -charge 284 -0.7900 -charge 285 0.3850 -charge 286 0.3550 -charge 287 0.1000 -charge 288 0.1000 -charge 289 -0.5300 -charge 290 0.2200 -charge 291 -0.5500 -charge 292 0.3800 -charge 293 0.1500 -charge 294 0.4400 -charge 295 -0.4900 -charge 296 0.2000 -charge 297 -0.5000 -charge 298 0.2000 -charge 299 -0.8100 -charge 300 0.3850 -charge 301 0.3550 -charge 302 0.2000 -charge 303 0.3500 -charge 304 -0.5600 -charge 305 0.4600 -charge 306 -0.5100 -charge 307 0.3400 -charge 308 0.1200 -charge 309 0.5200 -charge 310 0.3800 -charge 311 -0.8000 -charge 312 0.4000 -charge 313 -0.5100 -charge 314 -0.0100 -charge 315 0.1200 -charge 316 -0.0100 -charge 317 0.1400 -charge 318 -0.0100 -charge 319 0.1300 -charge 320 -0.6400 -charge 321 0.6500 -charge 322 -0.7400 -charge 323 0.6600 -charge 324 -0.0600 -charge 325 0.1000 -charge 326 0.4900 -charge 327 -0.3000 -charge 328 0.4800 -charge 329 -0.8100 -charge 330 0.4600 -charge 331 0.4300 -charge 332 0.1400 -charge 333 0.1400 -charge 334 0.0100 -charge 335 0.1600 -charge 336 0.7800 -charge 337 -0.6600 -charge 338 -0.4300 -charge 339 0.2000 -charge 340 0.1800 -charge 341 -0.0600 -charge 342 0.1200 -charge 343 -1.0000 -charge 344 -1.0000 -charge 345 -1.0000 -charge 346 -1.0000 -charge 347 1.0000 -charge 348 1.0000 -charge 349 1.0000 -charge 350 1.0000 -charge 351 1.0000 -charge 352 1.0000 -charge 353 2.0000 -charge 354 2.0000 -charge 355 2.0000 -charge 356 2.0000 -charge 357 -0.4000 -charge 358 0.1000 -charge 359 -0.9000 -charge 360 -0.2000 -charge 361 0.0600 -charge 362 -0.9800 -charge 363 -1.0700 -charge 364 0.1900 -charge 365 0.5100 -charge 366 -0.8200 -charge 367 -0.3000 -charge 368 0.0700 -charge 369 -1.3100 -charge 370 0.4000 -charge 371 -0.4000 -charge 372 0.0800 -charge 373 0.0000 -charge 374 0.0700 -charge 375 -0.9800 -charge 376 -1.3000 -charge 377 0.3000 -charge 378 2.5000 -charge 379 -0.2500 -charge 380 -0.8650 -charge 381 1.6200 -charge 382 -0.9200 -charge 383 -0.6000 -charge 384 0.3000 -charge 385 -0.0300 -charge 386 1.9200 -charge 387 -1.1200 -charge 388 -0.7000 -charge 389 0.4400 -charge 390 -0.1000 -charge 391 1.6200 -charge 392 -0.9700 -charge 393 -0.6300 -charge 394 0.2800 -charge 395 -0.0200 -charge 396 -0.5100 -charge 397 0.0800 -charge 398 -0.1400 -charge 399 0.3200 -charge 400 0.0200 -charge 401 -0.0400 -charge 402 -0.4700 -charge 403 0.1200 -charge 404 0.1400 -charge 405 0.2400 -charge 406 0.5100 -charge 407 -0.4300 -charge 408 -0.3300 -charge 409 0.1600 -charge 410 0.0300 -charge 411 0.6350 -charge 412 0.6250 -charge 413 0.1350 -charge 414 -0.2150 -charge 415 1.4800 -charge 416 -0.6800 -charge 417 -0.5400 -charge 418 0.1800 -charge 419 -1.0000 -charge 420 0.4400 -charge 421 -0.8000 -charge 422 0.4100 -charge 423 0.1800 -charge 424 0.0300 -charge 425 0.3900 -charge 426 -0.0600 -charge 427 -0.1800 -charge 428 0.0600 -charge 429 0.0000 -charge 430 0.0300 -charge 431 0.1900 -charge 432 0.2200 -charge 433 0.2500 -charge 434 1.3740 -charge 435 -0.6870 -charge 436 0.2450 -charge 437 0.1300 -charge 438 -0.4200 -charge 439 -0.0350 -charge 440 0.0250 -charge 441 0.0750 -charge 442 -0.0550 -charge 443 0.1300 -charge 444 -0.5700 -charge 445 0.4200 -charge 446 -0.0050 -charge 447 0.2950 -charge 448 -0.0150 -charge 449 0.0150 -charge 450 0.3850 -charge 451 0.2150 -charge 452 -0.4900 -charge 453 -0.5400 -charge 454 0.4600 -charge 455 -0.1150 -charge 456 0.0550 -charge 457 0.1150 -charge 458 -0.0300 -charge 459 0.0850 -charge 460 0.0000 -charge 461 -0.6780 -charge 462 0.4730 -charge 463 -0.4470 -charge 464 0.2270 -charge 465 0.0120 -charge 466 0.1550 -charge 467 0.0650 -charge 468 -0.4680 -charge 469 0.1920 -charge 470 0.0420 -charge 471 -0.8390 -charge 472 0.8740 -charge 473 0.6530 -charge 474 -0.6890 -charge 475 -0.0320 -charge 476 0.0110 -charge 477 0.1970 -charge 478 -0.3310 -charge 479 0.3780 -charge 480 -0.1600 -charge 481 -0.0090 -charge 482 0.1220 -charge 483 -0.2390 -charge 484 -0.1630 -charge 485 -0.1490 -charge 486 0.3170 -charge 487 0.1550 -charge 488 0.1180 -charge 489 -0.0590 -charge 490 -0.4910 -charge 491 0.2460 -charge 492 -0.3200 -charge 493 -0.0340 -charge 494 0.3010 -charge 495 0.0720 -charge 496 0.1500 -charge 497 0.1350 -charge 498 -0.2570 -charge 499 0.2750 -charge 500 -0.5630 -charge 501 0.1850 -charge 502 -0.2860 -charge 503 0.3060 -charge 504 0.0780 -charge 505 0.0750 -charge 506 0.1870 -charge 507 -0.1900 -charge 508 -0.0190 -charge 509 -0.1540 -charge 510 0.1420 -charge 511 0.1260 -charge 512 -0.2570 -charge 513 0.5110 -charge 514 -0.5900 -charge 515 0.1690 -charge 516 -0.1480 -charge 517 0.0430 -charge 518 0.0910 -charge 519 0.1810 -charge 520 -0.1220 -charge 521 -0.4130 -charge 522 0.4050 -charge 523 -0.4550 -charge 524 0.2500 -charge 525 0.0530 -charge 526 0.1840 -charge 527 0.0980 -charge 528 -0.5000 -charge 529 0.0010 -charge 530 -0.3900 -charge 531 -0.2700 -charge 532 -0.1270 -charge 533 -0.1080 -charge 534 -0.2580 -charge 535 0.2200 -charge 536 0.2250 -charge 537 0.3760 -charge 538 0.1470 -charge 539 0.1720 -charge 540 0.1550 -charge 541 0.1070 -charge 542 0.1100 -charge 543 0.1400 -charge 544 -0.6940 -charge 545 0.4250 -charge 546 -0.3590 -charge 547 -0.0080 -charge 548 -0.1970 -charge 549 -0.1120 -charge 550 -0.0700 -charge 551 -0.3070 -charge 552 0.5630 -charge 553 -0.0510 -charge 554 0.0280 -charge 555 0.1460 -charge 556 0.1190 -charge 557 0.1330 -charge 558 0.1130 -charge 559 0.1140 -charge 560 0.1570 -charge 561 -0.7600 -charge 562 0.6790 -charge 563 -0.7880 -charge 564 0.7360 -charge 565 0.0380 -charge 566 0.3430 -charge 567 -0.6420 -charge 568 0.4520 -charge 569 -0.6820 -charge 570 0.0240 -charge 571 0.1010 -charge 572 0.0860 -charge 573 0.4130 -charge 574 -0.0300 -charge 575 0.2420 -charge 576 -0.5150 -charge 577 0.2280 -charge 578 -0.2990 -charge 579 0.1010 -charge 580 0.0680 -charge 581 0.2050 -charge 582 -0.9510 -charge 583 0.9650 -charge 584 -0.0140 -charge 585 0.1300 -charge 586 0.0520 -charge 587 -0.5990 -charge 588 0.3920 -charge 589 -0.3480 -charge 590 0.0200 -charge 591 -0.0420 -charge 592 0.3470 -charge 593 -0.1960 -charge 594 0.0320 -charge 595 0.1460 -charge 596 0.1080 -charge 597 0.1400 -charge 598 0.1220 -charge 599 0.1660 -charge 600 -0.5800 -charge 601 0.1730 -charge 602 -0.3950 -charge 603 -0.1990 -charge 604 0.1180 -charge 605 0.0930 -charge 606 0.2080 -charge 607 0.0980 -charge 608 -0.1390 -charge 609 -0.0790 -charge 610 0.0990 -charge 611 -0.1680 -charge 612 -0.1080 -charge 613 -0.1890 -charge 614 -0.1290 -charge 615 -0.1690 -charge 616 -0.1090 -charge 617 -0.1380 -charge 618 -0.0780 -charge 619 -0.0250 -charge 620 0.0350 -charge 621 -0.0380 -charge 622 0.0220 -charge 623 -0.3340 -charge 624 0.2550 -charge 625 0.5230 -charge 626 0.5000 -charge 627 -0.1400 -charge 628 0.2275 -charge 629 0.1400 -charge 630 -0.0080 -charge 631 0.5880 -charge 632 -0.1030 -charge 633 -0.3320 -charge 634 0.0400 -charge 635 0.3420 -charge 636 -0.0500 -charge 637 -0.2050 -charge 638 3.0000 -charge 639 4.0000 -charge 640 3.0000 -charge 641 0.6190 -charge 642 -0.3950 -charge 643 0.1740 -charge 644 3.0000 -charge 645 3.0000 -charge 646 3.0000 -charge 647 3.0000 -charge 648 3.0000 -charge 649 -0.3440 -charge 650 -0.6280 -charge 651 0.2000 -charge 652 -0.1200 -charge 653 -0.0600 -charge 654 0.0000 -charge 655 -0.2300 -charge 656 0.0300 -charge 657 -0.0990 -charge 658 0.0990 -charge 659 0.2200 -charge 660 -0.2200 -charge 661 0.1300 -charge 662 -0.1300 -charge 663 -0.2200 -charge 664 0.2200 -charge 665 0.1500 -charge 666 0.4500 -charge 667 -0.2000 -charge 668 0.2000 -charge 669 -0.2000 -charge 670 0.2000 -charge 671 -0.2000 -charge 672 0.1000 -charge 673 -0.1000 -charge 674 0.0550 -charge 675 -0.2200 -charge 676 0.0650 -charge 677 0.0130 -charge 678 -0.1060 -charge 679 -0.0900 -charge 680 -0.1190 -charge 681 0.1410 -charge 682 0.1290 -charge 683 0.8270 -charge 684 -0.8850 -charge 685 0.4260 -charge 686 0.4650 -charge 687 0.1190 -charge 688 -0.0200 -charge 689 0.0400 -charge 690 -0.6200 -charge 691 -0.7850 -charge 692 -0.7850 -charge 693 0.5500 -charge 694 -0.5600 -charge 695 0.4600 -charge 696 -0.0800 -charge 697 -0.0200 -charge 698 0.0400 -charge 699 0.1000 -charge 700 0.0600 -charge 701 0.5400 -charge 702 -0.3700 -charge 703 0.0200 -charge 704 0.0600 -charge 705 0.0800 -charge 706 0.1400 -charge 707 0.2000 -charge 708 0.6500 -charge 709 0.0900 -charge 710 0.0350 -charge 711 -0.9000 -charge 712 -0.5000 -charge 713 0.8600 -charge 714 -0.4500 -charge 715 0.2100 -charge 716 0.1600 -charge 717 -0.1000 -charge 718 0.0300 -charge 719 0.0300 -charge 720 0.0600 -charge 721 -0.7800 -charge 722 0.9684 -charge 723 -0.5081 -charge 724 -0.0080 -charge 725 0.1720 -charge 726 1.3400 -charge 727 -0.3900 -charge 728 0.7940 -charge 729 -0.5980 -charge 730 -0.9000 -charge 731 -0.7800 -charge 732 -0.6300 -charge 733 0.0000 -charge 734 0.0200 -charge 735 0.0300 -charge 736 0.0600 -charge 737 0.0800 -charge 738 0.0900 -charge 739 0.3600 -charge 740 0.3800 -charge 741 0.0600 -charge 742 0.1200 -charge 743 0.1800 -charge 744 0.1400 -charge 745 0.1500 -charge 746 0.1800 -charge 747 0.2000 -charge 748 0.2100 -charge 749 0.1150 -charge 750 0.1750 -charge 751 0.2350 -charge 752 0.1950 -charge 753 0.1525 -charge 754 0.1350 -charge 755 -0.2100 -charge 756 0.2000 -charge 757 0.0100 -charge 758 0.0100 -charge 759 0.0100 -charge 760 0.0600 -charge 761 0.4500 -charge 762 0.4800 -charge 763 0.5100 -charge 764 -0.6550 -charge 765 0.3900 -charge 766 -0.5000 -charge 767 -0.5600 -charge 768 -0.6000 -charge 769 0.0000 -charge 770 -0.1000 -charge 771 0.2900 -charge 772 0.0900 -charge 773 0.1500 -charge 774 0.2100 -charge 775 0.2700 -charge 776 0.0960 -charge 777 -0.0390 -charge 778 0.0270 -charge 779 0.0110 -charge 780 0.0740 -charge 781 -0.0290 -charge 782 0.7000 -charge 783 -0.3520 -charge 784 -0.7090 -charge 785 0.3170 -charge 786 -0.2200 -charge 787 0.0200 -charge 788 0.1000 -charge 789 0.1200 -charge 790 0.2200 -charge 791 0.3600 -charge 792 0.2400 -charge 793 0.1200 -charge 794 0.4800 -charge 795 -0.1200 -charge 796 0.2500 -charge 797 0.1500 -charge 798 -0.0800 -charge 799 -0.1060 -charge 800 -0.2000 -charge 801 -0.0060 -charge 802 0.1030 -charge 803 0.0970 -charge 804 0.2000 -charge 805 -0.2000 -charge 806 -0.0060 -charge 807 0.1030 -charge 808 0.0970 -charge 809 0.2000 -charge 810 -0.0800 -charge 811 -0.0800 -charge 812 -0.0800 -charge 813 0.1000 -charge 814 -0.2500 -charge 815 0.6000 -charge 816 -0.1500 -charge 817 -0.0250 -charge 818 -0.0450 -charge 819 0.1450 -charge 820 0.8880 -charge 821 1.0030 -charge 822 -0.6580 -charge 823 -0.6340 -charge 824 0.4110 -charge 825 -0.4420 -charge 826 0.4350 -charge 827 0.2250 -charge 828 0.2550 -charge 829 -0.0340 -charge 830 0.0030 -charge 831 0.3000 -charge 832 -0.0400 -charge 833 -0.0575 -charge 834 2.0000 -charge 835 -0.0700 -charge 836 0.0300 -charge 837 0.1300 -charge 838 -0.1300 -charge 839 0.1000 -charge 840 -0.6850 -charge 841 0.1550 -charge 842 -0.1000 -charge 843 -0.4270 -charge 844 0.2180 -charge 845 0.6000 -charge 846 -0.6000 -charge 847 -0.3600 -charge 848 0.0000 -charge 849 0.0600 -charge 850 0.1200 -charge 851 0.1800 -charge 852 0.0600 -charge 853 0.5700 -charge 854 -0.5700 -charge 855 0.0000 -charge 856 0.0200 -charge 857 -0.0400 -charge 858 0.0000 -charge 859 0.0600 -charge 860 -0.0700 -charge 861 -0.1400 -charge 862 0.1700 -charge 863 0.1100 -charge 864 0.1500 -charge 865 0.1700 -charge 866 1.0000 -charge 867 0.8500 -charge 868 0.7000 -charge 869 0.5500 -charge 870 -0.1000 -charge 871 -0.4300 -charge 872 -0.3700 -charge 873 -0.3100 -charge 874 -0.2500 -charge 875 -1.0000 -charge 876 -1.0000 -charge 877 -1.0000 -charge 878 -1.0000 -charge 879 1.0000 -charge 880 1.0000 -charge 881 1.0000 -charge 882 1.0000 -charge 883 1.0000 -charge 884 2.0000 -charge 885 2.0000 -charge 886 2.0000 -charge 887 2.0000 -charge 888 -0.0500 -charge 889 0.0500 -charge 890 0.1500 -charge 891 0.2500 -charge 892 0.1000 -charge 893 0.1150 -charge 894 0.1350 -charge 895 0.0150 -charge 896 0.1550 -charge 897 0.0000 -charge 898 -0.1150 -charge 899 0.1500 -charge 900 -0.2500 -charge 901 -0.1000 -charge 902 0.0500 -charge 903 -0.1000 -charge 904 0.2000 -charge 905 -0.2500 -charge 906 0.0880 - - - ######################################## - ## ## - ## Biopolymer Atom Type Conversions ## - ## ## - ######################################## - - -biotype 1 N "Glycine" 180 -biotype 2 CA "Glycine" 165 -biotype 3 C "Glycine" 177 -biotype 4 HN "Glycine" 183 -biotype 5 O "Glycine" 178 -biotype 6 HA "Glycine" 85 -biotype 7 N "Alanine" 180 -biotype 8 CA "Alanine" 166 -biotype 9 C "Alanine" 177 -biotype 10 HN "Alanine" 183 -biotype 11 O "Alanine" 178 -biotype 12 HA "Alanine" 85 -biotype 13 CB "Alanine" 80 -biotype 14 HB "Alanine" 85 -biotype 15 N "Valine" 180 -biotype 16 CA "Valine" 166 -biotype 17 C "Valine" 177 -biotype 18 HN "Valine" 183 -biotype 19 O "Valine" 178 -biotype 20 HA "Valine" 85 -biotype 21 CB "Valine" 82 -biotype 22 HB "Valine" 85 -biotype 23 CG1 "Valine" 80 -biotype 24 HG1 "Valine" 85 -biotype 25 CG2 "Valine" 80 -biotype 26 HG2 "Valine" 85 -biotype 27 N "Leucine" 180 -biotype 28 CA "Leucine" 166 -biotype 29 C "Leucine" 177 -biotype 30 HN "Leucine" 183 -biotype 31 O "Leucine" 178 -biotype 32 HA "Leucine" 85 -biotype 33 CB "Leucine" 81 -biotype 34 HB "Leucine" 85 -biotype 35 CG "Leucine" 82 -biotype 36 HG "Leucine" 85 -biotype 37 CD1 "Leucine" 80 -biotype 38 HD1 "Leucine" 85 -biotype 39 CD2 "Leucine" 80 -biotype 40 HD2 "Leucine" 85 -biotype 41 N "Isoleucine" 180 -biotype 42 CA "Isoleucine" 166 -biotype 43 C "Isoleucine" 177 -biotype 44 HN "Isoleucine" 183 -biotype 45 O "Isoleucine" 178 -biotype 46 HA "Isoleucine" 85 -biotype 47 CB "Isoleucine" 82 -biotype 48 HB "Isoleucine" 85 -biotype 49 CG1 "Isoleucine" 80 -biotype 50 HG1 "Isoleucine" 85 -biotype 51 CG2 "Isoleucine" 81 -biotype 52 HG2 "Isoleucine" 85 -biotype 53 CD "Isoleucine" 80 -biotype 54 HD "Isoleucine" 85 -biotype 55 N "Serine" 180 -biotype 56 CA "Serine" 166 -biotype 57 C "Serine" 177 -biotype 58 HN "Serine" 183 -biotype 59 O "Serine" 178 -biotype 60 HA "Serine" 85 -biotype 61 CB "Serine" 99 -biotype 62 HB "Serine" 85 -biotype 63 OG "Serine" 96 -biotype 64 HG "Serine" 97 -biotype 65 N "Threonine" 180 -biotype 66 CA "Threonine" 166 -biotype 67 C "Threonine" 177 -biotype 68 HN "Threonine" 183 -biotype 69 O "Threonine" 178 -biotype 70 HA "Threonine" 85 -biotype 71 CB "Threonine" 100 -biotype 72 HB "Threonine" 85 -biotype 73 OG1 "Threonine" 96 -biotype 74 HG1 "Threonine" 97 -biotype 75 CG2 "Threonine" 80 -biotype 76 HG2 "Threonine" 85 -biotype 77 N "Cysteine (SH)" 180 -biotype 78 CA "Cysteine (SH)" 166 -biotype 79 C "Cysteine (SH)" 177 -biotype 80 HN "Cysteine (SH)" 183 -biotype 81 O "Cysteine (SH)" 178 -biotype 82 HA "Cysteine (SH)" 85 -biotype 83 CB "Cysteine (SH)" 148 -biotype 84 HB "Cysteine (SH)" 85 -biotype 85 SG "Cysteine (SH)" 142 -biotype 86 HG "Cysteine (SH)" 146 -biotype 87 N "Cystine (SS)" 180 -biotype 88 CA "Cystine (SS)" 166 -biotype 89 C "Cystine (SS)" 177 -biotype 90 HN "Cystine (SS)" 183 -biotype 91 O "Cystine (SS)" 178 -biotype 92 HA "Cystine (SS)" 85 -biotype 93 CB "Cystine (SS)" 156 -biotype 94 HB "Cystine (SS)" 85 -biotype 95 SG "Cystine (SS)" 145 -biotype 96 N "Cysteine (S-)" -1 -biotype 97 CA "Cysteine (S-)" -1 -biotype 98 C "Cysteine (S-)" -1 -biotype 99 HN "Cysteine (S-)" -1 -biotype 100 O "Cysteine (S-)" -1 -biotype 101 HA "Cysteine (S-)" -1 -biotype 102 CB "Cysteine (S-)" -1 -biotype 103 HB "Cysteine (S-)" -1 -biotype 104 SG "Cysteine (S-)" -1 -biotype 105 N "Proline" 181 -biotype 106 CA "Proline" 188 -biotype 107 C "Proline" 177 -biotype 108 O "Proline" 178 -biotype 109 HA "Proline" 85 -biotype 110 CB "Proline" 81 -biotype 111 HB "Proline" 85 -biotype 112 CG "Proline" 81 -biotype 113 HG "Proline" 85 -biotype 114 CD "Proline" 187 -biotype 115 HD "Proline" 85 -biotype 116 N "Phenylalanine" 180 -biotype 117 CA "Phenylalanine" 166 -biotype 118 C "Phenylalanine" 177 -biotype 119 HN "Phenylalanine" 183 -biotype 120 O "Phenylalanine" 178 -biotype 121 HA "Phenylalanine" 85 -biotype 122 CB "Phenylalanine" 94 -biotype 123 HB "Phenylalanine" 85 -biotype 124 CG "Phenylalanine" 90 -biotype 125 CD "Phenylalanine" 90 -biotype 126 HD "Phenylalanine" 91 -biotype 127 CE "Phenylalanine" 90 -biotype 128 HE "Phenylalanine" 91 -biotype 129 CZ "Phenylalanine" 90 -biotype 130 HZ "Phenylalanine" 91 -biotype 131 N "Tyrosine" 180 -biotype 132 CA "Tyrosine" 166 -biotype 133 C "Tyrosine" 177 -biotype 134 HN "Tyrosine" 183 -biotype 135 O "Tyrosine" 178 -biotype 136 HA "Tyrosine" 85 -biotype 137 CB "Tyrosine" 94 -biotype 138 HB "Tyrosine" 85 -biotype 139 CG "Tyrosine" 90 -biotype 140 CD "Tyrosine" 90 -biotype 141 HD "Tyrosine" 91 -biotype 142 CE "Tyrosine" 90 -biotype 143 HE "Tyrosine" 91 -biotype 144 CZ "Tyrosine" 108 -biotype 145 OH "Tyrosine" 109 -biotype 146 HH "Tyrosine" 110 -biotype 147 N "Tyrosine (O-)" -1 -biotype 148 CA "Tyrosine (O-)" -1 -biotype 149 C "Tyrosine (O-)" -1 -biotype 150 HN "Tyrosine (O-)" -1 -biotype 151 O "Tyrosine (O-)" -1 -biotype 152 HA "Tyrosine (O-)" -1 -biotype 153 CB "Tyrosine (O-)" -1 -biotype 154 HB "Tyrosine (O-)" -1 -biotype 155 CG "Tyrosine (O-)" -1 -biotype 156 CD "Tyrosine (O-)" -1 -biotype 157 HD "Tyrosine (O-)" -1 -biotype 158 CE "Tyrosine (O-)" -1 -biotype 159 HE "Tyrosine (O-)" -1 -biotype 160 CZ "Tyrosine (O-)" -1 -biotype 161 OH "Tyrosine (O-)" -1 -biotype 162 N "Tryptophan" 180 -biotype 163 CA "Tryptophan" 166 -biotype 164 C "Tryptophan" 177 -biotype 165 HN "Tryptophan" 183 -biotype 166 O "Tryptophan" 178 -biotype 167 HA "Tryptophan" 85 -biotype 168 CB "Tryptophan" 81 -biotype 169 HB "Tryptophan" 85 -biotype 170 CG "Tryptophan" 441 -biotype 171 CD1 "Tryptophan" 455 -biotype 172 HD1 "Tryptophan" 91 -biotype 173 CD2 "Tryptophan" 442 -biotype 174 NE1 "Tryptophan" 444 -biotype 175 HE1 "Tryptophan" 445 -biotype 176 CE2 "Tryptophan" 443 -biotype 177 CE3 "Tryptophan" 90 -biotype 178 HE3 "Tryptophan" 91 -biotype 179 CZ2 "Tryptophan" 90 -biotype 180 HZ2 "Tryptophan" 91 -biotype 181 CZ3 "Tryptophan" 90 -biotype 182 HZ3 "Tryptophan" 91 -biotype 183 CH2 "Tryptophan" 90 -biotype 184 HH2 "Tryptophan" 91 -biotype 185 N "Histidine (+)" 180 -biotype 186 CA "Histidine (+)" 166 -biotype 187 C "Histidine (+)" 177 -biotype 188 HN "Histidine (+)" 183 -biotype 189 O "Histidine (+)" 178 -biotype 190 HA "Histidine (+)" 85 -biotype 191 CB "Histidine (+)" 446 -biotype 192 HB "Histidine (+)" 85 -biotype 193 CG "Histidine (+)" 451 -biotype 194 ND1 "Histidine (+)" 453 -biotype 195 HD1 "Histidine (+)" 454 -biotype 196 CD2 "Histidine (+)" 451 -biotype 197 HD2 "Histidine (+)" 91 -biotype 198 CE1 "Histidine (+)" 450 -biotype 199 HE1 "Histidine (+)" 91 -biotype 200 NE2 "Histidine (+)" 453 -biotype 201 HE2 "Histidine (+)" 454 -biotype 202 N "Histidine (HD)" 180 -biotype 203 CA "Histidine (HD)" 166 -biotype 204 C "Histidine (HD)" 177 -biotype 205 HN "Histidine (HD)" 183 -biotype 206 O "Histidine (HD)" 178 -biotype 207 HA "Histidine (HD)" 85 -biotype 208 CB "Histidine (HD)" 446 -biotype 209 HB "Histidine (HD)" 85 -biotype 210 CG "Histidine (HD)" 449 -biotype 211 ND1 "Histidine (HD)" 444 -biotype 212 HD1 "Histidine (HD)" 445 -biotype 213 CD2 "Histidine (HD)" 448 -biotype 214 HD2 "Histidine (HD)" 91 -biotype 215 CE1 "Histidine (HD)" 447 -biotype 216 HE1 "Histidine (HD)" 91 -biotype 217 NE2 "Histidine (HD)" 452 -biotype 218 N "Histidine (HE)" 180 -biotype 219 CA "Histidine (HE)" 166 -biotype 220 C "Histidine (HE)" 177 -biotype 221 HN "Histidine (HE)" 183 -biotype 222 O "Histidine (HE)" 178 -biotype 223 HA "Histidine (HE)" 85 -biotype 224 CB "Histidine (HE)" 446 -biotype 225 HB "Histidine (HE)" 85 -biotype 226 CG "Histidine (HE)" 448 -biotype 227 ND1 "Histidine (HE)" 452 -biotype 228 CD2 "Histidine (HE)" 449 -biotype 229 HD2 "Histidine (HE)" 91 -biotype 230 CE1 "Histidine (HE)" 447 -biotype 231 HE1 "Histidine (HE)" 91 -biotype 232 NE2 "Histidine (HE)" 444 -biotype 233 HE2 "Histidine (HE)" 445 -biotype 234 N "Aspartic Acid" 180 -biotype 235 CA "Aspartic Acid" 166 -biotype 236 C "Aspartic Acid" 177 -biotype 237 HN "Aspartic Acid" 183 -biotype 238 O "Aspartic Acid" 178 -biotype 239 HA "Aspartic Acid" 85 -biotype 240 CB "Aspartic Acid" 216 -biotype 241 HB "Aspartic Acid" 85 -biotype 242 CG "Aspartic Acid" 213 -biotype 243 OD "Aspartic Acid" 214 -biotype 244 N "Aspartic Acid (COOH)" -1 -biotype 245 CA "Aspartic Acid (COOH)" -1 -biotype 246 C "Aspartic Acid (COOH)" -1 -biotype 247 HN "Aspartic Acid (COOH)" -1 -biotype 248 O "Aspartic Acid (COOH)" -1 -biotype 249 HA "Aspartic Acid (COOH)" -1 -biotype 250 CB "Aspartic Acid (COOH)" -1 -biotype 251 HB "Aspartic Acid (COOH)" -1 -biotype 252 CG "Aspartic Acid (COOH)" -1 -biotype 253 OD1 "Aspartic Acid (COOH)" -1 -biotype 254 OD2 "Aspartic Acid (COOH)" -1 -biotype 255 HD2 "Aspartic Acid (COOH)" -1 -biotype 256 N "Asparagine" 180 -biotype 257 CA "Asparagine" 166 -biotype 258 C "Asparagine" 177 -biotype 259 HN "Asparagine" 183 -biotype 260 O "Asparagine" 178 -biotype 261 HA "Asparagine" 85 -biotype 262 CB "Asparagine" 81 -biotype 263 HB "Asparagine" 85 -biotype 264 CG "Asparagine" 177 -biotype 265 OD1 "Asparagine" 178 -biotype 266 ND2 "Asparagine" 179 -biotype 267 HD2 "Asparagine" 182 -biotype 268 N "Glutamic Acid" 180 -biotype 269 CA "Glutamic Acid" 166 -biotype 270 C "Glutamic Acid" 177 -biotype 271 HN "Glutamic Acid" 183 -biotype 272 O "Glutamic Acid" 178 -biotype 273 HA "Glutamic Acid" 85 -biotype 274 CB "Glutamic Acid" 81 -biotype 275 HB "Glutamic Acid" 85 -biotype 276 CG "Glutamic Acid" 216 -biotype 277 HG "Glutamic Acid" 85 -biotype 278 CD "Glutamic Acid" 213 -biotype 279 OE "Glutamic Acid" 214 -biotype 280 N "Glutamic Acid (COOH)" -1 -biotype 281 CA "Glutamic Acid (COOH)" -1 -biotype 282 C "Glutamic Acid (COOH)" -1 -biotype 283 HN "Glutamic Acid (COOH)" -1 -biotype 284 O "Glutamic Acid (COOH)" -1 -biotype 285 HA "Glutamic Acid (COOH)" -1 -biotype 286 CB "Glutamic Acid (COOH)" -1 -biotype 287 HB "Glutamic Acid (COOH)" -1 -biotype 288 CG "Glutamic Acid (COOH)" -1 -biotype 289 HG "Glutamic Acid (COOH)" -1 -biotype 290 CD "Glutamic Acid (COOH)" -1 -biotype 291 OE1 "Glutamic Acid (COOH)" -1 -biotype 292 OE2 "Glutamic Acid (COOH)" -1 -biotype 293 HE2 "Glutamic Acid (COOH)" -1 -biotype 294 N "Glutamine" 180 -biotype 295 CA "Glutamine" 166 -biotype 296 C "Glutamine" 177 -biotype 297 HN "Glutamine" 183 -biotype 298 O "Glutamine" 178 -biotype 299 HA "Glutamine" 85 -biotype 300 CB "Glutamine" 81 -biotype 301 HB "Glutamine" 85 -biotype 302 CG "Glutamine" 81 -biotype 303 HG "Glutamine" 85 -biotype 304 CD "Glutamine" 177 -biotype 305 OE1 "Glutamine" 178 -biotype 306 NE2 "Glutamine" 179 -biotype 307 HE2 "Glutamine" 182 -biotype 308 N "Methionine" 180 -biotype 309 CA "Methionine" 166 -biotype 310 C "Methionine" 177 -biotype 311 HN "Methionine" 183 -biotype 312 O "Methionine" 178 -biotype 313 HA "Methionine" 85 -biotype 314 CB "Methionine" 81 -biotype 315 HB "Methionine" 85 -biotype 316 CG "Methionine" 152 -biotype 317 HG "Methionine" 85 -biotype 318 SD "Methionine" 144 -biotype 319 CE "Methionine" 151 -biotype 320 HE "Methionine" 85 -biotype 321 N "Lysine" 180 -biotype 322 CA "Lysine" 166 -biotype 323 C "Lysine" 177 -biotype 324 HN "Lysine" 183 -biotype 325 O "Lysine" 178 -biotype 326 HA "Lysine" 85 -biotype 327 CB "Lysine" 81 -biotype 328 HB "Lysine" 85 -biotype 329 CG "Lysine" 81 -biotype 330 HG "Lysine" 85 -biotype 331 CD "Lysine" 81 -biotype 332 HD "Lysine" 85 -biotype 333 CE "Lysine" 235 -biotype 334 HE "Lysine" 85 -biotype 335 NZ "Lysine" 230 -biotype 336 HZ "Lysine" 233 -biotype 337 N "Lysine (NH2)" -1 -biotype 338 CA "Lysine (NH2)" -1 -biotype 339 C "Lysine (NH2)" -1 -biotype 340 HN "Lysine (NH2)" -1 -biotype 341 O "Lysine (NH2)" -1 -biotype 342 HA "Lysine (NH2)" -1 -biotype 343 CB "Lysine (NH2)" -1 -biotype 344 HB "Lysine (NH2)" -1 -biotype 345 CG "Lysine (NH2)" -1 -biotype 346 HG "Lysine (NH2)" -1 -biotype 347 CD "Lysine (NH2)" -1 -biotype 348 HD "Lysine (NH2)" -1 -biotype 349 CE "Lysine (NH2)" -1 -biotype 350 HE "Lysine (NH2)" -1 -biotype 351 NZ "Lysine (NH2)" -1 -biotype 352 HZ "Lysine (NH2)" -1 -biotype 353 N "Arginine" 180 -biotype 354 CA "Arginine" 166 -biotype 355 C "Arginine" 177 -biotype 356 HN "Arginine" 183 -biotype 357 O "Arginine" 178 -biotype 358 HA "Arginine" 85 -biotype 359 CB "Arginine" 81 -biotype 360 HB "Arginine" 85 -biotype 361 CG "Arginine" 251 -biotype 362 HG "Arginine" 85 -biotype 363 CD "Arginine" 250 -biotype 364 HD "Arginine" 85 -biotype 365 NE "Arginine" 246 -biotype 366 HE "Arginine" 247 -biotype 367 CZ "Arginine" 245 -biotype 368 NH "Arginine" 243 -biotype 369 HH "Arginine" 244 -biotype 370 N "Ornithine" 180 -biotype 371 CA "Ornithine" 166 -biotype 372 C "Ornithine" 177 -biotype 373 HN "Ornithine" 183 -biotype 374 O "Ornithine" 178 -biotype 375 HA "Ornithine" 85 -biotype 376 CB "Ornithine" 81 -biotype 377 HB "Ornithine" 85 -biotype 378 CG "Ornithine" 81 -biotype 379 HG "Ornithine" 85 -biotype 380 CD "Ornithine" 235 -biotype 381 HD "Ornithine" 85 -biotype 382 NE "Ornithine" 230 -biotype 383 HE "Ornithine" 233 -biotype 384 N "MethylAlanine (AIB)" 180 -biotype 385 CA "MethylAlanine (AIB)" 167 -biotype 386 C "MethylAlanine (AIB)" 177 -biotype 387 HN "MethylAlanine (AIB)" 183 -biotype 388 O "MethylAlanine (AIB)" 178 -biotype 389 CB "MethylAlanine (AIB)" 80 -biotype 390 HB "MethylAlanine (AIB)" 85 -biotype 391 N "Pyroglutamic Acid" 180 -biotype 392 CA "Pyroglutamic Acid" 166 -biotype 393 C "Pyroglutamic Acid" 177 -biotype 394 HN "Pyroglutamic Acid" 183 -biotype 395 O "Pyroglutamic Acid" 178 -biotype 396 HA "Pyroglutamic Acid" 85 -biotype 397 CB "Pyroglutamic Acid" 81 -biotype 398 HB "Pyroglutamic Acid" 85 -biotype 399 CG "Pyroglutamic Acid" 216 -biotype 400 HG "Pyroglutamic Acid" 85 -biotype 401 CD "Pyroglutamic Acid" 177 -biotype 402 OE "Pyroglutamic Acid" 178 -biotype 403 N "N-Terminal GLY" 230 -biotype 404 CA "N-Terminal GLY" 235 -biotype 405 C "N-Terminal GLY" 177 -biotype 406 HN "N-Terminal GLY" 233 -biotype 407 O "N-Terminal GLY" 178 -biotype 408 HA "N-Terminal GLY" 85 -biotype 409 N "N-Terminal ALA" 230 -biotype 410 CA "N-Terminal ALA" 236 -biotype 411 C "N-Terminal ALA" 177 -biotype 412 HN "N-Terminal ALA" 233 -biotype 413 O "N-Terminal ALA" 178 -biotype 414 HA "N-Terminal ALA" 85 -biotype 415 N "N-Terminal VAL" 230 -biotype 416 CA "N-Terminal VAL" 236 -biotype 417 C "N-Terminal VAL" 177 -biotype 418 HN "N-Terminal VAL" 233 -biotype 419 O "N-Terminal VAL" 178 -biotype 420 HA "N-Terminal VAL" 85 -biotype 421 N "N-Terminal LEU" 230 -biotype 422 CA "N-Terminal LEU" 236 -biotype 423 C "N-Terminal LEU" 177 -biotype 424 HN "N-Terminal LEU" 233 -biotype 425 O "N-Terminal LEU" 178 -biotype 426 HA "N-Terminal LEU" 85 -biotype 427 N "N-Terminal ILE" 230 -biotype 428 CA "N-Terminal ILE" 236 -biotype 429 C "N-Terminal ILE" 177 -biotype 430 HN "N-Terminal ILE" 233 -biotype 431 O "N-Terminal ILE" 178 -biotype 432 HA "N-Terminal ILE" 85 -biotype 433 N "N-Terminal SER" 230 -biotype 434 CA "N-Terminal SER" 236 -biotype 435 C "N-Terminal SER" 177 -biotype 436 HN "N-Terminal SER" 233 -biotype 437 O "N-Terminal SER" 178 -biotype 438 HA "N-Terminal SER" 85 -biotype 439 N "N-Terminal THR" 230 -biotype 440 CA "N-Terminal THR" 236 -biotype 441 C "N-Terminal THR" 177 -biotype 442 HN "N-Terminal THR" 233 -biotype 443 O "N-Terminal THR" 178 -biotype 444 HA "N-Terminal THR" 85 -biotype 445 N "N-Terminal CYS (SH)" 230 -biotype 446 CA "N-Terminal CYS (SH)" 236 -biotype 447 C "N-Terminal CYS (SH)" 177 -biotype 448 HN "N-Terminal CYS (SH)" 233 -biotype 449 O "N-Terminal CYS (SH)" 178 -biotype 450 HA "N-Terminal CYS (SH)" 85 -biotype 451 N "N-Terminal CYX (SS)" 230 -biotype 452 CA "N-Terminal CYX (SS)" 236 -biotype 453 C "N-Terminal CYX (SS)" 177 -biotype 454 HN "N-Terminal CYX (SS)" 233 -biotype 455 O "N-Terminal CYX (SS)" 178 -biotype 456 HA "N-Terminal CYX (SS)" 85 -biotype 457 N "N-Terminal CYD (S-)" -1 -biotype 458 CA "N-Terminal CYD (S-)" -1 -biotype 459 C "N-Terminal CYD (S-)" -1 -biotype 460 HN "N-Terminal CYD (S-)" -1 -biotype 461 O "N-Terminal CYD (S-)" -1 -biotype 462 HA "N-Terminal CYD (S-)" -1 -biotype 463 N "N-Terminal PRO" 252 -biotype 464 CA "N-Terminal PRO" 238 -biotype 465 C "N-Terminal PRO" 177 -biotype 466 HN "N-Terminal PRO" 253 -biotype 467 O "N-Terminal PRO" 178 -biotype 468 HA "N-Terminal PRO" 85 -biotype 469 CD "N-Terminal PRO" 239 -biotype 470 HD "N-Terminal PRO" 85 -biotype 471 N "N-Terminal PHE" 230 -biotype 472 CA "N-Terminal PHE" 236 -biotype 473 C "N-Terminal PHE" 177 -biotype 474 HN "N-Terminal PHE" 233 -biotype 475 O "N-Terminal PHE" 178 -biotype 476 HA "N-Terminal PHE" 85 -biotype 477 N "N-Terminal TYR" 230 -biotype 478 CA "N-Terminal TYR" 236 -biotype 479 C "N-Terminal TYR" 177 -biotype 480 HN "N-Terminal TYR" 233 -biotype 481 O "N-Terminal TYR" 178 -biotype 482 HA "N-Terminal TYR" 85 -biotype 483 N "N-Terminal TYD (O-)" -1 -biotype 484 CA "N-Terminal TYD (O-)" -1 -biotype 485 C "N-Terminal TYD (O-)" -1 -biotype 486 HN "N-Terminal TYD (O-)" -1 -biotype 487 O "N-Terminal TYD (O-)" -1 -biotype 488 HA "N-Terminal TYD (O-)" -1 -biotype 489 N "N-Terminal TRP" 230 -biotype 490 CA "N-Terminal TRP" 236 -biotype 491 C "N-Terminal TRP" 177 -biotype 492 HN "N-Terminal TRP" 233 -biotype 493 O "N-Terminal TRP" 178 -biotype 494 HA "N-Terminal TRP" 85 -biotype 495 N "N-Terminal HIS (+)" 230 -biotype 496 CA "N-Terminal HIS (+)" 236 -biotype 497 C "N-Terminal HIS (+)" 177 -biotype 498 HN "N-Terminal HIS (+)" 233 -biotype 499 O "N-Terminal HIS (+)" 178 -biotype 500 HA "N-Terminal HIS (+)" 85 -biotype 501 N "N-Terminal HIS (HD)" 230 -biotype 502 CA "N-Terminal HIS (HD)" 236 -biotype 503 C "N-Terminal HIS (HD)" 177 -biotype 504 HN "N-Terminal HIS (HD)" 233 -biotype 505 O "N-Terminal HIS (HD)" 178 -biotype 506 HA "N-Terminal HIS (HD)" 85 -biotype 507 N "N-Terminal HIS (HE)" 230 -biotype 508 CA "N-Terminal HIS (HE)" 236 -biotype 509 C "N-Terminal HIS (HE)" 177 -biotype 510 HN "N-Terminal HIS (HE)" 233 -biotype 511 O "N-Terminal HIS (HE)" 178 -biotype 512 HA "N-Terminal HIS (HE)" 85 -biotype 513 N "N-Terminal ASP" 230 -biotype 514 CA "N-Terminal ASP" 236 -biotype 515 C "N-Terminal ASP" 177 -biotype 516 HN "N-Terminal ASP" 233 -biotype 517 O "N-Terminal ASP" 178 -biotype 518 HA "N-Terminal ASP" 85 -biotype 519 N "N-Terminal ASH (COOH)" -1 -biotype 520 CA "N-Terminal ASH (COOH)" -1 -biotype 521 C "N-Terminal ASH (COOH)" -1 -biotype 522 HN "N-Terminal ASH (COOH)" -1 -biotype 523 O "N-Terminal ASH (COOH)" -1 -biotype 524 HA "N-Terminal ASH (COOH)" -1 -biotype 525 N "N-Terminal ASN" 230 -biotype 526 CA "N-Terminal ASN" 236 -biotype 527 C "N-Terminal ASN" 177 -biotype 528 HN "N-Terminal ASN" 233 -biotype 529 O "N-Terminal ASN" 178 -biotype 530 HA "N-Terminal ASN" 85 -biotype 531 N "N-Terminal GLU" 230 -biotype 532 CA "N-Terminal GLU" 236 -biotype 533 C "N-Terminal GLU" 177 -biotype 534 HN "N-Terminal GLU" 233 -biotype 535 O "N-Terminal GLU" 178 -biotype 536 HA "N-Terminal GLU" 85 -biotype 537 N "N-Terminal GLH (COOH)" -1 -biotype 538 CA "N-Terminal GLH (COOH)" -1 -biotype 539 C "N-Terminal GLH (COOH)" -1 -biotype 540 HN "N-Terminal GLH (COOH)" -1 -biotype 541 O "N-Terminal GLH (COOH)" -1 -biotype 542 HA "N-Terminal GLH (COOH)" -1 -biotype 543 N "N-Terminal GLN" 230 -biotype 544 CA "N-Terminal GLN" 236 -biotype 545 C "N-Terminal GLN" 177 -biotype 546 HN "N-Terminal GLN" 233 -biotype 547 O "N-Terminal GLN" 178 -biotype 548 HA "N-Terminal GLN" 85 -biotype 549 N "N-Terminal MET" 230 -biotype 550 CA "N-Terminal MET" 236 -biotype 551 C "N-Terminal MET" 177 -biotype 552 HN "N-Terminal MET" 233 -biotype 553 O "N-Terminal MET" 178 -biotype 554 HA "N-Terminal MET" 85 -biotype 555 N "N-Terminal LYS" 230 -biotype 556 CA "N-Terminal LYS" 236 -biotype 557 C "N-Terminal LYS" 177 -biotype 558 HN "N-Terminal LYS" 233 -biotype 559 O "N-Terminal LYS" 178 -biotype 560 HA "N-Terminal LYS" 85 -biotype 561 N "N-Terminal LYD (NH2)" -1 -biotype 562 CA "N-Terminal LYD (NH2)" -1 -biotype 563 C "N-Terminal LYD (NH2)" -1 -biotype 564 HN "N-Terminal LYD (NH2)" -1 -biotype 565 O "N-Terminal LYD (NH2)" -1 -biotype 566 HA "N-Terminal LYD (NH2)" -1 -biotype 567 N "N-Terminal ARG" 230 -biotype 568 CA "N-Terminal ARG" 236 -biotype 569 C "N-Terminal ARG" 177 -biotype 570 HN "N-Terminal ARG" 233 -biotype 571 O "N-Terminal ARG" 178 -biotype 572 HA "N-Terminal ARG" 85 -biotype 573 N "N-Terminal ORN" 230 -biotype 574 CA "N-Terminal ORN" 236 -biotype 575 C "N-Terminal ORN" 177 -biotype 576 HN "N-Terminal ORN" 233 -biotype 577 O "N-Terminal ORN" 178 -biotype 578 HA "N-Terminal ORN" 85 -biotype 579 N "N-Terminal AIB" 230 -biotype 580 CA "N-Terminal AIB" 237 -biotype 581 C "N-Terminal AIB" 177 -biotype 582 HN "N-Terminal AIB" 233 -biotype 583 O "N-Terminal AIB" 178 -biotype 584 N "C-Terminal GLY" 180 -biotype 585 CA "C-Terminal GLY" 226 -biotype 586 C "C-Terminal GLY" 213 -biotype 587 HN "C-Terminal GLY" 183 -biotype 588 OXT "C-Terminal GLY" 214 -biotype 589 HA "C-Terminal GLY" 85 -biotype 590 N "C-Terminal ALA" 180 -biotype 591 CA "C-Terminal ALA" 225 -biotype 592 C "C-Terminal ALA" 213 -biotype 593 HN "C-Terminal ALA" 183 -biotype 594 OXT "C-Terminal ALA" 214 -biotype 595 HA "C-Terminal ALA" 85 -biotype 596 N "C-Terminal VAL" 180 -biotype 597 CA "C-Terminal VAL" 225 -biotype 598 C "C-Terminal VAL" 213 -biotype 599 HN "C-Terminal VAL" 183 -biotype 600 OXT "C-Terminal VAL" 214 -biotype 601 HA "C-Terminal VAL" 85 -biotype 602 N "C-Terminal LEU" 180 -biotype 603 CA "C-Terminal LEU" 225 -biotype 604 C "C-Terminal LEU" 213 -biotype 605 HN "C-Terminal LEU" 183 -biotype 606 OXT "C-Terminal LEU" 214 -biotype 607 HA "C-Terminal LEU" 85 -biotype 608 N "C-Terminal ILE" 180 -biotype 609 CA "C-Terminal ILE" 225 -biotype 610 C "C-Terminal ILE" 213 -biotype 611 HN "C-Terminal ILE" 183 -biotype 612 OXT "C-Terminal ILE" 214 -biotype 613 HA "C-Terminal ILE" 85 -biotype 614 N "C-Terminal SER" 180 -biotype 615 CA "C-Terminal SER" 225 -biotype 616 C "C-Terminal SER" 213 -biotype 617 HN "C-Terminal SER" 183 -biotype 618 OXT "C-Terminal SER" 214 -biotype 619 HA "C-Terminal SER" 85 -biotype 620 N "C-Terminal THR" 180 -biotype 621 CA "C-Terminal THR" 225 -biotype 622 C "C-Terminal THR" 213 -biotype 623 HN "C-Terminal THR" 183 -biotype 624 OXT "C-Terminal THR" 214 -biotype 625 HA "C-Terminal THR" 85 -biotype 626 N "C-Terminal CYS (SH)" 180 -biotype 627 CA "C-Terminal CYS (SH)" 225 -biotype 628 C "C-Terminal CYS (SH)" 213 -biotype 629 HN "C-Terminal CYS (SH)" 183 -biotype 630 OXT "C-Terminal CYS (SH)" 214 -biotype 631 HA "C-Terminal CYS (SH)" 85 -biotype 632 N "C-Terminal CYX (SS)" 180 -biotype 633 CA "C-Terminal CYX (SS)" 225 -biotype 634 C "C-Terminal CYX (SS)" 213 -biotype 635 HN "C-Terminal CYX (SS)" 183 -biotype 636 OXT "C-Terminal CYX (SS)" 214 -biotype 637 HA "C-Terminal CYX (SS)" 85 -biotype 638 N "C-Terminal CYD (S-)" -1 -biotype 639 CA "C-Terminal CYD (S-)" -1 -biotype 640 C "C-Terminal CYD (S-)" -1 -biotype 641 HN "C-Terminal CYD (S-)" -1 -biotype 642 OXT "C-Terminal CYD (S-)" -1 -biotype 643 HA "C-Terminal CYD (S-)" -1 -biotype 644 N "C-Terminal PRO" 181 -biotype 645 CA "C-Terminal PRO" 228 -biotype 646 C "C-Terminal PRO" 213 -biotype 647 OXT "C-Terminal PRO" 214 -biotype 648 HA "C-Terminal PRO" 85 -biotype 649 N "C-Terminal PHE" 180 -biotype 650 CA "C-Terminal PHE" 225 -biotype 651 C "C-Terminal PHE" 213 -biotype 652 HN "C-Terminal PHE" 183 -biotype 653 OXT "C-Terminal PHE" 214 -biotype 654 HA "C-Terminal PHE" 85 -biotype 655 N "C-Terminal TYR" 180 -biotype 656 CA "C-Terminal TYR" 225 -biotype 657 C "C-Terminal TYR" 213 -biotype 658 HN "C-Terminal TYR" 183 -biotype 659 OXT "C-Terminal TYR" 214 -biotype 660 HA "C-Terminal TYR" 85 -biotype 661 N "C-Terminal TYD (O-)" -1 -biotype 662 CA "C-Terminal TYD (O-)" -1 -biotype 663 C "C-Terminal TYD (O-)" -1 -biotype 664 HN "C-Terminal TYD (O-)" -1 -biotype 665 OXT "C-Terminal TYD (O-)" -1 -biotype 666 HA "C-Terminal TYD (O-)" -1 -biotype 667 N "C-Terminal TRP" 180 -biotype 668 CA "C-Terminal TRP" 225 -biotype 669 C "C-Terminal TRP" 213 -biotype 670 HN "C-Terminal TRP" 183 -biotype 671 OXT "C-Terminal TRP" 214 -biotype 672 HA "C-Terminal TRP" 85 -biotype 673 N "C-Terminal HIS (+)" 180 -biotype 674 CA "C-Terminal HIS (+)" 225 -biotype 675 C "C-Terminal HIS (+)" 213 -biotype 676 HN "C-Terminal HIS (+)" 183 -biotype 677 OXT "C-Terminal HIS (+)" 214 -biotype 678 HA "C-Terminal HIS (+)" 85 -biotype 679 N "C-Terminal HIS (HD)" 180 -biotype 680 CA "C-Terminal HIS (HD)" 225 -biotype 681 C "C-Terminal HIS (HD)" 213 -biotype 682 HN "C-Terminal HIS (HD)" 183 -biotype 683 OXT "C-Terminal HIS (HD)" 214 -biotype 684 HA "C-Terminal HIS (HD)" 85 -biotype 685 N "C-Terminal HIS (HE)" 180 -biotype 686 CA "C-Terminal HIS (HE)" 225 -biotype 687 C "C-Terminal HIS (HE)" 213 -biotype 688 HN "C-Terminal HIS (HE)" 183 -biotype 689 OXT "C-Terminal HIS (HE)" 214 -biotype 690 HA "C-Terminal HIS (HE)" 85 -biotype 691 N "C-Terminal ASP" 180 -biotype 692 CA "C-Terminal ASP" 225 -biotype 693 C "C-Terminal ASP" 213 -biotype 694 HN "C-Terminal ASP" 183 -biotype 695 OXT "C-Terminal ASP" 214 -biotype 696 HA "C-Terminal ASP" 85 -biotype 697 N "C-Terminal ASH (COOH)" -1 -biotype 698 CA "C-Terminal ASH (COOH)" -1 -biotype 699 C "C-Terminal ASH (COOH)" -1 -biotype 700 HN "C-Terminal ASH (COOH)" -1 -biotype 701 OXT "C-Terminal ASH (COOH)" -1 -biotype 702 HA "C-Terminal ASH (COOH)" -1 -biotype 703 N "C-Terminal ASN" 180 -biotype 704 CA "C-Terminal ASN" 225 -biotype 705 C "C-Terminal ASN" 213 -biotype 706 HN "C-Terminal ASN" 183 -biotype 707 OXT "C-Terminal ASN" 214 -biotype 708 HA "C-Terminal ASN" 85 -biotype 709 N "C-Terminal GLU" 180 -biotype 710 CA "C-Terminal GLU" 225 -biotype 711 C "C-Terminal GLU" 213 -biotype 712 HN "C-Terminal GLU" 183 -biotype 713 OXT "C-Terminal GLU" 214 -biotype 714 HA "C-Terminal GLU" 85 -biotype 715 N "C-Terminal GLH (COOH)" -1 -biotype 716 CA "C-Terminal GLH (COOH)" -1 -biotype 717 C "C-Terminal GLH (COOH)" -1 -biotype 718 HN "C-Terminal GLH (COOH)" -1 -biotype 719 OXT "C-Terminal GLH (COOH)" -1 -biotype 720 HA "C-Terminal GLH (COOH)" -1 -biotype 721 N "C-Terminal GLN" 180 -biotype 722 CA "C-Terminal GLN" 225 -biotype 723 C "C-Terminal GLN" 213 -biotype 724 HN "C-Terminal GLN" 183 -biotype 725 OXT "C-Terminal GLN" 214 -biotype 726 HA "C-Terminal GLN" 85 -biotype 727 N "C-Terminal MET" 180 -biotype 728 CA "C-Terminal MET" 225 -biotype 729 C "C-Terminal MET" 213 -biotype 730 HN "C-Terminal MET" 183 -biotype 731 OXT "C-Terminal MET" 214 -biotype 732 HA "C-Terminal MET" 85 -biotype 733 N "C-Terminal LYS" 180 -biotype 734 CA "C-Terminal LYS" 225 -biotype 735 C "C-Terminal LYS" 213 -biotype 736 HN "C-Terminal LYS" 183 -biotype 737 OXT "C-Terminal LYS" 214 -biotype 738 HA "C-Terminal LYS" 85 -biotype 739 N "C-Terminal LYD (NH2)" -1 -biotype 740 CA "C-Terminal LYD (NH2)" -1 -biotype 741 C "C-Terminal LYD (NH2)" -1 -biotype 742 HN "C-Terminal LYD (NH2)" -1 -biotype 743 OXT "C-Terminal LYD (NH2)" -1 -biotype 744 HA "C-Terminal LYD (NH2)" -1 -biotype 745 N "C-Terminal ARG" 180 -biotype 746 CA "C-Terminal ARG" 225 -biotype 747 C "C-Terminal ARG" 213 -biotype 748 HN "C-Terminal ARG" 183 -biotype 749 OXT "C-Terminal ARG" 214 -biotype 750 HA "C-Terminal ARG" 85 -biotype 751 N "C-Terminal ORN" 180 -biotype 752 CA "C-Terminal ORN" 225 -biotype 753 C "C-Terminal ORN" 213 -biotype 754 HN "C-Terminal ORN" 183 -biotype 755 OXT "C-Terminal ORN" 214 -biotype 756 HA "C-Terminal ORN" 85 -biotype 757 N "C-Terminal AIB" 180 -biotype 758 CA "C-Terminal AIB" 227 -biotype 759 C "C-Terminal AIB" 213 -biotype 760 HN "C-Terminal AIB" 183 -biotype 761 OXT "C-Terminal AIB" 214 -biotype 762 N "Deprotonated N-Terminus" -1 -biotype 763 H "Deprotonated N-Terminus" -1 -biotype 764 C "Formyl N-Terminus" 177 -biotype 765 H "Formyl N-Terminus" 221 -biotype 766 O "Formyl N-Terminus" 178 -biotype 767 CH3 "Acetyl N-Terminus" 80 -biotype 768 H "Acetyl N-Terminus" 85 -biotype 769 C "Acetyl N-Terminus" 177 -biotype 770 O "Acetyl N-Terminus" 178 -biotype 771 C "Protonated C-Terminus" -1 -biotype 772 O "Protonated C-Terminus" -1 -biotype 773 OH "Protonated C-Terminus" -1 -biotype 774 HO "Protonated C-Terminus" -1 -biotype 775 N "Amide C-Terminus" 179 -biotype 776 HN "Amide C-Terminus" 182 -biotype 777 N "N-MeAmide C-Terminus" 180 -biotype 778 HN "N-MeAmide C-Terminus" 183 -biotype 779 CH3 "N-MeAmide C-Terminus" 184 -biotype 780 H "N-MeAmide C-Terminus" 85 -biotype 2001 O "Water" 63 -biotype 2002 H "Water" 64 -biotype 2003 NA "Sodium Ion" -1 -biotype 2004 K "Potassium Ion" -1 -biotype 2005 MG "Magnesium Ion" -1 -biotype 2006 CA "Calcium Ion" -1 -biotype 2007 CL "Chloride Ion" -1 diff --git a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/moltemplate_files/system.lt b/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/moltemplate_files/system.lt deleted file mode 100644 index fae58d65c9..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/moltemplate_files/system.lt +++ /dev/null @@ -1,21 +0,0 @@ -import "ethylene.lt" # <- defines the "Ethylene" molecule type. -import "benzene.lt" # <- defines the "Benzene" molecule type. - - -# Periodic boundary conditions: -write_once("Data Boundary") { - 0.0 80.00 xlo xhi - 0.0 80.00 ylo yhi - 0.0 80.00 zlo zhi -} - - -# Create 1000 ethylenes and 500 benzenes -# List them in the same order they appear in the PACKMOL .inp file(s). - -ethylenes = new Ethylene[1000] -benzenes = new Benzene[500] - -# Note: We can omit the .move() and .rot() commands which normally appear -# after the "new" command because we will be using a separate program -# (PACKMOL) to generate the coordinates of these molecules. diff --git a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/moltemplate_files/system.xyz b/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/moltemplate_files/system.xyz deleted file mode 100644 index d64a95504d..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/moltemplate_files/system.xyz +++ /dev/null @@ -1,12002 +0,0 @@ - 12000 - Built with Packmol - C1 22.651014 24.498564 11.614060 - C2 22.571262 24.140589 10.326266 - H11 23.515857 24.451603 12.160727 - H12 21.853441 24.847475 12.153636 - H21 23.368835 23.791678 9.786690 - H22 21.706418 24.187550 9.779599 - C1 21.435403 10.177603 61.812264 - C2 20.874880 11.369561 61.571491 - H11 22.444012 10.040471 61.925867 - H12 20.899589 9.309329 61.901752 - H21 21.410694 12.237834 61.482003 - H22 19.866271 11.506692 61.457888 - C1 50.424240 2.165264 4.144155 - C2 51.118136 2.597830 3.083817 - H11 49.739110 2.740029 4.643402 - H12 50.524074 1.225635 4.539293 - H21 51.018302 3.537459 2.688679 - H22 51.803265 2.023065 2.584570 - C1 69.502684 36.682180 15.542915 - C2 70.510550 36.378868 14.715189 - H11 68.606679 37.063658 15.225656 - H12 69.548565 36.556544 16.558353 - H21 70.464670 36.504504 13.699751 - H22 71.406555 35.997391 15.032448 - C1 63.290190 42.633189 15.920572 - C2 63.657324 41.430907 15.459430 - H11 63.819808 43.491766 15.743500 - H12 62.450898 42.788725 16.486611 - H21 64.496616 41.275370 14.893390 - H22 63.127707 40.572330 15.636501 - C1 51.014039 43.520922 29.546351 - C2 51.721815 42.741456 30.373640 - H11 51.246058 43.652102 28.557431 - H12 50.185018 44.047214 29.837460 - H21 52.550836 42.215165 30.082531 - H22 51.489796 42.610276 31.362560 - C1 21.041209 33.203742 56.448080 - C2 20.018646 33.390439 57.292136 - H11 21.505740 33.966278 55.946329 - H12 21.439201 32.283731 56.237879 - H21 19.620655 34.310451 57.502338 - H22 19.554115 32.627903 57.793888 - C1 19.380903 57.909273 60.136394 - C2 18.507842 56.895938 60.198342 - H11 20.339380 57.808490 59.789740 - H12 19.158845 58.864795 60.430795 - H21 18.729900 55.940416 59.903941 - H22 17.549365 56.996721 60.544995 - C1 69.943496 73.076888 53.702677 - C2 70.336463 72.141689 54.576692 - H11 70.543548 73.846082 53.390775 - H12 69.011982 73.096524 53.277355 - H21 71.267977 72.122052 55.002014 - H22 69.736411 71.372495 54.888594 - C1 53.216166 34.782224 61.298469 - C2 52.832439 34.524767 62.555207 - H11 54.194493 34.781481 60.995353 - H12 52.561509 35.000129 60.541538 - H21 53.487097 34.306861 63.312139 - H22 51.854112 34.525510 62.858323 - C1 37.787302 28.010773 79.082839 - C2 39.036254 28.109043 78.610206 - H11 37.327390 27.117487 79.281648 - H12 37.193735 28.821168 79.282692 - H21 39.629821 27.298648 78.410353 - H22 39.496167 29.002329 78.411398 - C1 57.917058 25.635725 48.236420 - C2 58.654068 24.999341 49.155524 - H11 56.959578 25.958090 48.404698 - H12 58.252876 25.850142 47.292887 - H21 58.318251 24.784924 50.099058 - H22 59.611548 24.676976 48.987247 - C1 48.704501 39.022829 79.368761 - C2 48.146767 39.263710 78.175518 - H11 48.670604 38.111147 79.834261 - H12 49.208841 39.731331 79.909751 - H21 47.642426 38.555209 77.634528 - H22 48.180664 40.175392 77.710018 - C1 49.290389 30.217190 60.388264 - C2 49.629489 31.508662 60.288103 - H11 48.386460 29.845304 60.082294 - H12 49.908290 29.499731 60.778719 - H21 49.011589 32.226121 59.897648 - H22 50.533418 31.880547 60.594072 - C1 70.285207 40.468345 63.514615 - C2 69.451519 39.423750 63.596504 - H11 69.973795 41.443456 63.549032 - H12 71.299829 40.374340 63.411125 - H21 68.436897 39.517755 63.699994 - H22 69.762931 38.448639 63.562087 - C1 74.639200 8.945741 65.383745 - C2 74.083871 8.050095 64.557700 - H11 75.439088 9.531374 65.126417 - H12 74.307728 9.115576 66.337833 - H21 74.415344 7.880259 63.603611 - H22 73.283984 7.464462 64.815028 - C1 39.172540 71.787133 27.530358 - C2 38.962281 73.109074 27.495972 - H11 38.439875 71.093963 27.352253 - H12 40.082557 71.365257 27.737466 - H21 38.052264 73.530950 27.288863 - H22 39.694946 73.802244 27.674077 - C1 65.444930 70.845785 18.893696 - C2 64.680569 70.650896 17.811711 - H11 65.752408 70.089077 19.511639 - H12 65.782184 71.766880 19.188396 - H21 64.343315 69.729802 17.517010 - H22 64.373091 71.407604 17.193767 - C1 71.315072 36.001969 8.560061 - C2 70.304030 35.509365 7.833388 - H11 72.136503 35.452946 8.829930 - H12 71.346447 36.966500 8.903134 - H21 70.272655 34.544833 7.490315 - H22 69.482599 36.058388 7.563519 - C1 54.191566 63.992227 58.039470 - C2 53.632368 65.208827 58.049583 - H11 53.651049 63.122259 58.038625 - H12 55.203761 63.836004 58.031784 - H21 52.620173 65.365050 58.057269 - H22 54.172885 66.078795 58.050428 - C1 21.609595 5.135661 55.089620 - C2 22.533981 6.060397 55.378228 - H11 21.510842 4.255922 55.604702 - H12 20.928637 5.235394 54.331099 - H21 23.214939 5.960664 56.136748 - H22 22.632735 6.940137 54.863145 - C1 26.879519 23.479073 55.696825 - C2 28.211869 23.566739 55.596432 - H11 26.250395 24.278425 55.577480 - H12 26.384818 22.605776 55.900851 - H21 28.706570 24.440036 55.392406 - H22 28.840993 22.767387 55.715778 - C1 62.158924 30.644098 72.300606 - C2 62.692496 31.260098 71.238172 - H11 61.873130 29.660573 72.298548 - H12 61.994654 31.108033 73.198817 - H21 62.856766 30.796162 70.339961 - H22 62.978290 32.243623 71.240230 - C1 34.188367 42.393096 23.904692 - C2 35.516091 42.311539 23.751663 - H11 33.656449 43.257919 23.769975 - H12 33.600361 41.597065 24.168489 - H21 36.104096 43.107570 23.487866 - H22 36.048008 41.446716 23.886380 - C1 13.879265 36.414981 75.272748 - C2 14.490672 36.171191 76.438796 - H11 12.892360 36.678130 75.196763 - H12 14.350455 36.357468 74.365182 - H21 14.019482 36.228704 77.346362 - H22 15.477578 35.908042 76.514781 - C1 44.333608 42.745532 32.963104 - C2 44.076743 42.033211 31.858777 - H11 45.280528 42.958100 33.290460 - H12 43.603353 43.133802 33.567238 - H21 44.806998 41.644941 31.254643 - H22 43.129823 41.820643 31.531421 - C1 75.807431 43.681223 40.332840 - C2 77.077645 43.265414 40.413954 - H11 75.523624 44.538495 39.849578 - H12 75.019823 43.174681 40.747683 - H21 77.865252 43.771955 39.999111 - H22 77.361452 42.408142 40.897216 - C1 36.461650 32.287602 26.835698 - C2 36.105596 33.336254 27.588342 - H11 36.493989 31.325833 27.186354 - H12 36.729639 32.364841 25.850193 - H21 35.837607 33.259015 28.573847 - H22 36.073257 34.298023 27.237686 - C1 75.437961 4.371036 70.982983 - C2 75.130503 5.594304 70.533531 - H11 75.172120 3.508321 70.499191 - H12 75.963140 4.201937 71.845883 - H21 74.605325 5.763404 69.670631 - H22 75.396344 6.457019 71.017323 - C1 34.736383 32.471107 61.860615 - C2 34.821355 33.435200 62.785939 - H11 35.097807 31.522737 61.998350 - H12 34.303285 32.606273 60.942377 - H21 35.254452 33.300034 63.704177 - H22 34.459930 34.383570 62.648204 - C1 68.248696 55.181995 56.218730 - C2 68.784952 54.133299 55.581873 - H11 67.581696 55.093055 56.990872 - H12 68.463370 56.155501 55.983770 - H21 68.570279 53.159793 55.816832 - H22 69.451953 54.222239 54.809730 - C1 48.511144 28.944432 68.606003 - C2 49.283761 28.207780 69.414291 - H11 47.677799 28.580112 68.135035 - H12 48.692795 29.930111 68.395188 - H21 49.102110 27.222100 69.625106 - H22 50.117106 28.572100 69.885259 - C1 4.556463 34.366964 31.086230 - C2 5.876827 34.198783 30.940365 - H11 4.023215 33.991611 31.876015 - H12 3.975997 34.884176 30.419481 - H21 6.457293 33.681571 31.607114 - H22 6.410075 34.574136 30.150580 - C1 41.710507 53.347212 43.580312 - C2 42.113206 54.581297 43.908620 - H11 42.002082 52.505061 44.085059 - H12 41.079257 53.148423 42.798640 - H21 42.744456 54.780086 44.690293 - H22 41.821631 55.423448 43.403874 - C1 19.790783 55.013910 20.328197 - C2 19.749862 54.158503 21.357530 - H11 18.993747 55.588771 20.039630 - H12 20.622337 55.160576 19.748532 - H21 18.918308 54.011837 21.937195 - H22 20.546898 53.583642 21.646097 - C1 8.143656 42.683712 21.395637 - C2 7.904280 41.425572 21.004863 - H11 7.868391 43.506262 20.850986 - H12 8.620832 42.922392 22.269901 - H21 7.427104 41.186892 20.130598 - H22 8.179545 40.603022 21.549514 - C1 9.076078 43.978357 59.924781 - C2 9.312663 45.122264 60.579323 - H11 8.367832 43.297774 60.214950 - H12 9.584765 43.694066 59.082510 - H21 8.803975 45.406555 61.421594 - H22 10.020908 45.802847 60.289154 - C1 31.249523 75.052516 20.231411 - C2 31.106461 76.226093 20.860038 - H11 32.144117 74.560344 20.150962 - H12 30.475600 74.554787 19.781619 - H21 31.880384 76.723822 21.309830 - H22 30.211867 76.718265 20.940487 - C1 31.940010 12.491378 39.160561 - C2 32.143367 13.201051 38.043453 - H11 31.078081 11.971730 39.350423 - H12 32.630410 12.412423 39.912970 - H21 31.452968 13.280006 37.291045 - H22 33.005297 13.720700 37.853592 - C1 46.972771 51.543538 54.957717 - C2 46.844195 50.581632 54.035153 - H11 47.793218 52.152582 55.027981 - H12 46.260778 51.745854 55.665628 - H21 47.556188 50.379316 53.327242 - H22 46.023748 49.972588 53.964889 - C1 65.969573 7.657589 41.010763 - C2 66.656346 7.452924 39.879668 - H11 65.724543 8.587900 41.362169 - H12 65.635316 6.899912 41.613425 - H21 66.990603 8.210601 39.277006 - H22 66.901376 6.522614 39.528262 - C1 55.336302 23.513249 17.058916 - C2 56.662450 23.421190 17.219469 - H11 54.894492 23.895307 16.217584 - H12 54.659519 23.208842 17.764823 - H21 57.339234 23.725597 16.513563 - H22 57.104260 23.039132 18.060801 - C1 36.704235 71.388396 71.225248 - C2 37.607597 70.654065 71.886773 - H11 36.837072 71.715379 70.263770 - H12 35.809420 71.680814 71.628735 - H21 38.502412 70.361647 71.483286 - H22 37.474759 70.327081 72.848251 - C1 75.533482 46.415410 48.760132 - C2 74.283642 45.935057 48.769209 - H11 76.050938 46.659252 49.609711 - H12 76.070254 46.576742 47.902898 - H21 73.746870 45.773726 49.626444 - H22 73.766186 45.691216 47.919630 - C1 54.786475 15.518643 62.020361 - C2 53.702166 14.733077 62.011445 - H11 55.745099 15.158028 62.020090 - H12 54.742456 16.541876 62.028152 - H21 53.746185 13.709844 62.003653 - H22 52.743541 15.093692 62.011715 - C1 6.297111 63.847009 32.798995 - C2 5.501701 63.847905 33.876141 - H11 6.312061 64.602314 32.107406 - H12 6.953083 63.090948 32.582021 - H21 4.845729 64.603965 34.093114 - H22 5.486751 63.092600 34.567729 - C1 62.019414 36.410072 52.321586 - C2 61.921326 37.744923 52.283207 - H11 61.209686 35.785845 52.382293 - H12 62.911877 35.908365 52.293252 - H21 61.028863 38.246630 52.311541 - H22 62.731054 38.369150 52.222500 - C1 18.418230 12.239910 47.031087 - C2 19.309493 12.986024 46.366342 - H11 17.844099 12.597496 47.800184 - H12 18.240589 11.252985 46.822697 - H21 19.487134 13.972949 46.574732 - H22 19.883624 12.628438 45.597245 - C1 6.851760 43.192701 43.853277 - C2 6.657568 44.004696 42.806436 - H11 7.243749 42.249999 43.771665 - H12 6.623569 43.450493 44.817889 - H21 6.885758 43.746904 41.841824 - H22 6.265579 44.947398 42.888048 - C1 9.924466 47.871793 46.926570 - C2 9.131751 48.344163 47.896823 - H11 9.717285 47.023845 46.390786 - H12 10.800294 48.321301 46.643955 - H21 8.255923 47.894655 48.179438 - H22 9.338932 49.192111 48.432607 - C1 70.293803 20.435201 36.006011 - C2 71.600713 20.322409 35.737336 - H11 69.579831 19.819402 35.605963 - H12 69.905409 21.146140 36.632685 - H21 71.989107 19.611470 35.110662 - H22 72.314685 20.938209 36.137385 - C1 60.627380 72.544908 66.536898 - C2 61.434029 71.511158 66.265607 - H11 60.947547 73.408775 66.984370 - H12 59.626813 72.553001 66.318257 - H21 62.434596 71.503066 66.484248 - H22 61.113862 70.647291 65.818135 - C1 72.707987 20.069413 78.398098 - C2 72.425227 20.873574 79.430712 - H11 73.641169 19.989441 77.983636 - H12 72.013309 19.471082 77.941559 - H21 73.119904 21.471905 79.887251 - H22 71.492044 20.953546 79.845174 - C1 72.426183 34.041616 74.908482 - C2 72.565284 34.863666 75.956243 - H11 71.732900 33.288725 74.869537 - H12 73.002137 34.101115 74.063650 - H21 71.989330 34.804168 76.801075 - H22 73.258568 35.616558 75.995188 - C1 45.744062 6.374741 34.180465 - C2 45.256451 6.813170 35.347914 - H11 46.490595 6.850927 33.665743 - H12 45.408825 5.528744 33.710456 - H21 45.591688 7.659167 35.817923 - H22 44.509918 6.336984 35.862636 - C1 59.376459 64.619177 32.610172 - C2 59.060510 63.320204 32.686106 - H11 58.709524 65.374293 32.794568 - H12 60.309894 64.959733 32.361727 - H21 58.127075 62.979649 32.934551 - H22 59.727444 62.565088 32.501710 - C1 69.738652 21.177781 56.714948 - C2 68.513696 20.693270 56.474840 - H11 70.244623 21.782963 56.061686 - H12 70.265921 20.981279 57.570739 - H21 67.986427 20.889772 55.619049 - H22 68.007725 20.088088 57.128102 - C1 65.365438 56.864613 2.461825 - C2 64.032599 56.992904 2.462764 - H11 65.845691 55.959980 2.462252 - H12 66.009423 57.661033 2.460604 - H21 63.388614 56.196483 2.463985 - H22 63.552346 57.897537 2.462337 - C1 12.824370 17.163565 22.149983 - C2 11.863155 17.986843 21.712718 - H11 12.635988 16.251345 22.575861 - H12 13.823528 17.381358 22.092936 - H21 10.863998 17.769050 21.769765 - H22 12.051537 18.899062 21.286840 - C1 31.582065 25.069299 57.525882 - C2 30.433862 25.663623 57.874205 - H11 32.248339 25.473665 56.861375 - H12 31.884290 24.163625 57.896583 - H21 30.131637 26.569297 57.503504 - H22 29.767588 25.259256 58.538712 - C1 14.805579 39.218967 22.159828 - C2 14.053961 40.322004 22.266126 - H11 15.605464 39.139663 21.525084 - H12 14.639678 38.367870 22.704909 - H21 14.219862 41.173102 21.721044 - H22 13.254076 40.401308 22.900869 - C1 26.688171 52.639484 35.523273 - C2 26.084610 52.414977 34.349292 - H11 27.653431 52.362134 35.724154 - H12 26.232009 53.106205 36.312635 - H21 26.540772 51.948256 33.559931 - H22 25.119350 52.692328 34.148412 - C1 55.610491 17.028389 57.811480 - C2 54.538325 16.226281 57.813793 - H11 56.562635 16.697858 57.629342 - H12 55.562709 18.035490 57.991668 - H21 54.586108 15.219180 57.633605 - H22 53.586181 16.556812 57.995931 - C1 41.380111 57.320149 74.764966 - C2 41.115191 56.376565 73.852613 - H11 40.680011 57.689788 75.414760 - H12 42.303668 57.746414 74.884734 - H21 40.191634 55.950300 73.732845 - H22 41.815291 56.006926 73.202820 - C1 71.480990 76.707299 66.210683 - C2 70.832050 75.536373 66.183674 - H11 72.499987 76.789767 66.148647 - H12 71.009369 77.612497 66.295501 - H21 71.303672 74.631176 66.098856 - H22 69.813054 75.453905 66.245710 - C1 59.265586 33.360837 4.782339 - C2 58.910264 33.642294 6.042279 - H11 60.144779 32.898126 4.533497 - H12 58.686105 33.586142 3.968433 - H21 59.489745 33.416990 6.856185 - H22 58.031071 34.105005 6.291121 - C1 43.268413 7.036586 17.767022 - C2 44.283133 7.909535 17.801991 - H11 42.282959 7.315538 17.775389 - H12 43.397960 6.021309 17.729159 - H21 44.153586 8.924813 17.839854 - H22 45.268587 7.630583 17.793624 - C1 14.303342 27.294886 78.058828 - C2 14.521918 25.976940 78.149183 - H11 13.930112 27.749233 77.220214 - H12 14.492205 27.952215 78.821228 - H21 14.333055 25.319612 77.386783 - H22 14.895148 25.522594 78.987796 - C1 56.503415 56.687620 20.535795 - C2 57.095322 57.887329 20.478662 - H11 56.683148 55.936620 19.862965 - H12 55.824416 56.426675 21.256815 - H21 57.774322 58.148274 19.757641 - H22 56.915590 58.638329 21.151491 - C1 26.325906 49.428751 6.752187 - C2 27.180578 49.773921 7.723431 - H11 25.560819 50.030285 6.433123 - H12 26.370084 48.536068 6.252018 - H21 27.136400 50.666603 8.223601 - H22 27.945665 49.172386 8.042495 - C1 68.356046 43.034127 49.281166 - C2 67.417903 42.154275 49.653551 - H11 69.243631 42.763629 48.847545 - H12 68.259775 44.046773 49.400684 - H21 67.514174 41.141630 49.534032 - H22 66.530318 42.424774 50.087171 - C1 58.750514 42.571025 9.951302 - C2 57.824206 41.901750 9.253487 - H11 58.536366 43.132401 10.780761 - H12 59.745995 42.574176 9.710444 - H21 56.828726 41.898599 9.494345 - H22 58.038354 41.340375 8.424028 - C1 78.096825 53.647615 56.170255 - C2 79.364665 53.762964 56.585223 - H11 77.653085 54.304099 55.521312 - H12 77.471154 52.893834 56.469178 - H21 79.990336 54.516745 56.286301 - H22 79.808405 53.106480 57.234166 - C1 75.443737 59.804447 59.852465 - C2 76.241925 59.946597 58.786815 - H11 74.496978 59.417114 59.801234 - H12 75.717232 60.071878 60.802563 - H21 75.968430 59.679166 57.836718 - H22 77.188684 60.333930 58.838047 - C1 72.964247 59.764211 68.198770 - C2 73.150980 60.805344 67.377738 - H11 73.302131 58.818540 67.997415 - H12 72.468856 59.831697 69.092659 - H21 73.646372 60.737859 66.483849 - H22 72.813096 61.751015 67.579093 - C1 3.780965 73.674108 18.276575 - C2 4.564058 72.615775 18.032407 - H11 2.868422 73.607194 18.736782 - H12 4.032977 74.633717 18.022321 - H21 4.312045 71.656167 18.286661 - H22 5.476601 72.682689 17.572200 - C1 51.326576 58.862193 60.033663 - C2 51.741900 57.749348 60.651726 - H11 50.393992 58.965574 59.623051 - H12 51.908839 59.697487 59.922945 - H21 51.159637 56.914054 60.762445 - H22 52.674484 57.645967 61.062339 - C1 70.918299 76.144497 3.411404 - C2 70.194075 75.217220 4.050605 - H11 70.536809 77.041836 3.097953 - H12 71.910665 76.029307 3.185694 - H21 69.201709 75.332410 4.276315 - H22 70.575565 74.319881 4.364056 - C1 23.286637 78.333899 45.532595 - C2 22.519205 78.753421 44.518706 - H11 22.950452 78.244662 46.495933 - H12 24.270143 78.069274 45.424463 - H21 21.535699 79.018046 44.626838 - H22 22.855390 78.842659 43.555368 - C1 54.053727 10.327201 40.973268 - C2 52.881685 10.416903 40.332025 - H11 54.450157 11.086960 41.534172 - H12 54.645903 9.491779 40.953246 - H21 52.289509 11.252325 40.352046 - H22 52.485256 9.657144 39.771121 - C1 55.723353 79.416682 76.098682 - C2 55.264541 79.365550 74.841781 - H11 56.539882 79.967357 76.379822 - H12 55.293827 78.909136 76.877725 - H21 55.694067 79.873096 74.062738 - H22 54.448012 78.814874 74.560641 - C1 14.375622 12.614939 44.307875 - C2 14.258224 11.281096 44.308595 - H11 15.131610 13.115559 44.784178 - H12 13.718656 13.239404 43.830964 - H21 14.915190 10.656631 44.785506 - H22 13.502236 10.780476 43.832292 - C1 20.301209 50.147413 12.467328 - C2 20.444032 48.967084 13.083238 - H11 20.701901 50.356994 11.548347 - H12 19.780047 50.933429 12.866794 - H21 20.965193 48.181068 12.683772 - H22 20.043339 48.757503 14.002219 - C1 22.305273 2.647366 41.472460 - C2 23.072121 3.515715 42.143903 - H11 22.673695 1.980522 40.787925 - H12 21.290023 2.581764 41.590640 - H21 24.087371 3.581316 42.025723 - H22 22.703699 4.182558 42.828439 - C1 53.544893 76.514586 76.075925 - C2 54.824801 76.127304 76.144988 - H11 52.822480 75.990069 75.573925 - H12 53.187716 77.365772 76.519672 - H21 55.181978 75.276118 75.701241 - H22 55.547215 76.651821 76.646988 - C1 50.682521 64.403223 74.198805 - C2 51.993393 64.651164 74.084521 - H11 50.303883 63.537608 74.594214 - H12 49.955450 65.059702 73.899793 - H21 52.720463 63.994685 74.383532 - H22 52.372031 65.516779 73.689112 - C1 30.077840 22.246797 59.754006 - C2 30.599371 21.013943 59.785634 - H11 29.071151 22.434702 59.770519 - H12 30.644623 23.098791 59.710815 - H21 30.032588 20.161949 59.828825 - H22 31.606060 20.826038 59.769120 - C1 9.783127 13.436311 17.658675 - C2 10.498487 12.305336 17.613106 - H11 8.759840 13.459141 17.621725 - H12 10.203015 14.367447 17.734060 - H21 10.078600 11.374200 17.537720 - H22 11.521775 12.282506 17.650055 - C1 9.353180 56.897278 35.092399 - C2 10.070813 57.602344 34.208767 - H11 8.577974 56.282372 34.827916 - H12 9.523068 56.917467 36.102218 - H21 9.900925 57.582154 33.198948 - H22 10.846018 58.217250 34.473251 - C1 8.597927 16.386744 38.202692 - C2 9.843071 16.711715 37.832650 - H11 8.370232 15.546188 38.741788 - H12 7.775353 16.953190 37.975721 - H21 10.665645 16.145269 38.059621 - H22 10.070765 17.552271 37.293554 - C1 71.235390 48.768090 39.194293 - C2 72.148338 47.934918 38.679249 - H11 71.066065 48.868802 40.199375 - H12 70.634651 49.370153 38.623646 - H21 72.749076 47.332856 39.249897 - H22 72.317663 47.834206 37.674167 - C1 1.707082 14.980152 40.607648 - C2 1.193022 13.756774 40.428735 - H11 1.153533 15.839737 40.546815 - H12 2.694236 15.152475 40.819393 - H21 0.205868 13.584452 40.216990 - H22 1.746571 12.897189 40.489568 - C1 41.744490 72.977878 22.255746 - C2 40.597602 73.580207 22.594522 - H11 42.530085 72.855218 22.901345 - H12 41.926284 72.592478 21.324391 - H21 40.415809 73.965607 23.525877 - H22 39.812008 73.702866 21.948923 - C1 4.018437 61.583014 75.997459 - C2 5.213520 61.683915 76.592872 - H11 3.634021 60.700068 75.648698 - H12 3.394812 62.380851 75.843995 - H21 5.837145 60.886078 76.746337 - H22 5.597936 62.566861 76.941633 - C1 77.185779 47.435685 70.227115 - C2 78.134261 47.947743 71.021533 - H11 76.548026 46.688935 70.518044 - H12 77.023496 47.750520 69.266101 - H21 78.296544 47.632908 71.982547 - H22 78.772013 48.694493 70.730603 - C1 67.886928 53.565391 18.883431 - C2 68.250619 54.777472 18.445813 - H11 66.914888 53.298940 19.065493 - H12 68.552197 52.809463 19.070495 - H21 67.585349 55.533400 18.258749 - H22 69.222659 55.043924 18.263751 - C1 36.745375 30.126906 68.613282 - C2 37.959645 30.538107 68.226781 - H11 35.877164 30.598983 68.344286 - H12 36.589359 29.307986 69.208288 - H21 38.115660 31.357027 67.631775 - H22 38.827855 30.066031 68.495777 - C1 30.031294 14.147621 30.810674 - C2 31.011016 13.242710 30.691500 - H11 30.193215 15.158945 30.807616 - H12 29.042987 13.899581 30.914255 - H21 31.999323 13.490750 30.587919 - H22 30.849095 12.231386 30.694558 - C1 16.794125 67.795458 57.969397 - C2 16.222307 67.996273 56.775404 - H11 16.440392 68.201833 58.840452 - H12 17.630181 67.219698 58.105464 - H21 15.386252 68.572034 56.639337 - H22 16.576040 67.589898 55.904350 - C1 66.450388 22.180511 61.877453 - C2 67.181728 23.253402 61.550390 - H11 65.528541 22.238992 62.319925 - H12 66.755357 21.217058 61.710855 - H21 66.876758 24.216855 61.716988 - H22 68.103575 23.194921 61.107918 - C1 3.895195 25.075174 62.467106 - C2 3.219485 26.222662 62.607133 - H11 3.446251 24.175824 62.270582 - H12 4.914095 25.006629 62.545518 - H21 2.200585 26.291207 62.528722 - H22 3.668429 27.122013 62.803657 - C1 50.640164 12.762978 39.560173 - C2 50.888838 14.068377 39.395813 - H11 50.211541 12.371627 40.404051 - H12 50.859034 12.053236 38.854930 - H21 50.669968 14.778119 40.101055 - H22 51.317461 14.459728 38.551934 - C1 55.589764 48.094060 21.756450 - C2 54.634165 47.163254 21.640905 - H11 55.395196 49.096741 21.832468 - H12 56.590371 47.876506 21.777894 - H21 53.633558 47.380808 21.619462 - H22 54.828732 46.160573 21.564887 - C1 57.459520 34.282991 45.843543 - C2 56.846495 33.099790 45.974526 - H11 58.474262 34.386002 45.750311 - H12 56.961859 35.178000 45.826291 - H21 57.344156 32.204782 45.991779 - H22 55.831754 32.996779 46.067758 - C1 10.253400 51.913840 49.969905 - C2 11.199522 51.376845 49.189258 - H11 9.629771 51.359599 50.563965 - H12 10.078985 52.921032 50.034314 - H21 11.373938 50.369654 49.124849 - H22 11.823152 51.931086 48.595198 - C1 3.382905 33.011196 18.270560 - C2 2.236200 32.320097 18.289825 - H11 4.291950 32.603627 18.508316 - H12 3.441095 34.001700 18.016555 - H21 2.178010 31.329593 18.543831 - H22 1.327155 32.727666 18.052069 - C1 11.638102 9.528396 43.030297 - C2 11.889634 10.049488 41.822773 - H11 11.124937 10.025530 43.764139 - H12 11.939101 8.591725 43.314992 - H21 11.588635 10.986158 41.538078 - H22 12.402799 9.552353 41.088932 - C1 44.281259 47.686892 11.628774 - C2 43.874065 47.967718 10.384486 - H11 43.684031 47.241034 12.331293 - H12 45.221952 47.895876 11.975799 - H21 42.933372 47.758734 10.037460 - H22 44.471293 48.413575 9.681967 - C1 25.508582 3.850226 26.739930 - C2 25.751064 3.230802 25.577847 - H11 25.178711 3.365908 27.579944 - H12 25.633923 4.857023 26.880122 - H21 25.625724 2.224005 25.437655 - H22 26.080936 3.715121 24.737832 - C1 78.839274 73.496762 25.790325 - C2 79.016321 72.652886 24.765898 - H11 78.037790 73.452428 26.426455 - H12 79.491421 74.252897 26.018289 - H21 78.364174 71.896751 24.537934 - H22 79.817805 72.697220 24.129768 - C1 59.793133 12.974603 29.277873 - C2 58.655937 12.742922 28.610018 - H11 60.567354 12.305668 29.323833 - H12 59.978127 13.838959 29.795241 - H21 58.470943 11.878566 28.092650 - H22 57.881717 13.411857 28.564057 - C1 63.810243 30.481974 61.953660 - C2 63.837353 31.757129 62.361295 - H11 62.945121 29.970349 61.756666 - H12 64.652499 29.918018 61.806819 - H21 62.995097 32.321085 62.508137 - H22 64.702475 32.268754 62.558289 - C1 66.278987 15.977907 70.856468 - C2 65.249655 16.505776 71.530821 - H11 67.243303 15.985056 71.201498 - H12 66.182902 15.525506 69.942627 - H21 65.345740 16.958177 72.444661 - H22 64.285338 16.498627 71.185790 - C1 44.783442 17.083909 21.393342 - C2 45.177943 15.853094 21.743177 - H11 45.112547 17.564258 20.550752 - H12 44.121580 17.641741 21.940850 - H21 45.839805 15.295262 21.195669 - H22 44.848837 15.372745 22.585767 - C1 5.527036 30.262819 7.175848 - C2 6.553646 30.165252 8.029940 - H11 5.449998 30.998190 6.467118 - H12 4.738139 29.609743 7.164158 - H21 7.342544 30.818327 8.041630 - H22 6.630684 29.429880 8.738670 - C1 11.620715 29.633348 67.431599 - C2 10.575185 28.855358 67.124159 - H11 11.540881 30.635779 67.625924 - H12 12.582444 29.287144 67.496596 - H21 9.613456 29.201561 67.059161 - H22 10.655019 27.852926 66.929834 - C1 31.259990 34.997736 48.465829 - C2 30.166825 35.770005 48.504718 - H11 31.227922 33.974230 48.445546 - H12 32.214131 35.369840 48.453309 - H21 29.212684 35.397902 48.517237 - H22 30.198893 36.793511 48.525000 - C1 75.069988 27.538186 68.426131 - C2 75.965497 26.718829 68.991498 - H11 74.121478 27.248166 68.170745 - H12 75.263145 28.519325 68.204635 - H21 75.772340 25.737690 69.212994 - H22 76.914006 27.008848 69.246884 - C1 1.460434 47.828474 69.217470 - C2 1.750062 49.037641 69.714412 - H11 1.310775 47.648778 68.220316 - H12 1.365795 46.988249 69.795457 - H21 1.844701 49.877866 69.136425 - H22 1.899721 49.217337 70.711565 - C1 30.970161 67.933396 13.612688 - C2 32.129504 68.563539 13.385175 - H11 30.467278 67.400302 12.897200 - H12 30.495147 67.934969 14.520082 - H21 32.604518 68.561965 12.477781 - H22 32.632387 69.096633 14.100664 - C1 7.301989 64.177370 56.561084 - C2 7.861392 64.085861 57.774185 - H11 6.853283 65.028012 56.208841 - H12 7.278844 63.403916 55.890087 - H21 7.884536 64.859315 58.445182 - H22 8.310098 63.235219 58.126428 - C1 16.547675 17.143252 78.402737 - C2 17.659406 17.889022 78.431093 - H11 15.640847 17.467908 78.750968 - H12 16.516770 16.189547 78.030588 - H21 17.690312 18.842727 78.803242 - H22 18.566234 17.564367 78.082862 - C1 37.215973 76.096868 66.794271 - C2 37.228767 76.305839 68.116802 - H11 36.827323 75.254990 66.359305 - H12 37.593832 76.762482 66.113694 - H21 36.850908 75.640225 68.797379 - H22 37.617417 77.147717 68.551768 - C1 33.651436 7.550502 38.099534 - C2 33.290583 8.823148 37.891983 - H11 33.678080 6.843171 37.359279 - H12 33.929168 7.184368 39.014856 - H21 33.012851 9.189282 36.976660 - H22 33.263938 9.530479 38.632237 - C1 61.440229 46.076559 79.999705 - C2 61.697127 44.762434 79.999615 - H11 60.493299 46.466850 79.999735 - H12 62.170467 46.794720 79.999751 - H21 60.966888 44.044273 79.999569 - H22 62.644057 44.372143 79.999584 - C1 21.123083 38.113446 56.826592 - C2 21.442727 36.818106 56.939918 - H11 20.956757 38.577615 55.928880 - H12 21.019791 38.741885 57.628714 - H21 21.546019 36.189668 56.137796 - H22 21.609053 36.353938 57.837630 - C1 10.836828 5.388075 17.438268 - C2 11.023542 6.711205 17.524213 - H11 9.912259 4.950352 17.387532 - H12 11.603905 4.709752 17.416511 - H21 10.256465 7.389529 17.545970 - H22 11.948111 7.148929 17.574949 - C1 73.674495 27.881726 23.301971 - C2 73.411565 26.609048 22.979359 - H11 74.615930 28.229630 23.506099 - H12 72.954841 28.607314 23.369963 - H21 74.131219 25.883459 22.911367 - H22 72.470130 26.261144 22.775231 - C1 64.554761 53.384535 30.416963 - C2 63.427075 52.970025 29.825840 - H11 64.574942 54.073558 31.174489 - H12 65.485772 53.045149 30.158045 - H21 62.496064 53.309412 30.084759 - H22 63.406893 52.281003 29.068315 - C1 8.789058 56.838742 18.849630 - C2 10.071176 56.907104 18.469603 - H11 8.079493 56.296660 18.347963 - H12 8.417167 57.323160 19.671847 - H21 10.443066 56.422686 17.647387 - H22 10.780740 57.449186 18.971270 - C1 18.936105 21.700420 39.050863 - C2 18.449272 20.559983 39.556152 - H11 18.428477 22.589718 39.072440 - H12 19.854373 21.773070 38.603079 - H21 17.531005 20.487333 40.003936 - H22 18.956901 19.670684 39.534575 - C1 75.369273 27.303807 47.018527 - C2 76.481183 28.036478 47.159135 - H11 75.349972 26.283752 47.108628 - H12 74.450688 27.705862 46.809824 - H21 77.399768 27.634423 47.367838 - H22 76.500484 29.056533 47.069034 - C1 76.424442 67.348977 53.571538 - C2 76.903514 68.583509 53.373189 - H11 76.559536 66.823631 54.440310 - H12 75.885255 66.833007 52.870071 - H21 77.442701 69.099479 54.074656 - H22 76.768420 69.108854 52.504417 - C1 12.410429 17.367652 65.229367 - C2 11.490397 16.412748 65.415428 - H11 13.416784 17.181826 65.187863 - H12 12.180114 18.358930 65.113930 - H21 11.720712 15.421469 65.530865 - H22 10.484042 16.598573 65.456932 - C1 40.437803 28.197151 43.088515 - C2 39.504808 27.281927 43.379728 - H11 40.280512 29.206638 43.160624 - H12 41.382067 27.959648 42.770771 - H21 38.560544 27.519431 43.697473 - H22 39.662098 26.272440 43.307619 - C1 50.583752 9.384702 57.537620 - C2 49.909086 10.319485 58.218742 - H11 51.374615 9.595276 56.921830 - H12 50.361963 8.385647 57.578890 - H21 50.130874 11.318540 58.177472 - H22 49.118222 10.108911 58.834533 - C1 35.297249 27.058100 24.425475 - C2 35.379700 27.628456 23.216832 - H11 35.615339 27.511759 25.286879 - H12 34.909612 26.123352 24.583550 - H21 35.767337 28.563203 23.058757 - H22 35.061609 27.174797 22.355428 - C1 9.057954 59.812220 30.878483 - C2 9.952214 60.805169 30.963763 - H11 8.214943 59.760162 31.457815 - H12 9.146665 59.026735 30.227216 - H21 9.863503 61.590653 31.615030 - H22 10.795225 60.857227 30.384430 - C1 64.264910 45.131375 37.444382 - C2 62.940588 45.313512 37.521311 - H11 64.788392 45.157701 36.564452 - H12 64.858481 44.951418 38.259424 - H21 62.347017 45.493469 36.706269 - H22 62.417106 45.287186 38.401241 - C1 73.238788 71.098449 75.867721 - C2 73.942590 70.051949 75.417808 - H11 72.542555 71.031123 76.615873 - H12 73.341370 72.048488 75.499067 - H21 73.840007 69.101910 75.786462 - H22 74.638822 70.119276 74.669656 - C1 22.247762 21.166930 39.876861 - C2 22.365440 19.846903 39.685542 - H11 23.005353 21.832992 39.699601 - H12 21.390912 21.614297 40.215497 - H21 23.222290 19.399536 39.346906 - H22 21.607849 19.180840 39.862801 - C1 70.412368 22.135464 62.932053 - C2 70.890249 23.384374 62.862939 - H11 69.455954 21.912045 63.222497 - H12 70.965696 21.305440 62.699905 - H21 70.336921 24.214398 63.095087 - H22 71.846663 23.607793 62.572495 - C1 33.850059 52.236067 2.683994 - C2 34.994545 51.657842 3.069647 - H11 33.662953 53.238330 2.781278 - H12 33.071802 51.721531 2.261416 - H21 35.772803 52.172378 3.492225 - H22 35.181651 50.655579 2.972363 - C1 69.400443 28.996292 46.933132 - C2 70.269746 28.195635 46.303701 - H11 69.437272 29.190691 47.938048 - H12 68.630366 29.477240 46.459134 - H21 71.039823 27.714687 46.777698 - H22 70.232917 28.001237 45.298785 - C1 43.138653 26.844237 52.190202 - C2 42.734952 28.083276 52.497983 - H11 44.094740 26.508484 52.339101 - H12 42.523083 26.134872 51.781693 - H21 43.350522 28.792640 52.906492 - H22 41.778865 28.419029 52.349084 - C1 9.371917 24.191934 26.600410 - C2 8.199979 24.838715 26.566407 - H11 10.203331 24.554326 27.076253 - H12 9.529023 23.283987 26.153247 - H21 8.042874 25.746661 27.013570 - H22 7.368566 24.476322 26.090564 - C1 56.252599 47.983714 14.967848 - C2 55.033838 48.505648 14.780427 - H11 56.414104 47.059999 15.379759 - H12 57.119107 48.467182 14.714025 - H21 54.167329 48.022180 15.034250 - H22 54.872332 49.429363 14.368515 - C1 6.405554 9.071805 3.998137 - C2 6.584095 10.361011 4.312768 - H11 5.609761 8.515809 4.324612 - H12 7.050749 8.540368 3.406273 - H21 5.938901 10.892447 4.904631 - H22 7.379888 10.917007 3.986292 - C1 44.591321 55.923366 30.973432 - C2 45.409231 55.922173 32.033594 - H11 44.523278 56.703713 30.313559 - H12 43.969464 55.144026 30.739069 - H21 46.031088 56.701514 32.267957 - H22 45.477274 55.141826 32.693467 - C1 76.641808 15.453264 32.115717 - C2 76.056652 16.076640 31.085224 - H11 76.202758 15.347819 33.035021 - H12 77.574431 15.032897 32.065623 - H21 75.124029 16.497007 31.135317 - H22 76.495702 16.182086 30.165920 - C1 44.854407 48.087508 67.454874 - C2 45.138988 48.124530 68.762759 - H11 44.661593 47.221478 66.943191 - H12 44.807178 48.922309 66.863368 - H21 45.186217 47.289728 69.354265 - H22 45.331802 48.990560 69.274442 - C1 77.250316 67.186794 67.413320 - C2 78.586798 67.119350 67.460103 - H11 76.723174 68.052908 67.558137 - H12 76.650149 66.377570 67.229042 - H21 79.186965 67.928575 67.644381 - H22 79.113941 66.253237 67.315286 - C1 11.305480 57.840073 6.683451 - C2 10.293221 58.704251 6.829908 - H11 11.180559 56.870543 6.377820 - H12 12.284232 58.080677 6.865546 - H21 9.314469 58.463647 6.647813 - H22 10.418142 59.673782 7.135538 - C1 53.147911 33.946128 20.473520 - C2 53.781973 32.776552 20.625103 - H11 53.633074 34.840080 20.353229 - H12 52.127922 34.038703 20.465954 - H21 54.801961 32.683977 20.632669 - H22 53.296810 31.882600 20.745395 - C1 41.221917 18.463562 42.126773 - C2 40.023606 17.866511 42.104390 - H11 41.603800 18.932602 42.953315 - H12 41.850799 18.498129 41.319112 - H21 39.394724 17.831944 42.912051 - H22 39.641724 17.397470 41.277848 - C1 15.049006 19.804583 4.553996 - C2 13.916935 19.104330 4.409144 - H11 15.977696 19.426063 4.346003 - H12 15.075206 20.773759 4.884169 - H21 13.890734 18.135153 4.078971 - H22 12.988244 19.482849 4.617137 - C1 2.678233 4.847308 75.450133 - C2 3.163721 6.093888 75.507243 - H11 3.264051 4.019010 75.309618 - H12 1.682911 4.624127 75.542477 - H21 4.159044 6.317068 75.414899 - H22 2.577904 6.922185 75.647758 - C1 26.082691 13.207121 9.320124 - C2 25.664876 13.454230 10.568038 - H11 26.981834 12.767721 9.102240 - H12 25.535971 13.438087 8.485405 - H21 26.211595 13.223264 11.402757 - H22 24.765733 13.893630 10.785922 - C1 69.058305 37.559153 48.629076 - C2 69.529485 37.427825 49.875536 - H11 68.516570 38.368666 48.312508 - H12 69.202605 36.860414 47.894267 - H21 69.385186 38.126564 50.610346 - H22 70.071221 36.618312 50.192104 - C1 39.441732 20.516334 74.913757 - C2 38.578963 21.516963 75.131225 - H11 39.296475 19.788890 74.207549 - H12 40.314727 20.399758 75.436532 - H21 37.705968 21.633540 74.608450 - H22 38.724220 22.244408 75.837432 - C1 14.076256 21.943959 52.317428 - C2 14.311861 23.241027 52.082849 - H11 14.817891 21.246362 52.428510 - H12 13.135891 21.547492 52.404210 - H21 15.252226 23.637494 51.996067 - H22 13.570226 23.938624 51.971766 - C1 25.152465 75.379446 8.076092 - C2 25.496207 76.657215 7.870986 - H11 24.390470 75.092381 8.697350 - H12 25.624516 74.588725 7.627839 - H21 25.024156 77.447937 8.319239 - H22 26.258202 76.944280 7.249727 - C1 69.096057 47.203382 63.043033 - C2 68.550228 48.418846 63.175845 - H11 70.016536 47.040358 62.624531 - H12 68.635979 46.341173 63.349511 - H21 69.010305 49.281054 62.869368 - H22 67.629748 48.581869 63.594348 - C1 19.846404 11.112015 38.962290 - C2 18.941512 11.923967 39.523383 - H11 20.721381 11.443653 38.545834 - H12 19.734696 10.095503 38.905470 - H21 19.053220 12.940478 39.580203 - H22 18.066535 11.592328 39.939840 - C1 71.779430 50.619109 27.112542 - C2 71.313631 51.227762 28.210492 - H11 72.761461 50.650069 26.823302 - H12 71.190295 50.074756 26.475671 - H21 71.902766 51.772114 28.847363 - H22 70.331600 51.196802 28.499732 - C1 51.234197 44.175339 4.418909 - C2 50.654836 42.968168 4.417656 - H11 50.781523 45.019356 4.055969 - H12 52.175556 44.349559 4.782906 - H21 49.713477 42.793948 4.053659 - H22 51.107510 42.124151 4.780596 - C1 59.425535 59.209178 72.774669 - C2 60.386701 60.058229 73.159626 - H11 59.567298 58.475855 72.073852 - H12 58.473038 59.226333 73.150779 - H21 61.339199 60.041074 72.783516 - H22 60.244939 60.791552 73.860443 - C1 21.201455 45.984120 3.833683 - C2 21.768610 45.217292 4.773486 - H11 21.247409 47.007295 3.836215 - H12 20.677112 45.607759 3.038434 - H21 22.292954 45.593653 5.568734 - H22 21.722656 44.194117 4.770953 - C1 71.347161 16.172929 71.608677 - C2 70.757106 17.338752 71.901272 - H11 71.919149 16.023745 70.772270 - H12 71.272880 15.338753 72.198284 - H21 70.831387 18.172929 71.311666 - H22 70.185118 17.487937 72.737680 - C1 66.803701 25.059812 16.771155 - C2 67.659235 24.091586 16.419700 - H11 66.706821 25.407214 17.729764 - H12 66.178946 25.529099 16.108997 - H21 68.283991 23.622299 17.081859 - H22 67.756116 23.744184 15.461092 - C1 52.410731 53.828681 18.549761 - C2 51.250894 54.412421 18.876788 - H11 53.160320 54.307276 18.041758 - H12 52.639454 52.857707 18.781921 - H21 51.022171 55.383396 18.644628 - H22 50.501305 53.933826 19.384791 - C1 20.415926 1.753005 35.659257 - C2 20.326729 3.077324 35.482784 - H11 21.077990 1.312645 36.304825 - H12 19.829098 1.076313 35.162543 - H21 20.913557 3.754016 35.979498 - H22 19.664665 3.517684 34.837216 - C1 53.466980 6.897163 51.324757 - C2 52.371105 7.416610 51.892342 - H11 53.756575 7.102235 50.363985 - H12 54.101745 6.253942 51.806777 - H21 51.736339 8.059832 51.410322 - H22 52.081510 7.211538 52.853115 - C1 52.841150 53.083877 77.962746 - C2 52.396161 53.647787 76.832742 - H11 52.254272 52.513038 78.578149 - H12 53.803373 53.179062 78.300491 - H21 51.433939 53.552602 76.494997 - H22 52.983039 54.218626 76.217339 - C1 53.316800 11.023429 26.366364 - C2 52.172753 10.342906 26.511160 - H11 54.063307 11.028793 27.067579 - H12 53.535287 11.592080 25.543015 - H21 51.954267 9.774255 27.334509 - H22 51.426246 10.337543 25.809945 - C1 24.813871 46.517123 14.878580 - C2 24.997766 47.641938 14.175804 - H11 24.085025 45.830180 14.664345 - H12 25.387603 46.255295 15.685600 - H21 24.424034 47.903766 13.368784 - H22 25.726612 48.328881 14.390039 - C1 25.839647 21.006956 34.980616 - C2 24.624435 21.405017 34.583465 - H11 26.368429 21.466850 35.727537 - H12 26.335886 20.211302 34.568687 - H21 24.128197 22.200671 34.995394 - H22 24.095654 20.945123 33.836544 - C1 44.810867 65.135598 60.654525 - C2 44.261505 64.081764 60.037633 - H11 44.412086 66.078511 60.624628 - H12 45.673029 65.081585 61.204763 - H21 43.399342 64.135777 59.487395 - H22 44.660285 63.138851 60.067530 - C1 48.627419 75.441731 61.676719 - C2 48.647333 75.619302 63.003743 - H11 49.007758 74.611910 61.212238 - H12 48.230282 76.121772 61.021868 - H21 49.044469 74.939261 63.658594 - H22 48.266994 76.449124 63.468224 - C1 53.932548 78.328880 37.026815 - C2 53.235252 77.329467 36.471953 - H11 54.423910 79.044460 36.483204 - H12 54.029350 78.456296 38.038446 - H21 53.138450 77.202051 35.460321 - H22 52.743891 76.613886 37.015563 - C1 58.483209 10.012566 66.994304 - C2 59.355862 11.028138 66.997204 - H11 58.680633 9.097179 67.409147 - H12 57.549709 10.071326 66.577016 - H21 60.289362 10.969378 67.414493 - H22 59.158438 11.943525 66.582362 - C1 33.875292 68.840401 51.909276 - C2 33.571639 70.057678 52.377201 - H11 34.273984 68.675759 50.980329 - H12 33.732728 67.978282 52.443532 - H21 33.714203 70.919797 51.842944 - H22 33.172947 70.222320 53.306147 - C1 35.108078 26.707981 41.706346 - C2 35.964916 26.280446 40.770416 - H11 34.218389 26.243996 41.911710 - H12 35.275033 27.532588 42.290430 - H21 35.797961 25.455839 40.186333 - H22 36.854605 26.744431 40.565052 - C1 65.955878 38.200065 40.425569 - C2 67.181014 38.442218 39.942533 - H11 65.583870 37.257572 40.574975 - H12 65.294495 38.938303 40.683600 - H21 67.842397 37.703979 39.684501 - H22 67.553022 39.384710 39.793127 - C1 7.721215 48.346957 24.341598 - C2 7.721048 48.031431 25.642891 - H11 7.641112 47.653298 23.592315 - H12 7.801458 49.306759 23.993252 - H21 7.640804 47.071629 25.991237 - H22 7.801150 48.725089 26.392174 - C1 76.825636 3.768012 10.154756 - C2 76.733963 3.341863 8.888693 - H11 76.256197 4.528571 10.537238 - H12 77.472401 3.366906 10.840185 - H21 76.087198 3.742969 8.203264 - H22 77.303402 2.581305 8.506210 - C1 58.831395 16.139398 79.840870 - C2 57.907427 17.105981 79.770721 - H11 58.610329 15.141267 79.778680 - H12 59.831820 16.322225 79.962231 - H21 56.907002 16.923153 79.649360 - H22 58.128492 18.104112 79.832912 - C1 27.471354 47.411917 18.151065 - C2 27.863368 46.262322 17.587437 - H11 27.961151 47.852101 18.935502 - H12 26.650897 47.941407 17.842043 - H21 28.683825 45.732832 17.896460 - H22 27.373572 45.822139 16.803000 - C1 14.201206 62.196489 44.530265 - C2 14.549076 60.979885 44.092335 - H11 14.185664 63.028504 43.933177 - H12 13.923321 62.390668 45.496742 - H21 14.826961 60.785706 43.125858 - H22 14.564618 60.147871 44.689423 - C1 79.109277 4.991419 72.008102 - C2 79.139615 3.659639 72.143607 - H11 78.250282 5.545850 72.069239 - H12 79.942682 5.560332 71.832667 - H21 78.306209 3.090725 72.319041 - H22 79.998609 3.105207 72.082470 - C1 36.393031 47.637687 38.121197 - C2 37.584979 47.028587 38.086881 - H11 36.279150 48.655440 38.135819 - H12 35.501515 47.133705 38.135521 - H21 38.476495 47.532569 38.072558 - H22 37.698860 46.010834 38.072260 - C1 64.430459 76.444430 19.432523 - C2 64.107608 75.145255 19.461362 - H11 63.954000 77.131736 18.841253 - H12 65.179241 76.852967 19.999469 - H21 63.358826 74.736718 18.894416 - H22 64.584068 74.457949 20.052632 - C1 8.109829 46.728631 74.226061 - C2 9.024451 47.010616 75.162475 - H11 7.101106 46.825722 74.374570 - H12 8.347077 46.393689 73.287695 - H21 8.787203 47.345559 76.100841 - H22 10.033174 46.913525 75.013966 - C1 5.251457 10.167018 66.745110 - C2 6.205026 11.086091 66.942418 - H11 5.323201 9.419322 66.048829 - H12 4.375385 10.139485 67.274963 - H21 7.081098 11.113624 66.412565 - H22 6.133282 11.833787 67.638699 - C1 58.961013 67.925860 73.391649 - C2 59.196756 69.028448 72.669399 - H11 58.030632 67.657701 73.725544 - H12 59.692546 67.263995 73.666964 - H21 58.465223 69.690312 72.394083 - H22 60.127137 69.296606 72.335503 - C1 11.660268 21.579002 26.850165 - C2 10.694178 21.051223 26.087905 - H11 11.483867 22.034264 27.750512 - H12 12.651557 21.568917 26.592778 - H21 9.702889 21.061308 26.345292 - H22 10.870579 20.595962 25.187559 - C1 3.261537 55.688316 48.796004 - C2 2.211535 55.623598 49.624393 - H11 4.167049 56.086157 49.062039 - H12 3.241692 55.345064 47.831230 - H21 2.231380 55.966849 50.589166 - H22 1.306023 55.225756 49.358358 - C1 69.187746 26.714662 49.633963 - C2 69.333086 26.442007 50.936827 - H11 68.450437 26.308146 49.050760 - H12 69.802462 27.351158 49.118210 - H21 68.718371 25.805510 51.452580 - H22 70.070395 26.848523 51.520030 - C1 10.087520 4.018829 78.972791 - C2 11.195941 4.298369 78.275524 - H11 9.200071 3.749144 78.538383 - H12 10.040025 4.052723 79.995336 - H21 11.243435 4.264475 77.252978 - H22 12.083389 4.568054 78.709931 - C1 22.539728 37.151571 69.830063 - C2 23.710179 37.738425 70.110362 - H11 22.365074 36.150465 69.957681 - H12 21.727117 37.657671 69.466016 - H21 24.522790 37.232325 70.474408 - H22 23.884833 38.739531 69.982744 - C1 42.005348 60.890595 72.797418 - C2 41.797473 62.152430 73.194256 - H11 42.900196 60.404443 72.906540 - H12 41.285841 60.312400 72.353567 - H21 42.516980 62.730625 73.638107 - H22 40.902625 62.638582 73.085134 - C1 78.255581 9.087120 16.579173 - C2 79.197062 9.734911 15.881390 - H11 78.264068 9.007361 17.600236 - H12 77.452962 8.620472 16.146682 - H21 79.999680 10.201558 16.313880 - H22 79.188575 9.814669 14.860327 - C1 47.450949 76.950313 40.335860 - C2 48.117631 77.334701 41.431626 - H11 46.548604 76.466620 40.364467 - H12 47.790954 77.109778 39.382985 - H21 47.777625 77.175235 42.384501 - H22 49.019976 77.818393 41.403019 - C1 11.357775 28.078884 48.483967 - C2 11.717495 29.367752 48.435566 - H11 11.882453 27.328528 48.024965 - H12 10.529676 27.742092 48.983794 - H21 12.545593 29.704544 47.935738 - H22 11.192817 30.118108 48.894567 - C1 53.030726 48.579392 11.573937 - C2 54.321857 48.918752 11.677541 - H11 52.691995 47.616005 11.652366 - H12 52.280399 49.256531 11.408118 - H21 55.072184 48.241613 11.843359 - H22 54.660588 49.882139 11.599112 - C1 23.383953 44.561409 75.508922 - C2 22.209052 44.082628 75.937054 - H11 23.472534 45.386234 74.908237 - H12 24.286391 44.140432 75.748480 - H21 21.306615 44.503605 75.697495 - H22 22.120472 43.257803 76.537738 - C1 11.494731 71.770393 79.094278 - C2 10.562116 72.034492 78.170480 - H11 11.286638 71.338800 79.999501 - H12 12.489475 71.979220 78.968271 - H21 9.567372 71.825665 78.296488 - H22 10.770210 72.466085 77.265257 - C1 74.147987 2.907457 78.347808 - C2 74.305758 4.118684 78.896404 - H11 73.940067 2.759511 77.355899 - H12 74.222828 2.033742 78.876983 - H21 74.230917 4.992398 78.367228 - H22 74.513678 4.266629 79.888313 - C1 47.871855 66.645273 63.122520 - C2 47.720366 65.318617 63.222298 - H11 48.520413 67.091933 62.467637 - H12 47.351076 67.317636 63.693241 - H21 48.241144 64.646255 62.651577 - H22 47.071808 64.871958 63.877181 - C1 12.044269 33.199876 42.599682 - C2 13.008082 34.120721 42.473066 - H11 11.195487 33.188308 42.026587 - H12 12.080085 32.434720 43.279577 - H21 12.972266 34.885877 41.793171 - H22 13.856864 34.132289 43.046162 - C1 69.830719 47.066950 27.107242 - C2 70.952631 46.336037 27.107285 - H11 68.891139 46.659282 27.107490 - H12 69.823976 48.091137 27.106958 - H21 70.959374 45.311850 27.107569 - H22 71.892211 46.743705 27.107037 - C1 22.790805 43.730680 13.517183 - C2 23.992074 43.240318 13.847967 - H11 21.967944 43.144181 13.350079 - H12 22.600405 44.730794 13.405274 - H21 24.182473 42.240204 13.959876 - H22 24.814934 43.826817 14.015071 - C1 61.371741 47.680421 30.864597 - C2 62.180223 48.228252 29.948541 - H11 61.476963 47.829978 31.872349 - H12 60.584572 47.068774 30.629530 - H21 62.967391 48.839900 30.183608 - H22 62.075001 48.078696 28.940788 - C1 33.540035 53.582911 47.957578 - C2 32.270494 53.245526 48.217114 - H11 34.246515 52.916127 47.633096 - H12 33.904400 54.534277 48.063143 - H21 31.906128 52.294159 48.111548 - H22 31.564014 53.912310 48.541595 - C1 68.532152 34.613663 68.401509 - C2 69.099583 34.632586 69.614186 - H11 67.521730 34.684311 68.249656 - H12 69.063952 34.527053 67.530480 - H21 68.567783 34.719196 70.485215 - H22 70.110005 34.561938 69.766039 - C1 23.144721 39.554212 3.423010 - C2 22.821392 38.778959 4.465777 - H11 22.759811 40.491824 3.275592 - H12 23.802356 39.270519 2.690864 - H21 22.163756 39.062652 5.197923 - H22 23.206302 37.841347 4.613195 - C1 11.592322 47.034534 71.965141 - C2 12.832327 46.529416 71.952276 - H11 11.391758 48.038192 72.003191 - H12 10.746954 46.456938 71.937943 - H21 13.677695 47.107012 71.979474 - H22 13.032891 45.525757 71.914226 - C1 52.731816 1.022167 11.605000 - C2 53.252794 1.061985 12.837850 - H11 51.840964 1.460757 11.353952 - H12 53.183228 0.549992 10.816152 - H21 52.801382 1.534160 13.626698 - H22 54.143646 0.623395 13.088899 - C1 15.643401 26.821603 26.562802 - C2 16.359566 27.936401 26.369792 - H11 15.073866 26.382891 25.833306 - H12 15.608858 26.319992 27.455101 - H21 16.394110 28.438012 25.477493 - H22 16.929102 28.375113 27.099289 - C1 42.917042 3.158656 23.177056 - C2 43.947281 3.837983 23.696715 - H11 42.067441 2.932220 23.702324 - H12 42.897648 2.812086 22.213460 - H21 43.966675 4.184552 24.660310 - H22 44.796883 4.064419 23.171446 - C1 29.424863 51.836411 31.788657 - C2 28.551841 52.725742 31.298919 - H11 30.439554 51.921499 31.678355 - H12 29.146558 51.001179 32.312049 - H21 28.830146 53.560973 30.775527 - H22 27.537150 52.640653 31.409221 - C1 29.834883 30.213871 56.138453 - C2 30.700559 31.140381 56.568691 - H11 29.196585 29.706364 56.758142 - H12 29.742992 29.939876 55.155861 - H21 30.792451 31.414376 57.551283 - H22 31.338858 31.647888 55.949002 - C1 60.051494 20.328770 46.041796 - C2 60.504344 21.517375 45.623388 - H11 59.059286 20.075060 46.054400 - H12 60.661726 19.579902 46.382115 - H21 59.894111 22.266243 45.283069 - H22 61.496552 21.771085 45.610785 - C1 65.042980 14.696591 39.215770 - C2 65.849966 13.632567 39.118059 - H11 65.377890 15.664024 39.185591 - H12 64.027384 14.626651 39.328368 - H21 66.865561 13.702506 39.005461 - H22 65.515056 12.665133 39.148238 - C1 72.898743 32.370725 51.117790 - C2 72.011497 33.373373 51.138118 - H11 73.426184 32.066601 51.941390 - H12 73.119684 31.829124 50.277042 - H21 71.790555 33.914974 51.978866 - H22 71.484056 33.677497 50.314517 - C1 38.676420 23.616101 79.010592 - C2 37.686690 24.447420 78.660927 - H11 38.531184 22.765962 79.563018 - H12 39.656483 23.765031 78.753106 - H21 36.706627 24.298490 78.918414 - H22 37.831926 25.297559 78.108501 - C1 76.784621 22.546437 76.362521 - C2 75.914633 22.871868 77.326957 - H11 77.686887 22.097024 76.544034 - H12 76.616181 22.721351 75.367515 - H21 76.083073 22.696954 78.321963 - H22 75.012366 23.321281 77.145444 - C1 59.612771 60.400201 18.178779 - C2 59.511633 60.111336 16.875227 - H11 60.461266 60.779726 18.608919 - H12 58.849584 60.264332 18.848174 - H21 60.274820 60.247206 16.205832 - H22 58.663138 59.731812 16.445087 - C1 19.556225 57.911765 4.926784 - C2 20.855809 57.596178 4.860399 - H11 19.202451 58.753250 5.391274 - H12 18.813812 57.336474 4.518291 - H21 21.598223 58.171468 5.268893 - H22 21.209583 56.754692 4.395910 - C1 53.206730 4.029818 79.993532 - C2 54.092264 3.025455 79.991000 - H11 52.192360 3.888317 79.999417 - H12 53.474161 5.018489 79.989782 - H21 53.824833 2.036784 79.994750 - H22 55.106634 3.166956 79.985114 - C1 12.453773 43.929505 14.298851 - C2 13.135418 45.081991 14.306446 - H11 11.915271 43.586618 15.099755 - H12 12.417315 43.300280 13.491540 - H21 13.171877 45.711215 15.113757 - H22 13.673921 45.424877 13.505542 - C1 20.258766 72.296914 30.444186 - C2 19.211790 73.073018 30.136898 - H11 20.218121 71.273618 30.458915 - H12 21.182525 72.665574 30.688651 - H21 18.288031 72.704358 29.892433 - H22 19.252435 74.096314 30.122168 - C1 29.383459 51.368607 47.354336 - C2 30.189911 50.339151 47.066628 - H11 28.362245 51.295395 47.382021 - H12 29.724438 52.310157 47.569330 - H21 29.848932 49.397602 46.851634 - H22 31.211124 50.412364 47.038943 - C1 28.680907 44.261107 50.844921 - C2 27.546943 44.667783 50.260402 - H11 28.704909 43.658179 51.672511 - H12 29.613392 44.521008 50.510366 - H21 26.614458 44.407883 50.594957 - H22 27.522941 45.270711 49.432812 - C1 30.133058 63.480995 49.320146 - C2 29.465459 62.354297 49.041246 - H11 31.154272 63.554002 49.291956 - H12 29.674957 64.358347 49.583586 - H21 29.923560 61.476945 48.777806 - H22 28.444244 62.281291 49.069437 - C1 61.104479 33.813781 51.044596 - C2 62.357499 33.859071 50.574689 - H11 60.334580 34.364799 50.653907 - H12 60.817468 33.224561 51.831646 - H21 62.644510 34.448291 49.787639 - H22 63.127398 33.308052 50.965378 - C1 38.481931 76.787305 5.237906 - C2 39.428184 77.363813 5.989681 - H11 37.493792 77.054705 5.270781 - H12 38.671916 76.033625 4.570916 - H21 39.238199 78.117493 6.656672 - H22 40.416323 77.096412 5.956806 - C1 62.765482 53.509820 24.807514 - C2 61.505618 53.554834 25.258776 - H11 63.116679 54.106581 24.052834 - H12 63.476968 52.875090 25.181557 - H21 60.794131 54.189564 24.884733 - H22 61.154421 52.958073 26.013455 - C1 46.370674 34.639224 54.008500 - C2 47.280773 35.618071 53.927881 - H11 46.613550 33.646822 54.080282 - H12 45.360138 34.805978 54.004720 - H21 48.291309 35.451317 53.931660 - H22 47.037898 36.610473 53.856099 - C1 50.743964 65.674373 49.786373 - C2 51.230684 65.079621 50.882865 - H11 51.334651 66.081774 49.055540 - H12 49.742733 65.768639 49.592324 - H21 52.231914 64.985355 51.076914 - H22 50.639996 64.672219 51.613698 - C1 65.576669 4.454953 52.132320 - C2 66.046233 3.409814 52.825223 - H11 65.658967 5.425454 52.449115 - H12 65.098299 4.366018 51.231067 - H21 66.524603 3.498749 53.726475 - H22 65.963935 2.439313 52.508427 - C1 42.517313 16.284902 7.835677 - C2 43.329486 15.694647 6.949734 - H11 42.486799 16.034175 8.828253 - H12 41.862766 17.033503 7.590384 - H21 43.984033 14.946045 7.195026 - H22 43.360000 15.945373 5.957157 - C1 61.644317 63.928104 68.812135 - C2 62.282971 64.805212 69.596816 - H11 62.099259 63.415847 68.050804 - H12 60.650677 63.700529 68.911594 - H21 63.276612 65.032787 69.497356 - H22 61.828030 65.317469 70.358146 - C1 28.402321 10.742188 54.308206 - C2 29.457171 10.046305 54.750879 - H11 27.478909 10.328356 54.149911 - H12 28.435977 11.742990 54.093111 - H21 29.423515 9.045503 54.965974 - H22 30.380583 10.460136 54.909174 - C1 7.931366 21.948575 8.170481 - C2 6.731636 22.534625 8.069923 - H11 8.212072 21.137151 7.612091 - H12 8.662623 22.265671 8.813690 - H21 6.000380 22.217529 7.426713 - H22 6.450930 23.346049 8.628312 - C1 54.945603 43.832113 39.564432 - C2 54.186228 44.865655 39.949218 - H11 54.987623 43.490507 38.599785 - H12 55.544110 43.301936 40.204515 - H21 53.587721 45.395831 39.309135 - H22 54.144208 45.207261 40.913865 - C1 9.201392 27.349639 41.619564 - C2 8.502956 28.484940 41.746847 - H11 10.070496 27.161304 42.127690 - H12 8.921413 26.580360 41.004076 - H21 8.782935 29.254219 42.362335 - H22 7.633852 28.673276 41.238721 - C1 9.667388 74.792017 55.236384 - C2 10.590705 74.971081 54.283313 - H11 8.845069 74.192547 55.120498 - H12 9.710899 75.240450 56.156177 - H21 10.547194 74.522648 53.363521 - H22 11.413024 75.570551 54.399200 - C1 2.973650 24.199255 6.700574 - C2 3.053531 25.521365 6.504199 - H11 3.222643 23.743392 7.583295 - H12 2.657278 23.539930 5.983495 - H21 3.369903 26.180691 7.221278 - H22 2.804538 25.977228 5.621478 - C1 23.008677 20.101769 3.036375 - C2 22.226672 19.709550 2.022692 - H11 24.010035 19.893519 3.090405 - H12 22.666934 20.640852 3.837378 - H21 22.568416 19.170468 1.221689 - H22 21.225315 19.917800 1.968662 - C1 57.160491 1.527237 28.957037 - C2 56.308111 2.559866 28.950331 - H11 58.178912 1.635566 28.947668 - H12 56.861046 0.547895 28.972061 - H21 56.607556 3.539208 28.935307 - H22 55.289690 2.451537 28.959700 - C1 1.554785 6.448617 23.851405 - C2 1.030315 7.464796 24.547990 - H11 1.023170 5.616444 23.579601 - H12 2.528785 6.423652 23.535646 - H21 0.056314 7.489761 24.863749 - H22 1.561930 8.296969 24.819795 - C1 44.927957 74.712104 12.420648 - C2 46.104144 74.101024 12.610609 - H11 44.666441 75.173833 11.544623 - H12 44.197370 74.765816 13.136442 - H21 46.834731 74.047312 11.894815 - H22 46.365660 73.639295 13.486634 - C1 77.510481 50.544758 16.966785 - C2 78.199558 50.052220 18.003848 - H11 77.669795 51.477469 16.574774 - H12 76.769937 50.027498 16.484043 - H21 78.940103 50.569480 18.486590 - H22 78.040245 49.119509 18.395859 - C1 57.704710 60.269135 30.975365 - C2 56.631345 61.069519 30.989332 - H11 57.647761 59.247314 31.015901 - H12 58.667031 60.615839 30.923048 - H21 55.669024 60.722814 31.041649 - H22 56.688294 62.091339 30.948796 - C1 14.824732 38.731175 31.630336 - C2 15.334636 37.554487 31.245206 - H11 13.826868 38.956994 31.582621 - H12 15.392497 39.497882 32.002905 - H21 14.766870 36.787781 30.872638 - H22 16.332500 37.328668 31.292922 - C1 71.791270 79.332234 32.988593 - C2 73.037821 78.907256 32.746885 - H11 71.022338 79.237053 32.318751 - H12 71.508746 79.785881 33.862315 - H21 73.320345 78.453610 31.873163 - H22 73.806753 79.002437 33.416727 - C1 61.316794 46.035221 48.274950 - C2 60.609896 47.163018 48.420862 - H11 61.281374 45.451317 47.434233 - H12 61.948476 45.667838 48.992593 - H21 59.978214 47.530401 47.703219 - H22 60.645317 47.746921 49.261579 - C1 29.952529 54.169249 37.213378 - C2 29.529903 55.439615 37.235248 - H11 29.320263 53.363535 37.221769 - H12 30.941275 53.903420 37.186541 - H21 28.541157 55.705444 37.262085 - H22 30.162168 56.245328 37.226857 - C1 66.752639 63.996761 7.493520 - C2 67.894748 63.794697 6.824432 - H11 66.414514 63.375353 8.234146 - H12 66.127406 64.788608 7.317264 - H21 68.519980 63.002850 7.000688 - H22 68.232873 64.416106 6.083806 - C1 28.760053 71.036813 56.726618 - C2 30.009857 70.871570 56.275392 - H11 27.926313 70.834937 56.167040 - H12 28.539594 71.378070 57.666802 - H21 30.230316 70.530313 55.335208 - H22 30.843597 71.073446 56.834971 - C1 33.267786 51.524917 59.153885 - C2 33.476145 50.897178 57.989646 - H11 32.522726 52.212478 59.299308 - H12 33.837098 51.366848 59.990486 - H21 32.906833 51.055248 57.153045 - H22 34.221206 50.209617 57.844223 - C1 26.712544 51.830014 24.896709 - C2 27.123966 50.579595 25.141871 - H11 27.241451 52.662747 25.172056 - H12 25.836605 52.051998 24.414569 - H21 27.999905 50.357611 25.624011 - H22 26.595059 49.746862 24.866524 - C1 38.168254 2.534351 2.948415 - C2 37.799073 1.790135 3.998543 - H11 37.582256 3.270701 2.544186 - H12 39.065651 2.425741 2.466870 - H21 36.901676 1.898745 4.480087 - H22 38.385070 1.053785 4.402771 - C1 34.457790 14.692706 28.188880 - C2 35.586005 13.973846 28.131510 - H11 34.306738 15.550522 27.650048 - H12 33.657203 14.441243 28.776102 - H21 36.386592 14.225310 27.544288 - H22 35.737057 13.116031 28.670343 - C1 11.276552 42.572648 8.077908 - C2 11.068979 43.801353 7.587889 - H11 10.696215 41.763532 7.838025 - H12 12.031974 42.345363 8.731118 - H21 10.313557 44.028638 6.934679 - H22 11.649316 44.610469 7.827772 - C1 69.795240 64.886410 42.197335 - C2 69.976054 66.212998 42.217134 - H11 69.081039 64.405477 42.751973 - H12 70.356928 64.248379 41.625997 - H21 69.414366 66.851030 42.788471 - H22 70.690255 66.693931 41.662496 - C1 35.779091 11.099334 17.241934 - C2 34.771022 11.965129 17.077264 - H11 35.756270 10.134291 16.899626 - H12 36.652209 11.334087 17.723141 - H21 33.897904 11.730377 16.596057 - H22 34.793843 12.930172 17.419573 - C1 58.570829 11.718035 73.722980 - C2 59.714673 11.210775 73.246296 - H11 57.716299 11.166837 73.845300 - H12 58.460537 12.697104 74.002739 - H21 59.824965 10.231707 72.966537 - H22 60.569204 11.761973 73.123976 - C1 43.273597 18.293554 26.391307 - C2 43.122547 17.167087 27.099246 - H11 42.925169 19.205750 26.700336 - H12 43.749433 18.331521 25.485138 - H21 42.646710 17.129119 28.005415 - H22 43.470974 16.254890 26.790217 - C1 46.940219 13.900108 27.372084 - C2 46.129161 14.772211 26.760086 - H11 47.957082 13.892964 27.249848 - H12 46.607475 13.171640 28.010536 - H21 46.461904 15.500678 26.121634 - H22 45.112297 14.779354 26.882322 - C1 71.411222 61.952127 33.820617 - C2 70.222823 61.870830 34.432187 - H11 71.769746 62.812057 33.395193 - H12 72.055103 61.160772 33.730189 - H21 69.578942 62.662186 34.522616 - H22 69.864299 61.010901 34.857612 - C1 30.677222 35.030359 8.459210 - C2 29.407742 35.048897 8.884647 - H11 31.167395 34.174928 8.181771 - H12 31.257844 35.870153 8.377798 - H21 28.827120 34.209104 8.966059 - H22 28.917569 35.904328 9.162086 - C1 13.771801 13.026861 49.354336 - C2 13.163045 13.160273 50.539469 - H11 13.295575 13.157267 48.457003 - H12 14.761506 12.783925 49.252021 - H21 12.173339 13.403209 50.641784 - H22 13.639271 13.029867 51.436802 - C1 62.009981 67.762069 49.473317 - C2 60.833556 67.994698 48.877641 - H11 62.914125 67.920673 49.019034 - H12 62.098141 67.407243 50.430046 - H21 60.745397 68.349524 47.920912 - H22 59.929413 67.836094 49.331924 - C1 21.652677 76.279406 12.982049 - C2 20.472409 75.973809 12.428426 - H11 22.012923 77.235610 13.052053 - H12 22.287976 75.580970 13.379020 - H21 19.837109 76.672244 12.031455 - H22 20.112163 75.017605 12.358422 - C1 67.927627 6.915116 10.527020 - C2 68.511242 7.783038 11.363097 - H11 68.203766 5.931798 10.450624 - H12 67.159213 7.166350 9.898191 - H21 69.279656 7.531803 11.991926 - H22 68.235102 8.766356 11.439493 - C1 30.058369 30.909205 74.994180 - C2 29.012246 30.174477 74.595780 - H11 30.919929 30.505868 75.373703 - H12 30.079204 31.932279 74.950703 - H21 28.991411 29.151403 74.639257 - H22 28.150687 30.577814 74.216256 - C1 47.071336 11.865702 66.078697 - C2 47.344844 12.418012 64.889972 - H11 46.274303 12.141753 66.659678 - H12 47.637667 11.123784 66.500396 - H21 46.778513 13.159930 64.468273 - H22 48.141877 12.141961 64.308991 - C1 15.616334 65.541434 5.149071 - C2 14.329831 65.897944 5.045473 - H11 16.305071 65.689798 4.405678 - H12 16.012749 65.092358 5.979847 - H21 13.933416 66.347021 4.214697 - H22 13.641093 65.749581 5.788866 - C1 48.731274 16.555834 22.928333 - C2 48.378839 17.822284 22.673742 - H11 49.698025 16.261182 23.094389 - H12 48.061797 15.782249 22.977023 - H21 49.048315 18.595869 22.625052 - H22 47.412087 18.116936 22.507686 - C1 15.069168 27.314220 60.299811 - C2 16.163113 27.085928 59.562187 - H11 15.097566 27.705072 61.246084 - H12 14.118038 27.115931 59.975717 - H21 17.114243 27.284217 59.886281 - H22 16.134715 26.695076 58.615914 - C1 32.500444 21.484586 54.386646 - C2 32.833424 20.463831 55.186711 - H11 33.187118 22.100711 53.941818 - H12 31.532905 21.729458 54.156626 - H21 33.800963 20.218959 55.416731 - H22 32.146750 19.847705 55.631539 - C1 20.227192 65.382021 15.541065 - C2 20.034240 65.556773 14.227614 - H11 20.226865 64.463720 15.994637 - H12 20.390271 66.152920 16.195376 - H21 19.871161 64.785874 13.573303 - H22 20.034567 66.475074 13.774042 - C1 64.703514 66.589798 46.655934 - C2 64.735944 67.927232 46.711983 - H11 65.512790 66.015411 46.402647 - H12 63.866883 66.036073 46.861945 - H21 65.572575 68.480957 46.505972 - H22 63.926667 68.501619 46.965270 - C1 76.386405 24.861667 24.417274 - C2 77.647855 24.437249 24.564016 - H11 75.632241 24.274512 24.049185 - H12 76.076548 25.806814 24.661586 - H21 77.957713 23.492102 24.319704 - H22 78.402020 25.024404 24.932105 - C1 22.198618 1.256760 23.691821 - C2 23.267110 1.789410 23.085578 - H11 21.289402 1.140838 23.234775 - H12 22.206572 0.923398 24.660227 - H21 23.259156 2.122772 22.117172 - H22 24.176327 1.905332 23.542623 - C1 37.731673 31.109490 32.400501 - C2 36.478841 31.505953 32.657698 - H11 37.981546 30.144514 32.165156 - H12 38.538552 31.740055 32.418903 - H21 35.671962 30.875388 32.639295 - H22 36.228967 32.470929 32.893043 - C1 21.126006 70.058441 26.076803 - C2 21.066063 69.320449 24.961143 - H11 20.297908 70.407075 26.568445 - H12 22.004665 70.332295 26.526209 - H21 20.187405 69.046595 24.511736 - H22 21.894161 68.971815 24.469501 - C1 34.801318 53.762978 74.857811 - C2 34.134859 54.422195 73.901680 - H11 34.469808 52.889501 75.277506 - H12 35.694981 54.080410 75.244603 - H21 33.241197 54.104763 73.514888 - H22 34.466370 55.295672 73.481986 - C1 55.419474 36.869759 69.103591 - C2 56.407416 37.529129 68.485429 - H11 54.771728 36.240507 68.620403 - H12 55.233901 36.942839 70.108194 - H21 56.592989 37.456049 67.480827 - H22 57.055162 38.158381 68.968618 - C1 36.146191 47.122369 60.848737 - C2 35.811251 45.978681 60.238234 - H11 37.111858 47.450405 60.942995 - H12 35.463044 47.759023 61.269432 - H21 36.494398 45.342026 59.817539 - H22 34.845584 45.650645 60.143976 - C1 60.540233 74.096131 62.084741 - C2 60.063213 75.347156 62.102328 - H11 59.943291 73.264564 62.050679 - H12 61.539538 73.872470 62.103968 - H21 59.063908 75.570817 62.083101 - H22 60.660156 76.178723 62.136390 - C1 10.690145 70.167127 69.134092 - C2 11.848045 69.921900 69.760233 - H11 10.504060 69.895595 68.164223 - H12 9.899552 70.645505 69.575818 - H21 12.638638 69.443522 69.318508 - H22 12.034130 70.193432 70.730102 - C1 9.428849 73.371865 40.258859 - C2 8.227287 73.812337 40.652754 - H11 10.052132 73.904427 39.644937 - H12 9.819073 72.467770 40.540533 - H21 7.837063 74.716432 40.371079 - H22 7.604004 73.279775 41.266675 - C1 77.490440 34.522666 3.483180 - C2 78.472932 35.282610 2.983063 - H11 76.562709 34.445974 3.056052 - H12 77.589448 33.958353 4.332150 - H21 78.373923 35.846924 2.134093 - H22 79.400662 35.359302 3.410190 - C1 19.833575 23.411118 49.525260 - C2 18.518471 23.641944 49.625971 - H11 20.237299 22.474000 49.436835 - H12 20.539128 24.153537 49.528737 - H21 17.812918 22.899525 49.622495 - H22 18.114747 24.579063 49.714397 - C1 59.690153 47.075360 8.259546 - C2 59.123720 47.938157 9.112572 - H11 60.699117 47.029363 8.089610 - H12 59.158969 46.393594 7.709961 - H21 59.654903 48.619923 9.662157 - H22 58.114755 47.984153 9.282508 - C1 52.952445 75.818161 12.673797 - C2 52.914769 76.822448 11.788975 - H11 53.700508 75.119205 12.703204 - H12 52.236160 75.670011 13.390730 - H21 53.631054 76.970598 11.072043 - H22 52.166705 77.521404 11.759569 - C1 30.931247 66.950108 54.368791 - C2 32.025247 66.863916 55.136031 - H11 30.363548 66.140529 54.101765 - H12 30.576167 67.832390 53.988659 - H21 32.380327 65.981634 55.516163 - H22 32.592946 67.673495 55.403057 - C1 3.732580 73.231362 8.976762 - C2 2.800539 74.189460 8.897585 - H11 4.699491 73.406611 9.265506 - H12 3.551835 72.247965 8.754804 - H21 2.981284 75.172857 9.119543 - H22 1.833628 74.014211 8.608841 - C1 49.544278 32.668792 72.288662 - C2 50.867328 32.689538 72.493675 - H11 49.093986 32.102680 71.563569 - H12 48.878590 33.217404 72.840828 - H21 51.533016 32.140926 71.941508 - H22 51.317619 33.255650 73.218767 - C1 22.671764 31.301017 59.036078 - C2 21.859476 30.370295 58.519488 - H11 22.386267 32.270538 59.201986 - H12 23.642417 31.116553 59.305908 - H21 20.888823 30.554760 58.249657 - H22 22.144973 29.400774 58.353579 - C1 67.042687 45.887331 30.166968 - C2 66.144438 44.916599 29.957807 - H11 67.572728 45.988245 31.037529 - H12 67.270311 46.605221 29.472832 - H21 65.916813 44.198709 30.651944 - H22 65.614397 44.815685 29.087246 - C1 60.735125 23.963765 70.162101 - C2 60.680633 23.466024 71.403957 - H11 60.366344 24.884314 69.905987 - H12 61.149870 23.463056 69.370721 - H21 60.265889 23.966732 72.195336 - H22 61.049414 22.545475 71.660071 - C1 68.727749 29.034965 57.504102 - C2 67.602547 28.652698 56.887082 - H11 69.544838 28.427606 57.615830 - H12 68.859756 29.964763 57.912824 - H21 67.470539 27.722901 56.478359 - H22 66.785457 29.260057 56.775354 - C1 30.881532 35.633947 62.215228 - C2 31.392056 34.431406 61.921660 - H11 30.119260 36.068170 61.686650 - H12 31.213182 36.214055 62.991428 - H21 31.060406 33.851298 61.145460 - H22 32.154328 33.997182 62.450238 - C1 23.182664 63.698474 7.601970 - C2 23.413913 62.502318 7.046401 - H11 23.923845 64.366219 7.833853 - H12 22.246425 64.039674 7.838705 - H21 24.350152 62.161118 6.809666 - H22 22.672731 61.834573 6.814517 - C1 31.141520 5.994576 13.267531 - C2 31.308669 4.679239 13.454275 - H11 30.223532 6.440656 13.182011 - H12 31.918521 6.657969 13.195536 - H21 30.531669 4.015846 13.526270 - H22 32.226657 4.233159 13.539795 - C1 24.600219 31.681400 37.911613 - C2 25.280935 31.401477 39.030178 - H11 24.996338 31.589619 36.971576 - H12 23.629921 32.009293 37.908150 - H21 26.251233 31.073584 39.033641 - H22 24.884816 31.493258 39.970215 - C1 19.773143 36.412800 76.029478 - C2 19.487679 37.016326 77.190162 - H11 19.785563 36.899125 75.128180 - H12 20.001511 35.417405 75.951749 - H21 19.259311 38.011721 77.267890 - H22 19.475259 36.530000 78.091459 - C1 53.245462 18.158635 44.178883 - C2 53.540466 17.747727 42.939105 - H11 53.093729 19.140627 44.427222 - H12 53.148363 17.523240 44.976284 - H21 53.637565 18.383121 42.141704 - H22 53.692199 16.765735 42.690766 - C1 2.499825 76.815059 5.731523 - C2 1.279040 76.280514 5.861395 - H11 3.358310 76.258252 5.687099 - H12 2.671060 77.822750 5.666401 - H21 1.107805 75.272823 5.926517 - H22 0.420555 76.837320 5.905820 - C1 13.115660 11.948933 65.389069 - C2 13.984644 11.279373 64.621294 - H11 13.379849 12.741049 65.982162 - H12 12.118492 11.721584 65.443586 - H21 14.981812 11.506722 64.566777 - H22 13.720455 10.487257 64.028200 - C1 14.854171 1.394216 59.434308 - C2 14.648523 2.622320 58.941974 - H11 14.310351 0.996747 60.205854 - H12 15.571451 0.755791 59.078041 - H21 13.931243 3.260744 59.298241 - H22 15.192343 3.019789 58.170429 - C1 68.029582 33.712105 17.204217 - C2 66.959941 33.060944 17.678325 - H11 68.005806 34.304130 16.368786 - H12 68.955590 33.669329 17.639743 - H21 66.033933 33.103721 17.242799 - H22 66.983717 32.468920 18.513756 - C1 23.012624 8.859320 31.382434 - C2 23.671753 7.695446 31.444609 - H11 22.737063 9.305968 30.502902 - H12 22.732215 9.394390 32.209522 - H21 23.952162 7.160376 30.617521 - H22 23.947313 7.248799 32.324141 - C1 30.517173 46.947424 47.356341 - C2 29.713705 47.357040 48.346075 - H11 31.532754 47.079969 47.361937 - H12 30.179311 46.469372 46.515913 - H21 30.051568 47.835093 49.186503 - H22 28.698124 47.224495 48.340479 - C1 26.268930 39.797994 13.406748 - C2 26.219248 38.772259 14.266003 - H11 25.945699 39.738245 12.436719 - H12 26.634067 40.722942 13.652003 - H21 25.854111 37.847311 14.020748 - H22 26.542478 38.832008 15.236031 - C1 63.359236 49.560777 47.142789 - C2 64.168989 49.799563 46.103461 - H11 63.548490 49.891000 48.093651 - H12 62.486963 49.029141 47.068589 - H21 65.041263 50.331200 46.177660 - H22 63.979735 49.469340 45.152598 - C1 62.153332 22.136214 17.849392 - C2 62.798640 21.858424 16.709510 - H11 62.161766 21.520255 18.667639 - H12 61.600587 22.986485 17.992625 - H21 63.351386 21.008153 16.566277 - H22 62.790207 22.474382 15.891263 - C1 75.895648 58.577303 72.759691 - C2 76.827329 58.215675 73.650823 - H11 74.899191 58.653539 72.983891 - H12 76.106241 58.806095 71.783828 - H21 76.616736 57.986882 74.626686 - H22 77.823785 58.139438 73.426622 - C1 4.053771 23.321514 15.836901 - C2 2.868509 22.704648 15.923797 - H11 4.183735 24.322255 16.011922 - H12 4.923564 22.841095 15.588585 - H21 1.998715 23.185066 16.172114 - H22 2.738545 21.703907 15.748777 - C1 66.086741 30.936688 66.398294 - C2 66.854766 29.839964 66.414276 - H11 65.111679 30.938763 66.084838 - H12 66.413981 31.859691 66.698268 - H21 66.527526 28.916962 66.114302 - H22 67.829827 29.837890 66.727732 - C1 24.883864 68.219121 61.367549 - C2 24.754618 69.219350 62.248320 - H11 25.664223 67.555828 61.376800 - H12 24.212523 68.038731 60.615376 - H21 25.425959 69.399741 63.000493 - H22 23.974259 69.882644 62.239069 - C1 55.680577 74.202534 47.300013 - C2 55.570044 72.889116 47.064139 - H11 54.889666 74.797456 47.563701 - H12 56.564722 74.715468 47.235283 - H21 54.685899 72.376182 47.128870 - H22 56.360955 72.294194 46.800452 - C1 32.667326 32.466980 22.683367 - C2 31.605104 33.058062 22.121916 - H11 32.714553 31.463879 22.884764 - H12 33.516073 32.971509 22.955549 - H21 30.756357 32.553533 21.849734 - H22 31.557876 34.061164 21.920519 - C1 44.593664 24.322693 22.123717 - C2 45.321894 23.353038 21.555939 - H11 44.840848 25.315526 22.076969 - H12 43.732225 24.147754 22.649381 - H21 46.183334 23.527978 21.030275 - H22 45.074711 22.360205 21.602687 - C1 44.598888 51.866619 76.032137 - C2 44.508506 50.531711 76.084800 - H11 44.910659 52.443011 76.819268 - H12 44.363353 52.416209 75.200585 - H21 44.744040 49.982121 76.916351 - H22 44.196735 49.955319 75.297669 - C1 56.843872 65.215295 77.830215 - C2 55.575245 65.630005 77.937550 - H11 57.650833 65.841923 77.902014 - H12 57.106987 64.238862 77.667880 - H21 55.312130 66.606438 78.099885 - H22 54.768284 65.003377 77.865750 - C1 1.003150 16.004251 68.915754 - C2 1.780707 16.369062 69.943003 - H11 1.335289 15.438686 68.129101 - H12 0.015149 16.262102 68.835934 - H21 2.768708 16.111211 70.022824 - H22 1.448568 16.934627 70.729656 - C1 29.466611 29.860128 61.137371 - C2 28.738964 29.376038 60.122922 - H11 30.322402 30.407662 61.007632 - H12 29.224584 29.720919 62.122789 - H21 28.980991 29.515246 59.137505 - H22 27.883173 28.828504 60.252661 - C1 35.125302 71.432115 15.095085 - C2 36.035548 71.988680 14.286006 - H11 34.281767 70.960345 14.756135 - H12 35.201052 71.434427 16.116487 - H21 35.959797 71.986367 13.264605 - H22 36.879082 72.460449 14.624957 - C1 33.354485 8.182562 54.111860 - C2 33.193931 7.507098 52.966918 - H11 34.169948 8.074019 54.721976 - H12 32.674447 8.860852 54.467492 - H21 33.873969 6.828808 52.611286 - H22 32.378468 7.615642 52.356802 - C1 66.866871 39.192719 55.877865 - C2 65.966296 39.551155 54.954063 - H11 66.795906 38.334720 56.432668 - H12 67.697463 39.748380 56.102280 - H21 65.135704 38.995494 54.729648 - H22 66.037261 40.409153 54.399260 - C1 20.042256 73.979391 47.648256 - C2 19.346752 74.311506 46.553315 - H11 20.669171 73.170837 47.695383 - H12 20.001991 74.507809 48.524702 - H21 19.387017 73.783088 45.676870 - H22 18.719836 75.120060 46.506189 - C1 37.390067 63.520883 28.094280 - C2 37.135465 63.059835 29.325350 - H11 36.802448 63.314431 27.281208 - H12 38.192440 64.116223 27.868956 - H21 36.333092 62.464495 29.550675 - H22 37.723083 63.266287 30.138423 - C1 10.689424 19.371851 18.653991 - C2 9.955616 18.275077 18.426981 - H11 10.332538 20.199316 19.140752 - H12 11.665271 19.469504 18.358710 - H21 8.979770 18.177424 18.722262 - H22 10.312503 17.447611 17.940220 - C1 17.038622 42.412248 10.967223 - C2 16.856181 41.517056 9.988312 - H11 17.773533 43.125432 10.950513 - H12 16.457598 42.454152 11.809636 - H21 17.437205 41.475153 9.145899 - H22 16.121270 40.803873 10.005022 - C1 40.523356 66.820996 33.020524 - C2 41.834836 66.713638 33.268345 - H11 40.040759 67.717807 32.911737 - H12 39.899732 66.014741 32.920277 - H21 42.458460 67.519893 33.368592 - H22 42.317434 65.816828 33.377132 - C1 64.414366 65.907105 25.045773 - C2 63.171008 65.428535 25.179760 - H11 64.675619 66.871463 25.271081 - H12 65.201873 65.346417 24.707447 - H21 62.383500 65.989223 25.518085 - H22 62.909755 64.464177 24.954451 - C1 26.378153 64.742997 14.478407 - C2 25.039323 64.724151 14.468500 - H11 26.930737 65.605305 14.487374 - H12 26.954861 63.896586 14.477798 - H21 24.462615 65.570561 14.469109 - H22 24.486739 63.861843 14.459533 - C1 77.554360 34.757262 52.696731 - C2 77.085777 35.861093 52.100989 - H11 78.376654 34.243343 52.366997 - H12 77.127311 34.340109 53.528967 - H21 77.512826 36.278245 51.268753 - H22 76.263484 36.375012 52.430723 - C1 61.231254 49.619958 26.341357 - C2 59.985245 50.067130 26.140315 - H11 61.446424 48.667512 26.650472 - H12 62.067082 50.195218 26.201820 - H21 59.149417 49.491870 26.279852 - H22 59.770075 51.019577 25.831200 - C1 43.312559 59.658391 45.663881 - C2 42.223988 60.429362 45.547534 - H11 43.274109 58.646740 45.819085 - H12 44.269208 60.019735 45.606814 - H21 41.267338 60.068019 45.604600 - H22 42.262437 61.441013 45.392330 - C1 2.169935 46.832932 26.950161 - C2 2.395267 45.776072 27.740851 - H11 2.405323 47.794658 27.212227 - H12 1.744481 46.762658 26.021153 - H21 2.820722 45.846346 28.669858 - H22 2.159879 44.814346 27.478784 - C1 39.859387 42.060831 18.536824 - C2 40.962180 42.307988 19.254934 - H11 39.862055 41.524260 17.664420 - H12 38.926523 42.388929 18.803508 - H21 41.895044 41.979891 18.988250 - H22 40.959511 42.844560 20.127337 - C1 28.639358 42.358118 53.904464 - C2 29.235204 41.159177 53.883722 - H11 27.622985 42.483914 53.891617 - H12 29.153141 43.243618 53.934807 - H21 28.721421 40.273677 53.853379 - H22 30.251577 41.033382 53.896570 - C1 62.128447 4.663865 22.447332 - C2 63.339089 4.119468 22.623115 - H11 61.900265 5.628555 22.704838 - H12 61.335464 4.158368 22.041556 - H21 64.132072 4.624965 23.028892 - H22 63.567271 3.154778 22.365609 - C1 48.128009 8.095819 43.506441 - C2 48.867854 6.994311 43.326916 - H11 48.518708 9.042482 43.520126 - H12 47.113256 8.078268 43.644183 - H21 49.882607 7.011862 43.189173 - H22 48.477155 6.047648 43.313231 - C1 19.068171 67.271215 10.471095 - C2 20.222884 67.947369 10.422355 - H11 18.154951 67.720683 10.585165 - H12 19.007401 66.251417 10.398136 - H21 20.283653 68.967167 10.495314 - H22 21.136103 67.497901 10.308286 - C1 36.203646 73.982747 39.777089 - C2 36.713202 72.882256 39.209468 - H11 35.766975 74.741711 39.245774 - H12 36.210510 74.152036 40.787187 - H21 36.706337 72.712966 38.199371 - H22 37.149873 72.123292 39.740783 - C1 46.263194 47.087380 34.504619 - C2 45.881779 46.827801 35.761624 - H11 46.088172 47.980246 34.034340 - H12 46.759936 46.413467 33.914625 - H21 45.385037 47.501714 36.351617 - H22 46.056801 45.934935 36.231903 - C1 77.014402 35.906448 72.496005 - C2 75.861185 36.414835 72.043727 - H11 77.128346 34.928448 72.778026 - H12 77.873186 36.455629 72.595476 - H21 75.002402 35.865654 71.944255 - H22 75.747242 37.392836 71.761706 - C1 32.296041 52.909747 54.473549 - C2 31.961723 52.842422 53.178706 - H11 31.913164 53.605630 55.120198 - H12 32.960914 52.270652 54.919089 - H21 31.296850 53.481518 52.733166 - H22 32.344600 52.146539 52.532057 - C1 57.616658 17.216783 76.934926 - C2 57.899625 17.749666 75.739566 - H11 56.710972 17.324170 77.400979 - H12 58.283663 16.659914 77.477148 - H21 57.232620 18.306535 75.197343 - H22 58.805311 17.642279 75.273513 - C1 54.871492 2.017313 68.204354 - C2 55.779713 2.343897 69.132469 - H11 53.861088 2.103649 68.347997 - H12 55.115821 1.655505 67.277853 - H21 55.535385 2.705704 70.058970 - H22 56.790117 2.257561 68.988825 - C1 68.457207 45.837040 4.589803 - C2 68.896776 46.881082 3.875888 - H11 67.896306 45.077529 4.192893 - H12 68.647336 45.715910 5.588893 - H21 68.706647 47.002212 2.876797 - H22 69.457677 47.640593 4.272798 - C1 73.986141 29.254892 9.674536 - C2 74.161572 27.953686 9.411841 - H11 73.065213 29.690743 9.779083 - H12 74.759093 29.916595 9.791570 - H21 73.388619 27.291983 9.294807 - H22 75.082499 27.517834 9.307293 - C1 44.608074 16.611506 18.023279 - C2 43.329840 16.890828 17.738643 - H11 45.392812 16.885869 17.425018 - H12 44.901515 16.101537 18.861627 - H21 43.036399 17.400797 16.900294 - H22 42.545103 16.616465 18.336903 - C1 51.414851 18.559897 8.882337 - C2 52.587456 18.822956 8.291813 - H11 51.004897 19.150453 9.611847 - H12 50.835723 17.747454 8.650928 - H21 53.166583 19.635400 8.523221 - H22 52.997409 18.232401 7.562302 - C1 48.238647 61.292689 15.824922 - C2 47.001494 60.903052 16.157424 - H11 48.484793 62.261561 15.601983 - H12 49.036027 60.652471 15.767400 - H21 46.204113 61.543270 16.214946 - H22 46.755348 59.934180 16.380364 - C1 31.773388 33.631856 45.274402 - C2 32.965787 34.115312 45.645044 - H11 30.926884 34.204842 45.210191 - H12 31.614113 32.651080 45.025981 - H21 33.125061 35.096088 45.893466 - H22 33.812290 33.542326 45.709255 - C1 22.101788 24.605040 59.235690 - C2 21.568564 23.421330 59.563444 - H11 23.104011 24.808214 59.292903 - H12 21.549334 25.400315 58.902019 - H21 22.121018 22.626055 59.897114 - H22 20.566342 23.218156 59.506231 - C1 51.790070 36.887945 37.180825 - C2 51.085356 37.227822 38.267463 - H11 51.689066 37.353122 36.273956 - H12 52.485494 36.136084 37.171125 - H21 50.389932 37.979683 38.277163 - H22 51.186361 36.762645 39.174333 - C1 20.462173 32.497314 65.003100 - C2 20.078931 31.261616 64.657993 - H11 19.913107 33.108830 65.614310 - H12 21.334500 32.928097 64.682983 - H21 19.206603 30.830833 64.978110 - H22 20.627997 30.650100 64.046782 - C1 42.668852 56.602125 49.969173 - C2 41.378624 56.573096 50.326092 - H11 43.171415 55.789088 49.601200 - H12 43.254583 57.439648 50.036089 - H21 40.792893 55.735573 50.259177 - H22 40.876061 57.386133 50.694066 - C1 13.554478 2.777278 45.851737 - C2 14.520004 2.175792 45.145413 - H11 13.487114 2.727587 46.872519 - H12 12.807429 3.334317 45.426732 - H21 15.267053 1.618753 45.570418 - H22 14.587368 2.225484 44.124631 - C1 46.059273 11.528632 18.915601 - C2 47.355161 11.657501 18.604173 - H11 45.467515 12.312648 19.205680 - H12 45.557961 10.635917 18.888210 - H21 47.856473 12.550216 18.631565 - H22 47.946919 10.873485 18.314095 - C1 63.976635 9.001674 21.043480 - C2 64.508774 8.161439 21.940003 - H11 64.353247 9.934410 20.850681 - H12 63.151169 8.777670 20.480070 - H21 65.334240 8.385444 22.503413 - H22 64.132162 7.228703 22.132801 - C1 13.111751 4.200558 36.112519 - C2 13.598627 5.308189 35.538911 - H11 13.651530 3.336958 36.221324 - H12 12.161298 4.129881 36.487548 - H21 14.549081 5.378865 35.163882 - H22 13.058849 6.171789 35.430106 - C1 48.500810 44.092272 50.399969 - C2 47.918495 44.552562 49.285536 - H11 48.065704 43.404470 51.021753 - H12 49.427094 44.391822 50.718200 - H21 46.992211 44.253011 48.967305 - H22 48.353602 45.240364 48.663752 - C1 58.873093 68.905503 39.621390 - C2 57.824212 69.212929 40.394862 - H11 59.414672 68.041969 39.721419 - H12 59.216235 69.509724 38.868945 - H21 57.481070 68.608707 41.147307 - H22 57.282632 70.076463 40.294833 - C1 48.174172 28.120624 79.997315 - C2 46.890916 28.502952 79.995898 - H11 48.471404 27.140493 79.996762 - H12 48.959353 28.778265 79.999064 - H21 46.105735 27.845311 79.994149 - H22 46.593683 29.483082 79.996451 - C1 63.370510 44.336358 24.882139 - C2 63.690457 43.078361 24.553509 - H11 64.063924 45.076476 25.024990 - H12 62.407224 44.657349 25.016484 - H21 64.653742 42.757370 24.419163 - H22 62.997043 42.338243 24.410658 - C1 51.084260 51.988649 72.708668 - C2 50.602843 52.541768 73.829033 - H11 51.809125 52.423669 72.130453 - H12 50.765467 51.087078 72.341866 - H21 50.921637 53.443339 74.195835 - H22 49.877979 52.106748 74.407248 - C1 31.575036 46.475325 61.018152 - C2 31.879891 45.176925 61.137071 - H11 30.660264 46.865365 61.263235 - H12 32.232664 47.180473 60.672761 - H21 31.222262 44.471777 61.482461 - H22 32.794662 44.786884 60.891987 - C1 54.218953 71.745131 55.204777 - C2 54.516230 70.442677 55.295126 - H11 54.926437 72.485136 55.175422 - H12 53.260718 72.103732 55.157924 - H21 55.474465 70.084076 55.341979 - H22 53.808746 69.702672 55.324481 - C1 16.408973 74.205296 66.789568 - C2 15.866493 75.428948 66.825771 - H11 17.405721 74.024756 66.940907 - H12 15.869803 73.353697 66.607692 - H21 16.405663 76.280547 67.007647 - H22 14.869745 75.609489 66.674432 - C1 25.577226 2.543454 77.846743 - C2 26.118485 1.642531 77.017106 - H11 24.584369 2.554943 78.097953 - H12 26.113537 3.291886 78.295324 - H21 25.582175 0.894100 76.568525 - H22 27.111342 1.631042 76.765896 - C1 26.161922 67.616671 58.158571 - C2 26.518102 68.743504 57.529045 - H11 26.716014 66.755693 58.132098 - H12 25.307394 67.527177 58.716045 - H21 27.372630 68.832999 56.971571 - H22 25.964009 69.604483 57.555518 - C1 34.872935 45.469696 67.091446 - C2 35.865780 45.476303 66.193038 - H11 35.012657 45.269050 68.086043 - H12 33.895757 45.664770 66.854647 - H21 36.842958 45.281229 66.429837 - H22 35.726058 45.676949 65.198442 - C1 59.591548 6.757295 20.344253 - C2 58.520952 7.510659 20.062850 - H11 59.565601 5.734526 20.391936 - H12 60.520534 7.144609 20.533930 - H21 57.591966 7.123345 19.873172 - H22 58.546899 8.533428 20.015167 - C1 26.487850 17.918298 4.178703 - C2 26.704685 18.484789 2.984973 - H11 27.131126 18.006420 4.970810 - H12 25.661675 17.352344 4.393495 - H21 27.530860 19.050743 2.770181 - H22 26.061409 18.396667 2.192866 - C1 42.028764 70.816569 31.148264 - C2 43.265948 71.328709 31.151305 - H11 41.190580 71.363629 31.365466 - H12 41.823394 69.837524 30.928497 - H21 43.471317 72.307754 31.371073 - H22 44.104132 70.781649 30.934103 - C1 37.059299 4.753839 26.268798 - C2 37.731943 5.771825 26.820319 - H11 37.253746 3.769967 26.476620 - H12 36.297482 4.879049 25.595774 - H21 38.493760 5.646615 27.493343 - H22 37.537495 6.755697 26.612497 - C1 71.050078 6.761111 70.566550 - C2 72.218084 6.941245 71.196021 - H11 70.814702 7.206236 69.674661 - H12 70.300251 6.164044 70.927486 - H21 72.967911 7.538312 70.835085 - H22 72.453460 6.496121 72.087910 - C1 25.649333 32.197657 61.872586 - C2 26.863969 32.761067 61.860376 - H11 24.777984 32.734816 61.907452 - H12 25.496147 31.185266 61.848019 - H21 27.017155 33.773457 61.884943 - H22 27.735317 32.223907 61.825510 - C1 56.879206 60.625940 23.453098 - C2 56.580506 61.929919 23.510880 - H11 57.834841 60.262323 23.512660 - H12 56.175522 59.889664 23.344798 - H21 57.284191 62.666196 23.619180 - H22 55.624871 62.293537 23.451318 - C1 24.712704 31.459918 54.840984 - C2 24.849446 32.320674 55.857508 - H11 24.380705 30.497907 54.956376 - H12 24.929363 31.695889 53.868163 - H21 24.632787 32.084704 56.830328 - H22 25.181445 33.282685 55.742115 - C1 73.267178 53.122045 63.561818 - C2 72.756271 53.862847 62.570300 - H11 73.985336 53.461777 64.208219 - H12 72.979964 52.157453 63.751753 - H21 73.043485 54.827439 62.380366 - H22 72.038113 53.523115 61.923899 - C1 24.944605 18.222727 33.096472 - C2 24.166374 17.798551 34.100142 - H11 25.004241 19.202266 32.803299 - H12 25.541399 17.600976 32.543058 - H21 23.569581 18.420302 34.653555 - H22 24.106738 16.819012 34.393314 - C1 55.102301 25.048407 43.693413 - C2 54.192180 24.140564 44.068145 - H11 55.407793 25.174937 42.724048 - H12 55.564486 25.687633 44.346696 - H21 53.729995 23.501337 43.414863 - H22 53.886687 24.014034 45.037510 - C1 59.877011 74.563182 76.015882 - C2 60.330871 75.263248 74.968580 - H11 59.143249 74.900860 76.645621 - H12 60.227946 73.635007 76.269532 - H21 59.979937 76.191423 74.714930 - H22 61.064633 74.925570 74.338841 - C1 24.811958 33.179389 31.145940 - C2 25.694376 34.181596 31.046746 - H11 24.952392 32.259005 30.719120 - H12 23.927212 33.254421 31.656428 - H21 26.579122 34.106564 30.536257 - H22 25.553943 35.101980 31.473566 - C1 60.749975 68.036921 11.556427 - C2 61.268204 69.113921 12.160107 - H11 61.184299 67.109803 11.585036 - H12 59.878529 68.055600 11.018619 - H21 62.139650 69.095243 12.697915 - H22 60.833880 70.041039 12.131498 - C1 73.609923 9.708779 6.346226 - C2 72.418134 9.744098 5.736872 - H11 74.033953 8.849526 6.708010 - H12 74.191157 10.538241 6.498426 - H21 71.836900 8.914637 5.584672 - H22 71.994105 10.603351 5.375088 - C1 1.883620 77.751591 77.114225 - C2 2.014487 78.915852 76.465927 - H11 1.009013 77.442009 77.548075 - H12 2.647841 77.079129 77.227209 - H21 1.250266 79.588313 76.352943 - H22 2.889094 79.225434 76.032077 - C1 68.936563 37.541627 42.796755 - C2 68.528071 38.674331 43.382448 - H11 69.026973 37.431084 41.782551 - H12 69.190713 36.696745 43.316934 - H21 68.273921 39.519214 42.862270 - H22 68.437661 38.784875 44.396652 - C1 45.484646 0.810481 68.349910 - C2 45.686448 1.068512 69.648224 - H11 45.932596 0.035702 67.851852 - H12 44.866478 1.367613 67.752854 - H21 46.304616 0.511380 70.245280 - H22 45.238498 1.843291 70.146282 - C1 22.066245 74.968498 69.280454 - C2 22.213254 73.653621 69.074523 - H11 21.787001 75.371522 70.179675 - H12 22.221487 75.674560 68.554934 - H21 22.058012 72.947558 69.800043 - H22 22.492498 73.250597 68.175302 - C1 59.840290 1.756482 11.944357 - C2 60.927598 2.520759 12.107344 - H11 58.887108 2.084519 12.125573 - H12 59.876339 0.783786 11.625664 - H21 60.891549 3.493456 12.426037 - H22 61.880780 2.192723 11.926128 - C1 67.012838 65.704133 35.736100 - C2 66.940306 64.399678 35.442746 - H11 67.896553 66.206582 35.860987 - H12 66.190304 66.301980 35.858654 - H21 67.762840 63.801831 35.320193 - H22 66.056591 63.897229 35.317859 - C1 19.560556 68.617122 79.401832 - C2 20.830478 69.041563 79.410152 - H11 19.295798 67.627726 79.402652 - H12 18.754148 69.248507 79.393994 - H21 21.636887 68.410178 79.417989 - H22 21.095237 70.030960 79.409331 - C1 28.115467 34.319919 36.209764 - C2 28.030397 33.195617 36.932003 - H11 28.674402 35.130806 36.490936 - H12 27.628287 34.457371 35.319389 - H21 28.517576 33.058166 37.822377 - H22 27.471461 32.384731 36.650830 - C1 6.839750 5.591477 26.795590 - C2 6.065347 6.352547 27.579168 - H11 7.858171 5.537201 26.889799 - H12 6.474529 5.003797 26.040440 - H21 6.430568 6.940226 28.334317 - H22 5.046926 6.406823 27.484959 - C1 75.394577 40.317215 36.091280 - C2 74.479612 39.488897 36.610556 - H11 76.210618 40.654167 36.610457 - H12 75.350301 40.678943 35.134098 - H21 74.523888 39.127169 37.567738 - H22 73.663571 39.151945 36.091379 - C1 58.249062 48.673225 17.906397 - C2 56.915863 48.795620 17.883600 - H11 58.843319 48.815114 17.084369 - H12 58.779347 48.428095 18.747654 - H21 56.385578 49.040750 17.042343 - H22 56.321606 48.653730 18.705628 - C1 12.681412 46.017897 39.692229 - C2 13.831081 46.152612 39.019151 - H11 12.062647 45.207357 39.596534 - H12 12.330443 46.714807 40.355660 - H21 14.182050 45.455702 38.355719 - H22 14.449846 46.963152 39.114846 - C1 74.097184 33.226811 17.810559 - C2 73.885287 31.912980 17.958438 - H11 74.974333 33.621237 17.458363 - H12 73.398768 33.940590 18.038021 - H21 74.583703 31.199201 17.730977 - H22 73.008138 31.518555 18.310634 - C1 48.699955 28.560107 13.358863 - C2 48.926701 27.241012 13.320176 - H11 47.764247 28.973890 13.311539 - H12 49.444403 29.258968 13.438820 - H21 48.182252 26.542151 13.240219 - H22 49.862408 26.827229 13.367500 - C1 37.425612 43.331546 72.986081 - C2 38.475067 42.777634 73.606361 - H11 36.966022 44.187877 73.309314 - H12 36.999997 42.942436 72.139649 - H21 38.900683 43.166745 74.452793 - H22 38.934657 41.921304 73.283128 - C1 17.824318 44.117482 54.835101 - C2 16.641178 44.740333 54.906924 - H11 18.708913 44.603774 54.661853 - H12 17.937689 43.105822 54.947765 - H21 16.527807 45.751994 54.794260 - H22 15.756582 44.254042 55.080172 - C1 8.539005 24.624287 33.519383 - C2 8.855741 25.456450 32.519331 - H11 9.162905 23.886539 33.859207 - H12 7.647941 24.660114 34.023095 - H21 9.746805 25.420623 32.015619 - H22 8.231841 26.194198 32.179507 - C1 45.023149 64.296830 24.670468 - C2 44.767724 64.606933 25.947776 - H11 44.587990 63.508200 24.182920 - H12 45.673756 64.823891 24.080620 - H21 44.117117 64.079873 26.537625 - H22 45.202883 65.395563 26.435325 - C1 61.102464 39.384191 40.736061 - C2 60.759280 40.616659 41.131241 - H11 62.061360 39.026108 40.772113 - H12 60.433041 38.702697 40.366679 - H21 61.428703 41.298152 41.500624 - H22 59.800384 40.974741 41.095189 - C1 19.432096 53.549636 15.174873 - C2 19.094868 54.842215 15.266727 - H11 20.399426 53.222687 15.094980 - H12 18.749217 52.786305 15.177288 - H21 19.777748 55.605545 15.264311 - H22 18.127538 55.169163 15.346620 - C1 76.194549 56.149264 17.038549 - C2 77.211864 56.151362 17.909173 - H11 75.229334 56.373755 17.297329 - H12 76.301668 55.923002 16.045404 - H21 77.104745 56.377624 18.902317 - H22 78.177080 55.926871 17.650392 - C1 51.699575 36.106177 21.337824 - C2 51.463253 36.213952 20.024257 - H11 51.240353 35.416155 21.939478 - H12 52.358133 36.705293 21.844150 - H21 50.804695 35.614837 19.517930 - H22 51.922475 36.903974 19.422602 - C1 25.842304 63.898079 57.561157 - C2 26.043374 63.777562 56.242837 - H11 25.591930 64.781023 58.015829 - H12 25.923076 63.116790 58.218475 - H21 25.962602 64.558851 55.585519 - H22 26.293747 62.894618 55.788164 - C1 62.185654 8.354336 51.106742 - C2 61.846033 9.649346 51.129738 - H11 61.515620 7.592251 51.245614 - H12 63.142154 8.024092 50.948472 - H21 60.889532 9.979589 51.288007 - H22 62.516066 10.411430 50.990865 - C1 73.371958 67.938752 53.053264 - C2 72.939335 68.297905 51.838041 - H11 73.883146 68.567744 53.679412 - H12 73.225684 67.006818 53.452147 - H21 73.085609 69.229838 51.439158 - H22 72.428148 67.668913 51.211894 - C1 20.652395 1.146548 73.481409 - C2 21.748579 1.911797 73.405941 - H11 19.701452 1.524696 73.522823 - H12 20.678717 0.122919 73.503652 - H21 21.722257 2.935426 73.383698 - H22 22.699522 1.533648 73.364527 - C1 71.455027 57.538305 33.792540 - C2 72.320234 58.231331 34.543575 - H11 70.974006 56.694776 34.118242 - H12 71.206254 57.797273 32.833346 - H21 72.569006 57.972363 35.502768 - H22 72.801254 59.074859 34.217873 - C1 15.491143 4.717339 71.099137 - C2 14.395879 5.104852 70.433441 - H11 16.362800 5.254928 71.113836 - H12 15.543331 3.852886 71.645948 - H21 14.343692 5.969305 69.886630 - H22 13.524222 4.567263 70.418742 - C1 1.508222 65.535484 59.360273 - C2 0.929492 66.733605 59.210273 - H11 1.342095 64.924953 60.165666 - H12 2.162501 65.135411 58.681403 - H21 0.275213 67.133678 59.889142 - H22 1.095618 67.344135 58.404879 - C1 43.866304 62.306281 42.355832 - C2 42.867291 62.823074 43.082342 - H11 43.733838 61.888204 41.430268 - H12 44.841429 62.288448 42.668590 - H21 41.892166 62.840907 42.769584 - H22 42.999757 63.241152 44.007906 - C1 51.113702 19.467180 39.091473 - C2 50.101173 19.488793 39.967395 - H11 51.738831 20.262498 38.931203 - H12 51.342631 18.653631 38.512912 - H21 49.872243 20.302342 40.545957 - H22 49.476043 18.693475 40.127665 - C1 47.805316 12.238564 71.212716 - C2 46.587749 12.747664 71.439144 - H11 48.635715 12.814044 71.044600 - H12 48.001922 11.233663 71.189841 - H21 46.391142 13.752565 71.462018 - H22 45.757349 12.172183 71.607259 - C1 14.229258 5.007535 11.088700 - C2 13.014338 4.498258 11.328545 - H11 14.383051 5.943991 10.703470 - H12 15.100241 4.500649 11.271623 - H21 12.143355 5.005144 11.145622 - H22 12.860545 3.561802 11.713775 - C1 63.872246 61.235796 1.519826 - C2 64.322917 61.859159 2.615835 - H11 62.915902 61.334818 1.166831 - H12 64.448452 60.610973 0.948349 - H21 63.746711 62.483982 3.187312 - H22 65.279261 61.760137 2.968830 - C1 20.235324 23.250589 23.734277 - C2 20.061737 24.421607 23.108574 - H11 19.603802 22.451929 23.623257 - H12 21.013265 23.061507 24.373073 - H21 19.283796 24.610690 22.469778 - H22 20.693259 25.220268 23.219594 - C1 20.557151 16.533930 6.103679 - C2 19.881459 16.246114 7.223288 - H11 21.196758 17.329355 6.018790 - H12 20.487485 15.981274 5.244190 - H21 19.951125 16.798770 8.082777 - H22 19.241852 15.450689 7.308178 - C1 66.387347 31.494779 25.010181 - C2 65.922775 32.750578 25.002365 - H11 65.834510 30.686266 24.710711 - H12 67.332047 31.244036 25.316244 - H21 64.978075 33.001321 24.696302 - H22 66.475612 33.559091 25.301835 - C1 4.518445 39.523912 42.643553 - C2 4.939482 40.741350 42.278184 - H11 3.571353 39.176961 42.465662 - H12 5.110397 38.843965 43.129629 - H21 4.347530 41.421296 41.792108 - H22 5.886574 41.088301 42.456075 - C1 69.214307 68.282573 72.837064 - C2 69.451639 69.390780 72.123993 - H11 69.945914 67.757537 73.325011 - H12 68.282513 67.872845 72.950585 - H21 70.383433 69.800508 72.010472 - H22 68.720032 69.915816 71.636045 - C1 32.558841 2.666228 31.243099 - C2 33.746070 2.127360 30.938089 - H11 32.446288 3.619917 31.599208 - H12 31.669979 2.167070 31.144263 - H21 34.634932 2.626518 31.036925 - H22 33.858623 1.173672 30.581980 - C1 62.513724 1.844808 52.930357 - C2 62.383848 1.779829 51.599256 - H11 63.163647 1.259756 53.463572 - H12 61.973351 2.484670 53.519914 - H21 62.924221 1.139967 51.009699 - H22 61.733925 2.364881 51.066041 - C1 79.474682 44.000850 71.629628 - C2 79.717575 45.233872 71.167479 - H11 79.378704 43.779590 72.625035 - H12 79.365781 43.182067 71.024038 - H21 79.826475 46.052655 71.773069 - H22 79.813552 45.455131 70.172072 - C1 48.116467 4.184351 1.401668 - C2 48.437195 5.315179 2.042981 - H11 47.162927 3.952399 1.108471 - H12 48.799475 3.462460 1.153923 - H21 47.754187 6.037070 2.290726 - H22 49.390735 5.547131 2.336178 - C1 78.729138 76.655070 63.447236 - C2 78.842943 77.730894 64.236268 - H11 77.940610 76.501605 62.811880 - H12 79.421671 75.901087 63.417049 - H21 78.150409 78.484876 64.266454 - H22 79.631471 77.884358 64.871624 - C1 26.860730 50.825706 14.173628 - C2 27.316695 52.077534 14.307583 - H11 25.869022 50.594677 14.063426 - H12 27.467835 50.000831 14.170841 - H21 26.709590 52.902409 14.310370 - H22 28.308403 52.308564 14.417785 - C1 54.170303 58.558340 15.385804 - C2 54.597278 59.713497 15.911375 - H11 53.184755 58.354570 15.195602 - H12 54.795700 57.787745 15.132692 - H21 53.971880 60.484091 16.164487 - H22 55.582826 59.917267 16.101577 - C1 27.162090 51.385740 63.063402 - C2 28.443452 50.997988 63.089506 - H11 26.833838 52.217477 62.563935 - H12 26.409526 50.881069 63.540851 - H21 29.196016 51.502659 62.612057 - H22 28.771704 50.166251 63.588974 - C1 37.294397 27.402767 46.302559 - C2 37.447973 28.690043 45.967512 - H11 36.401167 26.905576 46.239751 - H12 38.058089 26.814152 46.647975 - H21 36.684281 29.278657 45.622096 - H22 38.341203 29.187233 46.030320 - C1 62.104303 67.448721 0.810214 - C2 63.371355 67.809942 0.571427 - H11 61.305239 68.077739 0.688410 - H12 61.834621 66.515016 1.133433 - H21 63.641038 68.743646 0.248208 - H22 64.170419 67.180923 0.693231 - C1 34.708721 25.805739 52.210645 - C2 34.959571 24.647262 52.833483 - H11 34.012925 25.907432 51.465978 - H12 35.192928 26.681211 52.429955 - H21 34.475364 23.771791 52.614173 - H22 35.655367 24.545569 53.578150 - C1 10.907939 49.901565 8.146029 - C2 10.417667 48.684313 7.879849 - H11 10.652270 50.444205 8.976197 - H12 11.577148 50.385666 7.540381 - H21 9.748458 48.200212 8.485497 - H22 10.673335 48.141674 7.049681 - C1 22.987075 72.321917 6.562767 - C2 23.770435 71.528434 7.304153 - H11 23.150440 73.326132 6.445011 - H12 22.162952 71.986996 6.055171 - H21 24.594558 71.863355 7.811749 - H22 23.607070 70.524219 7.421909 - C1 72.654571 22.280440 65.087676 - C2 73.682036 23.135809 65.012963 - H11 72.766938 21.275856 65.252564 - H12 71.675548 22.563529 64.985808 - H21 74.661060 22.852721 65.114831 - H22 73.569669 24.140393 64.848075 - C1 39.513365 65.855521 9.098071 - C2 38.714386 66.928085 9.033575 - H11 39.296806 64.962054 8.646603 - H12 40.403856 65.844290 9.603940 - H21 37.823896 66.939316 8.527705 - H22 38.930946 67.821552 9.485042 - C1 34.382292 55.370456 66.496014 - C2 35.329718 54.442481 66.311168 - H11 33.424215 55.149940 66.783183 - H12 34.541223 56.373709 66.364760 - H21 35.170786 53.439228 66.442422 - H22 36.287794 54.662996 66.023999 - C1 43.880511 32.319499 71.332704 - C2 44.415747 33.266047 70.551365 - H11 43.102129 32.491596 71.975750 - H12 44.207427 31.348997 71.348710 - H21 44.088831 34.236548 70.535358 - H22 45.194128 33.093949 69.908319 - C1 53.966675 20.652875 28.542242 - C2 53.497506 21.906735 28.516991 - H11 53.402372 19.833746 28.298125 - H12 54.926717 20.414386 28.807658 - H21 52.537464 22.145225 28.251575 - H22 54.061809 22.725864 28.761107 - C1 7.128126 35.496436 59.265076 - C2 6.664852 36.505675 60.013230 - H11 8.030912 35.519775 58.781923 - H12 6.616108 34.621814 59.117169 - H21 7.176870 37.380298 60.161138 - H22 5.762067 36.482337 60.496384 - C1 59.190358 72.354861 12.052523 - C2 60.066122 73.281688 12.461119 - H11 58.967457 72.183833 11.067603 - H12 58.674560 71.744119 12.692797 - H21 60.581920 73.892430 11.820845 - H22 60.289023 73.452716 13.446039 - C1 10.291462 70.695433 22.993057 - C2 8.993973 70.654727 23.321365 - H11 10.863220 69.858541 22.845717 - H12 10.814123 71.566660 22.863472 - H21 8.471311 69.783500 23.450951 - H22 8.422215 71.491619 23.468705 - C1 28.967268 47.116963 11.376249 - C2 29.364252 48.395139 11.416132 - H11 29.320307 46.436931 10.696600 - H12 28.279375 46.718865 12.022257 - H21 30.052144 48.793236 10.770124 - H22 29.011212 49.075171 12.095781 - C1 16.388327 1.775588 6.247161 - C2 16.141521 0.659676 5.549487 - H11 15.848106 2.058137 7.070162 - H12 17.136727 2.434300 6.012641 - H21 15.393122 0.000963 5.784007 - H22 16.681743 0.377127 4.726486 - C1 38.780936 24.364490 50.285995 - C2 37.582445 24.819107 50.673116 - H11 38.906915 23.642838 49.570208 - H12 39.665874 24.702677 50.675250 - H21 36.697507 24.480921 50.283862 - H22 37.456466 25.540760 51.388903 - C1 64.766598 72.740041 67.429670 - C2 65.430101 71.853802 66.676500 - H11 64.423757 73.637750 67.075295 - H12 64.549782 72.589866 68.419338 - H21 65.646918 72.003977 65.686832 - H22 65.772942 70.956092 67.030875 - C1 10.948819 15.499437 41.287654 - C2 10.441690 14.422850 41.901415 - H11 10.508181 15.948664 40.479547 - H12 11.817215 15.958301 41.578060 - H21 9.573294 13.963986 41.611010 - H22 10.882328 13.973624 42.709523 - C1 55.610557 56.850591 77.667883 - C2 55.438235 58.176832 77.733546 - H11 54.872958 56.198593 77.385305 - H12 56.493508 56.383917 77.895075 - H21 54.555284 58.643506 77.506354 - H22 56.175834 58.828829 78.016125 - C1 72.242050 74.931251 17.647848 - C2 71.637819 73.846890 17.145864 - H11 73.019405 75.410224 17.183836 - H12 71.974357 75.366926 18.535277 - H21 71.905512 73.411214 16.258435 - H22 70.860464 73.367916 17.609876 - C1 6.495083 16.915098 56.974777 - C2 7.033107 15.881843 57.634954 - H11 5.505569 16.965941 56.715392 - H12 7.030779 17.735797 56.677308 - H21 6.497411 15.061144 57.932423 - H22 8.022621 15.831000 57.894339 - C1 63.452509 16.472465 68.531424 - C2 62.181586 16.631507 68.921784 - H11 63.920440 15.562404 68.488609 - H12 64.056590 17.248375 68.244975 - H21 61.577505 15.855596 69.208234 - H22 61.713654 17.541568 68.964600 - C1 11.513772 42.659140 61.699214 - C2 12.382197 43.607437 62.072699 - H11 10.826490 42.241395 62.333357 - H12 11.468544 42.277005 60.750040 - H21 12.427425 43.989572 63.021873 - H22 13.069479 44.025181 61.438556 - C1 26.962111 72.873618 2.638199 - C2 27.488985 72.311058 3.733120 - H11 27.483103 73.502372 2.019943 - H12 25.996707 72.719378 2.332899 - H21 28.454389 72.465298 4.038420 - H22 26.967993 71.682304 4.351375 - C1 17.032413 44.739017 19.802718 - C2 17.957421 45.506411 19.212475 - H11 16.713060 44.879289 20.765703 - H12 16.571530 43.951456 19.337597 - H21 18.418304 46.293973 19.677596 - H22 18.276775 45.366139 18.249489 - C1 3.852711 9.677188 40.786028 - C2 4.799518 8.905964 40.236764 - H11 4.016508 10.640787 41.092054 - H12 2.890292 9.364110 40.943301 - H21 5.761938 9.219042 40.079492 - H22 4.635722 7.942365 39.930738 - C1 54.107114 39.896713 6.215316 - C2 54.922181 40.922984 5.940810 - H11 53.230184 39.995425 6.735176 - H12 54.296541 38.932350 5.927000 - H21 54.732754 41.887346 6.229126 - H22 55.799111 40.824271 5.420950 - C1 41.823886 18.475397 56.035215 - C2 42.231708 17.227709 56.299555 - H11 41.596693 19.161028 56.761367 - H12 41.707085 18.842180 55.086093 - H21 42.348509 16.860926 57.248677 - H22 42.458901 16.542078 55.573403 - C1 55.227945 52.275810 29.326984 - C2 54.025354 52.864620 29.327191 - H11 56.110868 52.794889 29.329703 - H12 55.359395 51.260076 29.324092 - H21 53.893903 53.880354 29.330083 - H22 53.142431 52.345540 29.324472 - C1 2.863275 11.111157 15.702065 - C2 3.730398 10.230540 16.217365 - H11 1.846672 11.015511 15.781895 - H12 3.148469 11.949595 15.187585 - H21 3.445204 9.392102 16.731845 - H22 4.747001 10.326186 16.137535 - C1 41.659501 60.703602 49.535743 - C2 41.965704 60.707632 48.232231 - H11 40.884963 61.241417 49.935554 - H12 42.175761 60.162388 50.235434 - H21 41.449444 61.248846 47.532540 - H22 42.740243 60.169817 47.832421 - C1 31.641998 41.646728 20.760602 - C2 30.405614 41.138504 20.683240 - H11 32.460610 41.100033 21.043449 - H12 31.866264 42.622106 20.543009 - H21 30.181348 40.163127 20.900833 - H22 29.587003 41.685200 20.400393 - C1 50.547528 42.601457 71.052816 - C2 49.424075 43.320615 71.169377 - H11 51.438018 42.871789 71.480544 - H12 50.604660 41.724523 70.526769 - H21 49.366943 44.197550 71.695424 - H22 48.533585 43.050284 70.741648 - C1 1.976668 34.855287 78.402071 - C2 2.370707 34.106664 79.439962 - H11 1.142214 34.652347 77.843945 - H12 2.478753 35.689685 78.084747 - H21 1.868622 33.272266 79.757286 - H22 3.205161 34.309604 79.998088 - C1 28.312526 76.220935 3.004613 - C2 29.575537 76.276853 2.563482 - H11 28.047347 75.818952 3.908546 - H12 27.512367 76.575750 2.472771 - H21 30.375696 75.922038 3.095324 - H22 29.840716 76.678836 1.659549 - C1 48.606015 58.576769 47.373096 - C2 48.382616 57.259515 47.461729 - H11 47.858343 59.276602 47.358107 - H12 49.542123 58.988029 47.313322 - H21 47.446509 56.848256 47.521502 - H22 49.130289 56.559683 47.476717 - C1 69.170849 67.056352 16.403015 - C2 70.406655 66.632975 16.108978 - H11 68.421010 66.434275 16.718871 - H12 68.878298 68.035544 16.335177 - H21 70.699206 65.653784 16.176817 - H22 71.156494 67.255052 15.793122 - C1 56.885962 54.708196 70.068548 - C2 56.780675 56.042636 70.035290 - H11 56.168620 54.075810 69.701790 - H12 57.692114 54.214995 70.463359 - H21 55.974523 56.535837 69.640479 - H22 57.498017 56.675022 70.402048 - C1 52.235458 52.524672 61.690392 - C2 52.776945 53.740923 61.833380 - H11 51.338333 52.357017 61.225566 - H12 52.675843 51.666430 62.034609 - H21 52.336560 54.599165 61.489163 - H22 53.674070 53.908577 62.298206 - C1 1.274803 16.532120 54.488972 - C2 1.654396 15.248347 54.461433 - H11 1.928567 17.311951 54.604982 - H12 0.300854 16.835138 54.396190 - H21 2.628344 14.945329 54.554214 - H22 1.000632 14.468516 54.345422 - C1 27.546459 52.027823 77.893394 - C2 28.760519 52.526721 77.628669 - H11 26.706633 52.606320 77.988465 - H12 27.362235 51.028511 78.021616 - H21 28.944742 53.526033 77.500446 - H22 29.600345 51.948224 77.533598 - C1 74.285490 2.634074 47.596966 - C2 74.985533 3.277059 46.653869 - H11 73.845399 1.721054 47.449596 - H12 74.135102 3.004743 48.539830 - H21 75.135921 2.906390 45.711005 - H22 75.425624 4.190079 46.801239 - C1 2.889005 64.748503 14.763460 - C2 3.504351 65.550492 15.641574 - H11 1.891646 64.815289 14.540257 - H12 3.367325 64.005246 14.245982 - H21 3.026031 66.293749 16.159051 - H22 4.501709 65.483705 15.864777 - C1 63.976619 51.770086 50.292570 - C2 64.145284 52.617307 51.315649 - H11 64.486867 50.886777 50.200828 - H12 63.324104 51.938771 49.521355 - H21 64.797799 52.448621 52.086865 - H22 63.635036 53.500615 51.407391 - C1 60.968599 1.367795 15.150290 - C2 59.765333 1.951413 15.083499 - H11 61.848244 1.890662 15.193166 - H12 61.103898 0.352651 15.163750 - H21 59.630034 2.966557 15.070038 - H22 58.885688 1.428546 15.040623 - C1 30.558259 51.596438 6.433048 - C2 29.401700 51.301083 5.826370 - H11 31.385216 50.993266 6.396589 - H12 30.706848 52.448739 6.981235 - H21 29.253110 50.448783 5.278184 - H22 28.574743 51.904256 5.862829 - C1 60.252707 4.485059 17.337557 - C2 60.965513 4.623076 18.462626 - H11 59.581618 3.726798 17.183658 - H12 60.322550 5.126903 16.542471 - H21 60.895670 3.981232 19.257712 - H22 61.636602 5.381337 18.616525 - C1 50.955930 58.064714 32.052768 - C2 49.629011 58.144190 31.891864 - H11 51.501057 57.223792 31.841366 - H12 51.530048 58.838599 32.399891 - H21 49.054893 57.370305 31.544741 - H22 49.083885 58.985112 32.103266 - C1 43.269673 38.396844 68.031845 - C2 42.698623 37.352929 67.417789 - H11 43.669626 38.348505 68.973495 - H12 43.351395 39.325716 67.608145 - H21 42.616901 36.424057 67.841489 - H22 42.298671 37.401269 66.476139 - C1 62.269366 29.399997 54.678256 - C2 62.605518 28.122500 54.459345 - H11 62.713984 29.986896 55.390203 - H12 61.541206 29.890656 54.150960 - H21 63.333678 27.631841 54.986641 - H22 62.160900 27.535600 53.747398 - C1 75.167154 10.441284 22.902266 - C2 75.937120 11.526362 22.751675 - H11 75.262678 9.784946 23.682714 - H12 74.422171 10.182367 22.248839 - H21 76.682103 11.785279 23.405102 - H22 75.841596 12.182700 21.971227 - C1 5.190319 37.997112 33.001879 - C2 3.921636 38.038484 33.428086 - H11 5.834290 37.230849 33.219009 - H12 5.616469 38.728478 32.425248 - H21 3.495485 37.307119 34.004717 - H22 3.277664 38.804747 33.210956 - C1 20.777650 11.945699 68.803120 - C2 21.102622 10.679016 69.090917 - H11 20.152473 12.207827 68.035366 - H12 21.128716 12.752006 69.328119 - H21 20.751556 9.872708 68.565918 - H22 21.727799 10.416888 69.858671 - C1 69.838123 51.377588 77.488405 - C2 71.074087 51.871031 77.636148 - H11 69.401996 51.210502 76.576879 - H12 69.231725 51.128460 78.275311 - H21 71.680484 52.120159 76.849242 - H22 71.510214 52.038117 78.547674 - C1 27.624412 6.498104 65.115414 - C2 26.854304 5.959492 64.161605 - H11 28.625057 6.681477 64.996716 - H12 27.273347 6.769046 66.038641 - H21 27.205369 5.688550 63.238379 - H22 25.853660 5.776119 64.280304 - C1 25.325759 73.852422 57.330289 - C2 26.307064 74.756184 57.445074 - H11 25.493250 72.850053 57.202988 - H12 24.330546 74.092477 57.360770 - H21 27.302277 74.516130 57.414593 - H22 26.139573 75.758554 57.572375 - C1 77.282015 6.644439 5.870446 - C2 77.439161 5.562086 6.642934 - H11 77.308183 7.603233 6.229657 - H12 77.123295 6.598600 4.859649 - H21 77.597881 5.607925 7.653731 - H22 77.412993 4.603291 6.283723 - C1 62.735959 7.990268 59.899641 - C2 61.711776 7.242476 59.469784 - H11 63.565320 7.601913 60.358275 - H12 62.770488 9.009378 59.803587 - H21 61.677247 6.223366 59.565838 - H22 60.882415 7.630831 59.011149 - C1 41.668004 40.892213 7.790296 - C2 41.293232 42.176972 7.833410 - H11 41.208115 40.151468 8.327700 - H12 42.444010 40.549274 7.216526 - H21 40.517226 42.519911 8.407179 - H22 41.753121 42.917717 7.296006 - C1 21.221570 45.365303 68.870514 - C2 20.118036 44.610122 68.940043 - H11 21.976517 45.327028 69.561596 - H12 21.397444 46.040565 68.120786 - H21 19.942162 43.934859 69.689771 - H22 19.363089 44.648396 68.248961 - C1 14.852097 31.679377 69.519519 - C2 14.080770 30.584870 69.514153 - H11 15.875841 31.648764 69.523382 - H12 14.478961 32.633197 69.520182 - H21 14.453906 29.631050 69.513489 - H22 13.057026 30.615483 69.510290 - C1 42.626753 67.402228 39.954993 - C2 43.516714 67.416072 40.955342 - H11 41.716132 66.937371 40.015668 - H12 42.786700 67.855408 39.050532 - H21 43.356767 66.962892 41.859803 - H22 44.427335 67.880928 40.894667 - C1 16.246587 59.577201 57.860347 - C2 15.323715 59.316319 58.794782 - H11 17.133939 60.048491 58.059085 - H12 16.137669 59.325964 56.873422 - H21 15.432633 59.567556 59.781707 - H22 14.436363 58.845029 58.596044 - C1 4.359713 2.032383 71.946451 - C2 3.826853 0.978897 71.314669 - H11 4.885489 2.770451 71.469146 - H12 4.283400 2.182922 72.956658 - H21 3.903166 0.828359 70.304462 - H22 3.301077 0.240830 71.791974 - C1 29.251257 13.263278 10.739759 - C2 29.063536 11.960706 10.492800 - H11 29.393981 13.962505 10.005106 - H12 29.266875 13.662758 11.682720 - H21 29.047918 11.561226 9.549839 - H22 28.920812 11.261479 11.227453 - C1 4.944751 71.493283 26.647294 - C2 4.405131 71.530850 27.872169 - H11 5.855376 71.070819 26.444094 - H12 4.489291 71.884061 25.817322 - H21 4.860591 71.140072 28.702141 - H22 3.494506 71.953314 28.075368 - C1 61.235476 51.073812 77.911146 - C2 62.496833 51.369625 77.572924 - H11 60.866815 50.118590 77.936502 - H12 60.540194 51.779519 78.171078 - H21 63.192115 50.663918 77.312992 - H22 62.865494 52.324847 77.547568 - C1 38.868206 15.290828 37.789736 - C2 40.066519 15.285832 37.192290 - H11 38.443577 14.459247 38.210648 - H12 38.282069 16.126623 37.872764 - H21 40.652656 14.450036 37.109262 - H22 40.491148 16.117412 36.771377 - C1 31.504702 10.771809 65.400232 - C2 31.915073 10.520075 66.649691 - H11 31.864280 11.544863 64.832697 - H12 30.798981 10.211092 64.913861 - H21 32.620794 11.080793 67.136062 - H22 31.555495 9.747022 67.217226 - C1 41.944866 50.441258 29.281146 - C2 43.053741 50.402716 30.030699 - H11 41.449710 51.307351 29.049395 - H12 41.504695 49.607675 28.880654 - H21 43.493912 51.236299 30.431190 - H22 43.548897 49.536624 30.262450 - C1 46.133549 28.837881 51.624780 - C2 45.269375 28.966320 50.610075 - H11 47.150679 28.847663 51.504976 - H12 45.845341 28.719761 52.600479 - H21 45.557583 29.084440 49.634376 - H22 44.252244 28.956538 50.729878 - C1 47.745114 38.750052 41.881833 - C2 46.709202 39.352965 42.478745 - H11 48.055599 38.970644 40.931075 - H12 48.308412 38.020910 42.329103 - H21 46.145904 40.082108 42.031475 - H22 46.398717 39.132373 43.429503 - C1 1.355998 38.746448 77.831667 - C2 2.076732 39.873028 77.897080 - H11 0.355244 38.703087 78.045244 - H12 1.748819 37.839548 77.562913 - H21 1.683911 40.779928 78.165834 - H22 3.077486 39.916389 77.683503 - C1 3.378819 58.290441 9.844625 - C2 4.162325 58.469762 10.915551 - H11 2.780607 57.469467 9.713677 - H12 3.316151 58.960160 9.072256 - H21 4.224992 57.800044 11.687920 - H22 4.760537 59.290737 11.046499 - C1 10.569278 72.191971 30.072752 - C2 10.768966 70.988021 30.623707 - H11 10.162460 72.984109 30.578737 - H12 10.807660 72.415352 29.102042 - H21 10.530584 70.764640 31.594418 - H22 11.175784 70.195883 30.117723 - C1 63.749962 67.502203 53.905733 - C2 65.076633 67.348160 54.001314 - H11 63.211569 68.141454 54.497759 - H12 63.169320 66.992886 53.233085 - H21 65.657274 67.857477 54.673963 - H22 65.615026 66.708909 53.409288 - C1 30.281742 50.350306 36.390350 - C2 29.607392 50.685127 35.283071 - H11 31.133613 50.827940 36.698871 - H12 29.998678 49.590254 37.015810 - H21 29.890456 51.445180 34.657611 - H22 28.755521 50.207494 34.974550 - C1 35.510983 5.374778 29.318361 - C2 35.929524 4.108628 29.197488 - H11 34.525993 5.651104 29.268938 - H12 36.142936 6.166436 29.469740 - H21 35.297571 3.316970 29.046110 - H22 36.914514 3.832302 29.246912 - C1 3.030935 9.730105 5.209992 - C2 1.693084 9.744779 5.263463 - H11 3.601095 10.574114 5.102429 - H12 3.589240 8.873718 5.272453 - H21 1.134779 10.601165 5.201003 - H22 1.122924 8.900769 5.371027 - C1 21.188861 64.569026 51.116089 - C2 20.654259 65.775191 50.887425 - H11 22.104158 64.430902 51.554446 - H12 20.724496 63.689760 50.870608 - H21 21.118625 66.654456 51.132906 - H22 19.738962 65.913315 50.449068 - C1 30.688283 65.341426 11.081817 - C2 32.010131 65.197429 10.924002 - H11 30.123078 66.000128 10.538073 - H12 30.138523 64.804184 11.758676 - H21 32.559891 65.734671 10.247143 - H22 32.575336 64.538726 11.467746 - C1 51.222566 47.326276 55.790029 - C2 50.765410 46.206085 55.216356 - H11 52.189142 47.444223 56.107556 - H12 50.641597 48.153200 55.956389 - H21 51.346379 45.379161 55.049996 - H22 49.798835 46.088138 54.898828 - C1 58.018354 45.765783 46.075456 - C2 58.460975 44.513116 46.242290 - H11 58.636217 46.581128 46.025834 - H12 57.027146 46.007051 45.984356 - H21 59.452183 44.271848 46.333390 - H22 57.843112 43.697771 46.291913 - C1 70.358909 35.649357 64.645351 - C2 71.248634 36.567989 65.042122 - H11 70.589372 34.660253 64.512825 - H12 69.377971 35.863605 64.443205 - H21 72.229571 36.353741 65.244269 - H22 71.018171 37.557093 65.174649 - C1 23.466920 43.620268 37.126682 - C2 22.187703 43.848387 37.449926 - H11 24.208779 44.318772 37.230320 - H12 23.804068 42.729347 36.750391 - H21 21.850555 44.739308 37.826218 - H22 21.445844 43.149883 37.346289 - C1 13.708672 21.926212 58.637331 - C2 13.701043 23.254634 58.469526 - H11 14.132046 21.275090 57.969650 - H12 13.291733 21.456824 59.446552 - H21 14.117982 23.724023 57.660305 - H22 13.277669 23.905757 59.137207 - C1 17.379531 52.533631 11.815826 - C2 18.497368 52.921750 11.189149 - H11 16.439979 52.672321 11.432405 - H12 17.376197 52.067567 12.727844 - H21 18.500702 53.387814 10.277131 - H22 19.436919 52.783061 11.572570 - C1 14.780879 65.541996 24.926770 - C2 15.372708 64.628263 25.706354 - H11 13.784430 65.772075 24.982956 - H12 15.278126 66.082643 24.213012 - H21 14.875461 64.087616 26.420112 - H22 16.369157 64.398184 25.650167 - C1 49.702117 11.204574 0.940667 - C2 48.699988 12.092431 0.959855 - H11 49.559446 10.193639 0.859063 - H12 50.690075 11.466610 1.006088 - H21 47.712030 11.830396 0.894434 - H22 48.842660 13.103366 1.041459 - C1 39.667404 5.755579 44.311969 - C2 38.834974 6.804173 44.332688 - H11 40.684723 5.840430 44.394834 - H12 39.352233 4.786248 44.211627 - H21 39.150145 7.773504 44.433029 - H22 37.817655 6.719322 44.249823 - C1 56.689404 42.266928 73.264819 - C2 56.770175 41.856533 74.536815 - H11 55.838563 42.190694 72.699786 - H12 57.472116 42.689325 72.756935 - H21 55.987463 41.434136 75.044699 - H22 57.621016 41.932767 75.101847 - C1 20.306384 2.040341 29.758701 - C2 21.151285 1.002364 29.799506 - H11 19.289391 1.938421 29.692813 - H12 20.610710 3.017786 29.790170 - H21 20.846959 0.024919 29.768037 - H22 22.168278 1.104284 29.865394 - C1 35.219708 17.553670 44.150803 - C2 35.099554 16.725755 45.196289 - H11 35.801851 17.349943 43.333118 - H12 34.738912 18.455735 44.086630 - H21 35.580350 15.823690 45.260462 - H22 34.517411 16.929482 46.013974 - C1 39.804245 48.239863 33.780065 - C2 39.962203 47.472278 32.694346 - H11 38.889599 48.528479 34.139406 - H12 40.585656 48.598696 34.336517 - H21 39.180792 47.113445 32.137894 - H22 40.876849 47.183661 32.335005 - C1 35.949577 51.336397 34.591618 - C2 35.702594 50.662731 35.722147 - H11 35.950903 52.358888 34.532344 - H12 36.156577 50.882136 33.697302 - H21 35.495593 51.116992 36.616463 - H22 35.701267 49.640240 35.781421 - C1 73.386173 10.794254 47.974112 - C2 73.011217 10.150849 49.086928 - H11 73.131154 10.486894 47.030980 - H12 73.957464 11.644319 47.978595 - H21 72.439926 9.300784 49.082446 - H22 73.266236 10.458208 50.030061 - C1 7.534276 17.014457 46.979613 - C2 6.743997 18.058435 46.699451 - H11 7.937074 16.843581 47.905658 - H12 7.798070 16.304747 46.289882 - H21 6.480202 18.768144 47.389182 - H22 6.341199 18.229310 45.773406 - C1 6.194632 51.875830 35.758525 - C2 5.291856 52.796103 36.120484 - H11 7.091844 51.746776 36.235347 - H12 6.058902 51.228642 34.976394 - H21 5.427586 53.443292 36.902615 - H22 4.394644 52.925157 35.643662 - C1 42.609815 21.367482 50.911043 - C2 42.294860 20.094295 51.180705 - H11 43.240820 21.644841 50.153476 - H12 42.244473 22.164045 51.441153 - H21 42.660202 19.297732 50.650595 - H22 41.663855 19.816935 51.938273 - C1 31.919471 69.590868 5.090947 - C2 32.998901 68.844616 5.357142 - H11 31.957343 70.474971 4.575262 - H12 30.971110 69.336222 5.382099 - H21 33.947263 69.099263 5.065991 - H22 32.961029 67.960513 5.872827 - C1 74.880594 64.409645 4.596804 - C2 73.917861 65.340115 4.579741 - H11 75.419685 64.170121 5.434070 - H12 75.153559 63.864324 3.773931 - H21 73.644896 65.885436 5.402614 - H22 73.378770 65.579639 3.742476 - C1 43.887497 7.236466 70.138384 - C2 43.871856 7.488398 71.453377 - H11 44.413133 7.797952 69.462037 - H12 43.375054 6.462478 69.705546 - H21 44.384299 8.262386 71.886214 - H22 43.346221 6.926912 72.129723 - C1 69.904799 10.670750 24.495011 - C2 71.109535 11.239609 24.361103 - H11 69.754771 9.657612 24.488134 - H12 69.038643 11.204060 24.614838 - H21 71.975690 10.706300 24.241276 - H22 71.259562 12.252747 24.367980 - C1 61.279231 33.215938 42.441044 - C2 61.350993 34.196568 43.349965 - H11 60.401748 32.904541 42.014361 - H12 62.096184 32.700184 42.101060 - H21 60.534040 34.712322 43.689948 - H22 62.228477 34.507965 43.776647 - C1 77.078552 22.007808 0.769677 - C2 77.299364 22.445641 2.015656 - H11 77.257961 21.045227 0.469253 - H12 76.712889 22.601080 0.019128 - H21 77.665026 21.852369 2.766205 - H22 77.119954 23.408222 2.316080 - C1 17.167773 29.206659 49.266131 - C2 16.874557 27.977714 48.822691 - H11 16.458901 29.885250 49.559423 - H12 18.123968 29.564673 49.346877 - H21 15.918362 27.619700 48.741946 - H22 17.583429 27.299124 48.529400 - C1 56.285388 75.760036 65.541539 - C2 57.491725 76.294983 65.768486 - H11 55.410888 76.288438 65.612560 - H12 56.142355 74.780410 65.279089 - H21 57.634758 77.274608 66.030935 - H22 58.366225 75.766581 65.697464 - C1 29.619152 53.639119 26.019953 - C2 30.160296 52.567146 25.427535 - H11 29.799618 54.601550 25.719683 - H12 28.982237 53.580887 26.819923 - H21 30.797211 52.625379 24.627565 - H22 29.979830 51.604715 25.727805 - C1 44.166313 35.927792 16.172669 - C2 43.201044 36.658890 15.601116 - H11 45.037044 36.326784 16.535485 - H12 44.109776 34.912125 16.291953 - H21 43.257581 37.674556 15.481832 - H22 42.330313 36.259897 15.238300 - C1 19.248037 5.826676 52.400722 - C2 18.906843 4.532151 52.427409 - H11 19.229538 6.432688 53.226199 - H12 19.554331 6.312584 51.552736 - H21 18.600549 4.046243 53.275396 - H22 18.925342 3.926139 51.601933 - C1 19.736178 23.573457 34.091039 - C2 21.038131 23.326298 33.899330 - H11 19.318947 24.504526 34.001415 - H12 19.055225 22.850865 34.342369 - H21 21.719085 24.048890 33.648001 - H22 21.455363 22.395229 33.988955 - C1 63.428703 19.567905 24.366196 - C2 64.197980 20.532273 24.886894 - H11 63.564803 18.571226 24.558843 - H12 62.643726 19.751147 23.734344 - H21 64.982958 20.349031 25.518746 - H22 64.061881 21.528952 24.694247 - C1 12.645605 26.360708 29.366021 - C2 12.956772 27.415524 30.129865 - H11 12.519317 26.416030 28.351134 - H12 12.509424 25.415657 29.736612 - H21 13.092952 28.360575 29.759273 - H22 13.083060 27.360202 31.144751 - C1 10.775171 46.710914 13.614566 - C2 10.605139 47.035632 14.902420 - H11 10.316360 47.203496 12.842647 - H12 11.377403 45.944436 13.300192 - H21 10.002907 47.802111 15.216794 - H22 11.063950 46.543050 15.674339 - C1 71.419426 45.898638 5.344489 - C2 72.200460 46.650606 6.130270 - H11 70.881134 45.096512 5.684841 - H12 71.298924 46.066486 4.341339 - H21 72.320963 46.482758 7.133420 - H22 72.738752 47.452732 5.789918 - C1 7.721322 57.149270 4.607244 - C2 7.472224 58.431562 4.312970 - H11 7.388681 56.364604 4.039218 - H12 8.264073 56.852334 5.423487 - H21 6.929473 58.728498 3.496727 - H22 7.804864 59.216228 4.880996 - C1 13.427616 65.132437 57.100003 - C2 12.440474 65.527250 56.286005 - H11 14.100335 65.776836 57.525684 - H12 13.587543 64.155018 57.360923 - H21 12.280547 66.504669 56.025085 - H22 11.767755 64.882851 55.860324 - C1 7.850832 64.679881 64.164247 - C2 9.003566 65.360289 64.198468 - H11 6.930836 65.128828 64.131743 - H12 7.798509 63.657016 64.167885 - H21 9.055890 66.383154 64.194829 - H22 9.923563 64.911341 64.230972 - C1 2.595337 27.739078 45.815122 - C2 1.671557 27.170289 46.599998 - H11 2.387281 28.491474 45.152087 - H12 3.582595 27.466449 45.816122 - H21 0.684300 27.442917 46.598998 - H22 1.879614 26.417892 47.263033 - C1 72.145962 10.826428 29.308959 - C2 71.467415 11.861643 28.798250 - H11 72.593926 10.843924 30.229842 - H12 72.270346 9.935737 28.818854 - H21 71.343031 12.752334 29.288354 - H22 71.019450 11.844147 27.877367 - C1 64.922657 28.623763 15.401653 - C2 64.228011 28.430918 16.530014 - H11 65.792811 28.129864 15.182792 - H12 64.638431 29.280326 14.668751 - H21 64.512238 27.774356 17.262916 - H22 63.357857 28.924817 16.748874 - C1 63.804498 28.822925 68.574986 - C2 64.109040 27.597941 68.128231 - H11 64.465754 29.605065 68.573702 - H12 62.886365 29.074047 68.953103 - H21 65.027173 27.346818 67.750114 - H22 63.447784 26.815801 68.129516 - C1 49.359825 33.108967 21.414071 - C2 48.628953 34.158745 21.018199 - H11 48.953852 32.209942 21.689649 - H12 50.382281 33.122515 21.472408 - H21 47.606497 34.145197 20.959862 - H22 49.034926 35.057770 20.742621 - C1 47.287302 19.747738 33.302294 - C2 45.953469 19.664292 33.385032 - H11 47.832573 19.336670 32.538942 - H12 47.867108 20.229193 33.995858 - H21 45.373663 19.182837 32.691468 - H22 45.408198 20.075361 34.148384 - C1 20.803249 7.143817 39.882737 - C2 19.566002 7.127480 40.394474 - H11 21.346654 6.296888 39.691885 - H12 21.303449 8.004527 39.641944 - H21 19.065802 6.266769 40.635267 - H22 19.022597 7.974409 40.585327 - C1 48.251338 70.279391 31.424040 - C2 49.156067 69.881663 30.520603 - H11 48.345396 71.135509 31.978314 - H12 47.394149 69.758753 31.631808 - H21 50.013255 70.402301 30.312836 - H22 49.062008 69.025545 29.966329 - C1 51.925486 44.404591 46.168815 - C2 50.631653 44.625487 45.904008 - H11 52.424474 44.840450 46.949867 - H12 52.517834 43.782409 45.611126 - H21 50.039305 45.247669 46.461698 - H22 50.132665 44.189628 45.122957 - C1 78.583297 32.443675 30.282834 - C2 77.286348 32.122016 30.196940 - H11 79.133100 32.348294 31.141684 - H12 79.127460 32.810372 29.496434 - H21 76.742185 31.755320 30.983340 - H22 76.736545 32.217397 29.338090 - C1 8.764308 57.748285 53.964295 - C2 10.096576 57.628666 54.024903 - H11 8.287381 58.598021 53.648869 - H12 8.117478 56.999447 54.228599 - H21 10.743406 58.377504 53.760599 - H22 10.573503 56.778930 54.340329 - C1 67.758697 47.671412 41.867843 - C2 67.896082 48.964585 42.186823 - H11 67.413704 47.347376 40.959557 - H12 67.987808 46.904667 42.507073 - H21 67.666971 49.731330 41.547593 - H22 68.241076 49.288621 43.095109 - C1 48.040583 72.465296 18.067365 - C2 48.831919 71.472120 17.642735 - H11 48.386532 73.397843 18.311659 - H12 47.027150 72.370484 18.181244 - H21 49.845351 71.566933 17.528857 - H22 48.485970 70.539573 17.398442 - C1 49.119542 3.321990 49.115032 - C2 49.806141 4.344587 49.640198 - H11 49.453431 2.765168 48.322902 - H12 48.206513 3.016261 49.464191 - H21 50.719169 4.650316 49.291039 - H22 49.472251 4.901408 50.432328 - C1 73.804063 17.926674 24.372109 - C2 73.292626 18.345376 25.536601 - H11 74.187119 16.987695 24.228617 - H12 73.852398 18.512482 23.533362 - H21 73.244291 17.759568 26.375348 - H22 72.909570 19.284355 25.680092 - C1 43.381651 74.271718 25.878720 - C2 42.894187 74.607263 27.079849 - H11 43.343280 73.321218 25.499140 - H12 43.831192 74.939189 25.245159 - H21 42.444646 73.939792 27.713409 - H22 42.932558 75.557763 27.459429 - C1 65.796250 5.281625 18.008767 - C2 65.510713 4.031901 17.622013 - H11 65.953540 6.053367 17.354033 - H12 65.879809 5.564013 18.989725 - H21 65.427155 3.749512 16.641055 - H22 65.353424 3.260158 18.276748 - C1 42.563988 31.310973 52.605013 - C2 43.254708 32.292762 53.198240 - H11 42.932029 30.749023 51.831863 - H12 41.613330 31.044794 52.877782 - H21 44.205365 32.558941 52.925471 - H22 42.886666 32.854712 53.971390 - C1 36.100294 29.073945 48.840675 - C2 34.801430 28.778565 48.977146 - H11 36.626509 29.633136 49.518470 - H12 36.669658 28.763903 48.047768 - H21 34.232065 29.088607 49.770054 - H22 34.275215 28.219373 48.299351 - C1 16.321997 5.852634 15.072798 - C2 15.163813 5.636253 14.436629 - H11 16.465189 5.655806 16.067663 - H12 17.155721 6.231978 14.614534 - H21 14.330089 5.256909 14.894892 - H22 15.020620 5.833082 13.441763 - C1 11.963124 15.010492 62.089563 - C2 12.546106 13.932646 62.629286 - H11 10.948307 15.122339 62.008072 - H12 12.486201 15.807798 61.715803 - H21 12.023028 13.135340 63.003047 - H22 13.560923 13.820799 62.710777 - C1 20.147885 66.637862 67.502127 - C2 21.317491 67.255349 67.293194 - H11 19.249803 67.128489 67.543815 - H12 20.059416 65.626391 67.636672 - H21 21.405960 68.266821 67.158649 - H22 22.215573 66.764723 67.251505 - C1 17.804664 9.606720 30.533566 - C2 17.719011 8.295711 30.275036 - H11 18.208258 10.285700 29.881567 - H12 17.473318 10.033566 31.403633 - H21 18.050357 7.868865 29.404969 - H22 17.315418 7.616731 30.927035 - C1 78.655769 46.629286 54.757145 - C2 78.192198 45.484226 54.240560 - H11 78.128025 47.507023 54.748903 - H12 79.574532 46.717397 55.201123 - H21 77.273435 45.396116 53.796583 - H22 78.719942 44.606490 54.248802 - C1 10.149778 46.143595 10.119351 - C2 9.594499 44.941878 10.320506 - H11 9.688246 47.026107 10.358444 - H12 11.079682 46.274720 9.710587 - H21 8.664595 44.810753 10.729270 - H22 10.056030 44.059366 10.081414 - C1 35.263783 38.004408 57.993765 - C2 36.399609 37.343012 57.738076 - H11 34.711528 37.869904 58.845779 - H12 34.857981 38.696793 57.357424 - H21 36.805411 36.650626 58.374417 - H22 36.951864 37.477516 56.886062 - C1 70.382569 59.433050 40.189444 - C2 71.465335 58.664197 40.017968 - H11 69.423767 59.092209 40.073126 - H12 70.428068 60.422411 40.450401 - H21 71.419836 57.674836 39.757011 - H22 72.424137 59.005038 40.134286 - C1 31.355275 55.630030 30.217667 - C2 32.245829 54.633497 30.135463 - H11 31.617166 56.619194 30.262066 - H12 30.342210 55.481432 30.242606 - H21 33.258893 54.782095 30.110523 - H22 31.983937 53.644333 30.091064 - C1 17.664376 59.086183 20.517920 - C2 17.690787 60.423153 20.586741 - H11 16.821885 58.528591 20.686153 - H12 18.484591 58.516054 20.291637 - H21 16.870572 60.993282 20.813024 - H22 18.533278 60.980745 20.418508 - C1 65.891190 77.847981 73.920562 - C2 66.084338 77.409371 75.170857 - H11 64.989870 77.796270 73.436878 - H12 66.629592 78.269655 73.349636 - H21 65.345936 76.987697 75.741784 - H22 66.985659 77.461081 75.654542 - C1 11.029744 62.810065 70.063349 - C2 11.034116 61.497145 70.326301 - H11 10.174795 63.351628 69.905943 - H12 11.881005 63.375938 69.998957 - H21 10.182855 60.931272 70.390692 - H22 11.889064 60.955583 70.483707 - C1 48.815436 15.812040 44.111147 - C2 49.673903 15.768702 45.137830 - H11 48.134322 16.564906 43.975940 - H12 48.772441 15.095730 43.380356 - H21 49.716898 16.485013 45.868620 - H22 50.355017 15.015837 45.273036 - C1 59.419318 42.167323 13.968977 - C2 60.466239 42.979361 13.775400 - H11 58.494028 42.332029 13.561897 - H12 59.461540 41.317670 14.539338 - H21 60.424017 43.829014 13.205040 - H22 61.391529 42.814655 14.182481 - C1 20.699955 73.354322 53.034549 - C2 21.444844 72.282271 52.736609 - H11 19.986000 73.737658 52.408190 - H12 20.785604 73.875250 53.912217 - H21 21.359195 71.761342 51.858940 - H22 22.158799 71.898934 53.362967 - C1 31.600507 38.541602 27.596170 - C2 30.669087 38.621324 26.637513 - H11 31.523849 39.018917 28.499108 - H12 32.462808 37.997044 27.501849 - H21 29.806785 39.165882 26.731834 - H22 30.745744 38.144009 25.734574 - C1 70.984111 18.275804 3.071668 - C2 70.007198 18.035754 3.955374 - H11 71.299345 19.217299 2.820234 - H12 71.492895 17.536790 2.577704 - H21 69.498414 18.774768 4.449338 - H22 69.691964 17.094259 4.206808 - C1 23.417934 46.799072 26.241177 - C2 23.044894 48.084872 26.219278 - H11 22.824816 46.033245 25.908424 - H12 24.325708 46.480337 26.592402 - H21 22.137121 48.403606 25.868053 - H22 23.638012 48.850698 26.552031 - C1 73.643991 1.854793 26.141801 - C2 74.415102 2.949214 26.118312 - H11 73.588124 1.186620 25.367574 - H12 73.049434 1.599832 26.935842 - H21 75.009659 3.204175 25.324271 - H22 74.470969 3.617387 26.892538 - C1 11.090998 73.729390 20.803661 - C2 10.175784 72.985218 20.170011 - H11 11.753924 73.349453 21.485702 - H12 11.200046 74.737029 20.656097 - H21 10.066735 71.977578 20.317575 - H22 9.512857 73.365155 19.487970 - C1 65.593952 21.118524 2.153587 - C2 65.494619 20.779619 0.862000 - H11 64.783747 21.274713 2.760362 - H12 66.487944 21.248197 2.636254 - H21 64.600627 20.649946 0.379334 - H22 66.304824 20.623429 0.255225 - C1 24.304221 51.187099 66.580686 - C2 23.286496 52.019914 66.832830 - H11 25.288677 51.454677 66.671531 - H12 24.178207 50.217050 66.277159 - H21 23.412510 52.989963 67.136356 - H22 22.302040 51.752336 66.741985 - C1 57.054002 17.634753 4.431546 - C2 57.845121 18.710816 4.335944 - H11 56.111898 17.589211 4.032334 - H12 57.328804 16.772645 4.911399 - H21 57.570318 19.572923 3.856091 - H22 58.787224 18.756358 4.735156 - C1 43.007439 39.321477 20.030126 - C2 42.915500 40.126468 21.096173 - H11 43.445659 38.396152 20.057341 - H12 42.646770 39.567799 19.103710 - H21 43.276169 39.880146 22.022589 - H22 42.477280 41.051793 21.068958 - C1 66.206498 63.028620 17.222710 - C2 65.181180 63.863278 17.434819 - H11 66.329913 62.146009 17.727458 - H12 66.947929 63.207204 16.539050 - H21 64.439749 63.684693 18.118479 - H22 65.057765 64.745888 16.930072 - C1 7.565612 32.165768 49.031309 - C2 8.179631 33.252865 48.547447 - H11 8.060642 31.392945 49.485944 - H12 6.552662 32.021636 48.984807 - H21 9.192581 33.396998 48.593949 - H22 7.684601 34.025688 48.092812 - C1 50.806819 39.457610 1.021789 - C2 51.597670 38.377208 1.007461 - H11 49.784279 39.409438 0.988682 - H12 51.162282 40.417093 1.066982 - H21 51.242206 37.417725 0.962268 - H22 52.620209 38.425381 1.040568 - C1 9.309972 17.982330 30.068825 - C2 8.762888 16.826207 29.672594 - H11 9.193627 18.864974 29.562458 - H12 9.887776 18.074866 30.909410 - H21 8.185083 16.733672 28.832009 - H22 8.879232 15.943563 30.178961 - C1 20.787834 28.071291 60.654777 - C2 20.064147 29.018194 61.265164 - H11 21.501963 27.511957 61.130351 - H12 20.684129 27.831920 59.664347 - H21 20.167852 29.257565 62.255593 - H22 19.350018 29.577527 60.789590 - C1 12.340580 78.234949 55.288629 - C2 11.227331 78.017078 56.000057 - H11 12.503192 77.837903 54.358621 - H12 13.116984 78.815768 55.618555 - H21 10.450928 77.436259 55.670131 - H22 11.064719 78.414124 56.930065 - C1 28.554232 6.668410 67.966604 - C2 29.254285 5.527790 67.923793 - H11 28.856756 7.534135 67.510530 - H12 27.661221 6.764787 68.458789 - H21 30.147297 5.431413 67.431608 - H22 28.951762 4.662065 68.379867 - C1 61.692058 39.472927 21.478875 - C2 62.065408 40.580576 20.825694 - H11 61.119065 38.735442 21.058401 - H12 61.950133 39.276121 22.450301 - H21 61.807332 40.777382 19.854269 - H22 62.638400 41.318062 21.246169 - C1 12.732059 32.364265 2.573186 - C2 11.404633 32.295552 2.411508 - H11 13.403763 32.113394 1.841831 - H12 13.180026 32.673094 3.440916 - H21 10.956666 31.986723 1.543779 - H22 10.732928 32.546423 3.142864 - C1 26.244177 35.612533 2.620514 - C2 27.206311 35.456395 1.702451 - H11 25.781218 36.506931 2.806861 - H12 25.895585 34.849836 3.208545 - H21 27.554903 36.219092 1.114419 - H22 27.669270 34.561997 1.516104 - C1 67.445336 78.226740 64.484068 - C2 66.908368 77.123029 65.019239 - H11 68.454040 78.370755 64.380246 - H12 66.889560 79.013695 64.136479 - H21 67.464144 76.336074 65.366829 - H22 65.899663 76.979014 65.123062 - C1 78.402648 56.186269 11.350052 - C2 78.253721 54.875909 11.118328 - H11 78.293203 56.903592 10.627229 - H12 78.637712 56.574224 12.268333 - H21 78.018657 54.487954 10.200047 - H22 78.363166 54.158586 11.841151 - C1 61.632455 38.423277 5.270807 - C2 60.763567 39.380146 4.921012 - H11 61.975669 37.707928 4.623131 - H12 62.022139 38.331515 6.213531 - H21 60.373882 39.471908 3.978288 - H22 60.420353 40.095494 5.568689 - C1 7.860160 19.271835 42.399107 - C2 7.072984 18.314781 42.906378 - H11 8.878408 19.187011 42.328538 - H12 7.505887 20.163925 42.041797 - H21 7.427257 17.422691 43.263688 - H22 6.054736 18.399605 42.976947 - C1 69.856904 63.479525 9.222674 - C2 68.611912 63.788933 9.606315 - H11 70.484864 64.140701 8.756287 - H12 70.279085 62.557365 9.365463 - H21 68.189731 64.711093 9.463526 - H22 67.983953 63.127757 10.072702 - C1 17.769326 48.281076 21.555333 - C2 18.268754 47.279007 22.289738 - H11 17.609839 49.224321 21.921197 - H12 17.507550 48.183067 20.570005 - H21 18.530530 47.377016 23.275066 - H22 18.428241 46.335762 21.923873 - C1 17.521888 46.051716 28.925489 - C2 17.896999 46.497237 27.719784 - H11 17.008970 45.177029 29.069856 - H12 17.718403 46.550611 29.798123 - H21 17.700484 45.998343 26.847150 - H22 18.409916 47.371924 27.575418 - C1 26.801146 64.254449 12.097853 - C2 25.535387 64.690871 12.115461 - H11 27.061172 63.284011 11.898752 - H12 27.608777 64.856768 12.282102 - H21 24.727756 64.088552 11.931212 - H22 25.275362 65.661309 12.314562 - C1 53.703777 10.351674 4.839083 - C2 52.619897 11.001346 5.281860 - H11 53.701437 9.360987 4.579200 - H12 54.620359 10.794367 4.725488 - H21 51.703315 10.558653 5.395455 - H22 52.622236 11.992032 5.541742 - C1 37.137315 38.446157 54.349853 - C2 37.408881 39.075052 53.199347 - H11 36.222719 38.479835 54.809618 - H12 37.822847 37.882012 54.860528 - H21 36.723349 39.639197 52.688671 - H22 38.323477 39.041374 52.739582 - C1 55.599686 70.820901 15.377027 - C2 54.741562 70.732627 16.401112 - H11 56.150128 71.659991 15.172221 - H12 55.773064 70.056270 14.718026 - H21 54.568184 71.497259 17.060114 - H22 54.191120 69.893537 16.605918 - C1 17.526341 22.731937 1.906455 - C2 17.865319 21.441296 2.017175 - H11 16.556787 23.060098 1.870680 - H12 18.209970 23.492421 1.848838 - H21 17.181690 20.680812 2.074792 - H22 18.834873 21.113135 2.052950 - C1 34.097808 8.796385 68.772432 - C2 34.892076 9.872949 68.827836 - H11 33.078834 8.840984 68.865742 - H12 34.446824 7.843716 68.632388 - H21 34.543060 10.825618 68.967879 - H22 35.911050 9.828350 68.734525 - C1 60.946794 63.231825 72.344503 - C2 62.253629 63.449421 72.538808 - H11 60.307781 62.931889 73.086598 - H12 60.483503 63.348222 71.438513 - H21 62.716920 63.333024 73.444797 - H22 62.892642 63.749357 71.796713 - C1 54.902971 28.779128 43.007308 - C2 54.966537 29.843963 42.197983 - H11 54.503448 28.809275 43.949898 - H12 55.248877 27.850803 42.747376 - H21 54.620631 30.772288 42.457915 - H22 55.366060 29.813816 41.255393 - C1 0.229781 47.059384 31.226107 - C2 0.237462 45.723902 31.129405 - H11 0.387336 47.562930 32.103957 - H12 0.065748 47.682303 30.429823 - H21 0.401495 45.100982 31.925689 - H22 0.079907 45.220356 30.251555 - C1 70.220985 29.246484 37.297574 - C2 70.858094 29.570010 38.429981 - H11 69.220564 29.406185 37.147057 - H12 70.684012 28.813891 36.492917 - H21 70.395068 30.002603 39.234638 - H22 71.858516 29.410308 38.580497 - C1 60.544323 41.057521 37.139645 - C2 61.816908 40.914342 37.530730 - H11 59.780026 41.293145 37.779437 - H12 60.235207 40.942667 36.169975 - H21 62.126025 41.029196 38.500400 - H22 62.581206 40.678719 36.890938 - C1 7.385966 55.097720 56.755726 - C2 8.534538 54.439151 56.955703 - H11 6.625477 55.127699 57.441117 - H12 7.177645 55.623238 55.901655 - H21 8.742858 53.913633 57.809774 - H22 9.295026 54.409172 56.270311 - C1 51.845029 6.023950 24.389002 - C2 52.145689 5.864204 23.094010 - H11 52.081535 6.864616 24.924118 - H12 51.354919 5.318027 24.946201 - H21 52.635799 6.570126 22.536812 - H22 51.909183 5.023538 22.558894 - C1 2.296128 56.183154 23.894974 - C2 2.116690 57.229977 24.710379 - H11 2.075741 56.202006 22.894936 - H12 2.667870 55.281317 24.207227 - H21 1.744949 58.131814 24.398127 - H22 2.337077 57.211125 25.710418 - C1 49.524557 37.253475 61.021848 - C2 49.484761 36.013519 61.525681 - H11 50.372808 37.679988 60.637710 - H12 48.709875 37.872853 60.981008 - H21 50.299443 35.394141 61.566522 - H22 48.636511 35.587006 61.909819 - C1 4.003846 74.874593 78.171276 - C2 4.319473 73.782604 78.878991 - H11 4.012418 75.821869 78.560631 - H12 3.729047 74.848399 77.184968 - H21 4.594272 73.808798 79.865299 - H22 4.310902 72.835328 78.489636 - C1 31.872735 48.167807 66.309564 - C2 31.262429 49.336139 66.545033 - H11 32.535318 48.021328 65.542406 - H12 31.724940 47.328807 66.878106 - H21 31.410224 50.175139 65.976490 - H22 30.599846 49.482618 67.312191 - C1 20.240997 69.062983 48.578686 - C2 20.508067 67.793304 48.247764 - H11 20.598267 69.512656 49.426717 - H12 19.658455 69.684273 48.009785 - H21 21.090609 67.172014 48.816664 - H22 20.150797 67.343631 47.399733 - C1 11.780471 60.450811 50.838768 - C2 12.306681 61.681013 50.787519 - H11 12.338828 59.602970 50.974441 - H12 10.778261 60.260987 50.746324 - H21 13.308892 61.870836 50.879963 - H22 11.748325 62.528854 50.651846 - C1 65.305257 71.890333 50.840622 - C2 64.993703 72.748372 51.820226 - H11 66.238884 71.487239 50.718725 - H12 64.634422 71.569678 50.136233 - H21 65.664538 73.069027 52.524615 - H22 64.060076 73.151466 51.942123 - C1 5.058328 64.432185 39.558136 - C2 6.378348 64.287774 39.730229 - H11 4.586897 65.341324 39.543214 - H12 4.416336 63.644856 39.427899 - H21 7.020340 65.075103 39.860465 - H22 6.849779 63.378635 39.745150 - C1 22.205984 12.135006 77.884874 - C2 22.124818 10.884851 77.412172 - H11 21.387675 12.702059 78.125345 - H12 23.092755 12.622446 78.043123 - H21 21.238047 10.397411 77.253923 - H22 22.943126 10.317798 77.171702 - C1 23.868616 6.668209 59.688960 - C2 24.210087 5.920523 60.745977 - H11 23.547651 6.275197 58.799282 - H12 23.901554 7.691886 59.687054 - H21 24.177150 4.896846 60.747883 - H22 24.531053 6.313535 61.635655 - C1 49.044545 50.761409 57.404198 - C2 48.533206 51.397721 58.465593 - H11 48.738940 49.831782 57.101869 - H12 49.781459 51.154313 56.811250 - H21 47.796291 51.004817 59.058542 - H22 48.838810 52.327348 58.767922 - C1 57.083420 24.274349 77.973997 - C2 56.456982 24.662626 79.091914 - H11 57.742909 23.491497 77.939054 - H12 56.952325 24.729692 77.065988 - H21 56.588077 24.207283 79.999923 - H22 55.797493 25.445478 79.126857 - C1 15.287095 42.687319 40.849017 - C2 14.002184 42.672998 40.472560 - H11 15.738937 41.913379 41.344858 - H12 15.919063 43.473340 40.670713 - H21 13.370216 41.886978 40.650864 - H22 13.550341 43.446938 39.976718 - C1 61.635186 10.257077 54.411322 - C2 61.220325 11.530182 54.407718 - H11 62.605747 9.978916 54.239154 - H12 61.014557 9.461385 54.586531 - H21 61.840954 12.325874 54.232509 - H22 60.249764 11.808344 54.579886 - C1 71.947400 12.982067 20.368409 - C2 71.914039 14.177598 19.766319 - H11 71.705395 12.105502 19.897164 - H12 72.217544 12.850211 21.347510 - H21 71.643894 14.309454 18.787218 - H22 72.156043 15.054163 20.237564 - C1 57.575399 65.211278 5.174228 - C2 57.341432 64.002698 5.701026 - H11 57.408298 66.088162 5.676378 - H12 57.939849 65.353818 4.227728 - H21 56.976982 63.860158 6.647526 - H22 57.508533 63.125814 5.198876 - C1 45.681580 72.582125 6.722450 - C2 46.455678 73.121943 7.672339 - H11 45.139658 73.136398 6.053043 - H12 45.570556 71.572520 6.590635 - H21 46.566702 74.131548 7.804154 - H22 46.997600 72.567670 8.341746 - C1 74.967648 31.446035 69.260802 - C2 76.146352 30.814128 69.326149 - H11 74.783097 32.233425 68.632342 - H12 74.157972 31.191654 69.834143 - H21 76.956027 31.068510 68.752808 - H22 76.330903 30.026738 69.954609 - C1 36.874854 70.608206 30.552186 - C2 35.681696 70.871259 30.004375 - H11 37.763944 70.901562 30.136896 - H12 36.992183 70.092968 31.429549 - H21 35.564367 71.386498 29.127011 - H22 34.792606 70.577903 30.419665 - C1 69.365335 60.404909 79.474801 - C2 68.828677 59.182701 79.369308 - H11 70.373211 60.583948 79.441137 - H12 68.810124 61.256790 79.597448 - H21 69.383889 58.330820 79.246662 - H22 67.820801 59.003662 79.402973 - C1 38.639217 51.775514 73.021055 - C2 37.578628 52.592870 73.019886 - H11 39.449101 51.902162 73.635101 - H12 38.723930 50.959436 72.407995 - H21 37.493915 53.408949 73.632946 - H22 36.768744 52.466223 72.405840 - C1 55.975308 42.481499 27.084613 - C2 56.978863 42.293716 27.950948 - H11 55.079976 42.907534 27.341282 - H12 56.024151 42.213856 26.097200 - H21 56.930020 42.561358 28.938362 - H22 57.874195 41.867681 27.694280 - C1 43.777653 33.073672 33.043408 - C2 43.298572 34.285354 33.352003 - H11 43.182905 32.255749 32.881298 - H12 44.776502 32.869554 32.945221 - H21 42.299723 34.489472 33.450190 - H22 43.893320 35.103277 33.514113 - C1 51.129979 25.789098 9.050619 - C2 49.819303 25.796839 9.324459 - H11 51.603553 26.536565 8.534844 - H12 51.761949 25.035102 9.335414 - H21 49.187333 26.550835 9.039664 - H22 49.345729 25.049372 9.840235 - C1 8.354039 32.051729 60.124066 - C2 8.565001 32.238782 61.433046 - H11 7.429872 32.112088 59.686716 - H12 9.100262 31.833592 59.457305 - H21 7.818778 32.456919 62.099807 - H22 9.489168 32.178422 61.870396 - C1 46.599375 39.919357 68.571901 - C2 47.435308 39.252342 69.377648 - H11 46.888199 40.709830 67.988174 - H12 45.605450 39.691506 68.475988 - H21 48.429234 39.480193 69.473561 - H22 47.146484 38.461869 69.961375 - C1 61.201340 71.945937 36.780146 - C2 60.987618 70.807403 36.108594 - H11 60.973881 72.872497 36.407649 - H12 61.609071 71.979721 37.719091 - H21 60.579887 70.773618 35.169649 - H22 61.215077 69.880843 36.481091 - C1 28.250321 2.494736 28.947870 - C2 28.894067 3.484262 28.315928 - H11 27.345944 2.616011 29.413057 - H12 28.611703 1.538806 29.015720 - H21 28.532685 4.440192 28.248078 - H22 29.798444 3.362987 27.850740 - C1 21.285311 77.447868 54.071650 - C2 20.441466 78.476010 53.917474 - H11 21.280522 76.618388 53.470865 - H12 22.001876 77.410121 54.802481 - H21 19.724901 78.513757 53.186643 - H22 20.446255 79.305491 54.518259 - C1 74.669613 34.134603 41.401256 - C2 74.163188 32.896196 41.454196 - H11 75.653105 34.350997 41.588127 - H12 74.113285 34.962794 41.169732 - H21 74.719516 32.068005 41.685721 - H22 73.179696 32.679802 41.267326 - C1 77.935013 73.276433 64.725556 - C2 78.395217 73.884269 65.826315 - H11 76.940815 73.218186 64.486433 - H12 78.541034 72.821977 64.036200 - H21 77.789196 74.338725 66.515671 - H22 79.389416 73.942516 66.065438 - C1 10.504812 7.950808 25.582722 - C2 9.343440 7.907814 24.917675 - H11 11.086488 7.126068 25.757255 - H12 10.902743 8.811812 25.969151 - H21 8.945510 7.046810 24.531246 - H22 8.761765 8.732554 24.743142 - C1 38.537315 66.266480 57.261231 - C2 39.102248 66.105018 56.058027 - H11 38.158839 67.158777 57.592239 - H12 38.439276 65.510375 57.945116 - H21 39.200287 66.861122 55.374142 - H22 39.480725 65.212721 55.727019 - C1 30.094699 56.292927 56.084811 - C2 28.950628 56.476116 55.413645 - H11 31.014895 56.267137 55.635835 - H12 30.139517 56.164199 57.099909 - H21 28.905810 56.604844 54.398547 - H22 28.030433 56.501905 55.862621 - C1 11.301703 23.398528 48.710910 - C2 11.425696 24.698738 48.415953 - H11 12.046746 22.843800 49.142409 - H12 10.452073 22.856540 48.528203 - H21 12.275326 25.240726 48.598660 - H22 10.680653 25.253466 47.984454 - C1 74.451118 72.023925 65.868684 - C2 75.194167 71.034740 65.356519 - H11 73.438502 71.956264 66.006650 - H12 74.836979 72.925953 66.162725 - H21 74.808306 70.132712 65.062479 - H22 76.206783 71.102401 65.218553 - C1 74.899888 15.097993 47.757024 - C2 74.191016 15.659727 46.769666 - H11 75.313394 14.163083 47.694092 - H12 75.084310 15.559085 48.652784 - H21 74.006594 15.198634 45.873906 - H22 73.777511 16.594637 46.832599 - C1 25.480775 71.450127 53.787221 - C2 25.156902 72.664161 54.249983 - H11 26.432079 71.071460 53.812418 - H12 24.802654 70.804768 53.371688 - H21 25.835022 73.309520 54.665516 - H22 24.205597 73.042828 54.224786 - C1 18.232590 25.930183 9.301224 - C2 18.570792 24.643108 9.449475 - H11 18.239540 26.415632 8.399395 - H12 17.940370 26.530370 10.078004 - H21 18.863012 24.042922 8.672695 - H22 18.563842 24.157659 10.351304 - C1 35.534195 40.858307 77.915233 - C2 35.189869 41.857845 78.736989 - H11 36.505128 40.604075 77.711129 - H12 34.853698 40.269437 77.426193 - H21 35.870366 42.446714 79.226029 - H22 34.218935 42.112077 78.941093 - C1 51.930564 40.624346 25.123512 - C2 53.111451 40.618680 24.492327 - H11 51.833641 40.555411 26.140792 - H12 51.031419 40.698060 24.638632 - H21 54.010595 40.544966 24.977208 - H22 53.208373 40.687615 23.475047 - C1 29.360953 41.057375 10.313621 - C2 29.795041 39.790696 10.317256 - H11 29.986122 41.868604 10.322321 - H12 28.369635 41.314578 10.301855 - H21 30.786359 39.533493 10.329022 - H22 29.169872 38.979468 10.308555 - C1 46.079623 33.891370 8.702870 - C2 44.915349 33.956614 8.044742 - H11 46.642302 33.038352 8.771837 - H12 46.498997 34.689355 9.189027 - H21 44.495975 33.158629 7.558585 - H22 44.352669 34.809631 7.975776 - C1 72.466164 14.952613 25.334641 - C2 71.627575 14.038548 25.838798 - H11 72.181973 15.667864 24.658878 - H12 73.457698 15.008369 25.585154 - H21 70.636041 13.982793 25.588285 - H22 71.911766 13.323298 26.514561 - C1 47.974332 46.603840 13.626774 - C2 48.876515 45.637682 13.413405 - H11 48.166228 47.598720 13.477129 - H12 47.021453 46.423905 13.956394 - H21 49.829394 45.817617 13.083785 - H22 48.684619 44.642802 13.563050 - C1 19.010589 65.516978 56.741963 - C2 17.834048 64.920558 56.972085 - H11 19.904986 65.017962 56.735511 - H12 19.108594 66.519068 56.554309 - H21 17.736044 63.918467 57.159738 - H22 16.939652 65.419573 56.978537 - C1 43.110944 22.468263 54.864330 - C2 44.146783 23.309083 54.978258 - H11 42.578837 22.115935 55.665411 - H12 42.769329 22.111368 53.967152 - H21 44.488397 23.665978 55.875437 - H22 44.678890 23.661411 54.177177 - C1 16.893460 63.021030 59.036723 - C2 18.185825 62.680547 58.954345 - H11 16.506932 63.591373 59.794555 - H12 16.189891 62.737882 58.348377 - H21 18.889394 62.963696 59.642692 - H22 18.572353 62.110205 58.196514 - C1 27.197519 70.324128 60.208370 - C2 27.832560 69.185635 60.514109 - H11 26.773779 70.939964 60.908510 - H12 27.085606 70.668601 59.250342 - H21 27.944473 68.841162 61.472137 - H22 28.256300 68.569800 59.813969 - C1 65.394877 71.961185 21.869505 - C2 64.865643 70.733003 21.803144 - H11 66.302846 72.162421 22.298572 - H12 64.933311 72.795908 21.496412 - H21 65.327209 69.898280 22.176237 - H22 63.957673 70.531767 21.374077 - C1 43.591369 61.107340 79.697356 - C2 43.025024 62.319990 79.656698 - H11 43.056774 60.233776 79.687365 - H12 44.603670 60.958044 79.741641 - H21 42.012723 62.469286 79.612412 - H22 43.559618 63.193553 79.666689 - C1 20.918666 58.498337 27.018229 - C2 22.140929 59.039325 27.097766 - H11 20.736813 57.495946 27.123800 - H12 20.069550 59.044410 26.845568 - H21 22.990044 58.493252 27.270426 - H22 22.322781 60.041716 26.992194 - C1 2.050656 38.133764 49.133257 - C2 0.948350 38.888434 49.224450 - H11 2.999173 38.519663 49.113225 - H12 2.031923 37.111307 49.076368 - H21 0.967082 39.910890 49.281338 - H22 -0.000167 38.502535 49.244481 - C1 22.029660 62.997586 19.533831 - C2 22.257763 62.560877 18.288771 - H11 21.789145 62.379142 20.314013 - H12 22.077771 63.984389 19.803846 - H21 22.209652 61.574074 18.018756 - H22 22.498278 63.179321 17.508589 - C1 30.911455 49.724370 29.478841 - C2 31.093663 51.042405 29.328820 - H11 30.020250 49.306013 29.761213 - H12 31.648969 49.030978 29.323010 - H21 30.356148 51.735797 29.484650 - H22 31.984868 51.460762 29.046447 - C1 30.222227 7.017360 61.994817 - C2 30.303383 6.442944 60.788011 - H11 30.476347 7.993231 62.173987 - H12 29.899653 6.526003 62.833577 - H21 30.625957 6.934301 59.949251 - H22 30.049263 5.467072 60.608841 - C1 77.717495 39.764689 43.768581 - C2 78.161412 38.533100 43.487431 - H11 76.724755 40.000720 43.856677 - H12 78.335794 40.567493 43.917633 - H21 77.543113 37.730297 43.338379 - H22 79.154152 38.297069 43.399335 - C1 14.404925 51.174627 17.115821 - C2 13.115192 51.219382 16.758740 - H11 14.749292 50.647345 17.923527 - H12 15.148436 51.664159 16.609310 - H21 12.371681 50.729850 17.265251 - H22 12.770826 51.746664 15.951034 - C1 76.295226 77.801864 19.718125 - C2 76.855036 77.375716 18.578857 - H11 76.788734 77.826132 20.615267 - H12 75.329523 78.137049 19.781945 - H21 77.820739 77.040531 18.515038 - H22 76.361528 77.351448 17.681715 - C1 3.429771 25.637709 49.207638 - C2 3.852871 26.906150 49.137181 - H11 4.059190 24.830160 49.181180 - H12 2.443470 25.375339 49.293524 - H21 4.839172 27.168520 49.051295 - H22 3.223451 27.713699 49.163639 - C1 31.236198 39.071751 66.386804 - C2 30.047560 39.109366 67.002145 - H11 31.384315 39.389984 65.424623 - H12 32.090688 38.721791 66.829951 - H21 29.193070 39.459326 66.558998 - H22 29.899444 38.791133 67.964327 - C1 4.030270 58.446402 54.004275 - C2 5.266880 58.958321 54.044938 - H11 3.335456 58.589032 54.743122 - H12 3.682014 57.871973 53.231130 - H21 5.615136 59.532750 54.818083 - H22 5.961694 58.815691 53.306091 - C1 33.740564 63.266157 4.725906 - C2 33.400468 61.971236 4.746821 - H11 34.710365 63.595124 4.709462 - H12 33.057632 64.029442 4.724708 - H21 34.083400 61.207951 4.748019 - H22 32.430667 61.642269 4.763264 - C1 36.223888 45.134082 10.298863 - C2 35.066546 45.740143 10.005317 - H11 36.333612 44.116666 10.341622 - H12 37.090372 45.640292 10.503708 - H21 34.200062 45.233933 9.800472 - H22 34.956822 46.757559 9.962558 - C1 75.916900 53.444902 18.236506 - C2 74.642820 53.537259 17.835120 - H11 76.396770 54.178639 18.765995 - H12 76.511705 52.633262 18.045583 - H21 74.048015 54.348899 18.026043 - H22 74.162950 52.803522 17.305632 - C1 30.738565 26.518182 42.847428 - C2 30.212662 27.229260 41.842085 - H11 31.491140 26.863590 43.450194 - H12 30.429583 25.572986 43.092659 - H21 30.521643 28.174457 41.596854 - H22 29.460087 26.883852 41.239318 - C1 76.374482 19.585066 31.678706 - C2 75.156915 20.125896 31.812705 - H11 77.223827 20.136797 31.526355 - H12 76.552144 18.577150 31.718029 - H21 74.979254 21.133811 31.773381 - H22 74.307571 19.574165 31.965055 - C1 57.068534 69.884704 77.115968 - C2 57.823669 69.044879 77.835264 - H11 56.790461 69.704936 76.146761 - H12 56.709658 70.772856 77.478456 - H21 58.182545 68.156727 77.472776 - H22 58.101741 69.224646 78.804472 - C1 36.588001 63.750755 67.562086 - C2 37.164860 64.543825 66.650387 - H11 35.585112 63.765185 67.769474 - H12 37.104315 63.067378 68.123708 - H21 36.648546 65.227202 66.088765 - H22 38.167749 64.529395 66.442999 - C1 11.084541 57.571250 68.807569 - C2 10.319105 56.509652 69.090483 - H11 10.711172 58.461700 68.465959 - H12 12.103548 57.576247 68.910545 - H21 9.300098 56.504655 68.987507 - H22 10.692474 55.619202 69.432093 - C1 64.181147 24.039087 38.031495 - C2 64.158039 25.374798 38.122400 - H11 63.357948 23.448513 38.181725 - H12 65.023838 23.503001 37.804586 - H21 63.315347 25.910884 38.349309 - H22 64.981238 25.965372 37.972170 - C1 10.151723 31.885389 39.726969 - C2 8.998339 32.426703 40.138802 - H11 10.340576 31.632112 38.752706 - H12 10.935738 31.682074 40.353856 - H21 8.214323 32.630018 39.511916 - H22 8.809486 32.679981 41.113065 - C1 71.978958 79.107950 19.923092 - C2 71.469851 79.007427 18.688739 - H11 72.229193 79.999938 20.359834 - H12 72.158151 78.300753 20.527514 - H21 71.290658 79.814624 18.084317 - H22 71.219616 78.115439 18.251997 - C1 59.120397 33.153146 22.338839 - C2 59.957424 34.157434 22.049511 - H11 58.100658 33.248576 22.333470 - H12 59.434111 32.210607 22.588255 - H21 59.643710 35.099973 21.800096 - H22 60.977163 34.062004 22.054881 - C1 21.028577 44.155393 57.592682 - C2 20.349453 45.238529 57.990837 - H11 20.977890 43.250279 58.069341 - H12 21.652097 44.146891 56.780184 - H21 19.725933 45.247031 58.803336 - H22 20.400140 46.143643 57.514179 - C1 76.004585 19.995772 23.445758 - C2 76.300250 21.297289 23.553264 - H11 76.003489 19.488537 22.555974 - H12 75.756291 19.405190 24.244861 - H21 76.548545 21.887871 22.754160 - H22 76.301347 21.804524 24.443047 - C1 75.957052 70.328214 32.175329 - C2 77.042707 70.541168 32.929599 - H11 75.305959 69.552658 32.328939 - H12 75.692404 70.924145 31.385498 - H21 77.307355 69.945237 33.719429 - H22 77.693800 71.316723 32.775989 - C1 45.994652 1.133518 58.899198 - C2 45.556997 0.834059 60.128712 - H11 46.897042 0.820757 58.529231 - H12 45.461419 1.698870 58.232082 - H21 46.090229 0.268707 60.795828 - H22 44.654606 1.146820 60.498678 - C1 9.336163 38.508165 74.690150 - C2 9.185798 37.961166 73.477260 - H11 9.261154 37.976801 75.562521 - H12 9.538004 39.500917 74.840842 - H21 8.983958 36.968414 73.326568 - H22 9.260807 38.492529 72.604889 - C1 23.903785 13.917560 23.222746 - C2 24.272163 13.250264 22.121867 - H11 22.992089 13.801614 23.674819 - H12 24.504758 14.596365 23.699253 - H21 23.671191 12.571459 21.645359 - H22 25.183859 13.366211 21.669793 - C1 63.262991 74.445113 76.439558 - C2 64.304780 75.045401 77.028837 - H11 63.303639 73.499790 76.047491 - H12 62.343602 74.884097 76.334574 - H21 65.224168 74.606417 77.133822 - H22 64.264131 75.990724 77.420904 - C1 35.606743 15.098612 77.232079 - C2 36.514479 14.115915 77.175138 - H11 34.597301 14.932734 77.282231 - H12 35.850518 16.093384 77.229955 - H21 36.270705 13.121142 77.177262 - H22 37.523921 14.281792 77.124986 - C1 12.767525 61.513950 61.205480 - C2 12.698144 62.706645 61.810115 - H11 13.410022 60.770656 61.494819 - H12 12.183551 61.251215 60.406137 - H21 13.282118 62.969380 62.609458 - H22 12.055648 63.449939 61.520777 - C1 44.617675 41.918918 15.635173 - C2 45.086649 41.083231 14.699967 - H11 44.940265 42.885097 15.742122 - H12 43.899510 41.657634 16.317063 - H21 45.804814 41.344515 14.018078 - H22 44.764059 40.117052 14.593018 - C1 34.393445 13.201940 8.880115 - C2 35.173523 13.718085 7.921995 - H11 34.212494 12.198973 8.981692 - H12 33.916409 13.769543 9.586703 - H21 35.650560 13.150482 7.215407 - H22 35.354474 14.721052 7.820417 - C1 75.582580 34.460954 50.136019 - C2 76.248629 33.468443 50.739526 - H11 76.010434 35.096786 49.456562 - H12 74.592920 34.662297 50.306423 - H21 77.238289 33.267101 50.569121 - H22 75.820775 32.832611 51.418983 - C1 62.075425 41.894877 56.177696 - C2 63.259611 41.269966 56.167119 - H11 61.228110 41.492306 56.588789 - H12 61.923891 42.824554 55.775525 - H21 63.411145 40.340289 56.569290 - H22 64.106926 41.672537 55.756026 - C1 31.532650 1.037549 47.150194 - C2 30.201428 0.903286 47.097829 - H11 32.002658 1.914442 47.393411 - H12 32.185515 0.273906 46.951147 - H21 29.548562 1.666929 47.296877 - H22 29.731419 0.026393 46.854612 - C1 27.391769 11.659943 31.394182 - C2 26.979764 11.773779 30.125240 - H11 27.211544 12.367841 32.112098 - H12 27.919517 10.856026 31.746607 - H21 26.452016 12.577696 29.772815 - H22 27.159990 11.065881 29.407324 - C1 7.991525 44.770812 13.463485 - C2 8.625380 43.605741 13.279754 - H11 8.319915 45.497059 14.106703 - H12 7.128484 45.027293 12.975241 - H21 9.488420 43.349260 13.767998 - H22 8.296989 42.879494 12.636536 - C1 51.372109 61.131823 37.026280 - C2 52.114164 61.946235 36.265354 - H11 51.747072 60.305527 37.501297 - H12 50.371230 61.271170 37.193096 - H21 53.115042 61.806889 36.098537 - H22 51.739201 62.772531 35.790336 - C1 45.294713 35.496833 39.529495 - C2 44.615906 36.027687 38.504637 - H11 46.137130 35.920822 39.928959 - H12 45.024864 34.625074 39.994491 - H21 44.885755 36.899447 38.039641 - H22 43.773490 35.603698 38.105173 - C1 66.572899 42.065106 43.081136 - C2 65.484386 42.106716 43.859807 - H11 67.430815 41.567059 43.335957 - H12 66.633135 42.528054 42.169515 - H21 65.424151 41.643768 44.771428 - H22 64.626470 42.604763 43.604986 - C1 53.510728 72.367819 62.916112 - C2 53.756214 71.057657 62.789091 - H11 53.111775 72.788350 63.760501 - H12 53.702617 73.052397 62.178863 - H21 53.564326 70.373079 63.526340 - H22 54.155168 70.637126 61.944702 - C1 58.185252 19.004358 19.113785 - C2 59.205867 19.870530 19.081953 - H11 57.240628 19.232541 18.790335 - H12 58.268998 18.045566 19.464084 - H21 59.122121 20.829321 18.731654 - H22 60.150492 19.642346 19.405403 - C1 6.619524 65.384156 36.641650 - C2 7.566135 65.722051 35.756960 - H11 5.755492 65.917557 36.775582 - H12 6.685097 64.565744 37.253945 - H21 7.500561 66.540463 35.144665 - H22 8.430166 65.188651 35.623028 - C1 34.094521 40.406184 15.434817 - C2 33.627026 40.194988 16.671654 - H11 33.824511 39.840516 14.624806 - H12 34.758859 41.149995 15.201567 - H21 32.962689 39.451178 16.904903 - H22 33.897036 40.760657 17.481664 - C1 55.939477 21.787570 49.034913 - C2 56.752690 22.785454 49.403470 - H11 54.922216 21.884417 48.965596 - H12 56.270800 20.849019 48.793357 - H21 56.421367 23.724005 49.645027 - H22 57.769951 22.688608 49.472788 - C1 52.669383 10.463949 14.838326 - C2 52.667331 9.857615 16.032175 - H11 52.645710 11.481204 14.721553 - H12 52.694786 9.958131 13.948097 - H21 52.641927 10.363433 16.922403 - H22 52.691003 8.840360 16.148947 - C1 33.396436 39.329934 50.651104 - C2 33.361450 38.025456 50.351048 - H11 34.192723 39.937478 50.437044 - H12 32.629659 39.822706 51.118259 - H21 34.128226 37.532684 49.883893 - H22 32.565163 37.417913 50.565108 - C1 71.018584 8.408527 46.902009 - C2 70.192442 7.601917 46.223930 - H11 70.695950 9.186652 47.484616 - H12 72.038061 8.310769 46.891354 - H21 69.172965 7.699674 46.234585 - H22 70.515076 6.823791 45.641322 - C1 52.027019 8.927805 54.782656 - C2 50.977469 8.152265 55.082494 - H11 51.979659 9.949981 54.738885 - H12 52.959665 8.559789 54.573516 - H21 50.044823 8.520280 55.291633 - H22 51.024829 7.130088 55.126265 - C1 48.056759 57.100413 3.633618 - C2 47.242637 58.156352 3.756577 - H11 49.000561 57.065833 4.029909 - H12 47.799662 56.244317 3.133613 - H21 47.499734 59.012447 4.256582 - H22 46.298835 58.190931 3.360286 - C1 14.422944 3.224980 62.094032 - C2 15.622263 2.877498 62.577571 - H11 14.104186 4.195364 62.018189 - H12 13.730087 2.547694 61.762013 - H21 16.315120 3.554784 62.909589 - H22 15.941021 1.907114 62.653414 - C1 56.826499 45.296749 74.806886 - C2 55.519506 45.281625 75.097507 - H11 57.373447 46.157202 74.709559 - H12 57.381988 44.449053 74.659076 - H21 54.964017 46.129321 75.245317 - H22 54.972558 44.421172 75.194833 - C1 31.876741 56.262832 32.972864 - C2 33.163987 56.454910 33.287545 - H11 31.457337 55.336406 32.851048 - H12 31.210365 57.027241 32.829249 - H21 33.830363 55.690501 33.431160 - H22 33.583391 57.381336 33.409361 - C1 1.023469 34.139632 15.728270 - C2 1.899671 35.152113 15.736842 - H11 1.297909 33.154779 15.789509 - H12 0.009962 34.270468 15.659801 - H21 2.913179 35.021278 15.805311 - H22 1.625232 36.136967 15.675604 - C1 29.902323 50.161142 16.035963 - C2 28.661713 50.461674 16.440300 - H11 30.588376 50.864897 15.747754 - H12 30.262714 49.203891 15.983119 - H21 28.301323 51.418926 16.493145 - H22 27.975661 49.757919 16.728510 - C1 45.330030 61.185539 58.322023 - C2 45.825082 60.731814 57.163585 - H11 44.330978 61.186035 58.547627 - H12 45.911511 61.567757 59.073550 - H21 45.243601 60.349596 56.412058 - H22 46.824135 60.731318 56.937981 - C1 4.171915 67.480024 25.011701 - C2 3.506889 66.364215 25.336712 - H11 4.935076 67.866841 25.574694 - H12 3.969696 68.034383 24.174564 - H21 3.709108 65.809857 26.173849 - H22 2.743728 65.977399 24.773719 - C1 33.484099 52.792764 32.153354 - C2 33.356374 51.629938 31.501860 - H11 32.805978 53.131670 32.842048 - H12 34.269954 53.434690 32.014190 - H21 32.570519 50.988012 31.641024 - H22 34.034495 51.291032 30.813166 - C1 49.337554 41.628724 35.394523 - C2 50.278955 42.568127 35.238934 - H11 49.548150 40.639591 35.556595 - H12 48.332895 41.825481 35.363688 - H21 51.283614 42.371370 35.269769 - H22 50.068359 43.557261 35.076862 - C1 2.914591 23.259027 13.202182 - C2 2.105025 24.303071 12.984249 - H11 2.575495 22.310529 13.387572 - H12 3.936549 23.326883 13.200618 - H21 1.083068 24.235215 12.985813 - H22 2.444121 25.251569 12.798859 - C1 2.346618 2.299155 52.420384 - C2 1.236833 1.775193 51.884882 - H11 3.018979 2.860628 51.889647 - H12 2.610349 2.179639 53.402812 - H21 0.973101 1.894709 50.902454 - H22 0.564471 1.213720 52.415619 - C1 32.036065 4.590848 45.650378 - C2 30.918233 5.058476 46.220201 - H11 32.853945 5.173707 45.449500 - H12 32.161066 3.613550 45.370616 - H21 30.793232 6.035774 46.499962 - H22 30.100353 4.475617 46.421079 - C1 25.816877 21.627802 12.752972 - C2 27.109817 21.319120 12.591903 - H11 25.049411 21.023065 12.445901 - H12 25.493761 22.492910 13.195904 - H21 27.432933 20.454012 12.148972 - H22 27.877283 21.923857 12.898974 - C1 65.984471 71.714283 38.323412 - C2 65.391206 72.865177 37.982236 - H11 66.997433 71.567955 38.284704 - H12 65.471921 70.889842 38.649899 - H21 65.903756 73.689618 37.655750 - H22 64.378243 73.011504 38.020945 - C1 44.650992 7.885894 75.761625 - C2 44.579588 9.030078 76.453480 - H11 43.926343 7.575047 75.107972 - H12 45.435871 7.231632 75.831704 - H21 43.794709 9.684340 76.383402 - H22 45.304237 9.340926 77.107133 - C1 55.381200 41.399243 19.327293 - C2 56.283770 40.440438 19.084432 - H11 55.609507 42.287139 19.783934 - H12 54.391584 41.320090 19.075504 - H21 57.273387 40.519591 19.336222 - H22 56.055464 39.552543 18.627791 - C1 56.176470 69.418846 44.476016 - C2 55.028459 69.216631 43.817153 - H11 56.661246 70.320683 44.502218 - H12 56.660031 68.687576 45.005559 - H21 54.544898 69.947902 43.287609 - H22 54.543683 68.314795 43.790951 - C1 36.820215 64.672430 24.054566 - C2 37.501862 64.048282 23.085692 - H11 35.939496 65.170212 23.894717 - H12 37.125970 64.701111 25.031651 - H21 37.196107 64.019602 22.108607 - H22 38.382581 63.550500 23.245541 - C1 76.285549 1.778460 21.857772 - C2 75.436749 1.500553 22.855382 - H11 76.336793 2.692212 21.397951 - H12 76.950261 1.099121 21.476118 - H21 74.772037 2.179892 23.237036 - H22 75.385505 0.586801 23.315203 - C1 70.327328 19.885361 42.611244 - C2 71.614648 20.252476 42.580354 - H11 69.550910 20.551893 42.654992 - H12 70.017904 18.909171 42.593551 - H21 71.924073 21.228666 42.598047 - H22 72.391067 19.585944 42.536606 - C1 52.359416 68.579654 76.847223 - C2 51.998675 67.719330 77.807759 - H11 53.304981 68.963129 76.758586 - H12 51.718132 68.921853 76.125657 - H21 52.639959 67.377130 78.529326 - H22 51.053110 67.335854 77.896396 - C1 66.503705 69.876437 74.806865 - C2 67.779326 69.877057 75.213941 - H11 65.706256 69.918910 75.448172 - H12 66.225179 69.833441 73.822193 - H21 68.057852 69.920053 76.198613 - H22 68.576775 69.834583 74.572635 - C1 8.570245 39.219840 28.101279 - C2 7.894012 38.613064 27.117687 - H11 8.235975 39.271449 29.068028 - H12 9.474912 39.680041 27.964180 - H21 6.989344 38.152863 27.254786 - H22 8.228282 38.561456 26.150938 - C1 20.974112 21.653894 64.188157 - C2 21.831894 20.670460 63.888175 - H11 20.024231 21.709862 63.809214 - H12 21.200462 22.427442 64.820132 - H21 21.605544 19.896912 63.256199 - H22 22.781775 20.614491 64.267117 - C1 68.346761 73.651389 66.962915 - C2 69.349867 73.023334 66.336619 - H11 68.067360 73.447721 67.926999 - H12 67.780051 74.384815 66.527106 - H21 69.916577 72.289908 66.772429 - H22 69.629268 73.227002 65.372535 - C1 1.134633 53.572304 33.678603 - C2 1.811477 53.786743 32.543341 - H11 0.498253 52.781626 33.815905 - H12 1.200102 54.182105 34.498884 - H21 1.746008 53.176942 31.723061 - H22 2.447857 54.577421 32.406039 - C1 56.513986 57.224926 40.207030 - C2 56.394486 58.188802 41.128759 - H11 55.729890 56.880282 39.645410 - H12 57.398880 56.756550 39.991180 - H21 55.509593 58.657177 41.344609 - H22 57.178583 58.533446 41.690379 - C1 38.029829 37.268866 65.245666 - C2 38.941264 38.248540 65.196208 - H11 37.021857 37.430610 65.162986 - H12 38.269013 36.280777 65.370063 - H21 38.702080 39.236629 65.071811 - H22 39.949236 38.086796 65.278888 - C1 21.377225 20.486824 58.632256 - C2 22.656232 20.833939 58.441014 - H11 21.089705 19.591701 59.038571 - H12 20.585916 21.089158 58.387253 - H21 23.447542 20.231605 58.686018 - H22 22.943753 21.729061 58.034700 - C1 60.595849 36.580691 0.785752 - C2 59.338524 36.945589 1.066654 - H11 60.845085 35.971048 0.001392 - H12 61.407154 36.882546 1.333174 - H21 58.527219 36.643734 0.519231 - H22 59.089288 37.555232 1.851013 - C1 5.229830 70.148556 74.682851 - C2 6.076331 70.492938 73.704201 - H11 4.642971 70.821441 75.184674 - H12 5.102672 69.185187 75.006511 - H21 6.203489 71.456307 73.380541 - H22 6.663190 69.820053 73.202379 - C1 62.297915 69.334043 9.504433 - C2 62.536427 70.627323 9.756349 - H11 61.361133 68.954254 9.339501 - H12 63.033515 68.622964 9.456875 - H21 61.800826 71.338402 9.803907 - H22 63.473209 71.007112 9.921281 - C1 25.546689 43.068526 26.242519 - C2 26.105307 43.018280 27.458389 - H11 25.551238 43.906150 25.653138 - H12 25.070950 42.273284 25.806323 - H21 26.581046 43.813522 27.894585 - H22 26.100758 42.180656 28.047770 - C1 73.784130 30.201479 4.374645 - C2 72.898311 29.274036 3.989815 - H11 73.562022 30.957384 5.029076 - H12 74.753418 30.227863 4.044816 - H21 71.929022 29.247652 4.319645 - H22 73.120419 28.518131 3.335385 - C1 63.188500 55.102486 16.799624 - C2 64.498507 55.066607 17.074424 - H11 62.754947 55.817437 16.208117 - H12 62.517075 54.417798 17.159339 - H21 65.169932 55.751294 16.714709 - H22 64.932060 54.351656 17.665931 - C1 50.124122 64.688159 54.567243 - C2 50.033698 63.394243 54.234787 - H11 49.493038 65.146007 55.231406 - H12 50.831476 65.321717 54.183502 - H21 49.326344 62.760685 54.618528 - H22 50.664782 62.936396 53.570624 - C1 11.225254 62.270892 55.966518 - C2 10.874539 62.827970 54.800506 - H11 10.816570 62.539697 56.866366 - H12 11.929762 61.532197 56.050191 - H21 10.170031 63.566665 54.716833 - H22 11.283223 62.559165 53.900659 - C1 32.252802 10.447299 6.130697 - C2 30.914162 10.478088 6.126703 - H11 32.797797 9.580400 6.109006 - H12 32.836937 11.288228 6.155757 - H21 30.330027 9.637159 6.101643 - H22 30.369167 11.344986 6.148393 - C1 41.330176 22.316003 45.983447 - C2 42.156310 23.084692 45.262654 - H11 40.744744 22.674312 46.743637 - H12 41.218771 21.309313 45.831239 - H21 42.267715 24.091382 45.414863 - H22 42.741741 22.726383 44.502465 - C1 8.240048 66.452349 26.083348 - C2 8.425907 67.690151 25.607719 - H11 8.326062 65.608162 25.509803 - H12 7.997264 66.252461 27.058081 - H21 8.668692 67.890039 24.632986 - H22 8.339893 68.534338 26.181264 - C1 10.522184 76.556890 33.730830 - C2 10.125181 76.261758 34.975099 - H11 9.901216 76.952379 33.018797 - H12 11.478020 76.410342 33.393332 - H21 9.169345 76.408306 35.312597 - H22 10.746150 75.866268 35.687132 - C1 51.141167 12.666925 69.174732 - C2 50.964967 11.424946 68.706369 - H11 51.702113 13.377054 68.695086 - H12 50.728845 13.004393 70.049437 - H21 51.377290 11.087478 67.831664 - H22 50.404022 10.714817 69.186015 - C1 18.278278 77.583707 57.841680 - C2 19.512780 77.514286 57.327766 - H11 17.638660 78.365222 57.671014 - H12 17.876606 76.860748 58.445826 - H21 19.914453 78.237245 56.723620 - H22 20.152399 76.732771 57.498432 - C1 53.952702 0.858668 76.873019 - C2 54.490606 2.084168 76.914613 - H11 54.507795 0.000061 76.812428 - H12 52.943893 0.683576 76.898527 - H21 55.499415 2.259259 76.889105 - H22 53.935513 2.942774 76.975204 - C1 37.423980 20.250871 57.093990 - C2 37.138528 18.942949 57.121892 - H11 36.732614 20.983818 57.277855 - H12 38.356121 20.621144 56.886590 - H21 36.206387 18.572676 57.329293 - H22 37.829894 18.210002 56.938027 - C1 15.685987 55.450913 52.310358 - C2 16.751375 56.213646 52.586235 - H11 14.968267 55.709260 51.626883 - H12 15.505063 54.549208 52.761132 - H21 16.932299 57.115352 52.135460 - H22 17.469096 55.955300 53.269710 - C1 24.453519 78.286949 70.565101 - C2 23.516410 77.330536 70.560647 - H11 25.459065 78.092319 70.564425 - H12 24.238417 79.288306 70.569534 - H21 23.731513 76.329179 70.556214 - H22 22.510864 77.525166 70.561323 - C1 71.060688 15.352602 78.023460 - C2 70.926146 16.684406 77.990016 - H11 70.408565 14.707512 77.567831 - H12 71.826297 14.874328 78.507300 - H21 70.160537 17.162680 77.506177 - H22 71.578269 17.329495 78.445645 - C1 5.847768 40.549760 78.564501 - C2 6.029296 39.239611 78.773013 - H11 4.930408 41.004341 78.592986 - H12 6.612010 41.200278 78.360138 - H21 5.265054 38.589093 78.977377 - H22 6.946655 38.785030 78.744528 - C1 58.041570 19.871482 50.895357 - C2 58.851274 19.691294 51.946468 - H11 58.188513 19.423704 49.986014 - H12 57.211650 20.471248 50.918099 - H21 59.681194 19.091528 51.923726 - H22 58.704331 20.139073 52.855811 - C1 35.944536 28.428831 64.477005 - C2 34.615947 28.354378 64.626102 - H11 36.577249 27.642392 64.650762 - H12 36.432475 29.278070 64.177486 - H21 34.128008 27.505139 64.925621 - H22 33.983234 29.140817 64.452345 - C1 10.409095 14.357773 4.553215 - C2 9.613726 14.747779 3.549121 - H11 11.196460 13.713961 4.432529 - H12 10.292616 14.672620 5.520845 - H21 9.730205 14.432932 2.581491 - H22 8.826361 15.391591 3.669807 - C1 26.259960 75.934327 38.800755 - C2 27.053469 76.087025 37.733073 - H11 25.317462 76.330007 38.865095 - H12 26.533139 75.409848 39.636996 - H21 26.780290 76.611504 36.896832 - H22 27.995967 75.691346 37.668733 - C1 19.876160 48.855589 16.732127 - C2 18.769200 49.608924 16.738963 - H11 20.823664 49.243932 16.752858 - H12 19.862367 47.831816 16.705630 - H21 18.782993 50.632697 16.765460 - H22 17.821696 49.220582 16.718232 - C1 50.706935 14.747893 20.976827 - C2 51.056146 14.224558 19.794840 - H11 51.318911 14.746237 21.798098 - H12 49.800402 15.190977 21.152551 - H21 51.962679 13.781473 19.619117 - H22 50.444170 14.226214 18.973569 - C1 29.476492 15.547132 21.715889 - C2 30.305362 14.505809 21.862664 - H11 29.797856 16.512328 21.597044 - H12 28.455984 15.460281 21.710931 - H21 31.325870 14.592660 21.867622 - H22 29.983998 13.540612 21.981510 - C1 3.847222 50.073894 43.025852 - C2 2.673792 49.749111 43.583078 - H11 4.749254 49.729835 43.367853 - H12 3.934966 50.691904 42.213837 - H21 2.586048 49.131101 44.395093 - H22 1.771760 50.093170 43.241077 - C1 39.424777 20.481342 65.622141 - C2 38.361703 21.295408 65.612620 - H11 40.389594 20.813451 65.710663 - H12 39.356654 19.462576 65.541652 - H21 38.429826 22.314174 65.693110 - H22 37.396886 20.963299 65.524099 - C1 55.344926 18.061066 17.248825 - C2 56.305051 18.336318 16.357020 - H11 54.928996 18.764633 17.866078 - H12 54.950998 17.125328 17.383802 - H21 56.698978 19.272056 16.222043 - H22 56.720980 17.632751 15.739767 - C1 71.720246 18.532055 62.581105 - C2 70.534209 18.263798 62.020502 - H11 71.890962 19.345573 63.179476 - H12 72.549941 17.944809 62.455597 - H21 69.704514 18.851044 62.146010 - H22 70.363492 17.450280 61.422131 - C1 41.521898 36.835316 35.211835 - C2 41.947913 36.105764 36.250674 - H11 40.942884 37.674354 35.310633 - H12 41.741573 36.611648 34.236787 - H21 41.728238 36.329432 37.225723 - H22 42.526928 35.266726 36.151877 - C1 73.960683 9.438002 39.049546 - C2 75.088665 9.205318 38.366584 - H11 73.911670 9.447484 40.072537 - H12 73.058254 9.624787 38.602626 - H21 75.991094 9.018533 38.813503 - H22 75.137678 9.195836 37.343592 - C1 17.237934 10.950564 42.300818 - C2 18.515416 10.820539 42.680362 - H11 16.845906 11.819212 41.925627 - H12 16.552417 10.191592 42.355869 - H21 19.200933 11.579512 42.625312 - H22 18.907443 9.951891 43.055554 - C1 73.093517 9.213583 43.269860 - C2 71.793580 9.282423 42.956257 - H11 73.584968 9.937136 43.802730 - H12 73.698549 8.431964 43.001512 - H21 71.188547 10.064042 43.224605 - H22 71.302128 8.558870 42.423388 - C1 11.446202 49.506560 24.843192 - C2 10.734770 50.049015 25.839450 - H11 12.331163 49.011105 24.985922 - H12 11.161327 49.544460 23.860129 - H21 11.019645 50.011115 26.822513 - H22 9.849809 50.544470 25.696720 - C1 27.214427 23.357231 47.378560 - C2 26.655156 22.141264 47.418076 - H11 28.208738 23.527518 47.555620 - H12 26.691854 24.212601 47.168169 - H21 27.177729 21.285894 47.628467 - H22 25.660845 21.970976 47.241016 - C1 29.100386 43.638771 6.703352 - C2 29.762790 42.571358 7.166785 - H11 28.115061 43.825875 6.911031 - H12 29.526979 44.352020 6.104771 - H21 29.336198 41.858109 7.765365 - H22 30.748115 42.384253 6.959106 - C1 23.047957 2.715605 49.533321 - C2 22.792627 1.550687 50.142165 - H11 23.816961 3.336511 49.801859 - H12 22.494321 3.077298 48.751227 - H21 23.346262 1.188994 50.924258 - H22 22.023623 0.929781 49.873627 - C1 13.261641 64.965111 78.078395 - C2 12.524519 64.127533 78.818688 - H11 13.119359 65.979268 78.062726 - H12 14.025679 64.657444 77.469634 - H21 11.760480 64.435200 79.427450 - H22 12.666801 63.113376 78.834358 - C1 73.047827 21.781856 8.051210 - C2 73.198806 20.479989 7.776858 - H11 72.150560 22.271775 7.988803 - H12 73.817745 22.390050 8.345030 - H21 72.428887 19.871795 7.483038 - H22 74.096073 19.990070 7.839265 - C1 55.037214 27.686513 74.848426 - C2 56.241056 27.402828 75.361466 - H11 54.795397 28.596369 74.445078 - H12 54.263603 27.015942 74.819030 - H21 57.014667 28.073399 75.390862 - H22 56.482873 26.492972 75.764814 - C1 15.827750 51.688724 74.308683 - C2 15.217826 52.817798 73.926445 - H11 15.332419 50.807925 74.475549 - H12 16.837545 51.617159 74.464232 - H21 14.208031 52.889362 73.770896 - H22 15.713157 53.698597 73.759580 - C1 29.307943 12.011698 62.687374 - C2 28.253872 11.186431 62.659269 - H11 29.855043 12.200393 63.532406 - H12 29.649941 12.519108 61.866048 - H21 27.911873 10.679021 63.480595 - H22 27.706771 10.997736 61.814238 - C1 41.885266 21.744568 67.077170 - C2 41.756112 20.539580 67.646594 - H11 41.255018 22.529295 67.266891 - H12 42.624455 21.976238 66.407146 - H21 41.016923 20.307911 68.316619 - H22 42.386361 19.754853 67.456873 - C1 73.621485 34.765720 36.763545 - C2 74.660767 34.898048 35.929697 - H11 73.584064 34.068781 37.513131 - H12 72.782281 35.351043 36.717302 - H21 75.499971 34.312726 35.975939 - H22 74.698188 35.594988 35.180111 - C1 76.904138 51.485204 64.819096 - C2 75.753327 50.803386 64.879759 - H11 76.953692 52.507694 64.786506 - H12 77.825283 51.037820 64.800518 - H21 74.832183 51.250769 64.898338 - H22 75.703774 49.780896 64.912350 - C1 53.772863 51.376390 26.278837 - C2 55.039336 50.955687 26.169396 - H11 52.977217 50.744712 26.408965 - H12 53.500252 52.362928 26.241022 - H21 55.311947 49.969149 26.207211 - H22 55.834982 51.587365 26.039268 - C1 18.285442 21.400117 16.765941 - C2 18.403987 22.672398 17.166155 - H11 19.000388 20.911094 16.219396 - H12 17.470504 20.815984 16.974911 - H21 19.218925 23.256531 16.957185 - H22 17.689041 23.161421 17.712701 - C1 12.323663 7.091078 7.684230 - C2 11.085296 6.598646 7.554311 - H11 12.682756 7.870928 7.125760 - H12 13.009121 6.726588 8.352286 - H21 10.399838 6.963136 6.886256 - H22 10.726203 5.818796 8.112782 - C1 57.895256 47.520514 78.162749 - C2 58.407278 48.756625 78.215507 - H11 57.599017 47.068636 77.292661 - H12 57.759608 46.929743 78.988336 - H21 58.542926 49.347395 77.389920 - H22 58.703517 49.208502 79.085595 - C1 65.319303 46.125251 47.336087 - C2 64.427805 47.093195 47.583547 - H11 66.320645 46.216477 47.531013 - H12 65.069931 45.217573 46.932432 - H21 64.677176 48.000873 47.987203 - H22 63.426463 47.001969 47.388621 - C1 37.127909 7.625215 2.334875 - C2 38.043759 6.738021 2.743565 - H11 36.195506 7.361981 2.002706 - H12 37.287802 8.636788 2.322317 - H21 37.883866 5.726448 2.756123 - H22 38.976162 7.001254 3.075734 - C1 3.584879 14.091997 26.432041 - C2 4.166743 12.891205 26.320449 - H11 2.578238 14.244308 26.320327 - H12 4.100722 14.952543 26.637882 - H21 3.650900 12.030659 26.114609 - H22 5.173384 12.738893 26.432163 - C1 31.199873 21.285780 63.305202 - C2 32.268041 20.577885 63.693561 - H11 30.444189 20.899229 62.732032 - H12 31.054567 22.269433 63.550795 - H21 32.413347 19.594232 63.447968 - H22 33.023725 20.964436 64.266731 - C1 59.977888 48.045174 61.997879 - C2 59.815799 49.373248 62.051441 - H11 59.198744 47.383166 61.937181 - H12 60.893752 47.586965 62.013399 - H21 58.899935 49.831457 62.035922 - H22 60.594942 50.035256 62.112139 - C1 78.389621 1.430750 44.299925 - C2 78.502721 2.650808 44.839913 - H11 78.622111 0.567920 44.800404 - H12 78.061733 1.264471 43.343973 - H21 78.830609 2.817087 45.795865 - H22 78.270232 3.513638 44.339435 - C1 61.606004 1.254226 44.863128 - C2 62.127761 1.649599 43.695065 - H11 61.641625 1.818238 45.717309 - H12 61.130287 0.356719 44.994197 - H21 62.603478 2.547106 43.563996 - H22 62.092140 1.085587 42.840884 - C1 76.741026 61.487624 14.390072 - C2 77.461986 62.613246 14.468266 - H11 75.778132 61.408965 14.730148 - H12 77.095797 60.616832 13.984040 - H21 77.107215 63.484038 14.874298 - H22 78.424880 62.691905 14.128190 - C1 70.995794 27.648288 60.695772 - C2 72.042546 26.855089 60.956668 - H11 71.086746 28.627523 60.409713 - H12 70.021917 27.338109 60.761768 - H21 73.016423 27.165269 60.890673 - H22 71.951594 25.875854 61.242727 - C1 42.655914 12.519322 7.972563 - C2 43.058527 11.255921 7.786440 - H11 43.140210 13.181893 8.585311 - H12 41.832018 12.922417 7.516808 - H21 43.882423 10.852825 8.242196 - H22 42.574231 10.593349 7.173693 - C1 49.649560 36.054190 73.653395 - C2 50.337056 37.166807 73.940368 - H11 50.092777 35.163068 73.411600 - H12 48.626447 36.006829 73.653131 - H21 51.360170 37.214167 73.940632 - H22 49.893840 38.057929 74.182163 - C1 76.528729 24.433700 56.651430 - C2 77.289752 25.484396 56.320065 - H11 75.670224 24.510333 57.204695 - H12 76.745316 23.470814 56.377669 - H21 77.073164 26.447281 56.593826 - H22 78.148256 25.407762 55.766800 - C1 10.280477 76.514126 64.374250 - C2 11.427855 76.031052 63.881214 - H11 10.113794 77.510330 64.543950 - H12 9.479357 75.925389 64.620422 - H21 12.228975 76.619789 63.635043 - H22 11.594538 75.034848 63.711514 - C1 9.449997 60.232491 63.612952 - C2 10.290652 59.337754 63.078474 - H11 9.736645 61.170212 63.908780 - H12 8.454265 60.049471 63.767951 - H21 11.286384 59.520773 62.923475 - H22 10.004003 58.400032 62.782645 - C1 49.271862 69.781833 10.076548 - C2 50.249792 70.557483 9.591840 - H11 48.286101 69.889688 9.820330 - H12 49.432748 69.019725 10.741612 - H21 50.088906 71.319591 8.926775 - H22 51.235552 70.449628 9.848057 - C1 73.568075 23.790000 68.110127 - C2 72.293581 24.176826 68.247790 - H11 74.075553 23.823618 67.221116 - H12 74.135622 23.430097 68.883021 - H21 71.726035 24.536730 67.474897 - H22 71.786104 24.143208 69.136801 - C1 23.734383 64.425930 22.479366 - C2 24.386247 63.256700 22.509303 - H11 24.203944 65.335389 22.516775 - H12 22.714979 64.502704 22.416705 - H21 25.405650 63.179926 22.571964 - H22 23.916686 62.347241 22.471894 - C1 51.945481 41.999057 9.550699 - C2 52.851621 42.710563 10.233040 - H11 50.989742 42.322394 9.374573 - H12 52.136898 41.075572 9.151277 - H21 52.660204 43.634049 10.632463 - H22 53.807360 42.387227 10.409167 - C1 49.731203 73.179956 50.097343 - C2 48.512705 73.333326 49.563806 - H11 49.905018 72.679081 50.973651 - H12 50.585179 73.551465 49.671069 - H21 47.658729 72.961817 49.990080 - H22 48.338890 73.834201 48.687497 - C1 38.867649 32.616462 78.464929 - C2 37.810037 31.975331 78.978084 - H11 39.263802 33.468528 78.872422 - H12 39.363583 32.305185 77.624596 - H21 37.314103 32.286608 79.818417 - H22 37.413884 31.123265 78.570591 - C1 5.677432 20.624340 76.394763 - C2 6.172413 21.831984 76.693951 - H11 4.879233 20.480300 75.769356 - H12 6.058120 19.749745 76.767809 - H21 5.791725 22.706579 76.320905 - H22 6.970612 21.976024 77.319358 - C1 45.654311 22.881439 6.011360 - C2 45.089401 21.684520 5.808424 - H11 45.124687 23.719609 6.268214 - H12 46.660431 23.052859 5.925681 - H21 44.083281 21.513100 5.894104 - H22 45.619025 20.846351 5.551570 - C1 61.331918 16.578218 78.365526 - C2 61.667425 15.429793 78.966753 - H11 60.549850 16.664931 77.709893 - H12 61.830989 17.460193 78.514029 - H21 61.168354 14.547818 78.818249 - H22 62.449493 15.343080 79.622386 - C1 43.386200 21.892619 61.316423 - C2 42.162443 21.391897 61.105193 - H11 43.578733 22.894614 61.405532 - H12 44.225895 21.312977 61.405484 - H21 41.322748 21.971539 61.016132 - H22 41.969910 20.389902 61.016084 - C1 34.059096 73.188330 71.011901 - C2 34.982848 73.312510 70.050557 - H11 33.170203 72.696707 70.880823 - H12 34.168812 73.575207 71.953862 - H21 34.873132 72.925633 69.108595 - H22 35.871741 73.804133 70.181635 - C1 38.440300 35.483334 32.700819 - C2 38.662581 36.750198 33.073064 - H11 39.058162 34.705113 32.949058 - H12 37.634947 35.192966 32.138595 - H21 39.467934 37.040566 33.635289 - H22 38.044719 37.528419 32.824826 - C1 69.063192 74.063187 38.163187 - C2 69.812348 73.251286 38.919827 - H11 69.318538 75.032000 37.950577 - H12 68.175941 73.779204 37.737578 - H21 70.699599 73.535269 39.345436 - H22 69.557003 72.282472 39.132437 - C1 52.351467 16.724643 6.038175 - C2 52.085888 15.660518 6.806307 - H11 51.632976 17.374155 5.705146 - H12 53.293972 16.972709 5.723291 - H21 51.143383 15.412452 7.121191 - H22 52.804378 15.011006 7.139336 - C1 53.773057 3.131617 21.346092 - C2 54.118995 2.301364 20.354160 - H11 53.057363 2.909885 22.044390 - H12 54.196957 4.053659 21.484480 - H21 53.695095 1.379322 20.215773 - H22 54.834689 2.523096 19.655863 - C1 39.729268 11.211416 12.831461 - C2 39.225257 9.983304 12.656432 - H11 40.442355 11.434642 13.531947 - H12 39.441309 12.024091 12.278611 - H21 39.513216 9.170629 13.209282 - H22 38.512170 9.760078 11.955946 - C1 48.770834 27.134949 58.374551 - C2 47.575929 27.202707 57.774108 - H11 48.909518 26.753301 59.314825 - H12 49.640040 27.459442 57.940745 - H21 46.706722 26.878213 58.207914 - H22 47.437244 27.584355 56.833834 - C1 34.264247 18.651999 4.558307 - C2 34.377665 19.964477 4.798013 - H11 33.504431 18.242186 4.007184 - H12 34.928395 17.954750 4.907240 - H21 33.713517 20.661726 4.449080 - H22 35.137481 20.374290 5.349136 - C1 60.320995 51.983564 4.751125 - C2 60.504210 51.232595 5.844468 - H11 60.858082 52.832811 4.552834 - H12 59.629368 51.767751 4.027191 - H21 61.195837 51.448407 6.568402 - H22 59.967123 50.383347 6.042759 - C1 27.983833 42.191094 68.767915 - C2 27.039766 43.138003 68.697045 - H11 27.782122 41.187996 68.721961 - H12 28.981856 42.395482 68.873646 - H21 26.041743 42.933614 68.591314 - H22 27.241478 44.141100 68.742999 - C1 69.860257 53.673887 22.459456 - C2 70.517349 54.147759 21.393343 - H11 70.108289 53.907350 23.425364 - H12 69.057975 53.040717 22.392804 - H21 71.319631 54.780929 21.459995 - H22 70.269317 53.914296 20.427434 - C1 28.772584 61.110305 59.945500 - C2 27.599121 60.525982 59.672606 - H11 29.440828 61.398889 59.224963 - H12 29.094146 61.314591 60.896220 - H21 27.277559 60.321695 58.721886 - H22 26.930877 60.237398 60.393142 - C1 50.795223 14.803453 55.298471 - C2 49.588248 14.252225 55.478137 - H11 51.022477 15.765257 55.567341 - H12 51.586041 14.306603 54.878053 - H21 48.797429 14.749074 55.898554 - H22 49.360994 13.290421 55.209266 - C1 62.722266 69.333394 27.483587 - C2 61.728976 70.160623 27.134319 - H11 62.831577 68.948668 28.426476 - H12 63.450785 69.020361 26.835302 - H21 61.000457 70.473657 27.782605 - H22 61.619664 70.545350 26.191430 - C1 21.647804 55.875140 23.234346 - C2 20.423492 56.403628 23.355508 - H11 21.878972 55.132703 22.567747 - H12 22.449333 56.171802 23.798745 - H21 19.621963 56.106966 22.791108 - H22 20.192324 57.146064 24.022106 - C1 6.938826 4.973082 46.422104 - C2 6.506494 6.047301 45.749747 - H11 6.606607 4.021511 46.240042 - H12 7.635713 5.018560 47.171293 - H21 5.809607 6.001824 45.000558 - H22 6.838713 6.998872 45.931809 - C1 5.361192 13.729814 74.404797 - C2 5.894501 13.898395 73.188211 - H11 5.038559 14.504307 74.992226 - H12 5.233983 12.813125 74.843548 - H21 6.021710 14.815085 72.749460 - H22 6.217134 13.123902 72.600782 - C1 59.006064 19.655428 43.144029 - C2 60.172106 18.997333 43.157414 - H11 58.881722 20.592156 43.539104 - H12 58.146861 19.273797 42.737666 - H21 61.031309 19.378964 43.563778 - H22 60.296448 18.060605 42.762340 - C1 3.689702 13.356969 7.762442 - C2 2.509922 12.913394 8.214417 - H11 4.443252 12.738128 7.449071 - H12 3.931286 14.349962 7.694577 - H21 2.268338 11.920401 8.282282 - H22 1.756372 13.532236 8.527787 - C1 29.326466 52.529724 9.266106 - C2 29.800414 51.302321 9.514654 - H11 28.332695 52.733483 9.125021 - H12 29.920467 53.361269 9.197542 - H21 29.206413 50.470777 9.583218 - H22 30.794185 51.098563 9.655738 - C1 5.376221 54.594217 70.698074 - C2 5.285766 55.812450 71.246387 - H11 5.922306 53.830142 71.106710 - H12 4.906433 54.330724 69.826940 - H21 5.755554 56.075943 72.117521 - H22 4.739681 56.576525 70.837751 - C1 38.826539 24.412406 42.124851 - C2 40.118207 24.079107 42.240721 - H11 38.059349 23.827535 42.468871 - H12 38.504218 25.278411 41.683095 - H21 40.440527 23.213101 42.682477 - H22 40.885397 24.663977 41.896701 - C1 49.159042 21.075000 8.101002 - C2 48.801694 19.881289 8.591182 - H11 49.116268 21.312521 7.105634 - H12 49.503236 21.844364 8.682908 - H21 48.457500 19.111926 8.009276 - H22 48.844468 19.643768 9.586550 - C1 33.472990 28.463003 70.116057 - C2 33.242441 28.991935 68.907753 - H11 34.358617 28.569315 70.619413 - H12 32.781830 27.910542 70.631894 - H21 33.933601 29.544396 68.391915 - H22 32.356814 28.885623 68.404397 - C1 70.614462 38.659056 22.283846 - C2 69.363955 38.206427 22.439665 - H11 71.329107 38.167688 21.739012 - H12 70.954609 39.532213 22.697249 - H21 69.023809 37.333270 22.026263 - H22 68.649311 38.697795 22.984499 - C1 30.831665 39.953927 13.754037 - C2 29.719477 39.243544 13.980564 - H11 31.771700 39.547316 13.756201 - H12 30.829749 40.959740 13.560800 - H21 29.721392 38.237731 14.173801 - H22 28.779441 39.650155 13.978401 - C1 48.747756 48.155795 23.609873 - C2 50.025882 48.333615 23.967217 - H11 48.170203 48.891922 23.193275 - H12 48.247221 47.269679 23.725054 - H21 50.526417 49.219731 23.852035 - H22 50.603435 47.597488 24.383814 - C1 22.245771 26.340927 28.951508 - C2 22.885482 26.132741 30.109243 - H11 21.606631 25.661056 28.529278 - H12 22.345321 27.196402 28.397200 - H21 22.785933 25.277267 30.663550 - H22 23.524622 26.812613 30.531473 - C1 7.230413 62.330139 16.996501 - C2 8.161855 62.660802 16.093174 - H11 7.306168 62.553041 17.993286 - H12 6.368995 61.828327 16.761664 - H21 9.023272 63.162613 16.328011 - H22 8.086100 62.437900 15.096389 - C1 55.204617 49.119980 31.406331 - C2 56.095154 49.064970 32.404749 - H11 54.626225 49.942166 31.210172 - H12 55.031848 48.344195 30.760334 - H21 56.267922 49.840755 33.050746 - H22 56.673545 48.242785 32.600908 - C1 38.021404 5.050175 40.263217 - C2 37.446145 4.464060 39.205641 - H11 37.530896 5.699461 40.885176 - H12 38.997138 4.895271 40.533314 - H21 36.470411 4.618964 38.935545 - H22 37.936653 3.814774 38.583682 - C1 8.468992 7.465683 75.470315 - C2 9.424019 7.083319 76.327428 - H11 7.472176 7.479979 75.705170 - H12 8.660252 7.773907 74.512494 - H21 9.232759 6.775094 77.285249 - H22 10.420835 7.069022 76.092573 - C1 48.940251 67.663173 52.655373 - C2 47.776154 68.255589 52.360684 - H11 49.103148 66.656986 52.555087 - H12 49.759259 68.169661 53.004227 - H21 46.957146 67.749100 52.011830 - H22 47.613257 69.261775 52.460970 - C1 56.743972 59.562021 45.264758 - C2 57.381417 59.724445 46.431036 - H11 57.135201 59.039809 44.475303 - H12 55.815063 59.947228 45.070469 - H21 58.310325 59.339238 46.625325 - H22 56.990187 60.246657 47.220490 - C1 69.545570 74.611082 61.290548 - C2 70.596788 74.794873 62.099303 - H11 69.038811 73.724169 61.215822 - H12 69.165637 75.342969 60.683098 - H21 70.976721 74.062985 62.706753 - H22 71.103547 75.681786 62.174029 - C1 26.870100 49.697857 51.554059 - C2 27.426508 50.714198 50.882955 - H11 27.320997 49.229651 52.345564 - H12 25.949878 49.308787 51.328625 - H21 28.346730 51.103267 51.108389 - H22 26.975612 51.182403 50.091450 - C1 45.834753 54.052785 11.638487 - C2 46.941445 53.462151 12.106787 - H11 45.017656 53.535080 11.301831 - H12 45.718365 55.068685 11.580136 - H21 47.057833 52.446251 12.165138 - H22 47.758542 53.979857 12.443443 - C1 30.758469 12.802026 18.726973 - C2 31.415146 11.655621 18.509137 - H11 31.215678 13.718075 18.755581 - H12 29.747360 12.852959 18.882108 - H21 32.426256 11.604688 18.354002 - H22 30.957938 10.739572 18.480530 - C1 69.058542 48.098454 34.961403 - C2 69.096107 46.765986 35.088048 - H11 68.408216 48.696814 35.479136 - H12 69.677182 48.624019 34.336848 - H21 68.477467 46.240421 35.712604 - H22 69.746432 46.167627 34.570316 - C1 27.032510 33.272349 49.654855 - C2 26.569458 33.042557 50.890047 - H11 26.895556 32.627141 48.871303 - H12 27.560044 34.111386 49.396534 - H21 26.041924 32.203521 51.148368 - H22 26.706412 33.687765 51.673599 - C1 77.336060 22.107934 15.859765 - C2 76.810623 22.120430 17.091301 - H11 76.898517 22.565134 15.054453 - H12 78.216806 21.640195 15.626288 - H21 75.929877 22.588169 17.324777 - H22 77.248167 21.663230 17.896613 - C1 48.869062 24.902172 44.366123 - C2 49.618299 23.793219 44.408436 - H11 47.848789 24.891316 44.277078 - H12 49.257361 25.848417 44.419477 - H21 49.230000 22.846974 44.355082 - H22 50.638572 23.804075 44.497481 - C1 30.801369 42.334352 24.694499 - C2 30.982439 41.014891 24.832910 - H11 29.906833 42.756862 24.429371 - H12 31.543175 43.024794 24.842878 - H21 30.240633 40.324448 24.684530 - H22 31.876976 40.592381 25.098038 - C1 6.912092 47.183378 16.029230 - C2 7.169977 48.495093 16.105517 - H11 7.641385 46.467504 15.960966 - H12 5.965275 46.792832 16.033147 - H21 8.116794 48.885639 16.101600 - H22 6.440684 49.210967 16.173781 - C1 9.431139 70.453594 16.154237 - C2 10.294012 71.310884 16.714080 - H11 8.467950 70.328731 16.479323 - H12 9.666502 69.855341 15.356928 - H21 10.058649 71.909137 17.511389 - H22 11.257201 71.435747 16.388995 - C1 20.630603 4.733452 62.290436 - C2 21.052020 3.594721 62.854900 - H11 19.741969 4.819852 61.788570 - H12 21.163776 5.607562 62.316181 - H21 20.518847 2.720611 62.829154 - H22 21.940654 3.508321 63.356765 - C1 56.070085 61.798516 56.896781 - C2 55.815266 62.195484 55.643623 - H11 56.892270 62.099360 57.428297 - H12 55.462837 61.162834 57.422293 - H21 56.422513 62.831167 55.118112 - H22 54.993081 61.894641 55.112108 - C1 23.392203 15.023053 3.585689 - C2 24.575736 14.744630 4.146628 - H11 23.242049 15.060875 2.573253 - H12 22.544057 15.220079 4.124980 - H21 25.423881 14.547605 3.607337 - H22 24.725889 14.706809 5.159064 - C1 71.069571 78.533781 15.448539 - C2 72.269034 77.939433 15.417537 - H11 70.943252 79.546762 15.531703 - H12 70.184155 78.022126 15.391523 - H21 73.154451 78.451088 15.474552 - H22 72.395353 76.926452 15.334372 - C1 1.791619 15.193775 47.903072 - C2 1.516311 14.478444 49.000992 - H11 1.614928 16.199633 47.825398 - H12 2.200529 14.791291 47.054660 - H21 1.107401 14.880928 49.849404 - H22 1.693001 13.472586 49.078665 - C1 10.698148 76.547329 70.839608 - C2 10.561357 77.706903 70.184172 - H11 9.951002 76.121542 71.395920 - H12 11.560675 75.995027 70.836152 - H21 9.698829 78.259205 70.187628 - H22 11.308502 78.132690 69.627860 - C1 23.558407 72.777767 10.917548 - C2 24.812373 72.870615 10.457255 - H11 23.009633 73.584862 11.228111 - H12 23.049472 71.892355 10.995239 - H21 25.321308 73.756026 10.379564 - H22 25.361146 72.063520 10.146692 - C1 63.154068 27.688429 44.726968 - C2 62.775433 26.404881 44.681546 - H11 64.113177 27.987570 44.926035 - H12 62.514333 28.471947 44.566213 - H21 63.415167 25.621362 44.842301 - H22 61.816324 26.105740 44.482479 - C1 56.695489 74.167669 60.962948 - C2 57.366720 73.160778 60.389763 - H11 57.104069 75.089899 61.140591 - H12 55.720732 74.094741 61.268781 - H21 58.341478 73.233705 60.083930 - H22 56.958141 72.238547 60.212120 - C1 72.778295 5.475190 74.810670 - C2 71.600062 5.549771 75.442434 - H11 73.125926 6.200426 74.176485 - H12 73.424494 4.687047 74.911967 - H21 70.953864 6.337914 75.341136 - H22 71.252432 4.824535 76.076618 - C1 69.179099 33.144357 24.432176 - C2 69.119688 33.969582 25.484980 - H11 69.919219 32.448635 24.301042 - H12 68.489090 33.144010 23.675280 - H21 69.809697 33.969930 26.241876 - H22 68.379568 34.665304 25.616113 - C1 34.492681 8.435878 73.779050 - C2 35.741645 8.569008 74.243041 - H11 34.012630 9.158239 73.234304 - H12 33.919244 7.601222 73.932423 - H21 36.315082 9.403664 74.089667 - H22 36.221697 7.846647 74.787786 - C1 74.042250 42.150995 10.111177 - C2 75.036279 42.679556 10.836057 - H11 73.520826 41.315475 10.392296 - H12 73.725219 42.540679 9.218629 - H21 75.353310 42.289872 11.728605 - H22 75.557703 43.515076 10.554938 - C1 42.724236 19.772296 18.961386 - C2 41.454726 19.562629 18.590840 - H11 43.517018 19.720991 18.314958 - H12 43.002274 20.000453 19.920366 - H21 41.176687 19.334471 17.631860 - H22 40.661944 19.613933 19.237267 - C1 60.874338 76.990666 47.798175 - C2 59.824182 77.806578 47.954321 - H11 61.845602 77.315598 47.789895 - H12 60.788870 75.977520 47.674747 - H21 59.909650 78.819724 48.077749 - H22 58.852918 77.481646 47.962602 - C1 65.374104 46.123188 10.775039 - C2 65.025054 44.850086 10.999308 - H11 65.104525 46.898872 11.387122 - H12 65.938103 46.421354 9.973786 - H21 64.461054 44.551920 11.800561 - H22 65.294632 44.074403 10.387225 - C1 73.029338 71.805861 41.096913 - C2 71.912666 71.105578 40.861182 - H11 73.966471 71.392618 41.092981 - H12 73.034106 72.809786 41.299682 - H21 71.907897 70.101653 40.658412 - H22 70.975533 71.518821 40.865114 - C1 53.260203 29.096722 40.566196 - C2 53.064501 30.416284 40.681859 - H11 52.705234 28.397384 41.068131 - H12 53.980246 28.683022 39.966701 - H21 52.344458 30.829984 41.281354 - H22 53.619470 31.115622 40.179924 - C1 1.359650 65.056231 2.335455 - C2 1.679649 64.428640 1.196749 - H11 1.673229 66.003751 2.565405 - H12 0.776156 64.638077 3.065993 - H21 2.263143 64.846794 0.466211 - H22 1.366070 63.481120 0.966798 - C1 11.518474 27.443722 45.182543 - C2 12.784273 27.878341 45.224726 - H11 11.059800 27.123018 44.324772 - H12 10.909457 27.397830 46.004734 - H21 13.393289 27.924233 44.402536 - H22 13.242947 28.199044 46.082497 - C1 35.367361 61.844339 11.665274 - C2 34.249342 61.259677 12.113744 - H11 35.570266 61.987466 10.671620 - H12 36.107495 62.194370 12.280648 - H21 33.509208 60.909647 11.498371 - H22 34.046437 61.116551 13.107398 - C1 73.481055 2.381057 5.007097 - C2 74.507896 2.904984 4.325908 - H11 72.880687 1.636962 4.639831 - H12 73.215293 2.683224 5.948940 - H21 74.773659 2.602816 3.384065 - H22 75.108265 3.649078 4.693174 - C1 77.390892 6.016157 54.163763 - C2 77.014726 7.122688 54.817223 - H11 77.046866 5.079494 54.394657 - H12 78.052209 6.019472 53.381681 - H21 76.353409 7.119373 55.599305 - H22 77.358752 8.059351 54.586329 - C1 66.806964 24.088688 47.745657 - C2 65.740564 23.549916 47.141144 - H11 67.233728 23.698802 48.591154 - H12 67.279699 24.933022 47.410062 - H21 65.267829 22.705582 47.476739 - H22 65.313800 23.939802 46.295646 - C1 58.859109 55.942100 74.928903 - C2 58.827858 54.603538 74.914875 - H11 59.725863 56.487056 74.901278 - H12 58.018714 56.526208 74.968361 - H21 59.668254 54.019430 74.875417 - H22 57.961104 54.058582 74.942500 - C1 20.234674 70.886112 69.086004 - C2 19.281662 71.826552 69.102198 - H11 21.154551 71.021637 68.656512 - H12 20.118653 69.957335 69.501836 - H21 19.397682 72.755329 68.686366 - H22 18.361785 71.691028 69.531690 - C1 6.468132 72.740497 52.558093 - C2 7.804627 72.711564 52.481518 - H11 5.953188 72.745419 53.443425 - H12 5.855754 72.759979 51.737351 - H21 8.417005 72.692082 53.302260 - H22 8.319571 72.706642 51.596186 - C1 64.475067 15.408226 53.648504 - C2 65.745563 15.770495 53.430509 - H11 63.982734 14.708662 53.085278 - H12 63.895747 15.802219 54.395607 - H21 66.324882 15.376501 52.683406 - H22 66.237895 16.470058 53.993735 - C1 73.676882 43.944810 21.626448 - C2 73.330706 42.665172 21.815149 - H11 74.616673 44.308490 21.809573 - H12 73.029089 44.660493 21.284154 - H21 73.978500 41.949488 22.157442 - H22 72.390916 42.301492 21.632024 - C1 8.416392 20.509747 23.061697 - C2 9.587299 21.152492 22.968004 - H11 8.336885 19.496045 23.184540 - H12 7.508250 20.981300 23.017884 - H21 10.495441 20.680938 23.011817 - H22 9.666806 22.166194 22.845162 - C1 1.704083 38.495416 0.693056 - C2 1.992409 37.187922 0.708830 - H11 0.748675 38.862609 0.656052 - H12 2.416290 39.231081 0.716755 - H21 1.280202 36.452257 0.685131 - H22 2.947817 36.820729 0.745834 - C1 47.355987 33.775394 23.997281 - C2 46.168124 33.249186 23.673232 - H11 48.180215 33.211611 24.224881 - H12 47.533711 34.783028 24.043012 - H21 45.990400 32.241552 23.627501 - H22 45.343896 33.812969 23.445632 - C1 43.404050 16.229040 32.787353 - C2 43.551175 14.898150 32.784534 - H11 43.712827 16.829701 33.557331 - H12 42.971175 16.750971 32.019752 - H21 43.984050 14.376219 33.552134 - H22 43.242398 14.297489 32.014556 - C1 46.775337 33.432097 45.820913 - C2 47.300463 32.633030 44.883547 - H11 46.759569 34.453585 45.747984 - H12 46.348166 33.084616 46.684502 - H21 47.727633 32.980511 44.019958 - H22 47.316231 31.611542 44.956476 - C1 75.761842 27.069965 4.301721 - C2 75.670406 27.784332 5.430543 - H11 76.603298 27.040693 3.718541 - H12 74.997511 26.496674 3.932750 - H21 76.434737 28.357623 5.799514 - H22 74.828950 27.813604 6.013723 - C1 34.265269 45.787437 36.530649 - C2 33.853542 45.108076 37.608550 - H11 34.156797 46.800517 36.426214 - H12 34.721030 45.347391 35.725885 - H21 33.397781 45.548121 38.413315 - H22 33.962014 44.094996 37.712985 - C1 2.390918 2.080301 28.380431 - C2 3.658100 1.663591 28.264140 - H11 2.117059 3.067058 28.362676 - H12 1.595921 1.445035 28.496277 - H21 4.453097 2.298857 28.148294 - H22 3.931959 0.676833 28.281895 - C1 43.846747 75.810858 2.062115 - C2 42.804097 76.530091 1.627941 - H11 43.883086 74.788075 2.022147 - H12 44.689872 76.226976 2.468305 - H21 41.960972 76.113974 1.221751 - H22 42.767757 77.552874 1.667909 - C1 50.884922 7.752844 32.783197 - C2 50.573837 8.740755 31.934564 - H11 50.573571 7.727281 33.758599 - H12 51.458671 6.945113 32.523608 - H21 50.000088 9.548487 32.194153 - H22 50.885188 8.766318 30.959161 - C1 40.489461 66.223216 79.490039 - C2 40.972824 64.998655 79.734435 - H11 39.489192 66.442837 79.474804 - H12 41.082017 67.036502 79.299128 - H21 40.380268 64.185369 79.925346 - H22 41.973094 64.779034 79.749670 - C1 45.939744 1.153274 16.460075 - C2 44.608297 1.260855 16.552797 - H11 46.570070 1.959586 16.420655 - H12 46.432481 0.256218 16.421286 - H21 44.115560 2.157911 16.591587 - H22 43.977971 0.454543 16.592218 - C1 70.399985 12.137260 48.561029 - C2 70.735697 13.182240 47.794064 - H11 69.773572 11.388149 48.252092 - H12 70.743229 12.004940 49.516895 - H21 70.392453 13.314559 46.838198 - H22 71.362110 13.931351 48.103001 - C1 22.454638 6.234256 51.196934 - C2 23.751627 6.564353 51.154779 - H11 21.973279 5.944209 52.053188 - H12 21.841999 6.245869 50.376238 - H21 24.364266 6.552740 51.975475 - H22 24.232986 6.854400 50.298525 - C1 9.120304 79.224340 73.354341 - C2 8.184763 79.360856 72.406160 - H11 9.029416 78.585198 74.149476 - H12 10.000311 79.748333 73.358988 - H21 7.304755 78.836863 72.401513 - H22 8.275651 79.999999 71.611024 - C1 5.847281 35.627685 65.821972 - C2 6.390350 34.548277 65.245019 - H11 5.537033 35.650537 66.797794 - H12 5.699455 36.515304 65.332805 - H21 6.538175 33.660658 65.734186 - H22 6.700598 34.525425 64.269197 - C1 37.977782 53.938790 12.032834 - C2 37.844915 53.489554 13.287208 - H11 37.529846 54.793078 11.688523 - H12 38.537791 53.463430 11.319092 - H21 37.284907 53.964914 14.000949 - H22 38.292852 52.635267 13.631519 - C1 46.836545 13.541271 58.529673 - C2 47.122869 14.841346 58.385640 - H11 45.882107 13.169720 58.528515 - H12 47.549471 12.816221 58.652320 - H21 46.409943 15.566396 58.262993 - H22 48.077307 15.212897 58.386798 - C1 14.285319 9.627328 27.541376 - C2 15.180622 8.759924 28.030216 - H11 14.490847 10.616541 27.373391 - H12 13.324612 9.369762 27.297030 - H21 16.141329 9.017491 28.274563 - H22 14.975094 7.770711 28.198202 - C1 1.790269 32.122223 13.436539 - C2 1.507632 33.290629 12.846738 - H11 2.720625 31.694089 13.424617 - H12 1.098314 31.564818 13.945953 - H21 2.199586 33.848034 12.337324 - H22 0.577275 33.718763 12.858660 - C1 67.130881 74.652521 15.092113 - C2 67.831762 75.636079 15.670302 - H11 66.138805 74.480427 15.279657 - H12 67.531771 73.994995 14.416873 - H21 67.430872 76.293606 16.345542 - H22 68.823837 75.808174 15.482758 - C1 8.987103 10.731203 6.950847 - C2 9.749328 9.989467 7.764335 - H11 9.118349 11.738027 6.816369 - H12 8.212928 10.350028 6.399157 - H21 10.523503 10.370642 8.316025 - H22 9.618082 8.982643 7.898814 - C1 41.520680 32.559014 29.864417 - C2 40.663485 31.858375 30.617572 - H11 42.334715 33.050861 30.244468 - H12 41.429682 32.658150 28.849087 - H21 40.754484 31.759238 31.632902 - H22 39.849451 31.366528 30.237521 - C1 51.778839 46.187359 15.562018 - C2 50.888835 47.165088 15.350218 - H11 52.784897 46.351377 15.661763 - H12 51.523491 45.198635 15.640924 - H21 51.144183 48.153812 15.271312 - H22 49.882777 47.001070 15.250473 - C1 29.321008 54.803303 13.549068 - C2 28.460975 55.336786 12.672336 - H11 29.697435 55.314065 14.353076 - H12 29.670013 53.842553 13.484575 - H21 28.111971 56.297536 12.736829 - H22 28.084549 54.826024 11.868328 - C1 77.575673 0.877468 57.625184 - C2 77.006642 0.905687 58.836930 - H11 77.367027 1.556512 56.887369 - H12 78.264292 0.174623 57.340903 - H21 76.318023 1.608533 59.121212 - H22 77.215288 0.226644 59.574745 - C1 38.435367 10.892873 71.231922 - C2 38.410801 11.798929 72.217507 - H11 39.123498 10.902102 70.473375 - H12 37.767957 10.119394 71.159137 - H21 39.078211 12.572408 72.290292 - H22 37.722669 11.789701 72.976054 - C1 74.756385 72.456677 10.057089 - C2 75.960179 72.746243 9.547235 - H11 73.894096 72.456928 9.504402 - H12 74.603283 72.212182 11.039833 - H21 76.113281 72.990738 8.564492 - H22 76.822468 72.745992 10.099922 - C1 0.609617 1.625784 72.335450 - C2 1.206370 2.517740 73.136212 - H11 0.218227 1.862575 71.419073 - H12 0.497651 0.636636 72.576393 - H21 1.318336 3.506889 72.895270 - H22 1.597761 2.280949 74.052589 - C1 43.679186 22.894246 79.760462 - C2 44.109260 21.628758 79.679854 - H11 42.692028 23.150245 79.855264 - H12 44.303581 23.705675 79.733653 - H21 43.484866 20.817330 79.706664 - H22 45.096418 21.372759 79.585053 - C1 33.281443 24.233215 21.982703 - C2 32.336812 25.122297 21.650853 - H11 33.511513 23.988294 22.950219 - H12 33.848162 23.728203 21.295101 - H21 31.770094 25.627309 22.338455 - H22 32.106743 25.367218 20.683338 - C1 25.739820 36.177095 44.754113 - C2 26.012871 37.148727 43.874173 - H11 25.956231 35.189533 44.590124 - H12 25.293094 36.345094 45.660322 - H21 26.459597 36.980729 42.967963 - H22 25.796461 38.136289 44.038161 - C1 32.705981 41.872462 7.988177 - C2 32.086246 40.690361 7.880988 - H11 33.625929 42.066667 7.581996 - H12 32.308773 42.675346 8.484771 - H21 32.483455 39.887477 7.384393 - H22 31.166298 40.496156 8.287169 - C1 68.258830 50.569596 25.013039 - C2 67.574528 51.581900 25.560664 - H11 69.279722 50.556744 24.931693 - H12 67.815140 49.728579 24.632469 - H21 68.018219 52.422917 25.941234 - H22 66.553636 51.594752 25.642011 - C1 51.672952 26.420372 39.191988 - C2 50.789717 27.415665 39.341017 - H11 52.549572 26.516552 38.671132 - H12 51.541332 25.484671 39.587139 - H21 50.921337 28.351365 38.945866 - H22 49.913097 27.319485 39.861873 - C1 64.559872 17.826425 75.299780 - C2 64.641319 18.591593 76.395593 - H11 64.695741 16.811306 75.308462 - H12 64.355302 18.196133 74.366789 - H21 64.845889 18.221885 77.328583 - H22 64.505450 19.606712 76.386910 - C1 58.028511 52.923870 10.790704 - C2 58.611933 53.997476 11.338344 - H11 58.175286 51.967893 11.127704 - H12 57.389625 52.974270 9.991775 - H21 59.250818 53.947077 12.137274 - H22 58.465157 54.953453 11.001344 - C1 55.086403 53.575611 20.743428 - C2 55.255610 52.248780 20.681713 - H11 54.964880 54.168444 19.917120 - H12 55.065200 54.101948 21.621792 - H21 55.276813 51.722443 19.803349 - H22 55.377132 51.655947 21.508021 - C1 18.741894 56.521017 56.345770 - C2 18.881357 57.729603 56.905048 - H11 18.302229 55.726707 56.819868 - H12 19.063923 56.295897 55.399925 - H21 18.559328 57.954723 57.850893 - H22 19.321022 58.523913 56.430949 - C1 34.590863 31.072641 46.692679 - C2 33.346202 30.611850 46.515448 - H11 35.194855 30.784020 47.467854 - H12 35.036732 31.749935 46.066997 - H21 32.900333 29.934556 47.141130 - H22 32.742210 30.900472 45.740274 - C1 34.531193 69.101481 22.981803 - C2 33.557129 68.515864 23.689738 - H11 34.578858 70.110752 22.814160 - H12 35.305142 68.586173 22.552310 - H21 32.783180 69.031172 24.119231 - H22 33.509464 67.506593 23.857382 - C1 43.000998 74.505266 53.157466 - C2 41.829177 75.148640 53.081143 - H11 43.900175 74.941013 52.932500 - H12 43.090242 73.526839 53.446811 - H21 41.739933 76.127067 52.791798 - H22 40.930000 74.712893 53.306109 - C1 24.494936 15.368202 45.789450 - C2 23.613376 16.244146 45.290958 - H11 24.227556 14.465984 46.193821 - H12 25.505904 15.531568 45.805552 - H21 22.602408 16.080779 45.274856 - H22 23.880756 17.146363 44.886587 - C1 79.471639 23.306346 62.551176 - C2 79.347996 23.578587 63.856365 - H11 79.185571 23.952652 61.809922 - H12 79.861997 22.430408 62.191515 - H21 78.957637 24.454525 64.216026 - H22 79.634063 22.932281 64.597619 - C1 39.761422 4.820517 36.094636 - C2 39.919663 4.494254 34.805670 - H11 39.375649 4.181254 36.795725 - H12 40.013719 5.734981 36.480778 - H21 39.667366 3.579790 34.419528 - H22 40.305436 5.133518 34.104582 - C1 41.901327 24.934669 69.282238 - C2 42.269496 23.647291 69.276661 - H11 42.546094 25.707249 69.091454 - H12 40.946013 25.247979 69.477726 - H21 43.224809 23.333980 69.081172 - H22 41.624729 22.874710 69.467444 - C1 28.387637 24.393144 78.372184 - C2 28.691811 23.321206 79.114712 - H11 29.013406 24.784065 77.661833 - H12 27.505301 24.906393 78.456220 - H21 29.574147 22.807957 79.030676 - H22 28.066043 22.930285 79.825063 - C1 62.567006 23.304354 66.717579 - C2 63.282777 24.276256 66.137925 - H11 61.605792 23.431139 67.047724 - H12 62.924475 22.357778 66.876367 - H21 62.925308 25.222832 65.979136 - H22 64.243992 24.149471 65.807780 - C1 19.367500 28.369737 7.369477 - C2 20.158447 27.752284 6.482868 - H11 18.498880 28.848522 7.114005 - H12 19.568965 28.411767 8.372797 - H21 19.956982 27.710254 5.479549 - H22 21.027068 27.273499 6.738340 - C1 4.559124 23.847923 74.443449 - C2 3.633532 22.880494 74.460208 - H11 4.336135 24.844285 74.524338 - H12 5.562842 23.667579 74.348424 - H21 2.629814 23.060839 74.555233 - H22 3.856521 21.884133 74.379319 - C1 20.085934 5.105069 26.963087 - C2 20.039544 3.805047 27.280440 - H11 19.274110 5.635079 26.632881 - H12 20.936886 5.671615 27.025609 - H21 19.188591 3.238501 27.217918 - H22 20.851367 3.275037 27.610646 - C1 46.633719 75.051711 23.913491 - C2 45.945756 73.941177 23.619652 - H11 46.708048 75.436147 24.859899 - H12 47.139682 75.604001 23.214934 - H21 45.439794 73.388888 24.318209 - H22 45.871428 73.556741 22.673244 - C1 35.980963 26.010683 29.059666 - C2 35.054293 26.070682 30.024344 - H11 35.896107 26.499938 28.163880 - H12 36.847457 25.470818 29.141755 - H21 34.187800 26.610547 29.942255 - H22 35.139149 25.581427 30.920130 - C1 64.996109 74.330667 79.341201 - C2 64.023626 75.241273 79.475341 - H11 65.993574 74.561851 79.366131 - H12 64.818925 73.331395 79.203124 - H21 64.200810 76.240545 79.613418 - H22 63.026161 75.010089 79.450411 - C1 9.126784 41.934662 2.655272 - C2 9.220907 40.662912 3.063577 - H11 9.923767 42.477306 2.309788 - H12 8.250409 42.464728 2.656355 - H21 10.097282 40.132846 3.062495 - H22 8.423924 40.120268 3.409061 - C1 58.287992 28.522192 60.465467 - C2 57.076079 28.949100 60.842215 - H11 59.136736 29.089865 60.545370 - H12 58.461484 27.594426 60.067780 - H21 56.902587 29.876865 61.239902 - H22 56.227335 28.381427 60.762311 - C1 42.747720 4.328136 6.551441 - C2 42.473960 5.630428 6.699811 - H11 42.789156 3.667197 7.332751 - H12 42.937197 3.890605 5.644982 - H21 42.284483 6.067959 7.606270 - H22 42.432524 6.291367 5.918501 - C1 12.584574 25.221108 5.203097 - C2 13.345651 24.252086 4.678997 - H11 12.077367 25.908597 4.638205 - H12 12.449820 25.350979 6.210062 - H21 13.480405 24.122215 3.672032 - H22 13.852858 23.564597 5.243889 - C1 24.613068 30.371185 76.976580 - C2 23.691570 29.421573 77.181512 - H11 25.614906 30.176631 76.890133 - H12 24.388505 31.366730 76.890168 - H21 23.916132 28.426028 77.267924 - H22 22.689732 29.616127 77.267959 - C1 75.047854 24.325896 62.800126 - C2 75.885511 24.572211 63.815302 - H11 75.051852 23.453431 62.263664 - H12 74.337300 24.990596 62.480298 - H21 76.596064 23.907510 64.135130 - H22 75.881512 25.444676 64.351765 - C1 64.913005 44.929075 3.581243 - C2 65.204195 46.181027 3.956405 - H11 63.966879 44.615932 3.345043 - H12 65.613515 44.186209 3.500997 - H21 64.503685 46.923893 4.036651 - H22 66.150321 46.494170 4.192605 - C1 52.054562 41.846439 78.533413 - C2 51.083698 42.173096 79.395759 - H11 52.396111 40.889634 78.403522 - H12 52.531926 42.527712 77.935924 - H21 50.606333 41.491823 79.993248 - H22 50.742148 43.129901 79.525650 - C1 15.036213 75.025481 31.368600 - C2 14.805687 75.311447 32.656235 - H11 14.362265 74.541415 30.768203 - H12 15.904608 75.268337 30.882890 - H21 13.937292 75.068590 33.141944 - H22 15.479635 75.795513 33.256632 - C1 53.198298 46.491980 3.913145 - C2 54.454873 46.035425 3.987290 - H11 52.643812 46.482251 3.052067 - H12 52.692874 46.886809 4.711682 - H21 54.960296 45.640596 3.188753 - H22 55.009359 46.045154 4.848367 - C1 72.326105 23.972012 59.099582 - C2 73.508216 24.329227 59.617204 - H11 71.742527 24.599420 58.538512 - H12 71.912583 23.043296 59.224044 - H21 73.921738 25.257942 59.492743 - H22 74.091794 23.701818 60.178274 - C1 49.839448 17.174431 26.673828 - C2 49.223450 16.866684 27.822201 - H11 50.569085 16.593190 26.250990 - H12 49.629399 18.015253 26.128025 - H21 49.433499 16.025862 28.368004 - H22 48.493813 17.447925 28.245040 - C1 3.146576 68.472381 53.317966 - C2 3.421245 68.365466 52.011808 - H11 3.311149 67.719957 53.993079 - H12 2.750322 69.314986 53.744584 - H21 3.817499 67.522862 51.585190 - H22 3.256671 69.117890 51.336695 - C1 77.607820 6.773850 23.619720 - C2 77.939739 5.480494 23.719629 - H11 76.978483 7.247556 24.274351 - H12 77.957187 7.391078 22.880818 - H21 77.590372 4.863267 24.458531 - H22 78.569076 5.006788 23.064998 - C1 14.461098 22.658831 70.577843 - C2 15.317370 22.874276 71.584473 - H11 14.468702 21.812285 70.001383 - H12 13.731238 23.323650 70.305221 - H21 16.047230 22.209457 71.857096 - H22 15.309766 23.720822 72.160934 - C1 26.420808 5.688563 54.232085 - C2 26.372204 4.360283 54.070126 - H11 25.588653 6.285075 54.258437 - H12 27.293961 6.212443 54.342344 - H21 25.499050 3.836403 53.959867 - H22 27.204359 3.763771 54.043774 - C1 59.195060 44.136081 19.584220 - C2 57.886765 44.416098 19.637851 - H11 59.922114 44.764928 19.937698 - H12 59.571540 43.271043 19.185503 - H21 57.510285 45.281137 20.036568 - H22 57.159711 43.787252 19.284372 - C1 21.706549 23.469656 3.274283 - C2 22.996227 23.827695 3.236092 - H11 20.932914 24.134862 3.184879 - H12 21.392352 22.502447 3.395900 - H21 23.310424 24.794904 3.114475 - H22 23.769862 23.162488 3.325496 - C1 32.879535 75.463869 67.088913 - C2 33.151730 74.348782 67.778414 - H11 32.895747 75.513455 66.066034 - H12 32.633728 76.354849 67.530205 - H21 33.397537 73.457803 67.337122 - H22 33.135518 74.299196 68.801293 - C1 71.999186 26.178111 79.767232 - C2 72.673464 25.021326 79.756329 - H11 70.976611 26.235682 79.772577 - H12 72.453015 27.096276 79.771084 - H21 72.219636 24.103160 79.752477 - H22 73.696040 24.963754 79.750984 - C1 35.121508 46.294879 26.631603 - C2 34.583453 46.719304 27.781943 - H11 35.700676 45.453579 26.555571 - H12 34.996184 46.778182 25.737335 - H21 34.708777 46.236001 28.676212 - H22 34.004285 47.560604 27.857976 - C1 46.800621 54.542786 60.587135 - C2 46.442531 53.252648 60.571721 - H11 47.774968 54.858462 60.586315 - H12 46.128319 55.315329 60.600956 - H21 47.114833 52.480105 60.557899 - H22 45.468185 52.936972 60.572541 - C1 23.590054 30.527222 64.819036 - C2 23.181570 29.368837 64.285927 - H11 22.953483 31.212076 65.237075 - H12 24.571178 30.819455 64.850671 - H21 22.200447 29.076604 64.254292 - H22 23.818141 28.683983 63.867888 - C1 63.996808 68.310533 58.060059 - C2 65.294167 68.009046 57.922629 - H11 63.242481 67.628758 57.936859 - H12 63.656826 69.246608 58.299180 - H21 65.634150 67.072971 57.683507 - H22 66.048494 68.690820 58.045829 - C1 59.759401 71.490598 57.570005 - C2 61.091401 71.606039 57.643298 - H11 59.127251 72.291427 57.480211 - H12 59.268022 70.592395 57.597976 - H21 61.582780 72.504242 57.615327 - H22 61.723551 70.805210 57.733092 - C1 49.378712 43.658744 11.222691 - C2 48.380314 42.771888 11.320716 - H11 49.231663 44.670861 11.167932 - H12 50.367901 43.394681 11.194768 - H21 47.391125 43.035951 11.348639 - H22 48.527363 41.759770 11.375475 - C1 59.252119 52.586795 72.306290 - C2 58.772381 51.584406 73.053276 - H11 59.385214 53.539495 72.657932 - H12 59.523679 52.479601 71.324573 - H21 58.500821 51.691600 74.034993 - H22 58.639286 50.631705 72.701635 - C1 34.622690 13.843977 13.747948 - C2 35.890745 14.065466 13.379301 - H11 33.813571 14.188507 13.222943 - H12 34.362217 13.312624 14.583903 - H21 36.151219 14.596819 12.543345 - H22 36.699864 13.720936 13.904305 - C1 69.076369 40.201630 76.189915 - C2 67.892029 40.501473 75.641868 - H11 69.190573 39.532142 76.956561 - H12 69.961144 40.618203 75.885540 - H21 67.007254 40.084900 75.946243 - H22 67.777825 41.170961 74.875222 - C1 36.258341 70.196333 36.134440 - C2 35.978604 71.486769 35.912077 - H11 37.211782 69.825326 36.182479 - H12 35.540856 69.478871 36.273962 - H21 36.696089 72.204231 35.772556 - H22 35.025163 71.857776 35.864038 - C1 11.062778 50.015159 35.792859 - C2 12.123653 50.923975 35.884781 - C3 13.025248 50.841619 36.952599 - C4 12.865969 49.850447 37.928494 - C5 11.804694 48.942452 37.836980 - C6 10.903099 49.024808 36.769162 - H11 10.367225 50.078977 34.969483 - H21 12.247025 51.688343 35.131612 - H31 13.844173 51.542169 37.022805 - H41 13.561122 49.787450 38.752277 - H51 11.681322 48.178085 38.590148 - H61 10.084574 48.323438 36.698548 - C1 53.294808 46.122258 50.226779 - C2 54.489966 45.399823 50.324426 - C3 54.510911 44.035760 50.010126 - C4 53.336697 43.394132 49.598180 - C5 52.141622 44.116339 49.501504 - C6 52.120677 45.480402 49.815804 - H11 53.278639 47.174210 50.469576 - H21 55.396094 45.894846 50.641639 - H31 55.433207 43.478832 50.084543 - H41 53.352949 42.341952 49.356354 - H51 51.235494 43.621315 49.184291 - H61 51.198298 46.037558 49.740417 - C1 21.146467 40.264329 35.737381 - C2 21.505903 39.185412 36.553834 - C3 20.661975 38.073051 36.655471 - C4 19.458612 38.039607 35.940655 - C5 19.098913 39.118801 35.125125 - C6 19.942840 40.231162 35.023488 - H11 21.797212 41.122382 35.659343 - H21 22.434569 39.210805 37.104901 - H31 20.939897 37.240391 37.284576 - H41 18.807604 37.181831 36.019616 - H51 18.170246 39.093408 34.574058 - H61 19.665182 41.063544 34.393459 - C1 52.300603 9.471745 43.584351 - C2 52.800112 8.164303 43.614980 - C3 53.787942 7.814053 44.543101 - C4 54.276263 8.771245 45.440592 - C5 53.777437 10.078655 45.409232 - C6 52.789607 10.428906 44.481111 - H11 51.539014 9.741912 42.868247 - H21 52.423023 7.425554 42.923030 - H31 54.172443 6.805137 44.567255 - H41 55.038535 8.501046 46.155966 - H51 54.154525 10.817405 46.101182 - H61 52.404423 11.437853 44.457688 - C1 29.444335 31.550344 51.630983 - C2 29.975894 32.816585 51.359082 - C3 31.331156 33.072904 51.598784 - C4 32.154858 32.062983 52.110388 - C5 31.623058 30.797298 52.383085 - C6 30.267796 30.540978 52.143383 - H11 28.398985 31.352839 51.446457 - H21 29.340661 33.595666 50.963794 - H31 31.741272 34.049491 51.388023 - H41 33.199967 32.261044 52.295710 - H51 32.258291 30.018217 52.778373 - H61 29.857920 29.563836 52.353348 - C1 67.928825 26.154463 69.078419 - C2 68.201830 27.024965 70.140278 - C3 68.971030 28.174318 69.922998 - C4 69.467225 28.453169 68.643859 - C5 69.194989 27.582249 67.582482 - C6 68.425789 26.432896 67.799762 - H11 67.335897 25.267831 69.246149 - H21 67.818563 26.810283 71.127070 - H31 69.180691 28.846268 70.742060 - H41 70.060923 29.339383 68.476612 - H51 69.578256 27.796932 66.595690 - H61 68.215358 25.761364 66.980217 - C1 50.530996 32.623247 10.031290 - C2 51.707498 32.022408 9.567946 - C3 51.650791 30.787857 8.910254 - C4 50.417582 30.154146 8.715905 - C5 49.241472 30.754534 9.180051 - C6 49.298179 31.989085 9.837744 - H11 50.574844 33.575217 10.538878 - H21 52.658937 32.511495 9.717270 - H31 52.558383 30.324975 8.551989 - H41 50.374125 29.201725 8.209119 - H51 48.290032 30.265447 9.030728 - H61 48.390196 32.452419 10.195206 - C1 38.086556 34.617106 72.582305 - C2 37.908094 35.019336 71.253315 - C3 37.066322 36.097567 70.955443 - C4 36.403012 36.773569 71.986561 - C5 36.580789 36.370711 73.315182 - C6 37.422562 35.292479 73.613054 - H11 38.735486 33.785258 72.811937 - H21 38.420259 34.498281 70.457745 - H31 36.929556 36.408362 69.930241 - H41 35.753397 37.604789 71.756560 - H51 36.068625 36.891765 74.110752 - H61 37.560012 34.982314 74.638624 - C1 60.594748 77.093077 34.230396 - C2 59.685276 78.139307 34.035162 - C3 59.525972 79.121154 35.020296 - C4 60.276139 79.056771 36.200664 - C5 61.184720 78.010157 36.396144 - C6 61.344025 77.028310 35.411010 - H11 60.717279 76.335639 33.470734 - H21 59.106894 78.189452 33.124283 - H31 58.825059 79.928738 34.869079 - H41 60.152718 79.813826 36.960573 - H51 61.763102 77.960013 37.307023 - H61 62.045828 76.221111 35.561981 - C1 20.710089 72.503180 73.820492 - C2 20.604713 73.456327 74.840423 - C3 20.968560 73.122681 76.150456 - C4 21.437783 71.835888 76.440558 - C5 21.542196 70.882725 75.420896 - C6 21.178349 71.216371 74.110863 - H11 20.429083 72.760454 72.810215 - H21 20.243303 74.449326 74.616645 - H31 20.888156 73.858406 76.936955 - H41 21.717826 71.578597 77.451104 - H51 21.903606 69.889726 75.644674 - H61 21.259716 70.480663 73.324095 - C1 47.098403 56.812347 64.611333 - C2 46.580886 57.038260 65.892345 - C3 45.196977 57.132734 66.081453 - C4 44.330585 57.001295 64.989550 - C5 44.848183 56.776369 63.708677 - C6 46.232092 56.681895 63.519569 - H11 48.165779 56.739884 64.465490 - H21 47.249162 57.139072 66.734951 - H31 44.797876 57.306009 67.069902 - H41 43.263290 57.074745 65.135531 - H51 44.179907 56.675557 62.866071 - H61 46.631111 56.507633 62.530981 - C1 9.618287 9.578244 61.590349 - C2 10.404986 10.190625 60.607523 - C3 10.299210 11.568666 60.384578 - C4 9.406735 12.334326 61.144457 - C5 8.619553 11.721774 62.126424 - C6 8.725329 10.343733 62.349369 - H11 9.699634 8.515351 61.761978 - H21 11.094030 9.600144 60.021612 - H31 10.906907 12.041077 59.627037 - H41 9.324905 13.397047 60.971969 - H51 7.930509 12.312255 62.712335 - H61 8.118115 9.871492 63.107769 - C1 44.870027 13.139396 45.190919 - C2 43.538555 12.834193 44.884515 - C3 43.124251 11.498621 44.817496 - C4 44.041419 10.468252 45.056882 - C5 45.372837 10.773516 45.362290 - C6 45.787141 12.109088 45.429309 - H11 45.189586 14.169476 45.242207 - H21 42.830695 13.629038 44.700408 - H31 42.096832 11.263386 44.582101 - H41 43.721806 9.438233 45.004597 - H51 46.080698 9.978671 45.546397 - H61 46.814615 12.344261 45.665700 - C1 52.497406 20.925612 16.415631 - C2 51.669241 21.397905 15.390482 - C3 50.427042 20.794694 15.160334 - C4 50.013008 19.719188 15.955335 - C5 50.841528 19.246469 16.979652 - C6 52.083727 19.849681 17.209800 - H11 53.455617 21.390635 16.592828 - H21 51.988269 22.228056 14.777447 - H31 49.787859 21.159821 14.370102 - H41 49.055152 19.253739 15.777306 - H51 50.522499 18.416319 17.592687 - H61 52.722554 19.484979 18.000865 - C1 24.785781 27.107394 53.102127 - C2 25.193046 28.343989 52.587520 - C3 26.543148 28.569422 52.293760 - C4 27.485986 27.558260 52.514607 - C5 27.078801 26.322262 53.030013 - C6 25.728698 26.096829 53.323773 - H11 23.744549 26.933728 53.329037 - H21 24.465663 29.123994 52.416503 - H31 26.856998 29.523094 51.895833 - H41 28.527298 27.732524 52.288496 - H51 27.806184 25.542257 53.201030 - H61 25.414770 25.142561 53.720901 - C1 50.525277 72.783647 25.289144 - C2 49.153820 72.880613 25.025416 - C3 48.333909 71.753851 25.159742 - C4 48.885455 70.530122 25.557796 - C5 50.256838 70.433085 25.820529 - C6 51.076749 71.559848 25.686203 - H11 51.157648 73.652615 25.185146 - H21 48.728049 73.824811 24.718901 - H31 47.275767 71.829081 24.957225 - H41 48.253009 69.661084 25.660800 - H51 50.682609 69.488888 26.127044 - H61 52.134966 71.484688 25.889715 - C1 32.082127 27.566998 31.080895 - C2 31.894371 27.230390 29.735052 - C3 31.381799 25.973361 29.392944 - C4 31.056981 25.052940 30.396679 - C5 31.245640 25.389262 31.742201 - C6 31.758212 26.646291 32.084309 - H11 32.477823 28.536361 31.344665 - H21 32.144347 27.940628 28.960575 - H31 31.236078 25.714236 28.354697 - H41 30.662188 24.083291 30.132588 - H51 30.995664 24.679024 32.516678 - H61 31.903030 26.905703 33.122877 - C1 62.052587 4.640388 57.155783 - C2 61.439156 5.796857 56.659666 - C3 62.222068 6.873972 56.227507 - C4 63.618412 6.794619 56.291465 - C5 64.231584 5.638671 56.788395 - C6 63.448671 4.561555 57.220554 - H11 61.448694 3.809844 57.489437 - H21 60.361888 5.857985 56.609687 - H31 61.748693 7.765644 55.843874 - H41 64.222045 7.625683 55.958624 - H51 65.308852 5.577542 56.838374 - H61 63.922306 3.669362 57.603374 - C1 65.864915 7.295032 75.721770 - C2 66.736608 8.375512 75.902227 - C3 66.642760 9.497085 75.069667 - C4 65.677218 9.538178 74.056648 - C5 64.806368 8.457428 73.875725 - C6 64.900216 7.335855 74.708285 - H11 65.937607 6.429877 76.363671 - H21 67.481178 8.344213 76.684133 - H31 67.314638 10.330940 75.209671 - H41 65.605369 10.403063 73.414281 - H51 64.061798 8.488727 73.093819 - H61 64.227495 6.502269 74.568748 - C1 38.643009 5.896930 15.815791 - C2 38.954877 6.171989 14.479029 - C3 38.013740 6.802096 13.656158 - C4 36.760734 7.157142 14.170048 - C5 36.448705 6.881222 15.506326 - C6 37.389842 6.251116 16.329198 - H11 39.368769 5.410601 16.450275 - H21 39.921767 5.898683 14.082584 - H31 38.254869 7.015117 12.625228 - H41 36.034812 7.642610 13.535080 - H51 35.481815 7.154528 15.902771 - H61 37.148874 6.038955 17.360610 - C1 18.835907 34.085291 29.214624 - C2 17.504889 33.881634 28.831522 - C3 16.922678 32.615991 28.969611 - C4 17.671484 31.554005 29.490802 - C5 19.002537 31.757532 29.872913 - C6 19.584748 33.023175 29.734824 - H11 19.284999 35.061357 29.107731 - H21 16.926865 34.701018 28.429977 - H31 15.895561 32.459310 28.674959 - H41 17.222427 30.577809 29.596704 - H51 19.580561 30.938148 30.274458 - H61 20.611829 33.179986 30.030467 - C1 34.653660 34.544209 14.922092 - C2 34.301495 35.002237 13.646929 - C3 34.710638 34.293568 12.511024 - C4 35.471946 33.126871 12.650281 - C5 35.824779 32.669556 13.925234 - C6 35.415636 33.378225 15.061140 - H11 34.338405 35.091036 15.798111 - H21 33.713621 35.902000 13.539356 - H31 34.438019 34.646504 11.527432 - H41 35.787870 32.580757 11.774053 - H51 36.412653 31.769793 14.032808 - H61 35.687587 33.024577 16.044942 - C1 17.079075 43.199560 36.261501 - C2 16.269758 42.715912 37.296365 - C3 15.305947 41.735755 37.031315 - C4 15.151454 41.239245 35.731402 - C5 15.960045 41.723573 34.696636 - C6 16.923855 42.703731 34.961686 - H11 17.822134 43.955795 36.465915 - H21 16.389254 43.098434 38.299429 - H31 14.682384 41.362041 37.829966 - H41 14.407668 40.483691 35.527085 - H51 15.840549 41.341052 33.693571 - H61 17.548145 43.076764 34.162937 - C1 47.083885 22.890077 24.898457 - C2 48.199967 22.138147 25.284218 - C3 48.112060 20.742945 25.358892 - C4 46.908071 20.099674 25.047804 - C5 45.791997 20.851653 24.663042 - C6 45.879904 22.246854 24.588369 - H11 47.151640 23.966159 24.841263 - H21 49.129100 22.634253 25.523660 - H31 48.973438 20.162969 25.655527 - H41 46.840325 19.023640 25.105997 - H51 44.862864 20.355547 24.423601 - H61 45.018517 22.826782 24.290734 - C1 58.590666 76.397686 39.935030 - C2 59.226989 77.629216 40.130676 - C3 60.624528 77.694798 40.180444 - C4 61.385742 76.528850 40.034567 - C5 60.749382 75.297474 39.839909 - C6 59.351844 75.231892 39.790140 - H11 57.512791 76.347120 39.897046 - H21 58.639856 78.528929 40.242621 - H31 61.115269 78.645077 40.330374 - H41 62.463580 76.579570 40.073538 - H51 61.336515 74.397760 39.727963 - H61 58.861139 74.281459 39.639223 - C1 67.744664 44.639056 53.432475 - C2 68.929248 43.986433 53.070957 - C3 70.140940 44.687619 53.065292 - C4 70.168047 46.041428 53.421144 - C5 68.983462 46.694054 53.781662 - C6 67.771771 45.992867 53.787327 - H11 66.810113 44.098303 53.436445 - H21 68.908585 42.941802 52.796984 - H31 71.054828 44.183741 52.787348 - H41 71.102597 46.582184 53.416173 - H51 69.004125 47.738684 54.055634 - H61 66.857883 46.496742 54.066270 - C1 47.586472 6.087430 14.154551 - C2 46.566858 6.861905 14.720614 - C3 46.887936 7.959108 15.528665 - C4 48.228627 8.281836 15.770652 - C5 49.247953 7.506853 15.205401 - C6 48.926876 6.409650 14.397350 - H11 47.338768 5.240985 13.531664 - H21 45.532459 6.613409 14.533507 - H31 46.101240 8.557057 15.964444 - H41 48.476043 9.127773 16.394351 - H51 50.282353 7.755349 15.392508 - H61 49.713859 5.812209 13.960759 - C1 72.022819 75.805123 77.846738 - C2 71.596452 76.528398 76.726499 - C3 70.229921 76.741585 76.509623 - C4 69.289757 76.231497 77.412987 - C5 69.716135 75.507562 78.532475 - C6 71.082666 75.294375 78.749350 - H11 73.076761 75.640402 78.013736 - H21 72.321710 76.922524 76.029787 - H31 69.901237 77.300432 75.645914 - H41 68.235826 76.395558 77.245238 - H51 68.990877 75.113436 79.229187 - H61 71.411339 74.736188 79.613811 - C1 13.876209 53.715461 32.559930 - C2 13.052420 54.610791 31.867393 - C3 11.861896 54.159468 31.285284 - C4 11.495160 52.812815 31.395713 - C5 12.319359 51.917560 32.087341 - C6 13.509884 52.368883 32.669449 - H11 14.794589 54.063533 33.008526 - H21 13.334922 55.649902 31.782640 - H31 11.226018 54.850507 30.751935 - H41 10.577190 52.464818 30.946208 - H51 12.036857 50.878449 32.172093 - H61 14.145352 51.677769 33.203707 - C1 70.294633 56.335829 69.329187 - C2 71.343502 57.180307 69.712045 - C3 72.643955 56.674301 69.824609 - C4 72.895539 55.323816 69.554313 - C5 71.846609 54.479387 69.172451 - C6 70.546156 54.985394 69.059888 - H11 69.291607 56.726066 69.242770 - H21 71.149663 58.222380 69.920016 - H31 73.453142 57.326137 70.118996 - H41 73.898504 54.933629 69.641726 - H51 72.040448 53.437314 68.964481 - H61 69.737030 54.333508 68.764504 - C1 19.661506 53.536523 45.714543 - C2 19.224267 52.232735 45.452227 - C3 19.400660 51.678272 44.178906 - C4 20.014292 52.427596 43.167900 - C5 20.450552 53.731474 43.430036 - C6 20.274159 54.285937 44.703357 - H11 19.525079 53.964237 46.696511 - H21 18.751383 51.654282 46.232300 - H31 19.064204 50.672105 43.977010 - H41 20.149740 51.999972 42.185751 - H51 20.923436 54.309927 42.649963 - H61 20.611595 55.292015 44.905433 - C1 55.775018 43.260034 14.043063 - C2 55.584250 41.873199 14.055212 - C3 54.885524 41.272051 15.108917 - C4 54.377566 42.057738 16.150473 - C5 54.569190 43.444200 16.138684 - C6 55.267916 44.045347 15.084979 - H11 56.314263 43.723564 13.230555 - H21 55.975553 41.266975 13.251399 - H31 54.737582 40.202297 15.117612 - H41 53.839177 41.593835 16.963341 - H51 54.177887 44.050424 16.942497 - H61 55.415003 45.115475 15.075924 - C1 43.657517 35.874873 50.046350 - C2 43.967765 34.556168 49.693343 - C3 45.170679 34.272175 49.035896 - C4 46.063345 35.306886 48.731456 - C5 45.752599 36.625430 49.083612 - C6 44.549685 36.909424 49.741059 - H11 42.729566 36.093887 50.553060 - H21 43.279445 33.757693 49.928704 - H31 45.410310 33.254686 48.764547 - H41 46.990798 35.087711 48.223895 - H51 46.440919 37.423905 48.848251 - H61 44.310552 37.927074 50.013260 - C1 51.147529 71.310032 58.197977 - C2 49.801479 71.376701 57.819090 - C3 49.213126 70.306312 57.134985 - C4 49.970823 69.169254 56.829767 - C5 51.316871 69.103120 57.207809 - C6 51.905224 70.173509 57.891914 - H11 51.601344 72.135774 58.725251 - H21 49.216617 72.253630 58.055042 - H31 48.174450 70.357499 56.843664 - H41 49.517006 68.344047 56.301649 - H51 51.901733 68.226191 56.971857 - H61 52.943903 70.121787 58.184081 - C1 52.109535 3.051588 40.874965 - C2 53.412015 2.545858 40.787595 - C3 54.408616 3.027051 41.644992 - C4 54.102737 4.013973 42.589761 - C5 52.800676 4.520202 42.676373 - C6 51.804074 4.039010 41.818975 - H11 51.341038 2.680703 40.213398 - H21 53.648010 1.783996 40.059162 - H31 55.413108 2.636074 41.578127 - H41 54.871653 4.385358 43.250569 - H51 52.564681 5.282064 43.404805 - H61 50.799164 4.429487 41.886599 - C1 60.459130 57.842217 10.115312 - C2 61.557925 58.637976 10.460666 - C3 62.847597 58.093453 10.449120 - C4 63.038473 56.753172 10.092221 - C5 61.939691 55.957412 9.747868 - C6 60.650020 56.501935 9.759413 - H11 59.464448 58.262140 10.124616 - H21 61.410884 59.672199 10.735443 - H31 63.695238 58.707753 10.714594 - H41 64.033169 56.333247 10.083918 - H51 62.086732 54.923189 9.473091 - H61 59.802365 55.887636 9.492940 - C1 49.812882 47.692124 8.944751 - C2 50.399310 46.456854 8.644649 - C3 49.610496 45.407181 8.159005 - C4 48.235254 45.592778 7.973463 - C5 47.648899 46.827578 8.274445 - C6 48.437713 47.877251 8.760089 - H11 50.421251 48.501527 9.319674 - H21 51.460413 46.313706 8.787162 - H31 50.063230 44.454629 7.926595 - H41 47.626959 44.782905 7.599420 - H51 46.587796 46.970726 8.131932 - H61 47.984905 48.830272 8.991619 - C1 4.041680 59.762891 57.680625 - C2 4.456645 59.474929 58.986279 - C3 4.729841 60.517460 59.879802 - C4 4.588072 61.847954 59.467671 - C5 4.174086 62.135732 58.161940 - C6 3.900890 61.093201 57.268417 - H11 3.831369 58.958788 56.991422 - H21 4.565473 58.448486 59.304574 - H31 5.048980 60.295120 60.887300 - H41 4.799363 62.651873 60.156798 - H51 4.065258 63.162176 57.843646 - H61 3.580772 61.315725 56.260996 - C1 4.606380 19.249529 15.704471 - C2 5.814003 18.776144 15.177779 - C3 5.919253 17.445873 14.754467 - C4 4.816881 16.588988 14.857847 - C5 3.609820 17.062158 15.385338 - C6 3.504569 18.392429 15.808650 - H11 4.525389 20.275414 16.031297 - H21 6.664395 19.437287 15.097387 - H31 6.850637 17.081132 14.347250 - H41 4.898434 15.562888 14.531821 - H51 2.759428 16.401014 15.465730 - H61 2.572625 18.757385 16.215069 - C1 36.841244 69.917383 18.694259 - C2 36.648419 71.279528 18.434969 - C3 35.432802 71.889801 18.766228 - C4 34.410009 71.137929 19.356777 - C5 34.602587 69.775829 19.615099 - C6 35.818204 69.165555 19.283840 - H11 37.778678 69.446680 18.438390 - H21 37.437644 71.859871 17.979924 - H31 35.284592 72.940848 18.567051 - H41 33.472327 71.608676 19.611678 - H51 33.813362 69.195485 20.070144 - H61 35.966661 68.114464 19.483984 - C1 27.742848 45.192928 76.312891 - C2 29.056680 45.420393 76.739456 - C3 29.856480 46.356817 76.073632 - C4 29.342448 47.065775 74.981243 - C5 28.029151 46.837571 74.554269 - C6 27.229351 45.901147 75.220093 - H11 27.126180 44.470408 76.826212 - H21 29.453196 44.873947 77.582612 - H31 30.869665 46.532891 76.403468 - H41 29.959651 47.787556 74.467513 - H51 27.632635 47.384017 73.711113 - H61 26.215632 45.725812 74.890667 - C1 39.562064 22.534954 53.849846 - C2 38.496173 22.997698 53.069082 - C3 37.584872 22.088242 52.519253 - C4 37.739463 20.716042 52.750189 - C5 38.805747 20.253445 53.530046 - C6 39.717048 21.162902 54.079875 - H11 40.265100 23.236402 54.273551 - H21 38.376421 24.056380 52.891335 - H31 36.762085 22.445476 51.917802 - H41 37.036820 20.014742 52.325576 - H51 38.925498 19.194764 53.707792 - H61 40.539442 20.805520 54.682234 - C1 51.371117 6.534399 68.863503 - C2 50.225289 7.102707 68.294332 - C3 48.971145 6.879827 68.875141 - C4 48.862830 6.088639 70.025121 - C5 50.008413 5.519718 70.593541 - C6 51.262557 5.742598 70.012732 - H11 52.338306 6.706016 68.415275 - H21 50.308773 7.713644 67.407468 - H31 48.087441 7.319147 68.436505 - H41 47.895397 5.916409 70.472598 - H51 49.924929 4.908781 71.480404 - H61 52.146506 5.303891 70.452119 - C1 25.234587 20.817880 41.221172 - C2 25.362586 22.151632 40.815496 - C3 24.354211 23.074740 41.117063 - C4 23.217838 22.664097 41.824305 - C5 23.089552 21.330350 42.229024 - C6 24.097926 20.407242 41.927457 - H11 26.012159 20.105892 40.988214 - H21 26.239535 22.468731 40.270382 - H31 24.453589 24.103827 40.804907 - H41 22.439978 23.376090 42.056306 - H51 22.212602 21.013252 42.774138 - H61 23.998837 19.378150 42.240570 - C1 37.740176 27.237069 33.665400 - C2 37.826107 26.059663 34.417849 - C3 36.661644 25.452494 34.902888 - C4 35.411250 26.022732 34.635478 - C5 35.325541 27.200442 33.883955 - C6 36.490004 27.807611 33.398916 - H11 38.638341 27.705514 33.291672 - H21 38.790684 25.619265 34.623718 - H31 36.728056 24.543652 35.482485 - H41 34.513307 25.554590 35.010133 - H51 34.360964 27.640839 33.678086 - H61 36.423370 28.716149 32.818392 - C1 22.948070 56.283354 69.594730 - C2 24.273394 56.154093 69.162687 - C3 25.271079 55.775147 70.068731 - C4 24.943442 55.525462 71.406817 - C5 23.618480 55.655655 71.838859 - C6 22.620795 56.034601 70.932816 - H11 22.178713 56.576002 68.895974 - H21 24.526218 56.346096 68.130236 - H31 26.293261 55.674502 69.735036 - H41 25.713161 55.233747 72.105573 - H51 23.365656 55.463653 72.871311 - H61 21.598251 56.134314 71.266512 - C1 11.284130 58.033471 60.036500 - C2 11.392749 56.890002 59.236167 - C3 10.404349 56.603598 58.286995 - C4 9.307329 57.460662 58.138155 - C5 9.198370 58.603384 58.939060 - C6 10.186771 58.889788 59.888233 - H11 12.046276 58.254095 60.768806 - H21 12.239366 56.229004 59.350458 - H31 10.488820 55.721975 57.668979 - H41 8.544843 57.239291 57.406421 - H51 8.351753 59.264382 58.824770 - H61 10.102640 59.772157 60.505676 - C1 21.247034 65.318310 38.392307 - C2 21.687357 64.155183 37.749576 - C3 20.943793 63.614821 36.693634 - C4 19.759907 64.237584 36.280423 - C5 19.319282 65.399962 36.923744 - C6 20.062845 65.940325 37.979686 - H11 21.820354 65.734796 39.206958 - H21 22.601039 63.674949 38.067855 - H31 21.284155 62.718101 36.197262 - H41 19.186284 63.820350 35.466362 - H51 18.405600 65.880196 36.605464 - H61 19.722786 66.837793 38.475468 - C1 14.284063 44.623741 32.727134 - C2 13.838584 45.891044 32.332998 - C3 12.476926 46.208087 32.405535 - C4 11.560746 45.257826 32.872208 - C5 12.006155 43.990472 33.265348 - C6 13.367813 43.673429 33.192810 - H11 15.334213 44.379153 32.670794 - H21 14.545386 46.624491 31.973515 - H31 12.133577 47.186122 32.102392 - H41 10.510525 45.502364 32.927551 - H51 11.299353 43.257025 33.624830 - H61 13.711232 42.695445 33.496950 - C1 75.918341 39.567726 53.281989 - C2 76.064161 40.549653 52.294869 - C3 75.009511 41.428564 52.020786 - C4 73.809041 41.325547 52.733824 - C5 73.663042 40.343145 53.720082 - C6 74.717692 39.464235 53.994165 - H11 76.731646 38.889641 53.493056 - H21 76.990495 40.629650 51.745098 - H31 75.122539 42.186645 51.259948 - H41 72.995558 42.003157 52.521895 - H51 72.736709 40.263149 54.269853 - H61 74.604842 38.706628 54.755864 - C1 60.210747 22.643934 56.578270 - C2 59.248425 22.369468 57.557277 - C3 57.896549 22.280997 57.204437 - C4 57.506996 22.466991 55.872589 - C5 58.469141 22.742337 54.894021 - C6 59.821017 22.830809 55.246862 - H11 61.253330 22.712541 56.850535 - H21 59.548884 22.225338 58.584746 - H31 57.154426 22.068259 57.959640 - H41 56.464236 22.399264 55.600763 - H51 58.168682 22.886467 53.866552 - H61 60.563318 23.042666 54.491219 - C1 22.552182 6.842566 8.947793 - C2 23.080084 6.017410 9.947937 - C3 23.491959 4.716137 9.636588 - C4 23.375932 4.240020 8.325094 - C5 22.847232 5.064805 7.325424 - C6 22.435357 6.366078 7.636774 - H11 22.234177 7.846036 9.188072 - H21 23.170233 6.384810 10.959684 - H31 23.900113 4.080067 10.408055 - H41 23.693139 3.236178 8.085289 - H51 22.757084 4.697405 6.313678 - H61 22.028002 7.002520 6.864832 - C1 76.442127 45.904500 75.658379 - C2 75.686749 46.873511 76.329401 - C3 74.341964 46.627513 76.630945 - C4 73.752557 45.412502 76.261468 - C5 74.507654 44.444133 75.589734 - C6 75.852439 44.690132 75.288190 - H11 77.479190 46.094449 75.425495 - H21 76.141511 47.810703 76.615066 - H31 73.759664 47.374755 77.149494 - H41 72.715213 45.223196 76.493640 - H51 74.052891 43.506942 75.304069 - H61 76.435021 43.942247 74.770353 - C1 29.430326 43.912510 31.535105 - C2 29.289848 43.148188 32.699549 - C3 30.077445 43.431272 33.821799 - C4 31.005521 44.478677 33.779605 - C5 31.146542 45.242176 32.614995 - C6 30.358945 44.959092 31.492745 - H11 28.823132 43.693876 30.669468 - H21 28.573436 42.340468 32.732458 - H31 29.968227 42.842185 34.720345 - H41 31.613258 44.696488 34.645076 - H51 31.862954 46.049896 32.582086 - H61 30.467620 45.549002 30.594365 - C1 76.767680 35.681643 14.946516 - C2 76.934112 34.360451 14.514539 - C3 77.797978 33.501955 15.204910 - C4 78.495412 33.964650 16.327257 - C5 78.329642 35.285898 16.758485 - C6 77.465776 36.144394 16.068115 - H11 76.101702 36.343824 14.413785 - H21 76.395633 34.003155 13.649022 - H31 77.925477 32.482477 14.872123 - H41 79.162052 33.302525 16.859239 - H51 78.868121 35.643194 17.624003 - H61 77.337615 37.163815 16.401650 - C1 63.371417 49.145041 19.395250 - C2 64.103155 48.703274 20.503966 - C3 64.771553 49.628095 21.315041 - C4 64.708213 50.994682 21.017399 - C5 63.977353 51.436151 19.908307 - C6 63.308955 50.511330 19.097233 - H11 62.856257 48.431680 18.769518 - H21 64.151607 47.649026 20.734082 - H31 65.335165 49.287208 22.170888 - H41 65.224251 51.707745 21.642755 - H51 63.928901 52.490399 19.678192 - H61 62.744465 50.852516 18.241760 - C1 58.378701 28.043993 49.811918 - C2 57.028672 27.854779 50.130464 - C3 56.106338 28.884396 49.908926 - C4 56.534033 30.103228 49.368842 - C5 57.884004 30.292609 49.051280 - C6 58.806338 29.262992 49.272818 - H11 59.090071 27.249991 49.983170 - H21 56.698448 26.914277 50.546577 - H31 55.064744 28.737896 50.153787 - H41 55.822605 30.897397 49.198574 - H51 58.214228 31.233111 48.635168 - H61 59.847989 29.409324 49.026973 - C1 46.598888 56.266862 53.150270 - C2 46.660784 57.664344 53.205617 - C3 45.819104 58.368300 54.075049 - C4 44.915527 57.674773 54.889133 - C5 44.853081 56.277603 54.833010 - C6 45.694762 55.573647 53.963579 - H11 47.247793 55.724016 52.479409 - H21 47.358282 58.199506 52.578052 - H31 45.867696 59.446308 54.118344 - H41 44.266072 58.217931 55.559218 - H51 44.155583 55.742440 55.460576 - H61 45.646718 54.495327 53.921059 - C1 47.299262 52.822013 5.193982 - C2 46.125231 53.435533 4.741108 - C3 44.886414 52.819257 4.954243 - C4 44.821627 51.589461 5.620253 - C5 45.995604 50.975705 6.072157 - C6 47.234421 51.591980 5.859021 - H11 48.254709 53.297184 5.029221 - H21 46.175002 54.384629 4.227804 - H31 43.980737 53.293181 4.605700 - H41 43.866125 51.114053 5.784043 - H51 45.945833 50.026609 6.585461 - H61 48.140153 51.118293 6.208535 - C1 53.864426 15.037754 35.287495 - C2 53.501651 16.166724 34.543403 - C3 52.161088 16.376785 34.198939 - C4 51.183300 15.457878 34.598568 - C5 51.546276 14.328665 35.341712 - C6 52.886839 14.118604 35.686175 - H11 54.898416 14.875600 35.552796 - H21 54.255826 16.876077 34.235541 - H31 51.881273 17.248293 33.625777 - H41 50.149510 15.619789 34.332318 - H51 50.792100 13.619312 35.649573 - H61 53.166453 13.247339 36.260287 - C1 46.043533 79.854902 18.061900 - C2 46.693186 79.740874 19.296727 - C3 45.945910 79.559526 20.466591 - C4 44.548980 79.492206 20.401628 - C5 43.899521 79.607176 19.167076 - C6 44.646797 79.788524 17.997212 - H11 46.619913 79.995159 17.159720 - H21 47.770956 79.792175 19.346930 - H31 46.447300 79.470571 21.418974 - H41 43.972794 79.352891 21.304083 - H51 42.821751 79.555874 19.116874 - H61 44.145213 79.876537 17.044554 - C1 3.579031 44.090882 75.641518 - C2 2.567836 44.925454 75.150778 - C3 2.749648 45.609511 73.942928 - C4 3.942654 45.458996 73.225818 - C5 4.953961 44.625283 73.717057 - C6 4.772149 43.941226 74.924907 - H11 3.438899 43.563633 76.573283 - H21 1.647121 45.041197 75.703613 - H31 1.969064 46.252503 73.563999 - H41 4.082899 45.987105 72.294552 - H51 5.874677 44.509540 73.164221 - H61 5.552621 43.297375 75.303338 - C1 37.273336 19.082814 70.480023 - C2 38.526632 18.899173 71.076158 - C3 39.297499 20.009350 71.441073 - C4 38.815071 21.303167 71.209851 - C5 37.562399 21.486632 70.612953 - C6 36.791531 20.376455 70.248039 - H11 36.679021 18.226539 70.198248 - H21 38.898694 17.901043 71.255173 - H31 40.263877 19.867494 71.901862 - H41 39.410009 22.159266 71.490864 - H51 37.190336 22.484762 70.433938 - H61 35.824530 20.518487 69.788011 - C1 4.095503 29.709670 29.957575 - C2 4.879459 28.920381 29.107700 - C3 5.863845 29.515749 28.309946 - C4 6.064275 30.900406 28.362067 - C5 5.279753 31.689553 29.211129 - C6 4.295367 31.094185 30.008884 - H11 3.336042 29.250473 30.572532 - H21 4.725357 27.852015 29.067837 - H31 6.469204 28.906580 27.655126 - H41 6.823170 31.359461 27.746298 - H51 5.433854 32.757919 29.250993 - H61 3.690573 31.703496 30.664516 - C1 71.138438 47.730880 59.877076 - C2 72.096428 48.426553 59.129985 - C3 71.805765 49.703294 58.634668 - C4 70.557112 50.284361 58.886441 - C5 69.599044 49.588317 59.632607 - C6 69.889707 48.311576 60.127924 - H11 71.362537 46.746028 60.258731 - H21 73.060042 47.978637 58.936181 - H31 72.545280 50.240230 58.059208 - H41 70.332936 51.268842 58.503860 - H51 68.635430 50.036232 59.826411 - H61 69.150269 47.775011 60.704309 - C1 55.605901 57.740572 33.982884 - C2 54.237354 57.909180 34.224754 - C3 53.394058 56.793179 34.282076 - C4 53.919309 55.508571 34.097529 - C5 55.287467 55.340206 33.854771 - C6 56.130763 56.456207 33.797449 - H11 56.256178 58.601366 33.938298 - H21 53.832076 58.900158 34.367765 - H31 52.338503 56.923364 34.469674 - H41 53.268643 54.648020 34.141227 - H51 55.692745 54.349228 33.711759 - H61 57.186707 56.325780 33.610739 - C1 3.633134 73.519045 15.008571 - C2 2.453559 72.836793 14.687656 - C3 1.968083 72.857613 13.374732 - C4 2.662182 73.560684 12.382723 - C5 3.841020 74.243553 12.703915 - C6 4.326496 74.222733 14.016839 - H11 4.007296 73.503271 16.021275 - H21 1.918278 72.293813 15.452762 - H31 1.058640 72.330406 13.127135 - H41 2.287284 73.577075 11.370296 - H51 4.376301 74.786533 11.938809 - H61 5.236676 74.749322 14.264160 - C1 18.992609 2.051244 20.407249 - C2 19.321729 3.409158 20.320063 - C3 20.449893 3.810701 19.594875 - C4 21.248938 2.854331 18.956872 - C5 20.920301 1.496620 19.044910 - C6 19.792136 1.095076 19.770099 - H11 18.122713 1.741586 20.966897 - H21 18.705005 4.147172 20.811721 - H31 20.703066 4.858374 19.526885 - H41 22.119317 3.164191 18.398076 - H51 21.537024 0.758605 18.553252 - H61 19.538481 0.047201 19.837237 - C1 67.590062 32.240509 55.030226 - C2 68.223285 33.354376 55.594300 - C3 67.469323 34.318334 56.274165 - C4 66.082138 34.168425 56.389957 - C5 65.449036 33.055196 55.825123 - C6 66.202998 32.091238 55.145258 - H11 68.171570 31.497287 54.505551 - H21 69.293582 33.469855 55.505579 - H31 67.958112 35.177035 56.710119 - H41 65.500751 34.912285 56.913871 - H51 64.378740 32.939717 55.913844 - H61 65.714088 31.231899 54.710064 - C1 31.771696 15.978520 24.590832 - C2 32.279130 14.684032 24.754117 - C3 33.106985 14.127737 23.771731 - C4 33.427407 14.865931 22.626059 - C5 32.919232 16.159815 22.462484 - C6 32.091376 16.716110 23.444870 - H11 31.132896 16.407358 25.348358 - H21 32.032508 14.114620 25.638249 - H31 33.499164 13.129487 23.898336 - H41 34.065465 14.436489 21.868243 - H51 33.165853 16.729227 21.578352 - H61 31.699939 17.714964 23.318555 - C1 53.376436 17.310462 72.585788 - C2 53.103761 18.660863 72.336957 - C3 52.618232 19.477801 73.364948 - C4 52.405378 18.944338 74.641770 - C5 52.677148 17.593942 74.890176 - C6 53.162676 16.777004 73.862186 - H11 53.750531 16.680356 71.792798 - H21 53.268514 19.072724 71.352087 - H31 52.408890 20.519768 73.173068 - H41 52.030378 19.574450 75.434335 - H51 52.512395 17.182082 75.875046 - H61 53.372924 15.735033 74.054490 - C1 52.368204 56.684855 6.715664 - C2 51.805454 55.798829 7.642012 - C3 52.633241 55.057725 8.493732 - C4 54.023777 55.202647 8.419102 - C5 54.586333 56.087844 7.492230 - C6 53.758546 56.828948 6.640511 - H11 51.729727 57.256115 6.058532 - H21 50.732635 55.687371 7.700128 - H31 52.198898 54.375007 9.208979 - H41 54.662059 54.630557 9.075710 - H51 55.659152 56.199302 7.434114 - H61 54.193083 57.512495 5.925787 - C1 5.621355 74.786851 36.629287 - C2 6.128648 75.810816 37.437991 - C3 5.431992 76.205973 38.586212 - C4 4.228043 75.577165 38.925730 - C5 3.720473 74.554048 38.116573 - C6 4.417128 74.158891 36.968351 - H11 6.158506 74.482399 35.743515 - H21 7.057807 76.295619 37.176513 - H31 5.824000 76.995228 39.210506 - H41 3.690615 75.882464 39.811048 - H51 2.791314 74.069244 38.378051 - H61 4.025398 73.368789 36.344511 - C1 30.663575 64.063202 25.215756 - C2 29.582132 63.670962 26.013553 - C3 28.437124 64.473379 26.084082 - C4 28.373559 65.668036 25.356814 - C5 29.455251 66.060559 24.559944 - C6 30.600259 65.258142 24.489415 - H11 31.546796 63.444482 25.161712 - H21 29.630783 62.748993 26.574220 - H31 27.602554 64.170130 26.698794 - H41 27.490587 66.287039 25.411785 - H51 29.406601 66.982527 23.999277 - H61 31.434580 65.561108 23.873777 - C1 65.660002 24.287146 52.450829 - C2 64.425978 24.884199 52.734666 - C3 63.449327 24.171246 53.440174 - C4 63.706701 22.861239 53.861844 - C5 64.940190 22.264080 53.577169 - C6 65.916840 22.977033 52.871661 - H11 66.413061 24.836934 51.906357 - H21 64.227497 25.895091 52.409944 - H31 62.497787 24.632350 53.659924 - H41 62.953106 22.311345 54.405478 - H51 65.138671 21.253188 53.901891 - H61 66.868916 22.516036 52.652749 - C1 78.439171 6.769237 67.969435 - C2 77.548915 7.351295 67.059213 - C3 77.496179 6.889098 65.738803 - C4 78.333699 5.844843 65.328614 - C5 79.224416 5.263614 66.238521 - C6 79.277152 5.725812 67.558931 - H11 78.480071 7.126020 68.987692 - H21 76.902263 8.156542 67.375694 - H31 76.808627 7.337562 65.037026 - H41 78.293260 5.488890 64.310043 - H51 79.871068 4.458368 65.922040 - H61 79.964243 5.276518 68.261022 - C1 61.859427 61.338298 45.152022 - C2 61.519949 62.651773 45.497549 - C3 62.526022 63.601505 45.711365 - C4 63.871573 63.237762 45.579656 - C5 64.210878 61.924256 45.235114 - C6 63.204805 60.974524 45.021297 - H11 61.083449 60.605762 44.987512 - H21 60.481871 62.932706 45.598597 - H31 62.263922 64.614974 45.976924 - H41 64.647378 63.970267 45.745150 - H51 65.248956 61.643323 45.134065 - H61 63.467078 59.961086 44.754754 - C1 27.762700 11.499647 46.279688 - C2 28.342965 10.910748 45.149936 - C3 29.734357 10.914592 44.995321 - C4 30.545483 11.507335 45.970459 - C5 29.965141 12.096926 47.099494 - C6 28.573749 12.093082 47.254108 - H11 26.689551 11.496993 46.398682 - H21 27.717338 10.452860 44.397825 - H31 30.181878 10.459357 44.124216 - H41 31.618554 11.510681 45.850747 - H51 30.590767 12.554814 47.851605 - H61 28.126304 12.547624 48.125931 - C1 77.449576 49.520592 12.824498 - C2 76.620764 49.352539 13.940150 - C3 76.463485 48.083693 14.510400 - C4 77.135020 46.982901 13.964999 - C5 77.962908 47.150896 12.848973 - C6 78.120186 48.419741 12.278722 - H11 77.570527 50.499155 12.384499 - H21 76.103088 50.201824 14.361418 - H31 75.824860 47.954416 15.371667 - H41 77.013144 46.004279 14.404624 - H51 78.480583 46.301610 12.427705 - H61 78.759737 48.549078 11.417830 - C1 76.747845 17.936309 26.153014 - C2 76.752363 19.248495 26.640865 - C3 77.920834 20.016546 26.572574 - C4 79.084788 19.472411 26.016433 - C5 79.080396 18.160131 25.529570 - C6 77.911924 17.392080 25.597861 - H11 75.846729 17.343867 26.206070 - H21 75.854269 19.668646 27.069399 - H31 77.923856 21.029139 26.948052 - H41 79.986030 20.064759 25.964365 - H51 79.978490 17.739980 25.101036 - H61 77.908776 16.379581 25.221395 - C1 3.150594 31.751641 33.227358 - C2 3.784987 32.363845 34.314833 - C3 3.227024 33.508204 34.897077 - C4 2.034666 34.040359 34.391847 - C5 1.400991 33.428719 33.303965 - C6 1.958955 32.284360 32.721721 - H11 3.581187 30.869276 32.778096 - H21 4.704581 31.953039 34.705123 - H31 3.716024 33.979763 35.736629 - H41 1.604791 34.923288 34.840702 - H51 0.481397 33.839525 32.913675 - H61 1.469235 31.812237 31.882575 - C1 3.163665 42.068864 55.755063 - C2 2.207996 41.079443 55.495076 - C3 2.450546 39.754573 55.876890 - C4 3.648765 39.419125 56.518692 - C5 4.604582 40.408292 56.777723 - C6 4.362032 41.733161 56.395908 - H11 2.976702 43.090588 55.460209 - H21 1.283247 41.338203 55.000481 - H31 1.712760 38.991610 55.677149 - H41 3.835875 38.397147 56.812590 - H51 5.529330 40.149532 57.272318 - H61 5.099670 42.496379 56.596606 - C1 34.329528 9.326990 32.971694 - C2 35.484650 8.549003 33.114107 - C3 35.377688 7.185536 33.413118 - C4 34.115605 6.600056 33.569716 - C5 32.960797 7.378218 33.428237 - C6 33.067759 8.741685 33.129225 - H11 34.412103 10.378651 32.741465 - H21 36.458413 9.000434 32.992710 - H31 36.268877 6.585306 33.521950 - H41 34.033344 5.548570 33.800878 - H51 31.987034 6.926787 33.549633 - H61 32.176257 9.341740 33.019460 - C1 16.502739 30.048185 77.314199 - C2 16.994645 28.772120 77.014970 - C3 18.367007 28.511555 77.107816 - C4 19.247462 29.527055 77.499890 - C5 18.755625 30.803099 77.798121 - C6 17.383263 31.063664 77.705275 - H11 15.444331 30.249187 77.242192 - H21 16.315416 27.988385 76.713063 - H31 18.746186 27.526819 76.877915 - H41 20.305939 29.326032 77.570899 - H51 19.434854 31.586834 78.100028 - H61 17.004016 32.048421 77.936174 - C1 58.994659 6.262862 44.948250 - C2 58.523948 6.208138 46.265553 - C3 59.424997 6.282691 47.334405 - C4 60.796756 6.411968 47.085953 - C5 61.267335 6.465718 45.768835 - C6 60.366286 6.391165 44.699983 - H11 58.299702 6.204964 44.123934 - H21 57.465595 6.109021 46.457397 - H31 59.061601 6.241472 48.350565 - H41 61.491582 6.468893 47.910454 - H51 62.325689 6.564836 45.576991 - H61 60.729814 6.433358 43.683638 - C1 53.965977 10.500823 22.115948 - C2 54.930863 11.069348 21.275933 - C3 56.290515 10.938380 21.582666 - C4 56.685281 10.238887 22.729415 - C5 55.720433 9.671325 23.569698 - C6 54.360781 9.802293 23.262965 - H11 52.917339 10.602205 21.879529 - H21 54.626473 11.608514 20.390841 - H31 57.034763 11.376164 20.933993 - H41 57.733956 10.138468 22.966102 - H51 56.024822 9.132159 24.454790 - H61 53.616495 9.363546 23.911370 - C1 76.965818 22.956785 30.477071 - C2 76.317047 22.502515 29.322694 - C3 76.452331 23.207186 28.120601 - C4 77.236386 24.366128 28.072884 - C5 77.884218 24.820732 29.227346 - C6 77.748935 24.116061 30.429439 - H11 76.861121 22.413474 31.404252 - H21 75.712607 21.608055 29.359208 - H31 75.952588 22.856037 27.229934 - H41 77.340145 24.909774 27.145788 - H51 78.488659 25.715193 29.190832 - H61 78.249616 24.466876 31.320022 - C1 9.278192 51.867413 13.829974 - C2 9.408974 52.028500 12.445489 - C3 8.267840 52.082784 11.636319 - C4 6.995924 51.975980 12.211633 - C5 6.865338 51.813975 13.595770 - C6 8.006472 51.759692 14.404941 - H11 10.158353 51.825162 14.453950 - H21 10.390182 52.111533 12.001556 - H31 8.368887 52.208068 10.568409 - H41 6.115959 52.017314 11.587310 - H51 5.884130 51.730943 14.039704 - H61 7.905228 51.635325 15.473198 - C1 17.721618 51.852054 58.540564 - C2 17.895260 52.553587 59.739544 - C3 17.370422 52.041756 60.932215 - C4 16.671941 50.828393 60.925907 - C5 16.497586 50.127562 59.726920 - C6 17.022424 50.639392 58.534249 - H11 18.126091 52.247058 57.620680 - H21 18.434653 53.489412 59.744670 - H31 17.505342 52.582578 61.857226 - H41 16.266755 50.434091 61.845784 - H51 15.958193 49.191736 59.721794 - H61 16.888217 50.097869 57.609245 - C1 0.183548 39.669458 40.235636 - C2 0.217755 38.427025 39.591399 - C3 0.337700 38.364239 38.198000 - C4 0.423438 39.543886 37.448837 - C5 0.388273 40.786043 38.092998 - C6 0.268328 40.848829 39.486398 - H11 0.090644 39.717818 41.310273 - H21 0.152237 37.516820 40.169306 - H31 0.365086 37.405674 37.701270 - H41 0.515384 39.495250 36.374125 - H51 0.453791 41.696247 37.515092 - H61 0.241900 41.807670 39.983203 - C1 36.958022 31.019926 56.022395 - C2 37.644564 30.961177 54.803765 - C3 37.185598 30.121816 53.781653 - C4 36.040090 29.341203 53.978170 - C5 35.354310 29.399325 55.196965 - C6 35.813276 30.238687 56.219078 - H11 37.312280 31.667016 56.810805 - H21 38.527995 31.563830 54.651782 - H31 37.714772 30.077379 52.841260 - H41 35.686595 28.693487 53.189926 - H51 34.470879 28.796672 55.348948 - H61 35.283340 30.283750 57.159305 - C1 42.051959 62.973300 38.414158 - C2 41.693980 62.466482 39.669084 - C3 41.443152 61.098102 39.825649 - C4 41.550304 60.236540 38.727289 - C5 41.907303 60.743542 37.472445 - C6 42.158131 62.111922 37.315879 - H11 42.245016 64.028742 38.293391 - H21 41.611872 63.130967 40.516703 - H31 41.167988 60.707144 40.794036 - H41 41.356267 59.181282 38.848138 - H51 41.989411 60.079057 36.624825 - H61 42.434275 62.502696 36.347411 - C1 78.496527 4.198959 59.708550 - C2 78.263656 4.165467 61.088587 - C3 77.103674 4.744472 61.616873 - C4 76.176564 5.356969 60.765124 - C5 76.409975 5.391218 59.385457 - C6 77.569957 4.812213 58.857170 - H11 79.391381 3.752723 59.301212 - H21 78.978539 3.692413 61.745780 - H31 76.923704 4.717654 62.681405 - H41 75.282250 5.803961 61.172832 - H51 75.695092 5.864271 58.728263 - H61 77.749388 4.838274 57.792269 - C1 73.377614 33.552116 9.816670 - C2 73.892846 34.717795 10.395962 - C3 75.223239 35.086094 10.162936 - C4 76.038400 34.288715 9.350617 - C5 75.523410 33.122773 8.772259 - C6 74.193017 32.754473 9.005285 - H11 72.351645 33.267912 9.996751 - H21 73.263885 35.333407 11.022197 - H31 75.620247 35.985910 10.609089 - H41 77.064611 34.572655 9.171470 - H51 76.152371 32.507160 8.146024 - H61 73.795767 31.854920 8.558197 - C1 3.373699 54.238281 13.902213 - C2 3.404318 54.331873 12.505734 - C3 2.209402 54.449002 11.785771 - C4 0.983867 54.472539 12.462286 - C5 0.953341 54.378003 13.858447 - C6 2.148257 54.260874 14.578411 - H11 4.295299 54.147552 14.457402 - H21 4.349789 54.314348 11.983701 - H31 2.233272 54.522205 10.708548 - H41 0.062360 54.562324 11.906779 - H51 0.007870 54.395528 14.380480 - H61 2.124293 54.188614 15.655951 - C1 29.981592 70.250084 35.299537 - C2 30.991594 69.371013 35.708171 - C3 30.712067 68.008253 35.865153 - C4 29.422539 67.524566 35.613501 - C5 28.412579 68.403739 35.205862 - C6 28.692105 69.766498 35.048880 - H11 30.197149 71.301173 35.178861 - H21 31.986677 69.743935 35.901764 - H31 31.491594 67.330088 36.179422 - H41 29.207024 66.473579 35.735171 - H51 27.417495 68.030816 35.012269 - H61 27.912537 70.444563 34.733617 - C1 50.200637 54.475558 41.235313 - C2 49.896533 55.166083 42.414528 - C3 50.184208 54.589359 43.657317 - C4 50.775988 53.322111 43.720891 - C5 51.079119 52.631417 42.541829 - C6 50.791443 53.208141 41.299040 - H11 49.978381 54.920251 40.276843 - H21 49.440532 56.144047 42.365630 - H31 49.950463 55.122631 44.566889 - H41 50.997270 52.877250 44.679513 - H51 51.535119 51.653453 42.590727 - H61 51.026162 52.675038 40.389315 - C1 56.478571 7.615103 2.222979 - C2 56.099177 8.411601 1.136010 - C3 55.958719 9.795112 1.297435 - C4 56.197655 10.382126 2.545829 - C5 56.576055 9.585538 3.632749 - C6 56.716513 8.202027 3.471324 - H11 56.586502 6.548017 2.098507 - H21 55.915400 7.958935 0.172650 - H31 55.667011 10.409533 0.458548 - H41 56.088730 11.449122 2.670252 - H51 56.759832 10.038204 4.596108 - H61 57.009216 7.587697 4.310260 - C1 56.209725 8.807083 77.212447 - C2 55.098566 9.464995 76.671773 - C3 53.882205 8.785932 76.533091 - C4 53.777004 7.448959 76.935084 - C5 54.888295 6.791003 77.474768 - C6 56.104656 7.470065 77.613450 - H11 57.147928 9.330755 77.319016 - H21 55.179409 10.496665 76.362157 - H31 53.024846 9.293931 76.116906 - H41 52.838933 6.925242 76.827525 - H51 54.807452 5.759332 77.784384 - H61 56.961883 6.962111 78.030625 - C1 67.403457 15.356949 31.710777 - C2 67.672414 14.482328 30.651271 - C3 68.762792 14.720997 29.806284 - C4 69.584214 15.834286 30.020803 - C5 69.314636 16.709189 31.079578 - C6 68.224257 16.470521 31.924565 - H11 66.562249 15.173032 32.362204 - H21 67.039132 13.623034 30.486016 - H31 68.970719 14.045619 28.989602 - H41 70.424801 16.018486 29.368645 - H51 69.947917 17.568483 31.244833 - H61 68.016952 17.145615 32.741977 - C1 13.507865 78.575849 17.709509 - C2 14.261208 78.761746 18.874742 - C3 15.659631 78.771733 18.809898 - C4 16.304711 78.595823 17.579820 - C5 15.551400 78.409025 16.415018 - C6 14.152977 78.399038 16.479863 - H11 12.429332 78.567767 17.759649 - H21 13.763654 78.898090 19.823737 - H31 16.240611 78.916159 19.708753 - H41 17.383276 78.603004 17.530111 - H51 16.048954 78.272681 15.466023 - H61 13.571966 78.255513 15.580576 - C1 42.755665 53.202628 72.377177 - C2 43.668017 54.245910 72.179625 - C3 44.296637 54.400267 70.938294 - C4 44.012905 53.511342 69.894516 - C5 43.101412 52.467726 70.092457 - C6 42.472792 52.313369 71.333787 - H11 42.271167 53.083401 73.334706 - H21 43.886556 54.932172 72.984625 - H31 44.999674 55.205755 70.785766 - H41 44.498262 53.630235 68.937375 - H51 42.882873 51.781464 69.287456 - H61 41.768896 51.508215 71.485927 - C1 2.490606 1.657863 15.811401 - C2 2.055402 2.949156 15.490447 - C3 1.205970 3.638727 16.363858 - C4 0.791741 3.037005 17.558224 - C5 1.226179 1.745576 17.878549 - C6 2.075611 1.056005 17.005138 - H11 3.145421 1.125931 15.137547 - H21 2.375395 3.413759 14.569312 - H31 0.871147 4.635262 16.116577 - H41 0.136160 3.568801 18.231449 - H51 0.906187 1.280973 18.799684 - H61 2.411200 0.059606 17.253048 - C1 55.094197 23.613600 21.969764 - C2 55.898028 24.100361 20.932088 - C3 57.275466 23.850314 20.937606 - C4 57.849075 23.113507 21.980799 - C5 57.045422 22.627700 23.018714 - C6 55.667983 22.877747 23.013197 - H11 54.031906 23.806820 21.965651 - H21 55.455533 24.668304 20.126868 - H31 57.895263 24.225038 20.136499 - H41 58.911544 22.921242 21.985152 - H51 57.487917 22.059757 23.823934 - H61 55.048009 22.502069 23.814064 - C1 66.676458 35.096853 52.764137 - C2 67.491764 35.569714 51.728989 - C3 67.472794 34.938878 50.479358 - C4 66.638519 33.835182 50.264874 - C5 65.824112 33.361925 51.300202 - C6 65.843082 33.992761 52.549833 - H11 66.691426 35.583193 53.728016 - H21 68.135011 36.421595 51.894131 - H31 68.101073 35.304420 49.680620 - H41 66.624450 33.348446 49.301176 - H51 65.180865 32.510044 51.135061 - H61 65.213903 33.627616 53.348390 - C1 28.647745 15.524374 59.009318 - C2 29.952631 15.870751 58.638985 - C3 30.213327 17.132978 58.092440 - C4 29.169137 18.048828 57.916227 - C5 27.864379 17.702039 58.285657 - C6 27.603683 16.439812 58.832203 - H11 28.446685 14.550714 59.430476 - H21 30.758437 15.164497 58.775446 - H31 31.220193 17.400384 57.807742 - H41 29.370325 19.022077 57.494166 - H51 27.058573 18.408294 58.149196 - H61 26.596689 16.172818 59.117802 - C1 20.298295 52.504730 8.362804 - C2 20.317495 51.166069 8.772034 - C3 19.169180 50.376623 8.637724 - C4 18.001666 50.925837 8.094183 - C5 17.982322 52.264530 7.685941 - C6 19.130637 53.053976 7.820252 - H11 21.183858 53.113648 8.466781 - H21 21.218353 50.742034 9.190830 - H31 19.184476 49.343669 8.952542 - H41 17.115960 50.316951 7.991194 - H51 17.081464 52.688565 7.267146 - H61 19.115485 54.086898 7.504445 - C1 28.209917 54.723345 6.517911 - C2 26.922038 54.249376 6.794625 - C3 25.811352 54.843401 6.183558 - C4 25.988546 55.911394 5.295776 - C5 27.276174 56.385795 5.019928 - C6 28.386860 55.791770 5.630995 - H11 29.066468 54.265409 6.989536 - H21 26.785220 53.425016 7.479062 - H31 24.817983 54.476976 6.396369 - H41 25.131744 56.369762 4.825017 - H51 27.412992 57.210155 4.335492 - H61 29.380480 56.157762 5.417318 - C1 48.725519 57.400910 71.951784 - C2 50.033116 57.077196 72.332900 - C3 50.464736 55.746054 72.292217 - C4 49.588759 54.738625 71.870418 - C5 48.281134 55.062293 71.490301 - C6 47.849514 56.393436 71.530984 - H11 48.392572 58.427531 71.983557 - H21 50.709245 57.854408 72.657757 - H31 51.473812 55.496645 72.585300 - H41 49.921678 53.711959 71.839643 - H51 47.605005 54.285081 71.165444 - H61 46.840465 56.642890 71.236902 - C1 73.615895 43.458700 43.476979 - C2 73.559052 42.673217 44.634405 - C3 72.743921 41.535558 44.668829 - C4 71.985634 41.183382 43.545825 - C5 72.041833 41.969339 42.388999 - C6 72.856964 43.106998 42.354576 - H11 74.244290 44.336333 43.450631 - H21 74.144493 42.944452 45.500679 - H31 72.700967 40.929160 45.561451 - H41 71.356594 40.306223 43.572773 - H51 71.456391 41.698103 41.522725 - H61 72.900562 43.712921 41.461353 - C1 11.957475 53.953938 13.483098 - C2 12.749102 52.799464 13.502223 - C3 14.141602 52.903968 13.402656 - C4 14.742475 54.162947 13.283965 - C5 13.950812 55.317071 13.263904 - C6 12.558312 55.212567 13.363470 - H11 10.883480 53.873244 13.559500 - H21 12.285707 51.828120 13.594409 - H31 14.752202 52.013319 13.418441 - H41 15.816434 54.243291 13.206627 - H51 14.414207 56.288414 13.171717 - H61 11.947747 56.103566 13.348621 - C1 47.656168 61.831850 33.043157 - C2 47.091475 61.698549 34.317207 - C3 46.190040 60.659660 34.578004 - C4 45.853298 59.754072 33.564752 - C5 46.417235 59.888027 32.290717 - C6 47.318670 60.926916 32.029919 - H11 48.351099 62.633356 32.841974 - H21 47.351651 62.396774 35.099211 - H31 45.755285 60.556379 35.561192 - H41 45.157611 58.953220 33.765950 - H51 46.157059 59.189802 31.508713 - H61 47.754181 61.029543 31.046717 - C1 31.213970 18.588010 12.142762 - C2 32.018866 17.445638 12.059208 - C3 33.369682 17.513288 12.420609 - C4 33.915602 18.723309 12.865563 - C5 33.110971 19.865624 12.948154 - C6 31.760155 19.797974 12.586754 - H11 30.172247 18.535859 11.863642 - H21 31.597675 16.511878 11.716526 - H31 33.990214 16.631678 12.357046 - H41 34.957590 18.775403 13.143721 - H51 33.532162 20.799384 13.290836 - H61 31.139357 20.679641 12.651278 - C1 48.410572 32.090168 63.800955 - C2 47.556669 32.186369 62.695765 - C3 47.146790 31.027893 62.025076 - C4 47.590814 29.773216 62.459577 - C5 48.445316 29.677241 63.564000 - C6 48.855195 30.835717 64.234689 - H11 48.726969 32.983717 64.317944 - H21 47.213525 33.154250 62.360804 - H31 46.487249 31.102225 61.173127 - H41 47.275017 28.879893 61.941821 - H51 48.788461 28.709360 63.898960 - H61 49.514137 30.761158 65.087406 - C1 57.577782 8.032593 27.130294 - C2 58.675325 7.576452 26.390574 - C3 59.382220 8.462251 25.568655 - C4 58.991571 9.804190 25.486455 - C5 57.893630 10.259903 26.225363 - C6 57.186735 9.374104 27.047282 - H11 57.032388 7.349274 27.763884 - H21 58.977210 6.541301 26.454365 - H31 60.229498 8.110418 24.998856 - H41 59.536567 10.487081 24.852053 - H51 57.591745 11.295053 26.161572 - H61 56.339855 9.726364 27.617893 - C1 73.853763 33.975716 25.008289 - C2 75.061633 34.386127 24.431691 - C3 75.215474 35.707350 23.995122 - C4 74.161445 36.618163 24.135151 - C5 72.953522 36.207450 24.710798 - C6 72.799680 34.886226 25.147367 - H11 73.735043 32.956598 25.344618 - H21 75.875128 33.683701 24.324154 - H31 76.147689 36.024043 23.551256 - H41 74.280111 37.636979 23.797871 - H51 72.140026 36.909876 24.818335 - H61 71.867519 34.569836 25.592185 - C1 21.492454 7.717084 65.910157 - C2 22.070858 6.878625 66.870515 - C3 23.058172 7.375360 67.729792 - C4 23.467080 8.710553 67.628713 - C5 22.889374 9.548496 66.667859 - C6 21.902061 9.051762 65.808581 - H11 20.731266 7.333805 65.247205 - H21 21.755045 5.848655 66.949026 - H31 23.503546 6.728668 68.471256 - H41 24.228966 9.093316 68.291168 - H51 23.205187 10.578467 66.589347 - H61 21.455988 9.698969 65.067614 - C1 11.092265 66.809133 71.511128 - C2 10.200039 67.886968 71.465816 - C3 10.366676 68.970545 72.336440 - C4 11.425540 68.976285 73.252376 - C5 12.316975 67.898149 73.298221 - C6 12.150337 66.814573 72.427597 - H11 10.963458 65.973270 70.839893 - H21 9.383431 67.882963 70.758797 - H31 9.678875 69.802402 72.300655 - H41 11.553556 69.811848 73.924143 - H51 13.133583 67.902155 74.005240 - H61 12.838930 65.983016 72.462848 - C1 51.310233 62.257698 12.156564 - C2 52.682191 62.195101 12.427976 - C3 53.495027 61.299731 11.722639 - C4 52.935906 60.466958 10.745891 - C5 51.564023 60.528976 10.475291 - C6 50.751186 61.424346 11.180628 - H11 50.683317 62.948004 12.700871 - H21 53.113806 62.837966 13.181085 - H31 54.553558 61.252291 11.931442 - H41 53.562897 59.776074 10.202396 - H51 51.132408 59.886111 9.722181 - H61 49.692581 61.472366 10.971013 - C1 35.596489 26.684390 77.491307 - C2 36.225063 27.610503 76.650438 - C3 36.078456 28.982559 76.886784 - C4 35.303274 29.428503 77.963999 - C5 34.674096 28.502467 78.804074 - C6 34.820703 27.130411 78.567728 - H11 35.709283 25.626204 77.308735 - H21 36.823658 27.266595 75.819684 - H31 36.564257 29.696838 76.238602 - H41 35.189876 30.486766 78.145777 - H51 34.075501 28.846375 79.634829 - H61 34.335506 26.416055 79.216704 - C1 77.382228 27.773106 51.205029 - C2 78.145157 26.615733 51.400676 - C3 79.083175 26.562953 52.438572 - C4 79.258264 27.667546 53.280820 - C5 78.496080 28.824988 53.084510 - C6 77.558062 28.877768 52.046614 - H11 76.659070 27.813888 50.404283 - H21 78.009749 25.763228 50.751338 - H31 79.670925 25.669665 52.589979 - H41 79.982167 27.626833 54.080903 - H51 78.631488 29.677493 53.733848 - H61 76.969567 29.770987 51.895870 - C1 48.283853 21.883190 73.274306 - C2 47.109849 22.558060 72.919178 - C3 45.886196 21.877968 72.913013 - C4 45.836547 20.523005 73.261976 - C5 47.010549 19.848137 73.616104 - C6 48.234202 20.528229 73.622270 - H11 49.227628 22.407675 73.278662 - H21 47.147907 23.603582 72.650522 - H31 44.980480 22.399004 72.640001 - H41 44.892771 19.998522 73.256620 - H51 46.972491 18.802615 73.884761 - H61 49.139920 20.007191 73.896282 - C1 8.162701 33.290998 17.857823 - C2 8.078225 32.015973 18.429686 - C3 8.361648 30.882705 17.658150 - C4 8.729547 31.024463 16.314751 - C5 8.813050 32.299258 15.742860 - C6 8.529627 33.432525 16.514396 - H11 7.943716 34.164973 18.452825 - H21 7.794999 31.906484 19.466284 - H31 8.297407 29.899241 18.099747 - H41 8.947559 30.150258 15.719721 - H51 9.096276 32.408747 14.706262 - H61 8.594841 34.416219 16.072828 - C1 18.103123 74.692029 55.441913 - C2 17.657595 74.399997 54.147281 - C3 18.125235 73.257363 53.487286 - C4 19.038404 72.406762 54.121924 - C5 19.484494 72.699365 55.415957 - C6 19.016854 73.841998 56.075952 - H11 17.742713 75.573518 55.950731 - H21 16.952607 75.055819 53.657761 - H31 17.780658 73.031697 52.488949 - H41 19.399377 71.525844 53.612507 - H51 20.189483 72.043542 55.905477 - H61 19.360870 74.067094 57.074888 - C1 20.503610 11.064309 24.549826 - C2 19.686706 9.928388 24.502889 - C3 18.294673 10.064439 24.563081 - C4 17.719542 11.336411 24.670209 - C5 18.536447 12.471977 24.718081 - C6 19.928480 12.335926 24.657890 - H11 21.577232 10.959282 24.503793 - H21 20.130257 8.947027 24.419619 - H31 17.664601 9.188106 24.525844 - H41 16.645921 11.441084 24.717178 - H51 18.092896 13.453338 24.801351 - H61 20.558551 13.212615 24.694192 - C1 27.543165 21.398238 52.520320 - C2 26.824660 22.583883 52.325779 - C3 26.002102 22.727410 51.202084 - C4 25.898050 21.685292 50.272930 - C5 26.617213 20.500282 50.467065 - C6 27.439771 20.356754 51.590759 - H11 28.177854 21.287758 53.386795 - H21 26.904358 23.387736 53.042863 - H31 25.447112 23.641744 51.052693 - H41 25.264019 21.796407 49.406049 - H51 26.537515 19.696429 49.749981 - H61 27.994103 19.441787 51.740557 - C1 16.629410 75.104030 24.629045 - C2 17.959590 75.513273 24.477416 - C3 18.856367 74.722687 23.748954 - C4 18.422963 73.522858 23.172122 - C5 17.093235 73.113337 23.324600 - C6 16.196458 73.903923 24.053061 - H11 15.937914 75.713628 25.191219 - H21 18.293957 76.439233 24.921869 - H31 19.882229 75.039049 23.631234 - H41 19.114910 72.912983 22.610797 - H51 16.758867 72.187378 22.880147 - H61 15.170144 73.587839 24.169934 - C1 22.438861 78.612509 21.439918 - C2 23.312921 77.519048 21.454440 - C3 22.803439 76.216577 21.516786 - C4 21.419896 76.007567 21.564609 - C5 20.546134 77.100951 21.551038 - C6 21.055616 78.403423 21.488693 - H11 22.831880 79.617037 21.392228 - H21 24.380343 77.680122 21.416928 - H31 23.477842 75.373123 21.526964 - H41 21.027176 75.002962 21.613251 - H51 19.478712 76.939878 21.588551 - H61 20.380915 79.246953 21.477564 - C1 43.159456 5.863302 61.446379 - C2 41.813219 6.236138 61.354237 - C3 41.471703 7.526875 60.933220 - C4 42.476424 8.444777 60.604347 - C5 43.822396 8.072181 60.697424 - C6 44.163913 6.781443 61.118440 - H11 43.422792 4.867921 61.771473 - H21 41.037944 5.527882 61.607341 - H31 40.433091 7.814000 60.861232 - H41 42.212823 9.440397 60.280188 - H51 44.597672 8.780437 60.444319 - H61 45.202789 6.494079 61.189494 - C1 53.533160 4.557902 37.703240 - C2 54.718776 4.704336 36.973362 - C3 54.858678 4.073200 35.731594 - C4 53.812963 3.295630 35.219706 - C5 52.627979 3.148534 35.949986 - C6 52.488078 3.779670 37.191754 - H11 53.425475 5.044377 38.661133 - H21 55.525405 5.304709 37.367877 - H31 55.772992 4.187097 35.168217 - H41 53.921280 2.808492 34.262215 - H51 51.821350 2.548161 35.555471 - H61 51.573131 3.666435 37.754729 - C1 64.549941 71.051462 3.372399 - C2 65.102840 71.942027 2.444473 - C3 65.860233 71.455059 1.372508 - C4 66.064726 70.077526 1.228468 - C5 65.512664 69.187294 2.156827 - C6 64.755271 69.674263 3.228792 - H11 63.966135 71.427131 4.199355 - H21 64.944642 73.004793 2.555124 - H31 66.285840 72.142156 0.656202 - H41 66.649369 69.702191 0.401945 - H51 65.670862 68.124529 2.046176 - H61 64.328826 68.986832 3.944665 - C1 61.461412 26.303792 47.878340 - C2 60.982638 25.174118 47.204201 - C3 60.195648 25.325349 46.056305 - C4 59.887431 26.606255 45.582547 - C5 60.365393 27.735649 46.257199 - C6 61.152384 27.584418 47.405095 - H11 62.068052 26.187087 48.763880 - H21 61.220860 24.185816 47.569238 - H31 59.827230 24.453752 45.535801 - H41 59.279980 26.722679 44.697520 - H51 60.127171 28.723950 45.892162 - H61 61.521613 28.456295 47.925086 - C1 29.518714 33.310423 29.565156 - C2 29.440557 32.065584 28.929454 - C3 30.572972 31.245927 28.854021 - C4 31.783544 31.671110 29.414289 - C5 31.861789 32.916154 30.049015 - C6 30.729374 33.735810 30.124449 - H11 28.645393 33.942709 29.622956 - H21 28.506503 31.737150 28.497696 - H31 30.512238 30.285208 28.364462 - H41 32.656953 31.039028 29.355513 - H51 32.795843 33.244587 30.480773 - H61 30.790019 34.696326 30.614982 - C1 67.286549 45.867330 70.822879 - C2 66.283968 46.658736 70.249852 - C3 65.817267 46.372593 68.961363 - C4 66.353146 45.295044 68.245901 - C5 67.356206 44.504440 68.818571 - C6 67.822908 44.790584 70.107060 - H11 67.646726 46.088313 71.816485 - H21 65.870002 47.489732 70.801956 - H31 65.043124 46.982606 68.519861 - H41 65.993449 45.074863 67.251938 - H51 67.770172 43.673444 68.266467 - H61 68.596571 44.179769 70.548919 - C1 23.124387 56.815299 41.573481 - C2 23.810824 57.882608 40.982291 - C3 25.210166 57.915063 41.008360 - C4 25.923071 56.880209 41.625618 - C5 25.236609 55.813630 42.217490 - C6 23.837267 55.781175 42.191422 - H11 22.045124 56.790527 41.553683 - H21 23.260966 58.680770 40.505495 - H31 25.739571 58.737997 40.551361 - H41 27.002309 56.905711 41.646099 - H51 25.786467 55.015468 42.694287 - H61 23.307887 54.957511 42.647738 - C1 72.924372 41.150195 15.263180 - C2 72.191006 42.282065 15.638542 - C3 72.747178 43.557964 15.488061 - C4 74.036716 43.701994 14.962217 - C5 74.770205 42.570192 14.587845 - C6 74.214033 41.294293 14.738326 - H11 72.495512 40.166156 15.379631 - H21 71.195866 42.171139 16.043676 - H31 72.180898 44.431077 15.776744 - H41 74.465699 44.686101 14.846756 - H51 75.765345 42.681119 14.182711 - H61 74.780190 40.421112 14.448653 - C1 41.920383 73.609361 16.397827 - C2 40.662113 74.131504 16.720275 - C3 39.792596 73.404902 17.542395 - C4 40.181349 72.156157 18.042066 - C5 41.439044 71.633801 17.718829 - C6 42.308561 72.360403 16.896710 - H11 42.590801 74.169634 15.763439 - H21 40.362290 75.095185 16.335351 - H31 38.822355 73.808310 17.791859 - H41 39.510356 71.595671 18.675666 - H51 41.738867 70.670121 18.103753 - H61 43.279377 71.957208 16.648034 - C1 33.392839 24.609942 71.160918 - C2 32.849981 23.671319 70.275399 - C3 33.592201 23.242376 69.168598 - C4 34.877278 23.752057 68.947315 - C5 35.419546 24.691212 69.832226 - C6 34.677326 25.120154 70.939027 - H11 32.820190 24.941017 72.014309 - H21 31.858787 23.277545 70.446332 - H31 33.173655 22.517527 68.486139 - H41 35.449337 23.421514 68.093316 - H51 36.410740 25.084986 69.661294 - H61 35.096461 25.844472 71.622094 - C1 39.673762 10.740774 57.745950 - C2 40.333924 11.962996 57.919761 - C3 39.812615 13.128016 57.344559 - C4 38.631145 13.070813 56.595546 - C5 37.971714 11.848587 56.421053 - C6 38.493023 10.683567 56.996255 - H11 40.076090 9.842215 58.189278 - H21 41.245116 12.007391 58.498121 - H31 40.321480 14.070969 57.479591 - H41 38.229548 13.969368 56.151536 - H51 37.060523 11.804192 55.842694 - H61 37.983428 9.740618 56.861906 - C1 25.625217 50.380970 42.419476 - C2 26.448216 49.320379 42.816553 - C3 26.017702 47.999072 42.647153 - C4 24.764189 47.738356 42.080676 - C5 23.941043 48.798863 41.684584 - C6 24.371557 50.120170 41.853984 - H11 25.957151 51.400020 42.550515 - H21 27.415597 49.521356 43.253044 - H31 26.653149 47.180999 42.952605 - H41 24.432109 46.719222 41.950623 - H51 22.973663 48.597886 41.248094 - H61 23.736257 50.938327 41.547547 - C1 19.473331 37.744027 24.312297 - C2 19.024258 36.545220 24.878907 - C3 17.994216 35.823288 24.264320 - C4 17.413247 36.300163 23.083121 - C5 17.861686 37.499249 22.517233 - C6 18.891728 38.221181 23.131821 - H11 20.267494 38.300972 24.786565 - H21 19.472805 36.176866 25.789875 - H31 17.648599 34.897989 24.701019 - H41 16.618450 35.743496 22.609575 - H51 17.413140 37.867603 21.606265 - H61 19.237978 39.146201 22.694399 - C1 57.828157 63.729494 14.029911 - C2 56.946759 62.744689 14.491591 - C3 55.581026 63.028172 14.611176 - C4 55.096690 64.296460 14.269081 - C5 55.978175 65.281289 13.808396 - C6 57.343908 64.997806 13.688811 - H11 58.881534 63.510912 13.938075 - H21 57.320191 61.765955 14.754974 - H31 54.901081 62.268020 14.966395 - H41 54.043401 64.515066 14.361913 - H51 55.604744 66.260023 13.545013 - H61 58.023767 65.757933 13.332597 - C1 54.541745 47.045496 79.662012 - C2 53.708048 45.926700 79.776448 - C3 52.323032 46.094842 79.891990 - C4 51.771713 47.381780 79.893095 - C5 52.605455 48.500321 79.779624 - C6 53.990471 48.332179 79.664083 - H11 55.609973 46.915759 79.573298 - H21 54.133196 44.933730 79.774991 - H31 51.679951 45.231610 79.979247 - H41 50.703529 47.511262 79.982775 - H51 52.180307 49.493291 79.781082 - H61 54.633507 49.195666 79.575860 - C1 8.134336 55.974229 10.992234 - C2 7.550592 55.332851 12.091202 - C3 7.354708 56.033214 13.287451 - C4 7.742568 57.374953 13.384733 - C5 8.327059 58.015821 12.286192 - C6 8.522943 57.315459 11.089943 - H11 8.285743 55.433899 10.069773 - H21 7.250741 54.297868 12.016102 - H31 6.903450 55.538560 14.134813 - H41 7.591909 57.914774 14.307621 - H51 8.626911 59.050804 12.361292 - H61 8.973454 57.810622 10.242155 - C1 45.194771 25.252295 77.371635 - C2 45.820445 24.004882 77.260539 - C3 45.167345 22.949536 76.612776 - C4 43.888571 23.141604 76.076109 - C5 43.262736 24.388571 76.188085 - C6 43.915836 25.443916 76.835848 - H11 45.698373 26.066084 77.871582 - H21 46.807281 23.856724 77.673992 - H31 45.650579 21.987590 76.526282 - H41 43.384807 22.327368 75.577042 - H51 42.275899 24.536728 75.774632 - H61 43.432762 26.406309 76.921462 - C1 35.238876 58.277199 17.814216 - C2 35.400508 59.147732 18.898604 - C3 34.331313 59.947454 19.319505 - C4 33.100487 59.876644 18.656017 - C5 32.939302 59.006919 17.571245 - C6 34.008496 58.207197 17.150344 - H11 36.063657 57.660721 17.489398 - H21 36.349858 59.202022 19.410978 - H31 34.455883 60.618222 20.156697 - H41 32.276153 60.493930 18.980451 - H51 31.989951 58.952629 17.058870 - H61 33.883480 57.535621 16.313536 - C1 43.086755 79.047610 74.222329 - C2 42.084520 78.072873 74.149772 - C3 42.331018 76.863407 73.489225 - C4 43.579750 76.628679 72.901234 - C5 44.581401 77.603704 72.973033 - C6 44.334903 78.813170 73.633580 - H11 42.896446 79.980554 74.731457 - H21 41.121266 78.253576 74.603897 - H31 41.558072 76.111166 73.434222 - H41 43.769474 75.696023 72.391348 - H51 45.544655 77.423001 72.518908 - H61 45.108433 79.565122 73.689342 - C1 18.118996 68.829559 30.667644 - C2 18.265525 67.790722 31.594575 - C3 19.443005 67.033808 31.617169 - C4 20.473957 67.315729 30.712834 - C5 20.326944 68.353790 29.785499 - C6 19.149463 69.110705 29.762904 - H11 17.210673 69.413042 30.650013 - H21 17.470471 67.573499 32.292748 - H31 19.556275 66.233101 32.332974 - H41 21.381796 66.731471 30.730061 - H51 21.121997 68.571014 29.087326 - H61 19.036678 69.912186 29.047504 - C1 57.976991 59.115864 26.251704 - C2 58.502488 59.960335 27.236880 - C3 59.609310 59.552314 27.990774 - C4 60.190634 58.299823 27.759492 - C5 59.664549 57.455213 26.775113 - C6 58.557727 57.863233 26.021219 - H11 57.123104 59.430452 25.670562 - H21 58.054479 60.926926 27.415009 - H31 60.015188 60.204318 28.750045 - H41 61.043933 57.985096 28.341431 - H51 60.112558 56.488621 26.596984 - H61 58.152438 57.211369 25.261151 - C1 45.169907 44.200419 57.209261 - C2 44.811740 42.916290 56.781968 - C3 45.791522 41.925874 56.644143 - C4 47.129470 42.219588 56.933612 - C5 47.487573 43.503786 57.359910 - C6 46.507792 44.494202 57.497735 - H11 44.414252 44.964346 57.315163 - H21 43.779452 42.689367 56.559194 - H31 45.514889 40.935024 56.315467 - H41 47.885062 41.455730 56.826714 - H51 48.519861 43.730709 57.582683 - H61 46.784488 45.484983 57.827406 - C1 26.166410 55.965961 33.777711 - C2 26.302497 56.827457 32.682651 - C3 26.668939 58.163447 32.884493 - C4 26.899293 58.637943 34.181395 - C5 26.762273 57.776740 35.276242 - C6 26.395832 56.440749 35.074400 - H11 25.883405 54.935681 33.622000 - H21 26.125410 56.461366 31.681972 - H31 26.774857 58.827637 32.039525 - H41 27.181365 59.668516 34.336893 - H51 26.939360 58.142831 36.276921 - H61 26.290846 55.776267 35.919581 - C1 55.616296 28.326116 11.519131 - C2 56.061880 28.036741 12.814341 - C3 55.139930 27.915129 13.860815 - C4 53.772395 28.082893 13.612080 - C5 53.327109 28.373147 12.317242 - C6 54.249060 28.494759 11.270768 - H11 56.327443 28.420283 10.712151 - H21 57.116861 27.906674 13.006278 - H31 55.483763 27.690895 14.859732 - H41 53.061546 27.989605 14.419432 - H51 52.272129 28.503214 12.125305 - H61 53.904928 28.718114 10.271480 - C1 2.881510 45.252494 57.989247 - C2 1.831376 46.152944 58.204329 - C3 1.913472 47.088894 59.242187 - C4 3.045701 47.124393 60.064964 - C5 4.095158 46.223427 59.850408 - C6 4.013062 45.287478 58.812549 - H11 2.817959 44.530405 57.189021 - H21 0.958057 46.126082 57.569244 - H31 1.103704 47.784121 59.407329 - H41 3.108576 47.845966 60.865716 - H51 4.968477 46.250289 60.485493 - H61 4.823507 44.592766 58.646882 - C1 35.418299 18.237704 7.652086 - C2 36.592245 17.475415 7.676932 - C3 37.740133 17.978209 8.300985 - C4 37.714075 19.243292 8.900192 - C5 36.540553 20.005735 8.874454 - C6 35.392665 19.502940 8.250401 - H11 34.533133 17.850025 7.170423 - H21 36.612322 16.499116 7.215218 - H31 38.645377 17.389589 8.320934 - H41 38.599666 19.631124 9.380963 - H51 36.520476 20.982033 9.336168 - H61 34.486998 20.091407 8.231344 - C1 71.465473 35.354920 44.926839 - C2 72.771636 34.954695 44.620883 - C3 73.802774 35.900846 44.582876 - C4 73.527749 37.247222 44.850824 - C5 72.221609 37.647389 45.155782 - C6 71.190471 36.701238 45.193790 - H11 70.670177 34.625206 44.955752 - H21 72.984085 33.915892 44.414741 - H31 74.810519 35.591757 44.347821 - H41 74.323068 37.976878 44.820914 - H51 72.009160 38.686192 45.361925 - H61 70.182703 37.010386 45.429843 - C1 53.780925 67.036331 35.759522 - C2 55.179663 67.048007 35.816499 - C3 55.905478 65.916213 35.426465 - C4 55.232556 64.772744 34.979455 - C5 53.834037 64.760874 34.923434 - C6 53.108221 65.892668 35.313468 - H11 53.221182 67.909131 36.060724 - H21 55.698990 67.930345 36.160766 - H31 56.984548 65.925751 35.469531 - H41 55.792518 63.899749 34.679209 - H51 53.314710 63.878536 34.579167 - H61 52.028932 65.883324 35.269446 - C1 51.517009 40.744155 13.821994 - C2 51.725955 39.744231 14.779252 - C3 50.690035 39.378717 15.647100 - C4 49.445168 40.013127 15.557689 - C5 49.236686 41.013513 14.601186 - C6 50.272606 41.379027 13.733339 - H11 52.316132 41.026285 13.152950 - H21 52.686137 39.254258 14.847945 - H31 50.851093 38.606614 16.384836 - H41 48.646509 39.731459 16.227488 - H51 48.276504 41.503486 14.532493 - H61 50.111084 42.150668 12.994846 - C1 40.958733 34.812440 57.382882 - C2 39.975947 35.809371 57.393490 - C3 40.215169 37.020988 58.052768 - C4 41.437177 37.235674 58.701437 - C5 42.419333 36.238476 58.691559 - C6 42.180111 35.026859 58.032282 - H11 40.774017 33.877844 56.874724 - H21 39.033346 35.644121 56.892556 - H31 39.457284 37.790335 58.059991 - H41 41.621264 38.170003 59.210325 - H51 43.361935 36.403725 59.192494 - H61 42.938626 34.257779 58.024328 - C1 10.339182 16.367123 26.016480 - C2 11.442499 15.566676 25.697373 - C3 11.487196 14.893194 24.470867 - C4 10.428577 15.020159 23.563469 - C5 9.325091 15.819737 23.883042 - C6 9.280394 16.493219 25.109548 - H11 10.304594 16.886211 26.962612 - H21 12.259589 15.469116 26.397077 - H31 12.338874 14.276546 24.224440 - H41 10.462995 14.500203 22.617803 - H51 8.508001 15.917297 23.183337 - H61 8.428886 17.110736 25.355510 - C1 6.626795 4.500477 18.398518 - C2 7.203743 5.259391 17.373319 - C3 7.132221 4.814342 16.047910 - C4 6.483751 3.610380 15.747701 - C5 5.907775 2.851230 16.772921 - C6 5.979297 3.296278 18.098329 - H11 6.682334 4.843586 19.420773 - H21 7.703540 6.188586 17.604705 - H31 7.576479 5.400429 15.257042 - H41 6.429185 3.267035 14.725467 - H51 5.407979 1.922034 16.541535 - H61 5.534067 2.710428 18.889177 - C1 1.571241 25.371628 35.268130 - C2 2.737145 26.038428 35.662968 - C3 3.988440 25.562076 35.254017 - C4 4.073831 24.418924 34.450229 - C5 2.908110 23.751794 34.056317 - C6 1.656815 24.228146 34.465268 - H11 0.606223 25.738844 35.583894 - H21 2.671392 26.920748 36.282587 - H31 4.887704 26.077180 35.557872 - H41 5.039032 24.051378 34.135391 - H51 2.973863 22.869474 33.436698 - H61 0.757368 23.713371 34.160487 - C1 54.780664 51.926807 53.255057 - C2 53.805104 50.945652 53.041821 - C3 53.005114 50.511317 54.105428 - C4 53.180685 51.058136 55.382271 - C5 54.156743 52.038423 55.595534 - C6 54.956733 52.472759 54.531927 - H11 55.397892 52.261464 52.434784 - H21 53.669117 50.524127 52.056648 - H31 52.251900 49.755134 53.940529 - H41 52.563955 50.722611 56.202571 - H51 54.292730 52.459948 56.580707 - H61 55.709450 53.229808 54.696799 - C1 37.895452 23.160450 37.916403 - C2 39.103349 23.749758 37.524544 - C3 40.226614 22.949726 37.283472 - C4 40.141982 21.560386 37.434259 - C5 38.934503 20.971399 37.826968 - C6 37.811238 21.771431 38.068040 - H11 37.029271 23.777572 38.102694 - H21 39.168628 24.821578 37.407572 - H31 41.158074 23.404424 36.980209 - H41 41.008580 20.943585 37.248818 - H51 38.869223 19.899579 37.943940 - H61 36.879360 21.316413 38.370452 - C1 57.132566 37.840406 74.581207 - C2 58.086804 38.665019 73.973510 - C3 57.817397 39.248336 72.729705 - C4 56.593752 39.007041 72.093596 - C5 55.640155 38.181798 72.700853 - C6 55.909562 37.598481 73.944659 - H11 57.340568 37.390236 75.540319 - H21 59.030656 38.851767 74.464438 - H31 58.553246 39.885255 72.261521 - H41 56.386390 39.456581 71.134045 - H51 54.696303 37.995049 72.209926 - H61 55.173072 36.962191 74.413283 - C1 20.234252 42.049114 47.812115 - C2 21.333568 41.293286 48.236473 - C3 21.614482 40.064053 47.628227 - C4 20.796081 39.590648 46.595623 - C5 19.696446 40.345993 46.172080 - C6 19.415531 41.575227 46.780326 - H11 20.017423 42.996977 48.281536 - H21 21.965421 41.658681 49.032707 - H31 22.463165 39.481586 47.955039 - H41 21.012590 38.642303 46.127017 - H51 19.064592 39.980598 45.375847 - H61 18.567168 42.158176 46.452699 - C1 42.996351 30.022517 65.508670 - C2 42.311445 28.802117 65.471546 - C3 42.991131 27.609465 65.746318 - C4 44.355724 27.637214 66.058215 - C5 45.040599 28.857367 66.094370 - C6 44.360913 30.050018 65.819598 - H11 42.472167 30.942282 65.296356 - H21 41.258509 28.780610 65.231534 - H31 42.462380 26.668194 65.718620 - H41 44.879877 26.717202 66.269560 - H51 46.093535 28.878873 66.334382 - H61 44.889695 30.991537 65.848265 - C1 77.587848 21.877382 68.893964 - C2 78.676493 22.181176 69.720046 - C3 78.498314 22.278251 71.105224 - C4 77.231491 22.071533 71.664321 - C5 76.142938 21.768734 70.838186 - C6 76.321116 21.671658 69.453007 - H11 77.725259 21.802912 67.825607 - H21 79.654043 22.340080 69.288901 - H31 79.338454 22.511625 71.742437 - H41 77.094172 22.146997 72.732625 - H51 75.165387 21.609829 71.269330 - H61 75.480885 21.437290 68.815848 - C1 20.549664 28.033434 43.912514 - C2 21.539780 28.989398 44.168744 - C3 22.852589 28.583042 44.435763 - C4 23.175282 27.220721 44.446550 - C5 22.185049 26.264996 44.191283 - C6 20.872240 26.671352 43.924265 - H11 19.537088 28.346890 43.706967 - H21 21.291102 30.040503 44.159848 - H31 23.616487 29.320690 44.632413 - H41 24.187741 26.907504 44.653060 - H51 22.433727 25.213891 44.200179 - H61 20.108459 25.933465 43.726651 - C1 49.994096 56.057151 13.332737 - C2 49.365404 56.721238 14.392731 - C3 48.815972 57.993470 14.194138 - C4 48.895232 58.601617 12.935552 - C5 49.524670 57.937940 11.876083 - C6 50.074102 56.665708 12.074675 - H11 50.418173 55.076100 13.486072 - H21 49.303635 56.251914 15.363638 - H31 48.330126 58.505198 15.011711 - H41 48.471902 59.583078 12.782742 - H51 49.586440 58.407264 10.905175 - H61 50.559203 56.153570 11.256578 - C1 54.650385 20.566400 37.777243 - C2 54.655128 19.734232 36.651487 - C3 53.558568 19.727921 35.781194 - C4 52.457267 20.553776 36.036658 - C5 52.452251 21.385045 37.162758 - C6 53.548810 21.391357 38.033050 - H11 55.495979 20.570930 38.448633 - H21 55.504983 19.097477 36.453929 - H31 53.562830 19.086634 34.912246 - H41 51.611399 20.548348 35.365611 - H51 51.602395 22.021801 37.360315 - H61 53.544822 22.033542 38.901654 - C1 79.906262 32.191730 74.243867 - C2 79.898860 31.412527 73.080837 - C3 79.899297 32.030250 71.824529 - C4 79.907135 33.427175 71.731251 - C5 79.913579 34.206123 72.894149 - C6 79.913142 33.588401 74.150457 - H11 79.905530 31.715246 75.212771 - H21 79.893435 30.334772 73.152642 - H31 79.894604 31.428979 70.927429 - H41 79.906910 33.903404 70.762214 - H51 79.919004 35.283878 72.822344 - H61 79.918793 34.189927 75.047688 - C1 60.122357 41.681859 50.981130 - C2 61.003454 42.119889 51.976946 - C3 62.385217 42.081137 51.755315 - C4 62.885883 41.604355 50.537868 - C5 62.004870 41.165550 49.542679 - C6 60.623107 41.204303 49.764310 - H11 59.056689 41.711408 51.152278 - H21 60.617313 42.488333 52.916033 - H31 63.064744 42.420032 52.523254 - H41 63.951635 41.574032 50.367346 - H51 62.391011 40.797107 48.603592 - H61 59.943496 40.866182 48.995744 - C1 29.472355 75.406739 69.300511 - C2 29.015180 74.095224 69.125095 - C3 27.790681 73.860143 68.488519 - C4 27.023356 74.936576 68.027359 - C5 27.480117 76.247844 68.203651 - C6 28.704617 76.482926 68.840228 - H11 30.416582 75.587994 69.791832 - H21 29.607359 73.264617 69.480281 - H31 27.438632 72.848280 68.352385 - H41 26.078715 74.755074 67.536915 - H51 26.887939 77.078451 67.848465 - H61 29.057079 77.495035 68.975486 - C1 47.452041 49.527847 26.886852 - C2 47.124116 50.887636 26.944212 - C3 48.118452 51.855746 26.759957 - C4 49.440713 51.464068 26.518342 - C5 49.768615 50.104496 26.461958 - C6 48.774279 49.136386 26.646213 - H11 46.685177 48.781238 27.029358 - H21 46.103912 51.189971 27.130000 - H31 47.865112 52.904690 26.803239 - H41 50.207554 52.210894 26.376813 - H51 50.788819 49.802161 26.276170 - H61 49.027642 48.087225 26.601955 - C1 56.823756 14.963628 26.252281 - C2 58.032970 14.397801 25.830981 - C3 59.231546 14.762459 26.455745 - C4 59.220909 15.692944 27.501808 - C5 58.011960 16.259301 27.922302 - C6 56.813384 15.894644 27.297538 - H11 55.899429 14.682634 25.770124 - H21 58.041260 13.679448 25.024358 - H31 60.164164 14.325101 26.131278 - H41 60.145501 15.974469 27.983160 - H51 58.003669 16.977654 28.728926 - H61 55.880501 16.331471 27.622811 - C1 69.885667 50.356980 8.091714 - C2 70.036774 51.672972 7.638745 - C3 69.491070 52.056491 6.407887 - C4 68.794259 51.124017 5.629998 - C5 68.644068 49.808053 6.082565 - C6 69.189772 49.424535 7.313423 - H11 70.306906 50.061154 9.040850 - H21 70.573814 52.392655 8.239067 - H31 69.606870 53.071999 6.059073 - H41 68.373935 51.419872 4.680460 - H51 68.107028 49.088371 5.482243 - H61 69.073056 48.408998 7.662639 - C1 33.051002 32.908351 6.315088 - C2 32.457033 31.727693 6.776714 - C3 33.257944 30.663271 7.207340 - C4 34.652824 30.779507 7.176338 - C5 35.246566 31.959651 6.713884 - C6 34.445655 33.024073 6.283259 - H11 32.433240 33.729109 5.982612 - H21 31.380877 31.638099 6.801269 - H31 32.799550 29.752919 7.564370 - H41 35.270358 29.958235 7.507986 - H51 36.322722 32.049245 6.689329 - H61 34.904277 33.934939 5.927056 - C1 35.791037 65.158216 15.749496 - C2 35.853228 64.607398 14.463968 - C3 36.759162 65.118142 13.526784 - C4 37.602906 66.179706 13.875128 - C5 37.539963 66.730955 15.160156 - C6 36.634029 66.220210 16.097340 - H11 35.092033 64.764512 16.472133 - H21 35.202765 63.787984 14.195267 - H31 36.807704 64.692433 12.535446 - H41 38.301158 66.573840 13.151991 - H51 38.190426 67.550369 15.428858 - H61 36.586239 66.645489 17.089179 - C1 26.942378 10.783186 72.709441 - C2 27.506670 11.990430 73.138379 - C3 28.092187 12.858505 72.209128 - C4 28.113411 12.519336 70.850939 - C5 27.550029 11.311845 70.422336 - C6 26.964512 10.443770 71.351587 - H11 26.491159 10.113543 73.426234 - H21 27.489823 12.252522 74.186122 - H31 28.526558 13.790240 72.540077 - H41 28.565540 13.188732 70.134480 - H51 27.566876 11.049753 69.374593 - H61 26.529231 9.512281 71.020302 - C1 57.913277 77.660462 56.724257 - C2 57.808717 76.743956 57.777316 - C3 56.550965 76.274542 58.174308 - C4 55.397775 76.721633 57.518241 - C5 55.502384 77.638695 56.466011 - C6 56.760136 78.108110 56.069019 - H11 58.883326 78.022759 56.418381 - H21 58.698372 76.398460 58.283168 - H31 56.470572 75.566748 58.986036 - H41 54.427775 76.359892 57.824946 - H51 54.612729 77.984192 55.960159 - H61 56.840480 78.815347 55.256461 - C1 54.057542 9.323766 34.264385 - C2 53.504787 10.122975 33.256626 - C3 54.338995 10.893275 32.437709 - C4 55.725958 10.864367 32.626551 - C5 56.278413 10.065990 33.634778 - C6 55.444205 9.295689 34.453695 - H11 53.414069 8.729992 34.896199 - H21 52.434796 10.144906 33.110413 - H31 53.912477 11.508980 31.659682 - H41 56.369132 11.458972 31.995205 - H51 57.348405 10.044058 33.780992 - H61 55.871024 8.679153 35.231255 - C1 20.022918 77.298950 36.776102 - C2 21.418726 77.212743 36.711769 - C3 22.040658 76.801317 35.526939 - C4 21.266782 76.476099 34.406443 - C5 19.871196 76.561425 34.471192 - C6 19.249264 76.972850 35.656022 - H11 19.543295 77.615895 37.690061 - H21 22.015939 77.464210 37.575969 - H31 23.117493 76.735840 35.477180 - H41 21.746627 76.158272 33.492900 - H51 19.273983 76.309957 33.606992 - H61 18.172207 77.039209 35.705364 - C1 15.233187 45.033339 43.875657 - C2 15.496136 44.390628 45.091235 - C3 16.716887 44.599872 45.743827 - C4 17.674688 45.451827 45.180839 - C5 17.412038 46.093618 43.965005 - C6 16.191287 45.884374 43.312414 - H11 14.291812 44.871608 43.372198 - H21 14.757035 43.733790 45.526015 - H31 16.919160 44.104764 46.682065 - H41 18.616363 45.612638 45.684042 - H51 18.151140 46.750456 43.530226 - H61 15.988714 46.380401 42.374431 - C1 66.778740 11.801111 67.494966 - C2 66.711108 13.166922 67.794696 - C3 67.874742 13.867461 68.133946 - C4 69.106008 13.202189 68.173467 - C5 69.173344 11.836417 67.874692 - C6 68.009710 11.135878 67.535441 - H11 65.881182 11.260789 67.233706 - H21 65.761340 13.680456 67.763647 - H31 67.822532 14.921318 68.364158 - H41 70.003270 13.742550 68.435682 - H51 70.123112 11.322883 67.905741 - H61 68.062216 10.081983 67.304276 - C1 72.786348 67.558598 61.587857 - C2 73.699820 66.661091 62.153455 - C3 75.066729 66.787515 61.878741 - C4 75.520166 67.811447 61.038428 - C5 74.606655 68.708145 60.472244 - C6 73.239746 68.581720 60.746958 - H11 71.732084 67.460797 61.799461 - H21 73.350204 65.871444 62.802274 - H31 75.771377 66.095669 62.315956 - H41 76.574392 67.908438 60.826238 - H51 74.956272 69.497792 59.823424 - H61 72.535137 69.274375 60.310329 - C1 37.159105 15.175545 60.732042 - C2 36.957607 14.682450 62.026688 - C3 37.953511 14.838892 62.998075 - C4 39.150912 15.488429 62.674817 - C5 39.352628 15.980550 61.380112 - C6 38.356724 15.824108 60.408724 - H11 36.391126 15.054508 59.982794 - H21 36.033604 14.181848 62.276401 - H31 37.797486 14.459327 63.997036 - H41 39.919109 15.608492 63.424005 - H51 40.276631 16.481152 61.130398 - H61 38.512531 16.204647 59.409823 - C1 24.542236 64.499765 62.145147 - C2 25.330588 63.497777 62.723396 - C3 24.794669 62.673364 63.719902 - C4 23.470399 62.850939 64.138160 - C5 22.682595 63.853399 63.560602 - C6 23.218513 64.677812 62.564096 - H11 24.955750 65.135819 61.376866 - H21 26.352099 63.360254 62.400374 - H31 25.402667 61.899787 64.165162 - H41 23.057432 62.215356 64.907132 - H51 21.661083 63.990921 63.883624 - H61 22.609968 65.450917 62.118145 - C1 68.185137 74.891025 25.613490 - C2 67.547775 75.960966 26.252900 - C3 68.243436 77.153987 26.482353 - C4 69.576459 77.277066 26.072396 - C5 70.213877 76.206910 25.433961 - C6 69.518216 75.013890 25.204508 - H11 67.648667 73.970790 25.436904 - H21 66.519149 75.866375 26.568690 - H31 67.751281 77.979630 26.974729 - H41 70.112985 78.197086 26.249957 - H51 71.242502 76.301502 25.118171 - H61 70.010315 74.188461 24.711157 - C1 33.434384 26.659359 5.335937 - C2 32.470872 25.703880 4.991620 - C3 32.803213 24.343940 4.989849 - C4 34.099067 23.939479 5.332395 - C5 35.062570 24.894952 5.675712 - C6 34.730229 26.254892 5.677483 - H11 33.178106 27.708232 5.336903 - H21 31.470896 26.015731 4.727917 - H31 32.059516 23.606918 4.725180 - H41 34.355336 22.890600 5.330429 - H51 36.062546 24.583101 5.939415 - H61 35.473935 26.991920 5.943152 - C1 75.439101 58.855608 3.681973 - C2 76.479726 59.520869 3.022899 - C3 77.132143 58.907191 1.946961 - C4 76.743936 57.628253 1.530098 - C5 75.704118 56.962836 2.189744 - C6 75.051700 57.576514 3.265681 - H11 74.936223 59.328808 4.512040 - H21 76.778931 60.507838 3.344005 - H31 77.934227 59.420961 1.438001 - H41 77.247620 57.154898 0.700603 - H51 75.404912 55.975867 1.868637 - H61 74.248810 57.062900 3.774070 - C1 24.241260 77.660641 65.860020 - C2 23.181723 78.467570 65.428627 - C3 22.437481 78.101599 64.300771 - C4 22.752776 76.928700 63.604307 - C5 23.812745 76.122502 64.035172 - C6 24.556987 76.488472 65.163028 - H11 24.815469 77.943160 66.729664 - H21 22.937961 79.372180 65.966216 - H31 21.619510 78.723691 63.968715 - H41 22.178999 76.646912 62.734135 - H51 24.056507 75.217892 63.497583 - H61 25.374526 75.865650 65.495612 - C1 67.881675 60.322936 60.276791 - C2 67.441663 60.403624 58.950244 - C3 66.534022 59.459645 58.455287 - C4 66.066394 58.434977 59.286878 - C5 66.507135 58.353864 60.612888 - C6 67.414775 59.297843 61.107845 - H11 68.582001 61.050789 60.658353 - H21 67.801880 61.194470 58.308723 - H31 66.193914 59.522637 57.432206 - H41 65.366797 57.706699 58.904779 - H51 66.146918 57.563018 61.254409 - H61 67.754155 59.235276 62.131464 - C1 44.062085 78.639301 44.504656 - C2 45.019869 78.404954 45.498428 - C3 45.153814 77.126899 46.053878 - C4 44.329976 76.083190 45.615555 - C5 43.371766 76.317854 44.622630 - C6 43.237820 77.595910 44.067180 - H11 43.958565 79.625125 44.076582 - H21 45.655957 79.209940 45.836262 - H31 45.893422 76.946060 46.819786 - H41 44.433069 75.097683 46.044476 - H51 42.735678 75.512869 44.284796 - H61 42.498639 77.776431 43.300426 - C1 9.256028 52.257765 0.338357 - C2 9.857280 53.479306 0.664215 - C3 11.234999 53.538903 0.905525 - C4 12.011465 52.376958 0.820976 - C5 11.410041 51.155534 0.496097 - C6 10.032322 51.095937 0.254787 - H11 8.193384 52.211800 0.152642 - H21 9.258460 54.375952 0.728878 - H31 11.698822 54.481514 1.155903 - H41 13.073937 52.423040 1.007670 - H51 12.008861 50.258888 0.431434 - H61 9.568670 50.153209 0.003430 - C1 66.932796 21.257229 38.653554 - C2 65.671701 21.354775 39.253533 - C3 65.292769 22.538601 39.897627 - C4 66.174933 23.624881 39.941743 - C5 67.436132 23.526891 39.342653 - C6 67.815064 22.343065 38.698559 - H11 67.225137 20.344031 38.157148 - H21 64.990759 20.516998 39.219045 - H31 64.319486 22.614023 40.359546 - H41 65.882696 24.537635 40.439038 - H51 68.117074 24.364668 39.377141 - H61 68.788243 22.268088 38.235751 - C1 56.996012 45.094167 30.891291 - C2 55.694758 44.696120 31.220152 - C3 55.457409 43.399022 31.690357 - C4 56.521314 42.499971 31.831703 - C5 57.822146 42.897773 31.501969 - C6 58.059495 44.194871 31.031764 - H11 57.178943 46.094452 30.528277 - H21 54.873933 45.389830 31.111739 - H31 54.453653 43.092447 31.944959 - H41 56.337961 41.499441 32.193844 - H51 58.642971 42.204063 31.610382 - H61 59.063673 44.501691 30.778035 - C1 30.163329 42.787509 40.137740 - C2 29.029731 41.971827 40.235045 - C3 28.507030 41.360380 39.089267 - C4 29.117928 41.564615 37.846184 - C5 30.250754 42.380931 37.748886 - C6 30.773454 42.992379 38.894664 - H11 30.566183 43.259376 41.021405 - H21 28.558674 41.813670 41.194124 - H31 27.633120 40.730356 39.164680 - H41 28.714302 41.093382 36.962526 - H51 30.721811 42.539088 36.789807 - H61 31.648137 43.621768 38.819243 - C1 60.038843 37.153238 37.547719 - C2 61.411651 36.930816 37.387166 - C3 62.111247 36.165009 38.327377 - C4 61.438034 35.621624 39.428141 - C5 60.065663 35.844872 39.589050 - C6 59.366068 36.610679 38.648839 - H11 59.499413 37.744207 36.822747 - H21 61.931055 37.349463 36.537640 - H31 63.170080 35.992687 38.202823 - H41 61.977901 35.031481 40.153469 - H51 59.546260 35.426225 40.438576 - H61 58.306797 36.782175 38.773038 - C1 16.113322 66.338301 69.374060 - C2 15.794153 65.481714 70.434362 - C3 16.162212 64.132140 70.378938 - C4 16.849439 63.639152 69.263211 - C5 17.167655 64.495481 68.202752 - C6 16.799596 65.845055 68.258176 - H11 15.829080 67.379072 69.416696 - H21 15.264496 65.862051 71.295494 - H31 15.916796 63.471706 71.197433 - H41 17.132728 62.598123 69.220418 - H51 17.697312 64.115144 67.341620 - H61 17.045965 66.505748 67.439837 - C1 59.655522 24.584875 62.095327 - C2 58.355286 25.085386 61.958489 - C3 57.413236 24.872785 62.972015 - C4 57.771423 24.159672 64.122378 - C5 59.071186 23.658492 64.258643 - C6 60.013235 23.871093 63.245117 - H11 60.381923 24.748543 61.313427 - H21 58.078970 25.636109 61.071305 - H31 56.410519 25.259839 62.866730 - H41 57.044548 23.995335 64.903705 - H51 59.347501 23.107769 65.145827 - H61 61.016426 23.484708 63.350975 - C1 71.212557 32.005289 0.620171 - C2 70.396530 32.816293 1.417807 - C3 70.967442 33.818470 2.211275 - C4 72.354381 34.009644 2.207107 - C5 73.170231 33.198097 1.410292 - C6 72.599319 32.195920 0.616824 - H11 70.772209 31.232115 0.008526 - H21 69.326421 32.669325 1.420658 - H31 70.337681 34.444676 2.825771 - H41 72.794552 34.782275 2.819573 - H51 74.240340 33.345065 1.407442 - H61 73.229257 31.570257 0.001507 - C1 8.624146 73.812144 10.554632 - C2 8.080690 74.279667 11.757100 - C3 7.545376 73.375003 12.681716 - C4 7.553518 72.002817 12.403863 - C5 8.096049 71.535592 11.201160 - C6 8.631363 72.440256 10.276544 - H11 9.036640 74.509958 9.841387 - H21 8.074895 75.338240 11.971877 - H31 7.127087 73.735762 13.609737 - H41 7.140099 71.305301 13.116872 - H51 8.101844 70.477019 10.986383 - H61 9.050576 72.079198 9.348758 - C1 36.806818 31.727776 9.493526 - C2 37.795638 30.773030 9.227924 - C3 39.147463 31.134056 9.273983 - C4 39.510467 32.449830 9.585644 - C5 38.521698 33.404531 9.850248 - C6 37.169873 33.043504 9.804189 - H11 35.764221 31.449360 9.457603 - H21 37.515749 29.757711 8.988065 - H31 39.910170 30.397155 9.070048 - H41 40.553115 32.728201 9.620569 - H51 38.801586 34.419849 10.090107 - H61 36.407114 33.780451 10.009122 - C1 63.520468 49.012220 6.218200 - C2 64.612494 49.704778 5.681830 - C3 65.233204 50.716104 6.424683 - C4 64.761888 51.034870 7.703907 - C5 63.669458 50.343005 8.239680 - C6 63.048748 49.331680 7.496827 - H11 63.041541 48.232507 5.645059 - H21 64.976618 49.458539 4.695158 - H31 66.076255 51.249577 6.011153 - H41 65.240411 51.815277 8.276451 - H51 63.305334 50.589245 9.226352 - H61 62.206101 48.797513 7.910954 - C1 47.823860 21.905371 53.771242 - C2 46.892511 21.209225 54.550870 - C3 47.307968 20.130754 55.340927 - C4 48.654773 19.748431 55.351355 - C5 49.585684 20.443939 54.571093 - C6 49.170227 21.522409 53.781037 - H11 47.503302 22.736892 53.161627 - H21 45.853512 21.504463 54.543402 - H31 46.589526 19.594472 55.943073 - H41 48.974893 18.916271 55.960336 - H51 50.624683 20.148700 54.578561 - H61 49.889107 22.059330 53.179523 - C1 17.235036 72.436523 15.575068 - C2 17.581447 73.738120 15.956768 - C3 16.580409 74.686906 16.196808 - C4 15.232959 74.334095 16.055147 - C5 14.886777 73.032963 15.672591 - C6 15.887815 72.084177 15.432552 - H11 18.007154 71.704923 15.389571 - H21 18.620955 74.010294 16.066700 - H31 16.847799 75.690680 16.492236 - H41 14.461070 75.066160 16.239788 - H51 13.847269 72.760789 15.562660 - H61 15.620196 71.079938 15.137979 - C1 24.880710 61.374869 50.969120 - C2 25.787292 62.186963 51.660832 - C3 26.027592 61.965682 53.022148 - C4 25.361311 60.932307 53.691753 - C5 24.454211 60.121037 53.000271 - C6 24.213911 60.342318 51.638955 - H11 24.695130 61.545837 49.919290 - H21 26.301870 62.983868 51.144216 - H31 26.727750 62.591620 53.555363 - H41 25.546373 60.762164 54.741814 - H51 23.939633 59.324132 53.516888 - H61 23.514271 59.715557 51.105511 - C1 46.278175 63.259182 9.530068 - C2 46.578877 61.913026 9.769433 - C3 45.859811 61.195906 10.733059 - C4 44.840044 61.824941 11.457319 - C5 44.540133 63.171115 11.218566 - C6 45.259199 63.888235 10.254940 - H11 46.833060 63.812315 8.787128 - H21 47.365197 61.427416 9.210305 - H31 46.091246 60.157162 10.916870 - H41 44.285950 61.271826 12.200871 - H51 43.753813 63.656725 11.777694 - H61 45.026973 64.926960 10.070517 - C1 20.921143 60.305485 45.129755 - C2 20.784913 61.282945 46.122661 - C3 21.915176 61.752406 46.802368 - C4 23.181670 61.244405 46.489170 - C5 23.317623 60.266441 45.497082 - C6 22.187359 59.796981 44.817375 - H11 20.049333 59.943171 44.605837 - H21 19.807939 61.675413 46.363977 - H31 21.810013 62.507186 47.567603 - H41 24.053203 61.606216 47.013906 - H51 24.294596 59.873974 45.255766 - H61 22.292799 59.042703 44.051321 - C1 71.580467 26.488640 15.594849 - C2 72.407909 25.474092 16.090715 - C3 73.756825 25.738287 16.356267 - C4 74.278299 27.017030 16.125954 - C5 73.451125 28.031049 15.629283 - C6 72.102209 27.766854 15.363730 - H11 70.540210 26.284707 15.389692 - H21 72.005583 24.487646 16.269035 - H31 74.394756 24.955775 16.739745 - H41 75.318824 27.220435 16.330306 - H51 73.853451 29.017496 15.450962 - H61 71.464011 28.549896 14.981058 - C1 19.039140 31.035984 3.557097 - C2 17.939580 30.324050 4.051027 - C3 16.641714 30.802153 3.834570 - C4 16.443410 31.992191 3.124183 - C5 17.542903 32.704392 2.631214 - C6 18.840769 32.226288 2.847671 - H11 20.040120 30.667392 3.724414 - H21 18.092386 29.405588 4.598584 - H31 15.793542 30.252283 4.214810 - H41 15.442363 32.361049 2.957827 - H51 17.390097 33.622854 2.083657 - H61 19.689009 32.775892 2.466470 - C1 51.314302 58.008105 52.781792 - C2 52.658611 58.135407 53.151225 - C3 53.327614 57.056209 53.740850 - C4 52.652308 55.849709 53.961042 - C5 51.307980 55.722871 53.592495 - C6 50.638977 56.802070 53.002870 - H11 50.798279 58.840609 52.327403 - H21 53.179920 59.065970 52.980844 - H31 54.364947 57.154267 54.024858 - H41 53.168312 55.017669 54.416317 - H51 50.786670 54.792308 53.762876 - H61 49.601664 56.703546 52.717976 - C1 40.219865 49.776697 54.622184 - C2 41.093198 48.778491 54.174160 - C3 40.843267 47.437306 54.488245 - C4 39.720005 47.094328 55.250354 - C5 38.847428 48.092541 55.699034 - C6 39.097358 49.433726 55.384949 - H11 40.412897 50.811113 54.380240 - H21 41.959510 49.042889 53.585656 - H31 41.516548 46.667289 54.141685 - H41 39.527728 46.059920 55.492954 - H51 37.981115 47.828143 56.287538 - H61 38.423322 50.203736 55.730853 - C1 60.916098 56.467350 21.750696 - C2 60.257349 55.258508 21.496529 - C3 60.987740 54.066897 21.416011 - C4 62.376881 54.084129 21.589662 - C5 63.035501 55.292953 21.842838 - C6 62.305110 56.484563 21.923355 - H11 60.352767 57.386407 21.812395 - H21 59.185543 55.244969 21.363146 - H31 60.479266 53.134302 21.220930 - H41 62.940084 53.165054 21.526972 - H51 64.107307 55.306492 21.976221 - H61 62.813713 57.417177 22.119428 - C1 70.916535 4.466493 43.021271 - C2 70.479201 3.242111 43.540383 - C3 69.158094 2.826792 43.335256 - C4 68.274321 3.635857 42.611016 - C5 68.711441 4.860428 42.092862 - C6 70.032548 5.275747 42.297989 - H11 71.935352 4.786931 43.179847 - H21 71.161097 2.617519 44.098635 - H31 68.821173 1.881763 43.734931 - H41 67.255290 3.315608 42.453397 - H51 68.029545 5.485020 41.534610 - H61 70.369683 6.220587 41.897356 - C1 11.773565 28.153065 55.259044 - C2 10.524010 28.379085 54.669654 - C3 9.455619 28.838975 55.448713 - C4 9.636782 29.072846 56.817160 - C5 10.885908 28.845924 57.406503 - C6 11.954300 28.386033 56.627445 - H11 12.597422 27.797998 54.658210 - H21 10.384254 28.199284 53.613775 - H31 8.492005 29.014242 54.993667 - H41 8.812497 29.427011 57.417947 - H51 11.025665 29.025724 58.462382 - H61 12.918342 28.211669 57.082537 - C1 10.597526 38.286228 43.875867 - C2 10.788329 39.663163 44.041678 - C3 11.877356 40.134369 44.784562 - C4 12.775579 39.228639 45.361635 - C5 12.584161 37.851959 45.196570 - C6 11.495135 37.380754 44.453686 - H11 9.757366 37.922866 43.303229 - H21 10.095773 40.362077 43.596004 - H31 12.024959 41.196645 44.911526 - H41 13.615125 39.592257 45.935020 - H51 13.276718 37.153045 45.642244 - H61 11.348146 36.318222 44.325976 - C1 53.454123 48.616581 60.007947 - C2 52.325376 48.994272 59.270971 - C3 51.231211 48.126507 59.172595 - C4 51.265793 46.881052 59.811195 - C5 52.394775 46.503163 60.547219 - C6 53.488940 47.370928 60.645595 - H11 54.298128 49.285736 60.083455 - H21 52.298303 49.955374 58.778742 - H31 50.360133 48.418455 58.604858 - H41 50.422024 46.211698 59.734735 - H51 52.421849 45.542060 61.039449 - H61 54.359782 47.079178 61.214284 - C1 9.690336 53.313935 5.186417 - C2 8.908390 52.174901 5.412277 - C3 9.327412 50.930676 4.926256 - C4 10.528380 50.825486 4.214376 - C5 11.309618 51.964551 3.987810 - C6 10.890596 53.208776 4.473831 - H11 9.366909 54.273587 5.560953 - H21 7.982114 52.255796 5.962014 - H31 8.724563 50.051919 5.101457 - H41 10.851098 49.865865 3.839134 - H51 12.235893 51.883656 3.438073 - H61 11.494153 54.087502 4.299335 - C1 66.918703 24.841404 22.095118 - C2 68.210298 24.321345 21.949610 - C3 68.438491 22.952476 22.134044 - C4 67.375089 22.103665 22.463985 - C5 66.083946 22.623912 22.610365 - C6 65.855753 23.992781 22.425931 - H11 66.742845 25.897226 21.953243 - H21 69.030713 24.975987 21.694456 - H31 69.434763 22.551296 22.020765 - H41 67.551398 21.048031 22.606733 - H51 65.263530 21.969270 22.865520 - H61 64.859028 24.393774 22.538339 - C1 24.687387 3.999210 33.351374 - C2 25.679135 3.054676 33.641447 - C3 25.351833 1.695341 33.711954 - C4 24.032782 1.280539 33.492388 - C5 23.041128 2.225097 33.203311 - C6 23.368430 3.584432 33.132804 - H11 24.939813 5.047629 33.297396 - H21 26.696959 3.374488 33.810259 - H31 26.117231 0.966734 33.934744 - H41 23.780451 0.232144 33.547362 - H51 22.023305 1.905285 33.034499 - H61 22.602939 4.313015 32.909018 - C1 12.646554 54.969645 39.444305 - C2 12.383384 54.088858 38.388461 - C3 11.079683 53.956637 37.895741 - C4 10.039153 54.705203 38.458864 - C5 10.302246 55.585090 39.515138 - C6 11.605947 55.717312 40.007858 - H11 13.651995 55.071284 39.824530 - H21 13.186168 53.511723 37.953496 - H31 10.877026 53.277864 37.080551 - H41 9.033635 54.602665 38.079069 - H51 9.499462 56.162225 39.950103 - H61 11.808680 56.396984 40.822618 - C1 41.011583 51.293190 13.956194 - C2 41.427210 52.578750 13.589530 - C3 42.790323 52.897717 13.580829 - C4 43.737808 51.931126 13.938791 - C5 43.322061 50.646119 14.306279 - C6 41.958949 50.327151 14.314980 - H11 39.960234 51.047366 13.963261 - H21 40.696373 53.324407 13.312741 - H31 43.110834 53.889199 13.296973 - H41 44.789038 52.177503 13.932548 - H51 44.052899 49.900462 14.583068 - H61 41.638557 49.335117 14.598012 - C1 38.844262 51.681866 6.069330 - C2 37.453212 51.559017 5.970638 - C3 36.845142 50.313008 6.164557 - C4 37.628121 49.189849 6.457169 - C5 39.018988 49.312630 6.554881 - C6 39.627058 50.558638 6.360961 - H11 39.313210 52.642810 5.919370 - H21 36.848952 52.425575 5.745499 - H31 35.771933 50.218623 6.089379 - H41 37.158990 48.228836 6.606148 - H51 39.623248 48.446071 6.780019 - H61 40.700449 50.653093 6.437121 - C1 60.144991 4.762001 68.688396 - C2 61.030161 3.975674 69.435399 - C3 62.261355 4.502835 69.843020 - C4 62.607379 5.816323 69.503636 - C5 61.722681 6.602083 68.755957 - C6 60.491487 6.074922 68.348337 - H11 59.195608 4.355234 68.373714 - H21 60.763077 2.962494 69.697839 - H31 62.943655 3.896423 70.420141 - H41 63.557235 6.222523 69.817643 - H51 61.989765 7.615263 68.493518 - H61 59.808716 6.681901 67.771891 - C1 67.720680 57.652624 75.985954 - C2 66.551046 56.928643 76.246067 - C3 65.315953 57.586320 76.289617 - C4 65.250494 58.967978 76.073053 - C5 66.420104 59.691859 75.813935 - C6 67.655197 59.034182 75.770386 - H11 68.673268 57.145388 75.952768 - H21 66.601317 55.862578 76.412557 - H31 64.413635 57.027491 76.489294 - H41 64.297882 59.475115 76.107235 - H51 66.369833 60.757924 75.647445 - H61 68.557538 59.593111 75.569714 - C1 30.565599 21.955565 43.172259 - C2 31.728426 22.199158 43.912763 - C3 31.712790 23.137168 44.951889 - C4 30.534327 23.831584 45.250512 - C5 29.372032 23.588626 44.509448 - C6 29.387668 22.650616 43.470322 - H11 30.577830 21.232390 42.370584 - H21 32.637534 21.663040 43.682890 - H31 32.609667 23.324225 45.523692 - H41 30.522628 24.555395 46.051627 - H51 28.462924 24.124744 44.739321 - H61 28.490259 22.462924 42.899079 - C1 70.849628 9.943158 71.703177 - C2 69.472444 10.185485 71.770203 - C3 68.999477 11.490560 71.951783 - C4 69.903693 12.553309 72.066336 - C5 71.280624 12.310764 72.000253 - C6 71.753592 11.005689 71.818673 - H11 71.214351 8.936536 71.563523 - H21 68.774696 9.365746 71.681223 - H31 67.937006 11.677444 72.002456 - H41 69.538718 13.559713 72.206933 - H51 71.978372 13.130502 72.089233 - H61 72.816315 10.819022 71.767057 - C1 33.310724 7.105224 60.668848 - C2 33.237237 5.962928 59.862865 - C3 32.835607 6.074041 58.526363 - C4 32.507465 7.327451 57.995844 - C5 32.580071 8.469331 58.802052 - C6 32.981701 8.358218 60.138554 - H11 33.620115 7.019404 61.699735 - H21 33.490963 4.995926 60.271853 - H31 32.779943 5.192859 57.904465 - H41 32.197193 7.412854 56.965182 - H51 32.326345 9.436333 58.393063 - H61 33.038246 9.239816 60.760227 - C1 39.202136 56.013163 37.501632 - C2 39.760222 55.912961 36.221652 - C3 41.149533 55.834762 36.068057 - C4 41.980758 55.856765 37.194443 - C5 41.422691 55.957906 38.474078 - C6 40.033380 56.036105 38.627673 - H11 38.130633 56.073865 37.620000 - H21 39.119021 55.895353 35.352576 - H31 41.579835 55.756452 35.080613 - H41 43.052280 55.797001 37.075729 - H51 42.063892 55.975513 39.343154 - H61 39.603059 56.113476 39.615462 - C1 23.950648 52.847805 57.211048 - C2 25.019617 53.648837 57.629980 - C3 26.280374 53.497865 57.040412 - C4 26.472162 52.545861 56.031913 - C5 25.403533 51.744388 55.613812 - C6 24.142776 51.895360 56.203380 - H11 22.978402 52.964025 57.666071 - H21 24.871654 54.383783 58.407605 - H31 27.104656 54.116592 57.363014 - H41 27.444748 52.429200 55.577720 - H51 25.551496 51.009441 54.836186 - H61 23.318153 51.277074 55.879947 - C1 5.476256 78.998547 55.689914 - C2 4.173748 79.037640 55.178253 - C3 3.409783 77.866022 55.118602 - C4 3.948326 76.655310 55.570612 - C5 5.250947 76.616187 56.081279 - C6 6.014912 77.787806 56.140930 - H11 6.065555 79.902129 55.735529 - H21 3.757902 79.971756 54.830057 - H31 2.404638 77.896555 54.724790 - H41 3.359140 75.751698 55.524003 - H51 5.666793 75.682071 56.429475 - H61 7.019944 77.757301 56.535735 - C1 59.602767 40.143603 28.911443 - C2 60.052988 39.016109 28.214371 - C3 61.374128 38.958779 27.754814 - C4 62.245047 40.028943 27.992329 - C5 61.794511 41.156573 28.688462 - C6 60.473370 41.213903 29.148019 - H11 58.583706 40.187921 29.265511 - H21 59.381357 38.190129 28.031588 - H31 61.721559 38.088481 27.217962 - H41 63.263793 39.984761 27.637321 - H51 62.466141 41.982553 28.871245 - H61 60.126255 42.084065 29.685810 - C1 51.373050 52.562388 35.774344 - C2 50.354835 53.510625 35.929058 - C3 49.224785 53.465079 35.103950 - C4 49.112950 52.471296 34.124128 - C5 50.131487 51.523865 33.968918 - C6 51.261537 51.569411 34.794026 - H11 52.244762 52.597809 36.410487 - H21 50.440692 54.277024 36.685366 - H31 48.438930 54.196057 35.224115 - H41 48.241561 52.436681 33.487489 - H51 50.045630 50.757466 33.212610 - H61 52.047069 50.837627 34.674356 - C1 68.196005 39.525804 19.218613 - C2 68.638679 38.208864 19.046685 - C3 67.711250 37.178875 18.849485 - C4 66.341146 37.465825 18.824213 - C5 65.898641 38.782429 18.997069 - C6 66.826070 39.812418 19.194269 - H11 68.911325 40.320085 19.371092 - H21 69.695725 37.987415 19.065542 - H31 68.052976 36.163145 18.715864 - H41 65.625996 36.671208 18.672662 - H51 64.841595 39.003877 18.978211 - H61 66.484175 40.828484 19.326963 - C1 5.451105 13.202297 22.159646 - C2 4.500080 14.223633 22.048856 - C3 4.522765 15.084333 20.944967 - C4 5.496476 14.923697 19.951868 - C5 6.447851 13.903100 20.063234 - C6 6.425165 13.042400 21.167123 - H11 5.433793 12.538756 23.011249 - H21 3.748414 14.347302 22.814653 - H31 3.788412 15.871543 20.859161 - H41 5.514138 15.587977 19.100841 - H51 7.199517 13.779431 19.297437 - H61 7.159170 12.254451 21.252352 - C1 14.790888 71.751187 48.536374 - C2 13.891702 72.806735 48.729074 - C3 14.332730 74.130817 48.618661 - C4 15.672945 74.399351 48.315548 - C5 16.572072 73.343911 48.123841 - C6 16.131043 72.019829 48.234254 - H11 14.450763 70.730007 48.621931 - H21 12.857548 72.599709 48.962327 - H31 13.638701 74.944971 48.766357 - H41 16.013010 75.420640 48.230984 - H51 17.606226 73.550938 47.890588 - H61 16.825132 71.205567 48.085566 - C1 46.152357 28.115253 21.675058 - C2 46.223848 28.576305 22.994971 - C3 45.501860 29.712408 23.379543 - C4 44.708382 30.387458 22.444202 - C5 44.637738 29.926936 21.124329 - C6 45.359726 28.790834 20.739757 - H11 46.709528 27.239249 21.378424 - H21 46.835496 28.055243 23.716858 - H31 45.556338 30.067349 24.398064 - H41 44.152058 31.263992 22.740877 - H51 44.026089 30.447998 20.402442 - H61 45.304401 28.435361 19.721195 - C1 48.095759 29.013510 71.194289 - C2 46.765521 28.828261 70.799319 - C3 46.147562 27.585537 70.982767 - C4 46.859841 26.528061 71.561185 - C5 48.190125 26.713135 71.955171 - C6 48.808084 27.955860 71.771723 - H11 48.572426 29.971880 71.052417 - H21 46.215672 29.644199 70.353615 - H31 45.121045 27.443104 70.678935 - H41 46.383220 25.569516 71.702074 - H51 48.739974 25.897197 72.400876 - H61 49.834554 28.098467 72.076539 - C1 70.028489 21.531330 25.105786 - C2 70.489360 22.807327 24.760413 - C3 71.231217 22.989706 23.587265 - C4 71.512204 21.896089 22.759489 - C5 71.052165 20.620219 23.105402 - C6 70.310308 20.437840 24.278551 - H11 69.456667 21.390672 26.010799 - H21 70.272129 23.651262 25.398633 - H31 71.585808 23.974299 23.320472 - H41 72.084858 22.036873 21.855016 - H51 71.269396 19.776284 22.467182 - H61 69.954885 19.453120 24.544803 - C1 5.413008 26.087021 70.106312 - C2 5.139400 27.332533 69.528654 - C3 4.217057 28.196142 70.131443 - C4 3.568321 27.814238 71.311890 - C5 3.841267 26.568533 71.888824 - C6 4.763610 25.704924 71.286035 - H11 6.124091 25.420843 69.641143 - H21 5.640286 27.627569 68.618265 - H31 4.006860 29.157356 69.686222 - H41 2.856577 28.480223 71.776334 - H51 3.340382 26.273496 72.799213 - H61 4.974469 24.743903 71.731980 - C1 29.724857 76.927574 76.791810 - C2 30.857152 77.368786 76.096762 - C3 32.079333 77.506428 76.765507 - C4 32.169219 77.202858 78.129300 - C5 31.036834 76.762642 78.824317 - C6 29.814653 76.625000 78.155572 - H11 28.782182 76.821813 76.276066 - H21 30.788101 77.602441 75.044442 - H31 32.952957 77.845844 76.228931 - H41 33.111804 77.309615 78.645014 - H51 31.105885 76.528987 79.876637 - H61 28.941118 76.284589 78.692179 - C1 77.982605 41.849060 64.494783 - C2 77.055397 42.890307 64.368522 - C3 76.456807 43.436673 65.510040 - C4 76.785424 42.941792 66.777821 - C5 77.711770 41.900094 66.903852 - C6 78.310360 41.353728 65.762333 - H11 78.443942 41.427454 63.614312 - H21 76.802227 43.272632 63.390527 - H31 75.742301 44.240605 65.412517 - H41 76.323225 43.362948 67.658062 - H51 77.964940 41.517769 67.881847 - H61 79.025729 40.550247 65.860087 - C1 71.774785 45.180997 58.369056 - C2 71.803605 45.880803 57.156913 - C3 72.999165 46.454646 56.708325 - C4 74.165905 46.328682 57.471879 - C5 74.136736 45.629786 58.684244 - C6 72.941176 45.055944 59.132832 - H11 70.852579 44.738776 58.715165 - H21 70.903675 45.977542 56.567414 - H31 73.021441 46.993606 55.772716 - H41 75.087762 46.771814 57.125991 - H51 75.036666 45.533047 59.273743 - H61 72.919248 44.516073 60.068219 - C1 27.304060 68.165394 31.744005 - C2 27.951729 67.348336 30.809772 - C3 27.670581 67.486454 29.445305 - C4 26.741765 68.441631 29.015071 - C5 26.093585 69.257830 29.949317 - C6 26.374733 69.119712 31.313785 - H11 27.520654 68.058551 32.796377 - H21 28.668799 66.611784 31.141500 - H31 28.171058 66.856746 28.724661 - H41 26.524660 68.547615 27.962713 - H51 25.376515 69.994381 29.617590 - H61 25.874767 69.750279 32.034415 - C1 33.206213 41.080710 58.354796 - C2 33.967933 42.208486 58.683059 - C3 34.598931 42.288068 59.930215 - C4 34.468209 41.239875 60.849109 - C5 33.705822 40.112781 60.521147 - C6 33.074824 40.033199 59.273991 - H11 32.719257 41.019569 57.393054 - H21 34.069384 43.016983 57.973988 - H31 35.187338 43.157707 60.182887 - H41 34.954499 41.301698 61.811152 - H51 33.604371 39.304284 61.230218 - H61 32.487084 39.162879 59.021019 - C1 56.551491 54.162130 64.972376 - C2 56.324388 55.490218 64.592300 - C3 55.316701 56.234488 65.217216 - C4 54.536117 55.650670 66.222209 - C5 54.762656 54.322520 66.601461 - C6 55.770343 53.578250 65.976544 - H11 57.328432 53.588041 64.490093 - H21 56.926943 55.940966 63.817385 - H31 55.142315 57.259326 64.924584 - H41 53.758612 56.224698 66.703668 - H51 54.160101 53.871772 67.376376 - H61 55.945293 52.553474 66.270000 - C1 5.704075 11.655231 53.032838 - C2 5.200345 12.950577 52.864953 - C3 5.675023 13.995469 53.666684 - C4 6.653431 13.745015 54.636300 - C5 7.156300 12.449676 54.804693 - C6 6.681621 11.404784 54.002962 - H11 5.337650 10.849321 52.414730 - H21 4.445938 13.144077 52.116509 - H31 5.287041 14.994878 53.536347 - H41 7.018995 14.550932 55.254916 - H51 7.910707 12.256176 55.553137 - H61 7.070465 10.405367 54.132790 - C1 65.712730 19.873042 17.722943 - C2 65.850013 18.549110 17.289114 - C3 67.090350 18.087116 16.833026 - C4 68.193404 18.949056 16.810766 - C5 68.055782 20.272990 17.243654 - C6 66.815445 20.734983 17.699743 - H11 64.755990 20.229403 18.074325 - H21 64.999234 17.883824 17.306809 - H31 67.196312 17.065470 16.499339 - H41 69.149805 18.592696 16.458444 - H51 68.906560 20.938275 17.225960 - H61 66.709822 21.756628 18.034371 - C1 74.903687 60.737457 7.817129 - C2 75.759724 61.799952 8.130427 - C3 75.330399 63.120510 7.952389 - C4 74.045037 63.378573 7.461053 - C5 73.189596 62.316170 7.146958 - C6 73.618921 60.995612 7.324996 - H11 75.235009 59.718988 7.954096 - H21 76.751199 61.601016 8.510088 - H31 75.990552 63.940043 8.195083 - H41 73.714311 64.397134 7.323289 - H51 72.198121 62.515106 6.767298 - H61 72.958171 60.175987 7.083100 - C1 78.292946 51.499946 29.356971 - C2 77.083814 52.090102 28.970231 - C3 75.966279 51.288746 28.707865 - C4 76.057877 49.897234 28.832239 - C5 77.267109 49.307250 29.217998 - C6 78.384643 50.108606 29.480364 - H11 79.154921 52.118029 29.558928 - H21 77.012823 53.163694 28.874831 - H31 75.033313 51.744256 28.410508 - H41 75.196002 49.279324 28.629301 - H51 77.338100 48.233658 29.313399 - H61 79.317509 49.652925 29.778702 - C1 11.056140 41.581516 19.811073 - C2 11.654407 42.639187 20.506243 - C3 13.029575 42.869818 20.381292 - C4 13.806476 42.042780 19.561173 - C5 13.208357 40.984758 18.866927 - C6 11.833189 40.754126 18.991877 - H11 9.995596 41.403456 19.907793 - H21 11.055043 43.277716 21.138527 - H31 13.490756 43.686409 20.916857 - H41 14.867168 42.220489 19.465377 - H51 13.807721 40.346228 18.234643 - H61 11.371860 39.937887 18.455389 - C1 12.902255 29.081108 73.842898 - C2 13.907721 28.275198 74.390073 - C3 13.627495 26.949948 74.743734 - C4 12.341804 26.430607 74.550221 - C5 11.336367 27.236764 74.004015 - C6 11.616592 28.562014 73.650353 - H11 13.118345 30.103325 73.570519 - H21 14.899852 28.675548 74.538857 - H31 14.403536 26.328081 75.164898 - H41 12.125742 25.408637 74.823569 - H51 10.344235 26.836414 73.855231 - H61 10.840523 29.183634 73.228221 - C1 10.051219 66.221031 78.241910 - C2 8.866628 65.896353 78.913610 - C3 8.079727 66.909459 79.474228 - C4 8.477416 68.247244 79.363147 - C5 9.662298 68.571649 78.692364 - C6 10.449200 67.558542 78.131746 - H11 10.658276 65.439586 77.809892 - H21 8.559362 64.864335 78.998857 - H31 7.165404 66.658886 79.991493 - H41 7.870651 69.028415 79.796082 - H51 9.969564 69.603667 78.607117 - H61 11.363231 67.809389 77.613564 - C1 28.473744 73.698924 64.142937 - C2 28.764124 74.142752 65.438524 - C3 29.182323 75.462096 65.649078 - C4 29.310142 76.337612 64.564044 - C5 29.020693 75.893465 63.268634 - C6 28.602494 74.574121 63.058080 - H11 28.151587 72.681248 63.980570 - H21 28.664965 73.467576 66.275809 - H31 29.405321 75.804596 66.648729 - H41 29.633231 77.354970 64.726588 - H51 29.119853 76.568642 62.431349 - H61 28.378565 74.231939 62.058252 - C1 5.867596 69.153092 37.428669 - C2 7.094524 69.086131 38.099501 - C3 7.174399 69.446455 39.449937 - C4 6.027347 69.873740 40.129541 - C5 4.800894 69.941546 39.458462 - C6 4.721018 69.581222 38.108026 - H11 5.806138 68.875549 36.387033 - H21 7.979448 68.755907 37.575476 - H31 8.120782 69.393775 39.967549 - H41 6.089279 70.152128 41.170930 - H51 3.915969 70.271769 39.982486 - H61 3.774161 69.633057 37.590662 - C1 46.904425 66.806742 35.648845 - C2 48.187212 67.248017 35.303034 - C3 48.534079 68.593577 35.473449 - C4 47.598160 69.497862 35.989673 - C5 46.315339 69.056727 36.334494 - C6 45.968471 67.711166 36.164080 - H11 46.636840 65.769035 35.517021 - H21 48.909587 66.550346 34.905328 - H31 49.524039 68.933613 35.207566 - H41 47.865710 70.535709 36.120508 - H51 45.592964 69.754398 36.732201 - H61 44.978546 67.370991 36.430952 - C1 61.912769 62.277308 26.345194 - C2 62.918880 61.336815 26.596318 - C3 62.872486 60.080780 25.979783 - C4 61.819982 59.765239 25.112123 - C5 60.813616 60.705310 24.861868 - C6 60.860009 61.961345 25.478403 - H11 61.948402 63.245873 26.821037 - H21 63.731287 61.580337 27.265221 - H31 63.649261 59.355738 26.172842 - H41 61.784094 58.796252 24.637149 - H51 60.001208 60.461788 24.192965 - H61 60.083490 62.686810 25.284474 - C1 26.833024 62.362063 37.465391 - C2 25.964750 61.309971 37.150663 - C3 25.149337 60.754526 38.143877 - C4 25.202198 61.251173 39.451819 - C5 26.071044 62.302446 39.766566 - C6 26.886457 62.857891 38.773352 - H11 27.462173 62.790148 36.699409 - H21 25.923410 60.927109 36.141481 - H31 24.478848 59.943579 37.900677 - H41 24.573621 60.822269 40.217820 - H51 26.112384 62.685308 40.775748 - H61 27.556374 63.669657 39.016533 - C1 18.099966 43.917223 15.683530 - C2 19.041514 43.082154 15.070345 - C3 18.661435 41.813460 14.616641 - C4 17.339807 41.379836 14.776121 - C5 16.398756 42.214481 15.390063 - C6 16.778835 43.483174 15.843767 - H11 18.393264 44.895545 16.033782 - H21 20.061053 43.416803 14.946680 - H31 19.387675 41.169787 14.142724 - H41 17.047006 40.401089 14.426626 - H51 15.379218 41.879832 15.513728 - H61 16.052098 44.127272 16.316928 - C1 71.064430 61.181145 65.793477 - C2 70.618434 62.048074 66.798152 - C3 71.175563 63.326870 66.917237 - C4 72.178687 63.738736 66.031646 - C5 72.625176 62.871521 65.027793 - C6 72.068047 61.592726 64.908708 - H11 70.634974 60.194737 65.701933 - H21 69.844088 61.730681 67.481080 - H31 70.830673 63.995884 67.691709 - H41 72.608636 64.724858 66.124012 - H51 73.399522 63.188914 64.344865 - H61 72.412444 60.923996 64.133414 - C1 49.657084 34.131784 37.753645 - C2 48.507813 33.356872 37.557326 - C3 48.535288 31.983410 37.827023 - C4 49.712033 31.384859 38.293040 - C5 50.861292 32.159572 38.488379 - C6 50.833817 33.533035 38.218682 - H11 49.635937 35.190999 37.545247 - H21 47.599695 33.818631 37.198381 - H31 47.648317 31.385953 37.676476 - H41 49.733168 30.325445 38.500458 - H51 51.769410 31.697813 38.847324 - H61 51.720800 34.130689 38.370209 - C1 33.132563 36.949848 68.635132 - C2 34.107766 37.638699 67.904163 - C3 34.331049 38.999725 68.144256 - C4 33.579130 39.671900 69.115318 - C5 32.603483 38.983280 69.845421 - C6 32.380200 37.622254 69.605328 - H11 32.960135 35.900242 68.449635 - H21 34.688382 37.120099 67.155377 - H31 35.084094 39.530730 67.580968 - H41 33.751114 40.721737 69.299949 - H51 32.022867 39.501880 70.594206 - H61 31.627599 37.091018 70.169482 - C1 70.691734 22.141298 2.920700 - C2 71.706663 22.580827 3.778944 - C3 71.378965 23.193985 4.994075 - C4 70.036338 23.367613 5.350962 - C5 69.021687 22.928971 4.492351 - C6 69.349385 22.315814 3.277220 - H11 70.944540 21.668757 1.983359 - H21 72.742560 22.446385 3.504020 - H31 72.162056 23.532083 5.656492 - H41 69.783810 23.841041 6.287936 - H51 67.985790 23.063414 4.767275 - H61 68.566015 21.976828 2.615170 - C1 10.560593 41.198222 39.085513 - C2 10.379742 39.902416 38.587486 - C3 9.108152 39.479420 38.182489 - C4 8.017412 40.352229 38.275520 - C5 8.198191 41.647456 38.774359 - C6 9.469782 42.070452 39.179356 - H11 11.541269 41.524267 39.398218 - H21 11.221278 39.229129 38.515077 - H31 8.969012 38.480088 37.797375 - H41 7.036665 40.025605 37.963627 - H51 7.356656 42.320743 38.846769 - H61 9.608993 43.070364 39.563658 - C1 72.964218 26.210510 36.263389 - C2 73.653236 25.031941 36.573356 - C3 73.367863 23.850881 35.877978 - C4 72.393471 23.848391 34.872633 - C5 71.703985 25.026593 34.563471 - C6 71.989358 26.207653 35.258849 - H11 73.184086 27.121284 36.800010 - H21 74.405450 25.033852 37.348541 - H31 73.900208 22.942018 36.116542 - H41 72.173135 22.937250 34.336816 - H51 70.951771 25.024683 33.788285 - H61 71.457481 27.116883 35.019480 - C1 64.689684 27.179347 73.964368 - C2 64.232768 26.112896 74.747797 - C3 63.699997 24.972389 74.135186 - C4 63.624143 24.898334 72.739147 - C5 64.080140 25.965053 71.956006 - C6 64.612910 27.105560 72.568616 - H11 65.100215 28.059102 74.436922 - H21 64.291792 26.169630 75.824847 - H31 63.348491 24.149368 74.739683 - H41 63.212692 24.018846 72.266880 - H51 64.021115 25.908319 70.878955 - H61 64.965336 27.928313 71.963832 - C1 16.098409 78.126963 4.353269 - C2 14.791467 77.711362 4.072147 - C3 14.293634 77.802305 2.766857 - C4 15.102743 78.308850 1.742689 - C5 16.409107 78.725222 2.024080 - C6 16.906940 78.634279 3.329370 - H11 16.482172 78.057160 5.360080 - H21 14.167323 77.319963 4.862078 - H31 13.285728 77.480709 2.549977 - H41 14.718403 78.379424 0.736147 - H51 17.033252 79.116622 1.234149 - H61 17.915425 78.955105 3.545981 - C1 35.880346 72.337949 59.110120 - C2 36.945107 71.442510 59.266082 - C3 37.969250 71.400033 58.312553 - C4 37.928632 72.252995 57.203062 - C5 36.863524 73.147561 57.046759 - C6 35.839381 73.190038 58.000288 - H11 35.090301 72.370384 59.845370 - H21 36.976896 70.784811 60.122331 - H31 38.791084 70.709899 58.433553 - H41 38.718329 72.219686 56.467471 - H51 36.831734 73.805260 56.190510 - H61 35.017894 73.881045 57.879630 - C1 37.157976 36.121675 39.559525 - C2 37.257214 37.491123 39.286367 - C3 38.483656 38.148416 39.440302 - C4 39.610861 37.436261 39.867395 - C5 39.511284 36.067264 40.141378 - C6 38.284841 35.409972 39.987443 - H11 36.211954 35.614877 39.441157 - H21 36.387795 38.040562 38.956261 - H31 38.560260 39.204653 39.228564 - H41 40.556544 37.943511 39.986588 - H51 40.380702 35.517826 40.471484 - H61 38.208577 34.353284 40.198356 - C1 69.819782 20.545611 68.281871 - C2 68.565738 20.042021 68.647413 - C3 67.447287 20.884010 68.650748 - C4 67.582880 22.229590 68.288542 - C5 68.836926 22.733188 67.924000 - C6 69.955378 21.891198 67.920664 - H11 70.682426 19.896261 68.279697 - H21 68.460858 19.003768 68.926289 - H31 66.479763 20.495107 68.931798 - H41 66.720239 22.878947 68.291716 - H51 68.941807 23.771441 67.645124 - H61 70.922899 22.280094 67.638614 - C1 51.397624 5.495732 64.781657 - C2 50.051775 5.186211 64.552012 - C3 49.102767 6.211735 64.464966 - C4 49.499610 7.546780 64.607566 - C5 50.845097 7.856050 64.838108 - C6 51.794104 6.830526 64.925153 - H11 52.129439 4.704719 64.849170 - H21 49.745553 4.156296 64.441361 - H31 48.064731 5.972833 64.286802 - H41 48.767432 8.337542 64.540950 - H51 51.151319 8.885965 64.948759 - H61 52.832503 7.069680 65.102420 - C1 38.299410 38.673992 61.327110 - C2 39.398513 37.906890 61.731311 - C3 39.330901 36.509272 61.686746 - C4 38.164186 35.878757 61.237979 - C5 37.065020 36.645826 60.834775 - C6 37.132631 38.043443 60.879341 - H11 38.351483 39.751903 61.361877 - H21 40.298931 38.393204 62.076980 - H31 40.179246 35.917675 61.997648 - H41 38.112049 34.800812 61.204210 - H51 36.164602 36.159511 60.489107 - H61 36.284350 38.635074 60.567441 - C1 63.267884 54.470577 59.640670 - C2 64.610448 54.451659 60.036921 - C3 65.029228 55.223116 61.127502 - C4 64.105445 56.013491 61.821833 - C5 62.763340 56.033046 61.424962 - C6 62.344560 55.261589 60.334380 - H11 62.945039 53.875865 58.799300 - H21 65.323151 53.841451 59.501719 - H31 66.064776 55.207620 61.433670 - H41 64.428748 56.608840 62.662582 - H51 62.050637 56.643254 61.960164 - H61 61.308553 55.276449 60.028833 - C1 64.286764 25.673678 10.015094 - C2 63.090309 26.390091 9.892222 - C3 61.863491 25.717645 9.943447 - C4 61.833128 24.328785 10.117544 - C5 63.029464 23.612504 10.239433 - C6 64.256282 24.284950 10.188208 - H11 65.232932 26.192319 9.975186 - H21 63.113559 27.461690 9.758517 - H31 60.940574 26.270602 9.849650 - H41 60.886841 23.810277 10.156469 - H51 63.006214 22.540905 10.373138 - H61 65.179319 23.731860 10.282989 - C1 39.769083 42.590974 68.610707 - C2 40.208900 43.683183 67.853416 - C3 40.134654 44.977117 68.382675 - C4 39.620592 45.178840 69.669225 - C5 39.180012 44.086842 70.425905 - C6 39.254258 42.792909 69.896646 - H11 39.826011 41.593087 68.202302 - H21 40.606100 43.527643 66.861055 - H31 40.474926 45.819464 67.798719 - H41 39.562901 46.176939 70.077019 - H51 38.782813 44.242382 71.418266 - H61 38.914749 41.950350 70.481213 - C1 66.966311 27.148334 44.417979 - C2 66.565872 27.868050 45.550017 - C3 66.613168 29.267193 45.542722 - C4 67.060902 29.946620 44.403391 - C5 67.462134 29.226885 43.271963 - C6 67.414839 27.827743 43.279257 - H11 66.930180 26.069226 44.423810 - H21 66.219835 27.344023 46.428877 - H31 66.303262 29.822274 46.415752 - H41 67.097826 31.025710 44.398169 - H51 67.808171 29.750912 42.393102 - H61 67.723951 27.272680 42.405618 - C1 38.237498 65.368405 36.308645 - C2 39.324526 64.690668 35.743938 - C3 40.631987 65.077640 36.061254 - C4 40.852420 66.142351 36.943277 - C5 39.765500 66.820489 37.507074 - C6 38.458039 66.433516 37.189758 - H11 37.229136 65.070151 36.063566 - H21 39.154617 63.868818 35.063912 - H31 41.470441 64.554044 35.626307 - H41 41.860890 66.441005 37.187446 - H51 39.935408 67.642339 38.187100 - H61 37.619478 66.956712 37.625615 - C1 7.318099 53.114999 27.391999 - C2 6.367327 52.861650 26.396158 - C3 5.156669 53.564609 26.389305 - C4 4.896783 54.520918 27.378293 - C5 5.847071 54.773448 28.374443 - C6 7.057729 54.070489 28.381296 - H11 8.251642 52.572523 27.397453 - H21 6.567948 52.124318 25.632722 - H31 4.423746 53.369754 25.620415 - H41 3.962756 55.062575 27.373148 - H51 5.646451 55.510780 29.137879 - H61 7.791135 54.266163 29.149877 - C1 5.462864 73.462177 21.913126 - C2 5.560445 74.751154 21.375662 - C3 4.486882 75.641866 21.493919 - C4 3.315737 75.243601 22.149639 - C5 3.217950 73.954512 22.686130 - C6 4.291513 73.063800 22.567873 - H11 6.290747 72.775128 21.821542 - H21 6.464161 75.058770 20.870280 - H31 4.562715 76.636530 21.080121 - H41 2.487648 75.930539 22.240251 - H51 2.314234 73.646897 23.191512 - H61 4.215886 72.069247 22.982644 - C1 45.851183 3.623096 46.192765 - C2 45.433219 4.266369 45.021716 - C3 45.484493 5.662620 44.933719 - C4 45.953732 6.415599 46.016771 - C5 46.370700 5.772372 47.187895 - C6 46.319426 4.376120 47.275892 - H11 45.811244 2.546247 46.260711 - H21 45.071752 3.685537 44.185823 - H31 45.162966 6.158637 44.029880 - H41 45.992675 7.492493 45.948900 - H51 46.732167 6.353204 48.023788 - H61 46.641949 3.880058 48.179656 - C1 73.527891 11.179236 52.962937 - C2 74.618123 10.772023 52.184848 - C3 75.357591 11.718915 51.466186 - C4 75.006826 13.073019 51.525613 - C5 73.916191 13.479904 52.302848 - C6 73.176723 12.533012 53.021510 - H11 72.957374 10.448839 53.516875 - H21 74.889238 9.727432 52.139390 - H31 76.199222 11.404720 50.866791 - H41 75.576940 13.803088 50.970821 - H51 73.645076 14.524495 52.348305 - H61 72.335494 12.847534 53.621760 - C1 37.323830 38.883603 13.693313 - C2 38.658498 38.860702 14.115201 - C3 39.424819 37.700763 13.950326 - C4 38.856473 36.563725 13.363564 - C5 37.521761 36.586450 12.942660 - C6 36.755439 37.746389 13.107535 - H11 36.732741 39.778119 13.820860 - H21 39.097301 39.738060 14.567348 - H31 40.454711 37.683604 14.274927 - H41 39.447517 35.669033 13.237000 - H51 37.082958 35.709092 12.490512 - H61 35.725592 37.763723 12.781950 - C1 23.555555 26.479036 40.921627 - C2 24.710725 26.568723 41.707367 - C3 25.730109 27.460780 41.353842 - C4 25.594324 28.263150 40.214575 - C5 24.439726 28.172699 39.428537 - C6 23.420341 27.280642 39.782063 - H11 22.769556 25.790729 41.194123 - H21 24.815358 25.950195 42.586694 - H31 26.620741 27.530559 41.960672 - H41 26.380894 28.950693 39.941781 - H51 24.335092 28.791227 38.549210 - H61 22.529137 27.211627 39.175530 - C1 49.407398 24.202634 19.834982 - C2 50.007977 23.471334 18.803306 - C3 51.126792 22.673379 19.070534 - C4 51.645029 22.606724 20.369439 - C5 51.045037 23.338682 21.400643 - C6 49.926221 24.136637 21.133415 - H11 48.544744 24.818348 19.628733 - H21 49.607892 23.522176 17.801264 - H31 51.589361 22.108507 18.274741 - H41 52.508270 21.991667 20.575216 - H51 51.445122 23.287839 22.402685 - H61 49.463065 24.700851 21.929680 - C1 61.659015 3.679677 1.538924 - C2 60.363337 3.876064 1.046478 - C3 59.260263 3.416784 1.775984 - C4 59.452866 2.761117 2.997937 - C5 60.748406 2.563993 3.489722 - C6 61.851480 3.023273 2.760215 - H11 62.509743 4.033578 0.976049 - H21 60.214555 4.382446 0.104043 - H31 58.260752 3.569265 1.396426 - H41 58.602000 2.406479 3.560151 - H51 60.897188 2.057612 4.432156 - H61 62.851128 2.871530 3.140436 - C1 27.051196 41.953004 4.053285 - C2 28.421824 41.678786 4.130974 - C3 28.879439 40.360676 4.016662 - C4 27.966427 39.316785 3.824661 - C5 26.596002 39.590984 3.747951 - C6 26.138386 40.909093 3.862263 - H11 26.698294 42.969582 4.141848 - H21 29.126390 42.484123 4.278485 - H31 29.936907 40.149436 4.075610 - H41 28.319532 38.300188 3.737077 - H51 25.891436 38.785646 3.600440 - H61 25.080716 41.120353 3.802335 - C1 5.679458 38.899321 47.232556 - C2 7.009196 39.043048 47.646065 - C3 7.451606 40.264262 48.168368 - C4 6.564279 41.341748 48.277162 - C5 5.235052 41.198201 47.862813 - C6 4.792642 39.976987 47.340510 - H11 5.338411 37.957544 46.829372 - H21 7.693736 38.211659 47.562762 - H31 8.477193 40.374650 48.488249 - H41 6.905837 42.283705 48.679506 - H51 4.550513 42.029589 47.946115 - H61 3.766544 39.866419 47.021468 - C1 48.492489 27.048823 27.426323 - C2 49.468124 26.370240 26.686382 - C3 49.901581 25.103491 27.095470 - C4 49.359404 24.515326 28.244500 - C5 48.384638 25.194299 28.984744 - C6 47.951181 26.461048 28.575656 - H11 48.158510 28.025976 27.110975 - H21 49.886065 26.823624 25.799528 - H31 50.653502 24.579722 26.523965 - H41 49.694252 23.538563 28.560152 - H51 47.966697 24.740915 29.871598 - H61 47.198391 26.984427 29.146858 - C1 71.266222 63.327385 72.634331 - C2 71.610829 62.156917 71.947962 - C3 72.855530 62.057501 71.314931 - C4 73.755624 63.128552 71.368270 - C5 73.410575 64.299107 72.053747 - C6 72.165874 64.398523 72.686777 - H11 70.306066 63.404142 73.122207 - H21 70.916750 61.330276 71.907245 - H31 73.121607 61.154102 70.786339 - H41 74.715338 63.051882 70.879502 - H51 74.104654 65.125749 72.094463 - H61 71.900239 65.301836 73.216262 - C1 7.433405 58.058348 40.714332 - C2 7.915685 57.705530 39.448324 - C3 8.848991 58.524503 38.801706 - C4 9.300017 59.696294 39.421097 - C5 8.817032 60.049421 40.686467 - C6 7.883726 59.230447 41.333085 - H11 6.713294 57.426867 41.212816 - H21 7.568271 56.801194 38.970599 - H31 9.221688 58.251648 37.825498 - H41 10.019423 60.328083 38.921975 - H51 9.164446 60.953757 41.164192 - H61 7.511734 59.502994 42.309932 - C1 71.405937 43.215796 30.744180 - C2 70.462199 43.679734 29.820075 - C3 70.227679 45.053684 29.689098 - C4 70.936898 45.963695 30.482227 - C5 71.879755 45.499655 31.406792 - C6 72.114275 44.125705 31.537769 - H11 71.586482 42.156094 30.845422 - H21 69.915396 42.977807 29.207665 - H31 69.500332 45.411458 28.975446 - H41 70.755472 47.023295 30.381445 - H51 72.426557 46.201582 32.019203 - H61 72.842503 43.768032 32.250961 - C1 35.009200 22.800117 46.784026 - C2 34.606749 21.459798 46.821803 - C3 35.245826 20.514047 46.011230 - C4 36.287354 20.908617 45.162880 - C5 36.689001 22.248894 45.124510 - C6 36.049924 23.194644 45.935083 - H11 34.516004 23.529552 47.408923 - H21 33.803627 21.155123 47.476716 - H31 34.935900 19.479938 46.041246 - H41 36.779746 20.179139 44.537391 - H51 37.492122 22.553568 44.469598 - H61 36.360654 24.228796 45.905660 - C1 20.081384 41.352379 26.137276 - C2 20.190521 40.514037 27.253127 - C3 19.318094 40.673508 28.336331 - C4 18.336529 41.671320 28.303684 - C5 18.228132 42.510055 27.188378 - C6 19.100560 42.350585 26.105174 - H11 20.754534 41.229587 25.302048 - H21 20.947359 39.743771 27.278196 - H31 19.401781 40.026034 29.196628 - H41 17.664119 41.794505 29.139456 - H51 17.471295 43.280321 27.163308 - H61 19.016132 42.997665 25.244332 - C1 54.371889 31.183187 51.268942 - C2 53.967791 31.972778 50.185843 - C3 54.837177 32.934933 49.658286 - C4 56.110660 33.107497 50.213827 - C5 56.514206 32.318635 51.297332 - C6 55.644820 31.356480 51.824889 - H11 53.701175 30.441406 51.676026 - H21 52.985548 31.839334 49.756738 - H31 54.525647 33.543270 48.822097 - H41 56.780822 33.850007 49.807149 - H51 57.496449 32.452079 51.726436 - H61 55.956902 30.747414 52.660672 - C1 23.896703 39.251324 44.229888 - C2 23.687467 39.563787 42.881394 - C3 24.058890 40.820301 42.388333 - C4 24.639549 41.764351 43.243767 - C5 24.847823 41.452157 44.592207 - C6 24.476400 40.195643 45.085268 - H11 23.609859 38.282352 44.610188 - H21 23.240059 38.835324 42.221159 - H31 23.898326 41.060810 41.347799 - H41 24.925431 42.733592 42.863413 - H51 25.295231 42.180619 45.252441 - H61 24.637926 39.954865 46.125856 - C1 79.056517 27.511768 44.552530 - C2 77.873312 26.782374 44.719441 - C3 76.701254 27.192409 44.072878 - C4 76.712403 28.331838 43.259403 - C5 77.895233 29.061549 43.093363 - C6 79.067290 28.651514 43.739927 - H11 79.960344 27.195696 45.051537 - H21 77.864704 25.902921 45.346521 - H31 75.788820 26.629028 44.200951 - H41 75.808200 28.648227 42.761267 - H51 77.903840 29.941002 42.466283 - H61 79.980100 29.214578 43.610983 - C1 17.043808 42.625124 62.067772 - C2 18.230564 41.883083 62.096679 - C3 18.585283 41.174964 63.251076 - C4 17.753247 41.208887 64.376566 - C5 16.567207 41.951598 64.347856 - C6 16.212488 42.659717 63.193459 - H11 16.770483 43.171559 61.177538 - H21 18.872282 41.856317 61.228219 - H31 19.500326 40.601763 63.272850 - H41 18.027288 40.663121 65.266996 - H51 15.925489 41.978364 65.216316 - H61 15.296728 43.232248 63.171488 - C1 75.514566 74.849132 44.100891 - C2 76.595478 75.551862 43.555317 - C3 77.538242 74.882919 42.765633 - C4 77.400094 73.511246 42.521521 - C5 76.319851 72.808572 43.067836 - C6 75.377087 73.477515 43.857521 - H11 74.787703 75.365040 44.710254 - H21 76.701855 76.610248 43.743056 - H31 78.371482 75.425396 42.344008 - H41 78.127626 72.995395 41.912899 - H51 76.213474 71.750187 42.880097 - H61 74.543178 72.934981 44.278404 - C1 34.328678 33.555695 71.668889 - C2 34.337273 32.417744 72.484269 - C3 33.144287 31.731561 72.740838 - C4 31.942705 32.183329 72.182027 - C5 31.934101 33.321635 71.367582 - C6 33.127087 34.007817 71.111012 - H11 35.248749 34.085097 71.471366 - H21 35.264325 32.068724 72.914967 - H31 33.151267 30.853138 73.369059 - H41 31.022625 31.654281 72.380484 - H51 31.007049 33.670655 70.936884 - H61 33.120115 34.885886 70.481857 - C1 7.626629 39.337758 63.587717 - C2 7.228440 38.072126 63.141093 - C3 8.144071 37.013152 63.131886 - C4 9.457891 37.219809 63.569303 - C5 9.856136 38.485491 64.014930 - C6 8.940505 39.544466 64.024137 - H11 6.920500 40.154551 63.594424 - H21 6.214681 37.912384 62.804172 - H31 7.836441 36.036617 62.788258 - H41 10.164076 36.403067 63.561599 - H51 10.869895 38.645233 64.351852 - H61 9.248079 40.520950 64.368763 - C1 17.112913 47.134257 70.144882 - C2 17.183235 48.295142 70.924146 - C3 16.079659 49.152903 71.003236 - C4 14.905760 48.849780 70.303064 - C5 14.835909 47.689562 69.523223 - C6 15.939486 46.831801 69.444133 - H11 17.964224 46.472948 70.083614 - H21 18.088629 48.528819 71.464883 - H31 16.133742 50.047890 71.605242 - H41 14.054921 49.511756 70.363755 - H51 13.930515 47.455885 68.982486 - H61 15.884931 45.936147 68.842703 - C1 13.416602 27.204287 52.299202 - C2 13.048021 28.539052 52.093288 - C3 14.032987 29.516551 51.908276 - C4 15.386533 29.159285 51.929179 - C5 15.754935 27.824881 52.136009 - C6 14.769970 26.847381 52.321021 - H11 12.656902 26.450497 52.442277 - H21 12.003772 28.814738 52.076521 - H31 13.748438 30.546027 51.748435 - H41 16.146055 29.913436 51.787020 - H51 16.799185 27.549195 52.152776 - H61 15.054698 25.817545 52.479947 - C1 33.690191 44.225294 46.311882 - C2 34.056261 42.875579 46.376012 - C3 35.339785 42.518196 46.805819 - C4 36.257238 43.510527 47.171498 - C5 35.891420 44.860000 47.106431 - C6 34.607896 45.217384 46.676624 - H11 32.700379 44.500877 45.980009 - H21 33.348341 42.109847 46.094507 - H31 35.621677 41.476881 46.856188 - H41 37.247302 43.234702 47.502434 - H51 36.599340 45.625732 47.387936 - H61 34.325752 46.258941 46.627192 - C1 43.389548 76.918996 60.870578 - C2 44.062829 75.744298 61.226429 - C3 43.366128 74.532010 61.296101 - C4 41.996145 74.494418 61.009923 - C5 41.322912 75.669140 60.655070 - C6 42.019613 76.881428 60.585398 - H11 43.926862 77.854016 60.817242 - H21 45.119910 75.773036 61.446647 - H31 43.885895 73.625727 61.569655 - H41 41.458879 73.559422 61.064257 - H51 40.265831 75.640402 60.434852 - H61 41.499799 77.787687 60.310846 - C1 59.306718 35.894985 72.140055 - C2 59.722014 34.962090 71.182408 - C3 59.865009 33.614563 71.533996 - C4 59.592709 33.199931 72.843231 - C5 59.178408 34.132917 73.800845 - C6 59.035413 35.480444 73.449257 - H11 59.196829 36.934324 71.868923 - H21 59.931539 35.281730 70.172125 - H31 60.184423 32.894863 70.794845 - H41 59.703593 32.160683 73.114330 - H51 58.968883 33.813278 74.811128 - H61 58.715004 36.200052 74.188441 - C1 55.185160 74.126793 42.521939 - C2 55.777331 72.890759 42.236625 - C3 57.168589 72.792544 42.115606 - C4 57.967676 73.930363 42.279900 - C5 57.375416 75.166293 42.564223 - C6 55.984158 75.264508 42.685243 - H11 54.112109 74.202548 42.614876 - H21 55.161003 72.012715 42.110453 - H31 57.625312 71.838745 41.896497 - H41 59.040638 73.854503 42.185973 - H51 57.991744 76.044337 42.690395 - H61 55.527524 76.218411 42.905342 - C1 74.984872 49.494297 24.669348 - C2 75.734250 50.561681 24.160451 - C3 75.088061 51.721126 23.715459 - C4 73.692495 51.813188 23.779364 - C5 72.943309 50.745553 24.287311 - C6 73.589498 49.586108 24.732304 - H11 75.483285 48.599942 25.012171 - H21 76.810990 50.491044 24.111658 - H31 75.666389 52.544844 23.323842 - H41 73.194274 52.707292 23.435592 - H51 71.866569 50.816190 24.336105 - H61 73.010978 48.762641 25.124869 - C1 72.873477 22.488039 13.493099 - C2 72.198615 21.321748 13.113391 - C3 72.345826 20.151134 13.866970 - C4 73.167900 20.146810 15.000258 - C5 73.843328 21.312701 15.379244 - C6 73.696116 22.483315 14.625664 - H11 72.760204 23.390743 12.911628 - H21 71.563858 21.325097 12.239427 - H31 71.824343 19.251779 13.574477 - H41 73.281739 19.243706 15.581007 - H51 74.478085 21.309352 16.253208 - H61 74.217035 23.383070 14.918879 - C1 8.765960 63.370544 25.863927 - C2 7.727392 63.551546 24.942805 - C3 7.981702 64.173350 23.714564 - C4 9.274581 64.614152 23.407445 - C5 10.312670 64.433971 24.328878 - C6 10.058360 63.812167 25.557119 - H11 8.569671 62.891318 26.811359 - H21 6.730001 63.210962 25.179356 - H31 7.180601 64.311992 23.003683 - H41 9.470391 65.094199 22.460324 - H51 11.310061 64.774555 24.092327 - H61 10.859940 63.672704 26.267689 - C1 60.276635 55.977928 56.556839 - C2 59.136701 56.186793 55.771488 - C3 58.702942 57.489896 55.500068 - C4 59.409118 58.584133 56.014000 - C5 60.548282 58.375147 56.799979 - C6 60.982041 57.072045 57.071398 - H11 60.610894 54.972869 56.766460 - H21 58.592131 55.342690 55.374404 - H31 57.824113 57.650852 54.893364 - H41 59.074089 59.589072 55.805007 - H51 61.092852 59.219250 57.197062 - H61 61.861639 56.911209 57.677475 - C1 3.671452 29.179967 13.954912 - C2 2.390966 29.133810 13.390930 - C3 2.134606 29.791379 12.181892 - C4 3.158733 30.495106 11.536836 - C5 4.438699 30.541966 12.101305 - C6 4.695059 29.884396 13.310343 - H11 3.869004 28.673118 14.887591 - H21 1.600899 28.590403 13.888167 - H31 1.146988 29.754822 11.746450 - H41 2.960661 31.002658 10.604643 - H51 5.228766 31.085372 11.604067 - H61 5.683197 29.920251 13.745298 - C1 52.117348 53.328068 48.301526 - C2 53.456738 53.564633 47.969982 - C3 54.347711 54.028482 48.945123 - C4 53.899295 54.255766 50.251810 - C5 52.559907 54.020105 50.582928 - C6 51.668934 53.556256 49.607786 - H11 51.430142 52.970695 47.549298 - H21 53.802982 53.388740 46.962054 - H31 55.381162 54.209962 48.689424 - H41 54.586503 54.614044 51.003612 - H51 52.213663 54.195998 51.590855 - H61 50.635481 53.373871 49.863912 - C1 22.935443 14.823465 38.852005 - C2 21.909098 15.272393 39.691607 - C3 21.585508 14.552559 40.847902 - C4 22.288262 13.383797 41.164596 - C5 23.313763 12.934546 40.324563 - C6 23.637354 13.654380 39.168268 - H11 23.184702 15.378475 37.960014 - H21 21.367241 16.174422 39.447729 - H31 20.794392 14.899577 41.496015 - H41 22.038160 12.828464 42.056156 - H51 23.855620 12.032517 40.568441 - H61 24.429313 13.307684 38.520585 - C1 56.826285 57.861019 51.199287 - C2 56.125181 59.066071 51.072190 - C3 56.585652 60.215868 51.724743 - C4 57.747227 60.160613 52.504393 - C5 58.447583 58.955492 52.632149 - C6 57.987112 57.805696 51.979597 - H11 56.470873 56.974175 50.696292 - H21 55.229342 59.109001 50.470218 - H31 56.045226 61.145642 51.625766 - H41 58.101891 61.047388 53.008047 - H51 59.343422 58.912562 53.234121 - H61 58.528287 56.875990 52.077914 - C1 21.581643 72.615201 64.678678 - C2 22.305461 71.451879 64.966116 - C3 21.670740 70.204729 64.925667 - C4 20.312202 70.120900 64.597781 - C5 19.588405 71.284173 64.311342 - C6 20.223126 72.531324 64.351790 - H11 22.071142 73.577078 64.710274 - H21 23.353740 71.516340 65.218498 - H31 22.229521 69.307313 65.146453 - H41 19.822724 69.158975 64.567183 - H51 18.540126 71.219713 64.058960 - H61 19.664324 73.428789 64.130006 - C1 65.155266 75.432847 30.522010 - C2 63.826655 75.026676 30.349763 - C3 63.426454 73.749456 30.760176 - C4 64.354864 72.878406 31.342835 - C5 65.683418 73.284283 31.514128 - C6 66.083619 74.561503 31.103716 - H11 65.463947 76.417781 30.205098 - H21 63.110124 75.698813 29.900814 - H31 62.401241 73.436658 30.628140 - H41 64.046126 71.893177 31.658794 - H51 66.399950 72.612145 31.963077 - H61 67.108889 74.874594 31.236706 - C1 55.984562 51.276022 4.708160 - C2 55.660427 50.270576 5.626780 - C3 54.390064 49.682830 5.601821 - C4 53.443836 50.100530 4.658242 - C5 53.767724 51.106465 3.740458 - C6 55.038087 51.694211 3.765417 - H11 56.964225 51.729557 4.727717 - H21 56.390553 49.947781 6.354420 - H31 54.140528 48.906500 6.309904 - H41 52.463926 49.647483 4.639522 - H51 53.037598 51.429260 3.012818 - H61 55.287870 52.470053 3.056497 - C1 10.296562 30.314499 35.211973 - C2 9.140980 31.069149 35.446462 - C3 8.012603 30.463793 36.012325 - C4 8.039808 29.103787 36.343699 - C5 9.194922 28.349172 36.108327 - C6 10.323299 28.954528 35.542464 - H11 11.166662 30.781355 34.775184 - H21 9.120050 32.118558 35.191426 - H31 7.121573 31.046346 36.194078 - H41 7.169240 28.636966 36.779605 - H51 9.215852 27.299763 36.363364 - H61 11.214797 28.371940 35.361595 - C1 45.117477 39.658047 76.319698 - C2 43.908931 40.065850 76.896729 - C3 43.622869 41.429602 77.031780 - C4 44.545353 42.385552 76.589799 - C5 45.754053 41.977689 76.013754 - C6 46.040114 40.613936 75.878704 - H11 45.338211 38.606229 76.215926 - H21 43.196860 39.328441 77.237206 - H31 42.690063 41.744012 77.476028 - H41 44.324772 43.437310 76.694557 - H51 46.466124 42.715097 75.673277 - H61 46.972767 40.299587 75.433469 - C1 39.963799 51.541199 31.322601 - C2 40.349847 52.873667 31.510611 - C3 39.609215 53.906416 30.923428 - C4 38.482534 53.606698 30.148235 - C5 38.097216 52.274382 29.959559 - C6 38.837849 51.241633 30.546742 - H11 40.535288 50.744712 31.775174 - H21 41.218710 53.105089 32.109161 - H31 39.906588 54.934325 31.069404 - H41 37.911775 54.403336 29.694995 - H51 37.228354 52.042960 29.361009 - H61 38.539745 50.213572 30.401431 - C1 43.534580 70.667586 11.483116 - C2 42.975412 71.108369 12.688476 - C3 41.585296 71.114874 12.854081 - C4 40.754347 70.680596 11.814325 - C5 41.313507 70.240811 10.608894 - C6 42.703623 70.234305 10.443290 - H11 44.606709 70.662963 11.355317 - H21 43.616393 71.442866 13.490970 - H31 41.154147 71.453994 13.784374 - H41 39.682210 70.686216 11.942053 - H51 40.672526 69.906313 9.806400 - H61 43.134780 69.894187 9.513068 - C1 58.592924 60.580112 67.040904 - C2 58.684167 61.879185 66.527157 - C3 57.709397 62.830197 66.851645 - C4 56.643386 62.482136 67.689879 - C5 56.551767 61.183000 68.202701 - C6 57.526536 60.231988 67.878213 - H11 59.344543 59.846577 66.790286 - H21 59.506880 62.148037 65.880936 - H31 57.780492 63.832584 66.456041 - H41 55.891391 63.215608 67.939572 - H51 55.729054 60.914148 68.848922 - H61 57.455818 59.229664 68.274741 - C1 53.182985 2.454441 51.343689 - C2 52.422358 2.069483 50.233236 - C3 52.568529 2.745912 49.016285 - C4 53.475326 3.807298 48.909786 - C5 54.235065 4.192696 50.020371 - C6 54.088895 3.516268 51.237322 - H11 53.069918 1.932953 52.282347 - H21 51.723163 1.250234 50.315080 - H31 51.982401 2.448151 48.159471 - H41 53.587505 4.329227 47.971261 - H51 54.934260 5.011945 49.938527 - H61 54.675910 3.813588 52.094004 - C1 3.518979 21.966275 71.227745 - C2 2.335427 21.270144 71.500616 - C3 2.030111 20.103216 70.790015 - C4 2.908347 19.632419 69.806544 - C5 4.091190 20.329039 69.533164 - C6 4.396506 21.495967 70.243765 - H11 3.754206 22.866484 71.775564 - H21 1.658061 21.632908 72.259772 - H31 1.117518 19.565771 71.001353 - H41 2.672412 18.732699 69.258216 - H51 4.768556 19.966275 68.774008 - H61 5.309808 22.032923 70.032936 - C1 62.145134 3.247417 26.873133 - C2 61.349722 4.363647 27.158091 - C3 61.907125 5.647395 27.123686 - C4 63.259940 5.814914 26.804324 - C5 64.055322 4.698729 26.520366 - C6 63.497919 3.414981 26.554770 - H11 61.715265 2.257316 26.900069 - H21 60.305849 4.234611 27.403895 - H31 61.293121 6.508460 27.342555 - H41 63.689779 6.805060 26.778388 - H51 65.099195 4.827765 26.274561 - H61 64.111953 2.553870 26.334902 - C1 49.983759 12.940995 75.889237 - C2 48.977954 13.759544 76.416670 - C3 48.541440 13.571652 77.733500 - C4 49.110730 12.565211 78.522898 - C5 50.115680 11.746266 77.995131 - C6 50.552195 11.934158 76.678301 - H11 50.320104 13.085707 74.873489 - H21 48.539079 14.536465 75.807963 - H31 47.766220 14.203862 78.140542 - H41 48.773530 12.420104 79.538312 - H51 50.554555 10.969345 78.603838 - H61 51.328269 11.302345 76.271594 - C1 70.351832 66.093737 52.522323 - C2 69.026204 66.540922 52.471447 - C3 68.136221 65.988050 51.542925 - C4 68.571866 64.987993 50.665278 - C5 69.897527 64.541649 50.715613 - C6 70.787510 65.094522 51.644136 - H11 71.038288 66.520462 53.238212 - H21 68.689792 67.312033 53.148911 - H31 67.113353 66.332436 51.504499 - H41 67.885443 64.562109 49.948848 - H51 70.233939 63.770539 50.038150 - H61 71.810344 64.749295 51.683102 - C1 54.138628 4.659273 74.520466 - C2 55.520840 4.457795 74.614000 - C3 56.387917 5.145051 73.756242 - C4 55.872782 6.033783 72.804951 - C5 54.490742 6.234418 72.710907 - C6 53.623665 5.547162 73.568665 - H11 53.469920 4.128896 75.181786 - H21 55.918458 3.772627 75.348292 - H31 57.454243 4.990259 73.829214 - H41 56.541662 6.563317 72.143121 - H51 54.093124 6.919586 71.976615 - H61 52.557167 5.702797 73.496203 - C1 56.534195 23.817034 73.062111 - C2 57.520639 23.203453 73.843326 - C3 57.561618 21.808154 73.949873 - C4 56.616153 21.026436 73.275205 - C5 55.629365 21.640074 72.494927 - C6 55.588387 23.035373 72.388380 - H11 56.502408 24.893189 72.980293 - H21 58.250517 23.806396 74.363401 - H31 58.323283 21.334942 74.551766 - H41 56.647596 19.950337 73.357960 - H51 54.899488 21.037130 71.974852 - H61 54.827065 23.508528 71.785550 - C1 41.610132 28.580710 16.064269 - C2 42.109452 28.258162 14.796794 - C3 41.923708 29.140671 13.726015 - C4 41.238643 30.345727 13.922710 - C5 40.738641 30.667660 15.189790 - C6 40.924385 29.785151 16.260569 - H11 41.753082 27.899846 16.889983 - H21 42.638543 27.328770 14.645029 - H31 42.309849 28.892142 12.748535 - H41 41.095011 31.025976 13.096601 - H51 40.209550 31.597053 15.341556 - H61 40.538926 30.034295 17.238444 - C1 16.795976 43.987244 49.696822 - C2 16.915044 45.357079 49.433719 - C3 15.766676 46.147048 49.302990 - C4 14.499239 45.567182 49.435365 - C5 14.380318 44.197405 49.697481 - C6 15.528687 43.407436 49.828210 - H11 17.681696 43.377958 49.797248 - H21 17.892826 45.804710 49.332176 - H31 15.858737 47.203964 49.101022 - H41 13.613666 46.176526 49.333952 - H51 13.402537 43.749775 49.799023 - H61 15.436478 42.350461 50.031165 - C1 58.338681 72.086677 7.271152 - C2 59.069924 73.162959 7.787633 - C3 58.440257 74.108509 8.605768 - C4 57.079347 73.977778 8.907423 - C5 56.348133 72.902166 8.390200 - C6 56.977800 71.956616 7.572065 - H11 58.824285 71.357666 6.639848 - H21 60.120029 73.263612 7.555493 - H31 59.004758 74.938174 9.004933 - H41 56.593772 74.707458 9.537985 - H51 55.298028 72.801512 8.622340 - H61 56.413269 71.126281 7.173643 - C1 43.045756 68.319042 22.269155 - C2 41.907367 67.512822 22.387178 - C3 41.558511 66.972133 23.630499 - C4 42.348044 67.237665 24.755796 - C5 43.486727 68.042980 24.637467 - C6 43.835583 68.583669 23.394146 - H11 43.314975 68.735700 21.310128 - H21 41.297793 67.308377 21.519213 - H31 40.679718 66.351031 23.721560 - H41 42.079119 66.820102 25.714517 - H51 44.096301 68.247425 25.505432 - H61 44.714082 69.205677 23.303391 - C1 21.213559 33.883823 61.501741 - C2 20.275195 32.849207 61.407442 - C3 18.910673 33.126554 61.552524 - C4 18.484515 34.438519 61.791906 - C5 19.422882 35.472703 61.887107 - C6 20.787404 35.195355 61.742025 - H11 22.265969 33.669787 61.390225 - H21 20.603783 31.837062 61.222146 - H31 18.186851 32.328447 61.478745 - H41 17.432108 34.652123 61.904324 - H51 19.094294 36.484848 62.072403 - H61 21.511222 35.993895 61.814902 - C1 65.264675 37.288792 36.083919 - C2 64.770985 37.130963 34.783453 - C3 65.297241 36.135981 33.951014 - C4 66.317187 35.298827 34.419040 - C5 66.811350 35.457352 35.718966 - C6 66.285094 36.452335 36.551405 - H11 64.859022 38.056454 36.725757 - H21 63.983664 37.776357 34.422437 - H31 64.915572 36.013713 32.948160 - H41 66.723313 34.531862 33.776662 - H51 67.598672 34.811958 36.079982 - H61 66.666290 36.573907 37.554799 - C1 54.507362 10.074095 72.273031 - C2 53.150855 9.941015 72.592450 - C3 52.406443 11.065889 72.967151 - C4 53.018538 12.323842 73.022434 - C5 54.375036 12.456606 72.703964 - C6 55.119447 11.331732 72.329263 - H11 55.081532 9.206426 71.984427 - H21 52.678330 8.970657 72.549248 - H31 51.359748 10.963200 73.212554 - H41 52.444358 13.191195 73.311988 - H51 54.847560 13.426964 72.747166 - H61 56.166152 11.434737 72.082912 - C1 29.793443 57.227241 19.838026 - C2 30.107213 57.044695 21.190090 - C3 30.092773 58.137030 22.065582 - C4 29.764563 59.411911 21.589010 - C5 29.451792 59.594450 20.236979 - C6 29.466233 58.502115 19.361487 - H11 29.804981 56.384796 19.162772 - H21 30.359850 56.061065 21.558040 - H31 30.333872 57.995844 23.108786 - H41 29.754025 60.254349 22.264297 - H51 29.199156 60.578081 19.869029 - H61 29.224134 58.643308 18.318250 - C1 37.762172 41.730901 21.220463 - C2 36.729165 40.797386 21.366395 - C3 35.396681 41.198258 21.212516 - C4 35.097204 42.532647 20.912706 - C5 36.130070 43.466088 20.767762 - C6 37.462554 43.065216 20.921641 - H11 38.789817 41.421742 21.339542 - H21 36.960090 39.767729 21.597092 - H31 34.599961 40.477761 21.324134 - H41 34.069418 42.841733 20.794615 - H51 35.899144 44.495745 20.537065 - H61 38.259415 43.785787 20.809035 - C1 26.521756 47.088030 36.367133 - C2 26.993868 47.491802 37.621697 - C3 27.939722 46.711917 38.297738 - C4 28.413464 45.528260 37.719215 - C5 27.940651 45.124188 36.465298 - C6 26.994797 45.904073 35.789257 - H11 25.791969 47.689365 35.845961 - H21 26.628923 48.405297 38.067884 - H31 28.304564 47.024077 39.265097 - H41 29.142549 44.926625 38.241034 - H51 28.305596 44.210693 36.019111 - H61 26.630657 45.592213 34.821252 - C1 3.663369 21.089868 24.012437 - C2 2.369602 20.917828 24.518817 - C3 1.780846 19.647688 24.517951 - C4 2.485857 18.549587 24.010705 - C5 3.779018 18.721903 23.503580 - C6 4.367774 19.992044 23.504446 - H11 4.117242 22.069569 24.012776 - H21 1.825792 21.764819 24.910760 - H31 0.783163 19.514977 24.909556 - H41 2.031378 17.570163 24.009621 - H51 4.322828 17.874913 23.111637 - H61 5.366063 20.124478 23.113587 - C1 70.094324 70.656792 57.622892 - C2 71.396103 70.593928 58.134040 - C3 72.012423 71.751656 58.623637 - C4 71.326965 72.972249 58.602087 - C5 70.025779 73.035144 58.090134 - C6 69.409459 71.877416 57.600537 - H11 69.619187 69.763925 57.244943 - H21 71.924837 69.652183 58.151298 - H31 73.016295 71.702779 59.018845 - H41 71.802695 73.865147 58.979231 - H51 69.497045 73.976889 58.072876 - H61 68.404994 71.926262 57.206134 - C1 34.335726 62.826794 41.019752 - C2 35.433813 63.109271 41.840887 - C3 36.396583 62.122903 42.085925 - C4 36.261266 60.854059 41.509828 - C5 35.162836 60.571473 40.689627 - C6 34.200066 61.557840 40.444589 - H11 33.593015 63.587461 40.831122 - H21 35.538669 64.088341 42.284923 - H31 37.244150 62.341307 42.718591 - H41 37.003634 60.093283 41.699392 - H51 35.057980 59.592403 40.245591 - H61 33.352841 61.339546 39.810989 - C1 30.259121 64.050060 70.477872 - C2 30.286607 64.683049 71.726239 - C3 31.493476 65.180114 72.232484 - C4 32.672859 65.044190 71.490363 - C5 32.645407 64.410455 70.242661 - C6 31.438538 63.913389 69.736415 - H11 29.328352 63.666370 70.087660 - H21 29.376673 64.788537 72.298632 - H31 31.514311 65.669292 73.195089 - H41 33.603662 65.427134 71.881239 - H51 33.555341 64.304967 69.670268 - H61 31.417669 63.424958 68.773146 - C1 61.521735 55.010091 47.119708 - C2 62.759080 55.334009 46.550581 - C3 63.435394 54.393719 45.764232 - C4 62.874363 53.129511 45.547010 - C5 61.637683 52.805450 46.116870 - C6 60.961368 53.745740 46.903219 - H11 61.000360 55.735205 47.726496 - H21 63.191756 56.309533 46.717574 - H31 64.389445 54.644128 45.324437 - H41 63.396403 52.404254 44.940955 - H51 61.205007 51.829926 45.949877 - H61 60.006653 53.495473 47.342280 - C1 50.469199 44.047652 22.609309 - C2 49.926061 42.937325 21.952022 - C3 48.765534 42.330022 22.446240 - C4 48.148146 42.833045 23.597745 - C5 48.691823 43.942593 24.255355 - C6 49.852349 44.549897 23.761137 - H11 51.364485 44.515751 22.228311 - H21 50.401922 42.549504 21.063264 - H31 48.346109 41.474101 21.938480 - H41 47.253398 42.364168 23.979066 - H51 48.215961 44.330415 25.144113 - H61 50.271236 45.406595 24.268574 - C1 30.257340 16.416614 14.689523 - C2 29.094136 17.183039 14.550239 - C3 29.126382 18.557935 14.811984 - C4 30.321832 19.166407 15.213014 - C5 31.484530 18.399837 15.353149 - C6 31.452285 17.024941 15.091404 - H11 30.232310 15.356151 14.488013 - H21 28.171905 16.713847 14.240253 - H31 28.229182 19.149206 14.703509 - H41 30.346357 20.226725 15.415375 - H51 32.406761 18.869029 15.663135 - H61 32.349991 16.433814 15.199029 - C1 14.457869 48.395322 22.298637 - C2 14.553331 47.546101 23.407493 - C3 13.402939 46.939210 23.925345 - C4 12.157084 47.181539 23.334342 - C5 12.061648 48.031373 22.226277 - C6 13.212040 48.638264 21.708424 - H11 15.345101 48.863668 21.899531 - H21 15.514536 47.358560 23.863184 - H31 13.476912 46.283323 24.780143 - H41 11.269878 46.713806 23.734238 - H51 11.100443 48.218914 21.770585 - H61 13.138041 49.293539 20.852837 - C1 38.174289 56.463321 43.601197 - C2 39.067526 57.452714 43.173319 - C3 38.849699 58.790762 43.522705 - C4 37.738634 59.139417 44.299969 - C5 36.845121 58.150229 44.726907 - C6 37.062948 56.812182 44.377521 - H11 38.342134 55.431414 43.331366 - H21 39.925104 57.183796 42.574166 - H31 39.539431 59.553752 43.193382 - H41 37.570513 60.171530 44.568860 - H51 35.987543 58.419147 45.326060 - H61 36.373492 56.048986 44.707783 - C1 13.169277 41.853304 26.248255 - C2 13.606472 43.117342 25.834833 - C3 14.885614 43.270875 25.287007 - C4 15.727561 42.160368 25.152602 - C5 15.290676 40.896780 25.566861 - C6 14.011534 40.743248 26.114687 - H11 12.182865 41.735028 26.671122 - H21 12.956784 43.974095 25.937897 - H31 15.222338 44.245903 24.967203 - H41 16.714283 42.279095 24.730572 - H51 15.940364 40.040028 25.463797 - H61 13.674500 39.767769 26.433654 - C1 42.900912 16.236991 40.244785 - C2 44.273213 16.024123 40.421780 - C3 44.721248 14.917136 41.152351 - C4 43.796982 14.023017 41.705929 - C5 42.424937 14.236484 41.529693 - C6 41.976902 15.343471 40.799121 - H11 42.555420 17.090997 39.681647 - H21 44.986427 16.713518 39.994227 - H31 45.779954 14.752525 41.287937 - H41 44.142730 13.169610 42.269825 - H51 41.711724 13.547088 41.957245 - H61 40.917940 15.507482 40.662777 - C1 44.128554 39.642266 39.156689 - C2 43.374796 40.552777 39.906802 - C3 44.000197 41.652060 40.507087 - C4 45.379357 41.840832 40.357259 - C5 46.133016 40.929893 39.608045 - C6 45.507615 39.830610 39.007760 - H11 43.646212 38.794244 38.694068 - H21 42.310652 40.407608 40.021971 - H31 43.418395 42.354912 41.084878 - H41 45.861600 42.688426 40.820779 - H51 47.197160 41.075063 39.492876 - H61 46.089516 39.128186 38.429071 - C1 12.198502 50.519004 66.525659 - C2 12.772554 51.199415 65.445216 - C3 14.164851 51.306515 65.345566 - C4 14.983096 50.733203 66.326359 - C5 14.408992 50.053759 67.407050 - C6 13.016695 49.946659 67.506700 - H11 11.124666 50.436776 66.602660 - H21 12.141417 51.641251 64.688124 - H31 14.607550 51.830578 64.511473 - H41 16.056880 50.816398 66.249607 - H51 15.040129 49.611924 68.164143 - H61 12.574048 49.421629 68.340545 - C1 41.976441 43.629626 38.246569 - C2 43.349383 43.762171 38.007171 - C3 44.173068 44.359295 38.968877 - C4 43.623811 44.823873 40.169980 - C5 42.250951 44.692144 40.408806 - C6 41.427266 44.095020 39.447100 - H11 41.341162 43.169434 37.504640 - H21 43.773383 43.403237 37.080818 - H31 45.232347 44.460552 38.784452 - H41 44.259173 45.284881 40.911338 - H51 41.826951 45.051078 41.335159 - H61 40.367904 43.992946 39.632096 - C1 33.399640 53.402375 14.325407 - C2 32.095265 52.901287 14.411247 - C3 31.622685 52.009869 13.440715 - C4 32.454480 51.619538 12.384342 - C5 33.758278 52.121345 12.298115 - C6 34.230858 53.012763 13.268647 - H11 33.763926 54.090187 15.073753 - H21 31.453618 53.201860 15.226530 - H31 30.616752 51.622629 13.507651 - H41 32.089616 50.932445 11.635609 - H51 34.399924 51.820772 11.482832 - H61 35.237368 53.399284 13.202098 - C1 31.604879 60.065236 53.043048 - C2 30.497332 59.371372 53.544789 - C3 29.621929 60.001810 54.437038 - C4 29.854073 61.326113 54.827546 - C5 30.961981 62.019426 54.326556 - C6 31.837384 61.388988 53.434307 - H11 32.280217 59.578820 52.355202 - H21 30.317759 58.349858 53.243121 - H31 28.767018 59.466712 54.823216 - H41 29.179096 61.811978 55.516143 - H51 31.141554 63.040940 54.628224 - H61 32.691934 61.924636 53.047377 - C1 21.557257 19.182298 43.906479 - C2 20.906102 20.305437 44.430319 - C3 19.695596 20.735513 43.873901 - C4 19.136245 20.042451 42.793644 - C5 19.787864 18.920095 42.269388 - C6 20.998370 18.490019 42.825806 - H11 22.491062 18.850885 44.335416 - H21 21.337212 20.839876 45.264141 - H31 19.192900 21.601366 44.278787 - H41 18.202903 20.374647 42.364292 - H51 19.356753 18.385655 41.435566 - H61 21.500601 17.623383 42.421336 - C1 47.281679 17.985834 63.256937 - C2 48.596896 18.312349 63.608282 - C3 49.587380 17.322989 63.608649 - C4 49.262647 16.007114 63.257671 - C5 47.947436 15.680598 62.907326 - C6 46.956952 16.669958 62.906960 - H11 46.517729 18.748851 63.257053 - H21 48.847709 19.327642 63.878492 - H31 50.602142 17.575266 63.878743 - H41 50.026602 15.244097 63.258555 - H51 47.696623 14.665305 62.637117 - H61 45.942183 16.417682 62.635866 - C1 39.540343 48.434226 41.302974 - C2 40.287495 49.212786 40.411089 - C3 41.686059 49.154203 40.432999 - C4 42.337469 48.317060 41.346792 - C5 41.590353 47.539406 42.239096 - C6 40.191790 47.597989 42.217187 - H11 38.461704 48.479750 41.286287 - H21 39.785054 49.858234 39.705617 - H31 42.262256 49.754127 39.744213 - H41 43.416145 48.272443 41.363899 - H51 42.092795 46.893959 42.944568 - H61 39.615556 46.997159 42.905553 - C1 56.163218 27.753557 53.631537 - C2 56.685938 28.860115 54.311348 - C3 58.059617 28.937792 54.569928 - C4 58.910576 27.908910 54.148697 - C5 58.387689 26.802160 53.469854 - C6 57.014010 26.724483 53.211274 - H11 55.103695 27.693525 53.432483 - H21 56.029626 29.654278 54.635850 - H31 58.462827 29.791986 55.093484 - H41 59.969932 27.968751 54.348719 - H51 59.044002 26.007998 53.145352 - H61 56.610967 25.870481 52.686750 - C1 4.836105 75.922636 71.000881 - C2 4.859251 77.135022 71.700478 - C3 4.543973 78.329359 71.041654 - C4 4.205550 78.311310 69.683233 - C5 4.183367 77.099193 68.983651 - C6 4.498645 75.904856 69.642476 - H11 5.079657 75.001580 71.508968 - H21 5.119729 77.149029 72.748665 - H31 4.560900 79.264422 71.581754 - H41 3.962961 79.232635 69.175161 - H51 3.922889 77.085186 67.935464 - H61 4.480755 74.969524 69.102360 - C1 33.924233 24.241700 62.107512 - C2 34.342948 25.402466 62.768687 - C3 35.022642 26.402927 62.063716 - C4 35.283622 26.242622 60.697569 - C5 34.865762 25.081600 60.036846 - C6 34.186068 24.081139 60.741817 - H11 33.400364 23.469954 62.651372 - H21 34.141129 25.526557 63.822543 - H31 35.344692 27.298764 62.573712 - H41 35.808346 27.014112 60.154161 - H51 35.067581 24.957509 58.982990 - H61 33.863163 23.185558 60.231370 - C1 16.890544 65.991037 20.983917 - C2 17.087044 64.947744 20.071350 - C3 17.702061 65.201817 18.839648 - C4 18.120580 66.499183 18.520512 - C5 17.923201 67.542374 19.432614 - C6 17.308184 67.288301 20.664316 - H11 16.415848 65.795087 21.933697 - H21 16.764763 63.946645 20.317679 - H31 17.854476 64.396669 18.136197 - H41 18.594397 66.695031 17.570267 - H51 18.245483 68.543472 19.186285 - H61 17.156648 68.093551 21.368233 - C1 45.344571 46.394896 60.820699 - C2 44.367407 47.292617 61.266904 - C3 44.742853 48.549051 61.757114 - C4 46.095463 48.907763 61.801119 - C5 47.072414 48.009748 61.355845 - C6 46.696968 46.753315 60.865635 - H11 45.054966 45.425730 60.442997 - H21 43.323773 47.016245 61.232442 - H31 43.988825 49.241846 62.100353 - H41 46.384856 49.876636 62.179752 - H51 48.116048 48.286120 61.390308 - H61 47.451209 46.060814 60.521464 - C1 70.490598 60.900385 16.952376 - C2 71.683631 61.291560 16.333098 - C3 71.757441 61.360661 14.936793 - C4 70.638217 61.038587 14.159766 - C5 69.445747 60.646587 14.779028 - C6 69.371937 60.577486 16.175333 - H11 70.433857 60.846734 18.029277 - H21 72.547020 61.540666 16.932469 - H31 72.677571 61.663418 14.459263 - H41 70.695521 61.091412 13.082849 - H51 68.582358 60.397480 14.179657 - H61 68.451244 60.275554 16.652879 - C1 30.918878 44.032873 64.181918 - C2 30.040047 43.302916 63.372801 - C3 28.829801 43.873800 62.961356 - C4 28.498386 45.174640 63.359029 - C5 29.376717 45.904005 64.168779 - C6 30.586963 45.333121 64.580223 - H11 31.852095 43.592372 64.499534 - H21 30.295880 42.299523 63.065405 - H31 28.152417 43.310907 62.336344 - H41 27.564669 45.614549 63.042045 - H51 29.120884 46.907398 64.476174 - H61 31.264847 45.896605 65.204603 - C1 21.021822 50.162047 5.303626 - C2 20.405023 51.379978 5.613551 - C3 21.128920 52.574658 5.520787 - C4 22.469616 52.551406 5.118097 - C5 23.086452 51.333535 4.809169 - C6 22.362556 50.138855 4.901934 - H11 20.463567 49.240641 5.375569 - H21 19.370495 51.398137 5.923651 - H31 20.652647 53.514223 5.758943 - H41 23.027909 53.472872 5.047151 - H51 24.120981 51.315376 4.499070 - H61 22.838791 49.199230 4.662780 - C1 28.399572 27.457107 24.347976 - C2 27.977747 28.179488 23.225443 - C3 27.724725 29.552331 23.331148 - C4 27.893528 30.202792 24.559386 - C5 28.314369 29.480240 25.681859 - C6 28.567392 28.107397 25.576154 - H11 28.594323 26.398219 24.266473 - H21 27.848064 27.677909 22.277634 - H31 27.400290 30.109639 22.464842 - H41 27.697794 31.261509 24.640828 - H51 28.444053 29.981819 26.629668 - H61 28.892810 27.550260 26.442520 - C1 2.534110 6.580821 55.321587 - C2 3.871401 6.560078 55.735197 - C3 4.893177 6.817045 54.813333 - C4 4.577661 7.094755 53.477859 - C5 3.240623 7.114531 53.064252 - C6 2.218847 6.857563 53.986116 - H11 1.746128 6.382239 56.032547 - H21 4.114947 6.346445 56.765628 - H31 5.924704 6.801994 55.132804 - H41 5.365896 7.292370 52.766902 - H51 2.997077 7.328164 52.033821 - H61 1.187067 6.873582 53.666642 - C1 3.802660 8.599062 58.517529 - C2 5.056441 8.667233 59.136589 - C3 6.115022 9.328497 58.502533 - C4 5.919822 9.921591 57.249417 - C5 4.666474 9.852542 56.630154 - C6 3.607894 9.191278 57.264210 - H11 2.986371 8.088705 59.006427 - H21 5.207026 8.210235 60.103656 - H31 7.081896 9.381857 58.980702 - H41 6.736545 10.431071 56.760317 - H51 4.515890 10.309540 55.663087 - H61 2.640586 9.138796 56.786243 - C1 58.216416 73.808730 68.566555 - C2 58.650855 72.893950 69.533143 - C3 57.738845 72.359804 70.451193 - C4 56.392395 72.740438 70.402655 - C5 55.958350 73.655780 69.436795 - C6 56.870361 74.189927 68.518745 - H11 58.919937 74.220954 67.858782 - H21 59.689503 72.599724 69.570322 - H31 58.073971 71.653354 71.196146 - H41 55.689268 72.328776 71.111156 - H51 54.919702 73.950007 69.399615 - H61 56.534840 74.895815 67.773065 - C1 49.579213 74.198356 75.612850 - C2 49.670263 74.538754 74.257974 - C3 50.905191 74.474566 73.601679 - C4 52.049070 74.069980 74.300261 - C5 51.958071 73.730580 75.655127 - C6 50.723143 73.794768 76.311421 - H11 48.626808 74.248259 76.119061 - H21 48.787723 74.850322 73.718724 - H31 50.975057 74.736231 72.556219 - H41 53.001526 74.021075 73.794040 - H51 52.840611 73.419012 76.194377 - H61 50.653225 73.532104 77.356892 - C1 35.774794 37.238951 6.309901 - C2 37.096493 36.941091 5.957421 - C3 38.118277 37.856877 6.235240 - C4 37.818362 39.070524 6.865540 - C5 36.496728 39.368614 7.217049 - C6 35.474944 38.452828 6.939229 - H11 34.986729 36.532770 6.095249 - H21 37.328122 36.004526 5.471690 - H31 39.137971 37.626493 5.964161 - H41 38.606492 39.776935 7.079221 - H51 36.265099 40.305179 7.702780 - H61 34.455185 38.682982 7.211279 - C1 53.363427 63.852088 26.607486 - C2 52.858849 62.921812 27.523913 - C3 53.736762 62.177700 28.321069 - C4 55.119253 62.363865 28.201798 - C5 55.623639 63.293325 27.284828 - C6 54.745726 64.037436 26.487672 - H11 52.686290 64.425675 25.992428 - H21 51.792248 62.778517 27.616480 - H31 53.347298 61.460818 29.028695 - H41 55.796199 61.789461 28.816313 - H51 56.690241 63.436620 27.192261 - H61 55.135382 64.755136 25.780589 - C1 39.272952 57.007287 77.920404 - C2 40.634983 57.194215 78.184566 - C3 41.340371 56.242230 78.930251 - C4 40.683727 55.103319 79.411773 - C5 39.321723 54.917015 79.148392 - C6 38.616336 55.869000 78.402707 - H11 38.728886 57.741743 77.345617 - H21 41.141868 58.072541 77.812610 - H31 42.391322 56.386101 79.133082 - H41 41.227820 54.369487 79.987341 - H51 38.814839 54.038689 79.520348 - H61 37.565358 55.724505 78.199095 - C1 22.767189 68.938635 36.216157 - C2 22.244204 69.253675 34.956360 - C3 20.911521 69.664824 34.834684 - C4 20.101824 69.760931 35.972803 - C5 20.624568 69.445009 37.232194 - C6 21.957251 69.033861 37.353871 - H11 23.794925 68.621164 36.309882 - H21 22.868947 69.180168 34.078275 - H31 20.508528 69.908786 33.862873 - H41 19.073847 70.077520 35.878672 - H51 19.999825 69.518517 38.110279 - H61 22.360484 68.790780 38.326087 - C1 47.939961 58.668974 22.283362 - C2 48.851264 59.321315 21.444418 - C3 50.203800 59.389997 21.799132 - C4 50.645031 58.806337 22.992790 - C5 49.733627 58.154967 23.831952 - C6 48.381091 58.086285 23.477238 - H11 46.896756 58.616379 22.009918 - H21 48.511104 59.771126 20.523167 - H31 50.906844 59.892403 21.151325 - H41 51.688135 58.859903 23.266451 - H51 50.073787 57.705156 24.753202 - H61 47.678148 57.582908 24.124827 - C1 7.514701 67.860694 75.334604 - C2 6.598187 67.610485 76.362829 - C3 5.642099 66.598271 76.217195 - C4 5.602526 65.836266 75.043335 - C5 6.518324 66.087162 74.014988 - C6 7.474412 67.099376 74.160622 - H11 8.251813 68.641646 75.446829 - H21 6.628990 68.197887 77.268782 - H31 4.935790 66.404721 77.010923 - H41 4.864698 65.056001 74.930988 - H51 6.487521 65.499760 73.109035 - H61 8.181437 67.292239 73.367016 - C1 69.731390 58.191733 10.643892 - C2 69.602137 56.847823 10.273691 - C3 70.724974 56.011690 10.270367 - C4 71.977063 56.519468 10.637244 - C5 72.106324 57.863386 11.006446 - C6 70.983487 58.699518 11.009770 - H11 68.865425 58.836648 10.646058 - H21 68.636093 56.455772 9.991210 - H31 70.624893 54.974724 9.985721 - H41 72.843036 55.874560 10.634079 - H51 73.072368 58.255436 11.288926 - H61 71.083559 59.736477 11.295416 - C1 12.640894 53.229744 18.969565 - C2 12.937187 52.153887 19.814902 - C3 13.881674 52.306354 20.836953 - C4 14.529868 53.534678 21.013668 - C5 14.234229 54.609978 20.167818 - C6 13.289741 54.457511 19.145767 - H11 11.912728 53.111970 18.181074 - H21 12.436730 51.206346 19.679076 - H31 14.109382 51.476587 21.489619 - H41 15.258687 53.651896 21.801646 - H51 14.734686 55.557520 20.303644 - H61 13.061380 55.287835 18.493615 - C1 69.115319 47.330280 11.470295 - C2 69.757526 46.307938 12.178983 - C3 70.933427 46.579943 12.888321 - C4 71.467121 47.874291 12.888972 - C5 70.825447 48.896141 12.179598 - C6 69.649547 48.624135 11.470259 - H11 68.208615 47.120338 10.922914 - H21 69.345560 45.309427 12.179078 - H31 71.428164 45.791374 13.435798 - H41 72.374359 48.083741 13.435667 - H51 71.237414 49.894652 12.179502 - H61 69.154275 49.413196 10.923470 - C1 48.159230 19.424629 37.180055 - C2 47.499103 19.084035 38.366680 - C3 47.745988 17.847447 38.974783 - C4 48.652999 16.951453 38.396261 - C5 49.312228 17.291718 37.209344 - C6 49.065343 18.528307 36.601241 - H11 47.968479 20.378210 36.710895 - H21 46.799771 19.775454 38.813463 - H31 47.237406 17.585285 39.890727 - H41 48.842852 15.997544 38.865130 - H51 50.011561 16.600300 36.762561 - H61 49.574824 18.790797 35.685589 - C1 55.722026 52.518840 76.408589 - C2 55.919722 52.462272 75.023827 - C3 56.133735 51.228801 74.397218 - C4 56.150053 50.051898 75.155372 - C5 55.953322 50.108694 76.540004 - C6 55.739309 51.342165 77.166612 - H11 55.557361 53.470235 76.891856 - H21 55.906546 53.370115 74.438687 - H31 56.285224 51.185249 73.328812 - H41 56.315682 49.100731 74.671975 - H51 55.966498 49.200851 77.125143 - H61 55.586855 51.385489 78.235149 - C1 48.846132 30.008624 17.283436 - C2 48.080387 31.122731 16.919771 - C3 46.685084 31.024304 16.862021 - C4 46.055527 29.811769 17.167935 - C5 46.821308 28.697683 17.530600 - C6 48.216610 28.796110 17.588350 - H11 49.922286 30.084497 17.327577 - H21 48.565917 32.058448 16.684326 - H31 46.094460 31.884148 16.582435 - H41 44.979408 29.735916 17.122794 - H51 46.335777 27.761966 17.766044 - H61 48.807199 27.936246 17.868935 - C1 47.761644 67.871490 16.066984 - C2 47.079300 66.718706 16.473611 - C3 45.679582 66.705119 16.495837 - C4 44.962207 67.844318 16.111436 - C5 45.644561 68.997137 15.705808 - C6 47.044280 69.010724 15.683583 - H11 48.841192 67.882030 16.050240 - H21 47.632618 65.839524 16.769620 - H31 45.153352 65.815398 16.808590 - H41 43.882670 67.833813 16.129180 - H51 45.091244 69.876319 15.409800 - H61 47.570500 69.900410 15.369830 - C1 34.802252 68.284974 48.575480 - C2 33.545950 68.294501 47.957853 - C3 32.840484 67.097274 47.787981 - C4 33.391321 65.890519 48.235737 - C5 34.647820 65.881009 48.852384 - C6 35.353285 67.078236 49.022256 - H11 35.346466 69.208326 48.706112 - H21 33.120574 69.225527 47.612907 - H31 31.870894 67.104947 47.312404 - H41 32.847303 64.967184 48.104125 - H51 35.073196 64.949983 49.197330 - H61 36.322679 67.070546 49.498813 - C1 16.191619 25.092838 34.494567 - C2 15.675703 24.155041 33.592225 - C3 14.297273 24.097265 33.354563 - C4 13.434758 24.977285 34.019242 - C5 13.950615 25.914230 34.922104 - C6 15.329045 25.972006 35.159767 - H11 17.254712 25.137084 34.678113 - H21 16.341079 23.476444 33.078882 - H31 13.899556 23.374422 32.657672 - H41 12.371606 24.932188 33.836216 - H51 13.285239 26.592827 35.435448 - H61 15.726821 26.695701 35.856136 - C1 8.334510 22.371804 54.889749 - C2 7.871848 21.051743 54.946628 - C3 8.712517 20.035059 55.415158 - C4 10.015847 20.338435 55.826809 - C5 10.478614 21.658147 55.768998 - C6 9.637946 22.674831 55.300468 - H11 7.686218 23.155818 54.528014 - H21 6.866136 20.817630 54.629650 - H31 8.355097 19.016931 55.459915 - H41 10.664245 19.554071 56.187612 - H51 11.484326 21.892260 56.085976 - H61 9.995260 23.693308 55.256643 - C1 3.244292 9.640680 47.988626 - C2 2.990775 10.973556 48.333621 - C3 4.051286 11.823296 48.669996 - C4 5.365314 11.340160 48.661376 - C5 5.618558 10.007253 48.317343 - C6 4.558046 9.157512 47.980968 - H11 2.426284 8.985261 47.729584 - H21 1.977101 11.346608 48.339718 - H31 3.855620 12.851768 48.935135 - H41 6.183049 11.995548 48.921379 - H51 6.632232 9.634201 48.311246 - H61 4.753986 8.129073 47.714868 - C1 9.299047 4.083580 41.555745 - C2 10.201745 3.737336 42.568218 - C3 10.813492 2.478135 42.559896 - C4 10.522540 1.565177 41.539103 - C5 9.619268 1.911133 40.527396 - C6 9.007521 3.170334 40.535718 - H11 8.826971 5.054618 41.562437 - H21 10.426785 4.441815 43.355496 - H31 11.510607 2.211576 43.340482 - H41 10.994042 0.593851 41.533177 - H51 9.394228 1.206653 39.740118 - H61 8.310979 3.437181 39.754365 - C1 19.477278 61.759726 54.629163 - C2 18.342017 61.349386 55.338145 - C3 17.067542 61.723686 54.895986 - C4 16.928328 62.508327 53.744847 - C5 18.063511 62.919315 53.036622 - C6 19.337986 62.545015 53.478781 - H11 20.460215 61.471337 54.970456 - H21 18.449233 60.743511 56.225929 - H31 16.191821 61.406200 55.442478 - H41 15.945313 62.797364 53.404311 - H51 17.956294 63.525190 52.148838 - H61 20.213784 62.861853 52.931532 - C1 77.288769 64.094196 31.040583 - C2 76.169647 63.962655 31.871315 - C3 75.457192 65.099566 32.270980 - C4 75.863858 66.368017 31.839914 - C5 76.983354 66.499474 31.010106 - C6 77.695810 65.362564 30.610441 - H11 77.838442 63.217340 30.732694 - H21 75.855415 62.984047 32.203465 - H31 74.593287 64.997814 32.911020 - H41 75.314559 67.244790 32.148727 - H51 77.297586 67.478083 30.677956 - H61 78.559340 65.464400 29.969477 - C1 9.923175 23.295118 3.589397 - C2 9.347323 24.458532 3.065268 - C3 8.102483 24.895519 3.533572 - C4 7.433497 24.169092 4.526006 - C5 8.008921 23.005388 5.049279 - C6 9.253760 22.568401 4.580975 - H11 10.883088 22.957930 3.227891 - H21 9.863616 25.019420 2.300032 - H31 7.658865 25.793596 3.129842 - H41 6.473156 24.505990 4.886656 - H51 7.492627 22.444500 5.814515 - H61 9.697808 21.670614 4.985561 - C1 75.910475 17.106200 76.986813 - C2 75.193619 16.870332 75.807688 - C3 75.036362 15.562368 75.333988 - C4 75.595960 14.490272 76.039413 - C5 76.313466 14.726324 77.217802 - C6 76.470724 16.034287 77.691501 - H11 76.032056 18.115036 77.351892 - H21 74.761302 17.697306 75.263668 - H31 74.482464 15.380506 74.424890 - H41 75.475029 13.481620 75.673598 - H51 76.745783 13.899350 77.761821 - H61 77.023971 16.215966 78.601337 - C1 33.974128 71.593254 62.756540 - C2 32.833281 72.128303 63.366491 - C3 32.661440 72.014557 64.751201 - C4 33.630448 71.365761 65.525961 - C5 34.770584 70.830024 64.915870 - C6 34.942424 70.943771 63.531160 - H11 34.106410 71.680673 61.688517 - H21 32.085894 72.629423 62.768968 - H31 31.781772 72.428258 65.221702 - H41 33.497454 71.277654 66.593844 - H51 35.517971 70.328904 65.513393 - H61 35.822805 70.530758 63.060799 - C1 18.876598 51.646165 26.656781 - C2 18.325631 51.501319 25.377990 - C3 17.067426 50.907851 25.221124 - C4 16.360188 50.459229 26.343050 - C5 16.911584 50.603252 27.621468 - C6 18.169789 51.196720 27.778334 - H11 19.847172 52.103535 26.777660 - H21 18.870883 51.847945 24.512373 - H31 16.642103 50.797106 24.234629 - H41 15.390042 50.001036 26.221798 - H51 16.366332 50.256626 28.487085 - H61 18.594682 51.308288 28.765202 - C1 2.257962 31.783602 75.287983 - C2 3.614807 31.811041 75.631599 - C3 4.430131 30.707982 75.351601 - C4 3.888610 29.577484 74.727988 - C5 2.531790 29.549810 74.385343 - C6 1.716466 30.652869 74.665341 - H11 1.629108 32.634224 75.504315 - H21 4.032873 32.683402 76.112170 - H31 5.477051 30.729722 75.615840 - H41 4.517488 28.726627 74.512627 - H51 2.113723 28.677449 73.904772 - H61 0.669522 30.631365 74.400130 - C1 38.195204 27.389115 73.245481 - C2 36.809311 27.517224 73.396273 - C3 36.044609 26.416553 73.800803 - C4 36.665801 25.187772 74.054540 - C5 38.051326 25.059572 73.902822 - C6 38.816028 26.160243 73.498292 - H11 38.784875 28.237951 72.933103 - H21 36.329995 28.465339 73.201145 - H31 34.975622 26.515832 73.918052 - H41 36.075761 24.338845 74.365992 - H51 38.530642 24.111457 74.097951 - H61 39.885383 26.061055 73.381969 - C1 39.816510 65.282451 61.990685 - C2 41.159660 65.212124 62.379082 - C3 41.822033 63.978804 62.387799 - C4 41.141256 62.815813 62.008119 - C5 39.798083 62.886130 61.620723 - C6 39.135710 64.119449 61.612005 - H11 39.305598 66.233631 61.984359 - H21 41.685192 66.109387 62.671443 - H31 42.858477 63.924888 62.686486 - H41 41.652145 61.864622 62.015445 - H51 39.272551 61.988866 61.328361 - H61 38.099288 64.173376 61.312318 - C1 53.852729 74.558168 79.814099 - C2 52.597125 75.133422 79.585207 - C3 51.484531 74.315944 79.353356 - C4 51.627541 72.923212 79.350396 - C5 52.883152 72.348213 79.578321 - C6 53.995747 73.165691 79.810173 - H11 54.710858 75.188719 79.992521 - H21 52.486519 76.207898 79.588072 - H31 50.515796 74.759870 79.177798 - H41 50.769420 72.292917 79.171007 - H51 52.993758 71.273737 79.575457 - H61 54.964474 72.721510 79.986698 - C1 20.528451 50.668154 36.476923 - C2 20.633319 50.540741 37.867110 - C3 21.634471 49.735083 38.422538 - C4 22.530755 49.056837 37.587780 - C5 22.425203 49.183562 36.197840 - C6 21.424052 49.989220 35.642411 - H11 19.756039 51.289228 36.048601 - H21 19.942285 51.064442 38.511277 - H31 21.715849 49.637709 39.495028 - H41 23.302484 48.435075 38.016349 - H51 23.116237 48.659861 35.553673 - H61 21.343356 50.087282 34.569676 - C1 39.884594 46.779280 45.707693 - C2 39.855486 45.513086 45.111240 - C3 38.660554 45.019893 44.573849 - C4 37.494730 45.792893 44.632911 - C5 37.523754 47.058446 45.230128 - C6 38.718686 47.551639 45.767519 - H11 40.806137 47.159435 46.122489 - H21 40.754991 44.916849 45.065049 - H31 38.638517 44.043500 44.112862 - H41 36.573104 45.412097 44.218878 - H51 36.624249 47.654683 45.276319 - H61 38.740808 48.528673 46.227742 - C1 14.347531 78.137420 72.241668 - C2 15.106784 78.946979 71.388438 - C3 16.403010 78.560781 71.027135 - C4 16.939984 77.365025 71.519061 - C5 16.181113 76.556177 72.372884 - C6 14.884887 76.942374 72.734187 - H11 13.347960 78.435530 72.520599 - H21 14.692411 79.869238 71.008341 - H31 16.988208 79.184931 70.368107 - H41 17.939937 77.067625 71.240723 - H51 16.595486 75.633918 72.752981 - H61 14.299307 76.317515 73.392623 - C1 8.826853 32.351552 77.329061 - C2 7.764466 32.780102 76.524367 - C3 7.380214 34.126281 76.531004 - C4 8.058348 35.043909 77.342334 - C5 9.119910 34.615127 78.147544 - C6 9.504163 33.268948 78.140908 - H11 9.122906 31.313215 77.324189 - H21 7.241584 32.072375 75.897903 - H31 6.561278 34.456891 75.909411 - H41 7.761471 36.082013 77.347722 - H51 9.642793 35.322854 78.774009 - H61 10.323922 32.938571 78.761984 - C1 7.627575 68.568432 4.676913 - C2 8.982856 68.525894 4.328698 - C3 9.543463 69.560644 3.570474 - C4 8.748789 70.637932 3.160466 - C5 7.393548 70.679869 3.507882 - C6 6.832941 69.645119 4.266105 - H11 7.195175 67.770148 5.261367 - H21 9.596224 67.695127 4.645474 - H31 10.589231 69.528161 3.302796 - H41 9.181230 71.435615 2.575213 - H51 6.780180 71.510636 3.191106 - H61 5.787132 69.678203 4.534582 - C1 24.159422 73.785873 60.328352 - C2 22.771092 73.665581 60.194482 - C3 21.972462 74.813388 60.126510 - C4 22.562162 76.081487 60.192410 - C5 23.950159 76.201608 60.327207 - C6 24.748789 75.053801 60.395179 - H11 24.775275 72.900576 60.381163 - H21 22.316050 72.687303 60.143007 - H31 20.901567 74.720407 60.022225 - H41 21.945977 76.966613 60.140526 - H51 24.405201 77.179886 60.378682 - H61 25.820017 75.146953 60.498537 - C1 50.190881 17.690601 70.635851 - C2 49.580104 16.599663 70.006045 - C3 48.728603 15.758839 70.732579 - C4 48.487878 16.008953 72.088919 - C5 49.099352 17.099175 72.718722 - C6 49.950853 17.939999 71.992188 - H11 50.847903 18.338824 70.075546 - H21 49.765245 16.406930 68.959471 - H31 48.256721 14.917883 70.246310 - H41 47.831552 15.360013 72.649221 - H51 48.914211 17.291907 73.765296 - H61 50.422038 18.781672 72.478460 - C1 45.454972 39.774691 62.686602 - C2 45.538201 38.442484 62.264528 - C3 46.196398 37.496366 63.059217 - C4 46.771366 37.882457 64.275979 - C5 46.688900 39.214648 64.697408 - C6 46.030703 40.160765 63.902719 - H11 44.947659 40.504420 62.073459 - H21 45.094123 38.144336 61.326102 - H31 46.259633 36.468490 62.733934 - H41 47.279443 37.152711 64.888477 - H51 47.132979 39.512795 65.635834 - H61 45.966705 41.188658 64.228647 - C1 32.932766 75.947525 73.322448 - C2 34.322763 76.020059 73.172448 - C3 34.873833 76.490387 71.974531 - C4 34.034907 76.888181 70.926615 - C5 32.645191 76.814718 71.076375 - C6 32.094121 76.344389 72.274291 - H11 32.507819 75.584403 74.246232 - H21 34.970123 75.713773 73.981061 - H31 35.946140 76.547223 71.859360 - H41 34.460135 77.250373 70.002590 - H51 31.997831 77.121003 70.267762 - H61 31.021533 76.288483 72.389704 - C1 32.341923 39.248954 46.154709 - C2 32.272056 37.871150 46.392672 - C3 31.072835 37.182946 46.173280 - C4 29.943479 37.872545 45.715924 - C5 30.013207 39.250266 45.478948 - C6 31.212429 39.938470 45.698340 - H11 33.266753 39.779745 46.324310 - H21 33.143452 37.338873 46.744938 - H31 31.019400 36.119877 46.355944 - H41 29.018511 37.341670 45.547310 - H51 29.141812 39.782543 45.126682 - H61 31.266002 41.001622 45.514689 - C1 62.484066 4.307450 30.925730 - C2 61.408771 4.191100 30.036880 - C3 60.293306 5.025737 30.174761 - C4 60.253136 5.976723 31.201491 - C5 61.327893 6.092305 32.090688 - C6 62.443358 5.257669 31.952808 - H11 63.344175 3.663435 30.819572 - H21 61.439885 3.457871 29.244323 - H31 59.464310 4.936522 29.488361 - H41 59.392488 6.619970 31.307996 - H51 61.296779 6.825535 32.883245 - H61 63.272892 5.347651 32.638859 - C1 53.847601 2.540910 26.160109 - C2 55.019480 2.716150 25.414560 - C3 55.530031 4.002789 25.205299 - C4 54.868704 5.114187 25.741588 - C5 53.696529 4.938914 26.486182 - C6 53.185978 3.652275 26.695442 - H11 53.453675 1.548586 26.321134 - H21 55.530148 1.858743 25.001266 - H31 56.434626 4.137705 24.630980 - H41 55.262334 6.106478 25.579607 - H51 53.185861 5.796321 26.899475 - H61 52.281679 3.517391 27.270716 - C1 20.777886 46.462688 40.527701 - C2 21.616092 45.360180 40.731997 - C3 21.109405 44.061817 40.600042 - C4 19.764511 43.865962 40.263790 - C5 18.926335 44.968352 40.060487 - C6 19.433022 46.266715 40.192442 - H11 21.168640 47.464031 40.629872 - H21 22.653862 45.511130 40.990819 - H31 21.756421 43.211424 40.756693 - H41 19.373788 42.864502 40.162612 - H51 17.888565 44.817402 39.801665 - H61 18.785976 47.117226 40.034799 - C1 12.936730 51.983868 41.562177 - C2 13.814800 53.052006 41.781089 - C3 15.196111 52.858343 41.661227 - C4 15.699350 51.596540 41.322452 - C5 14.821378 50.528453 41.104534 - C6 13.440068 50.722117 41.224396 - H11 11.871417 52.133205 41.655022 - H21 13.426663 54.025705 42.041860 - H31 15.873286 53.682703 41.829153 - H41 16.764762 51.447254 41.230601 - H51 15.209516 49.554754 40.843763 - H61 12.762794 49.897704 41.055476 - C1 17.002868 61.136811 9.593658 - C2 18.368066 61.424895 9.708085 - C3 19.237665 60.482127 10.269224 - C4 18.742066 59.251276 10.715937 - C5 17.376945 58.963749 10.602337 - C6 16.507346 59.906516 10.041198 - H11 16.332176 61.864127 9.161224 - H21 18.750670 62.374220 9.362923 - H31 20.290961 60.704137 10.356496 - H41 19.412834 58.524517 11.149199 - H51 16.994341 58.014423 10.947499 - H61 15.453973 59.683950 9.953098 - C1 66.980413 37.286297 30.107572 - C2 65.893880 38.002666 30.623434 - C3 65.715585 39.347871 30.279161 - C4 66.623822 39.976708 29.419025 - C5 67.710643 39.260618 28.904079 - C6 67.888938 37.915412 29.248352 - H11 67.118084 36.248910 30.373445 - H21 65.192739 37.517477 31.286558 - H31 64.876772 39.900069 30.676411 - H41 66.486438 41.014373 29.154068 - H51 68.411784 39.745807 28.240955 - H61 68.727463 37.362937 28.850186 - C1 43.851099 53.377295 65.404455 - C2 43.812985 52.042297 64.984719 - C3 44.955770 51.241154 65.094735 - C4 46.136670 51.775010 65.624487 - C5 46.174913 53.110047 66.043233 - C6 45.032128 53.911189 65.933217 - H11 42.969796 53.995236 65.319215 - H21 42.901806 51.630108 64.576560 - H31 44.925894 50.211024 64.771817 - H41 47.018103 51.157107 65.708737 - H51 47.086093 53.522235 66.451392 - H61 45.061875 54.941281 66.257126 - C1 3.701299 37.918010 8.634022 - C2 2.431770 37.516330 8.201817 - C3 1.768421 36.470786 8.855038 - C4 2.374601 35.826922 9.940464 - C5 3.644303 36.227998 10.371889 - C6 4.307652 37.273542 9.718668 - H11 4.213022 38.724139 8.129930 - H21 1.963707 38.013392 7.364806 - H31 0.788636 36.161719 8.522119 - H41 1.863051 35.020190 10.443777 - H51 4.112365 35.730937 11.208901 - H61 5.287264 37.583213 10.052367 - C1 10.774699 19.157968 48.376860 - C2 10.384435 18.567819 47.168858 - C3 10.854420 17.293831 46.828326 - C4 11.714668 16.609994 47.695796 - C5 12.105535 17.200545 48.903110 - C6 11.635550 18.474532 49.243642 - H11 10.412495 20.140705 48.639256 - H21 9.720261 19.095026 46.499780 - H31 10.552449 16.838303 45.896852 - H41 12.077475 15.627659 47.432711 - H51 12.769709 16.673337 49.572188 - H61 11.936917 18.929660 50.175804 - C1 75.265676 76.881054 52.842322 - C2 74.628463 77.751224 53.734855 - C3 73.735628 77.246184 54.687574 - C4 73.480007 75.870975 54.747759 - C5 74.116450 75.001182 53.854711 - C6 75.009284 75.506222 52.901992 - H11 75.953971 77.270679 52.107300 - H21 74.826046 78.812164 53.688945 - H31 73.244917 77.917499 55.376685 - H41 72.790942 75.481727 55.482265 - H51 73.918866 73.940242 53.900620 - H61 75.500766 74.834530 52.213395 - C1 11.851791 49.614216 51.783968 - C2 11.926956 50.893060 52.348555 - C3 10.962581 51.306789 53.275216 - C4 9.923042 50.441674 53.637290 - C5 9.847472 49.163436 53.072019 - C6 10.811847 48.749707 52.145357 - H11 12.595382 49.295330 51.068986 - H21 12.729261 51.560390 52.069773 - H31 11.021295 52.293004 53.711415 - H41 9.179047 50.761166 54.351587 - H51 9.045168 48.496107 53.350801 - H61 10.753538 47.762886 51.709842 - C1 35.596455 33.430015 53.846758 - C2 35.327719 33.994804 52.594302 - C3 34.108681 34.644374 52.366494 - C4 33.158379 34.729156 53.391142 - C5 33.426808 34.163602 54.643032 - C6 34.645846 33.514032 54.870840 - H11 36.536506 32.928703 54.022270 - H21 36.061039 33.930011 51.803869 - H31 33.901950 35.080894 51.400549 - H41 32.218021 35.229703 53.215064 - H51 32.693488 34.228394 55.433465 - H61 34.852884 33.078277 55.837351 - C1 29.905010 55.748659 1.505518 - C2 29.093569 54.619062 1.346066 - C3 29.109442 53.604178 2.310249 - C4 29.936756 53.718891 3.433885 - C5 30.748703 54.847895 3.592712 - C6 30.732830 55.862779 2.628528 - H11 29.893011 56.531177 0.761653 - H21 28.454778 54.530706 0.479533 - H31 28.482650 52.733304 2.187582 - H41 29.949261 52.935780 4.177125 - H51 31.387494 54.936252 4.459245 - H61 31.359115 56.734246 2.751822 - C1 58.730976 18.735286 12.503408 - C2 58.547090 20.122121 12.451181 - C3 57.994659 20.712322 11.308214 - C4 57.626113 19.915688 10.217474 - C5 57.810894 18.529222 10.269453 - C6 58.363325 17.939021 11.412419 - H11 59.157409 18.280197 13.384805 - H21 58.830809 20.736793 13.292859 - H31 57.851944 21.782084 11.268495 - H41 57.200575 20.371146 9.335828 - H51 57.527175 17.914550 9.427774 - H61 58.505145 16.868891 11.452388 - C1 39.350750 30.539015 36.571059 - C2 40.668757 30.068364 36.536464 - C3 41.315134 29.709319 37.725234 - C4 40.643504 29.820926 38.948599 - C5 39.326063 30.292401 38.983141 - C6 38.679686 30.651445 37.794371 - H11 38.852419 30.816284 35.654215 - H21 41.186844 29.981621 35.592641 - H31 42.331552 29.345308 37.698255 - H41 41.142400 29.544481 39.865390 - H51 38.807976 30.379143 39.926965 - H61 37.662703 31.014633 37.821404 - C1 51.286373 68.307449 39.090517 - C2 50.967874 69.610912 38.691276 - C3 51.987098 70.504062 38.340053 - C4 53.324821 70.093748 38.388071 - C5 53.643180 68.790788 38.788166 - C6 52.623956 67.897638 39.139389 - H11 50.500265 67.618773 39.361763 - H21 49.935819 69.927426 38.653588 - H31 51.741150 71.509252 38.031120 - H41 54.110789 70.782926 38.117679 - H51 54.675235 68.474273 38.825853 - H61 52.870043 66.891946 39.447469 - C1 45.166475 41.009232 72.151657 - C2 46.344637 41.580709 72.646834 - C3 47.474937 40.782099 72.857867 - C4 47.427076 39.412014 72.573723 - C5 46.248776 38.840594 72.079534 - C6 45.118475 39.639203 71.868501 - H11 44.294639 41.625149 71.989289 - H21 46.381902 42.637841 72.865518 - H31 48.384038 41.223315 73.238920 - H41 48.298773 38.796153 72.737079 - H51 46.211510 37.783461 71.860850 - H61 44.209513 39.197931 71.486460 - C1 59.975724 46.805462 40.158970 - C2 58.659000 46.334348 40.223335 - C3 57.737786 46.946578 41.081491 - C4 58.133296 48.029922 41.875281 - C5 59.450059 48.500247 41.811529 - C6 60.371272 47.888017 40.953374 - H11 60.686268 46.332981 39.497380 - H21 58.353552 45.498941 39.610525 - H31 56.721793 46.583652 41.130270 - H41 57.422790 48.501614 42.537484 - H51 59.755507 49.335654 42.424339 - H61 61.387226 48.251732 40.903981 - C1 78.415534 40.128607 77.310164 - C2 77.065905 39.987826 77.654448 - C3 76.218085 41.101647 77.632233 - C4 76.719895 42.356251 77.265734 - C5 78.069512 42.497049 76.922449 - C6 78.917331 41.383227 76.944664 - H11 79.069455 39.269599 77.327696 - H21 76.678471 39.019834 77.936631 - H31 75.176730 40.992663 77.896884 - H41 76.065961 43.215275 77.249201 - H51 78.456946 43.465041 76.640266 - H61 79.958699 41.492194 76.679014 - C1 67.854150 23.856106 77.997120 - C2 67.116434 25.029543 77.800466 - C3 67.766375 26.209022 77.417978 - C4 69.154033 26.215064 77.232145 - C5 69.891617 25.042004 77.429716 - C6 69.241675 23.862525 77.812203 - H11 67.352867 22.946556 78.292495 - H21 66.045759 25.024885 77.943201 - H31 67.196983 27.113914 77.265338 - H41 69.655184 27.124991 76.937686 - H51 70.962292 25.046662 77.286981 - H61 69.811200 22.957256 77.963927 - C1 57.566273 45.221994 67.701897 - C2 57.677832 44.097410 66.875630 - C3 56.860420 42.982590 67.096781 - C4 55.931451 42.992355 68.144199 - C5 55.820674 44.116431 68.970828 - C6 56.638085 45.231251 68.749676 - H11 58.197010 46.081620 67.531521 - H21 58.394065 44.089968 66.067116 - H31 56.945917 42.115522 66.458643 - H41 55.301496 42.132221 68.314937 - H51 55.104441 44.123873 69.779342 - H61 56.551806 46.098826 69.387453 - C1 56.122027 11.238654 49.191552 - C2 56.872432 12.394781 49.436733 - C3 56.224189 13.613011 49.672502 - C4 54.825540 13.675114 49.663090 - C5 54.075407 12.519313 49.417004 - C6 54.723650 11.301083 49.181235 - H11 56.622058 10.299197 49.009334 - H21 57.951499 12.346900 49.444636 - H31 56.803225 14.504587 49.862623 - H41 54.325781 14.614897 49.844402 - H51 52.996340 12.567194 49.409101 - H61 54.144342 10.409181 48.992019 - C1 66.572646 30.834141 20.526408 - C2 65.174829 30.789781 20.463235 - C3 64.432378 31.973436 20.550515 - C4 65.087745 33.201452 20.700968 - C5 66.485271 33.245568 20.765065 - C6 67.227721 32.061912 20.677785 - H11 67.145188 29.921163 20.459479 - H21 64.669093 29.842492 20.346543 - H31 63.354100 31.939126 20.500751 - H41 64.514911 34.114186 20.768821 - H51 66.991006 34.192856 20.881758 - H61 68.306290 32.096467 20.726624 - C1 68.201610 58.855535 52.010869 - C2 68.520495 60.139486 51.553013 - C3 67.545915 61.144515 51.552662 - C4 66.252448 60.865593 52.010167 - C5 65.933495 59.581583 52.467027 - C6 66.908076 58.576554 52.467378 - H11 68.953202 58.080342 52.010747 - H21 69.518542 60.354991 51.200590 - H31 67.792369 62.135212 51.200361 - H41 65.500789 61.640727 52.009293 - H51 64.935449 59.366078 52.819450 - H61 66.661689 57.585915 52.820675 - C1 11.678710 20.699025 71.435605 - C2 12.010628 19.349924 71.263534 - C3 11.080397 18.353952 71.583849 - C4 9.818248 18.707081 72.076235 - C5 9.486860 20.055943 72.249120 - C6 10.417091 21.051914 71.928805 - H11 12.396344 21.467111 71.188910 - H21 12.984126 19.077348 70.883082 - H31 11.336262 17.313289 71.450091 - H41 9.101144 17.938755 72.323744 - H51 8.513361 20.328519 72.629572 - H61 10.160697 22.092817 72.061748 - C1 72.301584 4.851604 21.435050 - C2 72.403280 4.600250 20.061613 - C3 71.244910 4.469353 19.286412 - C4 69.984844 4.589809 19.884649 - C5 69.883299 4.840177 21.258017 - C6 71.041669 4.971075 22.033217 - H11 73.195020 4.952160 22.032941 - H21 73.375368 4.507905 19.599815 - H31 71.323562 4.276451 18.226724 - H41 69.091559 4.488268 19.286688 - H51 68.911211 4.932523 21.719814 - H61 70.962865 5.164963 23.092975 - C1 68.766933 5.347804 3.141368 - C2 68.481768 4.959358 1.826971 - C3 67.611994 5.727050 1.043367 - C4 67.027386 6.883187 1.574161 - C5 67.311844 7.270931 2.888647 - C6 68.181617 6.503240 3.672250 - H11 69.437454 4.755458 3.745803 - H21 68.933205 4.067750 1.417117 - H31 67.392910 5.427788 0.029078 - H41 66.356158 7.474832 0.969814 - H51 66.860407 8.162540 3.298501 - H61 68.401408 6.803204 4.686451 - C1 67.125489 62.477693 64.884730 - C2 66.211355 61.913568 65.782490 - C3 64.913140 61.605711 65.358520 - C4 64.529057 61.861980 64.036789 - C5 65.442831 62.426880 63.139550 - C6 66.741047 62.734737 63.563520 - H11 68.126610 62.715468 65.211889 - H21 66.507723 61.715227 66.802082 - H31 64.208386 61.169596 66.050952 - H41 63.527577 61.624980 63.710151 - H51 65.146464 62.625220 62.119958 - H61 67.446160 63.170077 62.870567 - C1 62.742745 36.731337 70.462036 - C2 63.146542 37.223480 71.708870 - C3 62.492296 38.325927 72.271422 - C4 61.434254 38.936230 71.587140 - C5 61.031250 38.444663 70.340110 - C6 61.685496 37.342217 69.777558 - H11 63.247635 35.881307 70.028043 - H21 63.962412 36.752348 72.237199 - H31 62.803277 38.704825 73.233744 - H41 60.930157 39.786837 72.020937 - H51 60.215380 38.915796 69.811781 - H61 61.373723 36.962742 68.815432 - C1 58.352128 63.526848 42.012852 - C2 58.894938 64.469492 42.894119 - C3 60.223837 64.347966 43.317379 - C4 61.009926 63.283795 42.859373 - C5 60.466806 62.340863 41.979013 - C6 59.137907 62.462389 41.555753 - H11 57.327081 63.620415 41.686756 - H21 58.288771 65.290908 43.247076 - H31 60.642717 65.075814 43.996432 - H41 62.034663 63.189940 43.186375 - H51 61.072973 61.519447 41.626056 - H61 58.719337 61.734829 40.875793 - C1 53.168794 64.326337 9.981384 - C2 52.598650 65.586334 9.764141 - C3 51.588837 65.742000 8.807095 - C4 51.149168 64.637670 8.067292 - C5 51.719953 63.378143 8.283928 - C6 52.729765 63.222476 9.240974 - H11 53.947887 64.206424 10.719251 - H21 52.937325 66.438308 10.335263 - H31 51.148419 66.713887 8.640350 - H41 50.370715 64.758053 7.328818 - H51 51.381277 62.526169 7.712806 - H61 53.169543 62.250119 9.408326 - C1 39.493785 34.563114 19.728196 - C2 40.317522 35.547551 20.286939 - C3 39.886946 36.878973 20.329478 - C4 38.632634 37.225959 19.813275 - C5 37.809542 36.241759 19.253806 - C6 38.240118 34.910337 19.211267 - H11 39.826093 33.536329 19.695065 - H21 41.285003 35.279899 20.685791 - H31 40.522119 37.638106 20.761461 - H41 38.300971 38.252981 19.845679 - H51 36.842061 36.509412 18.854954 - H61 37.604300 34.150967 18.780010 - C1 3.174496 30.752925 42.901568 - C2 1.912062 30.148338 42.925817 - C3 0.977939 30.517397 43.901062 - C4 1.306250 31.491042 44.852057 - C5 2.568824 32.094758 44.828279 - C6 3.502947 31.725700 43.853035 - H11 3.895036 30.467959 42.149618 - H21 1.658405 29.397590 42.191804 - H31 0.003741 30.051615 43.918998 - H41 0.585850 31.775138 45.604479 - H51 2.822482 32.845507 45.562293 - H61 4.477004 32.192352 43.834626 - C1 20.146883 10.181185 20.496316 - C2 20.519196 11.112343 19.519495 - C3 19.548734 11.924517 18.920774 - C4 18.205958 11.805533 19.298874 - C5 17.833715 10.873846 20.274849 - C6 18.804178 10.061672 20.873571 - H11 20.895354 9.554550 20.957763 - H21 21.555207 11.204684 19.228127 - H31 19.836274 12.643494 18.167959 - H41 17.457558 12.431639 18.836582 - H51 16.797704 10.781505 20.566218 - H61 18.516567 9.343225 21.627231 - C1 24.912711 48.641116 60.711033 - C2 24.082343 49.148621 61.717402 - C3 23.300957 48.277338 62.485641 - C4 23.349940 46.898549 62.247512 - C5 24.179486 46.391352 61.240666 - C6 24.960872 47.262636 60.472427 - H11 25.515039 49.313189 60.118300 - H21 24.044911 50.212291 61.901647 - H31 22.661197 48.668935 63.262620 - H41 22.746789 46.226784 62.839768 - H51 24.216918 45.327682 61.056421 - H61 25.601454 46.870730 59.695925 - C1 60.944536 42.839509 74.678331 - C2 60.232489 43.693759 75.528683 - C3 60.363371 45.081314 75.396576 - C4 61.206298 45.614619 74.414118 - C5 61.918885 44.760403 73.564607 - C6 61.788003 43.372848 73.696714 - H11 60.843848 41.769354 74.780529 - H21 59.581651 43.282463 76.286301 - H31 59.813220 45.740173 76.051997 - H41 61.307526 46.684808 74.312761 - H51 62.569723 45.171699 72.806988 - H61 62.337614 42.713955 73.040452 - C1 22.921892 7.029901 13.070638 - C2 23.003542 5.632906 13.110496 - C3 21.862223 4.858042 12.872027 - C4 20.639254 5.480173 12.593700 - C5 20.557554 6.876936 12.554813 - C6 21.698873 7.651800 12.793282 - H11 23.802095 7.627467 13.254954 - H21 23.947136 5.152775 13.324607 - H31 21.925615 3.780345 12.901822 - H41 19.759000 4.882375 12.410355 - H51 19.613959 7.357067 12.340702 - H61 21.635532 8.729729 12.762516 - C1 16.188788 19.895434 75.407860 - C2 16.107239 20.078032 74.022270 - C3 14.948861 19.699211 73.333397 - C4 13.872033 19.137792 74.030113 - C5 13.954065 18.954410 75.415312 - C6 15.112442 19.333231 76.104185 - H11 17.082375 20.187263 75.939040 - H21 16.937702 20.511727 73.484701 - H31 14.885737 19.841077 72.264647 - H41 12.978929 18.845179 73.498542 - H51 13.123602 18.520715 75.952882 - H61 15.175084 19.192149 77.173326 - C1 44.184038 44.751574 28.937039 - C2 42.968410 45.222739 29.447042 - C3 41.958407 45.642335 28.573129 - C4 42.164032 45.590766 27.189213 - C5 43.379837 45.120554 26.679456 - C6 44.389840 44.700958 27.553369 - H11 44.963113 44.428341 29.611114 - H21 42.809393 45.262005 30.514709 - H31 41.020315 46.004835 28.966721 - H41 41.385134 45.914953 26.515383 - H51 43.538854 45.081288 25.611789 - H61 45.327755 44.337506 27.159531 - C1 42.780196 29.389619 45.814511 - C2 43.635334 30.485731 45.649800 - C3 43.103410 31.771746 45.497771 - C4 41.716348 31.961650 45.510455 - C5 40.861454 30.865530 45.674197 - C6 41.393379 29.579514 45.826225 - H11 43.190501 28.397748 45.931367 - H21 44.705502 30.339455 45.640610 - H31 43.763273 32.617341 45.371727 - H41 41.306287 32.953513 45.392630 - H51 39.791286 31.011806 45.683386 - H61 40.733272 28.733928 45.953240 - C1 15.092446 17.581072 10.479527 - C2 14.902390 18.899258 10.910938 - C3 15.345731 19.965502 10.119442 - C4 15.979128 19.713559 8.896537 - C5 16.169932 18.395544 8.465767 - C6 15.726592 17.329300 9.257263 - H11 14.750843 16.758762 11.090205 - H21 14.413184 19.093805 11.854108 - H31 15.198128 20.982359 10.451935 - H41 16.321480 20.536040 8.286500 - H51 16.659138 18.200997 7.522597 - H61 15.873446 16.312272 8.924129 - C1 30.125131 44.068367 15.540116 - C2 29.165011 43.070412 15.334918 - C3 29.079984 41.988560 16.219372 - C4 29.955076 41.904664 17.309023 - C5 30.915596 42.902016 17.513529 - C6 31.000623 43.983868 16.629076 - H11 30.190913 44.902524 14.857715 - H21 28.489396 43.135321 14.494637 - H31 28.338587 41.219313 16.061491 - H41 29.889694 41.069905 17.990732 - H51 31.591211 42.837108 18.353811 - H61 31.741620 44.753718 16.787648 - C1 79.127367 32.467222 48.065859 - C2 78.705011 33.801338 48.105892 - C3 77.586558 34.203859 47.366344 - C4 76.890461 33.272266 46.586764 - C5 77.313411 31.938627 46.546082 - C6 78.431864 31.536105 47.285630 - H11 79.990222 32.156925 48.635956 - H21 79.241587 34.520053 48.707785 - H31 77.260279 35.232873 47.398140 - H41 76.028200 33.583040 46.016018 - H51 76.776835 31.219911 45.944190 - H61 78.757549 30.506615 47.254483 - C1 58.949325 45.893095 53.907888 - C2 59.570172 45.672074 55.143020 - C3 59.671897 44.372096 55.652529 - C4 59.152775 43.293139 54.926908 - C5 58.531226 43.514365 53.692457 - C6 58.429501 44.814343 53.182947 - H11 58.870555 46.895780 53.515165 - H21 59.971273 46.504330 55.702670 - H31 60.151769 44.201667 56.604902 - H41 59.230842 42.290660 55.320311 - H51 58.130124 42.682109 53.132807 - H61 57.950331 44.984566 52.229893 - C1 50.865020 58.288178 28.566798 - C2 50.020513 59.337004 28.183884 - C3 48.747526 59.059223 27.671796 - C4 48.319047 57.732617 27.542622 - C5 49.163862 56.684047 27.924619 - C6 50.436849 56.961827 28.436708 - H11 51.846956 58.502475 28.961376 - H21 50.350713 60.360563 28.284060 - H31 48.095791 59.868485 27.377393 - H41 47.337418 57.518575 27.147127 - H51 48.833662 55.660487 27.824443 - H61 51.088277 56.152310 28.732026 - C1 38.260028 22.995914 1.403308 - C2 37.440599 22.072326 0.743480 - C3 37.886896 20.761165 0.539601 - C4 39.152622 20.373592 0.995550 - C5 39.972181 21.297370 1.654405 - C6 39.525885 22.608531 1.858284 - H11 37.915916 24.007247 1.560172 - H21 36.463808 22.371027 0.392200 - H31 37.254217 20.048533 0.031458 - H41 39.496865 19.362449 0.837713 - H51 40.948973 20.998669 2.005685 - H61 40.158433 23.320973 2.367401 - C1 30.906254 56.619399 67.794873 - C2 31.176744 57.618681 66.852471 - C3 30.315494 57.806634 65.764899 - C4 29.183754 56.995305 65.619730 - C5 28.913943 55.995620 66.561518 - C6 29.775193 55.807667 67.649090 - H11 31.570752 56.474234 68.633434 - H21 32.049520 58.245111 66.964672 - H31 30.523772 58.578229 65.038539 - H41 28.519935 57.140067 64.780555 - H51 28.041167 55.369190 66.449318 - H61 29.566236 55.036475 68.376064 - C1 67.198694 58.909230 8.795679 - C2 66.598884 57.838319 9.468902 - C3 66.171624 57.994996 10.792832 - C4 66.344175 59.222582 11.443540 - C5 66.944748 60.292930 10.770636 - C6 67.372008 60.136254 9.446705 - H11 67.528553 58.788207 7.774718 - H21 66.465133 56.891351 8.966803 - H31 65.708015 57.169050 11.311695 - H41 66.015079 59.343043 12.464819 - H51 67.078498 61.239899 11.272734 - H61 67.834854 60.962762 8.927525 - C1 69.291281 48.872254 22.068552 - C2 70.405638 48.179927 22.557167 - C3 70.387124 46.781656 22.623392 - C4 69.254254 46.075711 22.201003 - C5 68.139810 46.768082 21.713384 - C6 68.158324 48.166353 21.647158 - H11 69.305477 49.950699 22.017868 - H21 71.279962 48.724402 22.882504 - H31 71.247253 46.247686 22.999414 - H41 69.239971 44.997310 22.252683 - H51 67.265486 46.223607 21.388047 - H61 67.298283 48.700279 21.270142 - C1 74.697220 37.114282 78.284834 - C2 74.035080 38.215449 77.729089 - C3 72.643900 38.325093 77.840836 - C4 71.914860 37.333570 78.508329 - C5 72.576900 36.232179 79.063104 - C6 73.968080 36.122535 78.951357 - H11 75.770135 37.029583 78.198272 - H21 74.597474 38.980808 77.214618 - H31 72.133378 39.175151 77.412928 - H41 70.841844 37.418045 78.593921 - H51 72.014506 35.466820 79.577574 - H61 74.478702 35.272700 79.380235 - C1 54.868107 38.653568 48.597497 - C2 55.294183 39.808421 49.264299 - C3 55.714134 39.732054 50.597604 - C4 55.708008 38.500835 51.264106 - C5 55.281090 37.346432 50.597600 - C6 54.861140 37.422799 49.264296 - H11 54.543860 38.712603 47.569299 - H21 55.299547 40.758282 48.750028 - H31 56.043745 40.622881 51.111531 - H41 56.031414 38.442250 52.292601 - H51 55.275726 36.396571 51.111872 - H61 54.532370 36.531522 48.750072 - C1 67.763621 2.479212 71.819703 - C2 68.191231 2.990033 73.050988 - C3 67.286805 3.661539 73.882242 - C4 65.954770 3.822226 73.482211 - C5 65.527596 3.312277 72.250704 - C6 66.432022 2.640771 71.419450 - H11 68.461311 1.961661 71.178466 - H21 69.218730 2.865601 73.360025 - H31 67.616615 4.054658 74.832516 - H41 65.257516 4.340649 74.123226 - H51 64.500097 3.436710 71.941667 - H61 66.101776 2.246780 70.469398 - C1 22.241493 66.794740 54.856384 - C2 21.046016 67.454082 54.546615 - C3 20.944250 68.839002 54.724187 - C4 22.037959 69.564580 55.211527 - C5 23.232850 68.905098 55.522094 - C6 23.334617 67.520178 55.344522 - H11 22.319786 65.726554 54.719777 - H21 20.202325 66.894515 54.170037 - H31 20.022265 69.347622 54.484215 - H41 21.959081 70.632626 55.348932 - H51 24.076542 69.464665 55.898672 - H61 24.257187 67.011699 55.583695 - C1 7.935514 4.738571 32.735389 - C2 7.650495 3.891006 33.812537 - C3 7.172533 4.424430 35.015409 - C4 6.979589 5.805419 35.141133 - C5 7.265493 6.652813 34.064418 - C6 7.743455 6.119389 32.861545 - H11 8.304514 4.327139 31.807824 - H21 7.798719 2.825477 33.715485 - H31 6.951756 3.770333 35.845922 - H41 6.611474 6.216680 36.069131 - H51 7.117270 7.718342 34.161470 - H61 7.963347 6.773657 32.030599 - C1 51.708834 28.866050 5.359652 - C2 50.960928 27.757401 5.773641 - C3 49.571419 27.861538 5.908955 - C4 48.929815 29.074324 5.630279 - C5 49.677811 30.182959 5.217286 - C6 51.067321 30.078822 5.081973 - H11 52.780543 28.785775 5.255688 - H21 51.455720 26.821487 5.988084 - H31 48.994501 27.005898 6.227362 - H41 47.858196 29.154584 5.735239 - H51 49.183019 31.118873 5.002843 - H61 51.644147 30.934475 4.762570 - C1 71.792832 54.213394 66.093174 - C2 72.203399 52.920322 66.438503 - C3 71.448131 51.814083 66.031445 - C4 70.282295 52.000915 65.279060 - C5 69.871404 53.293856 64.934668 - C6 70.626672 54.400096 65.341725 - H11 72.375172 55.066566 66.407485 - H21 73.103162 52.775988 67.018446 - H31 71.765554 50.816577 66.297078 - H41 69.699631 51.147613 64.965686 - H51 68.971640 53.438190 64.354724 - H61 70.309572 55.397732 65.075155 - C1 13.763145 70.551672 5.512055 - C2 12.644901 69.782075 5.854259 - C3 12.662878 68.998684 7.014374 - C4 13.799099 68.984888 7.832283 - C5 14.917422 69.753656 7.489524 - C6 14.899445 70.537048 6.329410 - H11 13.749359 71.155542 4.617088 - H21 11.767996 69.793095 5.223659 - H31 11.799759 68.405834 7.278740 - H41 13.812964 68.380190 8.726695 - H51 15.794328 69.742636 8.120124 - H61 15.762486 71.130726 6.065598 - C1 55.204930 25.324298 28.688362 - C2 54.578315 26.576141 28.698012 - C3 54.800907 27.462060 29.758904 - C4 55.650115 27.096135 30.810146 - C5 56.275808 25.844115 30.800844 - C6 56.053216 24.958196 29.739952 - H11 55.032903 24.640920 27.870307 - H21 53.923601 26.858840 27.886734 - H31 54.318220 28.428136 29.765681 - H41 55.821220 27.779336 31.628550 - H51 56.930522 25.561416 31.612123 - H61 56.536824 23.992296 29.732827 - C1 29.378247 23.811382 9.330534 - C2 30.570979 23.249257 9.800912 - C3 30.722139 21.857974 9.837949 - C4 29.680565 21.028815 9.404608 - C5 28.487746 21.590952 8.935227 - C6 28.336587 22.982235 8.898190 - H11 29.261582 24.884420 9.302363 - H21 31.374883 23.888843 10.134694 - H31 31.642707 21.424522 10.199903 - H41 29.797144 19.955789 9.433776 - H51 27.683843 20.951366 8.601445 - H61 27.416105 23.415675 8.535240 - C1 78.967029 11.686827 26.682102 - C2 78.730548 12.911713 27.317383 - C3 77.435027 13.440791 27.357306 - C4 76.375988 12.744983 26.761948 - C5 76.612726 11.520789 26.125993 - C6 77.908247 10.991712 26.086070 - H11 79.966299 11.279019 26.651007 - H21 79.547400 13.448352 27.777288 - H31 77.252610 14.385239 27.848305 - H41 75.376975 13.153484 26.792369 - H51 75.795874 10.984151 25.666088 - H61 78.090407 10.046572 25.595745 - C1 5.222112 44.633218 38.718534 - C2 6.019760 44.350319 37.603377 - C3 5.768427 43.207423 36.834929 - C4 4.719445 42.347427 37.181638 - C5 3.922614 42.629889 38.297169 - C6 4.173947 43.772784 39.065617 - H11 5.416255 45.514492 39.311391 - H21 6.828708 45.014048 37.335404 - H31 6.383231 42.989878 35.974099 - H41 4.526120 41.465716 36.589155 - H51 3.113667 41.966160 38.565141 - H61 3.558325 43.990766 39.926072 - C1 36.720489 49.806267 16.448096 - C2 36.179413 49.498471 15.194162 - C3 36.978552 48.894359 14.216247 - C4 38.318766 48.598042 14.492267 - C5 38.859874 48.906697 15.745689 - C6 38.060735 49.510809 16.723604 - H11 36.104199 50.272548 17.202141 - H21 35.145275 49.726461 14.981275 - H31 36.560703 48.656067 13.249316 - H41 38.935088 48.132620 13.737711 - H51 39.894012 48.678707 15.958576 - H61 38.478551 49.748242 17.691047 - C1 55.041644 44.996472 34.017970 - C2 55.814140 43.891420 34.394745 - C3 55.241376 42.614321 34.423902 - C4 53.896115 42.442274 34.076284 - C5 53.123621 43.547343 33.700508 - C6 53.696385 44.824442 33.671351 - H11 55.483350 45.981471 33.995881 - H21 56.852198 44.023912 34.662369 - H31 55.837728 41.761814 34.713615 - H41 53.454411 41.457292 34.099373 - H51 52.085563 43.414851 33.432884 - H61 53.100031 45.676932 33.380638 - C1 7.907062 43.732061 33.766385 - C2 7.823911 43.336073 32.426187 - C3 7.581114 44.288084 31.428883 - C4 7.421468 45.636083 31.771777 - C5 7.503687 46.031727 33.111866 - C6 7.746484 45.079716 34.109171 - H11 8.093934 42.997709 34.535554 - H21 7.947670 42.296205 32.161425 - H31 7.518001 43.982568 30.394952 - H41 7.233663 46.370091 31.002500 - H51 7.379927 47.071595 33.376629 - H61 7.810529 45.385576 35.143210 - C1 13.834675 62.995255 31.630445 - C2 15.112219 62.518007 31.314268 - C3 15.357198 61.139950 31.285353 - C4 14.324634 60.239142 31.572614 - C5 13.047608 60.716459 31.889643 - C6 12.802628 62.094515 31.918558 - H11 13.645899 64.058111 31.653111 - H21 15.908796 63.212853 31.092019 - H31 16.342551 60.771939 31.040437 - H41 14.513927 59.176354 31.550800 - H51 12.251030 60.021613 32.111892 - H61 11.816757 62.462457 32.162621 - C1 71.467076 24.321086 20.188365 - C2 70.683358 23.318198 19.605398 - C3 71.295432 22.206393 19.014513 - C4 72.691225 22.097476 19.006593 - C5 73.474714 23.100715 19.588652 - C6 72.862640 24.212520 20.179537 - H11 70.994959 25.178737 20.643726 - H21 69.606459 23.401788 19.611976 - H31 70.690650 21.432332 18.565729 - H41 73.163112 21.240175 18.550324 - H51 74.551612 23.017124 19.582074 - H61 73.467651 24.986230 20.629229 - C1 74.854391 15.783596 15.518567 - C2 76.031800 15.585025 14.787725 - C3 76.082888 15.937131 13.433730 - C4 74.956568 16.487808 12.810577 - C5 73.779141 16.685413 13.541161 - C6 73.728053 16.333307 14.895156 - H11 74.814934 15.511647 16.562741 - H21 76.901040 15.160753 15.268513 - H31 76.991585 15.784808 12.870343 - H41 74.996007 16.758791 11.766145 - H51 72.909902 17.109685 13.060373 - H61 72.819374 16.486596 15.458800 - C1 73.122618 7.854637 19.294659 - C2 72.297384 7.250458 18.338725 - C3 72.567047 7.417799 16.975212 - C4 73.661943 8.189320 16.567631 - C5 74.486391 8.794112 17.523479 - C6 74.216728 8.626771 18.886993 - H11 72.914353 7.725855 20.346255 - H21 71.452986 6.654687 18.653035 - H31 71.930913 6.950810 16.237924 - H41 73.869422 8.318714 15.515949 - H51 75.330789 9.389883 17.209169 - H61 74.853647 9.093147 19.624365 - C1 2.985176 15.612917 64.586507 - C2 2.282687 15.000754 63.541702 - C3 2.901074 14.809130 62.300425 - C4 4.221948 15.229669 62.103952 - C5 4.923879 15.842561 63.148361 - C6 4.305493 16.034185 64.389639 - H11 2.508052 15.761032 65.543706 - H21 1.263821 14.675696 63.693321 - H31 2.359330 14.335957 61.494845 - H41 4.698514 15.082283 61.146358 - H51 5.942746 16.167619 62.996743 - H61 4.847794 16.506628 65.195615 - C1 5.006051 77.680375 26.601879 - C2 6.131870 78.057097 27.343809 - C3 7.213237 77.177030 27.470379 - C4 7.168783 75.920241 26.855018 - C5 6.042714 75.543342 26.114039 - C6 4.961348 76.423409 25.987469 - H11 4.171911 78.359027 26.504626 - H21 6.166568 79.026930 27.818110 - H31 8.082074 77.468211 28.041932 - H41 8.002673 75.241412 26.953222 - H51 6.008016 74.573509 25.639738 - H61 4.092760 76.132405 25.414964 - C1 74.943486 27.716123 28.576874 - C2 74.440202 26.443085 28.283738 - C3 73.178649 26.063187 28.757083 - C4 72.420381 26.956329 29.523563 - C5 72.924094 28.228762 29.817369 - C6 74.185646 28.608659 29.344025 - H11 75.916639 28.008916 28.212103 - H21 75.024835 25.754133 27.691885 - H31 72.790129 25.081442 28.530001 - H41 71.447656 26.662930 29.889005 - H51 72.339460 28.917713 30.409223 - H61 74.573738 29.591009 29.570436 - C1 23.719511 40.242223 11.064073 - C2 24.323332 39.218357 10.324513 - C3 25.335655 39.521658 9.406308 - C4 25.744157 40.848827 9.227662 - C5 25.139708 41.872519 9.966464 - C6 24.127385 41.569218 10.884669 - H11 22.938485 40.008276 11.771944 - H21 24.008701 38.194316 10.462678 - H31 25.802050 38.731565 8.836602 - H41 26.524555 41.082600 8.519033 - H51 25.454339 42.896560 9.828299 - H61 23.661618 42.359485 11.455133 - C1 75.550908 48.414066 3.044270 - C2 76.727555 47.725722 3.362917 - C3 77.624638 48.265909 4.292074 - C4 77.345073 49.494439 4.902584 - C5 76.169063 50.183007 4.583199 - C6 75.271980 49.642821 3.654042 - H11 74.859260 47.997575 2.327352 - H21 76.943080 46.777595 2.892445 - H31 78.531811 47.734271 4.538520 - H41 78.037358 49.911154 5.618765 - H51 75.953538 51.131135 5.053671 - H61 74.364171 50.174233 3.408334 - C1 2.118900 68.274556 65.655093 - C2 3.301933 67.768490 65.103566 - C3 3.293418 66.535948 64.439745 - C4 2.101870 65.809472 64.327451 - C5 0.919318 66.315115 64.879746 - C6 0.927833 67.547657 65.543567 - H11 2.125618 69.224984 66.167397 - H21 4.221174 68.329149 65.189587 - H31 4.205941 66.146179 64.013461 - H41 2.095633 64.858621 63.815915 - H51 0.000077 65.754457 64.793726 - H61 0.014829 67.937850 65.969083 - C1 75.899323 69.201341 7.124091 - C2 75.601985 69.394991 8.478322 - C3 75.378498 68.291644 9.310529 - C4 75.452350 66.994647 8.788506 - C5 75.748711 66.801204 7.434296 - C6 75.972197 67.904552 6.602089 - H11 76.071293 70.052361 6.482214 - H21 75.545580 70.395556 8.881346 - H31 75.150124 68.441189 10.355430 - H41 75.279403 66.143834 9.430403 - H51 75.805115 65.800639 7.031271 - H61 76.201549 67.754799 5.557167 - C1 51.945333 67.492308 17.935227 - C2 51.765445 67.428284 19.322091 - C3 51.774692 68.602730 20.083986 - C4 51.963825 69.841199 19.459016 - C5 52.144613 69.904985 18.072516 - C6 52.135366 68.730539 17.310622 - H11 51.938581 66.586436 17.347719 - H21 51.618901 66.472922 19.804324 - H31 51.634899 68.553239 21.153726 - H41 51.971477 70.746833 20.046888 - H51 52.291157 70.860347 17.590283 - H61 52.274259 68.780267 16.240516 - C1 63.199160 29.800629 49.859610 - C2 63.888360 29.106168 50.860900 - C3 65.287511 29.136626 50.897500 - C4 65.997463 29.861545 49.932810 - C5 65.308297 30.555058 48.931199 - C6 63.909146 30.524600 48.894600 - H11 62.120069 29.776776 49.831209 - H21 63.340742 28.547349 51.605598 - H31 65.818984 28.601660 51.670600 - H41 67.076588 29.884451 49.960890 - H51 65.855915 31.113878 48.186501 - H61 63.377639 31.060513 48.121821 - C1 36.483801 75.804887 14.595253 - C2 35.278751 76.374641 14.167369 - C3 34.928335 76.335689 12.812532 - C4 35.782970 75.726983 11.885579 - C5 36.988214 75.158206 12.313380 - C6 37.338630 75.197158 13.668217 - H11 36.754185 75.835308 15.640136 - H21 34.619002 76.843754 14.882494 - H31 33.998203 76.774380 12.482774 - H41 35.512780 75.697539 10.840613 - H51 37.647963 74.689093 11.598254 - H61 38.268569 74.757489 13.998058 - C1 70.698397 43.827631 66.227920 - C2 71.014925 45.120813 66.660752 - C3 72.331057 45.436591 67.018481 - C4 73.330662 44.459189 66.943379 - C5 73.013872 43.166027 66.511512 - C6 71.697739 42.850248 66.153783 - H11 69.683226 43.584045 65.952407 - H21 70.243948 45.875160 66.718158 - H31 72.575252 46.434525 67.351400 - H41 74.345571 44.702794 67.219857 - H51 73.784849 42.411679 66.454106 - H61 71.453807 41.852296 65.819899 - C1 57.208831 27.297751 7.825242 - C2 57.530329 25.950944 8.031642 - C3 56.546531 24.965961 7.883850 - C4 55.241236 25.327786 7.529658 - C5 54.919705 26.674470 7.324250 - C6 55.903502 27.659453 7.472042 - H11 57.967545 28.057411 7.939627 - H21 58.537480 25.671584 8.304306 - H31 56.794968 23.926941 8.042129 - H41 54.482489 24.568003 7.416265 - H51 53.912554 26.953831 7.051586 - H61 55.655099 28.698596 7.312771 - C1 44.040163 74.312204 76.314010 - C2 42.819789 74.390229 76.995516 - C3 42.452239 75.577945 77.639045 - C4 43.305064 76.687635 77.601067 - C5 44.525613 76.609188 76.920451 - C6 44.893163 75.421472 76.276922 - H11 44.323754 73.396016 75.818036 - H21 42.161445 73.534372 77.024381 - H31 41.510305 75.638276 78.163884 - H41 43.021648 77.603401 78.097931 - H51 45.183957 77.465045 76.891586 - H61 45.834922 75.361563 75.751194 - C1 21.348389 54.169732 52.154683 - C2 21.701005 52.880255 52.570331 - C3 23.050659 52.525957 52.683456 - C4 24.047697 53.461135 52.380933 - C5 23.695007 54.750048 51.964462 - C6 22.345353 55.104346 51.851337 - H11 20.307440 54.442800 52.067079 - H21 20.931893 52.158840 52.804358 - H31 23.322495 51.531474 53.005087 - H41 25.088572 53.187503 52.467714 - H51 24.464119 55.471463 51.730435 - H61 22.073591 56.099393 51.530529 - C1 26.197950 69.277423 8.235662 - C2 27.259753 69.918617 7.586590 - C3 28.327724 69.167228 7.081869 - C4 28.333892 67.774644 7.226220 - C5 27.272677 67.133782 7.876030 - C6 26.204706 67.885171 8.380751 - H11 25.374490 69.857033 8.625253 - H21 27.254836 70.992943 7.474602 - H31 29.146266 69.661944 6.580290 - H41 29.157939 67.195366 6.837367 - H51 27.277594 66.059456 7.988018 - H61 25.385575 67.390124 8.881593 - C1 67.455021 39.524735 72.123171 - C2 68.519078 40.144181 71.456897 - C3 69.110328 39.521178 70.351374 - C4 68.637522 38.278730 69.912124 - C5 67.574272 37.659067 70.578947 - C6 66.983022 38.282069 71.684470 - H11 66.999317 40.005102 72.976046 - H21 68.883558 41.103027 71.795289 - H31 69.930512 39.999658 69.836890 - H41 69.094033 37.798145 69.059798 - H51 67.209793 36.700220 70.240555 - H61 66.162031 37.803807 72.198405 - C1 4.772877 61.080316 30.441400 - C2 5.330659 61.713812 29.324524 - C3 5.046592 63.060692 29.069354 - C4 4.204744 63.774076 29.931060 - C5 3.646374 63.140317 31.047172 - C6 3.930440 61.793437 31.302342 - H11 4.991693 60.041417 30.637927 - H21 5.980663 61.163728 28.659961 - H31 5.477780 63.549507 28.208264 - H41 3.985340 64.812711 29.733769 - H51 2.996370 63.690401 31.711735 - H61 3.499841 61.304886 32.164196 - C1 76.374200 27.099629 38.604675 - C2 77.400333 26.149561 38.670050 - C3 77.533476 25.340145 39.804514 - C4 76.640487 25.480795 40.873603 - C5 75.615163 26.431378 40.808507 - C6 75.482020 27.240795 39.674043 - H11 76.271807 27.724133 37.729847 - H21 78.088983 26.040509 37.845059 - H31 78.324519 24.606588 39.854351 - H41 76.743689 24.856807 41.748710 - H51 74.926514 26.540431 41.633498 - H61 74.690168 27.973836 39.623927 - C1 47.762159 7.110335 60.494537 - C2 48.347009 5.929705 60.967733 - C3 48.816273 4.969746 60.063212 - C4 48.700688 5.190416 58.685493 - C5 48.115067 6.370450 58.212521 - C6 47.645802 7.330409 59.117043 - H11 47.399902 7.850494 61.192211 - H21 48.436811 5.759592 62.030625 - H31 49.268333 4.059474 60.428429 - H41 49.062174 4.449662 57.988044 - H51 48.025265 6.540563 57.149630 - H61 47.194514 8.241277 58.751601 - C1 23.350138 77.181586 56.994509 - C2 23.602396 78.262954 57.847071 - C3 24.637143 79.159069 57.553528 - C4 25.419632 78.973817 56.407423 - C5 25.167923 77.892067 55.555604 - C6 24.133176 76.995952 55.849147 - H11 22.552320 76.490266 57.221172 - H21 22.998387 78.406357 58.731010 - H31 24.830952 79.993792 58.210804 - H41 26.217999 79.664755 56.181503 - H51 25.771932 77.748664 54.671665 - H61 23.938818 76.161611 55.191128 - C1 61.748925 34.659583 28.793291 - C2 62.183774 34.457279 30.108521 - C3 61.303398 34.666471 31.176729 - C4 59.988173 35.077966 30.929707 - C5 59.553810 35.281110 29.614718 - C6 60.434185 35.071918 28.546510 - H11 62.428086 34.498602 27.969495 - H21 63.198272 34.139213 30.299225 - H31 61.638735 34.509385 32.191229 - H41 59.309497 35.239787 31.753744 - H51 58.539311 35.599177 29.424014 - H61 60.098363 35.228164 27.531769 - C1 20.424924 22.860619 14.405888 - C2 19.964320 21.541982 14.311586 - C3 20.787183 20.482828 14.712808 - C4 22.070651 20.742310 15.208332 - C5 22.531401 22.060691 15.301678 - C6 21.708538 23.119845 14.900456 - H11 19.790381 23.677427 14.096059 - H21 18.973906 21.341673 13.929881 - H31 20.431312 19.465711 14.640932 - H41 22.705340 19.925247 15.517205 - H51 23.521815 22.261000 15.683383 - H61 22.064263 24.137217 14.973288 diff --git a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/packmol_files/README.TXT b/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/packmol_files/README.TXT deleted file mode 100644 index f0e39ec90a..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/packmol_files/README.TXT +++ /dev/null @@ -1,5 +0,0 @@ -You can use packmol to create a file containing the atomic coordinates -for a system of ethylene mixed with benzene using this command: - -packmol < mix_ethylene+benzene.inp - diff --git a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/packmol_files/benzene.xyz b/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/packmol_files/benzene.xyz deleted file mode 100644 index 1a727ff40c..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/packmol_files/benzene.xyz +++ /dev/null @@ -1,14 +0,0 @@ -12 - Benzene -C1 5.274 1.999 -8.568 -C2 6.627 2.018 -8.209 -C3 7.366 0.829 -8.202 -C4 6.752 -0.379 -8.554 -C5 5.399 -0.398 -8.912 -C6 4.660 0.791 -8.919 -H11 4.704 2.916 -8.573 -H21 7.101 2.950 -7.938 -H31 8.410 0.844 -7.926 -H41 7.322 -1.296 -8.548 -H51 4.925 -1.330 -9.183 -H61 3.616 0.776 -9.196 diff --git a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/packmol_files/ethylene.xyz b/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/packmol_files/ethylene.xyz deleted file mode 100644 index 35326fe81f..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/packmol_files/ethylene.xyz +++ /dev/null @@ -1,8 +0,0 @@ -6 - Ethylene -C1 -0.6695 0.000000 0.000000 -C2 0.6695 0.000000 0.000000 -H11 -1.234217 -0.854458 0.000000 -H12 -1.234217 0.854458 0.000000 -H21 1.234217 -0.854458 0.000000 -H22 1.234217 0.854458 0.000000 diff --git a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/packmol_files/mix_ethylene+benzene.inp b/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/packmol_files/mix_ethylene+benzene.inp deleted file mode 100644 index 76202ebf30..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/packmol_files/mix_ethylene+benzene.inp +++ /dev/null @@ -1,31 +0,0 @@ -# -# A mixture of ethylene and benzene -# - -# All the atoms from diferent molecules will be separated at least 2.0 -# Anstroms at the solution. - -tolerance 2.0 - -# The file type of input and output files is XYZ - -filetype xyz - -# The name of the output file - -output system.xyz - -# 1000 water molecules and 500 urea molecules will be put in a box -# defined by the minimum coordinates x, y and z = 0. 0. 0. and maximum -# coordinates 80. 80. 80. That is, they will be put in a cube of side -# 80. (the keyword "inside cube 0. 0. 0. 80.") could be used as well. - -structure ethylene.xyz - number 1000 - inside box 0. 0. 0. 80. 80. 80. -end structure - -structure benzene.xyz - number 500 - inside box 0. 0. 0. 80. 80. 80. -end structure diff --git a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/run.in.npt b/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/run.in.npt deleted file mode 100644 index 1066f810d7..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/run.in.npt +++ /dev/null @@ -1,58 +0,0 @@ -# PREREQUISITES: -# -# You must use moltemplate.sh to create 3 files: -# system.data system.in.init system.in.settings -# (Follow the instructions in README_setup.sh, -# or run the file as a script using ./README_setup.sh) - -# ------------------------------- Initialization Section -------------------- - -include "system.in.init" - -# ------------------------------- Atom Definition Section ------------------- - -read_data "system.data" - -# OPLSAA atom charges are stored in a separate file. -# Load that file now: - -include "system.in.charges" - -# ------------------------------- Settings Section -------------------------- - -include "system.in.settings" - -# ------------------------------- Run Section ------------------------------- - - -# -- minimization protocol -- - -minimize 1.0e-4 1.0e-6 100000 400000 - -# -- simulation protocol -- - -timestep 1.0 - -print "---------------------------------------------------------------------------" -print "First, use Langevin dynamics to randomize the initial shape of the molecules" -print "(This is not really necessary, but it seems to speed up equilibration.)" -print "---------------------------------------------------------------------------" - -fix fxlan all langevin 300.0 300.0 120 123456 # temp: 300 K -fix fxnph all nph iso 50.0 50.0 1000.0 # pressure: 50 barr -run 2000 -unfix fxlan -unfix fxnph - -print "---------------------------------------------------------------------------" -print "--- Now continue the simulation using a Nose-Hoover Thermostat/Barostat ---" -print "---------------------------------------------------------------------------" -dump 1 all custom 1000 traj_npt.lammpstrj id mol type x y z ix iy iz -# temperature: 300 K, pressure: 50 barr -fix fxnpt all npt temp 300.0 300.0 100.0 iso 50.0 50.0 1000.0 drag 1.0 -thermo 100 -#thermo_modify flush yes - -run 200000 - -write_data system_after_npt.data diff --git a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/run.in.nvt b/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/run.in.nvt deleted file mode 100644 index 2f3b81c186..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/ethylene+benzene_PACKMOL/run.in.nvt +++ /dev/null @@ -1,51 +0,0 @@ -# PREREQUISITES: -# -# 1) You must use moltemplate.sh to create 3 files: -# system.data system.in.init system.in.settings -# (Follow the instructions in README_setup.sh, -# or run the file as a script using ./README_setup.sh) -# 2) You must equilibrate the system beforehand using "run.in.npt". -# This will create the file "system_after_npt.data" which this file reads. -# (Note: I have not verified that this equilibration protocol works well.) - -# ------------------------------- Initialization Section -------------------- - -include "system.in.init" - -# ------------------------------- Atom Definition Section ------------------- - -# Read the coordinates generated by an earlier NPT simulation - -read_data "system_after_npt.data" - -# OPLSAA atom charges are stored in a separate file. -# Load that file now: - -include "system.in.charges" - -# ------------------------------- Settings Section -------------------------- - -include "system.in.settings" - - -# (The "write_restart" and "read_restart" commands were buggy in 2012, -# but they should work also. I prefer "write_data" and "read_data".) - -# ------------------------------- Settings Section -------------------------- - -include system.in.settings - -# ------------------------------- Run Section ------------------------------- - -# -- simulation protocol -- - - -timestep 1.0 -dump 1 all custom 5000 traj_nvt.lammpstrj id mol type x y z ix iy iz -fix fxnvt all nvt temp 300.0 300.0 500.0 tchain 1 -thermo 500 -#thermo_modify flush yes - -run 200000 - -write_data system_after_nvt.data diff --git a/tools/moltemplate/examples/force_field_OPLSAA/hexadecane/README.TXT b/tools/moltemplate/examples/force_field_OPLSAA/hexadecane/README.TXT deleted file mode 100644 index eceba67ef6..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/hexadecane/README.TXT +++ /dev/null @@ -1,43 +0,0 @@ -This example is a simple simulation of many long alkane chains (hexadecane) in a -box at room temperature and atmospheric pressure. Please read "WARNING.TXT". - -NOTE: This particular example uses the OPLSAA force-field - However, moltemplate is not limited to OPLSAA. - -1) Create the "system.data", "system.in.init", and "system.in.settings" -files which LAMMPS will read by running: - -moltemplate.sh system.lt - - -2) Run LAMMPS in this order: - -lmp_mpi -i run.in.min # minimize the energy (to avoid atom overlap) before... -lmp_mpi -i run.in.npt # running the simulation at constant pressure -lmp_mpi -i run.in.nvt # running the simulation at constant temperature - -(The name of the LAMMPS executable, eg "lmp_mpi", may vary.) - ----- Details ---- - -The "Hexadecane" molecule, as well as the "CH2", and "CH3" monomers it contains -use the OPLSAA force-field. This means that when we define these molecules, -we only specify the atom names, bond list, and coordinates. -We do not have to list the atom charges, angles, dihedrals, or impropers. -The rules for creating atomic charge and angle topology are contained in -the "loplsaa.lt" file created by step 3) above. The "ch2group.lt", -"ch3group.lt", and "hexadecane.lt" files all refer to "loplsaa.lt", -(as well as the "OPLSAA" force-field object which it defines). Excerpt: - -import "loplsaa.lt" -CH2 inherits OPLSAA { ... -CH3 inherits OPLSAA { ... -Hexadecane inherits OPLSAA { ... - -Alternatively, you can manually define a list of angles, dihedrals, and -improper interactions in these files, instead of asking the force-field -to generate them for you. You can also specify some of the angles and -dihedrals explicitly, and let the force-field handle the rest. -(Many of the examples which come with moltemplate do this.) - - diff --git a/tools/moltemplate/examples/force_field_OPLSAA/hexadecane/README_run.sh b/tools/moltemplate/examples/force_field_OPLSAA/hexadecane/README_run.sh deleted file mode 100755 index 5f82866644..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/hexadecane/README_run.sh +++ /dev/null @@ -1,34 +0,0 @@ -# --- Running LAMMPS --- -# -# The 2 files "run.in.npt", and "run.in.nvt" are LAMMPS -# input scripts which link to the input scripts and data files -# you hopefully have created earlier with moltemplate.sh: -# system.in.init, system.in.settings, system.data -# If not, carry out the instructions in "README_setup.sh". -# -# -- Instructions: -- -# If "lmp_mpi" is the name of the command you use to invoke lammps, -# then you would run lammps on these files this way: - - -lmp_mpi -i run.in.npt # minimization and simulation at constant pressure -lmp_mpi -i run.in.nvt # minimization and simulation at constant volume - -#(Note: The constant volume simulation lacks pressure equilibration. These are -# completely separate simulations. The results of the constant pressure -# simulation might be ignored when beginning the simulation at constant -# volume. (This is because restart files in LAMMPS don't always work, -# and I was spending a lot of time trying to convince people it was a -# LAMMPS bug, instead of a moltemplate bug, so I disabled restart files.) -# Read the "run.in.nvt" file to find out how to use the "read_restart" -# command to load the results of the pressure-equilibration simulation, -# before beginning a constant-volume run. - - - - - -# If you have compiled the MPI version of lammps, you can run lammps in parallel -#mpirun -np 4 lmp_mpi -i run.in.npt -#mpirun -np 4 lmp_mpi -i run.in.nvt -# (assuming you have 4 processors available) diff --git a/tools/moltemplate/examples/force_field_OPLSAA/hexadecane/README_setup.sh b/tools/moltemplate/examples/force_field_OPLSAA/hexadecane/README_setup.sh deleted file mode 100755 index 33b505dbb9..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/hexadecane/README_setup.sh +++ /dev/null @@ -1,29 +0,0 @@ - -# Create LAMMPS input files this way: -cd moltemplate_files - - # run moltemplate - - moltemplate.sh system.lt - - # This will generate various files with names ending in *.in* and *.data. - # Move them to the directory where you plan to run LAMMPS (in this case "../") - mv -f system.data system.in* ../ - - # Optional: - # The "./output_ttree/" directory is full of temporary files generated by - # moltemplate. They can be useful for debugging, but are usually thrown away. - rm -rf output_ttree/ - -cd ../ - - - - - -# Optional: -# Note: The system.data and system.in.settings files contain extra information -# for atoms defined in OPLSAA which you are not using in this simulation. This -# is harmless, but if you to delete this information from your -# system.in.settings and system.in.data files, follow the instructions in -# this script: "optional_cleanup/README_remove_irrelevant_info.sh" diff --git a/tools/moltemplate/examples/force_field_OPLSAA/hexadecane/README_visualize.txt b/tools/moltemplate/examples/force_field_OPLSAA/hexadecane/README_visualize.txt deleted file mode 100644 index 019afc1444..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/hexadecane/README_visualize.txt +++ /dev/null @@ -1,87 +0,0 @@ - - ------- To view a lammps trajectory in VMD -------- - - -1) Build a PSF file for use in viewing with VMD. - -This step works with VMD 1.9 and topotools 1.2. -(Older versions, like VMD 1.8.6, don't support this.) - - -a) Start VMD -b) Menu Extensions->Tk Console -c) Enter: - -(I assume that the the DATA file is called "system.data") - - topo readlammpsdata system.data full - animate write psf system.psf - -2) - -Later, to Load a trajectory in VMD: - - Start VMD - Select menu: File->New Molecule - -Browse to select the PSF file you created above, and load it. - (Don't close the window yet.) - -Browse to select the trajectory file. - If necessary, for "file type" select: "LAMMPS Trajectory" - Load it. - - ---- A note on trajectory format: ----- -If the trajectory is a DUMP file, then make sure the it contains the -information you need for pbctools (see below. I've been using this -command in my LAMMPS scripts to create the trajectories: - - dump 1 all custom 5000 DUMP_FILE.lammpstrj id mol type x y z ix iy iz - -It's a good idea to use an atom_style which supports molecule-ID numbers -so that you can assign a molecule-ID number to each atom. (I think this -is needed to wrap atom coordinates without breaking molecules in half.) - -Of course, you don't have to save your trajectories in DUMP format, -(other formats like DCD work fine) I just mention dump files -because these are the files I'm familiar with. - -3) ----- Wrap the coordinates to the unit cell - (without cutting the molecules in half) - -a) Start VMD -b) Load the trajectory in VMD (see above) -c) Menu Extensions->Tk Console -d) Try entering these commands: - - pbc wrap -compound res -all - pbc box - - ----- Optional ---- - Sometimes the solvent or membrane obscures the view of the solute. - It can help to shift the location of the periodic boundary box - To shift the box in the y direction (for example) do this: - - pbc wrap -compound res -all -shiftcenterrel {0.0 0.15 0.0} - pbc box -shiftcenterrel {0.0 0.15 0.0} - - Distances are measured in units of box-length fractions, not Angstroms. - - Alternately if you have a solute whose atoms are all of type 1, - then you can also try this to center the box around it: - - pbc wrap -sel type=1 -all -centersel type=2 -center com - -4) - You should check if your periodic boundary conditions are too small. - To do that: - select Graphics->Representations menu option - click on the "Periodic" tab, and - click on the "+x", "-x", "+y", "-y", "+z", "-z" checkboxes. - -5) Optional: If you like, change the atom types in the PSF file so - that VMD recognizes the atom types, use something like: - -sed -e 's/ 1 1 / C C /g' < system.psf > temp1.psf -sed -e 's/ 2 2 / H H /g' < temp1.psf > temp2.psf -sed -e 's/ 3 3 / P P /g' < temp2.psf > system.psf - -(If you do this, it might effect step 2 above.) diff --git a/tools/moltemplate/examples/force_field_OPLSAA/hexadecane/WARNING.TXT b/tools/moltemplate/examples/force_field_OPLSAA/hexadecane/WARNING.TXT deleted file mode 100644 index c92b2592a6..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/hexadecane/WARNING.TXT +++ /dev/null @@ -1,15 +0,0 @@ -# -------- WARNING: -------- - -This software is experimental, and the force-fields and equilbration protocols -have not been tested carefully by me. There is no gaurantee that the simulation -will reproduce the behavior of real hexadecane molecules, -(or even of hexadecane molecules simulated using AMBER, which should - be using the same force-field). - -# -------- REQUEST FOR HELP: -------- - -However, if you notice a problem with this example, please report it. -Peer-review is the only way to improve this software (or any software). -Other suggestions are also welcome! - -(Contact jewett.aij@gmail.com, 2014-12-16) diff --git a/tools/moltemplate/examples/force_field_OPLSAA/hexadecane/images/hexadecane_12x12x2_t=0_LR.jpg b/tools/moltemplate/examples/force_field_OPLSAA/hexadecane/images/hexadecane_12x12x2_t=0_LR.jpg deleted file mode 100644 index b0d31f88453d4594681cc81791d66c5c1e8c0b99..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 27017 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\rwJO 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 Op_CsiKd1iyPygBZ$I|=& diff --git a/tools/moltemplate/examples/force_field_OPLSAA/hexadecane/images/hexadecane_LR.jpg b/tools/moltemplate/examples/force_field_OPLSAA/hexadecane/images/hexadecane_LR.jpg deleted file mode 100644 index 3ad353dbb4e083ccc07be687ea044170e86ec952..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5237 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 Ob8E+5TPj`WGyehPY6hJE diff --git a/tools/moltemplate/examples/force_field_OPLSAA/hexadecane/moltemplate_files/ch2group.lt b/tools/moltemplate/examples/force_field_OPLSAA/hexadecane/moltemplate_files/ch2group.lt deleted file mode 100644 index 510b7e111a..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/hexadecane/moltemplate_files/ch2group.lt +++ /dev/null @@ -1,82 +0,0 @@ -# This file contains a definition for the "CH2" molecular subunit. - -# First, load the OPLS force field parameters we will need. -# These 2 files are located in the "src/moltemplate_force_fields/" subdirectory: - -import "oplsaa.lt" # <-- defines the standard "OPLSAA" force field -import "loplsaa.lt" # <-- custom parameters for long alkane chains taken from - # Sui et al. J.Chem.Theory.Comp (2012), 8, 1459 - # To use the ordinary OPLSAA force field parameters, - # (instead of the Sui et al. parameters), change the - # atom types below from "@atom:81L","@atom:85LCH2" to - # "@atom:81" and "@atom:85" (defined in "oplsaa.lt") - - - -# Then define "CH2": - - -CH2 inherits OPLSAA { - - # atom-id mol-id atom-type charge x y z - - write("Data Atoms") { - $atom:C $mol:... @atom:81L 0.0 0.000000 0.000000 0.000000 - $atom:H1 $mol:... @atom:85LCH2 0.0 0.000000 0.631044 0.892431 - $atom:H2 $mol:... @atom:85LCH2 0.0 0.000000 0.631044 -0.892431 - } - - write('Data Bond List') { - $bond:CH1 $atom:C $atom:H1 - $bond:CH2 $atom:C $atom:H2 - } - - # Atom type numbers (@atom:80L,@atom:85LCH3) are defined in "loplsaa.lt", - # which is usually located in the "src/moltemplate_force_fields/" subdirectory - # @atom:80L "Alkane CH3- (LOPLS CT_CH3)" - # @atom:81L "Alkane -CH2- (LOPLS CT_CH2)" - # @atom:85LCH3 "Alkane H-C CH3 (LOPLS HC_CH3)" - # @atom:85LCH2 "Alkane H-C CH2 (LOPLS HC_CH2)" - # In this example, atomic charges are generated by atom type (according to the - # rules in loplsaa.lt), and can be omitted. Just leave them as "0.00" for now. - # The "..." in "$mol:..." tells moltemplate that this molecule may be part - # of a larger molecule, and (if so) to use the larger parent object's - # molecule id number as it's own. - -} # CH2 - - - - - - - - - - - - - - - -# Optional: Shift all the coordinates in the +Y direction by 0.4431163. -# This way, the carbon atom is no longer located at 0,0,0, but the -# axis of an alkane chain containing this monomer is at 0,0,0. -# (This makes it more convenient to construct a polymer later. -# If this is confusing, then simply add 0.4431163 to the Y -# coordinates in the "Data Atoms" section above.) - -CH2.move(0,0.4431163,0) - - - - -######### (scratchwork calculations for the atomic coordinates) ######### -# Lcc = 1.5350 # length of the C-C bond (Sp3) -# Lch = 1.0930 # length of the C-H bond -# theta=2*atan(sqrt(2)) # ~= 109.5 degrees = tetrahedronal angle (C-C-C angle) -# DeltaXc = Lcc*sin(theta/2) # = 1.2533222517240594 -# DeltaYc = Lcc*cos(theta/2) # = 0.8862326632060754 -# # 0.5*DeltaYc = 0.4431163 -# DeltaZh = Lch*sin(theta/2) # = 0.892431 -# DeltaYh = Lch*cos(theta/2) # = 0.631044 diff --git a/tools/moltemplate/examples/force_field_OPLSAA/hexadecane/moltemplate_files/ch3group.lt b/tools/moltemplate/examples/force_field_OPLSAA/hexadecane/moltemplate_files/ch3group.lt deleted file mode 100644 index b01c8c0cd2..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/hexadecane/moltemplate_files/ch3group.lt +++ /dev/null @@ -1,83 +0,0 @@ -# This file contains a definition for the "CH3" molecular subunit. - -# First, load the OPLS force field parameters we will need. -# These 2 files are located in the "src/moltemplate_force_fields/" subdirectory: - -import "oplsaa.lt" # <-- defines the standard "OPLSAA" force field -import "loplsaa.lt" # <-- custom parameters for long alkane chains taken from - # Sui et al. J.Chem.Theory.Comp (2012), 8, 1459 - # To use the ordinary OPLSAA force field parameters, - # (instead of the Sui et al. parameters), change the - # atom types below from "@atom:80L","@atom:85LCH3" to - # "@atom:80" and "@atom:85" (defined in "oplsaa.lt") - - - -# Then define "CH3": - - -CH3 inherits OPLSAA { - - # atom-id mol-id atom-type charge x y z - - write("Data Atoms") { - $atom:C $mol:... @atom:80L 0.0 0.000000 0.000000 0.000000 - $atom:H1 $mol:... @atom:85LCH3 0.0 0.000000 0.631044 0.892431 - $atom:H2 $mol:... @atom:85LCH3 0.0 0.000000 0.631044 -0.892431 - $atom:H3 $mol:... @atom:85LCH3 0.0 -0.892431 -0.631044 0.000000 - } - - write('Data Bond List') { - $bond:CH1 $atom:C $atom:H1 - $bond:CH2 $atom:C $atom:H2 - $bond:CH3 $atom:C $atom:H3 - } - - # Atom type numbers (@atom:80L,@atom:85LCH3) are defined in "loplsaa.lt", - # @atom:80L "Alkane CH3- (LOPLS CT_CH3)" - # @atom:81L "Alkane -CH2- (LOPLS CT_CH2)" - # @atom:85LCH3 "Alkane H-C CH3 (LOPLS HC_CH3)" - # @atom:85LCH2 "Alkane H-C CH2 (LOPLS HC_CH2)" - # In this example, atomic charges are generated by atom type (according to the - # rules in loplsaa.lt), and can be omitted. Just leave them as "0.00" for now. - # The "..." in "$mol:..." tells moltemplate that this molecule may be part - # of a larger molecule, and (if so) to use the larger parent object's - # molecule id number as it's own. - -} # CH3 - - - - - - - - - - - - - - - -# Optional: Shift all the coordinates in the +Y direction by 0.4431163. -# This way, the carbon atom is no longer located at 0,0,0, but the -# axis of an alkane chain containing this monomer is at 0,0,0. -# (This makes it more convenient to construct a polymer later. -# If this is confusing, then simply add 0.4431163 to the Y -# coordinates in the "Data Atoms" section above.) - -CH3.move(0,0.4431163,0) - - - - -######### (scratchwork calculations for the atomic coordinates) ######### -# Lcc = 1.5350 # length of the C-C bond (Sp3) -# Lch = 1.0930 # length of the C-H bond -# theta=2*atan(sqrt(2)) # ~= 109.5 degrees = tetrahedronal angle (C-C-C angle) -# DeltaXc = Lcc*sin(theta/2) # = 1.2533222517240594 -# DeltaYc = Lcc*cos(theta/2) # = 0.8862326632060754 -# # 0.5*DeltaYc = 0.4431163 -# DeltaZh = Lch*sin(theta/2) # = 0.892431 -# DeltaYh = Lch*cos(theta/2) # = 0.631044 diff --git a/tools/moltemplate/examples/force_field_OPLSAA/hexadecane/moltemplate_files/hexadecane.lt b/tools/moltemplate/examples/force_field_OPLSAA/hexadecane/moltemplate_files/hexadecane.lt deleted file mode 100644 index 96e9e6b4bf..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/hexadecane/moltemplate_files/hexadecane.lt +++ /dev/null @@ -1,79 +0,0 @@ -# This example looks complicated because I split the -# hexadecane molecule into individual CH2 and CH3 monomers. -# -# I defined it this way so that you can easily modify -# it to change the length of the alkane chain. - - -import "oplsaa.lt" # load the "OPLSAA" force-field information -import "ch2group.lt" # load the definition of the "CH2" object -import "ch3group.lt" # load the definition of the "CH3" object - - - -Hexadecane inherits OPLSAA { - - - create_var {$mol} # optional:force all monomers to share the same molecule-ID - - - # Now create an array of 16 "CH2" objects distributed along the X axis - - monomers = new CH2 [16].rot(180,1,0,0).move(1.2533223,0,0) - - # Each monomer is rotated 180 degrees with respect to the previous - # monomer, and then moved 1.2533223 Angstroms down the X axis. - - # ---- Now, modify the ends: --- - # Delete the CH2 groups at the beginning and end, and replace them with CH3. - - delete monomers[0] - delete monomers[15] - - monomers[0] = new CH3 - monomers[15] = new CH3 - - # Move the CH3 groups to the correct location at either end of the chain: - - monomers[15].rot(180.0,0,0,1).move(18.7998345,0,0) - # Note: 18.7998345 = (16-1) * 1.2533223 - - - # Now add a list of bonds connecting the carbon atoms together: - - write('Data Bond List') { - $bond:b1 $atom:monomers[0]/C $atom:monomers[1]/C - $bond:b2 $atom:monomers[1]/C $atom:monomers[2]/C - $bond:b3 $atom:monomers[2]/C $atom:monomers[3]/C - $bond:b4 $atom:monomers[3]/C $atom:monomers[4]/C - $bond:b5 $atom:monomers[4]/C $atom:monomers[5]/C - $bond:b6 $atom:monomers[5]/C $atom:monomers[6]/C - $bond:b7 $atom:monomers[6]/C $atom:monomers[7]/C - $bond:b8 $atom:monomers[7]/C $atom:monomers[8]/C - $bond:b9 $atom:monomers[8]/C $atom:monomers[9]/C - $bond:b10 $atom:monomers[9]/C $atom:monomers[10]/C - $bond:b11 $atom:monomers[10]/C $atom:monomers[11]/C - $bond:b12 $atom:monomers[11]/C $atom:monomers[12]/C - $bond:b13 $atom:monomers[12]/C $atom:monomers[13]/C - $bond:b14 $atom:monomers[13]/C $atom:monomers[14]/C - $bond:b15 $atom:monomers[14]/C $atom:monomers[15]/C - } - -} # Hexadecane - - - - - - - - -######### (scratchwork calculations for the atomic coordinates) ######### -# Lcc = 1.5350 # length of the C-C bond (Sp3) -# Lch = 1.0930 # length of the C-H bond -# theta=2*atan(sqrt(2)) # ~= 109.5 degrees = tetrahedronal angle (C-C-C angle) -# DeltaXc = Lcc*sin(theta/2) # = 1.2533222517240594 -# DeltaYc = Lcc*cos(theta/2) # = 0.8862326632060754 -# # 0.5*DeltaYc = 0.4431163316030377 -# DeltaZh = Lch*sin(theta/2) # = 0.8924307629540046 -# DeltaYh = Lch*cos(theta/2) # = 0.6310438442242609 diff --git a/tools/moltemplate/examples/force_field_OPLSAA/hexadecane/moltemplate_files/oplsaa_lt_generator/AUTHOR.TXT b/tools/moltemplate/examples/force_field_OPLSAA/hexadecane/moltemplate_files/oplsaa_lt_generator/AUTHOR.TXT deleted file mode 100644 index d5e469af37..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/hexadecane/moltemplate_files/oplsaa_lt_generator/AUTHOR.TXT +++ /dev/null @@ -1,3 +0,0 @@ - -OPLSAA force-field conversion tools provided by Jason Lambert. - diff --git a/tools/moltemplate/examples/force_field_OPLSAA/hexadecane/moltemplate_files/oplsaa_lt_generator/README.TXT b/tools/moltemplate/examples/force_field_OPLSAA/hexadecane/moltemplate_files/oplsaa_lt_generator/README.TXT deleted file mode 100644 index 5b6e32d845..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/hexadecane/moltemplate_files/oplsaa_lt_generator/README.TXT +++ /dev/null @@ -1,108 +0,0 @@ -This directory contains instructions for creating a a moltemplate file -("oplsaa.lt") containing force-field definitions relevant to the -"ethylene" example. (However, these instructions should work -for other molecules too.) - -First, check and see if there is an "oplsaa_subset.prm" file present. -If not, then download this file: - -http://dasher.wustl.edu/tinker/distribution/params/oplsaa.prm - This file is also available here: -http://dasher.wustl.edu/ffe/distribution/params/oplsaa.prm - -and save this file as "oplsaa_subset.prm". Then you must EDIT THIS FILE -so that it only contains atom types you plan to have in your simulation -(see below for details). Then run the opls_moltemplate.py script this way: - - -oplsaa_moltemplate.py oplsaa_subset.prm - - -This will create a file named "oplsaa.lt" -Look over the newly created "oplsaa.lt" file. -Then move this file to wherever you plan to run moltemplate. For example: - -mv -f oplsaa.lt .. - ------ DETAILS: Editing the "oplsaa_subset.prm" file ------- - -Again, before you run "oplsaa_moltemplate.py", you must edit the "oplsaa.prm" -file (or "oplsaa_subset.prm file) and eliminate atom types which do not -correspond to any of the atoms in your simulation. This means you must -look for lines near the beginning of this file which begin with the word "atom" -and refer to atom types which appear in the simulation you plan to run. All -other lines (beginning with the word "atom") must be deleted or commented out. -(Leave the rest of the file alone.) - -For example: -If you were working with ethylene, you would delete every line -beginning with the word "atom", except for these two lines: - - -atom 80 13 CT "Alkane CH3-" 6 12.011 4 -atom 81 13 CT "Alkane -CH2-" 6 12.011 4 -atom 85 46 HC "Alkane H-C" 1 1.008 1 - - -Then you are ready to run oplsaa_moltemplate.py on this file. - -(Note: Atom type numbers, like "88", "89", "47", etc... may vary depending on - when you downloaded "oplsaa.prm".) - - ------ Using the "oplsaa.lt" file ----- - -Once you have created the "oplsaa.lt" file, you can create files (like -ethylene.lt) which define molecules that refer to these atom types. -Here is an excerpt from "ethyelene.lt": - -import "oplsaa.lt" -Ethylene inherits OPLSAA { - write('Data Atoms') { - list of atoms goes here ... - } - write('Data Bond List') { - list of bonds goes here ... - } -} - -And then run moltemplate. - - ------------ CHARGE: ----------- - -By default, the OPLSAA force-field assigns atom charge according to atom type. -When you run moltemplate, it will create a file named "system.in.charges", -containing commands like: - -set type 2 charge -0.42 -set type 3 charge 0.21 - -(This assumes your main moltemplate file is named "system.lt". If it was -named something else, eg "polymer.lt", then the file created by moltemplate -will be named "polymer.in.charges".) - -Include these commands somewhere in your LAMMPS input script -(or use the LAMMPS "include" command to load the commands in system.in.charges) - -Note that the atom numbers (eg "2", "3") in this file will not match the -OPLS atom numbers. (Check the output_ttree/ttree_assignments.txt file, -created by moltemplate, to see a table of "@atom" type numbers translated -from OPLSAA into LAMMPS.) - ------------ CREDIT ----------- - -If you use these tools and you publish a paper using OPLSAA, please also cite -the TINKER program. (Because these examples use the "oplsaa.prm" file which -is distributed with TINKER.) I think these are the relevant citations: - -1) Ponder, J. W., & Richards, F. M. (1987). "An efficient newtonâ€like method for molecular mechanics energy minimization of large molecules. Journal of Computational Chemistry", 8(7), 1016-1024. - -2) Ponder, J. W, (2004) "TINKER: Software tools for molecular design", http://dasher.wustl.edu/tinker/ - -------------------------------- - -Jason Lambert and Andrew Jewett -December 14 2014 - -Please email bugs to jewett.aij@gmail.com and jlamber9@gmail.com diff --git a/tools/moltemplate/examples/force_field_OPLSAA/hexadecane/moltemplate_files/oplsaa_lt_generator/oplsaa_subset.prm b/tools/moltemplate/examples/force_field_OPLSAA/hexadecane/moltemplate_files/oplsaa_lt_generator/oplsaa_subset.prm deleted file mode 100644 index 1260acdbd3..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/hexadecane/moltemplate_files/oplsaa_lt_generator/oplsaa_subset.prm +++ /dev/null @@ -1,151 +0,0 @@ -# This file is a heavily redacted version of the "oplsaa.prm" file distributed -# with TINKER (Downloaded April, 2014). This version only contains information -# relevant to alkane chains. The complete version of that file works with most -# small organic molecules and you can use that file with moltemplate too. -# Unfortunately, I do not own or have permission to distribute that file. -# You can download the latest complete version of that file here: -# -# http://dasher.wustl.edu/tinker/distribution/params/oplsaa.prm -# -# When building your own molecules, you should download this file, and delete -# only the lines from the "atoms" section which you don't need. (But leave the -# rest of that file alone. I deleted other sections of this file here in order -# to reduce the file size, but this is not necessary.) -# -# Rename the resulting file "oplsaa_subset.prm" -# -# Then you can create an oplsaa.lt file (which moltemplate.sh needs) this way: -# oplsaa_moltemplate.py oplsaa_subset.prm -# -# Then copy the newly created "oplsa.lt" file to the directory where you -# plan to run moltemplate, and run moltemplate: -# moltemplate system.lt - - - ############################## - ## ## - ## Force Field Definition ## - ## ## - ############################## - - -forcefield OPLS-AA - -vdwindex TYPE -vdwtype LENNARD-JONES -radiusrule GEOMETRIC -radiustype SIGMA -radiussize DIAMETER -epsilonrule GEOMETRIC -torsionunit 0.5 -imptorunit 0.5 -vdw-14-scale 2.0 -chg-14-scale 2.0 -electric 332.06 -dielectric 1.0 - - - ############################# - ## ## - ## Literature References ## - ## ## - ############################# - - -The parameters supplied with TINKER are from "OPLS All-Atom Parameters -for Organic Molecules, Ions, Peptides & Nucleic Acids, July 2008" as -provided by W. L. Jorgensen, Yale University during June 2009. These -parameters are taken from those distributed with BOSS Version 4.8. - -Note that "atom type" numbers and not "atom class" numbers are used -to index van der Waals parameters, see the "vdwindex" keyword above - -The atom types with (UA) in the description are "united atom" values, -ie, OPLS-UA, where any nonpolar hydrogen atoms are combined onto their -attached atoms. All other parameters are "all-atom", OPLS-AA, including -explicit hydrogen atoms. - - - ############################# - ## ## - ## Atom Type Definitions ## - ## ## - ############################# - - -atom 80 13 CT "Alkane CH3-" 6 12.011 4 -atom 81 13 CT "Alkane -CH2-" 6 12.011 4 -atom 85 46 HC "Alkane H-C" 1 1.008 1 - - - ################################ - ## ## - ## Van der Waals Parameters ## - ## ## - ################################ - - -vdw 80 3.5000 0.0660 -vdw 81 3.5000 0.0660 -vdw 85 2.5000 0.0300 - - -bond 13 13 268.00 1.5290 -bond 13 46 340.00 1.0900 - - - ################################ - ## ## - ## Angle Bending Parameters ## - ## ## - ################################ - - -angle 13 13 13 58.35 112.70 -angle 46 13 46 33.00 107.80 -angle 13 13 46 37.50 110.70 - - - ############################ - ## ## - ## Torsional Parameters ## - ## ## - ############################ - - - ################################################################### - ## ## - ## Alternative Torsional Parameter Values for Use with OPLS-AA ## - ## ## - ## For some torsions, OPLS-AA has multiple possible parameter ## - ## values; the list below shows functional groups for which ## - ## these alternate (commented) values should be preferred; the ## - ## values are in the same order as in the full parameter list ## - ## ## - ## 13 13 13 13 hydrocarbon (default) ## - ## 13 13 13 13 perfluoroalkane ## - ## ## - ################################################################### - - -torsion 0 13 13 13 1.711 0.0 1 -0.500 180.0 2 0.663 0.0 3 -#torsion 0 13 13 13 -1.336 0.0 1 0.000 180.0 2 0.000 0.0 3 -torsion 13 13 13 13 1.300 0.0 1 -0.050 180.0 2 0.200 0.0 3 -#torsion 13 13 13 13 6.622 0. 1 0.948 180. 2 -1.388 0. 3 -2.118 180. 4 -torsion 13 13 13 46 0.000 0.0 1 0.000 180.0 2 0.300 0.0 3 -torsion 46 13 13 46 0.000 0.0 1 0.000 180.0 2 0.300 0.0 3 - - - - - ######################################## - ## ## - ## Atomic Partial Charge Parameters ## - ## ## - ######################################## - - -charge 80 -0.1800 -charge 81 -0.1200 -charge 85 0.0600 - diff --git a/tools/moltemplate/examples/force_field_OPLSAA/hexadecane/moltemplate_files/system.lt b/tools/moltemplate/examples/force_field_OPLSAA/hexadecane/moltemplate_files/system.lt deleted file mode 100644 index 4e0cfaec69..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/hexadecane/moltemplate_files/system.lt +++ /dev/null @@ -1,18 +0,0 @@ -import "hexadecane.lt" # <- defines the "Hexadecane" molecule type. - -# Periodic boundary conditions: -write_once("Data Boundary") { - 0.0 62.4 xlo xhi - 0.0 62.4 ylo yhi - 0.0 62.4 zlo zhi -} - -molecules = new Hexadecane [12].move(0, 0, 5.2) - [12].move(0, 5.2, 0) - [2].move(31.2, 0, 0) - - -# NOTE: The spacing between molecules is large. There should be extra room to -# move during the initial stages of equilibration. However, you will have to -# run the simulation at NPT conditions later to compress the system to a -# more realistic density. diff --git a/tools/moltemplate/examples/force_field_OPLSAA/hexadecane/run.in.npt b/tools/moltemplate/examples/force_field_OPLSAA/hexadecane/run.in.npt deleted file mode 100644 index 1b1a28fabc..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/hexadecane/run.in.npt +++ /dev/null @@ -1,87 +0,0 @@ -# PREREQUISITES: -# -# You must use moltemplate.sh to create 3 files: -# system.data system.in.init system.in.settings -# (Follow the instructions in README_setup.sh, -# or run the file as a script using ./README_setup.sh) - -# ------------------------------- Initialization Section -------------------- - -include system.in.init - -# ------------------------------- Atom Definition Section ------------------- - -read_data system.data - -# ------------------------------- Settings Section -------------------------- - -include system.in.settings -include system.in.charges - -# ------------------------------- Run Section ------------------------------- - -# To avoid explosions, I have a 4-step equilibraion process (expand, minimize, -# reorient, compress). The system (as defined in the "system.data" file) -# is already expanded. That means there are 3 steps left: - -dump dumpeq1 all custom 50 traj_eq1_min.lammpstrj id mol type x y z ix iy iz -thermo 50 - -# -- Equilibration: part 1: initial minimization -- - -# Note: In general, it's always a good idea to minimize the system at first. - -minimize 1.0e-5 1.0e-7 100000 400000 -undump dumpeq1 - -write_data system_after_eq1_min.data - -# -- Equilibration part 2: reorienting the molecules (NVT) -- - -timestep 1.0 -dump dumpeq2 all custom 200 traj_eq2_reorient.lammpstrj id mol type x y z ix iy iz - -# Run the system at high temperature (at constant volume) to reorient the -# the molecules (which would otherwise be pointing in the same direction). - -# To speed it up, I randomize the atomic positions for a few thousand steps -# using fix langevin (and fix nve). Then I switch to fix nvt (Nose-Hoover). -# (If I start with fix nvt (Nose-Hoover), it seems to get "stuck" for a while.) - - -fix fxlan all langevin 900.0 900.0 120 48279 -fix fxnve all nve - -run 4000 - -unfix fxlan -unfix fxnve -# Now continue the simulation at high temperature using fix nvt (Nose-Hoover). -fix fxnvt all nvt temp 900.0 900.0 100.0 - -run 50000 -undump dumpeq2 - - -write_data system_after_eq2_reorient.data - -unfix fxnvt - -# -- equilibration part 3: Equilibrating the density (NPT) -- - -# Originally, the simulation box (in "system.data" and "system.lt") was -# unrealistically large. The spacing between the molecules was large also. -# I did this to enable the molecules to move freely and reorient themselves. -# After doing that, we should run the simulation under NPT conditions to -# allow the simulation box to contract to it's natural size. We do that here: -# We begin the simulation at 100 barr (a relatively low pressure), and -# slowly decrease it to 1 barr, maintianing the temperature at 300K. - -dump dumpeq3 all custom 200 traj_eq3_npt.lammpstrj id mol type x y z ix iy iz -fix fxnpt all npt temp 900.0 300.0 100.0 iso 100.0 1.0 1000.0 drag 2.0 - -timestep 1.0 -run 100000 - -write_data system_after_eq3_npt.data - diff --git a/tools/moltemplate/examples/force_field_OPLSAA/hexadecane/run.in.nvt b/tools/moltemplate/examples/force_field_OPLSAA/hexadecane/run.in.nvt deleted file mode 100644 index 38815745c5..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/hexadecane/run.in.nvt +++ /dev/null @@ -1,44 +0,0 @@ -# PREREQUISITES: -# -# 1) You must use moltemplate.sh to create 3 files: -# system.data system.in.init system.in.settings -# (Follow the instructions in README_setup.sh, -# or run the file as a script using ./README_setup.sh) -# 2) You must equilibrate the system beforehand using "run.in.npt". -# This will create the file "system_after_npt.data" which this file reads. -# (Note: I have not verified that this equilibration protocol works well.) - -# ------------------------------- Initialization Section -------------------- - -include system.in.init - -# ------------------------------- Atom Definition Section ------------------- - - -# Read the coordinates generated by an earlier NPT simulation - -read_data system_after_eq3_npt.data - -# (The "write_restart" and "read_restart" commands were buggy in 2012, -# but they should work also. I prefer "write_data" and "read_data".) - - -# ------------------------------- Settings Section -------------------------- - -include system.in.settings -include system.in.charges - -# ------------------------------- Run Section ------------------------------- - -# -- simulation protocol -- - - -timestep 1.0 -dump 1 all custom 500 traj_nvt.lammpstrj id mol type x y z ix iy iz -fix fxnvt all nvt temp 350.0 350.0 500.0 tchain 1 -thermo 100 -#thermo_modify flush yes - -run 50000 - -write_data system_after_nvt.data diff --git a/tools/moltemplate/examples/force_field_OPLSAA/methane/README.TXT b/tools/moltemplate/examples/force_field_OPLSAA/methane/README.TXT deleted file mode 100644 index 9f9e9d0994..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/methane/README.TXT +++ /dev/null @@ -1,24 +0,0 @@ -This example demonstrates how to build a simulation containing a box of methane. -(Not a very interesting example.) - ----- Details ---- - -The methane molecules in this example use the OPLSAA force-field. -This means that the database of force-field parameters in "oplsaa.lt" -will be used to generate angles, dihedrals, and impropers. -The "moltemplate_files/methane.lt" file -contains these lines which refer to OPLSAA: - -import "oplsaa.lt" -Methane inherits OPLSAA { ... - --------- Instructions: --------- - -More detailed instructions on how to build LAMMPS input files and -run a short simulation are provided in other README files. - -step 1) -README_setup.sh - -step 2) -README_run.sh diff --git a/tools/moltemplate/examples/force_field_OPLSAA/methane/README_run.sh b/tools/moltemplate/examples/force_field_OPLSAA/methane/README_run.sh deleted file mode 100755 index 5f82866644..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/methane/README_run.sh +++ /dev/null @@ -1,34 +0,0 @@ -# --- Running LAMMPS --- -# -# The 2 files "run.in.npt", and "run.in.nvt" are LAMMPS -# input scripts which link to the input scripts and data files -# you hopefully have created earlier with moltemplate.sh: -# system.in.init, system.in.settings, system.data -# If not, carry out the instructions in "README_setup.sh". -# -# -- Instructions: -- -# If "lmp_mpi" is the name of the command you use to invoke lammps, -# then you would run lammps on these files this way: - - -lmp_mpi -i run.in.npt # minimization and simulation at constant pressure -lmp_mpi -i run.in.nvt # minimization and simulation at constant volume - -#(Note: The constant volume simulation lacks pressure equilibration. These are -# completely separate simulations. The results of the constant pressure -# simulation might be ignored when beginning the simulation at constant -# volume. (This is because restart files in LAMMPS don't always work, -# and I was spending a lot of time trying to convince people it was a -# LAMMPS bug, instead of a moltemplate bug, so I disabled restart files.) -# Read the "run.in.nvt" file to find out how to use the "read_restart" -# command to load the results of the pressure-equilibration simulation, -# before beginning a constant-volume run. - - - - - -# If you have compiled the MPI version of lammps, you can run lammps in parallel -#mpirun -np 4 lmp_mpi -i run.in.npt -#mpirun -np 4 lmp_mpi -i run.in.nvt -# (assuming you have 4 processors available) diff --git a/tools/moltemplate/examples/force_field_OPLSAA/methane/README_setup.sh b/tools/moltemplate/examples/force_field_OPLSAA/methane/README_setup.sh deleted file mode 100755 index 6aa6c06f4c..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/methane/README_setup.sh +++ /dev/null @@ -1,28 +0,0 @@ - -# Create LAMMPS input files this way: -cd moltemplate_files - - # run moltemplate - - moltemplate.sh system.lt - - # This will generate various files with names ending in *.in* and *.data. - # Move them to the directory where you plan to run LAMMPS (in this case "../") - mv -f system.data system.in* ../ - - # Optional: - # The "./output_ttree/" directory is full of temporary files generated by - # moltemplate. They can be useful for debugging, but are usually thrown away. - rm -rf output_ttree/ - -cd ../ - - - - -# Optional: -# Note: The system.data and system.in.settings files contain extra information -# for atoms defined in OPLSAA which you are not using in this simulation. This -# is harmless, but if you to delete this information from your -# system.in.settings and system.in.data files, follow the instructions in -# this script: "optional_cleanup/README_remove_irrelevant_info.sh" diff --git a/tools/moltemplate/examples/force_field_OPLSAA/methane/README_visualize.txt b/tools/moltemplate/examples/force_field_OPLSAA/methane/README_visualize.txt deleted file mode 100644 index 019afc1444..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/methane/README_visualize.txt +++ /dev/null @@ -1,87 +0,0 @@ - - ------- To view a lammps trajectory in VMD -------- - - -1) Build a PSF file for use in viewing with VMD. - -This step works with VMD 1.9 and topotools 1.2. -(Older versions, like VMD 1.8.6, don't support this.) - - -a) Start VMD -b) Menu Extensions->Tk Console -c) Enter: - -(I assume that the the DATA file is called "system.data") - - topo readlammpsdata system.data full - animate write psf system.psf - -2) - -Later, to Load a trajectory in VMD: - - Start VMD - Select menu: File->New Molecule - -Browse to select the PSF file you created above, and load it. - (Don't close the window yet.) - -Browse to select the trajectory file. - If necessary, for "file type" select: "LAMMPS Trajectory" - Load it. - - ---- A note on trajectory format: ----- -If the trajectory is a DUMP file, then make sure the it contains the -information you need for pbctools (see below. I've been using this -command in my LAMMPS scripts to create the trajectories: - - dump 1 all custom 5000 DUMP_FILE.lammpstrj id mol type x y z ix iy iz - -It's a good idea to use an atom_style which supports molecule-ID numbers -so that you can assign a molecule-ID number to each atom. (I think this -is needed to wrap atom coordinates without breaking molecules in half.) - -Of course, you don't have to save your trajectories in DUMP format, -(other formats like DCD work fine) I just mention dump files -because these are the files I'm familiar with. - -3) ----- Wrap the coordinates to the unit cell - (without cutting the molecules in half) - -a) Start VMD -b) Load the trajectory in VMD (see above) -c) Menu Extensions->Tk Console -d) Try entering these commands: - - pbc wrap -compound res -all - pbc box - - ----- Optional ---- - Sometimes the solvent or membrane obscures the view of the solute. - It can help to shift the location of the periodic boundary box - To shift the box in the y direction (for example) do this: - - pbc wrap -compound res -all -shiftcenterrel {0.0 0.15 0.0} - pbc box -shiftcenterrel {0.0 0.15 0.0} - - Distances are measured in units of box-length fractions, not Angstroms. - - Alternately if you have a solute whose atoms are all of type 1, - then you can also try this to center the box around it: - - pbc wrap -sel type=1 -all -centersel type=2 -center com - -4) - You should check if your periodic boundary conditions are too small. - To do that: - select Graphics->Representations menu option - click on the "Periodic" tab, and - click on the "+x", "-x", "+y", "-y", "+z", "-z" checkboxes. - -5) Optional: If you like, change the atom types in the PSF file so - that VMD recognizes the atom types, use something like: - -sed -e 's/ 1 1 / C C /g' < system.psf > temp1.psf -sed -e 's/ 2 2 / H H /g' < temp1.psf > temp2.psf -sed -e 's/ 3 3 / P P /g' < temp2.psf > system.psf - -(If you do this, it might effect step 2 above.) diff --git a/tools/moltemplate/examples/force_field_OPLSAA/methane/moltemplate_files/methane.lt b/tools/moltemplate/examples/force_field_OPLSAA/methane/moltemplate_files/methane.lt deleted file mode 100644 index bb8f0469cf..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/methane/moltemplate_files/methane.lt +++ /dev/null @@ -1,32 +0,0 @@ -import "oplsaa.lt" - -# Atom type numbers are from the "oplsaa_subset.prm" -# file used to generate "oplsaa.lt". - -# atom 83 13 CT "Methane CH4" -# atom 85 46 HC "Alkane H-C" - -Methane inherits OPLSAA { - - # atomID molID atomTyle charge X Y Z - write('Data Atoms') { - $atom:C $mol:. @atom:83 0.0 0.000000 0.000000 0.000000 - $atom:H1 $mol:. @atom:85 0.0 0.000000 0.000000 1.089000 - $atom:H2 $mol:. @atom:85 0.0 1.026719 0.000000 -0.363000 - $atom:H3 $mol:. @atom:85 0.0 -0.513360 -0.889165 -0.363000 - $atom:H4 $mol:. @atom:85 0.0 -0.513360 0.889165 -0.363000 - } - - # Charges will be assigned by OPLSAA, so we leave them 0.0 here. - # - # (The "." in "$mol:." refers to this molecule-object's molecule-ID number. - # The "." simply means this molecule is not a part of a larger molecule.) - - write('Data Bond List') { - $bond:CH1 $atom:C $atom:H1 - $bond:CH2 $atom:C $atom:H2 - $bond:CH3 $atom:C $atom:H3 - $bond:CH4 $atom:C $atom:H4 - } - -} # Methane diff --git a/tools/moltemplate/examples/force_field_OPLSAA/methane/moltemplate_files/oplsaa_lt_generator/AUTHOR.TXT b/tools/moltemplate/examples/force_field_OPLSAA/methane/moltemplate_files/oplsaa_lt_generator/AUTHOR.TXT deleted file mode 100644 index d5e469af37..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/methane/moltemplate_files/oplsaa_lt_generator/AUTHOR.TXT +++ /dev/null @@ -1,3 +0,0 @@ - -OPLSAA force-field conversion tools provided by Jason Lambert. - diff --git a/tools/moltemplate/examples/force_field_OPLSAA/methane/moltemplate_files/oplsaa_lt_generator/README.TXT b/tools/moltemplate/examples/force_field_OPLSAA/methane/moltemplate_files/oplsaa_lt_generator/README.TXT deleted file mode 100644 index 3336341da8..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/methane/moltemplate_files/oplsaa_lt_generator/README.TXT +++ /dev/null @@ -1,108 +0,0 @@ -This directory contains instructions for creating a a moltemplate file -("oplsaa.lt") containing force-field definitions relevant to the "Methane" -molecule. (However, these instructions should work for other molecules too.) - ---- Instructions --- - -First, check and see if there is an "oplsaa_subset.prm" file present. -If not, then download this file: - -http://dasher.wustl.edu/tinker/distribution/params/oplsaa.prm - This file is also available here: -http://dasher.wustl.edu/ffe/distribution/params/oplsaa.prm - -and save this file as "oplsaa_subset.prm". Then you must EDIT THIS FILE -so that it only contains atom types you plan to have in your simulation -(see below for details). Then run the opls_moltemplate.py script this way: - - -oplsaa_moltemplate.py oplsaa_subset.prm - - -This will create a file named "oplsaa.lt" -Look over the newly created "oplsaa.lt" file. -Then move this file to wherever you plan to run moltemplate. For example: - -mv -f oplsaa.lt .. - ------ DETAILS: Editing the "oplsaa_subset.prm" file ------- - -Again, before you run "oplsaa_moltemplate.py", you must edit the "oplsaa.prm" -file (or "oplsaa_subset.prm file) and eliminate atom types which do not -correspond to any of the atoms in your simulation. This means you must -look for lines near the beginning of this file which begin with the word "atom" -and refer to atom types which appear in the simulation you plan to run. All -other lines (beginning with the word "atom") must be deleted or commented out. -(Leave the rest of the file alone.) - -For example: -If you were working with methane, you would delete every line -beginning with the word "atom", except for these two lines: - - -atom 83 13 CT "Methane CH4" 6 12.011 4 -atom 85 46 HC "Alkane H-C" 1 1.008 1 - - -Then you are ready to run oplsaa_moltemplate.py on this file. - -(Note: Atom type numbers, like "83", "85", "46", etc... may vary depending on - when you downloaded "oplsaa.prm".) - - ------ Using the "oplsaa.lt" file ----- - -Once you have created the "oplsaa.lt" file, you can create files (like -ethylene.lt) which define molecules that refer to these atom types. -Here is an excerpt from "methane.lt": - -import "oplsaa.lt" -Methane inherits OPLSAA { - write('Data Atoms') { - list of atoms goes here ... - } - write('Data Bond List') { - list of bonds goes here ... - } -} - -And then run moltemplate. - - ------------ CHARGE: ----------- - -By default, the OPLSAA force-field assigns atom charge according to atom type. -When you run moltemplate, it will create a file named "system.in.charges", -containing commands like: - -set type 2 charge -0.42 -set type 3 charge 0.21 - -(This assumes your main moltemplate file is named "system.lt". If it was -named something else, eg "polymer.lt", then the file created by moltemplate -will be named "polymer.in.charges".) - -Include these commands somewhere in your LAMMPS input script -(or use the LAMMPS "include" command to load the commands in system.in.charges) - -Note that the atom numbers (eg "2", "3") in this file will not match the -OPLS atom numbers. (Check the output_ttree/ttree_assignments.txt file, -created by moltemplate, to see a table of "@atom" type numbers translated -from OPLSAA into LAMMPS.) - ------------ CREDIT ----------- - -If you use these tools and you publish a paper using OPLSAA, please also cite -the TINKER program. (Because these examples use the "oplsaa.prm" file which -is distributed with TINKER.) I think these are the relevant citations: - -1) Ponder, J. W., & Richards, F. M. (1987). "An efficient newtonâ€like method for molecular mechanics energy minimization of large molecules. Journal of Computational Chemistry", 8(7), 1016-1024. - -2) Ponder, J. W, (2004) "TINKER: Software tools for molecular design", http://dasher.wustl.edu/tinker/ - -------------------------------- - -Andrew Jewett and Jason Lambert -May, 2014 - -Please email bugs to jewett.aij@gmail.com and jlamber9@gmail.com diff --git a/tools/moltemplate/examples/force_field_OPLSAA/methane/moltemplate_files/oplsaa_lt_generator/oplsaa_subset.prm b/tools/moltemplate/examples/force_field_OPLSAA/methane/moltemplate_files/oplsaa_lt_generator/oplsaa_subset.prm deleted file mode 100644 index 5f982059b3..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/methane/moltemplate_files/oplsaa_lt_generator/oplsaa_subset.prm +++ /dev/null @@ -1,115 +0,0 @@ -# This is a modified version of the file "oplsaa.prm" distributed with TINKER -# http://dasher.wustl.edu/tinker/distribution/params/oplsaa.prm -# In this version, all of the lines beginning with "atom" have been deleted -# except for the atom types we will be using in this simulation -# (I also deleted some other lines from that file data to reduce the file size, -# but doing that is not necessary.) -# -# If you use this file, please also cite the software this file comes from: -# -# Ponder, J. W., and Richards, F. M. J. Comput. Chem. (1987) 8(7), 1016-1024 -# "An efficient newtonâ€like method for molecular mechanics energy -# minimization of large molecules." -# -# Ponder, J. W, (2004) -# "TINKER: Software tools for molecular design" -# http://dasher.wustl.edu/tinker/ - - ############################## - ## ## - ## Force Field Definition ## - ## ## - ############################## - - -forcefield OPLS-AA - -vdwindex TYPE -vdwtype LENNARD-JONES -radiusrule GEOMETRIC -radiustype SIGMA -radiussize DIAMETER -epsilonrule GEOMETRIC -torsionunit 0.5 -imptorunit 0.5 -vdw-14-scale 2.0 -chg-14-scale 2.0 -electric 332.06 -dielectric 1.0 - - - ############################# - ## ## - ## Literature References ## - ## ## - ############################# - - -The parameters supplied with TINKER are from "OPLS All-Atom Parameters -for Organic Molecules, Ions, Peptides & Nucleic Acids, July 2008" as -provided by W. L. Jorgensen, Yale University during June 2009. These -parameters are taken from those distributed with BOSS Version 4.8. - -Note that "atom type" numbers and not "atom class" numbers are used -to index van der Waals parameters, see the "vdwindex" keyword above - -The atom types with (UA) in the description are "united atom" values, -ie, OPLS-UA, where any nonpolar hydrogen atoms are combined onto their -attached atoms. All other parameters are "all-atom", OPLS-AA, including -explicit hydrogen atoms. - - - ############################# - ## ## - ## Atom Type Definitions ## - ## ## - ############################# - -# Note: -# In this example, I am only using OPLSAA to lookup force-field parameters -# for methane. (The water molecules in this example do not need OPLSAA.) -# So I deleted all of the lines beginning with "atom" except these two: - -atom 83 13 CT "Methane CH4" 6 12.011 4 -atom 85 46 HC "Alkane H-C" 1 1.008 1 - - ################################ - ## ## - ## Van der Waals Parameters ## - ## ## - ################################ - - -vdw 83 3.5000 0.0660 -vdw 85 2.5000 0.0300 - - - ################################## - ## ## - ## Bond Stretching Parameters ## - ## ## - ################################## - - -bond 13 46 340.00 1.0900 - - - ################################ - ## ## - ## Angle Bending Parameters ## - ## ## - ################################ - - -angle 46 13 46 33.00 107.80 - - - ######################################## - ## ## - ## Atomic Partial Charge Parameters ## - ## ## - ######################################## - - -charge 83 -0.2400 -charge 85 0.0600 diff --git a/tools/moltemplate/examples/force_field_OPLSAA/methane/moltemplate_files/system.lt b/tools/moltemplate/examples/force_field_OPLSAA/methane/moltemplate_files/system.lt deleted file mode 100644 index 7c846cd937..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/methane/moltemplate_files/system.lt +++ /dev/null @@ -1,15 +0,0 @@ -import "methane.lt" # <- defines the "Methane" molecule type (uses OPLSAA) - -# Periodic boundary conditions: -write_once("Data Boundary") { - 0.0 103.5 xlo xhi - 0.0 103.5 ylo yhi - 0.0 103.5 zlo zhi -} - -# Now add methane molecules: - -methanes = new Methane [10].move(0, 0, 10.35) - [10].move(0, 10.35, 0) - [10].move(10.35, 0, 0) - diff --git a/tools/moltemplate/examples/force_field_OPLSAA/methane/run.in.npt b/tools/moltemplate/examples/force_field_OPLSAA/methane/run.in.npt deleted file mode 100644 index 208d4b681f..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/methane/run.in.npt +++ /dev/null @@ -1,51 +0,0 @@ -# PREREQUISITES: -# -# You must use moltemplate.sh to create 3 files: -# system.data system.in.init system.in.settings -# (Follow the instructions in README_setup.sh, -# or run the file as a script using ./README_setup.sh) -# -# ------------------------------- Initialization Section -------------------- - -include "system.in.init" - -# ------------------------------- Atom Definition Section ------------------- - -read_data "system.data" - -# ------------------------------- Settings Section -------------------------- - -include "system.in.settings" -include "system.in.charges" - - -# ------------------------------- Run Section ------------------------------- - - -# -- minimization protocol -- - -# Note: The minimization step is not necessary in this example. However -# in general, it's always a good idea to minimize the system beforehand. -# (The "fShakeSPCE" fix was defined in system.in.settings. -# It is incompatible with "minimize", so we disable it first.) -#unfix fShakeSPCE -thermo 500 -minimize 1.0e-4 1.0e-6 100000 400000 - -# Now read "system.in.settings" in order to enable fShakeSPCE again: -#include system.in.settings - -# Optional: write the coordinates after minimization -write_data system_after_min.data - - -# -- simulation protocol -- - - -timestep 1.0 -dump 1 all custom 2500 traj_npt.lammpstrj id mol type x y z ix iy iz -fix fxnpt all npt temp 300.0 300.0 100.0 iso 1.0 1.0 1000.0 drag 1.0 - -run 500000 - -write_data system_after_npt.data diff --git a/tools/moltemplate/examples/force_field_OPLSAA/methane/run.in.nvt b/tools/moltemplate/examples/force_field_OPLSAA/methane/run.in.nvt deleted file mode 100644 index a4f382118f..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/methane/run.in.nvt +++ /dev/null @@ -1,42 +0,0 @@ -# PREREQUISITES: -# -# 1) You must use moltemplate.sh to create 3 files: -# system.data system.in.init system.in.settings -# (Follow the instructions in README_setup.sh, -# or run the file as a script using ./README_setup.sh) -# 2) You must equilibrate the system beforehand using "run.in.npt". -# This will create the file "system_after_npt.data" which this file reads. -# (Note: I have not verified that this equilibration protocol works well.) - -# ------------------------------- Initialization Section -------------------- - -include "system.in.init" - -# ------------------------------- Atom Definition Section ------------------- - -# Read the coordinates generated by an earlier NPT simulation - -read_data "system_after_npt.data" - -# (The "write_restart" and "reagd_restart" commands were buggy in 2012, -# but they should work also. I prefer "write_data" and "read_data".) - -# ------------------------------- Settings Section -------------------------- - -include "system.in.settings" -include "system.in.charges" - -# ------------------------------- Run Section ------------------------------- - -# -- simulation protocol -- - - -timestep 1.0 -dump 1 all custom 1000 traj_nvt.lammpstrj id mol type x y z ix iy iz -fix fxnvt all nvt temp 300.0 300.0 500.0 tchain 1 -thermo 500 -#thermo_modify flush yes - -run 50000 - -write_restart system_after_nvt.data diff --git a/tools/moltemplate/examples/force_field_OPLSAA/waterSPCE+methane/README.TXT b/tools/moltemplate/examples/force_field_OPLSAA/waterSPCE+methane/README.TXT deleted file mode 100644 index 5ad3a04b50..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/waterSPCE+methane/README.TXT +++ /dev/null @@ -1,30 +0,0 @@ -This example contains a mixture of water(SPCE) and methane. -The methane molecules use OPLSAA force-field, but the water molecules do not. - ----- Details ---- - -The methane molecules in this example use the OPLSAA force-field. -This means that the database of force-field parameters in "oplsaa.lt" -will be used to generate angles, dihedrals, and impropers. -The "moltemplate_files/methane.lt" file -contains these lines which refer to OPLSAA: - -import "oplsaa.lt" -Methane inherits OPLSAA { ... - -However the "SPCE" (water) molecules does NOT use a database to look up the -force-field parameters for this tiny molecule. -Instead, the "moltemplate_files/spce.lt" file declares all of the angle -interactions, atom properties and force-field parameters for water explicitly. -(Consequently, it makes no mention of "oplsaa.lt" or "OPLSAA".) - --------- Instructions: --------- - -More detailed instructions on how to build LAMMPS input files and -run a short simulation are provided in other README files. - -step 1) -README_setup.sh - -step 2) -README_run.sh diff --git a/tools/moltemplate/examples/force_field_OPLSAA/waterSPCE+methane/README_run.sh b/tools/moltemplate/examples/force_field_OPLSAA/waterSPCE+methane/README_run.sh deleted file mode 100755 index 5f82866644..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/waterSPCE+methane/README_run.sh +++ /dev/null @@ -1,34 +0,0 @@ -# --- Running LAMMPS --- -# -# The 2 files "run.in.npt", and "run.in.nvt" are LAMMPS -# input scripts which link to the input scripts and data files -# you hopefully have created earlier with moltemplate.sh: -# system.in.init, system.in.settings, system.data -# If not, carry out the instructions in "README_setup.sh". -# -# -- Instructions: -- -# If "lmp_mpi" is the name of the command you use to invoke lammps, -# then you would run lammps on these files this way: - - -lmp_mpi -i run.in.npt # minimization and simulation at constant pressure -lmp_mpi -i run.in.nvt # minimization and simulation at constant volume - -#(Note: The constant volume simulation lacks pressure equilibration. These are -# completely separate simulations. The results of the constant pressure -# simulation might be ignored when beginning the simulation at constant -# volume. (This is because restart files in LAMMPS don't always work, -# and I was spending a lot of time trying to convince people it was a -# LAMMPS bug, instead of a moltemplate bug, so I disabled restart files.) -# Read the "run.in.nvt" file to find out how to use the "read_restart" -# command to load the results of the pressure-equilibration simulation, -# before beginning a constant-volume run. - - - - - -# If you have compiled the MPI version of lammps, you can run lammps in parallel -#mpirun -np 4 lmp_mpi -i run.in.npt -#mpirun -np 4 lmp_mpi -i run.in.nvt -# (assuming you have 4 processors available) diff --git a/tools/moltemplate/examples/force_field_OPLSAA/waterSPCE+methane/README_setup.sh b/tools/moltemplate/examples/force_field_OPLSAA/waterSPCE+methane/README_setup.sh deleted file mode 100755 index 6aa6c06f4c..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/waterSPCE+methane/README_setup.sh +++ /dev/null @@ -1,28 +0,0 @@ - -# Create LAMMPS input files this way: -cd moltemplate_files - - # run moltemplate - - moltemplate.sh system.lt - - # This will generate various files with names ending in *.in* and *.data. - # Move them to the directory where you plan to run LAMMPS (in this case "../") - mv -f system.data system.in* ../ - - # Optional: - # The "./output_ttree/" directory is full of temporary files generated by - # moltemplate. They can be useful for debugging, but are usually thrown away. - rm -rf output_ttree/ - -cd ../ - - - - -# Optional: -# Note: The system.data and system.in.settings files contain extra information -# for atoms defined in OPLSAA which you are not using in this simulation. This -# is harmless, but if you to delete this information from your -# system.in.settings and system.in.data files, follow the instructions in -# this script: "optional_cleanup/README_remove_irrelevant_info.sh" diff --git a/tools/moltemplate/examples/force_field_OPLSAA/waterSPCE+methane/README_visualize.txt b/tools/moltemplate/examples/force_field_OPLSAA/waterSPCE+methane/README_visualize.txt deleted file mode 100644 index 019afc1444..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/waterSPCE+methane/README_visualize.txt +++ /dev/null @@ -1,87 +0,0 @@ - - ------- To view a lammps trajectory in VMD -------- - - -1) Build a PSF file for use in viewing with VMD. - -This step works with VMD 1.9 and topotools 1.2. -(Older versions, like VMD 1.8.6, don't support this.) - - -a) Start VMD -b) Menu Extensions->Tk Console -c) Enter: - -(I assume that the the DATA file is called "system.data") - - topo readlammpsdata system.data full - animate write psf system.psf - -2) - -Later, to Load a trajectory in VMD: - - Start VMD - Select menu: File->New Molecule - -Browse to select the PSF file you created above, and load it. - (Don't close the window yet.) - -Browse to select the trajectory file. - If necessary, for "file type" select: "LAMMPS Trajectory" - Load it. - - ---- A note on trajectory format: ----- -If the trajectory is a DUMP file, then make sure the it contains the -information you need for pbctools (see below. I've been using this -command in my LAMMPS scripts to create the trajectories: - - dump 1 all custom 5000 DUMP_FILE.lammpstrj id mol type x y z ix iy iz - -It's a good idea to use an atom_style which supports molecule-ID numbers -so that you can assign a molecule-ID number to each atom. (I think this -is needed to wrap atom coordinates without breaking molecules in half.) - -Of course, you don't have to save your trajectories in DUMP format, -(other formats like DCD work fine) I just mention dump files -because these are the files I'm familiar with. - -3) ----- Wrap the coordinates to the unit cell - (without cutting the molecules in half) - -a) Start VMD -b) Load the trajectory in VMD (see above) -c) Menu Extensions->Tk Console -d) Try entering these commands: - - pbc wrap -compound res -all - pbc box - - ----- Optional ---- - Sometimes the solvent or membrane obscures the view of the solute. - It can help to shift the location of the periodic boundary box - To shift the box in the y direction (for example) do this: - - pbc wrap -compound res -all -shiftcenterrel {0.0 0.15 0.0} - pbc box -shiftcenterrel {0.0 0.15 0.0} - - Distances are measured in units of box-length fractions, not Angstroms. - - Alternately if you have a solute whose atoms are all of type 1, - then you can also try this to center the box around it: - - pbc wrap -sel type=1 -all -centersel type=2 -center com - -4) - You should check if your periodic boundary conditions are too small. - To do that: - select Graphics->Representations menu option - click on the "Periodic" tab, and - click on the "+x", "-x", "+y", "-y", "+z", "-z" checkboxes. - -5) Optional: If you like, change the atom types in the PSF file so - that VMD recognizes the atom types, use something like: - -sed -e 's/ 1 1 / C C /g' < system.psf > temp1.psf -sed -e 's/ 2 2 / H H /g' < temp1.psf > temp2.psf -sed -e 's/ 3 3 / P P /g' < temp2.psf > system.psf - -(If you do this, it might effect step 2 above.) diff --git a/tools/moltemplate/examples/force_field_OPLSAA/waterSPCE+methane/moltemplate_files/methane.lt b/tools/moltemplate/examples/force_field_OPLSAA/waterSPCE+methane/moltemplate_files/methane.lt deleted file mode 100644 index bb8f0469cf..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/waterSPCE+methane/moltemplate_files/methane.lt +++ /dev/null @@ -1,32 +0,0 @@ -import "oplsaa.lt" - -# Atom type numbers are from the "oplsaa_subset.prm" -# file used to generate "oplsaa.lt". - -# atom 83 13 CT "Methane CH4" -# atom 85 46 HC "Alkane H-C" - -Methane inherits OPLSAA { - - # atomID molID atomTyle charge X Y Z - write('Data Atoms') { - $atom:C $mol:. @atom:83 0.0 0.000000 0.000000 0.000000 - $atom:H1 $mol:. @atom:85 0.0 0.000000 0.000000 1.089000 - $atom:H2 $mol:. @atom:85 0.0 1.026719 0.000000 -0.363000 - $atom:H3 $mol:. @atom:85 0.0 -0.513360 -0.889165 -0.363000 - $atom:H4 $mol:. @atom:85 0.0 -0.513360 0.889165 -0.363000 - } - - # Charges will be assigned by OPLSAA, so we leave them 0.0 here. - # - # (The "." in "$mol:." refers to this molecule-object's molecule-ID number. - # The "." simply means this molecule is not a part of a larger molecule.) - - write('Data Bond List') { - $bond:CH1 $atom:C $atom:H1 - $bond:CH2 $atom:C $atom:H2 - $bond:CH3 $atom:C $atom:H3 - $bond:CH4 $atom:C $atom:H4 - } - -} # Methane diff --git a/tools/moltemplate/examples/force_field_OPLSAA/waterSPCE+methane/moltemplate_files/oplsaa_lt_generator/AUTHOR.TXT b/tools/moltemplate/examples/force_field_OPLSAA/waterSPCE+methane/moltemplate_files/oplsaa_lt_generator/AUTHOR.TXT deleted file mode 100644 index d5e469af37..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/waterSPCE+methane/moltemplate_files/oplsaa_lt_generator/AUTHOR.TXT +++ /dev/null @@ -1,3 +0,0 @@ - -OPLSAA force-field conversion tools provided by Jason Lambert. - diff --git a/tools/moltemplate/examples/force_field_OPLSAA/waterSPCE+methane/moltemplate_files/oplsaa_lt_generator/README.TXT b/tools/moltemplate/examples/force_field_OPLSAA/waterSPCE+methane/moltemplate_files/oplsaa_lt_generator/README.TXT deleted file mode 100644 index 0bc46d88c8..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/waterSPCE+methane/moltemplate_files/oplsaa_lt_generator/README.TXT +++ /dev/null @@ -1,111 +0,0 @@ -This directory contains instructions for creating a a moltemplate file -("oplsaa.lt") containing force-field definitions relevant to the "Methane" -molecule. (However, these instructions should work for other molecules too.) -Note that the "SPCE" (water) molecules in this example, do NOT use the OPLSAA -database to look up the force-field parameters, so I did not include water -atom types in the "oplsaa_subset.prm". - ---- Instructions --- - -First, check and see if there is an "oplsaa_subset.prm" file present. -If not, then download this file: - -http://dasher.wustl.edu/tinker/distribution/params/oplsaa.prm - This file is also available here: -http://dasher.wustl.edu/ffe/distribution/params/oplsaa.prm - -and save this file as "oplsaa_subset.prm". Then you must EDIT THIS FILE -so that it only contains atom types you plan to have in your simulation -(see below for details). Then run the opls_moltemplate.py script this way: - - -oplsaa_moltemplate.py oplsaa_subset.prm - - -This will create a file named "oplsaa.lt" -Look over the newly created "oplsaa.lt" file. -Then move this file to wherever you plan to run moltemplate. For example: - -mv -f oplsaa.lt .. - ------ DETAILS: Editing the "oplsaa_subset.prm" file ------- - -Again, before you run "oplsaa_moltemplate.py", you must edit the "oplsaa.prm" -file (or "oplsaa_subset.prm file) and eliminate atom types which do not -correspond to any of the atoms in your simulation. This means you must -look for lines near the beginning of this file which begin with the word "atom" -and refer to atom types which appear in the simulation you plan to run. All -other lines (beginning with the word "atom") must be deleted or commented out. -(Leave the rest of the file alone.) - -For example: -If you were working with methane, you would delete every line -beginning with the word "atom", except for these two lines: - - -atom 83 13 CT "Methane CH4" 6 12.011 4 -atom 85 46 HC "Alkane H-C" 1 1.008 1 - - -Then you are ready to run oplsaa_moltemplate.py on this file. - -(Note: Atom type numbers, like "83", "85", "46", etc... may vary depending on - when you downloaded "oplsaa.prm".) - - ------ Using the "oplsaa.lt" file ----- - -Once you have created the "oplsaa.lt" file, you can create files (like -ethylene.lt) which define molecules that refer to these atom types. -Here is an excerpt from "methane.lt": - -import "oplsaa.lt" -Methane inherits OPLSAA { - write('Data Atoms') { - list of atoms goes here ... - } - write('Data Bond List') { - list of bonds goes here ... - } -} - -And then run moltemplate. - - ------------ CHARGE: ----------- - -By default, the OPLSAA force-field assigns atom charge according to atom type. -When you run moltemplate, it will create a file named "system.in.charges", -containing commands like: - -set type 2 charge -0.42 -set type 3 charge 0.21 - -(This assumes your main moltemplate file is named "system.lt". If it was -named something else, eg "polymer.lt", then the file created by moltemplate -will be named "polymer.in.charges".) - -Include these commands somewhere in your LAMMPS input script -(or use the LAMMPS "include" command to load the commands in system.in.charges) - -Note that the atom numbers (eg "2", "3") in this file will not match the -OPLS atom numbers. (Check the output_ttree/ttree_assignments.txt file, -created by moltemplate, to see a table of "@atom" type numbers translated -from OPLSAA into LAMMPS.) - ------------ CREDIT ----------- - -If you use these tools and you publish a paper using OPLSAA, please also cite -the TINKER program. (Because these examples use the "oplsaa.prm" file which -is distributed with TINKER.) I think these are the relevant citations: - -1) Ponder, J. W., & Richards, F. M. (1987). "An efficient newtonâ€like method for molecular mechanics energy minimization of large molecules. Journal of Computational Chemistry", 8(7), 1016-1024. - -2) Ponder, J. W, (2004) "TINKER: Software tools for molecular design", http://dasher.wustl.edu/tinker/ - -------------------------------- - -Andrew Jewett and Jason Lambert -May, 2014 - -Please email bugs to jewett.aij@gmail.com and jlamber9@gmail.com diff --git a/tools/moltemplate/examples/force_field_OPLSAA/waterSPCE+methane/moltemplate_files/oplsaa_lt_generator/oplsaa_subset.prm b/tools/moltemplate/examples/force_field_OPLSAA/waterSPCE+methane/moltemplate_files/oplsaa_lt_generator/oplsaa_subset.prm deleted file mode 100644 index fee34956bc..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/waterSPCE+methane/moltemplate_files/oplsaa_lt_generator/oplsaa_subset.prm +++ /dev/null @@ -1,126 +0,0 @@ -# This is a modified version of the file "oplsaa.prm" distributed with TINKER -# http://dasher.wustl.edu/tinker/distribution/params/oplsaa.prm -# In this version, all of the lines beginning with "atom" have been deleted -# except for the atom types we will be using in this simulation. -# (I also deleted some other lines from that file data to reduce the file size, -# but doing that is not necessary.) -# -# If you use this file, please also cite the software this file comes from: -# -# Ponder, J. W., and Richards, F. M. J. Comput. Chem. (1987) 8(7), 1016-1024 -# "An efficient newtonâ€like method for molecular mechanics energy -# minimization of large molecules." -# -# Ponder, J. W, (2004) -# "TINKER: Software tools for molecular design" -# http://dasher.wustl.edu/tinker/ - - ############################## - ## ## - ## Force Field Definition ## - ## ## - ############################## - - -forcefield OPLS-AA - -vdwindex TYPE -vdwtype LENNARD-JONES -radiusrule GEOMETRIC -radiustype SIGMA -radiussize DIAMETER -epsilonrule GEOMETRIC -torsionunit 0.5 -imptorunit 0.5 -vdw-14-scale 2.0 -chg-14-scale 2.0 -electric 332.06 -dielectric 1.0 - - - ############################# - ## ## - ## Literature References ## - ## ## - ############################# - - -The parameters supplied with TINKER are from "OPLS All-Atom Parameters -for Organic Molecules, Ions, Peptides & Nucleic Acids, July 2008" as -provided by W. L. Jorgensen, Yale University during June 2009. These -parameters are taken from those distributed with BOSS Version 4.8. - -Note that "atom type" numbers and not "atom class" numbers are used -to index van der Waals parameters, see the "vdwindex" keyword above - -The atom types with (UA) in the description are "united atom" values, -ie, OPLS-UA, where any nonpolar hydrogen atoms are combined onto their -attached atoms. All other parameters are "all-atom", OPLS-AA, including -explicit hydrogen atoms. - - - ############################# - ## ## - ## Atom Type Definitions ## - ## ## - ############################# - -# Note: -# In this example, I am only using OPLSAA to lookup force-field parameters -# for methane. (The water molecules in this example do not need OPLSAA.) -# So I deleted all of the lines beginning with "atom" except these two: - -atom 83 13 CT "Methane CH4" 6 12.011 4 -atom 85 46 HC "Alkane H-C" 1 1.008 1 - -# NOTE: You can use the OPLSAA force field to look up SPC water parameters as -# In that case, you could do this by uncommenting these next two lines: -# atom 76 42 OW "SPC Water O" 8 15.999 2 -# atom 77 43 HW "SPC Water H" 1 1.008 1 - - - - ################################ - ## ## - ## Van der Waals Parameters ## - ## ## - ################################ - - -vdw 83 3.5000 0.0660 -vdw 85 2.5000 0.0300 - - - ################################## - ## ## - ## Bond Stretching Parameters ## - ## ## - ################################## - - -bond 13 46 340.00 1.0900 -bond 42 43 600.00 1.0000 - - - ################################ - ## ## - ## Angle Bending Parameters ## - ## ## - ################################ - - -angle 46 13 46 33.00 107.80 -angle 43 42 43 75.00 109.47 - - - ######################################## - ## ## - ## Atomic Partial Charge Parameters ## - ## ## - ######################################## - - -charge 76 -0.8200 -charge 77 0.4100 -charge 83 -0.2400 -charge 85 0.0600 diff --git a/tools/moltemplate/examples/force_field_OPLSAA/waterSPCE+methane/moltemplate_files/spce.lt b/tools/moltemplate/examples/force_field_OPLSAA/waterSPCE+methane/moltemplate_files/spce.lt deleted file mode 100644 index fdf6172a4b..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/waterSPCE+methane/moltemplate_files/spce.lt +++ /dev/null @@ -1,52 +0,0 @@ -# file "spce.lt" -# -# H1 H2 -# \ / -# O - -SPCE { - - write("Data Atoms") { - $atom:O $mol:. @atom:O -0.8476 0.0000000 0.00000 0.000000 - $atom:H1 $mol:. @atom:H 0.4238 0.8164904 0.00000 0.5773590 - $atom:H2 $mol:. @atom:H 0.4238 -0.8164904 0.00000 0.5773590 - } - - write_once("Data Masses") { - @atom:O 15.9994 - @atom:H 1.008 - } - - write("Data Bonds") { - $bond:OH1 @bond:OH $atom:O $atom:H1 - $bond:OH2 @bond:OH $atom:O $atom:H2 - } - - write("Data Angles") { - $angle:HOH @angle:HOH $atom:H1 $atom:O $atom:H2 - } - - write_once("In Settings") { - bond_coeff @bond:OH harmonic 600.0 1.0 - angle_coeff @angle:HOH harmonic 75.0 109.47 - pair_coeff @atom:O @atom:O lj/cut/coul/long 0.1553 3.166 - pair_coeff @atom:H @atom:H lj/cut/coul/long 0.0 0.0 - group spce type @atom:O @atom:H - fix fShakeSPCE spce shake 0.0001 10 100 b @bond:OH a @angle:HOH - # (Remember to "unfix" fShakeSPCE during minimization.) - } - - write_once("In Init") { - # -- Default styles (for solo "SPCE" water) -- - units real - atom_style full - # (Hybrid force fields were not necessary but are used for portability.) - pair_style hybrid lj/cut/coul/long 10.0 10.0 - bond_style hybrid harmonic - angle_style hybrid harmonic - kspace_style pppm 0.0001 - #pair_modify mix arithmetic # LEAVE THIS UNSPECIFIED! - } - -} # end of definition of "SPCE" water molecule type - diff --git a/tools/moltemplate/examples/force_field_OPLSAA/waterSPCE+methane/moltemplate_files/system.lt b/tools/moltemplate/examples/force_field_OPLSAA/waterSPCE+methane/moltemplate_files/system.lt deleted file mode 100644 index 3957d08eb7..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/waterSPCE+methane/moltemplate_files/system.lt +++ /dev/null @@ -1,26 +0,0 @@ -import "spce.lt" # <- defines the "SPCE" (water) molecule type. -import "methane.lt" # <- defines the "Methane" molecule type (uses OPLSAA) - -# Periodic boundary conditions: -write_once("Data Boundary") { - 0.0 41.50 xlo xhi - 0.0 41.50 ylo yhi - 0.0 41.50 zlo zhi -} - -# The next command generates a (rather dense) cubic lattice with -# spacing 3.45 Angstroms. (The pressure must be equilibrated later.) - -waters = new SPCE [12].move(0.00, 0.00, 3.45) - [12].move(0.00, 3.45, 0.00) - [12].move(3.45, 0.00, 0.00) - -# Now add methane molecules: - -methanes = new Methane [4].move(0, 0, 10.35) - [4].move(0, 10.35, 0) - [4].move(10.35, 0, 0) - -# Move the methane molecules slightly to reduce overlap with the water -methanes[*][*][*].move(1.725, 1.725, 1.725) - diff --git a/tools/moltemplate/examples/force_field_OPLSAA/waterSPCE+methane/run.in.npt b/tools/moltemplate/examples/force_field_OPLSAA/waterSPCE+methane/run.in.npt deleted file mode 100644 index df9c1f95f2..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/waterSPCE+methane/run.in.npt +++ /dev/null @@ -1,52 +0,0 @@ -# PREREQUISITES: -# -# You must use moltemplate.sh to create 3 files: -# system.data system.in.init system.in.settings -# (Follow the instructions in README_setup.sh, -# or run the file as a script using ./README_setup.sh) -# -# ------------------------------- Initialization Section -------------------- - -include "system.in.init" - -# ------------------------------- Atom Definition Section ------------------- - -read_data "system.data" - -# ------------------------------- Settings Section -------------------------- - -include "system.in.settings" -include "system.in.charges" - - -# ------------------------------- Run Section ------------------------------- - - -# -- minimization protocol -- - -# Note: The minimization step is not necessary in this example. However -# in general, it's always a good idea to minimize the system beforehand. -# (The "fShakeSPCE" fix was defined in system.in.settings. -# It is incompatible with "minimize", so we disable it first.) -unfix fShakeSPCE -thermo 50 -minimize 1.0e-4 1.0e-6 100000 400000 - -# Now read "system.in.settings" in order to enable fShakeSPCE again: -include system.in.settings - -# Optional: write the coordinates after minimization -write_data system_after_min.data - - -# -- simulation protocol -- - - -timestep 1.0 -dump 1 all custom 10000 traj_npt.lammpstrj id mol type x y z ix iy iz -fix fxnpt all npt temp 300.0 300.0 100.0 iso 1.0 1.0 1000.0 drag 1.0 -thermo 100 - -run 2000000 - -write_data system_after_npt.data diff --git a/tools/moltemplate/examples/force_field_OPLSAA/waterSPCE+methane/run.in.nvt b/tools/moltemplate/examples/force_field_OPLSAA/waterSPCE+methane/run.in.nvt deleted file mode 100644 index 9652779bb0..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/waterSPCE+methane/run.in.nvt +++ /dev/null @@ -1,42 +0,0 @@ -# PREREQUISITES: -# -# 1) You must use moltemplate.sh to create 3 files: -# system.data system.in.init system.in.settings -# (Follow the instructions in README_setup.sh, -# or run the file as a script using ./README_setup.sh) -# 2) You must equilibrate the system beforehand using "run.in.npt". -# This will create the file "system_after_npt.data" which this file reads. -# (Note: I have not verified that this equilibration protocol works well.) - -# ------------------------------- Initialization Section -------------------- - -include "system.in.init" - -# ------------------------------- Atom Definition Section ------------------- - -# Read the coordinates generated by an earlier NPT simulation - -read_data "system_after_npt.data" - -# (The "write_restart" and "read_restart" commands were buggy in 2012, -# but they should work also. I prefer "write_data" and "read_data".) - -# ------------------------------- Settings Section -------------------------- - -include "system.in.settings" -include "system.in.charges" - -# ------------------------------- Run Section ------------------------------- - -# -- simulation protocol -- - - -timestep 1.0 -dump 1 all custom 1000 traj_nvt.lammpstrj id mol type x y z ix iy iz -fix fxnvt all nvt temp 300.0 300.0 500.0 tchain 1 -thermo 500 -#thermo_modify flush yes - -run 50000 - -write_data system_after_nvt.data diff --git a/tools/moltemplate/examples/force_field_OPLSAA/waterSPC_using_OPLSAA/README.TXT b/tools/moltemplate/examples/force_field_OPLSAA/waterSPC_using_OPLSAA/README.TXT deleted file mode 100644 index 292d9d0ec0..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/waterSPC_using_OPLSAA/README.TXT +++ /dev/null @@ -1,18 +0,0 @@ -The purpose of this example is to test the density of water -constructed using the OPLSAA force-field. (I think this is SPC water, not SPCE) - -I just wanted some kind of sanity check to make sure we are converting -the OPLSAA parameters into moltemplate/LAMMPS format correctly. - -The "TEST_density_estimate.txt" contains the results of that test. - --------- Instructions: --------- - -More detailed instructions on how to build LAMMPS input files and -run a short simulation are provided in other README files. - -step 1) -README_setup.sh - -step 2) -README_run.sh diff --git a/tools/moltemplate/examples/force_field_OPLSAA/waterSPC_using_OPLSAA/README_run.sh b/tools/moltemplate/examples/force_field_OPLSAA/waterSPC_using_OPLSAA/README_run.sh deleted file mode 100755 index 71a18b0ab2..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/waterSPC_using_OPLSAA/README_run.sh +++ /dev/null @@ -1,20 +0,0 @@ -# --- Running LAMMPS --- -# The 2 files "run.in.npt", and "run.in.nvt" are LAMMPS -# input scripts which link to the input scripts and data files -# you hopefully have created earlier with moltemplate.sh: -# system.in.init, system.in.settings, system.data -# If not, carry out the instructions in "README_setup.sh". -# -# -- Instructions: -- -# If "lmp_mpi" is the name of the command you use to invoke lammps, -# then you would run lammps on these files this way: - - -lmp_mpi -i run.in.npt # minimization and simulation at constant pressure -lmp_mpi -i run.in.nvt # simulation at constant volume - - -# If you have compiled the MPI version of lammps, you can run lammps in parallel -#mpirun -np 4 lmp_mpi -i run.in.npt -#mpirun -np 4 lmp_mpi -i run.in.nvt -# (assuming you have 4 processors available) diff --git a/tools/moltemplate/examples/force_field_OPLSAA/waterSPC_using_OPLSAA/README_setup.sh b/tools/moltemplate/examples/force_field_OPLSAA/waterSPC_using_OPLSAA/README_setup.sh deleted file mode 100755 index 6aa6c06f4c..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/waterSPC_using_OPLSAA/README_setup.sh +++ /dev/null @@ -1,28 +0,0 @@ - -# Create LAMMPS input files this way: -cd moltemplate_files - - # run moltemplate - - moltemplate.sh system.lt - - # This will generate various files with names ending in *.in* and *.data. - # Move them to the directory where you plan to run LAMMPS (in this case "../") - mv -f system.data system.in* ../ - - # Optional: - # The "./output_ttree/" directory is full of temporary files generated by - # moltemplate. They can be useful for debugging, but are usually thrown away. - rm -rf output_ttree/ - -cd ../ - - - - -# Optional: -# Note: The system.data and system.in.settings files contain extra information -# for atoms defined in OPLSAA which you are not using in this simulation. This -# is harmless, but if you to delete this information from your -# system.in.settings and system.in.data files, follow the instructions in -# this script: "optional_cleanup/README_remove_irrelevant_info.sh" diff --git a/tools/moltemplate/examples/force_field_OPLSAA/waterSPC_using_OPLSAA/README_visualize.txt b/tools/moltemplate/examples/force_field_OPLSAA/waterSPC_using_OPLSAA/README_visualize.txt deleted file mode 100644 index 019afc1444..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/waterSPC_using_OPLSAA/README_visualize.txt +++ /dev/null @@ -1,87 +0,0 @@ - - ------- To view a lammps trajectory in VMD -------- - - -1) Build a PSF file for use in viewing with VMD. - -This step works with VMD 1.9 and topotools 1.2. -(Older versions, like VMD 1.8.6, don't support this.) - - -a) Start VMD -b) Menu Extensions->Tk Console -c) Enter: - -(I assume that the the DATA file is called "system.data") - - topo readlammpsdata system.data full - animate write psf system.psf - -2) - -Later, to Load a trajectory in VMD: - - Start VMD - Select menu: File->New Molecule - -Browse to select the PSF file you created above, and load it. - (Don't close the window yet.) - -Browse to select the trajectory file. - If necessary, for "file type" select: "LAMMPS Trajectory" - Load it. - - ---- A note on trajectory format: ----- -If the trajectory is a DUMP file, then make sure the it contains the -information you need for pbctools (see below. I've been using this -command in my LAMMPS scripts to create the trajectories: - - dump 1 all custom 5000 DUMP_FILE.lammpstrj id mol type x y z ix iy iz - -It's a good idea to use an atom_style which supports molecule-ID numbers -so that you can assign a molecule-ID number to each atom. (I think this -is needed to wrap atom coordinates without breaking molecules in half.) - -Of course, you don't have to save your trajectories in DUMP format, -(other formats like DCD work fine) I just mention dump files -because these are the files I'm familiar with. - -3) ----- Wrap the coordinates to the unit cell - (without cutting the molecules in half) - -a) Start VMD -b) Load the trajectory in VMD (see above) -c) Menu Extensions->Tk Console -d) Try entering these commands: - - pbc wrap -compound res -all - pbc box - - ----- Optional ---- - Sometimes the solvent or membrane obscures the view of the solute. - It can help to shift the location of the periodic boundary box - To shift the box in the y direction (for example) do this: - - pbc wrap -compound res -all -shiftcenterrel {0.0 0.15 0.0} - pbc box -shiftcenterrel {0.0 0.15 0.0} - - Distances are measured in units of box-length fractions, not Angstroms. - - Alternately if you have a solute whose atoms are all of type 1, - then you can also try this to center the box around it: - - pbc wrap -sel type=1 -all -centersel type=2 -center com - -4) - You should check if your periodic boundary conditions are too small. - To do that: - select Graphics->Representations menu option - click on the "Periodic" tab, and - click on the "+x", "-x", "+y", "-y", "+z", "-z" checkboxes. - -5) Optional: If you like, change the atom types in the PSF file so - that VMD recognizes the atom types, use something like: - -sed -e 's/ 1 1 / C C /g' < system.psf > temp1.psf -sed -e 's/ 2 2 / H H /g' < temp1.psf > temp2.psf -sed -e 's/ 3 3 / P P /g' < temp2.psf > system.psf - -(If you do this, it might effect step 2 above.) diff --git a/tools/moltemplate/examples/force_field_OPLSAA/waterSPC_using_OPLSAA/TEST_density_estimate.txt b/tools/moltemplate/examples/force_field_OPLSAA/waterSPC_using_OPLSAA/TEST_density_estimate.txt deleted file mode 100644 index 9dc50b389e..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/waterSPC_using_OPLSAA/TEST_density_estimate.txt +++ /dev/null @@ -1,20 +0,0 @@ -This system contains 1728 water molecules -(This is SPC water I think.) - -Then I ran a short simulation for 170000 timesteps at 300Kelvin and 1 atm. -(that's when it crashed. I'll worry about why later...) - -Anyway, the average volume was 52149.8 (in Angstroms^3) -(for the last 80000 timesteps, after it had equilibrated) - -Given that the mass of water is 18.0154 grams per mole, I'm getting -this value for the density: - -density = (1728*18.0154/6.02214129e23) / (52149.8*1e-30*1e6) - = 0.991 (in grams per mL) - -I'm only looking for gross errors in the OPLSAA force-field. -So I'm satisfied with a 1% error. -But I realize this is not a particularly rigorous test. - -Andrew 2014-5-21 diff --git a/tools/moltemplate/examples/force_field_OPLSAA/waterSPC_using_OPLSAA/moltemplate_files/oplsaa_lt_generator/AUTHOR.TXT b/tools/moltemplate/examples/force_field_OPLSAA/waterSPC_using_OPLSAA/moltemplate_files/oplsaa_lt_generator/AUTHOR.TXT deleted file mode 100644 index d5e469af37..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/waterSPC_using_OPLSAA/moltemplate_files/oplsaa_lt_generator/AUTHOR.TXT +++ /dev/null @@ -1,3 +0,0 @@ - -OPLSAA force-field conversion tools provided by Jason Lambert. - diff --git a/tools/moltemplate/examples/force_field_OPLSAA/waterSPC_using_OPLSAA/moltemplate_files/oplsaa_lt_generator/README.TXT b/tools/moltemplate/examples/force_field_OPLSAA/waterSPC_using_OPLSAA/moltemplate_files/oplsaa_lt_generator/README.TXT deleted file mode 100644 index 8ae373d713..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/waterSPC_using_OPLSAA/moltemplate_files/oplsaa_lt_generator/README.TXT +++ /dev/null @@ -1,115 +0,0 @@ -This directory contains instructions for creating a a moltemplate file -("oplsaa.lt") containing force-field definitions relevant to the "Methane" -molecule. (However, these instructions should work for other molecules too.) -Note that the "SPCE" (water) molecules in this example, do NOT use the OPLSAA -database to look up the force-field parameters, so I did not include water -atom types in the "oplsaa_subset.prm". - ---- Instructions --- - -First, check and see if there is an "oplsaa_subset.prm" file present. -If not, then download this file: - -http://dasher.wustl.edu/tinker/distribution/params/oplsaa.prm - This file is also available here: -http://dasher.wustl.edu/ffe/distribution/params/oplsaa.prm - -and save this file as "oplsaa_subset.prm". Then you must EDIT THIS FILE -so that it only contains atom types you plan to have in your simulation -(see below for details). Then run the opls_moltemplate.py script this way: - - -oplsaa_moltemplate.py oplsaa_subset.prm - - -This will create a file named "oplsaa.lt" -Look over the newly created "oplsaa.lt" file. -Then move this file to wherever you plan to run moltemplate. For example: - -mv -f oplsaa.lt .. - ------ DETAILS: Editing the "oplsaa_subset.prm" file ------- - -Again, before you run "oplsaa_moltemplate.py", you must edit the "oplsaa.prm" -file (or "oplsaa_subset.prm file) and eliminate atom types which do not -correspond to any of the atoms in your simulation. This means you must -look for lines near the beginning of this file which begin with the word "atom" -and refer to atom types which appear in the simulation you plan to run. All -other lines (beginning with the word "atom") must be deleted or commented out. -(Leave the rest of the file alone.) - -For example: -If you were working with methane and SPC water, you would delete every line -beginning with the word "atom", except for these two lines: - - -atom 76 42 OW "SPC Water O" 8 15.999 2 -atom 77 43 HW "SPC Water H" 1 1.008 1 -atom 83 13 CT "Methane CH4" 6 12.011 4 -atom 85 46 HC "Alkane H-C" 1 1.008 1 - - -Then you are ready to run oplsaa_moltemplate.py on this file. - -(Note: Atom type numbers, like "83", "85", "46", etc... may vary depending on - when you downloaded "oplsaa.prm".) - - ------ Using the "oplsaa.lt" file ----- - -Once you have created the "oplsaa.lt" file, you can create files (like -ethylene.lt) which define molecules that refer to these atom types. -Here is an excerpt from "methane.lt": - -import "oplsaa.lt" -Methane inherits OPLSAA { - write('Data Atoms') { - list of atoms goes here ... - } - write('Data Bond List') { - list of bonds goes here ... - } -} - -And then run moltemplate. - - ------------ CHARGE: ----------- - -By default, the OPLSAA force-field assigns atom charge according to atom type. -When you run moltemplate, it will create a file named "system.in.charges", -containing commands like: - -set type 1 charge -0.82 -set type 2 charge 0.41 -set type 3 charge -0.42 -set type 4 charge 0.21 - -(This assumes your main moltemplate file is named "system.lt". If it was -named something else, eg "polymer.lt", then the file created by moltemplate -will be named "polymer.in.charges".) - -Include these commands somewhere in your LAMMPS input script -(or use the LAMMPS "include" command to load the commands in system.in.charges) - -Note that the atom numbers (eg "2", "3") in this file will not match the -OPLS atom numbers. (Check the output_ttree/ttree_assignments.txt file, -created by moltemplate, to see a table of "@atom" type numbers translated -from OPLSAA into LAMMPS.) - ------------ CREDIT ----------- - -If you use these tools and you publish a paper using OPLSAA, please also cite -the TINKER program. (Because these examples use the "oplsaa.prm" file which -is distributed with TINKER.) I think these are the relevant citations: - -1) Ponder, J. W., & Richards, F. M. (1987). "An efficient newtonâ€like method for molecular mechanics energy minimization of large molecules. Journal of Computational Chemistry", 8(7), 1016-1024. - -2) Ponder, J. W, (2004) "TINKER: Software tools for molecular design", http://dasher.wustl.edu/tinker/ - -------------------------------- - -Andrew Jewett and Jason Lambert -May, 2014 - -Please email bugs to jewett.aij@gmail.com and jlamber9@gmail.com diff --git a/tools/moltemplate/examples/force_field_OPLSAA/waterSPC_using_OPLSAA/moltemplate_files/oplsaa_lt_generator/oplsaa_subset.prm b/tools/moltemplate/examples/force_field_OPLSAA/waterSPC_using_OPLSAA/moltemplate_files/oplsaa_lt_generator/oplsaa_subset.prm deleted file mode 100644 index 60bf1d855e..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/waterSPC_using_OPLSAA/moltemplate_files/oplsaa_lt_generator/oplsaa_subset.prm +++ /dev/null @@ -1,112 +0,0 @@ -# This is a modified version of the file "oplsaa.prm" distributed with TINKER -# http://dasher.wustl.edu/tinker/distribution/params/oplsaa.prm -# In this version, all of the lines beginning with "atom" have been deleted -# except for the atom types we will be using in this simulation. -# (That's all you need to do, but in this version, I also deleted -# everything else we don't need to reduce the file size.) -# -# If you use this file, please also cite the software this file comes from: -# -# Ponder, J. W., and Richards, F. M. J. Comput. Chem. (1987) 8(7), 1016-1024 -# "An efficient newtonâ€like method for molecular mechanics energy -# minimization of large molecules." -# -# Ponder, J. W, (2004) -# "TINKER: Software tools for molecular design" -# http://dasher.wustl.edu/tinker/ - - ############################## - ## ## - ## Force Field Definition ## - ## ## - ############################## - - -forcefield OPLS-AA - -vdwindex TYPE -vdwtype LENNARD-JONES -radiusrule GEOMETRIC -radiustype SIGMA -radiussize DIAMETER -epsilonrule GEOMETRIC -torsionunit 0.5 -imptorunit 0.5 -vdw-14-scale 2.0 -chg-14-scale 2.0 -electric 332.06 -dielectric 1.0 - - - ############################# - ## ## - ## Literature References ## - ## ## - ############################# - - -The parameters supplied with TINKER are from "OPLS All-Atom Parameters -for Organic Molecules, Ions, Peptides & Nucleic Acids, July 2008" as -provided by W. L. Jorgensen, Yale University during June 2009. These -parameters are taken from those distributed with BOSS Version 4.8. - -Note that "atom type" numbers and not "atom class" numbers are used -to index van der Waals parameters, see the "vdwindex" keyword above - -The atom types with (UA) in the description are "united atom" values, -ie, OPLS-UA, where any nonpolar hydrogen atoms are combined onto their -attached atoms. All other parameters are "all-atom", OPLS-AA, including -explicit hydrogen atoms. - - - ############################# - ## ## - ## Atom Type Definitions ## - ## ## - ############################# - - -atom 76 42 OW "SPC Water O" 8 15.999 2 -atom 77 43 HW "SPC Water H" 1 1.008 1 - - - ################################ - ## ## - ## Van der Waals Parameters ## - ## ## - ################################ - - -vdw 76 3.16557 0.1554 -vdw 77 0.0000 0.0000 - - - ################################## - ## ## - ## Bond Stretching Parameters ## - ## ## - ################################## - - -bond 42 43 600.00 1.0000 - - - ################################ - ## ## - ## Angle Bending Parameters ## - ## ## - ################################ - - -angle 43 42 43 75.00 109.47 - - - ######################################## - ## ## - ## Atomic Partial Charge Parameters ## - ## ## - ######################################## - - -charge 76 -0.8200 -charge 77 0.4100 diff --git a/tools/moltemplate/examples/force_field_OPLSAA/waterSPC_using_OPLSAA/moltemplate_files/spc.lt b/tools/moltemplate/examples/force_field_OPLSAA/waterSPC_using_OPLSAA/moltemplate_files/spc.lt deleted file mode 100644 index e7f3d6d843..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/waterSPC_using_OPLSAA/moltemplate_files/spc.lt +++ /dev/null @@ -1,86 +0,0 @@ -# file "spce.lt" -# -# H1 H2 -# \ / -# O - - -import "oplsaa.lt" - -SPC inherits OPLSAA { - - # Atom types from "oplsaa_lt_generator/oplsaa_subset.prm" - # @atom:76 <--> OW "SPC Water O" - # @atom:77 <--> HW "SPC Water H" - - write("Data Atoms") { - $atom:O $mol:. @atom:76 -0.8200 0.0000000 0.0000 0.000000 - $atom:H1 $mol:. @atom:77 0.4100 0.8164904 0.0000 0.577359 - $atom:H2 $mol:. @atom:77 0.4100 -0.8164904 0.0000 0.577359 - } - - write("Data Bond List") { - $bond:OH1 $atom:O $atom:H1 - $bond:OH2 $atom:O $atom:H2 - } - -} # end of definition of "SPC" water molecule type - - - - - - - - - - - -###################### old version (SPCE) ###################### -# -#SPCE { -# -# write("Data Atoms") { -# $atom:O $mol:. @atom:O -0.8476 0.0000000 0.0000 0.000000 -# $atom:H1 $mol:. @atom:H 0.4238 0.8164904 0.0000 0.577359 -# $atom:H2 $mol:. @atom:H 0.4238 -0.8164904 0.0000 0.577359 -# } -# -# write_once("Data Masses") { -# @atom:O 15.9994 -# @atom:H 1.008 -# } -# -# write("Data Bonds") { -# $bond:OH1 @bond:OH $atom:O $atom:H1 -# $bond:OH2 @bond:OH $atom:O $atom:H2 -# } -# -# write("Data Angles") { -# $angle:HOH @angle:HOH $atom:H1 $atom:O $atom:H2 -# } -# -# write_once("In Settings") { -# bond_coeff @bond:OH harmonic 1000.0 1.0 -# angle_coeff @angle:HOH harmonic 1000.0 109.47 -# pair_coeff @atom:O @atom:O lj/cut/coul/long 0.1553 3.166 -# pair_coeff @atom:H @atom:H lj/cut/coul/long 0.0 2.058 -# group spce type @atom:O @atom:H -# fix fShakeSPCE spce shake 0.0001 10 100 b @bond:OH a @angle:HOH -# # (Remember to "unfix" fShakeSPCE during minimization.) -# } -# -# write_once("In Init") { -# # -- Default styles (for solo "SPCE" water) -- -# units real -# atom_style full -# # (Hybrid force fields were not necessary but are used for portability.) -# pair_style hybrid lj/cut/coul/long 10.0 -# bond_style hybrid harmonic -# angle_style hybrid harmonic -# kspace_style pppm 0.0001 -# pair_modify shift yes -# } -# -#} SPCE -################################################################### diff --git a/tools/moltemplate/examples/force_field_OPLSAA/waterSPC_using_OPLSAA/moltemplate_files/system.lt b/tools/moltemplate/examples/force_field_OPLSAA/waterSPC_using_OPLSAA/moltemplate_files/system.lt deleted file mode 100644 index 5dd56c116f..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/waterSPC_using_OPLSAA/moltemplate_files/system.lt +++ /dev/null @@ -1,16 +0,0 @@ -import "spc.lt" # <- defines the "SPC" (water) molecule type (uses OPLSAA) - -# Periodic boundary conditions: -write_once("Data Boundary") { - 0.0 41.40 xlo xhi - 0.0 41.40 ylo yhi - 0.0 41.40 zlo zhi -} - -# The next command generates a (rather dense) cubic lattice with -# spacing 3.45 Angstroms. (The pressure must be equilibrated later.) - -waters = new SPC [12].move(0.00, 0.00, 3.45) - [12].move(0.00, 3.45, 0.00) - [12].move(3.45, 0.00, 0.00) - diff --git a/tools/moltemplate/examples/force_field_OPLSAA/waterSPC_using_OPLSAA/run.in.npt b/tools/moltemplate/examples/force_field_OPLSAA/waterSPC_using_OPLSAA/run.in.npt deleted file mode 100644 index 642880af2d..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/waterSPC_using_OPLSAA/run.in.npt +++ /dev/null @@ -1,52 +0,0 @@ -# PREREQUISITES: -# -# You must use moltemplate.sh to create 3 files: -# system.data system.in.init system.in.settings -# (Follow the instructions in README_setup.sh, -# or run the file as a script using ./README_setup.sh) -# -# ------------------------------- Initialization Section -------------------- - -include "system.in.init" - -# ------------------------------- Atom Definition Section ------------------- - -read_data "system.data" - -# ------------------------------- Settings Section -------------------------- - -include "system.in.settings" -include "system.in.charges" - - -# ------------------------------- Run Section ------------------------------- - - -# -- minimization protocol -- - -# Note: The minimization step is not necessary in this example. However -# in general, it's always a good idea to minimize the system beforehand. -# (The "fShakeSPCE" fix was defined in system.in.settings. -# It is incompatible with "minimize", so we disable it first.) -#unfix fShakeSPCE -thermo 50 -minimize 1.0e-4 1.0e-6 100000 400000 - -# Now read "system.in.settings" in order to enable fShakeSPCE again: -#include system.in.settings - -# Optional: write the coordinates after minimization -write_data system_after_min.data - - -# -- simulation protocol -- - - -timestep 1.0 -dump 1 all custom 2500 traj_npt.lammpstrj id mol type x y z ix iy iz -fix fxnpt all npt temp 300.0 300.0 100.0 iso 1.0 1.0 1000.0 drag 1.0 -thermo 100 - -run 2000000 - -write_data system_after_npt.data diff --git a/tools/moltemplate/examples/force_field_OPLSAA/waterSPC_using_OPLSAA/run.in.nvt b/tools/moltemplate/examples/force_field_OPLSAA/waterSPC_using_OPLSAA/run.in.nvt deleted file mode 100644 index 9652779bb0..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSAA/waterSPC_using_OPLSAA/run.in.nvt +++ /dev/null @@ -1,42 +0,0 @@ -# PREREQUISITES: -# -# 1) You must use moltemplate.sh to create 3 files: -# system.data system.in.init system.in.settings -# (Follow the instructions in README_setup.sh, -# or run the file as a script using ./README_setup.sh) -# 2) You must equilibrate the system beforehand using "run.in.npt". -# This will create the file "system_after_npt.data" which this file reads. -# (Note: I have not verified that this equilibration protocol works well.) - -# ------------------------------- Initialization Section -------------------- - -include "system.in.init" - -# ------------------------------- Atom Definition Section ------------------- - -# Read the coordinates generated by an earlier NPT simulation - -read_data "system_after_npt.data" - -# (The "write_restart" and "read_restart" commands were buggy in 2012, -# but they should work also. I prefer "write_data" and "read_data".) - -# ------------------------------- Settings Section -------------------------- - -include "system.in.settings" -include "system.in.charges" - -# ------------------------------- Run Section ------------------------------- - -# -- simulation protocol -- - - -timestep 1.0 -dump 1 all custom 1000 traj_nvt.lammpstrj id mol type x y z ix iy iz -fix fxnvt all nvt temp 300.0 300.0 500.0 tchain 1 -thermo 500 -#thermo_modify flush yes - -run 50000 - -write_data system_after_nvt.data diff --git a/tools/moltemplate/examples/force_field_OPLSUA_united_atom/propane/README.TXT b/tools/moltemplate/examples/force_field_OPLSUA_united_atom/propane/README.TXT deleted file mode 100644 index 036c6e7569..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSUA_united_atom/propane/README.TXT +++ /dev/null @@ -1,21 +0,0 @@ -This example was contributed by Yue Chun Chiu (Chinese University of Hong Kong) -(Thanks!) - -This is a simulation of propane using the OPLSUA force-field. -(It uses the OPLSUA force field even though the file names begin with "oplsaa") - -IMPORTANT: This is NOT an all-atom simulation. - OPLSUA is a united-atom force-field. - Hydrogen atoms are not represented explicitly. - The force-field has been adjusted accordingly. - --------- Instructions: --------- - -More detailed instructions on how to build LAMMPS input files and -run a short simulation are provided in other README files. - -step 1) -README_setup.sh - -step 2) -README_run.sh diff --git a/tools/moltemplate/examples/force_field_OPLSUA_united_atom/propane/README_run.sh b/tools/moltemplate/examples/force_field_OPLSUA_united_atom/propane/README_run.sh deleted file mode 100755 index 5f82866644..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSUA_united_atom/propane/README_run.sh +++ /dev/null @@ -1,34 +0,0 @@ -# --- Running LAMMPS --- -# -# The 2 files "run.in.npt", and "run.in.nvt" are LAMMPS -# input scripts which link to the input scripts and data files -# you hopefully have created earlier with moltemplate.sh: -# system.in.init, system.in.settings, system.data -# If not, carry out the instructions in "README_setup.sh". -# -# -- Instructions: -- -# If "lmp_mpi" is the name of the command you use to invoke lammps, -# then you would run lammps on these files this way: - - -lmp_mpi -i run.in.npt # minimization and simulation at constant pressure -lmp_mpi -i run.in.nvt # minimization and simulation at constant volume - -#(Note: The constant volume simulation lacks pressure equilibration. These are -# completely separate simulations. The results of the constant pressure -# simulation might be ignored when beginning the simulation at constant -# volume. (This is because restart files in LAMMPS don't always work, -# and I was spending a lot of time trying to convince people it was a -# LAMMPS bug, instead of a moltemplate bug, so I disabled restart files.) -# Read the "run.in.nvt" file to find out how to use the "read_restart" -# command to load the results of the pressure-equilibration simulation, -# before beginning a constant-volume run. - - - - - -# If you have compiled the MPI version of lammps, you can run lammps in parallel -#mpirun -np 4 lmp_mpi -i run.in.npt -#mpirun -np 4 lmp_mpi -i run.in.nvt -# (assuming you have 4 processors available) diff --git a/tools/moltemplate/examples/force_field_OPLSUA_united_atom/propane/README_setup.sh b/tools/moltemplate/examples/force_field_OPLSUA_united_atom/propane/README_setup.sh deleted file mode 100755 index 412634dfe2..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSUA_united_atom/propane/README_setup.sh +++ /dev/null @@ -1,33 +0,0 @@ -# Create LAMMPS input files this way: -cd moltemplate_files - - # run moltemplate - - moltemplate.sh system.lt - - ######################### WEIRD LAMMPS QUIRK:############################### - # The default pair_style used with the OPLSAA forcefield requires that SOME - # atoms have non-zero charge. Unfortunately, in this example none of them do. - # (This does not happen very often.) - # Since you don't need long-range coulombics in this example, LAMMPS will - # print out an error message and tell you to use a more efficient pair_style. - # To get around this AFTER RUNNING MOLTEMPLATE, run these commands in the - # shell: - - echo "pair_style hybrid lj/cut 10.0" >> system.in.init - sed -i 's/lj\/cut\/coul\/long/lj\/cut/g' system.in.settings - sed -i 's/kspace_style/#kspace_style/g' system.in.init - - # This will override the pair_style and pair_coeff commands in the - # system.in.init and system.in.settings files (created by moltemplate): - - # Moltemplate generates various files with names ending in *.in* and *.data. - # Move them to the directory where you plan to run LAMMPS (in this case "../") - mv -f system.data system.in* ../ - - # Optional: - # The "./output_ttree/" directory is full of temporary files generated by - # moltemplate. They can be useful for debugging, but are usually thrown away. - rm -rf output_ttree/ - -cd ../ diff --git a/tools/moltemplate/examples/force_field_OPLSUA_united_atom/propane/README_visualize.txt b/tools/moltemplate/examples/force_field_OPLSUA_united_atom/propane/README_visualize.txt deleted file mode 100644 index 019afc1444..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSUA_united_atom/propane/README_visualize.txt +++ /dev/null @@ -1,87 +0,0 @@ - - ------- To view a lammps trajectory in VMD -------- - - -1) Build a PSF file for use in viewing with VMD. - -This step works with VMD 1.9 and topotools 1.2. -(Older versions, like VMD 1.8.6, don't support this.) - - -a) Start VMD -b) Menu Extensions->Tk Console -c) Enter: - -(I assume that the the DATA file is called "system.data") - - topo readlammpsdata system.data full - animate write psf system.psf - -2) - -Later, to Load a trajectory in VMD: - - Start VMD - Select menu: File->New Molecule - -Browse to select the PSF file you created above, and load it. - (Don't close the window yet.) - -Browse to select the trajectory file. - If necessary, for "file type" select: "LAMMPS Trajectory" - Load it. - - ---- A note on trajectory format: ----- -If the trajectory is a DUMP file, then make sure the it contains the -information you need for pbctools (see below. I've been using this -command in my LAMMPS scripts to create the trajectories: - - dump 1 all custom 5000 DUMP_FILE.lammpstrj id mol type x y z ix iy iz - -It's a good idea to use an atom_style which supports molecule-ID numbers -so that you can assign a molecule-ID number to each atom. (I think this -is needed to wrap atom coordinates without breaking molecules in half.) - -Of course, you don't have to save your trajectories in DUMP format, -(other formats like DCD work fine) I just mention dump files -because these are the files I'm familiar with. - -3) ----- Wrap the coordinates to the unit cell - (without cutting the molecules in half) - -a) Start VMD -b) Load the trajectory in VMD (see above) -c) Menu Extensions->Tk Console -d) Try entering these commands: - - pbc wrap -compound res -all - pbc box - - ----- Optional ---- - Sometimes the solvent or membrane obscures the view of the solute. - It can help to shift the location of the periodic boundary box - To shift the box in the y direction (for example) do this: - - pbc wrap -compound res -all -shiftcenterrel {0.0 0.15 0.0} - pbc box -shiftcenterrel {0.0 0.15 0.0} - - Distances are measured in units of box-length fractions, not Angstroms. - - Alternately if you have a solute whose atoms are all of type 1, - then you can also try this to center the box around it: - - pbc wrap -sel type=1 -all -centersel type=2 -center com - -4) - You should check if your periodic boundary conditions are too small. - To do that: - select Graphics->Representations menu option - click on the "Periodic" tab, and - click on the "+x", "-x", "+y", "-y", "+z", "-z" checkboxes. - -5) Optional: If you like, change the atom types in the PSF file so - that VMD recognizes the atom types, use something like: - -sed -e 's/ 1 1 / C C /g' < system.psf > temp1.psf -sed -e 's/ 2 2 / H H /g' < temp1.psf > temp2.psf -sed -e 's/ 3 3 / P P /g' < temp2.psf > system.psf - -(If you do this, it might effect step 2 above.) diff --git a/tools/moltemplate/examples/force_field_OPLSUA_united_atom/propane/moltemplate_files/propane.lt b/tools/moltemplate/examples/force_field_OPLSUA_united_atom/propane/moltemplate_files/propane.lt deleted file mode 100644 index d82d8cfd9b..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSUA_united_atom/propane/moltemplate_files/propane.lt +++ /dev/null @@ -1,31 +0,0 @@ -import "oplsaa.lt" - - -Propane inherits OPLSAA { - - # atomID molID atomTyle charge X Y Z - write('Data Atoms') { - $atom:CH3a $mol:. @atom:10 0.0 -0.748 -0.015 0.024 - $atom:CH2 $mol:. @atom:13 0.0 0.558 0.420 -0.278 - $atom:CH3b $mol:. @atom:10 0.0 0.716 1.404 0.137 - } - - write('Data Bond List') { - $bond:CC1 $atom:CH3a $atom:CH2 - $bond:CC2 $atom:CH2 $atom:CH3b - } - - # These atom types are defined in the "oplsaa.lt" file - # (usually located in the "src/moltemplate_force_fields/" subdirectory) - # @atom:10 "N-Alkane CH3- (UA)" - # @atom:13 "Alkanes -CH2- (UA)" - # - # NOTE: UA means united atom (no explicit hydrogens). - # The first 56 atoms in the "oplsaa.lt" file are united atoms - # - # NOTE: Charges will be assigned by OPLSAA, so we leave them 0.0 here. - # - # (The "." in "$mol:." refers to this molecule-object's molecule-ID number. - # The "." simply means this molecule is not a part of a larger molecule.) - -} diff --git a/tools/moltemplate/examples/force_field_OPLSUA_united_atom/propane/moltemplate_files/system.lt b/tools/moltemplate/examples/force_field_OPLSUA_united_atom/propane/moltemplate_files/system.lt deleted file mode 100644 index 6f266aac3d..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSUA_united_atom/propane/moltemplate_files/system.lt +++ /dev/null @@ -1,37 +0,0 @@ -import "propane.lt" - -# Periodic boundary conditions: -write_once("Data Boundary") { - 0.0 36.0 xlo xhi - 0.0 36.0 ylo yhi - 0.0 36.0 zlo zhi -} - -# Now add methane molecules: - -propanes = new Propane [6].move(0, 0, 6) - [6].move(0, 6, 0) - [6].move(6, 0, 0) - -propanes[*][*][*].move(2.0, 2.0, 2.0) - - - - - - - -######################### WEIRD LAMMPS QUIRK:############################### -# The default pair_style used with the OPLSAA forcefield requires that SOME -# atoms have non-zero charge. Unfortunately, in this example none of them do. -# (This does not happen very often.) -# Since you don't need long-range coulombics in this example, LAMMPS will -# terminate with an error message and ask you to use a more efficient pair_style -# To get around this AFTER RUNNING MOLTEMPLATE, run these commands in the shell -# -# echo "pair_style hybrid lj/cut 10.0" >> system.in.init -# sed -i 's/lj\/cut\/coul\/long/lj\/cut/g' system.in.settings -# sed -i 's/kspace_style/#kspace_style/g' system.in.init -# -# This will override the pair_style and pair_coeff commands in the -# system.in.init and system.in.settings files (created by moltemplate): diff --git a/tools/moltemplate/examples/force_field_OPLSUA_united_atom/propane/run.in.npt b/tools/moltemplate/examples/force_field_OPLSUA_united_atom/propane/run.in.npt deleted file mode 100644 index c1115f67bb..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSUA_united_atom/propane/run.in.npt +++ /dev/null @@ -1,43 +0,0 @@ -# PREREQUISITES: -# -# You must use moltemplate.sh to create 3 files: -# system.data system.in.init system.in.settings -# (Follow the instructions in README_setup.sh, -# or run the file as a script using ./README_setup.sh) -# -# ------------------------------- Initialization Section -------------------- - -include "system.in.init" - -# ------------------------------- Atom Definition Section ------------------- - -read_data "system.data" - -# ------------------------------- Settings Section -------------------------- - -include "system.in.settings" -include "system.in.charges" - -# ------------------------------- Run Section ------------------------------- - - -# -- minimization protocol -- - -thermo 500 -thermo_style custom step temp etotal press vol -minimize 6.0e-5 1.0e-6 500 400000 - -write_data system_after_min.data - -# -- simulation protocol -- - -reset_timestep 0 -timestep 1.0 -dump 1 all custom 200 traj_npt.lammpstrj id mol type x y z ix iy iz element -velocity all create 200.0 4928459 rot yes mom yes dist gaussian -fix fxnpt all npt temp 200.0 200.0 100.0 iso 1.0 1.0 1000.0 -neigh_modify delay 5 every 1 check yes - -run 100000 - -write_data system_after_npt.data diff --git a/tools/moltemplate/examples/force_field_OPLSUA_united_atom/propane/run.in.nvt b/tools/moltemplate/examples/force_field_OPLSUA_united_atom/propane/run.in.nvt deleted file mode 100644 index 115bfe527f..0000000000 --- a/tools/moltemplate/examples/force_field_OPLSUA_united_atom/propane/run.in.nvt +++ /dev/null @@ -1,39 +0,0 @@ -# PREREQUISITES: -# -# You must use moltemplate.sh to create 3 files: -# system.data system.in.init system.in.settings -# (Follow the instructions in README_setup.sh, -# or run the file as a script using ./README_setup.sh) -# -# ------------------------------- Initialization Section -------------------- - -include "system.in.init" - -# ------------------------------- Atom Definition Section ------------------- - -#read_data "system.data" -read_data "system_after_npt.data" - -# ------------------------------- Settings Section -------------------------- - -include "system.in.settings" -include "system.in.charges" - -# ------------------------------- Run Section ------------------------------- - - -# -- simulation protocol -- - -reset_timestep 0 -timestep 2.0 -thermo 500 -thermo_style custom step temp etotal press -dump 1 all custom 2000 traj_nvt.lammpstrj id mol type x y z ix iy iz element type -dump_modify 1 element "C" "C" -velocity all create 200.0 4928459 rot yes mom yes dist gaussian -fix fxnvt all nvt temp 200.0 200.0 100.0 -neigh_modify delay 5 every 1 check yes - -run 1000000 - -write_data system_after_nvt.data diff --git a/tools/moltemplate/examples/force_field_explicit_parameters/aluminum_crystal_strain/README.TXT b/tools/moltemplate/examples/force_field_explicit_parameters/aluminum_crystal_strain/README.TXT deleted file mode 100644 index 115c1fab35..0000000000 --- a/tools/moltemplate/examples/force_field_explicit_parameters/aluminum_crystal_strain/README.TXT +++ /dev/null @@ -1,54 +0,0 @@ -NOTE: This example requires the "Al99.eam.alloy" file. - (It was not included in this directory because if its large size.) - As of 2012-11, I was able to obtain it here: - http://www.ctcms.nist.gov/~cbecker/Download/Al-YM/Al99.eam.alloy - Copy it to the directory containing this README file. ------------------------------------------------------------------------- -This example shows an alternative way to setup the -aluminum crystal loading simulation described here: -http://icme.hpc.msstate.edu/mediawiki/index.php/Uniaxial_Compression -by Mark Tschopp and Nathan R. Rhodes -For additional backgroumd information, please consult that web page. - -In this example, I use moltemplate to build a "DATA" file for this system. -(I can't think of a compelling reason to do this for simple simulations like -this. But this approach might be useful if you want to artificially create -unusual structures out of aluminum crystals, or mix them with other molecules. -I created this example in response to a user request.) - - - --- To build the system --- - -Carry out the instructions in README_setup.sh, -to generate the LAMMPS DATA file and input scripts you need: -system.data, system.in.init, system.in.settings. -(The run.in script contains references to these files.) - - - --- To run LAMMPS, try a command like: --- - -lmp_mpi -i run.in - - or (if you have mpi installed) - -mpirun -np 4 lmp_mpi -i run.in - -This will create an ordinary LAMMPS dump file you can visualize with VMD -traj.lammpstrj (See README_visualize.txt) - -It will also create a number of other files, such as: -dump.comp_0.cfg -dump.comp_500.cfg -dump.comp_20000.cfg -Al_comp_100.def1.txt - -The dump.comp_*.cfg files can be visualized using -AtomEye if you have AtomEye and ImageJ installed. -The procedure for doing this is explained in the original tutorial at: -http://icme.hpc.msstate.edu/mediawiki/index.php/Uniaxial_Compression - -The "Al_comp_100.def1.txt" file is a four-column text file containing: -column 1: v_strain = (lx - v_L0)/v_L0 -column 2: -pxx/10000 (diagonal components of the stress tensor) -column 3: -pyy/10000 -column 4: -pzz/10000 diff --git a/tools/moltemplate/examples/force_field_explicit_parameters/aluminum_crystal_strain/README_setup.sh b/tools/moltemplate/examples/force_field_explicit_parameters/aluminum_crystal_strain/README_setup.sh deleted file mode 100755 index 22eb8c4357..0000000000 --- a/tools/moltemplate/examples/force_field_explicit_parameters/aluminum_crystal_strain/README_setup.sh +++ /dev/null @@ -1,29 +0,0 @@ -# Use these commands to generate the LAMMPS input script and data file -# (and other auxilliary files): - - -# Create LAMMPS input files this way: -cd moltemplate_files - - # run moltemplate - - moltemplate.sh -atomstyle full system.lt - - # This will generate various files with names ending in *.in* and *.data. - # These files are the input files directly read by LAMMPS. Move them to - # the parent directory (or wherever you plan to run the simulation). - - mv -f system.in* system.data ../ - - # We will also need the "Al99.eam.alloy" file: - #cp -f Al99.eam.alloy ../ - # This file was (can be) downloaded from: - # http://www.ctcms.nist.gov/~cbecker/Download/Al-YM/Al99.eam.alloy - - - # Optional: - # The "./output_ttree/" directory is full of temporary files generated by - # moltemplate. They can be useful for debugging, but are usually thrown away. - rm -rf output_ttree/ - -cd ../ diff --git a/tools/moltemplate/examples/force_field_explicit_parameters/aluminum_crystal_strain/README_visualize.txt b/tools/moltemplate/examples/force_field_explicit_parameters/aluminum_crystal_strain/README_visualize.txt deleted file mode 100644 index 019afc1444..0000000000 --- a/tools/moltemplate/examples/force_field_explicit_parameters/aluminum_crystal_strain/README_visualize.txt +++ /dev/null @@ -1,87 +0,0 @@ - - ------- To view a lammps trajectory in VMD -------- - - -1) Build a PSF file for use in viewing with VMD. - -This step works with VMD 1.9 and topotools 1.2. -(Older versions, like VMD 1.8.6, don't support this.) - - -a) Start VMD -b) Menu Extensions->Tk Console -c) Enter: - -(I assume that the the DATA file is called "system.data") - - topo readlammpsdata system.data full - animate write psf system.psf - -2) - -Later, to Load a trajectory in VMD: - - Start VMD - Select menu: File->New Molecule - -Browse to select the PSF file you created above, and load it. - (Don't close the window yet.) - -Browse to select the trajectory file. - If necessary, for "file type" select: "LAMMPS Trajectory" - Load it. - - ---- A note on trajectory format: ----- -If the trajectory is a DUMP file, then make sure the it contains the -information you need for pbctools (see below. I've been using this -command in my LAMMPS scripts to create the trajectories: - - dump 1 all custom 5000 DUMP_FILE.lammpstrj id mol type x y z ix iy iz - -It's a good idea to use an atom_style which supports molecule-ID numbers -so that you can assign a molecule-ID number to each atom. (I think this -is needed to wrap atom coordinates without breaking molecules in half.) - -Of course, you don't have to save your trajectories in DUMP format, -(other formats like DCD work fine) I just mention dump files -because these are the files I'm familiar with. - -3) ----- Wrap the coordinates to the unit cell - (without cutting the molecules in half) - -a) Start VMD -b) Load the trajectory in VMD (see above) -c) Menu Extensions->Tk Console -d) Try entering these commands: - - pbc wrap -compound res -all - pbc box - - ----- Optional ---- - Sometimes the solvent or membrane obscures the view of the solute. - It can help to shift the location of the periodic boundary box - To shift the box in the y direction (for example) do this: - - pbc wrap -compound res -all -shiftcenterrel {0.0 0.15 0.0} - pbc box -shiftcenterrel {0.0 0.15 0.0} - - Distances are measured in units of box-length fractions, not Angstroms. - - Alternately if you have a solute whose atoms are all of type 1, - then you can also try this to center the box around it: - - pbc wrap -sel type=1 -all -centersel type=2 -center com - -4) - You should check if your periodic boundary conditions are too small. - To do that: - select Graphics->Representations menu option - click on the "Periodic" tab, and - click on the "+x", "-x", "+y", "-y", "+z", "-z" checkboxes. - -5) Optional: If you like, change the atom types in the PSF file so - that VMD recognizes the atom types, use something like: - -sed -e 's/ 1 1 / C C /g' < system.psf > temp1.psf -sed -e 's/ 2 2 / H H /g' < temp1.psf > temp2.psf -sed -e 's/ 3 3 / P P /g' < temp2.psf > system.psf - -(If you do this, it might effect step 2 above.) diff --git a/tools/moltemplate/examples/force_field_explicit_parameters/aluminum_crystal_strain/images/AlCell_LR.jpg b/tools/moltemplate/examples/force_field_explicit_parameters/aluminum_crystal_strain/images/AlCell_LR.jpg deleted file mode 100644 index bf07914dac8fc5c9e0a6aa8f19befc1a24a3b2ca..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2364 zcmb7_c|26>AIHy`&CJ-&jL4E2YqAt$>*iuyT_Ry*xhW%5vNs9|p+#9HKl_@pH9~bK zONz>v1{H;g>`SX9?vPxh+%sD4{rC4h=XGA^^*pcd^L(Dq^L^gWYVYbO09jjDSpXmi z0=wV`SRDY&0VF~Yf-e#d6b2;-ECz$d;IMc+4vWL#MZ`t$!eYWWoG3w5OdNs;5MG2R zL4+jWe@HM0D9A*juy7(Ij1z`i|Ib)$0ti^Z4zNdp1OPz*kpyt{5g-Rk1&{){KLdk8 z3xP;1+$jq;Bar{;0stf$M4&LM{eTGEj)0I50DvoHKXRXM+fkD>)pIA&Px^REfL@1V zD==k}DQEqKS=yZR80t&|N`q>FijfHM_OU`aL1vQmN$)xY|n!;K)L9kQ+ zcKC-D0Eq$-Xbce`Nvxy5g0b*oKr~|IaS`t=Qz+Q4G@<9f>)Fy9nAdd<58^_=jrq}f zBe*JBS+C1Z4z2(4w8cP}qi3z%wcSYdD}kPjDynGE-H6B%se)%oPNp^tvZ{koj}$>q zTDoPUK47qL+u7{7Eze!zXdozkF(&;)MU>M1^x;guu39FQ$i8RP0wVupl`RZ;H0LOJ zuZ+NwRpEVr-9)2*N(K=CfdmnC%oNBJbE@KR4j!><%Ha(%1t;1=3+gl;;JL}&WhDt| zWcj2g!$(|}tcfrDvUVF?`CqQAYhK?VqpT)833Jag{86ALy7C5%SZQ4K%d9TewNhG0ehN+F)0I63jx5o{b()Q~VD~1pQqo*PMO|54E>UuOzm9M$*EM(! z4fb8LcgSYkH)kjjyl1sKqOIg>o=F)^TR!qL;Y4rwRGxn~u)p;{Z_VQjVorW>72QZR z{<62lyhcVw5YB`zcBW>ObM{JrzCY8IKGd3=!`R^1dT_aVVSF=9r0~W20cY3gK#9g^ zh2o3xRkiL2&a@dVH;msWLh6NsQ+1`etH9n(1J6cWy;K_L>d8`-o{V-T;l^$sOZxMA?s|vD z%E&E@sd%6Mm+H|4viEQKR=sb1RNYxRqnCeD>U`EwHyKG68h{t?XD06IVxz^BO{!SEXrA)7^)#d=>SA1VMMyDgpLFBMXOGnSxgYNPW4O#j0rHTEp1_5A@9@-xwB$d;_%%KPisp;N=8m^G>$0#l}lH=t3KpsNX9|) z()u^a({l`la-ld2BTGO7oQ1bai_vpZ*h98FV& z#m4ZZKVIZvi*gYgU%ql$(e-%~&Y0-w2oqks;7Z(?91;0sPiRc)t50qu?Y+B7x0=PP zI;k|q0e~Yvx>x_O+w(!}XVIgF-2K@*ahaIyg1?k^-LsmBDB*x7#u)Jn)sUbkhIrw?kIn8K@C zBP1Z;5tM4By!L|nOUkq_B{5c#sg}xLtrU@ul`EYNeebpVh6Di-Q2$a4go&V_<3TZ_ z(pj;EY(A9Ix#pMv2@t1mYr&*@f->;d3VC9i+S?6WpM~=uK%pDGCMo2^k3dDYy;-@; zsU!@ep}f98A>D8TDe^3tO90cyqDZ4v?PW1Z%7d!qzE0wuD?7Dw`T!Jvt+-VQFe?RQ z`pN!p`{t2CqS9jvAqtDlA6t_l-~qHSu4&7XYg=Ua(j4`ad_ShoL-KuH7Zfx>^>O=R zv3N+bjU<($a|zcp@1bZt-i8YbokEpU2fSShid*=e@*S(dX&)OOQI*GlO18rhk-JSw z4ld_%zBX=dJEk(55VS-2Ph2+;PV48-*Y#~WAa3I}W;>lYJ^1Cc-1y-AnNr+7A*nqgj%emnPgHM1{hg4mVF8{MA;I;B08u}0z%>)7W+V@KEG32Y4T!K& zrqIffID`5A0Uk3eFkwo~7A14)>L^F7o+FGNM<-RSKXiz&Xy77ZR>ngZZ)!Z%|30Pn zUB!D99zqK`AK$ucvw`AJJ*_rJi{O4HJDt(iJT_Om(i^CEHE7lXC&sF?P~c$b%#&vI z=ZxqwP1(2VQl4p}D<(I0s%73Zy_QJjL$4n;1oLcc*`d+Hi&?A&VH9-7wu*M^kJ57= zcz*|1AC)vS=jze^O15U&+PH0IbsAsioqiw@H7B7oD({^)rqBFqLx|e=LgdLWV@j4# za;}fzbfUp8_qfhwE>E)Q6CRsn>`faA+!C$xcy-0bEcV;`A1_VGQpSivw#02Sm=tZx z^u%XHEzHveNNSmee`CqLqy$}d2k(ZLVrywj4B}WIt+vr-AyttD RX!NLYjPO&9hb^mp{{YWDqPPG6 diff --git a/tools/moltemplate/examples/force_field_explicit_parameters/aluminum_crystal_strain/images/AlCrystal10x10x10_t=0steps_LR.jpg b/tools/moltemplate/examples/force_field_explicit_parameters/aluminum_crystal_strain/images/AlCrystal10x10x10_t=0steps_LR.jpg deleted file mode 100644 index 8650cf5cb0510222cf243a4d6cdcbfcd8994fb22..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 30158 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 a@xM7k|JC{ax3fEKC^(FPC@5CC-l9e}^f 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 Console -c) Enter: - -(I assume that the the DATA file is called "system.data") - - topo readlammpsdata system.data full - animate write psf system.psf - -2) - -Later, to Load a trajectory in VMD: - - Start VMD - Select menu: File->New Molecule - -Browse to select the PSF file you created above, and load it. - (Don't close the window yet.) - -Browse to select the trajectory file. - If necessary, for "file type" select: "LAMMPS Trajectory" - Load it. - - ---- A note on trajectory format: ----- -If the trajectory is a DUMP file, then make sure the it contains the -information you need for pbctools (see below. I've been using this -command in my LAMMPS scripts to create the trajectories: - - dump 1 all custom 500 DUMP_FILE.lammpstrj id mol type x y z ix iy iz - -It's a good idea to use an atom_style which supports molecule-ID numbers -so that you can assign a molecule-ID number to each atom. (I think this -is needed to wrap atom coordinates without breaking molecules in half.) - -Of course, you don't have to save your trajectories in DUMP format, -(other formats like DCD work fine) I just mention dump files -because these are the files I'm familiar with. - -3) ----- Wrap the coordinates to the unit cell - (without cutting the molecules in half) - -a) Start VMD -b) Load the trajectory in VMD (see above) -c) Menu Extensions->Tk Console -d) Try entering these commands: - - pbc wrap -compound res -all - pbc box - - ----- Optional ---- - Sometimes the solvent or membrane obscures the view of the solute. - It can help to shift the location of the periodic boundary box - To shift the box in the y direction (for example) do this: - - pbc wrap -compound res -all -shiftcenterrel {0.0 0.15 0.0} - pbc box -shiftcenterrel {0.0 0.15 0.0} - - Distances are measured in units of box-length fractions, not Angstroms. - - Alternately if you have a solute whose atoms are all of type 1, - then you can also try this to center the box around it: - - pbc wrap -sel type=1 -all -centersel type=2 -center com - -4) - You should check if your periodic boundary conditions are too small. - To do that: - select Graphics->Representations menu option - click on the "Periodic" tab, and - click on the "+x", "-x", "+y", "-y", "+z", "-z" checkboxes. - -5) Optional: If you like, change the atom types in the PSF file so - that VMD recognizes the atom types, use something like: - -sed -e 's/ 1 1 / C C /g' < system.psf > temp1.psf -sed -e 's/ 2 2 / H H /g' < temp1.psf > temp2.psf -sed -e 's/ 3 3 / P P /g' < temp2.psf > system.psf - -(If you do this, it might effect step 2 above.) diff --git a/tools/moltemplate/examples/force_field_explicit_parameters/ice_crystal/images/ice_rect8_crystal_3x2x2_LR.jpg b/tools/moltemplate/examples/force_field_explicit_parameters/ice_crystal/images/ice_rect8_crystal_3x2x2_LR.jpg deleted file mode 100644 index 2cdc08b312b4431ed0677777b6f96249836f3809..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25820 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 diff --git a/tools/moltemplate/examples/force_field_explicit_parameters/ice_crystal/images/ice_rect8_unitcell.png b/tools/moltemplate/examples/force_field_explicit_parameters/ice_crystal/images/ice_rect8_unitcell.png deleted file mode 100644 index 5bd6057e1e6ffb99a48879d64cedc5a1dbb96459..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21951 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 Console -c) Enter: - -(I assume that the the DATA file is called "system.data") - - topo readlammpsdata system.data full - animate write psf system.psf - -2) - -Later, to Load a trajectory in VMD: - - Start VMD - Select menu: File->New Molecule - -Browse to select the PSF file you created above, and load it. - (Don't close the window yet.) - -Browse to select the trajectory file. - If necessary, for "file type" select: "LAMMPS Trajectory" - Load it. - - ---- A note on trajectory format: ----- -If the trajectory is a DUMP file, then make sure the it contains the -information you need for pbctools (see below. I've been using this -command in my LAMMPS scripts to create the trajectories: - - dump 1 all custom 5000 DUMP_FILE.lammpstrj id mol type x y z ix iy iz - -It's a good idea to use an atom_style which supports molecule-ID numbers -so that you can assign a molecule-ID number to each atom. (I think this -is needed to wrap atom coordinates without breaking molecules in half.) - -Of course, you don't have to save your trajectories in DUMP format, -(other formats like DCD work fine) I just mention dump files -because these are the files I'm familiar with. - -3) ----- Wrap the coordinates to the unit cell - (without cutting the molecules in half) - -a) Start VMD -b) Load the trajectory in VMD (see above) -c) Menu Extensions->Tk Console -d) Try entering these commands: - - pbc wrap -compound res -all - pbc box - - ----- Optional ---- - To shift the box by a fraction in the x direction (for example) - do this: - - pbc wrap -compound res -all -shiftcenterrel {-0.50 -0.52 0.0 } - pbc box -shiftcenterrel {-0.50 -0.52 0.0 } - - # Alternately if you have a solute whose atoms are all of type 1, - # then you can also try this to center the box around it: - - pbc wrap -sel type=1 -all -centersel type=2 -center com - -4) Optional: If you like, change the atom types in the PSF file so - that VMD recognizes the atom types, use something like: - -sed -e 's/ 1 1 / C C /g' < system.psf > temp1.psf -sed -e 's/ 2 2 / H H /g' < temp1.psf > temp2.psf -sed -e 's/ 3 3 / P P /g' < temp2.psf > system.psf - -(If you do this, it might effect step 2 above.) diff --git a/tools/moltemplate/examples/force_field_explicit_parameters/nanotube+water/images/graphene_unit_cell.jpg b/tools/moltemplate/examples/force_field_explicit_parameters/nanotube+water/images/graphene_unit_cell.jpg deleted file mode 100644 index 12dbf8fca27b11b0fd470210ddce55b065a5ea51..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13144 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 I_}{|+0SPm*vj6}9 diff --git a/tools/moltemplate/examples/force_field_explicit_parameters/nanotube+water/images/nanotube+walls+water_side_pbc_t=0ps_LR.jpg b/tools/moltemplate/examples/force_field_explicit_parameters/nanotube+water/images/nanotube+walls+water_side_pbc_t=0ps_LR.jpg deleted file mode 100644 index 15d3f189d3097433de7d8d9b89ebd454fd30c9d3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 30772 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 Lo%oHM|H1wb_{1a{ diff --git a/tools/moltemplate/examples/force_field_explicit_parameters/nanotube+water/images/nanotube+walls+water_side_pbc_t=108ps_LR.jpg b/tools/moltemplate/examples/force_field_explicit_parameters/nanotube+water/images/nanotube+walls+water_side_pbc_t=108ps_LR.jpg deleted file mode 100644 index 298957864f16def4e4351b43dbe4bba173f12477..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28367 zcmb5VcT`hP6fPP%1f>Zm9V8I~0)l|_UXsw0P^2jWB2{Th@1P(hgaoBX4G?+{Rhmdu zkdAYt1@qX3hTg%sKn)GvA*1H~DWKzyQ~RX#q$`NC435 z3-E6mpbj7-{ZIZY$*zT*lKelRrlh2xq@e}^X{c#vfH&xG0BPxHX=rXT-lU^vU|?hb z-e9`L#Bl5Sp5Z?wB>(j!Bd5OZ$UsX&dtLi~DgW94jMOA?06ZDVT>vQ~2^k~FzfJ%b z06d6vMYzcQqQpMy8@EZ>L?RiI}fj1yav)Zta^B4f##l|rm1~+ zWKqb4sYjjd_5=tOBEhPoTwT0K{i~w>9CO&b> zTX$8BY}}b85TS|Ll~qH#52ZZXS*{I1qMq4?VMajep1IWvRJS#9h9xy4uCb;7H^@k? z2Y#(U8Q`_MS0^9*nIrqPxkZXZ<5%PTqCCF82k(`chpiy!@b6TZuo&ZbT*8B;k@46o z-f2-Lrqq??bj~Bx%Qr%V1tLP7ts z)MNnFX2TsR=jK&`dxY5K^M8QP8(M4QxA!LA1zSAH$Nzn34K0~hpmLccx!d5g$Gx;A zy&L@Gck7cKxr;Y#CjD|hwWn|Ud8m@3(qzt-L>T8DUz!iIO9sj9(Ot2&>T%zgzzECm zkW9 zEg#Vims%cod(&n;P!G`i;!7lL0Hh`<@=Wzkh|eoO?|^H1?6UDD9Va~&0Ht3!ucik- zrva^Pu`6@=gukSHlAl27+*`6(PRb!uLT1?vy|Xqtt*mT%bzaCWzQOKUdVwYN4Kkl$~2kX6h z5)zk-XrLwj)%TMjbZACDM*E(?xuf0^x5JYT+{=XW6-?@#F;DU9C;+frS6D0G(PHH~yr!L#?C@;t?Dg6T+1b1Kh58#H%uH^TqHsD7A zg1gU~Q@``KDUC#W-p)H?=})|y$9d~-aP3t@LK%Ha?zRC%lZeB#u|-a0z}$CL{1-o$ z54TY9%xsQA=4}^kRJ_~?gWOZ2Q&|@%c#2P&`j=mq~yaDSQBN*An|QopS~uO7n@$Ii8C9Po$;>3(^$TDn@- z)Q64m<~b@GC5G>JPgws0&?P9>y#fDR=p)qb5_ycRe_BM~pgGq*$Dg=m{{fXhnj3;D zA&J=Nov)Ej18%81lixickdmAi^d?L+Tn38;PuVwXwBugr6CYj0ei?vOfs&nXRHYXg zv#V00F;q?>7*41nSIWc6TWxFAvXh!()1O4JA*QF5+p&bd(D3 zRp9vhT7{qx)5c)&J4kJ<$dW%+%152QthjcOimRa`%VNp z1756R*3v8hFfX3QmFG^%($vR>Zps86uR`06;xyxdFXrCz&)YTCmQ?k=c-mGAn{fF=J88e= zsbNG3Ph$JpMS>snC$LsidbtU>fUYZktx>Is*@#{&yaA%nOiaj)WgRfE%d@^ZtE@Gf zi%F=PIO6v<$@(soGwgaE8Bh`RBX2(%qCWlOk4T}$;fJ?}-n8`h{(QJkmuI;gSaTT6 zWT*1$v0tIiZ*)<0jibu;@x+aPfW4~-pLB02DuHsh^OMscW%cr*rZh`c{#P&VkSPwj z1Q!?uQ_fyRKIsc$F8Q;Ozr~K^s3www-d}~TA75F|Jt=Q#bqj5>c&e`)0R#*Z9f-;` z8=2wd${OV>%D{&OWoeR*P`B|(#>@rM5Jk;vjc=~QakydnBH{mEG!a1WBEI!`(2UwL33O=2>ykb5c{0G1bzx)RnGy4Y^{|B(XN?n~l zZ~b5W;*9-??JaKo$QRRJ&?`MGXJ?9g2JdPLiK7w{T!||JWtT$ABGO#L)8et)T(xt9 zTPEV?r;h$FhTZ()x*PXz^;kYsqQm5I?&fKNiS^-A0o@9#(9;9hnNwH$hlcoQ{_csS*H}`nR-DlYF7tvfqDki$7|)c{P+OG|G|#LpbM={BffFk_ zJM)%90rPv&*n}lamh_to_xW*mYp@mju>0$e{Yy3eIVp8#;+7Y8d8KH*Q)tX?Zd)1i zitTuF^X}|zm~Io4Y0?c#f5k`Sk$mniTA*12`HH`VDJHzk9NCp?l^PJ4xZ`t~=`JaL z_$-chCyUBeAdG~ELw7AU{GvrEvnH}d(Y0o24(a%|{Op{)wEe2G?)=3`q{tw{3G(eE z*3x$K-Suo1=bqPgZ?f}TX@+kl99Jo}WK5l`jfxr%3Z6L{3dx$RG}n3>1JjMSl33WT zzVjpzuRM=gwI}$E0C)# zx`Pe8_l||t)!A-Idh7nu^n>ZEEgsBxcir-e*v0qO?a}oK~<%aBy#< z>1kTBP~)QYrr>6WkE>?B@>!AWr>sCm+*RKn zaa!)+#!r$jhKl;E9Cj$97o48--sxW1(&2hdm3Vt@x^ z^>#t7c^cudu!79<4fe7Qr3%}vf?4JQ1@&JBe%FD*Tl6|kyvX_A70t$Zr(TZRHdL_= z`nOLEvd))Q^0u*d6x7? z#@cZ-Z^AA}%<~`M?k6*W^`pz0^CEmup!AEOT;s#WYy}R8@N|FNDA-2S$}^cppQK;+ zHPy(`#X;_qj2jP1ON(T1*)WgAWc=O$)$gCDJZ=Z$aWDQhZ8RmGKLI|UTT8NRzR$Be zaDXQXZSZzGIQSB1%ky^P_{N(+XMUI8yVD%@emggnmZI$4|fN7Ffp*C;y~XGnry4w-Zg0vtJJr-e=*ZS5sq%7MWVyp zZ`m5&zlZP{KnggiRpA^$pcPj;l8KK=lf6LyhL-8zCw2Khu_+1Ak4ucJz3zGu)r@$h z$dEmw9z=ZzfT~siEX!W_MVv!RjLo+j07bwQL)CN<+AIU$%aOcMU>?Hfj;Pi}EMLB?DZ;WXDD;TZJQkr;)EJBZwc@N%P|GgfKr!tNO+X*ryG-nP2oWu5K zHYu==CWIRasTwMW~q4ovhUYblUq!_7H-1p|) zO?+W~3_G%(DMOn{91%g}|<7T4pGD5Drxb*ow3SJD*y&rJWF-iF_L61$(!cWR{yjg22jw|M|TkgGV(TerdI7(qz zG${gC`Zdp90f8-L1FepQ&;Yy35*KM5oiTT!4Vvy)?C?T5UzzY@szN@XsF;h<$Ad(c z6KW#`kuY1C!y)Y0`&{Gu^vo8TQWG<;iJL;6Zq5Bt5Rr&(Y<`sS%2QnNnj$|aL>{5` z`KXoQ++HiUy|@mUWMr(5;Ol%#Co5s;?zpT-yA&F_?S9Cn_+poMrFG)lrAW0(2rRxc&7t8i6-o9Fpb}q`XEe7(C^cMX;QjTDCP5{s7lUJJCxKop zVt@z_xue(AhJ8>u^JyNYrpMghbB7B?@$CuPq3r3GYC3%4I51)9yDOE#C;}Ou^pl^B z{FZ{X#TC86UeUVfe|u5qbnr}Vht7SZixovCag;&C+leG}t7gT^%@HN@24 zL~OQ$P}^Z*`cYZmlXr@QBDkjfes=vxe8A)&F^lk5M(G&_$T&Cl#PXa|<&n$Hak-N` zd&v*;O;j&K@Kn;9g}nPl0nijIc=ie#(rPNI9?ctGp51bXH0kw@ zjCs?e<$aO?m4n*}!ABSR>5m3&MDz}`YV}LuIK4tO+P}bb5lSKT=S z3w+jC5=M#Lc83D)Xul>Hl;PaUdlNEJPi=*Yfm5jZ!=iAU6E^u7>$<)DT_Fs*jv+KO z#L}RFLQ^DOrmwccj=le0p2Shvw`W;d9TAcl5>G_;o&)E z-C@LhIwWxQFskv}2&E+fE8t*!ug6_H=bJUqFrrZCVhTW&0s)+--=O0qq&P)9vNN#w z0IH~qt;zQ43Gi3Zr|0I5pl`g@%|Dm@M}W|U{${d-djyTBY2w4sAp4ET!2+N{tB6>C z+ls)@d6o6kotYu2+fsd)387q%83`-GXHfR|QZw^DTJ|;&n}rYWpIlxQ0(p_lJIqKF z{sYh$d@QnOa!QJ_^0qWx$r4DB?Q1lhCD9f#9Po_3w-6u{Bt%Z04ONNREOdw#HWh^f zGL(J=jLL1U3Zy&To;uKdU|A^g)us+lsO2KI|8erAzikci{6(NS>+*)}H;E*p2N z>rT9Tz0Fa-Mm=uS--HIG@eyR7u!6t^ASImqu(qg@8RB7&SQbF&rhr~;jQ8RYqEbNbT3YQe}9@YSi#Pk0F z6eacS8)_TBrRa}|0&5y>aU#$&QJfU2!IFZ-3ejtaL7(Eg8ZL%flZFX}#_%yVi24t(^iGd=ripK?9TOc1Su2eF zxQGlht;58w2@^O)4jd?XFg;+!kPJRaP@mf_$58o>`k=Z@2YK zBkwWb#6W_sJmViA?v~M?L~o26-b+_) z5+|3dS)@qwaa(#r@+5uP(mbKOUxtg~>4Juxod*aISc>>)d#V5tLx8}w7iMo1EMGZL zlh5PP;^C9By$1b67io~#UjTUIViBL ze$j$4LWv52{Tq~b{YmZhIrQ9z?o=P1UHt=iIDZIDOt_icdrD|A7}-gj*uL;`cD`QC zKAEMTEg#J_D!qzU96Mcj$7^lz%`gM_P#)2{5qRg|+|l`!^!m`uhVS(A{k*$&nrPxEv*89Ey#t5Y z7Vw12KTNd;#L3t^%i|W8k&G9aUuoiNef!=hlHs?(sw^cwF=Xl-WN)TG#hnxp$T>`R zUXdbi@WkeY8U`=kBPPQOb;)$QG9RpbE|#f&i$a5DJ&E~`iJ@M=q~u)qG{OH@xCFs&S6Zv3L-R^{x)_rw)fo|z$6Pnrt#WeIr3IT974)~M zV?IWG<6sJFvo!87Pb;Xw6-K6)R%K;q3V|>We{PHn%9kZj>q^~cB7ImZY+>asgp)kf z^xlk$m+y8l=e|NW@STjI2})l}?0rjH?&Gv_d!yH5%uynaaU(6@?B6Y`JT(CGFX10j z3*hLm+G73?wr=x;Ia;!puY090O&tk>m?K0$@|<9y!l4HPW0$mVA%w(<_U1gNbW1mv zOg@%ml(XeC<*z3|k|Lo3!v=e;XVu2>=5>qB95~T*g#r+9Bia})CXUG&`qgfj2 zGBFYQ2cUmtygc@-%}w%6a)G+|t9a^5ax9)4cf;=7q50&KdD?r;T-PK0j0-I%sUA@k z*JGg@#ozM94MFuAy5vOkGz6?O-=ZT3k%cP6XYKw2*qc348b%6?iI^)|dDu7c{q%r1 zQYUY?)hExXajt~6&D)lZg-Cc6Ker#IH@W1PVD>7{T*TJtGf$!R2Olwqu(^}9R8Z3M z%}vN&nlC##d8;ZgEX5ck_i;g8yM{s#E$Y0759E(8{my*Gf4F+;!rz~gX}G6gkRrc- zMZIMzKp1z1WT~kvH-l_=Au0fxLB1M`r)+6#CR~hNPGb2Q$)BR$GSuDbk6z4D=>~f} zP=s$(7hc`)`y*TYTLOYFB((X)v4nkloC`D+|EhDKq{1LS;K!p{Jo4p36vRJju5{m}@?ok`xgU!bH_W68EMgPY{8vK$C#Amz5e<$_hmxgn`DW(M5Em zARj+igZ`<6{AI2Vsjd;~O&CeSjq$JwRY6>O`Z1_p*`baY=eY~V7JO06LcoB3XM5V$ zZF|pdoWB?kfA8JB)7s@ZCpp5Sk+EPE#Kl^>&ARUic=qQNefdGcKR_<~=Oc9=kKUQU z-vU>Xg27Wgr{_U~$>pEk#MFGfeQfa$pvTgsU|>Lu`q~ALqG2|s1dtYSxB^E53jA=_}x)voR2CxG@UXg&6BO#@WPy0 z4z~%ylPz^bA+&~rH}?9P1b3ZruHRBz9_qPEAGswNpn$bz$X^VLU1SGNZzu%SeriMc zDO5WJWalOO%`yh|wjYkK7^UVlm^sp2NIk7soIic_$xLS$U4@0hTK;8G4HG$kOM80O($XZu|&-)SFYB8u^uvAvNMF zr7>x8C;Gd^mX|CaF<^{bx<%~u`WKfyAsU(^;TXoGPra2N6sG%K98E#JC4Ed2AZ-gh ztWAW{l55^$G9elj^3d3GmcXUBGM$)g{rcP1pJ($%gNCD?BlG&6HWykuVG8b+f1@B7 z%^sE3Vov^%g{L=%{gh|4^q8M&gr5(6OY)TIext;HEc$PTp7%_Y8`TNNIL#C_rmrw$8g>PKariTvT?OupAA-vp zYtPp(F60kVC_s%hZ2tk8L2DBZ;TjP>FKdP=0Uiba0Q(YNP8%_?OB1b2vO7g-wrfc< zin#gR{mKi-j=Uuz;}I!KL`KtV)8LXNfxUt9Pli`Kl#eWYN4~0GC=K-fGuKYs^xZ1e6!m z12nm=zGgq0R=0{a`8Oz)rUDn>o}G%LN7wATDPnE><(_IlclNAF9@vZHbxwV0(M!1+ zEiPUA#x-@gkS}>QRi7ugiUo_upqcd1#^}U7F318h7d&wi4uQ|QR=SWVC2Dl467~{#NWSVl~ zVcL&AULmBGt#X99ro4H4?g$unlWVx#>jn#OK4td3jkBr3TQOE$Qx3#u@ z*7{AAbEuKqdX6k*i}YIJ$iziHFDqEYF6@U=yU)`4D#XAJ!;+6IaUdGt^h?X`mo~$n z)ScZ`shJE^%8g^4k08WPFWt6H{zwOE&LaNQn!oS=AoB>Kd19{3Ef!5JQiCaZ8j`q! z6EzZhAvGVA#}PFvL9B~CC8LfKbva+(3(0$0 z`EhC8?|d+op{j$S<0pW-uuL6EzgIuHEM@utr^z%ON7gvH=DrkI(Mc`|i_~M7Z!mcA z#=lbzygOQ6Bu_jd9l)D2V>>O{`(k1H*gdyA^u#CL7M*u0u5`Q-xEpjDu?$jGLY0}8)mgS2c z4~s+}$@+MiEY^M-N1bifaSX1JHd|kyLWRo0CC`NGi3(bL4diW z%EM6oxY&eK(8kvWC&B6WrRprSn*n;Q=<+1p6m5p5pFlrL}85UB`+0 z`d`RHsx^4eE7KP)G9YB!$4?Wzu~0~&Pj^!;fK675nCE(a>c-e z{p(YU$xN!fe^xy=#pF4+F%ajcARx88Nl_LLlYKarxHYpnc;@9a60Pszw0m_l7%n}kfx!GYzMTTG`P8MwoTS~g9rAf!!eHG(!S}m6@ycQE-z_IB_jcXt zZxz3@v3gefI3n=>i_~u$Giv^yP(64BD)Tq_Mzic;3+!FZ=q#>7&HOci-jM zw%0~=RTFDag9HSn)TM+kq`~E>MFpFi3DOASJtHA zjAXGWcj3u1dI9}O4Q_}R(m|i<530d1z}Jy(6I-qso<%QceF>AtIme7uiNLYQbV5Sb-xK8 zP|4$Du#FGoBnc1jf+VFct3B4LiGAVser2aB%2ePhsp~C8$m{Xxg&G9Rbpl19s@&9f zbQ;Ver;7SB#^Y^2Dp{b%F6lI!s3V^Nowle64-@p0ItZ*?qE7o1(ox)BU;LC;ay%h}xWx!n=zyKZSbHHtZn<;=rxB9n(_JEjT^ z6j)b;$I_SkeKLQ}J&BTZ&Ws|@<6v}*C?M+zh(Fi?kK`ijBL>90f_++jhRy%;aMa{8 z{L9~`-KIRcQ^@eFgY)$W086O%LGEU-Oh&>&!DqgmqOjMP6(J+C1xo0dZ}gZO z<54(|tI}>>!y@;3!1Z3E;zBQH#lIQFlZ?W|W#N`tKmRVtx1rDS>))f>EUu}dr-f~` z5gB{&0?}I*uZOL9@o%@8rc>p9E13XoG%wq3}J7X@N#&j^>+%S>fu5P z7;=j-`==@AS4(jH!_wNLt!k&a2KF4oS%OLNgD-|_55Xz-rQ5yXe@)N;1T!;pO*ULq zILwCtQE^JGDQ(n!hi0$e5h?-Bm~F?{F-t^e!F3{qT;2bI)iDiz9>zNpL>KslJa<6T zGm&b(bp?%)OgC@ueD)-vR|wzlVx_7zgrAszzqmR(klFV^@B@V%afmZe$5BSe)Y^<@rO3Qes!y-} z>%6dQlP9w5HgB&lbO{m?!Pm7Sxrp+?d+b**s~n>BRd1%*-?ek@N`uyKIk|4=qL>Zh z!6RWKbi&Rg9ypATz(I<6a=Kvh06qSXNF%TGEjHq?*P(NropFX(WXn=aGqTq_7UzWa z1kjLKzupBte=|AyNx!s)39`%oUMN?+NOF>1`+5F_#$bH8ScvI^r2(<;Leykjyux4w zWT{Oxy~V!tEM}|J07v&xH)I&BP>^mOzD-eY(u!y($5g5Ou>w4hN>~@1mN`luIUchv z*TW>gQ^ ztNa7F6%aBPU)&)N20P~{_wYnt{Sw=rs^4;*aZfzH-{v=H4X^3e;dHEILK#PKunB<9 zvAX`Y^Ov>K^?>vi-jc&EY$H3ae8uhPls{x3~sFGnb#}UZr}S7EK2h zV^5N7s@1P}wN)^?khe%OSva8s0{w#o4%7Ayo4Ado`7lH$=qy+cK* zkKU!Z??$kL7T2fTVLDD~4I&VsHBR9uO5iA(WYCO!V_)oD|8o`BdvUTlUd&k%`0{UW zq7jB6uky%ZJs^NvhwV~ITrXEfQuHj$2ZDsmYe2>XS4*RHP!4&4T{5Tr&DNX3j&Ntu zJTuRaDlmPZZ)QNOOxGTdQ)9$!$A=BY2Tvd1WjKBCSmHPw)zZyW#>c1eCXA)X)PMWE zyhriqdJXS|f7r*78)cF;e3Q=F895x#HgA1<9pFNzpFar1^mS}n$1Xxp&l|!!{Oc3t zm^6N_wlvhkz%)6{{M~oi8JTNFgf(lpp&pU(6d#d$<0J#tQOx@AQL|s#2Nr}#<=tpf z%QN9vBD;r0ToX>qyid&#Pr=8BPtf-T0Icm2QE9dY_<<@%lE!8qo__nB|B|-HC znK%sxv7!?(K-@L4mIGAmR$PyB+BA1&gp{4;y&I{Qm@@eXc%*KJ#pJ+444Bd(PMh=V zHEdAcFsd?#x?p3=g`H`M%)UCI#FCT*0ntwGl(mukOzAUP+J>i-l!|VIT9dY2}b!r@d@@pNKUq+2NQhVOuuueB<*y@6aF zChF3jhP)PMZ?>grK2%lGL>O`{eqCtv-nbEUCS*99jMaRH%JbC(t$ahJ@4t7Ev|Qh9Mj;-`=nLQWEjXI;G-G)5|Sdc%*a1 zSJ-GpWH&wKFjls0#f`Koas4rfPqu9>AQbofjNuRB9Uwuu;QIkflA*Y1R~*VPK=(0| z?U%syKv<&qQB_hqC&$vxcP9jb^ZBW?|<4q83!W=2G0 zBs^9wpJTPY(~X6&=}Em5ijmIQ;w8JH!qRE^iJ*gv_0S_7{M21C#Kg<%40-7;QOxyo z*^hY@!b72~;jG;6E|imqju_ejJ8(-<(ocZk(_*UI#-GjcrhgdMQSfl&-BJJ*hoOuN zmtas#l$PqIQ>RtMQ7VV43IU=K-@!;V>L?3ErDBGq&l#lEU&Vy*n%6$_aQ_DglRr3h zT!p3`w~9SGVf&WYHBy|OaF*7X7(vr{hliNygRtDY=^G#)Cau)JT=E;!SDl&IJ5)AE zAH7t?s$Kp;2xRPV=R`&3GNt=uZFnzN2G@SMc)6q=#Ji2RN(K33%wdZ`*lBH z#lSarf|wu?9ik$D354_Uf3S0uJDwHJb+>!CM?dmSCR$JR)wH3dAT@#pmNbNl1VQr9 z%Kb2xTOscGcgITi<&1l#|6H>#&Ot>YXjG=`acbQo`c8R07Q|+dj!O^99`%E1FyLmI~Wkrq&VXXe=hV+1`1RoA+dZF>8^5T;6;5QPbp2Y73;D*k9`Xo=zbbP6@id_Wy-A*`zB0f%_EQHV_3ayD=Uu8cGJlP zzpUqv$7R%uv9XbHr;}#s>yUU)7Osrivq&UQt1~^92;!=_ukc-oW~JxYfWkpw?nA=~ zFK#0NyH=bD_qfZC?0edYbbgXr5OYfPlR_0{B(ek|Ut;T4e-eLLGV%uxP6@_(&nSX> zX0R5q6$T6;>FN0Sr`Y*p3AyF|y}U8pN?zgXOTsYLGG1MEjETg=hsOvE=}Q_{G3xNl z0}m(hude32E2NPR_R*@&GZu-7gcPimHuq{gUO26F;B>EPU3t(f7k@vbiWyxZKq9pK zs!pd&*Ge=Inw68QPtbw9s^3+AV25qS@zLR)%1!x1t~ijG$=q4?RYVdhopkG;_|Db1 zJyuPo-7Nk-PYs5;!%p-W)5Z9k!I11| zNFH}LoM#`kL;}>FM*jl@UUEq}zkL={;i|jxEz+k03S>|L#y!0y$M7cX27@TqSG)dt z!Uw%Pxk7JUkp^~4^2W1qJ1<_tzD9~A22-%2c-Hs}8!9i~KfEBKOx z099m^zC>>j2K>N6--`GK$Oc}^DMT?3SI3(j$NFMs`;v<*A0r)SE$fl1my z`^ijPpB|u21gFGnc;xp5aa+Kjd~Hz7O>c}{;jE113_t9{Ktn%CD?su*GjVsLJ&Ad& zPw~~9x+e%(=2r?ZT29gm8a6VJr_Cc;1EJ{OIUlUE89s8WneKUFs**y#D%te;0}mt6 zRD(cm$icx_<>AD$f;hwH3aj?w?V~dF4~z6qzrG-gx#NzeKBggq@B?@naW^F={c}Cd zs!io0&J#MHb|;7`{2?K1kp^qZwyXB?J;kIG&RMuj67y?C?>FX=zPl*$Uw0DG{njnG zofNi+{PJF-5ORiPjNgX`O0mUuV@GOJ(;J)KCnx{GQKIq}OCdDEcIEvFjU6f~i{d?W zGE{}WP*j1MQc#d4qs5@x31Vo5K&eTI@5__QR1)Lwy<^0g)B`FM$f2Wxv(YHhbN>S@ z{iU7>IOl+uDQ~-N+#cGvZ4WHxeo9bw)w>Rc#zGm9;0YA|%H2hB3f2b4JScli2LSYi zHmtYs3!W!baD?g>bth61-n$jD=*!HqyMKMKZ#abo(0GN0Jzz3MCt;YRIi;fWHno1y zt$F5JhYxVKnpWjDzfPWe_5X; zfGgK|Ot$`v2)o3uYL)HH?EeO}V5Tclg>^G|dd6*XYw_$owks#9x`r=44bOv>@i z?&1u?$<#1--~@W~0qv$KAz4tMdXmdy?~l7%am|g}_20*SYZO3VyRfFcMPXiHP9%;W zBe1m#RTuz5`~Gs8n5T4KQ=>)YB5Ry8y+kEr6T-#p%7H|<{~hXaFCRazon7d6!2zY+ z0zr9)X8*ibNEbi1sR`G=Ye+p5_*>Y8$z41H>p_e+gtNm#jf$|8ZP~ zd?sni?B$R}JY!|sY=z$r^J`AEc+{aI2s+a{Ou~V@@m?)N_{SfPq~Ot2W%!FK$Kx%5 z_cbfoRb&aJK5AGTNiQ`JWQPkM(kU`%d;zdB+TMvL%;?FWmkED>NX{Or!x&B=yh>I1 z0d;%7+oJ32q1hYPUQKDPZVzQS=Y-DkF9j{v1V{%KYJ`Ld!XW&q`ZDtu74WTgRO9V{ zfr1(7gRp8Hn|EGQYKZBfB|Z@lu`kRt&nR4r7&RW`@09|k8(*&g(08bOcZRgC2pOC;jMJ?MnI=xt$H*FJ3UUF zXK>$r6`&Cq1~g^*4d|jiKrUFn>EHup>*aq}swTh+AdTh;{= zjW8&RJdB2tGz!lIKtH!NV{;iL3|N@@bEL6aX&vgRN$LHmB-IqxZM-!L?ETG(!o~8O z$sNqNPBDm5m8L!4FE^-RVWT&-*NQ5?K)awr%YL1EtDKFT|!`Lux!WB4&aGX`7ACrsW*JOvnkN$I|y)GgdLP?Ey>P4GD8 z#CmjAX3RhIgvZJA;k>W2xJd=WK8LEiZV3fM8>}s~hA*JJw^lIyI%;`_C{=6tdNX;M zM)I+@!*T$xQ`RD_exYKCARkx{4Lu?YBlVAnu9L@pY7Vuq1p2vFn^?*IDQQ9f4andV zOT+p$g2G@#=uo6I72zsR?u%tM8ggdh1p zn$XmuE9YcJ6qzR4_0&oStP{k>rnLSUl_Tn_p4Qu zH{&Dt`1lpU0J^9QJJ=+9OW%006zTbGTcnP=WqxU=2Xv9cg-G*~j$Dwb<`5>^_G9q) zgFS%c7U6*18qzT-ebe?byQ;ufB@s;+ct%ZSbXW2Lh$}Yb0SeCY`)E%O{q+|`aZKY# zk8fWwMZOtDZK)6i#2Of-rZ0yG?bEh-_9bJhWB&!N@sqixXf8xTKs8TdGH@|yAF&kE z0fU+PnC@&U`M8%Mw$gH>ULV)k&ph`GCee3v;hQh$`E%1#W_6$Dyjuna+C$Oqy>Oo? znKRKdkJy=Jp;0aN&?$1WW0t!<6a^Fr?Fx(ud#gg>zow?Pb*j}PL`85N+Lv3aUzib{ zVBd8vR!c^OGN61r?AGkOIj1-aJf1hd34c`Es!0IjgRkn#UdEm4MHO~DVte0{Vt-1 zf6hE#XI@>qPd(U6JTB@naSNk**(HF0!?_uCOmfLLm^7z?G*39u|eW?RP;fOI; zqqmhvuMVQeNa5J+$-o~EALk65~4I^^~W^>c8lHV2;QF4|)*_H5k8;$Q_$B z%PV|NZ+Jw>y%+Z1#$Yx+JDtoCx_rf+&rMPT>B~}${M%&QJ;H#t%ye&-%DG* zn=nh1M}+VQJ3Y#vT4h22xJ&4)mxk%rR{92J%|F*wPUK}H-m;@OJ{8iyzpSfoDs1qz zz+inQ32JIhVP0cLHbX6 zjgU|Tq&FedB+^3YT|jA}3QF%qq=tkd9TIx)MG=sWfb@_sqAPiL(Q|iGAsG)* z%KzO%uH`3nRm=zMMK5I4pxpNo+&w<1%^4e&fk@{acHN3rXGXwOBmzvK8!};$IOyiVvxD{6*knRMd>rtf~>N zz|P?IR)HCNFZ^rHFPuuphYIuYj!6#=`?`%XA#nPB*i)5zk;H)*e?D(*6c)<}e)tl)liLK3}Z*eVD|$(b9fQpQX_R z&gdWmL$FE}e(>Qydqyn*sO4k|StjFd;uB1PlCdW$-nr96uw+?pb8gXCV>xJ}i{8gy z);b9W^Sy?k8-XS$=yAArye&7dAvrGuIMwb|bM-^6$v-kutwh~9O9NN%X(QIDF|sX+ zn#;j1h0E)JVt^q&ptR%mI(DG3Y zAAzM7k0!59f%*O`r~H%K`jUGA5$5$mSW9~N! z<_}NGT+D{a0^|BcseLB<7Z=NM7OXXH7H}`B)-O^UUx7(Hc+Pl@p4<&QO|2z-3;-bI zR^co4m;%VUAx&wJM8jHhqiuJ-I1dd7)xDDV#<%rKqNxZALlQ&3!Wv=7w!5-JWZt!9 zmLEE$q=%SvLnanaQfS=4yq^!qlf zNcZ03@mEX~$d3a{fviAE!P z^ol3*v%R>0+8Z~p@i)dS%dcc!xV}wqggzcASE96dt^zq`Oh@8q81QWC{IPs&^b0d# zeyE>whyz0Ki)D+~44_kDTKy8_T4}!-OCrVAUY%KH{LpawifW9nM93ZA6<-6@_=1W;b7o;TmL62cmwqNTa_V_E2gQJlj zR}`LaeNyw2DNB`9ySmkxC4}k|Jj=L!pIRt3WsQucQ3mSc%wOEae@F+oN>EU%t#VeJ z9h+S_-S|jpH}S=}&Qnl1yw-RNsM)*>V6X`g04XK~FPAmDNV#ol7cBVDYA}}3>$_Q? zb3jRmI6}Fqi`g+<%_s())@5Dk^^g}~(X8D?RVIr_WqI`;U*G?&$HH>`0a=a@&_*Z& z2F*Bil`B%_8!~E+{+eUg+i_laU4!^pE^EkCpb=~L;n>7>lE8-aqJXQDr31s0#SRu+ zmI7RqYj=Ja?u;88!j;%<;6;=#PMlaDgtA8rJ;Qqr)E$2?U=i%UQ$tdB7T4X+inT;lz1rd?0O9~`E2W)%~^^oLMZ3VN2_O>?pH#F`$or1Pk zCEk?8q3P;F$w=C9*FNFOWHMvbnhT3TVN3oJa6{C$vr(h>8!dz&s$ro`8SVk%H-2E~ zhAe-jpe)Ci=IF^09r@_)VrieP1n9P`<+stc}F0 zeR8kRkHcLI2B$Km>#K$io0kFPN{DIFdi)~#H0#B_$|YyjT5$rUIt(j$o{G)hAYp;OLArP(5E?9lHg}yUZ)Z9BPxhqv*dh7{NYzIFtRR7w_0FH=L$q!a~j3 zXm981ct=N{#HCTleZ_RioV|DXvxvxTxpgRZ*hWB@4|4yn<0KcF;z=z_fGu?&c>!{A#{$9(Gz`|Q+pKQ$yXq?@lw=A_TI zsw_l4v1BZw-O0m3YS{y-VDq@Y!IyFU%W+_eoWMS;TPD&b+qd@Moqp`;a0`6OMp3Wy1MCxCGaHDSR_%61?%=5 zqj8LUp2J>|xr0C$2uvooj>JB7<80w*@a z72yn*&oW`b;l(pYwacbZLBE2%@3nL^1rx_f`$A&Xf+9_}9iE4Za)!^>(CcE3w6pWZ z-Q7-s*xuChv}&jCwGfEPPMO({R_BJ9PwDqv+H3g?!G<9*F~+tgi2#HiHniqdK`nhR zN8Fn~4aKO9g$nAiix&a`IZS0>n&A44|5Q~L!k~^?5KayHA#!`+<~g+A$Imk(n51ED zoifl@r?PJnEQYd7uZ2wNuX|;RhUqYLdJM3cvFR`|z8s%Nq{hZGpLN45N{nq0<^BDh z(VCy}V5jJE?m~8eeQ04mzC;m&_1t0eMX6r<1RA;Bt9Vmx_~KxY21EStRe?b+dqHwR zBK)B;%vTzO8tq;;osg|<)~C(_|A9>e05BxWNGqI7a}YC3_$nk9b-{2UTp@CcPN zE;pMgl>jRR=TO5wSM`q!y#q#H(p=F|recKE1<$xOnL!8$3%PmN#diNPtJ=8_bzFMz z=4jRXUtK%DZ0bbrfW<2}`MP3w`+21G~8iBMy)xt(866`bo3 zHSn=_9H?j9aY7`;w5e&AcFf=D9`I=0@Q6OSurn6s^yWeey>Ik(Fc&wLddy!kmRR%d zSz~Cp$*Wh{3|O4qf(hUES)S4e9V2-mDc0+jbqU1i)o9s z)u}&XScOVylNpS%!^KO5I~%Im_d6$4o@*}DX#03tTwp2$oS?=T9$I{1eO!T;9R2d| z|H4bMOw>|8DgTHYUDeno{#+xB^&G-KVx1C?#%@ z0_)-(G>sB=8|Z|x{C!tcmdYf}t5f-e2z8~@HEVP@y!xyaBuPjDHVgnN=!z&^Rqq?Q zZHm*kik8jMaTfPDaJXRj*PEBLMu8Zir;CPtor7 z^3%c%zRIEr?C)YBbo3f<`h%X*hhBQ$*?Ftjo zotYRqaBLX2<8vDaZUHd!55X_`dY8X6r&wT1A`f3d>c5m|Hz#%Gwlt`x1{QPF7q?lo zv17ILiPSaJRQQD=n(MWA%*GcuY3NIbq8!Y|M_TsBJracH=20!J;RwSaW!(3Gb+XMI zWkb~2d@Yz!4!1XA*x`Ai=@UkEFMR(I!eH}q$XaTaBgpxbD?jwE3YYVO5|1=Tcawm5 zkjt#ohr&w@iBL>Olu+Uw-i_>Q0Z!KdA3VJCbIn3}ykd=I_Zf~7D@Cfk&hnHL3Y%po z?P?OtgeQc{uR#n_vUj28Dz(?jDfKuPMS$OKOw|#Y$V}8qYh=dQAS_WiSqp*D;#YGd zq6@%93o_mUKR%Wvj@D_kzUxu4>5Tf0X(Ltt(HSAlJq3NZxuF7FCqXib3GQpeNp1wC z|Em2J@w!oWlUOj3pP#cJ(h!R|Dx@+y8>JOb#i6qNrtkcPmxoJPVWaJ+QlygZFT*df zqxekyY~g~Y4+O>kCiVt(*}}8e@h)0#BHXB+^c>7UiXW-G)hhlR#_rCog;;>ilN;N- ztd0xq=33v8{P5p!1xqtLRM|6MB4VAY&+i|Aji--kRAdJBrBffay{$42W5k84C_c9d zRbhN_fKd2Y(?IAt(F5)70OS&riW7VfYI)tNY`jy{BeHL0Iid+H!GA`lO3ttcl2Mv* zf*fwS{l>2=`lQx08h`Zn`&x zqwieOs+pB3h3a+Ha-re@qmH84Mn8`lS08-HAL6^+U7;hz8_%3f4}EIPAq$_XVcH_B z|6yR2y*lrd;2_@uy25ZKZ1WYsAOTB#dpEu-vrYmY`?zi?Kh!93Gyh>1%^9OrJXEH) zravnSDSa|Z;cIMb>9N_z>7z=?Oe9xw_SB~3?zLM(tMClhe`Wf!Ji@zh_sA&fnO!K~ zuZ`SaWV{nMtQ-@|lvHn5nSPdNz2{p>-E*7zRxFPJ3r^ALO~_sk9%p(kl@#KHnFskz z<;lXluQer`pee2Nm9H{bX2&^t7P%W2&>hi8f-`M#Ay5xykP(~sr~gGMeBnQBtK?B5 z_5!OUck?~?RF1!VR2rK%g`hzsfD)st**SETV?K+@Y?R&_o2m9cAc)^dzI>EGGN>%n znQ}gjexT%b-}926Q(Ua)?b=HZlnGtM`N`n;ma|HhnJ*_e-5O))Ri;9BgUN znDX`2?~^M*^~C27zcJzFpWlO1wdVV2jM)Ha4DR0FrKfozNixc;Roqu#DYk^G{qkPY zRA?YYa0Jn(_*eKXC6^s3-*4s~kF~p+omIkJA1g=nvm#zJiy*gom*TtK8qCsV-v~m% z2%2o77*ZBD(?r?`2 zJn0iYJ6kl{tHX^qiSPq|%8$o+OMD?K(t%tQG*a96f!BLUv5~llWcoz}MmDE^QHxr6 zt^r3;V%gfrbe7&SR%PS>BjQsY6^{~%C}saB*ENmki*Z277LMdwO6>i{F8CNZ(d0e% zx&=K|d-0uaB%TyI71K}(NRq9rl41`5H83AgnBFWYU(FqZbo>(69*8YL8`XciMaQG~ zu5^@#wUqv@>+LMH_f@qR1{Id-D^XV=tKKp`j)S28ga}i>%mifC5Qw4`Kaa$Iv6nMB zi-d7k=W~v$x$;A|d)nN3VA63BO*AGC)X2|a>Y9Db7Bp>`tjqPC+}t*T$nS;k+;jP7 zL8r7Ywib8aRG2O`ZF+4e{B()}DhE41(c=0cekiAF^f;&O!$F0CebGV1DR`Q+Dj$T- ziaWN1!-t&KqWG{jY#=Z!midqjnbVr^*>|D*&@jh18Qds)Us182j$w~S7z|qhJg|Q} z2vmMWiP56CB?o9+&wqjs2Bf0gb<3trY>RhKy?)uY8w_~}U}aS9r0085Achh3WM-$9 zR!j=d^lHp1?>Ut4t5gkn&ghmvonn6i`xph2J-doqk9iyOj$utgz&Uf(ip(Fh^AE<$ z8-|1Xdyd!o2?AQ-_u?q;Y9S^mzTN?llkAqsPg!;}N}tX+Ef7i|?VXRFy`QFdp^(nd zrhYo;D*WqkJkhU|{u~i7t}f+!+Vb+=h&N|nqq6ELd{J1DI*iaL-hqeHQ^8MN3T z!|nT%yEyEsfYkrdo}=j^l0>sDH-4vb@SUaph*+~JRE#T$;X)!@~BTP+aYJje3{ zj(|Oj@^j+01@Tk-*oX+#z@HHuq&5AhVE+J3?&WF=QiLAf7lkD(YR#tnammG#l|U02 zO7@LhRf8-~@a%lm*rzJ(^^$VIy=TolN_If&EKePe0`koA+VepD zlhjgKgE1al#n@8F$k-205L}p!0vIh0Eb|uqlt3G}<-WlTg-VkZI-N-U6utQ6u<@El z#r%B%ls6|8qOs-kWZr3|SLCPl`5h*>qCslXw)zkwv7N!oa=Ql-7O-R--u}`JsHzbCV9v_2`7LkY_C)is zLm8q9k}oFd%9ABqiZ*@R&ZOnJ0lM>+RE5tboiT5c<#=r2EEDgh4SN=M-eq!Ra!fBS zXV?1HZPcN7A&9GzzUxzR6wwgZHan{ui)ss-dW?t`a0}{w48Il z!e#CK_^NvC`N(K0H&s8}=v0757&~(Gf0pk*DVW&%DfdOL;fFx|?*mWpS_nK=k0fbV zkeMqiSmTJ*@LvNIq5Qt9Q(>Zwq`m0iy3kZSYjF!7n? zhbJB3z;2@c)#lF>u2XzCPN6jHWxY~Nk_4IoYj3lPT5S60*POhHg(&mbWN?P4`&Vqo ziZ)vt%vNEzw$0GWB2+rIQ@CdtasW9&2}7Vo(+YR{N8L52BMUcToD>s|i>5Hr8$_gl zj!LH3fFM05`o>%4unmnJ>CQ+FpXSB*!xa5g(oLdX6Beq`Tysk5nBf&ELXp7`(Iu40=oO$w*kZj^#(;fV6#>1WFSQf&&wu{n@4dT!FZc&lFTtPD!!~U}SMm~wqM+_1GT9s*hau@`YDJN< znKuIj;c9pb$N8c$9nL)MnUS4FalvLQ*6>CNF%oAiN(gol@v|dUv*WVoIQa6*pdI>Q zze&5OZKt%rqCOqC<3mAR+dAwSIGqG{xrYLSx#9)*@5IFpwY%osmk2O+NSuXNJdv|+ zb1p;ji##$-;kMz13SoU$Fn3Hg=h@o%SVz%xVz)h|V za?i#c25AH)u&B9TO@$WecJPz&7O6&EkGQx|;^1}M)LP~08LPk36JZaqbm`Y)kT4Q9 z+Qg>(>?2n9uV>9OOIgKH#`l*{s>;tEmYL95*?loXFw|C4tZlzs;;%L(!>V!llXaduB5f`eb^M zhbveb1qeJM(^7ZSgeQFotqc*~~Z> ztmAr6@(YV1$iF&hYb}4?U{>~_Wg8mX1Z+k(k~}=1BQj729lj4zOAU)W8e@fik_^hJ zb-TBh+ln=d+BA56JAJ6Dp!bq{8eOHAX*wGEh|#-X9#v0G&(JJoPhv6W@PJ%0J>tpXX!8PX?fmNHF<8 z_I+#opzUXib|c=aNaRWrH}_>ZyIq>op+&^PpRo*)Vue_;9d@=A9^wv+L*@wqHM!N| zZMJ#Y_kOpQUWX>#Hy>?f#cHSMp`6xmU5RL=NU7XLmkAAJ=OohF zRTH%rse{|#9?hWh>l3Gz#Fq>K+I~BWr4>-si+yXT%upj&O1NTM)8X&SJ?U2;?xV)O z&pAu0Gp$yb8?waB0kt(%-Bq7q?b8DbiLY-f!>9q?bL`N?oq>dR6Ba3d*SSwTM=obS zcD~vFv`|G-8bT9XWIH2a7UktG5mgY!rfFuNeK`^9rh3Sg zENTf$jL6ln1)DU`yQ*`I4 z<@0Lc1ho3hd)XbX2s--GZQ7b=RIkv26Rj^}MZ^eGF>8l^)w{f1(fMStjJP`s>~d3h z%8`PL*vcjOgtjJ-@0VeQhtsVR(_bLHuf*p>ZWB}+SeYilIEd%S%7$cqf0Sd@PNKj59t9v|lGl>c{!HfC(4nhiM?OVZ;>*6(?*}BcB5A=3d5n5o z%H`th&ffU$EhRG(u1FFOSZw#LMX#eO1=3Q=^ijB+y-76;S|XMQ=6g73i?QE0f&jFJ z__C>dzb#o*{g+t$UzuV_&EY?Q^ScC3;#!>LcPSk*;UOY+Eu9U%!?Mt4`}7|J*Oqpt zB@S~=%~QO@3@>E0eC4(UM=xs4G-#Aev=o%t0V$zmX8ylSby`zAEzHB5%@e1y5eZ`V zOaCaS)xT-~^?MMs{Y9fkd5rk4S_KtxQdLZw-%&l8Q zW z+=ipMJU8TzR?Gg_b_)Xl&SIr~w(-(XFglGrI1oUQr|j(M}weT(oy#BzvS@*HP5o zlk(bJ-jX^C*@E7)dM;^O62Ha33Lx=R-U^++vt@ue@4I98ciMIA%0fN`+9{Z2{3wff zCF4ue0D2F!rCP-a(PJYu*}#-myd@zf8X~h+X>=}M`?k2YE3KZ-Bb#3VN^H|N&X1c~ z{bL-v+Uk;FN6E}Yo-s}8MyBy`I!>f&b`9;DCZNyEWr6a!2$8J$?CVxLa7{a)`1)N! zUdTVd;~S3AZm^&JH)jS33e;K3g79Ab8`VC$^aH*RUlQnt2vd%Xgz@;vTvS+%OzAF~x~{Z9JnGAzxb7CtX!+lchoHFTeUI`P zEw}ns(cDBc-(o_n7G*rO-dcFvR~#K0rl=4Xen)Y+?sfIj8|$Tgg4c76D6`7AXO6#^ z{iw?YiOZN>M1)C-&=}fCyc!@BI@A*!u@`YP-Nf6o`TedaehQNGHK^bgFLq?nB{LD1 z$$RjIN_8|~w~FeJan0RUWc8i(#th$X*>2+QobyM}j=2Y~R1**e7a+lH(Dw#7&UxLX zN!AbroR1|K3Jg6eb$Lo~11U*Y&w5Y(cr!Avm;Ch~06H5!8<-E`96)cujKf`-D0IA2 zkF;N3*w9{|=ARa=x#OCjwz@1An=V*xwZHiCPAB>X;=S`+!U*$wta4SjfD0>-mkgjU zPj?k6SG-2Smf+RsoxC^G?3MMn59@RfBXQA%4O`8)(vsD$3%oKw`*i}x!JnK*c+J8C zOA!_4;O|Ivkh4n9Vo3pTp}ItoO&pya_@}!%82cG69(Qs3j*Wx;;y*Dc!w3()iqGDFC~sV;>>$o}r4(;XZxq~_DORSt`! zzK;H_R)pdI`Y0dH*xpFHHWV0EvS3|Hi)(a^=U-p*bT}#5Lk?%?-=dtlR$HSp=AU-F z-l`P2MM@3h=4W1jbx3YbyFD)H2%OIvca8tP{2?_jx>-$C@b`ovgm#AWJaXKA%FXeK zPvA9payIB_16_09Sc&*)Udhd&=bx$?_mcCM#@CM}xiMO{(=tj&>trreo(CINxG z-IvI-2O0mpUY;9?$q^ZKkjmjp{949OJ?8z(%y_eDZjcjYAqQOuU_59e$gx*R&M4|R zMer2vB>`o{Hvh8*TI2W4LZ2#29F)g9oPFyMuo*#xMxNp2Ui{?+E0#;F+eGfS-L4f& zIsO(V|9>o54V7;K@p>Urc&|cz&`_(o2YuW9U@BI?WPF5M)9Qc)!BjlWluF_(@U4QA zx~Xl3s_FSsl^lN7b-_zGE=BfWKJI&z{dLrn&Buz{w=fbYS9a2P^(uh7zDBA-M}zFf z_US)BUW>srzP#_~u~CuiWxLz@1fjea$PK!Nky9xxDxZUGwOfl$Ijz2MCLE31jabC~ z7HsU@2s+%3S^neG(epK>&*-%PO}Y^wq9WTt*%xRF{f#ut8x-Jp%NVjVQDg$fnx5r` zuOwcj=oxSO_6h2$-480fjSocJ_@^zCCiHzHa5`mp=P0d=?piC4kvmvfJbHU(%#Xo? z$d*B59E;KBN4vSQ+td7TRO#q}I8J755N3vwRPzGMumjLu-V^5o5Z#^=Cu1bMCdm1q z^4Su&Be5IyI}Icjml^x*L0y+ApItIYhUEla_q|FwPVlT=M1QnEK8jt<}0}2 z5yp{!C_vC|VY%?A(2$+d{r{GY*)G2^?HFlyeV6QDx`}c^-U%?$IS&)=tAE0o` zi9+kCL8!Qo`k{NwF#fQkF=4*>9Bf%-QjDP2w)NcI3DWxW`>nxSM4Bkf0d#AmS?Nq$ zAsk#JP7j16Fm@H(8-94rA+!A@xU(*AK<;GZka(cBg7t-4^2(#IY>)`l>g}=sS190) z71k#+GJ8~5t=RqywOeISWD507yWv4*`~&p6eSkZX!mgS4{eF|Fo`k$V=bZc_e=HL9 zNf<2tG`{Lhj4~pm>qwDL%6P@9U{*Bb+!?FDH`(0ja%uTDM}8!a@2XR>TEc~c&z*pH z=g?6I#lhPDFHAY;#JluOxkhlK8MCtk0?3)NmPSZY2}Vj}o4ryIfy&IZ+(lF$U>DnG3u4US|Bbw7gl#oBK6q_E_?n09M^hm=_SD%kknV8sc~OAb;00C7iJ zEAI<2^x5y(rP)EyGoioCV;_c>MsJTU3f5J`>4~>maX?7cF7*37{F@fxkjxu71&|W- zG| zs*8+!ebV*6G33@h(RN(1y4+y+!Z$+Xc~W)8?N9&C4XomCxAgnSe}KR_e8}wwc9u)3 zShrS|aM{kv1-1NCc(f(xk>fq8Y)$_xRA!sqUhJ>&sSAFbN&bW|rGNQm^+F=*wq=6N zswph-X~sT5=fQLP1G|OBuW$cEU2{(L%ZwDCS==(kEp)m|qI! h*YVO~))aP_lN)h diff --git a/tools/moltemplate/examples/force_field_explicit_parameters/nanotube+water/images/nanotube+walls+water_side_pbc_t=305ps_LR.jpg b/tools/moltemplate/examples/force_field_explicit_parameters/nanotube+water/images/nanotube+walls+water_side_pbc_t=305ps_LR.jpg deleted file mode 100644 index 4aa301ce8b79796a2b040180e8874e38ef1a0412..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 27305 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 PJ}I|tzsZ>Bf6M;^Z@)td diff --git a/tools/moltemplate/examples/force_field_explicit_parameters/nanotube+water/images/nanotube+walls+water_top_nopbc_t=0_LR.jpg b/tools/moltemplate/examples/force_field_explicit_parameters/nanotube+water/images/nanotube+walls+water_top_nopbc_t=0_LR.jpg deleted file mode 100644 index 920354c544b9569acbf1d7885d6a126339d3f55c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33740 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 z�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 mbGNiC1@4_-W?=kc`s=c9&E7mqMU8L( diff --git a/tools/moltemplate/examples/force_field_explicit_parameters/nanotube+water/images/nanotube+walls_side_nopbc_LR.jpg b/tools/moltemplate/examples/force_field_explicit_parameters/nanotube+water/images/nanotube+walls_side_nopbc_LR.jpg deleted file mode 100644 index aa26f13948b0a7c00163df3daaee1de5b25c0529..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18748 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 diff --git a/tools/moltemplate/examples/force_field_explicit_parameters/nanotube+water/images/water_side_nopbc_LR.jpg b/tools/moltemplate/examples/force_field_explicit_parameters/nanotube+water/images/water_side_nopbc_LR.jpg deleted file mode 100644 index cdc143510ba17140844f34c577fab53ffcc0b826..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26968 zcmb4qRZtvVwDsWb4nYD#aM$1x+=m(5f&_PWC&68V1c$-hEx5Z|!T`bDgWP-%|HEH( zU+(Vi(_MXP?{liFYn@eVpZ&J-_6vZkD61d~fP;er$p1S4Z|eYQ00R7f_Fs$e&k&Ij z|1(r%WF%xXRCIJSR5UbnOdL#f3~UTEG%P$UY#dx%JX~~4d;)x2f`8Ar{{?~j&l3R= z^`9dy1{%h{xBo|b>jmJU0)7A<5a4J5@OW?tcyMn607?Mh->m+d?*B6sQ~)v}5*h;h zf8Bz(0C+gWf9HS0!z05Z0N~&e5Rs7aQ1IUaPzktb3ArVS=ro9>KJz%EkpMx#iPC2D zu9yEjDc}JAe_Q|pA^;u<4jJWN=SMsM90EKNJOUExe;?)F(Eq~XA-)G7;d4nMYY@!iek|a-+9-uSnZS2$#&RAUno&u8W zFvuTcO%vvYXvFFz7W(_^>#pBko_DcC5hD_uJCHJ^y7xOyy7Py@J!P!={obV~s@Gg# zK^&U7)wI#m7a7LVnjGTo9RH_xE&{DAn_n3n#D8+7by#pOBw_(mu6Uhiq3|{oD%j9!!Mh;5;%Z*k*yZXKdvU3M?b94XqmkW?)S?Xc@72@cW~YI zOgOl$5(^;v|0J{6`je~Ud|1#iQb&?{XjIw=zMDjj`OT&pa_I@h@s}y3K_t~Q ziH??~l~}r3+jMfxNYe2?^|eP(z-7iQ>X0wtjLlrW{EWvKWG_!4&p51b^i<3=)Y{l= zVXjE}9k1fCqK*o8FT&>=v5lTbKru0A6txYUsV|ZG zm`Kvv({7nYn4>Y2x zh7iJviFb?6Bwcd?DEFir_fQklq1dLr4%u)S-Z^%Q^@KL}@loHFLLbYa6(oiVtkS6f zLDL_n!ApHu2Xxrl_P;l5sCb5;_GCmx7Pj~sF!?YQ`!k_Z%QMJkN)ll>%VoKEms%B- zu2r|M4NOSc*+EOcGjpw=YK{Jwt(gXTf=ijx{01O{yDSkxDZl-!-X$|@D*C(A10hoM zwUxX+%BkOth5WlyLVseRF2lr52^c>S06fRfBxRGH6sbtM#uTxR+cYiU=hO2|a12p9 z;)C;5;P8lT|0Ej{1_<7L2?s@pP7%LKg&aD-GWM$4)E6r?o(~u4OSB|eN14P4yf_v- zu6%Nc{_52vta$ZDS_~i8eRrQ`nzkw_Yu1_pleG3X9$zUALS}WFevp1$h?0csG86hD zf;YhH=rjZ?>e=TWl(FlWU9`8RWm%I+h#*f4y5I#r0&|0?3X1K^D!)7Y@KiHFLAmWc z;?~n^PE<_^Dv-9TqCsr8oZ4A%D2lCe8zEUoJ`=b{$#4;;)0&yl)5;@`(lw1VN`3?A zB@T#x1e*S0@mQL9KVu@2ptHr)woTSG1KM)79-LYwbmtTB$@0qe{1NiLR*!VpzbC0D zQ0{yx^$l>4aZlyzKjMNBi*y%qpORjX-_frFeDQ7P;RUkBwr*DjH;39NY}aIqbGAD> zqG?-{e;GOT#QgfJapilyjU}tFNVVc&pjmzBUMJEFYkw6)aKo0HrfdpU8-HHHVw?zq zq@ueWs_T*2(H=Mj?`!BLUhk}ht)sls-BW6eEJ8}o%_8RIF!7gu{!*d~$WhzKqSWqt z=}r9I>2>SW;~GF=rkFLak0jF^H@9qEVVa}IfeA4Ib!=4jOL}0B1=ssAlk$}$ll*d! zXj95EW=oep9ha&Xeg6+n(I|TqnpK!ww?r%8#ndIP3$F({qdyO|mWs9x`bT92=`C#| z67k=f>Fd&3$@~apYs^u5keKjeA26+&L`ClmQS9)mn^-Qjnv{{sB*$=g-`EH|&dAVM z$r+dy%diq`$g}fHRnpX?Z(|+GLF{>VTTa($HwX>_2w(07Qc(M%EJg$O?39SIUWnF; zXUsfqTbEmQc&q->sU)t+(n}Zv(lxqrd_Z2rm}w0-ljdI&Sku<`3}a~u`EYB@qh(|p zk08(7_w(-DEVx@JHQSEM>qKYo((x;Nk;WnlsrZOe@8yz<3?Zx0#3+VfE}(67D9)c{ z>tn4(eyp+J9(>{WWrWG6FIib7RReigm{kbmA3^k{+48RMnagUwIf+J$Lw*i-}6v;5Pu0zxieA z656%indn|SdS~u&iqyj5A=`{X`!`AmVhpKmxr(EujM?#RkKvcj^5$DKPzlVM@=|%c zXlBq**IrN0Oo2%Q?q~R?l*t%7U}SA%^E+1IM9$~e*osS*25pHPU#^lg_O9+=eC7nT zm!9Fr+xm);6JDN0O)bMi6CZL{ZS5;XLd{;d4+>}((LYqzr6rye9s*fLIHz1&f0Nky z4`JBzR3WCV2`!c>*wC)a_Ar=yzw+Z@L|PF@kgF`a^4;u7r6vNTL`i}?G6Aq=_80?3+u@YMZhN6Zk`CG;i)hT&XiA}wv?5$I zMrAA?M`u7{XGVYW=Ls%WD1SQ17@I(t8ukKF-2&1ZpiRpC$VauS$GnB2lz+*jQ^lh? z4?BujDcrB|@O@ks_axaF0B*CVx%Ba5axuh8O?j@fbbX-?+3dB8D>Ba_W)BiTB%C!< z6pm0A!ms{YI`Kl#Q&bJonU~0U!oGH2S#pony!q~DCiKrr^gb{?hPv4i<$${I6{n`t zRcxSsU4`$Sx+AK>-7Mo5lymgoBJ9wPd4!U7AwK%FU3jco#S^eHe&-o#Bo{gTHdfP0s2Ay;cK4xX`_bq5>)uE*f6~-=iXHIsQ6;mt;9W=`%R> z_%UYV@C+Lf_(sz@C$jXUKyP*UZz21nR#+8I4SNHG5cxDU8%d*Y8cV(bytc-Dj9Pfc znR&Dd`z@W@Q@n!&;de6to}pjaZ@o+ELBksA7-WCqvIwaiS!0M~-vIFp)6WQZem+Ec zT{E9O&t%>J;|3nn?ww0)lBK@kaN%W;pyzLin`A*IlJ8N)Puc2@A%45hnjF7}diJO3 z`N;y>7Bs2`GhvC0X81&zy1c(%<)aF5ScPg=>1=uk`eMI`)XAtsK$M0b)|Q@Acmm2s zjWhynp6BrMBPp9oFzWf&P-a+;mQ`UY&2kyfu=)6EJ|VSI>xL+yBWNR(%q~H$od}uF zSmOa`4@|TZeHR|s76ZCkIZ)Hpun5JRU=%USKx~V&!yaEB9hw5K>c11XH z%b<^@Hd%k0>_6GHo+fqeMkIYqhtfoFo2lc*5B7X`IbCltwTf7cSicmLtJAN4`WveU z)>v#hDsa#GRPF(vL<@$S`&fvg2Z%&tFmEaLWo&67y~@@yAP|C1@}!n2IHW6n(-QJJ zrtA>0Q~H?L8M5nTc)MycmOr^v5^DR7(e{lO;wT#_qlLFqumzjKsa7&e>}A6qxCn2EI)_#eQSfwV)TqLHGQ@OQKJ-LlH=? zzQ20M=M2jhx_AQ+(Kn|tG4A-70?>EeJuVkBBO;!I3Z>^MU7}t-HyKf<@#xzu?R#81 zMtC(55kZk6`aRb@SlSh$I=pt@q$%DlW5b-BLAxed?qLC&>{G2Q&I8930eZqM-n zydoIL4jtxHOjmMUS`rw!#aKbk<%Vh8iK%n0Q0aIxa->g$riqUI;w99o^yhpQvXLw9 zG-9zu)aXZGP6AK=#oJ9n2eXn z)N(>L^*WBKNqf#JsShUJ6S=6wn_c9>B$Tfl9IHt~wDz^N=s>y~cEP3__v-TseAl1l zw+PJ^4@d+T%~B0nW+(VDCYoy!Kx401h;I;A$Z!D?v`V7Hl^YRgR-xq3m{;)5*w@T^3K}6W7T_@ zqq;0f$#{^GO-28w7GTUL_^(a`UV9Qh8Tbv*XchQP&;GHdHGH5RbE>3)qBxj%*_cnA zR!EddEw+>SaC00NaK4e)us`;p7`42F%JCVl7n+ps1xt(;_^88f(nKp_R*10Ek3c;RA*dR@SbeL2Gz%uzYYznt)TdiQLrd;5TCz( zB{h+Pm!aAqbBLsbxi*sgiPQ=9cbnAwg}>5r8<_~H9->3&Q9fBHLmCE&eB@HZZ7JMv z*FgE1UmKw$8+h@|OpH8Y?p@|9ODz7?z2)ZLx+J2!=~^^dZKjw0LA;7I%F@V;sh|JT z*w~ewZx#<@nUw>{kpq9dmK;`fw#aqIP-wZ6aYMNU`&f}ZIQWO>LA1?SeUJTynM|7c zvM$SMo28y2IRdrPR}(ZIBt(`VaT4GIJ@TC#R2=Si_V5tD{`$qxW2yw zG=hkag`p^BF@eq`emKOt@AN5$d6@rp^H??2mi~B=YB{iE_ZZv7!701bA$agl{2`DH z%kXOzW9av4c^_SwT30o7(!eTeWiSGa#2A8;Wm|2pqu0!Taz1M6YcSW%qnUHjHzQp2 zkaXz~9rL2iWh|E7cB$1x1(W-;k02(i7_$A+49@8z(Tul4_!zwrM$3+ zwiJN})`ewp^10UUNP{(YJ=sc)0jCNpRN%m=bPQxAk3qqZ*`eEJ zw96wii07#zZ^NSUFY82kWcfvDsz3hGlmVN~{fu9OtVL^sRTpoTkLkT_q=5|u(;y(= z9yBCy7V~u3c(TUw$8#waT*#fh92d)KFXAK5oHPG!w0Y^DqN*f26MFv>(3K& zIPzB;cAB;=o^6`c8JsQh2hM?HoZaIa?MWbvJ!EokfPmDoik1iyII*UHRoKue8H89s zH)P#Kft$rV#LMt^q6GN?P(e0bSuydx8RezBRa@c1_4O2|PE; zweF`p-psKPJED>wsl=inoZj}k{B-yJ4bY@Cy~vLq&H6P^5);K zya;T4btpVLciyYer$KDa(c<}Iet>o0__&?VFrd!L&&$S~ zNI@NWLru$heOP2+zrSdUGuJ*MH5NOIE2*fumSW!?QZ&Lq;b1W#*h4+>D>R6O{nnFW zVrGdz1;Y0!qIPsu3gwh;bsg{P{gadSQ+FtPeF8TYW#)W`Gs z{&@qa=QloICaP!utaxV9m{-h9hPx*R6A@0s(ZYSd^!?nw^IV8HVs{NTNh4~Use}S! zt;~v$Wz}V81Cvm%Ys7ff$`4RZ%>cVX+56WS<{6tX(m}fIo4x~%>ryO``o!Xjb%0{315pT4(+GDTMB)QX~C^CqRv0Qy{?_r zHnv7I=PFilC8DhALX~4a@kmA3MQvBTG#5k?Ex(Np>jNaC@$UAb*XW{3j*XFuE12Z= zDDhjYEirmp^A&(ce1FA;FQ%_+8grTdv>()D;?x!hWS;*^wIB}bE|-BlN$*A@$mT=^pAp?)9V}x<+&t| z`E31|$F~0-#_MLeTOgawFFYz{UN<7=0z|$$R=A2hZNpJ}iVTnFI5oMcq)6PH>PD0)DxlB`vb@u=I+q1 zklqr2qYBz%5f!J~<>gw%ch=+sR!*_QiE{);6FuwenV_w#y!x}Lzq935ic;?i60bc! zj-ALKV}6Yeh%AAyJ#K(Lks(WhVx!D1E)P828$`C>?M$KcPt%$#G?6yhR~07>CCFZM zX_D?26gpRj8b;b90|q995myab<3#imA8F$P)RS`i;~?O1O&QyKwVByMfz((kQSP$k zZTk}(@qo-}=QLYS(Mx{K&^7jjN!L07qzejD)r?CH1EOhTK@2 z{fWZ&#XHPO?{2kiEi~8XkkUA!&>&H*eCXSF=#s100iBKulc2*gs~~ha%8AoBH;fz9 z(c`41avVmyN(Dw`-(EjYey)*bAp*NH*f%FJ^`8&ZMIJU>Sa!*kNedp(GD>sG)#v~g zOu5g^!3z&_Pg);^`Uan!U5a2+A6m7x&))#}fsjtECAwiGX}~AvjGt#}4Bb;HuVVVO zTAJ%ME#sy5zr4R7jI4$u-bZ&)Ox^Nc@utjx+TQ@q>$~XsAbjfP;8@xx`YxI}Epr1t z*EU#oYy?lcBWotE4mMfwaN>|O zADe(tEO$dzB~niWdEOsHG5)r7>)yl_`VJuY9hKpBPoO=67s%5ANh91^l3Z$mMt>6!9sTR@XWJWq|0*@N=G(;@FmB|EKy<3G$VF2A4G@h)t^9;o z_OyLAb6dQ7^6=Mj>$`a^rFakKLkopghQhZAj7K{1@@EjT6WuiMV z+sOY-5d-P;b>{_IYsy)smC~Vxk&1<}W75EAi&TXZIH4OM=-#{N4OvI+T=QE(jbVop zru4rSr@JD*@=_Lpl%?~A;Sa?DYR$$!$zSi~It_D5SN<}R| z&Xpb2()|>sLkzC%A-EIWMm3FE(pRx21F$o5%+vRzk6Lg{C`!)FL(K z9wjRaf}%J!`ZK-(HU@AQmN!=}A$jW%Wc`GRH^5^!7(Zf|l3t@U3q2@5OOyQd0H)de z1rZ;@UmTI)p2~Sv^5cCipL50cp+B|a-CQougO&3fY+4UdO�$za>&JB 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 dRdE1^t)5kG)NYan$@Kqv4wC"Tk Console" menu and enter -# -# topo writelammpsdata nanotube.data full -# -# --- ltemplify.py --- -# -# That data file can be converted to moltemplate format (an .LT file) -# using the "ltemplify.py" utility. -# -# The first step is to create a short input script containing the atom_style -# command (ltemplify.py will read this script. Presumably atom_style is "full"). -# -# echo "atom_style full" > nanotube.in -# -# Then run ltemplify to convert nanotube.data into a moltemplate file: -# ltemplify.py -name Nanotube nanotube.in nanotube.data > nanotube.lt -# -# You will need to edit the "nanotube.lt" file to replace all of the -# "@atom:type1" atoms types file to match the carbon atom types in the other lt -# files (ie "@atom:../C"). If you don't plan on defining bonded interactions -# between carbon atoms, then be sure to remove the write("Data Bonds") section -# of the "nanotube.lt" file (if it is present). -# -# Finally make sure the "system.lt" contains these lines: -# -# import "nanotube.lt" -# nanotube = new Nanotube.move(?,?,?) -# -# (Replace ?,?,? with the location where you want the nanotube to go. -# You can also rotate it using .rot(angle,axisx,axisy,axiz).) -# -# ... and then run moltemplate the normal way -# -# Let me know if you run into trouble with this approach, -# and I will make note of that in this file. -# -# --- links --- -# Note: there are numerous programs for specifying the coordinates -# of the atoms in a nanotube, some of which are below. -# http://www.nanotube.msu.edu/tubeASP/ -# http://turin.nss.udel.edu/research/tubegenonline.html -# http://www.ugr.es/~gmdm/java/contub/contub.html -# (You can load coordinates into moltemplate using the "-xyz" or "-pdb" -# arguments. However currently (2013-12-01), the file must contain coordinates -# for all of the atoms in your sytem, not just the nanotube.) -# ------------------------------------------------------------------------- diff --git a/tools/moltemplate/examples/force_field_explicit_parameters/nanotube+water/moltemplate_files/spce.lt b/tools/moltemplate/examples/force_field_explicit_parameters/nanotube+water/moltemplate_files/spce.lt deleted file mode 100644 index e1bf2390a0..0000000000 --- a/tools/moltemplate/examples/force_field_explicit_parameters/nanotube+water/moltemplate_files/spce.lt +++ /dev/null @@ -1,52 +0,0 @@ -# file "spce.lt" -# -# H1 H2 -# \ / -# O - -SPCE { - - write("Data Atoms") { - $atom:O $mol:. @atom:O -0.8476 0.0000000 0.00000 0.000000 - $atom:H1 $mol:. @atom:H 0.4238 0.8164904 0.00000 0.5773590 - $atom:H2 $mol:. @atom:H 0.4238 -0.8164904 0.00000 0.5773590 - } - - write_once("Data Masses") { - @atom:O 15.9994 - @atom:H 1.008 - } - - write("Data Bonds") { - $bond:OH1 @bond:OH $atom:O $atom:H1 - $bond:OH2 @bond:OH $atom:O $atom:H2 - } - - write("Data Angles") { - $angle:HOH @angle:HOH $atom:H1 $atom:O $atom:H2 - } - - write_once("In Settings") { - bond_coeff @bond:OH harmonic 600.0 1.0 - angle_coeff @angle:HOH harmonic 75.0 109.47 - pair_coeff @atom:O @atom:O lj/cut/coul/long 0.1553 3.166 - pair_coeff @atom:H @atom:H lj/cut/coul/long 0.0 2.058 - group spce type @atom:O @atom:H - fix fShakeSPCE spce shake 0.0001 10 100 b @bond:OH a @angle:HOH - # (Remember to "unfix" fShakeSPCE during minimization.) - } - - write_once("In Init") { - # -- Default styles (for solo "SPCE" water) -- - units real - atom_style full - # (Hybrid force fields were not necessary but are used for portability.) - pair_style hybrid lj/cut/coul/long 9.0 - bond_style hybrid harmonic - angle_style hybrid harmonic - kspace_style pppm 0.0001 - #pair_modify mix arithmetic # LEAVE THIS UNSPECIFIED! - } - -} # end of definition of "SPCE" water molecule type - diff --git a/tools/moltemplate/examples/force_field_explicit_parameters/nanotube+water/moltemplate_files/system.lt b/tools/moltemplate/examples/force_field_explicit_parameters/nanotube+water/moltemplate_files/system.lt deleted file mode 100644 index d7c610fc0c..0000000000 --- a/tools/moltemplate/examples/force_field_explicit_parameters/nanotube+water/moltemplate_files/system.lt +++ /dev/null @@ -1,29 +0,0 @@ -# This is a small version of a carbon-nanotube, water capillary system. It was -# inspired by this paper: Laurent Joly, J. Chem. Phys. 135(21):214705 (2011) - -import "graphene_walls.lt" - -import "nanotube.lt" - -import "water_box.lt" - - -# ------------ boundary conditions ------------ - -write_once("Data Boundary") { - -15.98682895386 15.98682895386 xlo xhi - -14.91 14.91 ylo yhi - -31.0 31.00 zlo zhi -} - -# --------------------------------------------- - -write_once("In Settings") { - # --- We must eventually specify the interactions between the atoms --- - # --- in different molecule types (graphene-water interactions). --- - # (See Laurent Joly, J. Chem. Phys. 135(21):214705 (2011) for details - - pair_coeff @atom:Graphene/C @atom:SPCE/O lj/cut/coul/long 0.114 3.28 - pair_coeff @atom:Graphene/C @atom:SPCE/H lj/cut/coul/long 0.0 3.28 -} - diff --git a/tools/moltemplate/examples/force_field_explicit_parameters/nanotube+water/moltemplate_files/water_box.lt b/tools/moltemplate/examples/force_field_explicit_parameters/nanotube+water/moltemplate_files/water_box.lt deleted file mode 100644 index c825276f5a..0000000000 --- a/tools/moltemplate/examples/force_field_explicit_parameters/nanotube+water/moltemplate_files/water_box.lt +++ /dev/null @@ -1,20 +0,0 @@ -import "spce.lt" - -# --------------- water ------------------ - -# Create a rhombohedral box of water. (A rectangular box works also.) - -wat = new SPCE [9].move(3.5526287, 0, 0 ) - [9].move(1.77631435, 3.3133, 0 ) - [6].move( 0, 0, 3.45) - -# Optional: Center the water box at the origin. (Not really necessary.) - -wat[*][*][*].move(-23.9802437, -14.90985, 11.47) - -# --------------- Note: ----------------- -# The spacing between water molecules does not matter much as long as it is -# reasonable. (I adjusted the spacing try to insure that the waters are spread -# uniformly throughout the box. We do not want bubles to form if there are -# gaps near the XY periodic boundaries.) We will have to equilibrate it later. - diff --git a/tools/moltemplate/examples/force_field_explicit_parameters/nanotube+water/moltemplate_files/watmw.lt b/tools/moltemplate/examples/force_field_explicit_parameters/nanotube+water/moltemplate_files/watmw.lt deleted file mode 100644 index c7aaecebbc..0000000000 --- a/tools/moltemplate/examples/force_field_explicit_parameters/nanotube+water/moltemplate_files/watmw.lt +++ /dev/null @@ -1,54 +0,0 @@ -# This file stores LAMMPS data for the "mW" water model. -# (Molinero, V. and Moore, E.B., J. Phys. Chem. B 2009, 113, 4008-4016) -# -# In this model, each water molecule is represented by a single "mW" particle. -# These particles interact with their neighbors via 3-body Stillinger-Weber -# forces whose parameters are tuned to mimic directional hydrogen-bonding -# in liquid water (as well as hexagonal ice, type II ice, and -# low-density super-cooled liquid/amorphous water phases). - -WatMW { - write("Data Atoms") { - $atom:mW $mol:. @atom:mW 0.0 0.0 0.0 0.0 - } - - write_once("Data Masses") { - @atom:mW 18.02 - } - - write_once("system.in.sw") { - mW mW mW 6.189 2.3925 1.8 23.15 1.2 -0.333333333 7.049556277 0.602224558 4 0 0 - } - - write_once("In Init") { - # -- Default styles for "WatMW" -- - units real - pair_style sw - } - - write_once("In Settings") { - # --Now indicate which atom type(s) are simulated using the "sw" pair style - # -- In this case only one of the atom types is used (the mW water "atom"). - - pair_coeff * * sw system.in.sw mW NULL NULL NULL - - # -- Unfortunately LAMMPS itself does not understand molemlate syntax, so - # -- the atoms are identified by order in the list, not by name. (The "mW" - # -- refers to to an identifier in the system.in.sw file, not watmw.lt.) - # -- This command says that the first atom type corresponds to the "mW" - # -- atom in system.in.sw, and to ignore the remaining three atom types - # -- (correspond to the CH2, CH3, CH4 atom types defined in trappe1998.lt. - # -- We don't want to use the "sw" force field for interactions involving - # -- these atom types, so we put "NULL" there.) - # -- Note: For this to work, you should probably run moltemplate this way: - # -- moltemplate.sh -a "@atom:WatMW/mW 1" system.lt - # -- This assigns the atom type named @atom:WatMW/mW to 1 (the first atom) - } - - # -- optional -- - - write_once("In Settings") { - group WatMW type @atom:mW #(Atoms of this type belong to the "WatMW" group) - } - -} # WatMW diff --git a/tools/moltemplate/examples/force_field_explicit_parameters/nanotube+water/run.in.npt b/tools/moltemplate/examples/force_field_explicit_parameters/nanotube+water/run.in.npt deleted file mode 100644 index 2728a1f5ac..0000000000 --- a/tools/moltemplate/examples/force_field_explicit_parameters/nanotube+water/run.in.npt +++ /dev/null @@ -1,147 +0,0 @@ -# PREREQUISITES: -# -# You must use moltemplate.sh to create 3 files: -# system.data system.in.init system.in.settings -# (You do not need to run LAMMPS to equilibrate the system before -# using this file.) -# -# Requirements: -# To run this system at constant pressure, it might help to compile LAMMPS with -# the optional RIGID package, and use "fix rigid" on the carbon. (Optional.) -# The use of fix rigid is controversial. This method is demonstrated below. -# THIS EXAMPLE HAS NOT BEEN RIGOROUSLY TESTED. This simulation may fail. -# (However the "run.in.nvt" example in this directory should work.) -# ------------------------------- Initialization Section -------------------- - -include system.in.init - -# ------------------------------- Atom Definition Section ------------------- - -read_data system.data - -# ------------------------------- Settings Section -------------------------- - -include system.in.settings - -# Use "neigh_modify" to turn off calculation of interactions between immobilized -# atoms. (Note: group "cGraphene" was defined in the file "system.insettings") -neigh_modify exclude group Cgraphene Cgraphene - -# ------------------------------- Run Section ------------------------------- - - -# Only the Cgraphene atoms are immobile. -group mobile subtract all Cgraphene - -# (Note: The "Cgraphene" group was defined in system.in.settings.) - - -# Unfortunately you can not use the LAMMPS "minimize" command on this system -# because there is no way to immobilize the carbon graphene & nanotube atoms -# during minimization. Instead, we can use langevin dynamics with a fast -# damping parameter and a small timestep. - -print "--------- beginning minimization (using fix langevin) ---------" - -timestep 0.1 -fix fxlan mobile langevin 1.0 1.0 100.0 48279 -fix fxnve mobile nve # <-- needed by fix langevin (see lammps documentation) -thermo 100 -run 2500 - -unfix fxlan -unfix fxnve - -# -- simulation protocol -- - -print "--------- beginning simulation (using fix nvt) ---------" - -dump 1 all custom 1000 traj_npt.lammpstrj id mol type x y z ix iy iz - -thermo_style custom step temp pe etotal press vol epair ebond eangle edihed -thermo 200 # time interval for printing out "thermo" data - - - - - -# ------------------------- NPT --------------------------- - - -# ------ QUESTIONABLE (see below): ------ - -fix Ffreezestuff Cgraphene rigid single force * off off off torque * off off off - -# Comment: -# The use of "fix rigid" to immobilize an object is somewhat controversial. -# Feel free to omit it. -# (Neither Trung or Steve Plimpton use fix rigid for immobilizing -# molecules, but I noticed that at NPT, it does a better job of maintaining -# the correct volume. However "fix rigid" has changed since then (2011), -# so this may no longer be true. Please use this example with caution.) - - - -# Thermostat+Barostat -# Set temp=300K, pressure=200bar, and equilibrate volume only in the z direction - -fix fxMoveStuff mobile npt temp 300 300 100 z 200 200 1000.0 dilate mobile drag 2.0 - -# ---------------------------------------- - -# The next two lines recalculate the temperature using -# only the mobile degrees of freedom (ie. water atom velocities): - -compute tempMobile mobile temp -compute pressMobile all pressure tempMobile - -thermo_style custom step c_tempMobile c_pressMobile temp press vol - -fix_modify fxMoveStuff temp tempMobile - -reset_timestep 0 - -timestep 0.25 - -run 100000 - -timestep 0.5 - -run 200000 - -# Hopefully the barostat is no longer oscillating. Increase the timestep and -# also get get rid of "drag 2.0". (A non-zero drag parameter will result in -# unrealistic fluctuations of volume under NPT conditions.) -# drag 2.0 <-- commenting out -# -# Set temp=300K, pressure=0bar, and equilibrate volume only in the z direction -unfix fxMoveStuff -fix fxMoveStuff mobile npt temp 300 300 100 z 0 0 1000.0 dilate mobile -fix_modify fxMoveStuff temp tempMobile - -timestep 0.5 - -run 1000000 - -write_data system_after_npt.data - -# (The "write_restart" and "read_restart" commands were buggy in 2012, -# but they should work also.) - - - - - - - -# ----- Comment: Avoid using fix rigid/npt on large single rigid objects ----- -# -# Use of the following is not recommended: -# -# fix Ffreezestuff Cgraphene rigid/npt single temp 300 300 100 z 200 200 1000.0 force * off off off torque * off off off dilate mobile -# (temp=300K, pressure=200bar, and equilibrate volume only in the z direction) -# -# In my experience, the system becomes unstable when applying "fix rigid/npt" -# to the immobile atoms, while also applying "fix npt" on the solvent atoms. -# (It is probably a bad idea to use two barostats simultaneously.) -# ---------------------------------------------------------------------------- diff --git a/tools/moltemplate/examples/force_field_explicit_parameters/nanotube+water/run.in.nvt b/tools/moltemplate/examples/force_field_explicit_parameters/nanotube+water/run.in.nvt deleted file mode 100644 index 86253c45b9..0000000000 --- a/tools/moltemplate/examples/force_field_explicit_parameters/nanotube+water/run.in.nvt +++ /dev/null @@ -1,78 +0,0 @@ -# PREREQUISITES: -# -# You must use moltemplate.sh to create 3 files: -# system.data system.in.init system.in.settings -# (You do not need to run LAMMPS to equilibrate the system before -# using this file.) - -# ----------------------------- Initialization Section -------------------- - -include system.in.init - - -# ----------------------------- Atom Definition Section ------------------- - -read_data system.data - - -# ----------------------------- Settings Section -------------------------- - -include system.in.settings - -# Use "neigh_modify" to turn off calculation of interactions between immobilized -# atoms. (Note: group "cGraphene" was defined in the file "system.insettings") -neigh_modify exclude group Cgraphene Cgraphene - -# ----------------------------- Run Section ------------------------------- - - - -# Only the Cgraphene atoms are immobile. -group mobile subtract all Cgraphene - -# (Note: The "Cgraphene" group was defined in system.in.settings.) - - - -# -- minimization protocol -- - -# Unfortunately you can not use the LAMMPS "minimize" command on this system -# because there is no way to immobilize the carbon graphene & nanotube atoms -# during minimization. Instead, we can use langevin dynamics with a fast -# damping parameter and a small timestep. - -print "--------- beginning minimization (using fix langevin) ---------" - -timestep 0.1 -fix fxlan mobile langevin 1.0 1.0 100.0 48279 -fix fxnve mobile nve # <-- needed by fix langevin (see lammps documentation) -thermo 100 -run 2500 - -unfix fxlan -unfix fxnve - -# -- simulation protocol -- - -print "--------- beginning simulation (using fix nvt) ---------" - -dump 1 all custom 1000 traj_nvt.lammpstrj id mol type x y z ix iy iz - -thermo_style custom step temp pe etotal press vol epair #ebond eangle edihed -thermo 500 # time interval for printing out "thermo" data - -# Integrate the equations of motion: -fix fxMoveStuff mobile nvt temp 300.0 300.0 100.0 - -# The next two lines recalculate the temperature -# using only the mobile degrees of freedom: - -compute tempMobile mobile temp -fix_modify fxMoveStuff temp tempMobile - - -timestep 2.0 -run 5000000 - -write_data system_after_nvt.data - diff --git a/tools/moltemplate/examples/force_field_explicit_parameters/waterSPCE+Na+Cl/README_run.sh b/tools/moltemplate/examples/force_field_explicit_parameters/waterSPCE+Na+Cl/README_run.sh deleted file mode 100755 index 70c34bd6f4..0000000000 --- a/tools/moltemplate/examples/force_field_explicit_parameters/waterSPCE+Na+Cl/README_run.sh +++ /dev/null @@ -1,33 +0,0 @@ -# --- Running LAMMPS --- -# -- Prerequisites: -- -# The 2 files "run.in.npt", and "run.in.nvt" are LAMMPS -# input scripts which link to the input scripts and data files -# you hopefully have created earlier with moltemplate.sh: -# system.in.init, system.in.settings, system.data -# If not, carry out the instructions in "README_setup.sh". -# -# -- Instructions: -- -# If "lmp_mpi" is the name of the command you use to invoke lammps, -# then you would run lammps on these files this way: - - -lmp_mpi -i run.in.npt # minimization and simulation at constant pressure - -# or - -lmp_mpi -i run.in.nvt # minimization and simulation at constant volume - -#(Note: The constant volume simulation lacks pressure equilibration. These are -# completely separate simulations. The results of the constant pressure -# simulation are ignored when beginning the simulation at constant volume. -# This can be fixed. Read "run.in.nvt" for equilibration instructions.) - - - - - -# If you have compiled the MPI version of lammps, you can run lammps in parallel -#mpirun -np 4 lmp_mpi -i run.in.npt -# or -#mpirun -np 4 lmp_mpi -i run.in.nvt -# (assuming you have 4 processors available) diff --git a/tools/moltemplate/examples/force_field_explicit_parameters/waterSPCE+Na+Cl/README_setup.sh b/tools/moltemplate/examples/force_field_explicit_parameters/waterSPCE+Na+Cl/README_setup.sh deleted file mode 100755 index 3a08212692..0000000000 --- a/tools/moltemplate/examples/force_field_explicit_parameters/waterSPCE+Na+Cl/README_setup.sh +++ /dev/null @@ -1,23 +0,0 @@ -# Use these commands to generate the LAMMPS input script and data file -# (and other auxilliary files): - - -# Create LAMMPS input files this way: -cd moltemplate_files - - # run moltemplate - - moltemplate.sh -atomstyle full system.lt - - # This will generate various files with names ending in *.in* and *.data. - # These files are the input files directly read by LAMMPS. Move them to - # the parent directory (or wherever you plan to run the simulation). - - mv -f system.in* system.data ../ - - # Optional: - # The "./output_ttree/" directory is full of temporary files generated by - # moltemplate. They can be useful for debugging, but are usually thrown away. - rm -rf output_ttree/ - -cd ../ diff --git a/tools/moltemplate/examples/force_field_explicit_parameters/waterSPCE+Na+Cl/README_visualize.txt b/tools/moltemplate/examples/force_field_explicit_parameters/waterSPCE+Na+Cl/README_visualize.txt deleted file mode 100644 index 019afc1444..0000000000 --- a/tools/moltemplate/examples/force_field_explicit_parameters/waterSPCE+Na+Cl/README_visualize.txt +++ /dev/null @@ -1,87 +0,0 @@ - - ------- To view a lammps trajectory in VMD -------- - - -1) Build a PSF file for use in viewing with VMD. - -This step works with VMD 1.9 and topotools 1.2. -(Older versions, like VMD 1.8.6, don't support this.) - - -a) Start VMD -b) Menu Extensions->Tk Console -c) Enter: - -(I assume that the the DATA file is called "system.data") - - topo readlammpsdata system.data full - animate write psf system.psf - -2) - -Later, to Load a trajectory in VMD: - - Start VMD - Select menu: File->New Molecule - -Browse to select the PSF file you created above, and load it. - (Don't close the window yet.) - -Browse to select the trajectory file. - If necessary, for "file type" select: "LAMMPS Trajectory" - Load it. - - ---- A note on trajectory format: ----- -If the trajectory is a DUMP file, then make sure the it contains the -information you need for pbctools (see below. I've been using this -command in my LAMMPS scripts to create the trajectories: - - dump 1 all custom 5000 DUMP_FILE.lammpstrj id mol type x y z ix iy iz - -It's a good idea to use an atom_style which supports molecule-ID numbers -so that you can assign a molecule-ID number to each atom. (I think this -is needed to wrap atom coordinates without breaking molecules in half.) - -Of course, you don't have to save your trajectories in DUMP format, -(other formats like DCD work fine) I just mention dump files -because these are the files I'm familiar with. - -3) ----- Wrap the coordinates to the unit cell - (without cutting the molecules in half) - -a) Start VMD -b) Load the trajectory in VMD (see above) -c) Menu Extensions->Tk Console -d) Try entering these commands: - - pbc wrap -compound res -all - pbc box - - ----- Optional ---- - Sometimes the solvent or membrane obscures the view of the solute. - It can help to shift the location of the periodic boundary box - To shift the box in the y direction (for example) do this: - - pbc wrap -compound res -all -shiftcenterrel {0.0 0.15 0.0} - pbc box -shiftcenterrel {0.0 0.15 0.0} - - Distances are measured in units of box-length fractions, not Angstroms. - - Alternately if you have a solute whose atoms are all of type 1, - then you can also try this to center the box around it: - - pbc wrap -sel type=1 -all -centersel type=2 -center com - -4) - You should check if your periodic boundary conditions are too small. - To do that: - select Graphics->Representations menu option - click on the "Periodic" tab, and - click on the "+x", "-x", "+y", "-y", "+z", "-z" checkboxes. - -5) Optional: If you like, change the atom types in the PSF file so - that VMD recognizes the atom types, use something like: - -sed -e 's/ 1 1 / C C /g' < system.psf > temp1.psf -sed -e 's/ 2 2 / H H /g' < temp1.psf > temp2.psf -sed -e 's/ 3 3 / P P /g' < temp2.psf > system.psf - -(If you do this, it might effect step 2 above.) diff --git a/tools/moltemplate/examples/force_field_explicit_parameters/waterSPCE+Na+Cl/images/Cl.jpg b/tools/moltemplate/examples/force_field_explicit_parameters/waterSPCE+Na+Cl/images/Cl.jpg deleted file mode 100644 index 5261bedc2ce1b6d41ea202b21a1dbd921e2ee6a6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1577 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 diff --git a/tools/moltemplate/examples/force_field_explicit_parameters/waterSPCE+Na+Cl/images/waterSPCE+Na+Cl_t=0.jpg b/tools/moltemplate/examples/force_field_explicit_parameters/waterSPCE+Na+Cl/images/waterSPCE+Na+Cl_t=0.jpg deleted file mode 100644 index 2c34754c4c2754c75502a87245bf882f555b1def..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 169027 zcmbTd1yCHp`zE}&27(3%nuRP2fdIi>f-SzdLxAA!?vUWJK!V%i9-I&)c!DpsXmEGe zi6yGo}PK;d7gfneOdv$gviLt08mg+0CLY8;AtKp1;9W< zM@L7)c-~=PU|?e5V`DuRLOeVid?G?(Vj@B!A`)`yS0toVWJE+13=~u}G<0-yB(L5u zzM*BLrlq6(PY{&ns#us<1lZUFw4_9&wEw@$Qzw838+8T^9}VRV0F?*@jR@tb2S5Wr z0idEiHx~u)KME!mItDfxDhkf?W!0Ae6tw4pijIbfhKYfKLWF{fh7Q0W!X#$E;*=m! zBYk7)%q1C&O$LM}=8@NSF@E?IGJY)OlJxK7RX!89dR_NNGgpm*w>&bMzbDq7BT}OP zP@d!b&vXF5e?mTY3-X`<(R&&klSpYvfqx9h)}hfah+%)m(^p@#XKjWjqhueNLa z7|8Vxi(C?#bVByQh4DGlr;z-*w;J726HiFM^F2P_A{r4u46xq{g)x93s$p=jBryz* z4f%gPObK^wLmrsCj_qSqj42d8Rn@#iKfBdnIh%T5!a^uoGLAR{H_kJVN!}|dCczh7 zN1K(CV;YDjKnkU3b-K0F>l9OHskyt9?(!8-aVM!Th4l7|g~R?)OnF%771_0$qxuCW z<`cl{<6C8}`FMwuE^Nn*(Op)Rdz|sWUdZe{PRk|w2-_2YxwYO=uv~fW3NL(>6(ZlA zK-O+{2wQ&w*n}_n{4tGcc(aJBxGKiUP@hx#d{&ipcX+&Agd%+Ltx`(~zCFu%;seQ9 z;ANS;`J@LP3zW^{OCk(*K)_UE0Nnj?Mu(UTT;zTN41*sNFJxEgF!Tzb7b>bH8PYMG z=E32W3BjRT?AczTEFTc8MX2>~;bQ_go1^(or} zRZgS}>t_3^zr_CBYVN-$BdCbuU$v!Ds;9bx*v>67rj$GZwoB1TZPJMS9|@lTxBex9 z?AMI31}lsqDqT4=9VaZ4b?qnQR#1M?3Xhq72j~lnsaGDM#MbnKO`!o_7v8#QqHO=I zNt&HHytR>sM0V54xW@Qo#+(_8Jy11cloV^fvmE`+OmcPec;PgWd=*Xf7YvMZ zeJYw6|1%WgX^T;^m0ABw*!k>^e3foQ z4Bqk4NvG8DG2VuWU!zh_C^(Z}S@`A&&;bviO|WsA@UTG~-N-8&0O;~YgE09|R;$X? zJG@z+0N(=TZh;}a@&xfV?lgN-UzUSV{zQ)c3N-Gxs4hHD){aOTn+EW@kS44(1Fkwp z1n0jDz;bQ7XqRvMsU4@}d+bnMkKE|?;gL7mir$_N_J3?5Uzdx*axDt5xjO{7EM zbk#2O@pQ)B@jT2)uVl)tz}P~_-4^7)yQ#lMbLad7@aDPpQK}BrCn~3)M@>j(JLXLi z`*#-HKT$0ReLT|+oP1!QCNJX|Nxh&negf!l=i}h~-Jy%5cr+67s17^-QOcm-(fgP2 zU_Q|)aen^zvV0oW@pG#E^?y}kcIznJR%M>XXABOK9+K-kxnbQfLrKik^cY7r|&=KOPL<1IXBHkb*00$hdVR0|mMjJv@fc5@yT11E0_ zf&^1WfJ*Kgj6^K^&WTTevxw2``xaU5Q6tnV98U|9!Fg|SG&&V%t01hSUHu6#5Pz#O z1p>IUX3|Zz`>OYTmY&UCW?C#P&b%fd40LofHIAxrKj2sMIrcD*F-#X3JlSeFU!CWa@uQU*tdzeuhG@)r99%=>U%mCEGwbL;xUdelX&VhWr7YEmi}7^* zJh^&)CV3{@ay`ma9)B871eB~0z+L4UE;ee^f8Dx>J+x!p9o_~m+5U4DJSNt8`vlmR zONzO^pSvX#eFEt1q^o!MEn17n8l zc3EdQiocr5zegcknzMmHTH%MEGYZeIo5Cl+MgC*X6g44n3taKygqQ~17#ATG_4@#J z(uvl2bS)dO?rbC@Ya|K9^NGX|&B2jz?z~*NylJ}v`E=f7LTeOd^#%14UzRjAABOqNshC+cgv1sd)i=&IG%;y)ERN(FN zp#1mh4k~*?32D(((P%+v*jSlYa>{`vt6$sQHy}7f4dfcGe@Rh}mM7PmZnc#)$!2Kl z-%hL{UFGEM2Rlh2nK|Fz5sTqj)*8306D*#^;(s7bCiy0XL27>SCzl3dHcP>7plR*4 z>jSU zE67O$-1nOCpPW}YO|`Ng6u%>%@5_hIHybYM$8t1SnBw5DsOOvz*B>j(3LN!A-DDQn zvRG<3$eLSTui_xpA1|c;x*oJqp2bW(PDPQMR=5kj_7t446-Qpx?l_yzez2TU+<|DP zvwnp@!wRZ@HrvZFC|RyFprZYp(RJ)9)0@?vG{d9J$VJZKgv z=j~zE$jn>((%`QSl8S8v@-_WhZ?0gSuZ!Q)SG#oh!R~$V+NU|F-~(T3*<}_lDW<>o z#9FUafM+JQ$_3BMUl%H}dNn!m22+VywTW$aNmy6Uqa573y;;^e$i>56Y|SLUUaxf* zxeaN25KjND<0DbP7R2&VyUNkT!XWef6q6feTkXj&QuR{yZV9cUo;>hv(ZM0s8oSQvyIFJ$O%l16cpz*f zFWw0~69X6k-~gN$*TXG};m-q_g1cwSw3Ich1GrV@{_zB;AiO9orN__4kQIc54UF-@ zit$jn(zjtI38Z?OiYek}d%4}{zel(QKmY~oTa zOszG77ozcL(mYxw{_k21ol)pUS)4rjrwxbOf759o{>zkcLN+<*1L*J_bBdsAYz*vL zq>12>e|0%|X)toBz>+@G}sz~Gfu4$*dSJ_gV|1^2iRK_k=e@ej)-%#qpxgAiy7lj;8@wy!iiQq!sUY3MMv z`YtA7!OctoPfd;uOIyM9K>%+h^R!J?>jQ z*<1Hr7V^wP`v#wAI=5m*P1>dGJ@#6>4-3hdLSIon`EC?4({kvcp~Y;i)7tu5Y*T56 z+lVMI9Dlf{utH*q{r&j_xX!N(3^hGpK5>_Ppe()I6)EM9_uR0V-z8|V9+0(Y1fHdB zDCpRWDVjMy=4vSYDs~5Iv=*HYe;*Flmt5@`Qcv!?sCJ_BE2%$6oA8}$}(PfxlL2FPwWZmYKYqk$K1tkVZVl9=Io2hiJV^`lbEZ_p7L2 zDFDqJ4pxKz_X*bd`2c6Vby1Vi;uat-y=J+JO9WtL2BK!*bvlY_9@ z&3d!Q73`ZQgYtfdk@OukkV6bG!~JAiy8SWig_CBDh97YbdM$+4?CP5gb)>8?AZo$@ z;VI)13WOkyD|@XzNu_?ub{H|dANNoTdtWRA#J@#W_0xvN&}o7-`OVuus#b#Q^`scA zAbQf!gv86c93~vfAe_Ik3w&~`+(O3c>lO3=JT{6qcygKw`LPH z5Iu1K6pDoFEi3C^C{1SXJa!HPp74<^|Z$#{`f2VLTvA}JtU*IA5 zHhwHBh?~*$gGqVawawF{vN+DQAK|MRKRKT=v1Oa++{)2B%)hBa0J46bi6)nHfp$}l zpJs+TzcgQ!(6-JQ=MEX%;d4gzozvhYeZp(!MElP%Gv1% zv->D_CY1dU6!HGQ{DWeSKDCw%Gp4^L349#c8kia^Uu(!>mS-4$0SMB2OAB z%y8At7M#yTIUxM?{JeL?{nXX56Bc6*6^b!yBBdISQPXFKoEh~DVL7rai*dNFX)1FzII zvEO>r?rJYaFnvYqF2TIkci8jL@s~)dVhjg-f;F@{U7umQ3&qtm<|`!%?5QGd(r>Dt zIaUk8E8E%>ll1DZxkb!;G)f7q;d5mpW#}h|nFr7laEaWY2f*NsuhbfDvMk!*);z=i zJZL!C*OBsiym_E*To_67!;kdd3Bll3I@x7Lk{K41{=Mat+J1y4B6oqgubthhysXj6 zk|r9i@D{6HR9|JBQE{rQ=#i4`(wVQdtmZW?74+~nEP$HBN)?1CsO?l@at`FCH|L0j zW$ZM=A!rGN!go>ewn~cAIoEF?s5##nm@tgP8Tc3EA7tr_;Q&Ma47?Nuxa|QSsS2*T zagVjw`wDC%+%nTQzS7*_b6=B$k6nM#AN<@(TeW?x+Xv=1eS=iT|D5W;YSBh@O@A6+ zC(p*yC?Js;pSpN$ilFK7>V6Z<^73Iy20`f)F2%J^(?iQt8z}kNJloHT>U%76H{_sVt5aI|n55dHWQr_FX7hOZ?&n`On`>Tq1&L{sp0X)bU zc_^&JoJyZGxHALe4sx%CBMX#nm=Pm7U<86 zgx}G6ue}>evG8zIg;Z*9XDV?}Fu;&|TzNG)RYp(1DKn(Q`hQ`dezz~OUFvH@!>9Gt z7-VIxjGR^&14}Q_l68IO3IUEvFt! zj07`$%oKN;C-fV@EAvDNfnRz4-k0ed3z>>Uy7+$D+Lo1Dv-)P$wv_Ow80pmvzRfL+> zLbpEsns7@*|CON&Z0!4{xzzO++DQum-d7r)`-q_<5v?rW#GuB4cE**&ds%XlS)xAD zsvEl5xU4d5Ov7Uc=2i zSq>}oQ~H+e%w}3tqH(I905}ZmjXAsdtQkazxDuO%VwJ8I(b&iI6awD91kKK&Bpem2 zq3ffIigHKU+xP&#(O-sd^cLKLRx`cY7>k1km0kNoI%rw-uS{Xc84aH7S1p&0hl*QCk$)J?{c$e~AH$~n10HfUcggn~8v!63^|mavtyz1(8ckHo zRpn;RHfCz{PP=c8Q`;{AXQ2o3)PTX8_71+N+WO1nNj*Qpg=v0{X|a=+V;4eZDLLPc zRdPT}3By6p+(T-=qMsXGK%t(tV}71~i+i~)|7xCOtBk3vfG&}~oG7M;1BJ*h$0}RV z(XnAQCtOd}UFI?9Y7@AmgdO~GJ*m1ob8D1mtiEI!nI3^(Ut7np!tP(J;-Ut41iBmO zw1RUFN@#ylzTy+h)?dFFHMgfj7B~K}Z=Iu-ZS0K3fnC~1Bq3$DvBtDCS&55ZmX(Rc zGkAW#0aNugnZV#I=`R1{M~}64=N;EBm2*$zt84XaB_H1Ucf{dnp`quZh(_=Syg7gE zp2&>2-|;_dA~NLl5PkqICGtHhJym!R+=FbxHR}82AP20yG+`*6g?fdVDCbBn`rMev zfwPcz@{1AL^5K<}%8t>g@#hb?0a9P>>mQkzk6H4Y7aCMl^ikbD7dM`^zhzOS@2?eZ^M8z)Ora86gKcY$|jQ&QiNaFpD?wWiMUnKGv^xnZ~3JBihKKzF4obR6- zcf(U@+?JR8(d82&99x%0F7v za&~QYr*J!~(5!7kzQ{O3>q+ZC!0JtX|KQ&J6{F+E0O<@ubjiD;ZY+g8r zXuj6a4|szNDU@+SFD-WMpFzK4O&no8liVwh%R^|jDZzu*6z?ZsT+oOPM zgdLcQu`JI@8adKTW^=fX`kBP7{@VAM{$rox+e$9Nw=Sm_)VUy`b}##jGX(3I{W9&f znXlwFw=nn@xjJI<4sHz=j_*lc@C{*k@R$0W6E)t9HVe3685WpNIBYln)i`T z^D+>4Pn@vIzXm?dyzeyQ#{v*(^(9T*YL@>%M$j}0KqhkJXHtIhLS5TYjDtu*v)5=b zRHON=*|luL1rjSFE^96;V@H*LPwR=krV4q3Oj>sn=&({4pB4w9#}S4IX@Wlg7?}{v zg4?vINhvn#+ej#HW^Xa($%Z%&j1UI!uij4~Luj)aD3dfuS79&z=yo}O41U0LQF)vy z@wq5I;#`@3|L%ACXEt=MRpNTMtdKIHS+>Xx9KU7QK3Pe^44-~`W2d-k8k@Z5@1jE! z56|#Y1~c|eGkT^cf1gTx6VJbDo_ZlxrQWbR<-g9>xb*AXAs>=_%};_aFw3&bt?sI# zblUVSMOga&y|8!MaF)NP&jAW_w_Rc_?D$xkQk8vdhB`QWc%clIkU&v>x5l`hNr*L? z)6OB>s;@6C3_I!n$V7N#Y&@>teNfy`+11W}hYF2xe<#;RV+$ZIq}}Q2ycD(sM!{R7 zOsO$`s`;1H;3ZD{3T8P5I4ndgM zqbQ&bG`fkVnU*p8G5oS& z;qP6j4HDsrbFT|@Sn3I0U`1A!7-cvkO_?q7!vL=xQNU>NFkel_a&7~KtS-G!6=mML zpCLv>3p(dHTFVaGYJHygp(C;aW$9a$4SwLW0wwP|_k)C@Y-rjus@%_^?EgeSi0&Ht zal)x{T!;{U-a@ksaNOIjUNkIW3;d}DU+3+~iLon!8fXuNu?7($)^FBA*EMx3DhN8i z@~-7>fdAN$!d?Hp!i^#dw~&CSEycrf;gKXvQnKwpUP%3*liJ*aN8gyceM{bu z_Lue5_f|bhzn{&+F)ftB<*-XV^?|ibY9}W-yLb4MkPM;{cZKUv$*Lj)g8E2QjjT>; zW|R0l+6&^{tj2z~hTeD&|Ls$}9x3M-pRc;q$G*jlfhus#l0C(X=C(|&iNlxTK@vy+ zbxGpdh;N+ioBSCi3s;2tr-d$qwzlZmh0nzDgZHt8=GPQwM$ zoz0y;!;l8pfpqTL#|AO6)k-LCN7PVbB`A|YUgRrvf(wC4!$)?i%`4|@ghEAsF-IX2 zr;c4p?9f5y24p?X#ZR*mUQf1qgS+=Aq-*`*+qoKL3y$+<%1>4V3#FVYvoeQY&L2@WW14q7#@<8*Ib_Sx+&?HvVA?Uu` z=S?1~f9|W}U3o1}P_r_Dry0#z)YT7n-f^m-->ONB281V!47OeKnJL6r0>?se*YqX> zS3DJeA;l{AKa}6ZHno1g04lbX)t{R5eR~5jJs&XbWh@oyRP7Ermi%(-8GWp}8 zC_Ucg%LZ)JIZ}j=Nt)rjfbKi+1WX?Q#UykhkoH}^?WbBbYTT)>OoL7v!nWzaYYep` z&hw1^k?G+(B95*O43n2$heOS5;yz0BrN7tCRfLoK)3si1Zo7fs+UCNrxYk`*Mfavz z_Y^-i^?BC}8c{df-K1vsyjYqW*|%(3*gbD+t=e5L`7AhJ!nmA*vj_p|jc8C)x!bmldt{15_S(L_J=6 zL==)vvDb`fSK2Nr0>TK@Et6W7L;7t{f*_|OMsz;gp)U8nzQInVd?pgI4rW>NiCYB- zub2b8Mm_|mFHK=hirBq+0xWE8ro!bs2?zZlEOuL)3xon7k^8CcEP0DhK5UK#>4fl_ z{9K)|ouB_t=kLa!qmxP|BZpS|njEso-g~A6jNRs&@p(;3#LK;j!iiARZ7ad%^N;{wYsN@%_swn1qAgz>VH{NRaCNYhr<6U}*NpPMyDSf`rJ1 zsncvUatT}^ShQKzp#0TJJ`$ZcKJ(v91Q%*cx5OpgOt0VhnYu9#+Vmfhbk?P4hj7tr zYl#R_#9ty9k z8oPBPF}YHyEGTd!Nivy$+d{Y$XK5M@9DNo7O8rb3dhL2G2Rr&dQVUDfCvny&7zET@ zP3MExw@V+mnrO(xk^qi^9#Jbh=YtMw$w zxmk>j;b`Lo7j7Z!9oTpPWnZM_!J4ke3+2}Z8wWhBWiq*Hy755?(Pn%hopwNMw!?>L zFo&y0qTz_~6(1#FFW$yuHV7J*;C;j<&-nD}tzTrf_yUeDKN8c|dl1yQ9QhM;BvoI-q2eO(`67L0}rDS2~{;`(Z+afbhQ!PC9Ue+mkmsLE8T{Mhs>C+jQJ zQ!Tig-;T{#j@}4c=IE&gX#rTY!Quj4Vm2WcScSahzn`Ub?_RxX2j*6%g5#s=k@Em( z;CKG@_0VA`*9C3a=fg^#(#liHWNMg@wL&t%8#EyQ zX_e?#tei^UYPQ`;-V$W%R)v~t^Us7y@)>CEDsqG)oQy7!F?5!2CRAIO&8MK0s`e#Y zZOmX5epZ349WNn^+I=Y{b+)qjdID?p{>*3NFKC+D*G^3?-Zy@u!y1)-rgID)rZcKd z$ZECS$GW}d6ADv@%3hdw5V9kZl2%^yni4wN6a=7=AJ0zJz4f$*PN)lBFwo0q7OtT^ z0lFH+SU%jAocaQ|Zlxxp#gzBOun37A2!lQ=LphpMY92KRaUOirGbY=lkXncu)iHe7 z!KBg$uN*=G-z*P?$oJm!&uYW5PDZP|;oy-jOqOR*eFz*IqPDOL*@o6%lS_xM)33PdMV z!kF61mYfMb=r0PKs5f^H)o-O#%0E3LxW6k7XNVzM#zW40@&)mO$U0t`m8CCSsMsl; zh|T&U-sW|5v$slKRdK_!Oj~A39*g*V>@Y-YKE%KpNyYD?f_FuKT3-`@+x(b@80ZhZ zSH?iXF^p`6?VX!>myUCHP!($yL^}M-*W(@y@IJox2qHAcB;Z19vK?=XypVn{^v&+6 zlS0xm|LCKJy|QQ+-E_|OVs`!$fJ+!}%b`ATSGLOg78fd_iva8*ttD{}937uE{ zRgq+0Y-L_Tw^BodpMhq&)(`U+7EM^|W%9U`LPvy^SojyuZdgC|V1v(@9s2gY*k>yOxBU+NeX};07 z26WtM|Csy)DAbHB7Szq%7iVG5j=3v%0+8!mOkLglM@LZt>s)v}0<{a1GTf*LP3jVB zIomLz zw~%5oQ64Lgu+?eSPY-3YiK?iABymWrJ=?(k3JhGW^?u$q^cX3eBCh1rf5hWdn6I4; zhXX+ihaftYcIH?169T<;1wGbIC4MI!RPZRm>w?&oJ3*U=TyiBS261q&$_?Aq9TjSH0~DlpY$Ty! z)GO6tPXIrB_1=Xk-L6D=+e$j<(JA-E>J-~0qTHoBu{%mK>lkOBK!DCdLrh!0-v3Hn z$FT`7+xSAYr8dl@{#V#3A4&{n)ra32jeFsJ`3vCbW3$?3} zZ~BLx89$@Rb2XSt^fELo=a_Jug-Nma%t1i3(D+Kujg3^3DP1_}K@N}97wer%jcQeQ z-0A83SOV_Y=}jnP(Ly|Ltsm!Dyg#5{%uGK!%NE_HR9g!vLxkTD8i)C?VEJh9*znP9 zS=z8ct1M8(P@(pqG3B$_*8y!mro!?rZIEc^18ad@Z3UG(xOVPe?Mnc;t_43x*g;LW zB-4{I8{CCzDUuX*LT)LOdP9QoY<|1X#uz3Fs@0 zE3jIWD10{}KQY0i{A2CIcfHdyE9&GvKHxGMaFv z&bJW%WRS9#Na%xuOi5*EIIoQ8TFGXml5;_&PubF*BcpWA&cP>NIofi=;}3o7r!Gm( zBQgZo1^Zbdt%?Yjeb4BYh>P0MfBX?w;e{Y4ok41o!YfeoYAf5^c*eJHHpVAWdGqV$^xQ^WT_-j`o z>a(&nlajQ(*zdR>eUKk#C4{+vyA`UhB^{GAavNc9WDl?U%;a4$6s!`HNHI~n1`e|O zDS*7Fg7L*~ z(^Ybyv-Ea4?esib!WRnw@MUE76uI6P+S(z=7YLZ1Zewam@nL~P2ZNj>i9W2FBb?$ycqgJenx#iG-7k-(;+(3m!=nk zNt#BM^h}{}t`MGAEGiThs6-&nm7N5`>{qrnF1HSCMi9KrukIu--hD2R!j@nF%gH;V zoiT^TE-OC)HZ&Dm;&E_ey041+2q~^AZu6Kk3{_a!+t57d-qL)w8gtlR^gG`em!o8< zmuWJpcdxzZ4kzW~sR!&OF5{}P^JB5#VhJ^_;Q(Vyl-@na|LCdX{uIozxxI9%^^@BC zem!`|b%lV-R(C?EA$8a?*~J@CfA>XB=R$c)q(;a&$B~D2w=eALd!;7C3mURZg^UzI zM(5NAv2S1m{s#R^7fcB(ehPsJVXfb0t!sK#bYIfAX=!dAe0*<9jmmb|LRuCqG_WRlWdZt|i9~(VJL~_~Lf>XdI?B>d`**zaaX@5n!DJFo+yn^FfH5%sL69 zs05F&ooG7q=f#=97JtGV%S33~3>#1#1r28vSxlY)_NE&?rtH**PS0iqzqp%&1g|-L zZYh86os@~)A+rI*CxQ1P_AE^GWPrj(6?!HC0f2ds+=&)K_SYLhn)B&7)eSrfXu!%$ z@5o1;)E(lYQgF;9L?12%w4y%QiYFZ#doj5vv`k?th@s~;uf^l;z*GBOq9LYoOQS~P z#|jYGvD~i1={W68IA~fP;wNB3p@B*;s&KU5R5dTe?xJoZ6i^7P%rL<-TX zfa!Jb8y6?!%^DU>Buy{Kz1^VjW3pXKb4i^UGaNyh&_pedgm#py`}<933|;C=^Abs8 z$a%f5eN9-l?eB^hSluF?vq(sh)@8bp-(R8VR`qWY5R-`eph{3#H0Wmm+tKGV9AS}Q z38%yJuK-jI$ol_uT|rx|&*B+JW|XKFnEr75QP&>TT;1AuEM z;iIha?b358%UM9`l#!p>4FqH!5|^W-4#E<-!%dd0o7U*_@jlzE#ZaaBu=8-HzpF76 z@UC1bFA2Srp<1ydI5sw%K*Pz!Nzyla<@LO({EzeB3R0n;ni|JbfD+C zSHI|r2Sw?woGLnXsM<(@HAU;Fa)$n?LByE@R)M^vCwV3y2;#zrPmDb<;u{)5(HDUS z-nI0Xie7Aem~0I)2%t$#Wo+LGAAn*bXGJ2>PMqhrZDg>4^y}I}rFu_*B0enp1O266 zjkkRD`!b}f)N*|qg&-EYVo@(qoXvU?!Rk^IJ&O#|t3|0EtU`I2jhY6_#y~!b5zg~b z?zv4{Z1P2gh<|m6zAH0PzSqjogz(kiahsH~@X!)h_UD+q^X{eg1sbD)Tf_?I4;(f%RB;8Bu( zck|7DAg-)vhaEOW)$785{Ow$+)YABIO9nboLx3ozul#5h+;5kd?ekjR?MTK-M$D&v zBIOM$1bRr4%>pF}Z4q}0bCMep=U>@`rz$Ab4cgl*T7~p5#|B`27ni%uDHWAppYAB( zwQRtQYSUd~wfo8mqZGP~SM?h}zjHtnQ=H(o05E;Om&ZG3eW=^@b)Sp0kY<#T=ydjT zcwlu4XV?r$4sWbq_kC%b&b|0}R>VGTciT86itg5|eSCx(CR(^c98Q>GLM(;@Y--ny zzxagsJ8c|aC!L1D#S}WEow(MA=_1A#Up92TX2n>fI;k-wXJ+PT8rYE(Z!4P6Zf5UU ziN0Sy_OrB?N3JQA_7zP?ixXvu->7OoOVv(=UUf~F-~H?p^fUq!g6uJR=rxu zG;6Sb|6rw@>)`f+Bhs{AcHpzX?{ax`3-EnM!1IEV;2qIikg{Z=y~6gcLVIHm=Y$7$WAvx+6X5rLmvcawhPXYBN=y$NapB<;cZm7-hfuA2g|jnHB|WL;gV-%Q>56XvZTt9;cw}F!dlkY7?n( zyCi-=Ax;4y=~MMsb2?PPszLRXau`qD`O*HP<7;Y9aDGpdRJdgWCngIKE#v3zmpGjO zZ_x6>4bKtHr8zIPMNf0+oV+mAvtiZB(5*+mp;%e}&`BV246P6Iv0^#cFfU#N z@^tKs6g}Lp>u}_pQ+SgRi}hRNE=1-n#wt<}KgnGh0A|vnrG@OlNgsd5OVL z9(9h=8!g@6{INr@>mCL*J=;`AbpON_Z|4O;Whnuylt-%XkrwC#`J88+{2v>tI%Wl|K$sN3IxXMUgr zff5pfl(8Y0AI<@Z3zuef-fQRg@^dCuzgkJonttvJmR+YZyil)1*L`tgzrS&;^xkx; zU3JPT`o()izXOFja>4?#U(U^O#M#%hDt74y%4yp|Z-XYkG$3^`u240(ppl~tot(`% zXun8i&F_-@Z(Z~4^hi|l$IasFsad4qC(W=k8dYJhS1*^zEpQM;mh`GkEgYD2OyZVDuw)Sm{Y|{nB ziyJ@(80=SVVCz9wY-9gOwnFEA+WbJcyMNj}k-Fx6VvhCvN^XWh<%!|@=eW{>|79(x zzTH58T78S(jC@5QVfvG}T~EWv8$>M6(husxqV+G&suppZzS1I}pVTI0tz%&3NbC~| z-t~P9JgrK@*@t_8UuLsnlC+31;U_ml^twMxY&bUb8nnT-$7aQcGX2NGg0IA!A8ZIc z_h`R{jB9v9i%WA3`I%m=tbOWq*CR zEUikcIj>qdrI`|u|7Hx0yHvxN?&^F39G5{N2oY$PJd*@HljA?WYHf*i#e(Kd{F`v; z(xiWJB4&pQb%eSw%Mh7mSlI|qxYvn+Il4ukU0A| zR*Yt$-Gc{On=wD!Xo(a&N~u2C-bpqo!sbWl1b#<`UZRm%>s#t?)}+iANhghrLCu;| ziXCI@`FkygqyAlczz{NP8Rxe-K2B!KZSB$DD;|h&!1ml@iRMSwE(qvQa z160!gD?H8;&yZrOL=toCMZbcIeP^;VMS|GaT?Dy)o)ekLZtx6e07PU7jF3G6UeSeJ z9*XQRCU9}tyTA(y-IWw{jA3-`DNg{Wc226};Zh;R$k!Lj8vx?$!0kY|kKPf71M%`# zS}6y?0bEu2L&8k|C%{Atn@{V3b3&&nbaN?N)pBwu(|IzJkx)!rSX<)U^`pW0AFe9T zov#5~0`;gv1ZtGPq?ktwVsBtP%xvMO06c%_RX^}8n@5*2dvd;b?CxJ@u;f$?+RfKv zvAiq_RNnFZ#GsR(SGfZ*NXSbo zgl%o=outreIM14|plI}tmef{}Yg0tpgp%vgLbk*xbLYI!n(;kvGn13DS%FG>dxs@c zyuOAh;Xfx`C@&C0%6%E~L$DtMbj;cT4=uw)nBTfu_0E7SnG@r_yVbUZ*q#c$(>MDJ z*P|fYFWP2L07(LDQS36lGAiY}f{OA)^UV7_g7xo8{DE<^S6TpEIn@yv?12IPx7Dp> z@6vnic3;O@Gh7>Y;O+Y|;9XaO;+&mGJQVTshqf~$ik zjdEB^1{2wDwMdUD?<(cx91-{WT2)=3W?9NRXXwmrFvgKdfFw%{3E1H;#XxRQ&D*3nd+XW=Nl&3H1o5MZ zs+g+0vep>UeO*>SwHG~}k0eHedXLC_$i^bO z8(&HgB2-bzDVZp_`YvTI_U+woaR%K!=N1Tss7DMcmks|sqxmLZYnv_)lRA}&0~F)S z-rDV*##({oX_oNb)x-XuZzulEhjdwu$HaUD|70oqYiV8ejf&d9?Icdu!0#A1VDWne zIaOA)g?-$$QJeVL1%%pL`N=;yM8x00dWG?;nPwvK4xHC*_)e~B!?vXjc!E{j77R_r zHSM(pzlVN*@Bf=1BhSB1I}6;k0P2^~$I%48+PS*W71Y<%apy_gbKkj451~9Cf*hyh zurfY6$Y5B(_wEV>Dy5qKI;-icz0A@Rzi__)y)6cQOlf##>$Xa{*LP+>Y7PkY@+nic zcckT3H>xMp#F{q|aun;AWnW|Is*CzGS9y|b>r5);oL(mU1c8C33?DQ9%{O}1dSWm`G4%Zl0}=eNBk-|ClnYTcgz2F~`@Q@oTiflGq9GV=X62XR~cWY$Bw zG-dBf-XW0+@f@Cz;$HODueMGS*(PyS|z? zNvW@Re3`%?T&>~K#j7qk+Syw~vfNHPB~zPQhIGjE#RLT*LvJ{GeO^M2>RF4CjEe*y zPMoKBSMlgXIsB{pcQX5Wb_LVq7!3McV%hrvelZBb)>bQj=Oc+%-Ga7LFe8k~fiIF0 z#E20$^jbDR04oU7W}$vR3RCHRrsJEKD-r7hVw_oX{l!)~2g6SL9pBB!e%Xfz| zARl%>)c9LC%AA91O~QzYnX;s|0xd$dG>ea>sJ4STP=E0REtJvF%;%pq){KtZw7@Sz z>v~0l=5o-FGmwx>Cl^Ui>Ks4T=Bo;;SJpGEch20q39B0@yFSsg5&ibN+QCPcXBsBo zAUv;Gy|SryL4X+pT2o`a9L?uN7*)%{wOn&dxf8GTT;{e|m_RL*PXP8Qd3VX*juU+A z89aT`-NWx3-SKpv?f9vPyzWT)(B-am5^Ya8w{@LV+urmOE}m(-1~k4gXf#;%dEJ#V zPCv*4WvF@og}7jGUa^iP+c#(UXr0_6&=!h2Nn@b{*4^3(aZd2>;zkC4vp^BUPLN_q z_|>;mtrz1~AZfs3i?zyL5^1xXLXY2Ef77)e-Tn>Ba7yPsSCgZT9aojIsXmXKqbG*N18zsWba)`>9bOk z4nTT>p>AsX%oMQ-LW|G=-LxoxwR3~?P#v-EYhJxV>|5vW8EZp`d8}a=!U4yDj&eEo zuU2A9zBuGaP$Wumz*Xr+ZA(z|zymy1mFr=HF>THDgRCzFrxCSCP(73nIUl7}4RMe> z?zZHpiIlFUZ{<4MqM7ve)o|5Xl@S*u`(>3yZa(*=orppdwE><6ae?0%&N!~C(=S?M zSs+8UlH4|%OA$iPDoRENeotzvdR3|6s?x=hDR1H*Aqn5N(hcLD4|DYMn%QbAyWKjU z>bl}5L6(A+20msEc?CWbpX-cw8LRFAt-FflqAr?1$eOKnB`Qfmk_t{i1aNa)>vhxj z?E!Ie;SKh#)+jH9ms>eo04sp%KjG|DGwwjG#mB4nR^To?R+)7~^EeK{U6Pdhf=4H? z@P8FYR>zH!T?%Q-$mJ3kQvZ2NbRJCAkJAv`X9C<%oSLvL{ zPQcb$2Gu4_x^pOy>{#ga6&+4OOK8Cn!Jz&IJO`06!z(d{4I0_><+6gADolnud7pShy-6ydz60klYOh2$mBOI(_za7)JzuO*tJk~L; zjyG?%M@uX+*lZ;U!Wu$G0#Ki1jx*=%1#I=6xJ9bc>Yzt)_tq4ap4*0j1HMmkKbPrN zp3+tfGckuv3Y6LHkZjhLEq0i##fcfcjI^BXNdEvc&m^8nB%0?QvnQFj@`^Wz)!CiJ(LuCXC00~@+cQ+utUpaW!<9pldP;(SoY>p>ylfM&gTAN6Xj>! zS^T4u&IcH*T~*ZWJ#0dw+T}5JpR;$S!+}U^J&M#jf93DTj`hvj=ESy7UY}~NqFz;~bo?lh zEq5YI&${?RRN_~)YS=PQKEsle=e*X((Y-rjwm*OB4E0TrkX&(w9$RtH0O2DTQ;PnX z;A4!NCrIiTlPu|SBoxMq-V)4a8_7Zkj1C9rD$|D$TFVj{O(XM%Sd{6ehqGu~0xkB) z==hfsgEmng#E{?}$vof^aGt{_+~-HuEnhQF%d}e|I2riwQOBGI3JF0#03R7DIs1L; z#i$=zw2h-v>DHv&Zi}?PZ&_SxJdmIrj?{Rte_ zGo4hv+gO!w(^n}Dy(K=RqanXgG*8M2$RMa4xL2?MQB~(v%coy3H z{)+nRW76@w6bIK8D@1N>+%Boe`kHx5V{vH*mo=g3UrR6guKxfsLvqEc z#}ZQGy&wWq_R?~Ol6W{E0;L=b{$dEOo65Ja!r2 z3f$YGGXey7QIoZn8%t;(Krk!WN=j3?L;yUKOlw0$f|hxmGxNW7rPaEc+ot0(a_O zeP0!~q}!pkxbo70ksoq_OPCzs_9w8yed}M+y?JZ9&TY%|&CRserx>_@gw`|o)BgZ? z{^CH^xug|T%_K6l?bHQI1TiJAN%q3fPH=tw$F*cK?fStL*>*=>EhH6W5?0UEC%MP= zsc%#uSz6TdE*2=?2W}^Nk-OwR?lwP=p2Nqm>^?Nr{v4Zgt-xdzHlUR_;QDt0vEdSN zGQ@t1(J>Q9XvEdA*w_)Lcyu37bn;#rdJe4W6|Zf&6KHt0t@2Bu21jkO%KA(9BeL+mSFnrq+*!q4q zALj5obI60)t*_l5+(}GytN4x+$@_bn^={7gLY9Ib@myHtjk<=OeJ(x?+@B2(5mSrS z;-pfwpxYR^Re5$xo-$&> zb<~XGBp{GKQ-M^!?2`xQzuZ(i23SY`0BK790P<>i`$JFo9+h0s7qQ7pYC1l-SSla- zQmVoInQiKa(<2IVuuQTIYwa?$Pb&E-AtM$uH>U&Bht=Rtn z5fR^2ZK(wZ3P>qX&O(9458*Y~4j~RUrrbhSg#r|n41y1EMR8o#oatX(K1D1?wp

%LC@Cr#1RR1r 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 diff --git a/tools/moltemplate/examples/force_field_explicit_parameters/waterSPCE+Na+Cl/images/waterSPCE+Na+Cl_t=100ps.jpg b/tools/moltemplate/examples/force_field_explicit_parameters/waterSPCE+Na+Cl/images/waterSPCE+Na+Cl_t=100ps.jpg deleted file mode 100644 index 220a717271c2e5fd6a8e9eb6ec47cd3851062339..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 144377 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π= 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

l^S==Le_#a<4CK+}-y(%f2bH3W>>@b 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 diff --git a/tools/moltemplate/examples/force_field_explicit_parameters/waterSPCE+Na+Cl/moltemplate_files/ions.lt b/tools/moltemplate/examples/force_field_explicit_parameters/waterSPCE+Na+Cl/moltemplate_files/ions.lt deleted file mode 100644 index 8d36341253..0000000000 --- a/tools/moltemplate/examples/force_field_explicit_parameters/waterSPCE+Na+Cl/moltemplate_files/ions.lt +++ /dev/null @@ -1,67 +0,0 @@ -# We define two molecule classes to represent Na+ and Cl- ions, respectively. -# This may seem like overkill since they both only consist of one atom each. - - -# Note: Monovalent ion parameters for Ewald and SPC/E water -# are from: Joung & Cheatham JPCB (2008) -# These Lennard Jones parameters match the parameters for ions -# in SPC/E water in the "frcmod.ionsjc_spce" file distributed -# with Amber (the 2010 version). - - -NaIon { - - # The epsilong & sigma parameters from that paper were 0.3526418 & 1.212. - # However sigma must be divided by 2^(1/6), because they use the alternate - # Lennard-Jones convention: U(r)=epsilon*((s/r)^12 - 2*(s/r)^6), and - # pair_style lj/charmm/coul/long uses U(r)=4*epsilon*((s/r)^12 - (s/r)^6) - # (Note: This change does not effect the epsilon parameter.) - - write_once("In Settings") { - pair_coeff @atom:Na @atom:Na lj/charmm/coul/long 0.3526418 1.079769246386 - } - - write_once("Data Masses") { - @atom:Na 22.9898 - } - - # assumes "full" atom style - write("Data Atoms") { - $atom:Na $mol @atom:Na 1.0 0.00000 0.00000 0.000000 - } -} # NaIon - - -ClIon { - write_once("In Settings") { - pair_coeff @atom:Cl @atom:Cl lj/charmm/coul/long 0.0127850 2.711 - } - - write_once("Data Masses") { - @atom:Cl 35.453 - } - - # assumes "full" atom style - write("Data Atoms") { - $atom:Cl $mol @atom:Cl -1.0 0.00000 0.00000 0.000000 - } -} # ClIon - - -write_once("In Init") { - # -- Default styles for ions -- - units real - atom_style full - # (Hybrid force fields were not necessary but are used for portability.) - pair_style hybrid lj/charmm/coul/long 9.0 10.0 10.0 - kspace_style pppm 0.0001 - pair_modify mix arithmetic -} - -# Optional: Define a group named "ions" consisting of either Na or Cl ions. -write_once("In Settings") { - group ionNa type @atom:NaIon/Na @atom:NaIon/Na - group ionCl type @atom:ClIon/Cl @atom:ClIon/Cl - group ions type @atom:NaIon/Na @atom:ClIon/Cl -} - diff --git a/tools/moltemplate/examples/force_field_explicit_parameters/waterSPCE+Na+Cl/moltemplate_files/spce.lt b/tools/moltemplate/examples/force_field_explicit_parameters/waterSPCE+Na+Cl/moltemplate_files/spce.lt deleted file mode 100644 index 019911c19b..0000000000 --- a/tools/moltemplate/examples/force_field_explicit_parameters/waterSPCE+Na+Cl/moltemplate_files/spce.lt +++ /dev/null @@ -1,52 +0,0 @@ -# file "spce.lt" -# -# H1 H2 -# \ / -# O - -SPCE { - - write_once("In Init") { - # -- Default styles (for solo "SPCE" water) -- - units real - atom_style full - # (Hybrid force fields were not necessary but are used for portability.) - pair_style hybrid lj/charmm/coul/long 9.0 10.0 10.0 - bond_style hybrid harmonic - angle_style hybrid harmonic - kspace_style pppm 0.0001 - pair_modify mix arithmetic - } - - write("Data Atoms") { - $atom:O $mol:. @atom:O -0.8476 0.0000000 0.00000 0.000000 - $atom:H1 $mol:. @atom:H 0.4238 0.8164904 0.00000 0.5773590 - $atom:H2 $mol:. @atom:H 0.4238 -0.8164904 0.00000 0.5773590 - } - - write_once("Data Masses") { - @atom:O 15.9994 - @atom:H 1.008 - } - - write("Data Bonds") { - $bond:OH1 @bond:OH $atom:O $atom:H1 - $bond:OH2 @bond:OH $atom:O $atom:H2 - } - - write("Data Angles") { - $angle:HOH @angle:HOH $atom:H1 $atom:O $atom:H2 - } - - write_once("In Settings") { - bond_coeff @bond:OH harmonic 1000.0 1.0 - angle_coeff @angle:HOH harmonic 1000.0 109.47 - pair_coeff @atom:O @atom:O lj/charmm/coul/long 0.1553 3.166 - pair_coeff @atom:H @atom:H lj/charmm/coul/long 0.0 2.058 - group spce type @atom:O @atom:H - fix fShakeSPCE spce shake 0.0001 10 100 b @bond:OH a @angle:HOH - # (Remember to "unfix" fShakeSPCE during minimization.) - } - -} # end of definition of "SPCE" water molecule type - diff --git a/tools/moltemplate/examples/force_field_explicit_parameters/waterSPCE+Na+Cl/moltemplate_files/system.lt b/tools/moltemplate/examples/force_field_explicit_parameters/waterSPCE+Na+Cl/moltemplate_files/system.lt deleted file mode 100644 index 639222d182..0000000000 --- a/tools/moltemplate/examples/force_field_explicit_parameters/waterSPCE+Na+Cl/moltemplate_files/system.lt +++ /dev/null @@ -1,49 +0,0 @@ -import "spce.lt" # <- This defines the SPCE water molecule. This file is - # located in the "src/moltemplate_force_fields" directory. - -import "ions.lt" # <- This defines the ions "NaIon" and "ClIon". - -# Periodic boundary conditions: -write_once("Data Boundary") { - 0.0 34.50 xlo xhi - 0.0 34.50 ylo yhi - 0.0 34.50 zlo zhi -} - - -# The next command generates a (rather dense) cubic lattice with -# spacing 3.45 Angstroms. (The pressure must be equilibrated later.) - -wat = new SPCE [10].move(0.00, 0.00, 3.45) - [10].move(0.00, 3.45, 0.00) - [10].move(3.45, 0.00, 0.00) - -# We now create a 2x2x2 lattice of Na+ and Cl- ions: - -na = new NaIon [2].move(0,0,17.25) - [2].move(0,17.25,0) - [2].move(17.25,0,0) - - -cl = new ClIon [2].move(0,0,17.25) - [2].move(0,17.25,0) - [2].move(17.25,0,0) - -na[*][*][*].move(5.175,5.175,5.6) -cl[*][*][*].move(12.075,12.075,12.5) - -# (The (5.175,5.175,5.175) and (12.075,12.075,12.075) translational shifts -# prevent the Na and Cl ions from overlapping -# with the water molecules or each other.) - - -# Comment: Fortunately the ions and the water in this example share the -# same force-field styles (so their was no need to use "hybrid" styles). -# If this were not the case, you might need to add something like this. -# -# write_once("In Init") { -# # -- Styles for the combined system (overrides earlier settings) -- -# pair_style hybrid lj/charmm/coul/long 9.0 10.0 10.0 NEWPAIRSTYLE -# bond_style hybrid harmonic NEWBONDSTYLE -# angle_style hybrid harmonic NEWANGLESTYLE -# } diff --git a/tools/moltemplate/examples/force_field_explicit_parameters/waterSPCE+Na+Cl/run.in.npt b/tools/moltemplate/examples/force_field_explicit_parameters/waterSPCE+Na+Cl/run.in.npt deleted file mode 100644 index 9bd2f15f46..0000000000 --- a/tools/moltemplate/examples/force_field_explicit_parameters/waterSPCE+Na+Cl/run.in.npt +++ /dev/null @@ -1,48 +0,0 @@ -# PREREQUISITES: -# -# You must use moltemplate.sh to create 3 files: -# system.data system.in.init system.in.settings -# (See README_setup.sh for details.) - -# ------------------------------- Initialization Section -------------------- - -include system.in.init - -# ------------------------------- Atom Definition Section ------------------- - -read_data system.data - -# ------------------------------- Settings Section -------------------------- - -include system.in.settings - -# ------------------------------- Run Section ------------------------------- - - -# -- minimization protocol -- - -# Note: The minimization step is not necessary in this example. However -# in general, it's always a good idea to minimize the system beforehand. -# fShakeSPCE was defined in system.in.settings. It is incompatible with "minimize". -unfix fShakeSPCE -minimize 1.0e-3 1.0e-5 100000 400000 -# Now read "system.in.settings" in order to redefine fShakeSPCE again: -include system.in.settings - -# -- simulation protocol -- - - -timestep 1.0 -dump 1 all custom 200 traj_npt.lammpstrj id mol type x y z ix iy iz -fix fxnpt all npt temp 300.0 300.0 100.0 iso 1.0 1.0 1000.0 drag 1.0 -thermo 100 - -run 10000 - -# Now that the system's temperature has become more equilibrated, -# we can increase the timestep: - -timestep 2.0 -run 50000 - -write_data system_after_npt.data diff --git a/tools/moltemplate/examples/force_field_explicit_parameters/waterSPCE+Na+Cl/run.in.nvt b/tools/moltemplate/examples/force_field_explicit_parameters/waterSPCE+Na+Cl/run.in.nvt deleted file mode 100644 index fb0642332f..0000000000 --- a/tools/moltemplate/examples/force_field_explicit_parameters/waterSPCE+Na+Cl/run.in.nvt +++ /dev/null @@ -1,58 +0,0 @@ -# PREREQUISITES: -# -# 1) You must use moltemplate.sh to create 3 files: -# system.data system.in.init system.in.settings -# (See README_setup.sh for details.) -# 2) You must equilibrate the system beforehand using "run.in.npt". -# This will create the file "system_after_npt.data" which this file reads. -# (Note: I have not verified that this equilibration protocol works well.) - -# ------------------------------- Initialization Section -------------------- - -include system.in.init - -# ------------------------------- Atom Definition Section ------------------- - -# Read the coordinates generated by an earlier NPT simulation - -read_data system_after_npt.data - - -# (The "write_restart" and "read_restart" commands were buggy in 2012, -# but they should work also. I prefer "write_data" and "read_data".) - -# ------------------------------- Settings Section -------------------------- - -include system.in.settings - -# ------------------------------- Run Section ------------------------------- - - -# -- minimization protocol -- -# Note: If you are reading the restart file instead of the data file, -# then you should not need to minimize the system beforehand.. -# fShakeSPCE was defined in system.in.settings. -# (It is incompatible with "minimize".) -unfix fShakeSPCE -minimize 1.0e-5 1.0e-7 100000 400000 -# Now read "system.in.settings" in order to redefine fShakeSPCE again: -include system.in.settings - -# -- simulation protocol -- - - - -timestep 1.0 -dump 1 all custom 500 traj_nvt.lammpstrj id mol type x y z ix iy iz -fix fxnvt all nvt temp 300.0 300.0 500.0 tchain 1 -thermo 500 - -run 10000 - -# Now that the system's temperature has become more equilibrated, -# we can increase the timestep: - -timestep 2.0 -run 50000 - -write_data system_after_nvt.data diff --git a/tools/moltemplate/examples/misc_examples/menger_sponge/README.TXT b/tools/moltemplate/examples/misc_examples/menger_sponge/README.TXT deleted file mode 100644 index 4d3a9d2f85..0000000000 --- a/tools/moltemplate/examples/misc_examples/menger_sponge/README.TXT +++ /dev/null @@ -1,45 +0,0 @@ -NOTE: This example requires the "Al99.eam.alloy" file. - (It was not included in this directory because if its large size.) - As of 2012-11, I was able to obtain it here: - http://www.ctcms.nist.gov/~cbecker/Download/Al-YM/Al99.eam.alloy - Copy it to the directory containing this README file. ------------------------------------------------------------------------- -3D fractal test - -Moltemplate is useful for building larger molecular structures from -smaller pieces. Although this simulation is of no scientific value, thiss -example illustrates how to build large (many-level) heirarchical objects -(Serpinski cubes) using moltemplate. (This is also called a "Menger Sponge".) - -The files in this directory demonstrate a way to build a periodic lattice of -3-dimensional Serpinski-cubes (with 3 levels of recursive self-similarity). - -In this example, the basic indivisible units are 4-atoms of Aluminum -(arranged in a cubic FCC unit-cell for bulk Aluminum). -This was an arbitrary choice. The resulting construct is not stable. -(But it makes pretty movies while collapsing.) - -To understand what is going on with this example, look at this file: - -./moltemplate_files/elegant_inefficient_version/serpinski_cubes.lt - -(This approach uses too much memory to be practical for large simulaions. -The version I actually use is here: ./moltemplate_files/serpinski_cubes.lt) - - --- To build the system --- - -Carry out the instructions in README_setup.sh, -to generate the LAMMPS DATA file and input scripts you need: -system.data, system.in.init, system.in.settings. -(The run.in script contains references to these files.) - - --- To run LAMMPS, try a command like: --- - -lmp_mpi -i run.in - - or (if you have mpi installed) - -mpirun -np 4 lmp_mpi -i run.in - -This will create an ordinary LAMMPS dump file you can visualize with VMD -traj.lammpstrj (See README_visualize.txt) diff --git a/tools/moltemplate/examples/misc_examples/menger_sponge/README_setup.sh b/tools/moltemplate/examples/misc_examples/menger_sponge/README_setup.sh deleted file mode 100755 index 2af3d7372c..0000000000 --- a/tools/moltemplate/examples/misc_examples/menger_sponge/README_setup.sh +++ /dev/null @@ -1,29 +0,0 @@ -# Use these commands to generate the LAMMPS input script and data file -# (and other auxilliary files): - - -# Create LAMMPS input files this way: -cd moltemplate_files - - # run moltemplate - - moltemplate.sh -atomstyle full system.lt - - # This will generate various files with names ending in *.in* and *.data. - # These files are the input files directly read by LAMMPS. Move them to - # the parent directory (or wherever you plan to run the simulation). - - mv -f system.in* system.data ../ - - # We will also need the "Al99.eam.alloy" file: - #cp -f Al99.eam.alloy ../ - # This file was downloaded from: - # http://www.ctcms.nist.gov/~cbecker/Download/Al-YM/Al99.eam.alloy - - - # Optional: - # The "./output_ttree/" directory is full of temporary files generated by - # moltemplate. They can be useful for debugging, but are usually thrown away. - rm -rf output_ttree/ - -cd ../ diff --git a/tools/moltemplate/examples/misc_examples/menger_sponge/README_visualize.txt b/tools/moltemplate/examples/misc_examples/menger_sponge/README_visualize.txt deleted file mode 100644 index 019afc1444..0000000000 --- a/tools/moltemplate/examples/misc_examples/menger_sponge/README_visualize.txt +++ /dev/null @@ -1,87 +0,0 @@ - - ------- To view a lammps trajectory in VMD -------- - - -1) Build a PSF file for use in viewing with VMD. - -This step works with VMD 1.9 and topotools 1.2. -(Older versions, like VMD 1.8.6, don't support this.) - - -a) Start VMD -b) Menu Extensions->Tk Console -c) Enter: - -(I assume that the the DATA file is called "system.data") - - topo readlammpsdata system.data full - animate write psf system.psf - -2) - -Later, to Load a trajectory in VMD: - - Start VMD - Select menu: File->New Molecule - -Browse to select the PSF file you created above, and load it. - (Don't close the window yet.) - -Browse to select the trajectory file. - If necessary, for "file type" select: "LAMMPS Trajectory" - Load it. - - ---- A note on trajectory format: ----- -If the trajectory is a DUMP file, then make sure the it contains the -information you need for pbctools (see below. I've been using this -command in my LAMMPS scripts to create the trajectories: - - dump 1 all custom 5000 DUMP_FILE.lammpstrj id mol type x y z ix iy iz - -It's a good idea to use an atom_style which supports molecule-ID numbers -so that you can assign a molecule-ID number to each atom. (I think this -is needed to wrap atom coordinates without breaking molecules in half.) - -Of course, you don't have to save your trajectories in DUMP format, -(other formats like DCD work fine) I just mention dump files -because these are the files I'm familiar with. - -3) ----- Wrap the coordinates to the unit cell - (without cutting the molecules in half) - -a) Start VMD -b) Load the trajectory in VMD (see above) -c) Menu Extensions->Tk Console -d) Try entering these commands: - - pbc wrap -compound res -all - pbc box - - ----- Optional ---- - Sometimes the solvent or membrane obscures the view of the solute. - It can help to shift the location of the periodic boundary box - To shift the box in the y direction (for example) do this: - - pbc wrap -compound res -all -shiftcenterrel {0.0 0.15 0.0} - pbc box -shiftcenterrel {0.0 0.15 0.0} - - Distances are measured in units of box-length fractions, not Angstroms. - - Alternately if you have a solute whose atoms are all of type 1, - then you can also try this to center the box around it: - - pbc wrap -sel type=1 -all -centersel type=2 -center com - -4) - You should check if your periodic boundary conditions are too small. - To do that: - select Graphics->Representations menu option - click on the "Periodic" tab, and - click on the "+x", "-x", "+y", "-y", "+z", "-z" checkboxes. - -5) Optional: If you like, change the atom types in the PSF file so - that VMD recognizes the atom types, use something like: - -sed -e 's/ 1 1 / C C /g' < system.psf > temp1.psf -sed -e 's/ 2 2 / H H /g' < temp1.psf > temp2.psf -sed -e 's/ 3 3 / P P /g' < temp2.psf > system.psf - -(If you do this, it might effect step 2 above.) diff --git a/tools/moltemplate/examples/misc_examples/menger_sponge/images/AlCell_LR.jpg b/tools/moltemplate/examples/misc_examples/menger_sponge/images/AlCell_LR.jpg deleted file mode 100644 index bf07914dac8fc5c9e0a6aa8f19befc1a24a3b2ca..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2364 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 RX!NLYjPO&9hb^mp{{YWDqPPG6 diff --git a/tools/moltemplate/examples/misc_examples/menger_sponge/images/lvl1_LR.jpg b/tools/moltemplate/examples/misc_examples/menger_sponge/images/lvl1_LR.jpg deleted file mode 100644 index 11174969a31106b16ee58318bb2fc3e5de426801..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2623 zcmb7Fdpy)>7k_5Pj2YuH7g_5JDc_Wrf+=RLpY^L&24=Q-#6&Uw!F`JUxJmj?iD zr#0Iez+f<73q4@D7gzuUd_`7f1SB#jnH52!P)HO8EhmRTV=!{^O7e18MJxuRfLBmd z!r|~ZIe7w+fFnZhxD_X`6-$H+8ZyLTF<5Bz|CHss0FMSfz#9R>12`Urz{8fsfDB*& z0YwYN`&E!ASs4TzhK6>P|7-cn_VP0zkAML<4uJyzwzTi76#($&U24&6bsM!C@<8E2 zt(pyfZr4>U%))R4P{^1!wRgqU>@Dw2jT5*4 z>v#Pck~yuhN55Fr7pyUFJAJwzzNdhoG<~{MShApq{NNf-QmyDBkJlc#zC{mjqGfrhtgO{Z| z7_tMGkyS43mmamnzIh5q3;T4VlodI0DyVAG01m?j$1 z(JZhK(XwdeQSG)rS%VQ?k>6Gt@{88INl1^)U+_H(<*!VhmmRtsH>E5SH%sYES8*nt zbn=ysOo@iJ4hyPxJLQeVoPz7e-DGn0Yt|VAmJDbHK0-t}r90u3iZ>icUwx3)Gp+hk zWJg{&AzuH~A@+{#n~G~TBDHY8w>7D&-yPPrDE?@;z5hz<|zv1*mX12Km_o45|g5AVXyk)y*jmp20|E8f(YiLy=9JEK&uN zUn+qzgU|o%d);sum|Q_j2^52;7w#)fnxCk9?K4Gp`0gAYF;HaUj24um0M=YyNbew? zu+@!JXB#+oyK9D6Yd2evd8OR2WNu%Tv493E`Hto-o!yZr~kM@uO4l-o;Q??&SG#WyoNcd2A=KGWZSxBTo@GpZ$W zTr=e-_Y4sHptM0oq&!M!?TD)WzRDhUAUYu@b#f$wj+Ag~XPMHL_}6{9lZoSHA3Gn? zo%zPqH?sG(7R-<}kNo~eNf|gbSRffdo6urWmnhUB{%7seNzo=!U|8Fxe<~9fs5UF(2lCu~v7+I!QaYTQ>`DqL`C7(co;U`d88`t%5GjKhB;r!H@p{-Qt1zB5#gD$1KWl37ADHc zmoGcSauw)4DB0HEbo?#-aUG4x9p9;p*?PSXiG1EVf%;j_S$j-TLs@a`akLnARWY5D zNTnQkV%heVR<%@M@6RQx)@FWhQ5$zx*j;BvVj9fGO!0YpwiuCy*X@9%Hg2yw|GGaZ zcgUXYS3n&I#cy=mMrtBZP^G?hK~(v+y@yhoMmI1nMk?%$(~mf~Xn%L{@luTkyf${Y zEK}MniYu$>S4b!ZglrO%3 z>h!4*00eZ?aeOxY%diCm44sdWfj+rtI-f=7vFRx=3Lk2QFnS6`2F|AN%pqmUHxo8J z=O5T*g?@1Vi+(;S&~Om0KKI%$O!f_4k*O@f#8<+B94`62VA-WH(b-kBaga#Nr)d<2xn;o!(-&rv@AkIKt&AyaBZx-CjK7 zgu=L@$N<@WApx|*u7#<`xs$!WX87yAFzmK`Q82KP6IsFA)?jy>{h|!b);=oRtMDti zSk*Xpw!SkwC%|2VUvI1tHr=w*{+D|@k1J@==NelQ)Pdd`#Ow-N^uD_FM(5#yhZ!VmNt5< z>HF6oE(-RZ!mpZX@KSH}nJys{kCdU4C?10#@Cf2mYr0t&1rdEcVqR))FTW~=BP_a^ zxHB%*6{HmYVLUxJf-!i`GF}F?-}#if&$iE2)Z~kwE%}%yjqv;~cDa4%cZWZr4P}j+ z>UC0EJ+W$7g|$HHv1vz(YN4~EDeWzZ^18!y3iN+Nm#&=ySJ z0x|$d#A{xbE;}_@Hh#TYEiXoLdx@Hqg>2M z`_&`T#ENqt!|6w^pJ^fnjY)e=37RLb87DdG4OZMADBEWq?T7RC+cKnHn{w0WaL()d UGbv?y)vKQU`mD|nqU)Z21NVR!(f|Me diff --git a/tools/moltemplate/examples/misc_examples/menger_sponge/images/lvl2_LR.jpg b/tools/moltemplate/examples/misc_examples/menger_sponge/images/lvl2_LR.jpg deleted file mode 100644 index 744c9af633276fff8c0663ed68d97766b488e84b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7722 zcmb7oby!sIv-sIvVp(eGh6R?ATDqlMx0R=@mrAq-3=@9Ae z-}<@V-}m|6f9`$mob${x^S(24&Uxp|`_9bm^z8xw*HBSc0YD%SpoY1C+aG`;00IAn zzZil6EF7%A0L8(<#=(QaV0chGJQx8n0SuoA9}ka^gpi0B4kv-b2uR6D;ba&Z{?`cT zuO_jUgbSU6w^HZBN? znI-?v@&6LIodpOW7#%nS4gjF5ihry9i@=>|@f(SmSR_w&xtlUnDt-oFg^yd}IdnO<< z2YFVdCj%A$vLsa&hK^>Fq3HKLnq2FJIfQHu1!16+E!7Tzy_IZ&XJ*j8&8%dNS`7dQ zj3d}cO?)`9hzj%3mT=KIL1)`2n+KQ{mUy5 zED#tQ2Oy(BkdTv7vY>R40vPW=F|#0S@GT&A3j|t|OdKyzmEHo@1R@s;pAUPvsYKyh zxXT7qvh)phbC2?wmrunZJ!Wj|cR41xU&R?D!80^vP(HHjV1`S#&&s{3^N+A59Fsrm zyi@Lw$ANNs=$%U<G;~Ktmf#m}E9)c(D|b8u-${xt^7_?3&9m{LEq$P( z(@!JR)6VNn(}&Z7&M(R>k&}0@?0fal{XHoV%12s^Tg@a-T2dOL zR8Qvm>3ss_OvlLcaD8E|xw(u%;Q5fsvmB5&j={!@?VhNXMj1~b+ELcQvG$1#&S9~rLmvl+4N60x*K=b zZtm2oEYm9CF{y7gC{Aqkv+Th?B83jbdDu}U{LMXc(B~Dh5io`;D1XfG!)aZ6p--={ zf-^5JjkUI#%^rv1wYoX?!e=C3(^#BW-XLS6E1^pt%LAiLYfa)E8{+ptH^;7bIjX7< zwQt*FPe^&|m^6N}^NJOEi+kG01`=hK%v*Ky7F}ki%==I9#RkM&|L$F5fm$g@tXhoQ z36K*05>q||Su21L>?`KGPunIo-uopEy${Nk$QMF<##6C&zCTGiKvx?5;NVhsW|7C+ zQ!N1Y@?o=rI@7(MoVM1)t*&8QdLG#10b(DdI#e?Px8|D}y|Z4LB;^EJlxi|X_e%#d zf3P6BsrNc3CKK|=B5pPJLC056ViD@--qkJ6s`&6+4F0}cEEYdhczP(G-ic|ApDk2l z-`@h6J&O?c`8_3RXU)zTFndbb68_U&?Xv<;|5$MqdkF}71lz76x6 zV`+Edsl@jW(-b1cKMK^UX_p6`$Bd43F5cwYn|$w6bq-)o^RrW7ruMl7UY-|qY^z&% z5xd}AZ!MatPs&}zU6D5?5Hx+0gG3Aa-2(B=Gu3H()B2og9?APwr()&PMf4MVS)Z89 zpWpL#x95Jq99&jD+o;q}`);RK#rb{~I^tUt zDJL$zM|UeStk4dGI8)C4F{krzbi1Q=;+ekCD)gk!(BO{=J~zPgX{}IDx`ijF*49Pe zMqmP4$+Bl|NOU0D(0~3<<$4DDG&PzvWVu{JtH=wHWP~-B?MmP1{l#SiS87s9l_o}! z$aS4_%1N7GC&TR+x?7f!Mt6KK(2*7!H$!bFY{vDg?D#L?%$|HccG1P}84f-7NNm5$ zua(cdzkBeF#3~0{FfQ`Oc>JZy(vor1PPg2YORo)T4u0&$Z(wKV`n>8Tzr{D!rLooA zq(PS)-3~jpoVF~%w@>L?j=}A#(o=zxIgO0>K0WiP_+Z~pOC`Z{4C`zY&26H~=kpN} zYmrkwlnqSfQA*;#Thc3QZq3j7L1YMx8oHSDC(Ms==~OXRK}6wl$l zHj=ivD>*vjZKo5-pF-ET9k|yhVc045`>y%@4;=FXQoY*IFDZ!BB3&|lzc8dM^2cg} zC9Tr8GhfEJCS7llB+N`J*bdma>5W7r6Ua@$@_44wDCj$kE!JMj6^|E@luxF1lZ(A5 zwKO)eZ1NFf`xN}G&9ZL8(6{%}!%4dBgzz1Y3Wd$GpSXleFdlQne)?cRKX>SJ9?ktE*SyPMJ6K35 zzB#HoFg;gM>DtvTFzQ6PhX>yy(S6H`HkdoXu-w>Nf!=hA@++?SMKghjwVv7cVV?)! zW{uwF&a@}E=MBnt`#yd0elXryr4!fvaZ0xGHQZ6aapL7x__)uN$RWDQERqR zK4_ISKl_uwM(Qc(S3aw!dLpOt=oT;uO!QMy*&0eWpF;YPsN=p$lA82ajzPv%OuVA5 zHGs}gWs308QN?`zn7(=li`>p&h56pw9;gv%nVAkbvK0^4cgu97TkKIj5~i6Qj8LYU zm>UJ6h9wX5rC@4(91?>vQdj$KW^^HRRWnjS`u)g!$CU1cb@$n9hIl#;`5NT%ev5LLVj@)Wy zdk_{($@S#NPotyKUOW3svi{uiO$zc%Xgaj2`*G-ePSQ|U@#oOty!yeWN@1$=?^JPi zXQsNDdY0N}IUUsj`k?Ih3zamzeQ?hr?_|S&ygZ1lC+I_l_2FAdB#}Z`)0fs6! zPSt@+~nmF-LEPj7mf*|Y4vf48~?7NOZDoD#f8)xi7fJ1>cBNVzW#s@7!O zNt(d(23pbaDwgEsRxfs(EFMY<4)bi?9DNQboyU>t(T+6qPfVe{KR(yspK#Kv@;KBu zaNfKgbw02WmMywW{_^?G_r_$@9~y_7HL73XAX{|cmAr`?qyN;sXW8LG1utnMp5<4Tr13FfrDC?_cr^iq!> zG(2MrmhiT+QKQvZX+P{@$NHcamCHzl#tEPP1Pefs@2bY)cO`4)io%X|?2Ms!^QySR zciv0v>(#Y08VfXF-9K1?Y*P>A7m(s(lW-aoET|B35XqBe+B`NTOzV^NX9nrxtQGbj zidWJmf<_}#V#DM>1s1u{Qt}|ZqV!qE*qb^_GW0Y~KIa_{OKS8oB`xbP|;;MbB1 zsnbHT$>Z~97qB)7lw&5@bjuxqMFt>K9I@1~e|VHd?FmW?o3{a6+dO_GB2`8i1S*PB z-Y@r_6gsQF+Q+PLpB5i`HT??hZ=%j*>r43-rBt-^J0Yx^DFc7hWT^^$er5Z|nEL#$ z9wP(b=drjF9%2KJk_jmL^~?ORTo%c7rUK+PmI{G-MWTXvr4AI$C~~*QhPTM4l4=>1 zQO)^z_mIQ}vf{?Gd>#(1Ykebgr2tC8VJ-5R19Bvv#c0XDb{nKLSc4L*B;Eof4z9Bl z-z(at2}Yx3RF`HX`Ef_X-ekV*@QWkzJvR75_&gpl&NQ^AKw_mE>u}FiGTp)fi{VKu zK>^8OC>Ey>+x!jN%ij~xjm5mB`%R2bS&zw~5DM_ZRLz^+@F>9Z4@dr{$)sJC+BjV#^y3;!?Lt8lpZ=)Vz|m%Rkv&SslV<{! zM2yN^Q3;DnR;FjYX^Y?+0-QW6Kt*3>>+tFn0F=&eOtlKx^UM7RMrW28FE;5}YnCk- zrpt+jZ*a=^5KsD!ku*~Sg2l5tEI$>BGRT#1JyXu*MoUsJ7__g$B+c?vIj^NP0rN22 z&5U+41AmtH=9?wjGOACS&DpFZD(-25^!8Ba6!~CQGhO>4tK^t22#S1I^Cs--T0O+U zpyK7bF8lc_ZQ^jR3Z;N*UU>$_TcEK}-S%8OmeBzbDJbaT{*9=_Wvo9ovp zB(MW-j7KpN(?;=saEMg;IeXsX+$zxY&*7D)!P~uP-DUZ5I$5*;-WPi&fi$cy?MmcS6ao zLbV1Ej`hNKAHIo5 zjf$(h1fp-SqxHTnIG!4aKCNMU+aG)26@Fs}2yCq|%0Yx$dqejCzl(Gi zNiEHFKO!_%n!`LAy^DG`YASx1X>5RHJ2+?12bLcdn`hReE4#N5V^N_C?=(Zo(Rn4` z0t4(K1Tht=u5DPRxN-wFoR2ifcK5&`lXM#B073?N9Xaeb*QbCPp0VLnMPRidf+w zB!(r$1HgF5RCy#^9t&d)3?Py*!WaSskg6lYFansTfDqww7!_oy91w=V>WE~F&3}mS zzxco1|3jJlw~&VauZ8q~NwCBJb|U|_7cr;e-_Hd=B+S4+MBzUfs6tn&()DyZ}HL2i!&-JZJ4cNmpl_=i)TZzBvUv*upVKv7#~Pyx5;iC{c-l zn+_c|L$W=~#%5Z!Q70SZ7nu81w4Ux+{@1A}tPtB=TEOi*3PSC&CywIR5ap#d^GF4^WE=aj zoNj5(nCU-U2{g0K&by%O)@`*Q!h*kTgpX*eb#=f$mJm}#zE1jgBYR* zIrTerLFPZyMz;rh?ol!cP7B|Gse;4ZyL6n}Vk6|=c7uu&sDqxVQ3NlUw7sp>ZJ?mD z==Mtb;AWV(js_RYk*?4i)_d|E`RyAPy?c8Fk|5XajY$I@25h4v>*5MRSk7T0kVre`abesTooOx_zX=K&|h2mg2< zk5h4o_G>m{Qj4j&xa%o=DF_>7Qk|3n;f6&f!`#rq3_bgjCH2#&Hn|GQv`9>6@ct)y z$hW%(1gUJ`NF_b?w+jZUj-C)xIz1KQ);_NL8-}b~ibqS5@VM+)BSq1m-Zs9(0S#oK ze^@vJ<(>RHvg>_e;fb%vYTR~yF1-;WyW@bn*zjwT+LPOcwgF%F{1;xSnoBV@erc`) zNMGKho@PJ4k&}L71&tQ^{E%hF2_K5-sNMq7w#p5l-v+b+xwZnvU8&@8?06^i5mZ?; zB04q4NU=KoeiPK->WQDusuw)cw?U7_$1NA^RHqkJL>V@C*&lx5gsIKT1#r3e_l z)CbUClGctz;3<$f(#Yd32WJ|O8oSS33v+p52c{xtjV8F^JR?xQxA#aNE~Ab8v6kaY zqPMq~bWQScYA2tkcprD#%M{#k9#WC%Z|g%Wlug2vsp?L<6g4W^W*R3xUw3cnilhAZoAnUQ*Xf>42cN(;T?*mgBe@F=AL(2UATdJaK5v zhW%k7SgR{UlH(QAawL2yfgR(T$2!}fX&Y-|wp`VfQYL}8@|&}8f*|nyNO_`LAgG5> zWSnL)s@lpUvs0$Rr1;z*i5fIRaq~;IH`mYL-W!qw!y*)`*(bD(nOKU@!PE0skq{sl z!RmY*nmo@M-(GqW1AA*bRw>95P5t~}YDn-=8hl!IeG~7EP`(1ol*frDV(ln8-bNa@ znHTl~DD;eqf-f(Yj2ftMe;l^dpGkdfkczWwg`I7P3kWkX4(C-rJwAq16~@GsAl~gJ zD6FugKXR?QO2}srt21<)RFLCsaT5VRQC6%nmDKxu+m#YFkG}fl&$MqDQ-fY?7S@Ca zor@`a)M@(D6D00H7LL+jU6gSMT#5YR@{eD~#0>{F-S9;~XwC~N7 zN798*|h!^pn23qEK|cjFqQA?)D^H{*c@om+KQpVN&wS`>}h5_}8wbw(B% zu{%y)l*OpWgCDSC>36>4HpP0}mL3>_ zKJc8@JpmvBl_gue5mXFccvv)QlxcPe>qM)Hd`FvZffn`TkGle!MeU>b{^2y*nm~LA z$8shGcATQswz+y*PGtYke3C6O*ZB%vdz0z2q+*g)g`J!8rGy1tvWLV1+&>@jp=c8N zm^QkdR+IEl3ujR5U1{9Vx4HU^E%NNoZEnPN@7$2+_A!zVzdc@l!j3p#NN$R8|MMxG zog4UG|AhWdMvtRQ7h4d=dOS=Q9V`4aT~8p_j(ONmlH(Duk2?|j=R*+_OBHPm>PfG` zdY|9hADF6twoB)TW2Dy-k*id)$->&Kx{cMlo*>y0L;vL09YE)2=;h7N+nN6dT%LOm diff --git a/tools/moltemplate/examples/misc_examples/menger_sponge/images/lvl3_LR.jpg b/tools/moltemplate/examples/misc_examples/menger_sponge/images/lvl3_LR.jpg deleted file mode 100644 index a72a1ea8d0e71ccead683b52f85dceb200d58453..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16455 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 diff --git a/tools/moltemplate/examples/misc_examples/menger_sponge/images/menger_sponge_lattice_8cells_t=0_zoom1_LR2.jpg b/tools/moltemplate/examples/misc_examples/menger_sponge/images/menger_sponge_lattice_8cells_t=0_zoom1_LR2.jpg deleted file mode 100644 index 9020a3be0e28a774ca26a22fa4b0daa4e4489a0c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 82092 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

?AKL<(1SsO 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 diff --git a/tools/moltemplate/examples/misc_examples/menger_sponge/moltemplate_files/al_cell.lt b/tools/moltemplate/examples/misc_examples/menger_sponge/moltemplate_files/al_cell.lt deleted file mode 100644 index 3054a45e01..0000000000 --- a/tools/moltemplate/examples/misc_examples/menger_sponge/moltemplate_files/al_cell.lt +++ /dev/null @@ -1,64 +0,0 @@ -# "AlCell" defines the 4-atom FCC unit cell -# of Aluminum (with a 4.05 angstrom spacing) - -AlCell { - - # AtomID MolID(IGNORE!) AtomType Charge X Y Z - - write("Data Atoms") { - $atom:AlC $mol:... @atom:Al 0.0 0.000 0.000 0.000 - $atom:AlX $mol:... @atom:Al 0.0 0.000 2.025 2.025 - $atom:AlY $mol:... @atom:Al 0.0 2.025 0.000 2.025 - $atom:AlZ $mol:... @atom:Al 0.0 2.025 2.025 0.000 - } - - write_once("In Init") { - units metal - atom_style full # <- Requires each atom has a MolID and Charge. - # This is not necessary. (Why use "full"? - # The "full" atom style is useful if you want to - # mix the aluminum with other molecules later. - # Otherwise, just use "atom_style atomic", and - # and remove the 2nd and 4th columns above.) - pair_style eam/alloy - } - - write_once("In Settings") { - pair_coeff * * Al99.eam.alloy Al - } - - write_once("Data Masses") { - @atom:Al 27.0 - } - -} # AlCell - - - - - -# Here is an alternate way to define AlCell -# using "scale(4.05)" to select the lattice spacing: -# -#FccCell { -# write("Data Atoms") { -# $atom:AlC $mol:... @atom:Al 0.0 0.0 0.0 0.0 -# $atom:AlX $mol:... @atom:Al 0.0 0.0 0.5 0.5 -# $atom:AlY $mol:... @atom:Al 0.0 0.5 0.0 0.5 -# $atom:AyZ $mol:... @atom:Al 0.0 0.5 0.5 0.0 -# } -# write_once("Data Masses") { -# @atom:Al 27.0 -# } -# write_once("In Init") { -# units metal -# atom_style full -# pair_style eam/alloy -# } -# write_once("In Settings") { -# pair_coeff * * Al99.eam.alloy Al -# } -#} -# -#AlCell = FccCell.scale(4.05) -# diff --git a/tools/moltemplate/examples/misc_examples/menger_sponge/moltemplate_files/elegant_inefficient_version/al_cell.lt b/tools/moltemplate/examples/misc_examples/menger_sponge/moltemplate_files/elegant_inefficient_version/al_cell.lt deleted file mode 100644 index 3054a45e01..0000000000 --- a/tools/moltemplate/examples/misc_examples/menger_sponge/moltemplate_files/elegant_inefficient_version/al_cell.lt +++ /dev/null @@ -1,64 +0,0 @@ -# "AlCell" defines the 4-atom FCC unit cell -# of Aluminum (with a 4.05 angstrom spacing) - -AlCell { - - # AtomID MolID(IGNORE!) AtomType Charge X Y Z - - write("Data Atoms") { - $atom:AlC $mol:... @atom:Al 0.0 0.000 0.000 0.000 - $atom:AlX $mol:... @atom:Al 0.0 0.000 2.025 2.025 - $atom:AlY $mol:... @atom:Al 0.0 2.025 0.000 2.025 - $atom:AlZ $mol:... @atom:Al 0.0 2.025 2.025 0.000 - } - - write_once("In Init") { - units metal - atom_style full # <- Requires each atom has a MolID and Charge. - # This is not necessary. (Why use "full"? - # The "full" atom style is useful if you want to - # mix the aluminum with other molecules later. - # Otherwise, just use "atom_style atomic", and - # and remove the 2nd and 4th columns above.) - pair_style eam/alloy - } - - write_once("In Settings") { - pair_coeff * * Al99.eam.alloy Al - } - - write_once("Data Masses") { - @atom:Al 27.0 - } - -} # AlCell - - - - - -# Here is an alternate way to define AlCell -# using "scale(4.05)" to select the lattice spacing: -# -#FccCell { -# write("Data Atoms") { -# $atom:AlC $mol:... @atom:Al 0.0 0.0 0.0 0.0 -# $atom:AlX $mol:... @atom:Al 0.0 0.0 0.5 0.5 -# $atom:AlY $mol:... @atom:Al 0.0 0.5 0.0 0.5 -# $atom:AyZ $mol:... @atom:Al 0.0 0.5 0.5 0.0 -# } -# write_once("Data Masses") { -# @atom:Al 27.0 -# } -# write_once("In Init") { -# units metal -# atom_style full -# pair_style eam/alloy -# } -# write_once("In Settings") { -# pair_coeff * * Al99.eam.alloy Al -# } -#} -# -#AlCell = FccCell.scale(4.05) -# diff --git a/tools/moltemplate/examples/misc_examples/menger_sponge/moltemplate_files/elegant_inefficient_version/menger_cubes.lt b/tools/moltemplate/examples/misc_examples/menger_sponge/moltemplate_files/elegant_inefficient_version/menger_cubes.lt deleted file mode 100644 index afafd46e9f..0000000000 --- a/tools/moltemplate/examples/misc_examples/menger_sponge/moltemplate_files/elegant_inefficient_version/menger_cubes.lt +++ /dev/null @@ -1,34 +0,0 @@ -import "al_cell.lt" # <- defines the 4-atom "AlCell" FCC Aluminum unit cell - -# This approach uses the "delete" command. -# It works and it is elegant, but because the majority of atoms will be -# deleted, (and because memory is allocated for all atoms, including -# deleted atoms) this approach is not very memory efficient. - -MengerCubeLvl1 { - cells = new AlCell [3].move(0.00, 0.00, 4.05) - [3].move(0.00, 4.05, 0.00) - [3].move(4.05, 0.00, 0.00) - delete cells[*][1][1] - delete cells[1][*][1] - delete cells[1][1][*] -} - -MengerCubeLvl2 { - cells = new MengerCubeLvl1 [3].move(0.00, 0.00, 12.15) - [3].move(0.00, 12.15, 0.00) - [3].move(12.15, 0.00, 0.00) - delete cells[*][1][1] - delete cells[1][*][1] - delete cells[1][1][*] -} - -MengerCubeLvl3 { - cells = new MengerCubeLvl2 [3].move(0.00, 0.00, 36.45) - [3].move(0.00, 36.45, 0.00) - [3].move(36.45, 0.00, 0.00) - delete cells[*][1][1] - delete cells[1][*][1] - delete cells[1][1][*] -} - diff --git a/tools/moltemplate/examples/misc_examples/menger_sponge/moltemplate_files/elegant_inefficient_version/system.lt b/tools/moltemplate/examples/misc_examples/menger_sponge/moltemplate_files/elegant_inefficient_version/system.lt deleted file mode 100644 index 8da5f2d9c9..0000000000 --- a/tools/moltemplate/examples/misc_examples/menger_sponge/moltemplate_files/elegant_inefficient_version/system.lt +++ /dev/null @@ -1,34 +0,0 @@ -# Periodic boundary conditions: -write_once("Data Boundary") { - 0.0 218.7 xlo xhi - 0.0 218.7 ylo yhi - 0.0 218.7 zlo zhi -} - -import "menger_cubes.lt" - -cube_at_000 = new MengerCubeLvl3.move(0.0000, 0.0000, 0.0000) -cube_at_100 = new MengerCubeLvl3.move(109.35, 0.0000, 0.0000) -cube_at_010 = new MengerCubeLvl3.move(0.0000, 109.35, 0.0000) -cube_at_001 = new MengerCubeLvl3.move(0.0000, 0.0000, 109.35) - - - - - - - - - - - - - - -################################################################ -# The next command is not necessary: -# - create_var { $mol } # <-This forces all of the Al atoms in the crystal -# # to share the same molecule ID number. -# # Molecule ID numbers are not necessary. Ignore this. -# diff --git a/tools/moltemplate/examples/misc_examples/menger_sponge/moltemplate_files/menger_cubes.lt b/tools/moltemplate/examples/misc_examples/menger_sponge/moltemplate_files/menger_cubes.lt deleted file mode 100644 index 0d2922d415..0000000000 --- a/tools/moltemplate/examples/misc_examples/menger_sponge/moltemplate_files/menger_cubes.lt +++ /dev/null @@ -1,66 +0,0 @@ -import "al_cell.lt" # <- defines the 4-atom "AlCell" FCC Aluminum unit cell - -# A Menger cube is a fractal which resembles a 3x3x3 Rubik's-cube. It has a -# cube in each central face (and in the interior) removed. There are 3x3x3-7=20 -# remaining sub-cubes. Each of these 20 sub-cubes is a smaller MengerCube. -# To build a MengerCube, you can list all 20 sub-cubes, or you can fill a -# 3x3x3 cube with sub-cubes and delete the interior sub-cubes. (The later -# approach is used in file "elegant_inefficient_version/menger_cubes.lt") - - - -MengerCubeLvl1 { - # Again, a Menger-cube is constructed of 20 smaller cube-shaped objects. - # Here, the small cube-shaped objects are "AlCells" (defined in "al_cell.lt"). - # I could list out the positions of all 20 AlCells, (and this would be clearer - # for the reader). However instead I built it from a combination of - # two-dimensional and three-dimensional arrays of AlCells (explained below). - - # The next command creates 12 AlCells (2x2x3) at: - # (0.0, 0.0, 0.0), (0.0, 0.0, 4.05), (0.0, 0.0, 8.1) - # (0.0, 8.1, 0.0), (0.0, 8.1, 4.05), (0.0, 8.1, 8.1) - # (8.1, 8.1, 0.0), (8.1, 8.1, 4.05), (8.1, 8.1, 8.1) - - cells_z = new AlCell [2].move(8.10, 0.00, 0.00) - [2].move(0.00, 8.10, 0.00) - [3].move(0.00, 0.00, 4.05) - - # The next command creates 4 AlCells at: (0, 4.05, 0.0), (8.1, 4.05, 0.0), - # (0, 4.05, 8.1), (8.1, 4.05, 8.1) - - cells_xz = new AlCell.move(0.00, 4.05, 0.00) [2].move(8.10, 0.0, 0.0 ) - [2].move(0.0, 0.0, 8.10) - - # The next command creates 4 AlCells at: (4.05, 0, 0.0), (4.05, 8.1, 0.0), - # (4.05, 0, 8.1), (4.05, 8.1, 8.1) - - cells_yz = new AlCell.move(4.05, 0.00, 0.00) [2].move(0.0, 8.10, 0.0 ) - [2].move(0.0, 0.0, 8.10) -} - - - -MengerCubeLvl2 { - # Identical arrangement to MengerCube1 (with 3x larger length scales) - cells_z = new MengerCubeLvl1 [2].move(24.3, 0.00, 0.00) - [2].move(0.00, 24.3, 0.00) - [3].move(0.00, 0.00, 12.15) - cells_xz= new MengerCubeLvl1.move(0.0,12.15,0.0) [2].move(24.3, 0.0, 0.0 ) - [2].move(0.0, 0.0, 24.3) - cells_yz= new MengerCubeLvl1.move(12.15,0.0,0.0) [2].move(0.0, 24.3, 0.0 ) - [2].move(0.0, 0.0, 24.3) -} - - - -MengerCubeLvl3 { - # Identical arrangement to MengerCube2 (with 3x larger length scales) - cells_z = new MengerCubeLvl2 [2].move(72.9, 0.00, 0.00) - [2].move(0.00, 72.9, 0.00) - [3].move(0.00, 0.00, 36.45) - cells_xz= new MengerCubeLvl2.move(0.0,36.45,0.0) [2].move(72.9, 0.0, 0.0 ) - [2].move(0.0, 0.0, 72.9) - cells_yz= new MengerCubeLvl2.move(36.45,0.0,0.0) [2].move(0.0, 72.9, 0.0 ) - [2].move(0.0, 0.0, 72.9) -} - diff --git a/tools/moltemplate/examples/misc_examples/menger_sponge/moltemplate_files/system.lt b/tools/moltemplate/examples/misc_examples/menger_sponge/moltemplate_files/system.lt deleted file mode 100644 index 8da5f2d9c9..0000000000 --- a/tools/moltemplate/examples/misc_examples/menger_sponge/moltemplate_files/system.lt +++ /dev/null @@ -1,34 +0,0 @@ -# Periodic boundary conditions: -write_once("Data Boundary") { - 0.0 218.7 xlo xhi - 0.0 218.7 ylo yhi - 0.0 218.7 zlo zhi -} - -import "menger_cubes.lt" - -cube_at_000 = new MengerCubeLvl3.move(0.0000, 0.0000, 0.0000) -cube_at_100 = new MengerCubeLvl3.move(109.35, 0.0000, 0.0000) -cube_at_010 = new MengerCubeLvl3.move(0.0000, 109.35, 0.0000) -cube_at_001 = new MengerCubeLvl3.move(0.0000, 0.0000, 109.35) - - - - - - - - - - - - - - -################################################################ -# The next command is not necessary: -# - create_var { $mol } # <-This forces all of the Al atoms in the crystal -# # to share the same molecule ID number. -# # Molecule ID numbers are not necessary. Ignore this. -# diff --git a/tools/moltemplate/examples/misc_examples/menger_sponge/run.in b/tools/moltemplate/examples/misc_examples/menger_sponge/run.in deleted file mode 100644 index 6b9ad17e6e..0000000000 --- a/tools/moltemplate/examples/misc_examples/menger_sponge/run.in +++ /dev/null @@ -1,38 +0,0 @@ -# ------------------------------- Initialization Section -------------------- - -include system.in.init - -# ------------------------------- Atom Definition Section ------------------- - -read_data system.data - -# ------------------------------- Settings Section -------------------------- - -include system.in.settings - -# ------------------------------- Run Section ------------------------------- -# -# Some of the run-settings below were stolen from: -# -# http://icme.hpc.msstate.edu/mediawiki/index.php/Uniaxial_Compression - -# EQUILIBRATION -reset_timestep 0 -timestep 0.001 -velocity all create 300 12345 mom yes rot no -fix 1 all npt temp 300 300 1 iso 0 0 1 drag 1 - -# Output files -thermo 100 -thermo_style custom step ke pe press -dump dCoords all custom 100 traj.lammpstrj id type x y z ix iy iz - -run 20000 - -# Run for at least 10 picosecond (assuming 1 fs timestep) -run 10000 - - -###################################### -# SIMULATION DONE -print "All done" diff --git a/tools/moltemplate/examples/misc_examples/pyramids_vs_gravity/README.TXT b/tools/moltemplate/examples/misc_examples/pyramids_vs_gravity/README.TXT deleted file mode 100644 index 68f7c2ab03..0000000000 --- a/tools/moltemplate/examples/misc_examples/pyramids_vs_gravity/README.TXT +++ /dev/null @@ -1,23 +0,0 @@ - Description: - -This is a simulation of pyramid-shaped objects resting on an immobile surface -(resembling graphene). Each pyramid is built from spherical particles stacked -like cannon-balls (or fruit). Ordinarily, the stack does not move -because the particles at the ground layer are immobilized. However, -given an initial (small) perturbation the pyramids collapse in an avalanche. - -(In this example, the perturbation is due to shock because we (intentionally) - did not minimize the system before starting the simulation. This shock - causes an avalanche to begin approximately 5000 timesteps later.) - -The particles roll down the pyramid and bounce off the "ground". The bouncing -is due to a repulsive external force which is added artificially. -(See the "run.in" file.) The simulation looks weird without something -to bounce off of. So I added a graphene surface at the bottom as scenery. -(It does not exert any force on the atoms.) - -(Random comment: This could be a fun example to illustrate the Boltzmann - distribution. Because there is no damping, in a small region, I'm guessing - the particle heights should eventually approach the Boltzmann distribution - for some temperature consistent with the initial potential energy of the - system.) diff --git a/tools/moltemplate/examples/misc_examples/pyramids_vs_gravity/README_VMD_graphene.txt b/tools/moltemplate/examples/misc_examples/pyramids_vs_gravity/README_VMD_graphene.txt deleted file mode 100644 index 096674f7ff..0000000000 --- a/tools/moltemplate/examples/misc_examples/pyramids_vs_gravity/README_VMD_graphene.txt +++ /dev/null @@ -1,28 +0,0 @@ - ------- A note on building the graphene sheet in VMD: ------ - -Probably you can ignore these instructions. -These instructions are not necessary for this example to run. - -This example contains several pyramid shaped objects resting on a surface -made of graphene. The instructions in this file explain how to build the -graphene (representing the "ground") using VMD instead of with moltemplate. - Why do this? -VMD can create graphene sheets with bonds connecting neighboring carbon atoms, -(which looks more pretty). However, as of 2013-4-29, moltemplate currently -can not generate these bonds. It does not matter physically in this case, -because the graphene sheet used here does not move. It is only used as -scenery, to graphically represent the ground surface. - -Select "Extensions"->"Modeling"->"Carbon Nanotube Builder" - Build a graphene sheet of size 39.8 x 39.8 (units: nm) - 400.3358398 399.876008 - (try to use a size compatible with the periodic boundaries) -Select "Extensions"->"Tk Console", and type - display backgroundgradient on - -Note: If you want to do this, before you run moltemplate, you may want to delete - the sections of the "system.lt" file (located in "moltemplate_files") - which define the graphene wall. Instead create the graphene data file - in VMD. You will have to manually merge the data file for graphene - with the data file for the pyramids created by moltemplate, - (taking care to avoid overlapping atom-id numbers). diff --git a/tools/moltemplate/examples/misc_examples/pyramids_vs_gravity/README_setup.sh b/tools/moltemplate/examples/misc_examples/pyramids_vs_gravity/README_setup.sh deleted file mode 100755 index acc5fbbaad..0000000000 --- a/tools/moltemplate/examples/misc_examples/pyramids_vs_gravity/README_setup.sh +++ /dev/null @@ -1,23 +0,0 @@ -# Use these commands to generate the LAMMPS input script and data file -# (and other auxilliary files): - - -# Create LAMMPS input files this way: -cd moltemplate_files - - # run moltemplate - - moltemplate.sh system.lt - - # This will generate various files with names ending in *.in* and *.data. - # These files are the input files directly read by LAMMPS. Move them to - # the parent directory (or wherever you plan to run the simulation). - - mv -f system.in* system.data ../ - - # Optional: - # The "./output_ttree/" directory is full of temporary files generated by - # moltemplate. They can be useful for debugging, but are usually thrown away. - rm -rf output_ttree/ - -cd ../ diff --git a/tools/moltemplate/examples/misc_examples/pyramids_vs_gravity/README_visualize.txt b/tools/moltemplate/examples/misc_examples/pyramids_vs_gravity/README_visualize.txt deleted file mode 100644 index 10198fc92f..0000000000 --- a/tools/moltemplate/examples/misc_examples/pyramids_vs_gravity/README_visualize.txt +++ /dev/null @@ -1,76 +0,0 @@ - ------- To view a lammps trajectory in VMD -------- - - -1) Build a PSF file for use in viewing with VMD. - -This step works with VMD 1.9 and topotools 1.2. -(Older versions, like VMD 1.8.6, don't support this.) - - -a) Start VMD -b) Menu Extensions->Tk Console -c) Enter: - -(I assume that the the DATA file is called "system.data") - - topo readlammpsdata system.data full - animate write psf system.psf - -2) - -Later, to Load a trajectory in VMD: - - Start VMD - Select menu: File->New Molecule - -Browse to select the PSF file you created above, and load it. - (Don't close the window yet.) - -Browse to select the trajectory file. - If necessary, for "file type" select: "LAMMPS Trajectory" - Load it. - - ---- A note on trajectory format: ----- -If the trajectory is a DUMP file, then make sure the it contains the -information you need for pbctools (see below. I've been using this -command in my LAMMPS scripts to create the trajectories: - - dump 1 all custom 5000 DUMP_FILE.lammpstrj id mol type x y z ix iy iz - -It's a good idea to use an atom_style which supports molecule-ID numbers -so that you can assign a molecule-ID number to each atom. (I think this -is needed to wrap atom coordinates without breaking molecules in half.) - -Of course, you don't have to save your trajectories in DUMP format, -(other formats like DCD work fine) I just mention dump files -because these are the files I'm familiar with. - -3) ----- Wrap the coordinates to the unit cell - (without cutting the molecules in half) - -a) Start VMD -b) Load the trajectory in VMD (see above) -c) Menu Extensions->Tk Console -d) Try entering these commands: - - pbc wrap -compound res -all - pbc box - - ----- Optional ---- - To shift the box by a fraction in the x direction (for example) - do this: - - pbc wrap -compound res -all -shiftcenterrel {-0.50 -0.52 0.0 } - pbc box -shiftcenterrel {-0.50 -0.52 0.0 } - - # Alternately if you have a solute whose atoms are all of type 1, - # then you can also try this to center the box around it: - - pbc wrap -sel type=1 -all -centersel type=2 -center com - -4) Optional: If you like, change the atom types in the PSF file so - that VMD recognizes the atom types, use something like: - -sed -e 's/ 1 1 / C C /g' < system.psf > temp1.psf -sed -e 's/ 2 2 / H H /g' < temp1.psf > temp2.psf -sed -e 's/ 3 3 / P P /g' < temp2.psf > system.psf - -(If you do this, it might effect step 2 above.) diff --git a/tools/moltemplate/examples/misc_examples/pyramids_vs_gravity/images/pyramids_vs_gravity_t=04800steps_LR.jpg b/tools/moltemplate/examples/misc_examples/pyramids_vs_gravity/images/pyramids_vs_gravity_t=04800steps_LR.jpg deleted file mode 100644 index dc010258f003bd390276d5c290a9ec9f11d4e3f3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 88094 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 diff --git a/tools/moltemplate/examples/misc_examples/pyramids_vs_gravity/images/pyramids_vs_gravity_t=12200steps_LR.jpg b/tools/moltemplate/examples/misc_examples/pyramids_vs_gravity/images/pyramids_vs_gravity_t=12200steps_LR.jpg deleted file mode 100644 index 53dc98f3e82be2e6dd74b7fefe1ee3cd79d91bdb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 91240 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

    dl2hiYQ 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 diff --git a/tools/moltemplate/examples/misc_examples/pyramids_vs_gravity/moltemplate_files/README.sh b/tools/moltemplate/examples/misc_examples/pyramids_vs_gravity/moltemplate_files/README.sh deleted file mode 100755 index 365ab9fb03..0000000000 --- a/tools/moltemplate/examples/misc_examples/pyramids_vs_gravity/moltemplate_files/README.sh +++ /dev/null @@ -1,15 +0,0 @@ -# This directory contains moltemplate files for the "Pyramids of Giza" example. -# (Note: the ground lattice work that appears in some images was not generated -# by moltemplate. Moltemplate can not currently create bonded periodic -# structures as of 2013-4-04. Those were generated by topotools.) -# -# To run moltemplate, use: - -moltemplate.sh system.lt - -# This will generate:system.data, system.in, system.in.init, system.in.settings -# -# The output_ttree/ directory will contain files like "Data Atoms", "Data Bonds" -# which contain the corresponding structures of the system.data file. -# (This might make it slightly easier to combine them with atom data and -# bond data generated by other programs, such as topotools, for example.) diff --git a/tools/moltemplate/examples/misc_examples/pyramids_vs_gravity/moltemplate_files/graphene.lt b/tools/moltemplate/examples/misc_examples/pyramids_vs_gravity/moltemplate_files/graphene.lt deleted file mode 100644 index 3b3e21333f..0000000000 --- a/tools/moltemplate/examples/misc_examples/pyramids_vs_gravity/moltemplate_files/graphene.lt +++ /dev/null @@ -1,61 +0,0 @@ -# This file contains a unit cell for building graphene and nanotubes -# -# -# The 4AtomRectCellXY "molecule" defined below is a reactangular unit cell -# for hexagonal tesselations in 2-dimensions. (See "graphene_unit_cell.jpg") -# Surfaces constructed with this unit cell can be flat or curved into tubes. -# The distance between nearest-neighbor carbon atoms (ie the length of a -# carbon-carbon bond) is equal to "d" which I set to 1.42 Angstroms. -# -# d = length of each hexagon's side = 1.42 Angstroms -# L = length of each hexagon = 2*d = 2.84 Angstroms -# W = width of each hexagon = 2*d*sqrt(3)/2 = 2.4595121467478056 Angstroms -# 2w = width of hexagon rows = 3*l = 4.26 Angstroms -# -# Consequently, the Lattice-cell vectors for singe-layer graphene are: -# (2.4595121467478, 0, 0) (aligned with X axis) -# (0, 4.26, 0) (aligned with Y axis) -# So, to build a sheet of graphite, you could use: -# sheet = new Graphene/4AtomRectCellXY [10].move(2.4595121467478, 0, 0) -# [10].move(0, 4.26, 0) - - - - -Graphene { - - 4AtomRectCellXY - { - # atomID molID atomType charge x y z - write("Data Atoms") { - $atom:C11 $mol:... @atom:../C 0.0 0.61487803668695 0.71 0.0 - $atom:C21 $mol:... @atom:../C 0.0 1.84463411006085 1.42 0.0 - $atom:C12 $mol:... @atom:../C 0.0 0.61487803668695 3.55 0.0 - $atom:C22 $mol:... @atom:../C 0.0 1.84463411006085 2.84 0.0 - } - } - - # Now define properties of the Carbon graphene atom - - write_once("In Init") { - pair_style hybrid lj/cut 9.0 - } - - write_once("Data Masses") { - @atom:C 12.0 - } - - write_once("In Settings") { - # i j epsilon sigma - pair_coeff @atom:C @atom:C lj/cut 0.068443 3.407 - - # These Lennard-Jones parameters come from - # R. Saito, R. Matsuo, T. Kimura, G. Dresselhaus, M.S. Dresselhaus, - # Chem Phys Lett, 348:187 (2001) - - # Define a group consisting of only carbon atoms in graphene molecules - group gGraphene type @atom:C - } - -} # Graphene - diff --git a/tools/moltemplate/examples/misc_examples/pyramids_vs_gravity/moltemplate_files/graphene_wall.lt b/tools/moltemplate/examples/misc_examples/pyramids_vs_gravity/moltemplate_files/graphene_wall.lt deleted file mode 100644 index 759f0f5d06..0000000000 --- a/tools/moltemplate/examples/misc_examples/pyramids_vs_gravity/moltemplate_files/graphene_wall.lt +++ /dev/null @@ -1,21 +0,0 @@ -import "graphene.lt" - -# -------------- graphene sheet ----------------- - -# Notes: -# Hexagonal lattice with: -# l = length of each hexagonal side = 1.42 Angstroms -# L = length of each hexagon = 2*l = 2.84 Angstroms -# W = width of each hexagon = 2*l*sqrt(3)/2 ~= 2.4595121467478 Angstroms -# 2w = width of hexagon rows = 3.0*l = 4.26 Angstroms - - -GrapheneWall { - - unitcells = new Graphene/4AtomRectCellXY [163].move(2.456, 0, 0) - [94].move(0, 4.254, 0) - - # (Note: I fudged the spacing slightly to make it line up better with the - # lattice spacing for graphene generated by VMD's graphene builder.) -} - diff --git a/tools/moltemplate/examples/misc_examples/pyramids_vs_gravity/moltemplate_files/pyramids.lt b/tools/moltemplate/examples/misc_examples/pyramids_vs_gravity/moltemplate_files/pyramids.lt deleted file mode 100644 index 84c2b6f6d1..0000000000 --- a/tools/moltemplate/examples/misc_examples/pyramids_vs_gravity/moltemplate_files/pyramids.lt +++ /dev/null @@ -1,283 +0,0 @@ -# Brick is a very simple molecule containing one "atom". -# "ImmobileBrick" and "GoldBrick" are identical to "Brick" but are -# given different atom types. (This makes it easier to put them in -# different groups and apply different LAMMPS "fixes" to them.) - -Brick { - - # atomID molID atomType charge x y z - write("Data Atoms") { - $atom $mol @atom 0.0 0.0 0.0 0.0 - } - - write_once("Data Masses") { - @atom 1.0 - } - - write_once("In Settings") { - # U(r) = 4*epsilon_ij*((sigma_ij/r)^12 - (sigma_ij/r)^6) - # - # i j eps sig - pair_coeff @atom @atom lj/cut 1.0 0.8908987181403393 - } - - write_once("In Settings") { - group gMobile type @atom - # (Atoms of this type belong to the "gMobile" group) - } - - write_once("In Init") { - atom_style full - units lj - pair_style lj/cut 1.0 - } -} - - - -#We want to stack "Brick"s the same way a green-grocer sometimes stack apples: -#Place the apples at the base an square lattice of apples at the base. -#The apples in the next layer up are placed in between the 4 apples beneath them. -#Each new layer is smaller and placed above the previous layer at a height -#of sigma / sqrt(2), where "sigma" is the diameter of each spherical "Brick". -#We will artificially hold the apples at the base in place -#(to keep the entire stack from collapsing). -# -# The lines below were generated from the following python loop: -# -#from math import * -#N=50 -#s=1.0 -#for i in range(0,N): -# print(" layer"+str(i)+" = new Brick.move("+str(-(N-(i+1))*s*0.5)+","+ -# str(-(N-(i+1))*s*0.5)+","+str(i*s/sqrt(2))+") ["+str(N-i)+"].move("+ -# str(s)+",0,0) ["+str(N-i)+"].move(0,"+str(s)+",0)") - - -PyramidKhufu { - layer0 = new ImmobileBrick.move(-24.5,-24.5,0.0) [50].move(1.0,0,0) [50].move(0,1.0,0) - layer1 = new Brick.move(-24.0,-24.0,0.707106781187) [49].move(1.0,0,0) [49].move(0,1.0,0) - layer2 = new Brick.move(-23.5,-23.5,1.41421356237) [48].move(1.0,0,0) [48].move(0,1.0,0) - layer3 = new Brick.move(-23.0,-23.0,2.12132034356) [47].move(1.0,0,0) [47].move(0,1.0,0) - layer4 = new Brick.move(-22.5,-22.5,2.82842712475) [46].move(1.0,0,0) [46].move(0,1.0,0) - layer5 = new Brick.move(-22.0,-22.0,3.53553390593) [45].move(1.0,0,0) [45].move(0,1.0,0) - layer6 = new Brick.move(-21.5,-21.5,4.24264068712) [44].move(1.0,0,0) [44].move(0,1.0,0) - layer7 = new Brick.move(-21.0,-21.0,4.94974746831) [43].move(1.0,0,0) [43].move(0,1.0,0) - layer8 = new Brick.move(-20.5,-20.5,5.65685424949) [42].move(1.0,0,0) [42].move(0,1.0,0) - layer9 = new Brick.move(-20.0,-20.0,6.36396103068) [41].move(1.0,0,0) [41].move(0,1.0,0) - layer10 = new Brick.move(-19.5,-19.5,7.07106781187) [40].move(1.0,0,0) [40].move(0,1.0,0) - layer11 = new Brick.move(-19.0,-19.0,7.77817459305) [39].move(1.0,0,0) [39].move(0,1.0,0) - layer12 = new Brick.move(-18.5,-18.5,8.48528137424) [38].move(1.0,0,0) [38].move(0,1.0,0) - layer13 = new Brick.move(-18.0,-18.0,9.19238815543) [37].move(1.0,0,0) [37].move(0,1.0,0) - layer14 = new Brick.move(-17.5,-17.5,9.89949493661) [36].move(1.0,0,0) [36].move(0,1.0,0) - layer15 = new Brick.move(-17.0,-17.0,10.6066017178) [35].move(1.0,0,0) [35].move(0,1.0,0) - layer16 = new Brick.move(-16.5,-16.5,11.313708499) [34].move(1.0,0,0) [34].move(0,1.0,0) - layer17 = new Brick.move(-16.0,-16.0,12.0208152802) [33].move(1.0,0,0) [33].move(0,1.0,0) - layer18 = new Brick.move(-15.5,-15.5,12.7279220614) [32].move(1.0,0,0) [32].move(0,1.0,0) - layer19 = new Brick.move(-15.0,-15.0,13.4350288425) [31].move(1.0,0,0) [31].move(0,1.0,0) - layer20 = new Brick.move(-14.5,-14.5,14.1421356237) [30].move(1.0,0,0) [30].move(0,1.0,0) - layer21 = new Brick.move(-14.0,-14.0,14.8492424049) [29].move(1.0,0,0) [29].move(0,1.0,0) - layer22 = new Brick.move(-13.5,-13.5,15.5563491861) [28].move(1.0,0,0) [28].move(0,1.0,0) - layer23 = new Brick.move(-13.0,-13.0,16.2634559673) [27].move(1.0,0,0) [27].move(0,1.0,0) - layer24 = new Brick.move(-12.5,-12.5,16.9705627485) [26].move(1.0,0,0) [26].move(0,1.0,0) - layer25 = new Brick.move(-12.0,-12.0,17.6776695297) [25].move(1.0,0,0) [25].move(0,1.0,0) - layer26 = new Brick.move(-11.5,-11.5,18.3847763109) [24].move(1.0,0,0) [24].move(0,1.0,0) - layer27 = new Brick.move(-11.0,-11.0,19.091883092) [23].move(1.0,0,0) [23].move(0,1.0,0) - layer28 = new Brick.move(-10.5,-10.5,19.7989898732) [22].move(1.0,0,0) [22].move(0,1.0,0) - layer29 = new Brick.move(-10.0,-10.0,20.5060966544) [21].move(1.0,0,0) [21].move(0,1.0,0) - layer30 = new Brick.move(-9.5,-9.5,21.2132034356) [20].move(1.0,0,0) [20].move(0,1.0,0) - layer31 = new Brick.move(-9.0,-9.0,21.9203102168) [19].move(1.0,0,0) [19].move(0,1.0,0) - layer32 = new Brick.move(-8.5,-8.5,22.627416998) [18].move(1.0,0,0) [18].move(0,1.0,0) - layer33 = new Brick.move(-8.0,-8.0,23.3345237792) [17].move(1.0,0,0) [17].move(0,1.0,0) - layer34 = new Brick.move(-7.5,-7.5,24.0416305603) [16].move(1.0,0,0) [16].move(0,1.0,0) - layer35 = new Brick.move(-7.0,-7.0,24.7487373415) [15].move(1.0,0,0) [15].move(0,1.0,0) - layer36 = new Brick.move(-6.5,-6.5,25.4558441227) [14].move(1.0,0,0) [14].move(0,1.0,0) - layer37 = new Brick.move(-6.0,-6.0,26.1629509039) [13].move(1.0,0,0) [13].move(0,1.0,0) - layer38 = new Brick.move(-5.5,-5.5,26.8700576851) [12].move(1.0,0,0) [12].move(0,1.0,0) - layer39 = new Brick.move(-5.0,-5.0,27.5771644663) [11].move(1.0,0,0) [11].move(0,1.0,0) - layer40 = new GoldBrick.move(-4.5,-4.5,28.2842712475) [10].move(1.0,0,0) [10].move(0,1.0,0) - layer41 = new GoldBrick.move(-4.0,-4.0,28.9913780286) [9].move(1.0,0,0) [9].move(0,1.0,0) - layer42 = new GoldBrick.move(-3.5,-3.5,29.6984848098) [8].move(1.0,0,0) [8].move(0,1.0,0) - layer43 = new GoldBrick.move(-3.0,-3.0,30.405591591) [7].move(1.0,0,0) [7].move(0,1.0,0) - layer44 = new GoldBrick.move(-2.5,-2.5,31.1126983722) [6].move(1.0,0,0) [6].move(0,1.0,0) - layer45 = new GoldBrick.move(-2.0,-2.0,31.8198051534) [5].move(1.0,0,0) [5].move(0,1.0,0) - layer46 = new GoldBrick.move(-1.5,-1.5,32.5269119346) [4].move(1.0,0,0) [4].move(0,1.0,0) - layer47 = new GoldBrick.move(-1.0,-1.0,33.2340187158) [3].move(1.0,0,0) [3].move(0,1.0,0) - layer48 = new GoldBrick.move(-0.5,-0.5,33.941125497) [2].move(1.0,0,0) [2].move(0,1.0,0) - layer49 = new GoldBrick.move(0.0,0.0,34.6482322781) [1].move(1.0,0,0) [1].move(0,1.0,0) -} - - -PyramidKhafre { - layer0 = new ImmobileBrick.move(-23.5,-23.5,0.0) [48].move(1.0,0,0) [48].move(0,1.0,0) - layer1 = new Brick.move(-23.0,-23.0,0.707106781187) [47].move(1.0,0,0) [47].move(0,1.0,0) - layer2 = new Brick.move(-22.5,-22.5,1.41421356237) [46].move(1.0,0,0) [46].move(0,1.0,0) - layer3 = new Brick.move(-22.0,-22.0,2.12132034356) [45].move(1.0,0,0) [45].move(0,1.0,0) - layer4 = new Brick.move(-21.5,-21.5,2.82842712475) [44].move(1.0,0,0) [44].move(0,1.0,0) - layer5 = new Brick.move(-21.0,-21.0,3.53553390593) [43].move(1.0,0,0) [43].move(0,1.0,0) - layer6 = new Brick.move(-20.5,-20.5,4.24264068712) [42].move(1.0,0,0) [42].move(0,1.0,0) - layer7 = new Brick.move(-20.0,-20.0,4.94974746831) [41].move(1.0,0,0) [41].move(0,1.0,0) - layer8 = new Brick.move(-19.5,-19.5,5.65685424949) [40].move(1.0,0,0) [40].move(0,1.0,0) - layer9 = new Brick.move(-19.0,-19.0,6.36396103068) [39].move(1.0,0,0) [39].move(0,1.0,0) - layer10 = new Brick.move(-18.5,-18.5,7.07106781187) [38].move(1.0,0,0) [38].move(0,1.0,0) - layer11 = new Brick.move(-18.0,-18.0,7.77817459305) [37].move(1.0,0,0) [37].move(0,1.0,0) - layer12 = new Brick.move(-17.5,-17.5,8.48528137424) [36].move(1.0,0,0) [36].move(0,1.0,0) - layer13 = new Brick.move(-17.0,-17.0,9.19238815543) [35].move(1.0,0,0) [35].move(0,1.0,0) - layer14 = new Brick.move(-16.5,-16.5,9.89949493661) [34].move(1.0,0,0) [34].move(0,1.0,0) - layer15 = new Brick.move(-16.0,-16.0,10.6066017178) [33].move(1.0,0,0) [33].move(0,1.0,0) - layer16 = new Brick.move(-15.5,-15.5,11.313708499) [32].move(1.0,0,0) [32].move(0,1.0,0) - layer17 = new Brick.move(-15.0,-15.0,12.0208152802) [31].move(1.0,0,0) [31].move(0,1.0,0) - layer18 = new Brick.move(-14.5,-14.5,12.7279220614) [30].move(1.0,0,0) [30].move(0,1.0,0) - layer19 = new Brick.move(-14.0,-14.0,13.4350288425) [29].move(1.0,0,0) [29].move(0,1.0,0) - layer20 = new Brick.move(-13.5,-13.5,14.1421356237) [28].move(1.0,0,0) [28].move(0,1.0,0) - layer21 = new Brick.move(-13.0,-13.0,14.8492424049) [27].move(1.0,0,0) [27].move(0,1.0,0) - layer22 = new Brick.move(-12.5,-12.5,15.5563491861) [26].move(1.0,0,0) [26].move(0,1.0,0) - layer23 = new Brick.move(-12.0,-12.0,16.2634559673) [25].move(1.0,0,0) [25].move(0,1.0,0) - layer24 = new Brick.move(-11.5,-11.5,16.9705627485) [24].move(1.0,0,0) [24].move(0,1.0,0) - layer25 = new Brick.move(-11.0,-11.0,17.6776695297) [23].move(1.0,0,0) [23].move(0,1.0,0) - layer26 = new Brick.move(-10.5,-10.5,18.3847763109) [22].move(1.0,0,0) [22].move(0,1.0,0) - layer27 = new Brick.move(-10.0,-10.0,19.091883092) [21].move(1.0,0,0) [21].move(0,1.0,0) - layer28 = new Brick.move(-9.5,-9.5,19.7989898732) [20].move(1.0,0,0) [20].move(0,1.0,0) - layer29 = new Brick.move(-9.0,-9.0,20.5060966544) [19].move(1.0,0,0) [19].move(0,1.0,0) - layer30 = new Brick.move(-8.5,-8.5,21.2132034356) [18].move(1.0,0,0) [18].move(0,1.0,0) - layer31 = new Brick.move(-8.0,-8.0,21.9203102168) [17].move(1.0,0,0) [17].move(0,1.0,0) - layer32 = new Brick.move(-7.5,-7.5,22.627416998) [16].move(1.0,0,0) [16].move(0,1.0,0) - layer33 = new Brick.move(-7.0,-7.0,23.3345237792) [15].move(1.0,0,0) [15].move(0,1.0,0) - layer34 = new Brick.move(-6.5,-6.5,24.0416305603) [14].move(1.0,0,0) [14].move(0,1.0,0) - layer35 = new GoldBrick.move(-6.0,-6.0,24.7487373415) [13].move(1.0,0,0) [13].move(0,1.0,0) - layer36 = new GoldBrick.move(-5.5,-5.5,25.4558441227) [12].move(1.0,0,0) [12].move(0,1.0,0) - layer37 = new GoldBrick.move(-5.0,-5.0,26.1629509039) [11].move(1.0,0,0) [11].move(0,1.0,0) - layer38 = new GoldBrick.move(-4.5,-4.5,26.8700576851) [10].move(1.0,0,0) [10].move(0,1.0,0) - layer39 = new GoldBrick.move(-4.0,-4.0,27.5771644663) [9].move(1.0,0,0) [9].move(0,1.0,0) - layer40 = new GoldBrick.move(-3.5,-3.5,28.2842712475) [8].move(1.0,0,0) [8].move(0,1.0,0) - layer41 = new GoldBrick.move(-3.0,-3.0,28.9913780286) [7].move(1.0,0,0) [7].move(0,1.0,0) - layer42 = new GoldBrick.move(-2.5,-2.5,29.6984848098) [6].move(1.0,0,0) [6].move(0,1.0,0) - layer43 = new GoldBrick.move(-2.0,-2.0,30.405591591) [5].move(1.0,0,0) [5].move(0,1.0,0) - layer44 = new GoldBrick.move(-1.5,-1.5,31.1126983722) [4].move(1.0,0,0) [4].move(0,1.0,0) - layer45 = new GoldBrick.move(-1.0,-1.0,31.8198051534) [3].move(1.0,0,0) [3].move(0,1.0,0) - layer46 = new GoldBrick.move(-0.5,-0.5,32.5269119346) [2].move(1.0,0,0) [2].move(0,1.0,0) - layer47 = new GoldBrick.move(0.0,0.0,33.2340187158) [1].move(1.0,0,0) [1].move(0,1.0,0) -} - - -PyramidMenkaure { - layer0 = new ImmobileBrick.move(-9.0,-9.0,0.0) [19].move(1.0,0,0) [19].move(0,1.0,0) - layer1 = new Brick.move(-8.5,-8.5,0.707106781187) [18].move(1.0,0,0) [18].move(0,1.0,0) - layer2 = new Brick.move(-8.0,-8.0,1.41421356237) [17].move(1.0,0,0) [17].move(0,1.0,0) - layer3 = new Brick.move(-7.5,-7.5,2.12132034356) [16].move(1.0,0,0) [16].move(0,1.0,0) - layer4 = new Brick.move(-7.0,-7.0,2.82842712475) [15].move(1.0,0,0) [15].move(0,1.0,0) - layer5 = new Brick.move(-6.5,-6.5,3.53553390593) [14].move(1.0,0,0) [14].move(0,1.0,0) - layer6 = new Brick.move(-6.0,-6.0,4.24264068712) [13].move(1.0,0,0) [13].move(0,1.0,0) - layer7 = new Brick.move(-5.5,-5.5,4.94974746831) [12].move(1.0,0,0) [12].move(0,1.0,0) - layer8 = new Brick.move(-5.0,-5.0,5.65685424949) [11].move(1.0,0,0) [11].move(0,1.0,0) - layer9 = new Brick.move(-4.5,-4.5,6.36396103068) [10].move(1.0,0,0) [10].move(0,1.0,0) - layer10 = new Brick.move(-4.0,-4.0,7.07106781187) [9].move(1.0,0,0) [9].move(0,1.0,0) - layer11 = new Brick.move(-3.5,-3.5,7.77817459305) [8].move(1.0,0,0) [8].move(0,1.0,0) - layer12 = new Brick.move(-3.0,-3.0,8.48528137424) [7].move(1.0,0,0) [7].move(0,1.0,0) - layer13 = new Brick.move(-2.5,-2.5,9.19238815543) [6].move(1.0,0,0) [6].move(0,1.0,0) - layer14 = new Brick.move(-2.0,-2.0,9.89949493661) [5].move(1.0,0,0) [5].move(0,1.0,0) - layer15 = new Brick.move(-1.5,-1.5,10.6066017178) [4].move(1.0,0,0) [4].move(0,1.0,0) - layer16 = new Brick.move(-1.0,-1.0,11.313708499) [3].move(1.0,0,0) [3].move(0,1.0,0) - layer17 = new Brick.move(-0.5,-0.5,12.0208152802) [2].move(1.0,0,0) [2].move(0,1.0,0) - layer18 = new Brick.move(0.0,0.0,12.7279220614) [1].move(1.0,0,0) [1].move(0,1.0,0) -} - -PyramidQueens1 { - layer0 = new ImmobileBrick.move(-3.5,-3.5,0.0) [8].move(1.0,0,0) [8].move(0,1.0,0) - layer1 = new ImmobileBrick.move(-3.0,-3.0,0.707106781187) [7].move(1.0,0,0) [7].move(0,1.0,0) - layer2 = new ImmobileBrick.move(-2.0,-2.0,1.707106781187) [5].move(1.0,0,0) [5].move(0,1.0,0) - layer3 = new Brick.move(-1.5,-1.5,2.41421356237) [4].move(1.0,0,0) [4].move(0,1.0,0) - layer4 = new Brick.move(-0.5,-0.5,3.41421356237) [2].move(1.0,0,0) [2].move(0,1.0,0) - layer5 = new Brick.move(0.0,0.0,4.12132034356) [1].move(1.0,0,0) [1].move(0,1.0,0) -} - -PyramidQueens2 { - layer0 = new ImmobileBrick.move(-3.5,-3.5,0.0) [8].move(1.0,0,0) [8].move(0,1.0,0) - layer1 = new ImmobileBrick.move(-3.0,-3.0,0.707106781187) [7].move(1.0,0,0) [7].move(0,1.0,0) - layer2 = new ImmobileBrick.move(-2.0,-2.0,1.707106781187) [5].move(1.0,0,0) [5].move(0,1.0,0) - layer3 = new Brick.move(-1.5,-1.5,2.41421356237) [4].move(1.0,0,0) [4].move(0,1.0,0) - layer4 = new Brick.move(-0.5,-0.5,3.41421356237) [2].move(1.0,0,0) [2].move(0,1.0,0) - layer5 = new Brick.move(0.0,0.0,4.12132034356) [1].move(1.0,0,0) [1].move(0,1.0,0) -} - -PyramidQueens3 { - layer0 = new ImmobileBrick.move(-3.5,-3.5,0.0) [8].move(1.0,0,0) [8].move(0,1.0,0) - layer1 = new Brick.move(-3.0,-3.0,0.707106781187) [7].move(1.0,0,0) [7].move(0,1.0,0) - layer2 = new Brick.move(-2.5,-2.5,1.41421356237) [6].move(1.0,0,0) [6].move(0,1.0,0) - layer3 = new Brick.move(-2.0,-2.0,2.12132034356) [5].move(1.0,0,0) [5].move(0,1.0,0) - layer4 = new Brick.move(-1.5,-1.5,2.82842712475) [4].move(1.0,0,0) [4].move(0,1.0,0) - layer5 = new Brick.move(-1.0,-1.0,3.53553390593) [3].move(1.0,0,0) [3].move(0,1.0,0) - layer6 = new Brick.move(-0.5,-0.5,4.24264068712) [2].move(1.0,0,0) [2].move(0,1.0,0) - layer7 = new Brick.move(0.0,0.0,4.94974746831) [1].move(1.0,0,0) [1].move(0,1.0,0) -} - - - - -# "ImmobileBrick"s are identical to "Brick"s, -# except that they have a different atom type. -# We can define groups based on atom type -# and apply fixes to them. - -ImmobileBrick { - - # atomID molID atomType charge x y z - write("Data Atoms") { - $atom $mol @atom 0.0 0.0 0.0 0.0 - } - - write_once("Data Masses") { - @atom 1.0 - } - - write_once("In Settings") { - # U(r) = 4*epsilon_ij*((sigma_ij/r)^12 - (sigma_ij/r)^6) - # - # i j eps sig - pair_coeff @atom @atom lj/cut 1.0 0.8908987181403393 - } - - write_once("In Settings") { - group gImmobile type @atom - # (Atoms of this type belong to the "gImmobile" group) - } - - write_once("In Init") { - atom_style full - units lj - pair_style hybrid lj/cut 1.0 - } -} - - - -GoldBrick { - - # atomID molID atomType charge x y z - write("Data Atoms") { - $atom $mol @atom 0.0 0.0 0.0 0.0 - } - - write_once("Data Masses") { - @atom 1.0 - } - - write_once("In Settings") { - # U(r) = 4*epsilon_ij*((sigma_ij/r)^12 - (sigma_ij/r)^6) - # - # i j eps sig - pair_coeff @atom @atom lj/cut 1.0 0.8908987181403393 - } - - write_once("In Settings") { - group gMobile type @atom - # (Atoms of this type belong to the "gMobile" group) - } - - write_once("In Init") { - atom_style full - units lj - pair_style lj/cut 1.0 - } -} - diff --git a/tools/moltemplate/examples/misc_examples/pyramids_vs_gravity/moltemplate_files/system.lt b/tools/moltemplate/examples/misc_examples/pyramids_vs_gravity/moltemplate_files/system.lt deleted file mode 100644 index 0c9c50ae9b..0000000000 --- a/tools/moltemplate/examples/misc_examples/pyramids_vs_gravity/moltemplate_files/system.lt +++ /dev/null @@ -1,80 +0,0 @@ -# Description. -# This is a simulation of pyramid-like objects made of particles stacked -# and arranged like cannon-balls, or fruit-stands. Ordinarilly, the stack -# does not collapse because the particles at the ground layer are immobilized. -# However given an initial perterbation the pyramids collapse in an avalanche. -# (This can happen, for example when you do not minimize the system beforehand.) -# The particles roll down the pyramid and bounce off the "ground". The bouncing -# is due to a repulsive external force which is added artificially. -# (See the "run.in" file.) The simulation looks weird without something -# to bounce off of. So I added a graphene surface at the bottom as scenery. -# The ground does not serve any purpose except to look pretty. -# -# (Because there is no damping, I suspect that the distribution of heights of -# the particles in a small area should approach the Boltzmann distribution, -# if you run the simulation long enough.) - - -# ----------------- Pyramids: ----------------- - -import "pyramids.lt" - -# Move the pyramids into their locations in Giza (approximate) - -pyramidKhufu = new PyramidKhufu.move(210, 215, 1) -pyramidKhafre = new PyramidKhafre.move(150, 150, 1) -pyramidMenkaure = new PyramidMenkaure.move(105, 082, 1) -PyramidQueens1 = new PyramidQueens1.move(089, 059, 1) -PyramidQueens2 = new PyramidQueens2.move(100, 059, 1) -PyramidQueens3 = new PyramidQueens3.move(111, 059, 1) - - -# --------------- Scenery: -------------------- - -import "graphene_wall.lt" - -graphene_wall = new GrapheneWall - -write_once("In Settings") { - # Turn off all interactions with the graphene atoms by setting epsilon to 0. - # (We will use a different repulsive barrier to represent the ground instead.) - # These atoms are just "for show". epsilon sigma - pair_coeff @atom:Graphene/C @atom:Graphene/C lj/cut 0.00000 3.407 - - # Optional: Add the graphene atoms to the "gImmobile" group. Later freeze them - group gImmobile type @atom:Graphene/C -} - -# Unfortunately, the ground still looks kind of ugly because moltemplate does -# not yet know how to automatically connect nearby carbon atoms with C-C bonds -# (based on distance). (As of 2013-4-29, moltemplate is not good at -# generating crystalline objects containing explicit bonds.) -# If you want bonds between atoms, use VMD's "carbon-nanotube-builder plugin" -# (which creates data files with bonds) and then merge the two data files -# manually later. (This is not done here.) - - -# -------- override earlier settings ---------- - -write_once("In Init") { - # Override any earlier style settings - atom_style full - units lj - pair_style hybrid lj/cut 1.0 - bond_style none - angle_style none - dihedral_style none - improper_style none - pair_modify mix arithmetic - special_bonds lj 0.0 0.0 0.0 -} - -# ------------ boundary conditions ------------ - -write_once("Data Boundary") { - -1.842033 398.493813 xlo xhi - -0.708994 399.167013 ylo yhi - 0.0 400.0 zlo zhi -} -# --------------------------------------------- - diff --git a/tools/moltemplate/examples/misc_examples/pyramids_vs_gravity/run.in b/tools/moltemplate/examples/misc_examples/pyramids_vs_gravity/run.in deleted file mode 100644 index a99dfda28f..0000000000 --- a/tools/moltemplate/examples/misc_examples/pyramids_vs_gravity/run.in +++ /dev/null @@ -1,68 +0,0 @@ -# -- Init Section -- - -include system.in.init -boundary p p f - -# -- Atom Definition Section -- - -read_data system.data - -# -- Settings Section -- - -include system.in.settings - -# -- Run Section -- - - -timestep 0.0025 -dump 1 all custom 200 traj.lammpstrj id mol type x y z ix iy iz - -thermo_style custom step temp pe etotal -thermo 100 # time interval for printing out "thermo" data - -# ---- Set up the physical environment ---- - -# Add gravity: -fix fxGrav gMobile gravity 0.05 vector 0 0 -1 - -# Create a "ground" surface. -# This is a repulsive "wall" which particles can bounce off of: - -fix fxWall gMobile wall/lj126 zlo EDGE 1.0 0.8908987181403393 1.0 - - -# ---- Evolve the system: ---- - -# Evolve the (mobile) atoms using ordinary Newton's laws (NVE) - -fix fxNVE gMobile nve - - -# IF YOU WANT TO ADD DAMPING, THEN UNCOMMENT THE NEXT LINE: -#fix fxLan gMobile langevin 0.001 0.001 10000.0 48279 -# To use Langevin dynamics in LAMMPS you need both "fix langevin" and "fix nve" -# (See http://lammps.sandia.gov/doc/fix_langevin.html for details.) -# This was not tested. - -# OPTIONAL: -# For efficient simulation in parallel, try using "fix balance": -# (This will adjust the spatial decomposition as the distribution of -# particles changes over time.) -# http://lammps.sandia.gov/doc/fix_balance.html -# fix fxBalance gMobile balance 1000 1.1 shift 1000 xy 20 1.1 -# Alternatiely, try this: -#fix fxBalance gMobile balance 1000 1.2 rcb - - -# OPTIONAL: Improve efficiency by omitting the calcuation of interactions -# between immobile atoms: - -neigh_modify exclude group gImmobile gImmobile - - -restart 50000 restart_nvt - -run 200000 - -write_data system_after_nvt.data - diff --git a/tools/moltemplate/moltemplate_manual.pdf b/tools/moltemplate/moltemplate_manual.pdf deleted file mode 100644 index 14246f1559ec6088013e94c4bed4f9040bdc66b5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 716411 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

    S!QPZO(9glMOFLNQDY_pB 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 z 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 z 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%0Aa54LsP2ClNa`0`5tfGrd15 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 diff --git a/tools/moltemplate/src/bonds_by_type.py b/tools/moltemplate/src/bonds_by_type.py deleted file mode 100644 index 919cfa51af..0000000000 --- a/tools/moltemplate/src/bonds_by_type.py +++ /dev/null @@ -1,370 +0,0 @@ -#!/usr/bin/env python - -# Author: Andrew Jewett (jewett.aij at g mail) -# http://www.chem.ucsb.edu/~sheagroup -# License: 3-clause BSD License (See LICENSE.TXT) -# Copyright (c) 2011, Regents of the University of California -# All rights reserved. - -""" - bonds_by_type.py reads a LAMMPS data file (or an excerpt of a LAMMPS) - data file containing bonded many-body interactions by atom type - (and bond type), and generates a list of additional interactions - in LAMMPS format consistent with those type (to the standard out). - - Typical Usage: - - bonds_by_type.py -atoms atoms.data \\ - -bonds bonds.data \\ - -bondsbytype bonds_by_type.data \\ - > new_bonds.data - -""" - -# -bonds-ids-atom-pairs bonds_ids_atom_pairs.data \\ - -import sys -#from extract_lammps_data import * -#from nbody_by_type_lib import GenInteractions_str -import ttree_lex -#from ttree_lex import * -from lttree_styles import AtomStyle2ColNames, ColNames2AidAtypeMolid - - - -def LookupBondTypes(bond_types, - bond_ids, - bond_pairs, - lines_atoms, - lines_bonds, - lines_bondsbytype, - atom_style, - section_name, - prefix='', - suffix='', - bond_ids_offset=0): - #report_progress = False): - """ - LookupBondTypes() looks up bond types. - - Output: - ...It looks up the corresponding type of each bond and store it in the - "bond_types" list. (If the bond_ids were not specified by the user, - generate them and store them in the bond_ids list.) - - - Input (continued): - This function requires: - ...a list of bonded pairs of atoms - stored in the lines_bonds variable (from the "Data Bond List" - or "Data Bonds AtomId AtomId" sections) - ...and a list of atom types - stored in the lines_atoms variable (from the "Data Atoms" section) - ...and a list of bond-types-as-a-function-of-atom-types - stored in the lines_bondsbytype (from the "Data Bonds By Type" section) - - Generated bond_ids (if applicable) are of the form - prefix + str(number) + suffix - (where "number" begins at bond_ids_offset+1) - - """ - - column_names = AtomStyle2ColNames(atom_style) - i_atomid, i_atomtype, i_molid = ColNames2AidAtypeMolid(column_names) - - atomids = [] - atomtypes = [] - atomids2types = {} - - for iv in range(0, len(lines_atoms)): - line = lines_atoms[iv].strip() - if '#' in line: - icomment = line.find('#') - line = (line[:icomment]).strip() - if len(line) > 0: - tokens = ttree_lex.SplitQuotedString(line) - if ((len(tokens) <= i_atomid) or (len(tokens) <= i_atomtype)): - sys.stderr.write("\""+line+"\"\n") - raise(ttree_lex.InputError('Error not enough columns on line '+str(iv+1)+' of \"Atoms\" section.')) - tokens = ttree_lex.SplitQuotedString(line) - atomid = ttree_lex.EscCharStrToChar(tokens[i_atomid]) - atomids.append(atomid) - atomtype = ttree_lex.EscCharStrToChar(tokens[i_atomtype]) - atomtypes.append(atomtype) - atomids2types[atomid] = atomtype - - - assert(isinstance(bond_ids, list)) - assert(isinstance(bond_types, list)) - assert(isinstance(bond_pairs, list)) - del bond_ids[:] - del bond_types[:] - del bond_pairs[:] - - for ie in range(0, len(lines_bonds)): - - line = lines_bonds[ie].strip() - if '#' in line: - icomment = line.find('#') - line = (line[:icomment]).strip() - - if len(line) == 0: - continue - - tokens = ttree_lex.SplitQuotedString(line) - - if section_name == "Data Bonds AtomId AtomId": - if len(tokens) == 2: - bondid_n = bond_ids_offset + len(bond_ids) + 1 - bond_ids.append(prefix+str(bondid_n)+suffix) - bond_pairs.append( (ttree_lex.EscCharStrToChar(tokens[0]), - ttree_lex.EscCharStrToChar(tokens[1])) ) - else: - raise(ttree_lex.InputError('Incorrect number of columns on line '+str(ie+1)+' of \"'+section_name+'\" section.')) - - elif section_name == "Data Bond List": - if len(tokens) == 3: - bond_ids.append(ttree_lex.EscCharStrToChar(tokens[0])) - bond_pairs.append( (ttree_lex.EscCharStrToChar(tokens[1]), - ttree_lex.EscCharStrToChar(tokens[2])) ) - else: - raise(ttree_lex.InputError('Incorrect number of columns on line '+str(ie+1)+' of \"'+section_name+'\" section.')) - - else: - raise(ttree_lex.InputError('Internal Error ('+g_program_name+'): Unknown section name: \"'+section_name+'\"')) - - - assert(len(bond_types) == 0) - typepattern_to_coefftypes = [] - - for i in range(0, len(lines_bondsbytype)): - line = lines_bondsbytype[i].strip() - if '#' in line: - icomment = line.find('#') - line = (line[:icomment]).strip() - if len(line) > 0: - tokens = ttree_lex.SplitQuotedString(line) - - if (len(tokens) != 3): - raise(ttree_lex.InputError('Error: Wrong number of columns in the \"Bonds By Type\" section of data file.\n' - 'Offending line:\n'+ - '\"'+line+'\"\n' - 'Expected 3 columns\n')) - - coefftype = ttree_lex.EscCharStrToChar(tokens[0]) - typepattern = [] - - for typestr in tokens[1:]: - if ((len(typestr) >= 2) and - (typestr[0] == '/') and (typestr[-1] == '/')): - regex_str = typestr[1:-1] - typepattern.append( re.compile(regex_str) ) - else: - typepattern.append(ttree_lex.EscCharStrToChar(typestr)) - - typepattern_to_coefftypes.append([typepattern, coefftype]) - - - - assert(len(bond_ids) == len(bond_pairs)) - - for ie in range(0,len(bond_ids)): - bond_types.append(None) - - for ie in range(0, len(bond_ids)): - bondid = bond_ids[ie] - (atomid1, atomid2) = bond_pairs[ie] - - if atomid1 not in atomids2types: - raise ttree_lex.InputError('Error: atom \"'+atomid1+'\" not defined in \"Data Atoms\".\n' - ' This usually happens when the user mistypes one of the names of the\n' - ' $atoms in either a \"Data Atoms\" or \"Data Bond List\" section.\n' - ' To find out where the mistake occured, search the \n' - ' \"ttree_assignments.txt\" file for:\n' - ' \"'+atomid1+'\"\n') - - if atomid2 not in atomids2types: - raise ttree_lex.InputError('Error: atom \"'+atomid2+'\" not defined in \"Data Atoms\".\n' - ' This usually happens when the user mistypes one of the names of the\n' - ' $atoms in either a \"Data Atoms\" or \"Data Bond List\" section.\n' - ' To find out where the mistake occured, search the \n' - ' \"ttree_assignments.txt\" file for:\n' - ' \"'+atomid2+'\"\n') - - atomtype1 = atomids2types[atomid1] - atomtype2 = atomids2types[atomid2] - - for typepattern, coefftype in typepattern_to_coefftypes: - - # use string comparisons to check if atom types match the pattern - if (ttree_lex.MatchesAll((atomtype1, atomtype2), typepattern) or - ttree_lex.MatchesAll((atomtype2, atomtype1), typepattern)): - # ("MatchesAll()" defined in "ttree_lex.py") - - bond_types[ie] = coefftype - - for ie in range(0, len(bond_ids)): - if not bond_types[ie]: - (atomid1, atomid2) = bond_pairs[ie] - atomtype1 = atomids2types[atomid1] - atomtype2 = atomids2types[atomid2] - raise ttree_lex.InputError('Error: No bond types defined for the bond between\n' - ' atoms '+atomid1+' (type '+atomtype1+')\n' - ' and '+atomid2+' (type '+atomtype2+')\n') - - - - -if __name__ == "__main__": - - g_program_name = __file__.split('/')[-1] # = 'nbody_by_type.py' - g_date_str = '2015-11-09' - g_version_str = '0.11' - - ####### Main Code Below: ####### - sys.stderr.write(g_program_name+' v'+g_version_str+' '+g_date_str+' ') - if sys.version < '3': - sys.stderr.write(' (python version < 3)\n') - else: - sys.stderr.write('\n') - - try: - fname_atoms = None - fname_bond_list = None - fname_bondsbytype = None - section_name = 'Data Bond List' # (This will be replaced later.) - atom_style = 'full' - prefix='' - suffix='' - bond_lack_types = False - - argv = [arg for arg in sys.argv] - - - # Loop over the remaining arguments not processed yet. - # These arguments are specific to the lttree.py program - # and are not understood by ttree.py: - i = 1 - while i < len(argv): - #sys.stderr.write('argv['+str(i)+'] = \"'+argv[i]+'\"\n') - if ((argv[i].lower() == '-?') or - (argv[i].lower() == '--?') or - (argv[i].lower() == '-help') or - (argv[i].lower() == '-help')): - if i+1 >= len(argv): - sys.stdout.write(man_page_text+'\n') - sys.exit(0) - - elif argv[i].lower() == '-atoms': - if i+1 >= len(argv): - raise ttree_lex.InputError('Error: '+argv[i]+' flag should be followed by a file name containing lines of\n' - ' text which might appear in the "Atoms" section of a LAMMPS data file.\n') - fname_atoms = argv[i+1] - del(argv[i:i+2]) - - elif argv[i].lower() == '-bonds': - if i+1 >= len(argv): - raise ttree_lex.InputError('Error: '+argv[i]+' flag should be followed by a file name containing lines of\n' - ' text which might appear in the "Bonds" section of a LAMMPS data file.\n') - fname_bond_list = argv[i+1] - del(argv[i:i+2]) - - elif argv[i].lower() == '-bond-list': - if i+1 >= len(argv): - raise ttree_lex.InputError('Error: '+argv[i]+' flag should be followed by a file name\n') - #raise ttree_lex.InputError('Error: '+argv[i]+' flag should be followed by a file name containing lines of\n' - # ' text which might appear in the "Bonds No Types" section of a LAMMPS data file.\n') - fname_bond_list = argv[i+1] - section_name = "Data Bond List" - del(argv[i:i+2]) - - elif argv[i].lower() == '-bondsbytype': - if i+1 >= len(argv): - raise ttree_lex.InputError('Error: '+argv[i]+' flag should be followed by a file name\n') - - #raise ttree_lex.InputError('Error: '+argv[i]+' flag should be followed by a file name containing\n' - # ' text which might appear in the "'+section_name+' By Type" section\n' - # ' of a LAMMPS data file.\n') - fname_bondsbytype = argv[i+1] - del(argv[i:i+2]) - - elif ((argv[i].lower() == '-atom-style') or - (argv[i].lower() == '-atom_style')): - if i+1 >= len(argv): - raise ttree_lex.InputError('Error: '+argv[i]+' flag should be followed by a an atom_style name.\n' - ' (Or single quoted string which includes a space-separated\n' - ' list of column names.)\n') - atom_style = argv[i+1] - del(argv[i:i+2]) - - elif argv[i].lower() == '-prefix': - if i+1 >= len(argv): - raise ttree_lex.InputError('Error: '+argv[i]+' flag should be followed by a prefix string\n' - ' (a string you want to appear to the left of the integer\n' - ' which counts the bonded interactions you have generated.)\n') - prefix = argv[i+1] - del(argv[i:i+2]) - - elif argv[i].lower() == '-suffix': - if i+1 >= len(argv): - raise ttree_lex.InputError('Error: '+argv[i]+' flag should be followed by a suffix string\n' - ' (a string you want to appear to the right of the integer\n' - ' which counts the bonded interactions you have generated.)\n') - prefix = argv[i+1] - del(argv[i:i+2]) - - elif argv[i][0] == '-': - raise ttree_lex.InputError('Error('+g_program_name+'):\n' - 'Unrecognized command line argument \"'+argv[i]+'\"\n') - else: - i += 1 - - if len(argv) != 1: - # if there are more than 2 remaining arguments, - problem_args = ['\"'+arg+'\"' for arg in argv[1:]] - raise ttree_lex.InputError('Syntax Error('+g_program_name+'):\n\n' - ' Problem with argument list.\n' - ' The remaining arguments are:\n\n' - ' '+(' '.join(problem_args))+'\n\n' - ' (The actual problem may be earlier in the argument list.)\n') - - bond_types = [] - bond_ids = [] - bond_pairs = [] - - fatoms = open(fname_atoms, 'r') - fbonds = open(fname_bond_list, 'r') - fbondsbytype = open(fname_bondsbytype, 'r') - lines_atoms = fatoms.readlines() - lines_bonds = fbonds.readlines() - lines_bondsbytype = fbondsbytype.readlines() - fatoms.close() - fbonds.close() - fbondsbytype.close() - - LookupBondTypes(bond_types, - bond_ids, - bond_pairs, - lines_atoms, - lines_bonds, - lines_bondsbytype, - atom_style, - section_name, - prefix='', - suffix='') - - assert(len(bond_types) == len(bond_ids) == len(bond_pairs)) - - ie=0 - N = len(bond_types) - for ie in range(0, N): - sys.stdout.write(bond_ids[ie] + ' ' + - bond_types[ie] + ' ' + - bond_pairs[ie][0] + ' ' + - bond_pairs[ie][1] + '\n') - - - except (ValueError, ttree_lex.InputError) as err: - sys.stderr.write('\n'+str(err)+'\n') - sys.exit(-1) - diff --git a/tools/moltemplate/src/chargepairs_by_type.py b/tools/moltemplate/src/chargepairs_by_type.py deleted file mode 100644 index 3de8131141..0000000000 --- a/tools/moltemplate/src/chargepairs_by_type.py +++ /dev/null @@ -1,389 +0,0 @@ -#!/usr/bin/env python - -# Author: Andrew Jewett (jewett.aij at g mail) -# http://www.chem.ucsb.edu/~sheagroup -# License: 3-clause BSD License (See LICENSE.TXT) -# Copyright (c) 2011, Regents of the University of California -# All rights reserved. - -""" - chargepairs_by_type.py reads a LAMMPS data file (or an excerpt of a LAMMPS) - data file containing bonded many-body interactions by atom type - (and bond type), and generates a list of atom charges in LAMMPS input - script format consistent with those types (to the standard out). - - Typical Usage: - - chargepairs_by_type.py -atoms atoms.data \\ - -bonds bonds.data \\ - -chargepairsbytype chargepairs_by_type.data \\ - > list_of_atom_charges.in - -""" - -# -bonds-ids-atom-pairs bonds_ids_atom_pairs.data \\ - -import sys -from collections import defaultdict -#from extract_lammps_data import * -#from nbody_by_type_lib import GenInteractions_str -import ttree_lex -#from ttree_lex import * -from lttree_styles import AtomStyle2ColNames, ColNames2AidAtypeMolid - - - -def LookupChargePairs(chargebyatomid, - #bond_ids, - #bond_pairs, - lines_atoms, - lines_bonds, - lines_bond_list, - lines_chargepairsbytype, - atom_style, - section_name, - prefix='', - suffix=''): - #bond_ids_offset=0): - #report_progress = False): - """ - LookupChargePairs() looks up partial-charge pair contributions from the - types of atoms participating in a bond. - - Output: - ...It looks up the corresponding change in the partial charges for - each pair of atoms and stores this in the "chargebyatomid" dictionary. - - Input (continued): - This function requires: - ...a list of bonded pairs of atoms - stored in the lines_bonds variable (from the "Data Bond List" - or "Data Bonds AtomId AtomId" sections) - ...and a list of atom types - stored in the lines_atoms variable (from the "Data Atoms" section) - - ...and a list of charge-pairs-as-a-function-of-atom-types - stored in the lines_chargepairsbytype (from the "Data Bonds By Type" section) - - """ - - column_names = AtomStyle2ColNames(atom_style) - i_atomid, i_atomtype, i_molid = ColNames2AidAtypeMolid(column_names) - - atomids = [] - atomtypes = [] - atomids2types = {} - - for iv in range(0, len(lines_atoms)): - line = lines_atoms[iv].strip() - if '#' in line: - icomment = line.find('#') - line = (line[:icomment]).strip() - if len(line) > 0: - tokens = ttree_lex.SplitQuotedString(line) - if ((len(tokens) <= i_atomid) or (len(tokens) <= i_atomtype)): - sys.stderr.write("\""+line+"\"\n") - raise(ttree_lex.InputError('Error not enough columns on line '+str(iv+1)+' of \"Atoms\" section.')) - tokens = ttree_lex.SplitQuotedString(line) - atomid = ttree_lex.EscCharStrToChar(tokens[i_atomid]) - atomids.append(atomid) - atomtype = ttree_lex.EscCharStrToChar(tokens[i_atomtype]) - atomtypes.append(atomtype) - atomids2types[atomid] = atomtype - - - #assert(isinstance(bond_ids, list)) - #assert(isinstance(bond_types, list)) - #assert(isinstance(bond_pairs, list)) - #del bond_ids[:] - #del bond_types[:] - #del bond_pairs[:] - bond_pairs = [] - - for ie in range(0, len(lines_bond_list)): - line = lines_bond_list[ie].strip() - if '#' in line: - icomment = line.find('#') - line = (line[:icomment]).strip() - if len(line) == 0: - continue - tokens = ttree_lex.SplitQuotedString(line) - if len(tokens) == 3: - #bond_ids.append(ttree_lex.EscCharStrToChar(tokens[0])) - bond_pairs.append( (ttree_lex.EscCharStrToChar(tokens[1]), - ttree_lex.EscCharStrToChar(tokens[2])) ) - else: - raise(ttree_lex.InputError('Incorrect number of columns on line '+str(ie+1)+' of \"'+section_name+'\" section.')) - - - for ie in range(0, len(lines_bonds)): - line = lines_bonds[ie].strip() - if '#' in line: - icomment = line.find('#') - line = (line[:icomment]).strip() - if len(line) == 0: - continue - tokens = ttree_lex.SplitQuotedString(line) - if len(tokens) == 4: - #bond_ids.append(ttree_lex.EscCharStrToChar(tokens[0])) - #bond_types.append(ttree_lex.EscCharStrToChar(tokens[1])) - bond_pairs.append( (ttree_lex.EscCharStrToChar(tokens[2]), - ttree_lex.EscCharStrToChar(tokens[3])) ) - else: - raise(ttree_lex.InputError('Incorrect number of columns on line '+str(ie+1)+' of \"'+section_name+'\" section.')) - - - - #for ie in range(0, len(lines_bonds_atomid_atomid)): - # line = lines_bonds_atomid_atomid[ie].strip() - # if '#' in line: - # icomment = line.find('#') - # line = (line[:icomment]).strip() - # if len(line) == 0: - # continue - # tokens = ttree_lex.SplitQuotedString(line) - # if len(tokens) == 2: - # #bondid_n = bond_ids_offset + len(bond_ids) + 1 - # #bond_ids.append(prefix+str(bondid_n)+suffix) - # bond_pairs.append( (ttree_lex.EscCharStrToChar(tokens[0]), - # ttree_lex.EscCharStrToChar(tokens[1])) ) - # else: - # raise(ttree_lex.InputError('Incorrect number of columns on line '+str(ie+1)+' of \"'+section_name+'\" section.')) - - - - assert(len(bond_types) == 0) - typepattern_to_chargepairs = [] - warning_unassigned_chargepairs = None - - for i in range(0, len(lines_chargepairsbytype)): - line = lines_chargepairsbytype[i].strip() - if '#' in line: - icomment = line.find('#') - line = (line[:icomment]).strip() - if len(line) > 0: - tokens = ttree_lex.SplitQuotedString(line) - - if (len(tokens) != 4): - raise(ttree_lex.InputError('Error: Wrong number of columns in the \"Charge Pairs By Type\" section of data file.\n' - 'Offending line:\n'+ - '\"'+line+'\"\n' - 'Expected 4 columns\n')) - - chargepair = (float(tokens[2]), - float(tokens[3])) - - typepattern = [] - - for typestr in tokens[:2]: - if ((len(typestr) >= 2) and - (typestr[0] == '/') and (typestr[-1] == '/')): - regex_str = typestr[1:-1] - typepattern.append( re.compile(regex_str) ) - else: - typepattern.append(ttree_lex.EscCharStrToChar(typestr)) - - typepattern_to_chargepairs.append([typepattern, chargepair]) - - - for atomid1, atomid2 in bond_pairs: - - if atomid1 not in atomids2types: - raise ttree_lex.InputError('Error: atom \"'+atomid1+'\" not defined in \"Data Atoms\".\n' - ' This usually happens when the user mistypes one of the names of the\n' - ' $atoms in either a \"Data Atoms\" or \"Data Bond List\" section.\n' - ' To find out where the mistake occured, search the \n' - ' \"ttree_assignments.txt\" file for:\n' - ' \"'+atomid1+'\"\n') - - if atomid2 not in atomids2types: - raise ttree_lex.InputError('Error: atom \"'+atomid2+'\" not defined in \"Data Atoms\".\n' - ' This usually happens when the user mistypes one of the names of the\n' - ' $atoms in either a \"Data Atoms\" or \"Data Bond List\" section.\n' - ' To find out where the mistake occured, search the \n' - ' \"ttree_assignments.txt\" file for:\n' - ' \"'+atomid2+'\"\n') - - - atomtype1 = atomids2types[atomid1] - atomtype2 = atomids2types[atomid2] - - for typepattern, chargepair in typepattern_to_chargepairs: - # use string comparisons to check if atom types match the pattern - if ttree_lex.MatchesAll((atomtype1, atomtype2), typepattern): - # ("MatchesAll()" defined in "ttree_lex.py") - chargebyatomid[atomid1] += chargepair[0] - chargebyatomid[atomid2] += chargepair[1] - elif ttree_lex.MatchesAll((atomtype2, atomtype1), typepattern): - chargebyatomid[atomid1] += chargepair[1] - chargebyatomid[atomid2] += chargepair[0] - else: - if not warning_unassigned_chargepairs: - warning_unassigned_chargepairs = (atomid1, atomid2) - - - if warning_unassigned_chargepairs: - sys.stderr.write('---------------------------------------------------------------------------\n' - 'Warning: bonds found between atoms with no partial-charge rules.\n' - ' This means that somewhere you are using a force-field\n' - ' which assigns atomic charge according to the bonds these atoms\n' - ' participate in, AND at least one pair of bonded atoms does NOT have\n' - ' a rule defined to assign charges to that pair of atoms.\n' - ' This can happen if there is a problem with the force-field file\n' - ' OR if you are defining the charges for these atoms manually\n' - ' In the later case, it is not a problem.\n' - ' The first bond with this problem is between this pair of atoms:\n' - ' '+str(warning_unassigned_chargepairs[0])+'\n' - ' '+str(warning_unassigned_chargepairs[1])+'\n' - '---------------------------------------------------------------------------\n') - - - - - -if __name__ == "__main__": - - g_program_name = __file__.split('/')[-1] # = 'nbody_by_type.py' - g_date_str = '2016-10-16' - g_version_str = '0.11' - - ####### Main Code Below: ####### - sys.stderr.write(g_program_name+' v'+g_version_str+' '+g_date_str+' ') - if sys.version < '3': - sys.stderr.write(' (python version < 3)\n') - else: - sys.stderr.write('\n') - - try: - fname_atoms = None - fname_bonds = None - fname_bond_list = None - fname_chargepairsbytype = None - section_name = 'Data Bond List' # (This will be replaced later.) - atom_style = 'full' - prefix='' - suffix='' - bond_lack_types = False - - argv = [arg for arg in sys.argv] - - - # Loop over the remaining arguments not processed yet. - # These arguments are specific to the lttree.py program - # and are not understood by ttree.py: - i = 1 - while i < len(argv): - #sys.stderr.write('argv['+str(i)+'] = \"'+argv[i]+'\"\n') - if ((argv[i].lower() == '-?') or - (argv[i].lower() == '--?') or - (argv[i].lower() == '-help') or - (argv[i].lower() == '-help')): - if i+1 >= len(argv): - sys.stdout.write(man_page_text+'\n') - sys.exit(0) - - elif argv[i].lower() == '-atoms': - if i+1 >= len(argv): - raise ttree_lex.InputError('Error: '+argv[i]+' flag should be followed by a file name containing lines of\n' - ' text which might appear in the "Atoms" section of a LAMMPS data file.\n') - fname_atoms = argv[i+1] - del(argv[i:i+2]) - - elif argv[i].lower() == '-bonds': - if i+1 >= len(argv): - raise ttree_lex.InputError('Error: '+argv[i]+' flag should be followed by a file name containing lines of\n' - ' text which might appear in the "Bonds" section of a LAMMPS data file.\n') - fname_bonds = argv[i+1] - del(argv[i:i+2]) - - elif argv[i].lower() == '-bond-list': - if i+1 >= len(argv): - raise ttree_lex.InputError('Error: '+argv[i]+' flag should be followed by a file name\n') - #raise ttree_lex.InputError('Error: '+argv[i]+' flag should be followed by a file name containing lines of\n' - # ' text which might appear in the "Bonds No Types" section of a LAMMPS data file.\n') - fname_bond_list = argv[i+1] - section_name = "Data Bond List" - del(argv[i:i+2]) - - elif ((argv[i].lower() == '-chargepairsbytype') or - (argv[i].lower() == '-chargepairs-by-type') or - (argv[i].lower() == '-charge-pairs-by-type')): - if i+1 >= len(argv): - raise ttree_lex.InputError('Error: '+argv[i]+' flag should be followed by a file name\n') - - #raise ttree_lex.InputError('Error: '+argv[i]+' flag should be followed by a file name containing\n' - # ' text which might appear in the "'+section_name+' By Type" section\n' - # ' of a LAMMPS data file.\n') - fname_chargepairsbytype = argv[i+1] - del(argv[i:i+2]) - - elif ((argv[i].lower() == '-atom-style') or - (argv[i].lower() == '-atom_style')): - if i+1 >= len(argv): - raise ttree_lex.InputError('Error: '+argv[i]+' flag should be followed by a an atom_style name.\n' - ' (Or single quoted string which includes a space-separated\n' - ' list of column names.)\n') - atom_style = argv[i+1] - del(argv[i:i+2]) - - elif argv[i][0] == '-': - raise ttree_lex.InputError('Error('+g_program_name+'):\n' - 'Unrecognized command line argument \"'+argv[i]+'\"\n') - else: - i += 1 - - if len(argv) != 1: - # if there are more than 2 remaining arguments, - problem_args = ['\"'+arg+'\"' for arg in argv[1:]] - raise ttree_lex.InputError('Syntax Error('+g_program_name+'):\n\n' - ' Problem with argument list.\n' - ' The remaining arguments are:\n\n' - ' '+(' '.join(problem_args))+'\n\n' - ' (The actual problem may be earlier in the argument list.)\n') - - bond_types = [] - fatoms = open(fname_atoms, 'r') - lines_bonds = [] - lines_bond_list = [] - fbonds = fbond_list = None - try: - if fname_bonds != None: - fbonds = open(fname_bonds, 'r') - lines_bonds = fbonds.readlines() - fbonds.close() - except IOError: - pass - try: - if fname_bond_list != None: - fbond_list = open(fname_bond_list, 'r') - lines_bond_list = fbond_list.readlines() - fbond_list.close() - except IOError: - pass - if ((len(lines_bonds) == 0) and (len(lines_bond_list) == 0)): - sys.stderr.write('Error('+g_program_name+'): No bonds defined for this system\n' - ' (This error may be a bug in moltemplate.)\n') - fchargepairsbytype = open(fname_chargepairsbytype, 'r') - lines_atoms = fatoms.readlines() - - lines_chargepairsbytype = fchargepairsbytype.readlines() - fatoms.close() - fchargepairsbytype.close() - chargebyatomid = defaultdict(float) - - LookupChargePairs(chargebyatomid, - lines_atoms, - lines_bonds, - lines_bond_list, - lines_chargepairsbytype, - atom_style, - section_name) - - for atomid, charge in chargebyatomid.items(): - sys.stdout.write(' set atom ' + str(atomid) + - ' charge ' + str(charge) + '\n') - - except (ValueError, ttree_lex.InputError) as err: - sys.stderr.write('\n'+str(err)+'\n') - sys.exit(-1) - diff --git a/tools/moltemplate/src/dump2data.py b/tools/moltemplate/src/dump2data.py deleted file mode 100644 index 25c73219dd..0000000000 --- a/tools/moltemplate/src/dump2data.py +++ /dev/null @@ -1,1290 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -""" -dump2data.py - -Extract dynamical degrees of freedom from a lammps DUMP file (from the stdin) -and construct a new DATA file (to the stdout). -A reference DATA file is needed (argument). - - basic usage -./dump2data.py orig_file.data < dump.lammpstrj > new_file.data - (This extract last frame, uses "full" atom_style.) - - options: -./dump2data.py [-t t -atomstyle style] orig.data < dump.lammpstrj > new.data - -""" - -# Authors: Andrew Jewett -# License: New BSD License -# Copyright (c) 2014 -# All rights reserved. - - -import sys -from collections import defaultdict -from operator import itemgetter, attrgetter - - -class InputError(Exception): - def __init__(self, err_msg): - self.err_msg = err_msg - def __str__(self): - return self.err_msg - - -def ErrorLeader(infile, lineno): - return '\"'+infile+'\", line '+str(lineno)+': ' - - -class MiscSettings(object): - def __init__(self): - self.tstart = None - self.tstop = None - self.timestep_str = '' - self.last_frame = False - self.center_frame = False - self.output_format = 'data' - self.input_format = 'dump' - self.multi = True - self.skip_interval = 1 - self.scale = None - - -class AtomStyleSettings(object): - def __init__(self): - # The following new member data indicate which columns store - # LAMMPS-specific information. - # The next 6 members store keep track of the different columns - # of the "Atoms" section of a LAMMPS data file: - self.column_names = [] #<--A list of column names (optional) - self.i_coords=[] #<--A triplet of integers indicating which columns store coordinate data - #self.ii_coords= [] #<--A list of triplets of column indexes storing coordinate data - self.ii_vects=[] #<--A list of triplets of column indexes storing directional data - # (such as dipole or ellipsoid orientations) - self.i_atomid=None #<--An integer indicating which column has the atomid - self.i_atomtype=None #<--An integer indicating which column has the atomtype - self.i_molid=None #<--An integer indicating which column has the molid, if applicable - - - -class DataSettings(AtomStyleSettings): - def __init__(self): - AtomStyleSettings.__init__(self) - self.contents = '' - self.file_name = '' - - - -# Atom Styles in LAMMPS as of 2011-7-29 -g_style_map = {'angle': ['atom-ID','molecule-ID','atom-type','x','y','z'], - 'atomic': ['atom-ID','atom-type','x','y','z'], - 'bond': ['atom-ID','molecule-ID','atom-type','x','y','z'], - 'charge': ['atom-ID','atom-type','q','x','y','z'], - 'colloid': ['atom-ID','atom-type','x','y','z'], - 'dipole': ['atom-ID','atom-type','q','x','y','z','mux','muy','muz'], - 'electron': ['atom-ID','atom-type','q','spin','eradius','x','y','z'], - 'ellipsoid':['atom-ID','atom-type','x','y','z','quatw','quati','quatj','quatk'], - 'full': ['atom-ID','molecule-ID','atom-type','q','x','y','z'], - 'granular': ['atom-ID','atom-type','diameter','density','x','y','z'], - 'molecular':['atom-ID','molecule-ID','atom-type','x','y','z'], - 'peri': ['atom-ID','atom-type','volume','density','x','y','z'], - 'hybrid': ['atom-ID','atom-type','x','y','z']} - - - - -def AtomStyle2ColNames(atom_style_string): - - atom_style_string = atom_style_string.strip() - if len(atom_style_string) == 0: - raise InputError('Error(dump2data): Invalid atom_style\n' - ' (The atom_style command was followed by an empty string.)\n') - atom_style_args = atom_style_string.split() - atom_style = atom_style_args[0] - - hybrid_args = atom_style_args[1:] - if (atom_style not in g_style_map): - if (len(atom_style_args) >= 2): - # If the atom_style_string includes at least 2 words, then we - # interpret this as a list of the individual column names - return atom_style_args - else: - raise InputError('Error(dump2data): Unrecognized atom_style: \"'+atom_style+'\"\n') - - if (atom_style != 'hybrid'): - return g_style_map[atom_style] - else: - column_names = ['atom-ID','atom-type','x','y','z'] - if (len(hybrid_args)==0): - raise InputError('Error(dump2data): atom_style hybrid must be followed by a sub_style.\n') - for sub_style in hybrid_args: - if (sub_style not in g_style_map): - raise InputError('Error(dump2data): Unrecognized atom_style: \"'+sub_style+'\"\n') - for cname in g_style_map[sub_style]: - if cname not in column_names: - column_names.append(cname) - - return column_names - - -def ColNames2AidAtypeMolid(column_names): - # Because of the diversity of ways that these - # numbers are referred to in the LAMMPS documentation, - # we have to be flexible and allow the user to refer - # to these quantities in a variety of ways. - # Hopefully this covers everything: - - i_atomid = None - if 'atom-ID' in column_names: - i_atomid = column_names.index('atom-ID') - elif 'atom−ID' in column_names: # (− is the character used in the manual) - i_atomid = column_names.index('atom−ID') - elif 'atomID' in column_names: - i_atomid = column_names.index('atomID') - elif 'atomid' in column_names: - i_atomid = column_names.index('atomid') - elif 'id' in column_names: - i_atomid = column_names.index('id') - elif 'atom' in column_names: - i_atomid = column_names.index('atom') - elif '$atom' in column_names: - i_atomid = column_names.index('$atom') - else: - raise InputError('Error(dump2data): List of column names lacks an \"atom-ID\"\n') - - i_atomtype = None - if 'atom-type' in column_names: - i_atomtype = column_names.index('atom-type') - elif 'atom−type' in column_names: # (− hyphen character used in manual) - i_atomtype = column_names.index('atom−type') - elif 'atomtype' in column_names: - i_atomtype = column_names.index('atomtype') - elif 'type' in column_names: - i_atomtype = column_names.index('type') - elif '@atom' in column_names: - i_atomtype = column_names.index('@atom') - else: - raise InputError('Error(dump2data): List of column names lacks an \"atom-type\"\n') - - i_molid = None - if 'molecule-ID' in column_names: - i_molid = column_names.index('molecule-ID') - elif 'molecule−ID' in column_names: # (− hyphen character used in manual) - i_molid = column_names.index('molecule−ID') - elif 'moleculeID' in column_names: - i_molid = column_names.index('moleculeID') - elif 'moleculeid' in column_names: - i_molid = column_names.index('moleculeid') - elif 'molecule' in column_names: - i_molid = column_names.index('molecule') - elif 'molID' in column_names: - i_molid = column_names.index('molID') - elif 'molid' in column_names: - i_molid = column_names.index('molid') - elif 'mol' in column_names: - i_molid = column_names.index('mol') - elif '$mol' in column_names: - i_molid = column_names.index('$mol') - else: - pass # some atom_types do not have a valid molecule-ID - - return i_atomid, i_atomtype, i_molid - - - -def ColNames2Coords(column_names): - """ Which of the columns correspond to coordinates - which must be transformed using rigid-body - (affine: rotation + translation) transformations? - This function outputs a list of lists of triplets of integers. - - """ - i_x = None - i_y = None - i_z = None - if 'x' in column_names: - i_x = column_names.index('x') - if 'y' in column_names: - i_y = column_names.index('y') - if 'z' in column_names: - i_z = column_names.index('z') - if (((i_x != None) != (i_y != None)) or - ((i_y != None) != (i_z != None)) or - ((i_z != None) != (i_x != None))): - raise InputError('Error(dump2data): columns must include \"x\", \"y\", and \"z\".\n') - return [[i_x, i_y, i_z]] - - -def ColNames2Vects(column_names): - """ Which of the columns correspond to coordinates - which must be transformed using rotations? - Some coordinates like dipole moments and - ellipsoid orientations should only be rotated - (not translated). - This function outputs a list of lists of triplets of integers. - - """ - vects = [] - i_mux = None - i_muy = None - i_muz = None - if 'mux' in column_names: - i_mux = column_names.index('mux') - if 'muy' in column_names: - i_muy = column_names.index('muy') - if 'muz' in column_names: - i_muz = column_names.index('muz') - if (((i_mux != None) != (i_muy != None)) or - ((i_muy != None) != (i_muz != None)) or - ((i_muz != None) != (i_mux != None))): - raise InputError('Error(dump2data): custom atom_style list must define mux, muy, and muz or none.\n') - if i_mux != None: - vects.append([i_mux, i_muy, i_muz]) - i_quati = None - i_quatj = None - i_quatk = None - if 'quati' in column_names: - i_quati = column_names.index('quati') - if 'quatj' in column_names: - i_quatj = column_names.index('quatj') - if 'quatk' in column_names: - i_quatk = column_names.index('quatk') - if (((i_quati != None) != (i_quatj != None)) or - ((i_quatj != None) != (i_quatk != None)) or - ((i_quatk != None) != (i_quati != None))): - raise InputError('Error(dump2data): custom atom_style list must define quati, quatj, and quatk or none.\n') - if i_quati != None: - vects.append([i_quati, i_quatj, i_quatk]) - return vects - - - - - -def ParseArgs(argv, - misc_settings, - data_settings, - warning_strings=None): - - # Loop over the remaining arguments not processed yet. - # These arguments are specific to the lttree.py program - # and are not understood by this program. - i = 1 - while i < len(argv): - #sys.stderr.write('argv['+str(i)+'] = \"'+argv[i]+'\"\n') - if ((argv[i].lower() == '-atomstyle') or - (argv[i].lower() == '-atom_style') or - (argv[i].lower() == '-atom-style')): - in_init = [] - if i+1 >= len(argv): - raise InputError('Error(dump2data): '+argv[i]+' flag should be followed by a an atom_style name.\n' - ' (Or single quoted string which includes a space-separated\n' - ' list of column names.)\n') - data_settings.column_names = AtomStyle2ColNames(argv[i+1]) - sys.stderr.write(' \"Atoms\" column format:\n') - sys.stderr.write(' '+(' '.join(data_settings.column_names))+'\n') - - # ColNames2Coords() and ColNames2Vects() generate lists of - # triplets of integers, storing the column numbers containing - # x, y, and z coordinate values, and vx,vy,vz direction vectors. - data_settings.ii_vects = ColNames2Vects(data_settings.column_names) - ii_coords = ColNames2Coords(data_settings.column_names) - # This program assumes that there is only one coordinate triplet - # (x,y,z) for each atom. Hence we assume that len(ii_coords)==1 - assert(len(ii_coords) == 1) - data_settings.i_coords = ii_coords[0] - - # Now figure out which columns correspond to atomid, atomtype, molid - data_settings.i_atomid, data_settings.i_atomtype, data_settings.i_molid = ColNames2AidAtypeMolid(data_settings.column_names) - del(argv[i:i+2]) - - elif (argv[i].lower() == '-icoord'): - if i+1 >= len(argv): - raise InputError('Error(dump2data): '+argv[i]+' flag should be followed by list of integers\n' - ' corresponding to column numbers for coordinates in\n' - ' the \"Atoms\" section of a LAMMPS data file.\n') - ilist = argv[i+1].split() - if (len(ilist) % 3) != 0: - raise InputError('Error(dump2data): '+argv[i]+' flag should be followed by list of integers.\n' - ' This is usually a list of 3 intebers, but it can contain more.\n' - ' The number of cooridnate columns must be divisible by 3,\n' - ' (even if the simulation is in 2 dimensions)\n') - - #ii_coords = [] - #for i in range(0, len(ilist)/3): - # cols = [ilist[3*i]+1, ilist[3*i+1]+1, ilist[3*i+2]+1] - # ii_coords.append(cols) - #if ((len(ii_coords) != 0) or (len(ii_coords[0]) != 3)): - # raise InputError('Error(dump2data): Argument \"'+argv[i]+'\" must be followed by exactly 3 integers.\n') - - data_settings.i_coords = ilist - if (len(i_coords) != 3): - raise InputError('Error(dump2data): Argument \"'+argv[i]+'\" must be followed by exactly 3 integers.\n') - - data_settings.i_coords = ii_coords[0] - - del(argv[i:i+2]) - - elif (argv[i].lower() == '-ivect'): - if i+1 >= len(argv): - raise InputError('Error(dump2data): '+argv[i]+' flag should be followed by list of integers\n' - ' corresponding to column numbers for direction vectors in\n' - ' the \"Atoms\" section of a LAMMPS data file.\n') - ilist = argv[i+1].split() - if (len(ilist) % 3) != 0: - raise InputError('Error(dump2data): '+argv[i]+' flag should be followed by list of integers.\n' - ' This is usually a list of 3 intebers, but it can contain more.\n' - ' The number of cooridnate columns must be divisible by 3,\n' - ' (even if the simulation is in 2 dimensions)\n') - - data_settings.ii_vects = [] - for i in range(0, len(ilist)/3): - cols = [ilist[3*i]+1, ilist[3*i+1]+1, ilist[3*i+2]+1] - setting.ii_vects.append(cols) - # This should override any earlier settings as a result of the - # -atomstyle argument. So you can specify a custom list of column - # names using -atomstyle "list of column names", and then afterwards - # specify which of these columns correspond to direction vectors - # using the "-ivect" command line argument later on. - # This way, in theory you should be able to read columns from - # new custom atom-styles that have not been invented yet. - # (Although I haven't tested this.) - - del(argv[i:i+2]) - # i_atomid is not really needed for this program, but I load it anyway - elif ((argv[i].lower() == '-iatomid') or - (argv[i].lower() == '-iid') or - (argv[i].lower() == '-iatom-id')): - if ((i+1 >= len(argv)) or (not str.isdigit(argv[i+1]))): - raise InputError('Error(dump2data): '+argv[i]+' flag should be followed by an integer\n' - ' (>=1) indicating which column in the \"Atoms\" section of a\n' - ' LAMMPS data file contains the atom id number (typically 1).\n' - ' (This argument is unnecessary if you use the -atomstyle argument.)\n') - i_atomid = int(argv[i+1])-1 - del(argv[i:i+2]) - # i_atomtype is not really needed for this program, but I load it anyway - elif ((argv[i].lower() == '-iatomtype') or - (argv[i].lower() == '-itype') or - (argv[i].lower() == '-iatom-type')): - if ((i+1 >= len(argv)) or (not str.isdigit(argv[i+1]))): - raise InputError('Error(dump2data): '+argv[i]+' flag should be followed by an integer\n' - ' (>=1) indicating which column in the \"Atoms\" section of a\n' - ' LAMMPS data file contains the atom type.\n' - ' (This argument is unnecessary if you use the -atomstyle argument.)\n') - i_atomtype = int(argv[i+1])-1 - del(argv[i:i+2]) - # i_molid is not really needed for this program, but I load it anyway - elif ((argv[i].lower() == '-imolid') or - (argv[i].lower() == '-imol') or - (argv[i].lower() == '-imol-id') or - (argv[i].lower() == '-imoleculeid') or - (argv[i].lower() == '-imolecule-id')): - if ((i+1 >= len(argv)) or (not str.isdigit(argv[i+1]))): - raise InputError('Error(dump2data): '+argv[i]+' flag should be followed by an integer\n' - ' (>=1) indicating which column in the \"Atoms\" section of a\n' - ' LAMMPS data file contains the molecule id number.\n' - ' (This argument is unnecessary if you use the -atomstyle argument.)\n') - del(argv[i:i+2]) - # Which frame do we want? - elif (argv[i].lower() == '-t'): - if ((i+1 >= len(argv)) or (not str.isdigit(argv[i+1]))): - raise InputError('Error(dump2data): '+argv[i]+' flag should be followed by an integer indicating\n' - ' the frame you want to extract from the dump file (trajectory).\n' - ' This integer should match the timestep corresponding to the frame\n' - ' whose coordinates you wish to extract.\n') - misc_settings.timestep_str = argv[i+1] - del(argv[i:i+2]) - misc_settings.multi = False - misc_settings.last_frame = False - - elif (argv[i].lower() == '-tstart'): - if ((i+1 >= len(argv)) or (not str.isdigit(argv[i+1]))): - raise InputError('Error(dump2data): '+argv[i]+' flag should be followed by an integer indicating\n' - ' the first frame you want to extract from the dump file (trajectory).\n' - ' This integer should match the timestep corresponding to the frame\n' - ' (after which) you wish to extract coordinates.\n') - misc_settings.tstart = float(argv[i+1]) - del(argv[i:i+2]) - misc_settings.multi = True - - elif (argv[i].lower() == '-tstop'): - if ((i+1 >= len(argv)) or (not str.isdigit(argv[i+1]))): - raise InputError('Error(dump2data): '+argv[i]+' flag should be followed by an number indicating\n' - ' the first frame you want to extract from the dump file (trajectory).\n' - ' Frames after this timestep will be ignored.\n') - misc_settings.tstop = float(argv[i+1]) - del(argv[i:i+2]) - misc_settings.multi = True - - elif (argv[i].lower() == '-center'): - misc_settings.center_frame = True - del(argv[i:i+1]) - - elif ((argv[i].lower() == '-raw') or (argv[i].lower() == '-rawout')): - misc_settings.output_format = 'raw' - del(argv[i:i+1]) - - elif (argv[i].lower() == '-rawin'): - misc_settings.input_format = 'raw' - misc_settings.multi = False - del(argv[i:i+1]) - - elif ((argv[i].lower() == '-xyz') or (argv[i].lower() == '-xyzout')): - misc_settings.output_format = 'xyz' - del(argv[i:i+1]) - - elif (argv[i].lower() == '-xyzin'): - misc_settings.input_format = 'xyz' - misc_settings.multi = False - del(argv[i:i+1]) - - elif (argv[i].lower() == '-multi'): - misc_settings.multi = True - del(argv[i:i+1]) - - elif (argv[i].lower() == '-last'): - misc_settings.last_frame = True - misc_settings.multi = False - del(argv[i:i+1]) - - elif (argv[i].lower() == '-interval'): - misc_settings.skip_interval = int(argv[i+1]) - del(argv[i:i+2]) - - elif (argv[i].lower() == '-scale'): - misc_settings.scale = float(argv[i+1]) - del(argv[i:i+2]) - - elif ((argv[i][0] == '-') and (__name__ == "__main__")): - raise InputError('Error(dump2data): Unrecognized command line argument \"'+argv[i]+'\"\n') - else: - i += 1 - - usage_examples = \ -""" Typical usage: -dump2data.py orig_file.data < dump.lammpstrj > new_file.data - (This extracts last frame, uses "full" atom_style.) - Additional options: -dump2data.py -t t -atomstyle style orig.data < dump.lammpstrj > new.data -""" - - #if __name__ == "__main__": - - if (len(argv) > 2): - # if there are more than 2 remaining arguments, - # AND - # no other function will process the remaining argument list - # (ie. if __name__ == "__main__") - # THEN - raise InputError(' ----\n' - 'ERROR(dump2data): You have too many arguments (or unrecognized arguments):\n' - ' \"'+(' '.join(argv))+'\"\n' - ' ----\n' - +usage_examples) - elif (len(argv) < 2): - if misc_settings.output_format == 'data': - raise InputError(' ----\n' - 'ERROR(dump2data): Problem with argument list:\n' - ' Expected a LAMMPS .data file as an argument.\n' - ' ----\n' - +usage_examples) - else: - in_data_file = open(argv[1], 'r') - data_settings.file_name = argv[1]; - data_settings.contents = in_data_file.readlines() - in_data_file.close() - - #end of if-then statement for "if __name__ == "__main__"" - - if len(data_settings.i_coords) == 0: - if warning_strings != None: - warning_strings.append('WARNING(dump2data): atom_style unknown. (Use -atomstyle style. Assuming \"full\")') - warn_atom_style_unspecified = True - # The default atom_style is "full" - data_settings.column_names = AtomStyle2ColNames('full') - ii_coords = ColNames2Coords(data_settings.column_names) - # This program assumes that there is only one coordinate triplet - # (x,y,z) for each atom. Hence we assume that len(ii_coords)==1 - assert(len(ii_coords) == 1) - data_settings.i_coords = ii_coords[0] - data_settings.ii_vects = ColNames2Vects(data_settings.column_names) - data_settings.i_atomid, data_settings.i_atomtype, data_settings.i_molid = ColNames2AidAtypeMolid(data_settings.column_names) - - ### sys.stderr.write('########################################################\n' - ### '## WARNING: atom_style unspecified ##\n' - ### '## --> \"Atoms\" column data has an unknown format. ##\n' - ### '## Assuming atom_style = \"full\" ##\n' - ### '########################################################\n' - ### '## To specify the \"Atoms\" column format you can: ##\n' - ### '## 1) Use the -atom_style \"STYLE\" argument ##\n' - ### '## where \"STYLE\" is a string indicating a LAMMPS ##\n' - ### '## atom_style, including hybrid styles.(Standard ##\n' - ### '## atom styles defined in 2011 are supported.) ##\n' - ### '## 2) Use the -atom_style \"COL_LIST\" argument ##\n' - ### '## where \"COL_LIST" is a quoted list of strings ##\n' - ### '## indicating the name of each column. ##\n' - ### '## Names \"x\",\"y\",\"z\" are interpreted as ##\n' - ### '## atomic coordinates. \"mux\",\"muy\",\"muz\" ##\n' - ### '## and \"quati\",\"quatj\",\"quatk\" are ##\n' - ### '## interpreted as direction vectors. ##\n' - ### '## 3) Use the -icoord \"cx cy cz...\" argument ##\n' - ### '## where \"cx cy cz\" is a list of integers ##\n' - ### '## indicating the column numbers for the x,y,z ##\n' - ### '## coordinates of each atom. ##\n' - ### '## 4) Use the -ivect \"cmux cmuy cmuz...\" argument ##\n' - ### '## where \"cmux cmuy cmuz...\" is a list of ##\n' - ### '## integers indicating the column numbers for ##\n' - ### '## the vector that determines the direction of a ##\n' - ### '## dipole or ellipsoid (ie. a rotateable vector).##\n' - ### '## (More than one triplet can be specified. The ##\n' - ### '## number of entries must be divisible by 3.) ##\n' - ### '## 5) Include a ##\n' - ### '## write(\"in_init.txt\"){atom_style ...} ##\n' - ### '## statement in your .ttree file. ##\n' - ### '########################################################\n') - - - - -def GetIntAtomID(pair): - return int(pair[0]) - - - -def WriteFrameToData(out_file, - descr_str, - misc_settings, - data_settings, - natoms, - coords, - coords_ixiyiz, - vects, - velocities, - atomtypes, - molids, - xlo_str, xhi_str, - ylo_str, yhi_str, - zlo_str, zhi_str, - xy_str, xz_str, yz_str): - - """ - Open a data file. Read the LAMMPS DATA file line by line. - When the line contains information which is also in the dump file, - replace that information with information from the dump file. - (Information from a dump file is stored in the arguments to this function.) - The resulting file also has LAMMPS DATA format. - - """ - - section = '' - firstline = True - for line in data_settings.contents: - ic = line.find('#') - if ic != -1: - line = line[:ic] - line = line.strip() - - if firstline: # Construct a new descriptive header line: - if descr_str != None: - line = descr_str - firstline = False - - if (len(line) > 0): - # The initial section (section='') is assumed to be - # the "LAMMPS Description" section. This is where the - # box boundaries are specified. - if section == '': - tokens = line.split() - if ((len(tokens) >= 2) and - ((tokens[-2] == 'xlo') and (tokens[-1] == 'xhi')) and - ((xlo_str != None) and (xhi_str != None))): - tokens[0] = xlo_str - tokens[1] = xhi_str - line = ' '.join(tokens) - elif ((len(tokens) >= 2) and - ((tokens[-2] == 'ylo') and (tokens[-1] == 'yhi')) and - ((ylo_str != None) and (yhi_str != None))): - tokens[0] = ylo_str - tokens[1] = yhi_str - line = ' '.join(tokens) - elif ((len(tokens) >= 2) and - ((tokens[-2] == 'zlo') and (tokens[-1] == 'zhi')) and - ((zlo_str != None) and (zhi_str != None))): - tokens[0] = zlo_str - tokens[1] = zhi_str - line = ' '.join(tokens) - elif ((len(tokens) >= 3) and - ((tokens[-3] == 'xy') and - (tokens[-2] == 'xz') and - (tokens[-1] == 'yz')) and - ((xy_str != None) and - (xz_str != None) and - (yz_str != None))): - tokens[0] = xy_str - tokens[1] = xz_str - tokens[2] = yz_str - line = ' '.join(tokens) - if (line in set(['Masses', 'Velocities', 'Atoms', - 'Bond Coeffs', 'Angle Coeffs', - 'Dihedral Coeffs', 'Improper Coeffs', - 'Bonds', 'Angles', 'Dihedrals', 'Impropers'])): - section = line - else: - if (section == 'Atoms'): - tokens = line.split() - atomid = tokens[0] - - # update the atomtype and molID - # (which may change during the simulation) - if atomtypes: - tokens[data_settings.i_atomtype] = atomtypes[atomid] - if molids and data_settings.i_molid: - tokens[data_settings.i_molid] = molids[atomid] - - if atomid in coords: - # Loop over all of the vector degrees of - # freedom of the particle, excluding coords - # (for example: mu_x, mu_y, mu_z, - # or quat_i, quat_j, quat_k) - # In principle, depending on the atom_style, - # there could be multiple vectors per atom. - for I in range(0,len(data_settings.ii_vects)): - vxvyvz = vects[atomid][I] - i_vx = data_settings.ii_vects[I][0] - i_vy = data_settings.ii_vects[I][1] - i_vz = data_settings.ii_vects[I][2] - if ((i_vx >= len(tokens)) or - (i_vy >= len(tokens)) or - (i_vz >= len(tokens))): - raise InputError('Error(dump2data): Atom style incompatible with data file.\n' - ' Specify the atom_style using -atomstyle style.\n') - if ((vxvyvz == None) or - (type(vxvyvz) is not tuple)): - assert(data_settings.column_names[i_vx] not in dump_column_names) - raise InputError('Error(dump2data): You have a vector coordinate in your DATA file named \"'+data_settings.column_names[i_vx]+'\"\n' - ' However there are no columns with this name in your DUMP file\n' - ' (or the column was not in the expected place).\n' - ' Hence, the atom styles in the dump and data files do not match.') - - # Replace the vector components with numbers - # from the dump file - tokens[i_vx] = vxvyvz[0] - tokens[i_vy] = vxvyvz[1] - tokens[i_vz] = vxvyvz[2] - - # Now loop over the coordinates of each atom. - #for I in range(0,len(data_settings.ii_coords)): - # xyz = coords[atomid][I] - # THIS LOOP IS SILLY. - # EACH ATOM ONLY HAS ONE SET OF X,Y,Z - # COORDINATES. COMMENTING OUT THIS LOOP: - # i_x = data_settings.ii_coords[I][0] - # i_y = data_settings.ii_coords[I][1] - # i_z = data_settings.ii_coords[I][2] - # USING THIS INSTEAD: - - xyz = coords[atomid] - i_x = data_settings.i_coords[0] - i_y = data_settings.i_coords[1] - i_z = data_settings.i_coords[2] - if ((i_x >= len(tokens)) or - (i_y >= len(tokens)) or - (i_z >= len(tokens))): - raise InputError('Error(dump2data): Atom style incompatible with data file.\n' - ' Specify the atom_style using -atomstyle style.\n') - # Replace the coordinates with coordinates from - # the dump file into tokens[i_x]... - tokens[i_x] = str(xyz[0]) - tokens[i_y] = str(xyz[1]) - tokens[i_z] = str(xyz[2]) - - # Are there there any integer coords - # (ix, iy, iz) in the dump file? - if coords_ixiyiz[atomid]: - assert(len(coords_ixiyiz[atomid]) == 3) - # Integer coords stored in the DATA file too? - if len(tokens)==(len(data_settings.column_names)+3): - # Then replace the last 3 columns of the - # line in the data file with: ix iy iz - tokens[-3] = coords_ixiyiz[atomid][0] - tokens[-2] = coords_ixiyiz[atomid][1] - tokens[-1] = coords_ixiyiz[atomid][2] - else: - if (not misc_settings.center_frame): - # Append them to the end of the line: - tokens.append(coords_ixiyiz[atomid][0]) - tokens.append(coords_ixiyiz[atomid][1]) - tokens.append(coords_ixiyiz[atomid][2]) - - # Now finally paste all the tokens together: - line = ' '.join(tokens) - - - elif (section == 'Velocities'): - tokens = line.split() - atomid = tokens[0] - if atomid in velocities: - - vxvyvz = velocities[atomid] - if len(tokens) < 4: - raise InputError('Error(dump2data): Not enough columns in the \"Velocities\" file.\n') - # Replace the coordinates with coordinates from - # the dump file into tokens[i_x]... - tokens[1] = str(vxvyvz[0]) - tokens[2] = str(vxvyvz[1]) - tokens[3] = str(vxvyvz[2]) - - # Now finally paste all the tokens together: - line = ' '.join(tokens) - - - out_file.write(line+'\n') - - - - - - - - - - - - - - - -if __name__ == "__main__": - - g_program_name = 'dump2data.py' - g_date_str = '2015-8-11' - g_version_str = 'v0.51' - - ####### Main Code Below: ####### - sys.stderr.write(g_program_name+' '+g_version_str+' '+g_date_str+' ') - #if sys.version < '3': - # sys.stderr.write(' (python version < 3)\n') - #else: - sys.stderr.write('\n') - - try: - data_settings = DataSettings() - misc_settings = MiscSettings() - warning_strings = [] - ParseArgs(sys.argv, - misc_settings, - data_settings, - warning_strings) - - # Open the lammps dump file (trajectory file) - # Skip to the line containing the correct frame/timestep. - # (this is the last frame by default). - # Read the "BOX BOUNDS" and the "ATOMS" sections. - # Store the x,y,z coordinates in the "coords" associative array - # (indexed by atom id, which could be non-numeric in general). - - section = '' - - #coords = defaultdict(list) - #coords_ixiyiz = defaultdict(list) - #vects = defaultdict(list) - #xlo_str = xhi_str = ylo_str = yhi_str = zlo_str = zhi_str = None - #xy_str = xz_str = yz_str = None - #natoms = -1 - #timestep_str = '' - - frame_coords = defaultdict(list) - frame_coords_ixiyiz = defaultdict(list) - frame_vects = defaultdict(list) - frame_velocities = defaultdict(list) - frame_atomtypes = defaultdict(list) - frame_molid = defaultdict(list) - frame_xlo_str = frame_xhi_str = None - frame_ylo_str = frame_yhi_str = None - frame_zlo_str = frame_zhi_str = None - frame_xy_str = frame_xz_str = frame_yz_str = None - frame_natoms = -1 - frame_timestep_str = '' - i_atomid = i_atomtype = i_molid = -1 - i_x = i_y = i_z = i_xu = i_yu = i_zu = -1 - i_xs = i_ys = i_zs = i_xsu = i_ysu = i_zsu = -1 - - dump_column_names = [] - - #num_frames_in = -1 - num_frames_out = 0 - finished_reading_frame = False - read_last_frame = False - - #in_coord_file = open('traj_nvt.lammpstrj','r') - #in_coord_file = open('deleteme.lammpstrj','r') - in_coord_file = sys.stdin - - while True: - - line = in_coord_file.readline() - if line == '': # if EOF - if len(frame_coords) > 0: - finished_reading_frame = True - read_last_frame = True - - line = line.strip() - if (line.find('ITEM:') == 0): - section = line - if (section.find('ITEM: ATOMS ') == 0): - dump_column_names = line[12:].split() - i_atomid, i_atomtype, i_molid = \ - ColNames2AidAtypeMolid(dump_column_names) - #ii_coords = ColNames2Coords(dump_column_names) - - x_already_unwrapped = False - y_already_unwrapped = False - z_already_unwrapped = False - - if 'x' in dump_column_names: - i_x = dump_column_names.index('x') - elif 'xu' in dump_column_names: - i_xu = dump_column_names.index('xu') - x_already_unwrapped = True - elif 'xs' in dump_column_names: - i_xs = dump_column_names.index('xs') - elif 'xsu' in dump_column_names: - i_xsu = dump_column_names.index('xsu') - x_already_unwrapped = True - else: - raise InputError('Error(dump2data): \"ATOMS\" section of dump file lacks a \"x\" column.\n'+ - ' (excerpt below)\n' + line) - - if 'y' in dump_column_names: - i_y = dump_column_names.index('y') - elif 'yu' in dump_column_names: - i_yu = dump_column_names.index('yu') - y_already_unwrapped = True - elif 'ys' in dump_column_names: - i_ys = dump_column_names.index('ys') - elif 'ysu' in dump_column_names: - i_ysu = dump_column_names.index('ysu') - y_already_unwrapped = True - else: - raise InputError('Error(dump2data): \"ATOMS\" section of dump file lacks a \"y\" column.\n'+ - ' (excerpt below)\n' + line) - - if 'z' in dump_column_names: - i_z = dump_column_names.index('z') - elif 'zu' in dump_column_names: - i_zu = dump_column_names.index('zu') - z_already_unwrapped = True - elif 'zs' in dump_column_names: - i_zs = dump_column_names.index('zs') - elif 'zsu' in dump_column_names: - i_zsu = dump_column_names.index('zsu') - z_already_unwrapped = True - else: - raise InputError('Error(dump2data): \"ATOMS\" section of dump file lacks a \"z\" column.\n'+ - ' (excerpt below)\n' + line) - - - - - - ii_vects = ColNames2Vects(dump_column_names) - if (len(ii_vects) != len(data_settings.ii_vects)): - raise InputError('Error(dump2data): atom styles in data and dump files differ.\n' - ' Some needed columns from the atom_styles are missing in the dump file.') - - i_ix = i_iy = i_iz = -1 - if 'ix' in dump_column_names: - i_ix = dump_column_names.index('ix') - if 'iy' in dump_column_names: - i_iy = dump_column_names.index('iy') - if 'iz' in dump_column_names: - i_iz = dump_column_names.index('iz') - - - i_vx = i_vy = i_vz = -1 - if 'vx' in dump_column_names: - i_vx = dump_column_names.index('vx') - if 'vy' in dump_column_names: - i_vy = dump_column_names.index('vy') - if 'vz' in dump_column_names: - i_vz = dump_column_names.index('vz') - - elif (section.find('ITEM: BOX BOUNDS') == 0): - avec=[1.0, 0.0, 0.0] - bvec=[0.0, 1.0, 0.0] - cvec=[0.0, 0.0, 1.0] - - elif (section.find('ITEM: TIMESTEP') == 0): - if len(frame_coords) > 0: - finished_reading_frame = True - - elif ((len(line) > 0) and (line[0] != '#')): - if (section.find('ITEM: TIMESTEP') == 0): - finished_reading_frame = False - frame_timestep_str = line - frame_coords = defaultdict(list) - frame_coords_ixiyiz = defaultdict(list) - frame_vects = defaultdict(list) - frame_velocities = defaultdict(list) - frame_atomtypes = defaultdict(list) - frame_molids = defaultdict(list) - frame_xlo_str = frame_xhi_str = None - frame_ylo_str = frame_yhi_str = None - frame_zlo_str = frame_zhi_str = None - frame_xy_str = frame_xz_str = frame_yz_str = None - - elif (section == 'ITEM: NUMBER OF ATOMS'): - frame_natoms = int(line) - - elif (section.find('ITEM: BOX BOUNDS') == 0): - is_triclinic = (section.find('xy xz yz') == 0) - - tokens = line.split() - if not frame_xlo_str: - assert(not frame_xhi_str) - frame_xlo_str = tokens[0] - frame_xhi_str = tokens[1] - avec[0] = float(frame_xhi_str) - float(frame_xlo_str) - if (is_triclinic and (len(tokens) > 2)): - frame_xy_str = tokens[2] - bvec[0] = float(frame_xy_str) - #See http://lammps.sandia.gov/doc/Section-howto.html#howto_12 - #sys.stderr.write('avec='+str(avec)+'\n') - - elif not frame_ylo_str: - assert(not frame_yhi_str) - frame_ylo_str = tokens[0] - frame_yhi_str = tokens[1] - bvec[1] = float(frame_yhi_str) - float(frame_ylo_str) - if (is_triclinic and (len(tokens) > 2)): - frame_xz_str = tokens[2] - cvec[0] = float(frame_xz_str) - #See http://lammps.sandia.gov/doc/Section-howto.html#howto_12 - #sys.stderr.write('bvec='+str(bvec)+'\n') - - elif not frame_zlo_str: - assert(not frame_zhi_str) - frame_zlo_str = tokens[0] - frame_zhi_str = tokens[1] - cvec = [0.0, 0.0, float(frame_zhi_str) - float(frame_zlo_str)] - if (is_triclinic and (len(tokens) > 2)): - frame_yz_str = tokens[2] - cvec[1] = float(frame_yz_str) - #See http://lammps.sandia.gov/doc/Section-howto.html#howto_12 - #sys.stderr.write('cvec='+str(cvec)+'\n') - - elif (section.find('ITEM: ATOMS') == 0): - tokens = line.split() - atomid = tokens[i_atomid] - atomtype = tokens[i_atomtype] - frame_atomtypes[atomid] = atomtype - if i_molid: - molid = tokens[i_molid] - frame_molids[atomid] = molid - - if ((i_x != -1) and (i_y != -1) and (i_z != -1)): - x = float(tokens[i_x]) #i_x determined above - y = float(tokens[i_y]) - z = float(tokens[i_z]) - - elif ((i_xu != -1) and (i_yu != -1) and (i_zu != -1)): - x = float(tokens[i_xu]) #i_x determined above - y = float(tokens[i_yu]) - z = float(tokens[i_zu]) - - elif ((i_xs != -1) and (i_ys != -1) and (i_zs != -1)): - xs = float(tokens[i_xs]) #i_xs determined above - ys = float(tokens[i_ys]) - zs = float(tokens[i_zs]) - - x = float(xlo_str) + xs*avec[0] + ys*bvec[0] + zs*cvec[0] - y = float(ylo_str) + xs*avec[1] + ys*bvec[1] + zs*cvec[1] - z = float(zlo_str) + xs*avec[2] + ys*bvec[2] + zs*cvec[2] - - # avec, bvec, cvec described here: - #http://lammps.sandia.gov/doc/Section-howto.html#howto_12 - - elif ((i_xsu != -1) and (i_ysu != -1) and (i_zsu != -1)): - xsu = float(tokens[i_xsu]) #i_xs determined above - ysu = float(tokens[i_ysu]) - zsu = float(tokens[i_zsu]) - - x = float(xlo_str) + xsu*avec[0] + ysu*bvec[0] + zsu*cvec[0] - y = float(ylo_str) + xsu*avec[1] + ysu*bvec[1] + zsu*cvec[1] - z = float(zlo_str) + xsu*avec[2] + ysu*bvec[2] + zsu*cvec[2] - - # Now deal with ix, iy, iz - if (i_ix != -1) and (not x_already_unwrapped): - ix = int(tokens[i_ix]) - if (misc_settings.center_frame or - (misc_settings.output_format != 'data')): - #sys.stderr.write('atomid='+str(atomid)+', ix = '+str(ix)+', avec='+str(avec)+'\n') - x += ix*avec[0] - y += ix*avec[1] - z += ix*avec[2] - else: - if atomid not in frame_coords_ixiyiz: - frame_coords_ixiyiz[atomid] = ["0", "0", "0"] - frame_coords_ixiyiz[atomid][0] = str(ix) - - if (i_iy != -1) and (not y_already_unwrapped): - iy = int(tokens[i_iy]) - if (misc_settings.center_frame or - (misc_settings.output_format != 'data')): - #sys.stderr.write('atomid='+str(atomid)+', iy = '+str(iy)+', bvec='+str(bvec)+'\n') - x += iy*bvec[0] - y += iy*bvec[1] - z += iy*bvec[2] - else: - if atomid not in frame_coords_ixiyiz: - frame_coords_ixiyiz[atomid] = ["0", "0", "0"] - frame_coords_ixiyiz[atomid][1] = str(iy) - - if (i_iz != -1) and (not z_already_unwrapped): - iz = int(tokens[i_iz]) - if (misc_settings.center_frame or - (misc_settings.output_format != 'data')): - #sys.stderr.write('atomid='+str(atomid)+', iz = '+str(iz)+', cvec='+str(cvec)+'\n') - x += iz*cvec[0] - y += iz*cvec[1] - z += iz*cvec[2] - else: - if atomid not in frame_coords_ixiyiz: - frame_coords_ixiyiz[atomid] = ["0", "0", "0"] - frame_coords_ixiyiz[atomid][2] = str(iz) - - #frame_coords[atomid] = [str(x), str(y), str(z)] - frame_coords[atomid] = [x, y, z] - - vx = 0.0 - vy = 0.0 - vz = 0.0 - if i_vx != -1: - vx = float(tokens[i_vx]) - if i_vy != -1: - vy = float(tokens[i_vy]) - if i_vz != -1: - vz = float(tokens[i_vz]) - - frame_velocities[atomid] = [vx, vy, vz] - - # Ugly detail: - # There can be multiple "vects" associated with each atom - # (for example, dipole moments, ellipsoid directions, etc..) - - if atomid not in frame_vects: - frame_vects[atomid] = [None for I in range(0,len(ii_vects))] - - for I in range(0, len(ii_vects)): - i_vx = ii_vects[I][0] - i_vy = ii_vects[I][1] - i_vz = ii_vects[I][2] - vx_str = tokens[i_vx] - vy_str = tokens[i_vy] - vz_str = tokens[i_vz] - - # Now the annoying part: - # Which vect is it (mux,muy,muz) or (quati,quatj,quatk)? - # The columns could be listed in a different order - # in the data file and in the dump file. - # Figure out which vector it is in the data file (stored - # in the integer "I_data") so that column names match. - name_vx = dump_column_names[i_vx] - name_vy = dump_column_names[i_vy] - name_vz = dump_column_names[i_vz] - i_vx_data = 0 - I_data = -1 - # This code is ugly and inneficient. - # I never want to touch this code again. (Hope it works) - while i_vx_data < len(data_settings.column_names): - if name_vx == data_settings.column_names[i_vx_data]: - I_data = 0 - while I_data < len(data_settings.ii_vects): - if ii_vects[I] == data_settings.ii_vects[I_data]: - break - I_data += 1 - - if (0= - # float(misc_settings.timestep_str)): - # num_frames_in = 1 - # if not misc_settings.multi: - # read_last_frame = True - # else: - # num_frames_in = 1 - - - - # Should we write out the coordinates in this frame? - write_this_frame = False - - if misc_settings.multi: - - write_this_frame = True - if (misc_settings.tstart and - (int(frame_timestep_str) < misc_settings.tstart)): - write_this_frame = False - if (misc_settings.tstop and - (int(frame_timestep_str) > misc_settings.tstop)): - write_this_frame = False - read_last_frame = True - - if misc_settings.tstart: - tstart = misc_settings.tstart - else: - tstart = 0 - - if ((int(frame_timestep_str) - tstart) - % - misc_settings.skip_interval) != 0: - write_this_frame = False - - else: - if misc_settings.last_frame: - if read_last_frame: - write_this_frame = True - else: - assert(misc_settings.timestep_str) - if (int(frame_timestep_str) >= - int(misc_settings.timestep_str)): - write_this_frame = True - read_last_frame = True - - - if write_this_frame: - - num_frames_out += 1 - - sys.stderr.write(' (writing frame '+str(num_frames_out)+ - ' at timestep '+frame_timestep_str+')\n') - - - # Print the frame - # First check which format to output the data: - if misc_settings.output_format == 'raw': - # Print out the coordinates in simple 3-column text format - for atomid, xyz in iter(sorted(frame_coords.items(), key=GetIntAtomID)): - if misc_settings.scale == None: - sys.stdout.write(str(xyz[0])+' '+str(xyz[1])+' '+str(xyz[2])+'\n') - else: - # Only convert to float and back if misc_settings.scale != None - sys.stdout.write(str(misc_settings.scale*float(xyz[0]))+' '+ - str(misc_settings.scale*float(xyz[1]))+' '+ - str(misc_settings.scale*float(xyz[2]))+'\n') - sys.stdout.write('\n') - - elif misc_settings.output_format == 'xyz': - # Print out the coordinates in simple 3-column text format - sys.stdout.write(str(len(frame_coords))+'\n') - descr_str = 'LAMMPS data from timestep '+frame_timestep_str - sys.stdout.write(descr_str+'\n') - for atomid, xyz in iter(sorted(frame_coords.items(), key=GetIntAtomID)): - if misc_settings.scale == None: - sys.stdout.write(str(atomid)+' '+ - str(xyz[0])+' '+ - str(xyz[1])+' '+ - str(xyz[2])+'\n') - else: - # Only convert to float and back if misc_settings.scale != None - sys.stdout.write(str(atomid)+' '+ - str(misc_settings.scale*float(xyz[0]))+' '+ - str(misc_settings.scale*float(xyz[1]))+' '+ - str(misc_settings.scale*float(xyz[2]))+'\n') - - else: - # Parse the DATA file specified by the user - # and replace appropriate lines or fields with - # the corresponding text from the DUMP file. - descr_str = 'LAMMPS data from timestep '+frame_timestep_str - if misc_settings.multi and (misc_settings.output_format == 'data'): - out_file_name = data_settings.file_name + '.'\ - + str(num_frames_out) - sys.stderr.write(' (creating file \"'+out_file_name+'\")\n') - out_file = open(out_file_name, 'w') - else: - out_file = sys.stdout - - WriteFrameToData(out_file, - descr_str, - misc_settings, - data_settings, - frame_natoms, - frame_coords, - frame_coords_ixiyiz, - frame_vects, - frame_velocities, - frame_atomtypes, - frame_molids, - frame_xlo_str, frame_xhi_str, - frame_ylo_str, frame_yhi_str, - frame_zlo_str, frame_zhi_str, - frame_xy_str, frame_xz_str, frame_yz_str) - - #if misc_settings.multi: - # out_file.close() - - - #if num_frames_in >= 0: - # num_frames_in += 1 - - - if read_last_frame: - exit(0) - - - for warning_str in warning_strings: - sys.stderr.write(warning_str+'\n') - - - - except (ValueError, InputError) as err: - sys.stderr.write('\n'+str(err)+'\n') - sys.exit(-1) - diff --git a/tools/moltemplate/src/extract_lammps_data.py b/tools/moltemplate/src/extract_lammps_data.py deleted file mode 100644 index 4fe3ec743d..0000000000 --- a/tools/moltemplate/src/extract_lammps_data.py +++ /dev/null @@ -1,119 +0,0 @@ -#!/usr/bin/env python - -lammps_data_sections = set(['Atoms', - 'Masses', - 'Bonds', - 'Bond Coeffs', - 'Angles', - 'Angle Coeffs', - 'Dihedrals', - 'Dihedral Coeffs', - 'Impropers', - 'Improper Coeffs', - 'BondBond Coeffs', # class2 angles - 'BondAngle Coeffs', # class2 angles - 'MiddleBondTorsion Coeffs', # class2 dihedrals - 'EndBondTorsion Coeffs', # class2 dihedrals - 'AngleTorsion Coeffs', # class2 dihedrals - 'AngleAngleTorsion Coeffs', # class2 dihedrals - 'BondBond13 Coeffs', # class2 dihedrals - 'AngleAngle Coeffs', # class2 impropers - 'Angles By Type', # new. not standard LAMMPS - 'Dihedrals By Type',# new. not standard LAMMPS - 'Angles By Type']) # new. not standard LAMMPS - - -def DeleteComments(string, - escape='\\', - comment_char='#'): - escaped_state = False - for i in range(0,len(string)): - if string[i] in escape: - if escaped_state: - escaped_state = False - else: - escaped_state = True - elif string[i] == comment_char: - if not escaped_state: - return string[0:i] - return string - - - -def ExtractDataSection(f, - section_name, - comment_char = '#', - include_section_name = False, - return_line_nums = False): - - inside_section = False - if section_name in ('header','Header'): #"Header" section includes beginning - inside_section = True - - nonblank_encountered = False - nonheader_encountered = False - - i = 0 - for line_orig in f: - return_this_line = False - line = DeleteComments(line_orig).strip() - if line in lammps_data_sections: - nonheader_encountered = True - if section_name in ('header', 'Header'): - # The "header" section includes all lines at the beginning of the - # before any other section is encountered. - if nonheader_encountered: - return_this_line = False - else: - return_this_line = True - elif line == section_name: - inside_section = True - nonblank_encountered = False - if include_section_name: - return_this_line = True - # A block of blank lines (which dont immediately follow - # the section_name) signal the end of a section: - elif len(line) == 0: - if inside_section and include_section_name: - return_this_line = True - if nonblank_encountered: - inside_section = False - elif line[0] != comment_char: - if inside_section: - nonblank_encountered = True - return_this_line = True - - if return_this_line: - if return_line_nums: - yield i - else: - yield line_orig - - i += 1 - - - -if __name__ == "__main__": - - import sys - lines = sys.stdin.readlines() - exclude_sections = False - if sys.argv[1] == '-n': - exclude_sections = True - del sys.argv[1] - - if not exclude_sections: - for section_name in sys.argv[1:]: - for line in ExtractDataSection(lines, section_name): - sys.stdout.write(line) - else: - line_nums_exclude = set([]) - for section_name in sys.argv[1:]: - for line_num in ExtractDataSection(lines, - section_name, - include_section_name=True, - return_line_nums=True): - line_nums_exclude.add(line_num) - for i in range(0, len(lines)): - if i not in line_nums_exclude: - sys.stdout.write(lines[i]) diff --git a/tools/moltemplate/src/ltemplify.py b/tools/moltemplate/src/ltemplify.py deleted file mode 100644 index 3ce6cb8e76..0000000000 --- a/tools/moltemplate/src/ltemplify.py +++ /dev/null @@ -1,3361 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -# Author: Andrew Jewett (jewett.aij at g mail) -# http://www.chem.ucsb.edu/~sheagroup -# License: 3-clause BSD License (See LICENSE.TXT) -# Copyright (c) 2012, Regents of the University of California -# All rights reserved. - -""" -ltemplify.py - -The "ltemplify.py" script can be used to convert existing LAMMPS -input script and data files into a single .lt file -(which includes both topology and force-field information - for a single molecule in your system). - -Example: - - ltemplify.py -name Mol file.in file.data > mol.lt - -This creates a template for a new type of molecule (named "Mol"), -consisting of all the atoms in the lammps files you included, -and saves this data in a single ttree file ("mol.lt"). -This file can be used with moltemplate (ttree) to -define large systems containing this molecule. - -""" - -import sys -from ttree_lex import * -from lttree_styles import * - - - -def Intify(s): - if s.isdigit(): - return int(s) - elif s[0:2] == 'id': - return int(s[2:]) - elif s[0:4] == 'type': - return int(s[4:]) - else: - return s - - -def IsNumber(s): - try: - float(s) - return True - except ValueError, TypeError: - return False - -def StringToInterval(sel_str, slice_delim='*'): - # Split a string into 1-3 tokens using the slice_delim and convert to int. - # What a mess. I should rewrite this function - - i_slice = sel_str.find(slice_delim) - - if i_slice == -1: - a = sel_str - b = sel_str - c = '' - else: - a = sel_str[:i_slice] - bc = sel_str[i_slice+len(slice_delim):] - b = '' - c = '' - i_slice = bc.find(slice_delim) - if i_slice == -1: - b = bc - c = '' - else: - b = bc[:i_slice] - c = bc[i_slice+len(slice_delim):] - - if a == '': - a = None - elif a.isdigit(): - a = int(a) - else: - raise InputError('Error: invalid selection string \"'+ - sel_str+'\"\n') - - if b == '': - b = None - elif b.isdigit(): - b = int(b) - else: - raise InputError('Error: invalid selection string \"'+ - sel_str+'\"\n') - - if c == '': - c = None - elif c.isdigit(): - c = int(c) - else: - raise InputError('Error: invalid selection string \"'+ - sel_str+'\"\n') - - if c == None: - return (a,b) - else: - return (a,b,c) - - - -# Selections are simply lists of 2-tuples (pairs) - -def LammpsSelectToIntervals(sel_str, slice_delim='*', or_delim=', '): - - """ - This function converts a string such as "1*4 6 9*12 50*70*10" into - a list of tuples, for example: [(1,4), (6,6), (9,12), (50,50), (60,60), (70,70)] - In general, the of intervals has the form: - [(a1,b1), (a2,b2), (a3,b3), ... ] - - An atom is considered to belong to this selection - if it happens to lie within the closed interval [a,b] - for any pair of a,b values in the list of intervals. - If for a given pair a,b, either a or b is "None", then that a or b - value is not used to disqualify membership in the interval. - (Similar to -infinity or +infinity. In other words if a is set to None, - then to belong to the interval it is enough to be less than b.) - - """ - selection_list = [] - #tokens = sel_str.split(or_delim) <-- Not what we want when len(or_delim)>1 - tokens = LineLex.TextBlock2Lines(sel_str, or_delim, keep_delim=False) - for token in tokens: - token = token.strip() - interval = StringToInterval(token, slice_delim) - - if len(interval)==2: - # Normally, "interval" should be a tuple containing 2 entries - selection_list.append(interval) - else: - assert(len(interval)==3) - # Handle 1000:2000:10 notation - # (corresponding to 1000, 1010, 1020, 1030, ..., 1990, 2000) - a=interval[0] - b=interval[1] - incr=interval[2] - i=a - while i<=b: - selection_list.append((i,i)) - i += incr - - return selection_list - - -def IntervalListToMinMax(interval_list): - min_a = None - max_b = None - for (a,b) in interval_list: - if ((not (type(a) is int)) or (not (type(b) is int))): - return None,None #only integer min/max makes sense. otherwise skip - - if (min_a == None) or (a < min_a): - min_a = a - if (max_b == None) or (b > max_b): - max_b = b - return min_a, max_b - - -def MergeIntervals(interval_list): - """ - A crude simple function that merges consecutive intervals in the list - whenever they overlap. (This function does not bother to compare - non-consecutive entries in the interval_list.) - - """ - i = 1 - while i < len(interval_list): - if ((interval_list[i-1][1] == None) or - (interval_list[i-1][1]+1 >= interval_list[i][0])): - interval_list[i-1] = (interval_list[i-1][0], interval_list[i][1]) - del interval_list[i] - else: - i += 1 - - -def BelongsToSel(i, sel): - if (i == None) or (sel == None) or (len(sel) == 0): - # If the user has not specified a selection for this category, - # then by default all objects are accepted - return True - - elif (type(i) is str): - if i.isdigit(): - i = int(i) - else: - return True - - belongs = False - for interval in sel: - assert(len(interval) == 2) - if interval[0]: - if i >= interval[0]: - if (interval[1] == None) or (i <= interval[1]): - belongs = True - break - elif interval[1]: - if i <= interval[1]: - belongs = True - break - else: - # In that case, the user entered something like "*" - # which covers all possible numbers - belongs = True - break - - return belongs - - - -try: - - g_program_name = __file__.split('/')[-1] # = 'ltemplify.py' - g_version_str = '0.51' - g_date_str = '2015-10-27' - sys.stderr.write(g_program_name+' v'+g_version_str+' '+g_date_str+'\n') - - non_empty_output = False - no_warnings = True - indent = 2 - cindent = 0 - atomid_selection = [] - atomtype_selection = [] - molid_selection = [] - mol_name = '' - - min_sel_atomid = None - min_sel_atomtype = None - min_sel_bondid = None - min_sel_bondtype = None - min_sel_angleid = None - min_sel_angletype = None - min_sel_dihedralid = None - min_sel_dihedraltype = None - min_sel_improperid = None - min_sel_impropertype = None - - max_sel_atomid = None - max_sel_atomtype = None - max_sel_bondid = None - max_sel_bondtype = None - max_sel_angleid = None - max_sel_angletype = None - max_sel_dihedralid = None - max_sel_dihedraltype = None - max_sel_improperid = None - max_sel_impropertype = None - - needed_atomids = set([]) - needed_atomtypes = set([]) - needed_molids = set([]) - needed_bondids = set([]) - needed_bondtypes = set([]) - needed_angleids = set([]) - needed_angletypes = set([]) - needed_dihedralids = set([]) - needed_dihedraltypes = set([]) - needed_improperids = set([]) - needed_impropertypes = set([]) - - min_needed_atomtype = None - max_needed_atomtype = None - min_needed_bondtype = None - max_needed_bondtype = None - min_needed_angletype = None - max_needed_angletype = None - min_needed_dihedraltype = None - max_needed_dihedraltype = None - min_needed_impropertype = None - max_needed_impropertype = None - - min_needed_atomid = None - max_needed_atomid = None - min_needed_molid = None - max_needed_molid = None - min_needed_bondid = None - max_needed_bondid = None - min_needed_angleid = None - max_needed_angleid = None - min_needed_dihedralid = None - max_needed_dihedralid = None - min_needed_improperid = None - max_needed_improperid = None - - - # To process the selections, we need to know the atom style: - atom_style_undefined = True - - i_atomid = None - i_atomtype = None - i_molid = None - i_x = None - i_y = None - i_z = None - - l_in_init = [] - l_in_settings = [] - l_in_masses = [] - l_in_pair_coeffs = [] - l_in_bond_coeffs = [] - l_in_angle_coeffs = [] - l_in_dihedral_coeffs = [] - l_in_improper_coeffs = [] - l_in_group = [] - l_in_fix_shake = [] - l_in_fix_rigid = [] - l_in_fix_poems = [] - l_in_fix_qeq = [] - l_in_fix_qmmm = [] - l_data_masses = [] - l_data_bond_coeffs = [] - l_data_angle_coeffs = [] - l_data_dihedral_coeffs = [] - l_data_improper_coeffs = [] - l_data_pair_coeffs = [] - l_data_pairij_coeffs = [] - l_data_atoms = [] - l_data_velocities = [] - l_data_bonds = [] - l_data_angles = [] - l_data_dihedrals = [] - l_data_impropers = [] - - # class2 force fields - #l_in_bondbond_coeffs = [] <--not needed, included in l_in_angle_coeff - #l_in_bondangle_coeffs = [] <--not needed, included in l_in_angle_coeff - #l_in_middlebondtorsion_coeffs = [] not needed, included in l_in_dihedral_coeff - #l_in_endbondtorsion_coeffs = [] <--not needed, included in l_in_dihedral_coeff - #l_in_angletorsion_coeffs = [] <--not needed, included in l_in_dihedral_coeff - #l_in_angleangletorsion_coeffs = [] not needed, included in l_in_dihedral_coeff - #l_in_bondbond13_coeffs = [] <--not needed, included in l_in_dihedral_coeff - #l_in_angleangle_coeffs = [] <--not needed, included in l_in_improper_coeff - l_data_bondbond_coeffs = [] - l_data_bondangle_coeffs = [] - l_data_middlebondtorsion_coeffs = [] - l_data_endbondtorsion_coeffs = [] - l_data_angletorsion_coeffs = [] - l_data_angleangletorsion_coeffs = [] - l_data_bondbond13_coeffs = [] - l_data_angleangle_coeffs = [] - - # non-point-like particles: - l_data_ellipsoids = [] - l_data_lines = [] - l_data_triangles = [] - - # automatic generation of bonded interactions by type: - l_data_angles_by_type = [] - l_data_dihedrals_by_type = [] - l_data_impropers_by_type = [] - - atoms_already_read = False - some_pair_coeffs_read = False - complained_atom_style_mismatch = False - infer_types_from_comments = False - remove_coeffs_from_data_file = True - - argv = [arg for arg in sys.argv] - - i = 1 - - while i < len(argv): - - #sys.stderr.write('argv['+str(i)+'] = \"'+argv[i]+'\"\n') - - if argv[i] == '-columns': - if i+1 >= len(argv): - raise InputError('Error: the \"'+argv[i]+'\" argument should be followed by a quoted\n' - ' string which contains a space-delimited list of the names of\n' - ' of columns in the \"Atoms\" section of the LAMMPS data file.\n' - ' If the list contains the symbols:\n' - ' \"atom-ID\" or \"atomid\", they are interpreted\n' - ' as unique atom ID numbers, and columns named\n' - ' \"atom-type\" or \"atomtype\" are interpreted\n' - ' as atom types. Finally, columns named\n' - ' \"molecule-ID\", \"molecule\", or \"mol-ID\", or \"mol\"\n' - ' are interpreted as unique molecule id numbers.\n' - 'Example:\n' - ' '+argv[i]+' \'atom-ID atom-type q polarizability molecule-ID x y z\'\n' - ' defines a custom atom_style containing the properties\n' - ' atom-ID atom-type q polarizability molecule-ID x y z\n' - ' Make sure you enclose the entire list in quotes.\n'); - column_names = argv[i+1].strip('\"\'').strip().split() - del argv[i:i+2] - - elif (argv[i] == '-ignore-comments'): - infer_types_from_comments = False - del argv[i:i+1] - - elif (argv[i] == '-infer-comments'): - infer_types_from_comments = True - del argv[i:i+1] - - elif ((argv[i] == '-name') or - (argv[i] == '-molname') or - (argv[i] == '-molecule-name') or - (argv[i] == '-molecule_name')): - if i+1 >= len(argv): - raise InputError('Error: '+argv[i]+' flag should be followed by a a molecule type name.\n') - cindent = 2 - indent += cindent - mol_name = argv[i+1] - del argv[i:i+2] - - elif ((argv[i].lower() == '-atomstyle') or - (argv[i].lower() == '-atom_style') or - (argv[i].lower() == '-atom-style')): - if i+1 >= len(argv): - raise InputError('Error: '+argv[i]+' flag should be followed by a an atom_style name.\n' - ' (or single quoted string which includes a space-separated\n' - ' list of column names).\n') - atom_style_undefined = False - column_names = AtomStyle2ColNames(argv[i+1]) - if (argv[i+1].strip().split()[0] in g_style_map): - l_in_init.append((' '*indent) + 'atom_style ' + argv[i+1] + '\n') - sys.stderr.write('\n \"Atoms\" column format:\n') - sys.stderr.write(' '+(' '.join(column_names))+'\n') - i_atomid, i_atomtype, i_molid = ColNames2AidAtypeMolid(column_names) - # Which columns contain the coordinates? - ii_coords = ColNames2Coords(column_names) - assert(len(ii_coords) == 1) - i_x = ii_coords[0][0] - i_y = ii_coords[0][1] - i_z = ii_coords[0][2] - - if i_molid: - sys.stderr.write(' (i_atomid='+str(i_atomid+1)+', i_atomtype='+str(i_atomtype+1)+', i_molid='+str(i_molid+1)+')\n\n') - else: - sys.stderr.write(' (i_atomid='+str(i_atomid+1)+', i_atomtype='+str(i_atomtype+1)+')\n') - del argv[i:i+2] - - elif ((argv[i].lower() == '-id') or - #(argv[i].lower() == '-a') or - #(argv[i].lower() == '-atoms') or - (argv[i].lower() == '-atomid') or - #(argv[i].lower() == '-atomids') or - (argv[i].lower() == '-atom-id') - #(argv[i].lower() == '-atom-ids') or - #(argv[i].lower() == '-$atom') or - #(argv[i].lower() == '-$atoms') - ): - if i+1 >= len(argv): - raise InputError('Error: '+argv[i]+' flag should be followed by a list of integers\n' - ' (or strings). These identify the group of atoms you want to\n' - ' to include in the template you are creating.\n') - atomid_selection += LammpsSelectToIntervals(argv[i+1]) - min_sel_atomid, max_sel_atomid = IntervalListToMinMax(atomid_selection) - del argv[i:i+2] - elif ((argv[i].lower() == '-datacoeffs') or - (argv[i].lower() == '-datacoeff') or - (argv[i].lower() == '-Coeff') or - (argv[i].lower() == '-Coeffs')): - remove_coeffs_from_data_file = False - del argv[i:i+1] - elif ((argv[i].lower() == '-type') or - #(argv[i].lower() == '-t') or - (argv[i].lower() == '-atomtype') or - (argv[i].lower() == '-atom-type') - #(argv[i].lower() == '-atomtypes') or - #(argv[i].lower() == '-atom-types') or - #(argv[i].lower() == '-@atom') or - #(argv[i].lower() == '-@atoms') or - #(argv[i].lower() == '-@atomtype') or - #(argv[i].lower() == '-@atomtypes') - ): - if i+1 >= len(argv): - raise InputError('Error: '+argv[i]+' flag should be followed by a list of integers.\n' - ' (or strings). These identify the group of atom types you want to\n' - ' to include in the template you are creating.\n') - atomtype_selection += LammpsSelectToIntervals(argv[i+1]) - min_sel_atomtype, max_sel_atomtype = IntervalListToMinMax(atomtype_selection) - del argv[i:i+2] - elif ((argv[i].lower() == '-mol') or - #(argv[i].lower() == '-m') or - (argv[i].lower() == '-molid') or - #(argv[i].lower() == '-molids') or - (argv[i].lower() == '-mol-id') or - #(argv[i].lower() == '-mol-ids') or - #(argv[i].lower() == '-molecule') or - (argv[i].lower() == '-moleculeid') or - (argv[i].lower() == '-molecule-id') - #(argv[i].lower() == '-molecules') or - #(argv[i].lower() == '-molecule-ids') or - #(argv[i].lower() == '-$mol') or - #(argv[i].lower() == '-$molecule') - ): - if i+1 >= len(argv): - sys.stderr.write('Error: '+argv[i]+' flag should be followed by a list of integers.\n' - ' (or strings). These identify the group of molecules you want to\n' - ' include in the template you are creating.\n') - molid_selection += LammpsSelectToIntervals(argv[i+1]) - del argv[i:i+2] - else: - i += 1 - - # We might need to parse the simulation boundary-box. - # If so, use these variables. (None means uninitialized.) - boundary_xlo = None - boundary_xhi = None - boundary_ylo = None - boundary_yhi = None - boundary_zlo = None - boundary_zhi = None - boundary_xy = None - boundary_yz = None - boundary_xz = None - - # atom type names - atomtypes_name2int = {} - atomtypes_int2name = {} - #atomids_name2int = {} not needed - atomids_int2name = {} - atomids_by_type = {} - - - if atom_style_undefined: - # The default atom_style is "full" - column_names = AtomStyle2ColNames('full') - i_atomid, i_atomtype, i_molid = ColNames2AidAtypeMolid(column_names) - # Which columns contain the coordinates? - ii_coords = ColNames2Coords(column_names) - assert(len(ii_coords) == 1) - i_x = ii_coords[0][0] - i_y = ii_coords[0][1] - i_z = ii_coords[0][2] - - #--------------------------------------------------------- - #-- The remaining arguments are files that the user wants - #-- us to read and convert. It is typical to have - #-- multiple input files, because LAMMPS users often - #-- store their force field parameters in either the LAMMPS - #-- data files and input script files, or both. - #-- We want to search all of the LAMMPS input files in - #-- order to make sure we extracted all the force field - #-- parameters (coeff commands). - #--------------------------------------------------------- - - for i_arg in range(1,len(argv)): - fname = argv[i_arg] - try: - lammps_file = open(fname, 'r') - except IOError: - raise InputError('Error: unrecognized argument (\"'+fname+'\"),\n' - ' OR unable to open file:\n' - '\n' - ' \"'+fname+'\"\n' - ' for reading.\n' - '\n' - ' (If you were not trying to open a file with this name,\n' - ' then there is a problem in your argument list.)\n') - - sys.stderr.write('reading file \"'+fname+'\"\n') - - atomid2type = {} - atomid2mol = {} - data_file_header_names = set(['LAMMPS Description', - 'Atoms', 'Masses', 'Velocities', 'Bonds', - 'Angles', 'Dihedrals', 'Impropers', - 'Pair Coeffs', - 'Bond Coeffs', 'Angle Coeffs', - 'Dihedral Coeffs', 'Improper Coeffs', - #class2 force fields: - 'BondBond Coeffs', 'BondAngle Coeffs', - 'MiddleBondTorsion Coeffs', 'EndBondTorsion Coeffs', - 'AngleTorsion Coeffs', 'AngleAngleTorsion Coeffs', - 'BondBond13 Coeffs', - 'AngleAngle Coeffs', - # non-point-like particles: - 'Ellipsoids', 'Triangles', 'Lines', - #specifying bonded interactions by type: - 'Angles By Type', 'Dihedrals By Type', 'Impropers By Type' - ]) - - lex=LineLex(lammps_file, fname) - lex.source_triggers = set(['include','import']) - # set up lex to accept most characters in file names: - lex.wordterminators = '(){}' + lex.whitespace - # set up lex to understand the "include" statement: - lex.source = 'include' - lex.escape = '\\' - - while lex: - infile = lex.infile - lineno = lex.lineno - line = lex.ReadLine() - if (lex.infile != infile): - infile = lex.infile - lineno = lex.lineno - - #sys.stderr.write(' processing \"'+line.strip()+'\", (\"'+infile+'\":'+str(lineno)+')\n') - - if line == '': - break - - tokens = line.strip().split() - if (len(tokens) > 0): - if ((tokens[0] == 'atom_style') and - atom_style_undefined): - - sys.stderr.write(' Atom Style found. Processing: \"'+line.strip()+'\"\n') - if atoms_already_read: - raise InputError('Error: The file containing the \"atom_style\" command must\n' - ' come before the data file in the argument list.\n' - ' (The templify program needs to know the atom style before reading\n' - ' the data file. Either change the order of arguments so that the\n' - ' LAMMPS input script file is processed before the data file, or use\n' - ' the \"-atom_style\" command line argument to specify the atom_style.)\n') - - column_names = AtomStyle2ColNames(line.split()[1]) - i_atomid, i_atomtype, i_molid = ColNames2AidAtypeMolid(column_names) - # Which columns contain the coordinates? - ii_coords = ColNames2Coords(column_names) - assert(len(ii_coords) == 1) - i_x = ii_coords[0][0] - i_y = ii_coords[0][1] - i_z = ii_coords[0][2] - - sys.stderr.write('\n \"Atoms\" column format:\n') - sys.stderr.write(' '+(' '.join(column_names))+'\n') - if i_molid: - sys.stderr.write(' (i_atomid='+str(i_atomid+1)+', i_atomtype='+str(i_atomtype+1)+', i_molid='+str(i_molid+1)+')\n\n') - else: - sys.stderr.write(' (i_atomid='+str(i_atomid+1)+', i_atomtype='+str(i_atomtype+1)+')\n\n') - l_in_init.append((' '*indent)+line.lstrip()) - - elif (tokens[0] in set(['units', - 'angle_style', - 'bond_style', - 'dihedral_style', - 'improper_style', - 'min_style', - 'pair_style', - 'pair_modify', - 'special_bonds', - 'kspace_style', - 'kspace_modify'])): - l_in_init.append((' '*indent)+line.lstrip()) - - #if (line.strip() == 'LAMMPS Description'): - # sys.stderr.write(' reading \"'+line.strip()+'\"\n') - # # skip over this section - # while lex: - # line = lex.ReadLine() - # if line.strip() in data_file_header_names: - # lex.push_raw_text(line) # <- Save line for later - # break - - elif (line.strip() == 'Atoms'): - sys.stderr.write(' reading \"'+line.strip()+'\"\n') - atoms_already_read = True - - # Before attempting to read atomic coordinates, first find - # the lattice vectors of the simulation's boundary box: - # Why do we care about the Simulation Boundary? - # Some LAMMPS data files store atomic coordinates in a - # complex format with 6 numbers, 3 floats, and 3 integers. - # The 3 floats are x,y,z coordinates. Any additional numbers - # following these are integers which tell LAMMPS which cell - # the particle belongs to, (in case it has wandered out of - # the original periodic boundary box). In order to find - # the true location of the particle, we need to offset that - # particle's position with the unit-cell lattice vectors: - # avec, bvec, cvec (or multiples thereof) - # avec, bvec, cvec are the axis of the parallelepiped which - # define the simulation's boundary. They are described here: - #http://lammps.sandia.gov/doc/Section_howto.html#howto-12 - if ((boundary_xlo==None) or (boundary_xhi==None) or - (boundary_ylo==None) or (boundary_yhi==None) or - (boundary_zlo==None) or (boundary_zhi==None)): - - raise InputError('Error: Either DATA file lacks a boundary-box header, or it is in the wrong\n' - ' place. At the beginning of the file, you need to specify the box size:\n' - ' xlo xhi ylo yhi zlo zhi (and xy xz yz if triclinic)\n' - ' These numbers should appear BEFORE the other sections in the data file\n' - ' (such as the \"Atoms\", \"Masses\", \"Bonds\", \"Pair Coeffs\" sections)\n' - '\n' - ' Use this format (example):\n' - ' -100.0 100.0 xhi xlo\n' - ' 0.0 200.0 yhi ylo\n' - ' -25.0 50.0 zhi zlo\n' - '\n' - 'For details, see http://lammps.sandia.gov/doc/read_data.html\n' - '\n' - ' (NOTE: If the atom coordinates are NOT followed by integers, then\n' - ' these numbers are all ignored, however you must still specify\n' - ' xlo, xhi, ylo, yhi, zlo, zhi. You can set them all to 0.0.)\n') - - if not (boundary_xy and boundary_yz and boundary_xz): - # Then use a simple rectangular boundary box: - avec = (boundary_xhi-boundary_xlo, 0.0, 0.0) - bvec = (0.0, boundary_yhi-boundary_ylo, 0.0) - cvec = (0.0, 0.0, boundary_zhi-boundary_zlo) - else: - # Triclinic geometry in LAMMPS is explained here: - # http://lammps.sandia.gov/doc/Section_howto.html#howto-12 - # http://lammps.sandia.gov/doc/read_data.html - avec = (boundary_xhi-boundary_xlo, 0.0, 0.0) - bvec = (boundary_xy, boundary_yhi-boundary_ylo, 0.0) - cvec = (boundary_xz, boundary_yz, boundary_zhi-boundary_zlo) - - - while lex: - line = lex.ReadLine() - if line.strip() in data_file_header_names: - lex.push_raw_text(line) # <- Save line for later - break - tokens = line.strip().split() - if len(tokens) > 0: - if ((len(tokens) <= i_atomid) or - (len(tokens) <= i_atomtype) or - ((i_molid != None) and - (len(tokens) <= i_molid))): - raise InputError('Error: The number of columns in the \"Atoms\" section does\n' - ' not match the atom_style (see column name list above).\n') - elif ((len(tokens) != len(column_names)) and - (len(tokens) != len(column_names)+3) and - (not complained_atom_style_mismatch)): - complained_atom_style_mismatch = True - sys.stderr.write('Warning: The number of columns in the \"Atoms\" section does\n' - ' not match the atom_style (see column name list above).\n') - # this is not a very serious warning. - #no_warnings = False <--no need. commenting out - - - atomid = Intify(tokens[i_atomid]) - atomtype = Intify(tokens[i_atomtype]) - - molid = None - if i_molid: - molid = Intify(tokens[i_molid]) - - atomid2type[atomid] = atomtype - if i_molid: - atomid2mol[atomid] = molid - - - if (BelongsToSel(atomid, atomid_selection) and - BelongsToSel(atomtype, atomtype_selection) and - BelongsToSel(molid, molid_selection)): - - tokens[i_atomid] = '$atom:id'+tokens[i_atomid] - #tokens[i_atomid] = '$atom:'+atomids_int2name[atomid] - # fill atomtype_int2str[] with a default name (change later): - #tokens[i_atomtype] = '@atom:type'+tokens[i_atomtype] - atomtype_name = 'type'+tokens[i_atomtype] - atomtypes_int2name[atomtype] = atomtype_name - tokens[i_atomtype] = '@atom:'+atomtype_name - - # Interpreting unit-cell counters - # If present, then unit-cell "flags" must be - # added to the x,y,z coordinates. - # - # For more details on unit-cell "flags", see: - # http://lammps.sandia.gov/doc/read_data.html - # "In the data file, atom lines (all lines or - # none of them) can optionally list 3 trailing - # integer values (nx,ny,nz), which are used to - # initialize the atom’s image flags. - # If nx,ny,nz values are not listed in the - # data file, LAMMPS initializes them to 0. - # Note that the image flags are immediately - # updated if an atom’s coordinates need to - # wrapped back into the simulation box." - - if (len(tokens) == len(column_names)+3): - nx = int(tokens[-3]) - ny = int(tokens[-2]) - nz = int(tokens[-1]) - x = float(tokens[i_x]) + nx*avec[0]+ny*bvec[0]+nz*cvec[0] - y = float(tokens[i_y]) + nx*avec[1]+ny*bvec[1]+nz*cvec[1] - z = float(tokens[i_z]) + nx*avec[2]+ny*bvec[2]+nz*cvec[2] - tokens[i_x] = str(x) - tokens[i_y] = str(y) - tokens[i_z] = str(z) - # Now get rid of them: - del tokens[-3:] - - - - # I can't use atomids_int2name or atomtypes_int2name yet - # because they probably have not been defined yet. - # (Instead assign these names in a later pass.) - - if i_molid: - tokens[i_molid] = '$mol:id'+tokens[i_molid] - l_data_atoms.append((' '*indent)+(' '.join(tokens)+'\n')) - needed_atomids.add(atomid) - - needed_atomtypes.add(atomtype) - # Not all atom_styles have molids. - # Check for this before adding. - if molid != None: - needed_molids.add(molid) - - for atomtype in needed_atomtypes: - assert(type(atomtype) is int) - if ((min_needed_atomtype == None) or - (min_needed_atomtype > atomtype)): - min_needed_atomtype = atomtype - if ((max_needed_atomtype == None) or - (max_needed_atomtype < atomtype)): - max_needed_atomtype = atomtype - - for atomid in needed_atomids: - assert(type(atomid) is int) - if ((min_needed_atomid == None) or - (min_needed_atomid > atomid)): - min_needed_atomid = atomid - if ((max_needed_atomid == None) or - (max_needed_atomid < atomid)): - max_needed_atomid = atomid - for molid in needed_molids: - assert(type(molid) is int) - if ((min_needed_molid == None) or - (min_needed_molid > molid)): - min_needed_molid = molid - if ((max_needed_molid == None) or - (max_needed_molid < molid)): - max_needed_molid = molid - - elif (line.strip() == 'Masses'): - sys.stderr.write(' reading \"'+line.strip()+'\"\n') - while lex: - # Read the next line of text but don't skip comments - comment_char_backup = lex.commenters - lex.commenters = '' - line = lex.ReadLine() - lex.commenters = comment_char_backup - - comment_text = '' - ic = line.find('#') - if ic != -1: - line = line[:ic] - comment_text = line[ic+1:].strip() - line = line.rstrip() - - if line.strip() in data_file_header_names: - lex.push_raw_text(line) # <- Save line for later - break - - tokens = line.strip().split() - if len(tokens) > 0: - atomtype = Intify(tokens[0]) - atomtype_name = str(atomtype) - - if comment_text != '': - comment_tokens = comment_text.split() - # Assume the first word after the # is the atom type name - atomtype_name = comment_tokens[0] - - if BelongsToSel(atomtype, atomtype_selection): - #tokens[0] = '@atom:type'+tokens[0] - l_data_masses.append((' '*indent)+(' '.join(tokens)+'\n')) - # infer atom type names from comment strings? - if infer_types_from_comments: - if atomtype_name in atomtypes_name2int: - raise InputError('Error: duplicate atom type names in mass section: \"'+atomtype_name+'\"\n' - ' (By default '+g_program_name+' attempts to infer atom type names from\n' - ' comments which appear in the \"Masses\" section of your data file.)\n' - ' You can avoid this error by adding the \"-ignore-comments\" argument.\n') - atomtypes_name2int[atomtype_name] = atomtype - atomtypes_int2name[atomtype] = atomtype_name - else: - atomtypes_int2name[atomtype] = 'type'+str(atomtype) - - - elif (line.strip() == 'Velocities'): - sys.stderr.write(' reading \"'+line.strip()+'\"\n') - while lex: - line = lex.ReadLine() - if line.strip() in data_file_header_names: - lex.push_raw_text(line) # <- Save line for later - break - tokens = line.strip().split() - if len(tokens) > 0: - atomid = Intify(tokens[0]) - atomtype = None - if atomid in atomid2type: - atomtype = atomid2type[atomid] - moldid = None - if atomid in atomid2mol: - molid = atomid2mol[atomid] - if (BelongsToSel(atomid, atomid_selection) and - BelongsToSel(atomtype, atomtype_selection) and - BelongsToSel(molid, molid_selection)): - tokens[0] = '$atom:id'+tokens[0] - #tokens[0] = '$atom:'+atomids_int2name[atomid] - #NOTE:I can't use "atomids_int2name" yet because - # they probably have not been defined yet. - # (Instead assign these names in a later pass.) - l_data_velocities.append((' '*indent)+(' '.join(tokens)+'\n')) - - # non-point-like-particles: - elif (line.strip() == 'Ellipsoids'): - sys.stderr.write(' reading \"'+line.strip()+'\"\n') - while lex: - line = lex.ReadLine() - if line.strip() in data_file_header_names: - lex.push_raw_text(line) # <- Save line for later - break - tokens = line.strip().split() - if len(tokens) > 0: - atomid = Intify(tokens[0]) - atomtype = None - if atomid in atomid2type: - atomtype = atomid2type[atomid] - moldid = None - if atomid in atomid2mol: - molid = atomid2mol[atomid] - if (BelongsToSel(atomid, atomid_selection) and - BelongsToSel(atomtype, atomtype_selection) and - BelongsToSel(molid, molid_selection)): - tokens[0] = '$atom:id'+tokens[0] - #tokens[0] = '$atom:'+atomids_int2name[atomid] - #NOTE:I can't use "atomids_int2name" yet because - # they probably have not been defined yet. - # (Instead assign these names in a later pass.) - l_data_ellipsoids.append((' '*indent)+(' '.join(tokens)+'\n')) - elif (line.strip() == 'Lines'): - sys.stderr.write(' reading \"'+line.strip()+'\"\n') - while lex: - line = lex.ReadLine() - if line.strip() in data_file_header_names: - lex.push_raw_text(line) # <- Save line for later - break - tokens = line.strip().split() - if len(tokens) > 0: - atomid = Intify(tokens[0]) - atomtype = None - if atomid in atomid2type: - atomtype = atomid2type[atomid] - moldid = None - if atomid in atomid2mol: - molid = atomid2mol[atomid] - if (BelongsToSel(atomid, atomid_selection) and - BelongsToSel(atomtype, atomtype_selection) and - BelongsToSel(molid, molid_selection)): - tokens[0] = '$atom:id'+tokens[0] - #tokens[0] = '$atom:'+atomids_int2name[atomid] - #NOTE:I can't use "atomids_int2name" yet because - # they probably have not been defined yet. - # (Instead assign these names in a later pass.) - l_data_lines.append((' '*indent)+(' '.join(tokens)+'\n')) - elif (line.strip() == 'Triangles'): - sys.stderr.write(' reading \"'+line.strip()+'\"\n') - while lex: - line = lex.ReadLine() - if line.strip() in data_file_header_names: - lex.push_raw_text(line) # <- Save line for later - break - tokens = line.strip().split() - if len(tokens) > 0: - atomid = Intify(tokens[0]) - atomtype = None - if atomid in atomid2type: - atomtype = atomid2type[atomid] - moldid = None - if atomid in atomid2mol: - molid = atomid2mol[atomid] - if (BelongsToSel(atomid, atomid_selection) and - BelongsToSel(atomtype, atomtype_selection) and - BelongsToSel(molid, molid_selection)): - tokens[0] = '$atom:id'+tokens[0] - #tokens[0] = '$atom:'+atomids_int2name[atomid] - #NOTE:I can't use "atomids_int2name" yet because - # they probably have not been defined yet. - # (Instead assign these names in a later pass.) - l_data_triangles.append((' '*indent)+(' '.join(tokens)+'\n')) - - elif (line.strip() == 'Bonds'): - sys.stderr.write(' reading \"'+line.strip()+'\"\n') - while lex: - line = lex.ReadLine() - if line.strip() in data_file_header_names: - lex.push_raw_text(line) # <- Save line for later - break - tokens = line.strip().split() - if len(tokens) > 0: - if (len(tokens) < 4): - raise InputError('Error: near or before '+ErrorLeader(infile, lineno)+'\n' - ' Nonsensical line in Bonds section:\n' - ' \"'+line.strip()+'\"\n') - #tokens[0] = '$bond:id'+tokens[0] - #tokens[1] = '@bond:type'+tokens[1] - atomids = [None, None] - atomtypes = [None, None] - molids = [None, None] - in_selections = True - some_in_selection = False - for n in range(0,2): - atomids[n] = Intify(tokens[2+n]) - if atomids[n] in atomid2type: - atomtypes[n] = atomid2type[atomids[n]] - if atomids[n] in atomid2mol: - molids[n] = atomid2mol[atomids[n]] - if (BelongsToSel(atomids[n], atomid_selection) and - BelongsToSel(atomtypes[n], atomtype_selection) and - BelongsToSel(molids[n], molid_selection)): - #tokens[2+n] = '$atom:id'+tokens[2+n] - #tokens[2+n] = '$atom:'+atomids_int2name[atomids[n]] - some_in_selection = True - else: - in_selections = False - if in_selections: - l_data_bonds.append((' '*indent)+(' '.join(tokens)+'\n')) - elif some_in_selection: - sys.stderr.write('WARNING: SELECTION BREAKS BONDS\n') - sys.stderr.write(' (between atom ids: ') - - for n in range(0,2): - sys.stderr.write(str(atomids[n])+' ') - sys.stderr.write(')\n' - ' The atoms you selected are bonded\n' - ' to other atoms you didn\'t select.\n' - ' Are you sure you selected the correct atoms?\n') - no_warnings = False - - - - elif (line.strip() == 'Angles'): - sys.stderr.write(' reading \"'+line.strip()+'\"\n') - while lex: - line = lex.ReadLine() - if line == '': - break - if line.strip() in data_file_header_names: - lex.push_raw_text(line) # <- Save line for later - break - tokens = line.strip().split() - if len(tokens) > 0: - if (len(tokens) < 5): - raise InputError('Error: near or before '+ErrorLeader(infile, lineno)+'\n' - ' Nonsensical line in Angles section:\n' - ' \"'+line.strip()+'\"\n') - #tokens[0] = '$angle:id'+tokens[0] - #tokens[1] = '@angle:type'+tokens[1] - atomids = [None, None, None] - atomtypes = [None, None, None] - molids = [None, None, None] - in_selections = True - some_in_selection = False - for n in range(0,3): - atomids[n] = Intify(tokens[2+n]) - if atomids[n] in atomid2type: - atomtypes[n] = atomid2type[atomids[n]] - if atomids[n] in atomid2mol: - molids[n] = atomid2mol[atomids[n]] - if (BelongsToSel(atomids[n], atomid_selection) and - BelongsToSel(atomtypes[n], atomtype_selection) and - BelongsToSel(molids[n], molid_selection)): - #tokens[2+n] = '$atom:id'+tokens[2+n] - #tokens[2+n] = '$atom:'+atomids_int2name[atomids[n]] - some_in_selection = True - else: - in_selections = False - if in_selections: - l_data_angles.append((' '*indent)+(' '.join(tokens)+'\n')) - elif some_in_selection: - sys.stderr.write('WARNING: SELECTION BREAKS ANGLES\n') - sys.stderr.write(' (between atom ids: ') - for n in range(0,3): - sys.stderr.write(str(atomids[n])+' ') - sys.stderr.write(')\n' - ' The atoms you selected participate in 3-body \"Angle\"\n' - ' interactions with other atoms you didn\'t select.\n' - ' (They will be ignored.)\n' - ' Are you sure you selected the correct atoms?\n') - no_warnings = False - - - elif (line.strip() == 'Dihedrals'): - sys.stderr.write(' reading \"'+line.strip()+'\"\n') - while lex: - line = lex.ReadLine() - if line.strip() in data_file_header_names: - lex.push_raw_text(line) # <- Save line for later - break - tokens = line.strip().split() - if len(tokens) > 0: - if (len(tokens) < 6): - raise InputError('Error: near or before '+ErrorLeader(infile, lineno)+'\n' - ' Nonsensical line in Dihedrals section:\n' - ' \"'+line.strip()+'\"\n') - #tokens[0] = '$dihedral:id'+tokens[0] - #tokens[1] = '@dihedral:type'+tokens[1] - atomids = [None, None, None, None] - atomtypes = [None, None, None, None] - molids = [None, None, None, None] - in_selections = True - some_in_selection = False - for n in range(0,4): - atomids[n] = Intify(tokens[2+n]) - if atomids[n] in atomid2type: - atomtypes[n] = atomid2type[atomids[n]] - if atomids[n] in atomid2mol: - molids[n] = atomid2mol[atomids[n]] - if (BelongsToSel(atomids[n], atomid_selection) and - BelongsToSel(atomtypes[n], atomtype_selection) and - BelongsToSel(molids[n], molid_selection)): - #tokens[2+n] = '$atom:id'+tokens[2+n] - #tokens[2+n] = '$atom:'+atomids_int2name[atomids[n]] - some_in_selection = True - else: - in_selections = False - if in_selections: - l_data_dihedrals.append((' '*indent)+(' '.join(tokens)+'\n')) - elif some_in_selection: - sys.stderr.write('WARNING: SELECTION BREAKS DIHEDRALS\n') - sys.stderr.write(' (between atom ids: ') - for n in range(0,4): - sys.stderr.write(str(atomids[n])+' ') - sys.stderr.write(')\n' - ' The atoms you selected participate in 4-body \"Dihedral\"\n' - ' interactions with other atoms you didn\'t select.\n' - ' (They will be ignored.)\n' - ' Are you sure you selected the correct atoms?\n') - no_warnings = False - - - elif (line.strip() == 'Impropers'): - sys.stderr.write(' reading \"'+line.strip()+'\"\n') - while lex: - line = lex.ReadLine() - if line.strip() in data_file_header_names: - lex.push_raw_text(line) # <- Save line for later - break - tokens = line.strip().split() - if len(tokens) > 0: - if (len(tokens) < 6): - raise InputError('Error: near or before '+ErrorLeader(infile, lineno)+'\n' - ' Nonsensical line in Impropers section:\n' - ' \"'+line.strip()+'\"\n') - #tokens[0] = '$improper:id'+tokens[0] - #tokens[1] = '@improper:type'+tokens[1] - atomids = [None, None, None, None] - atomtypes = [None, None, None, None] - molids = [None, None, None, None] - in_selections = True - some_in_selection = False - for n in range(0,4): - atomids[n] = Intify(tokens[2+n]) - if atomids[n] in atomid2type: - atomtypes[n] = atomid2type[atomids[n]] - if atomids[n] in atomid2mol: - molids[n] = atomid2mol[atomids[n]] - if (BelongsToSel(atomids[n], atomid_selection) and - BelongsToSel(atomtypes[n], atomtype_selection) and - BelongsToSel(molids[n], molid_selection)): - #tokens[2+n] = '$atom:id'+tokens[2+n] - #tokens[2+n] = '$atom:'+atomids_int2name[atomids[n]] - some_in_selection = True - else: - in_selections = False - if in_selections: - l_data_impropers.append((' '*indent)+(' '.join(tokens)+'\n')) - elif some_in_selection: - sys.stderr.write('WARNING: SELECTION BREAKS IMPROPERS\n') - sys.stderr.write(' (between atom ids: ') - for n in range(0,4): - sys.stderr.write(str(atomids[n])+' ') - sys.stderr.write(')\n' - ' The atoms you selected participate in 4-body \"Improper\"\n' - ' interactions with other atoms you didn\'t select.\n' - ' (They will be ignored.)\n' - ' Are you sure you selected the correct atoms?\n') - no_warnings = False - - - elif (line.strip() == 'Bond Coeffs'): - sys.stderr.write(' reading \"'+line.strip()+'\"\n') - while lex: - line = lex.ReadLine() - if line.strip() in data_file_header_names: - lex.push_raw_text(line) # <- Save line for later - break - tokens = line.strip().split() - if len(tokens) > 0: - #tokens[0] = '@bond:type'+tokens[0] - l_data_bond_coeffs.append((' '*indent)+(' '.join(tokens)+'\n')) - - elif (line.strip() == 'Angle Coeffs'): - sys.stderr.write(' reading \"'+line.strip()+'\"\n') - while lex: - line = lex.ReadLine() - if line.strip() in data_file_header_names: - lex.push_raw_text(line) # <- Save line for later - break - tokens = line.strip().split() - if len(tokens) > 0: - #tokens[0] = '@angle:type'+tokens[0] - l_data_angle_coeffs.append((' '*indent)+(' '.join(tokens)+'\n')) - - elif (line.strip() == 'Dihedral Coeffs'): - sys.stderr.write(' reading \"'+line.strip()+'\"\n') - while lex: - line = lex.ReadLine() - if line.strip() in data_file_header_names: - lex.push_raw_text(line) # <- Save line for later - break - tokens = line.strip().split() - if len(tokens) > 0: - #tokens[0] = '@dihedral:type'+tokens[0] - l_data_dihedral_coeffs.append((' '*indent)+(' '.join(tokens)+'\n')) - - elif (line.strip() == 'Improper Coeffs'): - sys.stderr.write(' reading \"'+line.strip()+'\"\n') - while lex: - line = lex.ReadLine() - if line.strip() in data_file_header_names: - lex.push_raw_text(line) # <- Save line for later - break - tokens = line.strip().split() - if len(tokens) > 0: - #tokens[0] = '@improper:type'+tokens[0] - l_data_improper_coeffs.append((' '*indent)+(' '.join(tokens)+'\n')) - - elif (line.strip() == 'Pair Coeffs'): - sys.stderr.write(' reading \"'+line.strip()+'\"\n') - some_pair_coeffs_read = True - while lex: - line = lex.ReadLine() - if line.strip() in data_file_header_names: - lex.push_raw_text(line) # <- Save line for later - break - tokens = line.strip().split() - if len(tokens) > 0: - if (len(tokens) < 2): - raise InputError('Error: near or before '+ErrorLeader(infile, lineno)+'\n' - ' Nonsensical line in Pair Coeffs section:\n' - ' \"'+line.strip()+'\"\n') - atomtype_i_str = tokens[0] - if '*' in atomtype_i_str: - raise InputError('PROBLEM near or before '+ErrorLeader(infile, lineno)+'\n' - ' As of 2015-8, moltemplate forbids use of the "\*\" wildcard\n' - ' character in the \"Pair Coeffs\" section.\n') - else: - i = int(atomtype_i_str) - if ((not i) or - BelongsToSel(i, atomtype_selection)): - i_str = '@atom:type'+str(i) - tokens[0] = i_str - l_data_pair_coeffs.append((' '*indent)+(' '.join(tokens)+'\n')) - - elif (line.strip() == 'PairIJ Coeffs'): - sys.stderr.write(' reading \"'+line.strip()+'\"\n') - some_pair_coeffs_read = True - while lex: - line = lex.ReadLine() - if line.strip() in data_file_header_names: - lex.push_raw_text(line) # <- Save line for later - break - tokens = line.strip().split() - if len(tokens) > 0: - if (len(tokens) < 2): - raise InputError('Error: near or before '+ErrorLeader(infile, lineno)+'\n' - ' Nonsensical line in Pair Coeffs section:\n' - ' \"'+line.strip()+'\"\n') - atomtype_i_str = tokens[0] - atomtype_j_str = tokens[1] - if (('*' in atomtype_i_str) or ('*' in atomtype_j_str)): - raise InputError('PROBLEM near or before '+ErrorLeader(infile, lineno)+'\n' - ' As of 2015-8, moltemplate forbids use of the "\*\" wildcard\n' - ' character in the \"PairIJ Coeffs\" section.\n') - else: - i = int(atomtype_i_str) - j = int(atomtype_j_str) - if (((not i) or BelongsToSel(i, atomtype_selection)) and - ((not j) or BelongsToSel(j, atomtype_selection))): - i_str = '@atom:type'+str(i) - j_str = '@atom:type'+str(j) - tokens[0] = i_str - tokens[1] = j_str - l_data_pair_coeffs.append((' '*indent)+(' '.join(tokens)+'\n')) - - elif (tokens[0] == 'pair_coeff'): - some_pair_coeffs_read = True - if (len(tokens) < 3): - raise InputError('Error: near or before '+ErrorLeader(infile, lineno)+'\n' - ' Nonsensical pair_coeff command:\n' - ' \"'+line.strip()+'\"\n') - l_in_pair_coeffs.append(' '*indent+line.strip()) - - elif (tokens[0] == 'mass'): - some_pair_coeffs_read = True - if (len(tokens) < 3): - raise InputError('Error: near or before '+ErrorLeader(infile, lineno)+'\n' - ' Nonsensical \"mass\" command:\n' - ' \"'+line.strip()+'\"\n') - l_in_masses.append((' '*indent)+(' '.join(tokens)+'\n')) - - elif (tokens[0] == 'bond_coeff'): - if (len(tokens) < 2): - raise InputError('Error: near or before '+ErrorLeader(infile, lineno)+'\n' - ' Nonsensical bond_coeff command:\n' - ' \"'+line.strip()+'\"\n') - #tokens[1] = '@bond:type'+tokens[1] - l_in_bond_coeffs.append((' '*indent)+(' '.join(tokens)+'\n')) - - elif (tokens[0] == 'angle_coeff'): - if (len(tokens) < 2): - raise InputError('Error: near or before '+ErrorLeader(infile, lineno)+'\n' - ' Nonsensical angle_coeff command:\n' - ' \"'+line.strip()+'\"\n') - #tokens[1] = '@angle:type'+tokens[1] - l_in_angle_coeffs.append((' '*indent)+(' '.join(tokens)+'\n')) - - elif (tokens[0] == 'dihedral_coeff'): - if (len(tokens) < 2): - raise InputError('Error: near or before '+ErrorLeader(infile, lineno)+'\n' - ' Nonsensical dihedral_coeff command:\n' - ' \"'+line.strip()+'\"\n') - #tokens[1] = '@dihedral:type'+tokens[1] - l_in_dihedral_coeffs.append((' '*indent)+(' '.join(tokens)+'\n')) - elif (tokens[0] == 'improper_coeff'): - if (len(tokens) < 2): - raise InputError('Error: near or before '+ErrorLeader(infile, lineno)+'\n' - ' Nonsensical improper_coeff command:\n' - ' \"'+line.strip()+'\"\n') - #tokens[1] = '@improper:type'+tokens[1] - l_in_improper_coeffs.append((' '*indent)+(' '.join(tokens)+'\n')) - - - # -- class2 force fields -- - elif (line.strip() == 'BondBond Coeffs'): - sys.stderr.write(' reading \"'+line.strip()+'\"\n') - while lex: - line = lex.ReadLine() - if line.strip() in data_file_header_names: - lex.push_raw_text(line) # <- Save line for later - break - tokens = line.strip().split() - if len(tokens) > 0: - #tokens[0] = '@angle:type'+tokens[0] - l_data_bondbond_coeffs.append((' '*indent)+(' '.join(tokens)+'\n')) - - elif (line.strip() == 'BondAngle Coeffs'): - sys.stderr.write(' reading \"'+line.strip()+'\"\n') - while lex: - line = lex.ReadLine() - if line.strip() in data_file_header_names: - lex.push_raw_text(line) # <- Save line for later - break - tokens = line.strip().split() - if len(tokens) > 0: - #tokens[0] = '@angle:type'+tokens[0] - l_data_bondangle_coeffs.append((' '*indent)+(' '.join(tokens)+'\n')) - - elif (line.strip() == 'MiddleBondTorsion Coeffs'): - sys.stderr.write(' reading \"'+line.strip()+'\"\n') - while lex: - line = lex.ReadLine() - if line.strip() in data_file_header_names: - lex.push_raw_text(line) # <- Save line for later - break - tokens = line.strip().split() - if len(tokens) > 0: - #tokens[0] = '@dihedral:type'+tokens[0] - l_data_middlebondtorsion_coeffs.append((' '*indent)+(' '.join(tokens)+'\n')) - - elif (line.strip() == 'EndBondTorsion Coeffs'): - sys.stderr.write(' reading \"'+line.strip()+'\"\n') - while lex: - line = lex.ReadLine() - if line.strip() in data_file_header_names: - lex.push_raw_text(line) # <- Save line for later - break - tokens = line.strip().split() - if len(tokens) > 0: - #tokens[0] = '@dihedral:type'+tokens[0] - l_data_endbondtorsion_coeffs.append((' '*indent)+(' '.join(tokens)+'\n')) - - elif (line.strip() == 'AngleTorsion Coeffs'): - sys.stderr.write(' reading \"'+line.strip()+'\"\n') - while lex: - line = lex.ReadLine() - if line.strip() in data_file_header_names: - lex.push_raw_text(line) # <- Save line for later - break - tokens = line.strip().split() - if len(tokens) > 0: - #tokens[0] = '@dihedral:type'+tokens[0] - l_data_angletorsion_coeffs.append((' '*indent)+(' '.join(tokens)+'\n')) - - elif (line.strip() == 'AngleAngleTorsion Coeffs'): - sys.stderr.write(' reading \"'+line.strip()+'\"\n') - while lex: - line = lex.ReadLine() - if line.strip() in data_file_header_names: - lex.push_raw_text(line) # <- Save line for later - break - tokens = line.strip().split() - if len(tokens) > 0: - #tokens[0] = '@dihedral:type'+tokens[0] - l_data_angleangletorsion_coeffs.append((' '*indent)+(' '.join(tokens)+'\n')) - - elif (line.strip() == 'BondBond13 Coeffs'): - sys.stderr.write(' reading \"'+line.strip()+'\"\n') - while lex: - line = lex.ReadLine() - if line.strip() in data_file_header_names: - lex.push_raw_text(line) # <- Save line for later - break - tokens = line.strip().split() - if len(tokens) > 0: - #tokens[0] = '@dihedral:type'+tokens[0] - l_data_bondbond13_coeffs.append((' '*indent)+(' '.join(tokens)+'\n')) - - elif (line.strip() == 'AngleAngle Coeffs'): - sys.stderr.write(' reading \"'+line.strip()+'\"\n') - while lex: - line = lex.ReadLine() - if line.strip() in data_file_header_names: - lex.push_raw_text(line) # <- Save line for later - break - tokens = line.strip().split() - if len(tokens) > 0: - #tokens[0] = '@improper:type'+tokens[0] - l_data_angleangle_coeffs.append((' '*indent)+(' '.join(tokens)+'\n')) - - elif (line.strip() == 'Angles By Type'): - sys.stderr.write(' reading \"'+line.strip()+'\"\n') - while lex: - line = lex.ReadLine() - if line.strip() in data_file_header_names: - lex.push_raw_text(line) # <- Save line for later - break - tokens = line.strip().split() - if len(tokens) > 0: - tokens[0] = '@angle:type'+tokens[0] - l_data_angles_by_type.append((' '*indent)+(' '.join(tokens)+'\n')) - - elif (line.strip() == 'Dihedrals By Type'): - sys.stderr.write(' reading \"'+line.strip()+'\"\n') - while lex: - line = lex.ReadLine() - if line.strip() in data_file_header_names: - lex.push_raw_text(line) # <- Save line for later - break - tokens = line.strip().split() - if len(tokens) > 0: - tokens[0] = '@dihedral:type'+tokens[0] - l_data_dihedrals_by_type.append((' '*indent)+(' '.join(tokens)+'\n')) - - elif (line.strip() == 'Impropers By Type'): - sys.stderr.write(' reading \"'+line.strip()+'\"\n') - while lex: - line = lex.ReadLine() - if line.strip() in data_file_header_names: - lex.push_raw_text(line) # <- Save line for later - break - tokens = line.strip().split() - if len(tokens) > 0: - tokens[0] = '@improper:type'+tokens[0] - l_data_impropers_by_type.append((' '*indent)+(' '.join(tokens)+'\n')) - - - # Figure out the size of the simulation box boundary: - elif ((len(tokens)==4) and - (tokens[2] == 'xlo') and - (tokens[3] == 'xhi') and - IsNumber(tokens[0]) and - IsNumber(tokens[1])): - boundary_xlo = float(tokens[0]) - boundary_xhi = float(tokens[1]) - - elif ((len(tokens)==4) and - (tokens[2] == 'ylo') and - (tokens[3] == 'yhi') and - IsNumber(tokens[0]) and - IsNumber(tokens[1])): - boundary_ylo = float(tokens[0]) - boundary_yhi = float(tokens[1]) - - elif ((len(tokens)==4) and - (tokens[2] == 'zlo') and - (tokens[3] == 'zhi') and - IsNumber(tokens[0]) and - IsNumber(tokens[1])): - boundary_zlo = float(tokens[0]) - boundary_zhi = float(tokens[1]) - - elif ((len(tokens)==6) and - (tokens[3] == 'xy') and - (tokens[4] == 'xz') and - (tokens[5] == 'yz') and - IsNumber(tokens[0]) and - IsNumber(tokens[1]) and - IsNumber(tokens[2])): - boundary_xy = float(tokens[0]) - boundary_xz = float(tokens[1]) - boundary_yz = float(tokens[2]) - - elif (tokens[0] == 'group'): - if (len(tokens) < 3): - raise InputError('Error: near or before '+ErrorLeader(infile, lineno)+'\n' - ' Nonsensical group command:\n' - ' \"'+line.strip()+'\"\n') - l_in_group.append((' '*indent)+(' '.join(tokens)+'\n')) - - elif ((tokens[0] == 'fix') and (len(tokens) >= 4)): - if (tokens[3].find('rigid') == 0): - if (len(tokens) < 6): - raise InputError('Error: near or before '+ErrorLeader(infile, lineno)+'\n' - ' Nonsensical '+tokens[0]+' '+tokens[3]+' command:\n' - ' \"'+line.strip()+'\"\n') - l_in_fix_rigid.append((' '*indent)+(' '.join(tokens)+'\n')) - elif (tokens[3].find('shake') == 0): - if (len(tokens) < 7): - raise InputError('Error: near or before '+ErrorLeader(infile, lineno)+'\n' - ' Nonsensical '+tokens[0]+' '+tokens[3]+' command:\n' - ' \"'+line.strip()+'\"\n') - l_in_fix_shake.append((' '*indent)+(' '.join(tokens)+'\n')) - elif (tokens[3].find('poems') == 0): - if (len(tokens) < 4): - raise InputError('Error: near or before '+ErrorLeader(infile, lineno)+'\n' - ' Nonsensical '+tokens[0]+' '+tokens[3]+' command:\n' - ' \"'+line.strip()+'\"\n') - l_in_fix_poems.append((' '*indent)+(' '.join(tokens)+'\n')) - elif (tokens[3].find('qeq') == 0): - if (len(tokens) < 8): - raise InputError('Error: near or before '+ErrorLeader(infile, lineno)+'\n' - ' Nonsensical '+tokens[0]+' '+tokens[3]+' command:\n' - ' \"'+line.strip()+'\"\n') - l_in_fix_qeq.append((' '*indent)+(' '.join(tokens)+'\n')) - elif (tokens[3].find('qmmm') == 0): - if (len(tokens) < 8): - raise InputError('Error: near or before '+ErrorLeader(infile, lineno)+'\n' - ' Nonsensical '+tokens[0]+' '+tokens[3]+' command:\n' - ' \"'+line.strip()+'\"\n') - l_in_fix_qmmm.append((' '*indent)+(' '.join(tokens)+'\n')) - elif (tokens[3].find('restrain') == 0): - sys.stderr('WARNING: fix \"'+tokens[3]+'\" commands are NOT understood by '+g_program_name+'.\n' - ' If you need restraints, add them to your final .LT file (eg. \"system.lt\"),\n' - ' (And be sure to use unique (full, long) moltemplate names for each $atom:.)\n' - ' Ignoring line \"'+line.strip()+'\"\n') - - else: - sys.stderr.write(' Ignoring line \"'+line.strip()+'\"\n') - - sys.stderr.write('\n\n') - - sys.stderr.write(' processing \"Atoms\" section (') - - # post-processing: - - if len(l_data_masses) == 0: - infer_types_from_comments = False - - # Pass 1 through l_data_atoms: - # Now do a second-pass throught the "l_data_atoms" section, and - # finish dealing with "infer_types_from_comments". - # During this pass, peplace the atomtype names and atomid names with - # atom type names which were inferred from comments read earlier. - - sys.stderr.write('pass1') - for i in range(0, len(l_data_atoms)): - tokens = l_data_atoms[i].split() - atomid = tokens[i_atomid] - if atomid.find('$atom:') == 0: - atomid = atomid[6:] - # convert to an integer - atomid = Intify(atomid) - - if infer_types_from_comments: - atomtype = tokens[i_atomtype] - # remove the "@atom:" prefix (we will put it back later) - if atomtype.find('@atom:') == 0: - atomtype = atomtype[6:] - # convert to an integer - atomtype = Intify(atomtype) - atomtype_name = atomtypes_int2name[atomtype] - if atomtype in atomids_by_type: - l_atomids = atomids_by_type[atomtype] - prev_count = len(l_atomids) - # lookup the most recently added atom of this type: - #prev_atomid_name = l_atomids[-1] - #ic = prev_atomid_name.rfind('_') - #prev_count = int(prev_atomid_name[ic+1:]) - atomid_name = atomtype_name+'_'+str(prev_count+1) - atomids_by_type[atomtype].append(atomid) - else: - atomids_by_type[atomtype] = [atomid] - atomid_name = atomtype_name+'_1' - atomids_int2name[atomid] = atomid_name - #atomids_name2str[atomid_name] = atomid - else: - atomids_int2name[atomid] = 'id'+str(atomid) - - sys.stderr.write(', pass2') - # Pass 2: If any atom types only appear once, simplify their atomid names. - for i in range(0, len(l_data_atoms)): - tokens = l_data_atoms[i].split() - - # remove the "@atom:" prefix (we will put it back later) - atomtype = tokens[i_atomtype] - if atomtype.find('@atom:') == 0: - atomtype = atomtype[6:] - atomtype = Intify(atomtype) - if infer_types_from_comments: - if len(atomids_by_type[atomtype]) == 1: - atomid = tokens[i_atomid] - if atomid.find('$atom:') == 0: - atomid = atomid[6:] - atomid = Intify(atomid) - atomtype_name = atomtypes_int2name[atomtype] - atomids_int2name[atomid] = atomtype_name - - sys.stderr.write(', pass3') - # Pass 3: substitute the atomid names and atom type names into l_data_atoms - for i in range(0, len(l_data_atoms)): - tokens = l_data_atoms[i].split() - atomid = tokens[i_atomid] - if atomid.find('$atom:') == 0: - atomid = atomid[6:] - # convert to an integer - atomid = Intify(atomid) - atomtype = tokens[i_atomtype] - if atomtype.find('@atom:') == 0: - atomtype = atomtype[6:] - atomtype = Intify(atomtype) - tokens = l_data_atoms[i].split() - tokens[i_atomid] = '$atom:'+atomids_int2name[atomid] - tokens[i_atomtype] = '@atom:'+atomtypes_int2name[atomtype] - l_data_atoms[i] = (' '*indent)+(' '.join(tokens)+'\n') - sys.stderr.write(')\n') - - - if len(l_data_atoms) == 0: - raise InputError('Error('+g_program_name+'): You have no atoms in you selection!\n' - '\n' - ' Either you have chosen a set of atoms, molecules, or atom types which\n' - ' does not exist, or there is a problem with (the format of) your\n' - ' arguments. Check the documentation and examples.\n') - - - # --- Now delete items that were not selected from the other lists --- - - # --- MASSES --- - - # delete masses for atom types we don't care about anymore: - i_line = 0 - while i_line < len(l_data_masses): - line = l_data_masses[i_line] - tokens = line.strip().split() - atomtype = Intify(tokens[0]) - if ((not (atomtype in needed_atomtypes)) and - (not ((len(atomtype_selection) > 0) and - BelongsToSel(atomtype, atomtype_selection)))): - del l_data_masses[i_line] - else: - atomtype_name = atomtypes_int2name[atomtype] - tokens[0] = '@atom:'+atomtype_name - l_data_masses[i_line] = (' '*indent)+(' '.join(tokens)+'\n') - i_line += 1 - - - - # --- PAIR COEFFS --- - - # delete data_pair_coeffs for atom types we don't care about anymore: - i_line = 0 - while i_line < len(l_data_pair_coeffs): - line = l_data_pair_coeffs[i_line] - tokens = line.strip().split() - assert(len(tokens) > 0) - split_colon = tokens[0].split(':') - assert(len(split_colon) == 2) - atomtype = Intify(split_colon[1]) - if ((not (atomtype in needed_atomtypes)) and - (not ((len(atomtype_selection) > 0) and - BelongsToSel(atomtype, atomtype_selection)))): - del l_data_pair_coeffs[i_line] - else: - i_line += 1 - - # delete data_pairij_coeffs for atom types we don't care about anymore: - i_line = 0 - while i_line < len(l_data_pairij_coeffs): - line = l_data_pairij_coeffs[i_line] - tokens = line.strip().split() - assert(len(tokens) > 0) - split_colon_I = tokens[0].split(':') - assert(len(split_colon_I) == 2) - atomtype_I = Intify(split_colon_I[1]) - split_colon_J = tokens[1].split(':') - assert(len(split_colon_J) == 2) - atomtype_J = Intify(split_colon_J[1]) - if (((not (atomtype_I in needed_atomtypes)) and - (not ((len(atomtype_selection) > 0) and - BelongsToSel(atomtype_I, atomtype_selection)))) - or - ((not (atomtype_J in needed_atomtypes)) and - (not ((len(atomtype_selection) > 0) and - BelongsToSel(atomtype_J, atomtype_selection))))): - del l_data_pairij_coeffs[i_line] - else: - i_line += 1 - - # delete in_pair_coeffs for atom we don't care about anymore: - i_line = 0 - while i_line < len(l_in_pair_coeffs): - line = l_in_pair_coeffs[i_line] - tokens = line.strip().split() - atomtype_i_str = tokens[1] - atomtype_j_str = tokens[2] - #if (('*' in atomtype_i_str) or - # ('*' in atomtype_j_str)): - # sys.stderr.write('WARNING: near or before '+ErrorLeader(infile, lineno)+'\n' - # ' pair_coeff command contains a \"*\" character.\n' - # ' Keep in mind that using moltemplate.sh you can manually change the\n' - # ' numbers assigned to each atom type (when using -a or -b). Make sure\n' - # ' nor to accidentally change the order of atom types in one of these\n' - # ' pair_coeff commands. For example, commands like\n' - # ' pair_coeff 10*4 20*10 0.15 3.6\n' - # ' can be generated by moltemplate.sh, however\n' - # ' they may be rejected by LAMMPS (because LAMMPS prefers this\n' - # ' pair_coeff 4*10 10*20 0.15 3.6)\n' - # ' Later on, you may want to check to make sure moltemplate.sh\n' - # ' is not doing this. (Fortunately you never have to worry unless\n' - # ' you are using the -a or -b arguments with moltemplate.sh)\n') - - if ('*' in atomtype_i_str): - atomtype_i_tokens = atomtype_i_str.split('*') - - if atomtype_i_tokens[0] == '': - if (min_sel_atomtype and - (min_sel_atomtype < min_needed_atomtype)): - i_a = min_sel_atomtype - else: - i_a = min_needed_atomtype - else: - i_a = Intify(atomtype_i_tokens[0]) - - if atomtype_i_tokens[1] == '': - if (max_sel_atomtype and - (max_sel_atomtype > max_needed_atomtype)): - i_b = max_sel_atomtype - else: - i_b = max_needed_atomtype - else: - i_b = Intify(atomtype_i_tokens[1]) - - else: - i_a = i_b = Intify(atomtype_i_str) - - i_a_final = None - i_b_final = None - for i in range(i_a, i_b+1): - if ((i in needed_atomtypes) or (min_sel_atomtype <= i)): - i_a_final = i - break - for i in reversed(range(i_a, i_b+1)): - if ((i in needed_atomtypes) or (max_sel_atomtype >= i)): - i_b_final = i - break - - #if i_a_final and i_b_final: - # if i_a_final == i_b_final: - # i_str = '@atom:type'+str(i_a_final) - # tokens[1] = i_str - # else: - # i_str = '@{atom:type'+str(i_a_final)+'}*@{atom:type'+str(i_b_final)+'}' - - - - if ('*' in atomtype_j_str): - atomtype_j_tokens = atomtype_j_str.split('*') - - if atomtype_j_tokens[0] == '': - if (min_sel_atomtype and - (min_sel_atomtype < min_needed_atomtype)): - j_a = min_sel_atomtype - else: - j_a = min_needed_atomtype - else: - j_a = Intify(atomtype_j_tokens[0]) - - if atomtype_j_tokens[1] == '': - if (max_sel_atomtype and - (max_sel_atomtype > max_needed_atomtype)): - j_b = max_sel_atomtype - else: - j_b = max_needed_atomtype - else: - j_b = Intify(atomtype_j_tokens[1]) - - else: - j_a = j_b = Intify(atomtype_j_str) - - j_a_final = None - j_b_final = None - for j in range(j_a, j_b+1): - if ((j in needed_atomtypes) or (min_sel_atomtype <= j)): - j_a_final = j - break - for j in reversed(range(j_a, j_b+1)): - if ((j in needed_atomtypes) or (max_sel_atomtype >= j)): - j_b_final = j - break - - #if j_a_final and j_b_final: - # if j_a_final == j_b_final: - # j_str = '@atom:type'+str(j_a_final) - # tokens[1] = j_str - # else: - # j_str = '@{atom:type'+str(j_a_final)+'}*@{atom:type'+str(j_b_final)+'}' - - - - if not (i_a_final and i_b_final and j_a_final and j_b_final): - del l_in_pair_coeffs[i_line] - elif (('*' in atomtype_i_str) or ('*' in atomtype_j_str)): - del l_in_pair_coeffs[i_line] - for i in range(i_a_final, i_b_final+1): - for j in range(j_a_final, j_b_final+1): - if j >= i: - #tokens[1] = '@atom:type'+str(i) - #tokens[2] = '@atom:type'+str(j) - tokens[1] = '@atom:'+atomtypes_int2name[i] - tokens[2] = '@atom:'+atomtypes_int2name[j] - l_in_pair_coeffs.insert(i_line, - (' '*indent)+(' '.join(tokens)+'\n')) - i_line += 1 - else: - #tokens[1] = '@atom:type'+tokens[1] - #tokens[2] = '@atom:type'+tokens[2] - tokens[1] = '@atom:'+atomtypes_int2name[int(tokens[1])] - tokens[2] = '@atom:'+atomtypes_int2name[int(tokens[2])] - l_in_pair_coeffs[i_line] = (' '*indent)+(' '.join(tokens)+'\n') - i_line += 1 - - - - - # delete mass commands for atom types we don't care about anymore: - i_line = 0 - while i_line < len(l_in_masses): - line = l_in_masses[i_line] - tokens = line.strip().split() - atomtype_i_str = tokens[1] - #if (('*' in atomtype_i_str) or - # ('*' in atomtype_j_str)): - # sys.stderr.write('WARNING: near or before '+ErrorLeader(infile, lineno)+'\n' - # ' pair_coeff command contains a \"*\" character.\n' - # ' Keep in mind that using moltemplate.sh you can manually change the\n' - # ' numbers assigned to each atom type (when using -a or -b). Make sure\n' - # ' nor to accidentally change the order of atom types in one of these\n' - # ' pair_coeff commands. For example, commands like\n' - # ' pair_coeff 10*4 20*10 0.15 3.6\n' - # ' can be generated by moltemplate.sh, however\n' - # ' they may be rejected by LAMMPS (because LAMMPS prefers this\n' - # ' pair_coeff 4*10 10*20 0.15 3.6)\n' - # ' Later on, you may want to check to make sure moltemplate.sh\n' - # ' is not doing this. (Fortunately you never have to worry unless\n' - # ' you are using the -a or -b arguments with moltemplate.sh)\n') - - if ('*' in atomtype_i_str): - atomtype_i_tokens = atomtype_i_str.split('*') - - if atomtype_i_tokens[0] == '': - if (min_sel_atomtype and - (min_sel_atomtype < min_needed_atomtype)): - i_a = min_sel_atomtype - else: - i_a = min_needed_atomtype - else: - i_a = Intify(atomtype_i_tokens[0]) - - if atomtype_i_tokens[1] == '': - if (max_sel_atomtype and - (max_sel_atomtype > max_needed_atomtype)): - i_b = max_sel_atomtype - else: - i_b = max_needed_atomtype - else: - i_b = Intify(atomtype_i_tokens[1]) - - else: - i_a = i_b = Intify(atomtype_i_str) - - i_a_final = None - i_b_final = None - for i in range(i_a, i_b+1): - if ((i in needed_atomtypes) or (min_sel_atomtype <= i)): - i_a_final = i - break - for i in reversed(range(i_a, i_b+1)): - if ((i in needed_atomtypes) or (max_sel_atomtype >= i)): - i_b_final = i - break - #if i_a_final and i_b_final: - # if i_a_final == i_b_final: - # i_str = '@atom:type'+str(i_a_final) - # tokens[1] = i_str - # else: - # i_str = '@{atom:type'+str(i_a_final)+'}*@{atom:type'+str(i_b_final)+'}' - - if not (i_a_final and i_b_final and j_a_final and j_b_final): - del l_in_masses[i_line] - elif ('*' in atomtype_i_str): - del l_in_masses[i_line] - for i in range(i_a_final, i_b_final+1): - #tokens[1] = '@atom:type'+str(i) - tokens[1] = '@atom:'+atomtypes_int2name[i] - # CONTINUEHERE: CHECK THAT THIS IS WORKING - l_in_masses.insert(i_line, (' '*indent)+(' '.join(tokens)+'\n')) - i_line += 1 - else: - assert(i_a == i_b) - #tokens[1] = '@atom:type'+str(i_a) - tokens[1] = '@atom:'+atomtypes_int2name[i_a] - # CONTINUEHERE: CHECK THAT THIS IS WORKING - l_in_masses[i_line] = (' '*indent)+(' '.join(tokens)+'\n') - i_line += 1 - - - - - # --- BONDS AND BOND COEFFS --- - - # delete lines from data_bonds if they involve atoms we don't care about - i_line = 0 - while i_line < len(l_data_bonds): - line = l_data_bonds[i_line] - tokens = line.strip().split() - assert(len(tokens) == 4) - - bondid = Intify(tokens[0]) - bondtype = Intify(tokens[1]) - atomid1 = Intify(tokens[2]) - atomid2 = Intify(tokens[3]) - #if ((atomid1 in needed_atomids) and - # (atomid2 in needed_atomids)): - tokens[0] = '$bond:id'+str(bondid) - tokens[1] = '@bond:type'+str(bondtype) - #tokens[2] = '$atom:id'+str(atomid1) - #tokens[3] = '$atom:id'+str(atomid2) - tokens[2] = '$atom:'+atomids_int2name[atomid1] - tokens[3] = '$atom:'+atomids_int2name[atomid2] - needed_bondids.add(bondid) - needed_bondtypes.add(bondtype) - l_data_bonds[i_line] = (' '*indent)+(' '.join(tokens)+'\n') - i_line += 1 - #else: - # del l_data_bonds[i_line] - - # delete data_bond_coeffs for bondtypes we don't care about anymore: - i_line = 0 - while i_line < len(l_data_bond_coeffs): - line = l_data_bond_coeffs[i_line] - tokens = line.strip().split() - bondtype = Intify(tokens[0]) - if (not (bondtype in needed_bondtypes)): - del l_data_bond_coeffs[i_line] - else: - tokens[0] = '@bond:type'+str(bondtype) - l_data_bond_coeffs[i_line] = (' '*indent)+(' '.join(tokens)+'\n') - i_line += 1 - - # delete in_bond_coeffs for bondtypes we don't care about anymore: - for bondtype in needed_bondtypes: - assert(type(bondtype) is int) - if ((min_needed_bondtype == None) or - (min_needed_bondtype > bondtype)): - min_needed_bondtype = bondtype - if ((max_needed_bondtype == None) or - (max_needed_bondtype < bondtype)): - max_needed_bondtype = bondtype - for bondid in needed_bondids: - assert(type(bondid) is int) - if ((min_needed_bondid == None) or - (min_needed_bondid > bondid)): - min_needed_bondid = bondid - if ((max_needed_bondid == None) or - (max_needed_bondid < bondid)): - max_needed_bondid = bondid - - - i_line = 0 - while i_line < len(l_in_bond_coeffs): - line = l_in_bond_coeffs[i_line] - tokens = line.strip().split() - bondtype_str = tokens[1] - - if ('*' in bondtype_str): - bondtype_tokens = bondtype_str.split('*') - - if bondtype_tokens[0] == '': - i_a = min_needed_bondtype - else: - i_a = Intify(bondtype_tokens[0]) - - if bondtype_tokens[1] == '': - i_b = max_needed_bondtype - else: - i_b = Intify(bondtype_tokens[1]) - - else: - i_a = Intify(bondtype_str) - i_b = i_a - - if i_a < min_needed_bondtype: - i_a = min_needed_bondtype - if i_b > max_needed_bondtype: - i_b = max_needed_bondtype - - #if i_a == i_b: - # i_str = '@bond:type'+str(i_a) - # tokens[1] = i_str - #else: - # i_str = '@{bond:type'+str(j_a)+'}*@{bond:type'+str(j_b)+'}' - - if ('*' in bondtype_str): - del l_in_bond_coeffs[i_line] - for i in range(i_a, i_b+1): - if (i in needed_bondtypes): - tokens[1] = '@bond:type'+str(i) - l_in_bond_coeffs.insert(i_line, - (' '*indent)+(' '.join(tokens)+'\n')) - i_line += 1 - else: - if i_a < i_b: - raise InputError('Error: number of bond types in data file is not consistent with the\n' - ' number of bond types you have define bond_coeffs for.\n') - if (i_a == i_b) and (i_a in needed_bondtypes): - tokens[1] = '@bond:type'+str(i_a) - l_in_bond_coeffs[i_line] = (' '*indent)+(' '.join(tokens)+'\n') - i_line += 1 - else: - del l_in_bond_coeffs[i_line] - - - - - - # --- ANGLES AND ANGLE COEFFS --- - - # delete lines from data_angles if they involve atoms we don't care about - i_line = 0 - while i_line < len(l_data_angles): - line = l_data_angles[i_line] - tokens = line.strip().split() - assert(len(tokens) == 5) - - angleid = Intify(tokens[0]) - angletype = Intify(tokens[1]) - atomid1 = Intify(tokens[2]) - atomid2 = Intify(tokens[3]) - atomid3 = Intify(tokens[4]) - #if ((atomid1 in needed_atomids) and - # (atomid2 in needed_atomids)): - tokens[0] = '$angle:id'+str(angleid) - tokens[1] = '@angle:type'+str(angletype) - #tokens[2] = '$atom:id'+str(atomid1) - #tokens[3] = '$atom:id'+str(atomid2) - #tokens[4] = '$atom:id'+str(atomid3) - tokens[2] = '$atom:'+atomids_int2name[atomid1] - tokens[3] = '$atom:'+atomids_int2name[atomid2] - tokens[4] = '$atom:'+atomids_int2name[atomid3] - needed_angleids.add(angleid) - needed_angletypes.add(angletype) - l_data_angles[i_line] = (' '*indent)+(' '.join(tokens)+'\n') - i_line += 1 - #else: - # del l_data_angles[i_line] - - # delete data_angle_coeffs for angletypes we don't care about anymore: - i_line = 0 - while i_line < len(l_data_angle_coeffs): - line = l_data_angle_coeffs[i_line] - tokens = line.strip().split() - angletype = Intify(tokens[0]) - if (not (angletype in needed_angletypes)): - del l_data_angle_coeffs[i_line] - else: - tokens[0] = '@angle:type'+str(angletype) - l_data_angle_coeffs[i_line] = (' '*indent)+(' '.join(tokens)+'\n') - i_line += 1 - - # --- class2specific ---- - # Do the same for BondBond and BondAngle Coeffs: - # NOTE: LAMMPS INPUT SCRIPTS, ALL CLASS2 COEFFS are represented by: - # angle_coeff, dihedral_coeff, and improper_coeff commands. - # THERE ARE NO bondbond_coeff commands, or bondangle_coeff commands, - # etc..., so we dont have to worry about l_in_bondbond_coeffs,... - # delete data_bondbond_coeffs for angletypes we don't care about anymore: - i_line = 0 - while i_line < len(l_data_bondbond_coeffs): - line = l_data_bondbond_coeffs[i_line] - tokens = line.strip().split() - angletype = Intify(tokens[0]) - if (not (angletype in needed_angletypes)): - del l_data_bondbond_coeffs[i_line] - else: - tokens[0] = '@angle:type'+str(angletype) - l_data_bondbond_coeffs[i_line] = (' '*indent)+(' '.join(tokens)+'\n') - i_line += 1 - # delete data_bondangle_coeffs for angletypes we don't care about anymore: - i_line = 0 - while i_line < len(l_data_bondangle_coeffs): - line = l_data_bondangle_coeffs[i_line] - tokens = line.strip().split() - angletype = Intify(tokens[0]) - if (not (angletype in needed_angletypes)): - del l_data_bondangle_coeffs[i_line] - else: - tokens[0] = '@angle:type'+str(angletype) - l_data_bondangle_coeffs[i_line] = (' '*indent)+(' '.join(tokens)+'\n') - i_line += 1 - # --- end of class2specific ---- - - - # delete in_angle_coeffs for angletypes we don't care about anymore: - for angletype in needed_angletypes: - assert(type(angletype) is int) - if ((min_needed_angletype == None) or - (min_needed_angletype > angletype)): - min_needed_angletype = angletype - if ((max_needed_angletype == None) or - (max_needed_angletype < angletype)): - max_needed_angletype = angletype - for angleid in needed_angleids: - assert(type(angleid) is int) - if ((min_needed_angleid == None) or - (min_needed_angleid > angleid)): - min_needed_angleid = angleid - if ((max_needed_angleid == None) or - (max_needed_angleid < angleid)): - max_needed_angleid = angleid - - i_line = 0 - while i_line < len(l_in_angle_coeffs): - line = l_in_angle_coeffs[i_line] - tokens = line.strip().split() - angletype_str = tokens[1] - - if ('*' in angletype_str): - angletype_tokens = angletype_str.split('*') - - if angletype_tokens[0] == '': - i_a = min_needed_angletype - else: - i_a = Intify(angletype_tokens[0]) - - if angletype_tokens[1] == '': - i_b = max_needed_angletype - else: - i_b = Intify(angletype_tokens[1]) - - else: - i_a = i_b = Intify(angletype_str) - - if i_a < min_needed_angletype: - i_a = min_needed_angletype - if i_b > max_needed_angletype: - i_b = max_needed_angletype - - #if i_a == i_b: - # i_str = '@angle:type'+str(i_a) - # tokens[1] = i_str - #else: - # i_str = '@{angle:type'+str(j_a)+'}*@{angle:type'+str(j_b)+'}' - - if ('*' in angletype_str): - del l_in_angle_coeffs[i_line] - for i in range(i_a, i_b+1): - if (i in needed_angletypes): - tokens[1] = '@angle:type'+str(i) - l_in_angle_coeffs.insert(i_line, - (' '*indent)+(' '.join(tokens)+'\n')) - i_line += 1 - else: - if i_a < i_b: - raise InputError('Error: number of angle types in data file is not consistent with the\n' - ' number of angle types you have define angle_coeffs for.\n') - if (i_a == i_b) and (i_a in needed_angletypes): - tokens[1] = '@angle:type'+str(i_a) - l_in_angle_coeffs[i_line] = (' '*indent)+(' '.join(tokens)+'\n') - i_line += 1 - else: - del l_in_angle_coeffs[i_line] - - - - - # --- DIHEDRALS AND DIHEDRAL COEFFS --- - - # delete lines from data_dihedrals if they involve atoms we don't care about - i_line = 0 - while i_line < len(l_data_dihedrals): - line = l_data_dihedrals[i_line] - tokens = line.strip().split() - assert(len(tokens) == 6) - - dihedralid = Intify(tokens[0]) - dihedraltype = Intify(tokens[1]) - atomid1 = Intify(tokens[2]) - atomid2 = Intify(tokens[3]) - atomid3 = Intify(tokens[4]) - atomid4 = Intify(tokens[5]) - #if ((atomid1 in needed_atomids) and - # (atomid2 in needed_atomids)): - tokens[0] = '$dihedral:id'+str(dihedralid) - tokens[1] = '@dihedral:type'+str(dihedraltype) - #tokens[2] = '$atom:id'+str(atomid1) - #tokens[3] = '$atom:id'+str(atomid2) - #tokens[4] = '$atom:id'+str(atomid3) - #tokens[5] = '$atom:id'+str(atomid4) - tokens[2] = '$atom:'+atomids_int2name[atomid1] - tokens[3] = '$atom:'+atomids_int2name[atomid2] - tokens[4] = '$atom:'+atomids_int2name[atomid3] - tokens[5] = '$atom:'+atomids_int2name[atomid4] - - needed_dihedralids.add(dihedralid) - needed_dihedraltypes.add(dihedraltype) - l_data_dihedrals[i_line] = (' '*indent)+(' '.join(tokens)+'\n') - i_line += 1 - #else: - # del l_data_dihedrals[i_line] - - # delete data_dihedral_coeffs for dihedraltypes we don't care about anymore: - i_line = 0 - while i_line < len(l_data_dihedral_coeffs): - line = l_data_dihedral_coeffs[i_line] - tokens = line.strip().split() - dihedraltype = Intify(tokens[0]) - if (not (dihedraltype in needed_dihedraltypes)): - del l_data_dihedral_coeffs[i_line] - else: - tokens[0] = '@dihedral:type'+str(dihedraltype) - l_data_dihedral_coeffs[i_line] = (' '*indent)+(' '.join(tokens)+'\n') - i_line += 1 - - # --- class2specific ---- - # Do the same for MiddleBondTorsion, EndBondTorsion, AngleTorsion, - # AngleAngleTorsion, and BondBond13 Coeffs - # NOTE: LAMMPS INPUT SCRIPTS, ALL CLASS2 COEFFS are represented by: - # angle_coeff, dihedral_coeff, and improper_coeff commands. - # THERE ARE NO "middlebondtorsion_coeff" commands, etc...so we don't - # have to worry about dealing with "l_in_middlebondtorsion_coeffs",... - # delete data_middlebondtorsion_coeffs for dihedraltypes we don't care about anymore: - i_line = 0 - while i_line < len(l_data_middlebondtorsion_coeffs): - line = l_data_middlebondtorsion_coeffs[i_line] - tokens = line.strip().split() - dihedraltype = Intify(tokens[0]) - if (not (dihedraltype in needed_dihedraltypes)): - del l_data_middlebondtorsion_coeffs[i_line] - else: - tokens[0] = '@dihedral:type'+str(dihedraltype) - l_data_middlebondtorsion_coeffs[i_line] = (' '*indent)+(' '.join(tokens)+'\n') - i_line += 1 - # delete data_endbondtorsion_coeffs for dihedraltypes we don't care about anymore: - i_line = 0 - while i_line < len(l_data_endbondtorsion_coeffs): - line = l_data_endbondtorsion_coeffs[i_line] - tokens = line.strip().split() - dihedraltype = Intify(tokens[0]) - if (not (dihedraltype in needed_dihedraltypes)): - del l_data_endbondtorsion_coeffs[i_line] - else: - tokens[0] = '@dihedral:type'+str(dihedraltype) - l_data_endbondtorsion_coeffs[i_line] = (' '*indent)+(' '.join(tokens)+'\n') - i_line += 1 - # delete data_angletorsion_coeffs for dihedraltypes we don't care about anymore: - i_line = 0 - while i_line < len(l_data_angletorsion_coeffs): - line = l_data_angletorsion_coeffs[i_line] - tokens = line.strip().split() - dihedraltype = Intify(tokens[0]) - if (not (dihedraltype in needed_dihedraltypes)): - del l_data_angletorsion_coeffs[i_line] - else: - tokens[0] = '@dihedral:type'+str(dihedraltype) - l_data_angletorsion_coeffs[i_line] = (' '*indent)+(' '.join(tokens)+'\n') - i_line += 1 - # delete data_angleangletorsion_coeffs for dihedraltypes we don't care about anymore: - i_line = 0 - while i_line < len(l_data_angleangletorsion_coeffs): - line = l_data_angleangletorsion_coeffs[i_line] - tokens = line.strip().split() - dihedraltype = Intify(tokens[0]) - if (not (dihedraltype in needed_dihedraltypes)): - del l_data_angleangletorsion_coeffs[i_line] - else: - tokens[0] = '@dihedral:type'+str(dihedraltype) - l_data_angleangletorsion_coeffs[i_line] = (' '*indent)+(' '.join(tokens)+'\n') - i_line += 1 - # delete data_bondbond13_coeffs for dihedraltypes we don't care about anymore: - i_line = 0 - while i_line < len(l_data_bondbond13_coeffs): - line = l_data_bondbond13_coeffs[i_line] - tokens = line.strip().split() - dihedraltype = Intify(tokens[0]) - if (not (dihedraltype in needed_dihedraltypes)): - del l_data_bondbond13_coeffs[i_line] - else: - tokens[0] = '@dihedral:type'+str(dihedraltype) - l_data_bondbond13_coeffs[i_line] = (' '*indent)+(' '.join(tokens)+'\n') - i_line += 1 - # --- end of class2specific ---- - - - # delete in_dihedral_coeffs for dihedraltypes we don't care about anymore: - for dihedraltype in needed_dihedraltypes: - assert(type(dihedraltype) is int) - if ((min_needed_dihedraltype == None) or - (min_needed_dihedraltype > dihedraltype)): - min_needed_dihedraltype = dihedraltype - if ((max_needed_dihedraltype == None) or - (max_needed_dihedraltype < dihedraltype)): - max_needed_dihedraltype = dihedraltype - for dihedralid in needed_dihedralids: - assert(type(dihedralid) is int) - if ((min_needed_dihedralid == None) or - (min_needed_dihedralid > dihedralid)): - min_needed_dihedralid = dihedralid - if ((max_needed_dihedralid == None) or - (max_needed_dihedralid < dihedralid)): - max_needed_dihedralid = dihedralid - - i_line = 0 - while i_line < len(l_in_dihedral_coeffs): - line = l_in_dihedral_coeffs[i_line] - tokens = line.strip().split() - dihedraltype_str = tokens[1] - - if ('*' in dihedraltype_str): - dihedraltype_tokens = dihedraltype_str.split('*') - - if dihedraltype_tokens[0] == '': - i_a = min_needed_dihedraltype - else: - i_a = Intify(dihedraltype_tokens[0]) - - if dihedraltype_tokens[1] == '': - i_b = max_needed_dihedraltype - else: - i_b = Intify(dihedraltype_tokens[1]) - - else: - i_a = i_b = Intify(dihedraltype_str) - - if i_a < min_needed_dihedraltype: - i_a = min_needed_dihedraltype - if i_b > max_needed_dihedraltype: - i_b = max_needed_dihedraltype - - #if i_a == i_b: - # i_str = '@dihedral:type'+str(i_a) - # tokens[1] = i_str - #else: - # i_str = '@{dihedral:type'+str(j_a)+'}*@{dihedral:type'+str(j_b)+'}' - - if ('*' in dihedraltype_str): - del l_in_dihedral_coeffs[i_line] - for i in range(i_a, i_b+1): - if (i in needed_dihedraltypes): - tokens[1] = '@dihedral:type'+str(i) - l_in_dihedral_coeffs.insert(i_line, - (' '*indent)+(' '.join(tokens)+'\n')) - i_line += 1 - else: - if i_a < i_b: - raise InputError('Error: number of dihedral types in data file is not consistent with the\n' - ' number of dihedral types you have define dihedral_coeffs for.\n') - if (i_a == i_b) and (i_a in needed_dihedraltypes): - tokens[1] = '@dihedral:type'+str(i_a) - l_in_dihedral_coeffs[i_line] = (' '*indent)+(' '.join(tokens)+'\n') - i_line += 1 - else: - del l_in_dihedral_coeffs[i_line] - - - - # --- IMPROPERS AND IMPROPER COEFFS --- - - # delete lines from data_impropers if they involve atoms we don't care about - i_line = 0 - while i_line < len(l_data_impropers): - line = l_data_impropers[i_line] - tokens = line.strip().split() - assert(len(tokens) == 6) - - improperid = Intify(tokens[0]) - impropertype = Intify(tokens[1]) - atomid1 = Intify(tokens[2]) - atomid2 = Intify(tokens[3]) - atomid3 = Intify(tokens[4]) - atomid4 = Intify(tokens[5]) - #if ((atomid1 in needed_atomids) and - # (atomid2 in needed_atomids)): - tokens[0] = '$improper:id'+str(improperid) - tokens[1] = '@improper:type'+str(impropertype) - #tokens[2] = '$atom:id'+str(atomid1) - #tokens[3] = '$atom:id'+str(atomid2) - #tokens[4] = '$atom:id'+str(atomid3) - #tokens[5] = '$atom:id'+str(atomid4) - tokens[2] = '$atom:'+atomids_int2name[atomid1] - tokens[3] = '$atom:'+atomids_int2name[atomid2] - tokens[4] = '$atom:'+atomids_int2name[atomid3] - tokens[5] = '$atom:'+atomids_int2name[atomid4] - - needed_improperids.add(improperid) - needed_impropertypes.add(impropertype) - l_data_impropers[i_line] = (' '*indent)+(' '.join(tokens)+'\n') - i_line += 1 - #else: - # del l_data_impropers[i_line] - - # delete data_improper_coeffs for impropertypes we don't care about anymore: - i_line = 0 - while i_line < len(l_data_improper_coeffs): - line = l_data_improper_coeffs[i_line] - tokens = line.strip().split() - impropertype = Intify(tokens[0]) - if (not (impropertype in needed_impropertypes)): - del l_data_improper_coeffs[i_line] - else: - tokens[0] = '@improper:type'+str(impropertype) - l_data_improper_coeffs[i_line] = (' '*indent)+(' '.join(tokens)+'\n') - i_line += 1 - - # --- class2specific ---- - # Do the same for AngleAngle Coeffs - # NOTE: LAMMPS INPUT SCRIPTS, ALL CLASS2 COEFFS are represented by: - # angle_coeff, dihedral_coeff, and improper_coeff commands. - # THERE ARE NO "angleangle_coeff" commands, etc...so we don't - # have to worry about dealing with "l_in_angleangle_coeffs",... - # delete data_middlebondtorsion_coeffs for dihedraltypes we don't care about anymore: - # delete data_angleangle_coeffs for impropertypes we don't care about anymore: - i_line = 0 - while i_line < len(l_data_angleangle_coeffs): - line = l_data_angleangle_coeffs[i_line] - tokens = line.strip().split() - impropertype = Intify(tokens[0]) - if (not (impropertype in needed_impropertypes)): - del l_data_angleangle_coeffs[i_line] - else: - tokens[0] = '@improper:type'+str(impropertype) - l_data_angleangle_coeffs[i_line] = (' '*indent)+(' '.join(tokens)+'\n') - i_line += 1 - # --- end of class2specific ---- - - - # delete in_improper_coeffs for impropertypes we don't care about anymore: - for impropertype in needed_impropertypes: - assert(type(impropertype) is int) - if ((min_needed_impropertype == None) or - (min_needed_impropertype > impropertype)): - min_needed_impropertype = impropertype - if ((max_needed_impropertype == None) or - (max_needed_impropertype < impropertype)): - max_needed_impropertype = impropertype - for improperid in needed_improperids: - assert(type(improperid) is int) - if ((min_needed_improperid == None) or - (min_needed_improperid > improperid)): - min_needed_improperid = improperid - if ((max_needed_improperid == None) or - (max_needed_improperid < improperid)): - max_needed_improperid = improperid - - i_line = 0 - while i_line < len(l_in_improper_coeffs): - line = l_in_improper_coeffs[i_line] - tokens = line.strip().split() - impropertype_str = tokens[1] - - if ('*' in impropertype_str): - impropertype_tokens = impropertype_str.split('*') - - if impropertype_tokens[0] == '': - i_a = min_needed_impropertype - else: - i_a = Intify(impropertype_tokens[0]) - - if impropertype_tokens[1] == '': - i_b = max_needed_impropertype - else: - i_b = Intify(impropertype_tokens[1]) - - else: - i_a = i_b = Intify(impropertype_str) - - if i_a < min_needed_impropertype: - i_a = min_needed_impropertype - if i_b > max_needed_impropertype: - i_b = max_needed_impropertype - - #if i_a == i_b: - # i_str = '@improper:type'+str(i_a) - # tokens[1] = i_str - #else: - # i_str = '@{improper:type'+str(j_a)+'}*@{improper:type'+str(j_b)+'}' - - if ('*' in impropertype_str): - del l_in_improper_coeffs[i_line] - for i in range(i_a, i_b+1): - if (i in needed_impropertypes): - tokens[1] = '@improper:type'+str(i) - l_in_improper_coeffs.insert(i_line, - (' '*indent)+(' '.join(tokens)+'\n')) - i_line += 1 - else: - if i_a < i_b: - raise InputError('Error: number of improper types in data file is not consistent with the\n' - ' number of improper types you have define improper_coeffs for.\n') - if (i_a == i_b) and (i_a in needed_impropertypes): - tokens[1] = '@improper:type'+str(i_a) - l_in_improper_coeffs[i_line] = (' '*indent)+(' '.join(tokens)+'\n') - i_line += 1 - else: - del l_in_improper_coeffs[i_line] - - # --- GROUPS --- - - # Now parse through all of the "group" commands and try and figure - # out if any of these groups contain any of the atoms we are keeping. - # If so, then save the group and write it out. - # (I hate trying to parse this kind of text.) - - #if len(l_in_group) > 0: - # sys.stderr.write('\n' - # ' --groups-- Attempting to parse \"group\" commands.\n' - # ' This may cause '+g_program_name+' to crash.\n' - # ' If so, comment out all group commands in your input script(s), and\n' - # ' try again. (And please report the error. -Andrew 2014-10-30)\n') - - i_line = 0 - groups_needed = set(['all']) - while i_line < len(l_in_group): - line = l_in_group[i_line] - tokens = line.strip().split() - delete_this_command = False - explicit_definition = False - if len(tokens) < 3: - delete_this_command = True - group_name = tokens[1] - specifier_style = tokens[2] - str_logical = '' - str_selection = '' - if specifier_style[0:4] == 'type': - str_logical+=specifier_style[4:] - explicit_definition = True - specifier_style = 'type' - elif specifier_style == 'id': - str_logical+=specifier_style[2:] - explicit_definition = True - specifier_style = 'id' - elif specifier_style == 'molecule': - str_logical+=specifier_style[8:] - specifier_style = 'molecule' - explicit_definition = True - - if explicit_definition: - i_token_sel_min = 3 - if len(tokens) <= i_token_sel_min: - sys.stderr.write('WARNING: possible syntax error on this line:\n' - +' '+l_in_group[i_line]+'\n') - delete_this_command = True - if str_logical == '': - str_logical = tokens[i_token_sel_min] - if not str_logical[0].isdigit(): - i_token_sel_min += 1 - if len(tokens) <= i_token_sel_min: - tokens.append('') - else: - tokens.insert(i_token_sel_min, str_logical) - - i_token_sel_max = len(tokens)-1 - - for i in range(i_token_sel_min, len(tokens)): - if tokens[i].isdigit(): - break - else: - i_token_sel_max = i - - assert(len(tokens) > i_token_sel_min) - - if str_logical[0:2] in ('<=','>=','==','!=','<>'): - tokens[i_token_sel_min] = str_logical[2:] + tokens[i_token_sel_min] - str_logical = str_logical[0:2] - if str_logical == '<=': - l_group_selection = [ (None,int(tokens[i_token_sel_min])) ] - elif str_logical == '>=': - l_group_selection = [ (int(tokens[i_token_sel_min]),None) ] - elif str_logical == '==': - l_group_selection = [ (int(tokens[i_token_sel_min]), - int(tokens[i_token_sel_min])) ] - elif str_logical == '!=': - l_group_selection = [ (None,int(tokens[i_token_sel_min])-1), - (int(tokens[i_token_sel_min])+1,None)] - elif str_logical == '<>': - l_group_selection = [ (int(tokens[i_token_sel_min]), - int(tokens[i_token_sel_max])) ] - - elif str_logical[0:1] in ('<','>'): - tokens[i_token_sel_min] = str_logical[1:] + tokens[i_token_sel_min] - str_logical = str_logical[0:1] - if str_logical == '<': - l_group_selection = [(None,int(tokens[i_token_sel_min])-1)] - elif str_logical == '>': - l_group_selection = [(int(tokens[i_token_sel_min])+1,None)] - else: - str_selection = ' '.join(tokens[i_token_sel_min:i_token_sel_max+1]) - l_group_selection = LammpsSelectToIntervals(str_selection, - slice_delim=':', - or_delim=' ') - - mn, mx = IntervalListToMinMax(l_group_selection) - if mn == None: - mn = 1 - filtered_selection=[] - if specifier_style == 'type': - if mx == None: - mx = max_needed_atomtype - for i in range(mn, mx+1): - if (BelongsToSel(i, l_group_selection) - and (i in needed_atomtypes)): - filtered_selection.append((i,i)) - elif specifier_style == 'id': - if mx == None: - mx = max_needed_atomid - for i in range(mn, mx+1): - if (BelongsToSel(i, l_group_selection) - and (i in needed_atomids)): - filtered_selection.append((i,i)) - elif specifier_style == 'molecule': - if mx == None: - mx = max_needed_molid - for i in range(mn, mx+1): - if (BelongsToSel(i, l_group_selection) - and (i in needed_molids)): - filtered_selection.append((i,i)) - - - MergeIntervals(filtered_selection) - - - if len(filtered_selection) > 0: - - tokens = ['group', group_name, specifier_style] - for interval in filtered_selection: - a = interval[0] - b = interval[1] - - if specifier_style == 'type': - if a == b: - tokens.append('@atom:type'+str(a)) - else: - tokens.append('@{atom:type'+str(a)+ - '}:@{atom:type'+str(b)+'}') - - if specifier_style == 'id': - if a == b: - tokens.append('$atom:id'+str(a)) - else: - tokens.append('${atom:id'+str(a) - +'}:${atom:id'+str(b)+'}') - - if specifier_style == 'molecule': - if a == b: - tokens.append('$mol:id'+str(a)) - else: - tokens.append('${mol:id'+str(a)+ - '}:${mol:id'+str(b)+'}') - - - # Commenting out next two lines. (This is handled later.) - #l_in_group[i_line] = ' '.join(tokens) - #groups_needed.add(group_name) - - else: - delete_this_command = True - - - else: - if len(tokens) > 3: - if tokens[2] == 'union': - i_token = 3 - while i_token < len(tokens): - if not (tokens[i_token] in groups_needed): - del tokens[i_token] - else: - i_token += 1 - # if none of the groups contain atoms we need, - # then delete the entire command - if len(tokens) <= 3: - delete_this_command = True - elif tokens[2] == 'intersect': - i_token = 3 - while i_token < len(tokens): - if not (tokens[i_token] in groups_needed): - # if any of the groups we need are empty - # then delete the command - delete_this_command = True - break - i_token += 1 - elif (tokens[2] == 'subtract') and (len(tokens) >= 5): - if not (tokens[3] in groups_needed): - delete_this_command = True - i_token = 4 - while i_token < len(tokens): - if not (tokens[i_token] in groups_needed): - del tokens[i_token] - else: - i_token += 1 - else: - # Otherwise I don't recongize the syntax of this - # group command. In that case, I just delete it. - delete_this_command = True - - elif tokens[2] == 'clear': - pass - elif tokens[2] == 'delete': - pass - else: - delete_this_command = True - if delete_this_command: - sys.stderr.write('WARNING: Ignoring line \n\"'+l_in_group[i_line].rstrip()+'\"\n') - del l_in_group[i_line] - else: - groups_needed.add(group_name) - l_in_group[i_line] = (' '*indent) + ' '.join(tokens) + '\n' - i_line += 1 - - - - # --- fix rigid --- - - i_line = 0 - while i_line < len(l_in_fix_rigid): - line = l_in_fix_rigid[i_line] - tokens = line.strip().split() - if len(tokens) < 4: - break - fixid = tokens[1] - group_name = tokens[2] - delete_this_command = True - assert(tokens[3].find('rigid') == 0) - if group_name in groups_needed: - delete_this_command = False - - if delete_this_command: - sys.stderr.write('WARNING: Ignoring line \n\"'+l_in_fix_rigid[i_line].rstrip()+'\"\n') - del l_in_fix_rigid[i_line] - else: - l_in_fix_rigid[i_line] = (' '*indent) + ' '.join(tokens) + '\n' - i_line += 1 - - - - # --- fix shake --- - - i_line = 0 - while i_line < len(l_in_fix_shake): - line = l_in_fix_shake[i_line] - tokens = line.strip().split() - if len(tokens) < 4: - break - fixid = tokens[1] - group_name = tokens[2] - delete_this_command = True - assert(tokens[3].find('shake') == 0) - - # parse the list of angle types - #i_token = tokens.index('a') - for i_token in range(0, len(tokens)): - if tokens[i_token] == 'a': - break - if i_token != len(tokens): - i_token += 1 - while (i_token < len(tokens)) and tokens[i_token].isdigit(): - # delete angle types from the list which - # do not belong to the selection - btype=int(tokens[i_token]) - if int(tokens[i_token]) in needed_angletypes: - tokens[i_token] = '@angle:type'+tokens[i_token] - i_token += 1 - delete_this_command = False - else: - del tokens[i_token] - - # parse the list of bond types - #i_token = tokens.index('b') - for i_token in range(0, len(tokens)): - if tokens[i_token] == 'b': - break - if i_token != len(tokens): - i_token += 1 - while (i_token < len(tokens)) and tokens[i_token].isdigit(): - # delete bond types from the list which - # do not belong to the selection - btype=int(tokens[i_token]) - if int(tokens[i_token]) in needed_bondtypes: - tokens[i_token] = '@bond:type'+tokens[i_token] - i_token += 1 - delete_this_command = False - else: - del tokens[i_token] - - # parse the list of atom types - # i_token = tokens.index('t') - for i_token in range(0, len(tokens)): - if tokens[i_token] == 't': - break - if i_token != len(tokens): - i_token += 1 - while (i_token < len(tokens)) and tokens[i_token].isdigit(): - # delete atom types from the list which - # do not belong to the selection - btype=int(tokens[i_token]) - if int(tokens[i_token]) in needed_atomtypes: - tokens[i_token] = '@atom:type'+tokens[i_token] - i_token += 1 - delete_this_command = False - else: - del tokens[i_token] - - - # Selecting atoms by mass feature should still work, so we - # don't need to delete or ignore these kinds of commands. - #for i_token in range(0, len(tokens)): - # if tokens[i_token] == 'm': - # break - #if i_token != len(tokens): - # delete_this_command = True - - if 'mol' in tokens: - delete_this_command = True - - if not (group_name in groups_needed): - delete_this_command = True - - if delete_this_command: - sys.stderr.write('WARNING: Ignoring line \n\"'+l_in_fix_shake[i_line].rstrip()+'\"\n') - del l_in_fix_shake[i_line] - else: - l_in_fix_shake[i_line] = (' '*indent) + ' '.join(tokens) + '\n' - i_line += 1 - - - # --- fix poems --- - - i_line = 0 - while i_line < len(l_in_fix_poems): - line = l_in_fix_poems[i_line] - tokens = line.strip().split() - if len(tokens) < 4: - break - fixid = tokens[1] - group_name = tokens[2] - delete_this_command = True - assert(tokens[3].find('poems') == 0) - if group_name in groups_needed: - delete_this_command = False - if tokens[4] != 'molecule': - delete_this_command = True - sys.stderr.write('WARNING: '+g_program_name+' ONLY supports \"fix poems\" commands\n' - ' which use the \"molecule\" keyword.\n') - if tokens[4] == 'file': - sys.stderr.write(' If you want use external files with fix poems, then you will have to\n' - ' generate the file yourself. You ask use moltemplate to generate\n' - ' this file for you, by manually adding a section at the end of your\n' - ' final .LT file (eg. \"system.lt\") which resembles the following:\n\n' - 'write(\"poems_file.txt\") {\n' - ' 1 1 $atom:idname1a $atom:idname2a $atom:idname3a ...\n' - ' 2 1 $atom:idname1b $atom:idname2b $atom:idname3b ...\n' - ' 3 1 $atom:idname1c $atom:idname2c $atom:idname3c ...\n' - ' : : etc...\n' - '}\n\n' - ' ...where $atom:idname1a, $atom:idname2a, ... are moltemplate-compatible\n' - ' unique (full,long) id-names for the atoms in each rigid body.\n' - ' This will insure the atom-id numbers in this file are correct.\n' - - ' See the documentation for fix poems for details.\n') - - - if delete_this_command: - sys.stderr.write('WARNING: Ignoring line \n\"'+l_in_fix_poems[i_line].rstrip()+'\"\n') - del l_in_fix_poems[i_line] - else: - l_in_fix_poems[i_line] = (' '*indent) + ' '.join(tokens) + '\n' - i_line += 1 - - - - # --- fix qeq --- - - i_line = 0 - while i_line < len(l_in_fix_qeq): - line = l_in_fix_qeq[i_line] - tokens = line.strip().split() - if len(tokens) < 4: - break - fixid = tokens[1] - group_name = tokens[2] - delete_this_command = True - assert(tokens[3].find('qeq') == 0) - if group_name in groups_needed: - delete_this_command = False - - if delete_this_command: - sys.stderr.write('WARNING: Ignoring line \n\"'+l_in_fix_qeq[i_line].rstrip()+'\"\n') - del l_in_fix_qeq[i_line] - else: - l_in_fix_qeq[i_line] = (' '*indent) + ' '.join(tokens) + '\n' - i_line += 1 - - - - # --- fix qmmm --- - - i_line = 0 - while i_line < len(l_in_fix_qmmm): - line = l_in_fix_qmmm[i_line] - tokens = line.strip().split() - if len(tokens) < 4: - break - fixid = tokens[1] - group_name = tokens[2] - delete_this_command = True - assert(tokens[3].find('qmmm') == 0) - if group_name in groups_needed: - delete_this_command = False - - if delete_this_command: - sys.stderr.write('WARNING: Ignoring line \n\"'+l_in_fix_qmmm[i_line].rstrip()+'\"\n') - del l_in_fix_qmmm[i_line] - else: - l_in_fix_qmmm[i_line] = (' '*indent) + ' '.join(tokens) + '\n' - i_line += 1 - - - - - - - ######################################## - ### Now begin writing the template. ### - ######################################## - - if not some_pair_coeffs_read: - sys.stderr.write('Warning: No \"pair coeffs\" set.\n' - ' (No interactions between non-bonded atoms defined.)\n') - no_warnings = False - - #sys.stderr.write('Writing ttree data to standard out.\n' - # ' You can redirect this to a file using:\n'+ - # ' '+' '.join(sys.argv)+' > filename.ttree\n' - # ' ----------------------\n') - - if mol_name != '': - sys.stdout.write(mol_name + ' {\n') - - if len(l_in_init) > 0: - sys.stdout.write('\n### LAMMPS commands for initialization\n' - '### (These can be overridden later.)\n\n') - l_in_init.insert(0, (' '*cindent)+'write_once(\"'+in_init+'\") {\n') - l_in_init.append((' '*cindent)+'}\n') - sys.stdout.write('\n') - sys.stdout.write(''.join(l_in_init)) - if len(l_in_settings) > 0: - sys.stdout.write('\n### LAMMPS commands for settings\n' - '### (These can be overridden later.)\n\n') - l_in_settings.insert(0, (' '*cindent)+'write_once(\"'+in_settings+'\") {\n') - l_in_settings.append((' '*cindent)+'}\n') - sys.stdout.write('\n') - sys.stdout.write(''.join(l_in_settings)) - non_empty_output = True - if len(l_in_masses) > 0: - l_in_masses.insert(0, (' '*cindent)+'write_once(\"'+in_settings+'\") {\n') - l_in_masses.append((' '*cindent)+'}\n') - sys.stdout.write('\n') - sys.stdout.write(''.join(l_in_masses)) - non_empty_output = True - - - if remove_coeffs_from_data_file: - if len(l_data_pair_coeffs) > 0: - for line in l_data_pair_coeffs: - tokens = line.strip().split() - atomtype_str = tokens[0] - l_in_pair_coeffs.append((' '*cindent)+' pair_coeff '+atomtype_str+' '+atomtype_str+' '+' '.join(tokens[1:])+'\n') - l_data_pair_coeffs = [] - if len(l_data_pairij_coeffs) > 0: - for line in l_data_pairij_coeffs: - l_in_pair_coeffs.append((' '*cindent)+' pair_coeff '+line.strip()+'\n') - l_data_pairij_coeffs = [] - if len(l_in_pair_coeffs) > 0: - l_in_pair_coeffs.insert(0, (' '*cindent)+'write_once(\"'+in_settings+'\") {\n') - l_in_pair_coeffs.append((' '*cindent)+'}\n') - sys.stdout.write('\n') - sys.stdout.write(''.join(l_in_pair_coeffs)) - non_empty_output = True - - - if (remove_coeffs_from_data_file and (len(l_data_bond_coeffs) > 0)): - for line in l_data_bond_coeffs: - l_in_bond_coeffs.append((' '*cindent)+' bond_coeff '+line.strip()+'\n') - l_data_bond_coeffs = [] - if len(l_in_bond_coeffs) > 0: - l_in_bond_coeffs.insert(0, (' '*cindent)+'write_once(\"'+in_settings+'\") {\n') - l_in_bond_coeffs.append((' '*cindent)+'}\n') - sys.stdout.write('\n') - sys.stdout.write(''.join(l_in_bond_coeffs)) - non_empty_output = True - - if (remove_coeffs_from_data_file and (len(l_data_angle_coeffs) > 0)): - for line in l_data_angle_coeffs: - l_in_angle_coeffs.append((' '*cindent)+' angle_coeff '+line.strip()+'\n') - l_data_angle_coeffs = [] - for line in l_data_bondbond_coeffs: - tokens = line.strip().split() - l_in_angle_coeffs.append((' '*cindent)+' angle_coeff '+tokens[0]+' bb '+' '.join(tokens[1:])+'\n') - l_data_bondbond_coeffs = [] - for line in l_data_bondangle_coeffs: - tokens = line.strip().split() - l_in_angle_coeffs.append((' '*cindent)+' angle_coeff '+tokens[0]+' ba '+' '.join(tokens[1:])+'\n') - l_data_bondangle_coeffs = [] - if len(l_in_angle_coeffs) > 0: - l_in_angle_coeffs.insert(0, (' '*cindent)+'write_once(\"'+in_settings+'\") {\n') - l_in_angle_coeffs.append((' '*cindent)+'}\n') - sys.stdout.write('\n') - sys.stdout.write(''.join(l_in_angle_coeffs)) - non_empty_output = True - - if (remove_coeffs_from_data_file and (len(l_data_dihedral_coeffs) > 0)): - for line in l_data_dihedral_coeffs: - l_in_dihedral_coeffs.append((' '*cindent)+' dihedral_coeff '+line.strip()+'\n') - l_data_dihedral_coeffs = [] - - for line in l_data_middlebondtorsion_coeffs: - tokens = line.strip().split() - l_in_dihedral_coeffs.append((' '*cindent)+' dihedral_coeff '+tokens[0]+' mbt '+' '.join(tokens[1:])+'\n') - l_data_middlebondtorsion_coeffs = [] - - for line in l_data_endbondtorsion_coeffs: - tokens = line.strip().split() - l_in_dihedral_coeffs.append((' '*cindent)+' dihedral_coeff '+tokens[0]+' ebt '+' '.join(tokens[1:])+'\n') - l_data_endbondtorsion_coeffs = [] - - for line in l_data_angletorsion_coeffs: - tokens = line.strip().split() - l_in_dihedral_coeffs.append((' '*cindent)+' dihedral_coeff '+tokens[0]+' at '+' '.join(tokens[1:])+'\n') - l_data_angletorsion_coeffs = [] - - for line in l_data_angleangletorsion_coeffs: - tokens = line.strip().split() - l_in_dihedral_coeffs.append((' '*cindent)+' dihedral_coeff '+tokens[0]+' aat '+' '.join(tokens[1:])+'\n') - l_data_angleangletorsion_coeffs = [] - - for line in l_data_bondbond13_coeffs: - tokens = line.strip().split() - l_in_dihedral_coeffs.append((' '*cindent)+' dihedral_coeff '+tokens[0]+' bb13 '+' '.join(tokens[1:])+'\n') - l_data_bondbond13_coeffs = [] - - if len(l_in_dihedral_coeffs) > 0: - l_in_dihedral_coeffs.insert(0, (' '*cindent)+'write_once(\"'+in_settings+'\") {\n') - l_in_dihedral_coeffs.append((' '*cindent)+'}\n') - sys.stdout.write('\n') - sys.stdout.write(''.join(l_in_dihedral_coeffs)) - non_empty_output = True - - if (remove_coeffs_from_data_file and (len(l_data_improper_coeffs) > 0)): - for line in l_data_improper_coeffs: - l_in_improper_coeffs.append((' '*cindent)+' improper_coeff '+line.strip()+'\n') - l_data_improper_coeffs = [] - - for line in l_data_angleangle_coeffs: - tokens = line.strip().split() - l_in_improper_coeffs.append((' '*cindent)+' improper_coeff '+tokens[0]+' aa '+' '.join(tokens[1:])+'\n') - l_data_angleangle_coeffs = [] - - if len(l_in_improper_coeffs) > 0: - l_in_improper_coeffs.insert(0, (' '*cindent)+'write_once(\"'+in_settings+'\") {\n') - l_in_improper_coeffs.append((' '*cindent)+'}\n') - sys.stdout.write('\n') - sys.stdout.write(''.join(l_in_improper_coeffs)) - non_empty_output = True - - if non_empty_output: - sys.stdout.write('\n\n### DATA sections\n\n') - - if len(l_data_masses) > 0: - l_data_masses.insert(0, (' '*cindent)+'write_once(\"'+data_masses+'\") {\n') - l_data_masses.append((' '*cindent)+'}\n') - sys.stdout.write('\n') - sys.stdout.write(''.join(l_data_masses)) - non_empty_output = True - if len(l_data_bond_coeffs) > 0: - l_data_bond_coeffs.insert(0, (' '*cindent)+'write_once(\"'+data_bond_coeffs+'\") {\n') - l_data_bond_coeffs.append((' '*cindent)+'}\n') - sys.stdout.write('\n') - sys.stdout.write(''.join(l_data_bond_coeffs)) - non_empty_output = True - if len(l_data_angle_coeffs) > 0: - l_data_angle_coeffs.insert(0, (' '*cindent)+'write_once(\"'+data_angle_coeffs+'\") {\n') - l_data_angle_coeffs.append((' '*cindent)+'}\n') - sys.stdout.write('\n') - sys.stdout.write(''.join(l_data_angle_coeffs)) - non_empty_output = True - if len(l_data_dihedral_coeffs) > 0: - l_data_dihedral_coeffs.insert(0, (' '*cindent)+'write_once(\"'+data_dihedral_coeffs+'\") {\n') - l_data_dihedral_coeffs.append((' '*cindent)+'}\n') - sys.stdout.write('\n') - sys.stdout.write(''.join(l_data_dihedral_coeffs)) - non_empty_output = True - if len(l_data_improper_coeffs) > 0: - l_data_improper_coeffs.insert(0, (' '*cindent)+'write_once(\"'+data_improper_coeffs+'\") {\n') - l_data_improper_coeffs.append((' '*cindent)+'}\n') - sys.stdout.write('\n') - sys.stdout.write(''.join(l_data_improper_coeffs)) - non_empty_output = True - if len(l_data_pair_coeffs) > 0: - l_data_pair_coeffs.insert(0, (' '*cindent)+'write_once(\"'+data_pair_coeffs+'\") {\n') - l_data_pair_coeffs.append((' '*cindent)+'}\n') - sys.stdout.write('\n') - sys.stdout.write(''.join(l_data_pair_coeffs)) - non_empty_output = True - if len(l_data_pairij_coeffs) > 0: - l_data_pairij_coeffs.insert(0, (' '*cindent)+'write_once(\"'+data_pairij_coeffs+'\") {\n') - l_data_pairij_coeffs.append((' '*cindent)+'}\n') - sys.stdout.write('\n') - sys.stdout.write(''.join(l_data_pairij_coeffs)) - non_empty_output = True - - # class2 force fields: - if len(l_data_bondbond_coeffs) > 0: - l_data_bondbond_coeffs.insert(0, (' '*cindent)+'write_once(\"'+data_bondbond_coeffs+'\") {\n') - l_data_bondbond_coeffs.append((' '*cindent)+'}\n') - sys.stdout.write('\n') - sys.stdout.write(''.join(l_data_bondbond_coeffs)) - non_empty_output = True - if len(l_data_bondangle_coeffs) > 0: - l_data_bondangle_coeffs.insert(0, (' '*cindent)+'write_once(\"'+data_bondangle_coeffs+'\") {\n') - l_data_bondangle_coeffs.append((' '*cindent)+'}\n') - sys.stdout.write('\n') - sys.stdout.write(''.join(l_data_bondangle_coeffs)) - non_empty_output = True - if len(l_data_middlebondtorsion_coeffs) > 0: - l_data_middlebondtorsion_coeffs.insert(0, (' '*cindent)+'write_once(\"'+data_middlebondtorsion_coeffs+'\") {\n') - l_data_middlebondtorsion_coeffs.append((' '*cindent)+'}\n') - sys.stdout.write('\n') - sys.stdout.write(''.join(l_data_middlebondtorsion_coeffs)) - non_empty_output = True - if len(l_data_endbondtorsion_coeffs) > 0: - l_data_endbondtorsion_coeffs.insert(0, (' '*cindent)+'write_once(\"'+data_endbondtorsion_coeffs+'\") {\n') - l_data_endbondtorsion_coeffs.append((' '*cindent)+'}\n') - sys.stdout.write('\n') - sys.stdout.write(''.join(l_data_endbondtorsion_coeffs)) - non_empty_output = True - if len(l_data_angletorsion_coeffs) > 0: - l_data_angletorsion_coeffs.insert(0, (' '*cindent)+'write_once(\"'+data_angletorsion_coeffs+'\") {\n') - l_data_angletorsion_coeffs.append((' '*cindent)+'}\n') - sys.stdout.write('\n') - sys.stdout.write(''.join(l_data_angletorsion_coeffs)) - non_empty_output = True - if len(l_data_angleangletorsion_coeffs) > 0: - l_data_angleangletorsion_coeffs.insert(0, (' '*cindent)+'write_once(\"'+data_angleangletorsion_coeffs+'\") {\n') - l_data_angleangletorsion_coeffs.append((' '*cindent)+'}\n') - sys.stdout.write('\n') - sys.stdout.write(''.join(l_data_angleangletorsion_coeffs)) - non_empty_output = True - if len(l_data_bondbond13_coeffs) > 0: - l_data_bondbond13_coeffs.insert(0, (' '*cindent)+'write_once(\"'+data_bondbond13_coeffs+'\") {\n') - l_data_bondbond13_coeffs.append((' '*cindent)+'}\n') - sys.stdout.write('\n') - sys.stdout.write(''.join(l_data_bondbond13_coeffs)) - non_empty_output = True - if len(l_data_angleangle_coeffs) > 0: - l_data_angleangle_coeffs.insert(0, (' '*cindent)+'write_once(\"'+data_angleangle_coeffs+'\") {\n') - l_data_angleangle_coeffs.append((' '*cindent)+'}\n') - sys.stdout.write('\n') - sys.stdout.write(''.join(l_data_angleangle_coeffs)) - non_empty_output = True - - # automatic generation of bonded interactions by type: - if len(l_data_angles_by_type) > 0: - l_data_angles_by_type.insert(0, (' '*cindent)+'write_once(\"'+data_angles_by_type+'\") {\n') - l_data_angles_by_type.append((' '*cindent)+'}\n') - sys.stdout.write('\n') - sys.stdout.write(''.join(l_data_angles_by_type)) - non_empty_output = True - if len(l_data_dihedrals_by_type) > 0: - l_data_dihedrals_by_type.insert(0, (' '*cindent)+'write_once(\"'+data_dihedrals_by_type+'\") {\n') - l_data_dihedrals_by_type.append((' '*cindent)+'}\n') - sys.stdout.write('\n') - sys.stdout.write(''.join(l_data_dihedrals_by_type)) - non_empty_output = True - if len(l_data_impropers_by_type) > 0: - l_data_impropers_by_type.insert(0, (' '*cindent)+'write_once(\"'+data_impropers_by_type+'\") {\n') - l_data_impropers_by_type.append((' '*cindent)+'}\n') - sys.stdout.write('\n') - sys.stdout.write(''.join(l_data_impropers_by_type)) - non_empty_output = True - - if len(l_data_atoms) > 0: - l_data_atoms.insert(0, (' '*cindent)+'write(\"'+data_atoms+'\") {\n') - l_data_atoms.append((' '*cindent)+'}\n') - sys.stdout.write('\n') - sys.stdout.write(''.join(l_data_atoms)) - non_empty_output = True - else: - sys.stderr.write('Warning: missing \"Atoms\" section.\n' - ' (Did you include a LAMMPS data file in your argument list?)\n') - no_warnings = False - - # non-point-like particles - if len(l_data_ellipsoids) > 0: - l_data_ellipsoids.insert(0, (' '*cindent)+'write(\"'+data_ellipsoids+'\") {\n') - l_data_ellipsoids.append((' '*cindent)+'}\n') - sys.stdout.write('\n') - sys.stdout.write(''.join(l_data_ellipsoids)) - if len(l_data_lines) > 0: - l_data_lines.insert(0, (' '*cindent)+'write(\"'+data_lines+'\") {\n') - l_data_lines.append((' '*cindent)+'}\n') - sys.stdout.write('\n') - sys.stdout.write(''.join(l_data_lines)) - if len(l_data_triangles) > 0: - l_data_triangles.insert(0, (' '*cindent)+'write(\"'+data_triangles+'\") {\n') - l_data_triangles.append((' '*cindent)+'}\n') - sys.stdout.write('\n') - sys.stdout.write(''.join(l_data_triangles)) - - # DO NOT WRITE OUT VELOCITY DATA - # (Why: because it makes it difficult to combine this molecular template - # with molecule templates from other sources which lack velocity data. - # LAMMPS (and topotools) will crash if the number of entries in the - # Velocities section of a data file does not match the number of atoms.) - # COMMENTING OUT: - #if len(l_data_velocities) > 0: - # l_data_velocities.insert(0, (' '*cindent)+'write(\"'+data_velocities+'\") {\n') - # l_data_velocities.append((' '*cindent)+'}\n') - # sys.stdout.write('\n') - # sys.stdout.write(''.join(l_data_velocities)) - if len(l_data_bonds) > 0: - l_data_bonds.insert(0, (' '*cindent)+'write(\"'+data_bonds+'\") {\n') - l_data_bonds.append((' '*cindent)+'}\n') - sys.stdout.write('\n') - sys.stdout.write(''.join(l_data_bonds)) - non_empty_output = True - if len(l_data_angles) > 0: - l_data_angles.insert(0, (' '*cindent)+'write(\"'+data_angles+'\") {\n') - l_data_angles.append((' '*cindent)+'}\n') - sys.stdout.write('\n') - sys.stdout.write(''.join(l_data_angles)) - non_empty_output = True - if len(l_data_dihedrals) > 0: - l_data_dihedrals.insert(0, (' '*cindent)+'write(\"'+data_dihedrals+'\") {\n') - l_data_dihedrals.append((' '*cindent)+'}\n') - sys.stdout.write('\n') - sys.stdout.write(''.join(l_data_dihedrals)) - non_empty_output = True - if len(l_data_impropers) > 0: - l_data_impropers.insert(0, (' '*cindent)+'write(\"'+data_impropers+'\") {\n') - l_data_impropers.append((' '*cindent)+'}\n') - sys.stdout.write('\n') - sys.stdout.write(''.join(l_data_impropers)) - non_empty_output = True - - if len(l_in_group) > 0: - no_warnings = False - l_in_group.insert(0, (' '*cindent)+'write(\"'+in_settings+'\") {\n') - l_in_group.append((' '*cindent)+'}\n') - sys.stdout.write('\n') - sys.stdout.write(''.join(l_in_group)) - #sys.stderr.write('######################################################\n' - # 'WARNING: One or more \"group\" commands appear to refer to relevant atoms.\n' - # ' Please check to make sure that the group(s) generated by\n' - # ' '+g_program_name+' contain the correct atoms. (-Andrew 2014-10-30)\n' - # '######################################################\n') - assert(non_empty_output) - - if len(l_in_fix_rigid) > 0: - no_warnings = False - l_in_fix_rigid.insert(0, (' '*cindent)+'write(\"'+in_settings+'\") {\n') - l_in_fix_rigid.append((' '*cindent)+'}\n') - sys.stdout.write('\n') - sys.stdout.write(''.join(l_in_fix_rigid)) - sys.stderr.write('WARNING: \"fix rigid\" style command(s) applied to selected atoms.\n' - ' Please make sure that the fix group(s) are defined correctly.\n' - '######################################################\n') - assert(non_empty_output) - - if len(l_in_fix_shake) > 0: - no_warnings = False - l_in_fix_shake.insert(0, (' '*cindent)+'write(\"'+in_settings+'\") {\n') - l_in_fix_shake.append((' '*cindent)+'}\n') - sys.stdout.write('\n') - sys.stdout.write(''.join(l_in_fix_shake)) - sys.stderr.write('WARNING: \"fix shake\" style command(s) applied to selected atoms.\n' - ' Please check to make sure that the fix group(s) are defined correctly,\n' - - ' and also check that the atom, bond, and angle types are correct.\n' - '######################################################\n') - assert(non_empty_output) - - if len(l_in_fix_poems) > 0: - no_warnings = False - l_in_fix_poems.insert(0, (' '*cindent)+'write(\"'+in_settings+'\") {\n') - l_in_fix_poems.append((' '*cindent)+'}\n') - sys.stdout.write('\n') - sys.stdout.write(''.join(l_in_fix_poems)) - sys.stderr.write('WARNING: \"fix poems\" style command(s) applied to selected atoms.\n' - ' Please make sure that the fix group(s) are defined correctly.\n' - '######################################################\n') - assert(non_empty_output) - - if len(l_in_fix_qeq) > 0: - no_warnings = False - l_in_fix_qeq.insert(0, (' '*cindent)+'write(\"'+in_settings+'\") {\n') - l_in_fix_qeq.append((' '*cindent)+'}\n') - sys.stdout.write('\n') - sys.stdout.write(''.join(l_in_fix_qeq)) - sys.stderr.write('WARNING: \"fix qeq\" style command(s) applied to selected atoms.\n' - ' Please make sure that the fix group(s) are defined correctly.\n' - '######################################################\n') - assert(non_empty_output) - - if len(l_in_fix_qmmm) > 0: - no_warnings = False - l_in_fix_qmmm.insert(0, (' '*cindent)+'write(\"'+in_settings+'\") {\n') - l_in_fix_qmmm.append((' '*cindent)+'}\n') - sys.stdout.write('\n') - sys.stdout.write(''.join(l_in_fix_qmmm)) - sys.stderr.write('WARNING: \"fix qmmm\" style command(s) applied to selected atoms.\n' - ' Please make sure that the fix group(s) are defined correctly.\n' - '######################################################\n') - assert(non_empty_output) - - - - if mol_name != '': - sys.stdout.write('\n} # end of \"'+mol_name+'\" type definition\n') - - - - #if non_empty_output and no_warnings: - if non_empty_output: - sys.stderr.write('WARNING: The '+g_program_name+' script has not been rigorously tested.\n' - ' Exotic (many-body) pair-styles and pair-styles with\n' - ' unusual syntax (such hbond/dreiding) are not understood\n' - ' by '+g_program_name+' (...although they are supported by moltemplate).\n' - ' Please look over the resulting LT file and check for errors.\n' - ' Convert any remaining atom, bond, angle, dihedral, or improper id\n' - ' or type numbers to the corresponding $ or @-style counter variables.\n' - ' Feel free to report any bugs you find. (-Andrew Jewett 2015-8-02)\n') - - - -except (ValueError, InputError) as err: - sys.stderr.write('\n'+str(err)+'\n') - sys.exit(-1) diff --git a/tools/moltemplate/src/lttree.py b/tools/moltemplate/src/lttree.py deleted file mode 100644 index 743419eb2b..0000000000 --- a/tools/moltemplate/src/lttree.py +++ /dev/null @@ -1,744 +0,0 @@ -#!/usr/bin/env python - -# Author: Andrew Jewett (jewett.aij at g mail) -# http://www.chem.ucsb.edu/~sheagroup -# License: 3-clause BSD License (See LICENSE.TXT) -# Copyright (c) 2011, Regents of the University of California -# All rights reserved. - -""" -lttree.py - -lttree.py is an extension of the generic ttree.py program. -This version can understand and manipulate ttree-style templates which -are specialized for storing molecule-specific data for use in LAMMPS. - -The main difference between lttree.py and ttree.py is: -Unlike ttree.py, lttree.py understands rigid-body movement commands like -"rot()" and "move()" which allows it to reorient and move each copy -of a molecule to a new location. (ttree.py just ignores these commands. -Consequently LAMMPS input file (fragments) created with ttree.py have -invalid (overlapping) atomic coordinates and must be modified or aguemted -later (by loading atomic coordinates from a PDB file or an XYZ file). -lttree.py understands the "Data Atoms" section of a LAMMPS -data file (in addition to the various "atom_styles" which effect it). - -Additional LAMMPS-specific features may be added in the future. - -""" - -import sys -from ttree import * -from lttree_styles import * -from ttree_matrix_stack import * - -try: - unicode -except NameError: - # Python 3 - basestring = unicode = str - - - - -class LttreeSettings(BasicUISettings): - def __init__(self, - user_bindings_x=None, - user_bindings=None, - order_method='by_command'): - - BasicUISettings.__init__(self, - user_bindings_x, - user_bindings, - order_method) - - # The following new member data indicate which columns store - # LAMMPS-specific information. - # The next 6 members store keep track of the different columns - # of the "Data Atoms" section of a LAMMPS data file: - self.column_names = [] #<--A list of column names (optional) - self.ii_coords=[] #<--A list of triplets of column indexes storing coordinate data - self.ii_vects=[] #<--A list of triplets of column indexes storing directional data - # (such as dipole or ellipsoid orientations) - self.i_atomid=None #<--An integer indicating which column has the atomid - self.i_atomtype=None #<--An integer indicating which column has the atomtype - self.i_molid=None #<--An integer indicating which column has the molid, if applicable - self.infile=None # Name of the outermost file. This is the file - # which was read at the moment parsing begins. - - - - -def LttreeParseArgs(argv, settings): - - BasicUIParseArgs(argv, settings) - - # Loop over the remaining arguments not processed yet. - # These arguments are specific to the lttree.py program - # and are not understood by ttree.py: - i = 1 - while i < len(argv): - #sys.stderr.write('argv['+str(i)+'] = \"'+argv[i]+'\"\n') - if ((argv[i].lower() == '-atomstyle') or - (argv[i].lower() == '-atom-style') or - (argv[i].lower() == '-atom_style')): - if i+1 >= len(argv): - raise InputError('Error('+g_program_name+'): The '+argv[i]+' flag should be followed by a LAMMPS\n' - ' atom_style name (or single quoted string containing a space-separated\n' - ' list of column names such as: atom-ID atom-type q x y z molecule-ID.)\n') - settings.column_names = AtomStyle2ColNames(argv[i+1]) - sys.stderr.write('\n \"'+data_atoms+'\" column format:\n') - sys.stderr.write(' '+(' '.join(settings.column_names))+'\n\n') - settings.ii_coords = ColNames2Coords(settings.column_names) - settings.ii_vects = ColNames2Vects(settings.column_names) - settings.i_atomid, settings.i_atomtype, settings.i_molid = ColNames2AidAtypeMolid(settings.column_names) - del(argv[i:i+2]) - elif (argv[i].lower() == '-icoord'): - if i+1 >= len(argv): - raise InputError('Error: '+argv[i]+' flag should be followed by list of integers\n' - ' corresponding to column numbers for coordinates in\n' - ' the \"'+data_atoms+'\" section of a LAMMPS data file.\n') - ilist = argv[i+1].split() - if (len(ilist) % 3) != 0: - raise InputError('Error: '+argv[i]+' flag should be followed by list of integers.\n' - ' This is usually a list of 3 integers, but it can contain more.\n' - ' The number of cooridnate columns must be divisible by 3,\n' - ' (even if the simulation is in 2 dimensions)\n') - settings.iaffinevects = [] - for i in range(0, len(ilist)/3): - cols = [int(ilist[3*i])+1, - int(ilist[3*i+1])+1, - int(ilist[3*i+2])+1] - settings.iaffinevects.append(cols) - del(argv[i:i+2]) - elif (argv[i].lower() == '-ivect'): - if i+1 >= len(argv): - raise InputError('Error: '+argv[i]+' flag should be followed by list of integers\n' - ' corresponding to column numbers for direction vectors in\n' - ' the \"'+data_atoms+'\" section of a LAMMPS data file.\n') - ilist = argv[i+1].split() - if (len(ilist) % 3) != 0: - raise InputError('Error: '+argv[i]+' flag should be followed by list of integers.\n' - ' This is usually a list of 3 integers, but it can contain more.\n' - ' The number of cooridnate columns must be divisible by 3,\n' - ' (even if the simulation is in 2 dimensions)\n') - settings.ivects = [] - for i in range(0, len(ilist)/3): - cols = [int(ilist[3*i])+1, - int(ilist[3*i+1])+1, - int(ilist[3*i+2])+1] - settings.ivects.append(cols) - del(argv[i:i+2]) - elif ((argv[i].lower() == '-iatomid') or - (argv[i].lower() == '-iid') or - (argv[i].lower() == '-iatom-id')): - if ((i+1 >= len(argv)) or (not str.isdigit(argv[i+1]))): - raise InputError('Error: '+argv[i]+' flag should be followed by an integer\n' - ' (>=1) indicating which column in the \"'+data_atoms+'\" section of a\n' - ' LAMMPS data file contains the atom id number (typically 1).\n' - ' (This argument is unnecessary if you use the -atomstyle argument.)\n') - i_atomid = int(argv[i+1])-1 - del(argv[i:i+2]) - elif ((argv[i].lower() == '-iatomtype') or - (argv[i].lower() == '-itype') or - (argv[i].lower() == '-iatom-type')): - if ((i+1 >= len(argv)) or (not str.isdigit(argv[i+1]))): - raise InputError('Error: '+argv[i]+' flag should be followed by an integer\n' - ' (>=1) indicating which column in the \"'+data_atoms+'\" section of a\n' - ' LAMMPS data file contains the atom type.\n' - ' (This argument is unnecessary if you use the -atomstyle argument.)\n') - i_atomtype = int(argv[i+1])-1 - del(argv[i:i+2]) - elif ((argv[i].lower() == '-imolid') or - (argv[i].lower() == '-imol') or - (argv[i].lower() == '-imol-id') or - (argv[i].lower() == '-imoleculeid') or - (argv[i].lower() == '-imolecule-id')): - if ((i+1 >= len(argv)) or (not str.isdigit(argv[i+1]))): - raise InputError('Error: '+argv[i]+' flag should be followed by an integer\n' - ' (>=1) indicating which column in the \"'+data_atoms+'\" section of a\n' - ' LAMMPS data file contains the molecule id number.\n' - ' (This argument is unnecessary if you use the -atomstyle argument.)\n') - i_molid = int(argv[i+1])-1 - del(argv[i:i+2]) - - elif ((argv[i][0] == '-') and (__name__ == "__main__")): - #elif (__name__ == "__main__"): - raise InputError('Error('+g_program_name+'):\n' - 'Unrecognized command line argument \"'+argv[i]+'\"\n') - else: - i += 1 - - - if __name__ == "__main__": - - # Instantiate the lexer we will be using. - # (The lexer's __init__() function requires an openned file. - # Assuming __name__ == "__main__", then the name of that file should - # be the last remaining (unprocessed) argument in the argument list. - # Otherwise, then name of that file will be determined later by the - # python script which imports this module, so we let them handle it.) - - if len(argv) == 1: - raise InputError('Error: This program requires at least one argument\n' - ' the name of a file containing ttree template commands\n') - elif len(argv) == 2: - try: - settings.lex = TemplateLexer(open(argv[1], 'r'), argv[1]) # Parse text from file - except IOError: - sys.stderr.write('Error: unable to open file\n' - ' \"'+argv[1]+'\"\n' - ' for reading.\n') - sys.exit(1) - del(argv[1:2]) - - else: - # if there are more than 2 remaining arguments, - problem_args = ['\"'+arg+'\"' for arg in argv[1:]] - raise InputError('Syntax Error('+g_program_name+'):\n\n' - ' Problem with argument list.\n' - ' The remaining arguments are:\n\n' - ' '+(' '.join(problem_args))+'\n\n' - ' (The actual problem may be earlier in the argument list.\n' - ' If these arguments are source files, then keep in mind\n' - ' that this program can not parse multiple source files.)\n' - ' Check the syntax of the entire argument list.\n') - - - - if len(settings.ii_coords) == 0: - sys.stderr.write('########################################################\n' - '## WARNING: atom_style unspecified ##\n' - '## --> \"'+data_atoms+'\" column data has an unknown format ##\n' - '## Assuming atom_style = \"full\" ##\n' - # '########################################################\n' - # '## To specify the \"'+data_atoms+'\" column format you can: ##\n' - # '## 1) Use the -atomstyle \"STYLE\" argument ##\n' - # '## where \"STYLE\" is a string indicating a LAMMPS ##\n' - # '## atom_style, including hybrid styles.(Standard ##\n' - # '## atom styles defined in 2011 are supported.) ##\n' - # '## 2) Use the -atomstyle \"COL_LIST\" argument ##\n' - # '## where \"COL_LIST" is a quoted list of strings ##\n' - # '## indicating the name of each column. ##\n' - # '## Names \"x\",\"y\",\"z\" are interpreted as ##\n' - # '## atomic coordinates. \"mux\",\"muy\",\"muz\" ##\n' - # '## are interpreted as direction vectors. ##\n' - # '## 3) Use the -icoord \"cx cy cz...\" argument ##\n' - # '## where \"cx cy cz\" is a list of integers ##\n' - # '## indicating the column numbers for the x,y,z ##\n' - # '## coordinates of each atom. ##\n' - # '## 4) Use the -ivect \"cmux cmuy cmuz...\" argument ##\n' - # '## where \"cmux cmuy cmuz...\" is a list of ##\n' - # '## integers indicating the column numbers for ##\n' - # '## the vector that determines the direction of a ##\n' - # '## dipole or ellipsoid (ie. a rotateable vector).##\n' - # '## (More than one triplet can be specified. The ##\n' - # '## number of entries must be divisible by 3.) ##\n' - '########################################################\n') - - # The default atom_style is "full" - settings.column_names = AtomStyle2ColNames('full') - settings.ii_coords = ColNames2Coords(settings.column_names) - settings.ii_vects = ColNames2Vects(settings.column_names) - settings.i_atomid, settings.i_atomtype, settings.i_molid = ColNames2AidAtypeMolid(settings.column_names) - - - - - - - - - -def TransformAtomText(text, matrix): - """ Apply transformations to the coordinates and other vector degrees - of freedom stored in the \"Data Atoms\" section of a LAMMPS data file. - This is the \"text\" argument. - The \"matrix\" stores the aggregate sum of combined transformations - to be applied. - - """ - - #sys.stderr.write('matrix_stack.M = \n'+ MatToStr(matrix) + '\n') - - lines = text.split('\n') - - for i in range(0, len(lines)): - line_orig = lines[i] - ic = line_orig.find('#') - if ic != -1: - line = line_orig[:ic] - comment = ' '+line_orig[ic:].rstrip('\n') - else: - line = line_orig.rstrip('\n') - comment = '' - - columns = line.split() - if len(columns) > 0: - if len(columns) == len(settings.column_names)+3: - raise InputError('Error: lttree.py does not yet support integer unit-cell counters \n' - ' within the \"'+data_atoms+'\" section of a LAMMPS data file.\n' - ' Instead please add the appropriate offsets (these offsets\n' - ' should be multiples of the cell size) to the atom coordinates\n' - ' in the data file, and eliminate the extra columns. Then try again.\n' - ' (If you get this message often, email me and I\'ll fix this limitation.)') - if len(columns) < len(settings.column_names): - raise InputError('Error: The number of columns in your data file does not\n' - ' match the LAMMPS atom_style you selected.\n' - ' Use the -atomstyle

    L}z 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

2hulJ}JO_#Oz^??$11DEVZ5Oe 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 z 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�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 diff --git a/tools/moltemplate/examples/coarse_grained_examples/MARTINI_examples/DPPC_bilayer_formation_PACKMOL/images/water_martini_LR.jpg b/tools/moltemplate/examples/coarse_grained_examples/MARTINI_examples/DPPC_bilayer_formation_PACKMOL/images/water_martini_LR.jpg deleted file mode 100644 index a43675a5aa627f1c051d7748aebec8bf791a2422..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1660 zcmb7Edo+}37=OR{X2xwM-!PKfno%!_8*P zWuS0w zUR_3u)<6o^D$i971jd49@`mwG zNhg}&nx8z^m$n$=rUjZ*g=JlGIcYf1YrU>(x#UfN>MtLtIK8P+*XZ+ohC2(+?n2tE z-n}?+AznM=s!GMmnoneTM$xWr$r~NT1x>CA)OD3|oL2tBsOq>!i<(sZE;8R>l@pE07(I?Bz&$3*S-DM7O&_Z-zKrv*tBRjv>X@`@^Di4kRi<0pXT7$1-8eq15ZQk&GQM>( zrYlrqaItoi6t%I{aG0Tb;P`TwUYOd0y;=8fPk1s->tzxHM|o?<7R#)pL;ikPP}_#X z^)KpFMb!-N`=_Q3(iHWjs5>xl5)fC}_}Z=1E+@tP>R9k;zy?sTDg_GuPuD}iG>pzN zclJpw7fBV?C)UeMeJ4KE>95Fm9x%k)6}IXVsba4Xka6Y#En#8z$dVC@oA0eIo$TB~ zvX9Y9^an)cQu6~vQjbsho@%x;@)QWclqqoRK|WvF0YET}2Ejgdg0Lj9nZxs;Q)6w1m2e}hEp719tJWQi^?nW?4)?=|bPNU*4uLN*;Xo6S$7sPZ z*FOq?Gr$a6;a79m#|kUXTB|3lZSHIBrpOtvh7N{1?S1sevgOY!hr>|w6Y|z&6{@S6 z`Lj$tOO$i9u%Ye9eHT+Mb=HfeMDL)IlXOBu!jlIRq%DG;WH8Z?7`{qot=?P>e z&u@OEfM@V@V0NKTk4x&FF_=jT{`R7dWph=^ISX0NT3x#L&_q!7nKTk Console -c) Enter: - -(I assume that the the DATA file is called "system.data") - - topo readlammpsdata system.data full - animate write psf system.psf - -2) - -Later, to Load a trajectory in VMD: - - Start VMD - Select menu: File->New Molecule - -Browse to select the PSF file you created above, and load it. - (Don't close the window yet.) - -Browse to select the trajectory file. - If necessary, for "file type" select: "LAMMPS Trajectory" - Load it. - - ---- A note on trajectory format: ----- -If the trajectory is a DUMP file, then make sure the it contains the -information you need for pbctools (see below. I've been using this -command in my LAMMPS scripts to create the trajectories: - - dump 1 all custom 5000 DUMP_FILE.lammpstrj id mol type x y z ix iy iz - -It's a good idea to use an atom_style which supports molecule-ID numbers -so that you can assign a molecule-ID number to each atom. (I think this -is needed to wrap atom coordinates without breaking molecules in half.) - -Of course, you don't have to save your trajectories in DUMP format, -(other formats like DCD work fine) I just mention dump files -because these are the files I'm familiar with. - -3) ----- Wrap the coordinates to the unit cell - (without cutting the molecules in half) - -a) Start VMD -b) Load the trajectory in VMD (see above) -c) Menu Extensions->Tk Console -d) Try entering these commands: - - pbc wrap -compound res -all - pbc box - - ----- Optional ---- - Sometimes the solvent or membrane obscures the view of the solute. - It can help to shift the location of the periodic boundary box - To shift the box in the y direction (for example) do this: - - pbc wrap -compound res -all -shiftcenterrel {0.0 0.0 -0.5} - pbc box -shiftcenterrel {0.0 0.0 -0.5} -style tubes -width 0.75 - - Distances are measured in units of box-length fractions, not Angstroms. - - Alternately if you have a solute whose atoms are all of type 1, - then you can also try this to center the box around it: - - pbc wrap -sel type=1 -all -centersel type=2 -center com - -4) - You should check if your periodic boundary conditions are too small. - To do that: - select Graphics->Representations menu option - click on the "Periodic" tab, and - click on the "+x", "-x", "+y", "-y", "+z", "-z" checkboxes. - -5) Optional: If you like, change the atom types in the PSF file so - that VMD recognizes the atom types, use something like: - -sed -e 's/ 1 1 / C C /g' < system.psf > temp1.psf -sed -e 's/ 2 2 / H H /g' < temp1.psf > temp2.psf -sed -e 's/ 3 3 / P P /g' < temp2.psf > system.psf - -(If you do this, it might effect step 2 above.) diff --git a/tools/moltemplate/examples/coarse_grained_examples/MARTINI_examples/DPPC_bilayer_preformed/images/DPPC_martini_LR.jpg b/tools/moltemplate/examples/coarse_grained_examples/MARTINI_examples/DPPC_bilayer_preformed/images/DPPC_martini_LR.jpg deleted file mode 100644 index cc85e79ff14717ece09368596bfdf3a60748935d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12907 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%0AQ%&NkLM6}83gYHEbL2k#$xJWNv#o$ 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Π#Bc#!uh}QT4p9aG?Nv+q(b=fqn4A!;qBcM6V1)y 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